[cig-commits] r7044 - in vendor: . Python Python/current Python/current/Demo Python/current/Demo/cgi Python/current/Demo/classes Python/current/Demo/comparisons Python/current/Demo/curses Python/current/Demo/embed Python/current/Demo/imputil Python/current/Demo/md5test Python/current/Demo/metaclasses Python/current/Demo/newmetaclasses Python/current/Demo/parser Python/current/Demo/pdist Python/current/Demo/pysvr Python/current/Demo/rpc Python/current/Demo/scripts Python/current/Demo/sockets Python/current/Demo/threads Python/current/Demo/tix Python/current/Demo/tix/bitmaps Python/current/Demo/tix/samples Python/current/Demo/tkinter Python/current/Demo/tkinter/guido Python/current/Demo/tkinter/matt Python/current/Demo/xml Python/current/Demo/zlib Python/current/Doc Python/current/Doc/api Python/current/Doc/commontex Python/current/Doc/dist Python/current/Doc/doc Python/current/Doc/ext Python/current/Doc/howto Python/current/Doc/html Python/current/Doc/html/icons Python/current/Doc/info Python/current/Doc/inst Python/current/Doc/lib Python/current/Doc/lib/sqlite3 Python/current/Doc/mac Python/current/Doc/paper-a4 Python/current/Doc/perl Python/current/Doc/ref Python/current/Doc/templates Python/current/Doc/tests Python/current/Doc/texinputs Python/current/Doc/tools Python/current/Doc/tools/sgmlconv Python/current/Doc/tut Python/current/Doc/whatsnew Python/current/Grammar Python/current/Include Python/current/Lib Python/current/Lib/bsddb Python/current/Lib/bsddb/test Python/current/Lib/compiler Python/current/Lib/ctypes Python/current/Lib/ctypes/macholib Python/current/Lib/ctypes/test Python/current/Lib/curses Python/current/Lib/distutils Python/current/Lib/distutils/command Python/current/Lib/distutils/tests Python/current/Lib/email Python/current/Lib/email/mime Python/current/Lib/email/test Python/current/Lib/email/test/data Python/current/Lib/encodings Python/current/Lib/hotshot Python/current/Lib/idlelib Python/current/Lib/idlelib/Icons Python/current/Lib/lib-tk Python/current/Lib/logging Python/current/Lib/msilib Python/current/Lib/plat-aix3 Python/current/Lib/plat-aix4 Python/current/Lib/plat-atheos Python/current/Lib/plat-beos5 Python/current/Lib/plat-darwin Python/current/Lib/plat-freebsd2 Python/current/Lib/plat-freebsd3 Python/current/Lib/plat-freebsd4 Python/current/Lib/plat-freebsd5 Python/current/Lib/plat-freebsd6 Python/current/Lib/plat-freebsd7 Python/current/Lib/plat-generic Python/current/Lib/plat-irix5 Python/current/Lib/plat-irix6 Python/current/Lib/plat-linux2 Python/current/Lib/plat-mac Python/current/Lib/plat-mac/Carbon Python/current/Lib/plat-mac/lib-scriptpackages Python/current/Lib/plat-mac/lib-scriptpackages/CodeWarrior Python/current/Lib/plat-mac/lib-scriptpackages/Explorer Python/current/Lib/plat-mac/lib-scriptpackages/Finder Python/current/Lib/plat-mac/lib-scriptpackages/Netscape Python/current/Lib/plat-mac/lib-scriptpackages/StdSuites Python/current/Lib/plat-mac/lib-scriptpackages/SystemEvents Python/current/Lib/plat-mac/lib-scriptpackages/Terminal Python/current/Lib/plat-mac/lib-scriptpackages/_builtinSuites Python/current/Lib/plat-netbsd1 Python/current/Lib/plat-next3 Python/current/Lib/plat-os2emx Python/current/Lib/plat-riscos Python/current/Lib/plat-sunos5 Python/current/Lib/plat-unixware7 Python/current/Lib/site-packages Python/current/Lib/sqlite3 Python/current/Lib/sqlite3/test Python/current/Lib/test Python/current/Lib/test/crashers Python/current/Lib/test/decimaltestdata Python/current/Lib/test/leakers Python/current/Lib/test/output Python/current/Lib/wsgiref Python/current/Lib/xml Python/current/Lib/xml/dom Python/current/Lib/xml/etree Python/current/Lib/xml/parsers Python/current/Lib/xml/sax Python/current/Mac Python/current/Mac/BuildScript Python/current/Mac/BuildScript/resources Python/current/Mac/BuildScript/scripts Python/current/Mac/Demo Python/current/Mac/Demo/PICTbrowse Python/current/Mac/Demo/applescript Python/current/Mac/Demo/applescript/Disk_Copy Python/current/Mac/Demo/example0 Python/current/Mac/Demo/example1 Python/current/Mac/Demo/example2 Python/current/Mac/Demo/html.icons Python/current/Mac/Demo/imgbrowse Python/current/Mac/Demo/mlte Python/current/Mac/Demo/quicktime Python/current/Mac/Demo/resources Python/current/Mac/Demo/sound Python/current/Mac/Demo/textedit Python/current/Mac/IDLE Python/current/Mac/Icons Python/current/Mac/Modules Python/current/Mac/Modules/ae Python/current/Mac/Modules/ah Python/current/Mac/Modules/app Python/current/Mac/Modules/carbonevt Python/current/Mac/Modules/cf Python/current/Mac/Modules/cg Python/current/Mac/Modules/cm Python/current/Mac/Modules/ctl Python/current/Mac/Modules/dlg Python/current/Mac/Modules/drag Python/current/Mac/Modules/evt Python/current/Mac/Modules/file Python/current/Mac/Modules/fm Python/current/Mac/Modules/folder Python/current/Mac/Modules/help Python/current/Mac/Modules/ibcarbon Python/current/Mac/Modules/icn Python/current/Mac/Modules/launch Python/current/Mac/Modules/list Python/current/Mac/Modules/menu Python/current/Mac/Modules/mlte Python/current/Mac/Modules/osa Python/current/Mac/Modules/qd Python/current/Mac/Modules/qdoffs Python/current/Mac/Modules/qt Python/current/Mac/Modules/res Python/current/Mac/Modules/scrap Python/current/Mac/Modules/snd Python/current/Mac/Modules/te Python/current/Mac/Modules/win Python/current/Mac/PythonLauncher Python/current/Mac/PythonLauncher/English.lproj Python/current/Mac/PythonLauncher/English.lproj/MainMenu.nib Python/current/Mac/PythonLauncher/English.lproj/MyDocument.nib Python/current/Mac/PythonLauncher/English.lproj/PreferenceWindow.nib Python/current/Mac/Resources Python/current/Mac/Resources/app Python/current/Mac/Resources/app/Resources Python/current/Mac/Resources/app/Resources/English.lproj Python/current/Mac/Resources/app/Resources/English.lproj/Documentation Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/doc Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/ide Python/current/Mac/Resources/framework Python/current/Mac/Resources/framework/English.lproj Python/current/Mac/Resources/iconsrc Python/current/Mac/Tools Python/current/Mac/Tools/Doc Python/current/Mac/Tools/Doc/HelpIndexingTool Python/current/Mac/scripts Python/current/Misc Python/current/Misc/RPM Python/current/Misc/Vim Python/current/Modules Python/current/Modules/_ctypes Python/current/Modules/_ctypes/darwin Python/current/Modules/_ctypes/libffi Python/current/Modules/_ctypes/libffi/include Python/current/Modules/_ctypes/libffi/src Python/current/Modules/_ctypes/libffi/src/alpha Python/current/Modules/_ctypes/libffi/src/arm Python/current/Modules/_ctypes/libffi/src/cris Python/current/Modules/_ctypes/libffi/src/darwin Python/current/Modules/_ctypes/libffi/src/frv Python/current/Modules/_ctypes/libffi/src/ia64 Python/current/Modules/_ctypes/libffi/src/m32r Python/current/Modules/_ctypes/libffi/src/m68k Python/current/Modules/_ctypes/libffi/src/mips Python/current/Modules/_ctypes/libffi/src/pa Python/current/Modules/_ctypes/libffi/src/powerpc Python/current/Modules/_ctypes/libffi/src/s390 Python/current/Modules/_ctypes/libffi/src/sh Python/current/Modules/_ctypes/libffi/src/sh64 Python/current/Modules/_ctypes/libffi/src/sparc Python/current/Modules/_ctypes/libffi/src/x86 Python/current/Modules/_ctypes/libffi_arm_wince Python/current/Modules/_ctypes/libffi_msvc Python/current/Modules/_sqlite Python/current/Modules/cjkcodecs Python/current/Modules/expat Python/current/Modules/zlib Python/current/Objects Python/current/Objects/stringlib Python/current/PC Python/current/PC/VC6 Python/current/PC/bdist_wininst Python/current/PC/example_nt Python/current/PC/icons Python/current/PC/os2emx Python/current/PC/os2vacpp Python/current/PCbuild Python/current/PCbuild8 Python/current/Parser Python/current/Python Python/current/RISCOS Python/current/RISCOS/Modules Python/current/RISCOS/Python Python/current/RISCOS/support Python/current/Tools Python/current/Tools/audiopy Python/current/Tools/bgen Python/current/Tools/bgen/bgen Python/current/Tools/buildbot Python/current/Tools/compiler Python/current/Tools/faqwiz Python/current/Tools/framer Python/current/Tools/framer/framer Python/current/Tools/freeze Python/current/Tools/i18n Python/current/Tools/modulator Python/current/Tools/modulator/Templates Python/current/Tools/msi Python/current/Tools/pybench Python/current/Tools/pybench/package Python/current/Tools/pynche Python/current/Tools/pynche/X Python/current/Tools/scripts Python/current/Tools/unicode Python/current/Tools/unicode/python-mappings Python/current/Tools/versioncheck Python/current/Tools/webchecker Python/current/Tools/world

leif at geodynamics.org leif at geodynamics.org
Fri Jun 1 17:22:08 PDT 2007


Author: leif
Date: 2007-06-01 17:21:15 -0700 (Fri, 01 Jun 2007)
New Revision: 7044

Added:
   vendor/Python/
   vendor/Python/current/
   vendor/Python/current/Demo/
   vendor/Python/current/Demo/README
   vendor/Python/current/Demo/cgi/
   vendor/Python/current/Demo/cgi/README
   vendor/Python/current/Demo/cgi/cgi0.sh
   vendor/Python/current/Demo/cgi/cgi1.py
   vendor/Python/current/Demo/cgi/cgi2.py
   vendor/Python/current/Demo/cgi/cgi3.py
   vendor/Python/current/Demo/cgi/wiki.py
   vendor/Python/current/Demo/classes/
   vendor/Python/current/Demo/classes/Complex.py
   vendor/Python/current/Demo/classes/Dates.py
   vendor/Python/current/Demo/classes/Dbm.py
   vendor/Python/current/Demo/classes/README
   vendor/Python/current/Demo/classes/Range.py
   vendor/Python/current/Demo/classes/Rat.py
   vendor/Python/current/Demo/classes/Rev.py
   vendor/Python/current/Demo/classes/Vec.py
   vendor/Python/current/Demo/classes/bitvec.py
   vendor/Python/current/Demo/comparisons/
   vendor/Python/current/Demo/comparisons/README
   vendor/Python/current/Demo/comparisons/patterns
   vendor/Python/current/Demo/comparisons/regextest.py
   vendor/Python/current/Demo/comparisons/sortingtest.py
   vendor/Python/current/Demo/comparisons/systemtest.py
   vendor/Python/current/Demo/curses/
   vendor/Python/current/Demo/curses/README
   vendor/Python/current/Demo/curses/life.py
   vendor/Python/current/Demo/curses/ncurses.py
   vendor/Python/current/Demo/curses/rain.py
   vendor/Python/current/Demo/curses/repeat.py
   vendor/Python/current/Demo/curses/tclock.py
   vendor/Python/current/Demo/curses/xmas.py
   vendor/Python/current/Demo/embed/
   vendor/Python/current/Demo/embed/README
   vendor/Python/current/Demo/embed/demo.c
   vendor/Python/current/Demo/embed/importexc.c
   vendor/Python/current/Demo/embed/loop.c
   vendor/Python/current/Demo/imputil/
   vendor/Python/current/Demo/imputil/importers.py
   vendor/Python/current/Demo/imputil/knee.py
   vendor/Python/current/Demo/md5test/
   vendor/Python/current/Demo/md5test/README
   vendor/Python/current/Demo/md5test/foo
   vendor/Python/current/Demo/md5test/md5driver.py
   vendor/Python/current/Demo/metaclasses/
   vendor/Python/current/Demo/metaclasses/Eiffel.py
   vendor/Python/current/Demo/metaclasses/Enum.py
   vendor/Python/current/Demo/metaclasses/Meta.py
   vendor/Python/current/Demo/metaclasses/Simple.py
   vendor/Python/current/Demo/metaclasses/Synch.py
   vendor/Python/current/Demo/metaclasses/Trace.py
   vendor/Python/current/Demo/metaclasses/index.html
   vendor/Python/current/Demo/metaclasses/meta-vladimir.txt
   vendor/Python/current/Demo/newmetaclasses/
   vendor/Python/current/Demo/newmetaclasses/Eiffel.py
   vendor/Python/current/Demo/newmetaclasses/Enum.py
   vendor/Python/current/Demo/parser/
   vendor/Python/current/Demo/parser/FILES
   vendor/Python/current/Demo/parser/README
   vendor/Python/current/Demo/parser/docstring.py
   vendor/Python/current/Demo/parser/example.py
   vendor/Python/current/Demo/parser/simple.py
   vendor/Python/current/Demo/parser/source.py
   vendor/Python/current/Demo/parser/test_parser.py
   vendor/Python/current/Demo/parser/texipre.dat
   vendor/Python/current/Demo/parser/unparse.py
   vendor/Python/current/Demo/pdist/
   vendor/Python/current/Demo/pdist/FSProxy.py
   vendor/Python/current/Demo/pdist/RCSProxy.py
   vendor/Python/current/Demo/pdist/README
   vendor/Python/current/Demo/pdist/client.py
   vendor/Python/current/Demo/pdist/cmdfw.py
   vendor/Python/current/Demo/pdist/cmptree.py
   vendor/Python/current/Demo/pdist/cvslib.py
   vendor/Python/current/Demo/pdist/cvslock.py
   vendor/Python/current/Demo/pdist/mac.py
   vendor/Python/current/Demo/pdist/makechangelog.py
   vendor/Python/current/Demo/pdist/rcsbump
   vendor/Python/current/Demo/pdist/rcsclient.py
   vendor/Python/current/Demo/pdist/rcslib.py
   vendor/Python/current/Demo/pdist/rcvs
   vendor/Python/current/Demo/pdist/rcvs.py
   vendor/Python/current/Demo/pdist/rrcs
   vendor/Python/current/Demo/pdist/rrcs.py
   vendor/Python/current/Demo/pdist/security.py
   vendor/Python/current/Demo/pdist/server.py
   vendor/Python/current/Demo/pdist/sumtree.py
   vendor/Python/current/Demo/pysvr/
   vendor/Python/current/Demo/pysvr/README
   vendor/Python/current/Demo/pysvr/pysvr.c
   vendor/Python/current/Demo/pysvr/pysvr.py
   vendor/Python/current/Demo/rpc/
   vendor/Python/current/Demo/rpc/MANIFEST
   vendor/Python/current/Demo/rpc/README
   vendor/Python/current/Demo/rpc/T.py
   vendor/Python/current/Demo/rpc/mountclient.py
   vendor/Python/current/Demo/rpc/nfsclient.py
   vendor/Python/current/Demo/rpc/rnusersclient.py
   vendor/Python/current/Demo/rpc/rpc.py
   vendor/Python/current/Demo/rpc/test
   vendor/Python/current/Demo/rpc/xdr.py
   vendor/Python/current/Demo/scripts/
   vendor/Python/current/Demo/scripts/README
   vendor/Python/current/Demo/scripts/beer.py
   vendor/Python/current/Demo/scripts/eqfix.py
   vendor/Python/current/Demo/scripts/fact.py
   vendor/Python/current/Demo/scripts/find-uname.py
   vendor/Python/current/Demo/scripts/from.py
   vendor/Python/current/Demo/scripts/ftpstats.py
   vendor/Python/current/Demo/scripts/lpwatch.py
   vendor/Python/current/Demo/scripts/makedir.py
   vendor/Python/current/Demo/scripts/markov.py
   vendor/Python/current/Demo/scripts/mboxconvert.py
   vendor/Python/current/Demo/scripts/mkrcs.py
   vendor/Python/current/Demo/scripts/morse.py
   vendor/Python/current/Demo/scripts/newslist.doc
   vendor/Python/current/Demo/scripts/newslist.py
   vendor/Python/current/Demo/scripts/pi.py
   vendor/Python/current/Demo/scripts/pp.py
   vendor/Python/current/Demo/scripts/primes.py
   vendor/Python/current/Demo/scripts/queens.py
   vendor/Python/current/Demo/scripts/script.py
   vendor/Python/current/Demo/scripts/unbirthday.py
   vendor/Python/current/Demo/scripts/update.py
   vendor/Python/current/Demo/scripts/wh.py
   vendor/Python/current/Demo/sockets/
   vendor/Python/current/Demo/sockets/README
   vendor/Python/current/Demo/sockets/broadcast.py
   vendor/Python/current/Demo/sockets/echosvr.py
   vendor/Python/current/Demo/sockets/finger.py
   vendor/Python/current/Demo/sockets/ftp.py
   vendor/Python/current/Demo/sockets/gopher.py
   vendor/Python/current/Demo/sockets/mcast.py
   vendor/Python/current/Demo/sockets/radio.py
   vendor/Python/current/Demo/sockets/rpython.py
   vendor/Python/current/Demo/sockets/rpythond.py
   vendor/Python/current/Demo/sockets/telnet.py
   vendor/Python/current/Demo/sockets/throughput.py
   vendor/Python/current/Demo/sockets/udpecho.py
   vendor/Python/current/Demo/sockets/unicast.py
   vendor/Python/current/Demo/sockets/unixclient.py
   vendor/Python/current/Demo/sockets/unixserver.py
   vendor/Python/current/Demo/threads/
   vendor/Python/current/Demo/threads/Coroutine.py
   vendor/Python/current/Demo/threads/Generator.py
   vendor/Python/current/Demo/threads/README
   vendor/Python/current/Demo/threads/fcmp.py
   vendor/Python/current/Demo/threads/find.py
   vendor/Python/current/Demo/threads/squasher.py
   vendor/Python/current/Demo/threads/sync.py
   vendor/Python/current/Demo/threads/telnet.py
   vendor/Python/current/Demo/tix/
   vendor/Python/current/Demo/tix/INSTALL.txt
   vendor/Python/current/Demo/tix/README.txt
   vendor/Python/current/Demo/tix/bitmaps/
   vendor/Python/current/Demo/tix/bitmaps/about.xpm
   vendor/Python/current/Demo/tix/bitmaps/bold.xbm
   vendor/Python/current/Demo/tix/bitmaps/capital.xbm
   vendor/Python/current/Demo/tix/bitmaps/centerj.xbm
   vendor/Python/current/Demo/tix/bitmaps/combobox.xbm
   vendor/Python/current/Demo/tix/bitmaps/combobox.xpm
   vendor/Python/current/Demo/tix/bitmaps/combobox.xpm.1
   vendor/Python/current/Demo/tix/bitmaps/drivea.xbm
   vendor/Python/current/Demo/tix/bitmaps/drivea.xpm
   vendor/Python/current/Demo/tix/bitmaps/exit.xpm
   vendor/Python/current/Demo/tix/bitmaps/filebox.xbm
   vendor/Python/current/Demo/tix/bitmaps/filebox.xpm
   vendor/Python/current/Demo/tix/bitmaps/italic.xbm
   vendor/Python/current/Demo/tix/bitmaps/justify.xbm
   vendor/Python/current/Demo/tix/bitmaps/leftj.xbm
   vendor/Python/current/Demo/tix/bitmaps/netw.xbm
   vendor/Python/current/Demo/tix/bitmaps/netw.xpm
   vendor/Python/current/Demo/tix/bitmaps/optmenu.xpm
   vendor/Python/current/Demo/tix/bitmaps/rightj.xbm
   vendor/Python/current/Demo/tix/bitmaps/select.xpm
   vendor/Python/current/Demo/tix/bitmaps/tix.gif
   vendor/Python/current/Demo/tix/bitmaps/underline.xbm
   vendor/Python/current/Demo/tix/grid.py
   vendor/Python/current/Demo/tix/samples/
   vendor/Python/current/Demo/tix/samples/Balloon.py
   vendor/Python/current/Demo/tix/samples/BtnBox.py
   vendor/Python/current/Demo/tix/samples/CmpImg.py
   vendor/Python/current/Demo/tix/samples/ComboBox.py
   vendor/Python/current/Demo/tix/samples/Control.py
   vendor/Python/current/Demo/tix/samples/DirList.py
   vendor/Python/current/Demo/tix/samples/DirTree.py
   vendor/Python/current/Demo/tix/samples/NoteBook.py
   vendor/Python/current/Demo/tix/samples/OptMenu.py
   vendor/Python/current/Demo/tix/samples/PanedWin.py
   vendor/Python/current/Demo/tix/samples/PopMenu.py
   vendor/Python/current/Demo/tix/samples/SHList1.py
   vendor/Python/current/Demo/tix/samples/SHList2.py
   vendor/Python/current/Demo/tix/samples/Tree.py
   vendor/Python/current/Demo/tix/tixwidgets.py
   vendor/Python/current/Demo/tkinter/
   vendor/Python/current/Demo/tkinter/README
   vendor/Python/current/Demo/tkinter/guido/
   vendor/Python/current/Demo/tkinter/guido/AttrDialog.py
   vendor/Python/current/Demo/tkinter/guido/ManPage.py
   vendor/Python/current/Demo/tkinter/guido/MimeViewer.py
   vendor/Python/current/Demo/tkinter/guido/ShellWindow.py
   vendor/Python/current/Demo/tkinter/guido/brownian.py
   vendor/Python/current/Demo/tkinter/guido/canvasevents.py
   vendor/Python/current/Demo/tkinter/guido/dialog.py
   vendor/Python/current/Demo/tkinter/guido/electrons.py
   vendor/Python/current/Demo/tkinter/guido/hanoi.py
   vendor/Python/current/Demo/tkinter/guido/hello.py
   vendor/Python/current/Demo/tkinter/guido/imagedraw.py
   vendor/Python/current/Demo/tkinter/guido/imageview.py
   vendor/Python/current/Demo/tkinter/guido/kill.py
   vendor/Python/current/Demo/tkinter/guido/listtree.py
   vendor/Python/current/Demo/tkinter/guido/mbox.py
   vendor/Python/current/Demo/tkinter/guido/newmenubardemo.py
   vendor/Python/current/Demo/tkinter/guido/optionmenu.py
   vendor/Python/current/Demo/tkinter/guido/paint.py
   vendor/Python/current/Demo/tkinter/guido/rmt.py
   vendor/Python/current/Demo/tkinter/guido/solitaire.py
   vendor/Python/current/Demo/tkinter/guido/sortvisu.py
   vendor/Python/current/Demo/tkinter/guido/ss1.py
   vendor/Python/current/Demo/tkinter/guido/svkill.py
   vendor/Python/current/Demo/tkinter/guido/switch.py
   vendor/Python/current/Demo/tkinter/guido/tkman.py
   vendor/Python/current/Demo/tkinter/guido/wish.py
   vendor/Python/current/Demo/tkinter/matt/
   vendor/Python/current/Demo/tkinter/matt/00-HELLO-WORLD.py
   vendor/Python/current/Demo/tkinter/matt/README
   vendor/Python/current/Demo/tkinter/matt/animation-simple.py
   vendor/Python/current/Demo/tkinter/matt/animation-w-velocity-ctrl.py
   vendor/Python/current/Demo/tkinter/matt/bind-w-mult-calls-p-type.py
   vendor/Python/current/Demo/tkinter/matt/canvas-demo-simple.py
   vendor/Python/current/Demo/tkinter/matt/canvas-gridding.py
   vendor/Python/current/Demo/tkinter/matt/canvas-moving-or-creating.py
   vendor/Python/current/Demo/tkinter/matt/canvas-moving-w-mouse.py
   vendor/Python/current/Demo/tkinter/matt/canvas-mult-item-sel.py
   vendor/Python/current/Demo/tkinter/matt/canvas-reading-tag-info.py
   vendor/Python/current/Demo/tkinter/matt/canvas-w-widget-draw-el.py
   vendor/Python/current/Demo/tkinter/matt/canvas-with-scrollbars.py
   vendor/Python/current/Demo/tkinter/matt/dialog-box.py
   vendor/Python/current/Demo/tkinter/matt/entry-simple.py
   vendor/Python/current/Demo/tkinter/matt/entry-with-shared-variable.py
   vendor/Python/current/Demo/tkinter/matt/killing-window-w-wm.py
   vendor/Python/current/Demo/tkinter/matt/menu-all-types-of-entries.py
   vendor/Python/current/Demo/tkinter/matt/menu-simple.py
   vendor/Python/current/Demo/tkinter/matt/not-what-you-might-think-1.py
   vendor/Python/current/Demo/tkinter/matt/not-what-you-might-think-2.py
   vendor/Python/current/Demo/tkinter/matt/packer-and-placer-together.py
   vendor/Python/current/Demo/tkinter/matt/packer-simple.py
   vendor/Python/current/Demo/tkinter/matt/placer-simple.py
   vendor/Python/current/Demo/tkinter/matt/pong-demo-1.py
   vendor/Python/current/Demo/tkinter/matt/printing-coords-of-items.py
   vendor/Python/current/Demo/tkinter/matt/radiobutton-simple.py
   vendor/Python/current/Demo/tkinter/matt/rubber-band-box-demo-1.py
   vendor/Python/current/Demo/tkinter/matt/rubber-line-demo-1.py
   vendor/Python/current/Demo/tkinter/matt/slider-demo-1.py
   vendor/Python/current/Demo/tkinter/matt/subclass-existing-widgets.py
   vendor/Python/current/Demo/tkinter/matt/two-radio-groups.py
   vendor/Python/current/Demo/tkinter/matt/window-creation-more.py
   vendor/Python/current/Demo/tkinter/matt/window-creation-simple.py
   vendor/Python/current/Demo/tkinter/matt/window-creation-w-location.py
   vendor/Python/current/Demo/xml/
   vendor/Python/current/Demo/xml/elem_count.py
   vendor/Python/current/Demo/xml/roundtrip.py
   vendor/Python/current/Demo/xml/rss2html.py
   vendor/Python/current/Demo/zlib/
   vendor/Python/current/Demo/zlib/minigzip.py
   vendor/Python/current/Demo/zlib/zlibdemo.py
   vendor/Python/current/Doc/
   vendor/Python/current/Doc/ACKS
   vendor/Python/current/Doc/Makefile.deps
   vendor/Python/current/Doc/README
   vendor/Python/current/Doc/TODO
   vendor/Python/current/Doc/api/
   vendor/Python/current/Doc/api/abstract.tex
   vendor/Python/current/Doc/api/api.tex
   vendor/Python/current/Doc/api/concrete.tex
   vendor/Python/current/Doc/api/exceptions.tex
   vendor/Python/current/Doc/api/init.tex
   vendor/Python/current/Doc/api/intro.tex
   vendor/Python/current/Doc/api/memory.tex
   vendor/Python/current/Doc/api/newtypes.tex
   vendor/Python/current/Doc/api/refcounting.tex
   vendor/Python/current/Doc/api/refcounts.dat
   vendor/Python/current/Doc/api/utilities.tex
   vendor/Python/current/Doc/api/veryhigh.tex
   vendor/Python/current/Doc/commontex/
   vendor/Python/current/Doc/commontex/boilerplate.tex
   vendor/Python/current/Doc/commontex/copyright.tex
   vendor/Python/current/Doc/commontex/license.tex
   vendor/Python/current/Doc/commontex/reportingbugs.tex
   vendor/Python/current/Doc/commontex/typestruct.h
   vendor/Python/current/Doc/dist/
   vendor/Python/current/Doc/dist/dist.tex
   vendor/Python/current/Doc/dist/sysconfig.tex
   vendor/Python/current/Doc/doc/
   vendor/Python/current/Doc/doc/doc.tex
   vendor/Python/current/Doc/ext/
   vendor/Python/current/Doc/ext/building.tex
   vendor/Python/current/Doc/ext/embedding.tex
   vendor/Python/current/Doc/ext/ext.tex
   vendor/Python/current/Doc/ext/extending.tex
   vendor/Python/current/Doc/ext/newtypes.tex
   vendor/Python/current/Doc/ext/noddy.c
   vendor/Python/current/Doc/ext/noddy2.c
   vendor/Python/current/Doc/ext/noddy3.c
   vendor/Python/current/Doc/ext/noddy4.c
   vendor/Python/current/Doc/ext/run-func.c
   vendor/Python/current/Doc/ext/setup.py
   vendor/Python/current/Doc/ext/shoddy.c
   vendor/Python/current/Doc/ext/test.py
   vendor/Python/current/Doc/ext/windows.tex
   vendor/Python/current/Doc/howto/
   vendor/Python/current/Doc/howto/TODO
   vendor/Python/current/Doc/howto/advocacy.tex
   vendor/Python/current/Doc/howto/curses.tex
   vendor/Python/current/Doc/howto/doanddont.tex
   vendor/Python/current/Doc/howto/regex.tex
   vendor/Python/current/Doc/howto/sockets.tex
   vendor/Python/current/Doc/howto/unicode.rst
   vendor/Python/current/Doc/howto/urllib2.rst
   vendor/Python/current/Doc/html/
   vendor/Python/current/Doc/html/about.dat
   vendor/Python/current/Doc/html/about.html
   vendor/Python/current/Doc/html/icons/
   vendor/Python/current/Doc/html/icons/blank.gif
   vendor/Python/current/Doc/html/icons/blank.png
   vendor/Python/current/Doc/html/icons/contents.gif
   vendor/Python/current/Doc/html/icons/contents.png
   vendor/Python/current/Doc/html/icons/index.gif
   vendor/Python/current/Doc/html/icons/index.png
   vendor/Python/current/Doc/html/icons/modules.gif
   vendor/Python/current/Doc/html/icons/modules.png
   vendor/Python/current/Doc/html/icons/next.gif
   vendor/Python/current/Doc/html/icons/next.png
   vendor/Python/current/Doc/html/icons/previous.gif
   vendor/Python/current/Doc/html/icons/previous.png
   vendor/Python/current/Doc/html/icons/pyfav.gif
   vendor/Python/current/Doc/html/icons/pyfav.png
   vendor/Python/current/Doc/html/icons/up.gif
   vendor/Python/current/Doc/html/icons/up.png
   vendor/Python/current/Doc/html/index.html.in
   vendor/Python/current/Doc/html/stdabout.dat
   vendor/Python/current/Doc/html/style.css
   vendor/Python/current/Doc/info/
   vendor/Python/current/Doc/info/README
   vendor/Python/current/Doc/info/python.dir
   vendor/Python/current/Doc/inst/
   vendor/Python/current/Doc/inst/inst.tex
   vendor/Python/current/Doc/isilo/
   vendor/Python/current/Doc/lib/
   vendor/Python/current/Doc/lib/archiving.tex
   vendor/Python/current/Doc/lib/asttable.tex
   vendor/Python/current/Doc/lib/caseless.py
   vendor/Python/current/Doc/lib/compiler.tex
   vendor/Python/current/Doc/lib/custominterp.tex
   vendor/Python/current/Doc/lib/datatypes.tex
   vendor/Python/current/Doc/lib/development.tex
   vendor/Python/current/Doc/lib/distutils.tex
   vendor/Python/current/Doc/lib/email-dir.py
   vendor/Python/current/Doc/lib/email-mime.py
   vendor/Python/current/Doc/lib/email-simple.py
   vendor/Python/current/Doc/lib/email-unpack.py
   vendor/Python/current/Doc/lib/email.tex
   vendor/Python/current/Doc/lib/emailcharsets.tex
   vendor/Python/current/Doc/lib/emailencoders.tex
   vendor/Python/current/Doc/lib/emailexc.tex
   vendor/Python/current/Doc/lib/emailgenerator.tex
   vendor/Python/current/Doc/lib/emailheaders.tex
   vendor/Python/current/Doc/lib/emailiter.tex
   vendor/Python/current/Doc/lib/emailmessage.tex
   vendor/Python/current/Doc/lib/emailmimebase.tex
   vendor/Python/current/Doc/lib/emailparser.tex
   vendor/Python/current/Doc/lib/emailutil.tex
   vendor/Python/current/Doc/lib/fileformats.tex
   vendor/Python/current/Doc/lib/filesys.tex
   vendor/Python/current/Doc/lib/frameworks.tex
   vendor/Python/current/Doc/lib/i18n.tex
   vendor/Python/current/Doc/lib/internet.tex
   vendor/Python/current/Doc/lib/ipc.tex
   vendor/Python/current/Doc/lib/language.tex
   vendor/Python/current/Doc/lib/lib.tex
   vendor/Python/current/Doc/lib/libaifc.tex
   vendor/Python/current/Doc/lib/libal.tex
   vendor/Python/current/Doc/lib/liballos.tex
   vendor/Python/current/Doc/lib/libamoeba.tex
   vendor/Python/current/Doc/lib/libanydbm.tex
   vendor/Python/current/Doc/lib/libarray.tex
   vendor/Python/current/Doc/lib/libascii.tex
   vendor/Python/current/Doc/lib/libast.tex
   vendor/Python/current/Doc/lib/libasynchat.tex
   vendor/Python/current/Doc/lib/libasyncore.tex
   vendor/Python/current/Doc/lib/libatexit.tex
   vendor/Python/current/Doc/lib/libaudioop.tex
   vendor/Python/current/Doc/lib/libbase64.tex
   vendor/Python/current/Doc/lib/libbasehttp.tex
   vendor/Python/current/Doc/lib/libbastion.tex
   vendor/Python/current/Doc/lib/libbinascii.tex
   vendor/Python/current/Doc/lib/libbinhex.tex
   vendor/Python/current/Doc/lib/libbisect.tex
   vendor/Python/current/Doc/lib/libbltin.tex
   vendor/Python/current/Doc/lib/libbsddb.tex
   vendor/Python/current/Doc/lib/libbz2.tex
   vendor/Python/current/Doc/lib/libcalendar.tex
   vendor/Python/current/Doc/lib/libcd.tex
   vendor/Python/current/Doc/lib/libcfgparser.tex
   vendor/Python/current/Doc/lib/libcgi.tex
   vendor/Python/current/Doc/lib/libcgihttp.tex
   vendor/Python/current/Doc/lib/libcgitb.tex
   vendor/Python/current/Doc/lib/libchunk.tex
   vendor/Python/current/Doc/lib/libcmath.tex
   vendor/Python/current/Doc/lib/libcmd.tex
   vendor/Python/current/Doc/lib/libcmp.tex
   vendor/Python/current/Doc/lib/libcmpcache.tex
   vendor/Python/current/Doc/lib/libcode.tex
   vendor/Python/current/Doc/lib/libcodecs.tex
   vendor/Python/current/Doc/lib/libcodeop.tex
   vendor/Python/current/Doc/lib/libcollections.tex
   vendor/Python/current/Doc/lib/libcolorsys.tex
   vendor/Python/current/Doc/lib/libcommands.tex
   vendor/Python/current/Doc/lib/libcompileall.tex
   vendor/Python/current/Doc/lib/libconsts.tex
   vendor/Python/current/Doc/lib/libcontextlib.tex
   vendor/Python/current/Doc/lib/libcookie.tex
   vendor/Python/current/Doc/lib/libcookielib.tex
   vendor/Python/current/Doc/lib/libcopy.tex
   vendor/Python/current/Doc/lib/libcopyreg.tex
   vendor/Python/current/Doc/lib/libcrypt.tex
   vendor/Python/current/Doc/lib/libcrypto.tex
   vendor/Python/current/Doc/lib/libcsv.tex
   vendor/Python/current/Doc/lib/libctypes.tex
   vendor/Python/current/Doc/lib/libcurses.tex
   vendor/Python/current/Doc/lib/libcursespanel.tex
   vendor/Python/current/Doc/lib/libdatetime.tex
   vendor/Python/current/Doc/lib/libdbhash.tex
   vendor/Python/current/Doc/lib/libdbm.tex
   vendor/Python/current/Doc/lib/libdecimal.tex
   vendor/Python/current/Doc/lib/libdifflib.tex
   vendor/Python/current/Doc/lib/libdircache.tex
   vendor/Python/current/Doc/lib/libdis.tex
   vendor/Python/current/Doc/lib/libdl.tex
   vendor/Python/current/Doc/lib/libdoctest.tex
   vendor/Python/current/Doc/lib/libdocxmlrpc.tex
   vendor/Python/current/Doc/lib/libdumbdbm.tex
   vendor/Python/current/Doc/lib/libdummythread.tex
   vendor/Python/current/Doc/lib/libdummythreading.tex
   vendor/Python/current/Doc/lib/liberrno.tex
   vendor/Python/current/Doc/lib/libetree.tex
   vendor/Python/current/Doc/lib/libexcs.tex
   vendor/Python/current/Doc/lib/libfcntl.tex
   vendor/Python/current/Doc/lib/libfilecmp.tex
   vendor/Python/current/Doc/lib/libfileinput.tex
   vendor/Python/current/Doc/lib/libfl.tex
   vendor/Python/current/Doc/lib/libfm.tex
   vendor/Python/current/Doc/lib/libfnmatch.tex
   vendor/Python/current/Doc/lib/libformatter.tex
   vendor/Python/current/Doc/lib/libfpectl.tex
   vendor/Python/current/Doc/lib/libfpformat.tex
   vendor/Python/current/Doc/lib/libftplib.tex
   vendor/Python/current/Doc/lib/libfuncs.tex
   vendor/Python/current/Doc/lib/libfunctools.tex
   vendor/Python/current/Doc/lib/libfuture.tex
   vendor/Python/current/Doc/lib/libgc.tex
   vendor/Python/current/Doc/lib/libgdbm.tex
   vendor/Python/current/Doc/lib/libgetopt.tex
   vendor/Python/current/Doc/lib/libgetpass.tex
   vendor/Python/current/Doc/lib/libgettext.tex
   vendor/Python/current/Doc/lib/libgl.tex
   vendor/Python/current/Doc/lib/libglob.tex
   vendor/Python/current/Doc/lib/libgopherlib.tex
   vendor/Python/current/Doc/lib/libgrp.tex
   vendor/Python/current/Doc/lib/libgzip.tex
   vendor/Python/current/Doc/lib/libhashlib.tex
   vendor/Python/current/Doc/lib/libheapq.tex
   vendor/Python/current/Doc/lib/libhmac.tex
   vendor/Python/current/Doc/lib/libhotshot.tex
   vendor/Python/current/Doc/lib/libhtmllib.tex
   vendor/Python/current/Doc/lib/libhtmlparser.tex
   vendor/Python/current/Doc/lib/libhttplib.tex
   vendor/Python/current/Doc/lib/libimageop.tex
   vendor/Python/current/Doc/lib/libimaplib.tex
   vendor/Python/current/Doc/lib/libimgfile.tex
   vendor/Python/current/Doc/lib/libimghdr.tex
   vendor/Python/current/Doc/lib/libimp.tex
   vendor/Python/current/Doc/lib/libinspect.tex
   vendor/Python/current/Doc/lib/libintro.tex
   vendor/Python/current/Doc/lib/libitertools.tex
   vendor/Python/current/Doc/lib/libjpeg.tex
   vendor/Python/current/Doc/lib/libkeyword.tex
   vendor/Python/current/Doc/lib/liblinecache.tex
   vendor/Python/current/Doc/lib/liblocale.tex
   vendor/Python/current/Doc/lib/liblogging.tex
   vendor/Python/current/Doc/lib/libmailbox.tex
   vendor/Python/current/Doc/lib/libmailcap.tex
   vendor/Python/current/Doc/lib/libmain.tex
   vendor/Python/current/Doc/lib/libmarshal.tex
   vendor/Python/current/Doc/lib/libmath.tex
   vendor/Python/current/Doc/lib/libmd5.tex
   vendor/Python/current/Doc/lib/libmhlib.tex
   vendor/Python/current/Doc/lib/libmimetools.tex
   vendor/Python/current/Doc/lib/libmimetypes.tex
   vendor/Python/current/Doc/lib/libmimewriter.tex
   vendor/Python/current/Doc/lib/libmimify.tex
   vendor/Python/current/Doc/lib/libmisc.tex
   vendor/Python/current/Doc/lib/libmm.tex
   vendor/Python/current/Doc/lib/libmmap.tex
   vendor/Python/current/Doc/lib/libmodulefinder.tex
   vendor/Python/current/Doc/lib/libmsilib.tex
   vendor/Python/current/Doc/lib/libmsvcrt.tex
   vendor/Python/current/Doc/lib/libmultifile.tex
   vendor/Python/current/Doc/lib/libmutex.tex
   vendor/Python/current/Doc/lib/libnetrc.tex
   vendor/Python/current/Doc/lib/libnew.tex
   vendor/Python/current/Doc/lib/libni.tex
   vendor/Python/current/Doc/lib/libnis.tex
   vendor/Python/current/Doc/lib/libnntplib.tex
   vendor/Python/current/Doc/lib/libobjs.tex
   vendor/Python/current/Doc/lib/liboperator.tex
   vendor/Python/current/Doc/lib/liboptparse.tex
   vendor/Python/current/Doc/lib/libos.tex
   vendor/Python/current/Doc/lib/libossaudiodev.tex
   vendor/Python/current/Doc/lib/libpanel.tex
   vendor/Python/current/Doc/lib/libparser.tex
   vendor/Python/current/Doc/lib/libpdb.tex
   vendor/Python/current/Doc/lib/libpickle.tex
   vendor/Python/current/Doc/lib/libpickletools.tex
   vendor/Python/current/Doc/lib/libpipes.tex
   vendor/Python/current/Doc/lib/libpkgutil.tex
   vendor/Python/current/Doc/lib/libplatform.tex
   vendor/Python/current/Doc/lib/libpopen2.tex
   vendor/Python/current/Doc/lib/libpoplib.tex
   vendor/Python/current/Doc/lib/libposix.tex
   vendor/Python/current/Doc/lib/libposixfile.tex
   vendor/Python/current/Doc/lib/libposixpath.tex
   vendor/Python/current/Doc/lib/libpprint.tex
   vendor/Python/current/Doc/lib/libprofile.tex
   vendor/Python/current/Doc/lib/libpty.tex
   vendor/Python/current/Doc/lib/libpwd.tex
   vendor/Python/current/Doc/lib/libpyclbr.tex
   vendor/Python/current/Doc/lib/libpycompile.tex
   vendor/Python/current/Doc/lib/libpydoc.tex
   vendor/Python/current/Doc/lib/libpyexpat.tex
   vendor/Python/current/Doc/lib/libpython.tex
   vendor/Python/current/Doc/lib/libqueue.tex
   vendor/Python/current/Doc/lib/libquopri.tex
   vendor/Python/current/Doc/lib/librandom.tex
   vendor/Python/current/Doc/lib/libre.tex
   vendor/Python/current/Doc/lib/libreadline.tex
   vendor/Python/current/Doc/lib/librepr.tex
   vendor/Python/current/Doc/lib/libresource.tex
   vendor/Python/current/Doc/lib/librestricted.tex
   vendor/Python/current/Doc/lib/librexec.tex
   vendor/Python/current/Doc/lib/librfc822.tex
   vendor/Python/current/Doc/lib/librgbimg.tex
   vendor/Python/current/Doc/lib/librlcompleter.tex
   vendor/Python/current/Doc/lib/librobotparser.tex
   vendor/Python/current/Doc/lib/librunpy.tex
   vendor/Python/current/Doc/lib/libsched.tex
   vendor/Python/current/Doc/lib/libselect.tex
   vendor/Python/current/Doc/lib/libsets.tex
   vendor/Python/current/Doc/lib/libsgi.tex
   vendor/Python/current/Doc/lib/libsgmllib.tex
   vendor/Python/current/Doc/lib/libsha.tex
   vendor/Python/current/Doc/lib/libshelve.tex
   vendor/Python/current/Doc/lib/libshlex.tex
   vendor/Python/current/Doc/lib/libshutil.tex
   vendor/Python/current/Doc/lib/libsignal.tex
   vendor/Python/current/Doc/lib/libsimplehttp.tex
   vendor/Python/current/Doc/lib/libsimplexmlrpc.tex
   vendor/Python/current/Doc/lib/libsite.tex
   vendor/Python/current/Doc/lib/libsmtpd.tex
   vendor/Python/current/Doc/lib/libsmtplib.tex
   vendor/Python/current/Doc/lib/libsndhdr.tex
   vendor/Python/current/Doc/lib/libsocket.tex
   vendor/Python/current/Doc/lib/libsocksvr.tex
   vendor/Python/current/Doc/lib/libsomeos.tex
   vendor/Python/current/Doc/lib/libspwd.tex
   vendor/Python/current/Doc/lib/libsqlite3.tex
   vendor/Python/current/Doc/lib/libstat.tex
   vendor/Python/current/Doc/lib/libstatvfs.tex
   vendor/Python/current/Doc/lib/libstdtypes.tex
   vendor/Python/current/Doc/lib/libstdwin.tex
   vendor/Python/current/Doc/lib/libstring.tex
   vendor/Python/current/Doc/lib/libstringio.tex
   vendor/Python/current/Doc/lib/libstringprep.tex
   vendor/Python/current/Doc/lib/libstrings.tex
   vendor/Python/current/Doc/lib/libstruct.tex
   vendor/Python/current/Doc/lib/libsubprocess.tex
   vendor/Python/current/Doc/lib/libsun.tex
   vendor/Python/current/Doc/lib/libsunau.tex
   vendor/Python/current/Doc/lib/libsunaudio.tex
   vendor/Python/current/Doc/lib/libsymbol.tex
   vendor/Python/current/Doc/lib/libsys.tex
   vendor/Python/current/Doc/lib/libsyslog.tex
   vendor/Python/current/Doc/lib/libtabnanny.tex
   vendor/Python/current/Doc/lib/libtarfile.tex
   vendor/Python/current/Doc/lib/libtelnetlib.tex
   vendor/Python/current/Doc/lib/libtempfile.tex
   vendor/Python/current/Doc/lib/libtermios.tex
   vendor/Python/current/Doc/lib/libtest.tex
   vendor/Python/current/Doc/lib/libtextwrap.tex
   vendor/Python/current/Doc/lib/libthread.tex
   vendor/Python/current/Doc/lib/libthreading.tex
   vendor/Python/current/Doc/lib/libtime.tex
   vendor/Python/current/Doc/lib/libtimeit.tex
   vendor/Python/current/Doc/lib/libtoken.tex
   vendor/Python/current/Doc/lib/libtokenize.tex
   vendor/Python/current/Doc/lib/libtrace.tex
   vendor/Python/current/Doc/lib/libtraceback.tex
   vendor/Python/current/Doc/lib/libtty.tex
   vendor/Python/current/Doc/lib/libturtle.tex
   vendor/Python/current/Doc/lib/libtypes.tex
   vendor/Python/current/Doc/lib/libundoc.tex
   vendor/Python/current/Doc/lib/libunicodedata.tex
   vendor/Python/current/Doc/lib/libunittest.tex
   vendor/Python/current/Doc/lib/libunix.tex
   vendor/Python/current/Doc/lib/liburllib.tex
   vendor/Python/current/Doc/lib/liburllib2.tex
   vendor/Python/current/Doc/lib/liburlparse.tex
   vendor/Python/current/Doc/lib/libuser.tex
   vendor/Python/current/Doc/lib/libuserdict.tex
   vendor/Python/current/Doc/lib/libuu.tex
   vendor/Python/current/Doc/lib/libuuid.tex
   vendor/Python/current/Doc/lib/libwarnings.tex
   vendor/Python/current/Doc/lib/libwave.tex
   vendor/Python/current/Doc/lib/libweakref.tex
   vendor/Python/current/Doc/lib/libwebbrowser.tex
   vendor/Python/current/Doc/lib/libwhichdb.tex
   vendor/Python/current/Doc/lib/libwinreg.tex
   vendor/Python/current/Doc/lib/libwinsound.tex
   vendor/Python/current/Doc/lib/libwsgiref.tex
   vendor/Python/current/Doc/lib/libxdrlib.tex
   vendor/Python/current/Doc/lib/libxmllib.tex
   vendor/Python/current/Doc/lib/libxmlrpclib.tex
   vendor/Python/current/Doc/lib/libzipfile.tex
   vendor/Python/current/Doc/lib/libzipimport.tex
   vendor/Python/current/Doc/lib/libzlib.tex
   vendor/Python/current/Doc/lib/markup.tex
   vendor/Python/current/Doc/lib/mimelib.tex
   vendor/Python/current/Doc/lib/minidom-example.py
   vendor/Python/current/Doc/lib/modules.tex
   vendor/Python/current/Doc/lib/netdata.tex
   vendor/Python/current/Doc/lib/numeric.tex
   vendor/Python/current/Doc/lib/persistence.tex
   vendor/Python/current/Doc/lib/required_1.py
   vendor/Python/current/Doc/lib/required_2.py
   vendor/Python/current/Doc/lib/sqlite3/
   vendor/Python/current/Doc/lib/sqlite3/adapter_datetime.py
   vendor/Python/current/Doc/lib/sqlite3/adapter_point_1.py
   vendor/Python/current/Doc/lib/sqlite3/adapter_point_2.py
   vendor/Python/current/Doc/lib/sqlite3/collation_reverse.py
   vendor/Python/current/Doc/lib/sqlite3/complete_statement.py
   vendor/Python/current/Doc/lib/sqlite3/connect_db_1.py
   vendor/Python/current/Doc/lib/sqlite3/connect_db_2.py
   vendor/Python/current/Doc/lib/sqlite3/converter_point.py
   vendor/Python/current/Doc/lib/sqlite3/countcursors.py
   vendor/Python/current/Doc/lib/sqlite3/createdb.py
   vendor/Python/current/Doc/lib/sqlite3/execsql_fetchonerow.py
   vendor/Python/current/Doc/lib/sqlite3/execsql_printall_1.py
   vendor/Python/current/Doc/lib/sqlite3/execute_1.py
   vendor/Python/current/Doc/lib/sqlite3/execute_2.py
   vendor/Python/current/Doc/lib/sqlite3/execute_3.py
   vendor/Python/current/Doc/lib/sqlite3/executemany_1.py
   vendor/Python/current/Doc/lib/sqlite3/executemany_2.py
   vendor/Python/current/Doc/lib/sqlite3/executescript.py
   vendor/Python/current/Doc/lib/sqlite3/insert_more_people.py
   vendor/Python/current/Doc/lib/sqlite3/md5func.py
   vendor/Python/current/Doc/lib/sqlite3/mysumaggr.py
   vendor/Python/current/Doc/lib/sqlite3/parse_colnames.py
   vendor/Python/current/Doc/lib/sqlite3/pysqlite_datetime.py
   vendor/Python/current/Doc/lib/sqlite3/row_factory.py
   vendor/Python/current/Doc/lib/sqlite3/rowclass.py
   vendor/Python/current/Doc/lib/sqlite3/shared_cache.py
   vendor/Python/current/Doc/lib/sqlite3/shortcut_methods.py
   vendor/Python/current/Doc/lib/sqlite3/simple_tableprinter.py
   vendor/Python/current/Doc/lib/sqlite3/text_factory.py
   vendor/Python/current/Doc/lib/tkinter.tex
   vendor/Python/current/Doc/lib/tzinfo-examples.py
   vendor/Python/current/Doc/lib/windows.tex
   vendor/Python/current/Doc/lib/xmldom.tex
   vendor/Python/current/Doc/lib/xmldomminidom.tex
   vendor/Python/current/Doc/lib/xmldompulldom.tex
   vendor/Python/current/Doc/lib/xmletree.tex
   vendor/Python/current/Doc/lib/xmlsax.tex
   vendor/Python/current/Doc/lib/xmlsaxhandler.tex
   vendor/Python/current/Doc/lib/xmlsaxreader.tex
   vendor/Python/current/Doc/lib/xmlsaxutils.tex
   vendor/Python/current/Doc/mac/
   vendor/Python/current/Doc/mac/libaepack.tex
   vendor/Python/current/Doc/mac/libaetools.tex
   vendor/Python/current/Doc/mac/libaetypes.tex
   vendor/Python/current/Doc/mac/libautogil.tex
   vendor/Python/current/Doc/mac/libcolorpicker.tex
   vendor/Python/current/Doc/mac/libframework.tex
   vendor/Python/current/Doc/mac/libgensuitemodule.tex
   vendor/Python/current/Doc/mac/libmac.tex
   vendor/Python/current/Doc/mac/libmacfs.tex
   vendor/Python/current/Doc/mac/libmacic.tex
   vendor/Python/current/Doc/mac/libmacos.tex
   vendor/Python/current/Doc/mac/libmacostools.tex
   vendor/Python/current/Doc/mac/libmacui.tex
   vendor/Python/current/Doc/mac/libminiae.tex
   vendor/Python/current/Doc/mac/libscrap.tex
   vendor/Python/current/Doc/mac/mac.tex
   vendor/Python/current/Doc/mac/scripting.tex
   vendor/Python/current/Doc/mac/toolbox.tex
   vendor/Python/current/Doc/mac/undoc.tex
   vendor/Python/current/Doc/mac/using.tex
   vendor/Python/current/Doc/paper-a4/
   vendor/Python/current/Doc/paper-a4/pypaper.sty
   vendor/Python/current/Doc/paper-letter/
   vendor/Python/current/Doc/perl/
   vendor/Python/current/Doc/perl/SynopsisTable.pm
   vendor/Python/current/Doc/perl/distutils.perl
   vendor/Python/current/Doc/perl/howto.perl
   vendor/Python/current/Doc/perl/isilo.perl
   vendor/Python/current/Doc/perl/l2hinit.perl
   vendor/Python/current/Doc/perl/ltxmarkup.perl
   vendor/Python/current/Doc/perl/manual.perl
   vendor/Python/current/Doc/perl/python.perl
   vendor/Python/current/Doc/python-docs.txt
   vendor/Python/current/Doc/ref/
   vendor/Python/current/Doc/ref/ref.tex
   vendor/Python/current/Doc/ref/ref1.tex
   vendor/Python/current/Doc/ref/ref2.tex
   vendor/Python/current/Doc/ref/ref3.tex
   vendor/Python/current/Doc/ref/ref4.tex
   vendor/Python/current/Doc/ref/ref5.tex
   vendor/Python/current/Doc/ref/ref6.tex
   vendor/Python/current/Doc/ref/ref7.tex
   vendor/Python/current/Doc/ref/ref8.tex
   vendor/Python/current/Doc/ref/reswords.py
   vendor/Python/current/Doc/templates/
   vendor/Python/current/Doc/templates/howto.tex
   vendor/Python/current/Doc/templates/manual.tex
   vendor/Python/current/Doc/templates/module.tex
   vendor/Python/current/Doc/templates/whatsnewXY.tex
   vendor/Python/current/Doc/tests/
   vendor/Python/current/Doc/tests/math.tex
   vendor/Python/current/Doc/texinputs/
   vendor/Python/current/Doc/texinputs/distutils.sty
   vendor/Python/current/Doc/texinputs/fancyhdr.sty
   vendor/Python/current/Doc/texinputs/fncychap.sty
   vendor/Python/current/Doc/texinputs/howto.cls
   vendor/Python/current/Doc/texinputs/ltxmarkup.sty
   vendor/Python/current/Doc/texinputs/manual.cls
   vendor/Python/current/Doc/texinputs/pypaper.sty
   vendor/Python/current/Doc/texinputs/python.ist
   vendor/Python/current/Doc/texinputs/python.sty
   vendor/Python/current/Doc/texinputs/underscore.sty
   vendor/Python/current/Doc/tools/
   vendor/Python/current/Doc/tools/anno-api.py
   vendor/Python/current/Doc/tools/buildindex.py
   vendor/Python/current/Doc/tools/checkargs.pm
   vendor/Python/current/Doc/tools/cklatex
   vendor/Python/current/Doc/tools/cmpcsyms
   vendor/Python/current/Doc/tools/custlib.py
   vendor/Python/current/Doc/tools/findcsyms
   vendor/Python/current/Doc/tools/findmodrefs
   vendor/Python/current/Doc/tools/findsyms
   vendor/Python/current/Doc/tools/fix_hack
   vendor/Python/current/Doc/tools/fix_libaux.sed
   vendor/Python/current/Doc/tools/fixinfo.el
   vendor/Python/current/Doc/tools/getpagecounts
   vendor/Python/current/Doc/tools/getversioninfo
   vendor/Python/current/Doc/tools/html2texi.pl
   vendor/Python/current/Doc/tools/indfix.py
   vendor/Python/current/Doc/tools/keywords.py
   vendor/Python/current/Doc/tools/listmodules
   vendor/Python/current/Doc/tools/listmodules.py
   vendor/Python/current/Doc/tools/makesec.sh
   vendor/Python/current/Doc/tools/mkackshtml
   vendor/Python/current/Doc/tools/mkhowto
   vendor/Python/current/Doc/tools/mkinfo
   vendor/Python/current/Doc/tools/mkmodindex
   vendor/Python/current/Doc/tools/mkpkglist
   vendor/Python/current/Doc/tools/mksourcepkg
   vendor/Python/current/Doc/tools/node2label.pl
   vendor/Python/current/Doc/tools/prechm.py
   vendor/Python/current/Doc/tools/push-docs.sh
   vendor/Python/current/Doc/tools/py2texi.el
   vendor/Python/current/Doc/tools/refcounts.py
   vendor/Python/current/Doc/tools/rewrite.py
   vendor/Python/current/Doc/tools/sgmlconv/
   vendor/Python/current/Doc/tools/sgmlconv/README
   vendor/Python/current/Doc/tools/sgmlconv/conversion.xml
   vendor/Python/current/Doc/tools/sgmlconv/docfixer.py
   vendor/Python/current/Doc/tools/sgmlconv/esis2sgml.py
   vendor/Python/current/Doc/tools/sgmlconv/esistools.py
   vendor/Python/current/Doc/tools/sgmlconv/latex2esis.py
   vendor/Python/current/Doc/tools/sgmlconv/make.rules
   vendor/Python/current/Doc/tools/support.py
   vendor/Python/current/Doc/tools/toc2bkm.py
   vendor/Python/current/Doc/tools/undoc_symbols.py
   vendor/Python/current/Doc/tools/update-docs.sh
   vendor/Python/current/Doc/tools/whichlibs
   vendor/Python/current/Doc/tut/
   vendor/Python/current/Doc/tut/glossary.tex
   vendor/Python/current/Doc/tut/tut.tex
   vendor/Python/current/Doc/whatsnew/
   vendor/Python/current/Doc/whatsnew/whatsnew20.tex
   vendor/Python/current/Doc/whatsnew/whatsnew21.tex
   vendor/Python/current/Doc/whatsnew/whatsnew22.tex
   vendor/Python/current/Doc/whatsnew/whatsnew23.tex
   vendor/Python/current/Doc/whatsnew/whatsnew24.tex
   vendor/Python/current/Doc/whatsnew/whatsnew25.tex
   vendor/Python/current/Grammar/
   vendor/Python/current/Grammar/Grammar
   vendor/Python/current/Include/
   vendor/Python/current/Include/Python-ast.h
   vendor/Python/current/Include/Python.h
   vendor/Python/current/Include/abstract.h
   vendor/Python/current/Include/asdl.h
   vendor/Python/current/Include/ast.h
   vendor/Python/current/Include/bitset.h
   vendor/Python/current/Include/boolobject.h
   vendor/Python/current/Include/bufferobject.h
   vendor/Python/current/Include/cStringIO.h
   vendor/Python/current/Include/cellobject.h
   vendor/Python/current/Include/ceval.h
   vendor/Python/current/Include/classobject.h
   vendor/Python/current/Include/cobject.h
   vendor/Python/current/Include/code.h
   vendor/Python/current/Include/codecs.h
   vendor/Python/current/Include/compile.h
   vendor/Python/current/Include/complexobject.h
   vendor/Python/current/Include/datetime.h
   vendor/Python/current/Include/descrobject.h
   vendor/Python/current/Include/dictobject.h
   vendor/Python/current/Include/enumobject.h
   vendor/Python/current/Include/errcode.h
   vendor/Python/current/Include/eval.h
   vendor/Python/current/Include/fileobject.h
   vendor/Python/current/Include/floatobject.h
   vendor/Python/current/Include/frameobject.h
   vendor/Python/current/Include/funcobject.h
   vendor/Python/current/Include/genobject.h
   vendor/Python/current/Include/graminit.h
   vendor/Python/current/Include/grammar.h
   vendor/Python/current/Include/import.h
   vendor/Python/current/Include/intobject.h
   vendor/Python/current/Include/intrcheck.h
   vendor/Python/current/Include/iterobject.h
   vendor/Python/current/Include/listobject.h
   vendor/Python/current/Include/longintrepr.h
   vendor/Python/current/Include/longobject.h
   vendor/Python/current/Include/marshal.h
   vendor/Python/current/Include/metagrammar.h
   vendor/Python/current/Include/methodobject.h
   vendor/Python/current/Include/modsupport.h
   vendor/Python/current/Include/moduleobject.h
   vendor/Python/current/Include/node.h
   vendor/Python/current/Include/object.h
   vendor/Python/current/Include/objimpl.h
   vendor/Python/current/Include/opcode.h
   vendor/Python/current/Include/osdefs.h
   vendor/Python/current/Include/parsetok.h
   vendor/Python/current/Include/patchlevel.h
   vendor/Python/current/Include/pgen.h
   vendor/Python/current/Include/pgenheaders.h
   vendor/Python/current/Include/py_curses.h
   vendor/Python/current/Include/pyarena.h
   vendor/Python/current/Include/pydebug.h
   vendor/Python/current/Include/pyerrors.h
   vendor/Python/current/Include/pyexpat.h
   vendor/Python/current/Include/pyfpe.h
   vendor/Python/current/Include/pygetopt.h
   vendor/Python/current/Include/pymactoolbox.h
   vendor/Python/current/Include/pymem.h
   vendor/Python/current/Include/pyport.h
   vendor/Python/current/Include/pystate.h
   vendor/Python/current/Include/pystrtod.h
   vendor/Python/current/Include/pythonrun.h
   vendor/Python/current/Include/pythread.h
   vendor/Python/current/Include/rangeobject.h
   vendor/Python/current/Include/setobject.h
   vendor/Python/current/Include/sliceobject.h
   vendor/Python/current/Include/stringobject.h
   vendor/Python/current/Include/structmember.h
   vendor/Python/current/Include/structseq.h
   vendor/Python/current/Include/symtable.h
   vendor/Python/current/Include/sysmodule.h
   vendor/Python/current/Include/timefuncs.h
   vendor/Python/current/Include/token.h
   vendor/Python/current/Include/traceback.h
   vendor/Python/current/Include/tupleobject.h
   vendor/Python/current/Include/ucnhash.h
   vendor/Python/current/Include/unicodeobject.h
   vendor/Python/current/Include/weakrefobject.h
   vendor/Python/current/LICENSE
   vendor/Python/current/Lib/
   vendor/Python/current/Lib/BaseHTTPServer.py
   vendor/Python/current/Lib/Bastion.py
   vendor/Python/current/Lib/CGIHTTPServer.py
   vendor/Python/current/Lib/ConfigParser.py
   vendor/Python/current/Lib/Cookie.py
   vendor/Python/current/Lib/DocXMLRPCServer.py
   vendor/Python/current/Lib/HTMLParser.py
   vendor/Python/current/Lib/MimeWriter.py
   vendor/Python/current/Lib/Queue.py
   vendor/Python/current/Lib/SimpleHTTPServer.py
   vendor/Python/current/Lib/SimpleXMLRPCServer.py
   vendor/Python/current/Lib/SocketServer.py
   vendor/Python/current/Lib/StringIO.py
   vendor/Python/current/Lib/UserDict.py
   vendor/Python/current/Lib/UserList.py
   vendor/Python/current/Lib/UserString.py
   vendor/Python/current/Lib/_LWPCookieJar.py
   vendor/Python/current/Lib/_MozillaCookieJar.py
   vendor/Python/current/Lib/__future__.py
   vendor/Python/current/Lib/__phello__.foo.py
   vendor/Python/current/Lib/_strptime.py
   vendor/Python/current/Lib/_threading_local.py
   vendor/Python/current/Lib/aifc.py
   vendor/Python/current/Lib/anydbm.py
   vendor/Python/current/Lib/asynchat.py
   vendor/Python/current/Lib/asyncore.py
   vendor/Python/current/Lib/atexit.py
   vendor/Python/current/Lib/audiodev.py
   vendor/Python/current/Lib/base64.py
   vendor/Python/current/Lib/bdb.py
   vendor/Python/current/Lib/binhex.py
   vendor/Python/current/Lib/bisect.py
   vendor/Python/current/Lib/bsddb/
   vendor/Python/current/Lib/bsddb/__init__.py
   vendor/Python/current/Lib/bsddb/db.py
   vendor/Python/current/Lib/bsddb/dbobj.py
   vendor/Python/current/Lib/bsddb/dbrecio.py
   vendor/Python/current/Lib/bsddb/dbshelve.py
   vendor/Python/current/Lib/bsddb/dbtables.py
   vendor/Python/current/Lib/bsddb/dbutils.py
   vendor/Python/current/Lib/bsddb/test/
   vendor/Python/current/Lib/bsddb/test/__init__.py
   vendor/Python/current/Lib/bsddb/test/test_1413192.py
   vendor/Python/current/Lib/bsddb/test/test_all.py
   vendor/Python/current/Lib/bsddb/test/test_associate.py
   vendor/Python/current/Lib/bsddb/test/test_basics.py
   vendor/Python/current/Lib/bsddb/test/test_compare.py
   vendor/Python/current/Lib/bsddb/test/test_compat.py
   vendor/Python/current/Lib/bsddb/test/test_cursor_pget_bug.py
   vendor/Python/current/Lib/bsddb/test/test_dbobj.py
   vendor/Python/current/Lib/bsddb/test/test_dbshelve.py
   vendor/Python/current/Lib/bsddb/test/test_dbtables.py
   vendor/Python/current/Lib/bsddb/test/test_env_close.py
   vendor/Python/current/Lib/bsddb/test/test_get_none.py
   vendor/Python/current/Lib/bsddb/test/test_join.py
   vendor/Python/current/Lib/bsddb/test/test_lock.py
   vendor/Python/current/Lib/bsddb/test/test_misc.py
   vendor/Python/current/Lib/bsddb/test/test_pickle.py
   vendor/Python/current/Lib/bsddb/test/test_queue.py
   vendor/Python/current/Lib/bsddb/test/test_recno.py
   vendor/Python/current/Lib/bsddb/test/test_sequence.py
   vendor/Python/current/Lib/bsddb/test/test_thread.py
   vendor/Python/current/Lib/cProfile.py
   vendor/Python/current/Lib/calendar.py
   vendor/Python/current/Lib/cgi.py
   vendor/Python/current/Lib/cgitb.py
   vendor/Python/current/Lib/chunk.py
   vendor/Python/current/Lib/cmd.py
   vendor/Python/current/Lib/code.py
   vendor/Python/current/Lib/codecs.py
   vendor/Python/current/Lib/codeop.py
   vendor/Python/current/Lib/colorsys.py
   vendor/Python/current/Lib/commands.py
   vendor/Python/current/Lib/compileall.py
   vendor/Python/current/Lib/compiler/
   vendor/Python/current/Lib/compiler/__init__.py
   vendor/Python/current/Lib/compiler/ast.py
   vendor/Python/current/Lib/compiler/consts.py
   vendor/Python/current/Lib/compiler/future.py
   vendor/Python/current/Lib/compiler/misc.py
   vendor/Python/current/Lib/compiler/pyassem.py
   vendor/Python/current/Lib/compiler/pycodegen.py
   vendor/Python/current/Lib/compiler/symbols.py
   vendor/Python/current/Lib/compiler/syntax.py
   vendor/Python/current/Lib/compiler/transformer.py
   vendor/Python/current/Lib/compiler/visitor.py
   vendor/Python/current/Lib/contextlib.py
   vendor/Python/current/Lib/cookielib.py
   vendor/Python/current/Lib/copy.py
   vendor/Python/current/Lib/copy_reg.py
   vendor/Python/current/Lib/csv.py
   vendor/Python/current/Lib/ctypes/
   vendor/Python/current/Lib/ctypes/__init__.py
   vendor/Python/current/Lib/ctypes/_endian.py
   vendor/Python/current/Lib/ctypes/macholib/
   vendor/Python/current/Lib/ctypes/macholib/README.ctypes
   vendor/Python/current/Lib/ctypes/macholib/__init__.py
   vendor/Python/current/Lib/ctypes/macholib/dyld.py
   vendor/Python/current/Lib/ctypes/macholib/dylib.py
   vendor/Python/current/Lib/ctypes/macholib/fetch_macholib
   vendor/Python/current/Lib/ctypes/macholib/fetch_macholib.bat
   vendor/Python/current/Lib/ctypes/macholib/framework.py
   vendor/Python/current/Lib/ctypes/test/
   vendor/Python/current/Lib/ctypes/test/__init__.py
   vendor/Python/current/Lib/ctypes/test/runtests.py
   vendor/Python/current/Lib/ctypes/test/test_anon.py
   vendor/Python/current/Lib/ctypes/test/test_array_in_pointer.py
   vendor/Python/current/Lib/ctypes/test/test_arrays.py
   vendor/Python/current/Lib/ctypes/test/test_as_parameter.py
   vendor/Python/current/Lib/ctypes/test/test_bitfields.py
   vendor/Python/current/Lib/ctypes/test/test_buffers.py
   vendor/Python/current/Lib/ctypes/test/test_byteswap.py
   vendor/Python/current/Lib/ctypes/test/test_callbacks.py
   vendor/Python/current/Lib/ctypes/test/test_cast.py
   vendor/Python/current/Lib/ctypes/test/test_cfuncs.py
   vendor/Python/current/Lib/ctypes/test/test_checkretval.py
   vendor/Python/current/Lib/ctypes/test/test_errcheck.py
   vendor/Python/current/Lib/ctypes/test/test_find.py
   vendor/Python/current/Lib/ctypes/test/test_funcptr.py
   vendor/Python/current/Lib/ctypes/test/test_functions.py
   vendor/Python/current/Lib/ctypes/test/test_incomplete.py
   vendor/Python/current/Lib/ctypes/test/test_init.py
   vendor/Python/current/Lib/ctypes/test/test_integers.py
   vendor/Python/current/Lib/ctypes/test/test_internals.py
   vendor/Python/current/Lib/ctypes/test/test_keeprefs.py
   vendor/Python/current/Lib/ctypes/test/test_libc.py
   vendor/Python/current/Lib/ctypes/test/test_loading.py
   vendor/Python/current/Lib/ctypes/test/test_macholib.py
   vendor/Python/current/Lib/ctypes/test/test_memfunctions.py
   vendor/Python/current/Lib/ctypes/test/test_numbers.py
   vendor/Python/current/Lib/ctypes/test/test_objects.py
   vendor/Python/current/Lib/ctypes/test/test_parameters.py
   vendor/Python/current/Lib/ctypes/test/test_pointers.py
   vendor/Python/current/Lib/ctypes/test/test_prototypes.py
   vendor/Python/current/Lib/ctypes/test/test_python_api.py
   vendor/Python/current/Lib/ctypes/test/test_random_things.py
   vendor/Python/current/Lib/ctypes/test/test_refcounts.py
   vendor/Python/current/Lib/ctypes/test/test_repr.py
   vendor/Python/current/Lib/ctypes/test/test_returnfuncptrs.py
   vendor/Python/current/Lib/ctypes/test/test_simplesubclasses.py
   vendor/Python/current/Lib/ctypes/test/test_sizes.py
   vendor/Python/current/Lib/ctypes/test/test_slicing.py
   vendor/Python/current/Lib/ctypes/test/test_stringptr.py
   vendor/Python/current/Lib/ctypes/test/test_strings.py
   vendor/Python/current/Lib/ctypes/test/test_struct_fields.py
   vendor/Python/current/Lib/ctypes/test/test_structures.py
   vendor/Python/current/Lib/ctypes/test/test_unaligned_structures.py
   vendor/Python/current/Lib/ctypes/test/test_unicode.py
   vendor/Python/current/Lib/ctypes/test/test_values.py
   vendor/Python/current/Lib/ctypes/test/test_varsize_struct.py
   vendor/Python/current/Lib/ctypes/test/test_win32.py
   vendor/Python/current/Lib/ctypes/util.py
   vendor/Python/current/Lib/ctypes/wintypes.py
   vendor/Python/current/Lib/curses/
   vendor/Python/current/Lib/curses/__init__.py
   vendor/Python/current/Lib/curses/ascii.py
   vendor/Python/current/Lib/curses/has_key.py
   vendor/Python/current/Lib/curses/panel.py
   vendor/Python/current/Lib/curses/textpad.py
   vendor/Python/current/Lib/curses/wrapper.py
   vendor/Python/current/Lib/dbhash.py
   vendor/Python/current/Lib/decimal.py
   vendor/Python/current/Lib/difflib.py
   vendor/Python/current/Lib/dircache.py
   vendor/Python/current/Lib/dis.py
   vendor/Python/current/Lib/distutils/
   vendor/Python/current/Lib/distutils/README
   vendor/Python/current/Lib/distutils/__init__.py
   vendor/Python/current/Lib/distutils/archive_util.py
   vendor/Python/current/Lib/distutils/bcppcompiler.py
   vendor/Python/current/Lib/distutils/ccompiler.py
   vendor/Python/current/Lib/distutils/cmd.py
   vendor/Python/current/Lib/distutils/command/
   vendor/Python/current/Lib/distutils/command/__init__.py
   vendor/Python/current/Lib/distutils/command/bdist.py
   vendor/Python/current/Lib/distutils/command/bdist_dumb.py
   vendor/Python/current/Lib/distutils/command/bdist_msi.py
   vendor/Python/current/Lib/distutils/command/bdist_rpm.py
   vendor/Python/current/Lib/distutils/command/bdist_wininst.py
   vendor/Python/current/Lib/distutils/command/build.py
   vendor/Python/current/Lib/distutils/command/build_clib.py
   vendor/Python/current/Lib/distutils/command/build_ext.py
   vendor/Python/current/Lib/distutils/command/build_py.py
   vendor/Python/current/Lib/distutils/command/build_scripts.py
   vendor/Python/current/Lib/distutils/command/clean.py
   vendor/Python/current/Lib/distutils/command/command_template
   vendor/Python/current/Lib/distutils/command/config.py
   vendor/Python/current/Lib/distutils/command/install.py
   vendor/Python/current/Lib/distutils/command/install_data.py
   vendor/Python/current/Lib/distutils/command/install_egg_info.py
   vendor/Python/current/Lib/distutils/command/install_headers.py
   vendor/Python/current/Lib/distutils/command/install_lib.py
   vendor/Python/current/Lib/distutils/command/install_scripts.py
   vendor/Python/current/Lib/distutils/command/register.py
   vendor/Python/current/Lib/distutils/command/sdist.py
   vendor/Python/current/Lib/distutils/command/upload.py
   vendor/Python/current/Lib/distutils/command/wininst-6.exe
   vendor/Python/current/Lib/distutils/command/wininst-7.1.exe
   vendor/Python/current/Lib/distutils/core.py
   vendor/Python/current/Lib/distutils/cygwinccompiler.py
   vendor/Python/current/Lib/distutils/debug.py
   vendor/Python/current/Lib/distutils/dep_util.py
   vendor/Python/current/Lib/distutils/dir_util.py
   vendor/Python/current/Lib/distutils/dist.py
   vendor/Python/current/Lib/distutils/emxccompiler.py
   vendor/Python/current/Lib/distutils/errors.py
   vendor/Python/current/Lib/distutils/extension.py
   vendor/Python/current/Lib/distutils/fancy_getopt.py
   vendor/Python/current/Lib/distutils/file_util.py
   vendor/Python/current/Lib/distutils/filelist.py
   vendor/Python/current/Lib/distutils/log.py
   vendor/Python/current/Lib/distutils/msvccompiler.py
   vendor/Python/current/Lib/distutils/mwerkscompiler.py
   vendor/Python/current/Lib/distutils/spawn.py
   vendor/Python/current/Lib/distutils/sysconfig.py
   vendor/Python/current/Lib/distutils/tests/
   vendor/Python/current/Lib/distutils/tests/__init__.py
   vendor/Python/current/Lib/distutils/tests/support.py
   vendor/Python/current/Lib/distutils/tests/test_build_py.py
   vendor/Python/current/Lib/distutils/tests/test_build_scripts.py
   vendor/Python/current/Lib/distutils/tests/test_dist.py
   vendor/Python/current/Lib/distutils/tests/test_install.py
   vendor/Python/current/Lib/distutils/tests/test_install_scripts.py
   vendor/Python/current/Lib/distutils/tests/test_versionpredicate.py
   vendor/Python/current/Lib/distutils/text_file.py
   vendor/Python/current/Lib/distutils/unixccompiler.py
   vendor/Python/current/Lib/distutils/util.py
   vendor/Python/current/Lib/distutils/version.py
   vendor/Python/current/Lib/distutils/versionpredicate.py
   vendor/Python/current/Lib/doctest.py
   vendor/Python/current/Lib/dumbdbm.py
   vendor/Python/current/Lib/dummy_thread.py
   vendor/Python/current/Lib/dummy_threading.py
   vendor/Python/current/Lib/email/
   vendor/Python/current/Lib/email/__init__.py
   vendor/Python/current/Lib/email/_parseaddr.py
   vendor/Python/current/Lib/email/base64mime.py
   vendor/Python/current/Lib/email/charset.py
   vendor/Python/current/Lib/email/encoders.py
   vendor/Python/current/Lib/email/errors.py
   vendor/Python/current/Lib/email/feedparser.py
   vendor/Python/current/Lib/email/generator.py
   vendor/Python/current/Lib/email/header.py
   vendor/Python/current/Lib/email/iterators.py
   vendor/Python/current/Lib/email/message.py
   vendor/Python/current/Lib/email/mime/
   vendor/Python/current/Lib/email/mime/__init__.py
   vendor/Python/current/Lib/email/mime/application.py
   vendor/Python/current/Lib/email/mime/audio.py
   vendor/Python/current/Lib/email/mime/base.py
   vendor/Python/current/Lib/email/mime/image.py
   vendor/Python/current/Lib/email/mime/message.py
   vendor/Python/current/Lib/email/mime/multipart.py
   vendor/Python/current/Lib/email/mime/nonmultipart.py
   vendor/Python/current/Lib/email/mime/text.py
   vendor/Python/current/Lib/email/parser.py
   vendor/Python/current/Lib/email/quoprimime.py
   vendor/Python/current/Lib/email/test/
   vendor/Python/current/Lib/email/test/__init__.py
   vendor/Python/current/Lib/email/test/data/
   vendor/Python/current/Lib/email/test/data/PyBanner048.gif
   vendor/Python/current/Lib/email/test/data/audiotest.au
   vendor/Python/current/Lib/email/test/data/msg_01.txt
   vendor/Python/current/Lib/email/test/data/msg_02.txt
   vendor/Python/current/Lib/email/test/data/msg_03.txt
   vendor/Python/current/Lib/email/test/data/msg_04.txt
   vendor/Python/current/Lib/email/test/data/msg_05.txt
   vendor/Python/current/Lib/email/test/data/msg_06.txt
   vendor/Python/current/Lib/email/test/data/msg_07.txt
   vendor/Python/current/Lib/email/test/data/msg_08.txt
   vendor/Python/current/Lib/email/test/data/msg_09.txt
   vendor/Python/current/Lib/email/test/data/msg_10.txt
   vendor/Python/current/Lib/email/test/data/msg_11.txt
   vendor/Python/current/Lib/email/test/data/msg_12.txt
   vendor/Python/current/Lib/email/test/data/msg_12a.txt
   vendor/Python/current/Lib/email/test/data/msg_13.txt
   vendor/Python/current/Lib/email/test/data/msg_14.txt
   vendor/Python/current/Lib/email/test/data/msg_15.txt
   vendor/Python/current/Lib/email/test/data/msg_16.txt
   vendor/Python/current/Lib/email/test/data/msg_17.txt
   vendor/Python/current/Lib/email/test/data/msg_18.txt
   vendor/Python/current/Lib/email/test/data/msg_19.txt
   vendor/Python/current/Lib/email/test/data/msg_20.txt
   vendor/Python/current/Lib/email/test/data/msg_21.txt
   vendor/Python/current/Lib/email/test/data/msg_22.txt
   vendor/Python/current/Lib/email/test/data/msg_23.txt
   vendor/Python/current/Lib/email/test/data/msg_24.txt
   vendor/Python/current/Lib/email/test/data/msg_25.txt
   vendor/Python/current/Lib/email/test/data/msg_26.txt
   vendor/Python/current/Lib/email/test/data/msg_27.txt
   vendor/Python/current/Lib/email/test/data/msg_28.txt
   vendor/Python/current/Lib/email/test/data/msg_29.txt
   vendor/Python/current/Lib/email/test/data/msg_30.txt
   vendor/Python/current/Lib/email/test/data/msg_31.txt
   vendor/Python/current/Lib/email/test/data/msg_32.txt
   vendor/Python/current/Lib/email/test/data/msg_33.txt
   vendor/Python/current/Lib/email/test/data/msg_34.txt
   vendor/Python/current/Lib/email/test/data/msg_35.txt
   vendor/Python/current/Lib/email/test/data/msg_36.txt
   vendor/Python/current/Lib/email/test/data/msg_37.txt
   vendor/Python/current/Lib/email/test/data/msg_38.txt
   vendor/Python/current/Lib/email/test/data/msg_39.txt
   vendor/Python/current/Lib/email/test/data/msg_40.txt
   vendor/Python/current/Lib/email/test/data/msg_41.txt
   vendor/Python/current/Lib/email/test/data/msg_42.txt
   vendor/Python/current/Lib/email/test/data/msg_43.txt
   vendor/Python/current/Lib/email/test/data/msg_44.txt
   vendor/Python/current/Lib/email/test/test_email.py
   vendor/Python/current/Lib/email/test/test_email_codecs.py
   vendor/Python/current/Lib/email/test/test_email_codecs_renamed.py
   vendor/Python/current/Lib/email/test/test_email_renamed.py
   vendor/Python/current/Lib/email/test/test_email_torture.py
   vendor/Python/current/Lib/email/utils.py
   vendor/Python/current/Lib/encodings/
   vendor/Python/current/Lib/encodings/__init__.py
   vendor/Python/current/Lib/encodings/aliases.py
   vendor/Python/current/Lib/encodings/ascii.py
   vendor/Python/current/Lib/encodings/base64_codec.py
   vendor/Python/current/Lib/encodings/big5.py
   vendor/Python/current/Lib/encodings/big5hkscs.py
   vendor/Python/current/Lib/encodings/bz2_codec.py
   vendor/Python/current/Lib/encodings/charmap.py
   vendor/Python/current/Lib/encodings/cp037.py
   vendor/Python/current/Lib/encodings/cp1006.py
   vendor/Python/current/Lib/encodings/cp1026.py
   vendor/Python/current/Lib/encodings/cp1140.py
   vendor/Python/current/Lib/encodings/cp1250.py
   vendor/Python/current/Lib/encodings/cp1251.py
   vendor/Python/current/Lib/encodings/cp1252.py
   vendor/Python/current/Lib/encodings/cp1253.py
   vendor/Python/current/Lib/encodings/cp1254.py
   vendor/Python/current/Lib/encodings/cp1255.py
   vendor/Python/current/Lib/encodings/cp1256.py
   vendor/Python/current/Lib/encodings/cp1257.py
   vendor/Python/current/Lib/encodings/cp1258.py
   vendor/Python/current/Lib/encodings/cp424.py
   vendor/Python/current/Lib/encodings/cp437.py
   vendor/Python/current/Lib/encodings/cp500.py
   vendor/Python/current/Lib/encodings/cp737.py
   vendor/Python/current/Lib/encodings/cp775.py
   vendor/Python/current/Lib/encodings/cp850.py
   vendor/Python/current/Lib/encodings/cp852.py
   vendor/Python/current/Lib/encodings/cp855.py
   vendor/Python/current/Lib/encodings/cp856.py
   vendor/Python/current/Lib/encodings/cp857.py
   vendor/Python/current/Lib/encodings/cp860.py
   vendor/Python/current/Lib/encodings/cp861.py
   vendor/Python/current/Lib/encodings/cp862.py
   vendor/Python/current/Lib/encodings/cp863.py
   vendor/Python/current/Lib/encodings/cp864.py
   vendor/Python/current/Lib/encodings/cp865.py
   vendor/Python/current/Lib/encodings/cp866.py
   vendor/Python/current/Lib/encodings/cp869.py
   vendor/Python/current/Lib/encodings/cp874.py
   vendor/Python/current/Lib/encodings/cp875.py
   vendor/Python/current/Lib/encodings/cp932.py
   vendor/Python/current/Lib/encodings/cp949.py
   vendor/Python/current/Lib/encodings/cp950.py
   vendor/Python/current/Lib/encodings/euc_jis_2004.py
   vendor/Python/current/Lib/encodings/euc_jisx0213.py
   vendor/Python/current/Lib/encodings/euc_jp.py
   vendor/Python/current/Lib/encodings/euc_kr.py
   vendor/Python/current/Lib/encodings/gb18030.py
   vendor/Python/current/Lib/encodings/gb2312.py
   vendor/Python/current/Lib/encodings/gbk.py
   vendor/Python/current/Lib/encodings/hex_codec.py
   vendor/Python/current/Lib/encodings/hp_roman8.py
   vendor/Python/current/Lib/encodings/hz.py
   vendor/Python/current/Lib/encodings/idna.py
   vendor/Python/current/Lib/encodings/iso2022_jp.py
   vendor/Python/current/Lib/encodings/iso2022_jp_1.py
   vendor/Python/current/Lib/encodings/iso2022_jp_2.py
   vendor/Python/current/Lib/encodings/iso2022_jp_2004.py
   vendor/Python/current/Lib/encodings/iso2022_jp_3.py
   vendor/Python/current/Lib/encodings/iso2022_jp_ext.py
   vendor/Python/current/Lib/encodings/iso2022_kr.py
   vendor/Python/current/Lib/encodings/iso8859_1.py
   vendor/Python/current/Lib/encodings/iso8859_10.py
   vendor/Python/current/Lib/encodings/iso8859_11.py
   vendor/Python/current/Lib/encodings/iso8859_13.py
   vendor/Python/current/Lib/encodings/iso8859_14.py
   vendor/Python/current/Lib/encodings/iso8859_15.py
   vendor/Python/current/Lib/encodings/iso8859_16.py
   vendor/Python/current/Lib/encodings/iso8859_2.py
   vendor/Python/current/Lib/encodings/iso8859_3.py
   vendor/Python/current/Lib/encodings/iso8859_4.py
   vendor/Python/current/Lib/encodings/iso8859_5.py
   vendor/Python/current/Lib/encodings/iso8859_6.py
   vendor/Python/current/Lib/encodings/iso8859_7.py
   vendor/Python/current/Lib/encodings/iso8859_8.py
   vendor/Python/current/Lib/encodings/iso8859_9.py
   vendor/Python/current/Lib/encodings/johab.py
   vendor/Python/current/Lib/encodings/koi8_r.py
   vendor/Python/current/Lib/encodings/koi8_u.py
   vendor/Python/current/Lib/encodings/latin_1.py
   vendor/Python/current/Lib/encodings/mac_arabic.py
   vendor/Python/current/Lib/encodings/mac_centeuro.py
   vendor/Python/current/Lib/encodings/mac_croatian.py
   vendor/Python/current/Lib/encodings/mac_cyrillic.py
   vendor/Python/current/Lib/encodings/mac_farsi.py
   vendor/Python/current/Lib/encodings/mac_greek.py
   vendor/Python/current/Lib/encodings/mac_iceland.py
   vendor/Python/current/Lib/encodings/mac_latin2.py
   vendor/Python/current/Lib/encodings/mac_roman.py
   vendor/Python/current/Lib/encodings/mac_romanian.py
   vendor/Python/current/Lib/encodings/mac_turkish.py
   vendor/Python/current/Lib/encodings/mbcs.py
   vendor/Python/current/Lib/encodings/palmos.py
   vendor/Python/current/Lib/encodings/ptcp154.py
   vendor/Python/current/Lib/encodings/punycode.py
   vendor/Python/current/Lib/encodings/quopri_codec.py
   vendor/Python/current/Lib/encodings/raw_unicode_escape.py
   vendor/Python/current/Lib/encodings/rot_13.py
   vendor/Python/current/Lib/encodings/shift_jis.py
   vendor/Python/current/Lib/encodings/shift_jis_2004.py
   vendor/Python/current/Lib/encodings/shift_jisx0213.py
   vendor/Python/current/Lib/encodings/string_escape.py
   vendor/Python/current/Lib/encodings/tis_620.py
   vendor/Python/current/Lib/encodings/undefined.py
   vendor/Python/current/Lib/encodings/unicode_escape.py
   vendor/Python/current/Lib/encodings/unicode_internal.py
   vendor/Python/current/Lib/encodings/utf_16.py
   vendor/Python/current/Lib/encodings/utf_16_be.py
   vendor/Python/current/Lib/encodings/utf_16_le.py
   vendor/Python/current/Lib/encodings/utf_7.py
   vendor/Python/current/Lib/encodings/utf_8.py
   vendor/Python/current/Lib/encodings/utf_8_sig.py
   vendor/Python/current/Lib/encodings/uu_codec.py
   vendor/Python/current/Lib/encodings/zlib_codec.py
   vendor/Python/current/Lib/filecmp.py
   vendor/Python/current/Lib/fileinput.py
   vendor/Python/current/Lib/fnmatch.py
   vendor/Python/current/Lib/formatter.py
   vendor/Python/current/Lib/fpformat.py
   vendor/Python/current/Lib/ftplib.py
   vendor/Python/current/Lib/functools.py
   vendor/Python/current/Lib/getopt.py
   vendor/Python/current/Lib/getpass.py
   vendor/Python/current/Lib/gettext.py
   vendor/Python/current/Lib/glob.py
   vendor/Python/current/Lib/gopherlib.py
   vendor/Python/current/Lib/gzip.py
   vendor/Python/current/Lib/hashlib.py
   vendor/Python/current/Lib/heapq.py
   vendor/Python/current/Lib/hmac.py
   vendor/Python/current/Lib/hotshot/
   vendor/Python/current/Lib/hotshot/__init__.py
   vendor/Python/current/Lib/hotshot/log.py
   vendor/Python/current/Lib/hotshot/stats.py
   vendor/Python/current/Lib/hotshot/stones.py
   vendor/Python/current/Lib/htmlentitydefs.py
   vendor/Python/current/Lib/htmllib.py
   vendor/Python/current/Lib/httplib.py
   vendor/Python/current/Lib/idlelib/
   vendor/Python/current/Lib/idlelib/AutoComplete.py
   vendor/Python/current/Lib/idlelib/AutoCompleteWindow.py
   vendor/Python/current/Lib/idlelib/AutoExpand.py
   vendor/Python/current/Lib/idlelib/Bindings.py
   vendor/Python/current/Lib/idlelib/CREDITS.txt
   vendor/Python/current/Lib/idlelib/CallTipWindow.py
   vendor/Python/current/Lib/idlelib/CallTips.py
   vendor/Python/current/Lib/idlelib/ChangeLog
   vendor/Python/current/Lib/idlelib/ClassBrowser.py
   vendor/Python/current/Lib/idlelib/CodeContext.py
   vendor/Python/current/Lib/idlelib/ColorDelegator.py
   vendor/Python/current/Lib/idlelib/Debugger.py
   vendor/Python/current/Lib/idlelib/Delegator.py
   vendor/Python/current/Lib/idlelib/EditorWindow.py
   vendor/Python/current/Lib/idlelib/FileList.py
   vendor/Python/current/Lib/idlelib/FormatParagraph.py
   vendor/Python/current/Lib/idlelib/GrepDialog.py
   vendor/Python/current/Lib/idlelib/HISTORY.txt
   vendor/Python/current/Lib/idlelib/HyperParser.py
   vendor/Python/current/Lib/idlelib/IOBinding.py
   vendor/Python/current/Lib/idlelib/Icons/
   vendor/Python/current/Lib/idlelib/Icons/folder.gif
   vendor/Python/current/Lib/idlelib/Icons/idle.icns
   vendor/Python/current/Lib/idlelib/Icons/minusnode.gif
   vendor/Python/current/Lib/idlelib/Icons/openfolder.gif
   vendor/Python/current/Lib/idlelib/Icons/plusnode.gif
   vendor/Python/current/Lib/idlelib/Icons/python.gif
   vendor/Python/current/Lib/idlelib/Icons/tk.gif
   vendor/Python/current/Lib/idlelib/IdleHistory.py
   vendor/Python/current/Lib/idlelib/MultiCall.py
   vendor/Python/current/Lib/idlelib/MultiStatusBar.py
   vendor/Python/current/Lib/idlelib/NEWS.txt
   vendor/Python/current/Lib/idlelib/ObjectBrowser.py
   vendor/Python/current/Lib/idlelib/OutputWindow.py
   vendor/Python/current/Lib/idlelib/ParenMatch.py
   vendor/Python/current/Lib/idlelib/PathBrowser.py
   vendor/Python/current/Lib/idlelib/Percolator.py
   vendor/Python/current/Lib/idlelib/PyParse.py
   vendor/Python/current/Lib/idlelib/PyShell.py
   vendor/Python/current/Lib/idlelib/README.txt
   vendor/Python/current/Lib/idlelib/RemoteDebugger.py
   vendor/Python/current/Lib/idlelib/RemoteObjectBrowser.py
   vendor/Python/current/Lib/idlelib/ReplaceDialog.py
   vendor/Python/current/Lib/idlelib/ScriptBinding.py
   vendor/Python/current/Lib/idlelib/ScrolledList.py
   vendor/Python/current/Lib/idlelib/SearchDialog.py
   vendor/Python/current/Lib/idlelib/SearchDialogBase.py
   vendor/Python/current/Lib/idlelib/SearchEngine.py
   vendor/Python/current/Lib/idlelib/StackViewer.py
   vendor/Python/current/Lib/idlelib/TODO.txt
   vendor/Python/current/Lib/idlelib/ToolTip.py
   vendor/Python/current/Lib/idlelib/TreeWidget.py
   vendor/Python/current/Lib/idlelib/UndoDelegator.py
   vendor/Python/current/Lib/idlelib/WidgetRedirector.py
   vendor/Python/current/Lib/idlelib/WindowList.py
   vendor/Python/current/Lib/idlelib/ZoomHeight.py
   vendor/Python/current/Lib/idlelib/__init__.py
   vendor/Python/current/Lib/idlelib/aboutDialog.py
   vendor/Python/current/Lib/idlelib/config-extensions.def
   vendor/Python/current/Lib/idlelib/config-highlight.def
   vendor/Python/current/Lib/idlelib/config-keys.def
   vendor/Python/current/Lib/idlelib/config-main.def
   vendor/Python/current/Lib/idlelib/configDialog.py
   vendor/Python/current/Lib/idlelib/configHandler.py
   vendor/Python/current/Lib/idlelib/configHelpSourceEdit.py
   vendor/Python/current/Lib/idlelib/configSectionNameDialog.py
   vendor/Python/current/Lib/idlelib/dynOptionMenuWidget.py
   vendor/Python/current/Lib/idlelib/extend.txt
   vendor/Python/current/Lib/idlelib/help.txt
   vendor/Python/current/Lib/idlelib/idle.bat
   vendor/Python/current/Lib/idlelib/idle.py
   vendor/Python/current/Lib/idlelib/idle.pyw
   vendor/Python/current/Lib/idlelib/idlever.py
   vendor/Python/current/Lib/idlelib/keybindingDialog.py
   vendor/Python/current/Lib/idlelib/macosxSupport.py
   vendor/Python/current/Lib/idlelib/rpc.py
   vendor/Python/current/Lib/idlelib/run.py
   vendor/Python/current/Lib/idlelib/tabpage.py
   vendor/Python/current/Lib/idlelib/testcode.py
   vendor/Python/current/Lib/idlelib/textView.py
   vendor/Python/current/Lib/ihooks.py
   vendor/Python/current/Lib/imaplib.py
   vendor/Python/current/Lib/imghdr.py
   vendor/Python/current/Lib/imputil.py
   vendor/Python/current/Lib/inspect.py
   vendor/Python/current/Lib/keyword.py
   vendor/Python/current/Lib/lib-old/
   vendor/Python/current/Lib/lib-tk/
   vendor/Python/current/Lib/lib-tk/Canvas.py
   vendor/Python/current/Lib/lib-tk/Dialog.py
   vendor/Python/current/Lib/lib-tk/FileDialog.py
   vendor/Python/current/Lib/lib-tk/FixTk.py
   vendor/Python/current/Lib/lib-tk/ScrolledText.py
   vendor/Python/current/Lib/lib-tk/SimpleDialog.py
   vendor/Python/current/Lib/lib-tk/Tix.py
   vendor/Python/current/Lib/lib-tk/Tkconstants.py
   vendor/Python/current/Lib/lib-tk/Tkdnd.py
   vendor/Python/current/Lib/lib-tk/Tkinter.py
   vendor/Python/current/Lib/lib-tk/tkColorChooser.py
   vendor/Python/current/Lib/lib-tk/tkCommonDialog.py
   vendor/Python/current/Lib/lib-tk/tkFileDialog.py
   vendor/Python/current/Lib/lib-tk/tkFont.py
   vendor/Python/current/Lib/lib-tk/tkMessageBox.py
   vendor/Python/current/Lib/lib-tk/tkSimpleDialog.py
   vendor/Python/current/Lib/lib-tk/turtle.py
   vendor/Python/current/Lib/linecache.py
   vendor/Python/current/Lib/locale.py
   vendor/Python/current/Lib/logging/
   vendor/Python/current/Lib/logging/__init__.py
   vendor/Python/current/Lib/logging/config.py
   vendor/Python/current/Lib/logging/handlers.py
   vendor/Python/current/Lib/macpath.py
   vendor/Python/current/Lib/macurl2path.py
   vendor/Python/current/Lib/mailbox.py
   vendor/Python/current/Lib/mailcap.py
   vendor/Python/current/Lib/markupbase.py
   vendor/Python/current/Lib/md5.py
   vendor/Python/current/Lib/mhlib.py
   vendor/Python/current/Lib/mimetools.py
   vendor/Python/current/Lib/mimetypes.py
   vendor/Python/current/Lib/mimify.py
   vendor/Python/current/Lib/modulefinder.py
   vendor/Python/current/Lib/msilib/
   vendor/Python/current/Lib/msilib/__init__.py
   vendor/Python/current/Lib/msilib/schema.py
   vendor/Python/current/Lib/msilib/sequence.py
   vendor/Python/current/Lib/msilib/text.py
   vendor/Python/current/Lib/multifile.py
   vendor/Python/current/Lib/mutex.py
   vendor/Python/current/Lib/netrc.py
   vendor/Python/current/Lib/new.py
   vendor/Python/current/Lib/nntplib.py
   vendor/Python/current/Lib/ntpath.py
   vendor/Python/current/Lib/nturl2path.py
   vendor/Python/current/Lib/opcode.py
   vendor/Python/current/Lib/optparse.py
   vendor/Python/current/Lib/os.py
   vendor/Python/current/Lib/os2emxpath.py
   vendor/Python/current/Lib/pdb.doc
   vendor/Python/current/Lib/pdb.py
   vendor/Python/current/Lib/pickle.py
   vendor/Python/current/Lib/pickletools.py
   vendor/Python/current/Lib/pipes.py
   vendor/Python/current/Lib/pkgutil.py
   vendor/Python/current/Lib/plat-aix3/
   vendor/Python/current/Lib/plat-aix3/IN.py
   vendor/Python/current/Lib/plat-aix3/regen
   vendor/Python/current/Lib/plat-aix4/
   vendor/Python/current/Lib/plat-aix4/IN.py
   vendor/Python/current/Lib/plat-aix4/regen
   vendor/Python/current/Lib/plat-atheos/
   vendor/Python/current/Lib/plat-atheos/IN.py
   vendor/Python/current/Lib/plat-atheos/TYPES.py
   vendor/Python/current/Lib/plat-atheos/regen
   vendor/Python/current/Lib/plat-beos5/
   vendor/Python/current/Lib/plat-beos5/IN.py
   vendor/Python/current/Lib/plat-beos5/regen
   vendor/Python/current/Lib/plat-darwin/
   vendor/Python/current/Lib/plat-darwin/IN.py
   vendor/Python/current/Lib/plat-darwin/regen
   vendor/Python/current/Lib/plat-freebsd2/
   vendor/Python/current/Lib/plat-freebsd2/IN.py
   vendor/Python/current/Lib/plat-freebsd2/regen
   vendor/Python/current/Lib/plat-freebsd3/
   vendor/Python/current/Lib/plat-freebsd3/IN.py
   vendor/Python/current/Lib/plat-freebsd3/regen
   vendor/Python/current/Lib/plat-freebsd4/
   vendor/Python/current/Lib/plat-freebsd4/IN.py
   vendor/Python/current/Lib/plat-freebsd4/regen
   vendor/Python/current/Lib/plat-freebsd5/
   vendor/Python/current/Lib/plat-freebsd5/IN.py
   vendor/Python/current/Lib/plat-freebsd5/regen
   vendor/Python/current/Lib/plat-freebsd6/
   vendor/Python/current/Lib/plat-freebsd6/IN.py
   vendor/Python/current/Lib/plat-freebsd6/regen
   vendor/Python/current/Lib/plat-freebsd7/
   vendor/Python/current/Lib/plat-freebsd7/IN.py
   vendor/Python/current/Lib/plat-freebsd7/regen
   vendor/Python/current/Lib/plat-generic/
   vendor/Python/current/Lib/plat-generic/regen
   vendor/Python/current/Lib/plat-irix5/
   vendor/Python/current/Lib/plat-irix5/AL.py
   vendor/Python/current/Lib/plat-irix5/CD.py
   vendor/Python/current/Lib/plat-irix5/CL.py
   vendor/Python/current/Lib/plat-irix5/CL_old.py
   vendor/Python/current/Lib/plat-irix5/DEVICE.py
   vendor/Python/current/Lib/plat-irix5/ERRNO.py
   vendor/Python/current/Lib/plat-irix5/FILE.py
   vendor/Python/current/Lib/plat-irix5/FL.py
   vendor/Python/current/Lib/plat-irix5/GET.py
   vendor/Python/current/Lib/plat-irix5/GL.py
   vendor/Python/current/Lib/plat-irix5/GLWS.py
   vendor/Python/current/Lib/plat-irix5/IN.py
   vendor/Python/current/Lib/plat-irix5/IOCTL.py
   vendor/Python/current/Lib/plat-irix5/SV.py
   vendor/Python/current/Lib/plat-irix5/WAIT.py
   vendor/Python/current/Lib/plat-irix5/cddb.py
   vendor/Python/current/Lib/plat-irix5/cdplayer.py
   vendor/Python/current/Lib/plat-irix5/flp.doc
   vendor/Python/current/Lib/plat-irix5/flp.py
   vendor/Python/current/Lib/plat-irix5/jpeg.py
   vendor/Python/current/Lib/plat-irix5/panel.py
   vendor/Python/current/Lib/plat-irix5/panelparser.py
   vendor/Python/current/Lib/plat-irix5/readcd.doc
   vendor/Python/current/Lib/plat-irix5/readcd.py
   vendor/Python/current/Lib/plat-irix5/regen
   vendor/Python/current/Lib/plat-irix5/torgb.py
   vendor/Python/current/Lib/plat-irix6/
   vendor/Python/current/Lib/plat-irix6/AL.py
   vendor/Python/current/Lib/plat-irix6/CD.py
   vendor/Python/current/Lib/plat-irix6/CL.py
   vendor/Python/current/Lib/plat-irix6/DEVICE.py
   vendor/Python/current/Lib/plat-irix6/ERRNO.py
   vendor/Python/current/Lib/plat-irix6/FILE.py
   vendor/Python/current/Lib/plat-irix6/FL.py
   vendor/Python/current/Lib/plat-irix6/GET.py
   vendor/Python/current/Lib/plat-irix6/GL.py
   vendor/Python/current/Lib/plat-irix6/GLWS.py
   vendor/Python/current/Lib/plat-irix6/IN.py
   vendor/Python/current/Lib/plat-irix6/IOCTL.py
   vendor/Python/current/Lib/plat-irix6/SV.py
   vendor/Python/current/Lib/plat-irix6/WAIT.py
   vendor/Python/current/Lib/plat-irix6/cddb.py
   vendor/Python/current/Lib/plat-irix6/cdplayer.py
   vendor/Python/current/Lib/plat-irix6/flp.doc
   vendor/Python/current/Lib/plat-irix6/flp.py
   vendor/Python/current/Lib/plat-irix6/jpeg.py
   vendor/Python/current/Lib/plat-irix6/panel.py
   vendor/Python/current/Lib/plat-irix6/panelparser.py
   vendor/Python/current/Lib/plat-irix6/readcd.doc
   vendor/Python/current/Lib/plat-irix6/readcd.py
   vendor/Python/current/Lib/plat-irix6/regen
   vendor/Python/current/Lib/plat-irix6/torgb.py
   vendor/Python/current/Lib/plat-linux2/
   vendor/Python/current/Lib/plat-linux2/CDROM.py
   vendor/Python/current/Lib/plat-linux2/DLFCN.py
   vendor/Python/current/Lib/plat-linux2/IN.py
   vendor/Python/current/Lib/plat-linux2/TYPES.py
   vendor/Python/current/Lib/plat-linux2/regen
   vendor/Python/current/Lib/plat-mac/
   vendor/Python/current/Lib/plat-mac/Audio_mac.py
   vendor/Python/current/Lib/plat-mac/Carbon/
   vendor/Python/current/Lib/plat-mac/Carbon/AE.py
   vendor/Python/current/Lib/plat-mac/Carbon/AH.py
   vendor/Python/current/Lib/plat-mac/Carbon/Alias.py
   vendor/Python/current/Lib/plat-mac/Carbon/Aliases.py
   vendor/Python/current/Lib/plat-mac/Carbon/App.py
   vendor/Python/current/Lib/plat-mac/Carbon/Appearance.py
   vendor/Python/current/Lib/plat-mac/Carbon/AppleEvents.py
   vendor/Python/current/Lib/plat-mac/Carbon/AppleHelp.py
   vendor/Python/current/Lib/plat-mac/Carbon/CF.py
   vendor/Python/current/Lib/plat-mac/Carbon/CG.py
   vendor/Python/current/Lib/plat-mac/Carbon/CarbonEvents.py
   vendor/Python/current/Lib/plat-mac/Carbon/CarbonEvt.py
   vendor/Python/current/Lib/plat-mac/Carbon/Cm.py
   vendor/Python/current/Lib/plat-mac/Carbon/Components.py
   vendor/Python/current/Lib/plat-mac/Carbon/ControlAccessor.py
   vendor/Python/current/Lib/plat-mac/Carbon/Controls.py
   vendor/Python/current/Lib/plat-mac/Carbon/CoreFoundation.py
   vendor/Python/current/Lib/plat-mac/Carbon/CoreGraphics.py
   vendor/Python/current/Lib/plat-mac/Carbon/Ctl.py
   vendor/Python/current/Lib/plat-mac/Carbon/Dialogs.py
   vendor/Python/current/Lib/plat-mac/Carbon/Dlg.py
   vendor/Python/current/Lib/plat-mac/Carbon/Drag.py
   vendor/Python/current/Lib/plat-mac/Carbon/Dragconst.py
   vendor/Python/current/Lib/plat-mac/Carbon/Events.py
   vendor/Python/current/Lib/plat-mac/Carbon/Evt.py
   vendor/Python/current/Lib/plat-mac/Carbon/File.py
   vendor/Python/current/Lib/plat-mac/Carbon/Files.py
   vendor/Python/current/Lib/plat-mac/Carbon/Fm.py
   vendor/Python/current/Lib/plat-mac/Carbon/Folder.py
   vendor/Python/current/Lib/plat-mac/Carbon/Folders.py
   vendor/Python/current/Lib/plat-mac/Carbon/Fonts.py
   vendor/Python/current/Lib/plat-mac/Carbon/Help.py
   vendor/Python/current/Lib/plat-mac/Carbon/IBCarbon.py
   vendor/Python/current/Lib/plat-mac/Carbon/IBCarbonRuntime.py
   vendor/Python/current/Lib/plat-mac/Carbon/Icn.py
   vendor/Python/current/Lib/plat-mac/Carbon/Icons.py
   vendor/Python/current/Lib/plat-mac/Carbon/Launch.py
   vendor/Python/current/Lib/plat-mac/Carbon/LaunchServices.py
   vendor/Python/current/Lib/plat-mac/Carbon/List.py
   vendor/Python/current/Lib/plat-mac/Carbon/Lists.py
   vendor/Python/current/Lib/plat-mac/Carbon/MacHelp.py
   vendor/Python/current/Lib/plat-mac/Carbon/MacTextEditor.py
   vendor/Python/current/Lib/plat-mac/Carbon/MediaDescr.py
   vendor/Python/current/Lib/plat-mac/Carbon/Menu.py
   vendor/Python/current/Lib/plat-mac/Carbon/Menus.py
   vendor/Python/current/Lib/plat-mac/Carbon/Mlte.py
   vendor/Python/current/Lib/plat-mac/Carbon/OSA.py
   vendor/Python/current/Lib/plat-mac/Carbon/OSAconst.py
   vendor/Python/current/Lib/plat-mac/Carbon/QDOffscreen.py
   vendor/Python/current/Lib/plat-mac/Carbon/Qd.py
   vendor/Python/current/Lib/plat-mac/Carbon/Qdoffs.py
   vendor/Python/current/Lib/plat-mac/Carbon/Qt.py
   vendor/Python/current/Lib/plat-mac/Carbon/QuickDraw.py
   vendor/Python/current/Lib/plat-mac/Carbon/QuickTime.py
   vendor/Python/current/Lib/plat-mac/Carbon/Res.py
   vendor/Python/current/Lib/plat-mac/Carbon/Resources.py
   vendor/Python/current/Lib/plat-mac/Carbon/Scrap.py
   vendor/Python/current/Lib/plat-mac/Carbon/Snd.py
   vendor/Python/current/Lib/plat-mac/Carbon/Sndihooks.py
   vendor/Python/current/Lib/plat-mac/Carbon/Sound.py
   vendor/Python/current/Lib/plat-mac/Carbon/TE.py
   vendor/Python/current/Lib/plat-mac/Carbon/TextEdit.py
   vendor/Python/current/Lib/plat-mac/Carbon/Win.py
   vendor/Python/current/Lib/plat-mac/Carbon/Windows.py
   vendor/Python/current/Lib/plat-mac/Carbon/__init__.py
   vendor/Python/current/Lib/plat-mac/EasyDialogs.py
   vendor/Python/current/Lib/plat-mac/FrameWork.py
   vendor/Python/current/Lib/plat-mac/MiniAEFrame.py
   vendor/Python/current/Lib/plat-mac/PixMapWrapper.py
   vendor/Python/current/Lib/plat-mac/aepack.py
   vendor/Python/current/Lib/plat-mac/aetools.py
   vendor/Python/current/Lib/plat-mac/aetypes.py
   vendor/Python/current/Lib/plat-mac/applesingle.py
   vendor/Python/current/Lib/plat-mac/appletrawmain.py
   vendor/Python/current/Lib/plat-mac/appletrunner.py
   vendor/Python/current/Lib/plat-mac/argvemulator.py
   vendor/Python/current/Lib/plat-mac/bgenlocations.py
   vendor/Python/current/Lib/plat-mac/buildtools.py
   vendor/Python/current/Lib/plat-mac/bundlebuilder.py
   vendor/Python/current/Lib/plat-mac/cfmfile.py
   vendor/Python/current/Lib/plat-mac/dialogs.rsrc
   vendor/Python/current/Lib/plat-mac/errors.rsrc
   vendor/Python/current/Lib/plat-mac/findertools.py
   vendor/Python/current/Lib/plat-mac/gensuitemodule.py
   vendor/Python/current/Lib/plat-mac/ic.py
   vendor/Python/current/Lib/plat-mac/icopen.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/CodeWarrior/
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/CodeWarrior/CodeWarrior_suite.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/CodeWarrior/Metrowerks_Shell_Suite.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/CodeWarrior/Required.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/CodeWarrior/Standard_Suite.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/CodeWarrior/__init__.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Explorer/
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Explorer/Microsoft_Internet_Explorer.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Explorer/Netscape_Suite.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Explorer/Required_Suite.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Explorer/Standard_Suite.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Explorer/URL_Suite.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Explorer/Web_Browser_Suite.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Explorer/__init__.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Finder/
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Finder/Containers_and_folders.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Finder/Enumerations.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Finder/Files.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Finder/Finder_Basics.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Finder/Finder_items.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Finder/Legacy_suite.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Finder/Standard_Suite.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Finder/Type_Definitions.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Finder/Window_classes.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Finder/__init__.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Netscape/
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Netscape/Mozilla_suite.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Netscape/PowerPlant.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Netscape/Required_suite.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Netscape/Standard_Suite.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Netscape/Standard_URL_suite.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Netscape/Text.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Netscape/WorldWideWeb_suite.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Netscape/__init__.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/StdSuites/
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/StdSuites/AppleScript_Suite.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/StdSuites/Macintosh_Connectivity_Clas.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/StdSuites/QuickDraw_Graphics_Suite.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/StdSuites/QuickDraw_Graphics_Suppleme.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/StdSuites/Required_Suite.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/StdSuites/Standard_Suite.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/StdSuites/Table_Suite.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/StdSuites/Text_Suite.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/StdSuites/Type_Names_Suite.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/StdSuites/__init__.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/SystemEvents/
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/SystemEvents/Disk_Folder_File_Suite.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/SystemEvents/Folder_Actions_Suite.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/SystemEvents/Hidden_Suite.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/SystemEvents/Login_Items_Suite.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/SystemEvents/Power_Suite.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/SystemEvents/Processes_Suite.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/SystemEvents/Standard_Suite.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/SystemEvents/System_Events_Suite.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/SystemEvents/Text_Suite.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/SystemEvents/__init__.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Terminal/
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Terminal/Standard_Suite.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Terminal/Terminal_Suite.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Terminal/Text_Suite.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Terminal/__init__.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/_builtinSuites/
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/_builtinSuites/__init__.py
   vendor/Python/current/Lib/plat-mac/lib-scriptpackages/_builtinSuites/builtin_Suite.py
   vendor/Python/current/Lib/plat-mac/macerrors.py
   vendor/Python/current/Lib/plat-mac/macfs.py
   vendor/Python/current/Lib/plat-mac/macostools.py
   vendor/Python/current/Lib/plat-mac/macresource.py
   vendor/Python/current/Lib/plat-mac/pimp.py
   vendor/Python/current/Lib/plat-mac/plistlib.py
   vendor/Python/current/Lib/plat-mac/terminalcommand.py
   vendor/Python/current/Lib/plat-mac/videoreader.py
   vendor/Python/current/Lib/plat-netbsd1/
   vendor/Python/current/Lib/plat-netbsd1/IN.py
   vendor/Python/current/Lib/plat-netbsd1/regen
   vendor/Python/current/Lib/plat-next3/
   vendor/Python/current/Lib/plat-next3/regen
   vendor/Python/current/Lib/plat-os2emx/
   vendor/Python/current/Lib/plat-os2emx/IN.py
   vendor/Python/current/Lib/plat-os2emx/SOCKET.py
   vendor/Python/current/Lib/plat-os2emx/_emx_link.py
   vendor/Python/current/Lib/plat-os2emx/grp.py
   vendor/Python/current/Lib/plat-os2emx/pwd.py
   vendor/Python/current/Lib/plat-os2emx/regen
   vendor/Python/current/Lib/plat-riscos/
   vendor/Python/current/Lib/plat-riscos/riscosenviron.py
   vendor/Python/current/Lib/plat-riscos/riscospath.py
   vendor/Python/current/Lib/plat-riscos/rourl2path.py
   vendor/Python/current/Lib/plat-sunos5/
   vendor/Python/current/Lib/plat-sunos5/CDIO.py
   vendor/Python/current/Lib/plat-sunos5/DLFCN.py
   vendor/Python/current/Lib/plat-sunos5/IN.py
   vendor/Python/current/Lib/plat-sunos5/STROPTS.py
   vendor/Python/current/Lib/plat-sunos5/SUNAUDIODEV.py
   vendor/Python/current/Lib/plat-sunos5/TYPES.py
   vendor/Python/current/Lib/plat-sunos5/regen
   vendor/Python/current/Lib/plat-unixware7/
   vendor/Python/current/Lib/plat-unixware7/IN.py
   vendor/Python/current/Lib/plat-unixware7/STROPTS.py
   vendor/Python/current/Lib/plat-unixware7/regen
   vendor/Python/current/Lib/platform.py
   vendor/Python/current/Lib/popen2.py
   vendor/Python/current/Lib/poplib.py
   vendor/Python/current/Lib/posixfile.py
   vendor/Python/current/Lib/posixpath.py
   vendor/Python/current/Lib/pprint.py
   vendor/Python/current/Lib/profile.py
   vendor/Python/current/Lib/pstats.py
   vendor/Python/current/Lib/pty.py
   vendor/Python/current/Lib/py_compile.py
   vendor/Python/current/Lib/pyclbr.py
   vendor/Python/current/Lib/pydoc.py
   vendor/Python/current/Lib/quopri.py
   vendor/Python/current/Lib/random.py
   vendor/Python/current/Lib/re.py
   vendor/Python/current/Lib/repr.py
   vendor/Python/current/Lib/rexec.py
   vendor/Python/current/Lib/rfc822.py
   vendor/Python/current/Lib/rlcompleter.py
   vendor/Python/current/Lib/robotparser.py
   vendor/Python/current/Lib/runpy.py
   vendor/Python/current/Lib/sched.py
   vendor/Python/current/Lib/sets.py
   vendor/Python/current/Lib/sgmllib.py
   vendor/Python/current/Lib/sha.py
   vendor/Python/current/Lib/shelve.py
   vendor/Python/current/Lib/shlex.py
   vendor/Python/current/Lib/shutil.py
   vendor/Python/current/Lib/site-packages/
   vendor/Python/current/Lib/site-packages/README
   vendor/Python/current/Lib/site.py
   vendor/Python/current/Lib/smtpd.py
   vendor/Python/current/Lib/smtplib.py
   vendor/Python/current/Lib/sndhdr.py
   vendor/Python/current/Lib/socket.py
   vendor/Python/current/Lib/sqlite3/
   vendor/Python/current/Lib/sqlite3/__init__.py
   vendor/Python/current/Lib/sqlite3/dbapi2.py
   vendor/Python/current/Lib/sqlite3/test/
   vendor/Python/current/Lib/sqlite3/test/__init__.py
   vendor/Python/current/Lib/sqlite3/test/dbapi.py
   vendor/Python/current/Lib/sqlite3/test/factory.py
   vendor/Python/current/Lib/sqlite3/test/hooks.py
   vendor/Python/current/Lib/sqlite3/test/regression.py
   vendor/Python/current/Lib/sqlite3/test/transactions.py
   vendor/Python/current/Lib/sqlite3/test/types.py
   vendor/Python/current/Lib/sqlite3/test/userfunctions.py
   vendor/Python/current/Lib/sre.py
   vendor/Python/current/Lib/sre_compile.py
   vendor/Python/current/Lib/sre_constants.py
   vendor/Python/current/Lib/sre_parse.py
   vendor/Python/current/Lib/stat.py
   vendor/Python/current/Lib/statvfs.py
   vendor/Python/current/Lib/string.py
   vendor/Python/current/Lib/stringold.py
   vendor/Python/current/Lib/stringprep.py
   vendor/Python/current/Lib/struct.py
   vendor/Python/current/Lib/subprocess.py
   vendor/Python/current/Lib/sunau.py
   vendor/Python/current/Lib/sunaudio.py
   vendor/Python/current/Lib/symbol.py
   vendor/Python/current/Lib/symtable.py
   vendor/Python/current/Lib/tabnanny.py
   vendor/Python/current/Lib/tarfile.py
   vendor/Python/current/Lib/telnetlib.py
   vendor/Python/current/Lib/tempfile.py
   vendor/Python/current/Lib/test/
   vendor/Python/current/Lib/test/185test.db
   vendor/Python/current/Lib/test/README
   vendor/Python/current/Lib/test/__init__.py
   vendor/Python/current/Lib/test/audiotest.au
   vendor/Python/current/Lib/test/autotest.py
   vendor/Python/current/Lib/test/bad_coding.py
   vendor/Python/current/Lib/test/bad_coding2.py
   vendor/Python/current/Lib/test/badsyntax_future3.py
   vendor/Python/current/Lib/test/badsyntax_future4.py
   vendor/Python/current/Lib/test/badsyntax_future5.py
   vendor/Python/current/Lib/test/badsyntax_future6.py
   vendor/Python/current/Lib/test/badsyntax_future7.py
   vendor/Python/current/Lib/test/badsyntax_future8.py
   vendor/Python/current/Lib/test/badsyntax_future9.py
   vendor/Python/current/Lib/test/badsyntax_nocaret.py
   vendor/Python/current/Lib/test/cfgparser.1
   vendor/Python/current/Lib/test/check_soundcard.vbs
   vendor/Python/current/Lib/test/cjkencodings_test.py
   vendor/Python/current/Lib/test/crashers/
   vendor/Python/current/Lib/test/crashers/README
   vendor/Python/current/Lib/test/crashers/bogus_code_obj.py
   vendor/Python/current/Lib/test/crashers/borrowed_ref_1.py
   vendor/Python/current/Lib/test/crashers/borrowed_ref_2.py
   vendor/Python/current/Lib/test/crashers/dangerous_subclassing.py
   vendor/Python/current/Lib/test/crashers/gc_inspection.py
   vendor/Python/current/Lib/test/crashers/infinite_rec_1.py
   vendor/Python/current/Lib/test/crashers/infinite_rec_2.py
   vendor/Python/current/Lib/test/crashers/infinite_rec_4.py
   vendor/Python/current/Lib/test/crashers/infinite_rec_5.py
   vendor/Python/current/Lib/test/crashers/loosing_dict_ref.py
   vendor/Python/current/Lib/test/crashers/modify_dict_attr.py
   vendor/Python/current/Lib/test/crashers/nasty_eq_vs_dict.py
   vendor/Python/current/Lib/test/crashers/recursion_limit_too_high.py
   vendor/Python/current/Lib/test/crashers/recursive_call.py
   vendor/Python/current/Lib/test/crashers/weakref_in_del.py
   vendor/Python/current/Lib/test/decimaltestdata/
   vendor/Python/current/Lib/test/decimaltestdata/abs.decTest
   vendor/Python/current/Lib/test/decimaltestdata/add.decTest
   vendor/Python/current/Lib/test/decimaltestdata/base.decTest
   vendor/Python/current/Lib/test/decimaltestdata/clamp.decTest
   vendor/Python/current/Lib/test/decimaltestdata/compare.decTest
   vendor/Python/current/Lib/test/decimaltestdata/decimal128.decTest
   vendor/Python/current/Lib/test/decimaltestdata/decimal32.decTest
   vendor/Python/current/Lib/test/decimaltestdata/decimal64.decTest
   vendor/Python/current/Lib/test/decimaltestdata/divide.decTest
   vendor/Python/current/Lib/test/decimaltestdata/divideint.decTest
   vendor/Python/current/Lib/test/decimaltestdata/inexact.decTest
   vendor/Python/current/Lib/test/decimaltestdata/max.decTest
   vendor/Python/current/Lib/test/decimaltestdata/min.decTest
   vendor/Python/current/Lib/test/decimaltestdata/minus.decTest
   vendor/Python/current/Lib/test/decimaltestdata/multiply.decTest
   vendor/Python/current/Lib/test/decimaltestdata/normalize.decTest
   vendor/Python/current/Lib/test/decimaltestdata/plus.decTest
   vendor/Python/current/Lib/test/decimaltestdata/power.decTest
   vendor/Python/current/Lib/test/decimaltestdata/quantize.decTest
   vendor/Python/current/Lib/test/decimaltestdata/randomBound32.decTest
   vendor/Python/current/Lib/test/decimaltestdata/randoms.decTest
   vendor/Python/current/Lib/test/decimaltestdata/remainder.decTest
   vendor/Python/current/Lib/test/decimaltestdata/remainderNear.decTest
   vendor/Python/current/Lib/test/decimaltestdata/rescale.decTest
   vendor/Python/current/Lib/test/decimaltestdata/rounding.decTest
   vendor/Python/current/Lib/test/decimaltestdata/samequantum.decTest
   vendor/Python/current/Lib/test/decimaltestdata/squareroot.decTest
   vendor/Python/current/Lib/test/decimaltestdata/subtract.decTest
   vendor/Python/current/Lib/test/decimaltestdata/testall.decTest
   vendor/Python/current/Lib/test/decimaltestdata/tointegral.decTest
   vendor/Python/current/Lib/test/doctest_aliases.py
   vendor/Python/current/Lib/test/double_const.py
   vendor/Python/current/Lib/test/empty.vbs
   vendor/Python/current/Lib/test/exception_hierarchy.txt
   vendor/Python/current/Lib/test/fork_wait.py
   vendor/Python/current/Lib/test/greyrgb.uue
   vendor/Python/current/Lib/test/infinite_reload.py
   vendor/Python/current/Lib/test/inspect_fodder.py
   vendor/Python/current/Lib/test/inspect_fodder2.py
   vendor/Python/current/Lib/test/leakers/
   vendor/Python/current/Lib/test/leakers/README.txt
   vendor/Python/current/Lib/test/leakers/__init__.py
   vendor/Python/current/Lib/test/leakers/test_ctypes.py
   vendor/Python/current/Lib/test/leakers/test_gestalt.py
   vendor/Python/current/Lib/test/leakers/test_selftype.py
   vendor/Python/current/Lib/test/list_tests.py
   vendor/Python/current/Lib/test/mapping_tests.py
   vendor/Python/current/Lib/test/output/
   vendor/Python/current/Lib/test/output/test_MimeWriter
   vendor/Python/current/Lib/test/output/test_cProfile
   vendor/Python/current/Lib/test/output/test_cgi
   vendor/Python/current/Lib/test/output/test_class
   vendor/Python/current/Lib/test/output/test_cookie
   vendor/Python/current/Lib/test/output/test_extcall
   vendor/Python/current/Lib/test/output/test_frozen
   vendor/Python/current/Lib/test/output/test_global
   vendor/Python/current/Lib/test/output/test_grammar
   vendor/Python/current/Lib/test/output/test_httplib
   vendor/Python/current/Lib/test/output/test_linuxaudiodev
   vendor/Python/current/Lib/test/output/test_logging
   vendor/Python/current/Lib/test/output/test_math
   vendor/Python/current/Lib/test/output/test_mmap
   vendor/Python/current/Lib/test/output/test_new
   vendor/Python/current/Lib/test/output/test_nis
   vendor/Python/current/Lib/test/output/test_opcodes
   vendor/Python/current/Lib/test/output/test_openpty
   vendor/Python/current/Lib/test/output/test_operations
   vendor/Python/current/Lib/test/output/test_ossaudiodev
   vendor/Python/current/Lib/test/output/test_pep277
   vendor/Python/current/Lib/test/output/test_pkg
   vendor/Python/current/Lib/test/output/test_poll
   vendor/Python/current/Lib/test/output/test_popen
   vendor/Python/current/Lib/test/output/test_popen2
   vendor/Python/current/Lib/test/output/test_profile
   vendor/Python/current/Lib/test/output/test_pty
   vendor/Python/current/Lib/test/output/test_pyexpat
   vendor/Python/current/Lib/test/output/test_regex
   vendor/Python/current/Lib/test/output/test_resource
   vendor/Python/current/Lib/test/output/test_rgbimg
   vendor/Python/current/Lib/test/output/test_scope
   vendor/Python/current/Lib/test/output/test_signal
   vendor/Python/current/Lib/test/output/test_thread
   vendor/Python/current/Lib/test/output/test_threadedtempfile
   vendor/Python/current/Lib/test/output/test_tokenize
   vendor/Python/current/Lib/test/output/test_types
   vendor/Python/current/Lib/test/output/test_winreg
   vendor/Python/current/Lib/test/output/test_xdrlib
   vendor/Python/current/Lib/test/output/xmltests
   vendor/Python/current/Lib/test/outstanding_bugs.py
   vendor/Python/current/Lib/test/pickletester.py
   vendor/Python/current/Lib/test/pyclbr_input.py
   vendor/Python/current/Lib/test/pydocfodder.py
   vendor/Python/current/Lib/test/pystone.py
   vendor/Python/current/Lib/test/re_tests.py
   vendor/Python/current/Lib/test/regex_tests.py
   vendor/Python/current/Lib/test/regrtest.py
   vendor/Python/current/Lib/test/reperf.py
   vendor/Python/current/Lib/test/sample_doctest.py
   vendor/Python/current/Lib/test/seq_tests.py
   vendor/Python/current/Lib/test/sgml_input.html
   vendor/Python/current/Lib/test/sortperf.py
   vendor/Python/current/Lib/test/string_tests.py
   vendor/Python/current/Lib/test/test.xml
   vendor/Python/current/Lib/test/test.xml.out
   vendor/Python/current/Lib/test/test_MimeWriter.py
   vendor/Python/current/Lib/test/test_StringIO.py
   vendor/Python/current/Lib/test/test___all__.py
   vendor/Python/current/Lib/test/test___future__.py
   vendor/Python/current/Lib/test/test__locale.py
   vendor/Python/current/Lib/test/test_aepack.py
   vendor/Python/current/Lib/test/test_al.py
   vendor/Python/current/Lib/test/test_anydbm.py
   vendor/Python/current/Lib/test/test_applesingle.py
   vendor/Python/current/Lib/test/test_array.py
   vendor/Python/current/Lib/test/test_ast.py
   vendor/Python/current/Lib/test/test_asynchat.py
   vendor/Python/current/Lib/test/test_atexit.py
   vendor/Python/current/Lib/test/test_audioop.py
   vendor/Python/current/Lib/test/test_augassign.py
   vendor/Python/current/Lib/test/test_base64.py
   vendor/Python/current/Lib/test/test_bastion.py
   vendor/Python/current/Lib/test/test_bigaddrspace.py
   vendor/Python/current/Lib/test/test_bigmem.py
   vendor/Python/current/Lib/test/test_binascii.py
   vendor/Python/current/Lib/test/test_binhex.py
   vendor/Python/current/Lib/test/test_binop.py
   vendor/Python/current/Lib/test/test_bisect.py
   vendor/Python/current/Lib/test/test_bool.py
   vendor/Python/current/Lib/test/test_bsddb.py
   vendor/Python/current/Lib/test/test_bsddb185.py
   vendor/Python/current/Lib/test/test_bsddb3.py
   vendor/Python/current/Lib/test/test_bufio.py
   vendor/Python/current/Lib/test/test_builtin.py
   vendor/Python/current/Lib/test/test_bz2.py
   vendor/Python/current/Lib/test/test_cProfile.py
   vendor/Python/current/Lib/test/test_calendar.py
   vendor/Python/current/Lib/test/test_call.py
   vendor/Python/current/Lib/test/test_capi.py
   vendor/Python/current/Lib/test/test_cd.py
   vendor/Python/current/Lib/test/test_cfgparser.py
   vendor/Python/current/Lib/test/test_cgi.py
   vendor/Python/current/Lib/test/test_charmapcodec.py
   vendor/Python/current/Lib/test/test_cl.py
   vendor/Python/current/Lib/test/test_class.py
   vendor/Python/current/Lib/test/test_cmath.py
   vendor/Python/current/Lib/test/test_cmd_line.py
   vendor/Python/current/Lib/test/test_code.py
   vendor/Python/current/Lib/test/test_codeccallbacks.py
   vendor/Python/current/Lib/test/test_codecencodings_cn.py
   vendor/Python/current/Lib/test/test_codecencodings_hk.py
   vendor/Python/current/Lib/test/test_codecencodings_jp.py
   vendor/Python/current/Lib/test/test_codecencodings_kr.py
   vendor/Python/current/Lib/test/test_codecencodings_tw.py
   vendor/Python/current/Lib/test/test_codecmaps_cn.py
   vendor/Python/current/Lib/test/test_codecmaps_hk.py
   vendor/Python/current/Lib/test/test_codecmaps_jp.py
   vendor/Python/current/Lib/test/test_codecmaps_kr.py
   vendor/Python/current/Lib/test/test_codecmaps_tw.py
   vendor/Python/current/Lib/test/test_codecs.py
   vendor/Python/current/Lib/test/test_codeop.py
   vendor/Python/current/Lib/test/test_coding.py
   vendor/Python/current/Lib/test/test_coercion.py
   vendor/Python/current/Lib/test/test_colorsys.py
   vendor/Python/current/Lib/test/test_commands.py
   vendor/Python/current/Lib/test/test_compare.py
   vendor/Python/current/Lib/test/test_compile.py
   vendor/Python/current/Lib/test/test_compiler.py
   vendor/Python/current/Lib/test/test_complex.py
   vendor/Python/current/Lib/test/test_complex_args.py
   vendor/Python/current/Lib/test/test_contains.py
   vendor/Python/current/Lib/test/test_contextlib.py
   vendor/Python/current/Lib/test/test_cookie.py
   vendor/Python/current/Lib/test/test_cookielib.py
   vendor/Python/current/Lib/test/test_copy.py
   vendor/Python/current/Lib/test/test_copy_reg.py
   vendor/Python/current/Lib/test/test_cpickle.py
   vendor/Python/current/Lib/test/test_crypt.py
   vendor/Python/current/Lib/test/test_csv.py
   vendor/Python/current/Lib/test/test_ctypes.py
   vendor/Python/current/Lib/test/test_curses.py
   vendor/Python/current/Lib/test/test_datetime.py
   vendor/Python/current/Lib/test/test_dbm.py
   vendor/Python/current/Lib/test/test_decimal.py
   vendor/Python/current/Lib/test/test_decorators.py
   vendor/Python/current/Lib/test/test_defaultdict.py
   vendor/Python/current/Lib/test/test_deque.py
   vendor/Python/current/Lib/test/test_descr.py
   vendor/Python/current/Lib/test/test_descrtut.py
   vendor/Python/current/Lib/test/test_dict.py
   vendor/Python/current/Lib/test/test_difflib.py
   vendor/Python/current/Lib/test/test_difflib_expect.html
   vendor/Python/current/Lib/test/test_dircache.py
   vendor/Python/current/Lib/test/test_dis.py
   vendor/Python/current/Lib/test/test_distutils.py
   vendor/Python/current/Lib/test/test_dl.py
   vendor/Python/current/Lib/test/test_doctest.py
   vendor/Python/current/Lib/test/test_doctest.txt
   vendor/Python/current/Lib/test/test_doctest2.py
   vendor/Python/current/Lib/test/test_doctest2.txt
   vendor/Python/current/Lib/test/test_doctest3.txt
   vendor/Python/current/Lib/test/test_doctest4.txt
   vendor/Python/current/Lib/test/test_dumbdbm.py
   vendor/Python/current/Lib/test/test_dummy_thread.py
   vendor/Python/current/Lib/test/test_dummy_threading.py
   vendor/Python/current/Lib/test/test_email.py
   vendor/Python/current/Lib/test/test_email_codecs.py
   vendor/Python/current/Lib/test/test_email_renamed.py
   vendor/Python/current/Lib/test/test_enumerate.py
   vendor/Python/current/Lib/test/test_eof.py
   vendor/Python/current/Lib/test/test_errno.py
   vendor/Python/current/Lib/test/test_exception_variations.py
   vendor/Python/current/Lib/test/test_exceptions.py
   vendor/Python/current/Lib/test/test_extcall.py
   vendor/Python/current/Lib/test/test_fcntl.py
   vendor/Python/current/Lib/test/test_file.py
   vendor/Python/current/Lib/test/test_filecmp.py
   vendor/Python/current/Lib/test/test_fileinput.py
   vendor/Python/current/Lib/test/test_float.py
   vendor/Python/current/Lib/test/test_fnmatch.py
   vendor/Python/current/Lib/test/test_fork1.py
   vendor/Python/current/Lib/test/test_format.py
   vendor/Python/current/Lib/test/test_fpformat.py
   vendor/Python/current/Lib/test/test_frozen.py
   vendor/Python/current/Lib/test/test_funcattrs.py
   vendor/Python/current/Lib/test/test_functools.py
   vendor/Python/current/Lib/test/test_future.py
   vendor/Python/current/Lib/test/test_future1.py
   vendor/Python/current/Lib/test/test_future2.py
   vendor/Python/current/Lib/test/test_future3.py
   vendor/Python/current/Lib/test/test_gc.py
   vendor/Python/current/Lib/test/test_gdbm.py
   vendor/Python/current/Lib/test/test_generators.py
   vendor/Python/current/Lib/test/test_genexps.py
   vendor/Python/current/Lib/test/test_getargs.py
   vendor/Python/current/Lib/test/test_getargs2.py
   vendor/Python/current/Lib/test/test_getopt.py
   vendor/Python/current/Lib/test/test_gettext.py
   vendor/Python/current/Lib/test/test_gl.py
   vendor/Python/current/Lib/test/test_glob.py
   vendor/Python/current/Lib/test/test_global.py
   vendor/Python/current/Lib/test/test_grammar.py
   vendor/Python/current/Lib/test/test_grp.py
   vendor/Python/current/Lib/test/test_gzip.py
   vendor/Python/current/Lib/test/test_hash.py
   vendor/Python/current/Lib/test/test_hashlib.py
   vendor/Python/current/Lib/test/test_heapq.py
   vendor/Python/current/Lib/test/test_hexoct.py
   vendor/Python/current/Lib/test/test_hmac.py
   vendor/Python/current/Lib/test/test_hotshot.py
   vendor/Python/current/Lib/test/test_htmllib.py
   vendor/Python/current/Lib/test/test_htmlparser.py
   vendor/Python/current/Lib/test/test_httplib.py
   vendor/Python/current/Lib/test/test_imageop.py
   vendor/Python/current/Lib/test/test_imaplib.py
   vendor/Python/current/Lib/test/test_imgfile.py
   vendor/Python/current/Lib/test/test_imp.py
   vendor/Python/current/Lib/test/test_import.py
   vendor/Python/current/Lib/test/test_importhooks.py
   vendor/Python/current/Lib/test/test_index.py
   vendor/Python/current/Lib/test/test_inspect.py
   vendor/Python/current/Lib/test/test_ioctl.py
   vendor/Python/current/Lib/test/test_isinstance.py
   vendor/Python/current/Lib/test/test_iter.py
   vendor/Python/current/Lib/test/test_iterlen.py
   vendor/Python/current/Lib/test/test_itertools.py
   vendor/Python/current/Lib/test/test_largefile.py
   vendor/Python/current/Lib/test/test_linuxaudiodev.py
   vendor/Python/current/Lib/test/test_list.py
   vendor/Python/current/Lib/test/test_locale.py
   vendor/Python/current/Lib/test/test_logging.py
   vendor/Python/current/Lib/test/test_long.py
   vendor/Python/current/Lib/test/test_long_future.py
   vendor/Python/current/Lib/test/test_longexp.py
   vendor/Python/current/Lib/test/test_macfs.py
   vendor/Python/current/Lib/test/test_macostools.py
   vendor/Python/current/Lib/test/test_macpath.py
   vendor/Python/current/Lib/test/test_mailbox.py
   vendor/Python/current/Lib/test/test_marshal.py
   vendor/Python/current/Lib/test/test_math.py
   vendor/Python/current/Lib/test/test_md5.py
   vendor/Python/current/Lib/test/test_mhlib.py
   vendor/Python/current/Lib/test/test_mimetools.py
   vendor/Python/current/Lib/test/test_mimetypes.py
   vendor/Python/current/Lib/test/test_minidom.py
   vendor/Python/current/Lib/test/test_mmap.py
   vendor/Python/current/Lib/test/test_module.py
   vendor/Python/current/Lib/test/test_multibytecodec.py
   vendor/Python/current/Lib/test/test_multibytecodec_support.py
   vendor/Python/current/Lib/test/test_multifile.py
   vendor/Python/current/Lib/test/test_mutants.py
   vendor/Python/current/Lib/test/test_netrc.py
   vendor/Python/current/Lib/test/test_new.py
   vendor/Python/current/Lib/test/test_nis.py
   vendor/Python/current/Lib/test/test_normalization.py
   vendor/Python/current/Lib/test/test_ntpath.py
   vendor/Python/current/Lib/test/test_old_mailbox.py
   vendor/Python/current/Lib/test/test_opcodes.py
   vendor/Python/current/Lib/test/test_openpty.py
   vendor/Python/current/Lib/test/test_operations.py
   vendor/Python/current/Lib/test/test_operator.py
   vendor/Python/current/Lib/test/test_optparse.py
   vendor/Python/current/Lib/test/test_os.py
   vendor/Python/current/Lib/test/test_ossaudiodev.py
   vendor/Python/current/Lib/test/test_parser.py
   vendor/Python/current/Lib/test/test_peepholer.py
   vendor/Python/current/Lib/test/test_pep247.py
   vendor/Python/current/Lib/test/test_pep263.py
   vendor/Python/current/Lib/test/test_pep277.py
   vendor/Python/current/Lib/test/test_pep292.py
   vendor/Python/current/Lib/test/test_pep352.py
   vendor/Python/current/Lib/test/test_pickle.py
   vendor/Python/current/Lib/test/test_pickletools.py
   vendor/Python/current/Lib/test/test_pkg.py
   vendor/Python/current/Lib/test/test_pkgimport.py
   vendor/Python/current/Lib/test/test_platform.py
   vendor/Python/current/Lib/test/test_plistlib.py
   vendor/Python/current/Lib/test/test_poll.py
   vendor/Python/current/Lib/test/test_popen.py
   vendor/Python/current/Lib/test/test_popen2.py
   vendor/Python/current/Lib/test/test_posix.py
   vendor/Python/current/Lib/test/test_posixpath.py
   vendor/Python/current/Lib/test/test_pow.py
   vendor/Python/current/Lib/test/test_pprint.py
   vendor/Python/current/Lib/test/test_profile.py
   vendor/Python/current/Lib/test/test_profilehooks.py
   vendor/Python/current/Lib/test/test_pty.py
   vendor/Python/current/Lib/test/test_pwd.py
   vendor/Python/current/Lib/test/test_pyclbr.py
   vendor/Python/current/Lib/test/test_pyexpat.py
   vendor/Python/current/Lib/test/test_queue.py
   vendor/Python/current/Lib/test/test_quopri.py
   vendor/Python/current/Lib/test/test_random.py
   vendor/Python/current/Lib/test/test_re.py
   vendor/Python/current/Lib/test/test_repr.py
   vendor/Python/current/Lib/test/test_resource.py
   vendor/Python/current/Lib/test/test_rfc822.py
   vendor/Python/current/Lib/test/test_rgbimg.py
   vendor/Python/current/Lib/test/test_richcmp.py
   vendor/Python/current/Lib/test/test_robotparser.py
   vendor/Python/current/Lib/test/test_runpy.py
   vendor/Python/current/Lib/test/test_sax.py
   vendor/Python/current/Lib/test/test_scope.py
   vendor/Python/current/Lib/test/test_scriptpackages.py
   vendor/Python/current/Lib/test/test_select.py
   vendor/Python/current/Lib/test/test_set.py
   vendor/Python/current/Lib/test/test_sets.py
   vendor/Python/current/Lib/test/test_sgmllib.py
   vendor/Python/current/Lib/test/test_sha.py
   vendor/Python/current/Lib/test/test_shelve.py
   vendor/Python/current/Lib/test/test_shlex.py
   vendor/Python/current/Lib/test/test_shutil.py
   vendor/Python/current/Lib/test/test_signal.py
   vendor/Python/current/Lib/test/test_site.py
   vendor/Python/current/Lib/test/test_slice.py
   vendor/Python/current/Lib/test/test_socket.py
   vendor/Python/current/Lib/test/test_socket_ssl.py
   vendor/Python/current/Lib/test/test_socketserver.py
   vendor/Python/current/Lib/test/test_softspace.py
   vendor/Python/current/Lib/test/test_sort.py
   vendor/Python/current/Lib/test/test_sqlite.py
   vendor/Python/current/Lib/test/test_startfile.py
   vendor/Python/current/Lib/test/test_str.py
   vendor/Python/current/Lib/test/test_strftime.py
   vendor/Python/current/Lib/test/test_string.py
   vendor/Python/current/Lib/test/test_stringprep.py
   vendor/Python/current/Lib/test/test_strop.py
   vendor/Python/current/Lib/test/test_strptime.py
   vendor/Python/current/Lib/test/test_struct.py
   vendor/Python/current/Lib/test/test_structmembers.py
   vendor/Python/current/Lib/test/test_structseq.py
   vendor/Python/current/Lib/test/test_subprocess.py
   vendor/Python/current/Lib/test/test_sunaudiodev.py
   vendor/Python/current/Lib/test/test_sundry.py
   vendor/Python/current/Lib/test/test_support.py
   vendor/Python/current/Lib/test/test_symtable.py
   vendor/Python/current/Lib/test/test_syntax.py
   vendor/Python/current/Lib/test/test_sys.py
   vendor/Python/current/Lib/test/test_tarfile.py
   vendor/Python/current/Lib/test/test_tcl.py
   vendor/Python/current/Lib/test/test_tempfile.py
   vendor/Python/current/Lib/test/test_textwrap.py
   vendor/Python/current/Lib/test/test_thread.py
   vendor/Python/current/Lib/test/test_threaded_import.py
   vendor/Python/current/Lib/test/test_threadedtempfile.py
   vendor/Python/current/Lib/test/test_threading.py
   vendor/Python/current/Lib/test/test_threading_local.py
   vendor/Python/current/Lib/test/test_threadsignals.py
   vendor/Python/current/Lib/test/test_time.py
   vendor/Python/current/Lib/test/test_timeout.py
   vendor/Python/current/Lib/test/test_tokenize.py
   vendor/Python/current/Lib/test/test_trace.py
   vendor/Python/current/Lib/test/test_traceback.py
   vendor/Python/current/Lib/test/test_transformer.py
   vendor/Python/current/Lib/test/test_tuple.py
   vendor/Python/current/Lib/test/test_types.py
   vendor/Python/current/Lib/test/test_ucn.py
   vendor/Python/current/Lib/test/test_unary.py
   vendor/Python/current/Lib/test/test_unicode.py
   vendor/Python/current/Lib/test/test_unicode_file.py
   vendor/Python/current/Lib/test/test_unicodedata.py
   vendor/Python/current/Lib/test/test_unittest.py
   vendor/Python/current/Lib/test/test_univnewlines.py
   vendor/Python/current/Lib/test/test_unpack.py
   vendor/Python/current/Lib/test/test_urllib.py
   vendor/Python/current/Lib/test/test_urllib2.py
   vendor/Python/current/Lib/test/test_urllib2net.py
   vendor/Python/current/Lib/test/test_urllibnet.py
   vendor/Python/current/Lib/test/test_urlparse.py
   vendor/Python/current/Lib/test/test_userdict.py
   vendor/Python/current/Lib/test/test_userlist.py
   vendor/Python/current/Lib/test/test_userstring.py
   vendor/Python/current/Lib/test/test_uu.py
   vendor/Python/current/Lib/test/test_uuid.py
   vendor/Python/current/Lib/test/test_wait3.py
   vendor/Python/current/Lib/test/test_wait4.py
   vendor/Python/current/Lib/test/test_warnings.py
   vendor/Python/current/Lib/test/test_wave.py
   vendor/Python/current/Lib/test/test_weakref.py
   vendor/Python/current/Lib/test/test_whichdb.py
   vendor/Python/current/Lib/test/test_winreg.py
   vendor/Python/current/Lib/test/test_winsound.py
   vendor/Python/current/Lib/test/test_with.py
   vendor/Python/current/Lib/test/test_wsgiref.py
   vendor/Python/current/Lib/test/test_xdrlib.py
   vendor/Python/current/Lib/test/test_xml_etree.py
   vendor/Python/current/Lib/test/test_xml_etree_c.py
   vendor/Python/current/Lib/test/test_xmllib.py
   vendor/Python/current/Lib/test/test_xmlrpc.py
   vendor/Python/current/Lib/test/test_xpickle.py
   vendor/Python/current/Lib/test/test_xrange.py
   vendor/Python/current/Lib/test/test_zipfile.py
   vendor/Python/current/Lib/test/test_zipfile64.py
   vendor/Python/current/Lib/test/test_zipimport.py
   vendor/Python/current/Lib/test/test_zlib.py
   vendor/Python/current/Lib/test/testall.py
   vendor/Python/current/Lib/test/testcodec.py
   vendor/Python/current/Lib/test/testimg.uue
   vendor/Python/current/Lib/test/testimgr.uue
   vendor/Python/current/Lib/test/testrgb.uue
   vendor/Python/current/Lib/test/testtar.tar
   vendor/Python/current/Lib/test/tf_inherit_check.py
   vendor/Python/current/Lib/test/threaded_import_hangers.py
   vendor/Python/current/Lib/test/time_hashlib.py
   vendor/Python/current/Lib/test/tokenize_tests.txt
   vendor/Python/current/Lib/test/xmltests.py
   vendor/Python/current/Lib/textwrap.py
   vendor/Python/current/Lib/this.py
   vendor/Python/current/Lib/threading.py
   vendor/Python/current/Lib/timeit.py
   vendor/Python/current/Lib/toaiff.py
   vendor/Python/current/Lib/token.py
   vendor/Python/current/Lib/tokenize.py
   vendor/Python/current/Lib/trace.py
   vendor/Python/current/Lib/traceback.py
   vendor/Python/current/Lib/tty.py
   vendor/Python/current/Lib/types.py
   vendor/Python/current/Lib/unittest.py
   vendor/Python/current/Lib/urllib.py
   vendor/Python/current/Lib/urllib2.py
   vendor/Python/current/Lib/urlparse.py
   vendor/Python/current/Lib/user.py
   vendor/Python/current/Lib/uu.py
   vendor/Python/current/Lib/uuid.py
   vendor/Python/current/Lib/warnings.py
   vendor/Python/current/Lib/wave.py
   vendor/Python/current/Lib/weakref.py
   vendor/Python/current/Lib/webbrowser.py
   vendor/Python/current/Lib/whichdb.py
   vendor/Python/current/Lib/wsgiref.egg-info
   vendor/Python/current/Lib/wsgiref/
   vendor/Python/current/Lib/wsgiref/__init__.py
   vendor/Python/current/Lib/wsgiref/handlers.py
   vendor/Python/current/Lib/wsgiref/headers.py
   vendor/Python/current/Lib/wsgiref/simple_server.py
   vendor/Python/current/Lib/wsgiref/util.py
   vendor/Python/current/Lib/wsgiref/validate.py
   vendor/Python/current/Lib/xdrlib.py
   vendor/Python/current/Lib/xml/
   vendor/Python/current/Lib/xml/__init__.py
   vendor/Python/current/Lib/xml/dom/
   vendor/Python/current/Lib/xml/dom/NodeFilter.py
   vendor/Python/current/Lib/xml/dom/__init__.py
   vendor/Python/current/Lib/xml/dom/domreg.py
   vendor/Python/current/Lib/xml/dom/expatbuilder.py
   vendor/Python/current/Lib/xml/dom/minicompat.py
   vendor/Python/current/Lib/xml/dom/minidom.py
   vendor/Python/current/Lib/xml/dom/pulldom.py
   vendor/Python/current/Lib/xml/dom/xmlbuilder.py
   vendor/Python/current/Lib/xml/etree/
   vendor/Python/current/Lib/xml/etree/ElementInclude.py
   vendor/Python/current/Lib/xml/etree/ElementPath.py
   vendor/Python/current/Lib/xml/etree/ElementTree.py
   vendor/Python/current/Lib/xml/etree/__init__.py
   vendor/Python/current/Lib/xml/etree/cElementTree.py
   vendor/Python/current/Lib/xml/parsers/
   vendor/Python/current/Lib/xml/parsers/__init__.py
   vendor/Python/current/Lib/xml/parsers/expat.py
   vendor/Python/current/Lib/xml/sax/
   vendor/Python/current/Lib/xml/sax/__init__.py
   vendor/Python/current/Lib/xml/sax/_exceptions.py
   vendor/Python/current/Lib/xml/sax/expatreader.py
   vendor/Python/current/Lib/xml/sax/handler.py
   vendor/Python/current/Lib/xml/sax/saxutils.py
   vendor/Python/current/Lib/xml/sax/xmlreader.py
   vendor/Python/current/Lib/xmllib.py
   vendor/Python/current/Lib/xmlrpclib.py
   vendor/Python/current/Lib/zipfile.py
   vendor/Python/current/Mac/
   vendor/Python/current/Mac/BuildScript/
   vendor/Python/current/Mac/BuildScript/README.txt
   vendor/Python/current/Mac/BuildScript/build-installer.py
   vendor/Python/current/Mac/BuildScript/ncurses-5.5.patch
   vendor/Python/current/Mac/BuildScript/resources/
   vendor/Python/current/Mac/BuildScript/resources/ReadMe.txt
   vendor/Python/current/Mac/BuildScript/resources/Welcome.rtf
   vendor/Python/current/Mac/BuildScript/resources/background.jpg
   vendor/Python/current/Mac/BuildScript/scripts/
   vendor/Python/current/Mac/BuildScript/scripts/postflight.documentation
   vendor/Python/current/Mac/BuildScript/scripts/postflight.framework
   vendor/Python/current/Mac/BuildScript/scripts/postflight.patch-profile
   vendor/Python/current/Mac/Demo/
   vendor/Python/current/Mac/Demo/PICTbrowse/
   vendor/Python/current/Mac/Demo/PICTbrowse/ICONbrowse.py
   vendor/Python/current/Mac/Demo/PICTbrowse/PICTbrowse.py
   vendor/Python/current/Mac/Demo/PICTbrowse/PICTbrowse.rsrc
   vendor/Python/current/Mac/Demo/PICTbrowse/PICTbrowse2.py
   vendor/Python/current/Mac/Demo/PICTbrowse/cicnbrowse.py
   vendor/Python/current/Mac/Demo/PICTbrowse/oldPICTbrowse.py
   vendor/Python/current/Mac/Demo/PICTbrowse/oldPICTbrowse.rsrc
   vendor/Python/current/Mac/Demo/applescript.html
   vendor/Python/current/Mac/Demo/applescript/
   vendor/Python/current/Mac/Demo/applescript/Disk_Copy/
   vendor/Python/current/Mac/Demo/applescript/Disk_Copy/Special_Events.py
   vendor/Python/current/Mac/Demo/applescript/Disk_Copy/Standard_Suite.py
   vendor/Python/current/Mac/Demo/applescript/Disk_Copy/Utility_Events.py
   vendor/Python/current/Mac/Demo/applescript/Disk_Copy/__init__.py
   vendor/Python/current/Mac/Demo/applescript/makedisk.py
   vendor/Python/current/Mac/Demo/example0.html
   vendor/Python/current/Mac/Demo/example0/
   vendor/Python/current/Mac/Demo/example0/checktext.py
   vendor/Python/current/Mac/Demo/example1.html
   vendor/Python/current/Mac/Demo/example1/
   vendor/Python/current/Mac/Demo/example1/dnslookup-1.gif
   vendor/Python/current/Mac/Demo/example1/dnslookup-1.py
   vendor/Python/current/Mac/Demo/example1/dnslookup-1.rsrc
   vendor/Python/current/Mac/Demo/example2.html
   vendor/Python/current/Mac/Demo/example2/
   vendor/Python/current/Mac/Demo/example2/dnslookup-2.gif
   vendor/Python/current/Mac/Demo/example2/dnslookup-2.py
   vendor/Python/current/Mac/Demo/example2/dnslookup-2.rsrc
   vendor/Python/current/Mac/Demo/html.icons/
   vendor/Python/current/Mac/Demo/html.icons/createmake.png
   vendor/Python/current/Mac/Demo/html.icons/mkapplet.gif
   vendor/Python/current/Mac/Demo/html.icons/modulator.gif
   vendor/Python/current/Mac/Demo/html.icons/options.gif
   vendor/Python/current/Mac/Demo/html.icons/preferences.gif
   vendor/Python/current/Mac/Demo/html.icons/python.gif
   vendor/Python/current/Mac/Demo/imgbrowse/
   vendor/Python/current/Mac/Demo/imgbrowse/imgbrowse.py
   vendor/Python/current/Mac/Demo/imgbrowse/mac_image.py
   vendor/Python/current/Mac/Demo/index.html
   vendor/Python/current/Mac/Demo/mlte/
   vendor/Python/current/Mac/Demo/mlte/mlted.py
   vendor/Python/current/Mac/Demo/quicktime/
   vendor/Python/current/Mac/Demo/quicktime/MovieInWindow.py
   vendor/Python/current/Mac/Demo/quicktime/VerySimplePlayer.py
   vendor/Python/current/Mac/Demo/resources/
   vendor/Python/current/Mac/Demo/resources/copyres.py
   vendor/Python/current/Mac/Demo/resources/listres.py
   vendor/Python/current/Mac/Demo/sound/
   vendor/Python/current/Mac/Demo/sound/morse.py
   vendor/Python/current/Mac/Demo/sound/morselib.py
   vendor/Python/current/Mac/Demo/sound/playaiff.py
   vendor/Python/current/Mac/Demo/textedit.html
   vendor/Python/current/Mac/Demo/textedit/
   vendor/Python/current/Mac/Demo/textedit/ped.py
   vendor/Python/current/Mac/Extras.ReadMe.txt
   vendor/Python/current/Mac/Extras.install.py
   vendor/Python/current/Mac/IDLE/
   vendor/Python/current/Mac/IDLE/Info.plist.in
   vendor/Python/current/Mac/IDLE/config-extensions.def
   vendor/Python/current/Mac/IDLE/config-main.def
   vendor/Python/current/Mac/IDLE/idlemain.py
   vendor/Python/current/Mac/Icons/
   vendor/Python/current/Mac/Icons/Disk Image.icns
   vendor/Python/current/Mac/Icons/IDLE.icns
   vendor/Python/current/Mac/Icons/Python Folder.icns
   vendor/Python/current/Mac/Icons/PythonCompiled.icns
   vendor/Python/current/Mac/Icons/PythonLauncher.icns
   vendor/Python/current/Mac/Icons/PythonSource.icns
   vendor/Python/current/Mac/Icons/ReadMe.txt
   vendor/Python/current/Mac/Modules/
   vendor/Python/current/Mac/Modules/ColorPickermodule.c
   vendor/Python/current/Mac/Modules/MacOS.c
   vendor/Python/current/Mac/Modules/Nav.c
   vendor/Python/current/Mac/Modules/OSATerminology.c
   vendor/Python/current/Mac/Modules/ae/
   vendor/Python/current/Mac/Modules/ae/README
   vendor/Python/current/Mac/Modules/ae/_AEmodule.c
   vendor/Python/current/Mac/Modules/ae/aescan.py
   vendor/Python/current/Mac/Modules/ae/aesupport.py
   vendor/Python/current/Mac/Modules/ah/
   vendor/Python/current/Mac/Modules/ah/_AHmodule.c
   vendor/Python/current/Mac/Modules/ah/ahscan.py
   vendor/Python/current/Mac/Modules/ah/ahsupport.py
   vendor/Python/current/Mac/Modules/app/
   vendor/Python/current/Mac/Modules/app/_Appmodule.c
   vendor/Python/current/Mac/Modules/app/appscan.py
   vendor/Python/current/Mac/Modules/app/appsupport.py
   vendor/Python/current/Mac/Modules/autoGIL.c
   vendor/Python/current/Mac/Modules/carbonevt/
   vendor/Python/current/Mac/Modules/carbonevt/CarbonEvtscan.py
   vendor/Python/current/Mac/Modules/carbonevt/CarbonEvtsupport.py
   vendor/Python/current/Mac/Modules/carbonevt/_CarbonEvtmodule.c
   vendor/Python/current/Mac/Modules/cf/
   vendor/Python/current/Mac/Modules/cf/_CFmodule.c
   vendor/Python/current/Mac/Modules/cf/cfscan.py
   vendor/Python/current/Mac/Modules/cf/cfsupport.py
   vendor/Python/current/Mac/Modules/cf/pycfbridge.c
   vendor/Python/current/Mac/Modules/cf/pycfbridge.h
   vendor/Python/current/Mac/Modules/cg/
   vendor/Python/current/Mac/Modules/cg/CFMLateImport.c
   vendor/Python/current/Mac/Modules/cg/CFMLateImport.h
   vendor/Python/current/Mac/Modules/cg/CGStubLib
   vendor/Python/current/Mac/Modules/cg/CGStubLib.exp
   vendor/Python/current/Mac/Modules/cg/CGStubLib.readme
   vendor/Python/current/Mac/Modules/cg/_CGmodule.c
   vendor/Python/current/Mac/Modules/cg/cgscan.py
   vendor/Python/current/Mac/Modules/cg/cgsupport.py
   vendor/Python/current/Mac/Modules/cm/
   vendor/Python/current/Mac/Modules/cm/_Cmmodule.c
   vendor/Python/current/Mac/Modules/cm/cmscan.py
   vendor/Python/current/Mac/Modules/cm/cmsupport.py
   vendor/Python/current/Mac/Modules/ctl/
   vendor/Python/current/Mac/Modules/ctl/_Ctlmodule.c
   vendor/Python/current/Mac/Modules/ctl/ctledit.py
   vendor/Python/current/Mac/Modules/ctl/ctlscan.py
   vendor/Python/current/Mac/Modules/ctl/ctlsupport.py
   vendor/Python/current/Mac/Modules/dlg/
   vendor/Python/current/Mac/Modules/dlg/_Dlgmodule.c
   vendor/Python/current/Mac/Modules/dlg/dlgscan.py
   vendor/Python/current/Mac/Modules/dlg/dlgsupport.py
   vendor/Python/current/Mac/Modules/drag/
   vendor/Python/current/Mac/Modules/drag/_Dragmodule.c
   vendor/Python/current/Mac/Modules/drag/dragscan.py
   vendor/Python/current/Mac/Modules/drag/dragsupport.py
   vendor/Python/current/Mac/Modules/evt/
   vendor/Python/current/Mac/Modules/evt/_Evtmodule.c
   vendor/Python/current/Mac/Modules/evt/evtedit.py
   vendor/Python/current/Mac/Modules/evt/evtscan.py
   vendor/Python/current/Mac/Modules/evt/evtsupport.py
   vendor/Python/current/Mac/Modules/file/
   vendor/Python/current/Mac/Modules/file/_Filemodule.c
   vendor/Python/current/Mac/Modules/file/filescan.py
   vendor/Python/current/Mac/Modules/file/filesupport.py
   vendor/Python/current/Mac/Modules/fm/
   vendor/Python/current/Mac/Modules/fm/_Fmmodule.c
   vendor/Python/current/Mac/Modules/fm/fmscan.py
   vendor/Python/current/Mac/Modules/fm/fmsupport.py
   vendor/Python/current/Mac/Modules/folder/
   vendor/Python/current/Mac/Modules/folder/_Foldermodule.c
   vendor/Python/current/Mac/Modules/folder/folderscan.py
   vendor/Python/current/Mac/Modules/folder/foldersupport.py
   vendor/Python/current/Mac/Modules/gestaltmodule.c
   vendor/Python/current/Mac/Modules/help/
   vendor/Python/current/Mac/Modules/help/_Helpmodule.c
   vendor/Python/current/Mac/Modules/help/helpscan.py
   vendor/Python/current/Mac/Modules/help/helpsupport.py
   vendor/Python/current/Mac/Modules/ibcarbon/
   vendor/Python/current/Mac/Modules/ibcarbon/IBCarbonscan.py
   vendor/Python/current/Mac/Modules/ibcarbon/IBCarbonsupport.py
   vendor/Python/current/Mac/Modules/ibcarbon/_IBCarbon.c
   vendor/Python/current/Mac/Modules/icgluemodule.c
   vendor/Python/current/Mac/Modules/icn/
   vendor/Python/current/Mac/Modules/icn/_Icnmodule.c
   vendor/Python/current/Mac/Modules/icn/icnscan.py
   vendor/Python/current/Mac/Modules/icn/icnsupport.py
   vendor/Python/current/Mac/Modules/launch/
   vendor/Python/current/Mac/Modules/launch/_Launchmodule.c
   vendor/Python/current/Mac/Modules/launch/launchscan.py
   vendor/Python/current/Mac/Modules/launch/launchsupport.py
   vendor/Python/current/Mac/Modules/launch/setup.py
   vendor/Python/current/Mac/Modules/list/
   vendor/Python/current/Mac/Modules/list/_Listmodule.c
   vendor/Python/current/Mac/Modules/list/listscan.py
   vendor/Python/current/Mac/Modules/list/listsupport.py
   vendor/Python/current/Mac/Modules/menu/
   vendor/Python/current/Mac/Modules/menu/_Menumodule.c
   vendor/Python/current/Mac/Modules/menu/menuedit.py
   vendor/Python/current/Mac/Modules/menu/menuscan.py
   vendor/Python/current/Mac/Modules/menu/menusupport.py
   vendor/Python/current/Mac/Modules/mlte/
   vendor/Python/current/Mac/Modules/mlte/_Mltemodule.c
   vendor/Python/current/Mac/Modules/mlte/mltescan.py
   vendor/Python/current/Mac/Modules/mlte/mltesupport.py
   vendor/Python/current/Mac/Modules/osa/
   vendor/Python/current/Mac/Modules/osa/_OSAmodule.c
   vendor/Python/current/Mac/Modules/osa/osascan.py
   vendor/Python/current/Mac/Modules/osa/osasupport.py
   vendor/Python/current/Mac/Modules/osa/setup.py
   vendor/Python/current/Mac/Modules/qd/
   vendor/Python/current/Mac/Modules/qd/_Qdmodule.c
   vendor/Python/current/Mac/Modules/qd/qdedit.py
   vendor/Python/current/Mac/Modules/qd/qdscan.py
   vendor/Python/current/Mac/Modules/qd/qdsupport.py
   vendor/Python/current/Mac/Modules/qdoffs/
   vendor/Python/current/Mac/Modules/qdoffs/_Qdoffsmodule.c
   vendor/Python/current/Mac/Modules/qdoffs/qdoffsscan.py
   vendor/Python/current/Mac/Modules/qdoffs/qdoffssupport.py
   vendor/Python/current/Mac/Modules/qt/
   vendor/Python/current/Mac/Modules/qt/_Qtmodule.c
   vendor/Python/current/Mac/Modules/qt/qtscan.py
   vendor/Python/current/Mac/Modules/qt/qtsupport.py
   vendor/Python/current/Mac/Modules/qt/setup.py
   vendor/Python/current/Mac/Modules/res/
   vendor/Python/current/Mac/Modules/res/_Resmodule.c
   vendor/Python/current/Mac/Modules/res/resedit.py
   vendor/Python/current/Mac/Modules/res/resscan.py
   vendor/Python/current/Mac/Modules/res/ressupport.py
   vendor/Python/current/Mac/Modules/scrap/
   vendor/Python/current/Mac/Modules/scrap/_Scrapmodule.c
   vendor/Python/current/Mac/Modules/scrap/scrapscan.py
   vendor/Python/current/Mac/Modules/scrap/scrapsupport.py
   vendor/Python/current/Mac/Modules/snd/
   vendor/Python/current/Mac/Modules/snd/_Sndihooks.c
   vendor/Python/current/Mac/Modules/snd/_Sndmodule.c
   vendor/Python/current/Mac/Modules/snd/sndscan.py
   vendor/Python/current/Mac/Modules/snd/sndsupport.py
   vendor/Python/current/Mac/Modules/te/
   vendor/Python/current/Mac/Modules/te/_TEmodule.c
   vendor/Python/current/Mac/Modules/te/tescan.py
   vendor/Python/current/Mac/Modules/te/tesupport.py
   vendor/Python/current/Mac/Modules/win/
   vendor/Python/current/Mac/Modules/win/_Winmodule.c
   vendor/Python/current/Mac/Modules/win/winedit.py
   vendor/Python/current/Mac/Modules/win/winscan.py
   vendor/Python/current/Mac/Modules/win/winsupport.py
   vendor/Python/current/Mac/PythonLauncher/
   vendor/Python/current/Mac/PythonLauncher/English.lproj/
   vendor/Python/current/Mac/PythonLauncher/English.lproj/Credits.rtf
   vendor/Python/current/Mac/PythonLauncher/English.lproj/MainMenu.nib/
   vendor/Python/current/Mac/PythonLauncher/English.lproj/MainMenu.nib/classes.nib
   vendor/Python/current/Mac/PythonLauncher/English.lproj/MainMenu.nib/info.nib
   vendor/Python/current/Mac/PythonLauncher/English.lproj/MainMenu.nib/objects.nib
   vendor/Python/current/Mac/PythonLauncher/English.lproj/MyDocument.nib/
   vendor/Python/current/Mac/PythonLauncher/English.lproj/MyDocument.nib/classes.nib
   vendor/Python/current/Mac/PythonLauncher/English.lproj/MyDocument.nib/info.nib
   vendor/Python/current/Mac/PythonLauncher/English.lproj/MyDocument.nib/objects.nib
   vendor/Python/current/Mac/PythonLauncher/English.lproj/PreferenceWindow.nib/
   vendor/Python/current/Mac/PythonLauncher/English.lproj/PreferenceWindow.nib/classes.nib
   vendor/Python/current/Mac/PythonLauncher/English.lproj/PreferenceWindow.nib/info.nib
   vendor/Python/current/Mac/PythonLauncher/English.lproj/PreferenceWindow.nib/objects.nib
   vendor/Python/current/Mac/PythonLauncher/FileSettings.h
   vendor/Python/current/Mac/PythonLauncher/FileSettings.m
   vendor/Python/current/Mac/PythonLauncher/Info.plist.in
   vendor/Python/current/Mac/PythonLauncher/MyAppDelegate.h
   vendor/Python/current/Mac/PythonLauncher/MyAppDelegate.m
   vendor/Python/current/Mac/PythonLauncher/MyDocument.h
   vendor/Python/current/Mac/PythonLauncher/MyDocument.m
   vendor/Python/current/Mac/PythonLauncher/PreferencesWindowController.h
   vendor/Python/current/Mac/PythonLauncher/PreferencesWindowController.m
   vendor/Python/current/Mac/PythonLauncher/doscript.h
   vendor/Python/current/Mac/PythonLauncher/doscript.m
   vendor/Python/current/Mac/PythonLauncher/factorySettings.plist
   vendor/Python/current/Mac/PythonLauncher/main.m
   vendor/Python/current/Mac/README
   vendor/Python/current/Mac/Resources/
   vendor/Python/current/Mac/Resources/app/
   vendor/Python/current/Mac/Resources/app/Info.plist
   vendor/Python/current/Mac/Resources/app/PkgInfo
   vendor/Python/current/Mac/Resources/app/Resources/
   vendor/Python/current/Mac/Resources/app/Resources/English.lproj/
   vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/
   vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/PackageManager.gif
   vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/community.html
   vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/doc/
   vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/doc/index.html
   vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/finder.html
   vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/gui.html
   vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/ide/
   vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/ide/IDE.gif
   vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/ide/entering_in_new_window.gif
   vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/ide/hello_world.gif
   vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/ide/index.html
   vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/ide/loading_ide.gif
   vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/ide/making_new_window.gif
   vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/ide/new_ide_window.gif
   vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/ide/new_window_made.gif
   vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/ide/output_window.gif
   vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/ide/saving_edited_file.gif
   vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/ide/simple_commands.gif
   vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/ide/syntax_error.gif
   vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/index.html
   vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/intro.html
   vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/packman.html
   vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/python.gif
   vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/pythonsmall.gif
   vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/scripting.html
   vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/shell.html
   vendor/Python/current/Mac/Resources/app/Resources/English.lproj/InfoPlist.strings
   vendor/Python/current/Mac/Resources/app/Resources/PythonApplet.icns
   vendor/Python/current/Mac/Resources/app/Resources/PythonInterpreter.icns
   vendor/Python/current/Mac/Resources/framework/
   vendor/Python/current/Mac/Resources/framework/English.lproj/
   vendor/Python/current/Mac/Resources/framework/English.lproj/InfoPlist.strings
   vendor/Python/current/Mac/Resources/framework/Info.plist
   vendor/Python/current/Mac/Resources/framework/version.plist
   vendor/Python/current/Mac/Resources/iconsrc/
   vendor/Python/current/Mac/Resources/iconsrc/IDE.psd
   vendor/Python/current/Mac/Resources/iconsrc/PackageManager.psd
   vendor/Python/current/Mac/Resources/iconsrc/PythonApplet.psd
   vendor/Python/current/Mac/Resources/iconsrc/PythonCompiled.psd
   vendor/Python/current/Mac/Resources/iconsrc/PythonIcon.psd
   vendor/Python/current/Mac/Resources/iconsrc/PythonSource.psd
   vendor/Python/current/Mac/Resources/iconsrc/PythonWSource.psd
   vendor/Python/current/Mac/Tools/
   vendor/Python/current/Mac/Tools/Doc/
   vendor/Python/current/Mac/Tools/Doc/HelpIndexingTool/
   vendor/Python/current/Mac/Tools/Doc/HelpIndexingTool/Help_Indexing_Tool_Suite.py
   vendor/Python/current/Mac/Tools/Doc/HelpIndexingTool/Miscellaneous_Standards.py
   vendor/Python/current/Mac/Tools/Doc/HelpIndexingTool/Required_Suite.py
   vendor/Python/current/Mac/Tools/Doc/HelpIndexingTool/Standard_Suite.py
   vendor/Python/current/Mac/Tools/Doc/HelpIndexingTool/__init__.py
   vendor/Python/current/Mac/Tools/Doc/HelpIndexingTool/odds_and_ends.py
   vendor/Python/current/Mac/Tools/Doc/README
   vendor/Python/current/Mac/Tools/Doc/setup.py
   vendor/Python/current/Mac/Tools/fixapplepython23.py
   vendor/Python/current/Mac/Tools/pythonw.c
   vendor/Python/current/Mac/scripts/
   vendor/Python/current/Mac/scripts/BuildApplet.icns
   vendor/Python/current/Mac/scripts/BuildApplet.plist
   vendor/Python/current/Mac/scripts/BuildApplet.py
   vendor/Python/current/Mac/scripts/BuildApplet.rsrc
   vendor/Python/current/Mac/scripts/bgenall.py
   vendor/Python/current/Mac/scripts/buildpkg.py
   vendor/Python/current/Mac/scripts/cachersrc.py
   vendor/Python/current/Mac/scripts/errors.txt
   vendor/Python/current/Mac/scripts/genallsuites.py
   vendor/Python/current/Mac/scripts/mkestrres-errno.h
   vendor/Python/current/Mac/scripts/mkestrres-macerrors.h
   vendor/Python/current/Mac/scripts/mkestrres.py
   vendor/Python/current/Mac/scripts/zappycfiles.py
   vendor/Python/current/Makefile.pre.in
   vendor/Python/current/Misc/
   vendor/Python/current/Misc/ACKS
   vendor/Python/current/Misc/AIX-NOTES
   vendor/Python/current/Misc/BeOS-NOTES
   vendor/Python/current/Misc/BeOS-setup.py
   vendor/Python/current/Misc/HISTORY
   vendor/Python/current/Misc/NEWS
   vendor/Python/current/Misc/NEWS.help
   vendor/Python/current/Misc/PURIFY.README
   vendor/Python/current/Misc/Porting
   vendor/Python/current/Misc/README
   vendor/Python/current/Misc/README.OpenBSD
   vendor/Python/current/Misc/README.coverity
   vendor/Python/current/Misc/README.klocwork
   vendor/Python/current/Misc/README.valgrind
   vendor/Python/current/Misc/RFD
   vendor/Python/current/Misc/RPM/
   vendor/Python/current/Misc/RPM/README
   vendor/Python/current/Misc/RPM/python-2.5.spec
   vendor/Python/current/Misc/SpecialBuilds.txt
   vendor/Python/current/Misc/Vim/
   vendor/Python/current/Misc/Vim/python.vim
   vendor/Python/current/Misc/Vim/syntax_test.py
   vendor/Python/current/Misc/Vim/vim_syntax.py
   vendor/Python/current/Misc/Vim/vimrc
   vendor/Python/current/Misc/build.sh
   vendor/Python/current/Misc/cheatsheet
   vendor/Python/current/Misc/developers.txt
   vendor/Python/current/Misc/find_recursionlimit.py
   vendor/Python/current/Misc/gdbinit
   vendor/Python/current/Misc/indent.pro
   vendor/Python/current/Misc/pymemcompat.h
   vendor/Python/current/Misc/python-config.in
   vendor/Python/current/Misc/python-mode.el
   vendor/Python/current/Misc/python.man
   vendor/Python/current/Misc/setuid-prog.c
   vendor/Python/current/Misc/valgrind-python.supp
   vendor/Python/current/Misc/vgrindefs
   vendor/Python/current/Modules/
   vendor/Python/current/Modules/Setup.config.in
   vendor/Python/current/Modules/Setup.dist
   vendor/Python/current/Modules/_bisectmodule.c
   vendor/Python/current/Modules/_bsddb.c
   vendor/Python/current/Modules/_codecsmodule.c
   vendor/Python/current/Modules/_csv.c
   vendor/Python/current/Modules/_ctypes/
   vendor/Python/current/Modules/_ctypes/_ctypes.c
   vendor/Python/current/Modules/_ctypes/_ctypes_test.c
   vendor/Python/current/Modules/_ctypes/_ctypes_test.h
   vendor/Python/current/Modules/_ctypes/callbacks.c
   vendor/Python/current/Modules/_ctypes/callproc.c
   vendor/Python/current/Modules/_ctypes/cfield.c
   vendor/Python/current/Modules/_ctypes/ctypes.h
   vendor/Python/current/Modules/_ctypes/ctypes_dlfcn.h
   vendor/Python/current/Modules/_ctypes/darwin/
   vendor/Python/current/Modules/_ctypes/darwin/LICENSE
   vendor/Python/current/Modules/_ctypes/darwin/README
   vendor/Python/current/Modules/_ctypes/darwin/README.ctypes
   vendor/Python/current/Modules/_ctypes/darwin/dlfcn.h
   vendor/Python/current/Modules/_ctypes/darwin/dlfcn_simple.c
   vendor/Python/current/Modules/_ctypes/libffi/
   vendor/Python/current/Modules/_ctypes/libffi/LICENSE
   vendor/Python/current/Modules/_ctypes/libffi/README
   vendor/Python/current/Modules/_ctypes/libffi/config.guess
   vendor/Python/current/Modules/_ctypes/libffi/config.sub
   vendor/Python/current/Modules/_ctypes/libffi/configure.ac
   vendor/Python/current/Modules/_ctypes/libffi/fficonfig.h.in
   vendor/Python/current/Modules/_ctypes/libffi/fficonfig.py.in
   vendor/Python/current/Modules/_ctypes/libffi/include/
   vendor/Python/current/Modules/_ctypes/libffi/include/ffi.h.in
   vendor/Python/current/Modules/_ctypes/libffi/include/ffi_common.h
   vendor/Python/current/Modules/_ctypes/libffi/install-sh
   vendor/Python/current/Modules/_ctypes/libffi/src/
   vendor/Python/current/Modules/_ctypes/libffi/src/alpha/
   vendor/Python/current/Modules/_ctypes/libffi/src/alpha/ffi.c
   vendor/Python/current/Modules/_ctypes/libffi/src/alpha/ffitarget.h
   vendor/Python/current/Modules/_ctypes/libffi/src/alpha/osf.S
   vendor/Python/current/Modules/_ctypes/libffi/src/arm/
   vendor/Python/current/Modules/_ctypes/libffi/src/arm/ffi.c
   vendor/Python/current/Modules/_ctypes/libffi/src/arm/ffitarget.h
   vendor/Python/current/Modules/_ctypes/libffi/src/arm/sysv.S
   vendor/Python/current/Modules/_ctypes/libffi/src/cris/
   vendor/Python/current/Modules/_ctypes/libffi/src/cris/ffi.c
   vendor/Python/current/Modules/_ctypes/libffi/src/cris/ffitarget.h
   vendor/Python/current/Modules/_ctypes/libffi/src/cris/sysv.S
   vendor/Python/current/Modules/_ctypes/libffi/src/darwin/
   vendor/Python/current/Modules/_ctypes/libffi/src/darwin/ffitarget.h
   vendor/Python/current/Modules/_ctypes/libffi/src/frv/
   vendor/Python/current/Modules/_ctypes/libffi/src/frv/eabi.S
   vendor/Python/current/Modules/_ctypes/libffi/src/frv/ffi.c
   vendor/Python/current/Modules/_ctypes/libffi/src/frv/ffitarget.h
   vendor/Python/current/Modules/_ctypes/libffi/src/ia64/
   vendor/Python/current/Modules/_ctypes/libffi/src/ia64/ffi.c
   vendor/Python/current/Modules/_ctypes/libffi/src/ia64/ffitarget.h
   vendor/Python/current/Modules/_ctypes/libffi/src/ia64/ia64_flags.h
   vendor/Python/current/Modules/_ctypes/libffi/src/ia64/unix.S
   vendor/Python/current/Modules/_ctypes/libffi/src/m32r/
   vendor/Python/current/Modules/_ctypes/libffi/src/m32r/ffi.c
   vendor/Python/current/Modules/_ctypes/libffi/src/m32r/ffitarget.h
   vendor/Python/current/Modules/_ctypes/libffi/src/m32r/sysv.S
   vendor/Python/current/Modules/_ctypes/libffi/src/m68k/
   vendor/Python/current/Modules/_ctypes/libffi/src/m68k/ffi.c
   vendor/Python/current/Modules/_ctypes/libffi/src/m68k/ffitarget.h
   vendor/Python/current/Modules/_ctypes/libffi/src/m68k/sysv.S
   vendor/Python/current/Modules/_ctypes/libffi/src/mips/
   vendor/Python/current/Modules/_ctypes/libffi/src/mips/ffi.c
   vendor/Python/current/Modules/_ctypes/libffi/src/mips/ffitarget.h
   vendor/Python/current/Modules/_ctypes/libffi/src/mips/n32.S
   vendor/Python/current/Modules/_ctypes/libffi/src/mips/o32.S
   vendor/Python/current/Modules/_ctypes/libffi/src/pa/
   vendor/Python/current/Modules/_ctypes/libffi/src/pa/ffi.c
   vendor/Python/current/Modules/_ctypes/libffi/src/pa/ffitarget.h
   vendor/Python/current/Modules/_ctypes/libffi/src/pa/linux.S
   vendor/Python/current/Modules/_ctypes/libffi/src/powerpc/
   vendor/Python/current/Modules/_ctypes/libffi/src/powerpc/aix.S
   vendor/Python/current/Modules/_ctypes/libffi/src/powerpc/aix_closure.S
   vendor/Python/current/Modules/_ctypes/libffi/src/powerpc/asm.h
   vendor/Python/current/Modules/_ctypes/libffi/src/powerpc/darwin.S
   vendor/Python/current/Modules/_ctypes/libffi/src/powerpc/darwin_closure.S
   vendor/Python/current/Modules/_ctypes/libffi/src/powerpc/ffi.c
   vendor/Python/current/Modules/_ctypes/libffi/src/powerpc/ffi_darwin.c
   vendor/Python/current/Modules/_ctypes/libffi/src/powerpc/ffitarget.h
   vendor/Python/current/Modules/_ctypes/libffi/src/powerpc/linux64.S
   vendor/Python/current/Modules/_ctypes/libffi/src/powerpc/linux64_closure.S
   vendor/Python/current/Modules/_ctypes/libffi/src/powerpc/ppc_closure.S
   vendor/Python/current/Modules/_ctypes/libffi/src/powerpc/sysv.S
   vendor/Python/current/Modules/_ctypes/libffi/src/prep_cif.c
   vendor/Python/current/Modules/_ctypes/libffi/src/s390/
   vendor/Python/current/Modules/_ctypes/libffi/src/s390/ffi.c
   vendor/Python/current/Modules/_ctypes/libffi/src/s390/ffitarget.h
   vendor/Python/current/Modules/_ctypes/libffi/src/s390/sysv.S
   vendor/Python/current/Modules/_ctypes/libffi/src/sh/
   vendor/Python/current/Modules/_ctypes/libffi/src/sh/ffi.c
   vendor/Python/current/Modules/_ctypes/libffi/src/sh/ffitarget.h
   vendor/Python/current/Modules/_ctypes/libffi/src/sh/sysv.S
   vendor/Python/current/Modules/_ctypes/libffi/src/sh64/
   vendor/Python/current/Modules/_ctypes/libffi/src/sh64/ffi.c
   vendor/Python/current/Modules/_ctypes/libffi/src/sh64/ffitarget.h
   vendor/Python/current/Modules/_ctypes/libffi/src/sh64/sysv.S
   vendor/Python/current/Modules/_ctypes/libffi/src/sparc/
   vendor/Python/current/Modules/_ctypes/libffi/src/sparc/ffi.c
   vendor/Python/current/Modules/_ctypes/libffi/src/sparc/ffitarget.h
   vendor/Python/current/Modules/_ctypes/libffi/src/sparc/v8.S
   vendor/Python/current/Modules/_ctypes/libffi/src/sparc/v9.S
   vendor/Python/current/Modules/_ctypes/libffi/src/x86/
   vendor/Python/current/Modules/_ctypes/libffi/src/x86/darwin.S
   vendor/Python/current/Modules/_ctypes/libffi/src/x86/ffi.c
   vendor/Python/current/Modules/_ctypes/libffi/src/x86/ffi64.c
   vendor/Python/current/Modules/_ctypes/libffi/src/x86/ffi_darwin.c
   vendor/Python/current/Modules/_ctypes/libffi/src/x86/ffitarget.h
   vendor/Python/current/Modules/_ctypes/libffi/src/x86/sysv.S
   vendor/Python/current/Modules/_ctypes/libffi/src/x86/unix64.S
   vendor/Python/current/Modules/_ctypes/libffi/src/x86/win32.S
   vendor/Python/current/Modules/_ctypes/libffi_arm_wince/
   vendor/Python/current/Modules/_ctypes/libffi_arm_wince/debug.c
   vendor/Python/current/Modules/_ctypes/libffi_arm_wince/ffi.c
   vendor/Python/current/Modules/_ctypes/libffi_arm_wince/ffi.h
   vendor/Python/current/Modules/_ctypes/libffi_arm_wince/ffi_common.h
   vendor/Python/current/Modules/_ctypes/libffi_arm_wince/fficonfig.h
   vendor/Python/current/Modules/_ctypes/libffi_arm_wince/ffitarget.h
   vendor/Python/current/Modules/_ctypes/libffi_arm_wince/prep_cif.c
   vendor/Python/current/Modules/_ctypes/libffi_arm_wince/sysv.asm
   vendor/Python/current/Modules/_ctypes/libffi_msvc/
   vendor/Python/current/Modules/_ctypes/libffi_msvc/LICENSE
   vendor/Python/current/Modules/_ctypes/libffi_msvc/README
   vendor/Python/current/Modules/_ctypes/libffi_msvc/README.ctypes
   vendor/Python/current/Modules/_ctypes/libffi_msvc/ffi.c
   vendor/Python/current/Modules/_ctypes/libffi_msvc/ffi.h
   vendor/Python/current/Modules/_ctypes/libffi_msvc/ffi_common.h
   vendor/Python/current/Modules/_ctypes/libffi_msvc/fficonfig.h
   vendor/Python/current/Modules/_ctypes/libffi_msvc/ffitarget.h
   vendor/Python/current/Modules/_ctypes/libffi_msvc/prep_cif.c
   vendor/Python/current/Modules/_ctypes/libffi_msvc/types.c
   vendor/Python/current/Modules/_ctypes/libffi_msvc/win32.S
   vendor/Python/current/Modules/_ctypes/libffi_msvc/win32.c
   vendor/Python/current/Modules/_ctypes/malloc_closure.c
   vendor/Python/current/Modules/_ctypes/stgdict.c
   vendor/Python/current/Modules/_curses_panel.c
   vendor/Python/current/Modules/_cursesmodule.c
   vendor/Python/current/Modules/_elementtree.c
   vendor/Python/current/Modules/_functoolsmodule.c
   vendor/Python/current/Modules/_hashopenssl.c
   vendor/Python/current/Modules/_heapqmodule.c
   vendor/Python/current/Modules/_hotshot.c
   vendor/Python/current/Modules/_localemodule.c
   vendor/Python/current/Modules/_lsprof.c
   vendor/Python/current/Modules/_randommodule.c
   vendor/Python/current/Modules/_sqlite/
   vendor/Python/current/Modules/_sqlite/cache.c
   vendor/Python/current/Modules/_sqlite/cache.h
   vendor/Python/current/Modules/_sqlite/connection.c
   vendor/Python/current/Modules/_sqlite/connection.h
   vendor/Python/current/Modules/_sqlite/cursor.c
   vendor/Python/current/Modules/_sqlite/cursor.h
   vendor/Python/current/Modules/_sqlite/microprotocols.c
   vendor/Python/current/Modules/_sqlite/microprotocols.h
   vendor/Python/current/Modules/_sqlite/module.c
   vendor/Python/current/Modules/_sqlite/module.h
   vendor/Python/current/Modules/_sqlite/prepare_protocol.c
   vendor/Python/current/Modules/_sqlite/prepare_protocol.h
   vendor/Python/current/Modules/_sqlite/row.c
   vendor/Python/current/Modules/_sqlite/row.h
   vendor/Python/current/Modules/_sqlite/sqlitecompat.h
   vendor/Python/current/Modules/_sqlite/statement.c
   vendor/Python/current/Modules/_sqlite/statement.h
   vendor/Python/current/Modules/_sqlite/util.c
   vendor/Python/current/Modules/_sqlite/util.h
   vendor/Python/current/Modules/_sre.c
   vendor/Python/current/Modules/_ssl.c
   vendor/Python/current/Modules/_struct.c
   vendor/Python/current/Modules/_testcapimodule.c
   vendor/Python/current/Modules/_tkinter.c
   vendor/Python/current/Modules/_typesmodule.c
   vendor/Python/current/Modules/_weakref.c
   vendor/Python/current/Modules/addrinfo.h
   vendor/Python/current/Modules/almodule.c
   vendor/Python/current/Modules/ar_beos
   vendor/Python/current/Modules/arraymodule.c
   vendor/Python/current/Modules/audioop.c
   vendor/Python/current/Modules/binascii.c
   vendor/Python/current/Modules/bsddbmodule.c
   vendor/Python/current/Modules/bz2module.c
   vendor/Python/current/Modules/cPickle.c
   vendor/Python/current/Modules/cStringIO.c
   vendor/Python/current/Modules/cdmodule.c
   vendor/Python/current/Modules/cgen.py
   vendor/Python/current/Modules/cgensupport.c
   vendor/Python/current/Modules/cgensupport.h
   vendor/Python/current/Modules/cjkcodecs/
   vendor/Python/current/Modules/cjkcodecs/README
   vendor/Python/current/Modules/cjkcodecs/_codecs_cn.c
   vendor/Python/current/Modules/cjkcodecs/_codecs_hk.c
   vendor/Python/current/Modules/cjkcodecs/_codecs_iso2022.c
   vendor/Python/current/Modules/cjkcodecs/_codecs_jp.c
   vendor/Python/current/Modules/cjkcodecs/_codecs_kr.c
   vendor/Python/current/Modules/cjkcodecs/_codecs_tw.c
   vendor/Python/current/Modules/cjkcodecs/alg_jisx0201.h
   vendor/Python/current/Modules/cjkcodecs/cjkcodecs.h
   vendor/Python/current/Modules/cjkcodecs/emu_jisx0213_2000.h
   vendor/Python/current/Modules/cjkcodecs/mappings_cn.h
   vendor/Python/current/Modules/cjkcodecs/mappings_hk.h
   vendor/Python/current/Modules/cjkcodecs/mappings_jisx0213_pair.h
   vendor/Python/current/Modules/cjkcodecs/mappings_jp.h
   vendor/Python/current/Modules/cjkcodecs/mappings_kr.h
   vendor/Python/current/Modules/cjkcodecs/mappings_tw.h
   vendor/Python/current/Modules/cjkcodecs/multibytecodec.c
   vendor/Python/current/Modules/cjkcodecs/multibytecodec.h
   vendor/Python/current/Modules/clmodule.c
   vendor/Python/current/Modules/cmathmodule.c
   vendor/Python/current/Modules/collectionsmodule.c
   vendor/Python/current/Modules/config.c.in
   vendor/Python/current/Modules/cryptmodule.c
   vendor/Python/current/Modules/cstubs
   vendor/Python/current/Modules/datetimemodule.c
   vendor/Python/current/Modules/dbmmodule.c
   vendor/Python/current/Modules/dlmodule.c
   vendor/Python/current/Modules/errnomodule.c
   vendor/Python/current/Modules/expat/
   vendor/Python/current/Modules/expat/amigaconfig.h
   vendor/Python/current/Modules/expat/ascii.h
   vendor/Python/current/Modules/expat/asciitab.h
   vendor/Python/current/Modules/expat/expat.h
   vendor/Python/current/Modules/expat/expat_config.h
   vendor/Python/current/Modules/expat/expat_external.h
   vendor/Python/current/Modules/expat/iasciitab.h
   vendor/Python/current/Modules/expat/internal.h
   vendor/Python/current/Modules/expat/latin1tab.h
   vendor/Python/current/Modules/expat/macconfig.h
   vendor/Python/current/Modules/expat/nametab.h
   vendor/Python/current/Modules/expat/pyexpatns.h
   vendor/Python/current/Modules/expat/utf8tab.h
   vendor/Python/current/Modules/expat/winconfig.h
   vendor/Python/current/Modules/expat/xmlparse.c
   vendor/Python/current/Modules/expat/xmlrole.c
   vendor/Python/current/Modules/expat/xmlrole.h
   vendor/Python/current/Modules/expat/xmltok.c
   vendor/Python/current/Modules/expat/xmltok.h
   vendor/Python/current/Modules/expat/xmltok_impl.c
   vendor/Python/current/Modules/expat/xmltok_impl.h
   vendor/Python/current/Modules/expat/xmltok_ns.c
   vendor/Python/current/Modules/fcntlmodule.c
   vendor/Python/current/Modules/flmodule.c
   vendor/Python/current/Modules/fmmodule.c
   vendor/Python/current/Modules/fpectlmodule.c
   vendor/Python/current/Modules/fpetestmodule.c
   vendor/Python/current/Modules/gc_weakref.txt
   vendor/Python/current/Modules/gcmodule.c
   vendor/Python/current/Modules/gdbmmodule.c
   vendor/Python/current/Modules/getaddrinfo.c
   vendor/Python/current/Modules/getbuildinfo.c
   vendor/Python/current/Modules/getnameinfo.c
   vendor/Python/current/Modules/getpath.c
   vendor/Python/current/Modules/glmodule.c
   vendor/Python/current/Modules/grpmodule.c
   vendor/Python/current/Modules/imageop.c
   vendor/Python/current/Modules/imgfile.c
   vendor/Python/current/Modules/itertoolsmodule.c
   vendor/Python/current/Modules/ld_so_aix
   vendor/Python/current/Modules/ld_so_beos
   vendor/Python/current/Modules/linuxaudiodev.c
   vendor/Python/current/Modules/main.c
   vendor/Python/current/Modules/makesetup
   vendor/Python/current/Modules/makexp_aix
   vendor/Python/current/Modules/mathmodule.c
   vendor/Python/current/Modules/md5.c
   vendor/Python/current/Modules/md5.h
   vendor/Python/current/Modules/md5module.c
   vendor/Python/current/Modules/mmapmodule.c
   vendor/Python/current/Modules/nismodule.c
   vendor/Python/current/Modules/operator.c
   vendor/Python/current/Modules/ossaudiodev.c
   vendor/Python/current/Modules/parsermodule.c
   vendor/Python/current/Modules/posixmodule.c
   vendor/Python/current/Modules/puremodule.c
   vendor/Python/current/Modules/pwdmodule.c
   vendor/Python/current/Modules/pyexpat.c
   vendor/Python/current/Modules/python.c
   vendor/Python/current/Modules/readline.c
   vendor/Python/current/Modules/resource.c
   vendor/Python/current/Modules/rgbimgmodule.c
   vendor/Python/current/Modules/rotatingtree.c
   vendor/Python/current/Modules/rotatingtree.h
   vendor/Python/current/Modules/selectmodule.c
   vendor/Python/current/Modules/sgimodule.c
   vendor/Python/current/Modules/sha256module.c
   vendor/Python/current/Modules/sha512module.c
   vendor/Python/current/Modules/shamodule.c
   vendor/Python/current/Modules/signalmodule.c
   vendor/Python/current/Modules/socketmodule.c
   vendor/Python/current/Modules/socketmodule.h
   vendor/Python/current/Modules/spwdmodule.c
   vendor/Python/current/Modules/sre.h
   vendor/Python/current/Modules/sre_constants.h
   vendor/Python/current/Modules/stropmodule.c
   vendor/Python/current/Modules/sunaudiodev.c
   vendor/Python/current/Modules/svmodule.c
   vendor/Python/current/Modules/symtablemodule.c
   vendor/Python/current/Modules/syslogmodule.c
   vendor/Python/current/Modules/termios.c
   vendor/Python/current/Modules/testcapi_long.h
   vendor/Python/current/Modules/threadmodule.c
   vendor/Python/current/Modules/timemodule.c
   vendor/Python/current/Modules/timing.h
   vendor/Python/current/Modules/timingmodule.c
   vendor/Python/current/Modules/tkappinit.c
   vendor/Python/current/Modules/unicodedata.c
   vendor/Python/current/Modules/unicodedata_db.h
   vendor/Python/current/Modules/unicodename_db.h
   vendor/Python/current/Modules/xxmodule.c
   vendor/Python/current/Modules/xxsubtype.c
   vendor/Python/current/Modules/yuv.h
   vendor/Python/current/Modules/yuvconvert.c
   vendor/Python/current/Modules/zipimport.c
   vendor/Python/current/Modules/zlib/
   vendor/Python/current/Modules/zlib/ChangeLog
   vendor/Python/current/Modules/zlib/FAQ
   vendor/Python/current/Modules/zlib/INDEX
   vendor/Python/current/Modules/zlib/README
   vendor/Python/current/Modules/zlib/adler32.c
   vendor/Python/current/Modules/zlib/algorithm.txt
   vendor/Python/current/Modules/zlib/compress.c
   vendor/Python/current/Modules/zlib/crc32.c
   vendor/Python/current/Modules/zlib/crc32.h
   vendor/Python/current/Modules/zlib/deflate.c
   vendor/Python/current/Modules/zlib/deflate.h
   vendor/Python/current/Modules/zlib/example.c
   vendor/Python/current/Modules/zlib/gzio.c
   vendor/Python/current/Modules/zlib/infback.c
   vendor/Python/current/Modules/zlib/inffast.c
   vendor/Python/current/Modules/zlib/inffast.h
   vendor/Python/current/Modules/zlib/inffixed.h
   vendor/Python/current/Modules/zlib/inflate.c
   vendor/Python/current/Modules/zlib/inflate.h
   vendor/Python/current/Modules/zlib/inftrees.c
   vendor/Python/current/Modules/zlib/inftrees.h
   vendor/Python/current/Modules/zlib/make_vms.com
   vendor/Python/current/Modules/zlib/minigzip.c
   vendor/Python/current/Modules/zlib/trees.c
   vendor/Python/current/Modules/zlib/trees.h
   vendor/Python/current/Modules/zlib/uncompr.c
   vendor/Python/current/Modules/zlib/zconf.h
   vendor/Python/current/Modules/zlib/zconf.in.h
   vendor/Python/current/Modules/zlib/zlib.3
   vendor/Python/current/Modules/zlib/zlib.h
   vendor/Python/current/Modules/zlib/zutil.c
   vendor/Python/current/Modules/zlib/zutil.h
   vendor/Python/current/Modules/zlibmodule.c
   vendor/Python/current/Objects/
   vendor/Python/current/Objects/abstract.c
   vendor/Python/current/Objects/boolobject.c
   vendor/Python/current/Objects/bufferobject.c
   vendor/Python/current/Objects/cellobject.c
   vendor/Python/current/Objects/classobject.c
   vendor/Python/current/Objects/cobject.c
   vendor/Python/current/Objects/codeobject.c
   vendor/Python/current/Objects/complexobject.c
   vendor/Python/current/Objects/descrobject.c
   vendor/Python/current/Objects/dictnotes.txt
   vendor/Python/current/Objects/dictobject.c
   vendor/Python/current/Objects/enumobject.c
   vendor/Python/current/Objects/exceptions.c
   vendor/Python/current/Objects/fileobject.c
   vendor/Python/current/Objects/floatobject.c
   vendor/Python/current/Objects/frameobject.c
   vendor/Python/current/Objects/funcobject.c
   vendor/Python/current/Objects/genobject.c
   vendor/Python/current/Objects/intobject.c
   vendor/Python/current/Objects/iterobject.c
   vendor/Python/current/Objects/listobject.c
   vendor/Python/current/Objects/listsort.txt
   vendor/Python/current/Objects/longobject.c
   vendor/Python/current/Objects/methodobject.c
   vendor/Python/current/Objects/moduleobject.c
   vendor/Python/current/Objects/object.c
   vendor/Python/current/Objects/obmalloc.c
   vendor/Python/current/Objects/rangeobject.c
   vendor/Python/current/Objects/setobject.c
   vendor/Python/current/Objects/sliceobject.c
   vendor/Python/current/Objects/stringlib/
   vendor/Python/current/Objects/stringlib/README.txt
   vendor/Python/current/Objects/stringlib/count.h
   vendor/Python/current/Objects/stringlib/fastsearch.h
   vendor/Python/current/Objects/stringlib/find.h
   vendor/Python/current/Objects/stringlib/partition.h
   vendor/Python/current/Objects/stringobject.c
   vendor/Python/current/Objects/structseq.c
   vendor/Python/current/Objects/tupleobject.c
   vendor/Python/current/Objects/typeobject.c
   vendor/Python/current/Objects/unicodectype.c
   vendor/Python/current/Objects/unicodeobject.c
   vendor/Python/current/Objects/unicodetype_db.h
   vendor/Python/current/Objects/weakrefobject.c
   vendor/Python/current/PC/
   vendor/Python/current/PC/VC6/
   vendor/Python/current/PC/VC6/_bsddb.dsp
   vendor/Python/current/PC/VC6/_ctypes.dsp
   vendor/Python/current/PC/VC6/_ctypes_test.dsp
   vendor/Python/current/PC/VC6/_elementtree.dsp
   vendor/Python/current/PC/VC6/_socket.dsp
   vendor/Python/current/PC/VC6/_sqlite3.dsp
   vendor/Python/current/PC/VC6/_ssl.dsp
   vendor/Python/current/PC/VC6/_ssl.mak
   vendor/Python/current/PC/VC6/_testcapi.dsp
   vendor/Python/current/PC/VC6/_tkinter.dsp
   vendor/Python/current/PC/VC6/build_ssl.py
   vendor/Python/current/PC/VC6/bz2.dsp
   vendor/Python/current/PC/VC6/make_versioninfo.dsp
   vendor/Python/current/PC/VC6/pcbuild.dsw
   vendor/Python/current/PC/VC6/pyexpat.dsp
   vendor/Python/current/PC/VC6/python.dsp
   vendor/Python/current/PC/VC6/pythoncore.dsp
   vendor/Python/current/PC/VC6/pythonw.dsp
   vendor/Python/current/PC/VC6/readme.txt
   vendor/Python/current/PC/VC6/rmpyc.py
   vendor/Python/current/PC/VC6/rt.bat
   vendor/Python/current/PC/VC6/select.dsp
   vendor/Python/current/PC/VC6/unicodedata.dsp
   vendor/Python/current/PC/VC6/w9xpopen.dsp
   vendor/Python/current/PC/VC6/winsound.dsp
   vendor/Python/current/PC/WinMain.c
   vendor/Python/current/PC/_msi.c
   vendor/Python/current/PC/_subprocess.c
   vendor/Python/current/PC/_winreg.c
   vendor/Python/current/PC/bdist_wininst/
   vendor/Python/current/PC/bdist_wininst/PythonPowered.bmp
   vendor/Python/current/PC/bdist_wininst/README.txt
   vendor/Python/current/PC/bdist_wininst/archive.h
   vendor/Python/current/PC/bdist_wininst/extract.c
   vendor/Python/current/PC/bdist_wininst/install.c
   vendor/Python/current/PC/bdist_wininst/install.rc
   vendor/Python/current/PC/bdist_wininst/resource.h
   vendor/Python/current/PC/bdist_wininst/wininst-7.1.sln
   vendor/Python/current/PC/bdist_wininst/wininst-7.1.vcproj
   vendor/Python/current/PC/bdist_wininst/wininst.dsp
   vendor/Python/current/PC/bdist_wininst/wininst.dsw
   vendor/Python/current/PC/config.c
   vendor/Python/current/PC/dl_nt.c
   vendor/Python/current/PC/dllbase_nt.txt
   vendor/Python/current/PC/empty.c
   vendor/Python/current/PC/errmap.h
   vendor/Python/current/PC/errmap.mak
   vendor/Python/current/PC/example_nt/
   vendor/Python/current/PC/example_nt/example.c
   vendor/Python/current/PC/example_nt/example.sln
   vendor/Python/current/PC/example_nt/example.vcproj
   vendor/Python/current/PC/example_nt/readme.txt
   vendor/Python/current/PC/frozen_dllmain.c
   vendor/Python/current/PC/generrmap.c
   vendor/Python/current/PC/getpathp.c
   vendor/Python/current/PC/icons.mak
   vendor/Python/current/PC/icons.rc
   vendor/Python/current/PC/icons/
   vendor/Python/current/PC/icons/baselogo.svg
   vendor/Python/current/PC/icons/source.xar
   vendor/Python/current/PC/import_nt.c
   vendor/Python/current/PC/make_versioninfo.c
   vendor/Python/current/PC/msvcrtmodule.c
   vendor/Python/current/PC/os2emx/
   vendor/Python/current/PC/os2emx/README.os2emx
   vendor/Python/current/PC/os2emx/config.c
   vendor/Python/current/PC/os2emx/dlfcn.c
   vendor/Python/current/PC/os2emx/dlfcn.h
   vendor/Python/current/PC/os2emx/dllentry.c
   vendor/Python/current/PC/os2emx/getpathp.c
   vendor/Python/current/PC/os2emx/pyconfig.h
   vendor/Python/current/PC/os2emx/python25.def
   vendor/Python/current/PC/os2emx/pythonpm.c
   vendor/Python/current/PC/os2vacpp/
   vendor/Python/current/PC/os2vacpp/_tkinter.def
   vendor/Python/current/PC/os2vacpp/config.c
   vendor/Python/current/PC/os2vacpp/getpathp.c
   vendor/Python/current/PC/os2vacpp/makefile
   vendor/Python/current/PC/os2vacpp/makefile.omk
   vendor/Python/current/PC/os2vacpp/pyconfig.h
   vendor/Python/current/PC/os2vacpp/python.def
   vendor/Python/current/PC/os2vacpp/readme.txt
   vendor/Python/current/PC/py.ico
   vendor/Python/current/PC/pyc.ico
   vendor/Python/current/PC/pycon.ico
   vendor/Python/current/PC/pyconfig.h
   vendor/Python/current/PC/python.mk
   vendor/Python/current/PC/python_exe.rc
   vendor/Python/current/PC/python_nt.rc
   vendor/Python/current/PC/readme.txt
   vendor/Python/current/PC/testpy.py
   vendor/Python/current/PC/w9xpopen.c
   vendor/Python/current/PC/winsound.c
   vendor/Python/current/PCbuild/
   vendor/Python/current/PCbuild/Uninstal.wse
   vendor/Python/current/PCbuild/_bsddb.vcproj
   vendor/Python/current/PCbuild/_ctypes.vcproj
   vendor/Python/current/PCbuild/_ctypes_test.vcproj
   vendor/Python/current/PCbuild/_elementtree.vcproj
   vendor/Python/current/PCbuild/_msi.vcproj
   vendor/Python/current/PCbuild/_socket.vcproj
   vendor/Python/current/PCbuild/_sqlite3.vcproj
   vendor/Python/current/PCbuild/_ssl.mak
   vendor/Python/current/PCbuild/_ssl.vcproj
   vendor/Python/current/PCbuild/_testcapi.vcproj
   vendor/Python/current/PCbuild/_tkinter.vcproj
   vendor/Python/current/PCbuild/build_ssl.bat
   vendor/Python/current/PCbuild/build_ssl.py
   vendor/Python/current/PCbuild/bz2.vcproj
   vendor/Python/current/PCbuild/db.build
   vendor/Python/current/PCbuild/field3.py
   vendor/Python/current/PCbuild/installer.bmp
   vendor/Python/current/PCbuild/make_buildinfo.c
   vendor/Python/current/PCbuild/make_buildinfo.vcproj
   vendor/Python/current/PCbuild/make_versioninfo.vcproj
   vendor/Python/current/PCbuild/pcbuild.sln
   vendor/Python/current/PCbuild/pyexpat.vcproj
   vendor/Python/current/PCbuild/python.build
   vendor/Python/current/PCbuild/python.iss
   vendor/Python/current/PCbuild/python.vcproj
   vendor/Python/current/PCbuild/python20.wse
   vendor/Python/current/PCbuild/pythoncore.vcproj
   vendor/Python/current/PCbuild/pythonw.vcproj
   vendor/Python/current/PCbuild/readme.txt
   vendor/Python/current/PCbuild/rmpyc.py
   vendor/Python/current/PCbuild/rt.bat
   vendor/Python/current/PCbuild/select.vcproj
   vendor/Python/current/PCbuild/unicodedata.vcproj
   vendor/Python/current/PCbuild/w9xpopen.vcproj
   vendor/Python/current/PCbuild/winsound.vcproj
   vendor/Python/current/PCbuild8/
   vendor/Python/current/PCbuild8/Uninstal.wse
   vendor/Python/current/PCbuild8/_bsddb.vcproj
   vendor/Python/current/PCbuild8/_ctypes.vcproj
   vendor/Python/current/PCbuild8/_ctypes_test.vcproj
   vendor/Python/current/PCbuild8/_elementtree.vcproj
   vendor/Python/current/PCbuild8/_msi.vcproj
   vendor/Python/current/PCbuild8/_socket.vcproj
   vendor/Python/current/PCbuild8/_sqlite3.vcproj
   vendor/Python/current/PCbuild8/_ssl.mak
   vendor/Python/current/PCbuild8/_ssl.vcproj
   vendor/Python/current/PCbuild8/_testcapi.vcproj
   vendor/Python/current/PCbuild8/_tkinter.vcproj
   vendor/Python/current/PCbuild8/build_ssl.py
   vendor/Python/current/PCbuild8/bz2.vcproj
   vendor/Python/current/PCbuild8/db.build
   vendor/Python/current/PCbuild8/field3.py
   vendor/Python/current/PCbuild8/installer.bmp
   vendor/Python/current/PCbuild8/make_buildinfo.c
   vendor/Python/current/PCbuild8/make_buildinfo.vcproj
   vendor/Python/current/PCbuild8/make_versioninfo.vcproj
   vendor/Python/current/PCbuild8/pcbuild.sln
   vendor/Python/current/PCbuild8/pyexpat.vcproj
   vendor/Python/current/PCbuild8/python.build
   vendor/Python/current/PCbuild8/python.iss
   vendor/Python/current/PCbuild8/python.vcproj
   vendor/Python/current/PCbuild8/python20.wse
   vendor/Python/current/PCbuild8/pythoncore.vcproj
   vendor/Python/current/PCbuild8/pythoncore_pgo.vcproj
   vendor/Python/current/PCbuild8/pythoncore_pgo_link.txt
   vendor/Python/current/PCbuild8/pythonw.vcproj
   vendor/Python/current/PCbuild8/readme.txt
   vendor/Python/current/PCbuild8/rmpyc.py
   vendor/Python/current/PCbuild8/rt.bat
   vendor/Python/current/PCbuild8/select.vcproj
   vendor/Python/current/PCbuild8/unicodedata.vcproj
   vendor/Python/current/PCbuild8/w9xpopen.vcproj
   vendor/Python/current/PCbuild8/winsound.vcproj
   vendor/Python/current/Parser/
   vendor/Python/current/Parser/Python.asdl
   vendor/Python/current/Parser/acceler.c
   vendor/Python/current/Parser/asdl.py
   vendor/Python/current/Parser/asdl_c.py
   vendor/Python/current/Parser/bitset.c
   vendor/Python/current/Parser/firstsets.c
   vendor/Python/current/Parser/grammar.c
   vendor/Python/current/Parser/grammar.mak
   vendor/Python/current/Parser/grammar1.c
   vendor/Python/current/Parser/intrcheck.c
   vendor/Python/current/Parser/listnode.c
   vendor/Python/current/Parser/metagrammar.c
   vendor/Python/current/Parser/myreadline.c
   vendor/Python/current/Parser/node.c
   vendor/Python/current/Parser/parser.c
   vendor/Python/current/Parser/parser.h
   vendor/Python/current/Parser/parsetok.c
   vendor/Python/current/Parser/pgen.c
   vendor/Python/current/Parser/pgenmain.c
   vendor/Python/current/Parser/printgrammar.c
   vendor/Python/current/Parser/spark.py
   vendor/Python/current/Parser/tokenizer.c
   vendor/Python/current/Parser/tokenizer.h
   vendor/Python/current/Parser/tokenizer_pgen.c
   vendor/Python/current/Python/
   vendor/Python/current/Python/Python-ast.c
   vendor/Python/current/Python/asdl.c
   vendor/Python/current/Python/ast.c
   vendor/Python/current/Python/atof.c
   vendor/Python/current/Python/bltinmodule.c
   vendor/Python/current/Python/ceval.c
   vendor/Python/current/Python/codecs.c
   vendor/Python/current/Python/compile.c
   vendor/Python/current/Python/dup2.c
   vendor/Python/current/Python/dynload_aix.c
   vendor/Python/current/Python/dynload_atheos.c
   vendor/Python/current/Python/dynload_beos.c
   vendor/Python/current/Python/dynload_dl.c
   vendor/Python/current/Python/dynload_hpux.c
   vendor/Python/current/Python/dynload_next.c
   vendor/Python/current/Python/dynload_os2.c
   vendor/Python/current/Python/dynload_shlib.c
   vendor/Python/current/Python/dynload_stub.c
   vendor/Python/current/Python/dynload_win.c
   vendor/Python/current/Python/errors.c
   vendor/Python/current/Python/fmod.c
   vendor/Python/current/Python/frozen.c
   vendor/Python/current/Python/frozenmain.c
   vendor/Python/current/Python/future.c
   vendor/Python/current/Python/getargs.c
   vendor/Python/current/Python/getcompiler.c
   vendor/Python/current/Python/getcopyright.c
   vendor/Python/current/Python/getcwd.c
   vendor/Python/current/Python/getmtime.c
   vendor/Python/current/Python/getopt.c
   vendor/Python/current/Python/getplatform.c
   vendor/Python/current/Python/getversion.c
   vendor/Python/current/Python/graminit.c
   vendor/Python/current/Python/hypot.c
   vendor/Python/current/Python/import.c
   vendor/Python/current/Python/importdl.c
   vendor/Python/current/Python/importdl.h
   vendor/Python/current/Python/mactoolboxglue.c
   vendor/Python/current/Python/marshal.c
   vendor/Python/current/Python/memmove.c
   vendor/Python/current/Python/modsupport.c
   vendor/Python/current/Python/mysnprintf.c
   vendor/Python/current/Python/mystrtoul.c
   vendor/Python/current/Python/pyarena.c
   vendor/Python/current/Python/pyfpe.c
   vendor/Python/current/Python/pystate.c
   vendor/Python/current/Python/pystrtod.c
   vendor/Python/current/Python/pythonrun.c
   vendor/Python/current/Python/sigcheck.c
   vendor/Python/current/Python/strdup.c
   vendor/Python/current/Python/strerror.c
   vendor/Python/current/Python/strtod.c
   vendor/Python/current/Python/structmember.c
   vendor/Python/current/Python/symtable.c
   vendor/Python/current/Python/sysmodule.c
   vendor/Python/current/Python/thread.c
   vendor/Python/current/Python/thread_atheos.h
   vendor/Python/current/Python/thread_beos.h
   vendor/Python/current/Python/thread_cthread.h
   vendor/Python/current/Python/thread_foobar.h
   vendor/Python/current/Python/thread_lwp.h
   vendor/Python/current/Python/thread_nt.h
   vendor/Python/current/Python/thread_os2.h
   vendor/Python/current/Python/thread_pth.h
   vendor/Python/current/Python/thread_pthread.h
   vendor/Python/current/Python/thread_sgi.h
   vendor/Python/current/Python/thread_solaris.h
   vendor/Python/current/Python/thread_wince.h
   vendor/Python/current/Python/traceback.c
   vendor/Python/current/README
   vendor/Python/current/RISCOS/
   vendor/Python/current/RISCOS/Modules/
   vendor/Python/current/RISCOS/Modules/config.c
   vendor/Python/current/RISCOS/Modules/drawfmodule.c
   vendor/Python/current/RISCOS/Modules/getpath_riscos.c
   vendor/Python/current/RISCOS/Modules/riscosmodule.c
   vendor/Python/current/RISCOS/Modules/swimodule.c
   vendor/Python/current/RISCOS/Python/
   vendor/Python/current/RISCOS/Python/dynload_riscos.c
   vendor/Python/current/RISCOS/Python/getcwd_riscos.c
   vendor/Python/current/RISCOS/Python/getmtime_riscos.c
   vendor/Python/current/RISCOS/README
   vendor/Python/current/RISCOS/pyconfig.h
   vendor/Python/current/RISCOS/sleep.c
   vendor/Python/current/RISCOS/support/
   vendor/Python/current/RISCOS/support/!Boot
   vendor/Python/current/RISCOS/support/!Run
   vendor/Python/current/RISCOS/support/!Sprites
   vendor/Python/current/RISCOS/support/!Sprites22
   vendor/Python/current/RISCOS/support/AddToPath
   vendor/Python/current/RISCOS/unixstuff.c
   vendor/Python/current/RISCOS/unixstuff.h
   vendor/Python/current/Tools/
   vendor/Python/current/Tools/README
   vendor/Python/current/Tools/audiopy/
   vendor/Python/current/Tools/audiopy/README
   vendor/Python/current/Tools/audiopy/audiopy
   vendor/Python/current/Tools/bgen/
   vendor/Python/current/Tools/bgen/README
   vendor/Python/current/Tools/bgen/bgen/
   vendor/Python/current/Tools/bgen/bgen/bgen.py
   vendor/Python/current/Tools/bgen/bgen/bgenBuffer.py
   vendor/Python/current/Tools/bgen/bgen/bgenGenerator.py
   vendor/Python/current/Tools/bgen/bgen/bgenGeneratorGroup.py
   vendor/Python/current/Tools/bgen/bgen/bgenHeapBuffer.py
   vendor/Python/current/Tools/bgen/bgen/bgenModule.py
   vendor/Python/current/Tools/bgen/bgen/bgenObjectDefinition.py
   vendor/Python/current/Tools/bgen/bgen/bgenOutput.py
   vendor/Python/current/Tools/bgen/bgen/bgenStackBuffer.py
   vendor/Python/current/Tools/bgen/bgen/bgenStringBuffer.py
   vendor/Python/current/Tools/bgen/bgen/bgenType.py
   vendor/Python/current/Tools/bgen/bgen/bgenVariable.py
   vendor/Python/current/Tools/bgen/bgen/macsupport.py
   vendor/Python/current/Tools/bgen/bgen/scantools.py
   vendor/Python/current/Tools/buildbot/
   vendor/Python/current/Tools/buildbot/build.bat
   vendor/Python/current/Tools/buildbot/clean.bat
   vendor/Python/current/Tools/buildbot/external.bat
   vendor/Python/current/Tools/buildbot/kill_python.bat
   vendor/Python/current/Tools/buildbot/kill_python.c
   vendor/Python/current/Tools/buildbot/kill_python.mak
   vendor/Python/current/Tools/buildbot/test.bat
   vendor/Python/current/Tools/compiler/
   vendor/Python/current/Tools/compiler/ACKS
   vendor/Python/current/Tools/compiler/README
   vendor/Python/current/Tools/compiler/ast.txt
   vendor/Python/current/Tools/compiler/astgen.py
   vendor/Python/current/Tools/compiler/compile.py
   vendor/Python/current/Tools/compiler/demo.py
   vendor/Python/current/Tools/compiler/dumppyc.py
   vendor/Python/current/Tools/compiler/regrtest.py
   vendor/Python/current/Tools/compiler/stacktest.py
   vendor/Python/current/Tools/faqwiz/
   vendor/Python/current/Tools/faqwiz/README
   vendor/Python/current/Tools/faqwiz/faqconf.py
   vendor/Python/current/Tools/faqwiz/faqcust.py
   vendor/Python/current/Tools/faqwiz/faqw.py
   vendor/Python/current/Tools/faqwiz/faqwiz.py
   vendor/Python/current/Tools/faqwiz/move-faqwiz.sh
   vendor/Python/current/Tools/framer/
   vendor/Python/current/Tools/framer/README.txt
   vendor/Python/current/Tools/framer/TODO.txt
   vendor/Python/current/Tools/framer/example.py
   vendor/Python/current/Tools/framer/framer/
   vendor/Python/current/Tools/framer/framer/__init__.py
   vendor/Python/current/Tools/framer/framer/bases.py
   vendor/Python/current/Tools/framer/framer/function.py
   vendor/Python/current/Tools/framer/framer/member.py
   vendor/Python/current/Tools/framer/framer/slots.py
   vendor/Python/current/Tools/framer/framer/struct.py
   vendor/Python/current/Tools/framer/framer/structparse.py
   vendor/Python/current/Tools/framer/framer/template.py
   vendor/Python/current/Tools/framer/framer/util.py
   vendor/Python/current/Tools/freeze/
   vendor/Python/current/Tools/freeze/README
   vendor/Python/current/Tools/freeze/bkfile.py
   vendor/Python/current/Tools/freeze/checkextensions.py
   vendor/Python/current/Tools/freeze/checkextensions_win32.py
   vendor/Python/current/Tools/freeze/extensions_win32.ini
   vendor/Python/current/Tools/freeze/freeze.py
   vendor/Python/current/Tools/freeze/hello.py
   vendor/Python/current/Tools/freeze/makeconfig.py
   vendor/Python/current/Tools/freeze/makefreeze.py
   vendor/Python/current/Tools/freeze/makemakefile.py
   vendor/Python/current/Tools/freeze/parsesetup.py
   vendor/Python/current/Tools/freeze/win32.html
   vendor/Python/current/Tools/freeze/winmakemakefile.py
   vendor/Python/current/Tools/i18n/
   vendor/Python/current/Tools/i18n/makelocalealias.py
   vendor/Python/current/Tools/i18n/msgfmt.py
   vendor/Python/current/Tools/i18n/pygettext.py
   vendor/Python/current/Tools/modulator/
   vendor/Python/current/Tools/modulator/EXAMPLE.py
   vendor/Python/current/Tools/modulator/README
   vendor/Python/current/Tools/modulator/ScrolledListbox.py
   vendor/Python/current/Tools/modulator/Templates/
   vendor/Python/current/Tools/modulator/Templates/copyright
   vendor/Python/current/Tools/modulator/Templates/module_head
   vendor/Python/current/Tools/modulator/Templates/module_method
   vendor/Python/current/Tools/modulator/Templates/module_tail
   vendor/Python/current/Tools/modulator/Templates/object_head
   vendor/Python/current/Tools/modulator/Templates/object_method
   vendor/Python/current/Tools/modulator/Templates/object_mlist
   vendor/Python/current/Tools/modulator/Templates/object_new
   vendor/Python/current/Tools/modulator/Templates/object_structure
   vendor/Python/current/Tools/modulator/Templates/object_tail
   vendor/Python/current/Tools/modulator/Templates/object_tp_as_mapping
   vendor/Python/current/Tools/modulator/Templates/object_tp_as_number
   vendor/Python/current/Tools/modulator/Templates/object_tp_as_sequence
   vendor/Python/current/Tools/modulator/Templates/object_tp_call
   vendor/Python/current/Tools/modulator/Templates/object_tp_compare
   vendor/Python/current/Tools/modulator/Templates/object_tp_dealloc
   vendor/Python/current/Tools/modulator/Templates/object_tp_getattr
   vendor/Python/current/Tools/modulator/Templates/object_tp_hash
   vendor/Python/current/Tools/modulator/Templates/object_tp_print
   vendor/Python/current/Tools/modulator/Templates/object_tp_repr
   vendor/Python/current/Tools/modulator/Templates/object_tp_setattr
   vendor/Python/current/Tools/modulator/Templates/object_tp_str
   vendor/Python/current/Tools/modulator/Tkextra.py
   vendor/Python/current/Tools/modulator/genmodule.py
   vendor/Python/current/Tools/modulator/modulator.py
   vendor/Python/current/Tools/modulator/varsubst.py
   vendor/Python/current/Tools/msi/
   vendor/Python/current/Tools/msi/README.txt
   vendor/Python/current/Tools/msi/msi.py
   vendor/Python/current/Tools/msi/msilib.py
   vendor/Python/current/Tools/msi/msisupport.c
   vendor/Python/current/Tools/msi/msisupport.mak
   vendor/Python/current/Tools/msi/schema.py
   vendor/Python/current/Tools/msi/sequence.py
   vendor/Python/current/Tools/msi/uisample.py
   vendor/Python/current/Tools/msi/uuids.py
   vendor/Python/current/Tools/pybench/
   vendor/Python/current/Tools/pybench/Arithmetic.py
   vendor/Python/current/Tools/pybench/Calls.py
   vendor/Python/current/Tools/pybench/CommandLine.py
   vendor/Python/current/Tools/pybench/Constructs.py
   vendor/Python/current/Tools/pybench/Dict.py
   vendor/Python/current/Tools/pybench/Exceptions.py
   vendor/Python/current/Tools/pybench/Imports.py
   vendor/Python/current/Tools/pybench/Instances.py
   vendor/Python/current/Tools/pybench/LICENSE
   vendor/Python/current/Tools/pybench/Lists.py
   vendor/Python/current/Tools/pybench/Lookups.py
   vendor/Python/current/Tools/pybench/NewInstances.py
   vendor/Python/current/Tools/pybench/Numbers.py
   vendor/Python/current/Tools/pybench/README
   vendor/Python/current/Tools/pybench/Setup.py
   vendor/Python/current/Tools/pybench/Strings.py
   vendor/Python/current/Tools/pybench/Tuples.py
   vendor/Python/current/Tools/pybench/Unicode.py
   vendor/Python/current/Tools/pybench/clockres.py
   vendor/Python/current/Tools/pybench/package/
   vendor/Python/current/Tools/pybench/package/__init__.py
   vendor/Python/current/Tools/pybench/package/submodule.py
   vendor/Python/current/Tools/pybench/pybench.py
   vendor/Python/current/Tools/pybench/systimes.py
   vendor/Python/current/Tools/pynche/
   vendor/Python/current/Tools/pynche/ChipViewer.py
   vendor/Python/current/Tools/pynche/ColorDB.py
   vendor/Python/current/Tools/pynche/DetailsViewer.py
   vendor/Python/current/Tools/pynche/ListViewer.py
   vendor/Python/current/Tools/pynche/Main.py
   vendor/Python/current/Tools/pynche/PyncheWidget.py
   vendor/Python/current/Tools/pynche/README
   vendor/Python/current/Tools/pynche/StripViewer.py
   vendor/Python/current/Tools/pynche/Switchboard.py
   vendor/Python/current/Tools/pynche/TextViewer.py
   vendor/Python/current/Tools/pynche/TypeinViewer.py
   vendor/Python/current/Tools/pynche/X/
   vendor/Python/current/Tools/pynche/X/rgb.txt
   vendor/Python/current/Tools/pynche/X/xlicense.txt
   vendor/Python/current/Tools/pynche/__init__.py
   vendor/Python/current/Tools/pynche/html40colors.txt
   vendor/Python/current/Tools/pynche/namedcolors.txt
   vendor/Python/current/Tools/pynche/pyColorChooser.py
   vendor/Python/current/Tools/pynche/pynche
   vendor/Python/current/Tools/pynche/pynche.pyw
   vendor/Python/current/Tools/pynche/webcolors.txt
   vendor/Python/current/Tools/pynche/websafe.txt
   vendor/Python/current/Tools/scripts/
   vendor/Python/current/Tools/scripts/README
   vendor/Python/current/Tools/scripts/byext.py
   vendor/Python/current/Tools/scripts/byteyears.py
   vendor/Python/current/Tools/scripts/checkappend.py
   vendor/Python/current/Tools/scripts/checkpyc.py
   vendor/Python/current/Tools/scripts/classfix.py
   vendor/Python/current/Tools/scripts/cleanfuture.py
   vendor/Python/current/Tools/scripts/combinerefs.py
   vendor/Python/current/Tools/scripts/copytime.py
   vendor/Python/current/Tools/scripts/crlf.py
   vendor/Python/current/Tools/scripts/cvsfiles.py
   vendor/Python/current/Tools/scripts/db2pickle.py
   vendor/Python/current/Tools/scripts/diff.py
   vendor/Python/current/Tools/scripts/dutree.doc
   vendor/Python/current/Tools/scripts/dutree.py
   vendor/Python/current/Tools/scripts/eptags.py
   vendor/Python/current/Tools/scripts/finddiv.py
   vendor/Python/current/Tools/scripts/findlinksto.py
   vendor/Python/current/Tools/scripts/findnocoding.py
   vendor/Python/current/Tools/scripts/fixcid.py
   vendor/Python/current/Tools/scripts/fixdiv.py
   vendor/Python/current/Tools/scripts/fixheader.py
   vendor/Python/current/Tools/scripts/fixnotice.py
   vendor/Python/current/Tools/scripts/fixps.py
   vendor/Python/current/Tools/scripts/ftpmirror.py
   vendor/Python/current/Tools/scripts/google.py
   vendor/Python/current/Tools/scripts/gprof2html.py
   vendor/Python/current/Tools/scripts/h2py.py
   vendor/Python/current/Tools/scripts/hotshotmain.py
   vendor/Python/current/Tools/scripts/idle
   vendor/Python/current/Tools/scripts/ifdef.py
   vendor/Python/current/Tools/scripts/lfcr.py
   vendor/Python/current/Tools/scripts/linktree.py
   vendor/Python/current/Tools/scripts/lll.py
   vendor/Python/current/Tools/scripts/logmerge.py
   vendor/Python/current/Tools/scripts/mailerdaemon.py
   vendor/Python/current/Tools/scripts/md5sum.py
   vendor/Python/current/Tools/scripts/methfix.py
   vendor/Python/current/Tools/scripts/mkreal.py
   vendor/Python/current/Tools/scripts/ndiff.py
   vendor/Python/current/Tools/scripts/nm2def.py
   vendor/Python/current/Tools/scripts/objgraph.py
   vendor/Python/current/Tools/scripts/parseentities.py
   vendor/Python/current/Tools/scripts/pathfix.py
   vendor/Python/current/Tools/scripts/pdeps.py
   vendor/Python/current/Tools/scripts/pickle2db.py
   vendor/Python/current/Tools/scripts/pindent.py
   vendor/Python/current/Tools/scripts/ptags.py
   vendor/Python/current/Tools/scripts/pydoc
   vendor/Python/current/Tools/scripts/pydocgui.pyw
   vendor/Python/current/Tools/scripts/pysource.py
   vendor/Python/current/Tools/scripts/redemo.py
   vendor/Python/current/Tools/scripts/reindent.py
   vendor/Python/current/Tools/scripts/rgrep.py
   vendor/Python/current/Tools/scripts/setup.py
   vendor/Python/current/Tools/scripts/suff.py
   vendor/Python/current/Tools/scripts/svneol.py
   vendor/Python/current/Tools/scripts/texcheck.py
   vendor/Python/current/Tools/scripts/texi2html.py
   vendor/Python/current/Tools/scripts/treesync.py
   vendor/Python/current/Tools/scripts/untabify.py
   vendor/Python/current/Tools/scripts/which.py
   vendor/Python/current/Tools/scripts/xxci.py
   vendor/Python/current/Tools/unicode/
   vendor/Python/current/Tools/unicode/comparecodecs.py
   vendor/Python/current/Tools/unicode/gencjkcodecs.py
   vendor/Python/current/Tools/unicode/gencodec.py
   vendor/Python/current/Tools/unicode/listcodecs.py
   vendor/Python/current/Tools/unicode/makeunicodedata.py
   vendor/Python/current/Tools/unicode/mkstringprep.py
   vendor/Python/current/Tools/unicode/python-mappings/
   vendor/Python/current/Tools/unicode/python-mappings/CP1140.TXT
   vendor/Python/current/Tools/unicode/python-mappings/KOI8-U.TXT
   vendor/Python/current/Tools/unicode/python-mappings/TIS-620.TXT
   vendor/Python/current/Tools/versioncheck/
   vendor/Python/current/Tools/versioncheck/README
   vendor/Python/current/Tools/versioncheck/_checkversion.py
   vendor/Python/current/Tools/versioncheck/checkversions.py
   vendor/Python/current/Tools/versioncheck/pyversioncheck.py
   vendor/Python/current/Tools/webchecker/
   vendor/Python/current/Tools/webchecker/README
   vendor/Python/current/Tools/webchecker/tktools.py
   vendor/Python/current/Tools/webchecker/wcgui.py
   vendor/Python/current/Tools/webchecker/wcmac.py
   vendor/Python/current/Tools/webchecker/webchecker.py
   vendor/Python/current/Tools/webchecker/websucker.py
   vendor/Python/current/Tools/webchecker/wsgui.py
   vendor/Python/current/Tools/world/
   vendor/Python/current/Tools/world/README
   vendor/Python/current/Tools/world/world
   vendor/Python/current/configure.in
   vendor/Python/current/install-sh
   vendor/Python/current/pyconfig.h.in
   vendor/Python/current/setup.py
Log:
Imported Python.

Added: vendor/Python/current/Demo/README
===================================================================
--- vendor/Python/current/Demo/README	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/README	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,61 @@
+This directory contains various demonstrations of what you can do with
+Python.  They were all written by me except where explicitly stated
+otherwise -- in general, demos contributed by others ends up in the
+../Contrib directory, unless I think they're of utmost general
+importance (like Matt Conway's Tk demos).
+
+A fair number of utilities that are useful when while developing
+Python code can be found in the ../Tools directory -- some of these
+can also be considered good examples of how to write Python code.
+
+Finally, in order to save disk space and net bandwidth, not all
+subdirectories listed here are distributed.  They are listed just
+in case I change my mind about them.
+
+
+cgi             CGI examples (see also ../Tools/faqwiz/.)
+
+classes		Some examples of how to use classes.
+
+comparisons	A set of responses to a really old language-comparison
+		challenge.
+
+curses		A set of curses demos.
+
+embed		An example of embedding Python in another application
+		(see also pysvr).
+
+imputil		Demonstration subclasses of imputil.Importer.
+
+md5test		Test program for the optional md5 module.
+
+metaclasses	The code from the 1.5 metaclasses paper on the web.
+
+parser		Example using the parser module.
+
+pdist		Old, unfinished code messing with CVS, RCS and remote
+		files.
+
+pysvr		An example of embedding Python in a threaded
+		application.
+
+rpc		A set of classes for building clients and servers for
+		Sun RPC.
+
+scripts		Some useful Python scripts that I put in my bin
+		directory.  No optional built-in modules needed.
+
+sockets		Examples for the new built-in module 'socket'.
+
+threads		Demos that use the 'thread' module.  (Currently these
+		only run on SGIs, but this may change in the future.)
+
+tix		Demos using the Tix widget set addition to Tkinter.
+
+tkinter		Demos using the Tk interface (including Matt Conway's
+		excellent set of demos).
+
+xml		Some XML demos.
+
+zlib		Some demos for the zlib module (see also the standard
+		library module gzip.py).

Added: vendor/Python/current/Demo/cgi/README
===================================================================
--- vendor/Python/current/Demo/cgi/README	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/cgi/README	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,11 @@
+CGI Examples
+------------
+
+Here are some example CGI programs.  For a larger example, see
+../../Tools/faqwiz/.
+
+cgi0.sh -- A shell script to test your server is configured for CGI
+cgi1.py -- A Python script to test your server is configured for CGI
+cgi2.py -- A Python script showing how to parse a form
+cgi3.py -- A Python script for driving an arbitrary CGI application
+wiki.py -- Sample CGI application: a minimal Wiki implementation

Added: vendor/Python/current/Demo/cgi/cgi0.sh
===================================================================
--- vendor/Python/current/Demo/cgi/cgi0.sh	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/cgi/cgi0.sh	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,8 @@
+#! /bin/sh
+
+# If you can't get this to work, your web server isn't set up right
+
+echo Content-type: text/plain
+echo
+echo Hello world
+echo This is cgi0.sh


Property changes on: vendor/Python/current/Demo/cgi/cgi0.sh
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/cgi/cgi1.py
===================================================================
--- vendor/Python/current/Demo/cgi/cgi1.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/cgi/cgi1.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,14 @@
+#!/usr/local/bin/python
+
+"""CGI test 1 - check server setup."""
+
+# Until you get this to work, your web server isn't set up right or
+# your Python isn't set up right.
+
+# If cgi0.sh works but cgi1.py doesn't, check the #! line and the file
+# permissions.  The docs for the cgi.py module have debugging tips.
+
+print "Content-type: text/html"
+print
+print "<h1>Hello world</h1>"
+print "<p>This is cgi1.py"


Property changes on: vendor/Python/current/Demo/cgi/cgi1.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/cgi/cgi2.py
===================================================================
--- vendor/Python/current/Demo/cgi/cgi2.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/cgi/cgi2.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,22 @@
+#!/usr/local/bin/python
+
+"""CGI test 2 - basic use of cgi module."""
+
+import cgitb; cgitb.enable()
+
+import cgi
+
+def main():
+    form = cgi.FieldStorage()
+    print "Content-type: text/html"
+    print
+    if not form:
+        print "<h1>No Form Keys</h1>"
+    else:
+        print "<h1>Form Keys</h1>"
+        for key in form.keys():
+            value = form[key].value
+            print "<p>", cgi.escape(key), ":", cgi.escape(value)
+
+if __name__ == "__main__":
+    main()


Property changes on: vendor/Python/current/Demo/cgi/cgi2.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/cgi/cgi3.py
===================================================================
--- vendor/Python/current/Demo/cgi/cgi3.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/cgi/cgi3.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,10 @@
+#!/usr/local/bin/python
+
+"""CGI test 3 (persistent data)."""
+
+import cgitb; cgitb.enable()
+
+from wiki import main
+
+if __name__ == "__main__":
+    main()


Property changes on: vendor/Python/current/Demo/cgi/cgi3.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/cgi/wiki.py
===================================================================
--- vendor/Python/current/Demo/cgi/wiki.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/cgi/wiki.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,123 @@
+"""Wiki main program.  Imported and run by cgi3.py."""
+
+import os, re, cgi, sys, tempfile
+escape = cgi.escape
+
+def main():
+    form = cgi.FieldStorage()
+    print "Content-type: text/html"
+    print
+    cmd = form.getvalue("cmd", "view")
+    page = form.getvalue("page", "FrontPage")
+    wiki = WikiPage(page)
+    method = getattr(wiki, 'cmd_' + cmd, None) or wiki.cmd_view
+    method(form)
+
+class WikiPage:
+
+    homedir = tempfile.gettempdir()
+    scripturl = os.path.basename(sys.argv[0])
+
+    def __init__(self, name):
+        if not self.iswikiword(name):
+            raise ValueError, "page name is not a wiki word"
+        self.name = name
+        self.load()
+
+    def cmd_view(self, form):
+        print "<h1>", escape(self.splitwikiword(self.name)), "</h1>"
+        print "<p>"
+        for line in self.data.splitlines():
+            line = line.rstrip()
+            if not line:
+                print "<p>"
+            else:
+                print self.formatline(line)
+        print "<hr>"
+        print "<p>", self.mklink("edit", self.name, "Edit this page") + ";"
+        print self.mklink("view", "FrontPage", "go to front page") + "."
+
+    def formatline(self, line):
+        words = []
+        for word in re.split('(\W+)', line):
+            if self.iswikiword(word):
+                if os.path.isfile(self.mkfile(word)):
+                    word = self.mklink("view", word, word)
+                else:
+                    word = self.mklink("new", word, word + "*")
+            else:
+                word = escape(word)
+            words.append(word)
+        return "".join(words)
+
+    def cmd_edit(self, form, label="Change"):
+        print "<h1>", label, self.name, "</h1>"
+        print '<form method="POST" action="%s">' % self.scripturl
+        s = '<textarea cols="70" rows="20" name="text">%s</textarea>'
+        print s % self.data
+        print '<input type="hidden" name="cmd" value="create">'
+        print '<input type="hidden" name="page" value="%s">' % self.name
+        print '<br>'
+        print '<input type="submit" value="%s Page">' % label
+        print "</form>"
+
+    def cmd_create(self, form):
+        self.data = form.getvalue("text", "").strip()
+        error = self.store()
+        if error:
+            print "<h1>I'm sorry.  That didn't work</h1>"
+            print "<p>An error occurred while attempting to write the file:"
+            print "<p>", escape(error)
+        else:
+            # Use a redirect directive, to avoid "reload page" problems
+            print "<head>"
+            s = '<meta http-equiv="refresh" content="1; URL=%s">'
+            print s % (self.scripturl + "?cmd=view&page=" + self.name)
+            print "<head>"
+            print "<h1>OK</h1>"
+            print "<p>If nothing happens, please click here:",
+            print self.mklink("view", self.name, self.name)
+
+    def cmd_new(self, form):
+        self.cmd_edit(form, label="Create")
+
+    def iswikiword(self, word):
+        return re.match("[A-Z][a-z]+([A-Z][a-z]*)+", word)
+
+    def splitwikiword(self, word):
+        chars = []
+        for c in word:
+            if chars and c.isupper():
+                chars.append(' ')
+            chars.append(c)
+        return "".join(chars)
+
+    def mkfile(self, name=None):
+        if name is None:
+            name = self.name
+        return os.path.join(self.homedir, name + ".txt")
+
+    def mklink(self, cmd, page, text):
+        link = self.scripturl + "?cmd=" + cmd + "&page=" + page
+        return '<a href="%s">%s</a>' % (link, text)
+
+    def load(self):
+        try:
+            f = open(self.mkfile())
+            data = f.read().strip()
+            f.close()
+        except IOError:
+            data = ""
+        self.data = data
+
+    def store(self):
+        data = self.data
+        try:
+            f = open(self.mkfile(), "w")
+            f.write(data)
+            if data and not data.endswith('\n'):
+                f.write('\n')
+            f.close()
+            return ""
+        except IOError, err:
+            return "IOError: %s" % str(err)

Added: vendor/Python/current/Demo/classes/Complex.py
===================================================================
--- vendor/Python/current/Demo/classes/Complex.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/classes/Complex.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,320 @@
+# Complex numbers
+# ---------------
+
+# [Now that Python has a complex data type built-in, this is not very
+# useful, but it's still a nice example class]
+
+# This module represents complex numbers as instances of the class Complex.
+# A Complex instance z has two data attribues, z.re (the real part) and z.im
+# (the imaginary part).  In fact, z.re and z.im can have any value -- all
+# arithmetic operators work regardless of the type of z.re and z.im (as long
+# as they support numerical operations).
+#
+# The following functions exist (Complex is actually a class):
+# Complex([re [,im]) -> creates a complex number from a real and an imaginary part
+# IsComplex(z) -> true iff z is a complex number (== has .re and .im attributes)
+# ToComplex(z) -> a complex number equal to z; z itself if IsComplex(z) is true
+#                 if z is a tuple(re, im) it will also be converted
+# PolarToComplex([r [,phi [,fullcircle]]]) ->
+#       the complex number z for which r == z.radius() and phi == z.angle(fullcircle)
+#       (r and phi default to 0)
+# exp(z) -> returns the complex exponential of z. Equivalent to pow(math.e,z).
+#
+# Complex numbers have the following methods:
+# z.abs() -> absolute value of z
+# z.radius() == z.abs()
+# z.angle([fullcircle]) -> angle from positive X axis; fullcircle gives units
+# z.phi([fullcircle]) == z.angle(fullcircle)
+#
+# These standard functions and unary operators accept complex arguments:
+# abs(z)
+# -z
+# +z
+# not z
+# repr(z) == `z`
+# str(z)
+# hash(z) -> a combination of hash(z.re) and hash(z.im) such that if z.im is zero
+#            the result equals hash(z.re)
+# Note that hex(z) and oct(z) are not defined.
+#
+# These conversions accept complex arguments only if their imaginary part is zero:
+# int(z)
+# long(z)
+# float(z)
+#
+# The following operators accept two complex numbers, or one complex number
+# and one real number (int, long or float):
+# z1 + z2
+# z1 - z2
+# z1 * z2
+# z1 / z2
+# pow(z1, z2)
+# cmp(z1, z2)
+# Note that z1 % z2 and divmod(z1, z2) are not defined,
+# nor are shift and mask operations.
+#
+# The standard module math does not support complex numbers.
+# The cmath modules should be used instead.
+#
+# Idea:
+# add a class Polar(r, phi) and mixed-mode arithmetic which
+# chooses the most appropriate type for the result:
+# Complex for +,-,cmp
+# Polar   for *,/,pow
+
+import math
+import sys
+
+twopi = math.pi*2.0
+halfpi = math.pi/2.0
+
+def IsComplex(obj):
+    return hasattr(obj, 're') and hasattr(obj, 'im')
+
+def ToComplex(obj):
+    if IsComplex(obj):
+        return obj
+    elif isinstance(obj, tuple):
+        return Complex(*obj)
+    else:
+        return Complex(obj)
+
+def PolarToComplex(r = 0, phi = 0, fullcircle = twopi):
+    phi = phi * (twopi / fullcircle)
+    return Complex(math.cos(phi)*r, math.sin(phi)*r)
+
+def Re(obj):
+    if IsComplex(obj):
+        return obj.re
+    return obj
+
+def Im(obj):
+    if IsComplex(obj):
+        return obj.im
+    return 0
+
+class Complex:
+
+    def __init__(self, re=0, im=0):
+        _re = 0
+        _im = 0
+        if IsComplex(re):
+            _re = re.re
+            _im = re.im
+        else:
+            _re = re
+        if IsComplex(im):
+            _re = _re - im.im
+            _im = _im + im.re
+        else:
+            _im = _im + im
+        # this class is immutable, so setting self.re directly is
+        # not possible.
+        self.__dict__['re'] = _re
+        self.__dict__['im'] = _im
+
+    def __setattr__(self, name, value):
+        raise TypeError, 'Complex numbers are immutable'
+
+    def __hash__(self):
+        if not self.im:
+            return hash(self.re)
+        return hash((self.re, self.im))
+
+    def __repr__(self):
+        if not self.im:
+            return 'Complex(%r)' % (self.re,)
+        else:
+            return 'Complex(%r, %r)' % (self.re, self.im)
+
+    def __str__(self):
+        if not self.im:
+            return repr(self.re)
+        else:
+            return 'Complex(%r, %r)' % (self.re, self.im)
+
+    def __neg__(self):
+        return Complex(-self.re, -self.im)
+
+    def __pos__(self):
+        return self
+
+    def __abs__(self):
+        return math.hypot(self.re, self.im)
+
+    def __int__(self):
+        if self.im:
+            raise ValueError, "can't convert Complex with nonzero im to int"
+        return int(self.re)
+
+    def __long__(self):
+        if self.im:
+            raise ValueError, "can't convert Complex with nonzero im to long"
+        return long(self.re)
+
+    def __float__(self):
+        if self.im:
+            raise ValueError, "can't convert Complex with nonzero im to float"
+        return float(self.re)
+
+    def __cmp__(self, other):
+        other = ToComplex(other)
+        return cmp((self.re, self.im), (other.re, other.im))
+
+    def __rcmp__(self, other):
+        other = ToComplex(other)
+        return cmp(other, self)
+
+    def __nonzero__(self):
+        return not (self.re == self.im == 0)
+
+    abs = radius = __abs__
+
+    def angle(self, fullcircle = twopi):
+        return (fullcircle/twopi) * ((halfpi - math.atan2(self.re, self.im)) % twopi)
+
+    phi = angle
+
+    def __add__(self, other):
+        other = ToComplex(other)
+        return Complex(self.re + other.re, self.im + other.im)
+
+    __radd__ = __add__
+
+    def __sub__(self, other):
+        other = ToComplex(other)
+        return Complex(self.re - other.re, self.im - other.im)
+
+    def __rsub__(self, other):
+        other = ToComplex(other)
+        return other - self
+
+    def __mul__(self, other):
+        other = ToComplex(other)
+        return Complex(self.re*other.re - self.im*other.im,
+                       self.re*other.im + self.im*other.re)
+
+    __rmul__ = __mul__
+
+    def __div__(self, other):
+        other = ToComplex(other)
+        d = float(other.re*other.re + other.im*other.im)
+        if not d: raise ZeroDivisionError, 'Complex division'
+        return Complex((self.re*other.re + self.im*other.im) / d,
+                       (self.im*other.re - self.re*other.im) / d)
+
+    def __rdiv__(self, other):
+        other = ToComplex(other)
+        return other / self
+
+    def __pow__(self, n, z=None):
+        if z is not None:
+            raise TypeError, 'Complex does not support ternary pow()'
+        if IsComplex(n):
+            if n.im:
+                if self.im: raise TypeError, 'Complex to the Complex power'
+                else: return exp(math.log(self.re)*n)
+            n = n.re
+        r = pow(self.abs(), n)
+        phi = n*self.angle()
+        return Complex(math.cos(phi)*r, math.sin(phi)*r)
+
+    def __rpow__(self, base):
+        base = ToComplex(base)
+        return pow(base, self)
+
+def exp(z):
+    r = math.exp(z.re)
+    return Complex(math.cos(z.im)*r,math.sin(z.im)*r)
+
+
+def checkop(expr, a, b, value, fuzz = 1e-6):
+    print '       ', a, 'and', b,
+    try:
+        result = eval(expr)
+    except:
+        result = sys.exc_type
+    print '->', result
+    if isinstance(result, str) or isinstance(value, str):
+        ok = (result == value)
+    else:
+        ok = abs(result - value) <= fuzz
+    if not ok:
+        print '!!\t!!\t!! should be', value, 'diff', abs(result - value)
+
+def test():
+    print 'test constructors'
+    constructor_test = (
+        # "expect" is an array [re,im] "got" the Complex.
+            ( (0,0), Complex() ),
+            ( (0,0), Complex() ),
+            ( (1,0), Complex(1) ),
+            ( (0,1), Complex(0,1) ),
+            ( (1,2), Complex(Complex(1,2)) ),
+            ( (1,3), Complex(Complex(1,2),1) ),
+            ( (0,0), Complex(0,Complex(0,0)) ),
+            ( (3,4), Complex(3,Complex(4)) ),
+            ( (-1,3), Complex(1,Complex(3,2)) ),
+            ( (-7,6), Complex(Complex(1,2),Complex(4,8)) ) )
+    cnt = [0,0]
+    for t in constructor_test:
+        cnt[0] += 1
+        if ((t[0][0]!=t[1].re)or(t[0][1]!=t[1].im)):
+            print "        expected", t[0], "got", t[1]
+            cnt[1] += 1
+    print "  ", cnt[1], "of", cnt[0], "tests failed"
+    # test operators
+    testsuite = {
+            'a+b': [
+                    (1, 10, 11),
+                    (1, Complex(0,10), Complex(1,10)),
+                    (Complex(0,10), 1, Complex(1,10)),
+                    (Complex(0,10), Complex(1), Complex(1,10)),
+                    (Complex(1), Complex(0,10), Complex(1,10)),
+            ],
+            'a-b': [
+                    (1, 10, -9),
+                    (1, Complex(0,10), Complex(1,-10)),
+                    (Complex(0,10), 1, Complex(-1,10)),
+                    (Complex(0,10), Complex(1), Complex(-1,10)),
+                    (Complex(1), Complex(0,10), Complex(1,-10)),
+            ],
+            'a*b': [
+                    (1, 10, 10),
+                    (1, Complex(0,10), Complex(0, 10)),
+                    (Complex(0,10), 1, Complex(0,10)),
+                    (Complex(0,10), Complex(1), Complex(0,10)),
+                    (Complex(1), Complex(0,10), Complex(0,10)),
+            ],
+            'a/b': [
+                    (1., 10, 0.1),
+                    (1, Complex(0,10), Complex(0, -0.1)),
+                    (Complex(0, 10), 1, Complex(0, 10)),
+                    (Complex(0, 10), Complex(1), Complex(0, 10)),
+                    (Complex(1), Complex(0,10), Complex(0, -0.1)),
+            ],
+            'pow(a,b)': [
+                    (1, 10, 1),
+                    (1, Complex(0,10), 1),
+                    (Complex(0,10), 1, Complex(0,10)),
+                    (Complex(0,10), Complex(1), Complex(0,10)),
+                    (Complex(1), Complex(0,10), 1),
+                    (2, Complex(4,0), 16),
+            ],
+            'cmp(a,b)': [
+                    (1, 10, -1),
+                    (1, Complex(0,10), 1),
+                    (Complex(0,10), 1, -1),
+                    (Complex(0,10), Complex(1), -1),
+                    (Complex(1), Complex(0,10), 1),
+            ],
+    }
+    for expr in sorted(testsuite):
+        print expr + ':'
+        t = (expr,)
+        for item in testsuite[expr]:
+            checkop(*(t+item))
+
+
+if __name__ == '__main__':
+    test()


Property changes on: vendor/Python/current/Demo/classes/Complex.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/classes/Dates.py
===================================================================
--- vendor/Python/current/Demo/classes/Dates.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/classes/Dates.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,222 @@
+# Class Date supplies date objects that support date arithmetic.
+#
+# Date(month,day,year) returns a Date object.  An instance prints as,
+# e.g., 'Mon 16 Aug 1993'.
+#
+# Addition, subtraction, comparison operators, min, max, and sorting
+# all work as expected for date objects:  int+date or date+int returns
+# the date `int' days from `date'; date+date raises an exception;
+# date-int returns the date `int' days before `date'; date2-date1 returns
+# an integer, the number of days from date1 to date2; int-date raises an
+# exception; date1 < date2 is true iff date1 occurs before date2 (&
+# similarly for other comparisons); min(date1,date2) is the earlier of
+# the two dates and max(date1,date2) the later; and date objects can be
+# used as dictionary keys.
+#
+# Date objects support one visible method, date.weekday().  This returns
+# the day of the week the date falls on, as a string.
+#
+# Date objects also have 4 read-only data attributes:
+#   .month  in 1..12
+#   .day    in 1..31
+#   .year   int or long int
+#   .ord    the ordinal of the date relative to an arbitrary staring point
+#
+# The Dates module also supplies function today(), which returns the
+# current date as a date object.
+#
+# Those entranced by calendar trivia will be disappointed, as no attempt
+# has been made to accommodate the Julian (etc) system.  On the other
+# hand, at least this package knows that 2000 is a leap year but 2100
+# isn't, and works fine for years with a hundred decimal digits <wink>.
+
+# Tim Peters   tim at ksr.com
+# not speaking for Kendall Square Research Corp
+
+# Adapted to Python 1.1 (where some hacks to overcome coercion are unnecessary)
+# by Guido van Rossum
+
+# Note that as of Python 2.3, a datetime module is included in the stardard
+# library.
+
+# vi:set tabsize=8:
+
+_MONTH_NAMES = [ 'January', 'February', 'March', 'April', 'May',
+                 'June', 'July', 'August', 'September', 'October',
+                 'November', 'December' ]
+
+_DAY_NAMES = [ 'Friday', 'Saturday', 'Sunday', 'Monday',
+               'Tuesday', 'Wednesday', 'Thursday' ]
+
+_DAYS_IN_MONTH = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ]
+
+_DAYS_BEFORE_MONTH = []
+dbm = 0
+for dim in _DAYS_IN_MONTH:
+    _DAYS_BEFORE_MONTH.append(dbm)
+    dbm = dbm + dim
+del dbm, dim
+
+_INT_TYPES = type(1), type(1L)
+
+def _is_leap(year):           # 1 if leap year, else 0
+    if year % 4 != 0: return 0
+    if year % 400 == 0: return 1
+    return year % 100 != 0
+
+def _days_in_year(year):      # number of days in year
+    return 365 + _is_leap(year)
+
+def _days_before_year(year):  # number of days before year
+    return year*365L + (year+3)/4 - (year+99)/100 + (year+399)/400
+
+def _days_in_month(month, year):      # number of days in month of year
+    if month == 2 and _is_leap(year): return 29
+    return _DAYS_IN_MONTH[month-1]
+
+def _days_before_month(month, year):  # number of days in year before month
+    return _DAYS_BEFORE_MONTH[month-1] + (month > 2 and _is_leap(year))
+
+def _date2num(date):          # compute ordinal of date.month,day,year
+    return _days_before_year(date.year) + \
+           _days_before_month(date.month, date.year) + \
+           date.day
+
+_DI400Y = _days_before_year(400)      # number of days in 400 years
+
+def _num2date(n):             # return date with ordinal n
+    if type(n) not in _INT_TYPES:
+        raise TypeError, 'argument must be integer: %r' % type(n)
+
+    ans = Date(1,1,1)   # arguments irrelevant; just getting a Date obj
+    del ans.ord, ans.month, ans.day, ans.year # un-initialize it
+    ans.ord = n
+
+    n400 = (n-1)/_DI400Y                # # of 400-year blocks preceding
+    year, n = 400 * n400, n - _DI400Y * n400
+    more = n / 365
+    dby = _days_before_year(more)
+    if dby >= n:
+        more = more - 1
+        dby = dby - _days_in_year(more)
+    year, n = year + more, int(n - dby)
+
+    try: year = int(year)               # chop to int, if it fits
+    except (ValueError, OverflowError): pass
+
+    month = min(n/29 + 1, 12)
+    dbm = _days_before_month(month, year)
+    if dbm >= n:
+        month = month - 1
+        dbm = dbm - _days_in_month(month, year)
+
+    ans.month, ans.day, ans.year = month, n-dbm, year
+    return ans
+
+def _num2day(n):      # return weekday name of day with ordinal n
+    return _DAY_NAMES[ int(n % 7) ]
+
+
+class Date:
+    def __init__(self, month, day, year):
+        if not 1 <= month <= 12:
+            raise ValueError, 'month must be in 1..12: %r' % (month,)
+        dim = _days_in_month(month, year)
+        if not 1 <= day <= dim:
+            raise ValueError, 'day must be in 1..%r: %r' % (dim, day)
+        self.month, self.day, self.year = month, day, year
+        self.ord = _date2num(self)
+
+    # don't allow setting existing attributes
+    def __setattr__(self, name, value):
+        if self.__dict__.has_key(name):
+            raise AttributeError, 'read-only attribute ' + name
+        self.__dict__[name] = value
+
+    def __cmp__(self, other):
+        return cmp(self.ord, other.ord)
+
+    # define a hash function so dates can be used as dictionary keys
+    def __hash__(self):
+        return hash(self.ord)
+
+    # print as, e.g., Mon 16 Aug 1993
+    def __repr__(self):
+        return '%.3s %2d %.3s %r' % (
+              self.weekday(),
+              self.day,
+              _MONTH_NAMES[self.month-1],
+              self.year)
+
+    # Python 1.1 coerces neither int+date nor date+int
+    def __add__(self, n):
+        if type(n) not in _INT_TYPES:
+            raise TypeError, 'can\'t add %r to date' % type(n)
+        return _num2date(self.ord + n)
+    __radd__ = __add__ # handle int+date
+
+    # Python 1.1 coerces neither date-int nor date-date
+    def __sub__(self, other):
+        if type(other) in _INT_TYPES:           # date-int
+            return _num2date(self.ord - other)
+        else:
+            return self.ord - other.ord         # date-date
+
+    # complain about int-date
+    def __rsub__(self, other):
+        raise TypeError, 'Can\'t subtract date from integer'
+
+    def weekday(self):
+        return _num2day(self.ord)
+
+def today():
+    import time
+    local = time.localtime(time.time())
+    return Date(local[1], local[2], local[0])
+
+DateTestError = 'DateTestError'
+def test(firstyear, lastyear):
+    a = Date(9,30,1913)
+    b = Date(9,30,1914)
+    if repr(a) != 'Tue 30 Sep 1913':
+        raise DateTestError, '__repr__ failure'
+    if (not a < b) or a == b or a > b or b != b:
+        raise DateTestError, '__cmp__ failure'
+    if a+365 != b or 365+a != b:
+        raise DateTestError, '__add__ failure'
+    if b-a != 365 or b-365 != a:
+        raise DateTestError, '__sub__ failure'
+    try:
+        x = 1 - a
+        raise DateTestError, 'int-date should have failed'
+    except TypeError:
+        pass
+    try:
+        x = a + b
+        raise DateTestError, 'date+date should have failed'
+    except TypeError:
+        pass
+    if a.weekday() != 'Tuesday':
+        raise DateTestError, 'weekday() failure'
+    if max(a,b) is not b or min(a,b) is not a:
+        raise DateTestError, 'min/max failure'
+    d = {a-1:b, b:a+1}
+    if d[b-366] != b or d[a+(b-a)] != Date(10,1,1913):
+        raise DateTestError, 'dictionary failure'
+
+    # verify date<->number conversions for first and last days for
+    # all years in firstyear .. lastyear
+
+    lord = _days_before_year(firstyear)
+    y = firstyear
+    while y <= lastyear:
+        ford = lord + 1
+        lord = ford + _days_in_year(y) - 1
+        fd, ld = Date(1,1,y), Date(12,31,y)
+        if (fd.ord,ld.ord) != (ford,lord):
+            raise DateTestError, ('date->num failed', y)
+        fd, ld = _num2date(ford), _num2date(lord)
+        if (1,1,y,12,31,y) != \
+           (fd.month,fd.day,fd.year,ld.month,ld.day,ld.year):
+            raise DateTestError, ('num->date failed', y)
+        y = y + 1


Property changes on: vendor/Python/current/Demo/classes/Dates.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/classes/Dbm.py
===================================================================
--- vendor/Python/current/Demo/classes/Dbm.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/classes/Dbm.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,66 @@
+# A wrapper around the (optional) built-in class dbm, supporting keys
+# and values of almost any type instead of just string.
+# (Actually, this works only for keys and values that can be read back
+# correctly after being converted to a string.)
+
+
+class Dbm:
+
+    def __init__(self, filename, mode, perm):
+        import dbm
+        self.db = dbm.open(filename, mode, perm)
+
+    def __repr__(self):
+        s = ''
+        for key in self.keys():
+            t = repr(key) + ': ' + repr(self[key])
+            if s: t = ', ' + t
+            s = s + t
+        return '{' + s + '}'
+
+    def __len__(self):
+        return len(self.db)
+
+    def __getitem__(self, key):
+        return eval(self.db[repr(key)])
+
+    def __setitem__(self, key, value):
+        self.db[repr(key)] = repr(value)
+
+    def __delitem__(self, key):
+        del self.db[repr(key)]
+
+    def keys(self):
+        res = []
+        for key in self.db.keys():
+            res.append(eval(key))
+        return res
+
+    def has_key(self, key):
+        return self.db.has_key(repr(key))
+
+
+def test():
+    d = Dbm('@dbm', 'rw', 0600)
+    print d
+    while 1:
+        try:
+            key = input('key: ')
+            if d.has_key(key):
+                value = d[key]
+                print 'currently:', value
+            value = input('value: ')
+            if value == None:
+                del d[key]
+            else:
+                d[key] = value
+        except KeyboardInterrupt:
+            print ''
+            print d
+        except EOFError:
+            print '[eof]'
+            break
+    print d
+
+
+test()


Property changes on: vendor/Python/current/Demo/classes/Dbm.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/classes/README
===================================================================
--- vendor/Python/current/Demo/classes/README	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/classes/README	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,13 @@
+Examples of classes that implement special operators (see reference manual):
+
+Complex.py	Complex numbers
+Dates.py	Date manipulation package by Tim Peters
+Dbm.py		Wrapper around built-in dbm, supporting	arbitrary values
+Range.py	Example of a generator: re-implement built-in range()
+Rat.py		Rational numbers
+Rev.py		Yield the reverse of a sequence
+Vec.py		A simple vector class
+bitvec.py	A bit-vector class by Jan-Hein B\"uhrman
+
+(For straightforward examples of basic class features, such as use of
+methods and inheritance, see the library code.)

Added: vendor/Python/current/Demo/classes/Range.py
===================================================================
--- vendor/Python/current/Demo/classes/Range.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/classes/Range.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,93 @@
+"""Example of a generator: re-implement the built-in range function
+without actually constructing the list of values.
+
+OldStyleRange is coded in the way required to work in a 'for' loop before
+iterators were introduced into the language; using __getitem__ and __len__ .
+
+"""
+def handleargs(arglist):
+    """Take list of arguments and extract/create proper start, stop, and step
+    values and return in a tuple"""
+    try:
+        if len(arglist) == 1:
+            return 0, int(arglist[0]), 1
+        elif len(arglist) == 2:
+            return int(arglist[0]), int(arglist[1]), 1
+        elif len(arglist) == 3:
+            if arglist[2] == 0:
+                raise ValueError("step argument must not be zero")
+            return tuple(int(x) for x in arglist)
+        else:
+            raise TypeError("range() accepts 1-3 arguments, given", len(arglist))
+    except TypeError:
+        raise TypeError("range() arguments must be numbers or strings "
+        "representing numbers")
+
+def genrange(*a):
+    """Function to implement 'range' as a generator"""
+    start, stop, step = handleargs(a)
+    value = start
+    while value < stop:
+        yield value
+        value += step
+
+class oldrange:
+    """Class implementing a range object.
+    To the user the instances feel like immutable sequences
+    (and you can't concatenate or slice them)
+
+    Done using the old way (pre-iterators; __len__ and __getitem__) to have an
+    object be used by a 'for' loop.
+
+    """
+
+    def __init__(self, *a):
+        """ Initialize start, stop, and step values along with calculating the
+        nubmer of values (what __len__ will return) in the range"""
+        self.start, self.stop, self.step = handleargs(a)
+        self.len = max(0, (self.stop - self.start) // self.step)
+
+    def __repr__(self):
+        """implement repr(x) which is also used by print"""
+        return 'range(%r, %r, %r)' % (self.start, self.stop, self.step)
+
+    def __len__(self):
+        """implement len(x)"""
+        return self.len
+
+    def __getitem__(self, i):
+        """implement x[i]"""
+        if 0 <= i <= self.len:
+            return self.start + self.step * i
+        else:
+            raise IndexError, 'range[i] index out of range'
+
+
+def test():
+    import time, __builtin__
+    #Just a quick sanity check
+    correct_result = __builtin__.range(5, 100, 3)
+    oldrange_result = list(oldrange(5, 100, 3))
+    genrange_result = list(genrange(5, 100, 3))
+    if genrange_result != correct_result or oldrange_result != correct_result:
+        raise Exception("error in implementation:\ncorrect   = %s"
+                         "\nold-style = %s\ngenerator = %s" %
+                         (correct_result, oldrange_result, genrange_result))
+    print "Timings for range(1000):"
+    t1 = time.time()
+    for i in oldrange(1000):
+        pass
+    t2 = time.time()
+    for i in genrange(1000):
+        pass
+    t3 = time.time()
+    for i in __builtin__.range(1000):
+        pass
+    t4 = time.time()
+    print t2-t1, 'sec (old-style class)'
+    print t3-t2, 'sec (generator)'
+    print t4-t3, 'sec (built-in)'
+
+
+if __name__ == '__main__':
+    test()


Property changes on: vendor/Python/current/Demo/classes/Range.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/classes/Rat.py
===================================================================
--- vendor/Python/current/Demo/classes/Rat.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/classes/Rat.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,310 @@
+'''\
+This module implements rational numbers.
+
+The entry point of this module is the function
+        rat(numerator, denominator)
+If either numerator or denominator is of an integral or rational type,
+the result is a rational number, else, the result is the simplest of
+the types float and complex which can hold numerator/denominator.
+If denominator is omitted, it defaults to 1.
+Rational numbers can be used in calculations with any other numeric
+type.  The result of the calculation will be rational if possible.
+
+There is also a test function with calling sequence
+        test()
+The documentation string of the test function contains the expected
+output.
+'''
+
+# Contributed by Sjoerd Mullender
+
+from types import *
+
+def gcd(a, b):
+    '''Calculate the Greatest Common Divisor.'''
+    while b:
+        a, b = b, a%b
+    return a
+
+def rat(num, den = 1):
+    # must check complex before float
+    if isinstance(num, complex) or isinstance(den, complex):
+        # numerator or denominator is complex: return a complex
+        return complex(num) / complex(den)
+    if isinstance(num, float) or isinstance(den, float):
+        # numerator or denominator is float: return a float
+        return float(num) / float(den)
+    # otherwise return a rational
+    return Rat(num, den)
+
+class Rat:
+    '''This class implements rational numbers.'''
+
+    def __init__(self, num, den = 1):
+        if den == 0:
+            raise ZeroDivisionError, 'rat(x, 0)'
+
+        # normalize
+
+        # must check complex before float
+        if (isinstance(num, complex) or
+            isinstance(den, complex)):
+            # numerator or denominator is complex:
+            # normalized form has denominator == 1+0j
+            self.__num = complex(num) / complex(den)
+            self.__den = complex(1)
+            return
+        if isinstance(num, float) or isinstance(den, float):
+            # numerator or denominator is float:
+            # normalized form has denominator == 1.0
+            self.__num = float(num) / float(den)
+            self.__den = 1.0
+            return
+        if (isinstance(num, self.__class__) or
+            isinstance(den, self.__class__)):
+            # numerator or denominator is rational
+            new = num / den
+            if not isinstance(new, self.__class__):
+                self.__num = new
+                if isinstance(new, complex):
+                    self.__den = complex(1)
+                else:
+                    self.__den = 1.0
+            else:
+                self.__num = new.__num
+                self.__den = new.__den
+        else:
+            # make sure numerator and denominator don't
+            # have common factors
+            # this also makes sure that denominator > 0
+            g = gcd(num, den)
+            self.__num = num / g
+            self.__den = den / g
+        # try making numerator and denominator of IntType if they fit
+        try:
+            numi = int(self.__num)
+            deni = int(self.__den)
+        except (OverflowError, TypeError):
+            pass
+        else:
+            if self.__num == numi and self.__den == deni:
+                self.__num = numi
+                self.__den = deni
+
+    def __repr__(self):
+        return 'Rat(%s,%s)' % (self.__num, self.__den)
+
+    def __str__(self):
+        if self.__den == 1:
+            return str(self.__num)
+        else:
+            return '(%s/%s)' % (str(self.__num), str(self.__den))
+
+    # a + b
+    def __add__(a, b):
+        try:
+            return rat(a.__num * b.__den + b.__num * a.__den,
+                       a.__den * b.__den)
+        except OverflowError:
+            return rat(long(a.__num) * long(b.__den) +
+                       long(b.__num) * long(a.__den),
+                       long(a.__den) * long(b.__den))
+
+    def __radd__(b, a):
+        return Rat(a) + b
+
+    # a - b
+    def __sub__(a, b):
+        try:
+            return rat(a.__num * b.__den - b.__num * a.__den,
+                       a.__den * b.__den)
+        except OverflowError:
+            return rat(long(a.__num) * long(b.__den) -
+                       long(b.__num) * long(a.__den),
+                       long(a.__den) * long(b.__den))
+
+    def __rsub__(b, a):
+        return Rat(a) - b
+
+    # a * b
+    def __mul__(a, b):
+        try:
+            return rat(a.__num * b.__num, a.__den * b.__den)
+        except OverflowError:
+            return rat(long(a.__num) * long(b.__num),
+                       long(a.__den) * long(b.__den))
+
+    def __rmul__(b, a):
+        return Rat(a) * b
+
+    # a / b
+    def __div__(a, b):
+        try:
+            return rat(a.__num * b.__den, a.__den * b.__num)
+        except OverflowError:
+            return rat(long(a.__num) * long(b.__den),
+                       long(a.__den) * long(b.__num))
+
+    def __rdiv__(b, a):
+        return Rat(a) / b
+
+    # a % b
+    def __mod__(a, b):
+        div = a / b
+        try:
+            div = int(div)
+        except OverflowError:
+            div = long(div)
+        return a - b * div
+
+    def __rmod__(b, a):
+        return Rat(a) % b
+
+    # a ** b
+    def __pow__(a, b):
+        if b.__den != 1:
+            if isinstance(a.__num, complex):
+                a = complex(a)
+            else:
+                a = float(a)
+            if isinstance(b.__num, complex):
+                b = complex(b)
+            else:
+                b = float(b)
+            return a ** b
+        try:
+            return rat(a.__num ** b.__num, a.__den ** b.__num)
+        except OverflowError:
+            return rat(long(a.__num) ** b.__num,
+                       long(a.__den) ** b.__num)
+
+    def __rpow__(b, a):
+        return Rat(a) ** b
+
+    # -a
+    def __neg__(a):
+        try:
+            return rat(-a.__num, a.__den)
+        except OverflowError:
+            # a.__num == sys.maxint
+            return rat(-long(a.__num), a.__den)
+
+    # abs(a)
+    def __abs__(a):
+        return rat(abs(a.__num), a.__den)
+
+    # int(a)
+    def __int__(a):
+        return int(a.__num / a.__den)
+
+    # long(a)
+    def __long__(a):
+        return long(a.__num) / long(a.__den)
+
+    # float(a)
+    def __float__(a):
+        return float(a.__num) / float(a.__den)
+
+    # complex(a)
+    def __complex__(a):
+        return complex(a.__num) / complex(a.__den)
+
+    # cmp(a,b)
+    def __cmp__(a, b):
+        diff = Rat(a - b)
+        if diff.__num < 0:
+            return -1
+        elif diff.__num > 0:
+            return 1
+        else:
+            return 0
+
+    def __rcmp__(b, a):
+        return cmp(Rat(a), b)
+
+    # a != 0
+    def __nonzero__(a):
+        return a.__num != 0
+
+    # coercion
+    def __coerce__(a, b):
+        return a, Rat(b)
+
+def test():
+    '''\
+    Test function for rat module.
+
+    The expected output is (module some differences in floating
+    precission):
+    -1
+    -1
+    0 0L 0.1 (0.1+0j)
+    [Rat(1,2), Rat(-3,10), Rat(1,25), Rat(1,4)]
+    [Rat(-3,10), Rat(1,25), Rat(1,4), Rat(1,2)]
+    0
+    (11/10)
+    (11/10)
+    1.1
+    OK
+    2 1.5 (3/2) (1.5+1.5j) (15707963/5000000)
+    2 2 2.0 (2+0j)
+
+    4 0 4 1 4 0
+    3.5 0.5 3.0 1.33333333333 2.82842712475 1
+    (7/2) (1/2) 3 (4/3) 2.82842712475 1
+    (3.5+1.5j) (0.5-1.5j) (3+3j) (0.666666666667-0.666666666667j) (1.43248815986+2.43884761145j) 1
+    1.5 1 1.5 (1.5+0j)
+
+    3.5 -0.5 3.0 0.75 2.25 -1
+    3.0 0.0 2.25 1.0 1.83711730709 0
+    3.0 0.0 2.25 1.0 1.83711730709 1
+    (3+1.5j) -1.5j (2.25+2.25j) (0.5-0.5j) (1.50768393746+1.04970907623j) -1
+    (3/2) 1 1.5 (1.5+0j)
+
+    (7/2) (-1/2) 3 (3/4) (9/4) -1
+    3.0 0.0 2.25 1.0 1.83711730709 -1
+    3 0 (9/4) 1 1.83711730709 0
+    (3+1.5j) -1.5j (2.25+2.25j) (0.5-0.5j) (1.50768393746+1.04970907623j) -1
+    (1.5+1.5j) (1.5+1.5j)
+
+    (3.5+1.5j) (-0.5+1.5j) (3+3j) (0.75+0.75j) 4.5j -1
+    (3+1.5j) 1.5j (2.25+2.25j) (1+1j) (1.18235814075+2.85446505899j) 1
+    (3+1.5j) 1.5j (2.25+2.25j) (1+1j) (1.18235814075+2.85446505899j) 1
+    (3+3j) 0j 4.5j (1+0j) (-0.638110484918+0.705394566962j) 0
+    '''
+    print rat(-1L, 1)
+    print rat(1, -1)
+    a = rat(1, 10)
+    print int(a), long(a), float(a), complex(a)
+    b = rat(2, 5)
+    l = [a+b, a-b, a*b, a/b]
+    print l
+    l.sort()
+    print l
+    print rat(0, 1)
+    print a+1
+    print a+1L
+    print a+1.0
+    try:
+        print rat(1, 0)
+        raise SystemError, 'should have been ZeroDivisionError'
+    except ZeroDivisionError:
+        print 'OK'
+    print rat(2), rat(1.5), rat(3, 2), rat(1.5+1.5j), rat(31415926,10000000)
+    list = [2, 1.5, rat(3,2), 1.5+1.5j]
+    for i in list:
+        print i,
+        if not isinstance(i, complex):
+            print int(i), float(i),
+        print complex(i)
+        print
+        for j in list:
+            print i + j, i - j, i * j, i / j, i ** j,
+            if not (isinstance(i, complex) or
+                    isinstance(j, complex)):
+                print cmp(i, j)
+            print
+
+
+if __name__ == '__main__':
+    test()


Property changes on: vendor/Python/current/Demo/classes/Rat.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/classes/Rev.py
===================================================================
--- vendor/Python/current/Demo/classes/Rev.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/classes/Rev.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,95 @@
+'''
+A class which presents the reverse of a sequence without duplicating it.
+From: "Steven D. Majewski" <sdm7g at elvis.med.virginia.edu>
+
+It works on mutable or inmutable sequences.
+
+>>> chars = list(Rev('Hello World!'))
+>>> print ''.join(chars)
+!dlroW olleH
+
+The .forw is so you can use anonymous sequences in __init__, and still
+keep a reference the forward sequence. )
+If you give it a non-anonymous mutable sequence, the reverse sequence
+will track the updated values. ( but not reassignment! - another
+good reason to use anonymous values in creating the sequence to avoid
+confusion. Maybe it should be change to copy input sequence to break
+the connection completely ? )
+
+>>> nnn = range(3)
+>>> rnn = Rev(nnn)
+>>> for n in rnn: print n
+...
+2
+1
+0
+>>> for n in range(4, 6): nnn.append(n)   # update nnn
+...
+>>> for n in rnn: print n     # prints reversed updated values
+...
+5
+4
+2
+1
+0
+>>> nnn = nnn[1:-1]
+>>> nnn
+[1, 2, 4]
+>>> for n in rnn: print n     # prints reversed values of old nnn
+...
+5
+4
+2
+1
+0
+
+#
+>>> WH = Rev('Hello World!')
+>>> print WH.forw, WH.back
+Hello World! !dlroW olleH
+>>> nnn = Rev(range(1, 10))
+>>> print nnn.forw
+[1, 2, 3, 4, 5, 6, 7, 8, 9]
+>>> print nnn.back
+[9, 8, 7, 6, 5, 4, 3, 2, 1]
+
+>>> rrr = Rev(nnn)
+>>> rrr
+<1, 2, 3, 4, 5, 6, 7, 8, 9>
+
+'''
+
+class Rev:
+    def __init__(self, seq):
+        self.forw = seq
+        self.back = self
+
+    def __len__(self):
+        return len(self.forw)
+
+    def __getitem__(self, j):
+        return self.forw[-(j + 1)]
+
+    def __repr__(self):
+        seq = self.forw
+        if isinstance(seq, list):
+            wrap = '[]'
+            sep = ', '
+        elif isinstance(seq, tuple):
+            wrap = '()'
+            sep = ', '
+        elif isinstance(seq, str):
+            wrap = ''
+            sep = ''
+        else:
+            wrap = '<>'
+            sep = ', '
+        outstrs = [str(item) for item in self.back]
+        return wrap[:1] + sep.join(outstrs) + wrap[-1:]
+
+def _test():
+    import doctest, Rev
+    return doctest.testmod(Rev)
+
+if __name__ == "__main__":
+    _test()


Property changes on: vendor/Python/current/Demo/classes/Rev.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/classes/Vec.py
===================================================================
--- vendor/Python/current/Demo/classes/Vec.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/classes/Vec.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,54 @@
+# A simple vector class
+
+
+def vec(*v):
+    return Vec(*v)
+
+
+class Vec:
+
+    def __init__(self, *v):
+        self.v = list(v)
+
+    def fromlist(self, v):
+        if not isinstance(v, list):
+            raise TypeError
+        self.v = v[:]
+        return self
+
+    def __repr__(self):
+        return 'vec(' + repr(self.v)[1:-1] + ')'
+
+    def __len__(self):
+        return len(self.v)
+
+    def __getitem__(self, i):
+        return self.v[i]
+
+    def __add__(self, other):
+        # Element-wise addition
+        v = map(lambda x, y: x+y, self, other)
+        return Vec().fromlist(v)
+
+    def __sub__(self, other):
+        # Element-wise subtraction
+        v = map(lambda x, y: x-y, self, other)
+        return Vec().fromlist(v)
+
+    def __mul__(self, scalar):
+        # Multiply by scalar
+        v = map(lambda x: x*scalar, self.v)
+        return Vec().fromlist(v)
+
+
+
+def test():
+    a = vec(1, 2, 3)
+    b = vec(3, 2, 1)
+    print a
+    print b
+    print a+b
+    print a-b
+    print a*3.0
+
+test()


Property changes on: vendor/Python/current/Demo/classes/Vec.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/classes/bitvec.py
===================================================================
--- vendor/Python/current/Demo/classes/bitvec.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/classes/bitvec.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,332 @@
+#
+# this is a rather strict implementation of a bit vector class
+# it is accessed the same way as an array of python-ints, except
+# the value must be 0 or 1
+#
+
+import sys; rprt = sys.stderr.write #for debugging
+
+error = 'bitvec.error'
+
+
+def _check_value(value):
+    if type(value) != type(0) or not 0 <= value < 2:
+        raise error, 'bitvec() items must have int value 0 or 1'
+
+
+import math
+
+def _compute_len(param):
+    mant, l = math.frexp(float(param))
+    bitmask = 1L << l
+    if bitmask <= param:
+        raise 'FATAL', '(param, l) = %r' % ((param, l),)
+    while l:
+        bitmask = bitmask >> 1
+        if param & bitmask:
+            break
+        l = l - 1
+    return l
+
+
+def _check_key(len, key):
+    if type(key) != type(0):
+        raise TypeError, 'sequence subscript not int'
+    if key < 0:
+        key = key + len
+    if not 0 <= key < len:
+        raise IndexError, 'list index out of range'
+    return key
+
+def _check_slice(len, i, j):
+    #the type is ok, Python already checked that
+    i, j = max(i, 0), min(len, j)
+    if i > j:
+        i = j
+    return i, j
+
+
+class BitVec:
+
+    def __init__(self, *params):
+        self._data = 0L
+        self._len = 0
+        if not len(params):
+            pass
+        elif len(params) == 1:
+            param, = params
+            if type(param) == type([]):
+                value = 0L
+                bit_mask = 1L
+                for item in param:
+                    # strict check
+                    #_check_value(item)
+                    if item:
+                        value = value | bit_mask
+                    bit_mask = bit_mask << 1
+                self._data = value
+                self._len = len(param)
+            elif type(param) == type(0L):
+                if param < 0:
+                    raise error, 'bitvec() can\'t handle negative longs'
+                self._data = param
+                self._len = _compute_len(param)
+            else:
+                raise error, 'bitvec() requires array or long parameter'
+        elif len(params) == 2:
+            param, length = params
+            if type(param) == type(0L):
+                if param < 0:
+                    raise error, \
+                      'can\'t handle negative longs'
+                self._data = param
+                if type(length) != type(0):
+                    raise error, 'bitvec()\'s 2nd parameter must be int'
+                computed_length = _compute_len(param)
+                if computed_length > length:
+                    print 'warning: bitvec() value is longer than the length indicates, truncating value'
+                    self._data = self._data & \
+                              ((1L << length) - 1)
+                self._len = length
+            else:
+                raise error, 'bitvec() requires array or long parameter'
+        else:
+            raise error, 'bitvec() requires 0 -- 2 parameter(s)'
+
+
+    def append(self, item):
+        #_check_value(item)
+        #self[self._len:self._len] = [item]
+        self[self._len:self._len] = \
+                  BitVec(long(not not item), 1)
+
+
+    def count(self, value):
+        #_check_value(value)
+        if value:
+            data = self._data
+        else:
+            data = (~self)._data
+        count = 0
+        while data:
+            data, count = data >> 1, count + (data & 1 != 0)
+        return count
+
+
+    def index(self, value):
+        #_check_value(value):
+        if value:
+            data = self._data
+        else:
+            data = (~self)._data
+        index = 0
+        if not data:
+            raise ValueError, 'list.index(x): x not in list'
+        while not (data & 1):
+            data, index = data >> 1, index + 1
+        return index
+
+
+    def insert(self, index, item):
+        #_check_value(item)
+        #self[index:index] = [item]
+        self[index:index] = BitVec(long(not not item), 1)
+
+
+    def remove(self, value):
+        del self[self.index(value)]
+
+
+    def reverse(self):
+        #ouch, this one is expensive!
+        #for i in self._len>>1: self[i], self[l-i] = self[l-i], self[i]
+        data, result = self._data, 0L
+        for i in range(self._len):
+            if not data:
+                result = result << (self._len - i)
+                break
+            result, data = (result << 1) | (data & 1), data >> 1
+        self._data = result
+
+
+    def sort(self):
+        c = self.count(1)
+        self._data = ((1L << c) - 1) << (self._len - c)
+
+
+    def copy(self):
+        return BitVec(self._data, self._len)
+
+
+    def seq(self):
+        result = []
+        for i in self:
+            result.append(i)
+        return result
+
+
+    def __repr__(self):
+        ##rprt('<bitvec class instance object>.' + '__repr__()\n')
+        return 'bitvec(%r, %r)' % (self._data, self._len)
+
+    def __cmp__(self, other, *rest):
+        #rprt('%r.__cmp__%r\n' % (self, (other,) + rest))
+        if type(other) != type(self):
+            other = apply(bitvec, (other, ) + rest)
+        #expensive solution... recursive binary, with slicing
+        length = self._len
+        if length == 0 or other._len == 0:
+            return cmp(length, other._len)
+        if length != other._len:
+            min_length = min(length, other._len)
+            return cmp(self[:min_length], other[:min_length]) or \
+                      cmp(self[min_length:], other[min_length:])
+        #the lengths are the same now...
+        if self._data == other._data:
+            return 0
+        if length == 1:
+            return cmp(self[0], other[0])
+        else:
+            length = length >> 1
+            return cmp(self[:length], other[:length]) or \
+                      cmp(self[length:], other[length:])
+
+
+    def __len__(self):
+        #rprt('%r.__len__()\n' % (self,))
+        return self._len
+
+    def __getitem__(self, key):
+        #rprt('%r.__getitem__(%r)\n' % (self, key))
+        key = _check_key(self._len, key)
+        return self._data & (1L << key) != 0
+
+    def __setitem__(self, key, value):
+        #rprt('%r.__setitem__(%r, %r)\n' % (self, key, value))
+        key = _check_key(self._len, key)
+        #_check_value(value)
+        if value:
+            self._data = self._data | (1L << key)
+        else:
+            self._data = self._data & ~(1L << key)
+
+    def __delitem__(self, key):
+        #rprt('%r.__delitem__(%r)\n' % (self, key))
+        key = _check_key(self._len, key)
+        #el cheapo solution...
+        self._data = self[:key]._data | self[key+1:]._data >> key
+        self._len = self._len - 1
+
+    def __getslice__(self, i, j):
+        #rprt('%r.__getslice__(%r, %r)\n' % (self, i, j))
+        i, j = _check_slice(self._len, i, j)
+        if i >= j:
+            return BitVec(0L, 0)
+        if i:
+            ndata = self._data >> i
+        else:
+            ndata = self._data
+        nlength = j - i
+        if j != self._len:
+            #we'll have to invent faster variants here
+            #e.g. mod_2exp
+            ndata = ndata & ((1L << nlength) - 1)
+        return BitVec(ndata, nlength)
+
+    def __setslice__(self, i, j, sequence, *rest):
+        #rprt('%s.__setslice__%r\n' % (self, (i, j, sequence) + rest))
+        i, j = _check_slice(self._len, i, j)
+        if type(sequence) != type(self):
+            sequence = apply(bitvec, (sequence, ) + rest)
+        #sequence is now of our own type
+        ls_part = self[:i]
+        ms_part = self[j:]
+        self._data = ls_part._data | \
+                  ((sequence._data | \
+                  (ms_part._data << sequence._len)) << ls_part._len)
+        self._len = self._len - j + i + sequence._len
+
+    def __delslice__(self, i, j):
+        #rprt('%r.__delslice__(%r, %r)\n' % (self, i, j))
+        i, j = _check_slice(self._len, i, j)
+        if i == 0 and j == self._len:
+            self._data, self._len = 0L, 0
+        elif i < j:
+            self._data = self[:i]._data | (self[j:]._data >> i)
+            self._len = self._len - j + i
+
+    def __add__(self, other):
+        #rprt('%r.__add__(%r)\n' % (self, other))
+        retval = self.copy()
+        retval[self._len:self._len] = other
+        return retval
+
+    def __mul__(self, multiplier):
+        #rprt('%r.__mul__(%r)\n' % (self, multiplier))
+        if type(multiplier) != type(0):
+            raise TypeError, 'sequence subscript not int'
+        if multiplier <= 0:
+            return BitVec(0L, 0)
+        elif multiplier == 1:
+            return self.copy()
+        #handle special cases all 0 or all 1...
+        if self._data == 0L:
+            return BitVec(0L, self._len * multiplier)
+        elif (~self)._data == 0L:
+            return ~BitVec(0L, self._len * multiplier)
+        #otherwise el cheapo again...
+        retval = BitVec(0L, 0)
+        while multiplier:
+            retval, multiplier = retval + self, multiplier - 1
+        return retval
+
+    def __and__(self, otherseq, *rest):
+        #rprt('%r.__and__%r\n' % (self, (otherseq,) + rest))
+        if type(otherseq) != type(self):
+            otherseq = apply(bitvec, (otherseq, ) + rest)
+        #sequence is now of our own type
+        return BitVec(self._data & otherseq._data, \
+                  min(self._len, otherseq._len))
+
+
+    def __xor__(self, otherseq, *rest):
+        #rprt('%r.__xor__%r\n' % (self, (otherseq,) + rest))
+        if type(otherseq) != type(self):
+            otherseq = apply(bitvec, (otherseq, ) + rest)
+        #sequence is now of our own type
+        return BitVec(self._data ^ otherseq._data, \
+                  max(self._len, otherseq._len))
+
+
+    def __or__(self, otherseq, *rest):
+        #rprt('%r.__or__%r\n' % (self, (otherseq,) + rest))
+        if type(otherseq) != type(self):
+            otherseq = apply(bitvec, (otherseq, ) + rest)
+        #sequence is now of our own type
+        return BitVec(self._data | otherseq._data, \
+                  max(self._len, otherseq._len))
+
+
+    def __invert__(self):
+        #rprt('%r.__invert__()\n' % (self,))
+        return BitVec(~self._data & ((1L << self._len) - 1), \
+                  self._len)
+
+    def __coerce__(self, otherseq, *rest):
+        #needed for *some* of the arithmetic operations
+        #rprt('%r.__coerce__%r\n' % (self, (otherseq,) + rest))
+        if type(otherseq) != type(self):
+            otherseq = apply(bitvec, (otherseq, ) + rest)
+        return self, otherseq
+
+    def __int__(self):
+        return int(self._data)
+
+    def __long__(self):
+        return long(self._data)
+
+    def __float__(self):
+        return float(self._data)
+
+
+bitvec = BitVec


Property changes on: vendor/Python/current/Demo/classes/bitvec.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/comparisons/README
===================================================================
--- vendor/Python/current/Demo/comparisons/README	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/comparisons/README	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,60 @@
+Subject: Re: What language would you use?
+From: Tom Christiansen <tchrist at mox.perl.com>
+Date: 6 Nov 1994 15:14:51 GMT
+Newsgroups: comp.lang.python,comp.lang.tcl,comp.lang.scheme,comp.lang.misc,comp.lang.perl
+Message-Id: <39irtb$3t4 at csnews.cs.Colorado.EDU>
+References: <39b7ha$j9v at zeno.nscf.org> <39hhjp$lgn at csnews.cs.Colorado.EDU> <39hvsu$dus at mathserv.mps.ohio-state.edu>
+
+[...]
+If you're really into benchmarks, I'd love it if someone were to code up
+the following problems in tcl, python, and scheme (and whatever else you'd
+like).  Separate versions (one optimized for speed, one for beauty :-) are
+ok.  Post your code so we can time it on our own systems.
+
+0)  Factorial Test  (numerics and function calls)
+
+        (we did this already)
+
+1)  Regular Expressions Test
+
+    Read a file of (extended per egrep) regular expressions (one per line), 
+    and apply those to all files whose names are listed on the command line.
+    Basically, an 'egrep -f' simulator.  Test it with 20 "vt100" patterns
+    against a five /etc/termcap files.  Tests using more elaborate patters
+    would also be interesting.  Your code should not break if given hundreds
+    of regular expressions or binary files to scan.  
+
+2)  Sorting Test
+
+    Sort an input file that consists of lines like this
+
+        var1=23 other=14 ditto=23 fred=2
+
+    such that each output line is sorted WRT to the number.  Order
+    of output lines does not change.  Resolve collisions using the
+    variable name.   e.g.
+
+        fred=2 other=14 ditto=23 var1=23 
+
+    Lines may be up to several kilobytes in length and contain
+    zillions of variables.
+
+3)  System Test
+
+    Given a list of directories, report any bogus symbolic links contained
+    anywhere in those subtrees.  A bogus symbolic link is one that cannot
+    be resolved because it points to a nonexistent or otherwise
+    unresolvable file.  Do *not* use an external find executable.
+    Directories may be very very deep.  Print a warning immediately if the
+    system you're running on doesn't support symbolic links.
+
+
+I'll post perl solutions if people post the others.
+
+
+--tom
+-- 
+Tom Christiansen      Perl Consultant, Gamer, Hiker      tchrist at mox.perl.com
+
+ "But Billy! A *small* allowance prepares you for a lifetime of small
+ salaries and for your Social Security payments."    --Family Circus

Added: vendor/Python/current/Demo/comparisons/patterns
===================================================================
--- vendor/Python/current/Demo/comparisons/patterns	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/comparisons/patterns	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,4 @@
+^def 
+^class 
+^import 
+^from 


Property changes on: vendor/Python/current/Demo/comparisons/patterns
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/comparisons/regextest.py
===================================================================
--- vendor/Python/current/Demo/comparisons/regextest.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/comparisons/regextest.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,47 @@
+#! /usr/bin/env python
+
+# 1)  Regular Expressions Test
+#
+#     Read a file of (extended per egrep) regular expressions (one per line),
+#     and apply those to all files whose names are listed on the command line.
+#     Basically, an 'egrep -f' simulator.  Test it with 20 "vt100" patterns
+#     against a five /etc/termcap files.  Tests using more elaborate patters
+#     would also be interesting.  Your code should not break if given hundreds
+#     of regular expressions or binary files to scan.
+
+# This implementation:
+# - combines all patterns into a single one using ( ... | ... | ... )
+# - reads patterns from stdin, scans files given as command line arguments
+# - produces output in the format <file>:<lineno>:<line>
+# - is only about 2.5 times as slow as egrep (though I couldn't run
+#   Tom's test -- this system, a vanilla SGI, only has /etc/terminfo)
+
+import string
+import sys
+import re
+
+def main():
+    pats = map(chomp, sys.stdin.readlines())
+    bigpat = '(' + '|'.join(pats) + ')'
+    prog = re.compile(bigpat)
+
+    for file in sys.argv[1:]:
+        try:
+            fp = open(file, 'r')
+        except IOError, msg:
+            print "%s: %s" % (file, msg)
+            continue
+        lineno = 0
+        while 1:
+            line = fp.readline()
+            if not line:
+                break
+            lineno = lineno + 1
+            if prog.search(line):
+                print "%s:%s:%s" % (file, lineno, line),
+
+def chomp(s):
+    return s.rstrip('\n')
+
+if __name__ == '__main__':
+    main()


Property changes on: vendor/Python/current/Demo/comparisons/regextest.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/comparisons/sortingtest.py
===================================================================
--- vendor/Python/current/Demo/comparisons/sortingtest.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/comparisons/sortingtest.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,51 @@
+#! /usr/bin/env python
+
+# 2)  Sorting Test
+#
+#     Sort an input file that consists of lines like this
+#
+#         var1=23 other=14 ditto=23 fred=2
+#
+#     such that each output line is sorted WRT to the number.  Order
+#     of output lines does not change.  Resolve collisions using the
+#     variable name.   e.g.
+#
+#         fred=2 other=14 ditto=23 var1=23
+#
+#     Lines may be up to several kilobytes in length and contain
+#     zillions of variables.
+
+# This implementation:
+# - Reads stdin, writes stdout
+# - Uses any amount of whitespace to separate fields
+# - Allows signed numbers
+# - Treats illegally formatted fields as field=0
+# - Outputs the sorted fields with exactly one space between them
+# - Handles blank input lines correctly
+
+import re
+import string
+import sys
+
+def main():
+    prog = re.compile('^(.*)=([-+]?[0-9]+)')
+    def makekey(item, prog=prog):
+        match = prog.match(item)
+        if match:
+            var, num = match.group(1, 2)
+            return string.atoi(num), var
+        else:
+            # Bad input -- pretend it's a var with value 0
+            return 0, item
+    while 1:
+        line = sys.stdin.readline()
+        if not line:
+            break
+        items = line.split()
+        items = map(makekey, items)
+        items.sort()
+        for num, var in items:
+            print "%s=%s" % (var, num),
+        print
+
+main()


Property changes on: vendor/Python/current/Demo/comparisons/sortingtest.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/comparisons/systemtest.py
===================================================================
--- vendor/Python/current/Demo/comparisons/systemtest.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/comparisons/systemtest.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,74 @@
+#! /usr/bin/env python
+
+# 3)  System Test
+#
+#     Given a list of directories, report any bogus symbolic links contained
+#     anywhere in those subtrees.  A bogus symbolic link is one that cannot
+#     be resolved because it points to a nonexistent or otherwise
+#     unresolvable file.  Do *not* use an external find executable.
+#     Directories may be very very deep.  Print a warning immediately if the
+#     system you're running on doesn't support symbolic links.
+
+# This implementation:
+# - takes one optional argument, using the current directory as default
+# - uses chdir to increase performance
+# - sorts the names per directory
+# - prints output lines of the form "path1 -> path2" as it goes
+# - prints error messages about directories it can't list or chdir into
+
+import os
+import sys
+from stat import *
+
+def main():
+    try:
+        # Note: can't test for presence of lstat -- it's always there
+        dummy = os.readlink
+    except AttributeError:
+        print "This system doesn't have symbolic links"
+        sys.exit(0)
+    if sys.argv[1:]:
+        prefix = sys.argv[1]
+    else:
+        prefix = ''
+    if prefix:
+        os.chdir(prefix)
+        if prefix[-1:] != '/': prefix = prefix + '/'
+        reportboguslinks(prefix)
+    else:
+        reportboguslinks('')
+
+def reportboguslinks(prefix):
+    try:
+        names = os.listdir('.')
+    except os.error, msg:
+        print "%s%s: can't list: %s" % (prefix, '.', msg)
+        return
+    names.sort()
+    for name in names:
+        if name == os.curdir or name == os.pardir:
+            continue
+        try:
+            mode = os.lstat(name)[ST_MODE]
+        except os.error:
+            print "%s%s: can't stat: %s" % (prefix, name, msg)
+            continue
+        if S_ISLNK(mode):
+            try:
+                os.stat(name)
+            except os.error:
+                print "%s%s -> %s" % \
+                      (prefix, name, os.readlink(name))
+        elif S_ISDIR(mode):
+            try:
+                os.chdir(name)
+            except os.error, msg:
+                print "%s%s: can't chdir: %s" % \
+                      (prefix, name, msg)
+                continue
+            try:
+                reportboguslinks(prefix + name + '/')
+            finally:
+                os.chdir('..')
+
+main()


Property changes on: vendor/Python/current/Demo/comparisons/systemtest.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/curses/README
===================================================================
--- vendor/Python/current/Demo/curses/README	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/curses/README	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,25 @@
+This is a collection of demos and tests for the curses module. 
+
+ncurses demos
+=============
+
+These demos are converted from the C versions in the ncurses
+distribution, and were contributed by Thomas Gellekum <tg at FreeBSD.org>
+I didn't strive for a `pythonic' style, but bluntly copied the
+originals. I won't attempt to `beautify' the program anytime soon, but
+I wouldn't mind someone else making an effort in that direction, of
+course.
+
+ncurses.py      -- currently only a panels demo
+rain.py         -- raindrops keep falling on my desktop
+tclock.py       -- ASCII clock, by Howard Jones
+xmas.py         -- I'm dreaming of an ASCII christmas
+
+Please submit bugfixes and new contributions to the Python bug tracker.
+
+
+Other demos
+===========
+
+life.py         -- Simple game of Life
+repeat.py       -- Repeatedly execute a shell command (like watch(1))

Added: vendor/Python/current/Demo/curses/life.py
===================================================================
--- vendor/Python/current/Demo/curses/life.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/curses/life.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,216 @@
+#!/usr/bin/env python
+# life.py -- A curses-based version of Conway's Game of Life.
+# Contributed by AMK
+#
+# An empty board will be displayed, and the following commands are available:
+#  E : Erase the board
+#  R : Fill the board randomly
+#  S : Step for a single generation
+#  C : Update continuously until a key is struck
+#  Q : Quit
+#  Cursor keys :  Move the cursor around the board
+#  Space or Enter : Toggle the contents of the cursor's position
+#
+# TODO :
+#   Support the mouse
+#   Use colour if available
+#   Make board updates faster
+#
+
+import random, string, traceback
+import curses
+
+class LifeBoard:
+    """Encapsulates a Life board
+
+    Attributes:
+    X,Y : horizontal and vertical size of the board
+    state : dictionary mapping (x,y) to 0 or 1
+
+    Methods:
+    display(update_board) -- If update_board is true, compute the
+                             next generation.  Then display the state
+                             of the board and refresh the screen.
+    erase() -- clear the entire board
+    makeRandom() -- fill the board randomly
+    set(y,x) -- set the given cell to Live; doesn't refresh the screen
+    toggle(y,x) -- change the given cell from live to dead, or vice
+                   versa, and refresh the screen display
+
+    """
+    def __init__(self, scr, char=ord('*')):
+        """Create a new LifeBoard instance.
+
+        scr -- curses screen object to use for display
+        char -- character used to render live cells (default: '*')
+        """
+        self.state = {}
+        self.scr = scr
+        Y, X = self.scr.getmaxyx()
+        self.X, self.Y = X-2, Y-2-1
+        self.char = char
+        self.scr.clear()
+
+        # Draw a border around the board
+        border_line = '+'+(self.X*'-')+'+'
+        self.scr.addstr(0, 0, border_line)
+        self.scr.addstr(self.Y+1,0, border_line)
+        for y in range(0, self.Y):
+            self.scr.addstr(1+y, 0, '|')
+            self.scr.addstr(1+y, self.X+1, '|')
+        self.scr.refresh()
+
+    def set(self, y, x):
+        """Set a cell to the live state"""
+        if x<0 or self.X<=x or y<0 or self.Y<=y:
+            raise ValueError, "Coordinates out of range %i,%i"% (y,x)
+        self.state[x,y] = 1
+
+    def toggle(self, y, x):
+        """Toggle a cell's state between live and dead"""
+        if x<0 or self.X<=x or y<0 or self.Y<=y:
+            raise ValueError, "Coordinates out of range %i,%i"% (y,x)
+        if self.state.has_key( (x,y) ):
+            del self.state[x,y]
+            self.scr.addch(y+1, x+1, ' ')
+        else:
+            self.state[x,y] = 1
+            self.scr.addch(y+1, x+1, self.char)
+        self.scr.refresh()
+
+    def erase(self):
+        """Clear the entire board and update the board display"""
+        self.state = {}
+        self.display(update_board=False)
+
+    def display(self, update_board=True):
+        """Display the whole board, optionally computing one generation"""
+        M,N = self.X, self.Y
+        if not update_board:
+            for i in range(0, M):
+                for j in range(0, N):
+                    if self.state.has_key( (i,j) ):
+                        self.scr.addch(j+1, i+1, self.char)
+                    else:
+                        self.scr.addch(j+1, i+1, ' ')
+            self.scr.refresh()
+            return
+
+        d = {}
+        self.boring = 1
+        for i in range(0, M):
+            L = range( max(0, i-1), min(M, i+2) )
+            for j in range(0, N):
+                s = 0
+                live = self.state.has_key( (i,j) )
+                for k in range( max(0, j-1), min(N, j+2) ):
+                    for l in L:
+                        if self.state.has_key( (l,k) ):
+                            s += 1
+                s -= live
+                if s == 3:
+                    # Birth
+                    d[i,j] = 1
+                    self.scr.addch(j+1, i+1, self.char)
+                    if not live: self.boring = 0
+                elif s == 2 and live: d[i,j] = 1       # Survival
+                elif live:
+                    # Death
+                    self.scr.addch(j+1, i+1, ' ')
+                    self.boring = 0
+        self.state = d
+        self.scr.refresh()
+
+    def makeRandom(self):
+        "Fill the board with a random pattern"
+        self.state = {}
+        for i in range(0, self.X):
+            for j in range(0, self.Y):
+                if random.random() > 0.5:
+                    self.set(j,i)
+
+
+def erase_menu(stdscr, menu_y):
+    "Clear the space where the menu resides"
+    stdscr.move(menu_y, 0)
+    stdscr.clrtoeol()
+    stdscr.move(menu_y+1, 0)
+    stdscr.clrtoeol()
+
+def display_menu(stdscr, menu_y):
+    "Display the menu of possible keystroke commands"
+    erase_menu(stdscr, menu_y)
+    stdscr.addstr(menu_y, 4,
+                  'Use the cursor keys to move, and space or Enter to toggle a cell.')
+    stdscr.addstr(menu_y+1, 4,
+                  'E)rase the board, R)andom fill, S)tep once or C)ontinuously, Q)uit')
+
+def keyloop(stdscr):
+    # Clear the screen and display the menu of keys
+    stdscr.clear()
+    stdscr_y, stdscr_x = stdscr.getmaxyx()
+    menu_y = (stdscr_y-3)-1
+    display_menu(stdscr, menu_y)
+
+    # Allocate a subwindow for the Life board and create the board object
+    subwin = stdscr.subwin(stdscr_y-3, stdscr_x, 0, 0)
+    board = LifeBoard(subwin, char=ord('*'))
+    board.display(update_board=False)
+
+    # xpos, ypos are the cursor's position
+    xpos, ypos = board.X/2, board.Y/2
+
+    # Main loop:
+    while (1):
+        stdscr.move(1+ypos, 1+xpos)     # Move the cursor
+        c = stdscr.getch()                # Get a keystroke
+        if 0<c<256:
+            c = chr(c)
+            if c in ' \n':
+                board.toggle(ypos, xpos)
+            elif c in 'Cc':
+                erase_menu(stdscr, menu_y)
+                stdscr.addstr(menu_y, 6, ' Hit any key to stop continuously '
+                              'updating the screen.')
+                stdscr.refresh()
+                # Activate nodelay mode; getch() will return -1
+                # if no keystroke is available, instead of waiting.
+                stdscr.nodelay(1)
+                while (1):
+                    c = stdscr.getch()
+                    if c != -1:
+                        break
+                    stdscr.addstr(0,0, '/')
+                    stdscr.refresh()
+                    board.display()
+                    stdscr.addstr(0,0, '+')
+                    stdscr.refresh()
+
+                stdscr.nodelay(0)       # Disable nodelay mode
+                display_menu(stdscr, menu_y)
+
+            elif c in 'Ee':
+                board.erase()
+            elif c in 'Qq':
+                break
+            elif c in 'Rr':
+                board.makeRandom()
+                board.display(update_board=False)
+            elif c in 'Ss':
+                board.display()
+            else: pass                  # Ignore incorrect keys
+        elif c == curses.KEY_UP and ypos>0:            ypos -= 1
+        elif c == curses.KEY_DOWN and ypos<board.Y-1:  ypos += 1
+        elif c == curses.KEY_LEFT and xpos>0:          xpos -= 1
+        elif c == curses.KEY_RIGHT and xpos<board.X-1: xpos += 1
+        else:
+            # Ignore incorrect keys
+            pass
+
+
+def main(stdscr):
+    keyloop(stdscr)                    # Enter the main loop
+
+
+if __name__ == '__main__':
+    curses.wrapper(main)


Property changes on: vendor/Python/current/Demo/curses/life.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/curses/ncurses.py
===================================================================
--- vendor/Python/current/Demo/curses/ncurses.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/curses/ncurses.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,273 @@
+#!/usr/bin/env python
+#
+# $Id: ncurses.py 36559 2004-07-18 05:56:09Z tim_one $
+#
+# (n)curses exerciser in Python, an interactive test for the curses
+# module. Currently, only the panel demos are ported.
+
+import curses
+from curses import panel
+
+def wGetchar(win = None):
+    if win == None: win = stdscr
+    return win.getch()
+
+def Getchar():
+    wGetchar()
+
+#
+# Panels tester
+#
+def wait_a_while():
+    if nap_msec == 1:
+        Getchar()
+    else:
+        curses.napms(nap_msec)
+
+def saywhat(text):
+    stdscr.move(curses.LINES - 1, 0)
+    stdscr.clrtoeol()
+    stdscr.addstr(text)
+
+def mkpanel(color, rows, cols, tly, tlx):
+    win = curses.newwin(rows, cols, tly, tlx)
+    pan = panel.new_panel(win)
+    if curses.has_colors():
+        if color == curses.COLOR_BLUE:
+            fg = curses.COLOR_WHITE
+        else:
+            fg = curses.COLOR_BLACK
+        bg = color
+        curses.init_pair(color, fg, bg)
+        win.bkgdset(ord(' '), curses.color_pair(color))
+    else:
+        win.bkgdset(ord(' '), curses.A_BOLD)
+
+    return pan
+
+def pflush():
+    panel.update_panels()
+    curses.doupdate()
+
+def fill_panel(pan):
+    win = pan.window()
+    num = pan.userptr()[1]
+
+    win.move(1, 1)
+    win.addstr("-pan%c-" % num)
+    win.clrtoeol()
+    win.box()
+
+    maxy, maxx = win.getmaxyx()
+    for y in range(2, maxy - 1):
+        for x in range(1, maxx - 1):
+            win.move(y, x)
+            win.addch(num)
+
+def demo_panels(win):
+    global stdscr, nap_msec, mod
+    stdscr = win
+    nap_msec = 1
+    mod = ["test", "TEST", "(**)", "*()*", "<-->", "LAST"]
+
+    stdscr.refresh()
+
+    for y in range(0, curses.LINES - 1):
+        for x in range(0, curses.COLS):
+            stdscr.addstr("%d" % ((y + x) % 10))
+    for y in range(0, 1):
+        p1 = mkpanel(curses.COLOR_RED,
+                     curses.LINES / 2 - 2,
+                     curses.COLS / 8 + 1,
+                     0,
+                     0)
+        p1.set_userptr("p1")
+
+        p2 = mkpanel(curses.COLOR_GREEN,
+                     curses.LINES / 2 + 1,
+                     curses.COLS / 7,
+                     curses.LINES / 4,
+                     curses.COLS / 10)
+        p2.set_userptr("p2")
+
+        p3 = mkpanel(curses.COLOR_YELLOW,
+                     curses.LINES / 4,
+                     curses.COLS / 10,
+                     curses.LINES / 2,
+                     curses.COLS / 9)
+        p3.set_userptr("p3")
+
+        p4 = mkpanel(curses.COLOR_BLUE,
+                     curses.LINES / 2 - 2,
+                     curses.COLS / 8,
+                     curses.LINES / 2 - 2,
+                     curses.COLS / 3)
+        p4.set_userptr("p4")
+
+        p5 = mkpanel(curses.COLOR_MAGENTA,
+                     curses.LINES / 2 - 2,
+                     curses.COLS / 8,
+                     curses.LINES / 2,
+                     curses.COLS / 2 - 2)
+        p5.set_userptr("p5")
+
+        fill_panel(p1)
+        fill_panel(p2)
+        fill_panel(p3)
+        fill_panel(p4)
+        fill_panel(p5)
+        p4.hide()
+        p5.hide()
+        pflush()
+        saywhat("press any key to continue")
+        wait_a_while()
+
+        saywhat("h3 s1 s2 s4 s5;press any key to continue")
+        p1.move(0, 0)
+        p3.hide()
+        p1.show()
+        p2.show()
+        p4.show()
+        p5.show()
+        pflush()
+        wait_a_while()
+
+        saywhat("s1; press any key to continue")
+        p1.show()
+        pflush()
+        wait_a_while()
+
+        saywhat("s2; press any key to continue")
+        p2.show()
+        pflush()
+        wait_a_while()
+
+        saywhat("m2; press any key to continue")
+        p2.move(curses.LINES / 3 + 1, curses.COLS / 8)
+        pflush()
+        wait_a_while()
+
+        saywhat("s3; press any key to continue")
+        p3.show()
+        pflush()
+        wait_a_while()
+
+        saywhat("m3; press any key to continue")
+        p3.move(curses.LINES / 4 + 1, curses.COLS / 15)
+        pflush()
+        wait_a_while()
+
+        saywhat("b3; press any key to continue")
+        p3.bottom()
+        pflush()
+        wait_a_while()
+
+        saywhat("s4; press any key to continue")
+        p4.show()
+        pflush()
+        wait_a_while()
+
+        saywhat("s5; press any key to continue")
+        p5.show()
+        pflush()
+        wait_a_while()
+
+        saywhat("t3; press any key to continue")
+        p3.top()
+        pflush()
+        wait_a_while()
+
+        saywhat("t1; press any key to continue")
+        p1.show()
+        pflush()
+        wait_a_while()
+
+        saywhat("t2; press any key to continue")
+        p2.show()
+        pflush()
+        wait_a_while()
+
+        saywhat("t3; press any key to continue")
+        p3.show()
+        pflush()
+        wait_a_while()
+
+        saywhat("t4; press any key to continue")
+        p4.show()
+        pflush()
+        wait_a_while()
+
+        for itmp in range(0, 6):
+            w4 = p4.window()
+            w5 = p5.window()
+
+            saywhat("m4; press any key to continue")
+            w4.move(curses.LINES / 8, 1)
+            w4.addstr(mod[itmp])
+            p4.move(curses.LINES / 6, itmp * curses.COLS / 8)
+            w5.move(curses.LINES / 6, 1)
+            w5.addstr(mod[itmp])
+            pflush()
+            wait_a_while()
+
+            saywhat("m5; press any key to continue")
+            w4.move(curses.LINES / 6, 1)
+            w4.addstr(mod[itmp])
+            p5.move(curses.LINES / 3 - 1, itmp * 10 + 6)
+            w5.move(curses.LINES / 8, 1)
+            w5.addstr(mod[itmp])
+            pflush()
+            wait_a_while()
+
+        saywhat("m4; press any key to continue")
+        p4.move(curses.LINES / 6, (itmp + 1) * curses.COLS / 8)
+        pflush()
+        wait_a_while()
+
+        saywhat("t5; press any key to continue")
+        p5.top()
+        pflush()
+        wait_a_while()
+
+        saywhat("t2; press any key to continue")
+        p2.top()
+        pflush()
+        wait_a_while()
+
+        saywhat("t1; press any key to continue")
+        p1.top()
+        pflush()
+        wait_a_while()
+
+        saywhat("d2; press any key to continue")
+        del p2
+        pflush()
+        wait_a_while()
+
+        saywhat("h3; press any key to continue")
+        p3.hide()
+        pflush()
+        wait_a_while()
+
+        saywhat("d1; press any key to continue")
+        del p1
+        pflush()
+        wait_a_while()
+
+        saywhat("d4; press any key to continue")
+        del p4
+        pflush()
+        wait_a_while()
+
+        saywhat("d5; press any key to continue")
+        del p5
+        pflush()
+        wait_a_while()
+        if nap_msec == 1:
+            break
+        nap_msec = 100
+
+#
+# one fine day there'll be the menu at this place
+#
+curses.wrapper(demo_panels)

Added: vendor/Python/current/Demo/curses/rain.py
===================================================================
--- vendor/Python/current/Demo/curses/rain.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/curses/rain.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,94 @@
+#!/usr/bin/env python
+#
+# $Id: rain.py 46625 2006-06-03 23:02:15Z andrew.kuchling $
+#
+# somebody should probably check the randrange()s...
+
+import curses
+from random import randrange
+
+def next_j(j):
+    if j == 0:
+        j = 4
+    else:
+        j -= 1
+
+    if curses.has_colors():
+        z = randrange(0, 3)
+        color = curses.color_pair(z)
+        if z:
+            color = color | curses.A_BOLD
+        stdscr.attrset(color)
+
+    return j
+
+def main(win):
+    # we know that the first argument from curses.wrapper() is stdscr.
+    # Initialize it globally for convenience.
+    global stdscr
+    stdscr = win
+
+    if curses.has_colors():
+        bg = curses.COLOR_BLACK
+        curses.init_pair(1, curses.COLOR_BLUE, bg)
+        curses.init_pair(2, curses.COLOR_CYAN, bg)
+
+    curses.nl()
+    curses.noecho()
+    # XXX curs_set() always returns ERR
+    # curses.curs_set(0)
+    stdscr.timeout(0)
+
+    c = curses.COLS - 4
+    r = curses.LINES - 4
+    xpos = [0] * c
+    ypos = [0] * r
+    for j in range(4, -1, -1):
+        xpos[j] = randrange(0, c) + 2
+        ypos[j] = randrange(0, r) + 2
+
+    j = 0
+    while True:
+        x = randrange(0, c) + 2
+        y = randrange(0, r) + 2
+
+        stdscr.addch(y, x, ord('.'))
+
+        stdscr.addch(ypos[j], xpos[j], ord('o'))
+
+        j = next_j(j)
+        stdscr.addch(ypos[j], xpos[j], ord('O'))
+
+        j = next_j(j)
+        stdscr.addch( ypos[j] - 1, xpos[j],     ord('-'))
+        stdscr.addstr(ypos[j],     xpos[j] - 1, "|.|")
+        stdscr.addch( ypos[j] + 1, xpos[j],     ord('-'))
+
+        j = next_j(j)
+        stdscr.addch( ypos[j] - 2, xpos[j],     ord('-'))
+        stdscr.addstr(ypos[j] - 1, xpos[j] - 1, "/ \\")
+        stdscr.addstr(ypos[j],     xpos[j] - 2, "| O |")
+        stdscr.addstr(ypos[j] + 1, xpos[j] - 1, "\\ /")
+        stdscr.addch( ypos[j] + 2, xpos[j],     ord('-'))
+
+        j = next_j(j)
+        stdscr.addch( ypos[j] - 2, xpos[j],     ord(' '))
+        stdscr.addstr(ypos[j] - 1, xpos[j] - 1, "   ")
+        stdscr.addstr(ypos[j],     xpos[j] - 2, "     ")
+        stdscr.addstr(ypos[j] + 1, xpos[j] - 1, "   ")
+        stdscr.addch( ypos[j] + 2, xpos[j],     ord(' '))
+
+        xpos[j] = x
+        ypos[j] = y
+
+        ch = stdscr.getch()
+        if ch == ord('q') or ch == ord('Q'):
+            return
+        elif ch == ord('s'):
+            stdscr.nodelay(0)
+        elif ch == ord(' '):
+            stdscr.nodelay(1)
+
+        curses.napms(50)
+
+curses.wrapper(main)

Added: vendor/Python/current/Demo/curses/repeat.py
===================================================================
--- vendor/Python/current/Demo/curses/repeat.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/curses/repeat.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,58 @@
+#! /usr/bin/env python
+
+"""repeat <shell-command>
+
+This simple program repeatedly (at 1-second intervals) executes the
+shell command given on the command line and displays the output (or as
+much of it as fits on the screen).  It uses curses to paint each new
+output on top of the old output, so that if nothing changes, the
+screen doesn't change.  This is handy to watch for changes in e.g. a
+directory or process listing.
+
+To end, hit Control-C.
+"""
+
+# Author: Guido van Rossum
+
+# Disclaimer: there's a Linux program named 'watch' that does the same
+# thing.  Honestly, I didn't know of its existence when I wrote this!
+
+# To do: add features until it has the same functionality as watch(1);
+# then compare code size and development time.
+
+import os
+import sys
+import time
+import curses
+
+def main():
+    if not sys.argv[1:]:
+        print __doc__
+        sys.exit(0)
+    cmd = " ".join(sys.argv[1:])
+    p = os.popen(cmd, "r")
+    text = p.read()
+    sts = p.close()
+    if sts:
+        print >>sys.stderr, "Exit code:", sts
+        sys.exit(sts)
+    w = curses.initscr()
+    try:
+        while True:
+            w.erase()
+            try:
+                w.addstr(text)
+            except curses.error:
+                pass
+            w.refresh()
+            time.sleep(1)
+            p = os.popen(cmd, "r")
+            text = p.read()
+            sts = p.close()
+            if sts:
+                print >>sys.stderr, "Exit code:", sts
+                sys.exit(sts)
+    finally:
+        curses.endwin()
+
+main()


Property changes on: vendor/Python/current/Demo/curses/repeat.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/curses/tclock.py
===================================================================
--- vendor/Python/current/Demo/curses/tclock.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/curses/tclock.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,147 @@
+#!/usr/bin/env python
+#
+# $Id: tclock.py 46626 2006-06-03 23:07:21Z andrew.kuchling $
+#
+# From tclock.c, Copyright Howard Jones <ha.jones at ic.ac.uk>, September 1994.
+
+from math import *
+import curses, time
+
+ASPECT = 2.2
+
+def sign(_x):
+    if _x < 0: return -1
+    return 1
+
+def A2XY(angle, radius):
+    return (int(round(ASPECT * radius * sin(angle))),
+            int(round(radius * cos(angle))))
+
+def plot(x, y, col):
+    stdscr.addch(y, x, col)
+
+# draw a diagonal line using Bresenham's algorithm
+def dline(pair, from_x, from_y, x2, y2, ch):
+    if curses.has_colors():
+        stdscr.attrset(curses.color_pair(pair))
+
+    dx = x2 - from_x
+    dy = y2 - from_y
+
+    ax = abs(dx * 2)
+    ay = abs(dy * 2)
+
+    sx = sign(dx)
+    sy = sign(dy)
+
+    x = from_x
+    y = from_y
+
+    if ax > ay:
+        d = ay - ax // 2
+
+        while True:
+            plot(x, y, ch)
+            if x == x2:
+                return
+
+            if d >= 0:
+                y += sy
+                d -= ax
+            x += sx
+            d += ay
+    else:
+        d = ax - ay // 2
+
+        while True:
+            plot(x, y, ch)
+            if y == y2:
+                return
+
+            if d >= 0:
+                x += sx
+                d -= ay
+            y += sy
+            d += ax
+
+def main(win):
+    global stdscr
+    stdscr = win
+
+    lastbeep = -1
+    my_bg = curses.COLOR_BLACK
+
+    stdscr.nodelay(1)
+    stdscr.timeout(0)
+#    curses.curs_set(0)
+    if curses.has_colors():
+        curses.init_pair(1, curses.COLOR_RED, my_bg)
+        curses.init_pair(2, curses.COLOR_MAGENTA, my_bg)
+        curses.init_pair(3, curses.COLOR_GREEN, my_bg)
+
+    cx = (curses.COLS - 1) // 2
+    cy = curses.LINES // 2
+    ch = min( cy-1, int(cx // ASPECT) - 1)
+    mradius = (3 * ch) // 4
+    hradius = ch // 2
+    sradius = 5 * ch // 6
+
+    for i in range(0, 12):
+        sangle = (i + 1) * 2.0 * pi / 12.0
+        sdx, sdy = A2XY(sangle, sradius)
+
+        stdscr.addstr(cy - sdy, cx + sdx, "%d" % (i + 1))
+
+    stdscr.addstr(0, 0,
+                  "ASCII Clock by Howard Jones <ha.jones at ic.ac.uk>, 1994")
+
+    sradius = max(sradius-4, 8)
+
+    while True:
+        curses.napms(1000)
+
+        tim = time.time()
+        t = time.localtime(tim)
+
+        hours = t[3] + t[4] / 60.0
+        if hours > 12.0:
+            hours -= 12.0
+
+        mangle = t[4] * 2 * pi / 60.0
+        mdx, mdy = A2XY(mangle, mradius)
+
+        hangle = hours * 2 * pi / 12.0
+        hdx, hdy = A2XY(hangle, hradius)
+
+        sangle = t[5] * 2 * pi / 60.0
+        sdx, sdy = A2XY(sangle, sradius)
+
+        dline(3, cx, cy, cx + mdx, cy - mdy, ord('#'))
+
+        stdscr.attrset(curses.A_REVERSE)
+        dline(2, cx, cy, cx + hdx, cy - hdy, ord('.'))
+        stdscr.attroff(curses.A_REVERSE)
+
+        if curses.has_colors():
+            stdscr.attrset(curses.color_pair(1))
+
+        plot(cx + sdx, cy - sdy, ord('O'))
+
+        if curses.has_colors():
+            stdscr.attrset(curses.color_pair(0))
+
+        stdscr.addstr(curses.LINES - 2, 0, time.ctime(tim))
+        stdscr.refresh()
+        if (t[5] % 5) == 0 and t[5] != lastbeep:
+            lastbeep = t[5]
+            curses.beep()
+
+        ch = stdscr.getch()
+        if ch == ord('q'):
+            return 0
+
+        plot(cx + sdx, cy - sdy, ord(' '))
+        dline(0, cx, cy, cx + hdx, cy - hdy, ord(' '))
+        dline(0, cx, cy, cx + mdx, cy - mdy, ord(' '))
+
+curses.wrapper(main)

Added: vendor/Python/current/Demo/curses/xmas.py
===================================================================
--- vendor/Python/current/Demo/curses/xmas.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/curses/xmas.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,906 @@
+# asciixmas
+# December 1989             Larry Bartz           Indianapolis, IN
+#
+# $Id: xmas.py 46623 2006-06-03 22:59:23Z andrew.kuchling $
+#
+# I'm dreaming of an ascii character-based monochrome Christmas,
+# Just like the ones I used to know!
+# Via a full duplex communications channel,
+# At 9600 bits per second,
+# Even though it's kinda slow.
+#
+# I'm dreaming of an ascii character-based monochrome Christmas,
+# With ev'ry C program I write!
+# May your screen be merry and bright!
+# And may all your Christmases be amber or green,
+# (for reduced eyestrain and improved visibility)!
+#
+#
+# Notes on the Python version:
+# I used a couple of `try...except curses.error' to get around some functions
+# returning ERR. The errors come from using wrapping functions to fill
+# windows to the last character cell. The C version doesn't have this problem,
+# it simply ignores any return values.
+#
+
+import curses
+import sys
+
+FROMWHO = "Thomas Gellekum <tg at FreeBSD.org>"
+
+def set_color(win, color):
+    if curses.has_colors():
+        n = color + 1
+        curses.init_pair(n, color, my_bg)
+        win.attroff(curses.A_COLOR)
+        win.attron(curses.color_pair(n))
+
+def unset_color(win):
+    if curses.has_colors():
+        win.attrset(curses.color_pair(0))
+
+def look_out(msecs):
+    curses.napms(msecs)
+    if stdscr.getch() != -1:
+        curses.beep()
+        sys.exit(0)
+
+def boxit():
+    for y in range(0, 20):
+        stdscr.addch(y, 7, ord('|'))
+
+    for x in range(8, 80):
+        stdscr.addch(19, x, ord('_'))
+
+    for x in range(0, 80):
+        stdscr.addch(22, x, ord('_'))
+
+    return
+
+def seas():
+    stdscr.addch(4, 1, ord('S'))
+    stdscr.addch(6, 1, ord('E'))
+    stdscr.addch(8, 1, ord('A'))
+    stdscr.addch(10, 1, ord('S'))
+    stdscr.addch(12, 1, ord('O'))
+    stdscr.addch(14, 1, ord('N'))
+    stdscr.addch(16, 1, ord("'"))
+    stdscr.addch(18, 1, ord('S'))
+
+    return
+
+def greet():
+    stdscr.addch(3, 5, ord('G'))
+    stdscr.addch(5, 5, ord('R'))
+    stdscr.addch(7, 5, ord('E'))
+    stdscr.addch(9, 5, ord('E'))
+    stdscr.addch(11, 5, ord('T'))
+    stdscr.addch(13, 5, ord('I'))
+    stdscr.addch(15, 5, ord('N'))
+    stdscr.addch(17, 5, ord('G'))
+    stdscr.addch(19, 5, ord('S'))
+
+    return
+
+def fromwho():
+    stdscr.addstr(21, 13, FROMWHO)
+    return
+
+def tree():
+    set_color(treescrn, curses.COLOR_GREEN)
+    treescrn.addch(1, 11, ord('/'))
+    treescrn.addch(2, 11, ord('/'))
+    treescrn.addch(3, 10, ord('/'))
+    treescrn.addch(4, 9, ord('/'))
+    treescrn.addch(5, 9, ord('/'))
+    treescrn.addch(6, 8, ord('/'))
+    treescrn.addch(7, 7, ord('/'))
+    treescrn.addch(8, 6, ord('/'))
+    treescrn.addch(9, 6, ord('/'))
+    treescrn.addch(10, 5, ord('/'))
+    treescrn.addch(11, 3, ord('/'))
+    treescrn.addch(12, 2, ord('/'))
+
+    treescrn.addch(1, 13, ord('\\'))
+    treescrn.addch(2, 13, ord('\\'))
+    treescrn.addch(3, 14, ord('\\'))
+    treescrn.addch(4, 15, ord('\\'))
+    treescrn.addch(5, 15, ord('\\'))
+    treescrn.addch(6, 16, ord('\\'))
+    treescrn.addch(7, 17, ord('\\'))
+    treescrn.addch(8, 18, ord('\\'))
+    treescrn.addch(9, 18, ord('\\'))
+    treescrn.addch(10, 19, ord('\\'))
+    treescrn.addch(11, 21, ord('\\'))
+    treescrn.addch(12, 22, ord('\\'))
+
+    treescrn.addch(4, 10, ord('_'))
+    treescrn.addch(4, 14, ord('_'))
+    treescrn.addch(8, 7, ord('_'))
+    treescrn.addch(8, 17, ord('_'))
+
+    treescrn.addstr(13, 0, "//////////// \\\\\\\\\\\\\\\\\\\\\\\\")
+
+    treescrn.addstr(14, 11, "| |")
+    treescrn.addstr(15, 11, "|_|")
+
+    unset_color(treescrn)
+    treescrn.refresh()
+    w_del_msg.refresh()
+
+    return
+
+def balls():
+    treescrn.overlay(treescrn2)
+
+    set_color(treescrn2, curses.COLOR_BLUE)
+    treescrn2.addch(3, 9, ord('@'))
+    treescrn2.addch(3, 15, ord('@'))
+    treescrn2.addch(4, 8, ord('@'))
+    treescrn2.addch(4, 16, ord('@'))
+    treescrn2.addch(5, 7, ord('@'))
+    treescrn2.addch(5, 17, ord('@'))
+    treescrn2.addch(7, 6, ord('@'))
+    treescrn2.addch(7, 18, ord('@'))
+    treescrn2.addch(8, 5, ord('@'))
+    treescrn2.addch(8, 19, ord('@'))
+    treescrn2.addch(10, 4, ord('@'))
+    treescrn2.addch(10, 20, ord('@'))
+    treescrn2.addch(11, 2, ord('@'))
+    treescrn2.addch(11, 22, ord('@'))
+    treescrn2.addch(12, 1, ord('@'))
+    treescrn2.addch(12, 23, ord('@'))
+
+    unset_color(treescrn2)
+    treescrn2.refresh()
+    w_del_msg.refresh()
+    return
+
+def star():
+    treescrn2.attrset(curses.A_BOLD | curses.A_BLINK)
+    set_color(treescrn2, curses.COLOR_YELLOW)
+
+    treescrn2.addch(0, 12, ord('*'))
+    treescrn2.standend()
+
+    unset_color(treescrn2)
+    treescrn2.refresh()
+    w_del_msg.refresh()
+    return
+
+def strng1():
+    treescrn2.attrset(curses.A_BOLD | curses.A_BLINK)
+    set_color(treescrn2, curses.COLOR_WHITE)
+
+    treescrn2.addch(3, 13, ord('\''))
+    treescrn2.addch(3, 12, ord(':'))
+    treescrn2.addch(3, 11, ord('.'))
+
+    treescrn2.attroff(curses.A_BOLD | curses.A_BLINK)
+    unset_color(treescrn2)
+
+    treescrn2.refresh()
+    w_del_msg.refresh()
+    return
+
+def strng2():
+    treescrn2.attrset(curses.A_BOLD | curses.A_BLINK)
+    set_color(treescrn2, curses.COLOR_WHITE)
+
+    treescrn2.addch(5, 14, ord('\''))
+    treescrn2.addch(5, 13, ord(':'))
+    treescrn2.addch(5, 12, ord('.'))
+    treescrn2.addch(5, 11, ord(','))
+    treescrn2.addch(6, 10, ord('\''))
+    treescrn2.addch(6, 9, ord(':'))
+
+    treescrn2.attroff(curses.A_BOLD | curses.A_BLINK)
+    unset_color(treescrn2)
+
+    treescrn2.refresh()
+    w_del_msg.refresh()
+    return
+
+def strng3():
+    treescrn2.attrset(curses.A_BOLD | curses.A_BLINK)
+    set_color(treescrn2, curses.COLOR_WHITE)
+
+    treescrn2.addch(7, 16, ord('\''))
+    treescrn2.addch(7, 15, ord(':'))
+    treescrn2.addch(7, 14, ord('.'))
+    treescrn2.addch(7, 13, ord(','))
+    treescrn2.addch(8, 12, ord('\''))
+    treescrn2.addch(8, 11, ord(':'))
+    treescrn2.addch(8, 10, ord('.'))
+    treescrn2.addch(8, 9, ord(','))
+
+    treescrn2.attroff(curses.A_BOLD | curses.A_BLINK)
+    unset_color(treescrn2)
+
+    treescrn2.refresh()
+    w_del_msg.refresh()
+    return
+
+def strng4():
+    treescrn2.attrset(curses.A_BOLD | curses.A_BLINK)
+    set_color(treescrn2, curses.COLOR_WHITE)
+
+    treescrn2.addch(9, 17, ord('\''))
+    treescrn2.addch(9, 16, ord(':'))
+    treescrn2.addch(9, 15, ord('.'))
+    treescrn2.addch(9, 14, ord(','))
+    treescrn2.addch(10, 13, ord('\''))
+    treescrn2.addch(10, 12, ord(':'))
+    treescrn2.addch(10, 11, ord('.'))
+    treescrn2.addch(10, 10, ord(','))
+    treescrn2.addch(11, 9, ord('\''))
+    treescrn2.addch(11, 8, ord(':'))
+    treescrn2.addch(11, 7, ord('.'))
+    treescrn2.addch(11, 6, ord(','))
+    treescrn2.addch(12, 5, ord('\''))
+
+    treescrn2.attroff(curses.A_BOLD | curses.A_BLINK)
+    unset_color(treescrn2)
+
+    treescrn2.refresh()
+    w_del_msg.refresh()
+    return
+
+def strng5():
+    treescrn2.attrset(curses.A_BOLD | curses.A_BLINK)
+    set_color(treescrn2, curses.COLOR_WHITE)
+
+    treescrn2.addch(11, 19, ord('\''))
+    treescrn2.addch(11, 18, ord(':'))
+    treescrn2.addch(11, 17, ord('.'))
+    treescrn2.addch(11, 16, ord(','))
+    treescrn2.addch(12, 15, ord('\''))
+    treescrn2.addch(12, 14, ord(':'))
+    treescrn2.addch(12, 13, ord('.'))
+    treescrn2.addch(12, 12, ord(','))
+
+    treescrn2.attroff(curses.A_BOLD | curses.A_BLINK)
+    unset_color(treescrn2)
+
+    # save a fully lit tree
+    treescrn2.overlay(treescrn)
+
+    treescrn2.refresh()
+    w_del_msg.refresh()
+    return
+
+def blinkit():
+    treescrn8.touchwin()
+
+    for cycle in range(5):
+        if cycle == 0:
+            treescrn3.overlay(treescrn8)
+            treescrn8.refresh()
+            w_del_msg.refresh()
+            break
+        elif cycle == 1:
+            treescrn4.overlay(treescrn8)
+            treescrn8.refresh()
+            w_del_msg.refresh()
+            break
+        elif cycle == 2:
+            treescrn5.overlay(treescrn8)
+            treescrn8.refresh()
+            w_del_msg.refresh()
+            break
+        elif cycle == 3:
+            treescrn6.overlay(treescrn8)
+            treescrn8.refresh()
+            w_del_msg.refresh()
+            break
+        elif cycle == 4:
+            treescrn7.overlay(treescrn8)
+            treescrn8.refresh()
+            w_del_msg.refresh()
+            break
+
+        treescrn8.touchwin()
+
+    # ALL ON
+    treescrn.overlay(treescrn8)
+    treescrn8.refresh()
+    w_del_msg.refresh()
+
+    return
+
+def deer_step(win, y, x):
+    win.mvwin(y, x)
+    win.refresh()
+    w_del_msg.refresh()
+    look_out(5)
+
+def reindeer():
+    y_pos = 0
+
+    for x_pos in range(70, 62, -1):
+        if x_pos < 66: y_pos = 1
+        for looper in range(0, 4):
+            dotdeer0.addch(y_pos, x_pos, ord('.'))
+            dotdeer0.refresh()
+            w_del_msg.refresh()
+            dotdeer0.erase()
+            dotdeer0.refresh()
+            w_del_msg.refresh()
+            look_out(50)
+
+    y_pos = 2
+
+    for x_pos in range(x_pos - 1, 50, -1):
+        for looper in range(0, 4):
+            if x_pos < 56:
+                y_pos = 3
+
+                try:
+                    stardeer0.addch(y_pos, x_pos, ord('*'))
+                except curses.error:
+                    pass
+                stardeer0.refresh()
+                w_del_msg.refresh()
+                stardeer0.erase()
+                stardeer0.refresh()
+                w_del_msg.refresh()
+            else:
+                dotdeer0.addch(y_pos, x_pos, ord('*'))
+                dotdeer0.refresh()
+                w_del_msg.refresh()
+                dotdeer0.erase()
+                dotdeer0.refresh()
+                w_del_msg.refresh()
+
+    x_pos = 58
+
+    for y_pos in range(2, 5):
+        lildeer0.touchwin()
+        lildeer0.refresh()
+        w_del_msg.refresh()
+
+        for looper in range(0, 4):
+            deer_step(lildeer3, y_pos, x_pos)
+            deer_step(lildeer2, y_pos, x_pos)
+            deer_step(lildeer1, y_pos, x_pos)
+            deer_step(lildeer2, y_pos, x_pos)
+            deer_step(lildeer3, y_pos, x_pos)
+
+            lildeer0.touchwin()
+            lildeer0.refresh()
+            w_del_msg.refresh()
+
+            x_pos -= 2
+
+    x_pos = 35
+
+    for y_pos in range(5, 10):
+
+        middeer0.touchwin()
+        middeer0.refresh()
+        w_del_msg.refresh()
+
+        for looper in range(2):
+            deer_step(middeer3, y_pos, x_pos)
+            deer_step(middeer2, y_pos, x_pos)
+            deer_step(middeer1, y_pos, x_pos)
+            deer_step(middeer2, y_pos, x_pos)
+            deer_step(middeer3, y_pos, x_pos)
+
+            middeer0.touchwin()
+            middeer0.refresh()
+            w_del_msg.refresh()
+
+            x_pos -= 3
+
+    look_out(300)
+
+    y_pos = 1
+
+    for x_pos in range(8, 16):
+        deer_step(bigdeer4, y_pos, x_pos)
+        deer_step(bigdeer3, y_pos, x_pos)
+        deer_step(bigdeer2, y_pos, x_pos)
+        deer_step(bigdeer1, y_pos, x_pos)
+        deer_step(bigdeer2, y_pos, x_pos)
+        deer_step(bigdeer3, y_pos, x_pos)
+        deer_step(bigdeer4, y_pos, x_pos)
+        deer_step(bigdeer0, y_pos, x_pos)
+
+    x_pos -= 1
+
+    for looper in range(0, 6):
+        deer_step(lookdeer4, y_pos, x_pos)
+        deer_step(lookdeer3, y_pos, x_pos)
+        deer_step(lookdeer2, y_pos, x_pos)
+        deer_step(lookdeer1, y_pos, x_pos)
+        deer_step(lookdeer2, y_pos, x_pos)
+        deer_step(lookdeer3, y_pos, x_pos)
+        deer_step(lookdeer4, y_pos, x_pos)
+
+    deer_step(lookdeer0, y_pos, x_pos)
+
+    for y_pos in range(y_pos, 10):
+        for looper in range(0, 2):
+            deer_step(bigdeer4, y_pos, x_pos)
+            deer_step(bigdeer3, y_pos, x_pos)
+            deer_step(bigdeer2, y_pos, x_pos)
+            deer_step(bigdeer1, y_pos, x_pos)
+            deer_step(bigdeer2, y_pos, x_pos)
+            deer_step(bigdeer3, y_pos, x_pos)
+            deer_step(bigdeer4, y_pos, x_pos)
+        deer_step(bigdeer0, y_pos, x_pos)
+
+    y_pos -= 1
+
+    deer_step(lookdeer3, y_pos, x_pos)
+    return
+
+def main(win):
+    global stdscr
+    stdscr = win
+
+    global my_bg, y_pos, x_pos
+    global treescrn, treescrn2, treescrn3, treescrn4
+    global treescrn5, treescrn6, treescrn7, treescrn8
+    global dotdeer0, stardeer0
+    global lildeer0, lildeer1, lildeer2, lildeer3
+    global middeer0, middeer1, middeer2, middeer3
+    global bigdeer0, bigdeer1, bigdeer2, bigdeer3, bigdeer4
+    global lookdeer0, lookdeer1, lookdeer2, lookdeer3, lookdeer4
+    global w_holiday, w_del_msg
+
+    my_bg = curses.COLOR_BLACK
+    # curses.curs_set(0)
+
+    treescrn = curses.newwin(16, 27, 3, 53)
+    treescrn2 = curses.newwin(16, 27, 3, 53)
+    treescrn3 = curses.newwin(16, 27, 3, 53)
+    treescrn4 = curses.newwin(16, 27, 3, 53)
+    treescrn5 = curses.newwin(16, 27, 3, 53)
+    treescrn6 = curses.newwin(16, 27, 3, 53)
+    treescrn7 = curses.newwin(16, 27, 3, 53)
+    treescrn8 = curses.newwin(16, 27, 3, 53)
+
+    dotdeer0 = curses.newwin(3, 71, 0, 8)
+
+    stardeer0 = curses.newwin(4, 56, 0, 8)
+
+    lildeer0 = curses.newwin(7, 53, 0, 8)
+    lildeer1 = curses.newwin(2, 4, 0, 0)
+    lildeer2 = curses.newwin(2, 4, 0, 0)
+    lildeer3 = curses.newwin(2, 4, 0, 0)
+
+    middeer0 = curses.newwin(15, 42, 0, 8)
+    middeer1 = curses.newwin(3, 7, 0, 0)
+    middeer2 = curses.newwin(3, 7, 0, 0)
+    middeer3 = curses.newwin(3, 7, 0, 0)
+
+    bigdeer0 = curses.newwin(10, 23, 0, 0)
+    bigdeer1 = curses.newwin(10, 23, 0, 0)
+    bigdeer2 = curses.newwin(10, 23, 0, 0)
+    bigdeer3 = curses.newwin(10, 23, 0, 0)
+    bigdeer4 = curses.newwin(10, 23, 0, 0)
+
+    lookdeer0 = curses.newwin(10, 25, 0, 0)
+    lookdeer1 = curses.newwin(10, 25, 0, 0)
+    lookdeer2 = curses.newwin(10, 25, 0, 0)
+    lookdeer3 = curses.newwin(10, 25, 0, 0)
+    lookdeer4 = curses.newwin(10, 25, 0, 0)
+
+    w_holiday = curses.newwin(1, 27, 3, 27)
+
+    w_del_msg = curses.newwin(1, 20, 23, 60)
+
+    try:
+        w_del_msg.addstr(0, 0, "Hit any key to quit")
+    except curses.error:
+        pass
+
+    try:
+        w_holiday.addstr(0, 0, "H A P P Y  H O L I D A Y S")
+    except curses.error:
+        pass
+
+    # set up the windows for our various reindeer
+    lildeer1.addch(0, 0, ord('V'))
+    lildeer1.addch(1, 0, ord('@'))
+    lildeer1.addch(1, 1, ord('<'))
+    lildeer1.addch(1, 2, ord('>'))
+    try:
+        lildeer1.addch(1, 3, ord('~'))
+    except curses.error:
+        pass
+
+    lildeer2.addch(0, 0, ord('V'))
+    lildeer2.addch(1, 0, ord('@'))
+    lildeer2.addch(1, 1, ord('|'))
+    lildeer2.addch(1, 2, ord('|'))
+    try:
+        lildeer2.addch(1, 3, ord('~'))
+    except curses.error:
+        pass
+
+    lildeer3.addch(0, 0, ord('V'))
+    lildeer3.addch(1, 0, ord('@'))
+    lildeer3.addch(1, 1, ord('>'))
+    lildeer3.addch(1, 2, ord('<'))
+    try:
+        lildeer2.addch(1, 3, ord('~'))  # XXX
+    except curses.error:
+        pass
+
+    middeer1.addch(0, 2, ord('y'))
+    middeer1.addch(0, 3, ord('y'))
+    middeer1.addch(1, 2, ord('0'))
+    middeer1.addch(1, 3, ord('('))
+    middeer1.addch(1, 4, ord('='))
+    middeer1.addch(1, 5, ord(')'))
+    middeer1.addch(1, 6, ord('~'))
+    middeer1.addch(2, 3, ord('\\'))
+    middeer1.addch(2, 5, ord('/'))
+
+    middeer2.addch(0, 2, ord('y'))
+    middeer2.addch(0, 3, ord('y'))
+    middeer2.addch(1, 2, ord('0'))
+    middeer2.addch(1, 3, ord('('))
+    middeer2.addch(1, 4, ord('='))
+    middeer2.addch(1, 5, ord(')'))
+    middeer2.addch(1, 6, ord('~'))
+    middeer2.addch(2, 3, ord('|'))
+    middeer2.addch(2, 5, ord('|'))
+
+    middeer3.addch(0, 2, ord('y'))
+    middeer3.addch(0, 3, ord('y'))
+    middeer3.addch(1, 2, ord('0'))
+    middeer3.addch(1, 3, ord('('))
+    middeer3.addch(1, 4, ord('='))
+    middeer3.addch(1, 5, ord(')'))
+    middeer3.addch(1, 6, ord('~'))
+    middeer3.addch(2, 3, ord('/'))
+    middeer3.addch(2, 5, ord('\\'))
+
+    bigdeer1.addch(0, 17, ord('\\'))
+    bigdeer1.addch(0, 18, ord('/'))
+    bigdeer1.addch(0, 19, ord('\\'))
+    bigdeer1.addch(0, 20, ord('/'))
+    bigdeer1.addch(1, 18, ord('\\'))
+    bigdeer1.addch(1, 20, ord('/'))
+    bigdeer1.addch(2, 19, ord('|'))
+    bigdeer1.addch(2, 20, ord('_'))
+    bigdeer1.addch(3, 18, ord('/'))
+    bigdeer1.addch(3, 19, ord('^'))
+    bigdeer1.addch(3, 20, ord('0'))
+    bigdeer1.addch(3, 21, ord('\\'))
+    bigdeer1.addch(4, 17, ord('/'))
+    bigdeer1.addch(4, 18, ord('/'))
+    bigdeer1.addch(4, 19, ord('\\'))
+    bigdeer1.addch(4, 22, ord('\\'))
+    bigdeer1.addstr(5, 7, "^~~~~~~~~//  ~~U")
+    bigdeer1.addstr(6, 7, "( \\_____( /")       # ))
+    bigdeer1.addstr(7, 8, "( )    /")
+    bigdeer1.addstr(8, 9, "\\\\   /")
+    bigdeer1.addstr(9, 11, "\\>/>")
+
+    bigdeer2.addch(0, 17, ord('\\'))
+    bigdeer2.addch(0, 18, ord('/'))
+    bigdeer2.addch(0, 19, ord('\\'))
+    bigdeer2.addch(0, 20, ord('/'))
+    bigdeer2.addch(1, 18, ord('\\'))
+    bigdeer2.addch(1, 20, ord('/'))
+    bigdeer2.addch(2, 19, ord('|'))
+    bigdeer2.addch(2, 20, ord('_'))
+    bigdeer2.addch(3, 18, ord('/'))
+    bigdeer2.addch(3, 19, ord('^'))
+    bigdeer2.addch(3, 20, ord('0'))
+    bigdeer2.addch(3, 21, ord('\\'))
+    bigdeer2.addch(4, 17, ord('/'))
+    bigdeer2.addch(4, 18, ord('/'))
+    bigdeer2.addch(4, 19, ord('\\'))
+    bigdeer2.addch(4, 22, ord('\\'))
+    bigdeer2.addstr(5, 7, "^~~~~~~~~//  ~~U")
+    bigdeer2.addstr(6, 7, "(( )____( /")        # ))
+    bigdeer2.addstr(7, 7, "( /    |")
+    bigdeer2.addstr(8, 8, "\\/    |")
+    bigdeer2.addstr(9, 9, "|>   |>")
+
+    bigdeer3.addch(0, 17, ord('\\'))
+    bigdeer3.addch(0, 18, ord('/'))
+    bigdeer3.addch(0, 19, ord('\\'))
+    bigdeer3.addch(0, 20, ord('/'))
+    bigdeer3.addch(1, 18, ord('\\'))
+    bigdeer3.addch(1, 20, ord('/'))
+    bigdeer3.addch(2, 19, ord('|'))
+    bigdeer3.addch(2, 20, ord('_'))
+    bigdeer3.addch(3, 18, ord('/'))
+    bigdeer3.addch(3, 19, ord('^'))
+    bigdeer3.addch(3, 20, ord('0'))
+    bigdeer3.addch(3, 21, ord('\\'))
+    bigdeer3.addch(4, 17, ord('/'))
+    bigdeer3.addch(4, 18, ord('/'))
+    bigdeer3.addch(4, 19, ord('\\'))
+    bigdeer3.addch(4, 22, ord('\\'))
+    bigdeer3.addstr(5, 7, "^~~~~~~~~//  ~~U")
+    bigdeer3.addstr(6, 6, "( ()_____( /")       # ))
+    bigdeer3.addstr(7, 6, "/ /       /")
+    bigdeer3.addstr(8, 5, "|/          \\")
+    bigdeer3.addstr(9, 5, "/>           \\>")
+
+    bigdeer4.addch(0, 17, ord('\\'))
+    bigdeer4.addch(0, 18, ord('/'))
+    bigdeer4.addch(0, 19, ord('\\'))
+    bigdeer4.addch(0, 20, ord('/'))
+    bigdeer4.addch(1, 18, ord('\\'))
+    bigdeer4.addch(1, 20, ord('/'))
+    bigdeer4.addch(2, 19, ord('|'))
+    bigdeer4.addch(2, 20, ord('_'))
+    bigdeer4.addch(3, 18, ord('/'))
+    bigdeer4.addch(3, 19, ord('^'))
+    bigdeer4.addch(3, 20, ord('0'))
+    bigdeer4.addch(3, 21, ord('\\'))
+    bigdeer4.addch(4, 17, ord('/'))
+    bigdeer4.addch(4, 18, ord('/'))
+    bigdeer4.addch(4, 19, ord('\\'))
+    bigdeer4.addch(4, 22, ord('\\'))
+    bigdeer4.addstr(5, 7, "^~~~~~~~~//  ~~U")
+    bigdeer4.addstr(6, 6, "( )______( /")       # )
+    bigdeer4.addstr(7, 5, "(/          \\")     # )
+    bigdeer4.addstr(8, 0, "v___=             ----^")
+
+    lookdeer1.addstr(0, 16, "\\/     \\/")
+    lookdeer1.addstr(1, 17, "\\Y/ \\Y/")
+    lookdeer1.addstr(2, 19, "\\=/")
+    lookdeer1.addstr(3, 17, "^\\o o/^")
+    lookdeer1.addstr(4, 17, "//( )")
+    lookdeer1.addstr(5, 7, "^~~~~~~~~// \\O/")
+    lookdeer1.addstr(6, 7, "( \\_____( /")      # ))
+    lookdeer1.addstr(7, 8, "( )    /")
+    lookdeer1.addstr(8, 9, "\\\\   /")
+    lookdeer1.addstr(9, 11, "\\>/>")
+
+    lookdeer2.addstr(0, 16, "\\/     \\/")
+    lookdeer2.addstr(1, 17, "\\Y/ \\Y/")
+    lookdeer2.addstr(2, 19, "\\=/")
+    lookdeer2.addstr(3, 17, "^\\o o/^")
+    lookdeer2.addstr(4, 17, "//( )")
+    lookdeer2.addstr(5, 7, "^~~~~~~~~// \\O/")
+    lookdeer2.addstr(6, 7, "(( )____( /")       # ))
+    lookdeer2.addstr(7, 7, "( /    |")
+    lookdeer2.addstr(8, 8, "\\/    |")
+    lookdeer2.addstr(9, 9, "|>   |>")
+
+    lookdeer3.addstr(0, 16, "\\/     \\/")
+    lookdeer3.addstr(1, 17, "\\Y/ \\Y/")
+    lookdeer3.addstr(2, 19, "\\=/")
+    lookdeer3.addstr(3, 17, "^\\o o/^")
+    lookdeer3.addstr(4, 17, "//( )")
+    lookdeer3.addstr(5, 7, "^~~~~~~~~// \\O/")
+    lookdeer3.addstr(6, 6, "( ()_____( /")      # ))
+    lookdeer3.addstr(7, 6, "/ /       /")
+    lookdeer3.addstr(8, 5, "|/          \\")
+    lookdeer3.addstr(9, 5, "/>           \\>")
+
+    lookdeer4.addstr(0, 16, "\\/     \\/")
+    lookdeer4.addstr(1, 17, "\\Y/ \\Y/")
+    lookdeer4.addstr(2, 19, "\\=/")
+    lookdeer4.addstr(3, 17, "^\\o o/^")
+    lookdeer4.addstr(4, 17, "//( )")
+    lookdeer4.addstr(5, 7, "^~~~~~~~~// \\O/")
+    lookdeer4.addstr(6, 6, "( )______( /")      # )
+    lookdeer4.addstr(7, 5, "(/          \\")    # )
+    lookdeer4.addstr(8, 0, "v___=             ----^")
+
+    ###############################################
+    curses.cbreak()
+    stdscr.nodelay(1)
+
+    while 1:
+        stdscr.clear()
+        treescrn.erase()
+        w_del_msg.touchwin()
+        treescrn.touchwin()
+        treescrn2.erase()
+        treescrn2.touchwin()
+        treescrn8.erase()
+        treescrn8.touchwin()
+        stdscr.refresh()
+        look_out(150)
+        boxit()
+        stdscr.refresh()
+        look_out(150)
+        seas()
+        stdscr.refresh()
+        greet()
+        stdscr.refresh()
+        look_out(150)
+        fromwho()
+        stdscr.refresh()
+        look_out(150)
+        tree()
+        look_out(150)
+        balls()
+        look_out(150)
+        star()
+        look_out(150)
+        strng1()
+        strng2()
+        strng3()
+        strng4()
+        strng5()
+
+        # set up the windows for our blinking trees
+        #
+        # treescrn3
+        treescrn.overlay(treescrn3)
+
+        # balls
+        treescrn3.addch(4, 18, ord(' '))
+        treescrn3.addch(7, 6, ord(' '))
+        treescrn3.addch(8, 19, ord(' '))
+        treescrn3.addch(11, 22, ord(' '))
+
+        # star
+        treescrn3.addch(0, 12, ord('*'))
+
+        # strng1
+        treescrn3.addch(3, 11, ord(' '))
+
+        # strng2
+        treescrn3.addch(5, 13, ord(' '))
+        treescrn3.addch(6, 10, ord(' '))
+
+        # strng3
+        treescrn3.addch(7, 16, ord(' '))
+        treescrn3.addch(7, 14, ord(' '))
+
+        # strng4
+        treescrn3.addch(10, 13, ord(' '))
+        treescrn3.addch(10, 10, ord(' '))
+        treescrn3.addch(11, 8, ord(' '))
+
+        # strng5
+        treescrn3.addch(11, 18, ord(' '))
+        treescrn3.addch(12, 13, ord(' '))
+
+        # treescrn4
+        treescrn.overlay(treescrn4)
+
+        # balls
+        treescrn4.addch(3, 9, ord(' '))
+        treescrn4.addch(4, 16, ord(' '))
+        treescrn4.addch(7, 6, ord(' '))
+        treescrn4.addch(8, 19, ord(' '))
+        treescrn4.addch(11, 2, ord(' '))
+        treescrn4.addch(12, 23, ord(' '))
+
+        # star
+        treescrn4.standout()
+        treescrn4.addch(0, 12, ord('*'))
+        treescrn4.standend()
+
+        # strng1
+        treescrn4.addch(3, 13, ord(' '))
+
+        # strng2
+
+        # strng3
+        treescrn4.addch(7, 15, ord(' '))
+        treescrn4.addch(8, 11, ord(' '))
+
+        # strng4
+        treescrn4.addch(9, 16, ord(' '))
+        treescrn4.addch(10, 12, ord(' '))
+        treescrn4.addch(11, 8, ord(' '))
+
+        # strng5
+        treescrn4.addch(11, 18, ord(' '))
+        treescrn4.addch(12, 14, ord(' '))
+
+        # treescrn5
+        treescrn.overlay(treescrn5)
+
+        # balls
+        treescrn5.addch(3, 15, ord(' '))
+        treescrn5.addch(10, 20, ord(' '))
+        treescrn5.addch(12, 1, ord(' '))
+
+        # star
+        treescrn5.addch(0, 12, ord(' '))
+
+        # strng1
+        treescrn5.addch(3, 11, ord(' '))
+
+        # strng2
+        treescrn5.addch(5, 12, ord(' '))
+
+        # strng3
+        treescrn5.addch(7, 14, ord(' '))
+        treescrn5.addch(8, 10, ord(' '))
+
+        # strng4
+        treescrn5.addch(9, 15, ord(' '))
+        treescrn5.addch(10, 11, ord(' '))
+        treescrn5.addch(11, 7, ord(' '))
+
+        # strng5
+        treescrn5.addch(11, 17, ord(' '))
+        treescrn5.addch(12, 13, ord(' '))
+
+        # treescrn6
+        treescrn.overlay(treescrn6)
+
+        # balls
+        treescrn6.addch(6, 7, ord(' '))
+        treescrn6.addch(7, 18, ord(' '))
+        treescrn6.addch(10, 4, ord(' '))
+        treescrn6.addch(11, 23, ord(' '))
+
+        # star
+        treescrn6.standout()
+        treescrn6.addch(0, 12, ord('*'))
+        treescrn6.standend()
+
+        # strng1
+
+        # strng2
+        treescrn6.addch(5, 11, ord(' '))
+
+        # strng3
+        treescrn6.addch(7, 13, ord(' '))
+        treescrn6.addch(8, 9, ord(' '))
+
+        # strng4
+        treescrn6.addch(9, 14, ord(' '))
+        treescrn6.addch(10, 10, ord(' '))
+        treescrn6.addch(11, 6, ord(' '))
+
+        # strng5
+        treescrn6.addch(11, 16, ord(' '))
+        treescrn6.addch(12, 12, ord(' '))
+
+        #  treescrn7
+
+        treescrn.overlay(treescrn7)
+
+        # balls
+        treescrn7.addch(3, 15, ord(' '))
+        treescrn7.addch(6, 7, ord(' '))
+        treescrn7.addch(7, 18, ord(' '))
+        treescrn7.addch(10, 4, ord(' '))
+        treescrn7.addch(11, 22, ord(' '))
+
+        # star
+        treescrn7.addch(0, 12, ord('*'))
+
+        # strng1
+        treescrn7.addch(3, 12, ord(' '))
+
+        # strng2
+        treescrn7.addch(5, 13, ord(' '))
+        treescrn7.addch(6, 9, ord(' '))
+
+        # strng3
+        treescrn7.addch(7, 15, ord(' '))
+        treescrn7.addch(8, 11, ord(' '))
+
+        # strng4
+        treescrn7.addch(9, 16, ord(' '))
+        treescrn7.addch(10, 12, ord(' '))
+        treescrn7.addch(11, 8, ord(' '))
+
+        # strng5
+        treescrn7.addch(11, 18, ord(' '))
+        treescrn7.addch(12, 14, ord(' '))
+
+        look_out(150)
+        reindeer()
+
+        w_holiday.touchwin()
+        w_holiday.refresh()
+        w_del_msg.refresh()
+
+        look_out(500)
+        for i in range(0, 20):
+            blinkit()
+
+curses.wrapper(main)

Added: vendor/Python/current/Demo/embed/README
===================================================================
--- vendor/Python/current/Demo/embed/README	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/embed/README	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,19 @@
+This directory show how to embed the Python interpreter in your own
+application.  The file demo.c shows you all that is needed in your C
+code.
+
+To build it, you may have to edit the Makefile:
+
+1) set blddir to the directory where you built Python, if it isn't in
+the source directory (../..)
+
+2) change the variables that together define the list of libraries
+(MODLIBS, LIBS, SYSLIBS) to link with, to match their definitions in
+$(blddir)/Modules/Makefile
+
+An additional test program, loop.c, is used to experiment with memory
+leakage caused by repeated initialization and finalization of the
+interpreter.  It can be build by saying "make loop" and tested with
+"make looptest".  Command line usage is "./loop <python-command>",
+e.g. "./loop 'print 2+2'" should spit out an endless number of lines
+containing the number 4.

Added: vendor/Python/current/Demo/embed/demo.c
===================================================================
--- vendor/Python/current/Demo/embed/demo.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/embed/demo.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,65 @@
+/* Example of embedding Python in another program */
+
+#include "Python.h"
+
+void initxyzzy(void); /* Forward */
+
+main(int argc, char **argv)
+{
+	/* Pass argv[0] to the Python interpreter */
+	Py_SetProgramName(argv[0]);
+
+	/* Initialize the Python interpreter.  Required. */
+	Py_Initialize();
+
+	/* Add a static module */
+	initxyzzy();
+
+	/* Define sys.argv.  It is up to the application if you
+	   want this; you can also let it undefined (since the Python 
+	   code is generally not a main program it has no business
+	   touching sys.argv...) */
+	PySys_SetArgv(argc, argv);
+
+	/* Do some application specific code */
+	printf("Hello, brave new world\n\n");
+
+	/* Execute some Python statements (in module __main__) */
+	PyRun_SimpleString("import sys\n");
+	PyRun_SimpleString("print sys.builtin_module_names\n");
+	PyRun_SimpleString("print sys.modules.keys()\n");
+	PyRun_SimpleString("print sys.executable\n");
+	PyRun_SimpleString("print sys.argv\n");
+
+	/* Note that you can call any public function of the Python
+	   interpreter here, e.g. call_object(). */
+
+	/* Some more application specific code */
+	printf("\nGoodbye, cruel world\n");
+
+	/* Exit, cleaning up the interpreter */
+	Py_Exit(0);
+	/*NOTREACHED*/
+}
+
+/* A static module */
+
+/* 'self' is not used */
+static PyObject *
+xyzzy_foo(PyObject *self, PyObject* args)
+{
+	return PyInt_FromLong(42L);
+}
+
+static PyMethodDef xyzzy_methods[] = {
+	{"foo",		xyzzy_foo,	METH_NOARGS,
+	 "Return the meaning of everything."},
+	{NULL,		NULL}		/* sentinel */
+};
+
+void
+initxyzzy(void)
+{
+	PyImport_AddModule("xyzzy");
+	Py_InitModule("xyzzy", xyzzy_methods);
+}

Added: vendor/Python/current/Demo/embed/importexc.c
===================================================================
--- vendor/Python/current/Demo/embed/importexc.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/embed/importexc.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,17 @@
+#include <Python.h>
+
+char* cmd = "import exceptions";
+
+int main()
+{
+	Py_Initialize();
+	PyEval_InitThreads();
+	PyRun_SimpleString(cmd);
+	Py_EndInterpreter(PyThreadState_Get());
+
+	Py_NewInterpreter();
+	PyRun_SimpleString(cmd);
+	Py_Finalize();
+
+	return 0;
+}

Added: vendor/Python/current/Demo/embed/loop.c
===================================================================
--- vendor/Python/current/Demo/embed/loop.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/embed/loop.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,33 @@
+/* Simple program that repeatedly calls Py_Initialize(), does something, and
+   then calls Py_Finalize().  This should help finding leaks related to
+   initialization. */
+
+#include "Python.h"
+
+main(int argc, char **argv)
+{
+	int count = -1;
+	char *command;
+
+	if (argc < 2 || argc > 3) {
+		fprintf(stderr, "usage: loop <python-command> [count]\n");
+		exit(2);
+	}
+	command = argv[1];
+
+	if (argc == 3) {
+		count = atoi(argv[2]);
+	}
+
+	Py_SetProgramName(argv[0]);
+
+	/* uncomment this if you don't want to load site.py */
+	/* Py_NoSiteFlag = 1; */
+
+	while (count == -1 || --count >= 0 ) {
+		Py_Initialize();
+		PyRun_SimpleString(command);
+		Py_Finalize();
+	}
+	return 0;
+}

Added: vendor/Python/current/Demo/imputil/importers.py
===================================================================
--- vendor/Python/current/Demo/imputil/importers.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/imputil/importers.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,248 @@
+#
+# importers.py
+#
+# Demonstration subclasses of imputil.Importer
+#
+
+# There should be consideration for the imports below if it is desirable
+# to have "all" modules be imported through the imputil system.
+
+# these are C extensions
+import sys
+import imp
+import struct
+import marshal
+
+# these are .py modules
+import imputil
+import os
+
+######################################################################
+
+_TupleType = type(())
+_StringType = type('')
+
+######################################################################
+
+# byte-compiled file suffic character
+_suffix_char = __debug__ and 'c' or 'o'
+
+# byte-compiled file suffix
+_suffix = '.py' + _suffix_char
+
+# the C_EXTENSION suffixes
+_c_suffixes = filter(lambda x: x[2] == imp.C_EXTENSION, imp.get_suffixes())
+
+def _timestamp(pathname):
+    "Return the file modification time as a Long."
+    try:
+        s = os.stat(pathname)
+    except OSError:
+        return None
+    return long(s[8])
+
+def _fs_import(dir, modname, fqname):
+    "Fetch a module from the filesystem."
+
+    pathname = os.path.join(dir, modname)
+    if os.path.isdir(pathname):
+        values = { '__pkgdir__' : pathname, '__path__' : [ pathname ] }
+        ispkg = 1
+        pathname = os.path.join(pathname, '__init__')
+    else:
+        values = { }
+        ispkg = 0
+
+        # look for dynload modules
+        for desc in _c_suffixes:
+            file = pathname + desc[0]
+            try:
+                fp = open(file, desc[1])
+            except IOError:
+                pass
+            else:
+                module = imp.load_module(fqname, fp, file, desc)
+                values['__file__'] = file
+                return 0, module, values
+
+    t_py = _timestamp(pathname + '.py')
+    t_pyc = _timestamp(pathname + _suffix)
+    if t_py is None and t_pyc is None:
+        return None
+    code = None
+    if t_py is None or (t_pyc is not None and t_pyc >= t_py):
+        file = pathname + _suffix
+        f = open(file, 'rb')
+        if f.read(4) == imp.get_magic():
+            t = struct.unpack('<I', f.read(4))[0]
+            if t == t_py:
+                code = marshal.load(f)
+        f.close()
+    if code is None:
+        file = pathname + '.py'
+        code = _compile(file, t_py)
+
+    values['__file__'] = file
+    return ispkg, code, values
+
+######################################################################
+#
+# Simple function-based importer
+#
+class FuncImporter(imputil.Importer):
+    "Importer subclass to delegate to a function rather than method overrides."
+    def __init__(self, func):
+        self.func = func
+    def get_code(self, parent, modname, fqname):
+        return self.func(parent, modname, fqname)
+
+def install_with(func):
+    FuncImporter(func).install()
+
+
+######################################################################
+#
+# Base class for archive-based importing
+#
+class PackageArchiveImporter(imputil.Importer):
+    """Importer subclass to import from (file) archives.
+
+    This Importer handles imports of the style <archive>.<subfile>, where
+    <archive> can be located using a subclass-specific mechanism and the
+    <subfile> is found in the archive using a subclass-specific mechanism.
+
+    This class defines two hooks for subclasses: one to locate an archive
+    (and possibly return some context for future subfile lookups), and one
+    to locate subfiles.
+    """
+
+    def get_code(self, parent, modname, fqname):
+        if parent:
+            # the Importer._finish_import logic ensures that we handle imports
+            # under the top level module (package / archive).
+            assert parent.__importer__ == self
+
+            # if a parent "package" is provided, then we are importing a
+            # sub-file from the archive.
+            result = self.get_subfile(parent.__archive__, modname)
+            if result is None:
+                return None
+            if isinstance(result, _TupleType):
+                assert len(result) == 2
+                return (0,) + result
+            return 0, result, {}
+
+        # no parent was provided, so the archive should exist somewhere on the
+        # default "path".
+        archive = self.get_archive(modname)
+        if archive is None:
+            return None
+        return 1, "", {'__archive__':archive}
+
+    def get_archive(self, modname):
+        """Get an archive of modules.
+
+        This method should locate an archive and return a value which can be
+        used by get_subfile to load modules from it. The value may be a simple
+        pathname, an open file, or a complex object that caches information
+        for future imports.
+
+        Return None if the archive was not found.
+        """
+        raise RuntimeError, "get_archive not implemented"
+
+    def get_subfile(self, archive, modname):
+        """Get code from a subfile in the specified archive.
+
+        Given the specified archive (as returned by get_archive()), locate
+        and return a code object for the specified module name.
+
+        A 2-tuple may be returned, consisting of a code object and a dict
+        of name/values to place into the target module.
+
+        Return None if the subfile was not found.
+        """
+        raise RuntimeError, "get_subfile not implemented"
+
+
+class PackageArchive(PackageArchiveImporter):
+    "PackageArchiveImporter subclass that refers to a specific archive."
+
+    def __init__(self, modname, archive_pathname):
+        self.__modname = modname
+        self.__path = archive_pathname
+
+    def get_archive(self, modname):
+        if modname == self.__modname:
+            return self.__path
+        return None
+
+    # get_subfile is passed the full pathname of the archive
+
+
+######################################################################
+#
+# Emulate the standard directory-based import mechanism
+#
+class DirectoryImporter(imputil.Importer):
+    "Importer subclass to emulate the standard importer."
+
+    def __init__(self, dir):
+        self.dir = dir
+
+    def get_code(self, parent, modname, fqname):
+        if parent:
+            dir = parent.__pkgdir__
+        else:
+            dir = self.dir
+
+        # Return the module (and other info) if found in the specified
+        # directory. Otherwise, return None.
+        return _fs_import(dir, modname, fqname)
+
+    def __repr__(self):
+        return '<%s.%s for "%s" at 0x%x>' % (self.__class__.__module__,
+                                             self.__class__.__name__,
+                                             self.dir,
+                                             id(self))
+
+
+######################################################################
+#
+# Emulate the standard path-style import mechanism
+#
+class PathImporter(imputil.Importer):
+    def __init__(self, path=sys.path):
+        self.path = path
+
+    def get_code(self, parent, modname, fqname):
+        if parent:
+            # we are looking for a module inside of a specific package
+            return _fs_import(parent.__pkgdir__, modname, fqname)
+
+        # scan sys.path, looking for the requested module
+        for dir in self.path:
+            if isinstance(dir, _StringType):
+                result = _fs_import(dir, modname, fqname)
+                if result:
+                    return result
+
+        # not found
+        return None
+
+######################################################################
+
+def _test_dir():
+    "Debug/test function to create DirectoryImporters from sys.path."
+    imputil.ImportManager().install()
+    path = sys.path[:]
+    path.reverse()
+    for d in path:
+        sys.path.insert(0, DirectoryImporter(d))
+    sys.path.insert(0, imputil.BuiltinImporter())
+
+def _test_revamp():
+    "Debug/test function for the revamped import system."
+    imputil.ImportManager().install()
+    sys.path.insert(0, PathImporter())
+    sys.path.insert(0, imputil.BuiltinImporter())

Added: vendor/Python/current/Demo/imputil/knee.py
===================================================================
--- vendor/Python/current/Demo/imputil/knee.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/imputil/knee.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,126 @@
+"""An Python re-implementation of hierarchical module import.
+
+This code is intended to be read, not executed.  However, it does work
+-- all you need to do to enable it is "import knee".
+
+(The name is a pun on the klunkier predecessor of this module, "ni".)
+
+"""
+
+import sys, imp, __builtin__
+
+
+# Replacement for __import__()
+def import_hook(name, globals=None, locals=None, fromlist=None):
+    parent = determine_parent(globals)
+    q, tail = find_head_package(parent, name)
+    m = load_tail(q, tail)
+    if not fromlist:
+        return q
+    if hasattr(m, "__path__"):
+        ensure_fromlist(m, fromlist)
+    return m
+
+def determine_parent(globals):
+    if not globals or  not globals.has_key("__name__"):
+        return None
+    pname = globals['__name__']
+    if globals.has_key("__path__"):
+        parent = sys.modules[pname]
+        assert globals is parent.__dict__
+        return parent
+    if '.' in pname:
+        i = pname.rfind('.')
+        pname = pname[:i]
+        parent = sys.modules[pname]
+        assert parent.__name__ == pname
+        return parent
+    return None
+
+def find_head_package(parent, name):
+    if '.' in name:
+        i = name.find('.')
+        head = name[:i]
+        tail = name[i+1:]
+    else:
+        head = name
+        tail = ""
+    if parent:
+        qname = "%s.%s" % (parent.__name__, head)
+    else:
+        qname = head
+    q = import_module(head, qname, parent)
+    if q: return q, tail
+    if parent:
+        qname = head
+        parent = None
+        q = import_module(head, qname, parent)
+        if q: return q, tail
+    raise ImportError, "No module named " + qname
+
+def load_tail(q, tail):
+    m = q
+    while tail:
+        i = tail.find('.')
+        if i < 0: i = len(tail)
+        head, tail = tail[:i], tail[i+1:]
+        mname = "%s.%s" % (m.__name__, head)
+        m = import_module(head, mname, m)
+        if not m:
+            raise ImportError, "No module named " + mname
+    return m
+
+def ensure_fromlist(m, fromlist, recursive=0):
+    for sub in fromlist:
+        if sub == "*":
+            if not recursive:
+                try:
+                    all = m.__all__
+                except AttributeError:
+                    pass
+                else:
+                    ensure_fromlist(m, all, 1)
+            continue
+        if sub != "*" and not hasattr(m, sub):
+            subname = "%s.%s" % (m.__name__, sub)
+            submod = import_module(sub, subname, m)
+            if not submod:
+                raise ImportError, "No module named " + subname
+
+def import_module(partname, fqname, parent):
+    try:
+        return sys.modules[fqname]
+    except KeyError:
+        pass
+    try:
+        fp, pathname, stuff = imp.find_module(partname,
+                                              parent and parent.__path__)
+    except ImportError:
+        return None
+    try:
+        m = imp.load_module(fqname, fp, pathname, stuff)
+    finally:
+        if fp: fp.close()
+    if parent:
+        setattr(parent, partname, m)
+    return m
+
+
+# Replacement for reload()
+def reload_hook(module):
+    name = module.__name__
+    if '.' not in name:
+        return import_module(name, name, None)
+    i = name.rfind('.')
+    pname = name[:i]
+    parent = sys.modules[pname]
+    return import_module(name[i+1:], name, parent)
+
+
+# Save the original hooks
+original_import = __builtin__.__import__
+original_reload = __builtin__.reload
+
+# Now install our hooks
+__builtin__.__import__ = import_hook
+__builtin__.reload = reload_hook

Added: vendor/Python/current/Demo/md5test/README
===================================================================
--- vendor/Python/current/Demo/md5test/README	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/md5test/README	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,10 @@
+This is the Python version of the MD5 test program from the MD5
+Internet Draft (Rivest and Dusse, The MD5 Message-Digest Algorithm, 10
+July 1991).  The file "foo" contains the string "abc" with no trailing
+newline.
+
+When called without arguments, it acts as a filter.  When called with
+"-x", it executes a self-test, and the output should literally match
+the output given in the RFC.
+
+Code by Jan-Hein B\"uhrman after the original in C.

Added: vendor/Python/current/Demo/md5test/foo
===================================================================
--- vendor/Python/current/Demo/md5test/foo	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/md5test/foo	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1 @@
+abc
\ No newline at end of file


Property changes on: vendor/Python/current/Demo/md5test/foo
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/md5test/md5driver.py
===================================================================
--- vendor/Python/current/Demo/md5test/md5driver.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/md5test/md5driver.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,123 @@
+import string
+import md5
+from sys import argv
+
+def MDPrint(str):
+    outstr = ''
+    for i in str:
+        o = ord(i)
+        outstr = (outstr
+                  + string.hexdigits[(o >> 4) & 0xF]
+                  + string.hexdigits[o & 0xF])
+    print outstr,
+
+
+from time import time
+
+def makestr(start, end):
+    result = ''
+    for i in range(start, end + 1):
+        result = result + chr(i)
+
+    return result
+
+
+def MDTimeTrial():
+    TEST_BLOCK_SIZE = 1000
+    TEST_BLOCKS = 10000
+
+    TEST_BYTES = TEST_BLOCK_SIZE * TEST_BLOCKS
+
+    # initialize test data, need temporary string filler
+
+    filsiz = 1 << 8
+    filler = makestr(0, filsiz-1)
+    data = filler * (TEST_BLOCK_SIZE / filsiz);
+    data = data + filler[:(TEST_BLOCK_SIZE % filsiz)]
+
+    del filsiz, filler
+
+
+    # start timer
+    print 'MD5 time trial. Processing', TEST_BYTES, 'characters...'
+    t1 = time()
+
+    mdContext = md5.new()
+
+    for i in range(TEST_BLOCKS):
+        mdContext.update(data)
+
+    str = mdContext.digest()
+    t2 = time()
+
+    MDPrint(str)
+    print 'is digest of test input.'
+    print 'Seconds to process test input:', t2 - t1
+    print 'Characters processed per second:', TEST_BYTES / (t2 - t1)
+
+
+def MDString(str):
+    MDPrint(md5.new(str).digest())
+    print '"' + str + '"'
+
+
+def MDFile(filename):
+    f = open(filename, 'rb');
+    mdContext = md5.new()
+
+    while 1:
+        data = f.read(1024)
+        if not data:
+            break
+        mdContext.update(data)
+
+    MDPrint(mdContext.digest())
+    print filename
+
+
+import sys
+
+def MDFilter():
+    mdContext = md5.new()
+
+    while 1:
+        data = sys.stdin.read(16)
+        if not data:
+            break
+        mdContext.update(data)
+
+    MDPrint(mdContext.digest())
+    print
+
+
+def MDTestSuite():
+    print 'MD5 test suite results:'
+    MDString('')
+    MDString('a')
+    MDString('abc')
+    MDString('message digest')
+    MDString(makestr(ord('a'), ord('z')))
+    MDString(makestr(ord('A'), ord('Z'))
+              + makestr(ord('a'), ord('z'))
+              + makestr(ord('0'), ord('9')))
+    MDString((makestr(ord('1'), ord('9')) + '0') * 8)
+
+    # Contents of file foo are "abc"
+    MDFile('foo')
+
+
+# I don't wanna use getopt(), since I want to use the same i/f...
+def main():
+    if len(argv) == 1:
+        MDFilter()
+    for arg in argv[1:]:
+        if arg[:2] == '-s':
+            MDString(arg[2:])
+        elif arg == '-t':
+            MDTimeTrial()
+        elif arg == '-x':
+            MDTestSuite()
+        else:
+            MDFile(arg)
+
+main()


Property changes on: vendor/Python/current/Demo/md5test/md5driver.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/metaclasses/Eiffel.py
===================================================================
--- vendor/Python/current/Demo/metaclasses/Eiffel.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/metaclasses/Eiffel.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,113 @@
+"""Support Eiffel-style preconditions and postconditions.
+
+For example,
+
+class C:
+    def m1(self, arg):
+        require arg > 0
+        return whatever
+        ensure Result > arg
+
+can be written (clumsily, I agree) as:
+
+class C(Eiffel):
+    def m1(self, arg):
+        return whatever
+    def m1_pre(self, arg):
+        assert arg > 0
+    def m1_post(self, Result, arg):
+        assert Result > arg
+
+Pre- and post-conditions for a method, being implemented as methods
+themselves, are inherited independently from the method.  This gives
+much of the same effect of Eiffel, where pre- and post-conditions are
+inherited when a method is overridden by a derived class.  However,
+when a derived class in Python needs to extend a pre- or
+post-condition, it must manually merge the base class' pre- or
+post-condition with that defined in the derived class', for example:
+
+class D(C):
+    def m1(self, arg):
+        return arg**2
+    def m1_post(self, Result, arg):
+        C.m1_post(self, Result, arg)
+        assert Result < 100
+
+This gives derived classes more freedom but also more responsibility
+than in Eiffel, where the compiler automatically takes care of this.
+
+In Eiffel, pre-conditions combine using contravariance, meaning a
+derived class can only make a pre-condition weaker; in Python, this is
+up to the derived class.  For example, a derived class that takes away
+the requirement that arg > 0 could write:
+
+    def m1_pre(self, arg):
+        pass
+
+but one could equally write a derived class that makes a stronger
+requirement:
+
+    def m1_pre(self, arg):
+        require arg > 50
+
+It would be easy to modify the classes shown here so that pre- and
+post-conditions can be disabled (separately, on a per-class basis).
+
+A different design would have the pre- or post-condition testing
+functions return true for success and false for failure.  This would
+make it possible to implement automatic combination of inherited
+and new pre-/post-conditions.  All this is left as an exercise to the
+reader.
+
+"""
+
+from Meta import MetaClass, MetaHelper, MetaMethodWrapper
+
+class EiffelMethodWrapper(MetaMethodWrapper):
+
+    def __init__(self, func, inst):
+        MetaMethodWrapper.__init__(self, func, inst)
+        # Note that the following causes recursive wrappers around
+        # the pre-/post-condition testing methods.  These are harmless
+        # but inefficient; to avoid them, the lookup must be done
+        # using the class.
+        try:
+            self.pre = getattr(inst, self.__name__ + "_pre")
+        except AttributeError:
+            self.pre = None
+        try:
+            self.post = getattr(inst, self.__name__ + "_post")
+        except AttributeError:
+            self.post = None
+
+    def __call__(self, *args, **kw):
+        if self.pre:
+            apply(self.pre, args, kw)
+        Result = apply(self.func, (self.inst,) + args, kw)
+        if self.post:
+            apply(self.post, (Result,) + args, kw)
+        return Result
+
+class EiffelHelper(MetaHelper):
+    __methodwrapper__ = EiffelMethodWrapper
+
+class EiffelMetaClass(MetaClass):
+    __helper__ = EiffelHelper
+
+Eiffel = EiffelMetaClass('Eiffel', (), {})
+
+
+def _test():
+    class C(Eiffel):
+        def m1(self, arg):
+            return arg+1
+        def m1_pre(self, arg):
+            assert arg > 0, "precondition for m1 failed"
+        def m1_post(self, Result, arg):
+            assert Result > arg
+    x = C()
+    x.m1(12)
+##    x.m1(-1)
+
+if __name__ == '__main__':
+    _test()

Added: vendor/Python/current/Demo/metaclasses/Enum.py
===================================================================
--- vendor/Python/current/Demo/metaclasses/Enum.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/metaclasses/Enum.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,169 @@
+"""Enumeration metaclass.
+
+XXX This is very much a work in progress.
+
+"""
+
+import string
+
+class EnumMetaClass:
+    """Metaclass for enumeration.
+
+    To define your own enumeration, do something like
+
+    class Color(Enum):
+        red = 1
+        green = 2
+        blue = 3
+
+    Now, Color.red, Color.green and Color.blue behave totally
+    different: they are enumerated values, not integers.
+
+    Enumerations cannot be instantiated; however they can be
+    subclassed.
+
+    """
+
+    def __init__(self, name, bases, dict):
+        """Constructor -- create an enumeration.
+
+        Called at the end of the class statement.  The arguments are
+        the name of the new class, a tuple containing the base
+        classes, and a dictionary containing everything that was
+        entered in the class' namespace during execution of the class
+        statement.  In the above example, it would be {'red': 1,
+        'green': 2, 'blue': 3}.
+
+        """
+        for base in bases:
+            if base.__class__ is not EnumMetaClass:
+                raise TypeError, "Enumeration base class must be enumeration"
+        bases = filter(lambda x: x is not Enum, bases)
+        self.__name__ = name
+        self.__bases__ = bases
+        self.__dict = {}
+        for key, value in dict.items():
+            self.__dict[key] = EnumInstance(name, key, value)
+
+    def __getattr__(self, name):
+        """Return an enumeration value.
+
+        For example, Color.red returns the value corresponding to red.
+
+        XXX Perhaps the values should be created in the constructor?
+
+        This looks in the class dictionary and if it is not found
+        there asks the base classes.
+
+        The special attribute __members__ returns the list of names
+        defined in this class (it does not merge in the names defined
+        in base classes).
+
+        """
+        if name == '__members__':
+            return self.__dict.keys()
+
+        try:
+            return self.__dict[name]
+        except KeyError:
+            for base in self.__bases__:
+                try:
+                    return getattr(base, name)
+                except AttributeError:
+                    continue
+
+        raise AttributeError, name
+
+    def __repr__(self):
+        s = self.__name__
+        if self.__bases__:
+            s = s + '(' + string.join(map(lambda x: x.__name__,
+                                          self.__bases__), ", ") + ')'
+        if self.__dict:
+            list = []
+            for key, value in self.__dict.items():
+                list.append("%s: %s" % (key, int(value)))
+            s = "%s: {%s}" % (s, string.join(list, ", "))
+        return s
+
+
+class EnumInstance:
+    """Class to represent an enumeration value.
+
+    EnumInstance('Color', 'red', 12) prints as 'Color.red' and behaves
+    like the integer 12 when compared, but doesn't support arithmetic.
+
+    XXX Should it record the actual enumeration rather than just its
+    name?
+
+    """
+
+    def __init__(self, classname, enumname, value):
+        self.__classname = classname
+        self.__enumname = enumname
+        self.__value = value
+
+    def __int__(self):
+        return self.__value
+
+    def __repr__(self):
+        return "EnumInstance(%r, %r, %r)" % (self.__classname,
+                                             self.__enumname,
+                                             self.__value)
+
+    def __str__(self):
+        return "%s.%s" % (self.__classname, self.__enumname)
+
+    def __cmp__(self, other):
+        return cmp(self.__value, int(other))
+
+
+# Create the base class for enumerations.
+# It is an empty enumeration.
+Enum = EnumMetaClass("Enum", (), {})
+
+
+def _test():
+
+    class Color(Enum):
+        red = 1
+        green = 2
+        blue = 3
+
+    print Color.red
+    print dir(Color)
+
+    print Color.red == Color.red
+    print Color.red == Color.blue
+    print Color.red == 1
+    print Color.red == 2
+
+    class ExtendedColor(Color):
+        white = 0
+        orange = 4
+        yellow = 5
+        purple = 6
+        black = 7
+
+    print ExtendedColor.orange
+    print ExtendedColor.red
+
+    print Color.red == ExtendedColor.red
+
+    class OtherColor(Enum):
+        white = 4
+        blue = 5
+
+    class MergedColor(Color, OtherColor):
+        pass
+
+    print MergedColor.red
+    print MergedColor.white
+
+    print Color
+    print ExtendedColor
+    print OtherColor
+    print MergedColor
+
+if __name__ == '__main__':
+    _test()

Added: vendor/Python/current/Demo/metaclasses/Meta.py
===================================================================
--- vendor/Python/current/Demo/metaclasses/Meta.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/metaclasses/Meta.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,118 @@
+"""Generic metaclass.
+
+XXX This is very much a work in progress.
+
+"""
+
+import types
+
+class MetaMethodWrapper:
+
+    def __init__(self, func, inst):
+        self.func = func
+        self.inst = inst
+        self.__name__ = self.func.__name__
+
+    def __call__(self, *args, **kw):
+        return apply(self.func, (self.inst,) + args, kw)
+
+class MetaHelper:
+
+    __methodwrapper__ = MetaMethodWrapper # For derived helpers to override
+
+    def __helperinit__(self, formalclass):
+        self.__formalclass__ = formalclass
+
+    def __getattr__(self, name):
+        # Invoked for any attr not in the instance's __dict__
+        try:
+            raw = self.__formalclass__.__getattr__(name)
+        except AttributeError:
+            try:
+                ga = self.__formalclass__.__getattr__('__usergetattr__')
+            except (KeyError, AttributeError):
+                raise AttributeError, name
+            return ga(self, name)
+        if type(raw) != types.FunctionType:
+            return raw
+        return self.__methodwrapper__(raw, self)
+
+class MetaClass:
+
+    """A generic metaclass.
+
+    This can be subclassed to implement various kinds of meta-behavior.
+
+    """
+
+    __helper__ = MetaHelper             # For derived metaclasses to override
+
+    __inited = 0
+
+    def __init__(self, name, bases, dict):
+        try:
+            ga = dict['__getattr__']
+        except KeyError:
+            pass
+        else:
+            dict['__usergetattr__'] = ga
+            del dict['__getattr__']
+        self.__name__ = name
+        self.__bases__ = bases
+        self.__realdict__ = dict
+        self.__inited = 1
+
+    def __getattr__(self, name):
+        try:
+            return self.__realdict__[name]
+        except KeyError:
+            for base in self.__bases__:
+                try:
+                    return base.__getattr__(name)
+                except AttributeError:
+                    pass
+            raise AttributeError, name
+
+    def __setattr__(self, name, value):
+        if not self.__inited:
+            self.__dict__[name] = value
+        else:
+            self.__realdict__[name] = value
+
+    def __call__(self, *args, **kw):
+        inst = self.__helper__()
+        inst.__helperinit__(self)
+        try:
+            init = inst.__getattr__('__init__')
+        except AttributeError:
+            init = lambda: None
+        apply(init, args, kw)
+        return inst
+
+
+Meta = MetaClass('Meta', (), {})
+
+
+def _test():
+    class C(Meta):
+        def __init__(self, *args):
+            print "__init__, args =", args
+        def m1(self, x):
+            print "m1(x=%r)" % (x,)
+    print C
+    x = C()
+    print x
+    x.m1(12)
+    class D(C):
+        def __getattr__(self, name):
+            if name[:2] == '__': raise AttributeError, name
+            return "getattr:%s" % name
+    x = D()
+    print x.foo
+    print x._foo
+##     print x.__foo
+##     print x.__foo__
+
+
+if __name__ == '__main__':
+    _test()

Added: vendor/Python/current/Demo/metaclasses/Simple.py
===================================================================
--- vendor/Python/current/Demo/metaclasses/Simple.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/metaclasses/Simple.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,45 @@
+import types
+
+class Tracing:
+    def __init__(self, name, bases, namespace):
+        """Create a new class."""
+        self.__name__ = name
+        self.__bases__ = bases
+        self.__namespace__ = namespace
+    def __call__(self):
+        """Create a new instance."""
+        return Instance(self)
+
+class Instance:
+    def __init__(self, klass):
+        self.__klass__ = klass
+    def __getattr__(self, name):
+        try:
+            value = self.__klass__.__namespace__[name]
+        except KeyError:
+            raise AttributeError, name
+        if type(value) is not types.FunctionType:
+            return value
+        return BoundMethod(value, self)
+
+class BoundMethod:
+    def __init__(self, function, instance):
+        self.function = function
+        self.instance = instance
+    def __call__(self, *args):
+        print "calling", self.function, "for", self.instance, "with", args
+        return apply(self.function, (self.instance,) + args)
+
+Trace = Tracing('Trace', (), {})
+
+class MyTracedClass(Trace):
+    def method1(self, a):
+        self.a = a
+    def method2(self):
+        return self.a
+
+aninstance = MyTracedClass()
+
+aninstance.method1(10)
+
+print aninstance.method2()

Added: vendor/Python/current/Demo/metaclasses/Synch.py
===================================================================
--- vendor/Python/current/Demo/metaclasses/Synch.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/metaclasses/Synch.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,256 @@
+"""Synchronization metaclass.
+
+This metaclass  makes it possible to declare synchronized methods.
+
+"""
+
+import thread
+
+# First we need to define a reentrant lock.
+# This is generally useful and should probably be in a standard Python
+# library module.  For now, we in-line it.
+
+class Lock:
+
+    """Reentrant lock.
+
+    This is a mutex-like object which can be acquired by the same
+    thread more than once.  It keeps a reference count of the number
+    of times it has been acquired by the same thread.  Each acquire()
+    call must be matched by a release() call and only the last
+    release() call actually releases the lock for acquisition by
+    another thread.
+
+    The implementation uses two locks internally:
+
+    __mutex is a short term lock used to protect the instance variables
+    __wait is the lock for which other threads wait
+
+    A thread intending to acquire both locks should acquire __wait
+    first.
+
+   The implementation uses two other instance variables, protected by
+   locking __mutex:
+
+    __tid is the thread ID of the thread that currently has the lock
+    __count is the number of times the current thread has acquired it
+
+    When the lock is released, __tid is None and __count is zero.
+
+    """
+
+    def __init__(self):
+        """Constructor.  Initialize all instance variables."""
+        self.__mutex = thread.allocate_lock()
+        self.__wait = thread.allocate_lock()
+        self.__tid = None
+        self.__count = 0
+
+    def acquire(self, flag=1):
+        """Acquire the lock.
+
+        If the optional flag argument is false, returns immediately
+        when it cannot acquire the __wait lock without blocking (it
+        may still block for a little while in order to acquire the
+        __mutex lock).
+
+        The return value is only relevant when the flag argument is
+        false; it is 1 if the lock is acquired, 0 if not.
+
+        """
+        self.__mutex.acquire()
+        try:
+            if self.__tid == thread.get_ident():
+                self.__count = self.__count + 1
+                return 1
+        finally:
+            self.__mutex.release()
+        locked = self.__wait.acquire(flag)
+        if not flag and not locked:
+            return 0
+        try:
+            self.__mutex.acquire()
+            assert self.__tid == None
+            assert self.__count == 0
+            self.__tid = thread.get_ident()
+            self.__count = 1
+            return 1
+        finally:
+            self.__mutex.release()
+
+    def release(self):
+        """Release the lock.
+
+        If this thread doesn't currently have the lock, an assertion
+        error is raised.
+
+        Only allow another thread to acquire the lock when the count
+        reaches zero after decrementing it.
+
+        """
+        self.__mutex.acquire()
+        try:
+            assert self.__tid == thread.get_ident()
+            assert self.__count > 0
+            self.__count = self.__count - 1
+            if self.__count == 0:
+                self.__tid = None
+                self.__wait.release()
+        finally:
+            self.__mutex.release()
+
+
+def _testLock():
+
+    done = []
+
+    def f2(lock, done=done):
+        lock.acquire()
+        print "f2 running in thread %d\n" % thread.get_ident(),
+        lock.release()
+        done.append(1)
+
+    def f1(lock, f2=f2, done=done):
+        lock.acquire()
+        print "f1 running in thread %d\n" % thread.get_ident(),
+        try:
+            f2(lock)
+        finally:
+            lock.release()
+        done.append(1)
+
+    lock = Lock()
+    lock.acquire()
+    f1(lock)                            # Adds 2 to done
+    lock.release()
+
+    lock.acquire()
+
+    thread.start_new_thread(f1, (lock,)) # Adds 2
+    thread.start_new_thread(f1, (lock, f1)) # Adds 3
+    thread.start_new_thread(f2, (lock,)) # Adds 1
+    thread.start_new_thread(f2, (lock,)) # Adds 1
+
+    lock.release()
+    import time
+    while len(done) < 9:
+        print len(done)
+        time.sleep(0.001)
+    print len(done)
+
+
+# Now, the Locking metaclass is a piece of cake.
+# As an example feature, methods whose name begins with exactly one
+# underscore are not synchronized.
+
+from Meta import MetaClass, MetaHelper, MetaMethodWrapper
+
+class LockingMethodWrapper(MetaMethodWrapper):
+    def __call__(self, *args, **kw):
+        if self.__name__[:1] == '_' and self.__name__[1:] != '_':
+            return apply(self.func, (self.inst,) + args, kw)
+        self.inst.__lock__.acquire()
+        try:
+            return apply(self.func, (self.inst,) + args, kw)
+        finally:
+            self.inst.__lock__.release()
+
+class LockingHelper(MetaHelper):
+    __methodwrapper__ = LockingMethodWrapper
+    def __helperinit__(self, formalclass):
+        MetaHelper.__helperinit__(self, formalclass)
+        self.__lock__ = Lock()
+
+class LockingMetaClass(MetaClass):
+    __helper__ = LockingHelper
+
+Locking = LockingMetaClass('Locking', (), {})
+
+def _test():
+    # For kicks, take away the Locking base class and see it die
+    class Buffer(Locking):
+        def __init__(self, initialsize):
+            assert initialsize > 0
+            self.size = initialsize
+            self.buffer = [None]*self.size
+            self.first = self.last = 0
+        def put(self, item):
+            # Do we need to grow the buffer?
+            if (self.last+1) % self.size != self.first:
+                # Insert the new item
+                self.buffer[self.last] = item
+                self.last = (self.last+1) % self.size
+                return
+            # Double the buffer size
+            # First normalize it so that first==0 and last==size-1
+            print "buffer =", self.buffer
+            print "first = %d, last = %d, size = %d" % (
+                self.first, self.last, self.size)
+            if self.first <= self.last:
+                temp = self.buffer[self.first:self.last]
+            else:
+                temp = self.buffer[self.first:] + self.buffer[:self.last]
+            print "temp =", temp
+            self.buffer = temp + [None]*(self.size+1)
+            self.first = 0
+            self.last = self.size-1
+            self.size = self.size*2
+            print "Buffer size doubled to", self.size
+            print "new buffer =", self.buffer
+            print "first = %d, last = %d, size = %d" % (
+                self.first, self.last, self.size)
+            self.put(item)              # Recursive call to test the locking
+        def get(self):
+            # Is the buffer empty?
+            if self.first == self.last:
+                raise EOFError          # Avoid defining a new exception
+            item = self.buffer[self.first]
+            self.first = (self.first+1) % self.size
+            return item
+
+    def producer(buffer, wait, n=1000):
+        import time
+        i = 0
+        while i < n:
+            print "put", i
+            buffer.put(i)
+            i = i+1
+        print "Producer: done producing", n, "items"
+        wait.release()
+
+    def consumer(buffer, wait, n=1000):
+        import time
+        i = 0
+        tout = 0.001
+        while i < n:
+            try:
+                x = buffer.get()
+                if x != i:
+                    raise AssertionError, \
+                          "get() returned %s, expected %s" % (x, i)
+                print "got", i
+                i = i+1
+                tout = 0.001
+            except EOFError:
+                time.sleep(tout)
+                tout = tout*2
+        print "Consumer: done consuming", n, "items"
+        wait.release()
+
+    pwait = thread.allocate_lock()
+    pwait.acquire()
+    cwait = thread.allocate_lock()
+    cwait.acquire()
+    buffer = Buffer(1)
+    n = 1000
+    thread.start_new_thread(consumer, (buffer, cwait, n))
+    thread.start_new_thread(producer, (buffer, pwait, n))
+    pwait.acquire()
+    print "Producer done"
+    cwait.acquire()
+    print "All done"
+    print "buffer size ==", len(buffer.buffer)
+
+if __name__ == '__main__':
+    _testLock()
+    _test()

Added: vendor/Python/current/Demo/metaclasses/Trace.py
===================================================================
--- vendor/Python/current/Demo/metaclasses/Trace.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/metaclasses/Trace.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,144 @@
+"""Tracing metaclass.
+
+XXX This is very much a work in progress.
+
+"""
+
+import types, sys
+
+class TraceMetaClass:
+    """Metaclass for tracing.
+
+    Classes defined using this metaclass have an automatic tracing
+    feature -- by setting the __trace_output__ instance (or class)
+    variable to a file object, trace messages about all calls are
+    written to the file.  The trace formatting can be changed by
+    defining a suitable __trace_call__ method.
+
+    """
+
+    __inited = 0
+
+    def __init__(self, name, bases, dict):
+        self.__name__ = name
+        self.__bases__ = bases
+        self.__dict = dict
+        # XXX Can't define __dict__, alas
+        self.__inited = 1
+
+    def __getattr__(self, name):
+        try:
+            return self.__dict[name]
+        except KeyError:
+            for base in self.__bases__:
+                try:
+                    return base.__getattr__(name)
+                except AttributeError:
+                    pass
+            raise AttributeError, name
+
+    def __setattr__(self, name, value):
+        if not self.__inited:
+            self.__dict__[name] = value
+        else:
+            self.__dict[name] = value
+
+    def __call__(self, *args, **kw):
+        inst = TracingInstance()
+        inst.__meta_init__(self)
+        try:
+            init = inst.__getattr__('__init__')
+        except AttributeError:
+            init = lambda: None
+        apply(init, args, kw)
+        return inst
+
+    __trace_output__ = None
+
+class TracingInstance:
+    """Helper class to represent an instance of a tracing class."""
+
+    def __trace_call__(self, fp, fmt, *args):
+        fp.write((fmt+'\n') % args)
+
+    def __meta_init__(self, klass):
+        self.__class = klass
+
+    def __getattr__(self, name):
+        # Invoked for any attr not in the instance's __dict__
+        try:
+            raw = self.__class.__getattr__(name)
+        except AttributeError:
+            raise AttributeError, name
+        if type(raw) != types.FunctionType:
+            return raw
+        # It's a function
+        fullname = self.__class.__name__ + "." + name
+        if not self.__trace_output__ or name == '__trace_call__':
+            return NotTracingWrapper(fullname, raw, self)
+        else:
+            return TracingWrapper(fullname, raw, self)
+
+class NotTracingWrapper:
+    def __init__(self, name, func, inst):
+        self.__name__ = name
+        self.func = func
+        self.inst = inst
+    def __call__(self, *args, **kw):
+        return apply(self.func, (self.inst,) + args, kw)
+
+class TracingWrapper(NotTracingWrapper):
+    def __call__(self, *args, **kw):
+        self.inst.__trace_call__(self.inst.__trace_output__,
+                                 "calling %s, inst=%s, args=%s, kw=%s",
+                                 self.__name__, self.inst, args, kw)
+        try:
+            rv = apply(self.func, (self.inst,) + args, kw)
+        except:
+            t, v, tb = sys.exc_info()
+            self.inst.__trace_call__(self.inst.__trace_output__,
+                                     "returning from %s with exception %s: %s",
+                                     self.__name__, t, v)
+            raise t, v, tb
+        else:
+            self.inst.__trace_call__(self.inst.__trace_output__,
+                                     "returning from %s with value %s",
+                                     self.__name__, rv)
+            return rv
+
+Traced = TraceMetaClass('Traced', (), {'__trace_output__': None})
+
+
+def _test():
+    global C, D
+    class C(Traced):
+        def __init__(self, x=0): self.x = x
+        def m1(self, x): self.x = x
+        def m2(self, y): return self.x + y
+        __trace_output__ = sys.stdout
+    class D(C):
+        def m2(self, y): print "D.m2(%r)" % (y,); return C.m2(self, y)
+        __trace_output__ = None
+    x = C(4321)
+    print x
+    print x.x
+    print x.m1(100)
+    print x.m1(10)
+    print x.m2(33)
+    print x.m1(5)
+    print x.m2(4000)
+    print x.x
+
+    print C.__init__
+    print C.m2
+    print D.__init__
+    print D.m2
+
+    y = D()
+    print y
+    print y.m1(10)
+    print y.m2(100)
+    print y.x
+
+if __name__ == '__main__':
+    _test()

Added: vendor/Python/current/Demo/metaclasses/index.html
===================================================================
--- vendor/Python/current/Demo/metaclasses/index.html	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/metaclasses/index.html	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,605 @@
+<HTML>
+
+<HEAD>
+<TITLE>Metaclasses in Python 1.5</TITLE>
+</HEAD>
+
+<BODY BGCOLOR="FFFFFF">
+
+<H1>Metaclasses in Python 1.5</H1>
+<H2>(A.k.a. The Killer Joke :-)</H2>
+
+<HR>
+
+(<i>Postscript:</i> reading this essay is probably not the best way to
+understand the metaclass hook described here.  See a <A
+HREF="meta-vladimir.txt">message posted by Vladimir Marangozov</A>
+which may give a gentler introduction to the matter.  You may also
+want to search Deja News for messages with "metaclass" in the subject
+posted to comp.lang.python in July and August 1998.)
+
+<HR>
+
+<P>In previous Python releases (and still in 1.5), there is something
+called the ``Don Beaudry hook'', after its inventor and champion.
+This allows C extensions to provide alternate class behavior, thereby
+allowing the Python class syntax to be used to define other class-like
+entities.  Don Beaudry has used this in his infamous <A
+HREF="http://maigret.cog.brown.edu/pyutil/">MESS</A> package; Jim
+Fulton has used it in his <A
+HREF="http://www.digicool.com/releases/ExtensionClass/">Extension
+Classes</A> package.  (It has also been referred to as the ``Don
+Beaudry <i>hack</i>,'' but that's a misnomer.  There's nothing hackish
+about it -- in fact, it is rather elegant and deep, even though
+there's something dark to it.)
+
+<P>(On first reading, you may want to skip directly to the examples in
+the section "Writing Metaclasses in Python" below, unless you want
+your head to explode.)
+
+<P>
+
+<HR>
+
+<P>Documentation of the Don Beaudry hook has purposefully been kept
+minimal, since it is a feature of incredible power, and is easily
+abused.  Basically, it checks whether the <b>type of the base
+class</b> is callable, and if so, it is called to create the new
+class.
+
+<P>Note the two indirection levels.  Take a simple example:
+
+<PRE>
+class B:
+    pass
+
+class C(B):
+    pass
+</PRE>
+
+Take a look at the second class definition, and try to fathom ``the
+type of the base class is callable.''
+
+<P>(Types are not classes, by the way.  See questions 4.2, 4.19 and in
+particular 6.22 in the <A
+HREF="http://www.python.org/cgi-bin/faqw.py" >Python FAQ</A>
+for more on this topic.)
+
+<P>
+
+<UL>
+
+<LI>The <b>base class</b> is B; this one's easy.<P>
+
+<LI>Since B is a class, its type is ``class''; so the <b>type of the
+base class</b> is the type ``class''.  This is also known as
+types.ClassType, assuming the standard module <code>types</code> has
+been imported.<P>
+
+<LI>Now is the type ``class'' <b>callable</b>?  No, because types (in
+core Python) are never callable.  Classes are callable (calling a
+class creates a new instance) but types aren't.<P>
+
+</UL>
+
+<P>So our conclusion is that in our example, the type of the base
+class (of C) is not callable.  So the Don Beaudry hook does not apply,
+and the default class creation mechanism is used (which is also used
+when there is no base class).  In fact, the Don Beaudry hook never
+applies when using only core Python, since the type of a core object
+is never callable.
+
+<P>So what do Don and Jim do in order to use Don's hook?  Write an
+extension that defines at least two new Python object types.  The
+first would be the type for ``class-like'' objects usable as a base
+class, to trigger Don's hook.  This type must be made callable.
+That's why we need a second type.  Whether an object is callable
+depends on its type.  So whether a type object is callable depends on
+<i>its</i> type, which is a <i>meta-type</i>.  (In core Python there
+is only one meta-type, the type ``type'' (types.TypeType), which is
+the type of all type objects, even itself.)  A new meta-type must
+be defined that makes the type of the class-like objects callable.
+(Normally, a third type would also be needed, the new ``instance''
+type, but this is not an absolute requirement -- the new class type
+could return an object of some existing type when invoked to create an
+instance.)
+
+<P>Still confused?  Here's a simple device due to Don himself to
+explain metaclasses.  Take a simple class definition; assume B is a
+special class that triggers Don's hook:
+
+<PRE>
+class C(B):
+    a = 1
+    b = 2
+</PRE>
+
+This can be though of as equivalent to:
+
+<PRE>
+C = type(B)('C', (B,), {'a': 1, 'b': 2})
+</PRE>
+
+If that's too dense for you, here's the same thing written out using
+temporary variables:
+
+<PRE>
+creator = type(B)               # The type of the base class
+name = 'C'                      # The name of the new class
+bases = (B,)                    # A tuple containing the base class(es)
+namespace = {'a': 1, 'b': 2}    # The namespace of the class statement
+C = creator(name, bases, namespace)
+</PRE>
+
+This is analogous to what happens without the Don Beaudry hook, except
+that in that case the creator function is set to the default class
+creator.
+
+<P>In either case, the creator is called with three arguments.  The
+first one, <i>name</i>, is the name of the new class (as given at the
+top of the class statement).  The <i>bases</i> argument is a tuple of
+base classes (a singleton tuple if there's only one base class, like
+the example).  Finally, <i>namespace</i> is a dictionary containing
+the local variables collected during execution of the class statement.
+
+<P>Note that the contents of the namespace dictionary is simply
+whatever names were defined in the class statement.  A little-known
+fact is that when Python executes a class statement, it enters a new
+local namespace, and all assignments and function definitions take
+place in this namespace.  Thus, after executing the following class
+statement:
+
+<PRE>
+class C:
+    a = 1
+    def f(s): pass
+</PRE>
+
+the class namespace's contents would be {'a': 1, 'f': &lt;function f
+...&gt;}.
+
+<P>But enough already about writing Python metaclasses in C; read the
+documentation of <A
+HREF="http://maigret.cog.brown.edu/pyutil/">MESS</A> or <A
+HREF="http://www.digicool.com/papers/ExtensionClass.html" >Extension
+Classes</A> for more information.
+
+<P>
+
+<HR>
+
+<H2>Writing Metaclasses in Python</H2>
+
+<P>In Python 1.5, the requirement to write a C extension in order to
+write metaclasses has been dropped (though you can still do
+it, of course).  In addition to the check ``is the type of the base
+class callable,'' there's a check ``does the base class have a
+__class__ attribute.''  If so, it is assumed that the __class__
+attribute refers to a class.
+
+<P>Let's repeat our simple example from above:
+
+<PRE>
+class C(B):
+    a = 1
+    b = 2
+</PRE>
+
+Assuming B has a __class__ attribute, this translates into:
+
+<PRE>
+C = B.__class__('C', (B,), {'a': 1, 'b': 2})
+</PRE>
+
+This is exactly the same as before except that instead of type(B),
+B.__class__ is invoked.  If you have read <A HREF=
+"http://www.python.org/cgi-bin/faqw.py?req=show&file=faq06.022.htp"
+>FAQ question 6.22</A> you will understand that while there is a big
+technical difference between type(B) and B.__class__, they play the
+same role at different abstraction levels.  And perhaps at some point
+in the future they will really be the same thing (at which point you
+would be able to derive subclasses from built-in types).
+
+<P>At this point it may be worth mentioning that C.__class__ is the
+same object as B.__class__, i.e., C's metaclass is the same as B's
+metaclass.  In other words, subclassing an existing class creates a
+new (meta)inststance of the base class's metaclass.
+
+<P>Going back to the example, the class B.__class__ is instantiated,
+passing its constructor the same three arguments that are passed to
+the default class constructor or to an extension's metaclass:
+<i>name</i>, <i>bases</i>, and <i>namespace</i>.
+
+<P>It is easy to be confused by what exactly happens when using a
+metaclass, because we lose the absolute distinction between classes
+and instances: a class is an instance of a metaclass (a
+``metainstance''), but technically (i.e. in the eyes of the python
+runtime system), the metaclass is just a class, and the metainstance
+is just an instance.  At the end of the class statement, the metaclass
+whose metainstance is used as a base class is instantiated, yielding a
+second metainstance (of the same metaclass).  This metainstance is
+then used as a (normal, non-meta) class; instantiation of the class
+means calling the metainstance, and this will return a real instance.
+And what class is that an instance of?  Conceptually, it is of course
+an instance of our metainstance; but in most cases the Python runtime
+system will see it as an instance of a a helper class used by the
+metaclass to implement its (non-meta) instances...
+
+<P>Hopefully an example will make things clearer.  Let's presume we
+have a metaclass MetaClass1.  It's helper class (for non-meta
+instances) is callled HelperClass1.  We now (manually) instantiate
+MetaClass1 once to get an empty special base class:
+
+<PRE>
+BaseClass1 = MetaClass1("BaseClass1", (), {})
+</PRE>
+
+We can now use BaseClass1 as a base class in a class statement:
+
+<PRE>
+class MySpecialClass(BaseClass1):
+    i = 1
+    def f(s): pass
+</PRE>
+
+At this point, MySpecialClass is defined; it is a metainstance of
+MetaClass1 just like BaseClass1, and in fact the expression
+``BaseClass1.__class__ == MySpecialClass.__class__ == MetaClass1''
+yields true.
+
+<P>We are now ready to create instances of MySpecialClass.  Let's
+assume that no constructor arguments are required:
+
+<PRE>
+x = MySpecialClass()
+y = MySpecialClass()
+print x.__class__, y.__class__
+</PRE>
+
+The print statement shows that x and y are instances of HelperClass1.
+How did this happen?  MySpecialClass is an instance of MetaClass1
+(``meta'' is irrelevant here); when an instance is called, its
+__call__ method is invoked, and presumably the __call__ method defined
+by MetaClass1 returns an instance of HelperClass1.
+
+<P>Now let's see how we could use metaclasses -- what can we do
+with metaclasses that we can't easily do without them?  Here's one
+idea: a metaclass could automatically insert trace calls for all
+method calls.  Let's first develop a simplified example, without
+support for inheritance or other ``advanced'' Python features (we'll
+add those later).
+
+<PRE>
+import types
+
+class Tracing:
+    def __init__(self, name, bases, namespace):
+        """Create a new class."""
+        self.__name__ = name
+        self.__bases__ = bases
+        self.__namespace__ = namespace
+    def __call__(self):
+        """Create a new instance."""
+        return Instance(self)
+
+class Instance:
+    def __init__(self, klass):
+        self.__klass__ = klass
+    def __getattr__(self, name):
+        try:
+            value = self.__klass__.__namespace__[name]
+        except KeyError:
+            raise AttributeError, name
+        if type(value) is not types.FunctionType:
+            return value
+        return BoundMethod(value, self)
+
+class BoundMethod:
+    def __init__(self, function, instance):
+        self.function = function
+        self.instance = instance
+    def __call__(self, *args):
+        print "calling", self.function, "for", self.instance, "with", args
+        return apply(self.function, (self.instance,) + args)
+
+Trace = Tracing('Trace', (), {})
+
+class MyTracedClass(Trace):
+    def method1(self, a):
+        self.a = a
+    def method2(self):
+        return self.a
+
+aninstance = MyTracedClass()
+
+aninstance.method1(10)
+
+print "the answer is %d" % aninstance.method2()
+</PRE>
+
+Confused already?  The intention is to read this from top down.  The
+Tracing class is the metaclass we're defining.  Its structure is
+really simple.
+
+<P>
+
+<UL>
+
+<LI>The __init__ method is invoked when a new Tracing instance is
+created, e.g. the definition of class MyTracedClass later in the
+example.  It simply saves the class name, base classes and namespace
+as instance variables.<P>
+
+<LI>The __call__ method is invoked when a Tracing instance is called,
+e.g. the creation of aninstance later in the example.  It returns an
+instance of the class Instance, which is defined next.<P>
+
+</UL>
+
+<P>The class Instance is the class used for all instances of classes
+built using the Tracing metaclass, e.g. aninstance.  It has two
+methods:
+
+<P>
+
+<UL>
+
+<LI>The __init__ method is invoked from the Tracing.__call__ method
+above to initialize a new instance.  It saves the class reference as
+an instance variable.  It uses a funny name because the user's
+instance variables (e.g. self.a later in the example) live in the same
+namespace.<P>
+
+<LI>The __getattr__ method is invoked whenever the user code
+references an attribute of the instance that is not an instance
+variable (nor a class variable; but except for __init__ and
+__getattr__ there are no class variables).  It will be called, for
+example, when aninstance.method1 is referenced in the example, with
+self set to aninstance and name set to the string "method1".<P>
+
+</UL>
+
+<P>The __getattr__ method looks the name up in the __namespace__
+dictionary.  If it isn't found, it raises an AttributeError exception.
+(In a more realistic example, it would first have to look through the
+base classes as well.)  If it is found, there are two possibilities:
+it's either a function or it isn't.  If it's not a function, it is
+assumed to be a class variable, and its value is returned.  If it's a
+function, we have to ``wrap'' it in instance of yet another helper
+class, BoundMethod.
+
+<P>The BoundMethod class is needed to implement a familiar feature:
+when a method is defined, it has an initial argument, self, which is
+automatically bound to the relevant instance when it is called.  For
+example, aninstance.method1(10) is equivalent to method1(aninstance,
+10).  In the example if this call, first a temporary BoundMethod
+instance is created with the following constructor call: temp =
+BoundMethod(method1, aninstance); then this instance is called as
+temp(10).  After the call, the temporary instance is discarded.
+
+<P>
+
+<UL>
+
+<LI>The __init__ method is invoked for the constructor call
+BoundMethod(method1, aninstance).  It simply saves away its
+arguments.<P>
+
+<LI>The __call__ method is invoked when the bound method instance is
+called, as in temp(10).  It needs to call method1(aninstance, 10).
+However, even though self.function is now method1 and self.instance is
+aninstance, it can't call self.function(self.instance, args) directly,
+because it should work regardless of the number of arguments passed.
+(For simplicity, support for keyword arguments has been omitted.)<P>
+
+</UL>
+
+<P>In order to be able to support arbitrary argument lists, the
+__call__ method first constructs a new argument tuple.  Conveniently,
+because of the notation *args in __call__'s own argument list, the
+arguments to __call__ (except for self) are placed in the tuple args.
+To construct the desired argument list, we concatenate a singleton
+tuple containing the instance with the args tuple: (self.instance,) +
+args.  (Note the trailing comma used to construct the singleton
+tuple.)  In our example, the resulting argument tuple is (aninstance,
+10).
+
+<P>The intrinsic function apply() takes a function and an argument
+tuple and calls the function for it.  In our example, we are calling
+apply(method1, (aninstance, 10)) which is equivalent to calling
+method(aninstance, 10).
+
+<P>From here on, things should come together quite easily.  The output
+of the example code is something like this:
+
+<PRE>
+calling &lt;function method1 at ae8d8&gt; for &lt;Instance instance at 95ab0&gt; with (10,)
+calling &lt;function method2 at ae900&gt; for &lt;Instance instance at 95ab0&gt; with ()
+the answer is 10
+</PRE>
+
+<P>That was about the shortest meaningful example that I could come up
+with.  A real tracing metaclass (for example, <A
+HREF="#Trace">Trace.py</A> discussed below) needs to be more
+complicated in two dimensions.
+
+<P>First, it needs to support more advanced Python features such as
+class variables, inheritance, __init__ methods, and keyword arguments.
+
+<P>Second, it needs to provide a more flexible way to handle the
+actual tracing information; perhaps it should be possible to write
+your own tracing function that gets called, perhaps it should be
+possible to enable and disable tracing on a per-class or per-instance
+basis, and perhaps a filter so that only interesting calls are traced;
+it should also be able to trace the return value of the call (or the
+exception it raised if an error occurs).  Even the Trace.py example
+doesn't support all these features yet.
+
+<P>
+
+<HR>
+
+<H1>Real-life Examples</H1>
+
+<P>Have a look at some very preliminary examples that I coded up to
+teach myself how to write metaclasses:
+
+<DL>
+
+<DT><A HREF="Enum.py">Enum.py</A>
+
+<DD>This (ab)uses the class syntax as an elegant way to define
+enumerated types.  The resulting classes are never instantiated --
+rather, their class attributes are the enumerated values.  For
+example:
+
+<PRE>
+class Color(Enum):
+    red = 1
+    green = 2
+    blue = 3
+print Color.red
+</PRE>
+
+will print the string ``Color.red'', while ``Color.red==1'' is true,
+and ``Color.red + 1'' raise a TypeError exception.
+
+<P>
+
+<DT><A NAME=Trace></A><A HREF="Trace.py">Trace.py</A>
+
+<DD>The resulting classes work much like standard
+classes, but by setting a special class or instance attribute
+__trace_output__ to point to a file, all calls to the class's methods
+are traced.  It was a bit of a struggle to get this right.  This
+should probably redone using the generic metaclass below.
+
+<P>
+
+<DT><A HREF="Meta.py">Meta.py</A>
+
+<DD>A generic metaclass.  This is an attempt at finding out how much
+standard class behavior can be mimicked by a metaclass.  The
+preliminary answer appears to be that everything's fine as long as the
+class (or its clients) don't look at the instance's __class__
+attribute, nor at the class's __dict__ attribute.  The use of
+__getattr__ internally makes the classic implementation of __getattr__
+hooks tough; we provide a similar hook _getattr_ instead.
+(__setattr__ and __delattr__ are not affected.)
+(XXX Hm.  Could detect presence of __getattr__ and rename it.)
+
+<P>
+
+<DT><A HREF="Eiffel.py">Eiffel.py</A>
+
+<DD>Uses the above generic metaclass to implement Eiffel style
+pre-conditions and post-conditions.
+
+<P>
+
+<DT><A HREF="Synch.py">Synch.py</A>
+
+<DD>Uses the above generic metaclass to implement synchronized
+methods.
+
+<P>
+
+<DT><A HREF="Simple.py">Simple.py</A>
+
+<DD>The example module used above.
+
+<P>
+
+</DL>
+
+<P>A pattern seems to be emerging: almost all these uses of
+metaclasses (except for Enum, which is probably more cute than useful)
+mostly work by placing wrappers around method calls.  An obvious
+problem with that is that it's not easy to combine the features of
+different metaclasses, while this would actually be quite useful: for
+example, I wouldn't mind getting a trace from the test run of the
+Synch module, and it would be interesting to add preconditions to it
+as well.  This needs more research.  Perhaps a metaclass could be
+provided that allows stackable wrappers...
+
+<P>
+
+<HR>
+
+<H2>Things You Could Do With Metaclasses</H2>
+
+<P>There are lots of things you could do with metaclasses.  Most of
+these can also be done with creative use of __getattr__, but
+metaclasses make it easier to modify the attribute lookup behavior of
+classes.  Here's a partial list.
+
+<P>
+
+<UL>
+
+<LI>Enforce different inheritance semantics, e.g. automatically call
+base class methods when a derived class overrides<P>
+
+<LI>Implement class methods (e.g. if the first argument is not named
+'self')<P>
+
+<LI>Implement that each instance is initialized with <b>copies</b> of
+all class variables<P>
+
+<LI>Implement a different way to store instance variables (e.g. in a
+list kept outside the instance but indexed by the instance's id())<P>
+
+<LI>Automatically wrap or trap all or certain methods
+
+<UL>
+
+<LI>for tracing
+
+<LI>for precondition and postcondition checking
+
+<LI>for synchronized methods
+
+<LI>for automatic value caching
+
+</UL>
+<P>
+
+<LI>When an attribute is a parameterless function, call it on
+reference (to mimic it being an instance variable); same on assignment<P>
+
+<LI>Instrumentation: see how many times various attributes are used<P>
+
+<LI>Different semantics for __setattr__ and __getattr__ (e.g.  disable
+them when they are being used recursively)<P>
+
+<LI>Abuse class syntax for other things<P>
+
+<LI>Experiment with automatic type checking<P>
+
+<LI>Delegation (or acquisition)<P>
+
+<LI>Dynamic inheritance patterns<P>
+
+<LI>Automatic caching of methods<P>
+
+</UL>
+
+<P>
+
+<HR>
+
+<H4>Credits</H4>
+
+<P>Many thanks to David Ascher and Donald Beaudry for their comments
+on earlier draft of this paper.  Also thanks to Matt Conway and Tommy
+Burnette for putting a seed for the idea of metaclasses in my
+mind, nearly three years ago, even though at the time my response was
+``you can do that with __getattr__ hooks...'' :-)
+
+<P>
+
+<HR>
+
+</BODY>
+
+</HTML>

Added: vendor/Python/current/Demo/metaclasses/meta-vladimir.txt
===================================================================
--- vendor/Python/current/Demo/metaclasses/meta-vladimir.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/metaclasses/meta-vladimir.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,256 @@
+Subject: Re: The metaclass saga using Python
+From: Vladimir Marangozov <Vladimir.Marangozov at imag.fr>
+To: tim_one at email.msn.com (Tim Peters)
+Cc: python-list at cwi.nl
+Date: Wed, 5 Aug 1998 15:59:06 +0200 (DFT)
+
+[Tim]
+> 
+> building-on-examples-tends-to-prevent-abstract-thrashing-ly y'rs  - tim
+> 
+
+OK, I stand corrected. I understand that anybody's interpretation of
+the meta-class concept is likely to be difficult to digest by others.
+
+Here's another try, expressing the same thing, but using the Python
+programming model, examples and, perhaps, more popular terms.
+
+1. Classes.
+
+   This is pure Python of today. Sorry about the tutorial, but it is
+   meant to illustrate the second part, which is the one we're
+   interested in and which will follow the same development scenario.
+   Besides, newbies are likely to understand that the discussion is
+   affordable even for them :-)
+
+   a) Class definition
+
+      A class is meant to define the common properties of a set of objects.
+      A class is a "package" of properties. The assembly of properties
+      in a class package is sometimes called a class structure (which isn't
+      always appropriate).
+
+      >>> class A:
+              attr1 = "Hello"                  # an attribute of A
+              def method1(self, *args): pass   # method1 of A
+              def method2(self, *args): pass   # method2 of A
+      >>>
+
+      So far, we defined the structure of the class A. The class A is
+      of type <class>. We can check this by asking Python: "what is A?"
+
+      >>> A                                # What is A?
+      <class __main__.A at 2023e360>
+
+   b) Class instantiation
+
+      Creating an object with the properties defined in the class A is
+      called instantiation of the class A. After an instantiation of A, we
+      obtain a new object, called an instance, which has the properties
+      packaged in the class A.
+
+      >>> a = A()                          # 'a' is the 1st instance of A 
+      >>> a                                # What is 'a'? 
+      <__main__.A instance at 2022b9d0>
+
+      >>> b = A()                          # 'b' is another instance of A
+      >>> b                                # What is 'b'?
+      <__main__.A instance at 2022b9c0>
+
+      The objects, 'a' and 'b', are of type <instance> and they both have
+      the same properties. Note, that 'a' and 'b' are different objects.
+      (their adresses differ). This is a bit hard to see, so let's ask Python:
+
+      >>> a == b                           # Is 'a' the same object as 'b'?
+      0                                    # No.
+
+      Instance objects have one more special property, indicating the class
+      they are an instance of. This property is named __class__.
+
+      >>> a.__class__                      # What is the class of 'a'?
+      <class __main__.A at 2023e360>       # 'a' is an instance of A
+      >>> b.__class__                      # What is the class of 'b'?
+      <class __main__.A at 2023e360>       # 'b' is an instance of A
+      >>> a.__class__ == b.__class__       # Is it really the same class A?
+      1                                    # Yes.
+
+   c) Class inheritance (class composition and specialization)
+
+      Classes can be defined in terms of other existing classes (and only
+      classes! -- don't bug me on this now). Thus, we can compose property
+      packages and create new ones. We reuse the property set defined
+      in a class by defining a new class, which "inherits" from the former.
+      In other words, a class B which inherits from the class A, inherits
+      the properties defined in A, or, B inherits the structure of A.
+
+      In the same time, at the definition of the new class B, we can enrich
+      the inherited set of properties by adding new ones and/or modify some
+      of the inherited properties.
+      
+      >>> class B(A):                          # B inherits A's properties
+              attr2 = "World"                  # additional attr2
+              def method2(self, arg1): pass    # method2 is redefined
+              def method3(self, *args): pass   # additional method3
+
+      >>> B                                 # What is B?
+      <class __main__.B at 2023e500>
+      >>> B == A                            # Is B the same class as A?
+      0                                     # No.
+
+      Classes define one special property, indicating whether a class
+      inherits the properties of another class. This property is called
+      __bases__ and it contains a list (a tuple) of the classes the new
+      class inherits from. The classes from which a class is inheriting the
+      properties are called superclasses (in Python, we call them also --
+      base classes).
+
+      >>> A.__bases__                       # Does A have any superclasses?
+      ()                                    # No.
+      >>> B.__bases__                       # Does B have any superclasses?
+      (<class __main__.A at 2023e360>,)     # Yes. It has one superclass.
+      >>> B.__bases__[0] == A               # Is it really the class A?
+      1                                     # Yes, it is.
+
+--------
+
+   Congratulations on getting this far! This was the hard part.
+   Now, let's continue with the easy one.
+
+--------
+
+2. Meta-classes
+
+   You have to admit, that an anonymous group of Python wizards are
+   not satisfied with the property packaging facilities presented above.
+   They say, that the Real-World bugs them with problems that cannot be
+   modelled successfully with classes. Or, that the way classes are
+   implemented in Python and the way classes and instances behave at
+   runtime isn't always appropriate for reproducing the Real-World's
+   behavior in a way that satisfies them.
+
+   Hence, what they want is the following:
+
+      a) leave objects as they are (instances of classes)
+      b) leave classes as they are (property packages and object creators)
+
+   BUT, at the same time:
+
+      c) consider classes as being instances of mysterious objects.
+      d) label mysterious objects "meta-classes".
+
+   Easy, eh?
+
+   You may ask: "Why on earth do they want to do that?".
+   They answer: "Poor soul... Go and see how cruel the Real-World is!".
+   You - fuzzy: "OK, will do!"
+
+   And here we go for another round of what I said in section 1 -- Classes.
+
+   However, be warned! The features we're going to talk about aren't fully
+   implemented yet, because the Real-World don't let wizards to evaluate
+   precisely how cruel it is, so the features are still highly-experimental.
+
+   a) Meta-class definition
+
+      A meta-class is meant to define the common properties of a set of
+      classes.  A meta-class is a "package" of properties. The assembly
+      of properties in a meta-class package is sometimes called a meta-class
+      structure (which isn't always appropriate).
+
+      In Python, a meta-class definition would have looked like this:
+
+      >>> metaclass M:
+              attr1 = "Hello"                  # an attribute of M
+              def method1(self, *args): pass   # method1 of M
+              def method2(self, *args): pass   # method2 of M
+      >>>
+
+      So far, we defined the structure of the meta-class M. The meta-class
+      M is of type <metaclass>. We cannot check this by asking Python, but
+      if we could, it would have answered:
+
+      >>> M                                # What is M?
+      <metaclass __main__.M at 2023e4e0>
+
+   b) Meta-class instantiation
+
+      Creating an object with the properties defined in the meta-class M is
+      called instantiation of the meta-class M. After an instantiation of M,
+      we obtain a new object, called an class, but now it is called also
+      a meta-instance, which has the properties packaged in the meta-class M.
+
+      In Python, instantiating a meta-class would have looked like this:
+
+      >>> A = M()                          # 'A' is the 1st instance of M
+      >>> A                                # What is 'A'?
+      <class __main__.A at 2022b9d0>
+
+      >>> B = M()                          # 'B' is another instance of M
+      >>> B                                # What is 'B'?
+      <class __main__.B at 2022b9c0>
+
+      The metaclass-instances, A and B, are of type <class> and they both
+      have the same properties. Note, that A and B are different objects.
+      (their adresses differ). This is a bit hard to see, but if it was
+      possible to ask Python, it would have answered:
+
+      >>> A == B                           # Is A the same class as B?
+      0                                    # No.
+
+      Class objects have one more special property, indicating the meta-class
+      they are an instance of. This property is named __metaclass__.
+
+      >>> A.__metaclass__                  # What is the meta-class of A?
+      <metaclass __main__.M at 2023e4e0>   # A is an instance of M
+      >>> A.__metaclass__                  # What is the meta-class of B?
+      <metaclass __main__.M at 2023e4e0>   # B is an instance of M
+      >>> A.__metaclass__ == B.__metaclass__  # Is it the same meta-class M?
+      1                                    # Yes.
+
+   c) Meta-class inheritance (meta-class composition and specialization)
+
+      Meta-classes can be defined in terms of other existing meta-classes
+      (and only meta-classes!). Thus, we can compose property packages and
+      create new ones. We reuse the property set defined in a meta-class by
+      defining a new meta-class, which "inherits" from the former.
+      In other words, a meta-class N which inherits from the meta-class M,
+      inherits the properties defined in M, or, N inherits the structure of M.
+
+      In the same time, at the definition of the new meta-class N, we can
+      enrich the inherited set of properties by adding new ones and/or modify
+      some of the inherited properties.
+
+      >>> metaclass N(M):                      # N inherits M's properties
+              attr2 = "World"                  # additional attr2
+              def method2(self, arg1): pass    # method2 is redefined
+              def method3(self, *args): pass   # additional method3
+
+      >>> N                              # What is N?
+      <metaclass __main__.N at 2023e500>
+      >>> N == M                         # Is N the same meta-class as M?
+      0                                  # No.
+
+      Meta-classes define one special property, indicating whether a
+      meta-class inherits the properties of another meta-class. This property
+      is called __metabases__ and it contains a list (a tuple) of the
+      meta-classes the new meta-class inherits from. The meta-classes from
+      which a meta-class is inheriting the properties are called
+      super-meta-classes (in Python, we call them also -- super meta-bases).
+
+      >>> M.__metabases__                # Does M have any supermetaclasses?
+      ()                                 # No.
+      >>> N.__metabases__                # Does N have any supermetaclasses?
+      (<metaclass __main__.M at 2023e360>,)  # Yes. It has a supermetaclass.
+      >>> N.__metabases__[0] == M        # Is it really the meta-class M?
+      1                                  # Yes, it is.
+
+--------
+
+   Triple congratulations on getting this far!
+   Now you know everything about meta-classes and the Real-World!
+
+<unless-wizards-want-meta-classes-be-instances-of-mysterious-objects!>
+
+-- 
+       Vladimir MARANGOZOV          | Vladimir.Marangozov at inrialpes.fr
+http://sirac.inrialpes.fr/~marangoz | tel:(+33-4)76615277 fax:76615252

Added: vendor/Python/current/Demo/newmetaclasses/Eiffel.py
===================================================================
--- vendor/Python/current/Demo/newmetaclasses/Eiffel.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/newmetaclasses/Eiffel.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,141 @@
+"""Support Eiffel-style preconditions and postconditions."""
+
+from new import function
+
+class EiffelBaseMetaClass(type):
+
+    def __new__(meta, name, bases, dict):
+        meta.convert_methods(dict)
+        return super(EiffelBaseMetaClass, meta).__new__(meta, name, bases,
+                                                        dict)
+
+    @classmethod
+    def convert_methods(cls, dict):
+        """Replace functions in dict with EiffelMethod wrappers.
+
+        The dict is modified in place.
+
+        If a method ends in _pre or _post, it is removed from the dict
+        regardless of whether there is a corresponding method.
+        """
+        # find methods with pre or post conditions
+        methods = []
+        for k, v in dict.iteritems():
+            if k.endswith('_pre') or k.endswith('_post'):
+                assert isinstance(v, function)
+            elif isinstance(v, function):
+                methods.append(k)
+        for m in methods:
+            pre = dict.get("%s_pre" % m)
+            post = dict.get("%s_post" % m)
+            if pre or post:
+                dict[k] = cls.make_eiffel_method(dict[m], pre, post)
+
+class EiffelMetaClass1(EiffelBaseMetaClass):
+    # an implementation of the "eiffel" meta class that uses nested functions
+
+    @staticmethod
+    def make_eiffel_method(func, pre, post):
+        def method(self, *args, **kwargs):
+            if pre:
+                pre(self, *args, **kwargs)
+            x = func(self, *args, **kwargs)
+            if post:
+                post(self, x, *args, **kwargs)
+            return x
+
+        if func.__doc__:
+            method.__doc__ = func.__doc__
+
+        return method
+
+class EiffelMethodWrapper:
+
+    def __init__(self, inst, descr):
+        self._inst = inst
+        self._descr = descr
+
+    def __call__(self, *args, **kwargs):
+        return self._descr.callmethod(self._inst, args, kwargs)
+
+class EiffelDescriptor(object):
+
+    def __init__(self, func, pre, post):
+        self._func = func
+        self._pre = pre
+        self._post = post
+
+        self.__name__ = func.__name__
+        self.__doc__ = func.__doc__
+
+    def __get__(self, obj, cls):
+        return EiffelMethodWrapper(obj, self)
+
+    def callmethod(self, inst, args, kwargs):
+        if self._pre:
+            self._pre(inst, *args, **kwargs)
+        x = self._func(inst, *args, **kwargs)
+        if self._post:
+            self._post(inst, x, *args, **kwargs)
+        return x
+
+class EiffelMetaClass2(EiffelBaseMetaClass):
+    # an implementation of the "eiffel" meta class that uses descriptors
+
+    make_eiffel_method = EiffelDescriptor
+
+def _test(metaclass):
+    class Eiffel:
+        __metaclass__ = metaclass
+
+    class Test(Eiffel):
+
+        def m(self, arg):
+            """Make it a little larger"""
+            return arg + 1
+
+        def m2(self, arg):
+            """Make it a little larger"""
+            return arg + 1
+
+        def m2_pre(self, arg):
+            assert arg > 0
+
+        def m2_post(self, result, arg):
+            assert result > arg
+
+    class Sub(Test):
+        def m2(self, arg):
+            return arg**2
+        def m2_post(self, Result, arg):
+            super(Sub, self).m2_post(Result, arg)
+            assert Result < 100
+
+    t = Test()
+    t.m(1)
+    t.m2(1)
+    try:
+        t.m2(0)
+    except AssertionError:
+        pass
+    else:
+        assert False
+
+    s = Sub()
+    try:
+        s.m2(1)
+    except AssertionError:
+        pass # result == arg
+    else:
+        assert False
+    try:
+        s.m2(10)
+    except AssertionError:
+        pass # result ==  100
+    else:
+        assert False
+    s.m2(5)
+
+if __name__ == "__main__":
+    _test(EiffelMetaClass1)
+    _test(EiffelMetaClass2)

Added: vendor/Python/current/Demo/newmetaclasses/Enum.py
===================================================================
--- vendor/Python/current/Demo/newmetaclasses/Enum.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/newmetaclasses/Enum.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,177 @@
+"""Enumeration metaclass."""
+
+class EnumMetaclass(type):
+    """Metaclass for enumeration.
+
+    To define your own enumeration, do something like
+
+    class Color(Enum):
+        red = 1
+        green = 2
+        blue = 3
+
+    Now, Color.red, Color.green and Color.blue behave totally
+    different: they are enumerated values, not integers.
+
+    Enumerations cannot be instantiated; however they can be
+    subclassed.
+    """
+
+    def __init__(cls, name, bases, dict):
+        super(EnumMetaclass, cls).__init__(name, bases, dict)
+        cls._members = []
+        for attr in dict.keys():
+            if not (attr.startswith('__') and attr.endswith('__')):
+                enumval = EnumInstance(name, attr, dict[attr])
+                setattr(cls, attr, enumval)
+                cls._members.append(attr)
+
+    def __getattr__(cls, name):
+        if name == "__members__":
+            return cls._members
+        raise AttributeError, name
+
+    def __repr__(cls):
+        s1 = s2 = ""
+        enumbases = [base.__name__ for base in cls.__bases__
+                     if isinstance(base, EnumMetaclass) and not base is Enum]
+        if enumbases:
+            s1 = "(%s)" % ", ".join(enumbases)
+        enumvalues = ["%s: %d" % (val, getattr(cls, val))
+                      for val in cls._members]
+        if enumvalues:
+            s2 = ": {%s}" % ", ".join(enumvalues)
+        return "%s%s%s" % (cls.__name__, s1, s2)
+
+class FullEnumMetaclass(EnumMetaclass):
+    """Metaclass for full enumerations.
+
+    A full enumeration displays all the values defined in base classes.
+    """
+
+    def __init__(cls, name, bases, dict):
+        super(FullEnumMetaclass, cls).__init__(name, bases, dict)
+        for obj in cls.__mro__:
+            if isinstance(obj, EnumMetaclass):
+                for attr in obj._members:
+                    # XXX inefficient
+                    if not attr in cls._members:
+                        cls._members.append(attr)
+
+class EnumInstance(int):
+    """Class to represent an enumeration value.
+
+    EnumInstance('Color', 'red', 12) prints as 'Color.red' and behaves
+    like the integer 12 when compared, but doesn't support arithmetic.
+
+    XXX Should it record the actual enumeration rather than just its
+    name?
+    """
+
+    def __new__(cls, classname, enumname, value):
+        return int.__new__(cls, value)
+
+    def __init__(self, classname, enumname, value):
+        self.__classname = classname
+        self.__enumname = enumname
+
+    def __repr__(self):
+        return "EnumInstance(%s, %s, %d)" % (self.__classname, self.__enumname,
+                                             self)
+
+    def __str__(self):
+        return "%s.%s" % (self.__classname, self.__enumname)
+
+class Enum:
+    __metaclass__ = EnumMetaclass
+
+class FullEnum:
+    __metaclass__ = FullEnumMetaclass
+
+def _test():
+
+    class Color(Enum):
+        red = 1
+        green = 2
+        blue = 3
+
+    print Color.red
+
+    print repr(Color.red)
+    print Color.red == Color.red
+    print Color.red == Color.blue
+    print Color.red == 1
+    print Color.red == 2
+
+    class ExtendedColor(Color):
+        white = 0
+        orange = 4
+        yellow = 5
+        purple = 6
+        black = 7
+
+    print ExtendedColor.orange
+    print ExtendedColor.red
+
+    print Color.red == ExtendedColor.red
+
+    class OtherColor(Enum):
+        white = 4
+        blue = 5
+
+    class MergedColor(Color, OtherColor):
+        pass
+
+    print MergedColor.red
+    print MergedColor.white
+
+    print Color
+    print ExtendedColor
+    print OtherColor
+    print MergedColor
+
+def _test2():
+
+    class Color(FullEnum):
+        red = 1
+        green = 2
+        blue = 3
+
+    print Color.red
+
+    print repr(Color.red)
+    print Color.red == Color.red
+    print Color.red == Color.blue
+    print Color.red == 1
+    print Color.red == 2
+
+    class ExtendedColor(Color):
+        white = 0
+        orange = 4
+        yellow = 5
+        purple = 6
+        black = 7
+
+    print ExtendedColor.orange
+    print ExtendedColor.red
+
+    print Color.red == ExtendedColor.red
+
+    class OtherColor(FullEnum):
+        white = 4
+        blue = 5
+
+    class MergedColor(Color, OtherColor):
+        pass
+
+    print MergedColor.red
+    print MergedColor.white
+
+    print Color
+    print ExtendedColor
+    print OtherColor
+    print MergedColor
+
+if __name__ == '__main__':
+    _test()
+    _test2()

Added: vendor/Python/current/Demo/parser/FILES
===================================================================
--- vendor/Python/current/Demo/parser/FILES	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/parser/FILES	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,6 @@
+Demo/parser
+Doc/libparser.tex
+Lib/AST.py
+Lib/symbol.py
+Lib/token.py
+Modules/parsermodule.c

Added: vendor/Python/current/Demo/parser/README
===================================================================
--- vendor/Python/current/Demo/parser/README	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/parser/README	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,31 @@
+These files are from the large example of using the `parser' module.  Refer
+to the Python Library Reference for more information.
+
+It also contains examples for the AST parser.
+
+Files:
+------
+
+	FILES	     -- list of files associated with the parser module.
+
+	README	     -- this file.
+
+	example.py   --	module that uses the `parser' module to extract
+			information from the parse tree of Python source
+			code.
+
+	docstring.py -- sample source file containing only a module docstring.
+
+	simple.py    -- sample source containing a "short form" definition.
+
+	source.py    --	sample source code used to demonstrate ability to
+			handle nested constructs easily using the functions
+			and classes in example.py.
+
+	test_parser.py  program to put the parser module through its paces.
+
+	unparse.py	AST (2.5) based example to recreate source code
+			from an AST. This is incomplete; contributions
+			are welcome.
+
+Enjoy!

Added: vendor/Python/current/Demo/parser/docstring.py
===================================================================
--- vendor/Python/current/Demo/parser/docstring.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/parser/docstring.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2 @@
+"""Some documentation.
+"""

Added: vendor/Python/current/Demo/parser/example.py
===================================================================
--- vendor/Python/current/Demo/parser/example.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/parser/example.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,190 @@
+"""Simple code to extract class & function docstrings from a module.
+
+This code is used as an example in the library reference manual in the
+section on using the parser module.  Refer to the manual for a thorough
+discussion of the operation of this code.
+"""
+
+import os
+import parser
+import symbol
+import token
+import types
+
+from types import ListType, TupleType
+
+
+def get_docs(fileName):
+    """Retrieve information from the parse tree of a source file.
+
+    fileName
+        Name of the file to read Python source code from.
+    """
+    source = open(fileName).read()
+    basename = os.path.basename(os.path.splitext(fileName)[0])
+    ast = parser.suite(source)
+    return ModuleInfo(ast.totuple(), basename)
+
+
+class SuiteInfoBase:
+    _docstring = ''
+    _name = ''
+
+    def __init__(self, tree = None):
+        self._class_info = {}
+        self._function_info = {}
+        if tree:
+            self._extract_info(tree)
+
+    def _extract_info(self, tree):
+        # extract docstring
+        if len(tree) == 2:
+            found, vars = match(DOCSTRING_STMT_PATTERN[1], tree[1])
+        else:
+            found, vars = match(DOCSTRING_STMT_PATTERN, tree[3])
+        if found:
+            self._docstring = eval(vars['docstring'])
+        # discover inner definitions
+        for node in tree[1:]:
+            found, vars = match(COMPOUND_STMT_PATTERN, node)
+            if found:
+                cstmt = vars['compound']
+                if cstmt[0] == symbol.funcdef:
+                    name = cstmt[2][1]
+                    self._function_info[name] = FunctionInfo(cstmt)
+                elif cstmt[0] == symbol.classdef:
+                    name = cstmt[2][1]
+                    self._class_info[name] = ClassInfo(cstmt)
+
+    def get_docstring(self):
+        return self._docstring
+
+    def get_name(self):
+        return self._name
+
+    def get_class_names(self):
+        return self._class_info.keys()
+
+    def get_class_info(self, name):
+        return self._class_info[name]
+
+    def __getitem__(self, name):
+        try:
+            return self._class_info[name]
+        except KeyError:
+            return self._function_info[name]
+
+
+class SuiteFuncInfo:
+    #  Mixin class providing access to function names and info.
+
+    def get_function_names(self):
+        return self._function_info.keys()
+
+    def get_function_info(self, name):
+        return self._function_info[name]
+
+
+class FunctionInfo(SuiteInfoBase, SuiteFuncInfo):
+    def __init__(self, tree = None):
+        self._name = tree[2][1]
+        SuiteInfoBase.__init__(self, tree and tree[-1] or None)
+
+
+class ClassInfo(SuiteInfoBase):
+    def __init__(self, tree = None):
+        self._name = tree[2][1]
+        SuiteInfoBase.__init__(self, tree and tree[-1] or None)
+
+    def get_method_names(self):
+        return self._function_info.keys()
+
+    def get_method_info(self, name):
+        return self._function_info[name]
+
+
+class ModuleInfo(SuiteInfoBase, SuiteFuncInfo):
+    def __init__(self, tree = None, name = "<string>"):
+        self._name = name
+        SuiteInfoBase.__init__(self, tree)
+        if tree:
+            found, vars = match(DOCSTRING_STMT_PATTERN, tree[1])
+            if found:
+                self._docstring = vars["docstring"]
+
+
+def match(pattern, data, vars=None):
+    """Match `data' to `pattern', with variable extraction.
+
+    pattern
+        Pattern to match against, possibly containing variables.
+
+    data
+        Data to be checked and against which variables are extracted.
+
+    vars
+        Dictionary of variables which have already been found.  If not
+        provided, an empty dictionary is created.
+
+    The `pattern' value may contain variables of the form ['varname'] which
+    are allowed to match anything.  The value that is matched is returned as
+    part of a dictionary which maps 'varname' to the matched value.  'varname'
+    is not required to be a string object, but using strings makes patterns
+    and the code which uses them more readable.
+
+    This function returns two values: a boolean indicating whether a match
+    was found and a dictionary mapping variable names to their associated
+    values.
+    """
+    if vars is None:
+        vars = {}
+    if type(pattern) is ListType:       # 'variables' are ['varname']
+        vars[pattern[0]] = data
+        return 1, vars
+    if type(pattern) is not TupleType:
+        return (pattern == data), vars
+    if len(data) != len(pattern):
+        return 0, vars
+    for pattern, data in map(None, pattern, data):
+        same, vars = match(pattern, data, vars)
+        if not same:
+            break
+    return same, vars
+
+
+#  This pattern identifies compound statements, allowing them to be readily
+#  differentiated from simple statements.
+#
+COMPOUND_STMT_PATTERN = (
+    symbol.stmt,
+    (symbol.compound_stmt, ['compound'])
+    )
+
+
+#  This pattern will match a 'stmt' node which *might* represent a docstring;
+#  docstrings require that the statement which provides the docstring be the
+#  first statement in the class or function, which this pattern does not check.
+#
+DOCSTRING_STMT_PATTERN = (
+    symbol.stmt,
+    (symbol.simple_stmt,
+     (symbol.small_stmt,
+      (symbol.expr_stmt,
+       (symbol.testlist,
+        (symbol.test,
+         (symbol.and_test,
+          (symbol.not_test,
+           (symbol.comparison,
+            (symbol.expr,
+             (symbol.xor_expr,
+              (symbol.and_expr,
+               (symbol.shift_expr,
+                (symbol.arith_expr,
+                 (symbol.term,
+                  (symbol.factor,
+                   (symbol.power,
+                    (symbol.atom,
+                     (token.STRING, ['docstring'])
+                     )))))))))))))))),
+     (token.NEWLINE, '')
+     ))

Added: vendor/Python/current/Demo/parser/simple.py
===================================================================
--- vendor/Python/current/Demo/parser/simple.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/parser/simple.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1 @@
+def f(): "maybe a docstring"

Added: vendor/Python/current/Demo/parser/source.py
===================================================================
--- vendor/Python/current/Demo/parser/source.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/parser/source.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,27 @@
+"""Exmaple file to be parsed for the parsermodule example.
+
+The classes and functions in this module exist only to exhibit the ability
+of the handling information extraction from nested definitions using parse
+trees.  They shouldn't interest you otherwise!
+"""
+
+class Simple:
+    "This class does very little."
+
+    def method(self):
+        "This method does almost nothing."
+        return 1
+
+    class Nested:
+        "This is a nested class."
+
+        def nested_method(self):
+            "Method of Nested class."
+            def nested_function():
+                "Function in method of Nested class."
+                pass
+            return nested_function
+
+def function():
+    "This function lives at the module level."
+    return 0

Added: vendor/Python/current/Demo/parser/test_parser.py
===================================================================
--- vendor/Python/current/Demo/parser/test_parser.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/parser/test_parser.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,48 @@
+#! /usr/bin/env python
+#  (Force the script to use the latest build.)
+#
+#  test_parser.py
+
+import parser, traceback
+
+_numFailed = 0
+
+def testChunk(t, fileName):
+    global _numFailed
+    print '----', fileName,
+    try:
+        ast = parser.suite(t)
+        tup = parser.ast2tuple(ast)
+        # this discards the first AST; a huge memory savings when running
+        # against a large source file like Tkinter.py.
+        ast = None
+        new = parser.tuple2ast(tup)
+    except parser.ParserError, err:
+        print
+        print 'parser module raised exception on input file', fileName + ':'
+        traceback.print_exc()
+        _numFailed = _numFailed + 1
+    else:
+        if tup != parser.ast2tuple(new):
+            print
+            print 'parser module failed on input file', fileName
+            _numFailed = _numFailed + 1
+        else:
+            print 'o.k.'
+
+def testFile(fileName):
+    t = open(fileName).read()
+    testChunk(t, fileName)
+
+def test():
+    import sys
+    args = sys.argv[1:]
+    if not args:
+        import glob
+        args = glob.glob("*.py")
+        args.sort()
+    map(testFile, args)
+    sys.exit(_numFailed != 0)
+
+if __name__ == '__main__':
+    test()


Property changes on: vendor/Python/current/Demo/parser/test_parser.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/parser/texipre.dat
===================================================================
--- vendor/Python/current/Demo/parser/texipre.dat	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/parser/texipre.dat	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,100 @@
+\input texinfo   @c -*-texinfo-*-
+ at c %**start of header
+ at setfilename parser.info
+ at settitle Python Parser Module Reference
+ at setchapternewpage odd
+ at footnotestyle end
+ at c %**end of header
+
+ at ifinfo
+This file describes the interfaces
+published by the optional @code{parser} module and gives examples of
+how they may be used.  It contains the same text as the chapter on the
+ at code{parser} module in the @cite{Python Library Reference}, but is
+presented as a separate document.
+
+Copyright 1995-1996 by Fred L. Drake, Jr., Reston, Virginia, USA, and
+Virginia Polytechnic Institute and State University, Blacksburg,
+Virginia, USA.  Portions of the software copyright 1991-1995 by
+Stichting Mathematisch Centrum, Amsterdam, The Netherlands.  Copying is
+permitted under the terms associated with the main Python distribution,
+with the additional restriction that this additional notice be included
+and maintained on all distributed copies.
+
+                        All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the names of Fred L. Drake, Jr. and
+Virginia Polytechnic Institute and State University not be used in
+advertising or publicity pertaining to distribution of the software
+without specific, written prior permission.
+
+FRED L. DRAKE, JR. AND VIRGINIA POLYTECHNIC INSTITUTE AND STATE
+UNIVERSITY DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+EVENT SHALL FRED L. DRAKE, JR. OR VIRGINIA POLYTECHNIC INSTITUTE AND
+STATE UNIVERSITY BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+ at end ifinfo
+
+ at titlepage
+ at title Python Parser Module Reference
+ at author Fred L. Drake, Jr.
+
+ at c  The following two commands start the copyright page.
+ at page
+ at vskip 0pt plus 1filll
+Copyright 1995-1996 by Fred L. Drake, Jr., Reston, Virginia, USA, and
+Virginia Polytechnic Institute and State University, Blacksburg,
+Virginia, USA.  Portions of the software copyright 1991-1995 by
+Stichting Mathematisch Centrum, Amsterdam, The Netherlands.  Copying is
+permitted under the terms associated with the main Python distribution,
+with the additional restriction that this additional notice be included
+and maintained on all distributed copies.
+
+ at center All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the names of Fred L. Drake, Jr. and
+Virginia Polytechnic Institute and State University not be used in
+advertising or publicity pertaining to distribution of the software
+without specific, written prior permission.
+
+FRED L. DRAKE, JR. AND VIRGINIA POLYTECHNIC INSTITUTE AND STATE
+UNIVERSITY DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+EVENT SHALL FRED L. DRAKE, JR. OR VIRGINIA POLYTECHNIC INSTITUTE AND
+STATE UNIVERSITY BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+ at end titlepage
+
+
+ at node Top, Overview, (dir), (dir)
+ at top The Python Parser Module
+
+ at ifinfo
+This file describes the interfaces
+published by the optional @code{parser} module and gives examples of
+how they may be used.  It contains the same text as the chapter on the
+ at code{parser} module in the @cite{Python Library Reference}, but is
+presented as a separate document.
+
+This version corresponds to Python version 1.4 (1 Sept. 1996).
+
+ at end ifinfo
+
+ at c placeholder for the master menu -- patched by texinfo-all-menus-update
+ at menu
+ at end menu

Added: vendor/Python/current/Demo/parser/unparse.py
===================================================================
--- vendor/Python/current/Demo/parser/unparse.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/parser/unparse.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,519 @@
+"Usage: unparse.py <path to source file>"
+import sys
+import _ast
+import cStringIO
+import os
+
+class Unparser:
+    """Methods in this class recursively traverse an AST and
+    output source code for the abstract syntax; original formatting
+    is disregarged. """
+
+    def __init__(self, tree, file = sys.stdout):
+        """Unparser(tree, file=sys.stdout) -> None.
+         Print the source for tree to file."""
+        self.f = file
+        self._indent = 0
+        self.dispatch(tree)
+        print >>self.f,""
+        self.f.flush()
+
+    def fill(self, text = ""):
+        "Indent a piece of text, according to the current indentation level"
+        self.f.write("\n"+"    "*self._indent + text)
+
+    def write(self, text):
+        "Append a piece of text to the current line."
+        self.f.write(text)
+
+    def enter(self):
+        "Print ':', and increase the indentation."
+        self.write(":")
+        self._indent += 1
+
+    def leave(self):
+        "Decrease the indentation level."
+        self._indent -= 1
+
+    def dispatch(self, tree):
+        "Dispatcher function, dispatching tree type T to method _T."
+        if isinstance(tree, list):
+            for t in tree:
+                self.dispatch(t)
+            return
+        meth = getattr(self, "_"+tree.__class__.__name__)
+        meth(tree)
+
+
+    ############### Unparsing methods ######################
+    # There should be one method per concrete grammar type #
+    # Constructors should be grouped by sum type. Ideally, #
+    # this would follow the order in the grammar, but      #
+    # currently doesn't.                                   #
+    ########################################################
+
+    def _Module(self, tree):
+        for stmt in tree.body:
+            self.dispatch(stmt)
+
+    # stmt
+    def _Expr(self, tree):
+        self.fill()
+        self.dispatch(tree.value)
+
+    def _Import(self, t):
+        self.fill("import ")
+        first = True
+        for a in t.names:
+            if first:
+                first = False
+            else:
+                self.write(", ")
+            self.write(a.name)
+            if a.asname:
+                self.write(" as "+a.asname)
+
+    def _ImportFrom(self, t):
+        self.fill("from ")
+        self.write(t.module)
+        self.write(" import ")
+        for i, a in enumerate(t.names):
+            if i == 0:
+                self.write(", ")
+            self.write(a.name)
+            if a.asname:
+                self.write(" as "+a.asname)
+        # XXX(jpe) what is level for?
+
+    def _Assign(self, t):
+        self.fill()
+        for target in t.targets:
+            self.dispatch(target)
+            self.write(" = ")
+        self.dispatch(t.value)
+
+    def _AugAssign(self, t):
+        self.fill()
+        self.dispatch(t.target)
+        self.write(" "+self.binop[t.op.__class__.__name__]+"= ")
+        self.dispatch(t.value)
+
+    def _Return(self, t):
+        self.fill("return ")
+        if t.value:
+            self.dispatch(t.value)
+
+    def _Pass(self, t):
+        self.fill("pass")
+
+    def _Break(self, t):
+        self.fill("break")
+
+    def _Continue(self, t):
+        self.fill("continue")
+
+    def _Delete(self, t):
+        self.fill("del ")
+        self.dispatch(t.targets)
+
+    def _Assert(self, t):
+        self.fill("assert ")
+        self.dispatch(t.test)
+        if t.msg:
+            self.write(", ")
+            self.dispatch(t.msg)
+
+    def _Exec(self, t):
+        self.fill("exec ")
+        self.dispatch(t.body)
+        if t.globals:
+            self.write(" in ")
+            self.dispatch(t.globals)
+        if t.locals:
+            self.write(", ")
+            self.dispatch(t.locals)
+
+    def _Print(self, t):
+        self.fill("print ")
+        do_comma = False
+        if t.dest:
+            self.write(">>")
+            self.dispatch(t.dest)
+            do_comma = True
+        for e in t.values:
+            if do_comma:self.write(", ")
+            else:do_comma=True
+            self.dispatch(e)
+        if not t.nl:
+            self.write(",")
+
+    def _Global(self, t):
+        self.fill("global")
+        for i, n in enumerate(t.names):
+            if i != 0:
+                self.write(",")
+            self.write(" " + n)
+
+    def _Yield(self, t):
+        self.fill("yield")
+        if t.value:
+            self.write(" (")
+            self.dispatch(t.value)
+            self.write(")")
+
+    def _Raise(self, t):
+        self.fill('raise ')
+        if t.type:
+            self.dispatch(t.type)
+        if t.inst:
+            self.write(", ")
+            self.dispatch(t.inst)
+        if t.tback:
+            self.write(", ")
+            self.dispatch(t.tback)
+
+    def _TryExcept(self, t):
+        self.fill("try")
+        self.enter()
+        self.dispatch(t.body)
+        self.leave()
+
+        for ex in t.handlers:
+            self.dispatch(ex)
+        if t.orelse:
+            self.fill("else")
+            self.enter()
+            self.dispatch(t.orelse)
+            self.leave()
+
+    def _TryFinally(self, t):
+        self.fill("try")
+        self.enter()
+        self.dispatch(t.body)
+        self.leave()
+
+        self.fill("finally")
+        self.enter()
+        self.dispatch(t.finalbody)
+        self.leave()
+
+    def _excepthandler(self, t):
+        self.fill("except ")
+        if t.type:
+            self.dispatch(t.type)
+        if t.name:
+            self.write(", ")
+            self.dispatch(t.name)
+        self.enter()
+        self.dispatch(t.body)
+        self.leave()
+
+    def _ClassDef(self, t):
+        self.write("\n")
+        self.fill("class "+t.name)
+        if t.bases:
+            self.write("(")
+            for a in t.bases:
+                self.dispatch(a)
+                self.write(", ")
+            self.write(")")
+        self.enter()
+        self.dispatch(t.body)
+        self.leave()
+
+    def _FunctionDef(self, t):
+        self.write("\n")
+        for deco in t.decorators:
+            self.fill("@")
+            self.dispatch(deco)
+        self.fill("def "+t.name + "(")
+        self.dispatch(t.args)
+        self.write(")")
+        self.enter()
+        self.dispatch(t.body)
+        self.leave()
+
+    def _For(self, t):
+        self.fill("for ")
+        self.dispatch(t.target)
+        self.write(" in ")
+        self.dispatch(t.iter)
+        self.enter()
+        self.dispatch(t.body)
+        self.leave()
+        if t.orelse:
+            self.fill("else")
+            self.enter()
+            self.dispatch(t.orelse)
+            self.leave
+
+    def _If(self, t):
+        self.fill("if ")
+        self.dispatch(t.test)
+        self.enter()
+        # XXX elif?
+        self.dispatch(t.body)
+        self.leave()
+        if t.orelse:
+            self.fill("else")
+            self.enter()
+            self.dispatch(t.orelse)
+            self.leave()
+
+    def _While(self, t):
+        self.fill("while ")
+        self.dispatch(t.test)
+        self.enter()
+        self.dispatch(t.body)
+        self.leave()
+        if t.orelse:
+            self.fill("else")
+            self.enter()
+            self.dispatch(t.orelse)
+            self.leave
+
+    def _With(self, t):
+        self.fill("with ")
+        self.dispatch(t.context_expr)
+        if t.optional_vars:
+            self.write(" as ")
+            self.dispatch(t.optional_vars)
+        self.enter()
+        self.dispatch(t.body)
+        self.leave()
+
+    # expr
+    def _Str(self, tree):
+        self.write(repr(tree.s))
+
+    def _Name(self, t):
+        self.write(t.id)
+
+    def _Repr(self, t):
+        self.write("`")
+        self.dispatch(t.value)
+        self.write("`")
+
+    def _Num(self, t):
+        self.write(repr(t.n))
+
+    def _List(self, t):
+        self.write("[")
+        for e in t.elts:
+            self.dispatch(e)
+            self.write(", ")
+        self.write("]")
+
+    def _ListComp(self, t):
+        self.write("[")
+        self.dispatch(t.elt)
+        for gen in t.generators:
+            self.dispatch(gen)
+        self.write("]")
+
+    def _GeneratorExp(self, t):
+        self.write("(")
+        self.dispatch(t.elt)
+        for gen in t.generators:
+            self.dispatch(gen)
+        self.write(")")
+
+    def _comprehension(self, t):
+        self.write(" for ")
+        self.dispatch(t.target)
+        self.write(" in ")
+        self.dispatch(t.iter)
+        for if_clause in t.ifs:
+            self.write(" if ")
+            self.dispatch(if_clause)
+
+    def _IfExp(self, t):
+        self.dispatch(t.body)
+        self.write(" if ")
+        self.dispatch(t.test)
+        if t.orelse:
+            self.write(" else ")
+            self.dispatch(t.orelse)
+
+    def _Dict(self, t):
+        self.write("{")
+        for k,v in zip(t.keys, t.values):
+            self.dispatch(k)
+            self.write(" : ")
+            self.dispatch(v)
+            self.write(", ")
+        self.write("}")
+
+    def _Tuple(self, t):
+        if not t.elts:
+            self.write("()")
+            return
+        self.write("(")
+        for e in t.elts:
+            self.dispatch(e)
+            self.write(", ")
+        self.write(")")
+
+    unop = {"Invert":"~", "Not": "not", "UAdd":"+", "USub":"-"}
+    def _UnaryOp(self, t):
+        self.write(self.unop[t.op.__class__.__name__])
+        self.write("(")
+        self.dispatch(t.operand)
+        self.write(")")
+
+    binop = { "Add":"+", "Sub":"-", "Mult":"*", "Div":"/", "Mod":"%",
+                    "LShift":">>", "RShift":"<<", "BitOr":"|", "BitXor":"^", "BitAnd":"&",
+                    "FloorDiv":"//", "Pow": "**"}
+    def _BinOp(self, t):
+        self.write("(")
+        self.dispatch(t.left)
+        self.write(")" + self.binop[t.op.__class__.__name__] + "(")
+        self.dispatch(t.right)
+        self.write(")")
+
+    cmpops = {"Eq":"==", "NotEq":"!=", "Lt":"<", "LtE":"<=", "Gt":">", "GtE":">=",
+                        "Is":"is", "IsNot":"is not", "In":"in", "NotIn":"not in"}
+    def _Compare(self, t):
+        self.write("(")
+        self.dispatch(t.left)
+        for o, e in zip(t.ops, t.comparators):
+            self.write(") " +self.cmpops[o.__class__.__name__] + " (")
+            self.dispatch(e)
+            self.write(")")
+
+    boolops = {_ast.And: 'and', _ast.Or: 'or'}
+    def _BoolOp(self, t):
+        self.write("(")
+        self.dispatch(t.values[0])
+        for v in t.values[1:]:
+            self.write(" %s " % self.boolops[t.op.__class__])
+            self.dispatch(v)
+        self.write(")")
+
+    def _Attribute(self,t):
+        self.dispatch(t.value)
+        self.write(".")
+        self.write(t.attr)
+
+    def _Call(self, t):
+        self.dispatch(t.func)
+        self.write("(")
+        comma = False
+        for e in t.args:
+            if comma: self.write(", ")
+            else: comma = True
+            self.dispatch(e)
+        for e in t.keywords:
+            if comma: self.write(", ")
+            else: comma = True
+            self.dispatch(e)
+        if t.starargs:
+            if comma: self.write(", ")
+            else: comma = True
+            self.write("*")
+            self.dispatch(t.starargs)
+        if t.kwargs:
+            if comma: self.write(", ")
+            else: comma = True
+            self.write("**")
+            self.dispatch(t.kwargs)
+        self.write(")")
+
+    def _Subscript(self, t):
+        self.dispatch(t.value)
+        self.write("[")
+        self.dispatch(t.slice)
+        self.write("]")
+
+    # slice
+    def _Ellipsis(self, t):
+        self.write("...")
+
+    def _Index(self, t):
+        self.dispatch(t.value)
+
+    def _Slice(self, t):
+        if t.lower:
+            self.dispatch(t.lower)
+        self.write(":")
+        if t.upper:
+            self.dispatch(t.upper)
+        if t.step:
+            self.write(":")
+            self.dispatch(t.step)
+
+    def _ExtSlice(self, t):
+        for i, d in enumerate(t.dims):
+            if i != 0:
+                self.write(': ')
+            self.dispatch(d)
+
+    # others
+    def _arguments(self, t):
+        first = True
+        nonDef = len(t.args)-len(t.defaults)
+        for a in t.args[0:nonDef]:
+            if first:first = False
+            else: self.write(", ")
+            self.dispatch(a)
+        for a,d in zip(t.args[nonDef:], t.defaults):
+            if first:first = False
+            else: self.write(", ")
+            self.dispatch(a),
+            self.write("=")
+            self.dispatch(d)
+        if t.vararg:
+            if first:first = False
+            else: self.write(", ")
+            self.write("*"+t.vararg)
+        if t.kwarg:
+            if first:first = False
+            else: self.write(", ")
+            self.write("**"+t.kwarg)
+
+    def _keyword(self, t):
+        self.write(t.arg)
+        self.write("=")
+        self.dispatch(t.value)
+
+    def _Lambda(self, t):
+        self.write("lambda ")
+        self.dispatch(t.args)
+        self.write(": ")
+        self.dispatch(t.body)
+
+def roundtrip(filename, output=sys.stdout):
+    source = open(filename).read()
+    tree = compile(source, filename, "exec", 0x400)
+    Unparser(tree, output)
+
+
+
+def testdir(a):
+    try:
+        names = [n for n in os.listdir(a) if n.endswith('.py')]
+    except OSError:
+        print >> sys.stderr, "Directory not readable: %s" % a
+    else:
+        for n in names:
+            fullname = os.path.join(a, n)
+            if os.path.isfile(fullname):
+                output = cStringIO.StringIO()
+                print 'Testing %s' % fullname
+                try:
+                    roundtrip(fullname, output)
+                except Exception, e:
+                    print '  Failed to compile, exception is %s' % repr(e)
+            elif os.path.isdir(fullname):
+                testdir(fullname)
+
+def main(args):
+    if args[0] == '--testdir':
+        for a in args[1:]:
+            testdir(a)
+    else:
+        for a in args:
+            roundtrip(a)
+
+if __name__=='__main__':
+    main(sys.argv[1:])

Added: vendor/Python/current/Demo/pdist/FSProxy.py
===================================================================
--- vendor/Python/current/Demo/pdist/FSProxy.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/pdist/FSProxy.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,322 @@
+"""File System Proxy.
+
+Provide an OS-neutral view on a file system, locally or remotely.
+The functionality is geared towards implementing some sort of
+rdist-like utility between a Mac and a UNIX system.
+
+The module defines three classes:
+
+FSProxyLocal  -- used for local access
+FSProxyServer -- used on the server side of remote access
+FSProxyClient -- used on the client side of remote access
+
+The remote classes are instantiated with an IP address and an optional
+verbosity flag.
+"""
+
+import server
+import client
+import md5
+import os
+import fnmatch
+from stat import *
+import time
+import fnmatch
+
+if os.name == 'mac':
+    import macfs
+    maxnamelen = 31
+else:
+    macfs = None
+    maxnamelen = 255
+
+skipnames = (os.curdir, os.pardir)
+
+
+class FSProxyLocal:
+
+    def __init__(self):
+        self._dirstack = []
+        self._ignore = ['*.pyc'] + self._readignore()
+
+    def _close(self):
+        while self._dirstack:
+            self.back()
+
+    def _readignore(self):
+        file = self._hide('ignore')
+        try:
+            f = open(file)
+        except IOError:
+            file = self._hide('synctree.ignorefiles')
+            try:
+                f = open(file)
+            except IOError:
+                return []
+        ignore = []
+        while 1:
+            line = f.readline()
+            if not line: break
+            if line[-1] == '\n': line = line[:-1]
+            ignore.append(line)
+        f.close()
+        return ignore
+
+    def _hidden(self, name):
+        if os.name == 'mac':
+            return name[0] == '(' and name[-1] == ')'
+        else:
+            return name[0] == '.'
+
+    def _hide(self, name):
+        if os.name == 'mac':
+            return '(%s)' % name
+        else:
+            return '.%s' % name
+
+    def visible(self, name):
+        if len(name) > maxnamelen: return 0
+        if name[-1] == '~': return 0
+        if name in skipnames: return 0
+        if self._hidden(name): return 0
+        head, tail = os.path.split(name)
+        if head or not tail: return 0
+        if macfs:
+            if os.path.exists(name) and not os.path.isdir(name):
+                try:
+                    fs = macfs.FSSpec(name)
+                    c, t = fs.GetCreatorType()
+                    if t != 'TEXT': return 0
+                except macfs.error, msg:
+                    print "***", name, msg
+                    return 0
+        else:
+            if os.path.islink(name): return 0
+            if '\0' in open(name, 'rb').read(512): return 0
+        for ign in self._ignore:
+            if fnmatch.fnmatch(name, ign): return 0
+        return 1
+
+    def check(self, name):
+        if not self.visible(name):
+            raise os.error, "protected name %s" % repr(name)
+
+    def checkfile(self, name):
+        self.check(name)
+        if not os.path.isfile(name):
+            raise os.error, "not a plain file %s" % repr(name)
+
+    def pwd(self):
+        return os.getcwd()
+
+    def cd(self, name):
+        self.check(name)
+        save = os.getcwd(), self._ignore
+        os.chdir(name)
+        self._dirstack.append(save)
+        self._ignore = self._ignore + self._readignore()
+
+    def back(self):
+        if not self._dirstack:
+            raise os.error, "empty directory stack"
+        dir, ignore = self._dirstack[-1]
+        os.chdir(dir)
+        del self._dirstack[-1]
+        self._ignore = ignore
+
+    def _filter(self, files, pat = None):
+        if pat:
+            def keep(name, pat = pat):
+                return fnmatch.fnmatch(name, pat)
+            files = filter(keep, files)
+        files = filter(self.visible, files)
+        files.sort()
+        return files
+
+    def list(self, pat = None):
+        files = os.listdir(os.curdir)
+        return self._filter(files, pat)
+
+    def listfiles(self, pat = None):
+        files = os.listdir(os.curdir)
+        files = filter(os.path.isfile, files)
+        return self._filter(files, pat)
+
+    def listsubdirs(self, pat = None):
+        files = os.listdir(os.curdir)
+        files = filter(os.path.isdir, files)
+        return self._filter(files, pat)
+
+    def exists(self, name):
+        return self.visible(name) and os.path.exists(name)
+
+    def isdir(self, name):
+        return self.visible(name) and os.path.isdir(name)
+
+    def islink(self, name):
+        return self.visible(name) and os.path.islink(name)
+
+    def isfile(self, name):
+        return self.visible(name) and os.path.isfile(name)
+
+    def sum(self, name):
+        self.checkfile(name)
+        BUFFERSIZE = 1024*8
+        f = open(name)
+        sum = md5.new()
+        while 1:
+            buffer = f.read(BUFFERSIZE)
+            if not buffer:
+                break
+            sum.update(buffer)
+        return sum.digest()
+
+    def size(self, name):
+        self.checkfile(name)
+        return os.stat(name)[ST_SIZE]
+
+    def mtime(self, name):
+        self.checkfile(name)
+        return time.localtime(os.stat(name)[ST_MTIME])
+
+    def stat(self, name):
+        self.checkfile(name)
+        size = os.stat(name)[ST_SIZE]
+        mtime = time.localtime(os.stat(name)[ST_MTIME])
+        return size, mtime
+
+    def info(self, name):
+        sum = self.sum(name)
+        size = os.stat(name)[ST_SIZE]
+        mtime = time.localtime(os.stat(name)[ST_MTIME])
+        return sum, size, mtime
+
+    def _list(self, function, list):
+        if list is None:
+            list = self.listfiles()
+        res = []
+        for name in list:
+            try:
+                res.append((name, function(name)))
+            except (os.error, IOError):
+                res.append((name, None))
+        return res
+
+    def sumlist(self, list = None):
+        return self._list(self.sum, list)
+
+    def statlist(self, list = None):
+        return self._list(self.stat, list)
+
+    def mtimelist(self, list = None):
+        return self._list(self.mtime, list)
+
+    def sizelist(self, list = None):
+        return self._list(self.size, list)
+
+    def infolist(self, list = None):
+        return self._list(self.info, list)
+
+    def _dict(self, function, list):
+        if list is None:
+            list = self.listfiles()
+        dict = {}
+        for name in list:
+            try:
+                dict[name] = function(name)
+            except (os.error, IOError):
+                pass
+        return dict
+
+    def sumdict(self, list = None):
+        return self.dict(self.sum, list)
+
+    def sizedict(self, list = None):
+        return self.dict(self.size, list)
+
+    def mtimedict(self, list = None):
+        return self.dict(self.mtime, list)
+
+    def statdict(self, list = None):
+        return self.dict(self.stat, list)
+
+    def infodict(self, list = None):
+        return self._dict(self.info, list)
+
+    def read(self, name, offset = 0, length = -1):
+        self.checkfile(name)
+        f = open(name)
+        f.seek(offset)
+        if length == 0:
+            data = ''
+        elif length < 0:
+            data = f.read()
+        else:
+            data = f.read(length)
+        f.close()
+        return data
+
+    def create(self, name):
+        self.check(name)
+        if os.path.exists(name):
+            self.checkfile(name)
+            bname = name + '~'
+            try:
+                os.unlink(bname)
+            except os.error:
+                pass
+            os.rename(name, bname)
+        f = open(name, 'w')
+        f.close()
+
+    def write(self, name, data, offset = 0):
+        self.checkfile(name)
+        f = open(name, 'r+')
+        f.seek(offset)
+        f.write(data)
+        f.close()
+
+    def mkdir(self, name):
+        self.check(name)
+        os.mkdir(name, 0777)
+
+    def rmdir(self, name):
+        self.check(name)
+        os.rmdir(name)
+
+
+class FSProxyServer(FSProxyLocal, server.Server):
+
+    def __init__(self, address, verbose = server.VERBOSE):
+        FSProxyLocal.__init__(self)
+        server.Server.__init__(self, address, verbose)
+
+    def _close(self):
+        server.Server._close(self)
+        FSProxyLocal._close(self)
+
+    def _serve(self):
+        server.Server._serve(self)
+        # Retreat into start directory
+        while self._dirstack: self.back()
+
+
+class FSProxyClient(client.Client):
+
+    def __init__(self, address, verbose = client.VERBOSE):
+        client.Client.__init__(self, address, verbose)
+
+
+def test():
+    import string
+    import sys
+    if sys.argv[1:]:
+        port = string.atoi(sys.argv[1])
+    else:
+        port = 4127
+    proxy = FSProxyServer(('', port))
+    proxy._serverloop()
+
+
+if __name__ == '__main__':
+    test()


Property changes on: vendor/Python/current/Demo/pdist/FSProxy.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/pdist/RCSProxy.py
===================================================================
--- vendor/Python/current/Demo/pdist/RCSProxy.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/pdist/RCSProxy.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,198 @@
+#! /usr/bin/env python
+
+"""RCS Proxy.
+
+Provide a simplified interface on RCS files, locally or remotely.
+The functionality is geared towards implementing some sort of
+remote CVS like utility.  It is modeled after the similar module
+FSProxy.
+
+The module defines two classes:
+
+RCSProxyLocal  -- used for local access
+RCSProxyServer -- used on the server side of remote access
+
+The corresponding client class, RCSProxyClient, is defined in module
+rcsclient.
+
+The remote classes are instantiated with an IP address and an optional
+verbosity flag.
+"""
+
+import server
+import md5
+import os
+import fnmatch
+import string
+import tempfile
+import rcslib
+
+
+class DirSupport:
+
+    def __init__(self):
+        self._dirstack = []
+
+    def __del__(self):
+        self._close()
+
+    def _close(self):
+        while self._dirstack:
+            self.back()
+
+    def pwd(self):
+        return os.getcwd()
+
+    def cd(self, name):
+        save = os.getcwd()
+        os.chdir(name)
+        self._dirstack.append(save)
+
+    def back(self):
+        if not self._dirstack:
+            raise os.error, "empty directory stack"
+        dir = self._dirstack[-1]
+        os.chdir(dir)
+        del self._dirstack[-1]
+
+    def listsubdirs(self, pat = None):
+        files = os.listdir(os.curdir)
+        files = filter(os.path.isdir, files)
+        return self._filter(files, pat)
+
+    def isdir(self, name):
+        return os.path.isdir(name)
+
+    def mkdir(self, name):
+        os.mkdir(name, 0777)
+
+    def rmdir(self, name):
+        os.rmdir(name)
+
+
+class RCSProxyLocal(rcslib.RCS, DirSupport):
+
+    def __init__(self):
+        rcslib.RCS.__init__(self)
+        DirSupport.__init__(self)
+
+    def __del__(self):
+        DirSupport.__del__(self)
+        rcslib.RCS.__del__(self)
+
+    def sumlist(self, list = None):
+        return self._list(self.sum, list)
+
+    def sumdict(self, list = None):
+        return self._dict(self.sum, list)
+
+    def sum(self, name_rev):
+        f = self._open(name_rev)
+        BUFFERSIZE = 1024*8
+        sum = md5.new()
+        while 1:
+            buffer = f.read(BUFFERSIZE)
+            if not buffer:
+                break
+            sum.update(buffer)
+        self._closepipe(f)
+        return sum.digest()
+
+    def get(self, name_rev):
+        f = self._open(name_rev)
+        data = f.read()
+        self._closepipe(f)
+        return data
+
+    def put(self, name_rev, data, message=None):
+        name, rev = self._unmangle(name_rev)
+        f = open(name, 'w')
+        f.write(data)
+        f.close()
+        self.checkin(name_rev, message)
+        self._remove(name)
+
+    def _list(self, function, list = None):
+        """INTERNAL: apply FUNCTION to all files in LIST.
+
+        Return a list of the results.
+
+        The list defaults to all files in the directory if None.
+
+        """
+        if list is None:
+            list = self.listfiles()
+        res = []
+        for name in list:
+            try:
+                res.append((name, function(name)))
+            except (os.error, IOError):
+                res.append((name, None))
+        return res
+
+    def _dict(self, function, list = None):
+        """INTERNAL: apply FUNCTION to all files in LIST.
+
+        Return a dictionary mapping files to results.
+
+        The list defaults to all files in the directory if None.
+
+        """
+        if list is None:
+            list = self.listfiles()
+        dict = {}
+        for name in list:
+            try:
+                dict[name] = function(name)
+            except (os.error, IOError):
+                pass
+        return dict
+
+
+class RCSProxyServer(RCSProxyLocal, server.SecureServer):
+
+    def __init__(self, address, verbose = server.VERBOSE):
+        RCSProxyLocal.__init__(self)
+        server.SecureServer.__init__(self, address, verbose)
+
+    def _close(self):
+        server.SecureServer._close(self)
+        RCSProxyLocal._close(self)
+
+    def _serve(self):
+        server.SecureServer._serve(self)
+        # Retreat into start directory
+        while self._dirstack: self.back()
+
+
+def test_server():
+    import string
+    import sys
+    if sys.argv[1:]:
+        port = string.atoi(sys.argv[1])
+    else:
+        port = 4127
+    proxy = RCSProxyServer(('', port))
+    proxy._serverloop()
+
+
+def test():
+    import sys
+    if not sys.argv[1:] or sys.argv[1] and sys.argv[1][0] in '0123456789':
+        test_server()
+        sys.exit(0)
+    proxy = RCSProxyLocal()
+    what = sys.argv[1]
+    if hasattr(proxy, what):
+        attr = getattr(proxy, what)
+        if callable(attr):
+            print apply(attr, tuple(sys.argv[2:]))
+        else:
+            print repr(attr)
+    else:
+        print "%s: no such attribute" % what
+        sys.exit(2)
+
+
+if __name__ == '__main__':
+    test()


Property changes on: vendor/Python/current/Demo/pdist/RCSProxy.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/pdist/README
===================================================================
--- vendor/Python/current/Demo/pdist/README	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/pdist/README	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,121 @@
+Filesystem, RCS and CVS client and server classes
+=================================================
+
+*** See the security warning at the end of this file! ***
+
+This directory contains various modules and classes that support
+remote file system operations.
+
+CVS stuff
+---------
+
+rcvs			Script to put in your bin directory
+rcvs.py			Remote CVS client command line interface
+
+cvslib.py		CVS admin files classes (used by rrcs)
+cvslock.py		CVS locking algorithms
+
+RCS stuff
+---------
+
+rrcs			Script to put in your bin directory
+rrcs.py			Remote RCS client command line interface
+
+rcsclient.py		Return an RCSProxyClient instance
+			(has reasonable default server/port/directory)
+
+RCSProxy.py		RCS proxy and server classes (on top of rcslib.py)
+
+rcslib.py		Local-only RCS base class (affects stdout &
+			local work files)
+
+FSProxy stuff
+-------------
+
+sumtree.py		Old demo for FSProxy
+cmptree.py		First FSProxy client (used to sync from the Mac)
+FSProxy.py		Filesystem interface classes
+
+Generic client/server stuff
+---------------------------
+
+client.py		Client class
+server.py		Server class
+
+security.py		Security mix-in class (not very secure I think)
+
+Other generic stuff
+-------------------
+
+cmdfw.py		CommandFrameWork class
+			(used by rcvs, should be used by rrcs as well)
+
+
+Client/Server operation
+-----------------------
+
+The Client and Server classes implement a simple-minded RPC protocol,
+using Python's pickle module to transfer arguments, return values and
+exceptions with the most generality.  The Server class is instantiated
+with a port number on which it should listen for requests; the Client
+class is instantiated with a host name and a port number where it
+should connect to.  Once a client is connected, a TCP connection is
+maintained between client and server.
+
+The Server class currently handles only one connection at a time;
+however it could be rewritten to allow various modes of operations,
+using multiple threads or processes or the select() system call as
+desired to serve multiple clients simultaneously (when using select(),
+still handling one request at a time).  This would not require
+rewriting of the Client class.  It may also be possible to adapt the
+code to use UDP instead of TCP, but then both classes will have to be
+rewritten (and unless extensive acknowlegements and request serial
+numbers are used, the server should handle duplicate requests, so its
+semantics should be idempotent -- shrudder).
+
+Even though the FSProxy and RCSProxy modules define client classes,
+the client class is fully generic -- what methods it supports is
+determined entirely by the server.  The server class, however, must be
+derived from.  This is generally done as follows:
+
+	from server import Server
+	from client import Client
+
+	# Define a class that performs the operations locally
+	class MyClassLocal:
+		def __init__(self): ...
+		def _close(self): ...
+
+	# Derive a server class using multiple inheritance
+	class MyClassServer(MyClassLocal, Server):
+		def __init__(self, address):
+			# Must initialize MyClassLocal as well as Server
+			MyClassLocal.__init__(self)
+			Server.__init__(self, address)
+		def _close(self):
+			Server._close()
+			MyClassLocal._close()
+
+	# A dummy client class
+	class MyClassClient(Client): pass
+
+Note that because MyClassLocal isn't used in the definition of
+MyClassClient, it would actually be better to place it in a separate
+module so the definition of MyClassLocal isn't executed when we only
+instantiate a client.
+
+The modules client and server should probably be renamed to Client and
+Server in order to match the class names.
+
+
+*** Security warning: this version requires that you have a file
+$HOME/.python_keyfile at the server and client side containing two
+comma- separated numbers.  The security system at the moment makes no
+guarantees of actuallng being secure -- however it requires that the
+key file exists and contains the same numbers at both ends for this to
+work.  (You can specify an alternative keyfile in $PYTHON_KEYFILE).
+Have a look at the Security class in security.py for details;
+basically, if the key file contains (x, y), then the security server
+class chooses a random number z (the challenge) in the range
+10..100000 and the client must be able to produce pow(z, x, y)
+(i.e. z**x mod y).

Added: vendor/Python/current/Demo/pdist/client.py
===================================================================
--- vendor/Python/current/Demo/pdist/client.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/pdist/client.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,157 @@
+"""RPC Client module."""
+
+import sys
+import socket
+import pickle
+import __builtin__
+import os
+
+
+# Default verbosity (0 = silent, 1 = print connections, 2 = print requests too)
+VERBOSE = 1
+
+
+class Client:
+
+    """RPC Client class.  No need to derive a class -- it's fully generic."""
+
+    def __init__(self, address, verbose = VERBOSE):
+        self._pre_init(address, verbose)
+        self._post_init()
+
+    def _pre_init(self, address, verbose = VERBOSE):
+        if type(address) == type(0):
+            address = ('', address)
+        self._address = address
+        self._verbose = verbose
+        if self._verbose: print "Connecting to %s ..." % repr(address)
+        self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        self._socket.connect(address)
+        if self._verbose: print "Connected."
+        self._lastid = 0 # Last id for which a reply has been received
+        self._nextid = 1 # Id of next request
+        self._replies = {} # Unprocessed replies
+        self._rf = self._socket.makefile('r')
+        self._wf = self._socket.makefile('w')
+
+    def _post_init(self):
+        self._methods = self._call('.methods')
+
+    def __del__(self):
+        self._close()
+
+    def _close(self):
+        if self._rf: self._rf.close()
+        self._rf = None
+        if self._wf: self._wf.close()
+        self._wf = None
+        if self._socket: self._socket.close()
+        self._socket = None
+
+    def __getattr__(self, name):
+        if name in self._methods:
+            method = _stub(self, name)
+            setattr(self, name, method) # XXX circular reference
+            return method
+        raise AttributeError, name
+
+    def _setverbose(self, verbose):
+        self._verbose = verbose
+
+    def _call(self, name, *args):
+        return self._vcall(name, args)
+
+    def _vcall(self, name, args):
+        return self._recv(self._vsend(name, args))
+
+    def _send(self, name, *args):
+        return self._vsend(name, args)
+
+    def _send_noreply(self, name, *args):
+        return self._vsend(name, args, 0)
+
+    def _vsend_noreply(self, name, args):
+        return self._vsend(name, args, 0)
+
+    def _vsend(self, name, args, wantreply = 1):
+        id = self._nextid
+        self._nextid = id+1
+        if not wantreply: id = -id
+        request = (name, args, id)
+        if self._verbose > 1: print "sending request: %s" % repr(request)
+        wp = pickle.Pickler(self._wf)
+        wp.dump(request)
+        return id
+
+    def _recv(self, id):
+        exception, value, rid = self._vrecv(id)
+        if rid != id:
+            raise RuntimeError, "request/reply id mismatch: %d/%d" % (id, rid)
+        if exception is None:
+            return value
+        x = exception
+        if hasattr(__builtin__, exception):
+            x = getattr(__builtin__, exception)
+        elif exception in ('posix.error', 'mac.error'):
+            x = os.error
+        if x == exception:
+            exception = x
+        raise exception, value
+
+    def _vrecv(self, id):
+        self._flush()
+        if self._replies.has_key(id):
+            if self._verbose > 1: print "retrieving previous reply, id = %d" % id
+            reply = self._replies[id]
+            del self._replies[id]
+            return reply
+        aid = abs(id)
+        while 1:
+            if self._verbose > 1: print "waiting for reply, id = %d" % id
+            rp = pickle.Unpickler(self._rf)
+            reply = rp.load()
+            del rp
+            if self._verbose > 1: print "got reply: %s" % repr(reply)
+            rid = reply[2]
+            arid = abs(rid)
+            if arid == aid:
+                if self._verbose > 1: print "got it"
+                return reply
+            self._replies[rid] = reply
+            if arid > aid:
+                if self._verbose > 1: print "got higher id, assume all ok"
+                return (None, None, id)
+
+    def _flush(self):
+        self._wf.flush()
+
+
+from security import Security
+
+
+class SecureClient(Client, Security):
+
+    def __init__(self, *args):
+        import string
+        apply(self._pre_init, args)
+        Security.__init__(self)
+        self._wf.flush()
+        line = self._rf.readline()
+        challenge = string.atoi(string.strip(line))
+        response = self._encode_challenge(challenge)
+        line = repr(long(response))
+        if line[-1] in 'Ll': line = line[:-1]
+        self._wf.write(line + '\n')
+        self._wf.flush()
+        self._post_init()
+
+class _stub:
+
+    """Helper class for Client -- each instance serves as a method of the client."""
+
+    def __init__(self, client, name):
+        self._client = client
+        self._name = name
+
+    def __call__(self, *args):
+        return self._client._vcall(self._name, args)


Property changes on: vendor/Python/current/Demo/pdist/client.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/pdist/cmdfw.py
===================================================================
--- vendor/Python/current/Demo/pdist/cmdfw.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/pdist/cmdfw.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,144 @@
+"Framework for command line interfaces like CVS.  See class CmdFrameWork."
+
+
+class CommandFrameWork:
+
+    """Framework class for command line interfaces like CVS.
+
+    The general command line structure is
+
+            command [flags] subcommand [subflags] [argument] ...
+
+    There's a class variable GlobalFlags which specifies the
+    global flags options.  Subcommands are defined by defining
+    methods named do_<subcommand>.  Flags for the subcommand are
+    defined by defining class or instance variables named
+    flags_<subcommand>.  If there's no command, method default()
+    is called.  The __doc__ strings for the do_ methods are used
+    for the usage message, printed after the general usage message
+    which is the class variable UsageMessage.  The class variable
+    PostUsageMessage is printed after all the do_ methods' __doc__
+    strings.  The method's return value can be a suggested exit
+    status.  [XXX Need to rewrite this to clarify it.]
+
+    Common usage is to derive a class, instantiate it, and then call its
+    run() method; by default this takes its arguments from sys.argv[1:].
+    """
+
+    UsageMessage = \
+      "usage: (name)s [flags] subcommand [subflags] [argument] ..."
+
+    PostUsageMessage = None
+
+    GlobalFlags = ''
+
+    def __init__(self):
+        """Constructor, present for completeness."""
+        pass
+
+    def run(self, args = None):
+        """Process flags, subcommand and options, then run it."""
+        import getopt, sys
+        if args is None: args = sys.argv[1:]
+        try:
+            opts, args = getopt.getopt(args, self.GlobalFlags)
+        except getopt.error, msg:
+            return self.usage(msg)
+        self.options(opts)
+        if not args:
+            self.ready()
+            return self.default()
+        else:
+            cmd = args[0]
+            mname = 'do_' + cmd
+            fname = 'flags_' + cmd
+            try:
+                method = getattr(self, mname)
+            except AttributeError:
+                return self.usage("command %r unknown" % (cmd,))
+            try:
+                flags = getattr(self, fname)
+            except AttributeError:
+                flags = ''
+            try:
+                opts, args = getopt.getopt(args[1:], flags)
+            except getopt.error, msg:
+                return self.usage(
+                        "subcommand %s: " % cmd + str(msg))
+            self.ready()
+            return method(opts, args)
+
+    def options(self, opts):
+        """Process the options retrieved by getopt.
+        Override this if you have any options."""
+        if opts:
+            print "-"*40
+            print "Options:"
+            for o, a in opts:
+                print 'option', o, 'value', repr(a)
+            print "-"*40
+
+    def ready(self):
+        """Called just before calling the subcommand."""
+        pass
+
+    def usage(self, msg = None):
+        """Print usage message.  Return suitable exit code (2)."""
+        if msg: print msg
+        print self.UsageMessage % {'name': self.__class__.__name__}
+        docstrings = {}
+        c = self.__class__
+        while 1:
+            for name in dir(c):
+                if name[:3] == 'do_':
+                    if docstrings.has_key(name):
+                        continue
+                    try:
+                        doc = getattr(c, name).__doc__
+                    except:
+                        doc = None
+                    if doc:
+                        docstrings[name] = doc
+            if not c.__bases__:
+                break
+            c = c.__bases__[0]
+        if docstrings:
+            print "where subcommand can be:"
+            names = docstrings.keys()
+            names.sort()
+            for name in names:
+                print docstrings[name]
+        if self.PostUsageMessage:
+            print self.PostUsageMessage
+        return 2
+
+    def default(self):
+        """Default method, called when no subcommand is given.
+        You should always override this."""
+        print "Nobody expects the Spanish Inquisition!"
+
+
+def test():
+    """Test script -- called when this module is run as a script."""
+    import sys
+    class Hello(CommandFrameWork):
+        def do_hello(self, opts, args):
+            "hello -- print 'hello world', needs no arguments"
+            print "Hello, world"
+    x = Hello()
+    tests = [
+            [],
+            ['hello'],
+            ['spam'],
+            ['-x'],
+            ['hello', '-x'],
+            None,
+            ]
+    for t in tests:
+        print '-'*10, t, '-'*10
+        sts = x.run(t)
+        print "Exit status:", repr(sts)
+
+
+if __name__ == '__main__':
+    test()


Property changes on: vendor/Python/current/Demo/pdist/cmdfw.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/pdist/cmptree.py
===================================================================
--- vendor/Python/current/Demo/pdist/cmptree.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/pdist/cmptree.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,208 @@
+"""Compare local and remote dictionaries and transfer differing files -- like rdist."""
+
+import sys
+from repr import repr
+import FSProxy
+import time
+import os
+
+def main():
+    pwd = os.getcwd()
+    s = raw_input("chdir [%s] " % pwd)
+    if s:
+        os.chdir(s)
+        pwd = os.getcwd()
+    host = ask("host", 'voorn.cwi.nl')
+    port = 4127
+    verbose = 1
+    mode = ''
+    print """\
+Mode should be a string of characters, indicating what to do with differences.
+r - read different files to local file system
+w - write different files to remote file system
+c - create new files, either remote or local
+d - delete disappearing files, either remote or local
+"""
+    s = raw_input("mode [%s] " % mode)
+    if s: mode = s
+    address = (host, port)
+    t1 = time.time()
+    local = FSProxy.FSProxyLocal()
+    remote = FSProxy.FSProxyClient(address, verbose)
+    compare(local, remote, mode)
+    remote._close()
+    local._close()
+    t2 = time.time()
+    dt = t2-t1
+    mins, secs = divmod(dt, 60)
+    print mins, "minutes and", round(secs), "seconds"
+    raw_input("[Return to exit] ")
+
+def ask(prompt, default):
+    s = raw_input("%s [%s] " % (prompt, default))
+    return s or default
+
+def askint(prompt, default):
+    s = raw_input("%s [%s] " % (prompt, str(default)))
+    if s: return string.atoi(s)
+    return default
+
+def compare(local, remote, mode):
+    print
+    print "PWD =", repr(os.getcwd())
+    sums_id = remote._send('sumlist')
+    subdirs_id = remote._send('listsubdirs')
+    remote._flush()
+    print "calculating local sums ..."
+    lsumdict = {}
+    for name, info in local.sumlist():
+        lsumdict[name] = info
+    print "getting remote sums ..."
+    sums = remote._recv(sums_id)
+    print "got", len(sums)
+    rsumdict = {}
+    for name, rsum in sums:
+        rsumdict[name] = rsum
+        if not lsumdict.has_key(name):
+            print repr(name), "only remote"
+            if 'r' in mode and 'c' in mode:
+                recvfile(local, remote, name)
+        else:
+            lsum = lsumdict[name]
+            if lsum != rsum:
+                print repr(name),
+                rmtime = remote.mtime(name)
+                lmtime = local.mtime(name)
+                if rmtime > lmtime:
+                    print "remote newer",
+                    if 'r' in mode:
+                        recvfile(local, remote, name)
+                elif lmtime > rmtime:
+                    print "local newer",
+                    if 'w' in mode:
+                        sendfile(local, remote, name)
+                else:
+                    print "same mtime but different sum?!?!",
+                print
+    for name in lsumdict.keys():
+        if not rsumdict.keys():
+            print repr(name), "only locally",
+            fl()
+            if 'w' in mode and 'c' in mode:
+                sendfile(local, remote, name)
+            elif 'r' in mode and 'd' in mode:
+                os.unlink(name)
+                print "removed."
+            print
+    print "gettin subdirs ..."
+    subdirs = remote._recv(subdirs_id)
+    common = []
+    for name in subdirs:
+        if local.isdir(name):
+            print "Common subdirectory", repr(name)
+            common.append(name)
+        else:
+            print "Remote subdirectory", repr(name), "not found locally"
+            if 'r' in mode and 'c' in mode:
+                pr = "Create local subdirectory %s? [y] " % \
+                     repr(name)
+                if 'y' in mode:
+                    ok = 'y'
+                else:
+                    ok = ask(pr, "y")
+                if ok[:1] in ('y', 'Y'):
+                    local.mkdir(name)
+                    print "Subdirectory %s made" % \
+                            repr(name)
+                    common.append(name)
+    lsubdirs = local.listsubdirs()
+    for name in lsubdirs:
+        if name not in subdirs:
+            print "Local subdirectory", repr(name), "not found remotely"
+    for name in common:
+        print "Entering subdirectory", repr(name)
+        local.cd(name)
+        remote.cd(name)
+        compare(local, remote, mode)
+        remote.back()
+        local.back()
+
+def sendfile(local, remote, name):
+    try:
+        remote.create(name)
+    except (IOError, os.error), msg:
+        print "cannot create:", msg
+        return
+
+    print "sending ...",
+    fl()
+
+    data = open(name).read()
+
+    t1 = time.time()
+
+    remote._send_noreply('write', name, data)
+    remote._flush()
+
+    t2 = time.time()
+
+    dt = t2-t1
+    print len(data), "bytes in", round(dt), "seconds",
+    if dt:
+        print "i.e.", round(len(data)/dt), "bytes/sec",
+    print
+
+def recvfile(local, remote, name):
+    ok = 0
+    try:
+        rv = recvfile_real(local, remote, name)
+        ok = 1
+        return rv
+    finally:
+        if not ok:
+            print "*** recvfile of %r failed, deleting" % (name,)
+            local.delete(name)
+
+def recvfile_real(local, remote, name):
+    try:
+        local.create(name)
+    except (IOError, os.error), msg:
+        print "cannot create:", msg
+        return
+
+    print "receiving ...",
+    fl()
+
+    f = open(name, 'w')
+    t1 = time.time()
+
+    length = 4*1024
+    offset = 0
+    id = remote._send('read', name, offset, length)
+    remote._flush()
+    while 1:
+        newoffset = offset + length
+        newid = remote._send('read', name, newoffset, length)
+        data = remote._recv(id)
+        id = newid
+        if not data: break
+        f.seek(offset)
+        f.write(data)
+        offset = newoffset
+    size = f.tell()
+
+    t2 = time.time()
+    f.close()
+
+    dt = t2-t1
+    print size, "bytes in", round(dt), "seconds",
+    if dt:
+        print "i.e.", int(size/dt), "bytes/sec",
+    print
+    remote._recv(id) # ignored
+
+def fl():
+    sys.stdout.flush()
+
+if __name__ == '__main__':
+    main()


Property changes on: vendor/Python/current/Demo/pdist/cmptree.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/pdist/cvslib.py
===================================================================
--- vendor/Python/current/Demo/pdist/cvslib.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/pdist/cvslib.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,364 @@
+"""Utilities for CVS administration."""
+
+import string
+import os
+import time
+import md5
+import fnmatch
+
+if not hasattr(time, 'timezone'):
+    time.timezone = 0
+
+class File:
+
+    """Represent a file's status.
+
+    Instance variables:
+
+    file -- the filename (no slashes), None if uninitialized
+    lseen -- true if the data for the local file is up to date
+    eseen -- true if the data from the CVS/Entries entry is up to date
+             (this implies that the entry must be written back)
+    rseen -- true if the data for the remote file is up to date
+    proxy -- RCSProxy instance used to contact the server, or None
+
+    Note that lseen and rseen don't necessary mean that a local
+    or remote file *exists* -- they indicate that we've checked it.
+    However, eseen means that this instance corresponds to an
+    entry in the CVS/Entries file.
+
+    If lseen is true:
+
+    lsum -- checksum of the local file, None if no local file
+    lctime -- ctime of the local file, None if no local file
+    lmtime -- mtime of the local file, None if no local file
+
+    If eseen is true:
+
+    erev -- revision, None if this is a no revision (not '0')
+    enew -- true if this is an uncommitted added file
+    edeleted -- true if this is an uncommitted removed file
+    ectime -- ctime of last local file corresponding to erev
+    emtime -- mtime of last local file corresponding to erev
+    extra -- 5th string from CVS/Entries file
+
+    If rseen is true:
+
+    rrev -- revision of head, None if non-existent
+    rsum -- checksum of that revision, Non if non-existent
+
+    If eseen and rseen are both true:
+
+    esum -- checksum of revision erev, None if no revision
+
+    Note
+    """
+
+    def __init__(self, file = None):
+        if file and '/' in file:
+            raise ValueError, "no slash allowed in file"
+        self.file = file
+        self.lseen = self.eseen = self.rseen = 0
+        self.proxy = None
+
+    def __cmp__(self, other):
+        return cmp(self.file, other.file)
+
+    def getlocal(self):
+        try:
+            self.lmtime, self.lctime = os.stat(self.file)[-2:]
+        except os.error:
+            self.lmtime = self.lctime = self.lsum = None
+        else:
+            self.lsum = md5.new(open(self.file).read()).digest()
+        self.lseen = 1
+
+    def getentry(self, line):
+        words = string.splitfields(line, '/')
+        if self.file and words[1] != self.file:
+            raise ValueError, "file name mismatch"
+        self.file = words[1]
+        self.erev = words[2]
+        self.edeleted = 0
+        self.enew = 0
+        self.ectime = self.emtime = None
+        if self.erev[:1] == '-':
+            self.edeleted = 1
+            self.erev = self.erev[1:]
+        if self.erev == '0':
+            self.erev = None
+            self.enew = 1
+        else:
+            dates = words[3]
+            self.ectime = unctime(dates[:24])
+            self.emtime = unctime(dates[25:])
+        self.extra = words[4]
+        if self.rseen:
+            self.getesum()
+        self.eseen = 1
+
+    def getremote(self, proxy = None):
+        if proxy:
+            self.proxy = proxy
+        try:
+            self.rrev = self.proxy.head(self.file)
+        except (os.error, IOError):
+            self.rrev = None
+        if self.rrev:
+            self.rsum = self.proxy.sum(self.file)
+        else:
+            self.rsum = None
+        if self.eseen:
+            self.getesum()
+        self.rseen = 1
+
+    def getesum(self):
+        if self.erev == self.rrev:
+            self.esum = self.rsum
+        elif self.erev:
+            name = (self.file, self.erev)
+            self.esum = self.proxy.sum(name)
+        else:
+            self.esum = None
+
+    def putentry(self):
+        """Return a line suitable for inclusion in CVS/Entries.
+
+        The returned line is terminated by a newline.
+        If no entry should be written for this file,
+        return "".
+        """
+        if not self.eseen:
+            return ""
+
+        rev = self.erev or '0'
+        if self.edeleted:
+            rev = '-' + rev
+        if self.enew:
+            dates = 'Initial ' + self.file
+        else:
+            dates = gmctime(self.ectime) + ' ' + \
+                    gmctime(self.emtime)
+        return "/%s/%s/%s/%s/\n" % (
+                self.file,
+                rev,
+                dates,
+                self.extra)
+
+    def report(self):
+        print '-'*50
+        def r(key, repr=repr, self=self):
+            try:
+                value = repr(getattr(self, key))
+            except AttributeError:
+                value = "?"
+            print "%-15s:" % key, value
+        r("file")
+        if self.lseen:
+            r("lsum", hexify)
+            r("lctime", gmctime)
+            r("lmtime", gmctime)
+        if self.eseen:
+            r("erev")
+            r("enew")
+            r("edeleted")
+            r("ectime", gmctime)
+            r("emtime", gmctime)
+        if self.rseen:
+            r("rrev")
+            r("rsum", hexify)
+            if self.eseen:
+                r("esum", hexify)
+
+
+class CVS:
+
+    """Represent the contents of a CVS admin file (and more).
+
+    Class variables:
+
+    FileClass -- the class to be instantiated for entries
+                 (this should be derived from class File above)
+    IgnoreList -- shell patterns for local files to be ignored
+
+    Instance variables:
+
+    entries -- a dictionary containing File instances keyed by
+               their file name
+    proxy -- an RCSProxy instance, or None
+    """
+
+    FileClass = File
+
+    IgnoreList = ['.*', '@*', ',*', '*~', '*.o', '*.a', '*.so', '*.pyc']
+
+    def __init__(self):
+        self.entries = {}
+        self.proxy = None
+
+    def setproxy(self, proxy):
+        if proxy is self.proxy:
+            return
+        self.proxy = proxy
+        for e in self.entries.values():
+            e.rseen = 0
+
+    def getentries(self):
+        """Read the contents of CVS/Entries"""
+        self.entries = {}
+        f = self.cvsopen("Entries")
+        while 1:
+            line = f.readline()
+            if not line: break
+            e = self.FileClass()
+            e.getentry(line)
+            self.entries[e.file] = e
+        f.close()
+
+    def putentries(self):
+        """Write CVS/Entries back"""
+        f = self.cvsopen("Entries", 'w')
+        for e in self.values():
+            f.write(e.putentry())
+        f.close()
+
+    def getlocalfiles(self):
+        list = self.entries.keys()
+        addlist = os.listdir(os.curdir)
+        for name in addlist:
+            if name in list:
+                continue
+            if not self.ignored(name):
+                list.append(name)
+        list.sort()
+        for file in list:
+            try:
+                e = self.entries[file]
+            except KeyError:
+                e = self.entries[file] = self.FileClass(file)
+            e.getlocal()
+
+    def getremotefiles(self, proxy = None):
+        if proxy:
+            self.proxy = proxy
+        if not self.proxy:
+            raise RuntimeError, "no RCS proxy"
+        addlist = self.proxy.listfiles()
+        for file in addlist:
+            try:
+                e = self.entries[file]
+            except KeyError:
+                e = self.entries[file] = self.FileClass(file)
+            e.getremote(self.proxy)
+
+    def report(self):
+        for e in self.values():
+            e.report()
+        print '-'*50
+
+    def keys(self):
+        keys = self.entries.keys()
+        keys.sort()
+        return keys
+
+    def values(self):
+        def value(key, self=self):
+            return self.entries[key]
+        return map(value, self.keys())
+
+    def items(self):
+        def item(key, self=self):
+            return (key, self.entries[key])
+        return map(item, self.keys())
+
+    def cvsexists(self, file):
+        file = os.path.join("CVS", file)
+        return os.path.exists(file)
+
+    def cvsopen(self, file, mode = 'r'):
+        file = os.path.join("CVS", file)
+        if 'r' not in mode:
+            self.backup(file)
+        return open(file, mode)
+
+    def backup(self, file):
+        if os.path.isfile(file):
+            bfile = file + '~'
+            try: os.unlink(bfile)
+            except os.error: pass
+            os.rename(file, bfile)
+
+    def ignored(self, file):
+        if os.path.isdir(file): return True
+        for pat in self.IgnoreList:
+            if fnmatch.fnmatch(file, pat): return True
+        return False
+
+
+# hexify and unhexify are useful to print MD5 checksums in hex format
+
+hexify_format = '%02x' * 16
+def hexify(sum):
+    "Return a hex representation of a 16-byte string (e.g. an MD5 digest)"
+    if sum is None:
+        return "None"
+    return hexify_format % tuple(map(ord, sum))
+
+def unhexify(hexsum):
+    "Return the original from a hexified string"
+    if hexsum == "None":
+        return None
+    sum = ''
+    for i in range(0, len(hexsum), 2):
+        sum = sum + chr(string.atoi(hexsum[i:i+2], 16))
+    return sum
+
+
+unctime_monthmap = {}
+def unctime(date):
+    if date == "None": return None
+    if not unctime_monthmap:
+        months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
+                  'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
+        i = 0
+        for m in months:
+            i = i+1
+            unctime_monthmap[m] = i
+    words = string.split(date) # Day Mon DD HH:MM:SS YEAR
+    year = string.atoi(words[4])
+    month = unctime_monthmap[words[1]]
+    day = string.atoi(words[2])
+    [hh, mm, ss] = map(string.atoi, string.splitfields(words[3], ':'))
+    ss = ss - time.timezone
+    return time.mktime((year, month, day, hh, mm, ss, 0, 0, 0))
+
+def gmctime(t):
+    if t is None: return "None"
+    return time.asctime(time.gmtime(t))
+
+def test_unctime():
+    now = int(time.time())
+    t = time.gmtime(now)
+    at = time.asctime(t)
+    print 'GMT', now, at
+    print 'timezone', time.timezone
+    print 'local', time.ctime(now)
+    u = unctime(at)
+    print 'unctime()', u
+    gu = time.gmtime(u)
+    print '->', gu
+    print time.asctime(gu)
+
+def test():
+    x = CVS()
+    x.getentries()
+    x.getlocalfiles()
+##      x.report()
+    import rcsclient
+    proxy = rcsclient.openrcsclient()
+    x.getremotefiles(proxy)
+    x.report()
+
+
+if __name__ == "__main__":
+    test()


Property changes on: vendor/Python/current/Demo/pdist/cvslib.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/pdist/cvslock.py
===================================================================
--- vendor/Python/current/Demo/pdist/cvslock.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/pdist/cvslock.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,280 @@
+"""CVS locking algorithm.
+
+CVS locking strategy
+====================
+
+As reverse engineered from the CVS 1.3 sources (file lock.c):
+
+- Locking is done on a per repository basis (but a process can hold
+write locks for multiple directories); all lock files are placed in
+the repository and have names beginning with "#cvs.".
+
+- Before even attempting to lock, a file "#cvs.tfl.<pid>" is created
+(and removed again), to test that we can write the repository.  [The
+algorithm can still be fooled (1) if the repository's mode is changed
+while attempting to lock; (2) if this file exists and is writable but
+the directory is not.]
+
+- While creating the actual read/write lock files (which may exist for
+a long time), a "meta-lock" is held.  The meta-lock is a directory
+named "#cvs.lock" in the repository.  The meta-lock is also held while
+a write lock is held.
+
+- To set a read lock:
+
+        - acquire the meta-lock
+        - create the file "#cvs.rfl.<pid>"
+        - release the meta-lock
+
+- To set a write lock:
+
+        - acquire the meta-lock
+        - check that there are no files called "#cvs.rfl.*"
+                - if there are, release the meta-lock, sleep, try again
+        - create the file "#cvs.wfl.<pid>"
+
+- To release a write lock:
+
+        - remove the file "#cvs.wfl.<pid>"
+        - rmdir the meta-lock
+
+- To release a read lock:
+
+        - remove the file "#cvs.rfl.<pid>"
+
+
+Additional notes
+----------------
+
+- A process should read-lock at most one repository at a time.
+
+- A process may write-lock as many repositories as it wishes (to avoid
+deadlocks, I presume it should always lock them top-down in the
+directory hierarchy).
+
+- A process should make sure it removes all its lock files and
+directories when it crashes.
+
+- Limitation: one user id should not be committing files into the same
+repository at the same time.
+
+
+Turn this into Python code
+--------------------------
+
+rl = ReadLock(repository, waittime)
+
+wl = WriteLock(repository, waittime)
+
+list = MultipleWriteLock([repository1, repository2, ...], waittime)
+
+"""
+
+
+import os
+import time
+import stat
+import pwd
+
+
+# Default wait time
+DELAY = 10
+
+
+# XXX This should be the same on all Unix versions
+EEXIST = 17
+
+
+# Files used for locking (must match cvs.h in the CVS sources)
+CVSLCK = "#cvs.lck"
+CVSRFL = "#cvs.rfl."
+CVSWFL = "#cvs.wfl."
+
+
+class Error:
+
+    def __init__(self, msg):
+        self.msg = msg
+
+    def __repr__(self):
+        return repr(self.msg)
+
+    def __str__(self):
+        return str(self.msg)
+
+
+class Locked(Error):
+    pass
+
+
+class Lock:
+
+    def __init__(self, repository = ".", delay = DELAY):
+        self.repository = repository
+        self.delay = delay
+        self.lockdir = None
+        self.lockfile = None
+        pid = repr(os.getpid())
+        self.cvslck = self.join(CVSLCK)
+        self.cvsrfl = self.join(CVSRFL + pid)
+        self.cvswfl = self.join(CVSWFL + pid)
+
+    def __del__(self):
+        print "__del__"
+        self.unlock()
+
+    def setlockdir(self):
+        while 1:
+            try:
+                self.lockdir = self.cvslck
+                os.mkdir(self.cvslck, 0777)
+                return
+            except os.error, msg:
+                self.lockdir = None
+                if msg[0] == EEXIST:
+                    try:
+                        st = os.stat(self.cvslck)
+                    except os.error:
+                        continue
+                    self.sleep(st)
+                    continue
+                raise Error("failed to lock %s: %s" % (
+                        self.repository, msg))
+
+    def unlock(self):
+        self.unlockfile()
+        self.unlockdir()
+
+    def unlockfile(self):
+        if self.lockfile:
+            print "unlink", self.lockfile
+            try:
+                os.unlink(self.lockfile)
+            except os.error:
+                pass
+            self.lockfile = None
+
+    def unlockdir(self):
+        if self.lockdir:
+            print "rmdir", self.lockdir
+            try:
+                os.rmdir(self.lockdir)
+            except os.error:
+                pass
+            self.lockdir = None
+
+    def sleep(self, st):
+        sleep(st, self.repository, self.delay)
+
+    def join(self, name):
+        return os.path.join(self.repository, name)
+
+
+def sleep(st, repository, delay):
+    if delay <= 0:
+        raise Locked(st)
+    uid = st[stat.ST_UID]
+    try:
+        pwent = pwd.getpwuid(uid)
+        user = pwent[0]
+    except KeyError:
+        user = "uid %d" % uid
+    print "[%s]" % time.ctime(time.time())[11:19],
+    print "Waiting for %s's lock in" % user, repository
+    time.sleep(delay)
+
+
+class ReadLock(Lock):
+
+    def __init__(self, repository, delay = DELAY):
+        Lock.__init__(self, repository, delay)
+        ok = 0
+        try:
+            self.setlockdir()
+            self.lockfile = self.cvsrfl
+            fp = open(self.lockfile, 'w')
+            fp.close()
+            ok = 1
+        finally:
+            if not ok:
+                self.unlockfile()
+            self.unlockdir()
+
+
+class WriteLock(Lock):
+
+    def __init__(self, repository, delay = DELAY):
+        Lock.__init__(self, repository, delay)
+        self.setlockdir()
+        while 1:
+            uid = self.readers_exist()
+            if not uid:
+                break
+            self.unlockdir()
+            self.sleep(uid)
+        self.lockfile = self.cvswfl
+        fp = open(self.lockfile, 'w')
+        fp.close()
+
+    def readers_exist(self):
+        n = len(CVSRFL)
+        for name in os.listdir(self.repository):
+            if name[:n] == CVSRFL:
+                try:
+                    st = os.stat(self.join(name))
+                except os.error:
+                    continue
+                return st
+        return None
+
+
+def MultipleWriteLock(repositories, delay = DELAY):
+    while 1:
+        locks = []
+        for r in repositories:
+            try:
+                locks.append(WriteLock(r, 0))
+            except Locked, instance:
+                del locks
+                break
+        else:
+            break
+        sleep(instance.msg, r, delay)
+    return list
+
+
+def test():
+    import sys
+    if sys.argv[1:]:
+        repository = sys.argv[1]
+    else:
+        repository = "."
+    rl = None
+    wl = None
+    try:
+        print "attempting write lock ..."
+        wl = WriteLock(repository)
+        print "got it."
+        wl.unlock()
+        print "attempting read lock ..."
+        rl = ReadLock(repository)
+        print "got it."
+        rl.unlock()
+    finally:
+        print [1]
+        sys.exc_traceback = None
+        print [2]
+        if rl:
+            rl.unlock()
+        print [3]
+        if wl:
+            wl.unlock()
+        print [4]
+        rl = None
+        print [5]
+        wl = None
+        print [6]
+
+
+if __name__ == '__main__':
+    test()


Property changes on: vendor/Python/current/Demo/pdist/cvslock.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/pdist/mac.py
===================================================================
--- vendor/Python/current/Demo/pdist/mac.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/pdist/mac.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,19 @@
+import sys
+import string
+import rcvs
+
+def main():
+    while 1:
+        try:
+            line = raw_input('$ ')
+        except EOFError:
+            break
+        words = string.split(line)
+        if not words:
+            continue
+        if words[0] != 'rcvs':
+            words.insert(0, 'rcvs')
+        sys.argv = words
+        rcvs.main()
+
+main()


Property changes on: vendor/Python/current/Demo/pdist/mac.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/pdist/makechangelog.py
===================================================================
--- vendor/Python/current/Demo/pdist/makechangelog.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/pdist/makechangelog.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,109 @@
+#! /usr/bin/env python
+
+"""Turn a pile of RCS log output into ChangeLog file entries.
+
+"""
+
+import sys
+import string
+import re
+import getopt
+import time
+
+def main():
+    args = sys.argv[1:]
+    opts, args = getopt.getopt(args, 'p:')
+    prefix = ''
+    for o, a in opts:
+        if p == '-p': prefix = a
+
+    f = sys.stdin
+    allrevs = []
+    while 1:
+        file = getnextfile(f)
+        if not file: break
+        revs = []
+        while 1:
+            rev = getnextrev(f, file)
+            if not rev:
+                break
+            revs.append(rev)
+        if revs:
+            allrevs[len(allrevs):] = revs
+    allrevs.sort()
+    allrevs.reverse()
+    for rev in allrevs:
+        formatrev(rev, prefix)
+
+parsedateprog = re.compile(
+    '^date: ([0-9]+)/([0-9]+)/([0-9]+) ' +
+    '([0-9]+):([0-9]+):([0-9]+);  author: ([^ ;]+)')
+
+authormap = {
+    'guido': 'Guido van Rossum  <guido at cnri.reston.va.us>',
+    'jack': 'Jack Jansen  <jack at cwi.nl>',
+    'sjoerd': 'Sjoerd Mullender  <sjoerd at cwi.nl>',
+    }
+
+def formatrev(rev, prefix):
+    dateline, file, revline, log = rev
+    if parsedateprog.match(dateline) >= 0:
+        fields = parsedateprog.group(1, 2, 3, 4, 5, 6)
+        author = parsedateprog.group(7)
+        if authormap.has_key(author): author = authormap[author]
+        tfields = map(string.atoi, fields) + [0, 0, 0]
+        tfields[5] = tfields[5] - time.timezone
+        t = time.mktime(tuple(tfields))
+        print time.ctime(t), '', author
+        words = string.split(log)
+        words[:0] = ['*', prefix + file + ':']
+        maxcol = 72-8
+        col = maxcol
+        for word in words:
+            if col > 0 and col + len(word) >= maxcol:
+                print
+                print '\t' + word,
+                col = -1
+            else:
+                print word,
+            col = col + 1 + len(word)
+        print
+        print
+
+startprog = re.compile("^Working file: (.*)$")
+
+def getnextfile(f):
+    while 1:
+        line = f.readline()
+        if not line: return None
+        if startprog.match(line) >= 0:
+            file = startprog.group(1)
+            # Skip until first revision
+            while 1:
+                line = f.readline()
+                if not line: return None
+                if line[:10] == '='*10: return None
+                if line[:10] == '-'*10: break
+##              print "Skipped", line,
+            return file
+##      else:
+##          print "Ignored", line,
+
+def getnextrev(f, file):
+    # This is called when we are positioned just after a '---' separator
+    revline = f.readline()
+    dateline = f.readline()
+    log = ''
+    while 1:
+        line = f.readline()
+        if not line: break
+        if line[:10] == '='*10:
+            # Ignore the *last* log entry for each file since it
+            # is the revision since which we are logging.
+            return None
+        if line[:10] == '-'*10: break
+        log = log + line
+    return dateline, file, revline, log
+
+if __name__ == '__main__':
+    main()


Property changes on: vendor/Python/current/Demo/pdist/makechangelog.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/pdist/rcsbump
===================================================================
--- vendor/Python/current/Demo/pdist/rcsbump	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/pdist/rcsbump	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,33 @@
+#!/usr/bin/env python
+# -*- python -*-
+#
+# guido's version, from rcsbump,v 1.2 1995/06/22 21:27:27 bwarsaw Exp
+#
+# Python script for bumping up an RCS major revision number.
+
+import sys
+import re
+import rcslib
+import string
+
+WITHLOCK = 1
+majorrev_re = re.compile('^[0-9]+')
+
+dir = rcslib.RCS()
+
+if sys.argv[1:]:
+    files = sys.argv[1:]
+else:
+    files = dir.listfiles()
+
+for file in files:
+    # get the major revnumber of the file
+    headbranch = dir.info(file)['head']
+    majorrev_re.match(headbranch)
+    majorrev = string.atoi(majorrev_re.group(0)) + 1
+
+    if not dir.islocked(file):
+        dir.checkout(file, WITHLOCK)
+
+    msg = "Bumping major revision number (to %d)" % majorrev
+    dir.checkin((file, "%s.0" % majorrev), msg, "-f")


Property changes on: vendor/Python/current/Demo/pdist/rcsbump
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/pdist/rcsclient.py
===================================================================
--- vendor/Python/current/Demo/pdist/rcsclient.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/pdist/rcsclient.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,71 @@
+"""Customize this file to change the default client etc.
+
+(In general, it is probably be better to make local operation the
+default and to require something like an RCSSERVER environment
+variable to enable remote operation.)
+
+"""
+
+import string
+import os
+
+# These defaults don't belong here -- they should be taken from the
+# environment or from a hidden file in the current directory
+
+HOST = 'voorn.cwi.nl'
+PORT = 4127
+VERBOSE = 1
+LOCAL = 0
+
+import client
+
+
+class RCSProxyClient(client.SecureClient):
+
+    def __init__(self, address, verbose = client.VERBOSE):
+        client.SecureClient.__init__(self, address, verbose)
+
+
+def openrcsclient(opts = []):
+    "open an RCSProxy client based on a list of options returned by getopt"
+    import RCSProxy
+    host = HOST
+    port = PORT
+    verbose = VERBOSE
+    local = LOCAL
+    directory = None
+    for o, a in opts:
+        if o == '-h':
+            host = a
+            if ':' in host:
+                i = string.find(host, ':')
+                host, p = host[:i], host[i+1:]
+                if p:
+                    port = string.atoi(p)
+        if o == '-p':
+            port = string.atoi(a)
+        if o == '-d':
+            directory = a
+        if o == '-v':
+            verbose = verbose + 1
+        if o == '-q':
+            verbose = 0
+        if o == '-L':
+            local = 1
+    if local:
+        import RCSProxy
+        x = RCSProxy.RCSProxyLocal()
+    else:
+        address = (host, port)
+        x = RCSProxyClient(address, verbose)
+    if not directory:
+        try:
+            directory = open(os.path.join("CVS", "Repository")).readline()
+        except IOError:
+            pass
+        else:
+            if directory[-1] == '\n':
+                directory = directory[:-1]
+    if directory:
+        x.cd(directory)
+    return x


Property changes on: vendor/Python/current/Demo/pdist/rcsclient.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/pdist/rcslib.py
===================================================================
--- vendor/Python/current/Demo/pdist/rcslib.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/pdist/rcslib.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,334 @@
+"""RCS interface module.
+
+Defines the class RCS, which represents a directory with rcs version
+files and (possibly) corresponding work files.
+
+"""
+
+
+import fnmatch
+import os
+import re
+import string
+import tempfile
+
+
+class RCS:
+
+    """RCS interface class (local filesystem version).
+
+    An instance of this class represents a directory with rcs version
+    files and (possible) corresponding work files.
+
+    Methods provide access to most rcs operations such as
+    checkin/checkout, access to the rcs metadata (revisions, logs,
+    branches etc.) as well as some filesystem operations such as
+    listing all rcs version files.
+
+    XXX BUGS / PROBLEMS
+
+    - The instance always represents the current directory so it's not
+    very useful to have more than one instance around simultaneously
+
+    """
+
+    # Characters allowed in work file names
+    okchars = string.ascii_letters + string.digits + '-_=+'
+
+    def __init__(self):
+        """Constructor."""
+        pass
+
+    def __del__(self):
+        """Destructor."""
+        pass
+
+    # --- Informational methods about a single file/revision ---
+
+    def log(self, name_rev, otherflags = ''):
+        """Return the full log text for NAME_REV as a string.
+
+        Optional OTHERFLAGS are passed to rlog.
+
+        """
+        f = self._open(name_rev, 'rlog ' + otherflags)
+        data = f.read()
+        status = self._closepipe(f)
+        if status:
+            data = data + "%s: %s" % status
+        elif data[-1] == '\n':
+            data = data[:-1]
+        return data
+
+    def head(self, name_rev):
+        """Return the head revision for NAME_REV"""
+        dict = self.info(name_rev)
+        return dict['head']
+
+    def info(self, name_rev):
+        """Return a dictionary of info (from rlog -h) for NAME_REV
+
+        The dictionary's keys are the keywords that rlog prints
+        (e.g. 'head' and its values are the corresponding data
+        (e.g. '1.3').
+
+        XXX symbolic names and locks are not returned
+
+        """
+        f = self._open(name_rev, 'rlog -h')
+        dict = {}
+        while 1:
+            line = f.readline()
+            if not line: break
+            if line[0] == '\t':
+                # XXX could be a lock or symbolic name
+                # Anything else?
+                continue
+            i = string.find(line, ':')
+            if i > 0:
+                key, value = line[:i], string.strip(line[i+1:])
+                dict[key] = value
+        status = self._closepipe(f)
+        if status:
+            raise IOError, status
+        return dict
+
+    # --- Methods that change files ---
+
+    def lock(self, name_rev):
+        """Set an rcs lock on NAME_REV."""
+        name, rev = self.checkfile(name_rev)
+        cmd = "rcs -l%s %s" % (rev, name)
+        return self._system(cmd)
+
+    def unlock(self, name_rev):
+        """Clear an rcs lock on NAME_REV."""
+        name, rev = self.checkfile(name_rev)
+        cmd = "rcs -u%s %s" % (rev, name)
+        return self._system(cmd)
+
+    def checkout(self, name_rev, withlock=0, otherflags=""):
+        """Check out NAME_REV to its work file.
+
+        If optional WITHLOCK is set, check out locked, else unlocked.
+
+        The optional OTHERFLAGS is passed to co without
+        interpretation.
+
+        Any output from co goes to directly to stdout.
+
+        """
+        name, rev = self.checkfile(name_rev)
+        if withlock: lockflag = "-l"
+        else: lockflag = "-u"
+        cmd = 'co %s%s %s %s' % (lockflag, rev, otherflags, name)
+        return self._system(cmd)
+
+    def checkin(self, name_rev, message=None, otherflags=""):
+        """Check in NAME_REV from its work file.
+
+        The optional MESSAGE argument becomes the checkin message
+        (default "<none>" if None); or the file description if this is
+        a new file.
+
+        The optional OTHERFLAGS argument is passed to ci without
+        interpretation.
+
+        Any output from ci goes to directly to stdout.
+
+        """
+        name, rev = self._unmangle(name_rev)
+        new = not self.isvalid(name)
+        if not message: message = "<none>"
+        if message and message[-1] != '\n':
+            message = message + '\n'
+        lockflag = "-u"
+        if new:
+            f = tempfile.NamedTemporaryFile()
+            f.write(message)
+            f.flush()
+            cmd = 'ci %s%s -t%s %s %s' % \
+                  (lockflag, rev, f.name, otherflags, name)
+        else:
+            message = re.sub(r'([\"$`])', r'\\\1', message)
+            cmd = 'ci %s%s -m"%s" %s %s' % \
+                  (lockflag, rev, message, otherflags, name)
+        return self._system(cmd)
+
+    # --- Exported support methods ---
+
+    def listfiles(self, pat = None):
+        """Return a list of all version files matching optional PATTERN."""
+        files = os.listdir(os.curdir)
+        files = filter(self._isrcs, files)
+        if os.path.isdir('RCS'):
+            files2 = os.listdir('RCS')
+            files2 = filter(self._isrcs, files2)
+            files = files + files2
+        files = map(self.realname, files)
+        return self._filter(files, pat)
+
+    def isvalid(self, name):
+        """Test whether NAME has a version file associated."""
+        namev = self.rcsname(name)
+        return (os.path.isfile(namev) or
+                os.path.isfile(os.path.join('RCS', namev)))
+
+    def rcsname(self, name):
+        """Return the pathname of the version file for NAME.
+
+        The argument can be a work file name or a version file name.
+        If the version file does not exist, the name of the version
+        file that would be created by "ci" is returned.
+
+        """
+        if self._isrcs(name): namev = name
+        else: namev = name + ',v'
+        if os.path.isfile(namev): return namev
+        namev = os.path.join('RCS', os.path.basename(namev))
+        if os.path.isfile(namev): return namev
+        if os.path.isdir('RCS'):
+            return os.path.join('RCS', namev)
+        else:
+            return namev
+
+    def realname(self, namev):
+        """Return the pathname of the work file for NAME.
+
+        The argument can be a work file name or a version file name.
+        If the work file does not exist, the name of the work file
+        that would be created by "co" is returned.
+
+        """
+        if self._isrcs(namev): name = namev[:-2]
+        else: name = namev
+        if os.path.isfile(name): return name
+        name = os.path.basename(name)
+        return name
+
+    def islocked(self, name_rev):
+        """Test whether FILE (which must have a version file) is locked.
+
+        XXX This does not tell you which revision number is locked and
+        ignores any revision you may pass in (by virtue of using rlog
+        -L -R).
+
+        """
+        f = self._open(name_rev, 'rlog -L -R')
+        line = f.readline()
+        status = self._closepipe(f)
+        if status:
+            raise IOError, status
+        if not line: return None
+        if line[-1] == '\n':
+            line = line[:-1]
+        return self.realname(name_rev) == self.realname(line)
+
+    def checkfile(self, name_rev):
+        """Normalize NAME_REV into a (NAME, REV) tuple.
+
+        Raise an exception if there is no corresponding version file.
+
+        """
+        name, rev = self._unmangle(name_rev)
+        if not self.isvalid(name):
+            raise os.error, 'not an rcs file %r' % (name,)
+        return name, rev
+
+    # --- Internal methods ---
+
+    def _open(self, name_rev, cmd = 'co -p', rflag = '-r'):
+        """INTERNAL: open a read pipe to NAME_REV using optional COMMAND.
+
+        Optional FLAG is used to indicate the revision (default -r).
+
+        Default COMMAND is "co -p".
+
+        Return a file object connected by a pipe to the command's
+        output.
+
+        """
+        name, rev = self.checkfile(name_rev)
+        namev = self.rcsname(name)
+        if rev:
+            cmd = cmd + ' ' + rflag + rev
+        return os.popen("%s %r" % (cmd, namev))
+
+    def _unmangle(self, name_rev):
+        """INTERNAL: Normalize NAME_REV argument to (NAME, REV) tuple.
+
+        Raise an exception if NAME contains invalid characters.
+
+        A NAME_REV argument is either NAME string (implying REV='') or
+        a tuple of the form (NAME, REV).
+
+        """
+        if type(name_rev) == type(''):
+            name_rev = name, rev = name_rev, ''
+        else:
+            name, rev = name_rev
+        for c in rev:
+            if c not in self.okchars:
+                raise ValueError, "bad char in rev"
+        return name_rev
+
+    def _closepipe(self, f):
+        """INTERNAL: Close PIPE and print its exit status if nonzero."""
+        sts = f.close()
+        if not sts: return None
+        detail, reason = divmod(sts, 256)
+        if reason == 0: return 'exit', detail   # Exit status
+        signal = reason&0x7F
+        if signal == 0x7F:
+            code = 'stopped'
+            signal = detail
+        else:
+            code = 'killed'
+        if reason&0x80:
+            code = code + '(coredump)'
+        return code, signal
+
+    def _system(self, cmd):
+        """INTERNAL: run COMMAND in a subshell.
+
+        Standard input for the command is taken from /dev/null.
+
+        Raise IOError when the exit status is not zero.
+
+        Return whatever the calling method should return; normally
+        None.
+
+        A derived class may override this method and redefine it to
+        capture stdout/stderr of the command and return it.
+
+        """
+        cmd = cmd + " </dev/null"
+        sts = os.system(cmd)
+        if sts: raise IOError, "command exit status %d" % sts
+
+    def _filter(self, files, pat = None):
+        """INTERNAL: Return a sorted copy of the given list of FILES.
+
+        If a second PATTERN argument is given, only files matching it
+        are kept.  No check for valid filenames is made.
+
+        """
+        if pat:
+            def keep(name, pat = pat):
+                return fnmatch.fnmatch(name, pat)
+            files = filter(keep, files)
+        else:
+            files = files[:]
+        files.sort()
+        return files
+
+    def _remove(self, fn):
+        """INTERNAL: remove FILE without complaints."""
+        try:
+            os.unlink(fn)
+        except os.error:
+            pass
+
+    def _isrcs(self, name):
+        """INTERNAL: Test whether NAME ends in ',v'."""
+        return name[-2:] == ',v'


Property changes on: vendor/Python/current/Demo/pdist/rcslib.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/pdist/rcvs
===================================================================
--- vendor/Python/current/Demo/pdist/rcvs	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/pdist/rcvs	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,8 @@
+#!/usr/bin/env python
+
+import addpack
+addpack.addpack('/home/guido/src/python/Demo/pdist')
+
+import rcvs
+
+rcvs.main()


Property changes on: vendor/Python/current/Demo/pdist/rcvs
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/pdist/rcvs.py
===================================================================
--- vendor/Python/current/Demo/pdist/rcvs.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/pdist/rcvs.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,477 @@
+#! /usr/bin/env python
+
+"""Remote CVS -- command line interface"""
+
+# XXX To do:
+#
+# Bugs:
+# - if the remote file is deleted, "rcvs update" will fail
+#
+# Functionality:
+# - cvs rm
+# - descend into directories (alraedy done for update)
+# - conflict resolution
+# - other relevant commands?
+# - branches
+#
+# - Finesses:
+# - retain file mode's x bits
+# - complain when "nothing known about filename"
+# - edit log message the way CVS lets you edit it
+# - cvs diff -rREVA -rREVB
+# - send mail the way CVS sends it
+#
+# Performance:
+# - cache remote checksums (for every revision ever seen!)
+# - translate symbolic revisions to numeric revisions
+#
+# Reliability:
+# - remote locking
+#
+# Security:
+# - Authenticated RPC?
+
+
+from cvslib import CVS, File
+import md5
+import os
+import string
+import sys
+from cmdfw import CommandFrameWork
+
+
+DEF_LOCAL = 1                           # Default -l
+
+
+class MyFile(File):
+
+    def action(self):
+        """Return a code indicating the update status of this file.
+
+        The possible return values are:
+
+        '=' -- everything's fine
+        '0' -- file doesn't exist anywhere
+        '?' -- exists locally only
+        'A' -- new locally
+        'R' -- deleted locally
+        'U' -- changed remotely, no changes locally
+               (includes new remotely or deleted remotely)
+        'M' -- changed locally, no changes remotely
+        'C' -- conflict: changed locally as well as remotely
+               (includes cases where the file has been added
+               or removed locally and remotely)
+        'D' -- deleted remotely
+        'N' -- new remotely
+        'r' -- get rid of entry
+        'c' -- create entry
+        'u' -- update entry
+
+        (and probably others :-)
+        """
+        if not self.lseen:
+            self.getlocal()
+        if not self.rseen:
+            self.getremote()
+        if not self.eseen:
+            if not self.lsum:
+                if not self.rsum: return '0' # Never heard of
+                else:
+                    return 'N' # New remotely
+            else: # self.lsum
+                if not self.rsum: return '?' # Local only
+                # Local and remote, but no entry
+                if self.lsum == self.rsum:
+                    return 'c' # Restore entry only
+                else: return 'C' # Real conflict
+        else: # self.eseen
+            if not self.lsum:
+                if self.edeleted:
+                    if self.rsum: return 'R' # Removed
+                    else: return 'r' # Get rid of entry
+                else: # not self.edeleted
+                    if self.rsum:
+                        print "warning:",
+                        print self.file,
+                        print "was lost"
+                        return 'U'
+                    else: return 'r' # Get rid of entry
+            else: # self.lsum
+                if not self.rsum:
+                    if self.enew: return 'A' # New locally
+                    else: return 'D' # Deleted remotely
+                else: # self.rsum
+                    if self.enew:
+                        if self.lsum == self.rsum:
+                            return 'u'
+                        else:
+                            return 'C'
+                    if self.lsum == self.esum:
+                        if self.esum == self.rsum:
+                            return '='
+                        else:
+                            return 'U'
+                    elif self.esum == self.rsum:
+                        return 'M'
+                    elif self.lsum == self.rsum:
+                        return 'u'
+                    else:
+                        return 'C'
+
+    def update(self):
+        code = self.action()
+        if code == '=': return
+        print code, self.file
+        if code in ('U', 'N'):
+            self.get()
+        elif code == 'C':
+            print "%s: conflict resolution not yet implemented" % \
+                  self.file
+        elif code == 'D':
+            remove(self.file)
+            self.eseen = 0
+        elif code == 'r':
+            self.eseen = 0
+        elif code in ('c', 'u'):
+            self.eseen = 1
+            self.erev = self.rrev
+            self.enew = 0
+            self.edeleted = 0
+            self.esum = self.rsum
+            self.emtime, self.ectime = os.stat(self.file)[-2:]
+            self.extra = ''
+
+    def commit(self, message = ""):
+        code = self.action()
+        if code in ('A', 'M'):
+            self.put(message)
+            return 1
+        elif code == 'R':
+            print "%s: committing removes not yet implemented" % \
+                  self.file
+        elif code == 'C':
+            print "%s: conflict resolution not yet implemented" % \
+                  self.file
+
+    def diff(self, opts = []):
+        self.action()           # To update lseen, rseen
+        flags = ''
+        rev = self.rrev
+        # XXX should support two rev options too!
+        for o, a in opts:
+            if o == '-r':
+                rev = a
+            else:
+                flags = flags + ' ' + o + a
+        if rev == self.rrev and self.lsum == self.rsum:
+            return
+        flags = flags[1:]
+        fn = self.file
+        data = self.proxy.get((fn, rev))
+        sum = md5.new(data).digest()
+        if self.lsum == sum:
+            return
+        import tempfile
+        tf = tempfile.NamedTemporaryFile()
+        tf.write(data)
+        tf.flush()
+        print 'diff %s -r%s %s' % (flags, rev, fn)
+        sts = os.system('diff %s %s %s' % (flags, tf.name, fn))
+        if sts:
+            print '='*70
+
+    def commitcheck(self):
+        return self.action() != 'C'
+
+    def put(self, message = ""):
+        print "Checking in", self.file, "..."
+        data = open(self.file).read()
+        if not self.enew:
+            self.proxy.lock(self.file)
+        messages = self.proxy.put(self.file, data, message)
+        if messages:
+            print messages
+        self.setentry(self.proxy.head(self.file), self.lsum)
+
+    def get(self):
+        data = self.proxy.get(self.file)
+        f = open(self.file, 'w')
+        f.write(data)
+        f.close()
+        self.setentry(self.rrev, self.rsum)
+
+    def log(self, otherflags):
+        print self.proxy.log(self.file, otherflags)
+
+    def add(self):
+        self.eseen = 0          # While we're hacking...
+        self.esum = self.lsum
+        self.emtime, self.ectime = 0, 0
+        self.erev = ''
+        self.enew = 1
+        self.edeleted = 0
+        self.eseen = 1          # Done
+        self.extra = ''
+
+    def setentry(self, erev, esum):
+        self.eseen = 0          # While we're hacking...
+        self.esum = esum
+        self.emtime, self.ectime = os.stat(self.file)[-2:]
+        self.erev = erev
+        self.enew = 0
+        self.edeleted = 0
+        self.eseen = 1          # Done
+        self.extra = ''
+
+
+SENDMAIL = "/usr/lib/sendmail -t"
+MAILFORM = """To: %s
+Subject: CVS changes: %s
+
+...Message from rcvs...
+
+Committed files:
+        %s
+
+Log message:
+        %s
+"""
+
+
+class RCVS(CVS):
+
+    FileClass = MyFile
+
+    def __init__(self):
+        CVS.__init__(self)
+
+    def update(self, files):
+        for e in self.whichentries(files, 1):
+            e.update()
+
+    def commit(self, files, message = ""):
+        list = self.whichentries(files)
+        if not list: return
+        ok = 1
+        for e in list:
+            if not e.commitcheck():
+                ok = 0
+        if not ok:
+            print "correct above errors first"
+            return
+        if not message:
+            message = raw_input("One-liner: ")
+        committed = []
+        for e in list:
+            if e.commit(message):
+                committed.append(e.file)
+        self.mailinfo(committed, message)
+
+    def mailinfo(self, files, message = ""):
+        towhom = "sjoerd at cwi.nl, jack at cwi.nl" # XXX
+        mailtext = MAILFORM % (towhom, string.join(files),
+                                string.join(files), message)
+        print '-'*70
+        print mailtext
+        print '-'*70
+        ok = raw_input("OK to mail to %s? " % towhom)
+        if string.lower(string.strip(ok)) in ('y', 'ye', 'yes'):
+            p = os.popen(SENDMAIL, "w")
+            p.write(mailtext)
+            sts = p.close()
+            if sts:
+                print "Sendmail exit status %s" % str(sts)
+            else:
+                print "Mail sent."
+        else:
+            print "No mail sent."
+
+    def report(self, files):
+        for e in self.whichentries(files):
+            e.report()
+
+    def diff(self, files, opts):
+        for e in self.whichentries(files):
+            e.diff(opts)
+
+    def add(self, files):
+        if not files:
+            raise RuntimeError, "'cvs add' needs at least one file"
+        list = []
+        for e in self.whichentries(files, 1):
+            e.add()
+
+    def rm(self, files):
+        if not files:
+            raise RuntimeError, "'cvs rm' needs at least one file"
+        raise RuntimeError, "'cvs rm' not yet imlemented"
+
+    def log(self, files, opts):
+        flags = ''
+        for o, a in opts:
+            flags = flags + ' ' + o + a
+        for e in self.whichentries(files):
+            e.log(flags)
+
+    def whichentries(self, files, localfilestoo = 0):
+        if files:
+            list = []
+            for file in files:
+                if self.entries.has_key(file):
+                    e = self.entries[file]
+                else:
+                    e = self.FileClass(file)
+                    self.entries[file] = e
+                list.append(e)
+        else:
+            list = self.entries.values()
+            for file in self.proxy.listfiles():
+                if self.entries.has_key(file):
+                    continue
+                e = self.FileClass(file)
+                self.entries[file] = e
+                list.append(e)
+            if localfilestoo:
+                for file in os.listdir(os.curdir):
+                    if not self.entries.has_key(file) \
+                       and not self.ignored(file):
+                        e = self.FileClass(file)
+                        self.entries[file] = e
+                        list.append(e)
+            list.sort()
+        if self.proxy:
+            for e in list:
+                if e.proxy is None:
+                    e.proxy = self.proxy
+        return list
+
+
+class rcvs(CommandFrameWork):
+
+    GlobalFlags = 'd:h:p:qvL'
+    UsageMessage = \
+"usage: rcvs [-d directory] [-h host] [-p port] [-q] [-v] [subcommand arg ...]"
+    PostUsageMessage = \
+            "If no subcommand is given, the status of all files is listed"
+
+    def __init__(self):
+        """Constructor."""
+        CommandFrameWork.__init__(self)
+        self.proxy = None
+        self.cvs = RCVS()
+
+    def close(self):
+        if self.proxy:
+            self.proxy._close()
+        self.proxy = None
+
+    def recurse(self):
+        self.close()
+        names = os.listdir(os.curdir)
+        for name in names:
+            if name == os.curdir or name == os.pardir:
+                continue
+            if name == "CVS":
+                continue
+            if not os.path.isdir(name):
+                continue
+            if os.path.islink(name):
+                continue
+            print "--- entering subdirectory", name, "---"
+            os.chdir(name)
+            try:
+                if os.path.isdir("CVS"):
+                    self.__class__().run()
+                else:
+                    self.recurse()
+            finally:
+                os.chdir(os.pardir)
+                print "--- left subdirectory", name, "---"
+
+    def options(self, opts):
+        self.opts = opts
+
+    def ready(self):
+        import rcsclient
+        self.proxy = rcsclient.openrcsclient(self.opts)
+        self.cvs.setproxy(self.proxy)
+        self.cvs.getentries()
+
+    def default(self):
+        self.cvs.report([])
+
+    def do_report(self, opts, files):
+        self.cvs.report(files)
+
+    def do_update(self, opts, files):
+        """update [-l] [-R] [file] ..."""
+        local = DEF_LOCAL
+        for o, a in opts:
+            if o == '-l': local = 1
+            if o == '-R': local = 0
+        self.cvs.update(files)
+        self.cvs.putentries()
+        if not local and not files:
+            self.recurse()
+    flags_update = '-lR'
+    do_up = do_update
+    flags_up = flags_update
+
+    def do_commit(self, opts, files):
+        """commit [-m message] [file] ..."""
+        message = ""
+        for o, a in opts:
+            if o == '-m': message = a
+        self.cvs.commit(files, message)
+        self.cvs.putentries()
+    flags_commit = 'm:'
+    do_com = do_commit
+    flags_com = flags_commit
+
+    def do_diff(self, opts, files):
+        """diff [difflags] [file] ..."""
+        self.cvs.diff(files, opts)
+    flags_diff = 'cbitwcefhnlr:sD:S:'
+    do_dif = do_diff
+    flags_dif = flags_diff
+
+    def do_add(self, opts, files):
+        """add file ..."""
+        if not files:
+            print "'rcvs add' requires at least one file"
+            return
+        self.cvs.add(files)
+        self.cvs.putentries()
+
+    def do_remove(self, opts, files):
+        """remove file ..."""
+        if not files:
+            print "'rcvs remove' requires at least one file"
+            return
+        self.cvs.remove(files)
+        self.cvs.putentries()
+    do_rm = do_remove
+
+    def do_log(self, opts, files):
+        """log [rlog-options] [file] ..."""
+        self.cvs.log(files, opts)
+    flags_log = 'bhLNRtd:s:V:r:'
+
+
+def remove(fn):
+    try:
+        os.unlink(fn)
+    except os.error:
+        pass
+
+
+def main():
+    r = rcvs()
+    try:
+        r.run()
+    finally:
+        r.close()
+
+
+if __name__ == "__main__":
+    main()


Property changes on: vendor/Python/current/Demo/pdist/rcvs.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/pdist/rrcs
===================================================================
--- vendor/Python/current/Demo/pdist/rrcs	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/pdist/rrcs	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,8 @@
+#!/usr/bin/env python
+
+import addpack
+addpack.addpack('/home/guido/src/python/Demo/pdist')
+
+import rrcs
+
+rrcs.main()


Property changes on: vendor/Python/current/Demo/pdist/rrcs
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/pdist/rrcs.py
===================================================================
--- vendor/Python/current/Demo/pdist/rrcs.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/pdist/rrcs.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,160 @@
+#! /usr/bin/env python
+
+"Remote RCS -- command line interface"
+
+import sys
+import os
+import getopt
+import string
+import md5
+import tempfile
+from rcsclient import openrcsclient
+
+def main():
+    sys.stdout = sys.stderr
+    try:
+        opts, rest = getopt.getopt(sys.argv[1:], 'h:p:d:qvL')
+        if not rest:
+            cmd = 'head'
+        else:
+            cmd, rest = rest[0], rest[1:]
+        if not commands.has_key(cmd):
+            raise getopt.error, "unknown command"
+        coptset, func = commands[cmd]
+        copts, files = getopt.getopt(rest, coptset)
+    except getopt.error, msg:
+        print msg
+        print "usage: rrcs [options] command [options] [file] ..."
+        print "where command can be:"
+        print "      ci|put      # checkin the given files"
+        print "      co|get      # checkout"
+        print "      info        # print header info"
+        print "      head        # print revision of head branch"
+        print "      list        # list filename if valid"
+        print "      log         # print full log"
+        print "      diff        # diff rcs file and work file"
+        print "if no files are given, all remote rcs files are assumed"
+        sys.exit(2)
+    x = openrcsclient(opts)
+    if not files:
+        files = x.listfiles()
+    for fn in files:
+        try:
+            func(x, copts, fn)
+        except (IOError, os.error), msg:
+            print "%s: %s" % (fn, msg)
+
+def checkin(x, copts, fn):
+    f = open(fn)
+    data = f.read()
+    f.close()
+    new = not x.isvalid(fn)
+    if not new and same(x, copts, fn, data):
+        print "%s: unchanged since last checkin" % fn
+        return
+    print "Checking in", fn, "..."
+    message = asklogmessage(new)
+    messages = x.put(fn, data, message)
+    if messages:
+        print messages
+
+def checkout(x, copts, fn):
+    data = x.get(fn)
+    f = open(fn, 'w')
+    f.write(data)
+    f.close()
+
+def lock(x, copts, fn):
+    x.lock(fn)
+
+def unlock(x, copts, fn):
+    x.unlock(fn)
+
+def info(x, copts, fn):
+    dict = x.info(fn)
+    keys = dict.keys()
+    keys.sort()
+    for key in keys:
+        print key + ':', dict[key]
+    print '='*70
+
+def head(x, copts, fn):
+    head = x.head(fn)
+    print fn, head
+
+def list(x, copts, fn):
+    if x.isvalid(fn):
+        print fn
+
+def log(x, copts, fn):
+    flags = ''
+    for o, a in copts:
+        flags = flags + ' ' + o + a
+    flags = flags[1:]
+    messages = x.log(fn, flags)
+    print messages
+
+def diff(x, copts, fn):
+    if same(x, copts, fn):
+        return
+    flags = ''
+    for o, a in copts:
+        flags = flags + ' ' + o + a
+    flags = flags[1:]
+    data = x.get(fn)
+    tf = tempfile.NamedTemporaryFile()
+    tf.write(data)
+    tf.flush()
+    print 'diff %s -r%s %s' % (flags, x.head(fn), fn)
+    sts = os.system('diff %s %s %s' % (flags, tf.name, fn))
+    if sts:
+        print '='*70
+
+def same(x, copts, fn, data = None):
+    if data is None:
+        f = open(fn)
+        data = f.read()
+        f.close()
+    lsum = md5.new(data).digest()
+    rsum = x.sum(fn)
+    return lsum == rsum
+
+def asklogmessage(new):
+    if new:
+        print "enter description,",
+    else:
+        print "enter log message,",
+    print "terminate with single '.' or end of file:"
+    if new:
+        print "NOTE: This is NOT the log message!"
+    message = ""
+    while 1:
+        sys.stderr.write(">> ")
+        sys.stderr.flush()
+        line = sys.stdin.readline()
+        if not line or line == '.\n': break
+        message = message + line
+    return message
+
+def remove(fn):
+    try:
+        os.unlink(fn)
+    except os.error:
+        pass
+
+commands = {
+        'ci': ('', checkin),
+        'put': ('', checkin),
+        'co': ('', checkout),
+        'get': ('', checkout),
+        'info': ('', info),
+        'head': ('', head),
+        'list': ('', list),
+        'lock': ('', lock),
+        'unlock': ('', unlock),
+        'log': ('bhLRtd:l:r:s:w:V:', log),
+        'diff': ('c', diff),
+        }
+
+if __name__ == '__main__':
+    main()


Property changes on: vendor/Python/current/Demo/pdist/rrcs.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/pdist/security.py
===================================================================
--- vendor/Python/current/Demo/pdist/security.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/pdist/security.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,33 @@
+class Security:
+
+    def __init__(self):
+        import os
+        env = os.environ
+        if env.has_key('PYTHON_KEYFILE'):
+            keyfile = env['PYTHON_KEYFILE']
+        else:
+            keyfile = '.python_keyfile'
+            if env.has_key('HOME'):
+                keyfile = os.path.join(env['HOME'], keyfile)
+            if not os.path.exists(keyfile):
+                import sys
+                for dir in sys.path:
+                    kf = os.path.join(dir, keyfile)
+                    if os.path.exists(kf):
+                        keyfile = kf
+                        break
+        try:
+            self._key = eval(open(keyfile).readline())
+        except IOError:
+            raise IOError, "python keyfile %s: cannot open" % keyfile
+
+    def _generate_challenge(self):
+        import random
+        return random.randint(100, 100000)
+
+    def _compare_challenge_response(self, challenge, response):
+        return self._encode_challenge(challenge) == response
+
+    def _encode_challenge(self, challenge):
+        p, m = self._key
+        return pow(long(challenge), p, m)


Property changes on: vendor/Python/current/Demo/pdist/security.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/pdist/server.py
===================================================================
--- vendor/Python/current/Demo/pdist/server.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/pdist/server.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,145 @@
+"""RPC Server module."""
+
+import sys
+import socket
+import pickle
+from fnmatch import fnmatch
+from repr import repr
+
+
+# Default verbosity (0 = silent, 1 = print connections, 2 = print requests too)
+VERBOSE = 1
+
+
+class Server:
+
+    """RPC Server class.  Derive a class to implement a particular service."""
+
+    def __init__(self, address, verbose = VERBOSE):
+        if type(address) == type(0):
+            address = ('', address)
+        self._address = address
+        self._verbose = verbose
+        self._socket = None
+        self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        self._socket.bind(address)
+        self._socket.listen(1)
+        self._listening = 1
+
+    def _setverbose(self, verbose):
+        self._verbose = verbose
+
+    def __del__(self):
+        self._close()
+
+    def _close(self):
+        self._listening = 0
+        if self._socket:
+            self._socket.close()
+        self._socket = None
+
+    def _serverloop(self):
+        while self._listening:
+            self._serve()
+
+    def _serve(self):
+        if self._verbose: print "Wait for connection ..."
+        conn, address = self._socket.accept()
+        if self._verbose: print "Accepted connection from %s" % repr(address)
+        if not self._verify(conn, address):
+            print "*** Connection from %s refused" % repr(address)
+            conn.close()
+            return
+        rf = conn.makefile('r')
+        wf = conn.makefile('w')
+        ok = 1
+        while ok:
+            wf.flush()
+            if self._verbose > 1: print "Wait for next request ..."
+            ok = self._dorequest(rf, wf)
+
+    _valid = ['192.16.201.*', '192.16.197.*', '132.151.1.*', '129.6.64.*']
+
+    def _verify(self, conn, address):
+        host, port = address
+        for pat in self._valid:
+            if fnmatch(host, pat): return 1
+        return 0
+
+    def _dorequest(self, rf, wf):
+        rp = pickle.Unpickler(rf)
+        try:
+            request = rp.load()
+        except EOFError:
+            return 0
+        if self._verbose > 1: print "Got request: %s" % repr(request)
+        try:
+            methodname, args, id = request
+            if '.' in methodname:
+                reply = (None, self._special(methodname, args), id)
+            elif methodname[0] == '_':
+                raise NameError, "illegal method name %s" % repr(methodname)
+            else:
+                method = getattr(self, methodname)
+                reply = (None, apply(method, args), id)
+        except:
+            reply = (sys.exc_type, sys.exc_value, id)
+        if id < 0 and reply[:2] == (None, None):
+            if self._verbose > 1: print "Suppress reply"
+            return 1
+        if self._verbose > 1: print "Send reply: %s" % repr(reply)
+        wp = pickle.Pickler(wf)
+        wp.dump(reply)
+        return 1
+
+    def _special(self, methodname, args):
+        if methodname == '.methods':
+            if not hasattr(self, '_methods'):
+                self._methods = tuple(self._listmethods())
+            return self._methods
+        raise NameError, "unrecognized special method name %s" % repr(methodname)
+
+    def _listmethods(self, cl=None):
+        if not cl: cl = self.__class__
+        names = cl.__dict__.keys()
+        names = filter(lambda x: x[0] != '_', names)
+        names.sort()
+        for base in cl.__bases__:
+            basenames = self._listmethods(base)
+            basenames = filter(lambda x, names=names: x not in names, basenames)
+            names[len(names):] = basenames
+        return names
+
+
+from security import Security
+
+
+class SecureServer(Server, Security):
+
+    def __init__(self, *args):
+        apply(Server.__init__, (self,) + args)
+        Security.__init__(self)
+
+    def _verify(self, conn, address):
+        import string
+        challenge = self._generate_challenge()
+        conn.send("%d\n" % challenge)
+        response = ""
+        while "\n" not in response and len(response) < 100:
+            data = conn.recv(100)
+            if not data:
+                break
+            response = response + data
+        try:
+            response = string.atol(string.strip(response))
+        except string.atol_error:
+            if self._verbose > 0:
+                print "Invalid response syntax", repr(response)
+            return 0
+        if not self._compare_challenge_response(challenge, response):
+            if self._verbose > 0:
+                print "Invalid response value", repr(response)
+            return 0
+        if self._verbose > 1:
+            print "Response matches challenge.  Go ahead!"
+        return 1


Property changes on: vendor/Python/current/Demo/pdist/server.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/pdist/sumtree.py
===================================================================
--- vendor/Python/current/Demo/pdist/sumtree.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/pdist/sumtree.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,24 @@
+import time
+import FSProxy
+
+def main():
+    t1 = time.time()
+    #proxy = FSProxy.FSProxyClient(('voorn.cwi.nl', 4127))
+    proxy = FSProxy.FSProxyLocal()
+    sumtree(proxy)
+    proxy._close()
+    t2 = time.time()
+    print t2-t1, "seconds"
+    raw_input("[Return to exit] ")
+
+def sumtree(proxy):
+    print "PWD =", proxy.pwd()
+    files = proxy.listfiles()
+    proxy.infolist(files)
+    subdirs = proxy.listsubdirs()
+    for name in subdirs:
+        proxy.cd(name)
+        sumtree(proxy)
+        proxy.back()
+
+main()


Property changes on: vendor/Python/current/Demo/pdist/sumtree.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/pysvr/README
===================================================================
--- vendor/Python/current/Demo/pysvr/README	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/pysvr/README	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,9 @@
+This is an example of a multi-threaded C application embedding a
+Python interpreter.
+
+The particular application is a multi-threaded telnet-like server that
+provides you with a Python prompt (instead of a shell prompt).
+
+The file pysvr.py is a prototype in Python.
+
+THIS APPLICATION IS NOT SECURE -- ONLY USE IT FOR TESTING!

Added: vendor/Python/current/Demo/pysvr/pysvr.c
===================================================================
--- vendor/Python/current/Demo/pysvr/pysvr.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/pysvr/pysvr.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,370 @@
+/* A multi-threaded telnet-like server that gives a Python prompt.
+
+Usage: pysvr [port]
+
+For security reasons, it only accepts requests from the current host.
+This can still be insecure, but restricts violations from people who
+can log in on your machine.  Use with caution!
+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#include <pthread.h>
+#include <getopt.h>
+
+/* XXX Umpfh.
+   Python.h defines a typedef destructor, which conflicts with pthread.h.
+   So Python.h must be included after pthread.h. */
+
+#include "Python.h"
+
+extern int Py_VerboseFlag;
+
+#ifndef PORT
+#define PORT 4000
+#endif
+
+struct workorder {
+	int conn;
+	struct sockaddr_in addr;
+};
+
+/* Forward */
+static void init_python(void);
+static void usage(void);
+static void oprogname(void);
+static void main_thread(int);
+static void create_thread(int, struct sockaddr_in *);
+static void *service_thread(struct workorder *);
+static void run_interpreter(FILE *, FILE *);
+static int run_command(char *, PyObject *);
+static void ps(void);
+
+static char *progname = "pysvr";
+
+static PyThreadState *gtstate;
+
+main(int argc, char **argv)
+{
+	int port = PORT;
+	int c;
+
+	if (argc > 0 && argv[0] != NULL && argv[0][0] != '\0')
+		progname = argv[0];
+
+	while ((c = getopt(argc, argv, "v")) != EOF) {
+		switch (c) {
+		case 'v':
+			Py_VerboseFlag++;
+			break;
+		default:
+			usage();
+		}
+	}
+
+	if (optind < argc) {
+		if (optind+1 < argc) {
+			oprogname();
+			fprintf(stderr, "too many arguments\n");
+			usage();
+		}
+		port = atoi(argv[optind]);
+		if (port <= 0) {
+			fprintf(stderr, "bad port (%s)\n", argv[optind]);
+			usage();
+		}
+	}
+
+	main_thread(port);
+
+	fprintf(stderr, "Bye.\n");
+
+	exit(0);
+}
+
+static char usage_line[] = "usage: %s [port]\n";
+
+static void
+usage(void)
+{
+	fprintf(stderr, usage_line, progname);
+	exit(2);
+}
+
+static void
+main_thread(int port)
+{
+	int sock, conn, size, i;
+	struct sockaddr_in addr, clientaddr;
+
+	sock = socket(PF_INET, SOCK_STREAM, 0);
+	if (sock < 0) {
+		oprogname();
+		perror("can't create socket");
+		exit(1);
+	}
+
+#ifdef SO_REUSEADDR
+	i = 1;
+	setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &i, sizeof i);
+#endif
+
+	memset((char *)&addr, '\0', sizeof addr);
+	addr.sin_family = AF_INET;
+	addr.sin_port = htons(port);
+	addr.sin_addr.s_addr = 0L;
+	if (bind(sock, (struct sockaddr *)&addr, sizeof addr) < 0) {
+		oprogname();
+		perror("can't bind socket to address");
+		exit(1);
+	}
+
+	if (listen(sock, 5) < 0) {
+		oprogname();
+		perror("can't listen on socket");
+		exit(1);
+	}
+
+	fprintf(stderr, "Listening on port %d...\n", port);
+
+	for (i = 0; ; i++) {
+		size = sizeof clientaddr;
+		memset((char *) &clientaddr, '\0', size);
+		conn = accept(sock, (struct sockaddr *) &clientaddr, &size);
+		if (conn < 0) {
+			oprogname();
+			perror("can't accept connection from socket");
+			exit(1);
+		}
+
+		size = sizeof addr;
+		memset((char *) &addr, '\0', size);
+		if (getsockname(conn, (struct sockaddr *)&addr, &size) < 0) {
+			oprogname();
+			perror("can't get socket name of connection");
+			exit(1);
+		}
+		if (clientaddr.sin_addr.s_addr != addr.sin_addr.s_addr) {
+			oprogname();
+			perror("connection from non-local host refused");
+			fprintf(stderr, "(addr=%lx, clientaddr=%lx)\n",
+				ntohl(addr.sin_addr.s_addr),
+				ntohl(clientaddr.sin_addr.s_addr));
+			close(conn);
+			continue;
+		}
+		if (i == 4) {
+			close(conn);
+			break;
+		}
+		create_thread(conn, &clientaddr);
+	}
+
+	close(sock);
+
+	if (gtstate) {
+		PyEval_AcquireThread(gtstate);
+		gtstate = NULL;
+		Py_Finalize();
+		/* And a second time, just because we can. */
+		Py_Finalize(); /* This should be harmless. */
+	}
+	exit(0);
+}
+
+static void
+create_thread(int conn, struct sockaddr_in *addr)
+{
+	struct workorder *work;
+	pthread_t tdata;
+
+	work = malloc(sizeof(struct workorder));
+	if (work == NULL) {
+		oprogname();
+		fprintf(stderr, "out of memory for thread.\n");
+		close(conn);
+		return;
+	}
+	work->conn = conn;
+	work->addr = *addr;
+
+	init_python();
+
+	if (pthread_create(&tdata, NULL, (void *)service_thread, work) < 0) {
+		oprogname();
+		perror("can't create new thread");
+		close(conn);
+		return;
+	}
+
+	if (pthread_detach(tdata) < 0) {
+		oprogname();
+		perror("can't detach from thread");
+	}
+}
+
+static PyThreadState *the_tstate;
+static PyInterpreterState *the_interp;
+static PyObject *the_builtins;
+
+static void
+init_python(void)
+{
+	if (gtstate)
+		return;
+	Py_Initialize(); /* Initialize the interpreter */
+	PyEval_InitThreads(); /* Create (and acquire) the interpreter lock */
+	gtstate = PyEval_SaveThread(); /* Release the thread state */
+}
+
+static void *
+service_thread(struct workorder *work)
+{
+	FILE *input, *output;
+
+	fprintf(stderr, "Start thread for connection %d.\n", work->conn);
+
+	ps();
+
+	input = fdopen(work->conn, "r");
+	if (input == NULL) {
+		oprogname();
+		perror("can't create input stream");
+		goto done;
+	}
+
+	output = fdopen(work->conn, "w");
+	if (output == NULL) {
+		oprogname();
+		perror("can't create output stream");
+		fclose(input);
+		goto done;
+	}
+
+	setvbuf(input, NULL, _IONBF, 0);
+	setvbuf(output, NULL, _IONBF, 0);
+
+	run_interpreter(input, output);
+
+	fclose(input);
+	fclose(output);
+
+  done:
+	fprintf(stderr, "End thread for connection %d.\n", work->conn);
+	close(work->conn);
+	free(work);
+}
+
+static void
+oprogname(void)
+{
+	int save = errno;
+	fprintf(stderr, "%s: ", progname);
+	errno = save;
+}
+
+static void
+run_interpreter(FILE *input, FILE *output)
+{
+	PyThreadState *tstate;
+	PyObject *new_stdin, *new_stdout;
+	PyObject *mainmod, *globals;
+	char buffer[1000];
+	char *p, *q;
+	int n, end;
+
+	PyEval_AcquireLock();
+	tstate = Py_NewInterpreter();
+	if (tstate == NULL) {
+		fprintf(output, "Sorry -- can't create an interpreter\n");
+		return;
+	}
+
+	mainmod = PyImport_AddModule("__main__");
+	globals = PyModule_GetDict(mainmod);
+	Py_INCREF(globals);
+
+	new_stdin = PyFile_FromFile(input, "<socket-in>", "r", NULL);
+	new_stdout = PyFile_FromFile(output, "<socket-out>", "w", NULL);
+
+	PySys_SetObject("stdin", new_stdin);
+	PySys_SetObject("stdout", new_stdout);
+	PySys_SetObject("stderr", new_stdout);
+
+	for (n = 1; !PyErr_Occurred(); n++) {
+		Py_BEGIN_ALLOW_THREADS
+		fprintf(output, "%d> ", n);
+		p = fgets(buffer, sizeof buffer, input);
+		Py_END_ALLOW_THREADS
+
+		if (p == NULL)
+			break;
+		if (p[0] == '\377' && p[1] == '\354')
+			break;
+
+		q = strrchr(p, '\r');
+		if (q && q[1] == '\n' && q[2] == '\0') {
+			*q++ = '\n';
+			*q++ = '\0';
+		}
+
+		while (*p && isspace(*p))
+			p++;
+		if (p[0] == '#' || p[0] == '\0')
+			continue;
+
+		end = run_command(buffer, globals);
+		if (end < 0)
+			PyErr_Print();
+
+		if (end)
+			break;
+	}
+
+	Py_XDECREF(globals);
+	Py_XDECREF(new_stdin);
+	Py_XDECREF(new_stdout);
+
+	Py_EndInterpreter(tstate);
+	PyEval_ReleaseLock();
+
+	fprintf(output, "Goodbye!\n");
+}
+
+static int
+run_command(char *buffer, PyObject *globals)
+{
+	PyObject *m, *d, *v;
+	fprintf(stderr, "run_command: %s", buffer);
+	if (strchr(buffer, '\n') == NULL)
+		fprintf(stderr, "\n");
+	v = PyRun_String(buffer, Py_single_input, globals, globals);
+	if (v == NULL) {
+		if (PyErr_Occurred() == PyExc_SystemExit) {
+			PyErr_Clear();
+			return 1;
+		}
+		PyErr_Print();
+		return 0;
+	}
+	Py_DECREF(v);
+	return 0;
+}
+
+static void
+ps(void)
+{
+	char buffer[100];
+	PyOS_snprintf(buffer, sizeof(buffer),
+		      "ps -l -p %d </dev/null | sed 1d\n", getpid());
+	system(buffer);
+}

Added: vendor/Python/current/Demo/pysvr/pysvr.py
===================================================================
--- vendor/Python/current/Demo/pysvr/pysvr.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/pysvr/pysvr.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,124 @@
+#! /usr/bin/env python
+
+"""A multi-threaded telnet-like server that gives a Python prompt.
+
+This is really a prototype for the same thing in C.
+
+Usage: pysvr.py [port]
+
+For security reasons, it only accepts requests from the current host.
+This can still be insecure, but restricts violations from people who
+can log in on your machine.  Use with caution!
+
+"""
+
+import sys, os, string, getopt, thread, socket, traceback
+
+PORT = 4000                             # Default port
+
+def main():
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], "")
+        if len(args) > 1:
+            raise getopt.error, "Too many arguments."
+    except getopt.error, msg:
+        usage(msg)
+    for o, a in opts:
+        pass
+    if args:
+        try:
+            port = string.atoi(args[0])
+        except ValueError, msg:
+            usage(msg)
+    else:
+        port = PORT
+    main_thread(port)
+
+def usage(msg=None):
+    sys.stdout = sys.stderr
+    if msg:
+        print msg
+    print "\n", __doc__,
+    sys.exit(2)
+
+def main_thread(port):
+    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+    sock.bind(("", port))
+    sock.listen(5)
+    print "Listening on port", port, "..."
+    while 1:
+        (conn, addr) = sock.accept()
+        if addr[0] != conn.getsockname()[0]:
+            conn.close()
+            print "Refusing connection from non-local host", addr[0], "."
+            continue
+        thread.start_new_thread(service_thread, (conn, addr))
+        del conn, addr
+
+def service_thread(conn, addr):
+    (caddr, cport) = addr
+    print "Thread %s has connection from %s.\n" % (str(thread.get_ident()),
+                                                   caddr),
+    stdin = conn.makefile("r")
+    stdout = conn.makefile("w", 0)
+    run_interpreter(stdin, stdout)
+    print "Thread %s is done.\n" % str(thread.get_ident()),
+
+def run_interpreter(stdin, stdout):
+    globals = {}
+    try:
+        str(sys.ps1)
+    except:
+        sys.ps1 = ">>> "
+    source = ""
+    while 1:
+        stdout.write(sys.ps1)
+        line = stdin.readline()
+        if line[:2] == '\377\354':
+            line = ""
+        if not line and not source:
+            break
+        if line[-2:] == '\r\n':
+            line = line[:-2] + '\n'
+        source = source + line
+        try:
+            code = compile_command(source)
+        except SyntaxError, err:
+            source = ""
+            traceback.print_exception(SyntaxError, err, None, file=stdout)
+            continue
+        if not code:
+            continue
+        source = ""
+        try:
+            run_command(code, stdin, stdout, globals)
+        except SystemExit, how:
+            if how:
+                try:
+                    how = str(how)
+                except:
+                    how = ""
+                stdout.write("Exit %s\n" % how)
+            break
+    stdout.write("\nGoodbye.\n")
+
+def run_command(code, stdin, stdout, globals):
+    save = sys.stdin, sys.stdout, sys.stderr
+    try:
+        sys.stdout = sys.stderr = stdout
+        sys.stdin = stdin
+        try:
+            exec code in globals
+        except SystemExit, how:
+            raise SystemExit, how, sys.exc_info()[2]
+        except:
+            type, value, tb = sys.exc_info()
+            if tb: tb = tb.tb_next
+            traceback.print_exception(type, value, tb)
+            del tb
+    finally:
+        sys.stdin, sys.stdout, sys.stderr = save
+
+from code import compile_command
+
+main()


Property changes on: vendor/Python/current/Demo/pysvr/pysvr.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/rpc/MANIFEST
===================================================================
--- vendor/Python/current/Demo/rpc/MANIFEST	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/rpc/MANIFEST	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,10 @@
+   File Name		Archive #	Description
+-----------------------------------------------------------
+ MANIFEST                   1	This shipping list
+ README                     1	
+ T.py                       1	
+ mountclient.py             1	
+ nfsclient.py               1	
+ rpc.py                     1	
+ test                       1
+ xdr.py                     1	

Added: vendor/Python/current/Demo/rpc/README
===================================================================
--- vendor/Python/current/Demo/rpc/README	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/rpc/README	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,31 @@
+This is a Python interface to Sun RPC, designed and implemented mostly
+by reading the Internet RFCs about the subject.
+
+*** NOTE: xdr.py has evolved into the standard module xdrlib.py ***
+
+There are two library modules, xdr.py and rpc.py, and several example
+clients: mountclient.py, nfsclient.py, and rnusersclient.py,
+implementing the NFS Mount protocol, (part of) the NFS protocol, and
+the "rnusers" protocol (used by rusers(1)), respectively.  The latter
+demonstrates the use of broadcast via the Port mapper's CALLIT
+procedure.
+
+There is also a way to create servers in Python.
+
+To test the nfs client, run it from the shell with something like this:
+
+  python -c 'import nfsclient; nfsclient.test()' [hostname [filesystemname]]
+
+When called without a filesystemname, it lists the filesystems at the
+host; default host is the local machine.
+
+Other clients are tested similarly.
+
+For hostname, use e.g. wuarchive.wustl.edu or gatekeeper.dec.com (two
+hosts that are known to export NFS filesystems with little restrictions).
+
+There are now two different RPC compilers:
+
+1) Wim Lewis rpcgen.py found on http://www.omnigroup.com/~wiml/soft/stale-index.html#python. 
+
+2) Peter Åstrands rpcgen.py, which is part of "pynfs" (http://www.cendio.se/~peter/pynfs/). 

Added: vendor/Python/current/Demo/rpc/T.py
===================================================================
--- vendor/Python/current/Demo/rpc/T.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/rpc/T.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,22 @@
+# Simple interface to report execution times of program fragments.
+# Call TSTART() to reset the timer, TSTOP(...) to report times.
+
+import sys, os, time
+
+def TSTART():
+    global t0, t1
+    u, s, cu, cs = os.times()
+    t0 = u+cu, s+cs, time.time()
+
+def TSTOP(*label):
+    global t0, t1
+    u, s, cu, cs = os.times()
+    t1 = u+cu, s+cs, time.time()
+    tt = []
+    for i in range(3):
+        tt.append(t1[i] - t0[i])
+    [u, s, r] = tt
+    msg = ''
+    for x in label: msg = msg + (x + ' ')
+    msg = msg + '%r user, %r sys, %r real\n' % (u, s, r)
+    sys.stderr.write(msg)

Added: vendor/Python/current/Demo/rpc/mountclient.py
===================================================================
--- vendor/Python/current/Demo/rpc/mountclient.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/rpc/mountclient.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,202 @@
+# Mount RPC client -- RFC 1094 (NFS), Appendix A
+
+# This module demonstrates how to write your own RPC client in Python.
+# When this example was written, there was no RPC compiler for
+# Python. Without such a compiler, you must first create classes
+# derived from Packer and Unpacker to handle the data types for the
+# server you want to interface to.  You then write the client class.
+# If you want to support both the TCP and the UDP version of a
+# protocol, use multiple inheritance as shown below.
+
+
+import rpc
+from rpc import Packer, Unpacker, TCPClient, UDPClient
+
+
+# Program number and version for the mount protocol
+MOUNTPROG = 100005
+MOUNTVERS = 1
+
+# Size of the 'fhandle' opaque structure
+FHSIZE = 32
+
+
+# Packer derived class for Mount protocol clients.
+# The only thing we need to pack beyond basic types is an 'fhandle'
+
+class MountPacker(Packer):
+
+    def pack_fhandle(self, fhandle):
+        self.pack_fopaque(FHSIZE, fhandle)
+
+
+# Unpacker derived class for Mount protocol clients.
+# The important types we need to unpack are fhandle, fhstatus,
+# mountlist and exportlist; mountstruct, exportstruct and groups are
+# used to unpack components of mountlist and exportlist and the
+# corresponding functions are passed as function argument to the
+# generic unpack_list function.
+
+class MountUnpacker(Unpacker):
+
+    def unpack_fhandle(self):
+        return self.unpack_fopaque(FHSIZE)
+
+    def unpack_fhstatus(self):
+        status = self.unpack_uint()
+        if status == 0:
+            fh = self.unpack_fhandle()
+        else:
+            fh = None
+        return status, fh
+
+    def unpack_mountlist(self):
+        return self.unpack_list(self.unpack_mountstruct)
+
+    def unpack_mountstruct(self):
+        hostname = self.unpack_string()
+        directory = self.unpack_string()
+        return (hostname, directory)
+
+    def unpack_exportlist(self):
+        return self.unpack_list(self.unpack_exportstruct)
+
+    def unpack_exportstruct(self):
+        filesys = self.unpack_string()
+        groups = self.unpack_groups()
+        return (filesys, groups)
+
+    def unpack_groups(self):
+        return self.unpack_list(self.unpack_string)
+
+
+# These are the procedures specific to the Mount client class.
+# Think of this as a derived class of either TCPClient or UDPClient.
+
+class PartialMountClient:
+
+    # This method is called by Client.__init__ to initialize
+    # self.packer and self.unpacker
+    def addpackers(self):
+        self.packer = MountPacker()
+        self.unpacker = MountUnpacker('')
+
+    # This method is called by Client.__init__ to bind the socket
+    # to a particular network interface and port.  We use the
+    # default network interface, but if we're running as root,
+    # we want to bind to a reserved port
+    def bindsocket(self):
+        import os
+        try:
+            uid = os.getuid()
+        except AttributeError:
+            uid = 1
+        if uid == 0:
+            port = rpc.bindresvport(self.sock, '')
+            # 'port' is not used
+        else:
+            self.sock.bind(('', 0))
+
+    # This function is called to cough up a suitable
+    # authentication object for a call to procedure 'proc'.
+    def mkcred(self):
+        if self.cred == None:
+            self.cred = rpc.AUTH_UNIX, rpc.make_auth_unix_default()
+        return self.cred
+
+    # The methods Mnt, Dump etc. each implement one Remote
+    # Procedure Call.  This is done by calling self.make_call()
+    # with as arguments:
+    #
+    # - the procedure number
+    # - the arguments (or None)
+    # - the "packer" function for the arguments (or None)
+    # - the "unpacker" function for the return value (or None)
+    #
+    # The packer and unpacker function, if not None, *must* be
+    # methods of self.packer and self.unpacker, respectively.
+    # A value of None means that there are no arguments or is no
+    # return value, respectively.
+    #
+    # The return value from make_call() is the return value from
+    # the remote procedure call, as unpacked by the "unpacker"
+    # function, or None if the unpacker function is None.
+    #
+    # (Even if you expect a result of None, you should still
+    # return the return value from make_call(), since this may be
+    # needed by a broadcasting version of the class.)
+    #
+    # If the call fails, make_call() raises an exception
+    # (this includes time-outs and invalid results).
+    #
+    # Note that (at least with the UDP protocol) there is no
+    # guarantee that a call is executed at most once.  When you do
+    # get a reply, you know it has been executed at least once;
+    # when you don't get a reply, you know nothing.
+
+    def Mnt(self, directory):
+        return self.make_call(1, directory, \
+                self.packer.pack_string, \
+                self.unpacker.unpack_fhstatus)
+
+    def Dump(self):
+        return self.make_call(2, None, \
+                None, self.unpacker.unpack_mountlist)
+
+    def Umnt(self, directory):
+        return self.make_call(3, directory, \
+                self.packer.pack_string, None)
+
+    def Umntall(self):
+        return self.make_call(4, None, None, None)
+
+    def Export(self):
+        return self.make_call(5, None, \
+                None, self.unpacker.unpack_exportlist)
+
+
+# We turn the partial Mount client into a full one for either protocol
+# by use of multiple inheritance.  (In general, when class C has base
+# classes B1...Bn, if x is an instance of class C, methods of x are
+# searched first in C, then in B1, then in B2, ..., finally in Bn.)
+
+class TCPMountClient(PartialMountClient, TCPClient):
+
+    def __init__(self, host):
+        TCPClient.__init__(self, host, MOUNTPROG, MOUNTVERS)
+
+
+class UDPMountClient(PartialMountClient, UDPClient):
+
+    def __init__(self, host):
+        UDPClient.__init__(self, host, MOUNTPROG, MOUNTVERS)
+
+
+# A little test program for the Mount client.  This takes a host as
+# command line argument (default the local machine), prints its export
+# list, and attempts to mount and unmount each exported files system.
+# An optional first argument of -t or -u specifies the protocol to use
+# (TCP or UDP), default is UDP.
+
+def test():
+    import sys
+    if sys.argv[1:] and sys.argv[1] == '-t':
+        C = TCPMountClient
+        del sys.argv[1]
+    elif sys.argv[1:] and sys.argv[1] == '-u':
+        C = UDPMountClient
+        del sys.argv[1]
+    else:
+        C = UDPMountClient
+    if sys.argv[1:]: host = sys.argv[1]
+    else: host = ''
+    mcl = C(host)
+    list = mcl.Export()
+    for item in list:
+        print item
+        try:
+            mcl.Mnt(item[0])
+        except:
+            print 'Sorry'
+            continue
+        mcl.Umnt(item[0])

Added: vendor/Python/current/Demo/rpc/nfsclient.py
===================================================================
--- vendor/Python/current/Demo/rpc/nfsclient.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/rpc/nfsclient.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,201 @@
+# NFS RPC client -- RFC 1094
+
+# XXX This is not yet complete.
+# XXX Only GETATTR, SETTTR, LOOKUP and READDIR are supported.
+
+# (See mountclient.py for some hints on how to write RPC clients in
+# Python in general)
+
+import rpc
+from rpc import UDPClient, TCPClient
+from mountclient import FHSIZE, MountPacker, MountUnpacker
+
+NFS_PROGRAM = 100003
+NFS_VERSION = 2
+
+# enum stat
+NFS_OK = 0
+# (...many error values...)
+
+# enum ftype
+NFNON = 0
+NFREG = 1
+NFDIR = 2
+NFBLK = 3
+NFCHR = 4
+NFLNK = 5
+
+
+class NFSPacker(MountPacker):
+
+    def pack_sattrargs(self, sa):
+        file, attributes = sa
+        self.pack_fhandle(file)
+        self.pack_sattr(attributes)
+
+    def pack_sattr(self, sa):
+        mode, uid, gid, size, atime, mtime = sa
+        self.pack_uint(mode)
+        self.pack_uint(uid)
+        self.pack_uint(gid)
+        self.pack_uint(size)
+        self.pack_timeval(atime)
+        self.pack_timeval(mtime)
+
+    def pack_diropargs(self, da):
+        dir, name = da
+        self.pack_fhandle(dir)
+        self.pack_string(name)
+
+    def pack_readdirargs(self, ra):
+        dir, cookie, count = ra
+        self.pack_fhandle(dir)
+        self.pack_uint(cookie)
+        self.pack_uint(count)
+
+    def pack_timeval(self, tv):
+        secs, usecs = tv
+        self.pack_uint(secs)
+        self.pack_uint(usecs)
+
+
+class NFSUnpacker(MountUnpacker):
+
+    def unpack_readdirres(self):
+        status = self.unpack_enum()
+        if status == NFS_OK:
+            entries = self.unpack_list(self.unpack_entry)
+            eof = self.unpack_bool()
+            rest = (entries, eof)
+        else:
+            rest = None
+        return (status, rest)
+
+    def unpack_entry(self):
+        fileid = self.unpack_uint()
+        name = self.unpack_string()
+        cookie = self.unpack_uint()
+        return (fileid, name, cookie)
+
+    def unpack_diropres(self):
+        status = self.unpack_enum()
+        if status == NFS_OK:
+            fh = self.unpack_fhandle()
+            fa = self.unpack_fattr()
+            rest = (fh, fa)
+        else:
+            rest = None
+        return (status, rest)
+
+    def unpack_attrstat(self):
+        status = self.unpack_enum()
+        if status == NFS_OK:
+            attributes = self.unpack_fattr()
+        else:
+            attributes = None
+        return status, attributes
+
+    def unpack_fattr(self):
+        type = self.unpack_enum()
+        mode = self.unpack_uint()
+        nlink = self.unpack_uint()
+        uid = self.unpack_uint()
+        gid = self.unpack_uint()
+        size = self.unpack_uint()
+        blocksize = self.unpack_uint()
+        rdev = self.unpack_uint()
+        blocks = self.unpack_uint()
+        fsid = self.unpack_uint()
+        fileid = self.unpack_uint()
+        atime = self.unpack_timeval()
+        mtime = self.unpack_timeval()
+        ctime = self.unpack_timeval()
+        return (type, mode, nlink, uid, gid, size, blocksize, \
+                rdev, blocks, fsid, fileid, atime, mtime, ctime)
+
+    def unpack_timeval(self):
+        secs = self.unpack_uint()
+        usecs = self.unpack_uint()
+        return (secs, usecs)
+
+
+class NFSClient(UDPClient):
+
+    def __init__(self, host):
+        UDPClient.__init__(self, host, NFS_PROGRAM, NFS_VERSION)
+
+    def addpackers(self):
+        self.packer = NFSPacker()
+        self.unpacker = NFSUnpacker('')
+
+    def mkcred(self):
+        if self.cred == None:
+            self.cred = rpc.AUTH_UNIX, rpc.make_auth_unix_default()
+        return self.cred
+
+    def Getattr(self, fh):
+        return self.make_call(1, fh, \
+                self.packer.pack_fhandle, \
+                self.unpacker.unpack_attrstat)
+
+    def Setattr(self, sa):
+        return self.make_call(2, sa, \
+                self.packer.pack_sattrargs, \
+                self.unpacker.unpack_attrstat)
+
+    # Root() is obsolete
+
+    def Lookup(self, da):
+        return self.make_call(4, da, \
+                self.packer.pack_diropargs, \
+                self.unpacker.unpack_diropres)
+
+    # ...
+
+    def Readdir(self, ra):
+        return self.make_call(16, ra, \
+                self.packer.pack_readdirargs, \
+                self.unpacker.unpack_readdirres)
+
+    # Shorthand to get the entire contents of a directory
+    def Listdir(self, dir):
+        list = []
+        ra = (dir, 0, 2000)
+        while 1:
+            (status, rest) = self.Readdir(ra)
+            if status <> NFS_OK:
+                break
+            entries, eof = rest
+            last_cookie = None
+            for fileid, name, cookie in entries:
+                list.append((fileid, name))
+                last_cookie = cookie
+            if eof or last_cookie == None:
+                break
+            ra = (ra[0], last_cookie, ra[2])
+        return list
+
+
+def test():
+    import sys
+    if sys.argv[1:]: host = sys.argv[1]
+    else: host = ''
+    if sys.argv[2:]: filesys = sys.argv[2]
+    else: filesys = None
+    from mountclient import UDPMountClient, TCPMountClient
+    mcl = TCPMountClient(host)
+    if filesys == None:
+        list = mcl.Export()
+        for item in list:
+            print item
+        return
+    sf = mcl.Mnt(filesys)
+    print sf
+    fh = sf[1]
+    if fh:
+        ncl = NFSClient(host)
+        as = ncl.Getattr(fh)
+        print as
+        list = ncl.Listdir(fh)
+        for item in list: print item
+        mcl.Umnt(filesys)

Added: vendor/Python/current/Demo/rpc/rnusersclient.py
===================================================================
--- vendor/Python/current/Demo/rpc/rnusersclient.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/rpc/rnusersclient.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,98 @@
+# Remote nusers client interface
+
+import rpc
+from rpc import Packer, Unpacker, UDPClient, BroadcastUDPClient
+
+
+class RnusersPacker(Packer):
+    def pack_utmp(self, ui):
+        ut_line, ut_name, ut_host, ut_time = utmp
+        self.pack_string(ut_line)
+        self.pack_string(ut_name)
+        self.pack_string(ut_host)
+        self.pack_int(ut_time)
+    def pack_utmpidle(self, ui):
+        ui_itmp, ui_idle = ui
+        self.pack_utmp(ui_utmp)
+        self.pack_uint(ui_idle)
+    def pack_utmpidlearr(self, list):
+        self.pack_array(list, self.pack_itmpidle)
+
+
+class RnusersUnpacker(Unpacker):
+    def unpack_utmp(self):
+        ut_line = self.unpack_string()
+        ut_name = self.unpack_string()
+        ut_host = self.unpack_string()
+        ut_time = self.unpack_int()
+        return ut_line, ut_name, ut_host, ut_time
+    def unpack_utmpidle(self):
+        ui_utmp = self.unpack_utmp()
+        ui_idle = self.unpack_uint()
+        return ui_utmp, ui_idle
+    def unpack_utmpidlearr(self):
+        return self.unpack_array(self.unpack_utmpidle)
+
+
+class PartialRnusersClient:
+
+    def addpackers(self):
+        self.packer = RnusersPacker()
+        self.unpacker = RnusersUnpacker('')
+
+    def Num(self):
+        return self.make_call(1, None, None, self.unpacker.unpack_int)
+
+    def Names(self):
+        return self.make_call(2, None, \
+                None, self.unpacker.unpack_utmpidlearr)
+
+    def Allnames(self):
+        return self.make_call(3, None, \
+                None, self.unpacker.unpack_utmpidlearr)
+
+
+class RnusersClient(PartialRnusersClient, UDPClient):
+
+    def __init__(self, host):
+        UDPClient.__init__(self, host, 100002, 2)
+
+
+class BroadcastRnusersClient(PartialRnusersClient, BroadcastUDPClient):
+
+    def __init__(self, bcastaddr):
+        BroadcastUDPClient.__init__(self, bcastaddr, 100002, 2)
+
+
+def test():
+    import sys
+    if not sys.argv[1:]:
+        testbcast()
+        return
+    else:
+        host = sys.argv[1]
+    c = RnusersClient(host)
+    list = c.Names()
+    for (line, name, host, time), idle in list:
+        line = strip0(line)
+        name = strip0(name)
+        host = strip0(host)
+        print "%r %r %r %s %s" % (name, host, line, time, idle)
+
+def testbcast():
+    c = BroadcastRnusersClient('<broadcast>')
+    def listit(list, fromaddr):
+        host, port = fromaddr
+        print host + '\t:',
+        for (line, name, host, time), idle in list:
+            print strip0(name),
+        print
+    c.set_reply_handler(listit)
+    all = c.Names()
+    print 'Total Count:', len(all)
+
+def strip0(s):
+    while s and s[-1] == '\0': s = s[:-1]
+    return s
+
+test()

Added: vendor/Python/current/Demo/rpc/rpc.py
===================================================================
--- vendor/Python/current/Demo/rpc/rpc.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/rpc/rpc.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,893 @@
+# Sun RPC version 2 -- RFC1057.
+
+# XXX There should be separate exceptions for the various reasons why
+# XXX an RPC can fail, rather than using RuntimeError for everything
+
+# XXX Need to use class based exceptions rather than string exceptions
+
+# XXX The UDP version of the protocol resends requests when it does
+# XXX not receive a timely reply -- use only for idempotent calls!
+
+# XXX There is no provision for call timeout on TCP connections
+
+import xdr
+import socket
+import os
+
+RPCVERSION = 2
+
+CALL = 0
+REPLY = 1
+
+AUTH_NULL = 0
+AUTH_UNIX = 1
+AUTH_SHORT = 2
+AUTH_DES = 3
+
+MSG_ACCEPTED = 0
+MSG_DENIED = 1
+
+SUCCESS = 0                             # RPC executed successfully
+PROG_UNAVAIL  = 1                       # remote hasn't exported program
+PROG_MISMATCH = 2                       # remote can't support version #
+PROC_UNAVAIL  = 3                       # program can't support procedure
+GARBAGE_ARGS  = 4                       # procedure can't decode params
+
+RPC_MISMATCH = 0                        # RPC version number != 2
+AUTH_ERROR = 1                          # remote can't authenticate caller
+
+AUTH_BADCRED      = 1                   # bad credentials (seal broken)
+AUTH_REJECTEDCRED = 2                   # client must begin new session
+AUTH_BADVERF      = 3                   # bad verifier (seal broken)
+AUTH_REJECTEDVERF = 4                   # verifier expired or replayed
+AUTH_TOOWEAK      = 5                   # rejected for security reasons
+
+
+class Packer(xdr.Packer):
+
+    def pack_auth(self, auth):
+        flavor, stuff = auth
+        self.pack_enum(flavor)
+        self.pack_opaque(stuff)
+
+    def pack_auth_unix(self, stamp, machinename, uid, gid, gids):
+        self.pack_uint(stamp)
+        self.pack_string(machinename)
+        self.pack_uint(uid)
+        self.pack_uint(gid)
+        self.pack_uint(len(gids))
+        for i in gids:
+            self.pack_uint(i)
+
+    def pack_callheader(self, xid, prog, vers, proc, cred, verf):
+        self.pack_uint(xid)
+        self.pack_enum(CALL)
+        self.pack_uint(RPCVERSION)
+        self.pack_uint(prog)
+        self.pack_uint(vers)
+        self.pack_uint(proc)
+        self.pack_auth(cred)
+        self.pack_auth(verf)
+        # Caller must add procedure-specific part of call
+
+    def pack_replyheader(self, xid, verf):
+        self.pack_uint(xid)
+        self.pack_enum(REPLY)
+        self.pack_uint(MSG_ACCEPTED)
+        self.pack_auth(verf)
+        self.pack_enum(SUCCESS)
+        # Caller must add procedure-specific part of reply
+
+
+# Exceptions
+BadRPCFormat = 'rpc.BadRPCFormat'
+BadRPCVersion = 'rpc.BadRPCVersion'
+GarbageArgs = 'rpc.GarbageArgs'
+
+class Unpacker(xdr.Unpacker):
+
+    def unpack_auth(self):
+        flavor = self.unpack_enum()
+        stuff = self.unpack_opaque()
+        return (flavor, stuff)
+
+    def unpack_callheader(self):
+        xid = self.unpack_uint()
+        temp = self.unpack_enum()
+        if temp != CALL:
+            raise BadRPCFormat, 'no CALL but %r' % (temp,)
+        temp = self.unpack_uint()
+        if temp != RPCVERSION:
+            raise BadRPCVersion, 'bad RPC version %r' % (temp,)
+        prog = self.unpack_uint()
+        vers = self.unpack_uint()
+        proc = self.unpack_uint()
+        cred = self.unpack_auth()
+        verf = self.unpack_auth()
+        return xid, prog, vers, proc, cred, verf
+        # Caller must add procedure-specific part of call
+
+    def unpack_replyheader(self):
+        xid = self.unpack_uint()
+        mtype = self.unpack_enum()
+        if mtype != REPLY:
+            raise RuntimeError, 'no REPLY but %r' % (mtype,)
+        stat = self.unpack_enum()
+        if stat == MSG_DENIED:
+            stat = self.unpack_enum()
+            if stat == RPC_MISMATCH:
+                low = self.unpack_uint()
+                high = self.unpack_uint()
+                raise RuntimeError, \
+                  'MSG_DENIED: RPC_MISMATCH: %r' % ((low, high),)
+            if stat == AUTH_ERROR:
+                stat = self.unpack_uint()
+                raise RuntimeError, \
+                        'MSG_DENIED: AUTH_ERROR: %r' % (stat,)
+            raise RuntimeError, 'MSG_DENIED: %r' % (stat,)
+        if stat != MSG_ACCEPTED:
+            raise RuntimeError, \
+              'Neither MSG_DENIED nor MSG_ACCEPTED: %r' % (stat,)
+        verf = self.unpack_auth()
+        stat = self.unpack_enum()
+        if stat == PROG_UNAVAIL:
+            raise RuntimeError, 'call failed: PROG_UNAVAIL'
+        if stat == PROG_MISMATCH:
+            low = self.unpack_uint()
+            high = self.unpack_uint()
+            raise RuntimeError, \
+                    'call failed: PROG_MISMATCH: %r' % ((low, high),)
+        if stat == PROC_UNAVAIL:
+            raise RuntimeError, 'call failed: PROC_UNAVAIL'
+        if stat == GARBAGE_ARGS:
+            raise RuntimeError, 'call failed: GARBAGE_ARGS'
+        if stat != SUCCESS:
+            raise RuntimeError, 'call failed: %r' % (stat,)
+        return xid, verf
+        # Caller must get procedure-specific part of reply
+
+
+# Subroutines to create opaque authentication objects
+
+def make_auth_null():
+    return ''
+
+def make_auth_unix(seed, host, uid, gid, groups):
+    p = Packer()
+    p.pack_auth_unix(seed, host, uid, gid, groups)
+    return p.get_buf()
+
+def make_auth_unix_default():
+    try:
+        from os import getuid, getgid
+        uid = getuid()
+        gid = getgid()
+    except ImportError:
+        uid = gid = 0
+    import time
+    return make_auth_unix(int(time.time()-unix_epoch()), \
+              socket.gethostname(), uid, gid, [])
+
+_unix_epoch = -1
+def unix_epoch():
+    """Very painful calculation of when the Unix Epoch is.
+
+    This is defined as the return value of time.time() on Jan 1st,
+    1970, 00:00:00 GMT.
+
+    On a Unix system, this should always return 0.0.  On a Mac, the
+    calculations are needed -- and hard because of integer overflow
+    and other limitations.
+
+    """
+    global _unix_epoch
+    if _unix_epoch >= 0: return _unix_epoch
+    import time
+    now = time.time()
+    localt = time.localtime(now)        # (y, m, d, hh, mm, ss, ..., ..., ...)
+    gmt = time.gmtime(now)
+    offset = time.mktime(localt) - time.mktime(gmt)
+    y, m, d, hh, mm, ss = 1970, 1, 1, 0, 0, 0
+    offset, ss = divmod(ss + offset, 60)
+    offset, mm = divmod(mm + offset, 60)
+    offset, hh = divmod(hh + offset, 24)
+    d = d + offset
+    _unix_epoch = time.mktime((y, m, d, hh, mm, ss, 0, 0, 0))
+    print "Unix epoch:", time.ctime(_unix_epoch)
+    return _unix_epoch
+
+
+# Common base class for clients
+
+class Client:
+
+    def __init__(self, host, prog, vers, port):
+        self.host = host
+        self.prog = prog
+        self.vers = vers
+        self.port = port
+        self.makesocket() # Assigns to self.sock
+        self.bindsocket()
+        self.connsocket()
+        self.lastxid = 0 # XXX should be more random?
+        self.addpackers()
+        self.cred = None
+        self.verf = None
+
+    def close(self):
+        self.sock.close()
+
+    def makesocket(self):
+        # This MUST be overridden
+        raise RuntimeError, 'makesocket not defined'
+
+    def connsocket(self):
+        # Override this if you don't want/need a connection
+        self.sock.connect((self.host, self.port))
+
+    def bindsocket(self):
+        # Override this to bind to a different port (e.g. reserved)
+        self.sock.bind(('', 0))
+
+    def addpackers(self):
+        # Override this to use derived classes from Packer/Unpacker
+        self.packer = Packer()
+        self.unpacker = Unpacker('')
+
+    def make_call(self, proc, args, pack_func, unpack_func):
+        # Don't normally override this (but see Broadcast)
+        if pack_func is None and args is not None:
+            raise TypeError, 'non-null args with null pack_func'
+        self.start_call(proc)
+        if pack_func:
+            pack_func(args)
+        self.do_call()
+        if unpack_func:
+            result = unpack_func()
+        else:
+            result = None
+        self.unpacker.done()
+        return result
+
+    def start_call(self, proc):
+        # Don't override this
+        self.lastxid = xid = self.lastxid + 1
+        cred = self.mkcred()
+        verf = self.mkverf()
+        p = self.packer
+        p.reset()
+        p.pack_callheader(xid, self.prog, self.vers, proc, cred, verf)
+
+    def do_call(self):
+        # This MUST be overridden
+        raise RuntimeError, 'do_call not defined'
+
+    def mkcred(self):
+        # Override this to use more powerful credentials
+        if self.cred == None:
+            self.cred = (AUTH_NULL, make_auth_null())
+        return self.cred
+
+    def mkverf(self):
+        # Override this to use a more powerful verifier
+        if self.verf == None:
+            self.verf = (AUTH_NULL, make_auth_null())
+        return self.verf
+
+    def call_0(self):               # Procedure 0 is always like this
+        return self.make_call(0, None, None, None)
+
+
+# Record-Marking standard support
+
+def sendfrag(sock, last, frag):
+    x = len(frag)
+    if last: x = x | 0x80000000L
+    header = (chr(int(x>>24 & 0xff)) + chr(int(x>>16 & 0xff)) + \
+              chr(int(x>>8 & 0xff)) + chr(int(x & 0xff)))
+    sock.send(header + frag)
+
+def sendrecord(sock, record):
+    sendfrag(sock, 1, record)
+
+def recvfrag(sock):
+    header = sock.recv(4)
+    if len(header) < 4:
+        raise EOFError
+    x = long(ord(header[0]))<<24 | ord(header[1])<<16 | \
+        ord(header[2])<<8 | ord(header[3])
+    last = ((x & 0x80000000) != 0)
+    n = int(x & 0x7fffffff)
+    frag = ''
+    while n > 0:
+        buf = sock.recv(n)
+        if not buf: raise EOFError
+        n = n - len(buf)
+        frag = frag + buf
+    return last, frag
+
+def recvrecord(sock):
+    record = ''
+    last = 0
+    while not last:
+        last, frag = recvfrag(sock)
+        record = record + frag
+    return record
+
+
+# Try to bind to a reserved port (must be root)
+
+last_resv_port_tried = None
+def bindresvport(sock, host):
+    global last_resv_port_tried
+    FIRST, LAST = 600, 1024 # Range of ports to try
+    if last_resv_port_tried == None:
+        import os
+        last_resv_port_tried = FIRST + os.getpid() % (LAST-FIRST)
+    for i in range(last_resv_port_tried, LAST) + \
+              range(FIRST, last_resv_port_tried):
+        last_resv_port_tried = i
+        try:
+            sock.bind((host, i))
+            return last_resv_port_tried
+        except socket.error, (errno, msg):
+            if errno != 114:
+                raise socket.error, (errno, msg)
+    raise RuntimeError, 'can\'t assign reserved port'
+
+
+# Client using TCP to a specific port
+
+class RawTCPClient(Client):
+
+    def makesocket(self):
+        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+
+    def do_call(self):
+        call = self.packer.get_buf()
+        sendrecord(self.sock, call)
+        reply = recvrecord(self.sock)
+        u = self.unpacker
+        u.reset(reply)
+        xid, verf = u.unpack_replyheader()
+        if xid != self.lastxid:
+            # Can't really happen since this is TCP...
+            raise RuntimeError, 'wrong xid in reply %r instead of %r' % (
+                                 xid, self.lastxid)
+
+
+# Client using UDP to a specific port
+
+class RawUDPClient(Client):
+
+    def makesocket(self):
+        self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+
+    def do_call(self):
+        call = self.packer.get_buf()
+        self.sock.send(call)
+        try:
+            from select import select
+        except ImportError:
+            print 'WARNING: select not found, RPC may hang'
+            select = None
+        BUFSIZE = 8192 # Max UDP buffer size
+        timeout = 1
+        count = 5
+        while 1:
+            r, w, x = [self.sock], [], []
+            if select:
+                r, w, x = select(r, w, x, timeout)
+            if self.sock not in r:
+                count = count - 1
+                if count < 0: raise RuntimeError, 'timeout'
+                if timeout < 25: timeout = timeout *2
+##                              print 'RESEND', timeout, count
+                self.sock.send(call)
+                continue
+            reply = self.sock.recv(BUFSIZE)
+            u = self.unpacker
+            u.reset(reply)
+            xid, verf = u.unpack_replyheader()
+            if xid != self.lastxid:
+##                              print 'BAD xid'
+                continue
+            break
+
+
+# Client using UDP broadcast to a specific port
+
+class RawBroadcastUDPClient(RawUDPClient):
+
+    def __init__(self, bcastaddr, prog, vers, port):
+        RawUDPClient.__init__(self, bcastaddr, prog, vers, port)
+        self.reply_handler = None
+        self.timeout = 30
+
+    def connsocket(self):
+        # Don't connect -- use sendto
+        self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
+
+    def set_reply_handler(self, reply_handler):
+        self.reply_handler = reply_handler
+
+    def set_timeout(self, timeout):
+        self.timeout = timeout # Use None for infinite timeout
+
+    def make_call(self, proc, args, pack_func, unpack_func):
+        if pack_func is None and args is not None:
+            raise TypeError, 'non-null args with null pack_func'
+        self.start_call(proc)
+        if pack_func:
+            pack_func(args)
+        call = self.packer.get_buf()
+        self.sock.sendto(call, (self.host, self.port))
+        try:
+            from select import select
+        except ImportError:
+            print 'WARNING: select not found, broadcast will hang'
+            select = None
+        BUFSIZE = 8192 # Max UDP buffer size (for reply)
+        replies = []
+        if unpack_func is None:
+            def dummy(): pass
+            unpack_func = dummy
+        while 1:
+            r, w, x = [self.sock], [], []
+            if select:
+                if self.timeout is None:
+                    r, w, x = select(r, w, x)
+                else:
+                    r, w, x = select(r, w, x, self.timeout)
+            if self.sock not in r:
+                break
+            reply, fromaddr = self.sock.recvfrom(BUFSIZE)
+            u = self.unpacker
+            u.reset(reply)
+            xid, verf = u.unpack_replyheader()
+            if xid != self.lastxid:
+##                              print 'BAD xid'
+                continue
+            reply = unpack_func()
+            self.unpacker.done()
+            replies.append((reply, fromaddr))
+            if self.reply_handler:
+                self.reply_handler(reply, fromaddr)
+        return replies
+
+
+# Port mapper interface
+
+# Program number, version and (fixed!) port number
+PMAP_PROG = 100000
+PMAP_VERS = 2
+PMAP_PORT = 111
+
+# Procedure numbers
+PMAPPROC_NULL = 0                       # (void) -> void
+PMAPPROC_SET = 1                        # (mapping) -> bool
+PMAPPROC_UNSET = 2                      # (mapping) -> bool
+PMAPPROC_GETPORT = 3                    # (mapping) -> unsigned int
+PMAPPROC_DUMP = 4                       # (void) -> pmaplist
+PMAPPROC_CALLIT = 5                     # (call_args) -> call_result
+
+# A mapping is (prog, vers, prot, port) and prot is one of:
+
+IPPROTO_TCP = 6
+IPPROTO_UDP = 17
+
+# A pmaplist is a variable-length list of mappings, as follows:
+# either (1, mapping, pmaplist) or (0).
+
+# A call_args is (prog, vers, proc, args) where args is opaque;
+# a call_result is (port, res) where res is opaque.
+
+
+class PortMapperPacker(Packer):
+
+    def pack_mapping(self, mapping):
+        prog, vers, prot, port = mapping
+        self.pack_uint(prog)
+        self.pack_uint(vers)
+        self.pack_uint(prot)
+        self.pack_uint(port)
+
+    def pack_pmaplist(self, list):
+        self.pack_list(list, self.pack_mapping)
+
+    def pack_call_args(self, ca):
+        prog, vers, proc, args = ca
+        self.pack_uint(prog)
+        self.pack_uint(vers)
+        self.pack_uint(proc)
+        self.pack_opaque(args)
+
+
+class PortMapperUnpacker(Unpacker):
+
+    def unpack_mapping(self):
+        prog = self.unpack_uint()
+        vers = self.unpack_uint()
+        prot = self.unpack_uint()
+        port = self.unpack_uint()
+        return prog, vers, prot, port
+
+    def unpack_pmaplist(self):
+        return self.unpack_list(self.unpack_mapping)
+
+    def unpack_call_result(self):
+        port = self.unpack_uint()
+        res = self.unpack_opaque()
+        return port, res
+
+
+class PartialPortMapperClient:
+
+    def addpackers(self):
+        self.packer = PortMapperPacker()
+        self.unpacker = PortMapperUnpacker('')
+
+    def Set(self, mapping):
+        return self.make_call(PMAPPROC_SET, mapping, \
+                self.packer.pack_mapping, \
+                self.unpacker.unpack_uint)
+
+    def Unset(self, mapping):
+        return self.make_call(PMAPPROC_UNSET, mapping, \
+                self.packer.pack_mapping, \
+                self.unpacker.unpack_uint)
+
+    def Getport(self, mapping):
+        return self.make_call(PMAPPROC_GETPORT, mapping, \
+                self.packer.pack_mapping, \
+                self.unpacker.unpack_uint)
+
+    def Dump(self):
+        return self.make_call(PMAPPROC_DUMP, None, \
+                None, \
+                self.unpacker.unpack_pmaplist)
+
+    def Callit(self, ca):
+        return self.make_call(PMAPPROC_CALLIT, ca, \
+                self.packer.pack_call_args, \
+                self.unpacker.unpack_call_result)
+
+
+class TCPPortMapperClient(PartialPortMapperClient, RawTCPClient):
+
+    def __init__(self, host):
+        RawTCPClient.__init__(self, \
+                host, PMAP_PROG, PMAP_VERS, PMAP_PORT)
+
+
+class UDPPortMapperClient(PartialPortMapperClient, RawUDPClient):
+
+    def __init__(self, host):
+        RawUDPClient.__init__(self, \
+                host, PMAP_PROG, PMAP_VERS, PMAP_PORT)
+
+
+class BroadcastUDPPortMapperClient(PartialPortMapperClient, \
+                                   RawBroadcastUDPClient):
+
+    def __init__(self, bcastaddr):
+        RawBroadcastUDPClient.__init__(self, \
+                bcastaddr, PMAP_PROG, PMAP_VERS, PMAP_PORT)
+
+
+# Generic clients that find their server through the Port mapper
+
+class TCPClient(RawTCPClient):
+
+    def __init__(self, host, prog, vers):
+        pmap = TCPPortMapperClient(host)
+        port = pmap.Getport((prog, vers, IPPROTO_TCP, 0))
+        pmap.close()
+        if port == 0:
+            raise RuntimeError, 'program not registered'
+        RawTCPClient.__init__(self, host, prog, vers, port)
+
+
+class UDPClient(RawUDPClient):
+
+    def __init__(self, host, prog, vers):
+        pmap = UDPPortMapperClient(host)
+        port = pmap.Getport((prog, vers, IPPROTO_UDP, 0))
+        pmap.close()
+        if port == 0:
+            raise RuntimeError, 'program not registered'
+        RawUDPClient.__init__(self, host, prog, vers, port)
+
+
+class BroadcastUDPClient(Client):
+
+    def __init__(self, bcastaddr, prog, vers):
+        self.pmap = BroadcastUDPPortMapperClient(bcastaddr)
+        self.pmap.set_reply_handler(self.my_reply_handler)
+        self.prog = prog
+        self.vers = vers
+        self.user_reply_handler = None
+        self.addpackers()
+
+    def close(self):
+        self.pmap.close()
+
+    def set_reply_handler(self, reply_handler):
+        self.user_reply_handler = reply_handler
+
+    def set_timeout(self, timeout):
+        self.pmap.set_timeout(timeout)
+
+    def my_reply_handler(self, reply, fromaddr):
+        port, res = reply
+        self.unpacker.reset(res)
+        result = self.unpack_func()
+        self.unpacker.done()
+        self.replies.append((result, fromaddr))
+        if self.user_reply_handler is not None:
+            self.user_reply_handler(result, fromaddr)
+
+    def make_call(self, proc, args, pack_func, unpack_func):
+        self.packer.reset()
+        if pack_func:
+            pack_func(args)
+        if unpack_func is None:
+            def dummy(): pass
+            self.unpack_func = dummy
+        else:
+            self.unpack_func = unpack_func
+        self.replies = []
+        packed_args = self.packer.get_buf()
+        dummy_replies = self.pmap.Callit( \
+                (self.prog, self.vers, proc, packed_args))
+        return self.replies
+
+
+# Server classes
+
+# These are not symmetric to the Client classes
+# XXX No attempt is made to provide authorization hooks yet
+
+class Server:
+
+    def __init__(self, host, prog, vers, port):
+        self.host = host # Should normally be '' for default interface
+        self.prog = prog
+        self.vers = vers
+        self.port = port # Should normally be 0 for random port
+        self.makesocket() # Assigns to self.sock and self.prot
+        self.bindsocket()
+        self.host, self.port = self.sock.getsockname()
+        self.addpackers()
+
+    def register(self):
+        mapping = self.prog, self.vers, self.prot, self.port
+        p = TCPPortMapperClient(self.host)
+        if not p.Set(mapping):
+            raise RuntimeError, 'register failed'
+
+    def unregister(self):
+        mapping = self.prog, self.vers, self.prot, self.port
+        p = TCPPortMapperClient(self.host)
+        if not p.Unset(mapping):
+            raise RuntimeError, 'unregister failed'
+
+    def handle(self, call):
+        # Don't use unpack_header but parse the header piecewise
+        # XXX I have no idea if I am using the right error responses!
+        self.unpacker.reset(call)
+        self.packer.reset()
+        xid = self.unpacker.unpack_uint()
+        self.packer.pack_uint(xid)
+        temp = self.unpacker.unpack_enum()
+        if temp != CALL:
+            return None # Not worthy of a reply
+        self.packer.pack_uint(REPLY)
+        temp = self.unpacker.unpack_uint()
+        if temp != RPCVERSION:
+            self.packer.pack_uint(MSG_DENIED)
+            self.packer.pack_uint(RPC_MISMATCH)
+            self.packer.pack_uint(RPCVERSION)
+            self.packer.pack_uint(RPCVERSION)
+            return self.packer.get_buf()
+        self.packer.pack_uint(MSG_ACCEPTED)
+        self.packer.pack_auth((AUTH_NULL, make_auth_null()))
+        prog = self.unpacker.unpack_uint()
+        if prog != self.prog:
+            self.packer.pack_uint(PROG_UNAVAIL)
+            return self.packer.get_buf()
+        vers = self.unpacker.unpack_uint()
+        if vers != self.vers:
+            self.packer.pack_uint(PROG_MISMATCH)
+            self.packer.pack_uint(self.vers)
+            self.packer.pack_uint(self.vers)
+            return self.packer.get_buf()
+        proc = self.unpacker.unpack_uint()
+        methname = 'handle_' + repr(proc)
+        try:
+            meth = getattr(self, methname)
+        except AttributeError:
+            self.packer.pack_uint(PROC_UNAVAIL)
+            return self.packer.get_buf()
+        cred = self.unpacker.unpack_auth()
+        verf = self.unpacker.unpack_auth()
+        try:
+            meth() # Unpack args, call turn_around(), pack reply
+        except (EOFError, GarbageArgs):
+            # Too few or too many arguments
+            self.packer.reset()
+            self.packer.pack_uint(xid)
+            self.packer.pack_uint(REPLY)
+            self.packer.pack_uint(MSG_ACCEPTED)
+            self.packer.pack_auth((AUTH_NULL, make_auth_null()))
+            self.packer.pack_uint(GARBAGE_ARGS)
+        return self.packer.get_buf()
+
+    def turn_around(self):
+        try:
+            self.unpacker.done()
+        except RuntimeError:
+            raise GarbageArgs
+        self.packer.pack_uint(SUCCESS)
+
+    def handle_0(self): # Handle NULL message
+        self.turn_around()
+
+    def makesocket(self):
+        # This MUST be overridden
+        raise RuntimeError, 'makesocket not defined'
+
+    def bindsocket(self):
+        # Override this to bind to a different port (e.g. reserved)
+        self.sock.bind((self.host, self.port))
+
+    def addpackers(self):
+        # Override this to use derived classes from Packer/Unpacker
+        self.packer = Packer()
+        self.unpacker = Unpacker('')
+
+
+class TCPServer(Server):
+
+    def makesocket(self):
+        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        self.prot = IPPROTO_TCP
+
+    def loop(self):
+        self.sock.listen(0)
+        while 1:
+            self.session(self.sock.accept())
+
+    def session(self, connection):
+        sock, (host, port) = connection
+        while 1:
+            try:
+                call = recvrecord(sock)
+            except EOFError:
+                break
+            except socket.error, msg:
+                print 'socket error:', msg
+                break
+            reply = self.handle(call)
+            if reply is not None:
+                sendrecord(sock, reply)
+
+    def forkingloop(self):
+        # Like loop but uses forksession()
+        self.sock.listen(0)
+        while 1:
+            self.forksession(self.sock.accept())
+
+    def forksession(self, connection):
+        # Like session but forks off a subprocess
+        import os
+        # Wait for deceased children
+        try:
+            while 1:
+                pid, sts = os.waitpid(0, 1)
+        except os.error:
+            pass
+        pid = None
+        try:
+            pid = os.fork()
+            if pid: # Parent
+                connection[0].close()
+                return
+            # Child
+            self.session(connection)
+        finally:
+            # Make sure we don't fall through in the parent
+            if pid == 0:
+                os._exit(0)
+
+
+class UDPServer(Server):
+
+    def makesocket(self):
+        self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+        self.prot = IPPROTO_UDP
+
+    def loop(self):
+        while 1:
+            self.session()
+
+    def session(self):
+        call, host_port = self.sock.recvfrom(8192)
+        reply = self.handle(call)
+        if reply != None:
+            self.sock.sendto(reply, host_port)
+
+
+# Simple test program -- dump local portmapper status
+
+def test():
+    pmap = UDPPortMapperClient('')
+    list = pmap.Dump()
+    list.sort()
+    for prog, vers, prot, port in list:
+        print prog, vers,
+        if prot == IPPROTO_TCP: print 'tcp',
+        elif prot == IPPROTO_UDP: print 'udp',
+        else: print prot,
+        print port
+
+
+# Test program for broadcast operation -- dump everybody's portmapper status
+
+def testbcast():
+    import sys
+    if sys.argv[1:]:
+        bcastaddr = sys.argv[1]
+    else:
+        bcastaddr = '<broadcast>'
+    def rh(reply, fromaddr):
+        host, port = fromaddr
+        print host + '\t' + repr(reply)
+    pmap = BroadcastUDPPortMapperClient(bcastaddr)
+    pmap.set_reply_handler(rh)
+    pmap.set_timeout(5)
+    replies = pmap.Getport((100002, 1, IPPROTO_UDP, 0))
+
+
+# Test program for server, with corresponding client
+# On machine A: python -c 'import rpc; rpc.testsvr()'
+# On machine B: python -c 'import rpc; rpc.testclt()' A
+# (A may be == B)
+
+def testsvr():
+    # Simple test class -- proc 1 doubles its string argument as reply
+    class S(UDPServer):
+        def handle_1(self):
+            arg = self.unpacker.unpack_string()
+            self.turn_around()
+            print 'RPC function 1 called, arg', repr(arg)
+            self.packer.pack_string(arg + arg)
+    #
+    s = S('', 0x20000000, 1, 0)
+    try:
+        s.unregister()
+    except RuntimeError, msg:
+        print 'RuntimeError:', msg, '(ignored)'
+    s.register()
+    print 'Service started...'
+    try:
+        s.loop()
+    finally:
+        s.unregister()
+        print 'Service interrupted.'
+
+
+def testclt():
+    import sys
+    if sys.argv[1:]: host = sys.argv[1]
+    else: host = ''
+    # Client for above server
+    class C(UDPClient):
+        def call_1(self, arg):
+            return self.make_call(1, arg, \
+                    self.packer.pack_string, \
+                    self.unpacker.unpack_string)
+    c = C(host, 0x20000000, 1)
+    print 'making call...'
+    reply = c.call_1('hello, world, ')
+    print 'call returned', repr(reply)

Added: vendor/Python/current/Demo/rpc/test
===================================================================
--- vendor/Python/current/Demo/rpc/test	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/rpc/test	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,24 @@
+: ${PYTHON=python}
+: ${SERVER=charon.cwi.nl}
+
+set -xe
+
+$PYTHON -c 'from rpc import test; test()'
+$PYTHON -c 'from rpc import test; test()' ${SERVER}
+
+$PYTHON -c 'from rpc import testsvr; testsvr()' &
+PID=$!
+sleep 2
+$PYTHON -c 'from rpc import testclt; testclt()'
+kill -2 $PID
+
+$PYTHON -c 'from mountclient import test; test()'
+$PYTHON -c 'from mountclient import test; test()' gatekeeper.dec.com
+
+$PYTHON -c 'from nfsclient import test; test()'
+$PYTHON -c 'from nfsclient import test; test()' gatekeeper.dec.com
+$PYTHON -c 'from nfsclient import test; test()' gatekeeper.dec.com /archive
+
+$PYTHON -c 'from rnusersclient import test; test()' ''
+
+$PYTHON -c 'from rpc import testbcast; testbcast()'


Property changes on: vendor/Python/current/Demo/rpc/test
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/rpc/xdr.py
===================================================================
--- vendor/Python/current/Demo/rpc/xdr.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/rpc/xdr.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,200 @@
+# Implement (a subset of) Sun XDR -- RFC1014.
+
+
+try:
+    import struct
+except ImportError:
+    struct = None
+
+
+Long = type(0L)
+
+
+class Packer:
+
+    def __init__(self):
+        self.reset()
+
+    def reset(self):
+        self.buf = ''
+
+    def get_buf(self):
+        return self.buf
+
+    def pack_uint(self, x):
+        self.buf = self.buf + \
+                (chr(int(x>>24 & 0xff)) + chr(int(x>>16 & 0xff)) + \
+                 chr(int(x>>8 & 0xff)) + chr(int(x & 0xff)))
+    if struct and struct.pack('l', 1) == '\0\0\0\1':
+        def pack_uint(self, x):
+            if type(x) == Long:
+                x = int((x + 0x80000000L) % 0x100000000L \
+                           - 0x80000000L)
+            self.buf = self.buf + struct.pack('l', x)
+
+    pack_int = pack_uint
+
+    pack_enum = pack_int
+
+    def pack_bool(self, x):
+        if x: self.buf = self.buf + '\0\0\0\1'
+        else: self.buf = self.buf + '\0\0\0\0'
+
+    def pack_uhyper(self, x):
+        self.pack_uint(int(x>>32 & 0xffffffff))
+        self.pack_uint(int(x & 0xffffffff))
+
+    pack_hyper = pack_uhyper
+
+    def pack_float(self, x):
+        # XXX
+        self.buf = self.buf + struct.pack('f', x)
+
+    def pack_double(self, x):
+        # XXX
+        self.buf = self.buf + struct.pack('d', x)
+
+    def pack_fstring(self, n, s):
+        if n < 0:
+            raise ValueError, 'fstring size must be nonnegative'
+        n = ((n+3)/4)*4
+        data = s[:n]
+        data = data + (n - len(data)) * '\0'
+        self.buf = self.buf + data
+
+    pack_fopaque = pack_fstring
+
+    def pack_string(self, s):
+        n = len(s)
+        self.pack_uint(n)
+        self.pack_fstring(n, s)
+
+    pack_opaque = pack_string
+
+    def pack_list(self, list, pack_item):
+        for item in list:
+            self.pack_uint(1)
+            pack_item(item)
+        self.pack_uint(0)
+
+    def pack_farray(self, n, list, pack_item):
+        if len(list) <> n:
+            raise ValueError, 'wrong array size'
+        for item in list:
+            pack_item(item)
+
+    def pack_array(self, list, pack_item):
+        n = len(list)
+        self.pack_uint(n)
+        self.pack_farray(n, list, pack_item)
+
+
+class Unpacker:
+
+    def __init__(self, data):
+        self.reset(data)
+
+    def reset(self, data):
+        self.buf = data
+        self.pos = 0
+
+    def done(self):
+        if self.pos < len(self.buf):
+            raise RuntimeError, 'unextracted data remains'
+
+    def unpack_uint(self):
+        i = self.pos
+        self.pos = j = i+4
+        data = self.buf[i:j]
+        if len(data) < 4:
+            raise EOFError
+        x = long(ord(data[0]))<<24 | ord(data[1])<<16 | \
+                ord(data[2])<<8 | ord(data[3])
+        # Return a Python long only if the value is not representable
+        # as a nonnegative Python int
+        if x < 0x80000000L: x = int(x)
+        return x
+    if struct and struct.unpack('l', '\0\0\0\1') == 1:
+        def unpack_uint(self):
+            i = self.pos
+            self.pos = j = i+4
+            data = self.buf[i:j]
+            if len(data) < 4:
+                raise EOFError
+            return struct.unpack('l', data)
+
+    def unpack_int(self):
+        x = self.unpack_uint()
+        if x >= 0x80000000L: x = x - 0x100000000L
+        return int(x)
+
+    unpack_enum = unpack_int
+
+    unpack_bool = unpack_int
+
+    def unpack_uhyper(self):
+        hi = self.unpack_uint()
+        lo = self.unpack_uint()
+        return long(hi)<<32 | lo
+
+    def unpack_hyper(self):
+        x = self.unpack_uhyper()
+        if x >= 0x8000000000000000L: x = x - 0x10000000000000000L
+        return x
+
+    def unpack_float(self):
+        # XXX
+        i = self.pos
+        self.pos = j = i+4
+        data = self.buf[i:j]
+        if len(data) < 4:
+            raise EOFError
+        return struct.unpack('f', data)[0]
+
+    def unpack_double(self):
+        # XXX
+        i = self.pos
+        self.pos = j = i+8
+        data = self.buf[i:j]
+        if len(data) < 8:
+            raise EOFError
+        return struct.unpack('d', data)[0]
+
+    def unpack_fstring(self, n):
+        if n < 0:
+            raise ValueError, 'fstring size must be nonnegative'
+        i = self.pos
+        j = i + (n+3)/4*4
+        if j > len(self.buf):
+            raise EOFError
+        self.pos = j
+        return self.buf[i:i+n]
+
+    unpack_fopaque = unpack_fstring
+
+    def unpack_string(self):
+        n = self.unpack_uint()
+        return self.unpack_fstring(n)
+
+    unpack_opaque = unpack_string
+
+    def unpack_list(self, unpack_item):
+        list = []
+        while 1:
+            x = self.unpack_uint()
+            if x == 0: break
+            if x <> 1:
+                raise RuntimeError, '0 or 1 expected, got %r' % (x, )
+            item = unpack_item()
+            list.append(item)
+        return list
+
+    def unpack_farray(self, n, unpack_item):
+        list = []
+        for i in range(n):
+            list.append(unpack_item())
+        return list
+
+    def unpack_array(self, unpack_item):
+        n = self.unpack_uint()
+        return self.unpack_farray(n, unpack_item)

Added: vendor/Python/current/Demo/scripts/README
===================================================================
--- vendor/Python/current/Demo/scripts/README	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/scripts/README	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,23 @@
+This directory contains a collection of executable Python scripts.
+
+See also the Tools/scripts directory!
+
+beer.py			Print the classic 'bottles of beer' list.
+eqfix.py		Fix .py files to use the correct equality test operator
+fact.py			Factorize numbers
+find-uname.py		Search for Unicode characters using regexps.
+from.py			Summarize mailbox
+ftpstats.py		Summarize ftp daemon log file
+lpwatch.py		Watch BSD line printer queues
+makedir.py		Like mkdir -p
+markov.py		Markov chain simulation of words or characters
+mboxconvvert.py		Convert MH or MMDF mailboxes to unix mailbox format
+mkrcs.py		Fix symlinks named RCS into parallel tree
+morse.py		Produce morse code (audible or on AIFF file)
+pi.py			Print all digits of pi -- given enough time and memory
+pp.py			Emulate some Perl command line options
+primes.py		Print prime numbers
+queens.py		Dijkstra's solution to Wirth's "N Queens problem"
+script.py		Equivalent to BSD script(1) -- by Steen Lumholt
+unbirthday.py		Print unbirthday count
+update.py		Update a bunch of files according to a script.

Added: vendor/Python/current/Demo/scripts/beer.py
===================================================================
--- vendor/Python/current/Demo/scripts/beer.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/scripts/beer.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,14 @@
+#! /usr/bin/env python
+# By GvR, demystified after a version by Fredrik Lundh.
+import sys
+n = 100
+if sys.argv[1:]: n = int(sys.argv[1])
+def bottle(n):
+    if n == 0: return "no more bottles of beer"
+    if n == 1: return "one bottle of beer"
+    return str(n) + " bottles of beer"
+for i in range(n):
+    print bottle(n-i), "on the wall,"
+    print bottle(n-i) + "."
+    print "Take one down, pass it around,"
+    print bottle(n-i-1), "on the wall."

Added: vendor/Python/current/Demo/scripts/eqfix.py
===================================================================
--- vendor/Python/current/Demo/scripts/eqfix.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/scripts/eqfix.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,198 @@
+#! /usr/bin/env python
+
+# Fix Python source files to use the new equality test operator, i.e.,
+#       if x = y: ...
+# is changed to
+#       if x == y: ...
+# The script correctly tokenizes the Python program to reliably
+# distinguish between assignments and equality tests.
+#
+# Command line arguments are files or directories to be processed.
+# Directories are searched recursively for files whose name looks
+# like a python module.
+# Symbolic links are always ignored (except as explicit directory
+# arguments).  Of course, the original file is kept as a back-up
+# (with a "~" attached to its name).
+# It complains about binaries (files containing null bytes)
+# and about files that are ostensibly not Python files: if the first
+# line starts with '#!' and does not contain the string 'python'.
+#
+# Changes made are reported to stdout in a diff-like format.
+#
+# Undoubtedly you can do this using find and sed or perl, but this is
+# a nice example of Python code that recurses down a directory tree
+# and uses regular expressions.  Also note several subtleties like
+# preserving the file's mode and avoiding to even write a temp file
+# when no changes are needed for a file.
+#
+# NB: by changing only the function fixline() you can turn this
+# into a program for a different change to Python programs...
+
+import sys
+import re
+import os
+from stat import *
+import string
+
+err = sys.stderr.write
+dbg = err
+rep = sys.stdout.write
+
+def main():
+    bad = 0
+    if not sys.argv[1:]: # No arguments
+        err('usage: ' + sys.argv[0] + ' file-or-directory ...\n')
+        sys.exit(2)
+    for arg in sys.argv[1:]:
+        if os.path.isdir(arg):
+            if recursedown(arg): bad = 1
+        elif os.path.islink(arg):
+            err(arg + ': will not process symbolic links\n')
+            bad = 1
+        else:
+            if fix(arg): bad = 1
+    sys.exit(bad)
+
+ispythonprog = re.compile('^[a-zA-Z0-9_]+\.py$')
+def ispython(name):
+    return ispythonprog.match(name) >= 0
+
+def recursedown(dirname):
+    dbg('recursedown(%r)\n' % (dirname,))
+    bad = 0
+    try:
+        names = os.listdir(dirname)
+    except os.error, msg:
+        err('%s: cannot list directory: %r\n' % (dirname, msg))
+        return 1
+    names.sort()
+    subdirs = []
+    for name in names:
+        if name in (os.curdir, os.pardir): continue
+        fullname = os.path.join(dirname, name)
+        if os.path.islink(fullname): pass
+        elif os.path.isdir(fullname):
+            subdirs.append(fullname)
+        elif ispython(name):
+            if fix(fullname): bad = 1
+    for fullname in subdirs:
+        if recursedown(fullname): bad = 1
+    return bad
+
+def fix(filename):
+##      dbg('fix(%r)\n' % (dirname,))
+    try:
+        f = open(filename, 'r')
+    except IOError, msg:
+        err('%s: cannot open: %r\n' % (filename, msg))
+        return 1
+    head, tail = os.path.split(filename)
+    tempname = os.path.join(head, '@' + tail)
+    g = None
+    # If we find a match, we rewind the file and start over but
+    # now copy everything to a temp file.
+    lineno = 0
+    while 1:
+        line = f.readline()
+        if not line: break
+        lineno = lineno + 1
+        if g is None and '\0' in line:
+            # Check for binary files
+            err(filename + ': contains null bytes; not fixed\n')
+            f.close()
+            return 1
+        if lineno == 1 and g is None and line[:2] == '#!':
+            # Check for non-Python scripts
+            words = string.split(line[2:])
+            if words and re.search('[pP]ython', words[0]) < 0:
+                msg = filename + ': ' + words[0]
+                msg = msg + ' script; not fixed\n'
+                err(msg)
+                f.close()
+                return 1
+        while line[-2:] == '\\\n':
+            nextline = f.readline()
+            if not nextline: break
+            line = line + nextline
+            lineno = lineno + 1
+        newline = fixline(line)
+        if newline != line:
+            if g is None:
+                try:
+                    g = open(tempname, 'w')
+                except IOError, msg:
+                    f.close()
+                    err('%s: cannot create: %r\n' % (tempname, msg))
+                    return 1
+                f.seek(0)
+                lineno = 0
+                rep(filename + ':\n')
+                continue # restart from the beginning
+            rep(repr(lineno) + '\n')
+            rep('< ' + line)
+            rep('> ' + newline)
+        if g is not None:
+            g.write(newline)
+
+    # End of file
+    f.close()
+    if not g: return 0 # No changes
+
+    # Finishing touch -- move files
+
+    # First copy the file's mode to the temp file
+    try:
+        statbuf = os.stat(filename)
+        os.chmod(tempname, statbuf[ST_MODE] & 07777)
+    except os.error, msg:
+        err('%s: warning: chmod failed (%r)\n' % (tempname, msg))
+    # Then make a backup of the original file as filename~
+    try:
+        os.rename(filename, filename + '~')
+    except os.error, msg:
+        err('%s: warning: backup failed (%r)\n' % (filename, msg))
+    # Now move the temp file to the original file
+    try:
+        os.rename(tempname, filename)
+    except os.error, msg:
+        err('%s: rename failed (%r)\n' % (filename, msg))
+        return 1
+    # Return succes
+    return 0
+
+
+from tokenize import tokenprog
+
+match = {'if':':', 'elif':':', 'while':':', 'return':'\n', \
+         '(':')', '[':']', '{':'}', '`':'`'}
+
+def fixline(line):
+    # Quick check for easy case
+    if '=' not in line: return line
+
+    i, n = 0, len(line)
+    stack = []
+    while i < n:
+        j = tokenprog.match(line, i)
+        if j < 0:
+            # A bad token; forget about the rest of this line
+            print '(Syntax error:)'
+            print line,
+            return line
+        a, b = tokenprog.regs[3] # Location of the token proper
+        token = line[a:b]
+        i = i+j
+        if stack and token == stack[-1]:
+            del stack[-1]
+        elif match.has_key(token):
+            stack.append(match[token])
+        elif token == '=' and stack:
+            line = line[:a] + '==' + line[b:]
+            i, n = a + len('=='), len(line)
+        elif token == '==' and not stack:
+            print '(Warning: \'==\' at top level:)'
+            print line,
+    return line
+
+if __name__ == "__main__":
+    main()


Property changes on: vendor/Python/current/Demo/scripts/eqfix.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/scripts/fact.py
===================================================================
--- vendor/Python/current/Demo/scripts/fact.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/scripts/fact.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,49 @@
+#! /usr/bin/env python
+
+# Factorize numbers.
+# The algorithm is not efficient, but easy to understand.
+# If there are large factors, it will take forever to find them,
+# because we try all odd numbers between 3 and sqrt(n)...
+
+import sys
+from math import sqrt
+
+error = 'fact.error'            # exception
+
+def fact(n):
+    if n < 1: raise error   # fact() argument should be >= 1
+    if n == 1: return []    # special case
+    res = []
+    # Treat even factors special, so we can use i = i+2 later
+    while n%2 == 0:
+        res.append(2)
+        n = n/2
+    # Try odd numbers up to sqrt(n)
+    limit = sqrt(float(n+1))
+    i = 3
+    while i <= limit:
+        if n%i == 0:
+            res.append(i)
+            n = n/i
+            limit = sqrt(n+1)
+        else:
+            i = i+2
+    if n != 1:
+        res.append(n)
+    return res
+
+def main():
+    if len(sys.argv) > 1:
+        for arg in sys.argv[1:]:
+            n = eval(arg)
+            print n, fact(n)
+    else:
+        try:
+            while 1:
+                n = input()
+                print n, fact(n)
+        except EOFError:
+            pass
+
+if __name__ == "__main__":
+    main()


Property changes on: vendor/Python/current/Demo/scripts/fact.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/scripts/find-uname.py
===================================================================
--- vendor/Python/current/Demo/scripts/find-uname.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/scripts/find-uname.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,40 @@
+#!/usr/bin/env python
+
+"""
+For each argument on the command line, look for it in the set of all Unicode
+names.  Arguments are treated as case-insensitive regular expressions, e.g.:
+
+    % find-uname 'small letter a$' 'horizontal line'
+    *** small letter a$ matches ***
+    LATIN SMALL LETTER A (97)
+    COMBINING LATIN SMALL LETTER A (867)
+    CYRILLIC SMALL LETTER A (1072)
+    PARENTHESIZED LATIN SMALL LETTER A (9372)
+    CIRCLED LATIN SMALL LETTER A (9424)
+    FULLWIDTH LATIN SMALL LETTER A (65345)
+    *** horizontal line matches ***
+    HORIZONTAL LINE EXTENSION (9135)
+"""
+
+import unicodedata
+import sys
+import re
+
+def main(args):
+    unicode_names= []
+    for ix in range(sys.maxunicode+1):
+        try:
+            unicode_names.append( (ix, unicodedata.name(unichr(ix))) )
+        except ValueError: # no name for the character
+            pass
+    for arg in args:
+        pat = re.compile(arg, re.I)
+        matches = [(x,y) for (x,y) in unicode_names
+                       if pat.search(y) is not None]
+        if matches:
+            print "***", arg, "matches", "***"
+            for (x,y) in matches:
+                print "%s (%d)" % (y,x)
+
+if __name__ == "__main__":
+    main(sys.argv[1:])

Added: vendor/Python/current/Demo/scripts/from.py
===================================================================
--- vendor/Python/current/Demo/scripts/from.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/scripts/from.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,35 @@
+#! /usr/bin/env python
+
+# Print From and Subject of messages in $MAIL.
+# Extension to multiple mailboxes and other bells & whistles are left
+# as exercises for the reader.
+
+import sys, os
+
+# Open mailbox file.  Exits with exception when this fails.
+
+try:
+    mailbox = os.environ['MAIL']
+except (AttributeError, KeyError):
+    sys.stderr.write('No environment variable $MAIL\n')
+    sys.exit(2)
+
+try:
+    mail = open(mailbox)
+except IOError:
+    sys.exit('Cannot open mailbox file: ' + mailbox)
+
+while 1:
+    line = mail.readline()
+    if not line:
+        break # EOF
+    if line.startswith('From '):
+        # Start of message found
+        print line[:-1],
+        while 1:
+            line = mail.readline()
+            if not line or line == '\n':
+                break
+            if line.startswith('Subject: '):
+                print repr(line[9:-1]),
+        print


Property changes on: vendor/Python/current/Demo/scripts/from.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/scripts/ftpstats.py
===================================================================
--- vendor/Python/current/Demo/scripts/ftpstats.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/scripts/ftpstats.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,145 @@
+#! /usr/bin/env python
+
+# Extract statistics from ftp daemon log.
+
+# Usage:
+# ftpstats [-m maxitems] [-s search] [file]
+# -m maxitems: restrict number of items in "top-N" lists, default 25.
+# -s string:   restrict statistics to lines containing this string.
+# Default file is /usr/adm/ftpd;  a "-" means read standard input.
+
+# The script must be run on the host where the ftp daemon runs.
+# (At CWI this is currently buizerd.)
+
+import os
+import sys
+import re
+import string
+import getopt
+
+pat = '^([a-zA-Z0-9 :]*)!(.*)!(.*)!([<>].*)!([0-9]+)!([0-9]+)$'
+prog = re.compile(pat)
+
+def main():
+    maxitems = 25
+    search = None
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], 'm:s:')
+    except getopt.error, msg:
+        print msg
+        print 'usage: ftpstats [-m maxitems] [file]'
+        sys.exit(2)
+    for o, a in opts:
+        if o == '-m':
+            maxitems = string.atoi(a)
+        if o == '-s':
+            search = a
+    file = '/usr/adm/ftpd'
+    if args: file = args[0]
+    if file == '-':
+        f = sys.stdin
+    else:
+        try:
+            f = open(file, 'r')
+        except IOError, msg:
+            print file, ':', msg
+            sys.exit(1)
+    bydate = {}
+    bytime = {}
+    byfile = {}
+    bydir = {}
+    byhost = {}
+    byuser = {}
+    bytype = {}
+    lineno = 0
+    try:
+        while 1:
+            line = f.readline()
+            if not line: break
+            lineno = lineno + 1
+            if search and string.find(line, search) < 0:
+                continue
+            if prog.match(line) < 0:
+                print 'Bad line', lineno, ':', repr(line)
+                continue
+            items = prog.group(1, 2, 3, 4, 5, 6)
+            (logtime, loguser, loghost, logfile, logbytes,
+             logxxx2) = items
+##                      print logtime
+##                      print '-->', loguser
+##                      print '--> -->', loghost
+##                      print '--> --> -->', logfile
+##                      print '--> --> --> -->', logbytes
+##                      print '--> --> --> --> -->', logxxx2
+##                      for i in logtime, loghost, logbytes, logxxx2:
+##                              if '!' in i: print '???', i
+            add(bydate, logtime[-4:] + ' ' + logtime[:6], items)
+            add(bytime, logtime[7:9] + ':00-59', items)
+            direction, logfile = logfile[0], logfile[1:]
+            # The real path probably starts at the last //...
+            while 1:
+                i = string.find(logfile, '//')
+                if i < 0: break
+                logfile = logfile[i+1:]
+            add(byfile, logfile + ' ' + direction, items)
+            logdir = os.path.dirname(logfile)
+##              logdir = os.path.normpath(logdir) + '/.'
+            while 1:
+                add(bydir, logdir + ' ' + direction, items)
+                dirhead = os.path.dirname(logdir)
+                if dirhead == logdir: break
+                logdir = dirhead
+            add(byhost, loghost, items)
+            add(byuser, loguser, items)
+            add(bytype, direction, items)
+    except KeyboardInterrupt:
+        print 'Interrupted at line', lineno
+    show(bytype, 'by transfer direction', maxitems)
+    show(bydir, 'by directory', maxitems)
+    show(byfile, 'by file', maxitems)
+    show(byhost, 'by host', maxitems)
+    show(byuser, 'by user', maxitems)
+    showbar(bydate, 'by date')
+    showbar(bytime, 'by time of day')
+
+def showbar(dict, title):
+    n = len(title)
+    print '='*((70-n)/2), title, '='*((71-n)/2)
+    list = []
+    keys = dict.keys()
+    keys.sort()
+    for key in keys:
+        n = len(str(key))
+        list.append((len(dict[key]), key))
+    maxkeylength = 0
+    maxcount = 0
+    for count, key in list:
+        maxkeylength = max(maxkeylength, len(key))
+        maxcount = max(maxcount, count)
+    maxbarlength = 72 - maxkeylength - 7
+    for count, key in list:
+        barlength = int(round(maxbarlength*float(count)/maxcount))
+        bar = '*'*barlength
+        print '%5d %-*s %s' % (count, maxkeylength, key, bar)
+
+def show(dict, title, maxitems):
+    if len(dict) > maxitems:
+        title = title + ' (first %d)'%maxitems
+    n = len(title)
+    print '='*((70-n)/2), title, '='*((71-n)/2)
+    list = []
+    keys = dict.keys()
+    for key in keys:
+        list.append((-len(dict[key]), key))
+    list.sort()
+    for count, key in list[:maxitems]:
+        print '%5d %s' % (-count, key)
+
+def add(dict, key, item):
+    if dict.has_key(key):
+        dict[key].append(item)
+    else:
+        dict[key] = [item]
+
+if __name__ == "__main__":
+    main()


Property changes on: vendor/Python/current/Demo/scripts/ftpstats.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/scripts/lpwatch.py
===================================================================
--- vendor/Python/current/Demo/scripts/lpwatch.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/scripts/lpwatch.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,110 @@
+#! /usr/bin/env python
+
+# Watch line printer queue(s).
+# Intended for BSD 4.3 lpq.
+
+import posix
+import sys
+import time
+import string
+
+DEF_PRINTER = 'psc'
+DEF_DELAY = 10
+
+def main():
+    delay = DEF_DELAY # XXX Use getopt() later
+    try:
+        thisuser = posix.environ['LOGNAME']
+    except:
+        thisuser = posix.environ['USER']
+    printers = sys.argv[1:]
+    if printers:
+        # Strip '-P' from printer names just in case
+        # the user specified it...
+        for i in range(len(printers)):
+            if printers[i][:2] == '-P':
+                printers[i] = printers[i][2:]
+    else:
+        if posix.environ.has_key('PRINTER'):
+            printers = [posix.environ['PRINTER']]
+        else:
+            printers = [DEF_PRINTER]
+    #
+    clearhome = posix.popen('clear', 'r').read()
+    #
+    while 1:
+        text = clearhome
+        for name in printers:
+            text = text + makestatus(name, thisuser) + '\n'
+        print text
+        time.sleep(delay)
+
+def makestatus(name, thisuser):
+    pipe = posix.popen('lpq -P' + name + ' 2>&1', 'r')
+    lines = []
+    users = {}
+    aheadbytes = 0
+    aheadjobs = 0
+    userseen = 0
+    totalbytes = 0
+    totaljobs = 0
+    while 1:
+        line = pipe.readline()
+        if not line: break
+        fields = string.split(line)
+        n = len(fields)
+        if len(fields) >= 6 and fields[n-1] == 'bytes':
+            rank = fields[0]
+            user = fields[1]
+            job = fields[2]
+            files = fields[3:-2]
+            bytes = eval(fields[n-2])
+            if user == thisuser:
+                userseen = 1
+            elif not userseen:
+                aheadbytes = aheadbytes + bytes
+                aheadjobs = aheadjobs + 1
+            totalbytes = totalbytes + bytes
+            totaljobs = totaljobs + 1
+            if users.has_key(user):
+                ujobs, ubytes = users[user]
+            else:
+                ujobs, ubytes = 0, 0
+            ujobs = ujobs + 1
+            ubytes = ubytes + bytes
+            users[user] = ujobs, ubytes
+        else:
+            if fields and fields[0] <> 'Rank':
+                line = string.strip(line)
+                if line == 'no entries':
+                    line = name + ': idle'
+                elif line[-22:] == ' is ready and printing':
+                    line = name
+                lines.append(line)
+    #
+    if totaljobs:
+        line = '%d K' % ((totalbytes+1023)/1024)
+        if totaljobs <> len(users):
+            line = line + ' (%d jobs)' % totaljobs
+        if len(users) == 1:
+            line = line + ' for %s' % (users.keys()[0],)
+        else:
+            line = line + ' for %d users' % len(users)
+            if userseen:
+                if aheadjobs == 0:
+                    line =  line + ' (%s first)' % thisuser
+                else:
+                    line = line + ' (%d K before %s)' % (
+                                   (aheadbytes+1023)/1024, thisuser)
+        lines.append(line)
+    #
+    sts = pipe.close()
+    if sts:
+        lines.append('lpq exit status %r' % (sts,))
+    return string.joinfields(lines, ': ')
+
+if __name__ == "__main__":
+    try:
+        main()
+    except KeyboardInterrupt:
+        pass


Property changes on: vendor/Python/current/Demo/scripts/lpwatch.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/scripts/makedir.py
===================================================================
--- vendor/Python/current/Demo/scripts/makedir.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/scripts/makedir.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,21 @@
+#! /usr/bin/env python
+
+# Like mkdir, but also make intermediate directories if necessary.
+# It is not an error if the given directory already exists (as long
+# as it is a directory).
+# Errors are not treated specially -- you just get a Python exception.
+
+import sys, os
+
+def main():
+    for p in sys.argv[1:]:
+        makedirs(p)
+
+def makedirs(p):
+    if p and not os.path.isdir(p):
+        head, tail = os.path.split(p)
+        makedirs(head)
+        os.mkdir(p, 0777)
+
+if __name__ == "__main__":
+    main()


Property changes on: vendor/Python/current/Demo/scripts/makedir.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/scripts/markov.py
===================================================================
--- vendor/Python/current/Demo/scripts/markov.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/scripts/markov.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,117 @@
+#! /usr/bin/env python
+
+class Markov:
+    def __init__(self, histsize, choice):
+        self.histsize = histsize
+        self.choice = choice
+        self.trans = {}
+    def add(self, state, next):
+        if not self.trans.has_key(state):
+            self.trans[state] = [next]
+        else:
+            self.trans[state].append(next)
+    def put(self, seq):
+        n = self.histsize
+        add = self.add
+        add(None, seq[:0])
+        for i in range(len(seq)):
+            add(seq[max(0, i-n):i], seq[i:i+1])
+        add(seq[len(seq)-n:], None)
+    def get(self):
+        choice = self.choice
+        trans = self.trans
+        n = self.histsize
+        seq = choice(trans[None])
+        while 1:
+            subseq = seq[max(0, len(seq)-n):]
+            options = trans[subseq]
+            next = choice(options)
+            if not next: break
+            seq = seq + next
+        return seq
+
+def test():
+    import sys, string, random, getopt
+    args = sys.argv[1:]
+    try:
+        opts, args = getopt.getopt(args, '0123456789cdw')
+    except getopt.error:
+        print 'Usage: markov [-#] [-cddqw] [file] ...'
+        print 'Options:'
+        print '-#: 1-digit history size (default 2)'
+        print '-c: characters (default)'
+        print '-w: words'
+        print '-d: more debugging output'
+        print '-q: no debugging output'
+        print 'Input files (default stdin) are split in paragraphs'
+        print 'separated blank lines and each paragraph is split'
+        print 'in words by whitespace, then reconcatenated with'
+        print 'exactly one space separating words.'
+        print 'Output consists of paragraphs separated by blank'
+        print 'lines, where lines are no longer than 72 characters.'
+    histsize = 2
+    do_words = 0
+    debug = 1
+    for o, a in opts:
+        if '-0' <= o <= '-9': histsize = eval(o[1:])
+        if o == '-c': do_words = 0
+        if o == '-d': debug = debug + 1
+        if o == '-q': debug = 0
+        if o == '-w': do_words = 1
+    if not args: args = ['-']
+    m = Markov(histsize, random.choice)
+    try:
+        for filename in args:
+            if filename == '-':
+                f = sys.stdin
+                if f.isatty():
+                    print 'Sorry, need stdin from file'
+                    continue
+            else:
+                f = open(filename, 'r')
+            if debug: print 'processing', filename, '...'
+            text = f.read()
+            f.close()
+            paralist = string.splitfields(text, '\n\n')
+            for para in paralist:
+                if debug > 1: print 'feeding ...'
+                words = string.split(para)
+                if words:
+                    if do_words: data = tuple(words)
+                    else: data = string.joinfields(words, ' ')
+                    m.put(data)
+    except KeyboardInterrupt:
+        print 'Interrupted -- continue with data read so far'
+    if not m.trans:
+        print 'No valid input files'
+        return
+    if debug: print 'done.'
+    if debug > 1:
+        for key in m.trans.keys():
+            if key is None or len(key) < histsize:
+                print repr(key), m.trans[key]
+        if histsize == 0: print repr(''), m.trans['']
+        print
+    while 1:
+        data = m.get()
+        if do_words: words = data
+        else: words = string.split(data)
+        n = 0
+        limit = 72
+        for w in words:
+            if n + len(w) > limit:
+                print
+                n = 0
+            print w,
+            n = n + len(w) + 1
+        print
+        print
+
+def tuple(list):
+    if len(list) == 0: return ()
+    if len(list) == 1: return (list[0],)
+    i = len(list)/2
+    return tuple(list[:i]) + tuple(list[i:])
+
+if __name__ == "__main__":
+    test()


Property changes on: vendor/Python/current/Demo/scripts/markov.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/scripts/mboxconvert.py
===================================================================
--- vendor/Python/current/Demo/scripts/mboxconvert.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/scripts/mboxconvert.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,124 @@
+#! /usr/bin/env python
+
+# Convert  MH directories (1 message per file) or MMDF mailboxes (4x^A
+# delimited) to unix mailbox (From ... delimited) on stdout.
+# If -f is given, files contain one message per file (e.g. MH messages)
+
+import rfc822
+import sys
+import time
+import os
+import stat
+import getopt
+import re
+
+def main():
+    dofile = mmdf
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], 'f')
+    except getopt.error, msg:
+        sys.stderr.write('%s\n' % msg)
+        sys.exit(2)
+    for o, a in opts:
+        if o == '-f':
+            dofile = message
+    if not args:
+        args = ['-']
+    sts = 0
+    for arg in args:
+        if arg == '-' or arg == '':
+            sts = dofile(sys.stdin) or sts
+        elif os.path.isdir(arg):
+            sts = mh(arg) or sts
+        elif os.path.isfile(arg):
+            try:
+                f = open(arg)
+            except IOError, msg:
+                sys.stderr.write('%s: %s\n' % (arg, msg))
+                sts = 1
+                continue
+            sts = dofile(f) or sts
+            f.close()
+        else:
+            sys.stderr.write('%s: not found\n' % arg)
+            sts = 1
+    if sts:
+        sys.exit(sts)
+
+numeric = re.compile('[1-9][0-9]*')
+
+def mh(dir):
+    sts = 0
+    msgs = os.listdir(dir)
+    for msg in msgs:
+        if numeric.match(msg) != len(msg):
+            continue
+        fn = os.path.join(dir, msg)
+        try:
+            f = open(fn)
+        except IOError, msg:
+            sys.stderr.write('%s: %s\n' % (fn, msg))
+            sts = 1
+            continue
+        sts = message(f) or sts
+    return sts
+
+def mmdf(f):
+    sts = 0
+    while 1:
+        line = f.readline()
+        if not line:
+            break
+        if line == '\1\1\1\1\n':
+            sts = message(f, line) or sts
+        else:
+            sys.stderr.write(
+                    'Bad line in MMFD mailbox: %r\n' % (line,))
+    return sts
+
+counter = 0 # for generating unique Message-ID headers
+
+def message(f, delimiter = ''):
+    sts = 0
+    # Parse RFC822 header
+    m = rfc822.Message(f)
+    # Write unix header line
+    fullname, email = m.getaddr('From')
+    tt = m.getdate('Date')
+    if tt:
+        t = time.mktime(tt)
+    else:
+        sys.stderr.write(
+                'Unparseable date: %r\n' % (m.getheader('Date'),))
+        t = os.fstat(f.fileno())[stat.ST_MTIME]
+    print 'From', email, time.ctime(t)
+    # Copy RFC822 header
+    for line in m.headers:
+        print line,
+    # Invent Message-ID header if none is present
+    if not m.has_key('message-id'):
+        global counter
+        counter = counter + 1
+        msgid = "<%s.%d>" % (hex(t), counter)
+        sys.stderr.write("Adding Message-ID %s (From %s)\n" %
+                         (msgid, email))
+        print "Message-ID:", msgid
+    print
+    # Copy body
+    while 1:
+        line = f.readline()
+        if line == delimiter:
+            break
+        if not line:
+            sys.stderr.write('Unexpected EOF in message\n')
+            sts = 1
+            break
+        if line[:5] == 'From ':
+            line = '>' + line
+        print line,
+    # Print trailing newline
+    print
+    return sts
+
+if __name__ == "__main__":
+    main()


Property changes on: vendor/Python/current/Demo/scripts/mboxconvert.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/scripts/mkrcs.py
===================================================================
--- vendor/Python/current/Demo/scripts/mkrcs.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/scripts/mkrcs.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,61 @@
+#! /usr/bin/env python
+
+# A rather specialized script to make sure that a symbolic link named
+# RCS exists pointing to a real RCS directory in a parallel tree
+# referenced as RCStree in an ancestor directory.
+# (I use this because I like my RCS files to reside on a physically
+# different machine).
+
+import os
+
+def main():
+    rcstree = 'RCStree'
+    rcs = 'RCS'
+    if os.path.islink(rcs):
+        print '%r is a symlink to %r' % (rcs, os.readlink(rcs))
+        return
+    if os.path.isdir(rcs):
+        print '%r is an ordinary directory' % (rcs,)
+        return
+    if os.path.exists(rcs):
+        print '%r is a file?!?!' % (rcs,)
+        return
+    #
+    p = os.getcwd()
+    up = ''
+    down = ''
+    # Invariants:
+    # (1) join(p, down) is the current directory
+    # (2) up is the same directory as p
+    # Ergo:
+    # (3) join(up, down) is the current directory
+    #print 'p =', repr(p)
+    while not os.path.isdir(os.path.join(p, rcstree)):
+        head, tail = os.path.split(p)
+        #print 'head = %r; tail = %r' % (head, tail)
+        if not tail:
+            print 'Sorry, no ancestor dir contains %r' % (rcstree,)
+            return
+        p = head
+        up = os.path.join(os.pardir, up)
+        down = os.path.join(tail, down)
+        #print 'p = %r; up = %r; down = %r' % (p, up, down)
+    there = os.path.join(up, rcstree)
+    there = os.path.join(there, down)
+    there = os.path.join(there, rcs)
+    if os.path.isdir(there):
+        print '%r already exists' % (there, )
+    else:
+        print 'making %r' % (there,)
+        makedirs(there)
+    print 'making symlink %r -> %r' % (rcs, there)
+    os.symlink(there, rcs)
+
+def makedirs(p):
+    if not os.path.isdir(p):
+        head, tail = os.path.split(p)
+        makedirs(head)
+        os.mkdir(p, 0777)
+
+if __name__ == "__main__":
+    main()


Property changes on: vendor/Python/current/Demo/scripts/mkrcs.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/scripts/morse.py
===================================================================
--- vendor/Python/current/Demo/scripts/morse.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/scripts/morse.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,149 @@
+# DAH should be three DOTs.
+# Space between DOTs and DAHs should be one DOT.
+# Space between two letters should be one DAH.
+# Space between two words should be DOT DAH DAH.
+
+import sys, math, audiodev
+
+DOT = 30
+DAH = 3 * DOT
+OCTAVE = 2                              # 1 == 441 Hz, 2 == 882 Hz, ...
+
+morsetab = {
+        'A': '.-',              'a': '.-',
+        'B': '-...',            'b': '-...',
+        'C': '-.-.',            'c': '-.-.',
+        'D': '-..',             'd': '-..',
+        'E': '.',               'e': '.',
+        'F': '..-.',            'f': '..-.',
+        'G': '--.',             'g': '--.',
+        'H': '....',            'h': '....',
+        'I': '..',              'i': '..',
+        'J': '.---',            'j': '.---',
+        'K': '-.-',             'k': '-.-',
+        'L': '.-..',            'l': '.-..',
+        'M': '--',              'm': '--',
+        'N': '-.',              'n': '-.',
+        'O': '---',             'o': '---',
+        'P': '.--.',            'p': '.--.',
+        'Q': '--.-',            'q': '--.-',
+        'R': '.-.',             'r': '.-.',
+        'S': '...',             's': '...',
+        'T': '-',               't': '-',
+        'U': '..-',             'u': '..-',
+        'V': '...-',            'v': '...-',
+        'W': '.--',             'w': '.--',
+        'X': '-..-',            'x': '-..-',
+        'Y': '-.--',            'y': '-.--',
+        'Z': '--..',            'z': '--..',
+        '0': '-----',
+        '1': '.----',
+        '2': '..---',
+        '3': '...--',
+        '4': '....-',
+        '5': '.....',
+        '6': '-....',
+        '7': '--...',
+        '8': '---..',
+        '9': '----.',
+        ',': '--..--',
+        '.': '.-.-.-',
+        '?': '..--..',
+        ';': '-.-.-.',
+        ':': '---...',
+        "'": '.----.',
+        '-': '-....-',
+        '/': '-..-.',
+        '(': '-.--.-',
+        ')': '-.--.-',
+        '_': '..--.-',
+        ' ': ' '
+}
+
+# If we play at 44.1 kHz (which we do), then if we produce one sine
+# wave in 100 samples, we get a tone of 441 Hz.  If we produce two
+# sine waves in these 100 samples, we get a tone of 882 Hz.  882 Hz
+# appears to be a nice one for playing morse code.
+def mkwave(octave):
+    global sinewave, nowave
+    sinewave = ''
+    for i in range(100):
+        val = int(math.sin(math.pi * float(i) * octave / 50.0) * 30000)
+        sinewave = sinewave + chr((val >> 8) & 255) + chr(val & 255)
+    nowave = '\0' * 200
+
+mkwave(OCTAVE)
+
+def main():
+    import getopt, string
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], 'o:p:')
+    except getopt.error:
+        sys.stderr.write('Usage ' + sys.argv[0] +
+                         ' [ -o outfile ] [ args ] ...\n')
+        sys.exit(1)
+    dev = None
+    for o, a in opts:
+        if o == '-o':
+            import aifc
+            dev = aifc.open(a, 'w')
+            dev.setframerate(44100)
+            dev.setsampwidth(2)
+            dev.setnchannels(1)
+        if o == '-p':
+            mkwave(string.atoi(a))
+    if not dev:
+        import audiodev
+        dev = audiodev.AudioDev()
+        dev.setoutrate(44100)
+        dev.setsampwidth(2)
+        dev.setnchannels(1)
+        dev.close = dev.stop
+        dev.writeframesraw = dev.writeframes
+    if args:
+        line = string.join(args)
+    else:
+        line = sys.stdin.readline()
+    while line:
+        mline = morse(line)
+        play(mline, dev)
+        if hasattr(dev, 'wait'):
+            dev.wait()
+        if not args:
+            line = sys.stdin.readline()
+        else:
+            line = ''
+    dev.close()
+
+# Convert a string to morse code with \001 between the characters in
+# the string.
+def morse(line):
+    res = ''
+    for c in line:
+        try:
+            res = res + morsetab[c] + '\001'
+        except KeyError:
+            pass
+    return res
+
+# Play a line of morse code.
+def play(line, dev):
+    for c in line:
+        if c == '.':
+            sine(dev, DOT)
+        elif c == '-':
+            sine(dev, DAH)
+        else:                   # space
+            pause(dev, DAH + DOT)
+        pause(dev, DOT)
+
+def sine(dev, length):
+    for i in range(length):
+        dev.writeframesraw(sinewave)
+
+def pause(dev, length):
+    for i in range(length):
+        dev.writeframesraw(nowave)
+
+if __name__ == '__main__' or sys.argv[0] == __name__:
+    main()


Property changes on: vendor/Python/current/Demo/scripts/morse.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/scripts/newslist.doc
===================================================================
--- vendor/Python/current/Demo/scripts/newslist.doc	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/scripts/newslist.doc	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,59 @@
+                             NEWSLIST
+                             ========    
+            A program to assist HTTP browsing of newsgroups
+            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+WWW browsers such as NCSA Mosaic allow the user to read newsgroup
+articles by specifying the group name in a URL eg 'news:comp.answers'.
+
+To browse through many groups, though, (and there are several thousand
+of them) you really need a page or pages containing links to all the
+groups. There are some good ones out there, for example,
+
+    http://info.cern.ch/hypertext/DataSources/News/Groups/Overview.html
+
+is the standard one at CERN, but it only shows the groups available there,
+which may be rather different from those available on your machine.
+
+Newslist is a program which creates a hierarchy of pages for you based
+on the groups available from YOUR server. It is written in python - a
+splendid interpreted object-oriented language which I suggest you get
+right now from the directory /pub/python at ftp.cwi.nl, if you haven't
+already got it.
+
+You should be able to see some sample output by looking at:
+   http://pelican.cl.cam.ac.uk/newspage/root.html
+
+Descriptions of newsgroups can be added from a file with one group
+per line. eg:
+
+	alt.foo   Articles about foo
+	comp.bar  Programming in 'bar' and related languages
+
+A suitable list detailing most groups can be found at ftp.uu.net in
+/uunet-info/newsgroups.gz.
+
+Make sure you read the information at the beginning of the program source and
+configure the variables before running.
+
+In addition to python, you need:
+
+	An NNTP-based news feed.
+	A directory in which to put the pages.
+
+The programming is not very beautiful, but it works!  It comes with no
+warranty, express or implied, but with the hope that some others may
+find it useful.
+
+Comments, improvements & suggestions welcomed.
+Quentin Stafford-Fraser
+
+ ----------------------------------------------------------------------
+                       Quentin Stafford-Fraser
+            http://pelican.cl.cam.ac.uk/people/qs101/me.html
+ 
+ Cambridge University Computer Lab        Rank Xerox Cambridge EuroPARC
+ qs101 at cl.cam.ac.uk                           fraser at europarc.xerox.com
+ Tel: +44 223 334411                                Tel: +44 223 341521
+ Fax: +44 223 334679                                Fax: +44 223 341510
+ ----------------------------------------------------------------------


Property changes on: vendor/Python/current/Demo/scripts/newslist.doc
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/scripts/newslist.py
===================================================================
--- vendor/Python/current/Demo/scripts/newslist.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/scripts/newslist.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,366 @@
+#! /usr/bin/env python
+#######################################################################
+# Newslist  $Revision: 37320 $
+#
+# Syntax:
+#    newslist [ -a ]
+#
+# This is a program to create a directory full of HTML pages
+# which between them contain links to all the newsgroups available
+# on your server.
+#
+# The -a option causes a complete list of all groups to be read from
+# the server rather than just the ones which have appeared since last
+# execution. This recreates the local list from scratch. Use this on
+# the first invocation of the program, and from time to time thereafter.
+#   When new groups are first created they may appear on your server as
+# empty groups. By default, empty groups are ignored by the -a option.
+# However, these new groups will not be created again, and so will not
+# appear in the server's list of 'new groups' at a later date. Hence it
+# won't appear until you do a '-a' after some articles have appeared.
+#
+# I should really keep a list of ignored empty groups and re-check them
+# for articles on every run, but I haven't got around to it yet.
+#
+# This assumes an NNTP news feed.
+#
+# Feel free to copy, distribute and modify this code for
+# non-commercial use. If you make any useful modifications, let me
+# know!
+#
+# (c) Quentin Stafford-Fraser 1994
+# fraser at europarc.xerox.com                     qs101 at cl.cam.ac.uk
+#                                                                     #
+#######################################################################
+import sys,nntplib, string, marshal, time, os, posix, string
+
+#######################################################################
+# Check these variables before running!                               #
+
+# Top directory.
+# Filenames which don't start with / are taken as being relative to this.
+topdir='/anfs/qsbigdisc/web/html/newspage'
+
+# The name of your NNTP host
+# eg.
+#    newshost = 'nntp-serv.cl.cam.ac.uk'
+# or use following to get the name from the NNTPSERVER environment
+# variable:
+#    newshost = posix.environ['NNTPSERVER']
+newshost = 'nntp-serv.cl.cam.ac.uk'
+
+# The filename for a local cache of the newsgroup list
+treefile = 'grouptree'
+
+# The filename for descriptions of newsgroups
+# I found a suitable one at ftp.uu.net in /uunet-info/newgroups.gz
+# You can set this to '' if you don't wish to use one.
+descfile = 'newsgroups'
+
+# The directory in which HTML pages should be created
+# eg.
+#   pagedir  = '/usr/local/lib/html/newspage'
+#   pagedir  = 'pages'
+pagedir  = topdir
+
+# The html prefix which will refer to this directory
+# eg.
+#   httppref = '/newspage/',
+# or leave blank for relative links between pages: (Recommended)
+#   httppref = ''
+httppref = ''
+
+# The name of the 'root' news page in this directory.
+# A .html suffix will be added.
+rootpage = 'root'
+
+# Set skipempty to 0 if you wish to see links to empty groups as well.
+# Only affects the -a option.
+skipempty = 1
+
+# pagelinkicon can contain html to put an icon after links to
+# further pages. This helps to make important links stand out.
+# Set to '' if not wanted, or '...' is quite a good one.
+pagelinkicon='... <img src="http://pelican.cl.cam.ac.uk/icons/page.xbm"> '
+
+# ---------------------------------------------------------------------
+# Less important personal preferences:
+
+# Sublistsize controls the maximum number of items the will appear as
+# an indented sub-list before the whole thing is moved onto a different
+# page. The smaller this is, the more pages you will have, but the
+# shorter each will be.
+sublistsize = 4
+
+# That should be all.                                                 #
+#######################################################################
+
+for dir in os.curdir, os.environ['HOME']:
+    rcfile = os.path.join(dir, '.newslistrc.py')
+    if os.path.exists(rcfile):
+        print rcfile
+        execfile(rcfile)
+        break
+
+from nntplib import NNTP
+from stat import *
+
+rcsrev = '$Revision: 37320 $'
+rcsrev = string.join(filter(lambda s: '$' not in s, string.split(rcsrev)))
+desc = {}
+
+# Make (possibly) relative filenames into absolute ones
+treefile = os.path.join(topdir,treefile)
+descfile = os.path.join(topdir,descfile)
+page = os.path.join(topdir,pagedir)
+
+# First the bits for creating trees ---------------------------
+
+# Addtotree creates/augments a tree from a list of group names
+def addtotree(tree, groups):
+    print 'Updating tree...'
+    for i in groups:
+        parts = string.splitfields(i,'.')
+        makeleaf(tree, parts)
+
+# Makeleaf makes a leaf and the branch leading to it if necessary
+def makeleaf(tree,path):
+    j = path[0]
+    l = len(path)
+
+    if not tree.has_key(j):
+        tree[j] = {}
+    if l == 1:
+        tree[j]['.'] = '.'
+    if l > 1:
+        makeleaf(tree[j],path[1:])
+
+# Then the bits for outputting trees as pages ----------------
+
+# Createpage creates an HTML file named <root>.html containing links
+# to those groups beginning with <root>.
+
+def createpage(root, tree, p):
+    filename = os.path.join(pagedir,root+'.html')
+    if root == rootpage:
+        detail = ''
+    else:
+        detail = ' under ' + root
+    f = open(filename,'w')
+    # f.write('Content-Type: text/html\n')
+    f.write('<TITLE>Newsgroups available' + detail + '</TITLE>\n')
+    f.write('<H1>Newsgroups available' + detail +'</H1>\n')
+    f.write('<A HREF="'+httppref+rootpage+'.html">Back to top level</A><P>\n')
+    printtree(f,tree,0,p)
+    f.write('<I>This page automatically created by \'newslist\' v. '+rcsrev+'.')
+    f.write(time.ctime(time.time()) + '</I><P>')
+    f.close()
+
+# Printtree prints the groups as a bulleted list.  Groups with
+# more than <sublistsize> subgroups will be put on a separate page.
+# Other sets of subgroups are just indented.
+
+def printtree(f, tree, indent, p):
+    global desc
+    l = len(tree)
+
+    if l > sublistsize and indent>0:
+        # Create a new page and a link to it
+        f.write('<LI><B><A HREF="'+httppref+p[1:]+'.html">')
+        f.write(p[1:]+'.*')
+        f.write('</A></B>'+pagelinkicon+'\n')
+        createpage(p[1:], tree, p)
+        return
+
+    kl = tree.keys()
+
+    if l > 1:
+        kl.sort()
+        if indent > 0:
+            # Create a sub-list
+            f.write('<LI>'+p[1:]+'\n<UL>')
+        else:
+            # Create a main list
+            f.write('<UL>')
+        indent = indent + 1
+
+    for i in kl:
+        if i == '.':
+            # Output a newsgroup
+            f.write('<LI><A HREF="news:' + p[1:] + '">'+ p[1:] + '</A> ')
+            if desc.has_key(p[1:]):
+                f.write('     <I>'+desc[p[1:]]+'</I>\n')
+            else:
+                f.write('\n')
+        else:
+            # Output a hierarchy
+            printtree(f,tree[i], indent, p+'.'+i)
+
+    if l > 1:
+        f.write('\n</UL>')
+
+# Reading descriptions file ---------------------------------------
+
+# This returns an array mapping group name to its description
+
+def readdesc(descfile):
+    global desc
+
+    desc = {}
+
+    if descfile == '':
+        return
+
+    try:
+        d = open(descfile, 'r')
+        print 'Reading descriptions...'
+    except (IOError):
+        print 'Failed to open description file ' + descfile
+        return
+    l = d.readline()
+    while l != '':
+        bits = string.split(l)
+        try:
+            grp = bits[0]
+            dsc = string.join(bits[1:])
+            if len(dsc)>1:
+                desc[grp] = dsc
+        except (IndexError):
+            pass
+        l = d.readline()
+
+# Check that ouput directory exists, ------------------------------
+# and offer to create it if not
+
+def checkopdir(pagedir):
+    if not os.path.isdir(pagedir):
+        print 'Directory '+pagedir+' does not exist.'
+        print 'Shall I create it for you? (y/n)'
+        if sys.stdin.readline()[0] == 'y':
+            try:
+                os.mkdir(pagedir,0777)
+            except:
+                print 'Sorry - failed!'
+                sys.exit(1)
+        else:
+            print 'OK. Exiting.'
+            sys.exit(1)
+
+# Read and write current local tree ----------------------------------
+
+def readlocallist(treefile):
+    print 'Reading current local group list...'
+    tree = {}
+    try:
+        treetime = time.localtime(os.stat(treefile)[ST_MTIME])
+    except:
+        print '\n*** Failed to open local group cache '+treefile
+        print 'If this is the first time you have run newslist, then'
+        print 'use the -a option to create it.'
+        sys.exit(1)
+    treedate = '%02d%02d%02d' % (treetime[0] % 100 ,treetime[1], treetime[2])
+    try:
+        dump = open(treefile,'r')
+        tree = marshal.load(dump)
+        dump.close()
+    except (IOError):
+        print 'Cannot open local group list ' + treefile
+    return (tree, treedate)
+
+def writelocallist(treefile, tree):
+    try:
+        dump = open(treefile,'w')
+        groups = marshal.dump(tree,dump)
+        dump.close()
+        print 'Saved list to '+treefile+'\n'
+    except:
+        print 'Sorry - failed to write to local group cache '+treefile
+        print 'Does it (or its directory) have the correct permissions?'
+        sys.exit(1)
+
+# Return list of all groups on server -----------------------------
+
+def getallgroups(server):
+    print 'Getting list of all groups...'
+    treedate='010101'
+    info = server.list()[1]
+    groups = []
+    print 'Processing...'
+    if skipempty:
+        print '\nIgnoring following empty groups:'
+    for i in info:
+        grpname = string.split(i[0])[0]
+        if skipempty and string.atoi(i[1]) < string.atoi(i[2]):
+            print grpname+' ',
+        else:
+            groups.append(grpname)
+    print '\n'
+    if skipempty:
+        print '(End of empty groups)'
+    return groups
+
+# Return list of new groups on server -----------------------------
+
+def getnewgroups(server, treedate):
+    print 'Getting list of new groups since start of '+treedate+'...',
+    info = server.newgroups(treedate,'000001')[1]
+    print 'got %d.' % len(info)
+    print 'Processing...',
+    groups = []
+    for i in info:
+        grpname = string.split(i)[0]
+        groups.append(grpname)
+    print 'Done'
+    return groups
+
+# Now the main program --------------------------------------------
+
+def main():
+    global desc
+
+    tree={}
+
+    # Check that the output directory exists
+    checkopdir(pagedir);
+
+    try:
+        print 'Connecting to '+newshost+'...'
+        if sys.version[0] == '0':
+            s = NNTP.init(newshost)
+        else:
+            s = NNTP(newshost)
+        connected = 1
+    except (nntplib.error_temp, nntplib.error_perm), x:
+        print 'Error connecting to host:', x
+        print 'I\'ll try to use just the local list.'
+        connected = 0
+
+    # If -a is specified, read the full list of groups from server
+    if connected and len(sys.argv) > 1 and sys.argv[1] == '-a':
+
+        groups = getallgroups(s)
+
+    # Otherwise just read the local file and then add
+    # groups created since local file last modified.
+    else:
+
+        (tree, treedate) = readlocallist(treefile)
+        if connected:
+            groups = getnewgroups(s, treedate)
+
+    if connected:
+        addtotree(tree, groups)
+        writelocallist(treefile,tree)
+
+    # Read group descriptions
+    readdesc(descfile)
+
+    print 'Creating pages...'
+    createpage(rootpage, tree, '')
+    print 'Done'
+
+if __name__ == "__main__":
+    main()
+
+# That's all folks
+######################################################################


Property changes on: vendor/Python/current/Demo/scripts/newslist.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/scripts/pi.py
===================================================================
--- vendor/Python/current/Demo/scripts/pi.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/scripts/pi.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,34 @@
+#! /usr/bin/env python
+
+# Print digits of pi forever.
+#
+# The algorithm, using Python's 'long' integers ("bignums"), works
+# with continued fractions, and was conceived by Lambert Meertens.
+#
+# See also the ABC Programmer's Handbook, by Geurts, Meertens & Pemberton,
+# published by Prentice-Hall (UK) Ltd., 1990.
+
+import sys
+
+def main():
+    k, a, b, a1, b1 = 2L, 4L, 1L, 12L, 4L
+    while 1:
+        # Next approximation
+        p, q, k = k*k, 2L*k+1L, k+1L
+        a, b, a1, b1 = a1, b1, p*a+q*a1, p*b+q*b1
+        # Print common digits
+        d, d1 = a/b, a1/b1
+        while d == d1:
+            output(d)
+            a, a1 = 10L*(a%b), 10L*(a1%b1)
+            d, d1 = a/b, a1/b1
+
+def output(d):
+    # Use write() to avoid spaces between the digits
+    # Use str() to avoid the 'L'
+    sys.stdout.write(str(d))
+    # Flush so the output is seen immediately
+    sys.stdout.flush()
+
+if __name__ == "__main__":
+    main()


Property changes on: vendor/Python/current/Demo/scripts/pi.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/scripts/pp.py
===================================================================
--- vendor/Python/current/Demo/scripts/pp.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/scripts/pp.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,130 @@
+#! /usr/bin/env python
+
+# Emulate some Perl command line options.
+# Usage: pp [-a] [-c] [-d] [-e scriptline] [-F fieldsep] [-n] [-p] [file] ...
+# Where the options mean the following:
+#   -a            : together with -n or -p, splits each line into list F
+#   -c            : check syntax only, do not execute any code
+#   -d            : run the script under the debugger, pdb
+#   -e scriptline : gives one line of the Python script; may be repeated
+#   -F fieldsep   : sets the field separator for the -a option [not in Perl]
+#   -n            : runs the script for each line of input
+#   -p            : prints the line after the script has run
+# When no script lines have been passed, the first file argument
+# contains the script.  With -n or -p, the remaining arguments are
+# read as input to the script, line by line.  If a file is '-'
+# or missing, standard input is read.
+
+# XXX To do:
+# - add -i extension option (change files in place)
+# - make a single loop over the files and lines (changes effect of 'break')?
+# - add an option to specify the record separator
+# - except for -n/-p, run directly from the file if at all possible
+
+import sys
+import string
+import getopt
+
+FS = ''
+SCRIPT = []
+AFLAG = 0
+CFLAG = 0
+DFLAG = 0
+NFLAG = 0
+PFLAG = 0
+
+try:
+    optlist, ARGS = getopt.getopt(sys.argv[1:], 'acde:F:np')
+except getopt.error, msg:
+    sys.stderr.write(sys.argv[0] + ': ' + msg + '\n')
+    sys.exit(2)
+
+for option, optarg in optlist:
+    if option == '-a':
+        AFLAG = 1
+    elif option == '-c':
+        CFLAG = 1
+    elif option == '-d':
+        DFLAG = 1
+    elif option == '-e':
+        for line in string.splitfields(optarg, '\n'):
+            SCRIPT.append(line)
+    elif option == '-F':
+        FS = optarg
+    elif option == '-n':
+        NFLAG = 1
+        PFLAG = 0
+    elif option == '-p':
+        NFLAG = 1
+        PFLAG = 1
+    else:
+        print option, 'not recognized???'
+
+if not ARGS: ARGS.append('-')
+
+if not SCRIPT:
+    if ARGS[0] == '-':
+        fp = sys.stdin
+    else:
+        fp = open(ARGS[0], 'r')
+    while 1:
+        line = fp.readline()
+        if not line: break
+        SCRIPT.append(line[:-1])
+    del fp
+    del ARGS[0]
+    if not ARGS: ARGS.append('-')
+
+if CFLAG:
+    prologue = ['if 0:']
+    epilogue = []
+elif NFLAG:
+    # Note that it is on purpose that AFLAG and PFLAG are
+    # tested dynamically each time through the loop
+    prologue = [ \
+            'LINECOUNT = 0', \
+            'for FILE in ARGS:', \
+            '   \tif FILE == \'-\':', \
+            '   \t   \tFP = sys.stdin', \
+            '   \telse:', \
+            '   \t   \tFP = open(FILE, \'r\')', \
+            '   \tLINENO = 0', \
+            '   \twhile 1:', \
+            '   \t   \tLINE = FP.readline()', \
+            '   \t   \tif not LINE: break', \
+            '   \t   \tLINENO = LINENO + 1', \
+            '   \t   \tLINECOUNT = LINECOUNT + 1', \
+            '   \t   \tL = LINE[:-1]', \
+            '   \t   \taflag = AFLAG', \
+            '   \t   \tif aflag:', \
+            '   \t   \t   \tif FS: F = string.splitfields(L, FS)', \
+            '   \t   \t   \telse: F = string.split(L)' \
+            ]
+    epilogue = [ \
+            '   \t   \tif not PFLAG: continue', \
+            '   \t   \tif aflag:', \
+            '   \t   \t   \tif FS: print string.joinfields(F, FS)', \
+            '   \t   \t   \telse: print string.join(F)', \
+            '   \t   \telse: print L', \
+            ]
+else:
+    prologue = ['if 1:']
+    epilogue = []
+
+# Note that we indent using tabs only, so that any indentation style
+# used in 'command' will come out right after re-indentation.
+
+program = string.joinfields(prologue, '\n') + '\n'
+for line in SCRIPT:
+    program = program + ('   \t   \t' + line + '\n')
+program = program + (string.joinfields(epilogue, '\n') + '\n')
+
+import tempfile
+fp = tempfile.NamedTemporaryFile()
+fp.write(program)
+fp.flush()
+if DFLAG:
+    import pdb
+    pdb.run('execfile(%r)' % (tfn,))
+else:
+    execfile(tfn)


Property changes on: vendor/Python/current/Demo/scripts/pp.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/scripts/primes.py
===================================================================
--- vendor/Python/current/Demo/scripts/primes.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/scripts/primes.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,27 @@
+#! /usr/bin/env python
+
+# Print prime numbers in a given range
+
+def main():
+    import sys
+    min, max = 2, 0x7fffffff
+    if sys.argv[1:]:
+        min = int(eval(sys.argv[1]))
+        if sys.argv[2:]:
+            max = int(eval(sys.argv[2]))
+    primes(min, max)
+
+def primes(min, max):
+    if 2 >= min: print 2
+    primes = [2]
+    i = 3
+    while i <= max:
+        for p in primes:
+            if i%p == 0 or p*p > i: break
+        if i%p <> 0:
+            primes.append(i)
+            if i >= min: print i
+        i = i+2
+
+if __name__ == "__main__":
+    main()


Property changes on: vendor/Python/current/Demo/scripts/primes.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/scripts/queens.py
===================================================================
--- vendor/Python/current/Demo/scripts/queens.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/scripts/queens.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,85 @@
+#! /usr/bin/env python
+
+"""N queens problem.
+
+The (well-known) problem is due to Niklaus Wirth.
+
+This solution is inspired by Dijkstra (Structured Programming).  It is
+a classic recursive backtracking approach.
+
+"""
+
+N = 8                                   # Default; command line overrides
+
+class Queens:
+
+    def __init__(self, n=N):
+        self.n = n
+        self.reset()
+
+    def reset(self):
+        n = self.n
+        self.y = [None]*n               # Where is the queen in column x
+        self.row = [0]*n                # Is row[y] safe?
+        self.up = [0] * (2*n-1)         # Is upward diagonal[x-y] safe?
+        self.down = [0] * (2*n-1)       # Is downward diagonal[x+y] safe?
+        self.nfound = 0                 # Instrumentation
+
+    def solve(self, x=0):               # Recursive solver
+        for y in range(self.n):
+            if self.safe(x, y):
+                self.place(x, y)
+                if x+1 == self.n:
+                    self.display()
+                else:
+                    self.solve(x+1)
+                self.remove(x, y)
+
+    def safe(self, x, y):
+        return not self.row[y] and not self.up[x-y] and not self.down[x+y]
+
+    def place(self, x, y):
+        self.y[x] = y
+        self.row[y] = 1
+        self.up[x-y] = 1
+        self.down[x+y] = 1
+
+    def remove(self, x, y):
+        self.y[x] = None
+        self.row[y] = 0
+        self.up[x-y] = 0
+        self.down[x+y] = 0
+
+    silent = 0                          # If set, count solutions only
+
+    def display(self):
+        self.nfound = self.nfound + 1
+        if self.silent:
+            return
+        print '+-' + '--'*self.n + '+'
+        for y in range(self.n-1, -1, -1):
+            print '|',
+            for x in range(self.n):
+                if self.y[x] == y:
+                    print "Q",
+                else:
+                    print ".",
+            print '|'
+        print '+-' + '--'*self.n + '+'
+
+def main():
+    import sys
+    silent = 0
+    n = N
+    if sys.argv[1:2] == ['-n']:
+        silent = 1
+        del sys.argv[1]
+    if sys.argv[1:]:
+        n = int(sys.argv[1])
+    q = Queens(n)
+    q.silent = silent
+    q.solve()
+    print "Found", q.nfound, "solutions."
+
+if __name__ == "__main__":
+    main()


Property changes on: vendor/Python/current/Demo/scripts/queens.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/scripts/script.py
===================================================================
--- vendor/Python/current/Demo/scripts/script.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/scripts/script.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,33 @@
+#! /usr/bin/env python
+# script.py -- Make typescript of terminal session.
+# Usage:
+#       -a      Append to typescript.
+#       -p      Use Python as shell.
+# Author: Steen Lumholt.
+
+
+import os, time, sys
+import pty
+
+def read(fd):
+    data = os.read(fd, 1024)
+    file.write(data)
+    return data
+
+shell = 'sh'
+filename = 'typescript'
+mode = 'w'
+if os.environ.has_key('SHELL'):
+    shell = os.environ['SHELL']
+if '-a' in sys.argv:
+    mode = 'a'
+if '-p' in sys.argv:
+    shell = 'python'
+
+file = open(filename, mode)
+
+sys.stdout.write('Script started, file is %s\n' % filename)
+file.write('Script started on %s\n' % time.ctime(time.time()))
+pty.spawn(shell, read)
+file.write('Script done on %s\n' % time.ctime(time.time()))
+sys.stdout.write('Script done, file is %s\n' % filename)


Property changes on: vendor/Python/current/Demo/scripts/script.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/scripts/unbirthday.py
===================================================================
--- vendor/Python/current/Demo/scripts/unbirthday.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/scripts/unbirthday.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,107 @@
+#! /usr/bin/env python
+
+# Calculate your unbirthday count (see Alice in Wonderland).
+# This is defined as the number of days from your birth until today
+# that weren't your birthday.  (The day you were born is not counted).
+# Leap years make it interesting.
+
+import sys
+import time
+import calendar
+
+def main():
+    # Note that the range checks below also check for bad types,
+    # e.g. 3.14 or ().  However syntactically invalid replies
+    # will raise an exception.
+    if sys.argv[1:]:
+        year = int(sys.argv[1])
+    else:
+        year = int(raw_input('In which year were you born? '))
+    if 0<=year<100:
+        print "I'll assume that by", year,
+        year = year + 1900
+        print 'you mean', year, 'and not the early Christian era'
+    elif not (1850<=year<=2002):
+        print "It's hard to believe you were born in", year
+        return
+    #
+    if sys.argv[2:]:
+        month = int(sys.argv[2])
+    else:
+        month = int(raw_input('And in which month? (1-12) '))
+    if not (1<=month<=12):
+        print 'There is no month numbered', month
+        return
+    #
+    if sys.argv[3:]:
+        day = int(sys.argv[3])
+    else:
+        day = int(raw_input('And on what day of that month? (1-31) '))
+    if month == 2 and calendar.isleap(year):
+        maxday = 29
+    else:
+        maxday = calendar.mdays[month]
+    if not (1<=day<=maxday):
+        print 'There are no', day, 'days in that month!'
+        return
+    #
+    bdaytuple = (year, month, day)
+    bdaydate = mkdate(bdaytuple)
+    print 'You were born on', format(bdaytuple)
+    #
+    todaytuple = time.localtime()[:3]
+    todaydate = mkdate(todaytuple)
+    print 'Today is', format(todaytuple)
+    #
+    if bdaytuple > todaytuple:
+        print 'You are a time traveler.  Go back to the future!'
+        return
+    #
+    if bdaytuple == todaytuple:
+        print 'You were born today.  Have a nice life!'
+        return
+    #
+    days = todaydate - bdaydate
+    print 'You have lived', days, 'days'
+    #
+    age = 0
+    for y in range(year, todaytuple[0] + 1):
+        if bdaytuple < (y, month, day) <= todaytuple:
+            age = age + 1
+    #
+    print 'You are', age, 'years old'
+    #
+    if todaytuple[1:] == bdaytuple[1:]:
+        print 'Congratulations!  Today is your', nth(age), 'birthday'
+        print 'Yesterday was your',
+    else:
+        print 'Today is your',
+    print nth(days - age), 'unbirthday'
+
+def format((year, month, day)):
+    return '%d %s %d' % (day, calendar.month_name[month], year)
+
+def nth(n):
+    if n == 1: return '1st'
+    if n == 2: return '2nd'
+    if n == 3: return '3rd'
+    return '%dth' % n
+
+def mkdate((year, month, day)):
+    # Januari 1st, in 0 A.D. is arbitrarily defined to be day 1,
+    # even though that day never actually existed and the calendar
+    # was different then...
+    days = year*365                 # years, roughly
+    days = days + (year+3)/4        # plus leap years, roughly
+    days = days - (year+99)/100     # minus non-leap years every century
+    days = days + (year+399)/400    # plus leap years every 4 centirues
+    for i in range(1, month):
+        if i == 2 and calendar.isleap(year):
+            days = days + 29
+        else:
+            days = days + calendar.mdays[i]
+    days = days + day
+    return days
+
+if __name__ == "__main__":
+    main()


Property changes on: vendor/Python/current/Demo/scripts/unbirthday.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/scripts/update.py
===================================================================
--- vendor/Python/current/Demo/scripts/update.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/scripts/update.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,92 @@
+#! /usr/bin/env python
+
+# Update a bunch of files according to a script.
+# The input file contains lines of the form <filename>:<lineno>:<text>,
+# meaning that the given line of the given file is to be replaced
+# by the given text.  This is useful for performing global substitutions
+# on grep output:
+
+import os
+import sys
+import re
+
+pat = '^([^: \t\n]+):([1-9][0-9]*):'
+prog = re.compile(pat)
+
+class FileObj:
+    def __init__(self, filename):
+        self.filename = filename
+        self.changed = 0
+        try:
+            self.lines = open(filename, 'r').readlines()
+        except IOError, msg:
+            print '*** Can\'t open "%s":' % filename, msg
+            self.lines = None
+            return
+        print 'diffing', self.filename
+
+    def finish(self):
+        if not self.changed:
+            print 'no changes to', self.filename
+            return
+        try:
+            os.rename(self.filename, self.filename + '~')
+            fp = open(self.filename, 'w')
+        except (os.error, IOError), msg:
+            print '*** Can\'t rewrite "%s":' % self.filename, msg
+            return
+        print 'writing', self.filename
+        for line in self.lines:
+            fp.write(line)
+        fp.close()
+        self.changed = 0
+
+    def process(self, lineno, rest):
+        if self.lines is None:
+            print '(not processed): %s:%s:%s' % (
+                      self.filename, lineno, rest),
+            return
+        i = eval(lineno) - 1
+        if not 0 <= i < len(self.lines):
+            print '*** Line number out of range: %s:%s:%s' % (
+                      self.filename, lineno, rest),
+            return
+        if self.lines[i] == rest:
+            print '(no change): %s:%s:%s' % (
+                      self.filename, lineno, rest),
+            return
+        if not self.changed:
+            self.changed = 1
+        print '%sc%s' % (lineno, lineno)
+        print '<', self.lines[i],
+        print '---'
+        self.lines[i] = rest
+        print '>', self.lines[i],
+
+def main():
+    if sys.argv[1:]:
+        try:
+            fp = open(sys.argv[1], 'r')
+        except IOError, msg:
+            print 'Can\'t open "%s":' % sys.argv[1], msg
+            sys.exit(1)
+    else:
+        fp = sys.stdin
+    curfile = None
+    while 1:
+        line = fp.readline()
+        if not line:
+            if curfile: curfile.finish()
+            break
+        n = prog.match(line)
+        if n < 0:
+            print 'Funny line:', line,
+            continue
+        filename, lineno = prog.group(1, 2)
+        if not curfile or filename <> curfile.filename:
+            if curfile: curfile.finish()
+            curfile = FileObj(filename)
+        curfile.process(lineno, line[n:])
+
+if __name__ == "__main__":
+    main()


Property changes on: vendor/Python/current/Demo/scripts/update.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/scripts/wh.py
===================================================================
--- vendor/Python/current/Demo/scripts/wh.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/scripts/wh.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2 @@
+# This is here so I can use 'wh' instead of 'which' in '~/bin/generic_python'
+import which


Property changes on: vendor/Python/current/Demo/scripts/wh.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/sockets/README
===================================================================
--- vendor/Python/current/Demo/sockets/README	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/sockets/README	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,21 @@
+This directory contains some demonstrations of the socket module:
+
+broadcast.py	 	Broadcast the time to radio.py.
+echosvr.py		About the simplest TCP server possible.
+finger.py		Client for the 'finger' protocol.
+ftp.py			A very simple ftp client.
+gopher.py		A simple gopher client.
+radio.py		Receive time broadcasts from broadcast.py.
+telnet.py		Client for the 'telnet' protocol.
+throughput.py		Client and server to measure TCP throughput.
+unixclient.py		Unix socket example, client side
+unixserver.py		Unix socket example, server side
+udpecho.py		Client and server for the UDP echo protocol.
+
+The following file is only relevant on SGI machines (or other systems
+that support multicast):
+
+mcast.py		A Python translation of
+			/usr/people/4Dgifts/examples/network/mcast.c
+			(Note that IN.py is in ../../lib/sgi.)
+

Added: vendor/Python/current/Demo/sockets/broadcast.py
===================================================================
--- vendor/Python/current/Demo/sockets/broadcast.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/sockets/broadcast.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,15 @@
+# Send UDP broadcast packets
+
+MYPORT = 50000
+
+import sys, time
+from socket import *
+
+s = socket(AF_INET, SOCK_DGRAM)
+s.bind(('', 0))
+s.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
+
+while 1:
+    data = repr(time.time()) + '\n'
+    s.sendto(data, ('<broadcast>', MYPORT))
+    time.sleep(2)


Property changes on: vendor/Python/current/Demo/sockets/broadcast.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/sockets/echosvr.py
===================================================================
--- vendor/Python/current/Demo/sockets/echosvr.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/sockets/echosvr.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,31 @@
+#! /usr/bin/env python
+
+# Python implementation of an 'echo' tcp server: echo all data it receives.
+#
+# This is the simplest possible server, servicing a single request only.
+
+import sys
+from socket import *
+
+# The standard echo port isn't very useful, it requires root permissions!
+# ECHO_PORT = 7
+ECHO_PORT = 50000 + 7
+BUFSIZE = 1024
+
+def main():
+    if len(sys.argv) > 1:
+        port = int(eval(sys.argv[1]))
+    else:
+        port = ECHO_PORT
+    s = socket(AF_INET, SOCK_STREAM)
+    s.bind(('', port))
+    s.listen(1)
+    conn, (remotehost, remoteport) = s.accept()
+    print 'connected by', remotehost, remoteport
+    while 1:
+        data = conn.recv(BUFSIZE)
+        if not data:
+            break
+        conn.send(data)
+
+main()


Property changes on: vendor/Python/current/Demo/sockets/echosvr.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/sockets/finger.py
===================================================================
--- vendor/Python/current/Demo/sockets/finger.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/sockets/finger.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,58 @@
+#! /usr/bin/env python
+
+# Python interface to the Internet finger daemon.
+#
+# Usage: finger [options] [user][@host] ...
+#
+# If no host is given, the finger daemon on the local host is contacted.
+# Options are passed uninterpreted to the finger daemon!
+
+
+import sys, string
+from socket import *
+
+
+# Hardcode the number of the finger port here.
+# It's not likely to change soon...
+#
+FINGER_PORT = 79
+
+
+# Function to do one remote finger invocation.
+# Output goes directly to stdout (although this can be changed).
+#
+def finger(host, args):
+    s = socket(AF_INET, SOCK_STREAM)
+    s.connect((host, FINGER_PORT))
+    s.send(args + '\n')
+    while 1:
+        buf = s.recv(1024)
+        if not buf: break
+        sys.stdout.write(buf)
+    sys.stdout.flush()
+
+
+# Main function: argument parsing.
+#
+def main():
+    options = ''
+    i = 1
+    while i < len(sys.argv) and sys.argv[i][:1] == '-':
+        options = options + sys.argv[i] + ' '
+        i = i+1
+    args = sys.argv[i:]
+    if not args:
+        args = ['']
+    for arg in args:
+        if '@' in arg:
+            at = string.index(arg, '@')
+            host = arg[at+1:]
+            arg = arg[:at]
+        else:
+            host = ''
+        finger(host, options + arg)
+
+
+# Call the main function.
+#
+main()


Property changes on: vendor/Python/current/Demo/sockets/finger.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/sockets/ftp.py
===================================================================
--- vendor/Python/current/Demo/sockets/ftp.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/sockets/ftp.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,146 @@
+# A simple FTP client.
+#
+# The information to write this program was gathered from RFC 959,
+# but this is not a complete implementation!  Yet it shows how a simple
+# FTP client can be built, and you are welcome to extend it to suit
+# it to your needs...
+#
+# How it works (assuming you've read the RFC):
+#
+# User commands are passed uninterpreted to the server.  However, the
+# user never needs to send a PORT command.  Rather, the client opens a
+# port right away and sends the appropriate PORT command to the server.
+# When a response code 150 is received, this port is used to receive
+# the data (which is written to stdout in this version), and when the
+# data is exhausted, a new port is opened and a corresponding PORT
+# command sent.  In order to avoid errors when reusing ports quickly
+# (and because there is no s.getsockname() method in Python yet) we
+# cycle through a number of ports in the 50000 range.
+
+
+import sys, posix, string
+from socket import *
+
+
+BUFSIZE = 1024
+
+# Default port numbers used by the FTP protocol.
+#
+FTP_PORT = 21
+FTP_DATA_PORT = FTP_PORT - 1
+
+# Change the data port to something not needing root permissions.
+#
+FTP_DATA_PORT = FTP_DATA_PORT + 50000
+
+
+# Main program (called at the end of this file).
+#
+def main():
+    hostname = sys.argv[1]
+    control(hostname)
+
+
+# Control process (user interface and user protocol interpreter).
+#
+def control(hostname):
+    #
+    # Create control connection
+    #
+    s = socket(AF_INET, SOCK_STREAM)
+    s.connect((hostname, FTP_PORT))
+    f = s.makefile('r') # Reading the replies is easier from a file...
+    #
+    # Control loop
+    #
+    r = None
+    while 1:
+        code = getreply(f)
+        if code in ('221', 'EOF'): break
+        if code == '150':
+            getdata(r)
+            code = getreply(f)
+            r = None
+        if not r:
+            r = newdataport(s, f)
+        cmd = getcommand()
+        if not cmd: break
+        s.send(cmd + '\r\n')
+
+
+# Create a new data port and send a PORT command to the server for it.
+# (Cycle through a number of ports to avoid problems with reusing
+# a port within a short time.)
+#
+nextport = 0
+#
+def newdataport(s, f):
+    global nextport
+    port = nextport + FTP_DATA_PORT
+    nextport = (nextport+1) % 16
+    r = socket(AF_INET, SOCK_STREAM)
+    r.bind((gethostbyname(gethostname()), port))
+    r.listen(1)
+    sendportcmd(s, f, port)
+    return r
+
+
+# Send an appropriate port command.
+#
+def sendportcmd(s, f, port):
+    hostname = gethostname()
+    hostaddr = gethostbyname(hostname)
+    hbytes = string.splitfields(hostaddr, '.')
+    pbytes = [repr(port/256), repr(port%256)]
+    bytes = hbytes + pbytes
+    cmd = 'PORT ' + string.joinfields(bytes, ',')
+    s.send(cmd + '\r\n')
+    code = getreply(f)
+
+
+# Process an ftp reply and return the 3-digit reply code (as a string).
+# The reply should be a line of text starting with a 3-digit number.
+# If the 4th char is '-', it is a multi-line reply and is
+# terminate by a line starting with the same 3-digit number.
+# Any text while receiving the reply is echoed to the file.
+#
+def getreply(f):
+    line = f.readline()
+    if not line: return 'EOF'
+    print line,
+    code = line[:3]
+    if line[3:4] == '-':
+        while 1:
+            line = f.readline()
+            if not line: break # Really an error
+            print line,
+            if line[:3] == code and line[3:4] != '-': break
+    return code
+
+
+# Get the data from the data connection.
+#
+def getdata(r):
+    print '(accepting data connection)'
+    conn, host = r.accept()
+    print '(data connection accepted)'
+    while 1:
+        data = conn.recv(BUFSIZE)
+        if not data: break
+        sys.stdout.write(data)
+    print '(end of data connection)'
+
+# Get a command from the user.
+#
+def getcommand():
+    try:
+        while 1:
+            line = raw_input('ftp.py> ')
+            if line: return line
+    except EOFError:
+        return ''
+
+
+# Call the main program.
+#
+main()


Property changes on: vendor/Python/current/Demo/sockets/ftp.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/sockets/gopher.py
===================================================================
--- vendor/Python/current/Demo/sockets/gopher.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/sockets/gopher.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,347 @@
+#! /usr/bin/env python
+
+# A simple gopher client.
+#
+# Usage: gopher [ [selector] host [port] ]
+
+import string
+import sys
+import os
+import socket
+
+# Default selector, host and port
+DEF_SELECTOR = ''
+DEF_HOST     = 'gopher.micro.umn.edu'
+DEF_PORT     = 70
+
+# Recognized file types
+T_TEXTFILE  = '0'
+T_MENU      = '1'
+T_CSO       = '2'
+T_ERROR     = '3'
+T_BINHEX    = '4'
+T_DOS       = '5'
+T_UUENCODE  = '6'
+T_SEARCH    = '7'
+T_TELNET    = '8'
+T_BINARY    = '9'
+T_REDUNDANT = '+'
+T_SOUND     = 's'
+
+# Dictionary mapping types to strings
+typename = {'0': '<TEXT>', '1': '<DIR>', '2': '<CSO>', '3': '<ERROR>', \
+        '4': '<BINHEX>', '5': '<DOS>', '6': '<UUENCODE>', '7': '<SEARCH>', \
+        '8': '<TELNET>', '9': '<BINARY>', '+': '<REDUNDANT>', 's': '<SOUND>'}
+
+# Oft-used characters and strings
+CRLF = '\r\n'
+TAB = '\t'
+
+# Open a TCP connection to a given host and port
+def open_socket(host, port):
+    if not port:
+        port = DEF_PORT
+    elif type(port) == type(''):
+        port = string.atoi(port)
+    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+    s.connect((host, port))
+    return s
+
+# Send a selector to a given host and port, return a file with the reply
+def send_request(selector, host, port):
+    s = open_socket(host, port)
+    s.send(selector + CRLF)
+    s.shutdown(1)
+    return s.makefile('r')
+
+# Get a menu in the form of a list of entries
+def get_menu(selector, host, port):
+    f = send_request(selector, host, port)
+    list = []
+    while 1:
+        line = f.readline()
+        if not line:
+            print '(Unexpected EOF from server)'
+            break
+        if line[-2:] == CRLF:
+            line = line[:-2]
+        elif line[-1:] in CRLF:
+            line = line[:-1]
+        if line == '.':
+            break
+        if not line:
+            print '(Empty line from server)'
+            continue
+        typechar = line[0]
+        parts = string.splitfields(line[1:], TAB)
+        if len(parts) < 4:
+            print '(Bad line from server: %r)' % (line,)
+            continue
+        if len(parts) > 4:
+            print '(Extra info from server: %r)' % (parts[4:],)
+        parts.insert(0, typechar)
+        list.append(parts)
+    f.close()
+    return list
+
+# Get a text file as a list of lines, with trailing CRLF stripped
+def get_textfile(selector, host, port):
+    list = []
+    get_alt_textfile(selector, host, port, list.append)
+    return list
+
+# Get a text file and pass each line to a function, with trailing CRLF stripped
+def get_alt_textfile(selector, host, port, func):
+    f = send_request(selector, host, port)
+    while 1:
+        line = f.readline()
+        if not line:
+            print '(Unexpected EOF from server)'
+            break
+        if line[-2:] == CRLF:
+            line = line[:-2]
+        elif line[-1:] in CRLF:
+            line = line[:-1]
+        if line == '.':
+            break
+        if line[:2] == '..':
+            line = line[1:]
+        func(line)
+    f.close()
+
+# Get a binary file as one solid data block
+def get_binary(selector, host, port):
+    f = send_request(selector, host, port)
+    data = f.read()
+    f.close()
+    return data
+
+# Get a binary file and pass each block to a function
+def get_alt_binary(selector, host, port, func, blocksize):
+    f = send_request(selector, host, port)
+    while 1:
+        data = f.read(blocksize)
+        if not data:
+            break
+        func(data)
+
+# A *very* simple interactive browser
+
+# Browser main command, has default arguments
+def browser(*args):
+    selector = DEF_SELECTOR
+    host = DEF_HOST
+    port = DEF_PORT
+    n = len(args)
+    if n > 0 and args[0]:
+        selector = args[0]
+    if n > 1 and args[1]:
+        host = args[1]
+    if n > 2 and args[2]:
+        port = args[2]
+    if n > 3:
+        raise RuntimeError, 'too many args'
+    try:
+        browse_menu(selector, host, port)
+    except socket.error, msg:
+        print 'Socket error:', msg
+        sys.exit(1)
+    except KeyboardInterrupt:
+        print '\n[Goodbye]'
+
+# Browse a menu
+def browse_menu(selector, host, port):
+    list = get_menu(selector, host, port)
+    while 1:
+        print '----- MENU -----'
+        print 'Selector:', repr(selector)
+        print 'Host:', host, ' Port:', port
+        print
+        for i in range(len(list)):
+            item = list[i]
+            typechar, description = item[0], item[1]
+            print string.rjust(repr(i+1), 3) + ':', description,
+            if typename.has_key(typechar):
+                print typename[typechar]
+            else:
+                print '<TYPE=' + repr(typechar) + '>'
+        print
+        while 1:
+            try:
+                str = raw_input('Choice [CR == up a level]: ')
+            except EOFError:
+                print
+                return
+            if not str:
+                return
+            try:
+                choice = string.atoi(str)
+            except string.atoi_error:
+                print 'Choice must be a number; try again:'
+                continue
+            if not 0 < choice <= len(list):
+                print 'Choice out of range; try again:'
+                continue
+            break
+        item = list[choice-1]
+        typechar = item[0]
+        [i_selector, i_host, i_port] = item[2:5]
+        if typebrowser.has_key(typechar):
+            browserfunc = typebrowser[typechar]
+            try:
+                browserfunc(i_selector, i_host, i_port)
+            except (IOError, socket.error):
+                print '***', sys.exc_type, ':', sys.exc_value
+        else:
+            print 'Unsupported object type'
+
+# Browse a text file
+def browse_textfile(selector, host, port):
+    x = None
+    try:
+        p = os.popen('${PAGER-more}', 'w')
+        x = SaveLines(p)
+        get_alt_textfile(selector, host, port, x.writeln)
+    except IOError, msg:
+        print 'IOError:', msg
+    if x:
+        x.close()
+    f = open_savefile()
+    if not f:
+        return
+    x = SaveLines(f)
+    try:
+        get_alt_textfile(selector, host, port, x.writeln)
+        print 'Done.'
+    except IOError, msg:
+        print 'IOError:', msg
+    x.close()
+
+# Browse a search index
+def browse_search(selector, host, port):
+    while 1:
+        print '----- SEARCH -----'
+        print 'Selector:', repr(selector)
+        print 'Host:', host, ' Port:', port
+        print
+        try:
+            query = raw_input('Query [CR == up a level]: ')
+        except EOFError:
+            print
+            break
+        query = string.strip(query)
+        if not query:
+            break
+        if '\t' in query:
+            print 'Sorry, queries cannot contain tabs'
+            continue
+        browse_menu(selector + TAB + query, host, port)
+
+# "Browse" telnet-based information, i.e. open a telnet session
+def browse_telnet(selector, host, port):
+    if selector:
+        print 'Log in as', repr(selector)
+    if type(port) <> type(''):
+        port = repr(port)
+    sts = os.system('set -x; exec telnet ' + host + ' ' + port)
+    if sts:
+        print 'Exit status:', sts
+
+# "Browse" a binary file, i.e. save it to a file
+def browse_binary(selector, host, port):
+    f = open_savefile()
+    if not f:
+        return
+    x = SaveWithProgress(f)
+    get_alt_binary(selector, host, port, x.write, 8*1024)
+    x.close()
+
+# "Browse" a sound file, i.e. play it or save it
+def browse_sound(selector, host, port):
+    browse_binary(selector, host, port)
+
+# Dictionary mapping types to browser functions
+typebrowser = {'0': browse_textfile, '1': browse_menu, \
+        '4': browse_binary, '5': browse_binary, '6': browse_textfile, \
+        '7': browse_search, \
+        '8': browse_telnet, '9': browse_binary, 's': browse_sound}
+
+# Class used to save lines, appending a newline to each line
+class SaveLines:
+    def __init__(self, f):
+        self.f = f
+    def writeln(self, line):
+        self.f.write(line + '\n')
+    def close(self):
+        sts = self.f.close()
+        if sts:
+            print 'Exit status:', sts
+
+# Class used to save data while showing progress
+class SaveWithProgress:
+    def __init__(self, f):
+        self.f = f
+    def write(self, data):
+        sys.stdout.write('#')
+        sys.stdout.flush()
+        self.f.write(data)
+    def close(self):
+        print
+        sts = self.f.close()
+        if sts:
+            print 'Exit status:', sts
+
+# Ask for and open a save file, or return None if not to save
+def open_savefile():
+    try:
+        savefile = raw_input( \
+    'Save as file [CR == don\'t save; |pipeline or ~user/... OK]: ')
+    except EOFError:
+        print
+        return None
+    savefile = string.strip(savefile)
+    if not savefile:
+        return None
+    if savefile[0] == '|':
+        cmd = string.strip(savefile[1:])
+        try:
+            p = os.popen(cmd, 'w')
+        except IOError, msg:
+            print repr(cmd), ':', msg
+            return None
+        print 'Piping through', repr(cmd), '...'
+        return p
+    if savefile[0] == '~':
+        savefile = os.path.expanduser(savefile)
+    try:
+        f = open(savefile, 'w')
+    except IOError, msg:
+        print repr(savefile), ':', msg
+        return None
+    print 'Saving to', repr(savefile), '...'
+    return f
+
+# Test program
+def test():
+    if sys.argv[4:]:
+        print 'usage: gopher [ [selector] host [port] ]'
+        sys.exit(2)
+    elif sys.argv[3:]:
+        browser(sys.argv[1], sys.argv[2], sys.argv[3])
+    elif sys.argv[2:]:
+        try:
+            port = string.atoi(sys.argv[2])
+            selector = ''
+            host = sys.argv[1]
+        except string.atoi_error:
+            selector = sys.argv[1]
+            host = sys.argv[2]
+            port = ''
+        browser(selector, host, port)
+    elif sys.argv[1:]:
+        browser('', sys.argv[1])
+    else:
+        browser()
+
+# Call the test program as a main program
+test()


Property changes on: vendor/Python/current/Demo/sockets/gopher.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/sockets/mcast.py
===================================================================
--- vendor/Python/current/Demo/sockets/mcast.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/sockets/mcast.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,93 @@
+# Send/receive UDP multicast packets.
+# Requires that your OS kernel supports IP multicast.
+# This is built-in on SGI, still optional for most other vendors.
+#
+# Usage:
+#   mcast -s (sender)
+#   mcast -b (sender, using broadcast instead multicast)
+#   mcast    (receivers)
+
+MYPORT = 8123
+MYGROUP = '225.0.0.250'
+
+import sys
+import time
+import struct
+from socket import *
+
+
+# Main program
+def main():
+    flags = sys.argv[1:]
+    #
+    if flags:
+        sender(flags[0])
+    else:
+        receiver()
+
+
+# Sender subroutine (only one per local area network)
+def sender(flag):
+    s = socket(AF_INET, SOCK_DGRAM)
+    if flag == '-b':
+        s.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
+        mygroup = '<broadcast>'
+    else:
+        mygroup = MYGROUP
+        ttl = struct.pack('b', 1)               # Time-to-live
+        s.setsockopt(IPPROTO_IP, IP_MULTICAST_TTL, ttl)
+    while 1:
+        data = repr(time.time())
+##              data = data + (1400 - len(data)) * '\0'
+        s.sendto(data, (mygroup, MYPORT))
+        time.sleep(1)
+
+
+# Receiver subroutine (as many as you like)
+def receiver():
+    # Open and initialize the socket
+    s = openmcastsock(MYGROUP, MYPORT)
+    #
+    # Loop, printing any data we receive
+    while 1:
+        data, sender = s.recvfrom(1500)
+        while data[-1:] == '\0': data = data[:-1] # Strip trailing \0's
+        print sender, ':', repr(data)
+
+
+# Open a UDP socket, bind it to a port and select a multicast group
+def openmcastsock(group, port):
+    # Import modules used only here
+    import string
+    import struct
+    #
+    # Create a socket
+    s = socket(AF_INET, SOCK_DGRAM)
+    #
+    # Allow multiple copies of this program on one machine
+    # (not strictly needed)
+    s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
+    #
+    # Bind it to the port
+    s.bind(('', port))
+    #
+    # Look up multicast group address in name server
+    # (doesn't hurt if it is already in ddd.ddd.ddd.ddd format)
+    group = gethostbyname(group)
+    #
+    # Construct binary group address
+    bytes = map(int, string.split(group, "."))
+    grpaddr = 0
+    for byte in bytes: grpaddr = (grpaddr << 8) | byte
+    #
+    # Construct struct mreq from grpaddr and ifaddr
+    ifaddr = INADDR_ANY
+    mreq = struct.pack('ll', htonl(grpaddr), htonl(ifaddr))
+    #
+    # Add group membership
+    s.setsockopt(IPPROTO_IP, IP_ADD_MEMBERSHIP, mreq)
+    #
+    return s
+
+
+main()


Property changes on: vendor/Python/current/Demo/sockets/mcast.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/sockets/radio.py
===================================================================
--- vendor/Python/current/Demo/sockets/radio.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/sockets/radio.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,14 @@
+# Receive UDP packets transmitted by a broadcasting service
+
+MYPORT = 50000
+
+import sys
+from socket import *
+
+s = socket(AF_INET, SOCK_DGRAM)
+s.bind(('', MYPORT))
+
+while 1:
+    data, wherefrom = s.recvfrom(1500, 0)
+    sys.stderr.write(repr(wherefrom) + '\n')
+    sys.stdout.write(data)


Property changes on: vendor/Python/current/Demo/sockets/radio.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/sockets/rpython.py
===================================================================
--- vendor/Python/current/Demo/sockets/rpython.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/sockets/rpython.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,35 @@
+#! /usr/bin/env python
+
+# Remote python client.
+# Execute Python commands remotely and send output back.
+
+import sys
+import string
+from socket import *
+
+PORT = 4127
+BUFSIZE = 1024
+
+def main():
+    if len(sys.argv) < 3:
+        print "usage: rpython host command"
+        sys.exit(2)
+    host = sys.argv[1]
+    port = PORT
+    i = string.find(host, ':')
+    if i >= 0:
+        port = string.atoi(port[i+1:])
+        host = host[:i]
+    command = string.join(sys.argv[2:])
+    s = socket(AF_INET, SOCK_STREAM)
+    s.connect((host, port))
+    s.send(command)
+    s.shutdown(1)
+    reply = ''
+    while 1:
+        data = s.recv(BUFSIZE)
+        if not data: break
+        reply = reply + data
+    print reply,
+
+main()


Property changes on: vendor/Python/current/Demo/sockets/rpython.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/sockets/rpythond.py
===================================================================
--- vendor/Python/current/Demo/sockets/rpythond.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/sockets/rpythond.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,52 @@
+#! /usr/bin/env python
+
+# Remote python server.
+# Execute Python commands remotely and send output back.
+# WARNING: This version has a gaping security hole -- it accepts requests
+# from any host on the Internet!
+
+import sys
+from socket import *
+import StringIO
+import traceback
+
+PORT = 4127
+BUFSIZE = 1024
+
+def main():
+    if len(sys.argv) > 1:
+        port = int(eval(sys.argv[1]))
+    else:
+        port = PORT
+    s = socket(AF_INET, SOCK_STREAM)
+    s.bind(('', port))
+    s.listen(1)
+    while 1:
+        conn, (remotehost, remoteport) = s.accept()
+        print 'connected by', remotehost, remoteport
+        request = ''
+        while 1:
+            data = conn.recv(BUFSIZE)
+            if not data:
+                break
+            request = request + data
+        reply = execute(request)
+        conn.send(reply)
+        conn.close()
+
+def execute(request):
+    stdout = sys.stdout
+    stderr = sys.stderr
+    sys.stdout = sys.stderr = fakefile = StringIO.StringIO()
+    try:
+        try:
+            exec request in {}, {}
+        except:
+            print
+            traceback.print_exc(100)
+    finally:
+        sys.stderr = stderr
+        sys.stdout = stdout
+    return fakefile.getvalue()
+
+main()


Property changes on: vendor/Python/current/Demo/sockets/rpythond.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/sockets/telnet.py
===================================================================
--- vendor/Python/current/Demo/sockets/telnet.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/sockets/telnet.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,109 @@
+#! /usr/bin/env python
+
+# Minimal interface to the Internet telnet protocol.
+#
+# It refuses all telnet options and does not recognize any of the other
+# telnet commands, but can still be used to connect in line-by-line mode.
+# It's also useful to play with a number of other services,
+# like time, finger, smtp and even ftp.
+#
+# Usage: telnet host [port]
+#
+# The port may be a service name or a decimal port number;
+# it defaults to 'telnet'.
+
+
+import sys, posix, time
+from socket import *
+
+BUFSIZE = 1024
+
+# Telnet protocol characters
+
+IAC  = chr(255) # Interpret as command
+DONT = chr(254)
+DO   = chr(253)
+WONT = chr(252)
+WILL = chr(251)
+
+def main():
+    host = sys.argv[1]
+    try:
+        hostaddr = gethostbyname(host)
+    except error:
+        sys.stderr.write(sys.argv[1] + ': bad host name\n')
+        sys.exit(2)
+    #
+    if len(sys.argv) > 2:
+        servname = sys.argv[2]
+    else:
+        servname = 'telnet'
+    #
+    if '0' <= servname[:1] <= '9':
+        port = eval(servname)
+    else:
+        try:
+            port = getservbyname(servname, 'tcp')
+        except error:
+            sys.stderr.write(servname + ': bad tcp service name\n')
+            sys.exit(2)
+    #
+    s = socket(AF_INET, SOCK_STREAM)
+    #
+    try:
+        s.connect((host, port))
+    except error, msg:
+        sys.stderr.write('connect failed: ' + repr(msg) + '\n')
+        sys.exit(1)
+    #
+    pid = posix.fork()
+    #
+    if pid == 0:
+        # child -- read stdin, write socket
+        while 1:
+            line = sys.stdin.readline()
+            s.send(line)
+    else:
+        # parent -- read socket, write stdout
+        iac = 0         # Interpret next char as command
+        opt = ''        # Interpret next char as option
+        while 1:
+            data = s.recv(BUFSIZE)
+            if not data:
+                # EOF; kill child and exit
+                sys.stderr.write( '(Closed by remote host)\n')
+                posix.kill(pid, 9)
+                sys.exit(1)
+            cleandata = ''
+            for c in data:
+                if opt:
+                    print ord(c)
+                    s.send(opt + c)
+                    opt = ''
+                elif iac:
+                    iac = 0
+                    if c == IAC:
+                        cleandata = cleandata + c
+                    elif c in (DO, DONT):
+                        if c == DO: print '(DO)',
+                        else: print '(DONT)',
+                        opt = IAC + WONT
+                    elif c in (WILL, WONT):
+                        if c == WILL: print '(WILL)',
+                        else: print '(WONT)',
+                        opt = IAC + DONT
+                    else:
+                        print '(command)', ord(c)
+                elif c == IAC:
+                    iac = 1
+                    print '(IAC)',
+                else:
+                    cleandata = cleandata + c
+            sys.stdout.write(cleandata)
+            sys.stdout.flush()
+
+
+try:
+    main()
+except KeyboardInterrupt:
+    pass


Property changes on: vendor/Python/current/Demo/sockets/telnet.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/sockets/throughput.py
===================================================================
--- vendor/Python/current/Demo/sockets/throughput.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/sockets/throughput.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,93 @@
+#! /usr/bin/env python
+
+# Test network throughput.
+#
+# Usage:
+# 1) on host_A: throughput -s [port]                    # start a server
+# 2) on host_B: throughput -c  count host_A [port]      # start a client
+#
+# The server will service multiple clients until it is killed.
+#
+# The client performs one transfer of count*BUFSIZE bytes and
+# measures the time it takes (roundtrip!).
+
+
+import sys, time
+from socket import *
+
+MY_PORT = 50000 + 42
+
+BUFSIZE = 1024
+
+
+def main():
+    if len(sys.argv) < 2:
+        usage()
+    if sys.argv[1] == '-s':
+        server()
+    elif sys.argv[1] == '-c':
+        client()
+    else:
+        usage()
+
+
+def usage():
+    sys.stdout = sys.stderr
+    print 'Usage:    (on host_A) throughput -s [port]'
+    print 'and then: (on host_B) throughput -c count host_A [port]'
+    sys.exit(2)
+
+
+def server():
+    if len(sys.argv) > 2:
+        port = eval(sys.argv[2])
+    else:
+        port = MY_PORT
+    s = socket(AF_INET, SOCK_STREAM)
+    s.bind(('', port))
+    s.listen(1)
+    print 'Server ready...'
+    while 1:
+        conn, (host, remoteport) = s.accept()
+        while 1:
+            data = conn.recv(BUFSIZE)
+            if not data:
+                break
+            del data
+        conn.send('OK\n')
+        conn.close()
+        print 'Done with', host, 'port', remoteport
+
+
+def client():
+    if len(sys.argv) < 4:
+        usage()
+    count = int(eval(sys.argv[2]))
+    host = sys.argv[3]
+    if len(sys.argv) > 4:
+        port = eval(sys.argv[4])
+    else:
+        port = MY_PORT
+    testdata = 'x' * (BUFSIZE-1) + '\n'
+    t1 = time.time()
+    s = socket(AF_INET, SOCK_STREAM)
+    t2 = time.time()
+    s.connect((host, port))
+    t3 = time.time()
+    i = 0
+    while i < count:
+        i = i+1
+        s.send(testdata)
+    s.shutdown(1) # Send EOF
+    t4 = time.time()
+    data = s.recv(BUFSIZE)
+    t5 = time.time()
+    print data
+    print 'Raw timers:', t1, t2, t3, t4, t5
+    print 'Intervals:', t2-t1, t3-t2, t4-t3, t5-t4
+    print 'Total:', t5-t1
+    print 'Throughput:', round((BUFSIZE*count*0.001) / (t5-t1), 3),
+    print 'K/sec.'
+
+
+main()


Property changes on: vendor/Python/current/Demo/sockets/throughput.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/sockets/udpecho.py
===================================================================
--- vendor/Python/current/Demo/sockets/udpecho.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/sockets/udpecho.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,63 @@
+#! /usr/bin/env python
+
+# Client and server for udp (datagram) echo.
+#
+# Usage: udpecho -s [port]            (to start a server)
+# or:    udpecho -c host [port] <file (client)
+
+import sys
+from socket import *
+
+ECHO_PORT = 50000 + 7
+BUFSIZE = 1024
+
+def main():
+    if len(sys.argv) < 2:
+        usage()
+    if sys.argv[1] == '-s':
+        server()
+    elif sys.argv[1] == '-c':
+        client()
+    else:
+        usage()
+
+def usage():
+    sys.stdout = sys.stderr
+    print 'Usage: udpecho -s [port]            (server)'
+    print 'or:    udpecho -c host [port] <file (client)'
+    sys.exit(2)
+
+def server():
+    if len(sys.argv) > 2:
+        port = eval(sys.argv[2])
+    else:
+        port = ECHO_PORT
+    s = socket(AF_INET, SOCK_DGRAM)
+    s.bind(('', port))
+    print 'udp echo server ready'
+    while 1:
+        data, addr = s.recvfrom(BUFSIZE)
+        print 'server received %r from %r' % (data, addr)
+        s.sendto(data, addr)
+
+def client():
+    if len(sys.argv) < 3:
+        usage()
+    host = sys.argv[2]
+    if len(sys.argv) > 3:
+        port = eval(sys.argv[3])
+    else:
+        port = ECHO_PORT
+    addr = host, port
+    s = socket(AF_INET, SOCK_DGRAM)
+    s.bind(('', 0))
+    print 'udp echo client ready, reading stdin'
+    while 1:
+        line = sys.stdin.readline()
+        if not line:
+            break
+        s.sendto(line, addr)
+        data, fromaddr = s.recvfrom(BUFSIZE)
+        print 'client received %r from %r' % (data, fromaddr)
+
+main()


Property changes on: vendor/Python/current/Demo/sockets/udpecho.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/sockets/unicast.py
===================================================================
--- vendor/Python/current/Demo/sockets/unicast.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/sockets/unicast.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,14 @@
+# Send UDP broadcast packets
+
+MYPORT = 50000
+
+import sys, time
+from socket import *
+
+s = socket(AF_INET, SOCK_DGRAM)
+s.bind(('', 0))
+
+while 1:
+    data = repr(time.time()) + '\n'
+    s.sendto(data, ('', MYPORT))
+    time.sleep(2)

Added: vendor/Python/current/Demo/sockets/unixclient.py
===================================================================
--- vendor/Python/current/Demo/sockets/unixclient.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/sockets/unixclient.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,12 @@
+# Echo client demo using Unix sockets
+# Piet van Oostrum
+
+from socket import *
+
+FILE = 'unix-socket'
+s = socket(AF_UNIX, SOCK_STREAM)
+s.connect(FILE)
+s.send('Hello, world')
+data = s.recv(1024)
+s.close()
+print 'Received', repr(data)

Added: vendor/Python/current/Demo/sockets/unixserver.py
===================================================================
--- vendor/Python/current/Demo/sockets/unixserver.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/sockets/unixserver.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,24 @@
+# Echo server demo using Unix sockets (handles one connection only)
+# Piet van Oostrum
+
+import os
+from socket import *
+
+FILE = 'unix-socket'
+s = socket(AF_UNIX, SOCK_STREAM)
+s.bind(FILE)
+
+print 'Sock name is: ['+s.getsockname()+']'
+
+# Wait for a connection
+s.listen(1)
+conn, addr = s.accept()
+
+while True:
+    data = conn.recv(1024)
+    if not data:
+        break
+    conn.send(data)
+
+conn.close()
+os.unlink(FILE)

Added: vendor/Python/current/Demo/threads/Coroutine.py
===================================================================
--- vendor/Python/current/Demo/threads/Coroutine.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/threads/Coroutine.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,159 @@
+# Coroutine implementation using Python threads.
+#
+# Combines ideas from Guido's Generator module, and from the coroutine
+# features of Icon and Simula 67.
+#
+# To run a collection of functions as coroutines, you need to create
+# a Coroutine object to control them:
+#    co = Coroutine()
+# and then 'create' a subsidiary object for each function in the
+# collection:
+#    cof1 = co.create(f1 [, arg1, arg2, ...]) # [] means optional,
+#    cof2 = co.create(f2 [, arg1, arg2, ...]) #... not list
+#    cof3 = co.create(f3 [, arg1, arg2, ...])
+# etc.  The functions need not be distinct; 'create'ing the same
+# function multiple times gives you independent instances of the
+# function.
+#
+# To start the coroutines running, use co.tran on one of the create'd
+# functions; e.g., co.tran(cof2).  The routine that first executes
+# co.tran is called the "main coroutine".  It's special in several
+# respects:  it existed before you created the Coroutine object; if any of
+# the create'd coroutines exits (does a return, or suffers an unhandled
+# exception), EarlyExit error is raised in the main coroutine; and the
+# co.detach() method transfers control directly to the main coroutine
+# (you can't use co.tran() for this because the main coroutine doesn't
+# have a name ...).
+#
+# Coroutine objects support these methods:
+#
+# handle = .create(func [, arg1, arg2, ...])
+#    Creates a coroutine for an invocation of func(arg1, arg2, ...),
+#    and returns a handle ("name") for the coroutine so created.  The
+#    handle can be used as the target in a subsequent .tran().
+#
+# .tran(target, data=None)
+#    Transfer control to the create'd coroutine "target", optionally
+#    passing it an arbitrary piece of data. To the coroutine A that does
+#    the .tran, .tran acts like an ordinary function call:  another
+#    coroutine B can .tran back to it later, and if it does A's .tran
+#    returns the 'data' argument passed to B's tran.  E.g.,
+#
+#    in coroutine coA   in coroutine coC    in coroutine coB
+#      x = co.tran(coC)   co.tran(coB)        co.tran(coA,12)
+#      print x # 12
+#
+#    The data-passing feature is taken from Icon, and greatly cuts
+#    the need to use global variables for inter-coroutine communication.
+#
+# .back( data=None )
+#    The same as .tran(invoker, data=None), where 'invoker' is the
+#    coroutine that most recently .tran'ed control to the coroutine
+#    doing the .back.  This is akin to Icon's "&source".
+#
+# .detach( data=None )
+#    The same as .tran(main, data=None), where 'main' is the
+#    (unnameable!) coroutine that started it all.  'main' has all the
+#    rights of any other coroutine:  upon receiving control, it can
+#    .tran to an arbitrary coroutine of its choosing, go .back to
+#    the .detach'er, or .kill the whole thing.
+#
+# .kill()
+#    Destroy all the coroutines, and return control to the main
+#    coroutine.  None of the create'ed coroutines can be resumed after a
+#    .kill().  An EarlyExit exception does a .kill() automatically.  It's
+#    a good idea to .kill() coroutines you're done with, since the
+#    current implementation consumes a thread for each coroutine that
+#    may be resumed.
+
+import thread
+import sync
+
+class _CoEvent:
+    def __init__(self, func):
+        self.f = func
+        self.e = sync.event()
+
+    def __repr__(self):
+        if self.f is None:
+            return 'main coroutine'
+        else:
+            return 'coroutine for func ' + self.f.func_name
+
+    def __hash__(self):
+        return id(self)
+
+    def __cmp__(x,y):
+        return cmp(id(x), id(y))
+
+    def resume(self):
+        self.e.post()
+
+    def wait(self):
+        self.e.wait()
+        self.e.clear()
+
+Killed = 'Coroutine.Killed'
+EarlyExit = 'Coroutine.EarlyExit'
+
+class Coroutine:
+    def __init__(self):
+        self.active = self.main = _CoEvent(None)
+        self.invokedby = {self.main: None}
+        self.killed = 0
+        self.value  = None
+        self.terminated_by = None
+
+    def create(self, func, *args):
+        me = _CoEvent(func)
+        self.invokedby[me] = None
+        thread.start_new_thread(self._start, (me,) + args)
+        return me
+
+    def _start(self, me, *args):
+        me.wait()
+        if not self.killed:
+            try:
+                try:
+                    apply(me.f, args)
+                except Killed:
+                    pass
+            finally:
+                if not self.killed:
+                    self.terminated_by = me
+                    self.kill()
+
+    def kill(self):
+        if self.killed:
+            raise TypeError, 'kill() called on dead coroutines'
+        self.killed = 1
+        for coroutine in self.invokedby.keys():
+            coroutine.resume()
+
+    def back(self, data=None):
+        return self.tran( self.invokedby[self.active], data )
+
+    def detach(self, data=None):
+        return self.tran( self.main, data )
+
+    def tran(self, target, data=None):
+        if not self.invokedby.has_key(target):
+            raise TypeError, '.tran target %r is not an active coroutine' % (target,)
+        if self.killed:
+            raise TypeError, '.tran target %r is killed' % (target,)
+        self.value = data
+        me = self.active
+        self.invokedby[target] = me
+        self.active = target
+        target.resume()
+
+        me.wait()
+        if self.killed:
+            if self.main is not me:
+                raise Killed
+            if self.terminated_by is not None:
+                raise EarlyExit, '%r terminated early' % (self.terminated_by,)
+
+        return self.value
+
+# end of module

Added: vendor/Python/current/Demo/threads/Generator.py
===================================================================
--- vendor/Python/current/Demo/threads/Generator.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/threads/Generator.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,84 @@
+# Generator implementation using threads
+
+import thread
+
+Killed = 'Generator.Killed'
+
+class Generator:
+    # Constructor
+    def __init__(self, func, args):
+        self.getlock = thread.allocate_lock()
+        self.putlock = thread.allocate_lock()
+        self.getlock.acquire()
+        self.putlock.acquire()
+        self.func = func
+        self.args = args
+        self.done = 0
+        self.killed = 0
+        thread.start_new_thread(self._start, ())
+    # Internal routine
+    def _start(self):
+        try:
+            self.putlock.acquire()
+            if not self.killed:
+                try:
+                    apply(self.func, (self,) + self.args)
+                except Killed:
+                    pass
+        finally:
+            if not self.killed:
+                self.done = 1
+                self.getlock.release()
+    # Called by producer for each value; raise Killed if no more needed
+    def put(self, value):
+        if self.killed:
+            raise TypeError, 'put() called on killed generator'
+        self.value = value
+        self.getlock.release()  # Resume consumer thread
+        self.putlock.acquire()  # Wait for next get() call
+        if self.killed:
+            raise Killed
+    # Called by producer to get next value; raise EOFError if no more
+    def get(self):
+        if self.killed:
+            raise TypeError, 'get() called on killed generator'
+        self.putlock.release()  # Resume producer thread
+        self.getlock.acquire()  # Wait for value to appear
+        if self.done:
+            raise EOFError  # Say there are no more values
+        return self.value
+    # Called by consumer if no more values wanted
+    def kill(self):
+        if self.killed:
+            raise TypeError, 'kill() called on killed generator'
+        self.killed = 1
+        self.putlock.release()
+    # Clone constructor
+    def clone(self):
+        return Generator(self.func, self.args)
+
+def pi(g):
+    k, a, b, a1, b1 = 2L, 4L, 1L, 12L, 4L
+    while 1:
+        # Next approximation
+        p, q, k = k*k, 2L*k+1L, k+1L
+        a, b, a1, b1 = a1, b1, p*a+q*a1, p*b+q*b1
+        # Print common digits
+        d, d1 = a/b, a1/b1
+        while d == d1:
+            g.put(int(d))
+            a, a1 = 10L*(a%b), 10L*(a1%b1)
+            d, d1 = a/b, a1/b1
+
+def test():
+    g = Generator(pi, ())
+    g.kill()
+    g = Generator(pi, ())
+    for i in range(10): print g.get(),
+    print
+    h = g.clone()
+    g.kill()
+    while 1:
+        print h.get(),
+
+test()

Added: vendor/Python/current/Demo/threads/README
===================================================================
--- vendor/Python/current/Demo/threads/README	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/threads/README	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,13 @@
+This directory contains some demonstrations of the thread module.
+
+These are mostly "proof of concept" type applications:
+
+Generator.py	Generator class implemented with threads.
+find.py		Parallelized "find(1)" (looks for directories).
+sync.py		Condition variables primitives by Tim Peters.
+telnet.py	Version of ../sockets/telnet.py using threads.
+wpi.py		Version of ../scripts/pi.py using threads (needs stdwin).
+
+Coroutine.py	Coroutines using threads, by Tim Peters (22 May 94)
+fcmp.py		Example of above, by Tim
+squasher.py	Another example of above, also by Tim

Added: vendor/Python/current/Demo/threads/fcmp.py
===================================================================
--- vendor/Python/current/Demo/threads/fcmp.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/threads/fcmp.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,64 @@
+# Coroutine example:  controlling multiple instances of a single function
+
+from Coroutine import *
+
+# fringe visits a nested list in inorder, and detaches for each non-list
+# element; raises EarlyExit after the list is exhausted
+def fringe(co, list):
+    for x in list:
+        if type(x) is type([]):
+            fringe(co, x)
+        else:
+            co.back(x)
+
+def printinorder(list):
+    co = Coroutine()
+    f = co.create(fringe, co, list)
+    try:
+        while 1:
+            print co.tran(f),
+    except EarlyExit:
+        pass
+    print
+
+printinorder([1,2,3])  # 1 2 3
+printinorder([[[[1,[2]]],3]]) # ditto
+x = [0, 1, [2, [3]], [4,5], [[[6]]] ]
+printinorder(x) # 0 1 2 3 4 5 6
+
+# fcmp lexicographically compares the fringes of two nested lists
+def fcmp(l1, l2):
+    co1 = Coroutine(); f1 = co1.create(fringe, co1, l1)
+    co2 = Coroutine(); f2 = co2.create(fringe, co2, l2)
+    while 1:
+        try:
+            v1 = co1.tran(f1)
+        except EarlyExit:
+            try:
+                v2 = co2.tran(f2)
+            except EarlyExit:
+                return 0
+            co2.kill()
+            return -1
+        try:
+            v2 = co2.tran(f2)
+        except EarlyExit:
+            co1.kill()
+            return 1
+        if v1 != v2:
+            co1.kill(); co2.kill()
+            return cmp(v1,v2)
+
+print fcmp(range(7), x)  #  0; fringes are equal
+print fcmp(range(6), x)  # -1; 1st list ends early
+print fcmp(x, range(6))  #  1; 2nd list ends early
+print fcmp(range(8), x)  #  1; 2nd list ends early
+print fcmp(x, range(8))  # -1; 1st list ends early
+print fcmp([1,[[2],8]],
+           [[[1],2],8])  #  0
+print fcmp([1,[[3],8]],
+           [[[1],2],8])  #  1
+print fcmp([1,[[2],8]],
+           [[[1],2],9])  # -1
+
+# end of example

Added: vendor/Python/current/Demo/threads/find.py
===================================================================
--- vendor/Python/current/Demo/threads/find.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/threads/find.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,155 @@
+# A parallelized "find(1)" using the thread module.
+
+# This demonstrates the use of a work queue and worker threads.
+# It really does do more stats/sec when using multiple threads,
+# although the improvement is only about 20-30 percent.
+# (That was 8 years ago.  In 2002, on Linux, I can't measure
+# a speedup. :-( )
+
+# I'm too lazy to write a command line parser for the full find(1)
+# command line syntax, so the predicate it searches for is wired-in,
+# see function selector() below.  (It currently searches for files with
+# world write permission.)
+
+# Usage: parfind.py [-w nworkers] [directory] ...
+# Default nworkers is 4
+
+
+import sys
+import getopt
+import string
+import time
+import os
+from stat import *
+import thread
+
+
+# Work queue class.  Usage:
+#   wq = WorkQ()
+#   wq.addwork(func, (arg1, arg2, ...)) # one or more calls
+#   wq.run(nworkers)
+# The work is done when wq.run() completes.
+# The function calls executed by the workers may add more work.
+# Don't use keyboard interrupts!
+
+class WorkQ:
+
+    # Invariants:
+
+    # - busy and work are only modified when mutex is locked
+    # - len(work) is the number of jobs ready to be taken
+    # - busy is the number of jobs being done
+    # - todo is locked iff there is no work and somebody is busy
+
+    def __init__(self):
+        self.mutex = thread.allocate()
+        self.todo = thread.allocate()
+        self.todo.acquire()
+        self.work = []
+        self.busy = 0
+
+    def addwork(self, func, args):
+        job = (func, args)
+        self.mutex.acquire()
+        self.work.append(job)
+        self.mutex.release()
+        if len(self.work) == 1:
+            self.todo.release()
+
+    def _getwork(self):
+        self.todo.acquire()
+        self.mutex.acquire()
+        if self.busy == 0 and len(self.work) == 0:
+            self.mutex.release()
+            self.todo.release()
+            return None
+        job = self.work[0]
+        del self.work[0]
+        self.busy = self.busy + 1
+        self.mutex.release()
+        if len(self.work) > 0:
+            self.todo.release()
+        return job
+
+    def _donework(self):
+        self.mutex.acquire()
+        self.busy = self.busy - 1
+        if self.busy == 0 and len(self.work) == 0:
+            self.todo.release()
+        self.mutex.release()
+
+    def _worker(self):
+        time.sleep(0.00001)     # Let other threads run
+        while 1:
+            job = self._getwork()
+            if not job:
+                break
+            func, args = job
+            apply(func, args)
+            self._donework()
+
+    def run(self, nworkers):
+        if not self.work:
+            return # Nothing to do
+        for i in range(nworkers-1):
+            thread.start_new(self._worker, ())
+        self._worker()
+        self.todo.acquire()
+
+
+# Main program
+
+def main():
+    nworkers = 4
+    opts, args = getopt.getopt(sys.argv[1:], '-w:')
+    for opt, arg in opts:
+        if opt == '-w':
+            nworkers = string.atoi(arg)
+    if not args:
+        args = [os.curdir]
+
+    wq = WorkQ()
+    for dir in args:
+        wq.addwork(find, (dir, selector, wq))
+
+    t1 = time.time()
+    wq.run(nworkers)
+    t2 = time.time()
+
+    sys.stderr.write('Total time %r sec.\n' % (t2-t1))
+
+
+# The predicate -- defines what files we look for.
+# Feel free to change this to suit your purpose
+
+def selector(dir, name, fullname, stat):
+    # Look for world writable files that are not symlinks
+    return (stat[ST_MODE] & 0002) != 0 and not S_ISLNK(stat[ST_MODE])
+
+
+# The find procedure -- calls wq.addwork() for subdirectories
+
+def find(dir, pred, wq):
+    try:
+        names = os.listdir(dir)
+    except os.error, msg:
+        print repr(dir), ':', msg
+        return
+    for name in names:
+        if name not in (os.curdir, os.pardir):
+            fullname = os.path.join(dir, name)
+            try:
+                stat = os.lstat(fullname)
+            except os.error, msg:
+                print repr(fullname), ':', msg
+                continue
+            if pred(dir, name, fullname, stat):
+                print fullname
+            if S_ISDIR(stat[ST_MODE]):
+                if not os.path.ismount(fullname):
+                    wq.addwork(find, (fullname, pred, wq))
+
+
+# Call the main program
+
+main()

Added: vendor/Python/current/Demo/threads/squasher.py
===================================================================
--- vendor/Python/current/Demo/threads/squasher.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/threads/squasher.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,105 @@
+# Coroutine example:  general coroutine transfers
+#
+# The program is a variation of a Simula 67 program due to Dahl & Hoare,
+# (Dahl/Dijkstra/Hoare, Structured Programming; Academic Press, 1972)
+# who in turn credit the original example to Conway.
+#
+# We have a number of input lines, terminated by a 0 byte.  The problem
+# is to squash them together into output lines containing 72 characters
+# each.  A semicolon must be added between input lines.  Runs of blanks
+# and tabs in input lines must be squashed into single blanks.
+# Occurrences of "**" in input lines must be replaced by "^".
+#
+# Here's a test case:
+
+test = """\
+   d    =   sqrt(b**2  -  4*a*c)
+twoa    =   2*a
+   L    =   -b/twoa
+   R    =   d/twoa
+  A1    =   L + R
+  A2    =   L - R\0
+"""
+
+# The program should print:
+
+# d = sqrt(b^2 - 4*a*c);twoa = 2*a; L = -b/twoa; R = d/twoa; A1 = L + R;
+#A2 = L - R
+#done
+
+# getline: delivers the next input line to its invoker
+# disassembler: grabs input lines from getline, and delivers them one
+#    character at a time to squasher, also inserting a semicolon into
+#    the stream between lines
+# squasher:  grabs characters from disassembler and passes them on to
+#    assembler, first replacing "**" with "^" and squashing runs of
+#    whitespace
+# assembler: grabs characters from squasher and packs them into lines
+#    with 72 character each, delivering each such line to putline;
+#    when it sees a null byte, passes the last line to putline and
+#    then kills all the coroutines
+# putline: grabs lines from assembler, and just prints them
+
+from Coroutine import *
+
+def getline(text):
+    for line in string.splitfields(text, '\n'):
+        co.tran(codisassembler, line)
+
+def disassembler():
+    while 1:
+        card = co.tran(cogetline)
+        for i in range(len(card)):
+            co.tran(cosquasher, card[i])
+        co.tran(cosquasher, ';')
+
+def squasher():
+    while 1:
+        ch = co.tran(codisassembler)
+        if ch == '*':
+            ch2 = co.tran(codisassembler)
+            if ch2 == '*':
+                ch = '^'
+            else:
+                co.tran(coassembler, ch)
+                ch = ch2
+        if ch in ' \t':
+            while 1:
+                ch2 = co.tran(codisassembler)
+                if ch2 not in ' \t':
+                    break
+            co.tran(coassembler, ' ')
+            ch = ch2
+        co.tran(coassembler, ch)
+
+def assembler():
+    line = ''
+    while 1:
+        ch = co.tran(cosquasher)
+        if ch == '\0':
+            break
+        if len(line) == 72:
+            co.tran(coputline, line)
+            line = ''
+        line = line + ch
+    line = line + ' ' * (72 - len(line))
+    co.tran(coputline, line)
+    co.kill()
+
+def putline():
+    while 1:
+        line = co.tran(coassembler)
+        print line
+
+import string
+co = Coroutine()
+cogetline = co.create(getline, test)
+coputline = co.create(putline)
+coassembler = co.create(assembler)
+codisassembler = co.create(disassembler)
+cosquasher = co.create(squasher)
+
+co.tran(coputline)
+print 'done'
+
+# end of example

Added: vendor/Python/current/Demo/threads/sync.py
===================================================================
--- vendor/Python/current/Demo/threads/sync.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/threads/sync.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,603 @@
+# Defines classes that provide synchronization objects.  Note that use of
+# this module requires that your Python support threads.
+#
+#    condition(lock=None)       # a POSIX-like condition-variable object
+#    barrier(n)                 # an n-thread barrier
+#    event()                    # an event object
+#    semaphore(n=1)             # a semaphore object, with initial count n
+#    mrsw()                     # a multiple-reader single-writer lock
+#
+# CONDITIONS
+#
+# A condition object is created via
+#   import this_module
+#   your_condition_object = this_module.condition(lock=None)
+#
+# As explained below, a condition object has a lock associated with it,
+# used in the protocol to protect condition data.  You can specify a
+# lock to use in the constructor, else the constructor will allocate
+# an anonymous lock for you.  Specifying a lock explicitly can be useful
+# when more than one condition keys off the same set of shared data.
+#
+# Methods:
+#   .acquire()
+#      acquire the lock associated with the condition
+#   .release()
+#      release the lock associated with the condition
+#   .wait()
+#      block the thread until such time as some other thread does a
+#      .signal or .broadcast on the same condition, and release the
+#      lock associated with the condition.  The lock associated with
+#      the condition MUST be in the acquired state at the time
+#      .wait is invoked.
+#   .signal()
+#      wake up exactly one thread (if any) that previously did a .wait
+#      on the condition; that thread will awaken with the lock associated
+#      with the condition in the acquired state.  If no threads are
+#      .wait'ing, this is a nop.  If more than one thread is .wait'ing on
+#      the condition, any of them may be awakened.
+#   .broadcast()
+#      wake up all threads (if any) that are .wait'ing on the condition;
+#      the threads are woken up serially, each with the lock in the
+#      acquired state, so should .release() as soon as possible.  If no
+#      threads are .wait'ing, this is a nop.
+#
+#      Note that if a thread does a .wait *while* a signal/broadcast is
+#      in progress, it's guaranteeed to block until a subsequent
+#      signal/broadcast.
+#
+#      Secret feature:  `broadcast' actually takes an integer argument,
+#      and will wake up exactly that many waiting threads (or the total
+#      number waiting, if that's less).  Use of this is dubious, though,
+#      and probably won't be supported if this form of condition is
+#      reimplemented in C.
+#
+# DIFFERENCES FROM POSIX
+#
+# + A separate mutex is not needed to guard condition data.  Instead, a
+#   condition object can (must) be .acquire'ed and .release'ed directly.
+#   This eliminates a common error in using POSIX conditions.
+#
+# + Because of implementation difficulties, a POSIX `signal' wakes up
+#   _at least_ one .wait'ing thread.  Race conditions make it difficult
+#   to stop that.  This implementation guarantees to wake up only one,
+#   but you probably shouldn't rely on that.
+#
+# PROTOCOL
+#
+# Condition objects are used to block threads until "some condition" is
+# true.  E.g., a thread may wish to wait until a producer pumps out data
+# for it to consume, or a server may wish to wait until someone requests
+# its services, or perhaps a whole bunch of threads want to wait until a
+# preceding pass over the data is complete.  Early models for conditions
+# relied on some other thread figuring out when a blocked thread's
+# condition was true, and made the other thread responsible both for
+# waking up the blocked thread and guaranteeing that it woke up with all
+# data in a correct state.  This proved to be very delicate in practice,
+# and gave conditions a bad name in some circles.
+#
+# The POSIX model addresses these problems by making a thread responsible
+# for ensuring that its own state is correct when it wakes, and relies
+# on a rigid protocol to make this easy; so long as you stick to the
+# protocol, POSIX conditions are easy to "get right":
+#
+#  A) The thread that's waiting for some arbitrarily-complex condition
+#     (ACC) to become true does:
+#
+#     condition.acquire()
+#     while not (code to evaluate the ACC):
+#           condition.wait()
+#           # That blocks the thread, *and* releases the lock.  When a
+#           # condition.signal() happens, it will wake up some thread that
+#           # did a .wait, *and* acquire the lock again before .wait
+#           # returns.
+#           #
+#           # Because the lock is acquired at this point, the state used
+#           # in evaluating the ACC is frozen, so it's safe to go back &
+#           # reevaluate the ACC.
+#
+#     # At this point, ACC is true, and the thread has the condition
+#     # locked.
+#     # So code here can safely muck with the shared state that
+#     # went into evaluating the ACC -- if it wants to.
+#     # When done mucking with the shared state, do
+#     condition.release()
+#
+#  B) Threads that are mucking with shared state that may affect the
+#     ACC do:
+#
+#     condition.acquire()
+#     # muck with shared state
+#     condition.release()
+#     if it's possible that ACC is true now:
+#         condition.signal() # or .broadcast()
+#
+#     Note:  You may prefer to put the "if" clause before the release().
+#     That's fine, but do note that anyone waiting on the signal will
+#     stay blocked until the release() is done (since acquiring the
+#     condition is part of what .wait() does before it returns).
+#
+# TRICK OF THE TRADE
+#
+# With simpler forms of conditions, it can be impossible to know when
+# a thread that's supposed to do a .wait has actually done it.  But
+# because this form of condition releases a lock as _part_ of doing a
+# wait, the state of that lock can be used to guarantee it.
+#
+# E.g., suppose thread A spawns thread B and later wants to wait for B to
+# complete:
+#
+# In A:                             In B:
+#
+# B_done = condition()              ... do work ...
+# B_done.acquire()                  B_done.acquire(); B_done.release()
+# spawn B                           B_done.signal()
+# ... some time later ...           ... and B exits ...
+# B_done.wait()
+#
+# Because B_done was in the acquire'd state at the time B was spawned,
+# B's attempt to acquire B_done can't succeed until A has done its
+# B_done.wait() (which releases B_done).  So B's B_done.signal() is
+# guaranteed to be seen by the .wait().  Without the lock trick, B
+# may signal before A .waits, and then A would wait forever.
+#
+# BARRIERS
+#
+# A barrier object is created via
+#   import this_module
+#   your_barrier = this_module.barrier(num_threads)
+#
+# Methods:
+#   .enter()
+#      the thread blocks until num_threads threads in all have done
+#      .enter().  Then the num_threads threads that .enter'ed resume,
+#      and the barrier resets to capture the next num_threads threads
+#      that .enter it.
+#
+# EVENTS
+#
+# An event object is created via
+#   import this_module
+#   your_event = this_module.event()
+#
+# An event has two states, `posted' and `cleared'.  An event is
+# created in the cleared state.
+#
+# Methods:
+#
+#   .post()
+#      Put the event in the posted state, and resume all threads
+#      .wait'ing on the event (if any).
+#
+#   .clear()
+#      Put the event in the cleared state.
+#
+#   .is_posted()
+#      Returns 0 if the event is in the cleared state, or 1 if the event
+#      is in the posted state.
+#
+#   .wait()
+#      If the event is in the posted state, returns immediately.
+#      If the event is in the cleared state, blocks the calling thread
+#      until the event is .post'ed by another thread.
+#
+# Note that an event, once posted, remains posted until explicitly
+# cleared.  Relative to conditions, this is both the strength & weakness
+# of events.  It's a strength because the .post'ing thread doesn't have to
+# worry about whether the threads it's trying to communicate with have
+# already done a .wait (a condition .signal is seen only by threads that
+# do a .wait _prior_ to the .signal; a .signal does not persist).  But
+# it's a weakness because .clear'ing an event is error-prone:  it's easy
+# to mistakenly .clear an event before all the threads you intended to
+# see the event get around to .wait'ing on it.  But so long as you don't
+# need to .clear an event, events are easy to use safely.
+#
+# SEMAPHORES
+#
+# A semaphore object is created via
+#   import this_module
+#   your_semaphore = this_module.semaphore(count=1)
+#
+# A semaphore has an integer count associated with it.  The initial value
+# of the count is specified by the optional argument (which defaults to
+# 1) passed to the semaphore constructor.
+#
+# Methods:
+#
+#   .p()
+#      If the semaphore's count is greater than 0, decrements the count
+#      by 1 and returns.
+#      Else if the semaphore's count is 0, blocks the calling thread
+#      until a subsequent .v() increases the count.  When that happens,
+#      the count will be decremented by 1 and the calling thread resumed.
+#
+#   .v()
+#      Increments the semaphore's count by 1, and wakes up a thread (if
+#      any) blocked by a .p().  It's an (detected) error for a .v() to
+#      increase the semaphore's count to a value larger than the initial
+#      count.
+#
+# MULTIPLE-READER SINGLE-WRITER LOCKS
+#
+# A mrsw lock is created via
+#   import this_module
+#   your_mrsw_lock = this_module.mrsw()
+#
+# This kind of lock is often useful with complex shared data structures.
+# The object lets any number of "readers" proceed, so long as no thread
+# wishes to "write".  When a (one or more) thread declares its intention
+# to "write" (e.g., to update a shared structure), all current readers
+# are allowed to finish, and then a writer gets exclusive access; all
+# other readers & writers are blocked until the current writer completes.
+# Finally, if some thread is waiting to write and another is waiting to
+# read, the writer takes precedence.
+#
+# Methods:
+#
+#   .read_in()
+#      If no thread is writing or waiting to write, returns immediately.
+#      Else blocks until no thread is writing or waiting to write.  So
+#      long as some thread has completed a .read_in but not a .read_out,
+#      writers are blocked.
+#
+#   .read_out()
+#      Use sometime after a .read_in to declare that the thread is done
+#      reading.  When all threads complete reading, a writer can proceed.
+#
+#   .write_in()
+#      If no thread is writing (has completed a .write_in, but hasn't yet
+#      done a .write_out) or reading (similarly), returns immediately.
+#      Else blocks the calling thread, and threads waiting to read, until
+#      the current writer completes writing or all the current readers
+#      complete reading; if then more than one thread is waiting to
+#      write, one of them is allowed to proceed, but which one is not
+#      specified.
+#
+#   .write_out()
+#      Use sometime after a .write_in to declare that the thread is done
+#      writing.  Then if some other thread is waiting to write, it's
+#      allowed to proceed.  Else all threads (if any) waiting to read are
+#      allowed to proceed.
+#
+#   .write_to_read()
+#      Use instead of a .write_in to declare that the thread is done
+#      writing but wants to continue reading without other writers
+#      intervening.  If there are other threads waiting to write, they
+#      are allowed to proceed only if the current thread calls
+#      .read_out; threads waiting to read are only allowed to proceed
+#      if there are are no threads waiting to write.  (This is a
+#      weakness of the interface!)
+
+import thread
+
+class condition:
+    def __init__(self, lock=None):
+        # the lock actually used by .acquire() and .release()
+        if lock is None:
+            self.mutex = thread.allocate_lock()
+        else:
+            if hasattr(lock, 'acquire') and \
+               hasattr(lock, 'release'):
+                self.mutex = lock
+            else:
+                raise TypeError, 'condition constructor requires ' \
+                                 'a lock argument'
+
+        # lock used to block threads until a signal
+        self.checkout = thread.allocate_lock()
+        self.checkout.acquire()
+
+        # internal critical-section lock, & the data it protects
+        self.idlock = thread.allocate_lock()
+        self.id = 0
+        self.waiting = 0  # num waiters subject to current release
+        self.pending = 0  # num waiters awaiting next signal
+        self.torelease = 0      # num waiters to release
+        self.releasing = 0      # 1 iff release is in progress
+
+    def acquire(self):
+        self.mutex.acquire()
+
+    def release(self):
+        self.mutex.release()
+
+    def wait(self):
+        mutex, checkout, idlock = self.mutex, self.checkout, self.idlock
+        if not mutex.locked():
+            raise ValueError, \
+                  "condition must be .acquire'd when .wait() invoked"
+
+        idlock.acquire()
+        myid = self.id
+        self.pending = self.pending + 1
+        idlock.release()
+
+        mutex.release()
+
+        while 1:
+            checkout.acquire(); idlock.acquire()
+            if myid < self.id:
+                break
+            checkout.release(); idlock.release()
+
+        self.waiting = self.waiting - 1
+        self.torelease = self.torelease - 1
+        if self.torelease:
+            checkout.release()
+        else:
+            self.releasing = 0
+            if self.waiting == self.pending == 0:
+                self.id = 0
+        idlock.release()
+        mutex.acquire()
+
+    def signal(self):
+        self.broadcast(1)
+
+    def broadcast(self, num = -1):
+        if num < -1:
+            raise ValueError, '.broadcast called with num %r' % (num,)
+        if num == 0:
+            return
+        self.idlock.acquire()
+        if self.pending:
+            self.waiting = self.waiting + self.pending
+            self.pending = 0
+            self.id = self.id + 1
+        if num == -1:
+            self.torelease = self.waiting
+        else:
+            self.torelease = min( self.waiting,
+                                  self.torelease + num )
+        if self.torelease and not self.releasing:
+            self.releasing = 1
+            self.checkout.release()
+        self.idlock.release()
+
+class barrier:
+    def __init__(self, n):
+        self.n = n
+        self.togo = n
+        self.full = condition()
+
+    def enter(self):
+        full = self.full
+        full.acquire()
+        self.togo = self.togo - 1
+        if self.togo:
+            full.wait()
+        else:
+            self.togo = self.n
+            full.broadcast()
+        full.release()
+
+class event:
+    def __init__(self):
+        self.state  = 0
+        self.posted = condition()
+
+    def post(self):
+        self.posted.acquire()
+        self.state = 1
+        self.posted.broadcast()
+        self.posted.release()
+
+    def clear(self):
+        self.posted.acquire()
+        self.state = 0
+        self.posted.release()
+
+    def is_posted(self):
+        self.posted.acquire()
+        answer = self.state
+        self.posted.release()
+        return answer
+
+    def wait(self):
+        self.posted.acquire()
+        if not self.state:
+            self.posted.wait()
+        self.posted.release()
+
+class semaphore:
+    def __init__(self, count=1):
+        if count <= 0:
+            raise ValueError, 'semaphore count %d; must be >= 1' % count
+        self.count = count
+        self.maxcount = count
+        self.nonzero = condition()
+
+    def p(self):
+        self.nonzero.acquire()
+        while self.count == 0:
+            self.nonzero.wait()
+        self.count = self.count - 1
+        self.nonzero.release()
+
+    def v(self):
+        self.nonzero.acquire()
+        if self.count == self.maxcount:
+            raise ValueError, '.v() tried to raise semaphore count above ' \
+                  'initial value %r' % self.maxcount
+        self.count = self.count + 1
+        self.nonzero.signal()
+        self.nonzero.release()
+
+class mrsw:
+    def __init__(self):
+        # critical-section lock & the data it protects
+        self.rwOK = thread.allocate_lock()
+        self.nr = 0  # number readers actively reading (not just waiting)
+        self.nw = 0  # number writers either waiting to write or writing
+        self.writing = 0  # 1 iff some thread is writing
+
+        # conditions
+        self.readOK  = condition(self.rwOK)  # OK to unblock readers
+        self.writeOK = condition(self.rwOK)  # OK to unblock writers
+
+    def read_in(self):
+        self.rwOK.acquire()
+        while self.nw:
+            self.readOK.wait()
+        self.nr = self.nr + 1
+        self.rwOK.release()
+
+    def read_out(self):
+        self.rwOK.acquire()
+        if self.nr <= 0:
+            raise ValueError, \
+                  '.read_out() invoked without an active reader'
+        self.nr = self.nr - 1
+        if self.nr == 0:
+            self.writeOK.signal()
+        self.rwOK.release()
+
+    def write_in(self):
+        self.rwOK.acquire()
+        self.nw = self.nw + 1
+        while self.writing or self.nr:
+            self.writeOK.wait()
+        self.writing = 1
+        self.rwOK.release()
+
+    def write_out(self):
+        self.rwOK.acquire()
+        if not self.writing:
+            raise ValueError, \
+                  '.write_out() invoked without an active writer'
+        self.writing = 0
+        self.nw = self.nw - 1
+        if self.nw:
+            self.writeOK.signal()
+        else:
+            self.readOK.broadcast()
+        self.rwOK.release()
+
+    def write_to_read(self):
+        self.rwOK.acquire()
+        if not self.writing:
+            raise ValueError, \
+                  '.write_to_read() invoked without an active writer'
+        self.writing = 0
+        self.nw = self.nw - 1
+        self.nr = self.nr + 1
+        if not self.nw:
+            self.readOK.broadcast()
+        self.rwOK.release()
+
+# The rest of the file is a test case, that runs a number of parallelized
+# quicksorts in parallel.  If it works, you'll get about 600 lines of
+# tracing output, with a line like
+#     test passed! 209 threads created in all
+# as the last line.  The content and order of preceding lines will
+# vary across runs.
+
+def _new_thread(func, *args):
+    global TID
+    tid.acquire(); id = TID = TID+1; tid.release()
+    io.acquire(); alive.append(id); \
+                  print 'starting thread', id, '--', len(alive), 'alive'; \
+                  io.release()
+    thread.start_new_thread( func, (id,) + args )
+
+def _qsort(tid, a, l, r, finished):
+    # sort a[l:r]; post finished when done
+    io.acquire(); print 'thread', tid, 'qsort', l, r; io.release()
+    if r-l > 1:
+        pivot = a[l]
+        j = l+1   # make a[l:j] <= pivot, and a[j:r] > pivot
+        for i in range(j, r):
+            if a[i] <= pivot:
+                a[j], a[i] = a[i], a[j]
+                j = j + 1
+        a[l], a[j-1] = a[j-1], pivot
+
+        l_subarray_sorted = event()
+        r_subarray_sorted = event()
+        _new_thread(_qsort, a, l, j-1, l_subarray_sorted)
+        _new_thread(_qsort, a, j, r,   r_subarray_sorted)
+        l_subarray_sorted.wait()
+        r_subarray_sorted.wait()
+
+    io.acquire(); print 'thread', tid, 'qsort done'; \
+                  alive.remove(tid); io.release()
+    finished.post()
+
+def _randarray(tid, a, finished):
+    io.acquire(); print 'thread', tid, 'randomizing array'; \
+                  io.release()
+    for i in range(1, len(a)):
+        wh.acquire(); j = randint(0,i); wh.release()
+        a[i], a[j] = a[j], a[i]
+    io.acquire(); print 'thread', tid, 'randomizing done'; \
+                  alive.remove(tid); io.release()
+    finished.post()
+
+def _check_sort(a):
+    if a != range(len(a)):
+        raise ValueError, ('a not sorted', a)
+
+def _run_one_sort(tid, a, bar, done):
+    # randomize a, and quicksort it
+    # for variety, all the threads running this enter a barrier
+    # at the end, and post `done' after the barrier exits
+    io.acquire(); print 'thread', tid, 'randomizing', a; \
+                  io.release()
+    finished = event()
+    _new_thread(_randarray, a, finished)
+    finished.wait()
+
+    io.acquire(); print 'thread', tid, 'sorting', a; io.release()
+    finished.clear()
+    _new_thread(_qsort, a, 0, len(a), finished)
+    finished.wait()
+    _check_sort(a)
+
+    io.acquire(); print 'thread', tid, 'entering barrier'; \
+                  io.release()
+    bar.enter()
+    io.acquire(); print 'thread', tid, 'leaving barrier'; \
+                  io.release()
+    io.acquire(); alive.remove(tid); io.release()
+    bar.enter() # make sure they've all removed themselves from alive
+                ##  before 'done' is posted
+    bar.enter() # just to be cruel
+    done.post()
+
+def test():
+    global TID, tid, io, wh, randint, alive
+    import random
+    randint = random.randint
+
+    TID = 0                             # thread ID (1, 2, ...)
+    tid = thread.allocate_lock()        # for changing TID
+    io  = thread.allocate_lock()        # for printing, and 'alive'
+    wh  = thread.allocate_lock()        # for calls to random
+    alive = []                          # IDs of active threads
+
+    NSORTS = 5
+    arrays = []
+    for i in range(NSORTS):
+        arrays.append( range( (i+1)*10 ) )
+
+    bar = barrier(NSORTS)
+    finished = event()
+    for i in range(NSORTS):
+        _new_thread(_run_one_sort, arrays[i], bar, finished)
+    finished.wait()
+
+    print 'all threads done, and checking results ...'
+    if alive:
+        raise ValueError, ('threads still alive at end', alive)
+    for i in range(NSORTS):
+        a = arrays[i]
+        if len(a) != (i+1)*10:
+            raise ValueError, ('length of array', i, 'screwed up')
+        _check_sort(a)
+
+    print 'test passed!', TID, 'threads created in all'
+
+if __name__ == '__main__':
+    test()
+
+# end of module

Added: vendor/Python/current/Demo/threads/telnet.py
===================================================================
--- vendor/Python/current/Demo/threads/telnet.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/threads/telnet.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,114 @@
+# Minimal interface to the Internet telnet protocol.
+#
+# *** modified to use threads ***
+#
+# It refuses all telnet options and does not recognize any of the other
+# telnet commands, but can still be used to connect in line-by-line mode.
+# It's also useful to play with a number of other services,
+# like time, finger, smtp and even ftp.
+#
+# Usage: telnet host [port]
+#
+# The port may be a service name or a decimal port number;
+# it defaults to 'telnet'.
+
+
+import sys, os, time
+from socket import *
+import thread
+
+BUFSIZE = 8*1024
+
+# Telnet protocol characters
+
+IAC  = chr(255) # Interpret as command
+DONT = chr(254)
+DO   = chr(253)
+WONT = chr(252)
+WILL = chr(251)
+
+def main():
+    if len(sys.argv) < 2:
+        sys.stderr.write('usage: telnet hostname [port]\n')
+        sys.exit(2)
+    host = sys.argv[1]
+    try:
+        hostaddr = gethostbyname(host)
+    except error:
+        sys.stderr.write(sys.argv[1] + ': bad host name\n')
+        sys.exit(2)
+    #
+    if len(sys.argv) > 2:
+        servname = sys.argv[2]
+    else:
+        servname = 'telnet'
+    #
+    if '0' <= servname[:1] <= '9':
+        port = eval(servname)
+    else:
+        try:
+            port = getservbyname(servname, 'tcp')
+        except error:
+            sys.stderr.write(servname + ': bad tcp service name\n')
+            sys.exit(2)
+    #
+    s = socket(AF_INET, SOCK_STREAM)
+    #
+    try:
+        s.connect((host, port))
+    except error, msg:
+        sys.stderr.write('connect failed: %r\n' % (msg,))
+        sys.exit(1)
+    #
+    thread.start_new(child, (s,))
+    parent(s)
+
+def parent(s):
+    # read socket, write stdout
+    iac = 0         # Interpret next char as command
+    opt = ''        # Interpret next char as option
+    while 1:
+        data, dummy = s.recvfrom(BUFSIZE)
+        if not data:
+            # EOF -- exit
+            sys.stderr.write( '(Closed by remote host)\n')
+            sys.exit(1)
+        cleandata = ''
+        for c in data:
+            if opt:
+                print ord(c)
+##                              print '(replying: %r)' % (opt+c,)
+                s.send(opt + c)
+                opt = ''
+            elif iac:
+                iac = 0
+                if c == IAC:
+                    cleandata = cleandata + c
+                elif c in (DO, DONT):
+                    if c == DO: print '(DO)',
+                    else: print '(DONT)',
+                    opt = IAC + WONT
+                elif c in (WILL, WONT):
+                    if c == WILL: print '(WILL)',
+                    else: print '(WONT)',
+                    opt = IAC + DONT
+                else:
+                    print '(command)', ord(c)
+            elif c == IAC:
+                iac = 1
+                print '(IAC)',
+            else:
+                cleandata = cleandata + c
+        sys.stdout.write(cleandata)
+        sys.stdout.flush()
+##              print 'Out:', repr(cleandata)
+
+def child(s):
+    # read stdin, write socket
+    while 1:
+        line = sys.stdin.readline()
+##              print 'Got:', repr(line)
+        if not line: break
+        s.send(line)
+
+main()

Added: vendor/Python/current/Demo/tix/INSTALL.txt
===================================================================
--- vendor/Python/current/Demo/tix/INSTALL.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tix/INSTALL.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,89 @@
+$Id: INSTALL.txt 24230 2001-11-11 14:07:37Z loewis $
+
+Installing Tix.py
+----------------
+
+0) To use Tix.py, you need Tcl/Tk (V8.3.3), Tix (V8.1.1) and Python (V2.1.1).
+   Tix.py has been written and tested on a Intel Pentium running RH Linux 5.2
+   and Mandrake Linux 7.0 and Windows with the above mentioned packages.
+
+   Older versions, e.g. Tix 4.1 and Tk 8.0, might also work.
+
+   There is nothing OS-specific in Tix.py itself so it should work on
+   any machine with Tix and Python installed. You can get Tcl and Tk
+   from http://dev.scriptics.com and Tix from http://tix.sourceforge.net.
+
+1) Build and install Tcl/Tk 8.3. Build and install Tix 8.1.
+   Ensure that Tix is properly installed by running tixwish and executing
+   the demo programs. Under Unix, use the --enable-shared configure option
+   for all three. We recommend tcl8.3.3 for this release of Tix.py.
+
+2a) If you have a distribution like ActiveState with a tcl subdirectory
+   of $PYTHONHOME, which contains the directories tcl8.3 and tk8.3,
+   make a directory tix8.1 as well. Recursively copy the files from
+   <tix>/library to $PYTHONHOME/lib/tix8.1, and copy the dynamic library
+   (tix8183.dll or libtix8.1.8.3.so) to the same place as the tcl dynamic
+   libraries  ($PYTHONHOME/Dlls or lib/python-2.1/lib-dynload). In this
+   case you are all installed, and you can skip to the end.
+
+2b) Modify Modules/Setup.dist and setup.py to change the version of the 
+   tix library from tix4.1.8.0 to tix8.1.8.3
+   These modified files can be used for Tkinter with or without Tix.
+   
+3) The default is to build dynamically, and use the Tcl 'package require'.
+   To build statically, modify the Modules/Setup file to link in the Tix 
+   library according to the comments in the file. On Linux this looks like:
+
+# *** Always uncomment this (leave the leading underscore in!):
+_tkinter _tkinter.c tkappinit.c -DWITH_APPINIT \
+# *** Uncomment and edit to reflect where your Tcl/Tk libraries are:
+	-L/usr/local/lib \
+# *** Uncomment and edit to reflect where your Tcl/Tk headers are:
+	-I/usr/local/include \
+# *** Uncomment and edit to reflect where your X11 header files are:
+	-I/usr/X11R6/include \
+# *** Or uncomment this for Solaris:
+#	-I/usr/openwin/include \
+# *** Uncomment and edit for BLT extension only:
+#	-DWITH_BLT -I/usr/local/blt/blt8.0-unoff/include -lBLT8.0 \
+# *** Uncomment and edit for PIL (TkImaging) extension only:
+#     (See http://www.pythonware.com/products/pil/ for more info)
+#	-DWITH_PIL -I../Extensions/Imaging/libImaging  tkImaging.c \
+# *** Uncomment and edit for TOGL extension only:
+#	-DWITH_TOGL togl.c \
+# *** Uncomment and edit for Tix extension only:
+	-DWITH_TIX -ltix8.1.8.3 \
+# *** Uncomment and edit to reflect your Tcl/Tk versions:
+	-ltk8.3 -ltcl8.3 \
+# *** Uncomment and edit to reflect where your X11 libraries are:
+	-L/usr/X11R6/lib \
+# *** Or uncomment this for Solaris:
+#	-L/usr/openwin/lib \
+# *** Uncomment these for TOGL extension only:
+#	-lGL -lGLU -lXext -lXmu \
+# *** Uncomment for AIX:
+#	-lld \
+# *** Always uncomment this; X11 libraries to link with:
+	-lX11
+
+4) Rebuild Python and reinstall.
+
+You should now have a working Tix implementation in Python. To see if all
+is as it should be, run the 'tixwidgets.py' script in the Demo/tix directory.
+Under X windows, do
+	/usr/local/bin/python Demo/tix/tixwidgets.py
+
+If this does not work, you may need to tell python where to find
+the Tcl, Tk and Tix library files. This is done by setting the
+TCL_LIBRARY, TK_LIBRARY and TIX_LIBRARY environment variables. Try this:
+
+	env 	TCL_LIBRARY=/usr/local/lib/tcl8.3 \
+		TK_LIBRARY=/usr/local/lib/tk8.3 \
+		TIX_LIBRARY=/usr/local/lib/tix8.1 \
+		/usr/local/bin/python Demo/tix/tixwidgets.py
+
+
+If you find any bugs or have suggestions for improvement, please report them
+via http://tix.sourceforge.net
+
+

Added: vendor/Python/current/Demo/tix/README.txt
===================================================================
--- vendor/Python/current/Demo/tix/README.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tix/README.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,19 @@
+About Tix.py
+-----------
+
+Tix.py is based on an idea of Jean-Marc Lugrin (lugrin at ms.com) who wrote
+pytix (another Python-Tix marriage). Tix widgets are an attractive and
+useful extension to Tk. See http://tix.sourceforge.net
+for more details about Tix and how to get it.
+
+Features:
+	1) It is almost complete.
+	2) Tix widgets are represented by classes in Python. Sub-widgets
+	   are members of the mega-widget class. For example, if a
+	   particular TixWidget (e.g. ScrolledText) has an embedded widget
+	   (Text in this case), it is possible to call the methods of the
+	   child directly.
+	3) The members of the class are created automatically. In the case
+	   of widgets like ButtonBox, the members are added dynamically.
+
+

Added: vendor/Python/current/Demo/tix/bitmaps/about.xpm
===================================================================
--- vendor/Python/current/Demo/tix/bitmaps/about.xpm	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tix/bitmaps/about.xpm	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,50 @@
+/* XPM */
+static char * about_xpm[] = {
+"50 40 7 1",
+" 	s None	c None",
+".	c black",
+"X	c white",
+"o	c gray70",
+"O	c navy",
+"+	c red",
+"@	c yellow",
+"                                                  ",
+"                                                  ",
+"                                                  ",
+"        .................................         ",
+"      ..XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXoo.         ",
+"      .XooooooooooooooooooooooooooooooXo.         ",
+"     .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXooXo.         ",
+"     ..oooooooooooooooooooooooooooooooXo.         ",
+"     ...............................XoXo.         ",
+"     .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo.         ",
+"     .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo.         ",
+"     .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo.         ",
+"     .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo.         ",
+"     .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo.++++     ",
+"     .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo+++       ",
+"     .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.Xo+++++       ",
+"     .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.Xo++++++      ",
+"     .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.Xo+++   +     ",
+"     .OOOOO@@@@@OOOOOOOOOOOOOOOOOOO.Xo++.         ",
+"     .OOOOOOO at OOOOO@OOOOOOOOOOOOOOO.XoXo.         ",
+"     .OOOOOOO at OOOOOOOOOOOOOOOOOOOOO.XoXo.         ",
+"     .OOOOOOO at OOOO@@OOO at OOO@OOOOOOO.XoXo.         ",
+"     .OOOOOOO at OOOOO@OOOO at O@OOOOOOOO.XoXo.         ",
+"     .OOOOOOO at OOOOO@OOOOO at OOOOOOOOO.XoXo.         ",
+"     .OOOOOOO at OOOOO@OOOOO at OOOOOOOOO.XoXo.         ",
+"     .OOOOOOO at OOOOO@OOOO at O@OOOOOOOO.XoXo.         ",
+"     .OOOOOOO at OOOO@@@OO at OOO@OOOOOOO.XoXo.         ",
+"     .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo.         ",
+"     .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo.         ",
+"     .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo.         ",
+"     .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo.         ",
+"     .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo.         ",
+"     .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo.         ",
+"     .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.Xo..          ",
+"     .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.Xo            ",
+"      OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.X.            ",
+"        .............................             ",
+"                                                  ",
+"                                                  ",
+"                                                  "};


Property changes on: vendor/Python/current/Demo/tix/bitmaps/about.xpm
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tix/bitmaps/bold.xbm
===================================================================
--- vendor/Python/current/Demo/tix/bitmaps/bold.xbm	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tix/bitmaps/bold.xbm	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,6 @@
+#define bold_width 16
+#define bold_height 16
+static unsigned char bold_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0xfc, 0x07, 0xfc, 0x0f, 0x18, 0x1c, 0x18, 0x18,
+   0x18, 0x18, 0x18, 0x1c, 0xf8, 0x0f, 0xf8, 0x0f, 0x18, 0x18, 0x18, 0x30,
+   0x18, 0x30, 0x18, 0x38, 0xfc, 0x3f, 0xfc, 0x1f};


Property changes on: vendor/Python/current/Demo/tix/bitmaps/bold.xbm
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tix/bitmaps/capital.xbm
===================================================================
--- vendor/Python/current/Demo/tix/bitmaps/capital.xbm	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tix/bitmaps/capital.xbm	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,6 @@
+#define capital_width 16
+#define capital_height 16
+static unsigned char capital_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x08, 0x30, 0x0c, 0x30, 0x06,
+   0x30, 0x03, 0xb0, 0x01, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x01, 0xb0, 0x03,
+   0x30, 0x07, 0x30, 0x0e, 0x30, 0x1c, 0x00, 0x00};


Property changes on: vendor/Python/current/Demo/tix/bitmaps/capital.xbm
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tix/bitmaps/centerj.xbm
===================================================================
--- vendor/Python/current/Demo/tix/bitmaps/centerj.xbm	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tix/bitmaps/centerj.xbm	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,6 @@
+#define centerj_width 16
+#define centerj_height 16
+static unsigned char centerj_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3e, 0x00, 0x00, 0xc0, 0x0d,
+   0x00, 0x00, 0x58, 0x77, 0x00, 0x00, 0xb0, 0x3b, 0x00, 0x00, 0xdc, 0xf7,
+   0x00, 0x00, 0xf0, 0x3e, 0x00, 0x00, 0xd8, 0x7e};


Property changes on: vendor/Python/current/Demo/tix/bitmaps/centerj.xbm
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tix/bitmaps/combobox.xbm
===================================================================
--- vendor/Python/current/Demo/tix/bitmaps/combobox.xbm	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tix/bitmaps/combobox.xbm	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,14 @@
+#define combobox_width 32
+#define combobox_height 32
+static unsigned char combobox_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0xfc, 0xff, 0xff, 0x3e, 0x04, 0x00, 0x80, 0x2a, 0x04, 0x00, 0x80, 0x2a,
+   0x04, 0x00, 0x80, 0x2a, 0x04, 0x00, 0x80, 0x2b, 0xfc, 0xff, 0xff, 0x3e,
+   0x08, 0x00, 0x00, 0x20, 0x08, 0x00, 0x00, 0x3e, 0x08, 0x00, 0x00, 0x2a,
+   0x28, 0x49, 0x00, 0x2a, 0x08, 0x00, 0x00, 0x3e, 0x08, 0x00, 0x00, 0x22,
+   0x08, 0x00, 0x00, 0x22, 0x28, 0x49, 0x12, 0x22, 0x08, 0x00, 0x00, 0x22,
+   0x08, 0x00, 0x00, 0x22, 0x08, 0x00, 0x00, 0x22, 0x28, 0x49, 0x02, 0x22,
+   0x08, 0x00, 0x00, 0x3e, 0x08, 0x00, 0x00, 0x2a, 0x08, 0x00, 0x00, 0x2a,
+   0xf8, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};


Property changes on: vendor/Python/current/Demo/tix/bitmaps/combobox.xbm
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tix/bitmaps/combobox.xpm
===================================================================
--- vendor/Python/current/Demo/tix/bitmaps/combobox.xpm	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tix/bitmaps/combobox.xpm	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,49 @@
+/* XPM */
+static char * combobox_xpm[] = {
+"50 40 6 1",
+" 	s None	c None",
+".	c black",
+"X	c white",
+"o	c #FFFF80808080",
+"O	c gray70",
+"+	c #808000008080",
+"                                                  ",
+"                                                  ",
+"                                                  ",
+"   ....................................  XXXXXXX  ",
+"   .ooooooooooooooooooooooooooooooooooX  X  .  .  ",
+"   .ooooooooooooooooooooooooooooooooooX  X  .  .  ",
+"   .oooo.oooooooooooooooooooooooooooooX  X  .  .  ",
+"   .oo.o..oo.o.oo.o.ooooooooooooooooooX  X  .  .  ",
+"   .o..o.o.o.oo.oo.oo.ooooooooooooooooX  X ... .  ",
+"   .oo.oo.oo.o.oo.ooo.ooooooooooooooooX  X  .  .  ",
+"   .ooooooooooooooooooooooooooooooooooX  X     .  ",
+"   .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX  X......  ",
+"                                                  ",
+"                                                  ",
+"                                                  ",
+"   XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX  ",
+"   X............................................  ",
+"   X.OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOX.OOOOX.  ",
+"   X.O+OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOX.OX OX.  ",
+"   X.O++OOO+OO+++OOOOOOOOOOOOOOOOOOOOOOOX.X ..X.  ",
+"   X.O+O+O+OOO+O+OOOOOOOOOOOOOOOOOOOOOOOX.OOOOX.  ",
+"   X.O++OOO+OO+++OOOOOOOOOOOOOOOOOOOOOOOX.OOOOX.  ",
+"   X.OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOX.XXXXX.  ",
+"   X.O.....X..........................OOX.X  .X.  ",
+"   X.OX...XXX.X.XX.XX.................OOX.X  .X.  ",
+"   X.OX.X..X..X.XX..XX.X..............OOX.X  .X.  ",
+"   X.O.X...X..X.X...X..X..............OOX.X  .X.  ",
+"   X.OOOOOOOOOOOOOOOOOOOOOOOO+OOOOOOOOOOX.X  .X.  ",
+"   X.OOOOOOOOO+OOO+OOOOO+OOOO+OOOOOOOOOOX.X  .X.  ",
+"   X.O+++OO+OO+O+OO++O++OO+OO+OOOOOOOOOOX.X...X.  ",
+"   X.OO+OO++OO+O+OO+OOO+OO+O++OOOOOOOOOOX.OOOOX.  ",
+"   X.OOOOOOOO+OOOOO++OO+OOOOOOOOOOOOOOOOX.OOOOX.  ",
+"   X.OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOX.X  .X.  ",
+"   X.OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOX.O .OX.  ",
+"   X.OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOX.OOOOX.  ",
+"   X.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.XXXXX.  ",
+"   X............................................  ",
+"                                                  ",
+"                                                  ",
+"                                                  "};


Property changes on: vendor/Python/current/Demo/tix/bitmaps/combobox.xpm
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tix/bitmaps/combobox.xpm.1
===================================================================
--- vendor/Python/current/Demo/tix/bitmaps/combobox.xpm.1	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tix/bitmaps/combobox.xpm.1	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,47 @@
+/* XPM */
+static char * combobox_xpm[] = {
+"50 40 4 1",
+" 	s None	c None",
+".	c black",
+"X	c #FFFF80808080",
+"o	c gray70",
+"                                                  ",
+"                                                  ",
+"                                                  ",
+"   ....................................  .......  ",
+"   .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.  .  .  .  ",
+"   .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.  .  .  .  ",
+"   .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.  .  .  .  ",
+"   .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.  .  .  .  ",
+"   .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.  . ... .  ",
+"   .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.  .  .  .  ",
+"   .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.  .     .  ",
+"   ....................................  .......  ",
+"                                                  ",
+"   .............................................  ",
+"   .ooooooooooooooooooooooooooooooooooooo.ooooo.  ",
+"   .ooooooooooooooooooooooooooooooooooooo.ooooo.  ",
+"   .o...................................o.ooooo.  ",
+"   .o...................................o.ooooo.  ",
+"   .o...................................o.ooooo.  ",
+"   .o...................................o.ooooo.  ",
+"   .ooooooooooooooooooooooooooooooooooooo.ooooo.  ",
+"   .ooooooooooooooooooooooooooooooooooooo.ooooo.  ",
+"   .ooooooooooooooooooooooooooooooooooooo.ooooo.  ",
+"   .ooooooooooooooooooooooooooooooooooooo.ooooo.  ",
+"   .ooooooooooooooooooooooooooooooooooooo.ooooo.  ",
+"   .ooooooooooooooooooooooooooooooooooooo.ooooo.  ",
+"   .ooooooooooooooooooooooooooooooooooooo.ooooo.  ",
+"   .ooooooooooooooooooooooooooooooooooooo.ooooo.  ",
+"   .ooooooooooooooooooooooooooooooooooooo.ooooo.  ",
+"   .ooooooooooooooooooooooooooooooooooooo.ooooo.  ",
+"   .ooooooooooooooooooooooooooooooooooooo.ooooo.  ",
+"   .ooooooooooooooooooooooooooooooooooooo.ooooo.  ",
+"   .ooooooooooooooooooooooooooooooooooooo.ooooo.  ",
+"   .ooooooooooooooooooooooooooooooooooooo.ooooo.  ",
+"   .............................................  ",
+"                                                  ",
+"                                                  ",
+"                                                  ",
+"                                                  ",
+"                                                  "};


Property changes on: vendor/Python/current/Demo/tix/bitmaps/combobox.xpm.1
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tix/bitmaps/drivea.xbm
===================================================================
--- vendor/Python/current/Demo/tix/bitmaps/drivea.xbm	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tix/bitmaps/drivea.xbm	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,14 @@
+#define drivea_width 32
+#define drivea_height 32
+static unsigned char drivea_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0xf8, 0xff, 0xff, 0x1f, 0x08, 0x00, 0x00, 0x18, 0xa8, 0xaa, 0xaa, 0x1a,
+   0x48, 0x55, 0xd5, 0x1d, 0xa8, 0xaa, 0xaa, 0x1b, 0x48, 0x55, 0x55, 0x1d,
+   0xa8, 0xfa, 0xaf, 0x1a, 0xc8, 0xff, 0xff, 0x1d, 0xa8, 0xfa, 0xaf, 0x1a,
+   0x48, 0x55, 0x55, 0x1d, 0xa8, 0xaa, 0xaa, 0x1a, 0x48, 0x55, 0x55, 0x1d,
+   0xa8, 0xaa, 0xaa, 0x1a, 0xf8, 0xff, 0xff, 0x1f, 0xf8, 0xff, 0xff, 0x1f,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};


Property changes on: vendor/Python/current/Demo/tix/bitmaps/drivea.xbm
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tix/bitmaps/drivea.xpm
===================================================================
--- vendor/Python/current/Demo/tix/bitmaps/drivea.xpm	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tix/bitmaps/drivea.xpm	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,43 @@
+/* XPM */
+static char * drivea_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"32 32 5 1",
+/* colors */
+" 	s None	c None",
+".	c #000000000000",
+"X	c white",
+"o	c #c000c000c000",
+"O	c #800080008000",
+/* pixels */
+"                                ",
+"                                ",
+"                                ",
+"                                ",
+"                                ",
+"                                ",
+"                                ",
+"                                ",
+"                                ",
+"   ..........................   ",
+"   .XXXXXXXXXXXXXXXXXXXXXXXo.   ",
+"   .XooooooooooooooooooooooO.   ",
+"   .Xooooooooooooooooo..oooO.   ",
+"   .Xooooooooooooooooo..oooO.   ",
+"   .XooooooooooooooooooooooO.   ",
+"   .Xoooooooo.......oooooooO.   ",
+"   .Xoo...................oO.   ",
+"   .Xoooooooo.......oooooooO.   ",
+"   .XooooooooooooooooooooooO.   ",
+"   .XooooooooooooooooooooooO.   ",
+"   .XooooooooooooooooooooooO.   ",
+"   .XooooooooooooooooooooooO.   ",
+"   .oOOOOOOOOOOOOOOOOOOOOOOO.   ",
+"   ..........................   ",
+"                                ",
+"                                ",
+"                                ",
+"                                ",
+"                                ",
+"                                ",
+"                                ",
+"                                "};


Property changes on: vendor/Python/current/Demo/tix/bitmaps/drivea.xpm
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tix/bitmaps/exit.xpm
===================================================================
--- vendor/Python/current/Demo/tix/bitmaps/exit.xpm	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tix/bitmaps/exit.xpm	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,48 @@
+/* XPM */
+static char * exit_xpm[] = {
+"50 40 5 1",
+" 	s None	c None",
+".	c black",
+"X	c white",
+"o	c #000080800000",
+"O	c yellow",
+"                                                  ",
+"                                                  ",
+"                                                  ",
+"                                                  ",
+"                                                  ",
+"                                                  ",
+"                                                  ",
+"                                                  ",
+"                                                  ",
+"     .......................................      ",
+"     .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.      ",
+"     .XoooooooooooooooooooooooooooooooooooX.      ",
+"     .XoooooooooooooooooooooooooooooooooooX.      ",
+"     .XoooooooooooooooooooooooOoooooooooooX.      ",
+"     .XoooooooooooooooooooooooOOooooooooooX.      ",
+"     .XoooooooooooooooooooooooOOOoooooooooX.      ",
+"     .XoooooOOOOOOOOOOOOOOOOOOOOOOooooooooX.      ",
+"     .XoooooOOOOOOOOOOOOOOOOOOOOOOOoooooooX.      ",
+"     .XoooooOOOOOOOOOOOOOOOOOOOOOOOOooooooX.      ",
+"     .XoooooOOOOOOOOOOOOOOOOOOOOOOOOOoooooX.      ",
+"     .XoooooOOOOOOOOOOOOOOOOOOOOOOOOooooooX.      ",
+"     .XoooooOOOOOOOOOOOOOOOOOOOOOOOoooooooX.      ",
+"     .XoooooOOOOOOOOOOOOOOOOOOOOOOooooooooX.      ",
+"     .XoooooooooooooooooooooooOOOoooooooooX.      ",
+"     .XoooooooooooooooooooooooOOooooooooooX.      ",
+"     .XoooooooooooooooooooooooOoooooooooooX.      ",
+"     .XoooooooooooooooooooooooooooooooooooX.      ",
+"     .XoooooooooooooooooooooooooooooooooooX.      ",
+"     .XoooooooooooooooooooooooooooooooooooX.      ",
+"     .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.      ",
+"     .......................................      ",
+"                                                  ",
+"                                                  ",
+"                                                  ",
+"                                                  ",
+"                                                  ",
+"                                                  ",
+"                                                  ",
+"                                                  ",
+"                                                  "};


Property changes on: vendor/Python/current/Demo/tix/bitmaps/exit.xpm
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tix/bitmaps/filebox.xbm
===================================================================
--- vendor/Python/current/Demo/tix/bitmaps/filebox.xbm	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tix/bitmaps/filebox.xbm	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,14 @@
+#define filebox_width 32
+#define filebox_height 32
+static unsigned char filebox_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0x3f, 0x04, 0x00, 0x00, 0x20,
+   0xe4, 0xff, 0xff, 0x27, 0x24, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x24,
+   0xe4, 0xff, 0xff, 0x27, 0x04, 0x00, 0x00, 0x20, 0xe4, 0x7f, 0xfe, 0x27,
+   0x24, 0x50, 0x02, 0x25, 0x24, 0x40, 0x02, 0x24, 0x24, 0x50, 0x02, 0x25,
+   0x24, 0x40, 0x02, 0x24, 0x24, 0x50, 0x02, 0x25, 0x24, 0x40, 0x02, 0x24,
+   0x24, 0x50, 0x02, 0x25, 0xe4, 0x7f, 0xfe, 0x27, 0x04, 0x00, 0x00, 0x20,
+   0xe4, 0xff, 0xff, 0x27, 0x24, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x24,
+   0xe4, 0xff, 0xff, 0x27, 0x04, 0x00, 0x00, 0x20, 0xfc, 0xff, 0xff, 0x3f,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};


Property changes on: vendor/Python/current/Demo/tix/bitmaps/filebox.xbm
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tix/bitmaps/filebox.xpm
===================================================================
--- vendor/Python/current/Demo/tix/bitmaps/filebox.xpm	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tix/bitmaps/filebox.xpm	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,49 @@
+/* XPM */
+static char * filebox_xpm[] = {
+"50 40 6 1",
+" 	s None	c None",
+".	c white",
+"X	c gray80",
+"o	c black",
+"O	c #FFFF80808080",
+"+	c gray70",
+"                                                  ",
+"                                                  ",
+"                                                  ",
+"   ............................................   ",
+"   .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo   ",
+"   .XXooXooXoXooXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo   ",
+"   .XXooXooXoXooXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo   ",
+"   .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo   ",
+"   .XXooooooooooooooooooooooooooooooooooooo.XXo   ",
+"   .XXoOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XXo   ",
+"   .XXoOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XXo   ",
+"   .XX......................................XXo   ",
+"   .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo   ",
+"   .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo   ",
+"   .XXoooooooooooooooo.XXXXoooooooooooooooo.XXo   ",
+"   .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo   ",
+"   .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo   ",
+"   .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo   ",
+"   .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo   ",
+"   .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo   ",
+"   .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo   ",
+"   .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo   ",
+"   .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo   ",
+"   .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo   ",
+"   .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo   ",
+"   .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo   ",
+"   .XX.................XXXX.................XXo   ",
+"   .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo   ",
+"   .XXooXooXoXooXoXXXXXXXXXXXXXXXXXXXXXXXXXXXXo   ",
+"   .XXooXooXoXooXoXooXXXXXXXXXXXXXXXXXXXXXXXXXo   ",
+"   .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo   ",
+"   .XXoooooooooooooooooooooooooooooooooooooo.Xo   ",
+"   .XXoOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO.Xo   ",
+"   .XXoOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO.Xo   ",
+"   .XX.......................................Xo   ",
+"   .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo   ",
+"   .ooooooooooooooooooooooooooooooooooooooooooo   ",
+"                                                  ",
+"                                                  ",
+"                                                  "};


Property changes on: vendor/Python/current/Demo/tix/bitmaps/filebox.xpm
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tix/bitmaps/italic.xbm
===================================================================
--- vendor/Python/current/Demo/tix/bitmaps/italic.xbm	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tix/bitmaps/italic.xbm	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,6 @@
+#define italic_width 16
+#define italic_height 16
+static unsigned char italic_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x80, 0x3f, 0x00, 0x06, 0x00, 0x06,
+   0x00, 0x03, 0x00, 0x03, 0x80, 0x01, 0x80, 0x01, 0xc0, 0x00, 0xc0, 0x00,
+   0x60, 0x00, 0x60, 0x00, 0xfc, 0x01, 0xfc, 0x01};


Property changes on: vendor/Python/current/Demo/tix/bitmaps/italic.xbm
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tix/bitmaps/justify.xbm
===================================================================
--- vendor/Python/current/Demo/tix/bitmaps/justify.xbm	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tix/bitmaps/justify.xbm	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,6 @@
+#define justify_width 16
+#define justify_height 16
+static unsigned char justify_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xdb, 0x00, 0x00, 0x7c, 0xdb,
+   0x00, 0x00, 0xbc, 0xf7, 0x00, 0x00, 0xdc, 0xde, 0x00, 0x00, 0x6c, 0xdf,
+   0x00, 0x00, 0x6c, 0xef, 0x00, 0x00, 0xdc, 0xdf};


Property changes on: vendor/Python/current/Demo/tix/bitmaps/justify.xbm
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tix/bitmaps/leftj.xbm
===================================================================
--- vendor/Python/current/Demo/tix/bitmaps/leftj.xbm	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tix/bitmaps/leftj.xbm	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,6 @@
+#define leftj_width 16
+#define leftj_height 16
+static unsigned char leftj_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x6d, 0x00, 0x00, 0xdc, 0x01,
+   0x00, 0x00, 0xec, 0x0e, 0x00, 0x00, 0xfc, 0x7e, 0x00, 0x00, 0xdc, 0x03,
+   0x00, 0x00, 0x6c, 0x3b, 0x00, 0x00, 0x6c, 0x1f};


Property changes on: vendor/Python/current/Demo/tix/bitmaps/leftj.xbm
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tix/bitmaps/netw.xbm
===================================================================
--- vendor/Python/current/Demo/tix/bitmaps/netw.xbm	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tix/bitmaps/netw.xbm	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,14 @@
+#define netw_width 32
+#define netw_height 32
+static unsigned char netw_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x7f, 0x00, 0x00, 0x02, 0x40,
+   0x00, 0x00, 0xfa, 0x5f, 0x00, 0x00, 0x0a, 0x50, 0x00, 0x00, 0x0a, 0x52,
+   0x00, 0x00, 0x0a, 0x52, 0x00, 0x00, 0x8a, 0x51, 0x00, 0x00, 0x0a, 0x50,
+   0x00, 0x00, 0x4a, 0x50, 0x00, 0x00, 0x0a, 0x50, 0x00, 0x00, 0x0a, 0x50,
+   0x00, 0x00, 0xfa, 0x5f, 0x00, 0x00, 0x02, 0x40, 0xfe, 0x7f, 0x52, 0x55,
+   0x02, 0x40, 0xaa, 0x6a, 0xfa, 0x5f, 0xfe, 0x7f, 0x0a, 0x50, 0xfe, 0x7f,
+   0x0a, 0x52, 0x80, 0x00, 0x0a, 0x52, 0x80, 0x00, 0x8a, 0x51, 0x80, 0x00,
+   0x0a, 0x50, 0x80, 0x00, 0x4a, 0x50, 0x80, 0x00, 0x0a, 0x50, 0xe0, 0x03,
+   0x0a, 0x50, 0x20, 0x02, 0xfa, 0xdf, 0x3f, 0x03, 0x02, 0x40, 0xa0, 0x02,
+   0x52, 0x55, 0xe0, 0x03, 0xaa, 0x6a, 0x00, 0x00, 0xfe, 0x7f, 0x00, 0x00,
+   0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};


Property changes on: vendor/Python/current/Demo/tix/bitmaps/netw.xbm
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tix/bitmaps/netw.xpm
===================================================================
--- vendor/Python/current/Demo/tix/bitmaps/netw.xpm	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tix/bitmaps/netw.xpm	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,45 @@
+/* XPM */
+static char * netw_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"32 32 7 1",
+/* colors */
+" 	s None	c None",
+".	c #000000000000",
+"X	c white",
+"o	c #c000c000c000",
+"O	c #404040",
+"+	c blue",
+"@	c red",
+/* pixels */
+"                                ",
+"                 .............. ",
+"                 .XXXXXXXXXXXX. ",
+"                 .XooooooooooO. ",
+"                 .Xo.......XoO. ",
+"                 .Xo.++++o+XoO. ",
+"                 .Xo.++++o+XoO. ",
+"                 .Xo.++oo++XoO. ",
+"                 .Xo.++++++XoO. ",
+"                 .Xo.+o++++XoO. ",
+"                 .Xo.++++++XoO. ",
+"                 .Xo.XXXXXXXoO. ",
+"                 .XooooooooooO. ",
+"                 .Xo at ooo....oO. ",
+" ..............  .XooooooooooO. ",
+" .XXXXXXXXXXXX.  .XooooooooooO. ",
+" .XooooooooooO.  .OOOOOOOOOOOO. ",
+" .Xo.......XoO.  .............. ",
+" .Xo.++++o+XoO.        @        ",
+" .Xo.++++o+XoO.        @        ",
+" .Xo.++oo++XoO.        @        ",
+" .Xo.++++++XoO.        @        ",
+" .Xo.+o++++XoO.        @        ",
+" .Xo.++++++XoO.      .....      ",
+" .Xo.XXXXXXXoO.      .XXX.      ",
+" .XooooooooooO.@@@@@@.X O.      ",
+" .Xo at ooo....oO.      .OOO.      ",
+" .XooooooooooO.      .....      ",
+" .XooooooooooO.                 ",
+" .OOOOOOOOOOOO.                 ",
+" ..............                 ",
+"                                "};


Property changes on: vendor/Python/current/Demo/tix/bitmaps/netw.xpm
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tix/bitmaps/optmenu.xpm
===================================================================
--- vendor/Python/current/Demo/tix/bitmaps/optmenu.xpm	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tix/bitmaps/optmenu.xpm	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,48 @@
+/* XPM */
+static char * optmenu_xpm[] = {
+"50 40 5 1",
+" 	s None	c None",
+".	c white",
+"X	c gray80",
+"o	c gray50",
+"O	c black",
+"                                                  ",
+"                                                  ",
+"   ..............................                 ",
+"   .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo                 ",
+"   .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo                 ",
+"   .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo                 ",
+"   .XXXOXOXXOXXOXXXXOOXXXXXXXXXXo                 ",
+"   .XXXOXOXXOXOXXXOXXOXXXXXXXXXXo                 ",
+"   .XXXXOXXOXXOXXXOXXXOXXXXXXXXXo                 ",
+"   .XXXXOXXXOXXOOXXOXOXXXXXXXXXXo                 ",
+"   .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo                 ",
+"   .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo.............o   ",
+"   .............................o             o   ",
+"   ..XXXOXXXXXOXXXXXXXXOXXXXXXXOo             o   ",
+"   ..XXOXOXOXXOXOXXXOXXOXXXXXXXOo     ......  o   ",
+"   ..XXXOXXXOXXOXXXOXXXOXXXXXXXOo     .    o  o   ",
+"   ..XXOXXXOXXXOXOXXOXXOXXXXXXXOo     .    o  o   ",
+"   ..XXXXXXXXXXXXXXXXXXXXXXXXXXOo     .ooooo  o   ",
+"   .OOOOOOOOOOOOOOOOOOOOOOOOOOOOo             o   ",
+"   .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo             o   ",
+"   .XXXXXXXXXXXXXXXXXXXXXXXXXXXXooooooooooooooo   ",
+"   .XXXXOXXXXXOXXXXXXXXXXXXXXXXXo                 ",
+"   .XXXOXXXXXXXXXOXXXXXXXXXXXXXXo                 ",
+"   .XXXXOXXOXXOXOXOXXXXXXXXXXXXXo                 ",
+"   .XXXXXOXXOXOXXXXXXXXXXXXXXXXXo                 ",
+"   .XXXXXXXXXXXXXOXXXXXXXXXXXXXXo                 ",
+"   .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo                 ",
+"   .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo                 ",
+"   .XXXOXOXXXXXXXOXOXXXXXOXXXXXXo                 ",
+"   .XXXXXOXOXOXXOXXXXXOXXOXXXXXXo                 ",
+"   .XXXXOXXOXOXOXXXOXOXOXXOXXXXXo                 ",
+"   .XXXOXXXXOXXOXXXOXXOXXXXOXXXXo                 ",
+"   .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo                 ",
+"   .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo                 ",
+"   .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo                 ",
+"   oooooooooooooooooooooooooooooo                 ",
+"                                                  ",
+"                                                  ",
+"                                                  ",
+"                                                  "};


Property changes on: vendor/Python/current/Demo/tix/bitmaps/optmenu.xpm
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tix/bitmaps/rightj.xbm
===================================================================
--- vendor/Python/current/Demo/tix/bitmaps/rightj.xbm	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tix/bitmaps/rightj.xbm	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,6 @@
+#define rightj_width 16
+#define rightj_height 16
+static unsigned char rightj_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xdb, 0x00, 0x00, 0x70, 0xdb,
+   0x00, 0x00, 0x00, 0xef, 0x00, 0x00, 0xd8, 0xde, 0x00, 0x00, 0xc0, 0xdd,
+   0x00, 0x00, 0xa0, 0xef, 0x00, 0x00, 0xd8, 0xde};


Property changes on: vendor/Python/current/Demo/tix/bitmaps/rightj.xbm
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tix/bitmaps/select.xpm
===================================================================
--- vendor/Python/current/Demo/tix/bitmaps/select.xpm	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tix/bitmaps/select.xpm	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,52 @@
+/* XPM */
+static char * select_xpm[] = {
+"50 40 9 1",
+" 	s None	c None",
+".	c black",
+"X	c gray95",
+"o	c gray50",
+"O	c gray70",
+"+	c navy",
+"@	c #000080800000",
+"#	c #808000000000",
+"$	c white",
+"                                                  ",
+"                                                  ",
+"                                                  ",
+"                                                  ",
+"                                                  ",
+"                                                  ",
+"                                                  ",
+"                                                  ",
+"                                                  ",
+"  ..............................................  ",
+"  .XXXXXXXXXXooooooooooooXXXXXXXXXXXoXXXXXXXXXX.  ",
+"  .X         ooOOOOOOOOOOXX         oX        o.  ",
+"  .X         ooOOOOOOOOOOXX         oX        o.  ",
+"  .X   ++++  ooOOOOOOOOOOXX  ...    oX  @     o.  ",
+"  .X  +++++  ooOOOOOOOOOOXX .   .   oX  @@@   o.  ",
+"  .X +++   + ooOOOOOOOOOOXX .    .  oX @  @   o.  ",
+"  .X +     + ooOO#####OOOXX .    .  oX @  @   o.  ",
+"  .X +     + ooOO#OOO##OOXX .       oX @   @  o.  ",
+"  .X +     + ooO##OOOO##OXX .       oX @    @ o.  ",
+"  .X ++   ++ ooO###OOO#OOXX .       oX @    @ o.  ",
+"  .X +++++++ ooO#######OOXX .       oX @    @ o.  ",
+"  .X +     + ooO##O#OO#OOXX .       oX @    @ o.  ",
+"  .X +    ++ ooO##OOOOO#OXX .    .  oX @    @ o.  ",
+"  .X +     + ooOO#OOOOO#OXX .    .  oX @   @@ o.  ",
+"  .X +    ++ ooOO#OOOOO#OXX  ....   oX @@@@@  o.  ",
+"  .X         ooOO######OOXX         oX        o.  ",
+"  .X         ooOOOOOOOOOOXX        $oX        o.  ",
+"  .XoooooooooooXXXXXXXXXXXoooooooooooXooooooooo.  ",
+"  ..............................................  ",
+"                                                  ",
+"                                                  ",
+"                                                  ",
+"                                                  ",
+"                                                  ",
+"                                                  ",
+"                                                  ",
+"                                                  ",
+"                                                  ",
+"                                                  ",
+"                                                  "};


Property changes on: vendor/Python/current/Demo/tix/bitmaps/select.xpm
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tix/bitmaps/tix.gif
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Demo/tix/bitmaps/tix.gif
___________________________________________________________________
Name: svn:executable
   + 
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Demo/tix/bitmaps/underline.xbm
===================================================================
--- vendor/Python/current/Demo/tix/bitmaps/underline.xbm	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tix/bitmaps/underline.xbm	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,6 @@
+#define underline_width 16
+#define underline_height 16
+static unsigned char underline_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x1c, 0x38, 0x1c,
+   0x30, 0x0c, 0x30, 0x0c, 0x30, 0x0c, 0x30, 0x0c, 0x30, 0x0c, 0x70, 0x0e,
+   0xf0, 0x0f, 0xe0, 0x07, 0x00, 0x00, 0xf8, 0x1f};


Property changes on: vendor/Python/current/Demo/tix/bitmaps/underline.xbm
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tix/grid.py
===================================================================
--- vendor/Python/current/Demo/tix/grid.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tix/grid.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,28 @@
+###
+import Tix as tk
+from pprint import pprint
+
+r= tk.Tk()
+r.title("test")
+
+l=tk.Label(r, name="a_label")
+l.pack()
+
+class MyGrid(tk.Grid):
+    def __init__(self, *args, **kwargs):
+        kwargs['editnotify']= self.editnotify
+        tk.Grid.__init__(self, *args, **kwargs)
+    def editnotify(self, x, y):
+        return True
+
+g = MyGrid(r, name="a_grid",
+selectunit="cell")
+g.pack(fill=tk.BOTH)
+for x in xrange(5):
+    for y in xrange(5):
+        g.set(x,y,text=str((x,y)))
+
+c = tk.Button(r, text="Close", command=r.destroy)
+c.pack()
+
+tk.mainloop()

Added: vendor/Python/current/Demo/tix/samples/Balloon.py
===================================================================
--- vendor/Python/current/Demo/tix/samples/Balloon.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tix/samples/Balloon.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,68 @@
+# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
+#
+# $Id: Balloon.py 36560 2004-07-18 06:16:08Z tim_one $
+#
+# Tix Demostration Program
+#
+# This sample program is structured in such a way so that it can be
+# executed from the Tix demo program "tixwidgets.py": it must have a
+# procedure called "RunSample". It should also have the "if" statment
+# at the end of this file so that it can be run as a standalone
+# program.
+
+# This file demonstrates the use of the tixBalloon widget, which provides
+# a interesting way to give help tips about elements in your user interface.
+# Your can display the help message in a "balloon" and a status bar widget.
+#
+
+import Tix
+
+TCL_ALL_EVENTS          = 0
+
+def RunSample (root):
+    balloon = DemoBalloon(root)
+    balloon.mainloop()
+    balloon.destroy()
+
+class DemoBalloon:
+    def __init__(self, w):
+        self.root = w
+        self.exit = -1
+
+        z = w.winfo_toplevel()
+        z.wm_protocol("WM_DELETE_WINDOW", lambda self=self: self.quitcmd())
+
+        status = Tix.Label(w, width=40, relief=Tix.SUNKEN, bd=1)
+        status.pack(side=Tix.BOTTOM, fill=Tix.Y, padx=2, pady=1)
+
+        # Create two mysterious widgets that need balloon help
+        button1 = Tix.Button(w, text='Something Unexpected',
+                             command=self.quitcmd)
+        button2 = Tix.Button(w, text='Something Else Unexpected')
+        button2['command'] = lambda w=button2: w.destroy()
+        button1.pack(side=Tix.TOP, expand=1)
+        button2.pack(side=Tix.TOP, expand=1)
+
+        # Create the balloon widget and associate it with the widgets that we want
+        # to provide tips for:
+        b = Tix.Balloon(w, statusbar=status)
+
+        b.bind_widget(button1, balloonmsg='Close Window',
+                      statusmsg='Press this button to close this window')
+        b.bind_widget(button2, balloonmsg='Self-destruct button',
+                      statusmsg='Press this button and it will destroy itself')
+
+    def quitcmd (self):
+        self.exit = 0
+
+    def mainloop(self):
+        foundEvent = 1
+        while self.exit < 0 and foundEvent > 0:
+            foundEvent = self.root.tk.dooneevent(TCL_ALL_EVENTS)
+
+    def destroy (self):
+        self.root.destroy()
+
+if __name__ == '__main__':
+    root = Tix.Tk()
+    RunSample(root)


Property changes on: vendor/Python/current/Demo/tix/samples/Balloon.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tix/samples/BtnBox.py
===================================================================
--- vendor/Python/current/Demo/tix/samples/BtnBox.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tix/samples/BtnBox.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,44 @@
+# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
+#
+# $Id: BtnBox.py 36560 2004-07-18 06:16:08Z tim_one $
+#
+# Tix Demostration Program
+#
+# This sample program is structured in such a way so that it can be
+# executed from the Tix demo program "tixwidgets.py": it must have a
+# procedure called "RunSample". It should also have the "if" statment
+# at the end of this file so that it can be run as a standalone
+# program.
+
+# This file demonstrates the use of the tixButtonBox widget, which is a
+# group of TK buttons. You can use it to manage the buttons in a dialog box,
+# for example.
+#
+
+import Tix
+
+def RunSample(w):
+    # Create the label on the top of the dialog box
+    #
+    top = Tix.Label(w, padx=20, pady=10, bd=1, relief=Tix.RAISED,
+                    anchor=Tix.CENTER, text='This dialog box is\n a demonstration of the\n tixButtonBox widget')
+
+    # Create the button box and add a few buttons in it. Set the
+    # -width of all the buttons to the same value so that they
+    # appear in the same size.
+    #
+    # Note that the -text, -underline, -command and -width options are all
+    # standard options of the button widgets.
+    #
+    box = Tix.ButtonBox(w, orientation=Tix.HORIZONTAL)
+    box.add('ok', text='OK', underline=0, width=5,
+            command=lambda w=w: w.destroy())
+    box.add('close', text='Cancel', underline=0, width=5,
+            command=lambda w=w: w.destroy())
+    box.pack(side=Tix.BOTTOM, fill=Tix.X)
+    top.pack(side=Tix.TOP, fill=Tix.BOTH, expand=1)
+
+if __name__ == '__main__':
+    root = Tix.Tk()
+    RunSample(root)
+    root.mainloop()


Property changes on: vendor/Python/current/Demo/tix/samples/BtnBox.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tix/samples/CmpImg.py
===================================================================
--- vendor/Python/current/Demo/tix/samples/CmpImg.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tix/samples/CmpImg.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,196 @@
+# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
+#
+# $Id: CmpImg.py 36560 2004-07-18 06:16:08Z tim_one $
+#
+# Tix Demostration Program
+#
+# This sample program is structured in such a way so that it can be
+# executed from the Tix demo program "tixwidgets.py": it must have a
+# procedure called "RunSample". It should also have the "if" statment
+# at the end of this file so that it can be run as a standalone
+# program.
+
+# This file demonstrates the use of the compound images: it uses compound
+# images to display a text string together with a pixmap inside
+# buttons
+#
+
+import Tix
+
+network_pixmap = """/* XPM */
+static char * netw_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"32 32 7 1",
+/* colors */
+"       s None  c None",
+".      c #000000000000",
+"X      c white",
+"o      c #c000c000c000",
+"O      c #404040",
+"+      c blue",
+"@      c red",
+/* pixels */
+"                                ",
+"                 .............. ",
+"                 .XXXXXXXXXXXX. ",
+"                 .XooooooooooO. ",
+"                 .Xo.......XoO. ",
+"                 .Xo.++++o+XoO. ",
+"                 .Xo.++++o+XoO. ",
+"                 .Xo.++oo++XoO. ",
+"                 .Xo.++++++XoO. ",
+"                 .Xo.+o++++XoO. ",
+"                 .Xo.++++++XoO. ",
+"                 .Xo.XXXXXXXoO. ",
+"                 .XooooooooooO. ",
+"                 .Xo at ooo....oO. ",
+" ..............  .XooooooooooO. ",
+" .XXXXXXXXXXXX.  .XooooooooooO. ",
+" .XooooooooooO.  .OOOOOOOOOOOO. ",
+" .Xo.......XoO.  .............. ",
+" .Xo.++++o+XoO.        @        ",
+" .Xo.++++o+XoO.        @        ",
+" .Xo.++oo++XoO.        @        ",
+" .Xo.++++++XoO.        @        ",
+" .Xo.+o++++XoO.        @        ",
+" .Xo.++++++XoO.      .....      ",
+" .Xo.XXXXXXXoO.      .XXX.      ",
+" .XooooooooooO.@@@@@@.X O.      ",
+" .Xo at ooo....oO.      .OOO.      ",
+" .XooooooooooO.      .....      ",
+" .XooooooooooO.                 ",
+" .OOOOOOOOOOOO.                 ",
+" ..............                 ",
+"                                "};
+"""
+
+hard_disk_pixmap = """/* XPM */
+static char * drivea_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"32 32 5 1",
+/* colors */
+"       s None  c None",
+".      c #000000000000",
+"X      c white",
+"o      c #c000c000c000",
+"O      c #800080008000",
+/* pixels */
+"                                ",
+"                                ",
+"                                ",
+"                                ",
+"                                ",
+"                                ",
+"                                ",
+"                                ",
+"                                ",
+"   ..........................   ",
+"   .XXXXXXXXXXXXXXXXXXXXXXXo.   ",
+"   .XooooooooooooooooooooooO.   ",
+"   .Xooooooooooooooooo..oooO.   ",
+"   .Xooooooooooooooooo..oooO.   ",
+"   .XooooooooooooooooooooooO.   ",
+"   .Xoooooooo.......oooooooO.   ",
+"   .Xoo...................oO.   ",
+"   .Xoooooooo.......oooooooO.   ",
+"   .XooooooooooooooooooooooO.   ",
+"   .XooooooooooooooooooooooO.   ",
+"   .XooooooooooooooooooooooO.   ",
+"   .XooooooooooooooooooooooO.   ",
+"   .oOOOOOOOOOOOOOOOOOOOOOOO.   ",
+"   ..........................   ",
+"                                ",
+"                                ",
+"                                ",
+"                                ",
+"                                ",
+"                                ",
+"                                ",
+"                                "};
+"""
+
+network_bitmap = """
+#define netw_width 32
+#define netw_height 32
+static unsigned char netw_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x7f, 0x00, 0x00, 0x02, 0x40,
+   0x00, 0x00, 0xfa, 0x5f, 0x00, 0x00, 0x0a, 0x50, 0x00, 0x00, 0x0a, 0x52,
+   0x00, 0x00, 0x0a, 0x52, 0x00, 0x00, 0x8a, 0x51, 0x00, 0x00, 0x0a, 0x50,
+   0x00, 0x00, 0x4a, 0x50, 0x00, 0x00, 0x0a, 0x50, 0x00, 0x00, 0x0a, 0x50,
+   0x00, 0x00, 0xfa, 0x5f, 0x00, 0x00, 0x02, 0x40, 0xfe, 0x7f, 0x52, 0x55,
+   0x02, 0x40, 0xaa, 0x6a, 0xfa, 0x5f, 0xfe, 0x7f, 0x0a, 0x50, 0xfe, 0x7f,
+   0x0a, 0x52, 0x80, 0x00, 0x0a, 0x52, 0x80, 0x00, 0x8a, 0x51, 0x80, 0x00,
+   0x0a, 0x50, 0x80, 0x00, 0x4a, 0x50, 0x80, 0x00, 0x0a, 0x50, 0xe0, 0x03,
+   0x0a, 0x50, 0x20, 0x02, 0xfa, 0xdf, 0x3f, 0x03, 0x02, 0x40, 0xa0, 0x02,
+   0x52, 0x55, 0xe0, 0x03, 0xaa, 0x6a, 0x00, 0x00, 0xfe, 0x7f, 0x00, 0x00,
+   0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+"""
+
+hard_disk_bitmap = """
+#define drivea_width 32
+#define drivea_height 32
+static unsigned char drivea_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0xf8, 0xff, 0xff, 0x1f, 0x08, 0x00, 0x00, 0x18, 0xa8, 0xaa, 0xaa, 0x1a,
+   0x48, 0x55, 0xd5, 0x1d, 0xa8, 0xaa, 0xaa, 0x1b, 0x48, 0x55, 0x55, 0x1d,
+   0xa8, 0xfa, 0xaf, 0x1a, 0xc8, 0xff, 0xff, 0x1d, 0xa8, 0xfa, 0xaf, 0x1a,
+   0x48, 0x55, 0x55, 0x1d, 0xa8, 0xaa, 0xaa, 0x1a, 0x48, 0x55, 0x55, 0x1d,
+   0xa8, 0xaa, 0xaa, 0x1a, 0xf8, 0xff, 0xff, 0x1f, 0xf8, 0xff, 0xff, 0x1f,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+"""
+
+def RunSample(w):
+    w.img0 = Tix.Image('pixmap', data=network_pixmap)
+    if not w.img0:
+        w.img0 = Tix.Image('bitmap', data=network_bitmap)
+    w.img1 = Tix.Image('pixmap', data=hard_disk_pixmap)
+    if not w.img0:
+        w.img1 = Tix.Image('bitmap', data=hard_disk_bitmap)
+
+    hdd = Tix.Button(w, padx=4, pady=1, width=120)
+    net = Tix.Button(w, padx=4, pady=1, width=120)
+
+    # Create the first image: we create a line, then put a string,
+    # a space and a image into this line, from left to right.
+    # The result: we have a one-line image that consists of three
+    # individual items
+    #
+    # The tk.calls should be methods in Tix ...
+    w.hdd_img = Tix.Image('compound', window=hdd)
+    w.hdd_img.tk.call(str(w.hdd_img), 'add', 'line')
+    w.hdd_img.tk.call(str(w.hdd_img), 'add', 'text', '-text', 'Hard Disk',
+                    '-underline', '0')
+    w.hdd_img.tk.call(str(w.hdd_img), 'add', 'space', '-width', '7')
+    w.hdd_img.tk.call(str(w.hdd_img), 'add', 'image', '-image', w.img1)
+
+    # Put this image into the first button
+    #
+    hdd['image'] = w.hdd_img
+
+    # Next button
+    w.net_img = Tix.Image('compound', window=net)
+    w.net_img.tk.call(str(w.net_img), 'add', 'line')
+    w.net_img.tk.call(str(w.net_img), 'add', 'text', '-text', 'Network',
+                    '-underline', '0')
+    w.net_img.tk.call(str(w.net_img), 'add', 'space', '-width', '7')
+    w.net_img.tk.call(str(w.net_img), 'add', 'image', '-image', w.img0)
+
+    # Put this image into the first button
+    #
+    net['image'] = w.net_img
+
+    close = Tix.Button(w, pady=1, text='Close',
+                       command=lambda w=w: w.destroy())
+
+    hdd.pack(side=Tix.LEFT, padx=10, pady=10, fill=Tix.Y, expand=1)
+    net.pack(side=Tix.LEFT, padx=10, pady=10, fill=Tix.Y, expand=1)
+    close.pack(side=Tix.LEFT, padx=10, pady=10, fill=Tix.Y, expand=1)
+
+if __name__ == '__main__':
+    root = Tix.Tk()
+    RunSample(root)
+    root.mainloop()


Property changes on: vendor/Python/current/Demo/tix/samples/CmpImg.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tix/samples/ComboBox.py
===================================================================
--- vendor/Python/current/Demo/tix/samples/ComboBox.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tix/samples/ComboBox.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,102 @@
+# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
+#
+# $Id: ComboBox.py 36560 2004-07-18 06:16:08Z tim_one $
+#
+# Tix Demostration Program
+#
+# This sample program is structured in such a way so that it can be
+# executed from the Tix demo program "tixwidgets.py": it must have a
+# procedure called "RunSample". It should also have the "if" statment
+# at the end of this file so that it can be run as a standalone
+# program.
+
+# This file demonstrates the use of the tixComboBox widget, which is close
+# to the MS Window Combo Box control.
+#
+import Tix
+
+def RunSample(w):
+    global demo_month, demo_year
+
+    top = Tix.Frame(w, bd=1, relief=Tix.RAISED)
+
+    demo_month = Tix.StringVar()
+    demo_year = Tix.StringVar()
+
+    # $w.top.a is a drop-down combo box. It is not editable -- who wants
+    # to invent new months?
+    #
+    # [Hint] The -options switch sets the options of the subwidgets.
+    # [Hint] We set the label.width subwidget option of both comboboxes to
+    #        be 10 so that their labels appear to be aligned.
+    #
+    a = Tix.ComboBox(top, label="Month: ", dropdown=1,
+        command=select_month, editable=0, variable=demo_month,
+        options='listbox.height 6 label.width 10 label.anchor e')
+
+    # $w.top.b is a non-drop-down combo box. It is not editable: we provide
+    # four choices for the user, but he can enter an alternative year if he
+    # wants to.
+    #
+    # [Hint] Use the padY and anchor options of the label subwidget to
+    #        align the label with the entry subwidget.
+    # [Hint] Notice that you should use padY (the NAME of the option) and not
+    #        pady (the SWITCH of the option).
+    #
+    b = Tix.ComboBox(top, label="Year: ", dropdown=0,
+        command=select_year, editable=1, variable=demo_year,
+        options='listbox.height 4 label.padY 5 label.width 10 label.anchor ne')
+
+    a.pack(side=Tix.TOP, anchor=Tix.W)
+    b.pack(side=Tix.TOP, anchor=Tix.W)
+
+    a.insert(Tix.END, 'January')
+    a.insert(Tix.END, 'February')
+    a.insert(Tix.END, 'March')
+    a.insert(Tix.END, 'April')
+    a.insert(Tix.END, 'May')
+    a.insert(Tix.END, 'June')
+    a.insert(Tix.END, 'July')
+    a.insert(Tix.END, 'August')
+    a.insert(Tix.END, 'September')
+    a.insert(Tix.END, 'October')
+    a.insert(Tix.END, 'November')
+    a.insert(Tix.END, 'December')
+
+    b.insert(Tix.END, '1992')
+    b.insert(Tix.END, '1993')
+    b.insert(Tix.END, '1994')
+    b.insert(Tix.END, '1995')
+    b.insert(Tix.END, '1996')
+
+    # Use "tixSetSilent" to set the values of the combo box if you
+    # don't want your -command procedures (cbx:select_month and
+    # cbx:select_year) to be called.
+    #
+    a.set_silent('January')
+    b.set_silent('1995')
+
+    box = Tix.ButtonBox(w, orientation=Tix.HORIZONTAL)
+    box.add('ok', text='Ok', underline=0, width=6,
+            command=lambda w=w: ok_command(w))
+    box.add('cancel', text='Cancel', underline=0, width=6,
+            command=lambda w=w: w.destroy())
+    box.pack(side=Tix.BOTTOM, fill=Tix.X)
+    top.pack(side=Tix.TOP, fill=Tix.BOTH, expand=1)
+
+def select_month(event=None):
+    # tixDemo:Status "Month = %s" % demo_month.get()
+    pass
+
+def select_year(event=None):
+    # tixDemo:Status "Year = %s" % demo_year.get()
+    pass
+
+def ok_command(w):
+    # tixDemo:Status "Month = %s, Year= %s" % (demo_month.get(), demo_year.get())
+    w.destroy()
+
+if __name__ == '__main__':
+    root = Tix.Tk()
+    RunSample(root)
+    root.mainloop()


Property changes on: vendor/Python/current/Demo/tix/samples/ComboBox.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tix/samples/Control.py
===================================================================
--- vendor/Python/current/Demo/tix/samples/Control.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tix/samples/Control.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,122 @@
+# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
+#
+# $Id: Control.py 36560 2004-07-18 06:16:08Z tim_one $
+#
+# Tix Demostration Program
+#
+# This sample program is structured in such a way so that it can be
+# executed from the Tix demo program "tixwidgets.py": it must have a
+# procedure called "RunSample". It should also have the "if" statment
+# at the end of this file so that it can be run as a standalone
+# program.
+
+# This file demonstrates the use of the tixControl widget -- it is an
+# entry widget with up/down arrow buttons. You can use the arrow buttons
+# to adjust the value inside the entry widget.
+#
+# This example program uses three Control widgets. One lets you select
+# integer values; one lets you select floating point values and the last
+# one lets you select a few names.
+
+import Tix
+
+TCL_ALL_EVENTS          = 0
+
+def RunSample (root):
+    control = DemoControl(root)
+    control.mainloop()
+    control.destroy()
+
+class DemoControl:
+    def __init__(self, w):
+        self.root = w
+        self.exit = -1
+
+        global demo_maker, demo_thrust, demo_num_engines
+
+        demo_maker = Tix.StringVar()
+        demo_thrust = Tix.DoubleVar()
+        demo_num_engines = Tix.IntVar()
+        demo_maker.set('P&W')
+        demo_thrust.set(20000.0)
+        demo_num_engines.set(2)
+
+        top = Tix.Frame(w, bd=1, relief=Tix.RAISED)
+
+        # $w.top.a allows only integer values
+        #
+        # [Hint] The -options switch sets the options of the subwidgets.
+        # [Hint] We set the label.width subwidget option of the Controls to
+        #        be 16 so that their labels appear to be aligned.
+        #
+        a = Tix.Control(top, label='Number of Engines: ', integer=1,
+                        variable=demo_num_engines, min=1, max=4,
+                        options='entry.width 10 label.width 20 label.anchor e')
+
+        b = Tix.Control(top, label='Thrust: ', integer=0,
+                        min='10000.0', max='60000.0', step=500,
+                        variable=demo_thrust,
+                        options='entry.width 10 label.width 20 label.anchor e')
+
+        c = Tix.Control(top, label='Engine Maker: ', value='P&W',
+                        variable=demo_maker,
+                        options='entry.width 10 label.width 20 label.anchor e')
+
+        # We can't define these in the init because the widget 'c' doesn't
+        # exist yet and we need to reference it
+        c['incrcmd'] = lambda w=c: adjust_maker(w, 1)
+        c['decrcmd'] = lambda w=c: adjust_maker(w, -1)
+        c['validatecmd'] = lambda w=c: validate_maker(w)
+
+        a.pack(side=Tix.TOP, anchor=Tix.W)
+        b.pack(side=Tix.TOP, anchor=Tix.W)
+        c.pack(side=Tix.TOP, anchor=Tix.W)
+
+        box = Tix.ButtonBox(w, orientation=Tix.HORIZONTAL)
+        box.add('ok', text='Ok', underline=0, width=6,
+                command=self.okcmd)
+        box.add('cancel', text='Cancel', underline=0, width=6,
+                command=self.quitcmd)
+        box.pack(side=Tix.BOTTOM, fill=Tix.X)
+        top.pack(side=Tix.TOP, fill=Tix.BOTH, expand=1)
+
+    def okcmd (self):
+        # tixDemo:Status "Selected %d of %s engines each of thrust %d", (demo_num_engines.get(), demo_maker.get(), demo_thrust.get())
+        self.quitcmd()
+
+    def quitcmd (self):
+        self.exit = 0
+
+    def mainloop(self):
+        while self.exit < 0:
+            self.root.tk.dooneevent(TCL_ALL_EVENTS)
+
+    def destroy (self):
+        self.root.destroy()
+
+maker_list = ['P&W', 'GE', 'Rolls Royce']
+
+def adjust_maker(w, inc):
+    i = maker_list.index(demo_maker.get())
+    i = i + inc
+    if i >= len(maker_list):
+        i = 0
+    elif i < 0:
+        i = len(maker_list) - 1
+
+    # In Tcl/Tix we should return the string maker_list[i]. We can't
+    # do that in Tkinter so we set the global variable. (This works).
+    demo_maker.set(maker_list[i])
+
+def validate_maker(w):
+    try:
+        i = maker_list.index(demo_maker.get())
+    except ValueError:
+        # Works here though. Why ? Beats me.
+        return maker_list[0]
+    # Works here though. Why ? Beats me.
+    return maker_list[i]
+
+if __name__ == '__main__':
+    root = Tix.Tk()
+    RunSample(root)


Property changes on: vendor/Python/current/Demo/tix/samples/Control.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tix/samples/DirList.py
===================================================================
--- vendor/Python/current/Demo/tix/samples/DirList.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tix/samples/DirList.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,131 @@
+# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
+#
+#       $Id: DirList.py 36560 2004-07-18 06:16:08Z tim_one $
+#
+# Tix Demostration Program
+#
+# This sample program is structured in such a way so that it can be
+# executed from the Tix demo program "tixwidgets.py":  it must have a
+# procedure called "RunSample". It should also have the "if" statment
+# at the end of this file so that it can be run as a standalone
+# program using tixwish.
+
+# This file demonstrates the use of the tixDirList widget -- you can
+# use it for the user to select a directory. For example, an installation
+# program can use the tixDirList widget to ask the user to select the
+# installation directory for an application.
+#
+
+import Tix, os, copy
+from Tkconstants import *
+
+TCL_ALL_EVENTS          = 0
+
+def RunSample (root):
+    dirlist = DemoDirList(root)
+    dirlist.mainloop()
+    dirlist.destroy()
+
+class DemoDirList:
+    def __init__(self, w):
+        self.root = w
+        self.exit = -1
+
+        z = w.winfo_toplevel()
+        z.wm_protocol("WM_DELETE_WINDOW", lambda self=self: self.quitcmd())
+
+        # Create the tixDirList and the tixLabelEntry widgets on the on the top
+        # of the dialog box
+
+        # bg = root.tk.eval('tix option get bg')
+        # adding bg=bg crashes Windows pythonw tk8.3.3 Python 2.1.0
+
+        top = Tix.Frame( w, relief=RAISED, bd=1)
+
+        # Create the DirList widget. By default it will show the current
+        # directory
+        #
+        #
+        top.dir = Tix.DirList(top)
+        top.dir.hlist['width'] = 40
+
+        # When the user presses the ".." button, the selected directory
+        # is "transferred" into the entry widget
+        #
+        top.btn = Tix.Button(top, text = "  >>  ", pady = 0)
+
+        # We use a LabelEntry to hold the installation directory. The user
+        # can choose from the DirList widget, or he can type in the directory
+        # manually
+        #
+        top.ent = Tix.LabelEntry(top, label="Installation Directory:",
+                                  labelside = 'top',
+                                  options = '''
+                                  entry.width 40
+                                  label.anchor w
+                                  ''')
+
+        font = self.root.tk.eval('tix option get fixed_font')
+        # font = self.root.master.tix_option_get('fixed_font')
+        top.ent.entry['font'] = font
+
+        self.dlist_dir = copy.copy(os.curdir)
+        # This should work setting the entry's textvariable
+        top.ent.entry['textvariable'] = self.dlist_dir
+        top.btn['command'] = lambda dir=top.dir, ent=top.ent, self=self: \
+                             self.copy_name(dir,ent)
+
+        # top.ent.entry.insert(0,'tix'+repr(self))
+        top.ent.entry.bind('<Return>', lambda self=self: self.okcmd () )
+
+        top.pack( expand='yes', fill='both', side=TOP)
+        top.dir.pack( expand=1, fill=BOTH, padx=4, pady=4, side=LEFT)
+        top.btn.pack( anchor='s', padx=4, pady=4, side=LEFT)
+        top.ent.pack( expand=1, fill=X, anchor='s', padx=4, pady=4, side=LEFT)
+
+        # Use a ButtonBox to hold the buttons.
+        #
+        box = Tix.ButtonBox (w, orientation='horizontal')
+        box.add ('ok', text='Ok', underline=0, width=6,
+                     command = lambda self=self: self.okcmd () )
+        box.add ('cancel', text='Cancel', underline=0, width=6,
+                     command = lambda self=self: self.quitcmd () )
+
+        box.pack( anchor='s', fill='x', side=BOTTOM)
+
+    def copy_name (self, dir, ent):
+        # This should work as it is the entry's textvariable
+        self.dlist_dir = dir.cget('value')
+        # but it isn't so I'll do it manually
+        ent.entry.delete(0,'end')
+        ent.entry.insert(0, self.dlist_dir)
+
+    def okcmd (self):
+        # tixDemo:Status "You have selected the directory" + self.dlist_dir
+        self.quitcmd()
+
+    def quitcmd (self):
+        self.exit = 0
+
+    def mainloop(self):
+        while self.exit < 0:
+            self.root.tk.dooneevent(TCL_ALL_EVENTS)
+
+    def destroy (self):
+        self.root.destroy()
+
+# This "if" statement makes it possible to run this script file inside or
+# outside of the main demo program "tixwidgets.py".
+#
+if __name__== '__main__' :
+    import tkMessageBox, traceback
+
+    try:
+        root=Tix.Tk()
+        RunSample(root)
+    except:
+        t, v, tb = sys.exc_info()
+        text = "Error running the demo script:\n"
+        for line in traceback.format_exception(t,v,tb):
+            text = text + line + '\n'
+            d = tkMessageBox.showerror ( 'Tix Demo Error', text)


Property changes on: vendor/Python/current/Demo/tix/samples/DirList.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tix/samples/DirTree.py
===================================================================
--- vendor/Python/current/Demo/tix/samples/DirTree.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tix/samples/DirTree.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,117 @@
+# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
+#
+#       $Id: DirTree.py 36560 2004-07-18 06:16:08Z tim_one $
+#
+# Tix Demostration Program
+#
+# This sample program is structured in such a way so that it can be
+# executed from the Tix demo program "tixwidgets.py":  it must have a
+# procedure called "RunSample". It should also have the "if" statment
+# at the end of this file so that it can be run as a standalone
+# program using tixwish.
+
+# This file demonstrates the use of the tixDirTree widget -- you can
+# use it for the user to select a directory. For example, an installation
+# program can use the tixDirTree widget to ask the user to select the
+# installation directory for an application.
+#
+
+import Tix, os, copy
+from Tkconstants import *
+
+TCL_ALL_EVENTS          = 0
+
+def RunSample (root):
+    dirtree = DemoDirTree(root)
+    dirtree.mainloop()
+    dirtree.destroy()
+
+class DemoDirTree:
+    def __init__(self, w):
+        self.root = w
+        self.exit = -1
+
+        z = w.winfo_toplevel()
+        z.wm_protocol("WM_DELETE_WINDOW", lambda self=self: self.quitcmd())
+
+        # Create the tixDirTree and the tixLabelEntry widgets on the on the top
+        # of the dialog box
+
+        # bg = root.tk.eval('tix option get bg')
+        # adding bg=bg crashes Windows pythonw tk8.3.3 Python 2.1.0
+
+        top = Tix.Frame( w, relief=RAISED, bd=1)
+
+        # Create the DirTree widget. By default it will show the current
+        # directory
+        #
+        #
+        top.dir = Tix.DirTree(top)
+        top.dir.hlist['width'] = 40
+
+        # When the user presses the ".." button, the selected directory
+        # is "transferred" into the entry widget
+        #
+        top.btn = Tix.Button(top, text = "  >>  ", pady = 0)
+
+        # We use a LabelEntry to hold the installation directory. The user
+        # can choose from the DirTree widget, or he can type in the directory
+        # manually
+        #
+        top.ent = Tix.LabelEntry(top, label="Installation Directory:",
+                                  labelside = 'top',
+                                  options = '''
+                                  entry.width 40
+                                  label.anchor w
+                                  ''')
+
+        self.dlist_dir = copy.copy(os.curdir)
+        top.ent.entry['textvariable'] = self.dlist_dir
+        top.btn['command'] = lambda dir=top.dir, ent=top.ent, self=self: \
+                             self.copy_name(dir,ent)
+
+        top.ent.entry.bind('<Return>', lambda self=self: self.okcmd () )
+
+        top.pack( expand='yes', fill='both', side=TOP)
+        top.dir.pack( expand=1, fill=BOTH, padx=4, pady=4, side=LEFT)
+        top.btn.pack( anchor='s', padx=4, pady=4, side=LEFT)
+        top.ent.pack( expand=1, fill=X, anchor='s', padx=4, pady=4, side=LEFT)
+
+        # Use a ButtonBox to hold the buttons.
+        #
+        box = Tix.ButtonBox (w, orientation='horizontal')
+        box.add ('ok', text='Ok', underline=0, width=6,
+                     command = lambda self=self: self.okcmd () )
+        box.add ('cancel', text='Cancel', underline=0, width=6,
+                     command = lambda self=self: self.quitcmd () )
+
+        box.pack( anchor='s', fill='x', side=BOTTOM)
+
+    def copy_name (self, dir, ent):
+        # This should work as it is the entry's textvariable
+        self.dlist_dir = dir.cget('value')
+        # but it isn't so I'll do it manually
+        ent.entry.delete(0,'end')
+        ent.entry.insert(0, self.dlist_dir)
+
+    def okcmd (self):
+        # tixDemo:Status "You have selected the directory" + self.dlist_dir
+        self.quitcmd()
+
+    def quitcmd (self):
+        # tixDemo:Status "You have selected the directory" + self.dlist_dir
+        self.exit = 0
+
+    def mainloop(self):
+        while self.exit < 0:
+            self.root.tk.dooneevent(TCL_ALL_EVENTS)
+
+    def destroy (self):
+        self.root.destroy()
+
+# This "if" statement makes it possible to run this script file inside or
+# outside of the main demo program "tixwidgets.py".
+#
+if __name__== '__main__' :
+    root=Tix.Tk()
+    RunSample(root)


Property changes on: vendor/Python/current/Demo/tix/samples/DirTree.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tix/samples/NoteBook.py
===================================================================
--- vendor/Python/current/Demo/tix/samples/NoteBook.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tix/samples/NoteBook.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,119 @@
+# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
+#
+# $Id: NoteBook.py 36560 2004-07-18 06:16:08Z tim_one $
+#
+# Tix Demostration Program
+#
+# This sample program is structured in such a way so that it can be
+# executed from the Tix demo program "tixwidgets.py": it must have a
+# procedure called "RunSample". It should also have the "if" statment
+# at the end of this file so that it can be run as a standalone
+# program.
+
+# This file demonstrates the use of the tixNoteBook widget, which allows
+# you to lay out your interface using a "notebook" metaphore
+#
+import Tix
+
+def RunSample(w):
+    global root
+    root = w
+
+    # We use these options to set the sizes of the subwidgets inside the
+    # notebook, so that they are well-aligned on the screen.
+    prefix = Tix.OptionName(w)
+    if prefix:
+        prefix = '*'+prefix
+    else:
+        prefix = ''
+    w.option_add(prefix+'*TixControl*entry.width', 10)
+    w.option_add(prefix+'*TixControl*label.width', 18)
+    w.option_add(prefix+'*TixControl*label.anchor', Tix.E)
+    w.option_add(prefix+'*TixNoteBook*tagPadX', 8)
+
+    # Create the notebook widget and set its backpagecolor to gray.
+    # Note that the -backpagecolor option belongs to the "nbframe"
+    # subwidget.
+    nb = Tix.NoteBook(w, name='nb', ipadx=6, ipady=6)
+    nb['bg'] = 'gray'
+    nb.nbframe['backpagecolor'] = 'gray'
+
+    # Create the two tabs on the notebook. The -underline option
+    # puts a underline on the first character of the labels of the tabs.
+    # Keyboard accelerators will be defined automatically according
+    # to the underlined character.
+    nb.add('hard_disk', label="Hard Disk", underline=0)
+    nb.add('network', label="Network", underline=0)
+
+    nb.pack(expand=1, fill=Tix.BOTH, padx=5, pady=5 ,side=Tix.TOP)
+
+    #----------------------------------------
+    # Create the first page
+    #----------------------------------------
+    # Create two frames: one for the common buttons, one for the
+    # other widgets
+    #
+    tab=nb.hard_disk
+    f = Tix.Frame(tab)
+    common = Tix.Frame(tab)
+
+    f.pack(side=Tix.LEFT, padx=2, pady=2, fill=Tix.BOTH, expand=1)
+    common.pack(side=Tix.RIGHT, padx=2, fill=Tix.Y)
+
+    a = Tix.Control(f, value=12,   label='Access time: ')
+    w = Tix.Control(f, value=400,  label='Write Throughput: ')
+    r = Tix.Control(f, value=400,  label='Read Throughput: ')
+    c = Tix.Control(f, value=1021, label='Capacity: ')
+
+    a.pack(side=Tix.TOP, padx=20, pady=2)
+    w.pack(side=Tix.TOP, padx=20, pady=2)
+    r.pack(side=Tix.TOP, padx=20, pady=2)
+    c.pack(side=Tix.TOP, padx=20, pady=2)
+
+    # Create the common buttons
+    createCommonButtons(common)
+
+    #----------------------------------------
+    # Create the second page
+    #----------------------------------------
+
+    tab = nb.network
+
+    f = Tix.Frame(tab)
+    common = Tix.Frame(tab)
+
+    f.pack(side=Tix.LEFT, padx=2, pady=2, fill=Tix.BOTH, expand=1)
+    common.pack(side=Tix.RIGHT, padx=2, fill=Tix.Y)
+
+    a = Tix.Control(f, value=12,   label='Access time: ')
+    w = Tix.Control(f, value=400,  label='Write Throughput: ')
+    r = Tix.Control(f, value=400,  label='Read Throughput: ')
+    c = Tix.Control(f, value=1021, label='Capacity: ')
+    u = Tix.Control(f, value=10,   label='Users: ')
+
+    a.pack(side=Tix.TOP, padx=20, pady=2)
+    w.pack(side=Tix.TOP, padx=20, pady=2)
+    r.pack(side=Tix.TOP, padx=20, pady=2)
+    c.pack(side=Tix.TOP, padx=20, pady=2)
+    u.pack(side=Tix.TOP, padx=20, pady=2)
+
+    createCommonButtons(common)
+
+def doDestroy():
+    global root
+    root.destroy()
+
+def createCommonButtons(master):
+    ok = Tix.Button(master, name='ok', text='OK', width=6,
+                command=doDestroy)
+    cancel = Tix.Button(master, name='cancel',
+                    text='Cancel', width=6,
+                    command=doDestroy)
+
+    ok.pack(side=Tix.TOP, padx=2, pady=2)
+    cancel.pack(side=Tix.TOP, padx=2, pady=2)
+
+if __name__ == '__main__':
+    root = Tix.Tk()
+    RunSample(root)
+    root.mainloop()


Property changes on: vendor/Python/current/Demo/tix/samples/NoteBook.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tix/samples/OptMenu.py
===================================================================
--- vendor/Python/current/Demo/tix/samples/OptMenu.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tix/samples/OptMenu.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,68 @@
+# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
+#
+# $Id: OptMenu.py 36560 2004-07-18 06:16:08Z tim_one $
+#
+# Tix Demostration Program
+#
+# This sample program is structured in such a way so that it can be
+# executed from the Tix demo program "tixwidgets.py": it must have a
+# procedure called "RunSample". It should also have the "if" statment
+# at the end of this file so that it can be run as a standalone
+# program.
+
+# This file demonstrates the use of the tixOptionMenu widget -- you can
+# use it for the user to choose from a fixed set of options
+#
+import Tix
+
+options = {'text':'Plain Text', 'post':'PostScript', 'html':'HTML',
+           'tex':'LaTeX', 'rtf':'Rich Text Format'}
+
+def RunSample(w):
+    global demo_opt_from, demo_opt_to
+
+    demo_opt_from = Tix.StringVar()
+    demo_opt_to = Tix.StringVar()
+
+    top = Tix.Frame(w, bd=1, relief=Tix.RAISED)
+
+    from_file = Tix.OptionMenu(top, label="From File Format : ",
+                               variable=demo_opt_from,
+                               options = 'label.width  19 label.anchor e menubutton.width 15')
+
+    to_file = Tix.OptionMenu(top, label="To File Format : ",
+                             variable=demo_opt_to,
+                             options='label.width  19 label.anchor e menubutton.width 15')
+
+    # Add the available options to the two OptionMenu widgets
+    #
+    # [Hint] You have to add the options first before you set the
+    #        global variables "demo_opt_from" and "demo_opt_to". Otherwise
+    #        the OptionMenu widget will complain about "unknown options"!
+    #
+    for opt in options.keys():
+        from_file.add_command(opt, label=options[opt])
+        to_file.add_command(opt, label=options[opt])
+
+    demo_opt_from.set('html')
+    demo_opt_to.set('post')
+
+    from_file.pack(side=Tix.TOP, anchor=Tix.W, pady=3, padx=6)
+    to_file.pack(side=Tix.TOP, anchor=Tix.W, pady=3, padx=6)
+
+    box = Tix.ButtonBox(w, orientation=Tix.HORIZONTAL)
+    box.add('ok', text='Ok', underline=0, width=6,
+            command=lambda w=w: ok_command(w))
+    box.add('cancel', text='Cancel', underline=0, width=6,
+            command=lambda w=w: w.destroy())
+    box.pack(side=Tix.BOTTOM, fill=Tix.X)
+    top.pack(side=Tix.TOP, fill=Tix.BOTH, expand=1)
+
+def ok_command(w):
+    # tixDemo:Status "Convert file from %s to %s" % ( demo_opt_from.get(), demo_opt_to.get())
+    w.destroy()
+
+if __name__ == '__main__':
+    root = Tix.Tk()
+    RunSample(root)
+    root.mainloop()


Property changes on: vendor/Python/current/Demo/tix/samples/OptMenu.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tix/samples/PanedWin.py
===================================================================
--- vendor/Python/current/Demo/tix/samples/PanedWin.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tix/samples/PanedWin.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,98 @@
+# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
+#
+# $Id: PanedWin.py 36560 2004-07-18 06:16:08Z tim_one $
+#
+# Tix Demostration Program
+#
+# This sample program is structured in such a way so that it can be
+# executed from the Tix demo program "tixwidgets.py": it must have a
+# procedure called "RunSample". It should also have the "if" statment
+# at the end of this file so that it can be run as a standalone
+# program.
+
+# This file demonstrates the use of the tixPanedWindow widget. This program
+# is a dummy news reader: the user can adjust the sizes of the list
+# of artical names and the size of the text widget that shows the body
+# of the article.
+
+import Tix
+
+TCL_ALL_EVENTS          = 0
+
+def RunSample (root):
+    panedwin = DemoPanedwin(root)
+    panedwin.mainloop()
+    panedwin.destroy()
+
+class DemoPanedwin:
+    def __init__(self, w):
+        self.root = w
+        self.exit = -1
+
+        z = w.winfo_toplevel()
+        z.wm_protocol("WM_DELETE_WINDOW", lambda self=self: self.quitcmd())
+
+        group = Tix.LabelEntry(w, label='Newsgroup:', options='entry.width 25')
+        group.entry.insert(0,'comp.lang.python')
+        pane = Tix.PanedWindow(w, orientation='vertical')
+
+        p1 = pane.add('list', min=70, size=100)
+        p2 = pane.add('text', min=70)
+        list = Tix.ScrolledListBox(p1)
+        list.listbox['width'] = 80
+        list.listbox['height'] = 5
+        text = Tix.ScrolledText(p2)
+        text.text['width'] = 80
+        text.text['height'] = 20
+
+        list.listbox.insert(Tix.END, "  12324 Re: Tkinter is good for your health")
+        list.listbox.insert(Tix.END, "+ 12325 Re: Tkinter is good for your health")
+        list.listbox.insert(Tix.END, "+ 12326 Re: Tix is even better for your health (Was: Tkinter is good...)")
+        list.listbox.insert(Tix.END, "  12327 Re: Tix is even better for your health (Was: Tkinter is good...)")
+        list.listbox.insert(Tix.END, "+ 12328 Re: Tix is even better for your health (Was: Tkinter is good...)")
+        list.listbox.insert(Tix.END, "  12329 Re: Tix is even better for your health (Was: Tkinter is good...)")
+        list.listbox.insert(Tix.END, "+ 12330 Re: Tix is even better for your health (Was: Tkinter is good...)")
+
+        text.text['bg'] = list.listbox['bg']
+        text.text['wrap'] = 'none'
+        text.text.insert(Tix.END, """
+    Mon, 19 Jun 1995 11:39:52        comp.lang.python              Thread   34 of  220
+    Lines 353       A new way to put text and bitmaps together iNo responses
+    ioi at blue.seas.upenn.edu                Ioi K. Lam at University of Pennsylvania
+
+    Hi,
+
+    I have implemented a new image type called "compound". It allows you
+    to glue together a bunch of bitmaps, images and text strings together
+    to form a bigger image. Then you can use this image with widgets that
+    support the -image option. For example, you can display a text string string
+    together with a bitmap, at the same time, inside a TK button widget.
+    """)
+        text.text['state'] = 'disabled'
+
+        list.pack(expand=1, fill=Tix.BOTH, padx=4, pady=6)
+        text.pack(expand=1, fill=Tix.BOTH, padx=4, pady=6)
+
+        group.pack(side=Tix.TOP, padx=3, pady=3, fill=Tix.BOTH)
+        pane.pack(side=Tix.TOP, padx=3, pady=3, fill=Tix.BOTH, expand=1)
+
+        box = Tix.ButtonBox(w, orientation=Tix.HORIZONTAL)
+        box.add('ok', text='Ok', underline=0, width=6,
+                command=self.quitcmd)
+        box.add('cancel', text='Cancel', underline=0, width=6,
+                command=self.quitcmd)
+        box.pack(side=Tix.BOTTOM, fill=Tix.X)
+
+    def quitcmd (self):
+        self.exit = 0
+
+    def mainloop(self):
+        while self.exit < 0:
+            self.root.tk.dooneevent(TCL_ALL_EVENTS)
+
+    def destroy (self):
+        self.root.destroy()
+
+if __name__ == '__main__':
+    root = Tix.Tk()
+    RunSample(root)


Property changes on: vendor/Python/current/Demo/tix/samples/PanedWin.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tix/samples/PopMenu.py
===================================================================
--- vendor/Python/current/Demo/tix/samples/PopMenu.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tix/samples/PopMenu.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,57 @@
+# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
+#
+#       $Id: PopMenu.py 36560 2004-07-18 06:16:08Z tim_one $
+#
+# Tix Demostration Program
+#
+# This sample program is structured in such a way so that it can be
+# executed from the Tix demo program "tixwidgets.py": it must have a
+# procedure called "RunSample". It should also have the "if" statment
+# at the end of this file so that it can be run as a standalone
+# program using tixwish.
+
+# This file demonstrates the use of the tixPopupMenu widget.
+#
+import Tix
+
+def RunSample(w):
+    # We create the frame and the button, then we'll bind the PopupMenu
+    # to both widgets. The result is, when you press the right mouse
+    # button over $w.top or $w.top.but, the PopupMenu will come up.
+    #
+    top = Tix.Frame(w, relief=Tix.RAISED, bd=1)
+    but = Tix.Button(top, text='Press the right mouse button over this button or its surrounding area')
+    but.pack(expand=1, fill=Tix.BOTH, padx=50, pady=50)
+
+    p = Tix.PopupMenu(top, title='Popup Test')
+    p.bind_widget(top)
+    p.bind_widget(but)
+
+    # Set the entries inside the PopupMenu widget.
+    # [Hint] You have to manipulate the "menu" subwidget.
+    #        $w.top.p itself is NOT a menu widget.
+    # [Hint] Watch carefully how the sub-menu is created
+    #
+    p.menu.add_command(label='Desktop', underline=0)
+    p.menu.add_command(label='Select', underline=0)
+    p.menu.add_command(label='Find', underline=0)
+    p.menu.add_command(label='System', underline=1)
+    p.menu.add_command(label='Help', underline=0)
+    m1 = Tix.Menu(p.menu)
+    m1.add_command(label='Hello')
+    p.menu.add_cascade(label='More', menu=m1)
+
+    but.pack(side=Tix.TOP, padx=40, pady=50)
+
+    box = Tix.ButtonBox(w, orientation=Tix.HORIZONTAL)
+    box.add('ok', text='Ok', underline=0, width=6,
+            command=lambda w=w: w.destroy())
+    box.add('cancel', text='Cancel', underline=0, width=6,
+            command=lambda w=w: w.destroy())
+    box.pack(side=Tix.BOTTOM, fill=Tix.X)
+    top.pack(side=Tix.TOP, fill=Tix.BOTH, expand=1)
+
+if __name__ == '__main__':
+    root = Tix.Tk()
+    RunSample(root)
+    root.mainloop()


Property changes on: vendor/Python/current/Demo/tix/samples/PopMenu.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tix/samples/SHList1.py
===================================================================
--- vendor/Python/current/Demo/tix/samples/SHList1.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tix/samples/SHList1.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,131 @@
+# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
+#
+# $Id: SHList1.py 36560 2004-07-18 06:16:08Z tim_one $
+#
+# Tix Demostration Program
+#
+# This sample program is structured in such a way so that it can be
+# executed from the Tix demo program "tixwidgets.py": it must have a
+# procedure called "RunSample". It should also have the "if" statment
+# at the end of this file so that it can be run as a standalone
+# program using tixwish.
+
+# This file demonstrates the use of the tixScrolledHList widget.
+#
+
+import Tix
+
+TCL_ALL_EVENTS          = 0
+
+def RunSample (root):
+    shlist = DemoSHList(root)
+    shlist.mainloop()
+    shlist.destroy()
+
+class DemoSHList:
+    def __init__(self, w):
+        self.root = w
+        self.exit = -1
+
+        z = w.winfo_toplevel()
+        z.wm_protocol("WM_DELETE_WINDOW", lambda self=self: self.quitcmd())
+
+        # We create the frame and the ScrolledHList widget
+        # at the top of the dialog box
+        #
+        top = Tix.Frame( w, relief=Tix.RAISED, bd=1)
+
+        # Put a simple hierachy into the HList (two levels). Use colors and
+        # separator widgets (frames) to make the list look fancy
+        #
+        top.a = Tix.ScrolledHList(top)
+        top.a.pack( expand=1, fill=Tix.BOTH, padx=10, pady=10, side=Tix.TOP)
+
+        # This is our little relational database
+        #
+        bosses = [
+            ('jeff',  'Jeff Waxman'),
+            ('john',  'John Lee'),
+            ('peter', 'Peter Kenson')
+        ]
+
+        employees = [
+            ('alex',  'john',  'Alex Kellman'),
+            ('alan',  'john',  'Alan Adams'),
+            ('andy',  'peter', 'Andreas Crawford'),
+            ('doug',  'jeff',  'Douglas Bloom'),
+            ('jon',   'peter', 'Jon Baraki'),
+            ('chris', 'jeff',  'Chris Geoffrey'),
+            ('chuck', 'jeff',  'Chuck McLean')
+        ]
+
+        hlist=top.a.hlist
+
+        # Let configure the appearance of the HList subwidget
+        #
+        hlist.config( separator='.', width=25, drawbranch=0, indent=10)
+
+        count=0
+        for boss,name in bosses :
+            if count :
+                f=Tix.Frame(hlist, name='sep%d' % count, height=2, width=150,
+                    bd=2, relief=Tix.SUNKEN )
+
+                hlist.add_child( itemtype=Tix.WINDOW,
+                    window=f, state=Tix.DISABLED )
+
+            hlist.add(boss, itemtype=Tix.TEXT, text=name)
+            count = count+1
+
+
+        for person,boss,name in employees :
+            # '.' is the separator character we chose above
+            #
+            key= boss    + '.'     + person
+            #    ^^^^                ^^^^^^
+            #    parent entryPath /  child's name
+
+            hlist.add( key, text=name )
+
+            # [Hint] Make sure the keys (e.g. 'boss.person') you choose
+            #    are unique names. If you cannot be sure of this (because of
+            #    the structure of your database, e.g.) you can use the
+            #    "add_child" command instead:
+            #
+            #  hlist.addchild( boss,  text=name)
+            #                  ^^^^
+            #                  parent entryPath
+
+
+        # Use a ButtonBox to hold the buttons.
+        #
+        box= Tix.ButtonBox(top, orientation=Tix.HORIZONTAL )
+        box.add( 'ok',  text='Ok', underline=0,  width=6,
+            command = self.okcmd)
+
+        box.add( 'cancel', text='Cancel', underline=0, width=6,
+            command = self.quitcmd)
+
+        box.pack( side=Tix.BOTTOM, fill=Tix.X)
+        top.pack( side=Tix.TOP,    fill=Tix.BOTH, expand=1 )
+
+    def okcmd (self):
+        self.quitcmd()
+
+    def quitcmd (self):
+        self.exit = 0
+
+    def mainloop(self):
+        while self.exit < 0:
+            self.root.tk.dooneevent(TCL_ALL_EVENTS)
+
+    def destroy (self):
+        self.root.destroy()
+
+
+# This "if" statement makes it possible to run this script file inside or
+# outside of the main demo program "tixwidgets.py".
+#
+if __name__== '__main__' :
+    root=Tix.Tk()
+    RunSample(root)


Property changes on: vendor/Python/current/Demo/tix/samples/SHList1.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tix/samples/SHList2.py
===================================================================
--- vendor/Python/current/Demo/tix/samples/SHList2.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tix/samples/SHList2.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,168 @@
+# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
+#
+# $Id: SHList2.py 36560 2004-07-18 06:16:08Z tim_one $
+#
+# Tix Demostration Program
+#
+# This sample program is structured in such a way so that it can be
+# executed from the Tix demo program "tixwidget": it must have a
+# procedure called "RunSample". It should also have the "if" statment
+# at the end of this file so that it can be run as a standalone
+# program using tixwish.
+
+# This file demonstrates how to use multiple columns and multiple styles
+# in the tixHList widget
+#
+# In a tixHList widget, you can have one ore more columns.
+#
+
+import Tix
+
+TCL_ALL_EVENTS          = 0
+
+def RunSample (root):
+    shlist = DemoSHList(root)
+    shlist.mainloop()
+    shlist.destroy()
+
+class DemoSHList:
+    def __init__(self, w):
+        self.root = w
+        self.exit = -1
+
+        z = w.winfo_toplevel()
+        z.wm_protocol("WM_DELETE_WINDOW", lambda self=self: self.quitcmd())
+
+        # We create the frame and the ScrolledHList widget
+        # at the top of the dialog box
+        #
+        top = Tix.Frame( w, relief=Tix.RAISED, bd=1)
+
+        # Put a simple hierachy into the HList (two levels). Use colors and
+        # separator widgets (frames) to make the list look fancy
+        #
+        top.a = Tix.ScrolledHList(top, options='hlist.columns 3 hlist.header 1' )
+        top.a.pack( expand=1, fill=Tix.BOTH, padx=10, pady=10, side=Tix.TOP)
+
+        hlist=top.a.hlist
+
+        # Create the title for the HList widget
+        #       >> Notice that we have set the hlist.header subwidget option to true
+        #      so that the header is displayed
+        #
+
+        boldfont=hlist.tk.call('tix','option','get','bold_font')
+
+        # First some styles for the headers
+        style={}
+        style['header'] = Tix.DisplayStyle(Tix.TEXT, refwindow=hlist,
+            anchor=Tix.CENTER, padx=8, pady=2, font = boldfont )
+
+        hlist.header_create(0, itemtype=Tix.TEXT, text='Name',
+            style=style['header'])
+        hlist.header_create(1, itemtype=Tix.TEXT, text='Position',
+            style=style['header'])
+
+        # Notice that we use 3 columns in the hlist widget. This way when the user
+        # expands the windows wide, the right side of the header doesn't look
+        # chopped off. The following line ensures that the 3 column header is
+        # not shown unless the hlist window is wider than its contents.
+        #
+        hlist.column_width(2,0)
+
+        # This is our little relational database
+        #
+        boss = ('doe', 'John Doe',      'Director')
+
+        managers = [
+            ('jeff',  'Jeff Waxman',    'Manager'),
+            ('john',  'John Lee',               'Manager'),
+            ('peter', 'Peter Kenson',   'Manager')
+        ]
+
+        employees = [
+            ('alex',  'john',   'Alex Kellman',         'Clerk'),
+            ('alan',  'john',       'Alan Adams',               'Clerk'),
+            ('andy',  'peter',      'Andreas Crawford', 'Salesman'),
+            ('doug',  'jeff',       'Douglas Bloom',    'Clerk'),
+            ('jon',   'peter',      'Jon Baraki',               'Salesman'),
+            ('chris', 'jeff',       'Chris Geoffrey',   'Clerk'),
+            ('chuck', 'jeff',       'Chuck McLean',             'Cleaner')
+        ]
+
+        style['mgr_name'] = Tix.DisplayStyle(Tix.TEXT, refwindow=hlist)
+
+        style['mgr_posn'] = Tix.DisplayStyle(Tix.TEXT, padx=8, refwindow=hlist)
+
+        style['empl_name'] = Tix.DisplayStyle(Tix.TEXT, refwindow=hlist)
+
+        style['empl_posn'] = Tix.DisplayStyle(Tix.TEXT, padx=8, refwindow=hlist)
+
+        # Let configure the appearance of the HList subwidget
+        #
+        hlist.config(separator='.', width=25, drawbranch=0, indent=10)
+        hlist.column_width(0, chars=20)
+
+        # Create the boss
+        #
+        hlist.add ('.',           itemtype=Tix.TEXT, text=boss[1],
+            style=style['mgr_name'])
+        hlist.item_create('.', 1, itemtype=Tix.TEXT, text=boss[2],
+            style=style['mgr_posn'])
+
+        # Create the managers
+        #
+
+        for key,name,posn in managers :
+            e= '.'+ key
+            hlist.add(e, itemtype=Tix.TEXT, text=name,
+                style=style['mgr_name'])
+            hlist.item_create(e, 1, itemtype=Tix.TEXT, text=posn,
+                style=style['mgr_posn'])
+
+
+        for key,mgr,name,posn in employees :
+            # "." is the separator character we chose above
+
+            entrypath = '.' + mgr        + '.' + key
+
+            #           ^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^^
+            #       parent entryPath / child's name
+
+            hlist.add(entrypath, text=name, style=style['empl_name'])
+            hlist.item_create(entrypath, 1, itemtype=Tix.TEXT,
+                text = posn, style = style['empl_posn'] )
+
+
+        # Use a ButtonBox to hold the buttons.
+        #
+        box= Tix.ButtonBox(top, orientation=Tix.HORIZONTAL )
+        box.add( 'ok',  text='Ok', underline=0,  width=6,
+            command = self.okcmd )
+
+        box.add( 'cancel', text='Cancel', underline=0, width=6,
+            command = self.quitcmd )
+
+        box.pack( side=Tix.BOTTOM, fill=Tix.X)
+        top.pack( side=Tix.TOP,    fill=Tix.BOTH, expand=1 )
+
+    def okcmd (self):
+        self.quitcmd()
+
+    def quitcmd (self):
+        self.exit = 0
+
+    def mainloop(self):
+        while self.exit < 0:
+            self.root.tk.dooneevent(TCL_ALL_EVENTS)
+
+    def destroy (self):
+        self.root.destroy()
+
+
+# This "if" statement makes it possible to run this script file inside or
+# outside of the main demo program "tixwidgets.py".
+#
+if __name__== '__main__' :
+    root=Tix.Tk()
+    RunSample(root)


Property changes on: vendor/Python/current/Demo/tix/samples/SHList2.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tix/samples/Tree.py
===================================================================
--- vendor/Python/current/Demo/tix/samples/Tree.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tix/samples/Tree.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,80 @@
+# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
+#
+# $Id: Tree.py 36560 2004-07-18 06:16:08Z tim_one $
+#
+# Tix Demostration Program
+#
+# This sample program is structured in such a way so that it can be
+# executed from the Tix demo program "tixwidgets.py": it must have a
+# procedure called "RunSample". It should also have the "if" statment
+# at the end of this file so that it can be run as a standalone
+# program.
+
+# This file demonstrates how to use the TixTree widget to display
+# dynamic hierachical data (the files in the Unix file system)
+#
+
+import Tix, os
+
+def RunSample(w):
+    top = Tix.Frame(w, relief=Tix.RAISED, bd=1)
+    tree = Tix.Tree(top, options='separator "/"')
+    tree.pack(expand=1, fill=Tix.BOTH, padx=10, pady=10, side=Tix.LEFT)
+    tree['opencmd'] = lambda dir=None, w=tree: opendir(w, dir)
+
+    # The / directory is added in the "open" mode. The user can open it
+    # and then browse its subdirectories ...
+    adddir(tree, "/")
+
+    box = Tix.ButtonBox(w, orientation=Tix.HORIZONTAL)
+    box.add('ok', text='Ok', underline=0, command=w.destroy, width=6)
+    box.add('cancel', text='Cancel', underline=0, command=w.destroy, width=6)
+    box.pack(side=Tix.BOTTOM, fill=Tix.X)
+    top.pack(side=Tix.TOP, fill=Tix.BOTH, expand=1)
+
+def adddir(tree, dir):
+    if dir == '/':
+        text = '/'
+    else:
+        text = os.path.basename(dir)
+    tree.hlist.add(dir, itemtype=Tix.IMAGETEXT, text=text,
+                   image=tree.tk.call('tix', 'getimage', 'folder'))
+    try:
+        os.listdir(dir)
+        tree.setmode(dir, 'open')
+    except os.error:
+        # No read permission ?
+        pass
+
+# This function is called whenever the user presses the (+) indicator or
+# double clicks on a directory whose mode is "open". It loads the files
+# inside that directory into the Tree widget.
+#
+# Note we didn't specify the closecmd option for the Tree widget, so it
+# performs the default action when the user presses the (-) indicator or
+# double clicks on a directory whose mode is "close": hide all of its child
+# entries
+def opendir(tree, dir):
+    entries = tree.hlist.info_children(dir)
+    if entries:
+        # We have already loaded this directory. Let's just
+        # show all the child entries
+        #
+        # Note: since we load the directory only once, it will not be
+        #       refreshed if the you add or remove files from this
+        #       directory.
+        #
+        for entry in entries:
+            tree.hlist.show_entry(entry)
+    files = os.listdir(dir)
+    for file in files:
+        if os.path.isdir(dir + '/' + file):
+            adddir(tree, dir + '/' + file)
+        else:
+            tree.hlist.add(dir + '/' + file, itemtype=Tix.IMAGETEXT, text=file,
+                           image=tree.tk.call('tix', 'getimage', 'file'))
+
+if __name__ == '__main__':
+    root = Tix.Tk()
+    RunSample(root)
+    root.mainloop()


Property changes on: vendor/Python/current/Demo/tix/samples/Tree.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tix/tixwidgets.py
===================================================================
--- vendor/Python/current/Demo/tix/tixwidgets.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tix/tixwidgets.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1003 @@
+# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
+#
+# $Id: tixwidgets.py 36560 2004-07-18 06:16:08Z tim_one $
+#
+# tixwidgets.py --
+#
+#       For Tix, see http://tix.sourceforge.net
+#
+#       This is a demo program of some of the Tix widgets available in Python.
+#       If you have installed Python & Tix properly, you can execute this as
+#
+#               % python tixwidgets.py
+#
+
+import os, os.path, sys, Tix
+from Tkconstants import *
+import traceback, tkMessageBox
+
+TCL_DONT_WAIT           = 1<<1
+TCL_WINDOW_EVENTS       = 1<<2
+TCL_FILE_EVENTS         = 1<<3
+TCL_TIMER_EVENTS        = 1<<4
+TCL_IDLE_EVENTS         = 1<<5
+TCL_ALL_EVENTS          = 0
+
+class Demo:
+    def __init__(self, top):
+        self.root = top
+        self.exit = -1
+
+        self.dir = None                         # script directory
+        self.balloon = None                     # balloon widget
+        self.useBalloons = Tix.StringVar()
+        self.useBalloons.set('0')
+        self.statusbar = None                   # status bar widget
+        self.welmsg = None                      # Msg widget
+        self.welfont = ''                       # font name
+        self.welsize = ''                       # font size
+
+        progname = sys.argv[0]
+        dirname = os.path.dirname(progname)
+        if dirname and dirname != os.curdir:
+            self.dir = dirname
+            index = -1
+            for i in range(len(sys.path)):
+                p = sys.path[i]
+                if p in ("", os.curdir):
+                    index = i
+            if index >= 0:
+                sys.path[index] = dirname
+            else:
+                sys.path.insert(0, dirname)
+        else:
+            self.dir = os.getcwd()
+        sys.path.insert(0, self.dir+'/samples')
+
+    def MkMainMenu(self):
+        top = self.root
+        w = Tix.Frame(top, bd=2, relief=RAISED)
+        file = Tix.Menubutton(w, text='File', underline=0, takefocus=0)
+        help = Tix.Menubutton(w, text='Help', underline=0, takefocus=0)
+        file.pack(side=LEFT)
+        help.pack(side=RIGHT)
+        fm = Tix.Menu(file, tearoff=0)
+        file['menu'] = fm
+        hm = Tix.Menu(help, tearoff=0)
+        help['menu'] = hm
+
+        fm.add_command(label='Exit', underline=1,
+                     command = lambda self=self: self.quitcmd () )
+        hm.add_checkbutton(label='BalloonHelp', underline=0, command=ToggleHelp,
+                           variable=self.useBalloons)
+        # The trace variable option doesn't seem to work, instead I use 'command'
+        #apply(w.tk.call, ('trace', 'variable', self.useBalloons, 'w',
+        #                     ToggleHelp))
+
+        return w
+
+    def MkMainNotebook(self):
+        top = self.root
+        w = Tix.NoteBook(top, ipadx=5, ipady=5, options="""
+        tagPadX 6
+        tagPadY 4
+        borderWidth 2
+        """)
+        # This may be required if there is no *Background option
+        top['bg'] = w['bg']
+
+        w.add('wel', label='Welcome', underline=0,
+              createcmd=lambda w=w, name='wel': MkWelcome(w, name))
+        w.add('cho', label='Choosers', underline=0,
+              createcmd=lambda w=w, name='cho': MkChoosers(w, name))
+        w.add('scr', label='Scrolled Widgets', underline=0,
+              createcmd=lambda w=w, name='scr': MkScroll(w, name))
+        w.add('mgr', label='Manager Widgets', underline=0,
+              createcmd=lambda w=w, name='mgr': MkManager(w, name))
+        w.add('dir', label='Directory List', underline=0,
+              createcmd=lambda w=w, name='dir': MkDirList(w, name))
+        w.add('exp', label='Run Sample Programs', underline=0,
+              createcmd=lambda w=w, name='exp': MkSample(w, name))
+        return w
+
+    def MkMainStatus(self):
+        global demo
+        top = self.root
+
+        w = Tix.Frame(top, relief=Tix.RAISED, bd=1)
+        demo.statusbar = Tix.Label(w, relief=Tix.SUNKEN, bd=1)
+        demo.statusbar.form(padx=3, pady=3, left=0, right='%70')
+        return w
+
+    def build(self):
+        root = self.root
+        z = root.winfo_toplevel()
+        z.wm_title('Tix Widget Demonstration')
+        if z.winfo_screenwidth() <= 800:
+            z.geometry('790x590+10+10')
+        else:
+            z.geometry('890x640+10+10')
+        demo.balloon = Tix.Balloon(root)
+        frame1 = self.MkMainMenu()
+        frame2 = self.MkMainNotebook()
+        frame3 = self.MkMainStatus()
+        frame1.pack(side=TOP, fill=X)
+        frame3.pack(side=BOTTOM, fill=X)
+        frame2.pack(side=TOP, expand=1, fill=BOTH, padx=4, pady=4)
+        demo.balloon['statusbar'] = demo.statusbar
+        z.wm_protocol("WM_DELETE_WINDOW", lambda self=self: self.quitcmd())
+
+        # To show Tcl errors - uncomment this to see the listbox bug.
+        # Tkinter defines a Tcl tkerror procedure that in effect
+        # silences all background Tcl error reporting.
+        # root.tk.eval('if {[info commands tkerror] != ""} {rename tkerror pytkerror}')
+    def quitcmd (self):
+        """Quit our mainloop. It is up to you to call root.destroy() after."""
+        self.exit = 0
+
+    def loop(self):
+        """This is an explict replacement for _tkinter mainloop()
+        It lets you catch keyboard interrupts easier, and avoids
+        the 20 msec. dead sleep() which burns a constant CPU."""
+        while self.exit < 0:
+            # There are 2 whiles here. The outer one lets you continue
+            # after a ^C interrupt.
+            try:
+                # This is the replacement for _tkinter mainloop()
+                # It blocks waiting for the next Tcl event using select.
+                while self.exit < 0:
+                    self.root.tk.dooneevent(TCL_ALL_EVENTS)
+            except SystemExit:
+                # Tkinter uses SystemExit to exit
+                #print 'Exit'
+                self.exit = 1
+                return
+            except KeyboardInterrupt:
+                if tkMessageBox.askquestion ('Interrupt', 'Really Quit?') == 'yes':
+                    # self.tk.eval('exit')
+                    self.exit = 1
+                    return
+                continue
+            except:
+                # Otherwise it's some other error - be nice and say why
+                t, v, tb = sys.exc_info()
+                text = ""
+                for line in traceback.format_exception(t,v,tb):
+                    text += line + '\n'
+                try: tkMessageBox.showerror ('Error', text)
+                except: pass
+                self.exit = 1
+                raise SystemExit, 1
+
+    def destroy (self):
+        self.root.destroy()
+
+def RunMain(root):
+    global demo
+
+    demo = Demo(root)
+
+    demo.build()
+    demo.loop()
+    demo.destroy()
+
+# Tabs
+def MkWelcome(nb, name):
+    w = nb.page(name)
+    bar = MkWelcomeBar(w)
+    text = MkWelcomeText(w)
+    bar.pack(side=TOP, fill=X, padx=2, pady=2)
+    text.pack(side=TOP, fill=BOTH, expand=1)
+
+def MkWelcomeBar(top):
+    global demo
+
+    w = Tix.Frame(top, bd=2, relief=Tix.GROOVE)
+    b1 = Tix.ComboBox(w, command=lambda w=top: MainTextFont(w))
+    b2 = Tix.ComboBox(w, command=lambda w=top: MainTextFont(w))
+    b1.entry['width'] = 15
+    b1.slistbox.listbox['height'] = 3
+    b2.entry['width'] = 4
+    b2.slistbox.listbox['height'] = 3
+
+    demo.welfont = b1
+    demo.welsize = b2
+
+    b1.insert(Tix.END, 'Courier')
+    b1.insert(Tix.END, 'Helvetica')
+    b1.insert(Tix.END, 'Lucida')
+    b1.insert(Tix.END, 'Times Roman')
+
+    b2.insert(Tix.END, '8')
+    b2.insert(Tix.END, '10')
+    b2.insert(Tix.END, '12')
+    b2.insert(Tix.END, '14')
+    b2.insert(Tix.END, '18')
+
+    b1.pick(1)
+    b2.pick(3)
+
+    b1.pack(side=Tix.LEFT, padx=4, pady=4)
+    b2.pack(side=Tix.LEFT, padx=4, pady=4)
+
+    demo.balloon.bind_widget(b1, msg='Choose\na font',
+                             statusmsg='Choose a font for this page')
+    demo.balloon.bind_widget(b2, msg='Point size',
+                             statusmsg='Choose the font size for this page')
+    return w
+
+def MkWelcomeText(top):
+    global demo
+
+    w = Tix.ScrolledWindow(top, scrollbar='auto')
+    win = w.window
+    text = 'Welcome to TIX in Python'
+    title = Tix.Label(win,
+                      bd=0, width=30, anchor=Tix.N, text=text)
+    msg = Tix.Message(win,
+                      bd=0, width=400, anchor=Tix.N,
+                      text='Tix is a set of mega-widgets based on TK. This program \
+demonstrates the widgets in the Tix widget set. You can choose the pages \
+in this window to look at the corresponding widgets. \n\n\
+To quit this program, choose the "File | Exit" command.\n\n\
+For more information, see http://tix.sourceforge.net.')
+    title.pack(expand=1, fill=Tix.BOTH, padx=10, pady=10)
+    msg.pack(expand=1, fill=Tix.BOTH, padx=10, pady=10)
+    demo.welmsg = msg
+    return w
+
+def MainTextFont(w):
+    global demo
+
+    if not demo.welmsg:
+        return
+    font = demo.welfont['value']
+    point = demo.welsize['value']
+    if font == 'Times Roman':
+        font = 'times'
+    fontstr = '%s %s' % (font, point)
+    demo.welmsg['font'] = fontstr
+
+def ToggleHelp():
+    if demo.useBalloons.get() == '1':
+        demo.balloon['state'] = 'both'
+    else:
+        demo.balloon['state'] = 'none'
+
+def MkChoosers(nb, name):
+    w = nb.page(name)
+    options = "label.padX 4"
+
+    til = Tix.LabelFrame(w, label='Chooser Widgets', options=options)
+    cbx = Tix.LabelFrame(w, label='tixComboBox', options=options)
+    ctl = Tix.LabelFrame(w, label='tixControl', options=options)
+    sel = Tix.LabelFrame(w, label='tixSelect', options=options)
+    opt = Tix.LabelFrame(w, label='tixOptionMenu', options=options)
+    fil = Tix.LabelFrame(w, label='tixFileEntry', options=options)
+    fbx = Tix.LabelFrame(w, label='tixFileSelectBox', options=options)
+    tbr = Tix.LabelFrame(w, label='Tool Bar', options=options)
+
+    MkTitle(til.frame)
+    MkCombo(cbx.frame)
+    MkControl(ctl.frame)
+    MkSelect(sel.frame)
+    MkOptMenu(opt.frame)
+    MkFileEnt(fil.frame)
+    MkFileBox(fbx.frame)
+    MkToolBar(tbr.frame)
+
+    # First column: comBox and selector
+    cbx.form(top=0, left=0, right='%33')
+    sel.form(left=0, right='&'+str(cbx), top=cbx)
+    opt.form(left=0, right='&'+str(cbx), top=sel, bottom=-1)
+
+    # Second column: title .. etc
+    til.form(left=cbx, top=0,right='%66')
+    ctl.form(left=cbx, right='&'+str(til), top=til)
+    fil.form(left=cbx, right='&'+str(til), top=ctl)
+    tbr.form(left=cbx, right='&'+str(til), top=fil, bottom=-1)
+
+    #
+    # Third column: file selection
+    fbx.form(right=-1, top=0, left='%66')
+
+def MkCombo(w):
+    options="label.width %d label.anchor %s entry.width %d" % (10, Tix.E, 14)
+
+    static = Tix.ComboBox(w, label='Static', editable=0, options=options)
+    editable = Tix.ComboBox(w, label='Editable', editable=1, options=options)
+    history = Tix.ComboBox(w, label='History', editable=1, history=1,
+                           anchor=Tix.E, options=options)
+    static.insert(Tix.END, 'January')
+    static.insert(Tix.END, 'February')
+    static.insert(Tix.END, 'March')
+    static.insert(Tix.END, 'April')
+    static.insert(Tix.END, 'May')
+    static.insert(Tix.END, 'June')
+    static.insert(Tix.END, 'July')
+    static.insert(Tix.END, 'August')
+    static.insert(Tix.END, 'September')
+    static.insert(Tix.END, 'October')
+    static.insert(Tix.END, 'November')
+    static.insert(Tix.END, 'December')
+
+    editable.insert(Tix.END, 'Angola')
+    editable.insert(Tix.END, 'Bangladesh')
+    editable.insert(Tix.END, 'China')
+    editable.insert(Tix.END, 'Denmark')
+    editable.insert(Tix.END, 'Ecuador')
+
+    history.insert(Tix.END, '/usr/bin/ksh')
+    history.insert(Tix.END, '/usr/local/lib/python')
+    history.insert(Tix.END, '/var/adm')
+
+    static.pack(side=Tix.TOP, padx=5, pady=3)
+    editable.pack(side=Tix.TOP, padx=5, pady=3)
+    history.pack(side=Tix.TOP, padx=5, pady=3)
+
+states = ['Bengal', 'Delhi', 'Karnataka', 'Tamil Nadu']
+
+def spin_cmd(w, inc):
+    idx = states.index(demo_spintxt.get()) + inc
+    if idx < 0:
+        idx = len(states) - 1
+    elif idx >= len(states):
+        idx = 0
+# following doesn't work.
+#    return states[idx]
+    demo_spintxt.set(states[idx])       # this works
+
+def spin_validate(w):
+    global states, demo_spintxt
+
+    try:
+        i = states.index(demo_spintxt.get())
+    except ValueError:
+        return states[0]
+    return states[i]
+    # why this procedure works as opposed to the previous one beats me.
+
+def MkControl(w):
+    global demo_spintxt
+
+    options="label.width %d label.anchor %s entry.width %d" % (10, Tix.E, 13)
+
+    demo_spintxt = Tix.StringVar()
+    demo_spintxt.set(states[0])
+    simple = Tix.Control(w, label='Numbers', options=options)
+    spintxt = Tix.Control(w, label='States', variable=demo_spintxt,
+                          options=options)
+    spintxt['incrcmd'] = lambda w=spintxt: spin_cmd(w, 1)
+    spintxt['decrcmd'] = lambda w=spintxt: spin_cmd(w, -1)
+    spintxt['validatecmd'] = lambda w=spintxt: spin_validate(w)
+
+    simple.pack(side=Tix.TOP, padx=5, pady=3)
+    spintxt.pack(side=Tix.TOP, padx=5, pady=3)
+
+def MkSelect(w):
+    options = "label.anchor %s" % Tix.CENTER
+
+    sel1 = Tix.Select(w, label='Mere Mortals', allowzero=1, radio=1,
+                      orientation=Tix.VERTICAL,
+                      labelside=Tix.TOP,
+                      options=options)
+    sel2 = Tix.Select(w, label='Geeks', allowzero=1, radio=0,
+                      orientation=Tix.VERTICAL,
+                      labelside= Tix.TOP,
+                      options=options)
+
+    sel1.add('eat', text='Eat')
+    sel1.add('work', text='Work')
+    sel1.add('play', text='Play')
+    sel1.add('party', text='Party')
+    sel1.add('sleep', text='Sleep')
+
+    sel2.add('eat', text='Eat')
+    sel2.add('prog1', text='Program')
+    sel2.add('prog2', text='Program')
+    sel2.add('prog3', text='Program')
+    sel2.add('sleep', text='Sleep')
+
+    sel1.pack(side=Tix.LEFT, padx=5, pady=3, fill=Tix.X)
+    sel2.pack(side=Tix.LEFT, padx=5, pady=3, fill=Tix.X)
+
+def MkOptMenu(w):
+    options='menubutton.width 15 label.anchor %s' % Tix.E
+
+    m = Tix.OptionMenu(w, label='File Format : ', options=options)
+    m.add_command('text', label='Plain Text')
+    m.add_command('post', label='PostScript')
+    m.add_command('format', label='Formatted Text')
+    m.add_command('html', label='HTML')
+    m.add_command('sep')
+    m.add_command('tex', label='LaTeX')
+    m.add_command('rtf', label='Rich Text Format')
+
+    m.pack(fill=Tix.X, padx=5, pady=3)
+
+def MkFileEnt(w):
+    msg = Tix.Message(w,
+                      relief=Tix.FLAT, width=240, anchor=Tix.N,
+                      text='Press the "open file" icon button and a TixFileSelectDialog will popup.')
+    ent = Tix.FileEntry(w, label='Select a file : ')
+    msg.pack(side=Tix.TOP, expand=1, fill=Tix.BOTH, padx=3, pady=3)
+    ent.pack(side=Tix.TOP, fill=Tix.X, padx=3, pady=3)
+
+def MkFileBox(w):
+    """The FileSelectBox is a Motif-style box with various enhancements.
+    For example, you can adjust the size of the two listboxes
+    and your past selections are recorded.
+    """
+    msg = Tix.Message(w,
+                      relief=Tix.FLAT, width=240, anchor=Tix.N,
+                      text='The Tix FileSelectBox is a Motif-style box with various enhancements. For example, you can adjust the size of the two listboxes and your past selections are recorded.')
+    box = Tix.FileSelectBox(w)
+    msg.pack(side=Tix.TOP, expand=1, fill=Tix.BOTH, padx=3, pady=3)
+    box.pack(side=Tix.TOP, fill=Tix.X, padx=3, pady=3)
+
+def MkToolBar(w):
+    """The Select widget is also good for arranging buttons in a tool bar.
+    """
+    global demo
+
+    options='frame.borderWidth 1'
+
+    msg = Tix.Message(w,
+                      relief=Tix.FLAT, width=240, anchor=Tix.N,
+                      text='The Select widget is also good for arranging buttons in a tool bar.')
+    bar = Tix.Frame(w, bd=2, relief=Tix.RAISED)
+    font = Tix.Select(w, allowzero=1, radio=0, label='', options=options)
+    para = Tix.Select(w, allowzero=0, radio=1, label='', options=options)
+
+    font.add('bold', bitmap='@' + demo.dir + '/bitmaps/bold.xbm')
+    font.add('italic', bitmap='@' + demo.dir + '/bitmaps/italic.xbm')
+    font.add('underline', bitmap='@' + demo.dir + '/bitmaps/underline.xbm')
+    font.add('capital', bitmap='@' + demo.dir + '/bitmaps/capital.xbm')
+
+    para.add('left', bitmap='@' + demo.dir + '/bitmaps/leftj.xbm')
+    para.add('right', bitmap='@' + demo.dir + '/bitmaps/rightj.xbm')
+    para.add('center', bitmap='@' + demo.dir + '/bitmaps/centerj.xbm')
+    para.add('justify', bitmap='@' + demo.dir + '/bitmaps/justify.xbm')
+
+    msg.pack(side=Tix.TOP, expand=1, fill=Tix.BOTH, padx=3, pady=3)
+    bar.pack(side=Tix.TOP, fill=Tix.X, padx=3, pady=3)
+    font.pack({'in':bar}, side=Tix.LEFT, padx=3, pady=3)
+    para.pack({'in':bar}, side=Tix.LEFT, padx=3, pady=3)
+
+def MkTitle(w):
+    msg = Tix.Message(w,
+                      relief=Tix.FLAT, width=240, anchor=Tix.N,
+                      text='There are many types of "chooser" widgets that allow the user to input different types of information')
+    msg.pack(side=Tix.TOP, expand=1, fill=Tix.BOTH, padx=3, pady=3)
+
+def MkScroll(nb, name):
+    w = nb.page(name)
+    options='label.padX 4'
+
+    sls = Tix.LabelFrame(w, label='Tix.ScrolledListBox', options=options)
+    swn = Tix.LabelFrame(w, label='Tix.ScrolledWindow', options=options)
+    stx = Tix.LabelFrame(w, label='Tix.ScrolledText', options=options)
+
+    MkSList(sls.frame)
+    MkSWindow(swn.frame)
+    MkSText(stx.frame)
+
+    sls.form(top=0, left=0, right='%33', bottom=-1)
+    swn.form(top=0, left=sls, right='%66', bottom=-1)
+    stx.form(top=0, left=swn, right=-1, bottom=-1)
+
+
+def MkSList(w):
+    """This TixScrolledListBox is configured so that it uses scrollbars
+    only when it is necessary. Use the handles to resize the listbox and
+    watch the scrollbars automatically appear and disappear.  """
+    top = Tix.Frame(w, width=300, height=330)
+    bot = Tix.Frame(w)
+    msg = Tix.Message(top,
+                      relief=Tix.FLAT, width=200, anchor=Tix.N,
+                      text='This TixScrolledListBox is configured so that it uses scrollbars only when it is necessary. Use the handles to resize the listbox and watch the scrollbars automatically appear and disappear.')
+
+    list = Tix.ScrolledListBox(top, scrollbar='auto')
+    list.place(x=50, y=150, width=120, height=80)
+    list.listbox.insert(Tix.END, 'Alabama')
+    list.listbox.insert(Tix.END, 'California')
+    list.listbox.insert(Tix.END, 'Montana')
+    list.listbox.insert(Tix.END, 'New Jersey')
+    list.listbox.insert(Tix.END, 'New York')
+    list.listbox.insert(Tix.END, 'Pennsylvania')
+    list.listbox.insert(Tix.END, 'Washington')
+
+    rh = Tix.ResizeHandle(top, bg='black',
+                          relief=Tix.RAISED,
+                          handlesize=8, gridded=1, minwidth=50, minheight=30)
+    btn = Tix.Button(bot, text='Reset', command=lambda w=rh, x=list: SList_reset(w,x))
+    top.propagate(0)
+    msg.pack(fill=Tix.X)
+    btn.pack(anchor=Tix.CENTER)
+    top.pack(expand=1, fill=Tix.BOTH)
+    bot.pack(fill=Tix.BOTH)
+    list.bind('<Map>', func=lambda arg=0, rh=rh, list=list:
+              list.tk.call('tixDoWhenIdle', str(rh), 'attachwidget', str(list)))
+
+def SList_reset(rh, list):
+    list.place(x=50, y=150, width=120, height=80)
+    list.update()
+    rh.attach_widget(list)
+
+def MkSWindow(w):
+    """The ScrolledWindow widget allows you to scroll any kind of Tk
+    widget. It is more versatile than a scrolled canvas widget.
+    """
+    global demo
+
+    text = 'The Tix ScrolledWindow widget allows you to scroll any kind of Tk widget. It is more versatile than a scrolled canvas widget.'
+
+    file = os.path.join(demo.dir, 'bitmaps', 'tix.gif')
+    if not os.path.isfile(file):
+        text += ' (Image missing)'
+
+    top = Tix.Frame(w, width=330, height=330)
+    bot = Tix.Frame(w)
+    msg = Tix.Message(top,
+                      relief=Tix.FLAT, width=200, anchor=Tix.N,
+                      text=text)
+
+    win = Tix.ScrolledWindow(top, scrollbar='auto')
+
+    image1 = win.window.image_create('photo', file=file)
+    lbl = Tix.Label(win.window, image=image1)
+    lbl.pack(expand=1, fill=Tix.BOTH)
+
+    win.place(x=30, y=150, width=190, height=120)
+
+    rh = Tix.ResizeHandle(top, bg='black',
+                          relief=Tix.RAISED,
+                          handlesize=8, gridded=1, minwidth=50, minheight=30)
+    btn = Tix.Button(bot, text='Reset', command=lambda w=rh, x=win: SWindow_reset(w,x))
+    top.propagate(0)
+    msg.pack(fill=Tix.X)
+    btn.pack(anchor=Tix.CENTER)
+    top.pack(expand=1, fill=Tix.BOTH)
+    bot.pack(fill=Tix.BOTH)
+
+    win.bind('<Map>', func=lambda arg=0, rh=rh, win=win:
+             win.tk.call('tixDoWhenIdle', str(rh), 'attachwidget', str(win)))
+
+def SWindow_reset(rh, win):
+    win.place(x=30, y=150, width=190, height=120)
+    win.update()
+    rh.attach_widget(win)
+
+def MkSText(w):
+    """The TixScrolledWindow widget allows you to scroll any kind of Tk
+    widget. It is more versatile than a scrolled canvas widget."""
+    top = Tix.Frame(w, width=330, height=330)
+    bot = Tix.Frame(w)
+    msg = Tix.Message(top,
+                      relief=Tix.FLAT, width=200, anchor=Tix.N,
+                      text='The Tix ScrolledWindow widget allows you to scroll any kind of Tk widget. It is more versatile than a scrolled canvas widget.')
+
+    win = Tix.ScrolledText(top, scrollbar='auto')
+    win.text['wrap'] = 'none'
+    win.text.insert(Tix.END, '''When -scrollbar is set to "auto", the
+scrollbars are shown only when needed.
+Additional modifiers can be used to force a
+scrollbar to be shown or hidden. For example,
+"auto -y" means the horizontal scrollbar
+should be shown when needed but the vertical
+scrollbar should always be hidden;
+"auto +x" means the vertical scrollbar
+should be shown when needed but the horizontal
+scrollbar should always be shown, and so on.'''
+)
+    win.place(x=30, y=150, width=190, height=100)
+
+    rh = Tix.ResizeHandle(top, bg='black',
+                          relief=Tix.RAISED,
+                          handlesize=8, gridded=1, minwidth=50, minheight=30)
+    btn = Tix.Button(bot, text='Reset', command=lambda w=rh, x=win: SText_reset(w,x))
+    top.propagate(0)
+    msg.pack(fill=Tix.X)
+    btn.pack(anchor=Tix.CENTER)
+    top.pack(expand=1, fill=Tix.BOTH)
+    bot.pack(fill=Tix.BOTH)
+    win.bind('<Map>', func=lambda arg=0, rh=rh, win=win:
+             win.tk.call('tixDoWhenIdle', str(rh), 'attachwidget', str(win)))
+
+def SText_reset(rh, win):
+    win.place(x=30, y=150, width=190, height=120)
+    win.update()
+    rh.attach_widget(win)
+
+def MkManager(nb, name):
+    w = nb.page(name)
+    options='label.padX 4'
+
+    pane = Tix.LabelFrame(w, label='Tix.PanedWindow', options=options)
+    note = Tix.LabelFrame(w, label='Tix.NoteBook', options=options)
+
+    MkPanedWindow(pane.frame)
+    MkNoteBook(note.frame)
+
+    pane.form(top=0, left=0, right=note, bottom=-1)
+    note.form(top=0, right=-1, bottom=-1)
+
+def MkPanedWindow(w):
+    """The PanedWindow widget allows the user to interactively manipulate
+    the sizes of several panes. The panes can be arranged either vertically
+    or horizontally.
+    """
+    msg = Tix.Message(w,
+                      relief=Tix.FLAT, width=240, anchor=Tix.N,
+                      text='The PanedWindow widget allows the user to interactively manipulate the sizes of several panes. The panes can be arranged either vertically or horizontally.')
+    group = Tix.LabelEntry(w, label='Newsgroup:', options='entry.width 25')
+    group.entry.insert(0,'comp.lang.python')
+    pane = Tix.PanedWindow(w, orientation='vertical')
+
+    p1 = pane.add('list', min=70, size=100)
+    p2 = pane.add('text', min=70)
+    list = Tix.ScrolledListBox(p1)
+    text = Tix.ScrolledText(p2)
+
+    list.listbox.insert(Tix.END, "  12324 Re: Tkinter is good for your health")
+    list.listbox.insert(Tix.END, "+ 12325 Re: Tkinter is good for your health")
+    list.listbox.insert(Tix.END, "+ 12326 Re: Tix is even better for your health (Was: Tkinter is good...)")
+    list.listbox.insert(Tix.END, "  12327 Re: Tix is even better for your health (Was: Tkinter is good...)")
+    list.listbox.insert(Tix.END, "+ 12328 Re: Tix is even better for your health (Was: Tkinter is good...)")
+    list.listbox.insert(Tix.END, "  12329 Re: Tix is even better for your health (Was: Tkinter is good...)")
+    list.listbox.insert(Tix.END, "+ 12330 Re: Tix is even better for your health (Was: Tkinter is good...)")
+
+    text.text['bg'] = list.listbox['bg']
+    text.text['wrap'] = 'none'
+    text.text.insert(Tix.END, """
+Mon, 19 Jun 1995 11:39:52        comp.lang.python              Thread   34 of  220
+Lines 353       A new way to put text and bitmaps together iNo responses
+ioi at blue.seas.upenn.edu                Ioi K. Lam at University of Pennsylvania
+
+Hi,
+
+I have implemented a new image type called "compound". It allows you
+to glue together a bunch of bitmaps, images and text strings together
+to form a bigger image. Then you can use this image with widgets that
+support the -image option. For example, you can display a text string string
+together with a bitmap, at the same time, inside a TK button widget.
+""")
+    list.pack(expand=1, fill=Tix.BOTH, padx=4, pady=6)
+    text.pack(expand=1, fill=Tix.BOTH, padx=4, pady=6)
+
+    msg.pack(side=Tix.TOP, padx=3, pady=3, fill=Tix.BOTH)
+    group.pack(side=Tix.TOP, padx=3, pady=3, fill=Tix.BOTH)
+    pane.pack(side=Tix.TOP, padx=3, pady=3, fill=Tix.BOTH, expand=1)
+
+def MkNoteBook(w):
+    msg = Tix.Message(w,
+                      relief=Tix.FLAT, width=240, anchor=Tix.N,
+                      text='The NoteBook widget allows you to layout a complex interface into individual pages.')
+    # prefix = Tix.OptionName(w)
+    # if not prefix: prefix = ''
+    # w.option_add('*' + prefix + '*TixNoteBook*tagPadX', 8)
+    options = "entry.width %d label.width %d label.anchor %s" % (10, 18, Tix.E)
+
+    nb = Tix.NoteBook(w, ipadx=6, ipady=6, options=options)
+    nb.add('hard_disk', label="Hard Disk", underline=0)
+    nb.add('network', label="Network", underline=0)
+
+    # Frame for the buttons that are present on all pages
+    common = Tix.Frame(nb.hard_disk)
+    common.pack(side=Tix.RIGHT, padx=2, pady=2, fill=Tix.Y)
+    CreateCommonButtons(common)
+
+    # Widgets belonging only to this page
+    a = Tix.Control(nb.hard_disk, value=12, label='Access Time: ')
+    w = Tix.Control(nb.hard_disk, value=400, label='Write Throughput: ')
+    r = Tix.Control(nb.hard_disk, value=400, label='Read Throughput: ')
+    c = Tix.Control(nb.hard_disk, value=1021, label='Capacity: ')
+    a.pack(side=Tix.TOP, padx=20, pady=2)
+    w.pack(side=Tix.TOP, padx=20, pady=2)
+    r.pack(side=Tix.TOP, padx=20, pady=2)
+    c.pack(side=Tix.TOP, padx=20, pady=2)
+
+    common = Tix.Frame(nb.network)
+    common.pack(side=Tix.RIGHT, padx=2, pady=2, fill=Tix.Y)
+    CreateCommonButtons(common)
+
+    a = Tix.Control(nb.network, value=12, label='Access Time: ')
+    w = Tix.Control(nb.network, value=400, label='Write Throughput: ')
+    r = Tix.Control(nb.network, value=400, label='Read Throughput: ')
+    c = Tix.Control(nb.network, value=1021, label='Capacity: ')
+    u = Tix.Control(nb.network, value=10, label='Users: ')
+    a.pack(side=Tix.TOP, padx=20, pady=2)
+    w.pack(side=Tix.TOP, padx=20, pady=2)
+    r.pack(side=Tix.TOP, padx=20, pady=2)
+    c.pack(side=Tix.TOP, padx=20, pady=2)
+    u.pack(side=Tix.TOP, padx=20, pady=2)
+
+    msg.pack(side=Tix.TOP, padx=3, pady=3, fill=Tix.BOTH)
+    nb.pack(side=Tix.TOP, padx=5, pady=5, fill=Tix.BOTH, expand=1)
+
+def CreateCommonButtons(f):
+    ok = Tix.Button(f, text='OK', width = 6)
+    cancel = Tix.Button(f, text='Cancel', width = 6)
+    ok.pack(side=Tix.TOP, padx=2, pady=2)
+    cancel.pack(side=Tix.TOP, padx=2, pady=2)
+
+def MkDirList(nb, name):
+    w = nb.page(name)
+    options = "label.padX 4"
+
+    dir = Tix.LabelFrame(w, label='Tix.DirList', options=options)
+    fsbox = Tix.LabelFrame(w, label='Tix.ExFileSelectBox', options=options)
+    MkDirListWidget(dir.frame)
+    MkExFileWidget(fsbox.frame)
+    dir.form(top=0, left=0, right='%40', bottom=-1)
+    fsbox.form(top=0, left='%40', right=-1, bottom=-1)
+
+def MkDirListWidget(w):
+    """The TixDirList widget gives a graphical representation of the file
+    system directory and makes it easy for the user to choose and access
+    directories.
+    """
+    msg = Tix.Message(w,
+                      relief=Tix.FLAT, width=240, anchor=Tix.N,
+                      text='The Tix DirList widget gives a graphical representation of the file system directory and makes it easy for the user to choose and access directories.')
+    dirlist = Tix.DirList(w, options='hlist.padY 1 hlist.width 25 hlist.height 16')
+    msg.pack(side=Tix.TOP, expand=1, fill=Tix.BOTH, padx=3, pady=3)
+    dirlist.pack(side=Tix.TOP, padx=3, pady=3)
+
+def MkExFileWidget(w):
+    """The TixExFileSelectBox widget is more user friendly than the Motif
+    style FileSelectBox.  """
+    msg = Tix.Message(w,
+                      relief=Tix.FLAT, width=240, anchor=Tix.N,
+                      text='The Tix ExFileSelectBox widget is more user friendly than the Motif style FileSelectBox.')
+    # There's a bug in the ComboBoxes - the scrolledlistbox is destroyed
+    box = Tix.ExFileSelectBox(w, bd=2, relief=Tix.RAISED)
+    msg.pack(side=Tix.TOP, expand=1, fill=Tix.BOTH, padx=3, pady=3)
+    box.pack(side=Tix.TOP, padx=3, pady=3)
+
+###
+### List of all the demos we want to show off
+comments = {'widget' : 'Widget Demos', 'image' : 'Image Demos'}
+samples = {'Balloon'            : 'Balloon',
+           'Button Box'         : 'BtnBox',
+           'Combo Box'          : 'ComboBox',
+           'Compound Image'     : 'CmpImg',
+           'Directory List'     : 'DirList',
+           'Directory Tree'     : 'DirTree',
+           'Control'            : 'Control',
+           'Notebook'           : 'NoteBook',
+           'Option Menu'        : 'OptMenu',
+           'Paned Window'       : 'PanedWin',
+           'Popup Menu'         : 'PopMenu',
+           'ScrolledHList (1)'  : 'SHList1',
+           'ScrolledHList (2)'  : 'SHList2',
+           'Tree (dynamic)'     : 'Tree'
+}
+
+# There are still a lot of demos to be translated:
+##      set root {
+##          {d "File Selectors"         file    }
+##          {d "Hierachical ListBox"    hlist   }
+##          {d "Tabular ListBox"        tlist   {c tixTList}}
+##          {d "Grid Widget"            grid    {c tixGrid}}
+##          {d "Manager Widgets"        manager }
+##          {d "Scrolled Widgets"       scroll  }
+##          {d "Miscellaneous Widgets"  misc    }
+##          {d "Image Types"            image   }
+##      }
+##
+##      set image {
+##          {d "Compound Image"         cmpimg  }
+##          {d "XPM Image"              xpm     {i pixmap}}
+##      }
+##
+##      set cmpimg {
+##done      {f "In Buttons"             CmpImg.tcl      }
+##          {f "In NoteBook"            CmpImg2.tcl     }
+##          {f "Notebook Color Tabs"    CmpImg4.tcl     }
+##          {f "Icons"                  CmpImg3.tcl     }
+##      }
+##
+##      set xpm {
+##          {f "In Button"              Xpm.tcl         {i pixmap}}
+##          {f "In Menu"                Xpm1.tcl        {i pixmap}}
+##      }
+##
+##      set file {
+##added     {f DirList                          DirList.tcl     }
+##added     {f DirTree                          DirTree.tcl     }
+##          {f DirSelectDialog                  DirDlg.tcl      }
+##          {f ExFileSelectDialog               EFileDlg.tcl    }
+##          {f FileSelectDialog                 FileDlg.tcl     }
+##          {f FileEntry                        FileEnt.tcl     }
+##      }
+##
+##      set hlist {
+##          {f HList                    HList1.tcl      }
+##          {f CheckList                ChkList.tcl     {c tixCheckList}}
+##done      {f "ScrolledHList (1)"      SHList.tcl      }
+##done      {f "ScrolledHList (2)"      SHList2.tcl     }
+##done      {f Tree                     Tree.tcl        }
+##done      {f "Tree (Dynamic)"         DynTree.tcl     {v win}}
+##      }
+##
+##      set tlist {
+##          {f "ScrolledTList (1)"      STList1.tcl     {c tixTList}}
+##          {f "ScrolledTList (2)"      STList2.tcl     {c tixTList}}
+##      }
+##      global tcl_platform
+##      #  This demo hangs windows
+##      if {$tcl_platform(platform) != "windows"} {
+##na    lappend tlist     {f "TList File Viewer"        STList3.tcl     {c tixTList}}
+##      }
+##
+##      set grid {
+##na        {f "Simple Grid"            SGrid0.tcl      {c tixGrid}}
+##na        {f "ScrolledGrid"           SGrid1.tcl      {c tixGrid}}
+##na        {f "Editable Grid"          EditGrid.tcl    {c tixGrid}}
+##      }
+##
+##      set scroll {
+##          {f ScrolledListBox          SListBox.tcl    }
+##          {f ScrolledText             SText.tcl       }
+##          {f ScrolledWindow           SWindow.tcl     }
+##na        {f "Canvas Object View"     CObjView.tcl    {c tixCObjView}}
+##      }
+##
+##      set manager {
+##          {f ListNoteBook             ListNBK.tcl     }
+##done      {f NoteBook                 NoteBook.tcl    }
+##done      {f PanedWindow              PanedWin.tcl    }
+##      }
+##
+##      set misc {
+##done      {f Balloon                  Balloon.tcl     }
+##done      {f ButtonBox                BtnBox.tcl      }
+##done      {f ComboBox                 ComboBox.tcl    }
+##done      {f Control                  Control.tcl     }
+##          {f LabelEntry               LabEntry.tcl    }
+##          {f LabelFrame               LabFrame.tcl    }
+##          {f Meter                    Meter.tcl       {c tixMeter}}
+##done      {f OptionMenu               OptMenu.tcl     }
+##done      {f PopupMenu                PopMenu.tcl     }
+##          {f Select                   Select.tcl      }
+##          {f StdButtonBox             StdBBox.tcl     }
+##      }
+##
+
+stypes = {}
+stypes['widget'] = ['Balloon', 'Button Box', 'Combo Box', 'Control',
+                    'Directory List', 'Directory Tree',
+                    'Notebook', 'Option Menu', 'Popup Menu', 'Paned Window',
+                    'ScrolledHList (1)', 'ScrolledHList (2)', 'Tree (dynamic)']
+stypes['image'] = ['Compound Image']
+
+def MkSample(nb, name):
+    w = nb.page(name)
+    options = "label.padX 4"
+
+    pane = Tix.PanedWindow(w, orientation='horizontal')
+    pane.pack(side=Tix.TOP, expand=1, fill=Tix.BOTH)
+    f1 = pane.add('list', expand='1')
+    f2 = pane.add('text', expand='5')
+    f1['relief'] = 'flat'
+    f2['relief'] = 'flat'
+
+    lab = Tix.LabelFrame(f1, label='Select a sample program:')
+    lab.pack(side=Tix.TOP, expand=1, fill=Tix.BOTH, padx=5, pady=5)
+    lab1 = Tix.LabelFrame(f2, label='Source:')
+    lab1.pack(side=Tix.TOP, expand=1, fill=Tix.BOTH, padx=5, pady=5)
+
+    slb = Tix.Tree(lab.frame, options='hlist.width 20')
+    slb.pack(side=Tix.TOP, expand=1, fill=Tix.BOTH, padx=5)
+
+    stext = Tix.ScrolledText(lab1.frame, name='stext')
+    font = root.tk.eval('tix option get fixed_font')
+    stext.text.config(font=font)
+
+    frame = Tix.Frame(lab1.frame, name='frame')
+
+    run = Tix.Button(frame, text='Run ...', name='run')
+    view = Tix.Button(frame, text='View Source ...', name='view')
+    run.pack(side=Tix.LEFT, expand=0, fill=Tix.NONE)
+    view.pack(side=Tix.LEFT, expand=0, fill=Tix.NONE)
+
+    stext.text['bg'] = slb.hlist['bg']
+    stext.text['state'] = 'disabled'
+    stext.text['wrap'] = 'none'
+    stext.text['width'] = 80
+
+    frame.pack(side=Tix.BOTTOM, expand=0, fill=Tix.X, padx=7)
+    stext.pack(side=Tix.TOP, expand=0, fill=Tix.BOTH, padx=7)
+
+    slb.hlist['separator'] = '.'
+    slb.hlist['width'] = 25
+    slb.hlist['drawbranch'] = 0
+    slb.hlist['indent'] = 10
+    slb.hlist['wideselect'] = 1
+    slb.hlist['command'] = lambda args=0, w=w,slb=slb,stext=stext,run=run,view=view: Sample_Action(w, slb, stext, run, view, 'run')
+    slb.hlist['browsecmd'] = lambda args=0, w=w,slb=slb,stext=stext,run=run,view=view: Sample_Action(w, slb, stext, run, view, 'browse')
+
+    run['command']      = lambda args=0, w=w,slb=slb,stext=stext,run=run,view=view: Sample_Action(w, slb, stext, run, view, 'run')
+    view['command'] = lambda args=0, w=w,slb=slb,stext=stext,run=run,view=view: Sample_Action(w, slb, stext, run, view, 'view')
+
+    for type in ['widget', 'image']:
+        if type != 'widget':
+            x = Tix.Frame(slb.hlist, bd=2, height=2, width=150,
+                          relief=Tix.SUNKEN, bg=slb.hlist['bg'])
+            slb.hlist.add_child(itemtype=Tix.WINDOW, window=x, state='disabled')
+        x = slb.hlist.add_child(itemtype=Tix.TEXT, state='disabled',
+                                text=comments[type])
+        for key in stypes[type]:
+            slb.hlist.add_child(x, itemtype=Tix.TEXT, data=key,
+                                text=key)
+    slb.hlist.selection_clear()
+
+    run['state'] = 'disabled'
+    view['state'] = 'disabled'
+
+def Sample_Action(w, slb, stext, run, view, action):
+    global demo
+
+    hlist = slb.hlist
+    anchor = hlist.info_anchor()
+    if not anchor:
+        run['state'] = 'disabled'
+        view['state'] = 'disabled'
+    elif not hlist.info_parent(anchor):
+        # a comment
+        return
+
+    run['state'] = 'normal'
+    view['state'] = 'normal'
+    key = hlist.info_data(anchor)
+    title = key
+    prog = samples[key]
+
+    if action == 'run':
+        exec('import ' + prog)
+        w = Tix.Toplevel()
+        w.title(title)
+        rtn = eval(prog + '.RunSample')
+        rtn(w)
+    elif action == 'view':
+        w = Tix.Toplevel()
+        w.title('Source view: ' + title)
+        LoadFile(w, demo.dir + '/samples/' + prog + '.py')
+    elif action == 'browse':
+        ReadFile(stext.text, demo.dir + '/samples/' + prog + '.py')
+
+def LoadFile(w, fname):
+    global root
+    b = Tix.Button(w, text='Close', command=w.destroy)
+    t = Tix.ScrolledText(w)
+    #    b.form(left=0, bottom=0, padx=4, pady=4)
+    #    t.form(left=0, bottom=b, right='-0', top=0)
+    t.pack()
+    b.pack()
+
+    font = root.tk.eval('tix option get fixed_font')
+    t.text.config(font=font)
+    t.text['bd'] = 2
+    t.text['wrap'] = 'none'
+
+    ReadFile(t.text, fname)
+
+def ReadFile(w, fname):
+    old_state = w['state']
+    w['state'] = 'normal'
+    w.delete('0.0', Tix.END)
+
+    try:
+        f = open(fname)
+        lines = f.readlines()
+        for s in lines:
+            w.insert(Tix.END, s)
+        f.close()
+    finally:
+#       w.see('1.0')
+        w['state'] = old_state
+
+if __name__ == '__main__':
+    root = Tix.Tk()
+    RunMain(root)

Added: vendor/Python/current/Demo/tkinter/README
===================================================================
--- vendor/Python/current/Demo/tkinter/README	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/README	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,10 @@
+Several collections of example code for Tkinter.
+
+See the toplevel README for an explanation of the difference between
+Tkinter and _tkinter, how to enable the Python Tk interface, and where
+to get Matt Conway's lifesaver document.
+
+Subdirectories:
+
+guido		my original example set (fairly random collection)
+matt		Matt Conway's examples, to go with his lifesaver document

Added: vendor/Python/current/Demo/tkinter/guido/AttrDialog.py
===================================================================
--- vendor/Python/current/Demo/tkinter/guido/AttrDialog.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/guido/AttrDialog.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,452 @@
+
+# The options of a widget are described by the following attributes
+# of the Pack and Widget dialogs:
+#
+# Dialog.current: {name: value}
+# -- changes during Widget's lifetime
+#
+# Dialog.options: {name: (default, klass)}
+# -- depends on widget class only
+#
+# Dialog.classes: {klass: (v0, v1, v2, ...) | 'boolean' | 'other'}
+# -- totally static, though different between PackDialog and WidgetDialog
+#    (but even that could be unified)
+
+from Tkinter import *
+
+class Option:
+
+    varclass = StringVar            # May be overridden
+
+    def __init__(self, dialog, option):
+        self.dialog = dialog
+        self.option = option
+        self.master = dialog.top
+        self.default, self.klass = dialog.options[option]
+        self.var = self.varclass(self.master)
+        self.frame = Frame(self.master)
+        self.frame.pack(fill=X)
+        self.label = Label(self.frame, text=(option + ":"))
+        self.label.pack(side=LEFT)
+        self.update()
+        self.addoption()
+
+    def refresh(self):
+        self.dialog.refresh()
+        self.update()
+
+    def update(self):
+        try:
+            self.current = self.dialog.current[self.option]
+        except KeyError:
+            self.current = self.default
+        self.var.set(self.current)
+
+    def set(self, e=None):          # Should be overridden
+        pass
+
+class BooleanOption(Option):
+
+    varclass = BooleanVar
+
+    def addoption(self):
+        self.button = Checkbutton(self.frame,
+                                 text='on/off',
+                                 onvalue=1,
+                                 offvalue=0,
+                                 variable=self.var,
+                                 relief=RAISED,
+                                 borderwidth=2,
+                                 command=self.set)
+        self.button.pack(side=RIGHT)
+
+class EnumOption(Option):
+
+    def addoption(self):
+        self.button = Menubutton(self.frame,
+                                 textvariable=self.var,
+                                 relief=RAISED, borderwidth=2)
+        self.button.pack(side=RIGHT)
+        self.menu = Menu(self.button)
+        self.button['menu'] = self.menu
+        for v in self.dialog.classes[self.klass]:
+            self.menu.add_radiobutton(
+                label=v,
+                variable=self.var,
+                value=v,
+                command=self.set)
+
+class StringOption(Option):
+
+    def addoption(self):
+        self.entry = Entry(self.frame,
+                           textvariable=self.var,
+                           width=10,
+                           relief=SUNKEN,
+                           borderwidth=2)
+        self.entry.pack(side=RIGHT, fill=X, expand=1)
+        self.entry.bind('<Return>', self.set)
+
+class ReadonlyOption(Option):
+
+    def addoption(self):
+        self.label = Label(self.frame, textvariable=self.var,
+                           anchor=E)
+        self.label.pack(side=RIGHT)
+
+class Dialog:
+
+    def __init__(self, master):
+        self.master = master
+        self.fixclasses()
+        self.refresh()
+        self.top = Toplevel(self.master)
+        self.top.title(self.__class__.__name__)
+        self.top.minsize(1, 1)
+        self.addchoices()
+
+    def refresh(self): pass         # Must override
+
+    def fixclasses(self): pass      # May override
+
+    def addchoices(self):
+        self.choices = {}
+        list = []
+        for k, dc in self.options.items():
+            list.append((k, dc))
+        list.sort()
+        for k, (d, c) in list:
+            try:
+                cl = self.classes[c]
+            except KeyError:
+                cl = 'unknown'
+            if type(cl) == TupleType:
+                cl = self.enumoption
+            elif cl == 'boolean':
+                cl = self.booleanoption
+            elif cl == 'readonly':
+                cl = self.readonlyoption
+            else:
+                cl = self.stringoption
+            self.choices[k] = cl(self, k)
+
+    # Must override:
+    options = {}
+    classes = {}
+
+    # May override:
+    booleanoption = BooleanOption
+    stringoption = StringOption
+    enumoption = EnumOption
+    readonlyoption = ReadonlyOption
+
+class PackDialog(Dialog):
+
+    def __init__(self, widget):
+        self.widget = widget
+        Dialog.__init__(self, widget)
+
+    def refresh(self):
+        self.current = self.widget.info()
+        self.current['.class'] = self.widget.winfo_class()
+        self.current['.name'] = self.widget._w
+
+    class packoption: # Mix-in class
+        def set(self, e=None):
+            self.current = self.var.get()
+            try:
+                apply(self.dialog.widget.pack, (),
+                      {self.option: self.current})
+            except TclError, msg:
+                print msg
+                self.refresh()
+
+    class booleanoption(packoption, BooleanOption): pass
+    class enumoption(packoption, EnumOption): pass
+    class stringoption(packoption, StringOption): pass
+    class readonlyoption(packoption, ReadonlyOption): pass
+
+    options = {
+            '.class': (None, 'Class'),
+            '.name': (None, 'Name'),
+            'after': (None, 'Widget'),
+            'anchor': ('center', 'Anchor'),
+            'before': (None, 'Widget'),
+            'expand': ('no', 'Boolean'),
+            'fill': ('none', 'Fill'),
+            'in': (None, 'Widget'),
+            'ipadx': (0, 'Pad'),
+            'ipady': (0, 'Pad'),
+            'padx': (0, 'Pad'),
+            'pady': (0, 'Pad'),
+            'side': ('top', 'Side'),
+            }
+
+    classes = {
+            'Anchor': (N, NE, E, SE, S, SW, W, NW, CENTER),
+            'Boolean': 'boolean',
+            'Class': 'readonly',
+            'Expand': 'boolean',
+            'Fill': (NONE, X, Y, BOTH),
+            'Name': 'readonly',
+            'Pad': 'pixel',
+            'Side': (TOP, RIGHT, BOTTOM, LEFT),
+            'Widget': 'readonly',
+            }
+
+class RemotePackDialog(PackDialog):
+
+    def __init__(self, master, app, widget):
+        self.master = master
+        self.app = app
+        self.widget = widget
+        self.refresh()
+        self.top = Toplevel(self.master)
+        self.top.title(self.app + ' PackDialog')
+        self.top.minsize(1, 1)
+        self.addchoices()
+
+    def refresh(self):
+        try:
+            words = self.master.tk.splitlist(
+                    self.master.send(self.app,
+                                     'pack',
+                                     'info',
+                                     self.widget))
+        except TclError, msg:
+            print msg
+            return
+        dict = {}
+        for i in range(0, len(words), 2):
+            key = words[i][1:]
+            value = words[i+1]
+            dict[key] = value
+        dict['.class'] = self.master.send(self.app,
+                                          'winfo',
+                                          'class',
+                                          self.widget)
+        dict['.name'] = self.widget
+        self.current = dict
+
+    class remotepackoption: # Mix-in class
+        def set(self, e=None):
+            self.current = self.var.get()
+            try:
+                self.dialog.master.send(
+                        self.dialog.app,
+                        'pack',
+                        'config',
+                        self.dialog.widget,
+                        '-'+self.option,
+                        self.dialog.master.tk.merge(
+                                self.current))
+            except TclError, msg:
+                print msg
+                self.refresh()
+
+    class booleanoption(remotepackoption, BooleanOption): pass
+    class enumoption(remotepackoption, EnumOption): pass
+    class stringoption(remotepackoption, StringOption): pass
+    class readonlyoption(remotepackoption, ReadonlyOption): pass
+
+class WidgetDialog(Dialog):
+
+    def __init__(self, widget):
+        self.widget = widget
+        self.klass = widget.winfo_class()
+        Dialog.__init__(self, widget)
+
+    def fixclasses(self):
+        if self.addclasses.has_key(self.klass):
+            classes = {}
+            for c in (self.classes,
+                      self.addclasses[self.klass]):
+                for k in c.keys():
+                    classes[k] = c[k]
+            self.classes = classes
+
+    def refresh(self):
+        self.configuration = self.widget.config()
+        self.update()
+        self.current['.class'] = self.widget.winfo_class()
+        self.current['.name'] = self.widget._w
+
+    def update(self):
+        self.current = {}
+        self.options = {}
+        for k, v in self.configuration.items():
+            if len(v) > 4:
+                self.current[k] = v[4]
+                self.options[k] = v[3], v[2] # default, klass
+        self.options['.class'] = (None, 'Class')
+        self.options['.name'] = (None, 'Name')
+
+    class widgetoption: # Mix-in class
+        def set(self, e=None):
+            self.current = self.var.get()
+            try:
+                self.dialog.widget[self.option] = self.current
+            except TclError, msg:
+                print msg
+                self.refresh()
+
+    class booleanoption(widgetoption, BooleanOption): pass
+    class enumoption(widgetoption, EnumOption): pass
+    class stringoption(widgetoption, StringOption): pass
+    class readonlyoption(widgetoption, ReadonlyOption): pass
+
+    # Universal classes
+    classes = {
+            'Anchor': (N, NE, E, SE, S, SW, W, NW, CENTER),
+            'Aspect': 'integer',
+            'Background': 'color',
+            'Bitmap': 'bitmap',
+            'BorderWidth': 'pixel',
+            'Class': 'readonly',
+            'CloseEnough': 'double',
+            'Command': 'command',
+            'Confine': 'boolean',
+            'Cursor': 'cursor',
+            'CursorWidth': 'pixel',
+            'DisabledForeground': 'color',
+            'ExportSelection': 'boolean',
+            'Font': 'font',
+            'Foreground': 'color',
+            'From': 'integer',
+            'Geometry': 'geometry',
+            'Height': 'pixel',
+            'InsertWidth': 'time',
+            'Justify': (LEFT, CENTER, RIGHT),
+            'Label': 'string',
+            'Length': 'pixel',
+            'MenuName': 'widget',
+            'Name': 'readonly',
+            'OffTime': 'time',
+            'OnTime': 'time',
+            'Orient': (HORIZONTAL, VERTICAL),
+            'Pad': 'pixel',
+            'Relief': (RAISED, SUNKEN, FLAT, RIDGE, GROOVE),
+            'RepeatDelay': 'time',
+            'RepeatInterval': 'time',
+            'ScrollCommand': 'command',
+            'ScrollIncrement': 'pixel',
+            'ScrollRegion': 'rectangle',
+            'ShowValue': 'boolean',
+            'SetGrid': 'boolean',
+            'Sliderforeground': 'color',
+            'SliderLength': 'pixel',
+            'Text': 'string',
+            'TickInterval': 'integer',
+            'To': 'integer',
+            'Underline': 'index',
+            'Variable': 'variable',
+            'Value': 'string',
+            'Width': 'pixel',
+            'Wrap': (NONE, CHAR, WORD),
+            }
+
+    # Classes that (may) differ per widget type
+    _tristate = {'State': (NORMAL, ACTIVE, DISABLED)}
+    _bistate = {'State': (NORMAL, DISABLED)}
+    addclasses = {
+            'Button': _tristate,
+            'Radiobutton': _tristate,
+            'Checkbutton': _tristate,
+            'Entry': _bistate,
+            'Text': _bistate,
+            'Menubutton': _tristate,
+            'Slider': _bistate,
+            }
+
+class RemoteWidgetDialog(WidgetDialog):
+
+    def __init__(self, master, app, widget):
+        self.app = app
+        self.widget = widget
+        self.klass = master.send(self.app,
+                                 'winfo',
+                                 'class',
+                                 self.widget)
+        Dialog.__init__(self, master)
+
+    def refresh(self):
+        try:
+            items = self.master.tk.splitlist(
+                    self.master.send(self.app,
+                                     self.widget,
+                                     'config'))
+        except TclError, msg:
+            print msg
+            return
+        dict = {}
+        for item in items:
+            words = self.master.tk.splitlist(item)
+            key = words[0][1:]
+            value = (key,) + words[1:]
+            dict[key] = value
+        self.configuration = dict
+        self.update()
+        self.current['.class'] = self.klass
+        self.current['.name'] = self.widget
+
+    class remotewidgetoption: # Mix-in class
+        def set(self, e=None):
+            self.current = self.var.get()
+            try:
+                self.dialog.master.send(
+                        self.dialog.app,
+                        self.dialog.widget,
+                        'config',
+                        '-'+self.option,
+                        self.current)
+            except TclError, msg:
+                print msg
+                self.refresh()
+
+    class booleanoption(remotewidgetoption, BooleanOption): pass
+    class enumoption(remotewidgetoption, EnumOption): pass
+    class stringoption(remotewidgetoption, StringOption): pass
+    class readonlyoption(remotewidgetoption, ReadonlyOption): pass
+
+def test():
+    import sys
+    root = Tk()
+    root.minsize(1, 1)
+    if sys.argv[1:]:
+        remotetest(root, sys.argv[1])
+    else:
+        frame = Frame(root, name='frame')
+        frame.pack(expand=1, fill=BOTH)
+        button = Button(frame, name='button', text='button')
+        button.pack(expand=1)
+        canvas = Canvas(frame, name='canvas')
+        canvas.pack()
+        fpd = PackDialog(frame)
+        fwd = WidgetDialog(frame)
+        bpd = PackDialog(button)
+        bwd = WidgetDialog(button)
+        cpd = PackDialog(canvas)
+        cwd = WidgetDialog(canvas)
+    root.mainloop()
+
+def remotetest(root, app):
+    from listtree import listtree
+    list = listtree(root, app)
+    list.bind('<Any-Double-1>', opendialogs)
+    list.app = app                  # Pass it on to handler
+
+def opendialogs(e):
+    import string
+    list = e.widget
+    sel = list.curselection()
+    for i in sel:
+        item = list.get(i)
+        widget = string.split(item)[0]
+        RemoteWidgetDialog(list, list.app, widget)
+        if widget == '.': continue
+        try:
+            RemotePackDialog(list, list.app, widget)
+        except TclError, msg:
+            print msg
+
+test()


Property changes on: vendor/Python/current/Demo/tkinter/guido/AttrDialog.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tkinter/guido/ManPage.py
===================================================================
--- vendor/Python/current/Demo/tkinter/guido/ManPage.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/guido/ManPage.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,220 @@
+# Widget to display a man page
+
+import re
+from Tkinter import *
+from Tkinter import _tkinter
+from ScrolledText import ScrolledText
+
+# XXX These fonts may have to be changed to match your system
+BOLDFONT = '*-Courier-Bold-R-Normal-*-120-*'
+ITALICFONT = '*-Courier-Medium-O-Normal-*-120-*'
+
+# XXX Recognizing footers is system dependent
+# (This one works for IRIX 5.2 and Solaris 2.2)
+footerprog = re.compile(
+        '^     Page [1-9][0-9]*[ \t]+\|^.*Last change:.*[1-9][0-9]*\n')
+emptyprog = re.compile('^[ \t]*\n')
+ulprog = re.compile('^[ \t]*[Xv!_][Xv!_ \t]*\n')
+
+# Basic Man Page class -- does not disable editing
+class EditableManPage(ScrolledText):
+
+    # Initialize instance
+    def __init__(self, master=None, **cnf):
+        # Initialize base class
+        apply(ScrolledText.__init__, (self, master), cnf)
+
+        # Define tags for formatting styles
+        self.tag_config('X', underline=1)
+        self.tag_config('!', font=BOLDFONT)
+        self.tag_config('_', font=ITALICFONT)
+
+        # Set state to idle
+        self.fp = None
+        self.lineno = 0
+
+    # Test whether we are busy parsing a file
+    def busy(self):
+        return self.fp != None
+
+    # Ensure we're not busy
+    def kill(self):
+        if self.busy():
+            self._endparser()
+
+    # Parse a file, in the background
+    def asyncparsefile(self, fp):
+        self._startparser(fp)
+        self.tk.createfilehandler(fp, _tkinter.READABLE,
+                                  self._filehandler)
+
+    parsefile = asyncparsefile      # Alias
+
+    # I/O handler used by background parsing
+    def _filehandler(self, fp, mask):
+        nextline = self.fp.readline()
+        if not nextline:
+            self._endparser()
+            return
+        self._parseline(nextline)
+
+    # Parse a file, now (cannot be aborted)
+    def syncparsefile(self, fp):
+        from select import select
+        def avail(fp=fp, tout=0.0, select=select):
+            return select([fp], [], [], tout)[0]
+        height = self.getint(self['height'])
+        self._startparser(fp)
+        while 1:
+            nextline = fp.readline()
+            if not nextline:
+                break
+            self._parseline(nextline)
+        self._endparser()
+
+    # Initialize parsing from a particular file -- must not be busy
+    def _startparser(self, fp):
+        if self.busy():
+            raise RuntimeError, 'startparser: still busy'
+        fp.fileno()             # Test for file-ness
+        self.fp = fp
+        self.lineno = 0
+        self.ok = 0
+        self.empty = 0
+        self.buffer = None
+        savestate = self['state']
+        self['state'] = NORMAL
+        self.delete('1.0', END)
+        self['state'] = savestate
+
+    # End parsing -- must be busy, need not be at EOF
+    def _endparser(self):
+        if not self.busy():
+            raise RuntimeError, 'endparser: not busy'
+        if self.buffer:
+            self._parseline('')
+        try:
+            self.tk.deletefilehandler(self.fp)
+        except TclError, msg:
+            pass
+        self.fp.close()
+        self.fp = None
+        del self.ok, self.empty, self.buffer
+
+    # Parse a single line
+    def _parseline(self, nextline):
+        if not self.buffer:
+            # Save this line -- we need one line read-ahead
+            self.buffer = nextline
+            return
+        if emptyprog.match(self.buffer) >= 0:
+            # Buffered line was empty -- set a flag
+            self.empty = 1
+            self.buffer = nextline
+            return
+        textline = self.buffer
+        if ulprog.match(nextline) >= 0:
+            # Next line is properties for buffered line
+            propline = nextline
+            self.buffer = None
+        else:
+            # Next line is read-ahead
+            propline = None
+            self.buffer = nextline
+        if not self.ok:
+            # First non blank line after footer must be header
+            # -- skip that too
+            self.ok = 1
+            self.empty = 0
+            return
+        if footerprog.match(textline) >= 0:
+            # Footer -- start skipping until next non-blank line
+            self.ok = 0
+            self.empty = 0
+            return
+        savestate = self['state']
+        self['state'] = NORMAL
+        if TkVersion >= 4.0:
+            self.mark_set('insert', 'end-1c')
+        else:
+            self.mark_set('insert', END)
+        if self.empty:
+            # One or more previous lines were empty
+            # -- insert one blank line in the text
+            self._insert_prop('\n')
+            self.lineno = self.lineno + 1
+            self.empty = 0
+        if not propline:
+            # No properties
+            self._insert_prop(textline)
+        else:
+            # Search for properties
+            p = ''
+            j = 0
+            for i in range(min(len(propline), len(textline))):
+                if propline[i] != p:
+                    if j < i:
+                        self._insert_prop(textline[j:i], p)
+                        j = i
+                    p = propline[i]
+            self._insert_prop(textline[j:])
+        self.lineno = self.lineno + 1
+        self['state'] = savestate
+
+    # Insert a string at the end, with at most one property (tag)
+    def _insert_prop(self, str, prop = ' '):
+        here = self.index(AtInsert())
+        self.insert(AtInsert(), str)
+        if TkVersion <= 4.0:
+            tags = self.tag_names(here)
+            for tag in tags:
+                self.tag_remove(tag, here, AtInsert())
+        if prop != ' ':
+            self.tag_add(prop, here, AtInsert())
+
+# Readonly Man Page class -- disables editing, otherwise the same
+class ReadonlyManPage(EditableManPage):
+
+    # Initialize instance
+    def __init__(self, master=None, **cnf):
+        cnf['state'] = DISABLED
+        apply(EditableManPage.__init__, (self, master), cnf)
+
+# Alias
+ManPage = ReadonlyManPage
+
+# Test program.
+# usage: ManPage [manpage]; or ManPage [-f] file
+# -f means that the file is nroff -man output run through ul -i
+def test():
+    import os
+    import sys
+    # XXX This directory may be different on your system
+    MANDIR = '/usr/local/man/mann'
+    DEFAULTPAGE = 'Tcl'
+    formatted = 0
+    if sys.argv[1:] and sys.argv[1] == '-f':
+        formatted = 1
+        del sys.argv[1]
+    if sys.argv[1:]:
+        name = sys.argv[1]
+    else:
+        name = DEFAULTPAGE
+    if not formatted:
+        if name[-2:-1] != '.':
+            name = name + '.n'
+        name = os.path.join(MANDIR, name)
+    root = Tk()
+    root.minsize(1, 1)
+    manpage = ManPage(root, relief=SUNKEN, borderwidth=2)
+    manpage.pack(expand=1, fill=BOTH)
+    if formatted:
+        fp = open(name, 'r')
+    else:
+        fp = os.popen('nroff -man %s | ul -i' % name, 'r')
+    manpage.parsefile(fp)
+    root.mainloop()
+
+# Run the test program when called as a script
+if __name__ == '__main__':
+    test()


Property changes on: vendor/Python/current/Demo/tkinter/guido/ManPage.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tkinter/guido/MimeViewer.py
===================================================================
--- vendor/Python/current/Demo/tkinter/guido/MimeViewer.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/guido/MimeViewer.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,143 @@
+#! /usr/bin/env python
+
+# View a single MIME multipart message.
+# Display each part as a box.
+
+import string
+from types import *
+from Tkinter import *
+from ScrolledText import ScrolledText
+
+class MimeViewer:
+    def __init__(self, parent, title, msg):
+        self.title = title
+        self.msg = msg
+        self.frame = Frame(parent, {'relief': 'raised', 'bd': 2})
+        self.frame.packing = {'expand': 0, 'fill': 'both'}
+        self.button = Checkbutton(self.frame,
+                             {'text': title,
+                              'command': self.toggle})
+        self.button.pack({'anchor': 'w'})
+        headertext = msg.getheadertext(
+                lambda x: x != 'received' and x[:5] != 'x400-')
+        height = countlines(headertext, 4)
+        if height:
+            self.htext = ScrolledText(self.frame,
+                              {'height': height,
+                               'width': 80,
+                               'wrap': 'none',
+                               'relief': 'raised',
+                               'bd': 2})
+            self.htext.packing = {'expand': 1, 'fill': 'both',
+                                  'after': self.button}
+            self.htext.insert('end', headertext)
+        else:
+            self.htext = Frame(self.frame,
+                               {'relief': 'raised', 'bd': 2})
+            self.htext.packing = {'side': 'top',
+                                  'ipady': 2,
+                                  'fill': 'x',
+                                  'after': self.button}
+        body = msg.getbody()
+        if type(body) == StringType:
+            self.pad = None
+            height = countlines(body, 10)
+            if height:
+                self.btext = ScrolledText(self.frame,
+                                  {'height': height,
+                                   'width': 80,
+                                   'wrap': 'none',
+                                   'relief': 'raised',
+                                   'bd': 2})
+                self.btext.packing = {'expand': 1,
+                                      'fill': 'both'}
+                self.btext.insert('end', body)
+            else:
+                self.btext = None
+            self.parts = None
+        else:
+            self.pad = Frame(self.frame,
+                             {'relief': 'flat', 'bd': 2})
+            self.pad.packing = {'side': 'left', 'ipadx': 10,
+                                'fill': 'y', 'after': self.htext}
+            self.parts = []
+            for i in range(len(body)):
+                p = MimeViewer(self.frame,
+                               '%s.%d' % (title, i+1),
+                               body[i])
+                self.parts.append(p)
+            self.btext = None
+        self.collapsed = 1
+    def pack(self):
+        self.frame.pack(self.frame.packing)
+    def destroy(self):
+        self.frame.destroy()
+    def show(self):
+        if self.collapsed:
+            self.button.invoke()
+    def toggle(self):
+        if self.collapsed:
+            self.explode()
+        else:
+            self.collapse()
+    def collapse(self):
+        self.collapsed = 1
+        for comp in self.htext, self.btext, self.pad:
+            if comp:
+                comp.forget()
+        if self.parts:
+            for part in self.parts:
+                part.frame.forget()
+        self.frame.pack({'expand': 0})
+    def explode(self):
+        self.collapsed = 0
+        for comp in self.htext, self.btext, self.pad:
+            if comp: comp.pack(comp.packing)
+        if self.parts:
+            for part in self.parts:
+                part.pack()
+        self.frame.pack({'expand': 1})
+
+def countlines(str, limit):
+    i = 0
+    n = 0
+    while  n < limit:
+        i = string.find(str, '\n', i)
+        if i < 0: break
+        n = n+1
+        i = i+1
+    return n
+
+def main():
+    import sys
+    import getopt
+    import mhlib
+    opts, args = getopt.getopt(sys.argv[1:], '')
+    for o, a in opts:
+        pass
+    message = None
+    folder = 'inbox'
+    for arg in args:
+        if arg[:1] == '+':
+            folder = arg[1:]
+        else:
+            message = string.atoi(arg)
+
+    mh = mhlib.MH()
+    f = mh.openfolder(folder)
+    if not message:
+        message = f.getcurrent()
+    m = f.openmessage(message)
+
+    root = Tk()
+    tk = root.tk
+
+    top = MimeViewer(root, '+%s/%d' % (folder, message), m)
+    top.pack()
+    top.show()
+
+    root.minsize(1, 1)
+
+    tk.mainloop()
+
+if __name__ == '__main__': main()


Property changes on: vendor/Python/current/Demo/tkinter/guido/MimeViewer.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tkinter/guido/ShellWindow.py
===================================================================
--- vendor/Python/current/Demo/tkinter/guido/ShellWindow.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/guido/ShellWindow.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,151 @@
+import os
+import sys
+import string
+from Tkinter import *
+from ScrolledText import ScrolledText
+from Dialog import Dialog
+import signal
+
+BUFSIZE = 512
+
+class ShellWindow(ScrolledText):
+
+    def __init__(self, master=None, shell=None, **cnf):
+        if not shell:
+            try:
+                shell = os.environ['SHELL']
+            except KeyError:
+                shell = '/bin/sh'
+            shell = shell + ' -i'
+        args = string.split(shell)
+        shell = args[0]
+
+        apply(ScrolledText.__init__, (self, master), cnf)
+        self.pos = '1.0'
+        self.bind('<Return>', self.inputhandler)
+        self.bind('<Control-c>', self.sigint)
+        self.bind('<Control-t>', self.sigterm)
+        self.bind('<Control-k>', self.sigkill)
+        self.bind('<Control-d>', self.sendeof)
+
+        self.pid, self.fromchild, self.tochild = spawn(shell, args)
+        self.tk.createfilehandler(self.fromchild, READABLE,
+                                  self.outputhandler)
+
+    def outputhandler(self, file, mask):
+        data = os.read(file, BUFSIZE)
+        if not data:
+            self.tk.deletefilehandler(file)
+            pid, sts = os.waitpid(self.pid, 0)
+            print 'pid', pid, 'status', sts
+            self.pid = None
+            detail = sts>>8
+            cause = sts & 0xff
+            if cause == 0:
+                msg = "exit status %d" % detail
+            else:
+                msg = "killed by signal %d" % (cause & 0x7f)
+                if cause & 0x80:
+                    msg = msg + " -- core dumped"
+            Dialog(self.master,
+                   text=msg,
+                   title="Exit status",
+                   bitmap='warning',
+                   default=0,
+                   strings=('OK',))
+            return
+        self.insert(END, data)
+        self.pos = self.index("end - 1 char")
+        self.yview_pickplace(END)
+
+    def inputhandler(self, *args):
+        if not self.pid:
+            self.no_process()
+            return "break"
+        self.insert(END, "\n")
+        line = self.get(self.pos, "end - 1 char")
+        self.pos = self.index(END)
+        os.write(self.tochild, line)
+        return "break"
+
+    def sendeof(self, *args):
+        if not self.pid:
+            self.no_process()
+            return "break"
+        os.close(self.tochild)
+        return "break"
+
+    def sendsig(self, sig):
+        if not self.pid:
+            self.no_process()
+            return "break"
+        os.kill(self.pid, sig)
+        return "break"
+
+    def sigint(self, *args):
+        return self.sendsig(signal.SIGINT)
+
+    def sigquit(self, *args):
+        return self.sendsig(signal.SIGQUIT)
+
+    def sigterm(self, *args):
+        return self.sendsig(signal.SIGTERM)
+
+    def sigkill(self, *args):
+        return self.sendsig(signal.SIGKILL)
+
+    def no_process(self):
+        Dialog(self.master,
+               text="No active process",
+               title="No process",
+               bitmap='error',
+               default=0,
+               strings=('OK',))
+
+MAXFD = 100     # Max number of file descriptors (os.getdtablesize()???)
+
+def spawn(prog, args):
+    p2cread, p2cwrite = os.pipe()
+    c2pread, c2pwrite = os.pipe()
+    pid = os.fork()
+    if pid == 0:
+        # Child
+        for i in 0, 1, 2:
+            try:
+                os.close(i)
+            except os.error:
+                pass
+        if os.dup(p2cread) <> 0:
+            sys.stderr.write('popen2: bad read dup\n')
+        if os.dup(c2pwrite) <> 1:
+            sys.stderr.write('popen2: bad write dup\n')
+        if os.dup(c2pwrite) <> 2:
+            sys.stderr.write('popen2: bad write dup\n')
+        for i in range(3, MAXFD):
+            try:
+                os.close(i)
+            except:
+                pass
+        try:
+            os.execvp(prog, args)
+        finally:
+            sys.stderr.write('execvp failed\n')
+            os._exit(1)
+    os.close(p2cread)
+    os.close(c2pwrite)
+    return pid, c2pread, p2cwrite
+
+def test():
+    shell = string.join(sys.argv[1:])
+    root = Tk()
+    root.minsize(1, 1)
+    if shell:
+        w = ShellWindow(root, shell=shell)
+    else:
+        w = ShellWindow(root)
+    w.pack(expand=1, fill=BOTH)
+    w.focus_set()
+    w.tk.mainloop()
+
+if __name__ == '__main__':
+    test()


Property changes on: vendor/Python/current/Demo/tkinter/guido/ShellWindow.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tkinter/guido/brownian.py
===================================================================
--- vendor/Python/current/Demo/tkinter/guido/brownian.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/guido/brownian.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,50 @@
+# Brownian motion -- an example of a multi-threaded Tkinter program.
+
+from Tkinter import *
+import random
+import threading
+import time
+import sys
+
+WIDTH = 400
+HEIGHT = 300
+SIGMA = 10
+BUZZ = 2
+RADIUS = 2
+LAMBDA = 10
+FILL = 'red'
+
+stop = 0                                # Set when main loop exits
+
+def particle(canvas):
+    r = RADIUS
+    x = random.gauss(WIDTH/2.0, SIGMA)
+    y = random.gauss(HEIGHT/2.0, SIGMA)
+    p = canvas.create_oval(x-r, y-r, x+r, y+r, fill=FILL)
+    while not stop:
+        dx = random.gauss(0, BUZZ)
+        dy = random.gauss(0, BUZZ)
+        dt = random.expovariate(LAMBDA)
+        try:
+            canvas.move(p, dx, dy)
+        except TclError:
+            break
+        time.sleep(dt)
+
+def main():
+    global stop
+    root = Tk()
+    canvas = Canvas(root, width=WIDTH, height=HEIGHT)
+    canvas.pack(fill='both', expand=1)
+    np = 30
+    if sys.argv[1:]:
+        np = int(sys.argv[1])
+    for i in range(np):
+        t = threading.Thread(target=particle, args=(canvas,))
+        t.start()
+    try:
+        root.mainloop()
+    finally:
+        stop = 1
+
+main()

Added: vendor/Python/current/Demo/tkinter/guido/canvasevents.py
===================================================================
--- vendor/Python/current/Demo/tkinter/guido/canvasevents.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/guido/canvasevents.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,244 @@
+#! /usr/bin/env python
+
+from Tkinter import *
+from Canvas import Oval, Group, CanvasText
+
+
+# Fix a bug in Canvas.Group as distributed in Python 1.4.  The
+# distributed bind() method is broken.  This is what should be used:
+
+class Group(Group):
+    def bind(self, sequence=None, command=None):
+        return self.canvas.tag_bind(self.id, sequence, command)
+
+class Object:
+
+    """Base class for composite graphical objects.
+
+    Objects belong to a canvas, and can be moved around on the canvas.
+    They also belong to at most one ``pile'' of objects, and can be
+    transferred between piles (or removed from their pile).
+
+    Objects have a canonical ``x, y'' position which is moved when the
+    object is moved.  Where the object is relative to this position
+    depends on the object; for simple objects, it may be their center.
+
+    Objects have mouse sensitivity.  They can be clicked, dragged and
+    double-clicked.  The behavior may actually determined by the pile
+    they are in.
+
+    All instance attributes are public since the derived class may
+    need them.
+
+    """
+
+    def __init__(self, canvas, x=0, y=0, fill='red', text='object'):
+        self.canvas = canvas
+        self.x = x
+        self.y = y
+        self.pile = None
+        self.group = Group(self.canvas)
+        self.createitems(fill, text)
+
+    def __str__(self):
+        return str(self.group)
+
+    def createitems(self, fill, text):
+        self.__oval = Oval(self.canvas,
+                           self.x-20, self.y-10, self.x+20, self.y+10,
+                           fill=fill, width=3)
+        self.group.addtag_withtag(self.__oval)
+        self.__text = CanvasText(self.canvas,
+                           self.x, self.y, text=text)
+        self.group.addtag_withtag(self.__text)
+
+    def moveby(self, dx, dy):
+        if dx == dy == 0:
+            return
+        self.group.move(dx, dy)
+        self.x = self.x + dx
+        self.y = self.y + dy
+
+    def moveto(self, x, y):
+        self.moveby(x - self.x, y - self.y)
+
+    def transfer(self, pile):
+        if self.pile:
+            self.pile.delete(self)
+            self.pile = None
+        self.pile = pile
+        if self.pile:
+            self.pile.add(self)
+
+    def tkraise(self):
+        self.group.tkraise()
+
+
+class Bottom(Object):
+
+    """An object to serve as the bottom of a pile."""
+
+    def createitems(self, *args):
+        self.__oval = Oval(self.canvas,
+                           self.x-20, self.y-10, self.x+20, self.y+10,
+                           fill='gray', outline='')
+        self.group.addtag_withtag(self.__oval)
+
+
+class Pile:
+
+    """A group of graphical objects."""
+
+    def __init__(self, canvas, x, y, tag=None):
+        self.canvas = canvas
+        self.x = x
+        self.y = y
+        self.objects = []
+        self.bottom = Bottom(self.canvas, self.x, self.y)
+        self.group = Group(self.canvas, tag=tag)
+        self.group.addtag_withtag(self.bottom.group)
+        self.bindhandlers()
+
+    def bindhandlers(self):
+        self.group.bind('<1>', self.clickhandler)
+        self.group.bind('<Double-1>', self.doubleclickhandler)
+
+    def add(self, object):
+        self.objects.append(object)
+        self.group.addtag_withtag(object.group)
+        self.position(object)
+
+    def delete(self, object):
+        object.group.dtag(self.group)
+        self.objects.remove(object)
+
+    def position(self, object):
+        object.tkraise()
+        i = self.objects.index(object)
+        object.moveto(self.x + i*4, self.y + i*8)
+
+    def clickhandler(self, event):
+        pass
+
+    def doubleclickhandler(self, event):
+        pass
+
+
+class MovingPile(Pile):
+
+    def bindhandlers(self):
+        Pile.bindhandlers(self)
+        self.group.bind('<B1-Motion>', self.motionhandler)
+        self.group.bind('<ButtonRelease-1>', self.releasehandler)
+
+    movethis = None
+
+    def clickhandler(self, event):
+        tags = self.canvas.gettags('current')
+        for i in range(len(self.objects)):
+            o = self.objects[i]
+            if o.group.tag in tags:
+                break
+        else:
+            self.movethis = None
+            return
+        self.movethis = self.objects[i:]
+        for o in self.movethis:
+            o.tkraise()
+        self.lastx = event.x
+        self.lasty = event.y
+
+    doubleclickhandler = clickhandler
+
+    def motionhandler(self, event):
+        if not self.movethis:
+            return
+        dx = event.x - self.lastx
+        dy = event.y - self.lasty
+        self.lastx = event.x
+        self.lasty = event.y
+        for o in self.movethis:
+            o.moveby(dx, dy)
+
+    def releasehandler(self, event):
+        objects = self.movethis
+        if not objects:
+            return
+        self.movethis = None
+        self.finishmove(objects)
+
+    def finishmove(self, objects):
+        for o in objects:
+            self.position(o)
+
+
+class Pile1(MovingPile):
+
+    x = 50
+    y = 50
+    tag = 'p1'
+
+    def __init__(self, demo):
+        self.demo = demo
+        MovingPile.__init__(self, self.demo.canvas, self.x, self.y, self.tag)
+
+    def doubleclickhandler(self, event):
+        try:
+            o = self.objects[-1]
+        except IndexError:
+            return
+        o.transfer(self.other())
+        MovingPile.doubleclickhandler(self, event)
+
+    def other(self):
+        return self.demo.p2
+
+    def finishmove(self, objects):
+        o = objects[0]
+        p = self.other()
+        x, y = o.x, o.y
+        if (x-p.x)**2 + (y-p.y)**2 < (x-self.x)**2 + (y-self.y)**2:
+            for o in objects:
+                o.transfer(p)
+        else:
+            MovingPile.finishmove(self, objects)
+
+class Pile2(Pile1):
+
+    x = 150
+    y = 50
+    tag = 'p2'
+
+    def other(self):
+        return self.demo.p1
+
+
+class Demo:
+
+    def __init__(self, master):
+        self.master = master
+        self.canvas = Canvas(master,
+                             width=200, height=200,
+                             background='yellow',
+                             relief=SUNKEN, borderwidth=2)
+        self.canvas.pack(expand=1, fill=BOTH)
+        self.p1 = Pile1(self)
+        self.p2 = Pile2(self)
+        o1 = Object(self.canvas, fill='red', text='o1')
+        o2 = Object(self.canvas, fill='green', text='o2')
+        o3 = Object(self.canvas, fill='light blue', text='o3')
+        o1.transfer(self.p1)
+        o2.transfer(self.p1)
+        o3.transfer(self.p2)
+
+
+# Main function, run when invoked as a stand-alone Python program.
+
+def main():
+    root = Tk()
+    demo = Demo(root)
+    root.protocol('WM_DELETE_WINDOW', root.quit)
+    root.mainloop()
+
+if __name__ == '__main__':
+    main()

Added: vendor/Python/current/Demo/tkinter/guido/dialog.py
===================================================================
--- vendor/Python/current/Demo/tkinter/guido/dialog.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/guido/dialog.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,109 @@
+#! /usr/bin/env python
+
+# A Python function that generates dialog boxes with a text message,
+# optional bitmap, and any number of buttons.
+# Cf. Ousterhout, Tcl and the Tk Toolkit, Figs. 27.2-3, pp. 269-270.
+
+from Tkinter import *
+import sys
+
+
+def dialog(master, title, text, bitmap, default, *args):
+
+    # 1. Create the top-level window and divide it into top
+    # and bottom parts.
+
+    w = Toplevel(master, class_='Dialog')
+    w.title(title)
+    w.iconname('Dialog')
+
+    top = Frame(w, relief=RAISED, borderwidth=1)
+    top.pack(side=TOP, fill=BOTH)
+    bot = Frame(w, relief=RAISED, borderwidth=1)
+    bot.pack(side=BOTTOM, fill=BOTH)
+
+    # 2. Fill the top part with the bitmap and message.
+
+    msg = Message(top, width='3i', text=text,
+                  font='-Adobe-Times-Medium-R-Normal-*-180-*')
+    msg.pack(side=RIGHT, expand=1, fill=BOTH, padx='3m', pady='3m')
+    if bitmap:
+        bm = Label(top, bitmap=bitmap)
+        bm.pack(side=LEFT, padx='3m', pady='3m')
+
+    # 3. Create a row of buttons at the bottom of the dialog.
+
+    var = IntVar()
+    buttons = []
+    i = 0
+    for but in args:
+        b = Button(bot, text=but, command=lambda v=var,i=i: v.set(i))
+        buttons.append(b)
+        if i == default:
+            bd = Frame(bot, relief=SUNKEN, borderwidth=1)
+            bd.pack(side=LEFT, expand=1, padx='3m', pady='2m')
+            b.lift()
+            b.pack (in_=bd, side=LEFT,
+                    padx='2m', pady='2m', ipadx='2m', ipady='1m')
+        else:
+            b.pack (side=LEFT, expand=1,
+                    padx='3m', pady='3m', ipadx='2m', ipady='1m')
+        i = i+1
+
+    # 4. Set up a binding for <Return>, if there's a default,
+    # set a grab, and claim the focus too.
+
+    if default >= 0:
+        w.bind('<Return>',
+               lambda e, b=buttons[default], v=var, i=default:
+               (b.flash(),
+                v.set(i)))
+
+    oldFocus = w.focus_get()
+    w.grab_set()
+    w.focus_set()
+
+    # 5. Wait for the user to respond, then restore the focus
+    # and return the index of the selected button.
+
+    w.waitvar(var)
+    w.destroy()
+    if oldFocus: oldFocus.focus_set()
+    return var.get()
+
+# The rest is the test program.
+
+def go():
+    i = dialog(mainWidget,
+               'Not Responding',
+               "The file server isn't responding right now; "
+               "I'll keep trying.",
+               '',
+               -1,
+               'OK')
+    print 'pressed button', i
+    i = dialog(mainWidget,
+               'File Modified',
+               'File "tcl.h" has been modified since '
+               'the last time it was saved. '
+               'Do you want to save it before exiting the application?',
+               'warning',
+               0,
+               'Save File',
+               'Discard Changes',
+               'Return To Editor')
+    print 'pressed button', i
+
+def test():
+    import sys
+    global mainWidget
+    mainWidget = Frame()
+    Pack.config(mainWidget)
+    start = Button(mainWidget, text='Press Here To Start', command=go)
+    start.pack()
+    endit = Button(mainWidget, text="Exit", command=sys.exit)
+    endit.pack(fill=BOTH)
+    mainWidget.mainloop()
+
+if __name__ == '__main__':
+    test()


Property changes on: vendor/Python/current/Demo/tkinter/guido/dialog.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tkinter/guido/electrons.py
===================================================================
--- vendor/Python/current/Demo/tkinter/guido/electrons.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/guido/electrons.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,91 @@
+#! /usr/bin/env python
+
+# Simulate "electrons" migrating across the screen.
+# An optional bitmap file in can be in the background.
+#
+# Usage: electrons [n [bitmapfile]]
+#
+# n is the number of electrons to animate; default is 30.
+#
+# The bitmap file can be any X11 bitmap file (look in
+# /usr/include/X11/bitmaps for samples); it is displayed as the
+# background of the animation.  Default is no bitmap.
+
+from Tkinter import *
+import random
+
+
+# The graphical interface
+class Electrons:
+
+    # Create our objects
+    def __init__(self, n, bitmap = None):
+        self.n = n
+        self.tk = tk = Tk()
+        self.canvas = c = Canvas(tk)
+        c.pack()
+        width, height = tk.getint(c['width']), tk.getint(c['height'])
+
+        # Add background bitmap
+        if bitmap:
+            self.bitmap = c.create_bitmap(width/2, height/2,
+                                          bitmap=bitmap,
+                                          foreground='blue')
+
+        self.pieces = []
+        x1, y1, x2, y2 = 10,70,14,74
+        for i in range(n):
+            p = c.create_oval(x1, y1, x2, y2, fill='red')
+            self.pieces.append(p)
+            y1, y2 = y1 +2, y2 + 2
+        self.tk.update()
+
+    def random_move(self, n):
+        c = self.canvas
+        for p in self.pieces:
+            x = random.choice(range(-2,4))
+            y = random.choice(range(-3,4))
+            c.move(p, x, y)
+        self.tk.update()
+
+    # Run -- allow 500 movemens
+    def run(self):
+        try:
+            for i in range(500):
+                self.random_move(self.n)
+        except TclError:
+            try:
+                self.tk.destroy()
+            except TclError:
+                pass
+
+
+# Main program
+def main():
+    import sys, string
+
+    # First argument is number of electrons, default 30
+    if sys.argv[1:]:
+        n = string.atoi(sys.argv[1])
+    else:
+        n = 30
+
+    # Second argument is bitmap file, default none
+    if sys.argv[2:]:
+        bitmap = sys.argv[2]
+        # Reverse meaning of leading '@' compared to Tk
+        if bitmap[0] == '@': bitmap = bitmap[1:]
+        else: bitmap = '@' + bitmap
+    else:
+        bitmap = None
+
+    # Create the graphical objects...
+    h = Electrons(n, bitmap)
+
+    # ...and run!
+    h.run()
+
+
+# Call main when run as script
+if __name__ == '__main__':
+    main()


Property changes on: vendor/Python/current/Demo/tkinter/guido/electrons.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tkinter/guido/hanoi.py
===================================================================
--- vendor/Python/current/Demo/tkinter/guido/hanoi.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/guido/hanoi.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,154 @@
+# Animated Towers of Hanoi using Tk with optional bitmap file in
+# background.
+#
+# Usage: tkhanoi [n [bitmapfile]]
+#
+# n is the number of pieces to animate; default is 4, maximum 15.
+#
+# The bitmap file can be any X11 bitmap file (look in
+# /usr/include/X11/bitmaps for samples); it is displayed as the
+# background of the animation.  Default is no bitmap.
+
+# This uses Steen Lumholt's Tk interface
+from Tkinter import *
+
+
+# Basic Towers-of-Hanoi algorithm: move n pieces from a to b, using c
+# as temporary.  For each move, call report()
+def hanoi(n, a, b, c, report):
+    if n <= 0: return
+    hanoi(n-1, a, c, b, report)
+    report(n, a, b)
+    hanoi(n-1, c, b, a, report)
+
+
+# The graphical interface
+class Tkhanoi:
+
+    # Create our objects
+    def __init__(self, n, bitmap = None):
+        self.n = n
+        self.tk = tk = Tk()
+        self.canvas = c = Canvas(tk)
+        c.pack()
+        width, height = tk.getint(c['width']), tk.getint(c['height'])
+
+        # Add background bitmap
+        if bitmap:
+            self.bitmap = c.create_bitmap(width/2, height/2,
+                                          bitmap=bitmap,
+                                          foreground='blue')
+
+        # Generate pegs
+        pegwidth = 10
+        pegheight = height/2
+        pegdist = width/3
+        x1, y1 = (pegdist-pegwidth)/2, height*1/3
+        x2, y2 = x1+pegwidth, y1+pegheight
+        self.pegs = []
+        p = c.create_rectangle(x1, y1, x2, y2, fill='black')
+        self.pegs.append(p)
+        x1, x2 = x1+pegdist, x2+pegdist
+        p = c.create_rectangle(x1, y1, x2, y2, fill='black')
+        self.pegs.append(p)
+        x1, x2 = x1+pegdist, x2+pegdist
+        p = c.create_rectangle(x1, y1, x2, y2, fill='black')
+        self.pegs.append(p)
+        self.tk.update()
+
+        # Generate pieces
+        pieceheight = pegheight/16
+        maxpiecewidth = pegdist*2/3
+        minpiecewidth = 2*pegwidth
+        self.pegstate = [[], [], []]
+        self.pieces = {}
+        x1, y1 = (pegdist-maxpiecewidth)/2, y2-pieceheight-2
+        x2, y2 = x1+maxpiecewidth, y1+pieceheight
+        dx = (maxpiecewidth-minpiecewidth) / (2*max(1, n-1))
+        for i in range(n, 0, -1):
+            p = c.create_rectangle(x1, y1, x2, y2, fill='red')
+            self.pieces[i] = p
+            self.pegstate[0].append(i)
+            x1, x2 = x1 + dx, x2-dx
+            y1, y2 = y1 - pieceheight-2, y2-pieceheight-2
+            self.tk.update()
+            self.tk.after(25)
+
+    # Run -- never returns
+    def run(self):
+        while 1:
+            hanoi(self.n, 0, 1, 2, self.report)
+            hanoi(self.n, 1, 2, 0, self.report)
+            hanoi(self.n, 2, 0, 1, self.report)
+            hanoi(self.n, 0, 2, 1, self.report)
+            hanoi(self.n, 2, 1, 0, self.report)
+            hanoi(self.n, 1, 0, 2, self.report)
+
+    # Reporting callback for the actual hanoi function
+    def report(self, i, a, b):
+        if self.pegstate[a][-1] != i: raise RuntimeError # Assertion
+        del self.pegstate[a][-1]
+        p = self.pieces[i]
+        c = self.canvas
+
+        # Lift the piece above peg a
+        ax1, ay1, ax2, ay2 = c.bbox(self.pegs[a])
+        while 1:
+            x1, y1, x2, y2 = c.bbox(p)
+            if y2 < ay1: break
+            c.move(p, 0, -1)
+            self.tk.update()
+
+        # Move it towards peg b
+        bx1, by1, bx2, by2 = c.bbox(self.pegs[b])
+        newcenter = (bx1+bx2)/2
+        while 1:
+            x1, y1, x2, y2 = c.bbox(p)
+            center = (x1+x2)/2
+            if center == newcenter: break
+            if center > newcenter: c.move(p, -1, 0)
+            else: c.move(p, 1, 0)
+            self.tk.update()
+
+        # Move it down on top of the previous piece
+        pieceheight = y2-y1
+        newbottom = by2 - pieceheight*len(self.pegstate[b]) - 2
+        while 1:
+            x1, y1, x2, y2 = c.bbox(p)
+            if y2 >= newbottom: break
+            c.move(p, 0, 1)
+            self.tk.update()
+
+        # Update peg state
+        self.pegstate[b].append(i)
+
+
+# Main program
+def main():
+    import sys, string
+
+    # First argument is number of pegs, default 4
+    if sys.argv[1:]:
+        n = string.atoi(sys.argv[1])
+    else:
+        n = 4
+
+    # Second argument is bitmap file, default none
+    if sys.argv[2:]:
+        bitmap = sys.argv[2]
+        # Reverse meaning of leading '@' compared to Tk
+        if bitmap[0] == '@': bitmap = bitmap[1:]
+        else: bitmap = '@' + bitmap
+    else:
+        bitmap = None
+
+    # Create the graphical objects...
+    h = Tkhanoi(n, bitmap)
+
+    # ...and run!
+    h.run()
+
+
+# Call main when run as script
+if __name__ == '__main__':
+    main()


Property changes on: vendor/Python/current/Demo/tkinter/guido/hanoi.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tkinter/guido/hello.py
===================================================================
--- vendor/Python/current/Demo/tkinter/guido/hello.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/guido/hello.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,17 @@
+# Display hello, world in a button; clicking it quits the program
+
+import sys
+from Tkinter import *
+
+def main():
+    root = Tk()
+    button = Button(root)
+    button['text'] = 'Hello, world'
+    button['command'] = quit_callback       # See below
+    button.pack()
+    root.mainloop()
+
+def quit_callback():
+    sys.exit(0)
+
+main()


Property changes on: vendor/Python/current/Demo/tkinter/guido/hello.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tkinter/guido/imagedraw.py
===================================================================
--- vendor/Python/current/Demo/tkinter/guido/imagedraw.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/guido/imagedraw.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,23 @@
+"""Draw on top of an image"""
+
+from Tkinter import *
+import sys
+
+def main():
+    filename = sys.argv[1]
+    root = Tk()
+    img = PhotoImage(file=filename)
+    w, h = img.width(), img.height()
+    canv = Canvas(root, width=w, height=h)
+    canv.create_image(0, 0, anchor=NW, image=img)
+    canv.pack()
+    canv.bind('<Button-1>', blob)
+    root.mainloop()
+
+def blob(event):
+    x, y = event.x, event.y
+    canv = event.widget
+    r = 5
+    canv.create_oval(x-r, y-r, x+r, y+r, fill='red', outline="")
+
+main()


Property changes on: vendor/Python/current/Demo/tkinter/guido/imagedraw.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tkinter/guido/imageview.py
===================================================================
--- vendor/Python/current/Demo/tkinter/guido/imageview.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/guido/imageview.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,12 @@
+from Tkinter import *
+import sys
+
+def main():
+    filename = sys.argv[1]
+    root = Tk()
+    img = PhotoImage(file=filename)
+    label = Label(root, image=img)
+    label.pack()
+    root.mainloop()
+
+main()


Property changes on: vendor/Python/current/Demo/tkinter/guido/imageview.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tkinter/guido/kill.py
===================================================================
--- vendor/Python/current/Demo/tkinter/guido/kill.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/guido/kill.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,98 @@
+#! /usr/bin/env python
+# Tkinter interface to Linux `kill' command.
+
+from Tkinter import *
+from string import splitfields
+from string import split
+import commands
+import os
+
+class BarButton(Menubutton):
+    def __init__(self, master=None, **cnf):
+        apply(Menubutton.__init__, (self, master), cnf)
+        self.pack(side=LEFT)
+        self.menu = Menu(self, name='menu')
+        self['menu'] = self.menu
+
+class Kill(Frame):
+    # List of (name, option, pid_column)
+    format_list = [('Default', '', 0),
+                   ('Long', '-l', 2),
+                   ('User', '-u', 1),
+                   ('Jobs', '-j', 1),
+                   ('Signal', '-s', 1),
+                   ('Memory', '-m', 0),
+                   ('VM', '-v', 0),
+                   ('Hex', '-X', 0)]
+    def kill(self, selected):
+        c = self.format_list[self.format.get()][2]
+        pid = split(selected)[c]
+        os.system('kill -9 ' + pid)
+        self.do_update()
+    def do_update(self):
+        name, option, column = self.format_list[self.format.get()]
+        s = commands.getoutput('ps -w ' + option)
+        list = splitfields(s, '\n')
+        self.header.set(list[0])
+        del list[0]
+        y = self.frame.vscroll.get()[0]
+        self.frame.list.delete(0, AtEnd())
+        for line in list:
+            self.frame.list.insert(0, line)
+        self.frame.list.yview(int(y))
+    def do_motion(self, e):
+        e.widget.select_clear(0, END)
+        e.widget.select_set(e.widget.nearest(e.y))
+    def do_leave(self, e):
+        e.widget.select_clear(0, END)
+    def do_1(self, e):
+        self.kill(e.widget.get(e.widget.nearest(e.y)))
+    def __init__(self, master=None, **cnf):
+        Frame.__init__(self, master, cnf)
+        self.pack(expand=1, fill=BOTH)
+        self.bar = Frame(self, name='bar', relief=RAISED,
+                         borderwidth=2)
+        self.bar.pack(fill=X)
+        self.bar.file = BarButton(self.bar, text='File')
+        self.bar.file.menu.add_command(
+                label='Quit', command=self.quit)
+        self.bar.view = BarButton(self.bar, text='View')
+        self.format = IntVar(self)
+        self.format.set(2)
+        for num in range(len(self.format_list)):
+            self.bar.view.menu.add_radiobutton(
+                    label=self.format_list[num][0],
+                    command=self.do_update,
+                    variable=self.format,
+                    value=num)
+        #self.bar.view.menu.add_separator()
+        #XXX ...
+        self.bar.tk_menuBar(self.bar.file, self.bar.view)
+        self.frame = Frame(self, relief=RAISED, borderwidth=2)
+        self.frame.pack(expand=1, fill=BOTH)
+        self.header = StringVar(self)
+        self.frame.label = Label(self.frame, relief=FLAT, anchor=NW,
+                                 borderwidth=0,
+                                 textvariable=self.header)
+        self.frame.label.pack(fill=X)
+        self.frame.vscroll = Scrollbar(self.frame, orient=VERTICAL)
+        self.frame.list = Listbox(self.frame, relief=SUNKEN,
+                                  selectbackground='#eed5b7',
+                                  selectborderwidth=0,
+                                  yscroll=self.frame.vscroll.set)
+        self.frame.vscroll['command'] = self.frame.list.yview
+        self.frame.vscroll.pack(side=RIGHT, fill=Y)
+        self.frame.list.pack(expand=1, fill=BOTH)
+        self.update = Button(self, text="Update",
+                             command=self.do_update)
+        self.update.pack(expand=1, fill=X)
+        self.frame.list.bind('<Motion>', self.do_motion)
+        self.frame.list.bind('<Leave>', self.do_leave)
+        self.frame.list.bind('<1>', self.do_1)
+        self.do_update()
+
+if __name__ == '__main__':
+    kill = Kill(None, borderwidth=5)
+    kill.winfo_toplevel().title('Tkinter Process Killer')
+    kill.winfo_toplevel().minsize(1, 1)
+    kill.mainloop()


Property changes on: vendor/Python/current/Demo/tkinter/guido/kill.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tkinter/guido/listtree.py
===================================================================
--- vendor/Python/current/Demo/tkinter/guido/listtree.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/guido/listtree.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,37 @@
+# List a remote app's widget tree (names and classes only)
+
+import sys
+import string
+
+from Tkinter import *
+
+def listtree(master, app):
+    list = Listbox(master, name='list')
+    list.pack(expand=1, fill=BOTH)
+    listnodes(list, app, '.', 0)
+    return list
+
+def listnodes(list, app, widget, level):
+    klass = list.send(app, 'winfo', 'class', widget)
+##      i = string.rindex(widget, '.')
+##      list.insert(END, '%s%s (%s)' % ((level-1)*'.   ', widget[i:], klass))
+    list.insert(END, '%s (%s)' % (widget, klass))
+    children = list.tk.splitlist(
+            list.send(app, 'winfo', 'children', widget))
+    for c in children:
+        listnodes(list, app, c, level+1)
+
+def main():
+    if not sys.argv[1:]:
+        sys.stderr.write('Usage: listtree appname\n')
+        sys.exit(2)
+    app = sys.argv[1]
+    tk = Tk()
+    tk.minsize(1, 1)
+    f = Frame(tk, name='f')
+    f.pack(expand=1, fill=BOTH)
+    list = listtree(f, app)
+    tk.mainloop()
+
+if __name__ == '__main__':
+    main()


Property changes on: vendor/Python/current/Demo/tkinter/guido/listtree.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tkinter/guido/mbox.py
===================================================================
--- vendor/Python/current/Demo/tkinter/guido/mbox.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/guido/mbox.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,285 @@
+#! /usr/bin/env python
+
+# Scan MH folder, display results in window
+
+import os
+import sys
+import re
+import getopt
+import string
+import mhlib
+
+from Tkinter import *
+
+from dialog import dialog
+
+mailbox = os.environ['HOME'] + '/Mail'
+
+def main():
+    global root, tk, top, mid, bot
+    global folderbox, foldermenu, scanbox, scanmenu, viewer
+    global folder, seq
+    global mh, mhf
+
+    # Parse command line options
+
+    folder = 'inbox'
+    seq = 'all'
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], '')
+    except getopt.error, msg:
+        print msg
+        sys.exit(2)
+    for arg in args:
+        if arg[:1] == '+':
+            folder = arg[1:]
+        else:
+            seq = arg
+
+    # Initialize MH
+
+    mh = mhlib.MH()
+    mhf = mh.openfolder(folder)
+
+    # Build widget hierarchy
+
+    root = Tk()
+    tk = root.tk
+
+    top = Frame(root)
+    top.pack({'expand': 1, 'fill': 'both'})
+
+    # Build right part: folder list
+
+    right = Frame(top)
+    right.pack({'fill': 'y', 'side': 'right'})
+
+    folderbar = Scrollbar(right, {'relief': 'sunken', 'bd': 2})
+    folderbar.pack({'fill': 'y', 'side': 'right'})
+
+    folderbox = Listbox(right, {'exportselection': 0})
+    folderbox.pack({'expand': 1, 'fill': 'both', 'side': 'left'})
+
+    foldermenu = Menu(root)
+    foldermenu.add('command',
+                   {'label': 'Open Folder',
+                    'command': open_folder})
+    foldermenu.add('separator')
+    foldermenu.add('command',
+                   {'label': 'Quit',
+                    'command': 'exit'})
+    foldermenu.bind('<ButtonRelease-3>', folder_unpost)
+
+    folderbox['yscrollcommand'] = (folderbar, 'set')
+    folderbar['command'] = (folderbox, 'yview')
+    folderbox.bind('<Double-1>', open_folder, 1)
+    folderbox.bind('<3>', folder_post)
+
+    # Build left part: scan list
+
+    left = Frame(top)
+    left.pack({'expand': 1, 'fill': 'both', 'side': 'left'})
+
+    scanbar = Scrollbar(left, {'relief': 'sunken', 'bd': 2})
+    scanbar.pack({'fill': 'y', 'side': 'right'})
+
+    scanbox = Listbox(left, {'font': 'fixed'})
+    scanbox.pack({'expand': 1, 'fill': 'both', 'side': 'left'})
+
+    scanmenu = Menu(root)
+    scanmenu.add('command',
+                 {'label': 'Open Message',
+                  'command': open_message})
+    scanmenu.add('command',
+                 {'label': 'Remove Message',
+                  'command': remove_message})
+    scanmenu.add('command',
+                 {'label': 'Refile Message',
+                  'command': refile_message})
+    scanmenu.add('separator')
+    scanmenu.add('command',
+                 {'label': 'Quit',
+                  'command': 'exit'})
+    scanmenu.bind('<ButtonRelease-3>', scan_unpost)
+
+    scanbox['yscrollcommand'] = (scanbar, 'set')
+    scanbar['command'] = (scanbox, 'yview')
+    scanbox.bind('<Double-1>', open_message)
+    scanbox.bind('<3>', scan_post)
+
+    # Separator between middle and bottom part
+
+    rule2 = Frame(root, {'bg': 'black'})
+    rule2.pack({'fill': 'x'})
+
+    # Build bottom part: current message
+
+    bot = Frame(root)
+    bot.pack({'expand': 1, 'fill': 'both'})
+    #
+    viewer = None
+
+    # Window manager commands
+
+    root.minsize(800, 1) # Make window resizable
+
+    # Fill folderbox with text
+
+    setfolders()
+
+    # Fill scanbox with text
+
+    rescan()
+
+    # Enter mainloop
+
+    root.mainloop()
+
+def folder_post(e):
+    x, y = e.x_root, e.y_root
+    foldermenu.post(x - 10, y - 10)
+    foldermenu.grab_set()
+
+def folder_unpost(e):
+    tk.call('update', 'idletasks')
+    foldermenu.grab_release()
+    foldermenu.unpost()
+    foldermenu.invoke('active')
+
+def scan_post(e):
+    x, y = e.x_root, e.y_root
+    scanmenu.post(x - 10, y - 10)
+    scanmenu.grab_set()
+
+def scan_unpost(e):
+    tk.call('update', 'idletasks')
+    scanmenu.grab_release()
+    scanmenu.unpost()
+    scanmenu.invoke('active')
+
+scanparser = re.compile('^ *([0-9]+)')
+
+def open_folder(e=None):
+    global folder, mhf
+    sel = folderbox.curselection()
+    if len(sel) != 1:
+        if len(sel) > 1:
+            msg = "Please open one folder at a time"
+        else:
+            msg = "Please select a folder to open"
+        dialog(root, "Can't Open Folder", msg, "", 0, "OK")
+        return
+    i = sel[0]
+    folder = folderbox.get(i)
+    mhf = mh.openfolder(folder)
+    rescan()
+
+def open_message(e=None):
+    global viewer
+    sel = scanbox.curselection()
+    if len(sel) != 1:
+        if len(sel) > 1:
+            msg = "Please open one message at a time"
+        else:
+            msg = "Please select a message to open"
+        dialog(root, "Can't Open Message", msg, "", 0, "OK")
+        return
+    cursor = scanbox['cursor']
+    scanbox['cursor'] = 'watch'
+    tk.call('update', 'idletasks')
+    i = sel[0]
+    line = scanbox.get(i)
+    if scanparser.match(line) >= 0:
+        num = string.atoi(scanparser.group(1))
+        m = mhf.openmessage(num)
+        if viewer: viewer.destroy()
+        from MimeViewer import MimeViewer
+        viewer = MimeViewer(bot, '+%s/%d' % (folder, num), m)
+        viewer.pack()
+        viewer.show()
+    scanbox['cursor'] = cursor
+
+def interestingheader(header):
+    return header != 'received'
+
+def remove_message(e=None):
+    itop = scanbox.nearest(0)
+    sel = scanbox.curselection()
+    if not sel:
+        dialog(root, "No Message To Remove",
+               "Please select a message to remove", "", 0, "OK")
+        return
+    todo = []
+    for i in sel:
+        line = scanbox.get(i)
+        if scanparser.match(line) >= 0:
+            todo.append(string.atoi(scanparser.group(1)))
+    mhf.removemessages(todo)
+    rescan()
+    fixfocus(min(todo), itop)
+
+lastrefile = ''
+tofolder = None
+def refile_message(e=None):
+    global lastrefile, tofolder
+    itop = scanbox.nearest(0)
+    sel = scanbox.curselection()
+    if not sel:
+        dialog(root, "No Message To Refile",
+               "Please select a message to refile", "", 0, "OK")
+        return
+    foldersel = folderbox.curselection()
+    if len(foldersel) != 1:
+        if not foldersel:
+            msg = "Please select a folder to refile to"
+        else:
+            msg = "Please select exactly one folder to refile to"
+        dialog(root, "No Folder To Refile", msg, "", 0, "OK")
+        return
+    refileto = folderbox.get(foldersel[0])
+    todo = []
+    for i in sel:
+        line = scanbox.get(i)
+        if scanparser.match(line) >= 0:
+            todo.append(string.atoi(scanparser.group(1)))
+    if lastrefile != refileto or not tofolder:
+        lastrefile = refileto
+        tofolder = None
+        tofolder = mh.openfolder(lastrefile)
+    mhf.refilemessages(todo, tofolder)
+    rescan()
+    fixfocus(min(todo), itop)
+
+def fixfocus(near, itop):
+    n = scanbox.size()
+    for i in range(n):
+        line = scanbox.get(repr(i))
+        if scanparser.match(line) >= 0:
+            num = string.atoi(scanparser.group(1))
+            if num >= near:
+                break
+    else:
+        i = 'end'
+    scanbox.select_from(i)
+    scanbox.yview(itop)
+
+def setfolders():
+    folderbox.delete(0, 'end')
+    for fn in mh.listallfolders():
+        folderbox.insert('end', fn)
+
+def rescan():
+    global viewer
+    if viewer:
+        viewer.destroy()
+        viewer = None
+    scanbox.delete(0, 'end')
+    for line in scanfolder(folder, seq):
+        scanbox.insert('end', line)
+
+def scanfolder(folder = 'inbox', sequence = 'all'):
+    return map(
+            lambda line: line[:-1],
+            os.popen('scan +%s %s' % (folder, sequence), 'r').readlines())
+
+main()


Property changes on: vendor/Python/current/Demo/tkinter/guido/mbox.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tkinter/guido/newmenubardemo.py
===================================================================
--- vendor/Python/current/Demo/tkinter/guido/newmenubardemo.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/guido/newmenubardemo.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,47 @@
+#! /usr/bin/env python
+
+"""Play with the new Tk 8.0 toplevel menu option."""
+
+from Tkinter import *
+
+class App:
+
+    def __init__(self, master):
+        self.master = master
+
+        self.menubar = Menu(self.master)
+
+        self.filemenu = Menu(self.menubar)
+
+        self.filemenu.add_command(label="New")
+        self.filemenu.add_command(label="Open...")
+        self.filemenu.add_command(label="Close")
+        self.filemenu.add_separator()
+        self.filemenu.add_command(label="Quit", command=self.master.quit)
+
+        self.editmenu = Menu(self.menubar)
+
+        self.editmenu.add_command(label="Cut")
+        self.editmenu.add_command(label="Copy")
+        self.editmenu.add_command(label="Paste")
+
+        self.helpmenu = Menu(self.menubar, name='help')
+
+        self.helpmenu.add_command(label="About...")
+
+        self.menubar.add_cascade(label="File", menu=self.filemenu)
+        self.menubar.add_cascade(label="Edit", menu=self.editmenu)
+        self.menubar.add_cascade(label="Help", menu=self.helpmenu)
+
+        self.top = Toplevel(menu=self.menubar)
+
+        # Rest of app goes here...
+
+def main():
+    root = Tk()
+    root.withdraw()
+    app = App(root)
+    root.mainloop()
+
+if __name__ == '__main__':
+    main()

Added: vendor/Python/current/Demo/tkinter/guido/optionmenu.py
===================================================================
--- vendor/Python/current/Demo/tkinter/guido/optionmenu.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/guido/optionmenu.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,27 @@
+# option menu sample (Fredrik Lundh, September 1997)
+
+from Tkinter import *
+
+root = Tk()
+
+#
+# standard usage
+
+var1  = StringVar()
+var1.set("One") # default selection
+
+menu1 = OptionMenu(root, var1, "One", "Two", "Three")
+menu1.pack()
+
+#
+# initialize from a sequence
+
+CHOICES = "Aah", "Bee", "Cee", "Dee", "Eff"
+
+var2  = StringVar()
+var2.set(CHOICES[0])
+
+menu2 = apply(OptionMenu, (root, var2) + tuple(CHOICES))
+menu2.pack()
+
+root.mainloop()

Added: vendor/Python/current/Demo/tkinter/guido/paint.py
===================================================================
--- vendor/Python/current/Demo/tkinter/guido/paint.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/guido/paint.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,60 @@
+""""Paint program by Dave Michell.
+
+Subject: tkinter "paint" example
+From: Dave Mitchell <davem at magnet.com>
+To: python-list at cwi.nl
+Date: Fri, 23 Jan 1998 12:18:05 -0500 (EST)
+
+  Not too long ago (last week maybe?) someone posted a request
+for an example of a paint program using Tkinter. Try as I might
+I can't seem to find it in the archive, so i'll just post mine
+here and hope that the person who requested it sees this!
+
+  All this does is put up a canvas and draw a smooth black line
+whenever you have the mouse button down, but hopefully it will
+be enough to start with.. It would be easy enough to add some
+options like other shapes or colors...
+
+                                                yours,
+                                                dave mitchell
+                                                davem at magnet.com
+"""
+
+from Tkinter import *
+
+"""paint.py: not exactly a paint program.. just a smooth line drawing demo."""
+
+b1 = "up"
+xold, yold = None, None
+
+def main():
+    root = Tk()
+    drawing_area = Canvas(root)
+    drawing_area.pack()
+    drawing_area.bind("<Motion>", motion)
+    drawing_area.bind("<ButtonPress-1>", b1down)
+    drawing_area.bind("<ButtonRelease-1>", b1up)
+    root.mainloop()
+
+def b1down(event):
+    global b1
+    b1 = "down"           # you only want to draw when the button is down
+                          # because "Motion" events happen -all the time-
+
+def b1up(event):
+    global b1, xold, yold
+    b1 = "up"
+    xold = None           # reset the line when you let go of the button
+    yold = None
+
+def motion(event):
+    if b1 == "down":
+        global xold, yold
+        if xold != None and yold != None:
+            event.widget.create_line(xold,yold,event.x,event.y,smooth=TRUE)
+                          # here's where you draw it. smooth. neat.
+        xold = event.x
+        yold = event.y
+
+if __name__ == "__main__":
+    main()

Added: vendor/Python/current/Demo/tkinter/guido/rmt.py
===================================================================
--- vendor/Python/current/Demo/tkinter/guido/rmt.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/guido/rmt.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,159 @@
+#! /usr/bin/env python
+
+# A Python program implementing rmt, an application for remotely
+# controlling other Tk applications.
+# Cf. Ousterhout, Tcl and the Tk Toolkit, Figs. 27.5-8, pp. 273-276.
+
+# Note that because of forward references in the original, we
+# sometimes delay bindings until after the corresponding procedure is
+# defined.  We also introduce names for some unnamed code blocks in
+# the original because of restrictions on lambda forms in Python.
+
+# XXX This should be written in a more Python-like style!!!
+
+from Tkinter import *
+import sys
+
+# 1. Create basic application structure: menu bar on top of
+# text widget, scrollbar on right.
+
+root = Tk()
+tk = root.tk
+mBar = Frame(root, relief=RAISED, borderwidth=2)
+mBar.pack(fill=X)
+
+f = Frame(root)
+f.pack(expand=1, fill=BOTH)
+s = Scrollbar(f, relief=FLAT)
+s.pack(side=RIGHT, fill=Y)
+t = Text(f, relief=RAISED, borderwidth=2, yscrollcommand=s.set, setgrid=1)
+t.pack(side=LEFT, fill=BOTH, expand=1)
+t.tag_config('bold', font='-Adobe-Courier-Bold-R-Normal-*-120-*')
+s['command'] = t.yview
+
+root.title('Tk Remote Controller')
+root.iconname('Tk Remote')
+
+# 2. Create menu button and menus.
+
+file = Menubutton(mBar, text='File', underline=0)
+file.pack(side=LEFT)
+file_m = Menu(file)
+file['menu'] = file_m
+file_m_apps = Menu(file_m, tearoff=0)
+file_m.add_cascade(label='Select Application', underline=0,
+                   menu=file_m_apps)
+file_m.add_command(label='Quit', underline=0, command=sys.exit)
+
+# 3. Create bindings for text widget to allow commands to be
+# entered and information to be selected.  New characters
+# can only be added at the end of the text (can't ever move
+# insertion point).
+
+def single1(e):
+    x = e.x
+    y = e.y
+    t.setvar('tk_priv(selectMode)', 'char')
+    t.mark_set('anchor', At(x, y))
+    # Should focus W
+t.bind('<1>', single1)
+
+def double1(e):
+    x = e.x
+    y = e.y
+    t.setvar('tk_priv(selectMode)', 'word')
+    t.tk_textSelectTo(At(x, y))
+t.bind('<Double-1>', double1)
+
+def triple1(e):
+    x = e.x
+    y = e.y
+    t.setvar('tk_priv(selectMode)', 'line')
+    t.tk_textSelectTo(At(x, y))
+t.bind('<Triple-1>', triple1)
+
+def returnkey(e):
+    t.insert(AtInsert(), '\n')
+    invoke()
+t.bind('<Return>', returnkey)
+
+def controlv(e):
+    t.insert(AtInsert(), t.selection_get())
+    t.yview_pickplace(AtInsert())
+    if t.index(AtInsert())[-2:] == '.0':
+        invoke()
+t.bind('<Control-v>', controlv)
+
+# 4. Procedure to backspace over one character, as long as
+# the character isn't part of the prompt.
+
+def backspace(e):
+    if t.index('promptEnd') != t.index('insert - 1 char'):
+        t.delete('insert - 1 char', AtInsert())
+        t.yview_pickplace(AtInsert())
+t.bind('<BackSpace>', backspace)
+t.bind('<Control-h>', backspace)
+t.bind('<Delete>', backspace)
+
+
+# 5. Procedure that's invoked when return is typed:  if
+# there's not yet a complete command (e.g. braces are open)
+# then do nothing.  Otherwise, execute command (locally or
+# remotely), output the result or error message, and issue
+# a new prompt.
+
+def invoke():
+    cmd = t.get('promptEnd + 1 char', AtInsert())
+    if t.getboolean(tk.call('info', 'complete', cmd)): # XXX
+        if app == root.winfo_name():
+            msg = tk.call('eval', cmd) # XXX
+        else:
+            msg = t.send(app, cmd)
+        if msg:
+            t.insert(AtInsert(), msg + '\n')
+        prompt()
+    t.yview_pickplace(AtInsert())
+
+def prompt():
+    t.insert(AtInsert(), app + ': ')
+    t.mark_set('promptEnd', 'insert - 1 char')
+    t.tag_add('bold', 'insert linestart', 'promptEnd')
+
+# 6. Procedure to select a new application.  Also changes
+# the prompt on the current command line to reflect the new
+# name.
+
+def newApp(appName):
+    global app
+    app = appName
+    t.delete('promptEnd linestart', 'promptEnd')
+    t.insert('promptEnd', appName + ':')
+    t.tag_add('bold', 'promptEnd linestart', 'promptEnd')
+
+def fillAppsMenu():
+    file_m_apps.add('command')
+    file_m_apps.delete(0, 'last')
+    names = root.winfo_interps()
+    names = map(None, names) # convert tuple to list
+    names.sort()
+    for name in names:
+        try:
+            root.send(name, 'winfo name .')
+        except TclError:
+            # Inoperative window -- ignore it
+            pass
+        else:
+            file_m_apps.add_command(
+                label=name,
+                command=lambda name=name: newApp(name))
+
+file_m_apps['postcommand'] = fillAppsMenu
+mBar.tk_menuBar(file)
+
+# 7. Miscellaneous initialization.
+
+app = root.winfo_name()
+prompt()
+t.focus()
+
+root.mainloop()


Property changes on: vendor/Python/current/Demo/tkinter/guido/rmt.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tkinter/guido/solitaire.py
===================================================================
--- vendor/Python/current/Demo/tkinter/guido/solitaire.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/guido/solitaire.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,637 @@
+#! /usr/bin/env python
+
+"""Solitaire game, much like the one that comes with MS Windows.
+
+Limitations:
+
+- No cute graphical images for the playing cards faces or backs.
+- No scoring or timer.
+- No undo.
+- No option to turn 3 cards at a time.
+- No keyboard shortcuts.
+- Less fancy animation when you win.
+- The determination of which stack you drag to is more relaxed.
+
+Apology:
+
+I'm not much of a card player, so my terminology in these comments may
+at times be a little unusual.  If you have suggestions, please let me
+know!
+
+"""
+
+# Imports
+
+import math
+import random
+
+from Tkinter import *
+from Canvas import Rectangle, CanvasText, Group, Window
+
+
+# Fix a bug in Canvas.Group as distributed in Python 1.4.  The
+# distributed bind() method is broken.  Rather than asking you to fix
+# the source, we fix it here by deriving a subclass:
+
+class Group(Group):
+    def bind(self, sequence=None, command=None):
+        return self.canvas.tag_bind(self.id, sequence, command)
+
+
+# Constants determining the size and lay-out of cards and stacks.  We
+# work in a "grid" where each card/stack is surrounded by MARGIN
+# pixels of space on each side, so adjacent stacks are separated by
+# 2*MARGIN pixels.  OFFSET is the offset used for displaying the
+# face down cards in the row stacks.
+
+CARDWIDTH = 100
+CARDHEIGHT = 150
+MARGIN = 10
+XSPACING = CARDWIDTH + 2*MARGIN
+YSPACING = CARDHEIGHT + 4*MARGIN
+OFFSET = 5
+
+# The background color, green to look like a playing table.  The
+# standard green is way too bright, and dark green is way to dark, so
+# we use something in between.  (There are a few more colors that
+# could be customized, but they are less controversial.)
+
+BACKGROUND = '#070'
+
+
+# Suits and colors.  The values of the symbolic suit names are the
+# strings used to display them (you change these and VALNAMES to
+# internationalize the game).  The COLOR dictionary maps suit names to
+# colors (red and black) which must be Tk color names.  The keys() of
+# the COLOR dictionary conveniently provides us with a list of all
+# suits (in arbitrary order).
+
+HEARTS = 'Heart'
+DIAMONDS = 'Diamond'
+CLUBS = 'Club'
+SPADES = 'Spade'
+
+RED = 'red'
+BLACK = 'black'
+
+COLOR = {}
+for s in (HEARTS, DIAMONDS):
+    COLOR[s] = RED
+for s in (CLUBS, SPADES):
+    COLOR[s] = BLACK
+
+ALLSUITS = COLOR.keys()
+NSUITS = len(ALLSUITS)
+
+
+# Card values are 1-13.  We also define symbolic names for the picture
+# cards.  ALLVALUES is a list of all card values.
+
+ACE = 1
+JACK = 11
+QUEEN = 12
+KING = 13
+ALLVALUES = range(1, 14) # (one more than the highest value)
+NVALUES = len(ALLVALUES)
+
+
+# VALNAMES is a list that maps a card value to string.  It contains a
+# dummy element at index 0 so it can be indexed directly with the card
+# value.
+
+VALNAMES = ["", "A"] + map(str, range(2, 11)) + ["J", "Q", "K"]
+
+
+# Solitaire constants.  The only one I can think of is the number of
+# row stacks.
+
+NROWS = 7
+
+
+# The rest of the program consists of class definitions.  These are
+# further described in their documentation strings.
+
+
+class Card:
+
+    """A playing card.
+
+    A card doesn't record to which stack it belongs; only the stack
+    records this (it turns out that we always know this from the
+    context, and this saves a ``double update'' with potential for
+    inconsistencies).
+
+    Public methods:
+
+    moveto(x, y) -- move the card to an absolute position
+    moveby(dx, dy) -- move the card by a relative offset
+    tkraise() -- raise the card to the top of its stack
+    showface(), showback() -- turn the card face up or down & raise it
+
+    Public read-only instance variables:
+
+    suit, value, color -- the card's suit, value and color
+    face_shown -- true when the card is shown face up, else false
+
+    Semi-public read-only instance variables (XXX should be made
+    private):
+
+    group -- the Canvas.Group representing the card
+    x, y -- the position of the card's top left corner
+
+    Private instance variables:
+
+    __back, __rect, __text -- the canvas items making up the card
+
+    (To show the card face up, the text item is placed in front of
+    rect and the back is placed behind it.  To show it face down, this
+    is reversed.  The card is created face down.)
+
+    """
+
+    def __init__(self, suit, value, canvas):
+        """Card constructor.
+
+        Arguments are the card's suit and value, and the canvas widget.
+
+        The card is created at position (0, 0), with its face down
+        (adding it to a stack will position it according to that
+        stack's rules).
+
+        """
+        self.suit = suit
+        self.value = value
+        self.color = COLOR[suit]
+        self.face_shown = 0
+
+        self.x = self.y = 0
+        self.group = Group(canvas)
+
+        text = "%s  %s" % (VALNAMES[value], suit)
+        self.__text = CanvasText(canvas, CARDWIDTH/2, 0,
+                               anchor=N, fill=self.color, text=text)
+        self.group.addtag_withtag(self.__text)
+
+        self.__rect = Rectangle(canvas, 0, 0, CARDWIDTH, CARDHEIGHT,
+                              outline='black', fill='white')
+        self.group.addtag_withtag(self.__rect)
+
+        self.__back = Rectangle(canvas, MARGIN, MARGIN,
+                              CARDWIDTH-MARGIN, CARDHEIGHT-MARGIN,
+                              outline='black', fill='blue')
+        self.group.addtag_withtag(self.__back)
+
+    def __repr__(self):
+        """Return a string for debug print statements."""
+        return "Card(%r, %r)" % (self.suit, self.value)
+
+    def moveto(self, x, y):
+        """Move the card to absolute position (x, y)."""
+        self.moveby(x - self.x, y - self.y)
+
+    def moveby(self, dx, dy):
+        """Move the card by (dx, dy)."""
+        self.x = self.x + dx
+        self.y = self.y + dy
+        self.group.move(dx, dy)
+
+    def tkraise(self):
+        """Raise the card above all other objects in its canvas."""
+        self.group.tkraise()
+
+    def showface(self):
+        """Turn the card's face up."""
+        self.tkraise()
+        self.__rect.tkraise()
+        self.__text.tkraise()
+        self.face_shown = 1
+
+    def showback(self):
+        """Turn the card's face down."""
+        self.tkraise()
+        self.__rect.tkraise()
+        self.__back.tkraise()
+        self.face_shown = 0
+
+
+class Stack:
+
+    """A generic stack of cards.
+
+    This is used as a base class for all other stacks (e.g. the deck,
+    the suit stacks, and the row stacks).
+
+    Public methods:
+
+    add(card) -- add a card to the stack
+    delete(card) -- delete a card from the stack
+    showtop() -- show the top card (if any) face up
+    deal() -- delete and return the top card, or None if empty
+
+    Method that subclasses may override:
+
+    position(card) -- move the card to its proper (x, y) position
+
+        The default position() method places all cards at the stack's
+        own (x, y) position.
+
+    userclickhandler(), userdoubleclickhandler() -- called to do
+    subclass specific things on single and double clicks
+
+        The default user (single) click handler shows the top card
+        face up.  The default user double click handler calls the user
+        single click handler.
+
+    usermovehandler(cards) -- called to complete a subpile move
+
+        The default user move handler moves all moved cards back to
+        their original position (by calling the position() method).
+
+    Private methods:
+
+    clickhandler(event), doubleclickhandler(event),
+    motionhandler(event), releasehandler(event) -- event handlers
+
+        The default event handlers turn the top card of the stack with
+        its face up on a (single or double) click, and also support
+        moving a subpile around.
+
+    startmoving(event) -- begin a move operation
+    finishmoving() -- finish a move operation
+
+    """
+
+    def __init__(self, x, y, game=None):
+        """Stack constructor.
+
+        Arguments are the stack's nominal x and y position (the top
+        left corner of the first card placed in the stack), and the
+        game object (which is used to get the canvas; subclasses use
+        the game object to find other stacks).
+
+        """
+        self.x = x
+        self.y = y
+        self.game = game
+        self.cards = []
+        self.group = Group(self.game.canvas)
+        self.group.bind('<1>', self.clickhandler)
+        self.group.bind('<Double-1>', self.doubleclickhandler)
+        self.group.bind('<B1-Motion>', self.motionhandler)
+        self.group.bind('<ButtonRelease-1>', self.releasehandler)
+        self.makebottom()
+
+    def makebottom(self):
+        pass
+
+    def __repr__(self):
+        """Return a string for debug print statements."""
+        return "%s(%d, %d)" % (self.__class__.__name__, self.x, self.y)
+
+    # Public methods
+
+    def add(self, card):
+        self.cards.append(card)
+        card.tkraise()
+        self.position(card)
+        self.group.addtag_withtag(card.group)
+
+    def delete(self, card):
+        self.cards.remove(card)
+        card.group.dtag(self.group)
+
+    def showtop(self):
+        if self.cards:
+            self.cards[-1].showface()
+
+    def deal(self):
+        if not self.cards:
+            return None
+        card = self.cards[-1]
+        self.delete(card)
+        return card
+
+    # Subclass overridable methods
+
+    def position(self, card):
+        card.moveto(self.x, self.y)
+
+    def userclickhandler(self):
+        self.showtop()
+
+    def userdoubleclickhandler(self):
+        self.userclickhandler()
+
+    def usermovehandler(self, cards):
+        for card in cards:
+            self.position(card)
+
+    # Event handlers
+
+    def clickhandler(self, event):
+        self.finishmoving()             # In case we lost an event
+        self.userclickhandler()
+        self.startmoving(event)
+
+    def motionhandler(self, event):
+        self.keepmoving(event)
+
+    def releasehandler(self, event):
+        self.keepmoving(event)
+        self.finishmoving()
+
+    def doubleclickhandler(self, event):
+        self.finishmoving()             # In case we lost an event
+        self.userdoubleclickhandler()
+        self.startmoving(event)
+
+    # Move internals
+
+    moving = None
+
+    def startmoving(self, event):
+        self.moving = None
+        tags = self.game.canvas.gettags('current')
+        for i in range(len(self.cards)):
+            card = self.cards[i]
+            if card.group.tag in tags:
+                break
+        else:
+            return
+        if not card.face_shown:
+            return
+        self.moving = self.cards[i:]
+        self.lastx = event.x
+        self.lasty = event.y
+        for card in self.moving:
+            card.tkraise()
+
+    def keepmoving(self, event):
+        if not self.moving:
+            return
+        dx = event.x - self.lastx
+        dy = event.y - self.lasty
+        self.lastx = event.x
+        self.lasty = event.y
+        if dx or dy:
+            for card in self.moving:
+                card.moveby(dx, dy)
+
+    def finishmoving(self):
+        cards = self.moving
+        self.moving = None
+        if cards:
+            self.usermovehandler(cards)
+
+
+class Deck(Stack):
+
+    """The deck is a stack with support for shuffling.
+
+    New methods:
+
+    fill() -- create the playing cards
+    shuffle() -- shuffle the playing cards
+
+    A single click moves the top card to the game's open deck and
+    moves it face up; if we're out of cards, it moves the open deck
+    back to the deck.
+
+    """
+
+    def makebottom(self):
+        bottom = Rectangle(self.game.canvas,
+                           self.x, self.y,
+                           self.x+CARDWIDTH, self.y+CARDHEIGHT,
+                           outline='black', fill=BACKGROUND)
+        self.group.addtag_withtag(bottom)
+
+    def fill(self):
+        for suit in ALLSUITS:
+            for value in ALLVALUES:
+                self.add(Card(suit, value, self.game.canvas))
+
+    def shuffle(self):
+        n = len(self.cards)
+        newcards = []
+        for i in randperm(n):
+            newcards.append(self.cards[i])
+        self.cards = newcards
+
+    def userclickhandler(self):
+        opendeck = self.game.opendeck
+        card = self.deal()
+        if not card:
+            while 1:
+                card = opendeck.deal()
+                if not card:
+                    break
+                self.add(card)
+                card.showback()
+        else:
+            self.game.opendeck.add(card)
+            card.showface()
+
+
+def randperm(n):
+    """Function returning a random permutation of range(n)."""
+    r = range(n)
+    x = []
+    while r:
+        i = random.choice(r)
+        x.append(i)
+        r.remove(i)
+    return x
+
+
+class OpenStack(Stack):
+
+    def acceptable(self, cards):
+        return 0
+
+    def usermovehandler(self, cards):
+        card = cards[0]
+        stack = self.game.closeststack(card)
+        if not stack or stack is self or not stack.acceptable(cards):
+            Stack.usermovehandler(self, cards)
+        else:
+            for card in cards:
+                self.delete(card)
+                stack.add(card)
+            self.game.wincheck()
+
+    def userdoubleclickhandler(self):
+        if not self.cards:
+            return
+        card = self.cards[-1]
+        if not card.face_shown:
+            self.userclickhandler()
+            return
+        for s in self.game.suits:
+            if s.acceptable([card]):
+                self.delete(card)
+                s.add(card)
+                self.game.wincheck()
+                break
+
+
+class SuitStack(OpenStack):
+
+    def makebottom(self):
+        bottom = Rectangle(self.game.canvas,
+                           self.x, self.y,
+                           self.x+CARDWIDTH, self.y+CARDHEIGHT,
+                           outline='black', fill='')
+
+    def userclickhandler(self):
+        pass
+
+    def userdoubleclickhandler(self):
+        pass
+
+    def acceptable(self, cards):
+        if len(cards) != 1:
+            return 0
+        card = cards[0]
+        if not self.cards:
+            return card.value == ACE
+        topcard = self.cards[-1]
+        return card.suit == topcard.suit and card.value == topcard.value + 1
+
+
+class RowStack(OpenStack):
+
+    def acceptable(self, cards):
+        card = cards[0]
+        if not self.cards:
+            return card.value == KING
+        topcard = self.cards[-1]
+        if not topcard.face_shown:
+            return 0
+        return card.color != topcard.color and card.value == topcard.value - 1
+
+    def position(self, card):
+        y = self.y
+        for c in self.cards:
+            if c == card:
+                break
+            if c.face_shown:
+                y = y + 2*MARGIN
+            else:
+                y = y + OFFSET
+        card.moveto(self.x, y)
+
+
+class Solitaire:
+
+    def __init__(self, master):
+        self.master = master
+
+        self.canvas = Canvas(self.master,
+                             background=BACKGROUND,
+                             highlightthickness=0,
+                             width=NROWS*XSPACING,
+                             height=3*YSPACING + 20 + MARGIN)
+        self.canvas.pack(fill=BOTH, expand=TRUE)
+
+        self.dealbutton = Button(self.canvas,
+                                 text="Deal",
+                                 highlightthickness=0,
+                                 background=BACKGROUND,
+                                 activebackground="green",
+                                 command=self.deal)
+        Window(self.canvas, MARGIN, 3*YSPACING + 20,
+               window=self.dealbutton, anchor=SW)
+
+        x = MARGIN
+        y = MARGIN
+
+        self.deck = Deck(x, y, self)
+
+        x = x + XSPACING
+        self.opendeck = OpenStack(x, y, self)
+
+        x = x + XSPACING
+        self.suits = []
+        for i in range(NSUITS):
+            x = x + XSPACING
+            self.suits.append(SuitStack(x, y, self))
+
+        x = MARGIN
+        y = y + YSPACING
+
+        self.rows = []
+        for i in range(NROWS):
+            self.rows.append(RowStack(x, y, self))
+            x = x + XSPACING
+
+        self.openstacks = [self.opendeck] + self.suits + self.rows
+
+        self.deck.fill()
+        self.deal()
+
+    def wincheck(self):
+        for s in self.suits:
+            if len(s.cards) != NVALUES:
+                return
+        self.win()
+        self.deal()
+
+    def win(self):
+        """Stupid animation when you win."""
+        cards = []
+        for s in self.openstacks:
+            cards = cards + s.cards
+        while cards:
+            card = random.choice(cards)
+            cards.remove(card)
+            self.animatedmoveto(card, self.deck)
+
+    def animatedmoveto(self, card, dest):
+        for i in range(10, 0, -1):
+            dx, dy = (dest.x-card.x)/i, (dest.y-card.y)/i
+            card.moveby(dx, dy)
+            self.master.update_idletasks()
+
+    def closeststack(self, card):
+        closest = None
+        cdist = 999999999
+        # Since we only compare distances,
+        # we don't bother to take the square root.
+        for stack in self.openstacks:
+            dist = (stack.x - card.x)**2 + (stack.y - card.y)**2
+            if dist < cdist:
+                closest = stack
+                cdist = dist
+        return closest
+
+    def deal(self):
+        self.reset()
+        self.deck.shuffle()
+        for i in range(NROWS):
+            for r in self.rows[i:]:
+                card = self.deck.deal()
+                r.add(card)
+        for r in self.rows:
+            r.showtop()
+
+    def reset(self):
+        for stack in self.openstacks:
+            while 1:
+                card = stack.deal()
+                if not card:
+                    break
+                self.deck.add(card)
+                card.showback()
+
+
+# Main function, run when invoked as a stand-alone Python program.
+
+def main():
+    root = Tk()
+    game = Solitaire(root)
+    root.protocol('WM_DELETE_WINDOW', root.quit)
+    root.mainloop()
+
+if __name__ == '__main__':
+    main()


Property changes on: vendor/Python/current/Demo/tkinter/guido/solitaire.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tkinter/guido/sortvisu.py
===================================================================
--- vendor/Python/current/Demo/tkinter/guido/sortvisu.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/guido/sortvisu.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,634 @@
+#! /usr/bin/env python
+
+"""Sorting algorithms visualizer using Tkinter.
+
+This module is comprised of three ``components'':
+
+- an array visualizer with methods that implement basic sorting
+operations (compare, swap) as well as methods for ``annotating'' the
+sorting algorithm (e.g. to show the pivot element);
+
+- a number of sorting algorithms (currently quicksort, insertion sort,
+selection sort and bubble sort, as well as a randomization function),
+all using the array visualizer for its basic operations and with calls
+to its annotation methods;
+
+- and a ``driver'' class which can be used as a Grail applet or as a
+stand-alone application.
+
+"""
+
+
+from Tkinter import *
+from Canvas import Line, Rectangle
+import random
+
+
+XGRID = 10
+YGRID = 10
+WIDTH = 6
+
+
+class Array:
+
+    def __init__(self, master, data=None):
+        self.master = master
+        self.frame = Frame(self.master)
+        self.frame.pack(fill=X)
+        self.label = Label(self.frame)
+        self.label.pack()
+        self.canvas = Canvas(self.frame)
+        self.canvas.pack()
+        self.report = Label(self.frame)
+        self.report.pack()
+        self.left = Line(self.canvas, 0, 0, 0, 0)
+        self.right = Line(self.canvas, 0, 0, 0, 0)
+        self.pivot = Line(self.canvas, 0, 0, 0, 0)
+        self.items = []
+        self.size = self.maxvalue = 0
+        if data:
+            self.setdata(data)
+
+    def setdata(self, data):
+        olditems = self.items
+        self.items = []
+        for item in olditems:
+            item.delete()
+        self.size = len(data)
+        self.maxvalue = max(data)
+        self.canvas.config(width=(self.size+1)*XGRID,
+                           height=(self.maxvalue+1)*YGRID)
+        for i in range(self.size):
+            self.items.append(ArrayItem(self, i, data[i]))
+        self.reset("Sort demo, size %d" % self.size)
+
+    speed = "normal"
+
+    def setspeed(self, speed):
+        self.speed = speed
+
+    def destroy(self):
+        self.frame.destroy()
+
+    in_mainloop = 0
+    stop_mainloop = 0
+
+    def cancel(self):
+        self.stop_mainloop = 1
+        if self.in_mainloop:
+            self.master.quit()
+
+    def step(self):
+        if self.in_mainloop:
+            self.master.quit()
+
+    Cancelled = "Array.Cancelled"       # Exception
+
+    def wait(self, msecs):
+        if self.speed == "fastest":
+            msecs = 0
+        elif self.speed == "fast":
+            msecs = msecs/10
+        elif self.speed == "single-step":
+            msecs = 1000000000
+        if not self.stop_mainloop:
+            self.master.update()
+            id = self.master.after(msecs, self.master.quit)
+            self.in_mainloop = 1
+            self.master.mainloop()
+            self.master.after_cancel(id)
+            self.in_mainloop = 0
+        if self.stop_mainloop:
+            self.stop_mainloop = 0
+            self.message("Cancelled")
+            raise Array.Cancelled
+
+    def getsize(self):
+        return self.size
+
+    def show_partition(self, first, last):
+        for i in range(self.size):
+            item = self.items[i]
+            if first <= i < last:
+                item.item.config(fill='red')
+            else:
+                item.item.config(fill='orange')
+        self.hide_left_right_pivot()
+
+    def hide_partition(self):
+        for i in range(self.size):
+            item = self.items[i]
+            item.item.config(fill='red')
+        self.hide_left_right_pivot()
+
+    def show_left(self, left):
+        if not 0 <= left < self.size:
+            self.hide_left()
+            return
+        x1, y1, x2, y2 = self.items[left].position()
+##      top, bot = HIRO
+        self.left.coords([(x1-2, 0), (x1-2, 9999)])
+        self.master.update()
+
+    def show_right(self, right):
+        if not 0 <= right < self.size:
+            self.hide_right()
+            return
+        x1, y1, x2, y2 = self.items[right].position()
+        self.right.coords(((x2+2, 0), (x2+2, 9999)))
+        self.master.update()
+
+    def hide_left_right_pivot(self):
+        self.hide_left()
+        self.hide_right()
+        self.hide_pivot()
+
+    def hide_left(self):
+        self.left.coords(((0, 0), (0, 0)))
+
+    def hide_right(self):
+        self.right.coords(((0, 0), (0, 0)))
+
+    def show_pivot(self, pivot):
+        x1, y1, x2, y2 = self.items[pivot].position()
+        self.pivot.coords(((0, y1-2), (9999, y1-2)))
+
+    def hide_pivot(self):
+        self.pivot.coords(((0, 0), (0, 0)))
+
+    def swap(self, i, j):
+        if i == j: return
+        self.countswap()
+        item = self.items[i]
+        other = self.items[j]
+        self.items[i], self.items[j] = other, item
+        item.swapwith(other)
+
+    def compare(self, i, j):
+        self.countcompare()
+        item = self.items[i]
+        other = self.items[j]
+        return item.compareto(other)
+
+    def reset(self, msg):
+        self.ncompares = 0
+        self.nswaps = 0
+        self.message(msg)
+        self.updatereport()
+        self.hide_partition()
+
+    def message(self, msg):
+        self.label.config(text=msg)
+
+    def countswap(self):
+        self.nswaps = self.nswaps + 1
+        self.updatereport()
+
+    def countcompare(self):
+        self.ncompares = self.ncompares + 1
+        self.updatereport()
+
+    def updatereport(self):
+        text = "%d cmps, %d swaps" % (self.ncompares, self.nswaps)
+        self.report.config(text=text)
+
+
+class ArrayItem:
+
+    def __init__(self, array, index, value):
+        self.array = array
+        self.index = index
+        self.value = value
+        x1, y1, x2, y2 = self.position()
+        self.item = Rectangle(array.canvas, x1, y1, x2, y2,
+                              fill='red', outline='black', width=1)
+        self.item.bind('<Button-1>', self.mouse_down)
+        self.item.bind('<Button1-Motion>', self.mouse_move)
+        self.item.bind('<ButtonRelease-1>', self.mouse_up)
+
+    def delete(self):
+        item = self.item
+        self.array = None
+        self.item = None
+        item.delete()
+
+    def mouse_down(self, event):
+        self.lastx = event.x
+        self.lasty = event.y
+        self.origx = event.x
+        self.origy = event.y
+        self.item.tkraise()
+
+    def mouse_move(self, event):
+        self.item.move(event.x - self.lastx, event.y - self.lasty)
+        self.lastx = event.x
+        self.lasty = event.y
+
+    def mouse_up(self, event):
+        i = self.nearestindex(event.x)
+        if i >= self.array.getsize():
+            i = self.array.getsize() - 1
+        if i < 0:
+            i = 0
+        other = self.array.items[i]
+        here = self.index
+        self.array.items[here], self.array.items[i] = other, self
+        self.index = i
+        x1, y1, x2, y2 = self.position()
+        self.item.coords(((x1, y1), (x2, y2)))
+        other.setindex(here)
+
+    def setindex(self, index):
+        nsteps = steps(self.index, index)
+        if not nsteps: return
+        if self.array.speed == "fastest":
+            nsteps = 0
+        oldpts = self.position()
+        self.index = index
+        newpts = self.position()
+        trajectory = interpolate(oldpts, newpts, nsteps)
+        self.item.tkraise()
+        for pts in trajectory:
+            self.item.coords((pts[:2], pts[2:]))
+            self.array.wait(50)
+
+    def swapwith(self, other):
+        nsteps = steps(self.index, other.index)
+        if not nsteps: return
+        if self.array.speed == "fastest":
+            nsteps = 0
+        myoldpts = self.position()
+        otheroldpts = other.position()
+        self.index, other.index = other.index, self.index
+        mynewpts = self.position()
+        othernewpts = other.position()
+        myfill = self.item['fill']
+        otherfill = other.item['fill']
+        self.item.config(fill='green')
+        other.item.config(fill='yellow')
+        self.array.master.update()
+        if self.array.speed == "single-step":
+            self.item.coords((mynewpts[:2], mynewpts[2:]))
+            other.item.coords((othernewpts[:2], othernewpts[2:]))
+            self.array.master.update()
+            self.item.config(fill=myfill)
+            other.item.config(fill=otherfill)
+            self.array.wait(0)
+            return
+        mytrajectory = interpolate(myoldpts, mynewpts, nsteps)
+        othertrajectory = interpolate(otheroldpts, othernewpts, nsteps)
+        if self.value > other.value:
+            self.item.tkraise()
+            other.item.tkraise()
+        else:
+            other.item.tkraise()
+            self.item.tkraise()
+        try:
+            for i in range(len(mytrajectory)):
+                mypts = mytrajectory[i]
+                otherpts = othertrajectory[i]
+                self.item.coords((mypts[:2], mypts[2:]))
+                other.item.coords((otherpts[:2], otherpts[2:]))
+                self.array.wait(50)
+        finally:
+            mypts = mytrajectory[-1]
+            otherpts = othertrajectory[-1]
+            self.item.coords((mypts[:2], mypts[2:]))
+            other.item.coords((otherpts[:2], otherpts[2:]))
+            self.item.config(fill=myfill)
+            other.item.config(fill=otherfill)
+
+    def compareto(self, other):
+        myfill = self.item['fill']
+        otherfill = other.item['fill']
+        outcome = cmp(self.value, other.value)
+        if outcome < 0:
+            myflash = 'white'
+            otherflash = 'black'
+        elif outcome > 0:
+            myflash = 'black'
+            otherflash = 'white'
+        else:
+            myflash = otherflash = 'grey'
+        try:
+            self.item.config(fill=myflash)
+            other.item.config(fill=otherflash)
+            self.array.wait(500)
+        finally:
+            self.item.config(fill=myfill)
+            other.item.config(fill=otherfill)
+        return outcome
+
+    def position(self):
+        x1 = (self.index+1)*XGRID - WIDTH/2
+        x2 = x1+WIDTH
+        y2 = (self.array.maxvalue+1)*YGRID
+        y1 = y2 - (self.value)*YGRID
+        return x1, y1, x2, y2
+
+    def nearestindex(self, x):
+        return int(round(float(x)/XGRID)) - 1
+
+
+# Subroutines that don't need an object
+
+def steps(here, there):
+    nsteps = abs(here - there)
+    if nsteps <= 3:
+        nsteps = nsteps * 3
+    elif nsteps <= 5:
+        nsteps = nsteps * 2
+    elif nsteps > 10:
+        nsteps = 10
+    return nsteps
+
+def interpolate(oldpts, newpts, n):
+    if len(oldpts) != len(newpts):
+        raise ValueError, "can't interpolate arrays of different length"
+    pts = [0]*len(oldpts)
+    res = [tuple(oldpts)]
+    for i in range(1, n):
+        for k in range(len(pts)):
+            pts[k] = oldpts[k] + (newpts[k] - oldpts[k])*i/n
+        res.append(tuple(pts))
+    res.append(tuple(newpts))
+    return res
+
+
+# Various (un)sorting algorithms
+
+def uniform(array):
+    size = array.getsize()
+    array.setdata([(size+1)/2] * size)
+    array.reset("Uniform data, size %d" % size)
+
+def distinct(array):
+    size = array.getsize()
+    array.setdata(range(1, size+1))
+    array.reset("Distinct data, size %d" % size)
+
+def randomize(array):
+    array.reset("Randomizing")
+    n = array.getsize()
+    for i in range(n):
+        j = random.randint(0, n-1)
+        array.swap(i, j)
+    array.message("Randomized")
+
+def insertionsort(array):
+    size = array.getsize()
+    array.reset("Insertion sort")
+    for i in range(1, size):
+        j = i-1
+        while j >= 0:
+            if array.compare(j, j+1) <= 0:
+                break
+            array.swap(j, j+1)
+            j = j-1
+    array.message("Sorted")
+
+def selectionsort(array):
+    size = array.getsize()
+    array.reset("Selection sort")
+    try:
+        for i in range(size):
+            array.show_partition(i, size)
+            for j in range(i+1, size):
+                if array.compare(i, j) > 0:
+                    array.swap(i, j)
+        array.message("Sorted")
+    finally:
+        array.hide_partition()
+
+def bubblesort(array):
+    size = array.getsize()
+    array.reset("Bubble sort")
+    for i in range(size):
+        for j in range(1, size):
+            if array.compare(j-1, j) > 0:
+                array.swap(j-1, j)
+    array.message("Sorted")
+
+def quicksort(array):
+    size = array.getsize()
+    array.reset("Quicksort")
+    try:
+        stack = [(0, size)]
+        while stack:
+            first, last = stack[-1]
+            del stack[-1]
+            array.show_partition(first, last)
+            if last-first < 5:
+                array.message("Insertion sort")
+                for i in range(first+1, last):
+                    j = i-1
+                    while j >= first:
+                        if array.compare(j, j+1) <= 0:
+                            break
+                        array.swap(j, j+1)
+                        j = j-1
+                continue
+            array.message("Choosing pivot")
+            j, i, k = first, (first+last)/2, last-1
+            if array.compare(k, i) < 0:
+                array.swap(k, i)
+            if array.compare(k, j) < 0:
+                array.swap(k, j)
+            if array.compare(j, i) < 0:
+                array.swap(j, i)
+            pivot = j
+            array.show_pivot(pivot)
+            array.message("Pivot at left of partition")
+            array.wait(1000)
+            left = first
+            right = last
+            while 1:
+                array.message("Sweep right pointer")
+                right = right-1
+                array.show_right(right)
+                while right > first and array.compare(right, pivot) >= 0:
+                    right = right-1
+                    array.show_right(right)
+                array.message("Sweep left pointer")
+                left = left+1
+                array.show_left(left)
+                while left < last and array.compare(left, pivot) <= 0:
+                    left = left+1
+                    array.show_left(left)
+                if left > right:
+                    array.message("End of partition")
+                    break
+                array.message("Swap items")
+                array.swap(left, right)
+            array.message("Swap pivot back")
+            array.swap(pivot, right)
+            n1 = right-first
+            n2 = last-left
+            if n1 > 1: stack.append((first, right))
+            if n2 > 1: stack.append((left, last))
+        array.message("Sorted")
+    finally:
+        array.hide_partition()
+
+def demosort(array):
+    while 1:
+        for alg in [quicksort, insertionsort, selectionsort, bubblesort]:
+            randomize(array)
+            alg(array)
+
+
+# Sort demo class -- usable as a Grail applet
+
+class SortDemo:
+
+    def __init__(self, master, size=15):
+        self.master = master
+        self.size = size
+        self.busy = 0
+        self.array = Array(self.master)
+
+        self.botframe = Frame(master)
+        self.botframe.pack(side=BOTTOM)
+        self.botleftframe = Frame(self.botframe)
+        self.botleftframe.pack(side=LEFT, fill=Y)
+        self.botrightframe = Frame(self.botframe)
+        self.botrightframe.pack(side=RIGHT, fill=Y)
+
+        self.b_qsort = Button(self.botleftframe,
+                              text="Quicksort", command=self.c_qsort)
+        self.b_qsort.pack(fill=X)
+        self.b_isort = Button(self.botleftframe,
+                              text="Insertion sort", command=self.c_isort)
+        self.b_isort.pack(fill=X)
+        self.b_ssort = Button(self.botleftframe,
+                              text="Selection sort", command=self.c_ssort)
+        self.b_ssort.pack(fill=X)
+        self.b_bsort = Button(self.botleftframe,
+                              text="Bubble sort", command=self.c_bsort)
+        self.b_bsort.pack(fill=X)
+
+        # Terrible hack to overcome limitation of OptionMenu...
+        class MyIntVar(IntVar):
+            def __init__(self, master, demo):
+                self.demo = demo
+                IntVar.__init__(self, master)
+            def set(self, value):
+                IntVar.set(self, value)
+                if str(value) != '0':
+                    self.demo.resize(value)
+
+        self.v_size = MyIntVar(self.master, self)
+        self.v_size.set(size)
+        sizes = [1, 2, 3, 4] + range(5, 55, 5)
+        if self.size not in sizes:
+            sizes.append(self.size)
+            sizes.sort()
+        self.m_size = apply(OptionMenu,
+                            (self.botleftframe, self.v_size) + tuple(sizes))
+        self.m_size.pack(fill=X)
+
+        self.v_speed = StringVar(self.master)
+        self.v_speed.set("normal")
+        self.m_speed = OptionMenu(self.botleftframe, self.v_speed,
+                                  "single-step", "normal", "fast", "fastest")
+        self.m_speed.pack(fill=X)
+
+        self.b_step = Button(self.botleftframe,
+                             text="Step", command=self.c_step)
+        self.b_step.pack(fill=X)
+
+        self.b_randomize = Button(self.botrightframe,
+                                  text="Randomize", command=self.c_randomize)
+        self.b_randomize.pack(fill=X)
+        self.b_uniform = Button(self.botrightframe,
+                                  text="Uniform", command=self.c_uniform)
+        self.b_uniform.pack(fill=X)
+        self.b_distinct = Button(self.botrightframe,
+                                  text="Distinct", command=self.c_distinct)
+        self.b_distinct.pack(fill=X)
+        self.b_demo = Button(self.botrightframe,
+                             text="Demo", command=self.c_demo)
+        self.b_demo.pack(fill=X)
+        self.b_cancel = Button(self.botrightframe,
+                               text="Cancel", command=self.c_cancel)
+        self.b_cancel.pack(fill=X)
+        self.b_cancel.config(state=DISABLED)
+        self.b_quit = Button(self.botrightframe,
+                             text="Quit", command=self.c_quit)
+        self.b_quit.pack(fill=X)
+
+    def resize(self, newsize):
+        if self.busy:
+            self.master.bell()
+            return
+        self.size = newsize
+        self.array.setdata(range(1, self.size+1))
+
+    def c_qsort(self):
+        self.run(quicksort)
+
+    def c_isort(self):
+        self.run(insertionsort)
+
+    def c_ssort(self):
+        self.run(selectionsort)
+
+    def c_bsort(self):
+        self.run(bubblesort)
+
+    def c_demo(self):
+        self.run(demosort)
+
+    def c_randomize(self):
+        self.run(randomize)
+
+    def c_uniform(self):
+        self.run(uniform)
+
+    def c_distinct(self):
+        self.run(distinct)
+
+    def run(self, func):
+        if self.busy:
+            self.master.bell()
+            return
+        self.busy = 1
+        self.array.setspeed(self.v_speed.get())
+        self.b_cancel.config(state=NORMAL)
+        try:
+            func(self.array)
+        except Array.Cancelled:
+            pass
+        self.b_cancel.config(state=DISABLED)
+        self.busy = 0
+
+    def c_cancel(self):
+        if not self.busy:
+            self.master.bell()
+            return
+        self.array.cancel()
+
+    def c_step(self):
+        if not self.busy:
+            self.master.bell()
+            return
+        self.v_speed.set("single-step")
+        self.array.setspeed("single-step")
+        self.array.step()
+
+    def c_quit(self):
+        if self.busy:
+            self.array.cancel()
+        self.master.after_idle(self.master.quit)
+
+
+# Main program -- for stand-alone operation outside Grail
+
+def main():
+    root = Tk()
+    demo = SortDemo(root)
+    root.protocol('WM_DELETE_WINDOW', demo.c_quit)
+    root.mainloop()
+
+if __name__ == '__main__':
+    main()

Added: vendor/Python/current/Demo/tkinter/guido/ss1.py
===================================================================
--- vendor/Python/current/Demo/tkinter/guido/ss1.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/guido/ss1.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,845 @@
+"""SS1 -- a spreadsheet."""
+
+import os
+import re
+import sys
+import cgi
+import rexec
+from xml.parsers import expat
+
+LEFT, CENTER, RIGHT = "LEFT", "CENTER", "RIGHT"
+
+def ljust(x, n):
+    return x.ljust(n)
+def center(x, n):
+    return x.center(n)
+def rjust(x, n):
+    return x.rjust(n)
+align2action = {LEFT: ljust, CENTER: center, RIGHT: rjust}
+
+align2xml = {LEFT: "left", CENTER: "center", RIGHT: "right"}
+xml2align = {"left": LEFT, "center": CENTER, "right": RIGHT}
+
+align2anchor = {LEFT: "w", CENTER: "center", RIGHT: "e"}
+
+def sum(seq):
+    total = 0
+    for x in seq:
+        if x is not None:
+            total += x
+    return total
+
+class Sheet:
+
+    def __init__(self):
+        self.cells = {} # {(x, y): cell, ...}
+        self.rexec = rexec.RExec()
+        m = self.rexec.add_module('__main__')
+        m.cell = self.cellvalue
+        m.cells = self.multicellvalue
+        m.sum = sum
+
+    def cellvalue(self, x, y):
+        cell = self.getcell(x, y)
+        if hasattr(cell, 'recalc'):
+            return cell.recalc(self.rexec)
+        else:
+            return cell
+
+    def multicellvalue(self, x1, y1, x2, y2):
+        if x1 > x2:
+            x1, x2 = x2, x1
+        if y1 > y2:
+            y1, y2 = y2, y1
+        seq = []
+        for y in range(y1, y2+1):
+            for x in range(x1, x2+1):
+                seq.append(self.cellvalue(x, y))
+        return seq
+
+    def getcell(self, x, y):
+        return self.cells.get((x, y))
+
+    def setcell(self, x, y, cell):
+        assert x > 0 and y > 0
+        assert isinstance(cell, BaseCell)
+        self.cells[x, y] = cell
+
+    def clearcell(self, x, y):
+        try:
+            del self.cells[x, y]
+        except KeyError:
+            pass
+
+    def clearcells(self, x1, y1, x2, y2):
+        for xy in self.selectcells(x1, y1, x2, y2):
+            del self.cells[xy]
+
+    def clearrows(self, y1, y2):
+        self.clearcells(0, y1, sys.maxint, y2)
+
+    def clearcolumns(self, x1, x2):
+        self.clearcells(x1, 0, x2, sys.maxint)
+
+    def selectcells(self, x1, y1, x2, y2):
+        if x1 > x2:
+            x1, x2 = x2, x1
+        if y1 > y2:
+            y1, y2 = y2, y1
+        return [(x, y) for x, y in self.cells
+                if x1 <= x <= x2 and y1 <= y <= y2]
+
+    def movecells(self, x1, y1, x2, y2, dx, dy):
+        if dx == 0 and dy == 0:
+            return
+        if x1 > x2:
+            x1, x2 = x2, x1
+        if y1 > y2:
+            y1, y2 = y2, y1
+        assert x1+dx > 0 and y1+dy > 0
+        new = {}
+        for x, y in self.cells:
+            cell = self.cells[x, y]
+            if hasattr(cell, 'renumber'):
+                cell = cell.renumber(x1, y1, x2, y2, dx, dy)
+            if x1 <= x <= x2 and y1 <= y <= y2:
+                x += dx
+                y += dy
+            new[x, y] = cell
+        self.cells = new
+
+    def insertrows(self, y, n):
+        assert n > 0
+        self.movecells(0, y, sys.maxint, sys.maxint, 0, n)
+
+    def deleterows(self, y1, y2):
+        if y1 > y2:
+            y1, y2 = y2, y1
+        self.clearrows(y1, y2)
+        self.movecells(0, y2+1, sys.maxint, sys.maxint, 0, y1-y2-1)
+
+    def insertcolumns(self, x, n):
+        assert n > 0
+        self.movecells(x, 0, sys.maxint, sys.maxint, n, 0)
+
+    def deletecolumns(self, x1, x2):
+        if x1 > x2:
+            x1, x2 = x2, x1
+        self.clearcells(x1, x2)
+        self.movecells(x2+1, 0, sys.maxint, sys.maxint, x1-x2-1, 0)
+
+    def getsize(self):
+        maxx = maxy = 0
+        for x, y in self.cells:
+            maxx = max(maxx, x)
+            maxy = max(maxy, y)
+        return maxx, maxy
+
+    def reset(self):
+        for cell in self.cells.itervalues():
+            if hasattr(cell, 'reset'):
+                cell.reset()
+
+    def recalc(self):
+        self.reset()
+        for cell in self.cells.itervalues():
+            if hasattr(cell, 'recalc'):
+                cell.recalc(self.rexec)
+
+    def display(self):
+        maxx, maxy = self.getsize()
+        width, height = maxx+1, maxy+1
+        colwidth = [1] * width
+        full = {}
+        # Add column heading labels in row 0
+        for x in range(1, width):
+            full[x, 0] = text, alignment = colnum2name(x), RIGHT
+            colwidth[x] = max(colwidth[x], len(text))
+        # Add row labels in column 0
+        for y in range(1, height):
+            full[0, y] = text, alignment = str(y), RIGHT
+            colwidth[0] = max(colwidth[0], len(text))
+        # Add sheet cells in columns with x>0 and y>0
+        for (x, y), cell in self.cells.iteritems():
+            if x <= 0 or y <= 0:
+                continue
+            if hasattr(cell, 'recalc'):
+                cell.recalc(self.rexec)
+            if hasattr(cell, 'format'):
+                text, alignment = cell.format()
+                assert isinstance(text, str)
+                assert alignment in (LEFT, CENTER, RIGHT)
+            else:
+                text = str(cell)
+                if isinstance(cell, str):
+                    alignment = LEFT
+                else:
+                    alignment = RIGHT
+            full[x, y] = (text, alignment)
+            colwidth[x] = max(colwidth[x], len(text))
+        # Calculate the horizontal separator line (dashes and dots)
+        sep = ""
+        for x in range(width):
+            if sep:
+                sep += "+"
+            sep += "-"*colwidth[x]
+        # Now print The full grid
+        for y in range(height):
+            line = ""
+            for x in range(width):
+                text, alignment = full.get((x, y)) or ("", LEFT)
+                text = align2action[alignment](text, colwidth[x])
+                if line:
+                    line += '|'
+                line += text
+            print line
+            if y == 0:
+                print sep
+
+    def xml(self):
+        out = ['<spreadsheet>']
+        for (x, y), cell in self.cells.iteritems():
+            if hasattr(cell, 'xml'):
+                cellxml = cell.xml()
+            else:
+                cellxml = '<value>%s</value>' % cgi.escape(cell)
+            out.append('<cell row="%s" col="%s">\n  %s\n</cell>' %
+                       (y, x, cellxml))
+        out.append('</spreadsheet>')
+        return '\n'.join(out)
+
+    def save(self, filename):
+        text = self.xml()
+        f = open(filename, "w")
+        f.write(text)
+        if text and not text.endswith('\n'):
+            f.write('\n')
+        f.close()
+
+    def load(self, filename):
+        f = open(filename, 'r')
+        SheetParser(self).parsefile(f)
+        f.close()
+
+class SheetParser:
+
+    def __init__(self, sheet):
+        self.sheet = sheet
+
+    def parsefile(self, f):
+        parser = expat.ParserCreate()
+        parser.StartElementHandler = self.startelement
+        parser.EndElementHandler = self.endelement
+        parser.CharacterDataHandler = self.data
+        parser.ParseFile(f)
+
+    def startelement(self, tag, attrs):
+        method = getattr(self, 'start_'+tag, None)
+        if method:
+            for key, value in attrs.iteritems():
+                attrs[key] = str(value) # XXX Convert Unicode to 8-bit
+            method(attrs)
+        self.texts = []
+
+    def data(self, text):
+        text = str(text) # XXX Convert Unicode to 8-bit
+        self.texts.append(text)
+
+    def endelement(self, tag):
+        method = getattr(self, 'end_'+tag, None)
+        if method:
+            method("".join(self.texts))
+
+    def start_cell(self, attrs):
+        self.y = int(attrs.get("row"))
+        self.x = int(attrs.get("col"))
+
+    def start_value(self, attrs):
+        self.fmt = attrs.get('format')
+        self.alignment = xml2align.get(attrs.get('align'))
+
+    start_formula = start_value
+
+    def end_int(self, text):
+        try:
+            self.value = int(text)
+        except:
+            self.value = None
+
+    def end_long(self, text):
+        try:
+            self.value = long(text)
+        except:
+            self.value = None
+
+    def end_double(self, text):
+        try:
+            self.value = float(text)
+        except:
+            self.value = None
+
+    def end_complex(self, text):
+        try:
+            self.value = complex(text)
+        except:
+            self.value = None
+
+    def end_string(self, text):
+        try:
+            self.value = text
+        except:
+            self.value = None
+
+    def end_value(self, text):
+        if isinstance(self.value, BaseCell):
+            self.cell = self.value
+        elif isinstance(self.value, str):
+            self.cell = StringCell(self.value,
+                                   self.fmt or "%s",
+                                   self.alignment or LEFT)
+        else:
+            self.cell = NumericCell(self.value,
+                                    self.fmt or "%s",
+                                    self.alignment or RIGHT)
+
+    def end_formula(self, text):
+        self.cell = FormulaCell(text,
+                                self.fmt or "%s",
+                                self.alignment or RIGHT)
+
+    def end_cell(self, text):
+        self.sheet.setcell(self.x, self.y, self.cell)
+
+class BaseCell:
+    __init__ = None # Must provide
+    """Abstract base class for sheet cells.
+
+    Subclasses may but needn't provide the following APIs:
+
+    cell.reset() -- prepare for recalculation
+    cell.recalc(rexec) -> value -- recalculate formula
+    cell.format() -> (value, alignment) -- return formatted value
+    cell.xml() -> string -- return XML
+    """
+
+class NumericCell(BaseCell):
+
+    def __init__(self, value, fmt="%s", alignment=RIGHT):
+        assert isinstance(value, (int, long, float, complex))
+        assert alignment in (LEFT, CENTER, RIGHT)
+        self.value = value
+        self.fmt = fmt
+        self.alignment = alignment
+
+    def recalc(self, rexec):
+        return self.value
+
+    def format(self):
+        try:
+            text = self.fmt % self.value
+        except:
+            text = str(self.value)
+        return text, self.alignment
+
+    def xml(self):
+        method = getattr(self, '_xml_' + type(self.value).__name__)
+        return '<value align="%s" format="%s">%s</value>' % (
+                align2xml[self.alignment],
+                self.fmt,
+                method())
+
+    def _xml_int(self):
+        if -2**31 <= self.value < 2**31:
+            return '<int>%s</int>' % self.value
+        else:
+            return self._xml_long()
+
+    def _xml_long(self):
+        return '<long>%s</long>' % self.value
+
+    def _xml_float(self):
+        return '<double>%s</double>' % repr(self.value)
+
+    def _xml_complex(self):
+        return '<complex>%s</double>' % repr(self.value)
+
+class StringCell(BaseCell):
+
+    def __init__(self, text, fmt="%s", alignment=LEFT):
+        assert isinstance(text, (str, unicode))
+        assert alignment in (LEFT, CENTER, RIGHT)
+        self.text = text
+        self.fmt = fmt
+        self.alignment = alignment
+
+    def recalc(self, rexec):
+        return self.text
+
+    def format(self):
+        return self.text, self.alignment
+
+    def xml(self):
+        s = '<value align="%s" format="%s"><string>%s</string></value>'
+        return s % (
+            align2xml[self.alignment],
+            self.fmt,
+            cgi.escape(self.text))
+
+class FormulaCell(BaseCell):
+
+    def __init__(self, formula, fmt="%s", alignment=RIGHT):
+        assert alignment in (LEFT, CENTER, RIGHT)
+        self.formula = formula
+        self.translated = translate(self.formula)
+        self.fmt = fmt
+        self.alignment = alignment
+        self.reset()
+
+    def reset(self):
+        self.value = None
+
+    def recalc(self, rexec):
+        if self.value is None:
+            try:
+                # A hack to evaluate expressions using true division
+                rexec.r_exec("from __future__ import division\n" +
+                             "__value__ = eval(%s)" % repr(self.translated))
+                self.value = rexec.r_eval("__value__")
+            except:
+                exc = sys.exc_info()[0]
+                if hasattr(exc, "__name__"):
+                    self.value = exc.__name__
+                else:
+                    self.value = str(exc)
+        return self.value
+
+    def format(self):
+        try:
+            text = self.fmt % self.value
+        except:
+            text = str(self.value)
+        return text, self.alignment
+
+    def xml(self):
+        return '<formula align="%s" format="%s">%s</formula>' % (
+            align2xml[self.alignment],
+            self.fmt,
+            self.formula)
+
+    def renumber(self, x1, y1, x2, y2, dx, dy):
+        out = []
+        for part in re.split('(\w+)', self.formula):
+            m = re.match('^([A-Z]+)([1-9][0-9]*)$', part)
+            if m is not None:
+                sx, sy = m.groups()
+                x = colname2num(sx)
+                y = int(sy)
+                if x1 <= x <= x2 and y1 <= y <= y2:
+                    part = cellname(x+dx, y+dy)
+            out.append(part)
+        return FormulaCell("".join(out), self.fmt, self.alignment)
+
+def translate(formula):
+    """Translate a formula containing fancy cell names to valid Python code.
+
+    Examples:
+        B4 -> cell(2, 4)
+        B4:Z100 -> cells(2, 4, 26, 100)
+    """
+    out = []
+    for part in re.split(r"(\w+(?::\w+)?)", formula):
+        m = re.match(r"^([A-Z]+)([1-9][0-9]*)(?::([A-Z]+)([1-9][0-9]*))?$", part)
+        if m is None:
+            out.append(part)
+        else:
+            x1, y1, x2, y2 = m.groups()
+            x1 = colname2num(x1)
+            if x2 is None:
+                s = "cell(%s, %s)" % (x1, y1)
+            else:
+                x2 = colname2num(x2)
+                s = "cells(%s, %s, %s, %s)" % (x1, y1, x2, y2)
+            out.append(s)
+    return "".join(out)
+
+def cellname(x, y):
+    "Translate a cell coordinate to a fancy cell name (e.g. (1, 1)->'A1')."
+    assert x > 0 # Column 0 has an empty name, so can't use that
+    return colnum2name(x) + str(y)
+
+def colname2num(s):
+    "Translate a column name to number (e.g. 'A'->1, 'Z'->26, 'AA'->27)."
+    s = s.upper()
+    n = 0
+    for c in s:
+        assert 'A' <= c <= 'Z'
+        n = n*26 + ord(c) - ord('A') + 1
+    return n
+
+def colnum2name(n):
+    "Translate a column number to name (e.g. 1->'A', etc.)."
+    assert n > 0
+    s = ""
+    while n:
+        n, m = divmod(n-1, 26)
+        s = chr(m+ord('A')) + s
+    return s
+
+import Tkinter as Tk
+
+class SheetGUI:
+
+    """Beginnings of a GUI for a spreadsheet.
+
+    TO DO:
+    - clear multiple cells
+    - Insert, clear, remove rows or columns
+    - Show new contents while typing
+    - Scroll bars
+    - Grow grid when window is grown
+    - Proper menus
+    - Undo, redo
+    - Cut, copy and paste
+    - Formatting and alignment
+    """
+
+    def __init__(self, filename="sheet1.xml", rows=10, columns=5):
+        """Constructor.
+
+        Load the sheet from the filename argument.
+        Set up the Tk widget tree.
+        """
+        # Create and load the sheet
+        self.filename = filename
+        self.sheet = Sheet()
+        if os.path.isfile(filename):
+            self.sheet.load(filename)
+        # Calculate the needed grid size
+        maxx, maxy = self.sheet.getsize()
+        rows = max(rows, maxy)
+        columns = max(columns, maxx)
+        # Create the widgets
+        self.root = Tk.Tk()
+        self.root.wm_title("Spreadsheet: %s" % self.filename)
+        self.beacon = Tk.Label(self.root, text="A1",
+                               font=('helvetica', 16, 'bold'))
+        self.entry = Tk.Entry(self.root)
+        self.savebutton = Tk.Button(self.root, text="Save",
+                                    command=self.save)
+        self.cellgrid = Tk.Frame(self.root)
+        # Configure the widget lay-out
+        self.cellgrid.pack(side="bottom", expand=1, fill="both")
+        self.beacon.pack(side="left")
+        self.savebutton.pack(side="right")
+        self.entry.pack(side="left", expand=1, fill="x")
+        # Bind some events
+        self.entry.bind("<Return>", self.return_event)
+        self.entry.bind("<Shift-Return>", self.shift_return_event)
+        self.entry.bind("<Tab>", self.tab_event)
+        self.entry.bind("<Shift-Tab>", self.shift_tab_event)
+        self.entry.bind("<Delete>", self.delete_event)
+        self.entry.bind("<Escape>", self.escape_event)
+        # Now create the cell grid
+        self.makegrid(rows, columns)
+        # Select the top-left cell
+        self.currentxy = None
+        self.cornerxy = None
+        self.setcurrent(1, 1)
+        # Copy the sheet cells to the GUI cells
+        self.sync()
+
+    def delete_event(self, event):
+        if self.cornerxy != self.currentxy and self.cornerxy is not None:
+            self.sheet.clearcells(*(self.currentxy + self.cornerxy))
+        else:
+            self.sheet.clearcell(*self.currentxy)
+        self.sync()
+        self.entry.delete(0, 'end')
+        return "break"
+
+    def escape_event(self, event):
+        x, y = self.currentxy
+        self.load_entry(x, y)
+
+    def load_entry(self, x, y):
+        cell = self.sheet.getcell(x, y)
+        if cell is None:
+            text = ""
+        elif isinstance(cell, FormulaCell):
+            text = '=' + cell.formula
+        else:
+            text, alignment = cell.format()
+        self.entry.delete(0, 'end')
+        self.entry.insert(0, text)
+        self.entry.selection_range(0, 'end')
+
+    def makegrid(self, rows, columns):
+        """Helper to create the grid of GUI cells.
+
+        The edge (x==0 or y==0) is filled with labels; the rest is real cells.
+        """
+        self.rows = rows
+        self.columns = columns
+        self.gridcells = {}
+        # Create the top left corner cell (which selects all)
+        cell = Tk.Label(self.cellgrid, relief='raised')
+        cell.grid_configure(column=0, row=0, sticky='NSWE')
+        cell.bind("<ButtonPress-1>", self.selectall)
+        # Create the top row of labels, and confiure the grid columns
+        for x in range(1, columns+1):
+            self.cellgrid.grid_columnconfigure(x, minsize=64)
+            cell = Tk.Label(self.cellgrid, text=colnum2name(x), relief='raised')
+            cell.grid_configure(column=x, row=0, sticky='WE')
+            self.gridcells[x, 0] = cell
+            cell.__x = x
+            cell.__y = 0
+            cell.bind("<ButtonPress-1>", self.selectcolumn)
+            cell.bind("<B1-Motion>", self.extendcolumn)
+            cell.bind("<ButtonRelease-1>", self.extendcolumn)
+            cell.bind("<Shift-Button-1>", self.extendcolumn)
+        # Create the leftmost column of labels
+        for y in range(1, rows+1):
+            cell = Tk.Label(self.cellgrid, text=str(y), relief='raised')
+            cell.grid_configure(column=0, row=y, sticky='WE')
+            self.gridcells[0, y] = cell
+            cell.__x = 0
+            cell.__y = y
+            cell.bind("<ButtonPress-1>", self.selectrow)
+            cell.bind("<B1-Motion>", self.extendrow)
+            cell.bind("<ButtonRelease-1>", self.extendrow)
+            cell.bind("<Shift-Button-1>", self.extendrow)
+        # Create the real cells
+        for x in range(1, columns+1):
+            for y in range(1, rows+1):
+                cell = Tk.Label(self.cellgrid, relief='sunken',
+                                bg='white', fg='black')
+                cell.grid_configure(column=x, row=y, sticky='NSWE')
+                self.gridcells[x, y] = cell
+                cell.__x = x
+                cell.__y = y
+                # Bind mouse events
+                cell.bind("<ButtonPress-1>", self.press)
+                cell.bind("<B1-Motion>", self.motion)
+                cell.bind("<ButtonRelease-1>", self.release)
+                cell.bind("<Shift-Button-1>", self.release)
+
+    def selectall(self, event):
+        self.setcurrent(1, 1)
+        self.setcorner(sys.maxint, sys.maxint)
+
+    def selectcolumn(self, event):
+        x, y = self.whichxy(event)
+        self.setcurrent(x, 1)
+        self.setcorner(x, sys.maxint)
+
+    def extendcolumn(self, event):
+        x, y = self.whichxy(event)
+        if x > 0:
+            self.setcurrent(self.currentxy[0], 1)
+            self.setcorner(x, sys.maxint)
+
+    def selectrow(self, event):
+        x, y = self.whichxy(event)
+        self.setcurrent(1, y)
+        self.setcorner(sys.maxint, y)
+
+    def extendrow(self, event):
+        x, y = self.whichxy(event)
+        if y > 0:
+            self.setcurrent(1, self.currentxy[1])
+            self.setcorner(sys.maxint, y)
+
+    def press(self, event):
+        x, y = self.whichxy(event)
+        if x > 0 and y > 0:
+            self.setcurrent(x, y)
+
+    def motion(self, event):
+        x, y = self.whichxy(event)
+        if x > 0 and y > 0:
+            self.setcorner(x, y)
+
+    release = motion
+
+    def whichxy(self, event):
+        w = self.cellgrid.winfo_containing(event.x_root, event.y_root)
+        if w is not None and isinstance(w, Tk.Label):
+            try:
+                return w.__x, w.__y
+            except AttributeError:
+                pass
+        return 0, 0
+
+    def save(self):
+        self.sheet.save(self.filename)
+
+    def setcurrent(self, x, y):
+        "Make (x, y) the current cell."
+        if self.currentxy is not None:
+            self.change_cell()
+        self.clearfocus()
+        self.beacon['text'] = cellname(x, y)
+        self.load_entry(x, y)
+        self.entry.focus_set()
+        self.currentxy = x, y
+        self.cornerxy = None
+        gridcell = self.gridcells.get(self.currentxy)
+        if gridcell is not None:
+            gridcell['bg'] = 'yellow'
+
+    def setcorner(self, x, y):
+        if self.currentxy is None or self.currentxy == (x, y):
+            self.setcurrent(x, y)
+            return
+        self.clearfocus()
+        self.cornerxy = x, y
+        x1, y1 = self.currentxy
+        x2, y2 = self.cornerxy or self.currentxy
+        if x1 > x2:
+            x1, x2 = x2, x1
+        if y1 > y2:
+            y1, y2 = y2, y1
+        for (x, y), cell in self.gridcells.iteritems():
+            if x1 <= x <= x2 and y1 <= y <= y2:
+                cell['bg'] = 'lightBlue'
+        gridcell = self.gridcells.get(self.currentxy)
+        if gridcell is not None:
+            gridcell['bg'] = 'yellow'
+        self.setbeacon(x1, y1, x2, y2)
+
+    def setbeacon(self, x1, y1, x2, y2):
+        if x1 == y1 == 1 and x2 == y2 == sys.maxint:
+            name = ":"
+        elif (x1, x2) == (1, sys.maxint):
+            if y1 == y2:
+                name = "%d" % y1
+            else:
+                name = "%d:%d" % (y1, y2)
+        elif (y1, y2) == (1, sys.maxint):
+            if x1 == x2:
+                name = "%s" % colnum2name(x1)
+            else:
+                name = "%s:%s" % (colnum2name(x1), colnum2name(x2))
+        else:
+            name1 = cellname(*self.currentxy)
+            name2 = cellname(*self.cornerxy)
+            name = "%s:%s" % (name1, name2)
+        self.beacon['text'] = name
+
+
+    def clearfocus(self):
+        if self.currentxy is not None:
+            x1, y1 = self.currentxy
+            x2, y2 = self.cornerxy or self.currentxy
+            if x1 > x2:
+                x1, x2 = x2, x1
+            if y1 > y2:
+                y1, y2 = y2, y1
+            for (x, y), cell in self.gridcells.iteritems():
+                if x1 <= x <= x2 and y1 <= y <= y2:
+                    cell['bg'] = 'white'
+
+    def return_event(self, event):
+        "Callback for the Return key."
+        self.change_cell()
+        x, y = self.currentxy
+        self.setcurrent(x, y+1)
+        return "break"
+
+    def shift_return_event(self, event):
+        "Callback for the Return key with Shift modifier."
+        self.change_cell()
+        x, y = self.currentxy
+        self.setcurrent(x, max(1, y-1))
+        return "break"
+
+    def tab_event(self, event):
+        "Callback for the Tab key."
+        self.change_cell()
+        x, y = self.currentxy
+        self.setcurrent(x+1, y)
+        return "break"
+
+    def shift_tab_event(self, event):
+        "Callback for the Tab key with Shift modifier."
+        self.change_cell()
+        x, y = self.currentxy
+        self.setcurrent(max(1, x-1), y)
+        return "break"
+
+    def change_cell(self):
+        "Set the current cell from the entry widget."
+        x, y = self.currentxy
+        text = self.entry.get()
+        cell = None
+        if text.startswith('='):
+            cell = FormulaCell(text[1:])
+        else:
+            for cls in int, long, float, complex:
+                try:
+                    value = cls(text)
+                except:
+                    continue
+                else:
+                    cell = NumericCell(value)
+                    break
+        if cell is None and text:
+            cell = StringCell(text)
+        if cell is None:
+            self.sheet.clearcell(x, y)
+        else:
+            self.sheet.setcell(x, y, cell)
+        self.sync()
+
+    def sync(self):
+        "Fill the GUI cells from the sheet cells."
+        self.sheet.recalc()
+        for (x, y), gridcell in self.gridcells.iteritems():
+            if x == 0 or y == 0:
+                continue
+            cell = self.sheet.getcell(x, y)
+            if cell is None:
+                gridcell['text'] = ""
+            else:
+                if hasattr(cell, 'format'):
+                    text, alignment = cell.format()
+                else:
+                    text, alignment = str(cell), LEFT
+                gridcell['text'] = text
+                gridcell['anchor'] = align2anchor[alignment]
+
+
+def test_basic():
+    "Basic non-gui self-test."
+    import os
+    a = Sheet()
+    for x in range(1, 11):
+        for y in range(1, 11):
+            if x == 1:
+                cell = NumericCell(y)
+            elif y == 1:
+                cell = NumericCell(x)
+            else:
+                c1 = cellname(x, 1)
+                c2 = cellname(1, y)
+                formula = "%s*%s" % (c1, c2)
+                cell = FormulaCell(formula)
+            a.setcell(x, y, cell)
+##    if os.path.isfile("sheet1.xml"):
+##        print "Loading from sheet1.xml"
+##        a.load("sheet1.xml")
+    a.display()
+    a.save("sheet1.xml")
+
+def test_gui():
+    "GUI test."
+    if sys.argv[1:]:
+        filename = sys.argv[1]
+    else:
+        filename = "sheet1.xml"
+    g = SheetGUI(filename)
+    g.root.mainloop()
+
+if __name__ == '__main__':
+    #test_basic()
+    test_gui()

Added: vendor/Python/current/Demo/tkinter/guido/svkill.py
===================================================================
--- vendor/Python/current/Demo/tkinter/guido/svkill.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/guido/svkill.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,128 @@
+#! /usr/bin/env python
+
+# Tkinter interface to SYSV `ps' and `kill' commands.
+
+from Tkinter import *
+
+if TkVersion < 4.0:
+    raise ImportError, "This version of svkill requires Tk 4.0 or later"
+
+from string import splitfields
+from string import split
+import commands
+import os
+
+user = os.environ['LOGNAME']
+
+class BarButton(Menubutton):
+    def __init__(self, master=None, **cnf):
+        apply(Menubutton.__init__, (self, master), cnf)
+        self.pack(side=LEFT)
+        self.menu = Menu(self, name='menu')
+        self['menu'] = self.menu
+
+class Kill(Frame):
+    # List of (name, option, pid_column)
+    view_list = [
+            ('Default', ''),
+            ('Every (-e)', '-e'),
+            ('Non process group leaders (-d)', '-d'),
+            ('Non leaders with tty (-a)', '-a'),
+            ('For this user (-u %s)' % user, '-u %s' % user),
+            ]
+    format_list = [
+            ('Default', '', 0),
+            ('Long (-l)', '-l', 3),
+            ('Full (-f)', '-f', 1),
+            ('Full Long (-f -l)', '-l -f', 3),
+            ('Session and group ID (-j)', '-j', 0),
+            ('Scheduler properties (-c)', '-c', 0),
+            ]
+    def kill(self, selected):
+        c = self.format_list[self.format.get()][2]
+        pid = split(selected)[c]
+        os.system('kill -9 ' + pid)
+        self.do_update()
+    def do_update(self):
+        format = self.format_list[self.format.get()][1]
+        view = self.view_list[self.view.get()][1]
+        s = commands.getoutput('ps %s %s' % (view, format))
+        list = splitfields(s, '\n')
+        self.header.set(list[0] + '          ')
+        del list[0]
+        self.frame.list.delete(0, AtEnd())
+        for line in list:
+            self.frame.list.insert(0, line)
+    def do_motion(self, e):
+        e.widget.select_clear('0', 'end')
+        e.widget.select_set(e.widget.nearest(e.y))
+    def do_leave(self, e):
+        e.widget.select_clear('0', 'end')
+    def do_1(self, e):
+        self.kill(e.widget.get(e.widget.nearest(e.y)))
+    def __init__(self, master=None, **cnf):
+        apply(Frame.__init__, (self, master), cnf)
+        self.pack(expand=1, fill=BOTH)
+        self.bar = Frame(self, name='bar', relief=RAISED,
+                         borderwidth=2)
+        self.bar.pack(fill=X)
+        self.bar.file = BarButton(self.bar, text='File')
+        self.bar.file.menu.add_command(
+                label='Quit', command=self.quit)
+        self.bar.view = BarButton(self.bar, text='View')
+        self.bar.format = BarButton(self.bar, text='Format')
+        self.view = IntVar(self)
+        self.view.set(0)
+        self.format = IntVar(self)
+        self.format.set(0)
+        for num in range(len(self.view_list)):
+            label, option = self.view_list[num]
+            self.bar.view.menu.add_radiobutton(
+                    label=label,
+                    command=self.do_update,
+                    variable=self.view,
+                    value=num)
+        for num in range(len(self.format_list)):
+            label, option, col = self.format_list[num]
+            self.bar.format.menu.add_radiobutton(
+                    label=label,
+                    command=self.do_update,
+                    variable=self.format,
+                    value=num)
+        self.bar.tk_menuBar(self.bar.file,
+                            self.bar.view,
+                            self.bar.format)
+        self.frame = Frame(self, relief=RAISED, borderwidth=2)
+        self.frame.pack(expand=1, fill=BOTH)
+        self.header = StringVar(self)
+        self.frame.label = Label(
+                self.frame, relief=FLAT, anchor=NW, borderwidth=0,
+                font='*-Courier-Bold-R-Normal-*-120-*',
+                textvariable=self.header)
+        self.frame.label.pack(fill=Y, anchor=W)
+        self.frame.vscroll = Scrollbar(self.frame, orient=VERTICAL)
+        self.frame.list = Listbox(
+                self.frame,
+                relief=SUNKEN,
+                font='*-Courier-Medium-R-Normal-*-120-*',
+                width=40, height=10,
+                selectbackground='#eed5b7',
+                selectborderwidth=0,
+                selectmode=BROWSE,
+                yscroll=self.frame.vscroll.set)
+        self.frame.vscroll['command'] = self.frame.list.yview
+        self.frame.vscroll.pack(side=RIGHT, fill=Y)
+        self.frame.list.pack(expand=1, fill=BOTH)
+        self.update = Button(self, text='Update',
+                             command=self.do_update)
+        self.update.pack(fill=X)
+        self.frame.list.bind('<Motion>', self.do_motion)
+        self.frame.list.bind('<Leave>', self.do_leave)
+        self.frame.list.bind('<1>', self.do_1)
+        self.do_update()
+
+if __name__ == '__main__':
+    kill = Kill(None, borderwidth=5)
+    kill.winfo_toplevel().title('Tkinter Process Killer (SYSV)')
+    kill.winfo_toplevel().minsize(1, 1)
+    kill.mainloop()


Property changes on: vendor/Python/current/Demo/tkinter/guido/svkill.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tkinter/guido/switch.py
===================================================================
--- vendor/Python/current/Demo/tkinter/guido/switch.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/guido/switch.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,55 @@
+# Show how to do switchable panels.
+
+from Tkinter import *
+
+class App:
+
+    def __init__(self, top=None, master=None):
+        if top is None:
+            if master is None:
+                top = Tk()
+            else:
+                top = Toplevel(master)
+        self.top = top
+        self.buttonframe = Frame(top)
+        self.buttonframe.pack()
+        self.panelframe = Frame(top,  borderwidth=2, relief=GROOVE)
+        self.panelframe.pack(expand=1, fill=BOTH)
+        self.panels = {}
+        self.curpanel = None
+
+    def addpanel(self, name, klass):
+        button = Button(self.buttonframe, text=name,
+                        command=lambda self=self, name=name: self.show(name))
+        button.pack(side=LEFT)
+        frame = Frame(self.panelframe)
+        instance = klass(frame)
+        self.panels[name] = (button, frame, instance)
+        if self.curpanel is None:
+            self.show(name)
+
+    def show(self, name):
+        (button, frame, instance) = self.panels[name]
+        if self.curpanel:
+            self.curpanel.pack_forget()
+        self.curpanel = frame
+        frame.pack(expand=1, fill="both")
+
+class LabelPanel:
+    def __init__(self, frame):
+        self.label = Label(frame, text="Hello world")
+        self.label.pack()
+
+class ButtonPanel:
+    def __init__(self, frame):
+        self.button = Button(frame, text="Press me")
+        self.button.pack()
+
+def main():
+    app = App()
+    app.addpanel("label", LabelPanel)
+    app.addpanel("button", ButtonPanel)
+    app.top.mainloop()
+
+if __name__ == '__main__':
+    main()

Added: vendor/Python/current/Demo/tkinter/guido/tkman.py
===================================================================
--- vendor/Python/current/Demo/tkinter/guido/tkman.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/guido/tkman.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,267 @@
+#! /usr/bin/env python
+
+# Tk man page browser -- currently only shows the Tcl/Tk man pages
+
+import sys
+import os
+import string
+import re
+from Tkinter import *
+from ManPage import ManPage
+
+MANNDIRLIST = ['/depot/sundry/man/mann','/usr/local/man/mann']
+MAN3DIRLIST = ['/depot/sundry/man/man3','/usr/local/man/man3']
+
+foundmanndir = 0
+for dir in MANNDIRLIST:
+    if os.path.exists(dir):
+        MANNDIR = dir
+        foundmanndir = 1
+
+foundman3dir = 0
+for dir in MAN3DIRLIST:
+    if os.path.exists(dir):
+        MAN3DIR = dir
+        foundman3dir =  1
+
+if not foundmanndir or not foundman3dir:
+    sys.stderr.write('\n')
+    if not foundmanndir:
+        msg = """\
+Failed to find mann directory.
+Please add the correct entry to the MANNDIRLIST
+at the top of %s script.""" % \
+sys.argv[0]
+        sys.stderr.write("%s\n\n" % msg)
+    if not foundman3dir:
+        msg = """\
+Failed to find man3 directory.
+Please add the correct entry to the MAN3DIRLIST
+at the top of %s script.""" % \
+sys.argv[0]
+        sys.stderr.write("%s\n\n" % msg)
+    sys.exit(1)
+
+del foundmanndir
+del foundman3dir
+
+def listmanpages(mandir):
+    files = os.listdir(mandir)
+    names = []
+    for file in files:
+        if file[-2:-1] == '.' and  (file[-1] in 'ln123456789'):
+            names.append(file[:-2])
+    names.sort()
+    return names
+
+class SelectionBox:
+
+    def __init__(self, master=None):
+        self.choices = []
+
+        self.frame = Frame(master, name="frame")
+        self.frame.pack(expand=1, fill=BOTH)
+        self.master = self.frame.master
+        self.subframe = Frame(self.frame, name="subframe")
+        self.subframe.pack(expand=0, fill=BOTH)
+        self.leftsubframe = Frame(self.subframe, name='leftsubframe')
+        self.leftsubframe.pack(side=LEFT, expand=1, fill=BOTH)
+        self.rightsubframe = Frame(self.subframe, name='rightsubframe')
+        self.rightsubframe.pack(side=RIGHT, expand=1, fill=BOTH)
+        self.chaptervar = StringVar(master)
+        self.chapter = Menubutton(self.rightsubframe, name='chapter',
+                                  text='Directory', relief=RAISED,
+                                  borderwidth=2)
+        self.chapter.pack(side=TOP)
+        self.chaptermenu = Menu(self.chapter, name='chaptermenu')
+        self.chaptermenu.add_radiobutton(label='C functions',
+                                         value=MAN3DIR,
+                                         variable=self.chaptervar,
+                                         command=self.newchapter)
+        self.chaptermenu.add_radiobutton(label='Tcl/Tk functions',
+                                         value=MANNDIR,
+                                         variable=self.chaptervar,
+                                         command=self.newchapter)
+        self.chapter['menu'] = self.chaptermenu
+        self.listbox = Listbox(self.rightsubframe, name='listbox',
+                               relief=SUNKEN, borderwidth=2,
+                               width=20, height=5)
+        self.listbox.pack(expand=1, fill=BOTH)
+        self.l1 = Button(self.leftsubframe, name='l1',
+                         text='Display manual page named:',
+                         command=self.entry_cb)
+        self.l1.pack(side=TOP)
+        self.entry = Entry(self.leftsubframe, name='entry',
+                            relief=SUNKEN, borderwidth=2,
+                            width=20)
+        self.entry.pack(expand=0, fill=X)
+        self.l2frame = Frame(self.leftsubframe, name='l2frame')
+        self.l2frame.pack(expand=0, fill=NONE)
+        self.l2 = Button(self.l2frame, name='l2',
+                         text='Search regexp:',
+                         command=self.search_cb)
+        self.l2.pack(side=LEFT)
+        self.casevar = BooleanVar()
+        self.casesense = Checkbutton(self.l2frame, name='casesense',
+                                     text='Case sensitive',
+                                     variable=self.casevar,
+                                     relief=FLAT)
+        self.casesense.pack(side=LEFT)
+        self.search = Entry(self.leftsubframe, name='search',
+                            relief=SUNKEN, borderwidth=2,
+                            width=20)
+        self.search.pack(expand=0, fill=X)
+        self.title = Label(self.leftsubframe, name='title',
+                           text='(none)')
+        self.title.pack(side=BOTTOM)
+        self.text = ManPage(self.frame, name='text',
+                            relief=SUNKEN, borderwidth=2,
+                            wrap=NONE, width=72,
+                            selectbackground='pink')
+        self.text.pack(expand=1, fill=BOTH)
+
+        self.entry.bind('<Return>', self.entry_cb)
+        self.search.bind('<Return>', self.search_cb)
+        self.listbox.bind('<Double-1>', self.listbox_cb)
+
+        self.entry.bind('<Tab>', self.entry_tab)
+        self.search.bind('<Tab>', self.search_tab)
+        self.text.bind('<Tab>', self.text_tab)
+
+        self.entry.focus_set()
+
+        self.chaptervar.set(MANNDIR)
+        self.newchapter()
+
+    def newchapter(self):
+        mandir = self.chaptervar.get()
+        self.choices = []
+        self.addlist(listmanpages(mandir))
+
+    def addchoice(self, choice):
+        if choice not in self.choices:
+            self.choices.append(choice)
+            self.choices.sort()
+        self.update()
+
+    def addlist(self, list):
+        self.choices[len(self.choices):] = list
+        self.choices.sort()
+        self.update()
+
+    def entry_cb(self, *e):
+        self.update()
+
+    def listbox_cb(self, e):
+        selection = self.listbox.curselection()
+        if selection and len(selection) == 1:
+            name = self.listbox.get(selection[0])
+            self.show_page(name)
+
+    def search_cb(self, *e):
+        self.search_string(self.search.get())
+
+    def entry_tab(self, e):
+        self.search.focus_set()
+
+    def search_tab(self, e):
+        self.entry.focus_set()
+
+    def text_tab(self, e):
+        self.entry.focus_set()
+
+    def updatelist(self):
+        key = self.entry.get()
+        ok = filter(lambda name, key=key, n=len(key): name[:n]==key,
+                 self.choices)
+        if not ok:
+            self.frame.bell()
+        self.listbox.delete(0, AtEnd())
+        exactmatch = 0
+        for item in ok:
+            if item == key: exactmatch = 1
+            self.listbox.insert(AtEnd(), item)
+        if exactmatch:
+            return key
+        n = self.listbox.size()
+        if n == 1:
+            return self.listbox.get(0)
+        # Else return None, meaning not a unique selection
+
+    def update(self):
+        name = self.updatelist()
+        if name:
+            self.show_page(name)
+            self.entry.delete(0, AtEnd())
+            self.updatelist()
+
+    def show_page(self, name):
+        file = '%s/%s.?' % (self.chaptervar.get(), name)
+        fp = os.popen('nroff -man %s | ul -i' % file, 'r')
+        self.text.kill()
+        self.title['text'] = name
+        self.text.parsefile(fp)
+
+    def search_string(self, search):
+        if not search:
+            self.frame.bell()
+            print 'Empty search string'
+            return
+        if not self.casevar.get():
+            map = re.IGNORECASE
+        else:
+            map = None
+        try:
+            if map:
+                prog = re.compile(search, map)
+            else:
+                prog = re.compile(search)
+        except re.error, msg:
+            self.frame.bell()
+            print 'Regex error:', msg
+            return
+        here = self.text.index(AtInsert())
+        lineno = string.atoi(here[:string.find(here, '.')])
+        end = self.text.index(AtEnd())
+        endlineno = string.atoi(end[:string.find(end, '.')])
+        wraplineno = lineno
+        found = 0
+        while 1:
+            lineno = lineno + 1
+            if lineno > endlineno:
+                if wraplineno <= 0:
+                    break
+                endlineno = wraplineno
+                lineno = 0
+                wraplineno = 0
+            line = self.text.get('%d.0 linestart' % lineno,
+                                 '%d.0 lineend' % lineno)
+            i = prog.search(line)
+            if i >= 0:
+                found = 1
+                n = max(1, len(prog.group(0)))
+                try:
+                    self.text.tag_remove('sel',
+                                         AtSelFirst(),
+                                         AtSelLast())
+                except TclError:
+                    pass
+                self.text.tag_add('sel',
+                                  '%d.%d' % (lineno, i),
+                                  '%d.%d' % (lineno, i+n))
+                self.text.mark_set(AtInsert(),
+                                   '%d.%d' % (lineno, i))
+                self.text.yview_pickplace(AtInsert())
+                break
+        if not found:
+            self.frame.bell()
+
+def main():
+    root = Tk()
+    sb = SelectionBox(root)
+    if sys.argv[1:]:
+        sb.show_page(sys.argv[1])
+    root.minsize(1, 1)
+    root.mainloop()
+
+main()


Property changes on: vendor/Python/current/Demo/tkinter/guido/tkman.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tkinter/guido/wish.py
===================================================================
--- vendor/Python/current/Demo/tkinter/guido/wish.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/guido/wish.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,27 @@
+# This is about all it requires to write a wish shell in Python!
+
+import _tkinter
+import os
+
+tk = _tkinter.create(os.environ['DISPLAY'], 'wish', 'Tk', 1)
+tk.call('update')
+
+cmd = ''
+
+while 1:
+    if cmd: prompt = ''
+    else: prompt = '% '
+    try:
+        line = raw_input(prompt)
+    except EOFError:
+        break
+    cmd = cmd + (line + '\n')
+    if tk.getboolean(tk.call('info', 'complete', cmd)):
+        tk.record(line)
+        try:
+            result = tk.call('eval', cmd)
+        except _tkinter.TclError, msg:
+            print 'TclError:', msg
+        else:
+            if result: print result
+        cmd = ''


Property changes on: vendor/Python/current/Demo/tkinter/guido/wish.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/tkinter/matt/00-HELLO-WORLD.py
===================================================================
--- vendor/Python/current/Demo/tkinter/matt/00-HELLO-WORLD.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/matt/00-HELLO-WORLD.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,27 @@
+from Tkinter import *
+
+# note that there is no explicit call to start Tk.
+# Tkinter is smart enough to start the system if it's not already going.
+
+class Test(Frame):
+    def printit(self):
+        print "hi"
+
+    def createWidgets(self):
+        self.QUIT = Button(self, text='QUIT', foreground='red',
+                           command=self.quit)
+
+        self.QUIT.pack(side=LEFT, fill=BOTH)
+
+        # a hello button
+        self.hi_there = Button(self, text='Hello',
+                               command=self.printit)
+        self.hi_there.pack(side=LEFT)
+
+    def __init__(self, master=None):
+        Frame.__init__(self, master)
+        Pack.config(self)
+        self.createWidgets()
+
+test = Test()
+test.mainloop()

Added: vendor/Python/current/Demo/tkinter/matt/README
===================================================================
--- vendor/Python/current/Demo/tkinter/matt/README	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/matt/README	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,30 @@
+This directory contains some ad-hoc examples of Tkinter widget
+creation. The files named 
+
+		*-simple.py
+
+are the ones to start with if you're looking for a bare-bones usage of
+a widget. The other files are meant to show common usage patters that
+are a tad more involved. 
+
+If you have a suggestion for an example program, please send mail to 
+	
+	conway at virginia.edu
+
+and I'll include it.
+
+
+matt
+
+TODO
+-------
+The X selection
+Dialog Boxes
+More canvas examples
+Message widgets
+Text Editors
+Scrollbars
+Listboxes
+
+
+

Added: vendor/Python/current/Demo/tkinter/matt/animation-simple.py
===================================================================
--- vendor/Python/current/Demo/tkinter/matt/animation-simple.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/matt/animation-simple.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,35 @@
+from Tkinter import *
+
+# This program shows how to use the "after" function to make animation.
+
+class Test(Frame):
+    def printit(self):
+        print "hi"
+
+    def createWidgets(self):
+        self.QUIT = Button(self, text='QUIT', foreground='red',
+                           command=self.quit)
+        self.QUIT.pack(side=LEFT, fill=BOTH)
+
+        self.draw = Canvas(self, width="5i", height="5i")
+
+        # all of these work..
+        self.draw.create_rectangle(0, 0, 10, 10, tags="thing", fill="blue")
+        self.draw.pack(side=LEFT)
+
+    def moveThing(self, *args):
+        # move 1/10 of an inch every 1/10 sec (1" per second, smoothly)
+        self.draw.move("thing", "0.01i", "0.01i")
+        self.after(10, self.moveThing)
+
+
+    def __init__(self, master=None):
+        Frame.__init__(self, master)
+        Pack.config(self)
+        self.createWidgets()
+        self.after(10, self.moveThing)
+
+
+test = Test()
+
+test.mainloop()

Added: vendor/Python/current/Demo/tkinter/matt/animation-w-velocity-ctrl.py
===================================================================
--- vendor/Python/current/Demo/tkinter/matt/animation-w-velocity-ctrl.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/matt/animation-w-velocity-ctrl.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,44 @@
+from Tkinter import *
+
+# this is the same as simple-demo-1.py, but uses
+# subclassing.
+# note that there is no explicit call to start Tk.
+# Tkinter is smart enough to start the system if it's not already going.
+
+
+class Test(Frame):
+    def printit(self):
+        print "hi"
+
+    def createWidgets(self):
+        self.QUIT = Button(self, text='QUIT', foreground='red',
+                           command=self.quit)
+        self.QUIT.pack(side=BOTTOM, fill=BOTH)
+
+        self.draw = Canvas(self, width="5i", height="5i")
+
+        self.speed = Scale(self, orient=HORIZONTAL, from_=-100, to=100)
+
+        self.speed.pack(side=BOTTOM, fill=X)
+
+        # all of these work..
+        self.draw.create_rectangle(0, 0, 10, 10, tags="thing", fill="blue")
+        self.draw.pack(side=LEFT)
+
+    def moveThing(self, *args):
+        velocity = self.speed.get()
+        str = float(velocity) / 1000.0
+        str = "%ri" % (str,)
+        self.draw.move("thing",  str, str)
+        self.after(10, self.moveThing)
+
+    def __init__(self, master=None):
+        Frame.__init__(self, master)
+        Pack.config(self)
+        self.createWidgets()
+        self.after(10, self.moveThing)
+
+
+test = Test()
+
+test.mainloop()

Added: vendor/Python/current/Demo/tkinter/matt/bind-w-mult-calls-p-type.py
===================================================================
--- vendor/Python/current/Demo/tkinter/matt/bind-w-mult-calls-p-type.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/matt/bind-w-mult-calls-p-type.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,44 @@
+from Tkinter import *
+import string
+
+# This program  shows how to use a simple type-in box
+
+class App(Frame):
+    def __init__(self, master=None):
+        Frame.__init__(self, master)
+        self.pack()
+
+        self.entrythingy = Entry()
+        self.entrythingy.pack()
+
+        # and here we get a callback when the user hits return. we could
+        # make the key that triggers the callback anything we wanted to.
+        # other typical options might be <Key-Tab> or <Key> (for anything)
+        self.entrythingy.bind('<Key-Return>', self.print_contents)
+
+        # Note that here is where we bind a completely different callback to
+        # the same event. We pass "+" here to indicate that we wish to ADD
+        # this callback to the list associated with this event type.
+        # Not specifying "+" would simply override whatever callback was
+        # defined on this event.
+        self.entrythingy.bind('<Key-Return>', self.print_something_else, "+")
+
+    def print_contents(self, event):
+        print "hi. contents of entry is now ---->", self.entrythingy.get()
+
+
+    def print_something_else(self, event):
+        print "hi. Now doing something completely different"
+
+
+root = App()
+root.master.title("Foo")
+root.mainloop()
+
+
+
+# secret tip for experts: if you pass *any* non-false value as
+# the third parameter to bind(), Tkinter.py will accumulate
+# callbacks instead of overwriting. I use "+" here because that's
+# the Tk notation for getting this sort of behavior. The perfect GUI
+# interface would use a less obscure notation.

Added: vendor/Python/current/Demo/tkinter/matt/canvas-demo-simple.py
===================================================================
--- vendor/Python/current/Demo/tkinter/matt/canvas-demo-simple.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/matt/canvas-demo-simple.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,28 @@
+from Tkinter import *
+
+# this program creates a canvas and puts a single polygon on the canvas
+
+class Test(Frame):
+    def printit(self):
+        print "hi"
+
+    def createWidgets(self):
+        self.QUIT = Button(self, text='QUIT', foreground='red',
+                           command=self.quit)
+        self.QUIT.pack(side=BOTTOM, fill=BOTH)
+
+        self.draw = Canvas(self, width="5i", height="5i")
+
+        # see the other demos for other ways of specifying coords for a polygon
+        self.draw.create_rectangle(0, 0, "3i", "3i", fill="black")
+
+        self.draw.pack(side=LEFT)
+
+    def __init__(self, master=None):
+        Frame.__init__(self, master)
+        Pack.config(self)
+        self.createWidgets()
+
+test = Test()
+
+test.mainloop()

Added: vendor/Python/current/Demo/tkinter/matt/canvas-gridding.py
===================================================================
--- vendor/Python/current/Demo/tkinter/matt/canvas-gridding.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/matt/canvas-gridding.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,61 @@
+from Tkinter import *
+
+# this is the same as simple-demo-1.py, but uses
+# subclassing.
+# note that there is no explicit call to start Tk.
+# Tkinter is smart enough to start the system if it's not already going.
+
+class Test(Frame):
+    def printit(self):
+        print "hi"
+
+    def createWidgets(self):
+        self.QUIT = Button(self, text='QUIT',
+                                  background='red',
+                                  foreground='white',
+                                  height=3,
+                                  command=self.quit)
+        self.QUIT.pack(side=BOTTOM, fill=BOTH)
+
+        self.canvasObject = Canvas(self, width="5i", height="5i")
+        self.canvasObject.pack(side=LEFT)
+
+    def mouseDown(self, event):
+        # canvas x and y take the screen coords from the event and translate
+        # them into the coordinate system of the canvas object
+        self.startx = self.canvasObject.canvasx(event.x, self.griddingSize)
+        self.starty = self.canvasObject.canvasy(event.y, self.griddingSize)
+
+    def mouseMotion(self, event):
+        # canvas x and y take the screen coords from the event and translate
+        # them into the coordinate system of the canvas object
+        x = self.canvasObject.canvasx(event.x, self.griddingSize)
+        y = self.canvasObject.canvasy(event.y, self.griddingSize)
+
+        if (self.startx != event.x)  and (self.starty != event.y) :
+            self.canvasObject.delete(self.rubberbandBox)
+            self.rubberbandBox = self.canvasObject.create_rectangle(
+                self.startx, self.starty, x, y)
+            # this flushes the output, making sure that
+            # the rectangle makes it to the screen
+            # before the next event is handled
+            self.update_idletasks()
+
+    def __init__(self, master=None):
+        Frame.__init__(self, master)
+        Pack.config(self)
+        self.createWidgets()
+
+        # this is a "tagOrId" for the rectangle we draw on the canvas
+        self.rubberbandBox = None
+
+        # this is the size of the gridding squares
+        self.griddingSize = 50
+
+        Widget.bind(self.canvasObject, "<Button-1>", self.mouseDown)
+        Widget.bind(self.canvasObject, "<Button1-Motion>", self.mouseMotion)
+
+
+test = Test()
+
+test.mainloop()

Added: vendor/Python/current/Demo/tkinter/matt/canvas-moving-or-creating.py
===================================================================
--- vendor/Python/current/Demo/tkinter/matt/canvas-moving-or-creating.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/matt/canvas-moving-or-creating.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,62 @@
+from Tkinter import *
+
+# this file demonstrates a more sophisticated movement --
+# move dots or create new ones if you click outside the dots
+
+class Test(Frame):
+    ###################################################################
+    ###### Event callbacks for THE CANVAS (not the stuff drawn on it)
+    ###################################################################
+    def mouseDown(self, event):
+        # see if we're inside a dot. If we are, it
+        # gets tagged as CURRENT for free by tk.
+        if not event.widget.find_withtag(CURRENT):
+            # there is no dot here, so we can make one,
+            # and bind some interesting behavior to it.
+            # ------
+            # create a dot, and mark it as CURRENT
+            fred = self.draw.create_oval(
+                event.x - 10, event.y -10, event.x +10, event.y + 10,
+                fill="green", tags=CURRENT)
+
+            self.draw.tag_bind(fred, "<Any-Enter>", self.mouseEnter)
+            self.draw.tag_bind(fred, "<Any-Leave>", self.mouseLeave)
+
+        self.lastx = event.x
+        self.lasty = event.y
+
+    def mouseMove(self, event):
+        self.draw.move(CURRENT, event.x - self.lastx, event.y - self.lasty)
+        self.lastx = event.x
+        self.lasty = event.y
+
+    ###################################################################
+    ###### Event callbacks for canvas ITEMS (stuff drawn on the canvas)
+    ###################################################################
+    def mouseEnter(self, event):
+        # the CURRENT tag is applied to the object the cursor is over.
+        # this happens automatically.
+        self.draw.itemconfig(CURRENT, fill="red")
+
+    def mouseLeave(self, event):
+        # the CURRENT tag is applied to the object the cursor is over.
+        # this happens automatically.
+        self.draw.itemconfig(CURRENT, fill="blue")
+
+    def createWidgets(self):
+        self.QUIT = Button(self, text='QUIT', foreground='red',
+                           command=self.quit)
+        self.QUIT.pack(side=LEFT, fill=BOTH)
+        self.draw = Canvas(self, width="5i", height="5i")
+        self.draw.pack(side=LEFT)
+
+        Widget.bind(self.draw, "<1>", self.mouseDown)
+        Widget.bind(self.draw, "<B1-Motion>", self.mouseMove)
+
+    def __init__(self, master=None):
+        Frame.__init__(self, master)
+        Pack.config(self)
+        self.createWidgets()
+
+test = Test()
+test.mainloop()

Added: vendor/Python/current/Demo/tkinter/matt/canvas-moving-w-mouse.py
===================================================================
--- vendor/Python/current/Demo/tkinter/matt/canvas-moving-w-mouse.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/matt/canvas-moving-w-mouse.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,55 @@
+from Tkinter import *
+
+# this file demonstrates the movement of a single canvas item under mouse control
+
+class Test(Frame):
+    ###################################################################
+    ###### Event callbacks for THE CANVAS (not the stuff drawn on it)
+    ###################################################################
+    def mouseDown(self, event):
+        # remember where the mouse went down
+        self.lastx = event.x
+        self.lasty = event.y
+
+    def mouseMove(self, event):
+        # whatever the mouse is over gets tagged as CURRENT for free by tk.
+        self.draw.move(CURRENT, event.x - self.lastx, event.y - self.lasty)
+        self.lastx = event.x
+        self.lasty = event.y
+
+    ###################################################################
+    ###### Event callbacks for canvas ITEMS (stuff drawn on the canvas)
+    ###################################################################
+    def mouseEnter(self, event):
+        # the CURRENT tag is applied to the object the cursor is over.
+        # this happens automatically.
+        self.draw.itemconfig(CURRENT, fill="red")
+
+    def mouseLeave(self, event):
+        # the CURRENT tag is applied to the object the cursor is over.
+        # this happens automatically.
+        self.draw.itemconfig(CURRENT, fill="blue")
+
+    def createWidgets(self):
+        self.QUIT = Button(self, text='QUIT', foreground='red',
+                           command=self.quit)
+        self.QUIT.pack(side=LEFT, fill=BOTH)
+        self.draw = Canvas(self, width="5i", height="5i")
+        self.draw.pack(side=LEFT)
+
+        fred = self.draw.create_oval(0, 0, 20, 20,
+                                     fill="green", tags="selected")
+
+        self.draw.tag_bind(fred, "<Any-Enter>", self.mouseEnter)
+        self.draw.tag_bind(fred, "<Any-Leave>", self.mouseLeave)
+
+        Widget.bind(self.draw, "<1>", self.mouseDown)
+        Widget.bind(self.draw, "<B1-Motion>", self.mouseMove)
+
+    def __init__(self, master=None):
+        Frame.__init__(self, master)
+        Pack.config(self)
+        self.createWidgets()
+
+test = Test()
+test.mainloop()

Added: vendor/Python/current/Demo/tkinter/matt/canvas-mult-item-sel.py
===================================================================
--- vendor/Python/current/Demo/tkinter/matt/canvas-mult-item-sel.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/matt/canvas-mult-item-sel.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,78 @@
+from Tkinter import *
+
+# allows moving dots with multiple selection.
+
+SELECTED_COLOR = "red"
+UNSELECTED_COLOR = "blue"
+
+class Test(Frame):
+    ###################################################################
+    ###### Event callbacks for THE CANVAS (not the stuff drawn on it)
+    ###################################################################
+    def mouseDown(self, event):
+        # see if we're inside a dot. If we are, it
+        # gets tagged as CURRENT for free by tk.
+
+        if not event.widget.find_withtag(CURRENT):
+            # we clicked outside of all dots on the canvas. unselect all.
+
+            # re-color everything back to an unselected color
+            self.draw.itemconfig("selected", fill=UNSELECTED_COLOR)
+            # unselect everything
+            self.draw.dtag("selected")
+        else:
+            # mark as "selected" the thing the cursor is under
+            self.draw.addtag("selected", "withtag", CURRENT)
+            # color it as selected
+            self.draw.itemconfig("selected", fill=SELECTED_COLOR)
+
+        self.lastx = event.x
+        self.lasty = event.y
+
+
+    def mouseMove(self, event):
+        self.draw.move("selected", event.x - self.lastx, event.y - self.lasty)
+        self.lastx = event.x
+        self.lasty = event.y
+
+    def makeNewDot(self):
+        # create a dot, and mark it as current
+        fred = self.draw.create_oval(0, 0, 20, 20,
+                                     fill=SELECTED_COLOR, tags=CURRENT)
+        # and make it selected
+        self.draw.addtag("selected", "withtag", CURRENT)
+
+    def createWidgets(self):
+        self.QUIT = Button(self, text='QUIT', foreground='red',
+                           command=self.quit)
+
+        ################
+        # make the canvas and bind some behavior to it
+        ################
+        self.draw = Canvas(self, width="5i", height="5i")
+        Widget.bind(self.draw, "<1>", self.mouseDown)
+        Widget.bind(self.draw, "<B1-Motion>", self.mouseMove)
+
+        # and other things.....
+        self.button = Button(self, text="make a new dot", foreground="blue",
+                             command=self.makeNewDot)
+
+        message = ("%s dots are selected and can be dragged.\n"
+                   "%s are not selected.\n"
+                   "Click in a dot to select it.\n"
+                   "Click on empty space to deselect all dots."
+                   ) % (SELECTED_COLOR, UNSELECTED_COLOR)
+        self.label = Message(self, width="5i", text=message)
+
+        self.QUIT.pack(side=BOTTOM, fill=BOTH)
+        self.label.pack(side=BOTTOM, fill=X, expand=1)
+        self.button.pack(side=BOTTOM, fill=X)
+        self.draw.pack(side=LEFT)
+
+    def __init__(self, master=None):
+        Frame.__init__(self, master)
+        Pack.config(self)
+        self.createWidgets()
+
+test = Test()
+test.mainloop()

Added: vendor/Python/current/Demo/tkinter/matt/canvas-reading-tag-info.py
===================================================================
--- vendor/Python/current/Demo/tkinter/matt/canvas-reading-tag-info.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/matt/canvas-reading-tag-info.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,49 @@
+from Tkinter import *
+
+
+class Test(Frame):
+    def printit(self):
+        print "hi"
+
+    def createWidgets(self):
+        self.QUIT = Button(self, text='QUIT', foreground='red',
+                           command=self.quit)
+        self.QUIT.pack(side=BOTTOM, fill=BOTH)
+
+        self.drawing = Canvas(self, width="5i", height="5i")
+
+        # make a shape
+        pgon = self.drawing.create_polygon(
+            10, 10, 110, 10, 110, 110, 10 , 110,
+            fill="red", tags=("weee", "foo", "groo"))
+
+        # this is how you query an object for its attributes
+        # config options FOR CANVAS ITEMS always come back in tuples of length 5.
+        # 0 attribute name
+        # 1 BLANK
+        # 2 BLANK
+        # 3 default value
+        # 4 current value
+        # the blank spots are for consistency with the config command that
+        # is used for widgets. (remember, this is for ITEMS drawn
+        # on a canvas widget, not widgets)
+        option_value = self.drawing.itemconfig(pgon, "stipple")
+        print "pgon's current stipple value is -->", option_value[4], "<--"
+        option_value = self.drawing.itemconfig(pgon,  "fill")
+        print "pgon's current fill value is -->", option_value[4], "<--"
+        print "  when he is usually colored -->", option_value[3], "<--"
+
+        ## here we print out all the tags associated with this object
+        option_value = self.drawing.itemconfig(pgon,  "tags")
+        print "pgon's tags are", option_value[4]
+
+        self.drawing.pack(side=LEFT)
+
+    def __init__(self, master=None):
+        Frame.__init__(self, master)
+        Pack.config(self)
+        self.createWidgets()
+
+test = Test()
+
+test.mainloop()

Added: vendor/Python/current/Demo/tkinter/matt/canvas-w-widget-draw-el.py
===================================================================
--- vendor/Python/current/Demo/tkinter/matt/canvas-w-widget-draw-el.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/matt/canvas-w-widget-draw-el.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,36 @@
+from Tkinter import *
+
+# this file demonstrates the creation of widgets as part of a canvas object
+
+class Test(Frame):
+    def printhi(self):
+        print "hi"
+
+    def createWidgets(self):
+        self.QUIT = Button(self, text='QUIT', foreground='red',
+                           command=self.quit)
+        self.QUIT.pack(side=BOTTOM, fill=BOTH)
+
+        self.draw = Canvas(self, width="5i", height="5i")
+
+        self.button = Button(self, text="this is a button",
+                             command=self.printhi)
+
+        # note here the coords are given in pixels (form the
+        # upper right and corner of the window, as usual for X)
+        # but might just have well been given in inches or points or
+        # whatever...use the "anchor" option to control what point of the
+        # widget (in this case the button) gets mapped to the given x, y.
+        # you can specify corners, edges, center, etc...
+        self.draw.create_window(300, 300, window=self.button)
+
+        self.draw.pack(side=LEFT)
+
+    def __init__(self, master=None):
+        Frame.__init__(self, master)
+        Pack.config(self)
+        self.createWidgets()
+
+test = Test()
+
+test.mainloop()

Added: vendor/Python/current/Demo/tkinter/matt/canvas-with-scrollbars.py
===================================================================
--- vendor/Python/current/Demo/tkinter/matt/canvas-with-scrollbars.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/matt/canvas-with-scrollbars.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,60 @@
+from Tkinter import *
+
+# This example program creates a scroling canvas, and demonstrates
+# how to tie scrollbars and canvses together. The mechanism
+# is analogus for listboxes and other widgets with
+# "xscroll" and "yscroll" configuration options.
+
+class Test(Frame):
+    def printit(self):
+        print "hi"
+
+    def createWidgets(self):
+        self.question = Label(self, text="Can Find The BLUE Square??????")
+        self.question.pack()
+
+        self.QUIT = Button(self, text='QUIT', background='red',
+                           height=3, command=self.quit)
+        self.QUIT.pack(side=BOTTOM, fill=BOTH)
+        spacer = Frame(self, height="0.25i")
+        spacer.pack(side=BOTTOM)
+
+        # notice that the scroll region (20" x 20") is larger than
+        # displayed size of the widget (5" x 5")
+        self.draw = Canvas(self, width="5i", height="5i",
+                           background="white",
+                           scrollregion=(0, 0, "20i", "20i"))
+
+        self.draw.scrollX = Scrollbar(self, orient=HORIZONTAL)
+        self.draw.scrollY = Scrollbar(self, orient=VERTICAL)
+
+        # now tie the three together. This is standard boilerplate text
+        self.draw['xscrollcommand'] = self.draw.scrollX.set
+        self.draw['yscrollcommand'] = self.draw.scrollY.set
+        self.draw.scrollX['command'] = self.draw.xview
+        self.draw.scrollY['command'] = self.draw.yview
+
+        # draw something. Note that the first square
+        # is visible, but you need to scroll to see the second one.
+        self.draw.create_rectangle(0, 0, "3.5i", "3.5i", fill="black")
+        self.draw.create_rectangle("10i", "10i", "13.5i", "13.5i", fill="blue")
+
+        # pack 'em up
+        self.draw.scrollX.pack(side=BOTTOM, fill=X)
+        self.draw.scrollY.pack(side=RIGHT, fill=Y)
+        self.draw.pack(side=LEFT)
+
+
+    def scrollCanvasX(self, *args):
+        print "scrolling", args
+        print self.draw.scrollX.get()
+
+
+    def __init__(self, master=None):
+        Frame.__init__(self, master)
+        Pack.config(self)
+        self.createWidgets()
+
+test = Test()
+
+test.mainloop()

Added: vendor/Python/current/Demo/tkinter/matt/dialog-box.py
===================================================================
--- vendor/Python/current/Demo/tkinter/matt/dialog-box.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/matt/dialog-box.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,64 @@
+from Tkinter import *
+from Dialog import Dialog
+
+# this shows how to create a new window with a button in it
+# that can create new windows
+
+class Test(Frame):
+    def printit(self):
+        print "hi"
+
+    def makeWindow(self):
+        """Create a top-level dialog with some buttons.
+
+        This uses the Dialog class, which is a wrapper around the Tcl/Tk
+        tk_dialog script.  The function returns 0 if the user clicks 'yes'
+        or 1 if the user clicks 'no'.
+        """
+        # the parameters to this call are as follows:
+        d = Dialog(
+            self,                       ## name of a toplevel window
+            title="fred the dialog box",## title on the window
+            text="click on a choice",   ## message to appear in window
+            bitmap="info",              ## bitmap (if any) to appear;
+                                        ## if none, use ""
+            #     legal values here are:
+            #      string      what it looks like
+            #      ----------------------------------------------
+            #      error       a circle with a slash through it
+            #      grey25      grey square
+            #      grey50      darker grey square
+            #      hourglass   use for "wait.."
+            #      info        a large, lower case "i"
+            #      questhead   a human head with a "?" in it
+            #      question    a large "?"
+            #      warning     a large "!"
+            #        @fname    X bitmap where fname is the path to the file
+            #
+            default=0,    # the index of the default button choice.
+                          # hitting return selects this
+            strings=("yes", "no"))
+                          # values of the 'strings' key are the labels for the
+                          # buttons that appear left to right in the dialog box
+        return d.num
+
+
+    def createWidgets(self):
+        self.QUIT = Button(self, text='QUIT', foreground='red',
+                           command=self.quit)
+        self.QUIT.pack(side=LEFT, fill=BOTH)
+
+        # a hello button
+        self.hi_there = Button(self, text='Make a New Window',
+                               command=self.makeWindow)
+        self.hi_there.pack(side=LEFT)
+
+
+    def __init__(self, master=None):
+        Frame.__init__(self, master)
+        Pack.config(self)
+        self.windownum = 0
+        self.createWidgets()
+
+test = Test()
+test.mainloop()

Added: vendor/Python/current/Demo/tkinter/matt/entry-simple.py
===================================================================
--- vendor/Python/current/Demo/tkinter/matt/entry-simple.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/matt/entry-simple.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,24 @@
+from Tkinter import *
+import string
+
+# This program  shows how to use a simple type-in box
+
+class App(Frame):
+    def __init__(self, master=None):
+        Frame.__init__(self, master)
+        self.pack()
+
+        self.entrythingy = Entry()
+        self.entrythingy.pack()
+
+        # and here we get a callback when the user hits return. we could
+        # make the key that triggers the callback anything we wanted to.
+        # other typical options might be <Key-Tab> or <Key> (for anything)
+        self.entrythingy.bind('<Key-Return>', self.print_contents)
+
+    def print_contents(self, event):
+        print "hi. contents of entry is now ---->", self.entrythingy.get()
+
+root = App()
+root.master.title("Foo")
+root.mainloop()

Added: vendor/Python/current/Demo/tkinter/matt/entry-with-shared-variable.py
===================================================================
--- vendor/Python/current/Demo/tkinter/matt/entry-with-shared-variable.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/matt/entry-with-shared-variable.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,46 @@
+from Tkinter import *
+import string
+
+# This program  shows how to make a typein box shadow a program variable.
+
+class App(Frame):
+    def __init__(self, master=None):
+        Frame.__init__(self, master)
+        self.pack()
+
+        self.entrythingy = Entry(self)
+        self.entrythingy.pack()
+
+        self.button = Button(self, text="Uppercase The Entry",
+                             command=self.upper)
+        self.button.pack()
+
+        # here we have the text in the entry widget tied to a variable.
+        # changes in the variable are echoed in the widget and vice versa.
+        # Very handy.
+        # there are other Variable types. See Tkinter.py for all
+        # the other variable types that can be shadowed
+        self.contents = StringVar()
+        self.contents.set("this is a variable")
+        self.entrythingy.config(textvariable=self.contents)
+
+        # and here we get a callback when the user hits return. we could
+        # make the key that triggers the callback anything we wanted to.
+        # other typical options might be <Key-Tab> or <Key> (for anything)
+        self.entrythingy.bind('<Key-Return>', self.print_contents)
+
+    def upper(self):
+        # notice here, we don't actually refer to the entry box.
+        # we just operate on the string variable and we
+        # because it's being looked at by the entry widget, changing
+        # the variable changes the entry widget display automatically.
+        # the strange get/set operators are clunky, true...
+        str = string.upper(self.contents.get())
+        self.contents.set(str)
+
+    def print_contents(self, event):
+        print "hi. contents of entry is now ---->", self.contents.get()
+
+root = App()
+root.master.title("Foo")
+root.mainloop()

Added: vendor/Python/current/Demo/tkinter/matt/killing-window-w-wm.py
===================================================================
--- vendor/Python/current/Demo/tkinter/matt/killing-window-w-wm.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/matt/killing-window-w-wm.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,42 @@
+from Tkinter import *
+
+# This file shows how to trap the killing of a window
+# when the user uses window manager menus (typ. upper left hand corner
+# menu in the decoration border).
+
+
+### ******* this isn't really called -- read the comments
+def my_delete_callback():
+    print "whoops -- tried to delete me!"
+
+class Test(Frame):
+    def deathHandler(self, event):
+        print self, "is now getting nuked. performing some save here...."
+
+    def createWidgets(self):
+        # a hello button
+        self.hi_there = Button(self, text='Hello')
+        self.hi_there.pack(side=LEFT)
+
+    def __init__(self, master=None):
+        Frame.__init__(self, master)
+        Pack.config(self)
+        self.createWidgets()
+
+        ###
+        ###  PREVENT WM kills from happening
+        ###
+
+        # the docs would have you do this:
+
+#       self.master.protocol("WM_DELETE_WINDOW", my_delete_callback)
+
+        # unfortunately, some window managers will not send this request to a window.
+        # the "protocol" function seems incapable of trapping these "aggressive" window kills.
+        # this line of code catches everything, tho. The window is deleted, but you have a chance
+        # of cleaning up first.
+        self.bind_all("<Destroy>", self.deathHandler)
+
+
+test = Test()
+test.mainloop()

Added: vendor/Python/current/Demo/tkinter/matt/menu-all-types-of-entries.py
===================================================================
--- vendor/Python/current/Demo/tkinter/matt/menu-all-types-of-entries.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/matt/menu-all-types-of-entries.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,244 @@
+from Tkinter import *
+
+# some vocabulary to keep from getting confused. This terminology
+# is something I cooked up for this file, but follows the man pages
+# pretty closely
+#
+#
+#
+#       This is a MENUBUTTON
+#       V
+# +-------------+
+# |             |
+#
+# +------------++------------++------------+
+# |            ||            ||            |
+# |  File      ||  Edit      || Options    |   <-------- the MENUBAR
+# |            ||            ||            |
+# +------------++------------++------------+
+# | New...         |
+# | Open...        |
+# | Print          |
+# |                |  <-------- This is a MENU. The lines of text in the menu are
+# |                |                            MENU ENTRIES
+# |                +---------------+
+# | Open Files >   | file1         |
+# |                | file2         |
+# |                | another file  | <------ this cascading part is also a MENU
+# +----------------|               |
+#                  |               |
+#                  |               |
+#                  |               |
+#                  +---------------+
+
+
+
+# some miscellaneous callbacks
+def new_file():
+    print "opening new file"
+
+def open_file():
+    print "opening OLD file"
+
+def print_something():
+    print "picked a menu item"
+
+
+
+anchovies = 0
+
+def print_anchovies():
+    global anchovies
+    anchovies = not anchovies
+    print "anchovies?", anchovies
+
+def makeCommandMenu():
+    # make menu button
+    Command_button = Menubutton(mBar, text='Simple Button Commands',
+                                underline=0)
+    Command_button.pack(side=LEFT, padx="2m")
+
+    # make the pulldown part of the File menu. The parameter passed is the master.
+    # we attach it to the button as a python attribute called "menu" by convention.
+    # hopefully this isn't too confusing...
+    Command_button.menu = Menu(Command_button)
+
+    # just to be cute, let's disable the undo option:
+    Command_button.menu.add_command(label="Undo")
+    # undo is the 0th entry...
+    Command_button.menu.entryconfig(0, state=DISABLED)
+
+    Command_button.menu.add_command(label='New...', underline=0,
+                                    command=new_file)
+    Command_button.menu.add_command(label='Open...', underline=0,
+                                    command=open_file)
+    Command_button.menu.add_command(label='Different Font', underline=0,
+                                    font='-*-helvetica-*-r-*-*-*-180-*-*-*-*-*-*',
+                                    command=print_something)
+
+    # we can make bitmaps be menu entries too. File format is X11 bitmap.
+    # if you use XV, save it under X11 bitmap format. duh-uh.,..
+    Command_button.menu.add_command(
+        bitmap="info")
+        #bitmap='@/home/mjc4y/dilbert/project.status.is.doomed.last.panel.bm')
+
+    # this is just a line
+    Command_button.menu.add('separator')
+
+    # change the color
+    Command_button.menu.add_command(label='Quit', underline=0,
+                                    background='red',
+                                    activebackground='green',
+                                    command=Command_button.quit)
+
+    # set up a pointer from the file menubutton back to the file menu
+    Command_button['menu'] = Command_button.menu
+
+    return Command_button
+
+
+
+def makeCascadeMenu():
+    # make menu button
+    Cascade_button = Menubutton(mBar, text='Cascading Menus', underline=0)
+    Cascade_button.pack(side=LEFT, padx="2m")
+
+    # the primary pulldown
+    Cascade_button.menu = Menu(Cascade_button)
+
+    # this is the menu that cascades from the primary pulldown....
+    Cascade_button.menu.choices = Menu(Cascade_button.menu)
+
+    # ...and this is a menu that cascades from that.
+    Cascade_button.menu.choices.wierdones = Menu(Cascade_button.menu.choices)
+
+    # then you define the menus from the deepest level on up.
+    Cascade_button.menu.choices.wierdones.add_command(label='avacado')
+    Cascade_button.menu.choices.wierdones.add_command(label='belgian endive')
+    Cascade_button.menu.choices.wierdones.add_command(label='beefaroni')
+
+    # definition of the menu one level up...
+    Cascade_button.menu.choices.add_command(label='Chocolate')
+    Cascade_button.menu.choices.add_command(label='Vanilla')
+    Cascade_button.menu.choices.add_command(label='TuttiFruiti')
+    Cascade_button.menu.choices.add_command(label='WopBopaLoopBapABopBamBoom')
+    Cascade_button.menu.choices.add_command(label='Rocky Road')
+    Cascade_button.menu.choices.add_command(label='BubbleGum')
+    Cascade_button.menu.choices.add_cascade(
+        label='Wierd Flavors',
+        menu=Cascade_button.menu.choices.wierdones)
+
+    # and finally, the definition for the top level
+    Cascade_button.menu.add_cascade(label='more choices',
+                                    menu=Cascade_button.menu.choices)
+
+    Cascade_button['menu'] = Cascade_button.menu
+
+    return Cascade_button
+
+def makeCheckbuttonMenu():
+    global fred
+    # make menu button
+    Checkbutton_button = Menubutton(mBar, text='Checkbutton Menus',
+                                    underline=0)
+    Checkbutton_button.pack(side=LEFT, padx='2m')
+
+    # the primary pulldown
+    Checkbutton_button.menu = Menu(Checkbutton_button)
+
+    # and all the check buttons. Note that the "variable" "onvalue" and "offvalue" options
+    # are not supported correctly at present. You have to do all your application
+    # work through the calback.
+    Checkbutton_button.menu.add_checkbutton(label='Pepperoni')
+    Checkbutton_button.menu.add_checkbutton(label='Sausage')
+    Checkbutton_button.menu.add_checkbutton(label='Extra Cheese')
+
+    # so here's a callback
+    Checkbutton_button.menu.add_checkbutton(label='Anchovy',
+                                            command=print_anchovies)
+
+    # and start with anchovies selected to be on. Do this by
+    # calling invoke on this menu option. To refer to the "anchovy" menu
+    # entry we need to know it's index. To do this, we use the index method
+    # which takes arguments of several forms:
+    #
+    # argument        what it does
+    # -----------------------------------
+    # a number        -- this is useless.
+    # "last"          -- last option in the menu
+    # "none"          -- used with the activate command. see the man page on menus
+    # "active"        -- the currently active menu option. A menu option is made active
+    #                         with the 'activate' method
+    # "@number"       -- where 'number' is an integer and is treated like a y coordinate in pixels
+    # string pattern  -- this is the option used below, and attempts to match "labels" using the
+    #                    rules of Tcl_StringMatch
+    Checkbutton_button.menu.invoke(Checkbutton_button.menu.index('Anchovy'))
+
+    # set up a pointer from the file menubutton back to the file menu
+    Checkbutton_button['menu'] = Checkbutton_button.menu
+
+    return Checkbutton_button
+
+
+def makeRadiobuttonMenu():
+    # make menu button
+    Radiobutton_button = Menubutton(mBar, text='Radiobutton Menus',
+                                    underline=0)
+    Radiobutton_button.pack(side=LEFT, padx='2m')
+
+    # the primary pulldown
+    Radiobutton_button.menu = Menu(Radiobutton_button)
+
+    # and all the Radio buttons. Note that the "variable" "onvalue" and "offvalue" options
+    # are not supported correctly at present. You have to do all your application
+    # work through the calback.
+    Radiobutton_button.menu.add_radiobutton(label='Republican')
+    Radiobutton_button.menu.add_radiobutton(label='Democrat')
+    Radiobutton_button.menu.add_radiobutton(label='Libertarian')
+    Radiobutton_button.menu.add_radiobutton(label='Commie')
+    Radiobutton_button.menu.add_radiobutton(label='Facist')
+    Radiobutton_button.menu.add_radiobutton(label='Labor Party')
+    Radiobutton_button.menu.add_radiobutton(label='Torie')
+    Radiobutton_button.menu.add_radiobutton(label='Independent')
+    Radiobutton_button.menu.add_radiobutton(label='Anarchist')
+    Radiobutton_button.menu.add_radiobutton(label='No Opinion')
+
+    # set up a pointer from the file menubutton back to the file menu
+    Radiobutton_button['menu'] = Radiobutton_button.menu
+
+    return Radiobutton_button
+
+
+def makeDisabledMenu():
+    Dummy_button = Menubutton(mBar, text='Dead Menu', underline=0)
+    Dummy_button.pack(side=LEFT, padx='2m')
+
+    # this is the standard way of turning off a whole menu
+    Dummy_button["state"] = DISABLED
+    return Dummy_button
+
+
+#################################################
+#### Main starts here ...
+root = Tk()
+
+
+# make a menu bar
+mBar = Frame(root, relief=RAISED, borderwidth=2)
+mBar.pack(fill=X)
+
+Command_button     = makeCommandMenu()
+Cascade_button     = makeCascadeMenu()
+Checkbutton_button = makeCheckbuttonMenu()
+Radiobutton_button = makeRadiobuttonMenu()
+NoMenu             = makeDisabledMenu()
+
+# finally, install the buttons in the menu bar.
+# This allows for scanning from one menubutton to the next.
+mBar.tk_menuBar(Command_button, Cascade_button, Checkbutton_button, Radiobutton_button, NoMenu)
+
+
+root.title('menu demo')
+root.iconname('menu demo')
+
+root.mainloop()

Added: vendor/Python/current/Demo/tkinter/matt/menu-simple.py
===================================================================
--- vendor/Python/current/Demo/tkinter/matt/menu-simple.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/matt/menu-simple.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,112 @@
+from Tkinter import *
+
+# some vocabulary to keep from getting confused. This terminology
+# is something I cooked up for this file, but follows the man pages
+# pretty closely
+#
+#
+#
+#       This is a MENUBUTTON
+#       V
+# +-------------+
+# |             |
+#
+# +------------++------------++------------+
+# |            ||            ||            |
+# |  File      ||  Edit      || Options    |   <-------- the MENUBAR
+# |            ||            ||            |
+# +------------++------------++------------+
+# | New...         |
+# | Open...        |
+# | Print          |
+# |                |  <------ This is a MENU. The lines of text in the menu are
+# |                |                          MENU ENTRIES
+# |                +---------------+
+# | Open Files >   | file1         |
+# |                | file2         |
+# |                | another file  | <------ this cascading part is also a MENU
+# +----------------|               |
+#                  |               |
+#                  |               |
+#                  |               |
+#                  +---------------+
+
+
+
+def new_file():
+    print "opening new file"
+
+
+def open_file():
+    print "opening OLD file"
+
+
+def makeFileMenu():
+    # make menu button : "File"
+    File_button = Menubutton(mBar, text='File', underline=0)
+    File_button.pack(side=LEFT, padx="1m")
+    File_button.menu = Menu(File_button)
+
+    # add an item. The first param is a menu entry type,
+    # must be one of: "cascade", "checkbutton", "command", "radiobutton", "seperator"
+    # see menu-demo-2.py for examples of use
+    File_button.menu.add_command(label='New...', underline=0,
+                                 command=new_file)
+
+
+    File_button.menu.add_command(label='Open...', underline=0,
+                                 command=open_file)
+
+    File_button.menu.add_command(label='Quit', underline=0,
+                                 command='exit')
+
+    # set up a pointer from the file menubutton back to the file menu
+    File_button['menu'] = File_button.menu
+
+    return File_button
+
+
+
+def makeEditMenu():
+    Edit_button = Menubutton(mBar, text='Edit', underline=0)
+    Edit_button.pack(side=LEFT, padx="1m")
+    Edit_button.menu = Menu(Edit_button)
+
+    # just to be cute, let's disable the undo option:
+    Edit_button.menu.add('command', label="Undo")
+    # Since the tear-off bar is the 0th entry,
+    # undo is the 1st entry...
+    Edit_button.menu.entryconfig(1, state=DISABLED)
+
+    # and these are just for show. No "command" callbacks attached.
+    Edit_button.menu.add_command(label="Cut")
+    Edit_button.menu.add_command(label="Copy")
+    Edit_button.menu.add_command(label="Paste")
+
+    # set up a pointer from the file menubutton back to the file menu
+    Edit_button['menu'] = Edit_button.menu
+
+    return Edit_button
+
+
+#################################################
+
+#### Main starts here ...
+root = Tk()
+
+
+# make a menu bar
+mBar = Frame(root, relief=RAISED, borderwidth=2)
+mBar.pack(fill=X)
+
+File_button = makeFileMenu()
+Edit_button = makeEditMenu()
+
+# finally, install the buttons in the menu bar.
+# This allows for scanning from one menubutton to the next.
+mBar.tk_menuBar(File_button, Edit_button)
+
+root.title('menu demo')
+root.iconname('packer')
+
+root.mainloop()

Added: vendor/Python/current/Demo/tkinter/matt/not-what-you-might-think-1.py
===================================================================
--- vendor/Python/current/Demo/tkinter/matt/not-what-you-might-think-1.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/matt/not-what-you-might-think-1.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,28 @@
+from Tkinter import *
+
+
+class Test(Frame):
+    def createWidgets(self):
+
+        self.Gpanel = Frame(self, width='1i', height='1i',
+                            background='green')
+        self.Gpanel.pack(side=LEFT)
+
+        # a QUIT button
+        self.Gpanel.QUIT = Button(self.Gpanel, text='QUIT',
+                                  foreground='red',
+                                  command=self.quit)
+        self.Gpanel.QUIT.pack(side=LEFT)
+
+
+    def __init__(self, master=None):
+        Frame.__init__(self, master)
+        Pack.config(self)
+        self.createWidgets()
+
+test = Test()
+
+test.master.title('packer demo')
+test.master.iconname('packer')
+
+test.mainloop()

Added: vendor/Python/current/Demo/tkinter/matt/not-what-you-might-think-2.py
===================================================================
--- vendor/Python/current/Demo/tkinter/matt/not-what-you-might-think-2.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/matt/not-what-you-might-think-2.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,30 @@
+from Tkinter import *
+
+
+class Test(Frame):
+    def createWidgets(self):
+
+        self.Gpanel = Frame(self, width='1i', height='1i',
+                            background='green')
+
+        # this line turns off the recalculation of geometry by masters.
+        self.Gpanel.propagate(0)
+
+        self.Gpanel.pack(side=LEFT)
+
+        # a QUIT button
+        self.Gpanel.QUIT = Button(self.Gpanel, text='QUIT', foreground='red',
+                                  command=self.quit)
+        self.Gpanel.QUIT.pack(side=LEFT)
+
+    def __init__(self, master=None):
+        Frame.__init__(self, master)
+        Pack.config(self)
+        self.createWidgets()
+
+test = Test()
+
+test.master.title('packer demo')
+test.master.iconname('packer')
+
+test.mainloop()

Added: vendor/Python/current/Demo/tkinter/matt/packer-and-placer-together.py
===================================================================
--- vendor/Python/current/Demo/tkinter/matt/packer-and-placer-together.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/matt/packer-and-placer-together.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,41 @@
+from Tkinter import *
+
+# This is a program that tests the placer geom manager in conjunction with
+# the packer. The background (green) is packed, while the widget inside is placed
+
+
+def do_motion(event):
+    app.button.place(x=event.x, y=event.y)
+
+def dothis():
+    print 'calling me!'
+
+def createWidgets(top):
+    # make a frame. Note that the widget is 200 x 200
+    # and the window containing is 400x400. We do this
+    # simply to show that this is possible. The rest of the
+    # area is inaccesssible.
+    f = Frame(top, width=200, height=200, background='green')
+
+    # note that we use a different manager here.
+    # This way, the top level frame widget resizes when the
+    # application window does.
+    f.pack(fill=BOTH, expand=1)
+
+    # now make a button
+    f.button = Button(f, foreground='red', text='amazing', command=dothis)
+
+    # and place it so that the nw corner is
+    # 1/2 way along the top X edge of its' parent
+    f.button.place(relx=0.5, rely=0.0, anchor=NW)
+
+    # allow the user to move the button SUIT-style.
+    f.bind('<Control-Shift-Motion>', do_motion)
+
+    return f
+
+root = Tk()
+app = createWidgets(root)
+root.geometry("400x400")
+root.maxsize(1000, 1000)
+root.mainloop()

Added: vendor/Python/current/Demo/tkinter/matt/packer-simple.py
===================================================================
--- vendor/Python/current/Demo/tkinter/matt/packer-simple.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/matt/packer-simple.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,32 @@
+from Tkinter import *
+
+
+class Test(Frame):
+    def printit(self):
+        print self.hi_there["command"]
+
+    def createWidgets(self):
+        # a hello button
+        self.QUIT = Button(self, text='QUIT', foreground='red',
+                           command=self.quit)
+        self.QUIT.pack(side=LEFT, fill=BOTH)
+
+        self.hi_there = Button(self, text='Hello',
+                               command=self.printit)
+        self.hi_there.pack(side=LEFT)
+
+        # note how Packer defaults to side=TOP
+
+        self.guy2 = Button(self, text='button 2')
+        self.guy2.pack()
+
+        self.guy3 = Button(self, text='button 3')
+        self.guy3.pack()
+
+    def __init__(self, master=None):
+        Frame.__init__(self, master)
+        Pack.config(self)
+        self.createWidgets()
+
+test = Test()
+test.mainloop()

Added: vendor/Python/current/Demo/tkinter/matt/placer-simple.py
===================================================================
--- vendor/Python/current/Demo/tkinter/matt/placer-simple.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/matt/placer-simple.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,39 @@
+from Tkinter import *
+
+# This is a program that tests the placer geom manager
+
+def do_motion(event):
+    app.button.place(x=event.x, y=event.y)
+
+def dothis():
+    print 'calling me!'
+
+def createWidgets(top):
+    # make a frame. Note that the widget is 200 x 200
+    # and the window containing is 400x400. We do this
+    # simply to show that this is possible. The rest of the
+    # area is inaccesssible.
+    f = Frame(top, width=200, height=200, background='green')
+
+    # place it so the upper left hand corner of
+    # the frame is in the upper left corner of
+    # the parent
+    f.place(relx=0.0, rely=0.0)
+
+    # now make a button
+    f.button = Button(f, foreground='red', text='amazing', command=dothis)
+
+    # and place it so that the nw corner is
+    # 1/2 way along the top X edge of its' parent
+    f.button.place(relx=0.5, rely=0.0, anchor=NW)
+
+    # allow the user to move the button SUIT-style.
+    f.bind('<Control-Shift-Motion>', do_motion)
+
+    return f
+
+root = Tk()
+app = createWidgets(root)
+root.geometry("400x400")
+root.maxsize(1000, 1000)
+root.mainloop()

Added: vendor/Python/current/Demo/tkinter/matt/pong-demo-1.py
===================================================================
--- vendor/Python/current/Demo/tkinter/matt/pong-demo-1.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/matt/pong-demo-1.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,54 @@
+from Tkinter import *
+
+import string
+
+
+class Pong(Frame):
+    def createWidgets(self):
+        self.QUIT = Button(self, text='QUIT', foreground='red',
+                           command=self.quit)
+        self.QUIT.pack(side=LEFT, fill=BOTH)
+
+        ## The playing field
+        self.draw = Canvas(self, width="5i", height="5i")
+
+        ## The speed control for the ball
+        self.speed = Scale(self, orient=HORIZONTAL, label="ball speed",
+                           from_=-100, to=100)
+
+        self.speed.pack(side=BOTTOM, fill=X)
+
+        # The ball
+        self.ball = self.draw.create_oval("0i", "0i", "0.10i", "0.10i",
+                                          fill="red")
+        self.x = 0.05
+        self.y = 0.05
+        self.velocity_x = 0.3
+        self.velocity_y = 0.5
+
+        self.draw.pack(side=LEFT)
+
+    def moveBall(self, *args):
+        if (self.x > 5.0) or (self.x < 0.0):
+            self.velocity_x = -1.0 * self.velocity_x
+        if (self.y > 5.0) or (self.y < 0.0):
+            self.velocity_y = -1.0 * self.velocity_y
+
+        deltax = (self.velocity_x * self.speed.get() / 100.0)
+        deltay = (self.velocity_y * self.speed.get() / 100.0)
+        self.x = self.x + deltax
+        self.y = self.y + deltay
+
+        self.draw.move(self.ball,  "%ri" % deltax, "%ri" % deltay)
+        self.after(10, self.moveBall)
+
+    def __init__(self, master=None):
+        Frame.__init__(self, master)
+        Pack.config(self)
+        self.createWidgets()
+        self.after(10, self.moveBall)
+
+
+game = Pong()
+
+game.mainloop()

Added: vendor/Python/current/Demo/tkinter/matt/printing-coords-of-items.py
===================================================================
--- vendor/Python/current/Demo/tkinter/matt/printing-coords-of-items.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/matt/printing-coords-of-items.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,61 @@
+from Tkinter import *
+
+# this file demonstrates the creation of widgets as part of a canvas object
+
+class Test(Frame):
+    ###################################################################
+    ###### Event callbacks for THE CANVAS (not the stuff drawn on it)
+    ###################################################################
+    def mouseDown(self, event):
+        # see if we're inside a dot. If we are, it
+        # gets tagged as CURRENT for free by tk.
+
+        if not event.widget.find_withtag(CURRENT):
+            # there is no dot here, so we can make one,
+            # and bind some interesting behavior to it.
+            # ------
+            # create a dot, and mark it as current
+            fred = self.draw.create_oval(
+                event.x - 10, event.y -10, event.x +10, event.y + 10,
+                fill="green")
+            self.draw.tag_bind(fred, "<Enter>", self.mouseEnter)
+            self.draw.tag_bind(fred, "<Leave>", self.mouseLeave)
+        self.lastx = event.x
+        self.lasty = event.y
+
+    def mouseMove(self, event):
+        self.draw.move(CURRENT, event.x - self.lastx, event.y - self.lasty)
+        self.lastx = event.x
+        self.lasty = event.y
+
+    ###################################################################
+    ###### Event callbacks for canvas ITEMS (stuff drawn on the canvas)
+    ###################################################################
+    def mouseEnter(self, event):
+        # the "current" tag is applied to the object the cursor is over.
+        # this happens automatically.
+        self.draw.itemconfig(CURRENT, fill="red")
+        print self.draw.coords(CURRENT)
+
+    def mouseLeave(self, event):
+        # the "current" tag is applied to the object the cursor is over.
+        # this happens automatically.
+        self.draw.itemconfig(CURRENT, fill="blue")
+
+    def createWidgets(self):
+        self.QUIT = Button(self, text='QUIT', foreground='red',
+                           command=self.quit)
+        self.QUIT.pack(side=LEFT, fill=BOTH)
+        self.draw = Canvas(self, width="5i", height="5i")
+        self.draw.pack(side=LEFT)
+
+        Widget.bind(self.draw, "<1>", self.mouseDown)
+        Widget.bind(self.draw, "<B1-Motion>", self.mouseMove)
+
+    def __init__(self, master=None):
+        Frame.__init__(self, master)
+        Pack.config(self)
+        self.createWidgets()
+
+test = Test()
+test.mainloop()

Added: vendor/Python/current/Demo/tkinter/matt/radiobutton-simple.py
===================================================================
--- vendor/Python/current/Demo/tkinter/matt/radiobutton-simple.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/matt/radiobutton-simple.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,62 @@
+from Tkinter import *
+
+# This is a demo program that shows how to
+# create radio buttons and how to get other widgets to
+# share the information in a radio button.
+#
+# There are other ways of doing this too, but
+# the "variable" option of radiobuttons seems to be the easiest.
+#
+# note how each button has a value it sets the variable to as it gets hit.
+
+
+class Test(Frame):
+    def printit(self):
+        print "hi"
+
+    def createWidgets(self):
+
+        self.flavor = StringVar()
+        self.flavor.set("chocolate")
+
+        self.radioframe = Frame(self)
+        self.radioframe.pack()
+
+        # 'text' is the label
+        # 'variable' is the name of the variable that all these radio buttons share
+        # 'value' is the value this variable takes on when the radio button is selected
+        # 'anchor' makes the text appear left justified (default is centered. ick)
+        self.radioframe.choc = Radiobutton(
+            self.radioframe, text="Chocolate Flavor",
+            variable=self.flavor, value="chocolate",
+            anchor=W)
+        self.radioframe.choc.pack(fill=X)
+
+        self.radioframe.straw = Radiobutton(
+            self.radioframe, text="Strawberry Flavor",
+            variable=self.flavor, value="strawberry",
+            anchor=W)
+        self.radioframe.straw.pack(fill=X)
+
+        self.radioframe.lemon = Radiobutton(
+            self.radioframe, text="Lemon Flavor",
+            variable=self.flavor, value="lemon",
+            anchor=W)
+        self.radioframe.lemon.pack(fill=X)
+
+        # this is a text entry that lets you type in the name of a flavor too.
+        self.entry = Entry(self, textvariable=self.flavor)
+        self.entry.pack(fill=X)
+        self.QUIT = Button(self, text='QUIT', foreground='red',
+                           command=self.quit)
+        self.QUIT.pack(side=BOTTOM, fill=BOTH)
+
+
+    def __init__(self, master=None):
+        Frame.__init__(self, master)
+        Pack.config(self)
+        self.createWidgets()
+
+test = Test()
+
+test.mainloop()

Added: vendor/Python/current/Demo/tkinter/matt/rubber-band-box-demo-1.py
===================================================================
--- vendor/Python/current/Demo/tkinter/matt/rubber-band-box-demo-1.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/matt/rubber-band-box-demo-1.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,58 @@
+from Tkinter import *
+
+class Test(Frame):
+    def printit(self):
+        print "hi"
+
+    def createWidgets(self):
+        self.QUIT = Button(self, text='QUIT',
+                                  background='red',
+                                  foreground='white',
+                                  height=3,
+                                  command=self.quit)
+        self.QUIT.pack(side=BOTTOM, fill=BOTH)
+
+        self.canvasObject = Canvas(self, width="5i", height="5i")
+        self.canvasObject.pack(side=LEFT)
+
+    def mouseDown(self, event):
+        # canvas x and y take the screen coords from the event and translate
+        # them into the coordinate system of the canvas object
+        self.startx = self.canvasObject.canvasx(event.x)
+        self.starty = self.canvasObject.canvasy(event.y)
+
+    def mouseMotion(self, event):
+        # canvas x and y take the screen coords from the event and translate
+        # them into the coordinate system of the canvas object
+        x = self.canvasObject.canvasx(event.x)
+        y = self.canvasObject.canvasy(event.y)
+
+        if (self.startx != event.x)  and (self.starty != event.y) :
+            self.canvasObject.delete(self.rubberbandBox)
+            self.rubberbandBox = self.canvasObject.create_rectangle(
+                self.startx, self.starty, x, y)
+            # this flushes the output, making sure that
+            # the rectangle makes it to the screen
+            # before the next event is handled
+            self.update_idletasks()
+
+    def mouseUp(self, event):
+        self.canvasObject.delete(self.rubberbandBox)
+
+    def __init__(self, master=None):
+        Frame.__init__(self, master)
+        Pack.config(self)
+        self.createWidgets()
+
+        # this is a "tagOrId" for the rectangle we draw on the canvas
+        self.rubberbandBox = None
+
+        # and the bindings that make it work..
+        Widget.bind(self.canvasObject, "<Button-1>", self.mouseDown)
+        Widget.bind(self.canvasObject, "<Button1-Motion>", self.mouseMotion)
+        Widget.bind(self.canvasObject, "<Button1-ButtonRelease>", self.mouseUp)
+
+
+test = Test()
+
+test.mainloop()

Added: vendor/Python/current/Demo/tkinter/matt/rubber-line-demo-1.py
===================================================================
--- vendor/Python/current/Demo/tkinter/matt/rubber-line-demo-1.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/matt/rubber-line-demo-1.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,51 @@
+from Tkinter import *
+
+class Test(Frame):
+    def printit(self):
+        print "hi"
+
+    def createWidgets(self):
+        self.QUIT = Button(self, text='QUIT',
+                                  background='red',
+                                  foreground='white',
+                                  height=3,
+                                  command=self.quit)
+        self.QUIT.pack(side=BOTTOM, fill=BOTH)
+
+        self.canvasObject = Canvas(self, width="5i", height="5i")
+        self.canvasObject.pack(side=LEFT)
+
+    def mouseDown(self, event):
+        # canvas x and y take the screen coords from the event and translate
+        # them into the coordinate system of the canvas object
+        self.startx = self.canvasObject.canvasx(event.x)
+        self.starty = self.canvasObject.canvasy(event.y)
+
+    def mouseMotion(self, event):
+        # canvas x and y take the screen coords from the event and translate
+        # them into the coordinate system of the canvas object
+        x = self.canvasObject.canvasx(event.x)
+        y = self.canvasObject.canvasy(event.y)
+
+        if (self.startx != event.x)  and (self.starty != event.y) :
+            self.canvasObject.delete(self.rubberbandLine)
+            self.rubberbandLine = self.canvasObject.create_line(
+                self.startx, self.starty, x, y)
+            # this flushes the output, making sure that
+            # the rectangle makes it to the screen
+            # before the next event is handled
+            self.update_idletasks()
+
+    def __init__(self, master=None):
+        Frame.__init__(self, master)
+        Pack.config(self)
+        self.createWidgets()
+        # this is a "tagOrId" for the rectangle we draw on the canvas
+        self.rubberbandLine = None
+        Widget.bind(self.canvasObject, "<Button-1>", self.mouseDown)
+        Widget.bind(self.canvasObject, "<Button1-Motion>", self.mouseMotion)
+
+
+test = Test()
+
+test.mainloop()

Added: vendor/Python/current/Demo/tkinter/matt/slider-demo-1.py
===================================================================
--- vendor/Python/current/Demo/tkinter/matt/slider-demo-1.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/matt/slider-demo-1.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,36 @@
+from Tkinter import *
+
+# shows how to make a slider, set and get its value under program control
+
+
+class Test(Frame):
+    def print_value(self, val):
+        print "slider now at", val
+
+    def reset(self):
+        self.slider.set(0)
+
+    def createWidgets(self):
+        self.slider = Scale(self, from_=0, to=100,
+                            orient=HORIZONTAL,
+                            length="3i",
+                            label="happy slider",
+                            command=self.print_value)
+
+        self.reset = Button(self, text='reset slider',
+                            command=self.reset)
+
+        self.QUIT = Button(self, text='QUIT', foreground='red',
+                           command=self.quit)
+
+        self.slider.pack(side=LEFT)
+        self.reset.pack(side=LEFT)
+        self.QUIT.pack(side=LEFT, fill=BOTH)
+
+    def __init__(self, master=None):
+        Frame.__init__(self, master)
+        Pack.config(self)
+        self.createWidgets()
+
+test = Test()
+test.mainloop()

Added: vendor/Python/current/Demo/tkinter/matt/subclass-existing-widgets.py
===================================================================
--- vendor/Python/current/Demo/tkinter/matt/subclass-existing-widgets.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/matt/subclass-existing-widgets.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,28 @@
+from Tkinter import *
+
+# This is a program that makes a simple two button application
+
+
+class New_Button(Button):
+    def callback(self):
+        print self.counter
+        self.counter = self.counter + 1
+
+def createWidgets(top):
+    f = Frame(top)
+    f.pack()
+    f.QUIT = Button(f, text='QUIT', foreground='red', command=top.quit)
+
+    f.QUIT.pack(side=LEFT, fill=BOTH)
+
+    # a hello button
+    f.hi_there = New_Button(f, text='Hello')
+    # we do this on a different line because we need to reference f.hi_there
+    f.hi_there.config(command=f.hi_there.callback)
+    f.hi_there.pack(side=LEFT)
+    f.hi_there.counter = 43
+
+
+root = Tk()
+createWidgets(root)
+root.mainloop()

Added: vendor/Python/current/Demo/tkinter/matt/two-radio-groups.py
===================================================================
--- vendor/Python/current/Demo/tkinter/matt/two-radio-groups.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/matt/two-radio-groups.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,110 @@
+from Tkinter import *
+
+#       The way to think about this is that each radio button menu
+#       controls a different variable -- clicking on one of the
+#       mutually exclusive choices in a radiobutton assigns some value
+#       to an application variable you provide. When you define a
+#       radiobutton menu choice, you have the option of specifying the
+#       name of a varaible and value to assign to that variable when
+#       that choice is selected. This clever mechanism relieves you,
+#       the programmer, from having to write a dumb callback that
+#       probably wouldn't have done anything more than an assignment
+#       anyway. The Tkinter options for this follow their Tk
+#       counterparts:
+#       {"variable" : my_flavor_variable, "value" : "strawberry"}
+#       where my_flavor_variable is an instance of one of the
+#       subclasses of Variable, provided in Tkinter.py (there is
+#       StringVar(), IntVar(), DoubleVar() and BooleanVar() to choose
+#       from)
+
+
+
+def makePoliticalParties(var):
+    # make menu button
+    Radiobutton_button = Menubutton(mBar, text='Political Party',
+                                    underline=0)
+    Radiobutton_button.pack(side=LEFT, padx='2m')
+
+    # the primary pulldown
+    Radiobutton_button.menu = Menu(Radiobutton_button)
+
+    Radiobutton_button.menu.add_radiobutton(label='Republican',
+                                            variable=var, value=1)
+
+    Radiobutton_button.menu.add('radiobutton', {'label': 'Democrat',
+                                                'variable' : var,
+                                                'value' : 2})
+
+    Radiobutton_button.menu.add('radiobutton', {'label': 'Libertarian',
+                                                'variable' : var,
+                                                'value' : 3})
+
+    var.set(2)
+
+    # set up a pointer from the file menubutton back to the file menu
+    Radiobutton_button['menu'] = Radiobutton_button.menu
+
+    return Radiobutton_button
+
+
+def makeFlavors(var):
+    # make menu button
+    Radiobutton_button = Menubutton(mBar, text='Flavors',
+                                    underline=0)
+    Radiobutton_button.pack(side=LEFT, padx='2m')
+
+    # the primary pulldown
+    Radiobutton_button.menu = Menu(Radiobutton_button)
+
+    Radiobutton_button.menu.add_radiobutton(label='Strawberry',
+                                            variable=var, value='Strawberry')
+
+    Radiobutton_button.menu.add_radiobutton(label='Chocolate',
+                                            variable=var, value='Chocolate')
+
+    Radiobutton_button.menu.add_radiobutton(label='Rocky Road',
+                                            variable=var, value='Rocky Road')
+
+    # choose a default
+    var.set("Chocolate")
+
+    # set up a pointer from the file menubutton back to the file menu
+    Radiobutton_button['menu'] = Radiobutton_button.menu
+
+    return Radiobutton_button
+
+
+def printStuff():
+    print "party is", party.get()
+    print "flavor is", flavor.get()
+    print
+
+#################################################
+#### Main starts here ...
+root = Tk()
+
+
+# make a menu bar
+mBar = Frame(root, relief=RAISED, borderwidth=2)
+mBar.pack(fill=X)
+
+# make two application variables,
+# one to control each radio button set
+party = IntVar()
+flavor = StringVar()
+
+Radiobutton_button = makePoliticalParties(party)
+Radiobutton_button2 = makeFlavors(flavor)
+
+# finally, install the buttons in the menu bar.
+# This allows for scanning from one menubutton to the next.
+mBar.tk_menuBar(Radiobutton_button, Radiobutton_button2)
+
+b = Button(root, text="print party and flavor", foreground="red",
+           command=printStuff)
+b.pack(side=TOP)
+
+root.title('menu demo')
+root.iconname('menu demo')
+
+root.mainloop()

Added: vendor/Python/current/Demo/tkinter/matt/window-creation-more.py
===================================================================
--- vendor/Python/current/Demo/tkinter/matt/window-creation-more.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/matt/window-creation-more.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,35 @@
+from Tkinter import *
+
+# this shows how to create a new window with a button in it
+# that can create new windows
+
+class Test(Frame):
+    def printit(self):
+        print "hi"
+
+    def makeWindow(self):
+        fred = Toplevel()
+        fred.label = Button(fred,
+                            text="This is window number %d." % self.windownum,
+                            command=self.makeWindow)
+        fred.label.pack()
+        self.windownum = self.windownum + 1
+
+    def createWidgets(self):
+        self.QUIT = Button(self, text='QUIT', foreground='red',
+                           command=self.quit)
+        self.QUIT.pack(side=LEFT, fill=BOTH)
+
+        # a hello button
+        self.hi_there = Button(self, text='Make a New Window',
+                               command=self.makeWindow)
+        self.hi_there.pack(side=LEFT)
+
+    def __init__(self, master=None):
+        Frame.__init__(self, master)
+        Pack.config(self)
+        self.windownum = 0
+        self.createWidgets()
+
+test = Test()
+test.mainloop()

Added: vendor/Python/current/Demo/tkinter/matt/window-creation-simple.py
===================================================================
--- vendor/Python/current/Demo/tkinter/matt/window-creation-simple.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/matt/window-creation-simple.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,31 @@
+from Tkinter import *
+
+# this shows how to spawn off new windows at a button press
+
+class Test(Frame):
+    def printit(self):
+        print "hi"
+
+    def makeWindow(self):
+        fred = Toplevel()
+        fred.label = Label(fred, text="Here's a new window")
+        fred.label.pack()
+
+    def createWidgets(self):
+        self.QUIT = Button(self, text='QUIT', foreground='red',
+                           command=self.quit)
+
+        self.QUIT.pack(side=LEFT, fill=BOTH)
+
+        # a hello button
+        self.hi_there = Button(self, text='Make a New Window',
+                               command=self.makeWindow)
+        self.hi_there.pack(side=LEFT)
+
+    def __init__(self, master=None):
+        Frame.__init__(self, master)
+        Pack.config(self)
+        self.createWidgets()
+
+test = Test()
+test.mainloop()

Added: vendor/Python/current/Demo/tkinter/matt/window-creation-w-location.py
===================================================================
--- vendor/Python/current/Demo/tkinter/matt/window-creation-w-location.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/tkinter/matt/window-creation-w-location.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,45 @@
+from Tkinter import *
+
+import sys
+##sys.path.append("/users/mjc4y/projects/python/tkinter/utils")
+##from TkinterUtils  import *
+
+# this shows how to create a new window with a button in it that
+# can create new windows
+
+class QuitButton(Button):
+    def __init__(self, master, *args, **kwargs):
+        if not kwargs.has_key("text"):
+            kwargs["text"] = "QUIT"
+        if not kwargs.has_key("command"):
+            kwargs["command"] = master.quit
+        apply(Button.__init__, (self, master) + args, kwargs)
+
+class Test(Frame):
+    def makeWindow(self, *args):
+        fred = Toplevel()
+
+        fred.label = Canvas (fred, width="2i", height="2i")
+
+        fred.label.create_line("0", "0", "2i", "2i")
+        fred.label.create_line("0", "2i", "2i", "0")
+        fred.label.pack()
+
+        ##centerWindow(fred, self.master)
+
+    def createWidgets(self):
+        self.QUIT = QuitButton(self)
+        self.QUIT.pack(side=LEFT, fill=BOTH)
+
+        self.makeWindow = Button(self, text='Make a New Window',
+                                 width=50, height=20,
+                                 command=self.makeWindow)
+        self.makeWindow.pack(side=LEFT)
+
+    def __init__(self, master=None):
+        Frame.__init__(self, master)
+        Pack.config(self)
+        self.createWidgets()
+
+test = Test()
+test.mainloop()

Added: vendor/Python/current/Demo/xml/elem_count.py
===================================================================
--- vendor/Python/current/Demo/xml/elem_count.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/xml/elem_count.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,36 @@
+import sys
+
+from xml.sax import make_parser, handler
+
+class FancyCounter(handler.ContentHandler):
+
+    def __init__(self):
+        self._elems = 0
+        self._attrs = 0
+        self._elem_types = {}
+        self._attr_types = {}
+
+    def startElement(self, name, attrs):
+        self._elems = self._elems + 1
+        self._attrs = self._attrs + len(attrs)
+        self._elem_types[name] = self._elem_types.get(name, 0) + 1
+
+        for name in attrs.keys():
+            self._attr_types[name] = self._attr_types.get(name, 0) + 1
+
+    def endDocument(self):
+        print "There were", self._elems, "elements."
+        print "There were", self._attrs, "attributes."
+
+        print "---ELEMENT TYPES"
+        for pair in  self._elem_types.items():
+            print "%20s %d" % pair
+
+        print "---ATTRIBUTE TYPES"
+        for pair in  self._attr_types.items():
+            print "%20s %d" % pair
+
+
+parser = make_parser()
+parser.setContentHandler(FancyCounter())
+parser.parse(sys.argv[1])

Added: vendor/Python/current/Demo/xml/roundtrip.py
===================================================================
--- vendor/Python/current/Demo/xml/roundtrip.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/xml/roundtrip.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,45 @@
+"""
+A simple demo that reads in an XML document and spits out an equivalent,
+but not necessarily identical, document.
+"""
+
+import sys, string
+
+from xml.sax import saxutils, handler, make_parser
+
+# --- The ContentHandler
+
+class ContentGenerator(handler.ContentHandler):
+
+    def __init__(self, out = sys.stdout):
+        handler.ContentHandler.__init__(self)
+        self._out = out
+
+    # ContentHandler methods
+
+    def startDocument(self):
+        self._out.write('<?xml version="1.0" encoding="iso-8859-1"?>\n')
+
+    def startElement(self, name, attrs):
+        self._out.write('<' + name)
+        for (name, value) in attrs.items():
+            self._out.write(' %s="%s"' % (name, saxutils.escape(value)))
+        self._out.write('>')
+
+    def endElement(self, name):
+        self._out.write('</%s>' % name)
+
+    def characters(self, content):
+        self._out.write(saxutils.escape(content))
+
+    def ignorableWhitespace(self, content):
+        self._out.write(content)
+
+    def processingInstruction(self, target, data):
+        self._out.write('<?%s %s?>' % (target, data))
+
+# --- The main program
+
+parser = make_parser()
+parser.setContentHandler(ContentGenerator())
+parser.parse(sys.argv[1])

Added: vendor/Python/current/Demo/xml/rss2html.py
===================================================================
--- vendor/Python/current/Demo/xml/rss2html.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/xml/rss2html.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,91 @@
+import sys
+
+from xml.sax import make_parser, handler
+
+# --- Templates
+
+top = \
+"""
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+  <TITLE>%s</TITLE>
+</HEAD>
+
+<BODY>
+<H1>%s</H1>
+"""
+
+bottom = \
+"""
+</ul>
+
+<HR>
+<ADDRESS>
+Converted to HTML by sax_rss2html.py.
+</ADDRESS>
+
+</BODY>
+</HTML>
+"""
+
+# --- The ContentHandler
+
+class RSSHandler(handler.ContentHandler):
+
+    def __init__(self, out = sys.stdout):
+        handler.ContentHandler.__init__(self)
+        self._out = out
+
+        self._text = ""
+        self._parent = None
+        self._list_started = 0
+        self._title = None
+        self._link = None
+        self._descr = ""
+
+    # ContentHandler methods
+
+    def startElement(self, name, attrs):
+        if name == "channel" or name == "image" or name == "item":
+            self._parent = name
+
+        self._text = ""
+
+    def endElement(self, name):
+        if self._parent == "channel":
+            if name == "title":
+                self._out.write(top % (self._text, self._text))
+            elif name == "description":
+                self._out.write("<p>%s</p>\n" % self._text)
+
+        elif self._parent == "item":
+            if name == "title":
+                self._title = self._text
+            elif name == "link":
+                self._link = self._text
+            elif name == "description":
+                self._descr = self._text
+            elif name == "item":
+                if not self._list_started:
+                    self._out.write("<ul>\n")
+                    self._list_started = 1
+
+                self._out.write('  <li><a href="%s">%s</a> %s\n' %
+                                (self._link, self._title, self._descr))
+
+                self._title = None
+                self._link = None
+                self._descr = ""
+
+        if name == "rss":
+            self._out.write(bottom)
+
+    def characters(self, content):
+        self._text = self._text + content
+
+# --- Main program
+
+parser = make_parser()
+parser.setContentHandler(RSSHandler())
+parser.parse(sys.argv[1])

Added: vendor/Python/current/Demo/zlib/minigzip.py
===================================================================
--- vendor/Python/current/Demo/zlib/minigzip.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/zlib/minigzip.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,133 @@
+#!/usr/bin/env python
+# Demo program for zlib; it compresses or decompresses files, but *doesn't*
+# delete the original.  This doesn't support all of gzip's options.
+#
+# The 'gzip' module in the standard library provides a more complete
+# implementation of gzip-format files.
+
+import zlib, sys, os
+
+FTEXT, FHCRC, FEXTRA, FNAME, FCOMMENT = 1, 2, 4, 8, 16
+
+def write32(output, value):
+    output.write(chr(value & 255)) ; value=value // 256
+    output.write(chr(value & 255)) ; value=value // 256
+    output.write(chr(value & 255)) ; value=value // 256
+    output.write(chr(value & 255))
+
+def read32(input):
+    v = ord(input.read(1))
+    v += (ord(input.read(1)) << 8 )
+    v += (ord(input.read(1)) << 16)
+    v += (ord(input.read(1)) << 24)
+    return v
+
+def compress (filename, input, output):
+    output.write('\037\213\010')        # Write the header, ...
+    output.write(chr(FNAME))            # ... flag byte ...
+
+    statval = os.stat(filename)           # ... modification time ...
+    mtime = statval[8]
+    write32(output, mtime)
+    output.write('\002')                # ... slowest compression alg. ...
+    output.write('\377')                # ... OS (=unknown) ...
+    output.write(filename+'\000')       # ... original filename ...
+
+    crcval = zlib.crc32("")
+    compobj = zlib.compressobj(9, zlib.DEFLATED, -zlib.MAX_WBITS,
+                             zlib.DEF_MEM_LEVEL, 0)
+    while True:
+        data = input.read(1024)
+        if data == "":
+            break
+        crcval = zlib.crc32(data, crcval)
+        output.write(compobj.compress(data))
+    output.write(compobj.flush())
+    write32(output, crcval)             # ... the CRC ...
+    write32(output, statval[6])         # and the file size.
+
+def decompress (input, output):
+    magic = input.read(2)
+    if magic != '\037\213':
+        print 'Not a gzipped file'
+        sys.exit(0)
+    if ord(input.read(1)) != 8:
+        print 'Unknown compression method'
+        sys.exit(0)
+    flag = ord(input.read(1))
+    input.read(4+1+1)                   # Discard modification time,
+                                        # extra flags, and OS byte.
+    if flag & FEXTRA:
+        # Read & discard the extra field, if present
+        xlen = ord(input.read(1))
+        xlen += 256*ord(input.read(1))
+        input.read(xlen)
+    if flag & FNAME:
+        # Read and discard a null-terminated string containing the filename
+        while True:
+            s = input.read(1)
+            if s == '\0': break
+    if flag & FCOMMENT:
+        # Read and discard a null-terminated string containing a comment
+        while True:
+            s=input.read(1)
+            if s=='\0': break
+    if flag & FHCRC:
+        input.read(2)                   # Read & discard the 16-bit header CRC
+
+    decompobj = zlib.decompressobj(-zlib.MAX_WBITS)
+    crcval = zlib.crc32("")
+    length = 0
+    while True:
+        data=input.read(1024)
+        if data == "":
+            break
+        decompdata = decompobj.decompress(data)
+        output.write(decompdata)
+        length += len(decompdata)
+        crcval = zlib.crc32(decompdata, crcval)
+
+    decompdata = decompobj.flush()
+    output.write(decompdata)
+    length += len(decompdata)
+    crcval = zlib.crc32(decompdata, crcval)
+
+    # We've read to the end of the file, so we have to rewind in order
+    # to reread the 8 bytes containing the CRC and the file size.  The
+    # decompressor is smart and knows when to stop, so feeding it
+    # extra data is harmless.
+    input.seek(-8, 2)
+    crc32 = read32(input)
+    isize = read32(input)
+    if crc32 != crcval:
+        print 'CRC check failed.'
+    if isize != length:
+        print 'Incorrect length of data produced'
+
+def main():
+    if len(sys.argv)!=2:
+        print 'Usage: minigzip.py <filename>'
+        print '  The file will be compressed or decompressed.'
+        sys.exit(0)
+
+    filename = sys.argv[1]
+    if filename.endswith('.gz'):
+        compressing = False
+        outputname = filename[:-3]
+    else:
+        compressing = True
+        outputname = filename + '.gz'
+
+    input = open(filename, 'rb')
+    output = open(outputname, 'wb')
+
+    if compressing:
+        compress(filename, input, output)
+    else:
+        decompress(input, output)
+
+    input.close()
+    output.close()
+
+if __name__ == '__main__':
+    main()


Property changes on: vendor/Python/current/Demo/zlib/minigzip.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Demo/zlib/zlibdemo.py
===================================================================
--- vendor/Python/current/Demo/zlib/zlibdemo.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Demo/zlib/zlibdemo.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,48 @@
+#!/usr/bin/env python
+
+# Takes an optional filename, defaulting to this file itself.
+# Reads the file and compresses the content using level 1 and level 9
+# compression, printing a summary of the results.
+
+import zlib, sys
+
+def main():
+    if len(sys.argv) > 1:
+        filename = sys.argv[1]
+    else:
+        filename = sys.argv[0]
+    print 'Reading', filename
+
+    f = open(filename, 'rb')           # Get the data to compress
+    s = f.read()
+    f.close()
+
+    # First, we'll compress the string in one step
+    comptext = zlib.compress(s, 1)
+    decomp = zlib.decompress(comptext)
+
+    print '1-step compression: (level 1)'
+    print '    Original:', len(s), 'Compressed:', len(comptext),
+    print 'Uncompressed:', len(decomp)
+
+    # Now, let's compress the string in stages; set chunk to work in smaller steps
+
+    chunk = 256
+    compressor = zlib.compressobj(9)
+    decompressor = zlib.decompressobj()
+    comptext = decomp = ''
+    for i in range(0, len(s), chunk):
+        comptext = comptext+compressor.compress(s[i:i+chunk])
+    # Don't forget to call flush()!!
+    comptext = comptext + compressor.flush()
+
+    for i in range(0, len(comptext), chunk):
+        decomp = decomp + decompressor.decompress(comptext[i:i+chunk])
+    decomp=decomp+decompressor.flush()
+
+    print 'Progressive compression (level 9):'
+    print '    Original:', len(s), 'Compressed:', len(comptext),
+    print 'Uncompressed:', len(decomp)
+
+if __name__ == '__main__':
+    main()


Property changes on: vendor/Python/current/Demo/zlib/zlibdemo.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Doc/ACKS
===================================================================
--- vendor/Python/current/Doc/ACKS	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/ACKS	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,202 @@
+Contributors to the Python Documentation
+----------------------------------------
+
+This file lists people who have contributed in some way to the Python
+documentation.  It is probably not complete -- if you feel that you or
+anyone else should be on this list, please let us know (send email to
+docs at python.org), and we'll be glad to correct the problem.
+
+It is only with the input and contributions of the Python community
+that Python has such wonderful documentation -- Thank You!
+
+In the official sources, this file is encoded in ISO-8859-1 (Latin-1).
+
+
+  -Fred
+
+
+Aahz
+Michael Abbott
+Steve Alexander
+Jim Ahlstrom
+Fred Allen
+A. Amoroso
+Pehr Anderson
+Oliver Andrich
+Jesús Cea Avión
+Daniel Barclay
+Chris Barker
+Don Bashford
+Anthony Baxter
+Bennett Benson
+Jonathan Black
+Robin Boerdijk
+Michal Bozon
+Aaron Brancotti
+Keith Briggs
+Lee Busby
+Lorenzo M. Catucci
+Mauro Cicognini
+Gilles Civario
+Mike Clarkson
+Steve Clift
+Dave Cole
+Matthew Cowles
+Jeremy Craven
+Andrew Dalke
+Ben Darnell
+L. Peter Deutsch
+Robert Donohue
+Fred L. Drake, Jr.
+Jeff Epler
+Michael Ernst
+Blame Andy Eskilsson
+Carey Evans
+Martijn Faassen
+Carl Feynman
+Hernán Martínez Foffani
+Stefan Franke
+Jim Fulton
+Peter Funk
+Lele Gaifax
+Matthew Gallagher
+Ben Gertzfield
+Nadim Ghaznavi
+Jonathan Giddy
+Shelley Gooch
+Nathaniel Gray
+Grant Griffin
+Thomas Guettler
+Anders Hammarquist
+Mark Hammond
+Harald Hanche-Olsen
+Manus Hand
+Gerhard Häring
+Travis B. Hartwell
+Janko Hauser
+Bernhard Herzog
+Magnus L. Hetland
+Konrad Hinsen
+Stefan Hoffmeister
+Albert Hofkamp
+Gregor Hoffleit
+Steve Holden
+Thomas Holenstein
+Gerrit Holl
+Rob Hooft
+Brian Hooper
+Randall Hopper
+Michael Hudson
+Eric Huss
+Jeremy Hylton
+Roger Irwin
+Jack Jansen
+Philip H. Jensen
+Pedro Diaz Jimenez
+Kent Johnson
+Lucas de Jonge
+Andreas Jung
+Robert Kern
+Jim Kerr
+Jan Kim
+Greg Kochanski
+Guido Kollerie
+Peter A. Koren
+Daniel Kozan
+Andrew M. Kuchling
+Dave Kuhlman
+Erno Kuusela
+Detlef Lannert
+Piers Lauder
+Glyph Lefkowitz
+Marc-André Lemburg
+Ulf A. Lindgren
+Everett Lipman
+Mirko Liss
+Martin von Löwis
+Fredrik Lundh
+Jeff MacDonald
+John Machin
+Andrew MacIntyre
+Vladimir Marangozov
+Vincent Marchetti
+Laura Matson
+Daniel May
+Doug Mennella
+Paolo Milani
+Skip Montanaro
+Paul Moore
+Ross Moore
+Sjoerd Mullender
+Dale Nagata
+Ng Pheng Siong
+Koray Oner
+Tomas Oppelstrup
+Denis S. Otkidach
+Zooko O'Whielacronx
+William Park
+Joonas Paalasmaa
+Harri Pasanen
+Bo Peng
+Tim Peters
+Christopher Petrilli
+Justin D. Pettit
+Chris Phoenix
+François Pinard
+Paul Prescod
+Eric S. Raymond
+Edward K. Ream
+Sean Reifschneider
+Bernhard Reiter
+Armin Rigo
+Wes Rishel
+Jim Roskind
+Guido van Rossum
+Donald Wallace Rouse II
+Nick Russo
+Chris Ryland
+Constantina S.
+Hugh Sasse
+Bob Savage
+Scott Schram
+Neil Schemenauer
+Barry Scott
+Joakim Sernbrant
+Justin Sheehy
+Michael Simcich
+Ionel Simionescu
+Gregory P. Smith
+Roy Smith
+Clay Spence
+Nicholas Spies
+Tage Stabell-Kulo
+Frank Stajano
+Anthony Starks
+Greg Stein
+Peter Stoehr
+Mark Summerfield
+Reuben Sumner
+Kalle Svensson
+Jim Tittsler
+Ville Vainio
+Martijn Vries
+Charles G. Waldman
+Greg Ward
+Barry Warsaw
+Corran Webster
+Glyn Webster
+Bob Weiner
+Eddy Welbourne
+Mats Wichmann
+Gerry Wiener
+Timothy Wild
+Collin Winter
+Blake Winton
+Dan Wolfe
+Steven Work
+Thomas Wouters
+Ka-Ping Yee
+Rory Yorke
+Moshe Zadka
+Milan Zamazal
+Cheng Zhang

Added: vendor/Python/current/Doc/Makefile.deps
===================================================================
--- vendor/Python/current/Doc/Makefile.deps	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/Makefile.deps	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,386 @@
+# LaTeX source dependencies.
+
+COMMONSTYLES= texinputs/python.sty \
+	texinputs/pypaper.sty
+
+INDEXSTYLES=texinputs/python.ist
+
+COMMONTEX=commontex/copyright.tex \
+	commontex/license.tex \
+	commontex/patchlevel.tex \
+	commontex/boilerplate.tex
+
+MANSTYLES= texinputs/fncychap.sty \
+	texinputs/manual.cls \
+	$(COMMONSTYLES)
+
+HOWTOSTYLES= texinputs/howto.cls \
+	$(COMMONSTYLES)
+
+
+APIFILES= $(MANSTYLES) $(INDEXSTYLES) $(COMMONTEX) \
+	api/api.tex \
+	api/abstract.tex \
+	api/concrete.tex \
+	api/exceptions.tex \
+	api/init.tex \
+	api/intro.tex \
+	api/memory.tex \
+	api/newtypes.tex \
+	api/refcounting.tex \
+	api/utilities.tex \
+	api/veryhigh.tex \
+	commontex/typestruct.h \
+	commontex/reportingbugs.tex
+
+# These files are generated from those listed above, and are used to
+# generate the typeset versions of the manuals.  The list is defined
+# here to make it easier to ensure parallelism.
+ANNOAPIFILES= $(MANSTYLES) $(INDEXSTYLES) $(COMMONTEX) api/refcounts.dat \
+	paper-$(PAPER)/api.tex \
+	paper-$(PAPER)/abstract.tex \
+	paper-$(PAPER)/concrete.tex \
+	paper-$(PAPER)/exceptions.tex \
+	paper-$(PAPER)/init.tex \
+	paper-$(PAPER)/intro.tex \
+	paper-$(PAPER)/memory.tex \
+	paper-$(PAPER)/newtypes.tex \
+	paper-$(PAPER)/refcounting.tex \
+	paper-$(PAPER)/utilities.tex \
+	paper-$(PAPER)/veryhigh.tex \
+	commontex/reportingbugs.tex
+
+DOCFILES= $(HOWTOSTYLES) \
+	commontex/boilerplate.tex \
+	texinputs/ltxmarkup.sty \
+	doc/doc.tex
+
+EXTFILES= ext/ext.tex $(MANSTYLES) $(INDEXSTYLES) $(COMMONTEX) \
+	ext/extending.tex \
+	ext/newtypes.tex \
+	ext/building.tex \
+	ext/windows.tex \
+	ext/embedding.tex \
+	ext/noddy.c \
+	ext/noddy2.c \
+	ext/noddy3.c \
+	ext/noddy4.c \
+	ext/run-func.c \
+	commontex/typestruct.h \
+	commontex/reportingbugs.tex
+
+TUTFILES= tut/tut.tex tut/glossary.tex $(MANSTYLES) $(COMMONTEX)
+
+# LaTeX source files for the Python Reference Manual
+REFFILES= $(MANSTYLES) $(INDEXSTYLES) $(COMMONTEX) \
+	ref/ref.tex \
+	ref/ref1.tex \
+	ref/ref2.tex \
+	ref/ref3.tex \
+	ref/ref4.tex \
+	ref/ref5.tex \
+	ref/ref6.tex \
+	ref/ref7.tex \
+	ref/ref8.tex 
+
+# LaTeX source files for the Python Library Reference
+LIBFILES= $(MANSTYLES) $(INDEXSTYLES) $(COMMONTEX) \
+	commontex/reportingbugs.tex \
+	lib/lib.tex \
+	lib/asttable.tex \
+	lib/compiler.tex \
+	lib/distutils.tex \
+	lib/email.tex \
+	lib/emailencoders.tex \
+	lib/emailexc.tex \
+	lib/emailgenerator.tex \
+	lib/emailiter.tex \
+	lib/emailmessage.tex \
+	lib/emailparser.tex \
+	lib/emailutil.tex \
+	lib/libintro.tex \
+	lib/libobjs.tex \
+	lib/libstdtypes.tex \
+	lib/libexcs.tex \
+	lib/libconsts.tex \
+	lib/libfuncs.tex \
+	lib/libpython.tex \
+	lib/libsys.tex \
+	lib/libplatform.tex \
+	lib/libfpectl.tex \
+	lib/libgc.tex \
+	lib/libsets.tex \
+	lib/libweakref.tex \
+	lib/libinspect.tex \
+	lib/libpydoc.tex \
+	lib/libdifflib.tex \
+	lib/libdoctest.tex \
+	lib/libunittest.tex \
+	lib/libtest.tex \
+	lib/libtypes.tex \
+	lib/libtraceback.tex \
+	lib/libpickle.tex \
+	lib/libshelve.tex \
+	lib/libcopy.tex \
+	lib/libmarshal.tex \
+	lib/libwarnings.tex \
+	lib/libimp.tex \
+	lib/libzipimport.tex \
+	lib/librunpy.tex \
+	lib/libpkgutil.tex \
+	lib/libparser.tex \
+	lib/libbltin.tex \
+	lib/libmain.tex \
+	lib/libfuture.tex \
+	lib/libstrings.tex \
+	lib/libstring.tex \
+	lib/libtextwrap.tex \
+	lib/libcodecs.tex \
+	lib/libunicodedata.tex \
+	lib/libstringprep.tex \
+	lib/libstruct.tex \
+	lib/libmisc.tex \
+	lib/libmath.tex \
+	lib/libdecimal.tex \
+	lib/libarray.tex \
+	lib/liballos.tex \
+	lib/libos.tex \
+	lib/libdatetime.tex \
+	lib/tzinfo-examples.py \
+	lib/libtime.tex \
+	lib/libgetopt.tex \
+	lib/liboptparse.tex \
+	lib/caseless.py \
+	lib/required_1.py \
+	lib/required_2.py \
+	lib/libtempfile.tex \
+	lib/liberrno.tex \
+	lib/libctypes.tex \
+	lib/libsomeos.tex \
+	lib/libsignal.tex \
+	lib/libsocket.tex \
+	lib/libselect.tex \
+	lib/libthread.tex \
+	lib/libdummythread.tex \
+	lib/libunix.tex \
+	lib/libposix.tex \
+	lib/libposixpath.tex \
+	lib/libpwd.tex \
+	lib/libspwd.tex \
+	lib/libgrp.tex \
+	lib/libcrypt.tex \
+	lib/libdbm.tex \
+	lib/libgdbm.tex \
+	lib/libtermios.tex \
+	lib/libfcntl.tex \
+	lib/libposixfile.tex \
+	lib/libsyslog.tex \
+	lib/liblogging.tex \
+	lib/libpdb.tex \
+	lib/libprofile.tex \
+	lib/libhotshot.tex \
+	lib/libtimeit.tex \
+	lib/libtrace.tex \
+	lib/libcgi.tex \
+	lib/libcgitb.tex \
+	lib/liburllib.tex \
+	lib/liburllib2.tex \
+	lib/libhttplib.tex \
+	lib/libftplib.tex \
+	lib/libgopherlib.tex \
+	lib/libnntplib.tex \
+	lib/liburlparse.tex \
+	lib/libhtmlparser.tex \
+	lib/libhtmllib.tex \
+	lib/libsgmllib.tex \
+	lib/librfc822.tex \
+	lib/libmimetools.tex \
+	lib/libmimewriter.tex \
+	lib/libbinascii.tex \
+	lib/libmm.tex \
+	lib/libaudioop.tex \
+	lib/libimageop.tex \
+	lib/libaifc.tex \
+	lib/libjpeg.tex \
+	lib/librgbimg.tex \
+	lib/libossaudiodev.tex \
+	lib/libcrypto.tex \
+	lib/libhashlib.tex \
+	lib/libmd5.tex \
+	lib/libsha.tex \
+	lib/libhmac.tex \
+	lib/libstdwin.tex \
+	lib/libsgi.tex \
+	lib/libal.tex \
+	lib/libcd.tex \
+	lib/libfl.tex \
+	lib/libfm.tex \
+	lib/libgl.tex \
+	lib/libimgfile.tex \
+	lib/libsun.tex \
+	lib/libxdrlib.tex \
+	lib/libimghdr.tex \
+	lib/librestricted.tex \
+	lib/librexec.tex \
+	lib/libbastion.tex \
+	lib/libformatter.tex \
+	lib/liboperator.tex \
+	lib/libresource.tex \
+	lib/libstat.tex \
+	lib/libstringio.tex \
+	lib/libtoken.tex \
+	lib/libkeyword.tex \
+	lib/libundoc.tex \
+	lib/libmailcap.tex \
+	lib/libglob.tex \
+	lib/libuser.tex \
+	lib/libanydbm.tex \
+	lib/libbsddb.tex \
+	lib/libdumbdbm.tex \
+	lib/libdbhash.tex \
+	lib/librandom.tex \
+	lib/libsite.tex \
+	lib/libwhichdb.tex \
+	lib/libbase64.tex \
+	lib/libfnmatch.tex \
+	lib/libquopri.tex \
+	lib/libzlib.tex \
+	lib/libsocksvr.tex \
+	lib/libmailbox.tex \
+	lib/libcommands.tex \
+	lib/libcmath.tex \
+	lib/libgzip.tex \
+	lib/libbz2.tex \
+	lib/libzipfile.tex \
+	lib/libpprint.tex \
+	lib/libcode.tex \
+	lib/libmimify.tex \
+	lib/libre.tex \
+	lib/libuserdict.tex \
+	lib/libdis.tex \
+	lib/libxmlrpclib.tex \
+	lib/libsimplexmlrpc.tex \
+	lib/libdocxmlrpc.tex \
+	lib/libpyexpat.tex \
+	lib/libfunctools.tex \
+	lib/xmldom.tex \
+	lib/xmldomminidom.tex \
+	lib/xmldompulldom.tex \
+	lib/xmlsax.tex \
+	lib/xmlsaxhandler.tex \
+	lib/xmlsaxutils.tex \
+	lib/xmlsaxreader.tex \
+	lib/libetree.tex \
+	lib/libqueue.tex \
+	lib/liblocale.tex \
+	lib/libgettext.tex \
+	lib/libbasehttp.tex \
+	lib/libcookie.tex \
+	lib/libcookielib.tex \
+	lib/libcopyreg.tex \
+	lib/libsymbol.tex \
+	lib/libbinhex.tex \
+	lib/libuu.tex \
+	lib/libsunaudio.tex \
+	lib/libfileinput.tex \
+	lib/libimaplib.tex \
+	lib/libpoplib.tex \
+	lib/libcalendar.tex \
+	lib/libpopen2.tex \
+	lib/libbisect.tex \
+	lib/libcollections.tex \
+	lib/libheapq.tex \
+	lib/libmimetypes.tex \
+	lib/libsmtplib.tex \
+	lib/libsmtpd.tex \
+	lib/libcmd.tex \
+	lib/libmultifile.tex \
+	lib/libthreading.tex \
+	lib/libdummythreading.tex \
+	lib/libwebbrowser.tex \
+	lib/internet.tex \
+	lib/netdata.tex \
+	lib/markup.tex \
+	lib/language.tex \
+	lib/libpycompile.tex \
+	lib/libcompileall.tex \
+	lib/libshlex.tex \
+	lib/libnetrc.tex \
+	lib/librobotparser.tex \
+	lib/libgetpass.tex \
+	lib/libshutil.tex \
+	lib/librepr.tex \
+	lib/libmsilib.tex \
+	lib/libmsvcrt.tex \
+	lib/libwinreg.tex \
+	lib/libwinsound.tex \
+	lib/windows.tex \
+	lib/libpyclbr.tex \
+	lib/libtokenize.tex \
+	lib/libtabnanny.tex \
+	lib/libmhlib.tex \
+	lib/libtelnetlib.tex \
+	lib/libcolorsys.tex \
+	lib/libfpformat.tex \
+	lib/libcgihttp.tex \
+	lib/libsimplehttp.tex \
+	lib/liblinecache.tex \
+	lib/libnew.tex \
+	lib/libdircache.tex \
+	lib/libfilecmp.tex \
+	lib/libsunau.tex \
+	lib/libwave.tex \
+	lib/libchunk.tex \
+	lib/libcodeop.tex \
+	lib/libcurses.tex \
+	lib/libcursespanel.tex \
+	lib/libascii.tex \
+	lib/libdl.tex \
+	lib/libmutex.tex \
+	lib/libnis.tex \
+	lib/libpipes.tex \
+	lib/libpty.tex \
+	lib/libreadline.tex \
+	lib/librlcompleter.tex \
+	lib/libsched.tex \
+	lib/libstatvfs.tex \
+	lib/libtty.tex \
+	lib/libasyncore.tex \
+	lib/libasynchat.tex \
+	lib/libatexit.tex \
+	lib/libmmap.tex \
+	lib/tkinter.tex \
+	lib/libturtle.tex \
+	lib/libtarfile.tex \
+	lib/libcsv.tex \
+	lib/libcfgparser.tex \
+	lib/libsqlite3.tex
+
+# LaTeX source files for Macintosh Library Modules.
+MACFILES= $(HOWTOSTYLES) $(INDEXSTYLES) $(COMMONTEX) \
+	mac/mac.tex \
+	mac/using.tex \
+	mac/scripting.tex \
+	mac/toolbox.tex \
+	mac/undoc.tex \
+	mac/libcolorpicker.tex \
+	mac/libmac.tex \
+	mac/libgensuitemodule.tex \
+	mac/libaetools.tex \
+	mac/libaepack.tex \
+	mac/libaetypes.tex \
+	mac/libmacfs.tex \
+	mac/libmacos.tex \
+	mac/libmacostools.tex \
+	mac/libmacui.tex \
+	mac/libmacic.tex \
+	mac/libframework.tex \
+	mac/libautogil.tex \
+	mac/libminiae.tex \
+	mac/libscrap.tex
+
+INSTFILES = $(HOWTOSTYLES) inst/inst.tex
+
+DISTFILES = $(HOWTOSTYLES) \
+	dist/dist.tex \
+	dist/sysconfig.tex

Added: vendor/Python/current/Doc/README
===================================================================
--- vendor/Python/current/Doc/README	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/README	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,246 @@
+Python standard documentation -- in LaTeX
+-----------------------------------------
+
+This directory contains the LaTeX sources to the Python documentation
+and tools required to support the formatting process.  The documents
+now require LaTeX2e; LaTeX 2.09 compatibility has been dropped.
+
+If you don't have LaTeX, or if you'd rather not format the
+documentation yourself, you can ftp a tar file containing HTML, PDF,
+or PostScript versions of all documents.  Additional formats may be
+available.  These should be in the same place where you fetched the
+main Python distribution (try <http://www.python.org/> or
+<ftp://ftp.python.org/pub/python/>).
+
+The following are the LaTeX source files:
+
+	api/*.tex	Python/C API Reference Manual
+	doc/*.tex	Documenting Python
+	ext/*.tex	Extending and Embedding the Python Interpreter
+	lib/*.tex	Python Library Reference
+	mac/*.tex	Macintosh Library Modules
+	ref/*.tex	Python Reference Manual
+	tut/*.tex	Python Tutorial
+        inst/*.tex      Installing Python Modules
+        dist/*.tex      Distributing Python Modules
+
+Most use the "manual" document class and "python" package, derived from 
+the old "myformat.sty" style file.  The Macintosh Library Modules
+document uses the "howto" document class instead.  These contains many
+macro definitions useful in documenting Python, and set some style
+parameters.
+
+There's a Makefile to call LaTeX and the other utilities in the right
+order and the right number of times.  By default, it will build the
+HTML version of the documentation, but DVI, PDF, and PostScript can
+also be made.  To view the generated HTML, point your favorite browser
+at the top-level index (html/index.html) after running "make".
+
+The Makefile can also produce DVI files for each document made; to
+preview them, use xdvi.  PostScript is produced by the same Makefile
+target that produces the DVI files.  This uses the dvips tool.
+Printing depends on local conventions; at our site, we use lpr.  For
+example:
+
+	make paper-letter/lib.ps	# create lib.dvi and lib.ps
+	xdvi paper-letter/lib.dvi	# preview lib.dvi
+	lpr paper-letter/lib.ps		# print on default printer
+
+
+What if I find a bug?
+---------------------
+
+First, check that the bug is present in the development version of the
+documentation at <http://www.python.org/dev/doc/devel/>; we may
+have already fixed it.
+
+If we haven't, tell us about it.  We'd like the documentation to be
+complete and accurate, but have limited time.  If you discover any
+inconsistencies between the documentation and implementation, or just
+have suggestions as to how to improve the documentation, let is know!
+Specific bugs and patches should be reported using our bug & patch
+databases at:
+
+	http://sourceforge.net/projects/python
+
+Other suggestions or questions should be sent to the Python
+Documentation Team:
+
+	docs at python.org
+
+Thanks!
+
+
+What tools do I need?
+---------------------
+
+You need to install Python; some of the scripts used to produce the
+documentation are written in Python.  You don't need this
+documentation to install Python; instructions are included in the
+README file in the Python distribution.
+
+The simplest way to get the rest of the tools in the configuration we
+used is to install the teTeX TeX distribution, versions 0.9 or newer.
+More information is available on teTeX at <http://www.tug.org/tetex/>.
+This is a Unix-only TeX distribution at this time.  This documentation
+release was tested with the 1.0.7 release, but there have been no
+substantial changes since late in the 0.9 series, which we used
+extensively for previous versions without any difficulty.
+
+If you don't want to get teTeX, here is what you'll need:
+
+To create DVI, PDF, or PostScript files:
+
+	- LaTeX2e, 1995/12/01 or newer.  Older versions are likely to 
+	  choke.
+
+	- makeindex.  This is used to produce the indexes for the
+	  library reference and Python/C API reference.
+
+To create PDF files:
+
+	- pdflatex.  We used the one in the teTeX distribution (pdfTeX
+          version 3.14159-13d (Web2C 7.3.1) at the time of this
+          writing).  Versions even a couple of patchlevels earlier are
+          highly likely to fail due to syntax changes for some of the
+          pdftex primitives.
+
+To create PostScript files:
+
+	- dvips.  Most TeX installations include this.  If you don't
+	  have one, check CTAN (<ftp://ctan.tug.org/tex-archive/>).
+
+To create info files:
+
+	Note that info support is currently being revised using new
+	conversion tools by Michael Ernst <mernst at cs.washington.edu>.
+
+	- makeinfo.  This is available from any GNU mirror.
+
+	- emacs or xemacs.  Emacs is available from the same place as
+	  makeinfo, and xemacs is available from ftp.xemacs.org.
+
+	- Perl.  Find the software at
+	  <http://language.perl.com/info/software.html>.
+
+	- HTML::Element.  If you don't have this installed, you can get
+	  this from CPAN.  Use the command:
+
+	  perl -e 'use CPAN; CPAN::install("HTML::Element");'
+
+	  You may need to be root to do this.
+
+To create HTML files:
+
+	- Perl 5.6.0 or newer.  Find the software at
+	  <http://language.perl.com/info/software.html>.
+
+	- LaTeX2HTML 99.2b8 or newer.  Older versions are not
+	  supported; each version changes enough that supporting
+	  multiple versions is not likely to work.  Many older
+	  versions don't work with Perl 5.6 as well.  This also screws
+	  up code fragments.  ;-(  Releases are available at:
+	  <http://www.latex2html.org/>.
+
+
+I got a make error: "make: don't know how to make commontex/patchlevel.tex."
+----------------------------------------------------------------------------
+
+Your version of make doesn't support the 'shell' function.  You will need to
+use a version which does, e.g. GNU make.
+
+
+LaTeX (or pdfLaTeX) ran out of memory; how can I fix it?
+--------------------------------------------------------
+
+This is known to be a problem at least on Mac OS X, but it has been
+observed on other systems in the past.
+
+On some systems, the default sizes of some of the memory pools
+allocated by TeX needs to be changed; this is a configuration setting
+for installations based on web2c (most if not all installations).
+This is usually set in a file named texmf/web2c/texmf.cnf (where the
+top-level texmf/ directory is part of the TeX installation).  If you
+get a "buffer overflow" warning from LaTeX, open that configuration
+file and look for the "main_memory.pdflatex" setting.  If there is not
+one, you can add a line with the setting.  The value 1500000 seems to
+be sufficient for formatting the Python documetantion.
+
+
+What if Times fonts are not available?
+--------------------------------------
+
+As distributed, the LaTeX documents use PostScript Times fonts.  This
+is done since they are much better looking and produce smaller
+PostScript files.  If, however, your TeX installation does not support
+them, they may be easily disabled.  Edit the file
+texinputs/pypaper.sty and comment out the line that starts
+"\RequirePackage{times}" by inserting a "%" character at the beginning
+of the line.  If you're formatting the docs for A4 paper instead of
+US-Letter paper, change paper-a4/pypaper.sty instead.  An alternative
+is to install the right fonts and LaTeX style file.
+
+
+What if I want to use A4 paper?
+-------------------------------
+
+Instead of building the PostScript by giving the command "make ps",
+give the command "make PAPER=a4 ps"; the output will be produced in
+the paper-a4/ subdirectory.  (You can use "make PAPER=a4 pdf" if you'd
+rather have PDF output.)
+
+
+Making HTML files
+-----------------
+
+The LaTeX documents can be converted to HTML using Nikos Drakos'
+LaTeX2HTML converter.  See the Makefile; after some twiddling, "make"
+should do the trick.
+
+
+What else is in here?
+---------------------
+
+There is a new LaTeX document class called "howto".  This is used for
+the new series of Python HOWTO documents which is being coordinated by
+Andrew Kuchling <akuchlin at mems-exchange.org>.  The file
+templates/howto.tex is a commented example which may be used as a
+template.  A Python script to "do the right thing" to format a howto
+document is included as tools/mkhowto.  These documents can be
+formatted as HTML, PDF, PostScript, or ASCII files.  Use "mkhowto
+--help" for information on using the formatting tool.
+
+For authors of module documentation, there is a file
+templates/module.tex which may be used as a template for a module
+section.  This may be used in conjunction with either the howto or
+manual document class.  Create the documentation for a new module by
+copying the template to lib<mymodule>.tex and editing according to the 
+instructions in the comments.
+
+Documentation on the authoring Python documentation, including
+information about both style and markup, is available in the
+"Documenting Python" manual.
+
+
+Copyright notice
+================
+
+The Python source is copyrighted, but you can freely use and copy it
+as long as you don't change or remove the copyright notice:
+
+----------------------------------------------------------------------
+Copyright (c) 2000-2007 Python Software Foundation.
+All rights reserved.
+
+Copyright (c) 2000 BeOpen.com.
+All rights reserved.
+
+Copyright (c) 1995-2000 Corporation for National Research Initiatives.
+All rights reserved.
+
+Copyright (c) 1991-1995 Stichting Mathematisch Centrum.
+All rights reserved.
+
+See the file "commontex/license.tex" for information on usage and
+redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+----------------------------------------------------------------------

Added: vendor/Python/current/Doc/TODO
===================================================================
--- vendor/Python/current/Doc/TODO	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/TODO	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,74 @@
+PYTHON DOCUMENTATION TO-DO LIST			-*- indented-text -*-
+===============================
+
+General
+-------
+
+* Figure out HTMLHelp generation for the Windows world.
+
+
+Python/C API
+------------
+
+* The "Very High Level Interface" in the API document has been
+  requested; I guess it wouldn't hurt to fill in a bit there.  Request 
+  by Albert Hofkamp <a.hofkamp at wtb.tue.nl>.  (Partly done.)
+
+* Describe implementing types in C, including use of the 'self'
+  parameter to the method implementation function.  (Missing material
+  mentioned in the Extending & Embedding manual, section 1.1; problem
+  reported by Clay Spence <cspence at sarnoff.com>.)  Heavily impacts one
+  chapter of the Python/C API manual.
+
+* Missing PyArg_ParseTuple(), PyArg_ParseTupleAndKeywords(),
+  Py_BuildValue().  Information requested by Greg Kochanski
+  <gpk at bell-labs.com>.  PyEval_EvalCode() has also been requested.
+
+Extending & Embedding
+---------------------
+
+* More information is needed about building dynamically linked
+  extensions in C++.  Specifically, the extensions must be linked
+  against the C++ libraries (and possibly runtime).  Also noted by
+  Albert Hofkamp <a.hofkamp at wtb.tue.nl>.
+
+Reference Manual
+----------------
+
+* Document the Extended Call Syntax in the language reference.
+  [Jeremy Hylton]
+
+* Document new comparison support for recursive objects (lang. ref.?
+  library ref.? (cmp() function).  [Jeremy Hylton]
+
+Library Reference
+-----------------
+
+* Update the pickle documentation to describe all of the current
+  behavior; only a subset is described.  __reduce__, etc.  Partial
+  update submitted by Jim Kerr <jbkerr at sr.hp.com>.
+
+* Update the httplib documentation to match Greg Stein's HTTP/1.1
+  support and new classes.  (Greg, this is yours!)
+
+Tutorial
+--------
+
+* Update tutorial to use string methods and talk about backward
+  compatibility of same.
+
+
+NOT WORTH THE TROUBLE
+---------------------
+
+* In the indexes, some subitem entries are separated from the item
+  entries by column- or page-breaks.  Reported by Lorenzo M. Catucci
+  <lorenzo at argon.roma2.infn.it>.  This one will be hard; probably not
+  really worth the pain.  (Only an issue at all when a header-letter
+  and the first index entry get separated -- can change as soon as we
+  change the index entries in the text.)  Also only a problem in the
+  print version.
+
+* Fix problem with howto documents getting the last module synopsis
+  twice (in \localmoduletable) so we can get rid of the ugly 'uniq'
+  hack in tools/mkhowto.  (Probably not worth the trouble of fixing.)

Added: vendor/Python/current/Doc/api/abstract.tex
===================================================================
--- vendor/Python/current/Doc/api/abstract.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/api/abstract.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1057 @@
+\chapter{Abstract Objects Layer \label{abstract}}
+
+The functions in this chapter interact with Python objects regardless
+of their type, or with wide classes of object types (e.g. all
+numerical types, or all sequence types).  When used on object types
+for which they do not apply, they will raise a Python exception.
+
+It is not possible to use these functions on objects that are not properly
+initialized, such as a list object that has been created by
+\cfunction{PyList_New()}, but whose items have not been set to some
+non-\code{NULL} value yet.
+
+\section{Object Protocol \label{object}}
+
+\begin{cfuncdesc}{int}{PyObject_Print}{PyObject *o, FILE *fp, int flags}
+  Print an object \var{o}, on file \var{fp}.  Returns \code{-1} on
+  error.  The flags argument is used to enable certain printing
+  options.  The only option currently supported is
+  \constant{Py_PRINT_RAW}; if given, the \function{str()} of the
+  object is written instead of the \function{repr()}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyObject_HasAttrString}{PyObject *o, const char *attr_name}
+  Returns \code{1} if \var{o} has the attribute \var{attr_name}, and
+  \code{0} otherwise.  This is equivalent to the Python expression
+  \samp{hasattr(\var{o}, \var{attr_name})}.  This function always
+  succeeds.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyObject_GetAttrString}{PyObject *o,
+                                                     const char *attr_name}
+  Retrieve an attribute named \var{attr_name} from object \var{o}.
+  Returns the attribute value on success, or \NULL{} on failure.
+  This is the equivalent of the Python expression
+  \samp{\var{o}.\var{attr_name}}.
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{int}{PyObject_HasAttr}{PyObject *o, PyObject *attr_name}
+  Returns \code{1} if \var{o} has the attribute \var{attr_name}, and
+  \code{0} otherwise.  This is equivalent to the Python expression
+  \samp{hasattr(\var{o}, \var{attr_name})}.  This function always
+  succeeds.
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{PyObject*}{PyObject_GetAttr}{PyObject *o,
+                                               PyObject *attr_name}
+  Retrieve an attribute named \var{attr_name} from object \var{o}.
+  Returns the attribute value on success, or \NULL{} on failure.  This
+  is the equivalent of the Python expression
+  \samp{\var{o}.\var{attr_name}}.
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{int}{PyObject_SetAttrString}{PyObject *o,
+                                               const char *attr_name, PyObject *v}
+  Set the value of the attribute named \var{attr_name}, for object
+  \var{o}, to the value \var{v}. Returns \code{-1} on failure.  This
+  is the equivalent of the Python statement
+  \samp{\var{o}.\var{attr_name} = \var{v}}.
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{int}{PyObject_SetAttr}{PyObject *o,
+                                         PyObject *attr_name, PyObject *v}
+  Set the value of the attribute named \var{attr_name}, for object
+  \var{o}, to the value \var{v}. Returns \code{-1} on failure.  This
+  is the equivalent of the Python statement
+  \samp{\var{o}.\var{attr_name} = \var{v}}.
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{int}{PyObject_DelAttrString}{PyObject *o, const char *attr_name}
+  Delete attribute named \var{attr_name}, for object \var{o}. Returns
+  \code{-1} on failure.  This is the equivalent of the Python
+  statement: \samp{del \var{o}.\var{attr_name}}.
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{int}{PyObject_DelAttr}{PyObject *o, PyObject *attr_name}
+  Delete attribute named \var{attr_name}, for object \var{o}. Returns
+  \code{-1} on failure.  This is the equivalent of the Python
+  statement \samp{del \var{o}.\var{attr_name}}.
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{PyObject*}{PyObject_RichCompare}{PyObject *o1,
+                                                   PyObject *o2, int opid}
+  Compare the values of \var{o1} and \var{o2} using the operation
+  specified by \var{opid}, which must be one of
+  \constant{Py_LT},
+  \constant{Py_LE},
+  \constant{Py_EQ},
+  \constant{Py_NE},
+  \constant{Py_GT}, or
+  \constant{Py_GE}, corresponding to
+  \code{<},
+  \code{<=},
+  \code{==},
+  \code{!=},
+  \code{>}, or
+  \code{>=} respectively. This is the equivalent of the Python expression
+  \samp{\var{o1} op \var{o2}}, where \code{op} is the operator
+  corresponding to \var{opid}. Returns the value of the comparison on
+  success, or \NULL{} on failure.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyObject_RichCompareBool}{PyObject *o1,
+                                                 PyObject *o2, int opid}
+  Compare the values of \var{o1} and \var{o2} using the operation
+  specified by \var{opid}, which must be one of
+  \constant{Py_LT},
+  \constant{Py_LE},
+  \constant{Py_EQ},
+  \constant{Py_NE},
+  \constant{Py_GT}, or
+  \constant{Py_GE}, corresponding to
+  \code{<},
+  \code{<=},
+  \code{==},
+  \code{!=},
+  \code{>}, or
+  \code{>=} respectively. Returns \code{-1} on error, \code{0} if the
+  result is false, \code{1} otherwise. This is the equivalent of the
+  Python expression \samp{\var{o1} op \var{o2}}, where
+  \code{op} is the operator corresponding to \var{opid}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyObject_Cmp}{PyObject *o1, PyObject *o2, int *result}
+  Compare the values of \var{o1} and \var{o2} using a routine provided
+  by \var{o1}, if one exists, otherwise with a routine provided by
+  \var{o2}.  The result of the comparison is returned in
+  \var{result}.  Returns \code{-1} on failure.  This is the equivalent
+  of the Python statement\bifuncindex{cmp} \samp{\var{result} =
+  cmp(\var{o1}, \var{o2})}.
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{int}{PyObject_Compare}{PyObject *o1, PyObject *o2}
+  Compare the values of \var{o1} and \var{o2} using a routine provided
+  by \var{o1}, if one exists, otherwise with a routine provided by
+  \var{o2}.  Returns the result of the comparison on success.  On
+  error, the value returned is undefined; use
+  \cfunction{PyErr_Occurred()} to detect an error.  This is equivalent
+  to the Python expression\bifuncindex{cmp} \samp{cmp(\var{o1},
+  \var{o2})}.
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{PyObject*}{PyObject_Repr}{PyObject *o}
+  Compute a string representation of object \var{o}.  Returns the
+  string representation on success, \NULL{} on failure.  This is the
+  equivalent of the Python expression \samp{repr(\var{o})}.  Called by
+  the \function{repr()}\bifuncindex{repr} built-in function and by
+  reverse quotes.
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{PyObject*}{PyObject_Str}{PyObject *o}
+  Compute a string representation of object \var{o}.  Returns the
+  string representation on success, \NULL{} on failure.  This is the
+  equivalent of the Python expression \samp{str(\var{o})}.  Called by
+  the \function{str()}\bifuncindex{str} built-in function and by the
+  \keyword{print} statement.
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{PyObject*}{PyObject_Unicode}{PyObject *o}
+  Compute a Unicode string representation of object \var{o}.  Returns
+  the Unicode string representation on success, \NULL{} on failure.
+  This is the equivalent of the Python expression
+  \samp{unicode(\var{o})}.  Called by the
+  \function{unicode()}\bifuncindex{unicode} built-in function.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyObject_IsInstance}{PyObject *inst, PyObject *cls}
+  Returns \code{1} if \var{inst} is an instance of the class \var{cls}
+  or a subclass of \var{cls}, or \code{0} if not.  On error, returns
+  \code{-1} and sets an exception.  If \var{cls} is a type object
+  rather than a class object, \cfunction{PyObject_IsInstance()}
+  returns \code{1} if \var{inst} is of type \var{cls}.  If \var{cls}
+  is a tuple, the check will be done against every entry in \var{cls}.
+  The result will be \code{1} when at least one of the checks returns
+  \code{1}, otherwise it will be \code{0}. If \var{inst} is not a class
+  instance and \var{cls} is neither a type object, nor a class object,
+  nor a tuple, \var{inst} must have a \member{__class__} attribute
+  --- the class relationship of the value of that attribute with
+  \var{cls} will be used to determine the result of this function.
+  \versionadded{2.1}
+  \versionchanged[Support for a tuple as the second argument added]{2.2}
+\end{cfuncdesc}
+
+Subclass determination is done in a fairly straightforward way, but
+includes a wrinkle that implementors of extensions to the class system
+may want to be aware of.  If \class{A} and \class{B} are class
+objects, \class{B} is a subclass of \class{A} if it inherits from
+\class{A} either directly or indirectly.  If either is not a class
+object, a more general mechanism is used to determine the class
+relationship of the two objects.  When testing if \var{B} is a
+subclass of \var{A}, if \var{A} is \var{B},
+\cfunction{PyObject_IsSubclass()} returns true.  If \var{A} and
+\var{B} are different objects, \var{B}'s \member{__bases__} attribute
+is searched in a depth-first fashion for \var{A} --- the presence of
+the \member{__bases__} attribute is considered sufficient for this
+determination.
+
+\begin{cfuncdesc}{int}{PyObject_IsSubclass}{PyObject *derived,
+                                            PyObject *cls}
+  Returns \code{1} if the class \var{derived} is identical to or
+  derived from the class \var{cls}, otherwise returns \code{0}.  In
+  case of an error, returns \code{-1}. If \var{cls}
+  is a tuple, the check will be done against every entry in \var{cls}.
+  The result will be \code{1} when at least one of the checks returns
+  \code{1}, otherwise it will be \code{0}. If either \var{derived} or
+  \var{cls} is not an actual class object (or tuple), this function
+  uses the generic algorithm described above.
+  \versionadded{2.1}
+  \versionchanged[Older versions of Python did not support a tuple
+                  as the second argument]{2.3}
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{int}{PyCallable_Check}{PyObject *o}
+  Determine if the object \var{o} is callable.  Return \code{1} if the
+  object is callable and \code{0} otherwise.  This function always
+  succeeds.
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{PyObject*}{PyObject_Call}{PyObject *callable_object,
+                                            PyObject *args,
+                                            PyObject *kw}
+  Call a callable Python object \var{callable_object}, with arguments
+  given by the tuple \var{args}, and named arguments given by the
+  dictionary \var{kw}. If no named arguments are needed, \var{kw} may
+  be \NULL{}. \var{args} must not be \NULL{}, use an empty tuple if
+  no arguments are needed. Returns the result of the call on success,
+  or \NULL{} on failure.  This is the equivalent of the Python
+  expression \samp{apply(\var{callable_object}, \var{args}, \var{kw})}
+  or \samp{\var{callable_object}(*\var{args}, **\var{kw})}.
+  \bifuncindex{apply}
+  \versionadded{2.2}
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{PyObject*}{PyObject_CallObject}{PyObject *callable_object,
+                                                  PyObject *args}
+  Call a callable Python object \var{callable_object}, with arguments
+  given by the tuple \var{args}.  If no arguments are needed, then
+  \var{args} may be \NULL.  Returns the result of the call on
+  success, or \NULL{} on failure.  This is the equivalent of the
+  Python expression \samp{apply(\var{callable_object}, \var{args})} or
+  \samp{\var{callable_object}(*\var{args})}.
+  \bifuncindex{apply}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyObject_CallFunction}{PyObject *callable,
+                                                    char *format, \moreargs}
+  Call a callable Python object \var{callable}, with a variable
+  number of C arguments.  The C arguments are described using a
+  \cfunction{Py_BuildValue()} style format string.  The format may be
+  \NULL, indicating that no arguments are provided.  Returns the
+  result of the call on success, or \NULL{} on failure.  This is the
+  equivalent of the Python expression \samp{apply(\var{callable},
+  \var{args})} or \samp{\var{callable}(*\var{args})}.
+  Note that if you only pass \ctype{PyObject *} args,
+  \cfunction{PyObject_CallFunctionObjArgs} is a faster alternative.
+  \bifuncindex{apply}
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{PyObject*}{PyObject_CallMethod}{PyObject *o,
+                                                  char *method, char *format,
+                                                  \moreargs}
+  Call the method named \var{method} of object \var{o} with a variable
+  number of C arguments.  The C arguments are described by a
+  \cfunction{Py_BuildValue()} format string that should 
+  produce a tuple.  The format may be \NULL,
+  indicating that no arguments are provided. Returns the result of the
+  call on success, or \NULL{} on failure.  This is the equivalent of
+  the Python expression \samp{\var{o}.\var{method}(\var{args})}.
+  Note that if you only pass \ctype{PyObject *} args,
+  \cfunction{PyObject_CallMethodObjArgs} is a faster alternative.
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{PyObject*}{PyObject_CallFunctionObjArgs}{PyObject *callable,
+                                                           \moreargs,
+                                                           \code{NULL}}
+  Call a callable Python object \var{callable}, with a variable
+  number of \ctype{PyObject*} arguments.  The arguments are provided
+  as a variable number of parameters followed by \NULL.
+  Returns the result of the call on success, or \NULL{} on failure.
+  \versionadded{2.2}
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{PyObject*}{PyObject_CallMethodObjArgs}{PyObject *o,
+                                                         PyObject *name,
+                                                         \moreargs,
+                                                         \code{NULL}}
+  Calls a method of the object \var{o}, where the name of the method
+  is given as a Python string object in \var{name}.  It is called with
+  a variable number of \ctype{PyObject*} arguments.  The arguments are
+  provided as a variable number of parameters followed by \NULL.
+  Returns the result of the call on success, or \NULL{} on failure.
+  \versionadded{2.2}
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{long}{PyObject_Hash}{PyObject *o}
+  Compute and return the hash value of an object \var{o}.  On failure,
+  return \code{-1}.  This is the equivalent of the Python expression
+  \samp{hash(\var{o})}.\bifuncindex{hash}
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{int}{PyObject_IsTrue}{PyObject *o}
+  Returns \code{1} if the object \var{o} is considered to be true, and
+  \code{0} otherwise.  This is equivalent to the Python expression
+  \samp{not not \var{o}}.  On failure, return \code{-1}. 
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{int}{PyObject_Not}{PyObject *o}
+  Returns \code{0} if the object \var{o} is considered to be true, and
+  \code{1} otherwise.  This is equivalent to the Python expression
+  \samp{not \var{o}}.  On failure, return \code{-1}. 
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{PyObject*}{PyObject_Type}{PyObject *o}
+  When \var{o} is non-\NULL, returns a type object corresponding to
+  the object type of object \var{o}. On failure, raises
+  \exception{SystemError} and returns \NULL.  This is equivalent to
+  the Python expression \code{type(\var{o})}.\bifuncindex{type}
+  This function increments the reference count of the return value.
+  There's really no reason to use this function instead of the
+  common expression \code{\var{o}->ob_type}, which returns a pointer
+  of type \ctype{PyTypeObject*}, except when the incremented reference
+  count is needed.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyObject_TypeCheck}{PyObject *o, PyTypeObject *type}
+  Return true if the object \var{o} is of type \var{type} or a subtype
+  of \var{type}.  Both parameters must be non-\NULL.
+  \versionadded{2.2}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{Py_ssize_t}{PyObject_Length}{PyObject *o}
+\cfuncline{Py_ssize_t}{PyObject_Size}{PyObject *o}
+  Return the length of object \var{o}.  If the object \var{o} provides
+  either the sequence and mapping protocols, the sequence length is
+  returned.  On error, \code{-1} is returned.  This is the equivalent
+  to the Python expression \samp{len(\var{o})}.\bifuncindex{len}
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{PyObject*}{PyObject_GetItem}{PyObject *o, PyObject *key}
+  Return element of \var{o} corresponding to the object \var{key} or
+  \NULL{} on failure.  This is the equivalent of the Python expression
+  \samp{\var{o}[\var{key}]}.
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{int}{PyObject_SetItem}{PyObject *o,
+                                         PyObject *key, PyObject *v}
+  Map the object \var{key} to the value \var{v}.  Returns \code{-1} on
+  failure.  This is the equivalent of the Python statement
+  \samp{\var{o}[\var{key}] = \var{v}}.
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{int}{PyObject_DelItem}{PyObject *o, PyObject *key}
+  Delete the mapping for \var{key} from \var{o}.  Returns \code{-1} on
+  failure. This is the equivalent of the Python statement \samp{del
+  \var{o}[\var{key}]}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyObject_AsFileDescriptor}{PyObject *o}
+  Derives a file-descriptor from a Python object.  If the object is an
+  integer or long integer, its value is returned.  If not, the
+  object's \method{fileno()} method is called if it exists; the method
+  must return an integer or long integer, which is returned as the
+  file descriptor value.  Returns \code{-1} on failure.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyObject_Dir}{PyObject *o}
+  This is equivalent to the Python expression \samp{dir(\var{o})},
+  returning a (possibly empty) list of strings appropriate for the
+  object argument, or \NULL{} if there was an error.  If the argument
+  is \NULL, this is like the Python \samp{dir()}, returning the names
+  of the current locals; in this case, if no execution frame is active
+  then \NULL{} is returned but \cfunction{PyErr_Occurred()} will
+  return false.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyObject_GetIter}{PyObject *o}
+  This is equivalent to the Python expression \samp{iter(\var{o})}.
+  It returns a new iterator for the object argument, or the object 
+  itself if the object is already an iterator.  Raises
+  \exception{TypeError} and returns \NULL{} if the object cannot be
+  iterated.
+\end{cfuncdesc}
+
+
+\section{Number Protocol \label{number}}
+
+\begin{cfuncdesc}{int}{PyNumber_Check}{PyObject *o}
+  Returns \code{1} if the object \var{o} provides numeric protocols,
+  and false otherwise.  This function always succeeds.
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{PyObject*}{PyNumber_Add}{PyObject *o1, PyObject *o2}
+  Returns the result of adding \var{o1} and \var{o2}, or \NULL{} on
+  failure.  This is the equivalent of the Python expression
+  \samp{\var{o1} + \var{o2}}.
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{PyObject*}{PyNumber_Subtract}{PyObject *o1, PyObject *o2}
+  Returns the result of subtracting \var{o2} from \var{o1}, or \NULL{}
+  on failure.  This is the equivalent of the Python expression
+  \samp{\var{o1} - \var{o2}}.
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{PyObject*}{PyNumber_Multiply}{PyObject *o1, PyObject *o2}
+  Returns the result of multiplying \var{o1} and \var{o2}, or \NULL{}
+  on failure.  This is the equivalent of the Python expression
+  \samp{\var{o1} * \var{o2}}.
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{PyObject*}{PyNumber_Divide}{PyObject *o1, PyObject *o2}
+  Returns the result of dividing \var{o1} by \var{o2}, or \NULL{} on
+  failure.  This is the equivalent of the Python expression
+  \samp{\var{o1} / \var{o2}}.
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{PyObject*}{PyNumber_FloorDivide}{PyObject *o1, PyObject *o2}
+  Return the floor of \var{o1} divided by \var{o2}, or \NULL{} on
+  failure.  This is equivalent to the ``classic'' division of
+  integers.
+  \versionadded{2.2}
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{PyObject*}{PyNumber_TrueDivide}{PyObject *o1, PyObject *o2}
+  Return a reasonable approximation for the mathematical value of
+  \var{o1} divided by \var{o2}, or \NULL{} on failure.  The return
+  value is ``approximate'' because binary floating point numbers are
+  approximate; it is not possible to represent all real numbers in
+  base two.  This function can return a floating point value when
+  passed two integers.
+  \versionadded{2.2}
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{PyObject*}{PyNumber_Remainder}{PyObject *o1, PyObject *o2}
+  Returns the remainder of dividing \var{o1} by \var{o2}, or \NULL{}
+  on failure.  This is the equivalent of the Python expression
+  \samp{\var{o1} \%\ \var{o2}}.
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{PyObject*}{PyNumber_Divmod}{PyObject *o1, PyObject *o2}
+  See the built-in function \function{divmod()}\bifuncindex{divmod}.
+  Returns \NULL{} on failure.  This is the equivalent of the Python
+  expression \samp{divmod(\var{o1}, \var{o2})}.
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{PyObject*}{PyNumber_Power}{PyObject *o1,
+                                             PyObject *o2, PyObject *o3}
+  See the built-in function \function{pow()}\bifuncindex{pow}.
+  Returns \NULL{} on failure.  This is the equivalent of the Python
+  expression \samp{pow(\var{o1}, \var{o2}, \var{o3})}, where \var{o3}
+  is optional.  If \var{o3} is to be ignored, pass \cdata{Py_None} in
+  its place (passing \NULL{} for \var{o3} would cause an illegal
+  memory access).
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{PyObject*}{PyNumber_Negative}{PyObject *o}
+  Returns the negation of \var{o} on success, or \NULL{} on failure.
+  This is the equivalent of the Python expression \samp{-\var{o}}.
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{PyObject*}{PyNumber_Positive}{PyObject *o}
+  Returns \var{o} on success, or \NULL{} on failure.  This is the
+  equivalent of the Python expression \samp{+\var{o}}.
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{PyObject*}{PyNumber_Absolute}{PyObject *o}
+  Returns the absolute value of \var{o}, or \NULL{} on failure.  This
+  is the equivalent of the Python expression \samp{abs(\var{o})}.
+  \bifuncindex{abs}
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{PyObject*}{PyNumber_Invert}{PyObject *o}
+  Returns the bitwise negation of \var{o} on success, or \NULL{} on
+  failure.  This is the equivalent of the Python expression
+  \samp{\~\var{o}}.
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{PyObject*}{PyNumber_Lshift}{PyObject *o1, PyObject *o2}
+  Returns the result of left shifting \var{o1} by \var{o2} on success,
+  or \NULL{} on failure.  This is the equivalent of the Python
+  expression \samp{\var{o1} <\code{<} \var{o2}}.
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{PyObject*}{PyNumber_Rshift}{PyObject *o1, PyObject *o2}
+  Returns the result of right shifting \var{o1} by \var{o2} on
+  success, or \NULL{} on failure.  This is the equivalent of the
+  Python expression \samp{\var{o1} >\code{>} \var{o2}}.
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{PyObject*}{PyNumber_And}{PyObject *o1, PyObject *o2}
+  Returns the ``bitwise and'' of \var{o1} and \var{o2} on success and
+  \NULL{} on failure. This is the equivalent of the Python expression
+  \samp{\var{o1} \&\ \var{o2}}.
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{PyObject*}{PyNumber_Xor}{PyObject *o1, PyObject *o2}
+  Returns the ``bitwise exclusive or'' of \var{o1} by \var{o2} on
+  success, or \NULL{} on failure.  This is the equivalent of the
+  Python expression \samp{\var{o1} \textasciicircum{} \var{o2}}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyNumber_Or}{PyObject *o1, PyObject *o2}
+  Returns the ``bitwise or'' of \var{o1} and \var{o2} on success, or
+  \NULL{} on failure.  This is the equivalent of the Python expression
+  \samp{\var{o1} | \var{o2}}.
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{PyObject*}{PyNumber_InPlaceAdd}{PyObject *o1, PyObject *o2}
+  Returns the result of adding \var{o1} and \var{o2}, or \NULL{} on
+  failure.  The operation is done \emph{in-place} when \var{o1}
+  supports it.  This is the equivalent of the Python statement
+  \samp{\var{o1} += \var{o2}}.
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{PyObject*}{PyNumber_InPlaceSubtract}{PyObject *o1,
+                                                       PyObject *o2}
+  Returns the result of subtracting \var{o2} from \var{o1}, or \NULL{}
+  on failure.  The operation is done \emph{in-place} when \var{o1}
+  supports it.  This is the equivalent of the Python statement
+  \samp{\var{o1} -= \var{o2}}.
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{PyObject*}{PyNumber_InPlaceMultiply}{PyObject *o1,
+                                                       PyObject *o2}
+  Returns the result of multiplying \var{o1} and \var{o2}, or \NULL{}
+  on failure.  The operation is done \emph{in-place} when \var{o1}
+  supports it.  This is the equivalent of the Python statement
+  \samp{\var{o1} *= \var{o2}}.
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{PyObject*}{PyNumber_InPlaceDivide}{PyObject *o1,
+                                                     PyObject *o2}
+  Returns the result of dividing \var{o1} by \var{o2}, or \NULL{} on
+  failure.  The operation is done \emph{in-place} when \var{o1}
+  supports it. This is the equivalent of the Python statement
+  \samp{\var{o1} /= \var{o2}}.
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{PyObject*}{PyNumber_InPlaceFloorDivide}{PyObject *o1,
+                                                          PyObject *o2}
+  Returns the mathematical floor of dividing \var{o1} by \var{o2}, or
+  \NULL{} on failure.  The operation is done \emph{in-place} when
+  \var{o1} supports it.  This is the equivalent of the Python
+  statement \samp{\var{o1} //= \var{o2}}.
+  \versionadded{2.2}
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{PyObject*}{PyNumber_InPlaceTrueDivide}{PyObject *o1,
+                                                         PyObject *o2}
+  Return a reasonable approximation for the mathematical value of
+  \var{o1} divided by \var{o2}, or \NULL{} on failure.  The return
+  value is ``approximate'' because binary floating point numbers are
+  approximate; it is not possible to represent all real numbers in
+  base two.  This function can return a floating point value when
+  passed two integers.  The operation is done \emph{in-place} when
+  \var{o1} supports it.
+  \versionadded{2.2}
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{PyObject*}{PyNumber_InPlaceRemainder}{PyObject *o1,
+                                                        PyObject *o2}
+  Returns the remainder of dividing \var{o1} by \var{o2}, or \NULL{}
+  on failure.  The operation is done \emph{in-place} when \var{o1}
+  supports it.  This is the equivalent of the Python statement
+  \samp{\var{o1} \%= \var{o2}}.
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{PyObject*}{PyNumber_InPlacePower}{PyObject *o1,
+                                                    PyObject *o2, PyObject *o3}
+  See the built-in function \function{pow()}.\bifuncindex{pow}
+  Returns \NULL{} on failure.  The operation is done \emph{in-place}
+  when \var{o1} supports it.  This is the equivalent of the Python
+  statement \samp{\var{o1} **= \var{o2}} when o3 is \cdata{Py_None},
+  or an in-place variant of \samp{pow(\var{o1}, \var{o2}, \var{o3})}
+  otherwise. If \var{o3} is to be ignored, pass \cdata{Py_None} in its
+  place (passing \NULL{} for \var{o3} would cause an illegal memory
+  access).
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyNumber_InPlaceLshift}{PyObject *o1,
+                                                     PyObject *o2}
+  Returns the result of left shifting \var{o1} by \var{o2} on success,
+  or \NULL{} on failure.  The operation is done \emph{in-place} when
+  \var{o1} supports it.  This is the equivalent of the Python
+  statement \samp{\var{o1} <\code{<=} \var{o2}}.
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{PyObject*}{PyNumber_InPlaceRshift}{PyObject *o1,
+                                                     PyObject *o2}
+  Returns the result of right shifting \var{o1} by \var{o2} on
+  success, or \NULL{} on failure.  The operation is done
+  \emph{in-place} when \var{o1} supports it.  This is the equivalent
+  of the Python statement \samp{\var{o1} >>= \var{o2}}.
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{PyObject*}{PyNumber_InPlaceAnd}{PyObject *o1, PyObject *o2}
+  Returns the ``bitwise and'' of \var{o1} and \var{o2} on success and
+  \NULL{} on failure. The operation is done \emph{in-place} when
+  \var{o1} supports it.  This is the equivalent of the Python
+  statement \samp{\var{o1} \&= \var{o2}}.
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{PyObject*}{PyNumber_InPlaceXor}{PyObject *o1, PyObject *o2}
+  Returns the ``bitwise exclusive or'' of \var{o1} by \var{o2} on
+  success, or \NULL{} on failure.  The operation is done
+  \emph{in-place} when \var{o1} supports it.  This is the equivalent
+  of the Python statement \samp{\var{o1} \textasciicircum= \var{o2}}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyNumber_InPlaceOr}{PyObject *o1, PyObject *o2}
+  Returns the ``bitwise or'' of \var{o1} and \var{o2} on success, or
+  \NULL{} on failure.  The operation is done \emph{in-place} when
+  \var{o1} supports it.  This is the equivalent of the Python
+  statement \samp{\var{o1} |= \var{o2}}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyNumber_Coerce}{PyObject **p1, PyObject **p2}
+  This function takes the addresses of two variables of type
+  \ctype{PyObject*}.  If the objects pointed to by \code{*\var{p1}}
+  and \code{*\var{p2}} have the same type, increment their reference
+  count and return \code{0} (success). If the objects can be converted
+  to a common numeric type, replace \code{*p1} and \code{*p2} by their
+  converted value (with 'new' reference counts), and return \code{0}.
+  If no conversion is possible, or if some other error occurs, return
+  \code{-1} (failure) and don't increment the reference counts.  The
+  call \code{PyNumber_Coerce(\&o1, \&o2)} is equivalent to the Python
+  statement \samp{\var{o1}, \var{o2} = coerce(\var{o1}, \var{o2})}.
+  \bifuncindex{coerce}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyNumber_Int}{PyObject *o}
+  Returns the \var{o} converted to an integer object on success, or
+  \NULL{} on failure.  If the argument is outside the integer range
+  a long object will be returned instead. This is the equivalent
+  of the Python expression \samp{int(\var{o})}.\bifuncindex{int}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyNumber_Long}{PyObject *o}
+  Returns the \var{o} converted to a long integer object on success,
+  or \NULL{} on failure.  This is the equivalent of the Python
+  expression \samp{long(\var{o})}.\bifuncindex{long}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyNumber_Float}{PyObject *o}
+  Returns the \var{o} converted to a float object on success, or
+  \NULL{} on failure.  This is the equivalent of the Python expression
+  \samp{float(\var{o})}.\bifuncindex{float}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyNumber_Index}{PyObject *o}
+  Returns the \var{o} converted to a Python int or long on success or \NULL{}
+  with a TypeError exception raised on failure.
+  \versionadded{2.5}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{Py_ssize_t}{PyNumber_AsSsize_t}{PyObject *o, PyObject *exc}
+  Returns \var{o} converted to a Py_ssize_t value if \var{o}
+  can be interpreted as an integer. If \var{o} can be converted to a Python
+  int or long but the attempt to convert to a Py_ssize_t value
+  would raise an \exception{OverflowError}, then the \var{exc} argument
+  is the type of exception that will be raised (usually \exception{IndexError}
+  or \exception{OverflowError}).  If \var{exc} is \NULL{}, then the exception
+  is cleared and the value is clipped to \var{PY_SSIZE_T_MIN}
+  for a negative integer or \var{PY_SSIZE_T_MAX} for a positive integer.
+  \versionadded{2.5}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyIndex_Check}{PyObject *o}
+  Returns True if \var{o} is an index integer (has the nb_index slot of 
+  the tp_as_number structure filled in).  
+  \versionadded{2.5}
+\end{cfuncdesc}
+
+
+\section{Sequence Protocol \label{sequence}}
+
+\begin{cfuncdesc}{int}{PySequence_Check}{PyObject *o}
+  Return \code{1} if the object provides sequence protocol, and
+  \code{0} otherwise.  This function always succeeds.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{Py_ssize_t}{PySequence_Size}{PyObject *o}
+  Returns the number of objects in sequence \var{o} on success, and
+  \code{-1} on failure.  For objects that do not provide sequence
+  protocol, this is equivalent to the Python expression
+  \samp{len(\var{o})}.\bifuncindex{len}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{Py_ssize_t}{PySequence_Length}{PyObject *o}
+  Alternate name for \cfunction{PySequence_Size()}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PySequence_Concat}{PyObject *o1, PyObject *o2}
+  Return the concatenation of \var{o1} and \var{o2} on success, and
+  \NULL{} on failure.   This is the equivalent of the Python
+  expression \samp{\var{o1} + \var{o2}}.
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{PyObject*}{PySequence_Repeat}{PyObject *o, Py_ssize_t count}
+  Return the result of repeating sequence object \var{o} \var{count}
+  times, or \NULL{} on failure.  This is the equivalent of the Python
+  expression \samp{\var{o} * \var{count}}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PySequence_InPlaceConcat}{PyObject *o1,
+                                                       PyObject *o2}
+  Return the concatenation of \var{o1} and \var{o2} on success, and
+  \NULL{} on failure.  The operation is done \emph{in-place} when
+  \var{o1} supports it.  This is the equivalent of the Python
+  expression \samp{\var{o1} += \var{o2}}.
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{PyObject*}{PySequence_InPlaceRepeat}{PyObject *o, Py_ssize_t count}
+  Return the result of repeating sequence object \var{o} \var{count}
+  times, or \NULL{} on failure.  The operation is done \emph{in-place}
+  when \var{o} supports it.  This is the equivalent of the Python
+  expression \samp{\var{o} *= \var{count}}.
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{PyObject*}{PySequence_GetItem}{PyObject *o, Py_ssize_t i}
+  Return the \var{i}th element of \var{o}, or \NULL{} on failure.
+  This is the equivalent of the Python expression
+  \samp{\var{o}[\var{i}]}.
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{PyObject*}{PySequence_GetSlice}{PyObject *o, Py_ssize_t i1, Py_ssize_t i2}
+  Return the slice of sequence object \var{o} between \var{i1} and
+  \var{i2}, or \NULL{} on failure. This is the equivalent of the
+  Python expression \samp{\var{o}[\var{i1}:\var{i2}]}.
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{int}{PySequence_SetItem}{PyObject *o, Py_ssize_t i, PyObject *v}
+  Assign object \var{v} to the \var{i}th element of \var{o}.  Returns
+  \code{-1} on failure.  This is the equivalent of the Python
+  statement \samp{\var{o}[\var{i}] = \var{v}}.  This function \emph{does not}
+  steal a reference to \var{v}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PySequence_DelItem}{PyObject *o, Py_ssize_t i}
+  Delete the \var{i}th element of object \var{o}.  Returns \code{-1}
+  on failure.  This is the equivalent of the Python statement
+  \samp{del \var{o}[\var{i}]}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PySequence_SetSlice}{PyObject *o, Py_ssize_t i1,
+                                            Py_ssize_t i2, PyObject *v}
+  Assign the sequence object \var{v} to the slice in sequence object
+  \var{o} from \var{i1} to \var{i2}.  This is the equivalent of the
+  Python statement \samp{\var{o}[\var{i1}:\var{i2}] = \var{v}}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PySequence_DelSlice}{PyObject *o, Py_ssize_t i1, Py_ssize_t i2}
+  Delete the slice in sequence object \var{o} from \var{i1} to
+  \var{i2}.  Returns \code{-1} on failure.  This is the equivalent of
+  the Python statement \samp{del \var{o}[\var{i1}:\var{i2}]}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{Py_ssize_t}{PySequence_Count}{PyObject *o, PyObject *value}
+  Return the number of occurrences of \var{value} in \var{o}, that is,
+  return the number of keys for which \code{\var{o}[\var{key}] ==
+  \var{value}}.  On failure, return \code{-1}.  This is equivalent to
+  the Python expression \samp{\var{o}.count(\var{value})}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PySequence_Contains}{PyObject *o, PyObject *value}
+  Determine if \var{o} contains \var{value}.  If an item in \var{o} is
+  equal to \var{value}, return \code{1}, otherwise return \code{0}.
+  On error, return \code{-1}.  This is equivalent to the Python
+  expression \samp{\var{value} in \var{o}}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{Py_ssize_t}{PySequence_Index}{PyObject *o, PyObject *value}
+  Return the first index \var{i} for which \code{\var{o}[\var{i}] ==
+  \var{value}}.  On error, return \code{-1}.    This is equivalent to
+  the Python expression \samp{\var{o}.index(\var{value})}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PySequence_List}{PyObject *o}
+  Return a list object with the same contents as the arbitrary
+  sequence \var{o}.  The returned list is guaranteed to be new.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PySequence_Tuple}{PyObject *o}
+  Return a tuple object with the same contents as the arbitrary
+  sequence \var{o} or \NULL{} on failure.  If \var{o} is a tuple,
+  a new reference will be returned, otherwise a tuple will be
+  constructed with the appropriate contents.  This is equivalent
+  to the Python expression \samp{tuple(\var{o})}.
+  \bifuncindex{tuple}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PySequence_Fast}{PyObject *o, const char *m}
+  Returns the sequence \var{o} as a tuple, unless it is already a
+  tuple or list, in which case \var{o} is returned.  Use
+  \cfunction{PySequence_Fast_GET_ITEM()} to access the members of the
+  result.  Returns \NULL{} on failure.  If the object is not a
+  sequence, raises \exception{TypeError} with \var{m} as the message
+  text.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PySequence_Fast_GET_ITEM}{PyObject *o, Py_ssize_t i}
+  Return the \var{i}th element of \var{o}, assuming that \var{o} was
+  returned by \cfunction{PySequence_Fast()}, \var{o} is not \NULL,
+  and that \var{i} is within bounds.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject**}{PySequence_Fast_ITEMS}{PyObject *o}
+  Return the underlying array of PyObject pointers.  Assumes that
+  \var{o} was returned by \cfunction{PySequence_Fast()} and
+  \var{o} is not \NULL.
+  \versionadded{2.4}  
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PySequence_ITEM}{PyObject *o, Py_ssize_t i}
+  Return the \var{i}th element of \var{o} or \NULL{} on failure.
+  Macro form of \cfunction{PySequence_GetItem()} but without checking
+  that \cfunction{PySequence_Check(\var{o})} is true and without
+  adjustment for negative indices.
+  \versionadded{2.3}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{Py_ssize_t}{PySequence_Fast_GET_SIZE}{PyObject *o}
+  Returns the length of \var{o}, assuming that \var{o} was
+  returned by \cfunction{PySequence_Fast()} and that \var{o} is
+  not \NULL.  The size can also be gotten by calling
+  \cfunction{PySequence_Size()} on \var{o}, but
+  \cfunction{PySequence_Fast_GET_SIZE()} is faster because it can
+  assume \var{o} is a list or tuple.
+\end{cfuncdesc}
+
+
+\section{Mapping Protocol \label{mapping}}
+
+\begin{cfuncdesc}{int}{PyMapping_Check}{PyObject *o}
+  Return \code{1} if the object provides mapping protocol, and
+  \code{0} otherwise.  This function always succeeds.
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{Py_ssize_t}{PyMapping_Length}{PyObject *o}
+  Returns the number of keys in object \var{o} on success, and
+  \code{-1} on failure.  For objects that do not provide mapping
+  protocol, this is equivalent to the Python expression
+  \samp{len(\var{o})}.\bifuncindex{len}
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{int}{PyMapping_DelItemString}{PyObject *o, char *key}
+  Remove the mapping for object \var{key} from the object \var{o}.
+  Return \code{-1} on failure.  This is equivalent to the Python
+  statement \samp{del \var{o}[\var{key}]}.
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{int}{PyMapping_DelItem}{PyObject *o, PyObject *key}
+  Remove the mapping for object \var{key} from the object \var{o}.
+  Return \code{-1} on failure.  This is equivalent to the Python
+  statement \samp{del \var{o}[\var{key}]}.
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{int}{PyMapping_HasKeyString}{PyObject *o, char *key}
+  On success, return \code{1} if the mapping object has the key
+  \var{key} and \code{0} otherwise.  This is equivalent to the Python
+  expression \samp{\var{o}.has_key(\var{key})}.  This function always
+  succeeds.
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{int}{PyMapping_HasKey}{PyObject *o, PyObject *key}
+  Return \code{1} if the mapping object has the key \var{key} and
+  \code{0} otherwise.  This is equivalent to the Python expression
+  \samp{\var{o}.has_key(\var{key})}.  This function always succeeds.
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{PyObject*}{PyMapping_Keys}{PyObject *o}
+  On success, return a list of the keys in object \var{o}.  On
+  failure, return \NULL. This is equivalent to the Python expression
+  \samp{\var{o}.keys()}.
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{PyObject*}{PyMapping_Values}{PyObject *o}
+  On success, return a list of the values in object \var{o}.  On
+  failure, return \NULL. This is equivalent to the Python expression
+  \samp{\var{o}.values()}.
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{PyObject*}{PyMapping_Items}{PyObject *o}
+  On success, return a list of the items in object \var{o}, where each
+  item is a tuple containing a key-value pair.  On failure, return
+  \NULL. This is equivalent to the Python expression
+  \samp{\var{o}.items()}.
+\end{cfuncdesc}
+
+
+\begin{cfuncdesc}{PyObject*}{PyMapping_GetItemString}{PyObject *o, char *key}
+  Return element of \var{o} corresponding to the object \var{key} or
+  \NULL{} on failure. This is the equivalent of the Python expression
+  \samp{\var{o}[\var{key}]}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyMapping_SetItemString}{PyObject *o, char *key,
+                                                PyObject *v}
+  Map the object \var{key} to the value \var{v} in object \var{o}.
+  Returns \code{-1} on failure.  This is the equivalent of the Python
+  statement \samp{\var{o}[\var{key}] = \var{v}}.
+\end{cfuncdesc}
+
+
+\section{Iterator Protocol \label{iterator}}
+
+\versionadded{2.2}
+
+There are only a couple of functions specifically for working with
+iterators.
+
+\begin{cfuncdesc}{int}{PyIter_Check}{PyObject *o}
+  Return true if the object \var{o} supports the iterator protocol.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyIter_Next}{PyObject *o}
+  Return the next value from the iteration \var{o}.  If the object is
+  an iterator, this retrieves the next value from the iteration, and
+  returns \NULL{} with no exception set if there are no remaining
+  items.  If the object is not an iterator, \exception{TypeError} is
+  raised, or if there is an error in retrieving the item, returns
+  \NULL{} and passes along the exception.
+\end{cfuncdesc}
+
+To write a loop which iterates over an iterator, the C code should
+look something like this:
+
+\begin{verbatim}
+PyObject *iterator = PyObject_GetIter(obj);
+PyObject *item;
+
+if (iterator == NULL) {
+    /* propagate error */
+}
+
+while (item = PyIter_Next(iterator)) {
+    /* do something with item */
+    ...
+    /* release reference when done */
+    Py_DECREF(item);
+}
+
+Py_DECREF(iterator);
+
+if (PyErr_Occurred()) {
+    /* propagate error */
+}
+else {
+    /* continue doing useful work */
+}
+\end{verbatim}
+
+
+\section{Buffer Protocol \label{abstract-buffer}}
+
+\begin{cfuncdesc}{int}{PyObject_AsCharBuffer}{PyObject *obj,
+                                              const char **buffer,
+                                              Py_ssize_t *buffer_len}
+  Returns a pointer to a read-only memory location useable as character-
+  based input.  The \var{obj} argument must support the single-segment
+  character buffer interface.  On success, returns \code{0}, sets
+  \var{buffer} to the memory location and \var{buffer_len} to the buffer
+  length.  Returns \code{-1} and sets a \exception{TypeError} on error.
+  \versionadded{1.6}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyObject_AsReadBuffer}{PyObject *obj,
+                                              const void **buffer,
+                                              Py_ssize_t *buffer_len}
+  Returns a pointer to a read-only memory location containing
+  arbitrary data.  The \var{obj} argument must support the
+  single-segment readable buffer interface.  On success, returns
+  \code{0}, sets \var{buffer} to the memory location and \var{buffer_len}
+  to the buffer length.  Returns \code{-1} and sets a
+  \exception{TypeError} on error.
+  \versionadded{1.6}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyObject_CheckReadBuffer}{PyObject *o}
+  Returns \code{1} if \var{o} supports the single-segment readable
+  buffer interface.  Otherwise returns \code{0}.
+  \versionadded{2.2}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyObject_AsWriteBuffer}{PyObject *obj,
+                                               void **buffer,
+                                               Py_ssize_t *buffer_len}
+  Returns a pointer to a writeable memory location.  The \var{obj}
+  argument must support the single-segment, character buffer
+  interface.  On success, returns \code{0}, sets \var{buffer} to the
+  memory location and \var{buffer_len} to the buffer length.  Returns
+  \code{-1} and sets a \exception{TypeError} on error.
+  \versionadded{1.6}
+\end{cfuncdesc}

Added: vendor/Python/current/Doc/api/api.tex
===================================================================
--- vendor/Python/current/Doc/api/api.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/api/api.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,60 @@
+\documentclass{manual}
+
+\title{Python/C API Reference Manual}
+
+\input{boilerplate}
+
+\makeindex			% tell \index to actually write the .idx file
+
+
+\begin{document}
+
+\maketitle
+
+\ifhtml
+\chapter*{Front Matter\label{front}}
+\fi
+
+\input{copyright}
+
+\begin{abstract}
+
+\noindent
+This manual documents the API used by C and \Cpp{} programmers who
+want to write extension modules or embed Python.  It is a companion to
+\citetitle[../ext/ext.html]{Extending and Embedding the Python
+Interpreter}, which describes the general principles of extension
+writing but does not document the API functions in detail.
+
+\warning{The current version of this document is incomplete.  I hope
+that it is nevertheless useful.  I will continue to work on it, and
+release new versions from time to time, independent from Python source
+code releases.}
+
+\end{abstract}
+
+\tableofcontents
+
+
+\input{intro}
+\input{veryhigh}
+\input{refcounting}
+\input{exceptions}
+\input{utilities}
+\input{abstract}
+\input{concrete}
+\input{init}
+\input{memory}
+\input{newtypes}
+
+
+\appendix
+\chapter{Reporting Bugs}
+\input{reportingbugs}
+
+\chapter{History and License}
+\input{license}
+
+\input{api.ind}			% Index -- must be last
+
+\end{document}

Added: vendor/Python/current/Doc/api/concrete.tex
===================================================================
--- vendor/Python/current/Doc/api/concrete.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/api/concrete.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,3203 @@
+\chapter{Concrete Objects Layer \label{concrete}}
+
+
+The functions in this chapter are specific to certain Python object
+types.  Passing them an object of the wrong type is not a good idea;
+if you receive an object from a Python program and you are not sure
+that it has the right type, you must perform a type check first;
+for example, to check that an object is a dictionary, use
+\cfunction{PyDict_Check()}.  The chapter is structured like the
+``family tree'' of Python object types.
+
+\warning{While the functions described in this chapter carefully check
+the type of the objects which are passed in, many of them do not check
+for \NULL{} being passed instead of a valid object.  Allowing \NULL{}
+to be passed in can cause memory access violations and immediate
+termination of the interpreter.}
+
+
+\section{Fundamental Objects \label{fundamental}}
+
+This section describes Python type objects and the singleton object
+\code{None}.
+
+
+\subsection{Type Objects \label{typeObjects}}
+
+\obindex{type}
+\begin{ctypedesc}{PyTypeObject}
+  The C structure of the objects used to describe built-in types.
+\end{ctypedesc}
+
+\begin{cvardesc}{PyObject*}{PyType_Type}
+  This is the type object for type objects; it is the same object as
+  \code{type} and \code{types.TypeType} in the Python layer.
+  \withsubitem{(in module types)}{\ttindex{TypeType}}
+\end{cvardesc}
+
+\begin{cfuncdesc}{int}{PyType_Check}{PyObject *o}
+  Return true if the object \var{o} is a type object, including
+  instances of types derived from the standard type object.  Return
+  false in all other cases.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyType_CheckExact}{PyObject *o}
+  Return true if the object \var{o} is a type object, but not a
+  subtype of the standard type object.  Return false in all other
+  cases.
+  \versionadded{2.2}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyType_HasFeature}{PyObject *o, int feature}
+  Return true if the type object \var{o} sets the feature
+  \var{feature}.  Type features are denoted by single bit flags.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyType_IS_GC}{PyObject *o}
+  Return true if the type object includes support for the cycle
+  detector; this tests the type flag \constant{Py_TPFLAGS_HAVE_GC}.
+  \versionadded{2.0}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyType_IsSubtype}{PyTypeObject *a, PyTypeObject *b}
+  Return true if \var{a} is a subtype of \var{b}.
+  \versionadded{2.2}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyType_GenericAlloc}{PyTypeObject *type,
+                                                  Py_ssize_t nitems}
+  \versionadded{2.2}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyType_GenericNew}{PyTypeObject *type,
+                                            PyObject *args, PyObject *kwds}
+  \versionadded{2.2}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyType_Ready}{PyTypeObject *type}
+  Finalize a type object.  This should be called on all type objects
+  to finish their initialization.  This function is responsible for
+  adding inherited slots from a type's base class.  Return \code{0}
+  on success, or return \code{-1} and sets an exception on error.
+  \versionadded{2.2}
+\end{cfuncdesc}
+
+
+\subsection{The None Object \label{noneObject}}
+
+\obindex{None}
+Note that the \ctype{PyTypeObject} for \code{None} is not directly
+exposed in the Python/C API.  Since \code{None} is a singleton,
+testing for object identity (using \samp{==} in C) is sufficient.
+There is no \cfunction{PyNone_Check()} function for the same reason.
+
+\begin{cvardesc}{PyObject*}{Py_None}
+  The Python \code{None} object, denoting lack of value.  This object
+  has no methods.  It needs to be treated just like any other object
+  with respect to reference counts.
+\end{cvardesc}
+
+\begin{csimplemacrodesc}{Py_RETURN_NONE}
+  Properly handle returning \cdata{Py_None} from within a C function.
+\end{csimplemacrodesc}
+
+
+\section{Numeric Objects \label{numericObjects}}
+
+\obindex{numeric}
+
+
+\subsection{Plain Integer Objects \label{intObjects}}
+
+\obindex{integer}
+\begin{ctypedesc}{PyIntObject}
+  This subtype of \ctype{PyObject} represents a Python integer
+  object.
+\end{ctypedesc}
+
+\begin{cvardesc}{PyTypeObject}{PyInt_Type}
+  This instance of \ctype{PyTypeObject} represents the Python plain
+  integer type.  This is the same object as \code{int} and
+  \code{types.IntType}.
+  \withsubitem{(in modules types)}{\ttindex{IntType}}
+\end{cvardesc}
+
+\begin{cfuncdesc}{int}{PyInt_Check}{PyObject *o}
+  Return true if \var{o} is of type \cdata{PyInt_Type} or a subtype
+  of \cdata{PyInt_Type}.
+  \versionchanged[Allowed subtypes to be accepted]{2.2}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyInt_CheckExact}{PyObject *o}
+  Return true if \var{o} is of type \cdata{PyInt_Type}, but not a
+  subtype of \cdata{PyInt_Type}.
+  \versionadded{2.2}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyInt_FromString}{char *str, char **pend,
+                                               int base}
+  Return a new \ctype{PyIntObject} or \ctype{PyLongObject} based on the
+  string value in \var{str}, which is interpreted according to the radix in
+  \var{base}.  If \var{pend} is non-\NULL{}, \code{*\var{pend}} will point to
+  the first character in \var{str} which follows the representation of the
+  number.  If \var{base} is \code{0}, the radix will be determined based on
+  the leading characters of \var{str}: if \var{str} starts with \code{'0x'}
+  or \code{'0X'}, radix 16 will be used; if \var{str} starts with
+  \code{'0'}, radix 8 will be used; otherwise radix 10 will be used.  If
+  \var{base} is not \code{0}, it must be between \code{2} and \code{36},
+  inclusive.  Leading spaces are ignored.  If there are no digits,
+  \exception{ValueError} will be raised.  If the string represents a number
+  too large to be contained within the machine's \ctype{long int} type and
+  overflow warnings are being suppressed, a \ctype{PyLongObject} will be
+  returned.  If overflow warnings are not being suppressed, \NULL{} will be
+  returned in this case.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyInt_FromLong}{long ival}
+  Create a new integer object with a value of \var{ival}.
+
+  The current implementation keeps an array of integer objects for all
+  integers between \code{-5} and \code{256}, when you create an int in
+  that range you actually just get back a reference to the existing
+  object. So it should be possible to change the value of \code{1}.  I
+  suspect the behaviour of Python in this case is undefined. :-)
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyInt_FromSsize_t}{Py_ssize_t ival}
+  Create a new integer object with a value of \var{ival}.
+  If the value exceeds \code{LONG_MAX}, a long integer object is
+  returned.
+
+ \versionadded{2.5}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{long}{PyInt_AsLong}{PyObject *io}
+  Will first attempt to cast the object to a \ctype{PyIntObject}, if
+  it is not already one, and then return its value. If there is an
+  error, \code{-1} is returned, and the caller should check
+  \code{PyErr_Occurred()} to find out whether there was an error, or
+  whether the value just happened to be -1.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{long}{PyInt_AS_LONG}{PyObject *io}
+  Return the value of the object \var{io}.  No error checking is
+  performed.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{unsigned long}{PyInt_AsUnsignedLongMask}{PyObject *io}
+  Will first attempt to cast the object to a \ctype{PyIntObject} or
+  \ctype{PyLongObject}, if it is not already one, and then return its
+  value as unsigned long.  This function does not check for overflow.
+  \versionadded{2.3}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{unsigned PY_LONG_LONG}{PyInt_AsUnsignedLongLongMask}{PyObject *io}
+  Will first attempt to cast the object to a \ctype{PyIntObject} or
+  \ctype{PyLongObject}, if it is not already one, and then return its
+  value as unsigned long long, without checking for overflow.
+  \versionadded{2.3}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{Py_ssize_t}{PyInt_AsSsize_t}{PyObject *io}
+  Will first attempt to cast the object to a \ctype{PyIntObject} or
+  \ctype{PyLongObject}, if it is not already one, and then return its
+  value as \ctype{Py_ssize_t}.
+  \versionadded{2.5}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{long}{PyInt_GetMax}{}
+  Return the system's idea of the largest integer it can handle
+  (\constant{LONG_MAX}\ttindex{LONG_MAX}, as defined in the system
+  header files).
+\end{cfuncdesc}
+
+\subsection{Boolean Objects \label{boolObjects}}
+
+Booleans in Python are implemented as a subclass of integers.  There
+are only two booleans, \constant{Py_False} and \constant{Py_True}.  As
+such, the normal creation and deletion functions don't apply to
+booleans.  The following macros are available, however.
+
+\begin{cfuncdesc}{int}{PyBool_Check}{PyObject *o}
+  Return true if \var{o} is of type \cdata{PyBool_Type}.
+  \versionadded{2.3}
+\end{cfuncdesc}
+
+\begin{cvardesc}{PyObject*}{Py_False}
+  The Python \code{False} object.  This object has no methods.  It needs to
+  be treated just like any other object with respect to reference counts.
+\end{cvardesc}
+
+\begin{cvardesc}{PyObject*}{Py_True}
+  The Python \code{True} object.  This object has no methods.  It needs to
+  be treated just like any other object with respect to reference counts.
+\end{cvardesc}
+
+\begin{csimplemacrodesc}{Py_RETURN_FALSE}
+  Return \constant{Py_False} from a function, properly incrementing its
+  reference count.
+\versionadded{2.4}
+\end{csimplemacrodesc}
+
+\begin{csimplemacrodesc}{Py_RETURN_TRUE}
+  Return \constant{Py_True} from a function, properly incrementing its
+  reference count.
+\versionadded{2.4}
+\end{csimplemacrodesc}
+
+\begin{cfuncdesc}{PyObject*}{PyBool_FromLong}{long v}
+  Return a new reference to \constant{Py_True} or \constant{Py_False}
+  depending on the truth value of \var{v}.
+\versionadded{2.3}
+\end{cfuncdesc}
+
+\subsection{Long Integer Objects \label{longObjects}}
+
+\obindex{long integer}
+\begin{ctypedesc}{PyLongObject}
+  This subtype of \ctype{PyObject} represents a Python long integer
+  object.
+\end{ctypedesc}
+
+\begin{cvardesc}{PyTypeObject}{PyLong_Type}
+  This instance of \ctype{PyTypeObject} represents the Python long
+  integer type.  This is the same object as \code{long} and
+  \code{types.LongType}.
+  \withsubitem{(in modules types)}{\ttindex{LongType}}
+\end{cvardesc}
+
+\begin{cfuncdesc}{int}{PyLong_Check}{PyObject *p}
+  Return true if its argument is a \ctype{PyLongObject} or a subtype
+  of \ctype{PyLongObject}.
+  \versionchanged[Allowed subtypes to be accepted]{2.2}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyLong_CheckExact}{PyObject *p}
+  Return true if its argument is a \ctype{PyLongObject}, but not a
+  subtype of \ctype{PyLongObject}.
+  \versionadded{2.2}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyLong_FromLong}{long v}
+  Return a new \ctype{PyLongObject} object from \var{v}, or \NULL{}
+  on failure.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyLong_FromUnsignedLong}{unsigned long v}
+  Return a new \ctype{PyLongObject} object from a C \ctype{unsigned
+  long}, or \NULL{} on failure.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyLong_FromLongLong}{PY_LONG_LONG v}
+  Return a new \ctype{PyLongObject} object from a C \ctype{long long},
+  or \NULL{} on failure.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyLong_FromUnsignedLongLong}{unsigned PY_LONG_LONG v}
+  Return a new \ctype{PyLongObject} object from a C \ctype{unsigned
+  long long}, or \NULL{} on failure.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyLong_FromDouble}{double v}
+  Return a new \ctype{PyLongObject} object from the integer part of
+  \var{v}, or \NULL{} on failure.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyLong_FromString}{char *str, char **pend,
+                                                int base}
+  Return a new \ctype{PyLongObject} based on the string value in
+  \var{str}, which is interpreted according to the radix in
+  \var{base}.  If \var{pend} is non-\NULL{}, \code{*\var{pend}} will
+  point to the first character in \var{str} which follows the
+  representation of the number.  If \var{base} is \code{0}, the radix
+  will be determined based on the leading characters of \var{str}: if
+  \var{str} starts with \code{'0x'} or \code{'0X'}, radix 16 will be
+  used; if \var{str} starts with \code{'0'}, radix 8 will be used;
+  otherwise radix 10 will be used.  If \var{base} is not \code{0}, it
+  must be between \code{2} and \code{36}, inclusive.  Leading spaces
+  are ignored.  If there are no digits, \exception{ValueError} will be
+  raised.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyLong_FromUnicode}{Py_UNICODE *u,
+                                                 Py_ssize_t length, int base}
+  Convert a sequence of Unicode digits to a Python long integer
+  value.  The first parameter, \var{u}, points to the first character
+  of the Unicode string, \var{length} gives the number of characters,
+  and \var{base} is the radix for the conversion.  The radix must be
+  in the range [2, 36]; if it is out of range, \exception{ValueError}
+  will be raised.
+  \versionadded{1.6}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyLong_FromVoidPtr}{void *p}
+  Create a Python integer or long integer from the pointer \var{p}.
+  The pointer value can be retrieved from the resulting value using
+  \cfunction{PyLong_AsVoidPtr()}.
+  \versionadded{1.5.2}
+  \versionchanged[If the integer is larger than LONG_MAX,
+  a positive long integer is returned]{2.5}
+ \end{cfuncdesc}
+
+\begin{cfuncdesc}{long}{PyLong_AsLong}{PyObject *pylong}
+  Return a C \ctype{long} representation of the contents of
+  \var{pylong}.  If \var{pylong} is greater than
+  \constant{LONG_MAX}\ttindex{LONG_MAX}, an \exception{OverflowError}
+  is raised.
+  \withsubitem{(built-in exception)}{\ttindex{OverflowError}}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{unsigned long}{PyLong_AsUnsignedLong}{PyObject *pylong}
+  Return a C \ctype{unsigned long} representation of the contents of
+  \var{pylong}.  If \var{pylong} is greater than
+  \constant{ULONG_MAX}\ttindex{ULONG_MAX}, an
+  \exception{OverflowError} is raised.
+  \withsubitem{(built-in exception)}{\ttindex{OverflowError}}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PY_LONG_LONG}{PyLong_AsLongLong}{PyObject *pylong}
+  Return a C \ctype{long long} from a Python long integer.  If
+  \var{pylong} cannot be represented as a \ctype{long long}, an
+  \exception{OverflowError} will be raised.
+  \versionadded{2.2}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{unsigned PY_LONG_LONG}{PyLong_AsUnsignedLongLong}{PyObject
+                                                                 *pylong}
+  Return a C \ctype{unsigned long long} from a Python long integer.
+  If \var{pylong} cannot be represented as an \ctype{unsigned long
+  long}, an \exception{OverflowError} will be raised if the value is
+  positive, or a \exception{TypeError} will be raised if the value is
+  negative.
+  \versionadded{2.2}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{unsigned long}{PyLong_AsUnsignedLongMask}{PyObject *io}
+  Return a C \ctype{unsigned long} from a Python long integer, without
+  checking for overflow.
+  \versionadded{2.3}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{unsigned PY_LONG_LONG}{PyLong_AsUnsignedLongLongMask}{PyObject *io}
+  Return a C \ctype{unsigned long long} from a Python long integer, without
+  checking for overflow.
+  \versionadded{2.3}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{double}{PyLong_AsDouble}{PyObject *pylong}
+  Return a C \ctype{double} representation of the contents of
+  \var{pylong}.  If \var{pylong} cannot be approximately represented
+  as a \ctype{double}, an \exception{OverflowError} exception is
+  raised and \code{-1.0} will be returned.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void*}{PyLong_AsVoidPtr}{PyObject *pylong}
+  Convert a Python integer or long integer \var{pylong} to a C
+  \ctype{void} pointer.  If \var{pylong} cannot be converted, an
+  \exception{OverflowError} will be raised.  This is only assured to
+  produce a usable \ctype{void} pointer for values created with
+  \cfunction{PyLong_FromVoidPtr()}.
+  \versionadded{1.5.2}
+  \versionchanged[For values outside 0..LONG_MAX, both signed and
+  unsigned integers are acccepted]{2.5}
+\end{cfuncdesc}
+
+
+\subsection{Floating Point Objects \label{floatObjects}}
+
+\obindex{floating point}
+\begin{ctypedesc}{PyFloatObject}
+  This subtype of \ctype{PyObject} represents a Python floating point
+  object.
+\end{ctypedesc}
+
+\begin{cvardesc}{PyTypeObject}{PyFloat_Type}
+  This instance of \ctype{PyTypeObject} represents the Python floating
+  point type.  This is the same object as \code{float} and
+  \code{types.FloatType}.
+  \withsubitem{(in modules types)}{\ttindex{FloatType}}
+\end{cvardesc}
+
+\begin{cfuncdesc}{int}{PyFloat_Check}{PyObject *p}
+  Return true if its argument is a \ctype{PyFloatObject} or a subtype
+  of \ctype{PyFloatObject}.
+  \versionchanged[Allowed subtypes to be accepted]{2.2}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyFloat_CheckExact}{PyObject *p}
+  Return true if its argument is a \ctype{PyFloatObject}, but not a
+  subtype of \ctype{PyFloatObject}.
+  \versionadded{2.2}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyFloat_FromString}{PyObject *str, char **pend}
+  Create a \ctype{PyFloatObject} object based on the string value in
+  \var{str}, or \NULL{} on failure.  The \var{pend} argument is ignored.  It
+  remains only for backward compatibility.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyFloat_FromDouble}{double v}
+  Create a \ctype{PyFloatObject} object from \var{v}, or \NULL{} on
+  failure.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{double}{PyFloat_AsDouble}{PyObject *pyfloat}
+  Return a C \ctype{double} representation of the contents of
+  \var{pyfloat}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{double}{PyFloat_AS_DOUBLE}{PyObject *pyfloat}
+  Return a C \ctype{double} representation of the contents of
+  \var{pyfloat}, but without error checking.
+\end{cfuncdesc}
+
+
+\subsection{Complex Number Objects \label{complexObjects}}
+
+\obindex{complex number}
+Python's complex number objects are implemented as two distinct types
+when viewed from the C API:  one is the Python object exposed to
+Python programs, and the other is a C structure which represents the
+actual complex number value.  The API provides functions for working
+with both.
+
+\subsubsection{Complex Numbers as C Structures}
+
+Note that the functions which accept these structures as parameters
+and return them as results do so \emph{by value} rather than
+dereferencing them through pointers.  This is consistent throughout
+the API.
+
+\begin{ctypedesc}{Py_complex}
+  The C structure which corresponds to the value portion of a Python
+  complex number object.  Most of the functions for dealing with
+  complex number objects use structures of this type as input or
+  output values, as appropriate.  It is defined as:
+
+\begin{verbatim}
+typedef struct {
+   double real;
+   double imag;
+} Py_complex;
+\end{verbatim}
+\end{ctypedesc}
+
+\begin{cfuncdesc}{Py_complex}{_Py_c_sum}{Py_complex left, Py_complex right}
+  Return the sum of two complex numbers, using the C
+  \ctype{Py_complex} representation.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{Py_complex}{_Py_c_diff}{Py_complex left, Py_complex right}
+  Return the difference between two complex numbers, using the C
+  \ctype{Py_complex} representation.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{Py_complex}{_Py_c_neg}{Py_complex complex}
+  Return the negation of the complex number \var{complex}, using the C
+  \ctype{Py_complex} representation.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{Py_complex}{_Py_c_prod}{Py_complex left, Py_complex right}
+  Return the product of two complex numbers, using the C
+  \ctype{Py_complex} representation.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{Py_complex}{_Py_c_quot}{Py_complex dividend,
+                                          Py_complex divisor}
+  Return the quotient of two complex numbers, using the C
+  \ctype{Py_complex} representation.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{Py_complex}{_Py_c_pow}{Py_complex num, Py_complex exp}
+  Return the exponentiation of \var{num} by \var{exp}, using the C
+  \ctype{Py_complex} representation.
+\end{cfuncdesc}
+
+
+\subsubsection{Complex Numbers as Python Objects}
+
+\begin{ctypedesc}{PyComplexObject}
+  This subtype of \ctype{PyObject} represents a Python complex number
+  object.
+\end{ctypedesc}
+
+\begin{cvardesc}{PyTypeObject}{PyComplex_Type}
+  This instance of \ctype{PyTypeObject} represents the Python complex
+  number type. It is the same object as \code{complex} and
+  \code{types.ComplexType}.
+\end{cvardesc}
+
+\begin{cfuncdesc}{int}{PyComplex_Check}{PyObject *p}
+  Return true if its argument is a \ctype{PyComplexObject} or a
+  subtype of \ctype{PyComplexObject}.
+  \versionchanged[Allowed subtypes to be accepted]{2.2}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyComplex_CheckExact}{PyObject *p}
+  Return true if its argument is a \ctype{PyComplexObject}, but not a
+  subtype of \ctype{PyComplexObject}.
+  \versionadded{2.2}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyComplex_FromCComplex}{Py_complex v}
+  Create a new Python complex number object from a C
+  \ctype{Py_complex} value.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyComplex_FromDoubles}{double real, double imag}
+  Return a new \ctype{PyComplexObject} object from \var{real} and
+  \var{imag}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{double}{PyComplex_RealAsDouble}{PyObject *op}
+  Return the real part of \var{op} as a C \ctype{double}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{double}{PyComplex_ImagAsDouble}{PyObject *op}
+  Return the imaginary part of \var{op} as a C \ctype{double}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{Py_complex}{PyComplex_AsCComplex}{PyObject *op}
+  Return the \ctype{Py_complex} value of the complex number
+  \var{op}.
+\end{cfuncdesc}
+
+
+
+\section{Sequence Objects \label{sequenceObjects}}
+
+\obindex{sequence}
+Generic operations on sequence objects were discussed in the previous
+chapter; this section deals with the specific kinds of sequence
+objects that are intrinsic to the Python language.
+
+
+\subsection{String Objects \label{stringObjects}}
+
+These functions raise \exception{TypeError} when expecting a string
+parameter and are called with a non-string parameter.
+
+\obindex{string}
+\begin{ctypedesc}{PyStringObject}
+  This subtype of \ctype{PyObject} represents a Python string object.
+\end{ctypedesc}
+
+\begin{cvardesc}{PyTypeObject}{PyString_Type}
+  This instance of \ctype{PyTypeObject} represents the Python string
+  type; it is the same object as \code{str} and \code{types.StringType}
+  in the Python layer.
+  \withsubitem{(in module types)}{\ttindex{StringType}}.
+\end{cvardesc}
+
+\begin{cfuncdesc}{int}{PyString_Check}{PyObject *o}
+  Return true if the object \var{o} is a string object or an instance
+  of a subtype of the string type.
+  \versionchanged[Allowed subtypes to be accepted]{2.2}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyString_CheckExact}{PyObject *o}
+  Return true if the object \var{o} is a string object, but not an
+  instance of a subtype of the string type.
+  \versionadded{2.2}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyString_FromString}{const char *v}
+  Return a new string object with a copy of the string \var{v} as value
+  on success, and \NULL{} on failure.  The parameter \var{v} must not be
+  \NULL{}; it will not be checked.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyString_FromStringAndSize}{const char *v,
+                                                         Py_ssize_t len}
+  Return a new string object with a copy of the string \var{v} as value
+  and length \var{len} on success, and \NULL{} on failure.  If \var{v} is
+  \NULL{}, the contents of the string are uninitialized.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyString_FromFormat}{const char *format, ...}
+  Take a C \cfunction{printf()}-style \var{format} string and a
+  variable number of arguments, calculate the size of the resulting
+  Python string and return a string with the values formatted into
+  it.  The variable arguments must be C types and must correspond
+  exactly to the format characters in the \var{format} string.  The
+  following format characters are allowed:
+
+  % This should be exactly the same as the table in PyErr_Format.
+  % One should just refer to the other.
+
+  % The descriptions for %zd and %zu are wrong, but the truth is complicated
+  % because not all compilers support the %z width modifier -- we fake it
+  % when necessary via interpolating PY_FORMAT_SIZE_T.
+
+  % %u, %lu, %zu should have "new in Python 2.5" blurbs.
+
+  \begin{tableiii}{l|l|l}{member}{Format Characters}{Type}{Comment}
+    \lineiii{\%\%}{\emph{n/a}}{The literal \% character.}
+    \lineiii{\%c}{int}{A single character, represented as an C int.}
+    \lineiii{\%d}{int}{Exactly equivalent to \code{printf("\%d")}.}
+    \lineiii{\%u}{unsigned int}{Exactly equivalent to \code{printf("\%u")}.}
+    \lineiii{\%ld}{long}{Exactly equivalent to \code{printf("\%ld")}.}
+    \lineiii{\%lu}{unsigned long}{Exactly equivalent to \code{printf("\%lu")}.}
+    \lineiii{\%zd}{Py_ssize_t}{Exactly equivalent to \code{printf("\%zd")}.}
+    \lineiii{\%zu}{size_t}{Exactly equivalent to \code{printf("\%zu")}.}
+    \lineiii{\%i}{int}{Exactly equivalent to \code{printf("\%i")}.}
+    \lineiii{\%x}{int}{Exactly equivalent to \code{printf("\%x")}.}
+    \lineiii{\%s}{char*}{A null-terminated C character array.}
+    \lineiii{\%p}{void*}{The hex representation of a C pointer.
+	Mostly equivalent to \code{printf("\%p")} except that it is
+	guaranteed to start with the literal \code{0x} regardless of
+	what the platform's \code{printf} yields.}
+  \end{tableiii}
+
+  An unrecognized format character causes all the rest of the format
+  string to be copied as-is to the result string, and any extra
+  arguments discarded.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyString_FromFormatV}{const char *format,
+                                                   va_list vargs}
+  Identical to \function{PyString_FromFormat()} except that it takes
+  exactly two arguments.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{Py_ssize_t}{PyString_Size}{PyObject *string}
+  Return the length of the string in string object \var{string}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{Py_ssize_t}{PyString_GET_SIZE}{PyObject *string}
+  Macro form of \cfunction{PyString_Size()} but without error
+  checking.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{char*}{PyString_AsString}{PyObject *string}
+  Return a NUL-terminated representation of the contents of
+  \var{string}.  The pointer refers to the internal buffer of
+  \var{string}, not a copy.  The data must not be modified in any way,
+  unless the string was just created using
+  \code{PyString_FromStringAndSize(NULL, \var{size})}.
+  It must not be deallocated.  If \var{string} is a Unicode object,
+  this function computes the default encoding of \var{string} and
+  operates on that.  If \var{string} is not a string object at all,
+  \cfunction{PyString_AsString()} returns \NULL{} and raises
+  \exception{TypeError}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{char*}{PyString_AS_STRING}{PyObject *string}
+  Macro form of \cfunction{PyString_AsString()} but without error
+  checking.  Only string objects are supported; no Unicode objects
+  should be passed.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyString_AsStringAndSize}{PyObject *obj,
+                                                 char **buffer,
+                                                 Py_ssize_t *length}
+  Return a NUL-terminated representation of the contents of the
+  object \var{obj} through the output variables \var{buffer} and
+  \var{length}.
+
+  The function accepts both string and Unicode objects as input. For
+  Unicode objects it returns the default encoded version of the
+  object.  If \var{length} is \NULL{}, the resulting buffer may not
+  contain NUL characters; if it does, the function returns \code{-1}
+  and a \exception{TypeError} is raised.
+
+  The buffer refers to an internal string buffer of \var{obj}, not a
+  copy. The data must not be modified in any way, unless the string
+  was just created using \code{PyString_FromStringAndSize(NULL,
+  \var{size})}.  It must not be deallocated.  If \var{string} is a
+  Unicode object, this function computes the default encoding of
+  \var{string} and operates on that.  If \var{string} is not a string
+  object at all, \cfunction{PyString_AsStringAndSize()} returns
+  \code{-1} and raises \exception{TypeError}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{PyString_Concat}{PyObject **string,
+                                         PyObject *newpart}
+  Create a new string object in \var{*string} containing the contents
+  of \var{newpart} appended to \var{string}; the caller will own the
+  new reference.  The reference to the old value of \var{string} will
+  be stolen.  If the new string cannot be created, the old reference
+  to \var{string} will still be discarded and the value of
+  \var{*string} will be set to \NULL{}; the appropriate exception will
+  be set.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{PyString_ConcatAndDel}{PyObject **string,
+                                               PyObject *newpart}
+  Create a new string object in \var{*string} containing the contents
+  of \var{newpart} appended to \var{string}.  This version decrements
+  the reference count of \var{newpart}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{_PyString_Resize}{PyObject **string, Py_ssize_t newsize}
+  A way to resize a string object even though it is ``immutable''.
+  Only use this to build up a brand new string object; don't use this
+  if the string may already be known in other parts of the code.  It
+  is an error to call this function if the refcount on the input string
+  object is not one.
+  Pass the address of an existing string object as an lvalue (it may
+  be written into), and the new size desired.  On success, \var{*string}
+  holds the resized string object and \code{0} is returned; the address in
+  \var{*string} may differ from its input value.  If the
+  reallocation fails, the original string object at \var{*string} is
+  deallocated, \var{*string} is set to \NULL{}, a memory exception is set,
+  and \code{-1} is returned.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyString_Format}{PyObject *format,
+                                              PyObject *args}
+  Return a new string object from \var{format} and \var{args}.
+  Analogous to \code{\var{format} \%\ \var{args}}.  The \var{args}
+  argument must be a tuple.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{PyString_InternInPlace}{PyObject **string}
+  Intern the argument \var{*string} in place.  The argument must be
+  the address of a pointer variable pointing to a Python string
+  object.  If there is an existing interned string that is the same as
+  \var{*string}, it sets \var{*string} to it (decrementing the
+  reference count of the old string object and incrementing the
+  reference count of the interned string object), otherwise it leaves
+  \var{*string} alone and interns it (incrementing its reference
+  count).  (Clarification: even though there is a lot of talk about
+  reference counts, think of this function as reference-count-neutral;
+  you own the object after the call if and only if you owned it before
+  the call.)
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyString_InternFromString}{const char *v}
+  A combination of \cfunction{PyString_FromString()} and
+  \cfunction{PyString_InternInPlace()}, returning either a new string
+  object that has been interned, or a new (``owned'') reference to an
+  earlier interned string object with the same value.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyString_Decode}{const char *s,
+                                               Py_ssize_t size,
+                                               const char *encoding,
+                                               const char *errors}
+  Create an object by decoding \var{size} bytes of the encoded
+  buffer \var{s} using the codec registered for
+  \var{encoding}.  \var{encoding} and \var{errors} have the same
+  meaning as the parameters of the same name in the
+  \function{unicode()} built-in function.  The codec to be used is
+  looked up using the Python codec registry.  Return \NULL{} if
+  an exception was raised by the codec.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyString_AsDecodedObject}{PyObject *str,
+                                               const char *encoding,
+                                               const char *errors}
+  Decode a string object by passing it to the codec registered for
+  \var{encoding} and return the result as Python
+  object. \var{encoding} and \var{errors} have the same meaning as the
+  parameters of the same name in the string \method{encode()} method.
+  The codec to be used is looked up using the Python codec registry.
+  Return \NULL{} if an exception was raised by the codec.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyString_Encode}{const char *s,
+                                               Py_ssize_t size,
+                                               const char *encoding,
+                                               const char *errors}
+  Encode the \ctype{char} buffer of the given size by passing it to
+  the codec registered for \var{encoding} and return a Python object.
+  \var{encoding} and \var{errors} have the same meaning as the
+  parameters of the same name in the string \method{encode()} method.
+  The codec to be used is looked up using the Python codec
+  registry.  Return \NULL{} if an exception was raised by the
+  codec.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyString_AsEncodedObject}{PyObject *str,
+                                               const char *encoding,
+                                               const char *errors}
+  Encode a string object using the codec registered for
+  \var{encoding} and return the result as Python object.
+  \var{encoding} and \var{errors} have the same meaning as the
+  parameters of the same name in the string \method{encode()} method.
+  The codec to be used is looked up using the Python codec registry.
+  Return \NULL{} if an exception was raised by the codec.
+\end{cfuncdesc}
+
+
+\subsection{Unicode Objects \label{unicodeObjects}}
+\sectionauthor{Marc-Andre Lemburg}{mal at lemburg.com}
+
+%--- Unicode Type -------------------------------------------------------
+
+These are the basic Unicode object types used for the Unicode
+implementation in Python:
+
+\begin{ctypedesc}{Py_UNICODE}
+  This type represents the storage type which is used by Python
+  internally as basis for holding Unicode ordinals.  Python's default
+  builds use a 16-bit type for \ctype{Py_UNICODE} and store Unicode
+  values internally as UCS2. It is also possible to build a UCS4
+  version of Python (most recent Linux distributions come with UCS4
+  builds of Python). These builds then use a 32-bit type for
+  \ctype{Py_UNICODE} and store Unicode data internally as UCS4. On
+  platforms where \ctype{wchar_t} is available and compatible with the
+  chosen Python Unicode build variant, \ctype{Py_UNICODE} is a typedef
+  alias for \ctype{wchar_t} to enhance native platform compatibility.
+  On all other platforms, \ctype{Py_UNICODE} is a typedef alias for
+  either \ctype{unsigned short} (UCS2) or \ctype{unsigned long}
+  (UCS4).
+\end{ctypedesc}
+
+Note that UCS2 and UCS4 Python builds are not binary compatible.
+Please keep this in mind when writing extensions or interfaces.
+
+\begin{ctypedesc}{PyUnicodeObject}
+  This subtype of \ctype{PyObject} represents a Python Unicode object.
+\end{ctypedesc}
+
+\begin{cvardesc}{PyTypeObject}{PyUnicode_Type}
+  This instance of \ctype{PyTypeObject} represents the Python Unicode
+  type.  It is exposed to Python code as \code{unicode} and
+  \code{types.UnicodeType}.
+\end{cvardesc}
+
+The following APIs are really C macros and can be used to do fast
+checks and to access internal read-only data of Unicode objects:
+
+\begin{cfuncdesc}{int}{PyUnicode_Check}{PyObject *o}
+  Return true if the object \var{o} is a Unicode object or an
+  instance of a Unicode subtype.
+  \versionchanged[Allowed subtypes to be accepted]{2.2}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyUnicode_CheckExact}{PyObject *o}
+  Return true if the object \var{o} is a Unicode object, but not an
+  instance of a subtype.
+  \versionadded{2.2}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{Py_ssize_t}{PyUnicode_GET_SIZE}{PyObject *o}
+  Return the size of the object.  \var{o} has to be a
+  \ctype{PyUnicodeObject} (not checked).
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{Py_ssize_t}{PyUnicode_GET_DATA_SIZE}{PyObject *o}
+  Return the size of the object's internal buffer in bytes.  \var{o}
+  has to be a \ctype{PyUnicodeObject} (not checked).
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{Py_UNICODE*}{PyUnicode_AS_UNICODE}{PyObject *o}
+  Return a pointer to the internal \ctype{Py_UNICODE} buffer of the
+  object.  \var{o} has to be a \ctype{PyUnicodeObject} (not checked).
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{const char*}{PyUnicode_AS_DATA}{PyObject *o}
+  Return a pointer to the internal buffer of the object.
+  \var{o} has to be a \ctype{PyUnicodeObject} (not checked).
+\end{cfuncdesc}
+
+% --- Unicode character properties ---------------------------------------
+
+Unicode provides many different character properties. The most often
+needed ones are available through these macros which are mapped to C
+functions depending on the Python configuration.
+
+\begin{cfuncdesc}{int}{Py_UNICODE_ISSPACE}{Py_UNICODE ch}
+  Return 1 or 0 depending on whether \var{ch} is a whitespace
+  character.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{Py_UNICODE_ISLOWER}{Py_UNICODE ch}
+  Return 1 or 0 depending on whether \var{ch} is a lowercase character.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{Py_UNICODE_ISUPPER}{Py_UNICODE ch}
+  Return 1 or 0 depending on whether \var{ch} is an uppercase
+  character.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{Py_UNICODE_ISTITLE}{Py_UNICODE ch}
+  Return 1 or 0 depending on whether \var{ch} is a titlecase character.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{Py_UNICODE_ISLINEBREAK}{Py_UNICODE ch}
+  Return 1 or 0 depending on whether \var{ch} is a linebreak character.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{Py_UNICODE_ISDECIMAL}{Py_UNICODE ch}
+  Return 1 or 0 depending on whether \var{ch} is a decimal character.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{Py_UNICODE_ISDIGIT}{Py_UNICODE ch}
+  Return 1 or 0 depending on whether \var{ch} is a digit character.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{Py_UNICODE_ISNUMERIC}{Py_UNICODE ch}
+  Return 1 or 0 depending on whether \var{ch} is a numeric character.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{Py_UNICODE_ISALPHA}{Py_UNICODE ch}
+  Return 1 or 0 depending on whether \var{ch} is an alphabetic
+  character.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{Py_UNICODE_ISALNUM}{Py_UNICODE ch}
+  Return 1 or 0 depending on whether \var{ch} is an alphanumeric
+  character.
+\end{cfuncdesc}
+
+These APIs can be used for fast direct character conversions:
+
+\begin{cfuncdesc}{Py_UNICODE}{Py_UNICODE_TOLOWER}{Py_UNICODE ch}
+  Return the character \var{ch} converted to lower case.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{Py_UNICODE}{Py_UNICODE_TOUPPER}{Py_UNICODE ch}
+  Return the character \var{ch} converted to upper case.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{Py_UNICODE}{Py_UNICODE_TOTITLE}{Py_UNICODE ch}
+  Return the character \var{ch} converted to title case.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{Py_UNICODE_TODECIMAL}{Py_UNICODE ch}
+  Return the character \var{ch} converted to a decimal positive
+  integer.  Return \code{-1} if this is not possible.  This macro
+  does not raise exceptions.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{Py_UNICODE_TODIGIT}{Py_UNICODE ch}
+  Return the character \var{ch} converted to a single digit integer.
+  Return \code{-1} if this is not possible.  This macro does not raise
+  exceptions.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{double}{Py_UNICODE_TONUMERIC}{Py_UNICODE ch}
+  Return the character \var{ch} converted to a double.
+  Return \code{-1.0} if this is not possible.  This macro does not raise
+  exceptions.
+\end{cfuncdesc}
+
+% --- Plain Py_UNICODE ---------------------------------------------------
+
+To create Unicode objects and access their basic sequence properties,
+use these APIs:
+
+\begin{cfuncdesc}{PyObject*}{PyUnicode_FromUnicode}{const Py_UNICODE *u,
+                                                    Py_ssize_t size}
+  Create a Unicode Object from the Py_UNICODE buffer \var{u} of the
+  given size. \var{u} may be \NULL{} which causes the contents to be
+  undefined. It is the user's responsibility to fill in the needed
+  data.  The buffer is copied into the new object. If the buffer is
+  not \NULL{}, the return value might be a shared object. Therefore,
+  modification of the resulting Unicode object is only allowed when
+  \var{u} is \NULL{}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{Py_UNICODE*}{PyUnicode_AsUnicode}{PyObject *unicode}
+  Return a read-only pointer to the Unicode object's internal
+  \ctype{Py_UNICODE} buffer, \NULL{} if \var{unicode} is not a Unicode
+  object.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{Py_ssize_t}{PyUnicode_GetSize}{PyObject *unicode}
+  Return the length of the Unicode object.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyUnicode_FromEncodedObject}{PyObject *obj,
+                                                      const char *encoding,
+                                                      const char *errors}
+  Coerce an encoded object \var{obj} to an Unicode object and return a
+  reference with incremented refcount.
+  
+  String and other char buffer compatible objects are decoded
+  according to the given encoding and using the error handling
+  defined by errors.  Both can be \NULL{} to have the interface
+  use the default values (see the next section for details).
+
+  All other objects, including Unicode objects, cause a
+  \exception{TypeError} to be set.
+
+  The API returns \NULL{} if there was an error.  The caller is
+  responsible for decref'ing the returned objects.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyUnicode_FromObject}{PyObject *obj}
+  Shortcut for \code{PyUnicode_FromEncodedObject(obj, NULL, "strict")}
+  which is used throughout the interpreter whenever coercion to
+  Unicode is needed.
+\end{cfuncdesc}
+
+% --- wchar_t support for platforms which support it ---------------------
+
+If the platform supports \ctype{wchar_t} and provides a header file
+wchar.h, Python can interface directly to this type using the
+following functions. Support is optimized if Python's own
+\ctype{Py_UNICODE} type is identical to the system's \ctype{wchar_t}.
+
+\begin{cfuncdesc}{PyObject*}{PyUnicode_FromWideChar}{const wchar_t *w,
+                                                     Py_ssize_t size}
+  Create a Unicode object from the \ctype{wchar_t} buffer \var{w} of
+  the given size.  Return \NULL{} on failure.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{Py_ssize_t}{PyUnicode_AsWideChar}{PyUnicodeObject *unicode,
+                                             wchar_t *w,
+                                             Py_ssize_t size}
+  Copy the Unicode object contents into the \ctype{wchar_t} buffer
+  \var{w}.  At most \var{size} \ctype{wchar_t} characters are copied
+  (excluding a possibly trailing 0-termination character).  Return
+  the number of \ctype{wchar_t} characters copied or -1 in case of an
+  error.  Note that the resulting \ctype{wchar_t} string may or may
+  not be 0-terminated.  It is the responsibility of the caller to make
+  sure that the \ctype{wchar_t} string is 0-terminated in case this is
+  required by the application.
+\end{cfuncdesc}
+
+
+\subsubsection{Built-in Codecs \label{builtinCodecs}}
+
+Python provides a set of builtin codecs which are written in C
+for speed. All of these codecs are directly usable via the
+following functions.
+
+Many of the following APIs take two arguments encoding and
+errors. These parameters encoding and errors have the same semantics
+as the ones of the builtin unicode() Unicode object constructor.
+
+Setting encoding to \NULL{} causes the default encoding to be used
+which is \ASCII.  The file system calls should use
+\cdata{Py_FileSystemDefaultEncoding} as the encoding for file
+names. This variable should be treated as read-only: On some systems,
+it will be a pointer to a static string, on others, it will change at
+run-time (such as when the application invokes setlocale).
+
+Error handling is set by errors which may also be set to \NULL{}
+meaning to use the default handling defined for the codec.  Default
+error handling for all builtin codecs is ``strict''
+(\exception{ValueError} is raised).
+
+The codecs all use a similar interface.  Only deviation from the
+following generic ones are documented for simplicity.
+
+% --- Generic Codecs -----------------------------------------------------
+
+These are the generic codec APIs:
+
+\begin{cfuncdesc}{PyObject*}{PyUnicode_Decode}{const char *s,
+                                               Py_ssize_t size,
+                                               const char *encoding,
+                                               const char *errors}
+  Create a Unicode object by decoding \var{size} bytes of the encoded
+  string \var{s}.  \var{encoding} and \var{errors} have the same
+  meaning as the parameters of the same name in the
+  \function{unicode()} builtin function.  The codec to be used is
+  looked up using the Python codec registry.  Return \NULL{} if an
+  exception was raised by the codec.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyUnicode_Encode}{const Py_UNICODE *s,
+                                               Py_ssize_t size,
+                                               const char *encoding,
+                                               const char *errors}
+  Encode the \ctype{Py_UNICODE} buffer of the given size and return
+  a Python string object.  \var{encoding} and \var{errors} have the
+  same meaning as the parameters of the same name in the Unicode
+  \method{encode()} method.  The codec to be used is looked up using
+  the Python codec registry.  Return \NULL{} if an exception was
+  raised by the codec.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyUnicode_AsEncodedString}{PyObject *unicode,
+                                               const char *encoding,
+                                               const char *errors}
+  Encode a Unicode object and return the result as Python string
+  object. \var{encoding} and \var{errors} have the same meaning as the
+  parameters of the same name in the Unicode \method{encode()} method.
+  The codec to be used is looked up using the Python codec registry.
+  Return \NULL{} if an exception was raised by the codec.
+\end{cfuncdesc}
+
+% --- UTF-8 Codecs -------------------------------------------------------
+
+These are the UTF-8 codec APIs:
+
+\begin{cfuncdesc}{PyObject*}{PyUnicode_DecodeUTF8}{const char *s,
+                                               Py_ssize_t size,
+                                               const char *errors}
+  Create a Unicode object by decoding \var{size} bytes of the UTF-8
+  encoded string \var{s}. Return \NULL{} if an exception was raised
+  by the codec.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyUnicode_DecodeUTF8Stateful}{const char *s,
+                                               Py_ssize_t size,
+                                               const char *errors,
+                                               Py_ssize_t *consumed}
+  If \var{consumed} is \NULL{}, behave like \cfunction{PyUnicode_DecodeUTF8()}.
+  If \var{consumed} is not \NULL{}, trailing incomplete UTF-8 byte sequences
+  will not be treated as an error. Those bytes will not be decoded and the
+  number of bytes that have been decoded will be stored in \var{consumed}.
+  \versionadded{2.4}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyUnicode_EncodeUTF8}{const Py_UNICODE *s,
+                                               Py_ssize_t size,
+                                               const char *errors}
+  Encode the \ctype{Py_UNICODE} buffer of the given size using UTF-8
+  and return a Python string object.  Return \NULL{} if an exception
+  was raised by the codec.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyUnicode_AsUTF8String}{PyObject *unicode}
+  Encode a Unicode objects using UTF-8 and return the result as
+  Python string object.  Error handling is ``strict''.  Return
+  \NULL{} if an exception was raised by the codec.
+\end{cfuncdesc}
+
+% --- UTF-16 Codecs ------------------------------------------------------ */
+
+These are the UTF-16 codec APIs:
+
+\begin{cfuncdesc}{PyObject*}{PyUnicode_DecodeUTF16}{const char *s,
+                                               Py_ssize_t size,
+                                               const char *errors,
+                                               int *byteorder}
+  Decode \var{length} bytes from a UTF-16 encoded buffer string and
+  return the corresponding Unicode object.  \var{errors} (if
+  non-\NULL{}) defines the error handling. It defaults to ``strict''.
+
+  If \var{byteorder} is non-\NULL{}, the decoder starts decoding using
+  the given byte order:
+
+\begin{verbatim}
+   *byteorder == -1: little endian
+   *byteorder == 0:  native order
+   *byteorder == 1:  big endian
+\end{verbatim}
+
+  and then switches according to all byte order marks (BOM) it finds
+  in the input data.  BOMs are not copied into the resulting Unicode
+  string.  After completion, \var{*byteorder} is set to the current
+  byte order at the end of input data.
+
+  If \var{byteorder} is \NULL{}, the codec starts in native order mode.
+
+  Return \NULL{} if an exception was raised by the codec.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyUnicode_DecodeUTF16Stateful}{const char *s,
+                                               Py_ssize_t size,
+                                               const char *errors,
+                                               int *byteorder,
+                                               Py_ssize_t *consumed}
+  If \var{consumed} is \NULL{}, behave like
+  \cfunction{PyUnicode_DecodeUTF16()}. If \var{consumed} is not \NULL{},
+  \cfunction{PyUnicode_DecodeUTF16Stateful()} will not treat trailing incomplete
+  UTF-16 byte sequences (such as an odd number of bytes or a split surrogate pair)
+  as an error. Those bytes will not be decoded and the number of bytes that
+  have been decoded will be stored in \var{consumed}.
+  \versionadded{2.4}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyUnicode_EncodeUTF16}{const Py_UNICODE *s,
+                                               Py_ssize_t size,
+                                               const char *errors,
+                                               int byteorder}
+  Return a Python string object holding the UTF-16 encoded value of
+  the Unicode data in \var{s}.  If \var{byteorder} is not \code{0},
+  output is written according to the following byte order:
+
+\begin{verbatim}
+   byteorder == -1: little endian
+   byteorder == 0:  native byte order (writes a BOM mark)
+   byteorder == 1:  big endian
+\end{verbatim}
+
+  If byteorder is \code{0}, the output string will always start with
+  the Unicode BOM mark (U+FEFF). In the other two modes, no BOM mark
+  is prepended.
+
+  If \var{Py_UNICODE_WIDE} is defined, a single \ctype{Py_UNICODE}
+  value may get represented as a surrogate pair. If it is not
+  defined, each \ctype{Py_UNICODE} values is interpreted as an
+  UCS-2 character.
+
+  Return \NULL{} if an exception was raised by the codec.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyUnicode_AsUTF16String}{PyObject *unicode}
+  Return a Python string using the UTF-16 encoding in native byte
+  order. The string always starts with a BOM mark.  Error handling is
+  ``strict''.  Return \NULL{} if an exception was raised by the
+  codec.
+\end{cfuncdesc}
+
+% --- Unicode-Escape Codecs ----------------------------------------------
+
+These are the ``Unicode Escape'' codec APIs:
+
+\begin{cfuncdesc}{PyObject*}{PyUnicode_DecodeUnicodeEscape}{const char *s,
+                                               Py_ssize_t size,
+                                               const char *errors}
+  Create a Unicode object by decoding \var{size} bytes of the
+  Unicode-Escape encoded string \var{s}.  Return \NULL{} if an
+  exception was raised by the codec.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyUnicode_EncodeUnicodeEscape}{const Py_UNICODE *s,
+                                               Py_ssize_t size}
+  Encode the \ctype{Py_UNICODE} buffer of the given size using
+  Unicode-Escape and return a Python string object.  Return \NULL{}
+  if an exception was raised by the codec.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyUnicode_AsUnicodeEscapeString}{PyObject *unicode}
+  Encode a Unicode objects using Unicode-Escape and return the
+  result as Python string object.  Error handling is ``strict''.
+  Return \NULL{} if an exception was raised by the codec.
+\end{cfuncdesc}
+
+% --- Raw-Unicode-Escape Codecs ------------------------------------------
+
+These are the ``Raw Unicode Escape'' codec APIs:
+
+\begin{cfuncdesc}{PyObject*}{PyUnicode_DecodeRawUnicodeEscape}{const char *s,
+                                               Py_ssize_t size,
+                                               const char *errors}
+  Create a Unicode object by decoding \var{size} bytes of the
+  Raw-Unicode-Escape encoded string \var{s}.  Return \NULL{} if an
+  exception was raised by the codec.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyUnicode_EncodeRawUnicodeEscape}{const Py_UNICODE *s,
+                                               Py_ssize_t size,
+                                               const char *errors}
+  Encode the \ctype{Py_UNICODE} buffer of the given size using
+  Raw-Unicode-Escape and return a Python string object.  Return
+  \NULL{} if an exception was raised by the codec.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyUnicode_AsRawUnicodeEscapeString}{PyObject *unicode}
+  Encode a Unicode objects using Raw-Unicode-Escape and return the
+  result as Python string object. Error handling is ``strict''.
+  Return \NULL{} if an exception was raised by the codec.
+\end{cfuncdesc}
+
+% --- Latin-1 Codecs -----------------------------------------------------
+
+These are the Latin-1 codec APIs:
+Latin-1 corresponds to the first 256 Unicode ordinals and only these
+are accepted by the codecs during encoding.
+
+\begin{cfuncdesc}{PyObject*}{PyUnicode_DecodeLatin1}{const char *s,
+                                                     Py_ssize_t size,
+                                                     const char *errors}
+  Create a Unicode object by decoding \var{size} bytes of the Latin-1
+  encoded string \var{s}.  Return \NULL{} if an exception was raised
+  by the codec.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyUnicode_EncodeLatin1}{const Py_UNICODE *s,
+                                                     Py_ssize_t size,
+                                                     const char *errors}
+  Encode the \ctype{Py_UNICODE} buffer of the given size using
+  Latin-1 and return a Python string object.  Return \NULL{} if an
+  exception was raised by the codec.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyUnicode_AsLatin1String}{PyObject *unicode}
+  Encode a Unicode objects using Latin-1 and return the result as
+  Python string object.  Error handling is ``strict''.  Return
+  \NULL{} if an exception was raised by the codec.
+\end{cfuncdesc}
+
+% --- ASCII Codecs -------------------------------------------------------
+
+These are the \ASCII{} codec APIs.  Only 7-bit \ASCII{} data is
+accepted. All other codes generate errors.
+
+\begin{cfuncdesc}{PyObject*}{PyUnicode_DecodeASCII}{const char *s,
+                                                    Py_ssize_t size,
+                                                    const char *errors}
+  Create a Unicode object by decoding \var{size} bytes of the
+  \ASCII{} encoded string \var{s}.  Return \NULL{} if an exception
+  was raised by the codec.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyUnicode_EncodeASCII}{const Py_UNICODE *s,
+                                                    Py_ssize_t size,
+                                                    const char *errors}
+  Encode the \ctype{Py_UNICODE} buffer of the given size using
+  \ASCII{} and return a Python string object.  Return \NULL{} if an
+  exception was raised by the codec.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyUnicode_AsASCIIString}{PyObject *unicode}
+  Encode a Unicode objects using \ASCII{} and return the result as
+  Python string object.  Error handling is ``strict''.  Return
+  \NULL{} if an exception was raised by the codec.
+\end{cfuncdesc}
+
+% --- Character Map Codecs -----------------------------------------------
+
+These are the mapping codec APIs:
+
+This codec is special in that it can be used to implement many
+different codecs (and this is in fact what was done to obtain most of
+the standard codecs included in the \module{encodings} package). The
+codec uses mapping to encode and decode characters.
+
+Decoding mappings must map single string characters to single Unicode
+characters, integers (which are then interpreted as Unicode ordinals)
+or None (meaning "undefined mapping" and causing an error).
+
+Encoding mappings must map single Unicode characters to single string
+characters, integers (which are then interpreted as Latin-1 ordinals)
+or None (meaning "undefined mapping" and causing an error).
+
+The mapping objects provided must only support the __getitem__ mapping
+interface.
+
+If a character lookup fails with a LookupError, the character is
+copied as-is meaning that its ordinal value will be interpreted as
+Unicode or Latin-1 ordinal resp. Because of this, mappings only need
+to contain those mappings which map characters to different code
+points.
+
+\begin{cfuncdesc}{PyObject*}{PyUnicode_DecodeCharmap}{const char *s,
+                                               Py_ssize_t size,
+                                               PyObject *mapping,
+                                               const char *errors}
+  Create a Unicode object by decoding \var{size} bytes of the encoded
+  string \var{s} using the given \var{mapping} object.  Return
+  \NULL{} if an exception was raised by the codec. If \var{mapping} is \NULL{}
+  latin-1 decoding will be done. Else it can be a dictionary mapping byte or a
+  unicode string, which is treated as a lookup table. Byte values greater
+  that the length of the string and U+FFFE "characters" are treated as
+  "undefined mapping".
+  \versionchanged[Allowed unicode string as mapping argument]{2.4}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyUnicode_EncodeCharmap}{const Py_UNICODE *s,
+                                               Py_ssize_t size,
+                                               PyObject *mapping,
+                                               const char *errors}
+  Encode the \ctype{Py_UNICODE} buffer of the given size using the
+  given \var{mapping} object and return a Python string object.
+  Return \NULL{} if an exception was raised by the codec.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyUnicode_AsCharmapString}{PyObject *unicode,
+                                                        PyObject *mapping}
+  Encode a Unicode objects using the given \var{mapping} object and
+  return the result as Python string object.  Error handling is
+  ``strict''.  Return \NULL{} if an exception was raised by the
+  codec.
+\end{cfuncdesc}
+
+The following codec API is special in that maps Unicode to Unicode.
+
+\begin{cfuncdesc}{PyObject*}{PyUnicode_TranslateCharmap}{const Py_UNICODE *s,
+                                               Py_ssize_t size,
+                                               PyObject *table,
+                                               const char *errors}
+  Translate a \ctype{Py_UNICODE} buffer of the given length by
+  applying a character mapping \var{table} to it and return the
+  resulting Unicode object.  Return \NULL{} when an exception was
+  raised by the codec.
+
+  The \var{mapping} table must map Unicode ordinal integers to Unicode
+  ordinal integers or None (causing deletion of the character).
+
+  Mapping tables need only provide the \method{__getitem__()}
+  interface; dictionaries and sequences work well.  Unmapped character
+  ordinals (ones which cause a \exception{LookupError}) are left
+  untouched and are copied as-is.
+\end{cfuncdesc}
+
+% --- MBCS codecs for Windows --------------------------------------------
+
+These are the MBCS codec APIs. They are currently only available on
+Windows and use the Win32 MBCS converters to implement the
+conversions.  Note that MBCS (or DBCS) is a class of encodings, not
+just one.  The target encoding is defined by the user settings on the
+machine running the codec.
+
+\begin{cfuncdesc}{PyObject*}{PyUnicode_DecodeMBCS}{const char *s,
+                                               Py_ssize_t size,
+                                               const char *errors}
+  Create a Unicode object by decoding \var{size} bytes of the MBCS
+  encoded string \var{s}.  Return \NULL{} if an exception was
+  raised by the codec.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyUnicode_DecodeMBCSStateful}{const char *s,
+                                               int size,
+                                               const char *errors,
+                                               int *consumed}
+  If \var{consumed} is \NULL{}, behave like
+  \cfunction{PyUnicode_DecodeMBCS()}. If \var{consumed} is not \NULL{},
+  \cfunction{PyUnicode_DecodeMBCSStateful()} will not decode trailing lead
+  byte and the number of bytes that have been decoded will be stored in
+  \var{consumed}.
+  \versionadded{2.5}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyUnicode_EncodeMBCS}{const Py_UNICODE *s,
+                                               Py_ssize_t size,
+                                               const char *errors}
+  Encode the \ctype{Py_UNICODE} buffer of the given size using MBCS
+  and return a Python string object.  Return \NULL{} if an exception
+  was raised by the codec.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyUnicode_AsMBCSString}{PyObject *unicode}
+  Encode a Unicode objects using MBCS and return the result as
+  Python string object.  Error handling is ``strict''.  Return
+  \NULL{} if an exception was raised by the codec.
+\end{cfuncdesc}
+
+% --- Methods & Slots ----------------------------------------------------
+
+\subsubsection{Methods and Slot Functions \label{unicodeMethodsAndSlots}}
+
+The following APIs are capable of handling Unicode objects and strings
+on input (we refer to them as strings in the descriptions) and return
+Unicode objects or integers as appropriate.
+
+They all return \NULL{} or \code{-1} if an exception occurs.
+
+\begin{cfuncdesc}{PyObject*}{PyUnicode_Concat}{PyObject *left,
+                                               PyObject *right}
+  Concat two strings giving a new Unicode string.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyUnicode_Split}{PyObject *s,
+                                              PyObject *sep,
+                                              Py_ssize_t maxsplit}
+  Split a string giving a list of Unicode strings.  If sep is \NULL{},
+  splitting will be done at all whitespace substrings.  Otherwise,
+  splits occur at the given separator.  At most \var{maxsplit} splits
+  will be done.  If negative, no limit is set.  Separators are not
+  included in the resulting list.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyUnicode_Splitlines}{PyObject *s,
+                                                   int keepend}
+  Split a Unicode string at line breaks, returning a list of Unicode
+  strings.  CRLF is considered to be one line break.  If \var{keepend}
+  is 0, the Line break characters are not included in the resulting
+  strings.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyUnicode_Translate}{PyObject *str,
+                                                  PyObject *table,
+                                                  const char *errors}
+  Translate a string by applying a character mapping table to it and
+  return the resulting Unicode object.
+
+  The mapping table must map Unicode ordinal integers to Unicode
+  ordinal integers or None (causing deletion of the character).
+
+  Mapping tables need only provide the \method{__getitem__()}
+  interface; dictionaries and sequences work well.  Unmapped character
+  ordinals (ones which cause a \exception{LookupError}) are left
+  untouched and are copied as-is.
+
+  \var{errors} has the usual meaning for codecs. It may be \NULL{}
+  which indicates to use the default error handling.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyUnicode_Join}{PyObject *separator,
+                                             PyObject *seq}
+  Join a sequence of strings using the given separator and return the
+  resulting Unicode string.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyUnicode_Tailmatch}{PyObject *str,
+                                                  PyObject *substr,
+                                                  Py_ssize_t start,
+                                                  Py_ssize_t end,
+                                                  int direction}
+  Return 1 if \var{substr} matches \var{str}[\var{start}:\var{end}] at
+  the given tail end (\var{direction} == -1 means to do a prefix
+  match, \var{direction} == 1 a suffix match), 0 otherwise.
+  Return \code{-1} if an error occurred.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{Py_ssize_t}{PyUnicode_Find}{PyObject *str,
+                                       PyObject *substr,
+                                       Py_ssize_t start,
+                                       Py_ssize_t end,
+                                       int direction}
+  Return the first position of \var{substr} in
+  \var{str}[\var{start}:\var{end}] using the given \var{direction}
+  (\var{direction} == 1 means to do a forward search,
+  \var{direction} == -1 a backward search).  The return value is the
+  index of the first match; a value of \code{-1} indicates that no
+  match was found, and \code{-2} indicates that an error occurred and
+  an exception has been set.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{Py_ssize_t}{PyUnicode_Count}{PyObject *str,
+                                        PyObject *substr,
+                                        Py_ssize_t start,
+                                        Py_ssize_t end}
+  Return the number of non-overlapping occurrences of \var{substr} in
+  \code{\var{str}[\var{start}:\var{end}]}.  Return \code{-1} if an
+  error occurred.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyUnicode_Replace}{PyObject *str,
+                                                PyObject *substr,
+                                                PyObject *replstr,
+                                                Py_ssize_t maxcount}
+  Replace at most \var{maxcount} occurrences of \var{substr} in
+  \var{str} with \var{replstr} and return the resulting Unicode object.
+  \var{maxcount} == -1 means replace all occurrences.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyUnicode_Compare}{PyObject *left, PyObject *right}
+  Compare two strings and return -1, 0, 1 for less than, equal, and
+  greater than, respectively.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyUnicode_RichCompare}{PyObject *left, 
+                                              PyObject *right, 
+                                              int op}
+
+  Rich compare two unicode strings and return one of the following:
+  \begin{itemize}
+    \item \code{NULL} in case an exception was raised
+    \item \constant{Py_True} or \constant{Py_False} for successful comparisons
+    \item \constant{Py_NotImplemented} in case the type combination is unknown
+  \end{itemize}
+
+   Note that \constant{Py_EQ} and \constant{Py_NE} comparisons can cause a
+   \exception{UnicodeWarning} in case the conversion of the arguments to
+   Unicode fails with a \exception{UnicodeDecodeError}.
+
+   Possible values for \var{op} are
+   \constant{Py_GT}, \constant{Py_GE}, \constant{Py_EQ},
+   \constant{Py_NE}, \constant{Py_LT}, and \constant{Py_LE}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyUnicode_Format}{PyObject *format,
+                                              PyObject *args}
+  Return a new string object from \var{format} and \var{args}; this
+  is analogous to \code{\var{format} \%\ \var{args}}.  The
+  \var{args} argument must be a tuple.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyUnicode_Contains}{PyObject *container,
+                                           PyObject *element}
+  Check whether \var{element} is contained in \var{container} and
+  return true or false accordingly.
+
+  \var{element} has to coerce to a one element Unicode
+  string. \code{-1} is returned if there was an error.
+\end{cfuncdesc}
+
+
+\subsection{Buffer Objects \label{bufferObjects}}
+\sectionauthor{Greg Stein}{gstein at lyra.org}
+
+\obindex{buffer}
+Python objects implemented in C can export a group of functions called
+the ``buffer\index{buffer interface} interface.''  These functions can
+be used by an object to expose its data in a raw, byte-oriented
+format. Clients of the object can use the buffer interface to access
+the object data directly, without needing to copy it first.
+
+Two examples of objects that support
+the buffer interface are strings and arrays. The string object exposes
+the character contents in the buffer interface's byte-oriented
+form. An array can also expose its contents, but it should be noted
+that array elements may be multi-byte values.
+
+An example user of the buffer interface is the file object's
+\method{write()} method. Any object that can export a series of bytes
+through the buffer interface can be written to a file. There are a
+number of format codes to \cfunction{PyArg_ParseTuple()} that operate
+against an object's buffer interface, returning data from the target
+object.
+
+More information on the buffer interface is provided in the section
+``Buffer Object Structures'' (section~\ref{buffer-structs}), under
+the description for \ctype{PyBufferProcs}\ttindex{PyBufferProcs}.
+
+A ``buffer object'' is defined in the \file{bufferobject.h} header
+(included by \file{Python.h}). These objects look very similar to
+string objects at the Python programming level: they support slicing,
+indexing, concatenation, and some other standard string
+operations. However, their data can come from one of two sources: from
+a block of memory, or from another object which exports the buffer
+interface.
+
+Buffer objects are useful as a way to expose the data from another
+object's buffer interface to the Python programmer. They can also be
+used as a zero-copy slicing mechanism. Using their ability to
+reference a block of memory, it is possible to expose any data to the
+Python programmer quite easily. The memory could be a large, constant
+array in a C extension, it could be a raw block of memory for
+manipulation before passing to an operating system library, or it
+could be used to pass around structured data in its native, in-memory
+format.
+
+\begin{ctypedesc}{PyBufferObject}
+  This subtype of \ctype{PyObject} represents a buffer object.
+\end{ctypedesc}
+
+\begin{cvardesc}{PyTypeObject}{PyBuffer_Type}
+  The instance of \ctype{PyTypeObject} which represents the Python
+  buffer type; it is the same object as \code{buffer} and 
+  \code{types.BufferType} in the Python layer.
+  \withsubitem{(in module types)}{\ttindex{BufferType}}.
+\end{cvardesc}
+
+\begin{cvardesc}{int}{Py_END_OF_BUFFER}
+  This constant may be passed as the \var{size} parameter to
+  \cfunction{PyBuffer_FromObject()} or
+  \cfunction{PyBuffer_FromReadWriteObject()}.  It indicates that the
+  new \ctype{PyBufferObject} should refer to \var{base} object from
+  the specified \var{offset} to the end of its exported buffer.  Using
+  this enables the caller to avoid querying the \var{base} object for
+  its length.
+\end{cvardesc}
+
+\begin{cfuncdesc}{int}{PyBuffer_Check}{PyObject *p}
+  Return true if the argument has type \cdata{PyBuffer_Type}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyBuffer_FromObject}{PyObject *base,
+                                                  Py_ssize_t offset, Py_ssize_t size}
+  Return a new read-only buffer object.  This raises
+  \exception{TypeError} if \var{base} doesn't support the read-only
+  buffer protocol or doesn't provide exactly one buffer segment, or it
+  raises \exception{ValueError} if \var{offset} is less than zero. The
+  buffer will hold a reference to the \var{base} object, and the
+  buffer's contents will refer to the \var{base} object's buffer
+  interface, starting as position \var{offset} and extending for
+  \var{size} bytes. If \var{size} is \constant{Py_END_OF_BUFFER}, then
+  the new buffer's contents extend to the length of the \var{base}
+  object's exported buffer data.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyBuffer_FromReadWriteObject}{PyObject *base,
+                                                           Py_ssize_t offset,
+                                                           Py_ssize_t size}
+  Return a new writable buffer object.  Parameters and exceptions are
+  similar to those for \cfunction{PyBuffer_FromObject()}.  If the
+  \var{base} object does not export the writeable buffer protocol,
+  then \exception{TypeError} is raised.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyBuffer_FromMemory}{void *ptr, Py_ssize_t size}
+  Return a new read-only buffer object that reads from a specified
+  location in memory, with a specified size.  The caller is
+  responsible for ensuring that the memory buffer, passed in as
+  \var{ptr}, is not deallocated while the returned buffer object
+  exists.  Raises \exception{ValueError} if \var{size} is less than
+  zero.  Note that \constant{Py_END_OF_BUFFER} may \emph{not} be
+  passed for the \var{size} parameter; \exception{ValueError} will be
+  raised in that case.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyBuffer_FromReadWriteMemory}{void *ptr, Py_ssize_t size}
+  Similar to \cfunction{PyBuffer_FromMemory()}, but the returned
+  buffer is writable.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyBuffer_New}{Py_ssize_t size}
+  Return a new writable buffer object that maintains its own memory
+  buffer of \var{size} bytes.  \exception{ValueError} is returned if
+  \var{size} is not zero or positive.  Note that the memory buffer (as
+  returned by \cfunction{PyObject_AsWriteBuffer()}) is not specifically
+  aligned.
+\end{cfuncdesc}
+
+
+\subsection{Tuple Objects \label{tupleObjects}}
+
+\obindex{tuple}
+\begin{ctypedesc}{PyTupleObject}
+  This subtype of \ctype{PyObject} represents a Python tuple object.
+\end{ctypedesc}
+
+\begin{cvardesc}{PyTypeObject}{PyTuple_Type}
+  This instance of \ctype{PyTypeObject} represents the Python tuple
+  type; it is the same object as \code{tuple} and \code{types.TupleType}
+  in the Python layer.\withsubitem{(in module types)}{\ttindex{TupleType}}.
+\end{cvardesc}
+
+\begin{cfuncdesc}{int}{PyTuple_Check}{PyObject *p}
+  Return true if \var{p} is a tuple object or an instance of a subtype
+  of the tuple type.
+  \versionchanged[Allowed subtypes to be accepted]{2.2}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyTuple_CheckExact}{PyObject *p}
+  Return true if \var{p} is a tuple object, but not an instance of a
+  subtype of the tuple type.
+  \versionadded{2.2}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyTuple_New}{Py_ssize_t len}
+  Return a new tuple object of size \var{len}, or \NULL{} on failure.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyTuple_Pack}{Py_ssize_t n, \moreargs}
+  Return a new tuple object of size \var{n}, or \NULL{} on failure.
+  The tuple values are initialized to the subsequent \var{n} C arguments
+  pointing to Python objects.  \samp{PyTuple_Pack(2, \var{a}, \var{b})}
+  is equivalent to \samp{Py_BuildValue("(OO)", \var{a}, \var{b})}.
+  \versionadded{2.4}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyTuple_Size}{PyObject *p}
+  Take a pointer to a tuple object, and return the size of that
+  tuple.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyTuple_GET_SIZE}{PyObject *p}
+  Return the size of the tuple \var{p}, which must be non-\NULL{} and
+  point to a tuple; no error checking is performed.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyTuple_GetItem}{PyObject *p, Py_ssize_t pos}
+  Return the object at position \var{pos} in the tuple pointed to by
+  \var{p}.  If \var{pos} is out of bounds, return \NULL{} and sets an
+  \exception{IndexError} exception.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyTuple_GET_ITEM}{PyObject *p, Py_ssize_t pos}
+  Like \cfunction{PyTuple_GetItem()}, but does no checking of its
+  arguments.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyTuple_GetSlice}{PyObject *p,
+                                               Py_ssize_t low, Py_ssize_t high}
+  Take a slice of the tuple pointed to by \var{p} from \var{low} to
+  \var{high} and return it as a new tuple.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyTuple_SetItem}{PyObject *p,
+                                        Py_ssize_t pos, PyObject *o}
+  Insert a reference to object \var{o} at position \var{pos} of the
+  tuple pointed to by \var{p}. Return \code{0} on success.
+  \note{This function ``steals'' a reference to \var{o}.}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{PyTuple_SET_ITEM}{PyObject *p,
+                                          Py_ssize_t pos, PyObject *o}
+  Like \cfunction{PyTuple_SetItem()}, but does no error checking, and
+  should \emph{only} be used to fill in brand new tuples.  \note{This
+  function ``steals'' a reference to \var{o}.}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{_PyTuple_Resize}{PyObject **p, Py_ssize_t newsize}
+  Can be used to resize a tuple.  \var{newsize} will be the new length
+  of the tuple.  Because tuples are \emph{supposed} to be immutable,
+  this should only be used if there is only one reference to the
+  object.  Do \emph{not} use this if the tuple may already be known to
+  some other part of the code.  The tuple will always grow or shrink
+  at the end.  Think of this as destroying the old tuple and creating
+  a new one, only more efficiently.  Returns \code{0} on success.
+  Client code should never assume that the resulting value of
+  \code{*\var{p}} will be the same as before calling this function.
+  If the object referenced by \code{*\var{p}} is replaced, the
+  original \code{*\var{p}} is destroyed.  On failure, returns
+  \code{-1} and sets \code{*\var{p}} to \NULL{}, and raises
+  \exception{MemoryError} or
+  \exception{SystemError}.
+  \versionchanged[Removed unused third parameter, \var{last_is_sticky}]{2.2}
+\end{cfuncdesc}
+
+
+\subsection{List Objects \label{listObjects}}
+
+\obindex{list}
+\begin{ctypedesc}{PyListObject}
+  This subtype of \ctype{PyObject} represents a Python list object.
+\end{ctypedesc}
+
+\begin{cvardesc}{PyTypeObject}{PyList_Type}
+  This instance of \ctype{PyTypeObject} represents the Python list
+  type.  This is the same object as \code{list} and \code{types.ListType}
+  in the Python layer.\withsubitem{(in module types)}{\ttindex{ListType}}
+\end{cvardesc}
+
+\begin{cfuncdesc}{int}{PyList_Check}{PyObject *p}
+  Return true if \var{p} is a list object or an instance of a
+  subtype of the list type.
+  \versionchanged[Allowed subtypes to be accepted]{2.2}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyList_CheckExact}{PyObject *p}
+  Return true if \var{p} is a list object, but not an instance of a
+  subtype of the list type.
+  \versionadded{2.2}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyList_New}{Py_ssize_t len}
+  Return a new list of length \var{len} on success, or \NULL{} on
+  failure.
+  \note{If \var{length} is greater than zero, the returned list object's
+        items are set to \code{NULL}.  Thus you cannot use abstract
+        API functions such as \cfunction{PySequence_SetItem()} 
+        or expose the object to Python code before setting all items to a
+        real object with \cfunction{PyList_SetItem()}.}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{Py_ssize_t}{PyList_Size}{PyObject *list}
+  Return the length of the list object in \var{list}; this is
+  equivalent to \samp{len(\var{list})} on a list object.
+  \bifuncindex{len}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{Py_ssize_t}{PyList_GET_SIZE}{PyObject *list}
+  Macro form of \cfunction{PyList_Size()} without error checking.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyList_GetItem}{PyObject *list, Py_ssize_t index}
+  Return the object at position \var{pos} in the list pointed to by
+  \var{p}.  The position must be positive, indexing from the end of the
+  list is not supported.  If \var{pos} is out of bounds, return \NULL{}
+  and set an \exception{IndexError} exception.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyList_GET_ITEM}{PyObject *list, Py_ssize_t i}
+  Macro form of \cfunction{PyList_GetItem()} without error checking.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyList_SetItem}{PyObject *list, Py_ssize_t index,
+                                       PyObject *item}
+  Set the item at index \var{index} in list to \var{item}.  Return
+  \code{0} on success or \code{-1} on failure.  \note{This function
+  ``steals'' a reference to \var{item} and discards a reference to an
+  item already in the list at the affected position.}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{PyList_SET_ITEM}{PyObject *list, Py_ssize_t i,
+                                              PyObject *o}
+  Macro form of \cfunction{PyList_SetItem()} without error checking.
+  This is normally only used to fill in new lists where there is no
+  previous content.
+  \note{This function ``steals'' a reference to \var{item}, and,
+  unlike \cfunction{PyList_SetItem()}, does \emph{not} discard a
+  reference to any item that it being replaced; any reference in
+  \var{list} at position \var{i} will be leaked.}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyList_Insert}{PyObject *list, Py_ssize_t index,
+                                      PyObject *item}
+  Insert the item \var{item} into list \var{list} in front of index
+  \var{index}.  Return \code{0} if successful; return \code{-1} and
+  set an exception if unsuccessful.  Analogous to
+  \code{\var{list}.insert(\var{index}, \var{item})}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyList_Append}{PyObject *list, PyObject *item}
+  Append the object \var{item} at the end of list \var{list}.
+  Return \code{0} if successful; return \code{-1} and set an
+  exception if unsuccessful.  Analogous to
+  \code{\var{list}.append(\var{item})}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyList_GetSlice}{PyObject *list,
+                                              Py_ssize_t low, Py_ssize_t high}
+  Return a list of the objects in \var{list} containing the objects
+  \emph{between} \var{low} and \var{high}.  Return \NULL{} and set
+  an exception if unsuccessful.
+  Analogous to \code{\var{list}[\var{low}:\var{high}]}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyList_SetSlice}{PyObject *list,
+                                        Py_ssize_t low, Py_ssize_t high,
+                                        PyObject *itemlist}
+  Set the slice of \var{list} between \var{low} and \var{high} to the
+  contents of \var{itemlist}.  Analogous to
+  \code{\var{list}[\var{low}:\var{high}] = \var{itemlist}}.
+  The \var{itemlist} may be \NULL{}, indicating the assignment
+  of an empty list (slice deletion).
+  Return \code{0} on success, \code{-1} on failure.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyList_Sort}{PyObject *list}
+  Sort the items of \var{list} in place.  Return \code{0} on
+  success, \code{-1} on failure.  This is equivalent to
+  \samp{\var{list}.sort()}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyList_Reverse}{PyObject *list}
+  Reverse the items of \var{list} in place.  Return \code{0} on
+  success, \code{-1} on failure.  This is the equivalent of
+  \samp{\var{list}.reverse()}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyList_AsTuple}{PyObject *list}
+  Return a new tuple object containing the contents of \var{list};
+  equivalent to \samp{tuple(\var{list})}.\bifuncindex{tuple}
+\end{cfuncdesc}
+
+
+\section{Mapping Objects \label{mapObjects}}
+
+\obindex{mapping}
+
+
+\subsection{Dictionary Objects \label{dictObjects}}
+
+\obindex{dictionary}
+\begin{ctypedesc}{PyDictObject}
+  This subtype of \ctype{PyObject} represents a Python dictionary
+  object.
+\end{ctypedesc}
+
+\begin{cvardesc}{PyTypeObject}{PyDict_Type}
+  This instance of \ctype{PyTypeObject} represents the Python
+  dictionary type.  This is exposed to Python programs as
+  \code{dict} and \code{types.DictType}.
+  \withsubitem{(in module types)}{\ttindex{DictType}\ttindex{DictionaryType}}
+\end{cvardesc}
+
+\begin{cfuncdesc}{int}{PyDict_Check}{PyObject *p}
+  Return true if \var{p} is a dict object or an instance of a
+  subtype of the dict type.
+  \versionchanged[Allowed subtypes to be accepted]{2.2}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyDict_CheckExact}{PyObject *p}
+  Return true if \var{p} is a dict object, but not an instance of a
+  subtype of the dict type.
+  \versionadded{2.4}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyDict_New}{}
+  Return a new empty dictionary, or \NULL{} on failure.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyDictProxy_New}{PyObject *dict}
+  Return a proxy object for a mapping which enforces read-only
+  behavior.  This is normally used to create a proxy to prevent
+  modification of the dictionary for non-dynamic class types.
+  \versionadded{2.2}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{PyDict_Clear}{PyObject *p}
+  Empty an existing dictionary of all key-value pairs.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyDict_Contains}{PyObject *p, PyObject *key}
+  Determine if dictionary \var{p} contains \var{key}.  If an item
+  in \var{p} is matches \var{key}, return \code{1}, otherwise return
+  \code{0}.  On error, return \code{-1}.  This is equivalent to the
+  Python expression \samp{\var{key} in \var{p}}.
+  \versionadded{2.4}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyDict_Copy}{PyObject *p}
+  Return a new dictionary that contains the same key-value pairs as
+  \var{p}.
+  \versionadded{1.6}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyDict_SetItem}{PyObject *p, PyObject *key,
+                                       PyObject *val}
+  Insert \var{value} into the dictionary \var{p} with a key of
+  \var{key}.  \var{key} must be hashable; if it isn't,
+  \exception{TypeError} will be raised.
+  Return \code{0} on success or \code{-1} on failure.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyDict_SetItemString}{PyObject *p,
+            const char *key,
+            PyObject *val}
+  Insert \var{value} into the dictionary \var{p} using \var{key} as a
+  key. \var{key} should be a \ctype{char*}.  The key object is created
+  using \code{PyString_FromString(\var{key})}. Return \code{0} on
+  success or \code{-1} on failure.
+  \ttindex{PyString_FromString()}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyDict_DelItem}{PyObject *p, PyObject *key}
+  Remove the entry in dictionary \var{p} with key \var{key}.
+  \var{key} must be hashable; if it isn't, \exception{TypeError} is
+  raised.  Return \code{0} on success or \code{-1} on failure.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyDict_DelItemString}{PyObject *p, char *key}
+  Remove the entry in dictionary \var{p} which has a key specified by
+  the string \var{key}.  Return \code{0} on success or \code{-1} on
+  failure.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyDict_GetItem}{PyObject *p, PyObject *key}
+  Return the object from dictionary \var{p} which has a key
+  \var{key}.  Return \NULL{} if the key \var{key} is not present, but
+  \emph{without} setting an exception.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyDict_GetItemString}{PyObject *p, const char *key}
+  This is the same as \cfunction{PyDict_GetItem()}, but \var{key} is
+  specified as a \ctype{char*}, rather than a \ctype{PyObject*}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyDict_Items}{PyObject *p}
+  Return a \ctype{PyListObject} containing all the items from the
+  dictionary, as in the dictionary method \method{items()} (see the
+  \citetitle[../lib/lib.html]{Python Library Reference}).
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyDict_Keys}{PyObject *p}
+  Return a \ctype{PyListObject} containing all the keys from the
+  dictionary, as in the dictionary method \method{keys()} (see the
+  \citetitle[../lib/lib.html]{Python Library Reference}).
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyDict_Values}{PyObject *p}
+  Return a \ctype{PyListObject} containing all the values from the
+  dictionary \var{p}, as in the dictionary method \method{values()}
+  (see the \citetitle[../lib/lib.html]{Python Library Reference}).
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{Py_ssize_t}{PyDict_Size}{PyObject *p}
+  Return the number of items in the dictionary.  This is equivalent
+  to \samp{len(\var{p})} on a dictionary.\bifuncindex{len}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyDict_Next}{PyObject *p, Py_ssize_t *ppos,
+                                    PyObject **pkey, PyObject **pvalue}
+  Iterate over all key-value pairs in the dictionary \var{p}.  The
+  \ctype{int} referred to by \var{ppos} must be initialized to
+  \code{0} prior to the first call to this function to start the
+  iteration; the function returns true for each pair in the
+  dictionary, and false once all pairs have been reported.  The
+  parameters \var{pkey} and \var{pvalue} should either point to
+  \ctype{PyObject*} variables that will be filled in with each key and
+  value, respectively, or may be \NULL{}.  Any references returned through
+  them are borrowed.  \var{ppos} should not be altered during iteration.
+  Its value represents offsets within the internal dictionary structure,
+  and since the structure is sparse, the offsets are not consecutive.
+
+  For example:
+
+\begin{verbatim}
+PyObject *key, *value;
+Py_ssize_t pos = 0;
+
+while (PyDict_Next(self->dict, &pos, &key, &value)) {
+    /* do something interesting with the values... */
+    ...
+}
+\end{verbatim}
+
+  The dictionary \var{p} should not be mutated during iteration.  It
+  is safe (since Python 2.1) to modify the values of the keys as you
+  iterate over the dictionary, but only so long as the set of keys
+  does not change.  For example:
+
+\begin{verbatim}
+PyObject *key, *value;
+Py_ssize_t pos = 0;
+
+while (PyDict_Next(self->dict, &pos, &key, &value)) {
+    int i = PyInt_AS_LONG(value) + 1;
+    PyObject *o = PyInt_FromLong(i);
+    if (o == NULL)
+        return -1;
+    if (PyDict_SetItem(self->dict, key, o) < 0) {
+        Py_DECREF(o);
+        return -1;
+    }
+    Py_DECREF(o);
+}
+\end{verbatim}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyDict_Merge}{PyObject *a, PyObject *b, int override}
+  Iterate over mapping object \var{b} adding key-value pairs to dictionary
+  \var{a}.
+  \var{b} may be a dictionary, or any object supporting
+  \function{PyMapping_Keys()} and \function{PyObject_GetItem()}.
+  If \var{override} is true, existing pairs in \var{a} will
+  be replaced if a matching key is found in \var{b}, otherwise pairs
+  will only be added if there is not a matching key in \var{a}.
+  Return \code{0} on success or \code{-1} if an exception was
+  raised.
+\versionadded{2.2}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyDict_Update}{PyObject *a, PyObject *b}
+  This is the same as \code{PyDict_Merge(\var{a}, \var{b}, 1)} in C,
+  or \code{\var{a}.update(\var{b})} in Python.  Return \code{0} on
+  success or \code{-1} if an exception was raised.
+  \versionadded{2.2}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyDict_MergeFromSeq2}{PyObject *a, PyObject *seq2,
+                                             int override}
+  Update or merge into dictionary \var{a}, from the key-value pairs in
+  \var{seq2}.  \var{seq2} must be an iterable object producing
+  iterable objects of length 2, viewed as key-value pairs.  In case of
+  duplicate keys, the last wins if \var{override} is true, else the
+  first wins.
+  Return \code{0} on success or \code{-1} if an exception
+  was raised.
+  Equivalent Python (except for the return value):
+
+\begin{verbatim}
+def PyDict_MergeFromSeq2(a, seq2, override):
+    for key, value in seq2:
+        if override or key not in a:
+            a[key] = value
+\end{verbatim}
+
+  \versionadded{2.2}
+\end{cfuncdesc}
+
+
+\section{Other Objects \label{otherObjects}}
+
+\subsection{File Objects \label{fileObjects}}
+
+\obindex{file}
+Python's built-in file objects are implemented entirely on the
+\ctype{FILE*} support from the C standard library.  This is an
+implementation detail and may change in future releases of Python.
+
+\begin{ctypedesc}{PyFileObject}
+  This subtype of \ctype{PyObject} represents a Python file object.
+\end{ctypedesc}
+
+\begin{cvardesc}{PyTypeObject}{PyFile_Type}
+  This instance of \ctype{PyTypeObject} represents the Python file
+  type.  This is exposed to Python programs as \code{file} and
+  \code{types.FileType}.
+  \withsubitem{(in module types)}{\ttindex{FileType}}
+\end{cvardesc}
+
+\begin{cfuncdesc}{int}{PyFile_Check}{PyObject *p}
+  Return true if its argument is a \ctype{PyFileObject} or a subtype
+  of \ctype{PyFileObject}.
+  \versionchanged[Allowed subtypes to be accepted]{2.2}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyFile_CheckExact}{PyObject *p}
+  Return true if its argument is a \ctype{PyFileObject}, but not a
+  subtype of \ctype{PyFileObject}.
+  \versionadded{2.2}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyFile_FromString}{char *filename, char *mode}
+  On success, return a new file object that is opened on the file
+  given by \var{filename}, with a file mode given by \var{mode}, where
+  \var{mode} has the same semantics as the standard C routine
+  \cfunction{fopen()}\ttindex{fopen()}.  On failure, return \NULL{}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyFile_FromFile}{FILE *fp,
+                                              char *name, char *mode,
+                                              int (*close)(FILE*)}
+  Create a new \ctype{PyFileObject} from the already-open standard C
+  file pointer, \var{fp}.  The function \var{close} will be called
+  when the file should be closed.  Return \NULL{} on failure.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{FILE*}{PyFile_AsFile}{PyObject *p}
+  Return the file object associated with \var{p} as a \ctype{FILE*}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyFile_GetLine}{PyObject *p, int n}
+  Equivalent to \code{\var{p}.readline(\optional{\var{n}})}, this
+  function reads one line from the object \var{p}.  \var{p} may be a
+  file object or any object with a \method{readline()} method.  If
+  \var{n} is \code{0}, exactly one line is read, regardless of the
+  length of the line.  If \var{n} is greater than \code{0}, no more
+  than \var{n} bytes will be read from the file; a partial line can be
+  returned.  In both cases, an empty string is returned if the end of
+  the file is reached immediately.  If \var{n} is less than \code{0},
+  however, one line is read regardless of length, but
+  \exception{EOFError} is raised if the end of the file is reached
+  immediately.
+  \withsubitem{(built-in exception)}{\ttindex{EOFError}}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyFile_Name}{PyObject *p}
+  Return the name of the file specified by \var{p} as a string
+  object.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{PyFile_SetBufSize}{PyFileObject *p, int n}
+  Available on systems with \cfunction{setvbuf()}\ttindex{setvbuf()}
+  only.  This should only be called immediately after file object
+  creation.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyFile_Encoding}{PyFileObject *p, char *enc}
+  Set the file's encoding for Unicode output to \var{enc}. Return
+  1 on success and 0 on failure.
+  \versionadded{2.3}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyFile_SoftSpace}{PyObject *p, int newflag}
+  This function exists for internal use by the interpreter.  Set the
+  \member{softspace} attribute of \var{p} to \var{newflag} and
+  \withsubitem{(file attribute)}{\ttindex{softspace}}return the
+  previous value.  \var{p} does not have to be a file object for this
+  function to work properly; any object is supported (thought its only
+  interesting if the \member{softspace} attribute can be set).  This
+  function clears any errors, and will return \code{0} as the previous
+  value if the attribute either does not exist or if there were errors
+  in retrieving it.  There is no way to detect errors from this
+  function, but doing so should not be needed.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyFile_WriteObject}{PyObject *obj, PyObject *p,
+                                           int flags}
+  Write object \var{obj} to file object \var{p}.  The only supported
+  flag for \var{flags} is
+  \constant{Py_PRINT_RAW}\ttindex{Py_PRINT_RAW}; if given, the
+  \function{str()} of the object is written instead of the
+  \function{repr()}.  Return \code{0} on success or \code{-1} on
+  failure; the appropriate exception will be set.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyFile_WriteString}{const char *s, PyObject *p}
+  Write string \var{s} to file object \var{p}.  Return \code{0} on
+  success or \code{-1} on failure; the appropriate exception will be
+  set.
+\end{cfuncdesc}
+
+
+\subsection{Instance Objects \label{instanceObjects}}
+
+\obindex{instance}
+There are very few functions specific to instance objects.
+
+\begin{cvardesc}{PyTypeObject}{PyInstance_Type}
+  Type object for class instances.
+\end{cvardesc}
+
+\begin{cfuncdesc}{int}{PyInstance_Check}{PyObject *obj}
+  Return true if \var{obj} is an instance.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyInstance_New}{PyObject *class,
+                                             PyObject *arg,
+                                             PyObject *kw}
+  Create a new instance of a specific class.  The parameters \var{arg}
+  and \var{kw} are used as the positional and keyword parameters to
+  the object's constructor.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyInstance_NewRaw}{PyObject *class,
+                                                PyObject *dict}
+  Create a new instance of a specific class without calling its
+  constructor.  \var{class} is the class of new object.  The
+  \var{dict} parameter will be used as the object's \member{__dict__};
+  if \NULL{}, a new dictionary will be created for the instance.
+\end{cfuncdesc}
+
+
+\subsection{Function Objects \label{function-objects}}
+
+\obindex{function}
+There are a few functions specific to Python functions.
+
+\begin{ctypedesc}{PyFunctionObject}
+  The C structure used for functions.
+\end{ctypedesc}
+
+\begin{cvardesc}{PyTypeObject}{PyFunction_Type}
+  This is an instance of \ctype{PyTypeObject} and represents the
+  Python function type.  It is exposed to Python programmers as
+  \code{types.FunctionType}.
+  \withsubitem{(in module types)}{\ttindex{MethodType}}
+\end{cvardesc}
+
+\begin{cfuncdesc}{int}{PyFunction_Check}{PyObject *o}
+  Return true if \var{o} is a function object (has type
+  \cdata{PyFunction_Type}).  The parameter must not be \NULL{}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyFunction_New}{PyObject *code,
+                                             PyObject *globals}
+  Return a new function object associated with the code object
+  \var{code}. \var{globals} must be a dictionary with the global
+  variables accessible to the function.
+
+  The function's docstring, name and \var{__module__} are retrieved
+  from the code object, the argument defaults and closure are set to
+  \NULL{}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyFunction_GetCode}{PyObject *op}
+  Return the code object associated with the function object \var{op}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyFunction_GetGlobals}{PyObject *op}
+  Return the globals dictionary associated with the function object
+  \var{op}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyFunction_GetModule}{PyObject *op}
+  Return the \var{__module__} attribute of the function object \var{op}.
+  This is normally a string containing the module name, but can be set
+  to any other object by Python code.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyFunction_GetDefaults}{PyObject *op}
+  Return the argument default values of the function object \var{op}.
+  This can be a tuple of arguments or \NULL{}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyFunction_SetDefaults}{PyObject *op,
+                                               PyObject *defaults}
+  Set the argument default values for the function object \var{op}.
+  \var{defaults} must be \var{Py_None} or a tuple.
+
+  Raises \exception{SystemError} and returns \code{-1} on failure.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyFunction_GetClosure}{PyObject *op}
+  Return the closure associated with the function object \var{op}.
+  This can be \NULL{} or a tuple of cell objects.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyFunction_SetClosure}{PyObject *op,
+                                              PyObject *closure}
+  Set the closure associated with the function object \var{op}.
+  \var{closure} must be \var{Py_None} or a tuple of cell objects.
+
+  Raises \exception{SystemError} and returns \code{-1} on failure.
+\end{cfuncdesc}
+
+
+\subsection{Method Objects \label{method-objects}}
+
+\obindex{method}
+There are some useful functions that are useful for working with
+method objects.
+
+\begin{cvardesc}{PyTypeObject}{PyMethod_Type}
+  This instance of \ctype{PyTypeObject} represents the Python method
+  type.  This is exposed to Python programs as \code{types.MethodType}.
+  \withsubitem{(in module types)}{\ttindex{MethodType}}
+\end{cvardesc}
+
+\begin{cfuncdesc}{int}{PyMethod_Check}{PyObject *o}
+  Return true if \var{o} is a method object (has type
+  \cdata{PyMethod_Type}).  The parameter must not be \NULL{}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyMethod_New}{PyObject *func,
+                                           PyObject *self, PyObject *class}
+  Return a new method object, with \var{func} being any callable
+  object; this is the function that will be called when the method is
+  called.  If this method should be bound to an instance, \var{self}
+  should be the instance and \var{class} should be the class of
+  \var{self}, otherwise \var{self} should be \NULL{} and \var{class}
+  should be the class which provides the unbound method..
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyMethod_Class}{PyObject *meth}
+  Return the class object from which the method \var{meth} was
+  created; if this was created from an instance, it will be the class
+  of the instance.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyMethod_GET_CLASS}{PyObject *meth}
+  Macro version of \cfunction{PyMethod_Class()} which avoids error
+  checking.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyMethod_Function}{PyObject *meth}
+  Return the function object associated with the method \var{meth}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyMethod_GET_FUNCTION}{PyObject *meth}
+  Macro version of \cfunction{PyMethod_Function()} which avoids error
+  checking.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyMethod_Self}{PyObject *meth}
+  Return the instance associated with the method \var{meth} if it is
+  bound, otherwise return \NULL{}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyMethod_GET_SELF}{PyObject *meth}
+  Macro version of \cfunction{PyMethod_Self()} which avoids error
+  checking.
+\end{cfuncdesc}
+
+
+\subsection{Module Objects \label{moduleObjects}}
+
+\obindex{module}
+There are only a few functions special to module objects.
+
+\begin{cvardesc}{PyTypeObject}{PyModule_Type}
+  This instance of \ctype{PyTypeObject} represents the Python module
+  type.  This is exposed to Python programs as
+  \code{types.ModuleType}.
+  \withsubitem{(in module types)}{\ttindex{ModuleType}}
+\end{cvardesc}
+
+\begin{cfuncdesc}{int}{PyModule_Check}{PyObject *p}
+  Return true if \var{p} is a module object, or a subtype of a module
+  object.
+  \versionchanged[Allowed subtypes to be accepted]{2.2}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyModule_CheckExact}{PyObject *p}
+  Return true if \var{p} is a module object, but not a subtype of
+  \cdata{PyModule_Type}.
+  \versionadded{2.2}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyModule_New}{const char *name}
+  Return a new module object with the \member{__name__} attribute set
+  to \var{name}.  Only the module's \member{__doc__} and
+  \member{__name__} attributes are filled in; the caller is
+  responsible for providing a \member{__file__} attribute.
+  \withsubitem{(module attribute)}{
+    \ttindex{__name__}\ttindex{__doc__}\ttindex{__file__}}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyModule_GetDict}{PyObject *module}
+  Return the dictionary object that implements \var{module}'s
+  namespace; this object is the same as the \member{__dict__}
+  attribute of the module object.  This function never fails.
+  \withsubitem{(module attribute)}{\ttindex{__dict__}}
+  It is recommended extensions use other \cfunction{PyModule_*()}
+  and \cfunction{PyObject_*()} functions rather than directly
+  manipulate a module's \member{__dict__}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{char*}{PyModule_GetName}{PyObject *module}
+  Return \var{module}'s \member{__name__} value.  If the module does
+  not provide one, or if it is not a string, \exception{SystemError}
+  is raised and \NULL{} is returned.
+  \withsubitem{(module attribute)}{\ttindex{__name__}}
+  \withsubitem{(built-in exception)}{\ttindex{SystemError}}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{char*}{PyModule_GetFilename}{PyObject *module}
+  Return the name of the file from which \var{module} was loaded using
+  \var{module}'s \member{__file__} attribute.  If this is not defined,
+  or if it is not a string, raise \exception{SystemError} and return
+  \NULL{}.
+  \withsubitem{(module attribute)}{\ttindex{__file__}}
+  \withsubitem{(built-in exception)}{\ttindex{SystemError}}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyModule_AddObject}{PyObject *module,
+                                           const char *name, PyObject *value}
+  Add an object to \var{module} as \var{name}.  This is a convenience
+  function which can be used from the module's initialization
+  function.  This steals a reference to \var{value}.  Return
+  \code{-1} on error, \code{0} on success.
+  \versionadded{2.0}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyModule_AddIntConstant}{PyObject *module,
+                                                const char *name, long value}
+  Add an integer constant to \var{module} as \var{name}.  This
+  convenience function can be used from the module's initialization
+  function. Return \code{-1} on error, \code{0} on success.
+  \versionadded{2.0}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyModule_AddStringConstant}{PyObject *module,
+                                                   const char *name, const char *value}
+  Add a string constant to \var{module} as \var{name}.  This
+  convenience function can be used from the module's initialization
+  function.  The string \var{value} must be null-terminated.  Return
+  \code{-1} on error, \code{0} on success.
+  \versionadded{2.0}
+\end{cfuncdesc}
+
+
+\subsection{Iterator Objects \label{iterator-objects}}
+
+Python provides two general-purpose iterator objects.  The first, a
+sequence iterator, works with an arbitrary sequence supporting the
+\method{__getitem__()} method.  The second works with a callable
+object and a sentinel value, calling the callable for each item in the
+sequence, and ending the iteration when the sentinel value is
+returned.
+
+\begin{cvardesc}{PyTypeObject}{PySeqIter_Type}
+  Type object for iterator objects returned by
+  \cfunction{PySeqIter_New()} and the one-argument form of the
+  \function{iter()} built-in function for built-in sequence types.
+  \versionadded{2.2}
+\end{cvardesc}
+
+\begin{cfuncdesc}{int}{PySeqIter_Check}{op}
+  Return true if the type of \var{op} is \cdata{PySeqIter_Type}.
+  \versionadded{2.2}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PySeqIter_New}{PyObject *seq}
+  Return an iterator that works with a general sequence object,
+  \var{seq}.  The iteration ends when the sequence raises
+  \exception{IndexError} for the subscripting operation.
+  \versionadded{2.2}
+\end{cfuncdesc}
+
+\begin{cvardesc}{PyTypeObject}{PyCallIter_Type}
+  Type object for iterator objects returned by
+  \cfunction{PyCallIter_New()} and the two-argument form of the
+  \function{iter()} built-in function.
+  \versionadded{2.2}
+\end{cvardesc}
+
+\begin{cfuncdesc}{int}{PyCallIter_Check}{op}
+  Return true if the type of \var{op} is \cdata{PyCallIter_Type}.
+  \versionadded{2.2}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyCallIter_New}{PyObject *callable,
+                                             PyObject *sentinel}
+  Return a new iterator.  The first parameter, \var{callable}, can be
+  any Python callable object that can be called with no parameters;
+  each call to it should return the next item in the iteration.  When
+  \var{callable} returns a value equal to \var{sentinel}, the
+  iteration will be terminated.
+  \versionadded{2.2}
+\end{cfuncdesc}
+
+
+\subsection{Descriptor Objects \label{descriptor-objects}}
+
+``Descriptors'' are objects that describe some attribute of an object.
+They are found in the dictionary of type objects.
+
+\begin{cvardesc}{PyTypeObject}{PyProperty_Type}
+  The type object for the built-in descriptor types.
+  \versionadded{2.2}
+\end{cvardesc}
+
+\begin{cfuncdesc}{PyObject*}{PyDescr_NewGetSet}{PyTypeObject *type,
+					        struct PyGetSetDef *getset}
+  \versionadded{2.2}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyDescr_NewMember}{PyTypeObject *type,
+					        struct PyMemberDef *meth}
+  \versionadded{2.2}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyDescr_NewMethod}{PyTypeObject *type,
+                                                struct PyMethodDef *meth}
+  \versionadded{2.2}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyDescr_NewWrapper}{PyTypeObject *type,
+						 struct wrapperbase *wrapper,
+                                                 void *wrapped}
+  \versionadded{2.2}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyDescr_NewClassMethod}{PyTypeObject *type,
+						     PyMethodDef *method}
+  \versionadded{2.3}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyDescr_IsData}{PyObject *descr}
+  Return true if the descriptor objects \var{descr} describes a data
+  attribute, or false if it describes a method.  \var{descr} must be a
+  descriptor object; there is no error checking.
+  \versionadded{2.2}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyWrapper_New}{PyObject *, PyObject *}
+  \versionadded{2.2}
+\end{cfuncdesc}
+
+
+\subsection{Slice Objects \label{slice-objects}}
+
+\begin{cvardesc}{PyTypeObject}{PySlice_Type}
+  The type object for slice objects.  This is the same as
+  \code{slice} and \code{types.SliceType}.
+  \withsubitem{(in module types)}{\ttindex{SliceType}}
+\end{cvardesc}
+
+\begin{cfuncdesc}{int}{PySlice_Check}{PyObject *ob}
+  Return true if \var{ob} is a slice object; \var{ob} must not be
+  \NULL{}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PySlice_New}{PyObject *start, PyObject *stop,
+                                          PyObject *step}
+  Return a new slice object with the given values.  The \var{start},
+  \var{stop}, and \var{step} parameters are used as the values of the
+  slice object attributes of the same names.  Any of the values may be
+  \NULL{}, in which case the \code{None} will be used for the
+  corresponding attribute.  Return \NULL{} if the new object could
+  not be allocated.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PySlice_GetIndices}{PySliceObject *slice, Py_ssize_t length,
+                                           Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step}
+Retrieve the start, stop and step indices from the slice object
+\var{slice}, assuming a sequence of length \var{length}. Treats
+indices greater than \var{length} as errors.
+
+Returns 0 on success and -1 on error with no exception set (unless one
+of the indices was not \constant{None} and failed to be converted to
+an integer, in which case -1 is returned with an exception set).
+
+You probably do not want to use this function.  If you want to use
+slice objects in versions of Python prior to 2.3, you would probably
+do well to incorporate the source of \cfunction{PySlice_GetIndicesEx},
+suitably renamed, in the source of your extension.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PySlice_GetIndicesEx}{PySliceObject *slice, Py_ssize_t length,
+                                             Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step,
+                                             Py_ssize_t *slicelength}
+Usable replacement for \cfunction{PySlice_GetIndices}.  Retrieve the
+start, stop, and step indices from the slice object \var{slice}
+assuming a sequence of length \var{length}, and store the length of
+the slice in \var{slicelength}.  Out of bounds indices are clipped in
+a manner consistent with the handling of normal slices.
+
+Returns 0 on success and -1 on error with exception set.
+
+\versionadded{2.3}
+\end{cfuncdesc}
+
+
+\subsection{Weak Reference Objects \label{weakref-objects}}
+
+Python supports \emph{weak references} as first-class objects.  There
+are two specific object types which directly implement weak
+references.  The first is a simple reference object, and the second
+acts as a proxy for the original object as much as it can.
+
+\begin{cfuncdesc}{int}{PyWeakref_Check}{ob}
+  Return true if \var{ob} is either a reference or proxy object.
+  \versionadded{2.2}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyWeakref_CheckRef}{ob}
+  Return true if \var{ob} is a reference object.
+  \versionadded{2.2}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyWeakref_CheckProxy}{ob}
+  Return true if \var{ob} is a proxy object.
+  \versionadded{2.2}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyWeakref_NewRef}{PyObject *ob,
+                                               PyObject *callback}
+  Return a weak reference object for the object \var{ob}.  This will
+  always return a new reference, but is not guaranteed to create a new
+  object; an existing reference object may be returned.  The second
+  parameter, \var{callback}, can be a callable object that receives
+  notification when \var{ob} is garbage collected; it should accept a
+  single parameter, which will be the weak reference object itself.
+  \var{callback} may also be \code{None} or \NULL{}.  If \var{ob}
+  is not a weakly-referencable object, or if \var{callback} is not
+  callable, \code{None}, or \NULL{}, this will return \NULL{} and
+  raise \exception{TypeError}.
+  \versionadded{2.2}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyWeakref_NewProxy}{PyObject *ob,
+                                                 PyObject *callback}
+  Return a weak reference proxy object for the object \var{ob}.  This
+  will always return a new reference, but is not guaranteed to create
+  a new object; an existing proxy object may be returned.  The second
+  parameter, \var{callback}, can be a callable object that receives
+  notification when \var{ob} is garbage collected; it should accept a
+  single parameter, which will be the weak reference object itself.
+  \var{callback} may also be \code{None} or \NULL{}.  If \var{ob} is not
+  a weakly-referencable object, or if \var{callback} is not callable,
+  \code{None}, or \NULL{}, this will return \NULL{} and raise
+  \exception{TypeError}.
+  \versionadded{2.2}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyWeakref_GetObject}{PyObject *ref}
+  Return the referenced object from a weak reference, \var{ref}.  If
+  the referent is no longer live, returns \code{None}.
+  \versionadded{2.2}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyWeakref_GET_OBJECT}{PyObject *ref}
+  Similar to \cfunction{PyWeakref_GetObject()}, but implemented as a
+  macro that does no error checking.
+  \versionadded{2.2}
+\end{cfuncdesc}
+
+
+\subsection{CObjects \label{cObjects}}
+
+\obindex{CObject}
+Refer to \emph{Extending and Embedding the Python Interpreter},
+section~1.12, ``Providing a C API for an Extension Module,'' for more
+information on using these objects.
+
+
+\begin{ctypedesc}{PyCObject}
+  This subtype of \ctype{PyObject} represents an opaque value, useful
+  for C extension modules who need to pass an opaque value (as a
+  \ctype{void*} pointer) through Python code to other C code.  It is
+  often used to make a C function pointer defined in one module
+  available to other modules, so the regular import mechanism can be
+  used to access C APIs defined in dynamically loaded modules.
+\end{ctypedesc}
+
+\begin{cfuncdesc}{int}{PyCObject_Check}{PyObject *p}
+  Return true if its argument is a \ctype{PyCObject}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyCObject_FromVoidPtr}{void* cobj,
+                                                    void (*destr)(void *)}
+  Create a \ctype{PyCObject} from the \code{void *}\var{cobj}.  The
+  \var{destr} function will be called when the object is reclaimed,
+  unless it is \NULL{}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyCObject_FromVoidPtrAndDesc}{void* cobj,
+	                          void* desc, void (*destr)(void *, void *)}
+  Create a \ctype{PyCObject} from the \ctype{void *}\var{cobj}.  The
+  \var{destr} function will be called when the object is reclaimed.
+  The \var{desc} argument can be used to pass extra callback data for
+  the destructor function.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void*}{PyCObject_AsVoidPtr}{PyObject* self}
+  Return the object \ctype{void *} that the \ctype{PyCObject}
+  \var{self} was created with.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void*}{PyCObject_GetDesc}{PyObject* self}
+  Return the description \ctype{void *} that the \ctype{PyCObject}
+  \var{self} was created with.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyCObject_SetVoidPtr}{PyObject* self, void* cobj}
+  Set the void pointer inside \var{self} to \var{cobj}.
+  The \ctype{PyCObject} must not have an associated destructor.
+  Return true on success, false on failure.
+\end{cfuncdesc}
+
+
+\subsection{Cell Objects \label{cell-objects}}
+
+``Cell'' objects are used to implement variables referenced by
+multiple scopes.  For each such variable, a cell object is created to
+store the value; the local variables of each stack frame that
+references the value contains a reference to the cells from outer
+scopes which also use that variable.  When the value is accessed, the
+value contained in the cell is used instead of the cell object
+itself.  This de-referencing of the cell object requires support from
+the generated byte-code; these are not automatically de-referenced
+when accessed.  Cell objects are not likely to be useful elsewhere.
+
+\begin{ctypedesc}{PyCellObject}
+  The C structure used for cell objects.
+\end{ctypedesc}
+
+\begin{cvardesc}{PyTypeObject}{PyCell_Type}
+  The type object corresponding to cell objects.
+\end{cvardesc}
+
+\begin{cfuncdesc}{int}{PyCell_Check}{ob}
+  Return true if \var{ob} is a cell object; \var{ob} must not be
+  \NULL{}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyCell_New}{PyObject *ob}
+  Create and return a new cell object containing the value \var{ob}.
+  The parameter may be \NULL{}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyCell_Get}{PyObject *cell}
+  Return the contents of the cell \var{cell}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyCell_GET}{PyObject *cell}
+  Return the contents of the cell \var{cell}, but without checking
+  that \var{cell} is non-\NULL{} and a cell object.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyCell_Set}{PyObject *cell, PyObject *value}
+  Set the contents of the cell object \var{cell} to \var{value}.  This
+  releases the reference to any current content of the cell.
+  \var{value} may be \NULL{}.  \var{cell} must be non-\NULL{}; if it is
+  not a cell object, \code{-1} will be returned.  On success, \code{0}
+  will be returned.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{PyCell_SET}{PyObject *cell, PyObject *value}
+  Sets the value of the cell object \var{cell} to \var{value}.  No
+  reference counts are adjusted, and no checks are made for safety;
+  \var{cell} must be non-\NULL{} and must be a cell object.
+\end{cfuncdesc}
+
+
+\subsection{Generator Objects \label{gen-objects}}
+
+Generator objects are what Python uses to implement generator iterators.
+They are normally created by iterating over a function that yields values,
+rather than explicitly calling \cfunction{PyGen_New}.
+
+\begin{ctypedesc}{PyGenObject}
+  The C structure used for generator objects.
+\end{ctypedesc}
+
+\begin{cvardesc}{PyTypeObject}{PyGen_Type}
+  The type object corresponding to generator objects
+\end{cvardesc}
+
+\begin{cfuncdesc}{int}{PyGen_Check}{ob}
+  Return true if \var{ob} is a generator object; \var{ob} must not be
+  \NULL{}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyGen_CheckExact}{ob}
+  Return true if \var{ob}'s type is \var{PyGen_Type}
+  is a generator object; \var{ob} must not be
+  \NULL{}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyGen_New}{PyFrameObject *frame}
+  Create and return a new generator object based on the \var{frame} object.
+  A reference to \var{frame} is stolen by this function.
+  The parameter must not be \NULL{}.
+\end{cfuncdesc}
+
+
+\subsection{DateTime Objects \label{datetime-objects}}
+
+Various date and time objects are supplied by the \module{datetime}
+module.  Before using any of these functions, the header file
+\file{datetime.h} must be included in your source (note that this is
+not included by \file{Python.h}), and the macro
+\cfunction{PyDateTime_IMPORT} must be invoked.  The macro puts a
+pointer to a C structure into a static variable, 
+\code{PyDateTimeAPI}, that is used by the following macros.
+
+Type-check macros:
+
+\begin{cfuncdesc}{int}{PyDate_Check}{PyObject *ob}
+  Return true if \var{ob} is of type \cdata{PyDateTime_DateType} or
+  a subtype of \cdata{PyDateTime_DateType}.  \var{ob} must not be
+  \NULL{}.
+  \versionadded{2.4}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyDate_CheckExact}{PyObject *ob}
+  Return true if \var{ob} is of type \cdata{PyDateTime_DateType}.
+  \var{ob} must not be \NULL{}.
+  \versionadded{2.4}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyDateTime_Check}{PyObject *ob}
+  Return true if \var{ob} is of type \cdata{PyDateTime_DateTimeType} or
+  a subtype of \cdata{PyDateTime_DateTimeType}.  \var{ob} must not be
+  \NULL{}.
+  \versionadded{2.4}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyDateTime_CheckExact}{PyObject *ob}
+  Return true if \var{ob} is of type \cdata{PyDateTime_DateTimeType}.
+  \var{ob} must not be \NULL{}.
+  \versionadded{2.4}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyTime_Check}{PyObject *ob}
+  Return true if \var{ob} is of type \cdata{PyDateTime_TimeType} or
+  a subtype of \cdata{PyDateTime_TimeType}.  \var{ob} must not be
+  \NULL{}.
+  \versionadded{2.4}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyTime_CheckExact}{PyObject *ob}
+  Return true if \var{ob} is of type \cdata{PyDateTime_TimeType}.
+  \var{ob} must not be \NULL{}.
+  \versionadded{2.4}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyDelta_Check}{PyObject *ob}
+  Return true if \var{ob} is of type \cdata{PyDateTime_DeltaType} or
+  a subtype of \cdata{PyDateTime_DeltaType}.  \var{ob} must not be
+  \NULL{}.
+  \versionadded{2.4}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyDelta_CheckExact}{PyObject *ob}
+  Return true if \var{ob} is of type \cdata{PyDateTime_DeltaType}.
+  \var{ob} must not be \NULL{}.
+  \versionadded{2.4}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyTZInfo_Check}{PyObject *ob}
+  Return true if \var{ob} is of type \cdata{PyDateTime_TZInfoType} or
+  a subtype of \cdata{PyDateTime_TZInfoType}.  \var{ob} must not be
+  \NULL{}.
+  \versionadded{2.4}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyTZInfo_CheckExact}{PyObject *ob}
+  Return true if \var{ob} is of type \cdata{PyDateTime_TZInfoType}.
+  \var{ob} must not be \NULL{}.
+  \versionadded{2.4}
+\end{cfuncdesc}
+
+Macros to create objects:
+
+\begin{cfuncdesc}{PyObject*}{PyDate_FromDate}{int year, int month, int day}
+  Return a \code{datetime.date} object with the specified year, month
+  and day.
+  \versionadded{2.4}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyDateTime_FromDateAndTime}{int year, int month,
+        int day, int hour, int minute, int second, int usecond}
+  Return a \code{datetime.datetime} object with the specified year, month,
+  day, hour, minute, second and microsecond.
+  \versionadded{2.4}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyTime_FromTime}{int hour, int minute,
+        int second, int usecond}
+  Return a \code{datetime.time} object with the specified hour, minute,
+  second and microsecond.
+  \versionadded{2.4}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyDelta_FromDSU}{int days, int seconds,
+        int useconds}
+  Return a \code{datetime.timedelta} object representing the given number
+  of days, seconds and microseconds.  Normalization is performed so that
+  the resulting number of microseconds and seconds lie in the ranges
+  documented for \code{datetime.timedelta} objects.
+  \versionadded{2.4}
+\end{cfuncdesc}
+
+Macros to extract fields from date objects.  The argument must be an
+instance of \cdata{PyDateTime_Date}, including subclasses (such as
+\cdata{PyDateTime_DateTime}).  The argument must not be \NULL{}, and
+the type is not checked:
+
+\begin{cfuncdesc}{int}{PyDateTime_GET_YEAR}{PyDateTime_Date *o}
+  Return the year, as a positive int.
+  \versionadded{2.4}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyDateTime_GET_MONTH}{PyDateTime_Date *o}
+  Return the month, as an int from 1 through 12.
+  \versionadded{2.4}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyDateTime_GET_DAY}{PyDateTime_Date *o}
+  Return the day, as an int from 1 through 31.
+  \versionadded{2.4}
+\end{cfuncdesc}
+
+Macros to extract fields from datetime objects.  The argument must be an
+instance of \cdata{PyDateTime_DateTime}, including subclasses.
+The argument must not be \NULL{}, and the type is not checked:
+
+\begin{cfuncdesc}{int}{PyDateTime_DATE_GET_HOUR}{PyDateTime_DateTime *o}
+  Return the hour, as an int from 0 through 23.
+  \versionadded{2.4}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyDateTime_DATE_GET_MINUTE}{PyDateTime_DateTime *o}
+  Return the minute, as an int from 0 through 59.
+  \versionadded{2.4}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyDateTime_DATE_GET_SECOND}{PyDateTime_DateTime *o}
+  Return the second, as an int from 0 through 59.
+  \versionadded{2.4}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyDateTime_DATE_GET_MICROSECOND}{PyDateTime_DateTime *o}
+  Return the microsecond, as an int from 0 through 999999.
+  \versionadded{2.4}
+\end{cfuncdesc}
+
+Macros to extract fields from time objects.  The argument must be an
+instance of \cdata{PyDateTime_Time}, including subclasses.
+The argument must not be \NULL{}, and the type is not checked:
+
+\begin{cfuncdesc}{int}{PyDateTime_TIME_GET_HOUR}{PyDateTime_Time *o}
+  Return the hour, as an int from 0 through 23.
+  \versionadded{2.4}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyDateTime_TIME_GET_MINUTE}{PyDateTime_Time *o}
+  Return the minute, as an int from 0 through 59.
+  \versionadded{2.4}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyDateTime_TIME_GET_SECOND}{PyDateTime_Time *o}
+  Return the second, as an int from 0 through 59.
+  \versionadded{2.4}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyDateTime_TIME_GET_MICROSECOND}{PyDateTime_Time *o}
+  Return the microsecond, as an int from 0 through 999999.
+  \versionadded{2.4}
+\end{cfuncdesc}
+
+Macros for the convenience of modules implementing the DB API:
+
+\begin{cfuncdesc}{PyObject*}{PyDateTime_FromTimestamp}{PyObject *args}
+  Create and return a new \code{datetime.datetime} object given an argument
+  tuple suitable for passing to \code{datetime.datetime.fromtimestamp()}.
+  \versionadded{2.4}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyDate_FromTimestamp}{PyObject *args}
+  Create and return a new \code{datetime.date} object given an argument
+  tuple suitable for passing to \code{datetime.date.fromtimestamp()}.
+  \versionadded{2.4}
+\end{cfuncdesc}
+
+
+\subsection{Set Objects \label{setObjects}}
+\sectionauthor{Raymond D. Hettinger}{python at rcn.com}
+
+\obindex{set}
+\obindex{frozenset}
+\versionadded{2.5}
+
+This section details the public API for \class{set} and \class{frozenset}
+objects.  Any functionality not listed below is best accessed using the
+either the abstract object protocol (including
+\cfunction{PyObject_CallMethod()}, \cfunction{PyObject_RichCompareBool()},
+\cfunction{PyObject_Hash()}, \cfunction{PyObject_Repr()},
+\cfunction{PyObject_IsTrue()}, \cfunction{PyObject_Print()}, and
+\cfunction{PyObject_GetIter()})
+or the abstract number protocol (including
+\cfunction{PyNumber_Add()}, \cfunction{PyNumber_Subtract()},
+\cfunction{PyNumber_Or()}, \cfunction{PyNumber_Xor()},
+\cfunction{PyNumber_InPlaceAdd()}, \cfunction{PyNumber_InPlaceSubtract()},
+\cfunction{PyNumber_InPlaceOr()}, and \cfunction{PyNumber_InPlaceXor()}).
+
+\begin{ctypedesc}{PySetObject}
+  This subtype of \ctype{PyObject} is used to hold the internal data for
+  both \class{set} and \class{frozenset} objects.  It is like a
+  \ctype{PyDictObject} in that it is a fixed size for small sets
+  (much like tuple storage) and will point to a separate, variable sized
+  block of memory for medium and large sized sets (much like list storage).
+  None of the fields of this structure should be considered public and
+  are subject to change.  All access should be done through the
+  documented API rather than by manipulating the values in the structure.
+
+\end{ctypedesc}
+
+\begin{cvardesc}{PyTypeObject}{PySet_Type}
+  This is an instance of \ctype{PyTypeObject} representing the Python
+  \class{set} type.
+\end{cvardesc}
+
+\begin{cvardesc}{PyTypeObject}{PyFrozenSet_Type}
+  This is an instance of \ctype{PyTypeObject} representing the Python
+  \class{frozenset} type.
+\end{cvardesc}
+
+
+The following type check macros work on pointers to any Python object.
+Likewise, the constructor functions work with any iterable Python object.
+
+\begin{cfuncdesc}{int}{PyAnySet_Check}{PyObject *p}
+  Return true if \var{p} is a \class{set} object, a \class{frozenset}
+  object, or an instance of a subtype.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyAnySet_CheckExact}{PyObject *p}
+  Return true if \var{p} is a \class{set} object or a \class{frozenset}
+  object but not an instance of a subtype.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyFrozenSet_CheckExact}{PyObject *p}
+  Return true if \var{p} is a \class{frozenset} object
+  but not an instance of a subtype.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PySet_New}{PyObject *iterable}
+  Return a new \class{set} containing objects returned by the
+  \var{iterable}.  The \var{iterable} may be \NULL{} to create a
+  new empty set.  Return the new set on success or \NULL{} on
+  failure.  Raise \exception{TypeError} if \var{iterable} is
+  not actually iterable.  The constructor is also useful for
+  copying a set (\code{c=set(s)}).
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyFrozenSet_New}{PyObject *iterable}
+  Return a new \class{frozenset} containing objects returned by the
+  \var{iterable}.  The \var{iterable} may be \NULL{} to create a
+  new empty frozenset.  Return the new set on success or \NULL{} on
+  failure.  Raise \exception{TypeError} if \var{iterable} is
+  not actually iterable.
+\end{cfuncdesc}
+
+
+The following functions and macros are available for instances of
+\class{set} or \class{frozenset} or instances of their subtypes.
+
+\begin{cfuncdesc}{int}{PySet_Size}{PyObject *anyset}
+  Return the length of a \class{set} or \class{frozenset} object.
+  Equivalent to \samp{len(\var{anyset})}.  Raises a
+  \exception{PyExc_SystemError} if \var{anyset} is not a \class{set},
+  \class{frozenset}, or an instance of a subtype.
+  \bifuncindex{len}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PySet_GET_SIZE}{PyObject *anyset}
+  Macro form of \cfunction{PySet_Size()} without error checking.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PySet_Contains}{PyObject *anyset, PyObject *key}
+  Return 1 if found, 0 if not found, and -1 if an error is
+  encountered.  Unlike the Python \method{__contains__()} method, this
+  function does not automatically convert unhashable sets into temporary
+  frozensets.  Raise a \exception{TypeError} if the \var{key} is unhashable.
+  Raise \exception{PyExc_SystemError} if \var{anyset} is not a \class{set},
+  \class{frozenset}, or an instance of a subtype.
+\end{cfuncdesc}
+
+The following functions are available for instances of \class{set} or
+its subtypes but not for instances of \class{frozenset} or its subtypes.
+
+\begin{cfuncdesc}{int}{PySet_Add}{PyObject *set, PyObject *key}
+  Add \var{key} to a \class{set} instance.  Does not apply to
+  \class{frozenset} instances.  Return 0 on success or -1 on failure.
+  Raise a \exception{TypeError} if the \var{key} is unhashable.
+  Raise a \exception{MemoryError} if there is no room to grow.
+  Raise a \exception{SystemError} if \var{set} is an not an instance
+  of \class{set} or its subtype.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PySet_Discard}{PyObject *set, PyObject *key}
+  Return 1 if found and removed, 0 if not found (no action taken),
+  and -1 if an error is encountered.  Does not raise \exception{KeyError}
+  for missing keys.  Raise a \exception{TypeError} if the \var{key} is
+  unhashable.  Unlike the Python \method{discard()} method, this function
+  does not automatically convert unhashable sets into temporary frozensets.
+  Raise \exception{PyExc_SystemError} if \var{set} is an not an instance
+  of \class{set} or its subtype.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PySet_Pop}{PyObject *set}
+  Return a new reference to an arbitrary object in the \var{set},
+  and removes the object from the \var{set}.  Return \NULL{} on
+  failure.  Raise \exception{KeyError} if the set is empty.
+  Raise a \exception{SystemError} if \var{set} is an not an instance
+  of \class{set} or its subtype.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PySet_Clear}{PyObject *set}
+  Empty an existing set of all elements.
+\end{cfuncdesc}

Added: vendor/Python/current/Doc/api/exceptions.tex
===================================================================
--- vendor/Python/current/Doc/api/exceptions.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/api/exceptions.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,442 @@
+\chapter{Exception Handling \label{exceptionHandling}}
+
+The functions described in this chapter will let you handle and raise Python
+exceptions.  It is important to understand some of the basics of
+Python exception handling.  It works somewhat like the
+\UNIX{} \cdata{errno} variable: there is a global indicator (per
+thread) of the last error that occurred.  Most functions don't clear
+this on success, but will set it to indicate the cause of the error on
+failure.  Most functions also return an error indicator, usually
+\NULL{} if they are supposed to return a pointer, or \code{-1} if they
+return an integer (exception: the \cfunction{PyArg_*()} functions
+return \code{1} for success and \code{0} for failure).
+
+When a function must fail because some function it called failed, it
+generally doesn't set the error indicator; the function it called
+already set it.  It is responsible for either handling the error and
+clearing the exception or returning after cleaning up any resources it
+holds (such as object references or memory allocations); it should
+\emph{not} continue normally if it is not prepared to handle the
+error.  If returning due to an error, it is important to indicate to
+the caller that an error has been set.  If the error is not handled or
+carefully propagated, additional calls into the Python/C API may not
+behave as intended and may fail in mysterious ways.
+
+The error indicator consists of three Python objects corresponding to
+\withsubitem{(in module sys)}{
+  \ttindex{exc_type}\ttindex{exc_value}\ttindex{exc_traceback}}
+the Python variables \code{sys.exc_type}, \code{sys.exc_value} and
+\code{sys.exc_traceback}.  API functions exist to interact with the
+error indicator in various ways.  There is a separate error indicator
+for each thread.
+
+% XXX Order of these should be more thoughtful.
+% Either alphabetical or some kind of structure.
+
+\begin{cfuncdesc}{void}{PyErr_Print}{}
+  Print a standard traceback to \code{sys.stderr} and clear the error
+  indicator.  Call this function only when the error indicator is
+  set.  (Otherwise it will cause a fatal error!)
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyErr_Occurred}{}
+  Test whether the error indicator is set.  If set, return the
+  exception \emph{type} (the first argument to the last call to one of
+  the \cfunction{PyErr_Set*()} functions or to
+  \cfunction{PyErr_Restore()}).  If not set, return \NULL.  You do
+  not own a reference to the return value, so you do not need to
+  \cfunction{Py_DECREF()} it.  \note{Do not compare the return value
+    to a specific exception; use \cfunction{PyErr_ExceptionMatches()}
+    instead, shown below.  (The comparison could easily fail since the
+    exception may be an instance instead of a class, in the case of a
+    class exception, or it may the a subclass of the expected
+    exception.)}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyErr_ExceptionMatches}{PyObject *exc}
+  Equivalent to \samp{PyErr_GivenExceptionMatches(PyErr_Occurred(),
+  \var{exc})}.  This should only be called when an exception is
+  actually set; a memory access violation will occur if no exception
+  has been raised.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyErr_GivenExceptionMatches}{PyObject *given, PyObject *exc}
+  Return true if the \var{given} exception matches the exception in
+  \var{exc}.  If \var{exc} is a class object, this also returns true
+  when \var{given} is an instance of a subclass.  If \var{exc} is a
+  tuple, all exceptions in the tuple (and recursively in subtuples)
+  are searched for a match.  If \var{given} is \NULL, a memory access
+  violation will occur.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{PyErr_NormalizeException}{PyObject**exc, PyObject**val, PyObject**tb}
+  Under certain circumstances, the values returned by
+  \cfunction{PyErr_Fetch()} below can be ``unnormalized'', meaning
+  that \code{*\var{exc}} is a class object but \code{*\var{val}} is
+  not an instance of the  same class.  This function can be used to
+  instantiate the class in that case.  If the values are already
+  normalized, nothing happens.  The delayed normalization is
+  implemented to improve performance.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{PyErr_Clear}{}
+  Clear the error indicator.  If the error indicator is not set, there
+  is no effect.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{PyErr_Fetch}{PyObject **ptype, PyObject **pvalue,
+                                     PyObject **ptraceback}
+  Retrieve the error indicator into three variables whose addresses
+  are passed.  If the error indicator is not set, set all three
+  variables to \NULL.  If it is set, it will be cleared and you own a
+  reference to each object retrieved.  The value and traceback object
+  may be \NULL{} even when the type object is not.  \note{This
+  function is normally only used by code that needs to handle
+  exceptions or by code that needs to save and restore the error
+  indicator temporarily.}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{PyErr_Restore}{PyObject *type, PyObject *value,
+                                       PyObject *traceback}
+  Set  the error indicator from the three objects.  If the error
+  indicator is already set, it is cleared first.  If the objects are
+  \NULL, the error indicator is cleared.  Do not pass a \NULL{} type
+  and non-\NULL{} value or traceback.  The exception type should be a
+  class.  Do not pass an invalid exception type or value.
+  (Violating these rules will cause subtle problems later.)  This call
+  takes away a reference to each object: you must own a reference to
+  each object before the call and after the call you no longer own
+  these references.  (If you don't understand this, don't use this
+  function.  I warned you.)  \note{This function is normally only used
+  by code that needs to save and restore the error indicator
+  temporarily; use \cfunction{PyErr_Fetch()} to save the current
+  exception state.}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{PyErr_SetString}{PyObject *type, const char *message}
+  This is the most common way to set the error indicator.  The first
+  argument specifies the exception type; it is normally one of the
+  standard exceptions, e.g. \cdata{PyExc_RuntimeError}.  You need not
+  increment its reference count.  The second argument is an error
+  message; it is converted to a string object.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{PyErr_SetObject}{PyObject *type, PyObject *value}
+  This function is similar to \cfunction{PyErr_SetString()} but lets
+  you specify an arbitrary Python object for the ``value'' of the
+  exception.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyErr_Format}{PyObject *exception,
+                                           const char *format, \moreargs}
+  This function sets the error indicator and returns \NULL.
+  \var{exception} should be a Python exception (class, not
+  an instance).  \var{format} should be a string, containing format
+  codes, similar to \cfunction{printf()}. The \code{width.precision}
+  before a format code is parsed, but the width part is ignored.
+
+  % This should be exactly the same as the table in PyString_FromFormat.
+  % One should just refer to the other.
+
+  % The descriptions for %zd and %zu are wrong, but the truth is complicated
+  % because not all compilers support the %z width modifier -- we fake it
+  % when necessary via interpolating PY_FORMAT_SIZE_T.
+
+  % %u, %lu, %zu should have "new in Python 2.5" blurbs.
+
+  \begin{tableiii}{l|l|l}{member}{Format Characters}{Type}{Comment}
+    \lineiii{\%\%}{\emph{n/a}}{The literal \% character.}
+    \lineiii{\%c}{int}{A single character, represented as an C int.}
+    \lineiii{\%d}{int}{Exactly equivalent to \code{printf("\%d")}.}
+    \lineiii{\%u}{unsigned int}{Exactly equivalent to \code{printf("\%u")}.}
+    \lineiii{\%ld}{long}{Exactly equivalent to \code{printf("\%ld")}.}
+    \lineiii{\%lu}{unsigned long}{Exactly equivalent to \code{printf("\%lu")}.}
+    \lineiii{\%zd}{Py_ssize_t}{Exactly equivalent to \code{printf("\%zd")}.}
+    \lineiii{\%zu}{size_t}{Exactly equivalent to \code{printf("\%zu")}.}
+    \lineiii{\%i}{int}{Exactly equivalent to \code{printf("\%i")}.}
+    \lineiii{\%x}{int}{Exactly equivalent to \code{printf("\%x")}.}
+    \lineiii{\%s}{char*}{A null-terminated C character array.}
+    \lineiii{\%p}{void*}{The hex representation of a C pointer.
+	Mostly equivalent to \code{printf("\%p")} except that it is
+	guaranteed to start with the literal \code{0x} regardless of
+	what the platform's \code{printf} yields.}
+  \end{tableiii}
+
+  An unrecognized format character causes all the rest of the format
+  string to be copied as-is to the result string, and any extra
+  arguments discarded.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{PyErr_SetNone}{PyObject *type}
+  This is a shorthand for \samp{PyErr_SetObject(\var{type},
+  Py_None)}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyErr_BadArgument}{}
+  This is a shorthand for \samp{PyErr_SetString(PyExc_TypeError,
+  \var{message})}, where \var{message} indicates that a built-in
+  operation was invoked with an illegal argument.  It is mostly for
+  internal use.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyErr_NoMemory}{}
+  This is a shorthand for \samp{PyErr_SetNone(PyExc_MemoryError)}; it
+  returns \NULL{} so an object allocation function can write
+  \samp{return PyErr_NoMemory();} when it runs out of memory.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyErr_SetFromErrno}{PyObject *type}
+  This is a convenience function to raise an exception when a C
+  library function has returned an error and set the C variable
+  \cdata{errno}.  It constructs a tuple object whose first item is the
+  integer \cdata{errno} value and whose second item is the
+  corresponding error message (gotten from
+  \cfunction{strerror()}\ttindex{strerror()}), and then calls
+  \samp{PyErr_SetObject(\var{type}, \var{object})}.  On \UNIX, when
+  the \cdata{errno} value is \constant{EINTR}, indicating an
+  interrupted system call, this calls
+  \cfunction{PyErr_CheckSignals()}, and if that set the error
+  indicator, leaves it set to that.  The function always returns
+  \NULL, so a wrapper function around a system call can write
+  \samp{return PyErr_SetFromErrno(\var{type});} when the system call
+  returns an error.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyErr_SetFromErrnoWithFilename}{PyObject *type,
+                                                             const char *filename}
+  Similar to \cfunction{PyErr_SetFromErrno()}, with the additional
+  behavior that if \var{filename} is not \NULL, it is passed to the
+  constructor of \var{type} as a third parameter.  In the case of
+  exceptions such as \exception{IOError} and \exception{OSError}, this
+  is used to define the \member{filename} attribute of the exception
+  instance.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyErr_SetFromWindowsErr}{int ierr}
+  This is a convenience function to raise \exception{WindowsError}.
+  If called with \var{ierr} of \cdata{0}, the error code returned by a
+  call to \cfunction{GetLastError()} is used instead.  It calls the
+  Win32 function \cfunction{FormatMessage()} to retrieve the Windows
+  description of error code given by \var{ierr} or
+  \cfunction{GetLastError()}, then it constructs a tuple object whose
+  first item is the \var{ierr} value and whose second item is the
+  corresponding error message (gotten from
+  \cfunction{FormatMessage()}), and then calls
+  \samp{PyErr_SetObject(\var{PyExc_WindowsError}, \var{object})}.
+  This function always returns \NULL.
+  Availability: Windows.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyErr_SetExcFromWindowsErr}{PyObject *type,
+	                                                 int ierr}
+  Similar to \cfunction{PyErr_SetFromWindowsErr()}, with an additional
+  parameter specifying the exception type to be raised.
+  Availability: Windows.
+  \versionadded{2.3}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyErr_SetFromWindowsErrWithFilename}{int ierr,
+                                                                const char *filename}
+  Similar to \cfunction{PyErr_SetFromWindowsErr()}, with the
+  additional behavior that if \var{filename} is not \NULL, it is
+  passed to the constructor of \exception{WindowsError} as a third
+  parameter.
+  Availability: Windows.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyErr_SetExcFromWindowsErrWithFilename}
+	{PyObject *type, int ierr, char *filename}
+  Similar to \cfunction{PyErr_SetFromWindowsErrWithFilename()}, with
+  an additional parameter specifying the exception type to be raised.
+  Availability: Windows.
+  \versionadded{2.3}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{PyErr_BadInternalCall}{}
+  This is a shorthand for \samp{PyErr_SetString(PyExc_TypeError,
+  \var{message})}, where \var{message} indicates that an internal
+  operation (e.g. a Python/C API function) was invoked with an illegal
+  argument.  It is mostly for internal use.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyErr_WarnEx}{PyObject *category, char *message, int stacklevel}
+  Issue a warning message.  The \var{category} argument is a warning
+  category (see below) or \NULL; the \var{message} argument is a
+  message string.  \var{stacklevel} is a positive number giving a
+  number of stack frames; the warning will be issued from the 
+  currently executing line of code in that stack frame.  A \var{stacklevel}
+  of 1 is the function calling \cfunction{PyErr_WarnEx()}, 2 is 
+  the function above that, and so forth.
+
+  This function normally prints a warning message to \var{sys.stderr};
+  however, it is also possible that the user has specified that
+  warnings are to be turned into errors, and in that case this will
+  raise an exception.  It is also possible that the function raises an
+  exception because of a problem with the warning machinery (the
+  implementation imports the \module{warnings} module to do the heavy
+  lifting).  The return value is \code{0} if no exception is raised,
+  or \code{-1} if an exception is raised.  (It is not possible to
+  determine whether a warning message is actually printed, nor what
+  the reason is for the exception; this is intentional.)  If an
+  exception is raised, the caller should do its normal exception
+  handling (for example, \cfunction{Py_DECREF()} owned references and
+  return an error value).
+
+  Warning categories must be subclasses of \cdata{Warning}; the
+  default warning category is \cdata{RuntimeWarning}.  The standard
+  Python warning categories are available as global variables whose
+  names are \samp{PyExc_} followed by the Python exception name.
+  These have the type \ctype{PyObject*}; they are all class objects.
+  Their names are \cdata{PyExc_Warning}, \cdata{PyExc_UserWarning},
+  \cdata{PyExc_UnicodeWarning}, \cdata{PyExc_DeprecationWarning},
+  \cdata{PyExc_SyntaxWarning}, \cdata{PyExc_RuntimeWarning}, and
+  \cdata{PyExc_FutureWarning}.  \cdata{PyExc_Warning} is a subclass of
+  \cdata{PyExc_Exception}; the other warning categories are subclasses
+  of \cdata{PyExc_Warning}.
+
+  For information about warning control, see the documentation for the
+  \module{warnings} module and the \programopt{-W} option in the
+  command line documentation.  There is no C API for warning control.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyErr_Warn}{PyObject *category, char *message}
+  Issue a warning message.  The \var{category} argument is a warning
+  category (see below) or \NULL; the \var{message} argument is a
+  message string.  The warning will appear to be issued from the function
+  calling \cfunction{PyErr_Warn()}, equivalent to calling
+  \cfunction{PyErr_WarnEx()} with a \var{stacklevel} of 1.
+  
+  Deprecated; use \cfunction{PyErr_WarnEx()} instead.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyErr_WarnExplicit}{PyObject *category,
+                const char *message, const char *filename, int lineno,
+                const char *module, PyObject *registry}
+  Issue a warning message with explicit control over all warning
+  attributes.  This is a straightforward wrapper around the Python
+  function \function{warnings.warn_explicit()}, see there for more
+  information.  The \var{module} and \var{registry} arguments may be
+  set to \NULL{} to get the default effect described there.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyErr_CheckSignals}{}
+  This function interacts with Python's signal handling.  It checks
+  whether a signal has been sent to the processes and if so, invokes
+  the corresponding signal handler.  If the
+  \module{signal}\refbimodindex{signal} module is supported, this can
+  invoke a signal handler written in Python.  In all cases, the
+  default effect for \constant{SIGINT}\ttindex{SIGINT} is to raise the
+  \withsubitem{(built-in exception)}{\ttindex{KeyboardInterrupt}}
+  \exception{KeyboardInterrupt} exception.  If an exception is raised
+  the error indicator is set and the function returns \code{-1};
+  otherwise the function returns \code{0}.  The error indicator may or
+  may not be cleared if it was previously set.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{PyErr_SetInterrupt}{}
+  This function simulates the effect of a
+  \constant{SIGINT}\ttindex{SIGINT} signal arriving --- the next time
+  \cfunction{PyErr_CheckSignals()} is called,
+  \withsubitem{(built-in exception)}{\ttindex{KeyboardInterrupt}}
+  \exception{KeyboardInterrupt} will be raised.  It may be called
+  without holding the interpreter lock.
+  % XXX This was described as obsolete, but is used in
+  % thread.interrupt_main() (used from IDLE), so it's still needed.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyErr_NewException}{char *name,
+                                                 PyObject *base,
+                                                 PyObject *dict}
+  This utility function creates and returns a new exception object.
+  The \var{name} argument must be the name of the new exception, a C
+  string of the form \code{module.class}.  The \var{base} and
+  \var{dict} arguments are normally \NULL.  This creates a class
+  object derived from \exception{Exception} (accessible in C as
+  \cdata{PyExc_Exception}).
+
+  The \member{__module__} attribute of the new class is set to the
+  first part (up to the last dot) of the \var{name} argument, and the
+  class name is set to the last part (after the last dot).  The
+  \var{base} argument can be used to specify alternate base classes;
+  it can either be only one class or a tuple of classes.
+  The \var{dict} argument can be used to specify a dictionary of class
+  variables and methods.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{PyErr_WriteUnraisable}{PyObject *obj}
+  This utility function prints a warning message to \code{sys.stderr}
+  when an exception has been set but it is impossible for the
+  interpreter to actually raise the exception.  It is used, for
+  example, when an exception occurs in an \method{__del__()} method.
+
+  The function is called with a single argument \var{obj} that
+  identifies the context in which the unraisable exception occurred.
+  The repr of \var{obj} will be printed in the warning message.
+\end{cfuncdesc}
+
+\section{Standard Exceptions \label{standardExceptions}}
+
+All standard Python exceptions are available as global variables whose
+names are \samp{PyExc_} followed by the Python exception name.  These
+have the type \ctype{PyObject*}; they are all class objects.  For
+completeness, here are all the variables:
+
+\begin{tableiii}{l|l|c}{cdata}{C Name}{Python Name}{Notes}
+  \lineiii{PyExc_BaseException\ttindex{PyExc_BaseException}}{\exception{BaseException}}{(1), (4)}
+  \lineiii{PyExc_Exception\ttindex{PyExc_Exception}}{\exception{Exception}}{(1)}
+  \lineiii{PyExc_StandardError\ttindex{PyExc_StandardError}}{\exception{StandardError}}{(1)}
+  \lineiii{PyExc_ArithmeticError\ttindex{PyExc_ArithmeticError}}{\exception{ArithmeticError}}{(1)}
+  \lineiii{PyExc_LookupError\ttindex{PyExc_LookupError}}{\exception{LookupError}}{(1)}
+  \lineiii{PyExc_AssertionError\ttindex{PyExc_AssertionError}}{\exception{AssertionError}}{}
+  \lineiii{PyExc_AttributeError\ttindex{PyExc_AttributeError}}{\exception{AttributeError}}{}
+  \lineiii{PyExc_EOFError\ttindex{PyExc_EOFError}}{\exception{EOFError}}{}
+  \lineiii{PyExc_EnvironmentError\ttindex{PyExc_EnvironmentError}}{\exception{EnvironmentError}}{(1)}
+  \lineiii{PyExc_FloatingPointError\ttindex{PyExc_FloatingPointError}}{\exception{FloatingPointError}}{}
+  \lineiii{PyExc_IOError\ttindex{PyExc_IOError}}{\exception{IOError}}{}
+  \lineiii{PyExc_ImportError\ttindex{PyExc_ImportError}}{\exception{ImportError}}{}
+  \lineiii{PyExc_IndexError\ttindex{PyExc_IndexError}}{\exception{IndexError}}{}
+  \lineiii{PyExc_KeyError\ttindex{PyExc_KeyError}}{\exception{KeyError}}{}
+  \lineiii{PyExc_KeyboardInterrupt\ttindex{PyExc_KeyboardInterrupt}}{\exception{KeyboardInterrupt}}{}
+  \lineiii{PyExc_MemoryError\ttindex{PyExc_MemoryError}}{\exception{MemoryError}}{}
+  \lineiii{PyExc_NameError\ttindex{PyExc_NameError}}{\exception{NameError}}{}
+  \lineiii{PyExc_NotImplementedError\ttindex{PyExc_NotImplementedError}}{\exception{NotImplementedError}}{}
+  \lineiii{PyExc_OSError\ttindex{PyExc_OSError}}{\exception{OSError}}{}
+  \lineiii{PyExc_OverflowError\ttindex{PyExc_OverflowError}}{\exception{OverflowError}}{}
+  \lineiii{PyExc_ReferenceError\ttindex{PyExc_ReferenceError}}{\exception{ReferenceError}}{(2)}
+  \lineiii{PyExc_RuntimeError\ttindex{PyExc_RuntimeError}}{\exception{RuntimeError}}{}
+  \lineiii{PyExc_SyntaxError\ttindex{PyExc_SyntaxError}}{\exception{SyntaxError}}{}
+  \lineiii{PyExc_SystemError\ttindex{PyExc_SystemError}}{\exception{SystemError}}{}
+  \lineiii{PyExc_SystemExit\ttindex{PyExc_SystemExit}}{\exception{SystemExit}}{}
+  \lineiii{PyExc_TypeError\ttindex{PyExc_TypeError}}{\exception{TypeError}}{}
+  \lineiii{PyExc_ValueError\ttindex{PyExc_ValueError}}{\exception{ValueError}}{}
+  \lineiii{PyExc_WindowsError\ttindex{PyExc_WindowsError}}{\exception{WindowsError}}{(3)}
+  \lineiii{PyExc_ZeroDivisionError\ttindex{PyExc_ZeroDivisionError}}{\exception{ZeroDivisionError}}{}
+\end{tableiii}
+
+\noindent
+Notes:
+\begin{description}
+\item[(1)]
+  This is a base class for other standard exceptions.
+
+\item[(2)]
+  This is the same as \exception{weakref.ReferenceError}.
+
+\item[(3)]
+  Only defined on Windows; protect code that uses this by testing that
+  the preprocessor macro \code{MS_WINDOWS} is defined.
+
+\item[(4)]
+  \versionadded{2.5}
+\end{description}
+
+
+\section{Deprecation of String Exceptions}
+
+All exceptions built into Python or provided in the standard library
+are derived from \exception{BaseException}.
+\withsubitem{(built-in exception)}{\ttindex{BaseException}}
+
+String exceptions are still supported in the interpreter to allow
+existing code to run unmodified, but this will also change in a future
+release.

Added: vendor/Python/current/Doc/api/init.tex
===================================================================
--- vendor/Python/current/Doc/api/init.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/api/init.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,884 @@
+\chapter{Initialization, Finalization, and Threads
+         \label{initialization}}
+
+\begin{cfuncdesc}{void}{Py_Initialize}{}
+  Initialize the Python interpreter.  In an application embedding 
+  Python, this should be called before using any other Python/C API
+  functions; with the exception of
+  \cfunction{Py_SetProgramName()}\ttindex{Py_SetProgramName()},
+  \cfunction{PyEval_InitThreads()}\ttindex{PyEval_InitThreads()},
+  \cfunction{PyEval_ReleaseLock()}\ttindex{PyEval_ReleaseLock()},
+  and \cfunction{PyEval_AcquireLock()}\ttindex{PyEval_AcquireLock()}.
+  This initializes the table of loaded modules (\code{sys.modules}),
+  and\withsubitem{(in module sys)}{\ttindex{modules}\ttindex{path}}
+  creates the fundamental modules
+  \module{__builtin__}\refbimodindex{__builtin__},
+  \module{__main__}\refbimodindex{__main__} and
+  \module{sys}\refbimodindex{sys}.  It also initializes the module
+  search\indexiii{module}{search}{path} path (\code{sys.path}).
+  It does not set \code{sys.argv}; use
+  \cfunction{PySys_SetArgv()}\ttindex{PySys_SetArgv()} for that.  This
+  is a no-op when called for a second time (without calling
+  \cfunction{Py_Finalize()}\ttindex{Py_Finalize()} first).  There is
+  no return value; it is a fatal error if the initialization fails.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{Py_InitializeEx}{int initsigs}
+  This function works like \cfunction{Py_Initialize()} if
+  \var{initsigs} is 1. If \var{initsigs} is 0, it skips
+  initialization registration of signal handlers, which
+  might be useful when Python is embedded. \versionadded{2.4}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{Py_IsInitialized}{}
+  Return true (nonzero) when the Python interpreter has been
+  initialized, false (zero) if not.  After \cfunction{Py_Finalize()}
+  is called, this returns false until \cfunction{Py_Initialize()} is
+  called again.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{Py_Finalize}{}
+  Undo all initializations made by \cfunction{Py_Initialize()} and
+  subsequent use of Python/C API functions, and destroy all
+  sub-interpreters (see \cfunction{Py_NewInterpreter()} below) that
+  were created and not yet destroyed since the last call to
+  \cfunction{Py_Initialize()}.  Ideally, this frees all memory
+  allocated by the Python interpreter.  This is a no-op when called
+  for a second time (without calling \cfunction{Py_Initialize()} again
+  first).  There is no return value; errors during finalization are
+  ignored.
+
+  This function is provided for a number of reasons.  An embedding
+  application might want to restart Python without having to restart
+  the application itself.  An application that has loaded the Python
+  interpreter from a dynamically loadable library (or DLL) might want
+  to free all memory allocated by Python before unloading the
+  DLL. During a hunt for memory leaks in an application a developer
+  might want to free all memory allocated by Python before exiting
+  from the application.
+
+  \strong{Bugs and caveats:} The destruction of modules and objects in
+  modules is done in random order; this may cause destructors
+  (\method{__del__()} methods) to fail when they depend on other
+  objects (even functions) or modules.  Dynamically loaded extension
+  modules loaded by Python are not unloaded.  Small amounts of memory
+  allocated by the Python interpreter may not be freed (if you find a
+  leak, please report it).  Memory tied up in circular references
+  between objects is not freed.  Some memory allocated by extension
+  modules may not be freed.  Some extensions may not work properly if
+  their initialization routine is called more than once; this can
+  happen if an application calls \cfunction{Py_Initialize()} and
+  \cfunction{Py_Finalize()} more than once.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyThreadState*}{Py_NewInterpreter}{}
+  Create a new sub-interpreter.  This is an (almost) totally separate
+  environment for the execution of Python code.  In particular, the
+  new interpreter has separate, independent versions of all imported
+  modules, including the fundamental modules
+  \module{__builtin__}\refbimodindex{__builtin__},
+  \module{__main__}\refbimodindex{__main__} and
+  \module{sys}\refbimodindex{sys}.  The table of loaded modules
+  (\code{sys.modules}) and the module search path (\code{sys.path})
+  are also separate.  The new environment has no \code{sys.argv}
+  variable.  It has new standard I/O stream file objects
+  \code{sys.stdin}, \code{sys.stdout} and \code{sys.stderr} (however
+  these refer to the same underlying \ctype{FILE} structures in the C
+  library).
+  \withsubitem{(in module sys)}{
+    \ttindex{stdout}\ttindex{stderr}\ttindex{stdin}}
+
+  The return value points to the first thread state created in the new
+  sub-interpreter.  This thread state is made in the current thread
+  state.  Note that no actual thread is created; see the discussion of
+  thread states below.  If creation of the new interpreter is
+  unsuccessful, \NULL{} is returned; no exception is set since the
+  exception state is stored in the current thread state and there may
+  not be a current thread state.  (Like all other Python/C API
+  functions, the global interpreter lock must be held before calling
+  this function and is still held when it returns; however, unlike
+  most other Python/C API functions, there needn't be a current thread
+  state on entry.)
+
+  Extension modules are shared between (sub-)interpreters as follows:
+  the first time a particular extension is imported, it is initialized
+  normally, and a (shallow) copy of its module's dictionary is
+  squirreled away.  When the same extension is imported by another
+  (sub-)interpreter, a new module is initialized and filled with the
+  contents of this copy; the extension's \code{init} function is not
+  called.  Note that this is different from what happens when an
+  extension is imported after the interpreter has been completely
+  re-initialized by calling
+  \cfunction{Py_Finalize()}\ttindex{Py_Finalize()} and
+  \cfunction{Py_Initialize()}\ttindex{Py_Initialize()}; in that case,
+  the extension's \code{init\var{module}} function \emph{is} called
+  again.
+
+  \strong{Bugs and caveats:} Because sub-interpreters (and the main
+  interpreter) are part of the same process, the insulation between
+  them isn't perfect --- for example, using low-level file operations
+  like \withsubitem{(in module os)}{\ttindex{close()}}
+  \function{os.close()} they can (accidentally or maliciously) affect
+  each other's open files.  Because of the way extensions are shared
+  between (sub-)interpreters, some extensions may not work properly;
+  this is especially likely when the extension makes use of (static)
+  global variables, or when the extension manipulates its module's
+  dictionary after its initialization.  It is possible to insert
+  objects created in one sub-interpreter into a namespace of another
+  sub-interpreter; this should be done with great care to avoid
+  sharing user-defined functions, methods, instances or classes
+  between sub-interpreters, since import operations executed by such
+  objects may affect the wrong (sub-)interpreter's dictionary of
+  loaded modules.  (XXX This is a hard-to-fix bug that will be
+  addressed in a future release.)
+
+  Also note that the use of this functionality is incompatible with
+  extension modules such as PyObjC and ctypes that use the
+  \cfunction{PyGILState_*} APIs (and this is inherent in the way the
+  \cfunction{PyGILState_*} functions work).  Simple things may work,
+  but confusing behavior will always be near.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{Py_EndInterpreter}{PyThreadState *tstate}
+  Destroy the (sub-)interpreter represented by the given thread state.
+  The given thread state must be the current thread state.  See the
+  discussion of thread states below.  When the call returns, the
+  current thread state is \NULL.  All thread states associated with
+  this interpreter are destroyed.  (The global interpreter lock must
+  be held before calling this function and is still held when it
+  returns.)  \cfunction{Py_Finalize()}\ttindex{Py_Finalize()} will
+  destroy all sub-interpreters that haven't been explicitly destroyed
+  at that point.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{Py_SetProgramName}{char *name}
+  This function should be called before
+  \cfunction{Py_Initialize()}\ttindex{Py_Initialize()} is called
+  for the first time, if it is called at all.  It tells the
+  interpreter the value of the \code{argv[0]} argument to the
+  \cfunction{main()}\ttindex{main()} function of the program.  This is
+  used by \cfunction{Py_GetPath()}\ttindex{Py_GetPath()} and some
+  other functions below to find the Python run-time libraries relative
+  to the interpreter executable.  The default value is
+  \code{'python'}.  The argument should point to a zero-terminated
+  character string in static storage whose contents will not change
+  for the duration of the program's execution.  No code in the Python
+  interpreter will change the contents of this storage.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{char*}{Py_GetProgramName}{}
+  Return the program name set with
+  \cfunction{Py_SetProgramName()}\ttindex{Py_SetProgramName()}, or the
+  default.  The returned string points into static storage; the caller
+  should not modify its value.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{char*}{Py_GetPrefix}{}
+  Return the \emph{prefix} for installed platform-independent files.
+  This is derived through a number of complicated rules from the
+  program name set with \cfunction{Py_SetProgramName()} and some
+  environment variables; for example, if the program name is
+  \code{'/usr/local/bin/python'}, the prefix is \code{'/usr/local'}.
+  The returned string points into static storage; the caller should
+  not modify its value.  This corresponds to the \makevar{prefix}
+  variable in the top-level \file{Makefile} and the
+  \longprogramopt{prefix} argument to the \program{configure} script
+  at build time.  The value is available to Python code as
+  \code{sys.prefix}.  It is only useful on \UNIX{}.  See also the next
+  function.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{char*}{Py_GetExecPrefix}{}
+  Return the \emph{exec-prefix} for installed
+  platform-\emph{de}pendent files.  This is derived through a number
+  of complicated rules from the program name set with
+  \cfunction{Py_SetProgramName()} and some environment variables; for
+  example, if the program name is \code{'/usr/local/bin/python'}, the
+  exec-prefix is \code{'/usr/local'}.  The returned string points into
+  static storage; the caller should not modify its value.  This
+  corresponds to the \makevar{exec_prefix} variable in the top-level
+  \file{Makefile} and the \longprogramopt{exec-prefix} argument to the
+  \program{configure} script at build  time.  The value is available
+  to Python code as \code{sys.exec_prefix}.  It is only useful on
+  \UNIX.
+
+  Background: The exec-prefix differs from the prefix when platform
+  dependent files (such as executables and shared libraries) are
+  installed in a different directory tree.  In a typical installation,
+  platform dependent files may be installed in the
+  \file{/usr/local/plat} subtree while platform independent may be
+  installed in \file{/usr/local}.
+
+  Generally speaking, a platform is a combination of hardware and
+  software families, e.g.  Sparc machines running the Solaris 2.x
+  operating system are considered the same platform, but Intel
+  machines running Solaris 2.x are another platform, and Intel
+  machines running Linux are yet another platform.  Different major
+  revisions of the same operating system generally also form different
+  platforms.  Non-\UNIX{} operating systems are a different story; the
+  installation strategies on those systems are so different that the
+  prefix and exec-prefix are meaningless, and set to the empty string.
+  Note that compiled Python bytecode files are platform independent
+  (but not independent from the Python version by which they were
+  compiled!).
+
+  System administrators will know how to configure the \program{mount}
+  or \program{automount} programs to share \file{/usr/local} between
+  platforms while having \file{/usr/local/plat} be a different
+  filesystem for each platform.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{char*}{Py_GetProgramFullPath}{}
+  Return the full program name of the Python executable; this is 
+  computed as a side-effect of deriving the default module search path 
+  from the program name (set by
+  \cfunction{Py_SetProgramName()}\ttindex{Py_SetProgramName()} above).
+  The returned string points into static storage; the caller should
+  not modify its value.  The value is available to Python code as
+  \code{sys.executable}.
+  \withsubitem{(in module sys)}{\ttindex{executable}}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{char*}{Py_GetPath}{}
+  \indexiii{module}{search}{path}
+  Return the default module search path; this is computed from the 
+  program name (set by \cfunction{Py_SetProgramName()} above) and some
+  environment variables.  The returned string consists of a series of
+  directory names separated by a platform dependent delimiter
+  character.  The delimiter character is \character{:} on \UNIX and Mac OS X,
+  \character{;} on Windows.  The returned string points into
+  static storage; the caller should not modify its value.  The value
+  is available to Python code as the list
+  \code{sys.path}\withsubitem{(in module sys)}{\ttindex{path}}, which
+  may be modified to change the future search path for loaded
+  modules.
+
+  % XXX should give the exact rules
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{const char*}{Py_GetVersion}{}
+  Return the version of this Python interpreter.  This is a string
+  that looks something like
+
+\begin{verbatim}
+"1.5 (#67, Dec 31 1997, 22:34:28) [GCC 2.7.2.2]"
+\end{verbatim}
+
+  The first word (up to the first space character) is the current
+  Python version; the first three characters are the major and minor
+  version separated by a period.  The returned string points into
+  static storage; the caller should not modify its value.  The value
+  is available to Python code as \code{sys.version}.
+  \withsubitem{(in module sys)}{\ttindex{version}}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{const char*}{Py_GetBuildNumber}{}
+  Return a string representing the Subversion revision that this Python
+  executable was built from.  This number is a string because it may contain a
+  trailing 'M' if Python was built from a mixed revision source tree.
+  \versionadded{2.5}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{const char*}{Py_GetPlatform}{}
+  Return the platform identifier for the current platform.  On \UNIX,
+  this is formed from the ``official'' name of the operating system,
+  converted to lower case, followed by the major revision number;
+  e.g., for Solaris 2.x, which is also known as SunOS 5.x, the value
+  is \code{'sunos5'}.  On Mac OS X, it is \code{'darwin'}.  On Windows,
+  it is \code{'win'}.  The returned string points into static storage;
+  the caller should not modify its value.  The value is available to
+  Python code as \code{sys.platform}.
+  \withsubitem{(in module sys)}{\ttindex{platform}}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{const char*}{Py_GetCopyright}{}
+  Return the official copyright string for the current Python version,
+  for example
+
+  \code{'Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam'}
+
+  The returned string points into static storage; the caller should
+  not modify its value.  The value is available to Python code as
+  \code{sys.copyright}.
+  \withsubitem{(in module sys)}{\ttindex{copyright}}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{const char*}{Py_GetCompiler}{}
+  Return an indication of the compiler used to build the current
+  Python version, in square brackets, for example:
+
+\begin{verbatim}
+"[GCC 2.7.2.2]"
+\end{verbatim}
+
+  The returned string points into static storage; the caller should
+  not modify its value.  The value is available to Python code as part
+  of the variable \code{sys.version}.
+  \withsubitem{(in module sys)}{\ttindex{version}}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{const char*}{Py_GetBuildInfo}{}
+  Return information about the sequence number and build date and time 
+  of the current Python interpreter instance, for example
+
+\begin{verbatim}
+"#67, Aug  1 1997, 22:34:28"
+\end{verbatim}
+
+  The returned string points into static storage; the caller should
+  not modify its value.  The value is available to Python code as part
+  of the variable \code{sys.version}.
+  \withsubitem{(in module sys)}{\ttindex{version}}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{PySys_SetArgv}{int argc, char **argv}
+  Set \code{sys.argv} based on \var{argc} and \var{argv}.  These
+  parameters are similar to those passed to the program's
+  \cfunction{main()}\ttindex{main()} function with the difference that
+  the first entry should refer to the script file to be executed
+  rather than the executable hosting the Python interpreter.  If there
+  isn't a script that will be run, the first entry in \var{argv} can
+  be an empty string.  If this function fails to initialize
+  \code{sys.argv}, a fatal condition is signalled using
+  \cfunction{Py_FatalError()}\ttindex{Py_FatalError()}.
+  \withsubitem{(in module sys)}{\ttindex{argv}}
+  % XXX impl. doesn't seem consistent in allowing 0/NULL for the params; 
+  % check w/ Guido.
+\end{cfuncdesc}
+
+% XXX Other PySys thingies (doesn't really belong in this chapter)
+
+\section{Thread State and the Global Interpreter Lock
+         \label{threads}}
+
+\index{global interpreter lock}
+\index{interpreter lock}
+\index{lock, interpreter}
+
+The Python interpreter is not fully thread safe.  In order to support
+multi-threaded Python programs, there's a global lock that must be
+held by the current thread before it can safely access Python objects.
+Without the lock, even the simplest operations could cause problems in
+a multi-threaded program: for example, when two threads simultaneously
+increment the reference count of the same object, the reference count
+could end up being incremented only once instead of twice.
+
+Therefore, the rule exists that only the thread that has acquired the
+global interpreter lock may operate on Python objects or call Python/C
+API functions.  In order to support multi-threaded Python programs,
+the interpreter regularly releases and reacquires the lock --- by
+default, every 100 bytecode instructions (this can be changed with
+\withsubitem{(in module sys)}{\ttindex{setcheckinterval()}}
+\function{sys.setcheckinterval()}).  The lock is also released and
+reacquired around potentially blocking I/O operations like reading or
+writing a file, so that other threads can run while the thread that
+requests the I/O is waiting for the I/O operation to complete.
+
+The Python interpreter needs to keep some bookkeeping information
+separate per thread --- for this it uses a data structure called
+\ctype{PyThreadState}\ttindex{PyThreadState}.  There's one global
+variable, however: the pointer to the current
+\ctype{PyThreadState}\ttindex{PyThreadState} structure.  While most
+thread packages have a way to store ``per-thread global data,''
+Python's internal platform independent thread abstraction doesn't
+support this yet.  Therefore, the current thread state must be
+manipulated explicitly.
+
+This is easy enough in most cases.  Most code manipulating the global
+interpreter lock has the following simple structure:
+
+\begin{verbatim}
+Save the thread state in a local variable.
+Release the interpreter lock.
+...Do some blocking I/O operation...
+Reacquire the interpreter lock.
+Restore the thread state from the local variable.
+\end{verbatim}
+
+This is so common that a pair of macros exists to simplify it:
+
+\begin{verbatim}
+Py_BEGIN_ALLOW_THREADS
+...Do some blocking I/O operation...
+Py_END_ALLOW_THREADS
+\end{verbatim}
+
+The
+\csimplemacro{Py_BEGIN_ALLOW_THREADS}\ttindex{Py_BEGIN_ALLOW_THREADS}
+macro opens a new block and declares a hidden local variable; the
+\csimplemacro{Py_END_ALLOW_THREADS}\ttindex{Py_END_ALLOW_THREADS}
+macro closes the block.  Another advantage of using these two macros
+is that when Python is compiled without thread support, they are
+defined empty, thus saving the thread state and lock manipulations.
+
+When thread support is enabled, the block above expands to the
+following code:
+
+\begin{verbatim}
+    PyThreadState *_save;
+
+    _save = PyEval_SaveThread();
+    ...Do some blocking I/O operation...
+    PyEval_RestoreThread(_save);
+\end{verbatim}
+
+Using even lower level primitives, we can get roughly the same effect
+as follows:
+
+\begin{verbatim}
+    PyThreadState *_save;
+
+    _save = PyThreadState_Swap(NULL);
+    PyEval_ReleaseLock();
+    ...Do some blocking I/O operation...
+    PyEval_AcquireLock();
+    PyThreadState_Swap(_save);
+\end{verbatim}
+
+There are some subtle differences; in particular,
+\cfunction{PyEval_RestoreThread()}\ttindex{PyEval_RestoreThread()} saves
+and restores the value of the  global variable
+\cdata{errno}\ttindex{errno}, since the lock manipulation does not
+guarantee that \cdata{errno} is left alone.  Also, when thread support
+is disabled,
+\cfunction{PyEval_SaveThread()}\ttindex{PyEval_SaveThread()} and
+\cfunction{PyEval_RestoreThread()} don't manipulate the lock; in this
+case, \cfunction{PyEval_ReleaseLock()}\ttindex{PyEval_ReleaseLock()} and
+\cfunction{PyEval_AcquireLock()}\ttindex{PyEval_AcquireLock()} are not
+available.  This is done so that dynamically loaded extensions
+compiled with thread support enabled can be loaded by an interpreter
+that was compiled with disabled thread support.
+
+The global interpreter lock is used to protect the pointer to the
+current thread state.  When releasing the lock and saving the thread
+state, the current thread state pointer must be retrieved before the
+lock is released (since another thread could immediately acquire the
+lock and store its own thread state in the global variable).
+Conversely, when acquiring the lock and restoring the thread state,
+the lock must be acquired before storing the thread state pointer.
+
+Why am I going on with so much detail about this?  Because when
+threads are created from C, they don't have the global interpreter
+lock, nor is there a thread state data structure for them.  Such
+threads must bootstrap themselves into existence, by first creating a
+thread state data structure, then acquiring the lock, and finally
+storing their thread state pointer, before they can start using the
+Python/C API.  When they are done, they should reset the thread state
+pointer, release the lock, and finally free their thread state data
+structure.
+
+Beginning with version 2.3, threads can now take advantage of the 
+\cfunction{PyGILState_*()} functions to do all of the above
+automatically.  The typical idiom for calling into Python from a C
+thread is now:
+
+\begin{verbatim}
+    PyGILState_STATE gstate;
+    gstate = PyGILState_Ensure();
+
+    /* Perform Python actions here.  */
+    result = CallSomeFunction();
+    /* evaluate result */
+
+    /* Release the thread. No Python API allowed beyond this point. */
+    PyGILState_Release(gstate);
+\end{verbatim}
+
+Note that the \cfunction{PyGILState_*()} functions assume there is
+only one global interpreter (created automatically by
+\cfunction{Py_Initialize()}).  Python still supports the creation of
+additional interpreters (using \cfunction{Py_NewInterpreter()}), but
+mixing multiple interpreters and the \cfunction{PyGILState_*()} API is
+unsupported.
+
+\begin{ctypedesc}{PyInterpreterState}
+  This data structure represents the state shared by a number of
+  cooperating threads.  Threads belonging to the same interpreter
+  share their module administration and a few other internal items.
+  There are no public members in this structure.
+
+  Threads belonging to different interpreters initially share nothing,
+  except process state like available memory, open file descriptors
+  and such.  The global interpreter lock is also shared by all
+  threads, regardless of to which interpreter they belong.
+\end{ctypedesc}
+
+\begin{ctypedesc}{PyThreadState}
+  This data structure represents the state of a single thread.  The
+  only public data member is \ctype{PyInterpreterState
+  *}\member{interp}, which points to this thread's interpreter state.
+\end{ctypedesc}
+
+\begin{cfuncdesc}{void}{PyEval_InitThreads}{}
+  Initialize and acquire the global interpreter lock.  It should be
+  called in the main thread before creating a second thread or
+  engaging in any other thread operations such as
+  \cfunction{PyEval_ReleaseLock()}\ttindex{PyEval_ReleaseLock()} or
+  \code{PyEval_ReleaseThread(\var{tstate})}\ttindex{PyEval_ReleaseThread()}.
+  It is not needed before calling
+  \cfunction{PyEval_SaveThread()}\ttindex{PyEval_SaveThread()} or
+  \cfunction{PyEval_RestoreThread()}\ttindex{PyEval_RestoreThread()}.
+
+  This is a no-op when called for a second time.  It is safe to call
+  this function before calling
+  \cfunction{Py_Initialize()}\ttindex{Py_Initialize()}.
+
+  When only the main thread exists, no lock operations are needed.
+  This is a common situation (most Python programs do not use
+  threads), and the lock operations slow the interpreter down a bit.
+  Therefore, the lock is not created initially.  This situation is
+  equivalent to having acquired the lock:  when there is only a single
+  thread, all object accesses are safe.  Therefore, when this function
+  initializes the lock, it also acquires it.  Before the Python
+  \module{thread}\refbimodindex{thread} module creates a new thread,
+  knowing that either it has the lock or the lock hasn't been created
+  yet, it calls \cfunction{PyEval_InitThreads()}.  When this call
+  returns, it is guaranteed that the lock has been created and that the
+  calling thread has acquired it.
+
+  It is \strong{not} safe to call this function when it is unknown
+  which thread (if any) currently has the global interpreter lock.
+
+  This function is not available when thread support is disabled at
+  compile time.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyEval_ThreadsInitialized}{}
+  Returns a non-zero value if \cfunction{PyEval_InitThreads()} has been
+  called.  This function can be called without holding the lock, and
+  therefore can be used to avoid calls to the locking API when running
+  single-threaded.  This function is not available when thread support
+  is disabled at compile time. \versionadded{2.4}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{PyEval_AcquireLock}{}
+  Acquire the global interpreter lock.  The lock must have been
+  created earlier.  If this thread already has the lock, a deadlock
+  ensues.  This function is not available when thread support is
+  disabled at compile time.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{PyEval_ReleaseLock}{}
+  Release the global interpreter lock.  The lock must have been
+  created earlier.  This function is not available when thread support
+  is disabled at compile time.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{PyEval_AcquireThread}{PyThreadState *tstate}
+  Acquire the global interpreter lock and set the current thread
+  state to \var{tstate}, which should not be \NULL.  The lock must
+  have been created earlier.  If this thread already has the lock,
+  deadlock ensues.  This function is not available when thread support
+  is disabled at compile time.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{PyEval_ReleaseThread}{PyThreadState *tstate}
+  Reset the current thread state to \NULL{} and release the global
+  interpreter lock.  The lock must have been created earlier and must
+  be held by the current thread.  The \var{tstate} argument, which
+  must not be \NULL, is only used to check that it represents the
+  current thread state --- if it isn't, a fatal error is reported.
+  This function is not available when thread support is disabled at
+  compile time.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyThreadState*}{PyEval_SaveThread}{}
+  Release the interpreter lock (if it has been created and thread
+  support is enabled) and reset the thread state to \NULL, returning
+  the previous thread state (which is not \NULL).  If the lock has
+  been created, the current thread must have acquired it.  (This
+  function is available even when thread support is disabled at
+  compile time.)
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{PyEval_RestoreThread}{PyThreadState *tstate}
+  Acquire the interpreter lock (if it has been created and thread
+  support is enabled) and set the thread state to \var{tstate}, which
+  must not be \NULL.  If the lock has been created, the current thread
+  must not have acquired it, otherwise deadlock ensues.  (This
+  function is available even when thread support is disabled at
+  compile time.)
+\end{cfuncdesc}
+
+The following macros are normally used without a trailing semicolon;
+look for example usage in the Python source distribution.
+
+\begin{csimplemacrodesc}{Py_BEGIN_ALLOW_THREADS}
+  This macro expands to
+  \samp{\{ PyThreadState *_save; _save = PyEval_SaveThread();}.
+  Note that it contains an opening brace; it must be matched with a
+  following \csimplemacro{Py_END_ALLOW_THREADS} macro.  See above for
+  further discussion of this macro.  It is a no-op when thread support
+  is disabled at compile time.
+\end{csimplemacrodesc}
+
+\begin{csimplemacrodesc}{Py_END_ALLOW_THREADS}
+  This macro expands to \samp{PyEval_RestoreThread(_save); \}}.
+  Note that it contains a closing brace; it must be matched with an
+  earlier \csimplemacro{Py_BEGIN_ALLOW_THREADS} macro.  See above for
+  further discussion of this macro.  It is a no-op when thread support
+  is disabled at compile time.
+\end{csimplemacrodesc}
+
+\begin{csimplemacrodesc}{Py_BLOCK_THREADS}
+  This macro expands to \samp{PyEval_RestoreThread(_save);}: it is
+  equivalent to \csimplemacro{Py_END_ALLOW_THREADS} without the
+  closing brace.  It is a no-op when thread support is disabled at
+  compile time.
+\end{csimplemacrodesc}
+
+\begin{csimplemacrodesc}{Py_UNBLOCK_THREADS}
+  This macro expands to \samp{_save = PyEval_SaveThread();}: it is
+  equivalent to \csimplemacro{Py_BEGIN_ALLOW_THREADS} without the
+  opening brace and variable declaration.  It is a no-op when thread
+  support is disabled at compile time.
+\end{csimplemacrodesc}
+
+All of the following functions are only available when thread support
+is enabled at compile time, and must be called only when the
+interpreter lock has been created.
+
+\begin{cfuncdesc}{PyInterpreterState*}{PyInterpreterState_New}{}
+  Create a new interpreter state object.  The interpreter lock need
+  not be held, but may be held if it is necessary to serialize calls
+  to this function.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{PyInterpreterState_Clear}{PyInterpreterState *interp}
+  Reset all information in an interpreter state object.  The
+  interpreter lock must be held.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{PyInterpreterState_Delete}{PyInterpreterState *interp}
+  Destroy an interpreter state object.  The interpreter lock need not
+  be held.  The interpreter state must have been reset with a previous
+  call to \cfunction{PyInterpreterState_Clear()}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyThreadState*}{PyThreadState_New}{PyInterpreterState *interp}
+  Create a new thread state object belonging to the given interpreter
+  object.  The interpreter lock need not be held, but may be held if
+  it is necessary to serialize calls to this function.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{PyThreadState_Clear}{PyThreadState *tstate}
+  Reset all information in a thread state object.  The interpreter lock
+  must be held.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{PyThreadState_Delete}{PyThreadState *tstate}
+  Destroy a thread state object.  The interpreter lock need not be
+  held.  The thread state must have been reset with a previous call to
+  \cfunction{PyThreadState_Clear()}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyThreadState*}{PyThreadState_Get}{}
+  Return the current thread state.  The interpreter lock must be
+  held.  When the current thread state is \NULL, this issues a fatal
+  error (so that the caller needn't check for \NULL).
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyThreadState*}{PyThreadState_Swap}{PyThreadState *tstate}
+  Swap the current thread state with the thread state given by the
+  argument \var{tstate}, which may be \NULL.  The interpreter lock
+  must be held.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyThreadState_GetDict}{}
+  Return a dictionary in which extensions can store thread-specific
+  state information.  Each extension should use a unique key to use to
+  store state in the dictionary.  It is okay to call this function
+  when no current thread state is available.
+  If this function returns \NULL, no exception has been raised and the
+  caller should assume no current thread state is available.
+  \versionchanged[Previously this could only be called when a current
+  thread is active, and \NULL{} meant that an exception was raised]{2.3}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyThreadState_SetAsyncExc}{long id, PyObject *exc}
+  Asynchronously raise an exception in a thread.
+  The \var{id} argument is the thread id of the target thread;
+  \var{exc} is the exception object to be raised.
+  This function does not steal any references to \var{exc}.
+  To prevent naive misuse, you must write your own C extension
+  to call this.  Must be called with the GIL held.
+  Returns the number of thread states modified; this is normally one, but
+  will be zero if the thread id isn't found.  If \var{exc} is
+  \constant{NULL}, the pending exception (if any) for the thread is cleared.
+  This raises no exceptions.
+  \versionadded{2.3}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyGILState_STATE}{PyGILState_Ensure}{}
+Ensure that the current thread is ready to call the Python C API
+regardless of the current state of Python, or of its thread lock.
+This may be called as many times as desired by a thread as long as
+each call is matched with a call to \cfunction{PyGILState_Release()}.
+In general, other thread-related APIs may be used between
+\cfunction{PyGILState_Ensure()} and \cfunction{PyGILState_Release()}
+calls as long as the thread state is restored to its previous state
+before the Release().  For example, normal usage of the
+\csimplemacro{Py_BEGIN_ALLOW_THREADS} and
+\csimplemacro{Py_END_ALLOW_THREADS} macros is acceptable.
+    
+The return value is an opaque "handle" to the thread state when
+\cfunction{PyGILState_Acquire()} was called, and must be passed to
+\cfunction{PyGILState_Release()} to ensure Python is left in the same
+state. Even though recursive calls are allowed, these handles
+\emph{cannot} be shared - each unique call to
+\cfunction{PyGILState_Ensure} must save the handle for its call to
+\cfunction{PyGILState_Release}.
+    
+When the function returns, the current thread will hold the GIL.
+Failure is a fatal error.
+  \versionadded{2.3}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{PyGILState_Release}{PyGILState_STATE}
+Release any resources previously acquired.  After this call, Python's
+state will be the same as it was prior to the corresponding
+\cfunction{PyGILState_Ensure} call (but generally this state will be
+unknown to the caller, hence the use of the GILState API.)
+    
+Every call to \cfunction{PyGILState_Ensure()} must be matched by a call to 
+\cfunction{PyGILState_Release()} on the same thread.
+  \versionadded{2.3}
+\end{cfuncdesc}
+
+
+\section{Profiling and Tracing \label{profiling}}
+
+\sectionauthor{Fred L. Drake, Jr.}{fdrake at acm.org}
+
+The Python interpreter provides some low-level support for attaching
+profiling and execution tracing facilities.  These are used for
+profiling, debugging, and coverage analysis tools.
+
+Starting with Python 2.2, the implementation of this facility was
+substantially revised, and an interface from C was added.  This C
+interface allows the profiling or tracing code to avoid the overhead
+of calling through Python-level callable objects, making a direct C
+function call instead.  The essential attributes of the facility have
+not changed; the interface allows trace functions to be installed
+per-thread, and the basic events reported to the trace function are
+the same as had been reported to the Python-level trace functions in
+previous versions.
+
+\begin{ctypedesc}[Py_tracefunc]{int (*Py_tracefunc)(PyObject *obj,
+                                PyFrameObject *frame, int what,
+                                PyObject *arg)}
+  The type of the trace function registered using
+  \cfunction{PyEval_SetProfile()} and \cfunction{PyEval_SetTrace()}.
+  The first parameter is the object passed to the registration
+  function as \var{obj}, \var{frame} is the frame object to which the
+  event pertains, \var{what} is one of the constants
+  \constant{PyTrace_CALL}, \constant{PyTrace_EXCEPTION},
+  \constant{PyTrace_LINE}, \constant{PyTrace_RETURN},
+  \constant{PyTrace_C_CALL}, \constant{PyTrace_C_EXCEPTION},
+  or \constant{PyTrace_C_RETURN}, and \var{arg}
+  depends on the value of \var{what}:
+
+  \begin{tableii}{l|l}{constant}{Value of \var{what}}{Meaning of \var{arg}}
+    \lineii{PyTrace_CALL}{Always \NULL.}
+    \lineii{PyTrace_EXCEPTION}{Exception information as returned by
+                            \function{sys.exc_info()}.}
+    \lineii{PyTrace_LINE}{Always \NULL.}
+    \lineii{PyTrace_RETURN}{Value being returned to the caller.}
+    \lineii{PyTrace_C_CALL}{Name of function being called.}
+    \lineii{PyTrace_C_EXCEPTION}{Always \NULL.}
+    \lineii{PyTrace_C_RETURN}{Always \NULL.}
+  \end{tableii}
+\end{ctypedesc}
+
+\begin{cvardesc}{int}{PyTrace_CALL}
+  The value of the \var{what} parameter to a \ctype{Py_tracefunc}
+  function when a new call to a function or method is being reported,
+  or a new entry into a generator.  Note that the creation of the
+  iterator for a generator function is not reported as there is no
+  control transfer to the Python bytecode in the corresponding frame.
+\end{cvardesc}
+
+\begin{cvardesc}{int}{PyTrace_EXCEPTION}
+  The value of the \var{what} parameter to a \ctype{Py_tracefunc}
+  function when an exception has been raised.  The callback function
+  is called with this value for \var{what} when after any bytecode is
+  processed after which the exception becomes set within the frame
+  being executed.  The effect of this is that as exception propagation
+  causes the Python stack to unwind, the callback is called upon
+  return to each frame as the exception propagates.  Only trace
+  functions receives these events; they are not needed by the
+  profiler.
+\end{cvardesc}
+
+\begin{cvardesc}{int}{PyTrace_LINE}
+  The value passed as the \var{what} parameter to a trace function
+  (but not a profiling function) when a line-number event is being
+  reported.
+\end{cvardesc}
+
+\begin{cvardesc}{int}{PyTrace_RETURN}
+  The value for the \var{what} parameter to \ctype{Py_tracefunc}
+  functions when a call is returning without propagating an exception.
+\end{cvardesc}
+
+\begin{cvardesc}{int}{PyTrace_C_CALL}
+  The value for the \var{what} parameter to \ctype{Py_tracefunc}
+  functions when a C function is about to be called.
+\end{cvardesc}
+
+\begin{cvardesc}{int}{PyTrace_C_EXCEPTION}
+  The value for the \var{what} parameter to \ctype{Py_tracefunc}
+  functions when a C function has thrown an exception.
+\end{cvardesc}
+
+\begin{cvardesc}{int}{PyTrace_C_RETURN}
+  The value for the \var{what} parameter to \ctype{Py_tracefunc}
+  functions when a C function has returned.
+\end{cvardesc}
+
+\begin{cfuncdesc}{void}{PyEval_SetProfile}{Py_tracefunc func, PyObject *obj}
+  Set the profiler function to \var{func}.  The \var{obj} parameter is
+  passed to the function as its first parameter, and may be any Python
+  object, or \NULL.  If the profile function needs to maintain state,
+  using a different value for \var{obj} for each thread provides a
+  convenient and thread-safe place to store it.  The profile function
+  is called for all monitored events except the line-number events.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{PyEval_SetTrace}{Py_tracefunc func, PyObject *obj}
+  Set the tracing function to \var{func}.  This is similar to
+  \cfunction{PyEval_SetProfile()}, except the tracing function does
+  receive line-number events.
+\end{cfuncdesc}
+
+
+\section{Advanced Debugger Support \label{advanced-debugging}}
+\sectionauthor{Fred L. Drake, Jr.}{fdrake at acm.org}
+
+These functions are only intended to be used by advanced debugging
+tools.
+
+\begin{cfuncdesc}{PyInterpreterState*}{PyInterpreterState_Head}{}
+  Return the interpreter state object at the head of the list of all
+  such objects.
+  \versionadded{2.2}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyInterpreterState*}{PyInterpreterState_Next}{PyInterpreterState *interp}
+  Return the next interpreter state object after \var{interp} from the
+  list of all such objects.
+  \versionadded{2.2}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyThreadState *}{PyInterpreterState_ThreadHead}{PyInterpreterState *interp}
+  Return the a pointer to the first \ctype{PyThreadState} object in
+  the list of threads associated with the interpreter \var{interp}.
+  \versionadded{2.2}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyThreadState*}{PyThreadState_Next}{PyThreadState *tstate}
+  Return the next thread state object after \var{tstate} from the list
+  of all such objects belonging to the same \ctype{PyInterpreterState}
+  object.
+  \versionadded{2.2}
+\end{cfuncdesc}

Added: vendor/Python/current/Doc/api/intro.tex
===================================================================
--- vendor/Python/current/Doc/api/intro.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/api/intro.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,627 @@
+\chapter{Introduction \label{intro}}
+
+
+The Application Programmer's Interface to Python gives C and
+\Cpp{} programmers access to the Python interpreter at a variety of
+levels.  The API is equally usable from \Cpp, but for brevity it is
+generally referred to as the Python/C API.  There are two
+fundamentally different reasons for using the Python/C API.  The first
+reason is to write \emph{extension modules} for specific purposes;
+these are C modules that extend the Python interpreter.  This is
+probably the most common use.  The second reason is to use Python as a
+component in a larger application; this technique is generally
+referred to as \dfn{embedding} Python in an application.
+
+Writing an extension module is a relatively well-understood process, 
+where a ``cookbook'' approach works well.  There are several tools 
+that automate the process to some extent.  While people have embedded 
+Python in other applications since its early existence, the process of 
+embedding Python is less straightforward than writing an extension.  
+
+Many API functions are useful independent of whether you're embedding 
+or extending Python; moreover, most applications that embed Python 
+will need to provide a custom extension as well, so it's probably a 
+good idea to become familiar with writing an extension before 
+attempting to embed Python in a real application.
+
+
+\section{Include Files \label{includes}}
+
+All function, type and macro definitions needed to use the Python/C
+API are included in your code by the following line:
+
+\begin{verbatim}
+#include "Python.h"
+\end{verbatim}
+
+This implies inclusion of the following standard headers:
+\code{<stdio.h>}, \code{<string.h>}, \code{<errno.h>},
+\code{<limits.h>}, and \code{<stdlib.h>} (if available).
+
+\begin{notice}[warning]
+  Since Python may define some pre-processor definitions which affect
+  the standard headers on some systems, you \emph{must} include
+  \file{Python.h} before any standard headers are included.
+\end{notice}
+
+All user visible names defined by Python.h (except those defined by
+the included standard headers) have one of the prefixes \samp{Py} or
+\samp{_Py}.  Names beginning with \samp{_Py} are for internal use by
+the Python implementation and should not be used by extension writers.
+Structure member names do not have a reserved prefix.
+
+\strong{Important:} user code should never define names that begin
+with \samp{Py} or \samp{_Py}.  This confuses the reader, and
+jeopardizes the portability of the user code to future Python
+versions, which may define additional names beginning with one of
+these prefixes.
+
+The header files are typically installed with Python.  On \UNIX, these 
+are located in the directories
+\file{\envvar{prefix}/include/python\var{version}/} and
+\file{\envvar{exec_prefix}/include/python\var{version}/}, where
+\envvar{prefix} and \envvar{exec_prefix} are defined by the
+corresponding parameters to Python's \program{configure} script and
+\var{version} is \code{sys.version[:3]}.  On Windows, the headers are
+installed in \file{\envvar{prefix}/include}, where \envvar{prefix} is
+the installation directory specified to the installer.
+
+To include the headers, place both directories (if different) on your
+compiler's search path for includes.  Do \emph{not} place the parent
+directories on the search path and then use
+\samp{\#include <python\shortversion/Python.h>}; this will break on
+multi-platform builds since the platform independent headers under
+\envvar{prefix} include the platform specific headers from
+\envvar{exec_prefix}.
+
+\Cpp{} users should note that though the API is defined entirely using
+C, the header files do properly declare the entry points to be
+\code{extern "C"}, so there is no need to do anything special to use
+the API from \Cpp.
+
+
+\section{Objects, Types and Reference Counts \label{objects}}
+
+Most Python/C API functions have one or more arguments as well as a
+return value of type \ctype{PyObject*}.  This type is a pointer
+to an opaque data type representing an arbitrary Python
+object.  Since all Python object types are treated the same way by the
+Python language in most situations (e.g., assignments, scope rules,
+and argument passing), it is only fitting that they should be
+represented by a single C type.  Almost all Python objects live on the
+heap: you never declare an automatic or static variable of type
+\ctype{PyObject}, only pointer variables of type \ctype{PyObject*} can 
+be declared.  The sole exception are the type objects\obindex{type};
+since these must never be deallocated, they are typically static
+\ctype{PyTypeObject} objects.
+
+All Python objects (even Python integers) have a \dfn{type} and a
+\dfn{reference count}.  An object's type determines what kind of object 
+it is (e.g., an integer, a list, or a user-defined function; there are 
+many more as explained in the \citetitle[../ref/ref.html]{Python
+Reference Manual}).  For each of the well-known types there is a macro
+to check whether an object is of that type; for instance,
+\samp{PyList_Check(\var{a})} is true if (and only if) the object
+pointed to by \var{a} is a Python list.
+
+
+\subsection{Reference Counts \label{refcounts}}
+
+The reference count is important because today's computers have a 
+finite (and often severely limited) memory size; it counts how many 
+different places there are that have a reference to an object.  Such a 
+place could be another object, or a global (or static) C variable, or 
+a local variable in some C function.  When an object's reference count 
+becomes zero, the object is deallocated.  If it contains references to 
+other objects, their reference count is decremented.  Those other 
+objects may be deallocated in turn, if this decrement makes their 
+reference count become zero, and so on.  (There's an obvious problem 
+with objects that reference each other here; for now, the solution is 
+``don't do that.'')
+
+Reference counts are always manipulated explicitly.  The normal way is 
+to use the macro \cfunction{Py_INCREF()}\ttindex{Py_INCREF()} to
+increment an object's reference count by one, and
+\cfunction{Py_DECREF()}\ttindex{Py_DECREF()} to decrement it by  
+one.  The \cfunction{Py_DECREF()} macro is considerably more complex
+than the incref one, since it must check whether the reference count
+becomes zero and then cause the object's deallocator to be called.
+The deallocator is a function pointer contained in the object's type
+structure.  The type-specific deallocator takes care of decrementing
+the reference counts for other objects contained in the object if this
+is a compound object type, such as a list, as well as performing any
+additional finalization that's needed.  There's no chance that the
+reference count can overflow; at least as many bits are used to hold
+the reference count as there are distinct memory locations in virtual
+memory (assuming \code{sizeof(long) >= sizeof(char*)}).  Thus, the
+reference count increment is a simple operation.
+
+It is not necessary to increment an object's reference count for every 
+local variable that contains a pointer to an object.  In theory, the 
+object's reference count goes up by one when the variable is made to 
+point to it and it goes down by one when the variable goes out of 
+scope.  However, these two cancel each other out, so at the end the 
+reference count hasn't changed.  The only real reason to use the 
+reference count is to prevent the object from being deallocated as 
+long as our variable is pointing to it.  If we know that there is at 
+least one other reference to the object that lives at least as long as 
+our variable, there is no need to increment the reference count 
+temporarily.  An important situation where this arises is in objects 
+that are passed as arguments to C functions in an extension module 
+that are called from Python; the call mechanism guarantees to hold a 
+reference to every argument for the duration of the call.
+
+However, a common pitfall is to extract an object from a list and
+hold on to it for a while without incrementing its reference count.
+Some other operation might conceivably remove the object from the
+list, decrementing its reference count and possible deallocating it.
+The real danger is that innocent-looking operations may invoke
+arbitrary Python code which could do this; there is a code path which
+allows control to flow back to the user from a \cfunction{Py_DECREF()},
+so almost any operation is potentially dangerous.
+
+A safe approach is to always use the generic operations (functions 
+whose name begins with \samp{PyObject_}, \samp{PyNumber_},
+\samp{PySequence_} or \samp{PyMapping_}).  These operations always
+increment the reference count of the object they return.  This leaves
+the caller with the responsibility to call
+\cfunction{Py_DECREF()} when they are done with the result; this soon
+becomes second nature.
+
+
+\subsubsection{Reference Count Details \label{refcountDetails}}
+
+The reference count behavior of functions in the Python/C API is best 
+explained in terms of \emph{ownership of references}.  Ownership
+pertains to references, never to objects (objects are not owned: they
+are always shared).  "Owning a reference" means being responsible for
+calling Py_DECREF on it when the reference is no longer needed. 
+Ownership can also be transferred, meaning that the code that receives
+ownership of the reference then becomes responsible for eventually
+decref'ing it by calling \cfunction{Py_DECREF()} or
+\cfunction{Py_XDECREF()} when it's no longer needed---or passing on
+this responsibility (usually to its caller).
+When a function passes ownership of a reference on to its caller, the
+caller is said to receive a \emph{new} reference.  When no ownership
+is transferred, the caller is said to \emph{borrow} the reference.
+Nothing needs to be done for a borrowed reference.
+
+Conversely, when a calling function passes it a reference to an 
+object, there are two possibilities: the function \emph{steals} a 
+reference to the object, or it does not.  \emph{Stealing a reference}
+means that when you pass a reference to a function, that function
+assumes that it now owns that reference, and you are not responsible
+for it any longer.
+
+Few functions steal references; the two notable exceptions are
+\cfunction{PyList_SetItem()}\ttindex{PyList_SetItem()} and
+\cfunction{PyTuple_SetItem()}\ttindex{PyTuple_SetItem()}, which 
+steal a reference to the item (but not to the tuple or list into which
+the item is put!).  These functions were designed to steal a reference
+because of a common idiom for populating a tuple or list with newly
+created objects; for example, the code to create the tuple \code{(1,
+2, "three")} could look like this (forgetting about error handling for
+the moment; a better way to code this is shown below):
+
+\begin{verbatim}
+PyObject *t;
+
+t = PyTuple_New(3);
+PyTuple_SetItem(t, 0, PyInt_FromLong(1L));
+PyTuple_SetItem(t, 1, PyInt_FromLong(2L));
+PyTuple_SetItem(t, 2, PyString_FromString("three"));
+\end{verbatim}
+
+Here, \cfunction{PyInt_FromLong()} returns a new reference which is
+immediately stolen by \cfunction{PyTuple_SetItem()}.  When you want to
+keep using an object although the reference to it will be stolen,
+use \cfunction{Py_INCREF()} to grab another reference before calling the
+reference-stealing function.
+
+Incidentally, \cfunction{PyTuple_SetItem()} is the \emph{only} way to
+set tuple items; \cfunction{PySequence_SetItem()} and
+\cfunction{PyObject_SetItem()} refuse to do this since tuples are an
+immutable data type.  You should only use
+\cfunction{PyTuple_SetItem()} for tuples that you are creating
+yourself.
+
+Equivalent code for populating a list can be written using
+\cfunction{PyList_New()} and \cfunction{PyList_SetItem()}.
+
+However, in practice, you will rarely use these ways of
+creating and populating a tuple or list.  There's a generic function,
+\cfunction{Py_BuildValue()}, that can create most common objects from
+C values, directed by a \dfn{format string}.  For example, the
+above two blocks of code could be replaced by the following (which
+also takes care of the error checking):
+
+\begin{verbatim}
+PyObject *tuple, *list;
+
+tuple = Py_BuildValue("(iis)", 1, 2, "three");
+list = Py_BuildValue("[iis]", 1, 2, "three");
+\end{verbatim}
+
+It is much more common to use \cfunction{PyObject_SetItem()} and
+friends with items whose references you are only borrowing, like
+arguments that were passed in to the function you are writing.  In
+that case, their behaviour regarding reference counts is much saner,
+since you don't have to increment a reference count so you can give a
+reference away (``have it be stolen'').  For example, this function
+sets all items of a list (actually, any mutable sequence) to a given
+item:
+
+\begin{verbatim}
+int
+set_all(PyObject *target, PyObject *item)
+{
+    int i, n;
+
+    n = PyObject_Length(target);
+    if (n < 0)
+        return -1;
+    for (i = 0; i < n; i++) {
+        PyObject *index = PyInt_FromLong(i);
+        if (!index)
+            return -1;
+        if (PyObject_SetItem(target, index, item) < 0)
+            return -1;
+        Py_DECREF(index);
+    }
+    return 0;
+}
+\end{verbatim}
+\ttindex{set_all()}
+
+The situation is slightly different for function return values.  
+While passing a reference to most functions does not change your 
+ownership responsibilities for that reference, many functions that 
+return a reference to an object give you ownership of the reference.
+The reason is simple: in many cases, the returned object is created 
+on the fly, and the reference you get is the only reference to the 
+object.  Therefore, the generic functions that return object 
+references, like \cfunction{PyObject_GetItem()} and 
+\cfunction{PySequence_GetItem()}, always return a new reference (the
+caller becomes the owner of the reference).
+
+It is important to realize that whether you own a reference returned 
+by a function depends on which function you call only --- \emph{the
+plumage} (the type of the object passed as an
+argument to the function) \emph{doesn't enter into it!}  Thus, if you 
+extract an item from a list using \cfunction{PyList_GetItem()}, you
+don't own the reference --- but if you obtain the same item from the
+same list using \cfunction{PySequence_GetItem()} (which happens to
+take exactly the same arguments), you do own a reference to the
+returned object.
+
+Here is an example of how you could write a function that computes the
+sum of the items in a list of integers; once using 
+\cfunction{PyList_GetItem()}\ttindex{PyList_GetItem()}, and once using
+\cfunction{PySequence_GetItem()}\ttindex{PySequence_GetItem()}.
+
+\begin{verbatim}
+long
+sum_list(PyObject *list)
+{
+    int i, n;
+    long total = 0;
+    PyObject *item;
+
+    n = PyList_Size(list);
+    if (n < 0)
+        return -1; /* Not a list */
+    for (i = 0; i < n; i++) {
+        item = PyList_GetItem(list, i); /* Can't fail */
+        if (!PyInt_Check(item)) continue; /* Skip non-integers */
+        total += PyInt_AsLong(item);
+    }
+    return total;
+}
+\end{verbatim}
+\ttindex{sum_list()}
+
+\begin{verbatim}
+long
+sum_sequence(PyObject *sequence)
+{
+    int i, n;
+    long total = 0;
+    PyObject *item;
+    n = PySequence_Length(sequence);
+    if (n < 0)
+        return -1; /* Has no length */
+    for (i = 0; i < n; i++) {
+        item = PySequence_GetItem(sequence, i);
+        if (item == NULL)
+            return -1; /* Not a sequence, or other failure */
+        if (PyInt_Check(item))
+            total += PyInt_AsLong(item);
+        Py_DECREF(item); /* Discard reference ownership */
+    }
+    return total;
+}
+\end{verbatim}
+\ttindex{sum_sequence()}
+
+
+\subsection{Types \label{types}}
+
+There are few other data types that play a significant role in 
+the Python/C API; most are simple C types such as \ctype{int}, 
+\ctype{long}, \ctype{double} and \ctype{char*}.  A few structure types 
+are used to describe static tables used to list the functions exported 
+by a module or the data attributes of a new object type, and another
+is used to describe the value of a complex number.  These will 
+be discussed together with the functions that use them.
+
+
+\section{Exceptions \label{exceptions}}
+
+The Python programmer only needs to deal with exceptions if specific 
+error handling is required; unhandled exceptions are automatically 
+propagated to the caller, then to the caller's caller, and so on, until
+they reach the top-level interpreter, where they are reported to the 
+user accompanied by a stack traceback.
+
+For C programmers, however, error checking always has to be explicit.  
+All functions in the Python/C API can raise exceptions, unless an 
+explicit claim is made otherwise in a function's documentation.  In 
+general, when a function encounters an error, it sets an exception, 
+discards any object references that it owns, and returns an 
+error indicator --- usually \NULL{} or \code{-1}.  A few functions 
+return a Boolean true/false result, with false indicating an error.
+Very few functions return no explicit error indicator or have an 
+ambiguous return value, and require explicit testing for errors with 
+\cfunction{PyErr_Occurred()}\ttindex{PyErr_Occurred()}.
+
+Exception state is maintained in per-thread storage (this is 
+equivalent to using global storage in an unthreaded application).  A 
+thread can be in one of two states: an exception has occurred, or not.
+The function \cfunction{PyErr_Occurred()} can be used to check for
+this: it returns a borrowed reference to the exception type object
+when an exception has occurred, and \NULL{} otherwise.  There are a
+number of functions to set the exception state:
+\cfunction{PyErr_SetString()}\ttindex{PyErr_SetString()} is the most
+common (though not the most general) function to set the exception
+state, and \cfunction{PyErr_Clear()}\ttindex{PyErr_Clear()} clears the
+exception state.
+
+The full exception state consists of three objects (all of which can 
+be \NULL): the exception type, the corresponding exception 
+value, and the traceback.  These have the same meanings as the Python
+\withsubitem{(in module sys)}{
+  \ttindex{exc_type}\ttindex{exc_value}\ttindex{exc_traceback}}
+objects \code{sys.exc_type}, \code{sys.exc_value}, and
+\code{sys.exc_traceback}; however, they are not the same: the Python
+objects represent the last exception being handled by a Python 
+\keyword{try} \ldots\ \keyword{except} statement, while the C level
+exception state only exists while an exception is being passed on
+between C functions until it reaches the Python bytecode interpreter's 
+main loop, which takes care of transferring it to \code{sys.exc_type}
+and friends.
+
+Note that starting with Python 1.5, the preferred, thread-safe way to 
+access the exception state from Python code is to call the function
+\withsubitem{(in module sys)}{\ttindex{exc_info()}}
+\function{sys.exc_info()}, which returns the per-thread exception state 
+for Python code.  Also, the semantics of both ways to access the 
+exception state have changed so that a function which catches an 
+exception will save and restore its thread's exception state so as to 
+preserve the exception state of its caller.  This prevents common bugs 
+in exception handling code caused by an innocent-looking function 
+overwriting the exception being handled; it also reduces the often 
+unwanted lifetime extension for objects that are referenced by the 
+stack frames in the traceback.
+
+As a general principle, a function that calls another function to 
+perform some task should check whether the called function raised an 
+exception, and if so, pass the exception state on to its caller.  It 
+should discard any object references that it owns, and return an 
+error indicator, but it should \emph{not} set another exception ---
+that would overwrite the exception that was just raised, and lose
+important information about the exact cause of the error.
+
+A simple example of detecting exceptions and passing them on is shown
+in the \cfunction{sum_sequence()}\ttindex{sum_sequence()} example
+above.  It so happens that that example doesn't need to clean up any
+owned references when it detects an error.  The following example
+function shows some error cleanup.  First, to remind you why you like
+Python, we show the equivalent Python code:
+
+\begin{verbatim}
+def incr_item(dict, key):
+    try:
+        item = dict[key]
+    except KeyError:
+        item = 0
+    dict[key] = item + 1
+\end{verbatim}
+\ttindex{incr_item()}
+
+Here is the corresponding C code, in all its glory:
+
+\begin{verbatim}
+int
+incr_item(PyObject *dict, PyObject *key)
+{
+    /* Objects all initialized to NULL for Py_XDECREF */
+    PyObject *item = NULL, *const_one = NULL, *incremented_item = NULL;
+    int rv = -1; /* Return value initialized to -1 (failure) */
+
+    item = PyObject_GetItem(dict, key);
+    if (item == NULL) {
+        /* Handle KeyError only: */
+        if (!PyErr_ExceptionMatches(PyExc_KeyError))
+            goto error;
+
+        /* Clear the error and use zero: */
+        PyErr_Clear();
+        item = PyInt_FromLong(0L);
+        if (item == NULL)
+            goto error;
+    }
+    const_one = PyInt_FromLong(1L);
+    if (const_one == NULL)
+        goto error;
+
+    incremented_item = PyNumber_Add(item, const_one);
+    if (incremented_item == NULL)
+        goto error;
+
+    if (PyObject_SetItem(dict, key, incremented_item) < 0)
+        goto error;
+    rv = 0; /* Success */
+    /* Continue with cleanup code */
+
+ error:
+    /* Cleanup code, shared by success and failure path */
+
+    /* Use Py_XDECREF() to ignore NULL references */
+    Py_XDECREF(item);
+    Py_XDECREF(const_one);
+    Py_XDECREF(incremented_item);
+
+    return rv; /* -1 for error, 0 for success */
+}
+\end{verbatim}
+\ttindex{incr_item()}
+
+This example represents an endorsed use of the \keyword{goto} statement 
+in C!  It illustrates the use of
+\cfunction{PyErr_ExceptionMatches()}\ttindex{PyErr_ExceptionMatches()} and
+\cfunction{PyErr_Clear()}\ttindex{PyErr_Clear()} to
+handle specific exceptions, and the use of
+\cfunction{Py_XDECREF()}\ttindex{Py_XDECREF()} to
+dispose of owned references that may be \NULL{} (note the
+\character{X} in the name; \cfunction{Py_DECREF()} would crash when
+confronted with a \NULL{} reference).  It is important that the
+variables used to hold owned references are initialized to \NULL{} for
+this to work; likewise, the proposed return value is initialized to
+\code{-1} (failure) and only set to success after the final call made
+is successful.
+
+
+\section{Embedding Python \label{embedding}}
+
+The one important task that only embedders (as opposed to extension
+writers) of the Python interpreter have to worry about is the
+initialization, and possibly the finalization, of the Python
+interpreter.  Most functionality of the interpreter can only be used
+after the interpreter has been initialized.
+
+The basic initialization function is
+\cfunction{Py_Initialize()}\ttindex{Py_Initialize()}.
+This initializes the table of loaded modules, and creates the
+fundamental modules \module{__builtin__}\refbimodindex{__builtin__},
+\module{__main__}\refbimodindex{__main__}, \module{sys}\refbimodindex{sys},
+and \module{exceptions}.\refbimodindex{exceptions}  It also initializes
+the module search path (\code{sys.path}).%
+\indexiii{module}{search}{path}
+\withsubitem{(in module sys)}{\ttindex{path}}
+
+\cfunction{Py_Initialize()} does not set the ``script argument list'' 
+(\code{sys.argv}).  If this variable is needed by Python code that 
+will be executed later, it must be set explicitly with a call to 
+\code{PySys_SetArgv(\var{argc},
+\var{argv})}\ttindex{PySys_SetArgv()} subsequent to the call to
+\cfunction{Py_Initialize()}.
+
+On most systems (in particular, on \UNIX{} and Windows, although the
+details are slightly different),
+\cfunction{Py_Initialize()} calculates the module search path based
+upon its best guess for the location of the standard Python
+interpreter executable, assuming that the Python library is found in a
+fixed location relative to the Python interpreter executable.  In
+particular, it looks for a directory named
+\file{lib/python\shortversion} relative to the parent directory where
+the executable named \file{python} is found on the shell command
+search path (the environment variable \envvar{PATH}).
+
+For instance, if the Python executable is found in
+\file{/usr/local/bin/python}, it will assume that the libraries are in
+\file{/usr/local/lib/python\shortversion}.  (In fact, this particular path
+is also the ``fallback'' location, used when no executable file named
+\file{python} is found along \envvar{PATH}.)  The user can override
+this behavior by setting the environment variable \envvar{PYTHONHOME},
+or insert additional directories in front of the standard path by
+setting \envvar{PYTHONPATH}.
+
+The embedding application can steer the search by calling 
+\code{Py_SetProgramName(\var{file})}\ttindex{Py_SetProgramName()} \emph{before} calling 
+\cfunction{Py_Initialize()}.  Note that \envvar{PYTHONHOME} still
+overrides this and \envvar{PYTHONPATH} is still inserted in front of
+the standard path.  An application that requires total control has to
+provide its own implementation of
+\cfunction{Py_GetPath()}\ttindex{Py_GetPath()},
+\cfunction{Py_GetPrefix()}\ttindex{Py_GetPrefix()},
+\cfunction{Py_GetExecPrefix()}\ttindex{Py_GetExecPrefix()}, and
+\cfunction{Py_GetProgramFullPath()}\ttindex{Py_GetProgramFullPath()} (all
+defined in \file{Modules/getpath.c}).
+
+Sometimes, it is desirable to ``uninitialize'' Python.  For instance, 
+the application may want to start over (make another call to 
+\cfunction{Py_Initialize()}) or the application is simply done with its 
+use of Python and wants to free memory allocated by Python.  This
+can be accomplished by calling \cfunction{Py_Finalize()}.  The function
+\cfunction{Py_IsInitialized()}\ttindex{Py_IsInitialized()} returns
+true if Python is currently in the initialized state.  More
+information about these functions is given in a later chapter.
+Notice that \cfunction{Py_Finalize} does \emph{not} free all memory
+allocated by the Python interpreter, e.g. memory allocated by extension
+modules currently cannot be released.
+
+
+\section{Debugging Builds \label{debugging}}
+
+Python can be built with several macros to enable extra checks of the
+interpreter and extension modules.  These checks tend to add a large
+amount of overhead to the runtime so they are not enabled by default.
+
+A full list of the various types of debugging builds is in the file
+\file{Misc/SpecialBuilds.txt} in the Python source distribution.
+Builds are available that support tracing of reference counts,
+debugging the memory allocator, or low-level profiling of the main
+interpreter loop.  Only the most frequently-used builds will be
+described in the remainder of this section.
+
+Compiling the interpreter with the \csimplemacro{Py_DEBUG} macro
+defined produces what is generally meant by "a debug build" of Python.
+\csimplemacro{Py_DEBUG} is enabled in the \UNIX{} build by adding
+\longprogramopt{with-pydebug} to the \file{configure} command.  It is also
+implied by the presence of the not-Python-specific
+\csimplemacro{_DEBUG} macro.  When \csimplemacro{Py_DEBUG} is enabled
+in the \UNIX{} build, compiler optimization is disabled.
+
+In addition to the reference count debugging described below, the
+following extra checks are performed:
+
+\begin{itemize}
+      \item Extra checks are added to the object allocator.
+      \item Extra checks are added to the parser and compiler.
+      \item Downcasts from wide types to narrow types are checked for
+            loss of information.
+      \item A number of assertions are added to the dictionary and set
+            implementations.  In addition, the set object acquires a
+            \method{test_c_api} method.
+      \item Sanity checks of the input arguments are added to frame
+            creation. 
+      \item The storage for long ints is initialized with a known
+            invalid pattern to catch reference to uninitialized
+            digits. 
+      \item Low-level tracing and extra exception checking are added
+            to the runtime virtual machine.
+      \item Extra checks are added to the memory arena implementation.
+      \item Extra debugging is added to the thread module.
+\end{itemize}
+
+There may be additional checks not mentioned here.
+
+Defining \csimplemacro{Py_TRACE_REFS} enables reference tracing.  When
+defined, a circular doubly linked list of active objects is maintained
+by adding two extra fields to every \ctype{PyObject}.  Total
+allocations are tracked as well.  Upon exit, all existing references
+are printed.  (In interactive mode this happens after every statement
+run by the interpreter.)  Implied by \csimplemacro{Py_DEBUG}.
+
+Please refer to \file{Misc/SpecialBuilds.txt} in the Python source
+distribution for more detailed information.

Added: vendor/Python/current/Doc/api/memory.tex
===================================================================
--- vendor/Python/current/Doc/api/memory.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/api/memory.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,204 @@
+\chapter{Memory Management \label{memory}}
+\sectionauthor{Vladimir Marangozov}{Vladimir.Marangozov at inrialpes.fr}
+
+
+\section{Overview \label{memoryOverview}}
+
+Memory management in Python involves a private heap containing all
+Python objects and data structures. The management of this private
+heap is ensured internally by the \emph{Python memory manager}.  The
+Python memory manager has different components which deal with various
+dynamic storage management aspects, like sharing, segmentation,
+preallocation or caching.
+
+At the lowest level, a raw memory allocator ensures that there is
+enough room in the private heap for storing all Python-related data
+by interacting with the memory manager of the operating system. On top
+of the raw memory allocator, several object-specific allocators
+operate on the same heap and implement distinct memory management
+policies adapted to the peculiarities of every object type. For
+example, integer objects are managed differently within the heap than
+strings, tuples or dictionaries because integers imply different
+storage requirements and speed/space tradeoffs. The Python memory
+manager thus delegates some of the work to the object-specific
+allocators, but ensures that the latter operate within the bounds of
+the private heap.
+
+It is important to understand that the management of the Python heap
+is performed by the interpreter itself and that the user has no
+control over it, even if she regularly manipulates object pointers to
+memory blocks inside that heap.  The allocation of heap space for
+Python objects and other internal buffers is performed on demand by
+the Python memory manager through the Python/C API functions listed in
+this document.
+
+To avoid memory corruption, extension writers should never try to
+operate on Python objects with the functions exported by the C
+library: \cfunction{malloc()}\ttindex{malloc()},
+\cfunction{calloc()}\ttindex{calloc()},
+\cfunction{realloc()}\ttindex{realloc()} and
+\cfunction{free()}\ttindex{free()}.  This will result in 
+mixed calls between the C allocator and the Python memory manager
+with fatal consequences, because they implement different algorithms
+and operate on different heaps.  However, one may safely allocate and
+release memory blocks with the C library allocator for individual
+purposes, as shown in the following example:
+
+\begin{verbatim}
+    PyObject *res;
+    char *buf = (char *) malloc(BUFSIZ); /* for I/O */
+
+    if (buf == NULL)
+        return PyErr_NoMemory();
+    ...Do some I/O operation involving buf...
+    res = PyString_FromString(buf);
+    free(buf); /* malloc'ed */
+    return res;
+\end{verbatim}
+
+In this example, the memory request for the I/O buffer is handled by
+the C library allocator. The Python memory manager is involved only
+in the allocation of the string object returned as a result.
+
+In most situations, however, it is recommended to allocate memory from
+the Python heap specifically because the latter is under control of
+the Python memory manager. For example, this is required when the
+interpreter is extended with new object types written in C. Another
+reason for using the Python heap is the desire to \emph{inform} the
+Python memory manager about the memory needs of the extension module.
+Even when the requested memory is used exclusively for internal,
+highly-specific purposes, delegating all memory requests to the Python
+memory manager causes the interpreter to have a more accurate image of
+its memory footprint as a whole. Consequently, under certain
+circumstances, the Python memory manager may or may not trigger
+appropriate actions, like garbage collection, memory compaction or
+other preventive procedures. Note that by using the C library
+allocator as shown in the previous example, the allocated memory for
+the I/O buffer escapes completely the Python memory manager.
+
+
+\section{Memory Interface \label{memoryInterface}}
+
+The following function sets, modeled after the ANSI C standard,
+but specifying  behavior when requesting zero bytes,
+are available for allocating and releasing memory from the Python heap:
+
+
+\begin{cfuncdesc}{void*}{PyMem_Malloc}{size_t n}
+  Allocates \var{n} bytes and returns a pointer of type \ctype{void*}
+  to the allocated memory, or \NULL{} if the request fails.
+  Requesting zero bytes returns a distinct non-\NULL{} pointer if
+  possible, as if \cfunction{PyMem_Malloc(1)} had been called instead.
+  The memory will not have been initialized in any way.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void*}{PyMem_Realloc}{void *p, size_t n}
+  Resizes the memory block pointed to by \var{p} to \var{n} bytes.
+  The contents will be unchanged to the minimum of the old and the new
+  sizes. If \var{p} is \NULL, the call is equivalent to
+  \cfunction{PyMem_Malloc(\var{n})}; else if \var{n} is equal to zero, the
+  memory block is resized but is not freed, and the returned pointer
+  is non-\NULL.  Unless \var{p} is \NULL, it must have been
+  returned by a previous call to \cfunction{PyMem_Malloc()} or
+  \cfunction{PyMem_Realloc()}. If the request fails,
+  \cfunction{PyMem_Realloc()} returns \NULL{} and \var{p} remains a
+  valid pointer to the previous memory area.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{PyMem_Free}{void *p}
+  Frees the memory block pointed to by \var{p}, which must have been
+  returned by a previous call to \cfunction{PyMem_Malloc()} or
+  \cfunction{PyMem_Realloc()}.  Otherwise, or if
+  \cfunction{PyMem_Free(p)} has been called before, undefined
+  behavior occurs. If \var{p} is \NULL, no operation is performed.
+\end{cfuncdesc}
+
+The following type-oriented macros are provided for convenience.  Note 
+that \var{TYPE} refers to any C type.
+
+\begin{cfuncdesc}{\var{TYPE}*}{PyMem_New}{TYPE, size_t n}
+  Same as \cfunction{PyMem_Malloc()}, but allocates \code{(\var{n} *
+  sizeof(\var{TYPE}))} bytes of memory.  Returns a pointer cast to
+  \ctype{\var{TYPE}*}.  The memory will not have been initialized in
+  any way.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{\var{TYPE}*}{PyMem_Resize}{void *p, TYPE, size_t n}
+  Same as \cfunction{PyMem_Realloc()}, but the memory block is resized
+  to \code{(\var{n} * sizeof(\var{TYPE}))} bytes.  Returns a pointer
+  cast to \ctype{\var{TYPE}*}. On return, \var{p} will be a pointer to
+  the new memory area, or \NULL{} in the event of failure.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{PyMem_Del}{void *p}
+  Same as \cfunction{PyMem_Free()}.
+\end{cfuncdesc}
+
+In addition, the following macro sets are provided for calling the
+Python memory allocator directly, without involving the C API functions
+listed above. However, note that their use does not preserve binary
+compatibility across Python versions and is therefore deprecated in
+extension modules.
+
+\cfunction{PyMem_MALLOC()}, \cfunction{PyMem_REALLOC()}, \cfunction{PyMem_FREE()}.
+
+\cfunction{PyMem_NEW()}, \cfunction{PyMem_RESIZE()}, \cfunction{PyMem_DEL()}.
+
+
+\section{Examples \label{memoryExamples}}
+
+Here is the example from section \ref{memoryOverview}, rewritten so
+that the I/O buffer is allocated from the Python heap by using the
+first function set:
+
+\begin{verbatim}
+    PyObject *res;
+    char *buf = (char *) PyMem_Malloc(BUFSIZ); /* for I/O */
+
+    if (buf == NULL)
+        return PyErr_NoMemory();
+    /* ...Do some I/O operation involving buf... */
+    res = PyString_FromString(buf);
+    PyMem_Free(buf); /* allocated with PyMem_Malloc */
+    return res;
+\end{verbatim}
+
+The same code using the type-oriented function set:
+
+\begin{verbatim}
+    PyObject *res;
+    char *buf = PyMem_New(char, BUFSIZ); /* for I/O */
+
+    if (buf == NULL)
+        return PyErr_NoMemory();
+    /* ...Do some I/O operation involving buf... */
+    res = PyString_FromString(buf);
+    PyMem_Del(buf); /* allocated with PyMem_New */
+    return res;
+\end{verbatim}
+
+Note that in the two examples above, the buffer is always
+manipulated via functions belonging to the same set. Indeed, it
+is required to use the same memory API family for a given
+memory block, so that the risk of mixing different allocators is
+reduced to a minimum. The following code sequence contains two errors,
+one of which is labeled as \emph{fatal} because it mixes two different
+allocators operating on different heaps.
+
+\begin{verbatim}
+char *buf1 = PyMem_New(char, BUFSIZ);
+char *buf2 = (char *) malloc(BUFSIZ);
+char *buf3 = (char *) PyMem_Malloc(BUFSIZ);
+...
+PyMem_Del(buf3);  /* Wrong -- should be PyMem_Free() */
+free(buf2);       /* Right -- allocated via malloc() */
+free(buf1);       /* Fatal -- should be PyMem_Del()  */
+\end{verbatim}
+
+In addition to the functions aimed at handling raw memory blocks from
+the Python heap, objects in Python are allocated and released with
+\cfunction{PyObject_New()}, \cfunction{PyObject_NewVar()} and
+\cfunction{PyObject_Del()}.
+
+These will be explained in the next chapter on defining and
+implementing new object types in C.

Added: vendor/Python/current/Doc/api/newtypes.tex
===================================================================
--- vendor/Python/current/Doc/api/newtypes.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/api/newtypes.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1780 @@
+\chapter{Object Implementation Support \label{newTypes}}
+
+
+This chapter describes the functions, types, and macros used when
+defining new object types.
+
+
+\section{Allocating Objects on the Heap
+         \label{allocating-objects}}
+
+\begin{cfuncdesc}{PyObject*}{_PyObject_New}{PyTypeObject *type}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyVarObject*}{_PyObject_NewVar}{PyTypeObject *type, Py_ssize_t size}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{_PyObject_Del}{PyObject *op}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyObject_Init}{PyObject *op,
+					    PyTypeObject *type}
+  Initialize a newly-allocated object \var{op} with its type and
+  initial reference.  Returns the initialized object.  If \var{type}
+  indicates that the object participates in the cyclic garbage
+  detector, it is added to the detector's set of observed objects.
+  Other fields of the object are not affected.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyVarObject*}{PyObject_InitVar}{PyVarObject *op,
+						  PyTypeObject *type, Py_ssize_t size}
+  This does everything \cfunction{PyObject_Init()} does, and also
+  initializes the length information for a variable-size object.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{\var{TYPE}*}{PyObject_New}{TYPE, PyTypeObject *type}
+  Allocate a new Python object using the C structure type \var{TYPE}
+  and the Python type object \var{type}.  Fields not defined by the
+  Python object header are not initialized; the object's reference
+  count will be one.  The size of the memory
+  allocation is determined from the \member{tp_basicsize} field of the
+  type object.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{\var{TYPE}*}{PyObject_NewVar}{TYPE, PyTypeObject *type,
+                                                Py_ssize_t size}
+  Allocate a new Python object using the C structure type \var{TYPE}
+  and the Python type object \var{type}.  Fields not defined by the
+  Python object header are not initialized.  The allocated memory
+  allows for the \var{TYPE} structure plus \var{size} fields of the
+  size given by the \member{tp_itemsize} field of \var{type}.  This is
+  useful for implementing objects like tuples, which are able to
+  determine their size at construction time.  Embedding the array of
+  fields into the same allocation decreases the number of allocations,
+  improving the memory management efficiency.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{PyObject_Del}{PyObject *op}
+  Releases memory allocated to an object using
+  \cfunction{PyObject_New()} or \cfunction{PyObject_NewVar()}.  This
+  is normally called from the \member{tp_dealloc} handler specified in
+  the object's type.  The fields of the object should not be accessed
+  after this call as the memory is no longer a valid Python object.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{Py_InitModule}{char *name,
+                                            PyMethodDef *methods}
+  Create a new module object based on a name and table of functions,
+  returning the new module object.
+
+  \versionchanged[Older versions of Python did not support \NULL{} as
+                  the value for the \var{methods} argument]{2.3}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{Py_InitModule3}{char *name,
+                                             PyMethodDef *methods,
+                                             char *doc}
+  Create a new module object based on a name and table of functions,
+  returning the new module object.  If \var{doc} is non-\NULL, it will
+  be used to define the docstring for the module.
+
+  \versionchanged[Older versions of Python did not support \NULL{} as
+                  the value for the \var{methods} argument]{2.3}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{Py_InitModule4}{char *name,
+                                             PyMethodDef *methods,
+                                             char *doc, PyObject *self,
+                                             int apiver}
+  Create a new module object based on a name and table of functions,
+  returning the new module object.  If \var{doc} is non-\NULL, it will
+  be used to define the docstring for the module.  If \var{self} is
+  non-\NULL, it will passed to the functions of the module as their
+  (otherwise \NULL) first parameter.  (This was added as an
+  experimental feature, and there are no known uses in the current
+  version of Python.)  For \var{apiver}, the only value which should
+  be passed is defined by the constant \constant{PYTHON_API_VERSION}.
+
+  \note{Most uses of this function should probably be using
+  the \cfunction{Py_InitModule3()} instead; only use this if you are
+  sure you need it.}
+
+  \versionchanged[Older versions of Python did not support \NULL{} as
+                  the value for the \var{methods} argument]{2.3}
+\end{cfuncdesc}
+
+\begin{cvardesc}{PyObject}{_Py_NoneStruct}
+  Object which is visible in Python as \code{None}.  This should only
+  be accessed using the \code{Py_None} macro, which evaluates to a
+  pointer to this object.
+\end{cvardesc}
+
+
+\section{Common Object Structures \label{common-structs}}
+
+There are a large number of structures which are used in the
+definition of object types for Python.  This section describes these
+structures and how they are used.
+
+All Python objects ultimately share a small number of fields at the
+beginning of the object's representation in memory.  These are
+represented by the \ctype{PyObject} and \ctype{PyVarObject} types,
+which are defined, in turn, by the expansions of some macros also
+used, whether directly or indirectly, in the definition of all other
+Python objects.
+
+\begin{ctypedesc}{PyObject}
+  All object types are extensions of this type.  This is a type which
+  contains the information Python needs to treat a pointer to an
+  object as an object.  In a normal ``release'' build, it contains
+  only the objects reference count and a pointer to the corresponding
+  type object.  It corresponds to the fields defined by the
+  expansion of the \code{PyObject_HEAD} macro.
+\end{ctypedesc}
+
+\begin{ctypedesc}{PyVarObject}
+  This is an extension of \ctype{PyObject} that adds the
+  \member{ob_size} field.  This is only used for objects that have
+  some notion of \emph{length}.  This type does not often appear in
+  the Python/C API.  It corresponds to the fields defined by the
+  expansion of the \code{PyObject_VAR_HEAD} macro.
+\end{ctypedesc}
+
+These macros are used in the definition of \ctype{PyObject} and
+\ctype{PyVarObject}:
+
+\begin{csimplemacrodesc}{PyObject_HEAD}
+  This is a macro which expands to the declarations of the fields of
+  the \ctype{PyObject} type; it is used when declaring new types which
+  represent objects without a varying length.  The specific fields it
+  expands to depend on the definition of
+  \csimplemacro{Py_TRACE_REFS}.  By default, that macro is not
+  defined, and \csimplemacro{PyObject_HEAD} expands to:
+  \begin{verbatim}
+    Py_ssize_t ob_refcnt;
+    PyTypeObject *ob_type;
+  \end{verbatim}
+  When \csimplemacro{Py_TRACE_REFS} is defined, it expands to:
+  \begin{verbatim}
+    PyObject *_ob_next, *_ob_prev;
+    Py_ssize_t ob_refcnt;
+    PyTypeObject *ob_type;
+  \end{verbatim}
+\end{csimplemacrodesc}
+
+\begin{csimplemacrodesc}{PyObject_VAR_HEAD}
+  This is a macro which expands to the declarations of the fields of
+  the \ctype{PyVarObject} type; it is used when declaring new types which
+  represent objects with a length that varies from instance to
+  instance.  This macro always expands to:
+  \begin{verbatim}
+    PyObject_HEAD
+    Py_ssize_t ob_size;
+  \end{verbatim}
+  Note that \csimplemacro{PyObject_HEAD} is part of the expansion, and
+  that its own expansion varies depending on the definition of
+  \csimplemacro{Py_TRACE_REFS}.
+\end{csimplemacrodesc}
+
+PyObject_HEAD_INIT
+
+\begin{ctypedesc}{PyCFunction}
+  Type of the functions used to implement most Python callables in C.
+  Functions of this type take two \ctype{PyObject*} parameters and
+  return one such value.  If the return value is \NULL, an exception
+  shall have been set.  If not \NULL, the return value is interpreted
+  as the return value of the function as exposed in Python.  The
+  function must return a new reference.
+\end{ctypedesc}
+
+\begin{ctypedesc}{PyMethodDef}
+  Structure used to describe a method of an extension type.  This
+  structure has four fields:
+
+  \begin{tableiii}{l|l|l}{member}{Field}{C Type}{Meaning}
+    \lineiii{ml_name}{char *}{name of the method}
+    \lineiii{ml_meth}{PyCFunction}{pointer to the C implementation}
+    \lineiii{ml_flags}{int}{flag bits indicating how the call should be
+                            constructed}
+    \lineiii{ml_doc}{char *}{points to the contents of the docstring}
+  \end{tableiii}
+\end{ctypedesc}
+
+The \member{ml_meth} is a C function pointer.  The functions may be of
+different types, but they always return \ctype{PyObject*}.  If the
+function is not of the \ctype{PyCFunction}, the compiler will require
+a cast in the method table.  Even though \ctype{PyCFunction} defines
+the first parameter as \ctype{PyObject*}, it is common that the method
+implementation uses a the specific C type of the \var{self} object.
+
+The \member{ml_flags} field is a bitfield which can include the
+following flags.  The individual flags indicate either a calling
+convention or a binding convention.  Of the calling convention flags,
+only \constant{METH_VARARGS} and \constant{METH_KEYWORDS} can be
+combined (but note that \constant{METH_KEYWORDS} alone is equivalent
+to \code{\constant{METH_VARARGS} | \constant{METH_KEYWORDS}}).
+Any of the calling convention flags can be combined with a
+binding flag.
+
+\begin{datadesc}{METH_VARARGS}
+  This is the typical calling convention, where the methods have the
+  type \ctype{PyCFunction}. The function expects two
+  \ctype{PyObject*} values.  The first one is the \var{self} object for
+  methods; for module functions, it has the value given to
+  \cfunction{Py_InitModule4()} (or \NULL{} if
+  \cfunction{Py_InitModule()} was used).  The second parameter
+  (often called \var{args}) is a tuple object representing all
+  arguments. This parameter is typically processed using
+  \cfunction{PyArg_ParseTuple()} or \cfunction{PyArg_UnpackTuple}.
+\end{datadesc}
+
+\begin{datadesc}{METH_KEYWORDS}
+  Methods with these flags must be of type
+  \ctype{PyCFunctionWithKeywords}.  The function expects three
+  parameters: \var{self}, \var{args}, and a dictionary of all the
+  keyword arguments.  The flag is typically combined with
+  \constant{METH_VARARGS}, and the parameters are typically processed
+  using \cfunction{PyArg_ParseTupleAndKeywords()}.
+\end{datadesc}
+
+\begin{datadesc}{METH_NOARGS}
+  Methods without parameters don't need to check whether arguments are
+  given if they are listed with the \constant{METH_NOARGS} flag.  They
+  need to be of type \ctype{PyCFunction}.  When used with object
+  methods, the first parameter is typically named \code{self} and will
+  hold a reference to the object instance.  In all cases the second
+  parameter will be \NULL.
+\end{datadesc}
+
+\begin{datadesc}{METH_O}
+  Methods with a single object argument can be listed with the
+  \constant{METH_O} flag, instead of invoking
+  \cfunction{PyArg_ParseTuple()} with a \code{"O"} argument. They have
+  the type \ctype{PyCFunction}, with the \var{self} parameter, and a
+  \ctype{PyObject*} parameter representing the single argument.
+\end{datadesc}
+
+\begin{datadesc}{METH_OLDARGS}
+  This calling convention is deprecated.  The method must be of type
+  \ctype{PyCFunction}.  The second argument is \NULL{} if no arguments
+  are given, a single object if exactly one argument is given, and a
+  tuple of objects if more than one argument is given.  There is no
+  way for a function using this convention to distinguish between a
+  call with multiple arguments and a call with a tuple as the only
+  argument.
+\end{datadesc}
+
+These two constants are not used to indicate the calling convention
+but the binding when use with methods of classes.  These may not be
+used for functions defined for modules.  At most one of these flags
+may be set for any given method.
+
+\begin{datadesc}{METH_CLASS}
+  The method will be passed the type object as the first parameter
+  rather than an instance of the type.  This is used to create
+  \emph{class methods}, similar to what is created when using the
+  \function{classmethod()}\bifuncindex{classmethod} built-in
+  function.
+  \versionadded{2.3}
+\end{datadesc}
+
+\begin{datadesc}{METH_STATIC}
+  The method will be passed \NULL{} as the first parameter rather than
+  an instance of the type.  This is used to create \emph{static
+  methods}, similar to what is created when using the
+  \function{staticmethod()}\bifuncindex{staticmethod} built-in
+  function.
+  \versionadded{2.3}
+\end{datadesc}
+
+One other constant controls whether a method is loaded in place of
+another definition with the same method name.
+
+\begin{datadesc}{METH_COEXIST}
+  The method will be loaded in place of existing definitions.  Without
+  \var{METH_COEXIST}, the default is to skip repeated definitions.  Since
+  slot wrappers are loaded before the method table, the existence of a
+  \var{sq_contains} slot, for example, would generate a wrapped method
+  named \method{__contains__()} and preclude the loading of a
+  corresponding PyCFunction with the same name.  With the flag defined,
+  the PyCFunction will be loaded in place of the wrapper object and will
+  co-exist with the slot.  This is helpful because calls to PyCFunctions
+  are optimized more than wrapper object calls.
+  \versionadded{2.4}
+\end{datadesc}
+
+\begin{cfuncdesc}{PyObject*}{Py_FindMethod}{PyMethodDef table[],
+                                            PyObject *ob, char *name}
+  Return a bound method object for an extension type implemented in
+  C.  This can be useful in the implementation of a
+  \member{tp_getattro} or \member{tp_getattr} handler that does not
+  use the \cfunction{PyObject_GenericGetAttr()} function.
+\end{cfuncdesc}
+
+
+\section{Type Objects \label{type-structs}}
+
+Perhaps one of the most important structures of the Python object
+system is the structure that defines a new type: the
+\ctype{PyTypeObject} structure.  Type objects can be handled using any
+of the \cfunction{PyObject_*()} or \cfunction{PyType_*()} functions,
+but do not offer much that's interesting to most Python applications.
+These objects are fundamental to how objects behave, so they are very
+important to the interpreter itself and to any extension module that
+implements new types.
+
+Type objects are fairly large compared to most of the standard types.
+The reason for the size is that each type object stores a large number
+of values, mostly C function pointers, each of which implements a
+small part of the type's functionality.  The fields of the type object
+are examined in detail in this section.  The fields will be described
+in the order in which they occur in the structure.
+
+Typedefs:
+unaryfunc, binaryfunc, ternaryfunc, inquiry, coercion, intargfunc,
+intintargfunc, intobjargproc, intintobjargproc, objobjargproc,
+destructor, freefunc, printfunc, getattrfunc, getattrofunc, setattrfunc,
+setattrofunc, cmpfunc, reprfunc, hashfunc
+
+The structure definition for \ctype{PyTypeObject} can be found in
+\file{Include/object.h}.  For convenience of reference, this repeats
+the definition found there:
+
+\verbatiminput{typestruct.h}
+
+The type object structure extends the \ctype{PyVarObject} structure.
+The \member{ob_size} field is used for dynamic types (created
+by  \function{type_new()}, usually called from a class statement).
+Note that \cdata{PyType_Type} (the metatype) initializes
+\member{tp_itemsize}, which means that its instances (i.e. type
+objects) \emph{must} have the \member{ob_size} field.
+
+\begin{cmemberdesc}{PyObject}{PyObject*}{_ob_next}
+\cmemberline{PyObject}{PyObject*}{_ob_prev}
+  These fields are only present when the macro \code{Py_TRACE_REFS} is
+  defined.  Their initialization to \NULL{} is taken care of by the
+  \code{PyObject_HEAD_INIT} macro.  For statically allocated objects,
+  these fields always remain \NULL.  For dynamically allocated
+  objects, these two fields are used to link the object into a
+  doubly-linked list of \emph{all} live objects on the heap.  This
+  could be used for various debugging purposes; currently the only use
+  is to print the objects that are still alive at the end of a run
+  when the environment variable \envvar{PYTHONDUMPREFS} is set.
+
+  These fields are not inherited by subtypes.
+\end{cmemberdesc}
+
+\begin{cmemberdesc}{PyObject}{Py_ssize_t}{ob_refcnt}
+  This is the type object's reference count, initialized to \code{1}
+  by the \code{PyObject_HEAD_INIT} macro.  Note that for statically
+  allocated type objects, the type's instances (objects whose
+  \member{ob_type} points back to the type) do \emph{not} count as
+  references.  But for dynamically allocated type objects, the
+  instances \emph{do} count as references.
+
+  This field is not inherited by subtypes.
+\end{cmemberdesc}
+
+\begin{cmemberdesc}{PyObject}{PyTypeObject*}{ob_type}
+  This is the type's type, in other words its metatype.  It is
+  initialized by the argument to the \code{PyObject_HEAD_INIT} macro,
+  and its value should normally be \code{\&PyType_Type}.  However, for
+  dynamically loadable extension modules that must be usable on
+  Windows (at least), the compiler complains that this is not a valid
+  initializer.  Therefore, the convention is to pass \NULL{} to the
+  \code{PyObject_HEAD_INIT} macro and to initialize this field
+  explicitly at the start of the module's initialization function,
+  before doing anything else.  This is typically done like this:
+
+\begin{verbatim}
+Foo_Type.ob_type = &PyType_Type;
+\end{verbatim}
+
+  This should be done before any instances of the type are created.
+  \cfunction{PyType_Ready()} checks if \member{ob_type} is \NULL, and
+  if so, initializes it: in Python 2.2, it is set to
+  \code{\&PyType_Type}; in Python 2.2.1 and later it is
+  initialized to the \member{ob_type} field of the base class.
+  \cfunction{PyType_Ready()} will not change this field if it is
+  non-zero.
+
+  In Python 2.2, this field is not inherited by subtypes.  In 2.2.1,
+  and in 2.3 and beyond, it is inherited by subtypes.
+\end{cmemberdesc}
+
+\begin{cmemberdesc}{PyVarObject}{Py_ssize_t}{ob_size}
+  For statically allocated type objects, this should be initialized
+  to zero.  For dynamically allocated type objects, this field has a
+  special internal meaning.
+
+  This field is not inherited by subtypes.
+\end{cmemberdesc}
+
+\begin{cmemberdesc}{PyTypeObject}{char*}{tp_name}
+  Pointer to a NUL-terminated string containing the name of the type.
+  For types that are accessible as module globals, the string should
+  be the full module name, followed by a dot, followed by the type
+  name; for built-in types, it should be just the type name.  If the
+  module is a submodule of a package, the full package name is part of
+  the full module name.  For example, a type named \class{T} defined
+  in module \module{M} in subpackage \module{Q} in package \module{P}
+  should have the \member{tp_name} initializer \code{"P.Q.M.T"}.
+
+  For dynamically allocated type objects, this should just be the type
+  name, and the module name explicitly stored in the type dict as the
+  value for key \code{'__module__'}.
+
+  For statically allocated type objects, the tp_name field should
+  contain a dot.  Everything before the last dot is made accessible as
+  the \member{__module__} attribute, and everything after the last dot
+  is made accessible as the \member{__name__} attribute.
+
+  If no dot is present, the entire \member{tp_name} field is made
+  accessible as the \member{__name__} attribute, and the
+  \member{__module__} attribute is undefined (unless explicitly set in
+  the dictionary, as explained above).  This means your type will be
+  impossible to pickle.
+
+  This field is not inherited by subtypes.
+\end{cmemberdesc}
+
+\begin{cmemberdesc}{PyTypeObject}{Py_ssize_t}{tp_basicsize}
+\cmemberline{PyTypeObject}{Py_ssize_t}{tp_itemsize}
+  These fields allow calculating the size in bytes of instances of
+  the type.
+
+  There are two kinds of types: types with fixed-length instances have
+  a zero \member{tp_itemsize} field, types with variable-length
+  instances have a non-zero \member{tp_itemsize} field.  For a type
+  with fixed-length instances, all instances have the same size,
+  given in \member{tp_basicsize}.
+
+  For a type with variable-length instances, the instances must have
+  an \member{ob_size} field, and the instance size is
+  \member{tp_basicsize} plus N times \member{tp_itemsize}, where N is
+  the ``length'' of the object.  The value of N is typically stored in
+  the instance's \member{ob_size} field.  There are exceptions:  for
+  example, long ints use a negative \member{ob_size} to indicate a
+  negative number, and N is \code{abs(\member{ob_size})} there.  Also,
+  the presence of an \member{ob_size} field in the instance layout
+  doesn't mean that the instance structure is variable-length (for
+  example, the structure for the list type has fixed-length instances,
+  yet those instances have a meaningful \member{ob_size} field).
+
+  The basic size includes the fields in the instance declared by the
+  macro \csimplemacro{PyObject_HEAD} or
+  \csimplemacro{PyObject_VAR_HEAD} (whichever is used to declare the
+  instance struct) and this in turn includes the \member{_ob_prev} and
+  \member{_ob_next} fields if they are present.  This means that the
+  only correct way to get an initializer for the \member{tp_basicsize}
+  is to use the \keyword{sizeof} operator on the struct used to
+  declare the instance layout.  The basic size does not include the GC
+  header size (this is new in Python 2.2; in 2.1 and 2.0, the GC
+  header size was included in \member{tp_basicsize}).
+
+  These fields are inherited separately by subtypes.  If the base type
+  has a non-zero \member{tp_itemsize}, it is generally not safe to set
+  \member{tp_itemsize} to a different non-zero value in a subtype
+  (though this depends on the implementation of the base type).
+
+  A note about alignment: if the variable items require a particular
+  alignment, this should be taken care of by the value of
+  \member{tp_basicsize}.  Example: suppose a type implements an array
+  of \code{double}. \member{tp_itemsize} is \code{sizeof(double)}.
+  It is the programmer's responsibility that \member{tp_basicsize} is
+  a multiple of \code{sizeof(double)} (assuming this is the alignment
+  requirement for \code{double}).
+\end{cmemberdesc}
+
+\begin{cmemberdesc}{PyTypeObject}{destructor}{tp_dealloc}
+  A pointer to the instance destructor function.  This function must
+  be defined unless the type guarantees that its instances will never
+  be deallocated (as is the case for the singletons \code{None} and
+  \code{Ellipsis}).
+
+  The destructor function is called by the \cfunction{Py_DECREF()} and
+  \cfunction{Py_XDECREF()} macros when the new reference count is
+  zero.  At this point, the instance is still in existence, but there
+  are no references to it.  The destructor function should free all
+  references which the instance owns, free all memory buffers owned by
+  the instance (using the freeing function corresponding to the
+  allocation function used to allocate the buffer), and finally (as
+  its last action) call the type's \member{tp_free} function.  If the
+  type is not subtypable (doesn't have the
+  \constant{Py_TPFLAGS_BASETYPE} flag bit set), it is permissible to
+  call the object deallocator directly instead of via
+  \member{tp_free}.  The object deallocator should be the one used to
+  allocate the instance; this is normally \cfunction{PyObject_Del()}
+  if the instance was allocated using \cfunction{PyObject_New()} or
+  \cfunction{PyObject_VarNew()}, or \cfunction{PyObject_GC_Del()} if
+  the instance was allocated using \cfunction{PyObject_GC_New()} or
+  \cfunction{PyObject_GC_VarNew()}.
+
+  This field is inherited by subtypes.
+\end{cmemberdesc}
+
+\begin{cmemberdesc}{PyTypeObject}{printfunc}{tp_print}
+  An optional pointer to the instance print function.
+
+  The print function is only called when the instance is printed to a
+  \emph{real} file; when it is printed to a pseudo-file (like a
+  \class{StringIO} instance), the instance's \member{tp_repr} or
+  \member{tp_str} function is called to convert it to a string.  These
+  are also called when the type's \member{tp_print} field is \NULL.  A
+  type should never implement \member{tp_print} in a way that produces
+  different output than \member{tp_repr} or \member{tp_str} would.
+
+  The print function is called with the same signature as
+  \cfunction{PyObject_Print()}: \code{int tp_print(PyObject *self, FILE
+  *file, int flags)}.  The \var{self} argument is the instance to be
+  printed.  The \var{file} argument is the stdio file to which it is
+  to be printed.  The \var{flags} argument is composed of flag bits.
+  The only flag bit currently defined is \constant{Py_PRINT_RAW}.
+  When the \constant{Py_PRINT_RAW} flag bit is set, the instance
+  should be printed the same way as \member{tp_str} would format it;
+  when the \constant{Py_PRINT_RAW} flag bit is clear, the instance
+  should be printed the same was as \member{tp_repr} would format it.
+  It should return \code{-1} and set an exception condition when an
+  error occurred during the comparison.
+
+  It is possible that the \member{tp_print} field will be deprecated.
+  In any case, it is recommended not to define \member{tp_print}, but
+  instead to rely on \member{tp_repr} and \member{tp_str} for
+  printing.
+
+  This field is inherited by subtypes.
+\end{cmemberdesc}
+
+\begin{cmemberdesc}{PyTypeObject}{getattrfunc}{tp_getattr}
+  An optional pointer to the get-attribute-string function.
+
+  This field is deprecated.  When it is defined, it should point to a
+  function that acts the same as the \member{tp_getattro} function,
+  but taking a C string instead of a Python string object to give the
+  attribute name.  The signature is the same as for
+  \cfunction{PyObject_GetAttrString()}.
+
+  This field is inherited by subtypes together with
+  \member{tp_getattro}: a subtype inherits both \member{tp_getattr}
+  and \member{tp_getattro} from its base type when the subtype's
+  \member{tp_getattr} and \member{tp_getattro} are both \NULL.
+\end{cmemberdesc}
+
+\begin{cmemberdesc}{PyTypeObject}{setattrfunc}{tp_setattr}
+  An optional pointer to the set-attribute-string function.
+
+  This field is deprecated.  When it is defined, it should point to a
+  function that acts the same as the \member{tp_setattro} function,
+  but taking a C string instead of a Python string object to give the
+  attribute name.  The signature is the same as for
+  \cfunction{PyObject_SetAttrString()}.
+
+  This field is inherited by subtypes together with
+  \member{tp_setattro}: a subtype inherits both \member{tp_setattr}
+  and \member{tp_setattro} from its base type when the subtype's
+  \member{tp_setattr} and \member{tp_setattro} are both \NULL.
+\end{cmemberdesc}
+
+\begin{cmemberdesc}{PyTypeObject}{cmpfunc}{tp_compare}
+  An optional pointer to the three-way comparison function.
+
+  The signature is the same as for \cfunction{PyObject_Compare()}.
+  The function should return \code{1} if \var{self} greater than
+  \var{other}, \code{0} if \var{self} is equal to \var{other}, and
+  \code{-1} if \var{self} less than \var{other}.  It should return
+  \code{-1} and set an exception condition when an error occurred
+  during the comparison.
+
+  This field is inherited by subtypes together with
+  \member{tp_richcompare} and \member{tp_hash}: a subtypes inherits
+  all three of \member{tp_compare}, \member{tp_richcompare}, and
+  \member{tp_hash} when the subtype's \member{tp_compare},
+  \member{tp_richcompare}, and \member{tp_hash} are all \NULL.
+\end{cmemberdesc}
+
+\begin{cmemberdesc}{PyTypeObject}{reprfunc}{tp_repr}
+  An optional pointer to a function that implements the built-in
+  function \function{repr()}.\bifuncindex{repr}
+
+  The signature is the same as for \cfunction{PyObject_Repr()}; it
+  must return a string or a Unicode object.  Ideally, this function
+  should return a string that, when passed to \function{eval()}, given
+  a suitable environment, returns an object with the same value.  If
+  this is not feasible, it should return a string starting with
+  \character{\textless} and ending with \character{\textgreater} from
+  which both the type and the value of the object can be deduced.
+
+  When this field is not set, a string of the form \samp{<\%s object
+  at \%p>} is returned, where \code{\%s} is replaced by the type name,
+  and \code{\%p} by the object's memory address.
+
+  This field is inherited by subtypes.
+\end{cmemberdesc}
+
+PyNumberMethods *tp_as_number;
+
+    XXX
+
+PySequenceMethods *tp_as_sequence;
+
+    XXX
+
+PyMappingMethods *tp_as_mapping;
+
+    XXX
+
+\begin{cmemberdesc}{PyTypeObject}{hashfunc}{tp_hash}
+  An optional pointer to a function that implements the built-in
+  function \function{hash()}.\bifuncindex{hash}
+
+  The signature is the same as for \cfunction{PyObject_Hash()}; it
+  must return a C long.  The value \code{-1} should not be returned as
+  a normal return value; when an error occurs during the computation
+  of the hash value, the function should set an exception and return
+  \code{-1}.
+
+  When this field is not set, two possibilities exist: if the
+  \member{tp_compare} and \member{tp_richcompare} fields are both
+  \NULL, a default hash value based on the object's address is
+  returned; otherwise, a \exception{TypeError} is raised.
+
+  This field is inherited by subtypes together with
+  \member{tp_richcompare} and \member{tp_compare}: a subtypes inherits
+  all three of \member{tp_compare}, \member{tp_richcompare}, and
+  \member{tp_hash}, when the subtype's \member{tp_compare},
+  \member{tp_richcompare} and \member{tp_hash} are all \NULL.
+\end{cmemberdesc}
+
+\begin{cmemberdesc}{PyTypeObject}{ternaryfunc}{tp_call}
+  An optional pointer to a function that implements calling the
+  object.  This should be \NULL{} if the object is not callable.  The
+  signature is the same as for \cfunction{PyObject_Call()}.
+
+  This field is inherited by subtypes.
+\end{cmemberdesc}
+
+\begin{cmemberdesc}{PyTypeObject}{reprfunc}{tp_str}
+  An optional pointer to a function that implements the built-in
+  operation \function{str()}.  (Note that \class{str} is a type now,
+  and \function{str()} calls the constructor for that type.  This
+  constructor calls \cfunction{PyObject_Str()} to do the actual work,
+  and \cfunction{PyObject_Str()} will call this handler.)
+
+  The signature is the same as for \cfunction{PyObject_Str()}; it must
+  return a string or a Unicode object.  This function should return a
+  ``friendly'' string representation of the object, as this is the
+  representation that will be used by the print statement.
+
+  When this field is not set, \cfunction{PyObject_Repr()} is called to
+  return a string representation.
+
+  This field is inherited by subtypes.
+\end{cmemberdesc}
+
+\begin{cmemberdesc}{PyTypeObject}{getattrofunc}{tp_getattro}
+  An optional pointer to the get-attribute function.
+
+  The signature is the same as for \cfunction{PyObject_GetAttr()}.  It
+  is usually convenient to set this field to
+  \cfunction{PyObject_GenericGetAttr()}, which implements the normal
+  way of looking for object attributes.
+
+  This field is inherited by subtypes together with
+  \member{tp_getattr}: a subtype inherits both \member{tp_getattr} and
+  \member{tp_getattro} from its base type when the subtype's
+  \member{tp_getattr} and \member{tp_getattro} are both \NULL.
+\end{cmemberdesc}
+
+\begin{cmemberdesc}{PyTypeObject}{setattrofunc}{tp_setattro}
+  An optional pointer to the set-attribute function.
+
+  The signature is the same as for \cfunction{PyObject_SetAttr()}.  It
+  is usually convenient to set this field to
+  \cfunction{PyObject_GenericSetAttr()}, which implements the normal
+  way of setting object attributes.
+
+  This field is inherited by subtypes together with
+  \member{tp_setattr}: a subtype inherits both \member{tp_setattr} and
+  \member{tp_setattro} from its base type when the subtype's
+  \member{tp_setattr} and \member{tp_setattro} are both \NULL.
+\end{cmemberdesc}
+
+\begin{cmemberdesc}{PyTypeObject}{PyBufferProcs*}{tp_as_buffer}
+  Pointer to an additional structure that contains fields relevant only to
+  objects which implement the buffer interface.  These fields are
+  documented in ``Buffer Object Structures'' (section
+  \ref{buffer-structs}).
+
+  The \member{tp_as_buffer} field is not inherited, but the contained
+  fields are inherited individually.
+\end{cmemberdesc}
+
+\begin{cmemberdesc}{PyTypeObject}{long}{tp_flags}
+  This field is a bit mask of various flags.  Some flags indicate
+  variant semantics for certain situations; others are used to
+  indicate that certain fields in the type object (or in the extension
+  structures referenced via \member{tp_as_number},
+  \member{tp_as_sequence}, \member{tp_as_mapping}, and
+  \member{tp_as_buffer}) that were historically not always present are
+  valid; if such a flag bit is clear, the type fields it guards must
+  not be accessed and must be considered to have a zero or \NULL{}
+  value instead.
+
+  Inheritance of this field is complicated.  Most flag bits are
+  inherited individually, i.e. if the base type has a flag bit set,
+  the subtype inherits this flag bit.  The flag bits that pertain to
+  extension structures are strictly inherited if the extension
+  structure is inherited, i.e. the base type's value of the flag bit
+  is copied into the subtype together with a pointer to the extension
+  structure.  The \constant{Py_TPFLAGS_HAVE_GC} flag bit is inherited
+  together with the \member{tp_traverse} and \member{tp_clear} fields,
+  i.e. if the \constant{Py_TPFLAGS_HAVE_GC} flag bit is clear in the
+  subtype and the \member{tp_traverse} and \member{tp_clear} fields in
+  the subtype exist (as indicated by the
+  \constant{Py_TPFLAGS_HAVE_RICHCOMPARE} flag bit) and have \NULL{}
+  values.
+
+  The following bit masks are currently defined; these can be or-ed
+  together using the \code{|} operator to form the value of the
+  \member{tp_flags} field.  The macro \cfunction{PyType_HasFeature()}
+  takes a type and a flags value, \var{tp} and \var{f}, and checks
+  whether \code{\var{tp}->tp_flags \& \var{f}} is non-zero.
+
+  \begin{datadesc}{Py_TPFLAGS_HAVE_GETCHARBUFFER}
+    If this bit is set, the \ctype{PyBufferProcs} struct referenced by
+    \member{tp_as_buffer} has the \member{bf_getcharbuffer} field.
+  \end{datadesc}
+
+  \begin{datadesc}{Py_TPFLAGS_HAVE_SEQUENCE_IN}
+    If this bit is set, the \ctype{PySequenceMethods} struct
+    referenced by \member{tp_as_sequence} has the \member{sq_contains}
+    field.
+  \end{datadesc}
+
+  \begin{datadesc}{Py_TPFLAGS_GC}
+    This bit is obsolete.  The bit it used to name is no longer in
+    use.  The symbol is now defined as zero.
+  \end{datadesc}
+
+  \begin{datadesc}{Py_TPFLAGS_HAVE_INPLACEOPS}
+    If this bit is set, the \ctype{PySequenceMethods} struct
+    referenced by \member{tp_as_sequence} and the
+    \ctype{PyNumberMethods} structure referenced by
+    \member{tp_as_number} contain the fields for in-place operators.
+    In particular, this means that the \ctype{PyNumberMethods}
+    structure has the fields \member{nb_inplace_add},
+    \member{nb_inplace_subtract}, \member{nb_inplace_multiply},
+    \member{nb_inplace_divide}, \member{nb_inplace_remainder},
+    \member{nb_inplace_power}, \member{nb_inplace_lshift},
+    \member{nb_inplace_rshift}, \member{nb_inplace_and},
+    \member{nb_inplace_xor}, and \member{nb_inplace_or}; and the
+    \ctype{PySequenceMethods} struct has the fields
+    \member{sq_inplace_concat} and \member{sq_inplace_repeat}.
+  \end{datadesc}
+
+  \begin{datadesc}{Py_TPFLAGS_CHECKTYPES}
+    If this bit is set, the binary and ternary operations in the
+    \ctype{PyNumberMethods} structure referenced by
+    \member{tp_as_number} accept arguments of arbitrary object types,
+    and do their own type conversions if needed.  If this bit is
+    clear, those operations require that all arguments have the
+    current type as their type, and the caller is supposed to perform
+    a coercion operation first.  This applies to \member{nb_add},
+    \member{nb_subtract}, \member{nb_multiply}, \member{nb_divide},
+    \member{nb_remainder}, \member{nb_divmod}, \member{nb_power},
+    \member{nb_lshift}, \member{nb_rshift}, \member{nb_and},
+    \member{nb_xor}, and \member{nb_or}.
+  \end{datadesc}
+
+  \begin{datadesc}{Py_TPFLAGS_HAVE_RICHCOMPARE}
+    If this bit is set, the type object has the
+    \member{tp_richcompare} field, as well as the \member{tp_traverse}
+    and the \member{tp_clear} fields.
+  \end{datadesc}
+
+  \begin{datadesc}{Py_TPFLAGS_HAVE_WEAKREFS}
+    If this bit is set, the \member{tp_weaklistoffset} field is
+    defined.  Instances of a type are weakly referenceable if the
+    type's \member{tp_weaklistoffset} field has a value greater than
+    zero.
+  \end{datadesc}
+
+  \begin{datadesc}{Py_TPFLAGS_HAVE_ITER}
+    If this bit is set, the type object has the \member{tp_iter} and
+    \member{tp_iternext} fields.
+  \end{datadesc}
+
+  \begin{datadesc}{Py_TPFLAGS_HAVE_CLASS}
+    If this bit is set, the type object has several new fields defined
+    starting in Python 2.2: \member{tp_methods}, \member{tp_members},
+    \member{tp_getset}, \member{tp_base}, \member{tp_dict},
+    \member{tp_descr_get}, \member{tp_descr_set},
+    \member{tp_dictoffset}, \member{tp_init}, \member{tp_alloc},
+    \member{tp_new}, \member{tp_free}, \member{tp_is_gc},
+    \member{tp_bases}, \member{tp_mro}, \member{tp_cache},
+    \member{tp_subclasses}, and \member{tp_weaklist}.
+  \end{datadesc}
+
+  \begin{datadesc}{Py_TPFLAGS_HEAPTYPE}
+    This bit is set when the type object itself is allocated on the
+    heap.  In this case, the \member{ob_type} field of its instances
+    is considered a reference to the type, and the type object is
+    INCREF'ed when a new instance is created, and DECREF'ed when an
+    instance is destroyed (this does not apply to instances of
+    subtypes; only the type referenced by the instance's ob_type gets
+    INCREF'ed or DECREF'ed).
+  \end{datadesc}
+
+  \begin{datadesc}{Py_TPFLAGS_BASETYPE}
+    This bit is set when the type can be used as the base type of
+    another type.  If this bit is clear, the type cannot be subtyped
+    (similar to a "final" class in Java).
+  \end{datadesc}
+
+  \begin{datadesc}{Py_TPFLAGS_READY}
+    This bit is set when the type object has been fully initialized by
+    \cfunction{PyType_Ready()}.
+  \end{datadesc}
+
+  \begin{datadesc}{Py_TPFLAGS_READYING}
+    This bit is set while \cfunction{PyType_Ready()} is in the process
+    of initializing the type object.
+  \end{datadesc}
+
+  \begin{datadesc}{Py_TPFLAGS_HAVE_GC}
+    This bit is set when the object supports garbage collection.  If
+    this bit is set, instances must be created using
+    \cfunction{PyObject_GC_New()} and destroyed using
+    \cfunction{PyObject_GC_Del()}.  More information in section XXX
+    about garbage collection.  This bit also implies that the
+    GC-related fields \member{tp_traverse} and \member{tp_clear} are
+    present in the type object; but those fields also exist when
+    \constant{Py_TPFLAGS_HAVE_GC} is clear but
+    \constant{Py_TPFLAGS_HAVE_RICHCOMPARE} is set.
+  \end{datadesc}
+
+  \begin{datadesc}{Py_TPFLAGS_DEFAULT}
+    This is a bitmask of all the bits that pertain to the existence of
+    certain fields in the type object and its extension structures.
+    Currently, it includes the following bits:
+    \constant{Py_TPFLAGS_HAVE_GETCHARBUFFER},
+    \constant{Py_TPFLAGS_HAVE_SEQUENCE_IN},
+    \constant{Py_TPFLAGS_HAVE_INPLACEOPS},
+    \constant{Py_TPFLAGS_HAVE_RICHCOMPARE},
+    \constant{Py_TPFLAGS_HAVE_WEAKREFS},
+    \constant{Py_TPFLAGS_HAVE_ITER}, and
+    \constant{Py_TPFLAGS_HAVE_CLASS}.
+  \end{datadesc}
+\end{cmemberdesc}
+
+\begin{cmemberdesc}{PyTypeObject}{char*}{tp_doc}
+  An optional pointer to a NUL-terminated C string giving the
+  docstring for this type object.  This is exposed as the
+  \member{__doc__} attribute on the type and instances of the type.
+
+  This field is \emph{not} inherited by subtypes.
+\end{cmemberdesc}
+
+The following three fields only exist if the
+\constant{Py_TPFLAGS_HAVE_RICHCOMPARE} flag bit is set.
+
+\begin{cmemberdesc}{PyTypeObject}{traverseproc}{tp_traverse}
+  An optional pointer to a traversal function for the garbage
+  collector.  This is only used if the \constant{Py_TPFLAGS_HAVE_GC}
+  flag bit is set.  More information about Python's garbage collection
+  scheme can be found in section \ref{supporting-cycle-detection}.
+
+  The \member{tp_traverse} pointer is used by the garbage collector
+  to detect reference cycles. A typical implementation of a
+  \member{tp_traverse} function simply calls \cfunction{Py_VISIT()} on
+  each of the instance's members that are Python objects.  For exampe, this
+  is function \cfunction{local_traverse} from the \module{thread} extension
+  module:
+
+  \begin{verbatim}
+  static int
+  local_traverse(localobject *self, visitproc visit, void *arg)
+  {
+      Py_VISIT(self->args);
+      Py_VISIT(self->kw);
+      Py_VISIT(self->dict);
+      return 0;
+  }
+  \end{verbatim}
+
+  Note that \cfunction{Py_VISIT()} is called only on those members that can
+  participate in reference cycles.  Although there is also a
+  \samp{self->key} member, it can only be \NULL{} or a Python string and
+  therefore cannot be part of a reference cycle.
+
+  On the other hand, even if you know a member can never be part of a cycle,
+  as a debugging aid you may want to visit it anyway just so the
+  \module{gc} module's \function{get_referents()} function will include it.
+
+  Note that \cfunction{Py_VISIT()} requires the \var{visit} and \var{arg}
+  parameters to \cfunction{local_traverse} to have these specific names;
+  don't name them just anything.
+
+  This field is inherited by subtypes together with \member{tp_clear}
+  and the \constant{Py_TPFLAGS_HAVE_GC} flag bit: the flag bit,
+  \member{tp_traverse}, and \member{tp_clear} are all inherited from
+  the base type if they are all zero in the subtype \emph{and} the
+  subtype has the \constant{Py_TPFLAGS_HAVE_RICHCOMPARE} flag bit set.
+\end{cmemberdesc}
+
+\begin{cmemberdesc}{PyTypeObject}{inquiry}{tp_clear}
+  An optional pointer to a clear function for the garbage collector.
+  This is only used if the \constant{Py_TPFLAGS_HAVE_GC} flag bit is
+  set.
+
+  The \member{tp_clear} member function is used to break reference
+  cycles in cyclic garbage detected by the garbage collector.  Taken
+  together, all \member{tp_clear} functions in the system must combine to
+  break all reference cycles.  This is subtle, and if in any doubt supply a
+  \member{tp_clear} function.  For example, the tuple type does not
+  implement a \member{tp_clear} function, because it's possible to prove
+  that no reference cycle can be composed entirely of tuples.  Therefore
+  the \member{tp_clear} functions of other types must be sufficient to
+  break any cycle containing a tuple.  This isn't immediately obvious, and
+  there's rarely a good reason to avoid implementing \member{tp_clear}.
+
+  Implementations of \member{tp_clear} should drop the instance's
+  references to those of its members that may be Python objects, and set
+  its pointers to those members to \NULL{}, as in the following example:
+
+  \begin{verbatim}
+  static int
+  local_clear(localobject *self)
+  {
+      Py_CLEAR(self->key);
+      Py_CLEAR(self->args);
+      Py_CLEAR(self->kw);
+      Py_CLEAR(self->dict);
+      return 0;
+  }
+  \end{verbatim}
+
+  The \cfunction{Py_CLEAR()} macro should be used, because clearing
+  references is delicate:  the reference to the contained object must not be
+  decremented until after the pointer to the contained object is set to
+  \NULL{}.  This is because decrementing the reference count may cause
+  the contained object to become trash, triggering a chain of reclamation
+  activity that may include invoking arbitrary Python code (due to
+  finalizers, or weakref callbacks, associated with the contained object).
+  If it's possible for such code to reference \var{self} again, it's
+  important that the pointer to the contained object be \NULL{} at that
+  time, so that \var{self} knows the contained object can no longer be
+  used.  The \cfunction{Py_CLEAR()} macro performs the operations in a
+  safe order.
+
+  Because the goal of \member{tp_clear} functions is to break reference
+  cycles, it's not necessary to clear contained objects like Python strings
+  or Python integers, which can't participate in reference cycles.
+  On the other hand, it may be convenient to clear all contained Python
+  objects, and write the type's \member{tp_dealloc} function to
+  invoke \member{tp_clear}.
+
+  More information about Python's garbage collection
+  scheme can be found in section \ref{supporting-cycle-detection}.
+
+  This field is inherited by subtypes together with \member{tp_traverse}
+  and the \constant{Py_TPFLAGS_HAVE_GC} flag bit: the flag bit,
+  \member{tp_traverse}, and \member{tp_clear} are all inherited from
+  the base type if they are all zero in the subtype \emph{and} the
+  subtype has the \constant{Py_TPFLAGS_HAVE_RICHCOMPARE} flag bit set.
+\end{cmemberdesc}
+
+\begin{cmemberdesc}{PyTypeObject}{richcmpfunc}{tp_richcompare}
+  An optional pointer to the rich comparison function.
+
+  The signature is the same as for \cfunction{PyObject_RichCompare()}.
+  The function should return the result of the comparison (usually
+  \code{Py_True} or \code{Py_False}).  If the comparison is undefined,
+  it must return \code{Py_NotImplemented}, if another error occurred
+  it must return \code{NULL} and set an exception condition.
+
+  This field is inherited by subtypes together with
+  \member{tp_compare} and \member{tp_hash}: a subtype inherits all
+  three of \member{tp_compare}, \member{tp_richcompare}, and
+  \member{tp_hash}, when the subtype's \member{tp_compare},
+  \member{tp_richcompare}, and \member{tp_hash} are all \NULL.
+
+  The following constants are defined to be used as the third argument
+  for \member{tp_richcompare} and for \cfunction{PyObject_RichCompare()}:
+
+  \begin{tableii}{l|c}{constant}{Constant}{Comparison}
+    \lineii{Py_LT}{\code{<}}
+    \lineii{Py_LE}{\code{<=}}
+    \lineii{Py_EQ}{\code{==}}
+    \lineii{Py_NE}{\code{!=}}
+    \lineii{Py_GT}{\code{>}}
+    \lineii{Py_GE}{\code{>=}}
+  \end{tableii}
+\end{cmemberdesc}
+
+The next field only exists if the \constant{Py_TPFLAGS_HAVE_WEAKREFS}
+flag bit is set.
+
+\begin{cmemberdesc}{PyTypeObject}{long}{tp_weaklistoffset}
+  If the instances of this type are weakly referenceable, this field
+  is greater than zero and contains the offset in the instance
+  structure of the weak reference list head (ignoring the GC header,
+  if present); this offset is used by
+  \cfunction{PyObject_ClearWeakRefs()} and the
+  \cfunction{PyWeakref_*()} functions.  The instance structure needs
+  to include a field of type \ctype{PyObject*} which is initialized to
+  \NULL.
+
+  Do not confuse this field with \member{tp_weaklist}; that is the
+  list head for weak references to the type object itself.
+
+  This field is inherited by subtypes, but see the rules listed below.
+  A subtype may override this offset; this means that the subtype uses
+  a different weak reference list head than the base type.  Since the
+  list head is always found via \member{tp_weaklistoffset}, this
+  should not be a problem.
+
+  When a type defined by a class statement has no \member{__slots__}
+  declaration, and none of its base types are weakly referenceable,
+  the type is made weakly referenceable by adding a weak reference
+  list head slot to the instance layout and setting the
+  \member{tp_weaklistoffset} of that slot's offset.
+
+  When a type's \member{__slots__} declaration contains a slot named
+  \member{__weakref__}, that slot becomes the weak reference list head
+  for instances of the type, and the slot's offset is stored in the
+  type's \member{tp_weaklistoffset}.
+
+  When a type's \member{__slots__} declaration does not contain a slot
+  named \member{__weakref__}, the type inherits its
+  \member{tp_weaklistoffset} from its base type.
+\end{cmemberdesc}
+
+The next two fields only exist if the
+\constant{Py_TPFLAGS_HAVE_CLASS} flag bit is set.
+
+\begin{cmemberdesc}{PyTypeObject}{getiterfunc}{tp_iter}
+  An optional pointer to a function that returns an iterator for the
+  object.  Its presence normally signals that the instances of this
+  type are iterable (although sequences may be iterable without this
+  function, and classic instances always have this function, even if
+  they don't define an \method{__iter__()} method).
+
+  This function has the same signature as
+  \cfunction{PyObject_GetIter()}.
+
+  This field is inherited by subtypes.
+\end{cmemberdesc}
+
+\begin{cmemberdesc}{PyTypeObject}{iternextfunc}{tp_iternext}
+  An optional pointer to a function that returns the next item in an
+  iterator, or raises \exception{StopIteration} when the iterator is
+  exhausted.  Its presence normally signals that the instances of this
+  type are iterators (although classic instances always have this
+  function, even if they don't define a \method{next()} method).
+
+  Iterator types should also define the \member{tp_iter} function, and
+  that function should return the iterator instance itself (not a new
+  iterator instance).
+
+  This function has the same signature as \cfunction{PyIter_Next()}.
+
+  This field is inherited by subtypes.
+\end{cmemberdesc}
+
+The next fields, up to and including \member{tp_weaklist}, only exist
+if the \constant{Py_TPFLAGS_HAVE_CLASS} flag bit is set.
+
+\begin{cmemberdesc}{PyTypeObject}{struct PyMethodDef*}{tp_methods}
+  An optional pointer to a static \NULL-terminated array of
+  \ctype{PyMethodDef} structures, declaring regular methods of this
+  type.
+
+  For each entry in the array, an entry is added to the type's
+  dictionary (see \member{tp_dict} below) containing a method
+  descriptor.
+
+  This field is not inherited by subtypes (methods are
+  inherited through a different mechanism).
+\end{cmemberdesc}
+
+\begin{cmemberdesc}{PyTypeObject}{struct PyMemberDef*}{tp_members}
+  An optional pointer to a static \NULL-terminated array of
+  \ctype{PyMemberDef} structures, declaring regular data members
+  (fields or slots) of instances of this type.
+
+  For each entry in the array, an entry is added to the type's
+  dictionary (see \member{tp_dict} below) containing a member
+  descriptor.
+
+  This field is not inherited by subtypes (members are inherited
+  through a different mechanism).
+\end{cmemberdesc}
+
+\begin{cmemberdesc}{PyTypeObject}{struct PyGetSetDef*}{tp_getset}
+  An optional pointer to a static \NULL-terminated array of
+  \ctype{PyGetSetDef} structures, declaring computed attributes of
+  instances of this type.
+
+  For each entry in the array, an entry is added to the type's
+  dictionary (see \member{tp_dict} below) containing a getset
+  descriptor.
+
+  This field is not inherited by subtypes (computed attributes are
+  inherited through a different mechanism).
+
+  Docs for PyGetSetDef (XXX belong elsewhere):
+
+\begin{verbatim}
+typedef PyObject *(*getter)(PyObject *, void *);
+typedef int (*setter)(PyObject *, PyObject *, void *);
+
+typedef struct PyGetSetDef {
+    char *name;    /* attribute name */
+    getter get;    /* C function to get the attribute */
+    setter set;    /* C function to set the attribute */
+    char *doc;     /* optional doc string */
+    void *closure; /* optional additional data for getter and setter */
+} PyGetSetDef;
+\end{verbatim}
+\end{cmemberdesc}
+
+\begin{cmemberdesc}{PyTypeObject}{PyTypeObject*}{tp_base}
+  An optional pointer to a base type from which type properties are
+  inherited.  At this level, only single inheritance is supported;
+  multiple inheritance require dynamically creating a type object by
+  calling the metatype.
+
+  This field is not inherited by subtypes (obviously), but it defaults
+  to \code{\&PyBaseObject_Type} (which to Python programmers is known
+  as the type \class{object}).
+\end{cmemberdesc}
+
+\begin{cmemberdesc}{PyTypeObject}{PyObject*}{tp_dict}
+  The type's dictionary is stored here by \cfunction{PyType_Ready()}.
+
+  This field should normally be initialized to \NULL{} before
+  PyType_Ready is called; it may also be initialized to a dictionary
+  containing initial attributes for the type.  Once
+  \cfunction{PyType_Ready()} has initialized the type, extra
+  attributes for the type may be added to this dictionary only if they
+  don't correspond to overloaded operations (like \method{__add__()}).
+
+  This field is not inherited by subtypes (though the attributes
+  defined in here are inherited through a different mechanism).
+\end{cmemberdesc}
+
+\begin{cmemberdesc}{PyTypeObject}{descrgetfunc}{tp_descr_get}
+  An optional pointer to a "descriptor get" function.
+
+
+  The function signature is
+
+\begin{verbatim}
+PyObject * tp_descr_get(PyObject *self, PyObject *obj, PyObject *type);
+\end{verbatim}
+
+  XXX blah, blah.
+
+  This field is inherited by subtypes.
+\end{cmemberdesc}
+
+\begin{cmemberdesc}{PyTypeObject}{descrsetfunc}{tp_descr_set}
+  An optional pointer to a "descriptor set" function.
+
+  The function signature is
+
+\begin{verbatim}
+int tp_descr_set(PyObject *self, PyObject *obj, PyObject *value);
+\end{verbatim}
+
+  This field is inherited by subtypes.
+
+  XXX blah, blah.
+
+\end{cmemberdesc}
+
+\begin{cmemberdesc}{PyTypeObject}{long}{tp_dictoffset}
+  If the instances of this type have a dictionary containing instance
+  variables, this field is non-zero and contains the offset in the
+  instances of the type of the instance variable dictionary; this
+  offset is used by \cfunction{PyObject_GenericGetAttr()}.
+
+  Do not confuse this field with \member{tp_dict}; that is the
+  dictionary for attributes of the type object itself.
+
+  If the value of this field is greater than zero, it specifies the
+  offset from the start of the instance structure.  If the value is
+  less than zero, it specifies the offset from the \emph{end} of the
+  instance structure.  A negative offset is more expensive to use, and
+  should only be used when the instance structure contains a
+  variable-length part.  This is used for example to add an instance
+  variable dictionary to subtypes of \class{str} or \class{tuple}.
+  Note that the \member{tp_basicsize} field should account for the
+  dictionary added to the end in that case, even though the dictionary
+  is not included in the basic object layout.  On a system with a
+  pointer size of 4 bytes, \member{tp_dictoffset} should be set to
+  \code{-4} to indicate that the dictionary is at the very end of the
+  structure.
+
+  The real dictionary offset in an instance can be computed from a
+  negative \member{tp_dictoffset} as follows:
+
+\begin{verbatim}
+dictoffset = tp_basicsize + abs(ob_size)*tp_itemsize + tp_dictoffset
+if dictoffset is not aligned on sizeof(void*):
+    round up to sizeof(void*)
+\end{verbatim}
+
+  where \member{tp_basicsize}, \member{tp_itemsize} and
+  \member{tp_dictoffset} are taken from the type object, and
+  \member{ob_size} is taken from the instance.  The absolute value is
+  taken because long ints use the sign of \member{ob_size} to store
+  the sign of the number.  (There's never a need to do this
+  calculation yourself; it is done for you by
+  \cfunction{_PyObject_GetDictPtr()}.)
+
+  This field is inherited by subtypes, but see the rules listed below.
+  A subtype may override this offset; this means that the subtype
+  instances store the dictionary at a difference offset than the base
+  type.  Since the dictionary is always found via
+  \member{tp_dictoffset}, this should not be a problem.
+
+  When a type defined by a class statement has no \member{__slots__}
+  declaration, and none of its base types has an instance variable
+  dictionary, a dictionary slot is added to the instance layout and
+  the \member{tp_dictoffset} is set to that slot's offset.
+
+  When a type defined by a class statement has a \member{__slots__}
+  declaration, the type inherits its \member{tp_dictoffset} from its
+  base type.
+
+  (Adding a slot named \member{__dict__} to the \member{__slots__}
+  declaration does not have the expected effect, it just causes
+  confusion.  Maybe this should be added as a feature just like
+  \member{__weakref__} though.)
+\end{cmemberdesc}
+
+\begin{cmemberdesc}{PyTypeObject}{initproc}{tp_init}
+  An optional pointer to an instance initialization function.
+
+  This function corresponds to the \method{__init__()} method of
+  classes.  Like \method{__init__()}, it is possible to create an
+  instance without calling \method{__init__()}, and it is possible to
+  reinitialize an instance by calling its \method{__init__()} method
+  again.
+
+  The function signature is
+
+\begin{verbatim}
+int tp_init(PyObject *self, PyObject *args, PyObject *kwds)
+\end{verbatim}
+
+  The self argument is the instance to be initialized; the \var{args}
+  and \var{kwds} arguments represent positional and keyword arguments
+  of the call to \method{__init__()}.
+
+  The \member{tp_init} function, if not \NULL, is called when an
+  instance is created normally by calling its type, after the type's
+  \member{tp_new} function has returned an instance of the type.  If
+  the \member{tp_new} function returns an instance of some other type
+  that is not a subtype of the original type, no \member{tp_init}
+  function is called; if \member{tp_new} returns an instance of a
+  subtype of the original type, the subtype's \member{tp_init} is
+  called.  (VERSION NOTE: described here is what is implemented in
+  Python 2.2.1 and later.  In Python 2.2, the \member{tp_init} of the
+  type of the object returned by \member{tp_new} was always called, if
+  not \NULL.)
+
+  This field is inherited by subtypes.
+\end{cmemberdesc}
+
+\begin{cmemberdesc}{PyTypeObject}{allocfunc}{tp_alloc}
+  An optional pointer to an instance allocation function.
+
+  The function signature is
+
+\begin{verbatim}
+PyObject *tp_alloc(PyTypeObject *self, Py_ssize_t nitems)
+\end{verbatim}
+
+  The purpose of this function is to separate memory allocation from
+  memory initialization.  It should return a pointer to a block of
+  memory of adequate length for the instance, suitably aligned, and
+  initialized to zeros, but with \member{ob_refcnt} set to \code{1}
+  and \member{ob_type} set to the type argument.  If the type's
+  \member{tp_itemsize} is non-zero, the object's \member{ob_size} field
+  should be initialized to \var{nitems} and the length of the
+  allocated memory block should be \code{tp_basicsize +
+  \var{nitems}*tp_itemsize}, rounded up to a multiple of
+  \code{sizeof(void*)}; otherwise, \var{nitems} is not used and the
+  length of the block should be \member{tp_basicsize}.
+
+  Do not use this function to do any other instance initialization,
+  not even to allocate additional memory; that should be done by
+  \member{tp_new}.
+
+  This field is inherited by static subtypes, but not by dynamic
+  subtypes (subtypes created by a class statement); in the latter,
+  this field is always set to \cfunction{PyType_GenericAlloc()}, to
+  force a standard heap allocation strategy.  That is also the
+  recommended value for statically defined types.
+\end{cmemberdesc}
+
+\begin{cmemberdesc}{PyTypeObject}{newfunc}{tp_new}
+  An optional pointer to an instance creation function.
+
+  If this function is \NULL{} for a particular type, that type cannot
+  be called to create new instances; presumably there is some other
+  way to create instances, like a factory function.
+
+  The function signature is
+
+\begin{verbatim}
+PyObject *tp_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)
+\end{verbatim}
+
+  The subtype argument is the type of the object being created; the
+  \var{args} and \var{kwds} arguments represent positional and keyword
+  arguments of the call to the type.  Note that subtype doesn't have
+  to equal the type whose \member{tp_new} function is called; it may
+  be a subtype of that type (but not an unrelated type).
+
+  The \member{tp_new} function should call
+  \code{\var{subtype}->tp_alloc(\var{subtype}, \var{nitems})} to
+  allocate space for the object, and then do only as much further
+  initialization as is absolutely necessary.  Initialization that can
+  safely be ignored or repeated should be placed in the
+  \member{tp_init} handler.  A good rule of thumb is that for
+  immutable types, all initialization should take place in
+  \member{tp_new}, while for mutable types, most initialization should
+  be deferred to \member{tp_init}.
+
+  This field is inherited by subtypes, except it is not inherited by
+  static types whose \member{tp_base} is \NULL{} or
+  \code{\&PyBaseObject_Type}.  The latter exception is a precaution so
+  that old extension types don't become callable simply by being
+  linked with Python 2.2.
+\end{cmemberdesc}
+
+\begin{cmemberdesc}{PyTypeObject}{destructor}{tp_free}
+  An optional pointer to an instance deallocation function.
+
+  The signature of this function has changed slightly: in Python
+  2.2 and 2.2.1, its signature is \ctype{destructor}:
+
+\begin{verbatim}
+void tp_free(PyObject *)
+\end{verbatim}
+
+  In Python 2.3 and beyond, its signature is \ctype{freefunc}:
+
+\begin{verbatim}
+void tp_free(void *)
+\end{verbatim}
+
+  The only initializer that is compatible with both versions is
+  \code{_PyObject_Del}, whose definition has suitably adapted in
+  Python 2.3.
+
+  This field is inherited by static subtypes, but not by dynamic
+  subtypes (subtypes created by a class statement); in the latter,
+  this field is set to a deallocator suitable to match
+  \cfunction{PyType_GenericAlloc()} and the value of the
+  \constant{Py_TPFLAGS_HAVE_GC} flag bit.
+\end{cmemberdesc}
+
+\begin{cmemberdesc}{PyTypeObject}{inquiry}{tp_is_gc}
+  An optional pointer to a function called by the garbage collector.
+
+  The garbage collector needs to know whether a particular object is
+  collectible or not.  Normally, it is sufficient to look at the
+  object's type's \member{tp_flags} field, and check the
+  \constant{Py_TPFLAGS_HAVE_GC} flag bit.  But some types have a
+  mixture of statically and dynamically allocated instances, and the
+  statically allocated instances are not collectible.  Such types
+  should define this function; it should return \code{1} for a
+  collectible instance, and \code{0} for a non-collectible instance.
+  The signature is
+
+\begin{verbatim}
+int tp_is_gc(PyObject *self)
+\end{verbatim}
+
+  (The only example of this are types themselves.  The metatype,
+  \cdata{PyType_Type}, defines this function to distinguish between
+  statically and dynamically allocated types.)
+
+  This field is inherited by subtypes.  (VERSION NOTE: in Python
+  2.2, it was not inherited.  It is inherited in 2.2.1 and later
+  versions.)
+\end{cmemberdesc}
+
+\begin{cmemberdesc}{PyTypeObject}{PyObject*}{tp_bases}
+  Tuple of base types.
+
+  This is set for types created by a class statement.  It should be
+  \NULL{} for statically defined types.
+
+  This field is not inherited.
+\end{cmemberdesc}
+
+\begin{cmemberdesc}{PyTypeObject}{PyObject*}{tp_mro}
+  Tuple containing the expanded set of base types, starting with the
+  type itself and ending with \class{object}, in Method Resolution
+  Order.
+
+  This field is not inherited; it is calculated fresh by
+  \cfunction{PyType_Ready()}.
+\end{cmemberdesc}
+
+\begin{cmemberdesc}{PyTypeObject}{PyObject*}{tp_cache}
+  Unused.  Not inherited.  Internal use only.
+\end{cmemberdesc}
+
+\begin{cmemberdesc}{PyTypeObject}{PyObject*}{tp_subclasses}
+  List of weak references to subclasses.  Not inherited.  Internal
+  use only.
+\end{cmemberdesc}
+
+\begin{cmemberdesc}{PyTypeObject}{PyObject*}{tp_weaklist}
+  Weak reference list head, for weak references to this type
+  object.  Not inherited.  Internal use only.
+\end{cmemberdesc}
+
+The remaining fields are only defined if the feature test macro
+\constant{COUNT_ALLOCS} is defined, and are for internal use only.
+They are documented here for completeness.  None of these fields are
+inherited by subtypes.
+
+\begin{cmemberdesc}{PyTypeObject}{Py_ssize_t}{tp_allocs}
+  Number of allocations.
+\end{cmemberdesc}
+
+\begin{cmemberdesc}{PyTypeObject}{Py_ssize_t}{tp_frees}
+  Number of frees.
+\end{cmemberdesc}
+
+\begin{cmemberdesc}{PyTypeObject}{Py_ssize_t}{tp_maxalloc}
+  Maximum simultaneously allocated objects.
+\end{cmemberdesc}
+
+\begin{cmemberdesc}{PyTypeObject}{PyTypeObject*}{tp_next}
+  Pointer to the next type object with a non-zero \member{tp_allocs}
+  field.
+\end{cmemberdesc}
+
+Also, note that, in a garbage collected Python, tp_dealloc may be
+called from any Python thread, not just the thread which created the
+object (if the object becomes part of a refcount cycle, that cycle
+might be collected by a garbage collection on any thread).  This is
+not a problem for Python API calls, since the thread on which
+tp_dealloc is called will own the Global Interpreter Lock (GIL).
+However, if the object being destroyed in turn destroys objects from
+some other C or \Cpp{} library, care should be taken to ensure that
+destroying those objects on the thread which called tp_dealloc will
+not violate any assumptions of the library.
+
+\section{Mapping Object Structures \label{mapping-structs}}
+
+\begin{ctypedesc}{PyMappingMethods}
+  Structure used to hold pointers to the functions used to implement
+  the mapping protocol for an extension type.
+\end{ctypedesc}
+
+
+\section{Number Object Structures \label{number-structs}}
+
+\begin{ctypedesc}{PyNumberMethods}
+  Structure used to hold pointers to the functions an extension type
+  uses to implement the number protocol.
+\end{ctypedesc}
+
+
+\section{Sequence Object Structures \label{sequence-structs}}
+
+\begin{ctypedesc}{PySequenceMethods}
+  Structure used to hold pointers to the functions which an object
+  uses to implement the sequence protocol.
+\end{ctypedesc}
+
+
+\section{Buffer Object Structures \label{buffer-structs}}
+\sectionauthor{Greg J. Stein}{greg at lyra.org}
+
+The buffer interface exports a model where an object can expose its
+internal data as a set of chunks of data, where each chunk is
+specified as a pointer/length pair.  These chunks are called
+\dfn{segments} and are presumed to be non-contiguous in memory.
+
+If an object does not export the buffer interface, then its
+\member{tp_as_buffer} member in the \ctype{PyTypeObject} structure
+should be \NULL.  Otherwise, the \member{tp_as_buffer} will point to
+a \ctype{PyBufferProcs} structure.
+
+\note{It is very important that your \ctype{PyTypeObject} structure
+uses \constant{Py_TPFLAGS_DEFAULT} for the value of the
+\member{tp_flags} member rather than \code{0}.  This tells the Python
+runtime that your \ctype{PyBufferProcs} structure contains the
+\member{bf_getcharbuffer} slot. Older versions of Python did not have
+this member, so a new Python interpreter using an old extension needs
+to be able to test for its presence before using it.}
+
+\begin{ctypedesc}{PyBufferProcs}
+  Structure used to hold the function pointers which define an
+  implementation of the buffer protocol.
+
+  The first slot is \member{bf_getreadbuffer}, of type
+  \ctype{getreadbufferproc}.  If this slot is \NULL, then the object
+  does not support reading from the internal data.  This is
+  non-sensical, so implementors should fill this in, but callers
+  should test that the slot contains a non-\NULL{} value.
+
+  The next slot is \member{bf_getwritebuffer} having type
+  \ctype{getwritebufferproc}.  This slot may be \NULL{} if the object
+  does not allow writing into its returned buffers.
+
+  The third slot is \member{bf_getsegcount}, with type
+  \ctype{getsegcountproc}.  This slot must not be \NULL{} and is used
+  to inform the caller how many segments the object contains.  Simple
+  objects such as \ctype{PyString_Type} and \ctype{PyBuffer_Type}
+  objects contain a single segment.
+
+  The last slot is \member{bf_getcharbuffer}, of type
+  \ctype{getcharbufferproc}.  This slot will only be present if the
+  \constant{Py_TPFLAGS_HAVE_GETCHARBUFFER} flag is present in the
+  \member{tp_flags} field of the object's \ctype{PyTypeObject}.
+  Before using this slot, the caller should test whether it is present
+  by using the
+  \cfunction{PyType_HasFeature()}\ttindex{PyType_HasFeature()}
+  function.  If the flag is present, \member{bf_getcharbuffer} may be
+  \NULL,
+  indicating that the object's
+  contents cannot be used as \emph{8-bit characters}.
+  The slot function may also raise an error if the object's contents
+  cannot be interpreted as 8-bit characters.  For example, if the
+  object is an array which is configured to hold floating point
+  values, an exception may be raised if a caller attempts to use
+  \member{bf_getcharbuffer} to fetch a sequence of 8-bit characters.
+  This notion of exporting the internal buffers as ``text'' is used to
+  distinguish between objects that are binary in nature, and those
+  which have character-based content.
+
+  \note{The current policy seems to state that these characters
+  may be multi-byte characters. This implies that a buffer size of
+  \var{N} does not mean there are \var{N} characters present.}
+\end{ctypedesc}
+
+\begin{datadesc}{Py_TPFLAGS_HAVE_GETCHARBUFFER}
+  Flag bit set in the type structure to indicate that the
+  \member{bf_getcharbuffer} slot is known.  This being set does not
+  indicate that the object supports the buffer interface or that the
+  \member{bf_getcharbuffer} slot is non-\NULL.
+\end{datadesc}
+
+\begin{ctypedesc}[getreadbufferproc]{Py_ssize_t (*readbufferproc)
+                            (PyObject *self, Py_ssize_t segment, void **ptrptr)}
+  Return a pointer to a readable segment of the buffer in
+  \code{*\var{ptrptr}}.  This function
+  is allowed to raise an exception, in which case it must return
+  \code{-1}.  The \var{segment} which is specified must be zero or
+  positive, and strictly less than the number of segments returned by
+  the \member{bf_getsegcount} slot function.  On success, it returns
+  the length of the segment, and sets \code{*\var{ptrptr}} to a
+  pointer to that memory.
+\end{ctypedesc}
+
+\begin{ctypedesc}[getwritebufferproc]{Py_ssize_t (*writebufferproc)
+                            (PyObject *self, Py_ssize_t segment, void **ptrptr)}
+  Return a pointer to a writable memory buffer in
+  \code{*\var{ptrptr}}, and the length of that segment as the function
+  return value.  The memory buffer must correspond to buffer segment
+  \var{segment}.  Must return \code{-1} and set an exception on
+  error.  \exception{TypeError} should be raised if the object only
+  supports read-only buffers, and \exception{SystemError} should be
+  raised when \var{segment} specifies a segment that doesn't exist.
+% Why doesn't it raise ValueError for this one?
+% GJS: because you shouldn't be calling it with an invalid
+%      segment. That indicates a blatant programming error in the C
+%      code.
+\end{ctypedesc}
+
+\begin{ctypedesc}[getsegcountproc]{Py_ssize_t (*segcountproc)
+                            (PyObject *self, Py_ssize_t *lenp)}
+  Return the number of memory segments which comprise the buffer.  If
+  \var{lenp} is not \NULL, the implementation must report the sum of
+  the sizes (in bytes) of all segments in \code{*\var{lenp}}.
+  The function cannot fail.
+\end{ctypedesc}
+
+\begin{ctypedesc}[getcharbufferproc]{Py_ssize_t (*charbufferproc)
+                            (PyObject *self, Py_ssize_t segment, const char **ptrptr)}
+  Return the size of the segment \var{segment} that \var{ptrptr} 
+  is set to.  \code{*\var{ptrptr}} is set to the memory buffer.
+  Returns \code{-1} on error.
+\end{ctypedesc}
+
+
+\section{Supporting the Iterator Protocol
+         \label{supporting-iteration}}
+
+
+\section{Supporting Cyclic Garbage Collection
+         \label{supporting-cycle-detection}}
+
+Python's support for detecting and collecting garbage which involves
+circular references requires support from object types which are
+``containers'' for other objects which may also be containers.  Types
+which do not store references to other objects, or which only store
+references to atomic types (such as numbers or strings), do not need
+to provide any explicit support for garbage collection.
+
+An example showing the use of these interfaces can be found in
+``\ulink{Supporting the Cycle
+Collector}{../ext/example-cycle-support.html}'' in
+\citetitle[../ext/ext.html]{Extending and Embedding the Python
+Interpreter}.
+
+To create a container type, the \member{tp_flags} field of the type
+object must include the \constant{Py_TPFLAGS_HAVE_GC} and provide an
+implementation of the \member{tp_traverse} handler.  If instances of the
+type are mutable, a \member{tp_clear} implementation must also be
+provided.
+
+\begin{datadesc}{Py_TPFLAGS_HAVE_GC}
+  Objects with a type with this flag set must conform with the rules
+  documented here.  For convenience these objects will be referred to
+  as container objects.
+\end{datadesc}
+
+Constructors for container types must conform to two rules:
+
+\begin{enumerate}
+\item  The memory for the object must be allocated using
+       \cfunction{PyObject_GC_New()} or \cfunction{PyObject_GC_VarNew()}.
+
+\item  Once all the fields which may contain references to other
+       containers are initialized, it must call
+       \cfunction{PyObject_GC_Track()}.
+\end{enumerate}
+
+\begin{cfuncdesc}{\var{TYPE}*}{PyObject_GC_New}{TYPE, PyTypeObject *type}
+  Analogous to \cfunction{PyObject_New()} but for container objects with
+  the \constant{Py_TPFLAGS_HAVE_GC} flag set.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{\var{TYPE}*}{PyObject_GC_NewVar}{TYPE, PyTypeObject *type,
+                                                   Py_ssize_t size}
+  Analogous to \cfunction{PyObject_NewVar()} but for container objects
+  with the \constant{Py_TPFLAGS_HAVE_GC} flag set.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyVarObject *}{PyObject_GC_Resize}{PyVarObject *op, Py_ssize_t}
+  Resize an object allocated by \cfunction{PyObject_NewVar()}.  Returns
+  the resized object or \NULL{} on failure.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{PyObject_GC_Track}{PyObject *op}
+  Adds the object \var{op} to the set of container objects tracked by
+  the collector.  The collector can run at unexpected times so objects
+  must be valid while being tracked.  This should be called once all
+  the fields followed by the \member{tp_traverse} handler become valid,
+  usually near the end of the constructor.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{_PyObject_GC_TRACK}{PyObject *op}
+  A macro version of \cfunction{PyObject_GC_Track()}.  It should not be
+  used for extension modules.
+\end{cfuncdesc}
+
+Similarly, the deallocator for the object must conform to a similar
+pair of rules:
+
+\begin{enumerate}
+\item  Before fields which refer to other containers are invalidated,
+       \cfunction{PyObject_GC_UnTrack()} must be called.
+
+\item  The object's memory must be deallocated using
+       \cfunction{PyObject_GC_Del()}.
+\end{enumerate}
+
+\begin{cfuncdesc}{void}{PyObject_GC_Del}{void *op}
+  Releases memory allocated to an object using
+  \cfunction{PyObject_GC_New()} or \cfunction{PyObject_GC_NewVar()}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{PyObject_GC_UnTrack}{void *op}
+  Remove the object \var{op} from the set of container objects tracked
+  by the collector.  Note that \cfunction{PyObject_GC_Track()} can be
+  called again on this object to add it back to the set of tracked
+  objects.  The deallocator (\member{tp_dealloc} handler) should call
+  this for the object before any of the fields used by the
+  \member{tp_traverse} handler become invalid.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{_PyObject_GC_UNTRACK}{PyObject *op}
+  A macro version of \cfunction{PyObject_GC_UnTrack()}.  It should not be
+  used for extension modules.
+\end{cfuncdesc}
+
+The \member{tp_traverse} handler accepts a function parameter of this
+type:
+
+\begin{ctypedesc}[visitproc]{int (*visitproc)(PyObject *object, void *arg)}
+  Type of the visitor function passed to the \member{tp_traverse}
+  handler.  The function should be called with an object to traverse
+  as \var{object} and the third parameter to the \member{tp_traverse}
+  handler as \var{arg}.  The Python core uses several visitor functions
+  to implement cyclic garbage detection; it's not expected that users will
+  need to write their own visitor functions.
+\end{ctypedesc}
+
+The \member{tp_traverse} handler must have the following type:
+
+\begin{ctypedesc}[traverseproc]{int (*traverseproc)(PyObject *self,
+                                visitproc visit, void *arg)}
+  Traversal function for a container object.  Implementations must
+  call the \var{visit} function for each object directly contained by
+  \var{self}, with the parameters to \var{visit} being the contained
+  object and the \var{arg} value passed to the handler.  The \var{visit}
+  function must not be called with a \NULL{} object argument.  If
+  \var{visit} returns a non-zero value
+  that value should be returned immediately.
+\end{ctypedesc}
+
+To simplify writing \member{tp_traverse} handlers, a
+\cfunction{Py_VISIT()} macro is provided.  In order to use this macro,
+the \member{tp_traverse} implementation must name its arguments
+exactly \var{visit} and \var{arg}:
+
+\begin{cfuncdesc}{void}{Py_VISIT}{PyObject *o}
+  Call the \var{visit} callback, with arguments \var{o} and \var{arg}.
+  If \var{visit} returns a non-zero value, then return it.  Using this
+  macro, \member{tp_traverse} handlers look like:
+
+\begin{verbatim}
+static int
+my_traverse(Noddy *self, visitproc visit, void *arg)
+{
+    Py_VISIT(self->foo);
+    Py_VISIT(self->bar);
+    return 0;
+}
+\end{verbatim}
+
+\versionadded{2.4}
+\end{cfuncdesc}
+
+
+The \member{tp_clear} handler must be of the \ctype{inquiry} type, or
+\NULL{} if the object is immutable.
+
+\begin{ctypedesc}[inquiry]{int (*inquiry)(PyObject *self)}
+  Drop references that may have created reference cycles.  Immutable
+  objects do not have to define this method since they can never
+  directly create reference cycles.  Note that the object must still
+  be valid after calling this method (don't just call
+  \cfunction{Py_DECREF()} on a reference).  The collector will call
+  this method if it detects that this object is involved in a
+  reference cycle.
+\end{ctypedesc}

Added: vendor/Python/current/Doc/api/refcounting.tex
===================================================================
--- vendor/Python/current/Doc/api/refcounting.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/api/refcounting.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,69 @@
+\chapter{Reference Counting \label{countingRefs}}
+
+
+The macros in this section are used for managing reference counts
+of Python objects.
+
+
+\begin{cfuncdesc}{void}{Py_INCREF}{PyObject *o}
+  Increment the reference count for object \var{o}.  The object must
+  not be \NULL; if you aren't sure that it isn't \NULL, use
+  \cfunction{Py_XINCREF()}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{Py_XINCREF}{PyObject *o}
+  Increment the reference count for object \var{o}.  The object may be
+  \NULL, in which case the macro has no effect.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{Py_DECREF}{PyObject *o}
+  Decrement the reference count for object \var{o}.  The object must
+  not be \NULL; if you aren't sure that it isn't \NULL, use
+  \cfunction{Py_XDECREF()}.  If the reference count reaches zero, the
+  object's type's deallocation function (which must not be \NULL) is
+  invoked.
+
+  \warning{The deallocation function can cause arbitrary Python code
+  to be invoked (e.g. when a class instance with a \method{__del__()}
+  method is deallocated).  While exceptions in such code are not
+  propagated, the executed code has free access to all Python global
+  variables.  This means that any object that is reachable from a
+  global variable should be in a consistent state before
+  \cfunction{Py_DECREF()} is invoked.  For example, code to delete an
+  object from a list should copy a reference to the deleted object in
+  a temporary variable, update the list data structure, and then call
+  \cfunction{Py_DECREF()} for the temporary variable.}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{Py_XDECREF}{PyObject *o}
+  Decrement the reference count for object \var{o}.  The object may be
+  \NULL, in which case the macro has no effect; otherwise the effect
+  is the same as for \cfunction{Py_DECREF()}, and the same warning
+  applies.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{Py_CLEAR}{PyObject *o}
+  Decrement the reference count for object \var{o}.  The object may be
+  \NULL, in which case the macro has no effect; otherwise the effect
+  is the same as for \cfunction{Py_DECREF()}, except that the argument
+  is also set to \NULL.  The warning for \cfunction{Py_DECREF()} does
+  not apply with respect to the object passed because the macro
+  carefully uses a temporary variable and sets the argument to \NULL
+  before decrementing its reference count.
+
+  It is a good idea to use this macro whenever decrementing the value
+  of a variable that might be traversed during garbage collection.
+
+\versionadded{2.4}
+\end{cfuncdesc}
+
+
+The following functions are for runtime dynamic embedding of Python:
+\cfunction{Py_IncRef(PyObject *o)}, \cfunction{Py_DecRef(PyObject *o)}.
+They are simply exported function versions of \cfunction{Py_XINCREF()} and 
+\cfunction{Py_XDECREF()}, respectively.
+
+The following functions or macros are only for use within the
+interpreter core: \cfunction{_Py_Dealloc()},
+\cfunction{_Py_ForgetReference()}, \cfunction{_Py_NewReference()}, as
+well as the global variable \cdata{_Py_RefTotal}.

Added: vendor/Python/current/Doc/api/refcounts.dat
===================================================================
--- vendor/Python/current/Doc/api/refcounts.dat	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/api/refcounts.dat	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1756 @@
+# Created by Skip Montanaro <skip at mojam.com>.
+
+# Format:
+#	function ':' type ':' [param name] ':' [refcount effect] ':' [comment]
+# If the param name slot is empty, that line corresponds to the function's
+# return value, otherwise it's the type of the named parameter.
+
+# The first line of a function block gives type/refcount information for the
+# function's return value.  Successive lines with the same function name
+# correspond to the function's parameter list and appear in the order the
+# parameters appear in the function's prototype.
+
+# For readability, each function's lines are surrounded by a blank line.
+# The blocks are sorted alphabetically by function name.
+
+# Refcount behavior is given for all PyObject* types: 0 (no change), +1
+# (increment) and -1 (decrement).  A blank refcount field indicates the
+# parameter or function value is not a PyObject* and is therefore not
+# subject to reference counting.  A special case for the value "null"
+# (without quotes) is used for functions which return a PyObject* type but
+# always return NULL.  This is used by some of the PyErr_*() functions, in
+# particular.
+
+# XXX NOTE: the 0/+1/-1 refcount information for arguments is
+# confusing!  Much more useful would be to indicate whether the
+# function "steals" a reference to the argument or not.  Take for
+# example PyList_SetItem(list, i, item).  This lists as a 0 change for
+# both the list and the item arguments.  However, in fact it steals a
+# reference to the item argument!
+
+# The parameter names are as they appear in the API manual, not the source
+# code. 
+
+PyBool_FromLong:PyObject*::+1:
+PyBool_FromLong:long:v:0:
+
+PyBuffer_FromObject:PyObject*::+1:
+PyBuffer_FromObject:PyObject*:base:+1:
+PyBuffer_FromObject:int:offset::
+PyBuffer_FromObject:int:size::
+
+PyBuffer_FromReadWriteObject:PyObject*::+1:
+PyBuffer_FromReadWriteObject:PyObject*:base:+1:
+PyBuffer_FromReadWriteObject:int:offset::
+PyBuffer_FromReadWriteObject:int:size::
+
+PyBuffer_FromMemory:PyObject*::+1:
+PyBuffer_FromMemory:void*:ptr::
+PyBuffer_FromMemory:int:size::
+
+PyBuffer_FromReadWriteMemory:PyObject*::+1:
+PyBuffer_FromReadWriteMemory:void*:ptr::
+PyBuffer_FromReadWriteMemory:int:size::
+
+PyBuffer_New:PyObject*::+1:
+PyBuffer_New:int:size::
+
+PyCObject_AsVoidPtr:void*:::
+PyCObject_AsVoidPtr:PyObject*:self:0:
+
+PyCObject_FromVoidPtr:PyObject*::+1:
+PyCObject_FromVoidPtr:void*:cobj::
+PyCObject_FromVoidPtr::void (* destr)(void* )::
+
+PyCObject_FromVoidPtrAndDesc:PyObject*::+1:
+PyCObject_FromVoidPtrAndDesc:void*:cobj::
+PyCObject_FromVoidPtrAndDesc:void*:desc::
+PyCObject_FromVoidPtrAndDesc:void(*)(void*,void*):destr::
+
+PyCObject_GetDesc:void*:::
+PyCObject_GetDesc:PyObject*:self:0:
+
+PyCell_New:PyObject*::+1:
+PyCell_New:PyObject*:ob:0:
+
+PyCell_GET:PyObject*::0:
+PyCell_GET:PyObject*:ob:0:
+
+PyCell_Get:PyObject*::+1:
+PyCell_Get:PyObject*:cell:0:
+
+PyCell_SET:void:::
+PyCell_SET:PyObject*:cell:0:
+PyCell_SET:PyObject*:value:0:
+
+PyCell_Set:int:::
+PyCell_Set:PyObject*:cell:0:
+PyCell_Set:PyObject*:value:0:
+
+PyCallIter_New:PyObject*::+1:
+PyCallIter_New:PyObject*:callable::
+PyCallIter_New:PyObject*:sentinel::
+
+PyCallable_Check:int:::
+PyCallable_Check:PyObject*:o:0:
+
+PyComplex_AsCComplex:Py_complex:::
+PyComplex_AsCComplex:PyObject*:op:0:
+
+PyComplex_Check:int:::
+PyComplex_Check:PyObject*:p:0:
+
+PyComplex_FromCComplex:PyObject*::+1:
+PyComplex_FromCComplex::Py_complex v::
+
+PyComplex_FromDoubles:PyObject*::+1:
+PyComplex_FromDoubles::double real::
+PyComplex_FromDoubles::double imag::
+
+PyComplex_ImagAsDouble:double:::
+PyComplex_ImagAsDouble:PyObject*:op:0:
+
+PyComplex_RealAsDouble:double:::
+PyComplex_RealAsDouble:PyObject*:op:0:
+
+PyDate_FromDate:PyObject*::+1:
+PyDate_FromDate:int:year::
+PyDate_FromDate:int:month::
+PyDate_FromDate:int:day::
+
+PyDate_FromTimestamp:PyObject*::+1:
+PyDate_FromTimestamp:PyObject*:args:0:
+
+PyDateTime_FromDateAndTime:PyObject*::+1:
+PyDateTime_FromDateAndTime:int:year::
+PyDateTime_FromDateAndTime:int:month::
+PyDateTime_FromDateAndTime:int:day::
+PyDateTime_FromDateAndTime:int:hour::
+PyDateTime_FromDateAndTime:int:minute::
+PyDateTime_FromDateAndTime:int:second::
+PyDateTime_FromDateAndTime:int:usecond::
+
+PyDateTime_FromTimestamp:PyObject*::+1:
+PyDateTime_FromTimestamp:PyObject*:args:0:
+
+PyDelta_FromDSU:PyObject*::+1:
+PyDelta_FromDSU:int:days::
+PyDelta_FromDSU:int:seconds::
+PyDelta_FromDSU:int:useconds::
+
+PyDescr_NewClassMethod:PyObject*::+1:
+PyDescr_NewClassMethod:PyTypeObject*:type::
+PyDescr_NewClassMethod:PyMethodDef*:method::
+
+PyDescr_NewGetSet:PyObject*::+1:
+PyDescr_NewGetSet:PyTypeObject*:type::
+PyDescr_NewGetSet:PyGetSetDef*:getset::
+
+PyDescr_NewMember:PyObject*::+1:
+PyDescr_NewMember:PyTypeObject*:type::
+PyDescr_NewMember:PyMemberDef*:member::
+
+PyDescr_NewMethod:PyObject*::+1:
+PyDescr_NewMethod:PyTypeObject*:type::
+PyDescr_NewMethod:PyMethodDef*:meth::
+
+PyDescr_NewWrapper:PyObject*::+1:
+PyDescr_NewWrapper:PyTypeObject*:type::
+PyDescr_NewWrapper:struct wrapperbase*:base::
+PyDescr_NewWrapper:void*:wrapped::
+
+PyDict_Check:int:::
+PyDict_Check:PyObject*:p:0:
+
+PyDict_Clear:void:::
+PyDict_Clear:PyObject*:p:0:
+
+PyDict_DelItem:int:::
+PyDict_DelItem:PyObject*:p:0:
+PyDict_DelItem:PyObject*:key:0:
+
+PyDict_DelItemString:int:::
+PyDict_DelItemString:PyObject*:p:0:
+PyDict_DelItemString:char*:key::
+
+PyDict_GetItem:PyObject*::0:0
+PyDict_GetItem:PyObject*:p:0:
+PyDict_GetItem:PyObject*:key:0:
+
+PyDict_GetItemString:PyObject*::0:
+PyDict_GetItemString:PyObject*:p:0:
+PyDict_GetItemString:char*:key::
+
+PyDict_Items:PyObject*::+1:
+PyDict_Items:PyObject*:p:0:
+
+PyDict_Keys:PyObject*::+1:
+PyDict_Keys:PyObject*:p:0:
+
+PyDict_New:PyObject*::+1:
+
+PyDict_Copy:PyObject*::+1:
+PyDict_Copy:PyObject*:p:0:
+
+PyDict_Next:int:::
+PyDict_Next:PyObject*:p:0:
+PyDict_Next:int:ppos::
+PyDict_Next:PyObject**:pkey:0:
+PyDict_Next:PyObject**:pvalue:0:
+
+PyDict_SetItem:int:::
+PyDict_SetItem:PyObject*:p:0:
+PyDict_SetItem:PyObject*:key:+1:
+PyDict_SetItem:PyObject*:val:+1:
+
+PyDict_SetItemString:int:::
+PyDict_SetItemString:PyObject*:p:0:
+PyDict_SetItemString:char*:key::
+PyDict_SetItemString:PyObject*:val:+1:
+
+PyDict_Size:int:::
+PyDict_Size:PyObject*:p::
+
+PyDict_Values:PyObject*::+1:
+PyDict_Values:PyObject*:p:0:
+
+PyDictProxy_New:PyObject*::+1:
+PyDictProxy_New:PyObject*:dict:0:
+
+PyErr_BadArgument:int:::
+
+PyErr_BadInternalCall:void:::
+
+PyErr_CheckSignals:int:::
+
+PyErr_Clear:void:::
+
+PyErr_ExceptionMatches:int:::
+PyErr_ExceptionMatches:PyObject*:exc:0:
+
+PyErr_Fetch:void:::
+PyErr_Fetch:PyObject**:ptype:0:
+PyErr_Fetch:PyObject**:pvalue:0:
+PyErr_Fetch:PyObject**:ptraceback:0:
+
+PyErr_GivenExceptionMatches:int:::
+PyErr_GivenExceptionMatches:PyObject*:given:0:
+PyErr_GivenExceptionMatches:PyObject*:exc:0:
+
+PyErr_NewException:PyObject*::+1:
+PyErr_NewException:char*:name::
+PyErr_NewException:PyObject*:base:0:
+PyErr_NewException:PyObject*:dict:0:
+
+PyErr_NoMemory:PyObject*::null:
+
+PyErr_NormalizeException:void:::
+PyErr_NormalizeException:PyObject**:exc::???
+PyErr_NormalizeException:PyObject**:val::???
+PyErr_NormalizeException:PyObject**:tb::???
+
+PyErr_Occurred:PyObject*::0:
+
+PyErr_Print:void:::
+
+PyErr_Restore:void:::
+PyErr_Restore:PyObject*:type:-1:
+PyErr_Restore:PyObject*:value:-1:
+PyErr_Restore:PyObject*:traceback:-1:
+
+PyErr_SetExcFromWindowsErr:PyObject*::null:
+PyErr_SetExcFromWindowsErr:PyObject*:type:0:
+PyErr_SetExcFromWindowsErr:int:ierr::
+
+PyErr_SetExcFromWindowsErrWithFilename:PyObject*::null:
+PyErr_SetExcFromWindowsErrWithFilename:PyObject*:type:0:
+PyErr_SetExcFromWindowsErrWithFilename:int:ierr::
+PyErr_SetExcFromWindowsErrWithFilename:char*:filename::
+
+PyErr_SetFromErrno:PyObject*::null:
+PyErr_SetFromErrno:PyObject*:type:0:
+
+PyErr_SetFromErrnoWithFilename:PyObject*::null:
+PyErr_SetFromErrnoWithFilename:PyObject*:type:0:
+PyErr_SetFromErrnoWithFilename:char*:filename::
+
+PyErr_SetFromWindowsErr:PyObject*::null:
+PyErr_SetFromWindowsErr:int:ierr::
+
+PyErr_SetFromWindowsErrWithFilename:PyObject*::null:
+PyErr_SetFromWindowsErrWithFilename:int:ierr::
+PyErr_SetFromWindowsErrWithFilename:char*:filename::
+
+PyErr_SetInterrupt:void:::
+
+PyErr_SetNone:void:::
+PyErr_SetNone:PyObject*:type:+1:
+
+PyErr_SetObject:void:::
+PyErr_SetObject:PyObject*:type:+1:
+PyErr_SetObject:PyObject*:value:+1:
+
+PyErr_SetString:void:::
+PyErr_SetString:PyObject*:type:+1:
+PyErr_SetString:char*:message::
+
+PyErr_Format:PyObject*::null:
+PyErr_Format:PyObject*:exception:+1:
+PyErr_Format:char*:format::
+PyErr_Format::...::
+
+PyErr_Warn:int:::
+PyErr_Warn:PyObject*:category:0:
+PyErr_Warn:char*:message::
+
+PyErr_WarnEx:int:::
+PyErr_WarnEx:PyObject*:category:0:
+PyErr_WarnEx:const char*:message::
+PyErr_WarnEx:Py_ssize_t:stack_level::
+
+PyEval_AcquireLock:void:::
+
+PyEval_AcquireThread:void:::
+PyEval_AcquireThread:PyThreadState*:tstate::
+
+PyEval_InitThreads:void:::
+
+PyEval_ReleaseLock:void:::
+
+PyEval_ReleaseThread:void:::
+PyEval_ReleaseThread:PyThreadState*:tstate::
+
+PyEval_RestoreThread:void:::
+PyEval_RestoreThread:PyThreadState*:tstate::
+
+PyEval_SaveThread:PyThreadState*:::
+
+PyEval_EvalCode:PyObject*::+1:
+PyEval_EvalCode:PyCodeObject*:co:0:
+PyEval_EvalCode:PyObject*:globals:0:
+PyEval_EvalCode:PyObject*:locals:0:
+
+PyFile_AsFile:FILE*:::
+PyFile_AsFile:PyFileObject*:p:0:
+
+PyFile_Check:int:::
+PyFile_Check:PyObject*:p:0:
+
+PyFile_FromFile:PyObject*::+1:
+PyFile_FromFile:FILE*:fp::
+PyFile_FromFile:char*:name::
+PyFile_FromFile:char*:mode::
+PyFile_FromFile:int(*:close)::
+
+PyFile_FromString:PyObject*::+1:
+PyFile_FromString:char*:name::
+PyFile_FromString:char*:mode::
+
+PyFile_GetLine:PyObject*::+1:
+PyFile_GetLine:PyObject*:p::
+PyFile_GetLine:int:n::
+
+PyFile_Name:PyObject*::0:
+PyFile_Name:PyObject*:p:0:
+
+PyFile_SetBufSize:void:::
+PyFile_SetBufSize:PyFileObject*:p:0:
+PyFile_SetBufSize:int:n::
+
+PyFile_SoftSpace:int:::
+PyFile_SoftSpace:PyFileObject*:p:0:
+PyFile_SoftSpace:int:newflag::
+
+PyFile_WriteObject:int:::
+PyFile_WriteObject:PyObject*:obj:0:
+PyFile_WriteObject:PyFileObject*:p:0:
+PyFile_WriteObject:int:flags::
+
+PyFile_WriteString:int:::
+PyFile_WriteString:const char*:s::
+PyFile_WriteString:PyFileObject*:p:0:
+PyFile_WriteString:int:flags::
+
+PyFloat_AS_DOUBLE:double:::
+PyFloat_AS_DOUBLE:PyObject*:pyfloat:0:
+
+PyFloat_AsDouble:double:::
+PyFloat_AsDouble:PyObject*:pyfloat:0:
+
+PyFloat_Check:int:::
+PyFloat_Check:PyObject*:p:0:
+
+PyFloat_FromDouble:PyObject*::+1:
+PyFloat_FromDouble:double:v::
+
+PyFloat_FromString:PyObject*::+1:
+PyFloat_FromString:PyObject*:str:0:
+PyFloat_FromString:char**:pend:0:ignored
+
+PyFrozenSet_New:PyObject*::+1:
+PyFrozenSet_New:PyObject*:iterable:0:
+
+PyFunction_GetClosure:PyObject*::0:
+PyFunction_GetClosure:PyObject*:op:0:
+
+PyFunction_GetCode:PyObject*::0:
+PyFunction_GetCode:PyObject*:op:0:
+
+PyFunction_GetDefaults:PyObject*::0:
+PyFunction_GetDefaults:PyObject*:op:0:
+
+PyFunction_GetGlobals:PyObject*::0:
+PyFunction_GetGlobals:PyObject*:op:0:
+
+PyFunction_GetModule:PyObject*::0:
+PyFunction_GetModule:PyObject*:op:0:
+
+PyFunction_New:PyObject*::+1:
+PyFunction_New:PyObject*:code:+1:
+PyFunction_New:PyObject*:globals:+1:
+
+PyFunction_SetClosure:int:::
+PyFunction_SetClosure:PyObject*:op:0:
+PyFunction_SetClosure:PyObject*:closure:+1:
+
+PyFunction_SetDefaults:int:::
+PyFunction_SetDefaults:PyObject*:op:0:
+PyFunction_SetDefaults:PyObject*:defaults:+1:
+
+PyGen_New:PyObject*::+1:
+PyGen_New:PyFrameObject*:frame:0:
+
+Py_InitModule:PyObject*::0:
+Py_InitModule:char*:name::
+Py_InitModule:PyMethodDef[]:methods::
+
+Py_InitModule3:PyObject*::0:
+Py_InitModule3:char*:name::
+Py_InitModule3:PyMethodDef[]:methods::
+Py_InitModule3:char*:doc::
+
+Py_InitModule4:PyObject*::0:
+Py_InitModule4:char*:name::
+Py_InitModule4:PyMethodDef[]:methods::
+Py_InitModule4:char*:doc::
+Py_InitModule4:PyObject*:self::
+Py_InitModule4:int:apiver::usually provided by Py_InitModule or Py_InitModule3
+
+PyImport_AddModule:PyObject*::0:reference borrowed from sys.modules
+PyImport_AddModule:char*:name::
+
+PyImport_Cleanup:void:::
+
+PyImport_ExecCodeModule:PyObject*::+1:
+PyImport_ExecCodeModule:char*:name::
+PyImport_ExecCodeModule:PyObject*:co:0:
+
+PyImport_GetMagicNumber:long:::
+
+PyImport_GetModuleDict:PyObject*::0:
+
+PyImport_Import:PyObject*::+1:
+PyImport_Import:PyObject*:name:0:
+
+PyImport_ImportFrozenModule:int:::
+PyImport_ImportFrozenModule:char*:::
+
+PyImport_ImportModule:PyObject*::+1:
+PyImport_ImportModule:char*:name::
+
+PyImport_ImportModuleEx:PyObject*::+1:
+PyImport_ImportModuleEx:char*:name::
+PyImport_ImportModuleEx:PyObject*:globals:0:???
+PyImport_ImportModuleEx:PyObject*:locals:0:???
+PyImport_ImportModuleEx:PyObject*:fromlist:0:???
+
+PyImport_ReloadModule:PyObject*::+1:
+PyImport_ReloadModule:PyObject*:m:0:
+
+PyInstance_New:PyObject*::+1:
+PyInstance_New:PyObject*:klass:+1:
+PyInstance_New:PyObject*:arg:0:
+PyInstance_New:PyObject*:kw:0:
+
+PyInstance_NewRaw:PyObject*::+1:
+PyInstance_NewRaw:PyObject*:klass:+1:
+PyInstance_NewRaw:PyObject*:dict:+1:
+
+PyInt_AS_LONG:long:::
+PyInt_AS_LONG:PyIntObject*:io:0:
+
+PyInt_AsLong:long:::
+PyInt_AsLong:PyObject*:io:0:
+
+PyInt_Check:int:::
+PyInt_Check:PyObject*:op:0:
+
+PyInt_FromLong:PyObject*::+1:
+PyInt_FromLong:long:ival::
+
+PyInt_FromString:PyObject*::+1:
+PyInt_FromString:char*:str:0:
+PyInt_FromString:char**:pend:0:
+PyInt_FromString:int:base:0:
+
+PyInt_FromSsize_t:PyObject*::+1:
+PyInt_FromSsize_t:Py_ssize_t:ival::
+
+PyInt_GetMax:long:::
+
+PyInterpreterState_Clear:void:::
+PyInterpreterState_Clear:PyInterpreterState*:interp::
+
+PyInterpreterState_Delete:void:::
+PyInterpreterState_Delete:PyInterpreterState*:interp::
+
+PyInterpreterState_New:PyInterpreterState*:::
+
+PyIter_Check:int:o:0:
+
+PyIter_Next:PyObject*::+1:
+PyIter_Next:PyObject*:o:0:
+
+PyList_Append:int:::
+PyList_Append:PyObject*:list:0:
+PyList_Append:PyObject*:item:+1:
+
+PyList_AsTuple:PyObject*::+1:
+PyList_AsTuple:PyObject*:list:0:
+
+PyList_Check:int:::
+PyList_Check:PyObject*:p:0:
+
+PyList_GET_ITEM:PyObject*::0:
+PyList_GET_ITEM:PyObject*:list:0:
+PyList_GET_ITEM:int:i:0:
+
+PyList_GET_SIZE:int:::
+PyList_GET_SIZE:PyObject*:list:0:
+
+PyList_GetItem:PyObject*::0:
+PyList_GetItem:PyObject*:list:0:
+PyList_GetItem:int:index::
+
+PyList_GetSlice:PyObject*::+1:
+PyList_GetSlice:PyObject*:list:0:
+PyList_GetSlice:int:low::
+PyList_GetSlice:int:high::
+
+PyList_Insert:int:::
+PyList_Insert:PyObject*:list:0:
+PyList_Insert:int:index::
+PyList_Insert:PyObject*:item:+1:
+
+PyList_New:PyObject*::+1:
+PyList_New:int:len::
+
+PyList_Reverse:int:::
+PyList_Reverse:PyObject*:list:0:
+
+PyList_SET_ITEM:void:::
+PyList_SET_ITEM:PyObject*:list:0:
+PyList_SET_ITEM:int:i::
+PyList_SET_ITEM:PyObject*:o:0:
+
+PyList_SetItem:int:::
+PyList_SetItem:PyObject*:list:0:
+PyList_SetItem:int:index::
+PyList_SetItem:PyObject*:item:0:
+
+PyList_SetSlice:int:::
+PyList_SetSlice:PyObject*:list:0:
+PyList_SetSlice:int:low::
+PyList_SetSlice:int:high::
+PyList_SetSlice:PyObject*:itemlist:0:but increfs its elements?
+
+PyList_Size:int:::
+PyList_Size:PyObject*:list:0:
+
+PyList_Sort:int:::
+PyList_Sort:PyObject*:list:0:
+
+PyLong_AsDouble:double:::
+PyLong_AsDouble:PyObject*:pylong:0:
+
+PyLong_AsLong:long:::
+PyLong_AsLong:PyObject*:pylong:0:
+
+PyLong_AsUnsignedLong:unsigned long:::
+PyLong_AsUnsignedLong:PyObject*:pylong:0:
+
+PyLong_Check:int:::
+PyLong_Check:PyObject*:p:0:
+
+PyLong_FromDouble:PyObject*::+1:
+PyLong_FromDouble:double:v::
+
+PyLong_FromLong:PyObject*::+1:
+PyLong_FromLong:long:v::
+
+PyLong_FromLongLong:PyObject*::+1:
+PyLong_FromLongLong:long long:v::
+
+PyLong_FromUnsignedLongLong:PyObject*::+1:
+PyLong_FromUnsignedLongLong:unsigned long long:v::
+
+PyLong_FromString:PyObject*::+1:
+PyLong_FromString:char*:str::
+PyLong_FromString:char**:pend::
+PyLong_FromString:int:base::
+
+PyLong_FromUnicode:PyObject*::+1:
+PyLong_FromUnicode:Py_UNICODE:u::
+PyLong_FromUnicode:int:length::
+PyLong_FromUnicode:int:base::
+
+PyLong_FromUnsignedLong:PyObject*::+1:
+PyLong_FromUnsignedLong:unsignedlong:v::
+
+PyLong_FromVoidPtr:PyObject*::+1:
+PyLong_FromVoidPtr:void*:p::
+
+PyMapping_Check:int:::
+PyMapping_Check:PyObject*:o:0:
+
+PyMapping_DelItem:int:::
+PyMapping_DelItem:PyObject*:o:0:
+PyMapping_DelItem:PyObject*:key:0:
+
+PyMapping_DelItemString:int:::
+PyMapping_DelItemString:PyObject*:o:0:
+PyMapping_DelItemString:char*:key::
+
+PyMapping_GetItemString:PyObject*::+1:
+PyMapping_GetItemString:PyObject*:o:0:
+PyMapping_GetItemString:char*:key::
+
+PyMapping_HasKey:int:::
+PyMapping_HasKey:PyObject*:o:0:
+PyMapping_HasKey:PyObject*:key::
+
+PyMapping_HasKeyString:int:::
+PyMapping_HasKeyString:PyObject*:o:0:
+PyMapping_HasKeyString:char*:key::
+
+PyMapping_Items:PyObject*::+1:
+PyMapping_Items:PyObject*:o:0:
+
+PyMapping_Keys:PyObject*::+1:
+PyMapping_Keys:PyObject*:o:0:
+
+PyMapping_Length:int:::
+PyMapping_Length:PyObject*:o:0:
+
+PyMapping_SetItemString:int:::
+PyMapping_SetItemString:PyObject*:o:0:
+PyMapping_SetItemString:char*:key::
+PyMapping_SetItemString:PyObject*:v:+1:
+
+PyMapping_Values:PyObject*::+1:
+PyMapping_Values:PyObject*:o:0:
+
+PyMarshal_ReadLastObjectFromFile:PyObject*::+1:
+PyMarshal_ReadLastObjectFromFile:FILE*:file::
+
+PyMarshal_ReadObjectFromFile:PyObject*::+1:
+PyMarshal_ReadObjectFromFile:FILE*:file::
+
+PyMarshal_ReadObjectFromString:PyObject*::+1:
+PyMarshal_ReadObjectFromString:char*:string::
+PyMarshal_ReadObjectFromString:int:len::
+
+PyMarshal_WriteObjectToString:PyObject*::+1:
+PyMarshal_WriteObjectToString:PyObject*:value:0:
+
+PyMethod_Class:PyObject*::0:
+PyMethod_Class:PyObject*:im:0:
+
+PyMethod_Function:PyObject*::0:
+PyMethod_Function:PyObject*:im:0:
+
+PyMethod_GET_CLASS:PyObject*::0:
+PyMethod_GET_CLASS:PyObject*:im:0:
+
+PyMethod_GET_FUNCTION:PyObject*::0:
+PyMethod_GET_FUNCTION:PyObject*:im:0:
+
+PyMethod_GET_SELF:PyObject*::0:
+PyMethod_GET_SELF:PyObject*:im:0:
+
+PyMethod_New:PyObject*::+1:
+PyMethod_New:PyObject*:func:0:
+PyMethod_New:PyObject*:self:0:
+PyMethod_New:PyObject*:class:0:
+
+PyMethod_Self:PyObject*::0:
+PyMethod_Self:PyObject*:im:0:
+
+PyModule_GetDict:PyObject*::0:
+PyModule_GetDict::PyObject* module:0:
+
+PyModule_GetFilename:char*:::
+PyModule_GetFilename:PyObject*:module:0:
+
+PyModule_GetName:char*:::
+PyModule_GetName:PyObject*:module:0:
+
+PyModule_New:PyObject*::+1:
+PyModule_New::char* name::
+
+PyNumber_Absolute:PyObject*::+1:
+PyNumber_Absolute:PyObject*:o:0:
+
+PyNumber_Add:PyObject*::+1:
+PyNumber_Add:PyObject*:o1:0:
+PyNumber_Add:PyObject*:o2:0:
+
+PyNumber_And:PyObject*::+1:
+PyNumber_And:PyObject*:o1:0:
+PyNumber_And:PyObject*:o2:0:
+
+PyNumber_Check:PyObject*:o:0:
+PyNumber_Check:int:::
+
+PyNumber_Coerce:int:::
+PyNumber_Coerce:PyObject**:p1:+1:
+PyNumber_Coerce:PyObject**:p2:+1:
+
+PyNumber_Divide:PyObject*::+1:
+PyNumber_Divide:PyObject*:o1:0:
+PyNumber_Divide:PyObject*:o2:0:
+
+PyNumber_Divmod:PyObject*::+1:
+PyNumber_Divmod:PyObject*:o1:0:
+PyNumber_Divmod:PyObject*:o2:0:
+
+PyNumber_Float:PyObject*::+1:
+PyNumber_Float:PyObject*:o:0:
+
+PyNumber_FloorDivide:PyObject*::+1:
+PyNumber_FloorDivide:PyObject*:v:0:
+PyNumber_FloorDivide:PyObject*:w:0:
+
+PyNumber_InPlaceAdd:PyObject*::+1:
+PyNumber_InPlaceAdd:PyObject*:v:0:
+PyNumber_InPlaceAdd:PyObject*:w:0:
+
+PyNumber_InPlaceAnd:PyObject*::+1:
+PyNumber_InPlaceAnd:PyObject*:v:0:
+PyNumber_InPlaceAnd:PyObject*:w:0:
+
+PyNumber_InPlaceDivide:PyObject*::+1:
+PyNumber_InPlaceDivide:PyObject*:v:0:
+PyNumber_InPlaceDivide:PyObject*:w:0:
+
+PyNumber_InPlaceFloorDivide:PyObject*::+1:
+PyNumber_InPlaceFloorDivide:PyObject*:v:0:
+PyNumber_InPlaceFloorDivide:PyObject*:w:0:
+
+PyNumber_InPlaceLshift:PyObject*::+1:
+PyNumber_InPlaceLshift:PyObject*:v:0:
+PyNumber_InPlaceLshift:PyObject*:w:0:
+
+PyNumber_InPlaceMultiply:PyObject*::+1:
+PyNumber_InPlaceMultiply:PyObject*:v:0:
+PyNumber_InPlaceMultiply:PyObject*:w:0:
+
+PyNumber_InPlaceOr:PyObject*::+1:
+PyNumber_InPlaceOr:PyObject*:v:0:
+PyNumber_InPlaceOr:PyObject*:w:0:
+
+PyNumber_InPlacePower:PyObject*::+1:
+PyNumber_InPlacePower:PyObject*:v:0:
+PyNumber_InPlacePower:PyObject*:w:0:
+PyNumber_InPlacePower:PyObject*:z:0:
+
+PyNumber_InPlaceRemainder:PyObject*::+1:
+PyNumber_InPlaceRemainder:PyObject*:v:0:
+PyNumber_InPlaceRemainder:PyObject*:w:0:
+
+PyNumber_InPlaceRshift:PyObject*::+1:
+PyNumber_InPlaceRshift:PyObject*:v:0:
+PyNumber_InPlaceRshift:PyObject*:w:0:
+
+PyNumber_InPlaceSubtract:PyObject*::+1:
+PyNumber_InPlaceSubtract:PyObject*:v:0:
+PyNumber_InPlaceSubtract:PyObject*:w:0:
+
+PyNumber_InPlaceTrueDivide:PyObject*::+1:
+PyNumber_InPlaceTrueDivide:PyObject*:v:0:
+PyNumber_InPlaceTrueDivide:PyObject*:w:0:
+
+PyNumber_InPlaceXor:PyObject*::+1:
+PyNumber_InPlaceXor:PyObject*:v:0:
+PyNumber_InPlaceXor:PyObject*:w:0:
+
+PyNumber_Int:PyObject*::+1:
+PyNumber_Int:PyObject*:o:0:
+
+PyNumber_Invert:PyObject*::+1:
+PyNumber_Invert:PyObject*:o:0:
+
+PyNumber_Long:PyObject*::+1:
+PyNumber_Long:PyObject*:o:0:
+
+PyNumber_Lshift:PyObject*::+1:
+PyNumber_Lshift:PyObject*:o1:0:
+PyNumber_Lshift:PyObject*:o2:0:
+
+PyNumber_Multiply:PyObject*::+1:
+PyNumber_Multiply:PyObject*:o1:0:
+PyNumber_Multiply:PyObject*:o2:0:
+
+PyNumber_Negative:PyObject*::+1:
+PyNumber_Negative:PyObject*:o:0:
+
+PyNumber_Or:PyObject*::+1:
+PyNumber_Or:PyObject*:o1:0:
+PyNumber_Or:PyObject*:o2:0:
+
+PyNumber_Positive:PyObject*::+1:
+PyNumber_Positive:PyObject*:o:0:
+
+PyNumber_Power:PyObject*::+1:
+PyNumber_Power:PyObject*:o1:0:
+PyNumber_Power:PyObject*:o2:0:
+PyNumber_Power:PyObject*:o3:0:
+
+PyNumber_Remainder:PyObject*::+1:
+PyNumber_Remainder:PyObject*:o1:0:
+PyNumber_Remainder:PyObject*:o2:0:
+
+PyNumber_Rshift:PyObject*::+1:
+PyNumber_Rshift:PyObject*:o1:0:
+PyNumber_Rshift:PyObject*:o2:0:
+
+PyNumber_Subtract:PyObject*::+1:
+PyNumber_Subtract:PyObject*:o1:0:
+PyNumber_Subtract:PyObject*:o2:0:
+
+PyNumber_TrueDivide:PyObject*::+1:
+PyNumber_TrueDivide:PyObject*:v:0:
+PyNumber_TrueDivide:PyObject*:w:0:
+
+PyNumber_Xor:PyObject*::+1:
+PyNumber_Xor:PyObject*:o1:0:
+PyNumber_Xor:PyObject*:o2:0:
+
+PyOS_GetLastModificationTime:long:::
+PyOS_GetLastModificationTime:char*:filename::
+
+PyObject_AsFileDescriptor:int::: 
+PyObject_AsFileDescriptor:PyObject*:o:0:
+
+PyObject_Call:PyObject*::+1:
+PyObject_Call:PyObject*:callable_object:0:
+PyObject_Call:PyObject*:args:0:
+PyObject_Call:PyObject*:kw:0:
+
+PyObject_CallFunction:PyObject*::+1:
+PyObject_CallFunction:PyObject*:callable_object:0:
+PyObject_CallFunction:char*:format::
+PyObject_CallFunction::...::
+
+PyObject_CallFunctionObjArgs:PyObject*::+1:
+PyObject_CallFunctionObjArgs:PyObject*:callable:0:
+PyObject_CallFunctionObjArgs::...::
+
+PyObject_CallMethod:PyObject*::+1:
+PyObject_CallMethod:PyObject*:o:0:
+PyObject_CallMethod:char*:m::
+PyObject_CallMethod:char*:format::
+PyObject_CallMethod::...::
+
+PyObject_CallMethodObjArgs:PyObject*::+1:
+PyObject_CallMethodObjArgs:PyObject*:o:0:
+PyObject_CallMethodObjArgs:char*:name::
+PyObject_CallMethodObjArgs::...::
+
+PyObject_CallObject:PyObject*::+1:
+PyObject_CallObject:PyObject*:callable_object:0:
+PyObject_CallObject:PyObject*:args:0:
+
+PyObject_Cmp:int:::
+PyObject_Cmp:PyObject*:o1:0:
+PyObject_Cmp:PyObject*:o2:0:
+PyObject_Cmp:int*:result::
+
+PyObject_Compare:int:::
+PyObject_Compare:PyObject*:o1:0:
+PyObject_Compare:PyObject*:o2:0:
+
+PyObject_DelAttr:int:::
+PyObject_DelAttr:PyObject*:o:0:
+PyObject_DelAttr:PyObject*:attr_name:0:
+
+PyObject_DelAttrString:int:::
+PyObject_DelAttrString:PyObject*:o:0:
+PyObject_DelAttrString:char*:attr_name::
+
+PyObject_DelItem:int:::
+PyObject_DelItem:PyObject*:o:0:
+PyObject_DelItem:PyObject*:key:0:
+
+PyObject_Dir:PyObject*::+1:
+PyObject_Dir:PyObject*:o:0:
+
+PyObject_GetAttr:PyObject*::+1:
+PyObject_GetAttr:PyObject*:o:0:
+PyObject_GetAttr:PyObject*:attr_name:0:
+
+PyObject_GetAttrString:PyObject*::+1:
+PyObject_GetAttrString:PyObject*:o:0:
+PyObject_GetAttrString:char*:attr_name::
+
+PyObject_GetItem:PyObject*::+1:
+PyObject_GetItem:PyObject*:o:0:
+PyObject_GetItem:PyObject*:key:0:
+
+PyObject_GetIter:PyObject*::+1:
+PyObject_GetIter:PyObject*:o:0:
+
+PyObject_HasAttr:int:::
+PyObject_HasAttr:PyObject*:o:0:
+PyObject_HasAttr:PyObject*:attr_name:0:
+
+PyObject_HasAttrString:int:::
+PyObject_HasAttrString:PyObject*:o:0:
+PyObject_HasAttrString:char*:attr_name:0:
+
+PyObject_Hash:int:::
+PyObject_Hash:PyObject*:o:0:
+
+PyObject_IsTrue:int:::
+PyObject_IsTrue:PyObject*:o:0:
+
+PyObject_Init:PyObject*::0:
+PyObject_Init:PyObject*:op:0:
+
+PyObject_InitVar:PyVarObject*::0:
+PyObject_InitVar:PyVarObject*:op:0:
+
+PyObject_Length:int:::
+PyObject_Length:PyObject*:o:0:
+
+PyObject_NEW:PyObject*::+1:
+
+PyObject_New:PyObject*::+1:
+
+PyObject_NEW_VAR:PyObject*::+1:
+
+PyObject_NewVar:PyObject*::+1:
+
+PyObject_Print:int:::
+PyObject_Print:PyObject*:o:0:
+PyObject_Print:FILE*:fp::
+PyObject_Print:int:flags::
+
+PyObject_Repr:PyObject*::+1:
+PyObject_Repr:PyObject*:o:0:
+
+PyObject_RichCompare:PyObject*::+1:
+PyObject_RichCompare:PyObject*:o1:0:
+PyObject_RichCompare:PyObject*:o2:0:
+PyObject_RichCompare:int:opid::
+
+PyObject_RichCompareBool:int:::
+PyObject_RichCompareBool:PyObject*:o1:0:
+PyObject_RichCompareBool:PyObject*:o2:0:
+PyObject_RichCompareBool:int:opid::
+
+PyObject_SetAttr:int:::
+PyObject_SetAttr:PyObject*:o:0:
+PyObject_SetAttr:PyObject*:attr_name:0:
+PyObject_SetAttr:PyObject*:v:+1:
+
+PyObject_SetAttrString:int:::
+PyObject_SetAttrString:PyObject*:o:0:
+PyObject_SetAttrString:char*:attr_name::
+PyObject_SetAttrString:PyObject*:v:+1:
+
+PyObject_SetItem:int:::
+PyObject_SetItem:PyObject*:o:0:
+PyObject_SetItem:PyObject*:key:0:
+PyObject_SetItem:PyObject*:v:+1:
+
+PyObject_Str:PyObject*::+1:
+PyObject_Str:PyObject*:o:0:
+
+PyObject_Type:PyObject*::+1:
+PyObject_Type:PyObject*:o:0:
+
+PyObject_Unicode:PyObject*::+1:
+PyObject_Unicode:PyObject*:o:0:
+
+PyParser_SimpleParseFile:struct _node*:::
+PyParser_SimpleParseFile:FILE*:fp::
+PyParser_SimpleParseFile:char*:filename::
+PyParser_SimpleParseFile:int:start::
+
+PyParser_SimpleParseString:struct _node*:::
+PyParser_SimpleParseString:char*:str::
+PyParser_SimpleParseString:int:start::
+
+PyRun_AnyFile:int:::
+PyRun_AnyFile:FILE*:fp::
+PyRun_AnyFile:char*:filename::
+
+PyRun_File:PyObject*::+1:??? -- same as eval_code2()
+PyRun_File:FILE*:fp::
+PyRun_File:char*:filename::
+PyRun_File:int:start::
+PyRun_File:PyObject*:globals:0:
+PyRun_File:PyObject*:locals:0:
+
+PyRun_FileEx:PyObject*::+1:??? -- same as eval_code2()
+PyRun_FileEx:FILE*:fp::
+PyRun_FileEx:char*:filename::
+PyRun_FileEx:int:start::
+PyRun_FileEx:PyObject*:globals:0:
+PyRun_FileEx:PyObject*:locals:0:
+PyRun_FileEx:int:closeit::
+
+PyRun_FileFlags:PyObject*::+1:??? -- same as eval_code2()
+PyRun_FileFlags:FILE*:fp::
+PyRun_FileFlags:char*:filename::
+PyRun_FileFlags:int:start::
+PyRun_FileFlags:PyObject*:globals:0:
+PyRun_FileFlags:PyObject*:locals:0:
+PyRun_FileFlags:PyCompilerFlags*:flags::
+
+PyRun_FileExFlags:PyObject*::+1:??? -- same as eval_code2()
+PyRun_FileExFlags:FILE*:fp::
+PyRun_FileExFlags:char*:filename::
+PyRun_FileExFlags:int:start::
+PyRun_FileExFlags:PyObject*:globals:0:
+PyRun_FileExFlags:PyObject*:locals:0:
+PyRun_FileExFlags:int:closeit::
+PyRun_FileExFlags:PyCompilerFlags*:flags::
+
+PyRun_InteractiveLoop:int:::
+PyRun_InteractiveLoop:FILE*:fp::
+PyRun_InteractiveLoop:char*:filename::
+
+PyRun_InteractiveOne:int:::
+PyRun_InteractiveOne:FILE*:fp::
+PyRun_InteractiveOne:char*:filename::
+
+PyRun_SimpleFile:int:::
+PyRun_SimpleFile:FILE*:fp::
+PyRun_SimpleFile:char*:filename::
+
+PyRun_SimpleString:int:::
+PyRun_SimpleString:char*:command::
+
+PyRun_String:PyObject*::+1:??? -- same as eval_code2()
+PyRun_String:char*:str::
+PyRun_String:int:start::
+PyRun_String:PyObject*:globals:0:
+PyRun_String:PyObject*:locals:0:
+
+PyRun_StringFlags:PyObject*::+1:??? -- same as eval_code2()
+PyRun_StringFlags:char*:str::
+PyRun_StringFlags:int:start::
+PyRun_StringFlags:PyObject*:globals:0:
+PyRun_StringFlags:PyObject*:locals:0:
+PyRun_StringFlags:PyCompilerFlags*:flags::
+
+PySeqIter_New:PyObject*::+1:
+PySeqIter_New:PyObject*:seq::
+
+PySequence_Check:int:::
+PySequence_Check:PyObject*:o:0:
+
+PySequence_Concat:PyObject*::+1:
+PySequence_Concat:PyObject*:o1:0:
+PySequence_Concat:PyObject*:o2:0:
+
+PySequence_Count:int:::
+PySequence_Count:PyObject*:o:0:
+PySequence_Count:PyObject*:value:0:
+
+PySequence_DelItem:int:::
+PySequence_DelItem:PyObject*:o:0:
+PySequence_DelItem:int:i::
+
+PySequence_DelSlice:int:::
+PySequence_DelSlice:PyObject*:o:0:
+PySequence_DelSlice:int:i1::
+PySequence_DelSlice:int:i2::
+
+PySequence_Fast:PyObject*::+1:
+PySequence_Fast:PyObject*:v:0:
+PySequence_Fast:const char*:m::
+
+PySequence_Fast_GET_ITEM:PyObject*::0:
+PySequence_Fast_GET_ITEM:PyObject*:o:0:
+PySequence_Fast_GET_ITEM:int:i::
+
+PySequence_GetItem:PyObject*::+1:
+PySequence_GetItem:PyObject*:o:0:
+PySequence_GetItem:int:i::
+
+PySequence_GetSlice:PyObject*::+1:
+PySequence_GetSlice:PyObject*:o:0:
+PySequence_GetSlice:int:i1::
+PySequence_GetSlice:int:i2::
+
+PySequence_In:int:::
+PySequence_In:PyObject*:o:0:
+PySequence_In:PyObject*:value:0:
+
+PySequence_Index:int:::
+PySequence_Index:PyObject*:o:0:
+PySequence_Index:PyObject*:value:0:
+
+PySequence_InPlaceConcat:PyObject*::+1:
+PySequence_InPlaceConcat:PyObject*:s:0:
+PySequence_InPlaceConcat:PyObject*:o:0:
+
+PySequence_InPlaceRepeat:PyObject*::+1:
+PySequence_InPlaceRepeat:PyObject*:s:0:
+PySequence_InPlaceRepeat:PyObject*:o:0:
+
+PySequence_ITEM:PyObject*::+1:
+PySequence_ITEM:PyObject*:o:0:
+PySequence_ITEM:int:i::
+
+PySequence_Repeat:PyObject*::+1:
+PySequence_Repeat:PyObject*:o:0:
+PySequence_Repeat:int:count::
+
+PySequence_SetItem:int:::
+PySequence_SetItem:PyObject*:o:0:
+PySequence_SetItem:int:i::
+PySequence_SetItem:PyObject*:v:+1:
+
+PySequence_SetSlice:int:::
+PySequence_SetSlice:PyObject*:o:0:
+PySequence_SetSlice:int:i1::
+PySequence_SetSlice:int:i2::
+PySequence_SetSlice:PyObject*:v:+1:
+
+PySequence_List:PyObject*::+1:
+PySequence_List:PyObject*:o:0:
+
+PySequence_Tuple:PyObject*::+1:
+PySequence_Tuple:PyObject*:o:0:
+
+PySet_Append:int:::
+PySet_Append:PyObject*:set:0:
+PySet_Append:PyObject*:key:+1:
+
+PySet_Contains:int:::
+PySet_Contains:PyObject*:anyset:0:
+PySet_Contains:PyObject*:key:0:
+
+PySet_Discard:int:::
+PySet_Discard:PyObject*:set:0:
+PySet_Discard:PyObject*:key:-1:no effect if key not found
+
+PySet_New:PyObject*::+1:
+PySet_New:PyObject*:iterable:0:
+
+PySet_Pop:PyObject*::+1:or returns NULL and raises KeyError if set is empty
+PySet_Pop:PyObject*:set:0:
+
+PySet_Size:int:::
+PySet_Size:PyObject*:anyset:0:
+
+PySlice_Check:int:::
+PySlice_Check:PyObject*:ob:0:
+
+PySlice_New:PyObject*::+1:
+PySlice_New:PyObject*:start:0:
+PySlice_New:PyObject*:stop:0:
+PySlice_New:PyObject*:step:0:
+
+PyString_AS_STRING:char*:::
+PyString_AS_STRING:PyObject*:string:0:
+
+PyString_AsDecodedObject:PyObject*::+1:
+PyString_AsDecodedObject:PyObject*:str:0:
+PyString_AsDecodedObject:const char*:encoding::
+PyString_AsDecodedObject:const char*:errors::
+
+PyString_AsEncodedObject:PyObject*::+1:
+PyString_AsEncodedObject:PyObject*:str:0:
+PyString_AsEncodedObject:const char*:encoding::
+PyString_AsEncodedObject:const char*:errors::
+
+PyString_AsString:char*:::
+PyString_AsString:PyObject*:string:0:
+
+PyString_AsStringAndSize:int:::
+PyString_AsStringAndSize:PyObject*:obj:0:
+PyString_AsStringAndSize:char**:buffer::
+PyString_AsStringAndSize:int*:length::
+
+PyString_Check:int:::
+PyString_Check:PyObject*:o:0:
+
+PyString_Concat:void:::
+PyString_Concat:PyObject**:string:0:??? -- replaces w/ new string or NULL
+PyString_Concat:PyObject*:newpart:0:
+
+PyString_ConcatAndDel:void:::
+PyString_ConcatAndDel:PyObject**:string:0:??? -- replaces w/ new string or NULL
+PyString_ConcatAndDel:PyObject*:newpart:-1:
+
+PyString_Format:PyObject*::+1:
+PyString_Format:PyObject*:format:0:
+PyString_Format:PyObject*:args:0:
+
+PyString_FromString:PyObject*::+1:
+PyString_FromString:const char*:v::
+
+PyString_FromStringAndSize:PyObject*::+1:
+PyString_FromStringAndSize:const char*:v::
+PyString_FromStringAndSize:int:len::
+
+PyString_FromFormat:PyObject*::+1:
+PyString_FromFormat:const char*:format::
+PyString_FromFormat::...::
+
+PyString_FromFormatV:PyObject*::+1:
+PyString_FromFormatV:const char*:format::
+PyString_FromFormatV:va_list:vargs::
+
+PyString_GET_SIZE:int:::
+PyString_GET_SIZE:PyObject*:string:0:
+
+PyString_InternFromString:PyObject*::+1:
+PyString_InternFromString:const char*:v::
+
+PyString_InternInPlace:void:::
+PyString_InternInPlace:PyObject**:string:+1:???
+
+PyString_Size:int:::
+PyString_Size:PyObject*:string:0:
+
+PyString_Decode:PyObject*::+1:
+PyString_Decode:const char*:s::
+PyString_Decode:int:size::
+PyString_Decode:const char*:encoding::
+PyString_Decode:const char*:errors::
+
+PyString_Encode:PyObject*::+1:
+PyString_Encode:const char*:s::
+PyString_Encode:int:size::
+PyString_Encode:const char*:encoding::
+PyString_Encode:const char*:errors::
+
+PyString_AsEncodedString:PyObject*::+1:
+PyString_AsEncodedString:PyObject*:str::
+PyString_AsEncodedString:const char*:encoding::
+PyString_AsEncodedString:const char*:errors::
+
+PySys_SetArgv:int:::
+PySys_SetArgv:int:argc::
+PySys_SetArgv:char**:argv::
+
+PyThreadState_Clear:void:::
+PyThreadState_Clear:PyThreadState*:tstate::
+
+PyThreadState_Delete:void:::
+PyThreadState_Delete:PyThreadState*:tstate::
+
+PyThreadState_Get:PyThreadState*:::
+
+PyThreadState_GetDict:PyObject*::0:
+
+PyThreadState_New:PyThreadState*:::
+PyThreadState_New:PyInterpreterState*:interp::
+
+PyThreadState_Swap:PyThreadState*:::
+PyThreadState_Swap:PyThreadState*:tstate::
+
+PyTime_FromTime:PyObject*::+1:
+PyTime_FromTime:int:hour::
+PyTime_FromTime:int:minute::
+PyTime_FromTime:int:second::
+PyTime_FromTime:int:usecond::
+
+PyTuple_Check:int:::
+PyTuple_Check:PyObject*:p:0:
+
+PyTuple_GET_ITEM:PyObject*::0:
+PyTuple_GET_ITEM:PyTupleObject*:p:0:
+PyTuple_GET_ITEM:int:pos::
+
+PyTuple_GetItem:PyObject*::0:
+PyTuple_GetItem:PyTupleObject*:p:0:
+PyTuple_GetItem:int:pos::
+
+PyTuple_GetSlice:PyObject*::+1:
+PyTuple_GetSlice:PyTupleObject*:p:0:
+PyTuple_GetSlice:int:low::
+PyTuple_GetSlice:int:high::
+
+PyTuple_New:PyObject*::+1:
+PyTuple_New:int:len::
+
+PyTuple_Pack:PyObject*::+1:
+PyTuple_Pack:int:len::
+PyTuple_Pack:PyObject*:...:0:
+
+PyTuple_SET_ITEM:void:::
+PyTuple_SET_ITEM:PyTupleObject*:p:0:
+PyTuple_SET_ITEM:int:pos::
+PyTuple_SET_ITEM:PyObject*:o:0:
+
+PyTuple_SetItem:int:::
+PyTuple_SetItem:PyTupleObject*:p:0:
+PyTuple_SetItem:int:pos::
+PyTuple_SetItem:PyObject*:o:0:
+
+PyTuple_Size:int:::
+PyTuple_Size:PyTupleObject*:p:0:
+
+PyType_GenericAlloc:PyObject*::+1:
+PyType_GenericAlloc:PyObject*:type:0:
+PyType_GenericAlloc:int:nitems:0:
+
+PyType_GenericNew:PyObject*::+1:
+PyType_GenericNew:PyObject*:type:0:
+PyType_GenericNew:PyObject*:args:0:
+PyType_GenericNew:PyObject*:kwds:0:
+
+PyUnicode_Check:int:::
+PyUnicode_Check:PyObject*:o:0:
+
+PyUnicode_GET_SIZE:int:::
+PyUnicode_GET_SIZE:PyObject*:o:0:
+
+PyUnicode_GET_DATA_SIZE:int:::
+PyUnicode_GET_DATA_SIZE:PyObject*:o:0:
+
+PyUnicode_AS_UNICODE:Py_UNICODE*:::
+PyUnicode_AS_UNICODE:PyObject*:o:0:
+
+PyUnicode_AS_DATA:const char*:::
+PyUnicode_AS_DATA:PyObject*:o:0:
+
+Py_UNICODE_ISSPACE:int:::
+Py_UNICODE_ISSPACE:Py_UNICODE:ch::
+
+Py_UNICODE_ISLOWER:int:::
+Py_UNICODE_ISLOWER:Py_UNICODE:ch::
+
+Py_UNICODE_ISUPPER:int:::
+Py_UNICODE_ISUPPER:Py_UNICODE:ch::
+
+Py_UNICODE_ISTITLE:int:::
+Py_UNICODE_ISTITLE:Py_UNICODE:ch::
+
+Py_UNICODE_ISLINEBREAK:int:::
+Py_UNICODE_ISLINEBREAK:Py_UNICODE:ch::
+
+Py_UNICODE_ISDECIMAL:int:::
+Py_UNICODE_ISDECIMAL:Py_UNICODE:ch::
+
+Py_UNICODE_ISDIGIT:int:::
+Py_UNICODE_ISDIGIT:Py_UNICODE:ch::
+
+Py_UNICODE_ISNUMERIC:int:::
+Py_UNICODE_ISNUMERIC:Py_UNICODE:ch::
+
+Py_UNICODE_TOLOWER:Py_UNICODE:::
+Py_UNICODE_TOLOWER:Py_UNICODE:ch::
+
+Py_UNICODE_TOUPPER:Py_UNICODE:::
+Py_UNICODE_TOUPPER:Py_UNICODE:ch::
+
+Py_UNICODE_TOTITLE:Py_UNICODE:::
+Py_UNICODE_TOTITLE:Py_UNICODE:ch::
+
+Py_UNICODE_TODECIMAL:int:::
+Py_UNICODE_TODECIMAL:Py_UNICODE:ch::
+
+Py_UNICODE_TODIGIT:int:::
+Py_UNICODE_TODIGIT:Py_UNICODE:ch::
+
+Py_UNICODE_TONUMERIC:double:::
+Py_UNICODE_TONUMERIC:Py_UNICODE:ch::
+
+PyUnicode_FromUnicode:PyObject*::+1:
+PyUnicode_FromUnicode:const Py_UNICODE*:u::
+PyUnicode_FromUnicode:int:size::
+
+PyUnicode_AsUnicode:Py_UNICODE*:::
+PyUnicode_AsUnicode:PyObject :*unicode:0:
+
+PyUnicode_GetSize:int:::
+PyUnicode_GetSize:PyObject :*unicode:0:
+
+PyUnicode_FromObject:PyObject*::+1:
+PyUnicode_FromObject:PyObject*:*obj:0:
+
+PyUnicode_FromEncodedObject:PyObject*::+1:
+PyUnicode_FromEncodedObject:PyObject*:*obj:0:
+PyUnicode_FromEncodedObject:const char*:encoding::
+PyUnicode_FromEncodedObject:const char*:errors::
+
+PyUnicode_FromWideChar:PyObject*::+1:
+PyUnicode_FromWideChar:const wchar_t*:w::
+PyUnicode_FromWideChar:int:size::
+
+PyUnicode_AsWideChar:int:::
+PyUnicode_AsWideChar:PyObject*:*unicode:0:
+PyUnicode_AsWideChar:wchar_t*:w::
+PyUnicode_AsWideChar:int:size::
+
+PyUnicode_Decode:PyObject*::+1:
+PyUnicode_Decode:const char*:s::
+PyUnicode_Decode:int:size::
+PyUnicode_Decode:const char*:encoding::
+PyUnicode_Decode:const char*:errors::
+
+PyUnicode_DecodeUTF16Stateful:PyObject*::+1:
+PyUnicode_DecodeUTF16Stateful:const char*:s::
+PyUnicode_DecodeUTF16Stateful:int:size::
+PyUnicode_DecodeUTF16Stateful:const char*:errors::
+PyUnicode_DecodeUTF16Stateful:int*:byteorder::
+PyUnicode_DecodeUTF16Stateful:int*:consumed::
+
+PyUnicode_DecodeUTF8Stateful:PyObject*::+1:
+PyUnicode_DecodeUTF8Stateful:const char*:s::
+PyUnicode_DecodeUTF8Stateful:int:size::
+PyUnicode_DecodeUTF8Stateful:const char*:errors::
+PyUnicode_DecodeUTF8Stateful:int*:consumed::
+
+PyUnicode_Encode:PyObject*::+1:
+PyUnicode_Encode:const Py_UNICODE*:s::
+PyUnicode_Encode:int:size::
+PyUnicode_Encode:const char*:encoding::
+PyUnicode_Encode:const char*:errors::
+
+PyUnicode_AsEncodedString:PyObject*::+1:
+PyUnicode_AsEncodedString:PyObject*:unicode::
+PyUnicode_AsEncodedString:const char*:encoding::
+PyUnicode_AsEncodedString:const char*:errors::
+
+PyUnicode_DecodeUTF8:PyObject*::+1:
+PyUnicode_DecodeUTF8:const char*:s::
+PyUnicode_DecodeUTF8:int:size::
+PyUnicode_DecodeUTF8:const char*:errors::
+
+PyUnicode_EncodeUTF8:PyObject*::+1:
+PyUnicode_EncodeUTF8:const Py_UNICODE*:s::
+PyUnicode_EncodeUTF8:int:size::
+PyUnicode_EncodeUTF8:const char*:errors::
+
+PyUnicode_AsUTF8String:PyObject*::+1:
+PyUnicode_AsUTF8String:PyObject*:unicode::
+
+PyUnicode_DecodeUTF16:PyObject*::+1:
+PyUnicode_DecodeUTF16:const char*:s::
+PyUnicode_DecodeUTF16:int:size::
+PyUnicode_DecodeUTF16:const char*:errors::
+PyUnicode_DecodeUTF16:int*:byteorder::
+
+PyUnicode_EncodeUTF16:PyObject*::+1:
+PyUnicode_EncodeUTF16:const Py_UNICODE*:s::
+PyUnicode_EncodeUTF16:int:size::
+PyUnicode_EncodeUTF16:const char*:errors::
+PyUnicode_EncodeUTF16:int:byteorder::
+
+PyUnicode_AsUTF16String:PyObject*::+1:
+PyUnicode_AsUTF16String:PyObject*:unicode::
+
+PyUnicode_DecodeUnicodeEscape:PyObject*::+1:
+PyUnicode_DecodeUnicodeEscape:const char*:s::
+PyUnicode_DecodeUnicodeEscape:int:size::
+PyUnicode_DecodeUnicodeEscape:const char*:errors::
+
+PyUnicode_EncodeUnicodeEscape:PyObject*::+1:
+PyUnicode_EncodeUnicodeEscape:const Py_UNICODE*:s::
+PyUnicode_EncodeUnicodeEscape:int:size::
+PyUnicode_EncodeUnicodeEscape:const char*:errors::
+
+PyUnicode_AsUnicodeEscapeString:PyObject*::+1:
+PyUnicode_AsUnicodeEscapeString:PyObject*:unicode::
+
+PyUnicode_DecodeRawUnicodeEscape:PyObject*::+1:
+PyUnicode_DecodeRawUnicodeEscape:const char*:s::
+PyUnicode_DecodeRawUnicodeEscape:int:size::
+PyUnicode_DecodeRawUnicodeEscape:const char*:errors::
+
+PyUnicode_EncodeRawUnicodeEscape:PyObject*::+1:
+PyUnicode_EncodeRawUnicodeEscape:const Py_UNICODE*:s::
+PyUnicode_EncodeRawUnicodeEscape:int:size::
+PyUnicode_EncodeRawUnicodeEscape:const char*:errors::
+
+PyUnicode_AsRawUnicodeEscapeString:PyObject*::+1:
+PyUnicode_AsRawUnicodeEscapeString:PyObject*:unicode::
+
+PyUnicode_DecodeLatin1:PyObject*::+1:
+PyUnicode_DecodeLatin1:const char*:s::
+PyUnicode_DecodeLatin1:int:size::
+PyUnicode_DecodeLatin1:const char*:errors::
+
+PyUnicode_EncodeLatin1:PyObject*::+1:
+PyUnicode_EncodeLatin1:const Py_UNICODE*:s::
+PyUnicode_EncodeLatin1:int:size::
+PyUnicode_EncodeLatin1:const char*:errors::
+
+PyUnicode_AsLatin1String:PyObject*::+1:
+PyUnicode_AsLatin1String:PyObject*:unicode::
+
+PyUnicode_DecodeASCII:PyObject*::+1:
+PyUnicode_DecodeASCII:const char*:s::
+PyUnicode_DecodeASCII:int:size::
+PyUnicode_DecodeASCII:const char*:errors::
+
+PyUnicode_EncodeASCII:PyObject*::+1:
+PyUnicode_EncodeASCII:const Py_UNICODE*:s::
+PyUnicode_EncodeASCII:int:size::
+PyUnicode_EncodeASCII:const char*:errors::
+
+PyUnicode_AsASCIIString:PyObject*::+1:
+PyUnicode_AsASCIIString:PyObject*:unicode::
+
+PyUnicode_DecodeCharmap:PyObject*::+1:
+PyUnicode_DecodeCharmap:const char*:s::
+PyUnicode_DecodeCharmap:int:size::
+PyUnicode_DecodeCharmap:PyObject*:mapping:0:
+PyUnicode_DecodeCharmap:const char*:errors::
+
+PyUnicode_EncodeCharmap:PyObject*::+1:
+PyUnicode_EncodeCharmap:const Py_UNICODE*:s::
+PyUnicode_EncodeCharmap:int:size::
+PyUnicode_EncodeCharmap:PyObject*:mapping:0:
+PyUnicode_EncodeCharmap:const char*:errors::
+
+PyUnicode_AsCharmapString:PyObject*::+1:
+PyUnicode_AsCharmapString:PyObject*:unicode:0:
+PyUnicode_AsCharmapString:PyObject*:mapping:0:
+
+PyUnicode_TranslateCharmap:PyObject*::+1:
+PyUnicode_TranslateCharmap:const Py_UNICODE*:s::
+PyUnicode_TranslateCharmap:int:size::
+PyUnicode_TranslateCharmap:PyObject*:table:0:
+PyUnicode_TranslateCharmap:const char*:errors::
+
+PyUnicode_DecodeMBCS:PyObject*::+1:
+PyUnicode_DecodeMBCS:const char*:s::
+PyUnicode_DecodeMBCS:int:size::
+PyUnicode_DecodeMBCS:const char*:errors::
+
+PyUnicode_EncodeMBCS:PyObject*::+1:
+PyUnicode_EncodeMBCS:const Py_UNICODE*:s::
+PyUnicode_EncodeMBCS:int:size::
+PyUnicode_EncodeMBCS:const char*:errors::
+
+PyUnicode_AsMBCSString:PyObject*::+1:
+PyUnicode_AsMBCSString:PyObject*:unicode::
+
+PyUnicode_Concat:PyObject*::+1:
+PyUnicode_Concat:PyObject*:left:0:
+PyUnicode_Concat:PyObject*:right:0:
+
+PyUnicode_Split:PyObject*::+1:
+PyUnicode_Split:PyObject*:left:0:
+PyUnicode_Split:PyObject*:right:0:
+PyUnicode_Split:int:maxsplit::
+
+PyUnicode_Splitlines:PyObject*::+1:
+PyUnicode_Splitlines:PyObject*:s:0:
+PyUnicode_Splitlines:int:maxsplit::
+
+PyUnicode_Translate:PyObject*::+1:
+PyUnicode_Translate:PyObject*:str:0:
+PyUnicode_Translate:PyObject*:table:0:
+PyUnicode_Translate:const char*:errors::
+
+PyUnicode_Join:PyObject*::+1:
+PyUnicode_Join:PyObject*:separator:0:
+PyUnicode_Join:PyObject*:seq:0:
+
+PyUnicode_Tailmatch:PyObject*::+1:
+PyUnicode_Tailmatch:PyObject*:str:0:
+PyUnicode_Tailmatch:PyObject*:substr:0:
+PyUnicode_Tailmatch:int:start::
+PyUnicode_Tailmatch:int:end::
+PyUnicode_Tailmatch:int:direction::
+
+PyUnicode_Find:int:::
+PyUnicode_Find:PyObject*:str:0:
+PyUnicode_Find:PyObject*:substr:0:
+PyUnicode_Find:int:start::
+PyUnicode_Find:int:end::
+PyUnicode_Find:int:direction::
+
+PyUnicode_Count:int:::
+PyUnicode_Count:PyObject*:str:0:
+PyUnicode_Count:PyObject*:substr:0:
+PyUnicode_Count:int:start::
+PyUnicode_Count:int:end::
+
+PyUnicode_Replace:PyObject*::+1:
+PyUnicode_Replace:PyObject*:str:0:
+PyUnicode_Replace:PyObject*:substr:0:
+PyUnicode_Replace:PyObject*:replstr:0:
+PyUnicode_Replace:int:maxcount::
+
+PyUnicode_Compare:int:::
+PyUnicode_Compare:PyObject*:left:0:
+PyUnicode_Compare:PyObject*:right:0:
+
+PyUnicode_Format:PyObject*::+1:
+PyUnicode_Format:PyObject*:format:0:
+PyUnicode_Format:PyObject*:args:0:
+
+PyUnicode_Contains:int:::
+PyUnicode_Contains:PyObject*:container:0:
+PyUnicode_Contains:PyObject*:element:0:
+
+PyWeakref_GET_OBJECT:PyObject*::0:
+PyWeakref_GET_OBJECT:PyObject*:ref:0:
+
+PyWeakref_GetObject:PyObject*::0:
+PyWeakref_GetObject:PyObject*:ref:0:
+
+PyWeakref_NewProxy:PyObject*::+1:
+PyWeakref_NewProxy:PyObject*:ob:0:
+PyWeakref_NewProxy:PyObject*:callback:0:
+
+PyWeakref_NewRef:PyObject*::+1:
+PyWeakref_NewRef:PyObject*:ob:0:
+PyWeakref_NewRef:PyObject*:callback:0:
+
+PyWrapper_New:PyObject*::+1:
+PyWrapper_New:PyObject*:d:0:
+PyWrapper_New:PyObject*:self:0:
+
+Py_AtExit:int:::
+Py_AtExit:void (*)():func::
+
+Py_BuildValue:PyObject*::+1:
+Py_BuildValue:char*:format::
+
+Py_CompileString:PyObject*::+1:
+Py_CompileString:char*:str::
+Py_CompileString:char*:filename::
+Py_CompileString:int:start::
+
+Py_CompileStringFlags:PyObject*::+1:
+Py_CompileStringFlags:char*:str::
+Py_CompileStringFlags:char*:filename::
+Py_CompileStringFlags:int:start::
+Py_CompileStringFlags:PyCompilerFlags*:flags::
+
+Py_DECREF:void:::
+Py_DECREF:PyObject*:o:-1:
+
+Py_EndInterpreter:void:::
+Py_EndInterpreter:PyThreadState*:tstate::
+
+Py_Exit:void:::
+Py_Exit:int:status::
+
+Py_FatalError:void:::
+Py_FatalError:char*:message::
+
+Py_FdIsInteractive:int:::
+Py_FdIsInteractive:FILE*:fp::
+Py_FdIsInteractive:char*:filename::
+
+Py_Finalize:void:::
+
+Py_FindMethod:PyObject*::+1:
+Py_FindMethod:PyMethodDef[]:methods::
+Py_FindMethod:PyObject*:self:+1:
+Py_FindMethod:char*:name::
+
+Py_GetBuildInfoconst:char*:::
+
+Py_GetCompilerconst:char*:::
+
+Py_GetCopyrightconst:char*:::
+
+Py_GetExecPrefix:char*:::
+
+Py_GetPath:char*:::
+
+Py_GetPlatformconst:char*:::
+
+Py_GetPrefix:char*:::
+
+Py_GetProgramFullPath:char*:::
+
+Py_GetProgramName:char*:::
+
+Py_GetVersionconst:char*:::
+
+Py_INCREF:void:::
+Py_INCREF:PyObject*:o:+1:
+
+Py_Initialize:void:::
+
+Py_IsInitialized:int:::
+
+Py_NewInterpreter:PyThreadState*:::
+
+Py_SetProgramName:void:::
+Py_SetProgramName:char*:name::
+
+Py_XDECREF:void:::
+Py_XDECREF:PyObject*:o:-1:if o is not NULL
+
+Py_XINCREF:void:::
+Py_XINCREF:PyObject*:o:+1:if o is not NULL
+
+_PyImport_FindExtension:PyObject*::0:??? see PyImport_AddModule
+_PyImport_FindExtension:char*:::
+_PyImport_FindExtension:char*:::
+
+_PyImport_Fini:void:::
+
+_PyImport_FixupExtension:PyObject*:::???
+_PyImport_FixupExtension:char*:::
+_PyImport_FixupExtension:char*:::
+
+_PyImport_Init:void:::
+
+_PyObject_Del:void:::
+_PyObject_Del:PyObject*:op:0:
+
+_PyObject_New:PyObject*::+1:
+_PyObject_New:PyTypeObject*:type:0:
+
+_PyObject_NewVar:PyObject*::+1:
+_PyObject_NewVar:PyTypeObject*:type:0:
+_PyObject_NewVar:int:size::
+
+_PyString_Resize:int:::
+_PyString_Resize:PyObject**:string:+1:
+_PyString_Resize:int:newsize::
+
+_PyTuple_Resize:int:::
+_PyTuple_Resize:PyTupleObject**:p:+1:
+_PyTuple_Resize:int:new::
+
+_Py_c_diff:Py_complex:::
+_Py_c_diff:Py_complex:left::
+_Py_c_diff:Py_complex:right::
+
+_Py_c_neg:Py_complex:::
+_Py_c_neg:Py_complex:complex::
+
+_Py_c_pow:Py_complex:::
+_Py_c_pow:Py_complex:num::
+_Py_c_pow:Py_complex:exp::
+
+_Py_c_prod:Py_complex:::
+_Py_c_prod:Py_complex:left::
+_Py_c_prod:Py_complex:right::
+
+_Py_c_quot:Py_complex:::
+_Py_c_quot:Py_complex:dividend::
+_Py_c_quot:Py_complex:divisor::
+
+_Py_c_sum:Py_complex:::
+_Py_c_sum:Py_complex:left::
+_Py_c_sum:Py_complex:right::

Added: vendor/Python/current/Doc/api/utilities.tex
===================================================================
--- vendor/Python/current/Doc/api/utilities.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/api/utilities.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1023 @@
+\chapter{Utilities \label{utilities}}
+
+The functions in this chapter perform various utility tasks, ranging
+from helping C code be more portable across platforms, using Python
+modules from C, and parsing function arguments and constructing Python
+values from C values.
+
+
+\section{Operating System Utilities \label{os}}
+
+\begin{cfuncdesc}{int}{Py_FdIsInteractive}{FILE *fp, const char *filename}
+  Return true (nonzero) if the standard I/O file \var{fp} with name
+  \var{filename} is deemed interactive.  This is the case for files
+  for which \samp{isatty(fileno(\var{fp}))} is true.  If the global
+  flag \cdata{Py_InteractiveFlag} is true, this function also returns
+  true if the \var{filename} pointer is \NULL{} or if the name is
+  equal to one of the strings \code{'<stdin>'} or \code{'???'}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{long}{PyOS_GetLastModificationTime}{char *filename}
+  Return the time of last modification of the file \var{filename}.
+  The result is encoded in the same way as the timestamp returned by
+  the standard C library function \cfunction{time()}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{PyOS_AfterFork}{}
+  Function to update some internal state after a process fork; this
+  should be called in the new process if the Python interpreter will
+  continue to be used.  If a new executable is loaded into the new
+  process, this function does not need to be called.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyOS_CheckStack}{}
+  Return true when the interpreter runs out of stack space.  This is a
+  reliable check, but is only available when \constant{USE_STACKCHECK}
+  is defined (currently on Windows using the Microsoft Visual \Cpp{}
+  compiler).  \constant{USE_STACKCHECK} will be
+  defined automatically; you should never change the definition in
+  your own code.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyOS_sighandler_t}{PyOS_getsig}{int i}
+  Return the current signal handler for signal \var{i}.  This is a
+  thin wrapper around either \cfunction{sigaction()} or
+  \cfunction{signal()}.  Do not call those functions directly!
+  \ctype{PyOS_sighandler_t} is a typedef alias for \ctype{void
+  (*)(int)}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyOS_sighandler_t}{PyOS_setsig}{int i, PyOS_sighandler_t h}
+  Set the signal handler for signal \var{i} to be \var{h}; return the
+  old signal handler.  This is a thin wrapper around either
+  \cfunction{sigaction()} or \cfunction{signal()}.  Do not call those
+  functions directly!  \ctype{PyOS_sighandler_t} is a typedef alias
+  for \ctype{void (*)(int)}.
+\end{cfuncdesc}
+
+
+\section{Process Control \label{processControl}}
+
+\begin{cfuncdesc}{void}{Py_FatalError}{const char *message}
+  Print a fatal error message and kill the process.  No cleanup is
+  performed.  This function should only be invoked when a condition is
+  detected that would make it dangerous to continue using the Python
+  interpreter; e.g., when the object administration appears to be
+  corrupted.  On \UNIX, the standard C library function
+  \cfunction{abort()}\ttindex{abort()} is called which will attempt to
+  produce a \file{core} file.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{Py_Exit}{int status}
+  Exit the current process.  This calls
+  \cfunction{Py_Finalize()}\ttindex{Py_Finalize()} and then calls the
+  standard C library function
+  \code{exit(\var{status})}\ttindex{exit()}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{Py_AtExit}{void (*func) ()}
+  Register a cleanup function to be called by
+  \cfunction{Py_Finalize()}\ttindex{Py_Finalize()}.  The cleanup
+  function will be called with no arguments and should return no
+  value.  At most 32 \index{cleanup functions}cleanup functions can be
+  registered.  When the registration is successful,
+  \cfunction{Py_AtExit()} returns \code{0}; on failure, it returns
+  \code{-1}.  The cleanup function registered last is called first.
+  Each cleanup function will be called at most once.  Since Python's
+  internal finalization will have completed before the cleanup
+  function, no Python APIs should be called by \var{func}.
+\end{cfuncdesc}
+
+
+\section{Importing Modules \label{importing}}
+
+\begin{cfuncdesc}{PyObject*}{PyImport_ImportModule}{const char *name}
+  This is a simplified interface to
+  \cfunction{PyImport_ImportModuleEx()} below, leaving the
+  \var{globals} and \var{locals} arguments set to \NULL.  When the
+  \var{name} argument contains a dot (when it specifies a submodule of
+  a package), the \var{fromlist} argument is set to the list
+  \code{['*']} so that the return value is the named module rather
+  than the top-level package containing it as would otherwise be the
+  case.  (Unfortunately, this has an additional side effect when
+  \var{name} in fact specifies a subpackage instead of a submodule:
+  the submodules specified in the package's \code{__all__} variable
+  are \index{package variable!\code{__all__}}
+  \withsubitem{(package variable)}{\ttindex{__all__}}loaded.)  Return
+  a new reference to the imported module, or \NULL{} with an exception
+  set on failure.  Before Python 2.4, the module may still be created in
+  the failure case --- examine \code{sys.modules} to find out.  Starting
+  with Python 2.4, a failing import of a module no longer leaves the
+  module in \code{sys.modules}.
+  \versionchanged[failing imports remove incomplete module objects]{2.4}
+  \withsubitem{(in module sys)}{\ttindex{modules}}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyImport_ImportModuleEx}{char *name,
+                       PyObject *globals, PyObject *locals, PyObject *fromlist}
+  Import a module.  This is best described by referring to the
+  built-in Python function
+  \function{__import__()}\bifuncindex{__import__}, as the standard
+  \function{__import__()} function calls this function directly.
+
+  The return value is a new reference to the imported module or
+  top-level package, or \NULL{} with an exception set on failure (before
+  Python 2.4, the
+  module may still be created in this case).  Like for
+  \function{__import__()}, the return value when a submodule of a
+  package was requested is normally the top-level package, unless a
+  non-empty \var{fromlist} was given.
+  \versionchanged[failing imports remove incomplete module objects]{2.4}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyImport_Import}{PyObject *name}
+  This is a higher-level interface that calls the current ``import
+  hook function''.  It invokes the \function{__import__()} function
+  from the \code{__builtins__} of the current globals.  This means
+  that the import is done using whatever import hooks are installed in
+  the current environment, e.g. by \module{rexec}\refstmodindex{rexec}
+  or \module{ihooks}\refstmodindex{ihooks}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyImport_ReloadModule}{PyObject *m}
+  Reload a module.  This is best described by referring to the
+  built-in Python function \function{reload()}\bifuncindex{reload}, as
+  the standard \function{reload()} function calls this function
+  directly.  Return a new reference to the reloaded module, or \NULL{}
+  with an exception set on failure (the module still exists in this
+  case).
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyImport_AddModule}{const char *name}
+  Return the module object corresponding to a module name.  The
+  \var{name} argument may be of the form \code{package.module}.
+  First check the modules dictionary if there's one there, and if not,
+  create a new one and insert it in the modules dictionary.
+  Return \NULL{} with an exception set on failure.
+  \note{This function does not load or import the module; if the
+  module wasn't already loaded, you will get an empty module object.
+  Use \cfunction{PyImport_ImportModule()} or one of its variants to
+  import a module.  Package structures implied by a dotted name for
+  \var{name} are not created if not already present.}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyImport_ExecCodeModule}{char *name, PyObject *co}
+  Given a module name (possibly of the form \code{package.module}) and
+  a code object read from a Python bytecode file or obtained from the
+  built-in function \function{compile()}\bifuncindex{compile}, load
+  the module.  Return a new reference to the module object, or \NULL{}
+  with an exception set if an error occurred.  Before Python 2.4, the module
+  could still be created in error cases.  Starting with Python 2.4,
+  \var{name} is removed from \code{sys.modules} in error cases, and even
+  if \var{name} was already in \code{sys.modules} on entry to
+  \cfunction{PyImport_ExecCodeModule()}.  Leaving incompletely initialized
+  modules in \code{sys.modules} is dangerous, as imports of such modules
+  have no way to know that the module object is an unknown (and probably
+  damaged with respect to the module author's intents) state.
+
+  This function will reload the module if it was already imported.  See
+  \cfunction{PyImport_ReloadModule()} for the intended way to reload a
+  module.
+
+  If \var{name} points to a dotted name of the
+  form \code{package.module}, any package structures not already
+  created will still not be created.
+
+  \versionchanged[\var{name} is removed from \code{sys.modules} in error cases]{2.4}
+
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{long}{PyImport_GetMagicNumber}{}
+  Return the magic number for Python bytecode files
+  (a.k.a. \file{.pyc} and \file{.pyo} files).  The magic number should
+  be present in the first four bytes of the bytecode file, in
+  little-endian byte order.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyImport_GetModuleDict}{}
+  Return the dictionary used for the module administration
+  (a.k.a.\ \code{sys.modules}).  Note that this is a per-interpreter
+  variable.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{_PyImport_Init}{}
+  Initialize the import mechanism.  For internal use only.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{PyImport_Cleanup}{}
+  Empty the module table.  For internal use only.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{_PyImport_Fini}{}
+  Finalize the import mechanism.  For internal use only.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{_PyImport_FindExtension}{char *, char *}
+  For internal use only.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{_PyImport_FixupExtension}{char *, char *}
+  For internal use only.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyImport_ImportFrozenModule}{char *name}
+  Load a frozen module named \var{name}.  Return \code{1} for success,
+  \code{0} if the module is not found, and \code{-1} with an exception
+  set if the initialization failed.  To access the imported module on
+  a successful load, use \cfunction{PyImport_ImportModule()}.  (Note
+  the misnomer --- this function would reload the module if it was
+  already imported.)
+\end{cfuncdesc}
+
+\begin{ctypedesc}[_frozen]{struct _frozen}
+  This is the structure type definition for frozen module descriptors,
+  as generated by the \program{freeze}\index{freeze utility} utility
+  (see \file{Tools/freeze/} in the Python source distribution).  Its
+  definition, found in \file{Include/import.h}, is:
+
+\begin{verbatim}
+struct _frozen {
+    char *name;
+    unsigned char *code;
+    int size;
+};
+\end{verbatim}
+\end{ctypedesc}
+
+\begin{cvardesc}{struct _frozen*}{PyImport_FrozenModules}
+  This pointer is initialized to point to an array of \ctype{struct
+  _frozen} records, terminated by one whose members are all \NULL{} or
+  zero.  When a frozen module is imported, it is searched in this
+  table.  Third-party code could play tricks with this to provide a
+  dynamically created collection of frozen modules.
+\end{cvardesc}
+
+\begin{cfuncdesc}{int}{PyImport_AppendInittab}{char *name,
+                                               void (*initfunc)(void)}
+  Add a single module to the existing table of built-in modules.  This
+  is a convenience wrapper around
+  \cfunction{PyImport_ExtendInittab()}, returning \code{-1} if the
+  table could not be extended.  The new module can be imported by the
+  name \var{name}, and uses the function \var{initfunc} as the
+  initialization function called on the first attempted import.  This
+  should be called before \cfunction{Py_Initialize()}.
+\end{cfuncdesc}
+
+\begin{ctypedesc}[_inittab]{struct _inittab}
+  Structure describing a single entry in the list of built-in
+  modules.  Each of these structures gives the name and initialization
+  function for a module built into the interpreter.  Programs which
+  embed Python may use an array of these structures in conjunction
+  with \cfunction{PyImport_ExtendInittab()} to provide additional
+  built-in modules.  The structure is defined in
+  \file{Include/import.h} as:
+
+\begin{verbatim}
+struct _inittab {
+    char *name;
+    void (*initfunc)(void);
+};
+\end{verbatim}
+\end{ctypedesc}
+
+\begin{cfuncdesc}{int}{PyImport_ExtendInittab}{struct _inittab *newtab}
+  Add a collection of modules to the table of built-in modules.  The
+  \var{newtab} array must end with a sentinel entry which contains
+  \NULL{} for the \member{name} field; failure to provide the sentinel
+  value can result in a memory fault.  Returns \code{0} on success or
+  \code{-1} if insufficient memory could be allocated to extend the
+  internal table.  In the event of failure, no modules are added to
+  the internal table.  This should be called before
+  \cfunction{Py_Initialize()}.
+\end{cfuncdesc}
+
+
+\section{Data marshalling support \label{marshalling-utils}}
+
+These routines allow C code to work with serialized objects using the
+same data format as the \module{marshal} module.  There are functions
+to write data into the serialization format, and additional functions
+that can be used to read the data back.  Files used to store marshalled
+data must be opened in binary mode.
+
+Numeric values are stored with the least significant byte first.
+
+The module supports two versions of the data format: version 0 is the
+historical version, version 1 (new in Python 2.4) shares interned
+strings in the file, and upon unmarshalling. \var{Py_MARSHAL_VERSION}
+indicates the current file format (currently 1).
+
+\begin{cfuncdesc}{void}{PyMarshal_WriteLongToFile}{long value, FILE *file, int version}
+  Marshal a \ctype{long} integer, \var{value}, to \var{file}.  This
+  will only write the least-significant 32 bits of \var{value};
+  regardless of the size of the native \ctype{long} type.
+
+  \versionchanged[\var{version} indicates the file format]{2.4}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{void}{PyMarshal_WriteObjectToFile}{PyObject *value,
+                                                     FILE *file, int version}
+  Marshal a Python object, \var{value}, to \var{file}.
+
+  \versionchanged[\var{version} indicates the file format]{2.4}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyMarshal_WriteObjectToString}{PyObject *value, int version}
+  Return a string object containing the marshalled representation of
+  \var{value}.
+
+  \versionchanged[\var{version} indicates the file format]{2.4}
+\end{cfuncdesc}
+
+The following functions allow marshalled values to be read back in.
+
+XXX What about error detection?  It appears that reading past the end
+of the file will always result in a negative numeric value (where
+that's relevant), but it's not clear that negative values won't be
+handled properly when there's no error.  What's the right way to tell?
+Should only non-negative values be written using these routines?
+
+\begin{cfuncdesc}{long}{PyMarshal_ReadLongFromFile}{FILE *file}
+  Return a C \ctype{long} from the data stream in a \ctype{FILE*}
+  opened for reading.  Only a 32-bit value can be read in using
+  this function, regardless of the native size of \ctype{long}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyMarshal_ReadShortFromFile}{FILE *file}
+  Return a C \ctype{short} from the data stream in a \ctype{FILE*}
+  opened for reading.  Only a 16-bit value can be read in using
+  this function, regardless of the native size of \ctype{short}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyMarshal_ReadObjectFromFile}{FILE *file}
+  Return a Python object from the data stream in a \ctype{FILE*}
+  opened for reading.  On error, sets the appropriate exception
+  (\exception{EOFError} or \exception{TypeError}) and returns \NULL.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyMarshal_ReadLastObjectFromFile}{FILE *file}
+  Return a Python object from the data stream in a \ctype{FILE*}
+  opened for reading.  Unlike
+  \cfunction{PyMarshal_ReadObjectFromFile()}, this function assumes
+  that no further objects will be read from the file, allowing it to
+  aggressively load file data into memory so that the de-serialization
+  can operate from data in memory rather than reading a byte at a time
+  from the file.  Only use these variant if you are certain that you
+  won't be reading anything else from the file.  On error, sets the
+  appropriate exception (\exception{EOFError} or
+  \exception{TypeError}) and returns \NULL.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyMarshal_ReadObjectFromString}{char *string,
+                                                             Py_ssize_t len}
+  Return a Python object from the data stream in a character buffer
+  containing \var{len} bytes pointed to by \var{string}.  On error,
+  sets the appropriate exception (\exception{EOFError} or
+  \exception{TypeError}) and returns \NULL.
+\end{cfuncdesc}
+
+
+\section{Parsing arguments and building values
+         \label{arg-parsing}}
+
+These functions are useful when creating your own extensions functions
+and methods.  Additional information and examples are available in
+\citetitle[../ext/ext.html]{Extending and Embedding the Python
+Interpreter}.
+
+The first three of these functions described,
+\cfunction{PyArg_ParseTuple()},
+\cfunction{PyArg_ParseTupleAndKeywords()}, and
+\cfunction{PyArg_Parse()}, all use \emph{format strings} which are
+used to tell the function about the expected arguments.  The format
+strings use the same syntax for each of these functions.
+
+A format string consists of zero or more ``format units.''  A format
+unit describes one Python object; it is usually a single character or
+a parenthesized sequence of format units.  With a few exceptions, a
+format unit that is not a parenthesized sequence normally corresponds
+to a single address argument to these functions.  In the following
+description, the quoted form is the format unit; the entry in (round)
+parentheses is the Python object type that matches the format unit;
+and the entry in [square] brackets is the type of the C variable(s)
+whose address should be passed.
+
+\begin{description}
+  \item[\samp{s} (string or Unicode object) {[const char *]}]
+  Convert a Python string or Unicode object to a C pointer to a
+  character string.  You must not provide storage for the string
+  itself; a pointer to an existing string is stored into the character
+  pointer variable whose address you pass.  The C string is
+  NUL-terminated.  The Python string must not contain embedded NUL
+  bytes; if it does, a \exception{TypeError} exception is raised.
+  Unicode objects are converted to C strings using the default
+  encoding.  If this conversion fails, a \exception{UnicodeError} is
+  raised.
+
+  \item[\samp{s\#} (string, Unicode or any read buffer compatible object)
+  {[const char *, int]}]
+  This variant on \samp{s} stores into two C variables, the first one
+  a pointer to a character string, the second one its length.  In this
+  case the Python string may contain embedded null bytes.  Unicode
+  objects pass back a pointer to the default encoded string version of
+  the object if such a conversion is possible.  All other read-buffer
+  compatible objects pass back a reference to the raw internal data
+  representation.
+
+  \item[\samp{z} (string or \code{None}) {[const char *]}]
+  Like \samp{s}, but the Python object may also be \code{None}, in
+  which case the C pointer is set to \NULL.
+
+  \item[\samp{z\#} (string or \code{None} or any read buffer
+  compatible object) {[const char *, int]}]
+  This is to \samp{s\#} as \samp{z} is to \samp{s}.
+
+  \item[\samp{u} (Unicode object) {[Py_UNICODE *]}]
+  Convert a Python Unicode object to a C pointer to a NUL-terminated
+  buffer of 16-bit Unicode (UTF-16) data.  As with \samp{s}, there is
+  no need to provide storage for the Unicode data buffer; a pointer to
+  the existing Unicode data is stored into the \ctype{Py_UNICODE}
+  pointer variable whose address you pass.
+
+  \item[\samp{u\#} (Unicode object) {[Py_UNICODE *, int]}]
+  This variant on \samp{u} stores into two C variables, the first one
+  a pointer to a Unicode data buffer, the second one its length.
+  Non-Unicode objects are handled by interpreting their read-buffer
+  pointer as pointer to a \ctype{Py_UNICODE} array.
+
+  \item[\samp{es} (string, Unicode object or character buffer
+  compatible object) {[const char *encoding, char **buffer]}]
+  This variant on \samp{s} is used for encoding Unicode and objects
+  convertible to Unicode into a character buffer. It only works for
+  encoded data without embedded NUL bytes.
+
+  This format requires two arguments.  The first is only used as
+  input, and must be a \ctype{const char*} which points to the name of an
+  encoding as a NUL-terminated string, or \NULL, in which case the
+  default encoding is used.  An exception is raised if the named
+  encoding is not known to Python.  The second argument must be a
+  \ctype{char**}; the value of the pointer it references will be set
+  to a buffer with the contents of the argument text.  The text will
+  be encoded in the encoding specified by the first argument.
+
+  \cfunction{PyArg_ParseTuple()} will allocate a buffer of the needed
+  size, copy the encoded data into this buffer and adjust
+  \var{*buffer} to reference the newly allocated storage.  The caller
+  is responsible for calling \cfunction{PyMem_Free()} to free the
+  allocated buffer after use.
+
+  \item[\samp{et} (string, Unicode object or character buffer
+  compatible object) {[const char *encoding, char **buffer]}]
+  Same as \samp{es} except that 8-bit string objects are passed
+  through without recoding them.  Instead, the implementation assumes
+  that the string object uses the encoding passed in as parameter.
+
+  \item[\samp{es\#} (string, Unicode object or character buffer compatible
+  object) {[const char *encoding, char **buffer, int *buffer_length]}]
+  This variant on \samp{s\#} is used for encoding Unicode and objects
+  convertible to Unicode into a character buffer.  Unlike the
+  \samp{es} format, this variant allows input data which contains NUL
+  characters.
+
+  It requires three arguments.  The first is only used as input, and
+  must be a \ctype{const char*} which points to the name of an encoding as a
+  NUL-terminated string, or \NULL, in which case the default encoding
+  is used.  An exception is raised if the named encoding is not known
+  to Python.  The second argument must be a \ctype{char**}; the value
+  of the pointer it references will be set to a buffer with the
+  contents of the argument text.  The text will be encoded in the
+  encoding specified by the first argument.  The third argument must
+  be a pointer to an integer; the referenced integer will be set to
+  the number of bytes in the output buffer.
+
+  There are two modes of operation:
+
+  If \var{*buffer} points a \NULL{} pointer, the function will
+  allocate a buffer of the needed size, copy the encoded data into
+  this buffer and set \var{*buffer} to reference the newly allocated
+  storage.  The caller is responsible for calling
+  \cfunction{PyMem_Free()} to free the allocated buffer after usage.
+
+  If \var{*buffer} points to a non-\NULL{} pointer (an already
+  allocated buffer), \cfunction{PyArg_ParseTuple()} will use this
+  location as the buffer and interpret the initial value of
+  \var{*buffer_length} as the buffer size.  It will then copy the
+  encoded data into the buffer and NUL-terminate it.  If the buffer
+  is not large enough, a \exception{ValueError} will be set.
+
+  In both cases, \var{*buffer_length} is set to the length of the
+  encoded data without the trailing NUL byte.
+
+  \item[\samp{et\#} (string, Unicode object or character buffer compatible
+  object) {[const char *encoding, char **buffer]}]
+  Same as \samp{es\#} except that string objects are passed through
+  without recoding them. Instead, the implementation assumes that the
+  string object uses the encoding passed in as parameter.
+
+  \item[\samp{b} (integer) {[char]}]
+  Convert a Python integer to a tiny int, stored in a C \ctype{char}.
+
+  \item[\samp{B} (integer) {[unsigned char]}]
+  Convert a Python integer to a tiny int without overflow checking,
+  stored in a C \ctype{unsigned char}. \versionadded{2.3}
+
+  \item[\samp{h} (integer) {[short int]}]
+  Convert a Python integer to a C \ctype{short int}.
+
+  \item[\samp{H} (integer) {[unsigned short int]}]
+  Convert a Python integer to a C \ctype{unsigned short int}, without
+  overflow checking.  \versionadded{2.3}
+
+  \item[\samp{i} (integer) {[int]}]
+  Convert a Python integer to a plain C \ctype{int}.
+
+  \item[\samp{I} (integer) {[unsigned int]}]
+  Convert a Python integer to a C \ctype{unsigned int}, without
+  overflow checking.  \versionadded{2.3}
+
+  \item[\samp{l} (integer) {[long int]}]
+  Convert a Python integer to a C \ctype{long int}.
+
+  \item[\samp{k} (integer) {[unsigned long]}]
+  Convert a Python integer or long integer to a C \ctype{unsigned long} without
+  overflow checking.  \versionadded{2.3}
+
+  \item[\samp{L} (integer) {[PY_LONG_LONG]}]
+  Convert a Python integer to a C \ctype{long long}.  This format is
+  only available on platforms that support \ctype{long long} (or
+  \ctype{_int64} on Windows).
+
+  \item[\samp{K} (integer) {[unsigned PY_LONG_LONG]}]
+  Convert a Python integer or long integer to a C \ctype{unsigned long long}
+  without overflow checking.  This format is only available on
+  platforms that support \ctype{unsigned long long} (or
+  \ctype{unsigned _int64} on Windows).  \versionadded{2.3}
+
+  \item[\samp{n} (integer) {[Py_ssize_t]}]
+  Convert a Python integer or long integer to a C \ctype{Py_ssize_t}.
+  \versionadded{2.5}
+
+  \item[\samp{c} (string of length 1) {[char]}]
+  Convert a Python character, represented as a string of length 1, to
+  a C \ctype{char}.
+
+  \item[\samp{f} (float) {[float]}]
+  Convert a Python floating point number to a C \ctype{float}.
+
+  \item[\samp{d} (float) {[double]}]
+  Convert a Python floating point number to a C \ctype{double}.
+
+  \item[\samp{D} (complex) {[Py_complex]}]
+  Convert a Python complex number to a C \ctype{Py_complex} structure.
+
+  \item[\samp{O} (object) {[PyObject *]}]
+  Store a Python object (without any conversion) in a C object
+  pointer.  The C program thus receives the actual object that was
+  passed.  The object's reference count is not increased.  The pointer
+  stored is not \NULL.
+
+  \item[\samp{O!} (object) {[\var{typeobject}, PyObject *]}]
+  Store a Python object in a C object pointer.  This is similar to
+  \samp{O}, but takes two C arguments: the first is the address of a
+  Python type object, the second is the address of the C variable (of
+  type \ctype{PyObject*}) into which the object pointer is stored.  If
+  the Python object does not have the required type,
+  \exception{TypeError} is raised.
+
+  \item[\samp{O\&} (object) {[\var{converter}, \var{anything}]}]
+  Convert a Python object to a C variable through a \var{converter}
+  function.  This takes two arguments: the first is a function, the
+  second is the address of a C variable (of arbitrary type), converted
+  to \ctype{void *}.  The \var{converter} function in turn is called
+  as follows:
+
+  \var{status}\code{ = }\var{converter}\code{(}\var{object},
+  \var{address}\code{);}
+
+  where \var{object} is the Python object to be converted and
+  \var{address} is the \ctype{void*} argument that was passed to the
+  \cfunction{PyArg_Parse*()} function.  The returned \var{status}
+  should be \code{1} for a successful conversion and \code{0} if the
+  conversion has failed.  When the conversion fails, the
+  \var{converter} function should raise an exception.
+
+  \item[\samp{S} (string) {[PyStringObject *]}]
+  Like \samp{O} but requires that the Python object is a string
+  object.  Raises \exception{TypeError} if the object is not a string
+  object.  The C variable may also be declared as \ctype{PyObject*}.
+
+  \item[\samp{U} (Unicode string) {[PyUnicodeObject *]}]
+  Like \samp{O} but requires that the Python object is a Unicode
+  object.  Raises \exception{TypeError} if the object is not a Unicode
+  object.  The C variable may also be declared as \ctype{PyObject*}.
+
+  \item[\samp{t\#} (read-only character buffer) {[char *, int]}]
+  Like \samp{s\#}, but accepts any object which implements the
+  read-only buffer interface.  The \ctype{char*} variable is set to
+  point to the first byte of the buffer, and the \ctype{int} is set to
+  the length of the buffer.  Only single-segment buffer objects are
+  accepted; \exception{TypeError} is raised for all others.
+
+  \item[\samp{w} (read-write character buffer) {[char *]}]
+  Similar to \samp{s}, but accepts any object which implements the
+  read-write buffer interface.  The caller must determine the length
+  of the buffer by other means, or use \samp{w\#} instead.  Only
+  single-segment buffer objects are accepted; \exception{TypeError} is
+  raised for all others.
+
+  \item[\samp{w\#} (read-write character buffer) {[char *, int]}]
+  Like \samp{s\#}, but accepts any object which implements the
+  read-write buffer interface.  The \ctype{char *} variable is set to
+  point to the first byte of the buffer, and the \ctype{int} is set to
+  the length of the buffer.  Only single-segment buffer objects are
+  accepted; \exception{TypeError} is raised for all others.
+
+  \item[\samp{(\var{items})} (tuple) {[\var{matching-items}]}]
+  The object must be a Python sequence whose length is the number of
+  format units in \var{items}.  The C arguments must correspond to the
+  individual format units in \var{items}.  Format units for sequences
+  may be nested.
+
+  \note{Prior to Python version 1.5.2, this format specifier only
+  accepted a tuple containing the individual parameters, not an
+  arbitrary sequence.  Code which previously caused
+  \exception{TypeError} to be raised here may now proceed without an
+  exception.  This is not expected to be a problem for existing code.}
+\end{description}
+
+It is possible to pass Python long integers where integers are
+requested; however no proper range checking is done --- the most
+significant bits are silently truncated when the receiving field is
+too small to receive the value (actually, the semantics are inherited
+from downcasts in C --- your mileage may vary).
+
+A few other characters have a meaning in a format string.  These may
+not occur inside nested parentheses.  They are:
+
+\begin{description}
+  \item[\samp{|}]
+  Indicates that the remaining arguments in the Python argument list
+  are optional.  The C variables corresponding to optional arguments
+  should be initialized to their default value --- when an optional
+  argument is not specified, \cfunction{PyArg_ParseTuple()} does not
+  touch the contents of the corresponding C variable(s).
+
+  \item[\samp{:}]
+  The list of format units ends here; the string after the colon is
+  used as the function name in error messages (the ``associated
+  value'' of the exception that \cfunction{PyArg_ParseTuple()}
+  raises).
+
+  \item[\samp{;}]
+  The list of format units ends here; the string after the semicolon
+  is used as the error message \emph{instead} of the default error
+  message.  Clearly, \samp{:} and \samp{;} mutually exclude each
+  other.
+\end{description}
+
+Note that any Python object references which are provided to the
+caller are \emph{borrowed} references; do not decrement their
+reference count!
+
+Additional arguments passed to these functions must be addresses of
+variables whose type is determined by the format string; these are
+used to store values from the input tuple.  There are a few cases, as
+described in the list of format units above, where these parameters
+are used as input values; they should match what is specified for the
+corresponding format unit in that case.
+
+For the conversion to succeed, the \var{arg} object must match the
+format and the format must be exhausted.  On success, the
+\cfunction{PyArg_Parse*()} functions return true, otherwise they
+return false and raise an appropriate exception.
+
+\begin{cfuncdesc}{int}{PyArg_ParseTuple}{PyObject *args, const char *format,
+                                         \moreargs}
+  Parse the parameters of a function that takes only positional
+  parameters into local variables.  Returns true on success; on
+  failure, it returns false and raises the appropriate exception.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyArg_VaParse}{PyObject *args, const char *format,
+                                         va_list vargs}
+  Identical to \cfunction{PyArg_ParseTuple()}, except that it accepts a
+  va_list rather than a variable number of arguments.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyArg_ParseTupleAndKeywords}{PyObject *args,
+                       PyObject *kw, const char *format, char *keywords[],
+                       \moreargs}
+  Parse the parameters of a function that takes both positional and
+  keyword parameters into local variables.  Returns true on success;
+  on failure, it returns false and raises the appropriate exception.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyArg_VaParseTupleAndKeywords}{PyObject *args,
+                       PyObject *kw, const char *format, char *keywords[],
+                       va_list vargs}
+  Identical to \cfunction{PyArg_ParseTupleAndKeywords()}, except that it
+  accepts a va_list rather than a variable number of arguments.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyArg_Parse}{PyObject *args, const char *format,
+                                    \moreargs}
+  Function used to deconstruct the argument lists of ``old-style''
+  functions --- these are functions which use the
+  \constant{METH_OLDARGS} parameter parsing method.  This is not
+  recommended for use in parameter parsing in new code, and most code
+  in the standard interpreter has been modified to no longer use this
+  for that purpose.  It does remain a convenient way to decompose
+  other tuples, however, and may continue to be used for that
+  purpose.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyArg_UnpackTuple}{PyObject *args, const char *name,
+                                          Py_ssize_t min, Py_ssize_t max, \moreargs}
+  A simpler form of parameter retrieval which does not use a format
+  string to specify the types of the arguments.  Functions which use
+  this method to retrieve their parameters should be declared as
+  \constant{METH_VARARGS} in function or method tables.  The tuple
+  containing the actual parameters should be passed as \var{args}; it
+  must actually be a tuple.  The length of the tuple must be at least
+  \var{min} and no more than \var{max}; \var{min} and \var{max} may be
+  equal.  Additional arguments must be passed to the function, each of
+  which should be a pointer to a \ctype{PyObject*} variable; these
+  will be filled in with the values from \var{args}; they will contain
+  borrowed references.  The variables which correspond to optional
+  parameters not given by \var{args} will not be filled in; these
+  should be initialized by the caller.
+  This function returns true on success and false if \var{args} is not
+  a tuple or contains the wrong number of elements; an exception will
+  be set if there was a failure.
+
+  This is an example of the use of this function, taken from the
+  sources for the \module{_weakref} helper module for weak references:
+
+\begin{verbatim}
+static PyObject *
+weakref_ref(PyObject *self, PyObject *args)
+{
+    PyObject *object;
+    PyObject *callback = NULL;
+    PyObject *result = NULL;
+
+    if (PyArg_UnpackTuple(args, "ref", 1, 2, &object, &callback)) {
+        result = PyWeakref_NewRef(object, callback);
+    }
+    return result;
+}
+\end{verbatim}
+
+  The call to \cfunction{PyArg_UnpackTuple()} in this example is
+  entirely equivalent to this call to \cfunction{PyArg_ParseTuple()}:
+
+\begin{verbatim}
+PyArg_ParseTuple(args, "O|O:ref", &object, &callback)
+\end{verbatim}
+
+  \versionadded{2.2}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{Py_BuildValue}{const char *format,
+                                            \moreargs}
+  Create a new value based on a format string similar to those
+  accepted by the \cfunction{PyArg_Parse*()} family of functions and a
+  sequence of values.  Returns the value or \NULL{} in the case of an
+  error; an exception will be raised if \NULL{} is returned.
+
+  \cfunction{Py_BuildValue()} does not always build a tuple.  It
+  builds a tuple only if its format string contains two or more format
+  units.  If the format string is empty, it returns \code{None}; if it
+  contains exactly one format unit, it returns whatever object is
+  described by that format unit.  To force it to return a tuple of
+  size 0 or one, parenthesize the format string.
+
+  When memory buffers are passed as parameters to supply data to build
+  objects, as for the \samp{s} and \samp{s\#} formats, the required
+  data is copied.  Buffers provided by the caller are never referenced
+  by the objects created by \cfunction{Py_BuildValue()}.  In other
+  words, if your code invokes \cfunction{malloc()} and passes the
+  allocated memory to \cfunction{Py_BuildValue()}, your code is
+  responsible for calling \cfunction{free()} for that memory once
+  \cfunction{Py_BuildValue()} returns.
+
+  In the following description, the quoted form is the format unit;
+  the entry in (round) parentheses is the Python object type that the
+  format unit will return; and the entry in [square] brackets is the
+  type of the C value(s) to be passed.
+
+  The characters space, tab, colon and comma are ignored in format
+  strings (but not within format units such as \samp{s\#}).  This can
+  be used to make long format strings a tad more readable.
+
+  \begin{description}
+    \item[\samp{s} (string) {[char *]}]
+    Convert a null-terminated C string to a Python object.  If the C
+    string pointer is \NULL, \code{None} is used.
+
+    \item[\samp{s\#} (string) {[char *, int]}]
+    Convert a C string and its length to a Python object.  If the C
+    string pointer is \NULL, the length is ignored and \code{None} is
+    returned.
+
+    \item[\samp{z} (string or \code{None}) {[char *]}]
+    Same as \samp{s}.
+
+    \item[\samp{z\#} (string or \code{None}) {[char *, int]}]
+    Same as \samp{s\#}.
+
+    \item[\samp{u} (Unicode string) {[Py_UNICODE *]}]
+    Convert a null-terminated buffer of Unicode (UCS-2 or UCS-4)
+    data to a Python Unicode object.  If the Unicode buffer pointer
+    is \NULL, \code{None} is returned.
+
+    \item[\samp{u\#} (Unicode string) {[Py_UNICODE *, int]}]
+    Convert a Unicode (UCS-2 or UCS-4) data buffer and its length
+    to a Python Unicode object.   If the Unicode buffer pointer
+    is \NULL, the length is ignored and \code{None} is returned.
+
+    \item[\samp{i} (integer) {[int]}]
+    Convert a plain C \ctype{int} to a Python integer object.
+
+    \item[\samp{b} (integer) {[char]}]
+    Convert a plain C \ctype{char} to a Python integer object.
+
+    \item[\samp{h} (integer) {[short int]}]
+    Convert a plain C \ctype{short int} to a Python integer object.
+
+    \item[\samp{l} (integer) {[long int]}]
+    Convert a C \ctype{long int} to a Python integer object.
+
+    \item[\samp{B} (integer) {[unsigned char]}]
+    Convert a C \ctype{unsigned char} to a Python integer object.
+
+    \item[\samp{H} (integer) {[unsigned short int]}]
+    Convert a C \ctype{unsigned short int} to a Python integer object.
+
+    \item[\samp{I} (integer/long) {[unsigned int]}]
+    Convert a C \ctype{unsigned int} to a Python integer object
+    or a Python long integer object, if it is larger than \code{sys.maxint}.
+
+    \item[\samp{k} (integer/long) {[unsigned long]}]
+    Convert a C \ctype{unsigned long} to a Python integer object
+    or a Python long integer object, if it is larger than \code{sys.maxint}.
+
+    \item[\samp{L} (long) {[PY_LONG_LONG]}]
+    Convert a C \ctype{long long} to a Python long integer object. Only
+    available on platforms that support \ctype{long long}.
+
+    \item[\samp{K} (long) {[unsigned PY_LONG_LONG]}]
+    Convert a C \ctype{unsigned long long} to a Python long integer object.
+    Only available on platforms that support \ctype{unsigned long long}.
+
+    \item[\samp{n} (int) {[Py_ssize_t]}]
+    Convert a C \ctype{Py_ssize_t} to a Python integer or long integer.
+    \versionadded{2.5}
+
+    \item[\samp{c} (string of length 1) {[char]}]
+    Convert a C \ctype{int} representing a character to a Python
+    string of length 1.
+
+    \item[\samp{d} (float) {[double]}]
+    Convert a C \ctype{double} to a Python floating point number.
+
+    \item[\samp{f} (float) {[float]}]
+    Same as \samp{d}.
+
+    \item[\samp{D} (complex) {[Py_complex *]}]
+    Convert a C \ctype{Py_complex} structure to a Python complex
+    number.
+
+    \item[\samp{O} (object) {[PyObject *]}]
+    Pass a Python object untouched (except for its reference count,
+    which is incremented by one).  If the object passed in is a
+    \NULL{} pointer, it is assumed that this was caused because the
+    call producing the argument found an error and set an exception.
+    Therefore, \cfunction{Py_BuildValue()} will return \NULL{} but
+    won't raise an exception.  If no exception has been raised yet,
+    \exception{SystemError} is set.
+
+    \item[\samp{S} (object) {[PyObject *]}]
+    Same as \samp{O}.
+
+    \item[\samp{N} (object) {[PyObject *]}]
+    Same as \samp{O}, except it doesn't increment the reference count
+    on the object.  Useful when the object is created by a call to an
+    object constructor in the argument list.
+
+    \item[\samp{O\&} (object) {[\var{converter}, \var{anything}]}]
+    Convert \var{anything} to a Python object through a
+    \var{converter} function.  The function is called with
+    \var{anything} (which should be compatible with \ctype{void *}) as
+    its argument and should return a ``new'' Python object, or \NULL{}
+    if an error occurred.
+
+    \item[\samp{(\var{items})} (tuple) {[\var{matching-items}]}]
+    Convert a sequence of C values to a Python tuple with the same
+    number of items.
+
+    \item[\samp{[\var{items}]} (list) {[\var{matching-items}]}]
+    Convert a sequence of C values to a Python list with the same
+    number of items.
+
+    \item[\samp{\{\var{items}\}} (dictionary) {[\var{matching-items}]}]
+    Convert a sequence of C values to a Python dictionary.  Each pair
+    of consecutive C values adds one item to the dictionary, serving
+    as key and value, respectively.
+
+  \end{description}
+
+  If there is an error in the format string, the
+  \exception{SystemError} exception is set and \NULL{} returned.
+\end{cfuncdesc}
+
+\section{String conversion and formatting \label{string-formatting}}
+
+Functions for number conversion and formatted string output.
+
+\begin{cfuncdesc}{int}{PyOS_snprintf}{char *str, size_t size, 
+                                      const char *format, \moreargs}
+Output not more than \var{size} bytes to \var{str} according to the format
+string \var{format} and the extra arguments. See the \UNIX{} man
+page \manpage{snprintf}{2}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyOS_vsnprintf}{char *str, size_t size,
+                                       const char *format, va_list va}
+Output not more than \var{size} bytes to \var{str} according to the format
+string \var{format} and the variable argument list \var{va}. \UNIX{}
+man page \manpage{vsnprintf}{2}.
+\end{cfuncdesc}
+
+\cfunction{PyOS_snprintf} and \cfunction{PyOS_vsnprintf} wrap the
+Standard C library functions \cfunction{snprintf()} and
+\cfunction{vsnprintf()}. Their purpose is to guarantee consistent
+behavior in corner cases, which the Standard C functions do not.
+
+The wrappers ensure that \var{str}[\var{size}-1] is always
+\character{\textbackslash0} upon return. They never write more than
+\var{size} bytes (including the trailing \character{\textbackslash0}
+into str. Both functions require that \code{\var{str} != NULL},
+\code{\var{size} > 0} and \code{\var{format} != NULL}.
+
+If the platform doesn't have \cfunction{vsnprintf()} and the buffer
+size needed to avoid truncation exceeds \var{size} by more than 512
+bytes, Python aborts with a \var{Py_FatalError}.
+
+The return value (\var{rv}) for these functions should be interpreted
+as follows:
+
+\begin{itemize}
+
+\item When \code{0 <= \var{rv} < \var{size}}, the output conversion
+  was successful and \var{rv} characters were written to \var{str}
+  (excluding the trailing \character{\textbackslash0} byte at
+  \var{str}[\var{rv}]).
+
+\item When \code{\var{rv} >= \var{size}}, the output conversion was
+  truncated and a buffer with \code{\var{rv} + 1} bytes would have
+  been needed to succeed. \var{str}[\var{size}-1] is
+  \character{\textbackslash0} in this case.
+
+\item When \code{\var{rv} < 0}, ``something bad happened.''
+  \var{str}[\var{size}-1] is \character{\textbackslash0} in this case
+  too, but the rest of \var{str} is undefined. The exact cause of the
+  error depends on the underlying platform.
+
+\end{itemize}
+
+The following functions provide locale-independent string to number
+conversions.
+
+\begin{cfuncdesc}{double}{PyOS_ascii_strtod}{const char *nptr, char **endptr}
+Convert a string to a \ctype{double}. This function behaves like the
+Standard C function \cfunction{strtod()} does in the C locale. It does
+this without changing the current locale, since that would not be
+thread-safe.
+
+\cfunction{PyOS_ascii_strtod} should typically be used for reading
+configuration files or other non-user input that should be locale
+independent. \versionadded{2.4}
+
+See the \UNIX{} man page \manpage{strtod}{2} for details.
+
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{char *}{PyOS_ascii_formatd}{char *buffer, size_t buf_len,
+                                              const char *format, double d}
+Convert a \ctype{double} to a string using the \character{.} as the
+decimal separator. \var{format} is a \cfunction{printf()}-style format
+string specifying the number format. Allowed conversion characters are
+\character{e}, \character{E}, \character{f}, \character{F},
+\character{g} and \character{G}.
+
+The return value is a pointer to \var{buffer} with the converted
+string or NULL if the conversion failed. \versionadded{2.4}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{double}{PyOS_ascii_atof}{const char *nptr}
+Convert a string to a \ctype{double} in a locale-independent
+way. \versionadded{2.4}
+
+See the \UNIX{} man page \manpage{atof}{2} for details.
+\end{cfuncdesc}

Added: vendor/Python/current/Doc/api/veryhigh.tex
===================================================================
--- vendor/Python/current/Doc/api/veryhigh.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/api/veryhigh.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,287 @@
+\chapter{The Very High Level Layer \label{veryhigh}}
+
+
+The functions in this chapter will let you execute Python source code
+given in a file or a buffer, but they will not let you interact in a
+more detailed way with the interpreter.
+
+Several of these functions accept a start symbol from the grammar as a 
+parameter.  The available start symbols are \constant{Py_eval_input},
+\constant{Py_file_input}, and \constant{Py_single_input}.  These are
+described following the functions which accept them as parameters.
+
+Note also that several of these functions take \ctype{FILE*}
+parameters.  On particular issue which needs to be handled carefully
+is that the \ctype{FILE} structure for different C libraries can be
+different and incompatible.  Under Windows (at least), it is possible
+for dynamically linked extensions to actually use different libraries,
+so care should be taken that \ctype{FILE*} parameters are only passed
+to these functions if it is certain that they were created by the same
+library that the Python runtime is using.
+
+
+\begin{cfuncdesc}{int}{Py_Main}{int argc, char **argv}
+  The main program for the standard interpreter.  This is made
+  available for programs which embed Python.  The \var{argc} and
+  \var{argv} parameters should be prepared exactly as those which are
+  passed to a C program's \cfunction{main()} function.  It is
+  important to note that the argument list may be modified (but the
+  contents of the strings pointed to by the argument list are not).
+  The return value will be the integer passed to the
+  \function{sys.exit()} function, \code{1} if the interpreter exits
+  due to an exception, or \code{2} if the parameter list does not
+  represent a valid Python command line.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyRun_AnyFile}{FILE *fp, const char *filename}
+  This is a simplified interface to \cfunction{PyRun_AnyFileExFlags()}
+  below, leaving \var{closeit} set to \code{0} and \var{flags} set to \NULL.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyRun_AnyFileFlags}{FILE *fp, const char *filename,
+                                           PyCompilerFlags *flags}
+  This is a simplified interface to \cfunction{PyRun_AnyFileExFlags()}
+  below, leaving the \var{closeit} argument set to \code{0}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyRun_AnyFileEx}{FILE *fp, const char *filename,
+                                        int closeit}
+  This is a simplified interface to \cfunction{PyRun_AnyFileExFlags()}
+  below, leaving the \var{flags} argument set to \NULL.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyRun_AnyFileExFlags}{FILE *fp, const char *filename,
+                                             int closeit,
+                                             PyCompilerFlags *flags}
+  If \var{fp} refers to a file associated with an interactive device
+  (console or terminal input or \UNIX{} pseudo-terminal), return the
+  value of \cfunction{PyRun_InteractiveLoop()}, otherwise return the
+  result of \cfunction{PyRun_SimpleFile()}.  If \var{filename} is
+  \NULL, this function uses \code{"???"} as the filename.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyRun_SimpleString}{const char *command}
+  This is a simplified interface to \cfunction{PyRun_SimpleStringFlags()}
+  below, leaving the \var{PyCompilerFlags*} argument set to NULL.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyRun_SimpleStringFlags}{const char *command,
+                                                PyCompilerFlags *flags}
+  Executes the Python source code from \var{command} in the
+  \module{__main__} module according to the \var{flags} argument.
+  If \module{__main__} does not already exist, it is created.  Returns
+  \code{0} on success or \code{-1} if an exception was raised.  If there
+  was an error, there is no way to get the exception information.
+  For the meaning of \var{flags}, see below.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyRun_SimpleFile}{FILE *fp, const char *filename}
+  This is a simplified interface to \cfunction{PyRun_SimpleFileExFlags()}
+  below, leaving \var{closeit} set to \code{0} and \var{flags} set to
+  \NULL.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyRun_SimpleFileFlags}{FILE *fp, const char *filename,
+                                              PyCompilerFlags *flags}
+  This is a simplified interface to \cfunction{PyRun_SimpleFileExFlags()}
+  below, leaving \var{closeit} set to \code{0}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyRun_SimpleFileEx}{FILE *fp, const char *filename,
+                                           int closeit}
+  This is a simplified interface to \cfunction{PyRun_SimpleFileExFlags()}
+  below, leaving \var{flags} set to \NULL.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyRun_SimpleFileExFlags}{FILE *fp, const char *filename,
+                                                int closeit,
+                                                PyCompilerFlags *flags}
+  Similar to \cfunction{PyRun_SimpleStringFlags()}, but the Python source
+  code is read from \var{fp} instead of an in-memory string.
+  \var{filename} should be the name of the file.  If \var{closeit} is
+  true, the file is closed before PyRun_SimpleFileExFlags returns.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyRun_InteractiveOne}{FILE *fp, const char *filename}
+  This is a simplified interface to \cfunction{PyRun_InteractiveOneFlags()}
+  below, leaving \var{flags} set to \NULL.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyRun_InteractiveOneFlags}{FILE *fp,
+                                                  const char *filename,
+                                                  PyCompilerFlags *flags}
+  Read and execute a single statement from a file associated with an
+  interactive device according to the \var{flags} argument.  If
+  \var{filename} is \NULL, \code{"???"} is used instead.  The user will
+  be prompted using \code{sys.ps1} and \code{sys.ps2}.  Returns \code{0}
+  when the input was executed successfully, \code{-1} if there was an
+  exception, or an error code from the \file{errcode.h} include file
+  distributed as part of Python if there was a parse error.  (Note that
+  \file{errcode.h} is not included by \file{Python.h}, so must be included
+  specifically if needed.)
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyRun_InteractiveLoop}{FILE *fp, const char *filename}
+  This is a simplified interface to \cfunction{PyRun_InteractiveLoopFlags()}
+  below, leaving \var{flags} set to \NULL.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyRun_InteractiveLoopFlags}{FILE *fp, 
+                                                   const char *filename,
+                                                   PyCompilerFlags *flags}
+  Read and execute statements from a file associated with an
+  interactive device until \EOF{} is reached.  If \var{filename} is
+  \NULL, \code{"???"} is used instead.  The user will be prompted
+  using \code{sys.ps1} and \code{sys.ps2}.  Returns \code{0} at \EOF.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{struct _node*}{PyParser_SimpleParseString}{const char *str,
+                                                             int start}
+  This is a simplified interface to
+  \cfunction{PyParser_SimpleParseStringFlagsFilename()} below, leaving 
+  \var{filename} set to \NULL{} and \var{flags} set to \code{0}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{struct _node*}{PyParser_SimpleParseStringFlags}{
+                                 const char *str, int start, int flags}
+  This is a simplified interface to
+  \cfunction{PyParser_SimpleParseStringFlagsFilename()} below, leaving 
+  \var{filename} set to \NULL.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{struct _node*}{PyParser_SimpleParseStringFlagsFilename}{
+                                 const char *str, const char *filename,
+                                 int start, int flags}
+  Parse Python source code from \var{str} using the start token
+  \var{start} according to the \var{flags} argument.  The result can
+  be used to create a code object which can be evaluated efficiently.
+  This is useful if a code fragment must be evaluated many times.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{struct _node*}{PyParser_SimpleParseFile}{FILE *fp,
+                                 const char *filename, int start}
+  This is a simplified interface to \cfunction{PyParser_SimpleParseFileFlags()}
+  below, leaving \var{flags} set to \code{0}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{struct _node*}{PyParser_SimpleParseFileFlags}{FILE *fp,
+                                 const char *filename, int start, int flags}
+  Similar to \cfunction{PyParser_SimpleParseStringFlagsFilename()}, but
+  the Python source code is read from \var{fp} instead of an in-memory
+  string.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyRun_String}{const char *str, int start,
+                                           PyObject *globals,
+                                           PyObject *locals}
+  This is a simplified interface to \cfunction{PyRun_StringFlags()} below,
+  leaving \var{flags} set to \NULL.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyRun_StringFlags}{const char *str, int start,
+                                                PyObject *globals,
+                                                PyObject *locals,
+                                                PyCompilerFlags *flags}
+  Execute Python source code from \var{str} in the context specified
+  by the dictionaries \var{globals} and \var{locals} with the compiler
+  flags specified by \var{flags}.  The parameter \var{start} specifies
+  the start token that should be used to parse the source code.
+
+  Returns the result of executing the code as a Python object, or
+  \NULL{} if an exception was raised.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyRun_File}{FILE *fp, const char *filename,
+                                         int start, PyObject *globals,
+                                         PyObject *locals}
+  This is a simplified interface to \cfunction{PyRun_FileExFlags()} below,
+  leaving \var{closeit} set to \code{0} and \var{flags} set to \NULL.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyRun_FileEx}{FILE *fp, const char *filename,
+                                         int start, PyObject *globals,
+                                         PyObject *locals, int closeit}
+  This is a simplified interface to \cfunction{PyRun_FileExFlags()} below,
+  leaving \var{flags} set to \NULL.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyRun_FileFlags}{FILE *fp, const char *filename,
+                                         int start, PyObject *globals,
+                                         PyObject *locals,
+                                         PyCompilerFlags *flags}
+  This is a simplified interface to \cfunction{PyRun_FileExFlags()} below,
+  leaving \var{closeit} set to \code{0}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyRun_FileExFlags}{FILE *fp, const char *filename,
+                                                int start, PyObject *globals,
+                                                PyObject *locals, int closeit,
+                                                PyCompilerFlags *flags}
+  Similar to \cfunction{PyRun_StringFlags()}, but the Python source code is
+  read from \var{fp} instead of an in-memory string.
+  \var{filename} should be the name of the file.
+  If \var{closeit} is true, the file is closed before
+  \cfunction{PyRun_FileExFlags()} returns.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{Py_CompileString}{const char *str,
+                                               const char *filename,
+                                               int start}
+  This is a simplified interface to \cfunction{Py_CompileStringFlags()} below,
+  leaving \var{flags} set to \NULL.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{Py_CompileStringFlags}{const char *str,
+                                                    const char *filename,
+                                                    int start,
+                                                    PyCompilerFlags *flags}
+  Parse and compile the Python source code in \var{str}, returning the
+  resulting code object.  The start token is given by \var{start};
+  this can be used to constrain the code which can be compiled and should
+  be \constant{Py_eval_input}, \constant{Py_file_input}, or
+  \constant{Py_single_input}.  The filename specified by
+  \var{filename} is used to construct the code object and may appear
+  in tracebacks or \exception{SyntaxError} exception messages.  This
+  returns \NULL{} if the code cannot be parsed or compiled.
+\end{cfuncdesc}
+
+\begin{cvardesc}{int}{Py_eval_input}
+  The start symbol from the Python grammar for isolated expressions;
+  for use with
+  \cfunction{Py_CompileString()}\ttindex{Py_CompileString()}.
+\end{cvardesc}
+
+\begin{cvardesc}{int}{Py_file_input}
+  The start symbol from the Python grammar for sequences of statements
+  as read from a file or other source; for use with
+  \cfunction{Py_CompileString()}\ttindex{Py_CompileString()}.  This is
+  the symbol to use when compiling arbitrarily long Python source code.
+\end{cvardesc}
+
+\begin{cvardesc}{int}{Py_single_input}
+  The start symbol from the Python grammar for a single statement; for
+  use with \cfunction{Py_CompileString()}\ttindex{Py_CompileString()}.
+  This is the symbol used for the interactive interpreter loop.
+\end{cvardesc}
+
+\begin{ctypedesc}[PyCompilerFlags]{struct PyCompilerFlags}
+  This is the structure used to hold compiler flags.  In cases where
+  code is only being compiled, it is passed as \code{int flags}, and in
+  cases where code is being executed, it is passed as
+  \code{PyCompilerFlags *flags}.  In this case, \code{from __future__
+  import} can modify \var{flags}.
+
+  Whenever \code{PyCompilerFlags *flags} is \NULL, \member{cf_flags}
+  is treated as equal to \code{0}, and any modification due to
+  \code{from __future__ import} is discarded.
+\begin{verbatim}
+struct PyCompilerFlags {
+    int cf_flags;
+}
+\end{verbatim}
+\end{ctypedesc}
+
+\begin{cvardesc}{int}{CO_FUTURE_DIVISION}
+  This bit can be set in \var{flags} to cause division operator \code{/}
+  to be interpreted as ``true division'' according to \pep{238}.
+\end{cvardesc}

Added: vendor/Python/current/Doc/commontex/boilerplate.tex
===================================================================
--- vendor/Python/current/Doc/commontex/boilerplate.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/commontex/boilerplate.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,9 @@
+\author{Guido van Rossum\\
+	Fred L. Drake, Jr., editor}
+\authoraddress{
+	\strong{Python Software Foundation}\\
+	Email: \email{docs at python.org}
+}
+
+\date{18th April, 2007}			% XXX update before final release!
+\input{patchlevel}		% include Python version information

Added: vendor/Python/current/Doc/commontex/copyright.tex
===================================================================
--- vendor/Python/current/Doc/commontex/copyright.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/commontex/copyright.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,14 @@
+Copyright \copyright{} 2001-2006 Python Software Foundation.
+All rights reserved.
+
+Copyright \copyright{} 2000 BeOpen.com.
+All rights reserved.
+
+Copyright \copyright{} 1995-2000 Corporation for National Research Initiatives.
+All rights reserved.
+
+Copyright \copyright{} 1991-1995 Stichting Mathematisch Centrum.
+All rights reserved.
+
+See the end of this document for complete license and permissions
+information.

Added: vendor/Python/current/Doc/commontex/license.tex
===================================================================
--- vendor/Python/current/Doc/commontex/license.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/commontex/license.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,673 @@
+\section{History of the software}
+
+Python was created in the early 1990s by Guido van Rossum at Stichting
+Mathematisch Centrum (CWI, see \url{http://www.cwi.nl/}) in the Netherlands
+as a successor of a language called ABC.  Guido remains Python's
+principal author, although it includes many contributions from others.
+
+In 1995, Guido continued his work on Python at the Corporation for
+National Research Initiatives (CNRI, see \url{http://www.cnri.reston.va.us/})
+in Reston, Virginia where he released several versions of the
+software.
+
+In May 2000, Guido and the Python core development team moved to
+BeOpen.com to form the BeOpen PythonLabs team.  In October of the same
+year, the PythonLabs team moved to Digital Creations (now Zope
+Corporation; see \url{http://www.zope.com/}).  In 2001, the Python
+Software Foundation (PSF, see \url{http://www.python.org/psf/}) was
+formed, a non-profit organization created specifically to own
+Python-related Intellectual Property.  Zope Corporation is a
+sponsoring member of the PSF.
+
+All Python releases are Open Source (see
+\url{http://www.opensource.org/} for the Open Source Definition).
+Historically, most, but not all, Python releases have also been
+GPL-compatible; the table below summarizes the various releases.
+
+\begin{tablev}{c|c|c|c|c}{textrm}%
+  {Release}{Derived from}{Year}{Owner}{GPL compatible?}
+  \linev{0.9.0 thru 1.2}{n/a}{1991-1995}{CWI}{yes}
+  \linev{1.3 thru 1.5.2}{1.2}{1995-1999}{CNRI}{yes}
+  \linev{1.6}{1.5.2}{2000}{CNRI}{no}
+  \linev{2.0}{1.6}{2000}{BeOpen.com}{no}
+  \linev{1.6.1}{1.6}{2001}{CNRI}{no}
+  \linev{2.1}{2.0+1.6.1}{2001}{PSF}{no}
+  \linev{2.0.1}{2.0+1.6.1}{2001}{PSF}{yes}
+  \linev{2.1.1}{2.1+2.0.1}{2001}{PSF}{yes}
+  \linev{2.2}{2.1.1}{2001}{PSF}{yes}
+  \linev{2.1.2}{2.1.1}{2002}{PSF}{yes}
+  \linev{2.1.3}{2.1.2}{2002}{PSF}{yes}
+  \linev{2.2.1}{2.2}{2002}{PSF}{yes}
+  \linev{2.2.2}{2.2.1}{2002}{PSF}{yes}
+  \linev{2.2.3}{2.2.2}{2002-2003}{PSF}{yes}
+  \linev{2.3}{2.2.2}{2002-2003}{PSF}{yes}
+  \linev{2.3.1}{2.3}{2002-2003}{PSF}{yes}
+  \linev{2.3.2}{2.3.1}{2003}{PSF}{yes}
+  \linev{2.3.3}{2.3.2}{2003}{PSF}{yes}
+  \linev{2.3.4}{2.3.3}{2004}{PSF}{yes}
+  \linev{2.3.5}{2.3.4}{2005}{PSF}{yes}
+  \linev{2.4}{2.3}{2004}{PSF}{yes}
+  \linev{2.4.1}{2.4}{2005}{PSF}{yes}
+  \linev{2.4.2}{2.4.1}{2005}{PSF}{yes}
+  \linev{2.4.3}{2.4.2}{2006}{PSF}{yes}
+  \linev{2.5}{2.4}{2006}{PSF}{yes}
+  \linev{2.5.1}{2.5}{2007}{PSF}{yes}
+\end{tablev}
+
+\note{GPL-compatible doesn't mean that we're distributing
+Python under the GPL.  All Python licenses, unlike the GPL, let you
+distribute a modified version without making your changes open source.
+The GPL-compatible licenses make it possible to combine Python with
+other software that is released under the GPL; the others don't.}
+
+Thanks to the many outside volunteers who have worked under Guido's
+direction to make these releases possible.
+
+
+\section{Terms and conditions for accessing or otherwise using Python}
+
+\centerline{\strong{PSF LICENSE AGREEMENT FOR PYTHON \version}}
+
+\begin{enumerate}
+\item
+This LICENSE AGREEMENT is between the Python Software Foundation
+(``PSF''), and the Individual or Organization (``Licensee'') accessing
+and otherwise using Python \version{} software in source or binary
+form and its associated documentation.
+
+\item
+Subject to the terms and conditions of this License Agreement, PSF
+hereby grants Licensee a nonexclusive, royalty-free, world-wide
+license to reproduce, analyze, test, perform and/or display publicly,
+prepare derivative works, distribute, and otherwise use Python
+\version{} alone or in any derivative version, provided, however, that
+PSF's License Agreement and PSF's notice of copyright, i.e.,
+``Copyright \copyright{} 2001-2006 Python Software Foundation; All
+Rights Reserved'' are retained in Python \version{} alone or in any
+derivative version prepared by Licensee.
+
+\item
+In the event Licensee prepares a derivative work that is based on
+or incorporates Python \version{} or any part thereof, and wants to
+make the derivative work available to others as provided herein, then
+Licensee hereby agrees to include in any such work a brief summary of
+the changes made to Python \version.
+
+\item
+PSF is making Python \version{} available to Licensee on an ``AS IS''
+basis.  PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
+DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON \version{} WILL
+NOT INFRINGE ANY THIRD PARTY RIGHTS.
+
+\item
+PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
+\version{} FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR
+LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON
+\version, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE
+POSSIBILITY THEREOF.
+
+\item
+This License Agreement will automatically terminate upon a material
+breach of its terms and conditions.
+
+\item
+Nothing in this License Agreement shall be deemed to create any
+relationship of agency, partnership, or joint venture between PSF and
+Licensee.  This License Agreement does not grant permission to use PSF
+trademarks or trade name in a trademark sense to endorse or promote
+products or services of Licensee, or any third party.
+
+\item
+By copying, installing or otherwise using Python \version, Licensee
+agrees to be bound by the terms and conditions of this License
+Agreement.
+\end{enumerate}
+
+
+\centerline{\strong{BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0}}
+
+\centerline{\strong{BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1}}
+
+\begin{enumerate}
+\item
+This LICENSE AGREEMENT is between BeOpen.com (``BeOpen''), having an
+office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the
+Individual or Organization (``Licensee'') accessing and otherwise
+using this software in source or binary form and its associated
+documentation (``the Software'').
+
+\item
+Subject to the terms and conditions of this BeOpen Python License
+Agreement, BeOpen hereby grants Licensee a non-exclusive,
+royalty-free, world-wide license to reproduce, analyze, test, perform
+and/or display publicly, prepare derivative works, distribute, and
+otherwise use the Software alone or in any derivative version,
+provided, however, that the BeOpen Python License is retained in the
+Software, alone or in any derivative version prepared by Licensee.
+
+\item
+BeOpen is making the Software available to Licensee on an ``AS IS''
+basis.  BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND
+DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT
+INFRINGE ANY THIRD PARTY RIGHTS.
+
+\item
+BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE
+SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS
+AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY
+DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+\item
+This License Agreement will automatically terminate upon a material
+breach of its terms and conditions.
+
+\item
+This License Agreement shall be governed by and interpreted in all
+respects by the law of the State of California, excluding conflict of
+law provisions.  Nothing in this License Agreement shall be deemed to
+create any relationship of agency, partnership, or joint venture
+between BeOpen and Licensee.  This License Agreement does not grant
+permission to use BeOpen trademarks or trade names in a trademark
+sense to endorse or promote products or services of Licensee, or any
+third party.  As an exception, the ``BeOpen Python'' logos available
+at http://www.pythonlabs.com/logos.html may be used according to the
+permissions granted on that web page.
+
+\item
+By copying, installing or otherwise using the software, Licensee
+agrees to be bound by the terms and conditions of this License
+Agreement.
+\end{enumerate}
+
+
+\centerline{\strong{CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1}}
+
+\begin{enumerate}
+\item
+This LICENSE AGREEMENT is between the Corporation for National
+Research Initiatives, having an office at 1895 Preston White Drive,
+Reston, VA 20191 (``CNRI''), and the Individual or Organization
+(``Licensee'') accessing and otherwise using Python 1.6.1 software in
+source or binary form and its associated documentation.
+
+\item
+Subject to the terms and conditions of this License Agreement, CNRI
+hereby grants Licensee a nonexclusive, royalty-free, world-wide
+license to reproduce, analyze, test, perform and/or display publicly,
+prepare derivative works, distribute, and otherwise use Python 1.6.1
+alone or in any derivative version, provided, however, that CNRI's
+License Agreement and CNRI's notice of copyright, i.e., ``Copyright
+\copyright{} 1995-2001 Corporation for National Research Initiatives;
+All Rights Reserved'' are retained in Python 1.6.1 alone or in any
+derivative version prepared by Licensee.  Alternately, in lieu of
+CNRI's License Agreement, Licensee may substitute the following text
+(omitting the quotes): ``Python 1.6.1 is made available subject to the
+terms and conditions in CNRI's License Agreement.  This Agreement
+together with Python 1.6.1 may be located on the Internet using the
+following unique, persistent identifier (known as a handle):
+1895.22/1013.  This Agreement may also be obtained from a proxy server
+on the Internet using the following URL:
+\url{http://hdl.handle.net/1895.22/1013}.''
+
+\item
+In the event Licensee prepares a derivative work that is based on
+or incorporates Python 1.6.1 or any part thereof, and wants to make
+the derivative work available to others as provided herein, then
+Licensee hereby agrees to include in any such work a brief summary of
+the changes made to Python 1.6.1.
+
+\item
+CNRI is making Python 1.6.1 available to Licensee on an ``AS IS''
+basis.  CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND
+DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT
+INFRINGE ANY THIRD PARTY RIGHTS.
+
+\item
+CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
+1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
+A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1,
+OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+\item
+This License Agreement will automatically terminate upon a material
+breach of its terms and conditions.
+
+\item
+This License Agreement shall be governed by the federal
+intellectual property law of the United States, including without
+limitation the federal copyright law, and, to the extent such
+U.S. federal law does not apply, by the law of the Commonwealth of
+Virginia, excluding Virginia's conflict of law provisions.
+Notwithstanding the foregoing, with regard to derivative works based
+on Python 1.6.1 that incorporate non-separable material that was
+previously distributed under the GNU General Public License (GPL), the
+law of the Commonwealth of Virginia shall govern this License
+Agreement only as to issues arising under or with respect to
+Paragraphs 4, 5, and 7 of this License Agreement.  Nothing in this
+License Agreement shall be deemed to create any relationship of
+agency, partnership, or joint venture between CNRI and Licensee.  This
+License Agreement does not grant permission to use CNRI trademarks or
+trade name in a trademark sense to endorse or promote products or
+services of Licensee, or any third party.
+
+\item
+By clicking on the ``ACCEPT'' button where indicated, or by copying,
+installing or otherwise using Python 1.6.1, Licensee agrees to be
+bound by the terms and conditions of this License Agreement.
+\end{enumerate}
+
+\centerline{ACCEPT}
+
+
+
+\centerline{\strong{CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2}}
+
+Copyright \copyright{} 1991 - 1995, Stichting Mathematisch Centrum
+Amsterdam, The Netherlands.  All rights reserved.
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Stichting Mathematisch
+Centrum or CWI not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
+THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
+FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+
+\section{Licenses and Acknowledgements for Incorporated Software}
+
+This section is an incomplete, but growing list of licenses and
+acknowledgements for third-party software incorporated in the
+Python distribution.
+
+
+\subsection{Mersenne Twister}
+
+The \module{_random} module includes code based on a download from
+\url{http://www.math.keio.ac.jp/~matumoto/MT2002/emt19937ar.html}.
+The following are the verbatim comments from the original code:
+
+\begin{verbatim}
+A C-program for MT19937, with initialization improved 2002/1/26.
+Coded by Takuji Nishimura and Makoto Matsumoto.
+
+Before using, initialize the state by using init_genrand(seed)
+or init_by_array(init_key, key_length).
+
+Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+
+ 3. The names of its contributors may not be used to endorse or promote
+    products derived from this software without specific prior written
+    permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+Any feedback is very welcome.
+http://www.math.keio.ac.jp/matumoto/emt.html
+email: matumoto at math.keio.ac.jp
+\end{verbatim}
+
+
+
+\subsection{Sockets}
+
+The \module{socket} module uses the functions, \function{getaddrinfo},
+and \function{getnameinfo}, which are coded in separate source files
+from the WIDE Project, \url{http://www.wide.ad.jp/about/index.html}.
+
+\begin{verbatim}      
+Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+All rights reserved.
+ 
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. Neither the name of the project nor the names of its contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+GAI_ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+FOR GAI_ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON GAI_ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN GAI_ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+\end{verbatim}
+
+
+
+\subsection{Floating point exception control}
+
+The source for the \module{fpectl} module includes the following notice:
+
+\begin{verbatim}
+     ---------------------------------------------------------------------  
+    /                       Copyright (c) 1996.                           \ 
+   |          The Regents of the University of California.                 |
+   |                        All rights reserved.                           |
+   |                                                                       |
+   |   Permission to use, copy, modify, and distribute this software for   |
+   |   any purpose without fee is hereby granted, provided that this en-   |
+   |   tire notice is included in all copies of any software which is or   |
+   |   includes  a  copy  or  modification  of  this software and in all   |
+   |   copies of the supporting documentation for such software.           |
+   |                                                                       |
+   |   This  work was produced at the University of California, Lawrence   |
+   |   Livermore National Laboratory under  contract  no.  W-7405-ENG-48   |
+   |   between  the  U.S.  Department  of  Energy and The Regents of the   |
+   |   University of California for the operation of UC LLNL.              |
+   |                                                                       |
+   |                              DISCLAIMER                               |
+   |                                                                       |
+   |   This  software was prepared as an account of work sponsored by an   |
+   |   agency of the United States Government. Neither the United States   |
+   |   Government  nor the University of California nor any of their em-   |
+   |   ployees, makes any warranty, express or implied, or  assumes  any   |
+   |   liability  or  responsibility  for the accuracy, completeness, or   |
+   |   usefulness of any information,  apparatus,  product,  or  process   |
+   |   disclosed,   or  represents  that  its  use  would  not  infringe   |
+   |   privately-owned rights. Reference herein to any specific  commer-   |
+   |   cial  products,  process,  or  service  by trade name, trademark,   |
+   |   manufacturer, or otherwise, does not  necessarily  constitute  or   |
+   |   imply  its endorsement, recommendation, or favoring by the United   |
+   |   States Government or the University of California. The views  and   |
+   |   opinions  of authors expressed herein do not necessarily state or   |
+   |   reflect those of the United States Government or  the  University   |
+   |   of  California,  and shall not be used for advertising or product   |
+    \  endorsement purposes.                                              / 
+     ---------------------------------------------------------------------
+\end{verbatim}
+
+
+
+\subsection{MD5 message digest algorithm}
+
+The source code for the \module{md5} module contains the following notice:
+
+\begin{verbatim}
+  Copyright (C) 1999, 2002 Aladdin Enterprises.  All rights reserved.
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  L. Peter Deutsch
+  ghost at aladdin.com
+
+  Independent implementation of MD5 (RFC 1321).
+
+  This code implements the MD5 Algorithm defined in RFC 1321, whose
+  text is available at
+	http://www.ietf.org/rfc/rfc1321.txt
+  The code is derived from the text of the RFC, including the test suite
+  (section A.5) but excluding the rest of Appendix A.  It does not include
+  any code or documentation that is identified in the RFC as being
+  copyrighted.
+
+  The original and principal author of md5.h is L. Peter Deutsch
+  <ghost at aladdin.com>.  Other authors are noted in the change history
+  that follows (in reverse chronological order):
+
+  2002-04-13 lpd Removed support for non-ANSI compilers; removed
+	references to Ghostscript; clarified derivation from RFC 1321;
+	now handles byte order either statically or dynamically.
+  1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
+  1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
+	added conditionalization for C++ compilation from Martin
+	Purschke <purschke at bnl.gov>.
+  1999-05-03 lpd Original version.
+\end{verbatim}
+
+
+
+\subsection{Asynchronous socket services}
+
+The \module{asynchat} and \module{asyncore} modules contain the
+following notice:
+
+\begin{verbatim}      
+ Copyright 1996 by Sam Rushing
+
+                         All Rights Reserved
+
+ Permission to use, copy, modify, and distribute this software and
+ its documentation for any purpose and without fee is hereby
+ granted, provided that the above copyright notice appear in all
+ copies and that both that copyright notice and this permission
+ notice appear in supporting documentation, and that the name of Sam
+ Rushing not be used in advertising or publicity pertaining to
+ distribution of the software without specific, written prior
+ permission.
+
+ SAM RUSHING DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+ NO EVENT SHALL SAM RUSHING BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+ OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+\end{verbatim}
+
+
+\subsection{Cookie management}
+
+The \module{Cookie} module contains the following notice:
+
+\begin{verbatim}
+ Copyright 2000 by Timothy O'Malley <timo at alum.mit.edu>
+
+                All Rights Reserved
+
+ Permission to use, copy, modify, and distribute this software
+ and its documentation for any purpose and without fee is hereby
+ granted, provided that the above copyright notice appear in all
+ copies and that both that copyright notice and this permission
+ notice appear in supporting documentation, and that the name of
+ Timothy O'Malley  not be used in advertising or publicity
+ pertaining to distribution of the software without specific, written
+ prior permission.
+
+ Timothy O'Malley DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS, IN NO EVENT SHALL Timothy O'Malley BE LIABLE FOR
+ ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ PERFORMANCE OF THIS SOFTWARE.
+\end{verbatim}      
+
+
+
+\subsection{Profiling}
+
+The \module{profile} and \module{pstats} modules contain
+the following notice:
+
+\begin{verbatim}
+ Copyright 1994, by InfoSeek Corporation, all rights reserved.
+ Written by James Roskind
+
+ Permission to use, copy, modify, and distribute this Python software
+ and its associated documentation for any purpose (subject to the
+ restriction in the following sentence) without fee is hereby granted,
+ provided that the above copyright notice appears in all copies, and
+ that both that copyright notice and this permission notice appear in
+ supporting documentation, and that the name of InfoSeek not be used in
+ advertising or publicity pertaining to distribution of the software
+ without specific, written prior permission.  This permission is
+ explicitly restricted to the copying and modification of the software
+ to remain in Python, compiled Python, or other languages (such as C)
+ wherein the modified or derived code is exclusively imported into a
+ Python module.
+
+ INFOSEEK CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS. IN NO EVENT SHALL INFOSEEK CORPORATION BE LIABLE FOR ANY
+ SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+\end{verbatim}
+
+
+
+\subsection{Execution tracing}
+
+The \module{trace} module contains the following notice:
+
+\begin{verbatim}
+ portions copyright 2001, Autonomous Zones Industries, Inc., all rights...
+ err...  reserved and offered to the public under the terms of the
+ Python 2.2 license.
+ Author: Zooko O'Whielacronx
+ http://zooko.com/
+ mailto:zooko at zooko.com
+
+ Copyright 2000, Mojam Media, Inc., all rights reserved.
+ Author: Skip Montanaro
+
+ Copyright 1999, Bioreason, Inc., all rights reserved.
+ Author: Andrew Dalke
+
+ Copyright 1995-1997, Automatrix, Inc., all rights reserved.
+ Author: Skip Montanaro
+
+ Copyright 1991-1995, Stichting Mathematisch Centrum, all rights reserved.
+
+
+ Permission to use, copy, modify, and distribute this Python software and
+ its associated documentation for any purpose without fee is hereby
+ granted, provided that the above copyright notice appears in all copies,
+ and that both that copyright notice and this permission notice appear in
+ supporting documentation, and that the name of neither Automatrix,
+ Bioreason or Mojam Media be used in advertising or publicity pertaining to
+ distribution of the software without specific, written prior permission.
+\end{verbatim} 
+
+
+
+\subsection{UUencode and UUdecode functions}
+
+The \module{uu} module contains the following notice:
+
+\begin{verbatim}
+ Copyright 1994 by Lance Ellinghouse
+ Cathedral City, California Republic, United States of America.
+                        All Rights Reserved
+ Permission to use, copy, modify, and distribute this software and its
+ documentation for any purpose and without fee is hereby granted,
+ provided that the above copyright notice appear in all copies and that
+ both that copyright notice and this permission notice appear in
+ supporting documentation, and that the name of Lance Ellinghouse
+ not be used in advertising or publicity pertaining to distribution
+ of the software without specific, written prior permission.
+ LANCE ELLINGHOUSE DISCLAIMS ALL WARRANTIES WITH REGARD TO
+ THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS, IN NO EVENT SHALL LANCE ELLINGHOUSE CENTRUM BE LIABLE
+ FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+ Modified by Jack Jansen, CWI, July 1995:
+ - Use binascii module to do the actual line-by-line conversion
+   between ascii and binary. This results in a 1000-fold speedup. The C
+   version is still 5 times faster, though.
+ - Arguments more compliant with python standard
+\end{verbatim}
+
+
+
+\subsection{XML Remote Procedure Calls}
+
+The \module{xmlrpclib} module contains the following notice:
+
+\begin{verbatim}
+     The XML-RPC client interface is
+
+ Copyright (c) 1999-2002 by Secret Labs AB
+ Copyright (c) 1999-2002 by Fredrik Lundh
+
+ By obtaining, using, and/or copying this software and/or its
+ associated documentation, you agree that you have read, understood,
+ and will comply with the following terms and conditions:
+
+ Permission to use, copy, modify, and distribute this software and
+ its associated documentation for any purpose and without fee is
+ hereby granted, provided that the above copyright notice appears in
+ all copies, and that both that copyright notice and this permission
+ notice appear in supporting documentation, and that the name of
+ Secret Labs AB or the author not be used in advertising or publicity
+ pertaining to distribution of the software without specific, written
+ prior permission.
+
+ SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
+ TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT-
+ ABILITY AND FITNESS.  IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR
+ BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+ DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ OF THIS SOFTWARE.
+\end{verbatim}

Added: vendor/Python/current/Doc/commontex/reportingbugs.tex
===================================================================
--- vendor/Python/current/Doc/commontex/reportingbugs.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/commontex/reportingbugs.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,61 @@
+\label{reporting-bugs}
+
+Python is a mature programming language which has established a
+reputation for stability.  In order to maintain this reputation, the
+developers would like to know of any deficiencies you find in Python
+or its documentation.
+
+Before submitting a report, you will be required to log into SourceForge;
+this will make it possible for the developers to contact you
+for additional information if needed.  It is not possible to submit a
+bug report anonymously.
+
+All bug reports should be submitted via the Python Bug Tracker on
+SourceForge (\url{http://sourceforge.net/bugs/?group_id=5470}).  The
+bug tracker offers a Web form which allows pertinent information to be
+entered and submitted to the developers.
+
+The first step in filing a report is to determine whether the problem
+has already been reported.  The advantage in doing so, aside from
+saving the developers time, is that you learn what has been done to
+fix it; it may be that the problem has already been fixed for the next
+release, or additional information is needed (in which case you are
+welcome to provide it if you can!).  To do this, search the bug
+database using the search box on the left side of the page.
+
+If the problem you're reporting is not already in the bug tracker, go
+back to the Python Bug Tracker
+(\url{http://sourceforge.net/bugs/?group_id=5470}).  Select the
+``Submit a Bug'' link at the top of the page to open the bug reporting
+form.
+
+The submission form has a number of fields.  The only fields that are
+required are the ``Summary'' and ``Details'' fields.  For the summary,
+enter a \emph{very} short description of the problem; less than ten
+words is good.  In the Details field, describe the problem in detail,
+including what you expected to happen and what did happen.  Be sure to
+include the version of Python you used, whether any extension modules
+were involved, and what hardware and software platform you were using
+(including version information as appropriate).
+
+The only other field that you may want to set is the ``Category''
+field, which allows you to place the bug report into a broad category
+(such as ``Documentation'' or ``Library'').
+
+Each bug report will be assigned to a developer who will determine
+what needs to be done to correct the problem.  You will
+receive an update each time action is taken on the bug.
+
+
+\begin{seealso}
+  \seetitle[http://www-mice.cs.ucl.ac.uk/multimedia/software/documentation/ReportingBugs.html]{How
+        to Report Bugs Effectively}{Article which goes into some
+        detail about how to create a useful bug report.  This
+        describes what kind of information is useful and why it is
+        useful.}
+
+  \seetitle[http://www.mozilla.org/quality/bug-writing-guidelines.html]{Bug
+        Writing Guidelines}{Information about writing a good bug
+        report.  Some of this is specific to the Mozilla project, but
+        describes general good practices.}
+\end{seealso}

Added: vendor/Python/current/Doc/commontex/typestruct.h
===================================================================
--- vendor/Python/current/Doc/commontex/typestruct.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/commontex/typestruct.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,76 @@
+typedef struct _typeobject {
+    PyObject_VAR_HEAD
+    char *tp_name; /* For printing, in format "<module>.<name>" */
+    int tp_basicsize, tp_itemsize; /* For allocation */
+
+    /* Methods to implement standard operations */
+
+    destructor tp_dealloc;
+    printfunc tp_print;
+    getattrfunc tp_getattr;
+    setattrfunc tp_setattr;
+    cmpfunc tp_compare;
+    reprfunc tp_repr;
+
+    /* Method suites for standard classes */
+
+    PyNumberMethods *tp_as_number;
+    PySequenceMethods *tp_as_sequence;
+    PyMappingMethods *tp_as_mapping;
+
+    /* More standard operations (here for binary compatibility) */
+
+    hashfunc tp_hash;
+    ternaryfunc tp_call;
+    reprfunc tp_str;
+    getattrofunc tp_getattro;
+    setattrofunc tp_setattro;
+
+    /* Functions to access object as input/output buffer */
+    PyBufferProcs *tp_as_buffer;
+
+    /* Flags to define presence of optional/expanded features */
+    long tp_flags;
+
+    char *tp_doc; /* Documentation string */
+
+    /* Assigned meaning in release 2.0 */
+    /* call function for all accessible objects */
+    traverseproc tp_traverse;
+
+    /* delete references to contained objects */
+    inquiry tp_clear;
+
+    /* Assigned meaning in release 2.1 */
+    /* rich comparisons */
+    richcmpfunc tp_richcompare;
+
+    /* weak reference enabler */
+    long tp_weaklistoffset;
+
+    /* Added in release 2.2 */
+    /* Iterators */
+    getiterfunc tp_iter;
+    iternextfunc tp_iternext;
+
+    /* Attribute descriptor and subclassing stuff */
+    struct PyMethodDef *tp_methods;
+    struct PyMemberDef *tp_members;
+    struct PyGetSetDef *tp_getset;
+    struct _typeobject *tp_base;
+    PyObject *tp_dict;
+    descrgetfunc tp_descr_get;
+    descrsetfunc tp_descr_set;
+    long tp_dictoffset;
+    initproc tp_init;
+    allocfunc tp_alloc;
+    newfunc tp_new;
+    freefunc tp_free; /* Low-level free-memory routine */
+    inquiry tp_is_gc; /* For PyObject_IS_GC */
+    PyObject *tp_bases;
+    PyObject *tp_mro; /* method resolution order */
+    PyObject *tp_cache;
+    PyObject *tp_subclasses;
+    PyObject *tp_weaklist;
+
+} PyTypeObject;

Added: vendor/Python/current/Doc/dist/dist.tex
===================================================================
--- vendor/Python/current/Doc/dist/dist.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/dist/dist.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,3795 @@
+\documentclass{manual}
+\usepackage{distutils}
+
+% $Id: dist.tex 53487 2007-01-19 05:52:46Z neal.norwitz $
+
+% TODO
+%   Document extension.read_setup_file
+%   Document build_clib command
+%
+
+\title{Distributing Python Modules}
+
+\input{boilerplate}
+
+\author{Greg Ward\\
+        Anthony Baxter}
+\authoraddress{
+	\strong{Python Software Foundation}\\
+	Email: \email{distutils-sig at python.org}
+}
+
+\makeindex
+\makemodindex
+
+\begin{document}
+
+\maketitle
+
+\input{copyright}
+
+\begin{abstract}
+  \noindent
+  This document describes the Python Distribution Utilities
+  (``Distutils'') from the module developer's point of view, describing
+  how to use the Distutils to make Python modules and extensions easily
+  available to a wider audience with very little overhead for
+  build/release/install mechanics.
+\end{abstract}
+
+% The ugly "%begin{latexonly}" pseudo-environment suppresses the table
+% of contents for HTML generation.
+%
+%begin{latexonly}
+\tableofcontents
+%end{latexonly}
+
+
+\chapter{An Introduction to Distutils}
+\label{intro}
+
+This document covers using the Distutils to distribute your Python
+modules, concentrating on the role of developer/distributor: if
+you're looking for information on installing Python modules, you
+should refer to the \citetitle[../inst/inst.html]{Installing Python
+Modules} manual.
+
+
+\section{Concepts \& Terminology}
+\label{concepts}
+
+Using the Distutils is quite simple, both for module developers and for
+users/administrators installing third-party modules.  As a developer,
+your responsibilities (apart from writing solid, well-documented and
+well-tested code, of course!) are:
+\begin{itemize}
+\item write a setup script (\file{setup.py} by convention)
+\item (optional) write a setup configuration file
+\item create a source distribution
+\item (optional) create one or more built (binary) distributions
+\end{itemize}
+Each of these tasks is covered in this document.
+
+Not all module developers have access to a multitude of platforms, so
+it's not always feasible to expect them to create a multitude of built
+distributions.  It is hoped that a class of intermediaries, called
+\emph{packagers}, will arise to address this need.  Packagers will take
+source distributions released by module developers, build them on one or
+more platforms, and release the resulting built distributions.  Thus,
+users on the most popular platforms will be able to install most popular
+Python module distributions in the most natural way for their platform,
+without having to run a single setup script or compile a line of code.
+
+
+\section{A Simple Example}
+\label{simple-example}
+
+The setup script is usually quite simple, although since it's written
+in Python, there are no arbitrary limits to what you can do with it,
+though you should be careful about putting arbitrarily expensive
+operations in your setup script. Unlike, say, Autoconf-style configure
+scripts, the setup script may be run multiple times in the course of
+building and installing your module distribution.  
+
+If all you want to do is distribute a module called \module{foo},
+contained in a file \file{foo.py}, then your setup script can be as
+simple as this:
+
+\begin{verbatim}
+from distutils.core import setup
+setup(name='foo',
+      version='1.0',
+      py_modules=['foo'],
+      )
+\end{verbatim}
+
+Some observations:
+\begin{itemize}
+\item most information that you supply to the Distutils is supplied as
+  keyword arguments to the \function{setup()} function
+\item those keyword arguments fall into two categories: package
+  metadata (name, version number) and information about what's in the
+  package (a list of pure Python modules, in this case)
+\item modules are specified by module name, not filename (the same will
+  hold true for packages and extensions)
+\item it's recommended that you supply a little more metadata, in
+  particular your name, email address and a URL for the project
+  (see section~\ref{setup-script} for an example)
+\end{itemize}
+
+To create a source distribution for this module, you would create a
+setup script, \file{setup.py}, containing the above code, and run:
+
+\begin{verbatim}
+python setup.py sdist
+\end{verbatim}
+
+which will create an archive file (e.g., tarball on \UNIX, ZIP file on
+Windows) containing your setup script \file{setup.py}, and your module
+\file{foo.py}.  The archive file will be named \file{foo-1.0.tar.gz} (or
+\file{.zip}), and will unpack into a directory \file{foo-1.0}.
+
+If an end-user wishes to install your \module{foo} module, all she has
+to do is download \file{foo-1.0.tar.gz} (or \file{.zip}), unpack it,
+and---from the \file{foo-1.0} directory---run
+
+\begin{verbatim}
+python setup.py install
+\end{verbatim}
+
+which will ultimately copy \file{foo.py} to the appropriate directory
+for third-party modules in their Python installation.
+
+This simple example demonstrates some fundamental concepts of the
+Distutils. First, both developers and installers have the same basic
+user interface, i.e. the setup script.  The difference is which
+Distutils \emph{commands} they use: the \command{sdist} command is
+almost exclusively for module developers, while \command{install} is
+more often for installers (although most developers will want to install
+their own code occasionally).
+
+If you want to make things really easy for your users, you can create
+one or more built distributions for them.  For instance, if you are
+running on a Windows machine, and want to make things easy for other
+Windows users, you can create an executable installer (the most
+appropriate type of built distribution for this platform) with the
+\command{bdist\_wininst} command.  For example:
+
+\begin{verbatim}
+python setup.py bdist_wininst
+\end{verbatim}
+
+will create an executable installer, \file{foo-1.0.win32.exe}, in the
+current directory.
+
+Other useful built distribution formats are RPM, implemented by the
+\command{bdist\_rpm} command, Solaris \program{pkgtool}
+(\command{bdist\_pkgtool}), and HP-UX \program{swinstall}
+(\command{bdist_sdux}).  For example, the following command will
+create an RPM file called \file{foo-1.0.noarch.rpm}:
+
+\begin{verbatim}
+python setup.py bdist_rpm
+\end{verbatim}
+
+(The \command{bdist\_rpm} command uses the \command{rpm} executable,
+therefore this has to be run on an RPM-based system such as Red Hat
+Linux, SuSE Linux, or Mandrake Linux.)
+
+You can find out what distribution formats are available at any time by
+running
+
+\begin{verbatim}
+python setup.py bdist --help-formats
+\end{verbatim}
+
+
+\section{General Python terminology}
+\label{python-terms}
+
+If you're reading this document, you probably have a good idea of what
+modules, extensions, and so forth are.  Nevertheless, just to be sure
+that everyone is operating from a common starting point, we offer the
+following glossary of common Python terms:
+\begin{description}
+\item[module] the basic unit of code reusability in Python: a block of
+  code imported by some other code.  Three types of modules concern us
+  here: pure Python modules, extension modules, and packages.
+
+\item[pure Python module] a module written in Python and contained in a
+  single \file{.py} file (and possibly associated \file{.pyc} and/or
+  \file{.pyo} files).  Sometimes referred to as a ``pure module.''
+
+\item[extension module] a module written in the low-level language of
+  the Python implementation: C/\Cpp{} for Python, Java for Jython.
+  Typically contained in a single dynamically loadable pre-compiled
+  file, e.g. a shared object (\file{.so}) file for Python extensions on
+  \UNIX, a DLL (given the \file{.pyd} extension) for Python extensions
+  on Windows, or a Java class file for Jython extensions.  (Note that
+  currently, the Distutils only handles C/\Cpp{} extensions for Python.)
+
+\item[package] a module that contains other modules; typically contained
+  in a directory in the filesystem and distinguished from other
+  directories by the presence of a file \file{\_\_init\_\_.py}.
+
+\item[root package] the root of the hierarchy of packages.  (This isn't
+  really a package, since it doesn't have an \file{\_\_init\_\_.py}
+  file.  But we have to call it something.)  The vast majority of the
+  standard library is in the root package, as are many small, standalone
+  third-party modules that don't belong to a larger module collection.
+  Unlike regular packages, modules in the root package can be found in
+  many directories: in fact, every directory listed in \code{sys.path}
+  contributes modules to the root package.
+\end{description}
+
+
+\section{Distutils-specific terminology}
+\label{distutils-term}
+
+The following terms apply more specifically to the domain of
+distributing Python modules using the Distutils:
+\begin{description}
+\item[module distribution] a collection of Python modules distributed
+  together as a single downloadable resource and meant to be installed
+  \emph{en masse}.  Examples of some well-known module distributions are
+  Numeric Python, PyXML, PIL (the Python Imaging Library), or
+  mxBase.  (This would be called a \emph{package}, except that term
+  is already taken in the Python context: a single module distribution
+  may contain zero, one, or many Python packages.)
+
+\item[pure module distribution] a module distribution that contains only
+  pure Python modules and packages.  Sometimes referred to as a ``pure
+  distribution.''
+
+\item[non-pure module distribution] a module distribution that contains
+  at least one extension module.  Sometimes referred to as a ``non-pure
+  distribution.''
+
+\item[distribution root] the top-level directory of your source tree (or 
+  source distribution); the directory where \file{setup.py} exists.  Generally 
+  \file{setup.py} will be run from this directory.
+\end{description}
+
+
+\chapter{Writing the Setup Script}
+\label{setup-script}
+
+The setup script is the centre of all activity in building,
+distributing, and installing modules using the Distutils.  The main
+purpose of the setup script is to describe your module distribution to
+the Distutils, so that the various commands that operate on your modules
+do the right thing.  As we saw in section~\ref{simple-example} above,
+the setup script consists mainly of a call to \function{setup()}, and
+most information supplied to the Distutils by the module developer is
+supplied as keyword arguments to \function{setup()}.
+
+Here's a slightly more involved example, which we'll follow for the next
+couple of sections: the Distutils' own setup script.  (Keep in mind that
+although the Distutils are included with Python 1.6 and later, they also
+have an independent existence so that Python 1.5.2 users can use them to
+install other module distributions.  The Distutils' own setup script,
+shown here, is used to install the package into Python 1.5.2.)
+
+\begin{verbatim}
+#!/usr/bin/env python
+
+from distutils.core import setup
+
+setup(name='Distutils',
+      version='1.0',
+      description='Python Distribution Utilities',
+      author='Greg Ward',
+      author_email='gward at python.net',
+      url='http://www.python.org/sigs/distutils-sig/',
+      packages=['distutils', 'distutils.command'],
+     )
+\end{verbatim}
+
+There are only two differences between this and the trivial one-file
+distribution presented in section~\ref{simple-example}: more
+metadata, and the specification of pure Python modules by package,
+rather than by module.  This is important since the Distutils consist of
+a couple of dozen modules split into (so far) two packages; an explicit
+list of every module would be tedious to generate and difficult to
+maintain.  For more information on the additional meta-data, see
+section~\ref{meta-data}.
+
+Note that any pathnames (files or directories) supplied in the setup
+script should be written using the \UNIX{} convention, i.e.
+slash-separated.  The Distutils will take care of converting this
+platform-neutral representation into whatever is appropriate on your
+current platform before actually using the pathname.  This makes your
+setup script portable across operating systems, which of course is one
+of the major goals of the Distutils.  In this spirit, all pathnames in
+this document are slash-separated.  (Mac OS 9 programmers should keep in
+mind that the \emph{absence} of a leading slash indicates a relative
+path, the opposite of the Mac OS convention with colons.)
+
+This, of course, only applies to pathnames given to Distutils
+functions.  If you, for example, use standard Python functions such as
+\function{glob.glob()} or \function{os.listdir()} to specify files, you
+should be careful to write portable code instead of hardcoding path
+separators:
+
+\begin{verbatim}
+    glob.glob(os.path.join('mydir', 'subdir', '*.html'))
+    os.listdir(os.path.join('mydir', 'subdir'))
+\end{verbatim}
+
+
+\section{Listing whole packages}
+\label{listing-packages}
+
+The \option{packages} option tells the Distutils to process (build,
+distribute, install, etc.) all pure Python modules found in each package
+mentioned in the \option{packages} list.  In order to do this, of
+course, there has to be a correspondence between package names and
+directories in the filesystem.  The default correspondence is the most
+obvious one, i.e. package \module{distutils} is found in the directory
+\file{distutils} relative to the distribution root.  Thus, when you say
+\code{packages = ['foo']} in your setup script, you are promising that
+the Distutils will find a file \file{foo/\_\_init\_\_.py} (which might
+be spelled differently on your system, but you get the idea) relative to
+the directory where your setup script lives.  If you break this
+promise, the Distutils will issue a warning but still process the broken
+package anyways.
+
+If you use a different convention to lay out your source directory,
+that's no problem: you just have to supply the \option{package\_dir}
+option to tell the Distutils about your convention.  For example, say
+you keep all Python source under \file{lib}, so that modules in the
+``root package'' (i.e., not in any package at all) are in
+\file{lib}, modules in the \module{foo} package are in \file{lib/foo},
+and so forth.  Then you would put
+
+\begin{verbatim}
+package_dir = {'': 'lib'}
+\end{verbatim}
+
+in your setup script.  The keys to this dictionary are package names,
+and an empty package name stands for the root package.  The values are
+directory names relative to your distribution root.  In this case, when
+you say \code{packages = ['foo']}, you are promising that the file
+\file{lib/foo/\_\_init\_\_.py} exists.
+
+Another possible convention is to put the \module{foo} package right in 
+\file{lib}, the \module{foo.bar} package in \file{lib/bar}, etc.  This
+would be written in the setup script as
+
+\begin{verbatim}
+package_dir = {'foo': 'lib'}
+\end{verbatim}
+
+A \code{\var{package}: \var{dir}} entry in the \option{package\_dir}
+dictionary implicitly applies to all packages below \var{package}, so
+the \module{foo.bar} case is automatically handled here.  In this
+example, having \code{packages = ['foo', 'foo.bar']} tells the Distutils
+to look for \file{lib/\_\_init\_\_.py} and
+\file{lib/bar/\_\_init\_\_.py}.  (Keep in mind that although
+\option{package\_dir} applies recursively, you must explicitly list all
+packages in \option{packages}: the Distutils will \emph{not} recursively
+scan your source tree looking for any directory with an
+\file{\_\_init\_\_.py} file.)
+
+
+\section{Listing individual modules}
+\label{listing-modules}
+
+For a small module distribution, you might prefer to list all modules
+rather than listing packages---especially the case of a single module
+that goes in the ``root package'' (i.e., no package at all).  This
+simplest case was shown in section~\ref{simple-example}; here is a
+slightly more involved example:
+
+\begin{verbatim}
+py_modules = ['mod1', 'pkg.mod2']
+\end{verbatim}
+
+This describes two modules, one of them in the ``root'' package, the
+other in the \module{pkg} package.  Again, the default package/directory
+layout implies that these two modules can be found in \file{mod1.py} and
+\file{pkg/mod2.py}, and that \file{pkg/\_\_init\_\_.py} exists as well.
+And again, you can override the package/directory correspondence using
+the \option{package\_dir} option.
+
+
+\section{Describing extension modules}
+\label{describing-extensions}
+
+% XXX read over this section
+Just as writing Python extension modules is a bit more complicated than
+writing pure Python modules, describing them to the Distutils is a bit
+more complicated.  Unlike pure modules, it's not enough just to list
+modules or packages and expect the Distutils to go out and find the
+right files; you have to specify the extension name, source file(s), and
+any compile/link requirements (include directories, libraries to link
+with, etc.).
+
+All of this is done through another keyword argument to
+\function{setup()}, the \option{ext_modules} option.  \option{ext_modules}
+is just a list of \class{Extension} instances, each of which describes a
+single extension module.  Suppose your distribution includes a single
+extension, called \module{foo} and implemented by \file{foo.c}.  If no
+additional instructions to the compiler/linker are needed, describing
+this extension is quite simple:
+
+\begin{verbatim}
+Extension('foo', ['foo.c'])
+\end{verbatim}
+
+The \class{Extension} class can be imported from
+\module{distutils.core} along with \function{setup()}.  Thus, the setup
+script for a module distribution that contains only this one extension
+and nothing else might be:
+
+\begin{verbatim}
+from distutils.core import setup, Extension
+setup(name='foo',
+      version='1.0',
+      ext_modules=[Extension('foo', ['foo.c'])],
+      )
+\end{verbatim}
+
+The \class{Extension} class (actually, the underlying extension-building
+machinery implemented by the \command{build\_ext} command) supports a
+great deal of flexibility in describing Python extensions, which is
+explained in the following sections.  
+
+
+\subsection{Extension names and packages}
+
+The first argument to the \class{Extension} constructor is always the
+name of the extension, including any package names.  For example,
+
+\begin{verbatim}
+Extension('foo', ['src/foo1.c', 'src/foo2.c'])
+\end{verbatim}
+
+describes an extension that lives in the root package, while
+
+\begin{verbatim}
+Extension('pkg.foo', ['src/foo1.c', 'src/foo2.c'])
+\end{verbatim}
+
+describes the same extension in the \module{pkg} package.  The source
+files and resulting object code are identical in both cases; the only
+difference is where in the filesystem (and therefore where in Python's
+namespace hierarchy) the resulting extension lives.
+
+If you have a number of extensions all in the same package (or all under
+the same base package), use the \option{ext\_package} keyword argument
+to \function{setup()}.  For example,
+
+\begin{verbatim}
+setup(...
+      ext_package='pkg',
+      ext_modules=[Extension('foo', ['foo.c']),
+                   Extension('subpkg.bar', ['bar.c'])],
+     )
+\end{verbatim}
+
+will compile \file{foo.c} to the extension \module{pkg.foo}, and
+\file{bar.c} to \module{pkg.subpkg.bar}.
+
+
+\subsection{Extension source files}
+
+The second argument to the \class{Extension} constructor is a list of
+source files.  Since the Distutils currently only support C, \Cpp, and
+Objective-C extensions, these are normally C/\Cpp/Objective-C source
+files.  (Be sure to use appropriate extensions to distinguish \Cpp\
+source files: \file{.cc} and \file{.cpp} seem to be recognized by both
+\UNIX{} and Windows compilers.)
+
+However, you can also include SWIG interface (\file{.i}) files in the
+list; the \command{build\_ext} command knows how to deal with SWIG
+extensions: it will run SWIG on the interface file and compile the
+resulting C/\Cpp{} file into your extension.
+
+\XXX{SWIG support is rough around the edges and largely untested;
+  especially SWIG support for \Cpp{} extensions!  Explain in more detail
+  here when the interface firms up.}
+
+On some platforms, you can include non-source files that are processed
+by the compiler and included in your extension.  Currently, this just
+means Windows message text (\file{.mc}) files and resource definition
+(\file{.rc}) files for Visual \Cpp. These will be compiled to binary resource
+(\file{.res}) files and linked into the executable.
+
+
+\subsection{Preprocessor options}
+
+Three optional arguments to \class{Extension} will help if you need to
+specify include directories to search or preprocessor macros to
+define/undefine: \code{include\_dirs}, \code{define\_macros}, and
+\code{undef\_macros}.
+
+For example, if your extension requires header files in the
+\file{include} directory under your distribution root, use the
+\code{include\_dirs} option:
+
+\begin{verbatim}
+Extension('foo', ['foo.c'], include_dirs=['include'])
+\end{verbatim}
+
+You can specify absolute directories there; if you know that your
+extension will only be built on \UNIX{} systems with X11R6 installed to
+\file{/usr}, you can get away with
+
+\begin{verbatim}
+Extension('foo', ['foo.c'], include_dirs=['/usr/include/X11'])
+\end{verbatim}
+
+You should avoid this sort of non-portable usage if you plan to
+distribute your code: it's probably better to write C code like
+\begin{verbatim}
+#include <X11/Xlib.h>
+\end{verbatim}
+
+If you need to include header files from some other Python extension,
+you can take advantage of the fact that header files are installed in a
+consistent way by the Distutils \command{install\_header} command.  For
+example, the Numerical Python header files are installed (on a standard
+\UNIX{} installation) to \file{/usr/local/include/python1.5/Numerical}.
+(The exact location will differ according to your platform and Python
+installation.)  Since the Python include
+directory---\file{/usr/local/include/python1.5} in this case---is always
+included in the search path when building Python extensions, the best
+approach is to write C code like
+\begin{verbatim}
+#include <Numerical/arrayobject.h>
+\end{verbatim}
+If you must put the \file{Numerical} include directory right into your
+header search path, though, you can find that directory using the
+Distutils \refmodule{distutils.sysconfig} module:
+
+\begin{verbatim}
+from distutils.sysconfig import get_python_inc
+incdir = os.path.join(get_python_inc(plat_specific=1), 'Numerical')
+setup(...,
+      Extension(..., include_dirs=[incdir]),
+      )
+\end{verbatim}
+
+Even though this is quite portable---it will work on any Python
+installation, regardless of platform---it's probably easier to just
+write your C code in the sensible way.
+
+You can define and undefine pre-processor macros with the
+\code{define\_macros} and \code{undef\_macros} options.
+\code{define\_macros} takes a list of \code{(name, value)} tuples, where
+\code{name} is the name of the macro to define (a string) and
+\code{value} is its value: either a string or \code{None}.  (Defining a
+macro \code{FOO} to \code{None} is the equivalent of a bare
+\code{\#define FOO} in your C source: with most compilers, this sets
+\code{FOO} to the string \code{1}.)  \code{undef\_macros} is just
+a list of macros to undefine.
+
+For example:
+
+\begin{verbatim}
+Extension(...,
+          define_macros=[('NDEBUG', '1'),
+                         ('HAVE_STRFTIME', None)],
+          undef_macros=['HAVE_FOO', 'HAVE_BAR'])
+\end{verbatim}
+
+is the equivalent of having this at the top of every C source file:
+
+\begin{verbatim}
+#define NDEBUG 1
+#define HAVE_STRFTIME
+#undef HAVE_FOO
+#undef HAVE_BAR
+\end{verbatim}
+
+
+\subsection{Library options}
+
+You can also specify the libraries to link against when building your
+extension, and the directories to search for those libraries.  The
+\code{libraries} option is a list of libraries to link against,
+\code{library\_dirs} is a list of directories to search for libraries at 
+link-time, and \code{runtime\_library\_dirs} is a list of directories to 
+search for shared (dynamically loaded) libraries at run-time.
+
+For example, if you need to link against libraries known to be in the
+standard library search path on target systems
+
+\begin{verbatim}
+Extension(...,
+          libraries=['gdbm', 'readline'])
+\end{verbatim}
+
+If you need to link with libraries in a non-standard location, you'll
+have to include the location in \code{library\_dirs}:
+
+\begin{verbatim}
+Extension(...,
+          library_dirs=['/usr/X11R6/lib'],
+          libraries=['X11', 'Xt'])
+\end{verbatim}
+
+(Again, this sort of non-portable construct should be avoided if you
+intend to distribute your code.)
+
+\XXX{Should mention clib libraries here or somewhere else!}
+
+\subsection{Other options}
+
+There are still some other options which can be used to handle special
+cases.
+
+The \option{extra\_objects} option is a list of object files to be passed
+to the linker. These files must not have extensions, as the default
+extension for the compiler is used.
+
+\option{extra\_compile\_args} and \option{extra\_link\_args} can be used
+to specify additional command line options for the respective compiler and
+linker command lines.
+
+\option{export\_symbols} is only useful on Windows.  It can contain a list
+of symbols (functions or variables) to be exported. This option
+is not needed when building compiled extensions: Distutils 
+will automatically add \code{initmodule}
+to the list of exported symbols.
+
+\section{Relationships between Distributions and Packages}
+
+A distribution may relate to packages in three specific ways:
+
+\begin{enumerate}
+  \item It can require packages or modules.
+
+  \item It can provide packages or modules.
+
+  \item It can obsolete packages or modules.
+\end{enumerate}
+
+These relationships can be specified using keyword arguments to the
+\function{distutils.core.setup()} function.
+
+Dependencies on other Python modules and packages can be specified by
+supplying the \var{requires} keyword argument to \function{setup()}.
+The value must be a list of strings.  Each string specifies a package
+that is required, and optionally what versions are sufficient.
+
+To specify that any version of a module or package is required, the
+string should consist entirely of the module or package name.
+Examples include \code{'mymodule'} and \code{'xml.parsers.expat'}.
+
+If specific versions are required, a sequence of qualifiers can be
+supplied in parentheses.  Each qualifier may consist of a comparison
+operator and a version number.  The accepted comparison operators are:
+
+\begin{verbatim}
+<    >    ==
+<=   >=   !=
+\end{verbatim}
+
+These can be combined by using multiple qualifiers separated by commas
+(and optional whitespace).  In this case, all of the qualifiers must
+be matched; a logical AND is used to combine the evaluations.
+
+Let's look at a bunch of examples:
+
+\begin{tableii}{l|l}{code}{Requires Expression}{Explanation}
+  \lineii{==1.0}               {Only version \code{1.0} is compatible}
+  \lineii{>1.0, !=1.5.1, <2.0} {Any version after \code{1.0} and before
+                                \code{2.0} is compatible, except
+                                \code{1.5.1}}
+\end{tableii}
+
+Now that we can specify dependencies, we also need to be able to
+specify what we provide that other distributions can require.  This is
+done using the \var{provides} keyword argument to \function{setup()}.
+The value for this keyword is a list of strings, each of which names a
+Python module or package, and optionally identifies the version.  If
+the version is not specified, it is assumed to match that of the
+distribution.
+
+Some examples:
+
+\begin{tableii}{l|l}{code}{Provides Expression}{Explanation}
+  \lineii{mypkg}      {Provide \code{mypkg}, using the distribution version}
+  \lineii{mypkg (1.1)} {Provide \code{mypkg} version 1.1, regardless of the
+                       distribution version}
+\end{tableii}
+
+A package can declare that it obsoletes other packages using the
+\var{obsoletes} keyword argument.  The value for this is similar to
+that of the \var{requires} keyword: a list of strings giving module or
+package specifiers.  Each specifier consists of a module or package
+name optionally followed by one or more version qualifiers.  Version
+qualifiers are given in parentheses after the module or package name.
+
+The versions identified by the qualifiers are those that are obsoleted
+by the distribution being described.  If no qualifiers are given, all
+versions of the named module or package are understood to be
+obsoleted.
+
+
+\section{Installing Scripts}
+
+So far we have been dealing with pure and non-pure Python modules,
+which are usually not run by themselves but imported by scripts.
+
+Scripts are files containing Python source code, intended to be
+started from the command line.  Scripts don't require Distutils to do
+anything very complicated.  The only clever feature is that if the
+first line of the script starts with \code{\#!} and contains the word
+``python'', the Distutils will adjust the first line to refer to the
+current interpreter location. By default, it is replaced with the
+current interpreter location.  The \longprogramopt{executable} (or
+\programopt{-e}) option will allow the interpreter path to be
+explicitly overridden.
+
+The \option{scripts} option simply is a list of files to be handled
+in this way.  From the PyXML setup script:
+
+\begin{verbatim}
+setup(... 
+      scripts=['scripts/xmlproc_parse', 'scripts/xmlproc_val']
+      )
+\end{verbatim}
+
+
+\section{Installing Package Data}
+
+Often, additional files need to be installed into a package.  These
+files are often data that's closely related to the package's
+implementation, or text files containing documentation that might be
+of interest to programmers using the package.  These files are called
+\dfn{package data}.
+
+Package data can be added to packages using the \code{package_data}
+keyword argument to the \function{setup()} function.  The value must
+be a mapping from package name to a list of relative path names that
+should be copied into the package.  The paths are interpreted as
+relative to the directory containing the package (information from the
+\code{package_dir} mapping is used if appropriate); that is, the files
+are expected to be part of the package in the source directories.
+They may contain glob patterns as well.
+
+The path names may contain directory portions; any necessary
+directories will be created in the installation.
+
+For example, if a package should contain a subdirectory with several
+data files, the files can be arranged like this in the source tree:
+
+\begin{verbatim}
+setup.py
+src/
+    mypkg/
+        __init__.py
+        module.py
+        data/
+            tables.dat
+            spoons.dat
+            forks.dat
+\end{verbatim}
+
+The corresponding call to \function{setup()} might be:
+
+\begin{verbatim}
+setup(...,
+      packages=['mypkg'],
+      package_dir={'mypkg': 'src/mypkg'},
+      package_data={'mypkg': ['data/*.dat']},
+      )
+\end{verbatim}
+
+
+\versionadded{2.4}
+
+
+\section{Installing Additional Files}
+
+The \option{data\_files} option can be used to specify additional
+files needed by the module distribution: configuration files, message
+catalogs, data files, anything which doesn't fit in the previous
+categories.
+
+\option{data\_files} specifies a sequence of (\var{directory},
+\var{files}) pairs in the following way:
+
+\begin{verbatim}
+setup(...
+      data_files=[('bitmaps', ['bm/b1.gif', 'bm/b2.gif']),
+                  ('config', ['cfg/data.cfg']),
+                  ('/etc/init.d', ['init-script'])]
+     )
+\end{verbatim}
+
+Note that you can specify the directory names where the data files
+will be installed, but you cannot rename the data files themselves.
+
+Each (\var{directory}, \var{files}) pair in the sequence specifies the
+installation directory and the files to install there.  If
+\var{directory} is a relative path, it is interpreted relative to the
+installation prefix (Python's \code{sys.prefix} for pure-Python
+packages, \code{sys.exec_prefix} for packages that contain extension
+modules).  Each file name in \var{files} is interpreted relative to
+the \file{setup.py} script at the top of the package source
+distribution.  No directory information from \var{files} is used to
+determine the final location of the installed file; only the name of
+the file is used.
+
+You can specify the \option{data\_files} options as a simple sequence
+of files without specifying a target directory, but this is not recommended,
+and the \command{install} command will print a warning in this case.
+To install data files directly in the target directory, an empty
+string should be given as the directory.
+
+\section{Additional meta-data}
+\label{meta-data}
+
+The setup script may include additional meta-data beyond the name and
+version. This information includes:
+
+\begin{tableiv}{l|l|l|c}{code}%
+  {Meta-Data}{Description}{Value}{Notes}
+  \lineiv{name}{name of the package}
+         {short string}{(1)}
+  \lineiv{version}{version of this release}
+         {short string}{(1)(2)}
+  \lineiv{author}{package author's name}
+         {short string}{(3)}
+  \lineiv{author_email}{email address of the package author}
+         {email address}{(3)}
+  \lineiv{maintainer}{package maintainer's name}
+         {short string}{(3)}
+  \lineiv{maintainer_email}{email address of the package maintainer}
+         {email address}{(3)}
+  \lineiv{url}{home page for the package}
+         {URL}{(1)}
+  \lineiv{description}{short, summary description of the package}
+         {short string}{}
+  \lineiv{long_description}{longer description of the package}
+         {long string}{}
+  \lineiv{download_url}{location where the package may be downloaded}
+         {URL}{(4)}
+  \lineiv{classifiers}{a list of classifiers}
+         {list of strings}{(4)}
+\end{tableiv}
+
+\noindent Notes:
+\begin{description}
+\item[(1)] These fields are required.
+\item[(2)] It is recommended that versions take the form
+  \emph{major.minor\optional{.patch\optional{.sub}}}.
+\item[(3)] Either the author or the maintainer must be identified.
+\item[(4)] These fields should not be used if your package is to be
+  compatible with Python versions prior to 2.2.3 or 2.3.  The list is
+  available from the \ulink{PyPI website}{http://www.python.org/pypi}.
+
+\item['short string'] A single line of text, not more than 200 characters.
+\item['long string'] Multiple lines of plain text in reStructuredText
+  format (see \url{http://docutils.sf.net/}).
+\item['list of strings'] See below.
+\end{description}
+
+None of the string values may be Unicode.
+
+Encoding the version information is an art in itself. Python packages
+generally adhere to the version format
+\emph{major.minor\optional{.patch}\optional{sub}}. The major number is
+0 for
+initial, experimental releases of software. It is incremented for
+releases that represent major milestones in a package. The minor
+number is incremented when important new features are added to the
+package. The patch number increments when bug-fix releases are
+made. Additional trailing version information is sometimes used to
+indicate sub-releases.  These are "a1,a2,...,aN" (for alpha releases,
+where functionality and API may change), "b1,b2,...,bN" (for beta
+releases, which only fix bugs) and "pr1,pr2,...,prN" (for final
+pre-release release testing). Some examples:
+
+\begin{description}
+\item[0.1.0] the first, experimental release of a package
+\item[1.0.1a2] the second alpha release of the first patch version of 1.0
+\end{description}
+
+\option{classifiers} are specified in a python list:
+
+\begin{verbatim}
+setup(...
+      classifiers=[
+          'Development Status :: 4 - Beta',
+          'Environment :: Console',
+          'Environment :: Web Environment',
+          'Intended Audience :: End Users/Desktop',
+          'Intended Audience :: Developers',
+          'Intended Audience :: System Administrators',
+          'License :: OSI Approved :: Python Software Foundation License',
+          'Operating System :: MacOS :: MacOS X',
+          'Operating System :: Microsoft :: Windows',
+          'Operating System :: POSIX',
+          'Programming Language :: Python',
+          'Topic :: Communications :: Email',
+          'Topic :: Office/Business',
+          'Topic :: Software Development :: Bug Tracking',
+          ],
+      )
+\end{verbatim}
+
+If you wish to include classifiers in your \file{setup.py} file and also
+wish to remain backwards-compatible with Python releases prior to 2.2.3,
+then you can include the following code fragment in your \file{setup.py}
+before the \function{setup()} call.
+
+\begin{verbatim}
+# patch distutils if it can't cope with the "classifiers" or
+# "download_url" keywords
+from sys import version
+if version < '2.2.3':
+    from distutils.dist import DistributionMetadata
+    DistributionMetadata.classifiers = None
+    DistributionMetadata.download_url = None
+\end{verbatim}
+
+
+\section{Debugging the setup script}
+
+Sometimes things go wrong, and the setup script doesn't do what the
+developer wants.
+
+Distutils catches any exceptions when running the setup script, and
+print a simple error message before the script is terminated.  The
+motivation for this behaviour is to not confuse administrators who
+don't know much about Python and are trying to install a package.  If
+they get a big long traceback from deep inside the guts of Distutils,
+they may think the package or the Python installation is broken
+because they don't read all the way down to the bottom and see that
+it's a permission problem.
+
+On the other hand, this doesn't help the developer to find the cause
+of the failure. For this purpose, the DISTUTILS_DEBUG environment
+variable can be set to anything except an empty string, and distutils
+will now print detailed information what it is doing, and prints the
+full traceback in case an exception occurs.
+
+\chapter{Writing the Setup Configuration File}
+\label{setup-config}
+
+Often, it's not possible to write down everything needed to build a
+distribution \emph{a priori}: you may need to get some information from
+the user, or from the user's system, in order to proceed.  As long as
+that information is fairly simple---a list of directories to search for
+C header files or libraries, for example---then providing a
+configuration file, \file{setup.cfg}, for users to edit is a cheap and
+easy way to solicit it.  Configuration files also let you provide
+default values for any command option, which the installer can then
+override either on the command-line or by editing the config file.
+
+% (If you have more advanced needs, such as determining which extensions
+% to build based on what capabilities are present on the target system,
+% then you need the Distutils ``auto-configuration'' facility.  This
+% started to appear in Distutils 0.9 but, as of this writing, isn't mature 
+% or stable enough yet for real-world use.)
+
+The setup configuration file is a useful middle-ground between the setup
+script---which, ideally, would be opaque to installers\footnote{This
+  ideal probably won't be achieved until auto-configuration is fully
+  supported by the Distutils.}---and the command-line to the setup
+script, which is outside of your control and entirely up to the
+installer.  In fact, \file{setup.cfg} (and any other Distutils
+configuration files present on the target system) are processed after
+the contents of the setup script, but before the command-line.  This has 
+several useful consequences:
+\begin{itemize}
+\item installers can override some of what you put in \file{setup.py} by
+  editing \file{setup.cfg}
+\item you can provide non-standard defaults for options that are not
+  easily set in \file{setup.py}
+\item installers can override anything in \file{setup.cfg} using the
+  command-line options to \file{setup.py}
+\end{itemize}
+
+The basic syntax of the configuration file is simple:
+
+\begin{verbatim}
+[command]
+option=value
+...
+\end{verbatim}
+
+where \var{command} is one of the Distutils commands (e.g.
+\command{build\_py}, \command{install}), and \var{option} is one of
+the options that command supports.  Any number of options can be
+supplied for each command, and any number of command sections can be
+included in the file.  Blank lines are ignored, as are comments, which
+run from a \character{\#} character until the end of the line.  Long
+option values can be split across multiple lines simply by indenting
+the continuation lines.
+
+You can find out the list of options supported by a particular command
+with the universal \longprogramopt{help} option, e.g.
+
+\begin{verbatim}
+> python setup.py --help build_ext
+[...]
+Options for 'build_ext' command:
+  --build-lib (-b)     directory for compiled extension modules
+  --build-temp (-t)    directory for temporary files (build by-products)
+  --inplace (-i)       ignore build-lib and put compiled extensions into the
+                       source directory alongside your pure Python modules
+  --include-dirs (-I)  list of directories to search for header files
+  --define (-D)        C preprocessor macros to define
+  --undef (-U)         C preprocessor macros to undefine
+[...]
+\end{verbatim}
+
+Note that an option spelled \longprogramopt{foo-bar} on the command-line 
+is spelled \option{foo\_bar} in configuration files.
+
+For example, say you want your extensions to be built
+``in-place''---that is, you have an extension \module{pkg.ext}, and you
+want the compiled extension file (\file{ext.so} on \UNIX, say) to be put
+in the same source directory as your pure Python modules
+\module{pkg.mod1} and \module{pkg.mod2}.  You can always use the
+\longprogramopt{inplace} option on the command-line to ensure this:
+
+\begin{verbatim}
+python setup.py build_ext --inplace
+\end{verbatim}
+
+But this requires that you always specify the \command{build\_ext}
+command explicitly, and remember to provide \longprogramopt{inplace}.
+An easier way is to ``set and forget'' this option, by encoding it in
+\file{setup.cfg}, the configuration file for this distribution:
+
+\begin{verbatim}
+[build_ext]
+inplace=1
+\end{verbatim}
+
+This will affect all builds of this module distribution, whether or not
+you explicitly specify \command{build\_ext}.  If you include
+\file{setup.cfg} in your source distribution, it will also affect
+end-user builds---which is probably a bad idea for this option, since
+always building extensions in-place would break installation of the
+module distribution.  In certain peculiar cases, though, modules are
+built right in their installation directory, so this is conceivably a
+useful ability.  (Distributing extensions that expect to be built in
+their installation directory is almost always a bad idea, though.)
+
+Another example: certain commands take a lot of options that don't
+change from run to run; for example, \command{bdist\_rpm} needs to know
+everything required to generate a ``spec'' file for creating an RPM
+distribution.  Some of this information comes from the setup script, and
+some is automatically generated by the Distutils (such as the list of
+files installed).  But some of it has to be supplied as options to
+\command{bdist\_rpm}, which would be very tedious to do on the
+command-line for every run.  Hence, here is a snippet from the
+Distutils' own \file{setup.cfg}:
+
+\begin{verbatim}
+[bdist_rpm]
+release = 1
+packager = Greg Ward <gward at python.net>
+doc_files = CHANGES.txt
+            README.txt
+            USAGE.txt
+            doc/
+            examples/
+\end{verbatim}
+
+Note that the \option{doc\_files} option is simply a
+whitespace-separated string split across multiple lines for readability.
+
+
+\begin{seealso}
+  \seetitle[../inst/config-syntax.html]{Installing Python
+            Modules}{More information on the configuration files is
+            available in the manual for system administrators.}
+\end{seealso}
+
+
+\chapter{Creating a Source Distribution}
+\label{source-dist}
+
+As shown in section~\ref{simple-example}, you use the
+\command{sdist} command to create a source distribution.  In the
+simplest case,
+
+\begin{verbatim}
+python setup.py sdist
+\end{verbatim}
+
+(assuming you haven't specified any \command{sdist} options in the setup
+script or config file), \command{sdist} creates the archive of the
+default format for the current platform.  The default format is a gzip'ed
+tar file (\file{.tar.gz}) on \UNIX, and ZIP file on Windows.
+
+You can specify as many formats as you like using the
+\longprogramopt{formats} option, for example:
+
+\begin{verbatim}
+python setup.py sdist --formats=gztar,zip
+\end{verbatim}
+
+to create a gzipped tarball and a zip file.  The available formats are:
+
+\begin{tableiii}{l|l|c}{code}%
+  {Format}{Description}{Notes}
+  \lineiii{zip}{zip file (\file{.zip})}{(1),(3)}
+  \lineiii{gztar}{gzip'ed tar file (\file{.tar.gz})}{(2),(4)}
+  \lineiii{bztar}{bzip2'ed tar file (\file{.tar.bz2})}{(4)}
+  \lineiii{ztar}{compressed tar file (\file{.tar.Z})}{(4)}
+  \lineiii{tar}{tar file (\file{.tar})}{(4)}
+\end{tableiii}
+
+\noindent Notes:
+\begin{description}
+\item[(1)] default on Windows
+\item[(2)] default on \UNIX
+\item[(3)] requires either external \program{zip} utility or
+  \module{zipfile} module (part of the standard Python library since
+  Python~1.6)
+\item[(4)] requires external utilities: \program{tar} and possibly one
+  of \program{gzip}, \program{bzip2}, or \program{compress}
+\end{description}
+
+
+
+\section{Specifying the files to distribute}
+\label{manifest}
+
+If you don't supply an explicit list of files (or instructions on how to
+generate one), the \command{sdist} command puts a minimal default set
+into the source distribution:
+\begin{itemize}
+\item all Python source files implied by the \option{py\_modules} and
+  \option{packages} options
+\item all C source files mentioned in the \option{ext\_modules} or
+  \option{libraries} options (\XXX{getting C library sources currently
+    broken---no \method{get_source_files()} method in \file{build_clib.py}!})
+\item scripts identified by the \option{scripts} option
+\item anything that looks like a test script: \file{test/test*.py}
+  (currently, the Distutils don't do anything with test scripts except
+  include them in source distributions, but in the future there will be
+  a standard for testing Python module distributions)
+\item \file{README.txt} (or \file{README}), \file{setup.py} (or whatever 
+  you called your setup script), and \file{setup.cfg}
+\end{itemize}
+
+Sometimes this is enough, but usually you will want to specify
+additional files to distribute.  The typical way to do this is to write
+a \emph{manifest template}, called \file{MANIFEST.in} by default.  The
+manifest template is just a list of instructions for how to generate
+your manifest file, \file{MANIFEST}, which is the exact list of files to
+include in your source distribution.  The \command{sdist} command
+processes this template and generates a manifest based on its
+instructions and what it finds in the filesystem.
+
+If you prefer to roll your own manifest file, the format is simple: one
+filename per line, regular files (or symlinks to them) only.  If you do
+supply your own \file{MANIFEST}, you must specify everything: the
+default set of files described above does not apply in this case.
+
+The manifest template has one command per line, where each command
+specifies a set of files to include or exclude from the source
+distribution.  For an example, again we turn to the Distutils' own
+manifest template:
+
+\begin{verbatim}
+include *.txt
+recursive-include examples *.txt *.py
+prune examples/sample?/build
+\end{verbatim}
+
+The meanings should be fairly clear: include all files in the
+distribution root matching \file{*.txt}, all files anywhere under the
+\file{examples} directory matching \file{*.txt} or \file{*.py}, and
+exclude all directories matching \file{examples/sample?/build}.  All of
+this is done \emph{after} the standard include set, so you can exclude
+files from the standard set with explicit instructions in the manifest
+template.  (Or, you can use the \longprogramopt{no-defaults} option to
+disable the standard set entirely.)  There are several other commands
+available in the manifest template mini-language; see
+section~\ref{sdist-cmd}.
+
+The order of commands in the manifest template matters: initially, we
+have the list of default files as described above, and each command in
+the template adds to or removes from that list of files.  Once we have
+fully processed the manifest template, we remove files that should not
+be included in the source distribution:
+\begin{itemize}
+\item all files in the Distutils ``build'' tree (default \file{build/})
+\item all files in directories named \file{RCS}, \file{CVS} or \file{.svn}
+\end{itemize}
+Now we have our complete list of files, which is written to the manifest
+for future reference, and then used to build the source distribution
+archive(s).
+
+You can disable the default set of included files with the
+\longprogramopt{no-defaults} option, and you can disable the standard
+exclude set with \longprogramopt{no-prune}.
+
+Following the Distutils' own manifest template, let's trace how the
+\command{sdist} command builds the list of files to include in the
+Distutils source distribution:
+\begin{enumerate}
+\item include all Python source files in the \file{distutils} and
+  \file{distutils/command} subdirectories (because packages
+  corresponding to those two directories were mentioned in the
+  \option{packages} option in the setup script---see
+  section~\ref{setup-script})
+\item include \file{README.txt}, \file{setup.py}, and \file{setup.cfg}
+  (standard files)
+\item include \file{test/test*.py} (standard files)
+\item include \file{*.txt} in the distribution root (this will find
+  \file{README.txt} a second time, but such redundancies are weeded out
+  later)
+\item include anything matching \file{*.txt} or \file{*.py} in the
+  sub-tree under \file{examples},
+\item exclude all files in the sub-trees starting at directories
+  matching \file{examples/sample?/build}---this may exclude files
+  included by the previous two steps, so it's important that the
+  \code{prune} command in the manifest template comes after the
+  \code{recursive-include} command
+\item exclude the entire \file{build} tree, and any \file{RCS},
+  \file{CVS} and \file{.svn} directories
+\end{enumerate}
+Just like in the setup script, file and directory names in the manifest
+template should always be slash-separated; the Distutils will take care
+of converting them to the standard representation on your platform.
+That way, the manifest template is portable across operating systems.
+
+
+\section{Manifest-related options}
+\label{manifest-options}
+
+The normal course of operations for the \command{sdist} command is as
+follows:
+\begin{itemize}
+\item if the manifest file, \file{MANIFEST} doesn't exist, read
+  \file{MANIFEST.in} and create the manifest
+\item if neither \file{MANIFEST} nor \file{MANIFEST.in} exist, create a
+  manifest with just the default file set
+\item if either \file{MANIFEST.in} or the setup script (\file{setup.py})
+  are more recent than \file{MANIFEST}, recreate \file{MANIFEST} by
+  reading \file{MANIFEST.in}
+\item use the list of files now in \file{MANIFEST} (either just
+  generated or read in) to create the source distribution archive(s)
+\end{itemize}
+There are a couple of options that modify this behaviour.  First, use
+the \longprogramopt{no-defaults} and \longprogramopt{no-prune} to
+disable the standard ``include'' and ``exclude'' sets.
+
+Second, you might want to force the manifest to be regenerated---for
+example, if you have added or removed files or directories that match an
+existing pattern in the manifest template, you should regenerate the
+manifest:
+
+\begin{verbatim}
+python setup.py sdist --force-manifest
+\end{verbatim}
+
+Or, you might just want to (re)generate the manifest, but not create a
+source distribution:
+
+\begin{verbatim}
+python setup.py sdist --manifest-only
+\end{verbatim}
+
+\longprogramopt{manifest-only} implies \longprogramopt{force-manifest}.
+\programopt{-o} is a shortcut for \longprogramopt{manifest-only}, and
+\programopt{-f} for \longprogramopt{force-manifest}.
+
+
+\chapter{Creating Built Distributions}
+\label{built-dist}
+
+A ``built distribution'' is what you're probably used to thinking of
+either as a ``binary package'' or an ``installer'' (depending on your
+background).  It's not necessarily binary, though, because it might
+contain only Python source code and/or byte-code; and we don't call it a
+package, because that word is already spoken for in Python.  (And
+``installer'' is a term specific to the world of mainstream desktop
+systems.)
+
+A built distribution is how you make life as easy as possible for
+installers of your module distribution: for users of RPM-based Linux
+systems, it's a binary RPM; for Windows users, it's an executable
+installer; for Debian-based Linux users, it's a Debian package; and so
+forth.  Obviously, no one person will be able to create built
+distributions for every platform under the sun, so the Distutils are
+designed to enable module developers to concentrate on their
+specialty---writing code and creating source distributions---while an
+intermediary species called \emph{packagers} springs up to turn source
+distributions into built distributions for as many platforms as there
+are packagers.
+
+Of course, the module developer could be his own packager; or the
+packager could be a volunteer ``out there'' somewhere who has access to
+a platform which the original developer does not; or it could be
+software periodically grabbing new source distributions and turning them
+into built distributions for as many platforms as the software has
+access to.  Regardless of who they are, a packager uses the
+setup script and the \command{bdist} command family to generate built
+distributions.
+
+As a simple example, if I run the following command in the Distutils
+source tree:
+
+\begin{verbatim}
+python setup.py bdist
+\end{verbatim}
+
+then the Distutils builds my module distribution (the Distutils itself
+in this case), does a ``fake'' installation (also in the \file{build}
+directory), and creates the default type of built distribution for my
+platform.  The default format for built distributions is a ``dumb'' tar
+file on \UNIX, and a simple executable installer on Windows.  (That tar
+file is considered ``dumb'' because it has to be unpacked in a specific
+location to work.)
+
+Thus, the above command on a \UNIX{} system creates
+\file{Distutils-1.0.\filevar{plat}.tar.gz}; unpacking this tarball
+from the right place installs the Distutils just as though you had
+downloaded the source distribution and run \code{python setup.py
+  install}.  (The ``right place'' is either the root of the filesystem or 
+Python's \filevar{prefix} directory, depending on the options given to
+the \command{bdist\_dumb} command; the default is to make dumb
+distributions relative to \filevar{prefix}.)  
+
+Obviously, for pure Python distributions, this isn't any simpler than
+just running \code{python setup.py install}---but for non-pure
+distributions, which include extensions that would need to be
+compiled, it can mean the difference between someone being able to use
+your extensions or not.  And creating ``smart'' built distributions,
+such as an RPM package or an executable installer for Windows, is far
+more convenient for users even if your distribution doesn't include
+any extensions.
+
+The \command{bdist} command has a \longprogramopt{formats} option,
+similar to the \command{sdist} command, which you can use to select the
+types of built distribution to generate: for example,
+
+\begin{verbatim}
+python setup.py bdist --format=zip
+\end{verbatim}
+
+would, when run on a \UNIX{} system, create
+\file{Distutils-1.0.\filevar{plat}.zip}---again, this archive would be
+unpacked from the root directory to install the Distutils.
+
+The available formats for built distributions are:
+
+\begin{tableiii}{l|l|c}{code}%
+  {Format}{Description}{Notes}
+  \lineiii{gztar}{gzipped tar file (\file{.tar.gz})}{(1),(3)}
+  \lineiii{ztar}{compressed tar file (\file{.tar.Z})}{(3)}
+  \lineiii{tar}{tar file (\file{.tar})}{(3)}
+  \lineiii{zip}{zip file (\file{.zip})}{(4)}
+  \lineiii{rpm}{RPM}{(5)}
+  \lineiii{pkgtool}{Solaris \program{pkgtool}}{}
+  \lineiii{sdux}{HP-UX \program{swinstall}}{}
+  \lineiii{rpm}{RPM}{(5)}
+%  \lineiii{srpm}{source RPM}{(5) \XXX{to do!}}
+  \lineiii{wininst}{self-extracting ZIP file for Windows}{(2),(4)}
+\end{tableiii}
+
+\noindent Notes:
+\begin{description}
+\item[(1)] default on \UNIX
+\item[(2)] default on Windows \XXX{to-do!}
+\item[(3)] requires external utilities: \program{tar} and possibly one
+  of \program{gzip}, \program{bzip2}, or \program{compress}
+\item[(4)] requires either external \program{zip} utility or
+  \module{zipfile} module (part of the standard Python library since
+  Python~1.6)
+\item[(5)] requires external \program{rpm} utility, version 3.0.4 or
+  better (use \code{rpm --version} to find out which version you have)
+\end{description}
+
+You don't have to use the \command{bdist} command with the
+\longprogramopt{formats} option; you can also use the command that
+directly implements the format you're interested in.  Some of these
+\command{bdist} ``sub-commands'' actually generate several similar
+formats; for instance, the \command{bdist\_dumb} command generates all
+the ``dumb'' archive formats (\code{tar}, \code{ztar}, \code{gztar}, and
+\code{zip}), and \command{bdist\_rpm} generates both binary and source
+RPMs.  The \command{bdist} sub-commands, and the formats generated by
+each, are:
+
+\begin{tableii}{l|l}{command}%
+  {Command}{Formats}
+  \lineii{bdist\_dumb}{tar, ztar, gztar, zip}
+  \lineii{bdist\_rpm}{rpm, srpm}
+  \lineii{bdist\_wininst}{wininst}
+\end{tableii}
+
+The following sections give details on the individual \command{bdist\_*}
+commands.
+
+
+\section{Creating dumb built distributions}
+\label{creating-dumb}
+
+\XXX{Need to document absolute vs. prefix-relative packages here, but
+  first I have to implement it!}
+
+
+\section{Creating RPM packages}
+\label{creating-rpms}
+
+The RPM format is used by many popular Linux distributions, including
+Red Hat, SuSE, and Mandrake.  If one of these (or any of the other
+RPM-based Linux distributions) is your usual environment, creating RPM
+packages for other users of that same distribution is trivial.
+Depending on the complexity of your module distribution and differences
+between Linux distributions, you may also be able to create RPMs that
+work on different RPM-based distributions.
+
+The usual way to create an RPM of your module distribution is to run the 
+\command{bdist\_rpm} command:
+
+\begin{verbatim}
+python setup.py bdist_rpm
+\end{verbatim}
+
+or the \command{bdist} command with the \longprogramopt{format} option:
+
+\begin{verbatim}
+python setup.py bdist --formats=rpm
+\end{verbatim}
+
+The former allows you to specify RPM-specific options; the latter allows 
+you to easily specify multiple formats in one run.  If you need to do
+both, you can explicitly specify multiple \command{bdist\_*} commands
+and their options:
+
+\begin{verbatim}
+python setup.py bdist_rpm --packager="John Doe <jdoe at example.org>" \
+                bdist_wininst --target_version="2.0"
+\end{verbatim}
+
+Creating RPM packages is driven by a \file{.spec} file, much as using
+the Distutils is driven by the setup script.  To make your life easier,
+the \command{bdist\_rpm} command normally creates a \file{.spec} file
+based on the information you supply in the setup script, on the command
+line, and in any Distutils configuration files.  Various options and
+sections in the \file{.spec} file are derived from options in the setup
+script as follows:
+
+\begin{tableii}{l|l}{textrm}%
+  {RPM \file{.spec} file option or section}{Distutils setup script option}
+  \lineii{Name}{\option{name}}
+  \lineii{Summary (in preamble)}{\option{description}}
+  \lineii{Version}{\option{version}}
+  \lineii{Vendor}{\option{author} and \option{author\_email}, or \\&
+                  \option{maintainer} and \option{maintainer\_email}}
+  \lineii{Copyright}{\option{licence}}
+  \lineii{Url}{\option{url}}
+  \lineii{\%description (section)}{\option{long\_description}}
+\end{tableii}
+
+Additionally, there are many options in \file{.spec} files that don't have
+corresponding options in the setup script.  Most of these are handled
+through options to the \command{bdist\_rpm} command as follows:
+
+\begin{tableiii}{l|l|l}{textrm}%
+  {RPM \file{.spec} file option or section}%
+  {\command{bdist\_rpm} option}%
+  {default value}
+  \lineiii{Release}{\option{release}}{``1''}
+  \lineiii{Group}{\option{group}}{``Development/Libraries''}
+  \lineiii{Vendor}{\option{vendor}}{(see above)}
+  \lineiii{Packager}{\option{packager}}{(none)}
+  \lineiii{Provides}{\option{provides}}{(none)}
+  \lineiii{Requires}{\option{requires}}{(none)}
+  \lineiii{Conflicts}{\option{conflicts}}{(none)}
+  \lineiii{Obsoletes}{\option{obsoletes}}{(none)}
+  \lineiii{Distribution}{\option{distribution\_name}}{(none)}
+  \lineiii{BuildRequires}{\option{build\_requires}}{(none)}
+  \lineiii{Icon}{\option{icon}}{(none)}
+\end{tableiii}
+
+Obviously, supplying even a few of these options on the command-line
+would be tedious and error-prone, so it's usually best to put them in
+the setup configuration file, \file{setup.cfg}---see
+section~\ref{setup-config}.  If you distribute or package many Python
+module distributions, you might want to put options that apply to all of
+them in your personal Distutils configuration file
+(\file{\textasciitilde/.pydistutils.cfg}).
+
+There are three steps to building a binary RPM package, all of which are 
+handled automatically by the Distutils:
+
+\begin{enumerate}
+\item create a \file{.spec} file, which describes the package (analogous 
+  to the Distutils setup script; in fact, much of the information in the 
+  setup script winds up in the \file{.spec} file)
+\item create the source RPM
+\item create the ``binary'' RPM (which may or may not contain binary
+  code, depending on whether your module distribution contains Python
+  extensions)
+\end{enumerate}
+
+Normally, RPM bundles the last two steps together; when you use the
+Distutils, all three steps are typically bundled together.
+
+If you wish, you can separate these three steps.  You can use the
+\longprogramopt{spec-only} option to make \command{bdist_rpm} just
+create the \file{.spec} file and exit; in this case, the \file{.spec}
+file will be written to the ``distribution directory''---normally
+\file{dist/}, but customizable with the \longprogramopt{dist-dir}
+option.  (Normally, the \file{.spec} file winds up deep in the ``build
+tree,'' in a temporary directory created by \command{bdist_rpm}.)
+
+% \XXX{this isn't implemented yet---is it needed?!}
+% You can also specify a custom \file{.spec} file with the
+% \longprogramopt{spec-file} option; used in conjunction with
+% \longprogramopt{spec-only}, this gives you an opportunity to customize
+% the \file{.spec} file manually:
+%
+% \ begin{verbatim}
+% > python setup.py bdist_rpm --spec-only
+% # ...edit dist/FooBar-1.0.spec
+% > python setup.py bdist_rpm --spec-file=dist/FooBar-1.0.spec
+% \ end{verbatim}
+%
+% (Although a better way to do this is probably to override the standard
+% \command{bdist\_rpm} command with one that writes whatever else you want
+% to the \file{.spec} file.)
+
+
+\section{Creating Windows Installers}
+\label{creating-wininst}
+
+Executable installers are the natural format for binary distributions
+on Windows.  They display a nice graphical user interface, display
+some information about the module distribution to be installed taken
+from the metadata in the setup script, let the user select a few
+options, and start or cancel the installation.
+
+Since the metadata is taken from the setup script, creating Windows
+installers is usually as easy as running:
+
+\begin{verbatim}
+python setup.py bdist_wininst
+\end{verbatim}
+
+or the \command{bdist} command with the \longprogramopt{formats} option:
+
+\begin{verbatim}
+python setup.py bdist --formats=wininst
+\end{verbatim}
+
+If you have a pure module distribution (only containing pure Python
+modules and packages), the resulting installer will be version
+independent and have a name like \file{foo-1.0.win32.exe}.  These
+installers can even be created on \UNIX{} or Mac OS platforms.
+
+If you have a non-pure distribution, the extensions can only be
+created on a Windows platform, and will be Python version dependent.
+The installer filename will reflect this and now has the form
+\file{foo-1.0.win32-py2.0.exe}.  You have to create a separate installer
+for every Python version you want to support.
+
+The installer will try to compile pure modules into bytecode after
+installation on the target system in normal and optimizing mode.  If
+you don't want this to happen for some reason, you can run the
+\command{bdist_wininst} command with the
+\longprogramopt{no-target-compile} and/or the
+\longprogramopt{no-target-optimize} option.
+
+By default the installer will display the cool ``Python Powered'' logo
+when it is run, but you can also supply your own bitmap which must be
+a Windows \file{.bmp} file with the \longprogramopt{bitmap} option.
+
+The installer will also display a large title on the desktop
+background window when it is run, which is constructed from the name
+of your distribution and the version number.  This can be changed to
+another text by using the \longprogramopt{title} option.
+
+The installer file will be written to the ``distribution directory''
+--- normally \file{dist/}, but customizable with the
+\longprogramopt{dist-dir} option.
+
+\subsection{The Postinstallation script}
+\label{postinstallation-script}
+
+Starting with Python 2.3, a postinstallation script can be specified
+which the \longprogramopt{install-script} option.  The basename of the
+script must be specified, and the script filename must also be listed
+in the scripts argument to the setup function.
+
+This script will be run at installation time on the target system
+after all the files have been copied, with \code{argv[1]} set to
+\programopt{-install}, and again at uninstallation time before the
+files are removed with \code{argv[1]} set to \programopt{-remove}.
+
+The installation script runs embedded in the windows installer, every
+output (\code{sys.stdout}, \code{sys.stderr}) is redirected into a
+buffer and will be displayed in the GUI after the script has finished.
+
+Some functions especially useful in this context are available as
+additional built-in functions in the installation script.
+
+\begin{funcdesc}{directory_created}{path}
+\funcline{file_created}{path}
+  These functions should be called when a directory or file is created
+  by the postinstall script at installation time.  It will register
+  \var{path} with the uninstaller, so that it will be removed when the
+  distribution is uninstalled.  To be safe, directories are only removed
+  if they are empty.
+\end{funcdesc}
+
+\begin{funcdesc}{get_special_folder_path}{csidl_string}
+  This function can be used to retrieve special folder locations on
+  Windows like the Start Menu or the Desktop.  It returns the full
+  path to the folder.  \var{csidl_string} must be one of the following
+  strings:
+
+\begin{verbatim}
+"CSIDL_APPDATA"
+
+"CSIDL_COMMON_STARTMENU"
+"CSIDL_STARTMENU"
+
+"CSIDL_COMMON_DESKTOPDIRECTORY"
+"CSIDL_DESKTOPDIRECTORY"
+
+"CSIDL_COMMON_STARTUP"
+"CSIDL_STARTUP"
+
+"CSIDL_COMMON_PROGRAMS"
+"CSIDL_PROGRAMS"
+
+"CSIDL_FONTS"
+\end{verbatim}
+
+  If the folder cannot be retrieved, \exception{OSError} is raised.
+
+  Which folders are available depends on the exact Windows version,
+  and probably also the configuration.  For details refer to
+  Microsoft's documentation of the
+  \cfunction{SHGetSpecialFolderPath()} function.
+\end{funcdesc}
+
+\begin{funcdesc}{create_shortcut}{target, description,
+                                  filename\optional{,
+                                  arguments\optional{,
+                                  workdir\optional{,
+                                  iconpath\optional{, iconindex}}}}}
+  This function creates a shortcut.
+  \var{target} is the path to the program to be started by the shortcut.
+  \var{description} is the description of the shortcut.
+  \var{filename} is the title of the shortcut that the user will see.
+  \var{arguments} specifies the command line arguments, if any.
+  \var{workdir} is the working directory for the program.
+  \var{iconpath} is the file containing the icon for the shortcut,
+  and \var{iconindex} is the index of the icon in the file
+  \var{iconpath}.  Again, for details consult the Microsoft
+  documentation for the \class{IShellLink} interface.
+\end{funcdesc}
+
+\chapter{Registering with the Package Index}
+\label{package-index}
+
+The Python Package Index (PyPI) holds meta-data describing distributions
+packaged with distutils. The distutils command \command{register} is
+used to submit your distribution's meta-data to the index. It is invoked
+as follows:
+
+\begin{verbatim}
+python setup.py register
+\end{verbatim}
+
+Distutils will respond with the following prompt:
+
+\begin{verbatim}
+running register
+We need to know who you are, so please choose either:
+ 1. use your existing login,
+ 2. register as a new user,
+ 3. have the server generate a new password for you (and email it to you), or
+ 4. quit
+Your selection [default 1]:
+\end{verbatim}
+
+\noindent Note: if your username and password are saved locally, you will
+not see this menu.
+
+If you have not registered with PyPI, then you will need to do so now. You
+should choose option 2, and enter your details as required. Soon after
+submitting your details, you will receive an email which will be used to
+confirm your registration.
+
+Once you are registered, you may choose option 1 from the menu. You will
+be prompted for your PyPI username and password, and \command{register}
+will then submit your meta-data to the index.
+
+You may submit any number of versions of your distribution to the index. If
+you alter the meta-data for a particular version, you may submit it again
+and the index will be updated.
+
+PyPI holds a record for each (name, version) combination submitted. The
+first user to submit information for a given name is designated the Owner
+of that name. They may submit changes through the \command{register}
+command or through the web interface. They may also designate other users
+as Owners or Maintainers. Maintainers may edit the package information, but
+not designate other Owners or Maintainers.
+
+By default PyPI will list all versions of a given package. To hide certain
+versions, the Hidden property should be set to yes. This must be edited
+through the web interface.
+
+\section{The .pypirc file}
+\label{pypirc}
+
+The format of the \file{.pypirc} file is formated as follows:
+
+\begin{verbatim}
+[server-login]
+repository: <repository-url>
+username: <username>
+password: <password>
+\end{verbatim}
+
+\var{repository} can be ommitted and defaults to
+\code{http://www.python.org/pypi}.
+
+\chapter{Uploading Packages to the Package Index}
+\label{package-upload}
+
+\versionadded{2.5}
+
+The Python Package Index (PyPI) not only stores the package info, but also 
+the package data if the author of the package wishes to. The distutils
+command \command{upload} pushes the distribution files to PyPI.
+
+The command is invoked immediately after building one or more distribution
+files.  For example, the command
+
+\begin{verbatim}
+python setup.py sdist bdist_wininst upload
+\end{verbatim}
+
+will cause the source distribution and the Windows installer to be
+uploaded to PyPI.  Note that these will be uploaded even if they are
+built using an earlier invocation of \file{setup.py}, but that only
+distributions named on the command line for the invocation including
+the \command{upload} command are uploaded.
+
+The \command{upload} command uses the username, password, and repository
+URL from the \file{\$HOME/.pypirc} file (see section~\ref{pypirc} for
+more on this file).
+
+You can use the \longprogramopt{sign} option to tell \command{upload} to
+sign each uploaded file using GPG (GNU Privacy Guard).  The 
+\program{gpg} program must be available for execution on the system
+\envvar{PATH}.  You can also specify which key to use for signing
+using the \longprogramopt{identity=\var{name}} option.
+
+Other \command{upload} options include 
+\longprogramopt{repository=\var{url}} (which lets you override the
+repository setting from \file{\$HOME/.pypirc}), and
+\longprogramopt{show-response} (which displays the full response text
+from the PyPI server for help in debugging upload problems).
+
+\chapter{Examples}
+\label{examples}
+
+This chapter provides a number of basic examples to help get started
+with distutils.  Additional information about using distutils can be
+found in the Distutils Cookbook.
+
+\begin{seealso}
+  \seelink{http://www.python.org/cgi-bin/moinmoin/DistutilsCookbook}
+          {Distutils Cookbook}
+          {Collection of recipes showing how to achieve more control
+           over distutils.}
+\end{seealso}
+
+
+\section{Pure Python distribution (by module)}
+\label{pure-mod}
+
+If you're just distributing a couple of modules, especially if they
+don't live in a particular package, you can specify them individually
+using the \option{py\_modules} option in the setup script.
+
+In the simplest case, you'll have two files to worry about: a setup
+script and the single module you're distributing, \file{foo.py} in this
+example:
+\begin{verbatim}
+<root>/
+        setup.py
+        foo.py
+\end{verbatim}
+(In all diagrams in this section, \verb|<root>| will refer to the
+distribution root directory.)  A minimal setup script to describe this
+situation would be:
+\begin{verbatim}
+from distutils.core import setup
+setup(name='foo',
+      version='1.0',
+      py_modules=['foo'],
+      )
+\end{verbatim}
+Note that the name of the distribution is specified independently with
+the \option{name} option, and there's no rule that says it has to be the
+same as the name of the sole module in the distribution (although that's
+probably a good convention to follow).  However, the distribution name
+is used to generate filenames, so you should stick to letters, digits,
+underscores, and hyphens.
+
+Since \option{py\_modules} is a list, you can of course specify multiple 
+modules, eg. if you're distributing modules \module{foo} and
+\module{bar}, your setup might look like this:
+\begin{verbatim}
+<root>/
+        setup.py
+        foo.py
+        bar.py
+\end{verbatim}
+and the setup script might be
+\begin{verbatim}
+from distutils.core import setup
+setup(name='foobar',
+      version='1.0',
+      py_modules=['foo', 'bar'],
+      )
+\end{verbatim}
+
+You can put module source files into another directory, but if you have
+enough modules to do that, it's probably easier to specify modules by
+package rather than listing them individually.
+
+
+\section{Pure Python distribution (by package)}
+\label{pure-pkg}
+
+If you have more than a couple of modules to distribute, especially if
+they are in multiple packages, it's probably easier to specify whole
+packages rather than individual modules.  This works even if your
+modules are not in a package; you can just tell the Distutils to process
+modules from the root package, and that works the same as any other
+package (except that you don't have to have an \file{\_\_init\_\_.py}
+file).
+
+The setup script from the last example could also be written as
+\begin{verbatim}
+from distutils.core import setup
+setup(name='foobar',
+      version='1.0',
+      packages=[''],
+      )
+\end{verbatim}
+(The empty string stands for the root package.)
+
+If those two files are moved into a subdirectory, but remain in the root
+package, e.g.:
+\begin{verbatim}
+<root>/
+        setup.py
+        src/      foo.py
+                  bar.py
+\end{verbatim}
+then you would still specify the root package, but you have to tell the
+Distutils where source files in the root package live:
+\begin{verbatim}
+from distutils.core import setup
+setup(name='foobar',
+      version='1.0',
+      package_dir={'': 'src'},
+      packages=[''],
+      )
+\end{verbatim}
+
+More typically, though, you will want to distribute multiple modules in
+the same package (or in sub-packages).  For example, if the \module{foo} 
+and \module{bar} modules belong in package \module{foobar}, one way to
+layout your source tree is
+\begin{verbatim}
+<root>/
+        setup.py
+        foobar/
+                 __init__.py
+                 foo.py
+                 bar.py
+\end{verbatim}
+This is in fact the default layout expected by the Distutils, and the
+one that requires the least work to describe in your setup script:
+\begin{verbatim}
+from distutils.core import setup
+setup(name='foobar',
+      version='1.0',
+      packages=['foobar'],
+      )
+\end{verbatim}
+
+If you want to put modules in directories not named for their package,
+then you need to use the \option{package\_dir} option again.  For
+example, if the \file{src} directory holds modules in the
+\module{foobar} package:
+\begin{verbatim}
+<root>/
+        setup.py
+        src/
+                 __init__.py
+                 foo.py
+                 bar.py
+\end{verbatim}
+an appropriate setup script would be
+\begin{verbatim}
+from distutils.core import setup
+setup(name='foobar',
+      version='1.0',
+      package_dir={'foobar': 'src'},
+      packages=['foobar'],
+      )
+\end{verbatim}
+
+Or, you might put modules from your main package right in the
+distribution root:
+\begin{verbatim}
+<root>/
+        setup.py
+        __init__.py
+        foo.py
+        bar.py
+\end{verbatim}
+in which case your setup script would be
+\begin{verbatim}
+from distutils.core import setup
+setup(name='foobar',
+      version='1.0',
+      package_dir={'foobar': ''},
+      packages=['foobar'],
+      )
+\end{verbatim}
+(The empty string also stands for the current directory.)
+
+If you have sub-packages, they must be explicitly listed in
+\option{packages}, but any entries in \option{package\_dir}
+automatically extend to sub-packages.  (In other words, the Distutils
+does \emph{not} scan your source tree, trying to figure out which
+directories correspond to Python packages by looking for
+\file{\_\_init\_\_.py} files.)  Thus, if the default layout grows a
+sub-package:
+\begin{verbatim}
+<root>/
+        setup.py
+        foobar/
+                 __init__.py
+                 foo.py
+                 bar.py
+                 subfoo/
+                           __init__.py
+                           blah.py
+\end{verbatim}
+then the corresponding setup script would be
+\begin{verbatim}
+from distutils.core import setup
+setup(name='foobar',
+      version='1.0',
+      packages=['foobar', 'foobar.subfoo'],
+      )
+\end{verbatim}
+(Again, the empty string in \option{package\_dir} stands for the current
+directory.)
+
+
+\section{Single extension module}
+\label{single-ext}
+
+Extension modules are specified using the \option{ext\_modules} option.
+\option{package\_dir} has no effect on where extension source files are
+found; it only affects the source for pure Python modules.  The simplest 
+case, a single extension module in a single C source file, is:
+\begin{verbatim}
+<root>/
+        setup.py
+        foo.c
+\end{verbatim}
+If the \module{foo} extension belongs in the root package, the setup
+script for this could be
+\begin{verbatim}
+from distutils.core import setup
+from distutils.extension import Extension
+setup(name='foobar',
+      version='1.0',
+      ext_modules=[Extension('foo', ['foo.c'])],
+      )
+\end{verbatim}
+
+If the extension actually belongs in a package, say \module{foopkg},
+then 
+
+With exactly the same source tree layout, this extension can be put in
+the \module{foopkg} package simply by changing the name of the
+extension:
+\begin{verbatim}
+from distutils.core import setup
+from distutils.extension import Extension
+setup(name='foobar',
+      version='1.0',
+      ext_modules=[Extension('foopkg.foo', ['foo.c'])],
+      )
+\end{verbatim}
+
+
+%\section{Multiple extension modules}
+%\label{multiple-ext}
+
+
+%\section{Putting it all together}
+
+
+\chapter{Extending Distutils \label{extending}}
+
+Distutils can be extended in various ways.  Most extensions take the
+form of new commands or replacements for existing commands.  New
+commands may be written to support new types of platform-specific
+packaging, for example, while replacements for existing commands may
+be made to modify details of how the command operates on a package.
+
+Most extensions of the distutils are made within \file{setup.py}
+scripts that want to modify existing commands; many simply add a few
+file extensions that should be copied into packages in addition to
+\file{.py} files as a convenience.
+
+Most distutils command implementations are subclasses of the
+\class{Command} class from \refmodule{distutils.cmd}.  New commands
+may directly inherit from \class{Command}, while replacements often
+derive from \class{Command} indirectly, directly subclassing the
+command they are replacing.  Commands are required to derive from
+\class{Command}.
+
+
+%\section{Extending existing commands}
+%\label{extend-existing}
+
+
+%\section{Writing new commands}
+%\label{new-commands}
+
+%\XXX{Would an uninstall command be a good example here?}
+
+\section{Integrating new commands}
+
+There are different ways to integrate new command implementations into
+distutils.  The most difficult is to lobby for the inclusion of the
+new features in distutils itself, and wait for (and require) a version
+of Python that provides that support.  This is really hard for many
+reasons.
+
+The most common, and possibly the most reasonable for most needs, is
+to include the new implementations with your \file{setup.py} script,
+and cause the \function{distutils.core.setup()} function use them:
+
+\begin{verbatim}
+from distutils.command.build_py import build_py as _build_py
+from distutils.core import setup
+
+class build_py(_build_py):
+    """Specialized Python source builder."""
+
+    # implement whatever needs to be different...
+
+setup(cmdclass={'build_py': build_py},
+      ...)
+\end{verbatim}
+
+This approach is most valuable if the new implementations must be used
+to use a particular package, as everyone interested in the package
+will need to have the new command implementation.
+
+Beginning with Python 2.4, a third option is available, intended to
+allow new commands to be added which can support existing
+\file{setup.py} scripts without requiring modifications to the Python
+installation.  This is expected to allow third-party extensions to
+provide support for additional packaging systems, but the commands can
+be used for anything distutils commands can be used for.  A new
+configuration option, \option{command\_packages} (command-line option
+\longprogramopt{command-packages}), can be used to specify additional
+packages to be searched for modules implementing commands.  Like all
+distutils options, this can be specified on the command line or in a
+configuration file.  This option can only be set in the
+\code{[global]} section of a configuration file, or before any
+commands on the command line.  If set in a configuration file, it can
+be overridden from the command line; setting it to an empty string on
+the command line causes the default to be used.  This should never be
+set in a configuration file provided with a package.
+
+This new option can be used to add any number of packages to the list
+of packages searched for command implementations; multiple package
+names should be separated by commas.  When not specified, the search
+is only performed in the \module{distutils.command} package.  When
+\file{setup.py} is run with the option
+\longprogramopt{command-packages} \programopt{distcmds,buildcmds},
+however, the packages \module{distutils.command}, \module{distcmds},
+and \module{buildcmds} will be searched in that order.  New commands
+are expected to be implemented in modules of the same name as the
+command by classes sharing the same name.  Given the example command
+line option above, the command \command{bdist\_openpkg} could be
+implemented by the class \class{distcmds.bdist_openpkg.bdist_openpkg}
+or \class{buildcmds.bdist_openpkg.bdist_openpkg}.
+
+\section{Adding new distribution types}
+
+Commands that create distributions (files in the \file{dist/}
+directory) need to add \code{(\var{command}, \var{filename})} pairs to
+\code{self.distribution.dist_files} so that \command{upload} can
+upload it to PyPI.  The \var{filename} in the pair contains no path
+information, only the name of the file itself.  In dry-run mode, pairs
+should still be added to represent what would have been created.
+
+\chapter{Command Reference}
+\label{reference}
+
+
+%\section{Building modules: the \protect\command{build} command family}
+%\label{build-cmds}
+
+%\subsubsection{\protect\command{build}}
+%\label{build-cmd}
+
+%\subsubsection{\protect\command{build\_py}}
+%\label{build-py-cmd}
+
+%\subsubsection{\protect\command{build\_ext}}
+%\label{build-ext-cmd}
+
+%\subsubsection{\protect\command{build\_clib}}
+%\label{build-clib-cmd}
+
+
+\section{Installing modules: the \protect\command{install} command family}
+\label{install-cmd}
+
+The install command ensures that the build commands have been run and then
+runs the subcommands \command{install\_lib},
+\command{install\_data} and
+\command{install\_scripts}.
+
+%\subsubsection{\protect\command{install\_lib}}
+%\label{install-lib-cmd}
+
+\subsection{\protect\command{install\_data}}
+\label{install-data-cmd}
+This command installs all data files provided with the distribution.
+
+\subsection{\protect\command{install\_scripts}}
+\label{install-scripts-cmd}
+This command installs all (Python) scripts in the distribution.
+
+
+%\subsection{Cleaning up: the \protect\command{clean} command}
+%\label{clean-cmd}
+
+
+\section{Creating a source distribution: the
+            \protect\command{sdist} command}
+\label{sdist-cmd}
+
+
+\XXX{fragment moved down from above: needs context!}
+
+The manifest template commands are:
+
+\begin{tableii}{ll}{command}{Command}{Description}
+  \lineii{include \var{pat1} \var{pat2} ... }
+    {include all files matching any of the listed patterns}
+  \lineii{exclude \var{pat1} \var{pat2} ... }
+    {exclude all files matching any of the listed patterns}
+  \lineii{recursive-include \var{dir} \var{pat1} \var{pat2} ... }
+    {include all files under \var{dir} matching any of the listed patterns}
+  \lineii{recursive-exclude \var{dir} \var{pat1} \var{pat2} ...}
+    {exclude all files under \var{dir} matching any of the listed patterns}
+  \lineii{global-include \var{pat1} \var{pat2} ...}
+    {include all files anywhere in the source tree matching\\&
+     any of the listed patterns}
+  \lineii{global-exclude \var{pat1} \var{pat2} ...}
+    {exclude all files anywhere in the source tree matching\\&
+     any of the listed patterns}
+  \lineii{prune \var{dir}}{exclude all files under \var{dir}}
+  \lineii{graft \var{dir}}{include all files under \var{dir}}
+\end{tableii}
+
+The patterns here are \UNIX-style ``glob'' patterns: \code{*} matches any
+sequence of regular filename characters, \code{?} matches any single
+regular filename character, and \code{[\var{range}]} matches any of the
+characters in \var{range} (e.g., \code{a-z}, \code{a-zA-Z},
+\code{a-f0-9\_.}).  The definition of ``regular filename character'' is
+platform-specific: on \UNIX{} it is anything except slash; on Windows
+anything except backslash or colon; on Mac OS 9 anything except colon.
+
+\XXX{Windows support not there yet}
+
+
+%\section{Creating a built distribution: the
+%  \protect\command{bdist} command family}
+%\label{bdist-cmds}
+
+
+%\subsection{\protect\command{bdist}}
+
+%\subsection{\protect\command{bdist\_dumb}}
+
+%\subsection{\protect\command{bdist\_rpm}}
+
+%\subsection{\protect\command{bdist\_wininst}}
+
+
+\chapter{API Reference \label{api-reference}}
+
+\section{\module{distutils.core} --- Core Distutils functionality}
+
+\declaremodule{standard}{distutils.core}
+\modulesynopsis{The core Distutils functionality}
+
+The \module{distutils.core} module is the only module that needs to be
+installed to use the Distutils. It provides the \function{setup()} (which
+is called from the setup script). Indirectly provides the 
+\class{distutils.dist.Distribution} and \class{distutils.cmd.Command} class.
+
+\begin{funcdesc}{setup}{arguments}
+The basic do-everything function that does most everything you could ever
+ask for from a Distutils method. See XXXXX
+
+The setup function takes a large number of arguments. These
+are laid out in the following table.
+
+\begin{tableiii}{c|l|l}{argument name}{argument name}{value}{type}
+\lineiii{name}{The name of the package}{a string}
+\lineiii{version}{The version number of the package}{See \refmodule{distutils.version}}
+\lineiii{description}{A single line describing the package}{a string}
+\lineiii{long_description}{Longer description of the package}{a string}
+\lineiii{author}{The name of the package author}{a string}
+\lineiii{author_email}{The email address of the package author}{a string}
+\lineiii{maintainer}{The name of the current maintainer, if different from the author}{a string}
+\lineiii{maintainer_email}{The email address of the current maintainer, if different from the author}{}
+\lineiii{url}{A URL for the package (homepage)}{a URL}
+\lineiii{download_url}{A URL to download the package}{a URL}
+\lineiii{packages}{A list of Python packages that distutils will manipulate}{a list of strings}
+\lineiii{py_modules}{A list of Python modules that distutils will manipulate}{a list of strings}
+\lineiii{scripts}{A list of standalone script files to be built and installed}{a list of strings}
+\lineiii{ext_modules}{A list of Python extensions to be built}{A list of 
+instances of \class{distutils.core.Extension}}
+\lineiii{classifiers}{A list of categories for the package}{The list of available categorizations is at \url{http://cheeseshop.python.org/pypi?:action=list_classifiers}.}
+\lineiii{distclass}{the \class{Distribution} class to use}{A subclass of \class{distutils.core.Distribution}}
+% What on earth is the use case for script_name?
+\lineiii{script_name}{The name of the setup.py script - defaults to \code{sys.argv[0]}}{a string}
+\lineiii{script_args}{Arguments to supply to the setup script}{a list of strings}
+\lineiii{options}{default options for the setup script}{a string}
+\lineiii{license}{The license for the package}{}
+\lineiii{keywords}{Descriptive meta-data. See \pep{314}}{}
+\lineiii{platforms}{}{}
+\lineiii{cmdclass}{A mapping of command names to \class{Command} subclasses}{a dictionary}
+\end{tableiii}
+
+\end{funcdesc}
+
+\begin{funcdesc}{run_setup}{script_name\optional{, script_args=\code{None}, stop_after=\code{'run'}}}
+Run a setup script in a somewhat controlled environment, and return 
+the \class{distutils.dist.Distribution} instance that drives things.  
+This is useful if you need to find out the distribution meta-data 
+(passed as keyword args from \var{script} to \function{setup()}), or 
+the contents of the config files or command-line.
+
+\var{script_name} is a file that will be run with \function{execfile()}
+\code{sys.argv[0]} will be replaced with \var{script} for the duration of the
+call.  \var{script_args} is a list of strings; if supplied,
+\code{sys.argv[1:]} will be replaced by \var{script_args} for the duration 
+of the call.
+
+\var{stop_after} tells \function{setup()} when to stop processing; possible 
+values:
+
+\begin{tableii}{c|l}{value}{value}{description}
+\lineii{init}{Stop after the \class{Distribution} instance has been created 
+and populated with the keyword arguments to \function{setup()}}
+\lineii{config}{Stop after config files have been parsed (and their data
+stored in the \class{Distribution} instance)}
+\lineii{commandline}{Stop after the command-line (\code{sys.argv[1:]} or 
+\var{script_args}) have been parsed (and the data stored in the 
+\class{Distribution} instance.)}
+\lineii{run}{Stop after all commands have been run (the same as 
+if \function{setup()} had been called in the usual way). This is the default 
+value.}
+\end{tableii}
+\end{funcdesc}
+
+In addition, the \module{distutils.core} module exposed a number of 
+classes that live elsewhere.
+
+\begin{itemize}
+\item \class{Extension} from \refmodule{distutils.extension}
+\item \class{Command} from \refmodule{distutils.cmd}
+\item \class{Distribution} from \refmodule{distutils.dist}
+\end{itemize}
+
+A short description of each of these follows, but see the relevant
+module for the full reference.
+
+\begin{classdesc*}{Extension}
+
+The Extension class describes a single C or \Cpp extension module in a
+setup script. It accepts the following keyword arguments in its
+constructor
+
+\begin{tableiii}{c|l|l}{argument name}{argument name}{value}{type}
+\lineiii{name}{the full name of the extension, including any packages
+--- ie. \emph{not} a filename or pathname, but Python dotted name}{string}
+\lineiii{sources}{list of source filenames, relative to the distribution
+root (where the setup script lives), in \UNIX{} form (slash-separated) for
+portability. Source files may be C, \Cpp, SWIG (.i), platform-specific
+resource files, or whatever else is recognized by the \command{build_ext}
+command as source for a Python extension.}{string}
+\lineiii{include_dirs}{list of directories to search for C/\Cpp{} header
+files (in \UNIX{} form for portability)}{string}
+\lineiii{define_macros}{list of macros to define; each macro is defined
+using a 2-tuple, where 'value' is either the string to define it to or
+\code{None} to define it without a particular value (equivalent of
+\code{\#define FOO} in source or \programopt{-DFOO} on \UNIX{} C
+compiler command line) }{ (string,string) 
+tuple or (name,\code{None}) }
+\lineiii{undef_macros}{list of macros to undefine explicitly}{string}
+\lineiii{library_dirs}{list of directories to search for C/\Cpp{} libraries
+at link time }{string}
+\lineiii{libraries}{list of library names (not filenames or paths) to
+link against }{string}
+\lineiii{runtime_library_dirs}{list of directories to search for C/\Cpp{}
+libraries at run time (for shared extensions, this is when the extension
+is loaded)}{string}
+\lineiii{extra_objects}{list of extra files to link with (eg. object
+files not implied by 'sources', static library that must be explicitly
+specified, binary resource files, etc.)}{string}
+\lineiii{extra_compile_args}{any extra platform- and compiler-specific
+information to use when compiling the source files in 'sources'. For
+platforms and compilers where a command line makes sense, this is
+typically a list of command-line arguments, but for other platforms it
+could be anything.}{string}
+\lineiii{extra_link_args}{any extra platform- and compiler-specific
+information to use when linking object files together to create the
+extension (or to create a new static Python interpreter). Similar
+interpretation as for 'extra_compile_args'.}{string}
+\lineiii{export_symbols}{list of symbols to be exported from a shared
+extension. Not used on all platforms, and not generally necessary for
+Python extensions, which typically export exactly one symbol: \code{init} +
+extension_name. }{string}
+\lineiii{depends}{list of files that the extension depends on }{string}
+\lineiii{language}{extension language (i.e. \code{'c'}, \code{'c++'}, 
+\code{'objc'}). Will be detected from the source extensions if not provided.
+}{string}
+\end{tableiii}
+\end{classdesc*}
+
+\begin{classdesc*}{Distribution}
+A \class{Distribution} describes how to build, install and package up a
+Python software package. 
+
+See the \function{setup()} function for a list of keyword arguments accepted 
+by the Distribution constructor. \function{setup()} creates a Distribution
+instance.
+\end{classdesc*}
+
+\begin{classdesc*}{Command}
+A \class{Command} class (or rather, an instance of one of its subclasses)
+implement a single distutils command.
+\end{classdesc*}
+
+
+\section{\module{distutils.ccompiler} --- CCompiler base class}
+\declaremodule{standard}{distutils.ccompiler}
+\modulesynopsis{Abstract CCompiler class}
+
+This module provides the abstract base class for the \class{CCompiler} 
+classes.  A \class{CCompiler} instance can be used for all the compile 
+and link steps needed to build a single project. Methods are provided to 
+set options for the compiler --- macro definitions, include directories, 
+link path, libraries and the like.
+
+This module provides the following functions.
+
+\begin{funcdesc}{gen_lib_options}{compiler, library_dirs, runtime_library_dirs, libraries}
+Generate linker options for searching library directories and
+linking with specific libraries.  \var{libraries} and \var{library_dirs} are,
+respectively, lists of library names (not filenames!) and search
+directories.  Returns a list of command-line options suitable for use
+with some compiler (depending on the two format strings passed in).
+\end{funcdesc}
+    
+\begin{funcdesc}{gen_preprocess_options}{macros, include_dirs}
+Generate C pre-processor options (\programopt{-D}, \programopt{-U},
+\programopt{-I}) as used by at least
+two types of compilers: the typical \UNIX{} compiler and Visual \Cpp.
+\var{macros} is the usual thing, a list of 1- or 2-tuples, where
+\code{(\var{name},)} means undefine (\programopt{-U}) macro \var{name},
+and \code{(\var{name}, \var{value})} means define (\programopt{-D})
+macro \var{name} to \var{value}.  \var{include_dirs} is just a list of
+directory names to be added to the header file search path (\programopt{-I}).
+Returns a list of command-line options suitable for either \UNIX{} compilers
+or Visual \Cpp.
+\end{funcdesc}
+
+\begin{funcdesc}{get_default_compiler}{osname, platform}
+Determine the default compiler to use for the given platform.
+    
+\var{osname} should be one of the standard Python OS names (i.e.\ the
+ones returned by \code{os.name}) and \var{platform} the common value
+returned by \code{sys.platform} for the platform in question.
+    
+The default values are \code{os.name} and \code{sys.platform} in case the
+parameters are not given.
+\end{funcdesc}
+
+\begin{funcdesc}{new_compiler}{plat=\code{None}, compiler=\code{None}, verbose=\code{0}, dry_run=\code{0}, force=\code{0}}
+Factory function to generate an instance of some CCompiler subclass
+for the supplied platform/compiler combination. \var{plat} defaults
+to \code{os.name} (eg. \code{'posix'}, \code{'nt'}), and \var{compiler} 
+defaults to the default compiler for that platform. Currently only
+\code{'posix'} and \code{'nt'} are supported, and the default
+compilers are ``traditional \UNIX{} interface'' (\class{UnixCCompiler}
+class) and Visual \Cpp (\class{MSVCCompiler} class).  Note that it's
+perfectly possible to ask for a \UNIX{} compiler object under Windows,
+and a Microsoft compiler object under \UNIX---if you supply a value
+for \var{compiler}, \var{plat} is ignored.
+% Is the posix/nt only thing still true? Mac OS X seems to work, and
+% returns a UnixCCompiler instance. How to document this... hmm.
+\end{funcdesc}
+
+\begin{funcdesc}{show_compilers}{}
+Print list of available compilers (used by the
+\longprogramopt{help-compiler} options to \command{build},
+\command{build_ext}, \command{build_clib}).
+\end{funcdesc}
+
+\begin{classdesc}{CCompiler}{\optional{verbose=\code{0}, dry_run=\code{0}, force=\code{0}}}
+
+The abstract base class \class{CCompiler} defines the interface that 
+must be implemented by real compiler classes.  The class also has 
+some utility methods used by several compiler classes.
+
+The basic idea behind a compiler abstraction class is that each
+instance can be used for all the compile/link steps in building a
+single project.  Thus, attributes common to all of those compile and
+link steps --- include directories, macros to define, libraries to link
+against, etc. --- are attributes of the compiler instance.  To allow for
+variability in how individual files are treated, most of those
+attributes may be varied on a per-compilation or per-link basis.
+
+The constructor for each subclass creates an instance of the Compiler
+object. Flags are \var{verbose} (show verbose output), \var{dry_run}
+(don't actually execute the steps) and \var{force} (rebuild
+everything, regardless of dependencies). All of these flags default to
+\code{0} (off). Note that you probably don't want to instantiate
+\class{CCompiler} or one of its subclasses directly - use the
+\function{distutils.CCompiler.new_compiler()} factory function
+instead.
+
+The following methods allow you to manually alter compiler options for 
+the instance of the Compiler class.
+
+\begin{methoddesc}{add_include_dir}{dir}
+Add \var{dir} to the list of directories that will be searched for
+header files.  The compiler is instructed to search directories in
+the order in which they are supplied by successive calls to
+\method{add_include_dir()}.
+\end{methoddesc}
+
+\begin{methoddesc}{set_include_dirs}{dirs}
+Set the list of directories that will be searched to \var{dirs} (a
+list of strings).  Overrides any preceding calls to
+\method{add_include_dir()}; subsequent calls to
+\method{add_include_dir()} add to the list passed to
+\method{set_include_dirs()}.  This does not affect any list of
+standard include directories that the compiler may search by default.
+\end{methoddesc}
+
+\begin{methoddesc}{add_library}{libname}
+
+Add \var{libname} to the list of libraries that will be included in
+all links driven by this compiler object.  Note that \var{libname}
+should *not* be the name of a file containing a library, but the
+name of the library itself: the actual filename will be inferred by
+the linker, the compiler, or the compiler class (depending on the
+platform).
+    
+The linker will be instructed to link against libraries in the
+order they were supplied to \method{add_library()} and/or
+\method{set_libraries()}.  It is perfectly valid to duplicate library
+names; the linker will be instructed to link against libraries as
+many times as they are mentioned.
+\end{methoddesc}
+
+\begin{methoddesc}{set_libraries}{libnames}
+Set the list of libraries to be included in all links driven by
+this compiler object to \var{libnames} (a list of strings).  This does
+not affect any standard system libraries that the linker may
+include by default.
+\end{methoddesc}
+
+\begin{methoddesc}{add_library_dir}{dir}
+Add \var{dir} to the list of directories that will be searched for
+libraries specified to \method{add_library()} and
+\method{set_libraries()}.  The linker will be instructed to search for
+libraries in the order they are supplied to \method{add_library_dir()}
+and/or \method{set_library_dirs()}.
+\end{methoddesc}
+
+\begin{methoddesc}{set_library_dirs}{dirs}
+Set the list of library search directories to \var{dirs} (a list of
+strings).  This does not affect any standard library search path
+that the linker may search by default.
+\end{methoddesc}
+
+\begin{methoddesc}{add_runtime_library_dir}{dir}
+Add \var{dir} to the list of directories that will be searched for
+shared libraries at runtime.
+\end{methoddesc}
+
+\begin{methoddesc}{set_runtime_library_dirs}{dirs}
+Set the list of directories to search for shared libraries at
+runtime to \var{dirs} (a list of strings).  This does not affect any
+standard search path that the runtime linker may search by
+default.
+\end{methoddesc}
+
+\begin{methoddesc}{define_macro}{name\optional{, value=\code{None}}}
+Define a preprocessor macro for all compilations driven by this
+compiler object.  The optional parameter \var{value} should be a
+string; if it is not supplied, then the macro will be defined
+without an explicit value and the exact outcome depends on the
+compiler used (XXX true? does ANSI say anything about this?)
+\end{methoddesc}
+
+\begin{methoddesc}{undefine_macro}{name}
+Undefine a preprocessor macro for all compilations driven by
+this compiler object.  If the same macro is defined by
+\method{define_macro()} and undefined by \method{undefine_macro()} 
+the last call takes precedence (including multiple redefinitions or
+undefinitions).  If the macro is redefined/undefined on a
+per-compilation basis (ie. in the call to \method{compile()}), then that
+takes precedence.
+\end{methoddesc}
+
+\begin{methoddesc}{add_link_object}{object}
+Add \var{object} to the list of object files (or analogues, such as
+explicitly named library files or the output of ``resource
+compilers'') to be included in every link driven by this compiler
+object.
+\end{methoddesc}
+
+\begin{methoddesc}{set_link_objects}{objects}
+Set the list of object files (or analogues) to be included in
+every link to \var{objects}.  This does not affect any standard object
+files that the linker may include by default (such as system
+libraries).
+\end{methoddesc}
+
+The following methods implement methods for autodetection of compiler 
+options, providing some functionality similar to GNU \program{autoconf}.
+
+\begin{methoddesc}{detect_language}{sources}
+Detect the language of a given file, or list of files. Uses the 
+instance attributes \member{language_map} (a dictionary), and 
+\member{language_order} (a list) to do the job.
+\end{methoddesc}
+
+\begin{methoddesc}{find_library_file}{dirs, lib\optional{, debug=\code{0}}}
+Search the specified list of directories for a static or shared
+library file \var{lib} and return the full path to that file.  If
+\var{debug} is true, look for a debugging version (if that makes sense on
+the current platform).  Return \code{None} if \var{lib} wasn't found in any of
+the specified directories.
+\end{methoddesc}
+
+\begin{methoddesc}{has_function}{funcname \optional{, includes=\code{None}, include_dirs=\code{None}, libraries=\code{None}, library_dirs=\code{None}}}
+Return a boolean indicating whether \var{funcname} is supported on
+the current platform.  The optional arguments can be used to
+augment the compilation environment by providing additional include
+files and paths and libraries and paths.
+\end{methoddesc}
+
+\begin{methoddesc}{library_dir_option}{dir}
+Return the compiler option to add \var{dir} to the list of
+directories searched for libraries.
+\end{methoddesc}
+
+\begin{methoddesc}{library_option}{lib}
+Return the compiler option to add \var{dir} to the list of libraries
+linked into the shared library or executable.
+\end{methoddesc}
+
+\begin{methoddesc}{runtime_library_dir_option}{dir}
+Return the compiler option to add \var{dir} to the list of
+directories searched for runtime libraries.
+\end{methoddesc}
+
+\begin{methoddesc}{set_executables}{**args}
+Define the executables (and options for them) that will be run
+to perform the various stages of compilation.  The exact set of
+executables that may be specified here depends on the compiler
+class (via the 'executables' class attribute), but most will have:
+
+\begin{tableii}{l|l}{attribute}{attribute}{description}
+\lineii{compiler}{the C/\Cpp{} compiler}
+\lineii{linker_so}{linker used to create shared objects and libraries}
+\lineii{linker_exe}{linker used to create binary executables}
+\lineii{archiver}{static library creator}
+\end{tableii}
+
+On platforms with a command-line (\UNIX, DOS/Windows), each of these
+is a string that will be split into executable name and (optional)
+list of arguments.  (Splitting the string is done similarly to how
+\UNIX{} shells operate: words are delimited by spaces, but quotes and
+backslashes can override this.  See
+\function{distutils.util.split_quoted()}.)
+\end{methoddesc}
+
+The following methods invoke stages in the build process.
+
+\begin{methoddesc}{compile}{sources\optional{, output_dir=\code{None}, macros=\code{None}, include_dirs=\code{None}, debug=\code{0}, extra_preargs=\code{None}, extra_postargs=\code{None}, depends=\code{None}}}
+Compile one or more source files. Generates object files (e.g. 
+transforms a \file{.c} file to a \file{.o} file.)
+
+\var{sources} must be a list of filenames, most likely C/\Cpp
+files, but in reality anything that can be handled by a
+particular compiler and compiler class (eg. \class{MSVCCompiler} can
+handle resource files in \var{sources}).  Return a list of object
+filenames, one per source filename in \var{sources}.  Depending on
+the implementation, not all source files will necessarily be
+compiled, but all corresponding object filenames will be
+returned.
+
+If \var{output_dir} is given, object files will be put under it, while
+retaining their original path component.  That is, \file{foo/bar.c}
+normally compiles to \file{foo/bar.o} (for a \UNIX{} implementation); if
+\var{output_dir} is \var{build}, then it would compile to
+\file{build/foo/bar.o}.
+
+\var{macros}, if given, must be a list of macro definitions.  A macro
+definition is either a \code{(\var{name}, \var{value})} 2-tuple or a
+\code{(\var{name},)} 1-tuple.
+The former defines a macro; if the value is \code{None}, the macro is
+defined without an explicit value.  The 1-tuple case undefines a
+macro.  Later definitions/redefinitions/undefinitions take
+precedence.
+
+\var{include_dirs}, if given, must be a list of strings, the
+directories to add to the default include file search path for this
+compilation only.
+
+\var{debug} is a boolean; if true, the compiler will be instructed to
+output debug symbols in (or alongside) the object file(s).
+
+\var{extra_preargs} and \var{extra_postargs} are implementation-dependent.
+On platforms that have the notion of a command-line (e.g. \UNIX,
+DOS/Windows), they are most likely lists of strings: extra
+command-line arguments to prepend/append to the compiler command
+line.  On other platforms, consult the implementation class
+documentation.  In any event, they are intended as an escape hatch
+for those occasions when the abstract compiler framework doesn't
+cut the mustard.
+
+\var{depends}, if given, is a list of filenames that all targets
+depend on.  If a source file is older than any file in
+depends, then the source file will be recompiled.  This
+supports dependency tracking, but only at a coarse
+granularity.
+
+Raises \exception{CompileError} on failure.
+\end{methoddesc}
+
+\begin{methoddesc}{create_static_lib}{objects, output_libname\optional{, output_dir=\code{None}, debug=\code{0}, target_lang=\code{None}}}
+Link a bunch of stuff together to create a static library file.
+The ``bunch of stuff'' consists of the list of object files supplied
+as \var{objects}, the extra object files supplied to
+\method{add_link_object()} and/or \method{set_link_objects()}, the libraries
+supplied to \method{add_library()} and/or \method{set_libraries()}, and the
+libraries supplied as \var{libraries} (if any).
+
+\var{output_libname} should be a library name, not a filename; the
+filename will be inferred from the library name.  \var{output_dir} is
+the directory where the library file will be put. XXX defaults to what?
+
+\var{debug} is a boolean; if true, debugging information will be
+included in the library (note that on most platforms, it is the
+compile step where this matters: the \var{debug} flag is included here
+just for consistency).
+
+\var{target_lang} is the target language for which the given objects
+are being compiled. This allows specific linkage time treatment of
+certain languages.
+
+Raises \exception{LibError} on failure.
+\end{methoddesc}
+
+\begin{methoddesc}{link}{target_desc, objects, output_filename\optional{, output_dir=\code{None}, libraries=\code{None}, library_dirs=\code{None}, runtime_library_dirs=\code{None}, export_symbols=\code{None}, debug=\code{0}, extra_preargs=\code{None}, extra_postargs=\code{None}, build_temp=\code{None}, target_lang=\code{None}}}
+Link a bunch of stuff together to create an executable or
+shared library file.
+
+The ``bunch of stuff'' consists of the list of object files supplied
+as \var{objects}.  \var{output_filename} should be a filename.  If
+\var{output_dir} is supplied, \var{output_filename} is relative to it
+(i.e. \var{output_filename} can provide directory components if
+needed).
+
+\var{libraries} is a list of libraries to link against.  These are
+library names, not filenames, since they're translated into
+filenames in a platform-specific way (eg. \var{foo} becomes \file{libfoo.a}
+on \UNIX{} and \file{foo.lib} on DOS/Windows).  However, they can include a
+directory component, which means the linker will look in that
+specific directory rather than searching all the normal locations.
+
+\var{library_dirs}, if supplied, should be a list of directories to
+search for libraries that were specified as bare library names
+(ie. no directory component).  These are on top of the system
+default and those supplied to \method{add_library_dir()} and/or
+\method{set_library_dirs()}.  \var{runtime_library_dirs} is a list of
+directories that will be embedded into the shared library and used
+to search for other shared libraries that *it* depends on at
+run-time.  (This may only be relevant on \UNIX.)
+
+\var{export_symbols} is a list of symbols that the shared library will
+export.  (This appears to be relevant only on Windows.)
+
+\var{debug} is as for \method{compile()} and \method{create_static_lib()}, 
+with the slight distinction that it actually matters on most platforms (as
+opposed to \method{create_static_lib()}, which includes a \var{debug} flag
+mostly for form's sake).
+
+\var{extra_preargs} and \var{extra_postargs} are as for \method{compile()} 
+(except of course that they supply command-line arguments for the
+particular linker being used).
+
+\var{target_lang} is the target language for which the given objects
+are being compiled. This allows specific linkage time treatment of
+certain languages.
+
+Raises \exception{LinkError} on failure.
+\end{methoddesc}
+
+\begin{methoddesc}{link_executable}{objects, output_progname\optional{, output_dir=\code{None}, libraries=\code{None}, library_dirs=\code{None}, runtime_library_dirs=\code{None}, debug=\code{0}, extra_preargs=\code{None}, extra_postargs=\code{None}, target_lang=\code{None}}}
+Link an executable. 
+\var{output_progname} is the name of the file executable,
+while \var{objects} are a list of object filenames to link in. Other arguments 
+are as for the \method{link} method. 
+\end{methoddesc}
+
+\begin{methoddesc}{link_shared_lib}{objects, output_libname\optional{, output_dir=\code{None}, libraries=\code{None}, library_dirs=\code{None}, runtime_library_dirs=\code{None}, export_symbols=\code{None}, debug=\code{0}, extra_preargs=\code{None}, extra_postargs=\code{None}, build_temp=\code{None}, target_lang=\code{None}}}
+Link a shared library. \var{output_libname} is the name of the output 
+library, while \var{objects} is a list of object filenames to link in. 
+Other arguments are as for the \method{link} method. 
+\end{methoddesc}
+
+\begin{methoddesc}{link_shared_object}{objects, output_filename\optional{, output_dir=\code{None}, libraries=\code{None}, library_dirs=\code{None}, runtime_library_dirs=\code{None}, export_symbols=\code{None}, debug=\code{0}, extra_preargs=\code{None}, extra_postargs=\code{None}, build_temp=\code{None}, target_lang=\code{None}}}
+Link a shared object. \var{output_filename} is the name of the shared object
+that will be created, while \var{objects} is a list of object filenames 
+to link in. Other arguments are as for the \method{link} method. 
+\end{methoddesc}
+
+\begin{methoddesc}{preprocess}{source\optional{, output_file=\code{None}, macros=\code{None}, include_dirs=\code{None}, extra_preargs=\code{None}, extra_postargs=\code{None}}}
+Preprocess a single C/\Cpp{} source file, named in \var{source}.
+Output will be written to file named \var{output_file}, or \var{stdout} if
+\var{output_file} not supplied.  \var{macros} is a list of macro
+definitions as for \method{compile()}, which will augment the macros set
+with \method{define_macro()} and \method{undefine_macro()}.  
+\var{include_dirs} is a list of directory names that will be added to the 
+default list, in the same way as \method{add_include_dir()}.
+
+Raises \exception{PreprocessError} on failure.
+\end{methoddesc}
+
+The following utility methods are defined by the \class{CCompiler} class,
+for use by the various concrete subclasses.
+
+\begin{methoddesc}{executable_filename}{basename\optional{, strip_dir=\code{0}, output_dir=\code{''}}}
+Returns the filename of the executable for the given \var{basename}. 
+Typically for non-Windows platforms this is the same as the basename, 
+while Windows will get a \file{.exe} added.
+\end{methoddesc}
+
+\begin{methoddesc}{library_filename}{libname\optional{, lib_type=\code{'static'}, strip_dir=\code{0}, output_dir=\code{''}}}
+Returns the filename for the given library name on the current platform.
+On \UNIX{} a library with \var{lib_type} of \code{'static'} will typically 
+be of the form \file{liblibname.a}, while a \var{lib_type} of \code{'dynamic'} 
+will be of the form \file{liblibname.so}.
+\end{methoddesc}
+
+\begin{methoddesc}{object_filenames}{source_filenames\optional{, strip_dir=\code{0}, output_dir=\code{''}}}
+Returns the name of the object files for the given source files. 
+\var{source_filenames} should be a list of filenames. 
+\end{methoddesc}
+
+\begin{methoddesc}{shared_object_filename}{basename\optional{, strip_dir=\code{0}, output_dir=\code{''}}}
+Returns the name of a shared object file for the given file name \var{basename}.
+\end{methoddesc}
+
+\begin{methoddesc}{execute}{func, args\optional{, msg=\code{None}, level=\code{1}}}
+Invokes \function{distutils.util.execute()} This method invokes a 
+Python function \var{func} with the given arguments \var{args}, after 
+logging and taking into account the \var{dry_run} flag. XXX see also.
+\end{methoddesc}
+
+\begin{methoddesc}{spawn}{cmd}
+Invokes \function{distutils.util.spawn()}. This invokes an external 
+process to run the given command. XXX see also.
+\end{methoddesc}
+
+\begin{methoddesc}{mkpath}{name\optional{, mode=\code{511}}}
+
+Invokes \function{distutils.dir_util.mkpath()}. This creates a directory 
+and any missing ancestor directories. XXX see also.
+\end{methoddesc}
+
+\begin{methoddesc}{move_file}{src, dst}
+Invokes \method{distutils.file_util.move_file()}. Renames \var{src} to 
+\var{dst}.  XXX see also.
+\end{methoddesc}
+
+\begin{methoddesc}{announce}{msg\optional{, level=\code{1}}}
+Write a message using \function{distutils.log.debug()}. XXX see also.
+\end{methoddesc}
+
+\begin{methoddesc}{warn}{msg}
+Write a warning message \var{msg} to standard error.
+\end{methoddesc}
+
+\begin{methoddesc}{debug_print}{msg}
+If the \var{debug} flag is set on this \class{CCompiler} instance, print 
+\var{msg} to standard output, otherwise do nothing.
+\end{methoddesc}
+
+\end{classdesc}
+
+%\subsection{Compiler-specific modules}
+%
+%The following modules implement concrete subclasses of the abstract 
+%\class{CCompiler} class. They should not be instantiated directly, but should
+%be created using \function{distutils.ccompiler.new_compiler()} factory 
+%function.
+
+\section{\module{distutils.unixccompiler} --- Unix C Compiler}
+\declaremodule{standard}{distutils.unixccompiler}
+\modulesynopsis{UNIX C Compiler}
+
+This module provides the \class{UnixCCompiler} class, a subclass of 
+\class{CCompiler} that handles the typical \UNIX-style command-line 
+C compiler:
+
+\begin{itemize}
+\item macros defined with \programopt{-D\var{name}\optional{=value}}
+\item macros undefined with \programopt{-U\var{name}}
+\item include search directories specified with
+      \programopt{-I\var{dir}}
+\item libraries specified with \programopt{-l\var{lib}}
+\item library search directories specified with \programopt{-L\var{dir}}
+\item compile handled by \program{cc} (or similar) executable with
+      \programopt{-c} option: compiles \file{.c} to \file{.o}
+\item link static library handled by \program{ar} command (possibly
+      with \program{ranlib})
+\item link shared library handled by \program{cc} \programopt{-shared}
+\end{itemize}
+
+\section{\module{distutils.msvccompiler} --- Microsoft Compiler}
+\declaremodule{standard}{distutils.msvccompiler}
+\modulesynopsis{Microsoft Compiler}
+
+This module provides \class{MSVCCompiler}, an implementation of the abstract 
+\class{CCompiler} class for Microsoft Visual Studio. Typically, extension
+modules need to be compiled with the same compiler that was used to compile
+Python. For Python 2.3 and earlier, the compiler was Visual Studio 6. For
+Python 2.4 and 2.5, the compiler is Visual Studio .NET 2003. The AMD64
+and Itanium binaries are created using the Platform SDK.
+
+\class{MSVCCompiler} will normally choose the right compiler, linker etc.
+on its own. To override this choice, the environment variables
+\var{DISTUTILS\_USE\_SDK} and \var{MSSdk} must be both set. \var{MSSdk}
+indicates that the current environment has been setup by the SDK's
+\code{SetEnv.Cmd} script, or that the environment variables had been
+registered when the SDK was installed; \var{DISTUTILS\_USE\_SDK} indicates
+that the distutils user has made an explicit choice to override the
+compiler selection by \class{MSVCCompiler}.
+
+\section{\module{distutils.bcppcompiler} --- Borland Compiler}
+\declaremodule{standard}{distutils.bcppcompiler}
+This module provides \class{BorlandCCompiler}, an subclass of the abstract \class{CCompiler} class for the Borland \Cpp{} compiler.
+
+\section{\module{distutils.cygwincompiler} --- Cygwin Compiler}
+\declaremodule{standard}{distutils.cygwinccompiler}
+
+This module provides the \class{CygwinCCompiler} class, a subclass of \class{UnixCCompiler} that
+handles the Cygwin port of the GNU C compiler to Windows.  It also contains
+the Mingw32CCompiler class which handles the mingw32 port of GCC (same as
+cygwin in no-cygwin mode).
+
+\section{\module{distutils.emxccompiler} --- OS/2 EMX Compiler}
+\declaremodule{standard}{distutils.emxccompiler}
+\modulesynopsis{OS/2 EMX Compiler support}
+
+This module provides the EMXCCompiler class, a subclass of \class{UnixCCompiler} that handles the EMX port of the GNU C compiler to OS/2.
+
+\section{\module{distutils.mwerkscompiler} --- Metrowerks CodeWarrior support}
+\declaremodule{standard}{distutils.mwerkscompiler}
+\modulesynopsis{Metrowerks CodeWarrior support}
+
+Contains \class{MWerksCompiler}, an implementation of the abstract 
+\class{CCompiler} class for MetroWerks CodeWarrior on the pre-Mac OS X Macintosh.
+Needs work to support CW on Windows or Mac OS X.
+
+
+%\subsection{Utility modules}
+%
+%The following modules all provide general utility functions. They haven't 
+%all been documented yet.
+
+\section{\module{distutils.archive_util} --- 
+			Archiving utilities}
+\declaremodule[distutils.archiveutil]{standard}{distutils.archive_util}
+\modulesynopsis{Utility functions for creating archive files (tarballs, zip files, ...)}
+
+This module provides a few functions for creating archive files, such as 
+tarballs or zipfiles.
+
+\begin{funcdesc}{make_archive}{base_name, format\optional{, root_dir=\code{None}, base_dir=\code{None}, verbose=\code{0}, dry_run=\code{0}}}
+Create an archive file (eg. \code{zip} or \code{tar}).  \var{base_name} 
+is the name of the file to create, minus any format-specific extension; 
+\var{format} is the archive format: one of \code{zip}, \code{tar}, 
+\code{ztar}, or \code{gztar}.
+\var{root_dir} is a directory that will be the root directory of the
+archive; ie. we typically \code{chdir} into \var{root_dir} before 
+creating the archive.  \var{base_dir} is the directory where we start 
+archiving from; ie. \var{base_dir} will be the common prefix of all files and
+directories in the archive.  \var{root_dir} and \var{base_dir} both default
+to the current directory.  Returns the name of the archive file.
+
+\warning{This should be changed to support bz2 files}
+\end{funcdesc}
+
+\begin{funcdesc}{make_tarball}{base_name, base_dir\optional{, compress=\code{'gzip'}, verbose=\code{0}, dry_run=\code{0}}}'Create an (optional compressed) archive as a tar file from all files in and under \var{base_dir}. \var{compress} must be \code{'gzip'} (the default), 
+\code{'compress'}, \code{'bzip2'}, or \code{None}.  Both \program{tar}
+and the compression utility named by \var{compress} must be on the 
+default program search path, so this is probably \UNIX-specific.  The 
+output tar file will be named \file{\var{base_dir}.tar}, possibly plus
+the appropriate compression extension (\file{.gz}, \file{.bz2} or
+\file{.Z}).  Return the output filename.
+
+\warning{This should be replaced with calls to the \module{tarfile} module.}
+\end{funcdesc}
+
+\begin{funcdesc}{make_zipfile}{base_name, base_dir\optional{, verbose=\code{0}, dry_run=\code{0}}}
+Create a zip file from all files in and under \var{base_dir}.  The output
+zip file will be named \var{base_dir} + \file{.zip}.  Uses either the 
+\module{zipfile} Python module (if available) or the InfoZIP \file{zip} 
+utility (if installed and found on the default search path).  If neither 
+tool is available, raises \exception{DistutilsExecError}.  
+Returns the name of the output zip file.
+\end{funcdesc}
+
+\section{\module{distutils.dep_util} --- Dependency checking}
+\declaremodule[distutils.deputil]{standard}{distutils.dep_util}
+\modulesynopsis{Utility functions for simple dependency checking}
+
+This module provides functions for performing simple, timestamp-based 
+dependency of files and groups of files; also, functions based entirely 
+on such timestamp dependency analysis.
+
+\begin{funcdesc}{newer}{source, target}
+Return true if \var{source} exists and is more recently modified than
+\var{target}, or if \var{source} exists and \var{target} doesn't.
+Return false if both exist and \var{target} is the same age or newer 
+than \var{source}.
+Raise \exception{DistutilsFileError} if \var{source} does not exist.
+\end{funcdesc}
+
+\begin{funcdesc}{newer_pairwise}{sources, targets}
+Walk two filename lists in parallel, testing if each source is newer
+than its corresponding target.  Return a pair of lists (\var{sources},
+\var{targets}) where source is newer than target, according to the semantics
+of \function{newer()}
+%% equivalent to a listcomp...
+\end{funcdesc}
+
+\begin{funcdesc}{newer_group}{sources, target\optional{, missing=\code{'error'}}}
+Return true if \var{target} is out-of-date with respect to any file
+listed in \var{sources}  In other words, if \var{target} exists and is newer
+than every file in \var{sources}, return false; otherwise return true.
+\var{missing} controls what we do when a source file is missing; the
+default (\code{'error'}) is to blow up with an \exception{OSError} from 
+inside \function{os.stat()};
+if it is \code{'ignore'}, we silently drop any missing source files; if it is
+\code{'newer'}, any missing source files make us assume that \var{target} is
+out-of-date (this is handy in ``dry-run'' mode: it'll make you pretend to
+carry out commands that wouldn't work because inputs are missing, but
+that doesn't matter because you're not actually going to run the
+commands).
+\end{funcdesc}
+
+\section{\module{distutils.dir_util} --- Directory tree operations}
+\declaremodule[distutils.dirutil]{standard}{distutils.dir_util}
+\modulesynopsis{Utility functions for operating on directories and directory trees}
+
+This module provides functions for operating on directories and trees
+of directories.
+
+\begin{funcdesc}{mkpath}{name\optional{, mode=\code{0777}, verbose=\code{0}, dry_run=\code{0}}}
+Create a directory and any missing ancestor directories.  If the
+directory already exists (or if \var{name} is the empty string, which
+means the current directory, which of course exists), then do
+nothing.  Raise \exception{DistutilsFileError} if unable to create some
+directory along the way (eg. some sub-path exists, but is a file
+rather than a directory).  If \var{verbose} is true, print a one-line
+summary of each mkdir to stdout.  Return the list of directories
+actually created.
+\end{funcdesc}
+
+\begin{funcdesc}{create_tree}{base_dir, files\optional{, mode=\code{0777}, verbose=\code{0}, dry_run=\code{0}}}
+Create all the empty directories under \var{base_dir} needed to
+put \var{files} there.  \var{base_dir} is just the a name of a directory
+which doesn't necessarily exist yet; \var{files} is a list of filenames
+to be interpreted relative to \var{base_dir}.  \var{base_dir} + the
+directory portion of every file in \var{files} will be created if it
+doesn't already exist.  \var{mode}, \var{verbose} and \var{dry_run} flags 
+are as for \function{mkpath()}.
+\end{funcdesc}
+
+\begin{funcdesc}{copy_tree}{src, dst\optional{preserve_mode=\code{1}, preserve_times=\code{1}, preserve_symlinks=\code{0}, update=\code{0}, verbose=\code{0}, dry_run=\code{0}}}
+Copy an entire directory tree \var{src} to a new location \var{dst}.  Both
+\var{src} and \var{dst} must be directory names.  If \var{src} is not a
+directory, raise \exception{DistutilsFileError}.  If \var{dst} does 
+not exist, it is created with \function{mkpath()}.  The end result of the 
+copy is that every file in \var{src} is copied to \var{dst}, and 
+directories under \var{src} are recursively copied to \var{dst}.  
+Return the list of files that were copied or might have been copied,
+using their output name. The return value is unaffected by \var{update}
+or \var{dry_run}: it is simply the list of all files under \var{src},
+with the names changed to be under \var{dst}.
+
+\var{preserve_mode} and \var{preserve_times} are the same as for
+\function{copy_file} in \refmodule[distutils.fileutil]{distutils.file_util};
+note that they only apply to regular files, not to directories.  If
+\var{preserve_symlinks} is true, symlinks will be copied as symlinks
+(on platforms that support them!); otherwise (the default), the
+destination of the symlink will be copied.  \var{update} and
+\var{verbose} are the same as for
+\function{copy_file()}.
+\end{funcdesc}
+
+\begin{funcdesc}{remove_tree}{directory\optional{verbose=\code{0}, dry_run=\code{0}}}
+Recursively remove \var{directory} and all files and directories underneath
+it. Any errors are ignored (apart from being reported to \code{sys.stdout} if
+\var{verbose} is true).
+\end{funcdesc}
+
+\XXX{Some of this could be replaced with the shutil module?}
+
+\section{\module{distutils.file_util} --- Single file operations}
+\declaremodule[distutils.fileutil]{standard}{distutils.file_util}
+\modulesynopsis{Utility functions for operating on single files}
+
+This module contains some utility functions for operating on individual files.
+
+\begin{funcdesc}{copy_file}{src, dst\optional{preserve_mode=\code{1}, preserve_times=\code{1}, update=\code{0}, link=\code{None}, verbose=\code{0}, dry_run=\code{0}}}
+Copy file \var{src} to \var{dst}. If \var{dst} is a directory, then
+\var{src} is copied there with the same name; otherwise, it must be a
+filename. (If the file exists, it will be ruthlessly clobbered.) If
+\var{preserve_mode} is true (the default), the file's mode (type and
+permission bits, or whatever is analogous on the current platform) is
+copied. If \var{preserve_times} is true (the default), the last-modified
+and last-access times are copied as well. If \var{update} is true,
+\var{src} will only be copied if \var{dst} does not exist, or if
+\var{dst} does exist but is older than \var{src}.
+
+\var{link} allows you to make hard links (using \function{os.link}) or
+symbolic links (using \function{os.symlink}) instead of copying: set it
+to \code{'hard'} or \code{'sym'}; if it is \code{None} (the default),
+files are copied. Don't set \var{link} on systems that don't support
+it: \function{copy_file()} doesn't check if hard or symbolic linking is
+available.  It uses \function{_copy_file_contents()} to copy file contents.
+
+Return a tuple \samp{(dest_name, copied)}: \var{dest_name} is the actual 
+name of the output file, and \var{copied} is true if the file was copied 
+(or would have been copied, if \var{dry_run} true).
+% XXX if the destination file already exists, we clobber it if
+% copying, but blow up if linking.  Hmmm.  And I don't know what
+% macostools.copyfile() does.  Should definitely be consistent, and
+% should probably blow up if destination exists and we would be
+% changing it (ie. it's not already a hard/soft link to src OR
+% (not update) and (src newer than dst)).
+\end{funcdesc}
+
+\begin{funcdesc}{move_file}{src, dst\optional{verbose, dry_run}}
+Move file \var{src} to \var{dst}. If \var{dst} is a directory, the file will
+be moved into it with the same name; otherwise, \var{src} is just renamed
+to \var{dst}.  Returns the new full name of the file.
+\warning{Handles cross-device moves on \UNIX{} using \function{copy_file()}.  
+What about other systems???}
+\end{funcdesc}
+
+\begin{funcdesc}{write_file}{filename, contents}
+Create a file called \var{filename} and write \var{contents} (a
+sequence of strings without line terminators) to it.
+\end{funcdesc}
+
+\section{\module{distutils.util} --- Miscellaneous other utility functions}
+\declaremodule{standard}{distutils.util}
+\modulesynopsis{Miscellaneous other utility functions}
+
+This module contains other assorted bits and pieces that don't fit into 
+any other utility module.
+
+\begin{funcdesc}{get_platform}{}
+Return a string that identifies the current platform.  This is used
+mainly to distinguish platform-specific build directories and
+platform-specific built distributions.  Typically includes the OS name
+and version and the architecture (as supplied by 'os.uname()'),
+although the exact information included depends on the OS; eg. for IRIX
+the architecture isn't particularly important (IRIX only runs on SGI
+hardware), but for Linux the kernel version isn't particularly
+important.
+
+Examples of returned values:
+\begin{itemize}
+\item \code{linux-i586}
+\item \code{linux-alpha}
+\item \code{solaris-2.6-sun4u}
+\item \code{irix-5.3}
+\item \code{irix64-6.2}
+\end{itemize}
+
+For non-\POSIX{} platforms, currently just returns \code{sys.platform}.
+% XXX isn't this also provided by some other non-distutils module?
+\end{funcdesc}
+
+\begin{funcdesc}{convert_path}{pathname}
+Return 'pathname' as a name that will work on the native filesystem,
+i.e. split it on '/' and put it back together again using the current
+directory separator.  Needed because filenames in the setup script are
+always supplied in \UNIX{} style, and have to be converted to the local
+convention before we can actually use them in the filesystem.  Raises
+\exception{ValueError} on non-\UNIX-ish systems if \var{pathname} either 
+starts or ends with a slash.
+\end{funcdesc}
+
+\begin{funcdesc}{change_root}{new_root, pathname}
+Return \var{pathname} with \var{new_root} prepended.  If \var{pathname} is
+relative, this is equivalent to \samp{os.path.join(new_root,pathname)}
+Otherwise, it requires making \var{pathname} relative and then joining the
+two, which is tricky on DOS/Windows.
+\end{funcdesc}
+
+\begin{funcdesc}{check_environ}{}
+Ensure that 'os.environ' has all the environment variables we
+guarantee that users can use in config files, command-line options,
+etc.  Currently this includes:
+\begin{itemize}
+\item \envvar{HOME} - user's home directory (\UNIX{} only)
+\item \envvar{PLAT} - description of the current platform, including
+      hardware and OS (see \function{get_platform()})
+\end{itemize}
+\end{funcdesc}
+
+\begin{funcdesc}{subst_vars}{s, local_vars}
+Perform shell/Perl-style variable substitution on \var{s}.  Every
+occurrence of \code{\$} followed by a name is considered a variable, and
+variable is substituted by the value found in the \var{local_vars}
+dictionary, or in \code{os.environ} if it's not in \var{local_vars}.
+\var{os.environ} is first checked/augmented to guarantee that it contains
+certain values: see \function{check_environ()}.  Raise \exception{ValueError} 
+for any variables not found in either \var{local_vars} or \code{os.environ}.
+
+Note that this is not a fully-fledged string interpolation function. A
+valid \code{\$variable} can consist only of upper and lower case letters,
+numbers and an underscore. No \{ \} or \( \) style quoting is available.
+\end{funcdesc}
+
+\begin{funcdesc}{grok_environment_error}{exc\optional{, prefix=\samp{'error: '}}}
+Generate a useful error message from an \exception{EnvironmentError} 
+(\exception{IOError} or \exception{OSError}) exception object.  
+Handles Python 1.5.1 and later styles, and does what it can to deal with 
+exception objects that don't have a filename (which happens when the error 
+is due to a two-file operation, such as \function{rename()} or 
+\function{link()}).  Returns the error message as a string prefixed 
+with \var{prefix}.
+\end{funcdesc}
+
+\begin{funcdesc}{split_quoted}{s}
+Split a string up according to \UNIX{} shell-like rules for quotes and
+backslashes.  In short: words are delimited by spaces, as long as those
+spaces are not escaped by a backslash, or inside a quoted string.
+Single and double quotes are equivalent, and the quote characters can
+be backslash-escaped.  The backslash is stripped from any two-character
+escape sequence, leaving only the escaped character.  The quote
+characters are stripped from any quoted string.  Returns a list of
+words.
+% Should probably be moved into the standard library.
+\end{funcdesc}
+
+\begin{funcdesc}{execute}{func, args\optional{, msg=\code{None}, verbose=\code{0}, dry_run=\code{0}}}
+Perform some action that affects the outside world (for instance,
+writing to the filesystem).  Such actions are special because they
+are disabled by the \var{dry_run} flag.  This method takes 
+care of all that bureaucracy for you; all you have to do is supply the
+function to call and an argument tuple for it (to embody the
+``external action'' being performed), and an optional message to
+print.
+\end{funcdesc}
+
+\begin{funcdesc}{strtobool}{val}
+Convert a string representation of truth to true (1) or false (0).
+
+True values are \code{y}, \code{yes}, \code{t}, \code{true}, \code{on} 
+and \code{1}; false values are \code{n}, \code{no}, \code{f}, \code{false}, 
+\code{off} and \code{0}.  Raises \exception{ValueError} if \var{val} 
+is anything else.
+\end{funcdesc}
+
+\begin{funcdesc}{byte_compile}{py_files\optional{,
+              optimize=\code{0}, force=\code{0},
+              prefix=\code{None}, base_dir=\code{None},
+              verbose=\code{1}, dry_run=\code{0},
+              direct=\code{None}}}
+Byte-compile a collection of Python source files to either \file{.pyc}
+or \file{.pyo} files in the same directory.  \var{py_files} is a list of files
+to compile; any files that don't end in \file{.py} are silently skipped.
+\var{optimize} must be one of the following:
+\begin{itemize}
+\item \code{0} - don't optimize (generate \file{.pyc})
+\item \code{1} - normal optimization (like \samp{python -O})
+\item \code{2} - extra optimization (like \samp{python -OO})
+\end{itemize}
+
+If \var{force} is true, all files are recompiled regardless of
+timestamps.
+
+The source filename encoded in each bytecode file defaults to the
+filenames listed in \var{py_files}; you can modify these with \var{prefix} and
+\var{basedir}.  \var{prefix} is a string that will be stripped off of each
+source filename, and \var{base_dir} is a directory name that will be
+prepended (after \var{prefix} is stripped).  You can supply either or both
+(or neither) of \var{prefix} and \var{base_dir}, as you wish.
+
+If \var{dry_run} is true, doesn't actually do anything that would
+affect the filesystem.
+
+Byte-compilation is either done directly in this interpreter process
+with the standard \module{py_compile} module, or indirectly by writing a
+temporary script and executing it.  Normally, you should let
+\function{byte_compile()} figure out to use direct compilation or not (see
+the source for details).  The \var{direct} flag is used by the script
+generated in indirect mode; unless you know what you're doing, leave
+it set to \code{None}.
+\end{funcdesc}
+
+\begin{funcdesc}{rfc822_escape}{header}
+Return a version of \var{header} escaped for inclusion in an
+\rfc{822} header, by ensuring there are 8 spaces space after each newline.
+Note that it does no other modification of the string.
+% this _can_ be replaced
+\end{funcdesc}
+
+%\subsection{Distutils objects}
+
+\section{\module{distutils.dist} --- The Distribution class}
+\declaremodule{standard}{distutils.dist}
+\modulesynopsis{Provides the Distribution class, which represents the
+                module distribution being built/installed/distributed}
+
+This module provides the \class{Distribution} class, which represents
+the module distribution being built/installed/distributed.
+
+
+\section{\module{distutils.extension} --- The Extension class}
+\declaremodule{standard}{distutils.extension}
+\modulesynopsis{Provides the Extension class, used to describe
+                C/\Cpp{} extension modules in setup scripts}
+
+This module provides the \class{Extension} class, used to describe
+C/\Cpp{} extension modules in setup scripts.
+
+%\subsection{Ungrouped modules}
+%The following haven't been moved into a more appropriate section yet.
+
+\section{\module{distutils.debug} --- Distutils debug mode}
+\declaremodule{standard}{distutils.debug}
+\modulesynopsis{Provides the debug flag for distutils}
+
+This module provides the DEBUG flag.
+
+\section{\module{distutils.errors} --- Distutils exceptions}
+\declaremodule{standard}{distutils.errors}
+\modulesynopsis{Provides standard distutils exceptions}
+
+Provides exceptions used by the Distutils modules.  Note that Distutils
+modules may raise standard exceptions; in particular, SystemExit is
+usually raised for errors that are obviously the end-user's fault
+(eg. bad command-line arguments).
+
+This module is safe to use in \samp{from ... import *} mode; it only exports
+symbols whose names start with \code{Distutils} and end with \code{Error}.
+
+\section{\module{distutils.fancy_getopt}
+         --- Wrapper around the standard getopt module}
+\declaremodule[distutils.fancygetopt]{standard}{distutils.fancy_getopt}
+\modulesynopsis{Additional \module{getopt} functionality}
+
+This module provides a wrapper around the standard \module{getopt} 
+module that provides the following additional features:
+
+\begin{itemize}
+\item short and long options are tied together
+\item options have help strings, so \function{fancy_getopt} could potentially 
+create a complete usage summary
+\item options set attributes of a passed-in object
+\item boolean options can have ``negative aliases'' --- eg. if
+\longprogramopt{quiet} is the ``negative alias'' of
+\longprogramopt{verbose}, then \longprogramopt{quiet} on the command
+line sets \var{verbose} to false.
+
+\end{itemize}
+
+\XXX{Should be replaced with \module{optik} (which is also now
+known as \module{optparse} in Python 2.3 and later).}
+
+\begin{funcdesc}{fancy_getopt}{options, negative_opt, object, args}
+Wrapper function. \var{options} is a list of
+\samp{(long_option, short_option, help_string)} 3-tuples as described in the
+constructor for \class{FancyGetopt}. \var{negative_opt} should be a dictionary
+mapping option names to option names, both the key and value should be in the
+\var{options} list. \var{object} is an object which will be used to store
+values (see the \method{getopt()} method of the \class{FancyGetopt} class).
+\var{args} is the argument list. Will use \code{sys.argv[1:]} if you 
+pass \code{None} as \var{args}.
+\end{funcdesc}
+
+\begin{funcdesc}{wrap_text}{text, width}
+Wraps \var{text} to less than \var{width} wide.
+
+\warning{Should be replaced with \module{textwrap} (which is available 
+in Python 2.3 and later).}
+\end{funcdesc}
+
+\begin{classdesc}{FancyGetopt}{\optional{option_table=\code{None}}}
+The option_table is a list of 3-tuples: \samp{(long_option,
+short_option, help_string)}
+
+If an option takes an argument, its \var{long_option} should have \code{'='}
+appended; \var{short_option} should just be a single character, no \code{':'}
+in any case. \var{short_option} should be \code{None} if a \var{long_option} 
+doesn't have a corresponding \var{short_option}. All option tuples must have
+long options.
+\end{classdesc}
+
+The \class{FancyGetopt} class provides the following methods:
+
+\begin{methoddesc}{getopt}{\optional{args=\code{None}, object=\code{None}}}
+Parse command-line options in args. Store as attributes on \var{object}.
+
+If \var{args} is \code{None} or not supplied, uses \code{sys.argv[1:]}.  If
+\var{object} is \code{None} or not supplied, creates a new \class{OptionDummy}
+instance, stores option values there, and returns a tuple \samp{(args,
+object)}.  If \var{object} is supplied, it is modified in place and
+\function{getopt()} just returns \var{args}; in both cases, the returned
+\var{args} is a modified copy of the passed-in \var{args} list, which
+is left untouched.
+% and args returned are?
+\end{methoddesc}
+
+\begin{methoddesc}{get_option_order}{}
+Returns the list of \samp{(option, value)} tuples processed by the
+previous run of \method{getopt()}  Raises \exception{RuntimeError} if
+\method{getopt()} hasn't been called yet.
+\end{methoddesc}
+
+\begin{methoddesc}{generate_help}{\optional{header=\code{None}}}
+Generate help text (a list of strings, one per suggested line of
+output) from the option table for this \class{FancyGetopt} object.
+
+If supplied, prints the supplied \var{header} at the top of the help.
+\end{methoddesc}
+
+\section{\module{distutils.filelist} --- The FileList class}
+\declaremodule{standard}{distutils.filelist}
+\modulesynopsis{The \class{FileList} class, used for poking about the
+                file system and building lists of files.}
+
+This module provides the \class{FileList} class, used for poking about
+the filesystem and building lists of files.
+
+
+\section{\module{distutils.log} --- Simple PEP 282-style logging}
+\declaremodule{standard}{distutils.log}
+\modulesynopsis{A simple logging mechanism, \pep{282}-style}
+
+\warning{Should be replaced with standard \module{logging} module.}
+
+%\subsubsection{\module{} --- }
+%\declaremodule{standard}{distutils.magic}
+%\modulesynopsis{ }
+
+
+\section{\module{distutils.spawn} --- Spawn a sub-process}
+\declaremodule{standard}{distutils.spawn}
+\modulesynopsis{Provides the spawn() function}
+
+This module provides the \function{spawn()} function, a front-end to 
+various platform-specific functions for launching another program in a 
+sub-process.
+Also provides \function{find_executable()} to search the path for a given
+executable name.
+
+
+\input{sysconfig}
+
+
+\section{\module{distutils.text_file} --- The TextFile class}
+\declaremodule[distutils.textfile]{standard}{distutils.text_file}
+\modulesynopsis{provides the TextFile class, a simple interface to text files}
+
+This module provides the \class{TextFile} class, which gives an interface 
+to text files that (optionally) takes care of stripping comments, ignoring 
+blank lines, and joining lines with backslashes.
+
+\begin{classdesc}{TextFile}{\optional{filename=\code{None}, file=\code{None}, **options}}
+This class provides a file-like object that takes care of all 
+the things you commonly want to do when processing a text file 
+that has some line-by-line syntax: strip comments (as long as \code{\#} 
+is your comment character), skip blank lines, join adjacent lines by
+escaping the newline (ie. backslash at end of line), strip
+leading and/or trailing whitespace.  All of these are optional
+and independently controllable.
+
+The class provides a \method{warn()} method so you can generate 
+warning messages that report physical line number, even if the 
+logical line in question spans multiple physical lines.  Also 
+provides \method{unreadline()} for implementing line-at-a-time lookahead.
+
+\class{TextFile} instances are create with either \var{filename}, \var{file},
+or both. \exception{RuntimeError} is raised if both are \code{None}.
+\var{filename} should be a string, and \var{file} a file object (or
+something that provides \method{readline()} and \method{close()} 
+methods).  It is recommended that you supply at least \var{filename}, 
+so that \class{TextFile} can include it in warning messages.  If 
+\var{file} is not supplied, \class{TextFile} creates its own using the 
+\function{open()} built-in function.
+
+The options are all boolean, and affect the values returned by
+\method{readline()}
+
+\begin{tableiii}{c|l|l}{option name}{option name}{description}{default}
+\lineiii{strip_comments}{
+strip from \character{\#} to end-of-line, as well as any whitespace
+leading up to the \character{\#}---unless it is escaped by a backslash}
+{true}
+\lineiii{lstrip_ws}{
+strip leading whitespace from each line before returning it}
+{false}
+\lineiii{rstrip_ws}{
+strip trailing whitespace (including line terminator!) from
+each line before returning it.}
+{true}
+\lineiii{skip_blanks}{
+skip lines that are empty *after* stripping comments and
+whitespace.  (If both lstrip_ws and rstrip_ws are false,
+then some lines may consist of solely whitespace: these will
+*not* be skipped, even if \var{skip_blanks} is true.)}
+{true}
+\lineiii{join_lines}{
+if a backslash is the last non-newline character on a line
+after stripping comments and whitespace, join the following line
+to it to form one logical line; if N consecutive lines end
+with a backslash, then N+1 physical lines will be joined to
+form one logical line.}
+{false}
+\lineiii{collapse_join}{
+strip leading whitespace from lines that are joined to their
+predecessor; only matters if \samp{(join_lines and not lstrip_ws)}}
+{false}
+\end{tableiii}
+
+Note that since \var{rstrip_ws} can strip the trailing newline, the
+semantics of \method{readline()} must differ from those of the builtin file
+object's \method{readline()} method!  In particular, \method{readline()} 
+returns \code{None} for end-of-file: an empty string might just be a 
+blank line (or an all-whitespace line), if \var{rstrip_ws} is true 
+but \var{skip_blanks} is not.
+
+\begin{methoddesc}{open}{filename}
+Open a new file \var{filename}. This overrides any \var{file} or 
+\var{filename} constructor arguments.
+\end{methoddesc}
+
+\begin{methoddesc}{close}{}
+Close the current file and forget everything we know about it (including
+the filename and the current line number).
+\end{methoddesc}
+
+\begin{methoddesc}{warn}{msg\optional{,line=\code{None}}}
+Print (to stderr) a warning message tied to the current logical
+line in the current file.  If the current logical line in the
+file spans multiple physical lines, the warning refers to the
+whole range, such as \samp{"lines 3-5"}.  If \var{line} is supplied, 
+it overrides the current line number; it may be a list or tuple 
+to indicate a range of physical lines, or an integer for a 
+single physical line.
+\end{methoddesc}
+
+\begin{methoddesc}{readline}{}
+Read and return a single logical line from the current file (or
+from an internal buffer if lines have previously been ``unread''
+with \method{unreadline()}).  If the \var{join_lines} option 
+is true, this may involve reading multiple physical lines 
+concatenated into a single string.  Updates the current line number, 
+so calling \method{warn()} after \method{readline()} emits a warning 
+about the physical line(s) just read.  Returns \code{None} on end-of-file, 
+since the empty string can occur if \var{rstrip_ws} is true but 
+\var{strip_blanks} is not.
+\end{methoddesc}
+\begin{methoddesc}{readlines}{}
+Read and return the list of all logical lines remaining in the current file.
+This updates the current line number to the last line of the file.
+\end{methoddesc}
+\begin{methoddesc}{unreadline}{line}
+Push \var{line} (a string) onto an internal buffer that will be
+checked by future \method{readline()} calls.  Handy for implementing
+a parser with line-at-a-time lookahead. Note that lines that are ``unread''
+with \method{unreadline} are not subsequently re-cleansed (whitespace 
+stripped, or whatever) when read with \method{readline}. If multiple
+calls are made to \method{unreadline} before a call to \method{readline},
+the lines will be returned most in most recent first order.
+\end{methoddesc}
+
+\end{classdesc}
+
+
+\section{\module{distutils.version} --- Version number classes}
+\declaremodule{standard}{distutils.version}
+\modulesynopsis{implements classes that represent module version numbers. }
+
+% todo
+
+%\section{Distutils Commands}
+%
+%This part of Distutils implements the various Distutils commands, such
+%as \code{build}, \code{install} \&c. Each command is implemented as a
+%separate module, with the command name as the name of the module.
+
+\section{\module{distutils.cmd} --- Abstract base class for Distutils commands}
+\declaremodule{standard}{distutils.cmd}
+\modulesynopsis{This module provides the abstract base class Command. This
+class is subclassed by the modules in the \refmodule{distutils.command} 
+subpackage. }
+
+This module supplies the abstract base class \class{Command}. 
+
+\begin{classdesc}{Command}{dist}
+Abstract base class for defining command classes, the ``worker bees''
+of the Distutils.  A useful analogy for command classes is to think of
+them as subroutines with local variables called \var{options}.  The
+options are declared in \method{initialize_options()} and defined
+(given their final values) in \method{finalize_options()}, both of
+which must be defined by every command class.  The distinction between
+the two is necessary because option values might come from the outside
+world (command line, config file, ...), and any options dependent on
+other options must be computed after these outside influences have
+been processed --- hence \method{finalize_options()}.  The body of the
+subroutine, where it does all its work based on the values of its
+options, is the \method{run()} method, which must also be implemented
+by every command class.
+
+The class constructor takes a single argument \var{dist}, a 
+\class{Distribution} instance. 
+\end{classdesc}
+
+
+\section{\module{distutils.command} --- Individual Distutils commands}
+\declaremodule{standard}{distutils.command}
+\modulesynopsis{This subpackage contains one module for each standard Distutils command.}
+
+%\subsubsection{Individual Distutils commands}
+
+% todo
+
+\section{\module{distutils.command.bdist} --- Build a binary installer}
+\declaremodule{standard}{distutils.command.bdist}
+\modulesynopsis{Build a binary installer for a package}
+
+% todo
+
+\section{\module{distutils.command.bdist_packager} --- Abstract base class for packagers}
+\declaremodule[distutils.command.bdistpackager]{standard}{distutils.command.bdist_packager}
+\modulesynopsis{Abstract base class for packagers}
+
+% todo
+
+\section{\module{distutils.command.bdist_dumb} --- Build a ``dumb'' installer}
+\declaremodule[distutils.command.bdistdumb]{standard}{distutils.command.bdist_dumb}
+\modulesynopsis{Build a ``dumb'' installer - a simple archive of files}
+
+% todo
+
+\section{\module{distutils.command.bdist_msi} --- Build a Microsoft Installer binary package}
+\declaremodule[distutils.command.bdistmsi]{standard}{distutils.command.bdist_msi}
+\modulesynopsis{Build a binary distribution as a Windows MSI file}
+
+% todo
+
+\section{\module{distutils.command.bdist_rpm} --- Build a binary distribution as a Redhat RPM and SRPM}
+\declaremodule[distutils.command.bdistrpm]{standard}{distutils.command.bdist_rpm}
+\modulesynopsis{Build a binary distribution as a Redhat RPM and SRPM}
+
+% todo
+
+\section{\module{distutils.command.bdist_wininst} --- Build a Windows installer}
+\declaremodule[distutils.command.bdistwininst]{standard}{distutils.command.bdist_wininst}
+\modulesynopsis{Build a Windows installer}
+
+% todo
+
+\section{\module{distutils.command.sdist} --- Build a source distribution}
+\declaremodule{standard}{distutils.command.sdist}
+\modulesynopsis{Build a source distribution}
+
+% todo
+
+\section{\module{distutils.command.build} --- Build all files of a package}
+\declaremodule{standard}{distutils.command.build}
+\modulesynopsis{Build all files of a package}
+
+% todo
+
+\section{\module{distutils.command.build_clib} --- Build any C libraries in a package}
+\declaremodule[distutils.command.buildclib]{standard}{distutils.command.build_clib}
+\modulesynopsis{Build any C libraries in a package}
+
+% todo
+
+\section{\module{distutils.command.build_ext} --- Build any extensions in a package}
+\declaremodule[distutils.command.buildext]{standard}{distutils.command.build_ext}
+\modulesynopsis{Build any extensions in a package}
+
+% todo
+
+\section{\module{distutils.command.build_py} --- Build the .py/.pyc files of a package}
+\declaremodule[distutils.command.buildpy]{standard}{distutils.command.build_py}
+\modulesynopsis{Build the .py/.pyc files of a package}
+
+% todo
+
+\section{\module{distutils.command.build_scripts} --- Build the scripts of a package}
+\declaremodule[distutils.command.buildscripts]{standard}{distutils.command.build_scripts}
+\modulesynopsis{Build the scripts of a package}
+
+% todo
+
+\section{\module{distutils.command.clean} --- Clean a package build area}
+\declaremodule{standard}{distutils.command.clean}
+\modulesynopsis{Clean a package build area}
+
+% todo
+
+\section{\module{distutils.command.config} --- Perform package configuration}
+\declaremodule{standard}{distutils.command.config}
+\modulesynopsis{Perform package configuration}
+
+% todo
+
+\section{\module{distutils.command.install} --- Install a package}
+\declaremodule{standard}{distutils.command.install}
+\modulesynopsis{Install a package}
+
+% todo
+
+\section{\module{distutils.command.install_data}
+               --- Install data files from a package}
+\declaremodule[distutils.command.installdata]{standard}{distutils.command.install_data}
+\modulesynopsis{Install data files from a package}
+
+% todo
+
+\section{\module{distutils.command.install_headers}
+               --- Install C/\Cpp{} header files from a package}
+\declaremodule[distutils.command.installheaders]{standard}{distutils.command.install_headers}
+\modulesynopsis{Install C/\Cpp{} header files from a package}
+
+% todo
+
+\section{\module{distutils.command.install_lib}
+               --- Install library files from a package}
+\declaremodule[distutils.command.installlib]{standard}{distutils.command.install_lib}
+\modulesynopsis{Install library files from a package}
+
+% todo
+
+\section{\module{distutils.command.install_scripts}
+               --- Install script files from a package}
+\declaremodule[distutils.command.installscripts]{standard}{distutils.command.install_scripts}
+\modulesynopsis{Install script files from a package}
+
+% todo
+
+\section{\module{distutils.command.register}
+               --- Register a module with the Python Package Index}
+\declaremodule{standard}{distutils.command.register}
+\modulesynopsis{Register a module with the Python Package Index}
+
+The \code{register} command registers the package with the Python Package 
+Index.  This is described in more detail in \pep{301}.
+% todo
+
+\section{Creating a new Distutils command}
+
+This section outlines the steps to create a new Distutils command.
+
+A new command lives in a module in the \module{distutils.command}
+package. There is a sample template in that directory called 
+\file{command_template}. Copy this file to a new module with the
+same name as the new command you're implementing. This module should
+implement a class with the same name as the module (and the command).
+So, for instance, to create the command \code{peel_banana} (so that users
+can run \samp{setup.py peel_banana}), you'd copy \file{command_template} 
+to \file{distutils/command/peel_banana.py}, then edit it so that it's
+implementing the class \class{peel_banana}, a subclass of 
+\class{distutils.cmd.Command}.
+
+Subclasses of \class{Command} must define the following methods.
+
+\begin{methoddesc}{initialize_options()}
+Set default values for all the options that this command
+supports.  Note that these defaults may be overridden by other
+commands, by the setup script, by config files, or by the
+command-line.  Thus, this is not the place to code dependencies
+between options; generally, \method{initialize_options()} implementations
+are just a bunch of \samp{self.foo = None} assignments.
+\end{methoddesc}
+
+\begin{methoddesc}{finalize_options}{}
+Set final values for all the options that this command supports.
+This is always called as late as possible, ie.  after any option
+assignments from the command-line or from other commands have been
+done.  Thus, this is the place to to code option dependencies: if
+\var{foo} depends on \var{bar}, then it is safe to set \var{foo} from 
+\var{bar} as long as \var{foo} still has the same value it was assigned in
+\method{initialize_options()}.
+\end{methoddesc}
+\begin{methoddesc}{run}{}
+A command's raison d'etre: carry out the action it exists to
+perform, controlled by the options initialized in
+\method{initialize_options()}, customized by other commands, the setup
+script, the command-line, and config files, and finalized in
+\method{finalize_options()}.  All terminal output and filesystem
+interaction should be done by \method{run()}.
+\end{methoddesc}
+
+\var{sub_commands} formalizes the notion of a ``family'' of commands,
+eg. \code{install} as the parent with sub-commands \code{install_lib},
+\code{install_headers}, etc.  The parent of a family of commands
+defines \var{sub_commands} as a class attribute; it's a list of
+2-tuples \samp{(command_name, predicate)}, with \var{command_name} a string
+and \var{predicate} an unbound method, a string or None.
+\var{predicate} is a method of the parent command that
+determines whether the corresponding command is applicable in the
+current situation.  (Eg. we \code{install_headers} is only applicable if
+we have any C header files to install.)  If \var{predicate} is None,
+that command is always applicable.
+
+\var{sub_commands} is usually defined at the *end* of a class, because
+predicates can be unbound methods, so they must already have been
+defined.  The canonical example is the \command{install} command.
+
+%
+%  The ugly "%begin{latexonly}" pseudo-environments are really just to
+%  keep LaTeX2HTML quiet during the \renewcommand{} macros; they're
+%  not really valuable.
+%
+
+%begin{latexonly}
+\renewcommand{\indexname}{Module Index}
+%end{latexonly}
+\input{moddist.ind}             % Module Index
+
+%begin{latexonly}
+\renewcommand{\indexname}{Index}
+%end{latexonly}
+\input{dist.ind}                % Index
+
+\end{document}

Added: vendor/Python/current/Doc/dist/sysconfig.tex
===================================================================
--- vendor/Python/current/Doc/dist/sysconfig.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/dist/sysconfig.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,113 @@
+\section{\module{distutils.sysconfig} ---
+         System configuration information}
+
+\declaremodule{standard}{distutils.sysconfig}
+\modulesynopsis{Low-level access to configuration information of the
+                Python interpreter.}
+\moduleauthor{Fred L. Drake, Jr.}{fdrake at acm.org}
+\moduleauthor{Greg Ward}{gward at python.net}
+\sectionauthor{Fred L. Drake, Jr.}{fdrake at acm.org}
+
+
+The \module{distutils.sysconfig} module provides access to Python's
+low-level configuration information.  The specific configuration
+variables available depend heavily on the platform and configuration.
+The specific variables depend on the build process for the specific
+version of Python being run; the variables are those found in the
+\file{Makefile} and configuration header that are installed with
+Python on \UNIX{} systems.  The configuration header is called
+\file{pyconfig.h} for Python versions starting with 2.2, and
+\file{config.h} for earlier versions of Python.
+
+Some additional functions are provided which perform some useful
+manipulations for other parts of the \module{distutils} package.
+
+
+\begin{datadesc}{PREFIX}
+  The result of \code{os.path.normpath(sys.prefix)}.
+\end{datadesc}
+
+\begin{datadesc}{EXEC_PREFIX}
+  The result of \code{os.path.normpath(sys.exec_prefix)}.
+\end{datadesc}
+
+\begin{funcdesc}{get_config_var}{name}
+  Return the value of a single variable.  This is equivalent to
+  \code{get_config_vars().get(\var{name})}.
+\end{funcdesc}
+
+\begin{funcdesc}{get_config_vars}{\moreargs}
+  Return a set of variable definitions.  If there are no arguments,
+  this returns a dictionary mapping names of configuration variables
+  to values.  If arguments are provided, they should be strings, and
+  the return value will be a sequence giving the associated values.
+  If a given name does not have a corresponding value, \code{None}
+  will be included for that variable.
+\end{funcdesc}
+
+\begin{funcdesc}{get_config_h_filename}{}
+  Return the full path name of the configuration header.  For \UNIX,
+  this will be the header generated by the \program{configure} script;
+  for other platforms the header will have been supplied directly by
+  the Python source distribution.  The file is a platform-specific
+  text file.
+\end{funcdesc}
+
+\begin{funcdesc}{get_makefile_filename}{}
+  Return the full path name of the \file{Makefile} used to build
+  Python.  For \UNIX, this will be a file generated by the
+  \program{configure} script; the meaning for other platforms will
+  vary.  The file is a platform-specific text file, if it exists.
+  This function is only useful on \POSIX{} platforms.
+\end{funcdesc}
+
+\begin{funcdesc}{get_python_inc}{\optional{plat_specific\optional{, prefix}}}
+  Return the directory for either the general or platform-dependent C
+  include files.  If \var{plat_specific} is true, the
+  platform-dependent include directory is returned; if false or
+  omitted, the platform-independent directory is returned.  If
+  \var{prefix} is given, it is used as either the prefix instead of
+  \constant{PREFIX}, or as the exec-prefix instead of
+  \constant{EXEC_PREFIX} if \var{plat_specific} is true.
+\end{funcdesc}
+
+\begin{funcdesc}{get_python_lib}{\optional{plat_specific\optional{,
+                                 standard_lib\optional{, prefix}}}}
+  Return the directory for either the general or platform-dependent
+  library installation.  If \var{plat_specific} is true, the
+  platform-dependent include directory is returned; if false or
+  omitted, the platform-independent directory is returned.  If
+  \var{prefix} is given, it is used as either the prefix instead of
+  \constant{PREFIX}, or as the exec-prefix instead of
+  \constant{EXEC_PREFIX} if \var{plat_specific} is true.  If
+  \var{standard_lib} is true, the directory for the standard library
+  is returned rather than the directory for the installation of
+  third-party extensions.
+\end{funcdesc}
+
+
+The following function is only intended for use within the
+\module{distutils} package.
+
+\begin{funcdesc}{customize_compiler}{compiler}
+  Do any platform-specific customization of a
+  \class{distutils.ccompiler.CCompiler} instance.
+
+  This function is only needed on \UNIX{} at this time, but should be
+  called consistently to support forward-compatibility.  It inserts
+  the information that varies across \UNIX{} flavors and is stored in
+  Python's \file{Makefile}.  This information includes the selected
+  compiler, compiler and linker options, and the extension used by the
+  linker for shared objects.
+\end{funcdesc}
+
+
+This function is even more special-purpose, and should only be used
+from Python's own build procedures.
+
+\begin{funcdesc}{set_python_build}{}
+  Inform the \module{distutils.sysconfig} module that it is being used
+  as part of the build process for Python.  This changes a lot of
+  relative locations for files, allowing them to be located in the
+  build area rather than in an installed Python.
+\end{funcdesc}

Added: vendor/Python/current/Doc/doc/doc.tex
===================================================================
--- vendor/Python/current/Doc/doc/doc.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/doc/doc.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2129 @@
+\documentclass{howto}
+\usepackage{ltxmarkup}
+
+\title{Documenting Python}
+
+\makeindex
+
+\input{boilerplate}
+
+% Now override the stuff that includes author information;
+% Guido did *not* write this one!
+
+\author{Fred L. Drake, Jr.}
+\authoraddress{
+        PythonLabs \\
+        Email: \email{fdrake at acm.org}
+}
+
+
+\begin{document}
+
+\maketitle
+
+\begin{abstract}
+\noindent
+The Python language has a substantial body of
+documentation, much of it contributed by various authors.  The markup
+used for the Python documentation is based on \LaTeX{} and requires a
+significant set of macros written specifically for documenting Python.
+This document describes the macros introduced to support Python
+documentation and how they should be used to support a wide range of
+output formats.
+
+This document describes the document classes and special markup used
+in the Python documentation.  Authors may use this guide, in
+conjunction with the template files provided with the
+distribution, to create or maintain whole documents or sections.
+
+If you're interested in contributing to Python's documentation,
+there's no need to learn \LaTeX{} if you're not so inclined; plain
+text contributions are more than welcome as well.
+\end{abstract}
+
+\tableofcontents
+
+
+\section{Introduction \label{intro}}
+
+  Python's documentation has long been considered to be good for a
+  free programming language.  There are a number of reasons for this,
+  the most important being the early commitment of Python's creator,
+  Guido van Rossum, to providing documentation on the language and its
+  libraries, and the continuing involvement of the user community in
+  providing assistance for creating and maintaining documentation.
+
+  The involvement of the community takes many forms, from authoring to
+  bug reports to just plain complaining when the documentation could
+  be more complete or easier to use.  All of these forms of input from
+  the community have proved useful during the time I've been involved
+  in maintaining the documentation.
+
+  This document is aimed at authors and potential authors of
+  documentation for Python.  More specifically, it is for people
+  contributing to the standard documentation and developing additional
+  documents using the same tools as the standard documents.  This
+  guide will be less useful for authors using the Python documentation
+  tools for topics other than Python, and less useful still for
+  authors not using the tools at all.
+
+  The material in this guide is intended to assist authors using the
+  Python documentation tools.  It includes information on the source
+  distribution of the standard documentation, a discussion of the
+  document types, reference material on the markup defined in the
+  document classes, a list of the external tools needed for processing
+  documents, and reference material on the tools provided with the
+  documentation resources.  At the end, there is also a section
+  discussing future directions for the Python documentation and where
+  to turn for more information.
+
+  If your interest is in contributing to the Python documentation, but
+  you don't have the time or inclination to learn \LaTeX{} and the
+  markup structures documented here, there's a welcoming place for you
+  among the Python contributors as well.  Any time you feel that you
+  can clarify existing documentation or provide documentation that's
+  missing, the existing documentation team will gladly work with you
+  to integrate your text, dealing with the markup for you.  Please
+  don't let the material in this document stand between the
+  documentation and your desire to help out!
+
+\section{Directory Structure \label{directories}}
+
+  The source distribution for the standard Python documentation
+  contains a large number of directories.  While third-party documents
+  do not need to be placed into this structure or need to be placed
+  within a similar structure, it can be helpful to know where to look
+  for examples and tools when developing new documents using the
+  Python documentation tools.  This section describes this directory
+  structure.
+
+  The documentation sources are usually placed within the Python
+  source distribution as the top-level directory \file{Doc/}, but
+  are not dependent on the Python source distribution in any way.
+
+  The \file{Doc/} directory contains a few files and several
+  subdirectories.  The files are mostly self-explanatory, including a
+  \file{README} and a \file{Makefile}.  The directories fall into
+  three categories:
+
+  \begin{definitions}
+    \term{Document Sources}
+        The \LaTeX{} sources for each document are placed in a
+        separate directory.  These directories are given short
+        names which vaguely indicate the document in each:
+
+        \begin{tableii}{p{.75in}|p{3in}}{filenq}{Directory}{Document Title}
+          \lineii{api/}
+            {\citetitle[../api/api.html]{The Python/C API}}
+          \lineii{dist/}
+            {\citetitle[../dist/dist.html]{Distributing Python Modules}}
+          \lineii{doc/}
+            {\citetitle[../doc/doc.html]{Documenting Python}}
+          \lineii{ext/}
+            {\citetitle[../ext/ext.html]
+                       {Extending and Embedding the Python Interpreter}}
+          \lineii{inst/}
+            {\citetitle[../inst/inst.html]{Installing Python Modules}}
+          \lineii{lib/}
+            {\citetitle[../lib/lib.html]{Python Library Reference}}
+          \lineii{mac/}
+            {\citetitle[../mac/mac.html]{Macintosh Module Reference}}
+          \lineii{ref/}
+            {\citetitle[../ref/ref.html]{Python Reference Manual}}
+          \lineii{tut/}
+            {\citetitle[../tut/tut.html]{Python Tutorial}}
+          \lineii{whatsnew/}
+            {\citetitle[../whatsnew/whatsnew24.html]
+                       {What's New in Python \shortversion}}
+        \end{tableii}
+
+    \term{Format-Specific Output}
+        Most output formats have a directory which contains a
+        \file{Makefile} which controls the generation of that format
+        and provides storage for the formatted documents.  The only
+        variations within this category are the Portable Document
+        Format (PDF) and PostScript versions are placed in the
+        directories \file{paper-a4/} and \file{paper-letter/} (this
+        causes all the temporary files created by \LaTeX{} to be kept
+        in the same place for each paper size, where they can be more
+        easily ignored).
+
+        \begin{tableii}{p{.75in}|p{3in}}{filenq}{Directory}{Output Formats}
+          \lineii{html/}{HTML output}
+          \lineii{info/}{GNU info output}
+          \lineii{isilo/}{\ulink{iSilo}{http://www.isilo.com/}
+                          documents (for Palm OS devices)}
+          \lineii{paper-a4/}{PDF and PostScript, A4 paper}
+          \lineii{paper-letter/}{PDF and PostScript, US-Letter paper}
+        \end{tableii}
+
+    \term{Supplemental Files}
+        Some additional directories are used to store supplemental
+        files used for the various processes.  Directories are
+        included for the shared \LaTeX{} document classes, the
+        \LaTeX2HTML support, template files for various document
+        components, and the scripts used to perform various steps in
+        the formatting processes.
+
+        \begin{tableii}{p{.75in}|p{3in}}{filenq}{Directory}{Contents}
+          \lineii{commontex/}{Document content shared among documents}
+          \lineii{perl/}     {Support for \LaTeX2HTML processing}
+          \lineii{templates/}{Example files for source documents}
+          \lineii{texinputs/}{Style implementation for \LaTeX}
+          \lineii{tools/}    {Custom processing scripts}
+        \end{tableii}
+
+  \end{definitions}
+
+
+\section{Style Guide \label{style-guide}}
+
+  The Python documentation should follow the \citetitle
+  [http://developer.apple.com/documentation/UserExperience/Conceptual/APStyleGuide/AppleStyleGuide2003.pdf]
+  {Apple Publications Style Guide} wherever possible.  This particular
+  style guide was selected mostly because it seems reasonable and is
+  easy to get online.
+
+  Topics which are not covered in the Apple's style guide will be
+  discussed in this document if necessary.
+
+  Footnotes are generally discouraged due to the pain of using
+  footnotes in the HTML conversion of documents.  Footnotes may be
+  used when they are the best way to present specific information.
+  When a footnote reference is added at the end of the sentence, it
+  should follow the sentence-ending punctuation.  The \LaTeX{} markup
+  should appear something like this:
+
+\begin{verbatim}
+This sentence has a footnote reference.%
+  \footnote{This is the footnote text.}
+\end{verbatim}
+
+  Footnotes may appear in the middle of sentences where appropriate.
+
+  Many special names are used in the Python documentation, including
+  the names of operating systems, programming languages, standards
+  bodies, and the like.  Many of these were assigned \LaTeX{} macros
+  at some point in the distant past, and these macros lived on long
+  past their usefulness.  In the current markup, most of these entities
+  are not assigned any special markup, but the preferred spellings are
+  given here to aid authors in maintaining the consistency of
+  presentation in the Python documentation.
+
+  Other terms and words deserve special mention as well; these conventions
+  should be used to ensure consistency throughout the documentation:
+
+  \begin{description}
+    \item[CPU]
+    For ``central processing unit.''  Many style guides say this
+    should be spelled out on the first use (and if you must use it,
+    do so!).  For the Python documentation, this abbreviation should
+    be avoided since there's no reasonable way to predict which occurrence
+    will be the first seen by the reader.  It is better to use the
+    word ``processor'' instead.
+
+    \item[\POSIX]
+        The name assigned to a particular group of standards.  This is
+        always uppercase.  Use the macro \macro{POSIX} to represent this
+        name.
+
+    \item[Python]
+        The name of our favorite programming language is always
+        capitalized.
+
+    \item[Unicode]
+        The name of a character set and matching encoding.  This is
+        always written capitalized.
+
+    \item[\UNIX]
+        The name of the operating system developed at AT\&T Bell Labs
+        in the early 1970s.  Use the macro \macro{UNIX} to use this
+        name.
+  \end{description}
+
+
+\section{\LaTeX{} Primer \label{latex-primer}}
+
+  This section is a brief introduction to \LaTeX{} concepts and
+  syntax, to provide authors enough information to author documents
+  productively without having to become ``\TeX{}nicians.''  This does
+  not teach everything needed to know about writing \LaTeX{} for
+  Python documentation; many of the standard ``environments'' are not
+  described here (though you will learn how to mark something as an
+  environment).
+
+  Perhaps the most important concept to keep in mind while marking up
+  Python documentation is that while \TeX{} is unstructured, \LaTeX{} was
+  designed as a layer on top of \TeX{} which specifically supports
+  structured markup.  The Python-specific markup is intended to extend
+  the structure provided by standard \LaTeX{} document classes to
+  support additional information specific to Python.
+
+  \LaTeX{} documents contain two parts: the preamble and the body.
+  The preamble is used to specify certain metadata about the document
+  itself, such as the title, the list of authors, the date, and the
+  \emph{class} the document belongs to.  Additional information used
+  to control index generation and the use of bibliographic databases
+  can also be placed in the preamble.  For most authors, the preamble
+  can be most easily created by copying it from an existing document
+  and modifying a few key pieces of information.
+
+  The \dfn{class} of a document is used to place a document within a
+  broad category of documents and set some fundamental formatting
+  properties.  For Python documentation, two classes are used: the
+  \code{manual} class and the \code{howto} class.  These classes also
+  define the additional markup used to document Python concepts and
+  structures.  Specific information about these classes is provided in
+  section \ref{classes}, ``Document Classes,'' below.  The first thing
+  in the preamble is the declaration of the document's class.
+
+  After the class declaration, a number of \emph{macros} are used to
+  provide further information about the document and setup any
+  additional markup that is needed.  No output is generated from the
+  preamble; it is an error to include free text in the preamble
+  because it would cause output.
+
+  The document body follows the preamble.  This contains all the
+  printed components of the document marked up structurally.  Generic
+  \LaTeX{} structures include hierarchical sections, numbered and
+  bulleted lists, and special structures for the document abstract and
+  indexes.
+
+  \subsection{Syntax \label{latex-syntax}}
+
+    There are some things that an author of Python documentation needs
+    to know about \LaTeX{} syntax.
+
+    A \dfn{comment} is started by the ``percent'' character
+    (\character{\%}) and continues through the end of the line
+    \emph{and all leading whitespace on the following line}.  This is
+    a little different from any programming language I know of, so an
+    example is in order:
+
+\begin{verbatim}
+This is text.% comment
+    This is more text.  % another comment
+Still more text.
+\end{verbatim}
+
+    The first non-comment character following the first comment is the
+    letter \character{T} on the second line; the leading whitespace on
+    that line is consumed as part of the first comment.  This means
+    that there is no space between the first and second sentences, so
+    the period and letter \character{T} will be directly adjacent in
+    the typeset document.
+
+    Note also that though the first non-comment character after the
+    second comment is the letter \character{S}, there is whitespace
+    preceding the comment, so the two sentences are separated as
+    expected.
+
+    A \dfn{group} is an enclosure for a collection of text and
+    commands which encloses the formatting context and constrains the
+    scope of any changes to that context made by commands within the
+    group.  Groups can be nested hierarchically.  The formatting
+    context includes the font and the definition of additional macros
+    (or overrides of macros defined in outer groups).  Syntactically,
+    groups are enclosed in braces:
+
+\begin{verbatim}
+{text in a group}
+\end{verbatim}
+
+    An alternate syntax for a group using brackets, \code{[...]}, is
+    used by macros and environment constructors which take optional
+    parameters; brackets do not normally hold syntactic significance.
+    A degenerate group, containing only one atomic bit of content,
+    does not need to have an explicit group, unless it is required to
+    avoid ambiguity.  Since Python tends toward the explicit, groups
+    are also made explicit in the documentation markup.
+
+    Groups are used only sparingly in the Python documentation, except
+    for their use in marking parameters to macros and environments.
+
+    A \dfn{macro} is usually a simple construct which is identified by
+    name and can take some number of parameters.  In normal \LaTeX{}
+    usage, one of these can be optional.  The markup is introduced
+    using the backslash character (\character{\e}), and the name is
+    given by alphabetic characters (no digits, hyphens, or
+    underscores).  Required parameters should be marked as a group,
+    and optional parameters should be marked using the alternate
+    syntax for a group.
+
+    For example, a macro which takes a single parameter
+    would appear like this:
+
+\begin{verbatim}
+\name{parameter}
+\end{verbatim}
+
+    A macro which takes an optional parameter would be typed like this
+    when the optional parameter is given:
+
+\begin{verbatim}
+\name[optional]
+\end{verbatim}
+
+    If both optional and required parameters are to be required, it
+    looks like this:
+
+\begin{verbatim}
+\name[optional]{required}
+\end{verbatim}
+
+    A macro name may be followed by a space or newline; a space
+    between the macro name and any parameters will be consumed, but
+    this usage is not practiced in the Python documentation.  Such a
+    space is still consumed if there are no parameters to the macro,
+    in which case inserting an empty group (\code{\{\}}) or explicit
+    word space (\samp{\e\ }) immediately after the macro name helps to
+    avoid running the expansion of the macro into the following text.
+    Macros which take no parameters but which should not be followed
+    by a word space do not need special treatment if the following
+    character in the document source if not a name character (such as
+    punctuation).
+
+    Each line of this example shows an appropriate way to write text
+    which includes a macro which takes no parameters:
+
+\begin{verbatim}
+This \UNIX{} is followed by a space.
+This \UNIX\ is also followed by a space.
+\UNIX, followed by a comma, needs no additional markup.
+\end{verbatim}
+
+    An \dfn{environment} is a larger construct than a macro, and can
+    be used for things with more content than would conveniently fit
+    in a macro parameter.  They are primarily used when formatting
+    parameters need to be changed before and after a large chunk of
+    content, but the content itself needs to be highly flexible.  Code
+    samples are presented using an environment, and descriptions of
+    functions, methods, and classes are also marked using environments.
+
+    Since the content of an environment is free-form and can consist
+    of several paragraphs, they are actually marked using a pair of
+    macros: \macro{begin} and \macro{end}.  These macros both take the
+    name of the environment as a parameter.  An example is the
+    environment used to mark the abstract of a document:
+
+\begin{verbatim}
+\begin{abstract}
+  This is the text of the abstract.  It concisely explains what
+  information is found in the document.
+
+  It can consist of multiple paragraphs.
+\end{abstract}
+\end{verbatim}
+
+    An environment can also have required and optional parameters of
+    its own.  These follow the parameter of the \macro{begin} macro.
+    This example shows an environment which takes a single required
+    parameter:
+
+\begin{verbatim}
+\begin{datadesc}{controlnames}
+  A 33-element string array that contains the \ASCII{} mnemonics for
+  the thirty-two \ASCII{} control characters from 0 (NUL) to 0x1f
+  (US), in order, plus the mnemonic \samp{SP} for the space character.
+\end{datadesc}
+\end{verbatim}
+
+    There are a number of less-used marks in \LaTeX{} which are used
+    to enter characters which are not found in \ASCII{} or which a
+    considered special, or \emph{active} in \TeX{} or \LaTeX.  Given
+    that these are often used adjacent to other characters, the markup
+    required to produce the proper character may need to be followed
+    by a space or an empty group, or the markup can be enclosed in a
+    group.  Some which are found in Python documentation are:
+
+\begin{tableii}{c|l}{textrm}{Character}{Markup}
+  \lineii{\textasciicircum}{\code{\e textasciicircum}}
+  \lineii{\textasciitilde}{\code{\e textasciitilde}}
+  \lineii{\textgreater}{\code{\e textgreater}}
+  \lineii{\textless}{\code{\e textless}}
+  \lineii{\c c}{\code{\e c c}}
+  \lineii{\"o}{\code{\e"o}}
+  \lineii{\o}{\code{\e o}}
+\end{tableii}
+
+
+  \subsection{Hierarchical Structure \label{latex-structure}}
+
+    \LaTeX{} expects documents to be arranged in a conventional,
+    hierarchical way, with chapters, sections, sub-sections,
+    appendixes, and the like.  These are marked using macros rather
+    than environments, probably because the end of a section can be
+    safely inferred when a section of equal or higher level starts.
+
+    There are six ``levels'' of sectioning in the document classes
+    used for Python documentation, and the deepest two
+    levels\footnote{The deepest levels have the highest numbers in the
+      table.} are not used.  The levels are:
+
+      \begin{tableiii}{c|l|c}{textrm}{Level}{Macro Name}{Notes}
+        \lineiii{1}{\macro{chapter}}{(1)}
+        \lineiii{2}{\macro{section}}{}
+        \lineiii{3}{\macro{subsection}}{}
+        \lineiii{4}{\macro{subsubsection}}{}
+        \lineiii{5}{\macro{paragraph}}{(2)}
+        \lineiii{6}{\macro{subparagraph}}{}
+      \end{tableiii}
+
+    \noindent
+    Notes:
+
+    \begin{description}
+      \item[(1)]
+      Only used for the \code{manual} documents, as described in
+      section \ref{classes}, ``Document Classes.''
+      \item[(2)]
+      Not the same as a paragraph of text; nobody seems to use this.
+    \end{description}
+
+
+  \subsection{Common Environments \label{latex-environments}}
+
+    \LaTeX{} provides a variety of environments even without the
+    additional markup provided by the Python-specific document classes
+    introduced in the next section.  The following environments are
+    provided as part of standard \LaTeX{} and are being used in the
+    standard Python documentation; descriptions will be added here as
+    time allows.
+
+\begin{verbatim}
+abstract
+alltt
+description
+displaymath
+document
+enumerate
+figure
+flushleft
+itemize
+list
+math
+quotation
+quote
+sloppypar
+verbatim
+\end{verbatim}
+
+
+\section{Document Classes \label{classes}}
+
+  Two \LaTeX{} document classes are defined specifically for use with
+  the Python documentation.  The \code{manual} class is for large
+  documents which are sectioned into chapters, and the \code{howto}
+  class is for smaller documents.
+
+  The \code{manual} documents are larger and are used for most of the
+  standard documents.  This document class is based on the standard
+  \LaTeX{} \code{report} class and is formatted very much like a long
+  technical report.  The \citetitle[../ref/ref.html]{Python Reference
+  Manual} is a good example of a \code{manual} document, and the
+  \citetitle[../lib/lib.html]{Python Library Reference} is a large
+  example.
+
+  The \code{howto} documents are shorter, and don't have the large
+  structure of the \code{manual} documents.  This class is based on
+  the standard \LaTeX{} \code{article} class and is formatted somewhat
+  like the Linux Documentation Project's ``HOWTO'' series as done
+  originally using the LinuxDoc software.  The original intent for the
+  document class was that it serve a similar role as the LDP's HOWTO
+  series, but the applicability of the class turns out to be somewhat
+  broader.  This class is used for ``how-to'' documents (this
+  document is an example) and for shorter reference manuals for small,
+  fairly cohesive module libraries.  Examples of the later use include
+\citetitle[http://starship.python.net/crew/fdrake/manuals/krb5py/krb5py.html]{Using
+  Kerberos from Python}, which contains reference material for an
+  extension package.  These documents are roughly equivalent to a
+  single chapter from a larger work.
+
+
+\section{Special Markup Constructs \label{special-constructs}}
+
+  The Python document classes define a lot of new environments and
+  macros.  This section contains the reference material for these
+  facilities.  Documentation for ``standard'' \LaTeX{} constructs is
+  not included here, though they are used in the Python documentation.
+
+  \subsection{Markup for the Preamble \label{preamble-info}}
+
+    \begin{macrodesc}{release}{\p{ver}}
+      Set the version number for the software described in the
+      document.
+    \end{macrodesc}
+
+    \begin{macrodesc}{setshortversion}{\p{sver}}
+      Specify the ``short'' version number of the documented software
+      to be \var{sver}.
+    \end{macrodesc}
+
+  \subsection{Meta-information Markup \label{meta-info}}
+
+    \begin{macrodesc}{sectionauthor}{\p{author}\p{email}}
+      Identifies the author of the current section.  \var{author}
+      should be the author's name such that it can be used for
+      presentation (though it isn't), and \var{email} should be the
+      author's email address.  The domain name portion of
+      the address should be lower case.
+
+      No presentation is generated from this markup, but it is used to
+      help keep track of contributions.
+    \end{macrodesc}
+
+  \subsection{Information Units \label{info-units}}
+
+    XXX Explain terminology, or come up with something more ``lay.''
+
+    There are a number of environments used to describe specific
+    features provided by modules.  Each environment requires
+    parameters needed to provide basic information about what is being
+    described, and the environment content should be the description.
+    Most of these environments make entries in the general index (if
+    one is being produced for the document); if no index entry is
+    desired, non-indexing variants are available for many of these
+    environments.  The environments have names of the form
+    \code{\var{feature}desc}, and the non-indexing variants are named
+    \code{\var{feature}descni}.  The available variants are explicitly
+    included in the list below.
+
+    For each of these environments, the first parameter, \var{name},
+    provides the name by which the feature is accessed.
+
+    Environments which describe features of objects within a module,
+    such as object methods or data attributes, allow an optional
+    \var{type name} parameter.  When the feature is an attribute of
+    class instances, \var{type name} only needs to be given if the
+    class was not the most recently described class in the module; the
+    \var{name} value from the most recent \env{classdesc} is implied.
+    For features of built-in or extension types, the \var{type name}
+    value should always be provided.  Another special case includes
+    methods and members of general ``protocols,'' such as the
+    formatter and writer protocols described for the
+    \module{formatter} module: these may be documented without any
+    specific implementation classes, and will always require the
+    \var{type name} parameter to be provided.
+
+    \begin{envdesc}{cfuncdesc}{\p{type}\p{name}\p{args}}
+      Environment used to described a C function.  The \var{type}
+      should be specified as a \keyword{typedef} name, \code{struct
+      \var{tag}}, or the name of a primitive type.  If it is a pointer
+      type, the trailing asterisk should not be preceded by a space.
+      \var{name} should be the name of the function (or function-like
+      pre-processor macro), and \var{args} should give the types and
+      names of the parameters.  The names need to be given so they may
+      be used in the description.
+    \end{envdesc}
+
+    \begin{envdesc}{cmemberdesc}{\p{container}\p{type}\p{name}}
+      Description for a structure member.  \var{container} should be
+      the \keyword{typedef} name, if there is one, otherwise if should
+      be \samp{struct \var{tag}}.  The type of the member should given
+      as \var{type}, and the name should be given as \var{name}.  The
+      text of the description should include the range of values
+      allowed, how the value should be interpreted, and whether the
+      value can be changed.  References to structure members in text
+      should use the \macro{member} macro.
+    \end{envdesc}
+
+    \begin{envdesc}{csimplemacrodesc}{\p{name}}
+      Documentation for a ``simple'' macro.  Simple macros are macros
+      which are used for code expansion, but which do not take
+      arguments so cannot be described as functions.  This is not to
+      be used for simple constant definitions.  Examples of its use
+      in the Python documentation include
+      \csimplemacro{PyObject_HEAD} and
+      \csimplemacro{Py_BEGIN_ALLOW_THREADS}.
+    \end{envdesc}
+
+    \begin{envdesc}{ctypedesc}{\op{tag}\p{name}}
+      Environment used to described a C type.  The \var{name}
+      parameter should be the \keyword{typedef} name.  If the type is
+      defined as a \keyword{struct} without a \keyword{typedef},
+      \var{name} should have the form \code{struct \var{tag}}.
+      \var{name} will be added to the index unless \var{tag} is
+      provided, in which case \var{tag} will be used instead.
+      \var{tag} should not be used for a \keyword{typedef} name.
+    \end{envdesc}
+
+    \begin{envdesc}{cvardesc}{\p{type}\p{name}}
+      Description of a global C variable.  \var{type} should be the
+      \keyword{typedef} name, \code{struct \var{tag}}, or the name of
+      a primitive type.  If variable has a pointer type, the trailing
+      asterisk should \emph{not} be preceded by a space.
+    \end{envdesc}
+
+    \begin{envdesc}{datadesc}{\p{name}}
+      This environment is used to document global data in a module,
+      including both variables and values used as ``defined
+      constants.''  Class and object attributes are not documented
+      using this environment.
+    \end{envdesc}
+    \begin{envdesc}{datadescni}{\p{name}}
+      Like \env{datadesc}, but without creating any index entries.
+    \end{envdesc}
+
+    \begin{envdesc}{excclassdesc}{\p{name}\p{constructor parameters}}
+      Describe an exception defined by a class.  \var{constructor
+      parameters} should not include the \var{self} parameter or
+      the parentheses used in the call syntax.  To describe an
+      exception class without describing the parameters to its
+      constructor, use the \env{excdesc} environment.
+    \end{envdesc}
+
+    \begin{envdesc}{excdesc}{\p{name}}
+      Describe an exception.  In the case of class exceptions, the
+      constructor parameters are not described; use \env{excclassdesc}
+      to describe an exception class and its constructor.
+    \end{envdesc}
+
+    \begin{envdesc}{funcdesc}{\p{name}\p{parameters}}
+      Describe a module-level function.  \var{parameters} should
+      not include the parentheses used in the call syntax.  Object
+      methods are not documented using this environment.  Bound object
+      methods placed in the module namespace as part of the public
+      interface of the module are documented using this, as they are
+      equivalent to normal functions for most purposes.
+
+      The description should include information about the parameters
+      required and how they are used (especially whether mutable
+      objects passed as parameters are modified), side effects, and
+      possible exceptions.  A small example may be provided.
+    \end{envdesc}
+    \begin{envdesc}{funcdescni}{\p{name}\p{parameters}}
+      Like \env{funcdesc}, but without creating any index entries.
+    \end{envdesc}
+
+    \begin{envdesc}{classdesc}{\p{name}\p{constructor parameters}}
+      Describe a class and its constructor.  \var{constructor
+      parameters} should not include the \var{self} parameter or
+      the parentheses used in the call syntax.
+    \end{envdesc}
+
+    \begin{envdesc}{classdesc*}{\p{name}}
+      Describe a class without describing the constructor.  This can
+      be used to describe classes that are merely containers for
+      attributes or which should never be instantiated or subclassed
+      by user code.
+    \end{envdesc}
+
+    \begin{envdesc}{memberdesc}{\op{type name}\p{name}}
+      Describe an object data attribute.  The description should
+      include information about the type of the data to be expected
+      and whether it may be changed directly.
+    \end{envdesc}
+    \begin{envdesc}{memberdescni}{\op{type name}\p{name}}
+      Like \env{memberdesc}, but without creating any index entries.
+    \end{envdesc}
+
+    \begin{envdesc}{methoddesc}{\op{type name}\p{name}\p{parameters}}
+      Describe an object method.  \var{parameters} should not include
+      the \var{self} parameter or the parentheses used in the call
+      syntax.  The description should include similar information to
+      that described for \env{funcdesc}.
+    \end{envdesc}
+    \begin{envdesc}{methoddescni}{\op{type name}\p{name}\p{parameters}}
+      Like \env{methoddesc}, but without creating any index entries.
+    \end{envdesc}
+
+
+  \subsection{Showing Code Examples \label{showing-examples}}
+
+    Examples of Python source code or interactive sessions are
+    represented as \env{verbatim} environments.  This environment
+    is a standard part of \LaTeX{}.  It is important to only use
+    spaces for indentation in code examples since \TeX{} drops tabs
+    instead of converting them to spaces.
+
+    Representing an interactive session requires including the prompts
+    and output along with the Python code.  No special markup is
+    required for interactive sessions.  After the last line of input
+    or output presented, there should not be an ``unused'' primary
+    prompt; this is an example of what \emph{not} to do:
+
+\begin{verbatim}
+>>> 1 + 1
+2
+>>>
+\end{verbatim}
+
+    Within the \env{verbatim} environment, characters special to
+    \LaTeX{} do not need to be specially marked in any way.  The entire
+    example will be presented in a monospaced font; no attempt at
+    ``pretty-printing'' is made, as the environment must work for
+    non-Python code and non-code displays.  There should be no blank
+    lines at the top or bottom of any \env{verbatim} display.
+
+    Longer displays of verbatim text may be included by storing the
+    example text in an external file containing only plain text.  The
+    file may be included using the standard \macro{verbatiminput}
+    macro; this macro takes a single argument naming the file
+    containing the text.  For example, to include the Python source
+    file \file{example.py}, use:
+
+\begin{verbatim}
+\verbatiminput{example.py}
+\end{verbatim}
+
+    Use of \macro{verbatiminput} allows easier use of special editing
+    modes for the included file.  The file should be placed in the
+    same directory as the \LaTeX{} files for the document.
+
+    The Python Documentation Special Interest Group has discussed a
+    number of approaches to creating pretty-printed code displays and
+    interactive sessions; see the Doc-SIG area on the Python Web site
+    for more information on this topic.
+
+
+  \subsection{Inline Markup \label{inline-markup}}
+
+    The macros described in this section are used to mark just about
+    anything interesting in the document text.  They may be used in
+    headings (though anything involving hyperlinks should be avoided
+    there) as well as in the body text.
+
+    \begin{macrodesc}{bfcode}{\p{text}}
+      Like \macro{code}, but also makes the font bold-face.
+    \end{macrodesc}
+
+    \begin{macrodesc}{cdata}{\p{name}}
+      The name of a C-language variable.
+    \end{macrodesc}
+
+    \begin{macrodesc}{cfunction}{\p{name}}
+      The name of a C-language function.  \var{name} should include the
+      function name and the trailing parentheses.
+    \end{macrodesc}
+
+    \begin{macrodesc}{character}{\p{char}}
+      A character when discussing the character rather than a one-byte
+      string value.  The character will be typeset as with \macro{samp}.
+    \end{macrodesc}
+
+    \begin{macrodesc}{citetitle}{\op{url}\p{title}}
+      A title for a referenced publication.  If \var{url} is specified,
+      the title will be made into a hyperlink when formatted as HTML.
+    \end{macrodesc}
+
+    \begin{macrodesc}{class}{\p{name}}
+      A class name; a dotted name may be used.
+    \end{macrodesc}
+
+    \begin{macrodesc}{code}{\p{text}}
+      A short code fragment or literal constant value.  Typically, it
+      should not include any spaces since no quotation marks are
+      added.
+    \end{macrodesc}
+
+    \begin{macrodesc}{constant}{\p{name}}
+      The name of a ``defined'' constant.  This may be a C-language
+      \code{\#define} or a Python variable that is not intended to be
+      changed.
+    \end{macrodesc}
+
+    \begin{macrodesc}{csimplemacro}{\p{name}}
+      The name of a ``simple'' macro.  Simple macros are macros
+      which are used for code expansion, but which do not take
+      arguments so cannot be described as functions.  This is not to
+      be used for simple constant definitions.  Examples of its use
+      in the Python documentation include
+      \csimplemacro{PyObject_HEAD} and
+      \csimplemacro{Py_BEGIN_ALLOW_THREADS}.
+    \end{macrodesc}
+
+    \begin{macrodesc}{ctype}{\p{name}}
+      The name of a C \keyword{typedef} or structure.  For structures
+      defined without a \keyword{typedef}, use \code{\e ctype\{struct
+      struct_tag\}} to make it clear that the \keyword{struct} is
+      required.
+    \end{macrodesc}
+
+    \begin{macrodesc}{deprecated}{\p{version}\p{what to do}}
+      Declare whatever is being described as being deprecated starting
+      with release \var{version}.  The text given as \var{what to do}
+      should recommend something to use instead.  It should be
+      complete sentences.  The entire deprecation notice will be
+      presented as a separate paragraph; it should either precede or
+      succeed the description of the deprecated feature.
+    \end{macrodesc}
+
+    \begin{macrodesc}{dfn}{\p{term}}
+      Mark the defining instance of \var{term} in the text.  (No index
+      entries are generated.)
+    \end{macrodesc}
+
+    \begin{macrodesc}{e}{}
+      Produces a backslash.  This is convenient in \macro{code},
+      \macro{file}, and similar macros, and the \env{alltt}
+      environment, and is only defined there.  To
+      create a backslash in ordinary text (such as the contents of the
+      \macro{citetitle} macro), use the standard \macro{textbackslash}
+      macro.
+    \end{macrodesc}
+
+    \begin{macrodesc}{email}{\p{address}}
+      An email address.  Note that this is \emph{not} hyperlinked in
+      any of the possible output formats.  The domain name portion of
+      the address should be lower case.
+    \end{macrodesc}
+
+    \begin{macrodesc}{emph}{\p{text}}
+      Emphasized text; this will be presented in an italic font.
+    \end{macrodesc}
+
+    \begin{macrodesc}{envvar}{\p{name}}
+      An environment variable.  Index entries are generated.
+    \end{macrodesc}
+
+    \begin{macrodesc}{exception}{\p{name}}
+      The name of an exception.  A dotted name may be used.
+    \end{macrodesc}
+
+    \begin{macrodesc}{file}{\p{file or dir}}
+      The name of a file or directory.  In the PDF and PostScript
+      outputs, single quotes and a font change are used to indicate
+      the file name, but no quotes are used in the HTML output.
+      \warning{The \macro{file} macro cannot be used in the
+      content of a section title due to processing limitations.}
+    \end{macrodesc}
+
+    \begin{macrodesc}{filenq}{\p{file or dir}}
+      Like \macro{file}, but single quotes are never used.  This can
+      be used in conjunction with tables if a column will only contain
+      file or directory names.
+      \warning{The \macro{filenq} macro cannot be used in the
+      content of a section title due to processing limitations.}
+    \end{macrodesc}
+
+    \begin{macrodesc}{function}{\p{name}}
+      The name of a Python function; dotted names may be used.
+    \end{macrodesc}
+
+    \begin{macrodesc}{infinity}{}
+      The symbol for mathematical infinity: \infinity.  Some Web
+      browsers are not able to render the HTML representation of this
+      symbol properly, but support is growing.
+    \end{macrodesc}
+
+    \begin{macrodesc}{kbd}{\p{key sequence}}
+      Mark a sequence of keystrokes.  What form \var{key sequence}
+      takes may depend on platform- or application-specific
+      conventions.  When there are no relevant conventions, the names
+      of modifier keys should be spelled out, to improve accessibility
+      for new users and non-native speakers.  For example, an
+      \program{xemacs} key sequence may be marked like
+      \code{\e kbd\{C-x C-f\}}, but without reference to a specific
+      application or platform, the same sequence should be marked as
+      \code{\e kbd\{Control-x Control-f\}}.
+    \end{macrodesc}
+
+    \begin{macrodesc}{keyword}{\p{name}}
+      The name of a keyword in a programming language.
+    \end{macrodesc}
+
+    \begin{macrodesc}{mailheader}{\p{name}}
+      The name of an \rfc{822}-style mail header.  This markup does
+      not imply that the header is being used in an email message, but
+      can be used to refer to any header of the same ``style.''  This
+      is also used for headers defined by the various MIME
+      specifications.  The header name should be entered in the same
+      way it would normally be found in practice, with the
+      camel-casing conventions being preferred where there is more
+      than one common usage.  The colon which follows the name of the
+      header should not be included.
+      For example: \code{\e mailheader\{Content-Type\}}.
+    \end{macrodesc}
+
+    \begin{macrodesc}{makevar}{\p{name}}
+      The name of a \program{make} variable.
+    \end{macrodesc}
+
+    \begin{macrodesc}{manpage}{\p{name}\p{section}}
+      A reference to a \UNIX{} manual page.
+    \end{macrodesc}
+
+    \begin{macrodesc}{member}{\p{name}}
+      The name of a data attribute of an object.
+    \end{macrodesc}
+
+    \begin{macrodesc}{method}{\p{name}}
+      The name of a method of an object.  \var{name} should include the
+      method name and the trailing parentheses.  A dotted name may be
+      used.
+    \end{macrodesc}
+
+    \begin{macrodesc}{mimetype}{\p{name}}
+      The name of a MIME type, or a component of a MIME type (the
+      major or minor portion, taken alone).
+    \end{macrodesc}
+
+    \begin{macrodesc}{module}{\p{name}}
+       The name of a module; a dotted name may be used.  This should
+       also be used for package names.
+    \end{macrodesc}
+
+    \begin{macrodesc}{newsgroup}{\p{name}}
+      The name of a Usenet newsgroup.
+    \end{macrodesc}
+
+    \begin{macrodesc}{note}{\p{text}}
+      An especially important bit of information about an API that a
+      user should be aware of when using whatever bit of API the
+      note pertains to.  This should be the last thing in the
+      paragraph as the end of the note is not visually marked in
+      any way.  The content of \var{text} should be written in
+      complete sentences and include all appropriate punctuation.
+    \end{macrodesc}
+
+    \begin{macrodesc}{pep}{\p{number}}
+      A reference to a Python Enhancement Proposal.  This generates
+      appropriate index entries.  The text \samp{PEP \var{number}} is
+      generated; in the HTML output, this text is a hyperlink to an
+      online copy of the specified PEP.
+    \end{macrodesc}
+
+    \begin{macrodesc}{plusminus}{}
+      The symbol for indicating a value that may take a positive or
+      negative value of a specified magnitude, typically represented
+      by a plus sign placed over a minus sign.  For example:
+      \code{\e plusminus 3\%{}}.
+    \end{macrodesc}
+
+    \begin{macrodesc}{program}{\p{name}}
+      The name of an executable program.  This may differ from the
+      file name for the executable for some platforms.  In particular,
+      the \file{.exe} (or other) extension should be omitted for
+      Windows programs.
+    \end{macrodesc}
+
+    \begin{macrodesc}{programopt}{\p{option}}
+      A command-line option to an executable program.  Use this only
+      for ``short'' options, and include the leading hyphen.
+    \end{macrodesc}
+
+    \begin{macrodesc}{longprogramopt}{\p{option}}
+      A long command-line option to an executable program.  This
+      should only be used for long option names which will be prefixed
+      by two hyphens; the hyphens should not be provided as part of
+      \var{option}.
+    \end{macrodesc}
+
+    \begin{macrodesc}{refmodule}{\op{key}\p{name}}
+      Like \macro{module}, but create a hyperlink to the documentation
+      for the named module.  Note that the corresponding
+      \macro{declaremodule} must be in the same document.  If the
+      \macro{declaremodule} defines a module key different from the
+      module name, it must also be provided as \var{key} to the
+      \macro{refmodule} macro.
+    \end{macrodesc}
+
+    \begin{macrodesc}{regexp}{\p{string}}
+      Mark a regular expression.
+    \end{macrodesc}
+
+    \begin{macrodesc}{rfc}{\p{number}}
+      A reference to an Internet Request for Comments.  This generates
+      appropriate index entries.  The text \samp{RFC \var{number}} is
+      generated; in the HTML output, this text is a hyperlink to an
+      online copy of the specified RFC.
+    \end{macrodesc}
+
+    \begin{macrodesc}{samp}{\p{text}}
+      A short code sample, but possibly longer than would be given
+      using \macro{code}.  Since quotation marks are added, spaces are
+      acceptable.
+    \end{macrodesc}
+
+    \begin{macrodesc}{shortversion}{}
+      The ``short'' version number of the documented software, as
+      specified using the \macro{setshortversion} macro in the
+      preamble.  For Python, the short version number for a release is
+      the first three characters of the \code{sys.version} value.  For
+      example, versions 2.0b1 and 2.0.1 both have a short version of
+      2.0.  This may not apply for all packages; if
+      \macro{setshortversion} is not used, this produces an empty
+      expansion.  See also the \macro{version} macro.
+    \end{macrodesc}
+
+    \begin{macrodesc}{strong}{\p{text}}
+      Strongly emphasized text; this will be presented using a bold
+      font.
+    \end{macrodesc}
+
+    \begin{macrodesc}{ulink}{\p{text}\p{url}}
+      A hypertext link with a target specified by a URL, but for which
+      the link text should not be the title of the resource.  For
+      resources being referenced by name, use the \macro{citetitle}
+      macro.  Not all formatted versions support arbitrary hypertext
+      links.  Note that many characters are special to \LaTeX{} and
+      this macro does not always do the right thing.  In particular,
+      the tilde character (\character{\~}) is mis-handled; encoding it
+      as a hex-sequence does work, use \samp{\%7e} in place of the
+      tilde character.
+    \end{macrodesc}
+
+    \begin{macrodesc}{url}{\p{url}}
+      A URL (or URN).  The URL will be presented as text.  In the HTML
+      and PDF formatted versions, the URL will also be a hyperlink.
+      This can be used when referring to external resources without
+      specific titles; references to resources which have titles
+      should be marked using the \macro{citetitle} macro.  See the
+      comments about special characters in the description of the
+      \macro{ulink} macro for special considerations.
+    \end{macrodesc}
+
+    \begin{macrodesc}{var}{\p{name}}
+      The name of a variable or formal parameter in running text.
+    \end{macrodesc}
+
+    \begin{macrodesc}{version}{}
+      The version number of the described software, as specified using
+      \macro{release} in the preamble.  See also the
+      \macro{shortversion} macro.
+    \end{macrodesc}
+
+    \begin{macrodesc}{warning}{\p{text}}
+      An important bit of information about an API that a user should
+      be very aware of when using whatever bit of API the warning
+      pertains to.  This should be the last thing in the paragraph as
+      the end of the warning is not visually marked in any way.  The
+      content of \var{text} should be written in complete sentences
+      and include all appropriate punctuation.  This differs from
+      \macro{note} in that it is recommended over \macro{note} for
+      information regarding security.
+    \end{macrodesc}
+
+    The following two macros are used to describe information that's
+    associated with changes from one release to another.  For features
+    which are described by a single paragraph, these are typically
+    added as separate source lines at the end of the paragraph.  When
+    adding these to features described by multiple paragraphs, they
+    are usually collected in a single separate paragraph after the
+    description.  When both \macro{versionadded} and
+    \macro{versionchanged} are used, \macro{versionadded} should come
+    first; the versions should be listed in chronological order.  Both
+    of these should come before availability statements.  The location
+    should be selected so the explanation makes sense and may vary as
+    needed.
+
+    \begin{macrodesc}{versionadded}{\op{explanation}\p{version}}
+      The version of Python which added the described feature to the
+      library or C API.  \var{explanation} should be a \emph{brief}
+      explanation of the change consisting of a capitalized sentence
+      fragment; a period will be appended by the formatting process.
+      When this applies to an entire module, it should be placed at
+      the top of the module section before any prose.
+    \end{macrodesc}
+
+    \begin{macrodesc}{versionchanged}{\op{explanation}\p{version}}
+      The version of Python in which the named feature was changed in
+      some way (new parameters, changed side effects, etc.).
+      \var{explanation} should be a \emph{brief} explanation of the
+      change consisting of a capitalized sentence fragment; a
+      period will be appended by the formatting process.  This should
+      not generally be applied to modules.
+    \end{macrodesc}
+
+
+  \subsection{Miscellaneous Text Markup \label{misc-text-markup}}
+
+  In addition to the inline markup, some additional ``block'' markup
+  is defined to make it easier to bring attention to various bits of
+  text.  The markup described here serves this purpose, and is
+  intended to be used when marking one or more paragraphs or other
+  block constructs (such as \env{verbatim} environments).
+
+  \begin{envdesc}{notice}{\op{type}}
+    Label some paragraphs as being worthy of additional attention from
+    the reader.  What sort of attention is warranted can be indicated
+    by specifying the \var{type} of the notice.  The only values
+    defined for \var{type} are \code{note} and \code{warning}; these
+    are equivalent in intent to the inline markup of the same name.
+    If \var{type} is omitted, \code{note} is used.  Additional values
+    may be defined in the future.
+  \end{envdesc}
+
+
+  \subsection{Module-specific Markup \label{module-markup}}
+
+  The markup described in this section is used to provide information
+  about a module being documented.  Each module should be documented
+  in its own \macro{section}.  A typical use of this markup
+  appears at the top of that section and might look like this:
+
+\begin{verbatim}
+\section{\module{spam} ---
+         Access to the SPAM facility}
+
+\declaremodule{extension}{spam}
+  \platform{Unix}
+\modulesynopsis{Access to the SPAM facility of \UNIX.}
+\moduleauthor{Jane Doe}{jane.doe at frobnitz.org}
+\end{verbatim}
+
+  Python packages\index{packages} --- collections of modules that can
+  be described as a unit --- are documented using the same markup as
+  modules.  The name for a module in a package should be typed in
+  ``fully qualified'' form (it should include the package name).
+  For example, a module ``foo'' in package ``bar'' should be marked as
+  \code{\e module\{bar.foo\}}, and the beginning of the reference
+  section would appear as:
+
+\begin{verbatim}
+\section{\module{bar.foo} ---
+         Module from the \module{bar} package}
+
+\declaremodule{extension}{bar.foo}
+\modulesynopsis{Nifty module from the \module{bar} package.}
+\moduleauthor{Jane Doe}{jane.doe at frobnitz.org}
+\end{verbatim}
+
+  Note that the name of a package is also marked using
+  \macro{module}.
+
+  \begin{macrodesc}{declaremodule}{\op{key}\p{type}\p{name}}
+    Requires two parameters: module type (\samp{standard},
+    \samp{builtin}, \samp{extension}, or \samp{}), and the module
+    name.  An optional parameter should be given as the basis for the
+    module's ``key'' used for linking to or referencing the section.
+    The ``key'' should only be given if the module's name contains any
+    underscores, and should be the name with the underscores stripped.
+    Note that the \var{type} parameter must be one of the values
+    listed above or an error will be printed.  For modules which are
+    contained in packages, the fully-qualified name should be given as
+    \var{name} parameter.  This should be the first thing after the
+    \macro{section} used to introduce the module.
+  \end{macrodesc}
+
+  \begin{macrodesc}{platform}{\p{specifier}}
+    Specifies the portability of the module.  \var{specifier} is a
+    comma-separated list of keys that specify what platforms the
+    module is available on.  The keys are short identifiers;
+    examples that are in use include \samp{IRIX}, \samp{Mac},
+    \samp{Windows}, and \samp{Unix}.  It is important to use a key
+    which has already been used when applicable.  This is used to
+    provide annotations in the Module Index and the HTML and GNU info
+    output.
+  \end{macrodesc}
+
+  \begin{macrodesc}{modulesynopsis}{\p{text}}
+    The \var{text} is a short, ``one line'' description of the
+    module that can be used as part of the chapter introduction.
+    This is must be placed after \macro{declaremodule}.
+    The synopsis is used in building the contents of the table
+    inserted as the \macro{localmoduletable}.  No text is
+    produced at the point of the markup.
+  \end{macrodesc}
+
+  \begin{macrodesc}{moduleauthor}{\p{name}\p{email}}
+    This macro is used to encode information about who authored a
+    module.  This is currently not used to generate output, but can be
+    used to help determine the origin of the module.
+  \end{macrodesc}
+
+
+  \subsection{Library-level Markup \label{library-markup}}
+
+    This markup is used when describing a selection of modules.  For
+    example, the \citetitle[../mac/mac.html]{Macintosh Library
+    Modules} document uses this to help provide an overview of the
+    modules in the collection, and many chapters in the
+    \citetitle[../lib/lib.html]{Python Library Reference} use it for
+    the same purpose.
+
+  \begin{macrodesc}{localmoduletable}{}
+    If a \file{.syn} file exists for the current
+    chapter (or for the entire document in \code{howto} documents), a
+    \env{synopsistable} is created with the contents loaded from the
+    \file{.syn} file.
+  \end{macrodesc}
+
+
+  \subsection{Table Markup \label{table-markup}}
+
+    There are three general-purpose table environments defined which
+    should be used whenever possible.  These environments are defined
+    to provide tables of specific widths and some convenience for
+    formatting.  These environments are not meant to be general
+    replacements for the standard \LaTeX{} table environments, but can
+    be used for an advantage when the documents are processed using
+    the tools for Python documentation processing.  In particular, the
+    generated HTML looks good!  There is also an advantage for the
+    eventual conversion of the documentation to XML (see section
+    \ref{futures}, ``Future Directions'').
+
+    Each environment is named \env{table\var{cols}}, where \var{cols}
+    is the number of columns in the table specified in lower-case
+    Roman numerals.  Within each of these environments, an additional
+    macro, \macro{line\var{cols}}, is defined, where \var{cols}
+    matches the \var{cols} value of the corresponding table
+    environment.  These are supported for \var{cols} values of
+    \code{ii}, \code{iii}, and \code{iv}.  These environments are all
+    built on top of the \env{tabular} environment.  Variants based on
+    the \env{longtable} environment are also provided.
+
+    Note that all tables in the standard Python documentation use
+    vertical lines between columns, and this must be specified in the
+    markup for each table.  A general border around the outside of the
+    table is not used, but would be the responsibility of the
+    processor; the document markup should not include an exterior
+    border.
+
+    The \env{longtable}-based variants of the table environments are
+    formatted with extra space before and after, so should only be
+    used on tables which are long enough that splitting over multiple
+    pages is reasonable; tables with fewer than twenty rows should
+    never by marked using the long flavors of the table environments.
+    The header row is repeated across the top of each part of the
+    table.
+
+    \begin{envdesc}{tableii}{\p{colspec}\p{col1font}\p{heading1}\p{heading2}}
+      Create a two-column table using the \LaTeX{} column specifier
+      \var{colspec}.  The column specifier should indicate vertical
+      bars between columns as appropriate for the specific table, but
+      should not specify vertical bars on the outside of the table
+      (that is considered a stylesheet issue).  The \var{col1font}
+      parameter is used as a stylistic treatment of the first column
+      of the table: the first column is presented as
+      \code{\e\var{col1font}\{column1\}}.  To avoid treating the first
+      column specially, \var{col1font} may be \samp{textrm}.  The
+      column headings are taken from the values \var{heading1} and
+      \var{heading2}.
+    \end{envdesc}
+
+    \begin{envdesc}{longtableii}{\unspecified}
+      Like \env{tableii}, but produces a table which may be broken
+      across page boundaries.  The parameters are the same as for
+      \env{tableii}.
+    \end{envdesc}
+
+    \begin{macrodesc}{lineii}{\p{column1}\p{column2}}
+      Create a single table row within a \env{tableii} or
+      \env{longtableii} environment.
+      The text for the first column will be generated by applying the
+      macro named by the \var{col1font} value when the \env{tableii}
+      was opened.
+    \end{macrodesc}
+
+    \begin{envdesc}{tableiii}{\p{colspec}\p{col1font}\p{heading1}\p{heading2}\p{heading3}}
+      Like the \env{tableii} environment, but with a third column.
+      The heading for the third column is given by \var{heading3}.
+    \end{envdesc}
+
+    \begin{envdesc}{longtableiii}{\unspecified}
+      Like \env{tableiii}, but produces a table which may be broken
+      across page boundaries.  The parameters are the same as for
+      \env{tableiii}.
+    \end{envdesc}
+
+    \begin{macrodesc}{lineiii}{\p{column1}\p{column2}\p{column3}}
+      Like the \macro{lineii} macro, but with a third column.  The
+      text for the third column is given by \var{column3}.
+    \end{macrodesc}
+
+    \begin{envdesc}{tableiv}{\p{colspec}\p{col1font}\p{heading1}\p{heading2}\p{heading3}\p{heading4}}
+      Like the \env{tableiii} environment, but with a fourth column.
+      The heading for the fourth column is given by \var{heading4}.
+    \end{envdesc}
+
+    \begin{envdesc}{longtableiv}{\unspecified}
+      Like \env{tableiv}, but produces a table which may be broken
+      across page boundaries.  The parameters are the same as for
+      \env{tableiv}.
+    \end{envdesc}
+
+    \begin{macrodesc}{lineiv}{\p{column1}\p{column2}\p{column3}\p{column4}}
+      Like the \macro{lineiii} macro, but with a fourth column.  The
+      text for the fourth column is given by \var{column4}.
+    \end{macrodesc}
+
+    \begin{envdesc}{tablev}{\p{colspec}\p{col1font}\p{heading1}\p{heading2}\p{heading3}\p{heading4}\p{heading5}}
+      Like the \env{tableiv} environment, but with a fifth column.
+      The heading for the fifth column is given by \var{heading5}.
+    \end{envdesc}
+
+    \begin{envdesc}{longtablev}{\unspecified}
+      Like \env{tablev}, but produces a table which may be broken
+      across page boundaries.  The parameters are the same as for
+      \env{tablev}.
+    \end{envdesc}
+
+    \begin{macrodesc}{linev}{\p{column1}\p{column2}\p{column3}\p{column4}\p{column5}}
+      Like the \macro{lineiv} macro, but with a fifth column.  The
+      text for the fifth column is given by \var{column5}.
+    \end{macrodesc}
+
+
+    An additional table-like environment is \env{synopsistable}.  The
+    table generated by this environment contains two columns, and each
+    row is defined by an alternate definition of
+    \macro{modulesynopsis}.  This environment is not normally used by
+    authors, but is created by the \macro{localmoduletable} macro.
+
+    Here is a small example of a table given in the documentation for
+    the \module{warnings} module; markup inside the table cells is
+    minimal so the markup for the table itself is readily discernable.
+    Here is the markup for the table:
+
+\begin{verbatim}
+\begin{tableii}{l|l}{exception}{Class}{Description}
+  \lineii{Warning}
+         {This is the base class of all warning category classes.  It
+          is a subclass of \exception{Exception}.}
+  \lineii{UserWarning}
+         {The default category for \function{warn()}.}
+  \lineii{DeprecationWarning}
+         {Base category for warnings about deprecated features.}
+  \lineii{SyntaxWarning}
+         {Base category for warnings about dubious syntactic
+          features.}
+  \lineii{RuntimeWarning}
+         {Base category for warnings about dubious runtime features.}
+  \lineii{FutureWarning}
+         {Base category for warnings about constructs that will change
+         semantically in the future.}
+\end{tableii}
+\end{verbatim}
+
+    Here is the resulting table:
+
+\begin{tableii}{l|l}{exception}{Class}{Description}
+  \lineii{Warning}
+         {This is the base class of all warning category classes.  It
+          is a subclass of \exception{Exception}.}
+  \lineii{UserWarning}
+         {The default category for \function{warn()}.}
+  \lineii{DeprecationWarning}
+         {Base category for warnings about deprecated features.}
+  \lineii{SyntaxWarning}
+         {Base category for warnings about dubious syntactic
+          features.}
+  \lineii{RuntimeWarning}
+         {Base category for warnings about dubious runtime features.}
+\end{tableii}
+
+    Note that the class names are implicitly marked using the
+    \macro{exception} macro, since that is given as the \var{col1font}
+    value for the \env{tableii} environment.  To create a table using
+    different markup for the first column, use \code{textrm} for the
+    \var{col1font} value and mark each entry individually.
+
+    To add a horizontal line between vertical sections of a table, use
+    the standard \macro{hline} macro between the rows which should be
+    separated:
+
+\begin{verbatim}
+\begin{tableii}{l|l}{constant}{Language}{Audience}
+  \lineii{APL}{Masochists.}
+  \lineii{BASIC}{First-time programmers on PC hardware.}
+  \lineii{C}{\UNIX{} \&\ Linux kernel developers.}
+    \hline
+  \lineii{Python}{Everyone!}
+\end{tableii}
+\end{verbatim}
+
+    Note that not all presentation formats are capable of displaying a
+    horizontal rule in this position.  This is how the table looks in
+    the format you're reading now:
+
+\begin{tableii}{l|l}{constant}{Language}{Audience}
+  \lineii{APL}{Masochists.}
+  \lineii{C}{\UNIX{} \&\ Linux kernel developers.}
+  \lineii{JavaScript}{Web developers.}
+    \hline
+  \lineii{Python}{Everyone!}
+\end{tableii}
+
+
+  \subsection{Reference List Markup \label{references}}
+
+    Many sections include a list of references to module documentation
+    or external documents.  These lists are created using the
+    \env{seealso} or \env{seealso*} environments.  These environments
+    define some additional macros to support creating reference
+    entries in a reasonable manner.
+
+    The \env{seealso} environment is typically placed in a section
+    just before any sub-sections.  This is done to ensure that
+    reference links related to the section are not hidden in a
+    subsection in the hypertext renditions of the documentation.  For
+    the HTML output, it is shown as a ``side bar,'' boxed off from the
+    main flow of the text.  The \env{seealso*} environment is
+    different in that it should be used when a list of references is
+    being presented as part of the primary content; it is not
+    specially set off from the text.
+
+    \begin{envdesc}{seealso}{}
+      This environment creates a ``See also:'' heading and defines the
+      markup used to describe individual references.
+    \end{envdesc}
+
+    \begin{envdesc}{seealso*}{}
+      This environment is used to create a list of references which
+      form part of the main content.  It is not given a special
+      header and is not set off from the main flow of the text.  It
+      provides the same additional markup used to describe individual
+      references.
+    \end{envdesc}
+
+    For each of the following macros, \var{why} should be one or more
+    complete sentences, starting with a capital letter (unless it
+    starts with an identifier, which should not be modified), and
+    ending with the appropriate punctuation.
+
+    These macros are only defined within the content of the
+    \env{seealso} and \env{seealso*} environments.
+
+    \begin{macrodesc}{seelink}{\p{url}\p{linktext}\p{why}}
+      References to specific on-line resources should be given using
+      the \macro{seelink} macro if they don't have a meaningful title
+      but there is some short description of what's at the end of the
+      link.  Online documents which have identifiable titles should be
+      referenced using the \macro{seetitle} macro, using the optional
+      parameter to that macro to provide the URL.
+    \end{macrodesc}
+
+    \begin{macrodesc}{seemodule}{\op{key}\p{name}\p{why}}
+      Refer to another module.  \var{why} should be a brief
+      explanation of why the reference may be interesting.  The module
+      name is given in \var{name}, with the link key given in
+      \var{key} if necessary.  In the HTML and PDF conversions, the
+      module name will be a hyperlink to the referred-to module.
+      \note{The module must be documented in the same
+      document (the corresponding \macro{declaremodule} is required).}
+    \end{macrodesc}
+
+    \begin{macrodesc}{seepep}{\p{number}\p{title}\p{why}}
+      Refer to an Python Enhancement Proposal (PEP).  \var{number}
+      should be the official number assigned by the PEP Editor,
+      \var{title} should be the human-readable title of the PEP as
+      found in the official copy of the document, and \var{why} should
+      explain what's interesting about the PEP.  This should be used
+      to refer the reader to PEPs which specify interfaces or language
+      features relevant to the material in the annotated section of the
+      documentation.
+    \end{macrodesc}
+
+    \begin{macrodesc}{seerfc}{\p{number}\p{title}\p{why}}
+      Refer to an IETF Request for Comments (RFC).  Otherwise very
+      similar to \macro{seepep}.  This should be used
+      to refer the reader to PEPs which specify protocols or data
+      formats relevant to the material in the annotated section of the
+      documentation.
+    \end{macrodesc}
+
+    \begin{macrodesc}{seetext}{\p{text}}
+      Add arbitrary text \var{text} to the ``See also:'' list.  This
+      can be used to refer to off-line materials or on-line materials
+      using the \macro{url} macro.  This should consist of one or more
+      complete sentences.
+    \end{macrodesc}
+
+    \begin{macrodesc}{seetitle}{\op{url}\p{title}\p{why}}
+      Add a reference to an external document named \var{title}.  If
+      \var{url} is given, the title is made a hyperlink in the HTML
+      version of the documentation, and displayed below the title in
+      the typeset versions of the documentation.
+    \end{macrodesc}
+
+    \begin{macrodesc}{seeurl}{\p{url}\p{why}}
+      References to specific on-line resources should be given using
+      the \macro{seeurl} macro if they don't have a meaningful title.
+      Online documents which have identifiable titles should be
+      referenced using the \macro{seetitle} macro, using the optional
+      parameter to that macro to provide the URL.
+    \end{macrodesc}
+
+
+  \subsection{Index-generating Markup \label{indexing}}
+
+    Effective index generation for technical documents can be very
+    difficult, especially for someone familiar with the topic but not
+    the creation of indexes.  Much of the difficulty arises in the
+    area of terminology: including the terms an expert would use for a
+    concept is not sufficient.  Coming up with the terms that a novice
+    would look up is fairly difficult for an author who, typically, is
+    an expert in the area she is writing on.
+
+    The truly difficult aspects of index generation are not areas with
+    which the documentation tools can help.  However, ease
+    of producing the index once content decisions are made is within
+    the scope of the tools.  Markup is provided which the processing
+    software is able to use to generate a variety of kinds of index
+    entry with minimal effort.  Additionally, many of the environments
+    described in section \ref{info-units}, ``Information Units,'' will
+    generate appropriate entries into the general and module indexes.
+
+    The following macro can be used to control the generation of index
+    data, and should be used in the document preamble:
+
+    \begin{macrodesc}{makemodindex}{}
+      This should be used in the document preamble if a ``Module
+      Index'' is desired for a document containing reference material
+      on many modules.  This causes a data file
+      \code{lib\var{jobname}.idx} to be created from the
+      \macro{declaremodule} macros.  This file can be processed by the
+      \program{makeindex} program to generate a file which can be
+      \macro{input} into the document at the desired location of the
+      module index.
+    \end{macrodesc}
+
+    There are a number of macros that are useful for adding index
+    entries for particular concepts, many of which are specific to
+    programming languages or even Python.
+
+    \begin{macrodesc}{bifuncindex}{\p{name}}
+      Add an index entry referring to a built-in function named
+      \var{name}; parentheses should not be included after
+      \var{name}.
+    \end{macrodesc}
+
+    \begin{macrodesc}{exindex}{\p{exception}}
+      Add a reference to an exception named \var{exception}.  The
+      exception should be class-based.
+    \end{macrodesc}
+
+    \begin{macrodesc}{kwindex}{\p{keyword}}
+      Add a reference to a language keyword (not a keyword parameter
+      in a function or method call).
+    \end{macrodesc}
+
+    \begin{macrodesc}{obindex}{\p{object type}}
+      Add an index entry for a built-in object type.
+    \end{macrodesc}
+
+    \begin{macrodesc}{opindex}{\p{operator}}
+      Add a reference to an operator, such as \samp{+}.
+    \end{macrodesc}
+
+    \begin{macrodesc}{refmodindex}{\op{key}\p{module}}
+      Add an index entry for module \var{module}; if \var{module}
+      contains an underscore, the optional parameter \var{key} should
+      be provided as the same string with underscores removed.  An
+      index entry ``\var{module} (module)'' will be generated.  This
+      is intended for use with non-standard modules implemented in
+      Python.
+    \end{macrodesc}
+
+    \begin{macrodesc}{refexmodindex}{\op{key}\p{module}}
+      As for \macro{refmodindex}, but the index entry will be
+      ``\var{module} (extension module).''  This is intended for use
+      with non-standard modules not implemented in Python.
+    \end{macrodesc}
+
+    \begin{macrodesc}{refbimodindex}{\op{key}\p{module}}
+      As for \macro{refmodindex}, but the index entry will be
+      ``\var{module} (built-in module).''  This is intended for use
+      with standard modules not implemented in Python.
+    \end{macrodesc}
+
+    \begin{macrodesc}{refstmodindex}{\op{key}\p{module}}
+      As for \macro{refmodindex}, but the index entry will be
+      ``\var{module} (standard module).''  This is intended for use
+      with standard modules implemented in Python.
+    \end{macrodesc}
+
+    \begin{macrodesc}{stindex}{\p{statement}}
+      Add an index entry for a statement type, such as \keyword{print}
+      or \keyword{try}/\keyword{finally}.
+
+      XXX Need better examples of difference from \macro{kwindex}.
+    \end{macrodesc}
+
+
+    Additional macros are provided which are useful for conveniently
+    creating general index entries which should appear at many places
+    in the index by rotating a list of words.  These are simple macros
+    that simply use \macro{index} to build some number of index
+    entries.  Index entries build using these macros contain both
+    primary and secondary text.
+
+    \begin{macrodesc}{indexii}{\p{word1}\p{word2}}
+      Build two index entries.  This is exactly equivalent to using
+      \code{\e index\{\var{word1}!\var{word2}\}} and
+      \code{\e index\{\var{word2}!\var{word1}\}}.
+    \end{macrodesc}
+
+    \begin{macrodesc}{indexiii}{\p{word1}\p{word2}\p{word3}}
+      Build three index entries.  This is exactly equivalent to using
+      \code{\e index\{\var{word1}!\var{word2} \var{word3}\}},
+      \code{\e index\{\var{word2}!\var{word3}, \var{word1}\}}, and
+      \code{\e index\{\var{word3}!\var{word1} \var{word2}\}}.
+    \end{macrodesc}
+
+    \begin{macrodesc}{indexiv}{\p{word1}\p{word2}\p{word3}\p{word4}}
+      Build four index entries.  This is exactly equivalent to using
+      \code{\e index\{\var{word1}!\var{word2} \var{word3} \var{word4}\}},
+      \code{\e index\{\var{word2}!\var{word3} \var{word4}, \var{word1}\}},
+      \code{\e index\{\var{word3}!\var{word4}, \var{word1} \var{word2}\}},
+      and
+      \code{\e index\{\var{word4}!\var{word1} \var{word2} \var{word3}\}}.
+    \end{macrodesc}
+
+  \subsection{Grammar Production Displays \label{grammar-displays}}
+
+    Special markup is available for displaying the productions of a
+    formal grammar.  The markup is simple and does not attempt to
+    model all aspects of BNF (or any derived forms), but provides
+    enough to allow context-free grammars to be displayed in a way
+    that causes uses of a symbol to be rendered as hyperlinks to the
+    definition of the symbol.  There is one environment and a pair of
+    macros:
+
+    \begin{envdesc}{productionlist}{\op{language}}
+      This environment is used to enclose a group of productions.  The
+      two macros are only defined within this environment.  If a
+      document describes more than one language, the optional parameter
+      \var{language} should be used to distinguish productions between
+      languages.  The value of the parameter should be a short name
+      that can be used as part of a filename; colons or other
+      characters that can't be used in filename across platforms
+      should be included.
+    \end{envdesc}
+
+    \begin{macrodesc}{production}{\p{name}\p{definition}}
+      A production rule in the grammar.  The rule defines the symbol
+      \var{name} to be \var{definition}.  \var{name} should not
+      contain any markup, and the use of hyphens in a document which
+      supports more than one grammar is undefined.  \var{definition}
+      may contain \macro{token} macros and any additional content
+      needed to describe the grammatical model of \var{symbol}.  Only
+      one \macro{production} may be used to define a symbol ---
+      multiple definitions are not allowed.
+    \end{macrodesc}
+
+    \begin{macrodesc}{token}{\p{name}}
+      The name of a symbol defined by a \macro{production} macro, used
+      in the \var{definition} of a symbol.  Where possible, this will
+      be rendered as a hyperlink to the definition of the symbol
+      \var{name}.
+    \end{macrodesc}
+
+    Note that the entire grammar does not need to be defined in a
+    single \env{productionlist} environment; any number of
+    groupings may be used to describe the grammar.  Every use of the
+    \macro{token} must correspond to a \macro{production}.
+
+    The following is an example taken from the
+    \citetitle[../ref/identifiers.html]{Python Reference Manual}:
+
+\begin{verbatim}
+\begin{productionlist}
+  \production{identifier}
+             {(\token{letter}|"_") (\token{letter} | \token{digit} | "_")*}
+  \production{letter}
+             {\token{lowercase} | \token{uppercase}}
+  \production{lowercase}
+             {"a"..."z"}
+  \production{uppercase}
+             {"A"..."Z"}
+  \production{digit}
+             {"0"..."9"}
+\end{productionlist}
+\end{verbatim}
+
+
+\subsection{Graphical Interface Components \label{gui-markup}}
+
+  The components of graphical interfaces will be assigned markup, but
+  most of the specifics have not been determined.
+
+  \begin{macrodesc}{guilabel}{\p{label}}
+    Labels presented as part of an interactive user interface should
+    be marked using \macro{guilabel}.  This includes labels from
+    text-based interfaces such as those created using \code{curses} or
+    other text-based libraries.  Any label used in the interface
+    should be marked with this macro, including button labels, window
+    titles, field names, menu and menu selection names, and even
+    values in selection lists.
+  \end{macrodesc}
+
+  \begin{macrodesc}{menuselection}{\p{menupath}}
+    Menu selections should be marked using a combination of
+    \macro{menuselection} and \macro{sub}.  This macro is used to mark
+    a complete sequence of menu selections, including selecting
+    submenus and choosing a specific operation, or any subsequence of
+    such a sequence.  The names of individual selections should be
+    separated by occurrences of \macro{sub}.
+
+    For example, to mark the selection ``\menuselection{Start \sub
+    Programs}'', use this markup:
+
+\begin{verbatim}
+\menuselection{Start \sub Programs}
+\end{verbatim}
+
+    When including a selection that includes some trailing indicator,
+    such as the ellipsis some operating systems use to indicate that
+    the command opens a dialog, the indicator should be omitted from
+    the selection name.
+
+    Individual selection names within the \macro{menuselection} should
+    not be marked using \macro{guilabel} since that's implied by using
+    \macro{menuselection}.
+  \end{macrodesc}
+
+  \begin{macrodesc}{sub}{}
+    Separator for menu selections that include multiple levels.  This
+    macro is only defined within the context of the
+    \macro{menuselection} macro.
+  \end{macrodesc}
+
+
+\section{Processing Tools \label{tools}}
+
+  \subsection{External Tools \label{tools-external}}
+
+    Many tools are needed to be able to process the Python
+    documentation if all supported formats are required.  This
+    section lists the tools used and when each is required.  Consult
+    the \file{Doc/README} file to see if there are specific version
+    requirements for any of these.
+
+    \begin{description}
+      \item[\program{dvips}]
+        This program is a typical part of \TeX{} installations.  It is
+        used to generate PostScript from the ``device independent''
+        \file{.dvi} files.  It is needed for the conversion to
+        PostScript.
+
+      \item[\program{emacs}]
+        Emacs is the kitchen sink of programmers' editors, and a damn
+        fine kitchen sink it is.  It also comes with some of the
+        processing needed to support the proper menu structures for
+        Texinfo documents when an info conversion is desired.  This is
+        needed for the info conversion.  Using \program{xemacs}
+        instead of FSF \program{emacs} may lead to instability in the
+        conversion, but that's because nobody seems to maintain the
+        Emacs Texinfo code in a portable manner.
+
+      \item[\program{latex}]
+        \LaTeX{} is a large and extensible macro package by Leslie
+        Lamport, based on \TeX, a world-class typesetter by Donald
+        Knuth.  It is used for the conversion to PostScript, and is
+        needed for the HTML conversion as well (\LaTeX2HTML requires
+        one of the intermediate files it creates).
+
+      \item[\program{latex2html}]
+        Probably the longest Perl script anyone ever attempted to
+        maintain.  This converts \LaTeX{} documents to HTML documents,
+        and does a pretty reasonable job.  It is required for the
+        conversions to HTML and GNU info.
+
+      \item[\program{lynx}]
+        This is a text-mode Web browser which includes an
+        HTML-to-plain text conversion.  This is used to convert
+        \code{howto} documents to text.
+
+      \item[\program{make}]
+        Just about any version should work for the standard documents,
+        but GNU \program{make} is required for the experimental
+        processes in \file{Doc/tools/sgmlconv/}, at least while
+        they're experimental.  This is not required for running the
+        \program{mkhowto} script.
+
+      \item[\program{makeindex}]
+        This is a standard program for converting \LaTeX{} index data
+        to a formatted index; it should be included with all \LaTeX{}
+        installations.  It is needed for the PDF and PostScript
+        conversions.
+
+      \item[\program{makeinfo}]
+        GNU \program{makeinfo} is used to convert Texinfo documents to
+        GNU info files.  Since Texinfo is used as an intermediate
+        format in the info conversion, this program is needed in that
+        conversion.
+
+      \item[\program{pdflatex}]
+        pdf\TeX{} is a relatively new variant of \TeX, and is used to
+        generate the PDF version of the manuals.  It is typically
+        installed as part of most of the large \TeX{} distributions.
+        \program{pdflatex} is pdf\TeX{} using the \LaTeX{} format.
+
+      \item[\program{perl}]
+        Perl is required for \LaTeX2HTML{} and one of the scripts used
+        to post-process \LaTeX2HTML output, as well as the
+        HTML-to-Texinfo conversion.  This is required for
+        the HTML and GNU info conversions.
+
+      \item[\program{python}]
+        Python is used for many of the scripts in the
+        \file{Doc/tools/} directory; it is required for all
+        conversions.  This shouldn't be a problem if you're interested
+        in writing documentation for Python!
+    \end{description}
+
+
+  \subsection{Internal Tools \label{tools-internal}}
+
+    This section describes the various scripts that are used to
+    implement various stages of document processing or to orchestrate
+    entire build sequences.  Most of these tools are only useful
+    in the context of building the standard documentation, but some
+    are more general.
+
+    \begin{description}
+      \item[\program{mkhowto}]
+        This is the primary script used to format third-party
+        documents.  It contains all the logic needed to ``get it
+        right.''  The proper way to use this script is to make a
+        symbolic link to it or run it in place; the actual script file
+        must be stored as part of the documentation source tree,
+        though it may be used to format documents outside the tree.
+        Use \program{mkhowto} \longprogramopt{help} for a list of
+        command line options.
+
+        \program{mkhowto} can be used for both \code{howto} and
+        \code{manual} class documents.  It is usually a good idea to
+        always use the latest version of this tool rather than a
+        version from an older source release of Python.  It can be
+        used to generate DVI, HTML, PDF, PostScript, and plain text
+        documents.  The GNU info and iSilo formats will be supported
+        by this script in some future version.
+
+        Use the \longprogramopt{help} option on this script's command
+        line to get a summary of options for this script.
+
+        XXX  Need more here.
+    \end{description}
+
+
+  \subsection{Working on Cygwin \label{cygwin}}
+
+    Installing the required tools under Cygwin under Cygwin can be a
+    little tedious.  Most of the required packages can be installed
+    using Cygwin's graphical installer, while netpbm and \LaTeX2HTML
+    must be installed from source. 
+
+    Start with a reasonably modern version of Cygwin.  If you haven't
+    upgraded for a few years, now would be a good time.
+
+    Using the Cygwin installer, make sure your Cygwin installation
+    includes Perl, Python, and the \TeX{} packages.  Perl and Python
+    are located under the \menuselection{Interpreters} heading.  The
+    \TeX{} packages are located under the \menuselection{Text}
+    heading, and are named \code{tetex-*}.  To ensure that all
+    required packages are available, install every \code{tetex}
+    package, except \code{tetex-x11}.  (There may be a more minimal
+    set, but I've not spent time trying to minimize the installation.) 
+
+    The netpbm package is used by \LaTeX2HTML, and \emph{must} be
+    installed before \LaTeX2HTML can be successfully installed, even
+    though its features will not be used for most Python
+    documentation.  References to download locations are located in
+    the \ulink{netpbm README}{http://netpbm.sourceforge.net/README}.
+    Install from the latest stable source distribution according to
+    the instructions.  (Note that binary packages of netpbm are
+    sometimes available, but these may not work correctly with
+    \LaTeX2HTML.)
+
+    \LaTeX2HTML can be installed from the source archive, but only
+    after munging one of the files in the distribution.  Download the
+    source archive from the \LaTeX2HTML website
+    \url{http://www.latex2html.org/} (or one of the many alternate
+    sites) and unpack it to a build directory. In the top level of
+    this build directory there will be a file named \file{L2hos.pm}.
+    Open \file{L2hos.pm} in an editor, and near the bottom of the file
+    replace the text \code{\$\textasciicircum{}O} with the text
+    \code{'unix'}.  Proceed using this command to build and install
+    the software:
+
+\begin{verbatim}
+% ./configure && make install
+\end{verbatim}
+
+    You should now be able to build at least the DVI, HTML, PDF, and
+    PostScript versions of the formatted documentation.
+
+
+\section{Including Graphics \label{graphics}}
+
+  The standard documentation included with Python makes no use of
+  diagrams or images; this is intentional.  The outside tools used to
+  format the documentation have not always been suited to working with
+  graphics.  As the tools have evolved and been improved by their
+  maintainers, support for graphics has improved.
+
+  The internal tools, starting with the \program{mkhowto} script, do
+  not provide any direct support for graphics.  However,
+  \program{mkhowto} will not interfere with graphics support in the
+  external tools.
+
+  Experience using graphics together with these tools and the
+  \code{howto} and \code{manual} document classes is not extensive,
+  but has been known to work.  The basic approach is this:
+
+  \begin{enumerate}
+    \item Create the image or graphic using your favorite
+          application.
+
+    \item Convert the image to a format supported by the conversion to
+          your desired output format.  If you want to generate HTML or
+          PostScript, you can convert the image or graphic to
+          encapsulated PostScript (a \file{.eps} file); \LaTeX2HTML
+          can convert that to a \file{.gif} file; it may be possible
+          to provide a \file{.gif} file directly.  If you want to
+          generate PDF, you need to provide an ``encapsulated'' PDF
+          file.  This can be generated from encapsulated PostScript
+          using the \program{epstopdf} tool provided with the te\TeX{}
+          distribution on Linux and \UNIX.
+
+    \item In your document, add this line to ``import'' the general
+          graphics support package \code{graphicx}:
+
+\begin{verbatim}
+\usepackage{graphicx}
+\end{verbatim}
+
+    \item Where you want to include your graphic or image, include
+          markup similar to this:
+
+\begin{verbatim}
+\begin{figure}
+  \centering
+  \includegraphics[width=5in]{myimage}
+  \caption{Description of my image}
+\end{figure}
+\end{verbatim}
+
+          In particular, note for the \macro{includegraphics} macro
+          that no file extension is provided.  If you're only
+          interested in one target format, you can include the
+          extension of the appropriate input file, but to allow
+          support for multiple formats, omitting the extension makes
+          life easier.
+
+    \item Run \program{mkhowto} normally.
+  \end{enumerate}
+
+  If you're working on systems which support some sort of
+  \program{make} facility, you can use that to ensure the intermediate
+  graphic formats are kept up to date.  This example shows a
+  \file{Makefile} used to format a document containing a diagram
+  created using the \program{dia} application:
+
+\begin{verbatim}
+default: pdf
+all:     html pdf ps
+
+html:   mydoc/mydoc.html
+pdf:    mydoc.pdf
+ps:     mydoc.ps
+
+mydoc/mydoc.html:  mydoc.tex mygraphic.eps
+        mkhowto --html $<
+
+mydoc.pdf:  mydoc.tex mygraphic.pdf
+        mkhowto --pdf $<
+
+mydoc.ps:   mydoc.tex mygraphic.eps
+        mkhowto --postscript $<
+
+.SUFFIXES: .dia .eps .pdf
+
+.dia.eps:
+        dia --nosplash --export $@ $<
+
+.eps.pdf:
+        epstopdf $<
+\end{verbatim} % $ <-- bow to font-lock
+
+
+\section{Future Directions \label{futures}}
+
+  The history of the Python documentation is full of changes, most of
+  which have been fairly small and evolutionary.  There has been a
+  great deal of discussion about making large changes in the markup
+  languages and tools used to process the documentation.  This section
+  deals with the nature of the changes and what appears to be the most
+  likely path of future development.
+
+  \subsection{Structured Documentation \label{structured}}
+
+    Most of the small changes to the \LaTeX{} markup have been made
+    with an eye to divorcing the markup from the presentation, making
+    both a bit more maintainable.  Over the course of 1998, a large
+    number of changes were made with exactly this in mind; previously,
+    changes had been made but in a less systematic manner and with
+    more concern for not needing to update the existing content.  The
+    result has been a highly structured and semantically loaded markup
+    language implemented in \LaTeX.  With almost no basic \TeX{} or
+    \LaTeX{} markup in use, however, the markup syntax is about the
+    only evidence of \LaTeX{} in the actual document sources.
+
+    One side effect of this is that while we've been able to use
+    standard ``engines'' for manipulating the documents, such as
+    \LaTeX{} and \LaTeX2HTML, most of the actual transformations have
+    been created specifically for Python.  The \LaTeX{} document
+    classes and \LaTeX2HTML support are both complete implementations
+    of the specific markup designed for these documents.
+
+    Combining highly customized markup with the somewhat esoteric
+    systems used to process the documents leads us to ask some
+    questions:  Can we do this more easily?  and, Can we do this
+    better?  After a great deal of discussion with the community, we
+    have determined that actively pursuing modern structured
+    documentation systems is worth some investment of time.
+
+    There appear to be two real contenders in this arena: the Standard
+    General Markup Language (SGML), and the Extensible Markup Language
+    (XML).  Both of these standards have advantages and disadvantages,
+    and many advantages are shared.
+
+    SGML offers advantages which may appeal most to authors,
+    especially those using ordinary text editors.  There are also
+    additional abilities to define content models.  A number of
+    high-quality tools with demonstrated maturity are available, but
+    most are not free; for those which are, portability issues remain
+    a problem.
+
+    The advantages of XML include the availability of a large number
+    of evolving tools.  Unfortunately, many of the associated
+    standards are still evolving, and the tools will have to follow
+    along.  This means that developing a robust tool set that uses
+    more than the basic XML 1.0 recommendation is not possible in the
+    short term.  The promised availability of a wide variety of
+    high-quality tools which support some of the most important
+    related standards is not immediate.  Many tools are likely to be
+    free, and the portability issues of those which are, are not
+    expected to be significant.
+
+    It turns out that converting to an XML or SGML system holds
+    promise for translators as well; how much can be done to ease the
+    burden on translators remains to be seen, and may have some impact
+    on the schema and specific technologies used.
+
+    XXX Eventual migration to XML.
+
+    The documentation will be moved to XML in the future, and tools
+    are being written which will convert the documentation from the
+    current format to something close to a finished version, to the
+    extent that the desired information is already present in the
+    documentation.  Some XSLT stylesheets have been started for
+    presenting a preliminary XML version as HTML, but the results are
+    fairly rough.
+
+    The timeframe for the conversion is not clear since there doesn't
+    seem to be much time available to work on this, but the apparent
+    benefits are growing more substantial at a moderately rapid pace.
+
+
+  \subsection{Discussion Forums \label{discussion}}
+
+    Discussion of the future of the Python documentation and related
+    topics takes place in the Documentation Special Interest Group, or
+    ``Doc-SIG.''  Information on the group, including mailing list
+    archives and subscription information, is available at
+    \url{http://www.python.org/sigs/doc-sig/}.  The SIG is open to all
+    interested parties.
+
+    Comments and bug reports on the standard documents should be sent
+    to \email{docs at python.org}.  This may include comments
+    about formatting, content, grammatical and spelling errors, or
+    this document.  You can also send comments on this document
+    directly to the author at \email{fdrake at acm.org}.
+
+\input{doc.ind}
+
+\end{document}

Added: vendor/Python/current/Doc/ext/building.tex
===================================================================
--- vendor/Python/current/Doc/ext/building.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/ext/building.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,143 @@
+\chapter{Building C and \Cpp{} Extensions with distutils
+     \label{building}}
+
+\sectionauthor{Martin v. L\"owis}{martin at v.loewis.de}
+
+Starting in Python 1.4, Python provides, on \UNIX{}, a special make
+file for building make files for building dynamically-linked
+extensions and custom interpreters.  Starting with Python 2.0, this
+mechanism (known as related to Makefile.pre.in, and Setup files) is no
+longer supported. Building custom interpreters was rarely used, and
+extension modules can be built using distutils.
+
+Building an extension module using distutils requires that distutils
+is installed on the build machine, which is included in Python 2.x and
+available separately for Python 1.5. Since distutils also supports
+creation of binary packages, users don't necessarily need a compiler
+and distutils to install the extension.
+
+A distutils package contains a driver script, \file{setup.py}. This is
+a plain Python file, which, in the most simple case, could look like
+this:
+
+\begin{verbatim}
+from distutils.core import setup, Extension
+
+module1 = Extension('demo',
+                    sources = ['demo.c'])
+
+setup (name = 'PackageName',
+       version = '1.0',
+       description = 'This is a demo package',
+       ext_modules = [module1])
+
+\end{verbatim}
+
+With this \file{setup.py}, and a file \file{demo.c}, running
+
+\begin{verbatim}
+python setup.py build 
+\end{verbatim}
+
+will compile \file{demo.c}, and produce an extension module named
+\samp{demo} in the \file{build} directory. Depending on the system,
+the module file will end up in a subdirectory \file{build/lib.system},
+and may have a name like \file{demo.so} or \file{demo.pyd}.
+
+In the \file{setup.py}, all execution is performed by calling the
+\samp{setup} function. This takes a variable number of keyword 
+arguments, of which the example above uses only a
+subset. Specifically, the example specifies meta-information to build
+packages, and it specifies the contents of the package.  Normally, a
+package will contain of addition modules, like Python source modules,
+documentation, subpackages, etc. Please refer to the distutils
+documentation in \citetitle[../dist/dist.html]{Distributing Python
+Modules} to learn more about the features of distutils; this section
+explains building extension modules only.
+
+It is common to pre-compute arguments to \function{setup}, to better
+structure the driver script. In the example above,
+the\samp{ext_modules} argument to \function{setup} is a list of
+extension modules, each of which is an instance of the
+\class{Extension}. In the example, the instance defines an extension
+named \samp{demo} which is build by compiling a single source file,
+\file{demo.c}.
+
+In many cases, building an extension is more complex, since additional
+preprocessor defines and libraries may be needed. This is demonstrated
+in the example below.
+
+\begin{verbatim}
+from distutils.core import setup, Extension
+
+module1 = Extension('demo',
+                    define_macros = [('MAJOR_VERSION', '1'),
+                                     ('MINOR_VERSION', '0')],
+                    include_dirs = ['/usr/local/include'],
+                    libraries = ['tcl83'],
+                    library_dirs = ['/usr/local/lib'],
+                    sources = ['demo.c'])
+
+setup (name = 'PackageName',
+       version = '1.0',
+       description = 'This is a demo package',
+       author = 'Martin v. Loewis',
+       author_email = 'martin at v.loewis.de',
+       url = 'http://www.python.org/doc/current/ext/building.html',
+       long_description = '''
+This is really just a demo package.
+''',
+       ext_modules = [module1])
+
+\end{verbatim}
+
+In this example, \function{setup} is called with additional
+meta-information, which is recommended when distribution packages have
+to be built. For the extension itself, it specifies preprocessor
+defines, include directories, library directories, and libraries.
+Depending on the compiler, distutils passes this information in
+different ways to the compiler. For example, on \UNIX{}, this may
+result in the compilation commands
+
+\begin{verbatim}
+gcc -DNDEBUG -g -O3 -Wall -Wstrict-prototypes -fPIC -DMAJOR_VERSION=1 -DMINOR_VERSION=0 -I/usr/local/include -I/usr/local/include/python2.2 -c demo.c -o build/temp.linux-i686-2.2/demo.o
+
+gcc -shared build/temp.linux-i686-2.2/demo.o -L/usr/local/lib -ltcl83 -o build/lib.linux-i686-2.2/demo.so
+\end{verbatim}
+
+These lines are for demonstration purposes only; distutils users
+should trust that distutils gets the invocations right.
+
+\section{Distributing your extension modules
+     \label{distributing}}
+
+When an extension has been successfully build, there are three ways to
+use it.
+
+End-users will typically want to install the module, they do so by
+running
+
+\begin{verbatim}
+python setup.py install
+\end{verbatim}
+
+Module maintainers should produce source packages; to do so, they run
+
+\begin{verbatim}
+python setup.py sdist
+\end{verbatim}
+
+In some cases, additional files need to be included in a source
+distribution; this is done through a \file{MANIFEST.in} file; see the
+distutils documentation for details.
+
+If the source distribution has been build successfully, maintainers
+can also create binary distributions. Depending on the platform, one
+of the following commands can be used to do so.
+
+\begin{verbatim}
+python setup.py bdist_wininst
+python setup.py bdist_rpm
+python setup.py bdist_dumb
+\end{verbatim}
+

Added: vendor/Python/current/Doc/ext/embedding.tex
===================================================================
--- vendor/Python/current/Doc/ext/embedding.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/ext/embedding.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,316 @@
+\chapter{Embedding Python in Another Application
+     \label{embedding}}
+
+The previous chapters discussed how to extend Python, that is, how to
+extend the functionality of Python by attaching a library of C
+functions to it.  It is also possible to do it the other way around:
+enrich your C/\Cpp{} application by embedding Python in it.  Embedding
+provides your application with the ability to implement some of the
+functionality of your application in Python rather than C or \Cpp.
+This can be used for many purposes; one example would be to allow
+users to tailor the application to their needs by writing some scripts
+in Python.  You can also use it yourself if some of the functionality
+can be written in Python more easily.
+
+Embedding Python is similar to extending it, but not quite.  The
+difference is that when you extend Python, the main program of the
+application is still the Python interpreter, while if you embed
+Python, the main program may have nothing to do with Python ---
+instead, some parts of the application occasionally call the Python
+interpreter to run some Python code.
+
+So if you are embedding Python, you are providing your own main
+program.  One of the things this main program has to do is initialize
+the Python interpreter.  At the very least, you have to call the
+function \cfunction{Py_Initialize()} (on Mac OS, call
+\cfunction{PyMac_Initialize()} instead).  There are optional calls to
+pass command line arguments to Python.  Then later you can call the
+interpreter from any part of the application.
+
+There are several different ways to call the interpreter: you can pass
+a string containing Python statements to
+\cfunction{PyRun_SimpleString()}, or you can pass a stdio file pointer
+and a file name (for identification in error messages only) to
+\cfunction{PyRun_SimpleFile()}.  You can also call the lower-level
+operations described in the previous chapters to construct and use
+Python objects.
+
+A simple demo of embedding Python can be found in the directory
+\file{Demo/embed/} of the source distribution.
+
+
+\begin{seealso}
+  \seetitle[../api/api.html]{Python/C API Reference Manual}{The
+            details of Python's C interface are given in this manual.
+            A great deal of necessary information can be found here.}
+\end{seealso}
+
+
+\section{Very High Level Embedding
+         \label{high-level-embedding}}
+
+The simplest form of embedding Python is the use of the very
+high level interface. This interface is intended to execute a
+Python script without needing to interact with the application
+directly. This can for example be used to perform some operation
+on a file.
+
+\begin{verbatim}
+#include <Python.h>
+
+int
+main(int argc, char *argv[])
+{
+  Py_Initialize();
+  PyRun_SimpleString("from time import time,ctime\n"
+                     "print 'Today is',ctime(time())\n");
+  Py_Finalize();
+  return 0;
+}
+\end{verbatim}
+
+The above code first initializes the Python interpreter with
+\cfunction{Py_Initialize()}, followed by the execution of a hard-coded
+Python script that print the date and time.  Afterwards, the
+\cfunction{Py_Finalize()} call shuts the interpreter down, followed by
+the end of the program.  In a real program, you may want to get the
+Python script from another source, perhaps a text-editor routine, a
+file, or a database.  Getting the Python code from a file can better
+be done by using the \cfunction{PyRun_SimpleFile()} function, which
+saves you the trouble of allocating memory space and loading the file
+contents.
+
+
+\section{Beyond Very High Level Embedding: An overview
+         \label{lower-level-embedding}}
+
+The high level interface gives you the ability to execute
+arbitrary pieces of Python code from your application, but
+exchanging data values is quite cumbersome to say the least. If
+you want that, you should use lower level calls. At the cost of
+having to write more C code, you can achieve almost anything.
+
+It should be noted that extending Python and embedding Python
+is quite the same activity, despite the different intent. Most
+topics discussed in the previous chapters are still valid. To
+show this, consider what the extension code from Python to C
+really does:
+
+\begin{enumerate}
+    \item Convert data values from Python to C,
+    \item Perform a function call to a C routine using the
+        converted values, and
+    \item Convert the data values from the call from C to Python.
+\end{enumerate}
+
+When embedding Python, the interface code does:
+
+\begin{enumerate}
+    \item Convert data values from C to Python,
+    \item Perform a function call to a Python interface routine
+        using the converted values, and
+    \item Convert the data values from the call from Python to C.
+\end{enumerate}
+
+As you can see, the data conversion steps are simply swapped to
+accommodate the different direction of the cross-language transfer.
+The only difference is the routine that you call between both
+data conversions. When extending, you call a C routine, when
+embedding, you call a Python routine.
+
+This chapter will not discuss how to convert data from Python
+to C and vice versa.  Also, proper use of references and dealing
+with errors is assumed to be understood.  Since these aspects do not
+differ from extending the interpreter, you can refer to earlier
+chapters for the required information.
+
+
+\section{Pure Embedding
+         \label{pure-embedding}}
+
+The first program aims to execute a function in a Python
+script. Like in the section about the very high level interface,
+the Python interpreter does not directly interact with the
+application (but that will change in the next section).
+
+The code to run a function defined in a Python script is:
+
+\verbatiminput{run-func.c}
+
+This code loads a Python script using \code{argv[1]}, and calls the
+function named in \code{argv[2]}.  Its integer arguments are the other
+values of the \code{argv} array.  If you compile and link this
+program (let's call the finished executable \program{call}), and use
+it to execute a Python script, such as:
+
+\begin{verbatim}
+def multiply(a,b):
+    print "Will compute", a, "times", b
+    c = 0
+    for i in range(0, a):
+        c = c + b
+    return c
+\end{verbatim}
+
+then the result should be:
+
+\begin{verbatim}
+$ call multiply multiply 3 2
+Will compute 3 times 2
+Result of call: 6
+\end{verbatim} % $
+
+Although the program is quite large for its functionality, most of the
+code is for data conversion between Python and C, and for error
+reporting.  The interesting part with respect to embedding Python
+starts with
+
+\begin{verbatim}
+    Py_Initialize();
+    pName = PyString_FromString(argv[1]);
+    /* Error checking of pName left out */
+    pModule = PyImport_Import(pName);
+\end{verbatim}
+
+After initializing the interpreter, the script is loaded using
+\cfunction{PyImport_Import()}.  This routine needs a Python string
+as its argument, which is constructed using the
+\cfunction{PyString_FromString()} data conversion routine.
+
+\begin{verbatim}
+    pFunc = PyObject_GetAttrString(pModule, argv[2]);
+    /* pFunc is a new reference */
+
+    if (pFunc && PyCallable_Check(pFunc)) {
+        ...
+    }
+    Py_XDECREF(pFunc);
+\end{verbatim}
+
+Once the script is loaded, the name we're looking for is retrieved
+using \cfunction{PyObject_GetAttrString()}.  If the name exists, and
+the object returned is callable, you can safely assume that it is a
+function.  The program then proceeds by constructing a tuple of
+arguments as normal.  The call to the Python function is then made
+with:
+
+\begin{verbatim}
+    pValue = PyObject_CallObject(pFunc, pArgs);
+\end{verbatim}
+
+Upon return of the function, \code{pValue} is either \NULL{} or it
+contains a reference to the return value of the function.  Be sure to
+release the reference after examining the value.
+
+
+\section{Extending Embedded Python
+         \label{extending-with-embedding}}
+
+Until now, the embedded Python interpreter had no access to
+functionality from the application itself.  The Python API allows this
+by extending the embedded interpreter.  That is, the embedded
+interpreter gets extended with routines provided by the application.
+While it sounds complex, it is not so bad.  Simply forget for a while
+that the application starts the Python interpreter.  Instead, consider
+the application to be a set of subroutines, and write some glue code
+that gives Python access to those routines, just like you would write
+a normal Python extension.  For example:
+
+\begin{verbatim}
+static int numargs=0;
+
+/* Return the number of arguments of the application command line */
+static PyObject*
+emb_numargs(PyObject *self, PyObject *args)
+{
+    if(!PyArg_ParseTuple(args, ":numargs"))
+        return NULL;
+    return Py_BuildValue("i", numargs);
+}
+
+static PyMethodDef EmbMethods[] = {
+    {"numargs", emb_numargs, METH_VARARGS,
+     "Return the number of arguments received by the process."},
+    {NULL, NULL, 0, NULL}
+};
+\end{verbatim}
+
+Insert the above code just above the \cfunction{main()} function.
+Also, insert the following two statements directly after
+\cfunction{Py_Initialize()}:
+
+\begin{verbatim}
+    numargs = argc;
+    Py_InitModule("emb", EmbMethods);
+\end{verbatim}
+
+These two lines initialize the \code{numargs} variable, and make the
+\function{emb.numargs()} function accessible to the embedded Python
+interpreter.  With these extensions, the Python script can do things
+like
+
+\begin{verbatim}
+import emb
+print "Number of arguments", emb.numargs()
+\end{verbatim}
+
+In a real application, the methods will expose an API of the
+application to Python.
+
+
+%\section{For the future}
+%
+%You don't happen to have a nice library to get textual
+%equivalents of numeric values do you :-) ?
+%Callbacks here ? (I may be using information from that section
+%?!)
+%threads
+%code examples do not really behave well if errors happen
+% (what to watch out for)
+
+
+\section{Embedding Python in \Cpp
+     \label{embeddingInCplusplus}}
+
+It is also possible to embed Python in a \Cpp{} program; precisely how this
+is done will depend on the details of the \Cpp{} system used; in general you
+will need to write the main program in \Cpp, and use the \Cpp{} compiler
+to compile and link your program.  There is no need to recompile Python
+itself using \Cpp.
+
+
+\section{Linking Requirements
+         \label{link-reqs}}
+
+While the \program{configure} script shipped with the Python sources
+will correctly build Python to export the symbols needed by
+dynamically linked extensions, this is not automatically inherited by
+applications which embed the Python library statically, at least on
+\UNIX.  This is an issue when the application is linked to the static
+runtime library (\file{libpython.a}) and needs to load dynamic
+extensions (implemented as \file{.so} files).
+
+The problem is that some entry points are defined by the Python
+runtime solely for extension modules to use.  If the embedding
+application does not use any of these entry points, some linkers will
+not include those entries in the symbol table of the finished
+executable.  Some additional options are needed to inform the linker
+not to remove these symbols.
+
+Determining the right options to use for any given platform can be
+quite difficult, but fortunately the Python configuration already has
+those values.  To retrieve them from an installed Python interpreter,
+start an interactive interpreter and have a short session like this:
+
+\begin{verbatim}
+>>> import distutils.sysconfig
+>>> distutils.sysconfig.get_config_var('LINKFORSHARED')
+'-Xlinker -export-dynamic'
+\end{verbatim}
+\refstmodindex{distutils.sysconfig}
+
+The contents of the string presented will be the options that should
+be used.  If the string is empty, there's no need to add any
+additional options.  The \constant{LINKFORSHARED} definition
+corresponds to the variable of the same name in Python's top-level
+\file{Makefile}.

Added: vendor/Python/current/Doc/ext/ext.tex
===================================================================
--- vendor/Python/current/Doc/ext/ext.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/ext/ext.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,67 @@
+\documentclass{manual}
+
+% XXX PM explain how to add new types to Python
+
+\title{Extending and Embedding the Python Interpreter}
+
+\input{boilerplate}
+
+% Tell \index to actually write the .idx file
+\makeindex
+
+\begin{document}
+
+\maketitle
+
+\ifhtml
+\chapter*{Front Matter\label{front}}
+\fi
+
+\input{copyright}
+
+
+\begin{abstract}
+
+\noindent
+Python is an interpreted, object-oriented programming language.  This
+document describes how to write modules in C or \Cpp{} to extend the
+Python interpreter with new modules.  Those modules can define new
+functions but also new object types and their methods.  The document
+also describes how to embed the Python interpreter in another
+application, for use as an extension language.  Finally, it shows how
+to compile and link extension modules so that they can be loaded
+dynamically (at run time) into the interpreter, if the underlying
+operating system supports this feature.
+
+This document assumes basic knowledge about Python.  For an informal
+introduction to the language, see the
+\citetitle[../tut/tut.html]{Python Tutorial}.  The
+\citetitle[../ref/ref.html]{Python Reference Manual} gives a more
+formal definition of the language.  The
+\citetitle[../lib/lib.html]{Python Library Reference} documents the
+existing object types, functions and modules (both built-in and
+written in Python) that give the language its wide application range.
+
+For a detailed description of the whole Python/C API, see the separate
+\citetitle[../api/api.html]{Python/C API Reference Manual}.
+
+\end{abstract}
+
+\tableofcontents
+
+
+\input{extending}
+\input{newtypes}
+\input{building}
+\input{windows}
+\input{embedding}
+
+
+\appendix
+\chapter{Reporting Bugs}
+\input{reportingbugs}
+
+\chapter{History and License}
+\input{license}
+
+\end{document}

Added: vendor/Python/current/Doc/ext/extending.tex
===================================================================
--- vendor/Python/current/Doc/ext/extending.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/ext/extending.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1390 @@
+\chapter{Extending Python with \C{} or \Cpp{} \label{intro}}
+
+
+It is quite easy to add new built-in modules to Python, if you know
+how to program in C.  Such \dfn{extension modules} can do two things
+that can't be done directly in Python: they can implement new built-in
+object types, and they can call C library functions and system calls.
+
+To support extensions, the Python API (Application Programmers
+Interface) defines a set of functions, macros and variables that
+provide access to most aspects of the Python run-time system.  The
+Python API is incorporated in a C source file by including the header
+\code{"Python.h"}.
+
+The compilation of an extension module depends on its intended use as
+well as on your system setup; details are given in later chapters.
+
+
+\section{A Simple Example
+         \label{simpleExample}}
+
+Let's create an extension module called \samp{spam} (the favorite food
+of Monty Python fans...) and let's say we want to create a Python
+interface to the C library function \cfunction{system()}.\footnote{An
+interface for this function already exists in the standard module
+\module{os} --- it was chosen as a simple and straightforward example.}
+This function takes a null-terminated character string as argument and
+returns an integer.  We want this function to be callable from Python
+as follows:
+
+\begin{verbatim}
+>>> import spam
+>>> status = spam.system("ls -l")
+\end{verbatim}
+
+Begin by creating a file \file{spammodule.c}.  (Historically, if a
+module is called \samp{spam}, the C file containing its implementation
+is called \file{spammodule.c}; if the module name is very long, like
+\samp{spammify}, the module name can be just \file{spammify.c}.)
+
+The first line of our file can be:
+
+\begin{verbatim}
+#include <Python.h>
+\end{verbatim}
+
+which pulls in the Python API (you can add a comment describing the
+purpose of the module and a copyright notice if you like).
+
+\begin{notice}[warning]
+  Since Python may define some pre-processor definitions which affect
+  the standard headers on some systems, you \emph{must} include
+  \file{Python.h} before any standard headers are included.
+\end{notice}
+
+All user-visible symbols defined by \file{Python.h} have a prefix of
+\samp{Py} or \samp{PY}, except those defined in standard header files.
+For convenience, and since they are used extensively by the Python
+interpreter, \code{"Python.h"} includes a few standard header files:
+\code{<stdio.h>}, \code{<string.h>}, \code{<errno.h>}, and
+\code{<stdlib.h>}.  If the latter header file does not exist on your
+system, it declares the functions \cfunction{malloc()},
+\cfunction{free()} and \cfunction{realloc()} directly.
+
+The next thing we add to our module file is the C function that will
+be called when the Python expression \samp{spam.system(\var{string})}
+is evaluated (we'll see shortly how it ends up being called):
+
+\begin{verbatim}
+static PyObject *
+spam_system(PyObject *self, PyObject *args)
+{
+    const char *command;
+    int sts;
+
+    if (!PyArg_ParseTuple(args, "s", &command))
+        return NULL;
+    sts = system(command);
+    return Py_BuildValue("i", sts);
+}
+\end{verbatim}
+
+There is a straightforward translation from the argument list in
+Python (for example, the single expression \code{"ls -l"}) to the
+arguments passed to the C function.  The C function always has two
+arguments, conventionally named \var{self} and \var{args}.
+
+The \var{self} argument is only used when the C function implements a
+built-in method, not a function. In the example, \var{self} will
+always be a \NULL{} pointer, since we are defining a function, not a
+method.  (This is done so that the interpreter doesn't have to
+understand two different types of C functions.)
+
+The \var{args} argument will be a pointer to a Python tuple object
+containing the arguments.  Each item of the tuple corresponds to an
+argument in the call's argument list.  The arguments are Python
+objects --- in order to do anything with them in our C function we have
+to convert them to C values.  The function \cfunction{PyArg_ParseTuple()}
+in the Python API checks the argument types and converts them to C
+values.  It uses a template string to determine the required types of
+the arguments as well as the types of the C variables into which to
+store the converted values.  More about this later.
+
+\cfunction{PyArg_ParseTuple()} returns true (nonzero) if all arguments have
+the right type and its components have been stored in the variables
+whose addresses are passed.  It returns false (zero) if an invalid
+argument list was passed.  In the latter case it also raises an
+appropriate exception so the calling function can return
+\NULL{} immediately (as we saw in the example).
+
+
+\section{Intermezzo: Errors and Exceptions
+         \label{errors}}
+
+An important convention throughout the Python interpreter is the
+following: when a function fails, it should set an exception condition
+and return an error value (usually a \NULL{} pointer).  Exceptions
+are stored in a static global variable inside the interpreter; if this
+variable is \NULL{} no exception has occurred.  A second global
+variable stores the ``associated value'' of the exception (the second
+argument to \keyword{raise}).  A third variable contains the stack
+traceback in case the error originated in Python code.  These three
+variables are the C equivalents of the Python variables
+\code{sys.exc_type}, \code{sys.exc_value} and \code{sys.exc_traceback} (see
+the section on module \module{sys} in the
+\citetitle[../lib/lib.html]{Python Library Reference}).  It is
+important to know about them to understand how errors are passed
+around.
+
+The Python API defines a number of functions to set various types of
+exceptions.
+
+The most common one is \cfunction{PyErr_SetString()}.  Its arguments
+are an exception object and a C string.  The exception object is
+usually a predefined object like \cdata{PyExc_ZeroDivisionError}.  The
+C string indicates the cause of the error and is converted to a
+Python string object and stored as the ``associated value'' of the
+exception.
+
+Another useful function is \cfunction{PyErr_SetFromErrno()}, which only
+takes an exception argument and constructs the associated value by
+inspection of the global variable \cdata{errno}.  The most
+general function is \cfunction{PyErr_SetObject()}, which takes two object
+arguments, the exception and its associated value.  You don't need to
+\cfunction{Py_INCREF()} the objects passed to any of these functions.
+
+You can test non-destructively whether an exception has been set with
+\cfunction{PyErr_Occurred()}.  This returns the current exception object,
+or \NULL{} if no exception has occurred.  You normally don't need
+to call \cfunction{PyErr_Occurred()} to see whether an error occurred in a
+function call, since you should be able to tell from the return value.
+
+When a function \var{f} that calls another function \var{g} detects
+that the latter fails, \var{f} should itself return an error value
+(usually \NULL{} or \code{-1}).  It should \emph{not} call one of the
+\cfunction{PyErr_*()} functions --- one has already been called by \var{g}.
+\var{f}'s caller is then supposed to also return an error indication
+to \emph{its} caller, again \emph{without} calling \cfunction{PyErr_*()},
+and so on --- the most detailed cause of the error was already
+reported by the function that first detected it.  Once the error
+reaches the Python interpreter's main loop, this aborts the currently
+executing Python code and tries to find an exception handler specified
+by the Python programmer.
+
+(There are situations where a module can actually give a more detailed
+error message by calling another \cfunction{PyErr_*()} function, and in
+such cases it is fine to do so.  As a general rule, however, this is
+not necessary, and can cause information about the cause of the error
+to be lost: most operations can fail for a variety of reasons.)
+
+To ignore an exception set by a function call that failed, the exception
+condition must be cleared explicitly by calling \cfunction{PyErr_Clear()}. 
+The only time C code should call \cfunction{PyErr_Clear()} is if it doesn't
+want to pass the error on to the interpreter but wants to handle it
+completely by itself (possibly by trying something else, or pretending
+nothing went wrong).
+
+Every failing \cfunction{malloc()} call must be turned into an
+exception --- the direct caller of \cfunction{malloc()} (or
+\cfunction{realloc()}) must call \cfunction{PyErr_NoMemory()} and
+return a failure indicator itself.  All the object-creating functions
+(for example, \cfunction{PyInt_FromLong()}) already do this, so this
+note is only relevant to those who call \cfunction{malloc()} directly.
+
+Also note that, with the important exception of
+\cfunction{PyArg_ParseTuple()} and friends, functions that return an
+integer status usually return a positive value or zero for success and
+\code{-1} for failure, like \UNIX{} system calls.
+
+Finally, be careful to clean up garbage (by making
+\cfunction{Py_XDECREF()} or \cfunction{Py_DECREF()} calls for objects
+you have already created) when you return an error indicator!
+
+The choice of which exception to raise is entirely yours.  There are
+predeclared C objects corresponding to all built-in Python exceptions,
+such as \cdata{PyExc_ZeroDivisionError}, which you can use directly.
+Of course, you should choose exceptions wisely --- don't use
+\cdata{PyExc_TypeError} to mean that a file couldn't be opened (that
+should probably be \cdata{PyExc_IOError}).  If something's wrong with
+the argument list, the \cfunction{PyArg_ParseTuple()} function usually
+raises \cdata{PyExc_TypeError}.  If you have an argument whose value
+must be in a particular range or must satisfy other conditions,
+\cdata{PyExc_ValueError} is appropriate.
+
+You can also define a new exception that is unique to your module.
+For this, you usually declare a static object variable at the
+beginning of your file:
+
+\begin{verbatim}
+static PyObject *SpamError;
+\end{verbatim}
+
+and initialize it in your module's initialization function
+(\cfunction{initspam()}) with an exception object (leaving out
+the error checking for now):
+
+\begin{verbatim}
+PyMODINIT_FUNC
+initspam(void)
+{
+    PyObject *m;
+
+    m = Py_InitModule("spam", SpamMethods);
+    if (m == NULL)
+        return;
+
+    SpamError = PyErr_NewException("spam.error", NULL, NULL);
+    Py_INCREF(SpamError);
+    PyModule_AddObject(m, "error", SpamError);
+}
+\end{verbatim}
+
+Note that the Python name for the exception object is
+\exception{spam.error}.  The \cfunction{PyErr_NewException()} function
+may create a class with the base class being \exception{Exception}
+(unless another class is passed in instead of \NULL), described in the
+\citetitle[../lib/lib.html]{Python Library Reference} under ``Built-in
+Exceptions.''
+
+Note also that the \cdata{SpamError} variable retains a reference to
+the newly created exception class; this is intentional!  Since the
+exception could be removed from the module by external code, an owned
+reference to the class is needed to ensure that it will not be
+discarded, causing \cdata{SpamError} to become a dangling pointer.
+Should it become a dangling pointer, C code which raises the exception
+could cause a core dump or other unintended side effects.
+
+We discuss the use of PyMODINIT_FUNC as a function return type later in this
+sample.
+
+\section{Back to the Example
+         \label{backToExample}}
+
+Going back to our example function, you should now be able to
+understand this statement:
+
+\begin{verbatim}
+    if (!PyArg_ParseTuple(args, "s", &command))
+        return NULL;
+\end{verbatim}
+
+It returns \NULL{} (the error indicator for functions returning
+object pointers) if an error is detected in the argument list, relying
+on the exception set by \cfunction{PyArg_ParseTuple()}.  Otherwise the
+string value of the argument has been copied to the local variable
+\cdata{command}.  This is a pointer assignment and you are not supposed
+to modify the string to which it points (so in Standard C, the variable
+\cdata{command} should properly be declared as \samp{const char
+*command}).
+
+The next statement is a call to the \UNIX{} function
+\cfunction{system()}, passing it the string we just got from
+\cfunction{PyArg_ParseTuple()}:
+
+\begin{verbatim}
+    sts = system(command);
+\end{verbatim}
+
+Our \function{spam.system()} function must return the value of
+\cdata{sts} as a Python object.  This is done using the function
+\cfunction{Py_BuildValue()}, which is something like the inverse of
+\cfunction{PyArg_ParseTuple()}: it takes a format string and an
+arbitrary number of C values, and returns a new Python object.
+More info on \cfunction{Py_BuildValue()} is given later.
+
+\begin{verbatim}
+    return Py_BuildValue("i", sts);
+\end{verbatim}
+
+In this case, it will return an integer object.  (Yes, even integers
+are objects on the heap in Python!)
+
+If you have a C function that returns no useful argument (a function
+returning \ctype{void}), the corresponding Python function must return
+\code{None}.   You need this idiom to do so (which is implemented by the
+\csimplemacro{Py_RETURN_NONE} macro):
+
+\begin{verbatim}
+    Py_INCREF(Py_None);
+    return Py_None;
+\end{verbatim}
+
+\cdata{Py_None} is the C name for the special Python object
+\code{None}.  It is a genuine Python object rather than a \NULL{}
+pointer, which means ``error'' in most contexts, as we have seen.
+
+
+\section{The Module's Method Table and Initialization Function
+         \label{methodTable}}
+
+I promised to show how \cfunction{spam_system()} is called from Python
+programs.  First, we need to list its name and address in a ``method
+table'':
+
+\begin{verbatim}
+static PyMethodDef SpamMethods[] = {
+    ...
+    {"system",  spam_system, METH_VARARGS,
+     "Execute a shell command."},
+    ...
+    {NULL, NULL, 0, NULL}        /* Sentinel */
+};
+\end{verbatim}
+
+Note the third entry (\samp{METH_VARARGS}).  This is a flag telling
+the interpreter the calling convention to be used for the C
+function.  It should normally always be \samp{METH_VARARGS} or
+\samp{METH_VARARGS | METH_KEYWORDS}; a value of \code{0} means that an
+obsolete variant of \cfunction{PyArg_ParseTuple()} is used.
+
+When using only \samp{METH_VARARGS}, the function should expect
+the Python-level parameters to be passed in as a tuple acceptable for
+parsing via \cfunction{PyArg_ParseTuple()}; more information on this
+function is provided below.
+
+The \constant{METH_KEYWORDS} bit may be set in the third field if
+keyword arguments should be passed to the function.  In this case, the
+C function should accept a third \samp{PyObject *} parameter which
+will be a dictionary of keywords.  Use
+\cfunction{PyArg_ParseTupleAndKeywords()} to parse the arguments to
+such a function.
+
+The method table must be passed to the interpreter in the module's
+initialization function.  The initialization function must be named
+\cfunction{init\var{name}()}, where \var{name} is the name of the
+module, and should be the only non-\keyword{static} item defined in
+the module file:
+
+\begin{verbatim}
+PyMODINIT_FUNC
+initspam(void)
+{
+    (void) Py_InitModule("spam", SpamMethods);
+}
+\end{verbatim}
+
+Note that PyMODINIT_FUNC declares the function as \code{void} return type, 
+declares any special linkage declarations required by the platform, and for 
+\Cpp{} declares the function as \code{extern "C"}.
+
+When the Python program imports module \module{spam} for the first
+time, \cfunction{initspam()} is called. (See below for comments about
+embedding Python.)  It calls
+\cfunction{Py_InitModule()}, which creates a ``module object'' (which
+is inserted in the dictionary \code{sys.modules} under the key
+\code{"spam"}), and inserts built-in function objects into the newly
+created module based upon the table (an array of \ctype{PyMethodDef}
+structures) that was passed as its second argument.
+\cfunction{Py_InitModule()} returns a pointer to the module object
+that it creates (which is unused here).  It may abort with a fatal error
+for certain errors, or return \NULL{} if the module could not be
+initialized satisfactorily.
+
+When embedding Python, the \cfunction{initspam()} function is not
+called automatically unless there's an entry in the
+\cdata{_PyImport_Inittab} table.  The easiest way to handle this is to 
+statically initialize your statically-linked modules by directly
+calling \cfunction{initspam()} after the call to
+\cfunction{Py_Initialize()}:
+
+\begin{verbatim}
+int
+main(int argc, char *argv[])
+{
+    /* Pass argv[0] to the Python interpreter */
+    Py_SetProgramName(argv[0]);
+
+    /* Initialize the Python interpreter.  Required. */
+    Py_Initialize();
+
+    /* Add a static module */
+    initspam();
+\end{verbatim}
+
+An example may be found in the file \file{Demo/embed/demo.c} in the
+Python source distribution.
+
+\note{Removing entries from \code{sys.modules} or importing
+compiled modules into multiple interpreters within a process (or
+following a \cfunction{fork()} without an intervening
+\cfunction{exec()}) can create problems for some extension modules.
+Extension module authors should exercise caution when initializing
+internal data structures.
+Note also that the \function{reload()} function can be used with
+extension modules, and will call the module initialization function
+(\cfunction{initspam()} in the example), but will not load the module
+again if it was loaded from a dynamically loadable object file
+(\file{.so} on \UNIX, \file{.dll} on Windows).}
+
+A more substantial example module is included in the Python source
+distribution as \file{Modules/xxmodule.c}.  This file may be used as a 
+template or simply read as an example.  The \program{modulator.py}
+script included in the source distribution or Windows install provides 
+a simple graphical user interface for declaring the functions and
+objects which a module should implement, and can generate a template
+which can be filled in.  The script lives in the
+\file{Tools/modulator/} directory; see the \file{README} file there
+for more information.
+
+
+\section{Compilation and Linkage
+         \label{compilation}}
+
+There are two more things to do before you can use your new extension:
+compiling and linking it with the Python system.  If you use dynamic
+loading, the details may depend on the style of dynamic loading your
+system uses; see the chapters about building extension modules
+(chapter \ref{building}) and additional information that pertains only
+to building on Windows (chapter \ref{building-on-windows}) for more
+information about this.
+
+If you can't use dynamic loading, or if you want to make your module a
+permanent part of the Python interpreter, you will have to change the
+configuration setup and rebuild the interpreter.  Luckily, this is
+very simple on \UNIX: just place your file (\file{spammodule.c} for
+example) in the \file{Modules/} directory of an unpacked source
+distribution, add a line to the file \file{Modules/Setup.local}
+describing your file:
+
+\begin{verbatim}
+spam spammodule.o
+\end{verbatim}
+
+and rebuild the interpreter by running \program{make} in the toplevel
+directory.  You can also run \program{make} in the \file{Modules/}
+subdirectory, but then you must first rebuild \file{Makefile}
+there by running `\program{make} Makefile'.  (This is necessary each
+time you change the \file{Setup} file.)
+
+If your module requires additional libraries to link with, these can
+be listed on the line in the configuration file as well, for instance:
+
+\begin{verbatim}
+spam spammodule.o -lX11
+\end{verbatim}
+
+\section{Calling Python Functions from C
+         \label{callingPython}}
+
+So far we have concentrated on making C functions callable from
+Python.  The reverse is also useful: calling Python functions from C.
+This is especially the case for libraries that support so-called
+``callback'' functions.  If a C interface makes use of callbacks, the
+equivalent Python often needs to provide a callback mechanism to the
+Python programmer; the implementation will require calling the Python
+callback functions from a C callback.  Other uses are also imaginable.
+
+Fortunately, the Python interpreter is easily called recursively, and
+there is a standard interface to call a Python function.  (I won't
+dwell on how to call the Python parser with a particular string as
+input --- if you're interested, have a look at the implementation of
+the \programopt{-c} command line option in \file{Python/pythonmain.c}
+from the Python source code.)
+
+Calling a Python function is easy.  First, the Python program must
+somehow pass you the Python function object.  You should provide a
+function (or some other interface) to do this.  When this function is
+called, save a pointer to the Python function object (be careful to
+\cfunction{Py_INCREF()} it!) in a global variable --- or wherever you
+see fit. For example, the following function might be part of a module
+definition:
+
+\begin{verbatim}
+static PyObject *my_callback = NULL;
+
+static PyObject *
+my_set_callback(PyObject *dummy, PyObject *args)
+{
+    PyObject *result = NULL;
+    PyObject *temp;
+
+    if (PyArg_ParseTuple(args, "O:set_callback", &temp)) {
+        if (!PyCallable_Check(temp)) {
+            PyErr_SetString(PyExc_TypeError, "parameter must be callable");
+            return NULL;
+        }
+        Py_XINCREF(temp);         /* Add a reference to new callback */
+        Py_XDECREF(my_callback);  /* Dispose of previous callback */
+        my_callback = temp;       /* Remember new callback */
+        /* Boilerplate to return "None" */
+        Py_INCREF(Py_None);
+        result = Py_None;
+    }
+    return result;
+}
+\end{verbatim}
+
+This function must be registered with the interpreter using the
+\constant{METH_VARARGS} flag; this is described in section
+\ref{methodTable}, ``The Module's Method Table and Initialization
+Function.''  The \cfunction{PyArg_ParseTuple()} function and its
+arguments are documented in section~\ref{parseTuple}, ``Extracting
+Parameters in Extension Functions.''
+
+The macros \cfunction{Py_XINCREF()} and \cfunction{Py_XDECREF()}
+increment/decrement the reference count of an object and are safe in
+the presence of \NULL{} pointers (but note that \var{temp} will not be 
+\NULL{} in this context).  More info on them in
+section~\ref{refcounts}, ``Reference Counts.''
+
+Later, when it is time to call the function, you call the C function
+\cfunction{PyEval_CallObject()}.\ttindex{PyEval_CallObject()}  This
+function has two arguments, both pointers to arbitrary Python objects:
+the Python function, and the argument list.  The argument list must
+always be a tuple object, whose length is the number of arguments.  To
+call the Python function with no arguments, pass an empty tuple; to
+call it with one argument, pass a singleton tuple.
+\cfunction{Py_BuildValue()} returns a tuple when its format string
+consists of zero or more format codes between parentheses.  For
+example:
+
+\begin{verbatim}
+    int arg;
+    PyObject *arglist;
+    PyObject *result;
+    ...
+    arg = 123;
+    ...
+    /* Time to call the callback */
+    arglist = Py_BuildValue("(i)", arg);
+    result = PyEval_CallObject(my_callback, arglist);
+    Py_DECREF(arglist);
+\end{verbatim}
+
+\cfunction{PyEval_CallObject()} returns a Python object pointer: this is
+the return value of the Python function.  \cfunction{PyEval_CallObject()} is
+``reference-count-neutral'' with respect to its arguments.  In the
+example a new tuple was created to serve as the argument list, which
+is \cfunction{Py_DECREF()}-ed immediately after the call.
+
+The return value of \cfunction{PyEval_CallObject()} is ``new'': either it
+is a brand new object, or it is an existing object whose reference
+count has been incremented.  So, unless you want to save it in a
+global variable, you should somehow \cfunction{Py_DECREF()} the result,
+even (especially!) if you are not interested in its value.
+
+Before you do this, however, it is important to check that the return
+value isn't \NULL.  If it is, the Python function terminated by
+raising an exception.  If the C code that called
+\cfunction{PyEval_CallObject()} is called from Python, it should now
+return an error indication to its Python caller, so the interpreter
+can print a stack trace, or the calling Python code can handle the
+exception.  If this is not possible or desirable, the exception should
+be cleared by calling \cfunction{PyErr_Clear()}.  For example:
+
+\begin{verbatim}
+    if (result == NULL)
+        return NULL; /* Pass error back */
+    ...use result...
+    Py_DECREF(result); 
+\end{verbatim}
+
+Depending on the desired interface to the Python callback function,
+you may also have to provide an argument list to
+\cfunction{PyEval_CallObject()}.  In some cases the argument list is
+also provided by the Python program, through the same interface that
+specified the callback function.  It can then be saved and used in the
+same manner as the function object.  In other cases, you may have to
+construct a new tuple to pass as the argument list.  The simplest way
+to do this is to call \cfunction{Py_BuildValue()}.  For example, if
+you want to pass an integral event code, you might use the following
+code:
+
+\begin{verbatim}
+    PyObject *arglist;
+    ...
+    arglist = Py_BuildValue("(l)", eventcode);
+    result = PyEval_CallObject(my_callback, arglist);
+    Py_DECREF(arglist);
+    if (result == NULL)
+        return NULL; /* Pass error back */
+    /* Here maybe use the result */
+    Py_DECREF(result);
+\end{verbatim}
+
+Note the placement of \samp{Py_DECREF(arglist)} immediately after the
+call, before the error check!  Also note that strictly spoken this
+code is not complete: \cfunction{Py_BuildValue()} may run out of
+memory, and this should be checked.
+
+
+\section{Extracting Parameters in Extension Functions
+         \label{parseTuple}}
+
+\ttindex{PyArg_ParseTuple()}
+
+The \cfunction{PyArg_ParseTuple()} function is declared as follows:
+
+\begin{verbatim}
+int PyArg_ParseTuple(PyObject *arg, char *format, ...);
+\end{verbatim}
+
+The \var{arg} argument must be a tuple object containing an argument
+list passed from Python to a C function.  The \var{format} argument
+must be a format string, whose syntax is explained in
+``\ulink{Parsing arguments and building
+values}{../api/arg-parsing.html}'' in the
+\citetitle[../api/api.html]{Python/C API Reference Manual}.  The
+remaining arguments must be addresses of variables whose type is
+determined by the format string.
+
+Note that while \cfunction{PyArg_ParseTuple()} checks that the Python
+arguments have the required types, it cannot check the validity of the
+addresses of C variables passed to the call: if you make mistakes
+there, your code will probably crash or at least overwrite random bits
+in memory.  So be careful!
+
+Note that any Python object references which are provided to the
+caller are \emph{borrowed} references; do not decrement their
+reference count!
+
+Some example calls:
+
+\begin{verbatim}
+    int ok;
+    int i, j;
+    long k, l;
+    const char *s;
+    int size;
+
+    ok = PyArg_ParseTuple(args, ""); /* No arguments */
+        /* Python call: f() */
+\end{verbatim}
+
+\begin{verbatim}
+    ok = PyArg_ParseTuple(args, "s", &s); /* A string */
+        /* Possible Python call: f('whoops!') */
+\end{verbatim}
+
+\begin{verbatim}
+    ok = PyArg_ParseTuple(args, "lls", &k, &l, &s); /* Two longs and a string */
+        /* Possible Python call: f(1, 2, 'three') */
+\end{verbatim}
+
+\begin{verbatim}
+    ok = PyArg_ParseTuple(args, "(ii)s#", &i, &j, &s, &size);
+        /* A pair of ints and a string, whose size is also returned */
+        /* Possible Python call: f((1, 2), 'three') */
+\end{verbatim}
+
+\begin{verbatim}
+    {
+        const char *file;
+        const char *mode = "r";
+        int bufsize = 0;
+        ok = PyArg_ParseTuple(args, "s|si", &file, &mode, &bufsize);
+        /* A string, and optionally another string and an integer */
+        /* Possible Python calls:
+           f('spam')
+           f('spam', 'w')
+           f('spam', 'wb', 100000) */
+    }
+\end{verbatim}
+
+\begin{verbatim}
+    {
+        int left, top, right, bottom, h, v;
+        ok = PyArg_ParseTuple(args, "((ii)(ii))(ii)",
+                 &left, &top, &right, &bottom, &h, &v);
+        /* A rectangle and a point */
+        /* Possible Python call:
+           f(((0, 0), (400, 300)), (10, 10)) */
+    }
+\end{verbatim}
+
+\begin{verbatim}
+    {
+        Py_complex c;
+        ok = PyArg_ParseTuple(args, "D:myfunction", &c);
+        /* a complex, also providing a function name for errors */
+        /* Possible Python call: myfunction(1+2j) */
+    }
+\end{verbatim}
+
+
+\section{Keyword Parameters for Extension Functions
+         \label{parseTupleAndKeywords}}
+
+\ttindex{PyArg_ParseTupleAndKeywords()}
+
+The \cfunction{PyArg_ParseTupleAndKeywords()} function is declared as
+follows:
+
+\begin{verbatim}
+int PyArg_ParseTupleAndKeywords(PyObject *arg, PyObject *kwdict,
+                                char *format, char *kwlist[], ...);
+\end{verbatim}
+
+The \var{arg} and \var{format} parameters are identical to those of the
+\cfunction{PyArg_ParseTuple()} function.  The \var{kwdict} parameter
+is the dictionary of keywords received as the third parameter from the
+Python runtime.  The \var{kwlist} parameter is a \NULL-terminated
+list of strings which identify the parameters; the names are matched
+with the type information from \var{format} from left to right.  On
+success, \cfunction{PyArg_ParseTupleAndKeywords()} returns true,
+otherwise it returns false and raises an appropriate exception.
+
+\note{Nested tuples cannot be parsed when using keyword
+arguments!  Keyword parameters passed in which are not present in the
+\var{kwlist} will cause \exception{TypeError} to be raised.}
+
+Here is an example module which uses keywords, based on an example by
+Geoff Philbrick (\email{philbrick at hks.com}):%
+\index{Philbrick, Geoff}
+
+\begin{verbatim}
+#include "Python.h"
+
+static PyObject *
+keywdarg_parrot(PyObject *self, PyObject *args, PyObject *keywds)
+{  
+    int voltage;
+    char *state = "a stiff";
+    char *action = "voom";
+    char *type = "Norwegian Blue";
+
+    static char *kwlist[] = {"voltage", "state", "action", "type", NULL};
+
+    if (!PyArg_ParseTupleAndKeywords(args, keywds, "i|sss", kwlist, 
+                                     &voltage, &state, &action, &type))
+        return NULL; 
+  
+    printf("-- This parrot wouldn't %s if you put %i Volts through it.\n", 
+           action, voltage);
+    printf("-- Lovely plumage, the %s -- It's %s!\n", type, state);
+
+    Py_INCREF(Py_None);
+
+    return Py_None;
+}
+
+static PyMethodDef keywdarg_methods[] = {
+    /* The cast of the function is necessary since PyCFunction values
+     * only take two PyObject* parameters, and keywdarg_parrot() takes
+     * three.
+     */
+    {"parrot", (PyCFunction)keywdarg_parrot, METH_VARARGS | METH_KEYWORDS,
+     "Print a lovely skit to standard output."},
+    {NULL, NULL, 0, NULL}   /* sentinel */
+};
+\end{verbatim}
+
+\begin{verbatim}
+void
+initkeywdarg(void)
+{
+  /* Create the module and add the functions */
+  Py_InitModule("keywdarg", keywdarg_methods);
+}
+\end{verbatim}
+
+
+\section{Building Arbitrary Values
+         \label{buildValue}}
+
+This function is the counterpart to \cfunction{PyArg_ParseTuple()}.  It is
+declared as follows:
+
+\begin{verbatim}
+PyObject *Py_BuildValue(char *format, ...);
+\end{verbatim}
+
+It recognizes a set of format units similar to the ones recognized by
+\cfunction{PyArg_ParseTuple()}, but the arguments (which are input to the
+function, not output) must not be pointers, just values.  It returns a
+new Python object, suitable for returning from a C function called
+from Python.
+
+One difference with \cfunction{PyArg_ParseTuple()}: while the latter
+requires its first argument to be a tuple (since Python argument lists
+are always represented as tuples internally),
+\cfunction{Py_BuildValue()} does not always build a tuple.  It builds
+a tuple only if its format string contains two or more format units.
+If the format string is empty, it returns \code{None}; if it contains
+exactly one format unit, it returns whatever object is described by
+that format unit.  To force it to return a tuple of size 0 or one,
+parenthesize the format string.
+
+Examples (to the left the call, to the right the resulting Python value):
+
+\begin{verbatim}
+    Py_BuildValue("")                        None
+    Py_BuildValue("i", 123)                  123
+    Py_BuildValue("iii", 123, 456, 789)      (123, 456, 789)
+    Py_BuildValue("s", "hello")              'hello'
+    Py_BuildValue("ss", "hello", "world")    ('hello', 'world')
+    Py_BuildValue("s#", "hello", 4)          'hell'
+    Py_BuildValue("()")                      ()
+    Py_BuildValue("(i)", 123)                (123,)
+    Py_BuildValue("(ii)", 123, 456)          (123, 456)
+    Py_BuildValue("(i,i)", 123, 456)         (123, 456)
+    Py_BuildValue("[i,i]", 123, 456)         [123, 456]
+    Py_BuildValue("{s:i,s:i}",
+                  "abc", 123, "def", 456)    {'abc': 123, 'def': 456}
+    Py_BuildValue("((ii)(ii)) (ii)",
+                  1, 2, 3, 4, 5, 6)          (((1, 2), (3, 4)), (5, 6))
+\end{verbatim}
+
+
+\section{Reference Counts
+         \label{refcounts}}
+
+In languages like C or \Cpp, the programmer is responsible for
+dynamic allocation and deallocation of memory on the heap.  In C,
+this is done using the functions \cfunction{malloc()} and
+\cfunction{free()}.  In \Cpp, the operators \keyword{new} and
+\keyword{delete} are used with essentially the same meaning and
+we'll restrict the following discussion to the C case.
+
+Every block of memory allocated with \cfunction{malloc()} should
+eventually be returned to the pool of available memory by exactly one
+call to \cfunction{free()}.  It is important to call
+\cfunction{free()} at the right time.  If a block's address is
+forgotten but \cfunction{free()} is not called for it, the memory it
+occupies cannot be reused until the program terminates.  This is
+called a \dfn{memory leak}.  On the other hand, if a program calls
+\cfunction{free()} for a block and then continues to use the block, it
+creates a conflict with re-use of the block through another
+\cfunction{malloc()} call.  This is called \dfn{using freed memory}.
+It has the same bad consequences as referencing uninitialized data ---
+core dumps, wrong results, mysterious crashes.
+
+Common causes of memory leaks are unusual paths through the code.  For
+instance, a function may allocate a block of memory, do some
+calculation, and then free the block again.  Now a change in the
+requirements for the function may add a test to the calculation that
+detects an error condition and can return prematurely from the
+function.  It's easy to forget to free the allocated memory block when
+taking this premature exit, especially when it is added later to the
+code.  Such leaks, once introduced, often go undetected for a long
+time: the error exit is taken only in a small fraction of all calls,
+and most modern machines have plenty of virtual memory, so the leak
+only becomes apparent in a long-running process that uses the leaking
+function frequently.  Therefore, it's important to prevent leaks from
+happening by having a coding convention or strategy that minimizes
+this kind of errors.
+
+Since Python makes heavy use of \cfunction{malloc()} and
+\cfunction{free()}, it needs a strategy to avoid memory leaks as well
+as the use of freed memory.  The chosen method is called
+\dfn{reference counting}.  The principle is simple: every object
+contains a counter, which is incremented when a reference to the
+object is stored somewhere, and which is decremented when a reference
+to it is deleted.  When the counter reaches zero, the last reference
+to the object has been deleted and the object is freed.
+
+An alternative strategy is called \dfn{automatic garbage collection}.
+(Sometimes, reference counting is also referred to as a garbage
+collection strategy, hence my use of ``automatic'' to distinguish the
+two.)  The big advantage of automatic garbage collection is that the
+user doesn't need to call \cfunction{free()} explicitly.  (Another claimed
+advantage is an improvement in speed or memory usage --- this is no
+hard fact however.)  The disadvantage is that for C, there is no
+truly portable automatic garbage collector, while reference counting
+can be implemented portably (as long as the functions \cfunction{malloc()}
+and \cfunction{free()} are available --- which the C Standard guarantees).
+Maybe some day a sufficiently portable automatic garbage collector
+will be available for C.  Until then, we'll have to live with
+reference counts.
+
+While Python uses the traditional reference counting implementation,
+it also offers a cycle detector that works to detect reference
+cycles.  This allows applications to not worry about creating direct
+or indirect circular references; these are the weakness of garbage
+collection implemented using only reference counting.  Reference
+cycles consist of objects which contain (possibly indirect) references
+to themselves, so that each object in the cycle has a reference count
+which is non-zero.  Typical reference counting implementations are not
+able to reclaim the memory belonging to any objects in a reference
+cycle, or referenced from the objects in the cycle, even though there
+are no further references to the cycle itself.
+
+The cycle detector is able to detect garbage cycles and can reclaim
+them so long as there are no finalizers implemented in Python
+(\method{__del__()} methods).  When there are such finalizers, the
+detector exposes the cycles through the \ulink{\module{gc}
+module}{../lib/module-gc.html} (specifically, the \code{garbage}
+variable in that module).  The \module{gc} module also exposes a way
+to run the detector (the \function{collect()} function), as well as
+configuration interfaces and the ability to disable the detector at
+runtime.  The cycle detector is considered an optional component;
+though it is included by default, it can be disabled at build time
+using the \longprogramopt{without-cycle-gc} option to the
+\program{configure} script on \UNIX{} platforms (including Mac OS X)
+or by removing the definition of \code{WITH_CYCLE_GC} in the
+\file{pyconfig.h} header on other platforms.  If the cycle detector is
+disabled in this way, the \module{gc} module will not be available.
+
+
+\subsection{Reference Counting in Python
+            \label{refcountsInPython}}
+
+There are two macros, \code{Py_INCREF(x)} and \code{Py_DECREF(x)},
+which handle the incrementing and decrementing of the reference count.
+\cfunction{Py_DECREF()} also frees the object when the count reaches zero.
+For flexibility, it doesn't call \cfunction{free()} directly --- rather, it
+makes a call through a function pointer in the object's \dfn{type
+object}.  For this purpose (and others), every object also contains a
+pointer to its type object.
+
+The big question now remains: when to use \code{Py_INCREF(x)} and
+\code{Py_DECREF(x)}?  Let's first introduce some terms.  Nobody
+``owns'' an object; however, you can \dfn{own a reference} to an
+object.  An object's reference count is now defined as the number of
+owned references to it.  The owner of a reference is responsible for
+calling \cfunction{Py_DECREF()} when the reference is no longer
+needed.  Ownership of a reference can be transferred.  There are three
+ways to dispose of an owned reference: pass it on, store it, or call
+\cfunction{Py_DECREF()}.  Forgetting to dispose of an owned reference
+creates a memory leak.
+
+It is also possible to \dfn{borrow}\footnote{The metaphor of
+``borrowing'' a reference is not completely correct: the owner still
+has a copy of the reference.} a reference to an object.  The borrower
+of a reference should not call \cfunction{Py_DECREF()}.  The borrower must
+not hold on to the object longer than the owner from which it was
+borrowed.  Using a borrowed reference after the owner has disposed of
+it risks using freed memory and should be avoided
+completely.\footnote{Checking that the reference count is at least 1
+\strong{does not work} --- the reference count itself could be in
+freed memory and may thus be reused for another object!}
+
+The advantage of borrowing over owning a reference is that you don't
+need to take care of disposing of the reference on all possible paths
+through the code --- in other words, with a borrowed reference you
+don't run the risk of leaking when a premature exit is taken.  The
+disadvantage of borrowing over leaking is that there are some subtle
+situations where in seemingly correct code a borrowed reference can be
+used after the owner from which it was borrowed has in fact disposed
+of it.
+
+A borrowed reference can be changed into an owned reference by calling
+\cfunction{Py_INCREF()}.  This does not affect the status of the owner from
+which the reference was borrowed --- it creates a new owned reference,
+and gives full owner responsibilities (the new owner must
+dispose of the reference properly, as well as the previous owner).
+
+
+\subsection{Ownership Rules
+            \label{ownershipRules}}
+
+Whenever an object reference is passed into or out of a function, it
+is part of the function's interface specification whether ownership is
+transferred with the reference or not.
+
+Most functions that return a reference to an object pass on ownership
+with the reference.  In particular, all functions whose function it is
+to create a new object, such as \cfunction{PyInt_FromLong()} and
+\cfunction{Py_BuildValue()}, pass ownership to the receiver.  Even if
+the object is not actually new, you still receive ownership of a new
+reference to that object.  For instance, \cfunction{PyInt_FromLong()}
+maintains a cache of popular values and can return a reference to a
+cached item.
+
+Many functions that extract objects from other objects also transfer
+ownership with the reference, for instance
+\cfunction{PyObject_GetAttrString()}.  The picture is less clear, here,
+however, since a few common routines are exceptions:
+\cfunction{PyTuple_GetItem()}, \cfunction{PyList_GetItem()},
+\cfunction{PyDict_GetItem()}, and \cfunction{PyDict_GetItemString()}
+all return references that you borrow from the tuple, list or
+dictionary.
+
+The function \cfunction{PyImport_AddModule()} also returns a borrowed
+reference, even though it may actually create the object it returns:
+this is possible because an owned reference to the object is stored in
+\code{sys.modules}.
+
+When you pass an object reference into another function, in general,
+the function borrows the reference from you --- if it needs to store
+it, it will use \cfunction{Py_INCREF()} to become an independent
+owner.  There are exactly two important exceptions to this rule:
+\cfunction{PyTuple_SetItem()} and \cfunction{PyList_SetItem()}.  These
+functions take over ownership of the item passed to them --- even if
+they fail!  (Note that \cfunction{PyDict_SetItem()} and friends don't
+take over ownership --- they are ``normal.'')
+
+When a C function is called from Python, it borrows references to its
+arguments from the caller.  The caller owns a reference to the object,
+so the borrowed reference's lifetime is guaranteed until the function
+returns.  Only when such a borrowed reference must be stored or passed
+on, it must be turned into an owned reference by calling
+\cfunction{Py_INCREF()}.
+
+The object reference returned from a C function that is called from
+Python must be an owned reference --- ownership is transferred from
+the function to its caller.
+
+
+\subsection{Thin Ice
+            \label{thinIce}}
+
+There are a few situations where seemingly harmless use of a borrowed
+reference can lead to problems.  These all have to do with implicit
+invocations of the interpreter, which can cause the owner of a
+reference to dispose of it.
+
+The first and most important case to know about is using
+\cfunction{Py_DECREF()} on an unrelated object while borrowing a
+reference to a list item.  For instance:
+
+\begin{verbatim}
+void
+bug(PyObject *list)
+{
+    PyObject *item = PyList_GetItem(list, 0);
+
+    PyList_SetItem(list, 1, PyInt_FromLong(0L));
+    PyObject_Print(item, stdout, 0); /* BUG! */
+}
+\end{verbatim}
+
+This function first borrows a reference to \code{list[0]}, then
+replaces \code{list[1]} with the value \code{0}, and finally prints
+the borrowed reference.  Looks harmless, right?  But it's not!
+
+Let's follow the control flow into \cfunction{PyList_SetItem()}.  The list
+owns references to all its items, so when item 1 is replaced, it has
+to dispose of the original item 1.  Now let's suppose the original
+item 1 was an instance of a user-defined class, and let's further
+suppose that the class defined a \method{__del__()} method.  If this
+class instance has a reference count of 1, disposing of it will call
+its \method{__del__()} method.
+
+Since it is written in Python, the \method{__del__()} method can execute
+arbitrary Python code.  Could it perhaps do something to invalidate
+the reference to \code{item} in \cfunction{bug()}?  You bet!  Assuming
+that the list passed into \cfunction{bug()} is accessible to the
+\method{__del__()} method, it could execute a statement to the effect of
+\samp{del list[0]}, and assuming this was the last reference to that
+object, it would free the memory associated with it, thereby
+invalidating \code{item}.
+
+The solution, once you know the source of the problem, is easy:
+temporarily increment the reference count.  The correct version of the
+function reads:
+
+\begin{verbatim}
+void
+no_bug(PyObject *list)
+{
+    PyObject *item = PyList_GetItem(list, 0);
+
+    Py_INCREF(item);
+    PyList_SetItem(list, 1, PyInt_FromLong(0L));
+    PyObject_Print(item, stdout, 0);
+    Py_DECREF(item);
+}
+\end{verbatim}
+
+This is a true story.  An older version of Python contained variants
+of this bug and someone spent a considerable amount of time in a C
+debugger to figure out why his \method{__del__()} methods would fail...
+
+The second case of problems with a borrowed reference is a variant
+involving threads.  Normally, multiple threads in the Python
+interpreter can't get in each other's way, because there is a global
+lock protecting Python's entire object space.  However, it is possible
+to temporarily release this lock using the macro
+\csimplemacro{Py_BEGIN_ALLOW_THREADS}, and to re-acquire it using
+\csimplemacro{Py_END_ALLOW_THREADS}.  This is common around blocking
+I/O calls, to let other threads use the processor while waiting for
+the I/O to complete.  Obviously, the following function has the same
+problem as the previous one:
+
+\begin{verbatim}
+void
+bug(PyObject *list)
+{
+    PyObject *item = PyList_GetItem(list, 0);
+    Py_BEGIN_ALLOW_THREADS
+    ...some blocking I/O call...
+    Py_END_ALLOW_THREADS
+    PyObject_Print(item, stdout, 0); /* BUG! */
+}
+\end{verbatim}
+
+
+\subsection{NULL Pointers
+            \label{nullPointers}}
+
+In general, functions that take object references as arguments do not
+expect you to pass them \NULL{} pointers, and will dump core (or
+cause later core dumps) if you do so.  Functions that return object
+references generally return \NULL{} only to indicate that an
+exception occurred.  The reason for not testing for \NULL{}
+arguments is that functions often pass the objects they receive on to
+other function --- if each function were to test for \NULL,
+there would be a lot of redundant tests and the code would run more
+slowly.
+
+It is better to test for \NULL{} only at the ``source:'' when a
+pointer that may be \NULL{} is received, for example, from
+\cfunction{malloc()} or from a function that may raise an exception.
+
+The macros \cfunction{Py_INCREF()} and \cfunction{Py_DECREF()}
+do not check for \NULL{} pointers --- however, their variants
+\cfunction{Py_XINCREF()} and \cfunction{Py_XDECREF()} do.
+
+The macros for checking for a particular object type
+(\code{Py\var{type}_Check()}) don't check for \NULL{} pointers ---
+again, there is much code that calls several of these in a row to test
+an object against various different expected types, and this would
+generate redundant tests.  There are no variants with \NULL{}
+checking.
+
+The C function calling mechanism guarantees that the argument list
+passed to C functions (\code{args} in the examples) is never
+\NULL{} --- in fact it guarantees that it is always a tuple.\footnote{
+These guarantees don't hold when you use the ``old'' style
+calling convention --- this is still found in much existing code.}
+
+It is a severe error to ever let a \NULL{} pointer ``escape'' to
+the Python user.
+
+% Frank Stajano:
+% A pedagogically buggy example, along the lines of the previous listing, 
+% would be helpful here -- showing in more concrete terms what sort of 
+% actions could cause the problem. I can't very well imagine it from the 
+% description.
+
+
+\section{Writing Extensions in \Cpp
+         \label{cplusplus}}
+
+It is possible to write extension modules in \Cpp.  Some restrictions
+apply.  If the main program (the Python interpreter) is compiled and
+linked by the C compiler, global or static objects with constructors
+cannot be used.  This is not a problem if the main program is linked
+by the \Cpp{} compiler.  Functions that will be called by the
+Python interpreter (in particular, module initialization functions)
+have to be declared using \code{extern "C"}.
+It is unnecessary to enclose the Python header files in
+\code{extern "C" \{...\}} --- they use this form already if the symbol
+\samp{__cplusplus} is defined (all recent \Cpp{} compilers define this
+symbol).
+
+
+\section{Providing a C API for an Extension Module
+         \label{using-cobjects}}
+\sectionauthor{Konrad Hinsen}{hinsen at cnrs-orleans.fr}
+
+Many extension modules just provide new functions and types to be
+used from Python, but sometimes the code in an extension module can
+be useful for other extension modules. For example, an extension
+module could implement a type ``collection'' which works like lists
+without order. Just like the standard Python list type has a C API
+which permits extension modules to create and manipulate lists, this
+new collection type should have a set of C functions for direct
+manipulation from other extension modules.
+
+At first sight this seems easy: just write the functions (without
+declaring them \keyword{static}, of course), provide an appropriate
+header file, and document the C API. And in fact this would work if
+all extension modules were always linked statically with the Python
+interpreter. When modules are used as shared libraries, however, the
+symbols defined in one module may not be visible to another module.
+The details of visibility depend on the operating system; some systems
+use one global namespace for the Python interpreter and all extension
+modules (Windows, for example), whereas others require an explicit
+list of imported symbols at module link time (AIX is one example), or
+offer a choice of different strategies (most Unices). And even if
+symbols are globally visible, the module whose functions one wishes to
+call might not have been loaded yet!
+
+Portability therefore requires not to make any assumptions about
+symbol visibility. This means that all symbols in extension modules
+should be declared \keyword{static}, except for the module's
+initialization function, in order to avoid name clashes with other
+extension modules (as discussed in section~\ref{methodTable}). And it
+means that symbols that \emph{should} be accessible from other
+extension modules must be exported in a different way.
+
+Python provides a special mechanism to pass C-level information
+(pointers) from one extension module to another one: CObjects.
+A CObject is a Python data type which stores a pointer (\ctype{void
+*}).  CObjects can only be created and accessed via their C API, but
+they can be passed around like any other Python object. In particular, 
+they can be assigned to a name in an extension module's namespace.
+Other extension modules can then import this module, retrieve the
+value of this name, and then retrieve the pointer from the CObject.
+
+There are many ways in which CObjects can be used to export the C API
+of an extension module. Each name could get its own CObject, or all C
+API pointers could be stored in an array whose address is published in
+a CObject. And the various tasks of storing and retrieving the pointers
+can be distributed in different ways between the module providing the
+code and the client modules.
+
+The following example demonstrates an approach that puts most of the
+burden on the writer of the exporting module, which is appropriate
+for commonly used library modules. It stores all C API pointers
+(just one in the example!) in an array of \ctype{void} pointers which
+becomes the value of a CObject. The header file corresponding to
+the module provides a macro that takes care of importing the module
+and retrieving its C API pointers; client modules only have to call
+this macro before accessing the C API.
+
+The exporting module is a modification of the \module{spam} module from
+section~\ref{simpleExample}. The function \function{spam.system()}
+does not call the C library function \cfunction{system()} directly,
+but a function \cfunction{PySpam_System()}, which would of course do
+something more complicated in reality (such as adding ``spam'' to
+every command). This function \cfunction{PySpam_System()} is also
+exported to other extension modules.
+
+The function \cfunction{PySpam_System()} is a plain C function,
+declared \keyword{static} like everything else:
+
+\begin{verbatim}
+static int
+PySpam_System(const char *command)
+{
+    return system(command);
+}
+\end{verbatim}
+
+The function \cfunction{spam_system()} is modified in a trivial way:
+
+\begin{verbatim}
+static PyObject *
+spam_system(PyObject *self, PyObject *args)
+{
+    const char *command;
+    int sts;
+
+    if (!PyArg_ParseTuple(args, "s", &command))
+        return NULL;
+    sts = PySpam_System(command);
+    return Py_BuildValue("i", sts);
+}
+\end{verbatim}
+
+In the beginning of the module, right after the line
+
+\begin{verbatim}
+#include "Python.h"
+\end{verbatim}
+
+two more lines must be added:
+
+\begin{verbatim}
+#define SPAM_MODULE
+#include "spammodule.h"
+\end{verbatim}
+
+The \code{\#define} is used to tell the header file that it is being
+included in the exporting module, not a client module. Finally,
+the module's initialization function must take care of initializing
+the C API pointer array:
+
+\begin{verbatim}
+PyMODINIT_FUNC
+initspam(void)
+{
+    PyObject *m;
+    static void *PySpam_API[PySpam_API_pointers];
+    PyObject *c_api_object;
+
+    m = Py_InitModule("spam", SpamMethods);
+    if (m == NULL)
+        return;
+
+    /* Initialize the C API pointer array */
+    PySpam_API[PySpam_System_NUM] = (void *)PySpam_System;
+
+    /* Create a CObject containing the API pointer array's address */
+    c_api_object = PyCObject_FromVoidPtr((void *)PySpam_API, NULL);
+
+    if (c_api_object != NULL)
+        PyModule_AddObject(m, "_C_API", c_api_object);
+}
+\end{verbatim}
+
+Note that \code{PySpam_API} is declared \keyword{static}; otherwise
+the pointer array would disappear when \function{initspam()} terminates!
+
+The bulk of the work is in the header file \file{spammodule.h},
+which looks like this:
+
+\begin{verbatim}
+#ifndef Py_SPAMMODULE_H
+#define Py_SPAMMODULE_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Header file for spammodule */
+
+/* C API functions */
+#define PySpam_System_NUM 0
+#define PySpam_System_RETURN int
+#define PySpam_System_PROTO (const char *command)
+
+/* Total number of C API pointers */
+#define PySpam_API_pointers 1
+
+
+#ifdef SPAM_MODULE
+/* This section is used when compiling spammodule.c */
+
+static PySpam_System_RETURN PySpam_System PySpam_System_PROTO;
+
+#else
+/* This section is used in modules that use spammodule's API */
+
+static void **PySpam_API;
+
+#define PySpam_System \
+ (*(PySpam_System_RETURN (*)PySpam_System_PROTO) PySpam_API[PySpam_System_NUM])
+
+/* Return -1 and set exception on error, 0 on success. */
+static int
+import_spam(void)
+{
+    PyObject *module = PyImport_ImportModule("spam");
+
+    if (module != NULL) {
+        PyObject *c_api_object = PyObject_GetAttrString(module, "_C_API");
+        if (c_api_object == NULL)
+            return -1;
+        if (PyCObject_Check(c_api_object))
+            PySpam_API = (void **)PyCObject_AsVoidPtr(c_api_object);
+        Py_DECREF(c_api_object);
+    }
+    return 0;
+}
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !defined(Py_SPAMMODULE_H) */
+\end{verbatim}
+
+All that a client module must do in order to have access to the
+function \cfunction{PySpam_System()} is to call the function (or
+rather macro) \cfunction{import_spam()} in its initialization
+function:
+
+\begin{verbatim}
+PyMODINIT_FUNC
+initclient(void)
+{
+    PyObject *m;
+
+    m = Py_InitModule("client", ClientMethods);
+    if (m == NULL)
+        return;
+    if (import_spam() < 0)
+        return;
+    /* additional initialization can happen here */
+}
+\end{verbatim}
+
+The main disadvantage of this approach is that the file
+\file{spammodule.h} is rather complicated. However, the
+basic structure is the same for each function that is
+exported, so it has to be learned only once.
+
+Finally it should be mentioned that CObjects offer additional
+functionality, which is especially useful for memory allocation and
+deallocation of the pointer stored in a CObject. The details
+are described in the \citetitle[../api/api.html]{Python/C API
+Reference Manual} in the section
+``\ulink{CObjects}{../api/cObjects.html}'' and in the implementation
+of CObjects (files \file{Include/cobject.h} and
+\file{Objects/cobject.c} in the Python source code distribution).

Added: vendor/Python/current/Doc/ext/newtypes.tex
===================================================================
--- vendor/Python/current/Doc/ext/newtypes.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/ext/newtypes.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1765 @@
+\chapter{Defining New Types
+        \label{defining-new-types}}
+\sectionauthor{Michael Hudson}{mwh at python.net}
+\sectionauthor{Dave Kuhlman}{dkuhlman at rexx.com}
+\sectionauthor{Jim Fulton}{jim at zope.com}
+
+As mentioned in the last chapter, Python allows the writer of an
+extension module to define new types that can be manipulated from
+Python code, much like strings and lists in core Python.
+
+This is not hard; the code for all extension types follows a pattern,
+but there are some details that you need to understand before you can
+get started.
+
+\begin{notice}
+The way new types are defined changed dramatically (and for the
+better) in Python 2.2.  This document documents how to define new
+types for Python 2.2 and later.  If you need to support older
+versions of Python, you will need to refer to
+\ulink{older versions of this documentation}
+      {http://www.python.org/doc/versions/}.
+\end{notice}
+
+\section{The Basics
+    \label{dnt-basics}}
+
+The Python runtime sees all Python objects as variables of type
+\ctype{PyObject*}.  A \ctype{PyObject} is not a very magnificent
+object - it just contains the refcount and a pointer to the object's
+``type object''.  This is where the action is; the type object
+determines which (C) functions get called when, for instance, an
+attribute gets looked up on an object or it is multiplied by another
+object.  These C functions are called ``type methods'' to distinguish
+them from things like \code{[].append} (which we call ``object
+methods'').
+
+So, if you want to define a new object type, you need to create a new
+type object.
+
+This sort of thing can only be explained by example, so here's a
+minimal, but complete, module that defines a new type:
+
+\verbatiminput{noddy.c}
+
+Now that's quite a bit to take in at once, but hopefully bits will
+seem familiar from the last chapter.
+
+The first bit that will be new is:
+
+\begin{verbatim}
+typedef struct {
+    PyObject_HEAD
+} noddy_NoddyObject;
+\end{verbatim}
+
+This is what a Noddy object will contain---in this case, nothing more
+than every Python object contains, namely a refcount and a pointer to a type
+object.  These are the fields the \code{PyObject_HEAD} macro brings
+in.  The reason for the macro is to standardize the layout and to
+enable special debugging fields in debug builds.  Note that there is
+no semicolon after the \code{PyObject_HEAD} macro; one is included in
+the macro definition.  Be wary of adding one by accident; it's easy to
+do from habit, and your compiler might not complain, but someone
+else's probably will!  (On Windows, MSVC is known to call this an
+error and refuse to compile the code.)
+
+For contrast, let's take a look at the corresponding definition for
+standard Python integers:
+
+\begin{verbatim}
+typedef struct {
+    PyObject_HEAD
+    long ob_ival;
+} PyIntObject;
+\end{verbatim}
+
+Moving on, we come to the crunch --- the type object.
+
+\begin{verbatim}
+static PyTypeObject noddy_NoddyType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "noddy.Noddy",             /*tp_name*/
+    sizeof(noddy_NoddyObject), /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    0,                         /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,        /*tp_flags*/
+    "Noddy objects",           /* tp_doc */
+};
+\end{verbatim}
+
+Now if you go and look up the definition of \ctype{PyTypeObject} in
+\file{object.h} you'll see that it has many more fields that the
+definition above.  The remaining fields will be filled with zeros by
+the C compiler, and it's common practice to not specify them
+explicitly unless you need them.
+
+This is so important that we're going to pick the top of it apart still
+further:
+
+\begin{verbatim}
+    PyObject_HEAD_INIT(NULL)
+\end{verbatim}
+
+This line is a bit of a wart; what we'd like to write is:
+
+\begin{verbatim}
+    PyObject_HEAD_INIT(&PyType_Type)
+\end{verbatim}
+
+as the type of a type object is ``type'', but this isn't strictly
+conforming C and some compilers complain.  Fortunately, this member
+will be filled in for us by \cfunction{PyType_Ready()}.
+
+\begin{verbatim}
+    0,                          /* ob_size */
+\end{verbatim}
+
+The \member{ob_size} field of the header is not used; its presence in
+the type structure is a historical artifact that is maintained for
+binary compatibility with extension modules compiled for older
+versions of Python.  Always set this field to zero.
+
+\begin{verbatim}
+    "noddy.Noddy",              /* tp_name */
+\end{verbatim}
+
+The name of our type.  This will appear in the default textual
+representation of our objects and in some error messages, for example:
+
+\begin{verbatim}
+>>> "" + noddy.new_noddy()
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+TypeError: cannot add type "noddy.Noddy" to string
+\end{verbatim}
+
+Note that the name is a dotted name that includes both the module name
+and the name of the type within the module. The module in this case is
+\module{noddy} and the type is \class{Noddy}, so we set the type name
+to \class{noddy.Noddy}.
+
+\begin{verbatim}
+    sizeof(noddy_NoddyObject),  /* tp_basicsize */
+\end{verbatim}
+
+This is so that Python knows how much memory to allocate when you call
+\cfunction{PyObject_New()}.
+
+\note{If you want your type to be subclassable from Python, and your
+type has the same \member{tp_basicsize} as its base type, you may
+have problems with multiple inheritance.  A Python subclass of your
+type will have to list your type first in its \member{__bases__}, or
+else it will not be able to call your type's \method{__new__} method
+without getting an error.  You can avoid this problem by ensuring
+that your type has a larger value for \member{tp_basicsize} than
+its base type does.  Most of the time, this will be true anyway,
+because either your base type will be \class{object}, or else you will
+be adding data members to your base type, and therefore increasing its
+size.}
+
+\begin{verbatim}
+    0,                          /* tp_itemsize */
+\end{verbatim}
+
+This has to do with variable length objects like lists and strings.
+Ignore this for now.
+
+Skipping a number of type methods that we don't provide, we set the
+class flags to \constant{Py_TPFLAGS_DEFAULT}.
+
+\begin{verbatim}
+    Py_TPFLAGS_DEFAULT,        /*tp_flags*/
+\end{verbatim}
+
+All types should include this constant in their flags.  It enables all
+of the members defined by the current version of Python.
+
+We provide a doc string for the type in \member{tp_doc}.
+
+\begin{verbatim}
+    "Noddy objects",           /* tp_doc */
+\end{verbatim}
+
+Now we get into the type methods, the things that make your objects
+different from the others.  We aren't going to implement any of these
+in this version of the module.  We'll expand this example later to
+have more interesting behavior.
+
+For now, all we want to be able to do is to create new \class{Noddy}
+objects. To enable object creation, we have to provide a
+\member{tp_new} implementation. In this case, we can just use the
+default implementation provided by the API function
+\cfunction{PyType_GenericNew()}.  We'd like to just assign this to the
+\member{tp_new} slot, but we can't, for portability sake, On some
+platforms or compilers, we can't statically initialize a structure
+member with a function defined in another C module, so, instead, we'll
+assign the \member{tp_new} slot in the module initialization function
+just before calling \cfunction{PyType_Ready()}:
+
+\begin{verbatim}
+    noddy_NoddyType.tp_new = PyType_GenericNew;
+    if (PyType_Ready(&noddy_NoddyType) < 0)
+        return;
+\end{verbatim}
+
+All the other type methods are \NULL, so we'll go over them later
+--- that's for a later section!
+
+Everything else in the file should be familiar, except for some code
+in \cfunction{initnoddy()}:
+
+\begin{verbatim}
+    if (PyType_Ready(&noddy_NoddyType) < 0)
+        return;
+\end{verbatim}
+
+This initializes the \class{Noddy} type, filing in a number of
+members, including \member{ob_type} that we initially set to \NULL.
+
+\begin{verbatim}
+    PyModule_AddObject(m, "Noddy", (PyObject *)&noddy_NoddyType);
+\end{verbatim}
+
+This adds the type to the module dictionary.  This allows us to create
+\class{Noddy} instances by calling the \class{Noddy} class:
+
+\begin{verbatim}
+>>> import noddy
+>>> mynoddy = noddy.Noddy()
+\end{verbatim}
+
+That's it!  All that remains is to build it; put the above code in a
+file called \file{noddy.c} and
+
+\begin{verbatim}
+from distutils.core import setup, Extension
+setup(name="noddy", version="1.0",
+      ext_modules=[Extension("noddy", ["noddy.c"])])
+\end{verbatim}
+
+in a file called \file{setup.py}; then typing
+
+\begin{verbatim}
+$ python setup.py build
+\end{verbatim} %$ <-- bow to font-lock  ;-(
+
+at a shell should produce a file \file{noddy.so} in a subdirectory;
+move to that directory and fire up Python --- you should be able to
+\code{import noddy} and play around with Noddy objects.
+
+That wasn't so hard, was it?
+
+Of course, the current Noddy type is pretty uninteresting. It has no
+data and doesn't do anything. It can't even be subclassed.
+
+\subsection{Adding data and methods to the Basic example}
+
+Let's expend the basic example to add some data and methods.  Let's
+also make the type usable as a base class. We'll create
+a new module, \module{noddy2} that adds these capabilities:
+
+\verbatiminput{noddy2.c}
+
+This version of the module has a number of changes.
+
+We've added an extra include:
+
+\begin{verbatim}
+#include "structmember.h"
+\end{verbatim}
+
+This include provides declarations that we use to handle attributes,
+as described a bit later.
+
+The name of the \class{Noddy} object structure has been shortened to
+\class{Noddy}.  The type object name has been shortened to
+\class{NoddyType}.
+
+The  \class{Noddy} type now has three data attributes, \var{first},
+\var{last}, and \var{number}.  The \var{first} and \var{last}
+variables are Python strings containing first and last names. The
+\var{number} attribute is an integer.
+
+The object structure is updated accordingly:
+
+\begin{verbatim}
+typedef struct {
+    PyObject_HEAD
+    PyObject *first;
+    PyObject *last;
+    int number;
+} Noddy;
+\end{verbatim}
+
+Because we now have data to manage, we have to be more careful about
+object allocation and deallocation.  At a minimum, we need a
+deallocation method:
+
+\begin{verbatim}
+static void
+Noddy_dealloc(Noddy* self)
+{
+    Py_XDECREF(self->first);
+    Py_XDECREF(self->last);
+    self->ob_type->tp_free((PyObject*)self);
+}
+\end{verbatim}
+
+which is assigned to the \member{tp_dealloc} member:
+
+\begin{verbatim}
+    (destructor)Noddy_dealloc, /*tp_dealloc*/
+\end{verbatim}
+
+This method decrements the reference counts of the two Python
+attributes. We use \cfunction{Py_XDECREF()} here because the
+\member{first} and \member{last} members could be \NULL.  It then
+calls the \member{tp_free} member of the object's type to free the
+object's memory.  Note that the object's type might not be
+\class{NoddyType}, because the object may be an instance of a
+subclass.
+
+We want to make sure that the first and last names are initialized to
+empty strings, so we provide a new method:
+
+\begin{verbatim}
+static PyObject *
+Noddy_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    Noddy *self;
+
+    self = (Noddy *)type->tp_alloc(type, 0);
+    if (self != NULL) {
+        self->first = PyString_FromString("");
+        if (self->first == NULL)
+          {
+            Py_DECREF(self);
+            return NULL;
+          }
+
+        self->last = PyString_FromString("");
+        if (self->last == NULL)
+          {
+            Py_DECREF(self);
+            return NULL;
+          }
+
+        self->number = 0;
+    }
+
+    return (PyObject *)self;
+}
+\end{verbatim}
+
+and install it in the \member{tp_new} member:
+
+\begin{verbatim}
+    Noddy_new,                 /* tp_new */
+\end{verbatim}
+
+The new member is responsible for creating (as opposed to
+initializing) objects of the type.  It is exposed in Python as the
+\method{__new__()} method.  See the paper titled ``Unifying types and
+classes in Python'' for a detailed discussion of the \method{__new__()}
+method.  One reason to implement a new method is to assure the initial
+values of instance variables.  In this case, we use the new method to
+make sure that the initial values of the members \member{first} and
+\member{last} are not \NULL. If we didn't care whether the initial
+values were \NULL, we could have used \cfunction{PyType_GenericNew()} as
+our new method, as we did before.  \cfunction{PyType_GenericNew()}
+initializes all of the instance variable members to \NULL.
+
+The new method is a static method that is passed the type being
+instantiated and any arguments passed when the type was called,
+and that returns the new object created. New methods always accept
+positional and keyword arguments, but they often ignore the arguments,
+leaving the argument handling to initializer methods. Note that if the
+type supports subclassing, the type passed may not be the type being
+defined.  The new method calls the tp_alloc slot to allocate memory.
+We don't fill the \member{tp_alloc} slot ourselves. Rather
+\cfunction{PyType_Ready()} fills it for us by inheriting it from our
+base class, which is \class{object} by default.  Most types use the
+default allocation.
+
+\note{If you are creating a co-operative \member{tp_new} (one that
+calls a base type's \member{tp_new} or \method{__new__}), you
+must \emph{not} try to determine what method to call using
+method resolution order at runtime.  Always statically determine
+what type you are going to call, and call its \member{tp_new}
+directly, or via \code{type->tp_base->tp_new}.  If you do
+not do this, Python subclasses of your type that also inherit
+from other Python-defined classes may not work correctly.
+(Specifically, you may not be able to create instances of
+such subclasses without getting a \exception{TypeError}.)}
+
+We provide an initialization function:
+
+\begin{verbatim}
+static int
+Noddy_init(Noddy *self, PyObject *args, PyObject *kwds)
+{
+    PyObject *first=NULL, *last=NULL, *tmp;
+
+    static char *kwlist[] = {"first", "last", "number", NULL};
+
+    if (! PyArg_ParseTupleAndKeywords(args, kwds, "|OOi", kwlist,
+                                      &first, &last,
+                                      &self->number))
+        return -1;
+
+    if (first) {
+        tmp = self->first;
+        Py_INCREF(first);
+        self->first = first;
+        Py_XDECREF(tmp);
+    }
+
+    if (last) {
+        tmp = self->last;
+        Py_INCREF(last);
+        self->last = last;
+        Py_XDECREF(tmp);
+    }
+
+    return 0;
+}
+\end{verbatim}
+
+by filling the \member{tp_init} slot.
+
+\begin{verbatim}
+    (initproc)Noddy_init,         /* tp_init */
+\end{verbatim}
+
+The \member{tp_init} slot is exposed in Python as the
+\method{__init__()} method. It is used to initialize an object after
+it's created. Unlike the new method, we can't guarantee that the
+initializer is called.  The initializer isn't called when unpickling
+objects and it can be overridden.  Our initializer accepts arguments
+to provide initial values for our instance. Initializers always accept
+positional and keyword arguments.
+
+Initializers can be called multiple times.  Anyone can call the
+\method{__init__()} method on our objects.  For this reason, we have
+to be extra careful when assigning the new values.  We might be
+tempted, for example to assign the \member{first} member like this:
+
+\begin{verbatim}
+    if (first) {
+        Py_XDECREF(self->first);
+        Py_INCREF(first);
+        self->first = first;
+    }
+\end{verbatim}
+
+But this would be risky.  Our type doesn't restrict the type of the
+\member{first} member, so it could be any kind of object.  It could
+have a destructor that causes code to be executed that tries to
+access the \member{first} member.  To be paranoid and protect
+ourselves against this possibility, we almost always reassign members
+before decrementing their reference counts.  When don't we have to do
+this?
+\begin{itemize}
+\item when we absolutely know that the reference count is greater than
+  1
+\item when we know that deallocation of the object\footnote{This is
+  true when we know that the object is a basic type, like a string or
+  a float.} will not cause any
+  calls back into our type's code
+\item when decrementing a reference count in a \member{tp_dealloc}
+  handler when garbage-collections is not supported\footnote{We relied
+  on this in the \member{tp_dealloc} handler in this example, because
+  our type doesn't support garbage collection. Even if a type supports
+  garbage collection, there are calls that can be made to ``untrack''
+  the object from garbage collection, however, these calls are
+  advanced and not covered here.}
+\end{itemize}
+
+
+We want to want to expose our instance variables as attributes. There
+are a number of ways to do that. The simplest way is to define member
+definitions:
+
+\begin{verbatim}
+static PyMemberDef Noddy_members[] = {
+    {"first", T_OBJECT_EX, offsetof(Noddy, first), 0,
+     "first name"},
+    {"last", T_OBJECT_EX, offsetof(Noddy, last), 0,
+     "last name"},
+    {"number", T_INT, offsetof(Noddy, number), 0,
+     "noddy number"},
+    {NULL}  /* Sentinel */
+};
+\end{verbatim}
+
+and put the definitions in the \member{tp_members} slot:
+
+\begin{verbatim}
+    Noddy_members,             /* tp_members */
+\end{verbatim}
+
+Each member definition has a member name, type, offset, access flags
+and documentation string. See the ``Generic Attribute Management''
+section below for details.
+
+A disadvantage of this approach is that it doesn't provide a way to
+restrict the types of objects that can be assigned to the Python
+attributes.  We expect the first and last names to be strings, but any
+Python objects can be assigned.  Further, the attributes can be
+deleted, setting the C pointers to \NULL.  Even though we can make
+sure the members are initialized to non-\NULL{} values, the members can
+be set to \NULL{} if the attributes are deleted.
+
+We define a single method, \method{name}, that outputs the objects
+name as the concatenation of the first and last names.
+
+\begin{verbatim}
+static PyObject *
+Noddy_name(Noddy* self)
+{
+    static PyObject *format = NULL;
+    PyObject *args, *result;
+
+    if (format == NULL) {
+        format = PyString_FromString("%s %s");
+        if (format == NULL)
+            return NULL;
+    }
+
+    if (self->first == NULL) {
+        PyErr_SetString(PyExc_AttributeError, "first");
+        return NULL;
+    }
+
+    if (self->last == NULL) {
+        PyErr_SetString(PyExc_AttributeError, "last");
+        return NULL;
+    }
+
+    args = Py_BuildValue("OO", self->first, self->last);
+    if (args == NULL)
+        return NULL;
+
+    result = PyString_Format(format, args);
+    Py_DECREF(args);
+
+    return result;
+}
+\end{verbatim}
+
+The method is implemented as a C function that takes a \class{Noddy} (or
+\class{Noddy} subclass) instance as the first argument.  Methods
+always take an instance as the first argument. Methods often take
+positional and keyword arguments as well, but in this cased we don't
+take any and don't need to accept a positional argument tuple or
+keyword argument dictionary. This method is equivalent to the Python
+method:
+
+\begin{verbatim}
+    def name(self):
+       return "%s %s" % (self.first, self.last)
+\end{verbatim}
+
+Note that we have to check for the possibility that our \member{first}
+and \member{last} members are \NULL.  This is because they can be
+deleted, in which case they are set to \NULL.  It would be better to
+prevent deletion of these attributes and to restrict the attribute
+values to be strings.  We'll see how to do that in the next section.
+
+Now that we've defined the method, we need to create an array of
+method definitions:
+
+\begin{verbatim}
+static PyMethodDef Noddy_methods[] = {
+    {"name", (PyCFunction)Noddy_name, METH_NOARGS,
+     "Return the name, combining the first and last name"
+    },
+    {NULL}  /* Sentinel */
+};
+\end{verbatim}
+
+and assign them to the \member{tp_methods} slot:
+
+\begin{verbatim}
+    Noddy_methods,             /* tp_methods */
+\end{verbatim}
+
+Note that we used the \constant{METH_NOARGS} flag to indicate that the
+method is passed no arguments.
+
+Finally, we'll make our type usable as a base class.  We've written
+our methods carefully so far so that they don't make any assumptions
+about the type of the object being created or used, so all we need to
+do is to add the \constant{Py_TPFLAGS_BASETYPE} to our class flag
+definition:
+
+\begin{verbatim}
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+\end{verbatim}
+
+We rename \cfunction{initnoddy()} to \cfunction{initnoddy2()}
+and update the module name passed to \cfunction{Py_InitModule3()}.
+
+Finally, we update our \file{setup.py} file to build the new module:
+
+\begin{verbatim}
+from distutils.core import setup, Extension
+setup(name="noddy", version="1.0",
+      ext_modules=[
+         Extension("noddy", ["noddy.c"]),
+         Extension("noddy2", ["noddy2.c"]),
+         ])
+\end{verbatim}
+
+\subsection{Providing finer control over data attributes}
+
+In this section, we'll provide finer control over how the
+\member{first} and \member{last} attributes are set in the
+\class{Noddy} example. In the previous version of our module, the
+instance variables \member{first} and \member{last} could be set to
+non-string values or even deleted. We want to make sure that these
+attributes always contain strings.
+
+\verbatiminput{noddy3.c}
+
+To provide greater control, over the \member{first} and \member{last}
+attributes, we'll use custom getter and setter functions.  Here are
+the functions for getting and setting the \member{first} attribute:
+
+\begin{verbatim}
+Noddy_getfirst(Noddy *self, void *closure)
+{
+    Py_INCREF(self->first);
+    return self->first;
+}
+
+static int
+Noddy_setfirst(Noddy *self, PyObject *value, void *closure)
+{
+  if (value == NULL) {
+    PyErr_SetString(PyExc_TypeError, "Cannot delete the first attribute");
+    return -1;
+  }
+
+  if (! PyString_Check(value)) {
+    PyErr_SetString(PyExc_TypeError,
+                    "The first attribute value must be a string");
+    return -1;
+  }
+
+  Py_DECREF(self->first);
+  Py_INCREF(value);
+  self->first = value;
+
+  return 0;
+}
+\end{verbatim}
+
+The getter function is passed a \class{Noddy} object and a
+``closure'', which is void pointer. In this case, the closure is
+ignored. (The closure supports an advanced usage in which definition
+data is passed to the getter and setter. This could, for example, be
+used to allow a single set of getter and setter functions that decide
+the attribute to get or set based on data in the closure.)
+
+The setter function is passed the \class{Noddy} object, the new value,
+and the closure. The new value may be \NULL, in which case the
+attribute is being deleted.  In our setter, we raise an error if the
+attribute is deleted or if the attribute value is not a string.
+
+We create an array of \ctype{PyGetSetDef} structures:
+
+\begin{verbatim}
+static PyGetSetDef Noddy_getseters[] = {
+    {"first",
+     (getter)Noddy_getfirst, (setter)Noddy_setfirst,
+     "first name",
+     NULL},
+    {"last",
+     (getter)Noddy_getlast, (setter)Noddy_setlast,
+     "last name",
+     NULL},
+    {NULL}  /* Sentinel */
+};
+\end{verbatim}
+
+and register it in the \member{tp_getset} slot:
+
+\begin{verbatim}
+    Noddy_getseters,           /* tp_getset */
+\end{verbatim}
+
+to register out attribute getters and setters.
+
+The last item in a \ctype{PyGetSetDef} structure is the closure
+mentioned above. In this case, we aren't using the closure, so we just
+pass \NULL.
+
+We also remove the member definitions for these attributes:
+
+\begin{verbatim}
+static PyMemberDef Noddy_members[] = {
+    {"number", T_INT, offsetof(Noddy, number), 0,
+     "noddy number"},
+    {NULL}  /* Sentinel */
+};
+\end{verbatim}
+
+We also need to update the \member{tp_init} handler to only allow
+strings\footnote{We now know that the first and last members are strings,
+so perhaps we could be less careful about decrementing their
+reference counts, however, we accept instances of string subclasses.
+Even though deallocating normal strings won't call back into our
+objects, we can't guarantee that deallocating an instance of a string
+subclass won't. call back into out objects.} to be passed:
+
+\begin{verbatim}
+static int
+Noddy_init(Noddy *self, PyObject *args, PyObject *kwds)
+{
+    PyObject *first=NULL, *last=NULL, *tmp;
+
+    static char *kwlist[] = {"first", "last", "number", NULL};
+
+    if (! PyArg_ParseTupleAndKeywords(args, kwds, "|SSi", kwlist,
+                                      &first, &last,
+                                      &self->number))
+        return -1;
+
+    if (first) {
+        tmp = self->first;
+        Py_INCREF(first);
+        self->first = first;
+        Py_DECREF(tmp);
+    }
+
+    if (last) {
+        tmp = self->last;
+        Py_INCREF(last);
+        self->last = last;
+        Py_DECREF(tmp);
+    }
+
+    return 0;
+}
+\end{verbatim}
+
+With these changes, we can assure that the \member{first} and
+\member{last} members are never \NULL{} so we can remove checks for \NULL{}
+values in almost all cases. This means that most of the
+\cfunction{Py_XDECREF()} calls can be converted to \cfunction{Py_DECREF()}
+calls. The only place we can't change these calls is in the
+deallocator, where there is the possibility that the initialization of
+these members failed in the constructor.
+
+We also rename the module initialization function and module name in
+the initialization function, as we did before, and we add an extra
+definition to the \file{setup.py} file.
+
+\subsection{Supporting cyclic garbage collection}
+
+Python has a cyclic-garbage collector that can identify unneeded
+objects even when their reference counts are not zero. This can happen
+when objects are involved in cycles.  For example, consider:
+
+\begin{verbatim}
+>>> l = []
+>>> l.append(l)
+>>> del l
+\end{verbatim}
+
+In this example, we create a list that contains itself. When we delete
+it, it still has a reference from itself. Its reference count doesn't
+drop to zero.  Fortunately, Python's cyclic-garbage collector will
+eventually figure out that the list is garbage and free it.
+
+In the second version of the \class{Noddy} example, we allowed any
+kind of object to be stored in the \member{first} or \member{last}
+attributes.\footnote{Even in the third version, we aren't guaranteed to
+avoid cycles.  Instances of string subclasses are allowed and string
+subclasses could allow cycles even if normal strings don't.} This
+means that \class{Noddy} objects can participate in cycles:
+
+\begin{verbatim}
+>>> import noddy2
+>>> n = noddy2.Noddy()
+>>> l = [n]
+>>> n.first = l
+\end{verbatim}
+
+This is pretty silly, but it gives us an excuse to add support for the
+cyclic-garbage collector to the \class{Noddy} example.  To support
+cyclic garbage collection, types need to fill two slots and set a
+class flag that enables these slots:
+
+\verbatiminput{noddy4.c}
+
+The traversal method provides access to subobjects that
+could participate in cycles:
+
+\begin{verbatim}
+static int
+Noddy_traverse(Noddy *self, visitproc visit, void *arg)
+{
+    int vret;
+
+    if (self->first) {
+        vret = visit(self->first, arg);
+        if (vret != 0)
+            return vret;
+    }
+    if (self->last) {
+        vret = visit(self->last, arg);
+        if (vret != 0)
+            return vret;
+    }
+
+    return 0;
+}
+\end{verbatim}
+
+For each subobject that can participate in cycles, we need to call the
+\cfunction{visit()} function, which is passed to the traversal method.
+The \cfunction{visit()} function takes as arguments the subobject and
+the extra argument \var{arg} passed to the traversal method.  It
+returns an integer value that must be returned if it is non-zero.
+
+
+Python 2.4 and higher provide a \cfunction{Py_VISIT()} macro that automates
+calling visit functions.  With \cfunction{Py_VISIT()},
+\cfunction{Noddy_traverse()} can be simplified:
+
+
+\begin{verbatim}
+static int
+Noddy_traverse(Noddy *self, visitproc visit, void *arg)
+{
+    Py_VISIT(self->first);
+    Py_VISIT(self->last);
+    return 0;
+}
+\end{verbatim}
+
+\note{Note that the \member{tp_traverse} implementation must name its
+    arguments exactly \var{visit} and \var{arg} in order to use
+    \cfunction{Py_VISIT()}.  This is to encourage uniformity
+    across these boring implementations.}
+
+We also need to provide a method for clearing any subobjects that can
+participate in cycles.  We implement the method and reimplement the
+deallocator to use it:
+
+\begin{verbatim}
+static int
+Noddy_clear(Noddy *self)
+{
+    PyObject *tmp;
+
+    tmp = self->first;
+    self->first = NULL;
+    Py_XDECREF(tmp);
+
+    tmp = self->last;
+    self->last = NULL;
+    Py_XDECREF(tmp);
+
+    return 0;
+}
+
+static void
+Noddy_dealloc(Noddy* self)
+{
+    Noddy_clear(self);
+    self->ob_type->tp_free((PyObject*)self);
+}
+\end{verbatim}
+
+Notice the use of a temporary variable in \cfunction{Noddy_clear()}.
+We use the temporary variable so that we can set each member to \NULL{}
+before decrementing its reference count.  We do this because, as was
+discussed earlier, if the reference count drops to zero, we might
+cause code to run that calls back into the object.  In addition,
+because we now support garbage collection, we also have to worry about
+code being run that triggers garbage collection.  If garbage
+collection is run, our \member{tp_traverse} handler could get called.
+We can't take a chance of having \cfunction{Noddy_traverse()} called
+when a member's reference count has dropped to zero and its value
+hasn't been set to \NULL.
+
+Python 2.4 and higher provide a \cfunction{Py_CLEAR()} that automates
+the careful decrementing of reference counts.  With
+\cfunction{Py_CLEAR()}, the \cfunction{Noddy_clear()} function can be
+simplified:
+
+\begin{verbatim}
+static int
+Noddy_clear(Noddy *self)
+{
+    Py_CLEAR(self->first);
+    Py_CLEAR(self->last);
+    return 0;
+}
+\end{verbatim}
+
+Finally, we add the \constant{Py_TPFLAGS_HAVE_GC} flag to the class
+flags:
+
+\begin{verbatim}
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+\end{verbatim}
+
+That's pretty much it.  If we had written custom \member{tp_alloc} or
+\member{tp_free} slots, we'd need to modify them for cyclic-garbage
+collection. Most extensions will use the versions automatically
+provided.
+
+\subsection{Subclassing other types}
+
+It is possible to create new extension types that are derived from existing
+types. It is easiest to inherit from the built in types, since an extension
+can easily use the \class{PyTypeObject} it needs. It can be difficult to
+share these \class{PyTypeObject} structures between extension modules.
+
+In this example we will create a \class{Shoddy} type that inherits from
+the builtin \class{list} type. The new type will be completely compatible
+with regular lists, but will have an additional \method{increment()} method
+that increases an internal counter.
+
+\begin{verbatim}
+>>> import shoddy
+>>> s = shoddy.Shoddy(range(3))
+>>> s.extend(s)
+>>> print len(s)
+6
+>>> print s.increment()
+1
+>>> print s.increment()
+2
+\end{verbatim}
+
+\verbatiminput{shoddy.c}
+
+As you can see, the source code closely resembles the \class{Noddy} examples in previous
+sections. We will break down the main differences between them.
+
+\begin{verbatim}
+typedef struct {
+	PyListObject list;
+	int state;
+} Shoddy;
+\end{verbatim}
+
+The primary difference for derived type objects is that the base type's
+object structure must be the first value. The base type will already
+include the \cfunction{PyObject_HEAD} at the beginning of its structure.
+
+When a Python object is a \class{Shoddy} instance, its \var{PyObject*} pointer
+can be safely cast to both \var{PyListObject*} and \var{Shoddy*}.
+
+\begin{verbatim}
+static int
+Shoddy_init(Shoddy *self, PyObject *args, PyObject *kwds)
+{
+	if (PyList_Type.tp_init((PyObject *)self, args, kwds) < 0)
+		return -1;
+	self->state = 0;
+	return 0;
+}
+\end{verbatim}
+
+In the \member{__init__} method for our type, we can see how to call through
+to the \member{__init__} method of the base type.
+
+This pattern is important when writing a type with custom \member{new} and
+\member{dealloc} methods. The \member{new} method should not actually create the
+memory for the object with \member{tp_alloc}, that will be handled by
+the base class when calling its \member{tp_new}.
+
+When filling out the \cfunction{PyTypeObject} for the \class{Shoddy} type,
+you see a slot for \cfunction{tp_base}. Due to cross platform compiler
+issues, you can't fill that field directly with the \cfunction{PyList_Type};
+it can be done later in the module's \cfunction{init} function.
+
+\begin{verbatim}
+PyMODINIT_FUNC
+initshoddy(void)
+{
+	PyObject *m;
+
+	ShoddyType.tp_base = &PyList_Type;
+	if (PyType_Ready(&ShoddyType) < 0)
+		return;
+
+	m = Py_InitModule3("shoddy", NULL, "Shoddy module");
+	if (m == NULL)
+		return;
+
+	Py_INCREF(&ShoddyType);
+	PyModule_AddObject(m, "Shoddy", (PyObject *) &ShoddyType);
+}
+\end{verbatim}
+
+Before calling \cfunction{PyType_Ready}, the type structure must have the
+\member{tp_base} slot filled in. When we are deriving a new type, it is
+not necessary to fill out the \member{tp_alloc} slot with
+\cfunction{PyType_GenericNew} -- the allocate function from the base type
+will be inherited.
+
+After that, calling \cfunction{PyType_Ready} and adding the type object
+to the module is the same as with the basic \class{Noddy} examples.
+
+
+\section{Type Methods
+         \label{dnt-type-methods}}
+
+This section aims to give a quick fly-by on the various type methods
+you can implement and what they do.
+
+Here is the definition of \ctype{PyTypeObject}, with some fields only
+used in debug builds omitted:
+
+\verbatiminput{typestruct.h}
+
+Now that's a \emph{lot} of methods.  Don't worry too much though - if
+you have a type you want to define, the chances are very good that you
+will only implement a handful of these.
+
+As you probably expect by now, we're going to go over this and give
+more information about the various handlers.  We won't go in the order
+they are defined in the structure, because there is a lot of
+historical baggage that impacts the ordering of the fields; be sure
+your type initialization keeps the fields in the right order!  It's
+often easiest to find an example that includes all the fields you need
+(even if they're initialized to \code{0}) and then change the values
+to suit your new type.
+
+\begin{verbatim}
+    char *tp_name; /* For printing */
+\end{verbatim}
+
+The name of the type - as mentioned in the last section, this will
+appear in various places, almost entirely for diagnostic purposes.
+Try to choose something that will be helpful in such a situation!
+
+\begin{verbatim}
+    int tp_basicsize, tp_itemsize; /* For allocation */
+\end{verbatim}
+
+These fields tell the runtime how much memory to allocate when new
+objects of this type are created.  Python has some built-in support
+for variable length structures (think: strings, lists) which is where
+the \member{tp_itemsize} field comes in.  This will be dealt with
+later.
+
+\begin{verbatim}
+    char *tp_doc;
+\end{verbatim}
+
+Here you can put a string (or its address) that you want returned when
+the Python script references \code{obj.__doc__} to retrieve the
+doc string.
+
+Now we come to the basic type methods---the ones most extension types
+will implement.
+
+
+\subsection{Finalization and De-allocation}
+
+\index{object!deallocation}
+\index{deallocation, object}
+\index{object!finalization}
+\index{finalization, of objects}
+
+\begin{verbatim}
+    destructor tp_dealloc;
+\end{verbatim}
+
+This function is called when the reference count of the instance of
+your type is reduced to zero and the Python interpreter wants to
+reclaim it.  If your type has memory to free or other clean-up to
+perform, put it here.  The object itself needs to be freed here as
+well.  Here is an example of this function:
+
+\begin{verbatim}
+static void
+newdatatype_dealloc(newdatatypeobject * obj)
+{
+    free(obj->obj_UnderlyingDatatypePtr);
+    obj->ob_type->tp_free(obj);
+}
+\end{verbatim}
+
+One important requirement of the deallocator function is that it
+leaves any pending exceptions alone.  This is important since
+deallocators are frequently called as the interpreter unwinds the
+Python stack; when the stack is unwound due to an exception (rather
+than normal returns), nothing is done to protect the deallocators from
+seeing that an exception has already been set.  Any actions which a
+deallocator performs which may cause additional Python code to be
+executed may detect that an exception has been set.  This can lead to
+misleading errors from the interpreter.  The proper way to protect
+against this is to save a pending exception before performing the
+unsafe action, and restoring it when done.  This can be done using the
+\cfunction{PyErr_Fetch()}\ttindex{PyErr_Fetch()} and
+\cfunction{PyErr_Restore()}\ttindex{PyErr_Restore()} functions:
+
+\begin{verbatim}
+static void
+my_dealloc(PyObject *obj)
+{
+    MyObject *self = (MyObject *) obj;
+    PyObject *cbresult;
+
+    if (self->my_callback != NULL) {
+        PyObject *err_type, *err_value, *err_traceback;
+        int have_error = PyErr_Occurred() ? 1 : 0;
+
+        if (have_error)
+            PyErr_Fetch(&err_type, &err_value, &err_traceback);
+
+        cbresult = PyObject_CallObject(self->my_callback, NULL);
+        if (cbresult == NULL)
+            PyErr_WriteUnraisable(self->my_callback);
+        else
+            Py_DECREF(cbresult);
+
+        if (have_error)
+            PyErr_Restore(err_type, err_value, err_traceback);
+
+        Py_DECREF(self->my_callback);
+    }
+    obj->ob_type->tp_free((PyObject*)self);
+}
+\end{verbatim}
+
+
+\subsection{Object Presentation}
+
+In Python, there are three ways to generate a textual representation
+of an object: the \function{repr()}\bifuncindex{repr} function (or
+equivalent back-tick syntax), the \function{str()}\bifuncindex{str}
+function, and the \keyword{print} statement.  For most objects, the
+\keyword{print} statement is equivalent to the \function{str()}
+function, but it is possible to special-case printing to a
+\ctype{FILE*} if necessary; this should only be done if efficiency is
+identified as a problem and profiling suggests that creating a
+temporary string object to be written to a file is too expensive.
+
+These handlers are all optional, and most types at most need to
+implement the \member{tp_str} and \member{tp_repr} handlers.
+
+\begin{verbatim}
+    reprfunc tp_repr;
+    reprfunc tp_str;
+    printfunc tp_print;
+\end{verbatim}
+
+The \member{tp_repr} handler should return a string object containing
+a representation of the instance for which it is called.  Here is a
+simple example:
+
+\begin{verbatim}
+static PyObject *
+newdatatype_repr(newdatatypeobject * obj)
+{
+    return PyString_FromFormat("Repr-ified_newdatatype{{size:\%d}}",
+                               obj->obj_UnderlyingDatatypePtr->size);
+}
+\end{verbatim}
+
+If no \member{tp_repr} handler is specified, the interpreter will
+supply a representation that uses the type's \member{tp_name} and a
+uniquely-identifying value for the object.
+
+The \member{tp_str} handler is to \function{str()} what the
+\member{tp_repr} handler described above is to \function{repr()}; that
+is, it is called when Python code calls \function{str()} on an
+instance of your object.  Its implementation is very similar to the
+\member{tp_repr} function, but the resulting string is intended for
+human consumption.  If \member{tp_str} is not specified, the
+\member{tp_repr} handler is used instead.
+
+Here is a simple example:
+
+\begin{verbatim}
+static PyObject *
+newdatatype_str(newdatatypeobject * obj)
+{
+    return PyString_FromFormat("Stringified_newdatatype{{size:\%d}}",
+                               obj->obj_UnderlyingDatatypePtr->size);
+}
+\end{verbatim}
+
+The print function will be called whenever Python needs to "print" an
+instance of the type.  For example, if 'node' is an instance of type
+TreeNode, then the print function is called when Python code calls:
+
+\begin{verbatim}
+print node
+\end{verbatim}
+
+There is a flags argument and one flag, \constant{Py_PRINT_RAW}, and
+it suggests that you print without string quotes and possibly without
+interpreting escape sequences.
+
+The print function receives a file object as an argument. You will
+likely want to write to that file object.
+
+Here is a sample print function:
+
+\begin{verbatim}
+static int
+newdatatype_print(newdatatypeobject *obj, FILE *fp, int flags)
+{
+    if (flags & Py_PRINT_RAW) {
+        fprintf(fp, "<{newdatatype object--size: %d}>",
+                obj->obj_UnderlyingDatatypePtr->size);
+    }
+    else {
+        fprintf(fp, "\"<{newdatatype object--size: %d}>\"",
+                obj->obj_UnderlyingDatatypePtr->size);
+    }
+    return 0;
+}
+\end{verbatim}
+
+
+\subsection{Attribute Management}
+
+For every object which can support attributes, the corresponding type
+must provide the functions that control how the attributes are
+resolved.  There needs to be a function which can retrieve attributes
+(if any are defined), and another to set attributes (if setting
+attributes is allowed).  Removing an attribute is a special case, for
+which the new value passed to the handler is \NULL.
+
+Python supports two pairs of attribute handlers; a type that supports
+attributes only needs to implement the functions for one pair.  The
+difference is that one pair takes the name of the attribute as a
+\ctype{char*}, while the other accepts a \ctype{PyObject*}.  Each type
+can use whichever pair makes more sense for the implementation's
+convenience.
+
+\begin{verbatim}
+    getattrfunc  tp_getattr;        /* char * version */
+    setattrfunc  tp_setattr;
+    /* ... */
+    getattrofunc tp_getattrofunc;   /* PyObject * version */
+    setattrofunc tp_setattrofunc;
+\end{verbatim}
+
+If accessing attributes of an object is always a simple operation
+(this will be explained shortly), there are generic implementations
+which can be used to provide the \ctype{PyObject*} version of the
+attribute management functions.  The actual need for type-specific
+attribute handlers almost completely disappeared starting with Python
+2.2, though there are many examples which have not been updated to use
+some of the new generic mechanism that is available.
+
+
+\subsubsection{Generic Attribute Management}
+
+\versionadded{2.2}
+
+Most extension types only use \emph{simple} attributes.  So, what
+makes the attributes simple?  There are only a couple of conditions
+that must be met:
+
+\begin{enumerate}
+  \item   The name of the attributes must be known when
+          \cfunction{PyType_Ready()} is called.
+
+  \item   No special processing is needed to record that an attribute
+          was looked up or set, nor do actions need to be taken based
+          on the value.
+\end{enumerate}
+
+Note that this list does not place any restrictions on the values of
+the attributes, when the values are computed, or how relevant data is
+stored.
+
+When \cfunction{PyType_Ready()} is called, it uses three tables
+referenced by the type object to create \emph{descriptors} which are
+placed in the dictionary of the type object.  Each descriptor controls
+access to one attribute of the instance object.  Each of the tables is
+optional; if all three are \NULL, instances of the type will only have
+attributes that are inherited from their base type, and should leave
+the \member{tp_getattro} and \member{tp_setattro} fields \NULL{} as
+well, allowing the base type to handle attributes.
+
+The tables are declared as three fields of the type object:
+
+\begin{verbatim}
+    struct PyMethodDef *tp_methods;
+    struct PyMemberDef *tp_members;
+    struct PyGetSetDef *tp_getset;
+\end{verbatim}
+
+If \member{tp_methods} is not \NULL, it must refer to an array of
+\ctype{PyMethodDef} structures.  Each entry in the table is an
+instance of this structure:
+
+\begin{verbatim}
+typedef struct PyMethodDef {
+    char        *ml_name;       /* method name */
+    PyCFunction  ml_meth;       /* implementation function */
+    int	         ml_flags;      /* flags */
+    char        *ml_doc;        /* docstring */
+} PyMethodDef;
+\end{verbatim}
+
+One entry should be defined for each method provided by the type; no
+entries are needed for methods inherited from a base type.  One
+additional entry is needed at the end; it is a sentinel that marks the
+end of the array.  The \member{ml_name} field of the sentinel must be
+\NULL.
+
+XXX Need to refer to some unified discussion of the structure fields,
+shared with the next section.
+
+The second table is used to define attributes which map directly to
+data stored in the instance.  A variety of primitive C types are
+supported, and access may be read-only or read-write.  The structures
+in the table are defined as:
+
+\begin{verbatim}
+typedef struct PyMemberDef {
+    char *name;
+    int   type;
+    int   offset;
+    int   flags;
+    char *doc;
+} PyMemberDef;
+\end{verbatim}
+
+For each entry in the table, a descriptor will be constructed and
+added to the type which will be able to extract a value from the
+instance structure.  The \member{type} field should contain one of the
+type codes defined in the \file{structmember.h} header; the value will
+be used to determine how to convert Python values to and from C
+values.  The \member{flags} field is used to store flags which control
+how the attribute can be accessed.
+
+XXX Need to move some of this to a shared section!
+
+The following flag constants are defined in \file{structmember.h};
+they may be combined using bitwise-OR.
+
+\begin{tableii}{l|l}{constant}{Constant}{Meaning}
+  \lineii{READONLY \ttindex{READONLY}}
+         {Never writable.}
+  \lineii{RO \ttindex{RO}}
+         {Shorthand for \constant{READONLY}.}
+  \lineii{READ_RESTRICTED \ttindex{READ_RESTRICTED}}
+         {Not readable in restricted mode.}
+  \lineii{WRITE_RESTRICTED \ttindex{WRITE_RESTRICTED}}
+         {Not writable in restricted mode.}
+  \lineii{RESTRICTED \ttindex{RESTRICTED}}
+         {Not readable or writable in restricted mode.}
+\end{tableii}
+
+An interesting advantage of using the \member{tp_members} table to
+build descriptors that are used at runtime is that any attribute
+defined this way can have an associated doc string simply by providing
+the text in the table.  An application can use the introspection API
+to retrieve the descriptor from the class object, and get the
+doc string using its \member{__doc__} attribute.
+
+As with the \member{tp_methods} table, a sentinel entry with a
+\member{name} value of \NULL{} is required.
+
+
+% XXX Descriptors need to be explained in more detail somewhere, but
+% not here.
+%
+% Descriptor objects have two handler functions which correspond to
+% the \member{tp_getattro} and \member{tp_setattro} handlers.  The
+% \method{__get__()} handler is a function which is passed the
+% descriptor, instance, and type objects, and returns the value of the
+% attribute, or it returns \NULL{} and sets an exception.  The
+% \method{__set__()} handler is passed the descriptor, instance, type,
+% and new value;
+
+
+\subsubsection{Type-specific Attribute Management}
+
+For simplicity, only the \ctype{char*} version will be demonstrated
+here; the type of the name parameter is the only difference between
+the \ctype{char*} and \ctype{PyObject*} flavors of the interface.
+This example effectively does the same thing as the generic example
+above, but does not use the generic support added in Python 2.2.  The
+value in showing this is two-fold: it demonstrates how basic attribute
+management can be done in a way that is portable to older versions of
+Python, and explains how the handler functions are called, so that if
+you do need to extend their functionality, you'll understand what
+needs to be done.
+
+The \member{tp_getattr} handler is called when the object requires an
+attribute look-up.  It is called in the same situations where the
+\method{__getattr__()} method of a class would be called.
+
+A likely way to handle this is (1) to implement a set of functions
+(such as \cfunction{newdatatype_getSize()} and
+\cfunction{newdatatype_setSize()} in the example below), (2) provide a
+method table listing these functions, and (3) provide a getattr
+function that returns the result of a lookup in that table.  The
+method table uses the same structure as the \member{tp_methods} field
+of the type object.
+
+Here is an example:
+
+\begin{verbatim}
+static PyMethodDef newdatatype_methods[] = {
+    {"getSize", (PyCFunction)newdatatype_getSize, METH_VARARGS,
+     "Return the current size."},
+    {"setSize", (PyCFunction)newdatatype_setSize, METH_VARARGS,
+     "Set the size."},
+    {NULL, NULL, 0, NULL}           /* sentinel */
+};
+
+static PyObject *
+newdatatype_getattr(newdatatypeobject *obj, char *name)
+{
+    return Py_FindMethod(newdatatype_methods, (PyObject *)obj, name);
+}
+\end{verbatim}
+
+The \member{tp_setattr} handler is called when the
+\method{__setattr__()} or \method{__delattr__()} method of a class
+instance would be called.  When an attribute should be deleted, the
+third parameter will be \NULL.  Here is an example that simply raises
+an exception; if this were really all you wanted, the
+\member{tp_setattr} handler should be set to \NULL.
+
+\begin{verbatim}
+static int
+newdatatype_setattr(newdatatypeobject *obj, char *name, PyObject *v)
+{
+    (void)PyErr_Format(PyExc_RuntimeError, "Read-only attribute: \%s", name);
+    return -1;
+}
+\end{verbatim}
+
+
+\subsection{Object Comparison}
+
+\begin{verbatim}
+    cmpfunc tp_compare;
+\end{verbatim}
+
+The \member{tp_compare} handler is called when comparisons are needed
+and the object does not implement the specific rich comparison method
+which matches the requested comparison.  (It is always used if defined
+and the \cfunction{PyObject_Compare()} or \cfunction{PyObject_Cmp()}
+functions are used, or if \function{cmp()} is used from Python.)
+It is analogous to the \method{__cmp__()} method.  This function
+should return \code{-1} if \var{obj1} is less than
+\var{obj2}, \code{0} if they are equal, and \code{1} if
+\var{obj1} is greater than
+\var{obj2}.
+(It was previously allowed to return arbitrary negative or positive
+integers for less than and greater than, respectively; as of Python
+2.2, this is no longer allowed.  In the future, other return values
+may be assigned a different meaning.)
+
+A \member{tp_compare} handler may raise an exception.  In this case it
+should return a negative value.  The caller has to test for the
+exception using \cfunction{PyErr_Occurred()}.
+
+
+Here is a sample implementation:
+
+\begin{verbatim}
+static int
+newdatatype_compare(newdatatypeobject * obj1, newdatatypeobject * obj2)
+{
+    long result;
+
+    if (obj1->obj_UnderlyingDatatypePtr->size <
+        obj2->obj_UnderlyingDatatypePtr->size) {
+        result = -1;
+    }
+    else if (obj1->obj_UnderlyingDatatypePtr->size >
+             obj2->obj_UnderlyingDatatypePtr->size) {
+        result = 1;
+    }
+    else {
+        result = 0;
+    }
+    return result;
+}
+\end{verbatim}
+
+
+\subsection{Abstract Protocol Support}
+
+Python supports a variety of \emph{abstract} `protocols;' the specific
+interfaces provided to use these interfaces are documented in the
+\citetitle[../api/api.html]{Python/C API Reference Manual} in the
+chapter ``\ulink{Abstract Objects Layer}{../api/abstract.html}.''
+
+A number of these abstract interfaces were defined early in the
+development of the Python implementation.  In particular, the number,
+mapping, and sequence protocols have been part of Python since the
+beginning.  Other protocols have been added over time.  For protocols
+which depend on several handler routines from the type implementation,
+the older protocols have been defined as optional blocks of handlers
+referenced by the type object.  For newer protocols there are
+additional slots in the main type object, with a flag bit being set to
+indicate that the slots are present and should be checked by the
+interpreter.  (The flag bit does not indicate that the slot values are
+non-\NULL. The flag may be set to indicate the presence of a slot,
+but a slot may still be unfilled.)
+
+\begin{verbatim}
+    PyNumberMethods   tp_as_number;
+    PySequenceMethods tp_as_sequence;
+    PyMappingMethods  tp_as_mapping;
+\end{verbatim}
+
+If you wish your object to be able to act like a number, a sequence,
+or a mapping object, then you place the address of a structure that
+implements the C type \ctype{PyNumberMethods},
+\ctype{PySequenceMethods}, or \ctype{PyMappingMethods}, respectively.
+It is up to you to fill in this structure with appropriate values. You
+can find examples of the use of each of these in the \file{Objects}
+directory of the Python source distribution.
+
+
+\begin{verbatim}
+    hashfunc tp_hash;
+\end{verbatim}
+
+This function, if you choose to provide it, should return a hash
+number for an instance of your data type. Here is a moderately
+pointless example:
+
+\begin{verbatim}
+static long
+newdatatype_hash(newdatatypeobject *obj)
+{
+    long result;
+    result = obj->obj_UnderlyingDatatypePtr->size;
+    result = result * 3;
+    return result;
+}
+\end{verbatim}
+
+\begin{verbatim}
+    ternaryfunc tp_call;
+\end{verbatim}
+
+This function is called when an instance of your data type is "called",
+for example, if \code{obj1} is an instance of your data type and the Python
+script contains \code{obj1('hello')}, the \member{tp_call} handler is
+invoked.
+
+This function takes three arguments:
+
+\begin{enumerate}
+  \item
+    \var{arg1} is the instance of the data type which is the subject of
+    the call. If the call is \code{obj1('hello')}, then \var{arg1} is
+    \code{obj1}.
+
+  \item
+    \var{arg2} is a tuple containing the arguments to the call.  You
+    can use \cfunction{PyArg_ParseTuple()} to extract the arguments.
+
+  \item
+    \var{arg3} is a dictionary of keyword arguments that were passed.
+    If this is non-\NULL{} and you support keyword arguments, use
+    \cfunction{PyArg_ParseTupleAndKeywords()} to extract the
+    arguments.  If you do not want to support keyword arguments and
+    this is non-\NULL, raise a \exception{TypeError} with a message
+    saying that keyword arguments are not supported.
+\end{enumerate}
+
+Here is a desultory example of the implementation of the call function.
+
+\begin{verbatim}
+/* Implement the call function.
+ *    obj1 is the instance receiving the call.
+ *    obj2 is a tuple containing the arguments to the call, in this
+ *         case 3 strings.
+ */
+static PyObject *
+newdatatype_call(newdatatypeobject *obj, PyObject *args, PyObject *other)
+{
+    PyObject *result;
+    char *arg1;
+    char *arg2;
+    char *arg3;
+
+    if (!PyArg_ParseTuple(args, "sss:call", &arg1, &arg2, &arg3)) {
+        return NULL;
+    }
+    result = PyString_FromFormat(
+        "Returning -- value: [\%d] arg1: [\%s] arg2: [\%s] arg3: [\%s]\n",
+        obj->obj_UnderlyingDatatypePtr->size,
+        arg1, arg2, arg3);
+    printf("\%s", PyString_AS_STRING(result));
+    return result;
+}
+\end{verbatim}
+
+XXX some fields need to be added here...
+
+
+\begin{verbatim}
+    /* Added in release 2.2 */
+    /* Iterators */
+    getiterfunc tp_iter;
+    iternextfunc tp_iternext;
+\end{verbatim}
+
+These functions provide support for the iterator protocol.  Any object
+which wishes to support iteration over its contents (which may be
+generated during iteration) must implement the \code{tp_iter}
+handler.  Objects which are returned by a \code{tp_iter} handler must
+implement both the \code{tp_iter} and \code{tp_iternext} handlers.
+Both handlers take exactly one parameter, the instance for which they
+are being called, and return a new reference.  In the case of an
+error, they should set an exception and return \NULL.
+
+For an object which represents an iterable collection, the
+\code{tp_iter} handler must return an iterator object.  The iterator
+object is responsible for maintaining the state of the iteration.  For
+collections which can support multiple iterators which do not
+interfere with each other (as lists and tuples do), a new iterator
+should be created and returned.  Objects which can only be iterated
+over once (usually due to side effects of iteration) should implement
+this handler by returning a new reference to themselves, and should
+also implement the \code{tp_iternext} handler.  File objects are an
+example of such an iterator.
+
+Iterator objects should implement both handlers.  The \code{tp_iter}
+handler should return a new reference to the iterator (this is the
+same as the \code{tp_iter} handler for objects which can only be
+iterated over destructively).  The \code{tp_iternext} handler should
+return a new reference to the next object in the iteration if there is
+one.  If the iteration has reached the end, it may return \NULL{}
+without setting an exception or it may set \exception{StopIteration};
+avoiding the exception can yield slightly better performance.  If an
+actual error occurs, it should set an exception and return \NULL.
+
+
+\subsection{Weak Reference Support\label{weakref-support}}
+
+One of the goals of Python's weak-reference implementation is to allow
+any type to participate in the weak reference mechanism without
+incurring the overhead on those objects which do not benefit by weak
+referencing (such as numbers).
+
+For an object to be weakly referencable, the extension must include a
+\ctype{PyObject*} field in the instance structure for the use of the
+weak reference mechanism; it must be initialized to \NULL{} by the
+object's constructor.  It must also set the \member{tp_weaklistoffset}
+field of the corresponding type object to the offset of the field.
+For example, the instance type is defined with the following
+structure:
+
+\begin{verbatim}
+typedef struct {
+    PyObject_HEAD
+    PyClassObject *in_class;       /* The class object */
+    PyObject      *in_dict;        /* A dictionary */
+    PyObject      *in_weakreflist; /* List of weak references */
+} PyInstanceObject;
+\end{verbatim}
+
+The statically-declared type object for instances is defined this way:
+
+\begin{verbatim}
+PyTypeObject PyInstance_Type = {
+    PyObject_HEAD_INIT(&PyType_Type)
+    0,
+    "module.instance",
+
+    /* Lots of stuff omitted for brevity... */
+
+    Py_TPFLAGS_DEFAULT,                         /* tp_flags */
+    0,                                          /* tp_doc */
+    0,                                          /* tp_traverse */
+    0,                                          /* tp_clear */
+    0,                                          /* tp_richcompare */
+    offsetof(PyInstanceObject, in_weakreflist), /* tp_weaklistoffset */
+};
+\end{verbatim}
+
+The type constructor is responsible for initializing the weak reference
+list to \NULL:
+
+\begin{verbatim}
+static PyObject *
+instance_new() {
+    /* Other initialization stuff omitted for brevity */
+
+    self->in_weakreflist = NULL;
+
+    return (PyObject *) self;
+}
+\end{verbatim}
+
+The only further addition is that the destructor needs to call the
+weak reference manager to clear any weak references.  This should be
+done before any other parts of the destruction have occurred, but is
+only required if the weak reference list is non-\NULL:
+
+\begin{verbatim}
+static void
+instance_dealloc(PyInstanceObject *inst)
+{
+    /* Allocate temporaries if needed, but do not begin
+       destruction just yet.
+     */
+
+    if (inst->in_weakreflist != NULL)
+        PyObject_ClearWeakRefs((PyObject *) inst);
+
+    /* Proceed with object destruction normally. */
+}
+\end{verbatim}
+
+
+\subsection{More Suggestions}
+
+Remember that you can omit most of these functions, in which case you
+provide \code{0} as a value.  There are type definitions for each of
+the functions you must provide.  They are in \file{object.h} in the
+Python include directory that comes with the source distribution of
+Python.
+
+In order to learn how to implement any specific method for your new
+data type, do the following: Download and unpack the Python source
+distribution.  Go the \file{Objects} directory, then search the
+C source files for \code{tp_} plus the function you want (for
+example, \code{tp_print} or \code{tp_compare}).  You will find
+examples of the function you want to implement.
+
+When you need to verify that an object is an instance of the type
+you are implementing, use the \cfunction{PyObject_TypeCheck} function.
+A sample of its use might be something like the following:
+
+\begin{verbatim}
+    if (! PyObject_TypeCheck(some_object, &MyType)) {
+        PyErr_SetString(PyExc_TypeError, "arg #1 not a mything");
+        return NULL;
+    }
+\end{verbatim}

Added: vendor/Python/current/Doc/ext/noddy.c
===================================================================
--- vendor/Python/current/Doc/ext/noddy.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/ext/noddy.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,54 @@
+#include <Python.h>
+
+typedef struct {
+    PyObject_HEAD
+    /* Type-specific fields go here. */
+} noddy_NoddyObject;
+
+static PyTypeObject noddy_NoddyType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "noddy.Noddy",             /*tp_name*/
+    sizeof(noddy_NoddyObject), /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    0,                         /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,        /*tp_flags*/
+    "Noddy objects",           /* tp_doc */
+};
+
+static PyMethodDef noddy_methods[] = {
+    {NULL}  /* Sentinel */
+};
+
+#ifndef PyMODINIT_FUNC	/* declarations for DLL import/export */
+#define PyMODINIT_FUNC void
+#endif
+PyMODINIT_FUNC
+initnoddy(void) 
+{
+    PyObject* m;
+
+    noddy_NoddyType.tp_new = PyType_GenericNew;
+    if (PyType_Ready(&noddy_NoddyType) < 0)
+        return;
+
+    m = Py_InitModule3("noddy", noddy_methods,
+                       "Example module that creates an extension type.");
+
+    Py_INCREF(&noddy_NoddyType);
+    PyModule_AddObject(m, "Noddy", (PyObject *)&noddy_NoddyType);
+}

Added: vendor/Python/current/Doc/ext/noddy2.c
===================================================================
--- vendor/Python/current/Doc/ext/noddy2.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/ext/noddy2.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,190 @@
+#include <Python.h>
+#include "structmember.h"
+
+typedef struct {
+    PyObject_HEAD
+    PyObject *first; /* first name */
+    PyObject *last;  /* last name */
+    int number;
+} Noddy;
+
+static void
+Noddy_dealloc(Noddy* self)
+{
+    Py_XDECREF(self->first);
+    Py_XDECREF(self->last);
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+static PyObject *
+Noddy_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    Noddy *self;
+
+    self = (Noddy *)type->tp_alloc(type, 0);
+    if (self != NULL) {
+        self->first = PyString_FromString("");
+        if (self->first == NULL)
+          {
+            Py_DECREF(self);
+            return NULL;
+          }
+        
+        self->last = PyString_FromString("");
+        if (self->last == NULL)
+          {
+            Py_DECREF(self);
+            return NULL;
+          }
+
+        self->number = 0;
+    }
+
+    return (PyObject *)self;
+}
+
+static int
+Noddy_init(Noddy *self, PyObject *args, PyObject *kwds)
+{
+    PyObject *first=NULL, *last=NULL, *tmp;
+
+    static char *kwlist[] = {"first", "last", "number", NULL};
+
+    if (! PyArg_ParseTupleAndKeywords(args, kwds, "|OOi", kwlist, 
+                                      &first, &last, 
+                                      &self->number))
+        return -1; 
+
+    if (first) {
+        tmp = self->first;
+        Py_INCREF(first);
+        self->first = first;
+        Py_XDECREF(tmp);
+    }
+
+    if (last) {
+        tmp = self->last;
+        Py_INCREF(last);
+        self->last = last;
+        Py_XDECREF(tmp);
+    }
+
+    return 0;
+}
+
+
+static PyMemberDef Noddy_members[] = {
+    {"first", T_OBJECT_EX, offsetof(Noddy, first), 0,
+     "first name"},
+    {"last", T_OBJECT_EX, offsetof(Noddy, last), 0,
+     "last name"},
+    {"number", T_INT, offsetof(Noddy, number), 0,
+     "noddy number"},
+    {NULL}  /* Sentinel */
+};
+
+static PyObject *
+Noddy_name(Noddy* self)
+{
+    static PyObject *format = NULL;
+    PyObject *args, *result;
+
+    if (format == NULL) {
+        format = PyString_FromString("%s %s");
+        if (format == NULL)
+            return NULL;
+    }
+
+    if (self->first == NULL) {
+        PyErr_SetString(PyExc_AttributeError, "first");
+        return NULL;
+    }
+
+    if (self->last == NULL) {
+        PyErr_SetString(PyExc_AttributeError, "last");
+        return NULL;
+    }
+
+    args = Py_BuildValue("OO", self->first, self->last);
+    if (args == NULL)
+        return NULL;
+
+    result = PyString_Format(format, args);
+    Py_DECREF(args);
+    
+    return result;
+}
+
+static PyMethodDef Noddy_methods[] = {
+    {"name", (PyCFunction)Noddy_name, METH_NOARGS,
+     "Return the name, combining the first and last name"
+    },
+    {NULL}  /* Sentinel */
+};
+
+static PyTypeObject NoddyType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "noddy.Noddy",             /*tp_name*/
+    sizeof(Noddy),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)Noddy_dealloc, /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+    "Noddy objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    Noddy_methods,             /* tp_methods */
+    Noddy_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)Noddy_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    Noddy_new,                 /* tp_new */
+};
+
+static PyMethodDef module_methods[] = {
+    {NULL}  /* Sentinel */
+};
+
+#ifndef PyMODINIT_FUNC	/* declarations for DLL import/export */
+#define PyMODINIT_FUNC void
+#endif
+PyMODINIT_FUNC
+initnoddy2(void) 
+{
+    PyObject* m;
+
+    if (PyType_Ready(&NoddyType) < 0)
+        return;
+
+    m = Py_InitModule3("noddy2", module_methods,
+                       "Example module that creates an extension type.");
+
+    if (m == NULL)
+      return;
+
+    Py_INCREF(&NoddyType);
+    PyModule_AddObject(m, "Noddy", (PyObject *)&NoddyType);
+}

Added: vendor/Python/current/Doc/ext/noddy3.c
===================================================================
--- vendor/Python/current/Doc/ext/noddy3.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/ext/noddy3.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,243 @@
+#include <Python.h>
+#include "structmember.h"
+
+typedef struct {
+    PyObject_HEAD
+    PyObject *first;
+    PyObject *last;
+    int number;
+} Noddy;
+
+static void
+Noddy_dealloc(Noddy* self)
+{
+    Py_XDECREF(self->first);
+    Py_XDECREF(self->last);
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+static PyObject *
+Noddy_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    Noddy *self;
+
+    self = (Noddy *)type->tp_alloc(type, 0);
+    if (self != NULL) {
+        self->first = PyString_FromString("");
+        if (self->first == NULL)
+          {
+            Py_DECREF(self);
+            return NULL;
+          }
+        
+        self->last = PyString_FromString("");
+        if (self->last == NULL)
+          {
+            Py_DECREF(self);
+            return NULL;
+          }
+
+        self->number = 0;
+    }
+
+    return (PyObject *)self;
+}
+
+static int
+Noddy_init(Noddy *self, PyObject *args, PyObject *kwds)
+{
+    PyObject *first=NULL, *last=NULL, *tmp;
+
+    static char *kwlist[] = {"first", "last", "number", NULL};
+
+    if (! PyArg_ParseTupleAndKeywords(args, kwds, "|SSi", kwlist, 
+                                      &first, &last, 
+                                      &self->number))
+        return -1; 
+
+    if (first) {
+        tmp = self->first;
+        Py_INCREF(first);
+        self->first = first;
+        Py_DECREF(tmp);
+    }
+
+    if (last) {
+        tmp = self->last;
+        Py_INCREF(last);
+        self->last = last;
+        Py_DECREF(tmp);
+    }
+
+    return 0;
+}
+
+static PyMemberDef Noddy_members[] = {
+    {"number", T_INT, offsetof(Noddy, number), 0,
+     "noddy number"},
+    {NULL}  /* Sentinel */
+};
+
+static PyObject *
+Noddy_getfirst(Noddy *self, void *closure)
+{
+    Py_INCREF(self->first);
+    return self->first;
+}
+
+static int
+Noddy_setfirst(Noddy *self, PyObject *value, void *closure)
+{
+  if (value == NULL) {
+    PyErr_SetString(PyExc_TypeError, "Cannot delete the first attribute");
+    return -1;
+  }
+  
+  if (! PyString_Check(value)) {
+    PyErr_SetString(PyExc_TypeError, 
+                    "The first attribute value must be a string");
+    return -1;
+  }
+      
+  Py_DECREF(self->first);
+  Py_INCREF(value);
+  self->first = value;    
+
+  return 0;
+}
+
+static PyObject *
+Noddy_getlast(Noddy *self, void *closure)
+{
+    Py_INCREF(self->last);
+    return self->last;
+}
+
+static int
+Noddy_setlast(Noddy *self, PyObject *value, void *closure)
+{
+  if (value == NULL) {
+    PyErr_SetString(PyExc_TypeError, "Cannot delete the last attribute");
+    return -1;
+  }
+  
+  if (! PyString_Check(value)) {
+    PyErr_SetString(PyExc_TypeError, 
+                    "The last attribute value must be a string");
+    return -1;
+  }
+      
+  Py_DECREF(self->last);
+  Py_INCREF(value);
+  self->last = value;    
+
+  return 0;
+}
+
+static PyGetSetDef Noddy_getseters[] = {
+    {"first", 
+     (getter)Noddy_getfirst, (setter)Noddy_setfirst,
+     "first name",
+     NULL},
+    {"last", 
+     (getter)Noddy_getlast, (setter)Noddy_setlast,
+     "last name",
+     NULL},
+    {NULL}  /* Sentinel */
+};
+
+static PyObject *
+Noddy_name(Noddy* self)
+{
+    static PyObject *format = NULL;
+    PyObject *args, *result;
+
+    if (format == NULL) {
+        format = PyString_FromString("%s %s");
+        if (format == NULL)
+            return NULL;
+    }
+
+    args = Py_BuildValue("OO", self->first, self->last);
+    if (args == NULL)
+        return NULL;
+
+    result = PyString_Format(format, args);
+    Py_DECREF(args);
+    
+    return result;
+}
+
+static PyMethodDef Noddy_methods[] = {
+    {"name", (PyCFunction)Noddy_name, METH_NOARGS,
+     "Return the name, combining the first and last name"
+    },
+    {NULL}  /* Sentinel */
+};
+
+static PyTypeObject NoddyType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "noddy.Noddy",             /*tp_name*/
+    sizeof(Noddy),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)Noddy_dealloc, /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+    "Noddy objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    Noddy_methods,             /* tp_methods */
+    Noddy_members,             /* tp_members */
+    Noddy_getseters,           /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)Noddy_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    Noddy_new,                 /* tp_new */
+};
+
+static PyMethodDef module_methods[] = {
+    {NULL}  /* Sentinel */
+};
+
+#ifndef PyMODINIT_FUNC	/* declarations for DLL import/export */
+#define PyMODINIT_FUNC void
+#endif
+PyMODINIT_FUNC
+initnoddy3(void) 
+{
+    PyObject* m;
+
+    if (PyType_Ready(&NoddyType) < 0)
+        return;
+
+    m = Py_InitModule3("noddy3", module_methods,
+                       "Example module that creates an extension type.");
+
+    if (m == NULL)
+      return;
+
+    Py_INCREF(&NoddyType);
+    PyModule_AddObject(m, "Noddy", (PyObject *)&NoddyType);
+}

Added: vendor/Python/current/Doc/ext/noddy4.c
===================================================================
--- vendor/Python/current/Doc/ext/noddy4.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/ext/noddy4.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,224 @@
+#include <Python.h>
+#include "structmember.h"
+
+typedef struct {
+    PyObject_HEAD
+    PyObject *first;
+    PyObject *last;
+    int number;
+} Noddy;
+
+static int
+Noddy_traverse(Noddy *self, visitproc visit, void *arg)
+{
+    int vret;
+
+    if (self->first) {
+        vret = visit(self->first, arg);
+        if (vret != 0)
+            return vret;
+    }
+    if (self->last) {
+        vret = visit(self->last, arg);
+        if (vret != 0)
+            return vret;
+    }
+
+    return 0;
+}
+
+static int 
+Noddy_clear(Noddy *self)
+{
+    PyObject *tmp;
+
+    tmp = self->first;
+    self->first = NULL;
+    Py_XDECREF(tmp);
+
+    tmp = self->last;
+    self->last = NULL;
+    Py_XDECREF(tmp);
+
+    return 0;
+}
+
+static void
+Noddy_dealloc(Noddy* self)
+{
+    Noddy_clear(self);
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+static PyObject *
+Noddy_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    Noddy *self;
+
+    self = (Noddy *)type->tp_alloc(type, 0);
+    if (self != NULL) {
+        self->first = PyString_FromString("");
+        if (self->first == NULL)
+          {
+            Py_DECREF(self);
+            return NULL;
+          }
+        
+        self->last = PyString_FromString("");
+        if (self->last == NULL)
+          {
+            Py_DECREF(self);
+            return NULL;
+          }
+
+        self->number = 0;
+    }
+
+    return (PyObject *)self;
+}
+
+static int
+Noddy_init(Noddy *self, PyObject *args, PyObject *kwds)
+{
+    PyObject *first=NULL, *last=NULL, *tmp;
+
+    static char *kwlist[] = {"first", "last", "number", NULL};
+
+    if (! PyArg_ParseTupleAndKeywords(args, kwds, "|OOi", kwlist, 
+                                      &first, &last, 
+                                      &self->number))
+        return -1; 
+
+    if (first) {
+        tmp = self->first;
+        Py_INCREF(first);
+        self->first = first;
+        Py_XDECREF(tmp);
+    }
+
+    if (last) {
+        tmp = self->last;
+        Py_INCREF(last);
+        self->last = last;
+        Py_XDECREF(tmp);
+    }
+
+    return 0;
+}
+
+
+static PyMemberDef Noddy_members[] = {
+    {"first", T_OBJECT_EX, offsetof(Noddy, first), 0,
+     "first name"},
+    {"last", T_OBJECT_EX, offsetof(Noddy, last), 0,
+     "last name"},
+    {"number", T_INT, offsetof(Noddy, number), 0,
+     "noddy number"},
+    {NULL}  /* Sentinel */
+};
+
+static PyObject *
+Noddy_name(Noddy* self)
+{
+    static PyObject *format = NULL;
+    PyObject *args, *result;
+
+    if (format == NULL) {
+        format = PyString_FromString("%s %s");
+        if (format == NULL)
+            return NULL;
+    }
+
+    if (self->first == NULL) {
+        PyErr_SetString(PyExc_AttributeError, "first");
+        return NULL;
+    }
+
+    if (self->last == NULL) {
+        PyErr_SetString(PyExc_AttributeError, "last");
+        return NULL;
+    }
+
+    args = Py_BuildValue("OO", self->first, self->last);
+    if (args == NULL)
+        return NULL;
+
+    result = PyString_Format(format, args);
+    Py_DECREF(args);
+    
+    return result;
+}
+
+static PyMethodDef Noddy_methods[] = {
+    {"name", (PyCFunction)Noddy_name, METH_NOARGS,
+     "Return the name, combining the first and last name"
+    },
+    {NULL}  /* Sentinel */
+};
+
+static PyTypeObject NoddyType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "noddy.Noddy",             /*tp_name*/
+    sizeof(Noddy),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)Noddy_dealloc, /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+    "Noddy objects",           /* tp_doc */
+    (traverseproc)Noddy_traverse,   /* tp_traverse */
+    (inquiry)Noddy_clear,           /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    Noddy_methods,             /* tp_methods */
+    Noddy_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)Noddy_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    Noddy_new,                 /* tp_new */
+};
+
+static PyMethodDef module_methods[] = {
+    {NULL}  /* Sentinel */
+};
+
+#ifndef PyMODINIT_FUNC	/* declarations for DLL import/export */
+#define PyMODINIT_FUNC void
+#endif
+PyMODINIT_FUNC
+initnoddy4(void) 
+{
+    PyObject* m;
+
+    if (PyType_Ready(&NoddyType) < 0)
+        return;
+
+    m = Py_InitModule3("noddy4", module_methods,
+                       "Example module that creates an extension type.");
+
+    if (m == NULL)
+      return;
+
+    Py_INCREF(&NoddyType);
+    PyModule_AddObject(m, "Noddy", (PyObject *)&NoddyType);
+}

Added: vendor/Python/current/Doc/ext/run-func.c
===================================================================
--- vendor/Python/current/Doc/ext/run-func.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/ext/run-func.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,68 @@
+#include <Python.h>
+
+int
+main(int argc, char *argv[])
+{
+    PyObject *pName, *pModule, *pDict, *pFunc;
+    PyObject *pArgs, *pValue;
+    int i;
+
+    if (argc < 3) {
+        fprintf(stderr,"Usage: call pythonfile funcname [args]\n");
+        return 1;
+    }
+
+    Py_Initialize();
+    pName = PyString_FromString(argv[1]);
+    /* Error checking of pName left out */
+
+    pModule = PyImport_Import(pName);
+    Py_DECREF(pName);
+
+    if (pModule != NULL) {
+        pFunc = PyObject_GetAttrString(pModule, argv[2]);
+        /* pFunc is a new reference */
+
+        if (pFunc && PyCallable_Check(pFunc)) {
+            pArgs = PyTuple_New(argc - 3);
+            for (i = 0; i < argc - 3; ++i) {
+                pValue = PyInt_FromLong(atoi(argv[i + 3]));
+                if (!pValue) {
+                    Py_DECREF(pArgs);
+                    Py_DECREF(pModule);
+                    fprintf(stderr, "Cannot convert argument\n");
+                    return 1;
+                }
+                /* pValue reference stolen here: */
+                PyTuple_SetItem(pArgs, i, pValue);
+            }
+            pValue = PyObject_CallObject(pFunc, pArgs);
+            Py_DECREF(pArgs);
+            if (pValue != NULL) {
+                printf("Result of call: %ld\n", PyInt_AsLong(pValue));
+                Py_DECREF(pValue);
+            }
+            else {
+                Py_DECREF(pFunc);
+                Py_DECREF(pModule);
+                PyErr_Print();
+                fprintf(stderr,"Call failed\n");
+                return 1;
+            }
+        }
+        else {
+            if (PyErr_Occurred())
+                PyErr_Print();
+            fprintf(stderr, "Cannot find function \"%s\"\n", argv[2]);
+        }
+        Py_XDECREF(pFunc);
+        Py_DECREF(pModule);
+    }
+    else {
+        PyErr_Print();
+        fprintf(stderr, "Failed to load \"%s\"\n", argv[1]);
+        return 1;
+    }
+    Py_Finalize();
+    return 0;
+}

Added: vendor/Python/current/Doc/ext/setup.py
===================================================================
--- vendor/Python/current/Doc/ext/setup.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/ext/setup.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,8 @@
+from distutils.core import setup, Extension
+setup(name="noddy", version="1.0",
+      ext_modules=[
+         Extension("noddy", ["noddy.c"]),
+         Extension("noddy2", ["noddy2.c"]),
+         Extension("noddy3", ["noddy3.c"]),
+         Extension("noddy4", ["noddy4.c"]),
+         ])

Added: vendor/Python/current/Doc/ext/shoddy.c
===================================================================
--- vendor/Python/current/Doc/ext/shoddy.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/ext/shoddy.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,91 @@
+#include <Python.h>
+
+typedef struct {
+    PyListObject list;
+    int state;
+} Shoddy;
+
+
+static PyObject *
+Shoddy_increment(Shoddy *self, PyObject *unused)
+{
+    self->state++;
+    return PyInt_FromLong(self->state);
+}
+
+
+static PyMethodDef Shoddy_methods[] = {
+    {"increment", (PyCFunction)Shoddy_increment, METH_NOARGS,
+     PyDoc_STR("increment state counter")},
+    {NULL,	NULL},
+};
+
+static int
+Shoddy_init(Shoddy *self, PyObject *args, PyObject *kwds)
+{
+    if (PyList_Type.tp_init((PyObject *)self, args, kwds) < 0)
+        return -1;
+    self->state = 0;
+    return 0;
+}
+
+
+static PyTypeObject ShoddyType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                       /* ob_size */
+    "shoddy.Shoddy",         /* tp_name */
+    sizeof(Shoddy),          /* tp_basicsize */
+    0,                       /* tp_itemsize */
+    0,                       /* tp_dealloc */
+    0,                       /* tp_print */
+    0,                       /* tp_getattr */
+    0,                       /* tp_setattr */
+    0,                       /* tp_compare */
+    0,                       /* tp_repr */
+    0,                       /* tp_as_number */
+    0,                       /* tp_as_sequence */
+    0,                       /* tp_as_mapping */
+    0,                       /* tp_hash */
+    0,                       /* tp_call */
+    0,                       /* tp_str */
+    0,                       /* tp_getattro */
+    0,                       /* tp_setattro */
+    0,                       /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT |
+      Py_TPFLAGS_BASETYPE,   /* tp_flags */
+    0,                       /* tp_doc */
+    0,                       /* tp_traverse */
+    0,                       /* tp_clear */
+    0,                       /* tp_richcompare */
+    0,                       /* tp_weaklistoffset */
+    0,                       /* tp_iter */
+    0,                       /* tp_iternext */
+    Shoddy_methods,          /* tp_methods */
+    0,                       /* tp_members */
+    0,                       /* tp_getset */
+    0,                       /* tp_base */
+    0,                       /* tp_dict */
+    0,                       /* tp_descr_get */
+    0,                       /* tp_descr_set */
+    0,                       /* tp_dictoffset */
+    (initproc)Shoddy_init,   /* tp_init */
+    0,                       /* tp_alloc */
+    0,                       /* tp_new */
+};
+
+PyMODINIT_FUNC
+initshoddy(void)
+{
+    PyObject *m;
+
+    ShoddyType.tp_base = &PyList_Type;
+    if (PyType_Ready(&ShoddyType) < 0)
+        return;
+
+    m = Py_InitModule3("shoddy", NULL, "Shoddy module");
+    if (m == NULL)
+        return;
+
+    Py_INCREF(&ShoddyType);
+    PyModule_AddObject(m, "Shoddy", (PyObject *) &ShoddyType);
+}

Added: vendor/Python/current/Doc/ext/test.py
===================================================================
--- vendor/Python/current/Doc/ext/test.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/ext/test.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,213 @@
+"""Test module for the noddy examples
+
+Noddy 1:
+
+>>> import noddy
+>>> n1 = noddy.Noddy()
+>>> n2 = noddy.Noddy()
+>>> del n1
+>>> del n2
+
+
+Noddy 2
+
+>>> import noddy2
+>>> n1 = noddy2.Noddy('jim', 'fulton', 42)
+>>> n1.first
+'jim'
+>>> n1.last
+'fulton'
+>>> n1.number
+42
+>>> n1.name()
+'jim fulton'
+>>> n1.first = 'will'
+>>> n1.name()
+'will fulton'
+>>> n1.last = 'tell'
+>>> n1.name()
+'will tell'
+>>> del n1.first
+>>> n1.name()
+Traceback (most recent call last):
+...
+AttributeError: first
+>>> n1.first
+Traceback (most recent call last):
+...
+AttributeError: first
+>>> n1.first = 'drew'
+>>> n1.first
+'drew'
+>>> del n1.number
+Traceback (most recent call last):
+...
+TypeError: can't delete numeric/char attribute
+>>> n1.number=2
+>>> n1.number
+2
+>>> n1.first = 42
+>>> n1.name()
+'42 tell'
+>>> n2 = noddy2.Noddy()
+>>> n2.name()
+' '
+>>> n2.first
+''
+>>> n2.last
+''
+>>> del n2.first
+>>> n2.first
+Traceback (most recent call last):
+...
+AttributeError: first
+>>> n2.first
+Traceback (most recent call last):
+...
+AttributeError: first
+>>> n2.name()
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+AttributeError: first
+>>> n2.number
+0
+>>> n3 = noddy2.Noddy('jim', 'fulton', 'waaa')
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+TypeError: an integer is required
+>>> del n1
+>>> del n2
+
+
+Noddy 3
+
+>>> import noddy3
+>>> n1 = noddy3.Noddy('jim', 'fulton', 42)
+>>> n1 = noddy3.Noddy('jim', 'fulton', 42)
+>>> n1.name()
+'jim fulton'
+>>> del n1.first
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+TypeError: Cannot delete the first attribute
+>>> n1.first = 42
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+TypeError: The first attribute value must be a string
+>>> n1.first = 'will'
+>>> n1.name()
+'will fulton'
+>>> n2 = noddy3.Noddy()
+>>> n2 = noddy3.Noddy()
+>>> n2 = noddy3.Noddy()
+>>> n3 = noddy3.Noddy('jim', 'fulton', 'waaa')
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+TypeError: an integer is required
+>>> del n1
+>>> del n2
+
+Noddy 4
+
+>>> import noddy4
+>>> n1 = noddy4.Noddy('jim', 'fulton', 42)
+>>> n1.first
+'jim'
+>>> n1.last
+'fulton'
+>>> n1.number
+42
+>>> n1.name()
+'jim fulton'
+>>> n1.first = 'will'
+>>> n1.name()
+'will fulton'
+>>> n1.last = 'tell'
+>>> n1.name()
+'will tell'
+>>> del n1.first
+>>> n1.name()
+Traceback (most recent call last):
+...
+AttributeError: first
+>>> n1.first
+Traceback (most recent call last):
+...
+AttributeError: first
+>>> n1.first = 'drew'
+>>> n1.first
+'drew'
+>>> del n1.number
+Traceback (most recent call last):
+...
+TypeError: can't delete numeric/char attribute
+>>> n1.number=2
+>>> n1.number
+2
+>>> n1.first = 42
+>>> n1.name()
+'42 tell'
+>>> n2 = noddy4.Noddy()
+>>> n2 = noddy4.Noddy()
+>>> n2 = noddy4.Noddy()
+>>> n2 = noddy4.Noddy()
+>>> n2.name()
+' '
+>>> n2.first
+''
+>>> n2.last
+''
+>>> del n2.first
+>>> n2.first
+Traceback (most recent call last):
+...
+AttributeError: first
+>>> n2.first
+Traceback (most recent call last):
+...
+AttributeError: first
+>>> n2.name()
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+AttributeError: first
+>>> n2.number
+0
+>>> n3 = noddy4.Noddy('jim', 'fulton', 'waaa')
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+TypeError: an integer is required
+
+
+Test cyclic gc(?)
+
+>>> import gc
+>>> gc.disable()
+
+>>> x = []
+>>> l = [x]
+>>> n2.first = l
+>>> n2.first
+[[]]
+>>> l.append(n2)
+>>> del l
+>>> del n1
+>>> del n2
+>>> sys.getrefcount(x)
+3
+>>> ignore = gc.collect()
+>>> sys.getrefcount(x)
+2
+
+>>> gc.enable()
+"""
+
+import os
+import sys
+from distutils.util import get_platform
+PLAT_SPEC = "%s-%s" % (get_platform(), sys.version[0:3])
+src = os.path.join("build", "lib.%s" % PLAT_SPEC)
+sys.path.append(src)
+
+if __name__ == "__main__":
+    import doctest, __main__
+    doctest.testmod(__main__)

Added: vendor/Python/current/Doc/ext/windows.tex
===================================================================
--- vendor/Python/current/Doc/ext/windows.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/ext/windows.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,320 @@
+\chapter{Building C and \Cpp{} Extensions on Windows%
+     \label{building-on-windows}}
+
+
+This chapter briefly explains how to create a Windows extension module
+for Python using Microsoft Visual \Cpp, and follows with more
+detailed background information on how it works.  The explanatory
+material is useful for both the Windows programmer learning to build
+Python extensions and the \UNIX{} programmer interested in producing
+software which can be successfully built on both \UNIX{} and Windows.
+
+Module authors are encouraged to use the distutils approach for
+building extension modules, instead of the one described in this
+section. You will still need the C compiler that was used to build
+Python; typically Microsoft Visual \Cpp.
+
+\begin{notice}
+  This chapter mentions a number of filenames that include an encoded
+  Python version number.  These filenames are represented with the
+  version number shown as \samp{XY}; in practive, \character{X} will
+  be the major version number and \character{Y} will be the minor
+  version number of the Python release you're working with.  For
+  example, if you are using Python 2.2.1, \samp{XY} will actually be
+  \samp{22}.
+\end{notice}
+
+
+\section{A Cookbook Approach \label{win-cookbook}}
+
+There are two approaches to building extension modules on Windows,
+just as there are on \UNIX: use the
+\ulink{\module{distutils}}{../lib/module-distutils.html} package to
+control the build process, or do things manually.  The distutils
+approach works well for most extensions; documentation on using
+\ulink{\module{distutils}}{../lib/module-distutils.html} to build and
+package extension modules is available in
+\citetitle[../dist/dist.html]{Distributing Python Modules}.  This
+section describes the manual approach to building Python extensions
+written in C or \Cpp.
+
+To build extensions using these instructions, you need to have a copy
+of the Python sources of the same version as your installed Python.
+You will need Microsoft Visual \Cpp{} ``Developer Studio''; project
+files are supplied for V\Cpp{} version 7.1, but you can use older
+versions of V\Cpp.  Notice that you should use the same version of
+V\Cpp that was used to build Python itself. The example files
+described here are distributed with the Python sources in the
+\file{PC\textbackslash example_nt\textbackslash} directory.
+
+\begin{enumerate}
+  \item
+  \strong{Copy the example files}\\
+    The \file{example_nt} directory is a subdirectory of the \file{PC}
+    directory, in order to keep all the PC-specific files under the
+    same directory in the source distribution.  However, the
+    \file{example_nt} directory can't actually be used from this
+    location.  You first need to copy or move it up one level, so that
+    \file{example_nt} is a sibling of the \file{PC} and \file{Include}
+    directories.  Do all your work from within this new location.
+
+  \item
+  \strong{Open the project}\\
+    From V\Cpp, use the \menuselection{File \sub Open Solution}
+    dialog (not \menuselection{File \sub Open}!).  Navigate to and
+    select the file \file{example.sln}, in the \emph{copy} of the
+    \file{example_nt} directory you made above.  Click Open.
+
+  \item
+  \strong{Build the example DLL}\\
+    In order to check that everything is set up right, try building:
+
+    \begin{enumerate}
+      \item
+        Select a configuration.  This step is optional.  Choose
+        \menuselection{Build \sub Configuration Manager \sub Active 
+        Solution Configuration} and select either \guilabel{Release} 
+        or\guilabel{Debug}.  If you skip this step,
+        V\Cpp{} will use the Debug configuration by default.
+
+      \item
+        Build the DLL.  Choose \menuselection{Build \sub Build
+        Solution}.  This creates all intermediate and result files in
+        a subdirectory called either \file{Debug} or \file{Release},
+        depending on which configuration you selected in the preceding
+        step.
+    \end{enumerate}
+
+  \item
+  \strong{Testing the debug-mode DLL}\\
+    Once the Debug build has succeeded, bring up a DOS box, and change
+    to the \file{example_nt\textbackslash Debug} directory.  You
+    should now be able to repeat the following session (\code{C>} is
+    the DOS prompt, \code{>>>} is the Python prompt; note that
+    build information and various debug output from Python may not
+    match this screen dump exactly):
+
+\begin{verbatim}
+C>..\..\PCbuild\python_d
+Adding parser accelerators ...
+Done.
+Python 2.2 (#28, Dec 19 2001, 23:26:37) [MSC 32 bit (Intel)] on win32
+Type "copyright", "credits" or "license" for more information.
+>>> import example
+[4897 refs]
+>>> example.foo()
+Hello, world
+[4903 refs]
+>>>
+\end{verbatim}
+
+    Congratulations!  You've successfully built your first Python
+    extension module.
+
+  \item
+  \strong{Creating your own project}\\
+    Choose a name and create a directory for it.  Copy your C sources
+    into it.  Note that the module source file name does not
+    necessarily have to match the module name, but the name of the
+    initialization function should match the module name --- you can
+    only import a module \module{spam} if its initialization function
+    is called \cfunction{initspam()}, and it should call
+    \cfunction{Py_InitModule()} with the string \code{"spam"} as its
+    first argument (use the minimal \file{example.c} in this directory
+    as a guide).  By convention, it lives in a file called
+    \file{spam.c} or \file{spammodule.c}.  The output file should be
+    called \file{spam.dll} or \file{spam.pyd} (the latter is supported
+    to avoid confusion with a system library \file{spam.dll} to which
+    your module could be a Python interface) in Release mode, or
+    \file{spam_d.dll} or \file{spam_d.pyd} in Debug mode.
+
+    Now your options are:
+
+    \begin{enumerate}
+      \item  Copy \file{example.sln} and \file{example.vcproj}, rename
+             them to \file{spam.*}, and edit them by hand, or
+      \item  Create a brand new project; instructions are below.
+    \end{enumerate}
+
+    In either case, copy \file{example_nt\textbackslash example.def}
+    to \file{spam\textbackslash spam.def}, and edit the new
+    \file{spam.def} so its second line contains the string
+    `\code{initspam}'.  If you created a new project yourself, add the
+    file \file{spam.def} to the project now.  (This is an annoying
+    little file with only two lines.  An alternative approach is to
+    forget about the \file{.def} file, and add the option
+    \programopt{/export:initspam} somewhere to the Link settings, by
+    manually editing the setting in Project Properties dialog).
+
+  \item
+  \strong{Creating a brand new project}\\
+    Use the \menuselection{File \sub New \sub Project} dialog to
+    create a new Project Workspace.  Select \guilabel{Visual C++
+    Projects/Win32/ Win32 Project}, enter the name (\samp{spam}), and
+    make sure the Location is set to parent of the \file{spam}
+    directory you have created (which should be a direct subdirectory
+    of the Python build tree, a sibling of \file{Include} and
+    \file{PC}).  Select Win32 as the platform (in my version, this is
+    the only choice).  Make sure the Create new workspace radio button
+    is selected.  Click OK.
+
+    You should now create the file \file{spam.def} as instructed in
+    the previous section. Add the source files to the project, using
+    \menuselection{Project \sub Add Existing Item}. Set the pattern to
+    \code{*.*} and select both \file{spam.c} and \file{spam.def} and
+    click OK.  (Inserting them one by one is fine too.)
+
+    Now open the \menuselection{Project \sub spam properties} dialog.
+    You only need to change a few settings.  Make sure \guilabel{All
+    Configurations} is selected from the \guilabel{Settings for:}
+    dropdown list.  Select the C/\Cpp{} tab.  Choose the General
+    category in the popup menu at the top.  Type the following text in
+    the entry box labeled \guilabel{Additional Include Directories}:
+
+\begin{verbatim}
+..\Include,..\PC
+\end{verbatim}
+
+    Then, choose the General category in the Linker tab, and enter
+
+\begin{verbatim}
+..\PCbuild
+\end{verbatim}
+
+    in the text box labelled \guilabel{Additional library Directories}.
+
+    Now you need to add some mode-specific settings:
+
+    Select \guilabel{Release} in the \guilabel{Configuration}
+    dropdown list.  Choose the \guilabel{Link} tab, choose the
+    \guilabel{Input} category, and append \code{pythonXY.lib} to the
+    list in the \guilabel{Additional Dependencies} box.
+
+    Select \guilabel{Debug} in the \guilabel{Configuration} dropdown
+    list, and append \code{pythonXY_d.lib} to the list in the
+    \guilabel{Additional Dependencies} box.  Then click the C/\Cpp{}
+    tab, select \guilabel{Code Generation}, and select
+    \guilabel{Multi-threaded Debug DLL} from the \guilabel{Runtime
+    library} dropdown list.
+
+    Select \guilabel{Release} again from the \guilabel{Configuration}
+    dropdown list.  Select \guilabel{Multi-threaded DLL} from the
+    \guilabel{Runtime library} dropdown list.
+\end{enumerate}
+
+
+If your module creates a new type, you may have trouble with this line:
+
+\begin{verbatim}
+    PyObject_HEAD_INIT(&PyType_Type)
+\end{verbatim}
+
+Change it to:
+
+\begin{verbatim}
+    PyObject_HEAD_INIT(NULL)
+\end{verbatim}
+
+and add the following to the module initialization function:
+
+\begin{verbatim}
+    MyObject_Type.ob_type = &PyType_Type;
+\end{verbatim}
+
+Refer to section~3 of the
+\citetitle[http://www.python.org/doc/FAQ.html]{Python FAQ} for details
+on why you must do this.
+
+
+\section{Differences Between \UNIX{} and Windows
+     \label{dynamic-linking}}
+\sectionauthor{Chris Phoenix}{cphoenix at best.com}
+
+
+\UNIX{} and Windows use completely different paradigms for run-time
+loading of code.  Before you try to build a module that can be
+dynamically loaded, be aware of how your system works.
+
+In \UNIX, a shared object (\file{.so}) file contains code to be used by the
+program, and also the names of functions and data that it expects to
+find in the program.  When the file is joined to the program, all
+references to those functions and data in the file's code are changed
+to point to the actual locations in the program where the functions
+and data are placed in memory.  This is basically a link operation.
+
+In Windows, a dynamic-link library (\file{.dll}) file has no dangling
+references.  Instead, an access to functions or data goes through a
+lookup table.  So the DLL code does not have to be fixed up at runtime
+to refer to the program's memory; instead, the code already uses the
+DLL's lookup table, and the lookup table is modified at runtime to
+point to the functions and data.
+
+In \UNIX, there is only one type of library file (\file{.a}) which
+contains code from several object files (\file{.o}).  During the link
+step to create a shared object file (\file{.so}), the linker may find
+that it doesn't know where an identifier is defined.  The linker will
+look for it in the object files in the libraries; if it finds it, it
+will include all the code from that object file.
+
+In Windows, there are two types of library, a static library and an
+import library (both called \file{.lib}).  A static library is like a
+\UNIX{} \file{.a} file; it contains code to be included as necessary.
+An import library is basically used only to reassure the linker that a
+certain identifier is legal, and will be present in the program when
+the DLL is loaded.  So the linker uses the information from the
+import library to build the lookup table for using identifiers that
+are not included in the DLL.  When an application or a DLL is linked,
+an import library may be generated, which will need to be used for all
+future DLLs that depend on the symbols in the application or DLL.
+
+Suppose you are building two dynamic-load modules, B and C, which should
+share another block of code A.  On \UNIX, you would \emph{not} pass
+\file{A.a} to the linker for \file{B.so} and \file{C.so}; that would
+cause it to be included twice, so that B and C would each have their
+own copy.  In Windows, building \file{A.dll} will also build
+\file{A.lib}.  You \emph{do} pass \file{A.lib} to the linker for B and
+C.  \file{A.lib} does not contain code; it just contains information
+which will be used at runtime to access A's code.  
+
+In Windows, using an import library is sort of like using \samp{import
+spam}; it gives you access to spam's names, but does not create a
+separate copy.  On \UNIX, linking with a library is more like
+\samp{from spam import *}; it does create a separate copy.
+
+
+\section{Using DLLs in Practice \label{win-dlls}}
+\sectionauthor{Chris Phoenix}{cphoenix at best.com}
+
+Windows Python is built in Microsoft Visual \Cpp; using other
+compilers may or may not work (though Borland seems to).  The rest of
+this section is MSV\Cpp{} specific.
+
+When creating DLLs in Windows, you must pass \file{pythonXY.lib} to
+the linker.  To build two DLLs, spam and ni (which uses C functions
+found in spam), you could use these commands:
+
+\begin{verbatim}
+cl /LD /I/python/include spam.c ../libs/pythonXY.lib
+cl /LD /I/python/include ni.c spam.lib ../libs/pythonXY.lib
+\end{verbatim}
+
+The first command created three files: \file{spam.obj},
+\file{spam.dll} and \file{spam.lib}.  \file{Spam.dll} does not contain
+any Python functions (such as \cfunction{PyArg_ParseTuple()}), but it
+does know how to find the Python code thanks to \file{pythonXY.lib}.
+
+The second command created \file{ni.dll} (and \file{.obj} and
+\file{.lib}), which knows how to find the necessary functions from
+spam, and also from the Python executable.
+
+Not every identifier is exported to the lookup table.  If you want any
+other modules (including Python) to be able to see your identifiers,
+you have to say \samp{_declspec(dllexport)}, as in \samp{void
+_declspec(dllexport) initspam(void)} or \samp{PyObject
+_declspec(dllexport) *NiGetSpamData(void)}.
+
+Developer Studio will throw in a lot of import libraries that you do
+not really need, adding about 100K to your executable.  To get rid of
+them, use the Project Settings dialog, Link tab, to specify
+\emph{ignore default libraries}.  Add the correct
+\file{msvcrt\var{xx}.lib} to the list of libraries.

Added: vendor/Python/current/Doc/howto/TODO
===================================================================
--- vendor/Python/current/Doc/howto/TODO	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/howto/TODO	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,13 @@
+
+Short-term tasks:
+  Quick revision pass to make HOWTOs match the current state of Python:
+curses doanddont regex sockets sorting
+
+Medium-term tasks:
+ Revisit the regex howto.  
+	* Add exercises with answers for each section
+	* More examples?
+
+Long-term tasks:
+ Integrate with other Python docs?
+

Added: vendor/Python/current/Doc/howto/advocacy.tex
===================================================================
--- vendor/Python/current/Doc/howto/advocacy.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/howto/advocacy.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,411 @@
+
+\documentclass{howto}
+
+\title{Python Advocacy HOWTO}
+
+\release{0.03}
+
+\author{A.M. Kuchling}
+\authoraddress{\email{amk at amk.ca}}
+
+\begin{document}
+\maketitle
+
+\begin{abstract}
+\noindent
+It's usually difficult to get your management to accept open source
+software, and Python is no exception to this rule.  This document
+discusses reasons to use Python, strategies for winning acceptance,
+facts and arguments you can use, and cases where you \emph{shouldn't}
+try to use Python.
+
+This document is available from the Python HOWTO page at
+\url{http://www.python.org/doc/howto}.
+
+\end{abstract}
+
+\tableofcontents
+
+\section{Reasons to Use Python}
+
+There are several reasons to incorporate a scripting language into
+your development process, and this section will discuss them, and why
+Python has some properties that make it a particularly good choice.
+
+ \subsection{Programmability}
+
+Programs are often organized in a modular fashion.  Lower-level
+operations are grouped together, and called by higher-level functions,
+which may in turn be used as basic operations by still further upper
+levels.  
+
+For example, the lowest level might define a very low-level
+set of functions for accessing a hash table.  The next level might use
+hash tables to store the headers of a mail message, mapping a header
+name like \samp{Date} to a value such as \samp{Tue, 13 May 1997
+20:00:54 -0400}.  A yet higher level may operate on message objects,
+without knowing or caring that message headers are stored in a hash
+table, and so forth.  
+
+Often, the lowest levels do very simple things; they implement a data
+structure such as a binary tree or hash table, or they perform some
+simple computation, such as converting a date string to a number.  The
+higher levels then contain logic connecting these primitive
+operations.  Using the approach, the primitives can be seen as basic
+building blocks which are then glued together to produce the complete
+product.  
+
+Why is this design approach relevant to Python?  Because Python is
+well suited to functioning as such a glue language.  A common approach
+is to write a Python module that implements the lower level
+operations; for the sake of speed, the implementation might be in C,
+Java, or even Fortran.  Once the primitives are available to Python
+programs, the logic underlying higher level operations is written in
+the form of Python code.  The high-level logic is then more
+understandable, and easier to modify.
+
+John Ousterhout wrote a paper that explains this idea at greater
+length, entitled ``Scripting: Higher Level Programming for the 21st
+Century''.  I recommend that you read this paper; see the references
+for the URL.  Ousterhout is the inventor of the Tcl language, and
+therefore argues that Tcl should be used for this purpose; he only
+briefly refers to other languages such as Python, Perl, and
+Lisp/Scheme, but in reality, Ousterhout's argument applies to
+scripting languages in general, since you could equally write
+extensions for any of the languages mentioned above.
+
+ \subsection{Prototyping}
+
+In \emph{The Mythical Man-Month}, Fredrick Brooks suggests the
+following rule when planning software projects: ``Plan to throw one
+away; you will anyway.''  Brooks is saying that the first attempt at a
+software design often turns out to be wrong; unless the problem is
+very simple or you're an extremely good designer, you'll find that new
+requirements and features become apparent once development has
+actually started.  If these new requirements can't be cleanly
+incorporated into the program's structure, you're presented with two
+unpleasant choices: hammer the new features into the program somehow,
+or scrap everything and write a new version of the program, taking the
+new features into account from the beginning.
+
+Python provides you with a good environment for quickly developing an
+initial prototype.  That lets you get the overall program structure
+and logic right, and you can fine-tune small details in the fast
+development cycle that Python provides.  Once you're satisfied with
+the GUI interface or program output, you can translate the Python code
+into C++, Fortran, Java, or some other compiled language.
+
+Prototyping means you have to be careful not to use too many Python
+features that are hard to implement in your other language.  Using
+\code{eval()}, or regular expressions, or the \module{pickle} module,
+means that you're going to need C or Java libraries for formula
+evaluation, regular expressions, and serialization, for example.  But
+it's not hard to avoid such tricky code, and in the end the
+translation usually isn't very difficult.  The resulting code can be
+rapidly debugged, because any serious logical errors will have been
+removed from the prototype, leaving only more minor slip-ups in the
+translation to track down.  
+
+This strategy builds on the earlier discussion of programmability.
+Using Python as glue to connect lower-level components has obvious
+relevance for constructing prototype systems.  In this way Python can
+help you with development, even if end users never come in contact
+with Python code at all.  If the performance of the Python version is
+adequate and corporate politics allow it, you may not need to do a
+translation into C or Java, but it can still be faster to develop a
+prototype and then translate it, instead of attempting to produce the
+final version immediately.
+
+One example of this development strategy is Microsoft Merchant Server.
+Version 1.0 was written in pure Python, by a company that subsequently
+was purchased by Microsoft.  Version 2.0 began to translate the code
+into \Cpp, shipping with some \Cpp code and some Python code.  Version
+3.0 didn't contain any Python at all; all the code had been translated
+into \Cpp.  Even though the product doesn't contain a Python
+interpreter, the Python language has still served a useful purpose by
+speeding up development.  
+
+This is a very common use for Python.  Past conference papers have
+also described this approach for developing high-level numerical
+algorithms; see David M. Beazley and Peter S. Lomdahl's paper
+``Feeding a Large-scale Physics Application to Python'' in the
+references for a good example.  If an algorithm's basic operations are
+things like "Take the inverse of this 4000x4000 matrix", and are
+implemented in some lower-level language, then Python has almost no
+additional performance cost; the extra time required for Python to
+evaluate an expression like \code{m.invert()} is dwarfed by the cost
+of the actual computation.  It's particularly good for applications
+where seemingly endless tweaking is required to get things right. GUI
+interfaces and Web sites are prime examples.
+
+The Python code is also shorter and faster to write (once you're
+familiar with Python), so it's easier to throw it away if you decide
+your approach was wrong; if you'd spent two weeks working on it
+instead of just two hours, you might waste time trying to patch up
+what you've got out of a natural reluctance to admit that those two
+weeks were wasted.  Truthfully, those two weeks haven't been wasted,
+since you've learnt something about the problem and the technology
+you're using to solve it, but it's human nature to view this as a
+failure of some sort.
+
+ \subsection{Simplicity and Ease of Understanding}
+
+Python is definitely \emph{not} a toy language that's only usable for
+small tasks.  The language features are general and powerful enough to
+enable it to be used for many different purposes.  It's useful at the
+small end, for 10- or 20-line scripts, but it also scales up to larger
+systems that contain thousands of lines of code.
+
+However, this expressiveness doesn't come at the cost of an obscure or
+tricky syntax.  While Python has some dark corners that can lead to
+obscure code, there are relatively few such corners, and proper design
+can isolate their use to only a few classes or modules.  It's
+certainly possible to write confusing code by using too many features
+with too little concern for clarity, but most Python code can look a
+lot like a slightly-formalized version of human-understandable
+pseudocode.
+
+In \emph{The New Hacker's Dictionary}, Eric S. Raymond gives the following
+definition for "compact":
+
+\begin{quotation}
+	Compact \emph{adj.}  Of a design, describes the valuable property
+	that it can all be apprehended at once in one's head. This
+	generally means the thing created from the design can be used
+	with greater facility and fewer errors than an equivalent tool
+	that is not compact. Compactness does not imply triviality or
+	lack of power; for example, C is compact and FORTRAN is not,
+	but C is more powerful than FORTRAN. Designs become
+	non-compact through accreting features and cruft that don't
+	merge cleanly into the overall design scheme (thus, some fans
+	of Classic C maintain that ANSI C is no longer compact).
+\end{quotation}
+
+(From \url{http://www.catb.org/~esr/jargon/html/C/compact.html})
+
+In this sense of the word, Python is quite compact, because the
+language has just a few ideas, which are used in lots of places.  Take
+namespaces, for example.  Import a module with \code{import math}, and
+you create a new namespace called \samp{math}.  Classes are also
+namespaces that share many of the properties of modules, and have a
+few of their own; for example, you can create instances of a class.
+Instances?  They're yet another namespace.  Namespaces are currently
+implemented as Python dictionaries, so they have the same methods as
+the standard dictionary data type: .keys() returns all the keys, and
+so forth.
+
+This simplicity arises from Python's development history.  The
+language syntax derives from different sources; ABC, a relatively
+obscure teaching language, is one primary influence, and Modula-3 is
+another.  (For more information about ABC and Modula-3, consult their
+respective Web sites at \url{http://www.cwi.nl/~steven/abc/} and
+\url{http://www.m3.org}.)  Other features have come from C, Icon,
+Algol-68, and even Perl.  Python hasn't really innovated very much,
+but instead has tried to keep the language small and easy to learn,
+building on ideas that have been tried in other languages and found
+useful.
+
+Simplicity is a virtue that should not be underestimated.  It lets you
+learn the language more quickly, and then rapidly write code, code
+that often works the first time you run it.
+
+ \subsection{Java Integration}
+
+If you're working with Java, Jython
+(\url{http://www.jython.org/}) is definitely worth your
+attention.  Jython is a re-implementation of Python in Java that
+compiles Python code into Java bytecodes.  The resulting environment
+has very tight, almost seamless, integration with Java.  It's trivial
+to access Java classes from Python, and you can write Python classes
+that subclass Java classes.  Jython can be used for prototyping Java
+applications in much the same way CPython is used, and it can also be
+used for test suites for Java code, or embedded in a Java application
+to add scripting capabilities.  
+
+\section{Arguments and Rebuttals}
+
+Let's say that you've decided upon Python as the best choice for your
+application.  How can you convince your management, or your fellow
+developers, to use Python?  This section lists some common arguments
+against using Python, and provides some possible rebuttals.
+
+\emph{Python is freely available software that doesn't cost anything.
+How good can it be?}
+
+Very good, indeed.  These days Linux and Apache, two other pieces of
+open source software, are becoming more respected as alternatives to
+commercial software, but Python hasn't had all the publicity.
+
+Python has been around for several years, with many users and
+developers.  Accordingly, the interpreter has been used by many
+people, and has gotten most of the bugs shaken out of it.  While bugs
+are still discovered at intervals, they're usually either quite
+obscure (they'd have to be, for no one to have run into them before)
+or they involve interfaces to external libraries.  The internals of
+the language itself are quite stable.
+
+Having the source code should be viewed as making the software
+available for peer review; people can examine the code, suggest (and
+implement) improvements, and track down bugs.  To find out more about
+the idea of open source code, along with arguments and case studies
+supporting it, go to \url{http://www.opensource.org}.
+
+\emph{Who's going to support it?}
+
+Python has a sizable community of developers, and the number is still
+growing.  The Internet community surrounding the language is an active
+one, and is worth being considered another one of Python's advantages.
+Most questions posted to the comp.lang.python newsgroup are quickly
+answered by someone.
+
+Should you need to dig into the source code, you'll find it's clear
+and well-organized, so it's not very difficult to write extensions and
+track down bugs yourself.  If you'd prefer to pay for support, there
+are companies and individuals who offer commercial support for Python.
+
+\emph{Who uses Python for serious work?}
+
+Lots of people; one interesting thing about Python is the surprising
+diversity of applications that it's been used for.  People are using
+Python to:
+
+\begin{itemize}
+\item Run Web sites
+\item Write GUI interfaces
+\item Control
+number-crunching code on supercomputers
+\item Make a commercial application scriptable by embedding the Python
+interpreter inside it
+\item Process large XML data sets
+\item Build test suites for C or Java code
+\end{itemize}
+
+Whatever your application domain is, there's probably someone who's
+used Python for something similar.  Yet, despite being useable for
+such high-end applications, Python's still simple enough to use for
+little jobs.
+
+See \url{http://wiki.python.org/moin/OrganizationsUsingPython} for a list of some of the 
+organizations that use Python.
+
+\emph{What are the restrictions on Python's use?}
+
+They're practically nonexistent.  Consult the \file{Misc/COPYRIGHT}
+file in the source distribution, or
+\url{http://www.python.org/doc/Copyright.html} for the full language,
+but it boils down to three conditions.
+
+\begin{itemize}
+
+\item You have to leave the copyright notice on the software; if you
+don't include the source code in a product, you have to put the
+copyright notice in the supporting documentation.  
+
+\item Don't claim that the institutions that have developed Python
+endorse your product in any way.
+
+\item If something goes wrong, you can't sue for damages.  Practically
+all software licences contain this condition.
+
+\end{itemize}
+
+Notice that you don't have to provide source code for anything that
+contains Python or is built with it.  Also, the Python interpreter and
+accompanying documentation can be modified and redistributed in any
+way you like, and you don't have to pay anyone any licensing fees at
+all.
+
+\emph{Why should we use an obscure language like Python instead of
+well-known language X?}
+
+I hope this HOWTO, and the documents listed in the final section, will
+help convince you that Python isn't obscure, and has a healthily
+growing user base.  One word of advice: always present Python's
+positive advantages, instead of concentrating on language X's
+failings.  People want to know why a solution is good, rather than why
+all the other solutions are bad.  So instead of attacking a competing
+solution on various grounds, simply show how Python's virtues can
+help.
+
+
+\section{Useful Resources}
+
+\begin{definitions}
+
+
+\term{\url{http://www.pythonology.com/success}}
+
+The Python Success Stories are a collection of stories from successful
+users of Python, with the emphasis on business and corporate users.
+ 
+%\term{\url{http://www.fsbassociates.com/books/pythonchpt1.htm}}
+
+%The first chapter of \emph{Internet Programming with Python} also
+%examines some of the reasons for using Python.  The book is well worth
+%buying, but the publishers have made the first chapter available on
+%the Web.
+
+\term{\url{http://home.pacbell.net/ouster/scripting.html}}
+ 
+John Ousterhout's white paper on scripting is a good argument for the
+utility of scripting languages, though naturally enough, he emphasizes
+Tcl, the language he developed.  Most of the arguments would apply to
+any scripting language.
+
+\term{\url{http://www.python.org/workshops/1997-10/proceedings/beazley.html}}
+
+The authors, David M. Beazley and Peter S. Lomdahl, 
+describe their use of Python at Los Alamos National Laboratory.
+It's another good example of how Python can help get real work done.
+This quotation from the paper has been echoed by many people:
+
+\begin{quotation}
+       Originally developed as a large monolithic application for
+       massively parallel processing systems, we have used Python to
+       transform our application into a flexible, highly modular, and
+       extremely powerful system for performing simulation, data
+       analysis, and visualization. In addition, we describe how Python
+       has solved a number of important problems related to the
+       development, debugging, deployment, and maintenance of scientific
+       software.
+\end{quotation}
+
+\term{\url{http://pythonjournal.cognizor.com/pyj1/Everitt-Feit_interview98-V1.html}}
+ 
+This interview with Andy Feit, discussing Infoseek's use of Python, can be
+used to show that choosing Python didn't introduce any difficulties
+into a company's development process, and provided some substantial benefits.
+
+%\term{\url{http://www.python.org/psa/Commercial.html}} 
+
+%Robin Friedrich wrote this document on how to support Python's use in
+%commercial projects.
+
+\term{\url{http://www.python.org/workshops/1997-10/proceedings/stein.ps}}
+
+For the 6th Python conference, Greg Stein presented a paper that
+traced Python's adoption and usage at a startup called eShop, and
+later at Microsoft.
+
+\term{\url{http://www.opensource.org}} 
+
+Management may be doubtful of the reliability and usefulness of
+software that wasn't written commercially.  This site presents
+arguments that show how open source software can have considerable
+advantages over closed-source software.
+
+\term{\url{http://sunsite.unc.edu/LDP/HOWTO/mini/Advocacy.html}}
+
+The Linux Advocacy mini-HOWTO was the inspiration for this document,
+and is also well worth reading for general suggestions on winning
+acceptance for a new technology, such as Linux or Python.  In general,
+you won't make much progress by simply attacking existing systems and
+complaining about their inadequacies; this often ends up looking like
+unfocused whining.  It's much better to point out some of the many
+areas where Python is an improvement over other systems.  
+
+\end{definitions}
+
+\end{document}
+
+

Added: vendor/Python/current/Doc/howto/curses.tex
===================================================================
--- vendor/Python/current/Doc/howto/curses.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/howto/curses.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,485 @@
+\documentclass{howto}
+
+\title{Curses Programming with Python}
+
+\release{2.01}
+
+\author{A.M. Kuchling, Eric S. Raymond}
+\authoraddress{\email{amk at amk.ca}, \email{esr at thyrsus.com}}
+
+\begin{document}
+\maketitle
+
+\begin{abstract}
+\noindent
+This document describes how to write text-mode programs with Python 2.x,
+using the \module{curses} extension module to control the display.   
+
+This document is available from the Python HOWTO page at
+\url{http://www.python.org/doc/howto}.
+\end{abstract}
+
+\tableofcontents
+
+\section{What is curses?}
+
+The curses library supplies a terminal-independent screen-painting and
+keyboard-handling facility for text-based terminals; such terminals
+include VT100s, the Linux console, and the simulated terminal provided
+by X11 programs such as xterm and rxvt.  Display terminals support
+various control codes to perform common operations such as moving the
+cursor, scrolling the screen, and erasing areas.  Different terminals
+use widely differing codes, and often have their own minor quirks.
+
+In a world of X displays, one might ask ``why bother''?  It's true
+that character-cell display terminals are an obsolete technology, but
+there are niches in which being able to do fancy things with them are
+still valuable.  One is on small-footprint or embedded Unixes that 
+don't carry an X server.  Another is for tools like OS installers
+and kernel configurators that may have to run before X is available.
+
+The curses library hides all the details of different terminals, and
+provides the programmer with an abstraction of a display, containing
+multiple non-overlapping windows.  The contents of a window can be
+changed in various ways--adding text, erasing it, changing its
+appearance--and the curses library will automagically figure out what
+control codes need to be sent to the terminal to produce the right
+output.
+
+The curses library was originally written for BSD Unix; the later System V
+versions of Unix from AT\&T added many enhancements and new functions.
+BSD curses is no longer maintained, having been replaced by ncurses,
+which is an open-source implementation of the AT\&T interface.  If you're
+using an open-source Unix such as Linux or FreeBSD, your system almost
+certainly uses ncurses.  Since most current commercial Unix versions
+are based on System V code, all the functions described here will
+probably be available.  The older versions of curses carried by some
+proprietary Unixes may not support everything, though.
+
+No one has made a Windows port of the curses module.  On a Windows
+platform, try the Console module written by Fredrik Lundh.  The
+Console module provides cursor-addressable text output, plus full
+support for mouse and keyboard input, and is available from
+\url{http://effbot.org/efflib/console}.
+
+\subsection{The Python curses module}
+
+Thy Python module is a fairly simple wrapper over the C functions
+provided by curses; if you're already familiar with curses programming
+in C, it's really easy to transfer that knowledge to Python.  The
+biggest difference is that the Python interface makes things simpler,
+by merging different C functions such as \function{addstr},
+\function{mvaddstr}, \function{mvwaddstr}, into a single
+\method{addstr()} method.  You'll see this covered in more detail
+later.
+
+This HOWTO is simply an introduction to writing text-mode programs
+with curses and Python. It doesn't attempt to be a complete guide to
+the curses API; for that, see the Python library guide's section on
+ncurses, and the C manual pages for ncurses.  It will, however, give
+you the basic ideas.
+
+\section{Starting and ending a curses application}
+
+Before doing anything, curses must be initialized.  This is done by
+calling the \function{initscr()} function, which will determine the
+terminal type, send any required setup codes to the terminal, and
+create various internal data structures.  If successful,
+\function{initscr()} returns a window object representing the entire
+screen; this is usually called \code{stdscr}, after the name of the
+corresponding C
+variable.
+
+\begin{verbatim}
+import curses
+stdscr = curses.initscr()
+\end{verbatim}
+
+Usually curses applications turn off automatic echoing of keys to the
+screen, in order to be able to read keys and only display them under
+certain circumstances.  This requires calling the \function{noecho()}
+function.
+
+\begin{verbatim}
+curses.noecho()
+\end{verbatim}
+
+Applications will also commonly need to react to keys instantly,
+without requiring the Enter key to be pressed; this is called cbreak
+mode, as opposed to the usual buffered input mode.
+
+\begin{verbatim}
+curses.cbreak()
+\end{verbatim}
+
+Terminals usually return special keys, such as the cursor keys or
+navigation keys such as Page Up and Home, as a multibyte escape
+sequence.  While you could write your application to expect such
+sequences and process them accordingly, curses can do it for you,
+returning a special value such as \constant{curses.KEY_LEFT}.  To get
+curses to do the job, you'll have to enable keypad mode.
+
+\begin{verbatim}
+stdscr.keypad(1)
+\end{verbatim}
+
+Terminating a curses application is much easier than starting one.
+You'll need to call 
+
+\begin{verbatim}
+curses.nocbreak(); stdscr.keypad(0); curses.echo()
+\end{verbatim}
+
+to reverse the curses-friendly terminal settings. Then call the
+\function{endwin()} function to restore the terminal to its original
+operating mode.
+
+\begin{verbatim}
+curses.endwin()
+\end{verbatim}
+
+A common problem when debugging a curses application is to get your
+terminal messed up when the application dies without restoring the
+terminal to its previous state.  In Python this commonly happens when
+your code is buggy and raises an uncaught exception.  Keys are no
+longer be echoed to the screen when you type them, for example, which
+makes using the shell difficult.
+
+In Python you can avoid these complications and make debugging much
+easier by importing the module \module{curses.wrapper}.  It supplies a
+function \function{wrapper} that takes a hook argument.  It does the
+initializations described above, and also initializes colors if color
+support is present.  It then runs your hook, and then finally
+deinitializes appropriately.  The hook is called inside a try-catch
+clause which catches exceptions, performs curses deinitialization, and
+then passes the exception upwards.  Thus, your terminal won't be left
+in a funny state on exception.
+
+\section{Windows and Pads}
+
+Windows are the basic abstraction in curses.  A window object
+represents a rectangular area of the screen, and supports various
+ methods to display text, erase it, allow the user to input strings,
+and so forth.
+
+The \code{stdscr} object returned by the \function{initscr()} function
+is a window object that covers the entire screen.  Many programs may
+need only this single window, but you might wish to divide the screen
+into smaller windows, in order to redraw or clear them separately.
+The \function{newwin()} function creates a new window of a given size,
+returning the new window object.
+
+\begin{verbatim}
+begin_x = 20 ; begin_y = 7
+height = 5 ; width = 40
+win = curses.newwin(height, width, begin_y, begin_x)
+\end{verbatim}
+
+A word about the coordinate system used in curses: coordinates are
+always passed in the order \emph{y,x}, and the top-left corner of a
+window is coordinate (0,0).  This breaks a common convention for
+handling coordinates, where the \emph{x} coordinate usually comes
+first.  This is an unfortunate difference from most other computer
+applications, but it's been part of curses since it was first written,
+and it's too late to change things now.
+
+When you call a method to display or erase text, the effect doesn't
+immediately show up on the display.  This is because curses was
+originally written with slow 300-baud terminal connections in mind;
+with these terminals, minimizing the time required to redraw the
+screen is very important.  This lets curses accumulate changes to the
+screen, and display them in the most efficient manner.  For example,
+if your program displays some characters in a window, and then clears
+the window, there's no need to send the original characters because
+they'd never be visible.  
+
+Accordingly, curses requires that you explicitly tell it to redraw
+windows, using the \function{refresh()} method of window objects.  In
+practice, this doesn't really complicate programming with curses much.
+Most programs go into a flurry of activity, and then pause waiting for
+a keypress or some other action on the part of the user.  All you have
+to do is to be sure that the screen has been redrawn before pausing to
+wait for user input, by simply calling \code{stdscr.refresh()} or the
+\function{refresh()} method of some other relevant window.
+
+A pad is a special case of a window; it can be larger than the actual
+display screen, and only a portion of it displayed at a time.
+Creating a pad simply requires the pad's height and width, while
+refreshing a pad requires giving the coordinates of the on-screen
+area where a subsection of the pad will be displayed.  
+
+\begin{verbatim}
+pad = curses.newpad(100, 100)
+#  These loops fill the pad with letters; this is
+# explained in the next section
+for y in range(0, 100):
+    for x in range(0, 100):
+        try: pad.addch(y,x, ord('a') + (x*x+y*y) % 26 )
+        except curses.error: pass
+
+#  Displays a section of the pad in the middle of the screen
+pad.refresh( 0,0, 5,5, 20,75)
+\end{verbatim}
+
+The \function{refresh()} call displays a section of the pad in the
+rectangle extending from coordinate (5,5) to coordinate (20,75) on the
+screen;the upper left corner of the displayed section is coordinate
+(0,0) on the pad.  Beyond that difference, pads are exactly like
+ordinary windows and support the same methods.
+
+If you have multiple windows and pads on screen there is a more
+efficient way to go, which will prevent annoying screen flicker at
+refresh time.  Use the methods \method{noutrefresh()} and/or
+\method{noutrefresh()} of each window to update the data structure
+representing the desired state of the screen; then change the physical
+screen to match the desired state in one go with the function
+\function{doupdate()}.  The normal \method{refresh()} method calls
+\function{doupdate()} as its last act.
+
+\section{Displaying Text}
+
+{}From a C programmer's point of view, curses may sometimes look like
+a twisty maze of functions, all subtly different.  For example,
+\function{addstr()} displays a string at the current cursor location
+in the \code{stdscr} window, while \function{mvaddstr()} moves to a
+given y,x coordinate first before displaying the string.
+\function{waddstr()} is just like \function{addstr()}, but allows
+specifying a window to use, instead of using \code{stdscr} by default.
+\function{mvwaddstr()} follows similarly.
+
+Fortunately the Python interface hides all these details;
+\code{stdscr} is a window object like any other, and methods like
+\function{addstr()} accept multiple argument forms.  Usually there are
+four different forms.
+
+\begin{tableii}{|c|l|}{textrm}{Form}{Description}
+\lineii{\var{str} or \var{ch}}{Display the string \var{str} or
+character \var{ch}}
+\lineii{\var{str} or \var{ch}, \var{attr}}{Display the string \var{str} or
+character \var{ch}, using attribute \var{attr}}
+\lineii{\var{y}, \var{x}, \var{str} or \var{ch}}
+{Move to position \var{y,x} within the window, and display \var{str}
+or \var{ch}}
+\lineii{\var{y}, \var{x}, \var{str} or \var{ch}, \var{attr}}
+{Move to position \var{y,x} within the window, and display \var{str}
+or \var{ch}, using attribute \var{attr}}
+\end{tableii}
+
+Attributes allow displaying text in highlighted forms, such as in
+boldface, underline, reverse code, or in color.  They'll be explained
+in more detail in the next subsection.
+
+The \function{addstr()} function takes a Python string as the value to
+be displayed, while the \function{addch()} functions take a character,
+which can be either a Python string of length 1, or an integer.  If
+it's a string, you're limited to displaying characters between 0 and
+255.  SVr4 curses provides constants for extension characters; these
+constants are integers greater than 255.  For example,
+\constant{ACS_PLMINUS} is a +/- symbol, and \constant{ACS_ULCORNER} is
+the upper left corner of a box (handy for drawing borders).
+
+Windows remember where the cursor was left after the last operation,
+so if you leave out the \var{y,x} coordinates, the string or character
+will be displayed wherever the last operation left off.  You can also
+move the cursor with the \function{move(\var{y,x})} method.  Because
+some terminals always display a flashing cursor, you may want to
+ensure that the cursor is positioned in some location where it won't
+be distracting; it can be confusing to have the cursor blinking at
+some apparently random location.  
+
+If your application doesn't need a blinking cursor at all, you can
+call \function{curs_set(0)} to make it invisible.  Equivalently, and
+for compatibility with older curses versions, there's a
+\function{leaveok(\var{bool})} function.  When \var{bool} is true, the
+curses library will attempt to suppress the flashing cursor, and you
+won't need to worry about leaving it in odd locations.
+
+\subsection{Attributes and Color}
+
+Characters can be displayed in different ways.  Status lines in a
+text-based application are commonly shown in reverse video; a text
+viewer may need to highlight certain words.  curses supports this by
+allowing you to specify an attribute for each cell on the screen.
+
+An attribute is a integer, each bit representing a different
+attribute.  You can try to display text with multiple attribute bits
+set, but curses doesn't guarantee that all the possible combinations
+are available, or that they're all visually distinct.  That depends on
+the ability of the terminal being used, so it's safest to stick to the
+most commonly available attributes, listed here.
+
+\begin{tableii}{|c|l|}{constant}{Attribute}{Description}
+\lineii{A_BLINK}{Blinking text}
+\lineii{A_BOLD}{Extra bright or bold text}
+\lineii{A_DIM}{Half bright text}
+\lineii{A_REVERSE}{Reverse-video text}
+\lineii{A_STANDOUT}{The best highlighting mode available}
+\lineii{A_UNDERLINE}{Underlined text}
+\end{tableii}
+
+So, to display a reverse-video status line on the top line of the
+screen,
+you could code:
+
+\begin{verbatim}
+stdscr.addstr(0, 0, "Current mode: Typing mode",
+	      curses.A_REVERSE)
+stdscr.refresh()
+\end{verbatim}
+
+The curses library also supports color on those terminals that
+provide it, The most common such terminal is probably the Linux
+console, followed by color xterms.
+
+To use color, you must call the \function{start_color()} function
+soon after calling \function{initscr()}, to initialize the default
+color set (the \function{curses.wrapper.wrapper()} function does this
+automatically).  Once that's done, the \function{has_colors()}
+function returns TRUE if the terminal in use can actually display
+color.  (Note from AMK:  curses uses the American spelling
+'color', instead of the Canadian/British spelling 'colour'.  If you're
+like me, you'll have to resign yourself to misspelling it for the sake
+of these functions.)
+
+The curses library maintains a finite number of color pairs,
+containing a foreground (or text) color and a background color.  You
+can get the attribute value corresponding to a color pair with the
+\function{color_pair()} function; this can be bitwise-OR'ed with other
+attributes such as \constant{A_REVERSE}, but again, such combinations
+are not guaranteed to work on all terminals.
+
+An example, which displays a line of text using color pair 1:
+
+\begin{verbatim}
+stdscr.addstr( "Pretty text", curses.color_pair(1) )
+stdscr.refresh()
+\end{verbatim}
+
+As I said before, a color pair consists of a foreground and
+background color.  \function{start_color()} initializes 8 basic
+colors when it activates color mode.  They are: 0:black, 1:red,
+2:green, 3:yellow, 4:blue, 5:magenta, 6:cyan, and 7:white.  The curses
+module defines named constants for each of these colors:
+\constant{curses.COLOR_BLACK}, \constant{curses.COLOR_RED}, and so
+forth.
+
+The \function{init_pair(\var{n, f, b})} function changes the
+definition of color pair \var{n}, to foreground color {f} and
+background color {b}.  Color pair 0 is hard-wired to white on black,
+and cannot be changed.  
+
+Let's put all this together. To change color 1 to red
+text on a white background, you would call:
+
+\begin{verbatim}
+curses.init_pair(1, curses.COLOR_RED, curses.COLOR_WHITE)
+\end{verbatim}
+
+When you change a color pair, any text already displayed using that
+color pair will change to the new colors.  You can also display new
+text in this color with:
+
+\begin{verbatim}
+stdscr.addstr(0,0, "RED ALERT!", curses.color_pair(1) )
+\end{verbatim}
+
+Very fancy terminals can change the definitions of the actual colors
+to a given RGB value.  This lets you change color 1, which is usually
+red, to purple or blue or any other color you like.  Unfortunately,
+the Linux console doesn't support this, so I'm unable to try it out,
+and can't provide any examples.  You can check if your terminal can do
+this by calling \function{can_change_color()}, which returns TRUE if
+the capability is there.  If you're lucky enough to have such a
+talented terminal, consult your system's man pages for more
+information.
+
+\section{User Input}
+
+The curses library itself offers only very simple input mechanisms.
+Python's support adds a text-input widget that makes up some of the
+lack.
+
+The most common way to get input to a window is to use its
+\method{getch()} method. that pauses, and waits for the user to hit
+a key, displaying it if \function{echo()} has been called earlier.
+You can optionally specify a coordinate to which the cursor should be
+moved before pausing.
+
+It's possible to change this behavior with the method
+\method{nodelay()}. After \method{nodelay(1)}, \method{getch()} for
+the window becomes non-blocking and returns ERR (-1) when no input is
+ready.  There's also a \function{halfdelay()} function, which can be
+used to (in effect) set a timer on each \method{getch()}; if no input
+becomes available within the number of milliseconds specified as the
+argument to \function{halfdelay()}, curses throws an exception.
+
+The \method{getch()} method returns an integer; if it's between 0 and
+255, it represents the ASCII code of the key pressed.  Values greater
+than 255 are special keys such as Page Up, Home, or the cursor keys.
+You can compare the value returned to constants such as
+\constant{curses.KEY_PPAGE}, \constant{curses.KEY_HOME}, or
+\constant{curses.KEY_LEFT}.  Usually the main loop of your program
+will look something like this:
+
+\begin{verbatim}
+while 1:
+    c = stdscr.getch()
+    if c == ord('p'): PrintDocument()
+    elif c == ord('q'): break  # Exit the while()
+    elif c == curses.KEY_HOME: x = y = 0
+\end{verbatim}
+
+The \module{curses.ascii} module supplies ASCII class membership
+functions that take either integer or 1-character-string
+arguments; these may be useful in writing more readable tests for
+your command interpreters.  It also supplies conversion functions 
+that take either integer or 1-character-string arguments and return
+the same type.  For example, \function{curses.ascii.ctrl()} returns
+the control character corresponding to its argument.
+
+There's also a method to retrieve an entire string,
+\constant{getstr()}.  It isn't used very often, because its
+functionality is quite limited; the only editing keys available are
+the backspace key and the Enter key, which terminates the string.  It
+can optionally be limited to a fixed number of characters.
+
+\begin{verbatim}
+curses.echo()            # Enable echoing of characters
+
+# Get a 15-character string, with the cursor on the top line 
+s = stdscr.getstr(0,0, 15)  
+\end{verbatim}
+
+The Python \module{curses.textpad} module supplies something better.
+With it, you can turn a window into a text box that supports an
+Emacs-like set of keybindings.  Various methods of \class{Textbox}
+class support editing with input validation and gathering the edit
+results either with or without trailing spaces.   See the library
+documentation on \module{curses.textpad} for the details.
+
+\section{For More Information}
+
+This HOWTO didn't cover some advanced topics, such as screen-scraping
+or capturing mouse events from an xterm instance.  But the Python
+library page for the curses modules is now pretty complete.  You
+should browse it next.
+
+If you're in doubt about the detailed behavior of any of the ncurses
+entry points, consult the manual pages for your curses implementation,
+whether it's ncurses or a proprietary Unix vendor's.  The manual pages
+will document any quirks, and provide complete lists of all the
+functions, attributes, and \constant{ACS_*} characters available to
+you.
+
+Because the curses API is so large, some functions aren't supported in
+the Python interface, not because they're difficult to implement, but
+because no one has needed them yet.  Feel free to add them and then
+submit a patch.  Also, we don't yet have support for the menus or
+panels libraries associated with ncurses; feel free to add that.
+
+If you write an interesting little program, feel free to contribute it
+as another demo.  We can always use more of them!
+
+The ncurses FAQ: \url{http://dickey.his.com/ncurses/ncurses.faq.html}
+
+\end{document}

Added: vendor/Python/current/Doc/howto/doanddont.tex
===================================================================
--- vendor/Python/current/Doc/howto/doanddont.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/howto/doanddont.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,344 @@
+\documentclass{howto}
+
+\title{Idioms and Anti-Idioms in Python}
+
+\release{0.00}
+
+\author{Moshe Zadka}
+\authoraddress{howto at zadka.site.co.il}
+
+\begin{document}
+\maketitle
+
+This document is placed in the public doman.
+
+\begin{abstract}
+\noindent
+This document can be considered a companion to the tutorial. It
+shows how to use Python, and even more importantly, how {\em not}
+to use Python. 
+\end{abstract}
+
+\tableofcontents
+
+\section{Language Constructs You Should Not Use}
+
+While Python has relatively few gotchas compared to other languages, it
+still has some constructs which are only useful in corner cases, or are
+plain dangerous. 
+
+\subsection{from module import *}
+
+\subsubsection{Inside Function Definitions}
+
+\code{from module import *} is {\em invalid} inside function definitions.
+While many versions of Python do no check for the invalidity, it does not
+make it more valid, no more then having a smart lawyer makes a man innocent.
+Do not use it like that ever. Even in versions where it was accepted, it made
+the function execution slower, because the compiler could not be certain
+which names are local and which are global. In Python 2.1 this construct
+causes warnings, and sometimes even errors.
+
+\subsubsection{At Module Level}
+
+While it is valid to use \code{from module import *} at module level it
+is usually a bad idea. For one, this loses an important property Python
+otherwise has --- you can know where each toplevel name is defined by
+a simple "search" function in your favourite editor. You also open yourself
+to trouble in the future, if some module grows additional functions or
+classes. 
+
+One of the most awful question asked on the newsgroup is why this code:
+
+\begin{verbatim}
+f = open("www")
+f.read()
+\end{verbatim}
+
+does not work. Of course, it works just fine (assuming you have a file
+called "www".) But it does not work if somewhere in the module, the
+statement \code{from os import *} is present. The \module{os} module
+has a function called \function{open()} which returns an integer. While
+it is very useful, shadowing builtins is one of its least useful properties.
+
+Remember, you can never know for sure what names a module exports, so either
+take what you need --- \code{from module import name1, name2}, or keep them in
+the module and access on a per-need basis --- 
+\code{import module;print module.name}.
+
+\subsubsection{When It Is Just Fine}
+
+There are situations in which \code{from module import *} is just fine:
+
+\begin{itemize}
+
+\item The interactive prompt. For example, \code{from math import *} makes
+      Python an amazing scientific calculator.
+
+\item When extending a module in C with a module in Python.
+
+\item When the module advertises itself as \code{from import *} safe.
+
+\end{itemize}
+
+\subsection{Unadorned \keyword{exec}, \function{execfile} and friends}
+
+The word ``unadorned'' refers to the use without an explicit dictionary,
+in which case those constructs evaluate code in the {\em current} environment.
+This is dangerous for the same reasons \code{from import *} is dangerous ---
+it might step over variables you are counting on and mess up things for
+the rest of your code. Simply do not do that.
+
+Bad examples:
+
+\begin{verbatim}
+>>> for name in sys.argv[1:]:
+>>>     exec "%s=1" % name
+>>> def func(s, **kw):
+>>>     for var, val in kw.items():
+>>>         exec "s.%s=val" % var  # invalid!
+>>> execfile("handler.py")
+>>> handle()
+\end{verbatim}
+
+Good examples:
+
+\begin{verbatim}
+>>> d = {}
+>>> for name in sys.argv[1:]:
+>>>     d[name] = 1
+>>> def func(s, **kw):
+>>>     for var, val in kw.items():
+>>>         setattr(s, var, val)
+>>> d={}
+>>> execfile("handle.py", d, d)
+>>> handle = d['handle']
+>>> handle()
+\end{verbatim}
+
+\subsection{from module import name1, name2}
+
+This is a ``don't'' which is much weaker then the previous ``don't''s
+but is still something you should not do if you don't have good reasons
+to do that. The reason it is usually bad idea is because you suddenly
+have an object which lives in two seperate namespaces. When the binding
+in one namespace changes, the binding in the other will not, so there
+will be a discrepancy between them. This happens when, for example,
+one module is reloaded, or changes the definition of a function at runtime. 
+
+Bad example:
+
+\begin{verbatim}
+# foo.py
+a = 1
+
+# bar.py
+from foo import a
+if something():
+    a = 2 # danger: foo.a != a 
+\end{verbatim}
+
+Good example:
+
+\begin{verbatim}
+# foo.py
+a = 1
+
+# bar.py
+import foo
+if something():
+    foo.a = 2
+\end{verbatim}
+
+\subsection{except:}
+
+Python has the \code{except:} clause, which catches all exceptions.
+Since {\em every} error in Python raises an exception, this makes many
+programming errors look like runtime problems, and hinders
+the debugging process.
+
+The following code shows a great example:
+
+\begin{verbatim}
+try:
+    foo = opne("file") # misspelled "open"
+except:
+    sys.exit("could not open file!")
+\end{verbatim}
+
+The second line triggers a \exception{NameError} which is caught by the
+except clause. The program will exit, and you will have no idea that
+this has nothing to do with the readability of \code{"file"}.
+
+The example above is better written
+
+\begin{verbatim}
+try:
+    foo = opne("file") # will be changed to "open" as soon as we run it
+except IOError:
+    sys.exit("could not open file")
+\end{verbatim}
+
+There are some situations in which the \code{except:} clause is useful:
+for example, in a framework when running callbacks, it is good not to
+let any callback disturb the framework.
+
+\section{Exceptions}
+
+Exceptions are a useful feature of Python. You should learn to raise
+them whenever something unexpected occurs, and catch them only where
+you can do something about them.
+
+The following is a very popular anti-idiom
+
+\begin{verbatim}
+def get_status(file):
+    if not os.path.exists(file):
+        print "file not found"
+        sys.exit(1)
+    return open(file).readline()
+\end{verbatim}
+
+Consider the case the file gets deleted between the time the call to 
+\function{os.path.exists} is made and the time \function{open} is called.
+That means the last line will throw an \exception{IOError}. The same would
+happen if \var{file} exists but has no read permission. Since testing this
+on a normal machine on existing and non-existing files make it seem bugless,
+that means in testing the results will seem fine, and the code will get
+shipped. Then an unhandled \exception{IOError} escapes to the user, who
+has to watch the ugly traceback.
+
+Here is a better way to do it.
+
+\begin{verbatim}
+def get_status(file):
+    try:
+        return open(file).readline()
+    except (IOError, OSError):
+        print "file not found"
+        sys.exit(1)
+\end{verbatim}
+
+In this version, *either* the file gets opened and the line is read
+(so it works even on flaky NFS or SMB connections), or the message
+is printed and the application aborted.
+
+Still, \function{get_status} makes too many assumptions --- that it
+will only be used in a short running script, and not, say, in a long
+running server. Sure, the caller could do something like
+
+\begin{verbatim}
+try:
+    status = get_status(log)
+except SystemExit:
+    status = None
+\end{verbatim}
+
+So, try to make as few \code{except} clauses in your code --- those will
+usually be a catch-all in the \function{main}, or inside calls which
+should always succeed.
+
+So, the best version is probably
+
+\begin{verbatim}
+def get_status(file):
+    return open(file).readline()
+\end{verbatim}
+
+The caller can deal with the exception if it wants (for example, if it 
+tries several files in a loop), or just let the exception filter upwards
+to {\em its} caller.
+
+The last version is not very good either --- due to implementation details,
+the file would not be closed when an exception is raised until the handler
+finishes, and perhaps not at all in non-C implementations (e.g., Jython).
+
+\begin{verbatim}
+def get_status(file):
+    fp = open(file)
+    try:
+        return fp.readline()
+    finally:
+        fp.close()
+\end{verbatim}
+
+\section{Using the Batteries}
+
+Every so often, people seem to be writing stuff in the Python library
+again, usually poorly. While the occasional module has a poor interface,
+it is usually much better to use the rich standard library and data
+types that come with Python then inventing your own.
+
+A useful module very few people know about is \module{os.path}. It 
+always has the correct path arithmetic for your operating system, and
+will usually be much better then whatever you come up with yourself.
+
+Compare:
+
+\begin{verbatim}
+# ugh!
+return dir+"/"+file
+# better
+return os.path.join(dir, file)
+\end{verbatim}
+
+More useful functions in \module{os.path}: \function{basename}, 
+\function{dirname} and \function{splitext}.
+
+There are also many useful builtin functions people seem not to be
+aware of for some reason: \function{min()} and \function{max()} can
+find the minimum/maximum of any sequence with comparable semantics,
+for example, yet many people write their own
+\function{max()}/\function{min()}. Another highly useful function is
+\function{reduce()}. A classical use of \function{reduce()}
+is something like
+
+\begin{verbatim}
+import sys, operator
+nums = map(float, sys.argv[1:])
+print reduce(operator.add, nums)/len(nums)
+\end{verbatim}
+
+This cute little script prints the average of all numbers given on the
+command line. The \function{reduce()} adds up all the numbers, and
+the rest is just some pre- and postprocessing.
+
+On the same note, note that \function{float()}, \function{int()} and
+\function{long()} all accept arguments of type string, and so are
+suited to parsing --- assuming you are ready to deal with the
+\exception{ValueError} they raise.
+
+\section{Using Backslash to Continue Statements}
+
+Since Python treats a newline as a statement terminator,
+and since statements are often more then is comfortable to put
+in one line, many people do:
+
+\begin{verbatim}
+if foo.bar()['first'][0] == baz.quux(1, 2)[5:9] and \
+   calculate_number(10, 20) != forbulate(500, 360):
+      pass
+\end{verbatim}
+
+You should realize that this is dangerous: a stray space after the
+\code{\\} would make this line wrong, and stray spaces are notoriously
+hard to see in editors. In this case, at least it would be a syntax
+error, but if the code was:
+
+\begin{verbatim}
+value = foo.bar()['first'][0]*baz.quux(1, 2)[5:9] \
+        + calculate_number(10, 20)*forbulate(500, 360)
+\end{verbatim}
+
+then it would just be subtly wrong.
+
+It is usually much better to use the implicit continuation inside parenthesis:
+
+This version is bulletproof:
+
+\begin{verbatim}
+value = (foo.bar()['first'][0]*baz.quux(1, 2)[5:9] 
+        + calculate_number(10, 20)*forbulate(500, 360))
+\end{verbatim}
+
+\end{document}

Added: vendor/Python/current/Doc/howto/regex.tex
===================================================================
--- vendor/Python/current/Doc/howto/regex.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/howto/regex.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1463 @@
+\documentclass{howto}
+
+% TODO:
+% Document lookbehind assertions
+% Better way of displaying a RE, a string, and what it matches
+% Mention optional argument to match.groups()
+% Unicode (at least a reference)
+
+\title{Regular Expression HOWTO}
+
+\release{0.05}
+
+\author{A.M. Kuchling}
+\authoraddress{\email{amk at amk.ca}}
+
+\begin{document}
+\maketitle
+
+\begin{abstract}
+\noindent
+This document is an introductory tutorial to using regular expressions
+in Python with the \module{re} module.  It provides a gentler
+introduction than the corresponding section in the Library Reference.
+
+This document is available from 
+\url{http://www.amk.ca/python/howto}.
+
+\end{abstract}
+
+\tableofcontents
+
+\section{Introduction}
+
+The \module{re} module was added in Python 1.5, and provides
+Perl-style regular expression patterns.  Earlier versions of Python
+came with the \module{regex} module, which provided Emacs-style
+patterns.  \module{regex} module was removed in Python 2.5.
+
+Regular expressions (or REs) are essentially a tiny, highly
+specialized programming language embedded inside Python and made
+available through the \module{re} module.  Using this little language,
+you specify the rules for the set of possible strings that you want to
+match; this set might contain English sentences, or e-mail addresses,
+or TeX commands, or anything you like.  You can then ask questions
+such as ``Does this string match the pattern?'', or ``Is there a match
+for the pattern anywhere in this string?''.  You can also use REs to
+modify a string or to split it apart in various ways.
+
+Regular expression patterns are compiled into a series of bytecodes
+which are then executed by a matching engine written in C.  For
+advanced use, it may be necessary to pay careful attention to how the
+engine will execute a given RE, and write the RE in a certain way in
+order to produce bytecode that runs faster.  Optimization isn't
+covered in this document, because it requires that you have a good
+understanding of the matching engine's internals.
+
+The regular expression language is relatively small and restricted, so
+not all possible string processing tasks can be done using regular
+expressions.  There are also tasks that \emph{can} be done with
+regular expressions, but the expressions turn out to be very
+complicated.  In these cases, you may be better off writing Python
+code to do the processing; while Python code will be slower than an
+elaborate regular expression, it will also probably be more understandable.
+
+\section{Simple Patterns}
+
+We'll start by learning about the simplest possible regular
+expressions.  Since regular expressions are used to operate on
+strings, we'll begin with the most common task: matching characters.
+
+For a detailed explanation of the computer science underlying regular
+expressions (deterministic and non-deterministic finite automata), you
+can refer to almost any textbook on writing compilers.
+
+\subsection{Matching Characters}
+
+Most letters and characters will simply match themselves.  For
+example, the regular expression \regexp{test} will match the string
+\samp{test} exactly.  (You can enable a case-insensitive mode that
+would let this RE match \samp{Test} or \samp{TEST} as well; more
+about this later.)  
+
+There are exceptions to this rule; some characters are
+special, and don't match themselves.  Instead, they signal that some
+out-of-the-ordinary thing should be matched, or they affect other
+portions of the RE by repeating them.  Much of this document is
+devoted to discussing various metacharacters and what they do.
+
+Here's a complete list of the metacharacters; their meanings will be
+discussed in the rest of this HOWTO.
+
+\begin{verbatim}
+. ^ $ * + ? { [ ] \ | ( )
+\end{verbatim}
+% $
+
+The first metacharacters we'll look at are \samp{[} and \samp{]}.
+They're used for specifying a character class, which is a set of
+characters that you wish to match.  Characters can be listed
+individually, or a range of characters can be indicated by giving two
+characters and separating them by a \character{-}.  For example,
+\regexp{[abc]} will match any of the characters \samp{a}, \samp{b}, or
+\samp{c}; this is the same as
+\regexp{[a-c]}, which uses a range to express the same set of
+characters.  If you wanted to match only lowercase letters, your
+RE would be \regexp{[a-z]}.
+
+Metacharacters are not active inside classes.  For example,
+\regexp{[akm\$]} will match any of the characters \character{a},
+\character{k}, \character{m}, or \character{\$}; \character{\$} is
+usually a metacharacter, but inside a character class it's stripped of
+its special nature.
+
+You can match the characters not within a range by \dfn{complementing}
+the set.  This is indicated by including a \character{\^} as the first
+character of the class; \character{\^} elsewhere will simply match the
+\character{\^} character.  For example, \verb|[^5]| will match any
+character except \character{5}.
+
+Perhaps the most important metacharacter is the backslash, \samp{\e}.  
+As in Python string literals, the backslash can be followed by various
+characters to signal various special sequences.  It's also used to escape
+all the metacharacters so you can still match them in patterns; for
+example, if you need to match a \samp{[} or 
+\samp{\e}, you can precede them with a backslash to remove their
+special meaning: \regexp{\e[} or \regexp{\e\e}.
+
+Some of the special sequences beginning with \character{\e} represent
+predefined sets of characters that are often useful, such as the set
+of digits, the set of letters, or the set of anything that isn't
+whitespace.  The following predefined special sequences are available:
+
+\begin{itemize}
+\item[\code{\e d}]Matches any decimal digit; this is
+equivalent to the class \regexp{[0-9]}.
+
+\item[\code{\e D}]Matches any non-digit character; this is
+equivalent to the class \verb|[^0-9]|.
+
+\item[\code{\e s}]Matches any whitespace character; this is
+equivalent to the class \regexp{[ \e t\e n\e r\e f\e v]}.
+
+\item[\code{\e S}]Matches any non-whitespace character; this is
+equivalent to the class \verb|[^ \t\n\r\f\v]|.
+
+\item[\code{\e w}]Matches any alphanumeric character; this is equivalent to the class
+\regexp{[a-zA-Z0-9_]}.  
+
+\item[\code{\e W}]Matches any non-alphanumeric character; this is equivalent to the class
+\verb|[^a-zA-Z0-9_]|.   
+\end{itemize}
+
+These sequences can be included inside a character class.  For
+example, \regexp{[\e s,.]} is a character class that will match any
+whitespace character, or \character{,} or \character{.}.
+
+The final metacharacter in this section is \regexp{.}.  It matches
+anything except a newline character, and there's an alternate mode
+(\code{re.DOTALL}) where it will match even a newline.  \character{.}
+is often used where you want to match ``any character''.  
+
+\subsection{Repeating Things}
+
+Being able to match varying sets of characters is the first thing
+regular expressions can do that isn't already possible with the
+methods available on strings.  However, if that was the only
+additional capability of regexes, they wouldn't be much of an advance.
+Another capability is that you can specify that portions of the RE
+must be repeated a certain number of times.
+
+The first metacharacter for repeating things that we'll look at is
+\regexp{*}.  \regexp{*} doesn't match the literal character \samp{*};
+instead, it specifies that the previous character can be matched zero
+or more times, instead of exactly once.
+
+For example, \regexp{ca*t} will match \samp{ct} (0 \samp{a}
+characters), \samp{cat} (1 \samp{a}), \samp{caaat} (3 \samp{a}
+characters), and so forth.  The RE engine has various internal
+limitations stemming from the size of C's \code{int} type, that will
+prevent it from matching over 2 billion \samp{a} characters; you
+probably don't have enough memory to construct a string that large, so
+you shouldn't run into that limit.
+
+Repetitions such as \regexp{*} are \dfn{greedy}; when repeating a RE,
+the matching engine will try to repeat it as many times as possible.
+If later portions of the pattern don't match, the matching engine will
+then back up and try again with few repetitions.
+
+A step-by-step example will make this more obvious.  Let's consider
+the expression \regexp{a[bcd]*b}.  This matches the letter
+\character{a}, zero or more letters from the class \code{[bcd]}, and
+finally ends with a \character{b}.  Now imagine matching this RE
+against the string \samp{abcbd}.  
+
+\begin{tableiii}{c|l|l}{}{Step}{Matched}{Explanation}
+\lineiii{1}{\code{a}}{The \regexp{a} in the RE matches.}
+\lineiii{2}{\code{abcbd}}{The engine matches \regexp{[bcd]*}, going as far as
+it can, which is to the end of the string.}
+\lineiii{3}{\emph{Failure}}{The engine tries to match \regexp{b}, but the
+current position is at the end of the string, so it fails.}
+\lineiii{4}{\code{abcb}}{Back up, so that  \regexp{[bcd]*} matches
+one less character.}
+\lineiii{5}{\emph{Failure}}{Try \regexp{b} again, but the
+current position is at the last character, which is a \character{d}.}
+\lineiii{6}{\code{abc}}{Back up again, so that  \regexp{[bcd]*} is
+only matching \samp{bc}.}
+\lineiii{6}{\code{abcb}}{Try \regexp{b} again.  This time 
+but the character at the current position is \character{b}, so it succeeds.}
+\end{tableiii}
+
+The end of the RE has now been reached, and it has matched
+\samp{abcb}.  This demonstrates how the matching engine goes as far as
+it can at first, and if no match is found it will then progressively
+back up and retry the rest of the RE again and again.  It will back up
+until it has tried zero matches for \regexp{[bcd]*}, and if that
+subsequently fails, the engine will conclude that the string doesn't
+match the RE at all.
+
+Another repeating metacharacter is \regexp{+}, which matches one or
+more times.  Pay careful attention to the difference between
+\regexp{*} and \regexp{+}; \regexp{*} matches \emph{zero} or more
+times, so whatever's being repeated may not be present at all, while
+\regexp{+} requires at least \emph{one} occurrence.  To use a similar
+example, \regexp{ca+t} will match \samp{cat} (1 \samp{a}),
+\samp{caaat} (3 \samp{a}'s), but won't match \samp{ct}.
+
+There are two more repeating qualifiers.  The question mark character,
+\regexp{?}, matches either once or zero times; you can think of it as
+marking something as being optional.  For example, \regexp{home-?brew}
+matches either \samp{homebrew} or \samp{home-brew}.  
+
+The most complicated repeated qualifier is
+\regexp{\{\var{m},\var{n}\}}, where \var{m} and \var{n} are decimal
+integers.  This qualifier means there must be at least \var{m}
+repetitions, and at most \var{n}.  For example, \regexp{a/\{1,3\}b}
+will match \samp{a/b}, \samp{a//b}, and \samp{a///b}.  It won't match
+\samp{ab}, which has no slashes, or \samp{a////b}, which has four.
+
+You can omit either \var{m} or \var{n}; in that case, a reasonable
+value is assumed for the missing value.  Omitting \var{m} is
+interpreted as a lower limit of 0, while omitting \var{n} results in  an
+upper bound of infinity --- actually, the 2 billion limit mentioned
+earlier, but that might as well be infinity.  
+
+Readers of a reductionist bent may notice that the three other qualifiers
+can all be expressed using this notation.  \regexp{\{0,\}} is the same
+as \regexp{*}, \regexp{\{1,\}} is equivalent to \regexp{+}, and
+\regexp{\{0,1\}} is the same as \regexp{?}.  It's better to use
+\regexp{*}, \regexp{+}, or \regexp{?} when you can, simply because
+they're shorter and easier to read.
+
+\section{Using Regular Expressions}
+
+Now that we've looked at some simple regular expressions, how do we
+actually use them in Python?  The \module{re} module provides an
+interface to the regular expression engine, allowing you to compile
+REs into objects and then perform matches with them.
+
+\subsection{Compiling Regular Expressions}
+
+Regular expressions are compiled into \class{RegexObject} instances,
+which have methods for various operations such as searching for
+pattern matches or performing string substitutions.
+
+\begin{verbatim}
+>>> import re
+>>> p = re.compile('ab*')
+>>> print p
+<re.RegexObject instance at 80b4150>
+\end{verbatim}
+
+\function{re.compile()} also accepts an optional \var{flags}
+argument, used to enable various special features and syntax
+variations.  We'll go over the available settings later, but for now a
+single example will do:
+
+\begin{verbatim}
+>>> p = re.compile('ab*', re.IGNORECASE)
+\end{verbatim}
+
+The RE is passed to \function{re.compile()} as a string.  REs are
+handled as strings because regular expressions aren't part of the core
+Python language, and no special syntax was created for expressing
+them.  (There are applications that don't need REs at all, so there's
+no need to bloat the language specification by including them.)
+Instead, the \module{re} module is simply a C extension module
+included with Python, just like the \module{socket} or \module{zlib}
+module.
+
+Putting REs in strings keeps the Python language simpler, but has one
+disadvantage which is the topic of the next section.
+
+\subsection{The Backslash Plague}
+
+As stated earlier, regular expressions use the backslash
+character (\character{\e}) to indicate special forms or to allow
+special characters to be used without invoking their special meaning.
+This conflicts with Python's usage of the same character for the same
+purpose in string literals.
+
+Let's say you want to write a RE that matches the string
+\samp{{\e}section}, which might be found in a \LaTeX\ file.  To figure
+out what to write in the program code, start with the desired string
+to be matched.  Next, you must escape any backslashes and other
+metacharacters by preceding them with a backslash, resulting in the
+string \samp{\e\e section}.  The resulting string that must be passed
+to \function{re.compile()} must be \verb|\\section|.  However, to
+express this as a Python string literal, both backslashes must be
+escaped \emph{again}.
+
+\begin{tableii}{c|l}{code}{Characters}{Stage}
+  \lineii{\e section}{Text string to be matched}
+  \lineii{\e\e section}{Escaped backslash for \function{re.compile}}
+  \lineii{"\e\e\e\e section"}{Escaped backslashes for a string literal}
+\end{tableii}
+
+In short, to match a literal backslash, one has to write
+\code{'\e\e\e\e'} as the RE string, because the regular expression
+must be \samp{\e\e}, and each backslash must be expressed as
+\samp{\e\e} inside a regular Python string literal.  In REs that
+feature backslashes repeatedly, this leads to lots of repeated
+backslashes and makes the resulting strings difficult to understand.
+
+The solution is to use Python's raw string notation for regular
+expressions; backslashes are not handled in any special way in
+a string literal prefixed with \character{r}, so \code{r"\e n"} is a
+two-character string containing \character{\e} and \character{n},
+while \code{"\e n"} is a one-character string containing a newline.
+Frequently regular expressions will be expressed in Python
+code using this raw string notation.  
+
+\begin{tableii}{c|c}{code}{Regular String}{Raw string}
+  \lineii{"ab*"}{\code{r"ab*"}}
+  \lineii{"\e\e\e\e section"}{\code{r"\e\e section"}}
+  \lineii{"\e\e w+\e\e s+\e\e 1"}{\code{r"\e w+\e s+\e 1"}}
+\end{tableii}
+
+\subsection{Performing Matches}
+
+Once you have an object representing a compiled regular expression,
+what do you do with it?  \class{RegexObject} instances have several
+methods and attributes.  Only the most significant ones will be
+covered here; consult \ulink{the Library
+Reference}{http://www.python.org/doc/lib/module-re.html} for a
+complete listing.
+
+\begin{tableii}{c|l}{code}{Method/Attribute}{Purpose}
+  \lineii{match()}{Determine if the RE matches at the beginning of
+  the string.}
+  \lineii{search()}{Scan through a string, looking for any location
+  where this RE matches.}
+  \lineii{findall()}{Find all substrings where the RE matches,
+and returns them as a list.}
+  \lineii{finditer()}{Find all substrings where the RE matches,
+and returns them as an iterator.}
+\end{tableii}
+
+\method{match()} and \method{search()} return \code{None} if no match
+can be found.  If they're successful, a \code{MatchObject} instance is
+returned, containing information about the match: where it starts and
+ends, the substring it matched, and more.
+
+You can learn about this by interactively experimenting with the
+\module{re} module.  If you have Tkinter available, you may also want
+to look at \file{Tools/scripts/redemo.py}, a demonstration program
+included with the Python distribution.  It allows you to enter REs and
+strings, and displays whether the RE matches or fails.
+\file{redemo.py} can be quite useful when trying to debug a
+complicated RE.  Phil Schwartz's
+\ulink{Kodos}{http://kodos.sourceforge.net} is also an interactive
+tool for developing and testing RE patterns.  This HOWTO will use the
+standard Python interpreter for its examples.
+
+First, run the Python interpreter, import the \module{re} module, and
+compile a RE:
+
+\begin{verbatim}
+Python 2.2.2 (#1, Feb 10 2003, 12:57:01)
+>>> import re
+>>> p = re.compile('[a-z]+')
+>>> p
+<_sre.SRE_Pattern object at 80c3c28>
+\end{verbatim}
+
+Now, you can try matching various strings against the RE
+\regexp{[a-z]+}.  An empty string shouldn't match at all, since
+\regexp{+} means 'one or more repetitions'.  \method{match()} should
+return \code{None} in this case, which will cause the interpreter to
+print no output.  You can explicitly print the result of
+\method{match()} to make this clear.
+
+\begin{verbatim}
+>>> p.match("")
+>>> print p.match("")
+None
+\end{verbatim}
+
+Now, let's try it on a string that it should match, such as
+\samp{tempo}.  In this case, \method{match()} will return a
+\class{MatchObject}, so you should store the result in a variable for
+later use.
+
+\begin{verbatim}
+>>> m = p.match( 'tempo')
+>>> print m
+<_sre.SRE_Match object at 80c4f68>
+\end{verbatim}
+
+Now you can query the \class{MatchObject} for information about the
+matching string.   \class{MatchObject} instances also have several
+methods and attributes; the most important ones are:
+
+\begin{tableii}{c|l}{code}{Method/Attribute}{Purpose}
+  \lineii{group()}{Return the string matched by the RE}
+  \lineii{start()}{Return the starting position of the match}
+  \lineii{end()}{Return the ending position of the match}
+  \lineii{span()}{Return a tuple containing the (start, end) positions 
+                  of the match}
+\end{tableii}
+
+Trying these methods will soon clarify their meaning:
+
+\begin{verbatim}
+>>> m.group()
+'tempo'
+>>> m.start(), m.end()
+(0, 5)
+>>> m.span()
+(0, 5)
+\end{verbatim}
+
+\method{group()} returns the substring that was matched by the
+RE.  \method{start()} and \method{end()} return the starting and
+ending index of the match. \method{span()} returns both start and end
+indexes in a single tuple.  Since the \method{match} method only
+checks if the RE matches at the start of a string,
+\method{start()} will always be zero.  However, the \method{search}
+method of \class{RegexObject} instances scans through the string, so 
+the match may not start at zero in that case.
+
+\begin{verbatim}
+>>> print p.match('::: message')
+None
+>>> m = p.search('::: message') ; print m
+<re.MatchObject instance at 80c9650>
+>>> m.group()
+'message'
+>>> m.span()
+(4, 11)
+\end{verbatim}
+
+In actual programs, the most common style is to store the
+\class{MatchObject} in a variable, and then check if it was
+\code{None}.  This usually looks like:
+
+\begin{verbatim}
+p = re.compile( ... )
+m = p.match( 'string goes here' )
+if m:
+    print 'Match found: ', m.group()
+else:
+    print 'No match'
+\end{verbatim}
+
+Two \class{RegexObject} methods return all of the matches for a pattern.
+\method{findall()} returns a list of matching strings:
+
+\begin{verbatim}
+>>> p = re.compile('\d+')
+>>> p.findall('12 drummers drumming, 11 pipers piping, 10 lords a-leaping')
+['12', '11', '10']
+\end{verbatim}
+
+\method{findall()} has to create the entire list before it can be
+returned as the result.  In Python 2.2, the \method{finditer()} method
+is also available, returning a sequence of \class{MatchObject} instances 
+as an iterator.
+
+\begin{verbatim}
+>>> iterator = p.finditer('12 drummers drumming, 11 ... 10 ...')
+>>> iterator
+<callable-iterator object at 0x401833ac>
+>>> for match in iterator:
+...     print match.span()
+...
+(0, 2)
+(22, 24)
+(29, 31)
+\end{verbatim}
+
+
+\subsection{Module-Level Functions}
+
+You don't have to produce a \class{RegexObject} and call its methods;
+the \module{re} module also provides top-level functions called
+\function{match()}, \function{search()}, \function{sub()}, and so
+forth.  These functions take the same arguments as the corresponding
+\class{RegexObject} method, with the RE string added as the first
+argument, and still return either \code{None} or a \class{MatchObject}
+instance.
+
+\begin{verbatim}
+>>> print re.match(r'From\s+', 'Fromage amk')
+None
+>>> re.match(r'From\s+', 'From amk Thu May 14 19:12:10 1998')
+<re.MatchObject instance at 80c5978>
+\end{verbatim}
+
+Under the hood, these functions simply produce a \class{RegexObject}
+for you and call the appropriate method on it.  They also store the
+compiled object in a cache, so future calls using the same
+RE are faster.  
+
+Should you use these module-level functions, or should you get the
+\class{RegexObject} and call its methods yourself?  That choice
+depends on how frequently the RE will be used, and on your personal
+coding style.  If a RE is being used at only one point in the code,
+then the module functions are probably more convenient.  If a program
+contains a lot of regular expressions, or re-uses the same ones in
+several locations, then it might be worthwhile to collect all the
+definitions in one place, in a section of code that compiles all the
+REs ahead of time.  To take an example from the standard library,
+here's an extract from \file{xmllib.py}:
+
+\begin{verbatim}
+ref = re.compile( ... )
+entityref = re.compile( ... )
+charref = re.compile( ... )
+starttagopen = re.compile( ... )
+\end{verbatim}
+
+I generally prefer to work with the compiled object, even for
+one-time uses, but few people will be as much of a purist about this
+as I am.
+
+\subsection{Compilation Flags}
+
+Compilation flags let you modify some aspects of how regular
+expressions work.  Flags are available in the \module{re} module under
+two names, a long name such as \constant{IGNORECASE}, and a short,
+one-letter form such as \constant{I}.  (If you're familiar with Perl's
+pattern modifiers, the one-letter forms use the same letters; the
+short form of \constant{re.VERBOSE} is \constant{re.X}, for example.)
+Multiple flags can be specified by bitwise OR-ing them; \code{re.I |
+re.M} sets both the \constant{I} and \constant{M} flags, for example.
+
+Here's a table of the available flags, followed by
+a more detailed explanation of each one.
+
+\begin{tableii}{c|l}{}{Flag}{Meaning}
+  \lineii{\constant{DOTALL}, \constant{S}}{Make \regexp{.} match any
+  character, including newlines}
+  \lineii{\constant{IGNORECASE}, \constant{I}}{Do case-insensitive matches}
+  \lineii{\constant{LOCALE}, \constant{L}}{Do a locale-aware match}
+  \lineii{\constant{MULTILINE}, \constant{M}}{Multi-line matching,
+  affecting \regexp{\^} and \regexp{\$}}
+  \lineii{\constant{VERBOSE}, \constant{X}}{Enable verbose REs,
+  which can be organized more cleanly and understandably.}
+\end{tableii}
+
+\begin{datadesc}{I}
+\dataline{IGNORECASE}
+Perform case-insensitive matching; character class and literal strings
+will match
+letters by ignoring case.  For example, \regexp{[A-Z]} will match
+lowercase letters, too, and \regexp{Spam} will match \samp{Spam},
+\samp{spam}, or \samp{spAM}.
+This lowercasing doesn't take the current locale into account; it will
+if you also set the \constant{LOCALE} flag.
+\end{datadesc}
+
+\begin{datadesc}{L}
+\dataline{LOCALE}
+Make \regexp{\e w}, \regexp{\e W}, \regexp{\e b},
+and \regexp{\e B}, dependent on the current locale.  
+
+Locales are a feature of the C library intended to help in writing
+programs that take account of language differences.  For example, if
+you're processing French text, you'd want to be able to write
+\regexp{\e w+} to match words, but \regexp{\e w} only matches the
+character class \regexp{[A-Za-z]}; it won't match \character{\'e} or
+\character{\c c}.  If your system is configured properly and a French
+locale is selected, certain C functions will tell the program that
+\character{\'e} should also be considered a letter.  Setting the
+\constant{LOCALE} flag when compiling a regular expression will cause the
+resulting compiled object to use these C functions for \regexp{\e w};
+this is slower, but also enables \regexp{\e w+} to match French words as
+you'd expect.
+\end{datadesc}
+
+\begin{datadesc}{M}
+\dataline{MULTILINE}
+(\regexp{\^} and \regexp{\$} haven't been explained yet; 
+they'll be introduced in section~\ref{more-metacharacters}.)
+
+Usually \regexp{\^} matches only at the beginning of the string, and
+\regexp{\$} matches only at the end of the string and immediately before the
+newline (if any) at the end of the string. When this flag is
+specified, \regexp{\^} matches at the beginning of the string and at
+the beginning of each line within the string, immediately following
+each newline.  Similarly, the \regexp{\$} metacharacter matches either at
+the end of the string and at the end of each line (immediately
+preceding each newline).
+
+\end{datadesc}
+
+\begin{datadesc}{S}
+\dataline{DOTALL}
+Makes the \character{.} special character match any character at all,
+including a newline; without this flag, \character{.} will match
+anything \emph{except} a newline.
+\end{datadesc}
+
+\begin{datadesc}{X}
+\dataline{VERBOSE} This flag allows you to write regular expressions
+that are more readable by granting you more flexibility in how you can
+format them.  When this flag has been specified, whitespace within the
+RE string is ignored, except when the whitespace is in a character
+class or preceded by an unescaped backslash; this lets you organize
+and indent the RE more clearly.  It also enables you to put comments
+within a RE that will be ignored by the engine; comments are marked by
+a \character{\#} that's neither in a character class or preceded by an
+unescaped backslash.
+
+For example, here's a RE that uses \constant{re.VERBOSE}; see how
+much easier it is to read?
+
+\begin{verbatim}
+charref = re.compile(r"""
+ &[#]		     # Start of a numeric entity reference
+ (
+   [0-9]+[^0-9]      # Decimal form
+   | 0[0-7]+[^0-7]   # Octal form
+   | x[0-9a-fA-F]+[^0-9a-fA-F] # Hexadecimal form
+ )
+""", re.VERBOSE)
+\end{verbatim}
+
+Without the verbose setting, the RE would look like this:
+\begin{verbatim}
+charref = re.compile("&#([0-9]+[^0-9]"
+                     "|0[0-7]+[^0-7]"
+                     "|x[0-9a-fA-F]+[^0-9a-fA-F])")
+\end{verbatim}
+
+In the above example, Python's automatic concatenation of string
+literals has been used to break up the RE into smaller pieces, but
+it's still more difficult to understand than the version using
+\constant{re.VERBOSE}.
+
+\end{datadesc}
+
+\section{More Pattern Power}
+
+So far we've only covered a part of the features of regular
+expressions.  In this section, we'll cover some new metacharacters,
+and how to use groups to retrieve portions of the text that was matched.
+
+\subsection{More Metacharacters\label{more-metacharacters}}
+
+There are some metacharacters that we haven't covered yet.  Most of
+them will be covered in this section.
+
+Some of the remaining metacharacters to be discussed are
+\dfn{zero-width assertions}.  They don't cause the engine to advance
+through the string; instead, they consume no characters at all,
+and simply succeed or fail.  For example, \regexp{\e b} is an
+assertion that the current position is located at a word boundary; the
+position isn't changed by the \regexp{\e b} at all.  This means that
+zero-width assertions should never be repeated, because if they match
+once at a given location, they can obviously be matched an infinite
+number of times.
+
+\begin{list}{}{}
+
+\item[\regexp{|}] 
+Alternation, or the ``or'' operator.  
+If A and B are regular expressions, 
+\regexp{A|B} will match any string that matches either \samp{A} or \samp{B}.
+\regexp{|} has very low precedence in order to make it work reasonably when
+you're alternating multi-character strings.
+\regexp{Crow|Servo} will match either \samp{Crow} or \samp{Servo}, not
+\samp{Cro}, a \character{w} or an \character{S}, and \samp{ervo}.
+
+To match a literal \character{|},
+use \regexp{\e|}, or enclose it inside a character class, as in \regexp{[|]}.
+
+\item[\regexp{\^}] Matches at the beginning of lines.  Unless the
+\constant{MULTILINE} flag has been set, this will only match at the
+beginning of the string.  In \constant{MULTILINE} mode, this also
+matches immediately after each newline within the string.  
+
+For example, if you wish to match the word \samp{From} only at the
+beginning of a line, the RE to use is \verb|^From|.
+
+\begin{verbatim}
+>>> print re.search('^From', 'From Here to Eternity')
+<re.MatchObject instance at 80c1520>
+>>> print re.search('^From', 'Reciting From Memory')
+None
+\end{verbatim}
+
+%To match a literal \character{\^}, use \regexp{\e\^} or enclose it
+%inside a character class, as in \regexp{[{\e}\^]}.
+
+\item[\regexp{\$}] Matches at the end of a line, which is defined as
+either the end of the string, or any location followed by a newline
+character.    
+
+\begin{verbatim}
+>>> print re.search('}$', '{block}')
+<re.MatchObject instance at 80adfa8>
+>>> print re.search('}$', '{block} ')
+None
+>>> print re.search('}$', '{block}\n')
+<re.MatchObject instance at 80adfa8>
+\end{verbatim}
+% $
+
+To match a literal \character{\$}, use \regexp{\e\$} or enclose it
+inside a character class, as in  \regexp{[\$]}.
+
+\item[\regexp{\e A}] Matches only at the start of the string.  When
+not in \constant{MULTILINE} mode, \regexp{\e A} and \regexp{\^} are
+effectively the same.  In \constant{MULTILINE} mode, however, they're
+different; \regexp{\e A} still matches only at the beginning of the
+string, but \regexp{\^} may match at any location inside the string
+that follows a newline character.
+
+\item[\regexp{\e Z}]Matches only at the end of the string.  
+
+\item[\regexp{\e b}] Word boundary.  
+This is a zero-width assertion that matches only at the
+beginning or end of a word.  A word is defined as a sequence of
+alphanumeric characters, so the end of a word is indicated by
+whitespace or a non-alphanumeric character.  
+
+The following example matches \samp{class} only when it's a complete
+word; it won't match when it's contained inside another word.
+
+\begin{verbatim}
+>>> p = re.compile(r'\bclass\b')
+>>> print p.search('no class at all')
+<re.MatchObject instance at 80c8f28>
+>>> print p.search('the declassified algorithm')
+None
+>>> print p.search('one subclass is')
+None
+\end{verbatim}
+
+There are two subtleties you should remember when using this special
+sequence.  First, this is the worst collision between Python's string
+literals and regular expression sequences.  In Python's string
+literals, \samp{\e b} is the backspace character, ASCII value 8.  If
+you're not using raw strings, then Python will convert the \samp{\e b} to
+a backspace, and your RE won't match as you expect it to.  The
+following example looks the same as our previous RE, but omits
+the \character{r} in front of the RE string.
+
+\begin{verbatim}
+>>> p = re.compile('\bclass\b')
+>>> print p.search('no class at all')
+None
+>>> print p.search('\b' + 'class' + '\b')  
+<re.MatchObject instance at 80c3ee0>
+\end{verbatim}
+
+Second, inside a character class, where there's no use for this
+assertion, \regexp{\e b} represents the backspace character, for
+compatibility with Python's string literals.
+
+\item[\regexp{\e B}] Another zero-width assertion, this is the
+opposite of \regexp{\e b}, only matching when the current
+position is not at a word boundary.
+
+\end{list}
+
+\subsection{Grouping}
+
+Frequently you need to obtain more information than just whether the
+RE matched or not.  Regular expressions are often used to dissect
+strings by writing a RE divided into several subgroups which
+match different components of interest.  For example, an RFC-822
+header line is divided into a header name and a value, separated by a
+\character{:}.  This can be handled by writing a regular expression
+which matches an entire header line, and has one group which matches the
+header name, and another group which matches the header's value.
+
+Groups are marked by the \character{(}, \character{)} metacharacters.
+\character{(} and \character{)} have much the same meaning as they do
+in mathematical expressions; they group together the expressions
+contained inside them. For example, you can repeat the contents of a
+group with a repeating qualifier, such as \regexp{*}, \regexp{+},
+\regexp{?}, or \regexp{\{\var{m},\var{n}\}}.  For example,
+\regexp{(ab)*} will match zero or more repetitions of \samp{ab}.
+
+\begin{verbatim}
+>>> p = re.compile('(ab)*')
+>>> print p.match('ababababab').span()
+(0, 10)
+\end{verbatim}
+
+Groups indicated with \character{(}, \character{)} also capture the
+starting and ending index of the text that they match; this can be
+retrieved by passing an argument to \method{group()},
+\method{start()}, \method{end()}, and \method{span()}.  Groups are
+numbered starting with 0.  Group 0 is always present; it's the whole
+RE, so \class{MatchObject} methods all have group 0 as their default
+argument.  Later we'll see how to express groups that don't capture
+the span of text that they match.
+
+\begin{verbatim}
+>>> p = re.compile('(a)b')
+>>> m = p.match('ab')
+>>> m.group()
+'ab'
+>>> m.group(0)
+'ab'
+\end{verbatim}
+
+Subgroups are numbered from left to right, from 1 upward.  Groups can
+be nested; to determine the number, just count the opening parenthesis
+characters, going from left to right.
+
+\begin{verbatim}
+>>> p = re.compile('(a(b)c)d')
+>>> m = p.match('abcd')
+>>> m.group(0)
+'abcd'
+>>> m.group(1)
+'abc'
+>>> m.group(2)
+'b'
+\end{verbatim}
+
+\method{group()} can be passed multiple group numbers at a time, in
+which case it will return a tuple containing the corresponding values
+for those groups.
+
+\begin{verbatim}  
+>>> m.group(2,1,2)
+('b', 'abc', 'b')
+\end{verbatim}  
+
+The \method{groups()} method returns a tuple containing the strings
+for all the subgroups, from 1 up to however many there are.
+
+\begin{verbatim}  
+>>> m.groups()
+('abc', 'b')
+\end{verbatim}  
+
+Backreferences in a pattern allow you to specify that the contents of
+an earlier capturing group must also be found at the current location
+in the string.  For example, \regexp{\e 1} will succeed if the exact
+contents of group 1 can be found at the current position, and fails
+otherwise.  Remember that Python's string literals also use a
+backslash followed by numbers to allow including arbitrary characters
+in a string, so be sure to use a raw string when incorporating
+backreferences in a RE.
+
+For example, the following RE detects doubled words in a string.
+
+\begin{verbatim}
+>>> p = re.compile(r'(\b\w+)\s+\1')
+>>> p.search('Paris in the the spring').group()
+'the the'
+\end{verbatim}
+
+Backreferences like this aren't often useful for just searching
+through a string --- there are few text formats which repeat data in
+this way --- but you'll soon find out that they're \emph{very} useful
+when performing string substitutions.
+
+\subsection{Non-capturing and Named Groups}
+
+Elaborate REs may use many groups, both to capture substrings of
+interest, and to group and structure the RE itself.  In complex REs,
+it becomes difficult to keep track of the group numbers.  There are
+two features which help with this problem.  Both of them use a common
+syntax for regular expression extensions, so we'll look at that first.
+
+Perl 5 added several additional features to standard regular
+expressions, and the Python \module{re} module supports most of them.
+It would have been difficult to choose new single-keystroke
+metacharacters or new special sequences beginning with \samp{\e} to
+represent the new features without making Perl's regular expressions
+confusingly different from standard REs.  If you chose \samp{\&} as a
+new metacharacter, for example, old expressions would be assuming that
+\samp{\&} was a regular character and wouldn't have escaped it by
+writing \regexp{\e \&} or \regexp{[\&]}.  
+
+The solution chosen by the Perl developers was to use \regexp{(?...)}
+as the extension syntax.  \samp{?} immediately after a parenthesis was
+a syntax error because the \samp{?} would have nothing to repeat, so
+this didn't introduce any compatibility problems.  The characters
+immediately after the \samp{?}  indicate what extension is being used,
+so \regexp{(?=foo)} is one thing (a positive lookahead assertion) and
+\regexp{(?:foo)} is something else (a non-capturing group containing
+the subexpression \regexp{foo}).
+
+Python adds an extension syntax to Perl's extension syntax.  If the
+first character after the question mark is a \samp{P}, you know that
+it's an extension that's specific to Python.  Currently there are two
+such extensions: \regexp{(?P<\var{name}>...)} defines a named group,
+and \regexp{(?P=\var{name})} is a backreference to a named group.  If
+future versions of Perl 5 add similar features using a different
+syntax, the \module{re} module will be changed to support the new
+syntax, while preserving the Python-specific syntax for
+compatibility's sake.
+
+Now that we've looked at the general extension syntax, we can return
+to the features that simplify working with groups in complex REs.
+Since groups are numbered from left to right and a complex expression
+may use many groups, it can become difficult to keep track of the
+correct numbering, and modifying such a complex RE is annoying.
+Insert a new group near the beginning, and you change the numbers of
+everything that follows it.
+
+First, sometimes you'll want to use a group to collect a part of a
+regular expression, but aren't interested in retrieving the group's
+contents.  You can make this fact explicit by using a non-capturing
+group: \regexp{(?:...)}, where you can put any other regular
+expression inside the parentheses.  
+
+\begin{verbatim}
+>>> m = re.match("([abc])+", "abc")
+>>> m.groups()
+('c',)
+>>> m = re.match("(?:[abc])+", "abc")
+>>> m.groups()
+()
+\end{verbatim}
+
+Except for the fact that you can't retrieve the contents of what the
+group matched, a non-capturing group behaves exactly the same as a
+capturing group; you can put anything inside it, repeat it with a
+repetition metacharacter such as \samp{*}, and nest it within other
+groups (capturing or non-capturing).  \regexp{(?:...)} is particularly
+useful when modifying an existing group, since you can add new groups
+without changing how all the other groups are numbered.  It should be
+mentioned that there's no performance difference in searching between
+capturing and non-capturing groups; neither form is any faster than
+the other.
+
+The second, and more significant, feature is named groups; instead of
+referring to them by numbers, groups can be referenced by a name.
+
+The syntax for a named group is one of the Python-specific extensions:
+\regexp{(?P<\var{name}>...)}.  \var{name} is, obviously, the name of
+the group.  Except for associating a name with a group, named groups
+also behave identically to capturing groups.  The \class{MatchObject}
+methods that deal with capturing groups all accept either integers, to
+refer to groups by number, or a string containing the group name.
+Named groups are still given numbers, so you can retrieve information
+about a group in two ways:
+
+\begin{verbatim}
+>>> p = re.compile(r'(?P<word>\b\w+\b)')
+>>> m = p.search( '(((( Lots of punctuation )))' )
+>>> m.group('word')
+'Lots'
+>>> m.group(1)
+'Lots'
+\end{verbatim}
+
+Named groups are handy because they let you use easily-remembered
+names, instead of having to remember numbers.  Here's an example RE
+from the \module{imaplib} module:
+
+\begin{verbatim}
+InternalDate = re.compile(r'INTERNALDATE "'
+        r'(?P<day>[ 123][0-9])-(?P<mon>[A-Z][a-z][a-z])-'
+	r'(?P<year>[0-9][0-9][0-9][0-9])'
+        r' (?P<hour>[0-9][0-9]):(?P<min>[0-9][0-9]):(?P<sec>[0-9][0-9])'
+        r' (?P<zonen>[-+])(?P<zoneh>[0-9][0-9])(?P<zonem>[0-9][0-9])'
+        r'"')
+\end{verbatim}
+
+It's obviously much easier to retrieve \code{m.group('zonem')},
+instead of having to remember to retrieve group 9.
+
+Since the syntax for backreferences, in an expression like
+\regexp{(...)\e 1}, refers to the number of the group there's
+naturally a variant that uses the group name instead of the number.
+This is also a Python extension: \regexp{(?P=\var{name})} indicates
+that the contents of the group called \var{name} should again be found
+at the current point.  The regular expression for finding doubled
+words, \regexp{(\e b\e w+)\e s+\e 1} can also be written as
+\regexp{(?P<word>\e b\e w+)\e s+(?P=word)}:
+
+\begin{verbatim}
+>>> p = re.compile(r'(?P<word>\b\w+)\s+(?P=word)')
+>>> p.search('Paris in the the spring').group()
+'the the'
+\end{verbatim}
+
+\subsection{Lookahead Assertions}
+
+Another zero-width assertion is the lookahead assertion.  Lookahead
+assertions are available in both positive and negative form, and 
+look like this:
+
+\begin{itemize}
+\item[\regexp{(?=...)}] Positive lookahead assertion.  This succeeds
+if the contained regular expression, represented here by \code{...},
+successfully matches at the current location, and fails otherwise.
+But, once the contained expression has been tried, the matching engine
+doesn't advance at all; the rest of the pattern is tried right where
+the assertion started.
+
+\item[\regexp{(?!...)}] Negative lookahead assertion.  This is the
+opposite of the positive assertion; it succeeds if the contained expression
+\emph{doesn't} match at the current position in the string.
+\end{itemize}
+
+An example will help make this concrete by demonstrating a case
+where a lookahead is useful.  Consider a simple pattern to match a
+filename and split it apart into a base name and an extension,
+separated by a \samp{.}.  For example, in \samp{news.rc}, \samp{news}
+is the base name, and \samp{rc} is the filename's extension.  
+
+The pattern to match this is quite simple: 
+
+\regexp{.*[.].*\$}
+
+Notice that the \samp{.} needs to be treated specially because it's a
+metacharacter; I've put it inside a character class.  Also notice the
+trailing \regexp{\$}; this is added to ensure that all the rest of the
+string must be included in the extension.  This regular expression
+matches \samp{foo.bar} and \samp{autoexec.bat} and \samp{sendmail.cf} and
+\samp{printers.conf}.
+
+Now, consider complicating the problem a bit; what if you want to
+match filenames where the extension is not \samp{bat}?
+Some incorrect attempts:
+
+\verb|.*[.][^b].*$|
+% $
+
+The first attempt above tries to exclude \samp{bat} by requiring that
+the first character of the extension is not a \samp{b}.  This is
+wrong, because the pattern also doesn't match \samp{foo.bar}.
+
+% Messes up the HTML without the curly braces around \^
+\regexp{.*[.]([{\^}b]..|.[{\^}a].|..[{\^}t])\$}
+
+The expression gets messier when you try to patch up the first
+solution by requiring one of the following cases to match: the first
+character of the extension isn't \samp{b}; the second character isn't
+\samp{a}; or the third character isn't \samp{t}.  This accepts
+\samp{foo.bar} and rejects \samp{autoexec.bat}, but it requires a
+three-letter extension and won't accept a filename with a two-letter
+extension such as \samp{sendmail.cf}.  We'll complicate the pattern
+again in an effort to fix it.
+
+\regexp{.*[.]([{\^}b].?.?|.[{\^}a]?.?|..?[{\^}t]?)\$}
+
+In the third attempt, the second and third letters are all made
+optional in order to allow matching extensions shorter than three
+characters, such as \samp{sendmail.cf}.
+
+The pattern's getting really complicated now, which makes it hard to
+read and understand.  Worse, if the problem changes and you want to
+exclude both \samp{bat} and \samp{exe} as extensions, the pattern
+would get even more complicated and confusing.
+
+A negative lookahead cuts through all this:
+
+\regexp{.*[.](?!bat\$).*\$}
+% $
+
+The lookahead means: if the expression \regexp{bat} doesn't match at
+this point, try the rest of the pattern; if \regexp{bat\$} does match,
+the whole pattern will fail.  The trailing \regexp{\$} is required to
+ensure that something like \samp{sample.batch}, where the extension
+only starts with \samp{bat}, will be allowed.
+
+Excluding another filename extension is now easy; simply add it as an
+alternative inside the assertion.  The following pattern excludes
+filenames that end in either \samp{bat} or \samp{exe}:
+
+\regexp{.*[.](?!bat\$|exe\$).*\$}
+% $
+
+
+\section{Modifying Strings}
+
+Up to this point, we've simply performed searches against a static
+string.  Regular expressions are also commonly used to modify a string
+in various ways, using the following \class{RegexObject} methods:
+
+\begin{tableii}{c|l}{code}{Method/Attribute}{Purpose}
+  \lineii{split()}{Split the string into a list, splitting it wherever the RE matches}
+  \lineii{sub()}{Find all substrings where the RE matches, and replace them with a different string}
+  \lineii{subn()}{Does the same thing as \method{sub()}, 
+   but returns the new string and the number of replacements}
+\end{tableii}
+
+
+\subsection{Splitting Strings}
+
+The \method{split()} method of a \class{RegexObject} splits a string
+apart wherever the RE matches, returning a list of the pieces.
+It's similar to the \method{split()} method of strings but
+provides much more
+generality in the delimiters that you can split by;
+\method{split()} only supports splitting by whitespace or by
+a fixed string.  As you'd expect, there's a module-level
+\function{re.split()} function, too.
+
+\begin{methoddesc}{split}{string \optional{, maxsplit\code{ = 0}}}
+  Split \var{string} by the matches of the regular expression.  If
+  capturing parentheses are used in the RE, then their contents will
+  also be returned as part of the resulting list.  If \var{maxsplit}
+  is nonzero, at most \var{maxsplit} splits are performed.
+\end{methoddesc}
+
+You can limit the number of splits made, by passing a value for
+\var{maxsplit}.  When \var{maxsplit} is nonzero, at most
+\var{maxsplit} splits will be made, and the remainder of the string is
+returned as the final element of the list.  In the following example,
+the delimiter is any sequence of non-alphanumeric characters.
+
+\begin{verbatim}
+>>> p = re.compile(r'\W+')
+>>> p.split('This is a test, short and sweet, of split().')
+['This', 'is', 'a', 'test', 'short', 'and', 'sweet', 'of', 'split', '']
+>>> p.split('This is a test, short and sweet, of split().', 3)
+['This', 'is', 'a', 'test, short and sweet, of split().']
+\end{verbatim}
+
+Sometimes you're not only interested in what the text between
+delimiters is, but also need to know what the delimiter was.  If
+capturing parentheses are used in the RE, then their values are also
+returned as part of the list.  Compare the following calls:
+
+\begin{verbatim}
+>>> p = re.compile(r'\W+')
+>>> p2 = re.compile(r'(\W+)')
+>>> p.split('This... is a test.')
+['This', 'is', 'a', 'test', '']
+>>> p2.split('This... is a test.')
+['This', '... ', 'is', ' ', 'a', ' ', 'test', '.', '']
+\end{verbatim}
+
+The module-level function \function{re.split()} adds the RE to be
+used as the first argument, but is otherwise the same.  
+
+\begin{verbatim}
+>>> re.split('[\W]+', 'Words, words, words.')
+['Words', 'words', 'words', '']
+>>> re.split('([\W]+)', 'Words, words, words.')
+['Words', ', ', 'words', ', ', 'words', '.', '']
+>>> re.split('[\W]+', 'Words, words, words.', 1)
+['Words', 'words, words.']
+\end{verbatim}
+
+\subsection{Search and Replace}
+
+Another common task is to find all the matches for a pattern, and
+replace them with a different string.  The \method{sub()} method takes
+a replacement value, which can be either a string or a function, and
+the string to be processed.
+
+\begin{methoddesc}{sub}{replacement, string\optional{, count\code{ = 0}}}
+Returns the string obtained by replacing the leftmost non-overlapping
+occurrences of the RE in \var{string} by the replacement
+\var{replacement}.  If the pattern isn't found, \var{string} is returned
+unchanged.  
+
+The optional argument \var{count} is the maximum number of pattern
+occurrences to be replaced; \var{count} must be a non-negative
+integer.  The default value of 0 means to replace all occurrences.
+\end{methoddesc}
+
+Here's a simple example of using the \method{sub()} method.  It
+replaces colour names with the word \samp{colour}:
+
+\begin{verbatim}
+>>> p = re.compile( '(blue|white|red)')
+>>> p.sub( 'colour', 'blue socks and red shoes')
+'colour socks and colour shoes'
+>>> p.sub( 'colour', 'blue socks and red shoes', count=1)
+'colour socks and red shoes'
+\end{verbatim}
+
+The \method{subn()} method does the same work, but returns a 2-tuple
+containing the new string value and the number of replacements 
+that were performed:
+
+\begin{verbatim}
+>>> p = re.compile( '(blue|white|red)')
+>>> p.subn( 'colour', 'blue socks and red shoes')
+('colour socks and colour shoes', 2)
+>>> p.subn( 'colour', 'no colours at all')
+('no colours at all', 0)
+\end{verbatim}
+
+Empty matches are replaced only when they're not
+adjacent to a previous match.  
+
+\begin{verbatim}
+>>> p = re.compile('x*')
+>>> p.sub('-', 'abxd')
+'-a-b-d-'
+\end{verbatim}
+
+If \var{replacement} is a string, any backslash escapes in it are
+processed.  That is, \samp{\e n} is converted to a single newline
+character, \samp{\e r} is converted to a carriage return, and so forth.
+Unknown escapes such as \samp{\e j} are left alone.  Backreferences,
+such as \samp{\e 6}, are replaced with the substring matched by the
+corresponding group in the RE.  This lets you incorporate
+portions of the original text in the resulting
+replacement string.
+
+This example matches the word \samp{section} followed by a string
+enclosed in \samp{\{}, \samp{\}}, and changes \samp{section} to
+\samp{subsection}:
+
+\begin{verbatim}
+>>> p = re.compile('section{ ( [^}]* ) }', re.VERBOSE)
+>>> p.sub(r'subsection{\1}','section{First} section{second}')
+'subsection{First} subsection{second}'
+\end{verbatim}
+
+There's also a syntax for referring to named groups as defined by the
+\regexp{(?P<name>...)} syntax.  \samp{\e g<name>} will use the
+substring matched by the group named \samp{name}, and 
+\samp{\e g<\var{number}>} 
+uses the corresponding group number.  
+\samp{\e g<2>} is therefore equivalent to \samp{\e 2}, 
+but isn't ambiguous in a
+replacement string such as \samp{\e g<2>0}.  (\samp{\e 20} would be
+interpreted as a reference to group 20, not a reference to group 2
+followed by the literal character \character{0}.)  The following
+substitutions are all equivalent, but use all three variations of the
+replacement string.
+
+\begin{verbatim}
+>>> p = re.compile('section{ (?P<name> [^}]* ) }', re.VERBOSE)
+>>> p.sub(r'subsection{\1}','section{First}')
+'subsection{First}'
+>>> p.sub(r'subsection{\g<1>}','section{First}')
+'subsection{First}'
+>>> p.sub(r'subsection{\g<name>}','section{First}')
+'subsection{First}'
+\end{verbatim}
+
+\var{replacement} can also be a function, which gives you even more
+control.  If \var{replacement} is a function, the function is
+called for every non-overlapping occurrence of \var{pattern}.  On each
+call, the function is 
+passed a \class{MatchObject} argument for the match
+and can use this information to compute the desired replacement string and return it.
+
+In the following example, the replacement function translates 
+decimals into hexadecimal:
+
+\begin{verbatim}
+>>> def hexrepl( match ):
+...     "Return the hex string for a decimal number"
+...     value = int( match.group() )
+...     return hex(value)
+...
+>>> p = re.compile(r'\d+')
+>>> p.sub(hexrepl, 'Call 65490 for printing, 49152 for user code.')
+'Call 0xffd2 for printing, 0xc000 for user code.'
+\end{verbatim}
+
+When using the module-level \function{re.sub()} function, the pattern
+is passed as the first argument.  The pattern may be a string or a
+\class{RegexObject}; if you need to specify regular expression flags,
+you must either use a \class{RegexObject} as the first parameter, or use
+embedded modifiers in the pattern, e.g.  \code{sub("(?i)b+", "x", "bbbb
+BBBB")} returns \code{'x x'}.
+
+\section{Common Problems}
+
+Regular expressions are a powerful tool for some applications, but in
+some ways their behaviour isn't intuitive and at times they don't
+behave the way you may expect them to.  This section will point out
+some of the most common pitfalls.
+
+\subsection{Use String Methods}
+
+Sometimes using the \module{re} module is a mistake.  If you're
+matching a fixed string, or a single character class, and you're not
+using any \module{re} features such as the \constant{IGNORECASE} flag,
+then the full power of regular expressions may not be required.
+Strings have several methods for performing operations with fixed
+strings and they're usually much faster, because the implementation is
+a single small C loop that's been optimized for the purpose, instead
+of the large, more generalized regular expression engine.
+
+One example might be replacing a single fixed string with another
+one; for example, you might replace \samp{word}
+with \samp{deed}.  \code{re.sub()} seems like the function to use for
+this, but consider the \method{replace()} method.  Note that 
+\function{replace()} will also replace \samp{word} inside
+words, turning \samp{swordfish} into \samp{sdeedfish}, but the 
+na{\"\i}ve RE \regexp{word} would have done that, too.  (To avoid performing
+the substitution on parts of words, the pattern would have to be
+\regexp{\e bword\e b}, in order to require that \samp{word} have a
+word boundary on either side.  This takes the job beyond 
+\method{replace}'s abilities.)
+
+Another common task is deleting every occurrence of a single character
+from a string or replacing it with another single character.  You
+might do this with something like \code{re.sub('\e n', ' ', S)}, but
+\method{translate()} is capable of doing both tasks
+and will be faster than any regular expression operation can be.
+
+In short, before turning to the \module{re} module, consider whether
+your problem can be solved with a faster and simpler string method.
+
+\subsection{match() versus search()}
+
+The \function{match()} function only checks if the RE matches at
+the beginning of the string while \function{search()} will scan
+forward through the string for a match.
+It's important to keep this distinction in mind.  Remember, 
+\function{match()} will only report a successful match which
+will start at 0; if the match wouldn't start at zero, 
+\function{match()} will \emph{not} report it.
+
+\begin{verbatim}
+>>> print re.match('super', 'superstition').span()  
+(0, 5)
+>>> print re.match('super', 'insuperable')    
+None
+\end{verbatim}
+
+On the other hand, \function{search()} will scan forward through the
+string, reporting the first match it finds.
+
+\begin{verbatim}
+>>> print re.search('super', 'superstition').span()
+(0, 5)
+>>> print re.search('super', 'insuperable').span()
+(2, 7)
+\end{verbatim}
+
+Sometimes you'll be tempted to keep using \function{re.match()}, and
+just add \regexp{.*} to the front of your RE.  Resist this temptation
+and use \function{re.search()} instead.  The regular expression
+compiler does some analysis of REs in order to speed up the process of
+looking for a match.  One such analysis figures out what the first
+character of a match must be; for example, a pattern starting with
+\regexp{Crow} must match starting with a \character{C}.  The analysis
+lets the engine quickly scan through the string looking for the
+starting character, only trying the full match if a \character{C} is found.
+
+Adding \regexp{.*} defeats this optimization, requiring scanning to
+the end of the string and then backtracking to find a match for the
+rest of the RE.  Use \function{re.search()} instead.
+
+\subsection{Greedy versus Non-Greedy}
+
+When repeating a regular expression, as in \regexp{a*}, the resulting
+action is to consume as much of the pattern as possible.  This
+fact often bites you when you're trying to match a pair of
+balanced delimiters, such as the angle brackets surrounding an HTML
+tag.  The na{\"\i}ve pattern for matching a single HTML tag doesn't
+work because of the greedy nature of \regexp{.*}.
+
+\begin{verbatim}
+>>> s = '<html><head><title>Title</title>'
+>>> len(s)
+32
+>>> print re.match('<.*>', s).span()
+(0, 32)
+>>> print re.match('<.*>', s).group()
+<html><head><title>Title</title>
+\end{verbatim}
+
+The RE matches the \character{<} in \samp{<html>}, and the
+\regexp{.*} consumes the rest of the string.  There's still more left
+in the RE, though, and the \regexp{>} can't match at the end of
+the string, so the regular expression engine has to backtrack
+character by character until it finds a match for the \regexp{>}.  
+The final match extends from the \character{<} in \samp{<html>}
+to the \character{>} in \samp{</title>}, which isn't what you want.
+
+In this case, the solution is to use the non-greedy qualifiers
+\regexp{*?}, \regexp{+?}, \regexp{??}, or
+\regexp{\{\var{m},\var{n}\}?}, which match as \emph{little} text as
+possible.  In the above example, the \character{>} is tried
+immediately after the first \character{<} matches, and when it fails,
+the engine advances a character at a time, retrying the \character{>}
+at every step.  This produces just the right result:
+
+\begin{verbatim}
+>>> print re.match('<.*?>', s).group()
+<html>
+\end{verbatim}
+
+(Note that parsing HTML or XML with regular expressions is painful.
+Quick-and-dirty patterns will handle common cases, but HTML and XML
+have special cases that will break the obvious regular expression; by
+the time you've written a regular expression that handles all of the
+possible cases, the patterns will be \emph{very} complicated.  Use an
+HTML or XML parser module for such tasks.)
+
+\subsection{Not Using re.VERBOSE}
+
+By now you've probably noticed that regular expressions are a very
+compact notation, but they're not terribly readable.  REs of
+moderate complexity can become lengthy collections of backslashes,
+parentheses, and metacharacters, making them difficult to read and
+understand.  
+
+For such REs, specifying the \code{re.VERBOSE} flag when
+compiling the regular expression can be helpful, because it allows
+you to format the regular expression more clearly.
+
+The \code{re.VERBOSE} flag has several effects.  Whitespace in the
+regular expression that \emph{isn't} inside a character class is
+ignored.  This means that an expression such as \regexp{dog | cat} is
+equivalent to the less readable \regexp{dog|cat}, but \regexp{[a b]}
+will still match the characters \character{a}, \character{b}, or a
+space.  In addition, you can also put comments inside a RE; comments
+extend from a \samp{\#} character to the next newline.  When used with
+triple-quoted strings, this enables REs to be formatted more neatly:
+
+\begin{verbatim}
+pat = re.compile(r"""
+ \s*                 # Skip leading whitespace
+ (?P<header>[^:]+)   # Header name
+ \s* :               # Whitespace, and a colon
+ (?P<value>.*?)      # The header's value -- *? used to
+                     # lose the following trailing whitespace
+ \s*$                # Trailing whitespace to end-of-line
+""", re.VERBOSE)
+\end{verbatim}
+% $
+
+This is far more readable than:
+
+\begin{verbatim}
+pat = re.compile(r"\s*(?P<header>[^:]+)\s*:(?P<value>.*?)\s*$")
+\end{verbatim}
+% $
+
+\section{Feedback}
+
+Regular expressions are a complicated topic.  Did this document help
+you understand them?  Were there parts that were unclear, or Problems
+you encountered that weren't covered here?  If so, please send
+suggestions for improvements to the author.
+
+The most complete book on regular expressions is almost certainly
+Jeffrey Friedl's \citetitle{Mastering Regular Expressions}, published
+by O'Reilly.  Unfortunately, it exclusively concentrates on Perl and
+Java's flavours of regular expressions, and doesn't contain any Python
+material at all, so it won't be useful as a reference for programming
+in Python.  (The first edition covered Python's now-removed
+\module{regex} module, which won't help you much.)  Consider checking
+it out from your library.
+
+\end{document}
+

Added: vendor/Python/current/Doc/howto/sockets.tex
===================================================================
--- vendor/Python/current/Doc/howto/sockets.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/howto/sockets.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,465 @@
+\documentclass{howto}
+
+\title{Socket Programming HOWTO}
+
+\release{0.00}
+
+\author{Gordon McMillan}
+\authoraddress{\email{gmcm at hypernet.com}}
+
+\begin{document}
+\maketitle
+
+\begin{abstract}
+\noindent
+Sockets are used nearly everywhere, but are one of the most severely
+misunderstood technologies around. This is a 10,000 foot overview of
+sockets. It's not really a tutorial - you'll still have work to do in
+getting things operational. It doesn't cover the fine points (and there
+are a lot of them), but I hope it will give you enough background to
+begin using them decently.
+
+This document is available from the Python HOWTO page at
+\url{http://www.python.org/doc/howto}.
+
+\end{abstract}
+
+\tableofcontents
+
+\section{Sockets}
+
+Sockets are used nearly everywhere, but are one of the most severely
+misunderstood technologies around. This is a 10,000 foot overview of
+sockets. It's not really a tutorial - you'll still have work to do in
+getting things working. It doesn't cover the fine points (and there
+are a lot of them), but I hope it will give you enough background to
+begin using them decently.
+
+I'm only going to talk about INET sockets, but they account for at
+least 99\% of the sockets in use. And I'll only talk about STREAM
+sockets - unless you really know what you're doing (in which case this
+HOWTO isn't for you!), you'll get better behavior and performance from
+a STREAM socket than anything else. I will try to clear up the mystery
+of what a socket is, as well as some hints on how to work with
+blocking and non-blocking sockets. But I'll start by talking about
+blocking sockets. You'll need to know how they work before dealing
+with non-blocking sockets.
+
+Part of the trouble with understanding these things is that "socket"
+can mean a number of subtly different things, depending on context. So
+first, let's make a distinction between a "client" socket - an
+endpoint of a conversation, and a "server" socket, which is more like
+a switchboard operator. The client application (your browser, for
+example) uses "client" sockets exclusively; the web server it's
+talking to uses both "server" sockets and "client" sockets.
+
+
+\subsection{History}
+
+Of the various forms of IPC (\emph{Inter Process Communication}),
+sockets are by far the most popular.  On any given platform, there are
+likely to be other forms of IPC that are faster, but for
+cross-platform communication, sockets are about the only game in town.
+
+They were invented in Berkeley as part of the BSD flavor of Unix. They
+spread like wildfire with the Internet. With good reason --- the
+combination of sockets with INET makes talking to arbitrary machines
+around the world unbelievably easy (at least compared to other
+schemes).  
+
+\section{Creating a Socket}
+
+Roughly speaking, when you clicked on the link that brought you to
+this page, your browser did something like the following:
+
+\begin{verbatim}
+    #create an INET, STREAMing socket
+    s = socket.socket(
+        socket.AF_INET, socket.SOCK_STREAM)
+    #now connect to the web server on port 80 
+    # - the normal http port
+    s.connect(("www.mcmillan-inc.com", 80))
+\end{verbatim}
+
+When the \code{connect} completes, the socket \code{s} can
+now be used to send in a request for the text of this page. The same
+socket will read the reply, and then be destroyed. That's right -
+destroyed. Client sockets are normally only used for one exchange (or
+a small set of sequential exchanges).
+
+What happens in the web server is a bit more complex. First, the web
+server creates a "server socket".
+
+\begin{verbatim}
+    #create an INET, STREAMing socket
+    serversocket = socket.socket(
+        socket.AF_INET, socket.SOCK_STREAM)
+    #bind the socket to a public host, 
+    # and a well-known port
+    serversocket.bind((socket.gethostname(), 80))
+    #become a server socket
+    serversocket.listen(5)
+\end{verbatim}
+
+A couple things to notice: we used \code{socket.gethostname()}
+so that the socket would be visible to the outside world. If we had
+used \code{s.bind(('', 80))} or \code{s.bind(('localhost',
+80))} or \code{s.bind(('127.0.0.1', 80))} we would still
+have a "server" socket, but one that was only visible within the same
+machine.
+
+A second thing to note: low number ports are usually reserved for
+"well known" services (HTTP, SNMP etc). If you're playing around, use
+a nice high number (4 digits).
+
+Finally, the argument to \code{listen} tells the socket library that
+we want it to queue up as many as 5 connect requests (the normal max)
+before refusing outside connections. If the rest of the code is
+written properly, that should be plenty.
+
+OK, now we have a "server" socket, listening on port 80. Now we enter
+the mainloop of the web server:
+
+\begin{verbatim}
+    while 1:
+        #accept connections from outside
+        (clientsocket, address) = serversocket.accept()
+        #now do something with the clientsocket
+        #in this case, we'll pretend this is a threaded server
+        ct = client_thread(clientsocket)
+        ct.run()
+\end{verbatim}
+
+There's actually 3 general ways in which this loop could work -
+dispatching a thread to handle \code{clientsocket}, create a new
+process to handle \code{clientsocket}, or restructure this app
+to use non-blocking sockets, and mulitplex between our "server" socket
+and any active \code{clientsocket}s using
+\code{select}. More about that later. The important thing to
+understand now is this: this is \emph{all} a "server" socket
+does. It doesn't send any data. It doesn't receive any data. It just
+produces "client" sockets. Each \code{clientsocket} is created
+in response to some \emph{other} "client" socket doing a
+\code{connect()} to the host and port we're bound to. As soon as
+we've created that \code{clientsocket}, we go back to listening
+for more connections. The two "clients" are free to chat it up - they
+are using some dynamically allocated port which will be recycled when
+the conversation ends.
+
+\subsection{IPC} If you need fast IPC between two processes
+on one machine, you should look into whatever form of shared memory
+the platform offers. A simple protocol based around shared memory and
+locks or semaphores is by far the fastest technique.
+
+If you do decide to use sockets, bind the "server" socket to
+\code{'localhost'}. On most platforms, this will take a shortcut
+around a couple of layers of network code and be quite a bit faster.
+
+
+\section{Using a Socket}
+
+The first thing to note, is that the web browser's "client" socket and
+the web server's "client" socket are identical beasts. That is, this
+is a "peer to peer" conversation. Or to put it another way, \emph{as the
+designer, you will have to decide what the rules of etiquette are for
+a conversation}. Normally, the \code{connect}ing socket
+starts the conversation, by sending in a request, or perhaps a
+signon. But that's a design decision - it's not a rule of sockets.
+
+Now there are two sets of verbs to use for communication. You can use
+\code{send} and \code{recv}, or you can transform your
+client socket into a file-like beast and use \code{read} and
+\code{write}. The latter is the way Java presents their
+sockets. I'm not going to talk about it here, except to warn you that
+you need to use \code{flush} on sockets. These are buffered
+"files", and a common mistake is to \code{write} something, and
+then \code{read} for a reply. Without a \code{flush} in
+there, you may wait forever for the reply, because the request may
+still be in your output buffer.
+
+Now we come the major stumbling block of sockets - \code{send}
+and \code{recv} operate on the network buffers. They do not
+necessarily handle all the bytes you hand them (or expect from them),
+because their major focus is handling the network buffers. In general,
+they return when the associated network buffers have been filled
+(\code{send}) or emptied (\code{recv}). They then tell you
+how many bytes they handled. It is \emph{your} responsibility to call
+them again until your message has been completely dealt with.
+
+When a \code{recv} returns 0 bytes, it means the other side has
+closed (or is in the process of closing) the connection.  You will not
+receive any more data on this connection. Ever.  You may be able to
+send data successfully; I'll talk about that some on the next page.
+
+A protocol like HTTP uses a socket for only one transfer. The client
+sends a request, the reads a reply.  That's it. The socket is
+discarded. This means that a client can detect the end of the reply by
+receiving 0 bytes.
+
+But if you plan to reuse your socket for further transfers, you need
+to realize that \emph{there is no "EOT" (End of Transfer) on a
+socket.} I repeat: if a socket \code{send} or
+\code{recv} returns after handling 0 bytes, the connection has
+been broken.  If the connection has \emph{not} been broken, you may
+wait on a \code{recv} forever, because the socket will
+\emph{not} tell you that there's nothing more to read (for now).  Now
+if you think about that a bit, you'll come to realize a fundamental
+truth of sockets: \emph{messages must either be fixed length} (yuck),
+\emph{or be delimited} (shrug), \emph{or indicate how long they are}
+(much better), \emph{or end by shutting down the connection}. The
+choice is entirely yours, (but some ways are righter than others).
+
+Assuming you don't want to end the connection, the simplest solution
+is a fixed length message:
+
+\begin{verbatim}
+class mysocket:
+    '''demonstration class only 
+      - coded for clarity, not efficiency
+    '''
+
+    def __init__(self, sock=None):
+	if sock is None:
+	    self.sock = socket.socket(
+		socket.AF_INET, socket.SOCK_STREAM)
+	else:
+	    self.sock = sock
+
+    def connect(self, host, port):
+	self.sock.connect((host, port))
+
+    def mysend(self, msg):
+	totalsent = 0
+	while totalsent < MSGLEN:
+	    sent = self.sock.send(msg[totalsent:])
+	    if sent == 0:
+		raise RuntimeError, \\
+		    "socket connection broken"
+	    totalsent = totalsent + sent
+
+    def myreceive(self):
+	msg = ''
+	while len(msg) < MSGLEN:
+	    chunk = self.sock.recv(MSGLEN-len(msg))
+	    if chunk == '':
+		raise RuntimeError, \\
+		    "socket connection broken"
+	    msg = msg + chunk
+	return msg
+\end{verbatim}
+
+The sending code here is usable for almost any messaging scheme - in
+Python you send strings, and you can use \code{len()} to
+determine its length (even if it has embedded \code{\e 0}
+characters). It's mostly the receiving code that gets more
+complex. (And in C, it's not much worse, except you can't use
+\code{strlen} if the message has embedded \code{\e 0}s.)
+
+The easiest enhancement is to make the first character of the message
+an indicator of message type, and have the type determine the
+length. Now you have two \code{recv}s - the first to get (at
+least) that first character so you can look up the length, and the
+second in a loop to get the rest. If you decide to go the delimited
+route, you'll be receiving in some arbitrary chunk size, (4096 or 8192
+is frequently a good match for network buffer sizes), and scanning
+what you've received for a delimiter.
+
+One complication to be aware of: if your conversational protocol
+allows multiple messages to be sent back to back (without some kind of
+reply), and you pass \code{recv} an arbitrary chunk size, you
+may end up reading the start of a following message. You'll need to
+put that aside and hold onto it, until it's needed.
+
+Prefixing the message with it's length (say, as 5 numeric characters)
+gets more complex, because (believe it or not), you may not get all 5
+characters in one \code{recv}. In playing around, you'll get
+away with it; but in high network loads, your code will very quickly
+break unless you use two \code{recv} loops - the first to
+determine the length, the second to get the data part of the
+message. Nasty. This is also when you'll discover that
+\code{send} does not always manage to get rid of everything in
+one pass. And despite having read this, you will eventually get bit by
+it!
+
+In the interests of space, building your character, (and preserving my
+competitive position), these enhancements are left as an exercise for
+the reader. Lets move on to cleaning up.
+
+\subsection{Binary Data}
+
+It is perfectly possible to send binary data over a socket. The major
+problem is that not all machines use the same formats for binary
+data. For example, a Motorola chip will represent a 16 bit integer
+with the value 1 as the two hex bytes 00 01. Intel and DEC, however,
+are byte-reversed - that same 1 is 01 00. Socket libraries have calls
+for converting 16 and 32 bit integers - \code{ntohl, htonl, ntohs,
+htons} where "n" means \emph{network} and "h" means \emph{host},
+"s" means \emph{short} and "l" means \emph{long}. Where network order
+is host order, these do nothing, but where the machine is
+byte-reversed, these swap the bytes around appropriately.
+
+In these days of 32 bit machines, the ascii representation of binary
+data is frequently smaller than the binary representation. That's
+because a surprising amount of the time, all those longs have the
+value 0, or maybe 1. The string "0" would be two bytes, while binary
+is four. Of course, this doesn't fit well with fixed-length
+messages. Decisions, decisions.
+
+\section{Disconnecting}
+
+Strictly speaking, you're supposed to use \code{shutdown} on a
+socket before you \code{close} it.  The \code{shutdown} is
+an advisory to the socket at the other end.  Depending on the argument
+you pass it, it can mean "I'm not going to send anymore, but I'll
+still listen", or "I'm not listening, good riddance!".  Most socket
+libraries, however, are so used to programmers neglecting to use this
+piece of etiquette that normally a \code{close} is the same as
+\code{shutdown(); close()}.  So in most situations, an explicit
+\code{shutdown} is not needed.
+
+One way to use \code{shutdown} effectively is in an HTTP-like
+exchange. The client sends a request and then does a
+\code{shutdown(1)}. This tells the server "This client is done
+sending, but can still receive."  The server can detect "EOF" by a
+receive of 0 bytes. It can assume it has the complete request.  The
+server sends a reply. If the \code{send} completes successfully
+then, indeed, the client was still receiving.
+
+Python takes the automatic shutdown a step further, and says that when a socket is garbage collected, it will automatically do a \code{close} if it's needed. But relying on this is a very bad habit. If your socket just disappears without doing a \code{close}, the socket at the other end may hang indefinitely, thinking you're just being slow. \emph{Please} \code{close} your sockets when you're done.
+
+
+\subsection{When Sockets Die}
+
+Probably the worst thing about using blocking sockets is what happens
+when the other side comes down hard (without doing a
+\code{close}). Your socket is likely to hang. SOCKSTREAM is a
+reliable protocol, and it will wait a long, long time before giving up
+on a connection. If you're using threads, the entire thread is
+essentially dead. There's not much you can do about it. As long as you
+aren't doing something dumb, like holding a lock while doing a
+blocking read, the thread isn't really consuming much in the way of
+resources. Do \emph{not} try to kill the thread - part of the reason
+that threads are more efficient than processes is that they avoid the
+overhead associated with the automatic recycling of resources. In
+other words, if you do manage to kill the thread, your whole process
+is likely to be screwed up.  
+
+\section{Non-blocking Sockets}
+
+If you've understood the preceeding, you already know most of what you
+need to know about the mechanics of using sockets. You'll still use
+the same calls, in much the same ways. It's just that, if you do it
+right, your app will be almost inside-out.
+
+In Python, you use \code{socket.setblocking(0)} to make it
+non-blocking. In C, it's more complex, (for one thing, you'll need to
+choose between the BSD flavor \code{O_NONBLOCK} and the almost
+indistinguishable Posix flavor \code{O_NDELAY}, which is
+completely different from \code{TCP_NODELAY}), but it's the
+exact same idea. You do this after creating the socket, but before
+using it. (Actually, if you're nuts, you can switch back and forth.)
+
+The major mechanical difference is that \code{send},
+\code{recv}, \code{connect} and \code{accept} can
+return without having done anything. You have (of course) a number of
+choices. You can check return code and error codes and generally drive
+yourself crazy. If you don't believe me, try it sometime. Your app
+will grow large, buggy and suck CPU. So let's skip the brain-dead
+solutions and do it right.
+
+Use \code{select}.
+
+In C, coding \code{select} is fairly complex. In Python, it's a
+piece of cake, but it's close enough to the C version that if you
+understand \code{select} in Python, you'll have little trouble
+with it in C.
+
+\begin{verbatim}    ready_to_read, ready_to_write, in_error = \\
+                   select.select(
+                      potential_readers, 
+                      potential_writers, 
+                      potential_errs, 
+                      timeout)
+\end{verbatim}
+
+You pass \code{select} three lists: the first contains all
+sockets that you might want to try reading; the second all the sockets
+you might want to try writing to, and the last (normally left empty)
+those that you want to check for errors.  You should note that a
+socket can go into more than one list. The \code{select} call is
+blocking, but you can give it a timeout. This is generally a sensible
+thing to do - give it a nice long timeout (say a minute) unless you
+have good reason to do otherwise.
+
+In return, you will get three lists. They have the sockets that are
+actually readable, writable and in error. Each of these lists is a
+subset (possbily empty) of the corresponding list you passed in. And
+if you put a socket in more than one input list, it will only be (at
+most) in one output list.
+
+If a socket is in the output readable list, you can be
+as-close-to-certain-as-we-ever-get-in-this-business that a
+\code{recv} on that socket will return \emph{something}. Same
+idea for the writable list. You'll be able to send
+\emph{something}. Maybe not all you want to, but \emph{something} is
+better than nothing. (Actually, any reasonably healthy socket will
+return as writable - it just means outbound network buffer space is
+available.)
+
+If you have a "server" socket, put it in the potential_readers
+list. If it comes out in the readable list, your \code{accept}
+will (almost certainly) work. If you have created a new socket to
+\code{connect} to someone else, put it in the ptoential_writers
+list. If it shows up in the writable list, you have a decent chance
+that it has connected.
+
+One very nasty problem with \code{select}: if somewhere in those
+input lists of sockets is one which has died a nasty death, the
+\code{select} will fail. You then need to loop through every
+single damn socket in all those lists and do a
+\code{select([sock],[],[],0)} until you find the bad one. That
+timeout of 0 means it won't take long, but it's ugly.
+
+Actually, \code{select} can be handy even with blocking sockets.
+It's one way of determining whether you will block - the socket
+returns as readable when there's something in the buffers.  However,
+this still doesn't help with the problem of determining whether the
+other end is done, or just busy with something else.
+
+\textbf{Portability alert}: On Unix, \code{select} works both with
+the sockets and files. Don't try this on Windows. On Windows,
+\code{select} works with sockets only. Also note that in C, many
+of the more advanced socket options are done differently on
+Windows. In fact, on Windows I usually use threads (which work very,
+very well) with my sockets. Face it, if you want any kind of
+performance, your code will look very different on Windows than on
+Unix. (I haven't the foggiest how you do this stuff on a Mac.)
+
+\subsection{Performance}
+
+There's no question that the fastest sockets code uses non-blocking
+sockets and select to multiplex them. You can put together something
+that will saturate a LAN connection without putting any strain on the
+CPU. The trouble is that an app written this way can't do much of
+anything else - it needs to be ready to shuffle bytes around at all
+times.
+
+Assuming that your app is actually supposed to do something more than
+that, threading is the optimal solution, (and using non-blocking
+sockets will be faster than using blocking sockets). Unfortunately,
+threading support in Unixes varies both in API and quality. So the
+normal Unix solution is to fork a subprocess to deal with each
+connection. The overhead for this is significant (and don't do this on
+Windows - the overhead of process creation is enormous there). It also
+means that unless each subprocess is completely independent, you'll
+need to use another form of IPC, say a pipe, or shared memory and
+semaphores, to communicate between the parent and child processes.
+
+Finally, remember that even though blocking sockets are somewhat
+slower than non-blocking, in many cases they are the "right"
+solution. After all, if your app is driven by the data it receives
+over a socket, there's not much sense in complicating the logic just
+so your app can wait on \code{select} instead of
+\code{recv}.
+
+\end{document}

Added: vendor/Python/current/Doc/howto/unicode.rst
===================================================================
--- vendor/Python/current/Doc/howto/unicode.rst	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/howto/unicode.rst	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,766 @@
+Unicode HOWTO
+================
+
+**Version 1.02**
+
+This HOWTO discusses Python's support for Unicode, and explains various 
+problems that people commonly encounter when trying to work with Unicode.
+
+Introduction to Unicode
+------------------------------
+
+History of Character Codes
+''''''''''''''''''''''''''''''
+
+In 1968, the American Standard Code for Information Interchange,
+better known by its acronym ASCII, was standardized.  ASCII defined
+numeric codes for various characters, with the numeric values running from 0 to
+127.  For example, the lowercase letter 'a' is assigned 97 as its code
+value.
+
+ASCII was an American-developed standard, so it only defined
+unaccented characters.  There was an 'e', but no 'é' or 'Í'.  This
+meant that languages which required accented characters couldn't be
+faithfully represented in ASCII.  (Actually the missing accents matter
+for English, too, which contains words such as 'naïve' and 'café', and some
+publications have house styles which require spellings such as
+'coöperate'.)
+
+For a while people just wrote programs that didn't display accents.  I
+remember looking at Apple ][ BASIC programs, published in French-language
+publications in the mid-1980s, that had lines like these::
+
+	PRINT "FICHER EST COMPLETE."
+	PRINT "CARACTERE NON ACCEPTE."
+
+Those messages should contain accents, and they just look wrong to
+someone who can read French.  
+
+In the 1980s, almost all personal computers were 8-bit, meaning that
+bytes could hold values ranging from 0 to 255.  ASCII codes only went
+up to 127, so some machines assigned values between 128 and 255 to
+accented characters.  Different machines had different codes, however,
+which led to problems exchanging files.  Eventually various commonly
+used sets of values for the 128-255 range emerged.  Some were true
+standards, defined by the International Standards Organization, and
+some were **de facto** conventions that were invented by one company
+or another and managed to catch on.
+
+255 characters aren't very many.  For example, you can't fit
+both the accented characters used in Western Europe and the Cyrillic
+alphabet used for Russian into the 128-255 range because there are more than
+127 such characters.
+
+You could write files using different codes (all your Russian
+files in a coding system called KOI8, all your French files in 
+a different coding system called Latin1), but what if you wanted
+to write a French document that quotes some Russian text?  In the
+1980s people began to want to solve this problem, and the Unicode
+standardization effort began.
+
+Unicode started out using 16-bit characters instead of 8-bit characters.  16
+bits means you have 2^16 = 65,536 distinct values available, making it
+possible to represent many different characters from many different
+alphabets; an initial goal was to have Unicode contain the alphabets for
+every single human language.  It turns out that even 16 bits isn't enough to
+meet that goal, and the modern Unicode specification uses a wider range of
+codes, 0-1,114,111 (0x10ffff in base-16).
+
+There's a related ISO standard, ISO 10646.  Unicode and ISO 10646 were
+originally separate efforts, but the specifications were merged with
+the 1.1 revision of Unicode.  
+
+(This discussion of Unicode's history is highly simplified.  I don't
+think the average Python programmer needs to worry about the
+historical details; consult the Unicode consortium site listed in the
+References for more information.)
+
+
+Definitions
+''''''''''''''''''''''''
+
+A **character** is the smallest possible component of a text.  'A',
+'B', 'C', etc., are all different characters.  So are 'È' and
+'Í'.  Characters are abstractions, and vary depending on the
+language or context you're talking about.  For example, the symbol for
+ohms (Ω) is usually drawn much like the capital letter
+omega (Ω) in the Greek alphabet (they may even be the same in
+some fonts), but these are two different characters that have
+different meanings.
+
+The Unicode standard describes how characters are represented by
+**code points**.  A code point is an integer value, usually denoted in
+base 16.  In the standard, a code point is written using the notation
+U+12ca to mean the character with value 0x12ca (4810 decimal).  The
+Unicode standard contains a lot of tables listing characters and their
+corresponding code points::
+
+	0061    'a'; LATIN SMALL LETTER A
+	0062    'b'; LATIN SMALL LETTER B
+	0063    'c'; LATIN SMALL LETTER C
+        ...
+	007B	'{'; LEFT CURLY BRACKET
+
+Strictly, these definitions imply that it's meaningless to say 'this is
+character U+12ca'.  U+12ca is a code point, which represents some particular
+character; in this case, it represents the character 'ETHIOPIC SYLLABLE WI'.
+In informal contexts, this distinction between code points and characters will
+sometimes be forgotten.
+
+A character is represented on a screen or on paper by a set of graphical
+elements that's called a **glyph**.  The glyph for an uppercase A, for
+example, is two diagonal strokes and a horizontal stroke, though the exact
+details will depend on the font being used.  Most Python code doesn't need
+to worry about glyphs; figuring out the correct glyph to display is
+generally the job of a GUI toolkit or a terminal's font renderer.
+
+
+Encodings
+'''''''''
+
+To summarize the previous section: 
+a Unicode string is a sequence of code points, which are
+numbers from 0 to 0x10ffff.  This sequence needs to be represented as
+a set of bytes (meaning, values from 0-255) in memory.  The rules for
+translating a Unicode string into a sequence of bytes are called an 
+**encoding**.
+
+The first encoding you might think of is an array of 32-bit integers.  
+In this representation, the string "Python" would look like this::
+
+       P           y           t           h           o           n
+    0x50 00 00 00 79 00 00 00 74 00 00 00 68 00 00 00 6f 00 00 00 6e 00 00 00 
+       0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 
+
+This representation is straightforward but using
+it presents a number of problems.
+
+1. It's not portable; different processors order the bytes 
+   differently. 
+
+2. It's very wasteful of space.  In most texts, the majority of the code 
+   points are less than 127, or less than 255, so a lot of space is occupied
+   by zero bytes.  The above string takes 24 bytes compared to the 6
+   bytes needed for an ASCII representation.  Increased RAM usage doesn't
+   matter too much (desktop computers have megabytes of RAM, and strings
+   aren't usually that large), but expanding our usage of disk and
+   network bandwidth by a factor of 4 is intolerable.
+
+3. It's not compatible with existing C functions such as ``strlen()``,
+   so a new family of wide string functions would need to be used.
+
+4. Many Internet standards are defined in terms of textual data, and 
+   can't handle content with embedded zero bytes.
+
+Generally people don't use this encoding, choosing other encodings
+that are more efficient and convenient.
+
+Encodings don't have to handle every possible Unicode character, and
+most encodings don't.  For example, Python's default encoding is the
+'ascii' encoding.  The rules for converting a Unicode string into the
+ASCII encoding are simple; for each code point:
+
+1. If the code point is <128, each byte is the same as the value of the 
+   code point.
+
+2. If the code point is 128 or greater, the Unicode string can't 
+   be represented in this encoding.  (Python raises  a 
+   ``UnicodeEncodeError`` exception in this case.)
+
+Latin-1, also known as ISO-8859-1, is a similar encoding.  Unicode
+code points 0-255 are identical to the Latin-1 values, so converting
+to this encoding simply requires converting code points to byte
+values; if a code point larger than 255 is encountered, the string
+can't be encoded into Latin-1.
+
+Encodings don't have to be simple one-to-one mappings like Latin-1.
+Consider IBM's EBCDIC, which was used on IBM mainframes.  Letter
+values weren't in one block: 'a' through 'i' had values from 129 to
+137, but 'j' through 'r' were 145 through 153.  If you wanted to use
+EBCDIC as an encoding, you'd probably use some sort of lookup table to
+perform the conversion, but this is largely an internal detail.
+
+UTF-8 is one of the most commonly used encodings.  UTF stands for
+"Unicode Transformation Format", and the '8' means that 8-bit numbers
+are used in the encoding.  (There's also a UTF-16 encoding, but it's
+less frequently used than UTF-8.)  UTF-8 uses the following rules:
+
+1. If the code point is <128, it's represented by the corresponding byte value.
+2. If the code point is between 128 and 0x7ff, it's turned into two byte values
+   between 128 and 255.
+3. Code points >0x7ff are turned into three- or four-byte sequences, where
+   each byte of the sequence is between 128 and 255.
+    
+UTF-8 has several convenient properties:
+
+1. It can handle any Unicode code point.
+2. A Unicode string is turned into a string of bytes containing no embedded zero bytes.  This avoids byte-ordering issues, and means UTF-8 strings can be processed by C functions such as ``strcpy()`` and sent through protocols that can't handle zero bytes.
+3. A string of ASCII text is also valid UTF-8 text. 
+4. UTF-8 is fairly compact; the majority of code points are turned into two bytes, and values less than 128 occupy only a single byte.
+5. If bytes are corrupted or lost, it's possible to determine the start of the next UTF-8-encoded code point and resynchronize.  It's also unlikely that random 8-bit data will look like valid UTF-8.
+
+
+
+References
+''''''''''''''
+
+The Unicode Consortium site at <http://www.unicode.org> has character
+charts, a glossary, and PDF versions of the Unicode specification.  Be
+prepared for some difficult reading.
+<http://www.unicode.org/history/> is a chronology of the origin and
+development of Unicode.
+
+To help understand the standard, Jukka Korpela has written an
+introductory guide to reading the Unicode character tables, 
+available at <http://www.cs.tut.fi/~jkorpela/unicode/guide.html>.
+
+Roman Czyborra wrote another explanation of Unicode's basic principles; 
+it's at <http://czyborra.com/unicode/characters.html>.
+Czyborra has written a number of other Unicode-related documentation, 
+available from <http://www.cyzborra.com>.
+
+Two other good introductory articles were written by Joel Spolsky
+<http://www.joelonsoftware.com/articles/Unicode.html> and Jason
+Orendorff <http://www.jorendorff.com/articles/unicode/>.  If this
+introduction didn't make things clear to you, you should try reading
+one of these alternate articles before continuing.
+
+Wikipedia entries are often helpful; see the entries for "character
+encoding" <http://en.wikipedia.org/wiki/Character_encoding> and UTF-8
+<http://en.wikipedia.org/wiki/UTF-8>, for example.
+
+
+Python's Unicode Support
+------------------------
+
+Now that you've learned the rudiments of Unicode, we can look at
+Python's Unicode features.
+
+
+The Unicode Type
+'''''''''''''''''''
+
+Unicode strings are expressed as instances of the ``unicode`` type,
+one of Python's repertoire of built-in types.  It derives from an
+abstract type called ``basestring``, which is also an ancestor of the
+``str`` type; you can therefore check if a value is a string type with
+``isinstance(value, basestring)``.  Under the hood, Python represents
+Unicode strings as either 16- or 32-bit integers, depending on how the
+Python interpreter was compiled.
+
+The ``unicode()`` constructor has the signature ``unicode(string[, encoding, errors])``.
+All of its arguments should be 8-bit strings.  The first argument is converted 
+to Unicode using the specified encoding; if you leave off the ``encoding`` argument, 
+the ASCII encoding is used for the conversion, so characters greater than 127 will 
+be treated as errors::
+
+    >>> unicode('abcdef')
+    u'abcdef'
+    >>> s = unicode('abcdef')
+    >>> type(s)
+    <type 'unicode'>
+    >>> unicode('abcdef' + chr(255))
+    Traceback (most recent call last):
+      File "<stdin>", line 1, in ?
+    UnicodeDecodeError: 'ascii' codec can't decode byte 0xff in position 6: 
+                        ordinal not in range(128)
+
+The ``errors`` argument specifies the response when the input string can't be converted according to the encoding's rules.  Legal values for this argument 
+are 'strict' (raise a ``UnicodeDecodeError`` exception), 
+'replace' (add U+FFFD, 'REPLACEMENT CHARACTER'), 
+or 'ignore' (just leave the character out of the Unicode result).  
+The following examples show the differences::
+
+    >>> unicode('\x80abc', errors='strict')
+    Traceback (most recent call last):
+      File "<stdin>", line 1, in ?
+    UnicodeDecodeError: 'ascii' codec can't decode byte 0x80 in position 0: 
+                        ordinal not in range(128)
+    >>> unicode('\x80abc', errors='replace')
+    u'\ufffdabc'
+    >>> unicode('\x80abc', errors='ignore')
+    u'abc'
+
+Encodings are specified as strings containing the encoding's name.
+Python 2.4 comes with roughly 100 different encodings; see the Python
+Library Reference at
+<http://docs.python.org/lib/standard-encodings.html> for a list.  Some
+encodings have multiple names; for example, 'latin-1', 'iso_8859_1'
+and '8859' are all synonyms for the same encoding.
+
+One-character Unicode strings can also be created with the
+``unichr()`` built-in function, which takes integers and returns a
+Unicode string of length 1 that contains the corresponding code point.
+The reverse operation is the built-in `ord()` function that takes a
+one-character Unicode string and returns the code point value::
+
+    >>> unichr(40960)
+    u'\ua000'
+    >>> ord(u'\ua000')
+    40960
+
+Instances of the ``unicode`` type have many of the same methods as 
+the 8-bit string type for operations such as searching and formatting::
+
+    >>> s = u'Was ever feather so lightly blown to and fro as this multitude?'
+    >>> s.count('e')
+    5
+    >>> s.find('feather')
+    9
+    >>> s.find('bird')
+    -1
+    >>> s.replace('feather', 'sand')
+    u'Was ever sand so lightly blown to and fro as this multitude?'
+    >>> s.upper()
+    u'WAS EVER FEATHER SO LIGHTLY BLOWN TO AND FRO AS THIS MULTITUDE?'
+
+Note that the arguments to these methods can be Unicode strings or 8-bit strings.  
+8-bit strings will be converted to Unicode before carrying out the operation;
+Python's default ASCII encoding will be used, so characters greater than 127 will cause an exception::
+
+    >>> s.find('Was\x9f')
+    Traceback (most recent call last):
+      File "<stdin>", line 1, in ?
+    UnicodeDecodeError: 'ascii' codec can't decode byte 0x9f in position 3: ordinal not in range(128)
+    >>> s.find(u'Was\x9f')
+    -1
+
+Much Python code that operates on strings will therefore work with
+Unicode strings without requiring any changes to the code.  (Input and
+output code needs more updating for Unicode; more on this later.)
+
+Another important method is ``.encode([encoding], [errors='strict'])``, 
+which returns an 8-bit string version of the
+Unicode string, encoded in the requested encoding.  The ``errors``
+parameter is the same as the parameter of the ``unicode()``
+constructor, with one additional possibility; as well as 'strict',
+'ignore', and 'replace', you can also pass 'xmlcharrefreplace' which
+uses XML's character references.  The following example shows the
+different results::
+
+    >>> u = unichr(40960) + u'abcd' + unichr(1972)
+    >>> u.encode('utf-8')
+    '\xea\x80\x80abcd\xde\xb4'
+    >>> u.encode('ascii')
+    Traceback (most recent call last):
+      File "<stdin>", line 1, in ?
+    UnicodeEncodeError: 'ascii' codec can't encode character '\ua000' in position 0: ordinal not in range(128)
+    >>> u.encode('ascii', 'ignore')
+    'abcd'
+    >>> u.encode('ascii', 'replace')
+    '?abcd?'
+    >>> u.encode('ascii', 'xmlcharrefreplace')
+    '&#40960;abcd&#1972;'
+
+Python's 8-bit strings have a ``.decode([encoding], [errors])`` method 
+that interprets the string using the given encoding::
+
+    >>> u = unichr(40960) + u'abcd' + unichr(1972)   # Assemble a string
+    >>> utf8_version = u.encode('utf-8')             # Encode as UTF-8
+    >>> type(utf8_version), utf8_version
+    (<type 'str'>, '\xea\x80\x80abcd\xde\xb4')
+    >>> u2 = utf8_version.decode('utf-8')            # Decode using UTF-8
+    >>> u == u2                                      # The two strings match
+    True
+ 
+The low-level routines for registering and accessing the available
+encodings are found in the ``codecs`` module.  However, the encoding
+and decoding functions returned by this module are usually more
+low-level than is comfortable, so I'm not going to describe the
+``codecs`` module here.  If you need to implement a completely new
+encoding, you'll need to learn about the ``codecs`` module interfaces,
+but implementing encodings is a specialized task that also won't be
+covered here.  Consult the Python documentation to learn more about
+this module.
+
+The most commonly used part of the ``codecs`` module is the 
+``codecs.open()`` function which will be discussed in the section
+on input and output.
+            
+            
+Unicode Literals in Python Source Code
+''''''''''''''''''''''''''''''''''''''''''
+
+In Python source code, Unicode literals are written as strings
+prefixed with the 'u' or 'U' character: ``u'abcdefghijk'``.  Specific
+code points can be written using the ``\u`` escape sequence, which is
+followed by four hex digits giving the code point.  The ``\U`` escape
+sequence is similar, but expects 8 hex digits, not 4.  
+
+Unicode literals can also use the same escape sequences as 8-bit
+strings, including ``\x``, but ``\x`` only takes two hex digits so it
+can't express an arbitrary code point.  Octal escapes can go up to
+U+01ff, which is octal 777.
+
+::
+
+    >>> s = u"a\xac\u1234\u20ac\U00008000"
+               ^^^^ two-digit hex escape
+                   ^^^^^^ four-digit Unicode escape 
+                               ^^^^^^^^^^ eight-digit Unicode escape
+    >>> for c in s:  print ord(c),
+    ... 
+    97 172 4660 8364 32768
+
+Using escape sequences for code points greater than 127 is fine in
+small doses, but becomes an annoyance if you're using many accented
+characters, as you would in a program with messages in French or some
+other accent-using language.  You can also assemble strings using the
+``unichr()`` built-in function, but this is even more tedious.
+
+Ideally, you'd want to be able to write literals in your language's
+natural encoding.  You could then edit Python source code with your
+favorite editor which would display the accented characters naturally,
+and have the right characters used at runtime.
+
+Python supports writing Unicode literals in any encoding, but you have
+to declare the encoding being used.  This is done by including a
+special comment as either the first or second line of the source
+file::
+
+    #!/usr/bin/env python
+    # -*- coding: latin-1 -*-
+    
+    u = u'abcdé'
+    print ord(u[-1])
+    
+The syntax is inspired by Emacs's notation for specifying variables local to a file.
+Emacs supports many different variables, but Python only supports 'coding'.  
+The ``-*-`` symbols indicate that the comment is special; within them,
+you must supply the name ``coding`` and the name of your chosen encoding, 
+separated by ``':'``.  
+
+If you don't include such a comment, the default encoding used will be
+ASCII.  Versions of Python before 2.4 were Euro-centric and assumed
+Latin-1 as a default encoding for string literals; in Python 2.4,
+characters greater than 127 still work but result in a warning.  For
+example, the following program has no encoding declaration::
+
+    #!/usr/bin/env python
+    u = u'abcdé'
+    print ord(u[-1])
+
+When you run it with Python 2.4, it will output the following warning::
+
+    amk:~$ python p263.py
+    sys:1: DeprecationWarning: Non-ASCII character '\xe9' 
+         in file p263.py on line 2, but no encoding declared; 
+         see http://www.python.org/peps/pep-0263.html for details
+  
+
+Unicode Properties
+'''''''''''''''''''
+
+The Unicode specification includes a database of information about
+code points.  For each code point that's defined, the information
+includes the character's name, its category, the numeric value if
+applicable (Unicode has characters representing the Roman numerals and
+fractions such as one-third and four-fifths).  There are also
+properties related to the code point's use in bidirectional text and
+other display-related properties.
+
+The following program displays some information about several
+characters, and prints the numeric value of one particular character::
+
+    import unicodedata
+    
+    u = unichr(233) + unichr(0x0bf2) + unichr(3972) + unichr(6000) + unichr(13231)
+    
+    for i, c in enumerate(u):
+        print i, '%04x' % ord(c), unicodedata.category(c),
+        print unicodedata.name(c)
+    
+    # Get numeric value of second character
+    print unicodedata.numeric(u[1])
+
+When run, this prints::
+
+    0 00e9 Ll LATIN SMALL LETTER E WITH ACUTE
+    1 0bf2 No TAMIL NUMBER ONE THOUSAND
+    2 0f84 Mn TIBETAN MARK HALANTA
+    3 1770 Lo TAGBANWA LETTER SA
+    4 33af So SQUARE RAD OVER S SQUARED
+    1000.0
+
+The category codes are abbreviations describing the nature of the
+character.  These are grouped into categories such as "Letter",
+"Number", "Punctuation", or "Symbol", which in turn are broken up into
+subcategories.  To take the codes from the above output, ``'Ll'``
+means 'Letter, lowercase', ``'No'`` means "Number, other", ``'Mn'`` is
+"Mark, nonspacing", and ``'So'`` is "Symbol, other".  See
+<http://www.unicode.org/Public/UNIDATA/UCD.html#General_Category_Values>
+for a list of category codes.
+
+References
+''''''''''''''
+
+The Unicode and 8-bit string types are described in the Python library
+reference at <http://docs.python.org/lib/typesseq.html>.
+
+The documentation for the ``unicodedata`` module is at 
+<http://docs.python.org/lib/module-unicodedata.html>.
+
+The documentation for the ``codecs`` module is at
+<http://docs.python.org/lib/module-codecs.html>.
+
+Marc-André Lemburg gave a presentation at EuroPython 2002
+titled "Python and Unicode".  A PDF version of his slides
+is available at <http://www.egenix.com/files/python/Unicode-EPC2002-Talk.pdf>,
+and is an excellent overview of the design of Python's Unicode features.
+
+
+Reading and Writing Unicode Data
+----------------------------------------
+
+Once you've written some code that works with Unicode data, the next
+problem is input/output.  How do you get Unicode strings into your
+program, and how do you convert Unicode into a form suitable for
+storage or transmission?  
+
+It's possible that you may not need to do anything depending on your
+input sources and output destinations; you should check whether the
+libraries used in your application support Unicode natively.  XML
+parsers often return Unicode data, for example.  Many relational
+databases also support Unicode-valued columns and can return Unicode
+values from an SQL query.
+
+Unicode data is usually converted to a particular encoding before it
+gets written to disk or sent over a socket.  It's possible to do all
+the work yourself: open a file, read an 8-bit string from it, and
+convert the string with ``unicode(str, encoding)``.  However, the
+manual approach is not recommended.
+
+One problem is the multi-byte nature of encodings; one Unicode
+character can be represented by several bytes.  If you want to read
+the file in arbitrary-sized chunks (say, 1K or 4K), you need to write
+error-handling code to catch the case where only part of the bytes
+encoding a single Unicode character are read at the end of a chunk.
+One solution would be to read the entire file into memory and then
+perform the decoding, but that prevents you from working with files
+that are extremely large; if you need to read a 2Gb file, you need 2Gb
+of RAM.  (More, really, since for at least a moment you'd need to have 
+both the encoded string and its Unicode version in memory.)
+
+The solution would be to use the low-level decoding interface to catch
+the case of partial coding sequences.   The work of implementing this
+has already been done for you: the ``codecs`` module includes a
+version of the ``open()`` function that returns a file-like object
+that assumes the file's contents are in a specified encoding and
+accepts Unicode parameters for methods such as ``.read()`` and
+``.write()``.
+
+The function's parameters are 
+``open(filename, mode='rb', encoding=None, errors='strict', buffering=1)``.  ``mode`` can be
+``'r'``, ``'w'``, or ``'a'``, just like the corresponding parameter to the
+regular built-in ``open()`` function; add a ``'+'`` to 
+update the file.  ``buffering`` is similarly
+parallel to the standard function's parameter.  
+``encoding`` is a string giving 
+the encoding to use; if it's left as ``None``, a regular Python file
+object that accepts 8-bit strings is returned.  Otherwise, a wrapper
+object is returned, and data written to or read from the wrapper
+object will be converted as needed.  ``errors`` specifies the action
+for encoding errors and can be one of the usual values of 'strict',
+'ignore', and 'replace'.
+
+Reading Unicode from a file is therefore simple::
+
+    import codecs
+    f = codecs.open('unicode.rst', encoding='utf-8')
+    for line in f:
+        print repr(line)
+
+It's also possible to open files in update mode, 
+allowing both reading and writing::
+
+    f = codecs.open('test', encoding='utf-8', mode='w+')
+    f.write(u'\u4500 blah blah blah\n')
+    f.seek(0)
+    print repr(f.readline()[:1])
+    f.close()
+
+Unicode character U+FEFF is used as a byte-order mark (BOM), 
+and is often written as the first character of a file in order
+to assist with autodetection of the file's byte ordering.
+Some encodings, such as UTF-16, expect a BOM to be present at 
+the start of a file; when such an encoding is used,
+the BOM will be automatically written as the first character 
+and will be silently dropped when the file is read.  There are 
+variants of these encodings, such as 'utf-16-le' and 'utf-16-be'
+for little-endian and big-endian encodings, that specify 
+one particular byte ordering and don't
+skip the BOM.
+
+
+Unicode filenames
+'''''''''''''''''''''''''
+
+Most of the operating systems in common use today support filenames
+that contain arbitrary Unicode characters.  Usually this is
+implemented by converting the Unicode string into some encoding that
+varies depending on the system.  For example, MacOS X uses UTF-8 while
+Windows uses a configurable encoding; on Windows, Python uses the name
+"mbcs" to refer to whatever the currently configured encoding is.  On
+Unix systems, there will only be a filesystem encoding if you've set
+the ``LANG`` or ``LC_CTYPE`` environment variables; if you haven't,
+the default encoding is ASCII.
+
+The ``sys.getfilesystemencoding()`` function returns the encoding to
+use on your current system, in case you want to do the encoding
+manually, but there's not much reason to bother.  When opening a file
+for reading or writing, you can usually just provide the Unicode
+string as the filename, and it will be automatically converted to the
+right encoding for you::
+
+    filename = u'filename\u4500abc'
+    f = open(filename, 'w')
+    f.write('blah\n')
+    f.close()
+
+Functions in the ``os`` module such as ``os.stat()`` will also accept
+Unicode filenames.
+
+``os.listdir()``, which returns filenames, raises an issue: should it
+return the Unicode version of filenames, or should it return 8-bit
+strings containing the encoded versions?  ``os.listdir()`` will do
+both, depending on whether you provided the directory path as an 8-bit
+string or a Unicode string.  If you pass a Unicode string as the path,
+filenames will be decoded using the filesystem's encoding and a list
+of Unicode strings will be returned, while passing an 8-bit path will
+return the 8-bit versions of the filenames.  For example, assuming the
+default filesystem encoding is UTF-8, running the following program::
+
+	fn = u'filename\u4500abc'
+	f = open(fn, 'w')
+	f.close()
+
+	import os
+	print os.listdir('.')
+	print os.listdir(u'.')
+
+will produce the following output::
+
+	amk:~$ python t.py
+	['.svn', 'filename\xe4\x94\x80abc', ...]
+	[u'.svn', u'filename\u4500abc', ...]
+
+The first list contains UTF-8-encoded filenames, and the second list
+contains the Unicode versions.
+
+
+	
+Tips for Writing Unicode-aware Programs
+''''''''''''''''''''''''''''''''''''''''''''
+
+This section provides some suggestions on writing software that 
+deals with Unicode.
+
+The most important tip is: 
+
+    Software should only work with Unicode strings internally, 
+    converting to a particular encoding on output.  
+
+If you attempt to write processing functions that accept both 
+Unicode and 8-bit strings, you will find your program vulnerable to 
+bugs wherever you combine the two different kinds of strings.  Python's 
+default encoding is ASCII, so whenever a character with an ASCII value >127
+is in the input data, you'll get a ``UnicodeDecodeError``
+because that character can't be handled by the ASCII encoding.  
+
+It's easy to miss such problems if you only test your software 
+with data that doesn't contain any 
+accents; everything will seem to work, but there's actually a bug in your
+program waiting for the first user who attempts to use characters >127.
+A second tip, therefore, is:
+
+    Include characters >127 and, even better, characters >255 in your
+    test data.
+
+When using data coming from a web browser or some other untrusted source,
+a common technique is to check for illegal characters in a string
+before using the string in a generated command line or storing it in a 
+database.  If you're doing this, be careful to check 
+the string once it's in the form that will be used or stored; it's 
+possible for encodings to be used to disguise characters.  This is especially
+true if the input data also specifies the encoding; 
+many encodings leave the commonly checked-for characters alone, 
+but Python includes some encodings such as ``'base64'``
+that modify every single character.
+
+For example, let's say you have a content management system that takes a 
+Unicode filename, and you want to disallow paths with a '/' character.
+You might write this code::
+
+    def read_file (filename, encoding):
+        if '/' in filename:
+            raise ValueError("'/' not allowed in filenames")
+        unicode_name = filename.decode(encoding)
+        f = open(unicode_name, 'r')
+        # ... return contents of file ...
+        
+However, if an attacker could specify the ``'base64'`` encoding,
+they could pass ``'L2V0Yy9wYXNzd2Q='``, which is the base-64
+encoded form of the string ``'/etc/passwd'``, to read a 
+system file.   The above code looks for ``'/'`` characters 
+in the encoded form and misses the dangerous character 
+in the resulting decoded form.
+
+References
+''''''''''''''
+
+The PDF slides for Marc-André Lemburg's presentation "Writing
+Unicode-aware Applications in Python" are available at
+<http://www.egenix.com/files/python/LSM2005-Developing-Unicode-aware-applications-in-Python.pdf>
+and discuss questions of character encodings as well as how to
+internationalize and localize an application.
+
+
+Revision History and Acknowledgements
+------------------------------------------
+
+Thanks to the following people who have noted errors or offered
+suggestions on this article: Nicholas Bastin, 
+Marius Gedminas, Kent Johnson, Ken Krugler,
+Marc-André Lemburg, Martin von Löwis, Chad Whitacre.
+
+Version 1.0: posted August 5 2005.
+
+Version 1.01: posted August 7 2005.  Corrects factual and markup
+errors; adds several links.
+
+Version 1.02: posted August 16 2005.  Corrects factual errors.
+
+
+.. comment Additional topic: building Python w/ UCS2 or UCS4 support
+.. comment Describe obscure -U switch somewhere?
+.. comment Describe use of codecs.StreamRecoder and StreamReaderWriter
+
+.. comment 
+   Original outline:
+
+   - [ ] Unicode introduction
+       - [ ] ASCII
+       - [ ] Terms
+	   - [ ] Character
+	   - [ ] Code point
+	 - [ ] Encodings
+	    - [ ] Common encodings: ASCII, Latin-1, UTF-8
+       - [ ] Unicode Python type
+	   - [ ] Writing unicode literals
+	       - [ ] Obscurity: -U switch
+	   - [ ] Built-ins
+	       - [ ] unichr()
+	       - [ ] ord()
+	       - [ ] unicode() constructor
+	   - [ ] Unicode type
+	       - [ ] encode(), decode() methods
+       - [ ] Unicodedata module for character properties
+       - [ ] I/O
+	   - [ ] Reading/writing Unicode data into files
+	       - [ ] Byte-order marks
+	   - [ ] Unicode filenames
+       - [ ] Writing Unicode programs
+	   - [ ] Do everything in Unicode
+	   - [ ] Declaring source code encodings (PEP 263)
+       - [ ] Other issues
+	   - [ ] Building Python (UCS2, UCS4)

Added: vendor/Python/current/Doc/howto/urllib2.rst
===================================================================
--- vendor/Python/current/Doc/howto/urllib2.rst	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/howto/urllib2.rst	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,598 @@
+==============================================
+ HOWTO Fetch Internet Resources Using urllib2
+==============================================
+----------------------------
+  Fetching URLs With Python
+----------------------------
+
+
+.. note::
+
+    There is an French translation of an earlier revision of this
+    HOWTO, available at `urllib2 - Le Manuel manquant
+    <http://www.voidspace/python/articles/urllib2_francais.shtml>`_.
+
+.. contents:: urllib2 Tutorial
+ 
+
+Introduction
+============
+
+.. sidebar:: Related Articles
+
+    You may also find useful the following article on fetching web
+    resources with Python :
+    
+    * `Basic Authentication <http://www.voidspace.org.uk/python/articles/authentication.shtml>`_
+    
+        A tutorial on *Basic Authentication*, with examples in Python.
+    
+    This HOWTO is written by `Michael Foord
+    <http://www.voidspace.org.uk/python/index.shtml>`_.
+
+**urllib2** is a `Python <http://www.python.org>`_ module for fetching URLs
+(Uniform Resource Locators). It offers a very simple interface, in the form of
+the *urlopen* function. This is capable of fetching URLs using a variety
+of different protocols. It also offers a slightly more complex
+interface for handling common situations - like basic authentication,
+cookies, proxies and so on. These are provided by objects called
+handlers and openers.
+
+urllib2 supports fetching URLs for many "URL schemes" (identified by the string
+before the ":" in URL - for example "ftp" is the URL scheme of
+"ftp://python.org/") using their associated network protocols (e.g. FTP, HTTP).
+This tutorial focuses on the most common case, HTTP.
+
+For straightforward situations *urlopen* is very easy to use. But as
+soon as you encounter errors or non-trivial cases when opening HTTP
+URLs, you will need some understanding of the HyperText Transfer
+Protocol. The most comprehensive and authoritative reference to HTTP
+is :RFC:`2616`. This is a technical document and not intended to be
+easy to read. This HOWTO aims to illustrate using *urllib2*, with
+enough detail about HTTP to help you through. It is not intended to
+replace the `urllib2 docs <http://docs.python.org/lib/module-urllib2.html>`_ ,
+but is supplementary to them.
+
+
+Fetching URLs
+=============
+
+The simplest way to use urllib2 is as follows : ::
+
+    import urllib2
+    response = urllib2.urlopen('http://python.org/')
+    html = response.read()
+
+Many uses of urllib2 will be that simple (note that instead of an
+'http:' URL we could have used an URL starting with 'ftp:', 'file:',
+etc.).  However, it's the purpose of this tutorial to explain the more
+complicated cases, concentrating on HTTP.
+
+HTTP is based on requests and responses - the client makes requests
+and servers send responses. urllib2 mirrors this with a ``Request``
+object which represents the HTTP request you are making. In its
+simplest form you create a Request object that specifies the URL you
+want to fetch. Calling ``urlopen`` with this Request object returns a
+response object for the URL requested. This response is a file-like
+object, which means you can for example call .read() on the response :
+::
+
+    import urllib2
+
+    req = urllib2.Request('http://www.voidspace.org.uk')
+    response = urllib2.urlopen(req)
+    the_page = response.read()
+
+Note that urllib2 makes use of the same Request interface to handle
+all URL schemes.  For example, you can make an FTP request like so: ::
+
+    req = urllib2.Request('ftp://example.com/')
+
+In the case of HTTP, there are two extra things that Request objects
+allow you to do: First, you can pass data to be sent to the server.
+Second, you can pass extra information ("metadata") *about* the data
+or the about request itself, to the server - this information is sent
+as HTTP "headers".  Let's look at each of these in turn.
+
+Data
+----
+
+Sometimes you want to send data to a URL (often the URL will refer to
+a CGI (Common Gateway Interface) script [#]_ or other web
+application). With HTTP, this is often done using what's known as a
+**POST** request. This is often what your browser does when you submit
+a HTML form that you filled in on the web. Not all POSTs have to come
+from forms: you can use a POST to transmit arbitrary data to your own
+application. In the common case of HTML forms, the data needs to be
+encoded in a standard way, and then passed to the Request object as
+the ``data`` argument. The encoding is done using a function from the
+``urllib`` library *not* from ``urllib2``. ::
+
+    import urllib
+    import urllib2  
+
+    url = 'http://www.someserver.com/cgi-bin/register.cgi'
+    values = {'name' : 'Michael Foord',
+              'location' : 'Northampton',
+              'language' : 'Python' }
+
+    data = urllib.urlencode(values)
+    req = urllib2.Request(url, data)
+    response = urllib2.urlopen(req)
+    the_page = response.read()
+
+Note that other encodings are sometimes required (e.g. for file upload
+from HTML forms - see
+`HTML Specification, Form Submission <http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13>`_
+for more details).
+
+If you do not pass the ``data`` argument, urllib2 uses a **GET**
+request. One way in which GET and POST requests differ is that POST
+requests often have "side-effects": they change the state of the
+system in some way (for example by placing an order with the website
+for a hundredweight of tinned spam to be delivered to your door).
+Though the HTTP standard makes it clear that POSTs are intended to
+*always* cause side-effects, and GET requests *never* to cause
+side-effects, nothing prevents a GET request from having side-effects,
+nor a POST requests from having no side-effects. Data can also be
+passed in an HTTP GET request by encoding it in the URL itself.
+
+This is done as follows::
+
+    >>> import urllib2
+    >>> import urllib
+    >>> data = {}
+    >>> data['name'] = 'Somebody Here'
+    >>> data['location'] = 'Northampton'
+    >>> data['language'] = 'Python'
+    >>> url_values = urllib.urlencode(data)
+    >>> print url_values
+    name=Somebody+Here&language=Python&location=Northampton
+    >>> url = 'http://www.example.com/example.cgi'
+    >>> full_url = url + '?' + url_values
+    >>> data = urllib2.open(full_url)
+
+Notice that the full URL is created by adding a ``?`` to the URL, followed by
+the encoded values.
+
+Headers
+-------
+
+We'll discuss here one particular HTTP header, to illustrate how to
+add headers to your HTTP request.
+
+Some websites [#]_ dislike being browsed by programs, or send
+different versions to different browsers [#]_ . By default urllib2
+identifies itself as ``Python-urllib/x.y`` (where ``x`` and ``y`` are
+the major and minor version numbers of the Python release,
+e.g. ``Python-urllib/2.5``), which may confuse the site, or just plain
+not work. The way a browser identifies itself is through the
+``User-Agent`` header [#]_. When you create a Request object you can
+pass a dictionary of headers in. The following example makes the same
+request as above, but identifies itself as a version of Internet
+Explorer [#]_. ::
+
+    import urllib
+    import urllib2  
+    
+    url = 'http://www.someserver.com/cgi-bin/register.cgi'
+    user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)' 
+    values = {'name' : 'Michael Foord',
+              'location' : 'Northampton',
+              'language' : 'Python' }
+    headers = { 'User-Agent' : user_agent }
+    
+    data = urllib.urlencode(values)
+    req = urllib2.Request(url, data, headers)
+    response = urllib2.urlopen(req)
+    the_page = response.read()
+
+The response also has two useful methods. See the section on `info and
+geturl`_ which comes after we have a look at what happens when things
+go wrong.
+
+
+Handling Exceptions
+===================
+
+*urlopen* raises ``URLError`` when it cannot handle a response (though
+as usual with Python APIs, builtin exceptions such as ValueError,
+TypeError etc. may also be raised).
+
+``HTTPError`` is the subclass of ``URLError`` raised in the specific
+case of HTTP URLs.
+
+URLError
+--------
+
+Often, URLError is raised because there is no network connection (no
+route to the specified server), or the specified server doesn't exist.
+In this case, the exception raised will have a 'reason' attribute,
+which is a tuple containing an error code and a text error message.
+
+e.g. ::
+
+    >>> req = urllib2.Request('http://www.pretend_server.org')
+    >>> try: urllib2.urlopen(req)
+    >>> except URLError, e:
+    >>>    print e.reason
+    >>>
+    (4, 'getaddrinfo failed')
+
+
+HTTPError
+---------
+
+Every HTTP response from the server contains a numeric "status
+code". Sometimes the status code indicates that the server is unable
+to fulfil the request. The default handlers will handle some of these
+responses for you (for example, if the response is a "redirection"
+that requests the client fetch the document from a different URL,
+urllib2 will handle that for you). For those it can't handle, urlopen
+will raise an ``HTTPError``. Typical errors include '404' (page not
+found), '403' (request forbidden), and '401' (authentication
+required).
+
+See section 10 of RFC 2616 for a reference on all the HTTP error
+codes.
+
+The ``HTTPError`` instance raised will have an integer 'code'
+attribute, which corresponds to the error sent by the server.
+
+Error Codes
+~~~~~~~~~~~
+
+Because the default handlers handle redirects (codes in the 300
+range), and codes in the 100-299 range indicate success, you will
+usually only see error codes in the 400-599 range.
+
+``BaseHTTPServer.BaseHTTPRequestHandler.responses`` is a useful
+dictionary of response codes in that shows all the response codes used
+by RFC 2616. The dictionary is reproduced here for convenience ::
+
+    # Table mapping response codes to messages; entries have the
+    # form {code: (shortmessage, longmessage)}.
+    responses = {
+        100: ('Continue', 'Request received, please continue'),
+        101: ('Switching Protocols',
+              'Switching to new protocol; obey Upgrade header'),
+
+        200: ('OK', 'Request fulfilled, document follows'),
+        201: ('Created', 'Document created, URL follows'),
+        202: ('Accepted',
+              'Request accepted, processing continues off-line'),
+        203: ('Non-Authoritative Information', 'Request fulfilled from cache'),
+        204: ('No Content', 'Request fulfilled, nothing follows'),
+        205: ('Reset Content', 'Clear input form for further input.'),
+        206: ('Partial Content', 'Partial content follows.'),
+
+        300: ('Multiple Choices',
+              'Object has several resources -- see URI list'),
+        301: ('Moved Permanently', 'Object moved permanently -- see URI list'),
+        302: ('Found', 'Object moved temporarily -- see URI list'),
+        303: ('See Other', 'Object moved -- see Method and URL list'),
+        304: ('Not Modified',
+              'Document has not changed since given time'),
+        305: ('Use Proxy',
+              'You must use proxy specified in Location to access this '
+              'resource.'),
+        307: ('Temporary Redirect',
+              'Object moved temporarily -- see URI list'),
+
+        400: ('Bad Request',
+              'Bad request syntax or unsupported method'),
+        401: ('Unauthorized',
+              'No permission -- see authorization schemes'),
+        402: ('Payment Required',
+              'No payment -- see charging schemes'),
+        403: ('Forbidden',
+              'Request forbidden -- authorization will not help'),
+        404: ('Not Found', 'Nothing matches the given URI'),
+        405: ('Method Not Allowed',
+              'Specified method is invalid for this server.'),
+        406: ('Not Acceptable', 'URI not available in preferred format.'),
+        407: ('Proxy Authentication Required', 'You must authenticate with '
+              'this proxy before proceeding.'),
+        408: ('Request Timeout', 'Request timed out; try again later.'),
+        409: ('Conflict', 'Request conflict.'),
+        410: ('Gone',
+              'URI no longer exists and has been permanently removed.'),
+        411: ('Length Required', 'Client must specify Content-Length.'),
+        412: ('Precondition Failed', 'Precondition in headers is false.'),
+        413: ('Request Entity Too Large', 'Entity is too large.'),
+        414: ('Request-URI Too Long', 'URI is too long.'),
+        415: ('Unsupported Media Type', 'Entity body in unsupported format.'),
+        416: ('Requested Range Not Satisfiable',
+              'Cannot satisfy request range.'),
+        417: ('Expectation Failed',
+              'Expect condition could not be satisfied.'),
+
+        500: ('Internal Server Error', 'Server got itself in trouble'),
+        501: ('Not Implemented',
+              'Server does not support this operation'),
+        502: ('Bad Gateway', 'Invalid responses from another server/proxy.'),
+        503: ('Service Unavailable',
+              'The server cannot process the request due to a high load'),
+        504: ('Gateway Timeout',
+              'The gateway server did not receive a timely response'),
+        505: ('HTTP Version Not Supported', 'Cannot fulfill request.'),
+        }
+
+When an error is raised the server responds by returning an HTTP error
+code *and* an error page. You can use the ``HTTPError`` instance as a
+response on the page returned. This means that as well as the code
+attribute, it also has read, geturl, and info, methods. ::
+
+    >>> req = urllib2.Request('http://www.python.org/fish.html')
+    >>> try: 
+    >>>     urllib2.urlopen(req)
+    >>> except URLError, e:
+    >>>     print e.code
+    >>>     print e.read()
+    >>> 
+    404
+    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
+        "http://www.w3.org/TR/html4/loose.dtd">
+    <?xml-stylesheet href="./css/ht2html.css" 
+        type="text/css"?>
+    <html><head><title>Error 404: File Not Found</title> 
+    ...... etc...
+
+Wrapping it Up
+--------------
+
+So if you want to be prepared for ``HTTPError`` *or* ``URLError``
+there are two basic approaches. I prefer the second approach.
+
+Number 1
+~~~~~~~~
+
+::
+
+
+    from urllib2 import Request, urlopen, URLError, HTTPError
+    req = Request(someurl)
+    try:
+        response = urlopen(req)
+    except HTTPError, e:
+        print 'The server couldn\'t fulfill the request.'
+        print 'Error code: ', e.code
+    except URLError, e:
+        print 'We failed to reach a server.'
+        print 'Reason: ', e.reason
+    else:
+        # everything is fine
+
+
+.. note::
+
+    The ``except HTTPError`` *must* come first, otherwise ``except URLError``
+    will *also* catch an ``HTTPError``.
+
+Number 2
+~~~~~~~~
+
+::
+
+    from urllib2 import Request, urlopen, URLError
+    req = Request(someurl)
+    try:
+        response = urlopen(req)
+    except URLError, e:
+        if hasattr(e, 'reason'):
+            print 'We failed to reach a server.'
+            print 'Reason: ', e.reason
+        elif hasattr(e, 'code'):
+            print 'The server couldn\'t fulfill the request.'
+            print 'Error code: ', e.code
+    else:
+        # everything is fine
+        
+
+info and geturl
+===============
+
+The response returned by urlopen (or the ``HTTPError`` instance) has
+two useful methods ``info`` and ``geturl``.
+
+**geturl** - this returns the real URL of the page fetched. This is
+useful because ``urlopen`` (or the opener object used) may have
+followed a redirect. The URL of the page fetched may not be the same
+as the URL requested.
+
+**info** - this returns a dictionary-like object that describes the
+page fetched, particularly the headers sent by the server. It is
+currently an ``httplib.HTTPMessage`` instance.
+
+Typical headers include 'Content-length', 'Content-type', and so
+on. See the
+`Quick Reference to HTTP Headers <http://www.cs.tut.fi/~jkorpela/http.html>`_
+for a useful listing of HTTP headers with brief explanations of their meaning
+and use.
+
+
+Openers and Handlers
+====================
+
+When you fetch a URL you use an opener (an instance of the perhaps
+confusingly-named ``urllib2.OpenerDirector``). Normally we have been using
+the default opener - via ``urlopen`` - but you can create custom
+openers. Openers use handlers. All the "heavy lifting" is done by the
+handlers. Each handler knows how to open URLs for a particular URL
+scheme (http, ftp, etc.), or how to handle an aspect of URL opening,
+for example HTTP redirections or HTTP cookies.
+
+You will want to create openers if you want to fetch URLs with
+specific handlers installed, for example to get an opener that handles
+cookies, or to get an opener that does not handle redirections.
+
+To create an opener, instantiate an OpenerDirector, and then call
+.add_handler(some_handler_instance) repeatedly.
+
+Alternatively, you can use ``build_opener``, which is a convenience
+function for creating opener objects with a single function call.
+``build_opener`` adds several handlers by default, but provides a
+quick way to add more and/or override the default handlers.
+
+Other sorts of handlers you might want to can handle proxies,
+authentication, and other common but slightly specialised
+situations.
+
+``install_opener`` can be used to make an ``opener`` object the
+(global) default opener. This means that calls to ``urlopen`` will use
+the opener you have installed.
+
+Opener objects have an ``open`` method, which can be called directly
+to fetch urls in the same way as the ``urlopen`` function: there's no
+need to call ``install_opener``, except as a convenience.
+
+
+Basic Authentication
+====================
+
+To illustrate creating and installing a handler we will use the
+``HTTPBasicAuthHandler``. For a more detailed discussion of this
+subject - including an explanation of how Basic Authentication works -
+see the `Basic Authentication Tutorial  <http://www.voidspace.org.uk/python/articles/authentication.shtml>`_.
+
+When authentication is required, the server sends a header (as well as
+the 401 error code) requesting authentication.  This specifies the
+authentication scheme and a 'realm'. The header looks like :
+``Www-authenticate: SCHEME realm="REALM"``.
+
+e.g. :: 
+
+    Www-authenticate: Basic realm="cPanel Users"
+
+
+The client should then retry the request with the appropriate name and
+password for the realm included as a header in the request. This is
+'basic authentication'. In order to simplify this process we can
+create an instance of ``HTTPBasicAuthHandler`` and an opener to use
+this handler.
+
+The ``HTTPBasicAuthHandler`` uses an object called a password manager
+to handle the mapping of URLs and realms to passwords and
+usernames. If you know what the realm is (from the authentication
+header sent by the server), then you can use a
+``HTTPPasswordMgr``. Frequently one doesn't care what the realm is. In
+that case, it is convenient to use
+``HTTPPasswordMgrWithDefaultRealm``. This allows you to specify a
+default username and password for a URL. This will be supplied in the
+absence of you providing an alternative combination for a specific
+realm. We indicate this by providing ``None`` as the realm argument to
+the ``add_password`` method.
+
+The top-level URL is the first URL that requires authentication. URLs
+"deeper" than the URL you pass to .add_password() will also match. ::
+
+    # create a password manager
+    password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()                        
+
+    # Add the username and password.
+    # If we knew the realm, we could use it instead of ``None``.
+    top_level_url = "http://example.com/foo/"
+    password_mgr.add_password(None, top_level_url, username, password)
+
+    handler = urllib2.HTTPBasicAuthHandler(password_mgr)                            
+
+    # create "opener" (OpenerDirector instance)
+    opener = urllib2.build_opener(handler)                       
+
+    # use the opener to fetch a URL
+    opener.open(a_url)      
+
+    # Install the opener.
+    # Now all calls to urllib2.urlopen use our opener.
+    urllib2.install_opener(opener)                               
+
+.. note::
+
+    In the above example we only supplied our ``HHTPBasicAuthHandler``
+    to ``build_opener``. By default openers have the handlers for
+    normal situations - ``ProxyHandler``, ``UnknownHandler``,
+    ``HTTPHandler``, ``HTTPDefaultErrorHandler``,
+    ``HTTPRedirectHandler``, ``FTPHandler``, ``FileHandler``,
+    ``HTTPErrorProcessor``.
+
+top_level_url is in fact *either* a full URL (including the 'http:'
+scheme component and the hostname and optionally the port number)
+e.g. "http://example.com/" *or* an "authority" (i.e. the hostname,
+optionally including the port number) e.g. "example.com" or
+"example.com:8080" (the latter example includes a port number).  The
+authority, if present, must NOT contain the "userinfo" component - for
+example "joe at password:example.com" is not correct.
+
+
+Proxies
+=======
+
+**urllib2** will auto-detect your proxy settings and use those. This
+is through the ``ProxyHandler`` which is part of the normal handler
+chain. Normally that's a good thing, but there are occasions when it
+may not be helpful [#]_. One way to do this is to setup our own
+``ProxyHandler``, with no proxies defined. This is done using similar
+steps to setting up a `Basic Authentication`_ handler : ::
+
+    >>> proxy_support = urllib2.ProxyHandler({})
+    >>> opener = urllib2.build_opener(proxy_support)
+    >>> urllib2.install_opener(opener)
+
+.. note::
+
+    Currently ``urllib2`` *does not* support fetching of ``https``
+    locations through a proxy. This can be a problem.
+
+Sockets and Layers
+==================
+
+The Python support for fetching resources from the web is
+layered. urllib2 uses the httplib library, which in turn uses the
+socket library.
+
+As of Python 2.3 you can specify how long a socket should wait for a
+response before timing out. This can be useful in applications which
+have to fetch web pages. By default the socket module has *no timeout*
+and can hang. Currently, the socket timeout is not exposed at the
+httplib or urllib2 levels.  However, you can set the default timeout
+globally for all sockets using : ::
+
+    import socket
+    import urllib2
+
+    # timeout in seconds
+    timeout = 10
+    socket.setdefaulttimeout(timeout) 
+
+    # this call to urllib2.urlopen now uses the default timeout
+    # we have set in the socket module
+    req = urllib2.Request('http://www.voidspace.org.uk')
+    response = urllib2.urlopen(req)
+
+
+-------
+
+
+Footnotes
+=========
+
+This document was reviewed and revised by John Lee.
+
+.. [#] For an introduction to the CGI protocol see
+       `Writing Web Applications in Python <http://www.pyzine.com/Issue008/Section_Articles/article_CGIOne.html>`_. 
+.. [#] Like Google for example. The *proper* way to use google from a program
+       is to use `PyGoogle <http://pygoogle.sourceforge.net>`_ of course. See
+       `Voidspace Google <http://www.voidspace.org.uk/python/recipebook.shtml#google>`_
+       for some examples of using the Google API.
+.. [#] Browser sniffing is a very bad practise for website design - building
+       sites using web standards is much more sensible. Unfortunately a lot of
+       sites still send different versions to different browsers.
+.. [#] The user agent for MSIE 6 is
+       *'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)'*
+.. [#] For details of more HTTP request headers, see
+       `Quick Reference to HTTP Headers`_.
+.. [#] In my case I have to use a proxy to access the internet at work. If you
+       attempt to fetch *localhost* URLs through this proxy it blocks them. IE
+       is set to use the proxy, which urllib2 picks up on. In order to test
+       scripts with a localhost server, I have to prevent urllib2 from using
+       the proxy.

Added: vendor/Python/current/Doc/html/about.dat
===================================================================
--- vendor/Python/current/Doc/html/about.dat	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/html/about.dat	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,24 @@
+<p> This document was generated using the <a
+    href="http://saftsack.fs.uni-bayreuth.de/;SPMtilde;latex2ht/">
+    <strong>LaTeX</strong>2<tt>HTML</tt></a> translator.
+</p>
+
+<p> <a
+    href="http://saftsack.fs.uni-bayreuth.de/;SPMtilde;latex2ht/">
+    <strong>LaTeX</strong>2<tt>HTML</tt></a> is Copyright &copy;
+  1993, 1994, 1995, 1996, 1997, <a
+    href="http://cbl.leeds.ac.uk/nikos/personal.html">Nikos
+    Drakos</a>, Computer Based Learning Unit, University of
+  Leeds, and Copyright &copy; 1997, 1998, <a
+    href="http://www.maths.mq.edu.au/;SPMtilde;ross/">Ross
+    Moore</a>, Mathematics Department, Macquarie University,
+  Sydney.
+</p>
+
+<p> The application of <a
+    href="http://saftsack.fs.uni-bayreuth.de/;SPMtilde;latex2ht/">
+    <strong>LaTeX</strong>2<tt>HTML</tt></a> to the Python
+  documentation has been heavily tailored by Fred L. Drake,
+  Jr.  Original navigation icons were contributed by Christopher
+  Petrilli.
+</p>

Added: vendor/Python/current/Doc/html/about.html
===================================================================
--- vendor/Python/current/Doc/html/about.html	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/html/about.html	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,84 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+  <head>
+    <title>About the Python Documentation</title>
+    <meta name="description"
+      content="Overview information about the Python documentation">
+    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+    <link rel="contents" href="index.html" title="Python Documentation Index">
+    <link rel="index" href="modindex.html" title="Global Module Index">
+    <link rel="start" href="index.html" title="Python Documentation Index">
+    <link rel="up" href="index.html" title="Python Documentation Index">
+    <link rel="SHORTCUT ICON" href="icons/pyfav.png" type="image/png">
+    <link rel="STYLESHEET" href="lib/lib.css">
+  </head>
+  <body>
+    <div class="navigation">
+      <table width="100%" cellpadding="0" cellspacing="2">
+          <tr>
+            <td><img width="32" height="32" align="bottom" border="0" alt=""
+                src="icons/blank.png"></td>
+            <td><a href="index.html"
+                title="Python Documentation Index"><img width="32" height="32"
+                  align="bottom" border="0" alt="up"
+                  src="icons/up.png"></a></td>
+            <td><img width="32" height="32" align="bottom" border="0" alt=""
+                src="icons/blank.png"></td>
+            <td align="center" width="100%">About the Python Documentation</td>
+            <td><img width="32" height="32" align="bottom" border="0" alt=""
+                src="icons/blank.png"></td>
+            <td><img width="32" height="32" align="bottom" border="0" alt=""
+                src="icons/blank.png"></td>
+            <td><img width="32" height="32" align="bottom" border="0" alt=""
+                src="icons/blank.png"></td>
+          </tr>
+      </table>
+      <b class="navlabel">Up:</b>
+      <span class="sectref">
+        <a href="index.html" title="Python Documentation Index">
+          Python Documentation Index</A></span>
+      <br>
+    </div>
+    <hr>
+
+    <h2>About the Python Documentation</h2>
+
+    <p>The Python documentation was originally written by Guido van
+      Rossum, but has increasingly become a community effort over the
+      past several years.  This growing collection of documents is
+      available in several formats, including typeset versions in PDF
+      and PostScript for printing, from the <a
+        href="http://www.python.org/">Python Web site</a>.
+
+    <p>A <a href="acks.html">list of contributors</a> is available.
+
+    <h2>Comments and Questions</h2>
+
+    <p> General comments and questions regarding this document should
+      be sent by email to <a href="mailto:docs at python.org"
+        >docs at python.org</a>.  If you find specific errors in
+      this document, please report the bug at the <a
+        href="http://sourceforge.net/bugs/?group_id=5470">Python Bug
+        Tracker</a> at <a href="http://sourceforge.net/">SourceForge</a>.
+      If you are able to provide suggested text, either to replace
+      existing incorrect or unclear material, or additional text to
+      supplement what's already available, we'd appreciate the
+      contribution.  There's no need to worry about text markup; our
+      documentation team will gladly take care of that.
+    </p>
+
+    <p> Questions regarding how to use the information in this
+      document should be sent to the Python news group, <a
+        href="news:comp.lang.python">comp.lang.python</a>, or the <a
+        href="http://www.python.org/mailman/listinfo/python-list"
+        >Python mailing list</a> (which is gated to the newsgroup and
+      carries the same content).
+    </p>
+
+    <p> For any of these channels, please be sure not to send HTML email.
+      Thanks.
+    </p>
+
+    <hr>
+  </body>
+</html>

Added: vendor/Python/current/Doc/html/icons/blank.gif
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Doc/html/icons/blank.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Doc/html/icons/blank.png
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Doc/html/icons/blank.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Doc/html/icons/contents.gif
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Doc/html/icons/contents.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Doc/html/icons/contents.png
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Doc/html/icons/contents.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Doc/html/icons/index.gif
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Doc/html/icons/index.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Doc/html/icons/index.png
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Doc/html/icons/index.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Doc/html/icons/modules.gif
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Doc/html/icons/modules.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Doc/html/icons/modules.png
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Doc/html/icons/modules.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Doc/html/icons/next.gif
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Doc/html/icons/next.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Doc/html/icons/next.png
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Doc/html/icons/next.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Doc/html/icons/previous.gif
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Doc/html/icons/previous.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Doc/html/icons/previous.png
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Doc/html/icons/previous.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Doc/html/icons/pyfav.gif
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Doc/html/icons/pyfav.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Doc/html/icons/pyfav.png
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Doc/html/icons/pyfav.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Doc/html/icons/up.gif
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Doc/html/icons/up.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Doc/html/icons/up.png
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Doc/html/icons/up.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Doc/html/index.html.in
===================================================================
--- vendor/Python/current/Doc/html/index.html.in	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/html/index.html.in	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,140 @@
+<html>
+  <head>
+    <title>Python @RELEASE@ Documentation - @DATE@</title>
+    <meta name="aesop" content="links">
+    <meta name="description"
+          content="Top-level index to the standard documentation for
+                   Python @RELEASE at .">
+    <link rel="SHORTCUT ICON" href="icons/pyfav.png" type="image/png">
+    <link rel="STYLESHEET" href="lib/lib.css" type="text/css">
+    <link rel="author" href="acks.html" title="Acknowledgements">
+    <link rel="help" href="about.html" title="About the Python Documentation">
+    <link rel="index" href="modindex.html" title="Global Module Index">
+    <style type="text/css">
+      a.title { font-weight: bold; font-size: 110%; }
+      ul { margin-left: 1em; padding: 0pt; border: 0pt; }
+      ul li { margin-top: 0.2em; }
+      td.left-column { padding-right: 1em; }
+      td.right-column { padding-left: 1em; }
+    </style>
+  </head>
+  <body>
+	<div class="navigation">
+	<table align="center" width="100%" cellpadding="0" cellspacing="2">
+	<tr>
+	  <td><img width="32" height="32" align="bottom" border="0" alt=""
+	      src="icons/blank.png"></td>
+	  <td><img width="32" height="32" align="bottom" border="0" alt=""
+	      src="icons/blank.png"></td>
+	  <td><img width="32" height="32" align="bottom" border="0" alt=""
+	      src="icons/blank.png"></td>
+	  <td align="center" width="100%">
+	    <b class="title">Python Documentation</b></td>
+	  <td><img width="32" height="32" align="bottom" border="0" alt=""
+	      src="icons/blank.png"></td>
+	  <td><a href="modindex.html"><img width="32" height="32"
+		align="bottom" border="0" alt="Module Index"
+		src="icons/modules.png"></a></td>
+	  <td><img width="32" height="32" align="bottom" border="0" alt=""
+	      src="icons/blank.png"></A></td>
+	</tr>
+	</table>
+        <hr>
+	</div>
+    <div align="center" class="titlepage">
+      <h1>Python Documentation</h1>
+
+      <p>
+	<strong>Release @RELEASE@</strong>
+	<br>
+	<strong>@DATE@</strong>
+      </p>
+    </div>
+
+    <table align="center">
+      <tbody>
+        <tr>
+          <td class="left-column">
+	  <ul>
+	    <li> <a href="tut/tut.html" class="title">Tutorial</a>
+	      <br>(start here)
+	  </ul>
+	  </td>
+	  <td class="right-column">
+	  <ul>
+            <li> <a href="whatsnew/@WHATSNEW at .html" class="title"
+                >What's New in Python</a>
+              <br>(changes since the last major release)
+	  </ul>
+	  </td>
+        </tr>
+        <tr>
+          <td valign="baseline" class="left-column">
+          &nbsp;
+	  <ul>
+	    <li> <a href="modindex.html" class="title">Global Module Index</a>
+	      <br>(for quick access to all documentation)
+
+	    <li> <a href="lib/lib.html" class="title">Library Reference</a>
+	      <br>(keep this under your pillow)
+
+	    <li> <a href="mac/mac.html" class="title">Macintosh Module
+		Reference</a>
+	      <br>(this too, if you use a Macintosh)
+
+	    <li> <a href="inst/inst.html" class="title">Installing
+		Python Modules</a>
+	      <br>(for administrators)
+
+	    <li> <a href="dist/dist.html" class="title">Distributing
+		Python Modules</a>
+	      <br>(for developers and packagers)
+	  </ul>
+	  </td>
+	  <td valign="baseline" class="right-column">
+          &nbsp;
+	  <ul>
+	    <li> <a href="ref/ref.html" class="title">Language Reference</a>
+	      <br>(for language lawyers)
+
+	    <li> <a href="ext/ext.html" class="title">Extending and
+		Embedding</a>
+	      <br>(tutorial for C/C++ programmers)
+
+	    <li> <a href="api/api.html" class="title">Python/C API</a>
+	      <br>(reference for C/C++ programmers)
+
+	    <li> <a href="doc/doc.html" class="title">Documenting Python</a>
+	      <br>(information for documentation authors)
+	  </ul>
+	  </td>
+        </tr>
+        <tr>
+          <td valign="baseline" class="left-column">
+          &nbsp;
+          <ul>
+            <li> <a href="http://www.python.org/doc/" class="title"
+                >Documentation Central</a>
+              <br>(for everyone)
+          </ul>
+          </td>
+          <td valign="baseline" class="right-column">
+          &nbsp;
+          <ul>
+            <li> <a href="http://www.python.org/doc/howto/" class="title"
+                >Python How-To Guides</a>
+              <br>(special topics)
+          </ul>
+          </td>
+        </tr>
+      </tbody>
+    </table>
+    <p>
+
+    <address>
+      <hr>
+      See <i><a href="about.html">About the Python Documentation</a></i>
+      for information on suggesting changes.
+    </address>
+  </body>
+</html>

Added: vendor/Python/current/Doc/html/stdabout.dat
===================================================================
--- vendor/Python/current/Doc/html/stdabout.dat	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/html/stdabout.dat	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,54 @@
+<p> This document was generated using the <a
+    href="http://saftsack.fs.uni-bayreuth.de/;SPMtilde;latex2ht/">
+    <strong>LaTeX</strong>2<tt>HTML</tt></a> translator.
+</p>
+
+<p> <a
+    href="http://saftsack.fs.uni-bayreuth.de/;SPMtilde;latex2ht/">
+    <strong>LaTeX</strong>2<tt>HTML</tt></a> is Copyright &copy;
+  1993, 1994, 1995, 1996, 1997, <a
+    href="http://cbl.leeds.ac.uk/nikos/personal.html">Nikos
+    Drakos</a>, Computer Based Learning Unit, University of
+  Leeds, and Copyright &copy; 1997, 1998, <a
+    href="http://www.maths.mq.edu.au/;SPMtilde;ross/">Ross
+    Moore</a>, Mathematics Department, Macquarie University,
+  Sydney.
+</p>
+
+<p> The application of <a
+    href="http://saftsack.fs.uni-bayreuth.de/;SPMtilde;latex2ht/">
+    <strong>LaTeX</strong>2<tt>HTML</tt></a> to the Python
+  documentation has been heavily tailored by Fred L. Drake,
+  Jr.  Original navigation icons were contributed by Christopher
+  Petrilli.
+</p>
+
+<hr>
+
+<h2>Comments and Questions</h2>
+
+<p> General comments and questions regarding this document should
+  be sent by email to <a href="mailto:docs at python.org"
+    >docs at python.org</a>.  If you find specific errors in
+  this document, either in the content or the presentation, please
+  report the bug at the <a
+    href="http://sourceforge.net/bugs/?group_id=5470">Python Bug
+    Tracker</a> at <a href="http://sourceforge.net/">SourceForge</a>.
+  If you are able to provide suggested text, either to replace
+  existing incorrect or unclear material, or additional text to
+  supplement what's already available, we'd appreciate the
+  contribution.  There's no need to worry about text markup; our
+  documentation team will gladly take care of that.
+</p>
+
+<p> Questions regarding how to use the information in this
+  document should be sent to the Python news group, <a
+    href="news:comp.lang.python">comp.lang.python</a>, or the <a
+    href="http://www.python.org/mailman/listinfo/python-list"
+    >Python mailing list</a> (which is gated to the newsgroup and
+  carries the same content).
+</p>
+
+<p> For any of these channels, please be sure not to send HTML email.
+  Thanks.
+</p>

Added: vendor/Python/current/Doc/html/style.css
===================================================================
--- vendor/Python/current/Doc/html/style.css	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/html/style.css	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,243 @@
+/*
+ * The first part of this is the standard CSS generated by LaTeX2HTML,
+ * with the "empty" declarations removed.
+ */
+
+/* Century Schoolbook font is very similar to Computer Modern Math: cmmi */
+.math                   { font-family: "Century Schoolbook", serif; }
+.math i                 { font-family: "Century Schoolbook", serif;
+                          font-weight: bold }
+.boldmath               { font-family: "Century Schoolbook", serif;
+                          font-weight: bold }
+
+/*
+ * Implement both fixed-size and relative sizes.
+ *
+ * I think these can be safely removed, as it doesn't appear that
+ * LaTeX2HTML ever generates these, even though these are carried
+ * over from the LaTeX2HTML stylesheet.
+ */
+small.xtiny             { font-size : xx-small; }
+small.tiny              { font-size : x-small; }
+small.scriptsize        { font-size : smaller; }
+small.footnotesize      { font-size : small; }
+big.xlarge              { font-size : large; }
+big.xxlarge             { font-size : x-large; }
+big.huge                { font-size : larger; }
+big.xhuge               { font-size : xx-large; }
+
+/*
+ * Document-specific styles come next;
+ * these are added for the Python documentation.
+ *
+ * Note that the size specifications for the H* elements are because
+ * Netscape on Solaris otherwise doesn't get it right; they all end up
+ * the normal text size.
+ */
+
+body                    { color: #000000;
+                          background-color: #ffffff; }
+
+a:link:active           { color: #ff0000; }
+a:link:hover            { background-color: #bbeeff; }
+a:visited:hover         { background-color: #bbeeff; }
+a:visited               { color: #551a8b; }
+a:link                  { color: #0000bb; }
+
+h1, h2, h3, h4, h5, h6  { font-family: avantgarde, sans-serif;
+                          font-weight: bold; }
+h1                      { font-size: 180%; }
+h2                      { font-size: 150%; }
+h3, h4                  { font-size: 120%; }
+
+/* These are section titles used in navigation links, so make sure we
+ * match the section header font here, even it not the weight.
+ */
+.sectref                { font-family: avantgarde, sans-serif; }
+/* And the label before the titles in navigation: */
+.navlabel               { font-size: 85%; }
+
+
+/* LaTeX2HTML insists on inserting <br> elements into headers which
+ * are marked with \label.  This little bit of CSS magic ensures that
+ * these elements don't cause spurious whitespace to be added.
+ */
+h1>br, h2>br, h3>br,
+h4>br, h5>br, h6>br     { display: none; }
+
+code, tt                { font-family: "lucida typewriter", lucidatypewriter,
+                                       monospace; }
+var                     { font-family: times, serif;
+                          font-style: italic;
+                          font-weight: normal; }
+
+.Unix                   { font-variant: small-caps; }
+
+.typelabel              { font-family: lucida, sans-serif; }
+
+.navigation td          { background-color: #99ccff;
+                          font-weight: bold;
+                          font-family: avantgarde, sans-serif;
+                          font-size: 110%; }
+
+div.warning             { background-color: #fffaf0;
+                          border: thin solid black;
+                          padding: 1em;
+                          margin-left: 2em;
+                          margin-right: 2em; }
+
+div.warning .label      { font-family: sans-serif;
+                          font-size: 110%;
+                          margin-right: 0.5em; }
+
+div.note                { background-color: #fffaf0;
+                          border: thin solid black;
+                          padding: 1em;
+                          margin-left: 2em;
+                          margin-right: 2em; }
+
+div.note .label         { margin-right: 0.5em;
+                          font-family: sans-serif; }
+
+address                 { font-size: 80%; }
+.release-info           { font-style: italic;
+                          font-size: 80%; }
+
+.titlegraphic           { vertical-align: top; }
+
+.verbatim pre           { color: #00008b;
+                          font-family: "lucida typewriter", lucidatypewriter,
+                                       monospace;
+                          font-size: 90%; }
+.verbatim               { margin-left: 2em; }
+.verbatim .footer       { padding: 0.05in;
+                          font-size: 85%;
+                          background-color: #99ccff;
+                          margin-right: 0.5in; }
+
+.grammar                { background-color: #99ccff;
+                          margin-right: 0.5in;
+                          padding: 0.05in; }
+.grammar-footer         { padding: 0.05in;
+                          font-size: 85%; }
+.grammartoken           { font-family: "lucida typewriter", lucidatypewriter,
+                                       monospace; }
+
+.productions                  { background-color: #bbeeff; }
+.productions a:active         { color: #ff0000; }
+.productions a:link:hover     { background-color: #99ccff; }
+.productions a:visited:hover  { background-color: #99ccff; }
+.productions a:visited        { color: #551a8b; }
+.productions a:link           { color: #0000bb; }
+.productions table            { vertical-align: baseline;
+                                empty-cells: show; }
+.productions > table td,
+.productions > table th       { padding: 2px; }
+.productions > table td:first-child,
+.productions > table td:last-child {
+                                font-family: "lucida typewriter",
+                                             lucidatypewriter,
+                                             monospace;
+                                }
+/* same as the second selector above, but expressed differently for Opera */
+.productions > table td:first-child + td + td {
+                                font-family: "lucida typewriter",
+                                             lucidatypewriter,
+                                             monospace;
+                                vertical-align: baseline;
+                                }
+.productions > table td:first-child + td {
+                                padding-left: 1em;
+                                padding-right: 1em;
+                                }
+.productions > table tr       { vertical-align: baseline; }
+
+.email                  { font-family: avantgarde, sans-serif; }
+.mailheader             { font-family: avantgarde, sans-serif; }
+.mimetype               { font-family: avantgarde, sans-serif; }
+.newsgroup              { font-family: avantgarde, sans-serif; }
+.url                    { font-family: avantgarde, sans-serif; }
+.file                   { font-family: avantgarde, sans-serif; }
+.guilabel               { font-family: avantgarde, sans-serif; }
+
+.realtable              { border-collapse: collapse;
+                          border-color: black;
+                          border-style: solid;
+                          border-width: 0px 0px 2px 0px;
+                          empty-cells: show;
+                          margin-left: auto;
+                          margin-right: auto;
+                          padding-left: 0.4em;
+                          padding-right: 0.4em;
+                          }
+.realtable tbody        { vertical-align: baseline; }
+.realtable tfoot        { display: table-footer-group; }
+.realtable thead        { background-color: #99ccff;
+                          border-width: 0px 0px 2px 1px;
+                          display: table-header-group;
+                          font-family: avantgarde, sans-serif;
+                          font-weight: bold;
+                          vertical-align: baseline;
+                          }
+.realtable thead :first-child {
+                          border-width: 0px 0px 2px 0px;
+                          }
+.realtable thead th     { border-width: 0px 0px 2px 1px }
+.realtable td,
+.realtable th           { border-color: black;
+                          border-style: solid;
+                          border-width: 0px 0px 1px 1px;
+                          padding-left: 0.4em;
+                          padding-right: 0.4em;
+                          }
+.realtable td:first-child,
+.realtable th:first-child {
+                          border-left-width: 0px;
+                          vertical-align: baseline;
+                          }
+.center                 { text-align: center; }
+.left                   { text-align: left; }
+.right                  { text-align: right; }
+
+.refcount-info          { font-style: italic; }
+.refcount-info .value   { font-weight: bold;
+                          color: #006600; }
+
+/*
+ * Some decoration for the "See also:" blocks, in part inspired by some of
+ * the styling on Lars Marius Garshol's XSA pages.
+ * (The blue in the navigation bars is #99CCFF.)
+ */
+.seealso                { background-color: #fffaf0;
+                          border: thin solid black;
+                          padding: 0pt 1em 4pt 1em; }
+
+.seealso > .heading     { font-size: 110%;
+                          font-weight: bold; }
+
+/*
+ * Class 'availability' is used for module availability statements at
+ * the top of modules.
+ */
+.availability .platform { font-weight: bold; }
+
+
+/*
+ * Additional styles for the distutils package.
+ */
+.du-command             { font-family: monospace; }
+.du-option              { font-family: avantgarde, sans-serif; }
+.du-filevar             { font-family: avantgarde, sans-serif;
+                          font-style: italic; }
+.du-xxx:before          { content: "** ";
+                          font-weight: bold; }
+.du-xxx:after           { content: " **";
+                          font-weight: bold; }
+
+
+/*
+ * Some specialization for printed output.
+ */
+ at media print {
+  .online-navigation    { display: none; }
+  }

Added: vendor/Python/current/Doc/info/README
===================================================================
--- vendor/Python/current/Doc/info/README	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/info/README	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,21 @@
+This archive contains the standard Python documentation in GNU info
+format.  Five manuals are included:
+
+    python-ref.info*	Python Reference Manual
+    python-mac.info*	Python Macintosh Modules
+    python-lib.info*	Python Library Reference
+    python-ext.info*	Extending and Embedding the Python Interpreter
+    python-api.info*	Python/C API Reference
+    python-tut.info*	Python Tutorial
+
+The file python.dir is a fragment of a "dir" file that can be used to
+incorporate these documents into an existing GNU info installation:
+insert the contents of this file into the "dir" or "localdir" file at
+an appropriate point and copy the python-*.info* files to the same
+directory.
+
+Thanks go to Milan Zamazal <pdm at zamazal.org> for providing this
+conversion to the info format.
+
+Questions and comments on these documents should be directed to
+docs at python.org.

Added: vendor/Python/current/Doc/info/python.dir
===================================================================
--- vendor/Python/current/Doc/info/python.dir	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/info/python.dir	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,11 @@
+
+Python Standard Documentation
+
+* What's New: (python-whatsnew25).      What's New in Python 2.5?
+* Python Library: (python-lib).         Python Library Reference
+* Python Mac Modules: (python-mac).     Python Macintosh Modules
+* Python Reference: (python-ref).       Python Reference Manual
+* Python API: (python-api).             Python/C API Reference Manual
+* Python Extending: (python-ext).       Extending & Embedding Python
+* Python Tutorial: (python-tut).        Python Tutorial
+* Distributing Modules: (python-dist).  Distributing Python Modules

Added: vendor/Python/current/Doc/inst/inst.tex
===================================================================
--- vendor/Python/current/Doc/inst/inst.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/inst/inst.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1112 @@
+\documentclass{howto}
+\usepackage{distutils}
+
+% TODO:
+%   Fill in XXX comments
+
+\title{Installing Python Modules}
+
+% The audience for this document includes people who don't know anything 
+% about Python and aren't about to learn the language just in order to
+% install and maintain it for their users, i.e. system administrators.
+% Thus, I have to be sure to explain the basics at some point:
+% sys.path and PYTHONPATH at least.  Should probably give pointers to
+% other docs on "import site", PYTHONSTARTUP, PYTHONHOME, etc.
+% 
+% Finally, it might be useful to include all the material from my "Care
+% and Feeding of a Python Installation" talk in here somewhere.  Yow!
+
+\input{boilerplate}
+
+\author{Greg Ward}
+\authoraddress{
+	\strong{Python Software Foundation}\\
+	Email: \email{distutils-sig at python.org}
+}
+
+\makeindex
+
+\begin{document}
+
+\maketitle
+
+\begin{abstract}
+  \noindent
+  This document describes the Python Distribution Utilities
+  (``Distutils'') from the end-user's point-of-view, describing how to
+  extend the capabilities of a standard Python installation by building
+  and installing third-party Python modules and extensions.
+\end{abstract}
+
+%\begin{abstract}
+%\noindent
+%Abstract this!
+%\end{abstract}
+
+
+% The ugly "%begin{latexonly}" pseudo-environment suppresses the table
+% of contents for HTML generation.
+%
+%begin{latexonly}
+\tableofcontents
+%end{latexonly}
+
+
+\section{Introduction}
+\label{intro}
+
+Although Python's extensive standard library covers many programming
+needs, there often comes a time when you need to add some new
+functionality to your Python installation in the form of third-party
+modules.  This might be necessary to support your own programming, or to
+support an application that you want to use and that happens to be
+written in Python.
+
+In the past, there has been little support for adding third-party
+modules to an existing Python installation.  With the introduction of
+the Python Distribution Utilities (Distutils for short) in Python 2.0,
+this changed.
+
+This document is aimed primarily at the people who need to install
+third-party Python modules: end-users and system administrators who just
+need to get some Python application running, and existing Python
+programmers who want to add some new goodies to their toolbox.  You
+don't need to know Python to read this document; there will be some
+brief forays into using Python's interactive mode to explore your
+installation, but that's it.  If you're looking for information on how
+to distribute your own Python modules so that others may use them, see
+the \citetitle[../dist/dist.html]{Distributing Python Modules} manual.
+
+
+\subsection{Best case: trivial installation}
+\label{trivial-install}
+
+In the best case, someone will have prepared a special version of the
+module distribution you want to install that is targeted specifically at
+your platform and is installed just like any other software on your
+platform.  For example, the module developer might make an executable
+installer available for Windows users, an RPM package for users of
+RPM-based Linux systems (Red Hat, SuSE, Mandrake, and many others), a
+Debian package for users of Debian-based Linux systems, and so forth.
+
+In that case, you would download the installer appropriate to your
+platform and do the obvious thing with it: run it if it's an executable
+installer, \code{rpm --install} it if it's an RPM, etc.  You don't need
+to run Python or a setup script, you don't need to compile
+anything---you might not even need to read any instructions (although
+it's always a good idea to do so anyways).
+
+Of course, things will not always be that easy.  You might be interested
+in a module distribution that doesn't have an easy-to-use installer for
+your platform.  In that case, you'll have to start with the source
+distribution released by the module's author/maintainer.  Installing
+from a source distribution is not too hard, as long as the modules are
+packaged in the standard way.  The bulk of this document is about
+building and installing modules from standard source distributions.
+
+
+\subsection{The new standard: Distutils}
+\label{new-standard}
+
+If you download a module source distribution, you can tell pretty
+quickly if it was packaged and distributed in the standard way, i.e.
+using the Distutils.  First, the distribution's name and version number
+will be featured prominently in the name of the downloaded archive, e.g.
+\file{foo-1.0.tar.gz} or \file{widget-0.9.7.zip}.  Next, the archive
+will unpack into a similarly-named directory: \file{foo-1.0} or
+\file{widget-0.9.7}.  Additionally, the distribution will contain a
+setup script \file{setup.py}, and a file named \file{README.txt} or possibly
+just \file{README}, which should explain that building and installing the
+module distribution is a simple matter of running
+
+\begin{verbatim}
+python setup.py install
+\end{verbatim}
+
+If all these things are true, then you already know how to build and
+install the modules you've just downloaded:  Run the command above.
+Unless you need to install things in a non-standard way or customize the
+build process, you don't really need this manual.  Or rather, the above
+command is everything you need to get out of this manual.
+
+
+\section{Standard Build and Install}
+\label{standard-install}
+
+As described in section~\ref{new-standard}, building and installing
+a module distribution using the Distutils is usually one simple command:
+
+\begin{verbatim}
+python setup.py install
+\end{verbatim}
+
+On \UNIX, you'd run this command from a shell prompt; on Windows, you
+have to open a command prompt window (``DOS box'') and do it there; on
+Mac OS X, you open a \command{Terminal} window to get a shell prompt.
+
+
+\subsection{Platform variations}
+\label{platform-variations}
+
+You should always run the setup command from the distribution root
+directory, i.e. the top-level subdirectory that the module source
+distribution unpacks into.  For example, if you've just downloaded a
+module source distribution \file{foo-1.0.tar.gz} onto a
+\UNIX{} system, the normal thing to do is:
+
+\begin{verbatim}
+gunzip -c foo-1.0.tar.gz | tar xf -    # unpacks into directory foo-1.0
+cd foo-1.0
+python setup.py install
+\end{verbatim}
+
+On Windows, you'd probably download \file{foo-1.0.zip}.  If you
+downloaded the archive file to \file{C:\textbackslash{}Temp}, then it
+would unpack into \file{C:\textbackslash{}Temp\textbackslash{}foo-1.0};
+you can use either a archive manipulator with a graphical user interface
+(such as WinZip) or a command-line tool (such as \program{unzip} or
+\program{pkunzip}) to unpack the archive.  Then, open a command prompt
+window (``DOS box''), and run:
+
+\begin{verbatim}
+cd c:\Temp\foo-1.0
+python setup.py install
+\end{verbatim}
+
+\subsection{Splitting the job up}
+\label{splitting-up}
+
+Running \code{setup.py install} builds and installs all modules in one
+run.  If you prefer to work incrementally---especially useful if you
+want to customize the build process, or if things are going wrong---you
+can use the setup script to do one thing at a time.  This is
+particularly helpful when the build and install will be done by
+different users---for example, you might want to build a module distribution
+and hand it off to a system administrator for installation (or do it
+yourself, with super-user privileges).
+
+For example, you can build everything in one step, and then install
+everything in a second step, by invoking the setup script twice:
+
+\begin{verbatim}
+python setup.py build
+python setup.py install
+\end{verbatim}
+
+If you do this, you will notice that running the \command{install}
+command first runs the \command{build} command, which---in this
+case---quickly notices that it has nothing to do, since everything in
+the \file{build} directory is up-to-date.
+
+You may not need this ability to break things down often if all you do
+is install modules downloaded off the 'net, but it's very handy for more
+advanced tasks.  If you get into distributing your own Python modules
+and extensions, you'll run lots of individual Distutils commands on
+their own.
+
+
+\subsection{How building works}
+\label{how-build-works}
+
+As implied above, the \command{build} command is responsible for putting
+the files to install into a \emph{build directory}.  By default, this is
+\file{build} under the distribution root; if you're excessively
+concerned with speed, or want to keep the source tree pristine, you can
+change the build directory with the \longprogramopt{build-base} option.
+For example:
+
+\begin{verbatim}
+python setup.py build --build-base=/tmp/pybuild/foo-1.0
+\end{verbatim}
+
+(Or you could do this permanently with a directive in your system or
+personal Distutils configuration file; see
+section~\ref{config-files}.)  Normally, this isn't necessary.
+
+The default layout for the build tree is as follows:
+
+\begin{verbatim}
+--- build/ --- lib/
+or
+--- build/ --- lib.<plat>/
+               temp.<plat>/
+\end{verbatim}
+
+where \code{<plat>} expands to a brief description of the current
+OS/hardware platform and Python version.  The first form, with just a
+\file{lib} directory, is used for ``pure module distributions''---that
+is, module distributions that include only pure Python modules.  If a
+module distribution contains any extensions (modules written in C/\Cpp),
+then the second form, with two \code{<plat>} directories, is used.  In
+that case, the \file{temp.\filevar{plat}} directory holds temporary
+files generated by the compile/link process that don't actually get
+installed.  In either case, the \file{lib} (or
+\file{lib.\filevar{plat}}) directory contains all Python modules (pure
+Python and extensions) that will be installed.
+
+In the future, more directories will be added to handle Python scripts,
+documentation, binary executables, and whatever else is needed to handle
+the job of installing Python modules and applications.
+
+
+\subsection{How installation works}
+\label{how-install-works}
+
+After the \command{build} command runs (whether you run it explicitly,
+or the \command{install} command does it for you), the work of the
+\command{install} command is relatively simple: all it has to do is copy
+everything under \file{build/lib} (or \file{build/lib.\filevar{plat}})
+to your chosen installation directory.
+
+If you don't choose an installation directory---i.e., if you just run
+\code{setup.py install}---then the \command{install} command installs to
+the standard location for third-party Python modules.  This location
+varies by platform and by how you built/installed Python itself.  On
+\UNIX{} (and Mac OS X, which is also \UNIX-based),
+it also depends on whether the module distribution
+being installed is pure Python or contains extensions (``non-pure''):
+\begin{tableiv}{l|l|l|c}{textrm}%
+  {Platform}{Standard installation location}{Default value}{Notes}
+  \lineiv{\UNIX{} (pure)}
+          {\filenq{\filevar{prefix}/lib/python\shortversion/site-packages}}
+          {\filenq{/usr/local/lib/python\shortversion/site-packages}}
+          {(1)}
+  \lineiv{\UNIX{} (non-pure)}
+          {\filenq{\filevar{exec-prefix}/lib/python\shortversion/site-packages}}
+          {\filenq{/usr/local/lib/python\shortversion/site-packages}}
+          {(1)}
+  \lineiv{Windows}
+          {\filenq{\filevar{prefix}}}
+          {\filenq{C:\textbackslash{}Python}}
+          {(2)}
+\end{tableiv}
+
+\noindent Notes:
+\begin{description}
+\item[(1)] Most Linux distributions include Python as a standard part of
+  the system, so \filevar{prefix} and \filevar{exec-prefix} are usually
+  both \file{/usr} on Linux.  If you build Python yourself on Linux (or
+  any \UNIX-like system), the default \filevar{prefix} and
+  \filevar{exec-prefix} are \file{/usr/local}.
+\item[(2)] The default installation directory on Windows was
+  \file{C:\textbackslash{}Program Files\textbackslash{}Python} under
+  Python 1.6a1, 1.5.2, and earlier.
+\end{description}
+
+\filevar{prefix} and \filevar{exec-prefix} stand for the directories
+that Python is installed to, and where it finds its libraries at
+run-time.  They are always the same under Windows, and very
+often the same under \UNIX and Mac OS X.  You can find out what your Python
+installation uses for \filevar{prefix} and \filevar{exec-prefix} by
+running Python in interactive mode and typing a few simple commands.
+Under \UNIX, just type \code{python} at the shell prompt.  Under
+Windows, choose \menuselection{Start \sub Programs \sub Python
+\shortversion \sub Python (command line)}.  
+Once the interpreter is started, you type Python code at the
+prompt.  For example, on my Linux system, I type the three Python
+statements shown below, and get the output as shown, to find out my
+\filevar{prefix} and \filevar{exec-prefix}:
+
+\begin{verbatim}
+Python 2.4 (#26, Aug  7 2004, 17:19:02) 
+Type "help", "copyright", "credits" or "license" for more information.
+>>> import sys
+>>> sys.prefix
+'/usr'
+>>> sys.exec_prefix
+'/usr'
+\end{verbatim}
+
+If you don't want to install modules to the standard location, or if you
+don't have permission to write there, then you need to read about
+alternate installations in section~\ref{alt-install}.  If you want to
+customize your installation directories more heavily, see
+section~\ref{custom-install} on custom installations.
+
+
+% This rather nasty macro is used to generate the tables that describe
+% each installation scheme.  It's nasty because it takes two arguments
+% for each "slot" in an installation scheme, there will soon be more
+% than five of these slots, and TeX has a limit of 10 arguments to a
+% macro.  Uh-oh.
+
+\newcommand{\installscheme}[8]
+  {\begin{tableiii}{l|l|l}{textrm}
+          {Type of file}
+          {Installation Directory}
+          {Override option}
+     \lineiii{pure module distribution}
+             {\filevar{#1}\filenq{#2}}
+             {\longprogramopt{install-purelib}}
+     \lineiii{non-pure module distribution}
+             {\filevar{#3}\filenq{#4}}
+             {\longprogramopt{install-platlib}}
+     \lineiii{scripts}
+             {\filevar{#5}\filenq{#6}}
+             {\longprogramopt{install-scripts}}
+     \lineiii{data}
+             {\filevar{#7}\filenq{#8}}
+             {\longprogramopt{install-data}}
+   \end{tableiii}}
+
+
+\section{Alternate Installation}
+\label{alt-install}
+
+Often, it is necessary or desirable to install modules to a location
+other than the standard location for third-party Python modules.  For
+example, on a \UNIX{} system you might not have permission to write to the
+standard third-party module directory.  Or you might wish to try out a
+module before making it a standard part of your local Python
+installation.  This is especially true when upgrading a distribution
+already present: you want to make sure your existing base of scripts
+still works with the new version before actually upgrading.
+
+The Distutils \command{install} command is designed to make installing
+module distributions to an alternate location simple and painless.  The
+basic idea is that you supply a base directory for the installation, and
+the \command{install} command picks a set of directories (called an
+\emph{installation scheme}) under this base directory in which to
+install files.  The details differ across platforms, so read whichever
+of the following sections applies to you.
+
+
+\subsection{Alternate installation: the home scheme}
+\label{alt-install-prefix}
+
+The idea behind the ``home scheme'' is that you build and maintain a
+personal stash of Python modules.  This scheme's name is derived from
+the idea of a ``home'' directory on \UNIX, since it's not unusual for
+a \UNIX{} user to make their home directory have a layout similar to
+\file{/usr/} or \file{/usr/local/}.  This scheme can be used by
+anyone, regardless of the operating system their installing for.
+
+Installing a new module distribution is as simple as
+
+\begin{verbatim}
+python setup.py install --home=<dir>
+\end{verbatim}
+
+where you can supply any directory you like for the
+\longprogramopt{home} option.  On \UNIX, lazy typists can just type a
+tilde (\code{\textasciitilde}); the \command{install} command will
+expand this to your home directory:
+
+\begin{verbatim}
+python setup.py install --home=~
+\end{verbatim}
+
+The \longprogramopt{home} option defines the installation base
+directory.  Files are installed to the following directories under the
+installation base as follows:
+\installscheme{home}{/lib/python}
+              {home}{/lib/python}
+              {home}{/bin}
+              {home}{/share}
+
+
+\versionchanged[The \longprogramopt{home} option used to be supported
+                only on \UNIX]{2.4}
+
+
+\subsection{Alternate installation: \UNIX{} (the prefix scheme)}
+\label{alt-install-home}
+
+The ``prefix scheme'' is useful when you wish to use one Python
+installation to perform the build/install (i.e., to run the setup
+script), but install modules into the third-party module directory of a
+different Python installation (or something that looks like a different
+Python installation).  If this sounds a trifle unusual, it is---that's
+why the ``home scheme'' comes first.  However, there are at least two
+known cases where the prefix scheme will be useful.
+
+First, consider that many Linux distributions put Python in \file{/usr},
+rather than the more traditional \file{/usr/local}.  This is entirely
+appropriate, since in those cases Python is part of ``the system''
+rather than a local add-on.  However, if you are installing Python
+modules from source, you probably want them to go in
+\file{/usr/local/lib/python2.\filevar{X}} rather than
+\file{/usr/lib/python2.\filevar{X}}.  This can be done with
+
+\begin{verbatim}
+/usr/bin/python setup.py install --prefix=/usr/local
+\end{verbatim}
+
+Another possibility is a network filesystem where the name used to write
+to a remote directory is different from the name used to read it: for
+example, the Python interpreter accessed as \file{/usr/local/bin/python}
+might search for modules in \file{/usr/local/lib/python2.\filevar{X}},
+but those modules would have to be installed to, say,
+\file{/mnt/\filevar{@server}/export/lib/python2.\filevar{X}}.  This
+could be done with
+
+\begin{verbatim}
+/usr/local/bin/python setup.py install --prefix=/mnt/@server/export
+\end{verbatim}
+
+In either case, the \longprogramopt{prefix} option defines the
+installation base, and the \longprogramopt{exec-prefix} option defines
+the platform-specific installation base, which is used for
+platform-specific files.  (Currently, this just means non-pure module
+distributions, but could be expanded to C libraries, binary executables,
+etc.)  If \longprogramopt{exec-prefix} is not supplied, it defaults to
+\longprogramopt{prefix}.  Files are installed as follows:
+
+\installscheme{prefix}{/lib/python2.\filevar{X}/site-packages}
+              {exec-prefix}{/lib/python2.\filevar{X}/site-packages}
+              {prefix}{/bin}
+              {prefix}{/share}
+
+There is no requirement that \longprogramopt{prefix} or
+\longprogramopt{exec-prefix} actually point to an alternate Python
+installation; if the directories listed above do not already exist, they
+are created at installation time.
+
+Incidentally, the real reason the prefix scheme is important is simply
+that a standard \UNIX{} installation uses the prefix scheme, but with
+\longprogramopt{prefix} and \longprogramopt{exec-prefix} supplied by
+Python itself as \code{sys.prefix} and \code{sys.exec\_prefix}.  Thus,
+you might think you'll never use the prefix scheme, but every time you
+run \code{python setup.py install} without any other options, you're
+using it.
+
+Note that installing extensions to an alternate Python installation has
+no effect on how those extensions are built: in particular, the Python
+header files (\file{Python.h} and friends) installed with the Python
+interpreter used to run the setup script will be used in compiling
+extensions.  It is your responsibility to ensure that the interpreter
+used to run extensions installed in this way is compatible with the
+interpreter used to build them.  The best way to do this is to ensure
+that the two interpreters are the same version of Python (possibly
+different builds, or possibly copies of the same build).  (Of course, if
+your \longprogramopt{prefix} and \longprogramopt{exec-prefix} don't even
+point to an alternate Python installation, this is immaterial.)
+
+
+\subsection{Alternate installation: Windows (the prefix scheme)}
+\label{alt-install-windows}
+
+Windows has no concept of a user's home directory, and since the
+standard Python installation under Windows is simpler than under
+\UNIX, the \longprogramopt{prefix} option has traditionally been used
+to install additional packages in separate locations on Windows.
+
+\begin{verbatim}
+python setup.py install --prefix="\Temp\Python"
+\end{verbatim}
+
+to install modules to the
+\file{\textbackslash{}Temp\textbackslash{}Python} directory on the
+current drive.
+
+The installation base is defined by the \longprogramopt{prefix} option;
+the \longprogramopt{exec-prefix} option is not supported under Windows.
+Files are installed as follows:
+\installscheme{prefix}{}
+              {prefix}{}
+              {prefix}{\textbackslash{}Scripts}
+              {prefix}{\textbackslash{}Data}
+
+
+
+\section{Custom Installation}
+\label{custom-install}
+
+Sometimes, the alternate installation schemes described in
+section~\ref{alt-install} just don't do what you want.  You might
+want to tweak just one or two directories while keeping everything under
+the same base directory, or you might want to completely redefine the
+installation scheme.  In either case, you're creating a \emph{custom
+installation scheme}.
+
+You probably noticed the column of ``override options'' in the tables
+describing the alternate installation schemes above.  Those options are
+how you define a custom installation scheme.  These override options can
+be relative, absolute, or explicitly defined in terms of one of the
+installation base directories.  (There are two installation base
+directories, and they are normally the same---they only differ when you
+use the \UNIX{} ``prefix scheme'' and supply different
+\longprogramopt{prefix} and \longprogramopt{exec-prefix} options.)
+
+For example, say you're installing a module distribution to your home
+directory under \UNIX---but you want scripts to go in
+\file{\textasciitilde/scripts} rather than \file{\textasciitilde/bin}.
+As you might expect, you can override this directory with the
+\longprogramopt{install-scripts} option; in this case, it makes most
+sense to supply a relative path, which will be interpreted relative to
+the installation base directory (your home directory, in this case):
+
+\begin{verbatim}
+python setup.py install --home=~ --install-scripts=scripts
+\end{verbatim}
+
+Another \UNIX{} example: suppose your Python installation was built and
+installed with a prefix of \file{/usr/local/python}, so under a standard 
+installation scripts will wind up in \file{/usr/local/python/bin}.  If
+you want them in \file{/usr/local/bin} instead, you would supply this
+absolute directory for the \longprogramopt{install-scripts} option:
+
+\begin{verbatim}
+python setup.py install --install-scripts=/usr/local/bin
+\end{verbatim}
+
+(This performs an installation using the ``prefix scheme,'' where the
+prefix is whatever your Python interpreter was installed with---
+\file{/usr/local/python} in this case.)
+
+If you maintain Python on Windows, you might want third-party modules to
+live in a subdirectory of \filevar{prefix}, rather than right in
+\filevar{prefix} itself.  This is almost as easy as customizing the
+script installation directory---you just have to remember that there are
+two types of modules to worry about, pure modules and non-pure modules
+(i.e., modules from a non-pure distribution).  For example:
+
+\begin{verbatim}
+python setup.py install --install-purelib=Site --install-platlib=Site
+\end{verbatim}
+
+The specified installation directories are relative to
+\filevar{prefix}.  Of course, you also have to ensure that these
+directories are in Python's module search path, such as by putting a
+\file{.pth} file in \filevar{prefix}.  See section~\ref{search-path}
+to find out how to modify Python's search path.
+
+If you want to define an entire installation scheme, you just have to
+supply all of the installation directory options.  The recommended way
+to do this is to supply relative paths; for example, if you want to
+maintain all Python module-related files under \file{python} in your
+home directory, and you want a separate directory for each platform that
+you use your home directory from, you might define the following
+installation scheme:
+
+\begin{verbatim}
+python setup.py install --home=~ \
+                        --install-purelib=python/lib \
+                        --install-platlib=python/lib.$PLAT \
+                        --install-scripts=python/scripts
+                        --install-data=python/data
+\end{verbatim}
+% $ % -- bow to font-lock
+
+or, equivalently,
+
+\begin{verbatim}
+python setup.py install --home=~/python \
+                        --install-purelib=lib \
+                        --install-platlib='lib.$PLAT' \
+                        --install-scripts=scripts
+                        --install-data=data
+\end{verbatim}
+% $ % -- bow to font-lock
+
+\code{\$PLAT} is not (necessarily) an environment variable---it will be
+expanded by the Distutils as it parses your command line options, just
+as it does when parsing your configuration file(s).
+
+Obviously, specifying the entire installation scheme every time you
+install a new module distribution would be very tedious.  Thus, you can
+put these options into your Distutils config file (see
+section~\ref{config-files}):
+
+\begin{verbatim}
+[install]
+install-base=$HOME
+install-purelib=python/lib
+install-platlib=python/lib.$PLAT
+install-scripts=python/scripts
+install-data=python/data
+\end{verbatim}
+
+or, equivalently,
+
+\begin{verbatim}
+[install]
+install-base=$HOME/python
+install-purelib=lib
+install-platlib=lib.$PLAT
+install-scripts=scripts
+install-data=data
+\end{verbatim}
+
+Note that these two are \emph{not} equivalent if you supply a different
+installation base directory when you run the setup script.  For example,
+
+\begin{verbatim}
+python setup.py install --install-base=/tmp
+\end{verbatim}
+
+would install pure modules to \filevar{/tmp/python/lib} in the first
+case, and to \filevar{/tmp/lib} in the second case.  (For the second
+case, you probably want to supply an installation base of
+\file{/tmp/python}.)
+
+You probably noticed the use of \code{\$HOME} and \code{\$PLAT} in the
+sample configuration file input.  These are Distutils configuration
+variables, which bear a strong resemblance to environment variables.
+In fact, you can use environment variables in config files on
+platforms that have such a notion but the Distutils additionally
+define a few extra variables that may not be in your environment, such
+as \code{\$PLAT}.  (And of course, on systems that don't have
+environment variables, such as Mac OS 9, the configuration
+variables supplied by the Distutils are the only ones you can use.)
+See section~\ref{config-files} for details.
+
+% XXX need some Windows examples---when would custom
+% installation schemes be needed on those platforms?
+
+
+% XXX I'm not sure where this section should go.
+\subsection{Modifying Python's Search Path}
+\label{search-path}
+
+When the Python interpreter executes an \keyword{import} statement, it
+searches for both Python code and extension modules along a search
+path.  A default value for the path is configured into the Python
+binary when the interpreter is built.  You can determine the path by
+importing the \module{sys} module and printing the value of
+\code{sys.path}.  
+
+\begin{verbatim}
+$ python
+Python 2.2 (#11, Oct  3 2002, 13:31:27)
+[GCC 2.96 20000731 (Red Hat Linux 7.3 2.96-112)] on linux2
+Type ``help'', ``copyright'', ``credits'' or ``license'' for more information.
+>>> import sys
+>>> sys.path
+['', '/usr/local/lib/python2.3', '/usr/local/lib/python2.3/plat-linux2', 
+ '/usr/local/lib/python2.3/lib-tk', '/usr/local/lib/python2.3/lib-dynload', 
+ '/usr/local/lib/python2.3/site-packages']
+>>>
+\end{verbatim} % $ <-- bow to font-lock
+
+The null string in \code{sys.path} represents the current working
+directory.   
+
+The expected convention for locally installed packages is to put them
+in the \file{.../site-packages/} directory, but you may want to
+install Python modules into some arbitrary directory.  For example,
+your site may have a convention of keeping all software related to the
+web server under \file{/www}.  Add-on Python modules might then belong
+in \file{/www/python}, and in order to import them, this directory
+must be added to \code{sys.path}.  There are several different ways to
+add the directory.
+
+The most convenient way is to add a path configuration file to a
+directory that's already on Python's path, usually to the
+\file{.../site-packages/} directory.  Path configuration files have an
+extension of \file{.pth}, and each line must contain a single path
+that will be appended to \code{sys.path}.  (Because the new paths are
+appended to \code{sys.path}, modules in the added directories will not
+override standard modules.  This means you can't use this mechanism
+for installing fixed versions of standard modules.)
+
+Paths can be absolute or relative, in which case they're relative to
+the directory containing the \file{.pth} file.  Any directories added
+to the search path will be scanned in turn for \file{.pth} files.  See
+\citetitle[http://www.python.org/dev/doc/devel/lib/module-site.html]
+{site module documentation} for more information.
+
+A slightly less convenient way is to edit the \file{site.py} file in
+Python's standard library, and modify \code{sys.path}.  \file{site.py}
+is automatically imported when the Python interpreter is executed,
+unless the \programopt{-S} switch is supplied to suppress this
+behaviour.  So you could simply edit \file{site.py} and add two lines to it:
+
+\begin{verbatim}
+import sys
+sys.path.append('/www/python/')
+\end{verbatim}
+
+However, if you reinstall the same major version of Python (perhaps
+when upgrading from 2.2 to 2.2.2, for example) \file{site.py} will be
+overwritten by the stock version.  You'd have to remember that it was
+modified and save a copy before doing the installation.
+
+There are two environment variables that can modify \code{sys.path}.
+\envvar{PYTHONHOME} sets an alternate value for the prefix of the
+Python installation.  For example, if \envvar{PYTHONHOME} is set to
+\samp{/www/python}, the search path will be set to \code{['',
+'/www/python/lib/python\shortversion/',
+'/www/python/lib/python\shortversion/plat-linux2', ...]}.  
+
+The \envvar{PYTHONPATH} variable can be set to a list of paths that
+will be added to the beginning of \code{sys.path}.  For example, if
+\envvar{PYTHONPATH} is set to \samp{/www/python:/opt/py}, the search
+path will begin with \code{['/www/python', '/opt/py']}.  (Note that
+directories must exist in order to be added to \code{sys.path}; the
+\module{site} module removes paths that don't exist.)
+
+Finally, \code{sys.path} is just a regular Python list, so any Python
+application can modify it by adding or removing entries.
+
+
+\section{Distutils Configuration Files}
+\label{config-files}
+
+As mentioned above, you can use Distutils configuration files to record
+personal or site preferences for any Distutils options.  That is, any
+option to any command can be stored in one of two or three (depending on
+your platform) configuration files, which will be consulted before the
+command-line is parsed.  This means that configuration files will
+override default values, and the command-line will in turn override
+configuration files.  Furthermore, if multiple configuration files
+apply, values from ``earlier'' files are overridden by ``later'' files.
+
+
+\subsection{Location and names of config files}
+\label{config-filenames}
+
+The names and locations of the configuration files vary slightly across
+platforms.  On \UNIX{} and Mac OS X, the three configuration files (in
+the order they are processed) are:
+\begin{tableiii}{l|l|c}{textrm}
+  {Type of file}{Location and filename}{Notes}
+  \lineiii{system}{\filenq{\filevar{prefix}/lib/python\filevar{ver}/distutils/distutils.cfg}}{(1)}
+  \lineiii{personal}{\filenq{\$HOME/.pydistutils.cfg}}{(2)}
+  \lineiii{local}{\filenq{setup.cfg}}{(3)}
+\end{tableiii}
+
+And on Windows, the configuration files are:
+\begin{tableiii}{l|l|c}{textrm}
+  {Type of file}{Location and filename}{Notes}
+  \lineiii{system}{\filenq{\filevar{prefix}\textbackslash{}Lib\textbackslash{}distutils\textbackslash{}distutils.cfg}}{(4)}
+  \lineiii{personal}{\filenq{\%HOME\%\textbackslash{}pydistutils.cfg}}{(5)}
+  \lineiii{local}{\filenq{setup.cfg}}{(3)}
+\end{tableiii}
+
+\noindent Notes:
+\begin{description}
+\item[(1)] Strictly speaking, the system-wide configuration file lives
+  in the directory where the Distutils are installed; under Python 1.6
+  and later on \UNIX, this is as shown. For Python 1.5.2, the Distutils
+  will normally be installed to
+  \file{\filevar{prefix}/lib/python1.5/site-packages/distutils},
+  so the system configuration file should be put there under Python
+  1.5.2.
+\item[(2)] On \UNIX, if the \envvar{HOME} environment variable is not
+  defined, the user's home directory will be determined with the
+  \function{getpwuid()} function from the standard
+  \ulink{\module{pwd}}{../lib/module-pwd.html} module.
+\item[(3)] I.e., in the current directory (usually the location of the
+  setup script).
+\item[(4)] (See also note (1).)  Under Python 1.6 and later, Python's
+  default ``installation prefix'' is \file{C:\textbackslash{}Python}, so
+  the system configuration file is normally
+  \file{C:\textbackslash{}Python\textbackslash{}Lib\textbackslash{}distutils\textbackslash{}distutils.cfg}.
+  Under Python 1.5.2, the default prefix was
+  \file{C:\textbackslash{}Program~Files\textbackslash{}Python}, and the
+  Distutils were not part of the standard library---so the system
+  configuration file would be
+  \file{C:\textbackslash{}Program~Files\textbackslash{}Python\textbackslash{}distutils\textbackslash{}distutils.cfg}
+  in a standard Python 1.5.2 installation under Windows.
+\item[(5)] On Windows, if the \envvar{HOME} environment variable is not
+  defined, no personal configuration file will be found or used.  (In
+  other words, the Distutils make no attempt to guess your home
+  directory on Windows.)
+\end{description}
+
+
+\subsection{Syntax of config files}
+\label{config-syntax}
+
+The Distutils configuration files all have the same syntax.  The config
+files are grouped into sections.  There is one section for each Distutils
+command, plus a \code{global} section for global options that affect
+every command.  Each section consists of one option per line, specified
+as \code{option=value}.
+
+For example, the following is a complete config file that just forces
+all commands to run quietly by default:
+
+\begin{verbatim}
+[global]
+verbose=0
+\end{verbatim}
+
+If this is installed as the system config file, it will affect all
+processing of any Python module distribution by any user on the current
+system.  If it is installed as your personal config file (on systems
+that support them), it will affect only module distributions processed
+by you.  And if it is used as the \file{setup.cfg} for a particular
+module distribution, it affects only that distribution.
+
+You could override the default ``build base'' directory and make the
+\command{build*} commands always forcibly rebuild all files with the
+following:
+
+\begin{verbatim}
+[build]
+build-base=blib
+force=1
+\end{verbatim}
+
+which corresponds to the command-line arguments
+
+\begin{verbatim}
+python setup.py build --build-base=blib --force
+\end{verbatim}
+
+except that including the \command{build} command on the command-line
+means that command will be run.  Including a particular command in
+config files has no such implication; it only means that if the command
+is run, the options in the config file will apply.  (Or if other
+commands that derive values from it are run, they will use the values in
+the config file.)
+
+You can find out the complete list of options for any command using the
+\longprogramopt{help} option, e.g.:
+
+\begin{verbatim}
+python setup.py build --help
+\end{verbatim}
+
+and you can find out the complete list of global options by using
+\longprogramopt{help} without a command:
+
+\begin{verbatim}
+python setup.py --help
+\end{verbatim}
+
+See also the ``Reference'' section of the ``Distributing Python
+Modules'' manual.
+
+\section{Building Extensions: Tips and Tricks}
+\label{building-ext}
+
+Whenever possible, the Distutils try to use the configuration
+information made available by the Python interpreter used to run the
+\file{setup.py} script.  For example, the same compiler and linker
+flags used to compile Python will also be used for compiling
+extensions.  Usually this will work well, but in complicated
+situations this might be inappropriate.  This section discusses how to
+override the usual Distutils behaviour.
+
+\subsection{Tweaking compiler/linker flags}
+\label{tweak-flags}
+
+Compiling a Python extension written in C or \Cpp{} will sometimes
+require specifying custom flags for the compiler and linker in order
+to use a particular library or produce a special kind of object code.
+This is especially true if the extension hasn't been tested on your 
+platform, or if you're trying to cross-compile Python.
+
+In the most general case, the extension author might have foreseen
+that compiling the extensions would be complicated, and provided a
+\file{Setup} file for you to edit.  This will likely only be done if
+the module distribution contains many separate extension modules, or
+if they often require elaborate sets of compiler flags in order to work.
+
+A \file{Setup} file, if present, is parsed in order to get a list of
+extensions to build.  Each line in a \file{Setup} describes a single
+module.  Lines have the following structure:
+
+\begin{alltt}
+\var{module} ... [\var{sourcefile} ...] [\var{cpparg} ...] [\var{library} ...]
+\end{alltt}
+
+Let's examine each of the fields in turn.
+
+\begin{itemize}
+
+\item \var{module} is the name of the extension module to be built,
+      and should be a valid Python identifier.  You can't just change
+      this in order to rename a module (edits to the source code would
+      also be needed), so this should be left alone.
+
+\item \var{sourcefile} is anything that's likely to be a source code
+      file, at least judging by the filename.  Filenames ending in
+      \file{.c} are assumed to be written in C, filenames ending in
+      \file{.C}, \file{.cc}, and \file{.c++} are assumed to be
+      \Cpp, and filenames ending in \file{.m} or \file{.mm} are
+      assumed to be in Objective C.
+
+\item \var{cpparg} is an argument for the C preprocessor, 
+      and is anything starting with \programopt{-I}, \programopt{-D},
+      \programopt{-U} or \programopt{-C}.
+
+\item \var{library} is anything ending in \file{.a} or beginning with
+      \programopt{-l} or \programopt{-L}.
+\end{itemize}
+
+If a particular platform requires a special library on your platform,
+you can add it by editing the \file{Setup} file and running
+\code{python setup.py build}.  For example, if the module defined by the line
+
+\begin{verbatim}
+foo foomodule.c
+\end{verbatim}
+
+must be linked with the math library \file{libm.a} on your platform,
+simply add \programopt{-lm} to the line:
+
+\begin{verbatim}
+foo foomodule.c -lm
+\end{verbatim}
+
+Arbitrary switches intended for the compiler or the linker can be
+supplied with the \programopt{-Xcompiler} \var{arg} and
+\programopt{-Xlinker} \var{arg} options:
+
+\begin{verbatim}
+foo foomodule.c -Xcompiler -o32 -Xlinker -shared -lm
+\end{verbatim}
+
+The next option after \programopt{-Xcompiler} and
+\programopt{-Xlinker} will be appended to the proper command line, so
+in the above example the compiler will be passed the \programopt{-o32}
+option, and the linker will be passed \programopt{-shared}.  If a
+compiler option requires an argument, you'll have to supply multiple
+\programopt{-Xcompiler} options; for example, to pass \code{-x c++} the
+\file{Setup} file would have to contain
+\code{-Xcompiler -x -Xcompiler c++}.
+
+Compiler flags can also be supplied through setting the
+\envvar{CFLAGS} environment variable.  If set, the contents of
+\envvar{CFLAGS} will be added to the compiler flags specified in the 
+\file{Setup} file.
+
+
+\subsection{Using non-Microsoft compilers on Windows \label{non-ms-compilers}}
+\sectionauthor{Rene Liebscher}{R.Liebscher at gmx.de}
+
+\subsubsection{Borland \Cpp}
+
+This subsection describes the necessary steps to use Distutils with the 
+Borland \Cpp{} compiler version 5.5.
+%Should we mention that users have to create cfg-files for the compiler?
+%see also http://community.borland.com/article/0,1410,21205,00.html 
+
+First you have to know that Borland's object file format (OMF) is
+different from the format used by the Python version you can download
+from the Python or ActiveState Web site.  (Python is built with
+Microsoft Visual \Cpp, which uses COFF as the object file format.)
+For this reason you have to convert Python's library
+\file{python25.lib} into the Borland format.  You can do this as
+follows:
+
+\begin{verbatim}
+coff2omf python25.lib python25_bcpp.lib
+\end{verbatim}
+
+The \file{coff2omf} program comes with the Borland compiler.  The file
+\file{python25.lib} is in the \file{Libs} directory of your Python
+installation.  If your extension uses other libraries (zlib,...) you
+have to convert them too.
+
+The converted files have to reside in the same directories as the
+normal libraries.
+
+How does Distutils manage to use these libraries with their changed
+names?  If the extension needs a library (eg. \file{foo}) Distutils
+checks first if it finds a library with suffix \file{_bcpp}
+(eg. \file{foo_bcpp.lib}) and then uses this library.  In the case it
+doesn't find such a special library it uses the default name
+(\file{foo.lib}.)\footnote{This also means you could replace all
+existing COFF-libraries with OMF-libraries of the same name.}
+
+To let Distutils compile your extension with Borland \Cpp{} you now have
+to type:
+
+\begin{verbatim}
+python setup.py build --compiler=bcpp
+\end{verbatim}
+
+If you want to use the Borland \Cpp{} compiler as the default, you
+could specify this in your personal or system-wide configuration file
+for Distutils (see section~\ref{config-files}.)
+ 
+\begin{seealso}
+  \seetitle[http://www.borland.com/bcppbuilder/freecompiler/]
+    {\Cpp{}Builder Compiler}
+    {Information about the free \Cpp{} compiler from Borland,
+     including links to the download pages.}
+
+  \seetitle[http://www.cyberus.ca/\~{}g_will/pyExtenDL.shtml]
+    {Creating Python Extensions Using Borland's Free Compiler}
+    {Document describing how to use Borland's free command-line \Cpp
+     compiler to build Python.}
+\end{seealso}
+
+
+\subsubsection{GNU C / Cygwin / MinGW}
+
+These instructions only apply if you're using a version of Python prior 
+to 2.4.1 with a MinGW prior to 3.0.0 (with binutils-2.13.90-20030111-1).
+
+This section describes the necessary steps to use Distutils with the
+GNU C/\Cpp{} compilers in their Cygwin and MinGW
+distributions.\footnote{Check
+\url{http://sources.redhat.com/cygwin/} and
+\url{http://www.mingw.org/} for more information}
+For a Python interpreter that was built with Cygwin, everything should
+work without any of these following steps.
+
+These compilers require some special libraries.
+This task is more complex than for Borland's \Cpp, because there is no
+program to convert the library.
+% I don't understand what the next line means. --amk
+% (inclusive the references on data structures.)
+ 
+First you have to create a list of symbols which the Python DLL exports.
+(You can find a good program for this task at 
+\url{http://starship.python.net/crew/kernr/mingw32/Notes.html}, see at 
+PExports 0.42h there.)
+
+\begin{verbatim}
+pexports python25.dll >python25.def
+\end{verbatim}
+
+The location of an installed \file{python25.dll} will depend on the
+installation options and the version and language of Windows.  In a
+``just for me'' installation, it will appear in the root of the
+installation directory.  In a shared installation, it will be located
+in the system directory.
+
+Then you can create from these information an import library for gcc.
+ 
+\begin{verbatim}
+/cygwin/bin/dlltool --dllname python25.dll --def python25.def --output-lib libpython25.a
+\end{verbatim}
+
+The resulting library has to be placed in the same directory as 
+\file{python25.lib}. (Should be the \file{libs} directory under your
+Python installation directory.)
+
+If your extension uses other libraries (zlib,...) you might 
+have to convert them too.
+The converted files have to reside in the same directories as the normal
+libraries do.
+
+To let Distutils compile your extension with Cygwin you now have to type
+
+\begin{verbatim}
+python setup.py build --compiler=cygwin
+\end{verbatim}
+
+and for Cygwin in no-cygwin mode\footnote{Then you have no
+\POSIX{} emulation available, but you also don't need
+\file{cygwin1.dll}.} or for MinGW type:
+ 
+\begin{verbatim}
+python setup.py build --compiler=mingw32
+\end{verbatim}
+
+If you want to use any of these options/compilers as default, you should
+consider to write it in your personal or system-wide configuration file
+for Distutils (see section~\ref{config-files}.)
+
+\begin{seealso}
+  \seetitle[http://www.zope.org/Members/als/tips/win32_mingw_modules]
+    {Building Python modules on MS Windows platform with MinGW}
+    {Information about building the required libraries for the MinGW
+     environment.}
+
+  \seeurl{http://pyopengl.sourceforge.net/ftp/win32-stuff/}
+    {Converted import libraries in Cygwin/MinGW and Borland format,
+     and a script to create the registry entries needed for Distutils
+     to locate the built Python.}
+\end{seealso}
+
+
+
+\end{document}

Added: vendor/Python/current/Doc/lib/archiving.tex
===================================================================
--- vendor/Python/current/Doc/lib/archiving.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/archiving.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,8 @@
+\chapter{Data Compression and Archiving}
+\label{archiving}
+
+The modules described in this chapter support data compression
+with the zlib, gzip, and bzip2 algorithms, and 
+the creation of ZIP- and tar-format archives.
+
+\localmoduletable

Added: vendor/Python/current/Doc/lib/asttable.tex
===================================================================
--- vendor/Python/current/Doc/lib/asttable.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/asttable.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,283 @@
+\begin{longtableiii}{lll}{class}{Node type}{Attribute}{Value}
+
+\lineiii{Add}{\member{left}}{left operand}
+\lineiii{}{\member{right}}{right operand}
+\hline 
+
+\lineiii{And}{\member{nodes}}{list of operands}
+\hline 
+
+\lineiii{AssAttr}{}{\emph{attribute as target of assignment}}
+\lineiii{}{\member{expr}}{expression on the left-hand side of the dot}
+\lineiii{}{\member{attrname}}{the attribute name, a string}
+\lineiii{}{\member{flags}}{XXX}
+\hline 
+
+\lineiii{AssList}{\member{nodes}}{list of list elements being assigned to}
+\hline 
+
+\lineiii{AssName}{\member{name}}{name being assigned to}
+\lineiii{}{\member{flags}}{XXX}
+\hline 
+
+\lineiii{AssTuple}{\member{nodes}}{list of tuple elements being assigned to}
+\hline 
+
+\lineiii{Assert}{\member{test}}{the expression to be tested}
+\lineiii{}{\member{fail}}{the value of the \exception{AssertionError}}
+\hline 
+
+\lineiii{Assign}{\member{nodes}}{a list of assignment targets, one per equal sign}
+\lineiii{}{\member{expr}}{the value being assigned}
+\hline 
+
+\lineiii{AugAssign}{\member{node}}{}
+\lineiii{}{\member{op}}{}
+\lineiii{}{\member{expr}}{}
+\hline 
+
+\lineiii{Backquote}{\member{expr}}{}
+\hline 
+
+\lineiii{Bitand}{\member{nodes}}{}
+\hline 
+
+\lineiii{Bitor}{\member{nodes}}{}
+\hline 
+
+\lineiii{Bitxor}{\member{nodes}}{}
+\hline 
+
+\lineiii{Break}{}{}
+\hline 
+
+\lineiii{CallFunc}{\member{node}}{expression for the callee}
+\lineiii{}{\member{args}}{a list of arguments}
+\lineiii{}{\member{star_args}}{the extended *-arg value}
+\lineiii{}{\member{dstar_args}}{the extended **-arg value}
+\hline 
+
+\lineiii{Class}{\member{name}}{the name of the class, a string}
+\lineiii{}{\member{bases}}{a list of base classes}
+\lineiii{}{\member{doc}}{doc string, a string or \code{None}}
+\lineiii{}{\member{code}}{the body of the class statement}
+\hline 
+
+\lineiii{Compare}{\member{expr}}{}
+\lineiii{}{\member{ops}}{}
+\hline 
+
+\lineiii{Const}{\member{value}}{}
+\hline 
+
+\lineiii{Continue}{}{}
+\hline 
+
+\lineiii{Decorators}{\member{nodes}}{List of function decorator expressions}
+\hline 
+
+\lineiii{Dict}{\member{items}}{}
+\hline 
+
+\lineiii{Discard}{\member{expr}}{}
+\hline 
+
+\lineiii{Div}{\member{left}}{}
+\lineiii{}{\member{right}}{}
+\hline 
+
+\lineiii{Ellipsis}{}{}
+\hline 
+
+\lineiii{Expression}{\member{node}}{}
+
+\lineiii{Exec}{\member{expr}}{}
+\lineiii{}{\member{locals}}{}
+\lineiii{}{\member{globals}}{}
+\hline 
+
+\lineiii{FloorDiv}{\member{left}}{}
+\lineiii{}{\member{right}}{}
+\hline 
+
+\lineiii{For}{\member{assign}}{}
+\lineiii{}{\member{list}}{}
+\lineiii{}{\member{body}}{}
+\lineiii{}{\member{else_}}{}
+\hline 
+
+\lineiii{From}{\member{modname}}{}
+\lineiii{}{\member{names}}{}
+\hline 
+
+\lineiii{Function}{\member{decorators}}{\class{Decorators} or \code{None}}
+\lineiii{}{\member{name}}{name used in def, a string}
+\lineiii{}{\member{argnames}}{list of argument names, as strings}
+\lineiii{}{\member{defaults}}{list of default values}
+\lineiii{}{\member{flags}}{xxx}
+\lineiii{}{\member{doc}}{doc string, a string or \code{None}}
+\lineiii{}{\member{code}}{the body of the function}
+\hline
+
+\lineiii{GenExpr}{\member{code}}{}
+\hline
+
+\lineiii{GenExprFor}{\member{assign}}{}
+\lineiii{}{\member{iter}}{}
+\lineiii{}{\member{ifs}}{}
+\hline
+
+\lineiii{GenExprIf}{\member{test}}{}
+\hline
+
+\lineiii{GenExprInner}{\member{expr}}{}
+\lineiii{}{\member{quals}}{}
+\hline
+
+\lineiii{Getattr}{\member{expr}}{}
+\lineiii{}{\member{attrname}}{}
+\hline 
+
+\lineiii{Global}{\member{names}}{}
+\hline 
+
+\lineiii{If}{\member{tests}}{}
+\lineiii{}{\member{else_}}{}
+\hline 
+
+\lineiii{Import}{\member{names}}{}
+\hline 
+
+\lineiii{Invert}{\member{expr}}{}
+\hline 
+
+\lineiii{Keyword}{\member{name}}{}
+\lineiii{}{\member{expr}}{}
+\hline 
+
+\lineiii{Lambda}{\member{argnames}}{}
+\lineiii{}{\member{defaults}}{}
+\lineiii{}{\member{flags}}{}
+\lineiii{}{\member{code}}{}
+\hline 
+
+\lineiii{LeftShift}{\member{left}}{}
+\lineiii{}{\member{right}}{}
+\hline 
+
+\lineiii{List}{\member{nodes}}{}
+\hline 
+
+\lineiii{ListComp}{\member{expr}}{}
+\lineiii{}{\member{quals}}{}
+\hline 
+
+\lineiii{ListCompFor}{\member{assign}}{}
+\lineiii{}{\member{list}}{}
+\lineiii{}{\member{ifs}}{}
+\hline 
+
+\lineiii{ListCompIf}{\member{test}}{}
+\hline 
+
+\lineiii{Mod}{\member{left}}{}
+\lineiii{}{\member{right}}{}
+\hline 
+
+\lineiii{Module}{\member{doc}}{doc string, a string or \code{None}}
+\lineiii{}{\member{node}}{body of the module, a \class{Stmt}}
+\hline 
+
+\lineiii{Mul}{\member{left}}{}
+\lineiii{}{\member{right}}{}
+\hline 
+
+\lineiii{Name}{\member{name}}{}
+\hline 
+
+\lineiii{Not}{\member{expr}}{}
+\hline 
+
+\lineiii{Or}{\member{nodes}}{}
+\hline 
+
+\lineiii{Pass}{}{}
+\hline 
+
+\lineiii{Power}{\member{left}}{}
+\lineiii{}{\member{right}}{}
+\hline 
+
+\lineiii{Print}{\member{nodes}}{}
+\lineiii{}{\member{dest}}{}
+\hline 
+
+\lineiii{Printnl}{\member{nodes}}{}
+\lineiii{}{\member{dest}}{}
+\hline 
+
+\lineiii{Raise}{\member{expr1}}{}
+\lineiii{}{\member{expr2}}{}
+\lineiii{}{\member{expr3}}{}
+\hline 
+
+\lineiii{Return}{\member{value}}{}
+\hline 
+
+\lineiii{RightShift}{\member{left}}{}
+\lineiii{}{\member{right}}{}
+\hline 
+
+\lineiii{Slice}{\member{expr}}{}
+\lineiii{}{\member{flags}}{}
+\lineiii{}{\member{lower}}{}
+\lineiii{}{\member{upper}}{}
+\hline 
+
+\lineiii{Sliceobj}{\member{nodes}}{list of statements}
+\hline 
+
+\lineiii{Stmt}{\member{nodes}}{}
+\hline 
+
+\lineiii{Sub}{\member{left}}{}
+\lineiii{}{\member{right}}{}
+\hline 
+
+\lineiii{Subscript}{\member{expr}}{}
+\lineiii{}{\member{flags}}{}
+\lineiii{}{\member{subs}}{}
+\hline 
+
+\lineiii{TryExcept}{\member{body}}{}
+\lineiii{}{\member{handlers}}{}
+\lineiii{}{\member{else_}}{}
+\hline 
+
+\lineiii{TryFinally}{\member{body}}{}
+\lineiii{}{\member{final}}{}
+\hline 
+
+\lineiii{Tuple}{\member{nodes}}{}
+\hline 
+
+\lineiii{UnaryAdd}{\member{expr}}{}
+\hline 
+
+\lineiii{UnarySub}{\member{expr}}{}
+\hline 
+
+\lineiii{While}{\member{test}}{}
+\lineiii{}{\member{body}}{}
+\lineiii{}{\member{else_}}{}
+\hline 
+
+\lineiii{With}{\member{expr}}{}
+\lineiii{}{\member{vars}}{}
+\lineiii{}{\member{body}}{}
+\hline 
+
+\lineiii{Yield}{\member{value}}{}
+\hline 
+
+\end{longtableiii}

Added: vendor/Python/current/Doc/lib/caseless.py
===================================================================
--- vendor/Python/current/Doc/lib/caseless.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/caseless.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,60 @@
+from optparse import Option, OptionParser, _match_abbrev
+
+# This case-insensitive option parser relies on having a
+# case-insensitive dictionary type available.  Here's one
+# for Python 2.2.  Note that a *real* case-insensitive
+# dictionary type would also have to implement __new__(),
+# update(), and setdefault() -- but that's not the point
+# of this exercise.
+
+class caseless_dict (dict):
+    def __setitem__ (self, key, value):
+        dict.__setitem__(self, key.lower(), value)
+
+    def __getitem__ (self, key):
+        return dict.__getitem__(self, key.lower())
+
+    def get (self, key, default=None):
+        return dict.get(self, key.lower())
+
+    def has_key (self, key):
+        return dict.has_key(self, key.lower())
+
+
+class CaselessOptionParser (OptionParser):
+
+    def _create_option_list (self):
+        self.option_list = []
+        self._short_opt = caseless_dict()
+        self._long_opt = caseless_dict()
+        self._long_opts = []
+        self.defaults = {}
+
+    def _match_long_opt (self, opt):
+        return _match_abbrev(opt.lower(), self._long_opt.keys())
+
+
+if __name__ == "__main__":
+    from optik.errors import OptionConflictError
+
+    # test 1: no options to start with
+    parser = CaselessOptionParser()
+    try:
+        parser.add_option("-H", dest="blah")
+    except OptionConflictError:
+        print "ok: got OptionConflictError for -H"
+    else:
+        print "not ok: no conflict between -h and -H"
+
+    parser.add_option("-f", "--file", dest="file")
+    #print repr(parser.get_option("-f"))
+    #print repr(parser.get_option("-F"))
+    #print repr(parser.get_option("--file"))
+    #print repr(parser.get_option("--fIlE"))
+    (options, args) = parser.parse_args(["--FiLe", "foo"])
+    assert options.file == "foo", options.file
+    print "ok: case insensitive long options work"
+
+    (options, args) = parser.parse_args(["-F", "bar"])
+    assert options.file == "bar", options.file
+    print "ok: case insensitive short options work"


Property changes on: vendor/Python/current/Doc/lib/caseless.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Doc/lib/compiler.tex
===================================================================
--- vendor/Python/current/Doc/lib/compiler.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/compiler.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,354 @@
+\chapter{Python compiler package \label{compiler}}
+
+\sectionauthor{Jeremy Hylton}{jeremy at zope.com}
+
+
+The Python compiler package is a tool for analyzing Python source code
+and generating Python bytecode.  The compiler contains libraries to
+generate an abstract syntax tree from Python source code and to
+generate Python bytecode from the tree.
+
+The \refmodule{compiler} package is a Python source to bytecode
+translator written in Python.  It uses the built-in parser and
+standard \refmodule{parser} module to generated a concrete syntax
+tree.  This tree is used to generate an abstract syntax tree (AST) and
+then Python bytecode.
+
+The full functionality of the package duplicates the builtin compiler
+provided with the Python interpreter.  It is intended to match its
+behavior almost exactly.  Why implement another compiler that does the
+same thing?  The package is useful for a variety of purposes.  It can
+be modified more easily than the builtin compiler.  The AST it
+generates is useful for analyzing Python source code.
+
+This chapter explains how the various components of the
+\refmodule{compiler} package work.  It blends reference material with
+a tutorial.
+
+The following modules are part of the \refmodule{compiler} package:
+
+\localmoduletable
+
+
+\section{The basic interface}
+
+\declaremodule{}{compiler}
+
+The top-level of the package defines four functions.  If you import
+\module{compiler}, you will get these functions and a collection of
+modules contained in the package.
+
+\begin{funcdesc}{parse}{buf}
+Returns an abstract syntax tree for the Python source code in \var{buf}.
+The function raises \exception{SyntaxError} if there is an error in the
+source code.  The return value is a \class{compiler.ast.Module} instance
+that contains the tree.  
+\end{funcdesc}
+
+\begin{funcdesc}{parseFile}{path}
+Return an abstract syntax tree for the Python source code in the file
+specified by \var{path}.  It is equivalent to
+\code{parse(open(\var{path}).read())}.
+\end{funcdesc}
+
+\begin{funcdesc}{walk}{ast, visitor\optional{, verbose}}
+Do a pre-order walk over the abstract syntax tree \var{ast}.  Call the
+appropriate method on the \var{visitor} instance for each node
+encountered.
+\end{funcdesc}
+
+\begin{funcdesc}{compile}{source, filename, mode, flags=None, 
+			dont_inherit=None}
+Compile the string \var{source}, a Python module, statement or
+expression, into a code object that can be executed by the exec
+statement or \function{eval()}. This function is a replacement for the
+built-in \function{compile()} function.
+
+The \var{filename} will be used for run-time error messages.
+
+The \var{mode} must be 'exec' to compile a module, 'single' to compile a
+single (interactive) statement, or 'eval' to compile an expression.
+
+The \var{flags} and \var{dont_inherit} arguments affect future-related
+statements, but are not supported yet.
+\end{funcdesc}
+
+\begin{funcdesc}{compileFile}{source}
+Compiles the file \var{source} and generates a .pyc file.
+\end{funcdesc}
+
+The \module{compiler} package contains the following modules:
+\refmodule[compiler.ast]{ast}, \module{consts}, \module{future},
+\module{misc}, \module{pyassem}, \module{pycodegen}, \module{symbols},
+\module{transformer}, and \refmodule[compiler.visitor]{visitor}.
+
+\section{Limitations}
+
+There are some problems with the error checking of the compiler
+package.  The interpreter detects syntax errors in two distinct
+phases.  One set of errors is detected by the interpreter's parser,
+the other set by the compiler.  The compiler package relies on the
+interpreter's parser, so it get the first phases of error checking for
+free.  It implements the second phase itself, and that implementation is
+incomplete.  For example, the compiler package does not raise an error
+if a name appears more than once in an argument list: 
+\code{def f(x, x): ...}
+
+A future version of the compiler should fix these problems.
+
+\section{Python Abstract Syntax}
+
+The \module{compiler.ast} module defines an abstract syntax for
+Python.  In the abstract syntax tree, each node represents a syntactic
+construct.  The root of the tree is \class{Module} object.
+
+The abstract syntax offers a higher level interface to parsed Python
+source code.  The \ulink{\module{parser}}
+{http://www.python.org/doc/current/lib/module-parser.html}
+module and the compiler written in C for the Python interpreter use a
+concrete syntax tree.  The concrete syntax is tied closely to the
+grammar description used for the Python parser.  Instead of a single
+node for a construct, there are often several levels of nested nodes
+that are introduced by Python's precedence rules.
+
+The abstract syntax tree is created by the
+\module{compiler.transformer} module.  The transformer relies on the
+builtin Python parser to generate a concrete syntax tree.  It
+generates an abstract syntax tree from the concrete tree.  
+
+The \module{transformer} module was created by Greg
+Stein\index{Stein, Greg} and Bill Tutt\index{Tutt, Bill} for an
+experimental Python-to-C compiler.  The current version contains a
+number of modifications and improvements, but the basic form of the
+abstract syntax and of the transformer are due to Stein and Tutt.
+
+\subsection{AST Nodes}
+
+\declaremodule{}{compiler.ast}
+
+The \module{compiler.ast} module is generated from a text file that
+describes each node type and its elements.  Each node type is
+represented as a class that inherits from the abstract base class
+\class{compiler.ast.Node} and defines a set of named attributes for
+child nodes.
+
+\begin{classdesc}{Node}{}
+  
+  The \class{Node} instances are created automatically by the parser
+  generator.  The recommended interface for specific \class{Node}
+  instances is to use the public attributes to access child nodes.  A
+  public attribute may be bound to a single node or to a sequence of
+  nodes, depending on the \class{Node} type.  For example, the
+  \member{bases} attribute of the \class{Class} node, is bound to a
+  list of base class nodes, and the \member{doc} attribute is bound to
+  a single node.
+  
+  Each \class{Node} instance has a \member{lineno} attribute which may
+  be \code{None}.  XXX Not sure what the rules are for which nodes
+  will have a useful lineno.
+\end{classdesc}
+
+All \class{Node} objects offer the following methods:
+
+\begin{methoddesc}{getChildren}{}
+  Returns a flattened list of the child nodes and objects in the
+  order they occur.  Specifically, the order of the nodes is the
+  order in which they appear in the Python grammar.  Not all of the
+  children are \class{Node} instances.  The names of functions and
+  classes, for example, are plain strings.
+\end{methoddesc}
+
+\begin{methoddesc}{getChildNodes}{}
+  Returns a flattened list of the child nodes in the order they
+  occur.  This method is like \method{getChildren()}, except that it
+  only returns those children that are \class{Node} instances.
+\end{methoddesc}
+
+Two examples illustrate the general structure of \class{Node}
+classes.  The \keyword{while} statement is defined by the following
+grammar production: 
+
+\begin{verbatim}
+while_stmt:     "while" expression ":" suite
+               ["else" ":" suite]
+\end{verbatim}
+
+The \class{While} node has three attributes: \member{test},
+\member{body}, and \member{else_}.  (If the natural name for an
+attribute is also a Python reserved word, it can't be used as an
+attribute name.  An underscore is appended to the word to make it a
+legal identifier, hence \member{else_} instead of \keyword{else}.)
+
+The \keyword{if} statement is more complicated because it can include
+several tests.  
+
+\begin{verbatim}
+if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
+\end{verbatim}
+
+The \class{If} node only defines two attributes: \member{tests} and
+\member{else_}.  The \member{tests} attribute is a sequence of test
+expression, consequent body pairs.  There is one pair for each
+\keyword{if}/\keyword{elif} clause.  The first element of the pair is
+the test expression.  The second elements is a \class{Stmt} node that
+contains the code to execute if the test is true.
+
+The \method{getChildren()} method of \class{If} returns a flat list of
+child nodes.  If there are three \keyword{if}/\keyword{elif} clauses
+and no \keyword{else} clause, then \method{getChildren()} will return
+a list of six elements: the first test expression, the first
+\class{Stmt}, the second text expression, etc.
+
+The following table lists each of the \class{Node} subclasses defined
+in \module{compiler.ast} and each of the public attributes available
+on their instances.  The values of most of the attributes are
+themselves \class{Node} instances or sequences of instances.  When the
+value is something other than an instance, the type is noted in the
+comment.  The attributes are listed in the order in which they are
+returned by \method{getChildren()} and \method{getChildNodes()}.
+
+\input{asttable}
+
+
+\subsection{Assignment nodes}
+
+There is a collection of nodes used to represent assignments.  Each
+assignment statement in the source code becomes a single
+\class{Assign} node in the AST.  The \member{nodes} attribute is a
+list that contains a node for each assignment target.  This is
+necessary because assignment can be chained, e.g. \code{a = b = 2}.
+Each \class{Node} in the list will be one of the following classes: 
+\class{AssAttr}, \class{AssList}, \class{AssName}, or
+\class{AssTuple}. 
+
+Each target assignment node will describe the kind of object being
+assigned to:  \class{AssName} for a simple name, e.g. \code{a = 1}.
+\class{AssAttr} for an attribute assigned, e.g. \code{a.x = 1}.
+\class{AssList} and \class{AssTuple} for list and tuple expansion
+respectively, e.g. \code{a, b, c = a_tuple}.
+
+The target assignment nodes also have a \member{flags} attribute that
+indicates whether the node is being used for assignment or in a delete
+statement.  The \class{AssName} is also used to represent a delete
+statement, e.g. \class{del x}.
+
+When an expression contains several attribute references, an
+assignment or delete statement will contain only one \class{AssAttr}
+node -- for the final attribute reference.  The other attribute
+references will be represented as \class{Getattr} nodes in the
+\member{expr} attribute of the \class{AssAttr} instance.
+
+\subsection{Examples}
+
+This section shows several simple examples of ASTs for Python source
+code.  The examples demonstrate how to use the \function{parse()}
+function, what the repr of an AST looks like, and how to access
+attributes of an AST node.
+
+The first module defines a single function.  Assume it is stored in
+\file{/tmp/doublelib.py}. 
+
+\begin{verbatim}
+"""This is an example module.
+
+This is the docstring.
+"""
+
+def double(x):
+    "Return twice the argument"
+    return x * 2
+\end{verbatim}
+
+In the interactive interpreter session below, I have reformatted the
+long AST reprs for readability.  The AST reprs use unqualified class
+names.  If you want to create an instance from a repr, you must import
+the class names from the \module{compiler.ast} module.
+
+\begin{verbatim}
+>>> import compiler
+>>> mod = compiler.parseFile("/tmp/doublelib.py")
+>>> mod
+Module('This is an example module.\n\nThis is the docstring.\n', 
+       Stmt([Function(None, 'double', ['x'], [], 0,
+                      'Return twice the argument', 
+                      Stmt([Return(Mul((Name('x'), Const(2))))]))]))
+>>> from compiler.ast import *
+>>> Module('This is an example module.\n\nThis is the docstring.\n', 
+...    Stmt([Function(None, 'double', ['x'], [], 0,
+...                   'Return twice the argument', 
+...                   Stmt([Return(Mul((Name('x'), Const(2))))]))]))
+Module('This is an example module.\n\nThis is the docstring.\n', 
+       Stmt([Function(None, 'double', ['x'], [], 0,
+                      'Return twice the argument', 
+                      Stmt([Return(Mul((Name('x'), Const(2))))]))]))
+>>> mod.doc
+'This is an example module.\n\nThis is the docstring.\n'
+>>> for node in mod.node.nodes:
+...     print node
+... 
+Function(None, 'double', ['x'], [], 0, 'Return twice the argument',
+         Stmt([Return(Mul((Name('x'), Const(2))))]))
+>>> func = mod.node.nodes[0]
+>>> func.code
+Stmt([Return(Mul((Name('x'), Const(2))))])
+\end{verbatim}
+
+\section{Using Visitors to Walk ASTs}
+
+\declaremodule{}{compiler.visitor}
+
+The visitor pattern is ...  The \refmodule{compiler} package uses a
+variant on the visitor pattern that takes advantage of Python's
+introspection features to eliminate the need for much of the visitor's
+infrastructure.
+
+The classes being visited do not need to be programmed to accept
+visitors.  The visitor need only define visit methods for classes it
+is specifically interested in; a default visit method can handle the
+rest. 
+
+XXX The magic \method{visit()} method for visitors.
+
+\begin{funcdesc}{walk}{tree, visitor\optional{, verbose}}
+\end{funcdesc}
+
+\begin{classdesc}{ASTVisitor}{}
+
+The \class{ASTVisitor} is responsible for walking over the tree in the
+correct order.  A walk begins with a call to \method{preorder()}.  For
+each node, it checks the \var{visitor} argument to \method{preorder()}
+for a method named `visitNodeType,' where NodeType is the name of the
+node's class, e.g. for a \class{While} node a \method{visitWhile()}
+would be called.  If the method exists, it is called with the node as
+its first argument.
+
+The visitor method for a particular node type can control how child
+nodes are visited during the walk.  The \class{ASTVisitor} modifies
+the visitor argument by adding a visit method to the visitor; this
+method can be used to visit a particular child node.  If no visitor is
+found for a particular node type, the \method{default()} method is
+called. 
+\end{classdesc}
+
+\class{ASTVisitor} objects have the following methods:
+
+XXX describe extra arguments
+
+\begin{methoddesc}{default}{node\optional{, \moreargs}}
+\end{methoddesc}
+
+\begin{methoddesc}{dispatch}{node\optional{, \moreargs}}
+\end{methoddesc}
+
+\begin{methoddesc}{preorder}{tree, visitor}
+\end{methoddesc}
+
+
+\section{Bytecode Generation}
+
+The code generator is a visitor that emits bytecodes.  Each visit method
+can call the \method{emit()} method to emit a new bytecode.  The basic
+code generator is specialized for modules, classes, and functions.  An
+assembler converts that emitted instructions to the low-level bytecode
+format.  It handles things like generator of constant lists of code
+objects and calculation of jump offsets.

Added: vendor/Python/current/Doc/lib/custominterp.tex
===================================================================
--- vendor/Python/current/Doc/lib/custominterp.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/custominterp.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,13 @@
+\chapter{Custom Python Interpreters}
+\label{custominterp}
+
+The modules described in this chapter allow writing interfaces similar
+to Python's interactive interpreter.  If you want a Python interpreter
+that supports some special feature in addition to the Python language,
+you should look at the \module{code} module.  (The \module{codeop}
+module is lower-level, used to support compiling a possibly-incomplete
+chunk of Python code.)
+
+The full list of modules described in this chapter is:
+
+\localmoduletable

Added: vendor/Python/current/Doc/lib/datatypes.tex
===================================================================
--- vendor/Python/current/Doc/lib/datatypes.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/datatypes.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,10 @@
+\chapter{Data Types}
+\label{datatypes}
+
+The modules described in this chapter provide a variety of specialized
+data types such as dates and times, fixed-type arrays, heap queues,
+synchronized queues, and sets.
+
+The following modules are documented in this chapter:
+
+\localmoduletable

Added: vendor/Python/current/Doc/lib/development.tex
===================================================================
--- vendor/Python/current/Doc/lib/development.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/development.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,13 @@
+\chapter{Development Tools}
+\label{development}
+
+The modules described in this chapter help you write software.  For
+example, the \module{pydoc} module takes a module and generates
+documentation based on the module's contents.  The \module{doctest}
+and \module{unittest} modules contains frameworks for writing unit tests
+that automatically exercise code and verify that the expected output 
+is produced.
+
+The list of modules described in this chapter is:
+
+\localmoduletable

Added: vendor/Python/current/Doc/lib/distutils.tex
===================================================================
--- vendor/Python/current/Doc/lib/distutils.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/distutils.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,38 @@
+\section{\module{distutils} ---
+         Building and installing Python modules}
+
+\declaremodule{standard}{distutils}
+\modulesynopsis{Support for building and installing Python modules
+                into an existing Python installation.}
+\sectionauthor{Fred L. Drake, Jr.}{fdrake at acm.org}
+
+
+The \module{distutils} package provides support for building and
+installing additional modules into a Python installation.  The new
+modules may be either 100\%{}-pure Python, or may be extension modules
+written in C, or may be collections of Python packages which include
+modules coded in both Python and C.
+
+This package is discussed in two separate documents which are included
+in the Python documentation package.  To learn about distributing new
+modules using the \module{distutils} facilities, read
+\citetitle[../dist/dist.html]{Distributing Python Modules}; this
+includes documentation needed to extend distutils.  To learn
+about installing Python modules, whether or not the author made use of
+the \module{distutils} package, read
+\citetitle[../inst/inst.html]{Installing Python Modules}.
+
+
+\begin{seealso}
+  \seetitle[../dist/dist.html]{Distributing Python Modules}{The manual
+            for developers and packagers of Python modules.  This
+            describes how to prepare \module{distutils}-based packages
+            so that they may be easily installed into an existing
+            Python installation.}
+
+  \seetitle[../inst/inst.html]{Installing Python Modules}{An
+            ``administrators'' manual which includes information on
+            installing modules into an existing Python installation.
+            You do not need to be a Python programmer to read this
+            manual.}
+\end{seealso}

Added: vendor/Python/current/Doc/lib/email-dir.py
===================================================================
--- vendor/Python/current/Doc/lib/email-dir.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/email-dir.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,115 @@
+#!/usr/bin/env python
+
+"""Send the contents of a directory as a MIME message."""
+
+import os
+import sys
+import smtplib
+# For guessing MIME type based on file name extension
+import mimetypes
+
+from optparse import OptionParser
+
+from email import encoders
+from email.message import Message
+from email.mime.audio import MIMEAudio
+from email.mime.base import MIMEBase
+from email.mime.image import MIMEImage
+from email.mime.multipart import MIMEMultipart
+from email.mime.text import MIMEText
+
+COMMASPACE = ', '
+
+
+def main():
+    parser = OptionParser(usage="""\
+Send the contents of a directory as a MIME message.
+
+Usage: %prog [options]
+
+Unless the -o option is given, the email is sent by forwarding to your local
+SMTP server, which then does the normal delivery process.  Your local machine
+must be running an SMTP server.
+""")
+    parser.add_option('-d', '--directory',
+                      type='string', action='store',
+                      help="""Mail the contents of the specified directory,
+                      otherwise use the current directory.  Only the regular
+                      files in the directory are sent, and we don't recurse to
+                      subdirectories.""")
+    parser.add_option('-o', '--output',
+                      type='string', action='store', metavar='FILE',
+                      help="""Print the composed message to FILE instead of
+                      sending the message to the SMTP server.""")
+    parser.add_option('-s', '--sender',
+                      type='string', action='store', metavar='SENDER',
+                      help='The value of the From: header (required)')
+    parser.add_option('-r', '--recipient',
+                      type='string', action='append', metavar='RECIPIENT',
+                      default=[], dest='recipients',
+                      help='A To: header value (at least one required)')
+    opts, args = parser.parse_args()
+    if not opts.sender or not opts.recipients:
+        parser.print_help()
+        sys.exit(1)
+    directory = opts.directory
+    if not directory:
+        directory = '.'
+    # Create the enclosing (outer) message
+    outer = MIMEMultipart()
+    outer['Subject'] = 'Contents of directory %s' % os.path.abspath(directory)
+    outer['To'] = COMMASPACE.join(opts.recipients)
+    outer['From'] = opts.sender
+    outer.preamble = 'You will not see this in a MIME-aware mail reader.\n'
+
+    for filename in os.listdir(directory):
+        path = os.path.join(directory, filename)
+        if not os.path.isfile(path):
+            continue
+        # Guess the content type based on the file's extension.  Encoding
+        # will be ignored, although we should check for simple things like
+        # gzip'd or compressed files.
+        ctype, encoding = mimetypes.guess_type(path)
+        if ctype is None or encoding is not None:
+            # No guess could be made, or the file is encoded (compressed), so
+            # use a generic bag-of-bits type.
+            ctype = 'application/octet-stream'
+        maintype, subtype = ctype.split('/', 1)
+        if maintype == 'text':
+            fp = open(path)
+            # Note: we should handle calculating the charset
+            msg = MIMEText(fp.read(), _subtype=subtype)
+            fp.close()
+        elif maintype == 'image':
+            fp = open(path, 'rb')
+            msg = MIMEImage(fp.read(), _subtype=subtype)
+            fp.close()
+        elif maintype == 'audio':
+            fp = open(path, 'rb')
+            msg = MIMEAudio(fp.read(), _subtype=subtype)
+            fp.close()
+        else:
+            fp = open(path, 'rb')
+            msg = MIMEBase(maintype, subtype)
+            msg.set_payload(fp.read())
+            fp.close()
+            # Encode the payload using Base64
+            encoders.encode_base64(msg)
+        # Set the filename parameter
+        msg.add_header('Content-Disposition', 'attachment', filename=filename)
+        outer.attach(msg)
+    # Now send or store the message
+    composed = outer.as_string()
+    if opts.output:
+        fp = open(opts.output, 'w')
+        fp.write(composed)
+        fp.close()
+    else:
+        s = smtplib.SMTP()
+        s.connect()
+        s.sendmail(opts.sender, opts.recipients, composed)
+        s.close()
+
+
+if __name__ == '__main__':
+    main()

Added: vendor/Python/current/Doc/lib/email-mime.py
===================================================================
--- vendor/Python/current/Doc/lib/email-mime.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/email-mime.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,32 @@
+# Import smtplib for the actual sending function
+import smtplib
+
+# Here are the email package modules we'll need
+from email.mime.image import MIMEImage
+from email.mime.multipart import MIMEMultipart
+
+COMMASPACE = ', '
+
+# Create the container (outer) email message.
+msg = MIMEMultipart()
+msg['Subject'] = 'Our family reunion'
+# me == the sender's email address
+# family = the list of all recipients' email addresses
+msg['From'] = me
+msg['To'] = COMMASPACE.join(family)
+msg.preamble = 'Our family reunion'
+
+# Assume we know that the image files are all in PNG format
+for file in pngfiles:
+    # Open the files in binary mode.  Let the MIMEImage class automatically
+    # guess the specific image type.
+    fp = open(file, 'rb')
+    img = MIMEImage(fp.read())
+    fp.close()
+    msg.attach(img)
+
+# Send the email via our own SMTP server.
+s = smtplib.SMTP()
+s.connect()
+s.sendmail(me, family, msg.as_string())
+s.close()

Added: vendor/Python/current/Doc/lib/email-simple.py
===================================================================
--- vendor/Python/current/Doc/lib/email-simple.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/email-simple.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,25 @@
+# Import smtplib for the actual sending function
+import smtplib
+
+# Import the email modules we'll need
+from email.mime.text import MIMEText
+
+# Open a plain text file for reading.  For this example, assume that
+# the text file contains only ASCII characters.
+fp = open(textfile, 'rb')
+# Create a text/plain message
+msg = MIMEText(fp.read())
+fp.close()
+
+# me == the sender's email address
+# you == the recipient's email address
+msg['Subject'] = 'The contents of %s' % textfile
+msg['From'] = me
+msg['To'] = you
+
+# Send the message via our own SMTP server, but don't include the
+# envelope header.
+s = smtplib.SMTP()
+s.connect()
+s.sendmail(me, [you], msg.as_string())
+s.close()

Added: vendor/Python/current/Doc/lib/email-unpack.py
===================================================================
--- vendor/Python/current/Doc/lib/email-unpack.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/email-unpack.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,68 @@
+#!/usr/bin/env python
+
+"""Unpack a MIME message into a directory of files."""
+
+import os
+import sys
+import email
+import errno
+import mimetypes
+
+from optparse import OptionParser
+
+
+def main():
+    parser = OptionParser(usage="""\
+Unpack a MIME message into a directory of files.
+
+Usage: %prog [options] msgfile
+""")
+    parser.add_option('-d', '--directory',
+                      type='string', action='store',
+                      help="""Unpack the MIME message into the named
+                      directory, which will be created if it doesn't already
+                      exist.""")
+    opts, args = parser.parse_args()
+    if not opts.directory:
+        parser.print_help()
+        sys.exit(1)
+
+    try:
+        msgfile = args[0]
+    except IndexError:
+        parser.print_help()
+        sys.exit(1)
+
+    try:
+        os.mkdir(opts.directory)
+    except OSError, e:
+        # Ignore directory exists error
+        if e.errno <> errno.EEXIST:
+            raise
+
+    fp = open(msgfile)
+    msg = email.message_from_file(fp)
+    fp.close()
+
+    counter = 1
+    for part in msg.walk():
+        # multipart/* are just containers
+        if part.get_content_maintype() == 'multipart':
+            continue
+        # Applications should really sanitize the given filename so that an
+        # email message can't be used to overwrite important files
+        filename = part.get_filename()
+        if not filename:
+            ext = mimetypes.guess_extension(part.get_type())
+            if not ext:
+                # Use a generic bag-of-bits extension
+                ext = '.bin'
+            filename = 'part-%03d%s' % (counter, ext)
+        counter += 1
+        fp = open(os.path.join(opts.directory, filename), 'wb')
+        fp.write(part.get_payload(decode=True))
+        fp.close()
+
+
+if __name__ == '__main__':
+    main()

Added: vendor/Python/current/Doc/lib/email.tex
===================================================================
--- vendor/Python/current/Doc/lib/email.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/email.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,402 @@
+% Copyright (C) 2001-2006 Python Software Foundation
+% Author: barry at python.org (Barry Warsaw)
+
+\section{\module{email} ---
+	 An email and MIME handling package}
+
+\declaremodule{standard}{email}
+\modulesynopsis{Package supporting the parsing, manipulating, and
+    generating email messages, including MIME documents.}
+\moduleauthor{Barry A. Warsaw}{barry at python.org}
+\sectionauthor{Barry A. Warsaw}{barry at python.org}
+
+\versionadded{2.2}
+
+The \module{email} package is a library for managing email messages,
+including MIME and other \rfc{2822}-based message documents.  It
+subsumes most of the functionality in several older standard modules
+such as \refmodule{rfc822}, \refmodule{mimetools},
+\refmodule{multifile}, and other non-standard packages such as
+\module{mimecntl}.  It is specifically \emph{not} designed to do any
+sending of email messages to SMTP (\rfc{2821}), NNTP, or other servers; those
+are functions of modules such as \refmodule{smtplib} and \refmodule{nntplib}.
+The \module{email} package attempts to be as RFC-compliant as possible,
+supporting in addition to \rfc{2822}, such MIME-related RFCs as
+\rfc{2045}, \rfc{2046}, \rfc{2047}, and \rfc{2231}.
+
+The primary distinguishing feature of the \module{email} package is
+that it splits the parsing and generating of email messages from the
+internal \emph{object model} representation of email.  Applications
+using the \module{email} package deal primarily with objects; you can
+add sub-objects to messages, remove sub-objects from messages,
+completely re-arrange the contents, etc.  There is a separate parser
+and a separate generator which handles the transformation from flat
+text to the object model, and then back to flat text again.  There
+are also handy subclasses for some common MIME object types, and a few
+miscellaneous utilities that help with such common tasks as extracting
+and parsing message field values, creating RFC-compliant dates, etc.
+
+The following sections describe the functionality of the
+\module{email} package.  The ordering follows a progression that
+should be common in applications: an email message is read as flat
+text from a file or other source, the text is parsed to produce the
+object structure of the email message, this structure is manipulated,
+and finally, the object tree is rendered back into flat text.
+
+It is perfectly feasible to create the object structure out of whole
+cloth --- i.e. completely from scratch.  From there, a similar
+progression can be taken as above.
+
+Also included are detailed specifications of all the classes and
+modules that the \module{email} package provides, the exception
+classes you might encounter while using the \module{email} package,
+some auxiliary utilities, and a few examples.  For users of the older
+\module{mimelib} package, or previous versions of the \module{email}
+package, a section on differences and porting is provided.
+
+\begin{seealso}
+    \seemodule{smtplib}{SMTP protocol client}
+    \seemodule{nntplib}{NNTP protocol client}
+\end{seealso}
+
+\subsection{Representing an email message}
+\input{emailmessage}
+
+\subsection{Parsing email messages}
+\input{emailparser}
+
+\subsection{Generating MIME documents}
+\input{emailgenerator}
+
+\subsection{Creating email and MIME objects from scratch}
+\input{emailmimebase}
+
+\subsection{Internationalized headers}
+\input{emailheaders}
+
+\subsection{Representing character sets}
+\input{emailcharsets}
+
+\subsection{Encoders}
+\input{emailencoders}
+
+\subsection{Exception and Defect classes}
+\input{emailexc}
+
+\subsection{Miscellaneous utilities}
+\input{emailutil}
+
+\subsection{Iterators}
+\input{emailiter}
+
+\subsection{Package History\label{email-pkg-history}}
+
+This table describes the release history of the email package, corresponding
+to the version of Python that the package was released with.  For purposes of
+this document, when you see a note about change or added versions, these refer
+to the Python version the change was made it, \emph{not} the email package
+version.  This table also describes the Python compatibility of each version
+of the package.
+
+\begin{tableiii}{l|l|l}{constant}{email version}{distributed with}{compatible with}
+\lineiii{1.x}{Python 2.2.0 to Python 2.2.1}{\emph{no longer supported}}
+\lineiii{2.5}{Python 2.2.2+ and Python 2.3}{Python 2.1 to 2.5}
+\lineiii{3.0}{Python 2.4}{Python 2.3 to 2.5}
+\lineiii{4.0}{Python 2.5}{Python 2.3 to 2.5}
+\end{tableiii}
+
+Here are the major differences between \module{email} version 4 and version 3:
+
+\begin{itemize}
+\item All modules have been renamed according to \pep{8} standards.  For
+      example, the version 3 module \module{email.Message} was renamed to
+      \module{email.message} in version 4.
+
+\item A new subpackage \module{email.mime} was added and all the version 3
+      \module{email.MIME*} modules were renamed and situated into the
+      \module{email.mime} subpackage.  For example, the version 3 module
+      \module{email.MIMEText} was renamed to \module{email.mime.text}.
+
+      \emph{Note that the version 3 names will continue to work until Python
+      2.6}.
+
+\item The \module{email.mime.application} module was added, which contains the
+      \class{MIMEApplication} class.
+
+\item Methods that were deprecated in version 3 have been removed.  These
+      include \method{Generator.__call__()}, \method{Message.get_type()},
+      \method{Message.get_main_type()}, \method{Message.get_subtype()}.
+
+\item Fixes have been added for \rfc{2231} support which can change some of
+      the return types for \function{Message.get_param()} and friends.  Under
+      some circumstances, values which used to return a 3-tuple now return
+      simple strings (specifically, if all extended parameter segments were
+      unencoded, there is no language and charset designation expected, so the
+      return type is now a simple string).  Also, \%-decoding used to be done
+      for both encoded and unencoded segments; this decoding is now done only
+      for encoded segments.
+\end{itemize}
+
+Here are the major differences between \module{email} version 3 and version 2:
+
+\begin{itemize}
+\item The \class{FeedParser} class was introduced, and the \class{Parser}
+      class was implemented in terms of the \class{FeedParser}.  All parsing
+      therefore is non-strict, and parsing will make a best effort never to
+      raise an exception.  Problems found while parsing messages are stored in
+      the message's \var{defect} attribute.
+
+\item All aspects of the API which raised \exception{DeprecationWarning}s in
+      version 2 have been removed.  These include the \var{_encoder} argument
+      to the \class{MIMEText} constructor, the \method{Message.add_payload()}
+      method, the \function{Utils.dump_address_pair()} function, and the
+      functions \function{Utils.decode()} and \function{Utils.encode()}.
+
+\item New \exception{DeprecationWarning}s have been added to:
+      \method{Generator.__call__()}, \method{Message.get_type()},
+      \method{Message.get_main_type()}, \method{Message.get_subtype()}, and
+      the \var{strict} argument to the \class{Parser} class.  These are
+      expected to be removed in future versions.
+
+\item Support for Pythons earlier than 2.3 has been removed.
+\end{itemize}
+
+Here are the differences between \module{email} version 2 and version 1:
+
+\begin{itemize}
+\item The \module{email.Header} and \module{email.Charset} modules
+      have been added.
+
+\item The pickle format for \class{Message} instances has changed.
+      Since this was never (and still isn't) formally defined, this
+      isn't considered a backward incompatibility.  However if your
+      application pickles and unpickles \class{Message} instances, be
+      aware that in \module{email} version 2, \class{Message}
+      instances now have private variables \var{_charset} and
+      \var{_default_type}.
+
+\item Several methods in the \class{Message} class have been
+      deprecated, or their signatures changed.  Also, many new methods
+      have been added.  See the documentation for the \class{Message}
+      class for details.  The changes should be completely backward
+      compatible.
+
+\item The object structure has changed in the face of
+      \mimetype{message/rfc822} content types.  In \module{email}
+      version 1, such a type would be represented by a scalar payload,
+      i.e. the container message's \method{is_multipart()} returned
+      false, \method{get_payload()} was not a list object, but a single
+      \class{Message} instance.
+
+      This structure was inconsistent with the rest of the package, so
+      the object representation for \mimetype{message/rfc822} content
+      types was changed.  In \module{email} version 2, the container
+      \emph{does} return \code{True} from \method{is_multipart()}, and
+      \method{get_payload()} returns a list containing a single
+      \class{Message} item.
+
+      Note that this is one place that backward compatibility could
+      not be completely maintained.  However, if you're already
+      testing the return type of \method{get_payload()}, you should be
+      fine.  You just need to make sure your code doesn't do a
+      \method{set_payload()} with a \class{Message} instance on a
+      container with a content type of \mimetype{message/rfc822}.
+
+\item The \class{Parser} constructor's \var{strict} argument was
+      added, and its \method{parse()} and \method{parsestr()} methods
+      grew a \var{headersonly} argument.  The \var{strict} flag was
+      also added to functions \function{email.message_from_file()}
+      and \function{email.message_from_string()}.
+
+\item \method{Generator.__call__()} is deprecated; use
+      \method{Generator.flatten()} instead.  The \class{Generator}
+      class has also grown the \method{clone()} method.
+
+\item The \class{DecodedGenerator} class in the
+      \module{email.Generator} module was added.
+
+\item The intermediate base classes \class{MIMENonMultipart} and
+      \class{MIMEMultipart} have been added, and interposed in the
+      class hierarchy for most of the other MIME-related derived
+      classes.
+
+\item The \var{_encoder} argument to the \class{MIMEText} constructor
+      has been deprecated.  Encoding  now happens implicitly based
+      on the \var{_charset} argument.
+
+\item The following functions in the \module{email.Utils} module have
+      been deprecated: \function{dump_address_pairs()},
+      \function{decode()}, and \function{encode()}.  The following
+      functions have been added to the module:
+      \function{make_msgid()}, \function{decode_rfc2231()},
+      \function{encode_rfc2231()}, and \function{decode_params()}.
+
+\item The non-public function \function{email.Iterators._structure()}
+      was added.
+\end{itemize}
+
+\subsection{Differences from \module{mimelib}}
+
+The \module{email} package was originally prototyped as a separate
+library called
+\ulink{\module{mimelib}}{http://mimelib.sf.net/}.
+Changes have been made so that
+method names are more consistent, and some methods or modules have
+either been added or removed.  The semantics of some of the methods
+have also changed.  For the most part, any functionality available in
+\module{mimelib} is still available in the \refmodule{email} package,
+albeit often in a different way.  Backward compatibility between
+the \module{mimelib} package and the \module{email} package was not a
+priority.
+
+Here is a brief description of the differences between the
+\module{mimelib} and the \refmodule{email} packages, along with hints on
+how to port your applications.
+
+Of course, the most visible difference between the two packages is
+that the package name has been changed to \refmodule{email}.  In
+addition, the top-level package has the following differences:
+
+\begin{itemize}
+\item \function{messageFromString()} has been renamed to
+      \function{message_from_string()}.
+
+\item \function{messageFromFile()} has been renamed to
+      \function{message_from_file()}.
+
+\end{itemize}
+
+The \class{Message} class has the following differences:
+
+\begin{itemize}
+\item The method \method{asString()} was renamed to \method{as_string()}.
+
+\item The method \method{ismultipart()} was renamed to
+      \method{is_multipart()}.
+
+\item The \method{get_payload()} method has grown a \var{decode}
+      optional argument.
+
+\item The method \method{getall()} was renamed to \method{get_all()}.
+
+\item The method \method{addheader()} was renamed to \method{add_header()}.
+
+\item The method \method{gettype()} was renamed to \method{get_type()}.
+
+\item The method \method{getmaintype()} was renamed to
+      \method{get_main_type()}.
+
+\item The method \method{getsubtype()} was renamed to
+      \method{get_subtype()}.
+
+\item The method \method{getparams()} was renamed to
+      \method{get_params()}.
+      Also, whereas \method{getparams()} returned a list of strings,
+      \method{get_params()} returns a list of 2-tuples, effectively
+      the key/value pairs of the parameters, split on the \character{=}
+      sign.
+
+\item The method \method{getparam()} was renamed to \method{get_param()}.
+
+\item The method \method{getcharsets()} was renamed to
+      \method{get_charsets()}.
+
+\item The method \method{getfilename()} was renamed to
+      \method{get_filename()}.
+
+\item The method \method{getboundary()} was renamed to
+      \method{get_boundary()}.
+
+\item The method \method{setboundary()} was renamed to
+      \method{set_boundary()}.
+
+\item The method \method{getdecodedpayload()} was removed.  To get
+      similar functionality, pass the value 1 to the \var{decode} flag
+      of the {get_payload()} method.
+
+\item The method \method{getpayloadastext()} was removed.  Similar
+      functionality
+      is supported by the \class{DecodedGenerator} class in the
+      \refmodule{email.generator} module.
+
+\item The method \method{getbodyastext()} was removed.  You can get
+      similar functionality by creating an iterator with
+      \function{typed_subpart_iterator()} in the
+      \refmodule{email.iterators} module.
+\end{itemize}
+
+The \class{Parser} class has no differences in its public interface.
+It does have some additional smarts to recognize
+\mimetype{message/delivery-status} type messages, which it represents as
+a \class{Message} instance containing separate \class{Message}
+subparts for each header block in the delivery status
+notification\footnote{Delivery Status Notifications (DSN) are defined
+in \rfc{1894}.}.
+
+The \class{Generator} class has no differences in its public
+interface.  There is a new class in the \refmodule{email.generator}
+module though, called \class{DecodedGenerator} which provides most of
+the functionality previously available in the
+\method{Message.getpayloadastext()} method.
+
+The following modules and classes have been changed:
+
+\begin{itemize}
+\item The \class{MIMEBase} class constructor arguments \var{_major}
+      and \var{_minor} have changed to \var{_maintype} and
+      \var{_subtype} respectively.
+
+\item The \code{Image} class/module has been renamed to
+      \code{MIMEImage}.  The \var{_minor} argument has been renamed to
+      \var{_subtype}.
+
+\item The \code{Text} class/module has been renamed to
+      \code{MIMEText}.  The \var{_minor} argument has been renamed to
+      \var{_subtype}.
+
+\item The \code{MessageRFC822} class/module has been renamed to
+      \code{MIMEMessage}.  Note that an earlier version of
+      \module{mimelib} called this class/module \code{RFC822}, but
+      that clashed with the Python standard library module
+      \refmodule{rfc822} on some case-insensitive file systems.
+
+      Also, the \class{MIMEMessage} class now represents any kind of
+      MIME message with main type \mimetype{message}.  It takes an
+      optional argument \var{_subtype} which is used to set the MIME
+      subtype.  \var{_subtype} defaults to \mimetype{rfc822}.
+\end{itemize}
+
+\module{mimelib} provided some utility functions in its
+\module{address} and \module{date} modules.  All of these functions
+have been moved to the \refmodule{email.utils} module.
+
+The \code{MsgReader} class/module has been removed.  Its functionality
+is most closely supported in the \function{body_line_iterator()}
+function in the \refmodule{email.iterators} module.
+
+\subsection{Examples}
+
+Here are a few examples of how to use the \module{email} package to
+read, write, and send simple email messages, as well as more complex
+MIME messages.
+
+First, let's see how to create and send a simple text message:
+
+\verbatiminput{email-simple.py}
+
+Here's an example of how to send a MIME message containing a bunch of
+family pictures that may be residing in a directory:
+
+\verbatiminput{email-mime.py}
+
+Here's an example of how to send the entire contents of a directory as
+an email message:
+\footnote{Thanks to Matthew Dixon Cowles for the original inspiration
+          and examples.}
+
+\verbatiminput{email-dir.py}
+
+And finally, here's an example of how to unpack a MIME message like
+the one above, into a directory of files:
+
+\verbatiminput{email-unpack.py}

Added: vendor/Python/current/Doc/lib/emailcharsets.tex
===================================================================
--- vendor/Python/current/Doc/lib/emailcharsets.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/emailcharsets.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,244 @@
+\declaremodule{standard}{email.charset}
+\modulesynopsis{Character Sets}
+
+This module provides a class \class{Charset} for representing
+character sets and character set conversions in email messages, as
+well as a character set registry and several convenience methods for
+manipulating this registry.  Instances of \class{Charset} are used in
+several other modules within the \module{email} package.
+
+Import this class from the \module{email.charset} module.
+
+\versionadded{2.2.2}
+
+\begin{classdesc}{Charset}{\optional{input_charset}}
+Map character sets to their email properties.
+
+This class provides information about the requirements imposed on
+email for a specific character set.  It also provides convenience
+routines for converting between character sets, given the availability
+of the applicable codecs.  Given a character set, it will do its best
+to provide information on how to use that character set in an email
+message in an RFC-compliant way.
+
+Certain character sets must be encoded with quoted-printable or base64
+when used in email headers or bodies.  Certain character sets must be
+converted outright, and are not allowed in email.
+
+Optional \var{input_charset} is as described below; it is always
+coerced to lower case.  After being alias normalized it is also used
+as a lookup into the registry of character sets to find out the header
+encoding, body encoding, and output conversion codec to be used for
+the character set.  For example, if
+\var{input_charset} is \code{iso-8859-1}, then headers and bodies will
+be encoded using quoted-printable and no output conversion codec is
+necessary.  If \var{input_charset} is \code{euc-jp}, then headers will
+be encoded with base64, bodies will not be encoded, but output text
+will be converted from the \code{euc-jp} character set to the
+\code{iso-2022-jp} character set.
+\end{classdesc}
+
+\class{Charset} instances have the following data attributes:
+
+\begin{datadesc}{input_charset}
+The initial character set specified.  Common aliases are converted to
+their \emph{official} email names (e.g. \code{latin_1} is converted to
+\code{iso-8859-1}).  Defaults to 7-bit \code{us-ascii}.
+\end{datadesc}
+
+\begin{datadesc}{header_encoding}
+If the character set must be encoded before it can be used in an
+email header, this attribute will be set to \code{Charset.QP} (for
+quoted-printable), \code{Charset.BASE64} (for base64 encoding), or
+\code{Charset.SHORTEST} for the shortest of QP or BASE64 encoding.
+Otherwise, it will be \code{None}.
+\end{datadesc}
+
+\begin{datadesc}{body_encoding}
+Same as \var{header_encoding}, but describes the encoding for the
+mail message's body, which indeed may be different than the header
+encoding.  \code{Charset.SHORTEST} is not allowed for
+\var{body_encoding}.
+\end{datadesc}
+
+\begin{datadesc}{output_charset}
+Some character sets must be converted before they can be used in
+email headers or bodies.  If the \var{input_charset} is one of
+them, this attribute will contain the name of the character set
+output will be converted to.  Otherwise, it will be \code{None}.
+\end{datadesc}
+
+\begin{datadesc}{input_codec}
+The name of the Python codec used to convert the \var{input_charset} to
+Unicode.  If no conversion codec is necessary, this attribute will be
+\code{None}.
+\end{datadesc}
+
+\begin{datadesc}{output_codec}
+The name of the Python codec used to convert Unicode to the
+\var{output_charset}.  If no conversion codec is necessary, this
+attribute will have the same value as the \var{input_codec}.
+\end{datadesc}
+
+\class{Charset} instances also have the following methods:
+
+\begin{methoddesc}[Charset]{get_body_encoding}{}
+Return the content transfer encoding used for body encoding.
+
+This is either the string \samp{quoted-printable} or \samp{base64}
+depending on the encoding used, or it is a function, in which case you
+should call the function with a single argument, the Message object
+being encoded.  The function should then set the
+\mailheader{Content-Transfer-Encoding} header itself to whatever is
+appropriate.
+
+Returns the string \samp{quoted-printable} if
+\var{body_encoding} is \code{QP}, returns the string
+\samp{base64} if \var{body_encoding} is \code{BASE64}, and returns the
+string \samp{7bit} otherwise.
+\end{methoddesc}
+
+\begin{methoddesc}{convert}{s}
+Convert the string \var{s} from the \var{input_codec} to the
+\var{output_codec}.
+\end{methoddesc}
+
+\begin{methoddesc}{to_splittable}{s}
+Convert a possibly multibyte string to a safely splittable format.
+\var{s} is the string to split.
+
+Uses the \var{input_codec} to try and convert the string to Unicode,
+so it can be safely split on character boundaries (even for multibyte
+characters).
+
+Returns the string as-is if it isn't known how to convert \var{s} to
+Unicode with the \var{input_charset}.
+
+Characters that could not be converted to Unicode will be replaced
+with the Unicode replacement character \character{U+FFFD}.
+\end{methoddesc}
+
+\begin{methoddesc}{from_splittable}{ustr\optional{, to_output}}
+Convert a splittable string back into an encoded string.  \var{ustr}
+is a Unicode string to ``unsplit''.
+
+This method uses the proper codec to try and convert the string from
+Unicode back into an encoded format.  Return the string as-is if it is
+not Unicode, or if it could not be converted from Unicode.
+
+Characters that could not be converted from Unicode will be replaced
+with an appropriate character (usually \character{?}).
+
+If \var{to_output} is \code{True} (the default), uses
+\var{output_codec} to convert to an 
+encoded format.  If \var{to_output} is \code{False}, it uses
+\var{input_codec}.
+\end{methoddesc}
+
+\begin{methoddesc}{get_output_charset}{}
+Return the output character set.
+
+This is the \var{output_charset} attribute if that is not \code{None},
+otherwise it is \var{input_charset}.
+\end{methoddesc}
+
+\begin{methoddesc}{encoded_header_len}{}
+Return the length of the encoded header string, properly calculating
+for quoted-printable or base64 encoding.
+\end{methoddesc}
+
+\begin{methoddesc}{header_encode}{s\optional{, convert}}
+Header-encode the string \var{s}.
+
+If \var{convert} is \code{True}, the string will be converted from the
+input charset to the output charset automatically.  This is not useful
+for multibyte character sets, which have line length issues (multibyte
+characters must be split on a character, not a byte boundary); use the
+higher-level \class{Header} class to deal with these issues (see
+\refmodule{email.header}).  \var{convert} defaults to \code{False}.
+
+The type of encoding (base64 or quoted-printable) will be based on
+the \var{header_encoding} attribute.
+\end{methoddesc}
+
+\begin{methoddesc}{body_encode}{s\optional{, convert}}
+Body-encode the string \var{s}.
+
+If \var{convert} is \code{True} (the default), the string will be
+converted from the input charset to output charset automatically.
+Unlike \method{header_encode()}, there are no issues with byte
+boundaries and multibyte charsets in email bodies, so this is usually
+pretty safe.
+
+The type of encoding (base64 or quoted-printable) will be based on
+the \var{body_encoding} attribute.
+\end{methoddesc}
+
+The \class{Charset} class also provides a number of methods to support
+standard operations and built-in functions.
+
+\begin{methoddesc}[Charset]{__str__}{}
+Returns \var{input_charset} as a string coerced to lower case.
+\method{__repr__()} is an alias for \method{__str__()}.
+\end{methoddesc}
+
+\begin{methoddesc}[Charset]{__eq__}{other}
+This method allows you to compare two \class{Charset} instances for equality.
+\end{methoddesc}
+
+\begin{methoddesc}[Header]{__ne__}{other}
+This method allows you to compare two \class{Charset} instances for inequality.
+\end{methoddesc}
+
+The \module{email.charset} module also provides the following
+functions for adding new entries to the global character set, alias,
+and codec registries:
+
+\begin{funcdesc}{add_charset}{charset\optional{, header_enc\optional{,
+    body_enc\optional{, output_charset}}}}
+Add character properties to the global registry.
+
+\var{charset} is the input character set, and must be the canonical
+name of a character set.
+
+Optional \var{header_enc} and \var{body_enc} is either
+\code{Charset.QP} for quoted-printable, \code{Charset.BASE64} for
+base64 encoding, \code{Charset.SHORTEST} for the shortest of
+quoted-printable or base64 encoding, or \code{None} for no encoding.
+\code{SHORTEST} is only valid for \var{header_enc}. The default is
+\code{None} for no encoding.
+
+Optional \var{output_charset} is the character set that the output
+should be in.  Conversions will proceed from input charset, to
+Unicode, to the output charset when the method
+\method{Charset.convert()} is called.  The default is to output in the
+same character set as the input.
+
+Both \var{input_charset} and \var{output_charset} must have Unicode
+codec entries in the module's character set-to-codec mapping; use
+\function{add_codec()} to add codecs the module does
+not know about.  See the \refmodule{codecs} module's documentation for
+more information.
+
+The global character set registry is kept in the module global
+dictionary \code{CHARSETS}.
+\end{funcdesc}
+
+\begin{funcdesc}{add_alias}{alias, canonical}
+Add a character set alias.  \var{alias} is the alias name,
+e.g. \code{latin-1}.  \var{canonical} is the character set's canonical
+name, e.g. \code{iso-8859-1}.
+
+The global charset alias registry is kept in the module global
+dictionary \code{ALIASES}.
+\end{funcdesc}
+
+\begin{funcdesc}{add_codec}{charset, codecname}
+Add a codec that map characters in the given character set to and from
+Unicode.
+
+\var{charset} is the canonical name of a character set.
+\var{codecname} is the name of a Python codec, as appropriate for the
+second argument to the \function{unicode()} built-in, or to the
+\method{encode()} method of a Unicode string.
+\end{funcdesc}

Added: vendor/Python/current/Doc/lib/emailencoders.tex
===================================================================
--- vendor/Python/current/Doc/lib/emailencoders.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/emailencoders.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,47 @@
+\declaremodule{standard}{email.encoders}
+\modulesynopsis{Encoders for email message payloads.}
+
+When creating \class{Message} objects from scratch, you often need to
+encode the payloads for transport through compliant mail servers.
+This is especially true for \mimetype{image/*} and \mimetype{text/*}
+type messages containing binary data.
+
+The \module{email} package provides some convenient encodings in its
+\module{encoders} module.  These encoders are actually used by the
+\class{MIMEAudio} and \class{MIMEImage} class constructors to provide default
+encodings.  All encoder functions take exactly one argument, the message
+object to encode.  They usually extract the payload, encode it, and reset the
+payload to this newly encoded value.  They should also set the
+\mailheader{Content-Transfer-Encoding} header as appropriate.
+
+Here are the encoding functions provided:
+
+\begin{funcdesc}{encode_quopri}{msg}
+Encodes the payload into quoted-printable form and sets the
+\mailheader{Content-Transfer-Encoding} header to
+\code{quoted-printable}\footnote{Note that encoding with
+\method{encode_quopri()} also encodes all tabs and space characters in
+the data.}.
+This is a good encoding to use when most of your payload is normal
+printable data, but contains a few unprintable characters.
+\end{funcdesc}
+
+\begin{funcdesc}{encode_base64}{msg}
+Encodes the payload into base64 form and sets the
+\mailheader{Content-Transfer-Encoding} header to
+\code{base64}.  This is a good encoding to use when most of your payload
+is unprintable data since it is a more compact form than
+quoted-printable.  The drawback of base64 encoding is that it
+renders the text non-human readable.
+\end{funcdesc}
+
+\begin{funcdesc}{encode_7or8bit}{msg}
+This doesn't actually modify the message's payload, but it does set
+the \mailheader{Content-Transfer-Encoding} header to either \code{7bit} or
+\code{8bit} as appropriate, based on the payload data.
+\end{funcdesc}
+
+\begin{funcdesc}{encode_noop}{msg}
+This does nothing; it doesn't even set the
+\mailheader{Content-Transfer-Encoding} header.
+\end{funcdesc}

Added: vendor/Python/current/Doc/lib/emailexc.tex
===================================================================
--- vendor/Python/current/Doc/lib/emailexc.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/emailexc.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,87 @@
+\declaremodule{standard}{email.errors}
+\modulesynopsis{The exception classes used by the email package.}
+
+The following exception classes are defined in the
+\module{email.errors} module:
+
+\begin{excclassdesc}{MessageError}{}
+This is the base class for all exceptions that the \module{email}
+package can raise.  It is derived from the standard
+\exception{Exception} class and defines no additional methods.
+\end{excclassdesc}
+
+\begin{excclassdesc}{MessageParseError}{}
+This is the base class for exceptions thrown by the \class{Parser}
+class.  It is derived from \exception{MessageError}.
+\end{excclassdesc}
+
+\begin{excclassdesc}{HeaderParseError}{}
+Raised under some error conditions when parsing the \rfc{2822} headers of
+a message, this class is derived from \exception{MessageParseError}.
+It can be raised from the \method{Parser.parse()} or
+\method{Parser.parsestr()} methods.
+
+Situations where it can be raised include finding an envelope
+header after the first \rfc{2822} header of the message, finding a
+continuation line before the first \rfc{2822} header is found, or finding
+a line in the headers which is neither a header or a continuation
+line.
+\end{excclassdesc}
+
+\begin{excclassdesc}{BoundaryError}{}
+Raised under some error conditions when parsing the \rfc{2822} headers of
+a message, this class is derived from \exception{MessageParseError}.
+It can be raised from the \method{Parser.parse()} or
+\method{Parser.parsestr()} methods.
+
+Situations where it can be raised include not being able to find the
+starting or terminating boundary in a \mimetype{multipart/*} message
+when strict parsing is used.
+\end{excclassdesc}
+
+\begin{excclassdesc}{MultipartConversionError}{}
+Raised when a payload is added to a \class{Message} object using
+\method{add_payload()}, but the payload is already a scalar and the
+message's \mailheader{Content-Type} main type is not either
+\mimetype{multipart} or missing.  \exception{MultipartConversionError}
+multiply inherits from \exception{MessageError} and the built-in
+\exception{TypeError}.
+
+Since \method{Message.add_payload()} is deprecated, this exception is
+rarely raised in practice.  However the exception may also be raised
+if the \method{attach()} method is called on an instance of a class
+derived from \class{MIMENonMultipart} (e.g. \class{MIMEImage}).
+\end{excclassdesc}
+
+Here's the list of the defects that the \class{FeedParser} can find while
+parsing messages.  Note that the defects are added to the message where the
+problem was found, so for example, if a message nested inside a
+\mimetype{multipart/alternative} had a malformed header, that nested message
+object would have a defect, but the containing messages would not.
+
+All defect classes are subclassed from \class{email.errors.MessageDefect}, but
+this class is \emph{not} an exception!
+
+\versionadded[All the defect classes were added]{2.4}
+
+\begin{itemize}
+\item \class{NoBoundaryInMultipartDefect} -- A message claimed to be a
+      multipart, but had no \mimetype{boundary} parameter.
+
+\item \class{StartBoundaryNotFoundDefect} -- The start boundary claimed in the
+      \mailheader{Content-Type} header was never found.
+
+\item \class{FirstHeaderLineIsContinuationDefect} -- The message had a
+      continuation line as its first header line.
+
+\item \class{MisplacedEnvelopeHeaderDefect} - A ``Unix From'' header was found
+      in the middle of a header block.
+
+\item \class{MalformedHeaderDefect} -- A header was found that was missing a
+      colon, or was otherwise malformed.
+
+\item \class{MultipartInvariantViolationDefect} -- A message claimed to be a
+      \mimetype{multipart}, but no subparts were found.  Note that when a
+      message has this defect, its \method{is_multipart()} method may return
+      false even though its content type claims to be \mimetype{multipart}.
+\end{itemize}

Added: vendor/Python/current/Doc/lib/emailgenerator.tex
===================================================================
--- vendor/Python/current/Doc/lib/emailgenerator.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/emailgenerator.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,133 @@
+\declaremodule{standard}{email.generator}
+\modulesynopsis{Generate flat text email messages from a message structure.}
+
+One of the most common tasks is to generate the flat text of the email
+message represented by a message object structure.  You will need to do
+this if you want to send your message via the \refmodule{smtplib}
+module or the \refmodule{nntplib} module, or print the message on the
+console.  Taking a message object structure and producing a flat text
+document is the job of the \class{Generator} class.
+
+Again, as with the \refmodule{email.parser} module, you aren't limited
+to the functionality of the bundled generator; you could write one
+from scratch yourself.  However the bundled generator knows how to
+generate most email in a standards-compliant way, should handle MIME
+and non-MIME email messages just fine, and is designed so that the
+transformation from flat text, to a message structure via the
+\class{Parser} class, and back to flat text, is idempotent (the input
+is identical to the output).
+
+Here are the public methods of the \class{Generator} class, imported from the
+\module{email.generator} module:
+
+\begin{classdesc}{Generator}{outfp\optional{, mangle_from_\optional{,
+    maxheaderlen}}}
+The constructor for the \class{Generator} class takes a file-like
+object called \var{outfp} for an argument.  \var{outfp} must support
+the \method{write()} method and be usable as the output file in a
+Python extended print statement.
+
+Optional \var{mangle_from_} is a flag that, when \code{True}, puts a
+\samp{>} character in front of any line in the body that starts exactly as
+\samp{From }, i.e. \code{From} followed by a space at the beginning of the
+line.  This is the only guaranteed portable way to avoid having such
+lines be mistaken for a \UNIX{} mailbox format envelope header separator (see
+\ulink{WHY THE CONTENT-LENGTH FORMAT IS BAD}
+{http://www.jwz.org/doc/content-length.html}
+for details).  \var{mangle_from_} defaults to \code{True}, but you
+might want to set this to \code{False} if you are not writing \UNIX{}
+mailbox format files.
+
+Optional \var{maxheaderlen} specifies the longest length for a
+non-continued header.  When a header line is longer than
+\var{maxheaderlen} (in characters, with tabs expanded to 8 spaces),
+the header will be split as defined in the \module{email.header.Header}
+class.  Set to zero to disable header wrapping.  The default is 78, as
+recommended (but not required) by \rfc{2822}.
+\end{classdesc}
+
+The other public \class{Generator} methods are:
+
+\begin{methoddesc}[Generator]{flatten}{msg\optional{, unixfrom}}
+Print the textual representation of the message object structure rooted at
+\var{msg} to the output file specified when the \class{Generator}
+instance was created.  Subparts are visited depth-first and the
+resulting text will be properly MIME encoded.
+
+Optional \var{unixfrom} is a flag that forces the printing of the
+envelope header delimiter before the first \rfc{2822} header of the
+root message object.  If the root object has no envelope header, a
+standard one is crafted.  By default, this is set to \code{False} to
+inhibit the printing of the envelope delimiter.
+
+Note that for subparts, no envelope header is ever printed.
+
+\versionadded{2.2.2}
+\end{methoddesc}
+
+\begin{methoddesc}[Generator]{clone}{fp}
+Return an independent clone of this \class{Generator} instance with
+the exact same options.
+
+\versionadded{2.2.2}
+\end{methoddesc}
+
+\begin{methoddesc}[Generator]{write}{s}
+Write the string \var{s} to the underlying file object,
+i.e. \var{outfp} passed to \class{Generator}'s constructor.  This
+provides just enough file-like API for \class{Generator} instances to
+be used in extended print statements.
+\end{methoddesc}
+
+As a convenience, see the methods \method{Message.as_string()} and
+\code{str(aMessage)}, a.k.a. \method{Message.__str__()}, which
+simplify the generation of a formatted string representation of a
+message object.  For more detail, see \refmodule{email.message}.
+
+The \module{email.generator} module also provides a derived class,
+called \class{DecodedGenerator} which is like the \class{Generator}
+base class, except that non-\mimetype{text} parts are substituted with
+a format string representing the part.
+
+\begin{classdesc}{DecodedGenerator}{outfp\optional{, mangle_from_\optional{,
+    maxheaderlen\optional{, fmt}}}}
+
+This class, derived from \class{Generator} walks through all the
+subparts of a message.  If the subpart is of main type
+\mimetype{text}, then it prints the decoded payload of the subpart.
+Optional \var{_mangle_from_} and \var{maxheaderlen} are as with the
+\class{Generator} base class.
+
+If the subpart is not of main type \mimetype{text}, optional \var{fmt}
+is a format string that is used instead of the message payload.
+\var{fmt} is expanded with the following keywords, \samp{\%(keyword)s}
+format:
+
+\begin{itemize}
+\item \code{type} -- Full MIME type of the non-\mimetype{text} part
+
+\item \code{maintype} -- Main MIME type of the non-\mimetype{text} part
+
+\item \code{subtype} -- Sub-MIME type of the non-\mimetype{text} part
+
+\item \code{filename} -- Filename of the non-\mimetype{text} part
+
+\item \code{description} -- Description associated with the
+      non-\mimetype{text} part
+
+\item \code{encoding} -- Content transfer encoding of the
+      non-\mimetype{text} part
+
+\end{itemize}
+
+The default value for \var{fmt} is \code{None}, meaning
+
+\begin{verbatim}
+[Non-text (%(type)s) part of message omitted, filename %(filename)s]
+\end{verbatim}
+
+\versionadded{2.2.2}
+\end{classdesc}
+
+\versionchanged[The previously deprecated method \method{__call__()} was
+removed]{2.5}

Added: vendor/Python/current/Doc/lib/emailheaders.tex
===================================================================
--- vendor/Python/current/Doc/lib/emailheaders.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/emailheaders.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,178 @@
+\declaremodule{standard}{email.header}
+\modulesynopsis{Representing non-ASCII headers}
+
+\rfc{2822} is the base standard that describes the format of email
+messages.  It derives from the older \rfc{822} standard which came
+into widespread use at a time when most email was composed of \ASCII{}
+characters only.  \rfc{2822} is a specification written assuming email
+contains only 7-bit \ASCII{} characters.
+
+Of course, as email has been deployed worldwide, it has become
+internationalized, such that language specific character sets can now
+be used in email messages.  The base standard still requires email
+messages to be transferred using only 7-bit \ASCII{} characters, so a
+slew of RFCs have been written describing how to encode email
+containing non-\ASCII{} characters into \rfc{2822}-compliant format.
+These RFCs include \rfc{2045}, \rfc{2046}, \rfc{2047}, and \rfc{2231}.
+The \module{email} package supports these standards in its
+\module{email.header} and \module{email.charset} modules.
+
+If you want to include non-\ASCII{} characters in your email headers,
+say in the \mailheader{Subject} or \mailheader{To} fields, you should
+use the \class{Header} class and assign the field in the
+\class{Message} object to an instance of \class{Header} instead of
+using a string for the header value.  Import the \class{Header} class from the
+\module{email.header} module.  For example:
+
+\begin{verbatim}
+>>> from email.message import Message
+>>> from email.header import Header
+>>> msg = Message()
+>>> h = Header('p\xf6stal', 'iso-8859-1')
+>>> msg['Subject'] = h
+>>> print msg.as_string()
+Subject: =?iso-8859-1?q?p=F6stal?=
+
+
+\end{verbatim}
+
+Notice here how we wanted the \mailheader{Subject} field to contain a
+non-\ASCII{} character?  We did this by creating a \class{Header}
+instance and passing in the character set that the byte string was
+encoded in.  When the subsequent \class{Message} instance was
+flattened, the \mailheader{Subject} field was properly \rfc{2047}
+encoded.  MIME-aware mail readers would show this header using the
+embedded ISO-8859-1 character.
+
+\versionadded{2.2.2}
+
+Here is the \class{Header} class description:
+
+\begin{classdesc}{Header}{\optional{s\optional{, charset\optional{,
+    maxlinelen\optional{, header_name\optional{, continuation_ws\optional{,
+    errors}}}}}}}
+Create a MIME-compliant header that can contain strings in different
+character sets.
+
+Optional \var{s} is the initial header value.  If \code{None} (the
+default), the initial header value is not set.  You can later append
+to the header with \method{append()} method calls.  \var{s} may be a
+byte string or a Unicode string, but see the \method{append()}
+documentation for semantics.
+
+Optional \var{charset} serves two purposes: it has the same meaning as
+the \var{charset} argument to the \method{append()} method.  It also
+sets the default character set for all subsequent \method{append()}
+calls that omit the \var{charset} argument.  If \var{charset} is not
+provided in the constructor (the default), the \code{us-ascii}
+character set is used both as \var{s}'s initial charset and as the
+default for subsequent \method{append()} calls.
+
+The maximum line length can be specified explicit via
+\var{maxlinelen}.  For splitting the first line to a shorter value (to
+account for the field header which isn't included in \var{s},
+e.g. \mailheader{Subject}) pass in the name of the field in
+\var{header_name}.  The default \var{maxlinelen} is 76, and the
+default value for \var{header_name} is \code{None}, meaning it is not
+taken into account for the first line of a long, split header.
+
+Optional \var{continuation_ws} must be \rfc{2822}-compliant folding
+whitespace, and is usually either a space or a hard tab character.
+This character will be prepended to continuation lines.
+\end{classdesc}
+
+Optional \var{errors} is passed straight through to the
+\method{append()} method.
+
+\begin{methoddesc}[Header]{append}{s\optional{, charset\optional{, errors}}}
+Append the string \var{s} to the MIME header.
+
+Optional \var{charset}, if given, should be a \class{Charset} instance
+(see \refmodule{email.charset}) or the name of a character set, which
+will be converted to a \class{Charset} instance.  A value of
+\code{None} (the default) means that the \var{charset} given in the
+constructor is used.
+
+\var{s} may be a byte string or a Unicode string.  If it is a byte
+string (i.e. \code{isinstance(s, str)} is true), then
+\var{charset} is the encoding of that byte string, and a
+\exception{UnicodeError} will be raised if the string cannot be
+decoded with that character set.
+
+If \var{s} is a Unicode string, then \var{charset} is a hint
+specifying the character set of the characters in the string.  In this
+case, when producing an \rfc{2822}-compliant header using \rfc{2047}
+rules, the Unicode string will be encoded using the following charsets
+in order: \code{us-ascii}, the \var{charset} hint, \code{utf-8}.  The
+first character set to not provoke a \exception{UnicodeError} is used.
+
+Optional \var{errors} is passed through to any \function{unicode()} or
+\function{ustr.encode()} call, and defaults to ``strict''.
+\end{methoddesc}
+
+\begin{methoddesc}[Header]{encode}{\optional{splitchars}}
+Encode a message header into an RFC-compliant format, possibly
+wrapping long lines and encapsulating non-\ASCII{} parts in base64 or
+quoted-printable encodings.  Optional \var{splitchars} is a string
+containing characters to split long ASCII lines on, in rough support
+of \rfc{2822}'s \emph{highest level syntactic breaks}.  This doesn't
+affect \rfc{2047} encoded lines.
+\end{methoddesc}
+
+The \class{Header} class also provides a number of methods to support
+standard operators and built-in functions.
+
+\begin{methoddesc}[Header]{__str__}{}
+A synonym for \method{Header.encode()}.  Useful for
+\code{str(aHeader)}.
+\end{methoddesc}
+
+\begin{methoddesc}[Header]{__unicode__}{}
+A helper for the built-in \function{unicode()} function.  Returns the
+header as a Unicode string.
+\end{methoddesc}
+
+\begin{methoddesc}[Header]{__eq__}{other}
+This method allows you to compare two \class{Header} instances for equality.
+\end{methoddesc}
+
+\begin{methoddesc}[Header]{__ne__}{other}
+This method allows you to compare two \class{Header} instances for inequality.
+\end{methoddesc}
+
+The \module{email.header} module also provides the following
+convenient functions.
+
+\begin{funcdesc}{decode_header}{header}
+Decode a message header value without converting the character set.
+The header value is in \var{header}.
+
+This function returns a list of \code{(decoded_string, charset)} pairs
+containing each of the decoded parts of the header.  \var{charset} is
+\code{None} for non-encoded parts of the header, otherwise a lower
+case string containing the name of the character set specified in the
+encoded string.
+
+Here's an example:
+
+\begin{verbatim}
+>>> from email.header import decode_header
+>>> decode_header('=?iso-8859-1?q?p=F6stal?=')
+[('p\xf6stal', 'iso-8859-1')]
+\end{verbatim}
+\end{funcdesc}
+
+\begin{funcdesc}{make_header}{decoded_seq\optional{, maxlinelen\optional{,
+    header_name\optional{, continuation_ws}}}}
+Create a \class{Header} instance from a sequence of pairs as returned
+by \function{decode_header()}.
+
+\function{decode_header()} takes a header value string and returns a
+sequence of pairs of the format \code{(decoded_string, charset)} where
+\var{charset} is the name of the character set.
+
+This function takes one of those sequence of pairs and returns a
+\class{Header} instance.  Optional \var{maxlinelen},
+\var{header_name}, and \var{continuation_ws} are as in the
+\class{Header} constructor.
+\end{funcdesc}

Added: vendor/Python/current/Doc/lib/emailiter.tex
===================================================================
--- vendor/Python/current/Doc/lib/emailiter.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/emailiter.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,65 @@
+\declaremodule{standard}{email.iterators}
+\modulesynopsis{Iterate over a  message object tree.}
+
+Iterating over a message object tree is fairly easy with the
+\method{Message.walk()} method.  The \module{email.iterators} module
+provides some useful higher level iterations over message object
+trees.
+
+\begin{funcdesc}{body_line_iterator}{msg\optional{, decode}}
+This iterates over all the payloads in all the subparts of \var{msg},
+returning the string payloads line-by-line.  It skips over all the
+subpart headers, and it skips over any subpart with a payload that
+isn't a Python string.  This is somewhat equivalent to reading the
+flat text representation of the message from a file using
+\method{readline()}, skipping over all the intervening headers.
+
+Optional \var{decode} is passed through to \method{Message.get_payload()}.
+\end{funcdesc}
+
+\begin{funcdesc}{typed_subpart_iterator}{msg\optional{,
+    maintype\optional{, subtype}}}
+This iterates over all the subparts of \var{msg}, returning only those
+subparts that match the MIME type specified by \var{maintype} and
+\var{subtype}.
+
+Note that \var{subtype} is optional; if omitted, then subpart MIME
+type matching is done only with the main type.  \var{maintype} is
+optional too; it defaults to \mimetype{text}.
+
+Thus, by default \function{typed_subpart_iterator()} returns each
+subpart that has a MIME type of \mimetype{text/*}.
+\end{funcdesc}
+
+The following function has been added as a useful debugging tool.  It
+should \emph{not} be considered part of the supported public interface
+for the package.
+
+\begin{funcdesc}{_structure}{msg\optional{, fp\optional{, level}}}
+Prints an indented representation of the content types of the
+message object structure.  For example:
+
+\begin{verbatim}
+>>> msg = email.message_from_file(somefile)
+>>> _structure(msg)
+multipart/mixed
+    text/plain
+    text/plain
+    multipart/digest
+        message/rfc822
+            text/plain
+        message/rfc822
+            text/plain
+        message/rfc822
+            text/plain
+        message/rfc822
+            text/plain
+        message/rfc822
+            text/plain
+    text/plain
+\end{verbatim}
+
+Optional \var{fp} is a file-like object to print the output to.  It
+must be suitable for Python's extended print statement.  \var{level}
+is used internally.
+\end{funcdesc}

Added: vendor/Python/current/Doc/lib/emailmessage.tex
===================================================================
--- vendor/Python/current/Doc/lib/emailmessage.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/emailmessage.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,561 @@
+\declaremodule{standard}{email.message}
+\modulesynopsis{The base class representing email messages.}
+
+The central class in the \module{email} package is the
+\class{Message} class, imported from the \module{email.message} module.  It is
+the base class for the \module{email} object model.  \class{Message} provides
+the core functionality for setting and querying header fields, and for
+accessing message bodies.
+
+Conceptually, a \class{Message} object consists of \emph{headers} and
+\emph{payloads}.  Headers are \rfc{2822} style field names and
+values where the field name and value are separated by a colon.  The
+colon is not part of either the field name or the field value.
+
+Headers are stored and returned in case-preserving form but are
+matched case-insensitively.  There may also be a single envelope
+header, also known as the \emph{Unix-From} header or the
+\code{From_} header.  The payload is either a string in the case of
+simple message objects or a list of \class{Message} objects for
+MIME container documents (e.g. \mimetype{multipart/*} and
+\mimetype{message/rfc822}).
+
+\class{Message} objects provide a mapping style interface for
+accessing the message headers, and an explicit interface for accessing
+both the headers and the payload.  It provides convenience methods for
+generating a flat text representation of the message object tree, for
+accessing commonly used header parameters, and for recursively walking
+over the object tree.
+
+Here are the methods of the \class{Message} class:
+
+\begin{classdesc}{Message}{}
+The constructor takes no arguments.
+\end{classdesc}
+
+\begin{methoddesc}[Message]{as_string}{\optional{unixfrom}}
+Return the entire message flatten as a string.  When optional
+\var{unixfrom} is \code{True}, the envelope header is included in the
+returned string.  \var{unixfrom} defaults to \code{False}.
+
+Note that this method is provided as a convenience and may not always format
+the message the way you want.  For example, by default it mangles lines that
+begin with \code{From }.  For more flexibility, instantiate a
+\class{Generator} instance and use its
+\method{flatten()} method directly.  For example:
+
+\begin{verbatim}
+from cStringIO import StringIO
+from email.generator import Generator
+fp = StringIO()
+g = Generator(fp, mangle_from_=False, maxheaderlen=60)
+g.flatten(msg)
+text = fp.getvalue()
+\end{verbatim}
+\end{methoddesc}
+
+\begin{methoddesc}[Message]{__str__}{}
+Equivalent to \method{as_string(unixfrom=True)}.
+\end{methoddesc}
+
+\begin{methoddesc}[Message]{is_multipart}{}
+Return \code{True} if the message's payload is a list of
+sub-\class{Message} objects, otherwise return \code{False}.  When
+\method{is_multipart()} returns False, the payload should be a string
+object.
+\end{methoddesc}
+
+\begin{methoddesc}[Message]{set_unixfrom}{unixfrom}
+Set the message's envelope header to \var{unixfrom}, which should be a string.
+\end{methoddesc}
+
+\begin{methoddesc}[Message]{get_unixfrom}{}
+Return the message's envelope header.  Defaults to \code{None} if the
+envelope header was never set.
+\end{methoddesc}
+
+\begin{methoddesc}[Message]{attach}{payload}
+Add the given \var{payload} to the current payload, which must be
+\code{None} or a list of \class{Message} objects before the call.
+After the call, the payload will always be a list of \class{Message}
+objects.  If you want to set the payload to a scalar object (e.g. a
+string), use \method{set_payload()} instead.
+\end{methoddesc}
+
+\begin{methoddesc}[Message]{get_payload}{\optional{i\optional{, decode}}}
+Return a reference the current payload, which will be a list of
+\class{Message} objects when \method{is_multipart()} is \code{True}, or a
+string when \method{is_multipart()} is \code{False}.  If the
+payload is a list and you mutate the list object, you modify the
+message's payload in place.
+
+With optional argument \var{i}, \method{get_payload()} will return the
+\var{i}-th element of the payload, counting from zero, if
+\method{is_multipart()} is \code{True}.  An \exception{IndexError}
+will be raised if \var{i} is less than 0 or greater than or equal to
+the number of items in the payload.  If the payload is a string
+(i.e. \method{is_multipart()} is \code{False}) and \var{i} is given, a
+\exception{TypeError} is raised.
+
+Optional \var{decode} is a flag indicating whether the payload should be
+decoded or not, according to the \mailheader{Content-Transfer-Encoding} header.
+When \code{True} and the message is not a multipart, the payload will be
+decoded if this header's value is \samp{quoted-printable} or
+\samp{base64}.  If some other encoding is used, or
+\mailheader{Content-Transfer-Encoding} header is
+missing, or if the payload has bogus base64 data, the payload is
+returned as-is (undecoded).  If the message is a multipart and the
+\var{decode} flag is \code{True}, then \code{None} is returned.  The
+default for \var{decode} is \code{False}.
+\end{methoddesc}
+
+\begin{methoddesc}[Message]{set_payload}{payload\optional{, charset}}
+Set the entire message object's payload to \var{payload}.  It is the
+client's responsibility to ensure the payload invariants.  Optional
+\var{charset} sets the message's default character set; see
+\method{set_charset()} for details.
+
+\versionchanged[\var{charset} argument added]{2.2.2}
+\end{methoddesc}
+
+\begin{methoddesc}[Message]{set_charset}{charset}
+Set the character set of the payload to \var{charset}, which can
+either be a \class{Charset} instance (see \refmodule{email.charset}), a
+string naming a character set,
+or \code{None}.  If it is a string, it will be converted to a
+\class{Charset} instance.  If \var{charset} is \code{None}, the
+\code{charset} parameter will be removed from the
+\mailheader{Content-Type} header. Anything else will generate a
+\exception{TypeError}.
+
+The message will be assumed to be of type \mimetype{text/*} encoded with
+\var{charset.input_charset}.  It will be converted to
+\var{charset.output_charset}
+and encoded properly, if needed, when generating the plain text
+representation of the message.  MIME headers
+(\mailheader{MIME-Version}, \mailheader{Content-Type},
+\mailheader{Content-Transfer-Encoding}) will be added as needed.
+
+\versionadded{2.2.2}
+\end{methoddesc}
+
+\begin{methoddesc}[Message]{get_charset}{}
+Return the \class{Charset} instance associated with the message's payload.
+\versionadded{2.2.2}
+\end{methoddesc}
+
+The following methods implement a mapping-like interface for accessing
+the message's \rfc{2822} headers.  Note that there are some
+semantic differences between these methods and a normal mapping
+(i.e. dictionary) interface.  For example, in a dictionary there are
+no duplicate keys, but here there may be duplicate message headers.  Also,
+in dictionaries there is no guaranteed order to the keys returned by
+\method{keys()}, but in a \class{Message} object, headers are always
+returned in the order they appeared in the original message, or were
+added to the message later.  Any header deleted and then re-added are
+always appended to the end of the header list.
+
+These semantic differences are intentional and are biased toward
+maximal convenience.
+
+Note that in all cases, any envelope header present in the message is
+not included in the mapping interface.
+
+\begin{methoddesc}[Message]{__len__}{}
+Return the total number of headers, including duplicates.
+\end{methoddesc}
+
+\begin{methoddesc}[Message]{__contains__}{name}
+Return true if the message object has a field named \var{name}.
+Matching is done case-insensitively and \var{name} should not include the
+trailing colon.  Used for the \code{in} operator,
+e.g.:
+
+\begin{verbatim}
+if 'message-id' in myMessage:
+    print 'Message-ID:', myMessage['message-id']
+\end{verbatim}
+\end{methoddesc}
+
+\begin{methoddesc}[Message]{__getitem__}{name}
+Return the value of the named header field.  \var{name} should not
+include the colon field separator.  If the header is missing,
+\code{None} is returned; a \exception{KeyError} is never raised.
+
+Note that if the named field appears more than once in the message's
+headers, exactly which of those field values will be returned is
+undefined.  Use the \method{get_all()} method to get the values of all
+the extant named headers.
+\end{methoddesc}
+
+\begin{methoddesc}[Message]{__setitem__}{name, val}
+Add a header to the message with field name \var{name} and value
+\var{val}.  The field is appended to the end of the message's existing
+fields.
+
+Note that this does \emph{not} overwrite or delete any existing header
+with the same name.  If you want to ensure that the new header is the
+only one present in the message with field name
+\var{name}, delete the field first, e.g.:
+
+\begin{verbatim}
+del msg['subject']
+msg['subject'] = 'Python roolz!'
+\end{verbatim}
+\end{methoddesc}
+
+\begin{methoddesc}[Message]{__delitem__}{name}
+Delete all occurrences of the field with name \var{name} from the
+message's headers.  No exception is raised if the named field isn't
+present in the headers.
+\end{methoddesc}
+
+\begin{methoddesc}[Message]{has_key}{name}
+Return true if the message contains a header field named \var{name},
+otherwise return false.
+\end{methoddesc}
+
+\begin{methoddesc}[Message]{keys}{}
+Return a list of all the message's header field names.
+\end{methoddesc}
+
+\begin{methoddesc}[Message]{values}{}
+Return a list of all the message's field values.
+\end{methoddesc}
+
+\begin{methoddesc}[Message]{items}{}
+Return a list of 2-tuples containing all the message's field headers
+and values.
+\end{methoddesc}
+
+\begin{methoddesc}[Message]{get}{name\optional{, failobj}}
+Return the value of the named header field.  This is identical to
+\method{__getitem__()} except that optional \var{failobj} is returned
+if the named header is missing (defaults to \code{None}).
+\end{methoddesc}
+
+Here are some additional useful methods:
+
+\begin{methoddesc}[Message]{get_all}{name\optional{, failobj}}
+Return a list of all the values for the field named \var{name}.
+If there are no such named headers in the message, \var{failobj} is
+returned (defaults to \code{None}).
+\end{methoddesc}
+
+\begin{methoddesc}[Message]{add_header}{_name, _value, **_params}
+Extended header setting.  This method is similar to
+\method{__setitem__()} except that additional header parameters can be
+provided as keyword arguments.  \var{_name} is the header field to add
+and \var{_value} is the \emph{primary} value for the header.
+
+For each item in the keyword argument dictionary \var{_params}, the
+key is taken as the parameter name, with underscores converted to
+dashes (since dashes are illegal in Python identifiers).  Normally,
+the parameter will be added as \code{key="value"} unless the value is
+\code{None}, in which case only the key will be added.
+
+Here's an example:
+
+\begin{verbatim}
+msg.add_header('Content-Disposition', 'attachment', filename='bud.gif')
+\end{verbatim}
+
+This will add a header that looks like
+
+\begin{verbatim}
+Content-Disposition: attachment; filename="bud.gif"
+\end{verbatim}
+\end{methoddesc}
+
+\begin{methoddesc}[Message]{replace_header}{_name, _value}
+Replace a header.  Replace the first header found in the message that
+matches \var{_name}, retaining header order and field name case.  If
+no matching header was found, a \exception{KeyError} is raised.
+
+\versionadded{2.2.2}
+\end{methoddesc}
+
+\begin{methoddesc}[Message]{get_content_type}{}
+Return the message's content type.  The returned string is coerced to
+lower case of the form \mimetype{maintype/subtype}.  If there was no
+\mailheader{Content-Type} header in the message the default type as
+given by \method{get_default_type()} will be returned.  Since
+according to \rfc{2045}, messages always have a default type,
+\method{get_content_type()} will always return a value.
+
+\rfc{2045} defines a message's default type to be
+\mimetype{text/plain} unless it appears inside a
+\mimetype{multipart/digest} container, in which case it would be
+\mimetype{message/rfc822}.  If the \mailheader{Content-Type} header
+has an invalid type specification, \rfc{2045} mandates that the
+default type be \mimetype{text/plain}.
+
+\versionadded{2.2.2}
+\end{methoddesc}
+
+\begin{methoddesc}[Message]{get_content_maintype}{}
+Return the message's main content type.  This is the
+\mimetype{maintype} part of the string returned by
+\method{get_content_type()}.
+
+\versionadded{2.2.2}
+\end{methoddesc}
+
+\begin{methoddesc}[Message]{get_content_subtype}{}
+Return the message's sub-content type.  This is the \mimetype{subtype}
+part of the string returned by \method{get_content_type()}.
+
+\versionadded{2.2.2}
+\end{methoddesc}
+
+\begin{methoddesc}[Message]{get_default_type}{}
+Return the default content type.  Most messages have a default content
+type of \mimetype{text/plain}, except for messages that are subparts
+of \mimetype{multipart/digest} containers.  Such subparts have a
+default content type of \mimetype{message/rfc822}.
+
+\versionadded{2.2.2}
+\end{methoddesc}
+
+\begin{methoddesc}[Message]{set_default_type}{ctype}
+Set the default content type.  \var{ctype} should either be
+\mimetype{text/plain} or \mimetype{message/rfc822}, although this is
+not enforced.  The default content type is not stored in the
+\mailheader{Content-Type} header.
+
+\versionadded{2.2.2}
+\end{methoddesc}
+
+\begin{methoddesc}[Message]{get_params}{\optional{failobj\optional{,
+    header\optional{, unquote}}}}
+Return the message's \mailheader{Content-Type} parameters, as a list.  The
+elements of the returned list are 2-tuples of key/value pairs, as
+split on the \character{=} sign.  The left hand side of the
+\character{=} is the key, while the right hand side is the value.  If
+there is no \character{=} sign in the parameter the value is the empty
+string, otherwise the value is as described in \method{get_param()} and is
+unquoted if optional \var{unquote} is \code{True} (the default).
+
+Optional \var{failobj} is the object to return if there is no
+\mailheader{Content-Type} header.  Optional \var{header} is the header to
+search instead of \mailheader{Content-Type}.
+
+\versionchanged[\var{unquote} argument added]{2.2.2}
+\end{methoddesc}
+
+\begin{methoddesc}[Message]{get_param}{param\optional{,
+    failobj\optional{, header\optional{, unquote}}}}
+Return the value of the \mailheader{Content-Type} header's parameter
+\var{param} as a string.  If the message has no \mailheader{Content-Type}
+header or if there is no such parameter, then \var{failobj} is
+returned (defaults to \code{None}).
+
+Optional \var{header} if given, specifies the message header to use
+instead of \mailheader{Content-Type}.
+
+Parameter keys are always compared case insensitively.  The return
+value can either be a string, or a 3-tuple if the parameter was
+\rfc{2231} encoded.  When it's a 3-tuple, the elements of the value are of
+the form \code{(CHARSET, LANGUAGE, VALUE)}.  Note that both \code{CHARSET} and
+\code{LANGUAGE} can be \code{None}, in which case you should consider
+\code{VALUE} to be encoded in the \code{us-ascii} charset.  You can
+usually ignore \code{LANGUAGE}.
+
+If your application doesn't care whether the parameter was encoded as in
+\rfc{2231}, you can collapse the parameter value by calling
+\function{email.Utils.collapse_rfc2231_value()}, passing in the return value
+from \method{get_param()}.  This will return a suitably decoded Unicode string
+whn the value is a tuple, or the original string unquoted if it isn't.  For
+example:
+
+\begin{verbatim}
+rawparam = msg.get_param('foo')
+param = email.Utils.collapse_rfc2231_value(rawparam)
+\end{verbatim}
+
+In any case, the parameter value (either the returned string, or the
+\code{VALUE} item in the 3-tuple) is always unquoted, unless
+\var{unquote} is set to \code{False}.
+
+\versionchanged[\var{unquote} argument added, and 3-tuple return value
+possible]{2.2.2}
+\end{methoddesc}
+
+\begin{methoddesc}[Message]{set_param}{param, value\optional{,
+    header\optional{, requote\optional{, charset\optional{, language}}}}}
+
+Set a parameter in the \mailheader{Content-Type} header.  If the
+parameter already exists in the header, its value will be replaced
+with \var{value}.  If the \mailheader{Content-Type} header as not yet
+been defined for this message, it will be set to \mimetype{text/plain}
+and the new parameter value will be appended as per \rfc{2045}.
+
+Optional \var{header} specifies an alternative header to
+\mailheader{Content-Type}, and all parameters will be quoted as
+necessary unless optional \var{requote} is \code{False} (the default
+is \code{True}).
+
+If optional \var{charset} is specified, the parameter will be encoded
+according to \rfc{2231}. Optional \var{language} specifies the RFC
+2231 language, defaulting to the empty string.  Both \var{charset} and
+\var{language} should be strings.
+
+\versionadded{2.2.2}
+\end{methoddesc}
+
+\begin{methoddesc}[Message]{del_param}{param\optional{, header\optional{,
+    requote}}}
+Remove the given parameter completely from the
+\mailheader{Content-Type} header.  The header will be re-written in
+place without the parameter or its value.  All values will be quoted
+as necessary unless \var{requote} is \code{False} (the default is
+\code{True}).  Optional \var{header} specifies an alternative to
+\mailheader{Content-Type}.
+
+\versionadded{2.2.2}
+\end{methoddesc}
+
+\begin{methoddesc}[Message]{set_type}{type\optional{, header}\optional{,
+    requote}}
+Set the main type and subtype for the \mailheader{Content-Type}
+header. \var{type} must be a string in the form
+\mimetype{maintype/subtype}, otherwise a \exception{ValueError} is
+raised.
+
+This method replaces the \mailheader{Content-Type} header, keeping all
+the parameters in place.  If \var{requote} is \code{False}, this
+leaves the existing header's quoting as is, otherwise the parameters
+will be quoted (the default).
+
+An alternative header can be specified in the \var{header} argument.
+When the \mailheader{Content-Type} header is set a
+\mailheader{MIME-Version} header is also added.
+
+\versionadded{2.2.2}
+\end{methoddesc}
+
+\begin{methoddesc}[Message]{get_filename}{\optional{failobj}}
+Return the value of the \code{filename} parameter of the
+\mailheader{Content-Disposition} header of the message.  If the header does
+not have a \code{filename} parameter, this method falls back to looking for
+the \code{name} parameter.  If neither is found, or the header is missing,
+then \var{failobj} is returned.  The returned string will always be unquoted
+as per \method{Utils.unquote()}.
+\end{methoddesc}
+
+\begin{methoddesc}[Message]{get_boundary}{\optional{failobj}}
+Return the value of the \code{boundary} parameter of the
+\mailheader{Content-Type} header of the message, or \var{failobj} if either
+the header is missing, or has no \code{boundary} parameter.  The
+returned string will always be unquoted as per
+\method{Utils.unquote()}.
+\end{methoddesc}
+
+\begin{methoddesc}[Message]{set_boundary}{boundary}
+Set the \code{boundary} parameter of the \mailheader{Content-Type}
+header to \var{boundary}.  \method{set_boundary()} will always quote
+\var{boundary} if necessary.  A \exception{HeaderParseError} is raised
+if the message object has no \mailheader{Content-Type} header.
+
+Note that using this method is subtly different than deleting the old
+\mailheader{Content-Type} header and adding a new one with the new boundary
+via \method{add_header()}, because \method{set_boundary()} preserves the
+order of the \mailheader{Content-Type} header in the list of headers.
+However, it does \emph{not} preserve any continuation lines which may
+have been present in the original \mailheader{Content-Type} header.
+\end{methoddesc}
+
+\begin{methoddesc}[Message]{get_content_charset}{\optional{failobj}}
+Return the \code{charset} parameter of the \mailheader{Content-Type}
+header, coerced to lower case.  If there is no
+\mailheader{Content-Type} header, or if that header has no
+\code{charset} parameter, \var{failobj} is returned.
+
+Note that this method differs from \method{get_charset()} which
+returns the \class{Charset} instance for the default encoding of the
+message body.
+
+\versionadded{2.2.2}
+\end{methoddesc}
+
+\begin{methoddesc}[Message]{get_charsets}{\optional{failobj}}
+Return a list containing the character set names in the message.  If
+the message is a \mimetype{multipart}, then the list will contain one
+element for each subpart in the payload, otherwise, it will be a list
+of length 1.
+
+Each item in the list will be a string which is the value of the
+\code{charset} parameter in the \mailheader{Content-Type} header for the
+represented subpart.  However, if the subpart has no
+\mailheader{Content-Type} header, no \code{charset} parameter, or is not of
+the \mimetype{text} main MIME type, then that item in the returned list
+will be \var{failobj}.
+\end{methoddesc}
+
+\begin{methoddesc}[Message]{walk}{}
+The \method{walk()} method is an all-purpose generator which can be
+used to iterate over all the parts and subparts of a message object
+tree, in depth-first traversal order.  You will typically use
+\method{walk()} as the iterator in a \code{for} loop; each
+iteration returns the next subpart.
+
+Here's an example that prints the MIME type of every part of a
+multipart message structure:
+
+\begin{verbatim}
+>>> for part in msg.walk():
+...     print part.get_content_type()
+multipart/report
+text/plain
+message/delivery-status
+text/plain
+text/plain
+message/rfc822
+\end{verbatim}
+\end{methoddesc}
+
+\versionchanged[The previously deprecated methods \method{get_type()},
+\method{get_main_type()}, and \method{get_subtype()} were removed]{2.5}
+
+\class{Message} objects can also optionally contain two instance
+attributes, which can be used when generating the plain text of a MIME
+message.
+
+\begin{datadesc}{preamble}
+The format of a MIME document allows for some text between the blank
+line following the headers, and the first multipart boundary string.
+Normally, this text is never visible in a MIME-aware mail reader
+because it falls outside the standard MIME armor.  However, when
+viewing the raw text of the message, or when viewing the message in a
+non-MIME aware reader, this text can become visible.
+
+The \var{preamble} attribute contains this leading extra-armor text
+for MIME documents.  When the \class{Parser} discovers some text after
+the headers but before the first boundary string, it assigns this text
+to the message's \var{preamble} attribute.  When the \class{Generator}
+is writing out the plain text representation of a MIME message, and it
+finds the message has a \var{preamble} attribute, it will write this
+text in the area between the headers and the first boundary.  See
+\refmodule{email.parser} and \refmodule{email.generator} for details.
+
+Note that if the message object has no preamble, the
+\var{preamble} attribute will be \code{None}.
+\end{datadesc}
+
+\begin{datadesc}{epilogue}
+The \var{epilogue} attribute acts the same way as the \var{preamble}
+attribute, except that it contains text that appears between the last
+boundary and the end of the message.
+
+\versionchanged[You do not need to set the epilogue to the empty string in
+order for the \class{Generator} to print a newline at the end of the
+file]{2.5}
+\end{datadesc}
+
+\begin{datadesc}{defects}
+The \var{defects} attribute contains a list of all the problems found when
+parsing this message.  See \refmodule{email.errors} for a detailed description
+of the possible parsing defects.
+
+\versionadded{2.4}
+\end{datadesc}

Added: vendor/Python/current/Doc/lib/emailmimebase.tex
===================================================================
--- vendor/Python/current/Doc/lib/emailmimebase.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/emailmimebase.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,186 @@
+\declaremodule{standard}{email.mime}
+\declaremodule{standard}{email.mime.base}
+\declaremodule{standard}{email.mime.nonmultipart}
+\declaremodule{standard}{email.mime.multipart}
+\declaremodule{standard}{email.mime.audio}
+\declaremodule{standard}{email.mime.image}
+\declaremodule{standard}{email.mime.message}
+\declaremodule{standard}{email.mime.text}
+Ordinarily, you get a message object structure by passing a file or
+some text to a parser, which parses the text and returns the root
+message object.  However you can also build a complete message
+structure from scratch, or even individual \class{Message} objects by
+hand.  In fact, you can also take an existing structure and add new
+\class{Message} objects, move them around, etc.  This makes a very
+convenient interface for slicing-and-dicing MIME messages.
+
+You can create a new object structure by creating \class{Message} instances,
+adding attachments and all the appropriate headers manually.  For MIME
+messages though, the \module{email} package provides some convenient
+subclasses to make things easier.
+
+Here are the classes:
+
+\begin{classdesc}{MIMEBase}{_maintype, _subtype, **_params}
+Module: \module{email.mime.base}
+
+This is the base class for all the MIME-specific subclasses of
+\class{Message}.  Ordinarily you won't create instances specifically
+of \class{MIMEBase}, although you could.  \class{MIMEBase} is provided
+primarily as a convenient base class for more specific MIME-aware
+subclasses.
+
+\var{_maintype} is the \mailheader{Content-Type} major type
+(e.g. \mimetype{text} or \mimetype{image}), and \var{_subtype} is the
+\mailheader{Content-Type} minor type 
+(e.g. \mimetype{plain} or \mimetype{gif}).  \var{_params} is a parameter
+key/value dictionary and is passed directly to
+\method{Message.add_header()}.
+
+The \class{MIMEBase} class always adds a \mailheader{Content-Type} header
+(based on \var{_maintype}, \var{_subtype}, and \var{_params}), and a
+\mailheader{MIME-Version} header (always set to \code{1.0}).
+\end{classdesc}
+
+\begin{classdesc}{MIMENonMultipart}{}
+Module: \module{email.mime.nonmultipart}
+
+A subclass of \class{MIMEBase}, this is an intermediate base class for
+MIME messages that are not \mimetype{multipart}.  The primary purpose
+of this class is to prevent the use of the \method{attach()} method,
+which only makes sense for \mimetype{multipart} messages.  If
+\method{attach()} is called, a \exception{MultipartConversionError}
+exception is raised.
+
+\versionadded{2.2.2}
+\end{classdesc}
+
+\begin{classdesc}{MIMEMultipart}{\optional{subtype\optional{,
+    boundary\optional{, _subparts\optional{, _params}}}}}
+Module: \module{email.mime.multipart}
+
+A subclass of \class{MIMEBase}, this is an intermediate base class for
+MIME messages that are \mimetype{multipart}.  Optional \var{_subtype}
+defaults to \mimetype{mixed}, but can be used to specify the subtype
+of the message.  A \mailheader{Content-Type} header of
+\mimetype{multipart/}\var{_subtype} will be added to the message
+object.  A \mailheader{MIME-Version} header will also be added.
+
+Optional \var{boundary} is the multipart boundary string.  When
+\code{None} (the default), the boundary is calculated when needed.
+
+\var{_subparts} is a sequence of initial subparts for the payload.  It
+must be possible to convert this sequence to a list.  You can always
+attach new subparts to the message by using the
+\method{Message.attach()} method.
+
+Additional parameters for the \mailheader{Content-Type} header are
+taken from the keyword arguments, or passed into the \var{_params}
+argument, which is a keyword dictionary.
+
+\versionadded{2.2.2}
+\end{classdesc}
+
+\begin{classdesc}{MIMEApplication}{_data\optional{, _subtype\optional{,
+    _encoder\optional{, **_params}}}}
+Module: \module{email.mime.application}
+
+A subclass of \class{MIMENonMultipart}, the \class{MIMEApplication} class is
+used to represent MIME message objects of major type \mimetype{application}.
+\var{_data} is a string containing the raw byte data.  Optional \var{_subtype}
+specifies the MIME subtype and defaults to \mimetype{octet-stream}.  
+
+Optional \var{_encoder} is a callable (i.e. function) which will
+perform the actual encoding of the data for transport.  This
+callable takes one argument, which is the \class{MIMEApplication} instance.
+It should use \method{get_payload()} and \method{set_payload()} to
+change the payload to encoded form.  It should also add any
+\mailheader{Content-Transfer-Encoding} or other headers to the message
+object as necessary.  The default encoding is base64.  See the
+\refmodule{email.encoders} module for a list of the built-in encoders.
+
+\var{_params} are passed straight through to the base class constructor.
+\versionadded{2.5}
+\end{classdesc}
+
+\begin{classdesc}{MIMEAudio}{_audiodata\optional{, _subtype\optional{,
+    _encoder\optional{, **_params}}}}
+Module: \module{email.mime.audio}
+
+A subclass of \class{MIMENonMultipart}, the \class{MIMEAudio} class
+is used to create MIME message objects of major type \mimetype{audio}.
+\var{_audiodata} is a string containing the raw audio data.  If this
+data can be decoded by the standard Python module \refmodule{sndhdr},
+then the subtype will be automatically included in the
+\mailheader{Content-Type} header.  Otherwise you can explicitly specify the
+audio subtype via the \var{_subtype} parameter.  If the minor type could
+not be guessed and \var{_subtype} was not given, then \exception{TypeError}
+is raised.
+
+Optional \var{_encoder} is a callable (i.e. function) which will
+perform the actual encoding of the audio data for transport.  This
+callable takes one argument, which is the \class{MIMEAudio} instance.
+It should use \method{get_payload()} and \method{set_payload()} to
+change the payload to encoded form.  It should also add any
+\mailheader{Content-Transfer-Encoding} or other headers to the message
+object as necessary.  The default encoding is base64.  See the
+\refmodule{email.encoders} module for a list of the built-in encoders.
+
+\var{_params} are passed straight through to the base class constructor.
+\end{classdesc}
+
+\begin{classdesc}{MIMEImage}{_imagedata\optional{, _subtype\optional{,
+    _encoder\optional{, **_params}}}}
+Module: \module{email.mime.image}
+
+A subclass of \class{MIMENonMultipart}, the \class{MIMEImage} class is
+used to create MIME message objects of major type \mimetype{image}.
+\var{_imagedata} is a string containing the raw image data.  If this
+data can be decoded by the standard Python module \refmodule{imghdr},
+then the subtype will be automatically included in the
+\mailheader{Content-Type} header.  Otherwise you can explicitly specify the
+image subtype via the \var{_subtype} parameter.  If the minor type could
+not be guessed and \var{_subtype} was not given, then \exception{TypeError}
+is raised.
+
+Optional \var{_encoder} is a callable (i.e. function) which will
+perform the actual encoding of the image data for transport.  This
+callable takes one argument, which is the \class{MIMEImage} instance.
+It should use \method{get_payload()} and \method{set_payload()} to
+change the payload to encoded form.  It should also add any
+\mailheader{Content-Transfer-Encoding} or other headers to the message
+object as necessary.  The default encoding is base64.  See the
+\refmodule{email.encoders} module for a list of the built-in encoders.
+
+\var{_params} are passed straight through to the \class{MIMEBase}
+constructor.
+\end{classdesc}
+
+\begin{classdesc}{MIMEMessage}{_msg\optional{, _subtype}}
+Module: \module{email.mime.message}
+
+A subclass of \class{MIMENonMultipart}, the \class{MIMEMessage} class
+is used to create MIME objects of main type \mimetype{message}.
+\var{_msg} is used as the payload, and must be an instance of class
+\class{Message} (or a subclass thereof), otherwise a
+\exception{TypeError} is raised.
+
+Optional \var{_subtype} sets the subtype of the message; it defaults
+to \mimetype{rfc822}.
+\end{classdesc}
+
+\begin{classdesc}{MIMEText}{_text\optional{, _subtype\optional{, _charset}}}
+Module: \module{email.mime.text}
+
+A subclass of \class{MIMENonMultipart}, the \class{MIMEText} class is
+used to create MIME objects of major type \mimetype{text}.
+\var{_text} is the string for the payload.  \var{_subtype} is the
+minor type and defaults to \mimetype{plain}.  \var{_charset} is the
+character set of the text and is passed as a parameter to the
+\class{MIMENonMultipart} constructor; it defaults to \code{us-ascii}.  No
+guessing or encoding is performed on the text data.
+
+\versionchanged[The previously deprecated \var{_encoding} argument has
+been removed.  Encoding happens implicitly based on the \var{_charset}
+argument]{2.4}
+\end{classdesc}

Added: vendor/Python/current/Doc/lib/emailparser.tex
===================================================================
--- vendor/Python/current/Doc/lib/emailparser.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/emailparser.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,208 @@
+\declaremodule{standard}{email.parser}
+\modulesynopsis{Parse flat text email messages to produce a message
+	        object structure.}
+
+Message object structures can be created in one of two ways: they can be
+created from whole cloth by instantiating \class{Message} objects and
+stringing them together via \method{attach()} and
+\method{set_payload()} calls, or they can be created by parsing a flat text
+representation of the email message.
+
+The \module{email} package provides a standard parser that understands
+most email document structures, including MIME documents.  You can
+pass the parser a string or a file object, and the parser will return
+to you the root \class{Message} instance of the object structure.  For
+simple, non-MIME messages the payload of this root object will likely
+be a string containing the text of the message.  For MIME
+messages, the root object will return \code{True} from its
+\method{is_multipart()} method, and the subparts can be accessed via
+the \method{get_payload()} and \method{walk()} methods.
+
+There are actually two parser interfaces available for use, the classic
+\class{Parser} API and the incremental \class{FeedParser} API.  The classic
+\class{Parser} API is fine if you have the entire text of the message in
+memory as a string, or if the entire message lives in a file on the file
+system.  \class{FeedParser} is more appropriate for when you're reading the
+message from a stream which might block waiting for more input (e.g. reading
+an email message from a socket).  The \class{FeedParser} can consume and parse
+the message incrementally, and only returns the root object when you close the
+parser\footnote{As of email package version 3.0, introduced in
+Python 2.4, the classic \class{Parser} was re-implemented in terms of the
+\class{FeedParser}, so the semantics and results are identical between the two
+parsers.}.
+
+Note that the parser can be extended in limited ways, and of course
+you can implement your own parser completely from scratch.  There is
+no magical connection between the \module{email} package's bundled
+parser and the \class{Message} class, so your custom parser can create
+message object trees any way it finds necessary.
+
+\subsubsection{FeedParser API}
+
+\versionadded{2.4}
+
+The \class{FeedParser}, imported from the \module{email.feedparser} module,
+provides an API that is conducive to incremental parsing of email messages,
+such as would be necessary when reading the text of an email message from a
+source that can block (e.g. a socket).  The
+\class{FeedParser} can of course be used to parse an email message fully
+contained in a string or a file, but the classic \class{Parser} API may be
+more convenient for such use cases.  The semantics and results of the two
+parser APIs are identical.
+
+The \class{FeedParser}'s API is simple; you create an instance, feed it a
+bunch of text until there's no more to feed it, then close the parser to
+retrieve the root message object.  The \class{FeedParser} is extremely
+accurate when parsing standards-compliant messages, and it does a very good
+job of parsing non-compliant messages, providing information about how a
+message was deemed broken.  It will populate a message object's \var{defects}
+attribute with a list of any problems it found in a message.  See the
+\refmodule{email.errors} module for the list of defects that it can find.
+
+Here is the API for the \class{FeedParser}:
+
+\begin{classdesc}{FeedParser}{\optional{_factory}}
+Create a \class{FeedParser} instance.  Optional \var{_factory} is a
+no-argument callable that will be called whenever a new message object is
+needed.  It defaults to the \class{email.message.Message} class.
+\end{classdesc}
+
+\begin{methoddesc}[FeedParser]{feed}{data}
+Feed the \class{FeedParser} some more data.  \var{data} should be a
+string containing one or more lines.  The lines can be partial and the
+\class{FeedParser} will stitch such partial lines together properly.  The
+lines in the string can have any of the common three line endings, carriage
+return, newline, or carriage return and newline (they can even be mixed).
+\end{methoddesc}
+
+\begin{methoddesc}[FeedParser]{close}{}
+Closing a \class{FeedParser} completes the parsing of all previously fed data,
+and returns the root message object.  It is undefined what happens if you feed
+more data to a closed \class{FeedParser}.
+\end{methoddesc}
+
+\subsubsection{Parser class API}
+
+The \class{Parser} class, imported from the \module{email.parser} module,
+provides an API that can be used to parse a message when the complete contents
+of the message are available in a string or file.  The
+\module{email.parser} module also provides a second class, called
+\class{HeaderParser} which can be used if you're only interested in
+the headers of the message. \class{HeaderParser} can be much faster in
+these situations, since it does not attempt to parse the message body,
+instead setting the payload to the raw body as a string.
+\class{HeaderParser} has the same API as the \class{Parser} class.
+
+\begin{classdesc}{Parser}{\optional{_class}}
+The constructor for the \class{Parser} class takes an optional
+argument \var{_class}.  This must be a callable factory (such as a
+function or a class), and it is used whenever a sub-message object
+needs to be created.  It defaults to \class{Message} (see
+\refmodule{email.message}).  The factory will be called without
+arguments.
+
+The optional \var{strict} flag is ignored.  \deprecated{2.4}{Because the
+\class{Parser} class is a backward compatible API wrapper around the
+new-in-Python 2.4 \class{FeedParser}, \emph{all} parsing is effectively
+non-strict.  You should simply stop passing a \var{strict} flag to the
+\class{Parser} constructor.}
+
+\versionchanged[The \var{strict} flag was added]{2.2.2}
+\versionchanged[The \var{strict} flag was deprecated]{2.4}
+\end{classdesc}
+
+The other public \class{Parser} methods are:
+
+\begin{methoddesc}[Parser]{parse}{fp\optional{, headersonly}}
+Read all the data from the file-like object \var{fp}, parse the
+resulting text, and return the root message object.  \var{fp} must
+support both the \method{readline()} and the \method{read()} methods
+on file-like objects.
+
+The text contained in \var{fp} must be formatted as a block of \rfc{2822}
+style headers and header continuation lines, optionally preceded by a
+envelope header.  The header block is terminated either by the
+end of the data or by a blank line.  Following the header block is the
+body of the message (which may contain MIME-encoded subparts).
+
+Optional \var{headersonly} is as with the \method{parse()} method.
+
+\versionchanged[The \var{headersonly} flag was added]{2.2.2}
+\end{methoddesc}
+
+\begin{methoddesc}[Parser]{parsestr}{text\optional{, headersonly}}
+Similar to the \method{parse()} method, except it takes a string
+object instead of a file-like object.  Calling this method on a string
+is exactly equivalent to wrapping \var{text} in a \class{StringIO}
+instance first and calling \method{parse()}.
+
+Optional \var{headersonly} is a flag specifying whether to stop
+parsing after reading the headers or not.  The default is \code{False},
+meaning it parses the entire contents of the file.
+
+\versionchanged[The \var{headersonly} flag was added]{2.2.2}
+\end{methoddesc}
+
+Since creating a message object structure from a string or a file
+object is such a common task, two functions are provided as a
+convenience.  They are available in the top-level \module{email}
+package namespace.
+
+\begin{funcdesc}{message_from_string}{s\optional{, _class\optional{, strict}}}
+Return a message object structure from a string.  This is exactly
+equivalent to \code{Parser().parsestr(s)}.  Optional \var{_class} and
+\var{strict} are interpreted as with the \class{Parser} class constructor.
+
+\versionchanged[The \var{strict} flag was added]{2.2.2}
+\end{funcdesc}
+
+\begin{funcdesc}{message_from_file}{fp\optional{, _class\optional{, strict}}}
+Return a message object structure tree from an open file object.  This
+is exactly equivalent to \code{Parser().parse(fp)}.  Optional
+\var{_class} and \var{strict} are interpreted as with the
+\class{Parser} class constructor.
+
+\versionchanged[The \var{strict} flag was added]{2.2.2}
+\end{funcdesc}
+
+Here's an example of how you might use this at an interactive Python
+prompt:
+
+\begin{verbatim}
+>>> import email
+>>> msg = email.message_from_string(myString)
+\end{verbatim}
+
+\subsubsection{Additional notes}
+
+Here are some notes on the parsing semantics:
+
+\begin{itemize}
+\item Most non-\mimetype{multipart} type messages are parsed as a single
+      message object with a string payload.  These objects will return
+      \code{False} for \method{is_multipart()}.  Their
+      \method{get_payload()} method will return a string object.
+
+\item All \mimetype{multipart} type messages will be parsed as a
+      container message object with a list of sub-message objects for
+      their payload.  The outer container message will return
+      \code{True} for \method{is_multipart()} and their
+      \method{get_payload()} method will return the list of
+      \class{Message} subparts.
+
+\item Most messages with a content type of \mimetype{message/*}
+      (e.g. \mimetype{message/delivery-status} and
+      \mimetype{message/rfc822}) will also be parsed as container
+      object containing a list payload of length 1.  Their
+      \method{is_multipart()} method will return \code{True}.  The
+      single element in the list payload will be a sub-message object.
+
+\item Some non-standards compliant messages may not be internally consistent
+      about their \mimetype{multipart}-edness.  Such messages may have a
+      \mailheader{Content-Type} header of type \mimetype{multipart}, but their
+      \method{is_multipart()} method may return \code{False}.  If such
+      messages were parsed with the \class{FeedParser}, they will have an
+      instance of the \class{MultipartInvariantViolationDefect} class in their
+      \var{defects} attribute list.  See \refmodule{email.errors} for
+      details.
+\end{itemize}

Added: vendor/Python/current/Doc/lib/emailutil.tex
===================================================================
--- vendor/Python/current/Doc/lib/emailutil.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/emailutil.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,157 @@
+\declaremodule{standard}{email.utils}
+\modulesynopsis{Miscellaneous email package utilities.}
+
+There are several useful utilities provided in the \module{email.utils}
+module:
+
+\begin{funcdesc}{quote}{str}
+Return a new string with backslashes in \var{str} replaced by two
+backslashes, and double quotes replaced by backslash-double quote.
+\end{funcdesc}
+
+\begin{funcdesc}{unquote}{str}
+Return a new string which is an \emph{unquoted} version of \var{str}.
+If \var{str} ends and begins with double quotes, they are stripped
+off.  Likewise if \var{str} ends and begins with angle brackets, they
+are stripped off.
+\end{funcdesc}
+
+\begin{funcdesc}{parseaddr}{address}
+Parse address -- which should be the value of some address-containing
+field such as \mailheader{To} or \mailheader{Cc} -- into its constituent
+\emph{realname} and \emph{email address} parts.  Returns a tuple of that
+information, unless the parse fails, in which case a 2-tuple of
+\code{('', '')} is returned.
+\end{funcdesc}
+
+\begin{funcdesc}{formataddr}{pair}
+The inverse of \method{parseaddr()}, this takes a 2-tuple of the form
+\code{(realname, email_address)} and returns the string value suitable
+for a \mailheader{To} or \mailheader{Cc} header.  If the first element of
+\var{pair} is false, then the second element is returned unmodified.
+\end{funcdesc}
+
+\begin{funcdesc}{getaddresses}{fieldvalues}
+This method returns a list of 2-tuples of the form returned by
+\code{parseaddr()}.  \var{fieldvalues} is a sequence of header field
+values as might be returned by \method{Message.get_all()}.  Here's a
+simple example that gets all the recipients of a message:
+
+\begin{verbatim}
+from email.utils import getaddresses
+
+tos = msg.get_all('to', [])
+ccs = msg.get_all('cc', [])
+resent_tos = msg.get_all('resent-to', [])
+resent_ccs = msg.get_all('resent-cc', [])
+all_recipients = getaddresses(tos + ccs + resent_tos + resent_ccs)
+\end{verbatim}
+\end{funcdesc}
+
+\begin{funcdesc}{parsedate}{date}
+Attempts to parse a date according to the rules in \rfc{2822}.
+however, some mailers don't follow that format as specified, so
+\function{parsedate()} tries to guess correctly in such cases. 
+\var{date} is a string containing an \rfc{2822} date, such as 
+\code{"Mon, 20 Nov 1995 19:12:08 -0500"}.  If it succeeds in parsing
+the date, \function{parsedate()} returns a 9-tuple that can be passed
+directly to \function{time.mktime()}; otherwise \code{None} will be
+returned.  Note that fields 6, 7, and 8 of the result tuple are not
+usable.
+\end{funcdesc}
+
+\begin{funcdesc}{parsedate_tz}{date}
+Performs the same function as \function{parsedate()}, but returns
+either \code{None} or a 10-tuple; the first 9 elements make up a tuple
+that can be passed directly to \function{time.mktime()}, and the tenth
+is the offset of the date's timezone from UTC (which is the official
+term for Greenwich Mean Time)\footnote{Note that the sign of the timezone
+offset is the opposite of the sign of the \code{time.timezone}
+variable for the same timezone; the latter variable follows the
+\POSIX{} standard while this module follows \rfc{2822}.}.  If the input
+string has no timezone, the last element of the tuple returned is
+\code{None}.  Note that fields 6, 7, and 8 of the result tuple are not
+usable.
+\end{funcdesc}
+
+\begin{funcdesc}{mktime_tz}{tuple}
+Turn a 10-tuple as returned by \function{parsedate_tz()} into a UTC
+timestamp.  It the timezone item in the tuple is \code{None}, assume
+local time.  Minor deficiency: \function{mktime_tz()} interprets the
+first 8 elements of \var{tuple} as a local time and then compensates
+for the timezone difference.  This may yield a slight error around
+changes in daylight savings time, though not worth worrying about for
+common use.
+\end{funcdesc}
+
+\begin{funcdesc}{formatdate}{\optional{timeval\optional{, localtime}\optional{, usegmt}}}
+Returns a date string as per \rfc{2822}, e.g.:
+
+\begin{verbatim}
+Fri, 09 Nov 2001 01:08:47 -0000
+\end{verbatim}
+
+Optional \var{timeval} if given is a floating point time value as
+accepted by \function{time.gmtime()} and \function{time.localtime()},
+otherwise the current time is used.
+
+Optional \var{localtime} is a flag that when \code{True}, interprets
+\var{timeval}, and returns a date relative to the local timezone
+instead of UTC, properly taking daylight savings time into account.
+The default is \code{False} meaning UTC is used.
+
+Optional \var{usegmt} is a flag that when \code{True}, outputs a 
+date string with the timezone as an ascii string \code{GMT}, rather
+than a numeric \code{-0000}. This is needed for some protocols (such
+as HTTP). This only applies when \var{localtime} is \code{False}.
+\versionadded{2.4}
+\end{funcdesc}
+
+\begin{funcdesc}{make_msgid}{\optional{idstring}}
+Returns a string suitable for an \rfc{2822}-compliant
+\mailheader{Message-ID} header.  Optional \var{idstring} if given, is
+a string used to strengthen the uniqueness of the message id.
+\end{funcdesc}
+
+\begin{funcdesc}{decode_rfc2231}{s}
+Decode the string \var{s} according to \rfc{2231}.
+\end{funcdesc}
+
+\begin{funcdesc}{encode_rfc2231}{s\optional{, charset\optional{, language}}}
+Encode the string \var{s} according to \rfc{2231}.  Optional
+\var{charset} and \var{language}, if given is the character set name
+and language name to use.  If neither is given, \var{s} is returned
+as-is.  If \var{charset} is given but \var{language} is not, the
+string is encoded using the empty string for \var{language}.
+\end{funcdesc}
+
+\begin{funcdesc}{collapse_rfc2231_value}{value\optional{, errors\optional{,
+    fallback_charset}}}
+When a header parameter is encoded in \rfc{2231} format,
+\method{Message.get_param()} may return a 3-tuple containing the character
+set, language, and value.  \function{collapse_rfc2231_value()} turns this into
+a unicode string.  Optional \var{errors} is passed to the \var{errors}
+argument of the built-in \function{unicode()} function; it defaults to
+\code{replace}.  Optional \var{fallback_charset} specifies the character set
+to use if the one in the \rfc{2231} header is not known by Python; it defaults
+to \code{us-ascii}.
+
+For convenience, if the \var{value} passed to
+\function{collapse_rfc2231_value()} is not a tuple, it should be a string and
+it is returned unquoted.
+\end{funcdesc}
+
+\begin{funcdesc}{decode_params}{params}
+Decode parameters list according to \rfc{2231}.  \var{params} is a
+sequence of 2-tuples containing elements of the form
+\code{(content-type, string-value)}.
+\end{funcdesc}
+
+\versionchanged[The \function{dump_address_pair()} function has been removed;
+use \function{formataddr()} instead]{2.4}
+
+\versionchanged[The \function{decode()} function has been removed; use the
+\method{Header.decode_header()} method instead]{2.4}
+
+\versionchanged[The \function{encode()} function has been removed; use the
+\method{Header.encode()} method instead]{2.4}

Added: vendor/Python/current/Doc/lib/fileformats.tex
===================================================================
--- vendor/Python/current/Doc/lib/fileformats.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/fileformats.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,7 @@
+\chapter{File Formats}
+\label{fileformats}
+
+The modules described in this chapter parse various miscellaneous file
+formats that aren't markup languages or are related to e-mail.
+
+\localmoduletable

Added: vendor/Python/current/Doc/lib/filesys.tex
===================================================================
--- vendor/Python/current/Doc/lib/filesys.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/filesys.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,18 @@
+\chapter{File and Directory Access}
+\label{filesys}
+
+The modules described in this chapter deal with disk files and
+directories.  For example, there are modules for reading the
+properties of files, manipulating paths in a portable way, and
+creating temporary files.  The full list of modules in this chapter is:
+
+\localmoduletable
+
+% XXX can this be included in the seealso environment? --amk
+Also see section \ref{bltin-file-objects} for a description 
+of Python's built-in file objects.
+
+\begin{seealso}
+    \seemodule{os}{Operating system interfaces, including functions to
+    work with files at a lower level than the built-in file object.} 
+\end{seealso}

Added: vendor/Python/current/Doc/lib/frameworks.tex
===================================================================
--- vendor/Python/current/Doc/lib/frameworks.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/frameworks.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,10 @@
+\chapter{Program Frameworks}
+\label{frameworks}
+
+The modules described in this chapter are frameworks that will largely
+dictate the structure of your program.  Currently the modules described 
+here are all oriented toward writing command-line interfaces.
+
+The full list of modules described in this chapter is:
+
+\localmoduletable

Added: vendor/Python/current/Doc/lib/i18n.tex
===================================================================
--- vendor/Python/current/Doc/lib/i18n.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/i18n.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,11 @@
+\chapter{Internationalization}
+\label{i18n}
+
+The modules described in this chapter help you write
+software that is independent of language and locale
+by providing mechanisms for selecting a language to be used in 
+program messages or by tailoring output to match local conventions.
+
+The list of modules described in this chapter is:
+
+\localmoduletable

Added: vendor/Python/current/Doc/lib/internet.tex
===================================================================
--- vendor/Python/current/Doc/lib/internet.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/internet.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,13 @@
+\chapter{Internet Protocols and Support \label{internet}}
+
+\index{WWW}
+\index{Internet}
+\index{World Wide Web}
+
+The modules described in this chapter implement Internet protocols and 
+support for related technology.  They are all implemented in Python.
+Most of these modules require the presence of the system-dependent
+module \refmodule{socket}\refbimodindex{socket}, which is currently
+supported on most popular platforms.  Here is an overview:
+
+\localmoduletable

Added: vendor/Python/current/Doc/lib/ipc.tex
===================================================================
--- vendor/Python/current/Doc/lib/ipc.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/ipc.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,14 @@
+\chapter{Interprocess Communication and Networking}
+\label{ipc}
+
+The modules described in this chapter provide mechanisms for different
+processes to communicate.
+
+Some modules only work for two processes that are on the same machine,
+e.g.  \module{signal} and \module{subprocess}.  Other modules support
+networking protocols that two or more processes can used to
+communicate across machines.
+
+The list of modules described in this chapter is:
+
+\localmoduletable

Added: vendor/Python/current/Doc/lib/language.tex
===================================================================
--- vendor/Python/current/Doc/lib/language.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/language.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,10 @@
+\chapter{Python Language Services
+         \label{language}}
+
+Python provides a number of modules to assist in working with the
+Python language.  These modules support tokenizing, parsing, syntax
+analysis, bytecode disassembly, and various other facilities.
+
+These modules include:
+
+\localmoduletable

Added: vendor/Python/current/Doc/lib/lib.tex
===================================================================
--- vendor/Python/current/Doc/lib/lib.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/lib.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,487 @@
+\documentclass{manual}
+
+% NOTE: this file controls which chapters/sections of the library
+% manual are actually printed.  It is easy to customize your manual
+% by commenting out sections that you're not interested in.
+
+\title{Python Library Reference}
+
+\input{boilerplate}
+
+\makeindex                      % tell \index to actually write the
+                                % .idx file
+\makemodindex                   % ... and the module index as well.
+
+ 
+\begin{document}
+
+\maketitle
+
+\ifhtml
+\chapter*{Front Matter\label{front}}
+\fi
+
+\input{copyright}
+
+\begin{abstract}
+
+\noindent
+Python is an extensible, interpreted, object-oriented programming
+language.  It supports a wide range of applications, from simple text
+processing scripts to interactive Web browsers.
+
+While the \citetitle[../ref/ref.html]{Python Reference Manual}
+describes the exact syntax and semantics of the language, it does not
+describe the standard library that is distributed with the language,
+and which greatly enhances its immediate usability.  This library
+contains built-in modules (written in C) that provide access to system
+functionality such as file I/O that would otherwise be inaccessible to
+Python programmers, as well as modules written in Python that provide
+standardized solutions for many problems that occur in everyday
+programming.  Some of these modules are explicitly designed to
+encourage and enhance the portability of Python programs.
+
+This library reference manual documents Python's standard library, as
+well as many optional library modules (which may or may not be
+available, depending on whether the underlying platform supports them
+and on the configuration choices made at compile time).  It also
+documents the standard types of the language and its built-in
+functions and exceptions, many of which are not or incompletely
+documented in the Reference Manual.
+
+This manual assumes basic knowledge about the Python language.  For an
+informal introduction to Python, see the
+\citetitle[../tut/tut.html]{Python Tutorial}; the
+\citetitle[../ref/ref.html]{Python Reference Manual} remains the
+highest authority on syntactic and semantic questions.  Finally, the
+manual entitled \citetitle[../ext/ext.html]{Extending and Embedding
+the Python Interpreter} describes how to add new extensions to Python
+and how to embed it in other applications.
+
+\end{abstract}
+
+\tableofcontents
+
+                                % Chapter title:
+
+\input{libintro}                % Introduction
+
+
+% =============
+% BUILT-INs
+% =============
+
+\input{libobjs}                 % Built-in Exceptions and Functions
+\input{libfuncs}
+\input{libexcs}
+\input{libconsts}
+
+\input{libstdtypes}             % Built-in types
+
+
+% =============
+% BASIC/GENERAL-PURPOSE OBJECTS
+% =============
+
+% Strings
+\input{libstrings}              % String Services
+\input{libstring}
+\input{libre}
+\input{libstruct}   % XXX also/better in File Formats?
+\input{libdifflib}
+\input{libstringio}
+\input{libtextwrap}
+\input{libcodecs}
+\input{libunicodedata}
+\input{libstringprep}
+\input{libfpformat}
+
+
+\input{datatypes}		% Data types and structures
+\input{libdatetime}
+\input{libcalendar}
+\input{libcollections}
+\input{libheapq}
+\input{libbisect}
+\input{libarray}
+\input{libsets}
+\input{libsched}
+\input{libmutex}
+\input{libqueue}
+\input{libweakref}
+\input{libuserdict}
+
+% General object services
+% XXX intro
+\input{libtypes}
+\input{libnew}
+\input{libcopy}
+\input{libpprint}
+\input{librepr}
+
+
+\input{numeric}			% Numeric/Mathematical modules
+\input{libmath}
+\input{libcmath}
+\input{libdecimal}
+\input{librandom}
+
+% Functions, Functional, Generators and Iterators
+% XXX intro functional
+\input{libitertools}
+\input{libfunctools}
+\input{liboperator}       % from runtime - better with itertools and functools
+
+
+% =============
+% DATA FORMATS
+% =============
+
+% Big move - include all the markup and internet formats here
+
+% MIME & email stuff
+\input{netdata}                 % Internet Data Handling
+\input{email}
+\input{libmailcap}
+\input{libmailbox}
+\input{libmhlib}
+\input{libmimetools}
+\input{libmimetypes}
+\input{libmimewriter}
+\input{libmimify}
+\input{libmultifile}
+\input{librfc822}
+
+% encoding stuff
+\input{libbase64}
+\input{libbinhex}
+\input{libbinascii}
+\input{libquopri}
+\input{libuu}
+
+\input{markup}                  % Structured Markup Processing Tools
+\input{libhtmlparser}
+\input{libsgmllib}
+\input{libhtmllib}
+\input{libpyexpat}
+\input{xmldom}
+\input{xmldomminidom}
+\input{xmldompulldom}
+\input{xmlsax}
+\input{xmlsaxhandler}
+\input{xmlsaxutils}
+\input{xmlsaxreader}
+\input{libetree}
+% \input{libxmllib}
+
+\input{fileformats}		% Miscellaneous file formats
+\input{libcsv}
+\input{libcfgparser}
+\input{librobotparser}
+\input{libnetrc}
+\input{libxdrlib}
+
+\input{libcrypto}               % Cryptographic Services
+\input{libhashlib}
+\input{libhmac}
+\input{libmd5}
+\input{libsha}
+
+% =============
+% FILE & DATABASE STORAGE
+% =============
+
+\input{filesys}			% File/directory support
+\input{libposixpath}            % os.path
+\input{libfileinput}
+\input{libstat}
+\input{libstatvfs}
+\input{libfilecmp}
+\input{libtempfile}
+\input{libglob}
+\input{libfnmatch}
+\input{liblinecache}
+\input{libshutil}
+\input{libdircache}
+
+
+\input{archiving}		% Data compression and archiving
+\input{libzlib}
+\input{libgzip}
+\input{libbz2}
+\input{libzipfile}
+\input{libtarfile}
+
+
+\input{persistence}		% Persistent storage
+\input{libpickle}
+\input{libcopyreg}              % really copy_reg % from runtime...
+\input{libshelve}
+\input{libmarshal}
+\input{libanydbm}
+\input{libwhichdb}
+\input{libdbm}
+\input{libgdbm}
+\input{libdbhash}
+\input{libbsddb}
+\input{libdumbdbm}
+\input{libsqlite3}
+
+
+% =============
+% OS
+% =============
+
+
+\input{liballos}                % Generic Operating System Services
+\input{libos}
+\input{libtime}
+\input{liboptparse}
+\input{libgetopt}
+\input{liblogging}
+\input{libgetpass}
+\input{libcurses}
+\input{libascii}                % curses.ascii
+\input{libcursespanel}
+\input{libplatform}
+\input{liberrno}
+\input{libctypes}
+
+\input{libsomeos}               % Optional Operating System Services
+\input{libselect}
+\input{libthread}
+\input{libthreading}
+\input{libdummythread}
+\input{libdummythreading}
+\input{libmmap}
+\input{libreadline}
+\input{librlcompleter}
+
+\input{libunix}                 % UNIX Specific Services
+\input{libposix}
+\input{libpwd}
+\input{libspwd}
+\input{libgrp}
+\input{libcrypt}
+\input{libdl}
+\input{libtermios}
+\input{libtty}
+\input{libpty}
+\input{libfcntl}
+\input{libpipes}
+\input{libposixfile}
+\input{libresource}
+\input{libnis}
+\input{libsyslog}
+\input{libcommands}
+
+
+% =============
+% NETWORK & COMMUNICATIONS
+% =============
+
+\input{ipc}                     % Interprocess communication/networking
+\input{libsubprocess}
+\input{libsocket}
+\input{libsignal}
+\input{libpopen2}
+\input{libasyncore}
+\input{libasynchat}
+
+\input{internet}                % Internet Protocols
+\input{libwebbrowser}
+\input{libcgi}
+\input{libcgitb}
+\input{libwsgiref}
+\input{liburllib}
+\input{liburllib2}
+\input{libhttplib}
+\input{libftplib}
+\input{libgopherlib}
+\input{libpoplib}
+\input{libimaplib}
+\input{libnntplib}
+\input{libsmtplib}
+\input{libsmtpd}
+\input{libtelnetlib}
+\input{libuuid}
+\input{liburlparse}
+\input{libsocksvr}
+\input{libbasehttp}
+\input{libsimplehttp}
+\input{libcgihttp}
+\input{libcookielib}
+\input{libcookie}
+\input{libxmlrpclib}
+\input{libsimplexmlrpc}
+\input{libdocxmlrpc}
+
+% =============
+% MULTIMEDIA
+% =============
+
+\input{libmm}                   % Multimedia Services
+\input{libaudioop}
+\input{libimageop}
+\input{libaifc}
+\input{libsunau}
+\input{libwave}
+\input{libchunk}
+\input{libcolorsys}
+\input{librgbimg}
+\input{libimghdr}
+\input{libsndhdr}
+\input{libossaudiodev}
+
+% Tkinter is a chapter in its own right.
+\input{tkinter}
+
+%                                % Internationalization
+\input{i18n}
+\input{libgettext}
+\input{liblocale}
+
+% =============
+% PROGRAM FRAMEWORKS
+% =============
+\input{frameworks}
+\input{libcmd}
+\input{libshlex}
+
+
+% =============
+% DEVELOPMENT TOOLS
+% =============
+%                                % Software development support
+\input{development}
+\input{libpydoc}
+\input{libdoctest}
+\input{libunittest}
+\input{libtest}
+
+\input{libpdb}                  % The Python Debugger
+
+\input{libprofile}              % The Python Profiler
+\input{libhotshot}              % unmaintained C profiler
+\input{libtimeit}
+\input{libtrace}
+
+% =============
+% PYTHON ENGINE
+% =============
+
+% Runtime services
+\input{libpython}               % Python Runtime Services
+\input{libsys}
+\input{libbltin}                % really __builtin__
+\input{libmain}                 % really __main__
+\input{libwarnings}
+\input{libcontextlib}
+\input{libatexit}
+\input{libtraceback}
+\input{libfuture}               % really __future__
+\input{libgc}
+\input{libinspect}
+\input{libsite}
+\input{libuser}
+\input{libfpectl}
+
+
+\input{custominterp}		% Custom interpreter
+\input{libcode}
+\input{libcodeop}
+\input{librestricted}           % Restricted Execution
+\input{librexec}
+\input{libbastion}
+
+
+\input{modules}			% Importing Modules
+\input{libimp}
+\input{libzipimport}
+\input{libpkgutil}
+\input{libmodulefinder}
+\input{librunpy}
+
+
+% =============
+% PYTHON LANGUAGE & COMPILER
+% =============
+
+\input{language}                % Python Language Services
+\input{libparser}
+\input{libsymbol}
+\input{libtoken}
+\input{libkeyword}
+\input{libtokenize}
+\input{libtabnanny}
+\input{libpyclbr}
+\input{libpycompile}            % really py_compile
+\input{libcompileall}
+\input{libdis}
+\input{libpickletools}
+\input{distutils}
+
+\input{compiler}                % compiler package
+\input{libast}
+
+\input{libmisc}                 % Miscellaneous Services
+\input{libformatter}
+
+% =============
+% OTHER PLATFORM-SPECIFIC STUFF
+% =============
+
+%\input{libamoeba}              % AMOEBA ONLY
+
+%\input{libstdwin}              % STDWIN ONLY
+
+\input{libsgi}                  % SGI IRIX ONLY
+\input{libal}
+\input{libcd}
+\input{libfl}
+\input{libfm}
+\input{libgl}
+\input{libimgfile}
+\input{libjpeg}
+%\input{libpanel}
+
+\input{libsun}                  % SUNOS ONLY
+\input{libsunaudio}
+
+\input{windows}                 % MS Windows ONLY
+\input{libmsilib}
+\input{libmsvcrt}
+\input{libwinreg}
+\input{libwinsound}
+
+\appendix
+\input{libundoc}
+
+%\chapter{Obsolete Modules}
+%\input{libcmpcache}
+%\input{libcmp}
+%\input{libni}
+
+\chapter{Reporting Bugs}
+\input{reportingbugs}
+
+\chapter{History and License}
+\input{license}
+
+%
+%  The ugly "%begin{latexonly}" pseudo-environments are really just to
+%  keep LaTeX2HTML quiet during the \renewcommand{} macros; they're
+%  not really valuable.
+%
+
+%begin{latexonly}
+\renewcommand{\indexname}{Module Index}
+%end{latexonly}
+\input{modlib.ind}              % Module Index
+
+%begin{latexonly}
+\renewcommand{\indexname}{Index}
+%end{latexonly}
+\input{lib.ind}                 % Index
+
+\end{document}

Added: vendor/Python/current/Doc/lib/libaifc.tex
===================================================================
--- vendor/Python/current/Doc/lib/libaifc.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libaifc.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,202 @@
+\section{\module{aifc} ---
+         Read and write AIFF and AIFC files}
+
+\declaremodule{standard}{aifc}
+\modulesynopsis{Read and write audio files in AIFF or AIFC format.}
+
+
+This module provides support for reading and writing AIFF and AIFF-C
+files.  AIFF is Audio Interchange File Format, a format for storing
+digital audio samples in a file.  AIFF-C is a newer version of the
+format that includes the ability to compress the audio data.
+\index{Audio Interchange File Format}
+\index{AIFF}
+\index{AIFF-C}
+
+\strong{Caveat:}  Some operations may only work under IRIX; these will
+raise \exception{ImportError} when attempting to import the
+\module{cl} module, which is only available on IRIX.
+
+Audio files have a number of parameters that describe the audio data.
+The sampling rate or frame rate is the number of times per second the
+sound is sampled.  The number of channels indicate if the audio is
+mono, stereo, or quadro.  Each frame consists of one sample per
+channel.  The sample size is the size in bytes of each sample.  Thus a
+frame consists of \var{nchannels}*\var{samplesize} bytes, and a
+second's worth of audio consists of
+\var{nchannels}*\var{samplesize}*\var{framerate} bytes.
+
+For example, CD quality audio has a sample size of two bytes (16
+bits), uses two channels (stereo) and has a frame rate of 44,100
+frames/second.  This gives a frame size of 4 bytes (2*2), and a
+second's worth occupies 2*2*44100 bytes (176,400 bytes).
+
+Module \module{aifc} defines the following function:
+
+\begin{funcdesc}{open}{file\optional{, mode}}
+Open an AIFF or AIFF-C file and return an object instance with
+methods that are described below.  The argument \var{file} is either a
+string naming a file or a file object.  \var{mode} must be \code{'r'}
+or \code{'rb'} when the file must be opened for reading, or \code{'w'} 
+or \code{'wb'} when the file must be opened for writing.  If omitted,
+\code{\var{file}.mode} is used if it exists, otherwise \code{'rb'} is
+used.  When used for writing, the file object should be seekable,
+unless you know ahead of time how many samples you are going to write
+in total and use \method{writeframesraw()} and \method{setnframes()}.
+\end{funcdesc}
+
+Objects returned by \function{open()} when a file is opened for
+reading have the following methods:
+
+\begin{methoddesc}[aifc]{getnchannels}{}
+Return the number of audio channels (1 for mono, 2 for stereo).
+\end{methoddesc}
+
+\begin{methoddesc}[aifc]{getsampwidth}{}
+Return the size in bytes of individual samples.
+\end{methoddesc}
+
+\begin{methoddesc}[aifc]{getframerate}{}
+Return the sampling rate (number of audio frames per second).
+\end{methoddesc}
+
+\begin{methoddesc}[aifc]{getnframes}{}
+Return the number of audio frames in the file.
+\end{methoddesc}
+
+\begin{methoddesc}[aifc]{getcomptype}{}
+Return a four-character string describing the type of compression used
+in the audio file.  For AIFF files, the returned value is
+\code{'NONE'}.
+\end{methoddesc}
+
+\begin{methoddesc}[aifc]{getcompname}{}
+Return a human-readable description of the type of compression used in
+the audio file.  For AIFF files, the returned value is \code{'not
+compressed'}.
+\end{methoddesc}
+
+\begin{methoddesc}[aifc]{getparams}{}
+Return a tuple consisting of all of the above values in the above
+order.
+\end{methoddesc}
+
+\begin{methoddesc}[aifc]{getmarkers}{}
+Return a list of markers in the audio file.  A marker consists of a
+tuple of three elements.  The first is the mark ID (an integer), the
+second is the mark position in frames from the beginning of the data
+(an integer), the third is the name of the mark (a string).
+\end{methoddesc}
+
+\begin{methoddesc}[aifc]{getmark}{id}
+Return the tuple as described in \method{getmarkers()} for the mark
+with the given \var{id}.
+\end{methoddesc}
+
+\begin{methoddesc}[aifc]{readframes}{nframes}
+Read and return the next \var{nframes} frames from the audio file.  The
+returned data is a string containing for each frame the uncompressed
+samples of all channels.
+\end{methoddesc}
+
+\begin{methoddesc}[aifc]{rewind}{}
+Rewind the read pointer.  The next \method{readframes()} will start from
+the beginning.
+\end{methoddesc}
+
+\begin{methoddesc}[aifc]{setpos}{pos}
+Seek to the specified frame number.
+\end{methoddesc}
+
+\begin{methoddesc}[aifc]{tell}{}
+Return the current frame number.
+\end{methoddesc}
+
+\begin{methoddesc}[aifc]{close}{}
+Close the AIFF file.  After calling this method, the object can no
+longer be used.
+\end{methoddesc}
+
+Objects returned by \function{open()} when a file is opened for
+writing have all the above methods, except for \method{readframes()} and
+\method{setpos()}.  In addition the following methods exist.  The
+\method{get*()} methods can only be called after the corresponding
+\method{set*()} methods have been called.  Before the first
+\method{writeframes()} or \method{writeframesraw()}, all parameters
+except for the number of frames must be filled in.
+
+\begin{methoddesc}[aifc]{aiff}{}
+Create an AIFF file.  The default is that an AIFF-C file is created,
+unless the name of the file ends in \code{'.aiff'} in which case the
+default is an AIFF file.
+\end{methoddesc}
+
+\begin{methoddesc}[aifc]{aifc}{}
+Create an AIFF-C file.  The default is that an AIFF-C file is created,
+unless the name of the file ends in \code{'.aiff'} in which case the
+default is an AIFF file.
+\end{methoddesc}
+
+\begin{methoddesc}[aifc]{setnchannels}{nchannels}
+Specify the number of channels in the audio file.
+\end{methoddesc}
+
+\begin{methoddesc}[aifc]{setsampwidth}{width}
+Specify the size in bytes of audio samples.
+\end{methoddesc}
+
+\begin{methoddesc}[aifc]{setframerate}{rate}
+Specify the sampling frequency in frames per second.
+\end{methoddesc}
+
+\begin{methoddesc}[aifc]{setnframes}{nframes}
+Specify the number of frames that are to be written to the audio file.
+If this parameter is not set, or not set correctly, the file needs to
+support seeking.
+\end{methoddesc}
+
+\begin{methoddesc}[aifc]{setcomptype}{type, name}
+Specify the compression type.  If not specified, the audio data will
+not be compressed.  In AIFF files, compression is not possible.  The
+name parameter should be a human-readable description of the
+compression type, the type parameter should be a four-character
+string.  Currently the following compression types are supported:
+NONE, ULAW, ALAW, G722.
+\index{u-LAW}
+\index{A-LAW}
+\index{G.722}
+\end{methoddesc}
+
+\begin{methoddesc}[aifc]{setparams}{nchannels, sampwidth, framerate, comptype, compname}
+Set all the above parameters at once.  The argument is a tuple
+consisting of the various parameters.  This means that it is possible
+to use the result of a \method{getparams()} call as argument to
+\method{setparams()}.
+\end{methoddesc}
+
+\begin{methoddesc}[aifc]{setmark}{id, pos, name}
+Add a mark with the given id (larger than 0), and the given name at
+the given position.  This method can be called at any time before
+\method{close()}.
+\end{methoddesc}
+
+\begin{methoddesc}[aifc]{tell}{}
+Return the current write position in the output file.  Useful in
+combination with \method{setmark()}.
+\end{methoddesc}
+
+\begin{methoddesc}[aifc]{writeframes}{data}
+Write data to the output file.  This method can only be called after
+the audio file parameters have been set.
+\end{methoddesc}
+
+\begin{methoddesc}[aifc]{writeframesraw}{data}
+Like \method{writeframes()}, except that the header of the audio file
+is not updated.
+\end{methoddesc}
+
+\begin{methoddesc}[aifc]{close}{}
+Close the AIFF file.  The header of the file is updated to reflect the
+actual size of the audio data. After calling this method, the object
+can no longer be used.
+\end{methoddesc}

Added: vendor/Python/current/Doc/lib/libal.tex
===================================================================
--- vendor/Python/current/Doc/lib/libal.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libal.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,181 @@
+\section{\module{al} ---
+         Audio functions on the SGI}
+
+\declaremodule{builtin}{al}
+  \platform{IRIX}
+\modulesynopsis{Audio functions on the SGI.}
+
+
+This module provides access to the audio facilities of the SGI Indy
+and Indigo workstations.  See section 3A of the IRIX man pages for
+details.  You'll need to read those man pages to understand what these
+functions do!  Some of the functions are not available in IRIX
+releases before 4.0.5.  Again, see the manual to check whether a
+specific function is available on your platform.
+
+All functions and methods defined in this module are equivalent to
+the C functions with \samp{AL} prefixed to their name.
+
+Symbolic constants from the C header file \code{<audio.h>} are
+defined in the standard module
+\refmodule[al-constants]{AL}\refstmodindex{AL}, see below.
+
+\warning{The current version of the audio library may dump core
+when bad argument values are passed rather than returning an error
+status.  Unfortunately, since the precise circumstances under which
+this may happen are undocumented and hard to check, the Python
+interface can provide no protection against this kind of problems.
+(One example is specifying an excessive queue size --- there is no
+documented upper limit.)}
+
+The module defines the following functions:
+
+
+\begin{funcdesc}{openport}{name, direction\optional{, config}}
+The name and direction arguments are strings.  The optional
+\var{config} argument is a configuration object as returned by
+\function{newconfig()}.  The return value is an \dfn{audio port
+object}; methods of audio port objects are described below.
+\end{funcdesc}
+
+\begin{funcdesc}{newconfig}{}
+The return value is a new \dfn{audio configuration object}; methods of
+audio configuration objects are described below.
+\end{funcdesc}
+
+\begin{funcdesc}{queryparams}{device}
+The device argument is an integer.  The return value is a list of
+integers containing the data returned by \cfunction{ALqueryparams()}.
+\end{funcdesc}
+
+\begin{funcdesc}{getparams}{device, list}
+The \var{device} argument is an integer.  The list argument is a list
+such as returned by \function{queryparams()}; it is modified in place
+(!).
+\end{funcdesc}
+
+\begin{funcdesc}{setparams}{device, list}
+The \var{device} argument is an integer.  The \var{list} argument is a
+list such as returned by \function{queryparams()}.
+\end{funcdesc}
+
+
+\subsection{Configuration Objects \label{al-config-objects}}
+
+Configuration objects returned by \function{newconfig()} have the
+following methods:
+
+\begin{methoddesc}[audio configuration]{getqueuesize}{}
+Return the queue size.
+\end{methoddesc}
+
+\begin{methoddesc}[audio configuration]{setqueuesize}{size}
+Set the queue size.
+\end{methoddesc}
+
+\begin{methoddesc}[audio configuration]{getwidth}{}
+Get the sample width.
+\end{methoddesc}
+
+\begin{methoddesc}[audio configuration]{setwidth}{width}
+Set the sample width.
+\end{methoddesc}
+
+\begin{methoddesc}[audio configuration]{getchannels}{}
+Get the channel count.
+\end{methoddesc}
+
+\begin{methoddesc}[audio configuration]{setchannels}{nchannels}
+Set the channel count.
+\end{methoddesc}
+
+\begin{methoddesc}[audio configuration]{getsampfmt}{}
+Get the sample format.
+\end{methoddesc}
+
+\begin{methoddesc}[audio configuration]{setsampfmt}{sampfmt}
+Set the sample format.
+\end{methoddesc}
+
+\begin{methoddesc}[audio configuration]{getfloatmax}{}
+Get the maximum value for floating sample formats.
+\end{methoddesc}
+
+\begin{methoddesc}[audio configuration]{setfloatmax}{floatmax}
+Set the maximum value for floating sample formats.
+\end{methoddesc}
+
+
+\subsection{Port Objects \label{al-port-objects}}
+
+Port objects, as returned by \function{openport()}, have the following
+methods:
+
+\begin{methoddesc}[audio port]{closeport}{}
+Close the port.
+\end{methoddesc}
+
+\begin{methoddesc}[audio port]{getfd}{}
+Return the file descriptor as an int.
+\end{methoddesc}
+
+\begin{methoddesc}[audio port]{getfilled}{}
+Return the number of filled samples.
+\end{methoddesc}
+
+\begin{methoddesc}[audio port]{getfillable}{}
+Return the number of fillable samples.
+\end{methoddesc}
+
+\begin{methoddesc}[audio port]{readsamps}{nsamples}
+Read a number of samples from the queue, blocking if necessary.
+Return the data as a string containing the raw data, (e.g., 2 bytes per
+sample in big-endian byte order (high byte, low byte) if you have set
+the sample width to 2 bytes).
+\end{methoddesc}
+
+\begin{methoddesc}[audio port]{writesamps}{samples}
+Write samples into the queue, blocking if necessary.  The samples are
+encoded as described for the \method{readsamps()} return value.
+\end{methoddesc}
+
+\begin{methoddesc}[audio port]{getfillpoint}{}
+Return the `fill point'.
+\end{methoddesc}
+
+\begin{methoddesc}[audio port]{setfillpoint}{fillpoint}
+Set the `fill point'.
+\end{methoddesc}
+
+\begin{methoddesc}[audio port]{getconfig}{}
+Return a configuration object containing the current configuration of
+the port.
+\end{methoddesc}
+
+\begin{methoddesc}[audio port]{setconfig}{config}
+Set the configuration from the argument, a configuration object.
+\end{methoddesc}
+
+\begin{methoddesc}[audio port]{getstatus}{list}
+Get status information on last error.
+\end{methoddesc}
+
+
+\section{\module{AL} ---
+         Constants used with the \module{al} module}
+
+\declaremodule[al-constants]{standard}{AL}
+  \platform{IRIX}
+\modulesynopsis{Constants used with the \module{al} module.}
+
+
+This module defines symbolic constants needed to use the built-in
+module \refmodule{al} (see above); they are equivalent to those defined
+in the C header file \code{<audio.h>} except that the name prefix
+\samp{AL_} is omitted.  Read the module source for a complete list of
+the defined names.  Suggested use:
+
+\begin{verbatim}
+import al
+from AL import *
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/liballos.tex
===================================================================
--- vendor/Python/current/Doc/lib/liballos.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/liballos.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,9 @@
+\chapter{Generic Operating System Services \label{allos}}
+
+The modules described in this chapter provide interfaces to operating
+system features that are available on (almost) all operating systems,
+such as files and a clock.  The interfaces are generally modeled
+after the \UNIX{} or C interfaces, but they are available on most
+other systems as well.  Here's an overview:
+
+\localmoduletable

Added: vendor/Python/current/Doc/lib/libamoeba.tex
===================================================================
--- vendor/Python/current/Doc/lib/libamoeba.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libamoeba.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,132 @@
+\chapter{Amoeba Specific Services}
+
+\section{\module{amoeba} ---
+         Amoeba system support}
+
+\declaremodule{builtin}{amoeba}
+  \platform{Amoeba}
+\modulesynopsis{Functions for the Amoeba operating system.}
+
+
+This module provides some object types and operations useful for
+Amoeba applications.  It is only available on systems that support
+Amoeba operations.  RPC errors and other Amoeba errors are reported as
+the exception \code{amoeba.error = 'amoeba.error'}.
+
+The module \module{amoeba} defines the following items:
+
+\begin{funcdesc}{name_append}{path, cap}
+Stores a capability in the Amoeba directory tree.
+Arguments are the pathname (a string) and the capability (a capability
+object as returned by
+\function{name_lookup()}).
+\end{funcdesc}
+
+\begin{funcdesc}{name_delete}{path}
+Deletes a capability from the Amoeba directory tree.
+Argument is the pathname.
+\end{funcdesc}
+
+\begin{funcdesc}{name_lookup}{path}
+Looks up a capability.
+Argument is the pathname.
+Returns a
+\dfn{capability}
+object, to which various interesting operations apply, described below.
+\end{funcdesc}
+
+\begin{funcdesc}{name_replace}{path, cap}
+Replaces a capability in the Amoeba directory tree.
+Arguments are the pathname and the new capability.
+(This differs from
+\function{name_append()}
+in the behavior when the pathname already exists:
+\function{name_append()}
+finds this an error while
+\function{name_replace()}
+allows it, as its name suggests.)
+\end{funcdesc}
+
+\begin{datadesc}{capv}
+A table representing the capability environment at the time the
+interpreter was started.
+(Alas, modifying this table does not affect the capability environment
+of the interpreter.)
+For example,
+\code{amoeba.capv['ROOT']}
+is the capability of your root directory, similar to
+\code{getcap("ROOT")}
+in C.
+\end{datadesc}
+
+\begin{excdesc}{error}
+The exception raised when an Amoeba function returns an error.
+The value accompanying this exception is a pair containing the numeric
+error code and the corresponding string, as returned by the C function
+\cfunction{err_why()}.
+\end{excdesc}
+
+\begin{funcdesc}{timeout}{msecs}
+Sets the transaction timeout, in milliseconds.
+Returns the previous timeout.
+Initially, the timeout is set to 2 seconds by the Python interpreter.
+\end{funcdesc}
+
+\subsection{Capability Operations}
+
+Capabilities are written in a convenient \ASCII{} format, also used by the
+Amoeba utilities
+\emph{c2a}(U)
+and
+\emph{a2c}(U).
+For example:
+
+\begin{verbatim}
+>>> amoeba.name_lookup('/profile/cap')
+aa:1c:95:52:6a:fa/14(ff)/8e:ba:5b:8:11:1a
+>>> 
+\end{verbatim}
+%
+The following methods are defined for capability objects.
+
+\setindexsubitem{(capability method)}
+\begin{funcdesc}{dir_list}{}
+Returns a list of the names of the entries in an Amoeba directory.
+\end{funcdesc}
+
+\begin{funcdesc}{b_read}{offset, maxsize}
+Reads (at most)
+\var{maxsize}
+bytes from a bullet file at offset
+\var{offset.}
+The data is returned as a string.
+EOF is reported as an empty string.
+\end{funcdesc}
+
+\begin{funcdesc}{b_size}{}
+Returns the size of a bullet file.
+\end{funcdesc}
+
+\begin{funcdesc}{dir_append}{}
+\funcline{dir_delete}{}
+\funcline{dir_lookup}{}
+\funcline{dir_replace}{}
+Like the corresponding
+\samp{name_}*
+functions, but with a path relative to the capability.
+(For paths beginning with a slash the capability is ignored, since this
+is the defined semantics for Amoeba.)
+\end{funcdesc}
+
+\begin{funcdesc}{std_info}{}
+Returns the standard info string of the object.
+\end{funcdesc}
+
+\begin{funcdesc}{tod_gettime}{}
+Returns the time (in seconds since the Epoch, in UCT, as for \POSIX) from
+a time server.
+\end{funcdesc}
+
+\begin{funcdesc}{tod_settime}{t}
+Sets the time kept by a time server.
+\end{funcdesc}

Added: vendor/Python/current/Doc/lib/libanydbm.tex
===================================================================
--- vendor/Python/current/Doc/lib/libanydbm.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libanydbm.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,85 @@
+\section{\module{anydbm} ---
+         Generic access to DBM-style databases}
+
+\declaremodule{standard}{anydbm}
+\modulesynopsis{Generic interface to DBM-style database modules.}
+
+
+\module{anydbm} is a generic interface to variants of the DBM
+database --- \refmodule{dbhash}\refstmodindex{dbhash} (requires
+\refmodule{bsddb}\refbimodindex{bsddb}),
+\refmodule{gdbm}\refbimodindex{gdbm}, or
+\refmodule{dbm}\refbimodindex{dbm}.  If none of these modules is
+installed, the slow-but-simple implementation in module
+\refmodule{dumbdbm}\refstmodindex{dumbdbm} will be used.
+
+\begin{funcdesc}{open}{filename\optional{, flag\optional{, mode}}}
+Open the database file \var{filename} and return a corresponding object.
+
+If the database file already exists, the \refmodule{whichdb} module is 
+used to determine its type and the appropriate module is used; if it
+does not exist, the first module listed above that can be imported is
+used.
+
+The optional \var{flag} argument can be
+\code{'r'} to open an existing database for reading only,
+\code{'w'} to open an existing database for reading and writing,
+\code{'c'} to create the database if it doesn't exist, or
+\code{'n'}, which will always create a new empty database.  If not
+specified, the default value is \code{'r'}.
+
+The optional \var{mode} argument is the \UNIX{} mode of the file, used
+only when the database has to be created.  It defaults to octal
+\code{0666} (and will be modified by the prevailing umask).
+\end{funcdesc}
+
+\begin{excdesc}{error}
+A tuple containing the exceptions that can be raised by each of the
+supported modules, with a unique exception \exception{anydbm.error} as
+the first item --- the latter is used when \exception{anydbm.error} is
+raised.
+\end{excdesc}
+
+The object returned by \function{open()} supports most of the same
+functionality as dictionaries; keys and their corresponding values can
+be stored, retrieved, and deleted, and the \method{has_key()} and
+\method{keys()} methods are available.  Keys and values must always be
+strings.
+
+The following example records some hostnames and a corresponding title, 
+and then prints out the contents of the database:
+
+\begin{verbatim}
+import anydbm
+
+# Open database, creating it if necessary.
+db = anydbm.open('cache', 'c')
+
+# Record some values
+db['www.python.org'] = 'Python Website'
+db['www.cnn.com'] = 'Cable News Network'
+
+# Loop through contents.  Other dictionary methods
+# such as .keys(), .values() also work.
+for k, v in db.iteritems():
+    print k, '\t', v
+
+# Storing a non-string key or value will raise an exception (most
+# likely a TypeError).
+db['www.yahoo.com'] = 4
+
+# Close when done.
+db.close()
+\end{verbatim}
+
+
+\begin{seealso}
+  \seemodule{dbhash}{BSD \code{db} database interface.}
+  \seemodule{dbm}{Standard \UNIX{} database interface.}
+  \seemodule{dumbdbm}{Portable implementation of the \code{dbm} interface.}
+  \seemodule{gdbm}{GNU database interface, based on the \code{dbm} interface.}
+  \seemodule{shelve}{General object persistence built on top of 
+                     the Python \code{dbm} interface.}
+  \seemodule{whichdb}{Utility module used to determine the type of an
+                      existing database.}
+\end{seealso}

Added: vendor/Python/current/Doc/lib/libarray.tex
===================================================================
--- vendor/Python/current/Doc/lib/libarray.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libarray.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,241 @@
+\section{\module{array} ---
+         Efficient arrays of numeric values}
+
+\declaremodule{builtin}{array}
+\modulesynopsis{Efficient arrays of uniformly typed numeric values.}
+
+
+This module defines an object type which can efficiently represent
+an array of basic values: characters, integers, floating point
+numbers.  Arrays\index{arrays} are sequence types and behave very much
+like lists, except that the type of objects stored in them is
+constrained.  The type is specified at object creation time by using a
+\dfn{type code}, which is a single character.  The following type
+codes are defined:
+
+\begin{tableiv}{c|l|l|c}{code}{Type code}{C Type}{Python Type}{Minimum size in bytes}
+  \lineiv{'c'}{char}          {character}        {1}
+  \lineiv{'b'}{signed char}   {int}              {1}
+  \lineiv{'B'}{unsigned char} {int}              {1}
+  \lineiv{'u'}{Py_UNICODE}    {Unicode character}{2}
+  \lineiv{'h'}{signed short}  {int}              {2}
+  \lineiv{'H'}{unsigned short}{int}              {2}
+  \lineiv{'i'}{signed int}    {int}              {2}
+  \lineiv{'I'}{unsigned int}  {long}             {2}
+  \lineiv{'l'}{signed long}   {int}              {4}
+  \lineiv{'L'}{unsigned long} {long}             {4}
+  \lineiv{'f'}{float}         {float}            {4}
+  \lineiv{'d'}{double}        {float}            {8}
+\end{tableiv}
+
+The actual representation of values is determined by the machine
+architecture (strictly speaking, by the C implementation).  The actual
+size can be accessed through the \member{itemsize} attribute.  The values
+stored  for \code{'L'} and \code{'I'} items will be represented as
+Python long integers when retrieved, because Python's plain integer
+type cannot represent the full range of C's unsigned (long) integers.
+
+
+The module defines the following type:
+
+\begin{funcdesc}{array}{typecode\optional{, initializer}}
+Return a new array whose items are restricted by \var{typecode},
+and initialized from the optional \var{initializer} value, which
+must be a list, string, or iterable over elements of the
+appropriate type.
+\versionchanged[Formerly, only lists or strings were accepted]{2.4}
+If given a list or string, the initializer is passed to the
+new array's \method{fromlist()}, \method{fromstring()}, or
+\method{fromunicode()} method (see below) to add initial items to
+the array.  Otherwise, the iterable initializer is passed to the
+\method{extend()} method.
+\end{funcdesc}
+
+\begin{datadesc}{ArrayType}
+Obsolete alias for \function{array}.
+\end{datadesc}
+
+
+Array objects support the ordinary sequence operations of
+indexing, slicing, concatenation, and multiplication.  When using
+slice assignment, the assigned value must be an array object with the
+same type code; in all other cases, \exception{TypeError} is raised.
+Array objects also implement the buffer interface, and may be used
+wherever buffer objects are supported.
+
+The following data items and methods are also supported:
+
+\begin{memberdesc}[array]{typecode}
+The typecode character used to create the array.
+\end{memberdesc}
+
+\begin{memberdesc}[array]{itemsize}
+The length in bytes of one array item in the internal representation.
+\end{memberdesc}
+
+
+\begin{methoddesc}[array]{append}{x}
+Append a new item with value \var{x} to the end of the array.
+\end{methoddesc}
+
+\begin{methoddesc}[array]{buffer_info}{}
+Return a tuple \code{(\var{address}, \var{length})} giving the current
+memory address and the length in elements of the buffer used to hold
+array's contents.  The size of the memory buffer in bytes can be
+computed as \code{\var{array}.buffer_info()[1] *
+\var{array}.itemsize}.  This is occasionally useful when working with
+low-level (and inherently unsafe) I/O interfaces that require memory
+addresses, such as certain \cfunction{ioctl()} operations.  The
+returned numbers are valid as long as the array exists and no
+length-changing operations are applied to it.
+
+\note{When using array objects from code written in C or
+\Cpp{} (the only way to effectively make use of this information), it
+makes more sense to use the buffer interface supported by array
+objects.  This method is maintained for backward compatibility and
+should be avoided in new code.  The buffer interface is documented in
+the \citetitle[../api/newTypes.html]{Python/C API Reference Manual}.}
+\end{methoddesc}
+
+\begin{methoddesc}[array]{byteswap}{}
+``Byteswap'' all items of the array.  This is only supported for
+values which are 1, 2, 4, or 8 bytes in size; for other types of
+values, \exception{RuntimeError} is raised.  It is useful when reading
+data from a file written on a machine with a different byte order.
+\end{methoddesc}
+
+\begin{methoddesc}[array]{count}{x}
+Return the number of occurrences of \var{x} in the array.
+\end{methoddesc}
+
+\begin{methoddesc}[array]{extend}{iterable}
+Append items from \var{iterable} to the end of the array.  If
+\var{iterable} is another array, it must have \emph{exactly} the same
+type code; if not, \exception{TypeError} will be raised.  If
+\var{iterable} is not an array, it must be iterable and its
+elements must be the right type to be appended to the array.
+\versionchanged[Formerly, the argument could only be another array]{2.4}
+\end{methoddesc}
+
+\begin{methoddesc}[array]{fromfile}{f, n}
+Read \var{n} items (as machine values) from the file object \var{f}
+and append them to the end of the array.  If less than \var{n} items
+are available, \exception{EOFError} is raised, but the items that were
+available are still inserted into the array.  \var{f} must be a real
+built-in file object; something else with a \method{read()} method won't
+do.
+\end{methoddesc}
+
+\begin{methoddesc}[array]{fromlist}{list}
+Append items from the list.  This is equivalent to
+\samp{for x in \var{list}:\ a.append(x)}
+except that if there is a type error, the array is unchanged.
+\end{methoddesc}
+
+\begin{methoddesc}[array]{fromstring}{s}
+Appends items from the string, interpreting the string as an
+array of machine values (as if it had been read from a
+file using the \method{fromfile()} method).
+\end{methoddesc}
+
+\begin{methoddesc}[array]{fromunicode}{s}
+Extends this array with data from the given unicode string.  The array
+must be a type \code{'u'} array; otherwise a \exception{ValueError}
+is raised.  Use \samp{array.fromstring(ustr.decode(enc))} to
+append Unicode data to an array of some other type.
+\end{methoddesc}
+
+\begin{methoddesc}[array]{index}{x}
+Return the smallest \var{i} such that \var{i} is the index of
+the first occurrence of \var{x} in the array.
+\end{methoddesc}
+
+\begin{methoddesc}[array]{insert}{i, x}
+Insert a new item with value \var{x} in the array before position
+\var{i}. Negative values are treated as being relative to the end
+of the array.
+\end{methoddesc}
+
+\begin{methoddesc}[array]{pop}{\optional{i}}
+Removes the item with the index \var{i} from the array and returns
+it. The optional argument defaults to \code{-1}, so that by default
+the last item is removed and returned.
+\end{methoddesc}
+
+\begin{methoddesc}[array]{read}{f, n}
+\deprecated {1.5.1}
+  {Use the \method{fromfile()} method.}
+Read \var{n} items (as machine values) from the file object \var{f}
+and append them to the end of the array.  If less than \var{n} items
+are available, \exception{EOFError} is raised, but the items that were
+available are still inserted into the array.  \var{f} must be a real
+built-in file object; something else with a \method{read()} method won't
+do.
+\end{methoddesc}
+
+\begin{methoddesc}[array]{remove}{x}
+Remove the first occurrence of \var{x} from the array.
+\end{methoddesc}
+
+\begin{methoddesc}[array]{reverse}{}
+Reverse the order of the items in the array.
+\end{methoddesc}
+
+\begin{methoddesc}[array]{tofile}{f}
+Write all items (as machine values) to the file object \var{f}.
+\end{methoddesc}
+
+\begin{methoddesc}[array]{tolist}{}
+Convert the array to an ordinary list with the same items.
+\end{methoddesc}
+
+\begin{methoddesc}[array]{tostring}{}
+Convert the array to an array of machine values and return the
+string representation (the same sequence of bytes that would
+be written to a file by the \method{tofile()} method.)
+\end{methoddesc}
+
+\begin{methoddesc}[array]{tounicode}{}
+Convert the array to a unicode string.  The array must be
+a type \code{'u'} array; otherwise a \exception{ValueError} is raised.
+Use \samp{array.tostring().decode(enc)} to obtain a unicode string
+from an array of some other type.
+\end{methoddesc}
+
+\begin{methoddesc}[array]{write}{f}
+\deprecated {1.5.1}
+  {Use the \method{tofile()} method.}
+Write all items (as machine values) to the file object \var{f}.
+\end{methoddesc}
+
+When an array object is printed or converted to a string, it is
+represented as \code{array(\var{typecode}, \var{initializer})}.  The
+\var{initializer} is omitted if the array is empty, otherwise it is a
+string if the \var{typecode} is \code{'c'}, otherwise it is a list of
+numbers.  The string is guaranteed to be able to be converted back to
+an array with the same type and value using reverse quotes
+(\code{``}), so long as the \function{array()} function has been
+imported using \code{from array import array}.  Examples:
+
+\begin{verbatim}
+array('l')
+array('c', 'hello world')
+array('u', u'hello \textbackslash u2641')
+array('l', [1, 2, 3, 4, 5])
+array('d', [1.0, 2.0, 3.14])
+\end{verbatim}
+
+
+\begin{seealso}
+  \seemodule{struct}{Packing and unpacking of heterogeneous binary data.}
+  \seemodule{xdrlib}{Packing and unpacking of External Data
+                     Representation (XDR) data as used in some remote
+                     procedure call systems.}
+  \seetitle[http://numpy.sourceforge.net/numdoc/HTML/numdoc.htm]{The
+           Numerical Python Manual}{The Numeric Python extension
+           (NumPy) defines another array type; see
+           \url{http://numpy.sourceforge.net/} for further information
+           about Numerical Python.  (A PDF version of the NumPy manual
+           is available at
+           \url{http://numpy.sourceforge.net/numdoc/numdoc.pdf}).}
+\end{seealso}

Added: vendor/Python/current/Doc/lib/libascii.tex
===================================================================
--- vendor/Python/current/Doc/lib/libascii.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libascii.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,175 @@
+\section{\module{curses.ascii} ---
+         Utilities for ASCII characters}
+
+\declaremodule{standard}{curses.ascii}
+\modulesynopsis{Constants and set-membership functions for
+                \ASCII\ characters.}
+\moduleauthor{Eric S. Raymond}{esr at thyrsus.com}
+\sectionauthor{Eric S. Raymond}{esr at thyrsus.com}
+
+\versionadded{1.6}
+
+The \module{curses.ascii} module supplies name constants for
+\ASCII{} characters and functions to test membership in various
+\ASCII{} character classes.  The constants supplied are names for
+control characters as follows:
+
+\begin{tableii}{l|l}{constant}{Name}{Meaning}
+  \lineii{NUL}{}
+  \lineii{SOH}{Start of heading, console interrupt}
+  \lineii{STX}{Start of text}
+  \lineii{ETX}{End of text}
+  \lineii{EOT}{End of transmission}
+  \lineii{ENQ}{Enquiry, goes with \constant{ACK} flow control}
+  \lineii{ACK}{Acknowledgement}
+  \lineii{BEL}{Bell}
+  \lineii{BS}{Backspace}
+  \lineii{TAB}{Tab}
+  \lineii{HT}{Alias for \constant{TAB}: ``Horizontal tab''}
+  \lineii{LF}{Line feed}
+  \lineii{NL}{Alias for \constant{LF}: ``New line''}
+  \lineii{VT}{Vertical tab}
+  \lineii{FF}{Form feed}
+  \lineii{CR}{Carriage return}
+  \lineii{SO}{Shift-out, begin alternate character set}
+  \lineii{SI}{Shift-in, resume default character set}
+  \lineii{DLE}{Data-link escape}
+  \lineii{DC1}{XON, for flow control}
+  \lineii{DC2}{Device control 2, block-mode flow control}
+  \lineii{DC3}{XOFF, for flow control}
+  \lineii{DC4}{Device control 4}
+  \lineii{NAK}{Negative acknowledgement}
+  \lineii{SYN}{Synchronous idle}
+  \lineii{ETB}{End transmission block}
+  \lineii{CAN}{Cancel}
+  \lineii{EM}{End of medium}
+  \lineii{SUB}{Substitute}
+  \lineii{ESC}{Escape}
+  \lineii{FS}{File separator}
+  \lineii{GS}{Group separator}
+  \lineii{RS}{Record separator, block-mode terminator}
+  \lineii{US}{Unit separator}
+  \lineii{SP}{Space}
+  \lineii{DEL}{Delete}
+\end{tableii}
+
+Note that many of these have little practical significance in modern
+usage.  The mnemonics derive from teleprinter conventions that predate
+digital computers.
+
+The module supplies the following functions, patterned on those in the
+standard C library:
+
+
+\begin{funcdesc}{isalnum}{c}
+Checks for an \ASCII{} alphanumeric character; it is equivalent to
+\samp{isalpha(\var{c}) or isdigit(\var{c})}.
+\end{funcdesc}
+
+\begin{funcdesc}{isalpha}{c}
+Checks for an \ASCII{} alphabetic character; it is equivalent to
+\samp{isupper(\var{c}) or islower(\var{c})}.
+\end{funcdesc}
+
+\begin{funcdesc}{isascii}{c}
+Checks for a character value that fits in the 7-bit \ASCII{} set.
+\end{funcdesc}
+
+\begin{funcdesc}{isblank}{c}
+Checks for an \ASCII{} whitespace character.
+\end{funcdesc}
+
+\begin{funcdesc}{iscntrl}{c}
+Checks for an \ASCII{} control character (in the range 0x00 to 0x1f).
+\end{funcdesc}
+
+\begin{funcdesc}{isdigit}{c}
+Checks for an \ASCII{} decimal digit, \character{0} through
+\character{9}.  This is equivalent to \samp{\var{c} in string.digits}.
+\end{funcdesc}
+
+\begin{funcdesc}{isgraph}{c}
+Checks for \ASCII{} any printable character except space.
+\end{funcdesc}
+
+\begin{funcdesc}{islower}{c}
+Checks for an \ASCII{} lower-case character.
+\end{funcdesc}
+
+\begin{funcdesc}{isprint}{c}
+Checks for any \ASCII{} printable character including space.
+\end{funcdesc}
+
+\begin{funcdesc}{ispunct}{c}
+Checks for any printable \ASCII{} character which is not a space or an
+alphanumeric character.
+\end{funcdesc}
+
+\begin{funcdesc}{isspace}{c}
+Checks for \ASCII{} white-space characters; space, line feed,
+carriage return, form feed, horizontal tab, vertical tab.
+\end{funcdesc}
+
+\begin{funcdesc}{isupper}{c}
+Checks for an \ASCII{} uppercase letter.
+\end{funcdesc}
+
+\begin{funcdesc}{isxdigit}{c}
+Checks for an \ASCII{} hexadecimal digit.  This is equivalent to
+\samp{\var{c} in string.hexdigits}.
+\end{funcdesc}
+
+\begin{funcdesc}{isctrl}{c}
+Checks for an \ASCII{} control character (ordinal values 0 to 31).
+\end{funcdesc}
+
+\begin{funcdesc}{ismeta}{c}
+Checks for a non-\ASCII{} character (ordinal values 0x80 and above).
+\end{funcdesc}
+
+These functions accept either integers or strings; when the argument
+is a string, it is first converted using the built-in function
+\function{ord()}.
+
+Note that all these functions check ordinal bit values derived from the 
+first character of the string you pass in; they do not actually know
+anything about the host machine's character encoding.  For functions 
+that know about the character encoding (and handle
+internationalization properly) see the \refmodule{string} module.
+
+The following two functions take either a single-character string or
+integer byte value; they return a value of the same type.
+
+\begin{funcdesc}{ascii}{c}
+Return the ASCII value corresponding to the low 7 bits of \var{c}.
+\end{funcdesc}
+
+\begin{funcdesc}{ctrl}{c}
+Return the control character corresponding to the given character
+(the character bit value is bitwise-anded with 0x1f).
+\end{funcdesc}
+
+\begin{funcdesc}{alt}{c}
+Return the 8-bit character corresponding to the given ASCII character
+(the character bit value is bitwise-ored with 0x80).
+\end{funcdesc}
+
+The following function takes either a single-character string or
+integer value; it returns a string.
+
+\begin{funcdesc}{unctrl}{c}
+Return a string representation of the \ASCII{} character \var{c}.  If
+\var{c} is printable, this string is the character itself.  If the
+character is a control character (0x00-0x1f) the string consists of a
+caret (\character{\^}) followed by the corresponding uppercase letter.
+If the character is an \ASCII{} delete (0x7f) the string is
+\code{'\^{}?'}.  If the character has its meta bit (0x80) set, the meta
+bit is stripped, the preceding rules applied, and
+\character{!} prepended to the result.
+\end{funcdesc}
+
+\begin{datadesc}{controlnames}
+A 33-element string array that contains the \ASCII{} mnemonics for the
+thirty-two \ASCII{} control characters from 0 (NUL) to 0x1f (US), in
+order, plus the mnemonic \samp{SP} for the space character.
+\end{datadesc}

Added: vendor/Python/current/Doc/lib/libast.tex
===================================================================
--- vendor/Python/current/Doc/lib/libast.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libast.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,57 @@
+% XXX Label can't be _ast?
+% XXX Where should this section/chapter go?
+\chapter{Abstract Syntax Trees\label{ast}}
+
+\sectionauthor{Martin v. L\"owis}{martin at v.loewis.de}
+
+\versionadded{2.5}
+
+The \code{_ast} module helps Python applications to process
+trees of the Python abstract syntax grammar. The Python compiler
+currently provides read-only access to such trees, meaning that
+applications can only create a tree for a given piece of Python
+source code; generating byte code from a (potentially modified)
+tree is not supported. The abstract syntax itself might change with
+each Python release; this module helps to find out programmatically
+what the current grammar looks like.
+
+An abstract syntax tree can be generated by passing \code{_ast.PyCF_ONLY_AST}
+as a flag to the \function{compile} builtin function. The result will be a tree
+of objects whose classes all inherit from \code{_ast.AST}.
+
+The actual classes are derived from the \code{Parser/Python.asdl} file,
+which is reproduced below. There is one class defined for each left-hand
+side symbol in the abstract grammar (for example, \code{_ast.stmt} or \code{_ast.expr}).
+In addition, there is one class defined for each constructor on the
+right-hand side; these classes inherit from the classes for the left-hand
+side trees. For example, \code{_ast.BinOp} inherits from \code{_ast.expr}.
+For production rules with alternatives (aka "sums"), the left-hand side
+class is abstract: only instances of specific constructor nodes are ever
+created.
+
+Each concrete class has an attribute \code{_fields} which gives the
+names of all child nodes.
+
+Each instance of a concrete class has one attribute for each child node,
+of the type as defined in the grammar. For example, \code{_ast.BinOp}
+instances have an attribute \code{left} of type \code{_ast.expr}.  
+Instances of \code{_ast.expr} and \code{_ast.stmt} subclasses also
+have lineno and col_offset attributes.  The lineno is the line number
+of source text (1 indexed so the first line is line 1) and the
+col_offset is the utf8 byte offset of the first token that generated
+the node.  The utf8 offset is recorded because the parser uses utf8 
+internally.
+
+If these attributes are marked as optional in the grammar (using a
+question mark), the value might be \code{None}. If the attributes
+can have zero-or-more values (marked with an asterisk), the
+values are represented as Python lists.
+
+\section{Abstract Grammar}
+
+The module defines a string constant \code{__version__} which
+is the decimal subversion revision number of the file shown below.
+
+The abstract grammar is currently defined as follows:
+
+\verbatiminput{../../Parser/Python.asdl}

Added: vendor/Python/current/Doc/lib/libasynchat.tex
===================================================================
--- vendor/Python/current/Doc/lib/libasynchat.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libasynchat.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,254 @@
+\section{\module{asynchat} ---
+         Asynchronous socket command/response handler}
+
+\declaremodule{standard}{asynchat}
+\modulesynopsis{Support for asynchronous command/response protocols.}
+\moduleauthor{Sam Rushing}{rushing at nightmare.com}
+\sectionauthor{Steve Holden}{sholden at holdenweb.com}
+
+This module builds on the \refmodule{asyncore} infrastructure,
+simplifying asynchronous clients and servers and making it easier to
+handle protocols whose elements are terminated by arbitrary strings, or
+are of variable length. \refmodule{asynchat} defines the abstract class
+\class{async_chat} that you subclass, providing implementations of the
+\method{collect_incoming_data()} and \method{found_terminator()}
+methods. It uses the same asynchronous loop as \refmodule{asyncore}, and
+the two types of channel, \class{asyncore.dispatcher} and
+\class{asynchat.async_chat}, can freely be mixed in the channel map.
+Typically an \class{asyncore.dispatcher} server channel generates new
+\class{asynchat.async_chat} channel objects as it receives incoming
+connection requests. 
+
+\begin{classdesc}{async_chat}{}
+  This class is an abstract subclass of \class{asyncore.dispatcher}. To make
+  practical use of the code you must subclass \class{async_chat}, providing
+  meaningful \method{collect_incoming_data()} and \method{found_terminator()}
+  methods. The \class{asyncore.dispatcher} methods can be
+  used, although not all make sense in a message/response context.  
+
+  Like \class{asyncore.dispatcher}, \class{async_chat} defines a set of events
+  that are generated by an analysis of socket conditions after a
+  \cfunction{select()} call. Once the polling loop has been started the
+  \class{async_chat} object's methods are called by the event-processing
+  framework with no action on the part of the programmer.
+
+  Unlike \class{asyncore.dispatcher}, \class{async_chat} allows you to define
+  a first-in-first-out queue (fifo) of \emph{producers}. A producer need have
+  only one method, \method{more()}, which should return data to be transmitted
+  on the channel. The producer indicates exhaustion (\emph{i.e.} that it contains
+  no more data) by having its \method{more()} method return the empty string. At
+  this point the \class{async_chat} object removes the producer from the fifo
+  and starts using the next producer, if any. When the producer fifo is empty
+  the \method{handle_write()} method does nothing. You use the channel object's
+  \method{set_terminator()} method to describe how to recognize the end
+  of, or an important breakpoint in, an incoming transmission from the
+  remote endpoint.
+
+  To build a functioning \class{async_chat} subclass your 
+  input methods \method{collect_incoming_data()} and
+  \method{found_terminator()} must handle the data that the channel receives
+  asynchronously. The methods are described below.
+\end{classdesc}
+
+\begin{methoddesc}{close_when_done}{}
+  Pushes a \code{None} on to the producer fifo. When this producer is
+  popped off the fifo it causes the channel to be closed.
+\end{methoddesc}
+
+\begin{methoddesc}{collect_incoming_data}{data}
+  Called with \var{data} holding an arbitrary amount of received data.
+  The default method, which must be overridden, raises a \exception{NotImplementedError} exception.
+\end{methoddesc}
+
+\begin{methoddesc}{discard_buffers}{}
+  In emergencies this method will discard any data held in the input and/or
+  output buffers and the producer fifo.
+\end{methoddesc}
+
+\begin{methoddesc}{found_terminator}{}
+  Called when the incoming data stream  matches the termination condition
+  set by \method{set_terminator}. The default method, which must be overridden,
+  raises a \exception{NotImplementedError} exception. The buffered input data should
+  be available via an instance attribute.
+\end{methoddesc}
+
+\begin{methoddesc}{get_terminator}{}
+  Returns the current terminator for the channel.
+\end{methoddesc}
+
+\begin{methoddesc}{handle_close}{}
+  Called when the channel is closed. The default method silently closes
+  the channel's socket.
+\end{methoddesc}
+
+\begin{methoddesc}{handle_read}{}
+  Called when a read event fires on the channel's socket in the
+  asynchronous loop. The default method checks for the termination
+  condition established by \method{set_terminator()}, which can be either
+  the appearance of a particular string in the input stream or the receipt
+  of a particular number of characters. When the terminator is found,
+  \method{handle_read} calls the \method{found_terminator()} method after
+  calling \method{collect_incoming_data()} with any data preceding the
+  terminating condition.
+\end{methoddesc}
+
+\begin{methoddesc}{handle_write}{}
+  Called when the application may write data to the channel.  
+  The default method calls the \method{initiate_send()} method, which in turn
+  will call \method{refill_buffer()} to collect data from the producer
+  fifo associated with the channel.
+\end{methoddesc}
+
+\begin{methoddesc}{push}{data}
+  Creates a \class{simple_producer} object (\emph{see below}) containing the data and
+  pushes it on to the channel's \code{producer_fifo} to ensure its
+  transmission. This is all you need to do to have the channel write
+  the data out to the network, although it is possible to use your
+  own producers in more complex schemes to implement encryption and
+  chunking, for example.
+\end{methoddesc}
+
+\begin{methoddesc}{push_with_producer}{producer}
+  Takes a producer object and adds it to the producer fifo associated with
+  the channel. When all currently-pushed producers have been exhausted
+  the channel will consume this producer's data by calling its
+  \method{more()} method and send the data to the remote endpoint. 
+\end{methoddesc}
+
+\begin{methoddesc}{readable}{}
+  Should return \code{True} for the channel to be included in the set of
+  channels tested by the \cfunction{select()} loop for readability.
+\end{methoddesc}
+
+\begin{methoddesc}{refill_buffer}{}
+  Refills the output buffer by calling the \method{more()} method of the
+  producer at the head of the fifo. If it is exhausted then the
+  producer is popped off the fifo and the next producer is activated.
+  If the current producer is, or becomes, \code{None} then the channel
+  is closed.
+\end{methoddesc}
+
+\begin{methoddesc}{set_terminator}{term}
+  Sets the terminating condition to be recognised on the channel. \code{term}
+  may be any of three types of value, corresponding to three different ways
+  to handle incoming protocol data.
+
+  \begin{tableii}{l|l}{}{term}{Description}
+    \lineii{\emph{string}}{Will call \method{found_terminator()} when the
+                string is found in the input stream}
+    \lineii{\emph{integer}}{Will call \method{found_terminator()} when the
+                indicated number of characters have been received}
+    \lineii{\code{None}}{The channel continues to collect data forever}
+  \end{tableii}
+
+  Note that any data following the terminator will be available for reading by
+  the channel after \method{found_terminator()} is called.
+\end{methoddesc}
+
+\begin{methoddesc}{writable}{}
+  Should return \code{True} as long as items remain on the producer fifo,
+  or the channel is connected and the channel's output buffer is non-empty.
+\end{methoddesc}
+
+\subsection{asynchat - Auxiliary Classes and Functions}
+
+\begin{classdesc}{simple_producer}{data\optional{, buffer_size=512}}
+  A \class{simple_producer} takes a chunk of data and an optional buffer size.
+  Repeated calls to its \method{more()} method yield successive chunks of the
+  data no larger than \var{buffer_size}.
+\end{classdesc}
+
+\begin{methoddesc}{more}{}
+  Produces the next chunk of information from the producer, or returns the empty string.
+\end{methoddesc}
+
+\begin{classdesc}{fifo}{\optional{list=None}}
+  Each channel maintains a \class{fifo} holding data which has been pushed by the
+  application but not yet popped for writing to the channel.
+  A \class{fifo} is a list used to hold data and/or producers until they are required.
+  If the \var{list} argument is provided then it should contain producers or
+  data items to be written to the channel.
+\end{classdesc}
+
+\begin{methoddesc}{is_empty}{}
+  Returns \code{True} iff the fifo is empty.
+\end{methoddesc}
+
+\begin{methoddesc}{first}{}
+  Returns the least-recently \method{push()}ed item from the fifo.
+\end{methoddesc}
+
+\begin{methoddesc}{push}{data}
+  Adds the given data (which may be a string or a producer object) to the
+  producer fifo.
+\end{methoddesc}
+
+\begin{methoddesc}{pop}{}
+  If the fifo is not empty, returns \code{True, first()}, deleting the popped
+  item. Returns \code{False, None} for an empty fifo.
+\end{methoddesc}
+
+The \module{asynchat} module also defines one utility function, which may be
+of use in network and textual analysis operations.
+
+\begin{funcdesc}{find_prefix_at_end}{haystack, needle}
+  Returns \code{True} if string \var{haystack} ends with any non-empty
+  prefix of string \var{needle}.
+\end{funcdesc}
+
+\subsection{asynchat Example \label{asynchat-example}}
+
+The following partial example shows how HTTP requests can be read with
+\class{async_chat}. A web server might create an \class{http_request_handler} object for
+each incoming client connection. Notice that initially the
+channel terminator is set to match the blank line at the end of the HTTP
+headers, and a flag indicates that the headers are being read.
+
+Once the headers have been read, if the request is of type POST
+(indicating that further data are present in the input stream) then the
+\code{Content-Length:} header is used to set a numeric terminator to
+read the right amount of data from the channel.
+
+The \method{handle_request()} method is called once all relevant input
+has been marshalled, after setting the channel terminator to \code{None}
+to ensure that any extraneous data sent by the web client are ignored.
+
+\begin{verbatim}
+class http_request_handler(asynchat.async_chat):
+
+    def __init__(self, conn, addr, sessions, log):
+        asynchat.async_chat.__init__(self, conn=conn)
+        self.addr = addr
+        self.sessions = sessions
+        self.ibuffer = []
+        self.obuffer = ""
+        self.set_terminator("\r\n\r\n")
+        self.reading_headers = True
+        self.handling = False
+        self.cgi_data = None
+        self.log = log
+
+    def collect_incoming_data(self, data):
+        """Buffer the data"""
+        self.ibuffer.append(data)
+
+    def found_terminator(self):
+        if self.reading_headers:
+            self.reading_headers = False
+            self.parse_headers("".join(self.ibuffer))
+            self.ibuffer = []
+            if self.op.upper() == "POST":
+                clen = self.headers.getheader("content-length")
+                self.set_terminator(int(clen))
+            else:
+                self.handling = True
+                self.set_terminator(None)
+                self.handle_request()
+        elif not self.handling:
+            self.set_terminator(None) # browsers sometimes over-send
+            self.cgi_data = parse(self.headers, "".join(self.ibuffer))
+            self.handling = True
+            self.ibuffer = []
+            self.handle_request()
+\end{verbatim}
+

Added: vendor/Python/current/Doc/lib/libasyncore.tex
===================================================================
--- vendor/Python/current/Doc/lib/libasyncore.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libasyncore.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,260 @@
+\section{\module{asyncore} ---
+         Asynchronous socket handler}
+
+\declaremodule{builtin}{asyncore}
+\modulesynopsis{A base class for developing asynchronous socket 
+                handling services.}
+\moduleauthor{Sam Rushing}{rushing at nightmare.com}
+\sectionauthor{Christopher Petrilli}{petrilli at amber.org}
+\sectionauthor{Steve Holden}{sholden at holdenweb.com}
+% Heavily adapted from original documentation by Sam Rushing.
+
+This module provides the basic infrastructure for writing asynchronous 
+socket service clients and servers.
+
+There are only two ways to have a program on a single processor do 
+``more than one thing at a time.'' Multi-threaded programming is the 
+simplest and most popular way to do it, but there is another very 
+different technique, that lets you have nearly all the advantages of 
+multi-threading, without actually using multiple threads.  It's really 
+only practical if your program is largely I/O bound.  If your program 
+is processor bound, then pre-emptive scheduled threads are probably what 
+you really need. Network servers are rarely processor bound, however.
+
+If your operating system supports the \cfunction{select()} system call 
+in its I/O library (and nearly all do), then you can use it to juggle 
+multiple communication channels at once; doing other work while your 
+I/O is taking place in the ``background.''  Although this strategy can 
+seem strange and complex, especially at first, it is in many ways 
+easier to understand and control than multi-threaded programming.  
+The \module{asyncore} module solves many of the difficult problems for 
+you, making the task of building sophisticated high-performance 
+network servers and clients a snap. For ``conversational'' applications
+and protocols the companion  \refmodule{asynchat} module is invaluable.
+
+The basic idea behind both modules is to create one or more network
+\emph{channels}, instances of class \class{asyncore.dispatcher} and
+\class{asynchat.async_chat}. Creating the channels adds them to a global
+map, used by the \function{loop()} function if you do not provide it
+with your own \var{map}.
+
+Once the initial channel(s) is(are) created, calling the \function{loop()}
+function activates channel service, which continues until the last
+channel (including any that have been added to the map during asynchronous
+service) is closed.
+
+\begin{funcdesc}{loop}{\optional{timeout\optional{, use_poll\optional{,
+                       map\optional{,count}}}}}
+  Enter a polling loop that terminates after count passes or all open
+  channels have been closed.  All arguments are optional.  The \var(count)
+  parameter defaults to None, resulting in the loop terminating only
+  when all channels have been closed.  The \var{timeout} argument sets the
+  timeout parameter for the appropriate \function{select()} or
+  \function{poll()} call, measured in seconds; the default is 30 seconds.
+  The \var{use_poll} parameter, if true, indicates that \function{poll()}
+  should be used in preference to \function{select()} (the default is
+  \code{False}).  
+
+  The \var{map} parameter is a dictionary whose items are
+  the channels to watch.  As channels are closed they are deleted from their
+  map.  If \var{map} is omitted, a global map is used.
+  Channels (instances of \class{asyncore.dispatcher}, \class{asynchat.async_chat}
+  and subclasses thereof) can freely be mixed in the map.
+\end{funcdesc}
+
+\begin{classdesc}{dispatcher}{}
+  The \class{dispatcher} class is a thin wrapper around a low-level socket object.
+  To make it more useful, it has a few methods for event-handling  which are called
+  from the asynchronous loop.  
+  Otherwise, it can be treated as a normal non-blocking socket object.
+
+  Two class attributes can be modified, to improve performance,
+  or possibly even to conserve memory.
+
+  \begin{datadesc}{ac_in_buffer_size}
+  The asynchronous input buffer size (default \code{4096}).
+  \end{datadesc}
+
+  \begin{datadesc}{ac_out_buffer_size}
+  The asynchronous output buffer size (default \code{4096}).
+  \end{datadesc}
+
+  The firing of low-level events at certain times or in certain connection
+  states tells the asynchronous loop that certain higher-level events have
+  taken place. For example, if we have asked for a socket to connect to
+  another host, we know that the connection has been made when the socket
+  becomes writable for the first time (at this point you know that you may
+  write to it with the expectation of success). The implied higher-level
+  events are:
+
+  \begin{tableii}{l|l}{code}{Event}{Description}
+    \lineii{handle_connect()}{Implied by the first write event}
+    \lineii{handle_close()}{Implied by a read event with no data available}
+    \lineii{handle_accept()}{Implied by a read event on a listening socket}
+  \end{tableii}
+
+  During asynchronous processing, each mapped channel's \method{readable()}
+  and \method{writable()} methods are used to determine whether the channel's
+  socket should be added to the list of channels \cfunction{select()}ed or
+  \cfunction{poll()}ed for read and write events.
+
+\end{classdesc}
+
+Thus, the set of channel events is larger than the basic socket events.
+The full set of methods that can be overridden in your subclass follows:
+
+\begin{methoddesc}{handle_read}{}
+  Called when the asynchronous loop detects that a \method{read()}
+  call on the channel's socket will succeed.
+\end{methoddesc}
+
+\begin{methoddesc}{handle_write}{}
+  Called when the asynchronous loop detects that a writable socket
+  can be written.  
+  Often this method will implement the necessary buffering for 
+  performance.  For example:
+
+\begin{verbatim}
+def handle_write(self):
+    sent = self.send(self.buffer)
+    self.buffer = self.buffer[sent:]
+\end{verbatim}
+\end{methoddesc}
+
+\begin{methoddesc}{handle_expt}{}
+  Called when there is out of band (OOB) data for a socket 
+  connection.  This will almost never happen, as OOB is 
+  tenuously supported and rarely used.
+\end{methoddesc}
+
+\begin{methoddesc}{handle_connect}{}
+  Called when the active opener's socket actually makes a connection.
+  Might send a ``welcome'' banner, or initiate a protocol
+  negotiation with the remote endpoint, for example.
+\end{methoddesc}
+
+\begin{methoddesc}{handle_close}{}
+  Called when the socket is closed.
+\end{methoddesc}
+
+\begin{methoddesc}{handle_error}{}
+  Called when an exception is raised and not otherwise handled.  The default
+  version prints a condensed traceback.
+\end{methoddesc}
+
+\begin{methoddesc}{handle_accept}{}
+  Called on listening channels (passive openers) when a  
+  connection can be established with a new remote endpoint that
+  has issued a \method{connect()} call for the local endpoint.
+\end{methoddesc}
+
+\begin{methoddesc}{readable}{}
+  Called each time around the asynchronous loop to determine whether a
+  channel's socket should be added to the list on which read events can
+  occur.  The default method simply returns \code{True}, 
+  indicating that by default, all channels will be interested in
+  read events.
+\end{methoddesc}
+
+\begin{methoddesc}{writable}{}
+  Called each time around the asynchronous loop to determine whether a
+  channel's socket should be added to the list on which write events can
+  occur.  The default method simply returns \code{True}, 
+  indicating that by default, all channels will be interested in
+  write events.
+\end{methoddesc}
+
+In addition, each channel delegates or extends many of the socket methods.
+Most of these are nearly identical to their socket partners.
+
+\begin{methoddesc}{create_socket}{family, type}
+  This is identical to the creation of a normal socket, and 
+  will use the same options for creation.  Refer to the
+  \refmodule{socket} documentation for information on creating
+  sockets.
+\end{methoddesc}
+
+\begin{methoddesc}{connect}{address}
+  As with the normal socket object, \var{address} is a 
+  tuple with the first element the host to connect to, and the 
+  second the port number.
+\end{methoddesc}
+
+\begin{methoddesc}{send}{data}
+  Send \var{data} to the remote end-point of the socket.
+\end{methoddesc}
+
+\begin{methoddesc}{recv}{buffer_size}
+  Read at most \var{buffer_size} bytes from the socket's remote end-point.
+  An empty string implies that the channel has been closed from the other
+  end.
+\end{methoddesc}
+
+\begin{methoddesc}{listen}{backlog}
+  Listen for connections made to the socket.  The \var{backlog}
+  argument specifies the maximum number of queued connections
+  and should be at least 1; the maximum value is
+  system-dependent (usually 5).
+\end{methoddesc}
+
+\begin{methoddesc}{bind}{address}
+  Bind the socket to \var{address}.  The socket must not already be
+  bound.  (The format of \var{address} depends on the address family
+  --- see above.)  To mark the socket as re-usable (setting the
+  \constant{SO_REUSEADDR} option), call the \class{dispatcher}
+  object's \method{set_reuse_addr()} method.
+\end{methoddesc}
+
+\begin{methoddesc}{accept}{}
+  Accept a connection.  The socket must be bound to an address
+  and listening for connections.  The return value is a pair
+  \code{(\var{conn}, \var{address})} where \var{conn} is a
+  \emph{new} socket object usable to send and receive data on
+  the connection, and \var{address} is the address bound to the
+  socket on the other end of the connection.
+\end{methoddesc}
+
+\begin{methoddesc}{close}{}
+  Close the socket.  All future operations on the socket object
+  will fail.  The remote end-point will receive no more data (after
+  queued data is flushed).  Sockets are automatically closed
+  when they are garbage-collected.
+\end{methoddesc}
+
+
+\subsection{asyncore Example basic HTTP client \label{asyncore-example}}
+
+Here is a very basic HTTP client that uses the \class{dispatcher}
+class to implement its socket handling:
+
+\begin{verbatim}
+import asyncore, socket
+
+class http_client(asyncore.dispatcher):
+
+    def __init__(self, host, path):
+        asyncore.dispatcher.__init__(self)
+        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
+        self.connect( (host, 80) )
+        self.buffer = 'GET %s HTTP/1.0\r\n\r\n' % path
+
+    def handle_connect(self):
+        pass
+
+    def handle_close(self):
+        self.close()
+
+    def handle_read(self):
+        print self.recv(8192)
+
+    def writable(self):
+        return (len(self.buffer) > 0)
+
+    def handle_write(self):
+        sent = self.send(self.buffer)
+        self.buffer = self.buffer[sent:]
+
+c = http_client('www.python.org', '/')
+
+asyncore.loop()
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/libatexit.tex
===================================================================
--- vendor/Python/current/Doc/lib/libatexit.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libatexit.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,94 @@
+\section{\module{atexit} ---
+         Exit handlers}
+
+\declaremodule{standard}{atexit}
+\moduleauthor{Skip Montanaro}{skip at mojam.com}
+\sectionauthor{Skip Montanaro}{skip at mojam.com}
+\modulesynopsis{Register and execute cleanup functions.}
+
+\versionadded{2.0}
+
+The \module{atexit} module defines a single function to register
+cleanup functions.  Functions thus registered are automatically
+executed upon normal interpreter termination.
+
+Note: the functions registered via this module are not called when the program is killed by a
+signal, when a Python fatal internal error is detected, or when
+\function{os._exit()} is called.
+
+This is an alternate interface to the functionality provided by the
+\code{sys.exitfunc} variable.
+\withsubitem{(in sys)}{\ttindex{exitfunc}}
+
+Note: This module is unlikely to work correctly when used with other code
+that sets \code{sys.exitfunc}.  In particular, other core Python modules are
+free to use \module{atexit} without the programmer's knowledge.  Authors who
+use \code{sys.exitfunc} should convert their code to use
+\module{atexit} instead.  The simplest way to convert code that sets
+\code{sys.exitfunc} is to import \module{atexit} and register the function
+that had been bound to \code{sys.exitfunc}.
+
+\begin{funcdesc}{register}{func\optional{, *args\optional{, **kargs}}}
+Register \var{func} as a function to be executed at termination.  Any
+optional arguments that are to be passed to \var{func} must be passed
+as arguments to \function{register()}.
+
+At normal program termination (for instance, if
+\function{sys.exit()} is called or the main module's execution
+completes), all functions registered are called in last in, first out
+order.  The assumption is that lower level modules will normally be
+imported before higher level modules and thus must be cleaned up
+later.
+
+If an exception is raised during execution of the exit handlers, a
+traceback is printed (unless \exception{SystemExit} is raised) and the
+exception information is saved.  After all exit handlers have had a
+chance to run the last exception to be raised is re-raised.
+\end{funcdesc}
+
+
+\begin{seealso}
+  \seemodule{readline}{Useful example of \module{atexit} to read and
+                       write \refmodule{readline} history files.}
+\end{seealso}
+
+
+\subsection{\module{atexit} Example \label{atexit-example}}
+
+The following simple example demonstrates how a module can initialize
+a counter from a file when it is imported and save the counter's
+updated value automatically when the program terminates without
+relying on the application making an explicit call into this module at
+termination.
+
+\begin{verbatim}
+try:
+    _count = int(open("/tmp/counter").read())
+except IOError:
+    _count = 0
+
+def incrcounter(n):
+    global _count
+    _count = _count + n
+
+def savecounter():
+    open("/tmp/counter", "w").write("%d" % _count)
+
+import atexit
+atexit.register(savecounter)
+\end{verbatim}
+
+Positional and keyword arguments may also be passed to
+\function{register()} to be passed along to the registered function
+when it is called:
+
+\begin{verbatim}
+def goodbye(name, adjective):
+    print 'Goodbye, %s, it was %s to meet you.' % (name, adjective)
+
+import atexit
+atexit.register(goodbye, 'Donny', 'nice')
+
+# or:
+atexit.register(goodbye, adjective='nice', name='Donny')
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/libaudioop.tex
===================================================================
--- vendor/Python/current/Doc/lib/libaudioop.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libaudioop.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,259 @@
+\section{\module{audioop} ---
+         Manipulate raw audio data}
+
+\declaremodule{builtin}{audioop}
+\modulesynopsis{Manipulate raw audio data.}
+
+
+The \module{audioop} module contains some useful operations on sound
+fragments.  It operates on sound fragments consisting of signed
+integer samples 8, 16 or 32 bits wide, stored in Python strings.  This
+is the same format as used by the \refmodule{al} and \refmodule{sunaudiodev}
+modules.  All scalar items are integers, unless specified otherwise.
+
+% This para is mostly here to provide an excuse for the index entries...
+This module provides support for a-LAW, u-LAW and Intel/DVI ADPCM encodings.
+\index{Intel/DVI ADPCM}
+\index{ADPCM, Intel/DVI}
+\index{a-LAW}
+\index{u-LAW}
+
+A few of the more complicated operations only take 16-bit samples,
+otherwise the sample size (in bytes) is always a parameter of the
+operation.
+
+The module defines the following variables and functions:
+
+\begin{excdesc}{error}
+This exception is raised on all errors, such as unknown number of bytes
+per sample, etc.
+\end{excdesc}
+
+\begin{funcdesc}{add}{fragment1, fragment2, width}
+Return a fragment which is the addition of the two samples passed as
+parameters.  \var{width} is the sample width in bytes, either
+\code{1}, \code{2} or \code{4}.  Both fragments should have the same
+length.
+\end{funcdesc}
+
+\begin{funcdesc}{adpcm2lin}{adpcmfragment, width, state}
+Decode an Intel/DVI ADPCM coded fragment to a linear fragment.  See
+the description of \function{lin2adpcm()} for details on ADPCM coding.
+Return a tuple \code{(\var{sample}, \var{newstate})} where the sample
+has the width specified in \var{width}.
+\end{funcdesc}
+
+\begin{funcdesc}{alaw2lin}{fragment, width}
+Convert sound fragments in a-LAW encoding to linearly encoded sound
+fragments.  a-LAW encoding always uses 8 bits samples, so \var{width}
+refers only to the sample width of the output fragment here.
+\versionadded{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{avg}{fragment, width}
+Return the average over all samples in the fragment.
+\end{funcdesc}
+
+\begin{funcdesc}{avgpp}{fragment, width}
+Return the average peak-peak value over all samples in the fragment.
+No filtering is done, so the usefulness of this routine is
+questionable.
+\end{funcdesc}
+
+\begin{funcdesc}{bias}{fragment, width, bias}
+Return a fragment that is the original fragment with a bias added to
+each sample.
+\end{funcdesc}
+
+\begin{funcdesc}{cross}{fragment, width}
+Return the number of zero crossings in the fragment passed as an
+argument.
+\end{funcdesc}
+
+\begin{funcdesc}{findfactor}{fragment, reference}
+Return a factor \var{F} such that
+\code{rms(add(\var{fragment}, mul(\var{reference}, -\var{F})))} is
+minimal, i.e., return the factor with which you should multiply
+\var{reference} to make it match as well as possible to
+\var{fragment}.  The fragments should both contain 2-byte samples.
+
+The time taken by this routine is proportional to
+\code{len(\var{fragment})}.
+\end{funcdesc}
+
+\begin{funcdesc}{findfit}{fragment, reference}
+Try to match \var{reference} as well as possible to a portion of
+\var{fragment} (which should be the longer fragment).  This is
+(conceptually) done by taking slices out of \var{fragment}, using
+\function{findfactor()} to compute the best match, and minimizing the
+result.  The fragments should both contain 2-byte samples.  Return a
+tuple \code{(\var{offset}, \var{factor})} where \var{offset} is the
+(integer) offset into \var{fragment} where the optimal match started
+and \var{factor} is the (floating-point) factor as per
+\function{findfactor()}.
+\end{funcdesc}
+
+\begin{funcdesc}{findmax}{fragment, length}
+Search \var{fragment} for a slice of length \var{length} samples (not
+bytes!)\ with maximum energy, i.e., return \var{i} for which
+\code{rms(fragment[i*2:(i+length)*2])} is maximal.  The fragments
+should both contain 2-byte samples.
+
+The routine takes time proportional to \code{len(\var{fragment})}.
+\end{funcdesc}
+
+\begin{funcdesc}{getsample}{fragment, width, index}
+Return the value of sample \var{index} from the fragment.
+\end{funcdesc}
+
+\begin{funcdesc}{lin2adpcm}{fragment, width, state}
+Convert samples to 4 bit Intel/DVI ADPCM encoding.  ADPCM coding is an
+adaptive coding scheme, whereby each 4 bit number is the difference
+between one sample and the next, divided by a (varying) step.  The
+Intel/DVI ADPCM algorithm has been selected for use by the IMA, so it
+may well become a standard.
+
+\var{state} is a tuple containing the state of the coder.  The coder
+returns a tuple \code{(\var{adpcmfrag}, \var{newstate})}, and the
+\var{newstate} should be passed to the next call of
+\function{lin2adpcm()}.  In the initial call, \code{None} can be
+passed as the state.  \var{adpcmfrag} is the ADPCM coded fragment
+packed 2 4-bit values per byte.
+\end{funcdesc}
+
+\begin{funcdesc}{lin2alaw}{fragment, width}
+Convert samples in the audio fragment to a-LAW encoding and return
+this as a Python string.  a-LAW is an audio encoding format whereby
+you get a dynamic range of about 13 bits using only 8 bit samples.  It
+is used by the Sun audio hardware, among others.
+\versionadded{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{lin2lin}{fragment, width, newwidth}
+Convert samples between 1-, 2- and 4-byte formats.
+\end{funcdesc}
+
+\begin{funcdesc}{lin2ulaw}{fragment, width}
+Convert samples in the audio fragment to u-LAW encoding and return
+this as a Python string.  u-LAW is an audio encoding format whereby
+you get a dynamic range of about 14 bits using only 8 bit samples.  It
+is used by the Sun audio hardware, among others.
+\end{funcdesc}
+
+\begin{funcdesc}{minmax}{fragment, width}
+Return a tuple consisting of the minimum and maximum values of all
+samples in the sound fragment.
+\end{funcdesc}
+
+\begin{funcdesc}{max}{fragment, width}
+Return the maximum of the \emph{absolute value} of all samples in a
+fragment.
+\end{funcdesc}
+
+\begin{funcdesc}{maxpp}{fragment, width}
+Return the maximum peak-peak value in the sound fragment.
+\end{funcdesc}
+
+\begin{funcdesc}{mul}{fragment, width, factor}
+Return a fragment that has all samples in the original fragment
+multiplied by the floating-point value \var{factor}.  Overflow is
+silently ignored.
+\end{funcdesc}
+
+\begin{funcdesc}{ratecv}{fragment, width, nchannels, inrate, outrate,
+                         state\optional{, weightA\optional{, weightB}}}
+Convert the frame rate of the input fragment.
+
+\var{state} is a tuple containing the state of the converter.  The
+converter returns a tuple \code{(\var{newfragment}, \var{newstate})},
+and \var{newstate} should be passed to the next call of
+\function{ratecv()}.  The initial call should pass \code{None}
+as the state.
+
+The \var{weightA} and \var{weightB} arguments are parameters for a
+simple digital filter and default to \code{1} and \code{0} respectively.
+\end{funcdesc}
+
+\begin{funcdesc}{reverse}{fragment, width}
+Reverse the samples in a fragment and returns the modified fragment.
+\end{funcdesc}
+
+\begin{funcdesc}{rms}{fragment, width}
+Return the root-mean-square of the fragment, i.e.
+\begin{displaymath}
+\catcode`_=8
+\sqrt{\frac{\sum{{S_{i}}^{2}}}{n}}
+\end{displaymath}
+This is a measure of the power in an audio signal.
+\end{funcdesc}
+
+\begin{funcdesc}{tomono}{fragment, width, lfactor, rfactor} 
+Convert a stereo fragment to a mono fragment.  The left channel is
+multiplied by \var{lfactor} and the right channel by \var{rfactor}
+before adding the two channels to give a mono signal.
+\end{funcdesc}
+
+\begin{funcdesc}{tostereo}{fragment, width, lfactor, rfactor}
+Generate a stereo fragment from a mono fragment.  Each pair of samples
+in the stereo fragment are computed from the mono sample, whereby left
+channel samples are multiplied by \var{lfactor} and right channel
+samples by \var{rfactor}.
+\end{funcdesc}
+
+\begin{funcdesc}{ulaw2lin}{fragment, width}
+Convert sound fragments in u-LAW encoding to linearly encoded sound
+fragments.  u-LAW encoding always uses 8 bits samples, so \var{width}
+refers only to the sample width of the output fragment here.
+\end{funcdesc}
+
+Note that operations such as \function{mul()} or \function{max()} make
+no distinction between mono and stereo fragments, i.e.\ all samples
+are treated equal.  If this is a problem the stereo fragment should be
+split into two mono fragments first and recombined later.  Here is an
+example of how to do that:
+
+\begin{verbatim}
+def mul_stereo(sample, width, lfactor, rfactor):
+    lsample = audioop.tomono(sample, width, 1, 0)
+    rsample = audioop.tomono(sample, width, 0, 1)
+    lsample = audioop.mul(sample, width, lfactor)
+    rsample = audioop.mul(sample, width, rfactor)
+    lsample = audioop.tostereo(lsample, width, 1, 0)
+    rsample = audioop.tostereo(rsample, width, 0, 1)
+    return audioop.add(lsample, rsample, width)
+\end{verbatim}
+
+If you use the ADPCM coder to build network packets and you want your
+protocol to be stateless (i.e.\ to be able to tolerate packet loss)
+you should not only transmit the data but also the state.  Note that
+you should send the \var{initial} state (the one you passed to
+\function{lin2adpcm()}) along to the decoder, not the final state (as
+returned by the coder).  If you want to use \function{struct.struct()}
+to store the state in binary you can code the first element (the
+predicted value) in 16 bits and the second (the delta index) in 8.
+
+The ADPCM coders have never been tried against other ADPCM coders,
+only against themselves.  It could well be that I misinterpreted the
+standards in which case they will not be interoperable with the
+respective standards.
+
+The \function{find*()} routines might look a bit funny at first sight.
+They are primarily meant to do echo cancellation.  A reasonably
+fast way to do this is to pick the most energetic piece of the output
+sample, locate that in the input sample and subtract the whole output
+sample from the input sample:
+
+\begin{verbatim}
+def echocancel(outputdata, inputdata):
+    pos = audioop.findmax(outputdata, 800)    # one tenth second
+    out_test = outputdata[pos*2:]
+    in_test = inputdata[pos*2:]
+    ipos, factor = audioop.findfit(in_test, out_test)
+    # Optional (for better cancellation):
+    # factor = audioop.findfactor(in_test[ipos*2:ipos*2+len(out_test)], 
+    #              out_test)
+    prefill = '\0'*(pos+ipos)*2
+    postfill = '\0'*(len(inputdata)-len(prefill)-len(outputdata))
+    outputdata = prefill + audioop.mul(outputdata,2,-factor) + postfill
+    return audioop.add(inputdata, outputdata, 2)
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/libbase64.tex
===================================================================
--- vendor/Python/current/Doc/lib/libbase64.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libbase64.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,169 @@
+\section{\module{base64} ---
+	 RFC 3548: Base16, Base32, Base64 Data Encodings}
+
+\declaremodule{standard}{base64}
+\modulesynopsis{RFC 3548: Base16, Base32, Base64 Data Encodings}
+
+
+\indexii{base64}{encoding}
+\index{MIME!base64 encoding}
+
+This module provides data encoding and decoding as specified in
+\rfc{3548}.  This standard defines the Base16, Base32, and Base64
+algorithms for encoding and decoding arbitrary binary strings into
+text strings that can be safely sent by email, used as parts of URLs,
+or included as part of an HTTP POST request.  The encoding algorithm is
+not the same as the \program{uuencode} program.
+
+There are two interfaces provided by this module.  The modern
+interface supports encoding and decoding string objects using all
+three alphabets.  The legacy interface provides for encoding and
+decoding to and from file-like objects as well as strings, but only
+using the Base64 standard alphabet.
+
+The modern interface, which was introduced in Python 2.4, provides:
+
+\begin{funcdesc}{b64encode}{s\optional{, altchars}}
+Encode a string use Base64.
+
+\var{s} is the string to encode.  Optional \var{altchars} must be a
+string of at least length 2 (additional characters are ignored) which
+specifies an alternative alphabet for the \code{+} and \code{/}
+characters.  This allows an application to e.g. generate URL or
+filesystem safe Base64 strings.  The default is \code{None}, for which
+the standard Base64 alphabet is used.
+
+The encoded string is returned.
+\end{funcdesc}
+
+\begin{funcdesc}{b64decode}{s\optional{, altchars}}
+Decode a Base64 encoded string.
+
+\var{s} is the string to decode.  Optional \var{altchars} must be a
+string of at least length 2 (additional characters are ignored) which
+specifies the alternative alphabet used instead of the \code{+} and
+\code{/} characters.
+
+The decoded string is returned.  A \exception{TypeError} is raised if
+\var{s} were incorrectly padded or if there are non-alphabet
+characters present in the string.
+\end{funcdesc}
+
+\begin{funcdesc}{standard_b64encode}{s}
+Encode string \var{s} using the standard Base64 alphabet.
+\end{funcdesc}
+
+\begin{funcdesc}{standard_b64decode}{s}
+Decode string \var{s} using the standard Base64 alphabet.
+\end{funcdesc}
+
+\begin{funcdesc}{urlsafe_b64encode}{s}
+Encode string \var{s} using a URL-safe alphabet, which substitutes
+\code{-} instead of \code{+} and \code{_} instead of \code{/} in the
+standard Base64 alphabet.
+\end{funcdesc}
+
+\begin{funcdesc}{urlsafe_b64decode}{s}
+Decode string \var{s} using a URL-safe alphabet, which substitutes
+\code{-} instead of \code{+} and \code{_} instead of \code{/} in the
+standard Base64 alphabet.
+\end{funcdesc}
+
+\begin{funcdesc}{b32encode}{s}
+Encode a string using Base32.  \var{s} is the string to encode.  The
+encoded string is returned.
+\end{funcdesc}
+
+\begin{funcdesc}{b32decode}{s\optional{, casefold\optional{, map01}}}
+Decode a Base32 encoded string.
+
+\var{s} is the string to decode.  Optional \var{casefold} is a flag
+specifying whether a lowercase alphabet is acceptable as input.  For
+security purposes, the default is \code{False}.
+
+\rfc{3548} allows for optional mapping of the digit 0 (zero) to the
+letter O (oh), and for optional mapping of the digit 1 (one) to either
+the letter I (eye) or letter L (el).  The optional argument
+\var{map01} when not \code{None}, specifies which letter the digit 1 should
+be mapped to (when map01 is not \var{None}, the digit 0 is always
+mapped to the letter O).  For security purposes the default is
+\code{None}, so that 0 and 1 are not allowed in the input.
+
+The decoded string is returned.  A \exception{TypeError} is raised if
+\var{s} were incorrectly padded or if there are non-alphabet characters
+present in the string.
+\end{funcdesc}
+
+\begin{funcdesc}{b16encode}{s}
+Encode a string using Base16.
+
+\var{s} is the string to encode.  The encoded string is returned.
+\end{funcdesc}
+
+\begin{funcdesc}{b16decode}{s\optional{, casefold}}
+Decode a Base16 encoded string.
+
+\var{s} is the string to decode.  Optional \var{casefold} is a flag
+specifying whether a lowercase alphabet is acceptable as input.  For
+security purposes, the default is \code{False}.
+
+The decoded string is returned.  A \exception{TypeError} is raised if
+\var{s} were incorrectly padded or if there are non-alphabet
+characters present in the string.
+\end{funcdesc}
+
+The legacy interface:
+
+\begin{funcdesc}{decode}{input, output}
+Decode the contents of the \var{input} file and write the resulting
+binary data to the \var{output} file.
+\var{input} and \var{output} must either be file objects or objects that
+mimic the file object interface. \var{input} will be read until
+\code{\var{input}.read()} returns an empty string.
+\end{funcdesc}
+
+\begin{funcdesc}{decodestring}{s}
+Decode the string \var{s}, which must contain one or more lines of
+base64 encoded data, and return a string containing the resulting
+binary data.
+\end{funcdesc}
+
+\begin{funcdesc}{encode}{input, output}
+Encode the contents of the \var{input} file and write the resulting
+base64 encoded data to the \var{output} file.
+\var{input} and \var{output} must either be file objects or objects that
+mimic the file object interface. \var{input} will be read until
+\code{\var{input}.read()} returns an empty string.  \function{encode()}
+returns the encoded data plus a trailing newline character
+(\code{'\e n'}).
+\end{funcdesc}
+
+\begin{funcdesc}{encodestring}{s}
+Encode the string \var{s}, which can contain arbitrary binary data,
+and return a string containing one or more lines of
+base64-encoded data.  \function{encodestring()} returns a
+string containing one or more lines of base64-encoded data
+always including an extra trailing newline (\code{'\e n'}).
+\end{funcdesc}
+
+An example usage of the module:
+
+\begin{verbatim}
+>>> import base64
+>>> encoded = base64.b64encode('data to be encoded')
+>>> encoded
+'ZGF0YSB0byBiZSBlbmNvZGVk'
+>>> data = base64.b64decode(encoded)
+>>> data
+'data to be encoded'
+\end{verbatim}
+
+\begin{seealso}
+  \seemodule{binascii}{Support module containing \ASCII-to-binary
+                       and binary-to-\ASCII{} conversions.}
+  \seerfc{1521}{MIME (Multipurpose Internet Mail Extensions) Part One:
+          Mechanisms for Specifying and Describing the Format of
+          Internet Message Bodies}{Section 5.2, ``Base64
+          Content-Transfer-Encoding,'' provides the definition of the
+          base64 encoding.}
+\end{seealso}

Added: vendor/Python/current/Doc/lib/libbasehttp.tex
===================================================================
--- vendor/Python/current/Doc/lib/libbasehttp.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libbasehttp.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,245 @@
+\section{\module{BaseHTTPServer} ---
+         Basic HTTP server}
+
+\declaremodule{standard}{BaseHTTPServer}
+\modulesynopsis{Basic HTTP server (base class for
+                \class{SimpleHTTPServer} and \class{CGIHTTPServer}).}
+
+
+\indexii{WWW}{server}
+\indexii{HTTP}{protocol}
+\index{URL}
+\index{httpd}
+
+This module defines two classes for implementing HTTP servers
+(Web servers). Usually, this module isn't used directly, but is used
+as a basis for building functioning Web servers. See the
+\refmodule{SimpleHTTPServer}\refstmodindex{SimpleHTTPServer} and
+\refmodule{CGIHTTPServer}\refstmodindex{CGIHTTPServer} modules.
+
+The first class, \class{HTTPServer}, is a
+\class{SocketServer.TCPServer} subclass.  It creates and listens at the
+HTTP socket, dispatching the requests to a handler.  Code to create and
+run the server looks like this:
+
+\begin{verbatim}
+def run(server_class=BaseHTTPServer.HTTPServer,
+        handler_class=BaseHTTPServer.BaseHTTPRequestHandler):
+    server_address = ('', 8000)
+    httpd = server_class(server_address, handler_class)
+    httpd.serve_forever()
+\end{verbatim}
+
+\begin{classdesc}{HTTPServer}{server_address, RequestHandlerClass}
+This class builds on the \class{TCPServer} class by
+storing the server address as instance
+variables named \member{server_name} and \member{server_port}. The
+server is accessible by the handler, typically through the handler's
+\member{server} instance variable.
+\end{classdesc}
+
+\begin{classdesc}{BaseHTTPRequestHandler}{request, client_address, server}
+This class is used
+to handle the HTTP requests that arrive at the server. By itself,
+it cannot respond to any actual HTTP requests; it must be subclassed
+to handle each request method (e.g. GET or POST).
+\class{BaseHTTPRequestHandler} provides a number of class and instance
+variables, and methods for use by subclasses.
+
+The handler will parse the request and the headers, then call a
+method specific to the request type. The method name is constructed
+from the request. For example, for the request method \samp{SPAM}, the
+\method{do_SPAM()} method will be called with no arguments. All of
+the relevant information is stored in instance variables of the
+handler.  Subclasses should not need to override or extend the
+\method{__init__()} method.
+\end{classdesc}
+
+
+\class{BaseHTTPRequestHandler} has the following instance variables:
+
+\begin{memberdesc}{client_address}
+Contains a tuple of the form \code{(\var{host}, \var{port})} referring
+to the client's address.
+\end{memberdesc}
+
+\begin{memberdesc}{command}
+Contains the command (request type). For example, \code{'GET'}.
+\end{memberdesc}
+
+\begin{memberdesc}{path}
+Contains the request path.
+\end{memberdesc}
+
+\begin{memberdesc}{request_version}
+Contains the version string from the request. For example,
+\code{'HTTP/1.0'}.
+\end{memberdesc}
+
+\begin{memberdesc}{headers}
+Holds an instance of the class specified by the \member{MessageClass}
+class variable. This instance parses and manages the headers in
+the HTTP request.
+\end{memberdesc}
+
+\begin{memberdesc}{rfile}
+Contains an input stream, positioned at the start of the optional
+input data.
+\end{memberdesc}
+
+\begin{memberdesc}{wfile}
+Contains the output stream for writing a response back to the client.
+Proper adherence to the HTTP protocol must be used when writing
+to this stream.
+\end{memberdesc}
+
+
+\class{BaseHTTPRequestHandler} has the following class variables:
+
+\begin{memberdesc}{server_version}
+Specifies the server software version.  You may want to override
+this.
+The format is multiple whitespace-separated strings,
+where each string is of the form name[/version].
+For example, \code{'BaseHTTP/0.2'}.
+\end{memberdesc}
+
+\begin{memberdesc}{sys_version}
+Contains the Python system version, in a form usable by the
+\member{version_string} method and the \member{server_version} class
+variable. For example, \code{'Python/1.4'}.
+\end{memberdesc}
+
+\begin{memberdesc}{error_message_format}
+Specifies a format string for building an error response to the
+client. It uses parenthesized, keyed format specifiers, so the
+format operand must be a dictionary. The \var{code} key should
+be an integer, specifying the numeric HTTP error code value.
+\var{message} should be a string containing a (detailed) error
+message of what occurred, and \var{explain} should be an
+explanation of the error code number. Default \var{message}
+and \var{explain} values can found in the \var{responses}
+class variable.
+\end{memberdesc}
+
+\begin{memberdesc}{protocol_version}
+This specifies the HTTP protocol version used in responses.  If set
+to \code{'HTTP/1.1'}, the server will permit HTTP persistent
+connections; however, your server \emph{must} then include an
+accurate \code{Content-Length} header (using \method{send_header()})
+in all of its responses to clients.  For backwards compatibility,
+the setting defaults to \code{'HTTP/1.0'}.
+\end{memberdesc}
+
+\begin{memberdesc}{MessageClass}
+Specifies a \class{rfc822.Message}-like class to parse HTTP
+headers. Typically, this is not overridden, and it defaults to
+\class{mimetools.Message}.
+\withsubitem{(in module mimetools)}{\ttindex{Message}}
+\end{memberdesc}
+
+\begin{memberdesc}{responses}
+This variable contains a mapping of error code integers to two-element
+tuples containing a short and long message. For example,
+\code{\{\var{code}: (\var{shortmessage}, \var{longmessage})\}}. The
+\var{shortmessage} is usually used as the \var{message} key in an
+error response, and \var{longmessage} as the \var{explain} key
+(see the \member{error_message_format} class variable).
+\end{memberdesc}
+
+
+A \class{BaseHTTPRequestHandler} instance has the following methods:
+
+\begin{methoddesc}{handle}{}
+Calls \method{handle_one_request()} once (or, if persistent connections
+are enabled, multiple times) to handle incoming HTTP requests.
+You should never need to override it; instead, implement appropriate
+\method{do_*()} methods.
+\end{methoddesc}
+
+\begin{methoddesc}{handle_one_request}{}
+This method will parse and dispatch
+the request to the appropriate \method{do_*()} method.  You should
+never need to override it.
+\end{methoddesc}
+
+\begin{methoddesc}{send_error}{code\optional{, message}}
+Sends and logs a complete error reply to the client. The numeric
+\var{code} specifies the HTTP error code, with \var{message} as
+optional, more specific text. A complete set of headers is sent,
+followed by text composed using the \member{error_message_format}
+class variable.
+\end{methoddesc}
+
+\begin{methoddesc}{send_response}{code\optional{, message}}
+Sends a response header and logs the accepted request. The HTTP
+response line is sent, followed by \emph{Server} and \emph{Date}
+headers. The values for these two headers are picked up from the
+\method{version_string()} and \method{date_time_string()} methods,
+respectively.
+\end{methoddesc}
+
+\begin{methoddesc}{send_header}{keyword, value}
+Writes a specific HTTP header to the output stream. \var{keyword}
+should specify the header keyword, with \var{value} specifying
+its value.
+\end{methoddesc}
+
+\begin{methoddesc}{end_headers}{}
+Sends a blank line, indicating the end of the HTTP headers in
+the response.
+\end{methoddesc}
+
+\begin{methoddesc}{log_request}{\optional{code\optional{, size}}}
+Logs an accepted (successful) request. \var{code} should specify
+the numeric HTTP code associated with the response. If a size of
+the response is available, then it should be passed as the
+\var{size} parameter.
+\end{methoddesc}
+
+\begin{methoddesc}{log_error}{...}
+Logs an error when a request cannot be fulfilled. By default,
+it passes the message to \method{log_message()}, so it takes the
+same arguments (\var{format} and additional values).
+\end{methoddesc}
+
+\begin{methoddesc}{log_message}{format, ...}
+Logs an arbitrary message to \code{sys.stderr}. This is typically
+overridden to create custom error logging mechanisms. The
+\var{format} argument is a standard printf-style format string,
+where the additional arguments to \method{log_message()} are applied
+as inputs to the formatting. The client address and current date
+and time are prefixed to every message logged.
+\end{methoddesc}
+
+\begin{methoddesc}{version_string}{}
+Returns the server software's version string. This is a combination
+of the \member{server_version} and \member{sys_version} class variables.
+\end{methoddesc}
+
+\begin{methoddesc}{date_time_string}{\optional{timestamp}}
+Returns the date and time given by \var{timestamp} (which must be in the
+format returned by \function{time.time()}), formatted for a message header.
+If \var{timestamp} is omitted, it uses the current date and time.
+
+The result looks like \code{'Sun, 06 Nov 1994 08:49:37 GMT'}.
+\versionadded[The \var{timestamp} parameter]{2.5}
+\end{methoddesc}
+
+\begin{methoddesc}{log_date_time_string}{}
+Returns the current date and time, formatted for logging.
+\end{methoddesc}
+
+\begin{methoddesc}{address_string}{}
+Returns the client address, formatted for logging. A name lookup
+is performed on the client's IP address.
+\end{methoddesc}
+
+
+\begin{seealso}
+  \seemodule{CGIHTTPServer}{Extended request handler that supports CGI
+                            scripts.}
+
+  \seemodule{SimpleHTTPServer}{Basic request handler that limits response
+                               to files actually under the document root.}
+\end{seealso}

Added: vendor/Python/current/Doc/lib/libbastion.tex
===================================================================
--- vendor/Python/current/Doc/lib/libbastion.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libbastion.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,57 @@
+\section{\module{Bastion} ---
+         Restricting access to objects}
+
+\declaremodule{standard}{Bastion}
+\modulesynopsis{Providing restricted access to objects.}
+\moduleauthor{Barry Warsaw}{bwarsaw at python.org}
+\versionchanged[Disabled module]{2.3}
+
+\begin{notice}[warning]
+  The documentation has been left in place to help in reading old code
+  that uses the module.
+\end{notice}
+
+% I'm concerned that the word 'bastion' won't be understood by people
+% for whom English is a second language, making the module name
+% somewhat mysterious.  Thus, the brief definition... --amk
+
+According to the dictionary, a bastion is ``a fortified area or
+position'', or ``something that is considered a stronghold.''  It's a
+suitable name for this module, which provides a way to forbid access
+to certain attributes of an object.  It must always be used with the
+\refmodule{rexec} module, in order to allow restricted-mode programs
+access to certain safe attributes of an object, while denying access
+to other, unsafe attributes.
+
+% I've punted on the issue of documenting keyword arguments for now.
+
+\begin{funcdesc}{Bastion}{object\optional{, filter\optional{,
+                          name\optional{, class}}}}
+Protect the object \var{object}, returning a bastion for the
+object.  Any attempt to access one of the object's attributes will
+have to be approved by the \var{filter} function; if the access is
+denied an \exception{AttributeError} exception will be raised.
+
+If present, \var{filter} must be a function that accepts a string
+containing an attribute name, and returns true if access to that
+attribute will be permitted; if \var{filter} returns false, the access
+is denied.  The default filter denies access to any function beginning
+with an underscore (\character{_}).  The bastion's string representation
+will be \samp{<Bastion for \var{name}>} if a value for
+\var{name} is provided; otherwise, \samp{repr(\var{object})} will be
+used.
+
+\var{class}, if present, should be a subclass of \class{BastionClass}; 
+see the code in \file{bastion.py} for the details.  Overriding the
+default \class{BastionClass} will rarely be required.
+\end{funcdesc}
+
+
+\begin{classdesc}{BastionClass}{getfunc, name}
+Class which actually implements bastion objects.  This is the default
+class used by \function{Bastion()}.  The \var{getfunc} parameter is a
+function which returns the value of an attribute which should be
+exposed to the restricted execution environment when called with the
+name of the attribute as the only parameter.  \var{name} is used to
+construct the \function{repr()} of the \class{BastionClass} instance.
+\end{classdesc}

Added: vendor/Python/current/Doc/lib/libbinascii.tex
===================================================================
--- vendor/Python/current/Doc/lib/libbinascii.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libbinascii.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,147 @@
+\section{\module{binascii} ---
+         Convert between binary and \ASCII}
+
+\declaremodule{builtin}{binascii}
+\modulesynopsis{Tools for converting between binary and various
+                \ASCII-encoded binary representations.}
+
+
+The \module{binascii} module contains a number of methods to convert
+between binary and various \ASCII-encoded binary
+representations. Normally, you will not use these functions directly
+but use wrapper modules like \refmodule{uu}\refstmodindex{uu},
+\refmodule{base64}\refstmodindex{base64}, or
+\refmodule{binhex}\refstmodindex{binhex} instead. The \module{binascii} module
+contains low-level functions written in C for greater speed
+that are used by the higher-level modules.
+
+The \module{binascii} module defines the following functions:
+
+\begin{funcdesc}{a2b_uu}{string}
+Convert a single line of uuencoded data back to binary and return the
+binary data. Lines normally contain 45 (binary) bytes, except for the
+last line. Line data may be followed by whitespace.
+\end{funcdesc}
+
+\begin{funcdesc}{b2a_uu}{data}
+Convert binary data to a line of \ASCII{} characters, the return value
+is the converted line, including a newline char. The length of
+\var{data} should be at most 45.
+\end{funcdesc}
+
+\begin{funcdesc}{a2b_base64}{string}
+Convert a block of base64 data back to binary and return the
+binary data. More than one line may be passed at a time.
+\end{funcdesc}
+
+\begin{funcdesc}{b2a_base64}{data}
+Convert binary data to a line of \ASCII{} characters in base64 coding.
+The return value is the converted line, including a newline char.
+The length of \var{data} should be at most 57 to adhere to the base64
+standard.
+\end{funcdesc}
+
+\begin{funcdesc}{a2b_qp}{string\optional{, header}}
+Convert a block of quoted-printable data back to binary and return the
+binary data. More than one line may be passed at a time.
+If the optional argument \var{header} is present and true, underscores
+will be decoded as spaces.
+\end{funcdesc}
+
+\begin{funcdesc}{b2a_qp}{data\optional{, quotetabs, istext, header}}
+Convert binary data to a line(s) of \ASCII{} characters in
+quoted-printable encoding.  The return value is the converted line(s).
+If the optional argument \var{quotetabs} is present and true, all tabs
+and spaces will be encoded.  
+If the optional argument \var{istext} is present and true,
+newlines are not encoded but trailing whitespace will be encoded.
+If the optional argument \var{header} is
+present and true, spaces will be encoded as underscores per RFC1522.
+If the optional argument \var{header} is present and false, newline
+characters will be encoded as well; otherwise linefeed conversion might
+corrupt the binary data stream.
+\end{funcdesc}
+
+\begin{funcdesc}{a2b_hqx}{string}
+Convert binhex4 formatted \ASCII{} data to binary, without doing
+RLE-decompression. The string should contain a complete number of
+binary bytes, or (in case of the last portion of the binhex4 data)
+have the remaining bits zero.
+\end{funcdesc}
+
+\begin{funcdesc}{rledecode_hqx}{data}
+Perform RLE-decompression on the data, as per the binhex4
+standard. The algorithm uses \code{0x90} after a byte as a repeat
+indicator, followed by a count. A count of \code{0} specifies a byte
+value of \code{0x90}. The routine returns the decompressed data,
+unless data input data ends in an orphaned repeat indicator, in which
+case the \exception{Incomplete} exception is raised.
+\end{funcdesc}
+
+\begin{funcdesc}{rlecode_hqx}{data}
+Perform binhex4 style RLE-compression on \var{data} and return the
+result.
+\end{funcdesc}
+
+\begin{funcdesc}{b2a_hqx}{data}
+Perform hexbin4 binary-to-\ASCII{} translation and return the
+resulting string. The argument should already be RLE-coded, and have a
+length divisible by 3 (except possibly the last fragment).
+\end{funcdesc}
+
+\begin{funcdesc}{crc_hqx}{data, crc}
+Compute the binhex4 crc value of \var{data}, starting with an initial
+\var{crc} and returning the result.
+\end{funcdesc}
+
+\begin{funcdesc}{crc32}{data\optional{, crc}}
+Compute CRC-32, the 32-bit checksum of data, starting with an initial
+crc.  This is consistent with the ZIP file checksum.  Since the
+algorithm is designed for use as a checksum algorithm, it is not
+suitable for use as a general hash algorithm.  Use as follows:
+\begin{verbatim}
+    print binascii.crc32("hello world")
+    # Or, in two pieces:
+    crc = binascii.crc32("hello")
+    crc = binascii.crc32(" world", crc)
+    print crc
+\end{verbatim}
+\end{funcdesc}
+ 
+\begin{funcdesc}{b2a_hex}{data}
+\funcline{hexlify}{data}
+Return the hexadecimal representation of the binary \var{data}.  Every
+byte of \var{data} is converted into the corresponding 2-digit hex
+representation.  The resulting string is therefore twice as long as
+the length of \var{data}.
+\end{funcdesc}
+
+\begin{funcdesc}{a2b_hex}{hexstr}
+\funcline{unhexlify}{hexstr}
+Return the binary data represented by the hexadecimal string
+\var{hexstr}.  This function is the inverse of \function{b2a_hex()}.
+\var{hexstr} must contain an even number of hexadecimal digits (which
+can be upper or lower case), otherwise a \exception{TypeError} is
+raised.
+\end{funcdesc}
+
+\begin{excdesc}{Error}
+Exception raised on errors. These are usually programming errors.
+\end{excdesc}
+
+\begin{excdesc}{Incomplete}
+Exception raised on incomplete data. These are usually not programming
+errors, but may be handled by reading a little more data and trying
+again.
+\end{excdesc}
+
+
+\begin{seealso}
+  \seemodule{base64}{Support for base64 encoding used in MIME email messages.}
+
+  \seemodule{binhex}{Support for the binhex format used on the Macintosh.}
+
+  \seemodule{uu}{Support for UU encoding used on \UNIX.}
+
+  \seemodule{quopri}{Support for quoted-printable encoding used in MIME email messages. }
+\end{seealso}

Added: vendor/Python/current/Doc/lib/libbinhex.tex
===================================================================
--- vendor/Python/current/Doc/lib/libbinhex.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libbinhex.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,55 @@
+\section{\module{binhex} ---
+         Encode and decode binhex4 files}
+
+\declaremodule{standard}{binhex}
+\modulesynopsis{Encode and decode files in binhex4 format.}
+
+
+This module encodes and decodes files in binhex4 format, a format
+allowing representation of Macintosh files in \ASCII.  On the Macintosh,
+both forks of a file and the finder information are encoded (or
+decoded), on other platforms only the data fork is handled.
+
+The \module{binhex} module defines the following functions:
+
+\begin{funcdesc}{binhex}{input, output}
+Convert a binary file with filename \var{input} to binhex file
+\var{output}. The \var{output} parameter can either be a filename or a
+file-like object (any object supporting a \method{write()} and
+\method{close()} method).
+\end{funcdesc}
+
+\begin{funcdesc}{hexbin}{input\optional{, output}}
+Decode a binhex file \var{input}. \var{input} may be a filename or a
+file-like object supporting \method{read()} and \method{close()} methods.
+The resulting file is written to a file named \var{output}, unless the
+argument is omitted in which case the output filename is read from the
+binhex file.
+\end{funcdesc}
+
+The following exception is also defined:
+
+\begin{excdesc}{Error}
+Exception raised when something can't be encoded using the binhex
+format (for example, a filename is too long to fit in the filename
+field), or when input is not properly encoded binhex data.
+\end{excdesc}
+
+
+\begin{seealso}
+  \seemodule{binascii}{Support module containing \ASCII-to-binary
+                       and binary-to-\ASCII{} conversions.}
+\end{seealso}
+
+
+\subsection{Notes \label{binhex-notes}}
+
+There is an alternative, more powerful interface to the coder and
+decoder, see the source for details.
+
+If you code or decode textfiles on non-Macintosh platforms they will
+still use the Macintosh newline convention (carriage-return as end of
+line).
+
+As of this writing, \function{hexbin()} appears to not work in all
+cases.

Added: vendor/Python/current/Doc/lib/libbisect.tex
===================================================================
--- vendor/Python/current/Doc/lib/libbisect.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libbisect.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,84 @@
+\section{\module{bisect} ---
+         Array bisection algorithm}
+
+\declaremodule{standard}{bisect}
+\modulesynopsis{Array bisection algorithms for binary searching.}
+\sectionauthor{Fred L. Drake, Jr.}{fdrake at acm.org}
+% LaTeX produced by Fred L. Drake, Jr. <fdrake at acm.org>, with an
+% example based on the PyModules FAQ entry by Aaron Watters
+% <arw at pythonpros.com>.
+
+
+This module provides support for maintaining a list in sorted order
+without having to sort the list after each insertion.  For long lists
+of items with expensive comparison operations, this can be an
+improvement over the more common approach.  The module is called
+\module{bisect} because it uses a basic bisection algorithm to do its
+work.  The source code may be most useful as a working example of the
+algorithm (the boundary conditions are already right!).
+
+The following functions are provided:
+
+\begin{funcdesc}{bisect_left}{list, item\optional{, lo\optional{, hi}}}
+  Locate the proper insertion point for \var{item} in \var{list} to
+  maintain sorted order.  The parameters \var{lo} and \var{hi} may be
+  used to specify a subset of the list which should be considered; by
+  default the entire list is used.  If \var{item} is already present
+  in \var{list}, the insertion point will be before (to the left of)
+  any existing entries.  The return value is suitable for use as the
+  first parameter to \code{\var{list}.insert()}.  This assumes that
+  \var{list} is already sorted.
+\versionadded{2.1}
+\end{funcdesc}
+
+\begin{funcdesc}{bisect_right}{list, item\optional{, lo\optional{, hi}}}
+  Similar to \function{bisect_left()}, but returns an insertion point
+  which comes after (to the right of) any existing entries of
+  \var{item} in \var{list}.
+\versionadded{2.1}
+\end{funcdesc}
+
+\begin{funcdesc}{bisect}{\unspecified}
+  Alias for \function{bisect_right()}.
+\end{funcdesc}
+
+\begin{funcdesc}{insort_left}{list, item\optional{, lo\optional{, hi}}}
+  Insert \var{item} in \var{list} in sorted order.  This is equivalent
+  to \code{\var{list}.insert(bisect.bisect_left(\var{list}, \var{item},
+  \var{lo}, \var{hi}), \var{item})}.  This assumes that \var{list} is
+  already sorted.
+\versionadded{2.1}
+\end{funcdesc}
+
+\begin{funcdesc}{insort_right}{list, item\optional{, lo\optional{, hi}}}
+  Similar to \function{insort_left()}, but inserting \var{item} in
+  \var{list} after any existing entries of \var{item}.
+\versionadded{2.1}
+\end{funcdesc}
+
+\begin{funcdesc}{insort}{\unspecified}
+  Alias for \function{insort_right()}.
+\end{funcdesc}
+
+
+\subsection{Examples}
+\nodename{bisect-example}
+
+The \function{bisect()} function is generally useful for categorizing
+numeric data.  This example uses \function{bisect()} to look up a
+letter grade for an exam total (say) based on a set of ordered numeric
+breakpoints: 85 and up is an `A', 75..84 is a `B', etc.
+
+\begin{verbatim}
+>>> grades = "FEDCBA"
+>>> breakpoints = [30, 44, 66, 75, 85]
+>>> from bisect import bisect
+>>> def grade(total):
+...           return grades[bisect(breakpoints, total)]
+...
+>>> grade(66)
+'C'
+>>> map(grade, [33, 99, 77, 44, 12, 88])
+['E', 'A', 'B', 'D', 'F', 'A']
+
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/libbltin.tex
===================================================================
--- vendor/Python/current/Doc/lib/libbltin.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libbltin.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,44 @@
+\section{\module{__builtin__} ---
+         Built-in objects}
+
+\declaremodule[builtin]{builtin}{__builtin__}
+\modulesynopsis{The module that provides the built-in namespace.}
+
+
+This module provides direct access to all `built-in' identifiers of
+Python; for example, \code{__builtin__.open} is the full name for the
+built-in function \function{open()}.  See chapter~\ref{builtin},
+``Built-in Objects.''
+
+This module is not normally accessed explicitly by most applications,
+but can be useful in modules that provide objects with the same name
+as a built-in value, but in which the built-in of that name is also
+needed.  For example, in a module that wants to implement an
+\function{open()} function that wraps the built-in \function{open()},
+this module can be used directly:
+
+\begin{verbatim}
+import __builtin__
+
+def open(path):
+    f = __builtin__.open(path, 'r')
+    return UpperCaser(f)
+
+class UpperCaser:
+    '''Wrapper around a file that converts output to upper-case.'''
+
+    def __init__(self, f):
+        self._f = f
+
+    def read(self, count=-1):
+        return self._f.read(count).upper()
+
+    # ...
+\end{verbatim}
+
+As an implementation detail, most modules have the name
+\code{__builtins__} (note the \character{s}) made available as part of
+their globals.  The value of \code{__builtins__} is normally either
+this module or the value of this modules's \member{__dict__}
+attribute.  Since this is an implementation detail, it may not be used
+by alternate implementations of Python.

Added: vendor/Python/current/Doc/lib/libbsddb.tex
===================================================================
--- vendor/Python/current/Doc/lib/libbsddb.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libbsddb.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,208 @@
+\section{\module{bsddb} ---
+         Interface to Berkeley DB library}
+
+\declaremodule{extension}{bsddb}
+\modulesynopsis{Interface to Berkeley DB database library}
+\sectionauthor{Skip Montanaro}{skip at mojam.com}
+
+
+The \module{bsddb} module provides an interface to the Berkeley DB
+library.  Users can create hash, btree or record based library files
+using the appropriate open call. Bsddb objects behave generally like
+dictionaries.  Keys and values must be strings, however, so to use
+other objects as keys or to store other kinds of objects the user must
+serialize them somehow, typically using \function{marshal.dumps()} or 
+\function{pickle.dumps()}.
+
+The \module{bsddb} module requires a Berkeley DB library version from
+3.3 thru 4.5.
+
+\begin{seealso}
+  \seeurl{http://pybsddb.sourceforge.net/}
+         {The website with documentation for the \module{bsddb.db}
+          Python Berkeley DB interface that closely mirrors the object
+          oriented interface provided in Berkeley DB 3 and 4.}
+
+  \seeurl{http://www.oracle.com/database/berkeley-db/}
+         {The Berkeley DB library.}
+\end{seealso}
+
+A more modern DB, DBEnv and DBSequence object interface is available in the
+\module{bsddb.db} module which closely matches the Berkeley DB C API
+documented at the above URLs.  Additional features provided by the
+\module{bsddb.db} API include fine tuning, transactions, logging, and
+multiprocess concurrent database access.
+
+The following is a description of the legacy \module{bsddb} interface
+compatible with the old Python bsddb module.  Starting in Python 2.5 this
+interface should be safe for multithreaded access.  The \module{bsddb.db}
+API is recommended for threading users as it provides better control.
+
+The \module{bsddb} module defines the following functions that create
+objects that access the appropriate type of Berkeley DB file.  The
+first two arguments of each function are the same.  For ease of
+portability, only the first two arguments should be used in most
+instances.
+
+\begin{funcdesc}{hashopen}{filename\optional{, flag\optional{,
+                           mode\optional{, pgsize\optional{,
+                           ffactor\optional{, nelem\optional{,
+                           cachesize\optional{, lorder\optional{,
+                           hflags}}}}}}}}}
+Open the hash format file named \var{filename}.  Files never intended
+to be preserved on disk may be created by passing \code{None} as the 
+\var{filename}.  The optional
+\var{flag} identifies the mode used to open the file.  It may be
+\character{r} (read only), \character{w} (read-write) ,
+\character{c} (read-write - create if necessary; the default) or
+\character{n} (read-write - truncate to zero length).  The other
+arguments are rarely used and are just passed to the low-level
+\cfunction{dbopen()} function.  Consult the Berkeley DB documentation
+for their use and interpretation.
+\end{funcdesc}
+
+\begin{funcdesc}{btopen}{filename\optional{, flag\optional{,
+mode\optional{, btflags\optional{, cachesize\optional{, maxkeypage\optional{,
+minkeypage\optional{, pgsize\optional{, lorder}}}}}}}}}
+
+Open the btree format file named \var{filename}.  Files never intended 
+to be preserved on disk may be created by passing \code{None} as the 
+\var{filename}.  The optional
+\var{flag} identifies the mode used to open the file.  It may be
+\character{r} (read only), \character{w} (read-write),
+\character{c} (read-write - create if necessary; the default) or
+\character{n} (read-write - truncate to zero length).  The other
+arguments are rarely used and are just passed to the low-level dbopen
+function.  Consult the Berkeley DB documentation for their use and
+interpretation.
+\end{funcdesc}
+
+\begin{funcdesc}{rnopen}{filename\optional{, flag\optional{, mode\optional{,
+rnflags\optional{, cachesize\optional{, pgsize\optional{, lorder\optional{,
+rlen\optional{, delim\optional{, source\optional{, pad}}}}}}}}}}}
+
+Open a DB record format file named \var{filename}.  Files never intended 
+to be preserved on disk may be created by passing \code{None} as the 
+\var{filename}.  The optional
+\var{flag} identifies the mode used to open the file.  It may be
+\character{r} (read only), \character{w} (read-write),
+\character{c} (read-write - create if necessary; the default) or
+\character{n} (read-write - truncate to zero length).  The other
+arguments are rarely used and are just passed to the low-level dbopen
+function.  Consult the Berkeley DB documentation for their use and
+interpretation.
+\end{funcdesc}
+
+
+\begin{notice}
+Beginning in 2.3 some \UNIX{} versions of Python may have a \module{bsddb185}
+module.  This is present \emph{only} to allow backwards compatibility with
+systems which ship with the old Berkeley DB 1.85 database library.  The
+\module{bsddb185} module should never be used directly in new code.
+\end{notice}
+
+
+\begin{seealso}
+  \seemodule{dbhash}{DBM-style interface to the \module{bsddb}}
+\end{seealso}
+
+\subsection{Hash, BTree and Record Objects \label{bsddb-objects}}
+
+Once instantiated, hash, btree and record objects support
+the same methods as dictionaries.  In addition, they support
+the methods listed below.
+\versionchanged[Added dictionary methods]{2.3.1}
+
+\begin{methoddesc}{close}{}
+Close the underlying file.  The object can no longer be accessed.  Since
+there is no open \method{open} method for these objects, to open the file
+again a new \module{bsddb} module open function must be called.
+\end{methoddesc}
+
+\begin{methoddesc}{keys}{}
+Return the list of keys contained in the DB file.  The order of the list is
+unspecified and should not be relied on.  In particular, the order of the
+list returned is different for different file formats.
+\end{methoddesc}
+
+\begin{methoddesc}{has_key}{key}
+Return \code{1} if the DB file contains the argument as a key.
+\end{methoddesc}
+
+\begin{methoddesc}{set_location}{key}
+Set the cursor to the item indicated by \var{key} and return a tuple
+containing the key and its value.  For binary tree databases (opened
+using \function{btopen()}), if \var{key} does not actually exist in
+the database, the cursor will point to the next item in sorted order
+and return that key and value.  For other databases,
+\exception{KeyError} will be raised if \var{key} is not found in the
+database.
+\end{methoddesc}
+
+\begin{methoddesc}{first}{}
+Set the cursor to the first item in the DB file and return it.  The order of 
+keys in the file is unspecified, except in the case of B-Tree databases.
+This method raises \exception{bsddb.error} if the database is empty.
+\end{methoddesc}
+
+\begin{methoddesc}{next}{}
+Set the cursor to the next item in the DB file and return it.  The order of 
+keys in the file is unspecified, except in the case of B-Tree databases.
+\end{methoddesc}
+
+\begin{methoddesc}{previous}{}
+Set the cursor to the previous item in the DB file and return it.  The
+order of keys in the file is unspecified, except in the case of B-Tree
+databases.  This is not supported on hashtable databases (those opened
+with \function{hashopen()}).
+\end{methoddesc}
+
+\begin{methoddesc}{last}{}
+Set the cursor to the last item in the DB file and return it.  The
+order of keys in the file is unspecified.  This is not supported on
+hashtable databases (those opened with \function{hashopen()}).
+This method raises \exception{bsddb.error} if the database is empty.
+\end{methoddesc}
+
+\begin{methoddesc}{sync}{}
+Synchronize the database on disk.
+\end{methoddesc}
+
+Example:
+
+\begin{verbatim}
+>>> import bsddb
+>>> db = bsddb.btopen('/tmp/spam.db', 'c')
+>>> for i in range(10): db['%d'%i] = '%d'% (i*i)
+... 
+>>> db['3']
+'9'
+>>> db.keys()
+['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
+>>> db.first()
+('0', '0')
+>>> db.next()
+('1', '1')
+>>> db.last()
+('9', '81')
+>>> db.set_location('2')
+('2', '4')
+>>> db.previous() 
+('1', '1')
+>>> for k, v in db.iteritems():
+...     print k, v
+0 0
+1 1
+2 4
+3 9
+4 16
+5 25
+6 36
+7 49
+8 64
+9 81
+>>> '8' in db
+True
+>>> db.sync()
+0
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/libbz2.tex
===================================================================
--- vendor/Python/current/Doc/lib/libbz2.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libbz2.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,174 @@
+\section{\module{bz2} ---
+         Compression compatible with \program{bzip2}}
+
+\declaremodule{builtin}{bz2}
+\modulesynopsis{Interface to compression and decompression
+                routines compatible with \program{bzip2}.}
+\moduleauthor{Gustavo Niemeyer}{niemeyer at conectiva.com}
+\sectionauthor{Gustavo Niemeyer}{niemeyer at conectiva.com}
+
+\versionadded{2.3}
+
+This module provides a comprehensive interface for the bz2 compression library.
+It implements a complete file interface, one-shot (de)compression functions,
+and types for sequential (de)compression.
+
+Here is a resume of the features offered by the bz2 module:
+
+\begin{itemize}
+\item \class{BZ2File} class implements a complete file interface, including
+      \method{readline()}, \method{readlines()},
+      \method{writelines()}, \method{seek()}, etc;
+\item \class{BZ2File} class implements emulated \method{seek()} support;
+\item \class{BZ2File} class implements universal newline support;
+\item \class{BZ2File} class offers an optimized line iteration using
+      the readahead algorithm borrowed from file objects;
+\item Sequential (de)compression supported by \class{BZ2Compressor} and
+      \class{BZ2Decompressor} classes;
+\item One-shot (de)compression supported by \function{compress()} and
+      \function{decompress()} functions;
+\item Thread safety uses individual locking mechanism;
+\item Complete inline documentation;
+\end{itemize}
+
+
+\subsection{(De)compression of files}
+
+Handling of compressed files is offered by the \class{BZ2File} class.
+
+\begin{classdesc}{BZ2File}{filename\optional{, mode\optional{,
+                           buffering\optional{, compresslevel}}}}
+Open a bz2 file. Mode can be either \code{'r'} or \code{'w'}, for reading 
+(default) or writing. When opened for writing, the file will be created if
+it doesn't exist, and truncated otherwise. If \var{buffering} is given,
+\code{0} means unbuffered, and larger numbers specify the buffer size;
+the default is \code{0}. If
+\var{compresslevel} is given, it must be a number between \code{1} and
+\code{9}; the default is \code{9}.
+Add a \character{U} to mode to open the file for input with universal newline
+support. Any line ending in the input file will be seen as a
+\character{\e n} in Python.  Also, a file so opened gains the
+attribute \member{newlines}; the value for this attribute is one of
+\code{None} (no newline read yet), \code{'\e r'}, \code{'\e n'},
+\code{'\e r\e n'} or a tuple containing all the newline types
+seen. Universal newlines are available only when reading.
+Instances support iteration in the same way as normal \class{file}
+instances.
+\end{classdesc}
+
+\begin{methoddesc}[BZ2File]{close}{}
+Close the file. Sets data attribute \member{closed} to true. A closed file
+cannot be used for further I/O operations. \method{close()} may be called
+more than once without error.
+\end{methoddesc}
+
+\begin{methoddesc}[BZ2File]{read}{\optional{size}}
+Read at most \var{size} uncompressed bytes, returned as a string. If the
+\var{size} argument is negative or omitted, read until EOF is reached.
+\end{methoddesc}
+
+\begin{methoddesc}[BZ2File]{readline}{\optional{size}}
+Return the next line from the file, as a string, retaining newline.
+A non-negative \var{size} argument limits the maximum number of bytes to
+return (an incomplete line may be returned then). Return an empty
+string at EOF.
+\end{methoddesc}
+
+\begin{methoddesc}[BZ2File]{readlines}{\optional{size}}
+Return a list of lines read. The optional \var{size} argument, if given,
+is an approximate bound on the total number of bytes in the lines returned.
+\end{methoddesc}
+
+\begin{methoddesc}[BZ2File]{xreadlines}{}
+For backward compatibility. \class{BZ2File} objects now include the
+performance optimizations previously implemented in the
+\module{xreadlines} module.
+\deprecated{2.3}{This exists only for compatibility with the method by
+                 this name on \class{file} objects, which is
+                 deprecated.  Use \code{for line in file} instead.}
+\end{methoddesc}
+
+\begin{methoddesc}[BZ2File]{seek}{offset\optional{, whence}}
+Move to new file position. Argument \var{offset} is a byte count. Optional
+argument \var{whence} defaults to \code{os.SEEK_SET} or \code{0} (offset from start of file;
+offset should be \code{>= 0}); other values are \code{os.SEEK_CUR} or \code{1} (move relative to
+current position; offset can be positive or negative), and \code{os.SEEK_END} or \code{2} (move relative to end
+of file; offset is usually negative, although many platforms allow seeking beyond
+the end of a file).
+
+Note that seeking of bz2 files is emulated, and depending on the parameters
+the operation may be extremely slow.
+\end{methoddesc}
+
+\begin{methoddesc}[BZ2File]{tell}{}
+Return the current file position, an integer (may be a long integer).
+\end{methoddesc}
+
+\begin{methoddesc}[BZ2File]{write}{data}
+Write string \var{data} to file. Note that due to buffering, \method{close()}
+may be needed before the file on disk reflects the data written.
+\end{methoddesc}
+
+\begin{methoddesc}[BZ2File]{writelines}{sequence_of_strings}
+Write the sequence of strings to the file. Note that newlines are not added.
+The sequence can be any iterable object producing strings. This is equivalent
+to calling write() for each string.
+\end{methoddesc}
+
+
+\subsection{Sequential (de)compression}
+
+Sequential compression and decompression is done using the classes
+\class{BZ2Compressor} and \class{BZ2Decompressor}.
+
+\begin{classdesc}{BZ2Compressor}{\optional{compresslevel}}
+Create a new compressor object. This object may be used to compress
+data sequentially. If you want to compress data in one shot, use the
+\function{compress()} function instead. The \var{compresslevel} parameter,
+if given, must be a number between \code{1} and \code{9}; the default
+is \code{9}.
+\end{classdesc}
+
+\begin{methoddesc}[BZ2Compressor]{compress}{data}
+Provide more data to the compressor object. It will return chunks of compressed
+data whenever possible. When you've finished providing data to compress, call
+the \method{flush()} method to finish the compression process, and return what
+is left in internal buffers.
+\end{methoddesc}
+
+\begin{methoddesc}[BZ2Compressor]{flush}{}
+Finish the compression process and return what is left in internal buffers. You
+must not use the compressor object after calling this method.
+\end{methoddesc}
+
+\begin{classdesc}{BZ2Decompressor}{}
+Create a new decompressor object. This object may be used to decompress
+data sequentially. If you want to decompress data in one shot, use the
+\function{decompress()} function instead.
+\end{classdesc}
+
+\begin{methoddesc}[BZ2Decompressor]{decompress}{data}
+Provide more data to the decompressor object. It will return chunks of
+decompressed data whenever possible. If you try to decompress data after the
+end of stream is found, \exception{EOFError} will be raised. If any data was
+found after the end of stream, it'll be ignored and saved in
+\member{unused\_data} attribute.
+\end{methoddesc}
+
+
+\subsection{One-shot (de)compression}
+
+One-shot compression and decompression is provided through the
+\function{compress()} and \function{decompress()} functions.
+
+\begin{funcdesc}{compress}{data\optional{, compresslevel}}
+Compress \var{data} in one shot. If you want to compress data sequentially,
+use an instance of \class{BZ2Compressor} instead. The \var{compresslevel}
+parameter, if given, must be a number between \code{1} and \code{9};
+the default is \code{9}.
+\end{funcdesc}
+
+\begin{funcdesc}{decompress}{data}
+Decompress \var{data} in one shot. If you want to decompress data
+sequentially, use an instance of \class{BZ2Decompressor} instead.
+\end{funcdesc}

Added: vendor/Python/current/Doc/lib/libcalendar.tex
===================================================================
--- vendor/Python/current/Doc/lib/libcalendar.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libcalendar.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,304 @@
+\section{\module{calendar} ---
+         General calendar-related functions}
+
+\declaremodule{standard}{calendar}
+\modulesynopsis{Functions for working with calendars,
+                including some emulation of the \UNIX\ \program{cal}
+                program.}
+\sectionauthor{Drew Csillag}{drew_csillag at geocities.com}
+
+This module allows you to output calendars like the \UNIX{}
+\program{cal} program, and provides additional useful functions
+related to the calendar. By default, these calendars have Monday as
+the first day of the week, and Sunday as the last (the European
+convention). Use \function{setfirstweekday()} to set the first day of the
+week to Sunday (6) or to any other weekday.  Parameters that specify
+dates are given as integers.
+
+Most of these functions and classses rely on the \module{datetime}
+module which uses an idealized calendar, the current Gregorian
+calendar indefinitely extended in both directions.  This matches
+the definition of the "proleptic Gregorian" calendar in Dershowitz
+and Reingold's book "Calendrical Calculations", where it's the
+base calendar for all computations.
+
+\begin{classdesc}{Calendar}{\optional{firstweekday}}
+Creates a \class{Calendar} object. \var{firstweekday} is an integer
+specifying the first day of the week. \code{0} is Monday (the default),
+\code{6} is Sunday.
+
+A \class{Calendar} object provides several methods that can
+be used for preparing the calendar data for formatting. This
+class doesn't do any formatting itself. This is the job of
+subclasses.
+\versionadded{2.5}
+\end{classdesc}
+
+\class{Calendar} instances have the following methods:
+
+\begin{methoddesc}{iterweekdays}{weekday}
+Return an iterator for the week day numbers that will be used
+for one week. The first number from the iterator will be the
+same as the number returned by \method{firstweekday()}.
+\end{methoddesc}
+
+\begin{methoddesc}{itermonthdates}{year, month}
+Return an iterator for the month \var{month} (1-12) in the
+year \var{year}. This iterator will return all days (as
+\class{datetime.date} objects) for the month and all days
+before the start of the month or after the end of the month
+that are required to get a complete week.
+\end{methoddesc}
+
+\begin{methoddesc}{itermonthdays2}{year, month}
+Return an iterator for the month \var{month} in the year
+\var{year} similar to \method{itermonthdates()}. Days returned
+will be tuples consisting of a day number and a week day
+number.
+\end{methoddesc}
+
+\begin{methoddesc}{itermonthdays}{year, month}
+Return an iterator for the month \var{month} in the year
+\var{year} similar to \method{itermonthdates()}. Days returned
+will simply be day numbers.
+\end{methoddesc}
+
+\begin{methoddesc}{monthdatescalendar}{year, month}
+Return a list of the weeks in the month \var{month} of
+the \var{year} as full weeks. Weeks are lists of seven
+\class{datetime.date} objects.
+\end{methoddesc}
+
+\begin{methoddesc}{monthdays2calendar}{year, month}
+Return a list of the weeks in the month \var{month} of
+the \var{year} as full weeks. Weeks are lists of seven
+tuples of day numbers and weekday numbers.
+\end{methoddesc}
+
+\begin{methoddesc}{monthdayscalendar}{year, month}
+Return a list of the weeks in the month \var{month} of
+the \var{year} as full weeks. Weeks are lists of seven
+day numbers.
+\end{methoddesc}
+
+\begin{methoddesc}{yeardatescalendar}{year, month\optional{, width}}
+Return the data for the specified year ready for formatting. The return
+value is a list of month rows. Each month row contains up to \var{width}
+months (defaulting to 3). Each month contains between 4 and 6 weeks and
+each week contains 1--7 days. Days are \class{datetime.date} objects.
+\end{methoddesc}
+
+\begin{methoddesc}{yeardays2calendar}{year, month\optional{, width}}
+Return the data for the specified year ready for formatting (similar to
+\method{yeardatescalendar()}). Entries in the week lists are tuples of
+day numbers and weekday numbers. Day numbers outside this month are zero.
+\end{methoddesc}
+
+\begin{methoddesc}{yeardayscalendar}{year, month\optional{, width}}
+Return the data for the specified year ready for formatting (similar to
+\method{yeardatescalendar()}). Entries in the week lists are day numbers.
+Day numbers outside this month are zero.
+\end{methoddesc}
+
+
+\begin{classdesc}{TextCalendar}{\optional{firstweekday}}
+This class can be used to generate plain text calendars.
+
+\versionadded{2.5}
+\end{classdesc}
+
+\class{TextCalendar} instances have the following methods:
+
+\begin{methoddesc}{formatmonth}{theyear, themonth\optional{, w\optional{, l}}}
+Return a month's calendar in a multi-line string. If \var{w} is
+provided, it specifies the width of the date columns, which are
+centered. If \var{l} is given, it specifies the number of lines that
+each week will use. Depends on the first weekday as set by
+\function{setfirstweekday()}.
+\end{methoddesc}
+
+\begin{methoddesc}{prmonth}{theyear, themonth\optional{, w\optional{, l}}}
+Print a month's calendar as returned by \method{formatmonth()}.
+\end{methoddesc}
+
+\begin{methoddesc}{formatyear}{theyear, themonth\optional{, w\optional{,
+                               l\optional{, c\optional{, m}}}}}
+Return a \var{m}-column calendar for an entire year as a multi-line string.
+Optional parameters \var{w}, \var{l}, and \var{c} are for date column
+width, lines per week, and number of spaces between month columns,
+respectively. Depends on the first weekday as set by
+\method{setfirstweekday()}.  The earliest year for which a calendar can
+be generated is platform-dependent.
+\end{methoddesc}
+
+\begin{methoddesc}{pryear}{theyear\optional{, w\optional{, l\optional{,
+                           c\optional{, m}}}}}
+Print the calendar for an entire year as returned by \method{formatyear()}.
+\end{methoddesc}
+
+
+\begin{classdesc}{HTMLCalendar}{\optional{firstweekday}}
+This class can be used to generate HTML calendars.
+
+\versionadded{2.5}
+\end{classdesc}
+
+\class{HTMLCalendar} instances have the following methods:
+
+\begin{methoddesc}{formatmonth}{theyear, themonth\optional{, withyear}}
+Return a month's calendar as an HTML table. If \var{withyear} is
+true the year will be included in the header, otherwise just the
+month name will be used.
+\end{methoddesc}
+
+\begin{methoddesc}{formatyear}{theyear, themonth\optional{, width}}
+Return a year's calendar as an HTML table. \var{width} (defaulting to 3)
+specifies the number of months per row.
+\end{methoddesc}
+
+\begin{methoddesc}{formatyearpage}{theyear, themonth\optional{,
+                                   width\optional{, css\optional{, encoding}}}}
+Return a year's calendar as a complete HTML page. \var{width}
+(defaulting to 3) specifies the number of months per row. \var{css}
+is the name for the cascading style sheet to be used. \constant{None}
+can be passed if no style sheet should be used. \var{encoding}
+specifies the encoding to be used for the output (defaulting
+to the system default encoding).
+\end{methoddesc}
+
+
+\begin{classdesc}{LocaleTextCalendar}{\optional{firstweekday\optional{, locale}}}
+This subclass of \class{TextCalendar} can be passed a locale name in the
+constructor and will return month and weekday names in the specified locale.
+If this locale includes an encoding all strings containing month and weekday
+names will be returned as unicode.
+\versionadded{2.5}
+\end{classdesc}
+
+
+\begin{classdesc}{LocaleHTMLCalendar}{\optional{firstweekday\optional{, locale}}}
+This subclass of \class{HTMLCalendar} can be passed a locale name in the
+constructor and will return month and weekday names in the specified locale.
+If this locale includes an encoding all strings containing month and weekday
+names will be returned as unicode.
+\versionadded{2.5}
+\end{classdesc}
+
+
+For simple text calendars this module provides the following functions.
+
+\begin{funcdesc}{setfirstweekday}{weekday}
+Sets the weekday (\code{0} is Monday, \code{6} is Sunday) to start
+each week. The values \constant{MONDAY}, \constant{TUESDAY},
+\constant{WEDNESDAY}, \constant{THURSDAY}, \constant{FRIDAY},
+\constant{SATURDAY}, and \constant{SUNDAY} are provided for
+convenience. For example, to set the first weekday to Sunday:
+
+\begin{verbatim}
+import calendar
+calendar.setfirstweekday(calendar.SUNDAY)
+\end{verbatim}
+\versionadded{2.0}
+\end{funcdesc}
+
+\begin{funcdesc}{firstweekday}{}
+Returns the current setting for the weekday to start each week.
+\versionadded{2.0}
+\end{funcdesc}
+
+\begin{funcdesc}{isleap}{year}
+Returns \constant{True} if \var{year} is a leap year, otherwise
+\constant{False}.
+\end{funcdesc}
+
+\begin{funcdesc}{leapdays}{y1, y2}
+Returns the number of leap years in the range
+[\var{y1}\ldots\var{y2}), where \var{y1} and \var{y2} are years.
+\versionchanged[This function didn't work for ranges spanning 
+                a century change in Python 1.5.2]{2.0}
+\end{funcdesc}
+
+\begin{funcdesc}{weekday}{year, month, day}
+Returns the day of the week (\code{0} is Monday) for \var{year}
+(\code{1970}--\ldots), \var{month} (\code{1}--\code{12}), \var{day}
+(\code{1}--\code{31}).
+\end{funcdesc}
+
+\begin{funcdesc}{weekheader}{n}
+Return a header containing abbreviated weekday names. \var{n} specifies
+the width in characters for one weekday.
+\end{funcdesc}
+
+\begin{funcdesc}{monthrange}{year, month}
+Returns weekday of first day of the month and number of days in month, 
+for the specified \var{year} and \var{month}.
+\end{funcdesc}
+
+\begin{funcdesc}{monthcalendar}{year, month}
+Returns a matrix representing a month's calendar.  Each row represents
+a week; days outside of the month a represented by zeros.
+Each week begins with Monday unless set by \function{setfirstweekday()}.
+\end{funcdesc}
+
+\begin{funcdesc}{prmonth}{theyear, themonth\optional{, w\optional{, l}}}
+Prints a month's calendar as returned by \function{month()}.
+\end{funcdesc}
+
+\begin{funcdesc}{month}{theyear, themonth\optional{, w\optional{, l}}}
+Returns a month's calendar in a multi-line string using the
+\method{formatmonth} of the \class{TextCalendar} class.
+\versionadded{2.0}
+\end{funcdesc}
+
+\begin{funcdesc}{prcal}{year\optional{, w\optional{, l\optional{c}}}}
+Prints the calendar for an entire year as returned by 
+\function{calendar()}.
+\end{funcdesc}
+
+\begin{funcdesc}{calendar}{year\optional{, w\optional{, l\optional{c}}}}
+Returns a 3-column calendar for an entire year as a multi-line string
+using the \method{formatyear} of the \class{TextCalendar} class.
+\versionadded{2.0}
+\end{funcdesc}
+
+\begin{funcdesc}{timegm}{tuple}
+An unrelated but handy function that takes a time tuple such as
+returned by the \function{gmtime()} function in the \refmodule{time}
+module, and returns the corresponding \UNIX{} timestamp value, assuming
+an epoch of 1970, and the POSIX encoding.  In fact,
+\function{time.gmtime()} and \function{timegm()} are each others' inverse.
+\versionadded{2.0}
+\end{funcdesc}
+
+The \module{calendar} module exports the following data attributes:
+
+\begin{datadesc}{day_name}
+An array that represents the days of the week in the
+current locale.
+\end{datadesc}
+
+\begin{datadesc}{day_abbr}
+An array that represents the abbreviated days of the week
+in the current locale.
+\end{datadesc}
+
+\begin{datadesc}{month_name}
+An array that represents the months of the year in the
+current locale.  This follows normal convention
+of January being month number 1, so it has a length of 13 and 
+\code{month_name[0]} is the empty string.
+\end{datadesc}
+
+\begin{datadesc}{month_abbr}
+An array that represents the abbreviated months of the year
+in the current locale.  This follows normal convention
+of January being month number 1, so it has a length of 13 and 
+\code{month_abbr[0]} is the empty string.
+\end{datadesc}
+
+\begin{seealso}
+  \seemodule{datetime}{Object-oriented interface to dates and times
+                       with similar functionality to the
+                       \refmodule{time} module.}
+  \seemodule{time}{Low-level time related functions.}
+\end{seealso}

Added: vendor/Python/current/Doc/lib/libcd.tex
===================================================================
--- vendor/Python/current/Doc/lib/libcd.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libcd.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,304 @@
+\section{\module{cd} ---
+         CD-ROM access on SGI systems}
+
+\declaremodule{builtin}{cd}
+  \platform{IRIX}
+\modulesynopsis{Interface to the CD-ROM on Silicon Graphics systems.}
+
+
+This module provides an interface to the Silicon Graphics CD library.
+It is available only on Silicon Graphics systems.
+
+The way the library works is as follows.  A program opens the CD-ROM
+device with \function{open()} and creates a parser to parse the data
+from the CD with \function{createparser()}.  The object returned by
+\function{open()} can be used to read data from the CD, but also to get
+status information for the CD-ROM device, and to get information about
+the CD, such as the table of contents.  Data from the CD is passed to
+the parser, which parses the frames, and calls any callback
+functions that have previously been added.
+
+An audio CD is divided into \dfn{tracks} or \dfn{programs} (the terms
+are used interchangeably).  Tracks can be subdivided into
+\dfn{indices}.  An audio CD contains a \dfn{table of contents} which
+gives the starts of the tracks on the CD.  Index 0 is usually the
+pause before the start of a track.  The start of the track as given by
+the table of contents is normally the start of index 1.
+
+Positions on a CD can be represented in two ways.  Either a frame
+number or a tuple of three values, minutes, seconds and frames.  Most
+functions use the latter representation.  Positions can be both
+relative to the beginning of the CD, and to the beginning of the
+track.
+
+Module \module{cd} defines the following functions and constants:
+
+
+\begin{funcdesc}{createparser}{}
+Create and return an opaque parser object.  The methods of the parser
+object are described below.
+\end{funcdesc}
+
+\begin{funcdesc}{msftoframe}{minutes, seconds, frames}
+Converts a \code{(\var{minutes}, \var{seconds}, \var{frames})} triple
+representing time in absolute time code into the corresponding CD
+frame number.
+\end{funcdesc}
+
+\begin{funcdesc}{open}{\optional{device\optional{, mode}}}
+Open the CD-ROM device.  The return value is an opaque player object;
+methods of the player object are described below.  The device is the
+name of the SCSI device file, e.g. \code{'/dev/scsi/sc0d4l0'}, or
+\code{None}.  If omitted or \code{None}, the hardware inventory is
+consulted to locate a CD-ROM drive.  The \var{mode}, if not omitted,
+should be the string \code{'r'}.
+\end{funcdesc}
+
+The module defines the following variables:
+
+\begin{excdesc}{error}
+Exception raised on various errors.
+\end{excdesc}
+
+\begin{datadesc}{DATASIZE}
+The size of one frame's worth of audio data.  This is the size of the
+audio data as passed to the callback of type \code{audio}.
+\end{datadesc}
+
+\begin{datadesc}{BLOCKSIZE}
+The size of one uninterpreted frame of audio data.
+\end{datadesc}
+
+The following variables are states as returned by
+\function{getstatus()}:
+
+\begin{datadesc}{READY}
+The drive is ready for operation loaded with an audio CD.
+\end{datadesc}
+
+\begin{datadesc}{NODISC}
+The drive does not have a CD loaded.
+\end{datadesc}
+
+\begin{datadesc}{CDROM}
+The drive is loaded with a CD-ROM.  Subsequent play or read operations
+will return I/O errors.
+\end{datadesc}
+
+\begin{datadesc}{ERROR}
+An error occurred while trying to read the disc or its table of
+contents.
+\end{datadesc}
+
+\begin{datadesc}{PLAYING}
+The drive is in CD player mode playing an audio CD through its audio
+jacks.
+\end{datadesc}
+
+\begin{datadesc}{PAUSED}
+The drive is in CD layer mode with play paused.
+\end{datadesc}
+
+\begin{datadesc}{STILL}
+The equivalent of \constant{PAUSED} on older (non 3301) model Toshiba
+CD-ROM drives.  Such drives have never been shipped by SGI.
+\end{datadesc}
+
+\begin{datadesc}{audio}
+\dataline{pnum}
+\dataline{index}
+\dataline{ptime}
+\dataline{atime}
+\dataline{catalog}
+\dataline{ident}
+\dataline{control}
+Integer constants describing the various types of parser callbacks
+that can be set by the \method{addcallback()} method of CD parser
+objects (see below).
+\end{datadesc}
+
+
+\subsection{Player Objects}
+\label{player-objects}
+
+Player objects (returned by \function{open()}) have the following
+methods:
+
+\begin{methoddesc}[CD player]{allowremoval}{}
+Unlocks the eject button on the CD-ROM drive permitting the user to
+eject the caddy if desired.
+\end{methoddesc}
+
+\begin{methoddesc}[CD player]{bestreadsize}{}
+Returns the best value to use for the \var{num_frames} parameter of
+the \method{readda()} method.  Best is defined as the value that
+permits a continuous flow of data from the CD-ROM drive.
+\end{methoddesc}
+
+\begin{methoddesc}[CD player]{close}{}
+Frees the resources associated with the player object.  After calling
+\method{close()}, the methods of the object should no longer be used.
+\end{methoddesc}
+
+\begin{methoddesc}[CD player]{eject}{}
+Ejects the caddy from the CD-ROM drive.
+\end{methoddesc}
+
+\begin{methoddesc}[CD player]{getstatus}{}
+Returns information pertaining to the current state of the CD-ROM
+drive.  The returned information is a tuple with the following values:
+\var{state}, \var{track}, \var{rtime}, \var{atime}, \var{ttime},
+\var{first}, \var{last}, \var{scsi_audio}, \var{cur_block}.
+\var{rtime} is the time relative to the start of the current track;
+\var{atime} is the time relative to the beginning of the disc;
+\var{ttime} is the total time on the disc.  For more information on
+the meaning of the values, see the man page \manpage{CDgetstatus}{3dm}.
+The value of \var{state} is one of the following: \constant{ERROR},
+\constant{NODISC}, \constant{READY}, \constant{PLAYING},
+\constant{PAUSED}, \constant{STILL}, or \constant{CDROM}.
+\end{methoddesc}
+
+\begin{methoddesc}[CD player]{gettrackinfo}{track}
+Returns information about the specified track.  The returned
+information is a tuple consisting of two elements, the start time of
+the track and the duration of the track.
+\end{methoddesc}
+
+\begin{methoddesc}[CD player]{msftoblock}{min, sec, frame}
+Converts a minutes, seconds, frames triple representing a time in
+absolute time code into the corresponding logical block number for the
+given CD-ROM drive.  You should use \function{msftoframe()} rather than
+\method{msftoblock()} for comparing times.  The logical block number
+differs from the frame number by an offset required by certain CD-ROM
+drives.
+\end{methoddesc}
+
+\begin{methoddesc}[CD player]{play}{start, play}
+Starts playback of an audio CD in the CD-ROM drive at the specified
+track.  The audio output appears on the CD-ROM drive's headphone and
+audio jacks (if fitted).  Play stops at the end of the disc.
+\var{start} is the number of the track at which to start playing the
+CD; if \var{play} is 0, the CD will be set to an initial paused
+state.  The method \method{togglepause()} can then be used to commence
+play.
+\end{methoddesc}
+
+\begin{methoddesc}[CD player]{playabs}{minutes, seconds, frames, play}
+Like \method{play()}, except that the start is given in minutes,
+seconds, and frames instead of a track number.
+\end{methoddesc}
+
+\begin{methoddesc}[CD player]{playtrack}{start, play}
+Like \method{play()}, except that playing stops at the end of the
+track.
+\end{methoddesc}
+
+\begin{methoddesc}[CD player]{playtrackabs}{track, minutes, seconds, frames, play}
+Like \method{play()}, except that playing begins at the specified
+absolute time and ends at the end of the specified track.
+\end{methoddesc}
+
+\begin{methoddesc}[CD player]{preventremoval}{}
+Locks the eject button on the CD-ROM drive thus preventing the user
+from arbitrarily ejecting the caddy.
+\end{methoddesc}
+
+\begin{methoddesc}[CD player]{readda}{num_frames}
+Reads the specified number of frames from an audio CD mounted in the
+CD-ROM drive.  The return value is a string representing the audio
+frames.  This string can be passed unaltered to the
+\method{parseframe()} method of the parser object.
+\end{methoddesc}
+
+\begin{methoddesc}[CD player]{seek}{minutes, seconds, frames}
+Sets the pointer that indicates the starting point of the next read of
+digital audio data from a CD-ROM.  The pointer is set to an absolute
+time code location specified in \var{minutes}, \var{seconds}, and
+\var{frames}.  The return value is the logical block number to which
+the pointer has been set.
+\end{methoddesc}
+
+\begin{methoddesc}[CD player]{seekblock}{block}
+Sets the pointer that indicates the starting point of the next read of
+digital audio data from a CD-ROM.  The pointer is set to the specified
+logical block number.  The return value is the logical block number to
+which the pointer has been set.
+\end{methoddesc}
+
+\begin{methoddesc}[CD player]{seektrack}{track}
+Sets the pointer that indicates the starting point of the next read of
+digital audio data from a CD-ROM.  The pointer is set to the specified
+track.  The return value is the logical block number to which the
+pointer has been set.
+\end{methoddesc}
+
+\begin{methoddesc}[CD player]{stop}{}
+Stops the current playing operation.
+\end{methoddesc}
+
+\begin{methoddesc}[CD player]{togglepause}{}
+Pauses the CD if it is playing, and makes it play if it is paused.
+\end{methoddesc}
+
+
+\subsection{Parser Objects}
+\label{cd-parser-objects}
+
+Parser objects (returned by \function{createparser()}) have the
+following methods:
+
+\begin{methoddesc}[CD parser]{addcallback}{type, func, arg}
+Adds a callback for the parser.  The parser has callbacks for eight
+different types of data in the digital audio data stream.  Constants
+for these types are defined at the \module{cd} module level (see above).
+The callback is called as follows: \code{\var{func}(\var{arg}, type,
+data)}, where \var{arg} is the user supplied argument, \var{type} is
+the particular type of callback, and \var{data} is the data returned
+for this \var{type} of callback.  The type of the data depends on the
+\var{type} of callback as follows:
+
+\begin{tableii}{l|p{4in}}{code}{Type}{Value}
+  \lineii{audio}{String which can be passed unmodified to
+\function{al.writesamps()}.}
+  \lineii{pnum}{Integer giving the program (track) number.}
+  \lineii{index}{Integer giving the index number.}
+  \lineii{ptime}{Tuple consisting of the program time in minutes,
+seconds, and frames.}
+  \lineii{atime}{Tuple consisting of the absolute time in minutes,
+seconds, and frames.}
+  \lineii{catalog}{String of 13 characters, giving the catalog number
+of the CD.}
+  \lineii{ident}{String of 12 characters, giving the ISRC
+identification number of the recording.  The string consists of two
+characters country code, three characters owner code, two characters
+giving the year, and five characters giving a serial number.}
+  \lineii{control}{Integer giving the control bits from the CD
+subcode data}
+\end{tableii}
+\end{methoddesc}
+
+\begin{methoddesc}[CD parser]{deleteparser}{}
+Deletes the parser and frees the memory it was using.  The object
+should not be used after this call.  This call is done automatically
+when the last reference to the object is removed.
+\end{methoddesc}
+
+\begin{methoddesc}[CD parser]{parseframe}{frame}
+Parses one or more frames of digital audio data from a CD such as
+returned by \method{readda()}.  It determines which subcodes are
+present in the data.  If these subcodes have changed since the last
+frame, then \method{parseframe()} executes a callback of the
+appropriate type passing to it the subcode data found in the frame.
+Unlike the \C{} function, more than one frame of digital audio data
+can be passed to this method.
+\end{methoddesc}
+
+\begin{methoddesc}[CD parser]{removecallback}{type}
+Removes the callback for the given \var{type}.
+\end{methoddesc}
+
+\begin{methoddesc}[CD parser]{resetparser}{}
+Resets the fields of the parser used for tracking subcodes to an
+initial state.  \method{resetparser()} should be called after the disc
+has been changed.
+\end{methoddesc}

Added: vendor/Python/current/Doc/lib/libcfgparser.tex
===================================================================
--- vendor/Python/current/Doc/lib/libcfgparser.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libcfgparser.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,313 @@
+\section{\module{ConfigParser} ---
+         Configuration file parser}
+
+\declaremodule{standard}{ConfigParser}
+\modulesynopsis{Configuration file parser.}
+\moduleauthor{Ken Manheimer}{klm at zope.com}
+\moduleauthor{Barry Warsaw}{bwarsaw at python.org}
+\moduleauthor{Eric S. Raymond}{esr at thyrsus.com}
+\sectionauthor{Christopher G. Petrilli}{petrilli at amber.org}
+
+This module defines the class \class{ConfigParser}.
+\indexii{.ini}{file}\indexii{configuration}{file}\index{ini file}
+\index{Windows ini file}
+The \class{ConfigParser} class implements a basic configuration file
+parser language which provides a structure similar to what you would
+find on Microsoft Windows INI files.  You can use this to write Python
+programs which can be customized by end users easily.
+
+\begin{notice}[warning]
+  This library does \emph{not} interpret or write the value-type
+  prefixes used in the Windows Registry extended version of INI syntax.
+\end{notice}
+
+The configuration file consists of sections, led by a
+\samp{[section]} header and followed by \samp{name: value} entries,
+with continuations in the style of \rfc{822}; \samp{name=value} is
+also accepted.  Note that leading whitespace is removed from values.
+The optional values can contain format strings which refer to other
+values in the same section, or values in a special
+\code{DEFAULT} section.  Additional defaults can be provided on
+initialization and retrieval.  Lines beginning with \character{\#} or
+\character{;} are ignored and may be used to provide comments.
+
+For example:
+
+\begin{verbatim}
+[My Section]
+foodir: %(dir)s/whatever
+dir=frob
+\end{verbatim}
+
+would resolve the \samp{\%(dir)s} to the value of
+\samp{dir} (\samp{frob} in this case).  All reference expansions are
+done on demand.
+
+Default values can be specified by passing them into the
+\class{ConfigParser} constructor as a dictionary.  Additional defaults 
+may be passed into the \method{get()} method which will override all
+others.
+
+\begin{classdesc}{RawConfigParser}{\optional{defaults}}
+The basic configuration object.  When \var{defaults} is given, it is
+initialized into the dictionary of intrinsic defaults.  This class
+does not support the magical interpolation behavior.
+\versionadded{2.3}
+\end{classdesc}
+
+\begin{classdesc}{ConfigParser}{\optional{defaults}}
+Derived class of \class{RawConfigParser} that implements the magical
+interpolation feature and adds optional arguments to the \method{get()}
+and \method{items()} methods.  The values in \var{defaults} must be
+appropriate for the \samp{\%()s} string interpolation.  Note that
+\var{__name__} is an intrinsic default; its value is the section name,
+and will override any value provided in \var{defaults}.
+
+All option names used in interpolation will be passed through the
+\method{optionxform()} method just like any other option name
+reference.  For example, using the default implementation of
+\method{optionxform()} (which converts option names to lower case),
+the values \samp{foo \%(bar)s} and \samp{foo \%(BAR)s} are
+equivalent.
+\end{classdesc}
+
+\begin{classdesc}{SafeConfigParser}{\optional{defaults}}
+Derived class of \class{ConfigParser} that implements a more-sane
+variant of the magical interpolation feature.  This implementation is
+more predictable as well.
+% XXX Need to explain what's safer/more predictable about it.
+New applications should prefer this version if they don't need to be
+compatible with older versions of Python.
+\versionadded{2.3}
+\end{classdesc}
+
+\begin{excdesc}{NoSectionError}
+Exception raised when a specified section is not found.
+\end{excdesc}
+
+\begin{excdesc}{DuplicateSectionError}
+Exception raised if \method{add_section()} is called with the name of
+a section that is already present.
+\end{excdesc}
+
+\begin{excdesc}{NoOptionError}
+Exception raised when a specified option is not found in the specified 
+section.
+\end{excdesc}
+
+\begin{excdesc}{InterpolationError}
+Base class for exceptions raised when problems occur performing string
+interpolation.
+\end{excdesc}
+
+\begin{excdesc}{InterpolationDepthError}
+Exception raised when string interpolation cannot be completed because
+the number of iterations exceeds \constant{MAX_INTERPOLATION_DEPTH}.
+Subclass of \exception{InterpolationError}.
+\end{excdesc}
+
+\begin{excdesc}{InterpolationMissingOptionError}
+Exception raised when an option referenced from a value does not exist.
+Subclass of \exception{InterpolationError}.
+\versionadded{2.3}
+\end{excdesc}
+
+\begin{excdesc}{InterpolationSyntaxError}
+Exception raised when the source text into which substitutions are
+made does not conform to the required syntax.
+Subclass of \exception{InterpolationError}.
+\versionadded{2.3}
+\end{excdesc}
+
+\begin{excdesc}{MissingSectionHeaderError}
+Exception raised when attempting to parse a file which has no section
+headers.
+\end{excdesc}
+
+\begin{excdesc}{ParsingError}
+Exception raised when errors occur attempting to parse a file.
+\end{excdesc}
+
+\begin{datadesc}{MAX_INTERPOLATION_DEPTH}
+The maximum depth for recursive interpolation for \method{get()} when
+the \var{raw} parameter is false.  This is relevant only for the
+\class{ConfigParser} class.
+\end{datadesc}
+
+
+\begin{seealso}
+  \seemodule{shlex}{Support for a creating \UNIX{} shell-like
+                    mini-languages which can be used as an alternate
+                    format for application configuration files.}
+\end{seealso}
+
+
+\subsection{RawConfigParser Objects \label{RawConfigParser-objects}}
+
+\class{RawConfigParser} instances have the following methods:
+
+\begin{methoddesc}{defaults}{}
+Return a dictionary containing the instance-wide defaults.
+\end{methoddesc}
+
+\begin{methoddesc}{sections}{}
+Return a list of the sections available; \code{DEFAULT} is not
+included in the list.
+\end{methoddesc}
+
+\begin{methoddesc}{add_section}{section}
+Add a section named \var{section} to the instance.  If a section by
+the given name already exists, \exception{DuplicateSectionError} is
+raised.
+\end{methoddesc}
+
+\begin{methoddesc}{has_section}{section}
+Indicates whether the named section is present in the
+configuration. The \code{DEFAULT} section is not acknowledged.
+\end{methoddesc}
+
+\begin{methoddesc}{options}{section}
+Returns a list of options available in the specified \var{section}.
+\end{methoddesc}
+
+\begin{methoddesc}{has_option}{section, option}
+If the given section exists, and contains the given option,
+return \constant{True}; otherwise return \constant{False}.
+\versionadded{1.6}
+\end{methoddesc}
+
+\begin{methoddesc}{read}{filenames}
+Attempt to read and parse a list of filenames, returning a list of filenames
+which were successfully parsed.  If \var{filenames} is a string or
+Unicode string, it is treated as a single filename.
+If a file named in \var{filenames} cannot be opened, that file will be
+ignored.  This is designed so that you can specify a list of potential
+configuration file locations (for example, the current directory, the
+user's home directory, and some system-wide directory), and all
+existing configuration files in the list will be read.  If none of the
+named files exist, the \class{ConfigParser} instance will contain an
+empty dataset.  An application which requires initial values to be
+loaded from a file should load the required file or files using
+\method{readfp()} before calling \method{read()} for any optional
+files:
+
+\begin{verbatim}
+import ConfigParser, os
+
+config = ConfigParser.ConfigParser()
+config.readfp(open('defaults.cfg'))
+config.read(['site.cfg', os.path.expanduser('~/.myapp.cfg')])
+\end{verbatim}
+\versionchanged[Returns list of successfully parsed filenames]{2.4}
+\end{methoddesc}
+
+\begin{methoddesc}{readfp}{fp\optional{, filename}}
+Read and parse configuration data from the file or file-like object in
+\var{fp} (only the \method{readline()} method is used).  If
+\var{filename} is omitted and \var{fp} has a \member{name} attribute,
+that is used for \var{filename}; the default is \samp{<???>}.
+\end{methoddesc}
+
+\begin{methoddesc}{get}{section, option}
+Get an \var{option} value for the named \var{section}.
+\end{methoddesc}
+
+\begin{methoddesc}{getint}{section, option}
+A convenience method which coerces the \var{option} in the specified
+\var{section} to an integer.
+\end{methoddesc}
+
+\begin{methoddesc}{getfloat}{section, option}
+A convenience method which coerces the \var{option} in the specified
+\var{section} to a floating point number.
+\end{methoddesc}
+
+\begin{methoddesc}{getboolean}{section, option}
+A convenience method which coerces the \var{option} in the specified
+\var{section} to a Boolean value.  Note that the accepted values
+for the option are \code{"1"}, \code{"yes"}, \code{"true"}, and \code{"on"},
+which cause this method to return \code{True}, and \code{"0"}, \code{"no"},
+\code{"false"}, and \code{"off"}, which cause it to return \code{False}.  These
+string values are checked in a case-insensitive manner.  Any other value will
+cause it to raise \exception{ValueError}.
+\end{methoddesc}
+
+\begin{methoddesc}{items}{section}
+Return a list of \code{(\var{name}, \var{value})} pairs for each
+option in the given \var{section}.
+\end{methoddesc}
+
+\begin{methoddesc}{set}{section, option, value}
+If the given section exists, set the given option to the specified
+value; otherwise raise \exception{NoSectionError}.  While it is
+possible to use \class{RawConfigParser} (or \class{ConfigParser} with
+\var{raw} parameters set to true) for \emph{internal} storage of
+non-string values, full functionality (including interpolation and
+output to files) can only be achieved using string values.
+\versionadded{1.6}
+\end{methoddesc}
+
+\begin{methoddesc}{write}{fileobject}
+Write a representation of the configuration to the specified file
+object.  This representation can be parsed by a future \method{read()}
+call.
+\versionadded{1.6}
+\end{methoddesc}
+
+\begin{methoddesc}{remove_option}{section, option}
+Remove the specified \var{option} from the specified \var{section}.
+If the section does not exist, raise \exception{NoSectionError}. 
+If the option existed to be removed, return \constant{True};
+otherwise return \constant{False}.
+\versionadded{1.6}
+\end{methoddesc}
+
+\begin{methoddesc}{remove_section}{section}
+Remove the specified \var{section} from the configuration.
+If the section in fact existed, return \code{True}.
+Otherwise return \code{False}.
+\end{methoddesc}
+
+\begin{methoddesc}{optionxform}{option}
+Transforms the option name \var{option} as found in an input file or
+as passed in by  client code to the form that should be used in the
+internal structures.  The default implementation returns a lower-case
+version of \var{option}; subclasses may override this or client code
+can set an attribute of this name on instances to affect this
+behavior.  Setting this to \function{str()}, for example, would make
+option names case sensitive.
+\end{methoddesc}
+
+
+\subsection{ConfigParser Objects \label{ConfigParser-objects}}
+
+The \class{ConfigParser} class extends some methods of the
+\class{RawConfigParser} interface, adding some optional arguments.
+
+\begin{methoddesc}{get}{section, option\optional{, raw\optional{, vars}}}
+Get an \var{option} value for the named \var{section}.  All the
+\character{\%} interpolations are expanded in the return values, based
+on the defaults passed into the constructor, as well as the options
+\var{vars} provided, unless the \var{raw} argument is true.
+\end{methoddesc}
+
+\begin{methoddesc}{items}{section\optional{, raw\optional{, vars}}}
+Return a list of \code{(\var{name}, \var{value})} pairs for each
+option in the given \var{section}. Optional arguments have the
+same meaning as for the \method{get()} method.
+\versionadded{2.3}
+\end{methoddesc}
+
+
+\subsection{SafeConfigParser Objects \label{SafeConfigParser-objects}}
+
+The \class{SafeConfigParser} class implements the same extended
+interface as \class{ConfigParser}, with the following addition:
+
+\begin{methoddesc}{set}{section, option, value}
+If the given section exists, set the given option to the specified
+value; otherwise raise \exception{NoSectionError}.  \var{value} must
+be a string (\class{str} or \class{unicode}); if not,
+\exception{TypeError} is raised.
+\versionadded{2.4}
+\end{methoddesc}

Added: vendor/Python/current/Doc/lib/libcgi.tex
===================================================================
--- vendor/Python/current/Doc/lib/libcgi.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libcgi.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,602 @@
+\section{\module{cgi} ---
+         Common Gateway Interface support.}
+\declaremodule{standard}{cgi}
+
+\modulesynopsis{Common Gateway Interface support, used to interpret
+forms in server-side scripts.}
+
+\indexii{WWW}{server}
+\indexii{CGI}{protocol}
+\indexii{HTTP}{protocol}
+\indexii{MIME}{headers}
+\index{URL}
+
+
+Support module for Common Gateway Interface (CGI) scripts.%
+\index{Common Gateway Interface}
+
+This module defines a number of utilities for use by CGI scripts
+written in Python.
+
+\subsection{Introduction}
+\nodename{cgi-intro}
+
+A CGI script is invoked by an HTTP server, usually to process user
+input submitted through an HTML \code{<FORM>} or \code{<ISINDEX>} element.
+
+Most often, CGI scripts live in the server's special \file{cgi-bin}
+directory.  The HTTP server places all sorts of information about the
+request (such as the client's hostname, the requested URL, the query
+string, and lots of other goodies) in the script's shell environment,
+executes the script, and sends the script's output back to the client.
+
+The script's input is connected to the client too, and sometimes the
+form data is read this way; at other times the form data is passed via
+the ``query string'' part of the URL.  This module is intended
+to take care of the different cases and provide a simpler interface to
+the Python script.  It also provides a number of utilities that help
+in debugging scripts, and the latest addition is support for file
+uploads from a form (if your browser supports it).
+
+The output of a CGI script should consist of two sections, separated
+by a blank line.  The first section contains a number of headers,
+telling the client what kind of data is following.  Python code to
+generate a minimal header section looks like this:
+
+\begin{verbatim}
+print "Content-Type: text/html"     # HTML is following
+print                               # blank line, end of headers
+\end{verbatim}
+
+The second section is usually HTML, which allows the client software
+to display nicely formatted text with header, in-line images, etc.
+Here's Python code that prints a simple piece of HTML:
+
+\begin{verbatim}
+print "<TITLE>CGI script output</TITLE>"
+print "<H1>This is my first CGI script</H1>"
+print "Hello, world!"
+\end{verbatim}
+
+\subsection{Using the cgi module}
+\nodename{Using the cgi module}
+
+Begin by writing \samp{import cgi}.  Do not use \samp{from cgi import
+*} --- the module defines all sorts of names for its own use or for
+backward compatibility that you don't want in your namespace.
+
+When you write a new script, consider adding the line:
+
+\begin{verbatim}
+import cgitb; cgitb.enable()
+\end{verbatim}
+
+This activates a special exception handler that will display detailed
+reports in the Web browser if any errors occur.  If you'd rather not
+show the guts of your program to users of your script, you can have
+the reports saved to files instead, with a line like this:
+
+\begin{verbatim}
+import cgitb; cgitb.enable(display=0, logdir="/tmp")
+\end{verbatim}
+
+It's very helpful to use this feature during script development.
+The reports produced by \refmodule{cgitb} provide information that
+can save you a lot of time in tracking down bugs.  You can always
+remove the \code{cgitb} line later when you have tested your script
+and are confident that it works correctly.
+
+To get at submitted form data,
+it's best to use the \class{FieldStorage} class.  The other classes
+defined in this module are provided mostly for backward compatibility.
+Instantiate it exactly once, without arguments.  This reads the form
+contents from standard input or the environment (depending on the
+value of various environment variables set according to the CGI
+standard).  Since it may consume standard input, it should be
+instantiated only once.
+
+The \class{FieldStorage} instance can be indexed like a Python
+dictionary, and also supports the standard dictionary methods
+\method{has_key()} and \method{keys()}.  The built-in \function{len()}
+is also supported.  Form fields containing empty strings are ignored
+and do not appear in the dictionary; to keep such values, provide
+a true value for the optional \var{keep_blank_values} keyword
+parameter when creating the \class{FieldStorage} instance.
+
+For instance, the following code (which assumes that the 
+\mailheader{Content-Type} header and blank line have already been
+printed) checks that the fields \code{name} and \code{addr} are both
+set to a non-empty string:
+
+\begin{verbatim}
+form = cgi.FieldStorage()
+if not (form.has_key("name") and form.has_key("addr")):
+    print "<H1>Error</H1>"
+    print "Please fill in the name and addr fields."
+    return
+print "<p>name:", form["name"].value
+print "<p>addr:", form["addr"].value
+...further form processing here...
+\end{verbatim}
+
+Here the fields, accessed through \samp{form[\var{key}]}, are
+themselves instances of \class{FieldStorage} (or
+\class{MiniFieldStorage}, depending on the form encoding).
+The \member{value} attribute of the instance yields the string value
+of the field.  The \method{getvalue()} method returns this string value
+directly; it also accepts an optional second argument as a default to
+return if the requested key is not present.
+
+If the submitted form data contains more than one field with the same
+name, the object retrieved by \samp{form[\var{key}]} is not a
+\class{FieldStorage} or \class{MiniFieldStorage}
+instance but a list of such instances.  Similarly, in this situation,
+\samp{form.getvalue(\var{key})} would return a list of strings.
+If you expect this possibility
+(when your HTML form contains multiple fields with the same name), use
+the \function{getlist()} function, which always returns a list of values (so that you
+do not need to special-case the single item case).  For example, this
+code concatenates any number of username fields, separated by
+commas:
+
+\begin{verbatim}
+value = form.getlist("username")
+usernames = ",".join(value)
+\end{verbatim}
+
+If a field represents an uploaded file, accessing the value via the
+\member{value} attribute or the \function{getvalue()} method reads the
+entire file in memory as a string.  This may not be what you want.
+You can test for an uploaded file by testing either the \member{filename}
+attribute or the \member{file} attribute.  You can then read the data at
+leisure from the \member{file} attribute:
+
+\begin{verbatim}
+fileitem = form["userfile"]
+if fileitem.file:
+    # It's an uploaded file; count lines
+    linecount = 0
+    while 1:
+        line = fileitem.file.readline()
+        if not line: break
+        linecount = linecount + 1
+\end{verbatim}
+
+The file upload draft standard entertains the possibility of uploading
+multiple files from one field (using a recursive
+\mimetype{multipart/*} encoding).  When this occurs, the item will be
+a dictionary-like \class{FieldStorage} item.  This can be determined
+by testing its \member{type} attribute, which should be
+\mimetype{multipart/form-data} (or perhaps another MIME type matching
+\mimetype{multipart/*}).  In this case, it can be iterated over
+recursively just like the top-level form object.
+
+When a form is submitted in the ``old'' format (as the query string or
+as a single data part of type
+\mimetype{application/x-www-form-urlencoded}), the items will actually
+be instances of the class \class{MiniFieldStorage}.  In this case, the
+\member{list}, \member{file}, and \member{filename} attributes are
+always \code{None}.
+
+
+\subsection{Higher Level Interface}
+
+\versionadded{2.2}  % XXX: Is this true ? 
+
+The previous section explains how to read CGI form data using the
+\class{FieldStorage} class.  This section describes a higher level
+interface which was added to this class to allow one to do it in a
+more readable and intuitive way.  The interface doesn't make the
+techniques described in previous sections obsolete --- they are still
+useful to process file uploads efficiently, for example.
+
+The interface consists of two simple methods. Using the methods
+you can process form data in a generic way, without the need to worry
+whether only one or more values were posted under one name.
+
+In the previous section, you learned to write following code anytime
+you expected a user to post more than one value under one name:
+
+\begin{verbatim}
+item = form.getvalue("item")
+if isinstance(item, list):
+    # The user is requesting more than one item.
+else:
+    # The user is requesting only one item.
+\end{verbatim}
+
+This situation is common for example when a form contains a group of
+multiple checkboxes with the same name:
+
+\begin{verbatim}
+<input type="checkbox" name="item" value="1" />
+<input type="checkbox" name="item" value="2" />
+\end{verbatim}
+
+In most situations, however, there's only one form control with a
+particular name in a form and then you expect and need only one value
+associated with this name.  So you write a script containing for
+example this code:
+
+\begin{verbatim}
+user = form.getvalue("user").upper()
+\end{verbatim}
+
+The problem with the code is that you should never expect that a
+client will provide valid input to your scripts.  For example, if a
+curious user appends another \samp{user=foo} pair to the query string,
+then the script would crash, because in this situation the
+\code{getvalue("user")} method call returns a list instead of a
+string.  Calling the \method{toupper()} method on a list is not valid
+(since lists do not have a method of this name) and results in an
+\exception{AttributeError} exception.
+
+Therefore, the appropriate way to read form data values was to always
+use the code which checks whether the obtained value is a single value
+or a list of values.  That's annoying and leads to less readable
+scripts.
+
+A more convenient approach is to use the methods \method{getfirst()}
+and \method{getlist()} provided by this higher level interface.
+
+\begin{methoddesc}[FieldStorage]{getfirst}{name\optional{, default}}
+  This method always returns only one value associated with form field
+  \var{name}.  The method returns only the first value in case that
+  more values were posted under such name.  Please note that the order
+  in which the values are received may vary from browser to browser
+  and should not be counted on.\footnote{Note that some recent
+      versions of the HTML specification do state what order the
+      field values should be supplied in, but knowing whether a
+      request was received from a conforming browser, or even from a
+      browser at all, is tedious and error-prone.}  If no such form
+  field or value exists then the method returns the value specified by
+  the optional parameter \var{default}.  This parameter defaults to
+  \code{None} if not specified.
+\end{methoddesc}
+
+\begin{methoddesc}[FieldStorage]{getlist}{name}
+  This method always returns a list of values associated with form
+  field \var{name}.  The method returns an empty list if no such form
+  field or value exists for \var{name}.  It returns a list consisting
+  of one item if only one such value exists.
+\end{methoddesc}
+
+Using these methods you can write nice compact code:
+
+\begin{verbatim}
+import cgi
+form = cgi.FieldStorage()
+user = form.getfirst("user", "").upper()    # This way it's safe.
+for item in form.getlist("item"):
+    do_something(item)
+\end{verbatim}
+
+
+\subsection{Old classes}
+
+These classes, present in earlier versions of the \module{cgi} module,
+are still supported for backward compatibility.  New applications
+should use the \class{FieldStorage} class.
+
+\class{SvFormContentDict} stores single value form content as
+dictionary; it assumes each field name occurs in the form only once.
+
+\class{FormContentDict} stores multiple value form content as a
+dictionary (the form items are lists of values).  Useful if your form
+contains multiple fields with the same name.
+
+Other classes (\class{FormContent}, \class{InterpFormContentDict}) are
+present for backwards compatibility with really old applications only.
+If you still use these and would be inconvenienced when they
+disappeared from a next version of this module, drop me a note.
+
+
+\subsection{Functions}
+\nodename{Functions in cgi module}
+
+These are useful if you want more control, or if you want to employ
+some of the algorithms implemented in this module in other
+circumstances.
+
+\begin{funcdesc}{parse}{fp\optional{, keep_blank_values\optional{,
+                        strict_parsing}}}
+  Parse a query in the environment or from a file (the file defaults
+  to \code{sys.stdin}).  The \var{keep_blank_values} and
+  \var{strict_parsing} parameters are passed to \function{parse_qs()}
+  unchanged.
+\end{funcdesc}
+
+\begin{funcdesc}{parse_qs}{qs\optional{, keep_blank_values\optional{,
+                           strict_parsing}}}
+Parse a query string given as a string argument (data of type 
+\mimetype{application/x-www-form-urlencoded}).  Data are
+returned as a dictionary.  The dictionary keys are the unique query
+variable names and the values are lists of values for each name.
+
+The optional argument \var{keep_blank_values} is
+a flag indicating whether blank values in
+URL encoded queries should be treated as blank strings.  
+A true value indicates that blanks should be retained as 
+blank strings.  The default false value indicates that
+blank values are to be ignored and treated as if they were
+not included.
+
+The optional argument \var{strict_parsing} is a flag indicating what
+to do with parsing errors.  If false (the default), errors
+are silently ignored.  If true, errors raise a \exception{ValueError}
+exception.
+
+Use the \function{\refmodule{urllib}.urlencode()} function to convert
+such dictionaries into query strings.
+
+\end{funcdesc}
+
+\begin{funcdesc}{parse_qsl}{qs\optional{, keep_blank_values\optional{,
+                            strict_parsing}}}
+Parse a query string given as a string argument (data of type 
+\mimetype{application/x-www-form-urlencoded}).  Data are
+returned as a list of name, value pairs.
+
+The optional argument \var{keep_blank_values} is
+a flag indicating whether blank values in
+URL encoded queries should be treated as blank strings.  
+A true value indicates that blanks should be retained as 
+blank strings.  The default false value indicates that
+blank values are to be ignored and treated as if they were
+not included.
+
+The optional argument \var{strict_parsing} is a flag indicating what
+to do with parsing errors.  If false (the default), errors
+are silently ignored.  If true, errors raise a \exception{ValueError}
+exception.
+
+Use the \function{\refmodule{urllib}.urlencode()} function to convert
+such lists of pairs into query strings.
+\end{funcdesc}
+
+\begin{funcdesc}{parse_multipart}{fp, pdict}
+Parse input of type \mimetype{multipart/form-data} (for 
+file uploads).  Arguments are \var{fp} for the input file and
+\var{pdict} for a dictionary containing other parameters in
+the \mailheader{Content-Type} header.
+
+Returns a dictionary just like \function{parse_qs()} keys are the
+field names, each value is a list of values for that field.  This is
+easy to use but not much good if you are expecting megabytes to be
+uploaded --- in that case, use the \class{FieldStorage} class instead
+which is much more flexible.
+
+Note that this does not parse nested multipart parts --- use
+\class{FieldStorage} for that.
+\end{funcdesc}
+
+\begin{funcdesc}{parse_header}{string}
+Parse a MIME header (such as \mailheader{Content-Type}) into a main
+value and a dictionary of parameters.
+\end{funcdesc}
+
+\begin{funcdesc}{test}{}
+Robust test CGI script, usable as main program.
+Writes minimal HTTP headers and formats all information provided to
+the script in HTML form.
+\end{funcdesc}
+
+\begin{funcdesc}{print_environ}{}
+Format the shell environment in HTML.
+\end{funcdesc}
+
+\begin{funcdesc}{print_form}{form}
+Format a form in HTML.
+\end{funcdesc}
+
+\begin{funcdesc}{print_directory}{}
+Format the current directory in HTML.
+\end{funcdesc}
+
+\begin{funcdesc}{print_environ_usage}{}
+Print a list of useful (used by CGI) environment variables in
+HTML.
+\end{funcdesc}
+
+\begin{funcdesc}{escape}{s\optional{, quote}}
+Convert the characters
+\character{\&}, \character{<} and \character{>} in string \var{s} to
+HTML-safe sequences.  Use this if you need to display text that might
+contain such characters in HTML.  If the optional flag \var{quote} is
+true, the quotation mark character (\character{"}) is also translated;
+this helps for inclusion in an HTML attribute value, as in \code{<A
+HREF="...">}.  If the value to be quoted might include single- or
+double-quote characters, or both, consider using the
+\function{quoteattr()} function in the \refmodule{xml.sax.saxutils}
+module instead.
+\end{funcdesc}
+
+
+\subsection{Caring about security \label{cgi-security}}
+
+\indexii{CGI}{security}
+
+There's one important rule: if you invoke an external program (via the
+\function{os.system()} or \function{os.popen()} functions. or others
+with similar functionality), make very sure you don't pass arbitrary
+strings received from the client to the shell.  This is a well-known
+security hole whereby clever hackers anywhere on the Web can exploit a
+gullible CGI script to invoke arbitrary shell commands.  Even parts of
+the URL or field names cannot be trusted, since the request doesn't
+have to come from your form!
+
+To be on the safe side, if you must pass a string gotten from a form
+to a shell command, you should make sure the string contains only
+alphanumeric characters, dashes, underscores, and periods.
+
+
+\subsection{Installing your CGI script on a \UNIX\ system}
+
+Read the documentation for your HTTP server and check with your local
+system administrator to find the directory where CGI scripts should be
+installed; usually this is in a directory \file{cgi-bin} in the server tree.
+
+Make sure that your script is readable and executable by ``others''; the
+\UNIX{} file mode should be \code{0755} octal (use \samp{chmod 0755
+\var{filename}}).  Make sure that the first line of the script contains
+\code{\#!} starting in column 1 followed by the pathname of the Python
+interpreter, for instance:
+
+\begin{verbatim}
+#!/usr/local/bin/python
+\end{verbatim}
+
+Make sure the Python interpreter exists and is executable by ``others''.
+
+Make sure that any files your script needs to read or write are
+readable or writable, respectively, by ``others'' --- their mode
+should be \code{0644} for readable and \code{0666} for writable.  This
+is because, for security reasons, the HTTP server executes your script
+as user ``nobody'', without any special privileges.  It can only read
+(write, execute) files that everybody can read (write, execute).  The
+current directory at execution time is also different (it is usually
+the server's cgi-bin directory) and the set of environment variables
+is also different from what you get when you log in.  In particular, don't
+count on the shell's search path for executables (\envvar{PATH}) or
+the Python module search path (\envvar{PYTHONPATH}) to be set to
+anything interesting.
+
+If you need to load modules from a directory which is not on Python's
+default module search path, you can change the path in your script,
+before importing other modules.  For example:
+
+\begin{verbatim}
+import sys
+sys.path.insert(0, "/usr/home/joe/lib/python")
+sys.path.insert(0, "/usr/local/lib/python")
+\end{verbatim}
+
+(This way, the directory inserted last will be searched first!)
+
+Instructions for non-\UNIX{} systems will vary; check your HTTP server's
+documentation (it will usually have a section on CGI scripts).
+
+
+\subsection{Testing your CGI script}
+
+Unfortunately, a CGI script will generally not run when you try it
+from the command line, and a script that works perfectly from the
+command line may fail mysteriously when run from the server.  There's
+one reason why you should still test your script from the command
+line: if it contains a syntax error, the Python interpreter won't
+execute it at all, and the HTTP server will most likely send a cryptic
+error to the client.
+
+Assuming your script has no syntax errors, yet it does not work, you
+have no choice but to read the next section.
+
+
+\subsection{Debugging CGI scripts} \indexii{CGI}{debugging}
+
+First of all, check for trivial installation errors --- reading the
+section above on installing your CGI script carefully can save you a
+lot of time.  If you wonder whether you have understood the
+installation procedure correctly, try installing a copy of this module
+file (\file{cgi.py}) as a CGI script.  When invoked as a script, the file
+will dump its environment and the contents of the form in HTML form.
+Give it the right mode etc, and send it a request.  If it's installed
+in the standard \file{cgi-bin} directory, it should be possible to send it a
+request by entering a URL into your browser of the form:
+
+\begin{verbatim}
+http://yourhostname/cgi-bin/cgi.py?name=Joe+Blow&addr=At+Home
+\end{verbatim}
+
+If this gives an error of type 404, the server cannot find the script
+-- perhaps you need to install it in a different directory.  If it
+gives another error, there's an installation problem that
+you should fix before trying to go any further.  If you get a nicely
+formatted listing of the environment and form content (in this
+example, the fields should be listed as ``addr'' with value ``At Home''
+and ``name'' with value ``Joe Blow''), the \file{cgi.py} script has been
+installed correctly.  If you follow the same procedure for your own
+script, you should now be able to debug it.
+
+The next step could be to call the \module{cgi} module's
+\function{test()} function from your script: replace its main code
+with the single statement
+
+\begin{verbatim}
+cgi.test()
+\end{verbatim}
+
+This should produce the same results as those gotten from installing
+the \file{cgi.py} file itself.
+
+When an ordinary Python script raises an unhandled exception (for
+whatever reason: of a typo in a module name, a file that can't be
+opened, etc.), the Python interpreter prints a nice traceback and
+exits.  While the Python interpreter will still do this when your CGI
+script raises an exception, most likely the traceback will end up in
+one of the HTTP server's log files, or be discarded altogether.
+
+Fortunately, once you have managed to get your script to execute
+\emph{some} code, you can easily send tracebacks to the Web browser
+using the \refmodule{cgitb} module.  If you haven't done so already,
+just add the line:
+
+\begin{verbatim}
+import cgitb; cgitb.enable()
+\end{verbatim}
+
+to the top of your script.  Then try running it again; when a
+problem occurs, you should see a detailed report that will
+likely make apparent the cause of the crash.
+
+If you suspect that there may be a problem in importing the
+\refmodule{cgitb} module, you can use an even more robust approach
+(which only uses built-in modules):
+
+\begin{verbatim}
+import sys
+sys.stderr = sys.stdout
+print "Content-Type: text/plain"
+print
+...your code here...
+\end{verbatim}
+
+This relies on the Python interpreter to print the traceback.  The
+content type of the output is set to plain text, which disables all
+HTML processing.  If your script works, the raw HTML will be displayed
+by your client.  If it raises an exception, most likely after the
+first two lines have been printed, a traceback will be displayed.
+Because no HTML interpretation is going on, the traceback will be
+readable.
+
+
+\subsection{Common problems and solutions}
+
+\begin{itemize}
+\item Most HTTP servers buffer the output from CGI scripts until the
+script is completed.  This means that it is not possible to display a
+progress report on the client's display while the script is running.
+
+\item Check the installation instructions above.
+
+\item Check the HTTP server's log files.  (\samp{tail -f logfile} in a
+separate window may be useful!)
+
+\item Always check a script for syntax errors first, by doing something
+like \samp{python script.py}.
+
+\item If your script does not have any syntax errors, try adding
+\samp{import cgitb; cgitb.enable()} to the top of the script.
+
+\item When invoking external programs, make sure they can be found.
+Usually, this means using absolute path names --- \envvar{PATH} is
+usually not set to a very useful value in a CGI script.
+
+\item When reading or writing external files, make sure they can be read
+or written by the userid under which your CGI script will be running:
+this is typically the userid under which the web server is running, or some
+explicitly specified userid for a web server's \samp{suexec} feature.
+
+\item Don't try to give a CGI script a set-uid mode.  This doesn't work on
+most systems, and is a security liability as well.
+\end{itemize}
+

Added: vendor/Python/current/Doc/lib/libcgihttp.tex
===================================================================
--- vendor/Python/current/Doc/lib/libcgihttp.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libcgihttp.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,70 @@
+\section{\module{CGIHTTPServer} ---
+         CGI-capable HTTP request handler}
+
+
+\declaremodule{standard}{CGIHTTPServer}
+\sectionauthor{Moshe Zadka}{moshez at zadka.site.co.il}
+\modulesynopsis{This module provides a request handler for HTTP servers
+                which can run CGI scripts.}
+
+
+The \module{CGIHTTPServer} module defines a request-handler class,
+interface compatible with
+\class{BaseHTTPServer.BaseHTTPRequestHandler} and inherits behavior
+from \class{SimpleHTTPServer.SimpleHTTPRequestHandler} but can also
+run CGI scripts.
+
+\note{This module can run CGI scripts on \UNIX{} and Windows systems;
+on Mac OS it will only be able to run Python scripts within the same
+process as itself.}
+
+\note{CGI scripts run by the \class{CGIHTTPRequestHandler} class cannot execute
+redirects (HTTP code 302), because code 200 (script output follows)
+is sent prior to execution of the CGI script.  This pre-empts the status
+code.}
+
+The \module{CGIHTTPServer} module defines the following class:
+
+\begin{classdesc}{CGIHTTPRequestHandler}{request, client_address, server}
+This class is used to serve either files or output of CGI scripts from 
+the current directory and below. Note that mapping HTTP hierarchic
+structure to local directory structure is exactly as in
+\class{SimpleHTTPServer.SimpleHTTPRequestHandler}.
+
+The class will however, run the CGI script, instead of serving it as a
+file, if it guesses it to be a CGI script. Only directory-based CGI
+are used --- the other common server configuration is to treat special
+extensions as denoting CGI scripts.
+
+The \function{do_GET()} and \function{do_HEAD()} functions are
+modified to run CGI scripts and serve the output, instead of serving
+files, if the request leads to somewhere below the
+\code{cgi_directories} path.
+\end{classdesc}
+
+The \class{CGIHTTPRequestHandler} defines the following data member:
+
+\begin{memberdesc}{cgi_directories}
+This defaults to \code{['/cgi-bin', '/htbin']} and describes
+directories to treat as containing CGI scripts.
+\end{memberdesc}
+
+The \class{CGIHTTPRequestHandler} defines the following methods:
+
+\begin{methoddesc}{do_POST}{}
+This method serves the \code{'POST'} request type, only allowed for
+CGI scripts.  Error 501, "Can only POST to CGI scripts", is output
+when trying to POST to a non-CGI url.
+\end{methoddesc}
+
+Note that CGI scripts will be run with UID of user nobody, for security
+reasons. Problems with the CGI script will be translated to error 403.
+
+For example usage, see the implementation of the \function{test()}
+function.
+
+
+\begin{seealso}
+  \seemodule{BaseHTTPServer}{Base class implementation for Web server
+                             and request handler.}
+\end{seealso}

Added: vendor/Python/current/Doc/lib/libcgitb.tex
===================================================================
--- vendor/Python/current/Doc/lib/libcgitb.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libcgitb.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,67 @@
+\section{\module{cgitb} ---
+         Traceback manager for CGI scripts}
+
+\declaremodule{standard}{cgitb}
+\modulesynopsis{Configurable traceback handler for CGI scripts.}
+\moduleauthor{Ka-Ping Yee}{ping at lfw.org}
+\sectionauthor{Fred L. Drake, Jr.}{fdrake at acm.org}
+
+\versionadded{2.2}
+\index{CGI!exceptions}
+\index{CGI!tracebacks}
+\index{exceptions!in CGI scripts}
+\index{tracebacks!in CGI scripts}
+
+The \module{cgitb} module provides a special exception handler for Python
+scripts.  (Its name is a bit misleading.  It was originally designed to
+display extensive traceback information in HTML for CGI scripts.  It was
+later generalized to also display this information in plain text.)  After
+this module is activated, if an uncaught exception occurs, a detailed,
+formatted report will be displayed.  The report
+includes a traceback showing excerpts of the source code for each level,
+as well as the values of the arguments and local variables to currently
+running functions, to help you debug the problem.  Optionally, you can
+save this information to a file instead of sending it to the browser.
+
+To enable this feature, simply add one line to the top of your CGI script:
+
+\begin{verbatim}
+import cgitb; cgitb.enable()
+\end{verbatim}
+
+The options to the \function{enable()} function control whether the
+report is displayed in the browser and whether the report is logged
+to a file for later analysis.
+
+
+\begin{funcdesc}{enable}{\optional{display\optional{, logdir\optional{,
+                         context\optional{, format}}}}}
+  This function causes the \module{cgitb} module to take over the
+  interpreter's default handling for exceptions by setting the
+  value of \code{\refmodule{sys}.excepthook}.
+  \withsubitem{(in module sys)}{\ttindex{excepthook()}}
+
+  The optional argument \var{display} defaults to \code{1} and can be set
+  to \code{0} to suppress sending the traceback to the browser.
+  If the argument \var{logdir} is present, the traceback reports are
+  written to files.  The value of \var{logdir} should be a directory
+  where these files will be placed.
+  The optional argument \var{context} is the number of lines of
+  context to display around the current line of source code in the
+  traceback; this defaults to \code{5}.
+  If the optional argument \var{format} is \code{"html"}, the output is
+  formatted as HTML.  Any other value forces plain text output.  The default
+  value is \code{"html"}.
+\end{funcdesc}
+
+\begin{funcdesc}{handler}{\optional{info}}
+  This function handles an exception using the default settings
+  (that is, show a report in the browser, but don't log to a file).
+  This can be used when you've caught an exception and want to
+  report it using \module{cgitb}.  The optional \var{info} argument
+  should be a 3-tuple containing an exception type, exception
+  value, and traceback object, exactly like the tuple returned by
+  \code{\refmodule{sys}.exc_info()}.  If the \var{info} argument
+  is not supplied, the current exception is obtained from
+  \code{\refmodule{sys}.exc_info()}.
+\end{funcdesc}

Added: vendor/Python/current/Doc/lib/libchunk.tex
===================================================================
--- vendor/Python/current/Doc/lib/libchunk.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libchunk.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,111 @@
+\section{\module{chunk} ---
+	 Read IFF chunked data}
+
+\declaremodule{standard}{chunk}
+\modulesynopsis{Module to read IFF chunks.}
+\moduleauthor{Sjoerd Mullender}{sjoerd at acm.org}
+\sectionauthor{Sjoerd Mullender}{sjoerd at acm.org}
+
+
+
+This module provides an interface for reading files that use EA IFF 85
+chunks.\footnote{``EA IFF 85'' Standard for Interchange Format Files,
+Jerry Morrison, Electronic Arts, January 1985.}  This format is used
+in at least the Audio\index{Audio Interchange File
+Format}\index{AIFF}\index{AIFF-C} Interchange File Format
+(AIFF/AIFF-C) and the Real\index{Real Media File Format} Media File
+Format\index{RMFF} (RMFF).  The WAVE audio file format is closely
+related and can also be read using this module.
+
+A chunk has the following structure:
+
+\begin{tableiii}{c|c|l}{textrm}{Offset}{Length}{Contents}
+  \lineiii{0}{4}{Chunk ID}
+  \lineiii{4}{4}{Size of chunk in big-endian byte order, not including the 
+                 header}
+  \lineiii{8}{\var{n}}{Data bytes, where \var{n} is the size given in
+                       the preceding field}
+  \lineiii{8 + \var{n}}{0 or 1}{Pad byte needed if \var{n} is odd and
+                                chunk alignment is used}
+\end{tableiii}
+
+The ID is a 4-byte string which identifies the type of chunk.
+
+The size field (a 32-bit value, encoded using big-endian byte order)
+gives the size of the chunk data, not including the 8-byte header.
+
+Usually an IFF-type file consists of one or more chunks.  The proposed
+usage of the \class{Chunk} class defined here is to instantiate an
+instance at the start of each chunk and read from the instance until
+it reaches the end, after which a new instance can be instantiated.
+At the end of the file, creating a new instance will fail with a
+\exception{EOFError} exception.
+
+\begin{classdesc}{Chunk}{file\optional{, align, bigendian, inclheader}}
+Class which represents a chunk.  The \var{file} argument is expected
+to be a file-like object.  An instance of this class is specifically
+allowed.  The only method that is needed is \method{read()}.  If the
+methods \method{seek()} and \method{tell()} are present and don't
+raise an exception, they are also used.  If these methods are present
+and raise an exception, they are expected to not have altered the
+object.  If the optional argument \var{align} is true, chunks are
+assumed to be aligned on 2-byte boundaries.  If \var{align} is
+false, no alignment is assumed.  The default value is true.  If the
+optional argument \var{bigendian} is false, the chunk size is assumed
+to be in little-endian order.  This is needed for WAVE audio files.
+The default value is true.  If the optional argument \var{inclheader}
+is true, the size given in the chunk header includes the size of the
+header.  The default value is false.
+\end{classdesc}
+
+A \class{Chunk} object supports the following methods:
+
+\begin{methoddesc}{getname}{}
+Returns the name (ID) of the chunk.  This is the first 4 bytes of the
+chunk.
+\end{methoddesc}
+
+\begin{methoddesc}{getsize}{}
+Returns the size of the chunk.
+\end{methoddesc}
+
+\begin{methoddesc}{close}{}
+Close and skip to the end of the chunk.  This does not close the
+underlying file.
+\end{methoddesc}
+
+The remaining methods will raise \exception{IOError} if called after
+the \method{close()} method has been called.
+
+\begin{methoddesc}{isatty}{}
+Returns \code{False}.
+\end{methoddesc}
+
+\begin{methoddesc}{seek}{pos\optional{, whence}}
+Set the chunk's current position.  The \var{whence} argument is
+optional and defaults to \code{0} (absolute file positioning); other
+values are \code{1} (seek relative to the current position) and
+\code{2} (seek relative to the file's end).  There is no return value.
+If the underlying file does not allow seek, only forward seeks are
+allowed.
+\end{methoddesc}
+
+\begin{methoddesc}{tell}{}
+Return the current position into the chunk.
+\end{methoddesc}
+
+\begin{methoddesc}{read}{\optional{size}}
+Read at most \var{size} bytes from the chunk (less if the read hits
+the end of the chunk before obtaining \var{size} bytes).  If the
+\var{size} argument is negative or omitted, read all data until the
+end of the chunk.  The bytes are returned as a string object.  An
+empty string is returned when the end of the chunk is encountered
+immediately.
+\end{methoddesc}
+
+\begin{methoddesc}{skip}{}
+Skip to the end of the chunk.  All further calls to \method{read()}
+for the chunk will return \code{''}.  If you are not interested in the
+contents of the chunk, this method should be called so that the file
+points to the start of the next chunk.
+\end{methoddesc}

Added: vendor/Python/current/Doc/lib/libcmath.tex
===================================================================
--- vendor/Python/current/Doc/lib/libcmath.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libcmath.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,142 @@
+\section{\module{cmath} ---
+         Mathematical functions for complex numbers}
+
+\declaremodule{builtin}{cmath}
+\modulesynopsis{Mathematical functions for complex numbers.}
+
+This module is always available.  It provides access to mathematical
+functions for complex numbers.  The functions are:
+
+\begin{funcdesc}{acos}{x}
+Return the arc cosine of \var{x}.
+There are two branch cuts:
+One extends right from 1 along the real axis to \infinity, continuous
+from below.
+The other extends left from -1 along the real axis to -\infinity,
+continuous from above.
+\end{funcdesc}
+
+\begin{funcdesc}{acosh}{x}
+Return the hyperbolic arc cosine of \var{x}.
+There is one branch cut, extending left from 1 along the real axis
+to -\infinity, continuous from above.
+\end{funcdesc}
+
+\begin{funcdesc}{asin}{x}
+Return the arc sine of \var{x}.
+This has the same branch cuts as \function{acos()}.
+\end{funcdesc}
+
+\begin{funcdesc}{asinh}{x}
+Return the hyperbolic arc sine of \var{x}.
+There are two branch cuts, extending left from \plusminus\code{1j} to
+\plusminus-\infinity\code{j}, both continuous from above.
+These branch cuts should be considered a bug to be corrected in a
+future release.
+The correct branch cuts should extend along the imaginary axis,
+one from \code{1j} up to \infinity\code{j} and continuous from the
+right, and one from -\code{1j} down to -\infinity\code{j} and
+continuous from the left.
+\end{funcdesc}
+
+\begin{funcdesc}{atan}{x}
+Return the arc tangent of \var{x}.
+There are two branch cuts:
+One extends from \code{1j} along the imaginary axis to
+\infinity\code{j}, continuous from the left.
+The other extends from -\code{1j} along the imaginary axis to
+-\infinity\code{j}, continuous from the left.
+(This should probably be changed so the upper cut becomes continuous
+from the other side.)
+\end{funcdesc}
+
+\begin{funcdesc}{atanh}{x}
+Return the hyperbolic arc tangent of \var{x}.
+There are two branch cuts:
+One extends from 1 along the real axis to \infinity, continuous
+from above.
+The other extends from -1 along the real axis to -\infinity,
+continuous from above.
+(This should probably be changed so the right cut becomes continuous from
+the other side.)
+\end{funcdesc}
+
+\begin{funcdesc}{cos}{x}
+Return the cosine of \var{x}.
+\end{funcdesc}
+
+\begin{funcdesc}{cosh}{x}
+Return the hyperbolic cosine of \var{x}.
+\end{funcdesc}
+
+\begin{funcdesc}{exp}{x}
+Return the exponential value \code{e**\var{x}}.
+\end{funcdesc}
+
+\begin{funcdesc}{log}{x\optional{, base}}
+Returns the logarithm of \var{x} to the given \var{base}.
+If the \var{base} is not specified, returns the natural logarithm of \var{x}.
+There is one branch cut, from 0 along the negative real axis to
+-\infinity, continuous from above.
+\versionchanged[\var{base} argument added]{2.4}
+\end{funcdesc}
+
+\begin{funcdesc}{log10}{x}
+Return the base-10 logarithm of \var{x}.
+This has the same branch cut as \function{log()}.
+\end{funcdesc}
+
+\begin{funcdesc}{sin}{x}
+Return the sine of \var{x}.
+\end{funcdesc}
+
+\begin{funcdesc}{sinh}{x}
+Return the hyperbolic sine of \var{x}.
+\end{funcdesc}
+
+\begin{funcdesc}{sqrt}{x}
+Return the square root of \var{x}.
+This has the same branch cut as \function{log()}.
+\end{funcdesc}
+
+\begin{funcdesc}{tan}{x}
+Return the tangent of \var{x}.
+\end{funcdesc}
+
+\begin{funcdesc}{tanh}{x}
+Return the hyperbolic tangent of \var{x}.
+\end{funcdesc}
+
+The module also defines two mathematical constants:
+
+\begin{datadesc}{pi}
+The mathematical constant \emph{pi}, as a real.
+\end{datadesc}
+
+\begin{datadesc}{e}
+The mathematical constant \emph{e}, as a real.
+\end{datadesc}
+
+Note that the selection of functions is similar, but not identical, to
+that in module \refmodule{math}\refbimodindex{math}.  The reason for having
+two modules is that some users aren't interested in complex numbers,
+and perhaps don't even know what they are.  They would rather have
+\code{math.sqrt(-1)} raise an exception than return a complex number.
+Also note that the functions defined in \module{cmath} always return a
+complex number, even if the answer can be expressed as a real number
+(in which case the complex number has an imaginary part of zero).
+
+A note on branch cuts: They are curves along which the given function
+fails to be continuous.  They are a necessary feature of many complex
+functions.  It is assumed that if you need to compute with complex
+functions, you will understand about branch cuts.  Consult almost any
+(not too elementary) book on complex variables for enlightenment.  For
+information of the proper choice of branch cuts for numerical
+purposes, a good reference should be the following:
+
+\begin{seealso}
+  \seetext{Kahan, W:  Branch cuts for complex elementary functions;
+           or, Much ado about nothing's sign bit.  In Iserles, A.,
+           and Powell, M. (eds.), \citetitle{The state of the art in
+           numerical analysis}. Clarendon Press (1987) pp165-211.}
+\end{seealso}

Added: vendor/Python/current/Doc/lib/libcmd.tex
===================================================================
--- vendor/Python/current/Doc/lib/libcmd.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libcmd.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,198 @@
+\section{\module{cmd} ---
+         Support for line-oriented command interpreters}
+
+\declaremodule{standard}{cmd}
+\sectionauthor{Eric S. Raymond}{esr at snark.thyrsus.com}
+\modulesynopsis{Build line-oriented command interpreters.}
+
+
+The \class{Cmd} class provides a simple framework for writing
+line-oriented command interpreters.  These are often useful for
+test harnesses, administrative tools, and prototypes that will
+later be wrapped in a more sophisticated interface.
+
+\begin{classdesc}{Cmd}{\optional{completekey\optional{,
+                       stdin\optional{, stdout}}}}
+A \class{Cmd} instance or subclass instance is a line-oriented
+interpreter framework.  There is no good reason to instantiate
+\class{Cmd} itself; rather, it's useful as a superclass of an
+interpreter class you define yourself in order to inherit
+\class{Cmd}'s methods and encapsulate action methods.
+
+The optional argument \var{completekey} is the \refmodule{readline} name
+of a completion key; it defaults to \kbd{Tab}. If \var{completekey} is
+not \constant{None} and \refmodule{readline} is available, command completion
+is done automatically.
+
+The optional arguments \var{stdin} and \var{stdout} specify the 
+input and output file objects that the Cmd instance or subclass 
+instance will use for input and output. If not specified, they
+will default to \var{sys.stdin} and \var{sys.stdout}.
+
+\versionchanged[The \var{stdin} and \var{stdout} parameters were added]{2.3}
+\end{classdesc}
+
+\subsection{Cmd Objects}
+\label{Cmd-objects}
+
+A \class{Cmd} instance has the following methods:
+
+\begin{methoddesc}{cmdloop}{\optional{intro}}
+Repeatedly issue a prompt, accept input, parse an initial prefix off
+the received input, and dispatch to action methods, passing them the
+remainder of the line as argument.
+
+The optional argument is a banner or intro string to be issued before the
+first prompt (this overrides the \member{intro} class member).
+
+If the \refmodule{readline} module is loaded, input will automatically
+inherit \program{bash}-like history-list editing (e.g. \kbd{Control-P}
+scrolls back to the last command, \kbd{Control-N} forward to the next
+one, \kbd{Control-F} moves the cursor to the right non-destructively,
+\kbd{Control-B} moves the cursor to the left non-destructively, etc.).
+
+An end-of-file on input is passed back as the string \code{'EOF'}.
+
+An interpreter instance will recognize a command name \samp{foo} if
+and only if it has a method \method{do_foo()}.  As a special case,
+a line beginning with the character \character{?} is dispatched to
+the method \method{do_help()}.  As another special case, a line
+beginning with the character \character{!} is dispatched to the
+method \method{do_shell()} (if such a method is defined).
+
+This method will return when the \method{postcmd()} method returns a
+true value.  The \var{stop} argument to \method{postcmd()} is the
+return value from the command's corresponding \method{do_*()} method.
+
+If completion is enabled, completing commands will be done
+automatically, and completing of commands args is done by calling
+\method{complete_foo()} with arguments \var{text}, \var{line},
+\var{begidx}, and \var{endidx}.  \var{text} is the string prefix we
+are attempting to match: all returned matches must begin with it.
+\var{line} is the current input line with leading whitespace removed,
+\var{begidx} and \var{endidx} are the beginning and ending indexes
+of the prefix text, which could be used to provide different
+completion depending upon which position the argument is in.
+
+All subclasses of \class{Cmd} inherit a predefined \method{do_help()}.
+This method, called with an argument \code{'bar'}, invokes the
+corresponding method \method{help_bar()}.  With no argument,
+\method{do_help()} lists all available help topics (that is, all
+commands with corresponding \method{help_*()} methods), and also lists
+any undocumented commands.
+\end{methoddesc}
+
+\begin{methoddesc}{onecmd}{str}
+Interpret the argument as though it had been typed in response to the
+prompt.  This may be overridden, but should not normally need to be;
+see the \method{precmd()} and \method{postcmd()} methods for useful
+execution hooks.  The return value is a flag indicating whether
+interpretation of commands by the interpreter should stop.  If there
+is a \method{do_*()} method for the command \var{str}, the return
+value of that method is returned, otherwise the return value from the
+\method{default()} method is returned.
+\end{methoddesc}
+
+\begin{methoddesc}{emptyline}{}
+Method called when an empty line is entered in response to the prompt.
+If this method is not overridden, it repeats the last nonempty command
+entered.  
+\end{methoddesc}
+
+\begin{methoddesc}{default}{line}
+Method called on an input line when the command prefix is not
+recognized. If this method is not overridden, it prints an
+error message and returns.
+\end{methoddesc}
+
+\begin{methoddesc}{completedefault}{text, line, begidx, endidx}
+Method called to complete an input line when no command-specific
+\method{complete_*()} method is available.  By default, it returns an
+empty list.
+\end{methoddesc}
+
+\begin{methoddesc}{precmd}{line}
+Hook method executed just before the command line \var{line} is
+interpreted, but after the input prompt is generated and issued.  This
+method is a stub in \class{Cmd}; it exists to be overridden by
+subclasses.  The return value is used as the command which will be
+executed by the \method{onecmd()} method; the \method{precmd()}
+implementation may re-write the command or simply return \var{line}
+unchanged.
+\end{methoddesc}
+
+\begin{methoddesc}{postcmd}{stop, line}
+Hook method executed just after a command dispatch is finished.  This
+method is a stub in \class{Cmd}; it exists to be overridden by
+subclasses.  \var{line} is the command line which was executed, and
+\var{stop} is a flag which indicates whether execution will be
+terminated after the call to \method{postcmd()}; this will be the
+return value of the \method{onecmd()} method.  The return value of
+this method will be used as the new value for the internal flag which
+corresponds to \var{stop}; returning false will cause interpretation
+to continue.
+\end{methoddesc}
+
+\begin{methoddesc}{preloop}{}
+Hook method executed once when \method{cmdloop()} is called.  This
+method is a stub in \class{Cmd}; it exists to be overridden by
+subclasses.
+\end{methoddesc}
+
+\begin{methoddesc}{postloop}{}
+Hook method executed once when \method{cmdloop()} is about to return.
+This method is a stub in \class{Cmd}; it exists to be overridden by
+subclasses.
+\end{methoddesc}
+
+Instances of \class{Cmd} subclasses have some public instance variables:
+
+\begin{memberdesc}{prompt}
+The prompt issued to solicit input.
+\end{memberdesc}
+
+\begin{memberdesc}{identchars}
+The string of characters accepted for the command prefix.
+\end{memberdesc}
+
+\begin{memberdesc}{lastcmd}
+The last nonempty command prefix seen. 
+\end{memberdesc}
+
+\begin{memberdesc}{intro}
+A string to issue as an intro or banner.  May be overridden by giving
+the \method{cmdloop()} method an argument.
+\end{memberdesc}
+
+\begin{memberdesc}{doc_header}
+The header to issue if the help output has a section for documented
+commands.
+\end{memberdesc}
+
+\begin{memberdesc}{misc_header}
+The header to issue if the help output has a section for miscellaneous 
+help topics (that is, there are \method{help_*()} methods without
+corresponding \method{do_*()} methods).
+\end{memberdesc}
+
+\begin{memberdesc}{undoc_header}
+The header to issue if the help output has a section for undocumented 
+commands (that is, there are \method{do_*()} methods without
+corresponding \method{help_*()} methods).
+\end{memberdesc}
+
+\begin{memberdesc}{ruler}
+The character used to draw separator lines under the help-message
+headers.  If empty, no ruler line is drawn.  It defaults to
+\character{=}.
+\end{memberdesc}
+
+\begin{memberdesc}{use_rawinput}
+A flag, defaulting to true.  If true, \method{cmdloop()} uses
+\function{raw_input()} to display a prompt and read the next command;
+if false, \method{sys.stdout.write()} and
+\method{sys.stdin.readline()} are used. (This means that by
+importing \refmodule{readline}, on systems that support it, the
+interpreter will automatically support \program{Emacs}-like line editing 
+and command-history keystrokes.)
+\end{memberdesc}

Added: vendor/Python/current/Doc/lib/libcmp.tex
===================================================================
--- vendor/Python/current/Doc/lib/libcmp.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libcmp.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,36 @@
+\section{\module{cmp} ---
+         File comparisons}
+
+\declaremodule{standard}{cmp}
+\sectionauthor{Moshe Zadka}{moshez at zadka.site.co.il}
+\modulesynopsis{Compare files very efficiently.}
+
+\deprecated{1.6}{Use the \refmodule{filecmp} module instead.}
+
+The \module{cmp} module defines a function to compare files, taking all
+sort of short-cuts to make it a highly efficient operation.
+
+The \module{cmp} module defines the following function:
+
+\begin{funcdesc}{cmp}{f1, f2}
+Compare two files given as names. The following tricks are used to
+optimize the comparisons:
+
+\begin{itemize}
+        \item Files with identical type, size and mtime are assumed equal.
+        \item Files with different type or size are never equal.
+        \item The module only compares files it already compared if their
+        signature (type, size and mtime) changed.
+        \item No external programs are called.
+\end{itemize}
+\end{funcdesc}
+
+Example:
+
+\begin{verbatim}
+>>> import cmp
+>>> cmp.cmp('libundoc.tex', 'libundoc.tex')
+1
+>>> cmp.cmp('libundoc.tex', 'lib.tex')
+0
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/libcmpcache.tex
===================================================================
--- vendor/Python/current/Doc/lib/libcmpcache.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libcmpcache.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,21 @@
+\section{\module{cmpcache} ---
+         Efficient file comparisons}
+
+\declaremodule{standard}{cmpcache}
+\sectionauthor{Moshe Zadka}{moshez at zadka.site.co.il}
+\modulesynopsis{Compare files very efficiently.}
+
+\deprecated{1.6}{Use the \refmodule{filecmp} module instead.}
+
+The \module{cmpcache} module provides an identical interface and similar
+functionality as the \refmodule{cmp} module, but can be a bit more efficient
+as it uses \function{statcache.stat()} instead of \function{os.stat()}
+(see the \refmodule{statcache} module for information on the
+difference).
+
+\note{Using the \refmodule{statcache} module to provide
+\function{stat()} information results in trashing the cache
+invalidation mechanism: results are not as reliable.  To ensure
+``current'' results, use \function{cmp.cmp()} instead of the version
+defined in this module, or use \function{statcache.forget()} to
+invalidate the appropriate entries.}

Added: vendor/Python/current/Doc/lib/libcode.tex
===================================================================
--- vendor/Python/current/Doc/lib/libcode.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libcode.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,173 @@
+\section{\module{code} ---
+         Interpreter base classes}
+\declaremodule{standard}{code}
+
+\modulesynopsis{Base classes for interactive Python interpreters.}
+
+
+The \code{code} module provides facilities to implement
+read-eval-print loops in Python.  Two classes and convenience
+functions are included which can be used to build applications which
+provide an interactive interpreter prompt.
+
+
+\begin{classdesc}{InteractiveInterpreter}{\optional{locals}}
+This class deals with parsing and interpreter state (the user's
+namespace); it does not deal with input buffering or prompting or
+input file naming (the filename is always passed in explicitly).
+The optional \var{locals} argument specifies the dictionary in
+which code will be executed; it defaults to a newly created
+dictionary with key \code{'__name__'} set to \code{'__console__'}
+and key \code{'__doc__'} set to \code{None}.
+\end{classdesc}
+
+\begin{classdesc}{InteractiveConsole}{\optional{locals\optional{, filename}}}
+Closely emulate the behavior of the interactive Python interpreter.
+This class builds on \class{InteractiveInterpreter} and adds
+prompting using the familiar \code{sys.ps1} and \code{sys.ps2}, and
+input buffering.
+\end{classdesc}
+
+
+\begin{funcdesc}{interact}{\optional{banner\optional{,
+                           readfunc\optional{, local}}}}
+Convenience function to run a read-eval-print loop.  This creates a
+new instance of \class{InteractiveConsole} and sets \var{readfunc}
+to be used as the \method{raw_input()} method, if provided.  If
+\var{local} is provided, it is passed to the
+\class{InteractiveConsole} constructor for use as the default
+namespace for the interpreter loop.  The \method{interact()} method
+of the instance is then run with \var{banner} passed as the banner
+to use, if provided.  The console object is discarded after use.
+\end{funcdesc}
+
+\begin{funcdesc}{compile_command}{source\optional{,
+                                  filename\optional{, symbol}}}
+This function is useful for programs that want to emulate Python's
+interpreter main loop (a.k.a. the read-eval-print loop).  The tricky
+part is to determine when the user has entered an incomplete command
+that can be completed by entering more text (as opposed to a
+complete command or a syntax error).  This function
+\emph{almost} always makes the same decision as the real interpreter
+main loop.
+
+\var{source} is the source string; \var{filename} is the optional
+filename from which source was read, defaulting to \code{'<input>'};
+and \var{symbol} is the optional grammar start symbol, which should
+be either \code{'single'} (the default) or \code{'eval'}.
+
+Returns a code object (the same as \code{compile(\var{source},
+\var{filename}, \var{symbol})}) if the command is complete and
+valid; \code{None} if the command is incomplete; raises
+\exception{SyntaxError} if the command is complete and contains a
+syntax error, or raises \exception{OverflowError} or
+\exception{ValueError} if the command contains an invalid literal.
+\end{funcdesc}
+
+
+\subsection{Interactive Interpreter Objects
+            \label{interpreter-objects}}
+
+\begin{methoddesc}{runsource}{source\optional{, filename\optional{, symbol}}}
+Compile and run some source in the interpreter.
+Arguments are the same as for \function{compile_command()}; the
+default for \var{filename} is \code{'<input>'}, and for
+\var{symbol} is \code{'single'}.  One several things can happen:
+
+\begin{itemize}
+\item
+The input is incorrect; \function{compile_command()} raised an
+exception (\exception{SyntaxError} or \exception{OverflowError}).  A
+syntax traceback will be printed by calling the
+\method{showsyntaxerror()} method.  \method{runsource()} returns
+\code{False}.
+
+\item
+The input is incomplete, and more input is required;
+\function{compile_command()} returned \code{None}.
+\method{runsource()} returns \code{True}.
+
+\item
+The input is complete; \function{compile_command()} returned a code
+object.  The code is executed by calling the \method{runcode()} (which
+also handles run-time exceptions, except for \exception{SystemExit}).
+\method{runsource()} returns \code{False}.
+\end{itemize}
+
+The return value can be used to decide whether to use
+\code{sys.ps1} or \code{sys.ps2} to prompt the next line.
+\end{methoddesc}
+
+\begin{methoddesc}{runcode}{code}
+Execute a code object.
+When an exception occurs, \method{showtraceback()} is called to
+display a traceback.  All exceptions are caught except
+\exception{SystemExit}, which is allowed to propagate.
+
+A note about \exception{KeyboardInterrupt}: this exception may occur
+elsewhere in this code, and may not always be caught.  The caller
+should be prepared to deal with it.
+\end{methoddesc}
+
+\begin{methoddesc}{showsyntaxerror}{\optional{filename}}
+Display the syntax error that just occurred.  This does not display
+a stack trace because there isn't one for syntax errors.
+If \var{filename} is given, it is stuffed into the exception instead
+of the default filename provided by Python's parser, because it
+always uses \code{'<string>'} when reading from a string.
+The output is written by the \method{write()} method.
+\end{methoddesc}
+
+\begin{methoddesc}{showtraceback}{}
+Display the exception that just occurred.  We remove the first stack
+item because it is within the interpreter object implementation.
+The output is written by the \method{write()} method.
+\end{methoddesc}
+
+\begin{methoddesc}{write}{data}
+Write a string to the standard error stream (\code{sys.stderr}).
+Derived classes should override this to provide the appropriate output
+handling as needed.
+\end{methoddesc}
+
+
+\subsection{Interactive Console Objects
+            \label{console-objects}}
+
+The \class{InteractiveConsole} class is a subclass of
+\class{InteractiveInterpreter}, and so offers all the methods of the
+interpreter objects as well as the following additions.
+
+\begin{methoddesc}{interact}{\optional{banner}}
+Closely emulate the interactive Python console.
+The optional banner argument specify the banner to print before the
+first interaction; by default it prints a banner similar to the one
+printed by the standard Python interpreter, followed by the class
+name of the console object in parentheses (so as not to confuse this
+with the real interpreter -- since it's so close!).
+\end{methoddesc}
+
+\begin{methoddesc}{push}{line}
+Push a line of source text to the interpreter.
+The line should not have a trailing newline; it may have internal
+newlines.  The line is appended to a buffer and the interpreter's
+\method{runsource()} method is called with the concatenated contents
+of the buffer as source.  If this indicates that the command was
+executed or invalid, the buffer is reset; otherwise, the command is
+incomplete, and the buffer is left as it was after the line was
+appended.  The return value is \code{True} if more input is required,
+\code{False} if the line was dealt with in some way (this is the same as
+\method{runsource()}).
+\end{methoddesc}
+
+\begin{methoddesc}{resetbuffer}{}
+Remove any unhandled source text from the input buffer.
+\end{methoddesc}
+
+\begin{methoddesc}{raw_input}{\optional{prompt}}
+Write a prompt and read a line.  The returned line does not include
+the trailing newline.  When the user enters the \EOF{} key sequence,
+\exception{EOFError} is raised.  The base implementation uses the
+built-in function \function{raw_input()}; a subclass may replace this
+with a different implementation.
+\end{methoddesc}

Added: vendor/Python/current/Doc/lib/libcodecs.tex
===================================================================
--- vendor/Python/current/Doc/lib/libcodecs.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libcodecs.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1348 @@
+\section{\module{codecs} ---
+         Codec registry and base classes}
+
+\declaremodule{standard}{codecs}
+\modulesynopsis{Encode and decode data and streams.}
+\moduleauthor{Marc-Andre Lemburg}{mal at lemburg.com}
+\sectionauthor{Marc-Andre Lemburg}{mal at lemburg.com}
+\sectionauthor{Martin v. L\"owis}{martin at v.loewis.de}
+
+\index{Unicode}
+\index{Codecs}
+\indexii{Codecs}{encode}
+\indexii{Codecs}{decode}
+\index{streams}
+\indexii{stackable}{streams}
+
+
+This module defines base classes for standard Python codecs (encoders
+and decoders) and provides access to the internal Python codec
+registry which manages the codec and error handling lookup process.
+
+It defines the following functions:
+
+\begin{funcdesc}{register}{search_function}
+Register a codec search function. Search functions are expected to
+take one argument, the encoding name in all lower case letters, and
+return a \class{CodecInfo} object having the following attributes:
+
+\begin{itemize}
+  \item \code{name} The name of the encoding;
+  \item \code{encoder} The stateless encoding function;
+  \item \code{decoder} The stateless decoding function;
+  \item \code{incrementalencoder} An incremental encoder class or factory function;
+  \item \code{incrementaldecoder} An incremental decoder class or factory function;
+  \item \code{streamwriter} A stream writer class or factory function;
+  \item \code{streamreader} A stream reader class or factory function.
+\end{itemize}
+
+The various functions or classes take the following arguments:
+
+  \var{encoder} and \var{decoder}: These must be functions or methods
+  which have the same interface as the
+  \method{encode()}/\method{decode()} methods of Codec instances (see
+  Codec Interface). The functions/methods are expected to work in a
+  stateless mode.
+
+  \var{incrementalencoder} and \var{incrementalencoder}: These have to be
+  factory functions providing the following interface:
+
+        \code{factory(\var{errors}='strict')}
+
+  The factory functions must return objects providing the interfaces
+  defined by the base classes \class{IncrementalEncoder} and
+  \class{IncrementalEncoder}, respectively. Incremental codecs can maintain
+  state.
+
+  \var{streamreader} and \var{streamwriter}: These have to be
+  factory functions providing the following interface:
+
+        \code{factory(\var{stream}, \var{errors}='strict')}
+
+  The factory functions must return objects providing the interfaces
+  defined by the base classes \class{StreamWriter} and
+  \class{StreamReader}, respectively. Stream codecs can maintain
+  state.
+
+  Possible values for errors are \code{'strict'} (raise an exception
+  in case of an encoding error), \code{'replace'} (replace malformed
+  data with a suitable replacement marker, such as \character{?}),
+  \code{'ignore'} (ignore malformed data and continue without further
+  notice), \code{'xmlcharrefreplace'} (replace with the appropriate XML
+  character reference (for encoding only)) and \code{'backslashreplace'}
+  (replace with backslashed escape sequences (for encoding only)) as
+  well as any other error handling name defined via
+  \function{register_error()}.
+
+In case a search function cannot find a given encoding, it should
+return \code{None}.
+\end{funcdesc}
+
+\begin{funcdesc}{lookup}{encoding}
+Looks up the codec info in the Python codec registry and returns a
+\class{CodecInfo} object as defined above.
+
+Encodings are first looked up in the registry's cache. If not found,
+the list of registered search functions is scanned. If no \class{CodecInfo}
+object is found, a \exception{LookupError} is raised. Otherwise, the
+\class{CodecInfo} object is stored in the cache and returned to the caller.
+\end{funcdesc}
+
+To simplify access to the various codecs, the module provides these
+additional functions which use \function{lookup()} for the codec
+lookup:
+
+\begin{funcdesc}{getencoder}{encoding}
+Look up the codec for the given encoding and return its encoder
+function.
+
+Raises a \exception{LookupError} in case the encoding cannot be found.
+\end{funcdesc}
+
+\begin{funcdesc}{getdecoder}{encoding}
+Look up the codec for the given encoding and return its decoder
+function.
+
+Raises a \exception{LookupError} in case the encoding cannot be found.
+\end{funcdesc}
+
+\begin{funcdesc}{getincrementalencoder}{encoding}
+Look up the codec for the given encoding and return its incremental encoder
+class or factory function.
+
+Raises a \exception{LookupError} in case the encoding cannot be found or the
+codec doesn't support an incremental encoder.
+\versionadded{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{getincrementaldecoder}{encoding}
+Look up the codec for the given encoding and return its incremental decoder
+class or factory function.
+
+Raises a \exception{LookupError} in case the encoding cannot be found or the
+codec doesn't support an incremental decoder.
+\versionadded{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{getreader}{encoding}
+Look up the codec for the given encoding and return its StreamReader
+class or factory function.
+
+Raises a \exception{LookupError} in case the encoding cannot be found.
+\end{funcdesc}
+
+\begin{funcdesc}{getwriter}{encoding}
+Look up the codec for the given encoding and return its StreamWriter
+class or factory function.
+
+Raises a \exception{LookupError} in case the encoding cannot be found.
+\end{funcdesc}
+
+\begin{funcdesc}{register_error}{name, error_handler}
+Register the error handling function \var{error_handler} under the
+name \var{name}. \var{error_handler} will be called during encoding
+and decoding in case of an error, when \var{name} is specified as the
+errors parameter.
+
+For encoding \var{error_handler} will be called with a
+\exception{UnicodeEncodeError} instance, which contains information about
+the location of the error. The error handler must either raise this or
+a different exception or return a tuple with a replacement for the
+unencodable part of the input and a position where encoding should
+continue. The encoder will encode the replacement and continue encoding
+the original input at the specified position. Negative position values
+will be treated as being relative to the end of the input string. If the
+resulting position is out of bound an \exception{IndexError} will be raised.
+
+Decoding and translating works similar, except \exception{UnicodeDecodeError}
+or \exception{UnicodeTranslateError} will be passed to the handler and
+that the replacement from the error handler will be put into the output
+directly.
+\end{funcdesc}
+
+\begin{funcdesc}{lookup_error}{name}
+Return the error handler previously registered under the name \var{name}.
+
+Raises a \exception{LookupError} in case the handler cannot be found.
+\end{funcdesc}
+
+\begin{funcdesc}{strict_errors}{exception}
+Implements the \code{strict} error handling.
+\end{funcdesc}
+
+\begin{funcdesc}{replace_errors}{exception}
+Implements the \code{replace} error handling.
+\end{funcdesc}
+
+\begin{funcdesc}{ignore_errors}{exception}
+Implements the \code{ignore} error handling.
+\end{funcdesc}
+
+\begin{funcdesc}{xmlcharrefreplace_errors_errors}{exception}
+Implements the \code{xmlcharrefreplace} error handling.
+\end{funcdesc}
+
+\begin{funcdesc}{backslashreplace_errors_errors}{exception}
+Implements the \code{backslashreplace} error handling.
+\end{funcdesc}
+
+To simplify working with encoded files or stream, the module
+also defines these utility functions:
+
+\begin{funcdesc}{open}{filename, mode\optional{, encoding\optional{,
+                       errors\optional{, buffering}}}}
+Open an encoded file using the given \var{mode} and return
+a wrapped version providing transparent encoding/decoding.
+
+\note{The wrapped version will only accept the object format
+defined by the codecs, i.e.\ Unicode objects for most built-in
+codecs.  Output is also codec-dependent and will usually be Unicode as
+well.}
+
+\var{encoding} specifies the encoding which is to be used for the
+file.
+
+\var{errors} may be given to define the error handling. It defaults
+to \code{'strict'} which causes a \exception{ValueError} to be raised
+in case an encoding error occurs.
+
+\var{buffering} has the same meaning as for the built-in
+\function{open()} function.  It defaults to line buffered.
+\end{funcdesc}
+
+\begin{funcdesc}{EncodedFile}{file, input\optional{,
+                              output\optional{, errors}}}
+Return a wrapped version of file which provides transparent
+encoding translation.
+
+Strings written to the wrapped file are interpreted according to the
+given \var{input} encoding and then written to the original file as
+strings using the \var{output} encoding. The intermediate encoding will
+usually be Unicode but depends on the specified codecs.
+
+If \var{output} is not given, it defaults to \var{input}.
+
+\var{errors} may be given to define the error handling. It defaults to
+\code{'strict'}, which causes \exception{ValueError} to be raised in case
+an encoding error occurs.
+\end{funcdesc}
+
+\begin{funcdesc}{iterencode}{iterable, encoding\optional{, errors}}
+Uses an incremental encoder to iteratively encode the input provided by
+\var{iterable}. This function is a generator. \var{errors} (as well as
+any other keyword argument) is passed through to the incremental encoder.
+\versionadded{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{iterdecode}{iterable, encoding\optional{, errors}}
+Uses an incremental decoder to iteratively decode the input provided by
+\var{iterable}. This function is a generator. \var{errors} (as well as
+any other keyword argument) is passed through to the incremental encoder.
+\versionadded{2.5}
+\end{funcdesc}
+
+The module also provides the following constants which are useful
+for reading and writing to platform dependent files:
+
+\begin{datadesc}{BOM}
+\dataline{BOM_BE}
+\dataline{BOM_LE}
+\dataline{BOM_UTF8}
+\dataline{BOM_UTF16}
+\dataline{BOM_UTF16_BE}
+\dataline{BOM_UTF16_LE}
+\dataline{BOM_UTF32}
+\dataline{BOM_UTF32_BE}
+\dataline{BOM_UTF32_LE}
+These constants define various encodings of the Unicode byte order mark
+(BOM) used in UTF-16 and UTF-32 data streams to indicate the byte order
+used in the stream or file and in UTF-8 as a Unicode signature.
+\constant{BOM_UTF16} is either \constant{BOM_UTF16_BE} or
+\constant{BOM_UTF16_LE} depending on the platform's native byte order,
+\constant{BOM} is an alias for \constant{BOM_UTF16}, \constant{BOM_LE}
+for \constant{BOM_UTF16_LE} and \constant{BOM_BE} for \constant{BOM_UTF16_BE}.
+The others represent the BOM in UTF-8 and UTF-32 encodings.
+\end{datadesc}
+
+
+\subsection{Codec Base Classes \label{codec-base-classes}}
+
+The \module{codecs} module defines a set of base classes which define the
+interface and can also be used to easily write you own codecs for use
+in Python.
+
+Each codec has to define four interfaces to make it usable as codec in
+Python: stateless encoder, stateless decoder, stream reader and stream
+writer. The stream reader and writers typically reuse the stateless
+encoder/decoder to implement the file protocols.
+
+The \class{Codec} class defines the interface for stateless
+encoders/decoders.
+
+To simplify and standardize error handling, the \method{encode()} and
+\method{decode()} methods may implement different error handling
+schemes by providing the \var{errors} string argument.  The following
+string values are defined and implemented by all standard Python
+codecs:
+
+\begin{tableii}{l|l}{code}{Value}{Meaning}
+  \lineii{'strict'}{Raise \exception{UnicodeError} (or a subclass);
+                    this is the default.}
+  \lineii{'ignore'}{Ignore the character and continue with the next.}
+  \lineii{'replace'}{Replace with a suitable replacement character;
+                     Python will use the official U+FFFD REPLACEMENT
+                     CHARACTER for the built-in Unicode codecs on
+                     decoding and '?' on encoding.}
+  \lineii{'xmlcharrefreplace'}{Replace with the appropriate XML
+                     character reference (only for encoding).}
+  \lineii{'backslashreplace'}{Replace with backslashed escape sequences
+                     (only for encoding).}
+\end{tableii}
+
+The set of allowed values can be extended via \method{register_error}.
+
+
+\subsubsection{Codec Objects \label{codec-objects}}
+
+The \class{Codec} class defines these methods which also define the
+function interfaces of the stateless encoder and decoder:
+
+\begin{methoddesc}{encode}{input\optional{, errors}}
+  Encodes the object \var{input} and returns a tuple (output object,
+  length consumed).  While codecs are not restricted to use with Unicode, in
+  a Unicode context, encoding converts a Unicode object to a plain string
+  using a particular character set encoding (e.g., \code{cp1252} or
+  \code{iso-8859-1}).
+
+  \var{errors} defines the error handling to apply. It defaults to
+  \code{'strict'} handling.
+
+  The method may not store state in the \class{Codec} instance. Use
+  \class{StreamCodec} for codecs which have to keep state in order to
+  make encoding/decoding efficient.
+
+  The encoder must be able to handle zero length input and return an
+  empty object of the output object type in this situation.
+\end{methoddesc}
+
+\begin{methoddesc}{decode}{input\optional{, errors}}
+  Decodes the object \var{input} and returns a tuple (output object,
+  length consumed).  In a Unicode context, decoding converts a plain string
+  encoded using a particular character set encoding to a Unicode object.
+
+  \var{input} must be an object which provides the \code{bf_getreadbuf}
+  buffer slot.  Python strings, buffer objects and memory mapped files
+  are examples of objects providing this slot.
+
+  \var{errors} defines the error handling to apply. It defaults to
+  \code{'strict'} handling.
+
+  The method may not store state in the \class{Codec} instance. Use
+  \class{StreamCodec} for codecs which have to keep state in order to
+  make encoding/decoding efficient.
+
+  The decoder must be able to handle zero length input and return an
+  empty object of the output object type in this situation.
+\end{methoddesc}
+
+The \class{IncrementalEncoder} and \class{IncrementalDecoder} classes provide
+the basic interface for incremental encoding and decoding. Encoding/decoding the
+input isn't done with one call to the stateless encoder/decoder function,
+but with multiple calls to the \method{encode}/\method{decode} method of the
+incremental encoder/decoder. The incremental encoder/decoder keeps track of
+the encoding/decoding process during method calls.
+
+The joined output of calls to the \method{encode}/\method{decode} method is the
+same as if all the single inputs were joined into one, and this input was
+encoded/decoded with the stateless encoder/decoder.
+
+
+\subsubsection{IncrementalEncoder Objects \label{incremental-encoder-objects}}
+
+\versionadded{2.5}
+
+The \class{IncrementalEncoder} class is used for encoding an input in multiple
+steps. It defines the following methods which every incremental encoder must
+define in order to be compatible with the Python codec registry.
+
+\begin{classdesc}{IncrementalEncoder}{\optional{errors}}
+  Constructor for an \class{IncrementalEncoder} instance.
+
+  All incremental encoders must provide this constructor interface. They are
+  free to add additional keyword arguments, but only the ones defined
+  here are used by the Python codec registry.
+
+  The \class{IncrementalEncoder} may implement different error handling
+  schemes by providing the \var{errors} keyword argument. These
+  parameters are predefined:
+
+  \begin{itemize}
+    \item \code{'strict'} Raise \exception{ValueError} (or a subclass);
+                          this is the default.
+    \item \code{'ignore'} Ignore the character and continue with the next.
+    \item \code{'replace'} Replace with a suitable replacement character
+    \item \code{'xmlcharrefreplace'} Replace with the appropriate XML
+                     character reference
+    \item \code{'backslashreplace'} Replace with backslashed escape sequences.
+  \end{itemize}
+
+  The \var{errors} argument will be assigned to an attribute of the
+  same name. Assigning to this attribute makes it possible to switch
+  between different error handling strategies during the lifetime
+  of the \class{IncrementalEncoder} object.
+
+  The set of allowed values for the \var{errors} argument can
+  be extended with \function{register_error()}.
+\end{classdesc}
+
+\begin{methoddesc}{encode}{object\optional{, final}}
+  Encodes \var{object} (taking the current state of the encoder into account)
+  and returns the resulting encoded object. If this is the last call to
+  \method{encode} \var{final} must be true (the default is false).
+\end{methoddesc}
+
+\begin{methoddesc}{reset}{}
+  Reset the encoder to the initial state.
+\end{methoddesc}
+
+
+\subsubsection{IncrementalDecoder Objects \label{incremental-decoder-objects}}
+
+The \class{IncrementalDecoder} class is used for decoding an input in multiple
+steps. It defines the following methods which every incremental decoder must
+define in order to be compatible with the Python codec registry.
+
+\begin{classdesc}{IncrementalDecoder}{\optional{errors}}
+  Constructor for an \class{IncrementalDecoder} instance.
+
+  All incremental decoders must provide this constructor interface. They are
+  free to add additional keyword arguments, but only the ones defined
+  here are used by the Python codec registry.
+
+  The \class{IncrementalDecoder} may implement different error handling
+  schemes by providing the \var{errors} keyword argument. These
+  parameters are predefined:
+
+  \begin{itemize}
+    \item \code{'strict'} Raise \exception{ValueError} (or a subclass);
+                          this is the default.
+    \item \code{'ignore'} Ignore the character and continue with the next.
+    \item \code{'replace'} Replace with a suitable replacement character.
+  \end{itemize}
+
+  The \var{errors} argument will be assigned to an attribute of the
+  same name. Assigning to this attribute makes it possible to switch
+  between different error handling strategies during the lifetime
+  of the \class{IncrementalEncoder} object.
+
+  The set of allowed values for the \var{errors} argument can
+  be extended with \function{register_error()}.
+\end{classdesc}
+
+\begin{methoddesc}{decode}{object\optional{, final}}
+  Decodes \var{object} (taking the current state of the decoder into account)
+  and returns the resulting decoded object. If this is the last call to
+  \method{decode} \var{final} must be true (the default is false).
+  If \var{final} is true the decoder must decode the input completely and must
+  flush all buffers. If this isn't possible (e.g. because of incomplete byte
+  sequences at the end of the input) it must initiate error handling just like
+  in the stateless case (which might raise an exception).
+\end{methoddesc}
+
+\begin{methoddesc}{reset}{}
+  Reset the decoder to the initial state.
+\end{methoddesc}
+
+
+The \class{StreamWriter} and \class{StreamReader} classes provide
+generic working interfaces which can be used to implement new
+encoding submodules very easily. See \module{encodings.utf_8} for an
+example of how this is done.
+
+
+\subsubsection{StreamWriter Objects \label{stream-writer-objects}}
+
+The \class{StreamWriter} class is a subclass of \class{Codec} and
+defines the following methods which every stream writer must define in
+order to be compatible with the Python codec registry.
+
+\begin{classdesc}{StreamWriter}{stream\optional{, errors}}
+  Constructor for a \class{StreamWriter} instance. 
+
+  All stream writers must provide this constructor interface. They are
+  free to add additional keyword arguments, but only the ones defined
+  here are used by the Python codec registry.
+
+  \var{stream} must be a file-like object open for writing binary
+  data.
+
+  The \class{StreamWriter} may implement different error handling
+  schemes by providing the \var{errors} keyword argument. These
+  parameters are predefined:
+
+  \begin{itemize}
+    \item \code{'strict'} Raise \exception{ValueError} (or a subclass);
+                          this is the default.
+    \item \code{'ignore'} Ignore the character and continue with the next.
+    \item \code{'replace'} Replace with a suitable replacement character
+    \item \code{'xmlcharrefreplace'} Replace with the appropriate XML
+                     character reference
+    \item \code{'backslashreplace'} Replace with backslashed escape sequences.
+  \end{itemize}
+
+  The \var{errors} argument will be assigned to an attribute of the
+  same name. Assigning to this attribute makes it possible to switch
+  between different error handling strategies during the lifetime
+  of the \class{StreamWriter} object.
+
+  The set of allowed values for the \var{errors} argument can
+  be extended with \function{register_error()}.
+\end{classdesc}
+
+\begin{methoddesc}{write}{object}
+  Writes the object's contents encoded to the stream.
+\end{methoddesc}
+
+\begin{methoddesc}{writelines}{list}
+  Writes the concatenated list of strings to the stream (possibly by
+  reusing the \method{write()} method).
+\end{methoddesc}
+
+\begin{methoddesc}{reset}{}
+  Flushes and resets the codec buffers used for keeping state.
+
+  Calling this method should ensure that the data on the output is put
+  into a clean state that allows appending of new fresh data without
+  having to rescan the whole stream to recover state.
+\end{methoddesc}
+
+In addition to the above methods, the \class{StreamWriter} must also
+inherit all other methods and attributes from the underlying stream.
+
+
+\subsubsection{StreamReader Objects \label{stream-reader-objects}}
+
+The \class{StreamReader} class is a subclass of \class{Codec} and
+defines the following methods which every stream reader must define in
+order to be compatible with the Python codec registry.
+
+\begin{classdesc}{StreamReader}{stream\optional{, errors}}
+  Constructor for a \class{StreamReader} instance. 
+
+  All stream readers must provide this constructor interface. They are
+  free to add additional keyword arguments, but only the ones defined
+  here are used by the Python codec registry.
+
+  \var{stream} must be a file-like object open for reading (binary)
+  data.
+
+  The \class{StreamReader} may implement different error handling
+  schemes by providing the \var{errors} keyword argument. These
+  parameters are defined:
+
+  \begin{itemize}
+    \item \code{'strict'} Raise \exception{ValueError} (or a subclass);
+                          this is the default.
+    \item \code{'ignore'} Ignore the character and continue with the next.
+    \item \code{'replace'} Replace with a suitable replacement character.
+  \end{itemize}
+
+  The \var{errors} argument will be assigned to an attribute of the
+  same name. Assigning to this attribute makes it possible to switch
+  between different error handling strategies during the lifetime
+  of the \class{StreamReader} object.
+
+  The set of allowed values for the \var{errors} argument can
+  be extended with \function{register_error()}.
+\end{classdesc}
+
+\begin{methoddesc}{read}{\optional{size\optional{, chars, \optional{firstline}}}}
+  Decodes data from the stream and returns the resulting object.
+
+  \var{chars} indicates the number of characters to read from the
+  stream. \function{read()} will never return more than \var{chars}
+  characters, but it might return less, if there are not enough
+  characters available.
+
+  \var{size} indicates the approximate maximum number of bytes to read
+  from the stream for decoding purposes. The decoder can modify this
+  setting as appropriate. The default value -1 indicates to read and
+  decode as much as possible.  \var{size} is intended to prevent having
+  to decode huge files in one step.
+
+  \var{firstline} indicates that it would be sufficient to only return
+  the first line, if there are decoding errors on later lines.
+
+  The method should use a greedy read strategy meaning that it should
+  read as much data as is allowed within the definition of the encoding
+  and the given size, e.g.  if optional encoding endings or state
+  markers are available on the stream, these should be read too.
+
+  \versionchanged[\var{chars} argument added]{2.4}
+  \versionchanged[\var{firstline} argument added]{2.4.2}
+\end{methoddesc}
+
+\begin{methoddesc}{readline}{\optional{size\optional{, keepends}}}
+  Read one line from the input stream and return the
+  decoded data.
+
+  \var{size}, if given, is passed as size argument to the stream's
+  \method{readline()} method.
+
+  If \var{keepends} is false line-endings will be stripped from the
+  lines returned.
+
+  \versionchanged[\var{keepends} argument added]{2.4}
+\end{methoddesc}
+
+\begin{methoddesc}{readlines}{\optional{sizehint\optional{, keepends}}}
+  Read all lines available on the input stream and return them as a list
+  of lines.
+
+  Line-endings are implemented using the codec's decoder method and are
+  included in the list entries if \var{keepends} is true.
+
+  \var{sizehint}, if given, is passed as the \var{size} argument to the
+  stream's \method{read()} method.
+\end{methoddesc}
+
+\begin{methoddesc}{reset}{}
+  Resets the codec buffers used for keeping state.
+
+  Note that no stream repositioning should take place.  This method is
+  primarily intended to be able to recover from decoding errors.
+\end{methoddesc}
+
+In addition to the above methods, the \class{StreamReader} must also
+inherit all other methods and attributes from the underlying stream.
+
+The next two base classes are included for convenience. They are not
+needed by the codec registry, but may provide useful in practice.
+
+
+\subsubsection{StreamReaderWriter Objects \label{stream-reader-writer}}
+
+The \class{StreamReaderWriter} allows wrapping streams which work in
+both read and write modes.
+
+The design is such that one can use the factory functions returned by
+the \function{lookup()} function to construct the instance.
+
+\begin{classdesc}{StreamReaderWriter}{stream, Reader, Writer, errors}
+  Creates a \class{StreamReaderWriter} instance.
+  \var{stream} must be a file-like object.
+  \var{Reader} and \var{Writer} must be factory functions or classes
+  providing the \class{StreamReader} and \class{StreamWriter} interface
+  resp.
+  Error handling is done in the same way as defined for the
+  stream readers and writers.
+\end{classdesc}
+
+\class{StreamReaderWriter} instances define the combined interfaces of
+\class{StreamReader} and \class{StreamWriter} classes. They inherit
+all other methods and attributes from the underlying stream.
+
+
+\subsubsection{StreamRecoder Objects \label{stream-recoder-objects}}
+
+The \class{StreamRecoder} provide a frontend - backend view of
+encoding data which is sometimes useful when dealing with different
+encoding environments.
+
+The design is such that one can use the factory functions returned by
+the \function{lookup()} function to construct the instance.
+
+\begin{classdesc}{StreamRecoder}{stream, encode, decode,
+                                 Reader, Writer, errors}
+  Creates a \class{StreamRecoder} instance which implements a two-way
+  conversion: \var{encode} and \var{decode} work on the frontend (the
+  input to \method{read()} and output of \method{write()}) while
+  \var{Reader} and \var{Writer} work on the backend (reading and
+  writing to the stream).
+
+  You can use these objects to do transparent direct recodings from
+  e.g.\ Latin-1 to UTF-8 and back.
+
+  \var{stream} must be a file-like object.
+
+  \var{encode}, \var{decode} must adhere to the \class{Codec}
+  interface. \var{Reader}, \var{Writer} must be factory functions or
+  classes providing objects of the \class{StreamReader} and
+  \class{StreamWriter} interface respectively.
+
+  \var{encode} and \var{decode} are needed for the frontend
+  translation, \var{Reader} and \var{Writer} for the backend
+  translation.  The intermediate format used is determined by the two
+  sets of codecs, e.g. the Unicode codecs will use Unicode as the
+  intermediate encoding.
+
+  Error handling is done in the same way as defined for the
+  stream readers and writers.
+\end{classdesc}
+
+\class{StreamRecoder} instances define the combined interfaces of
+\class{StreamReader} and \class{StreamWriter} classes. They inherit
+all other methods and attributes from the underlying stream.
+
+\subsection{Encodings and Unicode\label{encodings-overview}}
+
+Unicode strings are stored internally as sequences of codepoints (to
+be precise as \ctype{Py_UNICODE} arrays). Depending on the way Python is
+compiled (either via \longprogramopt{enable-unicode=ucs2} or 
+\longprogramopt{enable-unicode=ucs4}, with the former being the default)
+\ctype{Py_UNICODE} is either a 16-bit or
+32-bit data type. Once a Unicode object is used outside of CPU and
+memory, CPU endianness and how these arrays are stored as bytes become
+an issue. Transforming a unicode object into a sequence of bytes is
+called encoding and recreating the unicode object from the sequence of
+bytes is known as decoding. There are many different methods for how this
+transformation can be done (these methods are also called encodings).
+The simplest method is to map the codepoints 0-255 to the bytes
+\code{0x0}-\code{0xff}. This means that a unicode object that contains 
+codepoints above \code{U+00FF} can't be encoded with this method (which 
+is called \code{'latin-1'} or \code{'iso-8859-1'}).
+\function{unicode.encode()} will raise a \exception{UnicodeEncodeError}
+that looks like this: \samp{UnicodeEncodeError: 'latin-1' codec can't
+encode character u'\e u1234' in position 3: ordinal not in range(256)}.
+
+There's another group of encodings (the so called charmap encodings)
+that choose a different subset of all unicode code points and how
+these codepoints are mapped to the bytes \code{0x0}-\code{0xff.}
+To see how this is done simply open e.g. \file{encodings/cp1252.py}
+(which is an encoding that is used primarily on Windows).
+There's a string constant with 256 characters that shows you which 
+character is mapped to which byte value.
+
+All of these encodings can only encode 256 of the 65536 (or 1114111)
+codepoints defined in unicode. A simple and straightforward way that
+can store each Unicode code point, is to store each codepoint as two
+consecutive bytes. There are two possibilities: Store the bytes in big
+endian or in little endian order. These two encodings are called
+UTF-16-BE and UTF-16-LE respectively. Their disadvantage is that if
+e.g. you use UTF-16-BE on a little endian machine you will always have
+to swap bytes on encoding and decoding. UTF-16 avoids this problem:
+Bytes will always be in natural endianness. When these bytes are read
+by a CPU with a different endianness, then bytes have to be swapped
+though. To be able to detect the endianness of a UTF-16 byte sequence,
+there's the so called BOM (the "Byte Order Mark"). This is the Unicode
+character \code{U+FEFF}. This character will be prepended to every UTF-16
+byte sequence. The byte swapped version of this character (\code{0xFFFE}) is
+an illegal character that may not appear in a Unicode text. So when
+the first character in an UTF-16 byte sequence appears to be a \code{U+FFFE}
+the bytes have to be swapped on decoding. Unfortunately upto Unicode
+4.0 the character \code{U+FEFF} had a second purpose as a \samp{ZERO WIDTH
+NO-BREAK SPACE}: A character that has no width and doesn't allow a
+word to be split. It can e.g. be used to give hints to a ligature
+algorithm. With Unicode 4.0 using \code{U+FEFF} as a \samp{ZERO WIDTH NO-BREAK
+SPACE} has been deprecated (with \code{U+2060} (\samp{WORD JOINER}) assuming
+this role). Nevertheless Unicode software still must be able to handle
+\code{U+FEFF} in both roles: As a BOM it's a device to determine the storage
+layout of the encoded bytes, and vanishes once the byte sequence has
+been decoded into a Unicode string; as a \samp{ZERO WIDTH NO-BREAK SPACE}
+it's a normal character that will be decoded like any other.
+
+There's another encoding that is able to encoding the full range of
+Unicode characters: UTF-8. UTF-8 is an 8-bit encoding, which means
+there are no issues with byte order in UTF-8. Each byte in a UTF-8
+byte sequence consists of two parts: Marker bits (the most significant
+bits) and payload bits. The marker bits are a sequence of zero to six
+1 bits followed by a 0 bit. Unicode characters are encoded like this
+(with x being payload bits, which when concatenated give the Unicode
+character):
+
+\begin{tableii}{l|l}{textrm}{Range}{Encoding}
+\lineii{\code{U-00000000} ... \code{U-0000007F}}{0xxxxxxx}
+\lineii{\code{U-00000080} ... \code{U-000007FF}}{110xxxxx 10xxxxxx}
+\lineii{\code{U-00000800} ... \code{U-0000FFFF}}{1110xxxx 10xxxxxx 10xxxxxx}
+\lineii{\code{U-00010000} ... \code{U-001FFFFF}}{11110xxx 10xxxxxx 10xxxxxx 10xxxxxx}
+\lineii{\code{U-00200000} ... \code{U-03FFFFFF}}{111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx}
+\lineii{\code{U-04000000} ... \code{U-7FFFFFFF}}{1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx}
+\end{tableii}
+
+The least significant bit of the Unicode character is the rightmost x
+bit.
+
+As UTF-8 is an 8-bit encoding no BOM is required and any \code{U+FEFF}
+character in the decoded Unicode string (even if it's the first
+character) is treated as a \samp{ZERO WIDTH NO-BREAK SPACE}.
+
+Without external information it's impossible to reliably determine
+which encoding was used for encoding a Unicode string. Each charmap
+encoding can decode any random byte sequence. However that's not
+possible with UTF-8, as UTF-8 byte sequences have a structure that
+doesn't allow arbitrary byte sequence. To increase the reliability
+with which a UTF-8 encoding can be detected, Microsoft invented a
+variant of UTF-8 (that Python 2.5 calls \code{"utf-8-sig"}) for its Notepad
+program: Before any of the Unicode characters is written to the file,
+a UTF-8 encoded BOM (which looks like this as a byte sequence: \code{0xef},
+\code{0xbb}, \code{0xbf}) is written. As it's rather improbable that any
+charmap encoded file starts with these byte values (which would e.g. map to
+
+   LATIN SMALL LETTER I WITH DIAERESIS \\
+   RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK \\
+   INVERTED QUESTION MARK
+
+in iso-8859-1), this increases the probability that a utf-8-sig
+encoding can be correctly guessed from the byte sequence. So here the
+BOM is not used to be able to determine the byte order used for
+generating the byte sequence, but as a signature that helps in
+guessing the encoding. On encoding the utf-8-sig codec will write
+\code{0xef}, \code{0xbb}, \code{0xbf} as the first three bytes to the file.
+On decoding utf-8-sig will skip those three bytes if they appear as the
+first three bytes in the file.
+
+
+\subsection{Standard Encodings\label{standard-encodings}}
+
+Python comes with a number of codecs built-in, either implemented as C
+functions or with dictionaries as mapping tables. The following table
+lists the codecs by name, together with a few common aliases, and the
+languages for which the encoding is likely used. Neither the list of
+aliases nor the list of languages is meant to be exhaustive. Notice
+that spelling alternatives that only differ in case or use a hyphen
+instead of an underscore are also valid aliases.
+
+Many of the character sets support the same languages. They vary in
+individual characters (e.g. whether the EURO SIGN is supported or
+not), and in the assignment of characters to code positions. For the
+European languages in particular, the following variants typically
+exist:
+
+\begin{itemize}
+\item an ISO 8859 codeset
+\item a Microsoft Windows code page, which is typically derived from
+      a 8859 codeset, but replaces control characters with additional
+      graphic characters
+\item an IBM EBCDIC code page
+\item an IBM PC code page, which is \ASCII{} compatible
+\end{itemize}
+
+\begin{longtableiii}{l|l|l}{textrm}{Codec}{Aliases}{Languages}
+
+\lineiii{ascii}
+        {646, us-ascii}
+        {English}
+
+\lineiii{big5}
+        {big5-tw, csbig5}
+        {Traditional Chinese}
+
+\lineiii{big5hkscs}
+        {big5-hkscs, hkscs}
+        {Traditional Chinese}
+
+\lineiii{cp037}
+        {IBM037, IBM039}
+        {English}
+
+\lineiii{cp424}
+        {EBCDIC-CP-HE, IBM424}
+        {Hebrew}
+
+\lineiii{cp437}
+        {437, IBM437}
+        {English}
+
+\lineiii{cp500}
+        {EBCDIC-CP-BE, EBCDIC-CP-CH, IBM500}
+        {Western Europe}
+
+\lineiii{cp737}
+        {}
+        {Greek}
+
+\lineiii{cp775}
+        {IBM775}
+        {Baltic languages}
+
+\lineiii{cp850}
+        {850, IBM850}
+        {Western Europe}
+
+\lineiii{cp852}
+        {852, IBM852}
+        {Central and Eastern Europe}
+
+\lineiii{cp855}
+        {855, IBM855}
+        {Bulgarian, Byelorussian, Macedonian, Russian, Serbian}
+
+\lineiii{cp856}
+        {}
+        {Hebrew}
+
+\lineiii{cp857}
+        {857, IBM857}
+        {Turkish}
+
+\lineiii{cp860}
+        {860, IBM860}
+        {Portuguese}
+
+\lineiii{cp861}
+        {861, CP-IS, IBM861}
+        {Icelandic}
+
+\lineiii{cp862}
+        {862, IBM862}
+        {Hebrew}
+
+\lineiii{cp863}
+        {863, IBM863}
+        {Canadian}
+
+\lineiii{cp864}
+        {IBM864}
+        {Arabic}
+
+\lineiii{cp865}
+        {865, IBM865}
+        {Danish, Norwegian}
+
+\lineiii{cp866}
+        {866, IBM866}
+        {Russian}
+
+\lineiii{cp869}
+        {869, CP-GR, IBM869}
+        {Greek}
+
+\lineiii{cp874}
+        {}
+        {Thai}
+
+\lineiii{cp875}
+        {}
+        {Greek}
+
+\lineiii{cp932}
+        {932, ms932, mskanji, ms-kanji}
+        {Japanese}
+
+\lineiii{cp949}
+        {949, ms949, uhc}
+        {Korean}
+
+\lineiii{cp950}
+        {950, ms950}
+        {Traditional Chinese}
+
+\lineiii{cp1006}
+        {}
+        {Urdu}
+
+\lineiii{cp1026}
+        {ibm1026}
+        {Turkish}
+
+\lineiii{cp1140}
+        {ibm1140}
+        {Western Europe}
+
+\lineiii{cp1250}
+        {windows-1250}
+        {Central and Eastern Europe}
+
+\lineiii{cp1251}
+        {windows-1251}
+        {Bulgarian, Byelorussian, Macedonian, Russian, Serbian}
+
+\lineiii{cp1252}
+        {windows-1252}
+        {Western Europe}
+
+\lineiii{cp1253}
+        {windows-1253}
+        {Greek}
+
+\lineiii{cp1254}
+        {windows-1254}
+        {Turkish}
+
+\lineiii{cp1255}
+        {windows-1255}
+        {Hebrew}
+
+\lineiii{cp1256}
+        {windows1256}
+        {Arabic}
+
+\lineiii{cp1257}
+        {windows-1257}
+        {Baltic languages}
+
+\lineiii{cp1258}
+        {windows-1258}
+        {Vietnamese}
+
+\lineiii{euc_jp}
+        {eucjp, ujis, u-jis}
+        {Japanese}
+
+\lineiii{euc_jis_2004}
+        {jisx0213, eucjis2004}
+        {Japanese}
+
+\lineiii{euc_jisx0213}
+        {eucjisx0213}
+        {Japanese}
+
+\lineiii{euc_kr}
+        {euckr, korean, ksc5601, ks_c-5601, ks_c-5601-1987, ksx1001, ks_x-1001}
+        {Korean}
+
+\lineiii{gb2312}
+        {chinese, csiso58gb231280, euc-cn, euccn, eucgb2312-cn, gb2312-1980,
+         gb2312-80, iso-ir-58}
+        {Simplified Chinese}
+
+\lineiii{gbk}
+        {936, cp936, ms936}
+        {Unified Chinese}
+
+\lineiii{gb18030}
+        {gb18030-2000}
+        {Unified Chinese}
+
+\lineiii{hz}
+        {hzgb, hz-gb, hz-gb-2312}
+        {Simplified Chinese}
+
+\lineiii{iso2022_jp}
+        {csiso2022jp, iso2022jp, iso-2022-jp}
+        {Japanese}
+
+\lineiii{iso2022_jp_1}
+        {iso2022jp-1, iso-2022-jp-1}
+        {Japanese}
+
+\lineiii{iso2022_jp_2}
+        {iso2022jp-2, iso-2022-jp-2}
+        {Japanese, Korean, Simplified Chinese, Western Europe, Greek}
+
+\lineiii{iso2022_jp_2004}
+        {iso2022jp-2004, iso-2022-jp-2004}
+        {Japanese}
+
+\lineiii{iso2022_jp_3}
+        {iso2022jp-3, iso-2022-jp-3}
+        {Japanese}
+
+\lineiii{iso2022_jp_ext}
+        {iso2022jp-ext, iso-2022-jp-ext}
+        {Japanese}
+
+\lineiii{iso2022_kr}
+        {csiso2022kr, iso2022kr, iso-2022-kr}
+        {Korean}
+
+\lineiii{latin_1}
+        {iso-8859-1, iso8859-1, 8859, cp819, latin, latin1, L1}
+        {West Europe}
+
+\lineiii{iso8859_2}
+        {iso-8859-2, latin2, L2}
+        {Central and Eastern Europe}
+
+\lineiii{iso8859_3}
+        {iso-8859-3, latin3, L3}
+        {Esperanto, Maltese}
+
+\lineiii{iso8859_4}
+        {iso-8859-4, latin4, L4}
+        {Baltic languagues}
+
+\lineiii{iso8859_5}
+        {iso-8859-5, cyrillic}
+        {Bulgarian, Byelorussian, Macedonian, Russian, Serbian}
+
+\lineiii{iso8859_6}
+        {iso-8859-6, arabic}
+        {Arabic}
+
+\lineiii{iso8859_7}
+        {iso-8859-7, greek, greek8}
+        {Greek}
+
+\lineiii{iso8859_8}
+        {iso-8859-8, hebrew}
+        {Hebrew}
+
+\lineiii{iso8859_9}
+        {iso-8859-9, latin5, L5}
+        {Turkish}
+
+\lineiii{iso8859_10}
+        {iso-8859-10, latin6, L6}
+        {Nordic languages}
+
+\lineiii{iso8859_13}
+        {iso-8859-13}
+        {Baltic languages}
+
+\lineiii{iso8859_14}
+        {iso-8859-14, latin8, L8}
+        {Celtic languages}
+
+\lineiii{iso8859_15}
+        {iso-8859-15}
+        {Western Europe}
+
+\lineiii{johab}
+        {cp1361, ms1361}
+        {Korean}
+
+\lineiii{koi8_r}
+        {}
+        {Russian}
+
+\lineiii{koi8_u}
+        {}
+        {Ukrainian}
+
+\lineiii{mac_cyrillic}
+        {maccyrillic}
+        {Bulgarian, Byelorussian, Macedonian, Russian, Serbian}
+
+\lineiii{mac_greek}
+        {macgreek}
+        {Greek}
+
+\lineiii{mac_iceland}
+        {maciceland}
+        {Icelandic}
+
+\lineiii{mac_latin2}
+        {maclatin2, maccentraleurope}
+        {Central and Eastern Europe}
+
+\lineiii{mac_roman}
+        {macroman}
+        {Western Europe}
+
+\lineiii{mac_turkish}
+        {macturkish}
+        {Turkish}
+
+\lineiii{ptcp154}
+        {csptcp154, pt154, cp154, cyrillic-asian}
+        {Kazakh}
+
+\lineiii{shift_jis}
+        {csshiftjis, shiftjis, sjis, s_jis}
+        {Japanese}
+
+\lineiii{shift_jis_2004}
+        {shiftjis2004, sjis_2004, sjis2004}
+        {Japanese}
+
+\lineiii{shift_jisx0213}
+        {shiftjisx0213, sjisx0213, s_jisx0213}
+        {Japanese}
+
+\lineiii{utf_16}
+        {U16, utf16}
+        {all languages}
+
+\lineiii{utf_16_be}
+        {UTF-16BE}
+        {all languages (BMP only)}
+
+\lineiii{utf_16_le}
+        {UTF-16LE}
+        {all languages (BMP only)}
+
+\lineiii{utf_7}
+        {U7, unicode-1-1-utf-7}
+        {all languages}
+
+\lineiii{utf_8}
+        {U8, UTF, utf8}
+        {all languages}
+
+\lineiii{utf_8_sig}
+        {}
+        {all languages}
+
+\end{longtableiii}
+
+A number of codecs are specific to Python, so their codec names have
+no meaning outside Python. Some of them don't convert from Unicode
+strings to byte strings, but instead use the property of the Python
+codecs machinery that any bijective function with one argument can be
+considered as an encoding.
+
+For the codecs listed below, the result in the ``encoding'' direction
+is always a byte string. The result of the ``decoding'' direction is
+listed as operand type in the table.
+
+\begin{tableiv}{l|l|l|l}{textrm}{Codec}{Aliases}{Operand type}{Purpose}
+
+\lineiv{base64_codec}
+         {base64, base-64}
+         {byte string}
+         {Convert operand to MIME base64}
+
+\lineiv{bz2_codec}
+         {bz2}
+         {byte string}
+         {Compress the operand using bz2}
+
+\lineiv{hex_codec}
+         {hex}
+         {byte string}
+         {Convert operand to hexadecimal representation, with two
+          digits per byte}
+
+\lineiv{idna}
+         {}
+         {Unicode string}
+         {Implements \rfc{3490}.
+          \versionadded{2.3}
+          See also \refmodule{encodings.idna}}
+
+\lineiv{mbcs}
+         {dbcs}
+         {Unicode string}
+         {Windows only: Encode operand according to the ANSI codepage (CP_ACP)}
+
+\lineiv{palmos}
+         {}
+         {Unicode string}
+         {Encoding of PalmOS 3.5}
+
+\lineiv{punycode}
+         {}
+         {Unicode string}
+         {Implements \rfc{3492}.
+          \versionadded{2.3}}
+
+\lineiv{quopri_codec}
+         {quopri, quoted-printable, quotedprintable}
+         {byte string}
+         {Convert operand to MIME quoted printable}
+
+\lineiv{raw_unicode_escape}
+         {}
+         {Unicode string}
+         {Produce a string that is suitable as raw Unicode literal in
+          Python source code}
+
+\lineiv{rot_13}
+         {rot13}
+         {Unicode string}
+         {Returns the Caesar-cypher encryption of the operand}
+
+\lineiv{string_escape}
+         {}
+         {byte string}
+         {Produce a string that is suitable as string literal in
+          Python source code}
+
+\lineiv{undefined}
+         {}
+         {any}
+         {Raise an exception for all conversions. Can be used as the
+          system encoding if no automatic coercion between byte and
+          Unicode strings is desired.} 
+
+\lineiv{unicode_escape}
+         {}
+         {Unicode string}
+         {Produce a string that is suitable as Unicode literal in
+          Python source code}
+
+\lineiv{unicode_internal}
+         {}
+         {Unicode string}
+         {Return the internal representation of the operand}
+
+\lineiv{uu_codec}
+         {uu}
+         {byte string}
+         {Convert the operand using uuencode}
+
+\lineiv{zlib_codec}
+         {zip, zlib}
+         {byte string}
+         {Compress the operand using gzip}
+
+\end{tableiv}
+
+\subsection{\module{encodings.idna} ---
+            Internationalized Domain Names in Applications}
+
+\declaremodule{standard}{encodings.idna}
+\modulesynopsis{Internationalized Domain Names implementation}
+% XXX The next line triggers a formatting bug, so it's commented out
+% until that can be fixed.
+%\moduleauthor{Martin v. L\"owis}
+
+\versionadded{2.3}
+
+This module implements \rfc{3490} (Internationalized Domain Names in
+Applications) and \rfc{3492} (Nameprep: A Stringprep Profile for
+Internationalized Domain Names (IDN)). It builds upon the
+\code{punycode} encoding and \refmodule{stringprep}.
+
+These RFCs together define a protocol to support non-\ASCII{} characters
+in domain names. A domain name containing non-\ASCII{} characters (such
+as ``www.Alliancefran\c caise.nu'') is converted into an
+\ASCII-compatible encoding (ACE, such as
+``www.xn--alliancefranaise-npb.nu''). The ACE form of the domain name
+is then used in all places where arbitrary characters are not allowed
+by the protocol, such as DNS queries, HTTP \mailheader{Host} fields, and so
+on. This conversion is carried out in the application; if possible
+invisible to the user: The application should transparently convert
+Unicode domain labels to IDNA on the wire, and convert back ACE labels
+to Unicode before presenting them to the user.
+
+Python supports this conversion in several ways: The \code{idna} codec
+allows to convert between Unicode and the ACE. Furthermore, the
+\refmodule{socket} module transparently converts Unicode host names to
+ACE, so that applications need not be concerned about converting host
+names themselves when they pass them to the socket module. On top of
+that, modules that have host names as function parameters, such as
+\refmodule{httplib} and \refmodule{ftplib}, accept Unicode host names
+(\refmodule{httplib} then also transparently sends an IDNA hostname in
+the \mailheader{Host} field if it sends that field at all). 
+
+When receiving host names from the wire (such as in reverse name
+lookup), no automatic conversion to Unicode is performed: Applications
+wishing to present such host names to the user should decode them to
+Unicode.
+
+The module \module{encodings.idna} also implements the nameprep
+procedure, which performs certain normalizations on host names, to
+achieve case-insensitivity of international domain names, and to unify
+similar characters. The nameprep functions can be used directly if
+desired.
+
+\begin{funcdesc}{nameprep}{label}
+Return the nameprepped version of \var{label}. The implementation
+currently assumes query strings, so \code{AllowUnassigned} is
+true.
+\end{funcdesc}
+
+\begin{funcdesc}{ToASCII}{label}
+Convert a label to \ASCII, as specified in \rfc{3490}.
+\code{UseSTD3ASCIIRules} is assumed to be false.
+\end{funcdesc}
+
+\begin{funcdesc}{ToUnicode}{label}
+Convert a label to Unicode, as specified in \rfc{3490}.
+\end{funcdesc}
+
+ \subsection{\module{encodings.utf_8_sig} ---
+             UTF-8 codec with BOM signature}
+\declaremodule{standard}{encodings.utf-8-sig}   % XXX utf_8_sig gives TeX errors
+\modulesynopsis{UTF-8 codec with BOM signature}
+\moduleauthor{Walter D\"orwald}{}
+
+\versionadded{2.5}
+
+This module implements a variant of the UTF-8 codec: On encoding a
+UTF-8 encoded BOM will be prepended to the UTF-8 encoded bytes. For
+the stateful encoder this is only done once (on the first write to the
+byte stream).  For decoding an optional UTF-8 encoded BOM at the start
+of the data will be skipped.

Added: vendor/Python/current/Doc/lib/libcodeop.tex
===================================================================
--- vendor/Python/current/Doc/lib/libcodeop.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libcodeop.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,103 @@
+\section{\module{codeop} ---
+         Compile Python code}
+
+% LaTeXed from excellent doc-string.
+
+\declaremodule{standard}{codeop}
+\sectionauthor{Moshe Zadka}{moshez at zadka.site.co.il}
+\sectionauthor{Michael Hudson}{mwh at python.net}
+\modulesynopsis{Compile (possibly incomplete) Python code.}
+
+The \module{codeop} module provides utilities upon which the Python
+read-eval-print loop can be emulated, as is done in the
+\refmodule{code} module.  As a result, you probably don't want to use
+the module directly; if you want to include such a loop in your
+program you probably want to use the \refmodule{code} module instead.
+
+There are two parts to this job: 
+
+\begin{enumerate}
+  \item Being able to tell if a line of input completes a Python 
+        statement: in short, telling whether to print
+        `\code{>>>~}' or `\code{...~}' next.
+  \item Remembering which future statements the user has entered, so 
+        subsequent input can be compiled with these in effect.
+\end{enumerate}
+
+The \module{codeop} module provides a way of doing each of these
+things, and a way of doing them both.
+
+To do just the former:
+
+\begin{funcdesc}{compile_command}
+                {source\optional{, filename\optional{, symbol}}}
+Tries to compile \var{source}, which should be a string of Python
+code and return a code object if \var{source} is valid
+Python code. In that case, the filename attribute of the code object
+will be \var{filename}, which defaults to \code{'<input>'}.
+Returns \code{None} if \var{source} is \emph{not} valid Python
+code, but is a prefix of valid Python code.
+
+If there is a problem with \var{source}, an exception will be raised.
+\exception{SyntaxError} is raised if there is invalid Python syntax,
+and \exception{OverflowError} or \exception{ValueError} if there is an
+invalid literal.
+
+The \var{symbol} argument determines whether \var{source} is compiled
+as a statement (\code{'single'}, the default) or as an expression
+(\code{'eval'}).  Any other value will cause \exception{ValueError} to 
+be raised.
+
+\strong{Caveat:}
+It is possible (but not likely) that the parser stops parsing
+with a successful outcome before reaching the end of the source;
+in this case, trailing symbols may be ignored instead of causing an
+error.  For example, a backslash followed by two newlines may be
+followed by arbitrary garbage.  This will be fixed once the API
+for the parser is better.
+\end{funcdesc}
+
+\begin{classdesc}{Compile}{}
+Instances of this class have \method{__call__()} methods identical in
+signature to the built-in function \function{compile()}, but with the
+difference that if the instance compiles program text containing a
+\module{__future__} statement, the instance 'remembers' and compiles
+all subsequent program texts with the statement in force.
+\end{classdesc}
+
+\begin{classdesc}{CommandCompiler}{}
+Instances of this class have \method{__call__()} methods identical in
+signature to \function{compile_command()}; the difference is that if
+the instance compiles program text containing a \code{__future__}
+statement, the instance 'remembers' and compiles all subsequent
+program texts with the statement in force.
+\end{classdesc}
+
+A note on version compatibility: the \class{Compile} and
+\class{CommandCompiler} are new in Python 2.2.  If you want to enable
+the future-tracking features of 2.2 but also retain compatibility with
+2.1 and earlier versions of Python you can either write
+
+\begin{verbatim}
+try:
+    from codeop import CommandCompiler
+    compile_command = CommandCompiler()
+    del CommandCompiler
+except ImportError:
+    from codeop import compile_command
+\end{verbatim}
+
+which is a low-impact change, but introduces possibly unwanted global
+state into your program, or you can write:
+
+\begin{verbatim}
+try:
+    from codeop import CommandCompiler
+except ImportError:
+    def CommandCompiler():
+        from codeop import compile_command
+        return compile_command
+\end{verbatim}
+
+and then call \code{CommandCompiler} every time you need a fresh
+compiler object.

Added: vendor/Python/current/Doc/lib/libcollections.tex
===================================================================
--- vendor/Python/current/Doc/lib/libcollections.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libcollections.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,341 @@
+\section{\module{collections} ---
+         High-performance container datatypes}
+
+\declaremodule{standard}{collections}
+\modulesynopsis{High-performance datatypes}
+\moduleauthor{Raymond Hettinger}{python at rcn.com}
+\sectionauthor{Raymond Hettinger}{python at rcn.com}
+\versionadded{2.4}
+
+
+This module implements high-performance container datatypes.  Currently,
+there are two datatypes, deque and defaultdict.
+Future additions may include balanced trees and ordered dictionaries.
+\versionchanged[Added defaultdict]{2.5}
+
+\subsection{\class{deque} objects \label{deque-objects}}
+
+\begin{funcdesc}{deque}{\optional{iterable}}
+  Returns a new deque object initialized left-to-right (using
+  \method{append()}) with data from \var{iterable}.  If \var{iterable}
+  is not specified, the new deque is empty.
+
+  Deques are a generalization of stacks and queues (the name is pronounced
+  ``deck'' and is short for ``double-ended queue'').  Deques support
+  thread-safe, memory efficient appends and pops from either side of the deque
+  with approximately the same \code{O(1)} performance in either direction.
+
+  Though \class{list} objects support similar operations, they are optimized
+  for fast fixed-length operations and incur \code{O(n)} memory movement costs
+  for \samp{pop(0)} and \samp{insert(0, v)} operations which change both the
+  size and position of the underlying data representation.
+  \versionadded{2.4}
+\end{funcdesc}
+
+Deque objects support the following methods:
+
+\begin{methoddesc}{append}{x}
+   Add \var{x} to the right side of the deque.
+\end{methoddesc}
+
+\begin{methoddesc}{appendleft}{x}
+   Add \var{x} to the left side of the deque.
+\end{methoddesc}
+
+\begin{methoddesc}{clear}{}
+   Remove all elements from the deque leaving it with length 0.
+\end{methoddesc}
+
+\begin{methoddesc}{extend}{iterable}
+   Extend the right side of the deque by appending elements from
+   the iterable argument.
+\end{methoddesc}
+
+\begin{methoddesc}{extendleft}{iterable}
+   Extend the left side of the deque by appending elements from
+   \var{iterable}.  Note, the series of left appends results in
+   reversing the order of elements in the iterable argument.
+\end{methoddesc}
+
+\begin{methoddesc}{pop}{}
+   Remove and return an element from the right side of the deque.
+   If no elements are present, raises an \exception{IndexError}.
+\end{methoddesc}
+
+\begin{methoddesc}{popleft}{}
+   Remove and return an element from the left side of the deque.
+   If no elements are present, raises an \exception{IndexError}.   
+\end{methoddesc}
+
+\begin{methoddesc}{remove}{value}
+   Removed the first occurrence of \var{value}.  If not found,
+   raises a \exception{ValueError}.
+   \versionadded{2.5}
+\end{methoddesc}
+
+\begin{methoddesc}{rotate}{n}
+   Rotate the deque \var{n} steps to the right.  If \var{n} is
+   negative, rotate to the left.  Rotating one step to the right
+   is equivalent to:  \samp{d.appendleft(d.pop())}. 
+\end{methoddesc}
+
+In addition to the above, deques support iteration, pickling, \samp{len(d)},
+\samp{reversed(d)}, \samp{copy.copy(d)}, \samp{copy.deepcopy(d)},
+membership testing with the \keyword{in} operator, and subscript references
+such as \samp{d[-1]}.
+
+Example:
+
+\begin{verbatim}
+>>> from collections import deque
+>>> d = deque('ghi')                 # make a new deque with three items
+>>> for elem in d:                   # iterate over the deque's elements
+...     print elem.upper()	
+G
+H
+I
+
+>>> d.append('j')                    # add a new entry to the right side
+>>> d.appendleft('f')                # add a new entry to the left side
+>>> d                                # show the representation of the deque
+deque(['f', 'g', 'h', 'i', 'j'])
+
+>>> d.pop()                          # return and remove the rightmost item
+'j'
+>>> d.popleft()                      # return and remove the leftmost item
+'f'
+>>> list(d)                          # list the contents of the deque
+['g', 'h', 'i']
+>>> d[0]                             # peek at leftmost item
+'g'
+>>> d[-1]                            # peek at rightmost item
+'i'
+
+>>> list(reversed(d))                # list the contents of a deque in reverse
+['i', 'h', 'g']
+>>> 'h' in d                         # search the deque
+True
+>>> d.extend('jkl')                  # add multiple elements at once
+>>> d
+deque(['g', 'h', 'i', 'j', 'k', 'l'])
+>>> d.rotate(1)                      # right rotation
+>>> d
+deque(['l', 'g', 'h', 'i', 'j', 'k'])
+>>> d.rotate(-1)                     # left rotation
+>>> d
+deque(['g', 'h', 'i', 'j', 'k', 'l'])
+
+>>> deque(reversed(d))               # make a new deque in reverse order
+deque(['l', 'k', 'j', 'i', 'h', 'g'])
+>>> d.clear()                        # empty the deque
+>>> d.pop()                          # cannot pop from an empty deque
+Traceback (most recent call last):
+  File "<pyshell#6>", line 1, in -toplevel-
+    d.pop()
+IndexError: pop from an empty deque
+
+>>> d.extendleft('abc')              # extendleft() reverses the input order
+>>> d
+deque(['c', 'b', 'a'])
+\end{verbatim}
+
+\subsubsection{Recipes \label{deque-recipes}}
+
+This section shows various approaches to working with deques.
+
+The \method{rotate()} method provides a way to implement \class{deque}
+slicing and deletion.  For example, a pure python implementation of
+\code{del d[n]} relies on the \method{rotate()} method to position
+elements to be popped:
+    
+\begin{verbatim}
+def delete_nth(d, n):
+    d.rotate(-n)
+    d.popleft()
+    d.rotate(n)
+\end{verbatim}
+
+To implement \class{deque} slicing, use a similar approach applying
+\method{rotate()} to bring a target element to the left side of the deque.
+Remove old entries with \method{popleft()}, add new entries with
+\method{extend()}, and then reverse the rotation.
+
+With minor variations on that approach, it is easy to implement Forth style
+stack manipulations such as \code{dup}, \code{drop}, \code{swap}, \code{over},
+\code{pick}, \code{rot}, and \code{roll}.
+
+A roundrobin task server can be built from a \class{deque} using
+\method{popleft()} to select the current task and \method{append()}
+to add it back to the tasklist if the input stream is not exhausted:
+
+\begin{verbatim}
+def roundrobin(*iterables):
+    pending = deque(iter(i) for i in iterables)
+    while pending:
+        task = pending.popleft()
+        try:
+            yield task.next()
+        except StopIteration:
+            continue
+        pending.append(task)
+
+>>> for value in roundrobin('abc', 'd', 'efgh'):
+...     print value
+
+a
+d
+e
+b
+f
+c
+g
+h
+
+\end{verbatim}
+
+
+Multi-pass data reduction algorithms can be succinctly expressed and
+efficiently coded by extracting elements with multiple calls to
+\method{popleft()}, applying the reduction function, and calling
+\method{append()} to add the result back to the queue.
+
+For example, building a balanced binary tree of nested lists entails
+reducing two adjacent nodes into one by grouping them in a list:
+
+\begin{verbatim}
+def maketree(iterable):
+    d = deque(iterable)
+    while len(d) > 1:
+        pair = [d.popleft(), d.popleft()]
+        d.append(pair)
+    return list(d)
+
+>>> print maketree('abcdefgh')
+[[[['a', 'b'], ['c', 'd']], [['e', 'f'], ['g', 'h']]]]
+
+\end{verbatim}
+
+
+
+\subsection{\class{defaultdict} objects \label{defaultdict-objects}}
+
+\begin{funcdesc}{defaultdict}{\optional{default_factory\optional{, ...}}}
+  Returns a new dictionary-like object.  \class{defaultdict} is a subclass
+  of the builtin \class{dict} class.  It overrides one method and adds one
+  writable instance variable.  The remaining functionality is the same as
+  for the \class{dict} class and is not documented here.
+
+  The first argument provides the initial value for the
+  \member{default_factory} attribute; it defaults to \code{None}.
+  All remaining arguments are treated the same as if they were
+  passed to the \class{dict} constructor, including keyword arguments.
+
+ \versionadded{2.5}
+\end{funcdesc}
+
+\class{defaultdict} objects support the following method in addition to
+the standard \class{dict} operations:
+
+\begin{methoddesc}{__missing__}{key}
+  If the \member{default_factory} attribute is \code{None}, this raises
+  an \exception{KeyError} exception with the \var{key} as argument.
+
+  If \member{default_factory} is not \code{None}, it is called without
+  arguments to provide a default value for the given \var{key}, this
+  value is inserted in the dictionary for the \var{key}, and returned.
+
+  If calling \member{default_factory} raises an exception this exception
+  is propagated unchanged.
+
+  This method is called by the \method{__getitem__} method of the
+  \class{dict} class when the requested key is not found; whatever it
+  returns or raises is then returned or raised by \method{__getitem__}.
+\end{methoddesc}
+
+\class{defaultdict} objects support the following instance variable:
+
+\begin{datadesc}{default_factory}
+  This attribute is used by the \method{__missing__} method; it is initialized
+  from the first argument to the constructor, if present, or to \code{None}, 
+  if absent.
+\end{datadesc}
+
+
+\subsubsection{\class{defaultdict} Examples \label{defaultdict-examples}}
+
+Using \class{list} as the \member{default_factory}, it is easy to group
+a sequence of key-value pairs into a dictionary of lists:
+
+\begin{verbatim}
+>>> s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
+>>> d = defaultdict(list)
+>>> for k, v in s:
+        d[k].append(v)
+
+>>> d.items()
+[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]
+\end{verbatim}
+
+When each key is encountered for the first time, it is not already in the
+mapping; so an entry is automatically created using the
+\member{default_factory} function which returns an empty \class{list}.  The
+\method{list.append()} operation then attaches the value to the new list.  When
+keys are encountered again, the look-up proceeds normally (returning the list
+for that key) and the \method{list.append()} operation adds another value to
+the list. This technique is simpler and faster than an equivalent technique
+using \method{dict.setdefault()}:
+
+\begin{verbatim}
+>>> d = {}
+>>> for k, v in s:
+	d.setdefault(k, []).append(v)
+
+>>> d.items()
+[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]
+\end{verbatim}
+
+Setting the \member{default_factory} to \class{int} makes the
+\class{defaultdict} useful for counting (like a bag or multiset in other
+languages):
+
+\begin{verbatim}
+>>> s = 'mississippi'
+>>> d = defaultdict(int)
+>>> for k in s:
+        d[k] += 1
+
+>>> d.items()
+[('i', 4), ('p', 2), ('s', 4), ('m', 1)]
+\end{verbatim}
+
+When a letter is first encountered, it is missing from the mapping, so the
+\member{default_factory} function calls \function{int()} to supply a default
+count of zero.  The increment operation then builds up the count for each
+letter.
+
+The function \function{int()} which always returns zero is just a special
+case of constant functions.  A faster and more flexible way to create
+constant functions is to use \function{itertools.repeat()} which can supply
+any constant value (not just zero):
+
+\begin{verbatim}
+>>> def constant_factory(value):
+...     return itertools.repeat(value).next
+>>> d = defaultdict(constant_factory('<missing>'))
+>>> d.update(name='John', action='ran')
+>>> '%(name)s %(action)s to %(object)s' % d
+'John ran to <missing>'
+\end{verbatim}
+
+Setting the \member{default_factory} to \class{set} makes the
+\class{defaultdict} useful for building a dictionary of sets:
+
+\begin{verbatim}
+>>> s = [('red', 1), ('blue', 2), ('red', 3), ('blue', 4), ('red', 1), ('blue', 4)]
+>>> d = defaultdict(set)
+>>> for k, v in s:
+        d[k].add(v)
+
+>>> d.items()
+[('blue', set([2, 4])), ('red', set([1, 3]))]
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/libcolorsys.tex
===================================================================
--- vendor/Python/current/Doc/lib/libcolorsys.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libcolorsys.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,54 @@
+\section{\module{colorsys} ---
+         Conversions between color systems}
+
+\declaremodule{standard}{colorsys}
+\modulesynopsis{Conversion functions between RGB and other color systems.}
+\sectionauthor{David Ascher}{da at python.net}
+
+The \module{colorsys} module defines bidirectional conversions of
+color values between colors expressed in the RGB (Red Green Blue)
+color space used in computer monitors and three other coordinate
+systems: YIQ, HLS (Hue Lightness Saturation) and HSV (Hue Saturation
+Value).  Coordinates in all of these color spaces are floating point
+values.  In the YIQ space, the Y coordinate is between 0 and 1, but
+the I and Q coordinates can be positive or negative.  In all other
+spaces, the coordinates are all between 0 and 1.
+
+More information about color spaces can be found at 
+\url{http://www.poynton.com/ColorFAQ.html}.
+
+The \module{colorsys} module defines the following functions:
+
+\begin{funcdesc}{rgb_to_yiq}{r, g, b}
+Convert the color from RGB coordinates to YIQ coordinates.
+\end{funcdesc}
+
+\begin{funcdesc}{yiq_to_rgb}{y, i, q}
+Convert the color from YIQ coordinates to RGB coordinates.
+\end{funcdesc}
+
+\begin{funcdesc}{rgb_to_hls}{r, g, b}
+Convert the color from RGB coordinates to HLS coordinates.
+\end{funcdesc}
+
+\begin{funcdesc}{hls_to_rgb}{h, l, s}
+Convert the color from HLS coordinates to RGB coordinates.
+\end{funcdesc}
+
+\begin{funcdesc}{rgb_to_hsv}{r, g, b}
+Convert the color from RGB coordinates to HSV coordinates.
+\end{funcdesc}
+
+\begin{funcdesc}{hsv_to_rgb}{h, s, v}
+Convert the color from HSV coordinates to RGB coordinates.
+\end{funcdesc}
+
+Example:
+
+\begin{verbatim}
+>>> import colorsys
+>>> colorsys.rgb_to_hsv(.3, .4, .2)
+(0.25, 0.5, 0.4)
+>>> colorsys.hsv_to_rgb(0.25, 0.5, 0.4)
+(0.3, 0.4, 0.2)
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/libcommands.tex
===================================================================
--- vendor/Python/current/Doc/lib/libcommands.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libcommands.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,62 @@
+\section{\module{commands} ---
+         Utilities for running commands}
+
+\declaremodule{standard}{commands}
+  \platform{Unix}
+\modulesynopsis{Utility functions for running external commands.}
+\sectionauthor{Sue Williams}{sbw at provis.com}
+
+
+The \module{commands} module contains wrapper functions for
+\function{os.popen()} which take a system command as a string and
+return any output generated by the command and, optionally, the exit
+status.
+
+The \module{subprocess} module provides more powerful facilities for
+spawning new processes and retrieving their results.  Using the
+\module{subprocess} module is preferable to using the \module{commands}
+module.
+
+The \module{commands} module defines the following functions:
+
+
+\begin{funcdesc}{getstatusoutput}{cmd}
+Execute the string \var{cmd} in a shell with \function{os.popen()} and
+return a 2-tuple \code{(\var{status}, \var{output})}.  \var{cmd} is
+actually run as \code{\{ \var{cmd} ; \} 2>\&1}, so that the returned
+output will contain output or error messages. A trailing newline is
+stripped from the output. The exit status for the command can be
+interpreted according to the rules for the C function
+\cfunction{wait()}.
+\end{funcdesc}
+
+\begin{funcdesc}{getoutput}{cmd}
+Like \function{getstatusoutput()}, except the exit status is ignored
+and the return value is a string containing the command's output.  
+\end{funcdesc}
+
+\begin{funcdesc}{getstatus}{file}
+Return the output of \samp{ls -ld \var{file}} as a string.  This
+function uses the \function{getoutput()} function, and properly
+escapes backslashes and dollar signs in the argument.
+\end{funcdesc}
+
+Example:
+
+\begin{verbatim}
+>>> import commands
+>>> commands.getstatusoutput('ls /bin/ls')
+(0, '/bin/ls')
+>>> commands.getstatusoutput('cat /bin/junk')
+(256, 'cat: /bin/junk: No such file or directory')
+>>> commands.getstatusoutput('/bin/junk')
+(256, 'sh: /bin/junk: not found')
+>>> commands.getoutput('ls /bin/ls')
+'/bin/ls'
+>>> commands.getstatus('/bin/ls')
+'-rwxr-xr-x  1 root        13352 Oct 14  1994 /bin/ls'
+\end{verbatim}
+
+\begin{seealso}
+  \seemodule{subprocess}{Module for spawning and managing subprocesses.}
+\end{seealso}

Added: vendor/Python/current/Doc/lib/libcompileall.tex
===================================================================
--- vendor/Python/current/Doc/lib/libcompileall.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libcompileall.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,63 @@
+\section{\module{compileall} ---
+         Byte-compile Python libraries}
+
+\declaremodule{standard}{compileall}
+\modulesynopsis{Tools for byte-compiling all Python source files in a
+                directory tree.}
+
+
+This module provides some utility functions to support installing
+Python libraries.  These functions compile Python source files in a
+directory tree, allowing users without permission to write to the
+libraries to take advantage of cached byte-code files.
+
+The source file for this module may also be used as a script to
+compile Python sources in directories named on the command line or in
+\code{sys.path}.
+
+
+\begin{funcdesc}{compile_dir}{dir\optional{, maxlevels\optional{,
+                              ddir\optional{, force\optional{, 
+                              rx\optional{, quiet}}}}}}
+  Recursively descend the directory tree named by \var{dir}, compiling
+  all \file{.py} files along the way.  The \var{maxlevels} parameter
+  is used to limit the depth of the recursion; it defaults to
+  \code{10}.  If \var{ddir} is given, it is used as the base path from 
+  which the filenames used in error messages will be generated.  If
+  \var{force} is true, modules are re-compiled even if the timestamps
+  are up to date. 
+
+  If \var{rx} is given, it specifies a regular expression of file
+  names to exclude from the search; that expression is searched for in
+  the full path.
+
+  If \var{quiet} is true, nothing is printed to the standard output
+  in normal operation.
+\end{funcdesc}
+
+\begin{funcdesc}{compile_path}{\optional{skip_curdir\optional{,
+                               maxlevels\optional{, force}}}}
+  Byte-compile all the \file{.py} files found along \code{sys.path}.
+  If \var{skip_curdir} is true (the default), the current directory is
+  not included in the search.  The \var{maxlevels} and
+  \var{force} parameters default to \code{0} and are passed to the
+  \function{compile_dir()} function.
+\end{funcdesc}
+
+To force a recompile of all the \file{.py} files in the \file{Lib/}
+subdirectory and all its subdirectories:
+
+\begin{verbatim}
+import compileall
+
+compileall.compile_dir('Lib/', force=True)
+
+# Perform same compilation, excluding files in .svn directories.
+import re
+compileall.compile_dir('Lib/', rx=re.compile('/[.]svn'), force=True)
+\end{verbatim}
+
+
+\begin{seealso}
+  \seemodule[pycompile]{py_compile}{Byte-compile a single source file.}
+\end{seealso}

Added: vendor/Python/current/Doc/lib/libconsts.tex
===================================================================
--- vendor/Python/current/Doc/lib/libconsts.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libconsts.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,31 @@
+\section{Built-in Constants}
+
+A small number of constants live in the built-in namespace.  They are:
+
+\begin{datadesc}{False}
+  The false value of the \class{bool} type.
+  \versionadded{2.3}
+\end{datadesc}
+
+\begin{datadesc}{True}
+  The true value of the \class{bool} type.
+  \versionadded{2.3}
+\end{datadesc}
+
+\begin{datadesc}{None}
+  The sole value of \code{\refmodule{types}.NoneType}.  \code{None} is
+  frequently used to represent the absence of a value, as when default
+  arguments are not passed to a function.
+\end{datadesc}
+
+\begin{datadesc}{NotImplemented}
+  Special value which can be returned by the ``rich comparison''
+  special methods (\method{__eq__()}, \method{__lt__()}, and friends),
+  to indicate that the comparison is not implemented with respect to
+  the other type.
+\end{datadesc}
+
+\begin{datadesc}{Ellipsis}
+  Special value used in conjunction with extended slicing syntax.
+  % XXX Someone who understands extended slicing should fill in here.
+\end{datadesc}

Added: vendor/Python/current/Doc/lib/libcontextlib.tex
===================================================================
--- vendor/Python/current/Doc/lib/libcontextlib.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libcontextlib.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,130 @@
+\section{\module{contextlib} ---
+         Utilities for \keyword{with}-statement contexts.}
+
+\declaremodule{standard}{contextlib}
+\modulesynopsis{Utilities for \keyword{with}-statement contexts.}
+
+\versionadded{2.5}
+
+This module provides utilities for common tasks involving the
+\keyword{with} statement.
+
+Functions provided:
+
+\begin{funcdesc}{contextmanager}{func}
+This function is a decorator that can be used to define a factory
+function for \keyword{with} statement context managers, without
+needing to create a class or separate \method{__enter__()} and
+\method{__exit__()} methods.
+
+A simple example (this is not recommended as a real way of
+generating HTML!):
+
+\begin{verbatim}
+from __future__ import with_statement
+from contextlib import contextmanager
+
+ at contextmanager
+def tag(name):
+    print "<%s>" % name
+    yield
+    print "</%s>" % name
+
+>>> with tag("h1"):
+...    print "foo"
+...
+<h1>
+foo
+</h1>
+\end{verbatim}
+
+The function being decorated must return a generator-iterator when
+called. This iterator must yield exactly one value, which will be
+bound to the targets in the \keyword{with} statement's \keyword{as}
+clause, if any.
+
+At the point where the generator yields, the block nested in the
+\keyword{with} statement is executed.  The generator is then resumed
+after the block is exited.  If an unhandled exception occurs in the
+block, it is reraised inside the generator at the point where the yield
+occurred.  Thus, you can use a
+\keyword{try}...\keyword{except}...\keyword{finally} statement to trap
+the error (if any), or ensure that some cleanup takes place. If an
+exception is trapped merely in order to log it or to perform some
+action (rather than to suppress it entirely), the generator must
+reraise that exception. Otherwise the generator context manager will
+indicate to the \keyword{with} statement that the exception has been
+handled, and execution will resume with the statement immediately
+following the \keyword{with} statement.
+\end{funcdesc}
+
+\begin{funcdesc}{nested}{mgr1\optional{, mgr2\optional{, ...}}}
+Combine multiple context managers into a single nested context manager.
+
+Code like this:
+
+\begin{verbatim}
+from contextlib import nested
+
+with nested(A, B, C) as (X, Y, Z):
+    do_something()
+\end{verbatim}
+
+is equivalent to this:
+
+\begin{verbatim}
+with A as X:
+    with B as Y:
+        with C as Z:
+            do_something()
+\end{verbatim}
+
+Note that if the \method{__exit__()} method of one of the nested
+context managers indicates an exception should be suppressed, no
+exception information will be passed to any remaining outer context
+managers. Similarly, if the \method{__exit__()} method of one of the
+nested managers raises an exception, any previous exception state will
+be lost; the new exception will be passed to the
+\method{__exit__()} methods of any remaining outer context managers.
+In general, \method{__exit__()} methods should avoid raising
+exceptions, and in particular they should not re-raise a
+passed-in exception.
+\end{funcdesc}
+
+\label{context-closing}
+\begin{funcdesc}{closing}{thing}
+Return a context manager that closes \var{thing} upon completion of
+the block.  This is basically equivalent to:
+
+\begin{verbatim}
+from contextlib import contextmanager
+
+ at contextmanager
+def closing(thing):
+    try:
+        yield thing
+    finally:
+        thing.close()
+\end{verbatim}
+
+And lets you write code like this:
+\begin{verbatim}
+from __future__ import with_statement
+from contextlib import closing
+import codecs
+
+with closing(urllib.urlopen('http://www.python.org')) as page:
+    for line in page:
+        print line
+\end{verbatim}
+
+without needing to explicitly close \code{page}.  Even if an error
+occurs, \code{page.close()} will be called when the \keyword{with}
+block is exited.
+\end{funcdesc}
+
+\begin{seealso}
+  \seepep{0343}{The "with" statement}
+         {The specification, background, and examples for the
+          Python \keyword{with} statement.}
+\end{seealso}

Added: vendor/Python/current/Doc/lib/libcookie.tex
===================================================================
--- vendor/Python/current/Doc/lib/libcookie.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libcookie.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,260 @@
+\section{\module{Cookie} ---
+         HTTP state management}
+
+\declaremodule{standard}{Cookie}
+\modulesynopsis{Support for HTTP state management (cookies).}
+\moduleauthor{Timothy O'Malley}{timo at alum.mit.edu}
+\sectionauthor{Moshe Zadka}{moshez at zadka.site.co.il}
+
+
+The \module{Cookie} module defines classes for abstracting the concept of 
+cookies, an HTTP state management mechanism. It supports both simple
+string-only cookies, and provides an abstraction for having any serializable
+data-type as cookie value.
+
+The module formerly strictly applied the parsing rules described in
+the \rfc{2109} and \rfc{2068} specifications.  It has since been discovered
+that MSIE 3.0x doesn't follow the character rules outlined in those
+specs.  As a result, the parsing rules used are a bit less strict.
+
+\begin{excdesc}{CookieError}
+Exception failing because of \rfc{2109} invalidity: incorrect
+attributes, incorrect \mailheader{Set-Cookie} header, etc.
+\end{excdesc}
+
+\begin{classdesc}{BaseCookie}{\optional{input}}
+This class is a dictionary-like object whose keys are strings and
+whose values are \class{Morsel} instances. Note that upon setting a key to
+a value, the value is first converted to a \class{Morsel} containing
+the key and the value.
+
+If \var{input} is given, it is passed to the \method{load()} method.
+\end{classdesc}
+
+\begin{classdesc}{SimpleCookie}{\optional{input}}
+This class derives from \class{BaseCookie} and overrides
+\method{value_decode()} and \method{value_encode()} to be the identity
+and \function{str()} respectively.
+\end{classdesc}
+
+\begin{classdesc}{SerialCookie}{\optional{input}}
+This class derives from \class{BaseCookie} and overrides
+\method{value_decode()} and \method{value_encode()} to be the
+\function{pickle.loads()} and \function{pickle.dumps()}.
+
+\deprecated{2.3}{Reading pickled values from untrusted
+cookie data is a huge security hole, as pickle strings can be crafted
+to cause arbitrary code to execute on your server.  It is supported
+for backwards compatibility only, and may eventually go away.}
+\end{classdesc}
+
+\begin{classdesc}{SmartCookie}{\optional{input}}
+This class derives from \class{BaseCookie}. It overrides
+\method{value_decode()} to be \function{pickle.loads()} if it is a
+valid pickle, and otherwise the value itself. It overrides
+\method{value_encode()} to be \function{pickle.dumps()} unless it is a
+string, in which case it returns the value itself.
+
+\deprecated{2.3}{The same security warning from \class{SerialCookie}
+applies here.}
+\end{classdesc}
+
+A further security note is warranted.  For backwards compatibility,
+the \module{Cookie} module exports a class named \class{Cookie} which
+is just an alias for \class{SmartCookie}.  This is probably a mistake
+and will likely be removed in a future version.  You should not use
+the \class{Cookie} class in your applications, for the same reason why
+you should not use the \class{SerialCookie} class.
+
+
+\begin{seealso}
+  \seemodule{cookielib}{HTTP cookie handling for web
+    \emph{clients}.  The \module{cookielib} and \module{Cookie}
+    modules do not depend on each other.}
+
+  \seerfc{2109}{HTTP State Management Mechanism}{This is the state
+                management specification implemented by this module.}
+\end{seealso}
+
+
+\subsection{Cookie Objects \label{cookie-objects}}
+
+\begin{methoddesc}[BaseCookie]{value_decode}{val}
+Return a decoded value from a string representation. Return value can
+be any type. This method does nothing in \class{BaseCookie} --- it exists
+so it can be overridden.
+\end{methoddesc}
+
+\begin{methoddesc}[BaseCookie]{value_encode}{val}
+Return an encoded value. \var{val} can be any type, but return value
+must be a string. This method does nothing in \class{BaseCookie} --- it exists
+so it can be overridden
+
+In general, it should be the case that \method{value_encode()} and 
+\method{value_decode()} are inverses on the range of \var{value_decode}.
+\end{methoddesc}
+
+\begin{methoddesc}[BaseCookie]{output}{\optional{attrs\optional{, header\optional{, sep}}}}
+Return a string representation suitable to be sent as HTTP headers.
+\var{attrs} and \var{header} are sent to each \class{Morsel}'s
+\method{output()} method. \var{sep} is used to join the headers
+together, and is by default the combination \code{'\e r\e n'} (CRLF).
+\versionchanged[The default separator has been changed from \code{'\e n'}
+to match the cookie specification]{2.5}
+\end{methoddesc}
+
+\begin{methoddesc}[BaseCookie]{js_output}{\optional{attrs}}
+Return an embeddable JavaScript snippet, which, if run on a browser which
+supports JavaScript, will act the same as if the HTTP headers was sent.
+
+The meaning for \var{attrs} is the same as in \method{output()}.
+\end{methoddesc}
+
+\begin{methoddesc}[BaseCookie]{load}{rawdata}
+If \var{rawdata} is a string, parse it as an \code{HTTP_COOKIE} and add
+the values found there as \class{Morsel}s. If it is a dictionary, it
+is equivalent to:
+
+\begin{verbatim}
+for k, v in rawdata.items():
+    cookie[k] = v
+\end{verbatim}
+\end{methoddesc}
+
+
+\subsection{Morsel Objects \label{morsel-objects}}
+
+\begin{classdesc}{Morsel}{}
+Abstract a key/value pair, which has some \rfc{2109} attributes.
+
+Morsels are dictionary-like objects, whose set of keys is constant ---
+the valid \rfc{2109} attributes, which are
+
+\begin{itemize}
+\item \code{expires}
+\item \code{path}
+\item \code{comment}
+\item \code{domain}
+\item \code{max-age}
+\item \code{secure}
+\item \code{version}
+\end{itemize}
+
+The keys are case-insensitive.
+\end{classdesc}
+
+\begin{memberdesc}[Morsel]{value}
+The value of the cookie.
+\end{memberdesc}
+
+\begin{memberdesc}[Morsel]{coded_value}
+The encoded value of the cookie --- this is what should be sent.
+\end{memberdesc}
+
+\begin{memberdesc}[Morsel]{key}
+The name of the cookie.
+\end{memberdesc}
+
+\begin{methoddesc}[Morsel]{set}{key, value, coded_value}
+Set the \var{key}, \var{value} and \var{coded_value} members.
+\end{methoddesc}
+
+\begin{methoddesc}[Morsel]{isReservedKey}{K}
+Whether \var{K} is a member of the set of keys of a \class{Morsel}.
+\end{methoddesc}
+
+\begin{methoddesc}[Morsel]{output}{\optional{attrs\optional{, header}}}
+Return a string representation of the Morsel, suitable
+to be sent as an HTTP header. By default, all the attributes are included,
+unless \var{attrs} is given, in which case it should be a list of attributes
+to use. \var{header} is by default \code{"Set-Cookie:"}.
+\end{methoddesc}
+
+\begin{methoddesc}[Morsel]{js_output}{\optional{attrs}}
+Return an embeddable JavaScript snippet, which, if run on a browser which
+supports JavaScript, will act the same as if the HTTP header was sent.
+
+The meaning for \var{attrs} is the same as in \method{output()}.
+\end{methoddesc}
+
+\begin{methoddesc}[Morsel]{OutputString}{\optional{attrs}}
+Return a string representing the Morsel, without any surrounding HTTP
+or JavaScript.
+
+The meaning for \var{attrs} is the same as in \method{output()}.
+\end{methoddesc}
+                
+
+\subsection{Example \label{cookie-example}}
+
+The following example demonstrates how to use the \module{Cookie} module.
+
+\begin{verbatim}
+>>> import Cookie
+>>> C = Cookie.SimpleCookie()
+>>> C = Cookie.SerialCookie()
+>>> C = Cookie.SmartCookie()
+>>> C["fig"] = "newton"
+>>> C["sugar"] = "wafer"
+>>> print C # generate HTTP headers
+Set-Cookie: sugar=wafer
+Set-Cookie: fig=newton
+>>> print C.output() # same thing
+Set-Cookie: sugar=wafer
+Set-Cookie: fig=newton
+>>> C = Cookie.SmartCookie()
+>>> C["rocky"] = "road"
+>>> C["rocky"]["path"] = "/cookie"
+>>> print C.output(header="Cookie:")
+Cookie: rocky=road; Path=/cookie
+>>> print C.output(attrs=[], header="Cookie:")
+Cookie: rocky=road
+>>> C = Cookie.SmartCookie()
+>>> C.load("chips=ahoy; vienna=finger") # load from a string (HTTP header)
+>>> print C
+Set-Cookie: vienna=finger
+Set-Cookie: chips=ahoy
+>>> C = Cookie.SmartCookie()
+>>> C.load('keebler="E=everybody; L=\\"Loves\\"; fudge=\\012;";')
+>>> print C
+Set-Cookie: keebler="E=everybody; L=\"Loves\"; fudge=\012;"
+>>> C = Cookie.SmartCookie()
+>>> C["oreo"] = "doublestuff"
+>>> C["oreo"]["path"] = "/"
+>>> print C
+Set-Cookie: oreo=doublestuff; Path=/
+>>> C = Cookie.SmartCookie()
+>>> C["twix"] = "none for you"
+>>> C["twix"].value
+'none for you'
+>>> C = Cookie.SimpleCookie()
+>>> C["number"] = 7 # equivalent to C["number"] = str(7)
+>>> C["string"] = "seven"
+>>> C["number"].value
+'7'
+>>> C["string"].value
+'seven'
+>>> print C
+Set-Cookie: number=7
+Set-Cookie: string=seven
+>>> C = Cookie.SerialCookie()
+>>> C["number"] = 7
+>>> C["string"] = "seven"
+>>> C["number"].value
+7
+>>> C["string"].value
+'seven'
+>>> print C
+Set-Cookie: number="I7\012."
+Set-Cookie: string="S'seven'\012p1\012."
+>>> C = Cookie.SmartCookie()
+>>> C["number"] = 7
+>>> C["string"] = "seven"
+>>> C["number"].value
+7
+>>> C["string"].value
+'seven'
+>>> print C
+Set-Cookie: number="I7\012."
+Set-Cookie: string=seven
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/libcookielib.tex
===================================================================
--- vendor/Python/current/Doc/lib/libcookielib.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libcookielib.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,720 @@
+\section{\module{cookielib} ---
+         Cookie handling for HTTP clients}
+
+\declaremodule{standard}{cookielib}
+\moduleauthor{John J. Lee}{jjl at pobox.com}
+\sectionauthor{John J. Lee}{jjl at pobox.com}
+
+\versionadded{2.4}
+
+\modulesynopsis{Cookie handling for HTTP clients}
+
+The \module{cookielib} module defines classes for automatic handling
+of HTTP cookies.  It is useful for accessing web sites that require
+small pieces of data -- \dfn{cookies} -- to be set on the client
+machine by an HTTP response from a web server, and then returned to
+the server in later HTTP requests.
+
+Both the regular Netscape cookie protocol and the protocol defined by
+\rfc{2965} are handled.  RFC 2965 handling is switched off by default.
+\rfc{2109} cookies are parsed as Netscape cookies and subsequently
+treated either as Netscape or RFC 2965 cookies according to the
+'policy' in effect.  Note that the great majority of cookies on the
+Internet are Netscape cookies.  \module{cookielib} attempts to follow
+the de-facto Netscape cookie protocol (which differs substantially
+from that set out in the original Netscape specification), including
+taking note of the \code{max-age} and \code{port} cookie-attributes
+introduced with RFC 2965.  \note{The various named parameters found in
+\mailheader{Set-Cookie} and \mailheader{Set-Cookie2} headers
+(eg. \code{domain} and \code{expires}) are conventionally referred to
+as \dfn{attributes}.  To distinguish them from Python attributes, the
+documentation for this module uses the term \dfn{cookie-attribute}
+instead}.
+
+
+The module defines the following exception:
+
+\begin{excdesc}{LoadError}
+Instances of \class{FileCookieJar} raise this exception on failure to
+load cookies from a file.  \note{For backwards-compatibility
+with Python 2.4 (which raised an \exception{IOError}),
+\exception{LoadError} is a subclass of \exception{IOError}}.
+\end{excdesc}
+
+
+The following classes are provided:
+
+\begin{classdesc}{CookieJar}{policy=\constant{None}}
+\var{policy} is an object implementing the \class{CookiePolicy}
+interface.
+
+The \class{CookieJar} class stores HTTP cookies.  It extracts cookies
+from HTTP requests, and returns them in HTTP responses.
+\class{CookieJar} instances automatically expire contained cookies
+when necessary.  Subclasses are also responsible for storing and
+retrieving cookies from a file or database.
+\end{classdesc}
+
+\begin{classdesc}{FileCookieJar}{filename, delayload=\constant{None},
+ policy=\constant{None}}
+\var{policy} is an object implementing the \class{CookiePolicy}
+interface.  For the other arguments, see the documentation for the
+corresponding attributes.
+
+A \class{CookieJar} which can load cookies from, and perhaps save
+cookies to, a file on disk.  Cookies are \strong{NOT} loaded from the
+named file until either the \method{load()} or \method{revert()}
+method is called.  Subclasses of this class are documented in section
+\ref{file-cookie-jar-classes}.
+\end{classdesc}
+
+\begin{classdesc}{CookiePolicy}{}
+This class is responsible for deciding whether each cookie should be
+accepted from / returned to the server.
+\end{classdesc}
+
+\begin{classdesc}{DefaultCookiePolicy}{
+    blocked_domains=\constant{None},
+    allowed_domains=\constant{None},
+    netscape=\constant{True}, rfc2965=\constant{False},
+    rfc2109_as_netscape=\constant{None},
+    hide_cookie2=\constant{False},
+    strict_domain=\constant{False},
+    strict_rfc2965_unverifiable=\constant{True},
+    strict_ns_unverifiable=\constant{False},
+    strict_ns_domain=\constant{DefaultCookiePolicy.DomainLiberal},
+    strict_ns_set_initial_dollar=\constant{False},
+    strict_ns_set_path=\constant{False}
+  }
+
+Constructor arguments should be passed as keyword arguments only.
+\var{blocked_domains} is a sequence of domain names that we never
+accept cookies from, nor return cookies to. \var{allowed_domains} if
+not \constant{None}, this is a sequence of the only domains for which
+we accept and return cookies.  For all other arguments, see the
+documentation for \class{CookiePolicy} and \class{DefaultCookiePolicy}
+objects.
+
+\class{DefaultCookiePolicy} implements the standard accept / reject
+rules for Netscape and RFC 2965 cookies.  By default, RFC 2109 cookies
+(ie. cookies received in a \mailheader{Set-Cookie} header with a
+version cookie-attribute of 1) are treated according to the RFC 2965
+rules.  However, if RFC 2965 handling is turned off or
+\member{rfc2109_as_netscape} is True, RFC 2109 cookies are
+'downgraded' by the \class{CookieJar} instance to Netscape cookies, by
+setting the \member{version} attribute of the \class{Cookie} instance
+to 0.  \class{DefaultCookiePolicy} also provides some parameters to
+allow some fine-tuning of policy.
+\end{classdesc}
+
+\begin{classdesc}{Cookie}{}
+This class represents Netscape, RFC 2109 and RFC 2965 cookies.  It is
+not expected that users of \module{cookielib} construct their own
+\class{Cookie} instances.  Instead, if necessary, call
+\method{make_cookies()} on a \class{CookieJar} instance.
+\end{classdesc}
+
+\begin{seealso}
+
+\seemodule{urllib2}{URL opening with automatic cookie handling.}
+
+\seemodule{Cookie}{HTTP cookie classes, principally useful for
+server-side code.  The \module{cookielib} and \module{Cookie} modules
+do not depend on each other.}
+
+\seeurl{http://wwwsearch.sf.net/ClientCookie/}{Extensions to this
+module, including a class for reading Microsoft Internet Explorer
+cookies on Windows.}
+
+\seeurl{http://www.netscape.com/newsref/std/cookie_spec.html}{The
+specification of the original Netscape cookie protocol.  Though this
+is still the dominant protocol, the 'Netscape cookie protocol'
+implemented by all the major browsers (and \module{cookielib}) only
+bears a passing resemblance to the one sketched out in
+\code{cookie_spec.html}.}
+
+\seerfc{2109}{HTTP State Management Mechanism}{Obsoleted by RFC 2965.
+Uses \mailheader{Set-Cookie} with version=1.}
+
+\seerfc{2965}{HTTP State Management Mechanism}{The Netscape protocol
+with the bugs fixed.  Uses \mailheader{Set-Cookie2} in place of
+\mailheader{Set-Cookie}.  Not widely used.}
+
+\seeurl{http://kristol.org/cookie/errata.html}{Unfinished errata to
+RFC 2965.}
+
+\seerfc{2964}{Use of HTTP State Management}{}
+
+\end{seealso}
+
+
+\subsection{CookieJar and FileCookieJar Objects \label{cookie-jar-objects}}
+
+\class{CookieJar} objects support the iterator protocol for iterating
+over contained \class{Cookie} objects.
+
+\class{CookieJar} has the following methods:
+
+\begin{methoddesc}[CookieJar]{add_cookie_header}{request}
+Add correct \mailheader{Cookie} header to \var{request}.
+
+If policy allows (ie. the \member{rfc2965} and \member{hide_cookie2}
+attributes of the \class{CookieJar}'s \class{CookiePolicy} instance
+are true and false respectively), the \mailheader{Cookie2} header is
+also added when appropriate.
+
+The \var{request} object (usually a \class{urllib2.Request} instance)
+must support the methods \method{get_full_url()}, \method{get_host()},
+\method{get_type()}, \method{unverifiable()},
+\method{get_origin_req_host()}, \method{has_header()},
+\method{get_header()}, \method{header_items()}, and
+\method{add_unredirected_header()},as documented by \module{urllib2}.
+\end{methoddesc}
+
+\begin{methoddesc}[CookieJar]{extract_cookies}{response, request}
+Extract cookies from HTTP \var{response} and store them in the
+\class{CookieJar}, where allowed by policy.
+
+The \class{CookieJar} will look for allowable \mailheader{Set-Cookie}
+and \mailheader{Set-Cookie2} headers in the \var{response} argument,
+and store cookies as appropriate (subject to the
+\method{CookiePolicy.set_ok()} method's approval).
+
+The \var{response} object (usually the result of a call to
+\method{urllib2.urlopen()}, or similar) should support an
+\method{info()} method, which returns an object with a
+\method{getallmatchingheaders()} method (usually a
+\class{mimetools.Message} instance).
+
+The \var{request} object (usually a \class{urllib2.Request} instance)
+must support the methods \method{get_full_url()}, \method{get_host()},
+\method{unverifiable()}, and \method{get_origin_req_host()}, as
+documented by \module{urllib2}.  The request is used to set default
+values for cookie-attributes as well as for checking that the cookie
+is allowed to be set.
+\end{methoddesc}
+
+\begin{methoddesc}[CookieJar]{set_policy}{policy}
+Set the \class{CookiePolicy} instance to be used.
+\end{methoddesc}
+
+\begin{methoddesc}[CookieJar]{make_cookies}{response, request}
+Return sequence of \class{Cookie} objects extracted from
+\var{response} object.
+
+See the documentation for \method{extract_cookies} for the interfaces
+required of the \var{response} and \var{request} arguments.
+\end{methoddesc}
+
+\begin{methoddesc}[CookieJar]{set_cookie_if_ok}{cookie, request}
+Set a \class{Cookie} if policy says it's OK to do so.
+\end{methoddesc}
+
+\begin{methoddesc}[CookieJar]{set_cookie}{cookie}
+Set a \class{Cookie}, without checking with policy to see whether or
+not it should be set.
+\end{methoddesc}
+
+\begin{methoddesc}[CookieJar]{clear}{\optional{domain\optional{,
+      path\optional{, name}}}}
+Clear some cookies.
+
+If invoked without arguments, clear all cookies.  If given a single
+argument, only cookies belonging to that \var{domain} will be removed.
+If given two arguments, cookies belonging to the specified
+\var{domain} and URL \var{path} are removed.  If given three
+arguments, then the cookie with the specified \var{domain}, \var{path}
+and \var{name} is removed.
+
+Raises \exception{KeyError} if no matching cookie exists.
+\end{methoddesc}
+
+\begin{methoddesc}[CookieJar]{clear_session_cookies}{}
+Discard all session cookies.
+
+Discards all contained cookies that have a true \member{discard}
+attribute (usually because they had either no \code{max-age} or
+\code{expires} cookie-attribute, or an explicit \code{discard}
+cookie-attribute).  For interactive browsers, the end of a session
+usually corresponds to closing the browser window.
+
+Note that the \method{save()} method won't save session cookies
+anyway, unless you ask otherwise by passing a true
+\var{ignore_discard} argument.
+\end{methoddesc}
+
+\class{FileCookieJar} implements the following additional methods:
+
+\begin{methoddesc}[FileCookieJar]{save}{filename=\constant{None},
+    ignore_discard=\constant{False}, ignore_expires=\constant{False}}
+Save cookies to a file.
+
+This base class raises \exception{NotImplementedError}.  Subclasses may
+leave this method unimplemented.
+
+\var{filename} is the name of file in which to save cookies.  If
+\var{filename} is not specified, \member{self.filename} is used (whose
+default is the value passed to the constructor, if any); if
+\member{self.filename} is \constant{None}, \exception{ValueError} is
+raised.
+
+\var{ignore_discard}: save even cookies set to be discarded.
+\var{ignore_expires}: save even cookies that have expired
+
+The file is overwritten if it already exists, thus wiping all the
+cookies it contains.  Saved cookies can be restored later using the
+\method{load()} or \method{revert()} methods.
+\end{methoddesc}
+
+\begin{methoddesc}[FileCookieJar]{load}{filename=\constant{None},
+    ignore_discard=\constant{False}, ignore_expires=\constant{False}}
+Load cookies from a file.
+
+Old cookies are kept unless overwritten by newly loaded ones.
+
+Arguments are as for \method{save()}.
+
+The named file must be in the format understood by the class, or
+\exception{LoadError} will be raised.  Also, \exception{IOError} may
+be raised, for example if the file does not exist.  \note{For
+backwards-compatibility with Python 2.4 (which raised
+an \exception{IOError}), \exception{LoadError} is a subclass
+of \exception{IOError}.}
+\end{methoddesc}
+
+\begin{methoddesc}[FileCookieJar]{revert}{filename=\constant{None},
+    ignore_discard=\constant{False}, ignore_expires=\constant{False}}
+Clear all cookies and reload cookies from a saved file.
+
+\method{revert()} can raise the same exceptions as \method{load()}.
+If there is a failure, the object's state will not be altered.
+\end{methoddesc}
+
+\class{FileCookieJar} instances have the following public attributes:
+
+\begin{memberdesc}{filename}
+Filename of default file in which to keep cookies.  This attribute may
+be assigned to.
+\end{memberdesc}
+
+\begin{memberdesc}{delayload}
+If true, load cookies lazily from disk.  This attribute should not be
+assigned to.  This is only a hint, since this only affects
+performance, not behaviour (unless the cookies on disk are changing).
+A \class{CookieJar} object may ignore it.  None of the
+\class{FileCookieJar} classes included in the standard library lazily
+loads cookies.
+\end{memberdesc}
+
+
+\subsection{FileCookieJar subclasses and co-operation with web browsers
+  \label{file-cookie-jar-classes}}
+
+The following \class{CookieJar} subclasses are provided for reading
+and writing .  Further \class{CookieJar} subclasses, including one
+that reads Microsoft Internet Explorer cookies, are available at
+\url{http://wwwsearch.sf.net/ClientCookie/}.
+
+\begin{classdesc}{MozillaCookieJar}{filename, delayload=\constant{None},
+ policy=\constant{None}}
+A \class{FileCookieJar} that can load from and save cookies to disk in
+the Mozilla \code{cookies.txt} file format (which is also used by the
+Lynx and Netscape browsers).  \note{This loses information about RFC
+2965 cookies, and also about newer or non-standard cookie-attributes
+such as \code{port}.}
+
+\warning{Back up your cookies before saving if you have cookies whose
+loss / corruption would be inconvenient (there are some subtleties
+which may lead to slight changes in the file over a load / save
+round-trip).}
+
+Also note that cookies saved while Mozilla is running will get
+clobbered by Mozilla.
+\end{classdesc}
+
+\begin{classdesc}{LWPCookieJar}{filename, delayload=\constant{None},
+ policy=\constant{None}}
+A \class{FileCookieJar} that can load from and save cookies to disk in
+format compatible with the libwww-perl library's \code{Set-Cookie3}
+file format.  This is convenient if you want to store cookies in a
+human-readable file.
+\end{classdesc}
+
+
+\subsection{CookiePolicy Objects \label{cookie-policy-objects}}
+
+Objects implementing the \class{CookiePolicy} interface have the
+following methods:
+
+\begin{methoddesc}[CookiePolicy]{set_ok}{cookie, request}
+Return boolean value indicating whether cookie should be accepted from server.
+
+\var{cookie} is a \class{cookielib.Cookie} instance.  \var{request} is
+an object implementing the interface defined by the documentation for
+\method{CookieJar.extract_cookies()}.
+\end{methoddesc}
+
+\begin{methoddesc}[CookiePolicy]{return_ok}{cookie, request}
+Return boolean value indicating whether cookie should be returned to server.
+
+\var{cookie} is a \class{cookielib.Cookie} instance.  \var{request} is
+an object implementing the interface defined by the documentation for
+\method{CookieJar.add_cookie_header()}.
+\end{methoddesc}
+
+\begin{methoddesc}[CookiePolicy]{domain_return_ok}{domain, request}
+Return false if cookies should not be returned, given cookie domain.
+
+This method is an optimization.  It removes the need for checking
+every cookie with a particular domain (which might involve reading
+many files).  Returning true from \method{domain_return_ok()} and
+\method{path_return_ok()} leaves all the work to \method{return_ok()}.
+
+If \method{domain_return_ok()} returns true for the cookie domain,
+\method{path_return_ok()} is called for the cookie path.  Otherwise,
+\method{path_return_ok()} and \method{return_ok()} are never called
+for that cookie domain.  If \method{path_return_ok()} returns true,
+\method{return_ok()} is called with the \class{Cookie} object itself
+for a full check.  Otherwise, \method{return_ok()} is never called for
+that cookie path.
+
+Note that \method{domain_return_ok()} is called for every
+\emph{cookie} domain, not just for the \emph{request} domain.  For
+example, the function might be called with both \code{".example.com"}
+and \code{"www.example.com"} if the request domain is
+\code{"www.example.com"}.  The same goes for
+\method{path_return_ok()}.
+
+The \var{request} argument is as documented for \method{return_ok()}.
+\end{methoddesc}
+
+\begin{methoddesc}[CookiePolicy]{path_return_ok}{path, request}
+Return false if cookies should not be returned, given cookie path.
+
+See the documentation for \method{domain_return_ok()}.
+\end{methoddesc}
+
+
+In addition to implementing the methods above, implementations of the
+\class{CookiePolicy} interface must also supply the following
+attributes, indicating which protocols should be used, and how.  All
+of these attributes may be assigned to.
+
+\begin{memberdesc}{netscape}
+Implement Netscape protocol.
+\end{memberdesc}
+\begin{memberdesc}{rfc2965}
+Implement RFC 2965 protocol.
+\end{memberdesc}
+\begin{memberdesc}{hide_cookie2}
+Don't add \mailheader{Cookie2} header to requests (the presence of
+this header indicates to the server that we understand RFC 2965
+cookies).
+\end{memberdesc}
+
+The most useful way to define a \class{CookiePolicy} class is by
+subclassing from \class{DefaultCookiePolicy} and overriding some or
+all of the methods above.  \class{CookiePolicy} itself may be used as
+a 'null policy' to allow setting and receiving any and all cookies
+(this is unlikely to be useful).
+
+
+\subsection{DefaultCookiePolicy Objects \label{default-cookie-policy-objects}}
+
+Implements the standard rules for accepting and returning cookies.
+
+Both RFC 2965 and Netscape cookies are covered.  RFC 2965 handling is
+switched off by default.
+
+The easiest way to provide your own policy is to override this class
+and call its methods in your overridden implementations before adding
+your own additional checks:
+
+\begin{verbatim}
+import cookielib
+class MyCookiePolicy(cookielib.DefaultCookiePolicy):
+    def set_ok(self, cookie, request):
+        if not cookielib.DefaultCookiePolicy.set_ok(self, cookie, request):
+            return False
+        if i_dont_want_to_store_this_cookie(cookie):
+            return False
+        return True
+\end{verbatim}
+
+In addition to the features required to implement the
+\class{CookiePolicy} interface, this class allows you to block and
+allow domains from setting and receiving cookies.  There are also some
+strictness switches that allow you to tighten up the rather loose
+Netscape protocol rules a little bit (at the cost of blocking some
+benign cookies).
+
+A domain blacklist and whitelist is provided (both off by default).
+Only domains not in the blacklist and present in the whitelist (if the
+whitelist is active) participate in cookie setting and returning.  Use
+the \var{blocked_domains} constructor argument, and
+\method{blocked_domains()} and \method{set_blocked_domains()} methods
+(and the corresponding argument and methods for
+\var{allowed_domains}).  If you set a whitelist, you can turn it off
+again by setting it to \constant{None}.
+
+Domains in block or allow lists that do not start with a dot must
+equal the cookie domain to be matched.  For example,
+\code{"example.com"} matches a blacklist entry of
+\code{"example.com"}, but \code{"www.example.com"} does not.  Domains
+that do start with a dot are matched by more specific domains too.
+For example, both \code{"www.example.com"} and
+\code{"www.coyote.example.com"} match \code{".example.com"} (but
+\code{"example.com"} itself does not).  IP addresses are an exception,
+and must match exactly.  For example, if blocked_domains contains
+\code{"192.168.1.2"} and \code{".168.1.2"}, 192.168.1.2 is blocked,
+but 193.168.1.2 is not.
+
+\class{DefaultCookiePolicy} implements the following additional
+methods:
+
+\begin{methoddesc}[DefaultCookiePolicy]{blocked_domains}{}
+Return the sequence of blocked domains (as a tuple).
+\end{methoddesc}
+
+\begin{methoddesc}[DefaultCookiePolicy]{set_blocked_domains}
+  {blocked_domains}
+Set the sequence of blocked domains.
+\end{methoddesc}
+
+\begin{methoddesc}[DefaultCookiePolicy]{is_blocked}{domain}
+Return whether \var{domain} is on the blacklist for setting or
+receiving cookies.
+\end{methoddesc}
+
+\begin{methoddesc}[DefaultCookiePolicy]{allowed_domains}{}
+Return \constant{None}, or the sequence of allowed domains (as a tuple).
+\end{methoddesc}
+
+\begin{methoddesc}[DefaultCookiePolicy]{set_allowed_domains}
+  {allowed_domains}
+Set the sequence of allowed domains, or \constant{None}.
+\end{methoddesc}
+
+\begin{methoddesc}[DefaultCookiePolicy]{is_not_allowed}{domain}
+Return whether \var{domain} is not on the whitelist for setting or
+receiving cookies.
+\end{methoddesc}
+
+\class{DefaultCookiePolicy} instances have the following attributes,
+which are all initialised from the constructor arguments of the same
+name, and which may all be assigned to.
+
+\begin{memberdesc}{rfc2109_as_netscape}
+If true, request that the \class{CookieJar} instance downgrade RFC
+2109 cookies (ie. cookies received in a \mailheader{Set-Cookie} header
+with a version cookie-attribute of 1) to Netscape cookies by setting
+the version attribute of the \class{Cookie} instance to 0.  The
+default value is \constant{None}, in which case RFC 2109 cookies are
+downgraded if and only if RFC 2965 handling is turned off.  Therefore,
+RFC 2109 cookies are downgraded by default.
+\versionadded{2.5}
+\end{memberdesc}
+
+General strictness switches:
+
+\begin{memberdesc}{strict_domain}
+Don't allow sites to set two-component domains with country-code
+top-level domains like \code{.co.uk}, \code{.gov.uk},
+\code{.co.nz}.etc.  This is far from perfect and isn't guaranteed to
+work!
+\end{memberdesc}
+
+RFC 2965 protocol strictness switches:
+
+\begin{memberdesc}{strict_rfc2965_unverifiable}
+Follow RFC 2965 rules on unverifiable transactions (usually, an
+unverifiable transaction is one resulting from a redirect or a request
+for an image hosted on another site).  If this is false, cookies are
+\emph{never} blocked on the basis of verifiability
+\end{memberdesc}
+
+Netscape protocol strictness switches:
+
+\begin{memberdesc}{strict_ns_unverifiable}
+apply RFC 2965 rules on unverifiable transactions even to Netscape
+cookies
+\end{memberdesc}
+\begin{memberdesc}{strict_ns_domain}
+Flags indicating how strict to be with domain-matching rules for
+Netscape cookies.  See below for acceptable values.
+\end{memberdesc}
+\begin{memberdesc}{strict_ns_set_initial_dollar}
+Ignore cookies in Set-Cookie: headers that have names starting with
+\code{'\$'}.
+\end{memberdesc}
+\begin{memberdesc}{strict_ns_set_path}
+Don't allow setting cookies whose path doesn't path-match request URI.
+\end{memberdesc}
+
+\member{strict_ns_domain} is a collection of flags.  Its value is
+constructed by or-ing together (for example,
+\code{DomainStrictNoDots|DomainStrictNonDomain} means both flags are
+set).
+
+\begin{memberdesc}{DomainStrictNoDots}
+When setting cookies, the 'host prefix' must not contain a dot
+(eg. \code{www.foo.bar.com} can't set a cookie for \code{.bar.com},
+because \code{www.foo} contains a dot).
+\end{memberdesc}
+\begin{memberdesc}{DomainStrictNonDomain}
+Cookies that did not explicitly specify a \code{domain}
+cookie-attribute can only be returned to a domain equal to the domain
+that set the cookie (eg. \code{spam.example.com} won't be returned
+cookies from \code{example.com} that had no \code{domain}
+cookie-attribute).
+\end{memberdesc}
+\begin{memberdesc}{DomainRFC2965Match}
+When setting cookies, require a full RFC 2965 domain-match.
+\end{memberdesc}
+
+The following attributes are provided for convenience, and are the
+most useful combinations of the above flags:
+
+\begin{memberdesc}{DomainLiberal}
+Equivalent to 0 (ie. all of the above Netscape domain strictness flags
+switched off).
+\end{memberdesc}
+\begin{memberdesc}{DomainStrict}
+Equivalent to \code{DomainStrictNoDots|DomainStrictNonDomain}.
+\end{memberdesc}
+
+
+\subsection{Cookie Objects \label{cookie-objects}}
+
+\class{Cookie} instances have Python attributes roughly corresponding
+to the standard cookie-attributes specified in the various cookie
+standards.  The correspondence is not one-to-one, because there are
+complicated rules for assigning default values, because the
+\code{max-age} and \code{expires} cookie-attributes contain equivalent
+information, and because RFC 2109 cookies may be 'downgraded' by
+\module{cookielib} from version 1 to version 0 (Netscape) cookies.
+
+Assignment to these attributes should not be necessary other than in
+rare circumstances in a \class{CookiePolicy} method.  The class does
+not enforce internal consistency, so you should know what you're
+doing if you do that.
+
+\begin{memberdesc}[Cookie]{version}
+Integer or \constant{None}.  Netscape cookies have \member{version} 0.
+RFC 2965 and RFC 2109 cookies have a \code{version} cookie-attribute
+of 1.  However, note that \module{cookielib} may 'downgrade' RFC 2109
+cookies to Netscape cookies, in which case \member{version} is 0.
+\end{memberdesc}
+\begin{memberdesc}[Cookie]{name}
+Cookie name (a string).
+\end{memberdesc}
+\begin{memberdesc}[Cookie]{value}
+Cookie value (a string), or \constant{None}.
+\end{memberdesc}
+\begin{memberdesc}[Cookie]{port}
+String representing a port or a set of ports (eg. '80', or '80,8080'),
+or \constant{None}.
+\end{memberdesc}
+\begin{memberdesc}[Cookie]{path}
+Cookie path (a string, eg. \code{'/acme/rocket_launchers'}).
+\end{memberdesc}
+\begin{memberdesc}[Cookie]{secure}
+True if cookie should only be returned over a secure connection.
+\end{memberdesc}
+\begin{memberdesc}[Cookie]{expires}
+Integer expiry date in seconds since epoch, or \constant{None}.  See
+also the \method{is_expired()} method.
+\end{memberdesc}
+\begin{memberdesc}[Cookie]{discard}
+True if this is a session cookie.
+\end{memberdesc}
+\begin{memberdesc}[Cookie]{comment}
+String comment from the server explaining the function of this cookie,
+or \constant{None}.
+\end{memberdesc}
+\begin{memberdesc}[Cookie]{comment_url}
+URL linking to a comment from the server explaining the function of
+this cookie, or \constant{None}.
+\end{memberdesc}
+\begin{memberdesc}[Cookie]{rfc2109}
+True if this cookie was received as an RFC 2109 cookie (ie. the cookie
+arrived in a \mailheader{Set-Cookie} header, and the value of the
+Version cookie-attribute in that header was 1).  This attribute is
+provided because \module{cookielib} may 'downgrade' RFC 2109 cookies
+to Netscape cookies, in which case \member{version} is 0.
+\versionadded{2.5}
+\end{memberdesc}
+
+\begin{memberdesc}[Cookie]{port_specified}
+True if a port or set of ports was explicitly specified by the server
+(in the \mailheader{Set-Cookie} / \mailheader{Set-Cookie2} header).
+\end{memberdesc}
+\begin{memberdesc}[Cookie]{domain_specified}
+True if a domain was explicitly specified by the server.
+\end{memberdesc}
+\begin{memberdesc}[Cookie]{domain_initial_dot}
+True if the domain explicitly specified by the server began with a
+dot (\code{'.'}).
+\end{memberdesc}
+
+Cookies may have additional non-standard cookie-attributes.  These may
+be accessed using the following methods:
+
+\begin{methoddesc}[Cookie]{has_nonstandard_attr}{name}
+Return true if cookie has the named cookie-attribute.
+\end{methoddesc}
+\begin{methoddesc}[Cookie]{get_nonstandard_attr}{name, default=\constant{None}}
+If cookie has the named cookie-attribute, return its value.
+Otherwise, return \var{default}.
+\end{methoddesc}
+\begin{methoddesc}[Cookie]{set_nonstandard_attr}{name, value}
+Set the value of the named cookie-attribute.
+\end{methoddesc}
+
+The \class{Cookie} class also defines the following method:
+
+\begin{methoddesc}[Cookie]{is_expired}{\optional{now=\constant{None}}}
+True if cookie has passed the time at which the server requested it
+should expire.  If \var{now} is given (in seconds since the epoch),
+return whether the cookie has expired at the specified time.
+\end{methoddesc}
+
+
+\subsection{Examples \label{cookielib-examples}}
+
+The first example shows the most common usage of \module{cookielib}:
+
+\begin{verbatim}
+import cookielib, urllib2
+cj = cookielib.CookieJar()
+opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
+r = opener.open("http://example.com/")
+\end{verbatim}
+
+This example illustrates how to open a URL using your Netscape,
+Mozilla, or Lynx cookies (assumes \UNIX{}/Netscape convention for
+location of the cookies file):
+
+\begin{verbatim}
+import os, cookielib, urllib2
+cj = cookielib.MozillaCookieJar()
+cj.load(os.path.join(os.environ["HOME"], ".netscape/cookies.txt"))
+opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
+r = opener.open("http://example.com/")
+\end{verbatim}
+
+The next example illustrates the use of \class{DefaultCookiePolicy}.
+Turn on RFC 2965 cookies, be more strict about domains when setting
+and returning Netscape cookies, and block some domains from setting
+cookies or having them returned:
+
+\begin{verbatim}
+import urllib2
+from cookielib import CookieJar, DefaultCookiePolicy
+policy = DefaultCookiePolicy(
+    rfc2965=True, strict_ns_domain=Policy.DomainStrict,
+    blocked_domains=["ads.net", ".ads.net"])
+cj = CookieJar(policy)
+opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
+r = opener.open("http://example.com/")
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/libcopy.tex
===================================================================
--- vendor/Python/current/Doc/lib/libcopy.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libcopy.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,97 @@
+\section{\module{copy} ---
+         Shallow and deep copy operations}
+
+\declaremodule{standard}{copy}
+\modulesynopsis{Shallow and deep copy operations.}
+
+
+This module provides generic (shallow and deep) copying operations.
+\withsubitem{(in copy)}{\ttindex{copy()}\ttindex{deepcopy()}}
+
+Interface summary:
+
+\begin{verbatim}
+import copy
+
+x = copy.copy(y)        # make a shallow copy of y
+x = copy.deepcopy(y)    # make a deep copy of y
+\end{verbatim}
+%
+For module specific errors, \exception{copy.error} is raised.
+
+The difference between shallow and deep copying is only relevant for
+compound objects (objects that contain other objects, like lists or
+class instances):
+
+\begin{itemize}
+
+\item
+A \emph{shallow copy} constructs a new compound object and then (to the
+extent possible) inserts \emph{references} into it to the objects found
+in the original.
+
+\item
+A \emph{deep copy} constructs a new compound object and then,
+recursively, inserts \emph{copies} into it of the objects found in the
+original.
+
+\end{itemize}
+
+Two problems often exist with deep copy operations that don't exist
+with shallow copy operations:
+
+\begin{itemize}
+
+\item
+Recursive objects (compound objects that, directly or indirectly,
+contain a reference to themselves) may cause a recursive loop.
+
+\item
+Because deep copy copies \emph{everything} it may copy too much,
+e.g., administrative data structures that should be shared even
+between copies.
+
+\end{itemize}
+
+The \function{deepcopy()} function avoids these problems by:
+
+\begin{itemize}
+
+\item
+keeping a ``memo'' dictionary of objects already copied during the current
+copying pass; and
+
+\item
+letting user-defined classes override the copying operation or the
+set of components copied.
+
+\end{itemize}
+
+This module does not copy types like module, method,
+stack trace, stack frame, file, socket, window, array, or any similar
+types.  It does ``copy'' functions and classes (shallow and deeply),
+by returning the original object unchanged; this is compatible with
+the way these are treated by the \module{pickle} module.
+\versionchanged[Added copying functions]{2.5}
+
+Classes can use the same interfaces to control copying that they use
+to control pickling.  See the description of module
+\refmodule{pickle}\refstmodindex{pickle} for information on these
+methods.  The \module{copy} module does not use the
+\refmodule[copyreg]{copy_reg} registration module.
+
+In order for a class to define its own copy implementation, it can
+define special methods \method{__copy__()} and
+\method{__deepcopy__()}.  The former is called to implement the
+shallow copy operation; no additional arguments are passed.  The
+latter is called to implement the deep copy operation; it is passed
+one argument, the memo dictionary.  If the \method{__deepcopy__()}
+implementation needs to make a deep copy of a component, it should
+call the \function{deepcopy()} function with the component as first
+argument and the memo dictionary as second argument.
+\withsubitem{(copy protocol)}{\ttindex{__copy__()}\ttindex{__deepcopy__()}}
+
+\begin{seealso}
+\seemodule{pickle}{Discussion of the special methods used to
+support object state retrieval and restoration.}
+\end{seealso}

Added: vendor/Python/current/Doc/lib/libcopyreg.tex
===================================================================
--- vendor/Python/current/Doc/lib/libcopyreg.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libcopyreg.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,40 @@
+\section{\module{copy_reg} ---
+         Register \module{pickle} support functions}
+
+\declaremodule[copyreg]{standard}{copy_reg}
+\modulesynopsis{Register \module{pickle} support functions.}
+
+
+The \module{copy_reg} module provides support for the
+\refmodule{pickle}\refstmodindex{pickle}\ and
+\refmodule{cPickle}\refbimodindex{cPickle}\ modules.  The
+\refmodule{copy}\refstmodindex{copy}\ module is likely to use this in the
+future as well.  It provides configuration information about object
+constructors which are not classes.  Such constructors may be factory
+functions or class instances.
+
+
+\begin{funcdesc}{constructor}{object}
+  Declares \var{object} to be a valid constructor.  If \var{object} is
+  not callable (and hence not valid as a constructor), raises
+  \exception{TypeError}.
+\end{funcdesc}
+
+\begin{funcdesc}{pickle}{type, function\optional{, constructor}}
+  Declares that \var{function} should be used as a ``reduction''
+  function for objects of type \var{type}; \var{type} must not be a
+  ``classic'' class object.  (Classic classes are handled differently;
+  see the documentation for the \refmodule{pickle} module for
+  details.)  \var{function} should return either a string or a tuple
+  containing two or three elements.
+
+  The optional \var{constructor} parameter, if provided, is a
+  callable object which can be used to reconstruct the object when
+  called with the tuple of arguments returned by \var{function} at
+  pickling time.  \exception{TypeError} will be raised if
+  \var{object} is a class or \var{constructor} is not callable.
+
+  See the \refmodule{pickle} module for more
+  details on the interface expected of \var{function} and
+  \var{constructor}.
+\end{funcdesc}

Added: vendor/Python/current/Doc/lib/libcrypt.tex
===================================================================
--- vendor/Python/current/Doc/lib/libcrypt.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libcrypt.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,54 @@
+\section{\module{crypt} ---
+         Function to check \UNIX{} passwords}
+
+\declaremodule{builtin}{crypt}
+  \platform{Unix}
+\modulesynopsis{The \cfunction{crypt()} function used to check
+  \UNIX\ passwords.}
+\moduleauthor{Steven D. Majewski}{sdm7g at virginia.edu}
+\sectionauthor{Steven D. Majewski}{sdm7g at virginia.edu}
+\sectionauthor{Peter Funk}{pf at artcom-gmbh.de}
+
+
+This module implements an interface to the
+\manpage{crypt}{3}\index{crypt(3)} routine, which is a one-way hash
+function based upon a modified DES\indexii{cipher}{DES} algorithm; see
+the \UNIX{} man page for further details.  Possible uses include
+allowing Python scripts to accept typed passwords from the user, or
+attempting to crack \UNIX{} passwords with a dictionary.
+
+Notice that the behavior of this module depends on the actual implementation 
+of the \manpage{crypt}{3}\index{crypt(3)} routine in the running system. 
+Therefore, any extensions available on the current implementation will also 
+be available on this module.
+\begin{funcdesc}{crypt}{word, salt} 
+  \var{word} will usually be a user's password as typed at a prompt or 
+  in a graphical interface.  \var{salt} is usually a random
+  two-character string which will be used to perturb the DES algorithm
+  in one of 4096 ways.  The characters in \var{salt} must be in the
+  set \regexp{[./a-zA-Z0-9]}.  Returns the hashed password as a
+  string, which will be composed of characters from the same alphabet
+   as the salt (the first two characters represent the salt itself).
+
+  Since a few \manpage{crypt}{3}\index{crypt(3)} extensions allow different
+  values, with different sizes in the \var{salt}, it is recommended to use 
+  the full crypted password as salt when checking for a password.
+\end{funcdesc}
+
+
+A simple example illustrating typical use:
+
+\begin{verbatim}
+import crypt, getpass, pwd
+
+def login():
+    username = raw_input('Python login:')
+    cryptedpasswd = pwd.getpwnam(username)[1]
+    if cryptedpasswd:
+        if cryptedpasswd == 'x' or cryptedpasswd == '*': 
+            raise "Sorry, currently no support for shadow passwords"
+        cleartext = getpass.getpass()
+        return crypt.crypt(cleartext, cryptedpasswd) == cryptedpasswd
+    else:
+        return 1
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/libcrypto.tex
===================================================================
--- vendor/Python/current/Doc/lib/libcrypto.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libcrypto.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,19 @@
+\chapter{Cryptographic Services}
+\label{crypto}
+\index{cryptography}
+
+The modules described in this chapter implement various algorithms of
+a cryptographic nature.  They are available at the discretion of the
+installation.  Here's an overview:
+
+\localmoduletable
+
+Hardcore cypherpunks will probably find the cryptographic modules
+written by A.M. Kuchling of further interest; the package contains
+modules for various encryption algorithms, most notably AES.  These modules
+are not distributed with Python but available separately.  See the URL
+\url{http://www.amk.ca/python/code/crypto.html} 
+for more information.
+\indexii{AES}{algorithm}
+\index{cryptography}
+\index{Kuchling, Andrew}

Added: vendor/Python/current/Doc/lib/libcsv.tex
===================================================================
--- vendor/Python/current/Doc/lib/libcsv.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libcsv.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,538 @@
+\section{\module{csv} --- CSV File Reading and Writing}
+
+\declaremodule{standard}{csv}
+\modulesynopsis{Write and read tabular data to and from delimited files.}
+\sectionauthor{Skip Montanaro}{skip at pobox.com}
+
+\versionadded{2.3}
+\index{csv}
+\indexii{data}{tabular}
+
+The so-called CSV (Comma Separated Values) format is the most common import
+and export format for spreadsheets and databases.  There is no ``CSV
+standard'', so the format is operationally defined by the many applications
+which read and write it.  The lack of a standard means that subtle
+differences often exist in the data produced and consumed by different
+applications.  These differences can make it annoying to process CSV files
+from multiple sources.  Still, while the delimiters and quoting characters
+vary, the overall format is similar enough that it is possible to write a
+single module which can efficiently manipulate such data, hiding the details
+of reading and writing the data from the programmer.
+
+The \module{csv} module implements classes to read and write tabular data in
+CSV format.  It allows programmers to say, ``write this data in the format
+preferred by Excel,'' or ``read data from this file which was generated by
+Excel,'' without knowing the precise details of the CSV format used by
+Excel.  Programmers can also describe the CSV formats understood by other
+applications or define their own special-purpose CSV formats.
+
+The \module{csv} module's \class{reader} and \class{writer} objects read and
+write sequences.  Programmers can also read and write data in dictionary
+form using the \class{DictReader} and \class{DictWriter} classes.
+
+\begin{notice}
+  This version of the \module{csv} module doesn't support Unicode
+  input.  Also, there are currently some issues regarding \ASCII{} NUL
+  characters.  Accordingly, all input should be UTF-8 or printable
+  \ASCII{} to be safe; see the examples in section~\ref{csv-examples}.
+  These restrictions will be removed in the future.
+\end{notice}
+
+\begin{seealso}
+%  \seemodule{array}{Arrays of uniformly types numeric values.}
+  \seepep{305}{CSV File API}
+         {The Python Enhancement Proposal which proposed this addition
+          to Python.}
+\end{seealso}
+
+
+\subsection{Module Contents \label{csv-contents}}
+
+The \module{csv} module defines the following functions:
+
+\begin{funcdesc}{reader}{csvfile\optional{,
+                         dialect=\code{'excel'}}\optional{, fmtparam}}
+Return a reader object which will iterate over lines in the given
+{}\var{csvfile}.  \var{csvfile} can be any object which supports the
+iterator protocol and returns a string each time its \method{next}
+method is called --- file objects and list objects are both suitable.  
+If \var{csvfile} is a file object, it must be opened with
+the 'b' flag on platforms where that makes a difference.  An optional
+{}\var{dialect} parameter can be given
+which is used to define a set of parameters specific to a particular CSV
+dialect.  It may be an instance of a subclass of the \class{Dialect}
+class or one of the strings returned by the \function{list_dialects}
+function.  The other optional {}\var{fmtparam} keyword arguments can be
+given to override individual formatting parameters in the current
+dialect.  For full details about the dialect and formatting
+parameters, see section~\ref{csv-fmt-params}, ``Dialects and Formatting
+Parameters''.
+
+All data read are returned as strings.  No automatic data type
+conversion is performed.
+
+\versionchanged[
+The parser is now stricter with respect to multi-line quoted
+fields. Previously, if a line ended within a quoted field without a
+terminating newline character, a newline would be inserted into the
+returned field. This behavior caused problems when reading files
+which contained carriage return characters within fields.  The
+behavior was changed to return the field without inserting newlines. As
+a consequence, if newlines embedded within fields are important, the
+input should be split into lines in a manner which preserves the newline
+characters]{2.5}
+
+\end{funcdesc}
+
+\begin{funcdesc}{writer}{csvfile\optional{,
+                         dialect=\code{'excel'}}\optional{, fmtparam}}
+Return a writer object responsible for converting the user's data into
+delimited strings on the given file-like object.  \var{csvfile} can be any
+object with a \function{write} method.  If \var{csvfile} is a file object,
+it must be opened with the 'b' flag on platforms where that makes a
+difference.  An optional
+{}\var{dialect} parameter can be given which is used to define a set of
+parameters specific to a particular CSV dialect.  It may be an instance
+of a subclass of the \class{Dialect} class or one of the strings
+returned by the \function{list_dialects} function.  The other optional
+{}\var{fmtparam} keyword arguments can be given to override individual
+formatting parameters in the current dialect.  For full details
+about the dialect and formatting parameters, see
+section~\ref{csv-fmt-params}, ``Dialects and Formatting Parameters''.
+To make it as easy as possible to
+interface with modules which implement the DB API, the value
+\constant{None} is written as the empty string.  While this isn't a
+reversible transformation, it makes it easier to dump SQL NULL data values
+to CSV files without preprocessing the data returned from a
+\code{cursor.fetch*()} call.  All other non-string data are stringified
+with \function{str()} before being written.
+\end{funcdesc}
+
+\begin{funcdesc}{register_dialect}{name\optional{, dialect}\optional{, fmtparam}}
+Associate \var{dialect} with \var{name}.  \var{name} must be a string
+or Unicode object. The dialect can be specified either by passing a
+sub-class of \class{Dialect}, or by \var{fmtparam} keyword arguments,
+or both, with keyword arguments overriding parameters of the dialect.
+For full details about the dialect and formatting parameters, see
+section~\ref{csv-fmt-params}, ``Dialects and Formatting Parameters''.
+\end{funcdesc}
+
+\begin{funcdesc}{unregister_dialect}{name}
+Delete the dialect associated with \var{name} from the dialect registry.  An
+\exception{Error} is raised if \var{name} is not a registered dialect
+name.
+\end{funcdesc}
+
+\begin{funcdesc}{get_dialect}{name}
+Return the dialect associated with \var{name}.  An \exception{Error} is
+raised if \var{name} is not a registered dialect name.
+\end{funcdesc}
+
+\begin{funcdesc}{list_dialects}{}
+Return the names of all registered dialects.
+\end{funcdesc}
+
+\begin{funcdesc}{field_size_limit}{\optional{new_limit}}
+  Returns the current maximum field size allowed by the parser. If
+  \var{new_limit} is given, this becomes the new limit.
+  \versionadded{2.5}
+\end{funcdesc}
+
+
+The \module{csv} module defines the following classes:
+
+\begin{classdesc}{DictReader}{csvfile\optional{,
+			      fieldnames=\constant{None},\optional{,
+                              restkey=\constant{None}\optional{,
+			      restval=\constant{None}\optional{,
+                              dialect=\code{'excel'}\optional{,
+			      *args, **kwds}}}}}}
+Create an object which operates like a regular reader but maps the
+information read into a dict whose keys are given by the optional
+{} \var{fieldnames}
+parameter.  If the \var{fieldnames} parameter is omitted, the values in
+the first row of the \var{csvfile} will be used as the fieldnames.
+If the row read has fewer fields than the fieldnames sequence,
+the value of \var{restval} will be used as the default value.  If the row
+read has more fields than the fieldnames sequence, the remaining data is
+added as a sequence keyed by the value of \var{restkey}.  If the row read
+has fewer fields than the fieldnames sequence, the remaining keys take the
+value of the optional \var{restval} parameter.  Any other optional or
+keyword arguments are passed to the underlying \class{reader} instance.
+\end{classdesc}
+
+
+\begin{classdesc}{DictWriter}{csvfile, fieldnames\optional{,
+                              restval=""\optional{,
+                              extrasaction=\code{'raise'}\optional{,
+                              dialect=\code{'excel'}\optional{,
+			      *args, **kwds}}}}}
+Create an object which operates like a regular writer but maps dictionaries
+onto output rows.  The \var{fieldnames} parameter identifies the order in
+which values in the dictionary passed to the \method{writerow()} method are
+written to the \var{csvfile}.  The optional \var{restval} parameter
+specifies the value to be written if the dictionary is missing a key in
+\var{fieldnames}.  If the dictionary passed to the \method{writerow()}
+method contains a key not found in \var{fieldnames}, the optional
+\var{extrasaction} parameter indicates what action to take.  If it is set
+to \code{'raise'} a \exception{ValueError} is raised.  If it is set to
+\code{'ignore'}, extra values in the dictionary are ignored.  Any other
+optional or keyword arguments are passed to the underlying \class{writer}
+instance.
+
+Note that unlike the \class{DictReader} class, the \var{fieldnames}
+parameter of the \class{DictWriter} is not optional.  Since Python's
+\class{dict} objects are not ordered, there is not enough information
+available to deduce the order in which the row should be written to the
+\var{csvfile}.
+
+\end{classdesc}
+
+\begin{classdesc*}{Dialect}{}
+The \class{Dialect} class is a container class relied on primarily for its
+attributes, which are used to define the parameters for a specific
+\class{reader} or \class{writer} instance.
+\end{classdesc*}
+
+\begin{classdesc}{excel}{}
+The \class{excel} class defines the usual properties of an Excel-generated
+CSV file.  It is registered with the dialect name \code{'excel'}.
+\end{classdesc}
+
+\begin{classdesc}{excel_tab}{}
+The \class{excel_tab} class defines the usual properties of an
+Excel-generated TAB-delimited file.  It is registered with the dialect name
+\code{'excel-tab'}.
+\end{classdesc}
+
+\begin{classdesc}{Sniffer}{}
+The \class{Sniffer} class is used to deduce the format of a CSV file.
+\end{classdesc}
+
+The \class{Sniffer} class provides two methods:
+
+\begin{methoddesc}{sniff}{sample\optional{,delimiters=None}}
+Analyze the given \var{sample} and return a \class{Dialect} subclass
+reflecting the parameters found.  If the optional \var{delimiters} parameter
+is given, it is interpreted as a string containing possible valid delimiter
+characters.
+\end{methoddesc}
+
+\begin{methoddesc}{has_header}{sample}
+Analyze the sample text (presumed to be in CSV format) and return
+\constant{True} if the first row appears to be a series of column
+headers.
+\end{methoddesc}
+
+
+The \module{csv} module defines the following constants:
+
+\begin{datadesc}{QUOTE_ALL}
+Instructs \class{writer} objects to quote all fields.
+\end{datadesc}
+
+\begin{datadesc}{QUOTE_MINIMAL}
+Instructs \class{writer} objects to only quote those fields which contain
+special characters such as \var{delimiter}, \var{quotechar} or any of the
+characters in \var{lineterminator}.
+\end{datadesc}
+
+\begin{datadesc}{QUOTE_NONNUMERIC}
+Instructs \class{writer} objects to quote all non-numeric
+fields. 
+
+Instructs the reader to convert all non-quoted fields to type \var{float}.
+\end{datadesc}
+
+\begin{datadesc}{QUOTE_NONE}
+Instructs \class{writer} objects to never quote fields.  When the current
+\var{delimiter} occurs in output data it is preceded by the current
+\var{escapechar} character.  If \var{escapechar} is not set, the writer
+will raise \exception{Error} if any characters that require escaping
+are encountered.
+
+Instructs \class{reader} to perform no special processing of quote characters.
+\end{datadesc}
+
+
+The \module{csv} module defines the following exception:
+
+\begin{excdesc}{Error}
+Raised by any of the functions when an error is detected.
+\end{excdesc}
+
+
+\subsection{Dialects and Formatting Parameters\label{csv-fmt-params}}
+
+To make it easier to specify the format of input and output records,
+specific formatting parameters are grouped together into dialects.  A
+dialect is a subclass of the \class{Dialect} class having a set of specific
+methods and a single \method{validate()} method.  When creating \class{reader}
+or \class{writer} objects, the programmer can specify a string or a subclass
+of the \class{Dialect} class as the dialect parameter.  In addition to, or
+instead of, the \var{dialect} parameter, the programmer can also specify
+individual formatting parameters, which have the same names as the
+attributes defined below for the \class{Dialect} class.
+
+Dialects support the following attributes:
+
+\begin{memberdesc}[Dialect]{delimiter}
+A one-character string used to separate fields.  It defaults to \code{','}.
+\end{memberdesc}
+
+\begin{memberdesc}[Dialect]{doublequote}
+Controls how instances of \var{quotechar} appearing inside a field should
+be themselves be quoted.  When \constant{True}, the character is doubled.
+When \constant{False}, the \var{escapechar} is used as a prefix to the
+\var{quotechar}.  It defaults to \constant{True}.
+
+On output, if \var{doublequote} is \constant{False} and no
+\var{escapechar} is set, \exception{Error} is raised if a \var{quotechar}
+is found in a field.
+\end{memberdesc}
+
+\begin{memberdesc}[Dialect]{escapechar}
+A one-character string used by the writer to escape the \var{delimiter} if
+\var{quoting} is set to \constant{QUOTE_NONE} and the \var{quotechar}
+if \var{doublequote} is \constant{False}. On reading, the \var{escapechar}
+removes any special meaning from the following character. It defaults
+to \constant{None}, which disables escaping.
+\end{memberdesc}
+
+\begin{memberdesc}[Dialect]{lineterminator}
+The string used to terminate lines produced by the \class{writer}.
+It defaults to \code{'\e r\e n'}. 
+
+\note{The \class{reader} is hard-coded to recognise either \code{'\e r'}
+or \code{'\e n'} as end-of-line, and ignores \var{lineterminator}. This
+behavior may change in the future.}
+\end{memberdesc}
+
+\begin{memberdesc}[Dialect]{quotechar}
+A one-character string used to quote fields containing special characters,
+such as the \var{delimiter} or \var{quotechar}, or which contain new-line
+characters.  It defaults to \code{'"'}.
+\end{memberdesc}
+
+\begin{memberdesc}[Dialect]{quoting}
+Controls when quotes should be generated by the writer and recognised
+by the reader.  It can take on any of the \constant{QUOTE_*} constants
+(see section~\ref{csv-contents}) and defaults to \constant{QUOTE_MINIMAL}.
+\end{memberdesc}
+
+\begin{memberdesc}[Dialect]{skipinitialspace}
+When \constant{True}, whitespace immediately following the \var{delimiter}
+is ignored.  The default is \constant{False}.
+\end{memberdesc}
+
+
+\subsection{Reader Objects}
+
+Reader objects (\class{DictReader} instances and objects returned by
+the \function{reader()} function) have the following public methods:
+
+\begin{methoddesc}[csv reader]{next}{}
+Return the next row of the reader's iterable object as a list, parsed
+according to the current dialect.
+\end{methoddesc}
+
+Reader objects have the following public attributes:
+
+\begin{memberdesc}[csv reader]{dialect}
+A read-only description of the dialect in use by the parser.
+\end{memberdesc}
+
+\begin{memberdesc}[csv reader]{line_num}
+ The number of lines read from the source iterator. This is not the same
+ as the number of records returned, as records can span multiple lines.
+ \versionadded{2.5}
+\end{memberdesc}
+
+
+\subsection{Writer Objects}
+
+\class{Writer} objects (\class{DictWriter} instances and objects returned by
+the \function{writer()} function) have the following public methods.  A
+{}\var{row} must be a sequence of strings or numbers for \class{Writer}
+objects and a dictionary mapping fieldnames to strings or numbers (by
+passing them through \function{str()} first) for {}\class{DictWriter}
+objects.  Note that complex numbers are written out surrounded by parens.
+This may cause some problems for other programs which read CSV files
+(assuming they support complex numbers at all).
+
+\begin{methoddesc}[csv writer]{writerow}{row}
+Write the \var{row} parameter to the writer's file object, formatted
+according to the current dialect.
+\end{methoddesc}
+
+\begin{methoddesc}[csv writer]{writerows}{rows}
+Write all the \var{rows} parameters (a list of \var{row} objects as
+described above) to the writer's file object, formatted
+according to the current dialect.
+\end{methoddesc}
+
+Writer objects have the following public attribute:
+
+\begin{memberdesc}[csv writer]{dialect}
+A read-only description of the dialect in use by the writer.
+\end{memberdesc}
+
+
+
+\subsection{Examples\label{csv-examples}}
+
+The simplest example of reading a CSV file:
+
+\begin{verbatim}
+import csv
+reader = csv.reader(open("some.csv", "rb"))
+for row in reader:
+    print row
+\end{verbatim}
+
+Reading a file with an alternate format:
+
+\begin{verbatim}
+import csv
+reader = csv.reader(open("passwd", "rb"), delimiter=':', quoting=csv.QUOTE_NONE)
+for row in reader:
+    print row
+\end{verbatim}
+
+The corresponding simplest possible writing example is:
+
+\begin{verbatim}
+import csv
+writer = csv.writer(open("some.csv", "wb"))
+writer.writerows(someiterable)
+\end{verbatim}
+
+Registering a new dialect:
+
+\begin{verbatim}
+import csv
+
+csv.register_dialect('unixpwd', delimiter=':', quoting=csv.QUOTE_NONE)
+
+reader = csv.reader(open("passwd", "rb"), 'unixpwd')
+\end{verbatim}
+
+A slightly more advanced use of the reader --- catching and reporting errors:
+
+\begin{verbatim}
+import csv, sys
+filename = "some.csv"
+reader = csv.reader(open(filename, "rb"))
+try:
+    for row in reader:
+        print row
+except csv.Error, e:
+    sys.exit('file %s, line %d: %s' % (filename, reader.line_num, e))
+\end{verbatim}
+
+And while the module doesn't directly support parsing strings, it can
+easily be done:
+
+\begin{verbatim}
+import csv
+for row in csv.reader(['one,two,three']):
+    print row
+\end{verbatim}
+
+The \module{csv} module doesn't directly support reading and writing
+Unicode, but it is 8-bit-clean save for some problems with \ASCII{} NUL
+characters.  So you can write functions or classes that handle the
+encoding and decoding for you as long as you avoid encodings like
+UTF-16 that use NULs.  UTF-8 is recommended.
+
+\function{unicode_csv_reader} below is a generator that wraps
+\class{csv.reader} to handle Unicode CSV data (a list of Unicode
+strings).  \function{utf_8_encoder} is a generator that encodes the
+Unicode strings as UTF-8, one string (or row) at a time.  The encoded
+strings are parsed by the CSV reader, and
+\function{unicode_csv_reader} decodes the UTF-8-encoded cells back
+into Unicode:
+
+\begin{verbatim}
+import csv
+
+def unicode_csv_reader(unicode_csv_data, dialect=csv.excel, **kwargs):
+    # csv.py doesn't do Unicode; encode temporarily as UTF-8:
+    csv_reader = csv.reader(utf_8_encoder(unicode_csv_data),
+                            dialect=dialect, **kwargs)
+    for row in csv_reader:
+        # decode UTF-8 back to Unicode, cell by cell:
+        yield [unicode(cell, 'utf-8') for cell in row]
+
+def utf_8_encoder(unicode_csv_data):
+    for line in unicode_csv_data:
+        yield line.encode('utf-8')
+\end{verbatim}
+
+For all other encodings the following \class{UnicodeReader} and
+\class{UnicodeWriter} classes can be used. They take an additional
+\var{encoding} parameter in their constructor and make sure that the data
+passes the real reader or writer encoded as UTF-8:
+
+\begin{verbatim}
+import csv, codecs, cStringIO
+
+class UTF8Recoder:
+    """
+    Iterator that reads an encoded stream and reencodes the input to UTF-8
+    """
+    def __init__(self, f, encoding):
+        self.reader = codecs.getreader(encoding)(f)
+
+    def __iter__(self):
+        return self
+
+    def next(self):
+        return self.reader.next().encode("utf-8")
+
+class UnicodeReader:
+    """
+    A CSV reader which will iterate over lines in the CSV file "f",
+    which is encoded in the given encoding.
+    """
+
+    def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds):
+        f = UTF8Recoder(f, encoding)
+        self.reader = csv.reader(f, dialect=dialect, **kwds)
+
+    def next(self):
+        row = self.reader.next()
+        return [unicode(s, "utf-8") for s in row]
+
+    def __iter__(self):
+        return self
+
+class UnicodeWriter:
+    """
+    A CSV writer which will write rows to CSV file "f",
+    which is encoded in the given encoding.
+    """
+
+    def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds):
+        # Redirect output to a queue
+        self.queue = cStringIO.StringIO()
+        self.writer = csv.writer(self.queue, dialect=dialect, **kwds)
+        self.stream = f
+        self.encoder = codecs.getincrementalencoder(encoding)()
+
+    def writerow(self, row):
+        self.writer.writerow([s.encode("utf-8") for s in row])
+        # Fetch UTF-8 output from the queue ...
+        data = self.queue.getvalue()
+        data = data.decode("utf-8")
+        # ... and reencode it into the target encoding
+        data = self.encoder.encode(data)
+        # write to the target stream
+        self.stream.write(data)
+        # empty queue
+        self.queue.truncate(0)
+
+    def writerows(self, rows):
+        for row in rows:
+            self.writerow(row)
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/libctypes.tex
===================================================================
--- vendor/Python/current/Doc/lib/libctypes.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libctypes.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2443 @@
+\ifx\locallinewidth\undefined\newlength{\locallinewidth}\fi
+\setlength{\locallinewidth}{\linewidth}
+\section{\module{ctypes} --- A foreign function library for Python.}
+\declaremodule{standard}{ctypes}
+\moduleauthor{Thomas Heller}{theller at python.net}
+\modulesynopsis{A foreign function library for Python.}
+\versionadded{2.5}
+
+\code{ctypes} is a foreign function library for Python.  It provides C
+compatible data types, and allows to call functions in dlls/shared
+libraries.  It can be used to wrap these libraries in pure Python.
+
+
+\subsection{ctypes tutorial\label{ctypes-ctypes-tutorial}}
+
+Note: The code samples in this tutorial uses \code{doctest} to make sure
+that they actually work.  Since some code samples behave differently
+under Linux, Windows, or Mac OS X, they contain doctest directives in
+comments.
+
+Note: Quite some code samples references the ctypes \class{c{\_}int} type.
+This type is an alias to the \class{c{\_}long} type on 32-bit systems.  So,
+you should not be confused if \class{c{\_}long} is printed if you would
+expect \class{c{\_}int} - they are actually the same type.
+
+
+\subsubsection{Loading dynamic link libraries\label{ctypes-loading-dynamic-link-libraries}}
+
+\code{ctypes} exports the \var{cdll}, and on Windows also \var{windll} and
+\var{oledll} objects to load dynamic link libraries.
+
+You load libraries by accessing them as attributes of these objects.
+\var{cdll} loads libraries which export functions using the standard
+\code{cdecl} calling convention, while \var{windll} libraries call
+functions using the \code{stdcall} calling convention. \var{oledll} also
+uses the \code{stdcall} calling convention, and assumes the functions
+return a Windows \class{HRESULT} error code. The error code is used to
+automatically raise \class{WindowsError} Python exceptions when the
+function call fails.
+
+Here are some examples for Windows, note that \code{msvcrt} is the MS
+standard C library containing most standard C functions, and uses the
+cdecl calling convention:
+\begin{verbatim}
+>>> from ctypes import *
+>>> print windll.kernel32 # doctest: +WINDOWS
+<WinDLL 'kernel32', handle ... at ...>
+>>> print cdll.msvcrt # doctest: +WINDOWS
+<CDLL 'msvcrt', handle ... at ...>
+>>> libc = cdll.msvcrt # doctest: +WINDOWS
+>>>
+\end{verbatim}
+
+Windows appends the usual '.dll' file suffix automatically.
+
+On Linux, it is required to specify the filename \emph{including} the
+extension to load a library, so attribute access does not work.
+Either the \method{LoadLibrary} method of the dll loaders should be used,
+or you should load the library by creating an instance of CDLL by
+calling the constructor:
+\begin{verbatim}
+>>> cdll.LoadLibrary("libc.so.6") # doctest: +LINUX
+<CDLL 'libc.so.6', handle ... at ...>
+>>> libc = CDLL("libc.so.6")     # doctest: +LINUX
+>>> libc                         # doctest: +LINUX
+<CDLL 'libc.so.6', handle ... at ...>
+>>>
+\end{verbatim}
+% XXX Add section for Mac OS X. 
+
+
+\subsubsection{Accessing functions from loaded dlls\label{ctypes-accessing-functions-from-loaded-dlls}}
+
+Functions are accessed as attributes of dll objects:
+\begin{verbatim}
+>>> from ctypes import *
+>>> libc.printf
+<_FuncPtr object at 0x...>
+>>> print windll.kernel32.GetModuleHandleA # doctest: +WINDOWS
+<_FuncPtr object at 0x...>
+>>> print windll.kernel32.MyOwnFunction # doctest: +WINDOWS
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+  File "ctypes.py", line 239, in __getattr__
+    func = _StdcallFuncPtr(name, self)
+AttributeError: function 'MyOwnFunction' not found
+>>>
+\end{verbatim}
+
+Note that win32 system dlls like \code{kernel32} and \code{user32} often
+export ANSI as well as UNICODE versions of a function. The UNICODE
+version is exported with an \code{W} appended to the name, while the ANSI
+version is exported with an \code{A} appended to the name. The win32
+\code{GetModuleHandle} function, which returns a \emph{module handle} for a
+given module name, has the following C prototype, and a macro is used
+to expose one of them as \code{GetModuleHandle} depending on whether
+UNICODE is defined or not:
+\begin{verbatim}
+/* ANSI version */
+HMODULE GetModuleHandleA(LPCSTR lpModuleName);
+/* UNICODE version */
+HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
+\end{verbatim}
+
+\var{windll} does not try to select one of them by magic, you must
+access the version you need by specifying \code{GetModuleHandleA} or
+\code{GetModuleHandleW} explicitely, and then call it with normal strings
+or unicode strings respectively.
+
+Sometimes, dlls export functions with names which aren't valid Python
+identifiers, like \code{"??2 at YAPAXI@Z"}. In this case you have to use
+\code{getattr} to retrieve the function:
+\begin{verbatim}
+>>> getattr(cdll.msvcrt, "??2 at YAPAXI@Z") # doctest: +WINDOWS
+<_FuncPtr object at 0x...>
+>>>
+\end{verbatim}
+
+On Windows, some dlls export functions not by name but by ordinal.
+These functions can be accessed by indexing the dll object with the
+ordinal number:
+\begin{verbatim}
+>>> cdll.kernel32[1] # doctest: +WINDOWS
+<_FuncPtr object at 0x...>
+>>> cdll.kernel32[0] # doctest: +WINDOWS
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+  File "ctypes.py", line 310, in __getitem__
+    func = _StdcallFuncPtr(name, self)
+AttributeError: function ordinal 0 not found
+>>>
+\end{verbatim}
+
+
+\subsubsection{Calling functions\label{ctypes-calling-functions}}
+
+You can call these functions like any other Python callable. This
+example uses the \code{time()} function, which returns system time in
+seconds since the \UNIX{} epoch, and the \code{GetModuleHandleA()} function,
+which returns a win32 module handle.
+
+This example calls both functions with a NULL pointer (\code{None} should
+be used as the NULL pointer):
+\begin{verbatim}
+>>> print libc.time(None) # doctest: +SKIP
+1150640792
+>>> print hex(windll.kernel32.GetModuleHandleA(None)) # doctest: +WINDOWS
+0x1d000000
+>>>
+\end{verbatim}
+
+\code{ctypes} tries to protect you from calling functions with the wrong
+number of arguments or the wrong calling convention.  Unfortunately
+this only works on Windows.  It does this by examining the stack after
+the function returns, so although an error is raised the function
+\emph{has} been called:
+\begin{verbatim}
+>>> windll.kernel32.GetModuleHandleA() # doctest: +WINDOWS
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+ValueError: Procedure probably called with not enough arguments (4 bytes missing)
+>>> windll.kernel32.GetModuleHandleA(0, 0) # doctest: +WINDOWS
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+ValueError: Procedure probably called with too many arguments (4 bytes in excess)
+>>>
+\end{verbatim}
+
+The same exception is raised when you call an \code{stdcall} function
+with the \code{cdecl} calling convention, or vice versa:
+\begin{verbatim}
+>>> cdll.kernel32.GetModuleHandleA(None) # doctest: +WINDOWS
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+ValueError: Procedure probably called with not enough arguments (4 bytes missing)
+>>>
+
+>>> windll.msvcrt.printf("spam") # doctest: +WINDOWS
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+ValueError: Procedure probably called with too many arguments (4 bytes in excess)
+>>>
+\end{verbatim}
+
+To find out the correct calling convention you have to look into the C
+header file or the documentation for the function you want to call.
+
+On Windows, \code{ctypes} uses win32 structured exception handling to
+prevent crashes from general protection faults when functions are
+called with invalid argument values:
+\begin{verbatim}
+>>> windll.kernel32.GetModuleHandleA(32) # doctest: +WINDOWS
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+WindowsError: exception: access violation reading 0x00000020
+>>>
+\end{verbatim}
+
+There are, however, enough ways to crash Python with \code{ctypes}, so
+you should be careful anyway.
+
+\code{None}, integers, longs, byte strings and unicode strings are the
+only native Python objects that can directly be used as parameters in
+these function calls.  \code{None} is passed as a C \code{NULL} pointer,
+byte strings and unicode strings are passed as pointer to the memory
+block that contains their data (\code{char *} or \code{wchar{\_}t *}).  Python
+integers and Python longs are passed as the platforms default C
+\code{int} type, their value is masked to fit into the C type.
+
+Before we move on calling functions with other parameter types, we
+have to learn more about \code{ctypes} data types.
+
+
+\subsubsection{Fundamental data types\label{ctypes-fundamental-data-types}}
+
+\code{ctypes} defines a number of primitive C compatible data types :
+\begin{quote}
+\begin{tableiii}{l|l|l}{textrm}
+{
+ctypes type
+}
+{
+C type
+}
+{
+Python type
+}
+\lineiii{
+\class{c{\_}char}
+}
+{
+\code{char}
+}
+{
+1-character
+string
+}
+\lineiii{
+\class{c{\_}wchar}
+}
+{
+\code{wchar{\_}t}
+}
+{
+1-character
+unicode string
+}
+\lineiii{
+\class{c{\_}byte}
+}
+{
+\code{char}
+}
+{
+int/long
+}
+\lineiii{
+\class{c{\_}ubyte}
+}
+{
+\code{unsigned char}
+}
+{
+int/long
+}
+\lineiii{
+\class{c{\_}short}
+}
+{
+\code{short}
+}
+{
+int/long
+}
+\lineiii{
+\class{c{\_}ushort}
+}
+{
+\code{unsigned short}
+}
+{
+int/long
+}
+\lineiii{
+\class{c{\_}int}
+}
+{
+\code{int}
+}
+{
+int/long
+}
+\lineiii{
+\class{c{\_}uint}
+}
+{
+\code{unsigned int}
+}
+{
+int/long
+}
+\lineiii{
+\class{c{\_}long}
+}
+{
+\code{long}
+}
+{
+int/long
+}
+\lineiii{
+\class{c{\_}ulong}
+}
+{
+\code{unsigned long}
+}
+{
+int/long
+}
+\lineiii{
+\class{c{\_}longlong}
+}
+{
+\code{{\_}{\_}int64} or
+\code{long long}
+}
+{
+int/long
+}
+\lineiii{
+\class{c{\_}ulonglong}
+}
+{
+\code{unsigned {\_}{\_}int64} or
+\code{unsigned long long}
+}
+{
+int/long
+}
+\lineiii{
+\class{c{\_}float}
+}
+{
+\code{float}
+}
+{
+float
+}
+\lineiii{
+\class{c{\_}double}
+}
+{
+\code{double}
+}
+{
+float
+}
+\lineiii{
+\class{c{\_}char{\_}p}
+}
+{
+\code{char *}
+(NUL terminated)
+}
+{
+string or
+\code{None}
+}
+\lineiii{
+\class{c{\_}wchar{\_}p}
+}
+{
+\code{wchar{\_}t *}
+(NUL terminated)
+}
+{
+unicode or
+\code{None}
+}
+\lineiii{
+\class{c{\_}void{\_}p}
+}
+{
+\code{void *}
+}
+{
+int/long
+or \code{None}
+}
+\end{tableiii}
+\end{quote}
+
+All these types can be created by calling them with an optional
+initializer of the correct type and value:
+\begin{verbatim}
+>>> c_int()
+c_long(0)
+>>> c_char_p("Hello, World")
+c_char_p('Hello, World')
+>>> c_ushort(-3)
+c_ushort(65533)
+>>>
+\end{verbatim}
+
+Since these types are mutable, their value can also be changed
+afterwards:
+\begin{verbatim}
+>>> i = c_int(42)
+>>> print i
+c_long(42)
+>>> print i.value
+42
+>>> i.value = -99
+>>> print i.value
+-99
+>>>
+\end{verbatim}
+
+Assigning a new value to instances of the pointer types \class{c{\_}char{\_}p},
+\class{c{\_}wchar{\_}p}, and \class{c{\_}void{\_}p} changes the \emph{memory location} they
+point to, \emph{not the contents} of the memory block (of course not,
+because Python strings are immutable):
+\begin{verbatim}
+>>> s = "Hello, World"
+>>> c_s = c_char_p(s)
+>>> print c_s
+c_char_p('Hello, World')
+>>> c_s.value = "Hi, there"
+>>> print c_s
+c_char_p('Hi, there')
+>>> print s                 # first string is unchanged
+Hello, World
+>>>
+\end{verbatim}
+
+You should be careful, however, not to pass them to functions
+expecting pointers to mutable memory. If you need mutable memory
+blocks, ctypes has a \code{create{\_}string{\_}buffer} function which creates
+these in various ways.  The current memory block contents can be
+accessed (or changed) with the \code{raw} property, if you want to access
+it as NUL terminated string, use the \code{string} property:
+\begin{verbatim}
+>>> from ctypes import *
+>>> p = create_string_buffer(3)      # create a 3 byte buffer, initialized to NUL bytes
+>>> print sizeof(p), repr(p.raw)
+3 '\x00\x00\x00'
+>>> p = create_string_buffer("Hello")      # create a buffer containing a NUL terminated string
+>>> print sizeof(p), repr(p.raw)
+6 'Hello\x00'
+>>> print repr(p.value)
+'Hello'
+>>> p = create_string_buffer("Hello", 10)  # create a 10 byte buffer
+>>> print sizeof(p), repr(p.raw)
+10 'Hello\x00\x00\x00\x00\x00'
+>>> p.value = "Hi"      
+>>> print sizeof(p), repr(p.raw)
+10 'Hi\x00lo\x00\x00\x00\x00\x00'
+>>>
+\end{verbatim}
+
+The \code{create{\_}string{\_}buffer} function replaces the \code{c{\_}buffer}
+function (which is still available as an alias), as well as the
+\code{c{\_}string} function from earlier ctypes releases.  To create a
+mutable memory block containing unicode characters of the C type
+\code{wchar{\_}t} use the \code{create{\_}unicode{\_}buffer} function.
+
+
+\subsubsection{Calling functions, continued\label{ctypes-calling-functions-continued}}
+
+Note that printf prints to the real standard output channel, \emph{not} to
+\code{sys.stdout}, so these examples will only work at the console
+prompt, not from within \emph{IDLE} or \emph{PythonWin}:
+\begin{verbatim}
+>>> printf = libc.printf
+>>> printf("Hello, %s\n", "World!")
+Hello, World!
+14
+>>> printf("Hello, %S", u"World!")
+Hello, World!
+13
+>>> printf("%d bottles of beer\n", 42)
+42 bottles of beer
+19
+>>> printf("%f bottles of beer\n", 42.5)
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+ArgumentError: argument 2: exceptions.TypeError: Don't know how to convert parameter 2
+>>>
+\end{verbatim}
+
+As has been mentioned before, all Python types except integers,
+strings, and unicode strings have to be wrapped in their corresponding
+\code{ctypes} type, so that they can be converted to the required C data
+type:
+\begin{verbatim}
+>>> printf("An int %d, a double %f\n", 1234, c_double(3.14))
+Integer 1234, double 3.1400001049
+31
+>>>
+\end{verbatim}
+
+
+\subsubsection{Calling functions with your own custom data types\label{ctypes-calling-functions-with-own-custom-data-types}}
+
+You can also customize \code{ctypes} argument conversion to allow
+instances of your own classes be used as function arguments.
+\code{ctypes} looks for an \member{{\_}as{\_}parameter{\_}} attribute and uses this as
+the function argument. Of course, it must be one of integer, string,
+or unicode:
+\begin{verbatim}
+>>> class Bottles(object):
+...     def __init__(self, number):
+...         self._as_parameter_ = number
+...
+>>> bottles = Bottles(42)
+>>> printf("%d bottles of beer\n", bottles)
+42 bottles of beer
+19
+>>>
+\end{verbatim}
+
+If you don't want to store the instance's data in the
+\member{{\_}as{\_}parameter{\_}} instance variable, you could define a \code{property}
+which makes the data avaiblable.
+
+
+\subsubsection{Specifying the required argument types (function prototypes)\label{ctypes-specifying-required-argument-types}}
+
+It is possible to specify the required argument types of functions
+exported from DLLs by setting the \member{argtypes} attribute.
+
+\member{argtypes} must be a sequence of C data types (the \code{printf}
+function is probably not a good example here, because it takes a
+variable number and different types of parameters depending on the
+format string, on the other hand this is quite handy to experiment
+with this feature):
+\begin{verbatim}
+>>> printf.argtypes = [c_char_p, c_char_p, c_int, c_double]
+>>> printf("String '%s', Int %d, Double %f\n", "Hi", 10, 2.2)
+String 'Hi', Int 10, Double 2.200000
+37
+>>>
+\end{verbatim}
+
+Specifying a format protects against incompatible argument types (just
+as a prototype for a C function), and tries to convert the arguments
+to valid types:
+\begin{verbatim}
+>>> printf("%d %d %d", 1, 2, 3)
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+ArgumentError: argument 2: exceptions.TypeError: wrong type
+>>> printf("%s %d %f", "X", 2, 3)
+X 2 3.00000012
+12
+>>>
+\end{verbatim}
+
+If you have defined your own classes which you pass to function calls,
+you have to implement a \method{from{\_}param} class method for them to be
+able to use them in the \member{argtypes} sequence. The \method{from{\_}param}
+class method receives the Python object passed to the function call,
+it should do a typecheck or whatever is needed to make sure this
+object is acceptable, and then return the object itself, it's
+\member{{\_}as{\_}parameter{\_}} attribute, or whatever you want to pass as the C
+function argument in this case. Again, the result should be an
+integer, string, unicode, a \code{ctypes} instance, or something having
+the \member{{\_}as{\_}parameter{\_}} attribute.
+
+
+\subsubsection{Return types\label{ctypes-return-types}}
+
+By default functions are assumed to return the C \code{int} type.  Other
+return types can be specified by setting the \member{restype} attribute of
+the function object.
+
+Here is a more advanced example, it uses the \code{strchr} function, which
+expects a string pointer and a char, and returns a pointer to a
+string:
+\begin{verbatim}
+>>> strchr = libc.strchr
+>>> strchr("abcdef", ord("d")) # doctest: +SKIP
+8059983
+>>> strchr.restype = c_char_p # c_char_p is a pointer to a string
+>>> strchr("abcdef", ord("d"))
+'def'
+>>> print strchr("abcdef", ord("x"))
+None
+>>>
+\end{verbatim}
+
+If you want to avoid the \code{ord("x")} calls above, you can set the
+\member{argtypes} attribute, and the second argument will be converted from
+a single character Python string into a C char:
+\begin{verbatim}
+>>> strchr.restype = c_char_p
+>>> strchr.argtypes = [c_char_p, c_char]
+>>> strchr("abcdef", "d")
+'def'
+>>> strchr("abcdef", "def")
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+ArgumentError: argument 2: exceptions.TypeError: one character string expected
+>>> print strchr("abcdef", "x")
+None
+>>> strchr("abcdef", "d")
+'def'
+>>>
+\end{verbatim}
+
+You can also use a callable Python object (a function or a class for
+example) as the \member{restype} attribute, if the foreign function returns
+an integer.  The callable will be called with the \code{integer} the C
+function returns, and the result of this call will be used as the
+result of your function call. This is useful to check for error return
+values and automatically raise an exception:
+\begin{verbatim}
+>>> GetModuleHandle = windll.kernel32.GetModuleHandleA # doctest: +WINDOWS
+>>> def ValidHandle(value):
+...     if value == 0:
+...         raise WinError()
+...     return value
+...
+>>>
+>>> GetModuleHandle.restype = ValidHandle # doctest: +WINDOWS
+>>> GetModuleHandle(None) # doctest: +WINDOWS
+486539264
+>>> GetModuleHandle("something silly") # doctest: +WINDOWS
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+  File "<stdin>", line 3, in ValidHandle
+WindowsError: [Errno 126] The specified module could not be found.
+>>>
+\end{verbatim}
+
+\code{WinError} is a function which will call Windows \code{FormatMessage()}
+api to get the string representation of an error code, and \emph{returns}
+an exception.  \code{WinError} takes an optional error code parameter, if
+no one is used, it calls \function{GetLastError()} to retrieve it.
+
+Please note that a much more powerful error checking mechanism is
+available through the \member{errcheck} attribute; see the reference manual
+for details.
+
+
+\subsubsection{Passing pointers (or: passing parameters by reference)\label{ctypes-passing-pointers}}
+
+Sometimes a C api function expects a \emph{pointer} to a data type as
+parameter, probably to write into the corresponding location, or if
+the data is too large to be passed by value. This is also known as
+\emph{passing parameters by reference}.
+
+\code{ctypes} exports the \function{byref} function which is used to pass
+parameters by reference.  The same effect can be achieved with the
+\code{pointer} function, although \code{pointer} does a lot more work since
+it constructs a real pointer object, so it is faster to use \function{byref}
+if you don't need the pointer object in Python itself:
+\begin{verbatim}
+>>> i = c_int()
+>>> f = c_float()
+>>> s = create_string_buffer('\000' * 32)
+>>> print i.value, f.value, repr(s.value)
+0 0.0 ''
+>>> libc.sscanf("1 3.14 Hello", "%d %f %s",
+...             byref(i), byref(f), s)
+3
+>>> print i.value, f.value, repr(s.value)
+1 3.1400001049 'Hello'
+>>>
+\end{verbatim}
+
+
+\subsubsection{Structures and unions\label{ctypes-structures-unions}}
+
+Structures and unions must derive from the \class{Structure} and \class{Union}
+base classes which are defined in the \code{ctypes} module. Each subclass
+must define a \member{{\_}fields{\_}} attribute.  \member{{\_}fields{\_}} must be a list of
+\emph{2-tuples}, containing a \emph{field name} and a \emph{field type}.
+
+The field type must be a \code{ctypes} type like \class{c{\_}int}, or any other
+derived \code{ctypes} type: structure, union, array, pointer.
+
+Here is a simple example of a POINT structure, which contains two
+integers named \code{x} and \code{y}, and also shows how to initialize a
+structure in the constructor:
+\begin{verbatim}
+>>> from ctypes import *
+>>> class POINT(Structure):
+...     _fields_ = [("x", c_int),
+...                 ("y", c_int)]
+...
+>>> point = POINT(10, 20)
+>>> print point.x, point.y
+10 20
+>>> point = POINT(y=5)
+>>> print point.x, point.y
+0 5
+>>> POINT(1, 2, 3)
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+ValueError: too many initializers
+>>>
+\end{verbatim}
+
+You can, however, build much more complicated structures. Structures
+can itself contain other structures by using a structure as a field
+type.
+
+Here is a RECT structure which contains two POINTs named \code{upperleft}
+and \code{lowerright}
+\begin{verbatim}
+>>> class RECT(Structure):
+...     _fields_ = [("upperleft", POINT),
+...                 ("lowerright", POINT)]
+...
+>>> rc = RECT(point)
+>>> print rc.upperleft.x, rc.upperleft.y
+0 5
+>>> print rc.lowerright.x, rc.lowerright.y
+0 0
+>>>
+\end{verbatim}
+
+Nested structures can also be initialized in the constructor in
+several ways:
+\begin{verbatim}
+>>> r = RECT(POINT(1, 2), POINT(3, 4))
+>>> r = RECT((1, 2), (3, 4))
+\end{verbatim}
+
+Fields descriptors can be retrieved from the \emph{class}, they are useful
+for debugging because they can provide useful information:
+\begin{verbatim}
+>>> print POINT.x
+<Field type=c_long, ofs=0, size=4>
+>>> print POINT.y
+<Field type=c_long, ofs=4, size=4>
+>>>
+\end{verbatim}
+
+
+\subsubsection{Structure/union alignment and byte order\label{ctypes-structureunion-alignment-byte-order}}
+
+By default, Structure and Union fields are aligned in the same way the
+C compiler does it. It is possible to override this behaviour be
+specifying a \member{{\_}pack{\_}} class attribute in the subclass
+definition. This must be set to a positive integer and specifies the
+maximum alignment for the fields. This is what \code{{\#}pragma pack(n)}
+also does in MSVC.
+
+\code{ctypes} uses the native byte order for Structures and Unions.  To
+build structures with non-native byte order, you can use one of the
+BigEndianStructure, LittleEndianStructure, BigEndianUnion, and
+LittleEndianUnion base classes.  These classes cannot contain pointer
+fields.
+
+
+\subsubsection{Bit fields in structures and unions\label{ctypes-bit-fields-in-structures-unions}}
+
+It is possible to create structures and unions containing bit fields.
+Bit fields are only possible for integer fields, the bit width is
+specified as the third item in the \member{{\_}fields{\_}} tuples:
+\begin{verbatim}
+>>> class Int(Structure):
+...     _fields_ = [("first_16", c_int, 16),
+...                 ("second_16", c_int, 16)]
+...
+>>> print Int.first_16
+<Field type=c_long, ofs=0:0, bits=16>
+>>> print Int.second_16
+<Field type=c_long, ofs=0:16, bits=16>
+>>>
+\end{verbatim}
+
+
+\subsubsection{Arrays\label{ctypes-arrays}}
+
+Arrays are sequences, containing a fixed number of instances of the
+same type.
+
+The recommended way to create array types is by multiplying a data
+type with a positive integer:
+\begin{verbatim}
+TenPointsArrayType = POINT * 10
+\end{verbatim}
+
+Here is an example of an somewhat artifical data type, a structure
+containing 4 POINTs among other stuff:
+\begin{verbatim}
+>>> from ctypes import *
+>>> class POINT(Structure):
+...    _fields_ = ("x", c_int), ("y", c_int)
+...
+>>> class MyStruct(Structure):
+...    _fields_ = [("a", c_int),
+...                ("b", c_float),
+...                ("point_array", POINT * 4)]
+>>>
+>>> print len(MyStruct().point_array)
+4
+>>>
+\end{verbatim}
+
+Instances are created in the usual way, by calling the class:
+\begin{verbatim}
+arr = TenPointsArrayType()
+for pt in arr:
+    print pt.x, pt.y
+\end{verbatim}
+
+The above code print a series of \code{0 0} lines, because the array
+contents is initialized to zeros.
+
+Initializers of the correct type can also be specified:
+\begin{verbatim}
+>>> from ctypes import *
+>>> TenIntegers = c_int * 10
+>>> ii = TenIntegers(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+>>> print ii
+<c_long_Array_10 object at 0x...>
+>>> for i in ii: print i,
+...
+1 2 3 4 5 6 7 8 9 10
+>>>
+\end{verbatim}
+
+
+\subsubsection{Pointers\label{ctypes-pointers}}
+
+Pointer instances are created by calling the \code{pointer} function on a
+\code{ctypes} type:
+\begin{verbatim}
+>>> from ctypes import *
+>>> i = c_int(42)
+>>> pi = pointer(i)
+>>>
+\end{verbatim}
+
+Pointer instances have a \code{contents} attribute which returns the
+object to which the pointer points, the \code{i} object above:
+\begin{verbatim}
+>>> pi.contents
+c_long(42)
+>>>
+\end{verbatim}
+
+Note that \code{ctypes} does not have OOR (original object return), it
+constructs a new, equivalent object each time you retrieve an
+attribute:
+\begin{verbatim}
+>>> pi.contents is i
+False
+>>> pi.contents is pi.contents
+False
+>>>
+\end{verbatim}
+
+Assigning another \class{c{\_}int} instance to the pointer's contents
+attribute would cause the pointer to point to the memory location
+where this is stored:
+\begin{verbatim}
+>>> i = c_int(99)
+>>> pi.contents = i
+>>> pi.contents
+c_long(99)
+>>>
+\end{verbatim}
+
+Pointer instances can also be indexed with integers:
+\begin{verbatim}
+>>> pi[0]
+99
+>>>
+\end{verbatim}
+
+Assigning to an integer index changes the pointed to value:
+\begin{verbatim}
+>>> print i
+c_long(99)
+>>> pi[0] = 22
+>>> print i
+c_long(22)
+>>>
+\end{verbatim}
+
+It is also possible to use indexes different from 0, but you must know
+what you're doing, just as in C: You can access or change arbitrary
+memory locations. Generally you only use this feature if you receive a
+pointer from a C function, and you \emph{know} that the pointer actually
+points to an array instead of a single item.
+
+Behind the scenes, the \code{pointer} function does more than simply
+create pointer instances, it has to create pointer \emph{types} first.
+This is done with the \code{POINTER} function, which accepts any
+\code{ctypes} type, and returns a new type:
+\begin{verbatim}
+>>> PI = POINTER(c_int)
+>>> PI
+<class 'ctypes.LP_c_long'>
+>>> PI(42)
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+TypeError: expected c_long instead of int
+>>> PI(c_int(42))
+<ctypes.LP_c_long object at 0x...>
+>>>
+\end{verbatim}
+
+Calling the pointer type without an argument creates a \code{NULL}
+pointer.  \code{NULL} pointers have a \code{False} boolean value:
+\begin{verbatim}
+>>> null_ptr = POINTER(c_int)()
+>>> print bool(null_ptr)
+False
+>>>
+\end{verbatim}
+
+\code{ctypes} checks for \code{NULL} when dereferencing pointers (but
+dereferencing non-\code{NULL} pointers would crash Python):
+\begin{verbatim}
+>>> null_ptr[0]
+Traceback (most recent call last):
+    ....
+ValueError: NULL pointer access
+>>>
+
+>>> null_ptr[0] = 1234
+Traceback (most recent call last):
+    ....
+ValueError: NULL pointer access
+>>>
+\end{verbatim}
+
+
+\subsubsection{Type conversions\label{ctypes-type-conversions}}
+
+Usually, ctypes does strict type checking.  This means, if you have
+\code{POINTER(c{\_}int)} in the \member{argtypes} list of a function or as the
+type of a member field in a structure definition, only instances of
+exactly the same type are accepted.  There are some exceptions to this
+rule, where ctypes accepts other objects.  For example, you can pass
+compatible array instances instead of pointer types.  So, for
+\code{POINTER(c{\_}int)}, ctypes accepts an array of c{\_}int:
+\begin{verbatim}
+>>> class Bar(Structure):
+...     _fields_ = [("count", c_int), ("values", POINTER(c_int))]
+...
+>>> bar = Bar()
+>>> bar.values = (c_int * 3)(1, 2, 3)
+>>> bar.count = 3
+>>> for i in range(bar.count):
+...     print bar.values[i]
+...
+1
+2
+3
+>>>
+\end{verbatim}
+
+To set a POINTER type field to \code{NULL}, you can assign \code{None}:
+\begin{verbatim}
+>>> bar.values = None
+>>>
+\end{verbatim}
+
+XXX list other conversions...
+
+Sometimes you have instances of incompatible types.  In \code{C}, you can
+cast one type into another type.  \code{ctypes} provides a \code{cast}
+function which can be used in the same way.  The \code{Bar} structure
+defined above accepts \code{POINTER(c{\_}int)} pointers or \class{c{\_}int} arrays
+for its \code{values} field, but not instances of other types:
+\begin{verbatim}
+>>> bar.values = (c_byte * 4)()
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+TypeError: incompatible types, c_byte_Array_4 instance instead of LP_c_long instance
+>>>
+\end{verbatim}
+
+For these cases, the \code{cast} function is handy.
+
+The \code{cast} function can be used to cast a ctypes instance into a
+pointer to a different ctypes data type.  \code{cast} takes two
+parameters, a ctypes object that is or can be converted to a pointer
+of some kind, and a ctypes pointer type.  It returns an instance of
+the second argument, which references the same memory block as the
+first argument:
+\begin{verbatim}
+>>> a = (c_byte * 4)()
+>>> cast(a, POINTER(c_int))
+<ctypes.LP_c_long object at ...>
+>>>
+\end{verbatim}
+
+So, \code{cast} can be used to assign to the \code{values} field of \code{Bar}
+the structure:
+\begin{verbatim}
+>>> bar = Bar()
+>>> bar.values = cast((c_byte * 4)(), POINTER(c_int))
+>>> print bar.values[0]
+0
+>>>
+\end{verbatim}
+
+
+\subsubsection{Incomplete Types\label{ctypes-incomplete-types}}
+
+\emph{Incomplete Types} are structures, unions or arrays whose members are
+not yet specified. In C, they are specified by forward declarations, which
+are defined later:
+\begin{verbatim}
+struct cell; /* forward declaration */
+
+struct {
+    char *name;
+    struct cell *next;
+} cell;
+\end{verbatim}
+
+The straightforward translation into ctypes code would be this, but it
+does not work:
+\begin{verbatim}
+>>> class cell(Structure):
+...     _fields_ = [("name", c_char_p),
+...                 ("next", POINTER(cell))]
+...
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+  File "<stdin>", line 2, in cell
+NameError: name 'cell' is not defined
+>>>
+\end{verbatim}
+
+because the new \code{class cell} is not available in the class statement
+itself.  In \code{ctypes}, we can define the \code{cell} class and set the
+\member{{\_}fields{\_}} attribute later, after the class statement:
+\begin{verbatim}
+>>> from ctypes import *
+>>> class cell(Structure):
+...     pass
+...
+>>> cell._fields_ = [("name", c_char_p),
+...                  ("next", POINTER(cell))]
+>>>
+\end{verbatim}
+
+Lets try it. We create two instances of \code{cell}, and let them point
+to each other, and finally follow the pointer chain a few times:
+\begin{verbatim}
+>>> c1 = cell()
+>>> c1.name = "foo"
+>>> c2 = cell()
+>>> c2.name = "bar"
+>>> c1.next = pointer(c2)
+>>> c2.next = pointer(c1)
+>>> p = c1
+>>> for i in range(8):
+...     print p.name,
+...     p = p.next[0]
+...
+foo bar foo bar foo bar foo bar
+>>>    
+\end{verbatim}
+
+
+\subsubsection{Callback functions\label{ctypes-callback-functions}}
+
+\code{ctypes} allows to create C callable function pointers from Python
+callables. These are sometimes called \emph{callback functions}.
+
+First, you must create a class for the callback function, the class
+knows the calling convention, the return type, and the number and
+types of arguments this function will receive.
+
+The CFUNCTYPE factory function creates types for callback functions
+using the normal cdecl calling convention, and, on Windows, the
+WINFUNCTYPE factory function creates types for callback functions
+using the stdcall calling convention.
+
+Both of these factory functions are called with the result type as
+first argument, and the callback functions expected argument types as
+the remaining arguments.
+
+I will present an example here which uses the standard C library's
+\function{qsort} function, this is used to sort items with the help of a
+callback function. \function{qsort} will be used to sort an array of
+integers:
+\begin{verbatim}
+>>> IntArray5 = c_int * 5
+>>> ia = IntArray5(5, 1, 7, 33, 99)
+>>> qsort = libc.qsort
+>>> qsort.restype = None
+>>>
+\end{verbatim}
+
+\function{qsort} must be called with a pointer to the data to sort, the
+number of items in the data array, the size of one item, and a pointer
+to the comparison function, the callback. The callback will then be
+called with two pointers to items, and it must return a negative
+integer if the first item is smaller than the second, a zero if they
+are equal, and a positive integer else.
+
+So our callback function receives pointers to integers, and must
+return an integer. First we create the \code{type} for the callback
+function:
+\begin{verbatim}
+>>> CMPFUNC = CFUNCTYPE(c_int, POINTER(c_int), POINTER(c_int))
+>>>
+\end{verbatim}
+
+For the first implementation of the callback function, we simply print
+the arguments we get, and return 0 (incremental development ;-):
+\begin{verbatim}
+>>> def py_cmp_func(a, b):
+...     print "py_cmp_func", a, b
+...     return 0
+...
+>>>
+\end{verbatim}
+
+Create the C callable callback:
+\begin{verbatim}
+>>> cmp_func = CMPFUNC(py_cmp_func)
+>>>
+\end{verbatim}
+
+And we're ready to go:
+\begin{verbatim}
+>>> qsort(ia, len(ia), sizeof(c_int), cmp_func) # doctest: +WINDOWS
+py_cmp_func <ctypes.LP_c_long object at 0x00...> <ctypes.LP_c_long object at 0x00...>
+py_cmp_func <ctypes.LP_c_long object at 0x00...> <ctypes.LP_c_long object at 0x00...>
+py_cmp_func <ctypes.LP_c_long object at 0x00...> <ctypes.LP_c_long object at 0x00...>
+py_cmp_func <ctypes.LP_c_long object at 0x00...> <ctypes.LP_c_long object at 0x00...>
+py_cmp_func <ctypes.LP_c_long object at 0x00...> <ctypes.LP_c_long object at 0x00...>
+py_cmp_func <ctypes.LP_c_long object at 0x00...> <ctypes.LP_c_long object at 0x00...>
+py_cmp_func <ctypes.LP_c_long object at 0x00...> <ctypes.LP_c_long object at 0x00...>
+py_cmp_func <ctypes.LP_c_long object at 0x00...> <ctypes.LP_c_long object at 0x00...>
+py_cmp_func <ctypes.LP_c_long object at 0x00...> <ctypes.LP_c_long object at 0x00...>
+py_cmp_func <ctypes.LP_c_long object at 0x00...> <ctypes.LP_c_long object at 0x00...>
+>>>
+\end{verbatim}
+
+We know how to access the contents of a pointer, so lets redefine our callback:
+\begin{verbatim}
+>>> def py_cmp_func(a, b):
+...     print "py_cmp_func", a[0], b[0]
+...     return 0
+...
+>>> cmp_func = CMPFUNC(py_cmp_func)
+>>>
+\end{verbatim}
+
+Here is what we get on Windows:
+\begin{verbatim}
+>>> qsort(ia, len(ia), sizeof(c_int), cmp_func) # doctest: +WINDOWS
+py_cmp_func 7 1
+py_cmp_func 33 1
+py_cmp_func 99 1
+py_cmp_func 5 1
+py_cmp_func 7 5
+py_cmp_func 33 5
+py_cmp_func 99 5
+py_cmp_func 7 99
+py_cmp_func 33 99
+py_cmp_func 7 33
+>>>
+\end{verbatim}
+
+It is funny to see that on linux the sort function seems to work much
+more efficient, it is doing less comparisons:
+\begin{verbatim}
+>>> qsort(ia, len(ia), sizeof(c_int), cmp_func) # doctest: +LINUX
+py_cmp_func 5 1
+py_cmp_func 33 99
+py_cmp_func 7 33
+py_cmp_func 5 7
+py_cmp_func 1 7
+>>>
+\end{verbatim}
+
+Ah, we're nearly done! The last step is to actually compare the two
+items and return a useful result:
+\begin{verbatim}
+>>> def py_cmp_func(a, b):
+...     print "py_cmp_func", a[0], b[0]
+...     return a[0] - b[0]
+...
+>>>
+\end{verbatim}
+
+Final run on Windows:
+\begin{verbatim}
+>>> qsort(ia, len(ia), sizeof(c_int), CMPFUNC(py_cmp_func)) # doctest: +WINDOWS
+py_cmp_func 33 7
+py_cmp_func 99 33
+py_cmp_func 5 99
+py_cmp_func 1 99
+py_cmp_func 33 7
+py_cmp_func 1 33
+py_cmp_func 5 33
+py_cmp_func 5 7
+py_cmp_func 1 7
+py_cmp_func 5 1
+>>>
+\end{verbatim}
+
+and on Linux:
+\begin{verbatim}
+>>> qsort(ia, len(ia), sizeof(c_int), CMPFUNC(py_cmp_func)) # doctest: +LINUX
+py_cmp_func 5 1
+py_cmp_func 33 99
+py_cmp_func 7 33
+py_cmp_func 1 7
+py_cmp_func 5 7
+>>>
+\end{verbatim}
+
+It is quite interesting to see that the Windows \function{qsort} function
+needs more comparisons than the linux version!
+
+As we can easily check, our array is sorted now:
+\begin{verbatim}
+>>> for i in ia: print i,
+...
+1 5 7 33 99
+>>>
+\end{verbatim}
+
+\textbf{Important note for callback functions:}
+
+Make sure you keep references to CFUNCTYPE objects as long as they are
+used from C code. \code{ctypes} doesn't, and if you don't, they may be
+garbage collected, crashing your program when a callback is made.
+
+
+\subsubsection{Accessing values exported from dlls\label{ctypes-accessing-values-exported-from-dlls}}
+
+Sometimes, a dll not only exports functions, it also exports
+variables. An example in the Python library itself is the
+\code{Py{\_}OptimizeFlag}, an integer set to 0, 1, or 2, depending on the
+\programopt{-O} or \programopt{-OO} flag given on startup.
+
+\code{ctypes} can access values like this with the \method{in{\_}dll} class
+methods of the type.  \var{pythonapi} ìs a predefined symbol giving
+access to the Python C api:
+\begin{verbatim}
+>>> opt_flag = c_int.in_dll(pythonapi, "Py_OptimizeFlag")
+>>> print opt_flag
+c_long(0)
+>>>
+\end{verbatim}
+
+If the interpreter would have been started with \programopt{-O}, the sample
+would have printed \code{c{\_}long(1)}, or \code{c{\_}long(2)} if \programopt{-OO} would have
+been specified.
+
+An extended example which also demonstrates the use of pointers
+accesses the \code{PyImport{\_}FrozenModules} pointer exported by Python.
+
+Quoting the Python docs: \emph{This pointer is initialized to point to an
+array of ``struct {\_}frozen`` records, terminated by one whose members
+are all NULL or zero. When a frozen module is imported, it is searched
+in this table. Third-party code could play tricks with this to provide
+a dynamically created collection of frozen modules.}
+
+So manipulating this pointer could even prove useful. To restrict the
+example size, we show only how this table can be read with
+\code{ctypes}:
+\begin{verbatim}
+>>> from ctypes import *
+>>>
+>>> class struct_frozen(Structure):
+...     _fields_ = [("name", c_char_p),
+...                 ("code", POINTER(c_ubyte)),
+...                 ("size", c_int)]
+...
+>>>
+\end{verbatim}
+
+We have defined the \code{struct {\_}frozen} data type, so we can get the
+pointer to the table:
+\begin{verbatim}
+>>> FrozenTable = POINTER(struct_frozen)
+>>> table = FrozenTable.in_dll(pythonapi, "PyImport_FrozenModules")
+>>>
+\end{verbatim}
+
+Since \code{table} is a \code{pointer} to the array of \code{struct{\_}frozen}
+records, we can iterate over it, but we just have to make sure that
+our loop terminates, because pointers have no size. Sooner or later it
+would probably crash with an access violation or whatever, so it's
+better to break out of the loop when we hit the NULL entry:
+\begin{verbatim}
+>>> for item in table:
+...    print item.name, item.size
+...    if item.name is None:
+...        break
+...
+__hello__ 104
+__phello__ -104
+__phello__.spam 104
+None 0
+>>>
+\end{verbatim}
+
+The fact that standard Python has a frozen module and a frozen package
+(indicated by the negative size member) is not wellknown, it is only
+used for testing. Try it out with \code{import {\_}{\_}hello{\_}{\_}} for example.
+
+
+\subsubsection{Surprises\label{ctypes-surprises}}
+
+There are some edges in \code{ctypes} where you may be expect something
+else than what actually happens.
+
+Consider the following example:
+\begin{verbatim}
+>>> from ctypes import *
+>>> class POINT(Structure):
+...     _fields_ = ("x", c_int), ("y", c_int)
+...
+>>> class RECT(Structure):
+...     _fields_ = ("a", POINT), ("b", POINT)
+...
+>>> p1 = POINT(1, 2)
+>>> p2 = POINT(3, 4)
+>>> rc = RECT(p1, p2)
+>>> print rc.a.x, rc.a.y, rc.b.x, rc.b.y
+1 2 3 4
+>>> # now swap the two points
+>>> rc.a, rc.b = rc.b, rc.a
+>>> print rc.a.x, rc.a.y, rc.b.x, rc.b.y
+3 4 3 4
+>>>
+\end{verbatim}
+
+Hm. We certainly expected the last statement to print \code{3 4 1 2}.
+What happended? Here are the steps of the \code{rc.a, rc.b = rc.b, rc.a}
+line above:
+\begin{verbatim}
+>>> temp0, temp1 = rc.b, rc.a
+>>> rc.a = temp0
+>>> rc.b = temp1
+>>>
+\end{verbatim}
+
+Note that \code{temp0} and \code{temp1} are objects still using the internal
+buffer of the \code{rc} object above. So executing \code{rc.a = temp0}
+copies the buffer contents of \code{temp0} into \code{rc} 's buffer.  This,
+in turn, changes the contents of \code{temp1}. So, the last assignment
+\code{rc.b = temp1}, doesn't have the expected effect.
+
+Keep in mind that retrieving subobjects from Structure, Unions, and
+Arrays doesn't \emph{copy} the subobject, instead it retrieves a wrapper
+object accessing the root-object's underlying buffer.
+
+Another example that may behave different from what one would expect is this:
+\begin{verbatim}
+>>> s = c_char_p()
+>>> s.value = "abc def ghi"
+>>> s.value
+'abc def ghi'
+>>> s.value is s.value
+False
+>>>
+\end{verbatim}
+
+Why is it printing \code{False}?  ctypes instances are objects containing
+a memory block plus some descriptors accessing the contents of the
+memory.  Storing a Python object in the memory block does not store
+the object itself, instead the \code{contents} of the object is stored.
+Accessing the contents again constructs a new Python each time!
+
+
+\subsubsection{Variable-sized data types\label{ctypes-variable-sized-data-types}}
+
+\code{ctypes} provides some support for variable-sized arrays and
+structures (this was added in version 0.9.9.7).
+
+The \code{resize} function can be used to resize the memory buffer of an
+existing ctypes object.  The function takes the object as first
+argument, and the requested size in bytes as the second argument.  The
+memory block cannot be made smaller than the natural memory block
+specified by the objects type, a \code{ValueError} is raised if this is
+tried:
+\begin{verbatim}
+>>> short_array = (c_short * 4)()
+>>> print sizeof(short_array)
+8
+>>> resize(short_array, 4)
+Traceback (most recent call last):
+    ...
+ValueError: minimum size is 8
+>>> resize(short_array, 32)
+>>> sizeof(short_array)
+32
+>>> sizeof(type(short_array))
+8
+>>>
+\end{verbatim}
+
+This is nice and fine, but how would one access the additional
+elements contained in this array?  Since the type still only knows
+about 4 elements, we get errors accessing other elements:
+\begin{verbatim}
+>>> short_array[:]
+[0, 0, 0, 0]
+>>> short_array[7]
+Traceback (most recent call last):
+    ...
+IndexError: invalid index
+>>>
+\end{verbatim}
+
+Another way to use variable-sized data types with \code{ctypes} is to use
+the dynamic nature of Python, and (re-)define the data type after the
+required size is already known, on a case by case basis.
+
+
+\subsubsection{Bugs, ToDo and non-implemented things\label{ctypes-bugs-todo-non-implemented-things}}
+
+Enumeration types are not implemented. You can do it easily yourself,
+using \class{c{\_}int} as the base class.
+
+\code{long double} is not implemented.
+% Local Variables:
+% compile-command: "make.bat"
+% End: 
+
+
+\subsection{ctypes reference\label{ctypes-ctypes-reference}}
+
+
+\subsubsection{Finding shared libraries\label{ctypes-finding-shared-libraries}}
+
+When programming in a compiled language, shared libraries are accessed
+when compiling/linking a program, and when the program is run.
+
+The purpose of the \code{find{\_}library} function is to locate a library in
+a way similar to what the compiler does (on platforms with several
+versions of a shared library the most recent should be loaded), while
+the ctypes library loaders act like when a program is run, and call
+the runtime loader directly.
+
+The \code{ctypes.util} module provides a function which can help to
+determine the library to load.
+
+\begin{datadescni}{find_library(name)}
+Try to find a library and return a pathname.  \var{name} is the
+library name without any prefix like \var{lib}, suffix like \code{.so},
+\code{.dylib} or version number (this is the form used for the posix
+linker option \programopt{-l}).  If no library can be found, returns
+\code{None}.
+\end{datadescni}
+
+The exact functionality is system dependend.
+
+On Linux, \code{find{\_}library} tries to run external programs
+(/sbin/ldconfig, gcc, and objdump) to find the library file.  It
+returns the filename of the library file.  Here are sone examples:
+\begin{verbatim}
+>>> from ctypes.util import find_library
+>>> find_library("m")
+'libm.so.6'
+>>> find_library("c")
+'libc.so.6'
+>>> find_library("bz2")
+'libbz2.so.1.0'
+>>>
+\end{verbatim}
+
+On OS X, \code{find{\_}library} tries several predefined naming schemes and
+paths to locate the library, and returns a full pathname if successfull:
+\begin{verbatim}
+>>> from ctypes.util import find_library
+>>> find_library("c")
+'/usr/lib/libc.dylib'
+>>> find_library("m")
+'/usr/lib/libm.dylib'
+>>> find_library("bz2")
+'/usr/lib/libbz2.dylib'
+>>> find_library("AGL")
+'/System/Library/Frameworks/AGL.framework/AGL'
+>>>
+\end{verbatim}
+
+On Windows, \code{find{\_}library} searches along the system search path,
+and returns the full pathname, but since there is no predefined naming
+scheme a call like \code{find{\_}library("c")} will fail and return
+\code{None}.
+
+If wrapping a shared library with \code{ctypes}, it \emph{may} be better to
+determine the shared library name at development type, and hardcode
+that into the wrapper module instead of using \code{find{\_}library} to
+locate the library at runtime.
+
+
+\subsubsection{Loading shared libraries\label{ctypes-loading-shared-libraries}}
+
+There are several ways to loaded shared libraries into the Python
+process.  One way is to instantiate one of the following classes:
+
+\begin{classdesc}{CDLL}{name, mode=DEFAULT_MODE, handle=None}
+Instances of this class represent loaded shared libraries.
+Functions in these libraries use the standard C calling
+convention, and are assumed to return \code{int}.
+\end{classdesc}
+
+\begin{classdesc}{OleDLL}{name, mode=DEFAULT_MODE, handle=None}
+Windows only: Instances of this class represent loaded shared
+libraries, functions in these libraries use the \code{stdcall}
+calling convention, and are assumed to return the windows specific
+\class{HRESULT} code.  \class{HRESULT} values contain information
+specifying whether the function call failed or succeeded, together
+with additional error code.  If the return value signals a
+failure, an \class{WindowsError} is automatically raised.
+\end{classdesc}
+
+\begin{classdesc}{WinDLL}{name, mode=DEFAULT_MODE, handle=None}
+Windows only: Instances of this class represent loaded shared
+libraries, functions in these libraries use the \code{stdcall}
+calling convention, and are assumed to return \code{int} by default.
+
+On Windows CE only the standard calling convention is used, for
+convenience the \class{WinDLL} and \class{OleDLL} use the standard calling
+convention on this platform.
+\end{classdesc}
+
+The Python GIL is released before calling any function exported by
+these libraries, and reaquired afterwards.
+
+\begin{classdesc}{PyDLL}{name, mode=DEFAULT_MODE, handle=None}
+Instances of this class behave like \class{CDLL} instances, except
+that the Python GIL is \emph{not} released during the function call,
+and after the function execution the Python error flag is checked.
+If the error flag is set, a Python exception is raised.
+
+Thus, this is only useful to call Python C api functions directly.
+\end{classdesc}
+
+All these classes can be instantiated by calling them with at least
+one argument, the pathname of the shared library.  If you have an
+existing handle to an already loaded shard library, it can be passed
+as the \code{handle} named parameter, otherwise the underlying platforms
+\code{dlopen} or \method{LoadLibrary} function is used to load the library
+into the process, and to get a handle to it.
+
+The \var{mode} parameter can be used to specify how the library is
+loaded.  For details, consult the \code{dlopen(3)} manpage, on Windows,
+\var{mode} is ignored.
+
+\begin{datadescni}{RTLD_GLOBAL}
+Flag to use as \var{mode} parameter.  On platforms where this flag
+is not available, it is defined as the integer zero.
+\end{datadescni}
+
+\begin{datadescni}{RTLD_LOCAL}
+Flag to use as \var{mode} parameter.  On platforms where this is not
+available, it is the same as \var{RTLD{\_}GLOBAL}.
+\end{datadescni}
+
+\begin{datadescni}{DEFAULT_MODE}
+The default mode which is used to load shared libraries.  On OSX
+10.3, this is \var{RTLD{\_}GLOBAL}, otherwise it is the same as
+\var{RTLD{\_}LOCAL}.
+\end{datadescni}
+
+Instances of these classes have no public methods, however
+\method{{\_}{\_}getattr{\_}{\_}} and \method{{\_}{\_}getitem{\_}{\_}} have special behaviour: functions
+exported by the shared library can be accessed as attributes of by
+index.  Please note that both \method{{\_}{\_}getattr{\_}{\_}} and \method{{\_}{\_}getitem{\_}{\_}}
+cache their result, so calling them repeatedly returns the same object
+each time.
+
+The following public attributes are available, their name starts with
+an underscore to not clash with exported function names:
+
+\begin{memberdesc}{_handle}
+The system handle used to access the library.
+\end{memberdesc}
+
+\begin{memberdesc}{_name}
+The name of the library passed in the contructor.
+\end{memberdesc}
+
+Shared libraries can also be loaded by using one of the prefabricated
+objects, which are instances of the \class{LibraryLoader} class, either by
+calling the \method{LoadLibrary} method, or by retrieving the library as
+attribute of the loader instance.
+
+\begin{classdesc}{LibraryLoader}{dlltype}
+Class which loads shared libraries.  \code{dlltype} should be one
+of the \class{CDLL}, \class{PyDLL}, \class{WinDLL}, or \class{OleDLL} types.
+
+\method{{\_}{\_}getattr{\_}{\_}} has special behaviour: It allows to load a shared
+library by accessing it as attribute of a library loader
+instance.  The result is cached, so repeated attribute accesses
+return the same library each time.
+\end{classdesc}
+
+\begin{methoddesc}{LoadLibrary}{name}
+Load a shared library into the process and return it.  This method
+always returns a new instance of the library.
+\end{methoddesc}
+
+These prefabricated library loaders are available:
+
+\begin{datadescni}{cdll}
+Creates \class{CDLL} instances.
+\end{datadescni}
+
+\begin{datadescni}{windll}
+Windows only: Creates \class{WinDLL} instances.
+\end{datadescni}
+
+\begin{datadescni}{oledll}
+Windows only: Creates \class{OleDLL} instances.
+\end{datadescni}
+
+\begin{datadescni}{pydll}
+Creates \class{PyDLL} instances.
+\end{datadescni}
+
+For accessing the C Python api directly, a ready-to-use Python shared
+library object is available:
+
+\begin{datadescni}{pythonapi}
+An instance of \class{PyDLL} that exposes Python C api functions as
+attributes.  Note that all these functions are assumed to return C
+\code{int}, which is of course not always the truth, so you have to
+assign the correct \member{restype} attribute to use these functions.
+\end{datadescni}
+
+
+\subsubsection{Foreign functions\label{ctypes-foreign-functions}}
+
+As explained in the previous section, foreign functions can be
+accessed as attributes of loaded shared libraries.  The function
+objects created in this way by default accept any number of arguments,
+accept any ctypes data instances as arguments, and return the default
+result type specified by the library loader.  They are instances of a
+private class:
+
+\begin{classdesc*}{_FuncPtr}
+Base class for C callable foreign functions.
+\end{classdesc*}
+
+Instances of foreign functions are also C compatible data types; they
+represent C function pointers.
+
+This behaviour can be customized by assigning to special attributes of
+the foreign function object.
+
+\begin{memberdesc}{restype}
+Assign a ctypes type to specify the result type of the foreign
+function.  Use \code{None} for \code{void} a function not returning
+anything.
+
+It is possible to assign a callable Python object that is not a
+ctypes type, in this case the function is assumed to return a
+C \code{int}, and the callable will be called with this integer,
+allowing to do further processing or error checking.  Using this
+is deprecated, for more flexible postprocessing or error checking
+use a ctypes data type as \member{restype} and assign a callable to the
+\member{errcheck} attribute.
+\end{memberdesc}
+
+\begin{memberdesc}{argtypes}
+Assign a tuple of ctypes types to specify the argument types that
+the function accepts.  Functions using the \code{stdcall} calling
+convention can only be called with the same number of arguments as
+the length of this tuple; functions using the C calling convention
+accept additional, unspecified arguments as well.
+
+When a foreign function is called, each actual argument is passed
+to the \method{from{\_}param} class method of the items in the
+\member{argtypes} tuple, this method allows to adapt the actual
+argument to an object that the foreign function accepts.  For
+example, a \class{c{\_}char{\_}p} item in the \member{argtypes} tuple will
+convert a unicode string passed as argument into an byte string
+using ctypes conversion rules.
+
+New: It is now possible to put items in argtypes which are not
+ctypes types, but each item must have a \method{from{\_}param} method
+which returns a value usable as argument (integer, string, ctypes
+instance).  This allows to define adapters that can adapt custom
+objects as function parameters.
+\end{memberdesc}
+
+\begin{memberdesc}{errcheck}
+Assign a Python function or another callable to this attribute.
+The callable will be called with three or more arguments:
+\end{memberdesc}
+
+\begin{funcdescni}{callable}{result, func, arguments}
+\code{result} is what the foreign function returns, as specified by the
+\member{restype} attribute.
+
+\code{func} is the foreign function object itself, this allows to
+reuse the same callable object to check or postprocess the results
+of several functions.
+
+\code{arguments} is a tuple containing the parameters originally
+passed to the function call, this allows to specialize the
+behaviour on the arguments used.
+
+The object that this function returns will be returned from the
+foreign function call, but it can also check the result value and
+raise an exception if the foreign function call failed.
+\end{funcdescni}
+
+\begin{excdesc}{ArgumentError()}
+This exception is raised when a foreign function call cannot
+convert one of the passed arguments.
+\end{excdesc}
+
+
+\subsubsection{Function prototypes\label{ctypes-function-prototypes}}
+
+Foreign functions can also be created by instantiating function
+prototypes.  Function prototypes are similar to function prototypes in
+C; they describe a function (return type, argument types, calling
+convention) without defining an implementation.  The factory
+functions must be called with the desired result type and the argument
+types of the function.
+
+\begin{funcdesc}{CFUNCTYPE}{restype, *argtypes}
+The returned function prototype creates functions that use the
+standard C calling convention.  The function will release the GIL
+during the call.
+\end{funcdesc}
+
+\begin{funcdesc}{WINFUNCTYPE}{restype, *argtypes}
+Windows only: The returned function prototype creates functions
+that use the \code{stdcall} calling convention, except on Windows CE
+where \function{WINFUNCTYPE} is the same as \function{CFUNCTYPE}.  The function
+will release the GIL during the call.
+\end{funcdesc}
+
+\begin{funcdesc}{PYFUNCTYPE}{restype, *argtypes}
+The returned function prototype creates functions that use the
+Python calling convention.  The function will \emph{not} release the
+GIL during the call.
+\end{funcdesc}
+
+Function prototypes created by the factory functions can be
+instantiated in different ways, depending on the type and number of
+the parameters in the call.
+
+\begin{funcdescni}{prototype}{address}
+Returns a foreign function at the specified address.
+\end{funcdescni}
+
+\begin{funcdescni}{prototype}{callable}
+Create a C callable function (a callback function) from a Python
+\code{callable}.
+\end{funcdescni}
+
+\begin{funcdescni}{prototype}{func_spec\optional{, paramflags}}
+Returns a foreign function exported by a shared library.
+\code{func{\_}spec} must be a 2-tuple \code{(name{\_}or{\_}ordinal, library)}.
+The first item is the name of the exported function as string, or
+the ordinal of the exported function as small integer.  The second
+item is the shared library instance.
+\end{funcdescni}
+
+\begin{funcdescni}{prototype}{vtbl_index, name\optional{, paramflags\optional{, iid}}}
+Returns a foreign function that will call a COM method.
+\code{vtbl{\_}index} is the index into the virtual function table, a
+small nonnegative integer. \var{name} is name of the COM method.
+\var{iid} is an optional pointer to the interface identifier which
+is used in extended error reporting.
+
+COM methods use a special calling convention: They require a
+pointer to the COM interface as first argument, in addition to
+those parameters that are specified in the \member{argtypes} tuple.
+\end{funcdescni}
+
+The optional \var{paramflags} parameter creates foreign function
+wrappers with much more functionality than the features described
+above.
+
+\var{paramflags} must be a tuple of the same length as \member{argtypes}.
+
+Each item in this tuple contains further information about a
+parameter, it must be a tuple containing 1, 2, or 3 items.
+
+The first item is an integer containing flags for the parameter:
+
+\begin{datadescni}{1}
+Specifies an input parameter to the function.
+\end{datadescni}
+
+\begin{datadescni}{2}
+Output parameter.  The foreign function fills in a value.
+\end{datadescni}
+
+\begin{datadescni}{4}
+Input parameter which defaults to the integer zero.
+\end{datadescni}
+
+The optional second item is the parameter name as string.  If this is
+specified, the foreign function can be called with named parameters.
+
+The optional third item is the default value for this parameter.
+
+This example demonstrates how to wrap the Windows \code{MessageBoxA}
+function so that it supports default parameters and named arguments.
+The C declaration from the windows header file is this:
+\begin{verbatim}
+WINUSERAPI int WINAPI
+MessageBoxA(
+    HWND hWnd ,
+    LPCSTR lpText,
+    LPCSTR lpCaption,
+    UINT uType);
+\end{verbatim}
+
+Here is the wrapping with \code{ctypes}:
+\begin{quote}
+\begin{verbatim}>>> from ctypes import c_int, WINFUNCTYPE, windll
+>>> from ctypes.wintypes import HWND, LPCSTR, UINT
+>>> prototype = WINFUNCTYPE(c_int, HWND, LPCSTR, LPCSTR, UINT)
+>>> paramflags = (1, "hwnd", 0), (1, "text", "Hi"), (1, "caption", None), (1, "flags", 0)
+>>> MessageBox = prototype(("MessageBoxA", windll.user32), paramflags)
+>>>\end{verbatim}
+\end{quote}
+
+The MessageBox foreign function can now be called in these ways:
+\begin{verbatim}
+>>> MessageBox()
+>>> MessageBox(text="Spam, spam, spam")
+>>> MessageBox(flags=2, text="foo bar")
+>>>
+\end{verbatim}
+
+A second example demonstrates output parameters.  The win32
+\code{GetWindowRect} function retrieves the dimensions of a specified
+window by copying them into \code{RECT} structure that the caller has to
+supply.  Here is the C declaration:
+\begin{verbatim}
+WINUSERAPI BOOL WINAPI
+GetWindowRect(
+     HWND hWnd,
+     LPRECT lpRect);
+\end{verbatim}
+
+Here is the wrapping with \code{ctypes}:
+\begin{quote}
+\begin{verbatim}>>> from ctypes import POINTER, WINFUNCTYPE, windll, WinError
+>>> from ctypes.wintypes import BOOL, HWND, RECT
+>>> prototype = WINFUNCTYPE(BOOL, HWND, POINTER(RECT))
+>>> paramflags = (1, "hwnd"), (2, "lprect")
+>>> GetWindowRect = prototype(("GetWindowRect", windll.user32), paramflags)
+>>>\end{verbatim}
+\end{quote}
+
+Functions with output parameters will automatically return the output
+parameter value if there is a single one, or a tuple containing the
+output parameter values when there are more than one, so the
+GetWindowRect function now returns a RECT instance, when called.
+
+Output parameters can be combined with the \member{errcheck} protocol to do
+further output processing and error checking.  The win32
+\code{GetWindowRect} api function returns a \code{BOOL} to signal success or
+failure, so this function could do the error checking, and raises an
+exception when the api call failed:
+\begin{verbatim}
+>>> def errcheck(result, func, args):
+...     if not result:
+...         raise WinError()
+...     return args
+>>> GetWindowRect.errcheck = errcheck
+>>>
+\end{verbatim}
+
+If the \member{errcheck} function returns the argument tuple it receives
+unchanged, \code{ctypes} continues the normal processing it does on the
+output parameters.  If you want to return a tuple of window
+coordinates instead of a \code{RECT} instance, you can retrieve the
+fields in the function and return them instead, the normal processing
+will no longer take place:
+\begin{verbatim}
+>>> def errcheck(result, func, args):
+...     if not result:
+...         raise WinError()
+...     rc = args[1]
+...     return rc.left, rc.top, rc.bottom, rc.right
+>>>
+>>> GetWindowRect.errcheck = errcheck
+>>>
+\end{verbatim}
+
+
+\subsubsection{Utility functions\label{ctypes-utility-functions}}
+
+\begin{funcdesc}{addressof}{obj}
+Returns the address of the memory buffer as integer.  \code{obj} must
+be an instance of a ctypes type.
+\end{funcdesc}
+
+\begin{funcdesc}{alignment}{obj_or_type}
+Returns the alignment requirements of a ctypes type.
+\code{obj{\_}or{\_}type} must be a ctypes type or instance.
+\end{funcdesc}
+
+\begin{funcdesc}{byref}{obj}
+Returns a light-weight pointer to \code{obj}, which must be an
+instance of a ctypes type. The returned object can only be used as
+a foreign function call parameter. It behaves similar to
+\code{pointer(obj)}, but the construction is a lot faster.
+\end{funcdesc}
+
+\begin{funcdesc}{cast}{obj, type}
+This function is similar to the cast operator in C. It returns a
+new instance of \code{type} which points to the same memory block as
+\code{obj}. \code{type} must be a pointer type, and \code{obj} must be an
+object that can be interpreted as a pointer.
+\end{funcdesc}
+
+\begin{funcdesc}{create_string_buffer}{init_or_size\optional{, size}}
+This function creates a mutable character buffer. The returned
+object is a ctypes array of \class{c{\_}char}.
+
+\code{init{\_}or{\_}size} must be an integer which specifies the size of
+the array, or a string which will be used to initialize the array
+items.
+
+If a string is specified as first argument, the buffer is made one
+item larger than the length of the string so that the last element
+in the array is a NUL termination character. An integer can be
+passed as second argument which allows to specify the size of the
+array if the length of the string should not be used.
+
+If the first parameter is a unicode string, it is converted into
+an 8-bit string according to ctypes conversion rules.
+\end{funcdesc}
+
+\begin{funcdesc}{create_unicode_buffer}{init_or_size\optional{, size}}
+This function creates a mutable unicode character buffer. The
+returned object is a ctypes array of \class{c{\_}wchar}.
+
+\code{init{\_}or{\_}size} must be an integer which specifies the size of
+the array, or a unicode string which will be used to initialize
+the array items.
+
+If a unicode string is specified as first argument, the buffer is
+made one item larger than the length of the string so that the
+last element in the array is a NUL termination character. An
+integer can be passed as second argument which allows to specify
+the size of the array if the length of the string should not be
+used.
+
+If the first parameter is a 8-bit string, it is converted into an
+unicode string according to ctypes conversion rules.
+\end{funcdesc}
+
+\begin{funcdesc}{DllCanUnloadNow}{}
+Windows only: This function is a hook which allows to implement
+inprocess COM servers with ctypes. It is called from the
+DllCanUnloadNow function that the {\_}ctypes extension dll exports.
+\end{funcdesc}
+
+\begin{funcdesc}{DllGetClassObject}{}
+Windows only: This function is a hook which allows to implement
+inprocess COM servers with ctypes. It is called from the
+DllGetClassObject function that the \code{{\_}ctypes} extension dll exports.
+\end{funcdesc}
+
+\begin{funcdesc}{FormatError}{\optional{code}}
+Windows only: Returns a textual description of the error code. If
+no error code is specified, the last error code is used by calling
+the Windows api function GetLastError.
+\end{funcdesc}
+
+\begin{funcdesc}{GetLastError}{}
+Windows only: Returns the last error code set by Windows in the
+calling thread.
+\end{funcdesc}
+
+\begin{funcdesc}{memmove}{dst, src, count}
+Same as the standard C memmove library function: copies \var{count}
+bytes from \code{src} to \var{dst}. \var{dst} and \code{src} must be
+integers or ctypes instances that can be converted to pointers.
+\end{funcdesc}
+
+\begin{funcdesc}{memset}{dst, c, count}
+Same as the standard C memset library function: fills the memory
+block at address \var{dst} with \var{count} bytes of value
+\var{c}. \var{dst} must be an integer specifying an address, or a
+ctypes instance.
+\end{funcdesc}
+
+\begin{funcdesc}{POINTER}{type}
+This factory function creates and returns a new ctypes pointer
+type. Pointer types are cached an reused internally, so calling
+this function repeatedly is cheap. type must be a ctypes type.
+\end{funcdesc}
+
+\begin{funcdesc}{pointer}{obj}
+This function creates a new pointer instance, pointing to
+\code{obj}. The returned object is of the type POINTER(type(obj)).
+
+Note: If you just want to pass a pointer to an object to a foreign
+function call, you should use \code{byref(obj)} which is much faster.
+\end{funcdesc}
+
+\begin{funcdesc}{resize}{obj, size}
+This function resizes the internal memory buffer of obj, which
+must be an instance of a ctypes type. It is not possible to make
+the buffer smaller than the native size of the objects type, as
+given by sizeof(type(obj)), but it is possible to enlarge the
+buffer.
+\end{funcdesc}
+
+\begin{funcdesc}{set_conversion_mode}{encoding, errors}
+This function sets the rules that ctypes objects use when
+converting between 8-bit strings and unicode strings. encoding
+must be a string specifying an encoding, like \code{'utf-8'} or
+\code{'mbcs'}, errors must be a string specifying the error handling
+on encoding/decoding errors. Examples of possible values are
+\code{"strict"}, \code{"replace"}, or \code{"ignore"}.
+
+\code{set{\_}conversion{\_}mode} returns a 2-tuple containing the previous
+conversion rules. On windows, the initial conversion rules are
+\code{('mbcs', 'ignore')}, on other systems \code{('ascii', 'strict')}.
+\end{funcdesc}
+
+\begin{funcdesc}{sizeof}{obj_or_type}
+Returns the size in bytes of a ctypes type or instance memory
+buffer. Does the same as the C \code{sizeof()} function.
+\end{funcdesc}
+
+\begin{funcdesc}{string_at}{address\optional{, size}}
+This function returns the string starting at memory address
+address. If size is specified, it is used as size, otherwise the
+string is assumed to be zero-terminated.
+\end{funcdesc}
+
+\begin{funcdesc}{WinError}{code=None, descr=None}
+Windows only: this function is probably the worst-named thing in
+ctypes. It creates an instance of WindowsError. If \var{code} is not
+specified, \code{GetLastError} is called to determine the error
+code. If \code{descr} is not spcified, \function{FormatError} is called to
+get a textual description of the error.
+\end{funcdesc}
+
+\begin{funcdesc}{wstring_at}{address}
+This function returns the wide character string starting at memory
+address \code{address} as unicode string. If \code{size} is specified,
+it is used as the number of characters of the string, otherwise
+the string is assumed to be zero-terminated.
+\end{funcdesc}
+
+
+\subsubsection{Data types\label{ctypes-data-types}}
+
+\begin{classdesc*}{_CData}
+This non-public class is the common base class of all ctypes data
+types.  Among other things, all ctypes type instances contain a
+memory block that hold C compatible data; the address of the
+memory block is returned by the \code{addressof()} helper function.
+Another instance variable is exposed as \member{{\_}objects}; this
+contains other Python objects that need to be kept alive in case
+the memory block contains pointers.
+\end{classdesc*}
+
+Common methods of ctypes data types, these are all class methods (to
+be exact, they are methods of the metaclass):
+
+\begin{methoddesc}{from_address}{address}
+This method returns a ctypes type instance using the memory
+specified by address which must be an integer.
+\end{methoddesc}
+
+\begin{methoddesc}{from_param}{obj}
+This method adapts obj to a ctypes type.  It is called with the
+actual object used in a foreign function call, when the type is
+present in the foreign functions \member{argtypes} tuple; it must
+return an object that can be used as function call parameter.
+
+All ctypes data types have a default implementation of this
+classmethod, normally it returns \code{obj} if that is an instance of
+the type.  Some types accept other objects as well.
+\end{methoddesc}
+
+\begin{methoddesc}{in_dll}{library, name}
+This method returns a ctypes type instance exported by a shared
+library. \var{name} is the name of the symbol that exports the data,
+\var{library} is the loaded shared library.
+\end{methoddesc}
+
+Common instance variables of ctypes data types:
+
+\begin{memberdesc}{_b_base_}
+Sometimes ctypes data instances do not own the memory block they
+contain, instead they share part of the memory block of a base
+object.  The \member{{\_}b{\_}base{\_}} readonly member is the root ctypes
+object that owns the memory block.
+\end{memberdesc}
+
+\begin{memberdesc}{_b_needsfree_}
+This readonly variable is true when the ctypes data instance has
+allocated the memory block itself, false otherwise.
+\end{memberdesc}
+
+\begin{memberdesc}{_objects}
+This member is either \code{None} or a dictionary containing Python
+objects that need to be kept alive so that the memory block
+contents is kept valid.  This object is only exposed for
+debugging; never modify the contents of this dictionary.
+\end{memberdesc}
+
+
+\subsubsection{Fundamental data types\label{ctypes-fundamental-data-types}}
+
+\begin{classdesc*}{_SimpleCData}
+This non-public class is the base class of all fundamental ctypes
+data types. It is mentioned here because it contains the common
+attributes of the fundamental ctypes data types.  \code{{\_}SimpleCData}
+is a subclass of \code{{\_}CData}, so it inherits their methods and
+attributes.
+\end{classdesc*}
+
+Instances have a single attribute:
+
+\begin{memberdesc}{value}
+This attribute contains the actual value of the instance. For
+integer and pointer types, it is an integer, for character types,
+it is a single character string, for character pointer types it
+is a Python string or unicode string.
+
+When the \code{value} attribute is retrieved from a ctypes instance,
+usually a new object is returned each time.  \code{ctypes} does \emph{not}
+implement original object return, always a new object is
+constructed.  The same is true for all other ctypes object
+instances.
+\end{memberdesc}
+
+Fundamental data types, when returned as foreign function call
+results, or, for example, by retrieving structure field members or
+array items, are transparently converted to native Python types.  In
+other words, if a foreign function has a \member{restype} of \class{c{\_}char{\_}p},
+you will always receive a Python string, \emph{not} a \class{c{\_}char{\_}p}
+instance.
+
+Subclasses of fundamental data types do \emph{not} inherit this behaviour.
+So, if a foreign functions \member{restype} is a subclass of \class{c{\_}void{\_}p},
+you will receive an instance of this subclass from the function call.
+Of course, you can get the value of the pointer by accessing the
+\code{value} attribute.
+
+These are the fundamental ctypes data types:
+
+\begin{classdesc*}{c_byte}
+Represents the C signed char datatype, and interprets the value as
+small integer. The constructor accepts an optional integer
+initializer; no overflow checking is done.
+\end{classdesc*}
+
+\begin{classdesc*}{c_char}
+Represents the C char datatype, and interprets the value as a single
+character. The constructor accepts an optional string initializer,
+the length of the string must be exactly one character.
+\end{classdesc*}
+
+\begin{classdesc*}{c_char_p}
+Represents the C char * datatype, which must be a pointer to a
+zero-terminated string. The constructor accepts an integer
+address, or a string.
+\end{classdesc*}
+
+\begin{classdesc*}{c_double}
+Represents the C double datatype. The constructor accepts an
+optional float initializer.
+\end{classdesc*}
+
+\begin{classdesc*}{c_float}
+Represents the C double datatype. The constructor accepts an
+optional float initializer.
+\end{classdesc*}
+
+\begin{classdesc*}{c_int}
+Represents the C signed int datatype. The constructor accepts an
+optional integer initializer; no overflow checking is done. On
+platforms where \code{sizeof(int) == sizeof(long)} it is an alias to
+\class{c{\_}long}.
+\end{classdesc*}
+
+\begin{classdesc*}{c_int8}
+Represents the C 8-bit \code{signed int} datatype. Usually an alias for
+\class{c{\_}byte}.
+\end{classdesc*}
+
+\begin{classdesc*}{c_int16}
+Represents the C 16-bit signed int datatype. Usually an alias for
+\class{c{\_}short}.
+\end{classdesc*}
+
+\begin{classdesc*}{c_int32}
+Represents the C 32-bit signed int datatype. Usually an alias for
+\class{c{\_}int}.
+\end{classdesc*}
+
+\begin{classdesc*}{c_int64}
+Represents the C 64-bit \code{signed int} datatype. Usually an alias
+for \class{c{\_}longlong}.
+\end{classdesc*}
+
+\begin{classdesc*}{c_long}
+Represents the C \code{signed long} datatype. The constructor accepts an
+optional integer initializer; no overflow checking is done.
+\end{classdesc*}
+
+\begin{classdesc*}{c_longlong}
+Represents the C \code{signed long long} datatype. The constructor accepts
+an optional integer initializer; no overflow checking is done.
+\end{classdesc*}
+
+\begin{classdesc*}{c_short}
+Represents the C \code{signed short} datatype. The constructor accepts an
+optional integer initializer; no overflow checking is done.
+\end{classdesc*}
+
+\begin{classdesc*}{c_size_t}
+Represents the C \code{size{\_}t} datatype.
+\end{classdesc*}
+
+\begin{classdesc*}{c_ubyte}
+Represents the C \code{unsigned char} datatype, it interprets the
+value as small integer. The constructor accepts an optional
+integer initializer; no overflow checking is done.
+\end{classdesc*}
+
+\begin{classdesc*}{c_uint}
+Represents the C \code{unsigned int} datatype. The constructor accepts an
+optional integer initializer; no overflow checking is done. On
+platforms where \code{sizeof(int) == sizeof(long)} it is an alias for
+\class{c{\_}ulong}.
+\end{classdesc*}
+
+\begin{classdesc*}{c_uint8}
+Represents the C 8-bit unsigned int datatype. Usually an alias for
+\class{c{\_}ubyte}.
+\end{classdesc*}
+
+\begin{classdesc*}{c_uint16}
+Represents the C 16-bit unsigned int datatype. Usually an alias for
+\class{c{\_}ushort}.
+\end{classdesc*}
+
+\begin{classdesc*}{c_uint32}
+Represents the C 32-bit unsigned int datatype. Usually an alias for
+\class{c{\_}uint}.
+\end{classdesc*}
+
+\begin{classdesc*}{c_uint64}
+Represents the C 64-bit unsigned int datatype. Usually an alias for
+\class{c{\_}ulonglong}.
+\end{classdesc*}
+
+\begin{classdesc*}{c_ulong}
+Represents the C \code{unsigned long} datatype. The constructor accepts an
+optional integer initializer; no overflow checking is done.
+\end{classdesc*}
+
+\begin{classdesc*}{c_ulonglong}
+Represents the C \code{unsigned long long} datatype. The constructor
+accepts an optional integer initializer; no overflow checking is
+done.
+\end{classdesc*}
+
+\begin{classdesc*}{c_ushort}
+Represents the C \code{unsigned short} datatype. The constructor accepts an
+optional integer initializer; no overflow checking is done.
+\end{classdesc*}
+
+\begin{classdesc*}{c_void_p}
+Represents the C \code{void *} type. The value is represented as
+integer. The constructor accepts an optional integer initializer.
+\end{classdesc*}
+
+\begin{classdesc*}{c_wchar}
+Represents the C \code{wchar{\_}t} datatype, and interprets the value as a
+single character unicode string. The constructor accepts an
+optional string initializer, the length of the string must be
+exactly one character.
+\end{classdesc*}
+
+\begin{classdesc*}{c_wchar_p}
+Represents the C \code{wchar{\_}t *} datatype, which must be a pointer to
+a zero-terminated wide character string. The constructor accepts
+an integer address, or a string.
+\end{classdesc*}
+
+\begin{classdesc*}{HRESULT}
+Windows only: Represents a \class{HRESULT} value, which contains success
+or error information for a function or method call.
+\end{classdesc*}
+
+\begin{classdesc*}{py_object}
+Represents the C \code{PyObject *} datatype.  Calling this without an
+argument creates a \code{NULL} \code{PyObject *} pointer.
+\end{classdesc*}
+
+The \code{ctypes.wintypes} module provides quite some other Windows
+specific data types, for example \code{HWND}, \code{WPARAM}, or \code{DWORD}.
+Some useful structures like \code{MSG} or \code{RECT} are also defined.
+
+
+\subsubsection{Structured data types\label{ctypes-structured-data-types}}
+
+\begin{classdesc}{Union}{*args, **kw}
+Abstract base class for unions in native byte order.
+\end{classdesc}
+
+\begin{classdesc}{BigEndianStructure}{*args, **kw}
+Abstract base class for structures in \emph{big endian} byte order.
+\end{classdesc}
+
+\begin{classdesc}{LittleEndianStructure}{*args, **kw}
+Abstract base class for structures in \emph{little endian} byte order.
+\end{classdesc}
+
+Structures with non-native byte order cannot contain pointer type
+fields, or any other data types containing pointer type fields.
+
+\begin{classdesc}{Structure}{*args, **kw}
+Abstract base class for structures in \emph{native} byte order.
+\end{classdesc}
+
+Concrete structure and union types must be created by subclassing one
+of these types, and at least define a \member{{\_}fields{\_}} class variable.
+\code{ctypes} will create descriptors which allow reading and writing the
+fields by direct attribute accesses.  These are the
+
+\begin{memberdesc}{_fields_}
+A sequence defining the structure fields.  The items must be
+2-tuples or 3-tuples.  The first item is the name of the field,
+the second item specifies the type of the field; it can be any
+ctypes data type.
+
+For integer type fields like \class{c{\_}int}, a third optional item can
+be given.  It must be a small positive integer defining the bit
+width of the field.
+
+Field names must be unique within one structure or union.  This is
+not checked, only one field can be accessed when names are
+repeated.
+
+It is possible to define the \member{{\_}fields{\_}} class variable \emph{after}
+the class statement that defines the Structure subclass, this
+allows to create data types that directly or indirectly reference
+themselves:
+\begin{verbatim}
+class List(Structure):
+    pass
+List._fields_ = [("pnext", POINTER(List)),
+                 ...
+                ]
+\end{verbatim}
+
+The \member{{\_}fields{\_}} class variable must, however, be defined before
+the type is first used (an instance is created, \code{sizeof()} is
+called on it, and so on).  Later assignments to the \member{{\_}fields{\_}}
+class variable will raise an AttributeError.
+
+Structure and union subclass constructors accept both positional
+and named arguments.  Positional arguments are used to initialize
+the fields in the same order as they appear in the \member{{\_}fields{\_}}
+definition, named arguments are used to initialize the fields with
+the corresponding name.
+
+It is possible to defined sub-subclasses of structure types, they
+inherit the fields of the base class plus the \member{{\_}fields{\_}} defined
+in the sub-subclass, if any.
+\end{memberdesc}
+
+\begin{memberdesc}{_pack_}
+An optional small integer that allows to override the alignment of
+structure fields in the instance.  \member{{\_}pack{\_}} must already be
+defined when \member{{\_}fields{\_}} is assigned, otherwise it will have no
+effect.
+\end{memberdesc}
+
+\begin{memberdesc}{_anonymous_}
+An optional sequence that lists the names of unnamed (anonymous)
+fields.  \code{{\_}anonymous{\_}} must be already defined when \member{{\_}fields{\_}}
+is assigned, otherwise it will have no effect.
+
+The fields listed in this variable must be structure or union type
+fields.  \code{ctypes} will create descriptors in the structure type
+that allows to access the nested fields directly, without the need
+to create the structure or union field.
+
+Here is an example type (Windows):
+\begin{verbatim}
+class _U(Union):
+    _fields_ = [("lptdesc", POINTER(TYPEDESC)),
+                ("lpadesc", POINTER(ARRAYDESC)),
+                ("hreftype", HREFTYPE)]
+
+class TYPEDESC(Structure):
+    _fields_ = [("u", _U),
+                ("vt", VARTYPE)]
+
+    _anonymous_ = ("u",)
+\end{verbatim}
+
+The \code{TYPEDESC} structure describes a COM data type, the \code{vt}
+field specifies which one of the union fields is valid.  Since the
+\code{u} field is defined as anonymous field, it is now possible to
+access the members directly off the TYPEDESC instance.
+\code{td.lptdesc} and \code{td.u.lptdesc} are equivalent, but the former
+is faster since it does not need to create a temporary union
+instance:
+\begin{verbatim}
+td = TYPEDESC()
+td.vt = VT_PTR
+td.lptdesc = POINTER(some_type)
+td.u.lptdesc = POINTER(some_type)
+\end{verbatim}
+\end{memberdesc}
+
+It is possible to defined sub-subclasses of structures, they inherit
+the fields of the base class.  If the subclass definition has a
+separate \member{{\_}fields{\_}} variable, the fields specified in this are
+appended to the fields of the base class.
+
+Structure and union constructors accept both positional and
+keyword arguments.  Positional arguments are used to initialize member
+fields in the same order as they are appear in \member{{\_}fields{\_}}.  Keyword
+arguments in the constructor are interpreted as attribute assignments,
+so they will initialize \member{{\_}fields{\_}} with the same name, or create new
+attributes for names not present in \member{{\_}fields{\_}}.
+
+
+\subsubsection{Arrays and pointers\label{ctypes-arrays-pointers}}
+
+Not yet written - please see section~\ref{ctypes-pointers}, pointers and
+section~\ref{ctypes-arrays}, arrays in the tutorial.
+


Property changes on: vendor/Python/current/Doc/lib/libctypes.tex
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Doc/lib/libcurses.tex
===================================================================
--- vendor/Python/current/Doc/lib/libcurses.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libcurses.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1395 @@
+\section{\module{curses} ---
+         Terminal handling for character-cell displays}
+
+\declaremodule{standard}{curses}
+\sectionauthor{Moshe Zadka}{moshez at zadka.site.co.il}
+\sectionauthor{Eric Raymond}{esr at thyrsus.com}
+\modulesynopsis{An interface to the curses library, providing portable
+                terminal handling.}
+
+\versionchanged[Added support for the \code{ncurses} library and
+                converted to a package]{1.6}
+
+The \module{curses} module provides an interface to the curses
+library, the de-facto standard for portable advanced terminal
+handling.
+
+While curses is most widely used in the \UNIX{} environment, versions
+are available for DOS, OS/2, and possibly other systems as well.  This
+extension module is designed to match the API of ncurses, an
+open-source curses library hosted on Linux and the BSD variants of
+\UNIX.
+
+\begin{seealso}
+  \seemodule{curses.ascii}{Utilities for working with \ASCII{}
+                           characters, regardless of your locale
+                           settings.}
+  \seemodule{curses.panel}{A panel stack extension that adds depth to 
+                           curses windows.}
+  \seemodule{curses.textpad}{Editable text widget for curses supporting 
+                             \program{Emacs}-like bindings.}
+  \seemodule{curses.wrapper}{Convenience function to ensure proper
+                             terminal setup and resetting on
+                             application entry and exit.}
+  \seetitle[http://www.python.org/doc/howto/curses/curses.html]{Curses
+            Programming with Python}{Tutorial material on using curses
+            with Python, by Andrew Kuchling and Eric Raymond, is
+            available on the Python Web site.}
+  \seetext{The \file{Demo/curses/} directory in the Python source
+           distribution contains some example programs using the
+           curses bindings provided by this module.}
+\end{seealso}
+
+
+\subsection{Functions \label{curses-functions}}
+
+The module \module{curses} defines the following exception:
+
+\begin{excdesc}{error}
+Exception raised when a curses library function returns an error.
+\end{excdesc}
+
+\note{Whenever \var{x} or \var{y} arguments to a function
+or a method are optional, they default to the current cursor location.
+Whenever \var{attr} is optional, it defaults to \constant{A_NORMAL}.}
+
+The module \module{curses} defines the following functions:
+
+\begin{funcdesc}{baudrate}{}
+Returns the output speed of the terminal in bits per second.  On
+software terminal emulators it will have a fixed high value.
+Included for historical reasons; in former times, it was used to 
+write output loops for time delays and occasionally to change
+interfaces depending on the line speed.
+\end{funcdesc}
+
+\begin{funcdesc}{beep}{}
+Emit a short attention sound.
+\end{funcdesc}
+
+\begin{funcdesc}{can_change_color}{}
+Returns true or false, depending on whether the programmer can change
+the colors displayed by the terminal.
+\end{funcdesc}
+
+\begin{funcdesc}{cbreak}{}
+Enter cbreak mode.  In cbreak mode (sometimes called ``rare'' mode)
+normal tty line buffering is turned off and characters are available
+to be read one by one.  However, unlike raw mode, special characters
+(interrupt, quit, suspend, and flow control) retain their effects on
+the tty driver and calling program.  Calling first \function{raw()}
+then \function{cbreak()} leaves the terminal in cbreak mode.
+\end{funcdesc}
+
+\begin{funcdesc}{color_content}{color_number}
+Returns the intensity of the red, green, and blue (RGB) components in
+the color \var{color_number}, which must be between \code{0} and
+\constant{COLORS}.  A 3-tuple is returned, containing the R,G,B values
+for the given color, which will be between \code{0} (no component) and
+\code{1000} (maximum amount of component).
+\end{funcdesc}
+
+\begin{funcdesc}{color_pair}{color_number}
+Returns the attribute value for displaying text in the specified
+color.  This attribute value can be combined with
+\constant{A_STANDOUT}, \constant{A_REVERSE}, and the other
+\constant{A_*} attributes.  \function{pair_number()} is the
+counterpart to this function.
+\end{funcdesc}
+
+\begin{funcdesc}{curs_set}{visibility}
+Sets the cursor state.  \var{visibility} can be set to 0, 1, or 2, for
+invisible, normal, or very visible.  If the terminal supports the
+visibility requested, the previous cursor state is returned;
+otherwise, an exception is raised.  On many terminals, the ``visible''
+mode is an underline cursor and the ``very visible'' mode is a block cursor.
+\end{funcdesc}
+
+\begin{funcdesc}{def_prog_mode}{}
+Saves the current terminal mode as the ``program'' mode, the mode when
+the running program is using curses.  (Its counterpart is the
+``shell'' mode, for when the program is not in curses.)  Subsequent calls
+to \function{reset_prog_mode()} will restore this mode.
+\end{funcdesc}
+
+\begin{funcdesc}{def_shell_mode}{}
+Saves the current terminal mode as the ``shell'' mode, the mode when
+the running program is not using curses.  (Its counterpart is the
+``program'' mode, when the program is using curses capabilities.)
+Subsequent calls
+to \function{reset_shell_mode()} will restore this mode.
+\end{funcdesc}
+
+\begin{funcdesc}{delay_output}{ms}
+Inserts an \var{ms} millisecond pause in output.  
+\end{funcdesc}
+
+\begin{funcdesc}{doupdate}{}
+Update the physical screen.  The curses library keeps two data
+structures, one representing the current physical screen contents
+and a virtual screen representing the desired next state.  The
+\function{doupdate()} ground updates the physical screen to match the
+virtual screen.
+
+The virtual screen may be updated by a \method{noutrefresh()} call
+after write operations such as \method{addstr()} have been performed
+on a window.  The normal \method{refresh()} call is simply
+\method{noutrefresh()} followed by \function{doupdate()}; if you have
+to update multiple windows, you can speed performance and perhaps
+reduce screen flicker by issuing \method{noutrefresh()} calls on
+all windows, followed by a single \function{doupdate()}.
+\end{funcdesc}
+
+\begin{funcdesc}{echo}{}
+Enter echo mode.  In echo mode, each character input is echoed to the
+screen as it is entered.  
+\end{funcdesc}
+
+\begin{funcdesc}{endwin}{}
+De-initialize the library, and return terminal to normal status.
+\end{funcdesc}
+
+\begin{funcdesc}{erasechar}{}
+Returns the user's current erase character.  Under \UNIX{} operating
+systems this is a property of the controlling tty of the curses
+program, and is not set by the curses library itself.
+\end{funcdesc}
+
+\begin{funcdesc}{filter}{}
+The \function{filter()} routine, if used, must be called before
+\function{initscr()} is  called.  The effect is that, during those
+calls, LINES is set to 1; the capabilities clear, cup, cud, cud1,
+cuu1, cuu, vpa are disabled; and the home string is set to the value of cr.
+The effect is that the cursor is confined to the current line, and so
+are screen updates.  This may be used for enabling character-at-a-time 
+line editing without touching the rest of the screen.
+\end{funcdesc}
+
+\begin{funcdesc}{flash}{}
+Flash the screen.  That is, change it to reverse-video and then change
+it back in a short interval.  Some people prefer such as `visible bell'
+to the audible attention signal produced by \function{beep()}.
+\end{funcdesc}
+
+\begin{funcdesc}{flushinp}{}
+Flush all input buffers.  This throws away any  typeahead  that  has
+been typed by the user and has not yet been processed by the program.
+\end{funcdesc}
+
+\begin{funcdesc}{getmouse}{}
+After \method{getch()} returns \constant{KEY_MOUSE} to signal a mouse
+event, this method should be call to retrieve the queued mouse event,
+represented as a 5-tuple
+\code{(\var{id}, \var{x}, \var{y}, \var{z}, \var{bstate})}.
+\var{id} is an ID value used to distinguish multiple devices,
+and \var{x}, \var{y}, \var{z} are the event's coordinates.  (\var{z}
+is currently unused.).  \var{bstate} is an integer value whose bits
+will be set to indicate the type of event, and will be the bitwise OR
+of one or more of the following constants, where \var{n} is the button
+number from 1 to 4:
+\constant{BUTTON\var{n}_PRESSED},
+\constant{BUTTON\var{n}_RELEASED},
+\constant{BUTTON\var{n}_CLICKED},
+\constant{BUTTON\var{n}_DOUBLE_CLICKED},
+\constant{BUTTON\var{n}_TRIPLE_CLICKED},
+\constant{BUTTON_SHIFT},
+\constant{BUTTON_CTRL},
+\constant{BUTTON_ALT}.
+\end{funcdesc}
+
+\begin{funcdesc}{getsyx}{}
+Returns the current coordinates of the virtual screen cursor in y and
+x.  If leaveok is currently true, then -1,-1 is returned.
+\end{funcdesc}
+
+\begin{funcdesc}{getwin}{file}
+Reads window related data stored in the file by an earlier
+\function{putwin()} call.  The routine then creates and initializes a
+new window using that data, returning the new window object.
+\end{funcdesc}
+
+\begin{funcdesc}{has_colors}{}
+Returns true if the terminal can display colors; otherwise, it
+returns false. 
+\end{funcdesc}
+
+\begin{funcdesc}{has_ic}{}
+Returns true if the terminal has insert- and delete- character
+capabilities.  This function is included for historical reasons only,
+as all modern software terminal emulators have such capabilities.
+\end{funcdesc}
+
+\begin{funcdesc}{has_il}{}
+Returns true if the terminal has insert- and
+delete-line  capabilities,  or  can  simulate  them  using
+scrolling regions. This function is included for historical reasons only,
+as all modern software terminal emulators have such capabilities.
+\end{funcdesc}
+
+\begin{funcdesc}{has_key}{ch}
+Takes a key value \var{ch}, and returns true if the current terminal
+type recognizes a key with that value.
+\end{funcdesc}
+
+\begin{funcdesc}{halfdelay}{tenths}
+Used for half-delay mode, which is similar to cbreak mode in that
+characters typed by the user are immediately available to the program.
+However, after blocking for \var{tenths} tenths of seconds, an
+exception is raised if nothing has been typed.  The value of
+\var{tenths} must be a number between 1 and 255.  Use
+\function{nocbreak()} to leave half-delay mode.
+\end{funcdesc}
+
+\begin{funcdesc}{init_color}{color_number, r, g, b}
+Changes the definition of a color, taking the number of the color to
+be changed followed by three RGB values (for the amounts of red,
+green, and blue components).  The value of \var{color_number} must be
+between \code{0} and \constant{COLORS}.  Each of \var{r}, \var{g},
+\var{b}, must be a value between \code{0} and \code{1000}.  When
+\function{init_color()} is used, all occurrences of that color on the
+screen immediately change to the new definition.  This function is a
+no-op on most terminals; it is active only if
+\function{can_change_color()} returns \code{1}.
+\end{funcdesc}
+
+\begin{funcdesc}{init_pair}{pair_number, fg, bg}
+Changes the definition of a color-pair.  It takes three arguments: the
+number of the color-pair to be changed, the foreground color number,
+and the background color number.  The value of \var{pair_number} must
+be between \code{1} and \code{COLOR_PAIRS - 1} (the \code{0} color
+pair is wired to white on black and cannot be changed).  The value of
+\var{fg} and \var{bg} arguments must be between \code{0} and
+\constant{COLORS}.  If the color-pair was previously initialized, the
+screen is refreshed and all occurrences of that color-pair are changed
+to the new definition.
+\end{funcdesc}
+
+\begin{funcdesc}{initscr}{}
+Initialize the library. Returns a \class{WindowObject} which represents
+the whole screen.  \note{If there is an error opening the terminal,
+the underlying curses library may cause the interpreter to exit.}
+\end{funcdesc}
+
+\begin{funcdesc}{isendwin}{}
+Returns true if \function{endwin()} has been called (that is, the 
+curses library has been deinitialized).
+\end{funcdesc}
+
+\begin{funcdesc}{keyname}{k}
+Return the name of the key numbered \var{k}.  The name of a key
+generating printable ASCII character is the key's character.  The name
+of a control-key combination is a two-character string consisting of a
+caret followed by the corresponding printable ASCII character.  The
+name of an alt-key combination (128-255) is a string consisting of the
+prefix `M-' followed by the name of the corresponding ASCII character.
+\end{funcdesc}
+
+\begin{funcdesc}{killchar}{}
+Returns the user's current line kill character. Under \UNIX{} operating
+systems this is a property of the controlling tty of the curses
+program, and is not set by the curses library itself.
+\end{funcdesc}
+
+\begin{funcdesc}{longname}{}
+Returns a string containing the terminfo long name field describing the current
+terminal.  The maximum length of a verbose description is 128
+characters.  It is defined only after the call to
+\function{initscr()}.
+\end{funcdesc}
+
+\begin{funcdesc}{meta}{yes}
+If \var{yes} is 1, allow 8-bit characters to be input. If \var{yes} is 0, 
+allow only 7-bit chars.
+\end{funcdesc}
+
+\begin{funcdesc}{mouseinterval}{interval}
+Sets the maximum time in milliseconds that can elapse between press and
+release events in order for them to be recognized as a click, and
+returns the previous interval value.  The default value is 200 msec,
+or one fifth of a second.
+\end{funcdesc}
+
+\begin{funcdesc}{mousemask}{mousemask}
+Sets the mouse events to be reported, and returns a tuple
+\code{(\var{availmask}, \var{oldmask})}.  
+\var{availmask} indicates which of the
+specified mouse events can be reported; on complete failure it returns
+0.  \var{oldmask} is the previous value of the given window's mouse
+event mask.  If this function is never called, no mouse events are
+ever reported.
+\end{funcdesc}
+
+\begin{funcdesc}{napms}{ms}
+Sleep for \var{ms} milliseconds.
+\end{funcdesc}
+
+\begin{funcdesc}{newpad}{nlines, ncols}
+Creates and returns a pointer to a new pad data structure with the
+given number of lines and columns.  A pad is returned as a
+window object.
+
+A pad is like a window, except that it is not restricted by the screen
+size, and is not necessarily associated with a particular part of the
+screen.  Pads can be used when a large window is needed, and only a
+part of the window will be on the screen at one time.  Automatic
+refreshes of pads (such as from scrolling or echoing of input) do not
+occur.  The \method{refresh()} and \method{noutrefresh()} methods of a
+pad require 6 arguments to specify the part of the pad to be
+displayed and the location on the screen to be used for the display.
+The arguments are pminrow, pmincol, sminrow, smincol, smaxrow,
+smaxcol; the p arguments refer to the upper left corner of the pad
+region to be displayed and the s arguments define a clipping box on
+the screen within which the pad region is to be displayed.
+\end{funcdesc}
+
+\begin{funcdesc}{newwin}{\optional{nlines, ncols,} begin_y, begin_x}
+Return a new window, whose left-upper corner is at 
+\code{(\var{begin_y}, \var{begin_x})}, and whose height/width is 
+\var{nlines}/\var{ncols}.  
+
+By default, the window will extend from the 
+specified position to the lower right corner of the screen.
+\end{funcdesc}
+
+\begin{funcdesc}{nl}{}
+Enter newline mode.  This mode translates the return key into newline
+on input, and translates newline into return and line-feed on output.
+Newline mode is initially on.
+\end{funcdesc}
+
+\begin{funcdesc}{nocbreak}{}
+Leave cbreak mode.  Return to normal ``cooked'' mode with line buffering.
+\end{funcdesc}
+
+\begin{funcdesc}{noecho}{}
+Leave echo mode.  Echoing of input characters is turned off.
+\end{funcdesc}
+
+\begin{funcdesc}{nonl}{}
+Leave newline mode.  Disable translation of return into newline on
+input, and disable low-level translation of newline into
+newline/return on output (but this does not change the behavior of
+\code{addch('\e n')}, which always does the equivalent of return and
+line feed on the virtual screen).  With translation off, curses can
+sometimes speed up vertical motion a little; also, it will be able to
+detect the return key on input.
+\end{funcdesc}
+
+\begin{funcdesc}{noqiflush}{}
+When the noqiflush routine is used, normal flush of input and
+output queues associated with the INTR, QUIT and SUSP
+characters will not be done.  You may want to call
+\function{noqiflush()} in a signal handler if you want output
+to continue as though the interrupt had not occurred, after the
+handler exits.
+\end{funcdesc}
+
+\begin{funcdesc}{noraw}{}
+Leave raw mode. Return to normal ``cooked'' mode with line buffering.
+\end{funcdesc}
+
+\begin{funcdesc}{pair_content}{pair_number}
+Returns a tuple \code{(\var{fg}, \var{bg})} containing the colors for
+the requested color pair.  The value of \var{pair_number} must be
+between \code{1} and \code{\constant{COLOR_PAIRS} - 1}.
+\end{funcdesc}
+
+\begin{funcdesc}{pair_number}{attr}
+Returns the number of the color-pair set by the attribute value
+\var{attr}.  \function{color_pair()} is the counterpart to this
+function.
+\end{funcdesc}
+
+\begin{funcdesc}{putp}{string}
+Equivalent to \code{tputs(str, 1, putchar)}; emits the value of a
+specified terminfo capability for the current terminal.  Note that the
+output of putp always goes to standard output.
+\end{funcdesc}
+
+\begin{funcdesc}{qiflush}{ \optional{flag} }
+If \var{flag} is false, the effect is the same as calling
+\function{noqiflush()}. If \var{flag} is true, or no argument is
+provided, the queues will be flushed when these control characters are
+read.
+\end{funcdesc}
+
+\begin{funcdesc}{raw}{}
+Enter raw mode.  In raw mode, normal line buffering and 
+processing of interrupt, quit, suspend, and flow control keys are
+turned off; characters are presented to curses input functions one
+by one.
+\end{funcdesc}
+
+\begin{funcdesc}{reset_prog_mode}{}
+Restores the  terminal  to ``program'' mode, as previously saved 
+by \function{def_prog_mode()}.
+\end{funcdesc}
+
+\begin{funcdesc}{reset_shell_mode}{}
+Restores the  terminal  to ``shell'' mode, as previously saved 
+by \function{def_shell_mode()}.
+\end{funcdesc}
+
+\begin{funcdesc}{setsyx}{y, x}
+Sets the virtual screen cursor to \var{y}, \var{x}.
+If \var{y} and \var{x} are both -1, then leaveok is set.  
+\end{funcdesc}
+
+\begin{funcdesc}{setupterm}{\optional{termstr, fd}}
+Initializes the terminal.  \var{termstr} is a string giving the
+terminal name; if omitted, the value of the TERM environment variable
+will be used.  \var{fd} is the file descriptor to which any
+initialization sequences will be sent; if not supplied, the file
+descriptor for \code{sys.stdout} will be used.
+\end{funcdesc}
+
+\begin{funcdesc}{start_color}{}
+Must be called if the programmer wants to use colors, and before any
+other color manipulation routine is called.  It is good
+practice to call this routine right after \function{initscr()}.
+
+\function{start_color()} initializes eight basic colors (black, red, 
+green, yellow, blue, magenta, cyan, and white), and two global
+variables in the \module{curses} module, \constant{COLORS} and
+\constant{COLOR_PAIRS}, containing the maximum number of colors and
+color-pairs the terminal can support.  It also restores the colors on
+the terminal to the values they had when the terminal was just turned
+on.
+\end{funcdesc}
+
+\begin{funcdesc}{termattrs}{}
+Returns a logical OR of all video attributes supported by the
+terminal.  This information is useful when a curses program needs
+complete control over the appearance of the screen.
+\end{funcdesc}
+
+\begin{funcdesc}{termname}{}
+Returns the value of the environment variable TERM, truncated to 14
+characters.
+\end{funcdesc}
+
+\begin{funcdesc}{tigetflag}{capname}
+Returns the value of the Boolean capability corresponding to the
+terminfo capability name \var{capname}.  The value \code{-1} is
+returned if \var{capname} is not a Boolean capability, or \code{0} if
+it is canceled or absent from the terminal description.
+\end{funcdesc}
+
+\begin{funcdesc}{tigetnum}{capname}
+Returns the value of the numeric capability corresponding to the
+terminfo capability name \var{capname}.  The value \code{-2} is
+returned if \var{capname} is not a numeric capability, or \code{-1} if
+it is canceled or absent from the terminal description.  
+\end{funcdesc}
+
+\begin{funcdesc}{tigetstr}{capname}
+Returns the value of the string capability corresponding to the
+terminfo capability name \var{capname}.  \code{None} is returned if
+\var{capname} is not a string capability, or is canceled or absent
+from the terminal description.
+\end{funcdesc}
+
+\begin{funcdesc}{tparm}{str\optional{,...}}
+Instantiates the string \var{str} with the supplied parameters, where 
+\var{str} should be a parameterized string obtained from the terminfo 
+database.  E.g. \code{tparm(tigetstr("cup"), 5, 3)} could result in 
+\code{'\e{}033[6;4H'}, the exact result depending on terminal type.
+\end{funcdesc}
+
+\begin{funcdesc}{typeahead}{fd}
+Specifies that the file descriptor \var{fd} be used for typeahead
+checking.  If \var{fd} is \code{-1}, then no typeahead checking is
+done.
+
+The curses library does ``line-breakout optimization'' by looking for
+typeahead periodically while updating the screen.  If input is found,
+and it is coming from a tty, the current update is postponed until
+refresh or doupdate is called again, allowing faster response to
+commands typed in advance. This function allows specifying a different
+file descriptor for typeahead checking.
+\end{funcdesc}
+
+\begin{funcdesc}{unctrl}{ch}
+Returns a string which is a printable representation of the character
+\var{ch}.  Control characters are displayed as a caret followed by the
+character, for example as \code{\textasciicircum C}. Printing
+characters are left as they are.
+\end{funcdesc}
+
+\begin{funcdesc}{ungetch}{ch}
+Push \var{ch} so the next \method{getch()} will return it.
+\note{Only one \var{ch} can be pushed before \method{getch()}
+is called.}
+\end{funcdesc}
+
+\begin{funcdesc}{ungetmouse}{id, x, y, z, bstate}
+Push a \constant{KEY_MOUSE} event onto the input queue, associating
+the given state data with it.
+\end{funcdesc}
+
+\begin{funcdesc}{use_env}{flag}
+If used, this function should be called before \function{initscr()} or
+newterm are called.  When \var{flag} is false, the values of
+lines and columns specified in the terminfo database will be
+used, even if environment variables \envvar{LINES} and
+\envvar{COLUMNS} (used by default) are set, or if curses is running in
+a window (in which case default behavior would be to use the window
+size if \envvar{LINES} and \envvar{COLUMNS} are not set).
+\end{funcdesc}
+
+\begin{funcdesc}{use_default_colors}{}
+Allow use of default values for colors on terminals supporting this
+feature. Use this to support transparency in your
+application.  The default color is assigned to the color number -1.
+After calling this function, 
+\code{init_pair(x, curses.COLOR_RED, -1)} initializes, for instance,
+color pair \var{x} to a red foreground color on the default background.
+\end{funcdesc}
+
+\subsection{Window Objects \label{curses-window-objects}}
+
+Window objects, as returned by \function{initscr()} and
+\function{newwin()} above, have the
+following methods:
+
+\begin{methoddesc}[window]{addch}{\optional{y, x,} ch\optional{, attr}}
+\note{A \emph{character} means a C character (an
+\ASCII{} code), rather then a Python character (a string of length 1).
+(This note is true whenever the documentation mentions a character.)
+The builtin \function{ord()} is handy for conveying strings to codes.}
+
+Paint character \var{ch} at \code{(\var{y}, \var{x})} with attributes
+\var{attr}, overwriting any character previously painter at that
+location.  By default, the character position and attributes are the
+current settings for the window object.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{addnstr}{\optional{y, x,} str, n\optional{, attr}}
+Paint at most \var{n} characters of the 
+string \var{str} at \code{(\var{y}, \var{x})} with attributes
+\var{attr}, overwriting anything previously on the display.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{addstr}{\optional{y, x,} str\optional{, attr}}
+Paint the string \var{str} at \code{(\var{y}, \var{x})} with attributes
+\var{attr}, overwriting anything previously on the display.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{attroff}{attr}
+Remove attribute \var{attr} from the ``background'' set applied to all
+writes to the current window.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{attron}{attr}
+Add attribute \var{attr} from the ``background'' set applied to all
+writes to the current window.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{attrset}{attr}
+Set the ``background'' set of attributes to \var{attr}.  This set is
+initially 0 (no attributes).
+\end{methoddesc}
+
+\begin{methoddesc}[window]{bkgd}{ch\optional{, attr}}
+Sets the background property of the window to the character \var{ch},
+with attributes \var{attr}.  The change is then applied to every
+character position in that window:
+\begin{itemize}
+\item  
+The attribute of every character in the window  is
+changed to the new background attribute.
+\item
+Wherever  the  former background character appears,
+it is changed to the new background character.
+\end{itemize}
+
+\end{methoddesc}
+
+\begin{methoddesc}[window]{bkgdset}{ch\optional{, attr}}
+Sets the window's background.  A window's background consists of a
+character and any combination of attributes.  The attribute part of
+the background is combined (OR'ed) with all non-blank characters that
+are written into the window.  Both the character and attribute parts
+of the background are combined with the blank characters.  The
+background becomes a property of the character and moves with the
+character through any scrolling and insert/delete line/character
+operations.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{border}{\optional{ls\optional{, rs\optional{,
+                                   ts\optional{, bs\optional{, tl\optional{,
+                                   tr\optional{, bl\optional{, br}}}}}}}}}
+Draw a border around the edges of the window. Each parameter specifies 
+the character to use for a specific part of the border; see the table
+below for more details.  The characters can be specified as integers
+or as one-character strings.
+
+\note{A \code{0} value for any parameter will cause the
+default character to be used for that parameter.  Keyword parameters
+can \emph{not} be used.  The defaults are listed in this table:}
+
+\begin{tableiii}{l|l|l}{var}{Parameter}{Description}{Default value}
+  \lineiii{ls}{Left side}{\constant{ACS_VLINE}}
+  \lineiii{rs}{Right side}{\constant{ACS_VLINE}}
+  \lineiii{ts}{Top}{\constant{ACS_HLINE}}
+  \lineiii{bs}{Bottom}{\constant{ACS_HLINE}}
+  \lineiii{tl}{Upper-left corner}{\constant{ACS_ULCORNER}}
+  \lineiii{tr}{Upper-right corner}{\constant{ACS_URCORNER}}
+  \lineiii{bl}{Bottom-left corner}{\constant{ACS_LLCORNER}}
+  \lineiii{br}{Bottom-right corner}{\constant{ACS_LRCORNER}}
+\end{tableiii}
+\end{methoddesc}
+
+\begin{methoddesc}[window]{box}{\optional{vertch, horch}}
+Similar to \method{border()}, but both \var{ls} and \var{rs} are
+\var{vertch} and both \var{ts} and {bs} are \var{horch}.  The default
+corner characters are always used by this function.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{clear}{}
+Like \method{erase()}, but also causes the whole window to be repainted
+upon next call to \method{refresh()}.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{clearok}{yes}
+If \var{yes} is 1, the next call to \method{refresh()}
+will clear the window completely.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{clrtobot}{}
+Erase from cursor to the end of the window: all lines below the cursor
+are deleted, and then the equivalent of \method{clrtoeol()} is performed.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{clrtoeol}{}
+Erase from cursor to the end of the line.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{cursyncup}{}
+Updates the current cursor position of all the ancestors of the window
+to reflect the current cursor position of the window.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{delch}{\optional{y, x}}
+Delete any character at \code{(\var{y}, \var{x})}.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{deleteln}{}
+Delete the line under the cursor. All following lines are moved up
+by 1 line.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{derwin}{\optional{nlines, ncols,} begin_y, begin_x}
+An abbreviation for ``derive window'', \method{derwin()} is the same
+as calling \method{subwin()}, except that \var{begin_y} and
+\var{begin_x} are relative to the origin of the window, rather than
+relative to the entire screen.  Returns a window object for the
+derived window.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{echochar}{ch\optional{, attr}}
+Add character \var{ch} with attribute \var{attr}, and immediately 
+call \method{refresh()} on the window.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{enclose}{y, x}
+Tests whether the given pair of screen-relative character-cell
+coordinates are enclosed by the given window, returning true or
+false.  It is useful for determining what subset of the screen
+windows enclose the location of a mouse event.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{erase}{}
+Clear the window.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{getbegyx}{}
+Return a tuple \code{(\var{y}, \var{x})} of co-ordinates of upper-left
+corner.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{getch}{\optional{y, x}}
+Get a character. Note that the integer returned does \emph{not} have to
+be in \ASCII{} range: function keys, keypad keys and so on return numbers
+higher than 256. In no-delay mode, -1 is returned if there is 
+no input.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{getkey}{\optional{y, x}}
+Get a character, returning a string instead of an integer, as
+\method{getch()} does. Function keys, keypad keys and so on return a
+multibyte string containing the key name.  In no-delay mode, an
+exception is raised if there is no input.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{getmaxyx}{}
+Return a tuple \code{(\var{y}, \var{x})} of the height and width of
+the window.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{getparyx}{}
+Returns the beginning coordinates of this window relative to its
+parent window into two integer variables y and x.  Returns
+\code{-1,-1} if this window has no parent.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{getstr}{\optional{y, x}}
+Read a string from the user, with primitive line editing capacity.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{getyx}{}
+Return a tuple \code{(\var{y}, \var{x})} of current cursor position 
+relative to the window's upper-left corner.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{hline}{\optional{y, x,} ch, n}
+Display a horizontal line starting at \code{(\var{y}, \var{x})} with
+length \var{n} consisting of the character \var{ch}.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{idcok}{flag}
+If \var{flag} is false, curses no longer considers using the hardware
+insert/delete character feature of the terminal; if \var{flag} is
+true, use of character insertion and deletion is enabled.  When curses
+is first initialized, use of character insert/delete is enabled by
+default.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{idlok}{yes}
+If called with \var{yes} equal to 1, \module{curses} will try and use
+hardware line editing facilities. Otherwise, line insertion/deletion
+are disabled.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{immedok}{flag}
+If \var{flag} is true, any change in the window image
+automatically causes the window to be refreshed; you no longer
+have to call \method{refresh()} yourself.  However, it may
+degrade performance considerably, due to repeated calls to
+wrefresh.  This option is disabled by default.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{inch}{\optional{y, x}}
+Return the character at the given position in the window. The bottom
+8 bits are the character proper, and upper bits are the attributes.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{insch}{\optional{y, x,} ch\optional{, attr}}
+Paint character \var{ch} at \code{(\var{y}, \var{x})} with attributes
+\var{attr}, moving the line from position \var{x} right by one
+character.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{insdelln}{nlines}
+Inserts \var{nlines} lines into the specified window above the current
+line.  The \var{nlines} bottom lines are lost.  For negative
+\var{nlines}, delete \var{nlines} lines starting with the one under
+the cursor, and move the remaining lines up.  The bottom \var{nlines}
+lines are cleared.  The current cursor position remains the same.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{insertln}{}
+Insert a blank line under the cursor. All following lines are moved
+down by 1 line.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{insnstr}{\optional{y, x,} str, n \optional{, attr}}
+Insert a character string (as many characters as will fit on the line)
+before the character under the cursor, up to \var{n} characters.  
+If \var{n} is zero or negative,
+the entire string is inserted.
+All characters to the right of
+the cursor are shifted right, with the rightmost characters on the
+line being lost.  The cursor position does not change (after moving to
+\var{y}, \var{x}, if specified). 
+\end{methoddesc}
+
+\begin{methoddesc}[window]{insstr}{\optional{y, x, } str \optional{, attr}}
+Insert a character string (as many characters as will fit on the line)
+before the character under the cursor.  All characters to the right of
+the cursor are shifted right, with the rightmost characters on the
+line being lost.  The cursor position does not change (after moving to
+\var{y}, \var{x}, if specified). 
+\end{methoddesc}
+
+\begin{methoddesc}[window]{instr}{\optional{y, x} \optional{, n}}
+Returns a string of characters, extracted from the window starting at
+the current cursor position, or at \var{y}, \var{x} if specified.
+Attributes are stripped from the characters.  If \var{n} is specified,
+\method{instr()} returns return a string at most \var{n} characters
+long (exclusive of the trailing NUL).
+\end{methoddesc}
+
+\begin{methoddesc}[window]{is_linetouched}{\var{line}}
+Returns true if the specified line was modified since the last call to
+\method{refresh()}; otherwise returns false.  Raises a
+\exception{curses.error} exception if \var{line} is not valid
+for the given window.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{is_wintouched}{}
+Returns true if the specified window was modified since the last call to
+\method{refresh()}; otherwise returns false.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{keypad}{yes}
+If \var{yes} is 1, escape sequences generated by some keys (keypad, 
+function keys) will be interpreted by \module{curses}.
+If \var{yes} is 0, escape sequences will be left as is in the input
+stream.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{leaveok}{yes}
+If \var{yes} is 1, cursor is left where it is on update, instead of
+being at ``cursor position.''  This reduces cursor movement where
+possible. If possible the cursor will be made invisible.
+
+If \var{yes} is 0, cursor will always be at ``cursor position'' after
+an update.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{move}{new_y, new_x}
+Move cursor to \code{(\var{new_y}, \var{new_x})}.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{mvderwin}{y, x}
+Moves the window inside its parent window.  The screen-relative
+parameters of the window are not changed.  This routine is used to
+display different parts of the parent window at the same physical
+position on the screen.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{mvwin}{new_y, new_x}
+Move the window so its upper-left corner is at
+\code{(\var{new_y}, \var{new_x})}.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{nodelay}{yes}
+If \var{yes} is \code{1}, \method{getch()} will be non-blocking.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{notimeout}{yes}
+If \var{yes} is \code{1}, escape sequences will not be timed out.
+
+If \var{yes} is \code{0}, after a few milliseconds, an escape sequence
+will not be interpreted, and will be left in the input stream as is.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{noutrefresh}{}
+Mark for refresh but wait.  This function updates the data structure
+representing the desired state of the window, but does not force
+an update of the physical screen.  To accomplish that, call 
+\function{doupdate()}.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{overlay}{destwin\optional{, sminrow, smincol,
+                                    dminrow, dmincol, dmaxrow, dmaxcol}}
+Overlay the window on top of \var{destwin}. The windows need not be
+the same size, only the overlapping region is copied. This copy is
+non-destructive, which means that the current background character
+does not overwrite the old contents of \var{destwin}.
+
+To get fine-grained control over the copied region, the second form
+of \method{overlay()} can be used. \var{sminrow} and \var{smincol} are
+the upper-left coordinates of the source window, and the other variables
+mark a rectangle in the destination window.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{overwrite}{destwin\optional{, sminrow, smincol,
+                                      dminrow, dmincol, dmaxrow, dmaxcol}}
+Overwrite the window on top of \var{destwin}. The windows need not be
+the same size, in which case only the overlapping region is
+copied. This copy is destructive, which means that the current
+background character overwrites the old contents of \var{destwin}.
+
+To get fine-grained control over the copied region, the second form
+of \method{overwrite()} can be used. \var{sminrow} and \var{smincol} are
+the upper-left coordinates of the source window, the other variables
+mark a rectangle in the destination window.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{putwin}{file}
+Writes all data associated with the window into the provided file
+object.  This information can be later retrieved using the
+\function{getwin()} function.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{redrawln}{beg, num}
+Indicates that the \var{num} screen lines, starting at line \var{beg},
+are corrupted and should be completely redrawn on the next
+\method{refresh()} call.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{redrawwin}{}
+Touches the entire window, causing it to be completely redrawn on the
+next \method{refresh()} call.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{refresh}{\optional{pminrow, pmincol, sminrow,
+                                    smincol, smaxrow, smaxcol}}
+Update the display immediately (sync actual screen with previous
+drawing/deleting methods).
+
+The 6 optional arguments can only be specified when the window is a
+pad created with \function{newpad()}.  The additional parameters are
+needed to indicate what part of the pad and screen are involved.
+\var{pminrow} and \var{pmincol} specify the upper left-hand corner of the
+rectangle to be displayed in the pad.  \var{sminrow}, \var{smincol},
+\var{smaxrow}, and \var{smaxcol} specify the edges of the rectangle to
+be displayed on the screen.  The lower right-hand corner of the
+rectangle to be displayed in the pad is calculated from the screen
+coordinates, since the rectangles must be the same size.  Both
+rectangles must be entirely contained within their respective
+structures.  Negative values of \var{pminrow}, \var{pmincol},
+\var{sminrow}, or \var{smincol} are treated as if they were zero.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{scroll}{\optional{lines\code{ = 1}}}
+Scroll the screen or scrolling region upward by \var{lines} lines.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{scrollok}{flag}
+Controls what happens when the cursor of a window is moved off the
+edge of the window or scrolling region, either as a result of a
+newline action on the bottom line, or typing the last character
+of the last line.  If \var{flag} is false, the cursor is left
+on the bottom line.  If \var{flag} is true, the window is
+scrolled up one line.  Note that in order to get the physical
+scrolling effect on the terminal, it is also necessary to call
+\method{idlok()}.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{setscrreg}{top, bottom}
+Set the scrolling region from line \var{top} to line \var{bottom}. All
+scrolling actions will take place in this region.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{standend}{}
+Turn off the standout attribute.  On some terminals this has the
+side effect of turning off all attributes.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{standout}{}
+Turn on attribute \var{A_STANDOUT}.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{subpad}{\optional{nlines, ncols,} begin_y, begin_x}
+Return a sub-window, whose upper-left corner is at
+\code{(\var{begin_y}, \var{begin_x})}, and whose width/height is
+\var{ncols}/\var{nlines}.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{subwin}{\optional{nlines, ncols,} begin_y, begin_x}
+Return a sub-window, whose upper-left corner is at
+\code{(\var{begin_y}, \var{begin_x})}, and whose width/height is
+\var{ncols}/\var{nlines}.
+
+By default, the sub-window will extend from the
+specified position to the lower right corner of the window.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{syncdown}{}
+Touches each location in the window that has been touched in any of
+its ancestor windows.  This routine is called by \method{refresh()},
+so it should almost never be necessary to call it manually.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{syncok}{flag}
+If called with \var{flag} set to true, then \method{syncup()} is
+called automatically whenever there is a change in the window.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{syncup}{}
+Touches all locations in ancestors of the window that have been changed in 
+the window.  
+\end{methoddesc}
+
+\begin{methoddesc}[window]{timeout}{delay}
+Sets blocking or non-blocking read behavior for the window.  If
+\var{delay} is negative, blocking read is used (which will wait
+indefinitely for input).  If \var{delay} is zero, then non-blocking
+read is used, and -1 will be returned by \method{getch()} if no input
+is waiting.  If \var{delay} is positive, then \method{getch()} will
+block for \var{delay} milliseconds, and return -1 if there is still no
+input at the end of that time.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{touchline}{start, count\optional{, changed}}
+Pretend \var{count} lines have been changed, starting with line
+\var{start}.  If \var{changed} is supplied, it specifies
+whether the affected lines are marked as 
+having been changed (\var{changed}=1) or unchanged (\var{changed}=0).
+\end{methoddesc}
+
+\begin{methoddesc}[window]{touchwin}{}
+Pretend the whole window has been changed, for purposes of drawing
+optimizations.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{untouchwin}{}
+Marks all lines in  the  window  as unchanged since the last call to
+\method{refresh()}. 
+\end{methoddesc}
+
+\begin{methoddesc}[window]{vline}{\optional{y, x,} ch, n}
+Display a vertical line starting at \code{(\var{y}, \var{x})} with
+length \var{n} consisting of the character \var{ch}.
+\end{methoddesc}
+
+\subsection{Constants}
+
+The \module{curses} module defines the following data members:
+
+\begin{datadesc}{ERR}
+Some curses routines  that  return  an integer, such as 
+\function{getch()}, return \constant{ERR} upon failure.  
+\end{datadesc}
+
+\begin{datadesc}{OK}
+Some curses routines  that  return  an integer, such as 
+\function{napms()}, return \constant{OK} upon success.  
+\end{datadesc}
+
+\begin{datadesc}{version}
+A string representing the current version of the module. 
+Also available as \constant{__version__}.
+\end{datadesc}
+
+Several constants are available to specify character cell attributes:
+
+\begin{tableii}{l|l}{code}{Attribute}{Meaning}
+  \lineii{A_ALTCHARSET}{Alternate character set mode.}
+  \lineii{A_BLINK}{Blink mode.}
+  \lineii{A_BOLD}{Bold mode.}
+  \lineii{A_DIM}{Dim mode.}
+  \lineii{A_NORMAL}{Normal attribute.}
+  \lineii{A_STANDOUT}{Standout mode.}
+  \lineii{A_UNDERLINE}{Underline mode.}
+\end{tableii}
+
+Keys are referred to by integer constants with names starting with 
+\samp{KEY_}.   The exact keycaps available are system dependent.
+
+% XXX this table is far too large!
+% XXX should this table be alphabetized?
+
+\begin{longtableii}{l|l}{code}{Key constant}{Key}
+  \lineii{KEY_MIN}{Minimum key value}
+  \lineii{KEY_BREAK}{ Break key (unreliable) }
+  \lineii{KEY_DOWN}{ Down-arrow }
+  \lineii{KEY_UP}{ Up-arrow }
+  \lineii{KEY_LEFT}{ Left-arrow }
+  \lineii{KEY_RIGHT}{ Right-arrow }
+  \lineii{KEY_HOME}{ Home key (upward+left arrow) }
+  \lineii{KEY_BACKSPACE}{ Backspace (unreliable) }
+  \lineii{KEY_F0}{ Function keys.  Up to 64 function keys are supported. }
+  \lineii{KEY_F\var{n}}{ Value of function key \var{n} }
+  \lineii{KEY_DL}{ Delete line }
+  \lineii{KEY_IL}{ Insert line }
+  \lineii{KEY_DC}{ Delete character }
+  \lineii{KEY_IC}{ Insert char or enter insert mode }
+  \lineii{KEY_EIC}{ Exit insert char mode }
+  \lineii{KEY_CLEAR}{ Clear screen }
+  \lineii{KEY_EOS}{ Clear to end of screen }
+  \lineii{KEY_EOL}{ Clear to end of line }
+  \lineii{KEY_SF}{ Scroll 1 line forward }
+  \lineii{KEY_SR}{ Scroll 1 line backward (reverse) }
+  \lineii{KEY_NPAGE}{ Next page }
+  \lineii{KEY_PPAGE}{ Previous page }
+  \lineii{KEY_STAB}{ Set tab }
+  \lineii{KEY_CTAB}{ Clear tab }
+  \lineii{KEY_CATAB}{ Clear all tabs }
+  \lineii{KEY_ENTER}{ Enter or send (unreliable) }
+  \lineii{KEY_SRESET}{ Soft (partial) reset (unreliable) }
+  \lineii{KEY_RESET}{ Reset or hard reset (unreliable) }
+  \lineii{KEY_PRINT}{ Print }
+  \lineii{KEY_LL}{ Home down or bottom (lower left) }
+  \lineii{KEY_A1}{ Upper left of keypad }
+  \lineii{KEY_A3}{ Upper right of keypad }
+  \lineii{KEY_B2}{ Center of keypad }
+  \lineii{KEY_C1}{ Lower left of keypad }
+  \lineii{KEY_C3}{ Lower right of keypad }
+  \lineii{KEY_BTAB}{ Back tab }
+  \lineii{KEY_BEG}{ Beg (beginning) }
+  \lineii{KEY_CANCEL}{ Cancel }
+  \lineii{KEY_CLOSE}{ Close }
+  \lineii{KEY_COMMAND}{ Cmd (command) }
+  \lineii{KEY_COPY}{ Copy }
+  \lineii{KEY_CREATE}{ Create }
+  \lineii{KEY_END}{ End }
+  \lineii{KEY_EXIT}{ Exit }
+  \lineii{KEY_FIND}{ Find }
+  \lineii{KEY_HELP}{ Help }
+  \lineii{KEY_MARK}{ Mark }
+  \lineii{KEY_MESSAGE}{ Message }
+  \lineii{KEY_MOVE}{ Move }
+  \lineii{KEY_NEXT}{ Next }
+  \lineii{KEY_OPEN}{ Open }
+  \lineii{KEY_OPTIONS}{ Options }
+  \lineii{KEY_PREVIOUS}{ Prev (previous) }
+  \lineii{KEY_REDO}{ Redo }
+  \lineii{KEY_REFERENCE}{ Ref (reference) }
+  \lineii{KEY_REFRESH}{ Refresh }
+  \lineii{KEY_REPLACE}{ Replace }
+  \lineii{KEY_RESTART}{ Restart }
+  \lineii{KEY_RESUME}{ Resume }
+  \lineii{KEY_SAVE}{ Save }
+  \lineii{KEY_SBEG}{ Shifted Beg (beginning) }
+  \lineii{KEY_SCANCEL}{ Shifted Cancel }
+  \lineii{KEY_SCOMMAND}{ Shifted Command }
+  \lineii{KEY_SCOPY}{ Shifted Copy }
+  \lineii{KEY_SCREATE}{ Shifted Create }
+  \lineii{KEY_SDC}{ Shifted Delete char }
+  \lineii{KEY_SDL}{ Shifted Delete line }
+  \lineii{KEY_SELECT}{ Select }
+  \lineii{KEY_SEND}{ Shifted End }
+  \lineii{KEY_SEOL}{ Shifted Clear line }
+  \lineii{KEY_SEXIT}{ Shifted Dxit }
+  \lineii{KEY_SFIND}{ Shifted Find }
+  \lineii{KEY_SHELP}{ Shifted Help }
+  \lineii{KEY_SHOME}{ Shifted Home }
+  \lineii{KEY_SIC}{ Shifted Input }
+  \lineii{KEY_SLEFT}{ Shifted Left arrow }
+  \lineii{KEY_SMESSAGE}{ Shifted Message }
+  \lineii{KEY_SMOVE}{ Shifted Move }
+  \lineii{KEY_SNEXT}{ Shifted Next }
+  \lineii{KEY_SOPTIONS}{ Shifted Options }
+  \lineii{KEY_SPREVIOUS}{ Shifted Prev }
+  \lineii{KEY_SPRINT}{ Shifted Print }
+  \lineii{KEY_SREDO}{ Shifted Redo }
+  \lineii{KEY_SREPLACE}{ Shifted Replace }
+  \lineii{KEY_SRIGHT}{ Shifted Right arrow }
+  \lineii{KEY_SRSUME}{ Shifted Resume }
+  \lineii{KEY_SSAVE}{ Shifted Save }
+  \lineii{KEY_SSUSPEND}{ Shifted Suspend }
+  \lineii{KEY_SUNDO}{ Shifted Undo }
+  \lineii{KEY_SUSPEND}{ Suspend }
+  \lineii{KEY_UNDO}{ Undo }
+  \lineii{KEY_MOUSE}{ Mouse event has occurred }
+  \lineii{KEY_RESIZE}{ Terminal resize event }
+  \lineii{KEY_MAX}{Maximum key value}
+\end{longtableii}
+
+On VT100s and their software emulations, such as X terminal emulators,
+there are normally at least four function keys (\constant{KEY_F1},
+\constant{KEY_F2}, \constant{KEY_F3}, \constant{KEY_F4}) available,
+and the arrow keys mapped to \constant{KEY_UP}, \constant{KEY_DOWN},
+\constant{KEY_LEFT} and \constant{KEY_RIGHT} in the obvious way.  If
+your machine has a PC keyboard, it is safe to expect arrow keys and
+twelve function keys (older PC keyboards may have only ten function
+keys); also, the following keypad mappings are standard:
+
+\begin{tableii}{l|l}{kbd}{Keycap}{Constant}
+   \lineii{Insert}{KEY_IC}
+   \lineii{Delete}{KEY_DC}
+   \lineii{Home}{KEY_HOME}
+   \lineii{End}{KEY_END}
+   \lineii{Page Up}{KEY_NPAGE}
+   \lineii{Page Down}{KEY_PPAGE}
+\end{tableii}
+
+The following table lists characters from the alternate character set.
+These are inherited from the VT100 terminal, and will generally be 
+available on software emulations such as X terminals.  When there
+is no graphic available, curses falls back on a crude printable ASCII
+approximation.
+\note{These are available only after \function{initscr()} has 
+been called.}
+
+\begin{longtableii}{l|l}{code}{ACS code}{Meaning}
+  \lineii{ACS_BBSS}{alternate name for upper right corner}
+  \lineii{ACS_BLOCK}{solid square block}
+  \lineii{ACS_BOARD}{board of squares}
+  \lineii{ACS_BSBS}{alternate name for horizontal line}
+  \lineii{ACS_BSSB}{alternate name for upper left corner}
+  \lineii{ACS_BSSS}{alternate name for top tee}
+  \lineii{ACS_BTEE}{bottom tee}
+  \lineii{ACS_BULLET}{bullet}
+  \lineii{ACS_CKBOARD}{checker board (stipple)}
+  \lineii{ACS_DARROW}{arrow pointing down}
+  \lineii{ACS_DEGREE}{degree symbol}
+  \lineii{ACS_DIAMOND}{diamond}
+  \lineii{ACS_GEQUAL}{greater-than-or-equal-to}
+  \lineii{ACS_HLINE}{horizontal line}
+  \lineii{ACS_LANTERN}{lantern symbol}
+  \lineii{ACS_LARROW}{left arrow}
+  \lineii{ACS_LEQUAL}{less-than-or-equal-to}
+  \lineii{ACS_LLCORNER}{lower left-hand corner}
+  \lineii{ACS_LRCORNER}{lower right-hand corner}
+  \lineii{ACS_LTEE}{left tee}
+  \lineii{ACS_NEQUAL}{not-equal sign}
+  \lineii{ACS_PI}{letter pi}
+  \lineii{ACS_PLMINUS}{plus-or-minus sign}
+  \lineii{ACS_PLUS}{big plus sign}
+  \lineii{ACS_RARROW}{right arrow}
+  \lineii{ACS_RTEE}{right tee}
+  \lineii{ACS_S1}{scan line 1}
+  \lineii{ACS_S3}{scan line 3}
+  \lineii{ACS_S7}{scan line 7}
+  \lineii{ACS_S9}{scan line 9}
+  \lineii{ACS_SBBS}{alternate name for lower right corner}
+  \lineii{ACS_SBSB}{alternate name for vertical line}
+  \lineii{ACS_SBSS}{alternate name for right tee}
+  \lineii{ACS_SSBB}{alternate name for lower left corner}
+  \lineii{ACS_SSBS}{alternate name for bottom tee}
+  \lineii{ACS_SSSB}{alternate name for left tee}
+  \lineii{ACS_SSSS}{alternate name for crossover or big plus}
+  \lineii{ACS_STERLING}{pound sterling}
+  \lineii{ACS_TTEE}{top tee}
+  \lineii{ACS_UARROW}{up arrow}
+  \lineii{ACS_ULCORNER}{upper left corner}
+  \lineii{ACS_URCORNER}{upper right corner}
+  \lineii{ACS_VLINE}{vertical line}
+\end{longtableii}
+
+The following table lists the predefined colors:
+
+\begin{tableii}{l|l}{code}{Constant}{Color}
+  \lineii{COLOR_BLACK}{Black}
+  \lineii{COLOR_BLUE}{Blue}
+  \lineii{COLOR_CYAN}{Cyan (light greenish blue)}
+  \lineii{COLOR_GREEN}{Green}
+  \lineii{COLOR_MAGENTA}{Magenta (purplish red)}
+  \lineii{COLOR_RED}{Red}
+  \lineii{COLOR_WHITE}{White}
+  \lineii{COLOR_YELLOW}{Yellow}
+\end{tableii}
+
+\section{\module{curses.textpad} ---
+         Text input widget for curses programs}
+
+\declaremodule{standard}{curses.textpad}
+\sectionauthor{Eric Raymond}{esr at thyrsus.com}
+\moduleauthor{Eric Raymond}{esr at thyrsus.com}
+\modulesynopsis{Emacs-like input editing in a curses window.}
+\versionadded{1.6}
+
+The \module{curses.textpad} module provides a \class{Textbox} class
+that handles elementary text editing in a curses window, supporting a
+set of keybindings resembling those of Emacs (thus, also of Netscape
+Navigator, BBedit 6.x, FrameMaker, and many other programs).  The
+module also provides a rectangle-drawing function useful for framing
+text boxes or for other purposes.
+
+The module \module{curses.textpad} defines the following function:
+
+\begin{funcdesc}{rectangle}{win, uly, ulx, lry, lrx}
+Draw a rectangle.  The first argument must be a window object; the
+remaining arguments are coordinates relative to that window.  The
+second and third arguments are the y and x coordinates of the upper
+left hand corner of the rectangle to be drawn; the fourth and fifth
+arguments are the y and x coordinates of the lower right hand corner.
+The rectangle will be drawn using VT100/IBM PC forms characters on
+terminals that make this possible (including xterm and most other
+software terminal emulators).  Otherwise it will be drawn with ASCII 
+dashes, vertical bars, and plus signs.
+\end{funcdesc}
+
+
+\subsection{Textbox objects \label{curses-textpad-objects}}
+
+You can instantiate a \class{Textbox} object as follows:
+
+\begin{classdesc}{Textbox}{win}
+Return a textbox widget object.  The \var{win} argument should be a
+curses \class{WindowObject} in which the textbox is to be contained.
+The edit cursor of the textbox is initially located at the upper left
+hand corner of the containing window, with coordinates \code{(0, 0)}.
+The instance's \member{stripspaces} flag is initially on.
+\end{classdesc}
+
+\class{Textbox} objects have the following methods:
+
+\begin{methoddesc}{edit}{\optional{validator}}
+This is the entry point you will normally use.  It accepts editing
+keystrokes until one of the termination keystrokes is entered.  If
+\var{validator} is supplied, it must be a function.  It will be called
+for each keystroke entered with the keystroke as a parameter; command
+dispatch is done on the result. This method returns the window
+contents as a string; whether blanks in the window are included is
+affected by the \member{stripspaces} member.
+\end{methoddesc}
+
+\begin{methoddesc}{do_command}{ch}
+Process a single command keystroke.  Here are the supported special
+keystrokes: 
+
+\begin{tableii}{l|l}{kbd}{Keystroke}{Action}
+  \lineii{Control-A}{Go to left edge of window.}
+  \lineii{Control-B}{Cursor left, wrapping to previous line if appropriate.}
+  \lineii{Control-D}{Delete character under cursor.}
+  \lineii{Control-E}{Go to right edge (stripspaces off) or end of line
+                  (stripspaces on).}
+  \lineii{Control-F}{Cursor right, wrapping to next line when appropriate.}
+  \lineii{Control-G}{Terminate, returning the window contents.}
+  \lineii{Control-H}{Delete character backward.}
+  \lineii{Control-J}{Terminate if the window is 1 line, otherwise
+                     insert newline.}
+  \lineii{Control-K}{If line is blank, delete it, otherwise clear to
+                     end of line.}
+  \lineii{Control-L}{Refresh screen.}
+  \lineii{Control-N}{Cursor down; move down one line.}
+  \lineii{Control-O}{Insert a blank line at cursor location.}
+  \lineii{Control-P}{Cursor up; move up one line.}
+\end{tableii}
+
+Move operations do nothing if the cursor is at an edge where the
+movement is not possible.  The following synonyms are supported where
+possible:
+
+\begin{tableii}{l|l}{constant}{Constant}{Keystroke}
+  \lineii{KEY_LEFT}{\kbd{Control-B}}
+  \lineii{KEY_RIGHT}{\kbd{Control-F}}
+  \lineii{KEY_UP}{\kbd{Control-P}}
+  \lineii{KEY_DOWN}{\kbd{Control-N}}
+  \lineii{KEY_BACKSPACE}{\kbd{Control-h}}
+\end{tableii}
+
+All other keystrokes are treated as a command to insert the given
+character and move right (with line wrapping).
+\end{methoddesc}
+
+\begin{methoddesc}{gather}{}
+This method returns the window contents as a string; whether blanks in
+the window are included is affected by the \member{stripspaces}
+member.
+\end{methoddesc}
+
+\begin{memberdesc}{stripspaces}
+This data member is a flag which controls the interpretation of blanks in
+the window.  When it is on, trailing blanks on each line are ignored;
+any cursor motion that would land the cursor on a trailing blank goes
+to the end of that line instead, and trailing blanks are stripped when
+the window contents are gathered.
+\end{memberdesc}
+
+
+\section{\module{curses.wrapper} ---
+         Terminal handler for curses programs}
+
+\declaremodule{standard}{curses.wrapper}
+\sectionauthor{Eric Raymond}{esr at thyrsus.com}
+\moduleauthor{Eric Raymond}{esr at thyrsus.com}
+\modulesynopsis{Terminal configuration wrapper for curses programs.}
+\versionadded{1.6}
+
+This module supplies one function, \function{wrapper()}, which runs
+another function which should be the rest of your curses-using
+application.  If the application raises an exception,
+\function{wrapper()} will restore the terminal to a sane state before
+re-raising the exception and generating a traceback.
+
+\begin{funcdesc}{wrapper}{func, \moreargs}
+Wrapper function that initializes curses and calls another function,
+\var{func}, restoring normal keyboard/screen behavior on error.
+The callable object \var{func} is then passed the main window 'stdscr'
+as its first argument, followed by any other arguments passed to
+\function{wrapper()}.
+\end{funcdesc}
+
+Before calling the hook function, \function{wrapper()} turns on cbreak
+mode, turns off echo, enables the terminal keypad, and initializes
+colors if the terminal has color support.  On exit (whether normally
+or by exception) it restores cooked mode, turns on echo, and disables
+the terminal keypad.
+

Added: vendor/Python/current/Doc/lib/libcursespanel.tex
===================================================================
--- vendor/Python/current/Doc/lib/libcursespanel.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libcursespanel.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,96 @@
+\section{\module{curses.panel} ---
+         A panel stack extension for curses.}
+
+\declaremodule{standard}{curses.panel}
+\sectionauthor{A.M. Kuchling}{amk at amk.ca}
+\modulesynopsis{A panel stack extension that adds depth to 
+                curses windows.}
+
+Panels are windows with the added feature of depth, so they can be
+stacked on top of each other, and only the visible portions of
+each window will be displayed.  Panels can be added, moved up
+or down in the stack, and removed. 
+
+\subsection{Functions \label{cursespanel-functions}}
+
+The module \module{curses.panel} defines the following functions:
+
+
+\begin{funcdesc}{bottom_panel}{}
+Returns the bottom panel in the panel stack.
+\end{funcdesc}
+
+\begin{funcdesc}{new_panel}{win}
+Returns a panel object, associating it with the given window \var{win}.
+Be aware that you need to keep the returned panel object referenced
+explicitly.  If you don't, the panel object is garbage collected and
+removed from the panel stack.
+\end{funcdesc}
+
+\begin{funcdesc}{top_panel}{}
+Returns the top panel in the panel stack.
+\end{funcdesc}
+
+\begin{funcdesc}{update_panels}{}
+Updates the virtual screen after changes in the panel stack. This does
+not call \function{curses.doupdate()}, so you'll have to do this yourself.
+\end{funcdesc}
+
+\subsection{Panel Objects \label{curses-panel-objects}}
+
+Panel objects, as returned by \function{new_panel()} above, are windows
+with a stacking order. There's always a window associated with a
+panel which determines the content, while the panel methods are
+responsible for the window's depth in the panel stack.
+
+Panel objects have the following methods:
+
+\begin{methoddesc}{above}{}
+Returns the panel above the current panel.
+\end{methoddesc}
+
+\begin{methoddesc}{below}{}
+Returns the panel below the current panel.
+\end{methoddesc}
+
+\begin{methoddesc}{bottom}{}
+Push the panel to the bottom of the stack.
+\end{methoddesc}
+
+\begin{methoddesc}{hidden}{}
+Returns true if the panel is hidden (not visible), false otherwise.
+\end{methoddesc}
+
+\begin{methoddesc}{hide}{}
+Hide the panel. This does not delete the object, it just makes the
+window on screen invisible.
+\end{methoddesc}
+
+\begin{methoddesc}{move}{y, x}
+Move the panel to the screen coordinates \code{(\var{y}, \var{x})}.
+\end{methoddesc}
+
+\begin{methoddesc}{replace}{win}
+Change the window associated with the panel to the window \var{win}.
+\end{methoddesc}
+
+\begin{methoddesc}{set_userptr}{obj}
+Set the panel's user pointer to \var{obj}. This is used to associate an
+arbitrary piece of data with the panel, and can be any Python object.
+\end{methoddesc}
+
+\begin{methoddesc}{show}{}
+Display the panel (which might have been hidden).
+\end{methoddesc}
+
+\begin{methoddesc}{top}{}
+Push panel to the top of the stack.
+\end{methoddesc}
+
+\begin{methoddesc}{userptr}{}
+Returns the user pointer for the panel.  This might be any Python object.
+\end{methoddesc}
+
+\begin{methoddesc}{window}{}
+Returns the window object associated with the panel.
+\end{methoddesc}

Added: vendor/Python/current/Doc/lib/libdatetime.tex
===================================================================
--- vendor/Python/current/Doc/lib/libdatetime.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libdatetime.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1441 @@
+% XXX what order should the types be discussed in?
+
+\section{\module{datetime} ---
+         Basic date and time types}
+
+\declaremodule{builtin}{datetime}
+\modulesynopsis{Basic date and time types.}
+\moduleauthor{Tim Peters}{tim at zope.com}
+\sectionauthor{Tim Peters}{tim at zope.com}
+\sectionauthor{A.M. Kuchling}{amk at amk.ca}
+
+\versionadded{2.3}
+
+
+The \module{datetime} module supplies classes for manipulating dates
+and times in both simple and complex ways.  While date and time
+arithmetic is supported, the focus of the implementation is on
+efficient member extraction for output formatting and manipulation.
+
+There are two kinds of date and time objects: ``naive'' and ``aware''.
+This distinction refers to whether the object has any notion of time
+zone, daylight saving time, or other kind of algorithmic or political
+time adjustment.  Whether a naive \class{datetime} object represents
+Coordinated Universal Time (UTC), local time, or time in some other
+timezone is purely up to the program, just like it's up to the program
+whether a particular number represents metres, miles, or mass.  Naive
+\class{datetime} objects are easy to understand and to work with, at
+the cost of ignoring some aspects of reality.
+
+For applications requiring more, \class{datetime} and \class{time}
+objects have an optional time zone information member,
+\member{tzinfo}, that can contain an instance of a subclass of
+the abstract \class{tzinfo} class.  These \class{tzinfo} objects
+capture information about the offset from UTC time, the time zone
+name, and whether Daylight Saving Time is in effect.  Note that no
+concrete \class{tzinfo} classes are supplied by the \module{datetime}
+module.  Supporting timezones at whatever level of detail is required
+is up to the application.  The rules for time adjustment across the
+world are more political than rational, and there is no standard
+suitable for every application.
+
+The \module{datetime} module exports the following constants:
+
+\begin{datadesc}{MINYEAR}
+  The smallest year number allowed in a \class{date} or
+  \class{datetime} object.  \constant{MINYEAR}
+  is \code{1}.
+\end{datadesc}
+
+\begin{datadesc}{MAXYEAR}
+  The largest year number allowed in a \class{date} or \class{datetime}
+  object.  \constant{MAXYEAR} is \code{9999}.
+\end{datadesc}
+
+\begin{seealso}
+  \seemodule{calendar}{General calendar related functions.}
+  \seemodule{time}{Time access and conversions.}
+\end{seealso}
+
+\subsection{Available Types}
+
+\begin{classdesc*}{date}
+  An idealized naive date, assuming the current Gregorian calendar
+  always was, and always will be, in effect.
+  Attributes: \member{year}, \member{month}, and \member{day}.
+\end{classdesc*}
+
+\begin{classdesc*}{time}
+  An idealized time, independent of any particular day, assuming
+  that every day has exactly 24*60*60 seconds (there is no notion
+  of "leap seconds" here).
+  Attributes: \member{hour}, \member{minute}, \member{second},
+              \member{microsecond}, and \member{tzinfo}.
+\end{classdesc*}
+
+\begin{classdesc*}{datetime}
+  A combination of a date and a time.
+  Attributes: \member{year}, \member{month}, \member{day},
+              \member{hour}, \member{minute}, \member{second},
+              \member{microsecond}, and \member{tzinfo}.
+\end{classdesc*}
+
+\begin{classdesc*}{timedelta}
+  A duration expressing the difference between two \class{date},
+  \class{time}, or \class{datetime} instances to microsecond
+  resolution.
+\end{classdesc*}
+
+\begin{classdesc*}{tzinfo}
+  An abstract base class for time zone information objects.  These
+  are used by the  \class{datetime} and \class{time} classes to
+  provide a customizable notion of time adjustment (for example, to
+  account for time zone and/or daylight saving time).
+\end{classdesc*}
+
+Objects of these types are immutable.
+
+Objects of the \class{date} type are always naive.
+
+An object \var{d} of type \class{time} or \class{datetime} may be
+naive or aware.  \var{d} is aware if \code{\var{d}.tzinfo} is not
+\code{None} and \code{\var{d}.tzinfo.utcoffset(\var{d})} does not return
+\code{None}.  If \code{\var{d}.tzinfo} is \code{None}, or if
+\code{\var{d}.tzinfo} is not \code{None} but
+\code{\var{d}.tzinfo.utcoffset(\var{d})} returns \code{None}, \var{d}
+is naive.
+
+The distinction between naive and aware doesn't apply to
+\class{timedelta} objects.
+
+Subclass relationships:
+
+\begin{verbatim}
+object
+    timedelta
+    tzinfo
+    time
+    date
+        datetime
+\end{verbatim}
+
+\subsection{\class{timedelta} Objects \label{datetime-timedelta}}
+
+A \class{timedelta} object represents a duration, the difference
+between two dates or times.
+
+\begin{classdesc}{timedelta}{\optional{days\optional{, seconds\optional{,
+                             microseconds\optional{, milliseconds\optional{,
+                             minutes\optional{, hours\optional{, weeks}}}}}}}}
+  All arguments are optional and default to \code{0}.  Arguments may
+  be ints, longs, or floats, and may be positive or negative.
+
+  Only \var{days}, \var{seconds} and \var{microseconds} are stored
+  internally.  Arguments are converted to those units:
+
+\begin{itemize}
+  \item A millisecond is converted to 1000 microseconds.
+  \item A minute is converted to 60 seconds.
+  \item An hour is converted to 3600 seconds.
+  \item A week is converted to 7 days.
+\end{itemize}
+
+  and days, seconds and microseconds are then normalized so that the
+  representation is unique, with
+
+\begin{itemize}
+  \item \code{0 <= \var{microseconds} < 1000000}
+  \item \code{0 <= \var{seconds} < 3600*24} (the number of seconds in one day)
+  \item \code{-999999999 <= \var{days} <= 999999999}
+\end{itemize}
+
+  If any argument is a float and there are fractional microseconds,
+  the fractional microseconds left over from all arguments are combined
+  and their sum is rounded to the nearest microsecond.  If no
+  argument is a float, the conversion and normalization processes
+  are exact (no information is lost).
+
+  If the normalized value of days lies outside the indicated range,
+  \exception{OverflowError} is raised.
+
+  Note that normalization of negative values may be surprising at first.
+  For example,
+
+\begin{verbatim}
+>>> d = timedelta(microseconds=-1)
+>>> (d.days, d.seconds, d.microseconds)
+(-1, 86399, 999999)
+\end{verbatim}
+\end{classdesc}
+
+Class attributes are:
+
+\begin{memberdesc}{min}
+  The most negative \class{timedelta} object,
+  \code{timedelta(-999999999)}.
+\end{memberdesc}
+
+\begin{memberdesc}{max}
+  The most positive \class{timedelta} object,
+  \code{timedelta(days=999999999, hours=23, minutes=59, seconds=59,
+                  microseconds=999999)}.
+\end{memberdesc}
+
+\begin{memberdesc}{resolution}
+  The smallest possible difference between non-equal
+  \class{timedelta} objects, \code{timedelta(microseconds=1)}.
+\end{memberdesc}
+
+Note that, because of normalization, \code{timedelta.max} \textgreater
+\code{-timedelta.min}.  \code{-timedelta.max} is not representable as
+a \class{timedelta} object.
+
+Instance attributes (read-only):
+
+\begin{tableii}{c|l}{code}{Attribute}{Value}
+  \lineii{days}{Between -999999999 and 999999999 inclusive}
+  \lineii{seconds}{Between 0 and 86399 inclusive}
+  \lineii{microseconds}{Between 0 and 999999 inclusive}
+\end{tableii}
+
+Supported operations:
+
+% XXX this table is too wide!
+\begin{tableii}{c|l}{code}{Operation}{Result}
+  \lineii{\var{t1} = \var{t2} + \var{t3}}
+          {Sum of \var{t2} and \var{t3}.
+           Afterwards \var{t1}-\var{t2} == \var{t3} and \var{t1}-\var{t3}
+           == \var{t2} are true.
+          (1)}
+  \lineii{\var{t1} = \var{t2} - \var{t3}}
+          {Difference of \var{t2} and \var{t3}.
+           Afterwards \var{t1} == \var{t2} - \var{t3} and
+           \var{t2} == \var{t1} + \var{t3} are true.
+          (1)}
+  \lineii{\var{t1} = \var{t2} * \var{i} or \var{t1} = \var{i} * \var{t2}}
+          {Delta multiplied by an integer or long.
+           Afterwards \var{t1} // i == \var{t2} is true,
+           provided \code{i != 0}.}
+  \lineii{}{In general, \var{t1} * i == \var{t1} * (i-1) + \var{t1} is true.
+          (1)}
+  \lineii{\var{t1} = \var{t2} // \var{i}}
+          {The floor is computed and the remainder (if any) is thrown away.
+          (3)}
+  \lineii{+\var{t1}}
+          {Returns a \class{timedelta} object with the same value.
+          (2)}
+  \lineii{-\var{t1}}
+          {equivalent to \class{timedelta}(-\var{t1.days}, -\var{t1.seconds},
+           -\var{t1.microseconds}), and to \var{t1}* -1.
+          (1)(4)}
+  \lineii{abs(\var{t})}
+          {equivalent to +\var{t} when \code{t.days >= 0}, and to
+           -\var{t} when \code{t.days < 0}.
+          (2)}
+\end{tableii}
+\noindent
+Notes:
+
+\begin{description}
+\item[(1)]
+  This is exact, but may overflow.
+
+\item[(2)]
+  This is exact, and cannot overflow.
+
+\item[(3)]
+  Division by 0 raises \exception{ZeroDivisionError}.
+
+\item[(4)]
+  -\var{timedelta.max} is not representable as a \class{timedelta} object.
+\end{description}
+
+In addition to the operations listed above \class{timedelta} objects
+support certain additions and subtractions with \class{date} and
+\class{datetime} objects (see below).
+
+Comparisons of \class{timedelta} objects are supported with the
+\class{timedelta} object representing the smaller duration considered
+to be the smaller timedelta.
+In order to stop mixed-type comparisons from falling back to the
+default comparison by object address, when a \class{timedelta} object is
+compared to an object of a different type, \exception{TypeError} is
+raised unless the comparison is \code{==} or \code{!=}.  The latter
+cases return \constant{False} or \constant{True}, respectively.
+
+\class{timedelta} objects are hashable (usable as dictionary keys),
+support efficient pickling, and in Boolean contexts, a \class{timedelta}
+object is considered to be true if and only if it isn't equal to
+\code{timedelta(0)}.
+
+
+\subsection{\class{date} Objects \label{datetime-date}}
+
+A \class{date} object represents a date (year, month and day) in an idealized
+calendar, the current Gregorian calendar indefinitely extended in both
+directions.  January 1 of year 1 is called day number 1, January 2 of year
+1 is called day number 2, and so on.  This matches the definition of the
+"proleptic Gregorian" calendar in Dershowitz and Reingold's book
+\citetitle{Calendrical Calculations}, where it's the base calendar for all
+computations.  See the book for algorithms for converting between
+proleptic Gregorian ordinals and many other calendar systems.
+
+\begin{classdesc}{date}{year, month, day}
+  All arguments are required.  Arguments may be ints or longs, in the
+  following ranges:
+
+  \begin{itemize}
+    \item \code{MINYEAR <= \var{year} <= MAXYEAR}
+    \item \code{1 <= \var{month} <= 12}
+    \item \code{1 <= \var{day} <= number of days in the given month and year}
+  \end{itemize}
+
+  If an argument outside those ranges is given, \exception{ValueError}
+  is raised.
+\end{classdesc}
+
+Other constructors, all class methods:
+
+\begin{methoddesc}{today}{}
+  Return the current local date.  This is equivalent to
+  \code{date.fromtimestamp(time.time())}.
+\end{methoddesc}
+
+\begin{methoddesc}{fromtimestamp}{timestamp}
+  Return the local date corresponding to the POSIX timestamp, such
+  as is returned by \function{time.time()}.  This may raise
+  \exception{ValueError}, if the timestamp is out of the range of
+  values supported by the platform C \cfunction{localtime()}
+  function.  It's common for this to be restricted to years from 1970
+  through 2038.  Note that on non-POSIX systems that include leap
+  seconds in their notion of a timestamp, leap seconds are ignored by
+  \method{fromtimestamp()}.
+\end{methoddesc}
+
+\begin{methoddesc}{fromordinal}{ordinal}
+  Return the date corresponding to the proleptic Gregorian ordinal,
+  where January 1 of year 1 has ordinal 1.  \exception{ValueError} is
+  raised unless \code{1 <= \var{ordinal} <= date.max.toordinal()}.
+  For any date \var{d}, \code{date.fromordinal(\var{d}.toordinal()) ==
+  \var{d}}.
+\end{methoddesc}
+
+Class attributes:
+
+\begin{memberdesc}{min}
+  The earliest representable date, \code{date(MINYEAR, 1, 1)}.
+\end{memberdesc}
+
+\begin{memberdesc}{max}
+  The latest representable date, \code{date(MAXYEAR, 12, 31)}.
+\end{memberdesc}
+
+\begin{memberdesc}{resolution}
+  The smallest possible difference between non-equal date
+  objects, \code{timedelta(days=1)}.
+\end{memberdesc}
+
+Instance attributes (read-only):
+
+\begin{memberdesc}{year}
+  Between \constant{MINYEAR} and \constant{MAXYEAR} inclusive.
+\end{memberdesc}
+
+\begin{memberdesc}{month}
+  Between 1 and 12 inclusive.
+\end{memberdesc}
+
+\begin{memberdesc}{day}
+  Between 1 and the number of days in the given month of the given
+  year.
+\end{memberdesc}
+
+Supported operations:
+
+\begin{tableii}{c|l}{code}{Operation}{Result}
+  \lineii{\var{date2} = \var{date1} + \var{timedelta}}
+    {\var{date2} is \code{\var{timedelta}.days} days removed from
+    \var{date1}.  (1)}
+
+
+  \lineii{\var{date2} = \var{date1} - \var{timedelta}}
+   {Computes \var{date2} such that \code{\var{date2} + \var{timedelta}
+   == \var{date1}}. (2)}
+
+  \lineii{\var{timedelta} = \var{date1} - \var{date2}}
+   {(3)}
+
+  \lineii{\var{date1} < \var{date2}}
+   {\var{date1} is considered less than \var{date2} when \var{date1}
+   precedes \var{date2} in time. (4)}
+
+\end{tableii}
+
+Notes:
+\begin{description}
+
+\item[(1)]
+ \var{date2} is moved forward in time if \code{\var{timedelta}.days
+    > 0}, or backward if \code{\var{timedelta}.days < 0}.  Afterward
+    \code{\var{date2} - \var{date1} == \var{timedelta}.days}.
+    \code{\var{timedelta}.seconds} and
+    \code{\var{timedelta}.microseconds} are ignored.
+    \exception{OverflowError} is raised if \code{\var{date2}.year}
+    would be smaller than \constant{MINYEAR} or larger than
+    \constant{MAXYEAR}.
+
+\item[(2)]
+ This isn't quite equivalent to date1 +
+   (-timedelta), because -timedelta in isolation can overflow in cases
+   where date1 - timedelta does not.  \code{\var{timedelta}.seconds}
+   and \code{\var{timedelta}.microseconds} are ignored.
+
+\item[(3)]
+This is exact, and cannot overflow.  timedelta.seconds and
+    timedelta.microseconds are 0, and date2 + timedelta == date1
+    after.
+
+\item[(4)]
+In other words, \code{date1 < date2}
+   if and only if \code{\var{date1}.toordinal() <
+   \var{date2}.toordinal()}.
+In order to stop comparison from falling back to the default
+scheme of comparing object addresses, date comparison
+normally raises \exception{TypeError} if the other comparand
+isn't also a \class{date} object.  However, \code{NotImplemented}
+is returned instead if the other comparand has a
+\method{timetuple} attribute.  This hook gives other kinds of
+date objects a chance at implementing mixed-type comparison.
+If not, when a \class{date} object is
+compared to an object of a different type, \exception{TypeError} is
+raised unless the comparison is \code{==} or \code{!=}.  The latter
+cases return \constant{False} or \constant{True}, respectively.
+
+\end{description}
+
+
+Dates can be used as dictionary keys. In Boolean contexts, all
+\class{date} objects are considered to be true.
+
+Instance methods:
+
+\begin{methoddesc}{replace}{year, month, day}
+  Return a date with the same value, except for those members given
+  new values by whichever keyword arguments are specified.  For
+  example, if \code{d == date(2002, 12, 31)}, then
+  \code{d.replace(day=26) == date(2002, 12, 26)}.
+\end{methoddesc}
+
+\begin{methoddesc}{timetuple}{}
+  Return a \class{time.struct_time} such as returned by
+  \function{time.localtime()}.  The hours, minutes and seconds are
+  0, and the DST flag is -1.
+  \code{\var{d}.timetuple()} is equivalent to
+      \code{time.struct_time((\var{d}.year, \var{d}.month, \var{d}.day,
+             0, 0, 0,
+             \var{d}.weekday(),
+             \var{d}.toordinal() - date(\var{d}.year, 1, 1).toordinal() + 1,
+            -1))}
+\end{methoddesc}
+
+\begin{methoddesc}{toordinal}{}
+  Return the proleptic Gregorian ordinal of the date, where January 1
+  of year 1 has ordinal 1.  For any \class{date} object \var{d},
+  \code{date.fromordinal(\var{d}.toordinal()) == \var{d}}.
+\end{methoddesc}
+
+\begin{methoddesc}{weekday}{}
+  Return the day of the week as an integer, where Monday is 0 and
+  Sunday is 6.  For example, \code{date(2002, 12, 4).weekday() == 2}, a
+  Wednesday.
+  See also \method{isoweekday()}.
+\end{methoddesc}
+
+\begin{methoddesc}{isoweekday}{}
+  Return the day of the week as an integer, where Monday is 1 and
+  Sunday is 7.  For example, \code{date(2002, 12, 4).isoweekday() == 3}, a
+  Wednesday.
+  See also \method{weekday()}, \method{isocalendar()}.
+\end{methoddesc}
+
+\begin{methoddesc}{isocalendar}{}
+  Return a 3-tuple, (ISO year, ISO week number, ISO weekday).
+
+  The ISO calendar is a widely used variant of the Gregorian calendar.
+  See \url{http://www.phys.uu.nl/~vgent/calendar/isocalendar.htm}
+  for a good explanation.
+
+  The ISO year consists of 52 or 53 full weeks, and where a week starts
+  on a Monday and ends on a Sunday.  The first week of an ISO year is
+  the first (Gregorian) calendar week of a year containing a Thursday.
+  This is called week number 1, and the ISO year of that Thursday is
+  the same as its Gregorian year.
+
+  For example, 2004 begins on a Thursday, so the first week of ISO
+  year 2004 begins on Monday, 29 Dec 2003 and ends on Sunday, 4 Jan
+  2004, so that
+  \code{date(2003, 12, 29).isocalendar() == (2004, 1, 1)}
+  and
+  \code{date(2004, 1, 4).isocalendar() == (2004, 1, 7)}.
+\end{methoddesc}
+
+\begin{methoddesc}{isoformat}{}
+  Return a string representing the date in ISO 8601 format,
+  'YYYY-MM-DD'.  For example,
+  \code{date(2002, 12, 4).isoformat() == '2002-12-04'}.
+\end{methoddesc}
+
+\begin{methoddesc}{__str__}{}
+  For a date \var{d}, \code{str(\var{d})} is equivalent to
+  \code{\var{d}.isoformat()}.
+\end{methoddesc}
+
+\begin{methoddesc}{ctime}{}
+  Return a string representing the date, for example
+  date(2002, 12, 4).ctime() == 'Wed Dec  4 00:00:00 2002'.
+  \code{\var{d}.ctime()} is equivalent to
+  \code{time.ctime(time.mktime(\var{d}.timetuple()))}
+  on platforms where the native C \cfunction{ctime()} function
+  (which \function{time.ctime()} invokes, but which
+  \method{date.ctime()} does not invoke) conforms to the C standard.
+\end{methoddesc}
+
+\begin{methoddesc}{strftime}{format}
+  Return a string representing the date, controlled by an explicit
+  format string.  Format codes referring to hours, minutes or seconds
+  will see 0 values.
+  See section~\ref{strftime-behavior} -- \method{strftime()} behavior.
+\end{methoddesc}
+
+
+\subsection{\class{datetime} Objects \label{datetime-datetime}}
+
+A \class{datetime} object is a single object containing all the
+information from a \class{date} object and a \class{time} object.  Like a
+\class{date} object, \class{datetime} assumes the current Gregorian
+calendar extended in both directions; like a time object,
+\class{datetime} assumes there are exactly 3600*24 seconds in every
+day.
+
+Constructor:
+
+\begin{classdesc}{datetime}{year, month, day\optional{,
+                            hour\optional{, minute\optional{,
+                            second\optional{, microsecond\optional{,
+                            tzinfo}}}}}}
+  The year, month and day arguments are required.  \var{tzinfo} may
+  be \code{None}, or an instance of a \class{tzinfo} subclass.  The
+  remaining arguments may be ints or longs, in the following ranges:
+
+  \begin{itemize}
+    \item \code{MINYEAR <= \var{year} <= MAXYEAR}
+    \item \code{1 <= \var{month} <= 12}
+    \item \code{1 <= \var{day} <= number of days in the given month and year}
+    \item \code{0 <= \var{hour} < 24}
+    \item \code{0 <= \var{minute} < 60}
+    \item \code{0 <= \var{second} < 60}
+    \item \code{0 <= \var{microsecond} < 1000000}
+  \end{itemize}
+
+  If an argument outside those ranges is given,
+  \exception{ValueError} is raised.
+\end{classdesc}
+
+Other constructors, all class methods:
+
+\begin{methoddesc}{today}{}
+  Return the current local datetime, with \member{tzinfo} \code{None}.
+  This is equivalent to
+  \code{datetime.fromtimestamp(time.time())}.
+  See also \method{now()}, \method{fromtimestamp()}.
+\end{methoddesc}
+
+\begin{methoddesc}{now}{\optional{tz}}
+  Return the current local date and time.  If optional argument
+  \var{tz} is \code{None} or not specified, this is like
+  \method{today()}, but, if possible, supplies more precision than can
+  be gotten from going through a \function{time.time()} timestamp (for
+  example, this may be possible on platforms supplying the C
+  \cfunction{gettimeofday()} function).
+
+  Else \var{tz} must be an instance of a class \class{tzinfo} subclass,
+  and the current date and time are converted to \var{tz}'s time
+  zone.  In this case the result is equivalent to
+  \code{\var{tz}.fromutc(datetime.utcnow().replace(tzinfo=\var{tz}))}.
+  See also \method{today()}, \method{utcnow()}.
+\end{methoddesc}
+
+\begin{methoddesc}{utcnow}{}
+  Return the current UTC date and time, with \member{tzinfo} \code{None}.
+  This is like \method{now()}, but returns the current UTC date and time,
+  as a naive \class{datetime} object.
+  See also \method{now()}.
+\end{methoddesc}
+
+\begin{methoddesc}{fromtimestamp}{timestamp\optional{, tz}}
+  Return the local date and time corresponding to the \POSIX{}
+  timestamp, such as is returned by \function{time.time()}.
+  If optional argument \var{tz} is \code{None} or not specified, the
+  timestamp is converted to the platform's local date and time, and
+  the returned \class{datetime} object is naive.
+
+  Else \var{tz} must be an instance of a class \class{tzinfo} subclass,
+  and the timestamp is converted to \var{tz}'s time zone.  In this case
+  the result is equivalent to
+  \code{\var{tz}.fromutc(datetime.utcfromtimestamp(\var{timestamp}).replace(tzinfo=\var{tz}))}.
+
+  \method{fromtimestamp()} may raise \exception{ValueError}, if the
+  timestamp is out of the range of values supported by the platform C
+  \cfunction{localtime()} or \cfunction{gmtime()} functions.  It's common
+  for this to be restricted to years in 1970 through 2038.
+  Note that on non-POSIX systems that include leap seconds in their
+  notion of a timestamp, leap seconds are ignored by
+  \method{fromtimestamp()}, and then it's possible to have two timestamps
+  differing by a second that yield identical \class{datetime} objects.
+  See also \method{utcfromtimestamp()}.
+\end{methoddesc}
+
+\begin{methoddesc}{utcfromtimestamp}{timestamp}
+  Return the UTC \class{datetime} corresponding to the \POSIX{}
+  timestamp, with \member{tzinfo} \code{None}.
+  This may raise \exception{ValueError}, if the
+  timestamp is out of the range of values supported by the platform
+  C \cfunction{gmtime()} function.  It's common for this to be
+  restricted to years in 1970 through 2038.
+  See also \method{fromtimestamp()}.
+\end{methoddesc}
+
+\begin{methoddesc}{fromordinal}{ordinal}
+  Return the \class{datetime} corresponding to the proleptic
+  Gregorian ordinal, where January 1 of year 1 has ordinal 1.
+  \exception{ValueError} is raised unless \code{1 <= ordinal <=
+  datetime.max.toordinal()}.  The hour, minute, second and
+  microsecond of the result are all 0,
+  and \member{tzinfo} is \code{None}.
+\end{methoddesc}
+
+\begin{methoddesc}{combine}{date, time}
+  Return a new \class{datetime} object whose date members are
+  equal to the given \class{date} object's, and whose time
+  and \member{tzinfo} members are equal to the given \class{time} object's.
+  For any \class{datetime} object \var{d}, \code{\var{d} ==
+  datetime.combine(\var{d}.date(), \var{d}.timetz())}.  If date is a
+  \class{datetime} object, its time and \member{tzinfo} members are
+  ignored.
+  \end{methoddesc}
+
+\begin{methoddesc}{strptime}{date_string, format}
+  Return a \class{datetime} corresponding to \var{date_string}, parsed
+  according to \var{format}.  This is equivalent to
+  \code{datetime(*(time.strptime(date_string,
+  format)[0:6]))}. \exception{ValueError} is raised if the date_string and
+  format can't be parsed by \function{time.strptime()} or if it returns a
+  value which isn't a time tuple.
+
+  \versionadded{2.5}
+\end{methoddesc}
+
+Class attributes:
+
+\begin{memberdesc}{min}
+  The earliest representable \class{datetime},
+  \code{datetime(MINYEAR, 1, 1, tzinfo=None)}.
+\end{memberdesc}
+
+\begin{memberdesc}{max}
+  The latest representable \class{datetime},
+  \code{datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, tzinfo=None)}.
+\end{memberdesc}
+
+\begin{memberdesc}{resolution}
+  The smallest possible difference between non-equal \class{datetime}
+  objects, \code{timedelta(microseconds=1)}.
+\end{memberdesc}
+
+Instance attributes (read-only):
+
+\begin{memberdesc}{year}
+  Between \constant{MINYEAR} and \constant{MAXYEAR} inclusive.
+\end{memberdesc}
+
+\begin{memberdesc}{month}
+  Between 1 and 12 inclusive.
+\end{memberdesc}
+
+\begin{memberdesc}{day}
+  Between 1 and the number of days in the given month of the given
+  year.
+\end{memberdesc}
+
+\begin{memberdesc}{hour}
+  In \code{range(24)}.
+\end{memberdesc}
+
+\begin{memberdesc}{minute}
+  In \code{range(60)}.
+\end{memberdesc}
+
+\begin{memberdesc}{second}
+  In \code{range(60)}.
+\end{memberdesc}
+
+\begin{memberdesc}{microsecond}
+  In \code{range(1000000)}.
+\end{memberdesc}
+
+\begin{memberdesc}{tzinfo}
+  The object passed as the \var{tzinfo} argument to the
+  \class{datetime} constructor, or \code{None} if none was passed.
+\end{memberdesc}
+
+Supported operations:
+
+\begin{tableii}{c|l}{code}{Operation}{Result}
+  \lineii{\var{datetime2} = \var{datetime1} + \var{timedelta}}{(1)}
+
+  \lineii{\var{datetime2} = \var{datetime1} - \var{timedelta}}{(2)}
+
+  \lineii{\var{timedelta} = \var{datetime1} - \var{datetime2}}{(3)}
+
+  \lineii{\var{datetime1} < \var{datetime2}}
+   {Compares \class{datetime} to \class{datetime}.
+    (4)}
+
+\end{tableii}
+
+\begin{description}
+
+\item[(1)]
+
+    datetime2 is a duration of timedelta removed from datetime1, moving
+    forward in time if \code{\var{timedelta}.days} > 0, or backward if
+    \code{\var{timedelta}.days} < 0.  The result has the same \member{tzinfo} member
+    as the input datetime, and datetime2 - datetime1 == timedelta after.
+    \exception{OverflowError} is raised if datetime2.year would be
+    smaller than \constant{MINYEAR} or larger than \constant{MAXYEAR}.
+    Note that no time zone adjustments are done even if the input is an
+    aware object.
+
+\item[(2)]
+    Computes the datetime2 such that datetime2 + timedelta == datetime1.
+    As for addition, the result has the same \member{tzinfo} member
+    as the input datetime, and no time zone adjustments are done even
+    if the input is aware.
+    This isn't quite equivalent to datetime1 + (-timedelta), because
+    -timedelta in isolation can overflow in cases where
+    datetime1 - timedelta does not.
+
+\item[(3)]
+    Subtraction of a \class{datetime} from a
+    \class{datetime} is defined only if both
+    operands are naive, or if both are aware.  If one is aware and the
+    other is naive, \exception{TypeError} is raised.
+
+    If both are naive, or both are aware and have the same \member{tzinfo}
+    member, the \member{tzinfo} members are ignored, and the result is
+    a \class{timedelta} object \var{t} such that
+    \code{\var{datetime2} + \var{t} == \var{datetime1}}.  No time zone
+    adjustments are done in this case.
+
+    If both are aware and have different \member{tzinfo} members,
+    \code{a-b} acts as if \var{a} and \var{b} were first converted to
+    naive UTC datetimes first.  The result is
+    \code{(\var{a}.replace(tzinfo=None) - \var{a}.utcoffset()) -
+          (\var{b}.replace(tzinfo=None) - \var{b}.utcoffset())}
+    except that the implementation never overflows.
+
+\item[(4)]
+
+\var{datetime1} is considered less than \var{datetime2}
+when \var{datetime1} precedes \var{datetime2} in time.
+
+If one comparand is naive and
+the other is aware, \exception{TypeError} is raised.  If both
+    comparands are aware, and have the same \member{tzinfo} member,
+    the common \member{tzinfo} member is ignored and the base datetimes
+    are compared.  If both comparands are aware and have different
+    \member{tzinfo} members, the comparands are first adjusted by
+    subtracting their UTC offsets (obtained from \code{self.utcoffset()}).
+    \note{In order to stop comparison from falling back to the default
+          scheme of comparing object addresses, datetime comparison
+          normally raises \exception{TypeError} if the other comparand
+          isn't also a \class{datetime} object.  However,
+          \code{NotImplemented} is returned instead if the other comparand
+          has a \method{timetuple} attribute.  This hook gives other
+          kinds of date objects a chance at implementing mixed-type
+          comparison.  If not, when a \class{datetime} object is
+          compared to an object of a different type, \exception{TypeError}
+          is raised unless the comparison is \code{==} or \code{!=}.  The
+          latter cases return \constant{False} or \constant{True},
+          respectively.}
+
+\end{description}
+
+\class{datetime} objects can be used as dictionary keys. In Boolean
+contexts, all \class{datetime} objects are considered to be true.
+
+
+Instance methods:
+
+\begin{methoddesc}{date}{}
+  Return \class{date} object with same year, month and day.
+\end{methoddesc}
+
+\begin{methoddesc}{time}{}
+  Return \class{time} object with same hour, minute, second and microsecond.
+  \member{tzinfo} is \code{None}.  See also method \method{timetz()}.
+\end{methoddesc}
+
+\begin{methoddesc}{timetz}{}
+  Return \class{time} object with same hour, minute, second, microsecond,
+  and tzinfo members.  See also method \method{time()}.
+\end{methoddesc}
+
+\begin{methoddesc}{replace}{\optional{year\optional{, month\optional{,
+                            day\optional{, hour\optional{, minute\optional{,
+                            second\optional{, microsecond\optional{,
+                            tzinfo}}}}}}}}}
+  Return a datetime with the same members, except for those members given
+  new values by whichever keyword arguments are specified.  Note that
+  \code{tzinfo=None} can be specified to create a naive datetime from
+  an aware datetime with no conversion of date and time members.
+\end{methoddesc}
+
+\begin{methoddesc}{astimezone}{tz}
+  Return a \class{datetime} object with new \member{tzinfo} member
+  \var{tz}, adjusting the date and time members so the result is the
+  same UTC time as \var{self}, but in \var{tz}'s local time.
+
+  \var{tz} must be an instance of a \class{tzinfo} subclass, and its
+  \method{utcoffset()} and \method{dst()} methods must not return
+  \code{None}.  \var{self} must be aware (\code{\var{self}.tzinfo} must
+  not be \code{None}, and \code{\var{self}.utcoffset()} must not return
+  \code{None}).
+
+  If \code{\var{self}.tzinfo} is \var{tz},
+  \code{\var{self}.astimezone(\var{tz})} is equal to \var{self}:  no
+  adjustment of date or time members is performed.
+  Else the result is local time in time zone \var{tz}, representing the
+  same UTC time as \var{self}:  after \code{\var{astz} =
+  \var{dt}.astimezone(\var{tz})},
+  \code{\var{astz} - \var{astz}.utcoffset()} will usually have the same
+  date and time members as \code{\var{dt} - \var{dt}.utcoffset()}.
+  The discussion of class \class{tzinfo} explains the cases at Daylight
+  Saving Time transition boundaries where this cannot be achieved (an issue
+  only if \var{tz} models both standard and daylight time).
+
+  If you merely want to attach a time zone object \var{tz} to a
+  datetime \var{dt} without adjustment of date and time members,
+  use \code{\var{dt}.replace(tzinfo=\var{tz})}.  If
+  you merely want to remove the time zone object from an aware datetime
+  \var{dt} without conversion of date and time members, use
+  \code{\var{dt}.replace(tzinfo=None)}.
+
+  Note that the default \method{tzinfo.fromutc()} method can be overridden
+  in a \class{tzinfo} subclass to affect the result returned by
+  \method{astimezone()}.  Ignoring error cases, \method{astimezone()}
+  acts like:
+
+  \begin{verbatim}
+  def astimezone(self, tz):
+      if self.tzinfo is tz:
+          return self
+      # Convert self to UTC, and attach the new time zone object.
+      utc = (self - self.utcoffset()).replace(tzinfo=tz)
+      # Convert from UTC to tz's local time.
+      return tz.fromutc(utc)
+  \end{verbatim}
+\end{methoddesc}
+
+\begin{methoddesc}{utcoffset}{}
+  If \member{tzinfo} is \code{None}, returns \code{None}, else
+  returns \code{\var{self}.tzinfo.utcoffset(\var{self})}, and
+  raises an exception if the latter doesn't return \code{None}, or
+  a \class{timedelta} object representing a whole number of minutes
+  with magnitude less than one day.
+\end{methoddesc}
+
+\begin{methoddesc}{dst}{}
+  If \member{tzinfo} is \code{None}, returns \code{None}, else
+  returns \code{\var{self}.tzinfo.dst(\var{self})}, and
+  raises an exception if the latter doesn't return \code{None}, or
+  a \class{timedelta} object representing a whole number of minutes
+  with magnitude less than one day.
+\end{methoddesc}
+
+\begin{methoddesc}{tzname}{}
+  If \member{tzinfo} is \code{None}, returns \code{None}, else
+  returns \code{\var{self}.tzinfo.tzname(\var{self})},
+  raises an exception if the latter doesn't return \code{None} or
+  a string object,
+\end{methoddesc}
+
+\begin{methoddesc}{timetuple}{}
+  Return a \class{time.struct_time} such as returned by
+  \function{time.localtime()}.
+  \code{\var{d}.timetuple()} is equivalent to
+  \code{time.struct_time((\var{d}.year, \var{d}.month, \var{d}.day,
+         \var{d}.hour, \var{d}.minute, \var{d}.second,
+         \var{d}.weekday(),
+         \var{d}.toordinal() - date(\var{d}.year, 1, 1).toordinal() + 1,
+         dst))}
+  The \member{tm_isdst} flag of the result is set according to
+  the \method{dst()} method:  \member{tzinfo} is \code{None} or
+  \method{dst()} returns \code{None},
+  \member{tm_isdst} is set to  \code{-1}; else if \method{dst()} returns
+  a non-zero value, \member{tm_isdst} is set to \code{1};
+  else \code{tm_isdst} is set to \code{0}.
+\end{methoddesc}
+
+\begin{methoddesc}{utctimetuple}{}
+  If \class{datetime} instance \var{d} is naive, this is the same as
+  \code{\var{d}.timetuple()} except that \member{tm_isdst} is forced to 0
+  regardless of what \code{d.dst()} returns.  DST is never in effect
+  for a UTC time.
+
+  If \var{d} is aware, \var{d} is normalized to UTC time, by subtracting
+  \code{\var{d}.utcoffset()}, and a \class{time.struct_time} for the
+  normalized time is returned.  \member{tm_isdst} is forced to 0.
+  Note that the result's \member{tm_year} member may be
+  \constant{MINYEAR}-1 or \constant{MAXYEAR}+1, if \var{d}.year was
+  \code{MINYEAR} or \code{MAXYEAR} and UTC adjustment spills over a
+  year boundary.
+\end{methoddesc}
+
+\begin{methoddesc}{toordinal}{}
+  Return the proleptic Gregorian ordinal of the date.  The same as
+  \code{self.date().toordinal()}.
+\end{methoddesc}
+
+\begin{methoddesc}{weekday}{}
+  Return the day of the week as an integer, where Monday is 0 and
+  Sunday is 6.  The same as \code{self.date().weekday()}.
+  See also \method{isoweekday()}.
+\end{methoddesc}
+
+\begin{methoddesc}{isoweekday}{}
+  Return the day of the week as an integer, where Monday is 1 and
+  Sunday is 7.  The same as \code{self.date().isoweekday()}.
+  See also \method{weekday()}, \method{isocalendar()}.
+\end{methoddesc}
+
+\begin{methoddesc}{isocalendar}{}
+  Return a 3-tuple, (ISO year, ISO week number, ISO weekday).  The
+  same as \code{self.date().isocalendar()}.
+\end{methoddesc}
+
+\begin{methoddesc}{isoformat}{\optional{sep}}
+  Return a string representing the date and time in ISO 8601 format,
+      YYYY-MM-DDTHH:MM:SS.mmmmmm
+  or, if \member{microsecond} is 0,
+      YYYY-MM-DDTHH:MM:SS
+
+  If \method{utcoffset()} does not return \code{None}, a 6-character
+  string is appended, giving the UTC offset in (signed) hours and
+  minutes:
+      YYYY-MM-DDTHH:MM:SS.mmmmmm+HH:MM
+  or, if \member{microsecond} is 0
+      YYYY-MM-DDTHH:MM:SS+HH:MM
+
+  The optional argument \var{sep} (default \code{'T'}) is a
+  one-character separator, placed between the date and time portions
+  of the result.  For example,
+
+\begin{verbatim}
+>>> from datetime import tzinfo, timedelta, datetime
+>>> class TZ(tzinfo):
+...     def utcoffset(self, dt): return timedelta(minutes=-399)
+...
+>>> datetime(2002, 12, 25, tzinfo=TZ()).isoformat(' ')
+'2002-12-25 00:00:00-06:39'
+\end{verbatim}
+\end{methoddesc}
+
+\begin{methoddesc}{__str__}{}
+  For a \class{datetime} instance \var{d}, \code{str(\var{d})} is
+  equivalent to \code{\var{d}.isoformat(' ')}.
+\end{methoddesc}
+
+\begin{methoddesc}{ctime}{}
+  Return a string representing the date and time, for example
+  \code{datetime(2002, 12, 4, 20, 30, 40).ctime() ==
+   'Wed Dec  4 20:30:40 2002'}.
+  \code{d.ctime()} is equivalent to
+  \code{time.ctime(time.mktime(d.timetuple()))} on platforms where
+  the native C \cfunction{ctime()} function (which
+  \function{time.ctime()} invokes, but which
+  \method{datetime.ctime()} does not invoke) conforms to the C
+  standard.
+\end{methoddesc}
+
+\begin{methoddesc}{strftime}{format}
+  Return a string representing the date and time, controlled by an
+  explicit format string.  See section~\ref{strftime-behavior} --
+  \method{strftime()} behavior.
+\end{methoddesc}
+
+
+\subsection{\class{time} Objects \label{datetime-time}}
+
+A time object represents a (local) time of day, independent of any
+particular day, and subject to adjustment via a \class{tzinfo} object.
+
+\begin{classdesc}{time}{hour\optional{, minute\optional{, second\optional{,
+                        microsecond\optional{, tzinfo}}}}}
+  All arguments are optional.  \var{tzinfo} may be \code{None}, or
+  an instance of a \class{tzinfo} subclass.  The remaining arguments
+  may be ints or longs, in the following ranges:
+
+  \begin{itemize}
+    \item \code{0 <= \var{hour} < 24}
+    \item \code{0 <= \var{minute} < 60}
+    \item \code{0 <= \var{second} < 60}
+    \item \code{0 <= \var{microsecond} < 1000000}.
+  \end{itemize}
+
+  If an argument outside those ranges is given,
+  \exception{ValueError} is raised.  All default to \code{0} except
+  \var{tzinfo}, which defaults to \constant{None}.
+\end{classdesc}
+
+Class attributes:
+
+\begin{memberdesc}{min}
+  The earliest representable \class{time}, \code{time(0, 0, 0, 0)}.
+\end{memberdesc}
+
+\begin{memberdesc}{max}
+  The latest representable \class{time}, \code{time(23, 59, 59, 999999)}.
+\end{memberdesc}
+
+\begin{memberdesc}{resolution}
+  The smallest possible difference between non-equal \class{time}
+  objects, \code{timedelta(microseconds=1)}, although note that
+  arithmetic on \class{time} objects is not supported.
+\end{memberdesc}
+
+Instance attributes (read-only):
+
+\begin{memberdesc}{hour}
+  In \code{range(24)}.
+\end{memberdesc}
+
+\begin{memberdesc}{minute}
+  In \code{range(60)}.
+\end{memberdesc}
+
+\begin{memberdesc}{second}
+  In \code{range(60)}.
+\end{memberdesc}
+
+\begin{memberdesc}{microsecond}
+  In \code{range(1000000)}.
+\end{memberdesc}
+
+\begin{memberdesc}{tzinfo}
+  The object passed as the tzinfo argument to the \class{time}
+  constructor, or \code{None} if none was passed.
+\end{memberdesc}
+
+Supported operations:
+
+\begin{itemize}
+  \item
+    comparison of \class{time} to \class{time},
+    where \var{a} is considered less than \var{b} when \var{a} precedes
+    \var{b} in time.  If one comparand is naive and the other is aware,
+    \exception{TypeError} is raised.  If both comparands are aware, and
+    have the same \member{tzinfo} member, the common \member{tzinfo}
+    member is ignored and the base times are compared.  If both
+    comparands are aware and have different \member{tzinfo} members,
+    the comparands are first adjusted by subtracting their UTC offsets
+    (obtained from \code{self.utcoffset()}).
+    In order to stop mixed-type comparisons from falling back to the
+    default comparison by object address, when a \class{time} object is
+    compared to an object of a different type, \exception{TypeError} is
+    raised unless the comparison is \code{==} or \code{!=}.  The latter
+    cases return \constant{False} or \constant{True}, respectively.
+
+  \item
+    hash, use as dict key
+
+  \item
+    efficient pickling
+
+  \item
+    in Boolean contexts, a \class{time} object is considered to be
+    true if and only if, after converting it to minutes and
+    subtracting \method{utcoffset()} (or \code{0} if that's
+    \code{None}), the result is non-zero.
+\end{itemize}
+
+Instance methods:
+
+\begin{methoddesc}{replace}{\optional{hour\optional{, minute\optional{,
+                            second\optional{, microsecond\optional{,
+                            tzinfo}}}}}}
+  Return a \class{time} with the same value, except for those members given
+  new values by whichever keyword arguments are specified.  Note that
+  \code{tzinfo=None} can be specified to create a naive \class{time} from
+  an aware \class{time}, without conversion of the time members.
+\end{methoddesc}
+
+\begin{methoddesc}{isoformat}{}
+  Return a string representing the time in ISO 8601 format,
+      HH:MM:SS.mmmmmm
+  or, if self.microsecond is 0,
+      HH:MM:SS
+  If \method{utcoffset()} does not return \code{None}, a 6-character
+  string is appended, giving the UTC offset in (signed) hours and
+  minutes:
+      HH:MM:SS.mmmmmm+HH:MM
+  or, if self.microsecond is 0,
+      HH:MM:SS+HH:MM
+\end{methoddesc}
+
+\begin{methoddesc}{__str__}{}
+  For a time \var{t}, \code{str(\var{t})} is equivalent to
+  \code{\var{t}.isoformat()}.
+\end{methoddesc}
+
+\begin{methoddesc}{strftime}{format}
+  Return a string representing the time, controlled by an explicit
+  format string.  See section~\ref{strftime-behavior} --
+  \method{strftime()} behavior.
+\end{methoddesc}
+
+\begin{methoddesc}{utcoffset}{}
+  If \member{tzinfo} is \code{None}, returns \code{None}, else
+  returns \code{\var{self}.tzinfo.utcoffset(None)}, and
+  raises an exception if the latter doesn't return \code{None} or
+  a \class{timedelta} object representing a whole number of minutes
+  with magnitude less than one day.
+\end{methoddesc}
+
+\begin{methoddesc}{dst}{}
+  If \member{tzinfo} is \code{None}, returns \code{None}, else
+  returns \code{\var{self}.tzinfo.dst(None)}, and
+  raises an exception if the latter doesn't return \code{None}, or
+  a \class{timedelta} object representing a whole number of minutes
+  with magnitude less than one day.
+\end{methoddesc}
+
+\begin{methoddesc}{tzname}{}
+  If \member{tzinfo} is \code{None}, returns \code{None}, else
+  returns \code{\var{self}.tzinfo.tzname(None)}, or
+  raises an exception if the latter doesn't return \code{None} or
+  a string object.
+\end{methoddesc}
+
+
+\subsection{\class{tzinfo} Objects \label{datetime-tzinfo}}
+
+\class{tzinfo} is an abstract base clase, meaning that this class
+should not be instantiated directly.  You need to derive a concrete
+subclass, and (at least) supply implementations of the standard
+\class{tzinfo} methods needed by the \class{datetime} methods you
+use.  The \module{datetime} module does not supply any concrete
+subclasses of \class{tzinfo}.
+
+An instance of (a concrete subclass of) \class{tzinfo} can be passed
+to the constructors for \class{datetime} and \class{time} objects.
+The latter objects view their members as being in local time, and the
+\class{tzinfo} object supports methods revealing offset of local time
+from UTC, the name of the time zone, and DST offset, all relative to a
+date or time object passed to them.
+
+Special requirement for pickling:  A \class{tzinfo} subclass must have an
+\method{__init__} method that can be called with no arguments, else it
+can be pickled but possibly not unpickled again.  This is a technical
+requirement that may be relaxed in the future.
+
+A concrete subclass of \class{tzinfo} may need to implement the
+following methods.  Exactly which methods are needed depends on the
+uses made of aware \module{datetime} objects.  If in doubt, simply
+implement all of them.
+
+\begin{methoddesc}{utcoffset}{self, dt}
+  Return offset of local time from UTC, in minutes east of UTC.  If
+  local time is west of UTC, this should be negative.  Note that this
+  is intended to be the total offset from UTC; for example, if a
+  \class{tzinfo} object represents both time zone and DST adjustments,
+  \method{utcoffset()} should return their sum.  If the UTC offset
+  isn't known, return \code{None}.  Else the value returned must be
+  a \class{timedelta} object specifying a whole number of minutes in the
+  range -1439 to 1439 inclusive (1440 = 24*60; the magnitude of the offset
+  must be less than one day).  Most implementations of
+  \method{utcoffset()} will probably look like one of these two:
+
+\begin{verbatim}
+    return CONSTANT                 # fixed-offset class
+    return CONSTANT + self.dst(dt)  # daylight-aware class
+\end{verbatim}
+
+    If \method{utcoffset()} does not return \code{None},
+    \method{dst()} should not return \code{None} either.
+
+    The default implementation of \method{utcoffset()} raises
+    \exception{NotImplementedError}.
+\end{methoddesc}
+
+\begin{methoddesc}{dst}{self, dt}
+  Return the daylight saving time (DST) adjustment, in minutes east of
+  UTC, or \code{None} if DST information isn't known.  Return
+  \code{timedelta(0)} if DST is not in effect.
+  If DST is in effect, return the offset as a
+  \class{timedelta} object (see \method{utcoffset()} for details).
+  Note that DST offset, if applicable, has
+  already been added to the UTC offset returned by
+  \method{utcoffset()}, so there's no need to consult \method{dst()}
+  unless you're interested in obtaining DST info separately.  For
+  example, \method{datetime.timetuple()} calls its \member{tzinfo}
+  member's \method{dst()} method to determine how the
+  \member{tm_isdst} flag should be set, and
+  \method{tzinfo.fromutc()} calls \method{dst()} to account for
+  DST changes when crossing time zones.
+
+  An instance \var{tz} of a \class{tzinfo} subclass that models both
+  standard and daylight times must be consistent in this sense:
+
+      \code{\var{tz}.utcoffset(\var{dt}) - \var{tz}.dst(\var{dt})}
+
+  must return the same result for every \class{datetime} \var{dt}
+  with \code{\var{dt}.tzinfo == \var{tz}}  For sane \class{tzinfo}
+  subclasses, this expression yields the time zone's "standard offset",
+  which should not depend on the date or the time, but only on geographic
+  location.  The implementation of \method{datetime.astimezone()} relies
+  on this, but cannot detect violations; it's the programmer's
+  responsibility to ensure it.  If a \class{tzinfo} subclass cannot
+  guarantee this, it may be able to override the default implementation
+  of \method{tzinfo.fromutc()} to work correctly with \method{astimezone()}
+  regardless.
+
+  Most implementations of \method{dst()} will probably look like one
+  of these two:
+
+\begin{verbatim}
+    def dst(self):
+        # a fixed-offset class:  doesn't account for DST
+        return timedelta(0)
+\end{verbatim}
+
+  or
+
+\begin{verbatim}
+    def dst(self):
+        # Code to set dston and dstoff to the time zone's DST
+        # transition times based on the input dt.year, and expressed
+        # in standard local time.  Then
+
+        if dston <= dt.replace(tzinfo=None) < dstoff:
+            return timedelta(hours=1)
+        else:
+            return timedelta(0)
+\end{verbatim}
+
+  The default implementation of \method{dst()} raises
+  \exception{NotImplementedError}.
+\end{methoddesc}
+
+\begin{methoddesc}{tzname}{self, dt}
+  Return the time zone name corresponding to the \class{datetime}
+  object \var{dt}, as a string.
+  Nothing about string names is defined by the
+  \module{datetime} module, and there's no requirement that it mean
+  anything in particular.  For example, "GMT", "UTC", "-500", "-5:00",
+  "EDT", "US/Eastern", "America/New York" are all valid replies.  Return
+  \code{None} if a string name isn't known.  Note that this is a method
+  rather than a fixed string primarily because some \class{tzinfo}
+  subclasses will wish to return different names depending on the specific
+  value of \var{dt} passed, especially if the \class{tzinfo} class is
+  accounting for daylight time.
+
+  The default implementation of \method{tzname()} raises
+  \exception{NotImplementedError}.
+\end{methoddesc}
+
+These methods are called by a \class{datetime} or \class{time} object,
+in response to their methods of the same names.  A \class{datetime}
+object passes itself as the argument, and a \class{time} object passes
+\code{None} as the argument.  A \class{tzinfo} subclass's methods should
+therefore be prepared to accept a \var{dt} argument of \code{None}, or of
+class \class{datetime}.
+
+When \code{None} is passed, it's up to the class designer to decide the
+best response.  For example, returning \code{None} is appropriate if the
+class wishes to say that time objects don't participate in the
+\class{tzinfo} protocols.  It may be more useful for \code{utcoffset(None)}
+to return the standard UTC offset, as there is no other convention for
+discovering the standard offset.
+
+When a \class{datetime} object is passed in response to a
+\class{datetime} method, \code{dt.tzinfo} is the same object as
+\var{self}.  \class{tzinfo} methods can rely on this, unless
+user code calls \class{tzinfo} methods directly.  The intent is that
+the \class{tzinfo} methods interpret \var{dt} as being in local time,
+and not need worry about objects in other timezones.
+
+There is one more \class{tzinfo} method that a subclass may wish to
+override:
+
+\begin{methoddesc}{fromutc}{self, dt}
+  This is called from the default \class{datetime.astimezone()}
+  implementation.  When called from that, \code{\var{dt}.tzinfo} is
+  \var{self}, and \var{dt}'s date and time members are to be viewed as
+  expressing a UTC time.  The purpose of \method{fromutc()} is to
+  adjust the date and time members, returning an equivalent datetime in
+  \var{self}'s local time.
+
+  Most \class{tzinfo} subclasses should be able to inherit the default
+  \method{fromutc()} implementation without problems.  It's strong enough
+  to handle fixed-offset time zones, and time zones accounting for both
+  standard and daylight time, and the latter even if the DST transition
+  times differ in different years.  An example of a time zone the default
+  \method{fromutc()} implementation may not handle correctly in all cases
+  is one where the standard offset (from UTC) depends on the specific date
+  and time passed, which can happen for political reasons.
+  The default implementations of \method{astimezone()} and
+  \method{fromutc()} may not produce the result you want if the result is
+  one of the hours straddling the moment the standard offset changes.
+
+  Skipping code for error cases, the default \method{fromutc()}
+  implementation acts like:
+
+  \begin{verbatim}
+  def fromutc(self, dt):
+      # raise ValueError error if dt.tzinfo is not self
+      dtoff = dt.utcoffset()
+      dtdst = dt.dst()
+      # raise ValueError if dtoff is None or dtdst is None
+      delta = dtoff - dtdst  # this is self's standard offset
+      if delta:
+          dt += delta   # convert to standard local time
+          dtdst = dt.dst()
+          # raise ValueError if dtdst is None
+      if dtdst:
+          return dt + dtdst
+      else:
+          return dt
+  \end{verbatim}
+\end{methoddesc}
+
+Example \class{tzinfo} classes:
+
+\verbatiminput{tzinfo-examples.py}
+
+Note that there are unavoidable subtleties twice per year in a
+\class{tzinfo}
+subclass accounting for both standard and daylight time, at the DST
+transition points.  For concreteness, consider US Eastern (UTC -0500),
+where EDT begins the minute after 1:59 (EST) on the first Sunday in
+April, and ends the minute after 1:59 (EDT) on the last Sunday in October:
+
+\begin{verbatim}
+    UTC   3:MM  4:MM  5:MM  6:MM  7:MM  8:MM
+    EST  22:MM 23:MM  0:MM  1:MM  2:MM  3:MM
+    EDT  23:MM  0:MM  1:MM  2:MM  3:MM  4:MM
+
+  start  22:MM 23:MM  0:MM  1:MM  3:MM  4:MM
+
+    end  23:MM  0:MM  1:MM  1:MM  2:MM  3:MM
+\end{verbatim}
+
+When DST starts (the "start" line), the local wall clock leaps from 1:59
+to 3:00.  A wall time of the form 2:MM doesn't really make sense on that
+day, so \code{astimezone(Eastern)} won't deliver a result with
+\code{hour == 2} on the
+day DST begins.  In order for \method{astimezone()} to make this
+guarantee, the \method{rzinfo.dst()} method must consider times
+in the "missing hour" (2:MM for Eastern) to be in daylight time.
+
+When DST ends (the "end" line), there's a potentially worse problem:
+there's an hour that can't be spelled unambiguously in local wall time:
+the last hour of daylight time.  In Eastern, that's times of
+the form 5:MM UTC on the day daylight time ends.  The local wall clock
+leaps from 1:59 (daylight time) back to 1:00 (standard time) again.
+Local times of the form 1:MM are ambiguous.  \method{astimezone()} mimics
+the local clock's behavior by mapping two adjacent UTC hours into the
+same local hour then.  In the Eastern example, UTC times of the form
+5:MM and 6:MM both map to 1:MM when converted to Eastern.  In order for
+\method{astimezone()} to make this guarantee, the \method{tzinfo.dst()}
+method must consider times in the "repeated hour" to be in
+standard time.  This is easily arranged, as in the example, by expressing
+DST switch times in the time zone's standard local time.
+
+Applications that can't bear such ambiguities should avoid using hybrid
+\class{tzinfo} subclasses; there are no ambiguities when using UTC, or
+any other fixed-offset \class{tzinfo} subclass (such as a class
+representing only EST (fixed offset -5 hours), or only EDT (fixed offset
+-4 hours)).
+
+
+\subsection{\method{strftime()} Behavior\label{strftime-behavior}}
+
+\class{date}, \class{datetime}, and \class{time}
+objects all support a \code{strftime(\var{format})}
+method, to create a string representing the time under the control of
+an explicit format string.  Broadly speaking,
+\code{d.strftime(fmt)}
+acts like the \refmodule{time} module's
+\code{time.strftime(fmt, d.timetuple())}
+although not all objects support a \method{timetuple()} method.
+
+For \class{time} objects, the format codes for
+year, month, and day should not be used, as time objects have no such
+values.  If they're used anyway, \code{1900} is substituted for the
+year, and \code{0} for the month and day.
+
+For \class{date} objects, the format codes for hours, minutes, and
+seconds should not be used, as \class{date} objects have no such
+values.  If they're used anyway, \code{0} is substituted for them.
+
+For a naive object, the \code{\%z} and \code{\%Z} format codes are
+replaced by empty strings.
+
+For an aware object:
+
+\begin{itemize}
+  \item[\code{\%z}]
+    \method{utcoffset()} is transformed into a 5-character string of
+    the form +HHMM or -HHMM, where HH is a 2-digit string giving the
+    number of UTC offset hours, and MM is a 2-digit string giving the
+    number of UTC offset minutes.  For example, if
+    \method{utcoffset()} returns \code{timedelta(hours=-3, minutes=-30)},
+    \code{\%z} is replaced with the string \code{'-0330'}.
+
+  \item[\code{\%Z}]
+    If \method{tzname()} returns \code{None}, \code{\%Z} is replaced
+    by an empty string.  Otherwise \code{\%Z} is replaced by the returned
+    value, which must be a string.
+\end{itemize}
+
+The full set of format codes supported varies across platforms,
+because Python calls the platform C library's \function{strftime()}
+function, and platform variations are common.  The documentation for
+Python's \refmodule{time} module lists the format codes that the C
+standard (1989 version) requires, and those work on all platforms
+with a standard C implementation.  Note that the 1999 version of the
+C standard added additional format codes.
+
+The exact range of years for which \method{strftime()} works also
+varies across platforms.  Regardless of platform, years before 1900
+cannot be used.
+
+%%% This example is obsolete, since strptime is now supported by datetime.
+% 
+% \subsection{Examples}
+% 
+% \subsubsection{Creating Datetime Objects from Formatted Strings}
+% 
+% The \class{datetime} class does not directly support parsing formatted time
+% strings.  You can use \function{time.strptime} to do the parsing and create
+% a \class{datetime} object from the tuple it returns:
+% 
+% \begin{verbatim}
+% >>> s = "2005-12-06T12:13:14"
+% >>> from datetime import datetime
+% >>> from time import strptime
+% >>> datetime(*strptime(s, "%Y-%m-%dT%H:%M:%S")[0:6])
+% datetime.datetime(2005, 12, 6, 12, 13, 14)
+% \end{verbatim}
+% 

Added: vendor/Python/current/Doc/lib/libdbhash.tex
===================================================================
--- vendor/Python/current/Doc/lib/libdbhash.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libdbhash.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,88 @@
+\section{\module{dbhash} ---
+         DBM-style interface to the BSD database library}
+
+\declaremodule{standard}{dbhash}
+\modulesynopsis{DBM-style interface to the BSD database library.}
+\sectionauthor{Fred L. Drake, Jr.}{fdrake at acm.org}
+
+
+The \module{dbhash} module provides a function to open databases using
+the BSD \code{db} library.  This module mirrors the interface of the
+other Python database modules that provide access to DBM-style
+databases.  The \refmodule{bsddb}\refbimodindex{bsddb} module is required 
+to use \module{dbhash}.
+
+This module provides an exception and a function:
+
+
+\begin{excdesc}{error}
+  Exception raised on database errors other than
+  \exception{KeyError}.  It is a synonym for \exception{bsddb.error}.
+\end{excdesc}
+
+\begin{funcdesc}{open}{path\optional{, flag\optional{, mode}}}
+  Open a \code{db} database and return the database object.  The
+  \var{path} argument is the name of the database file.
+
+  The \var{flag} argument can be
+  \code{'r'} (the default), \code{'w'},
+  \code{'c'} (which creates the database if it doesn't exist), or
+  \code{'n'} (which always creates a new empty database).
+  For platforms on which the BSD \code{db} library supports locking,
+  an \character{l} can be appended to indicate that locking should be
+  used.
+
+  The optional \var{mode} parameter is used to indicate the \UNIX{}
+  permission bits that should be set if a new database must be
+  created; this will be masked by the current umask value for the
+  process.
+\end{funcdesc}
+
+
+\begin{seealso}
+  \seemodule{anydbm}{Generic interface to \code{dbm}-style databases.}
+  \seemodule{bsddb}{Lower-level interface to the BSD \code{db} library.}
+  \seemodule{whichdb}{Utility module used to determine the type of an
+                      existing database.}
+\end{seealso}
+
+
+\subsection{Database Objects \label{dbhash-objects}}
+
+The database objects returned by \function{open()} provide the methods 
+common to all the DBM-style databases and mapping objects.  The following
+methods are available in addition to the standard methods.
+
+\begin{methoddesc}[dbhash]{first}{}
+  It's possible to loop over every key/value pair in the database using
+  this method   and the \method{next()} method.  The traversal is ordered by
+  the databases internal hash values, and won't be sorted by the key
+  values.  This method returns the starting key.
+\end{methoddesc}
+
+\begin{methoddesc}[dbhash]{last}{}
+  Return the last key/value pair in a database traversal.  This may be used to
+  begin a reverse-order traversal; see \method{previous()}.
+\end{methoddesc}
+
+\begin{methoddesc}[dbhash]{next}{}
+  Returns the key next key/value pair in a database traversal.  The
+  following code prints every key in the database \code{db}, without
+  having to create a list in memory that contains them all:
+
+\begin{verbatim}
+print db.first()
+for i in xrange(1, len(db)):
+    print db.next()
+\end{verbatim}
+\end{methoddesc}
+
+\begin{methoddesc}[dbhash]{previous}{}
+  Returns the previous key/value pair in a forward-traversal of the database.
+  In conjunction with \method{last()}, this may be used to implement
+  a reverse-order traversal.
+\end{methoddesc}
+
+\begin{methoddesc}[dbhash]{sync}{}
+  This method forces any unwritten data to be written to the disk.
+\end{methoddesc}

Added: vendor/Python/current/Doc/lib/libdbm.tex
===================================================================
--- vendor/Python/current/Doc/lib/libdbm.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libdbm.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,61 @@
+\section{\module{dbm} ---
+         Simple ``database'' interface}
+
+\declaremodule{builtin}{dbm}
+  \platform{Unix}
+\modulesynopsis{The standard ``database'' interface, based on ndbm.}
+
+
+The \module{dbm} module provides an interface to the \UNIX{}
+(\code{n})\code{dbm} library.  Dbm objects behave like mappings
+(dictionaries), except that keys and values are always strings.
+Printing a dbm object doesn't print the keys and values, and the
+\method{items()} and \method{values()} methods are not supported.
+
+This module can be used with the ``classic'' ndbm interface, the BSD
+DB compatibility interface, or the GNU GDBM compatibility interface.
+On \UNIX, the \program{configure} script will attempt to locate the
+appropriate header file to simplify building this module.
+
+The module defines the following:
+
+\begin{excdesc}{error}
+Raised on dbm-specific errors, such as I/O errors.
+\exception{KeyError} is raised for general mapping errors like
+specifying an incorrect key.
+\end{excdesc}
+
+\begin{datadesc}{library}
+Name of the \code{ndbm} implementation library used.
+\end{datadesc}
+
+\begin{funcdesc}{open}{filename\optional{, flag\optional{, mode}}}
+Open a dbm database and return a dbm object.  The \var{filename}
+argument is the name of the database file (without the \file{.dir} or
+\file{.pag} extensions; note that the BSD DB implementation of the
+interface will append the extension \file{.db} and only create one
+file).
+
+The optional \var{flag} argument must be one of these values:
+
+\begin{tableii}{c|l}{code}{Value}{Meaning}
+  \lineii{'r'}{Open existing database for reading only (default)}
+  \lineii{'w'}{Open existing database for reading and writing}
+  \lineii{'c'}{Open database for reading and writing, creating it if
+               it doesn't exist}
+  \lineii{'n'}{Always create a new, empty database, open for reading
+               and writing}
+\end{tableii}
+
+The optional \var{mode} argument is the \UNIX{} mode of the file, used
+only when the database has to be created.  It defaults to octal
+\code{0666}.
+\end{funcdesc}
+
+
+\begin{seealso}
+  \seemodule{anydbm}{Generic interface to \code{dbm}-style databases.}
+  \seemodule{gdbm}{Similar interface to the GNU GDBM library.}
+  \seemodule{whichdb}{Utility module used to determine the type of an
+                      existing database.}
+\end{seealso}

Added: vendor/Python/current/Doc/lib/libdecimal.tex
===================================================================
--- vendor/Python/current/Doc/lib/libdecimal.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libdecimal.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1313 @@
+\section{\module{decimal} ---
+         Decimal floating point arithmetic}
+
+\declaremodule{standard}{decimal}
+\modulesynopsis{Implementation of the General Decimal Arithmetic 
+Specification.}
+
+\moduleauthor{Eric Price}{eprice at tjhsst.edu}
+\moduleauthor{Facundo Batista}{facundo at taniquetil.com.ar}
+\moduleauthor{Raymond Hettinger}{python at rcn.com}
+\moduleauthor{Aahz}{aahz at pobox.com}
+\moduleauthor{Tim Peters}{tim.one at comcast.net}
+
+\sectionauthor{Raymond D. Hettinger}{python at rcn.com}
+
+\versionadded{2.4}
+
+The \module{decimal} module provides support for decimal floating point
+arithmetic.  It offers several advantages over the \class{float()} datatype:
+
+\begin{itemize}
+
+\item Decimal numbers can be represented exactly.  In contrast, numbers like
+\constant{1.1} do not have an exact representation in binary floating point.
+End users typically would not expect \constant{1.1} to display as
+\constant{1.1000000000000001} as it does with binary floating point.
+
+\item The exactness carries over into arithmetic.  In decimal floating point,
+\samp{0.1 + 0.1 + 0.1 - 0.3} is exactly equal to zero.  In binary floating
+point, result is \constant{5.5511151231257827e-017}.  While near to zero, the
+differences prevent reliable equality testing and differences can accumulate.
+For this reason, decimal would be preferred in accounting applications which
+have strict equality invariants.
+
+\item The decimal module incorporates a notion of significant places so that
+\samp{1.30 + 1.20} is \constant{2.50}.  The trailing zero is kept to indicate
+significance.  This is the customary presentation for monetary applications. For
+multiplication, the ``schoolbook'' approach uses all the figures in the
+multiplicands.  For instance, \samp{1.3 * 1.2} gives \constant{1.56} while
+\samp{1.30 * 1.20} gives \constant{1.5600}.
+
+\item Unlike hardware based binary floating point, the decimal module has a user
+settable precision (defaulting to 28 places) which can be as large as needed for
+a given problem:
+
+\begin{verbatim}
+>>> getcontext().prec = 6
+>>> Decimal(1) / Decimal(7)
+Decimal("0.142857")
+>>> getcontext().prec = 28
+>>> Decimal(1) / Decimal(7)
+Decimal("0.1428571428571428571428571429")
+\end{verbatim}
+
+\item Both binary and decimal floating point are implemented in terms of published
+standards.  While the built-in float type exposes only a modest portion of its
+capabilities, the decimal module exposes all required parts of the standard.
+When needed, the programmer has full control over rounding and signal handling.
+
+\end{itemize}
+
+
+The module design is centered around three concepts:  the decimal number, the
+context for arithmetic, and signals.
+
+A decimal number is immutable.  It has a sign, coefficient digits, and an
+exponent.  To preserve significance, the coefficient digits do not truncate
+trailing zeroes.  Decimals also include special values such as
+\constant{Infinity}, \constant{-Infinity}, and \constant{NaN}.  The standard
+also differentiates \constant{-0} from \constant{+0}.
+                                                   
+The context for arithmetic is an environment specifying precision, rounding
+rules, limits on exponents, flags indicating the results of operations,
+and trap enablers which determine whether signals are treated as
+exceptions.  Rounding options include \constant{ROUND_CEILING},
+\constant{ROUND_DOWN}, \constant{ROUND_FLOOR}, \constant{ROUND_HALF_DOWN},
+\constant{ROUND_HALF_EVEN}, \constant{ROUND_HALF_UP}, and \constant{ROUND_UP}.
+
+Signals are groups of exceptional conditions arising during the course of
+computation.  Depending on the needs of the application, signals may be
+ignored, considered as informational, or treated as exceptions. The signals in
+the decimal module are: \constant{Clamped}, \constant{InvalidOperation},
+\constant{DivisionByZero}, \constant{Inexact}, \constant{Rounded},
+\constant{Subnormal}, \constant{Overflow}, and \constant{Underflow}.
+
+For each signal there is a flag and a trap enabler.  When a signal is
+encountered, its flag is incremented from zero and, then, if the trap enabler
+is set to one, an exception is raised.  Flags are sticky, so the user
+needs to reset them before monitoring a calculation.
+
+
+\begin{seealso}
+  \seetext{IBM's General Decimal Arithmetic Specification,
+           \citetitle[http://www2.hursley.ibm.com/decimal/decarith.html]
+           {The General Decimal Arithmetic Specification}.}
+
+  \seetext{IEEE standard 854-1987,
+           \citetitle[http://www.cs.berkeley.edu/\textasciitilde ejr/projects/754/private/drafts/854-1987/dir.html]
+           {Unofficial IEEE 854 Text}.} 
+\end{seealso}
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\subsection{Quick-start Tutorial \label{decimal-tutorial}}
+
+The usual start to using decimals is importing the module, viewing the current
+context with \function{getcontext()} and, if necessary, setting new values
+for precision, rounding, or enabled traps:
+
+\begin{verbatim}
+>>> from decimal import *
+>>> getcontext()
+Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999,
+        capitals=1, flags=[], traps=[Overflow, InvalidOperation,
+        DivisionByZero])
+
+>>> getcontext().prec = 7       # Set a new precision
+\end{verbatim}
+
+
+Decimal instances can be constructed from integers, strings, or tuples.  To
+create a Decimal from a \class{float}, first convert it to a string.  This
+serves as an explicit reminder of the details of the conversion (including
+representation error).  Decimal numbers include special values such as
+\constant{NaN} which stands for ``Not a number'', positive and negative
+\constant{Infinity}, and \constant{-0}.        
+
+\begin{verbatim}
+>>> Decimal(10)
+Decimal("10")
+>>> Decimal("3.14")
+Decimal("3.14")
+>>> Decimal((0, (3, 1, 4), -2))
+Decimal("3.14")
+>>> Decimal(str(2.0 ** 0.5))
+Decimal("1.41421356237")
+>>> Decimal("NaN")
+Decimal("NaN")
+>>> Decimal("-Infinity")
+Decimal("-Infinity")
+\end{verbatim}
+
+
+The significance of a new Decimal is determined solely by the number
+of digits input.  Context precision and rounding only come into play during
+arithmetic operations.
+
+\begin{verbatim}
+>>> getcontext().prec = 6
+>>> Decimal('3.0')
+Decimal("3.0")
+>>> Decimal('3.1415926535')
+Decimal("3.1415926535")
+>>> Decimal('3.1415926535') + Decimal('2.7182818285')
+Decimal("5.85987")
+>>> getcontext().rounding = ROUND_UP
+>>> Decimal('3.1415926535') + Decimal('2.7182818285')
+Decimal("5.85988")
+\end{verbatim}
+
+
+Decimals interact well with much of the rest of Python.  Here is a small
+decimal floating point flying circus:
+    
+\begin{verbatim}    
+>>> data = map(Decimal, '1.34 1.87 3.45 2.35 1.00 0.03 9.25'.split())
+>>> max(data)
+Decimal("9.25")
+>>> min(data)
+Decimal("0.03")
+>>> sorted(data)
+[Decimal("0.03"), Decimal("1.00"), Decimal("1.34"), Decimal("1.87"),
+ Decimal("2.35"), Decimal("3.45"), Decimal("9.25")]
+>>> sum(data)
+Decimal("19.29")
+>>> a,b,c = data[:3]
+>>> str(a)
+'1.34'
+>>> float(a)
+1.3400000000000001
+>>> round(a, 1)     # round() first converts to binary floating point
+1.3
+>>> int(a)
+1
+>>> a * 5
+Decimal("6.70")
+>>> a * b
+Decimal("2.5058")
+>>> c % a
+Decimal("0.77")
+\end{verbatim}
+
+The \method{quantize()} method rounds a number to a fixed exponent.  This
+method is useful for monetary applications that often round results to a fixed
+number of places:
+
+\begin{verbatim} 
+>>> Decimal('7.325').quantize(Decimal('.01'), rounding=ROUND_DOWN)
+Decimal("7.32")
+>>> Decimal('7.325').quantize(Decimal('1.'), rounding=ROUND_UP)
+Decimal("8")
+\end{verbatim}
+
+As shown above, the \function{getcontext()} function accesses the current
+context and allows the settings to be changed.  This approach meets the
+needs of most applications.
+
+For more advanced work, it may be useful to create alternate contexts using
+the Context() constructor.  To make an alternate active, use the
+\function{setcontext()} function.
+
+In accordance with the standard, the \module{Decimal} module provides two
+ready to use standard contexts, \constant{BasicContext} and
+\constant{ExtendedContext}. The former is especially useful for debugging
+because many of the traps are enabled:
+
+\begin{verbatim}
+>>> myothercontext = Context(prec=60, rounding=ROUND_HALF_DOWN)
+>>> setcontext(myothercontext)
+>>> Decimal(1) / Decimal(7)
+Decimal("0.142857142857142857142857142857142857142857142857142857142857")
+
+>>> ExtendedContext
+Context(prec=9, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999,
+        capitals=1, flags=[], traps=[])
+>>> setcontext(ExtendedContext)
+>>> Decimal(1) / Decimal(7)
+Decimal("0.142857143")
+>>> Decimal(42) / Decimal(0)
+Decimal("Infinity")
+
+>>> setcontext(BasicContext)
+>>> Decimal(42) / Decimal(0)
+Traceback (most recent call last):
+  File "<pyshell#143>", line 1, in -toplevel-
+    Decimal(42) / Decimal(0)
+DivisionByZero: x / 0
+\end{verbatim}
+
+
+Contexts also have signal flags for monitoring exceptional conditions
+encountered during computations.  The flags remain set until explicitly
+cleared, so it is best to clear the flags before each set of monitored
+computations by using the \method{clear_flags()} method.
+
+\begin{verbatim}
+>>> setcontext(ExtendedContext)
+>>> getcontext().clear_flags()
+>>> Decimal(355) / Decimal(113)
+Decimal("3.14159292")
+>>> getcontext()
+Context(prec=9, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999,
+        capitals=1, flags=[Inexact, Rounded], traps=[])
+\end{verbatim}
+
+The \var{flags} entry shows that the rational approximation to \constant{Pi}
+was rounded (digits beyond the context precision were thrown away) and that
+the result is inexact (some of the discarded digits were non-zero).
+
+Individual traps are set using the dictionary in the \member{traps}
+field of a context:
+
+\begin{verbatim}
+>>> Decimal(1) / Decimal(0)
+Decimal("Infinity")
+>>> getcontext().traps[DivisionByZero] = 1
+>>> Decimal(1) / Decimal(0)
+Traceback (most recent call last):
+  File "<pyshell#112>", line 1, in -toplevel-
+    Decimal(1) / Decimal(0)
+DivisionByZero: x / 0
+\end{verbatim}
+
+Most programs adjust the current context only once, at the beginning of the
+program.  And, in many applications, data is converted to \class{Decimal} with
+a single cast inside a loop.  With context set and decimals created, the bulk
+of the program manipulates the data no differently than with other Python
+numeric types.
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\subsection{Decimal objects \label{decimal-decimal}}
+
+\begin{classdesc}{Decimal}{\optional{value \optional{, context}}}
+  Constructs a new \class{Decimal} object based from \var{value}.
+
+  \var{value} can be an integer, string, tuple, or another \class{Decimal}
+  object. If no \var{value} is given, returns \code{Decimal("0")}.  If
+  \var{value} is a string, it should conform to the decimal numeric string
+  syntax:
+    
+  \begin{verbatim}
+    sign           ::=  '+' | '-'
+    digit          ::=  '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
+    indicator      ::=  'e' | 'E'
+    digits         ::=  digit [digit]...
+    decimal-part   ::=  digits '.' [digits] | ['.'] digits
+    exponent-part  ::=  indicator [sign] digits
+    infinity       ::=  'Infinity' | 'Inf'
+    nan            ::=  'NaN' [digits] | 'sNaN' [digits]
+    numeric-value  ::=  decimal-part [exponent-part] | infinity
+    numeric-string ::=  [sign] numeric-value | [sign] nan  
+  \end{verbatim}
+
+  If \var{value} is a \class{tuple}, it should have three components,
+  a sign (\constant{0} for positive or \constant{1} for negative),
+  a \class{tuple} of digits, and an integer exponent. For example,
+  \samp{Decimal((0, (1, 4, 1, 4), -3))} returns \code{Decimal("1.414")}.
+
+  The \var{context} precision does not affect how many digits are stored.
+  That is determined exclusively by the number of digits in \var{value}. For
+  example, \samp{Decimal("3.00000")} records all five zeroes even if the
+  context precision is only three.
+
+  The purpose of the \var{context} argument is determining what to do if
+  \var{value} is a malformed string.  If the context traps
+  \constant{InvalidOperation}, an exception is raised; otherwise, the
+  constructor returns a new Decimal with the value of \constant{NaN}.
+
+  Once constructed, \class{Decimal} objects are immutable.
+\end{classdesc}
+
+Decimal floating point objects share many properties with the other builtin
+numeric types such as \class{float} and \class{int}.  All of the usual
+math operations and special methods apply.  Likewise, decimal objects can
+be copied, pickled, printed, used as dictionary keys, used as set elements,
+compared, sorted, and coerced to another type (such as \class{float}
+or \class{long}).
+
+In addition to the standard numeric properties, decimal floating point objects
+also have a number of specialized methods:
+
+\begin{methoddesc}{adjusted}{}
+  Return the adjusted exponent after shifting out the coefficient's rightmost
+  digits until only the lead digit remains: \code{Decimal("321e+5").adjusted()}
+  returns seven.  Used for determining the position of the most significant
+  digit with respect to the decimal point.
+\end{methoddesc}
+
+\begin{methoddesc}{as_tuple}{}
+  Returns a tuple representation of the number:
+  \samp{(sign, digittuple, exponent)}.
+\end{methoddesc}
+
+\begin{methoddesc}{compare}{other\optional{, context}}
+  Compares like \method{__cmp__()} but returns a decimal instance:
+  \begin{verbatim}
+        a or b is a NaN ==> Decimal("NaN")
+        a < b           ==> Decimal("-1")
+        a == b          ==> Decimal("0")
+        a > b           ==> Decimal("1")
+  \end{verbatim}
+\end{methoddesc}
+
+\begin{methoddesc}{max}{other\optional{, context}}
+  Like \samp{max(self, other)} except that the context rounding rule
+  is applied before returning and that \constant{NaN} values are
+  either signalled or ignored (depending on the context and whether
+  they are signaling or quiet).
+\end{methoddesc}
+
+\begin{methoddesc}{min}{other\optional{, context}}
+  Like \samp{min(self, other)} except that the context rounding rule
+  is applied before returning and that \constant{NaN} values are
+  either signalled or ignored (depending on the context and whether
+  they are signaling or quiet).
+\end{methoddesc}
+
+\begin{methoddesc}{normalize}{\optional{context}}
+  Normalize the number by stripping the rightmost trailing zeroes and
+  converting any result equal to \constant{Decimal("0")} to
+  \constant{Decimal("0e0")}. Used for producing canonical values for members
+  of an equivalence class. For example, \code{Decimal("32.100")} and
+  \code{Decimal("0.321000e+2")} both normalize to the equivalent value
+  \code{Decimal("32.1")}.
+\end{methoddesc}                                              
+
+\begin{methoddesc}{quantize}
+  {exp \optional{, rounding\optional{, context\optional{, watchexp}}}}
+  Quantize makes the exponent the same as \var{exp}.  Searches for a
+  rounding method in \var{rounding}, then in \var{context}, and then
+  in the current context.
+
+  If \var{watchexp} is set (default), then an error is returned whenever
+  the resulting exponent is greater than \member{Emax} or less than
+  \member{Etiny}.
+\end{methoddesc} 
+
+\begin{methoddesc}{remainder_near}{other\optional{, context}}
+  Computes the modulo as either a positive or negative value depending
+  on which is closest to zero.  For instance,
+  \samp{Decimal(10).remainder_near(6)} returns \code{Decimal("-2")}
+  which is closer to zero than \code{Decimal("4")}.
+
+  If both are equally close, the one chosen will have the same sign
+  as \var{self}.
+\end{methoddesc}  
+
+\begin{methoddesc}{same_quantum}{other\optional{, context}}
+  Test whether self and other have the same exponent or whether both
+  are \constant{NaN}.
+\end{methoddesc}
+
+\begin{methoddesc}{sqrt}{\optional{context}}
+  Return the square root to full precision.
+\end{methoddesc}                    
+ 
+\begin{methoddesc}{to_eng_string}{\optional{context}}
+  Convert to an engineering-type string.
+
+  Engineering notation has an exponent which is a multiple of 3, so there
+  are up to 3 digits left of the decimal place.  For example, converts
+  \code{Decimal('123E+1')} to \code{Decimal("1.23E+3")}
+\end{methoddesc}  
+
+\begin{methoddesc}{to_integral}{\optional{rounding\optional{, context}}}                   
+  Rounds to the nearest integer without signaling \constant{Inexact}
+  or \constant{Rounded}.  If given, applies \var{rounding}; otherwise,
+  uses the rounding method in either the supplied \var{context} or the
+  current context.
+\end{methoddesc} 
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%            
+\subsection{Context objects \label{decimal-decimal}}
+
+Contexts are environments for arithmetic operations.  They govern precision,
+set rules for rounding, determine which signals are treated as exceptions, and
+limit the range for exponents.
+
+Each thread has its own current context which is accessed or changed using
+the \function{getcontext()} and \function{setcontext()} functions:
+
+\begin{funcdesc}{getcontext}{}
+  Return the current context for the active thread.
+\end{funcdesc}            
+
+\begin{funcdesc}{setcontext}{c}
+  Set the current context for the active thread to \var{c}.
+\end{funcdesc}  
+
+Beginning with Python 2.5, you can also use the \keyword{with} statement
+and the \function{localcontext()} function to temporarily change the
+active context.
+
+\begin{funcdesc}{localcontext}{\optional{c}}
+  Return a context manager that will set the current context for
+  the active thread to a copy of \var{c} on entry to the with-statement
+  and restore the previous context when exiting the with-statement. If
+  no context is specified, a copy of the current context is used.
+  \versionadded{2.5}
+
+  For example, the following code sets the current decimal precision
+  to 42 places, performs a calculation, and then automatically restores
+  the previous context:
+\begin{verbatim}
+    from __future__ import with_statement
+    from decimal import localcontext
+
+    with localcontext() as ctx:
+        ctx.prec = 42   # Perform a high precision calculation
+        s = calculate_something()
+    s = +s  # Round the final result back to the default precision
+\end{verbatim}
+\end{funcdesc}
+
+New contexts can also be created using the \class{Context} constructor
+described below. In addition, the module provides three pre-made
+contexts:
+
+\begin{classdesc*}{BasicContext}
+  This is a standard context defined by the General Decimal Arithmetic
+  Specification.  Precision is set to nine.  Rounding is set to
+  \constant{ROUND_HALF_UP}.  All flags are cleared.  All traps are enabled
+  (treated as exceptions) except \constant{Inexact}, \constant{Rounded}, and
+  \constant{Subnormal}.
+
+  Because many of the traps are enabled, this context is useful for debugging.
+\end{classdesc*}
+
+\begin{classdesc*}{ExtendedContext}
+  This is a standard context defined by the General Decimal Arithmetic
+  Specification.  Precision is set to nine.  Rounding is set to
+  \constant{ROUND_HALF_EVEN}.  All flags are cleared.  No traps are enabled
+  (so that exceptions are not raised during computations).
+
+  Because the trapped are disabled, this context is useful for applications
+  that prefer to have result value of \constant{NaN} or \constant{Infinity}
+  instead of raising exceptions.  This allows an application to complete a
+  run in the presence of conditions that would otherwise halt the program.
+\end{classdesc*}
+
+\begin{classdesc*}{DefaultContext}
+  This context is used by the \class{Context} constructor as a prototype for
+  new contexts.  Changing a field (such a precision) has the effect of
+  changing the default for new contexts creating by the \class{Context}
+  constructor.
+
+  This context is most useful in multi-threaded environments.  Changing one of
+  the fields before threads are started has the effect of setting system-wide
+  defaults.  Changing the fields after threads have started is not recommended
+  as it would require thread synchronization to prevent race conditions.
+
+  In single threaded environments, it is preferable to not use this context
+  at all.  Instead, simply create contexts explicitly as described below.
+
+  The default values are precision=28, rounding=ROUND_HALF_EVEN, and enabled
+  traps for Overflow, InvalidOperation, and DivisionByZero.
+\end{classdesc*}
+
+
+In addition to the three supplied contexts, new contexts can be created
+with the \class{Context} constructor.
+
+\begin{classdesc}{Context}{prec=None, rounding=None, traps=None,
+        flags=None, Emin=None, Emax=None, capitals=1}
+  Creates a new context.  If a field is not specified or is \constant{None},
+  the default values are copied from the \constant{DefaultContext}.  If the
+  \var{flags} field is not specified or is \constant{None}, all flags are
+  cleared.
+
+  The \var{prec} field is a positive integer that sets the precision for
+  arithmetic operations in the context.
+
+  The \var{rounding} option is one of:
+  \begin{itemize}
+  \item \constant{ROUND_CEILING} (towards \constant{Infinity}),
+  \item \constant{ROUND_DOWN} (towards zero),
+  \item \constant{ROUND_FLOOR} (towards \constant{-Infinity}),
+  \item \constant{ROUND_HALF_DOWN} (to nearest with ties going towards zero),
+  \item \constant{ROUND_HALF_EVEN} (to nearest with ties going to nearest even integer),
+  \item \constant{ROUND_HALF_UP} (to nearest with ties going away from zero), or
+  \item \constant{ROUND_UP} (away from zero).
+  \end{itemize}
+
+  The \var{traps} and \var{flags} fields list any signals to be set.
+  Generally, new contexts should only set traps and leave the flags clear.
+
+  The \var{Emin} and \var{Emax} fields are integers specifying the outer
+  limits allowable for exponents.
+
+  The \var{capitals} field is either \constant{0} or \constant{1} (the
+  default). If set to \constant{1}, exponents are printed with a capital
+  \constant{E}; otherwise, a lowercase \constant{e} is used:
+  \constant{Decimal('6.02e+23')}.
+\end{classdesc}
+
+The \class{Context} class defines several general purpose methods as well as a
+large number of methods for doing arithmetic directly in a given context.
+
+\begin{methoddesc}{clear_flags}{}
+  Resets all of the flags to \constant{0}.
+\end{methoddesc}  
+
+\begin{methoddesc}{copy}{}
+  Return a duplicate of the context.
+\end{methoddesc}  
+
+\begin{methoddesc}{create_decimal}{num}
+  Creates a new Decimal instance from \var{num} but using \var{self} as
+  context. Unlike the \class{Decimal} constructor, the context precision,
+  rounding method, flags, and traps are applied to the conversion.
+
+  This is useful because constants are often given to a greater precision than
+  is needed by the application.  Another benefit is that rounding immediately
+  eliminates unintended effects from digits beyond the current precision.
+  In the following example, using unrounded inputs means that adding zero
+  to a sum can change the result:
+
+  \begin{verbatim}
+    >>> getcontext().prec = 3
+    >>> Decimal("3.4445") + Decimal("1.0023")
+    Decimal("4.45")
+    >>> Decimal("3.4445") + Decimal(0) + Decimal("1.0023")
+    Decimal("4.44")
+  \end{verbatim}
+      
+\end{methoddesc} 
+
+\begin{methoddesc}{Etiny}{}
+  Returns a value equal to \samp{Emin - prec + 1} which is the minimum
+  exponent value for subnormal results.  When underflow occurs, the
+  exponent is set to \constant{Etiny}.
+\end{methoddesc} 
+
+\begin{methoddesc}{Etop}{}
+  Returns a value equal to \samp{Emax - prec + 1}.
+\end{methoddesc} 
+
+
+The usual approach to working with decimals is to create \class{Decimal}
+instances and then apply arithmetic operations which take place within the
+current context for the active thread.  An alternate approach is to use
+context methods for calculating within a specific context.  The methods are
+similar to those for the \class{Decimal} class and are only briefly recounted
+here.
+
+\begin{methoddesc}{abs}{x}
+  Returns the absolute value of \var{x}.
+\end{methoddesc}
+
+\begin{methoddesc}{add}{x, y}
+  Return the sum of \var{x} and \var{y}.
+\end{methoddesc}
+   
+\begin{methoddesc}{compare}{x, y}
+  Compares values numerically.
+  
+  Like \method{__cmp__()} but returns a decimal instance:
+  \begin{verbatim}
+        a or b is a NaN ==> Decimal("NaN")
+        a < b           ==> Decimal("-1")
+        a == b          ==> Decimal("0")
+        a > b           ==> Decimal("1")
+  \end{verbatim}                                          
+\end{methoddesc}
+
+\begin{methoddesc}{divide}{x, y}
+  Return \var{x} divided by \var{y}.
+\end{methoddesc}   
+  
+\begin{methoddesc}{divmod}{x, y}
+  Divides two numbers and returns the integer part of the result.
+\end{methoddesc} 
+
+\begin{methoddesc}{max}{x, y}
+  Compare two values numerically and return the maximum.
+
+  If they are numerically equal then the left-hand operand is chosen as the
+  result.
+\end{methoddesc} 
+ 
+\begin{methoddesc}{min}{x, y}
+  Compare two values numerically and return the minimum.
+
+  If they are numerically equal then the left-hand operand is chosen as the
+  result.
+\end{methoddesc}
+
+\begin{methoddesc}{minus}{x}
+  Minus corresponds to the unary prefix minus operator in Python.
+\end{methoddesc}
+
+\begin{methoddesc}{multiply}{x, y}
+  Return the product of \var{x} and \var{y}.
+\end{methoddesc}
+
+\begin{methoddesc}{normalize}{x}
+  Normalize reduces an operand to its simplest form.
+
+  Essentially a \method{plus} operation with all trailing zeros removed from
+  the result.
+\end{methoddesc}
+  
+\begin{methoddesc}{plus}{x}
+  Plus corresponds to the unary prefix plus operator in Python.  This
+  operation applies the context precision and rounding, so it is
+  \emph{not} an identity operation.
+\end{methoddesc}
+
+\begin{methoddesc}{power}{x, y\optional{, modulo}}
+  Return \samp{x ** y} to the \var{modulo} if given.
+
+  The right-hand operand must be a whole number whose integer part (after any
+  exponent has been applied) has no more than 9 digits and whose fractional
+  part (if any) is all zeros before any rounding. The operand may be positive,
+  negative, or zero; if negative, the absolute value of the power is used, and
+  the left-hand operand is inverted (divided into 1) before use.
+
+  If the increased precision needed for the intermediate calculations exceeds
+  the capabilities of the implementation then an \constant{InvalidOperation}
+  condition is signaled.
+
+  If, when raising to a negative power, an underflow occurs during the
+  division into 1, the operation is not halted at that point but continues. 
+\end{methoddesc}
+
+\begin{methoddesc}{quantize}{x, y}
+  Returns a value equal to \var{x} after rounding and having the exponent of
+  \var{y}.
+
+  Unlike other operations, if the length of the coefficient after the quantize
+  operation would be greater than precision, then an
+  \constant{InvalidOperation} is signaled. This guarantees that, unless there
+  is an error condition, the quantized exponent is always equal to that of the
+  right-hand operand.
+
+  Also unlike other operations, quantize never signals Underflow, even
+  if the result is subnormal and inexact.  
+\end{methoddesc} 
+
+\begin{methoddesc}{remainder}{x, y}
+  Returns the remainder from integer division.
+
+  The sign of the result, if non-zero, is the same as that of the original
+  dividend. 
+\end{methoddesc}
+ 
+\begin{methoddesc}{remainder_near}{x, y}
+  Computed the modulo as either a positive or negative value depending
+  on which is closest to zero.  For instance,
+  \samp{Decimal(10).remainder_near(6)} returns \code{Decimal("-2")}
+  which is closer to zero than \code{Decimal("4")}.
+
+  If both are equally close, the one chosen will have the same sign
+  as \var{self}.
+\end{methoddesc}
+
+\begin{methoddesc}{same_quantum}{x, y}
+  Test whether \var{x} and \var{y} have the same exponent or whether both are
+  \constant{NaN}.
+\end{methoddesc}
+
+\begin{methoddesc}{sqrt}{x}
+  Return the square root of \var{x} to full precision.
+\end{methoddesc}                    
+
+\begin{methoddesc}{subtract}{x, y}
+  Return the difference between \var{x} and \var{y}.
+\end{methoddesc}
+ 
+\begin{methoddesc}{to_eng_string}{}
+  Convert to engineering-type string.
+
+  Engineering notation has an exponent which is a multiple of 3, so there
+  are up to 3 digits left of the decimal place.  For example, converts
+  \code{Decimal('123E+1')} to \code{Decimal("1.23E+3")}
+\end{methoddesc}  
+
+\begin{methoddesc}{to_integral}{x}                  
+  Rounds to the nearest integer without signaling \constant{Inexact}
+  or \constant{Rounded}.                                        
+\end{methoddesc} 
+
+\begin{methoddesc}{to_sci_string}{x}
+  Converts a number to a string using scientific notation.
+\end{methoddesc} 
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%            
+\subsection{Signals \label{decimal-signals}}
+
+Signals represent conditions that arise during computation.
+Each corresponds to one context flag and one context trap enabler.
+
+The context flag is incremented whenever the condition is encountered.
+After the computation, flags may be checked for informational
+purposes (for instance, to determine whether a computation was exact).
+After checking the flags, be sure to clear all flags before starting
+the next computation.
+
+If the context's trap enabler is set for the signal, then the condition
+causes a Python exception to be raised.  For example, if the
+\class{DivisionByZero} trap is set, then a \exception{DivisionByZero}
+exception is raised upon encountering the condition.
+
+
+\begin{classdesc*}{Clamped}
+    Altered an exponent to fit representation constraints.
+
+    Typically, clamping occurs when an exponent falls outside the context's
+    \member{Emin} and \member{Emax} limits.  If possible, the exponent is
+    reduced to fit by adding zeroes to the coefficient.
+\end{classdesc*}
+
+\begin{classdesc*}{DecimalException}
+    Base class for other signals and a subclass of
+    \exception{ArithmeticError}.
+\end{classdesc*}
+
+\begin{classdesc*}{DivisionByZero}
+    Signals the division of a non-infinite number by zero.
+
+    Can occur with division, modulo division, or when raising a number to a
+    negative power.  If this signal is not trapped, returns
+    \constant{Infinity} or \constant{-Infinity} with the sign determined by
+    the inputs to the calculation.
+\end{classdesc*}
+
+\begin{classdesc*}{Inexact}
+    Indicates that rounding occurred and the result is not exact.
+
+    Signals when non-zero digits were discarded during rounding. The rounded
+    result is returned.  The signal flag or trap is used to detect when
+    results are inexact.
+\end{classdesc*}
+
+\begin{classdesc*}{InvalidOperation}
+    An invalid operation was performed.
+
+    Indicates that an operation was requested that does not make sense.
+    If not trapped, returns \constant{NaN}.  Possible causes include:
+
+    \begin{verbatim}
+        Infinity - Infinity
+        0 * Infinity
+        Infinity / Infinity
+        x % 0
+        Infinity % x
+        x._rescale( non-integer )
+        sqrt(-x) and x > 0
+        0 ** 0
+        x ** (non-integer)
+        x ** Infinity      
+    \end{verbatim}    
+\end{classdesc*}
+
+\begin{classdesc*}{Overflow}
+    Numerical overflow.
+
+    Indicates the exponent is larger than \member{Emax} after rounding has
+    occurred.  If not trapped, the result depends on the rounding mode, either
+    pulling inward to the largest representable finite number or rounding
+    outward to \constant{Infinity}.  In either case, \class{Inexact} and
+    \class{Rounded} are also signaled.   
+\end{classdesc*}
+
+\begin{classdesc*}{Rounded}
+    Rounding occurred though possibly no information was lost.
+
+    Signaled whenever rounding discards digits; even if those digits are
+    zero (such as rounding \constant{5.00} to \constant{5.0}).   If not
+    trapped, returns the result unchanged.  This signal is used to detect
+    loss of significant digits.
+\end{classdesc*}
+
+\begin{classdesc*}{Subnormal}
+    Exponent was lower than \member{Emin} prior to rounding.
+          
+    Occurs when an operation result is subnormal (the exponent is too small).
+    If not trapped, returns the result unchanged.
+\end{classdesc*}
+
+\begin{classdesc*}{Underflow}
+    Numerical underflow with result rounded to zero.
+
+    Occurs when a subnormal result is pushed to zero by rounding.
+    \class{Inexact} and \class{Subnormal} are also signaled.
+\end{classdesc*}
+
+The following table summarizes the hierarchy of signals:
+
+\begin{verbatim}    
+    exceptions.ArithmeticError(exceptions.StandardError)
+        DecimalException
+            Clamped
+            DivisionByZero(DecimalException, exceptions.ZeroDivisionError)
+            Inexact
+                Overflow(Inexact, Rounded)
+                Underflow(Inexact, Rounded, Subnormal)
+            InvalidOperation
+            Rounded
+            Subnormal
+\end{verbatim}            
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\subsection{Floating Point Notes \label{decimal-notes}}
+
+\subsubsection{Mitigating round-off error with increased precision}
+
+The use of decimal floating point eliminates decimal representation error
+(making it possible to represent \constant{0.1} exactly); however, some
+operations can still incur round-off error when non-zero digits exceed the
+fixed precision.
+
+The effects of round-off error can be amplified by the addition or subtraction
+of nearly offsetting quantities resulting in loss of significance.  Knuth
+provides two instructive examples where rounded floating point arithmetic with
+insufficient precision causes the breakdown of the associative and
+distributive properties of addition:
+
+\begin{verbatim}
+# Examples from Seminumerical Algorithms, Section 4.2.2.
+>>> from decimal import Decimal, getcontext
+>>> getcontext().prec = 8
+
+>>> u, v, w = Decimal(11111113), Decimal(-11111111), Decimal('7.51111111')
+>>> (u + v) + w
+Decimal("9.5111111")
+>>> u + (v + w)
+Decimal("10")
+
+>>> u, v, w = Decimal(20000), Decimal(-6), Decimal('6.0000003')
+>>> (u*v) + (u*w)
+Decimal("0.01")
+>>> u * (v+w)
+Decimal("0.0060000")
+\end{verbatim}
+
+The \module{decimal} module makes it possible to restore the identities
+by expanding the precision sufficiently to avoid loss of significance:
+
+\begin{verbatim}
+>>> getcontext().prec = 20
+>>> u, v, w = Decimal(11111113), Decimal(-11111111), Decimal('7.51111111')
+>>> (u + v) + w
+Decimal("9.51111111")
+>>> u + (v + w)
+Decimal("9.51111111")
+>>> 
+>>> u, v, w = Decimal(20000), Decimal(-6), Decimal('6.0000003')
+>>> (u*v) + (u*w)
+Decimal("0.0060000")
+>>> u * (v+w)
+Decimal("0.0060000")
+\end{verbatim}
+
+\subsubsection{Special values}
+
+The number system for the \module{decimal} module provides special
+values including \constant{NaN}, \constant{sNaN}, \constant{-Infinity},
+\constant{Infinity}, and two zeroes, \constant{+0} and \constant{-0}.
+
+Infinities can be constructed directly with:  \code{Decimal('Infinity')}. Also,
+they can arise from dividing by zero when the \exception{DivisionByZero}
+signal is not trapped.  Likewise, when the \exception{Overflow} signal is not
+trapped, infinity can result from rounding beyond the limits of the largest
+representable number.
+
+The infinities are signed (affine) and can be used in arithmetic operations
+where they get treated as very large, indeterminate numbers.  For instance,
+adding a constant to infinity gives another infinite result.
+
+Some operations are indeterminate and return \constant{NaN}, or if the
+\exception{InvalidOperation} signal is trapped, raise an exception.  For
+example, \code{0/0} returns \constant{NaN} which means ``not a number''.  This
+variety of \constant{NaN} is quiet and, once created, will flow through other
+computations always resulting in another \constant{NaN}.  This behavior can be
+useful for a series of computations that occasionally have missing inputs ---
+it allows the calculation to proceed while flagging specific results as
+invalid.     
+
+A variant is \constant{sNaN} which signals rather than remaining quiet
+after every operation.  This is a useful return value when an invalid
+result needs to interrupt a calculation for special handling.
+
+The signed zeros can result from calculations that underflow.
+They keep the sign that would have resulted if the calculation had
+been carried out to greater precision.  Since their magnitude is
+zero, both positive and negative zeros are treated as equal and their
+sign is informational.
+
+In addition to the two signed zeros which are distinct yet equal,
+there are various representations of zero with differing precisions
+yet equivalent in value.  This takes a bit of getting used to.  For
+an eye accustomed to normalized floating point representations, it
+is not immediately obvious that the following calculation returns
+a value equal to zero:          
+
+\begin{verbatim}
+>>> 1 / Decimal('Infinity')
+Decimal("0E-1000000026")
+\end{verbatim}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\subsection{Working with threads \label{decimal-threads}}
+
+The \function{getcontext()} function accesses a different \class{Context}
+object for each thread.  Having separate thread contexts means that threads
+may make changes (such as \code{getcontext.prec=10}) without interfering with
+other threads.
+
+Likewise, the \function{setcontext()} function automatically assigns its target
+to the current thread.
+
+If \function{setcontext()} has not been called before \function{getcontext()},
+then \function{getcontext()} will automatically create a new context for use
+in the current thread.
+
+The new context is copied from a prototype context called
+\var{DefaultContext}. To control the defaults so that each thread will use the
+same values throughout the application, directly modify the
+\var{DefaultContext} object. This should be done \emph{before} any threads are
+started so that there won't be a race condition between threads calling
+\function{getcontext()}. For example:
+
+\begin{verbatim}
+# Set applicationwide defaults for all threads about to be launched
+DefaultContext.prec = 12
+DefaultContext.rounding = ROUND_DOWN
+DefaultContext.traps = ExtendedContext.traps.copy()
+DefaultContext.traps[InvalidOperation] = 1
+setcontext(DefaultContext)
+
+# Afterwards, the threads can be started
+t1.start()
+t2.start()
+t3.start()
+ . . .
+\end{verbatim}
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\subsection{Recipes \label{decimal-recipes}}
+
+Here are a few recipes that serve as utility functions and that demonstrate
+ways to work with the \class{Decimal} class:
+
+\begin{verbatim}
+def moneyfmt(value, places=2, curr='', sep=',', dp='.',
+             pos='', neg='-', trailneg=''):
+    """Convert Decimal to a money formatted string.
+
+    places:  required number of places after the decimal point
+    curr:    optional currency symbol before the sign (may be blank)
+    sep:     optional grouping separator (comma, period, space, or blank)
+    dp:      decimal point indicator (comma or period)
+             only specify as blank when places is zero
+    pos:     optional sign for positive numbers: '+', space or blank
+    neg:     optional sign for negative numbers: '-', '(', space or blank
+    trailneg:optional trailing minus indicator:  '-', ')', space or blank
+
+    >>> d = Decimal('-1234567.8901')
+    >>> moneyfmt(d, curr='$')
+    '-$1,234,567.89'
+    >>> moneyfmt(d, places=0, sep='.', dp='', neg='', trailneg='-')
+    '1.234.568-'
+    >>> moneyfmt(d, curr='$', neg='(', trailneg=')')
+    '($1,234,567.89)'
+    >>> moneyfmt(Decimal(123456789), sep=' ')
+    '123 456 789.00'
+    >>> moneyfmt(Decimal('-0.02'), neg='<', trailneg='>')
+    '<.02>'
+
+    """
+    q = Decimal((0, (1,), -places))    # 2 places --> '0.01'
+    sign, digits, exp = value.quantize(q).as_tuple()
+    assert exp == -places    
+    result = []
+    digits = map(str, digits)
+    build, next = result.append, digits.pop
+    if sign:
+        build(trailneg)
+    for i in range(places):
+        if digits:
+            build(next())
+        else:
+            build('0')
+    build(dp)
+    i = 0
+    while digits:
+        build(next())
+        i += 1
+        if i == 3 and digits:
+            i = 0
+            build(sep)
+    build(curr)
+    if sign:
+        build(neg)
+    else:
+        build(pos)
+    result.reverse()
+    return ''.join(result)
+
+def pi():
+    """Compute Pi to the current precision.
+
+    >>> print pi()
+    3.141592653589793238462643383
+    
+    """
+    getcontext().prec += 2  # extra digits for intermediate steps
+    three = Decimal(3)      # substitute "three=3.0" for regular floats
+    lasts, t, s, n, na, d, da = 0, three, 3, 1, 0, 0, 24
+    while s != lasts:
+        lasts = s
+        n, na = n+na, na+8
+        d, da = d+da, da+32
+        t = (t * n) / d
+        s += t
+    getcontext().prec -= 2
+    return +s               # unary plus applies the new precision
+
+def exp(x):
+    """Return e raised to the power of x.  Result type matches input type.
+
+    >>> print exp(Decimal(1))
+    2.718281828459045235360287471
+    >>> print exp(Decimal(2))
+    7.389056098930650227230427461
+    >>> print exp(2.0)
+    7.38905609893
+    >>> print exp(2+0j)
+    (7.38905609893+0j)
+    
+    """
+    getcontext().prec += 2
+    i, lasts, s, fact, num = 0, 0, 1, 1, 1
+    while s != lasts:
+        lasts = s    
+        i += 1
+        fact *= i
+        num *= x     
+        s += num / fact   
+    getcontext().prec -= 2        
+    return +s
+
+def cos(x):
+    """Return the cosine of x as measured in radians.
+
+    >>> print cos(Decimal('0.5'))
+    0.8775825618903727161162815826
+    >>> print cos(0.5)
+    0.87758256189
+    >>> print cos(0.5+0j)
+    (0.87758256189+0j)
+    
+    """
+    getcontext().prec += 2
+    i, lasts, s, fact, num, sign = 0, 0, 1, 1, 1, 1
+    while s != lasts:
+        lasts = s    
+        i += 2
+        fact *= i * (i-1)
+        num *= x * x
+        sign *= -1
+        s += num / fact * sign 
+    getcontext().prec -= 2        
+    return +s
+
+def sin(x):
+    """Return the sine of x as measured in radians.
+
+    >>> print sin(Decimal('0.5'))
+    0.4794255386042030002732879352
+    >>> print sin(0.5)
+    0.479425538604
+    >>> print sin(0.5+0j)
+    (0.479425538604+0j)
+    
+    """
+    getcontext().prec += 2
+    i, lasts, s, fact, num, sign = 1, 0, x, 1, x, 1
+    while s != lasts:
+        lasts = s    
+        i += 2
+        fact *= i * (i-1)
+        num *= x * x
+        sign *= -1
+        s += num / fact * sign 
+    getcontext().prec -= 2        
+    return +s
+
+\end{verbatim}                                             
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\subsection{Decimal FAQ \label{decimal-faq}}
+
+Q.  It is cumbersome to type \code{decimal.Decimal('1234.5')}.  Is there a way
+to minimize typing when using the interactive interpreter?
+
+A.  Some users abbreviate the constructor to just a single letter:
+
+\begin{verbatim}
+>>> D = decimal.Decimal
+>>> D('1.23') + D('3.45')
+Decimal("4.68")
+\end{verbatim}
+
+
+Q.  In a fixed-point application with two decimal places, some inputs
+have many places and need to be rounded.  Others are not supposed to have
+excess digits and need to be validated.  What methods should be used?
+
+A.  The \method{quantize()} method rounds to a fixed number of decimal places.
+If the \constant{Inexact} trap is set, it is also useful for validation:
+
+\begin{verbatim}
+>>> TWOPLACES = Decimal(10) ** -2       # same as Decimal('0.01')
+
+>>> # Round to two places
+>>> Decimal("3.214").quantize(TWOPLACES)
+Decimal("3.21")
+
+>>> # Validate that a number does not exceed two places 
+>>> Decimal("3.21").quantize(TWOPLACES, context=Context(traps=[Inexact]))
+Decimal("3.21")
+
+>>> Decimal("3.214").quantize(TWOPLACES, context=Context(traps=[Inexact]))
+Traceback (most recent call last):
+   ...
+Inexact: Changed in rounding
+\end{verbatim}
+
+
+Q.  Once I have valid two place inputs, how do I maintain that invariant
+throughout an application?
+
+A.  Some operations like addition and subtraction automatically preserve fixed
+point.  Others, like multiplication and division, change the number of decimal
+places and need to be followed-up with a \method{quantize()} step.
+
+
+Q.  There are many ways to express the same value.  The numbers
+\constant{200}, \constant{200.000}, \constant{2E2}, and \constant{.02E+4} all
+have the same value at various precisions. Is there a way to transform them to
+a single recognizable canonical value?
+
+A.  The \method{normalize()} method maps all equivalent values to a single
+representative:
+
+\begin{verbatim}
+>>> values = map(Decimal, '200 200.000 2E2 .02E+4'.split())
+>>> [v.normalize() for v in values]
+[Decimal("2E+2"), Decimal("2E+2"), Decimal("2E+2"), Decimal("2E+2")]
+\end{verbatim}
+
+
+Q.  Some decimal values always print with exponential notation.  Is there
+a way to get a non-exponential representation?
+
+A.  For some values, exponential notation is the only way to express
+the number of significant places in the coefficient.  For example,
+expressing \constant{5.0E+3} as \constant{5000} keeps the value
+constant but cannot show the original's two-place significance.
+
+
+Q.  Is there a way to convert a regular float to a \class{Decimal}?
+
+A.  Yes, all binary floating point numbers can be exactly expressed as a
+Decimal.  An exact conversion may take more precision than intuition would
+suggest, so trapping \constant{Inexact} will signal a need for more precision:
+
+\begin{verbatim}
+def floatToDecimal(f):
+    "Convert a floating point number to a Decimal with no loss of information"
+    # Transform (exactly) a float to a mantissa (0.5 <= abs(m) < 1.0) and an
+    # exponent.  Double the mantissa until it is an integer.  Use the integer
+    # mantissa and exponent to compute an equivalent Decimal.  If this cannot
+    # be done exactly, then retry with more precision.
+
+    mantissa, exponent = math.frexp(f)
+    while mantissa != int(mantissa):
+        mantissa *= 2.0
+        exponent -= 1
+    mantissa = int(mantissa)
+
+    oldcontext = getcontext()
+    setcontext(Context(traps=[Inexact]))
+    try:
+        while True:
+            try:
+               return mantissa * Decimal(2) ** exponent
+            except Inexact:
+                getcontext().prec += 1
+    finally:
+        setcontext(oldcontext)
+\end{verbatim}
+
+
+Q.  Why isn't the \function{floatToDecimal()} routine included in the module?
+
+A.  There is some question about whether it is advisable to mix binary and
+decimal floating point.  Also, its use requires some care to avoid the
+representation issues associated with binary floating point:
+
+\begin{verbatim}
+>>> floatToDecimal(1.1)
+Decimal("1.100000000000000088817841970012523233890533447265625")
+\end{verbatim}
+
+
+Q.  Within a complex calculation, how can I make sure that I haven't gotten a
+spurious result because of insufficient precision or rounding anomalies.
+
+A.  The decimal module makes it easy to test results.  A best practice is to
+re-run calculations using greater precision and with various rounding modes.
+Widely differing results indicate insufficient precision, rounding mode
+issues, ill-conditioned inputs, or a numerically unstable algorithm.
+
+
+Q.  I noticed that context precision is applied to the results of operations
+but not to the inputs.  Is there anything to watch out for when mixing
+values of different precisions?
+
+A.  Yes.  The principle is that all values are considered to be exact and so
+is the arithmetic on those values.  Only the results are rounded.  The
+advantage for inputs is that ``what you type is what you get''.  A
+disadvantage is that the results can look odd if you forget that the inputs
+haven't been rounded:
+
+\begin{verbatim}
+>>> getcontext().prec = 3
+>>> Decimal('3.104') + D('2.104')
+Decimal("5.21")
+>>> Decimal('3.104') + D('0.000') + D('2.104')
+Decimal("5.20")
+\end{verbatim}
+
+The solution is either to increase precision or to force rounding of inputs
+using the unary plus operation:
+
+\begin{verbatim}
+>>> getcontext().prec = 3
+>>> +Decimal('1.23456789')      # unary plus triggers rounding
+Decimal("1.23")
+\end{verbatim}
+
+Alternatively, inputs can be rounded upon creation using the
+\method{Context.create_decimal()} method:
+
+\begin{verbatim}
+>>> Context(prec=5, rounding=ROUND_DOWN).create_decimal('1.2345678')
+Decimal("1.2345")
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/libdifflib.tex
===================================================================
--- vendor/Python/current/Doc/lib/libdifflib.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libdifflib.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,704 @@
+\section{\module{difflib} ---
+         Helpers for computing deltas}
+
+\declaremodule{standard}{difflib}
+\modulesynopsis{Helpers for computing differences between objects.}
+\moduleauthor{Tim Peters}{tim_one at users.sourceforge.net}
+\sectionauthor{Tim Peters}{tim_one at users.sourceforge.net}
+% LaTeXification by Fred L. Drake, Jr. <fdrake at acm.org>.
+
+\versionadded{2.1}
+
+
+\begin{classdesc*}{SequenceMatcher}
+  This is a flexible class for comparing pairs of sequences of any
+  type, so long as the sequence elements are hashable.  The basic
+  algorithm predates, and is a little fancier than, an algorithm
+  published in the late 1980's by Ratcliff and Obershelp under the
+  hyperbolic name ``gestalt pattern matching.''  The idea is to find
+  the longest contiguous matching subsequence that contains no
+  ``junk'' elements (the Ratcliff and Obershelp algorithm doesn't
+  address junk).  The same idea is then applied recursively to the
+  pieces of the sequences to the left and to the right of the matching
+  subsequence.  This does not yield minimal edit sequences, but does
+  tend to yield matches that ``look right'' to people.
+
+  \strong{Timing:} The basic Ratcliff-Obershelp algorithm is cubic
+  time in the worst case and quadratic time in the expected case.
+  \class{SequenceMatcher} is quadratic time for the worst case and has
+  expected-case behavior dependent in a complicated way on how many
+  elements the sequences have in common; best case time is linear.
+\end{classdesc*}
+
+\begin{classdesc*}{Differ}
+  This is a class for comparing sequences of lines of text, and
+  producing human-readable differences or deltas.  Differ uses
+  \class{SequenceMatcher} both to compare sequences of lines, and to
+  compare sequences of characters within similar (near-matching)
+  lines.
+
+  Each line of a \class{Differ} delta begins with a two-letter code:
+
+\begin{tableii}{l|l}{code}{Code}{Meaning}
+  \lineii{'- '}{line unique to sequence 1}
+  \lineii{'+ '}{line unique to sequence 2}
+  \lineii{'  '}{line common to both sequences}
+  \lineii{'? '}{line not present in either input sequence}
+\end{tableii}
+
+  Lines beginning with `\code{?~}' attempt to guide the eye to
+  intraline differences, and were not present in either input
+  sequence. These lines can be confusing if the sequences contain tab
+  characters.
+\end{classdesc*}
+
+\begin{classdesc*}{HtmlDiff}
+
+  This class can be used to create an HTML table (or a complete HTML file
+  containing the table) showing a side by side, line by line comparison
+  of text with inter-line and intra-line change highlights.  The table can
+  be generated in either full or contextual difference mode.
+
+  The constructor for this class is:
+
+  \begin{funcdesc}{__init__}{\optional{tabsize}\optional{,
+    wrapcolumn}\optional{, linejunk}\optional{, charjunk}}
+
+    Initializes instance of \class{HtmlDiff}.
+
+    \var{tabsize} is an optional keyword argument to specify tab stop spacing
+    and defaults to \code{8}.
+
+    \var{wrapcolumn} is an optional keyword to specify column number where
+    lines are broken and wrapped, defaults to \code{None} where lines are not
+    wrapped.
+
+    \var{linejunk} and \var{charjunk} are optional keyword arguments passed
+    into \code{ndiff()} (used by \class{HtmlDiff} to generate the
+    side by side HTML differences).  See \code{ndiff()} documentation for
+    argument default values and descriptions.
+
+  \end{funcdesc}
+
+  The following methods are public:
+
+  \begin{funcdesc}{make_file}{fromlines, tolines
+    \optional{, fromdesc}\optional{, todesc}\optional{, context}\optional{,
+    numlines}}
+    Compares \var{fromlines} and \var{tolines} (lists of strings) and returns
+    a string which is a complete HTML file containing a table showing line by
+    line differences with inter-line and intra-line changes highlighted.
+
+    \var{fromdesc} and \var{todesc} are optional keyword arguments to specify
+    from/to file column header strings (both default to an empty string).
+
+    \var{context} and \var{numlines} are both optional keyword arguments.
+    Set \var{context} to \code{True} when contextual differences are to be
+    shown, else the default is \code{False} to show the full files.
+    \var{numlines} defaults to \code{5}.  When \var{context} is \code{True}
+    \var{numlines} controls the number of context lines which surround the
+    difference highlights.  When \var{context} is \code{False} \var{numlines}
+    controls the number of lines which are shown before a difference
+    highlight when using the "next" hyperlinks (setting to zero would cause
+    the "next" hyperlinks to place the next difference highlight at the top of
+    the browser without any leading context).
+  \end{funcdesc}
+
+  \begin{funcdesc}{make_table}{fromlines, tolines
+    \optional{, fromdesc}\optional{, todesc}\optional{, context}\optional{,
+    numlines}}
+    Compares \var{fromlines} and \var{tolines} (lists of strings) and returns
+    a string which is a complete HTML table showing line by line differences
+    with inter-line and intra-line changes highlighted.
+
+    The arguments for this method are the same as those for the
+    \method{make_file()} method.
+  \end{funcdesc}
+
+  \file{Tools/scripts/diff.py} is a command-line front-end to this class
+  and contains a good example of its use.
+
+  \versionadded{2.4}
+\end{classdesc*}
+
+\begin{funcdesc}{context_diff}{a, b\optional{, fromfile}\optional{,
+    tofile}\optional{, fromfiledate}\optional{, tofiledate}\optional{,
+    n}\optional{, lineterm}}
+  Compare \var{a} and \var{b} (lists of strings); return a
+  delta (a generator generating the delta lines) in context diff
+  format.
+
+  Context diffs are a compact way of showing just the lines that have
+  changed plus a few lines of context.  The changes are shown in a
+  before/after style.  The number of context lines is set by \var{n}
+  which defaults to three.
+
+  By default, the diff control lines (those with \code{***} or \code{---})
+  are created with a trailing newline.  This is helpful so that inputs created
+  from \function{file.readlines()} result in diffs that are suitable for use
+  with \function{file.writelines()} since both the inputs and outputs have
+  trailing newlines.
+
+  For inputs that do not have trailing newlines, set the \var{lineterm}
+  argument to \code{""} so that the output will be uniformly newline free.
+
+  The context diff format normally has a header for filenames and
+  modification times.  Any or all of these may be specified using strings for
+  \var{fromfile}, \var{tofile}, \var{fromfiledate}, and \var{tofiledate}.
+  The modification times are normally expressed in the format returned by
+  \function{time.ctime()}.  If not specified, the strings default to blanks.
+
+  \file{Tools/scripts/diff.py} is a command-line front-end for this
+  function.
+
+  \versionadded{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{get_close_matches}{word, possibilities\optional{,
+                 n}\optional{, cutoff}}
+  Return a list of the best ``good enough'' matches.  \var{word} is a
+  sequence for which close matches are desired (typically a string),
+  and \var{possibilities} is a list of sequences against which to
+  match \var{word} (typically a list of strings).
+
+  Optional argument \var{n} (default \code{3}) is the maximum number
+  of close matches to return; \var{n} must be greater than \code{0}.
+
+  Optional argument \var{cutoff} (default \code{0.6}) is a float in
+  the range [0, 1].  Possibilities that don't score at least that
+  similar to \var{word} are ignored.
+
+  The best (no more than \var{n}) matches among the possibilities are
+  returned in a list, sorted by similarity score, most similar first.
+
+\begin{verbatim}
+>>> get_close_matches('appel', ['ape', 'apple', 'peach', 'puppy'])
+['apple', 'ape']
+>>> import keyword
+>>> get_close_matches('wheel', keyword.kwlist)
+['while']
+>>> get_close_matches('apple', keyword.kwlist)
+[]
+>>> get_close_matches('accept', keyword.kwlist)
+['except']
+\end{verbatim}
+\end{funcdesc}
+
+\begin{funcdesc}{ndiff}{a, b\optional{, linejunk}\optional{, charjunk}}
+  Compare \var{a} and \var{b} (lists of strings); return a
+  \class{Differ}-style delta (a generator generating the delta lines).
+
+  Optional keyword parameters \var{linejunk} and \var{charjunk} are
+  for filter functions (or \code{None}):
+
+  \var{linejunk}: A function that accepts a single string
+  argument, and returns true if the string is junk, or false if not.
+  The default is (\code{None}), starting with Python 2.3.  Before then,
+  the default was the module-level function
+  \function{IS_LINE_JUNK()}, which filters out lines without visible
+  characters, except for at most one pound character (\character{\#}).
+  As of Python 2.3, the underlying \class{SequenceMatcher} class
+  does a dynamic analysis of which lines are so frequent as to
+  constitute noise, and this usually works better than the pre-2.3
+  default.
+
+  \var{charjunk}: A function that accepts a character (a string of
+  length 1), and returns if the character is junk, or false if not.
+  The default is module-level function \function{IS_CHARACTER_JUNK()},
+  which filters out whitespace characters (a blank or tab; note: bad
+  idea to include newline in this!).
+
+  \file{Tools/scripts/ndiff.py} is a command-line front-end to this
+  function.
+
+\begin{verbatim}
+>>> diff = ndiff('one\ntwo\nthree\n'.splitlines(1),
+...              'ore\ntree\nemu\n'.splitlines(1))
+>>> print ''.join(diff),
+- one
+?  ^
++ ore
+?  ^
+- two
+- three
+?  -
++ tree
++ emu
+\end{verbatim}
+\end{funcdesc}
+
+\begin{funcdesc}{restore}{sequence, which}
+  Return one of the two sequences that generated a delta.
+
+  Given a \var{sequence} produced by \method{Differ.compare()} or
+  \function{ndiff()}, extract lines originating from file 1 or 2
+  (parameter \var{which}), stripping off line prefixes.
+
+  Example:
+
+\begin{verbatim}
+>>> diff = ndiff('one\ntwo\nthree\n'.splitlines(1),
+...              'ore\ntree\nemu\n'.splitlines(1))
+>>> diff = list(diff) # materialize the generated delta into a list
+>>> print ''.join(restore(diff, 1)),
+one
+two
+three
+>>> print ''.join(restore(diff, 2)),
+ore
+tree
+emu
+\end{verbatim}
+
+\end{funcdesc}
+
+\begin{funcdesc}{unified_diff}{a, b\optional{, fromfile}\optional{,
+    tofile}\optional{, fromfiledate}\optional{, tofiledate}\optional{,
+    n}\optional{, lineterm}}
+  Compare \var{a} and \var{b} (lists of strings); return a
+  delta (a generator generating the delta lines) in unified diff
+  format.
+
+  Unified diffs are a compact way of showing just the lines that have
+  changed plus a few lines of context.  The changes are shown in a
+  inline style (instead of separate before/after blocks).  The number
+  of context lines is set by \var{n} which defaults to three.
+
+  By default, the diff control lines (those with \code{---}, \code{+++},
+  or \code{@@}) are created with a trailing newline.  This is helpful so
+  that inputs created from \function{file.readlines()} result in diffs
+  that are suitable for use with \function{file.writelines()} since both
+  the inputs and outputs have trailing newlines.
+
+  For inputs that do not have trailing newlines, set the \var{lineterm}
+  argument to \code{""} so that the output will be uniformly newline free.
+
+  The context diff format normally has a header for filenames and
+  modification times.  Any or all of these may be specified using strings for
+  \var{fromfile}, \var{tofile}, \var{fromfiledate}, and \var{tofiledate}.
+  The modification times are normally expressed in the format returned by
+  \function{time.ctime()}.  If not specified, the strings default to blanks.
+
+  \file{Tools/scripts/diff.py} is a command-line front-end for this
+  function.
+
+  \versionadded{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{IS_LINE_JUNK}{line}
+  Return true for ignorable lines.  The line \var{line} is ignorable
+  if \var{line} is blank or contains a single \character{\#},
+  otherwise it is not ignorable.  Used as a default for parameter
+  \var{linejunk} in \function{ndiff()} before Python 2.3.
+\end{funcdesc}
+
+
+\begin{funcdesc}{IS_CHARACTER_JUNK}{ch}
+  Return true for ignorable characters.  The character \var{ch} is
+  ignorable if \var{ch} is a space or tab, otherwise it is not
+  ignorable.  Used as a default for parameter \var{charjunk} in
+  \function{ndiff()}.
+\end{funcdesc}
+
+
+\begin{seealso}
+  \seetitle[http://www.ddj.com/documents/s=1103/ddj8807c/]
+           {Pattern Matching: The Gestalt Approach}{Discussion of a
+            similar algorithm by John W. Ratcliff and D. E. Metzener.
+            This was published in
+            \citetitle[http://www.ddj.com/]{Dr. Dobb's Journal} in
+            July, 1988.}
+\end{seealso}
+
+
+\subsection{SequenceMatcher Objects \label{sequence-matcher}}
+
+The \class{SequenceMatcher} class has this constructor:
+
+\begin{classdesc}{SequenceMatcher}{\optional{isjunk\optional{,
+                                   a\optional{, b}}}}
+  Optional argument \var{isjunk} must be \code{None} (the default) or
+  a one-argument function that takes a sequence element and returns
+  true if and only if the element is ``junk'' and should be ignored.
+  Passing \code{None} for \var{isjunk} is equivalent to passing
+  \code{lambda x: 0}; in other words, no elements are ignored.  For
+  example, pass:
+
+\begin{verbatim}
+lambda x: x in " \t"
+\end{verbatim}
+
+  if you're comparing lines as sequences of characters, and don't want
+  to synch up on blanks or hard tabs.
+
+  The optional arguments \var{a} and \var{b} are sequences to be
+  compared; both default to empty strings.  The elements of both
+  sequences must be hashable.
+\end{classdesc}
+
+
+\class{SequenceMatcher} objects have the following methods:
+
+\begin{methoddesc}{set_seqs}{a, b}
+  Set the two sequences to be compared.
+\end{methoddesc}
+
+\class{SequenceMatcher} computes and caches detailed information about
+the second sequence, so if you want to compare one sequence against
+many sequences, use \method{set_seq2()} to set the commonly used
+sequence once and call \method{set_seq1()} repeatedly, once for each
+of the other sequences.
+
+\begin{methoddesc}{set_seq1}{a}
+  Set the first sequence to be compared.  The second sequence to be
+  compared is not changed.
+\end{methoddesc}
+
+\begin{methoddesc}{set_seq2}{b}
+  Set the second sequence to be compared.  The first sequence to be
+  compared is not changed.
+\end{methoddesc}
+
+\begin{methoddesc}{find_longest_match}{alo, ahi, blo, bhi}
+  Find longest matching block in \code{\var{a}[\var{alo}:\var{ahi}]}
+  and \code{\var{b}[\var{blo}:\var{bhi}]}.
+
+  If \var{isjunk} was omitted or \code{None},
+  \method{get_longest_match()} returns \code{(\var{i}, \var{j},
+  \var{k})} such that \code{\var{a}[\var{i}:\var{i}+\var{k}]} is equal
+  to \code{\var{b}[\var{j}:\var{j}+\var{k}]}, where
+      \code{\var{alo} <= \var{i} <= \var{i}+\var{k} <= \var{ahi}} and
+      \code{\var{blo} <= \var{j} <= \var{j}+\var{k} <= \var{bhi}}.
+  For all \code{(\var{i'}, \var{j'}, \var{k'})} meeting those
+  conditions, the additional conditions
+      \code{\var{k} >= \var{k'}},
+      \code{\var{i} <= \var{i'}},
+      and if \code{\var{i} == \var{i'}}, \code{\var{j} <= \var{j'}}
+  are also met.
+  In other words, of all maximal matching blocks, return one that
+  starts earliest in \var{a}, and of all those maximal matching blocks
+  that start earliest in \var{a}, return the one that starts earliest
+  in \var{b}.
+
+\begin{verbatim}
+>>> s = SequenceMatcher(None, " abcd", "abcd abcd")
+>>> s.find_longest_match(0, 5, 0, 9)
+(0, 4, 5)
+\end{verbatim}
+
+  If \var{isjunk} was provided, first the longest matching block is
+  determined as above, but with the additional restriction that no
+  junk element appears in the block.  Then that block is extended as
+  far as possible by matching (only) junk elements on both sides.
+  So the resulting block never matches on junk except as identical
+  junk happens to be adjacent to an interesting match.
+
+  Here's the same example as before, but considering blanks to be junk.
+  That prevents \code{' abcd'} from matching the \code{' abcd'} at the
+  tail end of the second sequence directly.  Instead only the
+  \code{'abcd'} can match, and matches the leftmost \code{'abcd'} in
+  the second sequence:
+
+\begin{verbatim}
+>>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
+>>> s.find_longest_match(0, 5, 0, 9)
+(1, 0, 4)
+\end{verbatim}
+
+  If no blocks match, this returns \code{(\var{alo}, \var{blo}, 0)}.
+\end{methoddesc}
+
+\begin{methoddesc}{get_matching_blocks}{}
+  Return list of triples describing matching subsequences.
+  Each triple is of the form \code{(\var{i}, \var{j}, \var{n})}, and
+  means that \code{\var{a}[\var{i}:\var{i}+\var{n}] ==
+  \var{b}[\var{j}:\var{j}+\var{n}]}.  The triples are monotonically
+  increasing in \var{i} and \var{j}.
+
+  The last triple is a dummy, and has the value \code{(len(\var{a}),
+  len(\var{b}), 0)}.  It is the only triple with \code{\var{n} == 0}.
+  % Explain why a dummy is used!
+
+  If
+  \code{(\var{i}, \var{j}, \var{n})} and
+  \code{(\var{i'}, \var{j'}, \var{n'})} are adjacent triples in the list,
+  and the second is not the last triple in the list, then
+  \code{\var{i}+\var{n} != \var{i'}} or
+  \code{\var{j}+\var{n} != \var{j'}}; in other words, adjacent triples
+  always describe non-adjacent equal blocks.
+  \versionchanged[The guarantee that adjacent triples always describe
+                  non-adjacent blocks was implemented]{2.5}
+
+\begin{verbatim}
+>>> s = SequenceMatcher(None, "abxcd", "abcd")
+>>> s.get_matching_blocks()
+[(0, 0, 2), (3, 2, 2), (5, 4, 0)]
+\end{verbatim}
+\end{methoddesc}
+
+\begin{methoddesc}{get_opcodes}{}
+  Return list of 5-tuples describing how to turn \var{a} into \var{b}.
+  Each tuple is of the form \code{(\var{tag}, \var{i1}, \var{i2},
+  \var{j1}, \var{j2})}.  The first tuple has \code{\var{i1} ==
+  \var{j1} == 0}, and remaining tuples have \var{i1} equal to the
+  \var{i2} from the preceding tuple, and, likewise, \var{j1} equal to
+  the previous \var{j2}.
+
+  The \var{tag} values are strings, with these meanings:
+
+\begin{tableii}{l|l}{code}{Value}{Meaning}
+  \lineii{'replace'}{\code{\var{a}[\var{i1}:\var{i2}]} should be
+                     replaced by \code{\var{b}[\var{j1}:\var{j2}]}.}
+  \lineii{'delete'}{\code{\var{a}[\var{i1}:\var{i2}]} should be
+                    deleted.  Note that \code{\var{j1} == \var{j2}} in
+                    this case.}
+  \lineii{'insert'}{\code{\var{b}[\var{j1}:\var{j2}]} should be
+                    inserted at \code{\var{a}[\var{i1}:\var{i1}]}.
+                    Note that \code{\var{i1} == \var{i2}} in this
+                    case.}
+  \lineii{'equal'}{\code{\var{a}[\var{i1}:\var{i2}] ==
+                   \var{b}[\var{j1}:\var{j2}]} (the sub-sequences are
+                   equal).}
+\end{tableii}
+
+For example:
+
+\begin{verbatim}
+>>> a = "qabxcd"
+>>> b = "abycdf"
+>>> s = SequenceMatcher(None, a, b)
+>>> for tag, i1, i2, j1, j2 in s.get_opcodes():
+...    print ("%7s a[%d:%d] (%s) b[%d:%d] (%s)" %
+...           (tag, i1, i2, a[i1:i2], j1, j2, b[j1:j2]))
+ delete a[0:1] (q) b[0:0] ()
+  equal a[1:3] (ab) b[0:2] (ab)
+replace a[3:4] (x) b[2:3] (y)
+  equal a[4:6] (cd) b[3:5] (cd)
+ insert a[6:6] () b[5:6] (f)
+\end{verbatim}
+\end{methoddesc}
+
+\begin{methoddesc}{get_grouped_opcodes}{\optional{n}}
+  Return a generator of groups with up to \var{n} lines of context.
+
+  Starting with the groups returned by \method{get_opcodes()},
+  this method splits out smaller change clusters and eliminates
+  intervening ranges which have no changes.
+
+  The groups are returned in the same format as \method{get_opcodes()}.
+  \versionadded{2.3}
+\end{methoddesc}
+
+\begin{methoddesc}{ratio}{}
+  Return a measure of the sequences' similarity as a float in the
+  range [0, 1].
+
+  Where T is the total number of elements in both sequences, and M is
+  the number of matches, this is 2.0*M / T. Note that this is
+  \code{1.0} if the sequences are identical, and \code{0.0} if they
+  have nothing in common.
+
+  This is expensive to compute if \method{get_matching_blocks()} or
+  \method{get_opcodes()} hasn't already been called, in which case you
+  may want to try \method{quick_ratio()} or
+  \method{real_quick_ratio()} first to get an upper bound.
+\end{methoddesc}
+
+\begin{methoddesc}{quick_ratio}{}
+  Return an upper bound on \method{ratio()} relatively quickly.
+
+  This isn't defined beyond that it is an upper bound on
+  \method{ratio()}, and is faster to compute.
+\end{methoddesc}
+
+\begin{methoddesc}{real_quick_ratio}{}
+  Return an upper bound on \method{ratio()} very quickly.
+
+  This isn't defined beyond that it is an upper bound on
+  \method{ratio()}, and is faster to compute than either
+  \method{ratio()} or \method{quick_ratio()}.
+\end{methoddesc}
+
+The three methods that return the ratio of matching to total characters
+can give different results due to differing levels of approximation,
+although \method{quick_ratio()} and \method{real_quick_ratio()} are always
+at least as large as \method{ratio()}:
+
+\begin{verbatim}
+>>> s = SequenceMatcher(None, "abcd", "bcde")
+>>> s.ratio()
+0.75
+>>> s.quick_ratio()
+0.75
+>>> s.real_quick_ratio()
+1.0
+\end{verbatim}
+
+
+\subsection{SequenceMatcher Examples \label{sequencematcher-examples}}
+
+
+This example compares two strings, considering blanks to be ``junk:''
+
+\begin{verbatim}
+>>> s = SequenceMatcher(lambda x: x == " ",
+...                     "private Thread currentThread;",
+...                     "private volatile Thread currentThread;")
+\end{verbatim}
+
+\method{ratio()} returns a float in [0, 1], measuring the similarity
+of the sequences.  As a rule of thumb, a \method{ratio()} value over
+0.6 means the sequences are close matches:
+
+\begin{verbatim}
+>>> print round(s.ratio(), 3)
+0.866
+\end{verbatim}
+
+If you're only interested in where the sequences match,
+\method{get_matching_blocks()} is handy:
+
+\begin{verbatim}
+>>> for block in s.get_matching_blocks():
+...     print "a[%d] and b[%d] match for %d elements" % block
+a[0] and b[0] match for 8 elements
+a[8] and b[17] match for 6 elements
+a[14] and b[23] match for 15 elements
+a[29] and b[38] match for 0 elements
+\end{verbatim}
+
+Note that the last tuple returned by \method{get_matching_blocks()} is
+always a dummy, \code{(len(\var{a}), len(\var{b}), 0)}, and this is
+the only case in which the last tuple element (number of elements
+matched) is \code{0}.
+
+If you want to know how to change the first sequence into the second,
+use \method{get_opcodes()}:
+
+\begin{verbatim}
+>>> for opcode in s.get_opcodes():
+...     print "%6s a[%d:%d] b[%d:%d]" % opcode
+ equal a[0:8] b[0:8]
+insert a[8:8] b[8:17]
+ equal a[8:14] b[17:23]
+ equal a[14:29] b[23:38]
+\end{verbatim}
+
+See also the function \function{get_close_matches()} in this module,
+which shows how simple code building on \class{SequenceMatcher} can be
+used to do useful work.
+
+
+\subsection{Differ Objects \label{differ-objects}}
+
+Note that \class{Differ}-generated deltas make no claim to be
+\strong{minimal} diffs. To the contrary, minimal diffs are often
+counter-intuitive, because they synch up anywhere possible, sometimes
+accidental matches 100 pages apart. Restricting synch points to
+contiguous matches preserves some notion of locality, at the
+occasional cost of producing a longer diff.
+
+The \class{Differ} class has this constructor:
+
+\begin{classdesc}{Differ}{\optional{linejunk\optional{, charjunk}}}
+  Optional keyword parameters \var{linejunk} and \var{charjunk} are
+  for filter functions (or \code{None}):
+
+  \var{linejunk}: A function that accepts a single string
+  argument, and returns true if the string is junk.  The default is
+  \code{None}, meaning that no line is considered junk.
+
+  \var{charjunk}: A function that accepts a single character argument
+  (a string of length 1), and returns true if the character is junk.
+  The default is \code{None}, meaning that no character is
+  considered junk.
+\end{classdesc}
+
+\class{Differ} objects are used (deltas generated) via a single
+method:
+
+\begin{methoddesc}{compare}{a, b}
+  Compare two sequences of lines, and generate the delta (a sequence
+  of lines).
+
+  Each sequence must contain individual single-line strings ending
+  with newlines. Such sequences can be obtained from the
+  \method{readlines()} method of file-like objects.  The delta generated
+  also consists of newline-terminated strings, ready to be printed as-is
+  via the \method{writelines()} method of a file-like object.
+\end{methoddesc}
+
+
+\subsection{Differ Example \label{differ-examples}}
+
+This example compares two texts. First we set up the texts, sequences
+of individual single-line strings ending with newlines (such sequences
+can also be obtained from the \method{readlines()} method of file-like
+objects):
+
+\begin{verbatim}
+>>> text1 = '''  1. Beautiful is better than ugly.
+...   2. Explicit is better than implicit.
+...   3. Simple is better than complex.
+...   4. Complex is better than complicated.
+... '''.splitlines(1)
+>>> len(text1)
+4
+>>> text1[0][-1]
+'\n'
+>>> text2 = '''  1. Beautiful is better than ugly.
+...   3.   Simple is better than complex.
+...   4. Complicated is better than complex.
+...   5. Flat is better than nested.
+... '''.splitlines(1)
+\end{verbatim}
+
+Next we instantiate a Differ object:
+
+\begin{verbatim}
+>>> d = Differ()
+\end{verbatim}
+
+Note that when instantiating a \class{Differ} object we may pass
+functions to filter out line and character ``junk.''  See the
+\method{Differ()} constructor for details.
+
+Finally, we compare the two:
+
+\begin{verbatim}
+>>> result = list(d.compare(text1, text2))
+\end{verbatim}
+
+\code{result} is a list of strings, so let's pretty-print it:
+
+\begin{verbatim}
+>>> from pprint import pprint
+>>> pprint(result)
+['    1. Beautiful is better than ugly.\n',
+ '-   2. Explicit is better than implicit.\n',
+ '-   3. Simple is better than complex.\n',
+ '+   3.   Simple is better than complex.\n',
+ '?     ++                                \n',
+ '-   4. Complex is better than complicated.\n',
+ '?            ^                     ---- ^  \n',
+ '+   4. Complicated is better than complex.\n',
+ '?           ++++ ^                      ^  \n',
+ '+   5. Flat is better than nested.\n']
+\end{verbatim}
+
+As a single multi-line string it looks like this:
+
+\begin{verbatim}
+>>> import sys
+>>> sys.stdout.writelines(result)
+    1. Beautiful is better than ugly.
+-   2. Explicit is better than implicit.
+-   3. Simple is better than complex.
++   3.   Simple is better than complex.
+?     ++
+-   4. Complex is better than complicated.
+?            ^                     ---- ^
++   4. Complicated is better than complex.
+?           ++++ ^                      ^
++   5. Flat is better than nested.
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/libdircache.tex
===================================================================
--- vendor/Python/current/Doc/lib/libdircache.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libdircache.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,49 @@
+\section{\module{dircache} ---
+         Cached directory listings}
+
+\declaremodule{standard}{dircache}
+\sectionauthor{Moshe Zadka}{moshez at zadka.site.co.il}
+\modulesynopsis{Return directory listing, with cache mechanism.}
+
+The \module{dircache} module defines a function for reading directory listing
+using a cache, and cache invalidation using the \var{mtime} of the directory.
+Additionally, it defines a function to annotate directories by appending
+a slash.
+
+The \module{dircache} module defines the following functions:
+
+\begin{funcdesc}{reset}{}
+Resets the directory cache.
+\end{funcdesc}
+
+\begin{funcdesc}{listdir}{path}
+Return a directory listing of \var{path}, as gotten from
+\function{os.listdir()}. Note that unless \var{path} changes, further call
+to \function{listdir()} will not re-read the directory structure.
+
+Note that the list returned should be regarded as read-only. (Perhaps
+a future version should change it to return a tuple?)
+\end{funcdesc}
+
+\begin{funcdesc}{opendir}{path}
+Same as \function{listdir()}. Defined for backwards compatibility.
+\end{funcdesc}
+
+\begin{funcdesc}{annotate}{head, list}
+Assume \var{list} is a list of paths relative to \var{head}, and append,
+in place, a \character{/} to each path which points to a directory.
+\end{funcdesc}
+
+\begin{verbatim}
+>>> import dircache
+>>> a = dircache.listdir('/')
+>>> a = a[:] # Copy the return value so we can change 'a'
+>>> a
+['bin', 'boot', 'cdrom', 'dev', 'etc', 'floppy', 'home', 'initrd', 'lib', 'lost+
+found', 'mnt', 'proc', 'root', 'sbin', 'tmp', 'usr', 'var', 'vmlinuz']
+>>> dircache.annotate('/', a)
+>>> a
+['bin/', 'boot/', 'cdrom/', 'dev/', 'etc/', 'floppy/', 'home/', 'initrd/', 'lib/
+', 'lost+found/', 'mnt/', 'proc/', 'root/', 'sbin/', 'tmp/', 'usr/', 'var/', 'vm
+linuz']
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/libdis.tex
===================================================================
--- vendor/Python/current/Doc/lib/libdis.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libdis.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,706 @@
+\section{\module{dis} ---
+         Disassembler for Python byte code}
+
+\declaremodule{standard}{dis}
+\modulesynopsis{Disassembler for Python byte code.}
+
+
+The \module{dis} module supports the analysis of Python byte code by
+disassembling it.  Since there is no Python assembler, this module
+defines the Python assembly language.  The Python byte code which
+this module takes as an input is defined in the file 
+\file{Include/opcode.h} and used by the compiler and the interpreter.
+
+Example: Given the function \function{myfunc}:
+
+\begin{verbatim}
+def myfunc(alist):
+    return len(alist)
+\end{verbatim}
+
+the following command can be used to get the disassembly of
+\function{myfunc()}:
+
+\begin{verbatim}
+>>> dis.dis(myfunc)
+  2           0 LOAD_GLOBAL              0 (len)
+              3 LOAD_FAST                0 (alist)
+              6 CALL_FUNCTION            1
+              9 RETURN_VALUE
+\end{verbatim}
+
+(The ``2'' is a line number).
+
+The \module{dis} module defines the following functions and constants:
+
+\begin{funcdesc}{dis}{\optional{bytesource}}
+Disassemble the \var{bytesource} object. \var{bytesource} can denote
+either a module, a class, a method, a function, or a code object.  
+For a module, it disassembles all functions.  For a class,
+it disassembles all methods.  For a single code sequence, it prints
+one line per byte code instruction.  If no object is provided, it
+disassembles the last traceback.
+\end{funcdesc}
+
+\begin{funcdesc}{distb}{\optional{tb}}
+Disassembles the top-of-stack function of a traceback, using the last
+traceback if none was passed.  The instruction causing the exception
+is indicated.
+\end{funcdesc}
+
+\begin{funcdesc}{disassemble}{code\optional{, lasti}}
+Disassembles a code object, indicating the last instruction if \var{lasti}
+was provided.  The output is divided in the following columns:
+
+\begin{enumerate}
+\item the line number, for the first instruction of each line
+\item the current instruction, indicated as \samp{-->},
+\item a labelled instruction, indicated with \samp{>>},
+\item the address of the instruction,
+\item the operation code name,
+\item operation parameters, and
+\item interpretation of the parameters in parentheses.
+\end{enumerate}
+
+The parameter interpretation recognizes local and global
+variable names, constant values, branch targets, and compare
+operators.
+\end{funcdesc}
+
+\begin{funcdesc}{disco}{code\optional{, lasti}}
+A synonym for disassemble.  It is more convenient to type, and kept
+for compatibility with earlier Python releases.
+\end{funcdesc}
+
+\begin{datadesc}{opname}
+Sequence of operation names, indexable using the byte code.
+\end{datadesc}
+
+\begin{datadesc}{opmap}
+Dictionary mapping byte codes to operation names.
+\end{datadesc}
+
+\begin{datadesc}{cmp_op}
+Sequence of all compare operation names.
+\end{datadesc}
+
+\begin{datadesc}{hasconst}
+Sequence of byte codes that have a constant parameter.
+\end{datadesc}
+
+\begin{datadesc}{hasfree}
+Sequence of byte codes that access a free variable.
+\end{datadesc}
+
+\begin{datadesc}{hasname}
+Sequence of byte codes that access an attribute by name.
+\end{datadesc}
+
+\begin{datadesc}{hasjrel}
+Sequence of byte codes that have a relative jump target.
+\end{datadesc}
+
+\begin{datadesc}{hasjabs}
+Sequence of byte codes that have an absolute jump target.
+\end{datadesc}
+
+\begin{datadesc}{haslocal}
+Sequence of byte codes that access a local variable.
+\end{datadesc}
+
+\begin{datadesc}{hascompare}
+Sequence of byte codes of Boolean operations.
+\end{datadesc}
+
+\subsection{Python Byte Code Instructions}
+\label{bytecodes}
+
+The Python compiler currently generates the following byte code
+instructions.
+
+\setindexsubitem{(byte code insns)}
+
+\begin{opcodedesc}{STOP_CODE}{}
+Indicates end-of-code to the compiler, not used by the interpreter.
+\end{opcodedesc}
+
+\begin{opcodedesc}{NOP}{}
+Do nothing code.  Used as a placeholder by the bytecode optimizer.
+\end{opcodedesc}
+
+\begin{opcodedesc}{POP_TOP}{}
+Removes the top-of-stack (TOS) item.
+\end{opcodedesc}
+
+\begin{opcodedesc}{ROT_TWO}{}
+Swaps the two top-most stack items.
+\end{opcodedesc}
+
+\begin{opcodedesc}{ROT_THREE}{}
+Lifts second and third stack item one position up, moves top down
+to position three.
+\end{opcodedesc}
+
+\begin{opcodedesc}{ROT_FOUR}{}
+Lifts second, third and forth stack item one position up, moves top down to
+position four.
+\end{opcodedesc}
+
+\begin{opcodedesc}{DUP_TOP}{}
+Duplicates the reference on top of the stack.
+\end{opcodedesc}
+
+Unary Operations take the top of the stack, apply the operation, and
+push the result back on the stack.
+
+\begin{opcodedesc}{UNARY_POSITIVE}{}
+Implements \code{TOS = +TOS}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{UNARY_NEGATIVE}{}
+Implements \code{TOS = -TOS}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{UNARY_NOT}{}
+Implements \code{TOS = not TOS}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{UNARY_CONVERT}{}
+Implements \code{TOS = `TOS`}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{UNARY_INVERT}{}
+Implements \code{TOS = \~{}TOS}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{GET_ITER}{}
+Implements \code{TOS = iter(TOS)}.
+\end{opcodedesc}
+
+Binary operations remove the top of the stack (TOS) and the second top-most
+stack item (TOS1) from the stack.  They perform the operation, and put the
+result back on the stack.
+
+\begin{opcodedesc}{BINARY_POWER}{}
+Implements \code{TOS = TOS1 ** TOS}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{BINARY_MULTIPLY}{}
+Implements \code{TOS = TOS1 * TOS}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{BINARY_DIVIDE}{}
+Implements \code{TOS = TOS1 / TOS} when
+\code{from __future__ import division} is not in effect.
+\end{opcodedesc}
+
+\begin{opcodedesc}{BINARY_FLOOR_DIVIDE}{}
+Implements \code{TOS = TOS1 // TOS}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{BINARY_TRUE_DIVIDE}{}
+Implements \code{TOS = TOS1 / TOS} when
+\code{from __future__ import division} is in effect.
+\end{opcodedesc}
+
+\begin{opcodedesc}{BINARY_MODULO}{}
+Implements \code{TOS = TOS1 \%{} TOS}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{BINARY_ADD}{}
+Implements \code{TOS = TOS1 + TOS}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{BINARY_SUBTRACT}{}
+Implements \code{TOS = TOS1 - TOS}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{BINARY_SUBSCR}{}
+Implements \code{TOS = TOS1[TOS]}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{BINARY_LSHIFT}{}
+Implements \code{TOS = TOS1 <\code{}< TOS}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{BINARY_RSHIFT}{}
+Implements \code{TOS = TOS1 >\code{}> TOS}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{BINARY_AND}{}
+Implements \code{TOS = TOS1 \&\ TOS}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{BINARY_XOR}{}
+Implements \code{TOS = TOS1 \^\ TOS}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{BINARY_OR}{}
+Implements \code{TOS = TOS1 | TOS}.
+\end{opcodedesc}
+
+In-place operations are like binary operations, in that they remove TOS and
+TOS1, and push the result back on the stack, but the operation is done
+in-place when TOS1 supports it, and the resulting TOS may be (but does not
+have to be) the original TOS1.
+
+\begin{opcodedesc}{INPLACE_POWER}{}
+Implements in-place \code{TOS = TOS1 ** TOS}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{INPLACE_MULTIPLY}{}
+Implements in-place \code{TOS = TOS1 * TOS}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{INPLACE_DIVIDE}{}
+Implements in-place \code{TOS = TOS1 / TOS} when
+\code{from __future__ import division} is not in effect.
+\end{opcodedesc}
+
+\begin{opcodedesc}{INPLACE_FLOOR_DIVIDE}{}
+Implements in-place \code{TOS = TOS1 // TOS}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{INPLACE_TRUE_DIVIDE}{}
+Implements in-place \code{TOS = TOS1 / TOS} when
+\code{from __future__ import division} is in effect.
+\end{opcodedesc}
+
+\begin{opcodedesc}{INPLACE_MODULO}{}
+Implements in-place \code{TOS = TOS1 \%{} TOS}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{INPLACE_ADD}{}
+Implements in-place \code{TOS = TOS1 + TOS}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{INPLACE_SUBTRACT}{}
+Implements in-place \code{TOS = TOS1 - TOS}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{INPLACE_LSHIFT}{}
+Implements in-place \code{TOS = TOS1 <\code{}< TOS}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{INPLACE_RSHIFT}{}
+Implements in-place \code{TOS = TOS1 >\code{}> TOS}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{INPLACE_AND}{}
+Implements in-place \code{TOS = TOS1 \&\ TOS}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{INPLACE_XOR}{}
+Implements in-place \code{TOS = TOS1 \^\ TOS}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{INPLACE_OR}{}
+Implements in-place \code{TOS = TOS1 | TOS}.
+\end{opcodedesc}
+
+The slice opcodes take up to three parameters.
+
+\begin{opcodedesc}{SLICE+0}{}
+Implements \code{TOS = TOS[:]}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{SLICE+1}{}
+Implements \code{TOS = TOS1[TOS:]}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{SLICE+2}{}
+Implements \code{TOS = TOS1[:TOS]}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{SLICE+3}{}
+Implements \code{TOS = TOS2[TOS1:TOS]}.
+\end{opcodedesc}
+
+Slice assignment needs even an additional parameter.  As any statement,
+they put nothing on the stack.
+
+\begin{opcodedesc}{STORE_SLICE+0}{}
+Implements \code{TOS[:] = TOS1}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{STORE_SLICE+1}{}
+Implements \code{TOS1[TOS:] = TOS2}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{STORE_SLICE+2}{}
+Implements \code{TOS1[:TOS] = TOS2}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{STORE_SLICE+3}{}
+Implements \code{TOS2[TOS1:TOS] = TOS3}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{DELETE_SLICE+0}{}
+Implements \code{del TOS[:]}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{DELETE_SLICE+1}{}
+Implements \code{del TOS1[TOS:]}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{DELETE_SLICE+2}{}
+Implements \code{del TOS1[:TOS]}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{DELETE_SLICE+3}{}
+Implements \code{del TOS2[TOS1:TOS]}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{STORE_SUBSCR}{}
+Implements \code{TOS1[TOS] = TOS2}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{DELETE_SUBSCR}{}
+Implements \code{del TOS1[TOS]}.
+\end{opcodedesc}
+
+Miscellaneous opcodes.
+
+\begin{opcodedesc}{PRINT_EXPR}{}
+Implements the expression statement for the interactive mode.  TOS is
+removed from the stack and printed.  In non-interactive mode, an
+expression statement is terminated with \code{POP_STACK}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{PRINT_ITEM}{}
+Prints TOS to the file-like object bound to \code{sys.stdout}.  There
+is one such instruction for each item in the \keyword{print} statement.
+\end{opcodedesc}
+
+\begin{opcodedesc}{PRINT_ITEM_TO}{}
+Like \code{PRINT_ITEM}, but prints the item second from TOS to the
+file-like object at TOS.  This is used by the extended print statement.
+\end{opcodedesc}
+
+\begin{opcodedesc}{PRINT_NEWLINE}{}
+Prints a new line on \code{sys.stdout}.  This is generated as the
+last operation of a \keyword{print} statement, unless the statement
+ends with a comma.
+\end{opcodedesc}
+
+\begin{opcodedesc}{PRINT_NEWLINE_TO}{}
+Like \code{PRINT_NEWLINE}, but prints the new line on the file-like
+object on the TOS.  This is used by the extended print statement.
+\end{opcodedesc}
+
+\begin{opcodedesc}{BREAK_LOOP}{}
+Terminates a loop due to a \keyword{break} statement.
+\end{opcodedesc}
+
+\begin{opcodedesc}{CONTINUE_LOOP}{target}
+Continues a loop due to a \keyword{continue} statement.  \var{target}
+is the address to jump to (which should be a \code{FOR_ITER}
+instruction).
+\end{opcodedesc}
+
+\begin{opcodedesc}{LIST_APPEND}{}
+Calls \code{list.append(TOS1, TOS)}.  Used to implement list comprehensions.
+\end{opcodedesc}
+
+\begin{opcodedesc}{LOAD_LOCALS}{}
+Pushes a reference to the locals of the current scope on the stack.
+This is used in the code for a class definition: After the class body
+is evaluated, the locals are passed to the class definition.
+\end{opcodedesc}
+
+\begin{opcodedesc}{RETURN_VALUE}{}
+Returns with TOS to the caller of the function.
+\end{opcodedesc}
+
+\begin{opcodedesc}{YIELD_VALUE}{}
+Pops \code{TOS} and yields it from a generator.
+\end{opcodedesc}
+
+\begin{opcodedesc}{IMPORT_STAR}{}
+Loads all symbols not starting with \character{_} directly from the module TOS
+to the local namespace. The module is popped after loading all names.
+This opcode implements \code{from module import *}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{EXEC_STMT}{}
+Implements \code{exec TOS2,TOS1,TOS}.  The compiler fills
+missing optional parameters with \code{None}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{POP_BLOCK}{}
+Removes one block from the block stack.  Per frame, there is a 
+stack of blocks, denoting nested loops, try statements, and such.
+\end{opcodedesc}
+
+\begin{opcodedesc}{END_FINALLY}{}
+Terminates a \keyword{finally} clause.  The interpreter recalls
+whether the exception has to be re-raised, or whether the function
+returns, and continues with the outer-next block.
+\end{opcodedesc}
+
+\begin{opcodedesc}{BUILD_CLASS}{}
+Creates a new class object.  TOS is the methods dictionary, TOS1
+the tuple of the names of the base classes, and TOS2 the class name.
+\end{opcodedesc}
+
+All of the following opcodes expect arguments.  An argument is two
+bytes, with the more significant byte last.
+
+\begin{opcodedesc}{STORE_NAME}{namei}
+Implements \code{name = TOS}. \var{namei} is the index of \var{name}
+in the attribute \member{co_names} of the code object.
+The compiler tries to use \code{STORE_LOCAL} or \code{STORE_GLOBAL}
+if possible.
+\end{opcodedesc}
+
+\begin{opcodedesc}{DELETE_NAME}{namei}
+Implements \code{del name}, where \var{namei} is the index into
+\member{co_names} attribute of the code object.
+\end{opcodedesc}
+
+\begin{opcodedesc}{UNPACK_SEQUENCE}{count}
+Unpacks TOS into \var{count} individual values, which are put onto
+the stack right-to-left.
+\end{opcodedesc}
+
+%\begin{opcodedesc}{UNPACK_LIST}{count}
+%This opcode is obsolete.
+%\end{opcodedesc}
+
+%\begin{opcodedesc}{UNPACK_ARG}{count}
+%This opcode is obsolete.
+%\end{opcodedesc}
+
+\begin{opcodedesc}{DUP_TOPX}{count}
+Duplicate \var{count} items, keeping them in the same order. Due to
+implementation limits, \var{count} should be between 1 and 5 inclusive.
+\end{opcodedesc}
+
+\begin{opcodedesc}{STORE_ATTR}{namei}
+Implements \code{TOS.name = TOS1}, where \var{namei} is the index
+of name in \member{co_names}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{DELETE_ATTR}{namei}
+Implements \code{del TOS.name}, using \var{namei} as index into
+\member{co_names}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{STORE_GLOBAL}{namei}
+Works as \code{STORE_NAME}, but stores the name as a global.
+\end{opcodedesc}
+
+\begin{opcodedesc}{DELETE_GLOBAL}{namei}
+Works as \code{DELETE_NAME}, but deletes a global name.
+\end{opcodedesc}
+
+%\begin{opcodedesc}{UNPACK_VARARG}{argc}
+%This opcode is obsolete.
+%\end{opcodedesc}
+
+\begin{opcodedesc}{LOAD_CONST}{consti}
+Pushes \samp{co_consts[\var{consti}]} onto the stack.
+\end{opcodedesc}
+
+\begin{opcodedesc}{LOAD_NAME}{namei}
+Pushes the value associated with \samp{co_names[\var{namei}]} onto the stack.
+\end{opcodedesc}
+
+\begin{opcodedesc}{BUILD_TUPLE}{count}
+Creates a tuple consuming \var{count} items from the stack, and pushes
+the resulting tuple onto the stack.
+\end{opcodedesc}
+
+\begin{opcodedesc}{BUILD_LIST}{count}
+Works as \code{BUILD_TUPLE}, but creates a list.
+\end{opcodedesc}
+
+\begin{opcodedesc}{BUILD_MAP}{zero}
+Pushes a new empty dictionary object onto the stack.  The argument is
+ignored and set to zero by the compiler.
+\end{opcodedesc}
+
+\begin{opcodedesc}{LOAD_ATTR}{namei}
+Replaces TOS with \code{getattr(TOS, co_names[\var{namei}])}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{COMPARE_OP}{opname}
+Performs a Boolean operation.  The operation name can be found
+in \code{cmp_op[\var{opname}]}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{IMPORT_NAME}{namei}
+Imports the module \code{co_names[\var{namei}]}.  The module object is
+pushed onto the stack.  The current namespace is not affected: for a
+proper import statement, a subsequent \code{STORE_FAST} instruction
+modifies the namespace.
+\end{opcodedesc}
+
+\begin{opcodedesc}{IMPORT_FROM}{namei}
+Loads the attribute \code{co_names[\var{namei}]} from the module found in
+TOS. The resulting object is pushed onto the stack, to be subsequently
+stored by a \code{STORE_FAST} instruction.
+\end{opcodedesc}
+
+\begin{opcodedesc}{JUMP_FORWARD}{delta}
+Increments byte code counter by \var{delta}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{JUMP_IF_TRUE}{delta}
+If TOS is true, increment the byte code counter by \var{delta}.  TOS is
+left on the stack.
+\end{opcodedesc}
+
+\begin{opcodedesc}{JUMP_IF_FALSE}{delta}
+If TOS is false, increment the byte code counter by \var{delta}.  TOS
+is not changed. 
+\end{opcodedesc}
+
+\begin{opcodedesc}{JUMP_ABSOLUTE}{target}
+Set byte code counter to \var{target}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{FOR_ITER}{delta}
+\code{TOS} is an iterator.  Call its \method{next()} method.  If this
+yields a new value, push it on the stack (leaving the iterator below
+it).  If the iterator indicates it is exhausted  \code{TOS} is
+popped, and the byte code counter is incremented by \var{delta}.
+\end{opcodedesc}
+
+%\begin{opcodedesc}{FOR_LOOP}{delta}
+%This opcode is obsolete.
+%\end{opcodedesc}
+
+%\begin{opcodedesc}{LOAD_LOCAL}{namei}
+%This opcode is obsolete.
+%\end{opcodedesc}
+
+\begin{opcodedesc}{LOAD_GLOBAL}{namei}
+Loads the global named \code{co_names[\var{namei}]} onto the stack.
+\end{opcodedesc}
+
+%\begin{opcodedesc}{SET_FUNC_ARGS}{argc}
+%This opcode is obsolete.
+%\end{opcodedesc}
+
+\begin{opcodedesc}{SETUP_LOOP}{delta}
+Pushes a block for a loop onto the block stack.  The block spans
+from the current instruction with a size of \var{delta} bytes.
+\end{opcodedesc}
+
+\begin{opcodedesc}{SETUP_EXCEPT}{delta}
+Pushes a try block from a try-except clause onto the block stack.
+\var{delta} points to the first except block.
+\end{opcodedesc}
+
+\begin{opcodedesc}{SETUP_FINALLY}{delta}
+Pushes a try block from a try-except clause onto the block stack.
+\var{delta} points to the finally block.
+\end{opcodedesc}
+
+\begin{opcodedesc}{LOAD_FAST}{var_num}
+Pushes a reference to the local \code{co_varnames[\var{var_num}]} onto
+the stack.
+\end{opcodedesc}
+
+\begin{opcodedesc}{STORE_FAST}{var_num}
+Stores TOS into the local \code{co_varnames[\var{var_num}]}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{DELETE_FAST}{var_num}
+Deletes local \code{co_varnames[\var{var_num}]}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{LOAD_CLOSURE}{i}
+Pushes a reference to the cell contained in slot \var{i} of the
+cell and free variable storage.  The name of the variable is 
+\code{co_cellvars[\var{i}]} if \var{i} is less than the length of
+\var{co_cellvars}.  Otherwise it is 
+\code{co_freevars[\var{i} - len(co_cellvars)]}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{LOAD_DEREF}{i}
+Loads the cell contained in slot \var{i} of the cell and free variable
+storage.  Pushes a reference to the object the cell contains on the
+stack. 
+\end{opcodedesc}
+
+\begin{opcodedesc}{STORE_DEREF}{i}
+Stores TOS into the cell contained in slot \var{i} of the cell and
+free variable storage.
+\end{opcodedesc}
+
+\begin{opcodedesc}{SET_LINENO}{lineno}
+This opcode is obsolete.
+\end{opcodedesc}
+
+\begin{opcodedesc}{RAISE_VARARGS}{argc}
+Raises an exception. \var{argc} indicates the number of parameters
+to the raise statement, ranging from 0 to 3.  The handler will find
+the traceback as TOS2, the parameter as TOS1, and the exception
+as TOS.
+\end{opcodedesc}
+
+\begin{opcodedesc}{CALL_FUNCTION}{argc}
+Calls a function.  The low byte of \var{argc} indicates the number of
+positional parameters, the high byte the number of keyword parameters.
+On the stack, the opcode finds the keyword parameters first.  For each
+keyword argument, the value is on top of the key.  Below the keyword
+parameters, the positional parameters are on the stack, with the
+right-most parameter on top.  Below the parameters, the function object
+to call is on the stack.
+\end{opcodedesc}
+
+\begin{opcodedesc}{MAKE_FUNCTION}{argc}
+Pushes a new function object on the stack.  TOS is the code associated
+with the function.  The function object is defined to have \var{argc}
+default parameters, which are found below TOS.
+\end{opcodedesc}
+
+\begin{opcodedesc}{MAKE_CLOSURE}{argc}
+Creates a new function object, sets its \var{func_closure} slot, and
+pushes it on the stack.  TOS is the code associated with the function.
+If the code object has N free variables, the next N items on the stack
+are the cells for these variables.  The function also has \var{argc}
+default parameters, where are found before the cells.
+\end{opcodedesc}
+
+\begin{opcodedesc}{BUILD_SLICE}{argc}
+Pushes a slice object on the stack.  \var{argc} must be 2 or 3.  If it
+is 2, \code{slice(TOS1, TOS)} is pushed; if it is 3,
+\code{slice(TOS2, TOS1, TOS)} is pushed.
+See the \code{slice()}\bifuncindex{slice} built-in function for more
+information.
+\end{opcodedesc}
+
+\begin{opcodedesc}{EXTENDED_ARG}{ext}
+Prefixes any opcode which has an argument too big to fit into the
+default two bytes.  \var{ext} holds two additional bytes which, taken
+together with the subsequent opcode's argument, comprise a four-byte
+argument, \var{ext} being the two most-significant bytes.
+\end{opcodedesc}
+
+\begin{opcodedesc}{CALL_FUNCTION_VAR}{argc}
+Calls a function. \var{argc} is interpreted as in \code{CALL_FUNCTION}.
+The top element on the stack contains the variable argument list, followed
+by keyword and positional arguments.
+\end{opcodedesc}
+
+\begin{opcodedesc}{CALL_FUNCTION_KW}{argc}
+Calls a function. \var{argc} is interpreted as in \code{CALL_FUNCTION}.
+The top element on the stack contains the keyword arguments dictionary, 
+followed by explicit keyword and positional arguments.
+\end{opcodedesc}
+
+\begin{opcodedesc}{CALL_FUNCTION_VAR_KW}{argc}
+Calls a function. \var{argc} is interpreted as in
+\code{CALL_FUNCTION}.  The top element on the stack contains the
+keyword arguments dictionary, followed by the variable-arguments
+tuple, followed by explicit keyword and positional arguments.
+\end{opcodedesc}
+
+\begin{opcodedesc}{HAVE_ARGUMENT}{}
+This is not really an opcode.  It identifies the dividing line between
+opcodes which don't take arguments \code{< HAVE_ARGUMENT} and those which do
+\code{>= HAVE_ARGUMENT}.
+\end{opcodedesc}

Added: vendor/Python/current/Doc/lib/libdl.tex
===================================================================
--- vendor/Python/current/Doc/lib/libdl.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libdl.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,101 @@
+\section{\module{dl} ---
+         Call C functions in shared objects}
+\declaremodule{extension}{dl}
+  \platform{Unix} %?????????? Anyone????????????
+\sectionauthor{Moshe Zadka}{moshez at zadka.site.co.il}
+\modulesynopsis{Call C functions in shared objects.}
+
+The \module{dl} module defines an interface to the
+\cfunction{dlopen()} function, which is the most common interface on
+\UNIX{} platforms for handling dynamically linked libraries. It allows
+the program to call arbitrary functions in such a library.
+
+\warning{The \module{dl} module bypasses the Python type system and 
+error handling. If used incorrectly it may cause segmentation faults,
+crashes or other incorrect behaviour.}
+
+\note{This module will not work unless
+\code{sizeof(int) == sizeof(long) == sizeof(char *)}
+If this is not the case, \exception{SystemError} will be raised on
+import.}
+
+The \module{dl} module defines the following function:
+
+\begin{funcdesc}{open}{name\optional{, mode\code{ = RTLD_LAZY}}}
+Open a shared object file, and return a handle. Mode
+signifies late binding (\constant{RTLD_LAZY}) or immediate binding
+(\constant{RTLD_NOW}). Default is \constant{RTLD_LAZY}. Note that some
+systems do not support \constant{RTLD_NOW}.
+
+Return value is a \class{dlobject}.
+\end{funcdesc}
+
+The \module{dl} module defines the following constants:
+
+\begin{datadesc}{RTLD_LAZY}
+Useful as an argument to \function{open()}.
+\end{datadesc}
+
+\begin{datadesc}{RTLD_NOW}
+Useful as an argument to \function{open()}.  Note that on systems
+which do not support immediate binding, this constant will not appear
+in the module. For maximum portability, use \function{hasattr()} to
+determine if the system supports immediate binding.
+\end{datadesc}
+
+The \module{dl} module defines the following exception:
+
+\begin{excdesc}{error}
+Exception raised when an error has occurred inside the dynamic loading
+and linking routines.
+\end{excdesc}
+
+Example:
+
+\begin{verbatim}
+>>> import dl, time
+>>> a=dl.open('/lib/libc.so.6')
+>>> a.call('time'), time.time()
+(929723914, 929723914.498)
+\end{verbatim}
+
+This example was tried on a Debian GNU/Linux system, and is a good
+example of the fact that using this module is usually a bad alternative.
+
+\subsection{Dl Objects \label{dl-objects}}
+
+Dl objects, as returned by \function{open()} above, have the
+following methods:
+
+\begin{methoddesc}{close}{}
+Free all resources, except the memory.
+\end{methoddesc}
+
+\begin{methoddesc}{sym}{name}
+Return the pointer for the function named \var{name}, as a number, if
+it exists in the referenced shared object, otherwise \code{None}. This
+is useful in code like:
+
+\begin{verbatim}
+>>> if a.sym('time'): 
+...     a.call('time')
+... else: 
+...     time.time()
+\end{verbatim}
+
+(Note that this function will return a non-zero number, as zero is the
+\NULL{} pointer)
+\end{methoddesc}
+
+\begin{methoddesc}{call}{name\optional{, arg1\optional{, arg2\ldots}}}
+Call the function named \var{name} in the referenced shared object.
+The arguments must be either Python integers, which will be 
+passed as is, Python strings, to which a pointer will be passed, 
+or \code{None}, which will be passed as \NULL.  Note that 
+strings should only be passed to functions as \ctype{const char*}, as
+Python will not like its string mutated.
+
+There must be at most 10 arguments, and arguments not given will be
+treated as \code{None}. The function's return value must be a C
+\ctype{long}, which is a Python integer.
+\end{methoddesc}

Added: vendor/Python/current/Doc/lib/libdoctest.tex
===================================================================
--- vendor/Python/current/Doc/lib/libdoctest.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libdoctest.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1949 @@
+\section{\module{doctest} ---
+         Test interactive Python examples}
+
+\declaremodule{standard}{doctest}
+\moduleauthor{Tim Peters}{tim at python.org}
+\sectionauthor{Tim Peters}{tim at python.org}
+\sectionauthor{Moshe Zadka}{moshez at debian.org}
+\sectionauthor{Edward Loper}{edloper at users.sourceforge.net}
+
+\modulesynopsis{A framework for verifying interactive Python examples.}
+
+The \refmodule{doctest} module searches for pieces of text that look like
+interactive Python sessions, and then executes those sessions to
+verify that they work exactly as shown.  There are several common ways to
+use doctest:
+
+\begin{itemize}
+\item To check that a module's docstrings are up-to-date by verifying
+      that all interactive examples still work as documented.
+\item To perform regression testing by verifying that interactive
+      examples from a test file or a test object work as expected.
+\item To write tutorial documentation for a package, liberally
+      illustrated with input-output examples.  Depending on whether
+      the examples or the expository text are emphasized, this has
+      the flavor of "literate testing" or "executable documentation".
+\end{itemize}
+
+Here's a complete but small example module:
+
+\begin{verbatim}
+"""
+This is the "example" module.
+
+The example module supplies one function, factorial().  For example,
+
+>>> factorial(5)
+120
+"""
+
+def factorial(n):
+    """Return the factorial of n, an exact integer >= 0.
+
+    If the result is small enough to fit in an int, return an int.
+    Else return a long.
+
+    >>> [factorial(n) for n in range(6)]
+    [1, 1, 2, 6, 24, 120]
+    >>> [factorial(long(n)) for n in range(6)]
+    [1, 1, 2, 6, 24, 120]
+    >>> factorial(30)
+    265252859812191058636308480000000L
+    >>> factorial(30L)
+    265252859812191058636308480000000L
+    >>> factorial(-1)
+    Traceback (most recent call last):
+        ...
+    ValueError: n must be >= 0
+
+    Factorials of floats are OK, but the float must be an exact integer:
+    >>> factorial(30.1)
+    Traceback (most recent call last):
+        ...
+    ValueError: n must be exact integer
+    >>> factorial(30.0)
+    265252859812191058636308480000000L
+
+    It must also not be ridiculously large:
+    >>> factorial(1e100)
+    Traceback (most recent call last):
+        ...
+    OverflowError: n too large
+    """
+
+\end{verbatim}
+% allow LaTeX to break here.
+\begin{verbatim}
+
+    import math
+    if not n >= 0:
+        raise ValueError("n must be >= 0")
+    if math.floor(n) != n:
+        raise ValueError("n must be exact integer")
+    if n+1 == n:  # catch a value like 1e300
+        raise OverflowError("n too large")
+    result = 1
+    factor = 2
+    while factor <= n:
+        result *= factor
+        factor += 1
+    return result
+
+def _test():
+    import doctest
+    doctest.testmod()
+
+if __name__ == "__main__":
+    _test()
+\end{verbatim}
+
+If you run \file{example.py} directly from the command line,
+\refmodule{doctest} works its magic:
+
+\begin{verbatim}
+$ python example.py
+$
+\end{verbatim}
+
+There's no output!  That's normal, and it means all the examples
+worked.  Pass \programopt{-v} to the script, and \refmodule{doctest}
+prints a detailed log of what it's trying, and prints a summary at the
+end:
+
+\begin{verbatim}
+$ python example.py -v
+Trying:
+    factorial(5)
+Expecting:
+    120
+ok
+Trying:
+    [factorial(n) for n in range(6)]
+Expecting:
+    [1, 1, 2, 6, 24, 120]
+ok
+Trying:
+    [factorial(long(n)) for n in range(6)]
+Expecting:
+    [1, 1, 2, 6, 24, 120]
+ok
+\end{verbatim}
+
+And so on, eventually ending with:
+
+\begin{verbatim}
+Trying:
+    factorial(1e100)
+Expecting:
+    Traceback (most recent call last):
+        ...
+    OverflowError: n too large
+ok
+1 items had no tests:
+    __main__._test
+2 items passed all tests:
+   1 tests in __main__
+   8 tests in __main__.factorial
+9 tests in 3 items.
+9 passed and 0 failed.
+Test passed.
+$
+\end{verbatim}
+
+That's all you need to know to start making productive use of
+\refmodule{doctest}!  Jump in.  The following sections provide full
+details.  Note that there are many examples of doctests in
+the standard Python test suite and libraries.  Especially useful examples
+can be found in the standard test file \file{Lib/test/test_doctest.py}.
+
+\subsection{Simple Usage: Checking Examples in
+            Docstrings\label{doctest-simple-testmod}}
+
+The simplest way to start using doctest (but not necessarily the way
+you'll continue to do it) is to end each module \module{M} with:
+
+\begin{verbatim}
+def _test():
+    import doctest
+    doctest.testmod()
+
+if __name__ == "__main__":
+    _test()
+\end{verbatim}
+
+\refmodule{doctest} then examines docstrings in module \module{M}.
+
+Running the module as a script causes the examples in the docstrings
+to get executed and verified:
+
+\begin{verbatim}
+python M.py
+\end{verbatim}
+
+This won't display anything unless an example fails, in which case the
+failing example(s) and the cause(s) of the failure(s) are printed to stdout,
+and the final line of output is
+\samp{***Test Failed*** \var{N} failures.}, where \var{N} is the
+number of examples that failed.
+
+Run it with the \programopt{-v} switch instead:
+
+\begin{verbatim}
+python M.py -v
+\end{verbatim}
+
+and a detailed report of all examples tried is printed to standard
+output, along with assorted summaries at the end.
+
+You can force verbose mode by passing \code{verbose=True} to
+\function{testmod()}, or
+prohibit it by passing \code{verbose=False}.  In either of those cases,
+\code{sys.argv} is not examined by \function{testmod()} (so passing
+\programopt{-v} or not has no effect).
+
+For more information on \function{testmod()}, see
+section~\ref{doctest-basic-api}.
+
+\subsection{Simple Usage: Checking Examples in a Text
+            File\label{doctest-simple-testfile}}
+
+Another simple application of doctest is testing interactive examples
+in a text file.  This can be done with the \function{testfile()}
+function:
+
+\begin{verbatim}
+import doctest
+doctest.testfile("example.txt")
+\end{verbatim}
+
+That short script executes and verifies any interactive Python
+examples contained in the file \file{example.txt}.  The file content
+is treated as if it were a single giant docstring; the file doesn't
+need to contain a Python program!   For example, perhaps \file{example.txt}
+contains this:
+
+\begin{verbatim}
+The ``example`` module
+======================
+
+Using ``factorial``
+-------------------
+
+This is an example text file in reStructuredText format.  First import
+``factorial`` from the ``example`` module:
+
+    >>> from example import factorial
+
+Now use it:
+
+    >>> factorial(6)
+    120
+\end{verbatim}
+
+Running \code{doctest.testfile("example.txt")} then finds the error
+in this documentation:
+
+\begin{verbatim}
+File "./example.txt", line 14, in example.txt
+Failed example:
+    factorial(6)
+Expected:
+    120
+Got:
+    720
+\end{verbatim}
+
+As with \function{testmod()}, \function{testfile()} won't display anything
+unless an example fails.  If an example does fail, then the failing
+example(s) and the cause(s) of the failure(s) are printed to stdout, using
+the same format as \function{testmod()}.
+
+By default, \function{testfile()} looks for files in the calling
+module's directory.  See section~\ref{doctest-basic-api} for a
+description of the optional arguments that can be used to tell it to
+look for files in other locations.
+
+Like \function{testmod()}, \function{testfile()}'s verbosity can be
+set with the \programopt{-v} command-line switch or with the optional
+keyword argument \var{verbose}.
+
+For more information on \function{testfile()}, see
+section~\ref{doctest-basic-api}.
+
+\subsection{How It Works\label{doctest-how-it-works}}
+
+This section examines in detail how doctest works: which docstrings it
+looks at, how it finds interactive examples, what execution context it
+uses, how it handles exceptions, and how option flags can be used to
+control its behavior.  This is the information that you need to know
+to write doctest examples; for information about actually running
+doctest on these examples, see the following sections.
+
+\subsubsection{Which Docstrings Are Examined?\label{doctest-which-docstrings}}
+
+The module docstring, and all function, class and method docstrings are
+searched.  Objects imported into the module are not searched.
+
+In addition, if \code{M.__test__} exists and "is true", it must be a
+dict, and each entry maps a (string) name to a function object, class
+object, or string.  Function and class object docstrings found from
+\code{M.__test__} are searched, and strings are treated as if they
+were docstrings.  In output, a key \code{K} in \code{M.__test__} appears
+with name
+
+\begin{verbatim}
+<name of M>.__test__.K
+\end{verbatim}
+
+Any classes found are recursively searched similarly, to test docstrings in
+their contained methods and nested classes.
+
+\versionchanged[A "private name" concept is deprecated and no longer
+                documented]{2.4}
+
+\subsubsection{How are Docstring Examples
+               Recognized?\label{doctest-finding-examples}}
+
+In most cases a copy-and-paste of an interactive console session works
+fine, but doctest isn't trying to do an exact emulation of any specific
+Python shell.  All hard tab characters are expanded to spaces, using
+8-column tab stops.  If you don't believe tabs should mean that, too
+bad:  don't use hard tabs, or write your own \class{DocTestParser}
+class.
+
+\versionchanged[Expanding tabs to spaces is new; previous versions
+                tried to preserve hard tabs, with confusing results]{2.4}
+
+\begin{verbatim}
+>>> # comments are ignored
+>>> x = 12
+>>> x
+12
+>>> if x == 13:
+...     print "yes"
+... else:
+...     print "no"
+...     print "NO"
+...     print "NO!!!"
+...
+no
+NO
+NO!!!
+>>>
+\end{verbatim}
+
+Any expected output must immediately follow the final
+\code{'>>>~'} or \code{'...~'} line containing the code, and
+the expected output (if any) extends to the next \code{'>>>~'}
+or all-whitespace line.
+
+The fine print:
+
+\begin{itemize}
+
+\item Expected output cannot contain an all-whitespace line, since such a
+  line is taken to signal the end of expected output.  If expected
+  output does contain a blank line, put \code{<BLANKLINE>} in your
+  doctest example each place a blank line is expected.
+  \versionchanged[\code{<BLANKLINE>} was added; there was no way to
+                  use expected output containing empty lines in
+                  previous versions]{2.4}
+
+\item Output to stdout is captured, but not output to stderr (exception
+  tracebacks are captured via a different means).
+
+\item If you continue a line via backslashing in an interactive session,
+  or for any other reason use a backslash, you should use a raw
+  docstring, which will preserve your backslashes exactly as you type
+  them:
+
+\begin{verbatim}
+>>> def f(x):
+...     r'''Backslashes in a raw docstring: m\n'''
+>>> print f.__doc__
+Backslashes in a raw docstring: m\n
+\end{verbatim}
+
+  Otherwise, the backslash will be interpreted as part of the string.
+  For example, the "{\textbackslash}" above would be interpreted as a
+  newline character.  Alternatively, you can double each backslash in the
+  doctest version (and not use a raw string):
+
+\begin{verbatim}
+>>> def f(x):
+...     '''Backslashes in a raw docstring: m\\n'''
+>>> print f.__doc__
+Backslashes in a raw docstring: m\n
+\end{verbatim}
+
+\item The starting column doesn't matter:
+
+\begin{verbatim}
+  >>> assert "Easy!"
+        >>> import math
+            >>> math.floor(1.9)
+            1.0
+\end{verbatim}
+
+and as many leading whitespace characters are stripped from the
+expected output as appeared in the initial \code{'>>>~'} line
+that started the example.
+\end{itemize}
+
+\subsubsection{What's the Execution Context?\label{doctest-execution-context}}
+
+By default, each time \refmodule{doctest} finds a docstring to test, it
+uses a \emph{shallow copy} of \module{M}'s globals, so that running tests
+doesn't change the module's real globals, and so that one test in
+\module{M} can't leave behind crumbs that accidentally allow another test
+to work.  This means examples can freely use any names defined at top-level
+in \module{M}, and names defined earlier in the docstring being run.
+Examples cannot see names defined in other docstrings.
+
+You can force use of your own dict as the execution context by passing
+\code{globs=your_dict} to \function{testmod()} or
+\function{testfile()} instead.
+
+\subsubsection{What About Exceptions?\label{doctest-exceptions}}
+
+No problem, provided that the traceback is the only output produced by
+the example:  just paste in the traceback.\footnote{Examples containing
+    both expected output and an exception are not supported.  Trying
+    to guess where one ends and the other begins is too error-prone,
+    and that also makes for a confusing test.}
+Since tracebacks contain details that are likely to change rapidly (for
+example, exact file paths and line numbers), this is one case where doctest
+works hard to be flexible in what it accepts.
+
+Simple example:
+
+\begin{verbatim}
+>>> [1, 2, 3].remove(42)
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+ValueError: list.remove(x): x not in list
+\end{verbatim}
+
+That doctest succeeds if \exception{ValueError} is raised, with the
+\samp{list.remove(x): x not in list} detail as shown.
+
+The expected output for an exception must start with a traceback
+header, which may be either of the following two lines, indented the
+same as the first line of the example:
+
+\begin{verbatim}
+Traceback (most recent call last):
+Traceback (innermost last):
+\end{verbatim}
+
+The traceback header is followed by an optional traceback stack, whose
+contents are ignored by doctest.  The traceback stack is typically
+omitted, or copied verbatim from an interactive session.
+
+The traceback stack is followed by the most interesting part:  the
+line(s) containing the exception type and detail.  This is usually the
+last line of a traceback, but can extend across multiple lines if the
+exception has a multi-line detail:
+
+\begin{verbatim}
+>>> raise ValueError('multi\n    line\ndetail')
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+ValueError: multi
+    line
+detail
+\end{verbatim}
+
+The last three lines (starting with \exception{ValueError}) are
+compared against the exception's type and detail, and the rest are
+ignored.
+
+Best practice is to omit the traceback stack, unless it adds
+significant documentation value to the example.  So the last example
+is probably better as:
+
+\begin{verbatim}
+>>> raise ValueError('multi\n    line\ndetail')
+Traceback (most recent call last):
+    ...
+ValueError: multi
+    line
+detail
+\end{verbatim}
+
+Note that tracebacks are treated very specially.  In particular, in the
+rewritten example, the use of \samp{...} is independent of doctest's
+\constant{ELLIPSIS} option.  The ellipsis in that example could be left
+out, or could just as well be three (or three hundred) commas or digits,
+or an indented transcript of a Monty Python skit.
+
+Some details you should read once, but won't need to remember:
+
+\begin{itemize}
+
+\item Doctest can't guess whether your expected output came from an
+  exception traceback or from ordinary printing.  So, e.g., an example
+  that expects \samp{ValueError: 42 is prime} will pass whether
+  \exception{ValueError} is actually raised or if the example merely
+  prints that traceback text.  In practice, ordinary output rarely begins
+  with a traceback header line, so this doesn't create real problems.
+
+\item Each line of the traceback stack (if present) must be indented
+  further than the first line of the example, \emph{or} start with a
+  non-alphanumeric character.  The first line following the traceback
+  header indented the same and starting with an alphanumeric is taken
+  to be the start of the exception detail.  Of course this does the
+  right thing for genuine tracebacks.
+
+\item When the \constant{IGNORE_EXCEPTION_DETAIL} doctest option is
+  is specified, everything following the leftmost colon is ignored.
+
+\item The interactive shell omits the traceback header line for some
+  \exception{SyntaxError}s.  But doctest uses the traceback header
+  line to distinguish exceptions from non-exceptions.  So in the rare
+  case where you need to test a \exception{SyntaxError} that omits the
+  traceback header, you will need to manually add the traceback header
+  line to your test example.
+
+\item For some \exception{SyntaxError}s, Python displays the character
+  position of the syntax error, using a \code{\^} marker:
+
+\begin{verbatim}
+>>> 1 1
+  File "<stdin>", line 1
+    1 1
+      ^
+SyntaxError: invalid syntax
+\end{verbatim}
+
+  Since the lines showing the position of the error come before the
+  exception type and detail, they are not checked by doctest.  For
+  example, the following test would pass, even though it puts the
+  \code{\^} marker in the wrong location:
+
+\begin{verbatim}
+>>> 1 1
+Traceback (most recent call last):
+  File "<stdin>", line 1
+    1 1
+    ^
+SyntaxError: invalid syntax
+\end{verbatim}
+
+\end{itemize}
+
+\versionchanged[The ability to handle a multi-line exception detail,
+                and the \constant{IGNORE_EXCEPTION_DETAIL} doctest option,
+                were added]{2.4}
+
+\subsubsection{Option Flags and Directives\label{doctest-options}}
+
+A number of option flags control various aspects of doctest's
+behavior.  Symbolic names for the flags are supplied as module constants,
+which can be or'ed together and passed to various functions.  The names
+can also be used in doctest directives (see below).
+
+The first group of options define test semantics, controlling
+aspects of how doctest decides whether actual output matches an
+example's expected output:
+
+\begin{datadesc}{DONT_ACCEPT_TRUE_FOR_1}
+    By default, if an expected output block contains just \code{1},
+    an actual output block containing just \code{1} or just
+    \code{True} is considered to be a match, and similarly for \code{0}
+    versus \code{False}.  When \constant{DONT_ACCEPT_TRUE_FOR_1} is
+    specified, neither substitution is allowed.  The default behavior
+    caters to that Python changed the return type of many functions
+    from integer to boolean; doctests expecting "little integer"
+    output still work in these cases.  This option will probably go
+    away, but not for several years.
+\end{datadesc}
+
+\begin{datadesc}{DONT_ACCEPT_BLANKLINE}
+    By default, if an expected output block contains a line
+    containing only the string \code{<BLANKLINE>}, then that line
+    will match a blank line in the actual output.  Because a
+    genuinely blank line delimits the expected output, this is
+    the only way to communicate that a blank line is expected.  When
+    \constant{DONT_ACCEPT_BLANKLINE} is specified, this substitution
+    is not allowed.
+\end{datadesc}
+
+\begin{datadesc}{NORMALIZE_WHITESPACE}
+    When specified, all sequences of whitespace (blanks and newlines) are
+    treated as equal.  Any sequence of whitespace within the expected
+    output will match any sequence of whitespace within the actual output.
+    By default, whitespace must match exactly.
+    \constant{NORMALIZE_WHITESPACE} is especially useful when a line
+    of expected output is very long, and you want to wrap it across
+    multiple lines in your source.
+\end{datadesc}
+
+\begin{datadesc}{ELLIPSIS}
+    When specified, an ellipsis marker (\code{...}) in the expected output
+    can match any substring in the actual output.  This includes
+    substrings that span line boundaries, and empty substrings, so it's
+    best to keep usage of this simple.  Complicated uses can lead to the
+    same kinds of "oops, it matched too much!" surprises that \regexp{.*}
+    is prone to in regular expressions.
+\end{datadesc}
+
+\begin{datadesc}{IGNORE_EXCEPTION_DETAIL}
+    When specified, an example that expects an exception passes if
+    an exception of the expected type is raised, even if the exception
+    detail does not match.  For example, an example expecting
+    \samp{ValueError: 42} will pass if the actual exception raised is
+    \samp{ValueError: 3*14}, but will fail, e.g., if
+    \exception{TypeError} is raised.
+
+    Note that a similar effect can be obtained using \constant{ELLIPSIS},
+    and \constant{IGNORE_EXCEPTION_DETAIL} may go away when Python releases
+    prior to 2.4 become uninteresting.  Until then,
+    \constant{IGNORE_EXCEPTION_DETAIL} is the only clear way to write a
+    doctest that doesn't care about the exception detail yet continues
+    to pass under Python releases prior to 2.4 (doctest directives
+    appear to be comments to them).  For example,
+
+\begin{verbatim}
+>>> (1, 2)[3] = 'moo' #doctest: +IGNORE_EXCEPTION_DETAIL
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+TypeError: object doesn't support item assignment
+\end{verbatim}
+
+    passes under Python 2.4 and Python 2.3.  The detail changed in 2.4,
+    to say "does not" instead of "doesn't".
+
+\end{datadesc}
+
+\begin{datadesc}{SKIP}
+
+    When specified, do not run the example at all.  This can be useful
+    in contexts where doctest examples serve as both documentation and
+    test cases, and an example should be included for documentation
+    purposes, but should not be checked.  E.g., the example's output
+    might be random; or the example might depend on resources which
+    would be unavailable to the test driver.
+
+    The SKIP flag can also be used for temporarily "commenting out"
+    examples.
+
+\end{datadesc}
+
+\begin{datadesc}{COMPARISON_FLAGS}
+    A bitmask or'ing together all the comparison flags above.
+\end{datadesc}
+
+The second group of options controls how test failures are reported:
+
+\begin{datadesc}{REPORT_UDIFF}
+    When specified, failures that involve multi-line expected and
+    actual outputs are displayed using a unified diff.
+\end{datadesc}
+
+\begin{datadesc}{REPORT_CDIFF}
+    When specified, failures that involve multi-line expected and
+    actual outputs will be displayed using a context diff.
+\end{datadesc}
+
+\begin{datadesc}{REPORT_NDIFF}
+    When specified, differences are computed by \code{difflib.Differ},
+    using the same algorithm as the popular \file{ndiff.py} utility.
+    This is the only method that marks differences within lines as
+    well as across lines.  For example, if a line of expected output
+    contains digit \code{1} where actual output contains letter \code{l},
+    a line is inserted with a caret marking the mismatching column
+    positions.
+\end{datadesc}
+
+\begin{datadesc}{REPORT_ONLY_FIRST_FAILURE}
+  When specified, display the first failing example in each doctest,
+  but suppress output for all remaining examples.  This will prevent
+  doctest from reporting correct examples that break because of
+  earlier failures; but it might also hide incorrect examples that
+  fail independently of the first failure.  When
+  \constant{REPORT_ONLY_FIRST_FAILURE} is specified, the remaining
+  examples are still run, and still count towards the total number of
+  failures reported; only the output is suppressed.
+\end{datadesc}
+
+\begin{datadesc}{REPORTING_FLAGS}
+    A bitmask or'ing together all the reporting flags above.
+\end{datadesc}
+
+"Doctest directives" may be used to modify the option flags for
+individual examples.  Doctest directives are expressed as a special
+Python comment following an example's source code:
+
+\begin{productionlist}[doctest]
+    \production{directive}
+               {"\#" "doctest:" \token{directive_options}}
+    \production{directive_options}
+               {\token{directive_option} ("," \token{directive_option})*}
+    \production{directive_option}
+               {\token{on_or_off} \token{directive_option_name}}
+    \production{on_or_off}
+               {"+" | "-"}
+    \production{directive_option_name}
+               {"DONT_ACCEPT_BLANKLINE" | "NORMALIZE_WHITESPACE" | ...}
+\end{productionlist}
+
+Whitespace is not allowed between the \code{+} or \code{-} and the
+directive option name.  The directive option name can be any of the
+option flag names explained above.
+
+An example's doctest directives modify doctest's behavior for that
+single example.  Use \code{+} to enable the named behavior, or
+\code{-} to disable it.
+
+For example, this test passes:
+
+\begin{verbatim}
+>>> print range(20) #doctest: +NORMALIZE_WHITESPACE
+[0,   1,  2,  3,  4,  5,  6,  7,  8,  9,
+10,  11, 12, 13, 14, 15, 16, 17, 18, 19]
+\end{verbatim}
+
+Without the directive it would fail, both because the actual output
+doesn't have two blanks before the single-digit list elements, and
+because the actual output is on a single line.  This test also passes,
+and also requires a directive to do so:
+
+\begin{verbatim}
+>>> print range(20) # doctest:+ELLIPSIS
+[0, 1, ..., 18, 19]
+\end{verbatim}
+
+Multiple directives can be used on a single physical line, separated
+by commas:
+
+\begin{verbatim}
+>>> print range(20) # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
+[0,    1, ...,   18,    19]
+\end{verbatim}
+
+If multiple directive comments are used for a single example, then
+they are combined:
+
+\begin{verbatim}
+>>> print range(20) # doctest: +ELLIPSIS
+...                 # doctest: +NORMALIZE_WHITESPACE
+[0,    1, ...,   18,    19]
+\end{verbatim}
+
+As the previous example shows, you can add \samp{...} lines to your
+example containing only directives.  This can be useful when an
+example is too long for a directive to comfortably fit on the same
+line:
+
+\begin{verbatim}
+>>> print range(5) + range(10,20) + range(30,40) + range(50,60)
+... # doctest: +ELLIPSIS
+[0, ..., 4, 10, ..., 19, 30, ..., 39, 50, ..., 59]
+\end{verbatim}
+
+Note that since all options are disabled by default, and directives apply
+only to the example they appear in, enabling options (via \code{+} in a
+directive) is usually the only meaningful choice.  However, option flags
+can also be passed to functions that run doctests, establishing different
+defaults.  In such cases, disabling an option via \code{-} in a directive
+can be useful.
+
+\versionchanged[Constants \constant{DONT_ACCEPT_BLANKLINE},
+    \constant{NORMALIZE_WHITESPACE}, \constant{ELLIPSIS},
+    \constant{IGNORE_EXCEPTION_DETAIL},
+    \constant{REPORT_UDIFF}, \constant{REPORT_CDIFF},
+    \constant{REPORT_NDIFF}, \constant{REPORT_ONLY_FIRST_FAILURE},
+    \constant{COMPARISON_FLAGS} and \constant{REPORTING_FLAGS}
+    were added; by default \code{<BLANKLINE>} in expected output
+    matches an empty line in actual output; and doctest directives
+    were added]{2.4}
+\versionchanged[Constant \constant{SKIP} was added]{2.5}
+
+There's also a way to register new option flag names, although this
+isn't useful unless you intend to extend \refmodule{doctest} internals
+via subclassing:
+
+\begin{funcdesc}{register_optionflag}{name}
+  Create a new option flag with a given name, and return the new
+  flag's integer value.  \function{register_optionflag()} can be
+  used when subclassing \class{OutputChecker} or
+  \class{DocTestRunner} to create new options that are supported by
+  your subclasses.  \function{register_optionflag} should always be
+  called using the following idiom:
+
+\begin{verbatim}
+  MY_FLAG = register_optionflag('MY_FLAG')
+\end{verbatim}
+
+  \versionadded{2.4}
+\end{funcdesc}
+
+\subsubsection{Warnings\label{doctest-warnings}}
+
+\refmodule{doctest} is serious about requiring exact matches in expected
+output.  If even a single character doesn't match, the test fails.  This
+will probably surprise you a few times, as you learn exactly what Python
+does and doesn't guarantee about output.  For example, when printing a
+dict, Python doesn't guarantee that the key-value pairs will be printed
+in any particular order, so a test like
+
+% Hey! What happened to Monty Python examples?
+% Tim: ask Guido -- it's his example!
+\begin{verbatim}
+>>> foo()
+{"Hermione": "hippogryph", "Harry": "broomstick"}
+\end{verbatim}
+
+is vulnerable!  One workaround is to do
+
+\begin{verbatim}
+>>> foo() == {"Hermione": "hippogryph", "Harry": "broomstick"}
+True
+\end{verbatim}
+
+instead.  Another is to do
+
+\begin{verbatim}
+>>> d = foo().items()
+>>> d.sort()
+>>> d
+[('Harry', 'broomstick'), ('Hermione', 'hippogryph')]
+\end{verbatim}
+
+There are others, but you get the idea.
+
+Another bad idea is to print things that embed an object address, like
+
+\begin{verbatim}
+>>> id(1.0) # certain to fail some of the time
+7948648
+>>> class C: pass
+>>> C()   # the default repr() for instances embeds an address
+<__main__.C instance at 0x00AC18F0>
+\end{verbatim}
+
+The \constant{ELLIPSIS} directive gives a nice approach for the last
+example:
+
+\begin{verbatim}
+>>> C() #doctest: +ELLIPSIS
+<__main__.C instance at 0x...>
+\end{verbatim}
+
+Floating-point numbers are also subject to small output variations across
+platforms, because Python defers to the platform C library for float
+formatting, and C libraries vary widely in quality here.
+
+\begin{verbatim}
+>>> 1./7  # risky
+0.14285714285714285
+>>> print 1./7 # safer
+0.142857142857
+>>> print round(1./7, 6) # much safer
+0.142857
+\end{verbatim}
+
+Numbers of the form \code{I/2.**J} are safe across all platforms, and I
+often contrive doctest examples to produce numbers of that form:
+
+\begin{verbatim}
+>>> 3./4  # utterly safe
+0.75
+\end{verbatim}
+
+Simple fractions are also easier for people to understand, and that makes
+for better documentation.
+
+\subsection{Basic API\label{doctest-basic-api}}
+
+The functions \function{testmod()} and \function{testfile()} provide a
+simple interface to doctest that should be sufficient for most basic
+uses.  For a less formal introduction to these two functions, see
+sections \ref{doctest-simple-testmod} and
+\ref{doctest-simple-testfile}.
+
+\begin{funcdesc}{testfile}{filename\optional{, module_relative}\optional{,
+                          name}\optional{, package}\optional{,
+                          globs}\optional{, verbose}\optional{,
+                          report}\optional{, optionflags}\optional{,
+                          extraglobs}\optional{, raise_on_error}\optional{,
+                          parser}\optional{, encoding}}
+
+  All arguments except \var{filename} are optional, and should be
+  specified in keyword form.
+
+  Test examples in the file named \var{filename}.  Return
+  \samp{(\var{failure_count}, \var{test_count})}.
+
+  Optional argument \var{module_relative} specifies how the filename
+  should be interpreted:
+
+  \begin{itemize}
+  \item If \var{module_relative} is \code{True} (the default), then
+        \var{filename} specifies an OS-independent module-relative
+        path.  By default, this path is relative to the calling
+        module's directory; but if the \var{package} argument is
+        specified, then it is relative to that package.  To ensure
+        OS-independence, \var{filename} should use \code{/} characters
+        to separate path segments, and may not be an absolute path
+        (i.e., it may not begin with \code{/}).
+  \item If \var{module_relative} is \code{False}, then \var{filename}
+        specifies an OS-specific path.  The path may be absolute or
+        relative; relative paths are resolved with respect to the
+        current working directory.
+  \end{itemize}
+
+  Optional argument \var{name} gives the name of the test; by default,
+  or if \code{None}, \code{os.path.basename(\var{filename})} is used.
+
+  Optional argument \var{package} is a Python package or the name of a
+  Python package whose directory should be used as the base directory
+  for a module-relative filename.  If no package is specified, then
+  the calling module's directory is used as the base directory for
+  module-relative filenames.  It is an error to specify \var{package}
+  if \var{module_relative} is \code{False}.
+
+  Optional argument \var{globs} gives a dict to be used as the globals
+  when executing examples.  A new shallow copy of this dict is
+  created for the doctest, so its examples start with a clean slate.
+  By default, or if \code{None}, a new empty dict is used.
+
+  Optional argument \var{extraglobs} gives a dict merged into the
+  globals used to execute examples.  This works like
+  \method{dict.update()}:  if \var{globs} and \var{extraglobs} have a
+  common key, the associated value in \var{extraglobs} appears in the
+  combined dict.  By default, or if \code{None}, no extra globals are
+  used.  This is an advanced feature that allows parameterization of
+  doctests.  For example, a doctest can be written for a base class, using
+  a generic name for the class, then reused to test any number of
+  subclasses by passing an \var{extraglobs} dict mapping the generic
+  name to the subclass to be tested.
+
+  Optional argument \var{verbose} prints lots of stuff if true, and prints
+  only failures if false; by default, or if \code{None}, it's true
+  if and only if \code{'-v'} is in \code{sys.argv}.
+
+  Optional argument \var{report} prints a summary at the end when true,
+  else prints nothing at the end.  In verbose mode, the summary is
+  detailed, else the summary is very brief (in fact, empty if all tests
+  passed).
+
+  Optional argument \var{optionflags} or's together option flags.  See
+  section~\ref{doctest-options}.
+
+  Optional argument \var{raise_on_error} defaults to false.  If true,
+  an exception is raised upon the first failure or unexpected exception
+  in an example.  This allows failures to be post-mortem debugged.
+  Default behavior is to continue running examples.
+
+  Optional argument \var{parser} specifies a \class{DocTestParser} (or
+  subclass) that should be used to extract tests from the files.  It
+  defaults to a normal parser (i.e., \code{\class{DocTestParser}()}).
+
+  Optional argument \var{encoding} specifies an encoding that should
+  be used to convert the file to unicode.
+
+  \versionadded{2.4}
+
+  \versionchanged[The parameter \var{encoding} was added]{2.5}
+
+\end{funcdesc}
+
+\begin{funcdesc}{testmod}{\optional{m}\optional{, name}\optional{,
+                          globs}\optional{, verbose}\optional{,
+                          report}\optional{,
+                          optionflags}\optional{, extraglobs}\optional{,
+                          raise_on_error}\optional{, exclude_empty}}
+
+  All arguments are optional, and all except for \var{m} should be
+  specified in keyword form.
+
+  Test examples in docstrings in functions and classes reachable
+  from module \var{m} (or module \module{__main__} if \var{m} is not
+  supplied or is \code{None}), starting with \code{\var{m}.__doc__}.
+
+  Also test examples reachable from dict \code{\var{m}.__test__}, if it
+  exists and is not \code{None}.  \code{\var{m}.__test__} maps
+  names (strings) to functions, classes and strings; function and class
+  docstrings are searched for examples; strings are searched directly,
+  as if they were docstrings.
+
+  Only docstrings attached to objects belonging to module \var{m} are
+  searched.
+
+  Return \samp{(\var{failure_count}, \var{test_count})}.
+
+  Optional argument \var{name} gives the name of the module; by default,
+  or if \code{None}, \code{\var{m}.__name__} is used.
+
+  Optional argument \var{exclude_empty} defaults to false.  If true,
+  objects for which no doctests are found are excluded from consideration.
+  The default is a backward compatibility hack, so that code still
+  using \method{doctest.master.summarize()} in conjunction with
+  \function{testmod()} continues to get output for objects with no tests.
+  The \var{exclude_empty} argument to the newer \class{DocTestFinder}
+  constructor defaults to true.
+
+  Optional arguments \var{extraglobs}, \var{verbose}, \var{report},
+  \var{optionflags}, \var{raise_on_error}, and \var{globs} are the same as
+  for function \function{testfile()} above, except that \var{globs}
+  defaults to \code{\var{m}.__dict__}.
+
+  \versionchanged[The parameter \var{optionflags} was added]{2.3}
+
+  \versionchanged[The parameters \var{extraglobs}, \var{raise_on_error}
+                  and \var{exclude_empty} were added]{2.4}
+
+  \versionchanged[The optional argument \var{isprivate}, deprecated
+                  in 2.4, was removed]{2.5}
+
+\end{funcdesc}
+
+There's also a function to run the doctests associated with a single object.
+This function is provided for backward compatibility.  There are no plans
+to deprecate it, but it's rarely useful:
+
+\begin{funcdesc}{run_docstring_examples}{f, globs\optional{,
+                            verbose}\optional{, name}\optional{,
+                            compileflags}\optional{, optionflags}}
+
+  Test examples associated with object \var{f}; for example, \var{f} may
+  be a module, function, or class object.
+
+  A shallow copy of dictionary argument \var{globs} is used for the
+  execution context.
+
+  Optional argument \var{name} is used in failure messages, and defaults
+  to \code{"NoName"}.
+
+  If optional argument \var{verbose} is true, output is generated even
+  if there are no failures.  By default, output is generated only in case
+  of an example failure.
+
+  Optional argument \var{compileflags} gives the set of flags that should
+  be used by the Python compiler when running the examples.  By default, or
+  if \code{None}, flags are deduced corresponding to the set of future
+  features found in \var{globs}.
+
+  Optional argument \var{optionflags} works as for function
+  \function{testfile()} above.
+\end{funcdesc}
+
+\subsection{Unittest API\label{doctest-unittest-api}}
+
+As your collection of doctest'ed modules grows, you'll want a way to run
+all their doctests systematically.  Prior to Python 2.4, \refmodule{doctest}
+had a barely documented \class{Tester} class that supplied a rudimentary
+way to combine doctests from multiple modules. \class{Tester} was feeble,
+and in practice most serious Python testing frameworks build on the
+\refmodule{unittest} module, which supplies many flexible ways to combine
+tests from multiple sources.  So, in Python 2.4, \refmodule{doctest}'s
+\class{Tester} class is deprecated, and \refmodule{doctest} provides two
+functions that can be used to create \refmodule{unittest} test suites from
+modules and text files containing doctests.  These test suites can then be
+run using \refmodule{unittest} test runners:
+
+\begin{verbatim}
+import unittest
+import doctest
+import my_module_with_doctests, and_another
+
+suite = unittest.TestSuite()
+for mod in my_module_with_doctests, and_another:
+    suite.addTest(doctest.DocTestSuite(mod))
+runner = unittest.TextTestRunner()
+runner.run(suite)
+\end{verbatim}
+
+There are two main functions for creating \class{\refmodule{unittest}.TestSuite}
+instances from text files and modules with doctests:
+
+\begin{funcdesc}{DocFileSuite}{\optional{module_relative}\optional{,
+                              package}\optional{, setUp}\optional{,
+                              tearDown}\optional{, globs}\optional{,
+                              optionflags}\optional{, parser}\optional{,
+                              encoding}}
+
+  Convert doctest tests from one or more text files to a
+  \class{\refmodule{unittest}.TestSuite}.
+
+  The returned \class{\refmodule{unittest}.TestSuite} is to be run by the
+  unittest framework and runs the interactive examples in each file.  If an
+  example in any file fails, then the synthesized unit test fails, and a
+  \exception{failureException} exception is raised showing the name of the
+  file containing the test and a (sometimes approximate) line number.
+
+  Pass one or more paths (as strings) to text files to be examined.
+
+  Options may be provided as keyword arguments:
+
+  Optional argument \var{module_relative} specifies how
+  the filenames in \var{paths} should be interpreted:
+
+  \begin{itemize}
+  \item If \var{module_relative} is \code{True} (the default), then
+        each filename specifies an OS-independent module-relative
+        path.  By default, this path is relative to the calling
+        module's directory; but if the \var{package} argument is
+        specified, then it is relative to that package.  To ensure
+        OS-independence, each filename should use \code{/} characters
+        to separate path segments, and may not be an absolute path
+        (i.e., it may not begin with \code{/}).
+  \item If \var{module_relative} is \code{False}, then each filename
+        specifies an OS-specific path.  The path may be absolute or
+        relative; relative paths are resolved with respect to the
+        current working directory.
+  \end{itemize}
+
+  Optional argument \var{package} is a Python package or the name
+  of a Python package whose directory should be used as the base
+  directory for module-relative filenames.  If no package is
+  specified, then the calling module's directory is used as the base
+  directory for module-relative filenames.  It is an error to specify
+  \var{package} if \var{module_relative} is \code{False}.
+
+  Optional argument \var{setUp} specifies a set-up function for
+  the test suite.  This is called before running the tests in each
+  file.  The \var{setUp} function will be passed a \class{DocTest}
+  object.  The setUp function can access the test globals as the
+  \var{globs} attribute of the test passed.
+
+  Optional argument \var{tearDown} specifies a tear-down function
+  for the test suite.  This is called after running the tests in each
+  file.  The \var{tearDown} function will be passed a \class{DocTest}
+  object.  The setUp function can access the test globals as the
+  \var{globs} attribute of the test passed.
+
+  Optional argument \var{globs} is a dictionary containing the
+  initial global variables for the tests.  A new copy of this
+  dictionary is created for each test.  By default, \var{globs} is
+  a new empty dictionary.
+
+  Optional argument \var{optionflags} specifies the default
+  doctest options for the tests, created by or-ing together
+  individual option flags.  See section~\ref{doctest-options}.
+  See function \function{set_unittest_reportflags()} below for
+  a better way to set reporting options.
+
+  Optional argument \var{parser} specifies a \class{DocTestParser} (or
+  subclass) that should be used to extract tests from the files.  It
+  defaults to a normal parser (i.e., \code{\class{DocTestParser}()}).
+
+  Optional argument \var{encoding} specifies an encoding that should
+  be used to convert the file to unicode.
+
+  \versionadded{2.4}
+
+  \versionchanged[The global \code{__file__} was added to the
+  globals provided to doctests loaded from a text file using
+  \function{DocFileSuite()}]{2.5}
+
+  \versionchanged[The parameter \var{encoding} was added]{2.5}
+
+\end{funcdesc}
+
+\begin{funcdesc}{DocTestSuite}{\optional{module}\optional{,
+                              globs}\optional{, extraglobs}\optional{,
+                              test_finder}\optional{, setUp}\optional{,
+                              tearDown}\optional{, checker}}
+  Convert doctest tests for a module to a
+  \class{\refmodule{unittest}.TestSuite}.
+
+  The returned \class{\refmodule{unittest}.TestSuite} is to be run by the
+  unittest framework and runs each doctest in the module.  If any of the
+  doctests fail, then the synthesized unit test fails, and a
+  \exception{failureException} exception is raised showing the name of the
+  file containing the test and a (sometimes approximate) line number.
+
+  Optional argument \var{module} provides the module to be tested.  It
+  can be a module object or a (possibly dotted) module name.  If not
+  specified, the module calling this function is used.
+
+  Optional argument \var{globs} is a dictionary containing the
+  initial global variables for the tests.  A new copy of this
+  dictionary is created for each test.  By default, \var{globs} is
+  a new empty dictionary.
+
+  Optional argument \var{extraglobs} specifies an extra set of
+  global variables, which is merged into \var{globs}.  By default, no
+  extra globals are used.
+
+  Optional argument \var{test_finder} is the \class{DocTestFinder}
+  object (or a drop-in replacement) that is used to extract doctests
+  from the module.
+
+  Optional arguments \var{setUp}, \var{tearDown}, and \var{optionflags}
+  are the same as for function \function{DocFileSuite()} above.
+
+  \versionadded{2.3}
+
+  \versionchanged[The parameters \var{globs}, \var{extraglobs},
+    \var{test_finder}, \var{setUp}, \var{tearDown}, and
+    \var{optionflags} were added; this function now uses the same search
+    technique as \function{testmod()}]{2.4}
+\end{funcdesc}
+
+Under the covers, \function{DocTestSuite()} creates a
+\class{\refmodule{unittest}.TestSuite} out of \class{doctest.DocTestCase}
+instances, and \class{DocTestCase} is a subclass of
+\class{\refmodule{unittest}.TestCase}. \class{DocTestCase} isn't documented
+here (it's an internal detail), but studying its code can answer questions
+about the exact details of \refmodule{unittest} integration.
+
+Similarly, \function{DocFileSuite()} creates a
+\class{\refmodule{unittest}.TestSuite} out of \class{doctest.DocFileCase}
+instances, and \class{DocFileCase} is a subclass of \class{DocTestCase}.
+
+So both ways of creating a \class{\refmodule{unittest}.TestSuite} run
+instances of \class{DocTestCase}.  This is important for a subtle reason:
+when you run \refmodule{doctest} functions yourself, you can control the
+\refmodule{doctest} options in use directly, by passing option flags to
+\refmodule{doctest} functions.  However, if you're writing a
+\refmodule{unittest} framework, \refmodule{unittest} ultimately controls
+when and how tests get run.  The framework author typically wants to
+control \refmodule{doctest} reporting options (perhaps, e.g., specified by
+command line options), but there's no way to pass options through
+\refmodule{unittest} to \refmodule{doctest} test runners.
+
+For this reason, \refmodule{doctest} also supports a notion of
+\refmodule{doctest} reporting flags specific to \refmodule{unittest}
+support, via this function:
+
+\begin{funcdesc}{set_unittest_reportflags}{flags}
+  Set the \refmodule{doctest} reporting flags to use.
+
+  Argument \var{flags} or's together option flags.  See
+  section~\ref{doctest-options}.  Only "reporting flags" can be used.
+
+  This is a module-global setting, and affects all future doctests run by
+  module \refmodule{unittest}:  the \method{runTest()} method of
+  \class{DocTestCase} looks at the option flags specified for the test case
+  when the \class{DocTestCase} instance was constructed.  If no reporting
+  flags were specified (which is the typical and expected case),
+  \refmodule{doctest}'s \refmodule{unittest} reporting flags are or'ed into
+  the option flags, and the option flags so augmented are passed to the
+  \class{DocTestRunner} instance created to run the doctest.  If any
+  reporting flags were specified when the \class{DocTestCase} instance was
+  constructed, \refmodule{doctest}'s \refmodule{unittest} reporting flags
+  are ignored.
+
+  The value of the \refmodule{unittest} reporting flags in effect before the
+  function was called is returned by the function.
+
+  \versionadded{2.4}
+\end{funcdesc}
+
+
+\subsection{Advanced API\label{doctest-advanced-api}}
+
+The basic API is a simple wrapper that's intended to make doctest easy
+to use.  It is fairly flexible, and should meet most users' needs;
+however, if you require more fine-grained control over testing, or
+wish to extend doctest's capabilities, then you should use the
+advanced API.
+
+The advanced API revolves around two container classes, which are used
+to store the interactive examples extracted from doctest cases:
+
+\begin{itemize}
+\item \class{Example}: A single python statement, paired with its
+      expected output.
+\item \class{DocTest}: A collection of \class{Example}s, typically
+      extracted from a single docstring or text file.
+\end{itemize}
+
+Additional processing classes are defined to find, parse, and run, and
+check doctest examples:
+
+\begin{itemize}
+\item \class{DocTestFinder}: Finds all docstrings in a given module,
+      and uses a \class{DocTestParser} to create a \class{DocTest}
+      from every docstring that contains interactive examples.
+\item \class{DocTestParser}: Creates a \class{DocTest} object from
+      a string (such as an object's docstring).
+\item \class{DocTestRunner}: Executes the examples in a
+      \class{DocTest}, and uses an \class{OutputChecker} to verify
+      their output.
+\item \class{OutputChecker}: Compares the actual output from a
+      doctest example with the expected output, and decides whether
+      they match.
+\end{itemize}
+
+The relationships among these processing classes are summarized in the
+following diagram:
+
+\begin{verbatim}
+                            list of:
++------+                   +---------+
+|module| --DocTestFinder-> | DocTest | --DocTestRunner-> results
++------+    |        ^     +---------+     |       ^    (printed)
+            |        |     | Example |     |       |
+            v        |     |   ...   |     v       |
+           DocTestParser   | Example |   OutputChecker
+                           +---------+
+\end{verbatim}
+
+\subsubsection{DocTest Objects\label{doctest-DocTest}}
+\begin{classdesc}{DocTest}{examples, globs, name, filename, lineno,
+                           docstring}
+    A collection of doctest examples that should be run in a single
+    namespace.  The constructor arguments are used to initialize the
+    member variables of the same names.
+    \versionadded{2.4}
+\end{classdesc}
+
+\class{DocTest} defines the following member variables.  They are
+initialized by the constructor, and should not be modified directly.
+
+\begin{memberdesc}{examples}
+    A list of \class{Example} objects encoding the individual
+    interactive Python examples that should be run by this test.
+\end{memberdesc}
+
+\begin{memberdesc}{globs}
+    The namespace (aka globals) that the examples should be run in.
+    This is a dictionary mapping names to values.  Any changes to the
+    namespace made by the examples (such as binding new variables)
+    will be reflected in \member{globs} after the test is run.
+\end{memberdesc}
+
+\begin{memberdesc}{name}
+    A string name identifying the \class{DocTest}.  Typically, this is
+    the name of the object or file that the test was extracted from.
+\end{memberdesc}
+
+\begin{memberdesc}{filename}
+    The name of the file that this \class{DocTest} was extracted from;
+    or \code{None} if the filename is unknown, or if the
+    \class{DocTest} was not extracted from a file.
+\end{memberdesc}
+
+\begin{memberdesc}{lineno}
+    The line number within \member{filename} where this
+    \class{DocTest} begins, or \code{None} if the line number is
+    unavailable.  This line number is zero-based with respect to the
+    beginning of the file.
+\end{memberdesc}
+
+\begin{memberdesc}{docstring}
+    The string that the test was extracted from, or `None` if the
+    string is unavailable, or if the test was not extracted from a
+    string.
+\end{memberdesc}
+
+\subsubsection{Example Objects\label{doctest-Example}}
+\begin{classdesc}{Example}{source, want\optional{,
+                           exc_msg}\optional{, lineno}\optional{,
+                           indent}\optional{, options}}
+    A single interactive example, consisting of a Python statement and
+    its expected output.  The constructor arguments are used to
+    initialize the member variables of the same names.
+    \versionadded{2.4}
+\end{classdesc}
+
+\class{Example} defines the following member variables.  They are
+initialized by the constructor, and should not be modified directly.
+
+\begin{memberdesc}{source}
+    A string containing the example's source code.  This source code
+    consists of a single Python statement, and always ends with a
+    newline; the constructor adds a newline when necessary.
+\end{memberdesc}
+
+\begin{memberdesc}{want}
+    The expected output from running the example's source code (either
+    from stdout, or a traceback in case of exception).  \member{want}
+    ends with a newline unless no output is expected, in which case
+    it's an empty string.  The constructor adds a newline when
+    necessary.
+\end{memberdesc}
+
+\begin{memberdesc}{exc_msg}
+    The exception message generated by the example, if the example is
+    expected to generate an exception; or \code{None} if it is not
+    expected to generate an exception.  This exception message is
+    compared against the return value of
+    \function{traceback.format_exception_only()}.  \member{exc_msg}
+    ends with a newline unless it's \code{None}.  The constructor adds
+    a newline if needed.
+\end{memberdesc}
+
+\begin{memberdesc}{lineno}
+    The line number within the string containing this example where
+    the example begins.  This line number is zero-based with respect
+    to the beginning of the containing string.
+\end{memberdesc}
+
+\begin{memberdesc}{indent}
+    The example's indentation in the containing string, i.e., the
+    number of space characters that precede the example's first
+    prompt.
+\end{memberdesc}
+
+\begin{memberdesc}{options}
+    A dictionary mapping from option flags to \code{True} or
+    \code{False}, which is used to override default options for this
+    example.  Any option flags not contained in this dictionary are
+    left at their default value (as specified by the
+    \class{DocTestRunner}'s \member{optionflags}).
+    By default, no options are set.
+\end{memberdesc}
+
+\subsubsection{DocTestFinder objects\label{doctest-DocTestFinder}}
+\begin{classdesc}{DocTestFinder}{\optional{verbose}\optional{,
+                                parser}\optional{, recurse}\optional{,
+                                exclude_empty}}
+    A processing class used to extract the \class{DocTest}s that are
+    relevant to a given object, from its docstring and the docstrings
+    of its contained objects.  \class{DocTest}s can currently be
+    extracted from the following object types: modules, functions,
+    classes, methods, staticmethods, classmethods, and properties.
+
+    The optional argument \var{verbose} can be used to display the
+    objects searched by the finder.  It defaults to \code{False} (no
+    output).
+
+    The optional argument \var{parser} specifies the
+    \class{DocTestParser} object (or a drop-in replacement) that is
+    used to extract doctests from docstrings.
+
+    If the optional argument \var{recurse} is false, then
+    \method{DocTestFinder.find()} will only examine the given object,
+    and not any contained objects.
+
+    If the optional argument \var{exclude_empty} is false, then
+    \method{DocTestFinder.find()} will include tests for objects with
+    empty docstrings.
+
+    \versionadded{2.4}
+\end{classdesc}
+
+\class{DocTestFinder} defines the following method:
+
+\begin{methoddesc}{find}{obj\optional{, name}\optional{,
+                   module}\optional{, globs}\optional{, extraglobs}}
+    Return a list of the \class{DocTest}s that are defined by
+    \var{obj}'s docstring, or by any of its contained objects'
+    docstrings.
+
+    The optional argument \var{name} specifies the object's name; this
+    name will be used to construct names for the returned
+    \class{DocTest}s.  If \var{name} is not specified, then
+    \code{\var{obj}.__name__} is used.
+
+    The optional parameter \var{module} is the module that contains
+    the given object.  If the module is not specified or is None, then
+    the test finder will attempt to automatically determine the
+    correct module.  The object's module is used:
+
+    \begin{itemize}
+    \item As a default namespace, if \var{globs} is not specified.
+    \item To prevent the DocTestFinder from extracting DocTests
+          from objects that are imported from other modules.  (Contained
+          objects with modules other than \var{module} are ignored.)
+    \item To find the name of the file containing the object.
+    \item To help find the line number of the object within its file.
+    \end{itemize}
+
+    If \var{module} is \code{False}, no attempt to find the module
+    will be made.  This is obscure, of use mostly in testing doctest
+    itself: if \var{module} is \code{False}, or is \code{None} but
+    cannot be found automatically, then all objects are considered to
+    belong to the (non-existent) module, so all contained objects will
+    (recursively) be searched for doctests.
+
+    The globals for each \class{DocTest} is formed by combining
+    \var{globs} and \var{extraglobs} (bindings in \var{extraglobs}
+    override bindings in \var{globs}).  A new shallow copy of the globals
+    dictionary is created for each \class{DocTest}.  If \var{globs} is
+    not specified, then it defaults to the module's \var{__dict__}, if
+    specified, or \code{\{\}} otherwise.  If \var{extraglobs} is not
+    specified, then it defaults to \code{\{\}}.
+\end{methoddesc}
+
+\subsubsection{DocTestParser objects\label{doctest-DocTestParser}}
+\begin{classdesc}{DocTestParser}{}
+    A processing class used to extract interactive examples from a
+    string, and use them to create a \class{DocTest} object.
+    \versionadded{2.4}
+\end{classdesc}
+
+\class{DocTestParser} defines the following methods:
+
+\begin{methoddesc}{get_doctest}{string, globs, name, filename, lineno}
+    Extract all doctest examples from the given string, and collect
+    them into a \class{DocTest} object.
+
+    \var{globs}, \var{name}, \var{filename}, and \var{lineno} are
+    attributes for the new \class{DocTest} object.  See the
+    documentation for \class{DocTest} for more information.
+\end{methoddesc}
+
+\begin{methoddesc}{get_examples}{string\optional{, name}}
+    Extract all doctest examples from the given string, and return
+    them as a list of \class{Example} objects.  Line numbers are
+    0-based.  The optional argument \var{name} is a name identifying
+    this string, and is only used for error messages.
+\end{methoddesc}
+
+\begin{methoddesc}{parse}{string\optional{, name}}
+    Divide the given string into examples and intervening text, and
+    return them as a list of alternating \class{Example}s and strings.
+    Line numbers for the \class{Example}s are 0-based.  The optional
+    argument \var{name} is a name identifying this string, and is only
+    used for error messages.
+\end{methoddesc}
+
+\subsubsection{DocTestRunner objects\label{doctest-DocTestRunner}}
+\begin{classdesc}{DocTestRunner}{\optional{checker}\optional{,
+                                 verbose}\optional{, optionflags}}
+    A processing class used to execute and verify the interactive
+    examples in a \class{DocTest}.
+
+    The comparison between expected outputs and actual outputs is done
+    by an \class{OutputChecker}.  This comparison may be customized
+    with a number of option flags; see section~\ref{doctest-options}
+    for more information.  If the option flags are insufficient, then
+    the comparison may also be customized by passing a subclass of
+    \class{OutputChecker} to the constructor.
+
+    The test runner's display output can be controlled in two ways.
+    First, an output function can be passed to
+    \method{TestRunner.run()}; this function will be called with
+    strings that should be displayed.  It defaults to
+    \code{sys.stdout.write}.  If capturing the output is not
+    sufficient, then the display output can be also customized by
+    subclassing DocTestRunner, and overriding the methods
+    \method{report_start}, \method{report_success},
+    \method{report_unexpected_exception}, and \method{report_failure}.
+
+    The optional keyword argument \var{checker} specifies the
+    \class{OutputChecker} object (or drop-in replacement) that should
+    be used to compare the expected outputs to the actual outputs of
+    doctest examples.
+
+    The optional keyword argument \var{verbose} controls the
+    \class{DocTestRunner}'s verbosity.  If \var{verbose} is
+    \code{True}, then information is printed about each example, as it
+    is run.  If \var{verbose} is \code{False}, then only failures are
+    printed.  If \var{verbose} is unspecified, or \code{None}, then
+    verbose output is used iff the command-line switch \programopt{-v}
+    is used.
+
+    The optional keyword argument \var{optionflags} can be used to
+    control how the test runner compares expected output to actual
+    output, and how it displays failures.  For more information, see
+    section~\ref{doctest-options}.
+
+    \versionadded{2.4}
+\end{classdesc}
+
+\class{DocTestParser} defines the following methods:
+
+\begin{methoddesc}{report_start}{out, test, example}
+    Report that the test runner is about to process the given example.
+    This method is provided to allow subclasses of
+    \class{DocTestRunner} to customize their output; it should not be
+    called directly.
+
+    \var{example} is the example about to be processed.  \var{test} is
+    the test containing \var{example}.  \var{out} is the output
+    function that was passed to \method{DocTestRunner.run()}.
+\end{methoddesc}
+
+\begin{methoddesc}{report_success}{out, test, example, got}
+    Report that the given example ran successfully.  This method is
+    provided to allow subclasses of \class{DocTestRunner} to customize
+    their output; it should not be called directly.
+
+    \var{example} is the example about to be processed.  \var{got} is
+    the actual output from the example.  \var{test} is the test
+    containing \var{example}.  \var{out} is the output function that
+    was passed to \method{DocTestRunner.run()}.
+\end{methoddesc}
+
+\begin{methoddesc}{report_failure}{out, test, example, got}
+    Report that the given example failed.  This method is provided to
+    allow subclasses of \class{DocTestRunner} to customize their
+    output; it should not be called directly.
+
+    \var{example} is the example about to be processed.  \var{got} is
+    the actual output from the example.  \var{test} is the test
+    containing \var{example}.  \var{out} is the output function that
+    was passed to \method{DocTestRunner.run()}.
+\end{methoddesc}
+
+\begin{methoddesc}{report_unexpected_exception}{out, test, example, exc_info}
+    Report that the given example raised an unexpected exception.
+    This method is provided to allow subclasses of
+    \class{DocTestRunner} to customize their output; it should not be
+    called directly.
+
+    \var{example} is the example about to be processed.
+    \var{exc_info} is a tuple containing information about the
+    unexpected exception (as returned by \function{sys.exc_info()}).
+    \var{test} is the test containing \var{example}.  \var{out} is the
+    output function that was passed to \method{DocTestRunner.run()}.
+\end{methoddesc}
+
+\begin{methoddesc}{run}{test\optional{, compileflags}\optional{,
+                        out}\optional{, clear_globs}}
+    Run the examples in \var{test} (a \class{DocTest} object), and
+    display the results using the writer function \var{out}.
+
+    The examples are run in the namespace \code{test.globs}.  If
+    \var{clear_globs} is true (the default), then this namespace will
+    be cleared after the test runs, to help with garbage collection.
+    If you would like to examine the namespace after the test
+    completes, then use \var{clear_globs=False}.
+
+    \var{compileflags} gives the set of flags that should be used by
+    the Python compiler when running the examples.  If not specified,
+    then it will default to the set of future-import flags that apply
+    to \var{globs}.
+
+    The output of each example is checked using the
+    \class{DocTestRunner}'s output checker, and the results are
+    formatted by the \method{DocTestRunner.report_*} methods.
+\end{methoddesc}
+
+\begin{methoddesc}{summarize}{\optional{verbose}}
+    Print a summary of all the test cases that have been run by this
+    DocTestRunner, and return a tuple \samp{(\var{failure_count},
+    \var{test_count})}.
+
+    The optional \var{verbose} argument controls how detailed the
+    summary is.  If the verbosity is not specified, then the
+    \class{DocTestRunner}'s verbosity is used.
+\end{methoddesc}
+
+\subsubsection{OutputChecker objects\label{doctest-OutputChecker}}
+
+\begin{classdesc}{OutputChecker}{}
+    A class used to check the whether the actual output from a doctest
+    example matches the expected output.  \class{OutputChecker}
+    defines two methods: \method{check_output}, which compares a given
+    pair of outputs, and returns true if they match; and
+    \method{output_difference}, which returns a string describing the
+    differences between two outputs.
+    \versionadded{2.4}
+\end{classdesc}
+
+\class{OutputChecker} defines the following methods:
+
+\begin{methoddesc}{check_output}{want, got, optionflags}
+    Return \code{True} iff the actual output from an example
+    (\var{got}) matches the expected output (\var{want}).  These
+    strings are always considered to match if they are identical; but
+    depending on what option flags the test runner is using, several
+    non-exact match types are also possible.  See
+    section~\ref{doctest-options} for more information about option
+    flags.
+\end{methoddesc}
+
+\begin{methoddesc}{output_difference}{example, got, optionflags}
+    Return a string describing the differences between the expected
+    output for a given example (\var{example}) and the actual output
+    (\var{got}).  \var{optionflags} is the set of option flags used to
+    compare \var{want} and \var{got}.
+\end{methoddesc}
+
+\subsection{Debugging\label{doctest-debugging}}
+
+Doctest provides several mechanisms for debugging doctest examples:
+
+\begin{itemize}
+\item Several functions convert doctests to executable Python
+      programs, which can be run under the Python debugger, \refmodule{pdb}.
+\item The \class{DebugRunner} class is a subclass of
+      \class{DocTestRunner} that raises an exception for the first
+      failing example, containing information about that example.
+      This information can be used to perform post-mortem debugging on
+      the example.
+\item The \refmodule{unittest} cases generated by \function{DocTestSuite()}
+      support the \method{debug()} method defined by
+      \class{\refmodule{unittest}.TestCase}.
+\item You can add a call to \function{\refmodule{pdb}.set_trace()} in a
+      doctest example, and you'll drop into the Python debugger when that
+      line is executed.  Then you can inspect current values of variables,
+      and so on.  For example, suppose \file{a.py} contains just this
+      module docstring:
+
+\begin{verbatim}
+"""
+>>> def f(x):
+...     g(x*2)
+>>> def g(x):
+...     print x+3
+...     import pdb; pdb.set_trace()
+>>> f(3)
+9
+"""
+\end{verbatim}
+
+      Then an interactive Python session may look like this:
+
+\begin{verbatim}
+>>> import a, doctest
+>>> doctest.testmod(a)
+--Return--
+> <doctest a[1]>(3)g()->None
+-> import pdb; pdb.set_trace()
+(Pdb) list
+  1     def g(x):
+  2         print x+3
+  3  ->     import pdb; pdb.set_trace()
+[EOF]
+(Pdb) print x
+6
+(Pdb) step
+--Return--
+> <doctest a[0]>(2)f()->None
+-> g(x*2)
+(Pdb) list
+  1     def f(x):
+  2  ->     g(x*2)
+[EOF]
+(Pdb) print x
+3
+(Pdb) step
+--Return--
+> <doctest a[2]>(1)?()->None
+-> f(3)
+(Pdb) cont
+(0, 3)
+>>>
+\end{verbatim}
+
+    \versionchanged[The ability to use \code{\refmodule{pdb}.set_trace()}
+                    usefully inside doctests was added]{2.4}
+\end{itemize}
+
+Functions that convert doctests to Python code, and possibly run
+the synthesized code under the debugger:
+
+\begin{funcdesc}{script_from_examples}{s}
+  Convert text with examples to a script.
+
+  Argument \var{s} is a string containing doctest examples.  The string
+  is converted to a Python script, where doctest examples in \var{s}
+  are converted to regular code, and everything else is converted to
+  Python comments.  The generated script is returned as a string.
+  For example,
+
+    \begin{verbatim}
+    import doctest
+    print doctest.script_from_examples(r"""
+        Set x and y to 1 and 2.
+        >>> x, y = 1, 2
+
+        Print their sum:
+        >>> print x+y
+        3
+    """)
+    \end{verbatim}
+
+  displays:
+
+    \begin{verbatim}
+    # Set x and y to 1 and 2.
+    x, y = 1, 2
+    #
+    # Print their sum:
+    print x+y
+    # Expected:
+    ## 3
+    \end{verbatim}
+
+  This function is used internally by other functions (see below), but
+  can also be useful when you want to transform an interactive Python
+  session into a Python script.
+
+  \versionadded{2.4}
+\end{funcdesc}
+
+\begin{funcdesc}{testsource}{module, name}
+   Convert the doctest for an object to a script.
+
+   Argument \var{module} is a module object, or dotted name of a module,
+   containing the object whose doctests are of interest.  Argument
+   \var{name} is the name (within the module) of the object with the
+   doctests of interest.  The result is a string, containing the
+   object's docstring converted to a Python script, as described for
+   \function{script_from_examples()} above.  For example, if module
+   \file{a.py} contains a top-level function \function{f()}, then
+
+\begin{verbatim}
+import a, doctest
+print doctest.testsource(a, "a.f")
+\end{verbatim}
+
+  prints a script version of function \function{f()}'s docstring,
+  with doctests converted to code, and the rest placed in comments.
+
+  \versionadded{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{debug}{module, name\optional{, pm}}
+  Debug the doctests for an object.
+
+  The \var{module} and \var{name} arguments are the same as for function
+  \function{testsource()} above.  The synthesized Python script for the
+  named object's docstring is written to a temporary file, and then that
+  file is run under the control of the Python debugger, \refmodule{pdb}.
+
+  A shallow copy of \code{\var{module}.__dict__} is used for both local
+  and global execution context.
+
+  Optional argument \var{pm} controls whether post-mortem debugging is
+  used.  If \var{pm} has a true value, the script file is run directly, and
+  the debugger gets involved only if the script terminates via raising an
+  unhandled exception.  If it does, then post-mortem debugging is invoked,
+  via \code{\refmodule{pdb}.post_mortem()}, passing the traceback object
+  from the unhandled exception.  If \var{pm} is not specified, or is false,
+  the script is run under the debugger from the start, via passing an
+  appropriate \function{execfile()} call to \code{\refmodule{pdb}.run()}.
+
+  \versionadded{2.3}
+
+  \versionchanged[The \var{pm} argument was added]{2.4}
+\end{funcdesc}
+
+\begin{funcdesc}{debug_src}{src\optional{, pm}\optional{, globs}}
+  Debug the doctests in a string.
+
+  This is like function \function{debug()} above, except that
+  a string containing doctest examples is specified directly, via
+  the \var{src} argument.
+
+  Optional argument \var{pm} has the same meaning as in function
+  \function{debug()} above.
+
+  Optional argument \var{globs} gives a dictionary to use as both
+  local and global execution context.  If not specified, or \code{None},
+  an empty dictionary is used.  If specified, a shallow copy of the
+  dictionary is used.
+
+  \versionadded{2.4}
+\end{funcdesc}
+
+The \class{DebugRunner} class, and the special exceptions it may raise,
+are of most interest to testing framework authors, and will only be
+sketched here.  See the source code, and especially \class{DebugRunner}'s
+docstring (which is a doctest!) for more details:
+
+\begin{classdesc}{DebugRunner}{\optional{checker}\optional{,
+                                 verbose}\optional{, optionflags}}
+
+    A subclass of \class{DocTestRunner} that raises an exception as
+    soon as a failure is encountered.  If an unexpected exception
+    occurs, an \exception{UnexpectedException} exception is raised,
+    containing the test, the example, and the original exception.  If
+    the output doesn't match, then a \exception{DocTestFailure}
+    exception is raised, containing the test, the example, and the
+    actual output.
+
+    For information about the constructor parameters and methods, see
+    the documentation for \class{DocTestRunner} in
+    section~\ref{doctest-advanced-api}.
+\end{classdesc}
+
+There are two exceptions that may be raised by \class{DebugRunner}
+instances:
+
+\begin{excclassdesc}{DocTestFailure}{test, example, got}
+    An exception thrown by \class{DocTestRunner} to signal that a
+    doctest example's actual output did not match its expected output.
+    The constructor arguments are used to initialize the member
+    variables of the same names.
+\end{excclassdesc}
+\exception{DocTestFailure} defines the following member variables:
+\begin{memberdesc}{test}
+    The \class{DocTest} object that was being run when the example failed.
+\end{memberdesc}
+\begin{memberdesc}{example}
+    The \class{Example} that failed.
+\end{memberdesc}
+\begin{memberdesc}{got}
+    The example's actual output.
+\end{memberdesc}
+
+\begin{excclassdesc}{UnexpectedException}{test, example, exc_info}
+    An exception thrown by \class{DocTestRunner} to signal that a
+    doctest example raised an unexpected exception.  The constructor
+    arguments are used to initialize the member variables of the same
+    names.
+\end{excclassdesc}
+\exception{UnexpectedException} defines the following member variables:
+\begin{memberdesc}{test}
+    The \class{DocTest} object that was being run when the example failed.
+\end{memberdesc}
+\begin{memberdesc}{example}
+    The \class{Example} that failed.
+\end{memberdesc}
+\begin{memberdesc}{exc_info}
+    A tuple containing information about the unexpected exception, as
+    returned by \function{sys.exc_info()}.
+\end{memberdesc}
+
+\subsection{Soapbox\label{doctest-soapbox}}
+
+As mentioned in the introduction, \refmodule{doctest} has grown to have
+three primary uses:
+
+\begin{enumerate}
+\item Checking examples in docstrings.
+\item Regression testing.
+\item Executable documentation / literate testing.
+\end{enumerate}
+
+These uses have different requirements, and it is important to
+distinguish them.  In particular, filling your docstrings with obscure
+test cases makes for bad documentation.
+
+When writing a docstring, choose docstring examples with care.
+There's an art to this that needs to be learned---it may not be
+natural at first.  Examples should add genuine value to the
+documentation.  A good example can often be worth many words.
+If done with care, the examples will be invaluable for your users, and
+will pay back the time it takes to collect them many times over as the
+years go by and things change.  I'm still amazed at how often one of
+my \refmodule{doctest} examples stops working after a "harmless"
+change.
+
+Doctest also makes an excellent tool for regression testing, especially if
+you don't skimp on explanatory text.  By interleaving prose and examples,
+it becomes much easier to keep track of what's actually being tested, and
+why.  When a test fails, good prose can make it much easier to figure out
+what the problem is, and how it should be fixed.  It's true that you could
+write extensive comments in code-based testing, but few programmers do.
+Many have found that using doctest approaches instead leads to much clearer
+tests.  Perhaps this is simply because doctest makes writing prose a little
+easier than writing code, while writing comments in code is a little
+harder.  I think it goes deeper than just that:  the natural attitude
+when writing a doctest-based test is that you want to explain the fine
+points of your software, and illustrate them with examples.  This in
+turn naturally leads to test files that start with the simplest features,
+and logically progress to complications and edge cases.  A coherent
+narrative is the result, instead of a collection of isolated functions
+that test isolated bits of functionality seemingly at random.  It's
+a different attitude, and produces different results, blurring the
+distinction between testing and explaining.
+
+Regression testing is best confined to dedicated objects or files.  There
+are several options for organizing tests:
+
+\begin{itemize}
+\item Write text files containing test cases as interactive examples,
+      and test the files using \function{testfile()} or
+      \function{DocFileSuite()}.  This is recommended, although is
+      easiest to do for new projects, designed from the start to use
+      doctest.
+\item Define functions named \code{_regrtest_\textit{topic}} that
+      consist of single docstrings, containing test cases for the
+      named topics.  These functions can be included in the same file
+      as the module, or separated out into a separate test file.
+\item Define a \code{__test__} dictionary mapping from regression test
+      topics to docstrings containing test cases.
+\end{itemize}

Added: vendor/Python/current/Doc/lib/libdocxmlrpc.tex
===================================================================
--- vendor/Python/current/Doc/lib/libdocxmlrpc.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libdocxmlrpc.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,105 @@
+\section{\module{DocXMLRPCServer} ---
+         Self-documenting XML-RPC server}
+
+\declaremodule{standard}{DocXMLRPCServer}
+\modulesynopsis{Self-documenting XML-RPC server implementation.}
+\moduleauthor{Brian Quinlan}{brianq at activestate.com}
+\sectionauthor{Brian Quinlan}{brianq at activestate.com}
+
+\versionadded{2.3}
+
+The \module{DocXMLRPCServer} module extends the classes found in
+\module{SimpleXMLRPCServer} to serve HTML documentation in response to
+HTTP GET requests. Servers can either be free standing, using
+\class{DocXMLRPCServer}, or embedded in a CGI environment, using
+\class{DocCGIXMLRPCRequestHandler}.
+
+\begin{classdesc}{DocXMLRPCServer}{addr\optional{, 
+                                   requestHandler\optional{, logRequests}}}
+
+Create a new server instance. All parameters have the same meaning as
+for \class{SimpleXMLRPCServer.SimpleXMLRPCServer};
+\var{requestHandler} defaults to \class{DocXMLRPCRequestHandler}.
+
+\end{classdesc}
+
+\begin{classdesc}{DocCGIXMLRPCRequestHandler}{}
+
+Create a new instance to handle XML-RPC requests in a CGI environment.
+
+\end{classdesc}
+
+\begin{classdesc}{DocXMLRPCRequestHandler}{}
+
+Create a new request handler instance. This request handler supports
+XML-RPC POST requests, documentation GET requests, and modifies
+logging so that the \var{logRequests} parameter to the
+\class{DocXMLRPCServer} constructor parameter is honored.
+
+\end{classdesc}
+
+\subsection{DocXMLRPCServer Objects \label{doc-xmlrpc-servers}}
+
+The \class{DocXMLRPCServer} class is derived from
+\class{SimpleXMLRPCServer.SimpleXMLRPCServer} and provides a means of
+creating self-documenting, stand alone XML-RPC servers. HTTP POST
+requests are handled as XML-RPC method calls. HTTP GET requests are
+handled by generating pydoc-style HTML documentation. This allows a
+server to provide its own web-based documentation.
+
+\begin{methoddesc}{set_server_title}{server_title}
+
+Set the title used in the generated HTML documentation. This title
+will be used inside the HTML "title" element.
+
+\end{methoddesc}
+
+\begin{methoddesc}{set_server_name}{server_name}
+
+Set the name used in the generated HTML documentation. This name will
+appear at the top of the generated documentation inside a "h1"
+element.
+
+\end{methoddesc}
+
+
+\begin{methoddesc}{set_server_documentation}{server_documentation}
+
+Set the description used in the generated HTML documentation. This
+description will appear as a paragraph, below the server name, in the
+documentation.
+
+\end{methoddesc}
+
+\subsection{DocCGIXMLRPCRequestHandler}
+
+The \class{DocCGIXMLRPCRequestHandler} class is derived from
+\class{SimpleXMLRPCServer.CGIXMLRPCRequestHandler} and provides a means
+of creating self-documenting, XML-RPC CGI scripts. HTTP POST requests
+are handled as XML-RPC method calls. HTTP GET requests are handled by
+generating pydoc-style HTML documentation. This allows a server to
+provide its own web-based documentation.
+
+\begin{methoddesc}{set_server_title}{server_title}
+
+Set the title used in the generated HTML documentation. This title
+will be used inside the HTML "title" element.
+
+\end{methoddesc}
+
+\begin{methoddesc}{set_server_name}{server_name}
+
+Set the name used in the generated HTML documentation. This name will
+appear at the top of the generated documentation inside a "h1"
+element.
+
+\end{methoddesc}
+
+
+\begin{methoddesc}{set_server_documentation}{server_documentation}
+
+Set the description used in the generated HTML documentation. This
+description will appear as a paragraph, below the server name, in the
+documentation.
+
+\end{methoddesc}

Added: vendor/Python/current/Doc/lib/libdumbdbm.tex
===================================================================
--- vendor/Python/current/Doc/lib/libdumbdbm.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libdumbdbm.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,63 @@
+\section{\module{dumbdbm} ---
+         Portable DBM implementation}
+
+\declaremodule{standard}{dumbdbm}
+\modulesynopsis{Portable implementation of the simple DBM interface.}
+
+\index{databases}
+
+\begin{notice}
+The \module{dumbdbm} module is intended as a last resort fallback for
+the \refmodule{anydbm} module when no more robust module is available.
+The \module{dumbdbm} module is not written for speed and is not nearly as
+heavily used as the other database modules.
+\end{notice}
+
+The \module{dumbdbm} module provides a persistent dictionary-like interface
+which is written entirely in Python.  Unlike other modules such as
+\refmodule{gdbm} and \refmodule{bsddb}, no external library is required.  As
+with other persistent mappings, the keys and values must always be strings.
+
+The module defines the following:
+
+\begin{excdesc}{error}
+Raised on dumbdbm-specific errors, such as I/O errors.  \exception{KeyError}
+is raised for general mapping errors like specifying an incorrect key.
+\end{excdesc}
+
+\begin{funcdesc}{open}{filename\optional{, flag\optional{, mode}}}
+Open a dumbdbm database and return a dumbdbm object.  The \var{filename}
+argument is the basename of the database file (without any specific
+extensions).  When a dumbdbm database is created, files with \file{.dat} and
+\file{.dir} extensions are created.
+
+The optional \var{flag} argument is currently ignored; the database is
+always opened for update, and will be created if it does not exist.
+
+The optional \var{mode} argument is the \UNIX{} mode of the file, used
+only when the database has to be created.  It defaults to octal
+\code{0666} (and will be modified by the prevailing umask).
+\versionchanged[The \var{mode} argument was ignored in earlier
+                versions]{2.2}
+\end{funcdesc}
+
+
+\begin{seealso}
+  \seemodule{anydbm}{Generic interface to \code{dbm}-style databases.}
+  \seemodule{dbm}{Similar interface to the DBM/NDBM library.}
+  \seemodule{gdbm}{Similar interface to the GNU GDBM library.}
+  \seemodule{shelve}{Persistence module which stores non-string data.}
+  \seemodule{whichdb}{Utility module used to determine the type of an
+                      existing database.}
+\end{seealso}
+
+
+\subsection{Dumbdbm Objects \label{dumbdbm-objects}}
+
+In addition to the methods provided by the \class{UserDict.DictMixin} class,
+\class{dumbdbm} objects provide the following methods.
+
+\begin{methoddesc}{sync}{}
+Synchronize the on-disk directory and data files.  This method is called by
+the \method{sync} method of \class{Shelve} objects.
+\end{methoddesc}

Added: vendor/Python/current/Doc/lib/libdummythread.tex
===================================================================
--- vendor/Python/current/Doc/lib/libdummythread.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libdummythread.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,22 @@
+\section{\module{dummy_thread} ---
+         Drop-in replacement for the \module{thread} module}
+
+\declaremodule[dummythread]{standard}{dummy_thread}
+\modulesynopsis{Drop-in replacement for the \refmodule{thread} module.}
+
+This module provides a duplicate interface to the \refmodule{thread}
+module.  It is meant to be imported when the \refmodule{thread} module
+is not provided on a platform.
+
+Suggested usage is:
+
+\begin{verbatim}
+try:
+    import thread as _thread
+except ImportError:
+    import dummy_thread as _thread
+\end{verbatim}
+
+Be careful to not use this module where deadlock might occur from a thread 
+being created that blocks waiting for another thread to be created.  This 
+often occurs with blocking I/O.

Added: vendor/Python/current/Doc/lib/libdummythreading.tex
===================================================================
--- vendor/Python/current/Doc/lib/libdummythreading.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libdummythreading.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,22 @@
+\section{\module{dummy_threading} ---
+         Drop-in replacement for the \module{threading} module}
+
+\declaremodule[dummythreading]{standard}{dummy_threading}
+\modulesynopsis{Drop-in replacement for the \refmodule{threading} module.}
+
+This module provides a duplicate interface to the
+\refmodule{threading} module.  It is meant to be imported when the
+\refmodule{thread} module is not provided on a platform.
+
+Suggested usage is:
+
+\begin{verbatim}
+try:
+    import threading as _threading
+except ImportError:
+    import dummy_threading as _threading
+\end{verbatim}
+
+Be careful to not use this module where deadlock might occur from a thread 
+being created that blocks waiting for another thread to be created.  This 
+often occurs with blocking I/O.

Added: vendor/Python/current/Doc/lib/liberrno.tex
===================================================================
--- vendor/Python/current/Doc/lib/liberrno.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/liberrno.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,149 @@
+\section{\module{errno} ---
+         Standard errno system symbols}
+
+\declaremodule{standard}{errno}
+\modulesynopsis{Standard errno system symbols.}
+
+
+This module makes available standard \code{errno} system symbols.
+The value of each symbol is the corresponding integer value.
+The names and descriptions are borrowed from \file{linux/include/errno.h},
+which should be pretty all-inclusive.
+
+\begin{datadesc}{errorcode}
+  Dictionary providing a mapping from the errno value to the string
+  name in the underlying system.  For instance,
+  \code{errno.errorcode[errno.EPERM]} maps to \code{'EPERM'}.
+\end{datadesc}
+
+To translate a numeric error code to an error message, use
+\function{os.strerror()}.
+
+Of the following list, symbols that are not used on the current
+platform are not defined by the module.  The specific list of defined
+symbols is available as \code{errno.errorcode.keys()}.  Symbols
+available can include:
+
+\begin{datadesc}{EPERM} Operation not permitted \end{datadesc}
+\begin{datadesc}{ENOENT} No such file or directory \end{datadesc}
+\begin{datadesc}{ESRCH} No such process \end{datadesc}
+\begin{datadesc}{EINTR} Interrupted system call \end{datadesc}
+\begin{datadesc}{EIO} I/O error \end{datadesc}
+\begin{datadesc}{ENXIO} No such device or address \end{datadesc}
+\begin{datadesc}{E2BIG} Arg list too long \end{datadesc}
+\begin{datadesc}{ENOEXEC} Exec format error \end{datadesc}
+\begin{datadesc}{EBADF} Bad file number \end{datadesc}
+\begin{datadesc}{ECHILD} No child processes \end{datadesc}
+\begin{datadesc}{EAGAIN} Try again \end{datadesc}
+\begin{datadesc}{ENOMEM} Out of memory \end{datadesc}
+\begin{datadesc}{EACCES} Permission denied \end{datadesc}
+\begin{datadesc}{EFAULT} Bad address \end{datadesc}
+\begin{datadesc}{ENOTBLK} Block device required \end{datadesc}
+\begin{datadesc}{EBUSY} Device or resource busy \end{datadesc}
+\begin{datadesc}{EEXIST} File exists \end{datadesc}
+\begin{datadesc}{EXDEV} Cross-device link \end{datadesc}
+\begin{datadesc}{ENODEV} No such device \end{datadesc}
+\begin{datadesc}{ENOTDIR} Not a directory \end{datadesc}
+\begin{datadesc}{EISDIR} Is a directory \end{datadesc}
+\begin{datadesc}{EINVAL} Invalid argument \end{datadesc}
+\begin{datadesc}{ENFILE} File table overflow \end{datadesc}
+\begin{datadesc}{EMFILE} Too many open files \end{datadesc}
+\begin{datadesc}{ENOTTY} Not a typewriter \end{datadesc}
+\begin{datadesc}{ETXTBSY} Text file busy \end{datadesc}
+\begin{datadesc}{EFBIG} File too large \end{datadesc}
+\begin{datadesc}{ENOSPC} No space left on device \end{datadesc}
+\begin{datadesc}{ESPIPE} Illegal seek \end{datadesc}
+\begin{datadesc}{EROFS} Read-only file system \end{datadesc}
+\begin{datadesc}{EMLINK} Too many links \end{datadesc}
+\begin{datadesc}{EPIPE} Broken pipe \end{datadesc}
+\begin{datadesc}{EDOM} Math argument out of domain of func \end{datadesc}
+\begin{datadesc}{ERANGE} Math result not representable \end{datadesc}
+\begin{datadesc}{EDEADLK} Resource deadlock would occur \end{datadesc}
+\begin{datadesc}{ENAMETOOLONG} File name too long \end{datadesc}
+\begin{datadesc}{ENOLCK} No record locks available \end{datadesc}
+\begin{datadesc}{ENOSYS} Function not implemented \end{datadesc}
+\begin{datadesc}{ENOTEMPTY} Directory not empty \end{datadesc}
+\begin{datadesc}{ELOOP} Too many symbolic links encountered \end{datadesc}
+\begin{datadesc}{EWOULDBLOCK} Operation would block \end{datadesc}
+\begin{datadesc}{ENOMSG} No message of desired type \end{datadesc}
+\begin{datadesc}{EIDRM} Identifier removed \end{datadesc}
+\begin{datadesc}{ECHRNG} Channel number out of range \end{datadesc}
+\begin{datadesc}{EL2NSYNC} Level 2 not synchronized \end{datadesc}
+\begin{datadesc}{EL3HLT} Level 3 halted \end{datadesc}
+\begin{datadesc}{EL3RST} Level 3 reset \end{datadesc}
+\begin{datadesc}{ELNRNG} Link number out of range \end{datadesc}
+\begin{datadesc}{EUNATCH} Protocol driver not attached \end{datadesc}
+\begin{datadesc}{ENOCSI} No CSI structure available \end{datadesc}
+\begin{datadesc}{EL2HLT} Level 2 halted \end{datadesc}
+\begin{datadesc}{EBADE} Invalid exchange \end{datadesc}
+\begin{datadesc}{EBADR} Invalid request descriptor \end{datadesc}
+\begin{datadesc}{EXFULL} Exchange full \end{datadesc}
+\begin{datadesc}{ENOANO} No anode \end{datadesc}
+\begin{datadesc}{EBADRQC} Invalid request code \end{datadesc}
+\begin{datadesc}{EBADSLT} Invalid slot \end{datadesc}
+\begin{datadesc}{EDEADLOCK} File locking deadlock error \end{datadesc}
+\begin{datadesc}{EBFONT} Bad font file format \end{datadesc}
+\begin{datadesc}{ENOSTR} Device not a stream \end{datadesc}
+\begin{datadesc}{ENODATA} No data available \end{datadesc}
+\begin{datadesc}{ETIME} Timer expired \end{datadesc}
+\begin{datadesc}{ENOSR} Out of streams resources \end{datadesc}
+\begin{datadesc}{ENONET} Machine is not on the network \end{datadesc}
+\begin{datadesc}{ENOPKG} Package not installed \end{datadesc}
+\begin{datadesc}{EREMOTE} Object is remote \end{datadesc}
+\begin{datadesc}{ENOLINK} Link has been severed \end{datadesc}
+\begin{datadesc}{EADV} Advertise error \end{datadesc}
+\begin{datadesc}{ESRMNT} Srmount error \end{datadesc}
+\begin{datadesc}{ECOMM} Communication error on send \end{datadesc}
+\begin{datadesc}{EPROTO} Protocol error \end{datadesc}
+\begin{datadesc}{EMULTIHOP} Multihop attempted \end{datadesc}
+\begin{datadesc}{EDOTDOT} RFS specific error \end{datadesc}
+\begin{datadesc}{EBADMSG} Not a data message \end{datadesc}
+\begin{datadesc}{EOVERFLOW} Value too large for defined data type \end{datadesc}
+\begin{datadesc}{ENOTUNIQ} Name not unique on network \end{datadesc}
+\begin{datadesc}{EBADFD} File descriptor in bad state \end{datadesc}
+\begin{datadesc}{EREMCHG} Remote address changed \end{datadesc}
+\begin{datadesc}{ELIBACC} Can not access a needed shared library \end{datadesc}
+\begin{datadesc}{ELIBBAD} Accessing a corrupted shared library \end{datadesc}
+\begin{datadesc}{ELIBSCN} .lib section in a.out corrupted \end{datadesc}
+\begin{datadesc}{ELIBMAX} Attempting to link in too many shared libraries \end{datadesc}
+\begin{datadesc}{ELIBEXEC} Cannot exec a shared library directly \end{datadesc}
+\begin{datadesc}{EILSEQ} Illegal byte sequence \end{datadesc}
+\begin{datadesc}{ERESTART} Interrupted system call should be restarted \end{datadesc}
+\begin{datadesc}{ESTRPIPE} Streams pipe error \end{datadesc}
+\begin{datadesc}{EUSERS} Too many users \end{datadesc}
+\begin{datadesc}{ENOTSOCK} Socket operation on non-socket \end{datadesc}
+\begin{datadesc}{EDESTADDRREQ} Destination address required \end{datadesc}
+\begin{datadesc}{EMSGSIZE} Message too long \end{datadesc}
+\begin{datadesc}{EPROTOTYPE} Protocol wrong type for socket \end{datadesc}
+\begin{datadesc}{ENOPROTOOPT} Protocol not available \end{datadesc}
+\begin{datadesc}{EPROTONOSUPPORT} Protocol not supported \end{datadesc}
+\begin{datadesc}{ESOCKTNOSUPPORT} Socket type not supported \end{datadesc}
+\begin{datadesc}{EOPNOTSUPP} Operation not supported on transport endpoint \end{datadesc}
+\begin{datadesc}{EPFNOSUPPORT} Protocol family not supported \end{datadesc}
+\begin{datadesc}{EAFNOSUPPORT} Address family not supported by protocol \end{datadesc}
+\begin{datadesc}{EADDRINUSE} Address already in use \end{datadesc}
+\begin{datadesc}{EADDRNOTAVAIL} Cannot assign requested address \end{datadesc}
+\begin{datadesc}{ENETDOWN} Network is down \end{datadesc}
+\begin{datadesc}{ENETUNREACH} Network is unreachable \end{datadesc}
+\begin{datadesc}{ENETRESET} Network dropped connection because of reset \end{datadesc}
+\begin{datadesc}{ECONNABORTED} Software caused connection abort \end{datadesc}
+\begin{datadesc}{ECONNRESET} Connection reset by peer \end{datadesc}
+\begin{datadesc}{ENOBUFS} No buffer space available \end{datadesc}
+\begin{datadesc}{EISCONN} Transport endpoint is already connected \end{datadesc}
+\begin{datadesc}{ENOTCONN} Transport endpoint is not connected \end{datadesc}
+\begin{datadesc}{ESHUTDOWN} Cannot send after transport endpoint shutdown \end{datadesc}
+\begin{datadesc}{ETOOMANYREFS} Too many references: cannot splice \end{datadesc}
+\begin{datadesc}{ETIMEDOUT} Connection timed out \end{datadesc}
+\begin{datadesc}{ECONNREFUSED} Connection refused \end{datadesc}
+\begin{datadesc}{EHOSTDOWN} Host is down \end{datadesc}
+\begin{datadesc}{EHOSTUNREACH} No route to host \end{datadesc}
+\begin{datadesc}{EALREADY} Operation already in progress \end{datadesc}
+\begin{datadesc}{EINPROGRESS} Operation now in progress \end{datadesc}
+\begin{datadesc}{ESTALE} Stale NFS file handle \end{datadesc}
+\begin{datadesc}{EUCLEAN} Structure needs cleaning \end{datadesc}
+\begin{datadesc}{ENOTNAM} Not a XENIX named type file \end{datadesc}
+\begin{datadesc}{ENAVAIL} No XENIX semaphores available \end{datadesc}
+\begin{datadesc}{EISNAM} Is a named type file \end{datadesc}
+\begin{datadesc}{EREMOTEIO} Remote I/O error \end{datadesc}
+\begin{datadesc}{EDQUOT} Quota exceeded \end{datadesc}
+

Added: vendor/Python/current/Doc/lib/libetree.tex
===================================================================
--- vendor/Python/current/Doc/lib/libetree.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libetree.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,356 @@
+\section{\module{xml.etree.ElementTree} --- The ElementTree XML API}
+\declaremodule{standard}{xml.etree.ElementTree}
+\moduleauthor{Fredrik Lundh}{fredrik at pythonware.com}
+\modulesynopsis{Implementation of the ElementTree API.}
+
+\versionadded{2.5}
+
+The Element type is a flexible container object, designed to store
+hierarchical data structures in memory. The type can be described as a
+cross between a list and a dictionary.
+
+Each element has a number of properties associated with it:
+
+\begin{itemize}
+  \item a tag which is a string identifying what kind of data
+        this element represents (the element type, in other words).
+  \item a number of attributes, stored in a Python dictionary.
+  \item a text string.
+  \item an optional tail string.
+  \item a number of child elements, stored in a Python sequence
+\end{itemize}
+
+To create an element instance, use the Element or SubElement factory
+functions.
+
+The \class{ElementTree} class can be used to wrap an element
+structure, and convert it from and to XML.
+
+A C implementation of this API is available as
+\module{xml.etree.cElementTree}.
+
+
+\subsection{Functions\label{elementtree-functions}}
+
+\begin{funcdesc}{Comment}{\optional{text}}
+Comment element factory.  This factory function creates a special
+element that will be serialized as an XML comment.
+The comment string can be either an 8-bit ASCII string or a Unicode
+string.
+\var{text} is a string containing the comment string.
+
+\begin{datadescni}{Returns:}
+An element instance, representing a comment.
+\end{datadescni}
+\end{funcdesc}
+
+\begin{funcdesc}{dump}{elem}
+Writes an element tree or element structure to sys.stdout.  This
+function should be used for debugging only.
+
+The exact output format is implementation dependent.  In this
+version, it's written as an ordinary XML file.
+
+\var{elem} is an element tree or an individual element.
+\end{funcdesc}
+
+\begin{funcdesc}{Element}{tag\optional{, attrib}\optional{, **extra}}
+Element factory.  This function returns an object implementing the
+standard Element interface.  The exact class or type of that object
+is implementation dependent, but it will always be compatible with
+the {\_}ElementInterface class in this module.
+
+The element name, attribute names, and attribute values can be
+either 8-bit ASCII strings or Unicode strings.
+\var{tag} is the element name.
+\var{attrib} is an optional dictionary, containing element attributes.
+\var{extra} contains additional attributes, given as keyword arguments.
+
+\begin{datadescni}{Returns:}
+An element instance.
+\end{datadescni}
+\end{funcdesc}
+
+\begin{funcdesc}{fromstring}{text}
+Parses an XML section from a string constant.  Same as XML.
+\var{text} is a string containing XML data.
+
+\begin{datadescni}{Returns:}
+An Element instance.
+\end{datadescni}
+\end{funcdesc}
+
+\begin{funcdesc}{iselement}{element}
+Checks if an object appears to be a valid element object.
+\var{element} is an element instance.
+
+\begin{datadescni}{Returns:}
+A true value if this is an element object.
+\end{datadescni}
+\end{funcdesc}
+
+\begin{funcdesc}{iterparse}{source\optional{, events}}
+Parses an XML section into an element tree incrementally, and reports
+what's going on to the user.
+\var{source} is a filename or file object containing XML data.
+\var{events} is a list of events to report back.  If omitted, only ``end''
+events are reported.
+
+\begin{datadescni}{Returns:}
+A (event, elem) iterator.
+\end{datadescni}
+\end{funcdesc}
+
+\begin{funcdesc}{parse}{source\optional{, parser}}
+Parses an XML section into an element tree.
+\var{source} is a filename or file object containing XML data.
+\var{parser} is an optional parser instance.  If not given, the
+standard XMLTreeBuilder parser is used.
+
+\begin{datadescni}{Returns:}
+An ElementTree instance
+\end{datadescni}
+\end{funcdesc}
+
+\begin{funcdesc}{ProcessingInstruction}{target\optional{, text}}
+PI element factory.  This factory function creates a special element
+that will be serialized as an XML processing instruction.
+\var{target} is a string containing the PI target.
+\var{text} is a string containing the PI contents, if given.
+
+\begin{datadescni}{Returns:}
+An element instance, representing a PI.
+\end{datadescni}
+\end{funcdesc}
+
+\begin{funcdesc}{SubElement}{parent, tag\optional{, attrib} \optional{, **extra}}
+Subelement factory.  This function creates an element instance, and
+appends it to an existing element.
+
+The element name, attribute names, and attribute values can be
+either 8-bit ASCII strings or Unicode strings.
+\var{parent} is the parent element.
+\var{tag} is the subelement name.
+\var{attrib} is an optional dictionary, containing element attributes.
+\var{extra} contains additional attributes, given as keyword arguments.
+
+\begin{datadescni}{Returns:}
+An element instance.
+\end{datadescni}
+\end{funcdesc}
+
+\begin{funcdesc}{tostring}{element\optional{, encoding}}
+Generates a string representation of an XML element, including all
+subelements.
+\var{element} is an Element instance.
+\var{encoding} is the output encoding (default is US-ASCII).
+
+\begin{datadescni}{Returns:}
+An encoded string containing the XML data.
+\end{datadescni}
+\end{funcdesc}
+
+\begin{funcdesc}{XML}{text}
+Parses an XML section from a string constant.  This function can
+be used to embed ``XML literals'' in Python code.
+\var{text} is a string containing XML data.
+
+\begin{datadescni}{Returns:}
+An Element instance.
+\end{datadescni}
+\end{funcdesc}
+
+\begin{funcdesc}{XMLID}{text}
+Parses an XML section from a string constant, and also returns
+a dictionary which maps from element id:s to elements.
+\var{text} is a string containing XML data.
+
+\begin{datadescni}{Returns:}
+A tuple containing an Element instance and a dictionary.
+\end{datadescni}
+\end{funcdesc}
+
+
+\subsection{ElementTree Objects\label{elementtree-elementtree-objects}}
+
+\begin{classdesc}{ElementTree}{\optional{element,} \optional{file}}
+ElementTree wrapper class.  This class represents an entire element
+hierarchy, and adds some extra support for serialization to and from
+standard XML.
+
+\var{element} is the root element.
+The tree is initialized with the contents of the XML \var{file} if given.
+\end{classdesc}
+
+\begin{methoddesc}{_setroot}{element}
+Replaces the root element for this tree.  This discards the
+current contents of the tree, and replaces it with the given
+element.  Use with care.
+\var{element} is an element instance.
+\end{methoddesc}
+
+\begin{methoddesc}{find}{path}
+Finds the first toplevel element with given tag.
+Same as getroot().find(path).
+\var{path} is the element to look for.
+
+\begin{datadescni}{Returns:}
+The first matching element, or None if no element was found.
+\end{datadescni}
+\end{methoddesc}
+
+\begin{methoddesc}{findall}{path}
+Finds all toplevel elements with the given tag.
+Same as getroot().findall(path).
+\var{path} is the element to look for.
+
+\begin{datadescni}{Returns:}
+A list or iterator containing all matching elements,
+in section order.
+\end{datadescni}
+\end{methoddesc}
+
+\begin{methoddesc}{findtext}{path\optional{, default}}
+Finds the element text for the first toplevel element with given
+tag.  Same as getroot().findtext(path).
+\var{path} is the toplevel element to look for.
+\var{default} is the value to return if the element was not found.
+
+\begin{datadescni}{Returns:}
+The text content of the first matching element, or the
+default value no element was found.  Note that if the element
+has is found, but has no text content, this method returns an
+empty string.
+\end{datadescni}
+\end{methoddesc}
+
+\begin{methoddesc}{getiterator}{\optional{tag}}
+Creates a tree iterator for the root element.  The iterator loops
+over all elements in this tree, in section order.
+\var{tag} is the tag to look for (default is to return all elements)
+
+\begin{datadescni}{Returns:}
+An iterator.
+\end{datadescni}
+\end{methoddesc}
+
+\begin{methoddesc}{getroot}{}
+Gets the root element for this tree.
+
+\begin{datadescni}{Returns:}
+An element instance.
+\end{datadescni}
+\end{methoddesc}
+
+\begin{methoddesc}{parse}{source\optional{, parser}}
+Loads an external XML section into this element tree.
+\var{source} is a file name or file object.
+\var{parser} is an optional parser instance.  If not given, the
+standard XMLTreeBuilder parser is used.
+
+\begin{datadescni}{Returns:}
+The section root element.
+\end{datadescni}
+\end{methoddesc}
+
+\begin{methoddesc}{write}{file\optional{, encoding}}
+Writes the element tree to a file, as XML.
+\var{file} is a file name, or a file object opened for writing.
+\var{encoding} is the output encoding (default is US-ASCII).
+\end{methoddesc}
+
+
+\subsection{QName Objects\label{elementtree-qname-objects}}
+
+\begin{classdesc}{QName}{text_or_uri\optional{, tag}}
+QName wrapper.  This can be used to wrap a QName attribute value, in
+order to get proper namespace handling on output.
+\var{text_or_uri} is a string containing the QName value,
+in the form {\{}uri{\}}local, or, if the tag argument is given,
+the URI part of a QName.
+If \var{tag} is given, the first argument is interpreted as
+an URI, and this argument is interpreted as a local name.
+
+\begin{datadescni}{Returns:}
+An opaque object, representing the QName.
+\end{datadescni}
+\end{classdesc}
+
+
+\subsection{TreeBuilder Objects\label{elementtree-treebuilder-objects}}
+
+\begin{classdesc}{TreeBuilder}{\optional{element_factory}}
+Generic element structure builder.  This builder converts a sequence
+of start, data, and end method calls to a well-formed element structure.
+You can use this class to build an element structure using a custom XML
+parser, or a parser for some other XML-like format.
+The \var{element_factory} is called to create new Element instances when
+given.
+\end{classdesc}
+
+\begin{methoddesc}{close}{}
+Flushes the parser buffers, and returns the toplevel documen
+element.
+
+\begin{datadescni}{Returns:}
+An Element instance.
+\end{datadescni}
+\end{methoddesc}
+
+\begin{methoddesc}{data}{data}
+Adds text to the current element.
+\var{data} is a string.  This should be either an 8-bit string
+containing ASCII text, or a Unicode string.
+\end{methoddesc}
+
+\begin{methoddesc}{end}{tag}
+Closes the current element.
+\var{tag} is the element name.
+
+\begin{datadescni}{Returns:}
+The closed element.
+\end{datadescni}
+\end{methoddesc}
+
+\begin{methoddesc}{start}{tag, attrs}
+Opens a new element.
+\var{tag} is the element name.
+\var{attrs} is a dictionary containing element attributes.
+
+\begin{datadescni}{Returns:}
+The opened element.
+\end{datadescni}
+\end{methoddesc}
+
+
+\subsection{XMLTreeBuilder Objects\label{elementtree-xmltreebuilder-objects}}
+
+\begin{classdesc}{XMLTreeBuilder}{\optional{html,} \optional{target}}
+Element structure builder for XML source data, based on the
+expat parser.
+\var{html} are predefined HTML entities.  This flag is not supported
+by the current implementation.
+\var{target} is the target object.  If omitted, the builder uses an
+instance of the standard TreeBuilder class.
+\end{classdesc}
+
+\begin{methoddesc}{close}{}
+Finishes feeding data to the parser.
+
+\begin{datadescni}{Returns:}
+An element structure.
+\end{datadescni}
+\end{methoddesc}
+
+\begin{methoddesc}{doctype}{name, pubid, system}
+Handles a doctype declaration.
+\var{name} is the doctype name.
+\var{pubid} is the public identifier.
+\var{system} is the system identifier.
+\end{methoddesc}
+
+\begin{methoddesc}{feed}{data}
+Feeds data to the parser.
+
+\var{data} is encoded data.
+\end{methoddesc}

Added: vendor/Python/current/Doc/lib/libexcs.tex
===================================================================
--- vendor/Python/current/Doc/lib/libexcs.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libexcs.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,466 @@
+\section{Built-in Exceptions}
+
+\declaremodule{standard}{exceptions}
+\modulesynopsis{Standard exception classes.}
+
+
+Exceptions should be class objects.  
+The exceptions are defined in the module \module{exceptions}.  This
+module never needs to be imported explicitly: the exceptions are
+provided in the built-in namespace as well as the \module{exceptions}
+module.
+
+\begin{notice}
+In past versions of Python string exceptions were supported.  In
+Python 1.5 and newer versions, all standard exceptions have been
+converted to class objects and users are encouraged to do the same.
+String exceptions will raise a \code{DeprecationWarning} in Python 2.5 and
+newer.
+In future versions, support for string exceptions will be removed.
+
+Two distinct string objects with the same value are considered different
+exceptions.  This is done to force programmers to use exception names
+rather than their string value when specifying exception handlers.
+The string value of all built-in exceptions is their name, but this is
+not a requirement for user-defined exceptions or exceptions defined by
+library modules.
+\end{notice}
+
+For class exceptions, in a \keyword{try}\stindex{try} statement with
+an \keyword{except}\stindex{except} clause that mentions a particular
+class, that clause also handles any exception classes derived from
+that class (but not exception classes from which \emph{it} is
+derived).  Two exception classes that are not related via subclassing
+are never equivalent, even if they have the same name.
+
+The built-in exceptions listed below can be generated by the
+interpreter or built-in functions.  Except where mentioned, they have
+an ``associated value'' indicating the detailed cause of the error.
+This may be a string or a tuple containing several items of
+information (e.g., an error code and a string explaining the code).
+The associated value is the second argument to the
+\keyword{raise}\stindex{raise} statement.  For string exceptions, the
+associated value itself will be stored in the variable named as the
+second argument of the \keyword{except} clause (if any).  For class
+exceptions, that variable receives the exception instance.  If the
+exception class is derived from the standard root class
+\exception{BaseException}, the associated value is present as the
+exception instance's \member{args} attribute.  If there is a single argument
+(as is preferred), it is bound to the \member{message} attribute.
+
+User code can raise built-in exceptions.  This can be used to test an
+exception handler or to report an error condition ``just like'' the
+situation in which the interpreter raises the same exception; but
+beware that there is nothing to prevent user code from raising an
+inappropriate error.
+
+The built-in exception classes can be sub-classed to define new
+exceptions; programmers are encouraged to at least derive new
+exceptions from the \exception{Exception} class and not
+\exception{BaseException}.  More
+information on defining exceptions is available in the
+\citetitle[../tut/tut.html]{Python Tutorial} under the heading
+``User-defined Exceptions.''
+
+\setindexsubitem{(built-in exception base class)}
+
+The following exceptions are only used as base classes for other
+exceptions.
+
+\begin{excdesc}{BaseException}
+The base class for all built-in exceptions.  It is not meant to be directly
+inherited by user-defined classes (for that use \exception{Exception}).  If
+\function{str()} or \function{unicode()} is called on an instance of this
+class, the representation of the argument(s) to the instance are returned or
+the emptry string when there were no arguments.  If only a single argument is
+passed in, it is stored in the \member{message} attribute.  If more than one
+argument is passed in, \member{message} is set to the empty string.  These
+semantics are meant to reflect the fact that \member{message} is to store a
+text message explaining why the exception had been raised.  If more data needs
+to be attached to the exception, attach it through arbitrary attributes on the
+instance.  All arguments are also stored in \member{args} as a tuple, but it will
+eventually be deprecated and thus its use is discouraged.
+\versionadded{2.5}
+\end{excdesc}
+
+\begin{excdesc}{Exception}
+All built-in, non-system-exiting exceptions are derived
+from this class.  All user-defined exceptions should also be derived
+from this class.
+\versionchanged[Changed to inherit from \exception{BaseException}]{2.5}
+\end{excdesc}
+
+\begin{excdesc}{StandardError}
+The base class for all built-in exceptions except
+\exception{StopIteration}, \exception{GeneratorExit},
+\exception{KeyboardInterrupt} and \exception{SystemExit}.
+\exception{StandardError} itself is derived from \exception{Exception}.
+\end{excdesc}
+
+\begin{excdesc}{ArithmeticError}
+The base class for those built-in exceptions that are raised for
+various arithmetic errors: \exception{OverflowError},
+\exception{ZeroDivisionError}, \exception{FloatingPointError}.
+\end{excdesc}
+
+\begin{excdesc}{LookupError}
+The base class for the exceptions that are raised when a key or
+index used on a mapping or sequence is invalid: \exception{IndexError},
+\exception{KeyError}.  This can be raised directly by
+\function{sys.setdefaultencoding()}.
+\end{excdesc}
+
+\begin{excdesc}{EnvironmentError}
+The base class for exceptions that
+can occur outside the Python system: \exception{IOError},
+\exception{OSError}.  When exceptions of this type are created with a
+2-tuple, the first item is available on the instance's \member{errno}
+attribute (it is assumed to be an error number), and the second item
+is available on the \member{strerror} attribute (it is usually the
+associated error message).  The tuple itself is also available on the
+\member{args} attribute.
+\versionadded{1.5.2}
+
+When an \exception{EnvironmentError} exception is instantiated with a
+3-tuple, the first two items are available as above, while the third
+item is available on the \member{filename} attribute.  However, for
+backwards compatibility, the \member{args} attribute contains only a
+2-tuple of the first two constructor arguments.
+
+The \member{filename} attribute is \code{None} when this exception is
+created with other than 3 arguments.  The \member{errno} and
+\member{strerror} attributes are also \code{None} when the instance was
+created with other than 2 or 3 arguments.  In this last case,
+\member{args} contains the verbatim constructor arguments as a tuple.
+\end{excdesc}
+
+
+\setindexsubitem{(built-in exception)}
+
+The following exceptions are the exceptions that are actually raised.
+
+\begin{excdesc}{AssertionError}
+\stindex{assert}
+Raised when an \keyword{assert} statement fails.
+\end{excdesc}
+
+\begin{excdesc}{AttributeError}
+% xref to attribute reference?
+  Raised when an attribute reference or assignment fails.  (When an
+  object does not support attribute references or attribute assignments
+  at all, \exception{TypeError} is raised.)
+\end{excdesc}
+
+\begin{excdesc}{EOFError}
+% XXXJH xrefs here
+  Raised when one of the built-in functions (\function{input()} or
+  \function{raw_input()}) hits an end-of-file condition (\EOF) without
+  reading any data.
+% XXXJH xrefs here
+  (N.B.: the \method{read()} and \method{readline()} methods of file
+  objects return an empty string when they hit \EOF.)
+\end{excdesc}
+
+\begin{excdesc}{FloatingPointError}
+  Raised when a floating point operation fails.  This exception is
+  always defined, but can only be raised when Python is configured
+  with the \longprogramopt{with-fpectl} option, or the
+  \constant{WANT_SIGFPE_HANDLER} symbol is defined in the
+  \file{pyconfig.h} file.
+\end{excdesc}
+
+\begin{excdesc}{GeneratorExit}
+  Raise when a generator's \method{close()} method is called.
+  It directly inherits from \exception{Exception} instead of
+  \exception{StandardError} since it is technically not an error.
+  \versionadded{2.5}
+\end{excdesc}
+
+\begin{excdesc}{IOError}
+% XXXJH xrefs here
+  Raised when an I/O operation (such as a \keyword{print} statement,
+  the built-in \function{open()} function or a method of a file
+  object) fails for an I/O-related reason, e.g., ``file not found'' or
+  ``disk full''.
+
+  This class is derived from \exception{EnvironmentError}.  See the
+  discussion above for more information on exception instance
+  attributes.
+\end{excdesc}
+
+\begin{excdesc}{ImportError}
+% XXXJH xref to import statement?
+  Raised when an \keyword{import} statement fails to find the module
+  definition or when a \code{from \textrm{\ldots} import} fails to find a
+  name that is to be imported.
+\end{excdesc}
+
+\begin{excdesc}{IndexError}
+% XXXJH xref to sequences
+  Raised when a sequence subscript is out of range.  (Slice indices are
+  silently truncated to fall in the allowed range; if an index is not a
+  plain integer, \exception{TypeError} is raised.)
+\end{excdesc}
+
+\begin{excdesc}{KeyError}
+% XXXJH xref to mapping objects?
+  Raised when a mapping (dictionary) key is not found in the set of
+  existing keys.
+\end{excdesc}
+
+\begin{excdesc}{KeyboardInterrupt}
+  Raised when the user hits the interrupt key (normally
+  \kbd{Control-C} or \kbd{Delete}).  During execution, a check for
+  interrupts is made regularly.
+% XXX(hylton) xrefs here
+  Interrupts typed when a built-in function \function{input()} or
+  \function{raw_input()} is waiting for input also raise this
+  exception.
+  The exception inherits from \exception{BaseException} so as to not be
+  accidentally caught by code that catches \exception{Exception} and thus
+  prevent the interpreter from exiting.
+  \versionchanged[Changed to inherit from \exception{BaseException}]{2.5}
+\end{excdesc}
+
+\begin{excdesc}{MemoryError}
+  Raised when an operation runs out of memory but the situation may
+  still be rescued (by deleting some objects).  The associated value is
+  a string indicating what kind of (internal) operation ran out of memory.
+  Note that because of the underlying memory management architecture
+  (C's \cfunction{malloc()} function), the interpreter may not
+  always be able to completely recover from this situation; it
+  nevertheless raises an exception so that a stack traceback can be
+  printed, in case a run-away program was the cause.
+\end{excdesc}
+
+\begin{excdesc}{NameError}
+  Raised when a local or global name is not found.  This applies only
+  to unqualified names.  The associated value is an error message that
+  includes the name that could not be found.
+\end{excdesc}
+
+\begin{excdesc}{NotImplementedError}
+  This exception is derived from \exception{RuntimeError}.  In user
+  defined base classes, abstract methods should raise this exception
+  when they require derived classes to override the method.
+  \versionadded{1.5.2}
+\end{excdesc}
+
+\begin{excdesc}{OSError}
+  %xref for os module
+  This class is derived from \exception{EnvironmentError} and is used
+  primarily as the \refmodule{os} module's \code{os.error} exception.
+  See \exception{EnvironmentError} above for a description of the
+  possible associated values.
+  \versionadded{1.5.2}
+\end{excdesc}
+
+\begin{excdesc}{OverflowError}
+% XXXJH reference to long's and/or int's?
+  Raised when the result of an arithmetic operation is too large to be
+  represented.  This cannot occur for long integers (which would rather
+  raise \exception{MemoryError} than give up).  Because of the lack of
+  standardization of floating point exception handling in C, most
+  floating point operations also aren't checked.  For plain integers,
+  all operations that can overflow are checked except left shift, where
+  typical applications prefer to drop bits than raise an exception.
+\end{excdesc}
+
+\begin{excdesc}{ReferenceError}
+  This exception is raised when a weak reference proxy, created by the
+  \function{\refmodule{weakref}.proxy()} function, is used to access
+  an attribute of the referent after it has been garbage collected.
+  For more information on weak references, see the \refmodule{weakref}
+  module.
+  \versionadded[Previously known as the
+                \exception{\refmodule{weakref}.ReferenceError}
+                exception]{2.2}
+\end{excdesc}
+
+\begin{excdesc}{RuntimeError}
+  Raised when an error is detected that doesn't fall in any of the
+  other categories.  The associated value is a string indicating what
+  precisely went wrong.  (This exception is mostly a relic from a
+  previous version of the interpreter; it is not used very much any
+  more.)
+\end{excdesc}
+
+\begin{excdesc}{StopIteration}
+  Raised by an iterator's \method{next()} method to signal that there
+  are no further values.
+  This is derived from \exception{Exception} rather than
+  \exception{StandardError}, since this is not considered an error in
+  its normal application.
+  \versionadded{2.2}
+\end{excdesc}
+
+
+\begin{excdesc}{SyntaxError}
+% XXXJH xref to these functions?
+  Raised when the parser encounters a syntax error.  This may occur in
+  an \keyword{import} statement, in an \keyword{exec} statement, in a call
+  to the built-in function \function{eval()} or \function{input()}, or
+  when reading the initial script or standard input (also
+  interactively).
+
+  Instances of this class have attributes \member{filename},
+  \member{lineno}, \member{offset} and \member{text} for easier access
+  to the details.  \function{str()} of the exception instance returns
+  only the message.
+\end{excdesc}
+
+\begin{excdesc}{SystemError}
+  Raised when the interpreter finds an internal error, but the
+  situation does not look so serious to cause it to abandon all hope.
+  The associated value is a string indicating what went wrong (in
+  low-level terms).
+  
+  You should report this to the author or maintainer of your Python
+  interpreter.  Be sure to report the version of the Python
+  interpreter (\code{sys.version}; it is also printed at the start of an
+  interactive Python session), the exact error message (the exception's
+  associated value) and if possible the source of the program that
+  triggered the error.
+\end{excdesc}
+
+\begin{excdesc}{SystemExit}
+% XXX(hylton) xref to module sys?
+  This exception is raised by the \function{sys.exit()} function.  When it
+  is not handled, the Python interpreter exits; no stack traceback is
+  printed.  If the associated value is a plain integer, it specifies the
+  system exit status (passed to C's \cfunction{exit()} function); if it is
+  \code{None}, the exit status is zero; if it has another type (such as
+  a string), the object's value is printed and the exit status is one.
+
+  Instances have an attribute \member{code} which is set to the
+  proposed exit status or error message (defaulting to \code{None}).
+  Also, this exception derives directly from \exception{BaseException} and
+  not \exception{StandardError}, since it is not technically an error.
+
+  A call to \function{sys.exit()} is translated into an exception so that
+  clean-up handlers (\keyword{finally} clauses of \keyword{try} statements)
+  can be executed, and so that a debugger can execute a script without
+  running the risk of losing control.  The \function{os._exit()} function
+  can be used if it is absolutely positively necessary to exit
+  immediately (for example, in the child process after a call to
+  \function{fork()}).
+
+  The exception inherits from \exception{BaseException} instead of
+  \exception{StandardError} or \exception{Exception} so that it is not
+  accidentally caught by code that catches \exception{Exception}.  This allows
+  the exception to properly propagate up and cause the interpreter to exit.
+  \versionchanged[Changed to inherit from \exception{BaseException}]{2.5}
+\end{excdesc}
+
+\begin{excdesc}{TypeError}
+  Raised when an operation or function is applied to an object
+  of inappropriate type.  The associated value is a string giving
+  details about the type mismatch.
+\end{excdesc}
+
+\begin{excdesc}{UnboundLocalError}
+  Raised when a reference is made to a local variable in a function or
+  method, but no value has been bound to that variable.  This is a
+  subclass of \exception{NameError}.
+\versionadded{2.0}
+\end{excdesc}
+
+\begin{excdesc}{UnicodeError}
+  Raised when a Unicode-related encoding or decoding error occurs.  It
+  is a subclass of \exception{ValueError}.
+\versionadded{2.0}
+\end{excdesc}
+
+\begin{excdesc}{UnicodeEncodeError}
+  Raised when a Unicode-related error occurs during encoding.  It
+  is a subclass of \exception{UnicodeError}.
+\versionadded{2.3}
+\end{excdesc}
+
+\begin{excdesc}{UnicodeDecodeError}
+  Raised when a Unicode-related error occurs during decoding.  It
+  is a subclass of \exception{UnicodeError}.
+\versionadded{2.3}
+\end{excdesc}
+
+\begin{excdesc}{UnicodeTranslateError}
+  Raised when a Unicode-related error occurs during translating.  It
+  is a subclass of \exception{UnicodeError}.
+\versionadded{2.3}
+\end{excdesc}
+
+\begin{excdesc}{ValueError}
+  Raised when a built-in operation or function receives an argument
+  that has the right type but an inappropriate value, and the
+  situation is not described by a more precise exception such as
+  \exception{IndexError}.
+\end{excdesc}
+
+\begin{excdesc}{WindowsError}
+  Raised when a Windows-specific error occurs or when the error number
+  does not correspond to an \cdata{errno} value.  The
+  \member{winerror} and \member{strerror} values are created from the
+  return values of the \cfunction{GetLastError()} and
+  \cfunction{FormatMessage()} functions from the Windows Platform API.
+  The \member{errno} value maps the \member{winerror} value to 
+  corresponding \code{errno.h} values.
+  This is a subclass of \exception{OSError}.
+\versionadded{2.0}
+\versionchanged[Previous versions put the \cfunction{GetLastError()}
+codes into \member{errno}]{2.5}
+\end{excdesc}
+
+\begin{excdesc}{ZeroDivisionError}
+  Raised when the second argument of a division or modulo operation is
+  zero.  The associated value is a string indicating the type of the
+  operands and the operation.
+\end{excdesc}
+
+
+\setindexsubitem{(built-in warning)}
+
+The following exceptions are used as warning categories; see the
+\refmodule{warnings} module for more information.
+
+\begin{excdesc}{Warning}
+Base class for warning categories.
+\end{excdesc}
+
+\begin{excdesc}{UserWarning}
+Base class for warnings generated by user code.
+\end{excdesc}
+
+\begin{excdesc}{DeprecationWarning}
+Base class for warnings about deprecated features.
+\end{excdesc}
+
+\begin{excdesc}{PendingDeprecationWarning}
+Base class for warnings about features which will be deprecated in the future.
+\end{excdesc}
+
+\begin{excdesc}{SyntaxWarning}
+Base class for warnings about dubious syntax
+\end{excdesc}
+
+\begin{excdesc}{RuntimeWarning}
+Base class for warnings about dubious runtime behavior.
+\end{excdesc}
+
+\begin{excdesc}{FutureWarning}
+Base class for warnings about constructs that will change semantically
+in the future.
+\end{excdesc}
+
+\begin{excdesc}{ImportWarning}
+Base class for warnings about probable mistakes in module imports.
+\versionadded{2.5}
+\end{excdesc}
+
+\begin{excdesc}{UnicodeWarning}
+Base class for warnings related to Unicode.
+\versionadded{2.5}
+\end{excdesc}
+
+The class hierarchy for built-in exceptions is:
+
+\verbatiminput{../../Lib/test/exception_hierarchy.txt}

Added: vendor/Python/current/Doc/lib/libfcntl.tex
===================================================================
--- vendor/Python/current/Doc/lib/libfcntl.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libfcntl.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,174 @@
+\section{\module{fcntl} ---
+         The \function{fcntl()} and \function{ioctl()} system calls}
+
+\declaremodule{builtin}{fcntl}
+  \platform{Unix}
+\modulesynopsis{The \function{fcntl()} and \function{ioctl()} system calls.}
+\sectionauthor{Jaap Vermeulen}{}
+
+\indexii{UNIX@\UNIX}{file control}
+\indexii{UNIX@\UNIX}{I/O control}
+
+This module performs file control and I/O control on file descriptors.
+It is an interface to the \cfunction{fcntl()} and \cfunction{ioctl()}
+\UNIX{} routines.
+
+All functions in this module take a file descriptor \var{fd} as their
+first argument.  This can be an integer file descriptor, such as
+returned by \code{sys.stdin.fileno()}, or a file object, such as
+\code{sys.stdin} itself, which provides a \method{fileno()} which
+returns a genuine file descriptor.
+
+The module defines the following functions:
+
+
+\begin{funcdesc}{fcntl}{fd, op\optional{, arg}}
+  Perform the requested operation on file descriptor \var{fd} (file
+  objects providing a \method{fileno()} method are accepted as well).
+  The operation is defined by \var{op} and is operating system
+  dependent.  These codes are also found in the \module{fcntl}
+  module. The argument \var{arg} is optional, and defaults to the
+  integer value \code{0}.  When present, it can either be an integer
+  value, or a string.  With the argument missing or an integer value,
+  the return value of this function is the integer return value of the
+  C \cfunction{fcntl()} call.  When the argument is a string it
+  represents a binary structure, e.g.\ created by
+  \function{\refmodule{struct}.pack()}. The binary data is copied to a buffer
+  whose address is passed to the C \cfunction{fcntl()} call.  The
+  return value after a successful call is the contents of the buffer,
+  converted to a string object.  The length of the returned string
+  will be the same as the length of the \var{arg} argument.  This is
+  limited to 1024 bytes.  If the information returned in the buffer by
+  the operating system is larger than 1024 bytes, this is most likely
+  to result in a segmentation violation or a more subtle data
+  corruption.
+
+  If the \cfunction{fcntl()} fails, an \exception{IOError} is
+  raised.
+\end{funcdesc}
+
+\begin{funcdesc}{ioctl}{fd, op\optional{, arg\optional{, mutate_flag}}}
+  This function is identical to the \function{fcntl()} function,
+  except that the operations are typically defined in the library
+  module \refmodule{termios} and the argument handling is even more
+  complicated.
+  
+  The parameter \var{arg} can be one of an integer, absent (treated
+  identically to the integer \code{0}), an object supporting the
+  read-only buffer interface (most likely a plain Python string) or an
+  object supporting the read-write buffer interface.
+  
+  In all but the last case, behaviour is as for the \function{fcntl()}
+  function.
+  
+  If a mutable buffer is passed, then the behaviour is determined by
+  the value of the \var{mutate_flag} parameter.
+  
+  If it is false, the buffer's mutability is ignored and behaviour is
+  as for a read-only buffer, except that the 1024 byte limit mentioned
+  above is avoided -- so long as the buffer you pass is as least as
+  long as what the operating system wants to put there, things should
+  work.
+  
+  If \var{mutate_flag} is true, then the buffer is (in effect) passed
+  to the underlying \function{ioctl()} system call, the latter's
+  return code is passed back to the calling Python, and the buffer's
+  new contents reflect the action of the \function{ioctl()}.  This is a
+  slight simplification, because if the supplied buffer is less than
+  1024 bytes long it is first copied into a static buffer 1024 bytes
+  long which is then passed to \function{ioctl()} and copied back into
+  the supplied buffer.
+  
+  If \var{mutate_flag} is not supplied, then from Python 2.5 it
+  defaults to true, which is a change from versions 2.3 and 2.4.
+  Supply the argument explicitly if version portability is a priority.
+
+  An example:
+
+\begin{verbatim}
+>>> import array, fcntl, struct, termios, os
+>>> os.getpgrp()
+13341
+>>> struct.unpack('h', fcntl.ioctl(0, termios.TIOCGPGRP, "  "))[0]
+13341
+>>> buf = array.array('h', [0])
+>>> fcntl.ioctl(0, termios.TIOCGPGRP, buf, 1)
+0
+>>> buf
+array('h', [13341])
+\end{verbatim}
+\end{funcdesc}
+
+\begin{funcdesc}{flock}{fd, op}
+Perform the lock operation \var{op} on file descriptor \var{fd} (file
+  objects providing a \method{fileno()} method are accepted as well).
+See the \UNIX{} manual \manpage{flock}{3} for details.  (On some
+systems, this function is emulated using \cfunction{fcntl()}.)
+\end{funcdesc}
+
+\begin{funcdesc}{lockf}{fd, operation,
+    \optional{length, \optional{start, \optional{whence}}}}
+This is essentially a wrapper around the \function{fcntl()} locking
+calls.  \var{fd} is the file descriptor of the file to lock or unlock,
+and \var{operation} is one of the following values:
+
+\begin{itemize}
+\item \constant{LOCK_UN} -- unlock
+\item \constant{LOCK_SH} -- acquire a shared lock
+\item \constant{LOCK_EX} -- acquire an exclusive lock
+\end{itemize}
+
+When \var{operation} is \constant{LOCK_SH} or \constant{LOCK_EX}, it
+can also be bit-wise OR'd with \constant{LOCK_NB} to avoid blocking on
+lock acquisition.  If \constant{LOCK_NB} is used and the lock cannot
+be acquired, an \exception{IOError} will be raised and the exception
+will have an \var{errno} attribute set to \constant{EACCES} or
+\constant{EAGAIN} (depending on the operating system; for portability,
+check for both values).  On at least some systems, \constant{LOCK_EX}
+can only be used if the file descriptor refers to a file opened for
+writing.
+
+\var{length} is the number of bytes to lock, \var{start} is the byte
+offset at which the lock starts, relative to \var{whence}, and
+\var{whence} is as with \function{fileobj.seek()}, specifically:
+
+\begin{itemize}
+\item \constant{0} -- relative to the start of the file
+      (\constant{SEEK_SET})
+\item \constant{1} -- relative to the current buffer position
+      (\constant{SEEK_CUR})
+\item \constant{2} -- relative to the end of the file
+      (\constant{SEEK_END})
+\end{itemize}
+
+The default for \var{start} is 0, which means to start at the
+beginning of the file.  The default for \var{length} is 0 which means
+to lock to the end of the file.  The default for \var{whence} is also
+0.
+\end{funcdesc}
+
+Examples (all on a SVR4 compliant system):
+
+\begin{verbatim}
+import struct, fcntl, os
+
+f = open(...)
+rv = fcntl.fcntl(f, fcntl.F_SETFL, os.O_NDELAY)
+
+lockdata = struct.pack('hhllhh', fcntl.F_WRLCK, 0, 0, 0, 0, 0)
+rv = fcntl.fcntl(f, fcntl.F_SETLKW, lockdata)
+\end{verbatim}
+
+Note that in the first example the return value variable \var{rv} will
+hold an integer value; in the second example it will hold a string
+value.  The structure lay-out for the \var{lockdata} variable is
+system dependent --- therefore using the \function{flock()} call may be
+better.
+
+\begin{seealso}
+  \seemodule{os}{If the locking flags \constant{O_SHLOCK} and
+		 \constant{O_EXLOCK} are present in the \module{os} module,
+  		 the \function{os.open()} function provides a more
+  		 platform-independent alternative to the \function{lockf()}
+  		 and \function{flock()} functions.}
+\end{seealso}

Added: vendor/Python/current/Doc/lib/libfilecmp.tex
===================================================================
--- vendor/Python/current/Doc/lib/libfilecmp.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libfilecmp.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,142 @@
+\section{\module{filecmp} ---
+         File and Directory Comparisons}
+
+\declaremodule{standard}{filecmp}
+\sectionauthor{Moshe Zadka}{moshez at zadka.site.co.il}
+\modulesynopsis{Compare files efficiently.}
+
+
+The \module{filecmp} module defines functions to compare files and
+directories, with various optional time/correctness trade-offs.
+
+The \module{filecmp} module defines the following functions:
+
+\begin{funcdesc}{cmp}{f1, f2\optional{, shallow}}
+Compare the files named \var{f1} and \var{f2}, returning \code{True} if
+they seem equal, \code{False} otherwise.
+
+Unless \var{shallow} is given and is false, files with identical
+\function{os.stat()} signatures are taken to be equal.
+
+Files that were compared using this function will not be compared again
+unless their \function{os.stat()} signature changes.
+
+Note that no external programs are called from this function, giving it
+portability and efficiency.
+\end{funcdesc}
+
+\begin{funcdesc}{cmpfiles}{dir1, dir2, common\optional{,
+                           shallow}}
+Returns three lists of file names: \var{match}, \var{mismatch},
+\var{errors}.  \var{match} contains the list of files match in both
+directories, \var{mismatch} includes the names of those that don't,
+and \var{errros} lists the names of files which could not be
+compared.  Files may be listed in \var{errors} because the user may
+lack permission to read them or many other reasons, but always that
+the comparison could not be done for some reason.
+
+The \var{common} parameter is a list of file names found in both directories.
+The \var{shallow} parameter has the same
+meaning and default value as for \function{filecmp.cmp()}.
+\end{funcdesc}
+
+Example:
+
+\begin{verbatim}
+>>> import filecmp
+>>> filecmp.cmp('libundoc.tex', 'libundoc.tex')
+True
+>>> filecmp.cmp('libundoc.tex', 'lib.tex')
+False
+\end{verbatim}
+
+
+\subsection{The \protect\class{dircmp} class \label{dircmp-objects}}
+
+\class{dircmp} instances are built using this constructor:
+
+\begin{classdesc}{dircmp}{a, b\optional{, ignore\optional{, hide}}}
+Construct a new directory comparison object, to compare the
+directories \var{a} and \var{b}. \var{ignore} is a list of names to
+ignore, and defaults to \code{['RCS', 'CVS', 'tags']}. \var{hide} is a
+list of names to hide, and defaults to \code{[os.curdir, os.pardir]}.
+\end{classdesc}
+
+The \class{dircmp} class provides the following methods:
+
+\begin{methoddesc}[dircmp]{report}{}
+Print (to \code{sys.stdout}) a comparison between \var{a} and \var{b}.
+\end{methoddesc}
+
+\begin{methoddesc}[dircmp]{report_partial_closure}{}
+Print a comparison between \var{a} and \var{b} and common immediate
+subdirectories.
+\end{methoddesc}
+
+\begin{methoddesc}[dircmp]{report_full_closure}{}
+Print a comparison between \var{a} and \var{b} and common 
+subdirectories (recursively).
+\end{methoddesc}
+
+
+The \class{dircmp} offers a number of interesting attributes that may
+be used to get various bits of information about the directory trees
+being compared.
+
+Note that via \method{__getattr__()} hooks, all attributes are
+computed lazily, so there is no speed penalty if only those
+attributes which are lightweight to compute are used.
+
+\begin{memberdesc}[dircmp]{left_list}
+Files and subdirectories in \var{a}, filtered by \var{hide} and
+\var{ignore}.
+\end{memberdesc}
+
+\begin{memberdesc}[dircmp]{right_list}
+Files and subdirectories in \var{b}, filtered by \var{hide} and
+\var{ignore}.
+\end{memberdesc}
+
+\begin{memberdesc}[dircmp]{common}
+Files and subdirectories in both \var{a} and \var{b}.
+\end{memberdesc}
+
+\begin{memberdesc}[dircmp]{left_only}
+Files and subdirectories only in \var{a}.
+\end{memberdesc}
+
+\begin{memberdesc}[dircmp]{right_only}
+Files and subdirectories only in \var{b}.
+\end{memberdesc}
+
+\begin{memberdesc}[dircmp]{common_dirs}
+Subdirectories in both \var{a} and \var{b}.
+\end{memberdesc}
+
+\begin{memberdesc}[dircmp]{common_files}
+Files in both \var{a} and \var{b}
+\end{memberdesc}
+
+\begin{memberdesc}[dircmp]{common_funny}
+Names in both \var{a} and \var{b}, such that the type differs between
+the directories, or names for which \function{os.stat()} reports an
+error.
+\end{memberdesc}
+
+\begin{memberdesc}[dircmp]{same_files}
+Files which are identical in both \var{a} and \var{b}.
+\end{memberdesc}
+
+\begin{memberdesc}[dircmp]{diff_files}
+Files which are in both \var{a} and \var{b}, whose contents differ.
+\end{memberdesc}
+
+\begin{memberdesc}[dircmp]{funny_files}
+Files which are in both \var{a} and \var{b}, but could not be
+compared.
+\end{memberdesc}
+
+\begin{memberdesc}[dircmp]{subdirs}
+A dictionary mapping names in \member{common_dirs} to
+\class{dircmp} objects.
+\end{memberdesc}

Added: vendor/Python/current/Doc/lib/libfileinput.tex
===================================================================
--- vendor/Python/current/Doc/lib/libfileinput.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libfileinput.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,192 @@
+\section{\module{fileinput} ---
+         Iterate over lines from multiple input streams}
+\declaremodule{standard}{fileinput}
+\moduleauthor{Guido van Rossum}{guido at python.org}
+\sectionauthor{Fred L. Drake, Jr.}{fdrake at acm.org}
+
+\modulesynopsis{Perl-like iteration over lines from multiple input
+streams, with ``save in place'' capability.}
+
+
+This module implements a helper class and functions to quickly write a
+loop over standard input or a list of files.
+
+The typical use is:
+
+\begin{verbatim}
+import fileinput
+for line in fileinput.input():
+    process(line)
+\end{verbatim}
+
+This iterates over the lines of all files listed in
+\code{sys.argv[1:]}, defaulting to \code{sys.stdin} if the list is
+empty.  If a filename is \code{'-'}, it is also replaced by
+\code{sys.stdin}.  To specify an alternative list of filenames, pass
+it as the first argument to \function{input()}.  A single file name is
+also allowed.
+
+All files are opened in text mode by default, but you can override this by
+specifying the \var{mode} parameter in the call to \function{input()}
+or \class{FileInput()}.  If an I/O error occurs during opening or reading
+a file, \exception{IOError} is raised.
+
+If \code{sys.stdin} is used more than once, the second and further use
+will return no lines, except perhaps for interactive use, or if it has
+been explicitly reset (e.g. using \code{sys.stdin.seek(0)}).
+
+Empty files are opened and immediately closed; the only time their
+presence in the list of filenames is noticeable at all is when the
+last file opened is empty.
+
+It is possible that the last line of a file does not end in a newline
+character; lines are returned including the trailing newline when it
+is present.
+
+You can control how files are opened by providing an opening hook via the
+\var{openhook} parameter to \function{input()} or \class{FileInput()}.
+The hook must be a function that takes two arguments, \var{filename}
+and \var{mode}, and returns an accordingly opened file-like object.
+Two useful hooks are already provided by this module.
+
+The following function is the primary interface of this module:
+
+\begin{funcdesc}{input}{\optional{files\optional{, inplace\optional{,
+                        backup\optional{, mode\optional{, openhook}}}}}}
+  Create an instance of the \class{FileInput} class.  The instance
+  will be used as global state for the functions of this module, and
+  is also returned to use during iteration.  The parameters to this
+  function will be passed along to the constructor of the
+  \class{FileInput} class.
+
+  \versionchanged[Added the \var{mode} and \var{openhook} parameters]{2.5}
+\end{funcdesc}
+
+
+The following functions use the global state created by
+\function{input()}; if there is no active state,
+\exception{RuntimeError} is raised.
+
+\begin{funcdesc}{filename}{}
+  Return the name of the file currently being read.  Before the first
+  line has been read, returns \code{None}.
+\end{funcdesc}
+
+\begin{funcdesc}{fileno}{}
+  Return the integer ``file descriptor'' for the current file. When no
+  file is opened (before the first line and between files), returns
+  \code{-1}.
+\versionadded{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{lineno}{}
+  Return the cumulative line number of the line that has just been
+  read.  Before the first line has been read, returns \code{0}.  After
+  the last line of the last file has been read, returns the line
+  number of that line.
+\end{funcdesc}
+
+\begin{funcdesc}{filelineno}{}
+  Return the line number in the current file.  Before the first line
+  has been read, returns \code{0}.  After the last line of the last
+  file has been read, returns the line number of that line within the
+  file.
+\end{funcdesc}
+
+\begin{funcdesc}{isfirstline}{}
+  Returns true if the line just read is the first line of its file,
+  otherwise returns false.
+\end{funcdesc}
+
+\begin{funcdesc}{isstdin}{}
+  Returns true if the last line was read from \code{sys.stdin},
+  otherwise returns false.
+\end{funcdesc}
+
+\begin{funcdesc}{nextfile}{}
+  Close the current file so that the next iteration will read the
+  first line from the next file (if any); lines not read from the file
+  will not count towards the cumulative line count.  The filename is
+  not changed until after the first line of the next file has been
+  read.  Before the first line has been read, this function has no
+  effect; it cannot be used to skip the first file.  After the last
+  line of the last file has been read, this function has no effect.
+\end{funcdesc}
+
+\begin{funcdesc}{close}{}
+  Close the sequence.
+\end{funcdesc}
+
+
+The class which implements the sequence behavior provided by the
+module is available for subclassing as well:
+
+\begin{classdesc}{FileInput}{\optional{files\optional{,
+                             inplace\optional{, backup\optional{,
+                             mode\optional{, openhook}}}}}}
+  Class \class{FileInput} is the implementation; its methods
+  \method{filename()}, \method{fileno()}, \method{lineno()},
+  \method{fileline()}, \method{isfirstline()}, \method{isstdin()},
+  \method{nextfile()} and \method{close()} correspond to the functions
+  of the same name in the module.
+  In addition it has a \method{readline()} method which
+  returns the next input line, and a \method{__getitem__()} method
+  which implements the sequence behavior.  The sequence must be
+  accessed in strictly sequential order; random access and
+  \method{readline()} cannot be mixed.
+
+  With \var{mode} you can specify which file mode will be passed to
+  \function{open()}. It must be one of \code{'r'}, \code{'rU'},
+  \code{'U'} and \code{'rb'}.
+
+  The \var{openhook}, when given, must be a function that takes two arguments,
+  \var{filename} and \var{mode}, and returns an accordingly opened
+  file-like object.
+  You cannot use \var{inplace} and \var{openhook} together.
+
+  \versionchanged[Added the \var{mode} and \var{openhook} parameters]{2.5}
+\end{classdesc}
+
+\strong{Optional in-place filtering:} if the keyword argument
+\code{\var{inplace}=1} is passed to \function{input()} or to the
+\class{FileInput} constructor, the file is moved to a backup file and
+standard output is directed to the input file (if a file of the same
+name as the backup file already exists, it will be replaced silently).
+This makes it possible to write a filter that rewrites its input file
+in place.  If the keyword argument \code{\var{backup}='.<some
+extension>'} is also given, it specifies the extension for the backup
+file, and the backup file remains around; by default, the extension is
+\code{'.bak'} and it is deleted when the output file is closed.  In-place
+filtering is disabled when standard input is read.
+
+\strong{Caveat:} The current implementation does not work for MS-DOS
+8+3 filesystems.
+
+
+The two following opening hooks are provided by this module:
+
+\begin{funcdesc}{hook_compressed}{filename, mode}
+  Transparently opens files compressed with gzip and bzip2 (recognized
+  by the extensions \code{'.gz'} and \code{'.bz2'}) using the \module{gzip}
+  and \module{bz2} modules.  If the filename extension is not \code{'.gz'}
+  or \code{'.bz2'}, the file is opened normally (ie,
+  using \function{open()} without any decompression).
+
+  Usage example: 
+  \samp{fi = fileinput.FileInput(openhook=fileinput.hook_compressed)}
+
+  \versionadded{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{hook_encoded}{encoding}
+  Returns a hook which opens each file with \function{codecs.open()},
+  using the given \var{encoding} to read the file.
+
+  Usage example:
+  \samp{fi = fileinput.FileInput(openhook=fileinput.hook_encoded("iso-8859-1"))}
+
+  \note{With this hook, \class{FileInput} might return Unicode strings
+        depending on the specified \var{encoding}.}
+  \versionadded{2.5}
+\end{funcdesc}
+

Added: vendor/Python/current/Doc/lib/libfl.tex
===================================================================
--- vendor/Python/current/Doc/lib/libfl.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libfl.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,507 @@
+\section{\module{fl} ---
+         FORMS library for graphical user interfaces}
+
+\declaremodule{builtin}{fl}
+  \platform{IRIX}
+\modulesynopsis{FORMS library for applications with graphical user
+                interfaces.}
+
+
+This module provides an interface to the FORMS Library\index{FORMS
+Library} by Mark Overmars\index{Overmars, Mark}.  The source for the
+library can be retrieved by anonymous ftp from host
+\samp{ftp.cs.ruu.nl}, directory \file{SGI/FORMS}.  It was last tested
+with version 2.0b.
+
+Most functions are literal translations of their C equivalents,
+dropping the initial \samp{fl_} from their name.  Constants used by
+the library are defined in module \refmodule[fl-constants]{FL}
+described below.
+
+The creation of objects is a little different in Python than in C:
+instead of the `current form' maintained by the library to which new
+FORMS objects are added, all functions that add a FORMS object to a
+form are methods of the Python object representing the form.
+Consequently, there are no Python equivalents for the C functions
+\cfunction{fl_addto_form()} and \cfunction{fl_end_form()}, and the
+equivalent of \cfunction{fl_bgn_form()} is called
+\function{fl.make_form()}.
+
+Watch out for the somewhat confusing terminology: FORMS uses the word
+\dfn{object} for the buttons, sliders etc. that you can place in a form.
+In Python, `object' means any value.  The Python interface to FORMS
+introduces two new Python object types: form objects (representing an
+entire form) and FORMS objects (representing one button, slider etc.).
+Hopefully this isn't too confusing.
+
+There are no `free objects' in the Python interface to FORMS, nor is
+there an easy way to add object classes written in Python.  The FORMS
+interface to GL event handling is available, though, so you can mix
+FORMS with pure GL windows.
+
+\strong{Please note:} importing \module{fl} implies a call to the GL
+function \cfunction{foreground()} and to the FORMS routine
+\cfunction{fl_init()}.
+
+\subsection{Functions Defined in Module \module{fl}}
+\nodename{FL Functions}
+
+Module \module{fl} defines the following functions.  For more
+information about what they do, see the description of the equivalent
+C function in the FORMS documentation:
+
+\begin{funcdesc}{make_form}{type, width, height}
+Create a form with given type, width and height.  This returns a
+\dfn{form} object, whose methods are described below.
+\end{funcdesc}
+
+\begin{funcdesc}{do_forms}{}
+The standard FORMS main loop.  Returns a Python object representing
+the FORMS object needing interaction, or the special value
+\constant{FL.EVENT}.
+\end{funcdesc}
+
+\begin{funcdesc}{check_forms}{}
+Check for FORMS events.  Returns what \function{do_forms()} above
+returns, or \code{None} if there is no event that immediately needs
+interaction.
+\end{funcdesc}
+
+\begin{funcdesc}{set_event_call_back}{function}
+Set the event callback function.
+\end{funcdesc}
+
+\begin{funcdesc}{set_graphics_mode}{rgbmode, doublebuffering}
+Set the graphics modes.
+\end{funcdesc}
+
+\begin{funcdesc}{get_rgbmode}{}
+Return the current rgb mode.  This is the value of the C global
+variable \cdata{fl_rgbmode}.
+\end{funcdesc}
+
+\begin{funcdesc}{show_message}{str1, str2, str3}
+Show a dialog box with a three-line message and an OK button.
+\end{funcdesc}
+
+\begin{funcdesc}{show_question}{str1, str2, str3}
+Show a dialog box with a three-line message and YES and NO buttons.
+It returns \code{1} if the user pressed YES, \code{0} if NO.
+\end{funcdesc}
+
+\begin{funcdesc}{show_choice}{str1, str2, str3, but1\optional{,
+                              but2\optional{, but3}}}
+Show a dialog box with a three-line message and up to three buttons.
+It returns the number of the button clicked by the user
+(\code{1}, \code{2} or \code{3}).
+\end{funcdesc}
+
+\begin{funcdesc}{show_input}{prompt, default}
+Show a dialog box with a one-line prompt message and text field in
+which the user can enter a string.  The second argument is the default
+input string.  It returns the string value as edited by the user.
+\end{funcdesc}
+
+\begin{funcdesc}{show_file_selector}{message, directory, pattern, default}
+Show a dialog box in which the user can select a file.  It returns
+the absolute filename selected by the user, or \code{None} if the user
+presses Cancel.
+\end{funcdesc}
+
+\begin{funcdesc}{get_directory}{}
+\funcline{get_pattern}{}
+\funcline{get_filename}{}
+These functions return the directory, pattern and filename (the tail
+part only) selected by the user in the last
+\function{show_file_selector()} call.
+\end{funcdesc}
+
+\begin{funcdesc}{qdevice}{dev}
+\funcline{unqdevice}{dev}
+\funcline{isqueued}{dev}
+\funcline{qtest}{}
+\funcline{qread}{}
+%\funcline{blkqread}{?}
+\funcline{qreset}{}
+\funcline{qenter}{dev, val}
+\funcline{get_mouse}{}
+\funcline{tie}{button, valuator1, valuator2}
+These functions are the FORMS interfaces to the corresponding GL
+functions.  Use these if you want to handle some GL events yourself
+when using \function{fl.do_events()}.  When a GL event is detected that
+FORMS cannot handle, \function{fl.do_forms()} returns the special value
+\constant{FL.EVENT} and you should call \function{fl.qread()} to read
+the event from the queue.  Don't use the equivalent GL functions!
+\end{funcdesc}
+
+\begin{funcdesc}{color}{}
+\funcline{mapcolor}{}
+\funcline{getmcolor}{}
+See the description in the FORMS documentation of
+\cfunction{fl_color()}, \cfunction{fl_mapcolor()} and
+\cfunction{fl_getmcolor()}.
+\end{funcdesc}
+
+\subsection{Form Objects}
+\label{form-objects}
+
+Form objects (returned by \function{make_form()} above) have the
+following methods.  Each method corresponds to a C function whose
+name is prefixed with \samp{fl_}; and whose first argument is a form
+pointer; please refer to the official FORMS documentation for
+descriptions.
+
+All the \method{add_*()} methods return a Python object representing
+the FORMS object.  Methods of FORMS objects are described below.  Most
+kinds of FORMS object also have some methods specific to that kind;
+these methods are listed here.
+
+\begin{flushleft}
+
+\begin{methoddesc}[form]{show_form}{placement, bordertype, name}
+  Show the form.
+\end{methoddesc}
+
+\begin{methoddesc}[form]{hide_form}{}
+  Hide the form.
+\end{methoddesc}
+
+\begin{methoddesc}[form]{redraw_form}{}
+  Redraw the form.
+\end{methoddesc}
+
+\begin{methoddesc}[form]{set_form_position}{x, y}
+Set the form's position.
+\end{methoddesc}
+
+\begin{methoddesc}[form]{freeze_form}{}
+Freeze the form.
+\end{methoddesc}
+
+\begin{methoddesc}[form]{unfreeze_form}{}
+  Unfreeze the form.
+\end{methoddesc}
+
+\begin{methoddesc}[form]{activate_form}{}
+  Activate the form.
+\end{methoddesc}
+
+\begin{methoddesc}[form]{deactivate_form}{}
+  Deactivate the form.
+\end{methoddesc}
+
+\begin{methoddesc}[form]{bgn_group}{}
+  Begin a new group of objects; return a group object.
+\end{methoddesc}
+
+\begin{methoddesc}[form]{end_group}{}
+  End the current group of objects.
+\end{methoddesc}
+
+\begin{methoddesc}[form]{find_first}{}
+  Find the first object in the form.
+\end{methoddesc}
+
+\begin{methoddesc}[form]{find_last}{}
+  Find the last object in the form.
+\end{methoddesc}
+
+%---
+
+\begin{methoddesc}[form]{add_box}{type, x, y, w, h, name}
+Add a box object to the form.
+No extra methods.
+\end{methoddesc}
+
+\begin{methoddesc}[form]{add_text}{type, x, y, w, h, name}
+Add a text object to the form.
+No extra methods.
+\end{methoddesc}
+
+%\begin{methoddesc}[form]{add_bitmap}{type, x, y, w, h, name}
+%Add a bitmap object to the form.
+%\end{methoddesc}
+
+\begin{methoddesc}[form]{add_clock}{type, x, y, w, h, name}
+Add a clock object to the form. \\
+Method:
+\method{get_clock()}.
+\end{methoddesc}
+
+%---
+
+\begin{methoddesc}[form]{add_button}{type, x, y, w, h,  name}
+Add a button object to the form. \\
+Methods:
+\method{get_button()},
+\method{set_button()}.
+\end{methoddesc}
+
+\begin{methoddesc}[form]{add_lightbutton}{type, x, y, w, h, name}
+Add a lightbutton object to the form. \\
+Methods:
+\method{get_button()},
+\method{set_button()}.
+\end{methoddesc}
+
+\begin{methoddesc}[form]{add_roundbutton}{type, x, y, w, h, name}
+Add a roundbutton object to the form. \\
+Methods:
+\method{get_button()},
+\method{set_button()}.
+\end{methoddesc}
+
+%---
+
+\begin{methoddesc}[form]{add_slider}{type, x, y, w, h, name}
+Add a slider object to the form. \\
+Methods:
+\method{set_slider_value()},
+\method{get_slider_value()},
+\method{set_slider_bounds()},
+\method{get_slider_bounds()},
+\method{set_slider_return()},
+\method{set_slider_size()},
+\method{set_slider_precision()},
+\method{set_slider_step()}.
+\end{methoddesc}
+
+\begin{methoddesc}[form]{add_valslider}{type, x, y, w, h, name}
+Add a valslider object to the form. \\
+Methods:
+\method{set_slider_value()},
+\method{get_slider_value()},
+\method{set_slider_bounds()},
+\method{get_slider_bounds()},
+\method{set_slider_return()},
+\method{set_slider_size()},
+\method{set_slider_precision()},
+\method{set_slider_step()}.
+\end{methoddesc}
+
+\begin{methoddesc}[form]{add_dial}{type, x, y, w, h, name}
+Add a dial object to the form. \\
+Methods:
+\method{set_dial_value()},
+\method{get_dial_value()},
+\method{set_dial_bounds()},
+\method{get_dial_bounds()}.
+\end{methoddesc}
+
+\begin{methoddesc}[form]{add_positioner}{type, x, y, w, h, name}
+Add a positioner object to the form. \\
+Methods:
+\method{set_positioner_xvalue()},
+\method{set_positioner_yvalue()},
+\method{set_positioner_xbounds()},
+\method{set_positioner_ybounds()},
+\method{get_positioner_xvalue()},
+\method{get_positioner_yvalue()},
+\method{get_positioner_xbounds()},
+\method{get_positioner_ybounds()}.
+\end{methoddesc}
+
+\begin{methoddesc}[form]{add_counter}{type, x, y, w, h, name}
+Add a counter object to the form. \\
+Methods:
+\method{set_counter_value()},
+\method{get_counter_value()},
+\method{set_counter_bounds()},
+\method{set_counter_step()},
+\method{set_counter_precision()},
+\method{set_counter_return()}.
+\end{methoddesc}
+
+%---
+
+\begin{methoddesc}[form]{add_input}{type, x, y, w, h, name}
+Add a input object to the form. \\
+Methods:
+\method{set_input()},
+\method{get_input()},
+\method{set_input_color()},
+\method{set_input_return()}.
+\end{methoddesc}
+
+%---
+
+\begin{methoddesc}[form]{add_menu}{type, x, y, w, h, name}
+Add a menu object to the form. \\
+Methods:
+\method{set_menu()},
+\method{get_menu()},
+\method{addto_menu()}.
+\end{methoddesc}
+
+\begin{methoddesc}[form]{add_choice}{type, x, y, w, h, name}
+Add a choice object to the form. \\
+Methods:
+\method{set_choice()},
+\method{get_choice()},
+\method{clear_choice()},
+\method{addto_choice()},
+\method{replace_choice()},
+\method{delete_choice()},
+\method{get_choice_text()},
+\method{set_choice_fontsize()},
+\method{set_choice_fontstyle()}.
+\end{methoddesc}
+
+\begin{methoddesc}[form]{add_browser}{type, x, y, w, h, name}
+Add a browser object to the form. \\
+Methods:
+\method{set_browser_topline()},
+\method{clear_browser()},
+\method{add_browser_line()},
+\method{addto_browser()},
+\method{insert_browser_line()},
+\method{delete_browser_line()},
+\method{replace_browser_line()},
+\method{get_browser_line()},
+\method{load_browser()},
+\method{get_browser_maxline()},
+\method{select_browser_line()},
+\method{deselect_browser_line()},
+\method{deselect_browser()},
+\method{isselected_browser_line()},
+\method{get_browser()},
+\method{set_browser_fontsize()},
+\method{set_browser_fontstyle()},
+\method{set_browser_specialkey()}.
+\end{methoddesc}
+
+%---
+
+\begin{methoddesc}[form]{add_timer}{type, x, y, w, h, name}
+Add a timer object to the form. \\
+Methods:
+\method{set_timer()},
+\method{get_timer()}.
+\end{methoddesc}
+\end{flushleft}
+
+Form objects have the following data attributes; see the FORMS
+documentation:
+
+\begin{tableiii}{l|l|l}{member}{Name}{C Type}{Meaning}
+  \lineiii{window}{int (read-only)}{GL window id}
+  \lineiii{w}{float}{form width}
+  \lineiii{h}{float}{form height}
+  \lineiii{x}{float}{form x origin}
+  \lineiii{y}{float}{form y origin}
+  \lineiii{deactivated}{int}{nonzero if form is deactivated}
+  \lineiii{visible}{int}{nonzero if form is visible}
+  \lineiii{frozen}{int}{nonzero if form is frozen}
+  \lineiii{doublebuf}{int}{nonzero if double buffering on}
+\end{tableiii}
+
+\subsection{FORMS Objects}
+\label{forms-objects}
+
+Besides methods specific to particular kinds of FORMS objects, all
+FORMS objects also have the following methods:
+
+\begin{methoddesc}[FORMS object]{set_call_back}{function, argument}
+Set the object's callback function and argument.  When the object
+needs interaction, the callback function will be called with two
+arguments: the object, and the callback argument.  (FORMS objects
+without a callback function are returned by \function{fl.do_forms()}
+or \function{fl.check_forms()} when they need interaction.)  Call this
+method without arguments to remove the callback function.
+\end{methoddesc}
+
+\begin{methoddesc}[FORMS object]{delete_object}{}
+  Delete the object.
+\end{methoddesc}
+
+\begin{methoddesc}[FORMS object]{show_object}{}
+  Show the object.
+\end{methoddesc}
+
+\begin{methoddesc}[FORMS object]{hide_object}{}
+  Hide the object.
+\end{methoddesc}
+
+\begin{methoddesc}[FORMS object]{redraw_object}{}
+  Redraw the object.
+\end{methoddesc}
+
+\begin{methoddesc}[FORMS object]{freeze_object}{}
+  Freeze the object.
+\end{methoddesc}
+
+\begin{methoddesc}[FORMS object]{unfreeze_object}{}
+  Unfreeze the object.
+\end{methoddesc}
+
+%\begin{methoddesc}[FORMS object]{handle_object}{} XXX
+%\end{methoddesc}
+
+%\begin{methoddesc}[FORMS object]{handle_object_direct}{} XXX
+%\end{methoddesc}
+
+FORMS objects have these data attributes; see the FORMS documentation:
+
+\begin{tableiii}{l|l|l}{member}{Name}{C Type}{Meaning}
+  \lineiii{objclass}{int (read-only)}{object class}
+  \lineiii{type}{int (read-only)}{object type}
+  \lineiii{boxtype}{int}{box type}
+  \lineiii{x}{float}{x origin}
+  \lineiii{y}{float}{y origin}
+  \lineiii{w}{float}{width}
+  \lineiii{h}{float}{height}
+  \lineiii{col1}{int}{primary color}
+  \lineiii{col2}{int}{secondary color}
+  \lineiii{align}{int}{alignment}
+  \lineiii{lcol}{int}{label color}
+  \lineiii{lsize}{float}{label font size}
+  \lineiii{label}{string}{label string}
+  \lineiii{lstyle}{int}{label style}
+  \lineiii{pushed}{int (read-only)}{(see FORMS docs)}
+  \lineiii{focus}{int (read-only)}{(see FORMS docs)}
+  \lineiii{belowmouse}{int (read-only)}{(see FORMS docs)}
+  \lineiii{frozen}{int (read-only)}{(see FORMS docs)}
+  \lineiii{active}{int (read-only)}{(see FORMS docs)}
+  \lineiii{input}{int (read-only)}{(see FORMS docs)}
+  \lineiii{visible}{int (read-only)}{(see FORMS docs)}
+  \lineiii{radio}{int (read-only)}{(see FORMS docs)}
+  \lineiii{automatic}{int (read-only)}{(see FORMS docs)}
+\end{tableiii}
+
+
+\section{\module{FL} ---
+         Constants used with the \module{fl} module}
+
+\declaremodule[fl-constants]{standard}{FL}
+  \platform{IRIX}
+\modulesynopsis{Constants used with the \module{fl} module.}
+
+
+This module defines symbolic constants needed to use the built-in
+module \refmodule{fl} (see above); they are equivalent to those defined in
+the C header file \code{<forms.h>} except that the name prefix
+\samp{FL_} is omitted.  Read the module source for a complete list of
+the defined names.  Suggested use:
+
+\begin{verbatim}
+import fl
+from FL import *
+\end{verbatim}
+
+
+\section{\module{flp} ---
+         Functions for loading stored FORMS designs}
+
+\declaremodule{standard}{flp}
+  \platform{IRIX}
+\modulesynopsis{Functions for loading stored FORMS designs.}
+
+
+This module defines functions that can read form definitions created
+by the `form designer' (\program{fdesign}) program that comes with the
+FORMS library (see module \refmodule{fl} above).
+
+For now, see the file \file{flp.doc} in the Python library source
+directory for a description.
+
+XXX A complete description should be inserted here!

Added: vendor/Python/current/Doc/lib/libfm.tex
===================================================================
--- vendor/Python/current/Doc/lib/libfm.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libfm.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,94 @@
+\section{\module{fm} ---
+         \emph{Font Manager} interface}
+
+\declaremodule{builtin}{fm}
+  \platform{IRIX}
+\modulesynopsis{\emph{Font Manager} interface for SGI workstations.}
+
+
+This module provides access to the IRIS \emph{Font Manager} library.
+\index{Font Manager, IRIS}
+\index{IRIS Font Manager}
+It is available only on Silicon Graphics machines.
+See also: \emph{4Sight User's Guide}, section 1, chapter 5: ``Using
+the IRIS Font Manager.''
+
+This is not yet a full interface to the IRIS Font Manager.
+Among the unsupported features are: matrix operations; cache
+operations; character operations (use string operations instead); some
+details of font info; individual glyph metrics; and printer matching.
+
+It supports the following operations:
+
+\begin{funcdesc}{init}{}
+Initialization function.
+Calls \cfunction{fminit()}.
+It is normally not necessary to call this function, since it is called
+automatically the first time the \module{fm} module is imported.
+\end{funcdesc}
+
+\begin{funcdesc}{findfont}{fontname}
+Return a font handle object.
+Calls \code{fmfindfont(\var{fontname})}.
+\end{funcdesc}
+
+\begin{funcdesc}{enumerate}{}
+Returns a list of available font names.
+This is an interface to \cfunction{fmenumerate()}.
+\end{funcdesc}
+
+\begin{funcdesc}{prstr}{string}
+Render a string using the current font (see the \function{setfont()} font
+handle method below).
+Calls \code{fmprstr(\var{string})}.
+\end{funcdesc}
+
+\begin{funcdesc}{setpath}{string}
+Sets the font search path.
+Calls \code{fmsetpath(\var{string})}.
+(XXX Does not work!?!)
+\end{funcdesc}
+
+\begin{funcdesc}{fontpath}{}
+Returns the current font search path.
+\end{funcdesc}
+
+Font handle objects support the following operations:
+
+\setindexsubitem{(font handle method)}
+\begin{funcdesc}{scalefont}{factor}
+Returns a handle for a scaled version of this font.
+Calls \code{fmscalefont(\var{fh}, \var{factor})}.
+\end{funcdesc}
+
+\begin{funcdesc}{setfont}{}
+Makes this font the current font.
+Note: the effect is undone silently when the font handle object is
+deleted.
+Calls \code{fmsetfont(\var{fh})}.
+\end{funcdesc}
+
+\begin{funcdesc}{getfontname}{}
+Returns this font's name.
+Calls \code{fmgetfontname(\var{fh})}.
+\end{funcdesc}
+
+\begin{funcdesc}{getcomment}{}
+Returns the comment string associated with this font.
+Raises an exception if there is none.
+Calls \code{fmgetcomment(\var{fh})}.
+\end{funcdesc}
+
+\begin{funcdesc}{getfontinfo}{}
+Returns a tuple giving some pertinent data about this font.
+This is an interface to \code{fmgetfontinfo()}.
+The returned tuple contains the following numbers:
+\code{(}\var{printermatched}, \var{fixed_width}, \var{xorig},
+\var{yorig}, \var{xsize}, \var{ysize}, \var{height},
+\var{nglyphs}\code{)}.
+\end{funcdesc}
+
+\begin{funcdesc}{getstrwidth}{string}
+Returns the width, in pixels, of \var{string} when drawn in this font.
+Calls \code{fmgetstrwidth(\var{fh}, \var{string})}.
+\end{funcdesc}

Added: vendor/Python/current/Doc/lib/libfnmatch.tex
===================================================================
--- vendor/Python/current/Doc/lib/libfnmatch.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libfnmatch.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,86 @@
+\section{\module{fnmatch} ---
+         \UNIX{} filename pattern matching}
+
+\declaremodule{standard}{fnmatch}
+\modulesynopsis{\UNIX\ shell style filename pattern matching.}
+
+
+\index{filenames!wildcard expansion}
+
+This module provides support for \UNIX{} shell-style wildcards, which
+are \emph{not} the same as regular expressions (which are documented
+in the \refmodule{re}\refstmodindex{re} module).  The special
+characters used in shell-style wildcards are:
+
+\begin{tableii}{c|l}{code}{Pattern}{Meaning}
+  \lineii{*}{matches everything}
+  \lineii{?}{matches any single character}
+  \lineii{[\var{seq}]}{matches any character in \var{seq}}
+  \lineii{[!\var{seq}]}{matches any character not in \var{seq}}
+\end{tableii}
+
+Note that the filename separator (\code{'/'} on \UNIX) is \emph{not}
+special to this module.  See module
+\refmodule{glob}\refstmodindex{glob} for pathname expansion
+(\refmodule{glob} uses \function{fnmatch()} to match pathname
+segments).  Similarly, filenames starting with a period are
+not special for this module, and are matched by the \code{*} and
+\code{?} patterns.
+
+
+\begin{funcdesc}{fnmatch}{filename, pattern}
+Test whether the \var{filename} string matches the \var{pattern}
+string, returning true or false.  If the operating system is
+case-insensitive, then both parameters will be normalized to all
+lower- or upper-case before the comparison is performed.  If you
+require a case-sensitive comparison regardless of whether that's
+standard for your operating system, use \function{fnmatchcase()}
+instead.
+
+This example will print all file names in the current directory with the
+extension \code{.txt}:
+
+\begin{verbatim}
+import fnmatch
+import os
+
+for file in os.listdir('.'):
+    if fnmatch.fnmatch(file, '*.txt'):
+        print file
+\end{verbatim}
+
+\end{funcdesc}
+
+\begin{funcdesc}{fnmatchcase}{filename, pattern}
+Test whether \var{filename} matches \var{pattern}, returning true or
+false; the comparison is case-sensitive.
+\end{funcdesc}
+
+\begin{funcdesc}{filter}{names, pattern}
+Return the subset of the list of \var{names} that match \var{pattern}.
+It is the same as \code{[n for n in names if fnmatch(n, pattern)]}, but
+implemented more efficiently.
+\versionadded{2.2}
+\end{funcdesc}
+
+\begin{funcdesc}{translate}{pattern}
+Return the shell-style \var{pattern} converted to a regular
+expression.
+
+Example:
+
+\begin{verbatim}
+>>> import fnmatch, re
+>>>
+>>> regex = fnmatch.translate('*.txt')
+>>> regex
+'.*\\.txt$'
+>>> reobj = re.compile(regex)
+>>> print reobj.match('foobar.txt')
+<_sre.SRE_Match object at 0x...>
+\end{verbatim}
+\end{funcdesc}
+
+\begin{seealso}
+  \seemodule{glob}{\UNIX{} shell-style path expansion.}
+\end{seealso}

Added: vendor/Python/current/Doc/lib/libformatter.tex
===================================================================
--- vendor/Python/current/Doc/lib/libformatter.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libformatter.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,329 @@
+\section{\module{formatter} ---
+         Generic output formatting}
+
+\declaremodule{standard}{formatter}
+\modulesynopsis{Generic output formatter and device interface.}
+
+
+
+This module supports two interface definitions, each with multiple
+implementations.  The \emph{formatter} interface is used by the
+\class{HTMLParser} class of the \refmodule{htmllib} module, and the
+\emph{writer} interface is required by the formatter interface.
+\withsubitem{(class in htmllib)}{\ttindex{HTMLParser}}
+
+Formatter objects transform an abstract flow of formatting events into
+specific output events on writer objects.  Formatters manage several
+stack structures to allow various properties of a writer object to be
+changed and restored; writers need not be able to handle relative
+changes nor any sort of ``change back'' operation.  Specific writer
+properties which may be controlled via formatter objects are
+horizontal alignment, font, and left margin indentations.  A mechanism
+is provided which supports providing arbitrary, non-exclusive style
+settings to a writer as well.  Additional interfaces facilitate
+formatting events which are not reversible, such as paragraph
+separation.
+
+Writer objects encapsulate device interfaces.  Abstract devices, such
+as file formats, are supported as well as physical devices.  The
+provided implementations all work with abstract devices.  The
+interface makes available mechanisms for setting the properties which
+formatter objects manage and inserting data into the output.
+
+
+\subsection{The Formatter Interface \label{formatter-interface}}
+
+Interfaces to create formatters are dependent on the specific
+formatter class being instantiated.  The interfaces described below
+are the required interfaces which all formatters must support once
+initialized.
+
+One data element is defined at the module level:
+
+
+\begin{datadesc}{AS_IS}
+Value which can be used in the font specification passed to the
+\code{push_font()} method described below, or as the new value to any
+other \code{push_\var{property}()} method.  Pushing the \code{AS_IS}
+value allows the corresponding \code{pop_\var{property}()} method to
+be called without having to track whether the property was changed.
+\end{datadesc}
+
+The following attributes are defined for formatter instance objects:
+
+
+\begin{memberdesc}[formatter]{writer}
+The writer instance with which the formatter interacts.
+\end{memberdesc}
+
+
+\begin{methoddesc}[formatter]{end_paragraph}{blanklines}
+Close any open paragraphs and insert at least \var{blanklines}
+before the next paragraph.
+\end{methoddesc}
+
+\begin{methoddesc}[formatter]{add_line_break}{}
+Add a hard line break if one does not already exist.  This does not
+break the logical paragraph.
+\end{methoddesc}
+
+\begin{methoddesc}[formatter]{add_hor_rule}{*args, **kw}
+Insert a horizontal rule in the output.  A hard break is inserted if
+there is data in the current paragraph, but the logical paragraph is
+not broken.  The arguments and keywords are passed on to the writer's
+\method{send_line_break()} method.
+\end{methoddesc}
+
+\begin{methoddesc}[formatter]{add_flowing_data}{data}
+Provide data which should be formatted with collapsed whitespace.
+Whitespace from preceding and successive calls to
+\method{add_flowing_data()} is considered as well when the whitespace
+collapse is performed.  The data which is passed to this method is
+expected to be word-wrapped by the output device.  Note that any
+word-wrapping still must be performed by the writer object due to the
+need to rely on device and font information.
+\end{methoddesc}
+
+\begin{methoddesc}[formatter]{add_literal_data}{data}
+Provide data which should be passed to the writer unchanged.
+Whitespace, including newline and tab characters, are considered legal
+in the value of \var{data}.  
+\end{methoddesc}
+
+\begin{methoddesc}[formatter]{add_label_data}{format, counter}
+Insert a label which should be placed to the left of the current left
+margin.  This should be used for constructing bulleted or numbered
+lists.  If the \var{format} value is a string, it is interpreted as a
+format specification for \var{counter}, which should be an integer.
+The result of this formatting becomes the value of the label; if
+\var{format} is not a string it is used as the label value directly.
+The label value is passed as the only argument to the writer's
+\method{send_label_data()} method.  Interpretation of non-string label
+values is dependent on the associated writer.
+
+Format specifications are strings which, in combination with a counter
+value, are used to compute label values.  Each character in the format
+string is copied to the label value, with some characters recognized
+to indicate a transform on the counter value.  Specifically, the
+character \character{1} represents the counter value formatter as an
+Arabic number, the characters \character{A} and \character{a}
+represent alphabetic representations of the counter value in upper and
+lower case, respectively, and \character{I} and \character{i}
+represent the counter value in Roman numerals, in upper and lower
+case.  Note that the alphabetic and roman transforms require that the
+counter value be greater than zero.
+\end{methoddesc}
+
+\begin{methoddesc}[formatter]{flush_softspace}{}
+Send any pending whitespace buffered from a previous call to
+\method{add_flowing_data()} to the associated writer object.  This
+should be called before any direct manipulation of the writer object.
+\end{methoddesc}
+
+\begin{methoddesc}[formatter]{push_alignment}{align}
+Push a new alignment setting onto the alignment stack.  This may be
+\constant{AS_IS} if no change is desired.  If the alignment value is
+changed from the previous setting, the writer's \method{new_alignment()}
+method is called with the \var{align} value.
+\end{methoddesc}
+
+\begin{methoddesc}[formatter]{pop_alignment}{}
+Restore the previous alignment.
+\end{methoddesc}
+
+\begin{methoddesc}[formatter]{push_font}{\code{(}size, italic, bold, teletype\code{)}}
+Change some or all font properties of the writer object.  Properties
+which are not set to \constant{AS_IS} are set to the values passed in
+while others are maintained at their current settings.  The writer's
+\method{new_font()} method is called with the fully resolved font
+specification.
+\end{methoddesc}
+
+\begin{methoddesc}[formatter]{pop_font}{}
+Restore the previous font.
+\end{methoddesc}
+
+\begin{methoddesc}[formatter]{push_margin}{margin}
+Increase the number of left margin indentations by one, associating
+the logical tag \var{margin} with the new indentation.  The initial
+margin level is \code{0}.  Changed values of the logical tag must be
+true values; false values other than \constant{AS_IS} are not
+sufficient to change the margin.
+\end{methoddesc}
+
+\begin{methoddesc}[formatter]{pop_margin}{}
+Restore the previous margin.
+\end{methoddesc}
+
+\begin{methoddesc}[formatter]{push_style}{*styles}
+Push any number of arbitrary style specifications.  All styles are
+pushed onto the styles stack in order.  A tuple representing the
+entire stack, including \constant{AS_IS} values, is passed to the
+writer's \method{new_styles()} method.
+\end{methoddesc}
+
+\begin{methoddesc}[formatter]{pop_style}{\optional{n\code{ = 1}}}
+Pop the last \var{n} style specifications passed to
+\method{push_style()}.  A tuple representing the revised stack,
+including \constant{AS_IS} values, is passed to the writer's
+\method{new_styles()} method.
+\end{methoddesc}
+
+\begin{methoddesc}[formatter]{set_spacing}{spacing}
+Set the spacing style for the writer.
+\end{methoddesc}
+
+\begin{methoddesc}[formatter]{assert_line_data}{\optional{flag\code{ = 1}}}
+Inform the formatter that data has been added to the current paragraph
+out-of-band.  This should be used when the writer has been manipulated
+directly.  The optional \var{flag} argument can be set to false if
+the writer manipulations produced a hard line break at the end of the
+output.
+\end{methoddesc}
+
+
+\subsection{Formatter Implementations \label{formatter-impls}}
+
+Two implementations of formatter objects are provided by this module.
+Most applications may use one of these classes without modification or
+subclassing.
+
+\begin{classdesc}{NullFormatter}{\optional{writer}}
+A formatter which does nothing.  If \var{writer} is omitted, a
+\class{NullWriter} instance is created.  No methods of the writer are
+called by \class{NullFormatter} instances.  Implementations should
+inherit from this class if implementing a writer interface but don't
+need to inherit any implementation.
+\end{classdesc}
+
+\begin{classdesc}{AbstractFormatter}{writer}
+The standard formatter.  This implementation has demonstrated wide
+applicability to many writers, and may be used directly in most
+circumstances.  It has been used to implement a full-featured
+World Wide Web browser.
+\end{classdesc}
+
+
+
+\subsection{The Writer Interface \label{writer-interface}}
+
+Interfaces to create writers are dependent on the specific writer
+class being instantiated.  The interfaces described below are the
+required interfaces which all writers must support once initialized.
+Note that while most applications can use the
+\class{AbstractFormatter} class as a formatter, the writer must
+typically be provided by the application.
+
+
+\begin{methoddesc}[writer]{flush}{}
+Flush any buffered output or device control events.
+\end{methoddesc}
+
+\begin{methoddesc}[writer]{new_alignment}{align}
+Set the alignment style.  The \var{align} value can be any object,
+but by convention is a string or \code{None}, where \code{None}
+indicates that the writer's ``preferred'' alignment should be used.
+Conventional \var{align} values are \code{'left'}, \code{'center'},
+\code{'right'}, and \code{'justify'}.
+\end{methoddesc}
+
+\begin{methoddesc}[writer]{new_font}{font}
+Set the font style.  The value of \var{font} will be \code{None},
+indicating that the device's default font should be used, or a tuple
+of the form \code{(}\var{size}, \var{italic}, \var{bold},
+\var{teletype}\code{)}.  Size will be a string indicating the size of
+font that should be used; specific strings and their interpretation
+must be defined by the application.  The \var{italic}, \var{bold}, and
+\var{teletype} values are Boolean values specifying which of those
+font attributes should be used.
+\end{methoddesc}
+
+\begin{methoddesc}[writer]{new_margin}{margin, level}
+Set the margin level to the integer \var{level} and the logical tag
+to \var{margin}.  Interpretation of the logical tag is at the
+writer's discretion; the only restriction on the value of the logical
+tag is that it not be a false value for non-zero values of
+\var{level}.
+\end{methoddesc}
+
+\begin{methoddesc}[writer]{new_spacing}{spacing}
+Set the spacing style to \var{spacing}.
+\end{methoddesc}
+
+\begin{methoddesc}[writer]{new_styles}{styles}
+Set additional styles.  The \var{styles} value is a tuple of
+arbitrary values; the value \constant{AS_IS} should be ignored.  The
+\var{styles} tuple may be interpreted either as a set or as a stack
+depending on the requirements of the application and writer
+implementation.
+\end{methoddesc}
+
+\begin{methoddesc}[writer]{send_line_break}{}
+Break the current line.
+\end{methoddesc}
+
+\begin{methoddesc}[writer]{send_paragraph}{blankline}
+Produce a paragraph separation of at least \var{blankline} blank
+lines, or the equivalent.  The \var{blankline} value will be an
+integer.  Note that the implementation will receive a call to
+\method{send_line_break()} before this call if a line break is needed; 
+this method should not include ending the last line of the paragraph.
+It is only responsible for vertical spacing between paragraphs.
+\end{methoddesc}
+
+\begin{methoddesc}[writer]{send_hor_rule}{*args, **kw}
+Display a horizontal rule on the output device.  The arguments to this
+method are entirely application- and writer-specific, and should be
+interpreted with care.  The method implementation may assume that a
+line break has already been issued via \method{send_line_break()}.
+\end{methoddesc}
+
+\begin{methoddesc}[writer]{send_flowing_data}{data}
+Output character data which may be word-wrapped and re-flowed as
+needed.  Within any sequence of calls to this method, the writer may
+assume that spans of multiple whitespace characters have been
+collapsed to single space characters.
+\end{methoddesc}
+
+\begin{methoddesc}[writer]{send_literal_data}{data}
+Output character data which has already been formatted
+for display.  Generally, this should be interpreted to mean that line
+breaks indicated by newline characters should be preserved and no new
+line breaks should be introduced.  The data may contain embedded
+newline and tab characters, unlike data provided to the
+\method{send_formatted_data()} interface.
+\end{methoddesc}
+
+\begin{methoddesc}[writer]{send_label_data}{data}
+Set \var{data} to the left of the current left margin, if possible.
+The value of \var{data} is not restricted; treatment of non-string
+values is entirely application- and writer-dependent.  This method
+will only be called at the beginning of a line.
+\end{methoddesc}
+
+
+\subsection{Writer Implementations \label{writer-impls}}
+
+Three implementations of the writer object interface are provided as
+examples by this module.  Most applications will need to derive new
+writer classes from the \class{NullWriter} class.
+
+\begin{classdesc}{NullWriter}{}
+A writer which only provides the interface definition; no actions are
+taken on any methods.  This should be the base class for all writers
+which do not need to inherit any implementation methods.
+\end{classdesc}
+
+\begin{classdesc}{AbstractWriter}{}
+A writer which can be used in debugging formatters, but not much
+else.  Each method simply announces itself by printing its name and
+arguments on standard output.
+\end{classdesc}
+
+\begin{classdesc}{DumbWriter}{\optional{file\optional{, maxcol\code{ = 72}}}}
+Simple writer class which writes output on the file object passed in
+as \var{file} or, if \var{file} is omitted, on standard output.  The
+output is simply word-wrapped to the number of columns specified by
+\var{maxcol}.  This class is suitable for reflowing a sequence of
+paragraphs.
+\end{classdesc}

Added: vendor/Python/current/Doc/lib/libfpectl.tex
===================================================================
--- vendor/Python/current/Doc/lib/libfpectl.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libfpectl.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,127 @@
+\section{\module{fpectl} ---
+         Floating point exception control}
+
+\declaremodule{extension}{fpectl}
+  \platform{Unix}
+\moduleauthor{Lee Busby}{busby1 at llnl.gov}
+\sectionauthor{Lee Busby}{busby1 at llnl.gov}
+\modulesynopsis{Provide control for floating point exception handling.}
+
+\note{The \module{fpectl} module is not built by default, and its usage
+      is discouraged and may be dangerous except in the hands of
+      experts.  See also the section \ref{fpectl-limitations} on
+      limitations for more details.}
+
+Most computers carry out floating point operations\index{IEEE-754}
+in conformance with the so-called IEEE-754 standard.
+On any real computer,
+some floating point operations produce results that cannot
+be expressed as a normal floating point value.
+For example, try
+
+\begin{verbatim}
+>>> import math
+>>> math.exp(1000)
+inf
+>>> math.exp(1000) / math.exp(1000)
+nan
+\end{verbatim}
+
+(The example above will work on many platforms.
+DEC Alpha may be one exception.)
+"Inf" is a special, non-numeric value in IEEE-754 that
+stands for "infinity", and "nan" means "not a number."
+Note that,
+other than the non-numeric results,
+nothing special happened when you asked Python
+to carry out those calculations.
+That is in fact the default behaviour prescribed in the IEEE-754 standard,
+and if it works for you,
+stop reading now.
+
+In some circumstances,
+it would be better to raise an exception and stop processing
+at the point where the faulty operation was attempted.
+The \module{fpectl} module
+is for use in that situation.
+It provides control over floating point
+units from several hardware manufacturers,
+allowing the user to turn on the generation
+of \constant{SIGFPE} whenever any of the
+IEEE-754 exceptions Division by Zero, Overflow, or
+Invalid Operation occurs.
+In tandem with a pair of wrapper macros that are inserted
+into the C code comprising your python system,
+\constant{SIGFPE} is trapped and converted into the Python
+\exception{FloatingPointError} exception.
+
+The \module{fpectl} module defines the following functions and
+may raise the given exception:
+
+\begin{funcdesc}{turnon_sigfpe}{}
+Turn on the generation of \constant{SIGFPE},
+and set up an appropriate signal handler.
+\end{funcdesc}
+
+\begin{funcdesc}{turnoff_sigfpe}{}
+Reset default handling of floating point exceptions.
+\end{funcdesc}
+
+\begin{excdesc}{FloatingPointError}
+After \function{turnon_sigfpe()} has been executed,
+a floating point operation that raises one of the
+IEEE-754 exceptions
+Division by Zero, Overflow, or Invalid operation
+will in turn raise this standard Python exception.
+\end{excdesc}
+
+
+\subsection{Example \label{fpectl-example}}
+
+The following example demonstrates how to start up and test operation of
+the \module{fpectl} module.
+
+\begin{verbatim}
+>>> import fpectl
+>>> import fpetest
+>>> fpectl.turnon_sigfpe()
+>>> fpetest.test()
+overflow        PASS
+FloatingPointError: Overflow
+
+div by 0        PASS
+FloatingPointError: Division by zero
+  [ more output from test elided ]
+>>> import math
+>>> math.exp(1000)
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+FloatingPointError: in math_1
+\end{verbatim}
+
+
+\subsection{Limitations and other considerations \label{fpectl-limitations}}
+
+Setting up a given processor to trap IEEE-754 floating point
+errors currently requires custom code on a per-architecture basis.
+You may have to modify \module{fpectl} to control your particular hardware.
+
+Conversion of an IEEE-754 exception to a Python exception requires
+that the wrapper macros \code{PyFPE_START_PROTECT} and
+\code{PyFPE_END_PROTECT} be inserted into your code in an appropriate
+fashion.  Python itself has been modified to support the
+\module{fpectl} module, but many other codes of interest to numerical
+analysts have not.
+
+The \module{fpectl} module is not thread-safe.
+
+\begin{seealso}
+  \seetext{Some files in the source distribution may be interesting in
+           learning more about how this module operates.
+           The include file \file{Include/pyfpe.h} discusses the
+           implementation of this module at some length.
+           \file{Modules/fpetestmodule.c} gives several examples of
+           use.
+           Many additional examples can be found in
+           \file{Objects/floatobject.c}.}
+\end{seealso}

Added: vendor/Python/current/Doc/lib/libfpformat.tex
===================================================================
--- vendor/Python/current/Doc/lib/libfpformat.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libfpformat.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,54 @@
+\section{\module{fpformat} ---
+         Floating point conversions}
+
+\declaremodule{standard}{fpformat}
+\sectionauthor{Moshe Zadka}{moshez at zadka.site.co.il}
+\modulesynopsis{General floating point formatting functions.}
+
+
+The \module{fpformat} module defines functions for dealing with
+floating point numbers representations in 100\% pure
+Python. \note{This module is unneeded: everything here could
+be done via the \code{\%} string interpolation operator.}
+
+The \module{fpformat} module defines the following functions and an
+exception:
+
+
+\begin{funcdesc}{fix}{x, digs}
+Format \var{x} as \code{[-]ddd.ddd} with \var{digs} digits after the
+point and at least one digit before.
+If \code{\var{digs} <= 0}, the decimal point is suppressed.
+
+\var{x} can be either a number or a string that looks like
+one. \var{digs} is an integer.
+
+Return value is a string.
+\end{funcdesc}
+
+\begin{funcdesc}{sci}{x, digs}
+Format \var{x} as \code{[-]d.dddE[+-]ddd} with \var{digs} digits after the 
+point and exactly one digit before.
+If \code{\var{digs} <= 0}, one digit is kept and the point is suppressed.
+
+\var{x} can be either a real number, or a string that looks like
+one. \var{digs} is an integer.
+
+Return value is a string.
+\end{funcdesc}
+
+\begin{excdesc}{NotANumber}
+Exception raised when a string passed to \function{fix()} or
+\function{sci()} as the \var{x} parameter does not look like a number.
+This is a subclass of \exception{ValueError} when the standard
+exceptions are strings.  The exception value is the improperly
+formatted string that caused the exception to be raised.
+\end{excdesc}
+
+Example:
+
+\begin{verbatim}
+>>> import fpformat
+>>> fpformat.fix(1.23, 1)
+'1.2'
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/libftplib.tex
===================================================================
--- vendor/Python/current/Doc/lib/libftplib.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libftplib.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,288 @@
+\section{\module{ftplib} ---
+         FTP protocol client}
+
+\declaremodule{standard}{ftplib}
+\modulesynopsis{FTP protocol client (requires sockets).}
+
+\indexii{FTP}{protocol}
+\index{FTP!\module{ftplib} (standard module)}
+
+This module defines the class \class{FTP} and a few related items.
+The \class{FTP} class implements the client side of the FTP
+protocol.  You can use this to write Python
+programs that perform a variety of automated FTP jobs, such as
+mirroring other ftp servers.  It is also used by the module
+\refmodule{urllib} to handle URLs that use FTP.  For more information
+on FTP (File Transfer Protocol), see Internet \rfc{959}.
+
+Here's a sample session using the \module{ftplib} module:
+
+\begin{verbatim}
+>>> from ftplib import FTP
+>>> ftp = FTP('ftp.cwi.nl')   # connect to host, default port
+>>> ftp.login()               # user anonymous, passwd anonymous@
+>>> ftp.retrlines('LIST')     # list directory contents
+total 24418
+drwxrwsr-x   5 ftp-usr  pdmaint     1536 Mar 20 09:48 .
+dr-xr-srwt 105 ftp-usr  pdmaint     1536 Mar 21 14:32 ..
+-rw-r--r--   1 ftp-usr  pdmaint     5305 Mar 20 09:48 INDEX
+ .
+ .
+ .
+>>> ftp.retrbinary('RETR README', open('README', 'wb').write)
+'226 Transfer complete.'
+>>> ftp.quit()
+\end{verbatim}
+
+The module defines the following items:
+
+\begin{classdesc}{FTP}{\optional{host\optional{, user\optional{,
+                       passwd\optional{, acct}}}}}
+Return a new instance of the \class{FTP} class.  When
+\var{host} is given, the method call \code{connect(\var{host})} is
+made.  When \var{user} is given, additionally the method call
+\code{login(\var{user}, \var{passwd}, \var{acct})} is made (where
+\var{passwd} and \var{acct} default to the empty string when not given).
+\end{classdesc}
+
+\begin{datadesc}{all_errors}
+The set of all exceptions (as a tuple) that methods of \class{FTP}
+instances may raise as a result of problems with the FTP connection
+(as opposed to programming errors made by the caller).  This set
+includes the four exceptions listed below as well as
+\exception{socket.error} and \exception{IOError}.
+\end{datadesc}
+
+\begin{excdesc}{error_reply}
+Exception raised when an unexpected reply is received from the server.
+\end{excdesc}
+
+\begin{excdesc}{error_temp}
+Exception raised when an error code in the range 400--499 is received.
+\end{excdesc}
+
+\begin{excdesc}{error_perm}
+Exception raised when an error code in the range 500--599 is received.
+\end{excdesc}
+
+\begin{excdesc}{error_proto}
+Exception raised when a reply is received from the server that does
+not begin with a digit in the range 1--5.
+\end{excdesc}
+
+
+\begin{seealso}
+  \seemodule{netrc}{Parser for the \file{.netrc} file format.  The file
+                    \file{.netrc} is typically used by FTP clients to
+                    load user authentication information before prompting
+                    the user.}
+  \seetext{The file \file{Tools/scripts/ftpmirror.py}\index{ftpmirror.py}
+           in the Python source distribution is a script that can mirror
+           FTP sites, or portions thereof, using the \module{ftplib} module.
+           It can be used as an extended example that applies this module.}
+\end{seealso}
+
+
+\subsection{FTP Objects \label{ftp-objects}}
+
+Several methods are available in two flavors: one for handling text
+files and another for binary files.  These are named for the command
+which is used followed by \samp{lines} for the text version or
+\samp{binary} for the binary version.
+
+\class{FTP} instances have the following methods:
+
+\begin{methoddesc}{set_debuglevel}{level}
+Set the instance's debugging level.  This controls the amount of
+debugging output printed.  The default, \code{0}, produces no
+debugging output.  A value of \code{1} produces a moderate amount of
+debugging output, generally a single line per request.  A value of
+\code{2} or higher produces the maximum amount of debugging output,
+logging each line sent and received on the control connection.
+\end{methoddesc}
+
+\begin{methoddesc}{connect}{host\optional{, port}}
+Connect to the given host and port.  The default port number is \code{21}, as
+specified by the FTP protocol specification.  It is rarely needed to
+specify a different port number.  This function should be called only
+once for each instance; it should not be called at all if a host was
+given when the instance was created.  All other methods can only be
+used after a connection has been made.
+\end{methoddesc}
+
+\begin{methoddesc}{getwelcome}{}
+Return the welcome message sent by the server in reply to the initial
+connection.  (This message sometimes contains disclaimers or help
+information that may be relevant to the user.)
+\end{methoddesc}
+
+\begin{methoddesc}{login}{\optional{user\optional{, passwd\optional{, acct}}}}
+Log in as the given \var{user}.  The \var{passwd} and \var{acct}
+parameters are optional and default to the empty string.  If no
+\var{user} is specified, it defaults to \code{'anonymous'}.  If
+\var{user} is \code{'anonymous'}, the default \var{passwd} is
+\code{'anonymous@'}.  This function should be called only
+once for each instance, after a connection has been established; it
+should not be called at all if a host and user were given when the
+instance was created.  Most FTP commands are only allowed after the
+client has logged in.
+\end{methoddesc}
+
+\begin{methoddesc}{abort}{}
+Abort a file transfer that is in progress.  Using this does not always
+work, but it's worth a try.
+\end{methoddesc}
+
+\begin{methoddesc}{sendcmd}{command}
+Send a simple command string to the server and return the response
+string.
+\end{methoddesc}
+
+\begin{methoddesc}{voidcmd}{command}
+Send a simple command string to the server and handle the response.
+Return nothing if a response code in the range 200--299 is received.
+Raise an exception otherwise.
+\end{methoddesc}
+
+\begin{methoddesc}{retrbinary}{command,
+    callback\optional{, maxblocksize\optional{, rest}}}
+Retrieve a file in binary transfer mode.  \var{command} should be an
+appropriate \samp{RETR} command: \code{'RETR \var{filename}'}.
+The \var{callback} function is called for each block of data received,
+with a single string argument giving the data block.
+The optional \var{maxblocksize} argument specifies the maximum chunk size to
+read on the low-level socket object created to do the actual transfer
+(which will also be the largest size of the data blocks passed to
+\var{callback}).  A reasonable default is chosen. \var{rest} means the
+same thing as in the \method{transfercmd()} method.
+\end{methoddesc}
+
+\begin{methoddesc}{retrlines}{command\optional{, callback}}
+Retrieve a file or directory listing in \ASCII{} transfer mode.
+\var{command} should be an appropriate \samp{RETR} command (see
+\method{retrbinary()}) or a \samp{LIST} command (usually just the string
+\code{'LIST'}).  The \var{callback} function is called for each line,
+with the trailing CRLF stripped.  The default \var{callback} prints
+the line to \code{sys.stdout}.
+\end{methoddesc}
+
+\begin{methoddesc}{set_pasv}{boolean}
+Enable ``passive'' mode if \var{boolean} is true, other disable
+passive mode.  (In Python 2.0 and before, passive mode was off by
+default; in Python 2.1 and later, it is on by default.)
+\end{methoddesc}
+
+\begin{methoddesc}{storbinary}{command, file\optional{, blocksize}}
+Store a file in binary transfer mode.  \var{command} should be an
+appropriate \samp{STOR} command: \code{"STOR \var{filename}"}.
+\var{file} is an open file object which is read until \EOF{} using its
+\method{read()} method in blocks of size \var{blocksize} to provide the
+data to be stored.  The \var{blocksize} argument defaults to 8192.
+\versionchanged[default for \var{blocksize} added]{2.1}
+\end{methoddesc}
+
+\begin{methoddesc}{storlines}{command, file}
+Store a file in \ASCII{} transfer mode.  \var{command} should be an
+appropriate \samp{STOR} command (see \method{storbinary()}).  Lines are
+read until \EOF{} from the open file object \var{file} using its
+\method{readline()} method to provide the data to be stored.
+\end{methoddesc}
+
+\begin{methoddesc}{transfercmd}{cmd\optional{, rest}}
+Initiate a transfer over the data connection.  If the transfer is
+active, send a \samp{EPRT} or  \samp{PORT} command and the transfer command specified
+by \var{cmd}, and accept the connection.  If the server is passive,
+send a \samp{EPSV} or \samp{PASV} command, connect to it, and start the transfer
+command.  Either way, return the socket for the connection.
+
+If optional \var{rest} is given, a \samp{REST} command is
+sent to the server, passing \var{rest} as an argument.  \var{rest} is
+usually a byte offset into the requested file, telling the server to
+restart sending the file's bytes at the requested offset, skipping
+over the initial bytes.  Note however that RFC
+959 requires only that \var{rest} be a string containing characters
+in the printable range from ASCII code 33 to ASCII code 126.  The
+\method{transfercmd()} method, therefore, converts
+\var{rest} to a string, but no check is
+performed on the string's contents.  If the server does
+not recognize the \samp{REST} command, an
+\exception{error_reply} exception will be raised.  If this happens,
+simply call \method{transfercmd()} without a \var{rest} argument.
+\end{methoddesc}
+
+\begin{methoddesc}{ntransfercmd}{cmd\optional{, rest}}
+Like \method{transfercmd()}, but returns a tuple of the data
+connection and the expected size of the data.  If the expected size
+could not be computed, \code{None} will be returned as the expected
+size.  \var{cmd} and \var{rest} means the same thing as in
+\method{transfercmd()}.
+\end{methoddesc}
+
+\begin{methoddesc}{nlst}{argument\optional{, \ldots}}
+Return a list of files as returned by the \samp{NLST} command.  The
+optional \var{argument} is a directory to list (default is the current
+server directory).  Multiple arguments can be used to pass
+non-standard options to the \samp{NLST} command.
+\end{methoddesc}
+
+\begin{methoddesc}{dir}{argument\optional{, \ldots}}
+Produce a directory listing as returned by the \samp{LIST} command,
+printing it to standard output.  The optional \var{argument} is a
+directory to list (default is the current server directory).  Multiple
+arguments can be used to pass non-standard options to the \samp{LIST}
+command.  If the last argument is a function, it is used as a
+\var{callback} function as for \method{retrlines()}; the default
+prints to \code{sys.stdout}.  This method returns \code{None}.
+\end{methoddesc}
+
+\begin{methoddesc}{rename}{fromname, toname}
+Rename file \var{fromname} on the server to \var{toname}.
+\end{methoddesc}
+
+\begin{methoddesc}{delete}{filename}
+Remove the file named \var{filename} from the server.  If successful,
+returns the text of the response, otherwise raises
+\exception{error_perm} on permission errors or
+\exception{error_reply} on other errors.
+\end{methoddesc}
+
+\begin{methoddesc}{cwd}{pathname}
+Set the current directory on the server.
+\end{methoddesc}
+
+\begin{methoddesc}{mkd}{pathname}
+Create a new directory on the server.
+\end{methoddesc}
+
+\begin{methoddesc}{pwd}{}
+Return the pathname of the current directory on the server.
+\end{methoddesc}
+
+\begin{methoddesc}{rmd}{dirname}
+Remove the directory named \var{dirname} on the server.
+\end{methoddesc}
+
+\begin{methoddesc}{size}{filename}
+Request the size of the file named \var{filename} on the server.  On
+success, the size of the file is returned as an integer, otherwise
+\code{None} is returned.  Note that the \samp{SIZE} command is not 
+standardized, but is supported by many common server implementations.
+\end{methoddesc}
+
+\begin{methoddesc}{quit}{}
+Send a \samp{QUIT} command to the server and close the connection.
+This is the ``polite'' way to close a connection, but it may raise an
+exception of the server reponds with an error to the
+\samp{QUIT} command.  This implies a call to the \method{close()}
+method which renders the \class{FTP} instance useless for subsequent
+calls (see below).
+\end{methoddesc}
+
+\begin{methoddesc}{close}{}
+Close the connection unilaterally.  This should not be applied to an
+already closed connection such as after a successful call to
+\method{quit()}.  After this call the \class{FTP} instance should not
+be used any more (after a call to \method{close()} or
+\method{quit()} you cannot reopen the connection by issuing another
+\method{login()} method).
+\end{methoddesc}

Added: vendor/Python/current/Doc/lib/libfuncs.tex
===================================================================
--- vendor/Python/current/Doc/lib/libfuncs.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libfuncs.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1321 @@
+\section{Built-in Functions \label{built-in-funcs}}
+
+The Python interpreter has a number of functions built into it that
+are always available.  They are listed here in alphabetical order.
+
+
+\setindexsubitem{(built-in function)}
+
+\begin{funcdesc}{__import__}{name\optional{, globals\optional{, locals\optional{, fromlist\optional{, level}}}}}
+  This function is invoked by the \keyword{import}\stindex{import}
+  statement.  It mainly exists so that you can replace it with another
+  function that has a compatible interface, in order to change the
+  semantics of the \keyword{import} statement.  For examples of why
+  and how you would do this, see the standard library modules
+  \module{ihooks}\refstmodindex{ihooks} and
+  \refmodule{rexec}\refstmodindex{rexec}.  See also the built-in
+  module \refmodule{imp}\refbimodindex{imp}, which defines some useful
+  operations out of which you can build your own
+  \function{__import__()} function.
+
+  For example, the statement \samp{import spam} results in the
+  following call: \code{__import__('spam',} \code{globals(),}
+  \code{locals(), [], -1)}; the statement \samp{from spam.ham import eggs}
+  results in \samp{__import__('spam.ham', globals(), locals(),
+  ['eggs'], -1)}.  Note that even though \code{locals()} and
+  \code{['eggs']} are passed in as arguments, the
+  \function{__import__()} function does not set the local variable
+  named \code{eggs}; this is done by subsequent code that is generated
+  for the import statement.  (In fact, the standard implementation
+  does not use its \var{locals} argument at all, and uses its
+  \var{globals} only to determine the package context of the
+  \keyword{import} statement.)
+
+  When the \var{name} variable is of the form \code{package.module},
+  normally, the top-level package (the name up till the first dot) is
+  returned, \emph{not} the module named by \var{name}.  However, when
+  a non-empty \var{fromlist} argument is given, the module named by
+  \var{name} is returned.  This is done for compatibility with the
+  bytecode generated for the different kinds of import statement; when
+  using \samp{import spam.ham.eggs}, the top-level package \module{spam}
+  must be placed in the importing namespace, but when using \samp{from
+  spam.ham import eggs}, the \code{spam.ham} subpackage must be used
+  to find the \code{eggs} variable.  As a workaround for this
+  behavior, use \function{getattr()} to extract the desired
+  components.  For example, you could define the following helper:
+
+\begin{verbatim}
+def my_import(name):
+    mod = __import__(name)
+    components = name.split('.')
+    for comp in components[1:]:
+        mod = getattr(mod, comp)
+    return mod
+\end{verbatim}
+
+  \var{level} specifies whether to use absolute or relative imports.
+  The default is \code{-1} which indicates both absolute and relative
+  imports will be attempted.  \code{0} means only perform absolute imports.
+  Positive values for \var{level} indicate the number of parent directories
+  to search relative to the directory of the module calling
+  \function{__import__}.
+\versionchanged[The level parameter was added]{2.5}
+\versionchanged[Keyword support for parameters was added]{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{abs}{x}
+  Return the absolute value of a number.  The argument may be a plain
+  or long integer or a floating point number.  If the argument is a
+  complex number, its magnitude is returned.
+\end{funcdesc}
+
+\begin{funcdesc}{all}{iterable}
+  Return True if all elements of the \var{iterable} are true.
+  Equivalent to:
+  \begin{verbatim}
+     def all(iterable):
+         for element in iterable:
+             if not element:
+                 return False
+         return True
+  \end{verbatim}
+  \versionadded{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{any}{iterable}
+  Return True if any element of the \var{iterable} is true.
+  Equivalent to:
+  \begin{verbatim}
+     def any(iterable):
+         for element in iterable:
+             if element:
+                 return True
+         return False
+  \end{verbatim}
+  \versionadded{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{basestring}{}
+  This abstract type is the superclass for \class{str} and \class{unicode}.
+  It cannot be called or instantiated, but it can be used to test whether
+  an object is an instance of \class{str} or \class{unicode}.
+  \code{isinstance(obj, basestring)} is equivalent to
+  \code{isinstance(obj, (str, unicode))}.
+  \versionadded{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{bool}{\optional{x}}
+  Convert a value to a Boolean, using the standard truth testing
+  procedure.  If \var{x} is false or omitted, this returns
+  \constant{False}; otherwise it returns \constant{True}.
+  \class{bool} is also a class, which is a subclass of \class{int}.
+  Class \class{bool} cannot be subclassed further.  Its only instances
+  are \constant{False} and \constant{True}.
+
+  \indexii{Boolean}{type}
+  \versionadded{2.2.1}
+  \versionchanged[If no argument is given, this function returns
+                  \constant{False}]{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{callable}{object}
+  Return true if the \var{object} argument appears callable, false if
+  not.  If this returns true, it is still possible that a call fails,
+  but if it is false, calling \var{object} will never succeed.  Note
+  that classes are callable (calling a class returns a new instance);
+  class instances are callable if they have a \method{__call__()}
+  method.
+\end{funcdesc}
+
+\begin{funcdesc}{chr}{i}
+  Return a string of one character whose \ASCII{} code is the integer
+  \var{i}.  For example, \code{chr(97)} returns the string \code{'a'}.
+  This is the inverse of \function{ord()}.  The argument must be in
+  the range [0..255], inclusive; \exception{ValueError} will be raised
+  if \var{i} is outside that range.
+\end{funcdesc}
+
+\begin{funcdesc}{classmethod}{function}
+  Return a class method for \var{function}.
+
+  A class method receives the class as implicit first argument,
+  just like an instance method receives the instance.
+  To declare a class method, use this idiom:
+
+\begin{verbatim}
+class C:
+    @classmethod
+    def f(cls, arg1, arg2, ...): ...
+\end{verbatim}
+
+  The \code{@classmethod} form is a function decorator -- see the description
+  of function definitions in chapter 7 of the
+  \citetitle[../ref/ref.html]{Python Reference Manual} for details.
+
+  It can be called either on the class (such as \code{C.f()}) or on an
+  instance (such as \code{C().f()}).  The instance is ignored except for
+  its class.
+  If a class method is called for a derived class, the derived class
+  object is passed as the implied first argument.
+
+  Class methods are different than \Cpp{} or Java static methods.
+  If you want those, see \function{staticmethod()} in this section.
+  
+  For more information on class methods, consult the documentation on the
+  standard type hierarchy in chapter 3 of the
+  \citetitle[../ref/types.html]{Python Reference Manual} (at the bottom).
+  \versionadded{2.2}
+  \versionchanged[Function decorator syntax added]{2.4}
+\end{funcdesc}
+
+\begin{funcdesc}{cmp}{x, y}
+  Compare the two objects \var{x} and \var{y} and return an integer
+  according to the outcome.  The return value is negative if \code{\var{x}
+  < \var{y}}, zero if \code{\var{x} == \var{y}} and strictly positive if
+  \code{\var{x} > \var{y}}.
+\end{funcdesc}
+
+\begin{funcdesc}{compile}{string, filename, kind\optional{,
+                          flags\optional{, dont_inherit}}}
+  Compile the \var{string} into a code object.  Code objects can be
+  executed by an \keyword{exec} statement or evaluated by a call to
+  \function{eval()}.  The \var{filename} argument should
+  give the file from which the code was read; pass some recognizable value
+  if it wasn't read from a file (\code{'<string>'} is commonly used).
+  The \var{kind} argument specifies what kind of code must be
+  compiled; it can be \code{'exec'} if \var{string} consists of a
+  sequence of statements, \code{'eval'} if it consists of a single
+  expression, or \code{'single'} if it consists of a single
+  interactive statement (in the latter case, expression statements
+  that evaluate to something else than \code{None} will be printed).
+
+  When compiling multi-line statements, two caveats apply: line
+  endings must be represented by a single newline character
+  (\code{'\e n'}), and the input must be terminated by at least one
+  newline character.  If line endings are represented by
+  \code{'\e r\e n'}, use the string \method{replace()} method to
+  change them into \code{'\e n'}.
+
+  The optional arguments \var{flags} and \var{dont_inherit}
+  (which are new in Python 2.2) control which future statements (see
+  \pep{236}) affect the compilation of \var{string}.  If neither is
+  present (or both are zero) the code is compiled with those future
+  statements that are in effect in the code that is calling compile.
+  If the \var{flags} argument is given and \var{dont_inherit} is not
+  (or is zero) then the future statements specified by the \var{flags}
+  argument are used in addition to those that would be used anyway.
+  If \var{dont_inherit} is a non-zero integer then the \var{flags}
+  argument is it -- the future statements in effect around the call to
+  compile are ignored.
+
+  Future statements are specified by bits which can be bitwise or-ed
+  together to specify multiple statements.  The bitfield required to
+  specify a given feature can be found as the \member{compiler_flag}
+  attribute on the \class{_Feature} instance in the
+  \module{__future__} module.
+\end{funcdesc}
+
+\begin{funcdesc}{complex}{\optional{real\optional{, imag}}}
+  Create a complex number with the value \var{real} + \var{imag}*j or
+  convert a string or number to a complex number.  If the first
+  parameter is a string, it will be interpreted as a complex number
+  and the function must be called without a second parameter.  The
+  second parameter can never be a string.
+  Each argument may be any numeric type (including complex).
+  If \var{imag} is omitted, it defaults to zero and the function
+  serves as a numeric conversion function like \function{int()},
+  \function{long()} and \function{float()}.  If both arguments
+  are omitted, returns \code{0j}.
+\end{funcdesc}
+
+\begin{funcdesc}{delattr}{object, name}
+  This is a relative of \function{setattr()}.  The arguments are an
+  object and a string.  The string must be the name
+  of one of the object's attributes.  The function deletes
+  the named attribute, provided the object allows it.  For example,
+  \code{delattr(\var{x}, '\var{foobar}')} is equivalent to
+  \code{del \var{x}.\var{foobar}}.
+\end{funcdesc}
+
+\begin{funcdesc}{dict}{\optional{arg}}
+  Return a new dictionary initialized from an optional positional
+  argument or from a set of keyword arguments.
+  If no arguments are given, return a new empty dictionary.
+  If the positional argument \var{arg} is a mapping object, return a dictionary
+  mapping the same keys to the same values as does the mapping object.
+  Otherwise the positional argument must be a sequence, a container that
+  supports iteration, or an iterator object.  The elements of the argument
+  must each also be of one of those kinds, and each must in turn contain
+  exactly two objects.  The first is used as a key in the new dictionary,
+  and the second as the key's value.  If a given key is seen more than
+  once, the last value associated with it is retained in the new
+  dictionary.
+
+  If keyword arguments are given, the keywords themselves with their
+  associated values are added as items to the dictionary. If a key
+  is specified both in the positional argument and as a keyword argument,
+  the value associated with the keyword is retained in the dictionary.
+  For example, these all return a dictionary equal to
+  \code{\{"one": 2, "two": 3\}}:
+
+  \begin{itemize}
+    \item \code{dict(\{'one': 2, 'two': 3\})}
+    \item \code{dict(\{'one': 2, 'two': 3\}.items())}
+    \item \code{dict(\{'one': 2, 'two': 3\}.iteritems())}
+    \item \code{dict(zip(('one', 'two'), (2, 3)))}
+    \item \code{dict([['two', 3], ['one', 2]])}
+    \item \code{dict(one=2, two=3)}
+    \item \code{dict([(['one', 'two'][i-2], i) for i in (2, 3)])}
+  \end{itemize}
+
+  \versionadded{2.2}
+  \versionchanged[Support for building a dictionary from keyword
+                  arguments added]{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{dir}{\optional{object}}
+  Without arguments, return the list of names in the current local
+  symbol table.  With an argument, attempts to return a list of valid
+  attributes for that object.  This information is gleaned from the
+  object's \member{__dict__} attribute, if defined, and from the class
+  or type object.  The list is not necessarily complete.
+  If the object is a module object, the list contains the names of the
+  module's attributes.
+  If the object is a type or class object,
+  the list contains the names of its attributes,
+  and recursively of the attributes of its bases.
+  Otherwise, the list contains the object's attributes' names,
+  the names of its class's attributes,
+  and recursively of the attributes of its class's base classes.
+  The resulting list is sorted alphabetically.
+  For example:
+
+\begin{verbatim}
+>>> import struct
+>>> dir()
+['__builtins__', '__doc__', '__name__', 'struct']
+>>> dir(struct)
+['__doc__', '__name__', 'calcsize', 'error', 'pack', 'unpack']
+\end{verbatim}
+
+  \note{Because \function{dir()} is supplied primarily as a convenience
+  for use at an interactive prompt,
+  it tries to supply an interesting set of names more than it tries to
+  supply a rigorously or consistently defined set of names,
+  and its detailed behavior may change across releases.}
+\end{funcdesc}
+
+\begin{funcdesc}{divmod}{a, b}
+  Take two (non complex) numbers as arguments and return a pair of numbers
+  consisting of their quotient and remainder when using long division.  With
+  mixed operand types, the rules for binary arithmetic operators apply.  For
+  plain and long integers, the result is the same as
+  \code{(\var{a} // \var{b}, \var{a} \%{} \var{b})}.
+  For floating point numbers the result is \code{(\var{q}, \var{a} \%{}
+  \var{b})}, where \var{q} is usually \code{math.floor(\var{a} /
+  \var{b})} but may be 1 less than that.  In any case \code{\var{q} *
+  \var{b} + \var{a} \%{} \var{b}} is very close to \var{a}, if
+  \code{\var{a} \%{} \var{b}} is non-zero it has the same sign as
+  \var{b}, and \code{0 <= abs(\var{a} \%{} \var{b}) < abs(\var{b})}.
+
+  \versionchanged[Using \function{divmod()} with complex numbers is
+                  deprecated]{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{enumerate}{iterable}
+  Return an enumerate object. \var{iterable} must be a sequence, an
+  iterator, or some other object which supports iteration.  The
+  \method{next()} method of the iterator returned by
+  \function{enumerate()} returns a tuple containing a count (from
+  zero) and the corresponding value obtained from iterating over
+  \var{iterable}.  \function{enumerate()} is useful for obtaining an
+  indexed series: \code{(0, seq[0])}, \code{(1, seq[1])}, \code{(2,
+  seq[2])}, \ldots.
+  \versionadded{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{eval}{expression\optional{, globals\optional{, locals}}}
+  The arguments are a string and optional globals and locals.  If provided,
+  \var{globals} must be a dictionary.  If provided, \var{locals} can be
+  any mapping object.  \versionchanged[formerly \var{locals} was required
+  to be a dictionary]{2.4}
+
+  The \var{expression} argument is parsed and evaluated as a Python
+  expression (technically speaking, a condition list) using the
+  \var{globals} and \var{locals} dictionaries as global and local name
+  space.  If the \var{globals} dictionary is present and lacks
+  '__builtins__', the current globals are copied into \var{globals} before
+  \var{expression} is parsed.  This means that \var{expression}
+  normally has full access to the standard
+  \refmodule[builtin]{__builtin__} module and restricted environments
+  are propagated.  If the \var{locals} dictionary is omitted it defaults to
+  the \var{globals} dictionary.  If both dictionaries are omitted, the
+  expression is executed in the environment where \keyword{eval} is
+  called.  The return value is the result of the evaluated expression.
+  Syntax errors are reported as exceptions.  Example:
+
+\begin{verbatim}
+>>> x = 1
+>>> print eval('x+1')
+2
+\end{verbatim}
+
+  This function can also be used to execute arbitrary code objects
+  (such as those created by \function{compile()}).  In this case pass
+  a code object instead of a string.  The code object must have been
+  compiled passing \code{'eval'} as the \var{kind} argument.
+
+  Hints: dynamic execution of statements is supported by the
+  \keyword{exec} statement.  Execution of statements from a file is
+  supported by the \function{execfile()} function.  The
+  \function{globals()} and \function{locals()} functions returns the
+  current global and local dictionary, respectively, which may be
+  useful to pass around for use by \function{eval()} or
+  \function{execfile()}.
+\end{funcdesc}
+
+\begin{funcdesc}{execfile}{filename\optional{, globals\optional{, locals}}}
+  This function is similar to the
+  \keyword{exec} statement, but parses a file instead of a string.  It
+  is different from the \keyword{import} statement in that it does not
+  use the module administration --- it reads the file unconditionally
+  and does not create a new module.\footnote{It is used relatively
+  rarely so does not warrant being made into a statement.}
+
+  The arguments are a file name and two optional dictionaries.  The file is
+  parsed and evaluated as a sequence of Python statements (similarly to a
+  module) using the \var{globals} and \var{locals} dictionaries as global and
+  local namespace. If provided, \var{locals} can be any mapping object.
+  \versionchanged[formerly \var{locals} was required to be a dictionary]{2.4}
+  If the \var{locals} dictionary is omitted it defaults to the \var{globals}
+  dictionary. If both dictionaries are omitted, the expression is executed in
+  the environment where \function{execfile()} is called.  The return value is
+  \code{None}.
+
+  \warning{The default \var{locals} act as described for function
+  \function{locals()} below:  modifications to the default \var{locals}
+  dictionary should not be attempted.  Pass an explicit \var{locals}
+  dictionary if you need to see effects of the code on \var{locals} after
+  function \function{execfile()} returns.  \function{execfile()} cannot
+  be used reliably to modify a function's locals.}
+\end{funcdesc}
+
+\begin{funcdesc}{file}{filename\optional{, mode\optional{, bufsize}}}
+  Constructor function for the \class{file} type, described further 
+  in section~\ref{bltin-file-objects}, ``\ulink{File
+  Objects}{bltin-file-objects.html}''.  The constructor's arguments
+  are the same as those of the \function{open()} built-in function
+  described below.
+
+  When opening a file, it's preferable to use \function{open()} instead of 
+  invoking this constructor directly.  \class{file} is more suited to
+  type testing (for example, writing \samp{isinstance(f, file)}).
+
+  \versionadded{2.2}
+\end{funcdesc}
+
+\begin{funcdesc}{filter}{function, iterable}
+  Construct a list from those elements of \var{iterable} for which
+  \var{function} returns true.  \var{iterable} may be either a sequence, a
+  container which supports iteration, or an iterator,  If \var{iterable}
+  is a string or a tuple, the result
+  also has that type; otherwise it is always a list.  If \var{function} is
+  \code{None}, the identity function is assumed, that is, all elements of
+  \var{iterable} that are false are removed.
+
+  Note that \code{filter(function, \var{iterable})} is equivalent to
+  \code{[item for item in \var{iterable} if function(item)]} if function is
+  not \code{None} and \code{[item for item in \var{iterable} if item]} if
+  function is \code{None}.
+\end{funcdesc}
+
+\begin{funcdesc}{float}{\optional{x}}
+  Convert a string or a number to floating point.  If the argument is a
+  string, it must contain a possibly signed decimal or floating point
+  number, possibly embedded in whitespace. Otherwise, the argument may be a plain
+  or long integer or a floating point number, and a floating point
+  number with the same value (within Python's floating point
+  precision) is returned.  If no argument is given, returns \code{0.0}.
+
+  \note{When passing in a string, values for NaN\index{NaN}
+  and Infinity\index{Infinity} may be returned, depending on the
+  underlying C library.  The specific set of strings accepted which
+  cause these values to be returned depends entirely on the C library
+  and is known to vary.}
+\end{funcdesc}
+
+\begin{funcdesc}{frozenset}{\optional{iterable}}
+  Return a frozenset object whose elements are taken from \var{iterable}.
+  Frozensets are sets that have no update methods but can be hashed and
+  used as members of other sets or as dictionary keys.  The elements of
+  a frozenset must be immutable themselves.  To represent sets of sets,
+  the inner sets should also be \class{frozenset} objects.  If
+  \var{iterable} is not specified, returns a new empty set,
+  \code{frozenset([])}.
+  \versionadded{2.4}
+\end{funcdesc}
+
+\begin{funcdesc}{getattr}{object, name\optional{, default}}
+  Return the value of the named attributed of \var{object}.  \var{name}
+  must be a string.  If the string is the name of one of the object's
+  attributes, the result is the value of that attribute.  For example,
+  \code{getattr(x, 'foobar')} is equivalent to \code{x.foobar}.  If the
+  named attribute does not exist, \var{default} is returned if provided,
+  otherwise \exception{AttributeError} is raised.
+\end{funcdesc}
+
+\begin{funcdesc}{globals}{}
+  Return a dictionary representing the current global symbol table.
+  This is always the dictionary of the current module (inside a
+  function or method, this is the module where it is defined, not the
+  module from which it is called).
+\end{funcdesc}
+
+\begin{funcdesc}{hasattr}{object, name}
+  The arguments are an object and a string.  The result is \code{True} if the
+  string is the name of one of the object's attributes, \code{False} if not.
+  (This is implemented by calling \code{getattr(\var{object},
+  \var{name})} and seeing whether it raises an exception or not.)
+\end{funcdesc}
+
+\begin{funcdesc}{hash}{object}
+  Return the hash value of the object (if it has one).  Hash values
+  are integers.  They are used to quickly compare dictionary
+  keys during a dictionary lookup.  Numeric values that compare equal
+  have the same hash value (even if they are of different types, as is
+  the case for 1 and 1.0).
+\end{funcdesc}
+
+\begin{funcdesc}{help}{\optional{object}}
+  Invoke the built-in help system.  (This function is intended for
+  interactive use.)  If no argument is given, the interactive help
+  system starts on the interpreter console.  If the argument is a
+  string, then the string is looked up as the name of a module,
+  function, class, method, keyword, or documentation topic, and a
+  help page is printed on the console.  If the argument is any other
+  kind of object, a help page on the object is generated.
+  \versionadded{2.2}
+\end{funcdesc}
+
+\begin{funcdesc}{hex}{x}
+  Convert an integer number (of any size) to a hexadecimal string.
+  The result is a valid Python expression.
+  \versionchanged[Formerly only returned an unsigned literal]{2.4}
+\end{funcdesc}
+
+\begin{funcdesc}{id}{object}
+  Return the ``identity'' of an object.  This is an integer (or long
+  integer) which is guaranteed to be unique and constant for this
+  object during its lifetime.  Two objects with non-overlapping lifetimes
+  may have the same \function{id()} value.  (Implementation
+  note: this is the address of the object.)
+\end{funcdesc}
+
+\begin{funcdesc}{input}{\optional{prompt}}
+  Equivalent to \code{eval(raw_input(\var{prompt}))}.
+  \warning{This function is not safe from user errors!  It
+  expects a valid Python expression as input; if the input is not
+  syntactically valid, a \exception{SyntaxError} will be raised.
+  Other exceptions may be raised if there is an error during
+  evaluation.  (On the other hand, sometimes this is exactly what you
+  need when writing a quick script for expert use.)}
+
+  If the \refmodule{readline} module was loaded, then
+  \function{input()} will use it to provide elaborate line editing and
+  history features.
+
+  Consider using the \function{raw_input()} function for general input
+  from users.
+\end{funcdesc}
+
+\begin{funcdesc}{int}{\optional{x\optional{, radix}}}
+  Convert a string or number to a plain integer.  If the argument is a
+  string, it must contain a possibly signed decimal number
+  representable as a Python integer, possibly embedded in whitespace.
+  The \var{radix} parameter gives the base for the
+  conversion and may be any integer in the range [2, 36], or zero.  If
+  \var{radix} is zero, the proper radix is guessed based on the
+  contents of string; the interpretation is the same as for integer
+  literals.  If \var{radix} is specified and \var{x} is not a string,
+  \exception{TypeError} is raised.
+  Otherwise, the argument may be a plain or
+  long integer or a floating point number.  Conversion of floating
+  point numbers to integers truncates (towards zero).
+  If the argument is outside the integer range a long object will
+  be returned instead.  If no arguments are given, returns \code{0}.
+\end{funcdesc}
+
+\begin{funcdesc}{isinstance}{object, classinfo}
+  Return true if the \var{object} argument is an instance of the
+  \var{classinfo} argument, or of a (direct or indirect) subclass
+  thereof.  Also return true if \var{classinfo} is a type object
+  (new-style class) and \var{object} is an object of that type or of a
+  (direct or indirect) subclass thereof.  If \var{object} is not a
+  class instance or an object of the given type, the function always
+  returns false.  If \var{classinfo} is neither a class object nor a
+  type object, it may be a tuple of class or type objects, or may
+  recursively contain other such tuples (other sequence types are not
+  accepted).  If \var{classinfo} is not a class, type, or tuple of
+  classes, types, and such tuples, a \exception{TypeError} exception
+  is raised.
+  \versionchanged[Support for a tuple of type information was added]{2.2}
+\end{funcdesc}
+
+\begin{funcdesc}{issubclass}{class, classinfo}
+  Return true if \var{class} is a subclass (direct or indirect) of
+  \var{classinfo}.  A class is considered a subclass of itself.
+  \var{classinfo} may be a tuple of class objects, in which case every
+  entry in \var{classinfo} will be checked. In any other case, a
+  \exception{TypeError} exception is raised.
+  \versionchanged[Support for a tuple of type information was added]{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{iter}{o\optional{, sentinel}}
+  Return an iterator object.  The first argument is interpreted very
+  differently depending on the presence of the second argument.
+  Without a second argument, \var{o} must be a collection object which
+  supports the iteration protocol (the \method{__iter__()} method), or
+  it must support the sequence protocol (the \method{__getitem__()}
+  method with integer arguments starting at \code{0}).  If it does not
+  support either of those protocols, \exception{TypeError} is raised.
+  If the second argument, \var{sentinel}, is given, then \var{o} must
+  be a callable object.  The iterator created in this case will call
+  \var{o} with no arguments for each call to its \method{next()}
+  method; if the value returned is equal to \var{sentinel},
+  \exception{StopIteration} will be raised, otherwise the value will
+  be returned.
+  \versionadded{2.2}
+\end{funcdesc}
+
+\begin{funcdesc}{len}{s}
+  Return the length (the number of items) of an object.  The argument
+  may be a sequence (string, tuple or list) or a mapping (dictionary).
+\end{funcdesc}
+
+\begin{funcdesc}{list}{\optional{iterable}}
+  Return a list whose items are the same and in the same order as
+  \var{iterable}'s items.  \var{iterable} may be either a sequence, a
+  container that supports iteration, or an iterator object.  If
+  \var{iterable} is already a list, a copy is made and returned,
+  similar to \code{\var{iterable}[:]}.  For instance,
+  \code{list('abc')} returns \code{['a', 'b', 'c']} and \code{list(
+  (1, 2, 3) )} returns \code{[1, 2, 3]}.  If no argument is given,
+  returns a new empty list, \code{[]}.
+\end{funcdesc}
+
+\begin{funcdesc}{locals}{}
+  Update and return a dictionary representing the current local symbol table.
+  \warning{The contents of this dictionary should not be modified;
+  changes may not affect the values of local variables used by the
+  interpreter.}
+\end{funcdesc}
+
+\begin{funcdesc}{long}{\optional{x\optional{, radix}}}
+  Convert a string or number to a long integer.  If the argument is a
+  string, it must contain a possibly signed number of
+  arbitrary size, possibly embedded in whitespace. The
+  \var{radix} argument is interpreted in the same way as for
+  \function{int()}, and may only be given when \var{x} is a string.
+  Otherwise, the argument may be a plain or
+  long integer or a floating point number, and a long integer with
+  the same value is returned.    Conversion of floating
+  point numbers to integers truncates (towards zero).  If no arguments
+  are given, returns \code{0L}.
+\end{funcdesc}
+
+\begin{funcdesc}{map}{function, iterable, ...}
+  Apply \var{function} to every item of \var{iterable} and return a list
+  of the results.  If additional \var{iterable} arguments are passed,
+  \var{function} must take that many arguments and is applied to the
+  items from all iterables in parallel.  If one iterable is shorter than another it
+  is assumed to be extended with \code{None} items.  If \var{function}
+  is \code{None}, the identity function is assumed; if there are
+  multiple arguments, \function{map()} returns a list consisting
+  of tuples containing the corresponding items from all iterables (a kind
+  of transpose operation).  The \var{iterable} arguments may be a sequence 
+  or any iterable object; the result is always a list.
+\end{funcdesc}
+
+\begin{funcdesc}{max}{iterable\optional{, args...}\optional{key}}
+  With a single argument \var{iterable}, return the largest item of a
+  non-empty iterable (such as a string, tuple or list).  With more
+  than one argument, return the largest of the arguments.
+
+  The optional \var{key} argument specifies a one-argument ordering
+  function like that used for \method{list.sort()}.  The \var{key}
+  argument, if supplied, must be in keyword form (for example,
+  \samp{max(a,b,c,key=func)}).
+  \versionchanged[Added support for the optional \var{key} argument]{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{min}{iterable\optional{, args...}\optional{key}}
+  With a single argument \var{iterable}, return the smallest item of a
+  non-empty iterable (such as a string, tuple or list).  With more
+  than one argument, return the smallest of the arguments.
+
+  The optional \var{key} argument specifies a one-argument ordering
+  function like that used for \method{list.sort()}.  The \var{key}
+  argument, if supplied, must be in keyword form (for example,
+  \samp{min(a,b,c,key=func)}).
+  \versionchanged[Added support for the optional \var{key} argument]{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{object}{}
+  Return a new featureless object.  \class{object} is a base
+  for all new style classes.  It has the methods that are common
+  to all instances of new style classes.
+  \versionadded{2.2}
+
+  \versionchanged[This function does not accept any arguments.
+  Formerly, it accepted arguments but ignored them]{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{oct}{x}
+  Convert an integer number (of any size) to an octal string.  The
+  result is a valid Python expression.
+  \versionchanged[Formerly only returned an unsigned literal]{2.4}
+\end{funcdesc}
+
+\begin{funcdesc}{open}{filename\optional{, mode\optional{, bufsize}}}
+  Open a file, returning an object of the \class{file} type described
+  in section~\ref{bltin-file-objects}, ``\ulink{File
+  Objects}{bltin-file-objects.html}''.  If the file cannot be opened,
+  \exception{IOError} is raised.  When opening a file, it's
+  preferable to use \function{open()} instead of invoking the
+  \class{file} constructor directly.
+
+  The first two arguments are the same as for \code{stdio}'s
+  \cfunction{fopen()}: \var{filename} is the file name to be opened,
+  and \var{mode} is a string indicating how the file is to be opened.
+
+  The most commonly-used values of \var{mode} are \code{'r'} for
+  reading, \code{'w'} for writing (truncating the file if it already
+  exists), and \code{'a'} for appending (which on \emph{some} \UNIX{}
+  systems means that \emph{all} writes append to the end of the file
+  regardless of the current seek position).  If \var{mode} is omitted,
+  it defaults to \code{'r'}.  When opening a binary file, you should
+  append \code{'b'} to the \var{mode} value to open the file in binary
+  mode, which will improve portability.  (Appending \code{'b'} is
+  useful even on systems that don't treat binary and text files
+  differently, where it serves as documentation.)  See below for more
+  possible values of \var{mode}.
+
+  \index{line-buffered I/O}\index{unbuffered I/O}\index{buffer size, I/O}
+  \index{I/O control!buffering}
+  The optional \var{bufsize} argument specifies the
+  file's desired buffer size: 0 means unbuffered, 1 means line
+  buffered, any other positive value means use a buffer of
+  (approximately) that size.  A negative \var{bufsize} means to use
+  the system default, which is usually line buffered for tty
+  devices and fully buffered for other files.  If omitted, the system
+  default is used.\footnote{
+    Specifying a buffer size currently has no effect on systems that
+    don't have \cfunction{setvbuf()}.  The interface to specify the
+    buffer size is not done using a method that calls
+    \cfunction{setvbuf()}, because that may dump core when called
+    after any I/O has been performed, and there's no reliable way to
+    determine whether this is the case.}
+
+  Modes \code{'r+'}, \code{'w+'} and \code{'a+'} open the file for
+  updating (note that \code{'w+'} truncates the file).  Append
+  \code{'b'} to the mode to open the file in binary mode, on systems
+  that differentiate between binary and text files; on systems
+  that don't have this distinction, adding the \code{'b'} has no effect.
+  
+  In addition to the standard \cfunction{fopen()} values \var{mode}
+  may be \code{'U'} or \code{'rU'}.  Python is usually built with universal
+  newline support; supplying \code{'U'} opens the file as a text file, but
+  lines may be terminated by any of the following: the \UNIX{} end-of-line
+  convention \code{'\e n'}, 
+  the Macintosh convention \code{'\e r'}, or the Windows
+  convention \code{'\e r\e n'}. All of these external representations are seen as
+  \code{'\e n'}
+  by the Python program. If Python is built without universal newline support
+  a \var{mode} with \code{'U'} is the same as normal text mode.  Note that
+  file objects so opened also have an attribute called
+  \member{newlines} which has a value of \code{None} (if no newlines
+  have yet been seen), \code{'\e n'}, \code{'\e r'}, \code{'\e r\e n'},
+  or a tuple containing all the newline types seen.
+
+  Python enforces that the mode, after stripping \code{'U'}, begins with
+  \code{'r'}, \code{'w'} or \code{'a'}.
+
+  \versionchanged[Restriction on first letter of mode string
+                  introduced]{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{ord}{c}
+  Given a string of length one, return an integer representing the
+  Unicode code point of the character when the argument is a unicode object,
+  or the value of the byte when the argument is an 8-bit string.
+  For example, \code{ord('a')} returns the integer \code{97},
+  \code{ord(u'\e u2020')} returns \code{8224}.  This is the inverse of
+  \function{chr()} for 8-bit strings and of \function{unichr()} for unicode
+  objects.  If a unicode argument is given and Python was built with
+  UCS2 Unicode, then the character's code point must be in the range
+  [0..65535] inclusive; otherwise the string length is two, and a
+  \exception{TypeError} will be raised.
+\end{funcdesc}
+
+\begin{funcdesc}{pow}{x, y\optional{, z}}
+  Return \var{x} to the power \var{y}; if \var{z} is present, return
+  \var{x} to the power \var{y}, modulo \var{z} (computed more
+  efficiently than \code{pow(\var{x}, \var{y}) \%\ \var{z}}).
+  The two-argument form \code{pow(\var{x}, \var{y})} is equivalent to using
+  the power operator: \code{\var{x}**\var{y}}.
+  
+  The arguments must have numeric types.  With mixed operand types, the
+  coercion rules for binary arithmetic operators apply.  For int and
+  long int operands, the result has the same type as the operands
+  (after coercion) unless the second argument is negative; in that
+  case, all arguments are converted to float and a float result is
+  delivered.  For example, \code{10**2} returns \code{100}, but
+  \code{10**-2} returns \code{0.01}.  (This last feature was added in
+  Python 2.2.  In Python 2.1 and before, if both arguments were of integer
+  types and the second argument was negative, an exception was raised.)
+  If the second argument is negative, the third argument must be omitted.
+  If \var{z} is present, \var{x} and \var{y} must be of integer types,
+  and \var{y} must be non-negative.  (This restriction was added in
+  Python 2.2.  In Python 2.1 and before, floating 3-argument \code{pow()}
+  returned platform-dependent results depending on floating-point
+  rounding accidents.)
+\end{funcdesc}
+
+\begin{funcdesc}{property}{\optional{fget\optional{, fset\optional{,
+                           fdel\optional{, doc}}}}}
+  Return a property attribute for new-style classes (classes that
+  derive from \class{object}).
+
+  \var{fget} is a function for getting an attribute value, likewise
+  \var{fset} is a function for setting, and \var{fdel} a function
+  for del'ing, an attribute.  Typical use is to define a managed attribute x:
+
+\begin{verbatim}
+class C(object):
+    def __init__(self): self._x = None
+    def getx(self): return self._x
+    def setx(self, value): self._x = value
+    def delx(self): del self._x
+    x = property(getx, setx, delx, "I'm the 'x' property.")
+\end{verbatim}
+
+  If given, \var{doc} will be the docstring of the property attribute.
+  Otherwise, the property will copy \var{fget}'s docstring (if it
+  exists).  This makes it possible to create read-only properties
+  easily using \function{property()} as a decorator:
+
+\begin{verbatim}
+class Parrot(object):
+    def __init__(self):
+        self._voltage = 100000
+
+    @property
+    def voltage(self):
+        """Get the current voltage."""
+        return self._voltage
+\end{verbatim}
+
+  turns the \method{voltage()} method into a ``getter'' for a read-only
+  attribute with the same name.
+
+  \versionadded{2.2}
+  \versionchanged[Use \var{fget}'s docstring if no \var{doc} given]{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{range}{\optional{start,} stop\optional{, step}}
+  This is a versatile function to create lists containing arithmetic
+  progressions.  It is most often used in \keyword{for} loops.  The
+  arguments must be plain integers.  If the \var{step} argument is
+  omitted, it defaults to \code{1}.  If the \var{start} argument is
+  omitted, it defaults to \code{0}.  The full form returns a list of
+  plain integers \code{[\var{start}, \var{start} + \var{step},
+  \var{start} + 2 * \var{step}, \ldots]}.  If \var{step} is positive,
+  the last element is the largest \code{\var{start} + \var{i} *
+  \var{step}} less than \var{stop}; if \var{step} is negative, the last
+  element is the smallest \code{\var{start} + \var{i} * \var{step}}
+  greater than \var{stop}.  \var{step} must not be zero (or else
+  \exception{ValueError} is raised).  Example:
+
+\begin{verbatim}
+>>> range(10)
+[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+>>> range(1, 11)
+[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+>>> range(0, 30, 5)
+[0, 5, 10, 15, 20, 25]
+>>> range(0, 10, 3)
+[0, 3, 6, 9]
+>>> range(0, -10, -1)
+[0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
+>>> range(0)
+[]
+>>> range(1, 0)
+[]
+\end{verbatim}
+\end{funcdesc}
+
+\begin{funcdesc}{raw_input}{\optional{prompt}}
+  If the \var{prompt} argument is present, it is written to standard output
+  without a trailing newline.  The function then reads a line from input,
+  converts it to a string (stripping a trailing newline), and returns that.
+  When \EOF{} is read, \exception{EOFError} is raised. Example:
+
+\begin{verbatim}
+>>> s = raw_input('--> ')
+--> Monty Python's Flying Circus
+>>> s
+"Monty Python's Flying Circus"
+\end{verbatim}
+
+  If the \refmodule{readline} module was loaded, then
+  \function{raw_input()} will use it to provide elaborate
+  line editing and history features.
+\end{funcdesc}
+
+\begin{funcdesc}{reduce}{function, iterable\optional{, initializer}}
+  Apply \var{function} of two arguments cumulatively to the items of
+  \var{iterable}, from left to right, so as to reduce the iterable to
+  a single value.  For example, \code{reduce(lambda x, y: x+y, [1, 2,
+  3, 4, 5])} calculates \code{((((1+2)+3)+4)+5)}.  The left argument,
+  \var{x}, is the accumulated value and the right argument, \var{y},
+  is the update value from the \var{iterable}.  If the optional
+  \var{initializer} is present, it is placed before the items of the
+  iterable in the calculation, and serves as a default when the
+  iterable is empty.  If \var{initializer} is not given and
+  \var{iterable} contains only one item, the first item is returned.
+\end{funcdesc}
+
+\begin{funcdesc}{reload}{module}
+  Reload a previously imported \var{module}.  The
+  argument must be a module object, so it must have been successfully
+  imported before.  This is useful if you have edited the module
+  source file using an external editor and want to try out the new
+  version without leaving the Python interpreter.  The return value is
+  the module object (the same as the \var{module} argument).
+
+  When \code{reload(module)} is executed:
+
+\begin{itemize}
+
+    \item Python modules' code is recompiled and the module-level code
+    reexecuted, defining a new set of objects which are bound to names in
+    the module's dictionary.  The \code{init} function of extension
+    modules is not called a second time.
+
+    \item As with all other objects in Python the old objects are only
+    reclaimed after their reference counts drop to zero.
+
+    \item The names in the module namespace are updated to point to
+    any new or changed objects.
+
+    \item Other references to the old objects (such as names external
+    to the module) are not rebound to refer to the new objects and
+    must be updated in each namespace where they occur if that is
+    desired.
+
+\end{itemize}
+
+  There are a number of other caveats:
+
+  If a module is syntactically correct but its initialization fails,
+  the first \keyword{import} statement for it does not bind its name
+  locally, but does store a (partially initialized) module object in
+  \code{sys.modules}.  To reload the module you must first
+  \keyword{import} it again (this will bind the name to the partially
+  initialized module object) before you can \function{reload()} it.
+
+  When a module is reloaded, its dictionary (containing the module's
+  global variables) is retained.  Redefinitions of names will override
+  the old definitions, so this is generally not a problem.  If the new
+  version of a module does not define a name that was defined by the
+  old version, the old definition remains.  This feature can be used
+  to the module's advantage if it maintains a global table or cache of
+  objects --- with a \keyword{try} statement it can test for the
+  table's presence and skip its initialization if desired:
+
+\begin{verbatim}
+try:
+    cache
+except NameError:
+    cache = {}
+\end{verbatim}
+
+
+  It is legal though generally not very useful to reload built-in or
+  dynamically loaded modules, except for \refmodule{sys},
+  \refmodule[main]{__main__} and \refmodule[builtin]{__builtin__}.  In
+  many cases, however, extension modules are not designed to be
+  initialized more than once, and may fail in arbitrary ways when
+  reloaded.
+
+  If a module imports objects from another module using \keyword{from}
+  \ldots{} \keyword{import} \ldots{}, calling \function{reload()} for
+  the other module does not redefine the objects imported from it ---
+  one way around this is to re-execute the \keyword{from} statement,
+  another is to use \keyword{import} and qualified names
+  (\var{module}.\var{name}) instead.
+
+  If a module instantiates instances of a class, reloading the module
+  that defines the class does not affect the method definitions of the
+  instances --- they continue to use the old class definition.  The
+  same is true for derived classes.
+\end{funcdesc}
+
+\begin{funcdesc}{repr}{object}
+  Return a string containing a printable representation of an object.
+  This is the same value yielded by conversions (reverse quotes).
+  It is sometimes useful to be able to access this operation as an
+  ordinary function.  For many types, this function makes an attempt
+  to return a string that would yield an object with the same value
+  when passed to \function{eval()}.
+\end{funcdesc}
+
+\begin{funcdesc}{reversed}{seq}
+  Return a reverse iterator.  \var{seq} must be an object which
+  supports the sequence protocol (the __len__() method and the
+  \method{__getitem__()} method with integer arguments starting at
+  \code{0}).
+  \versionadded{2.4}
+\end{funcdesc}
+
+\begin{funcdesc}{round}{x\optional{, n}}
+  Return the floating point value \var{x} rounded to \var{n} digits
+  after the decimal point.  If \var{n} is omitted, it defaults to zero.
+  The result is a floating point number.  Values are rounded to the
+  closest multiple of 10 to the power minus \var{n}; if two multiples
+  are equally close, rounding is done away from 0 (so. for example,
+  \code{round(0.5)} is \code{1.0} and \code{round(-0.5)} is \code{-1.0}).
+\end{funcdesc}
+
+\begin{funcdesc}{set}{\optional{iterable}}
+  Return a set whose elements are taken from \var{iterable}.  The elements
+  must be immutable.  To represent sets of sets, the inner sets should
+  be \class{frozenset} objects.  If \var{iterable} is not specified,
+  returns a new empty set, \code{set([])}.
+  \versionadded{2.4}
+\end{funcdesc}
+
+\begin{funcdesc}{setattr}{object, name, value}
+  This is the counterpart of \function{getattr()}.  The arguments are an
+  object, a string and an arbitrary value.  The string may name an
+  existing attribute or a new attribute.  The function assigns the
+  value to the attribute, provided the object allows it.  For example,
+  \code{setattr(\var{x}, '\var{foobar}', 123)} is equivalent to
+  \code{\var{x}.\var{foobar} = 123}.
+\end{funcdesc}
+
+\begin{funcdesc}{slice}{\optional{start,} stop\optional{, step}}
+  Return a slice object representing the set of indices specified by
+  \code{range(\var{start}, \var{stop}, \var{step})}.  The \var{start}
+  and \var{step} arguments default to \code{None}.  Slice objects have
+  read-only data attributes \member{start}, \member{stop} and
+  \member{step} which merely return the argument values (or their
+  default).  They have no other explicit functionality; however they
+  are used by Numerical Python\index{Numerical Python} and other third
+  party extensions.  Slice objects are also generated when extended
+  indexing syntax is used.  For example: \samp{a[start:stop:step]} or
+  \samp{a[start:stop, i]}.
+\end{funcdesc}
+
+\begin{funcdesc}{sorted}{iterable\optional{, cmp\optional{,
+                         key\optional{, reverse}}}}
+  Return a new sorted list from the items in \var{iterable}.
+
+  The optional arguments \var{cmp}, \var{key}, and \var{reverse} have
+  the same meaning as those for the \method{list.sort()} method
+  (described in section~\ref{typesseq-mutable}).
+
+  \var{cmp} specifies a custom comparison function of two arguments
+  (iterable elements) which should return a negative, zero or positive
+  number depending on whether the first argument is considered smaller
+  than, equal to, or larger than the second argument:
+  \samp{\var{cmp}=\keyword{lambda} \var{x},\var{y}:
+  \function{cmp}(x.lower(), y.lower())}
+     
+  \var{key} specifies a function of one argument that is used to
+     extract a comparison key from each list element:
+     \samp{\var{key}=\function{str.lower}}
+
+  \var{reverse} is a boolean value.  If set to \code{True}, then the
+     list elements are sorted as if each comparison were reversed.
+
+  In general, the \var{key} and \var{reverse} conversion processes are
+  much faster than specifying an equivalent \var{cmp} function.  This is
+  because \var{cmp} is called multiple times for each list element while
+  \var{key} and \var{reverse} touch each element only once.
+
+  \versionadded{2.4}
+\end{funcdesc}
+
+\begin{funcdesc}{staticmethod}{function}
+  Return a static method for \var{function}.
+
+  A static method does not receive an implicit first argument.
+  To declare a static method, use this idiom:
+
+\begin{verbatim}
+class C:
+    @staticmethod
+    def f(arg1, arg2, ...): ...
+\end{verbatim}
+
+  The \code{@staticmethod} form is a function decorator -- see the description
+  of function definitions in chapter 7 of the
+  \citetitle[../ref/function.html]{Python Reference Manual} for details.
+
+  It can be called either on the class (such as \code{C.f()}) or on an
+  instance (such as \code{C().f()}).  The instance is ignored except
+  for its class.
+
+  Static methods in Python are similar to those found in Java or \Cpp.
+  For a more advanced concept, see \function{classmethod()} in this
+  section.
+  
+  For more information on static methods, consult the documentation on the
+  standard type hierarchy in chapter 3 of the
+  \citetitle[../ref/types.html]{Python Reference Manual} (at the bottom).
+  \versionadded{2.2}
+  \versionchanged[Function decorator syntax added]{2.4}
+\end{funcdesc}
+
+\begin{funcdesc}{str}{\optional{object}}
+  Return a string containing a nicely printable representation of an
+  object.  For strings, this returns the string itself.  The
+  difference with \code{repr(\var{object})} is that
+  \code{str(\var{object})} does not always attempt to return a string
+  that is acceptable to \function{eval()}; its goal is to return a
+  printable string.  If no argument is given, returns the empty
+  string, \code{''}.
+\end{funcdesc}
+
+\begin{funcdesc}{sum}{iterable\optional{, start}}
+  Sums \var{start} and the items of an \var{iterable} from left to
+  right and returns the total.  \var{start} defaults to \code{0}.
+  The \var{iterable}'s items are normally numbers, and are not allowed
+  to be strings.  The fast, correct way to concatenate a sequence of
+  strings is by calling \code{''.join(\var{sequence})}.
+  Note that \code{sum(range(\var{n}), \var{m})} is equivalent to
+  \code{reduce(operator.add, range(\var{n}), \var{m})}
+  \versionadded{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{super}{type\optional{, object-or-type}}
+  Return the superclass of \var{type}.  If the second argument is omitted
+  the super object returned is unbound.  If the second argument is an
+  object, \code{isinstance(\var{obj}, \var{type})} must be true.  If
+  the second argument is a type, \code{issubclass(\var{type2},
+  \var{type})} must be true.
+  \function{super()} only works for new-style classes.
+
+  A typical use for calling a cooperative superclass method is:
+\begin{verbatim}
+class C(B):
+    def meth(self, arg):
+        super(C, self).meth(arg)
+\end{verbatim}
+
+  Note that \function{super} is implemented as part of the binding process for
+  explicit dotted attribute lookups such as
+  \samp{super(C, self).__getitem__(name)}.  Accordingly, \function{super} is
+  undefined for implicit lookups using statements or operators such as
+  \samp{super(C, self)[name]}.
+\versionadded{2.2}
+\end{funcdesc}
+
+\begin{funcdesc}{tuple}{\optional{iterable}}
+  Return a tuple whose items are the same and in the same order as
+  \var{iterable}'s items.  \var{iterable} may be a sequence, a
+  container that supports iteration, or an iterator object.
+  If \var{iterable} is already a tuple, it
+  is returned unchanged.  For instance, \code{tuple('abc')} returns
+  \code{('a', 'b', 'c')} and \code{tuple([1, 2, 3])} returns
+  \code{(1, 2, 3)}.  If no argument is given, returns a new empty
+  tuple, \code{()}.
+\end{funcdesc}
+
+\begin{funcdesc}{type}{object}
+  Return the type of an \var{object}.  The return value is a
+  type\obindex{type} object.  The \function{isinstance()} built-in
+  function is recommended for testing the type of an object.
+
+  With three arguments, \function{type} functions as a constructor
+  as detailed below.
+\end{funcdesc}
+
+\begin{funcdesc}{type}{name, bases, dict}
+  Return a new type object.  This is essentially a dynamic form of the
+  \keyword{class} statement. The \var{name} string is the class name
+  and becomes the \member{__name__} attribute; the \var{bases} tuple
+  itemizes the base classes and becomes the \member{__bases__}
+  attribute; and the \var{dict} dictionary is the namespace containing
+  definitions for class body and becomes the \member{__dict__}
+  attribute.  For example, the following two statements create
+  identical \class{type} objects:
+
+\begin{verbatim}
+  >>> class X(object):
+  ...     a = 1
+  ...     
+  >>> X = type('X', (object,), dict(a=1))
+\end{verbatim}
+\versionadded{2.2}          
+\end{funcdesc}
+
+\begin{funcdesc}{unichr}{i}
+  Return the Unicode string of one character whose Unicode code is the
+  integer \var{i}.  For example, \code{unichr(97)} returns the string
+  \code{u'a'}.  This is the inverse of \function{ord()} for Unicode
+  strings.  The valid range for the argument depends how Python was
+  configured -- it may be either UCS2 [0..0xFFFF] or UCS4 [0..0x10FFFF].
+  \exception{ValueError} is raised otherwise.
+  \versionadded{2.0}
+\end{funcdesc}
+
+\begin{funcdesc}{unicode}{\optional{object\optional{, encoding
+				    \optional{, errors}}}}
+  Return the Unicode string version of \var{object} using one of the
+  following modes:
+
+  If \var{encoding} and/or \var{errors} are given, \code{unicode()}
+  will decode the object which can either be an 8-bit string or a
+  character buffer using the codec for \var{encoding}. The
+  \var{encoding} parameter is a string giving the name of an encoding;
+  if the encoding is not known, \exception{LookupError} is raised.
+  Error handling is done according to \var{errors}; this specifies the
+  treatment of characters which are invalid in the input encoding.  If
+  \var{errors} is \code{'strict'} (the default), a
+  \exception{ValueError} is raised on errors, while a value of
+  \code{'ignore'} causes errors to be silently ignored, and a value of
+  \code{'replace'} causes the official Unicode replacement character,
+  \code{U+FFFD}, to be used to replace input characters which cannot
+  be decoded.  See also the \refmodule{codecs} module.
+
+  If no optional parameters are given, \code{unicode()} will mimic the
+  behaviour of \code{str()} except that it returns Unicode strings
+  instead of 8-bit strings. More precisely, if \var{object} is a
+  Unicode string or subclass it will return that Unicode string without
+  any additional decoding applied.
+
+  For objects which provide a \method{__unicode__()} method, it will
+  call this method without arguments to create a Unicode string. For
+  all other objects, the 8-bit string version or representation is
+  requested and then converted to a Unicode string using the codec for
+  the default encoding in \code{'strict'} mode.
+
+  \versionadded{2.0}
+  \versionchanged[Support for \method{__unicode__()} added]{2.2}
+\end{funcdesc}
+
+\begin{funcdesc}{vars}{\optional{object}}
+  Without arguments, return a dictionary corresponding to the current
+  local symbol table.  With a module, class or class instance object
+  as argument (or anything else that has a \member{__dict__}
+  attribute), returns a dictionary corresponding to the object's
+  symbol table.  The returned dictionary should not be modified: the
+  effects on the corresponding symbol table are undefined.\footnote{
+    In the current implementation, local variable bindings cannot
+    normally be affected this way, but variables retrieved from
+    other scopes (such as modules) can be.  This may change.}
+\end{funcdesc}
+
+\begin{funcdesc}{xrange}{\optional{start,} stop\optional{, step}}
+  This function is very similar to \function{range()}, but returns an
+  ``xrange object'' instead of a list.  This is an opaque sequence
+  type which yields the same values as the corresponding list, without
+  actually storing them all simultaneously.  The advantage of
+  \function{xrange()} over \function{range()} is minimal (since
+  \function{xrange()} still has to create the values when asked for
+  them) except when a very large range is used on a memory-starved
+  machine or when all of the range's elements are never used (such as
+  when the loop is usually terminated with \keyword{break}).
+
+  \note{\function{xrange()} is intended to be simple and fast.
+        Implementations may impose restrictions to achieve this.
+        The C implementation of Python restricts all arguments to
+        native C longs ("short" Python integers), and also requires
+        that the number of elements fit in a native C long.}
+\end{funcdesc}
+
+\begin{funcdesc}{zip}{\optional{iterable, \moreargs}}
+  This function returns a list of tuples, where the \var{i}-th tuple contains
+  the \var{i}-th element from each of the argument sequences or iterables.
+  The returned list is truncated in length to the length of
+  the shortest argument sequence.  When there are multiple arguments
+  which are all of the same length, \function{zip()} is
+  similar to \function{map()} with an initial argument of \code{None}.
+  With a single sequence argument, it returns a list of 1-tuples.
+  With no arguments, it returns an empty list.
+  \versionadded{2.0}
+
+  \versionchanged[Formerly, \function{zip()} required at least one argument
+  and \code{zip()} raised a \exception{TypeError} instead of returning
+  an empty list]{2.4}
+\end{funcdesc}
+
+
+% ---------------------------------------------------------------------------
+
+
+\section{Non-essential Built-in Functions \label{non-essential-built-in-funcs}}
+
+There are several built-in functions that are no longer essential to learn,
+know or use in modern Python programming.  They have been kept here to
+maintain backwards compatibility with programs written for older versions
+of Python.
+
+Python programmers, trainers, students and bookwriters should feel free to
+bypass these functions without concerns about missing something important.
+
+
+\setindexsubitem{(non-essential built-in functions)}
+
+\begin{funcdesc}{apply}{function, args\optional{, keywords}}
+  The \var{function} argument must be a callable object (a
+  user-defined or built-in function or method, or a class object) and
+  the \var{args} argument must be a sequence.  The \var{function} is
+  called with \var{args} as the argument list; the number of arguments
+  is the length of the tuple.
+  If the optional \var{keywords} argument is present, it must be a
+  dictionary whose keys are strings.  It specifies keyword arguments
+  to be added to the end of the argument list.
+  Calling \function{apply()} is different from just calling
+  \code{\var{function}(\var{args})}, since in that case there is always
+  exactly one argument.  The use of \function{apply()} is equivalent
+  to \code{\var{function}(*\var{args}, **\var{keywords})}.
+  Use of \function{apply()} is not necessary since the ``extended call
+  syntax,'' as used in the last example, is completely equivalent.
+
+  \deprecated{2.3}{Use the extended call syntax instead, as described
+                   above.}
+\end{funcdesc}
+
+\begin{funcdesc}{buffer}{object\optional{, offset\optional{, size}}}
+  The \var{object} argument must be an object that supports the buffer
+  call interface (such as strings, arrays, and buffers).  A new buffer
+  object will be created which references the \var{object} argument.
+  The buffer object will be a slice from the beginning of \var{object}
+  (or from the specified \var{offset}). The slice will extend to the
+  end of \var{object} (or will have a length given by the \var{size}
+  argument).
+\end{funcdesc}
+
+\begin{funcdesc}{coerce}{x, y}
+  Return a tuple consisting of the two numeric arguments converted to
+  a common type, using the same rules as used by arithmetic
+  operations. If coercion is not possible, raise \exception{TypeError}.
+\end{funcdesc}
+
+\begin{funcdesc}{intern}{string}
+  Enter \var{string} in the table of ``interned'' strings and return
+  the interned string -- which is \var{string} itself or a copy.
+  Interning strings is useful to gain a little performance on
+  dictionary lookup -- if the keys in a dictionary are interned, and
+  the lookup key is interned, the key comparisons (after hashing) can
+  be done by a pointer compare instead of a string compare.  Normally,
+  the names used in Python programs are automatically interned, and
+  the dictionaries used to hold module, class or instance attributes
+  have interned keys.  \versionchanged[Interned strings are not
+  immortal (like they used to be in Python 2.2 and before);
+  you must keep a reference to the return value of \function{intern()}
+  around to benefit from it]{2.3}
+\end{funcdesc}

Added: vendor/Python/current/Doc/lib/libfunctools.tex
===================================================================
--- vendor/Python/current/Doc/lib/libfunctools.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libfunctools.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,132 @@
+\section{\module{functools} ---
+         Higher order functions and operations on callable objects.}
+
+\declaremodule{standard}{functools}		% standard library, in Python
+
+\moduleauthor{Peter Harris}{scav at blueyonder.co.uk}
+\moduleauthor{Raymond Hettinger}{python at rcn.com}
+\moduleauthor{Nick Coghlan}{ncoghlan at gmail.com}
+\sectionauthor{Peter Harris}{scav at blueyonder.co.uk}
+
+\modulesynopsis{Higher-order functions and operations on callable objects.}
+
+\versionadded{2.5}
+
+The \module{functools} module is for higher-order functions: functions
+that act on or return other functions. In general, any callable object can
+be treated as a function for the purposes of this module.
+
+
+The \module{functools} module defines the following function:
+
+\begin{funcdesc}{partial}{func\optional{,*args}\optional{, **keywords}}
+Return a new \class{partial} object which when called will behave like
+\var{func} called with the positional arguments \var{args} and keyword
+arguments \var{keywords}. If more arguments are supplied to the call, they
+are appended to \var{args}. If additional keyword arguments are supplied,
+they extend and override \var{keywords}. Roughly equivalent to:
+  \begin{verbatim}
+        def partial(func, *args, **keywords):
+            def newfunc(*fargs, **fkeywords):
+                newkeywords = keywords.copy()
+                newkeywords.update(fkeywords)
+                return func(*(args + fargs), **newkeywords)
+            newfunc.func = func
+            newfunc.args = args
+            newfunc.keywords = keywords
+            return newfunc
+  \end{verbatim}
+
+The \function{partial} is used for partial function application which
+``freezes'' some portion of a function's arguments and/or keywords
+resulting in a new object with a simplified signature.  For example,
+\function{partial} can be used to create a callable that behaves like
+the \function{int} function where the \var{base} argument defaults to
+two:
+  \begin{verbatim}
+        >>> basetwo = partial(int, base=2)
+        >>> basetwo.__doc__ = 'Convert base 2 string to an int.'
+        >>> basetwo('10010')
+        18
+  \end{verbatim}
+\end{funcdesc}
+
+\begin{funcdesc}{update_wrapper}
+{wrapper, wrapped\optional{, assigned}\optional{, updated}}
+Update a \var{wrapper} function to look like the \var{wrapped} function.
+The optional arguments are tuples to specify which attributes of the original
+function are assigned directly to the matching attributes on the wrapper
+function and which attributes of the wrapper function are updated with
+the corresponding attributes from the original function. The default
+values for these arguments are the module level constants
+\var{WRAPPER_ASSIGNMENTS} (which assigns to the wrapper function's
+\var{__name__}, \var{__module__} and \var{__doc__}, the documentation string)
+and \var{WRAPPER_UPDATES} (which updates the wrapper function's \var{__dict__},
+i.e. the instance dictionary).
+
+The main intended use for this function is in decorator functions
+which wrap the decorated function and return the wrapper. If the
+wrapper function is not updated, the metadata of the returned function
+will reflect the wrapper definition rather than the original function
+definition, which is typically less than helpful.
+\end{funcdesc}
+
+\begin{funcdesc}{wraps}
+{wrapped\optional{, assigned}\optional{, updated}}
+This is a convenience function for invoking
+\code{partial(update_wrapper, wrapped=wrapped, assigned=assigned, updated=updated)}
+as a function decorator when defining a wrapper function. For example:
+  \begin{verbatim}
+        >>> def my_decorator(f):
+        ...     @wraps(f)
+        ...     def wrapper(*args, **kwds):
+        ...         print 'Calling decorated function'
+        ...         return f(*args, **kwds)
+        ...     return wrapper
+        ...
+        >>> @my_decorator
+        ... def example():
+	...     """Docstring"""
+        ...     print 'Called example function'
+        ...
+        >>> example()
+        Calling decorated function
+        Called example function
+        >>> example.__name__
+        'example'
+	>>> example.__doc__
+	'Docstring'
+  \end{verbatim}
+Without the use of this decorator factory, the name of the example
+function would have been \code{'wrapper'}, and the docstring of the
+original \function{example()} would have been lost.
+\end{funcdesc}
+
+
+\subsection{\class{partial} Objects \label{partial-objects}}
+
+
+\class{partial} objects are callable objects created by \function{partial()}.
+They have three read-only attributes:
+
+\begin{memberdesc}[callable]{func}{}
+A callable object or function.  Calls to the \class{partial} object will
+be forwarded to \member{func} with new arguments and keywords.
+\end{memberdesc}
+
+\begin{memberdesc}[tuple]{args}{}
+The leftmost positional arguments that will be prepended to the
+positional arguments provided to a \class{partial} object call.
+\end{memberdesc}
+
+\begin{memberdesc}[dict]{keywords}{}
+The keyword arguments that will be supplied when the \class{partial} object
+is called.
+\end{memberdesc}
+
+\class{partial} objects are like \class{function} objects in that they are
+callable, weak referencable, and can have attributes.  There are some
+important differences.  For instance, the \member{__name__} and
+\member{__doc__} attributes are not created automatically.  Also,
+\class{partial} objects defined in classes behave like static methods and
+do not transform into bound methods during instance attribute look-up.

Added: vendor/Python/current/Doc/lib/libfuture.tex
===================================================================
--- vendor/Python/current/Doc/lib/libfuture.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libfuture.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,69 @@
+\section{\module{__future__} ---
+         Future statement definitions}
+
+\declaremodule[future]{standard}{__future__}
+\modulesynopsis{Future statement definitions}
+
+\module{__future__} is a real module, and serves three purposes:
+
+\begin{itemize}
+
+\item To avoid confusing existing tools that analyze import statements
+      and expect to find the modules they're importing.
+
+\item To ensure that future_statements run under releases prior to 2.1
+      at least yield runtime exceptions (the import of
+      \module{__future__} will fail, because there was no module of
+      that name prior to 2.1). 
+
+\item To document when incompatible changes were introduced, and when they
+      will be --- or were --- made mandatory.  This is a form of executable
+      documentation, and can be inspected programatically via importing
+      \module{__future__} and examining its contents.
+
+\end{itemize}
+
+Each statement in \file{__future__.py} is of the form:
+
+\begin{alltt}
+FeatureName = "_Feature(" \var{OptionalRelease} "," \var{MandatoryRelease} ","
+                        \var{CompilerFlag} ")"
+\end{alltt}
+
+where, normally, \var{OptionalRelease} is less than
+\var{MandatoryRelease}, and both are 5-tuples of the same form as
+\code{sys.version_info}:
+
+\begin{verbatim}
+    (PY_MAJOR_VERSION, # the 2 in 2.1.0a3; an int
+     PY_MINOR_VERSION, # the 1; an int
+     PY_MICRO_VERSION, # the 0; an int
+     PY_RELEASE_LEVEL, # "alpha", "beta", "candidate" or "final"; string
+     PY_RELEASE_SERIAL # the 3; an int
+    )
+\end{verbatim}
+
+\var{OptionalRelease} records the first release in which the feature
+was accepted.
+
+In the case of a \var{MandatoryRelease} that has not yet occurred,
+\var{MandatoryRelease} predicts the release in which the feature will
+become part of the language.
+
+Else \var{MandatoryRelease} records when the feature became part of
+the language; in releases at or after that, modules no longer need a
+future statement to use the feature in question, but may continue to
+use such imports.
+
+\var{MandatoryRelease} may also be \code{None}, meaning that a planned
+feature got dropped.
+
+Instances of class \class{_Feature} have two corresponding methods,
+\method{getOptionalRelease()} and \method{getMandatoryRelease()}.
+
+\var{CompilerFlag} is the (bitfield) flag that should be passed in the
+fourth argument to the builtin function \function{compile()} to enable
+the feature in dynamically compiled code.  This flag is stored in the
+\member{compiler_flag} attribute on \class{_Feature} instances.
+
+No feature description will ever be deleted from \module{__future__}.

Added: vendor/Python/current/Doc/lib/libgc.tex
===================================================================
--- vendor/Python/current/Doc/lib/libgc.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libgc.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,196 @@
+\section{\module{gc} ---
+         Garbage Collector interface}
+
+\declaremodule{extension}{gc}
+\modulesynopsis{Interface to the cycle-detecting garbage collector.}
+\moduleauthor{Neil Schemenauer}{nas at arctrix.com}
+\sectionauthor{Neil Schemenauer}{nas at arctrix.com}
+
+This module provides an interface to the optional garbage collector.  It
+provides the ability to disable the collector, tune the collection
+frequency, and set debugging options.  It also provides access to
+unreachable objects that the collector found but cannot free.  Since the
+collector supplements the reference counting already used in Python, you
+can disable the collector if you are sure your program does not create
+reference cycles.  Automatic collection can be disabled by calling
+\code{gc.disable()}.  To debug a leaking program call
+\code{gc.set_debug(gc.DEBUG_LEAK)}. Notice that this includes 
+\code{gc.DEBUG_SAVEALL}, causing garbage-collected objects to be
+saved in gc.garbage for inspection.
+
+The \module{gc} module provides the following functions:
+
+\begin{funcdesc}{enable}{}
+Enable automatic garbage collection.
+\end{funcdesc}
+
+\begin{funcdesc}{disable}{}
+Disable automatic garbage collection.
+\end{funcdesc}
+
+\begin{funcdesc}{isenabled}{}
+Returns true if automatic collection is enabled.
+\end{funcdesc}
+
+\begin{funcdesc}{collect}{\optional{generation}}
+With no arguments, run a full collection.  The optional argument
+\var{generation} may be an integer specifying which generation to collect
+(from 0 to 2).  A \exception{ValueError} is raised if the generation number 
+is invalid.
+The number of unreachable objects found is returned.
+
+\versionchanged[The optional \var{generation} argument was added]{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{set_debug}{flags}
+Set the garbage collection debugging flags.
+Debugging information will be written to \code{sys.stderr}.  See below
+for a list of debugging flags which can be combined using bit
+operations to control debugging.
+\end{funcdesc}
+
+\begin{funcdesc}{get_debug}{}
+Return the debugging flags currently set.
+\end{funcdesc}
+
+\begin{funcdesc}{get_objects}{}
+Returns a list of all objects tracked by the collector, excluding the
+list returned.
+\versionadded{2.2}
+\end{funcdesc}
+
+\begin{funcdesc}{set_threshold}{threshold0\optional{,
+                                threshold1\optional{, threshold2}}}
+Set the garbage collection thresholds (the collection frequency).
+Setting \var{threshold0} to zero disables collection.
+
+The GC classifies objects into three generations depending on how many
+collection sweeps they have survived.  New objects are placed in the
+youngest generation (generation \code{0}).  If an object survives a
+collection it is moved into the next older generation.  Since
+generation \code{2} is the oldest generation, objects in that
+generation remain there after a collection.  In order to decide when
+to run, the collector keeps track of the number object allocations and
+deallocations since the last collection.  When the number of
+allocations minus the number of deallocations exceeds
+\var{threshold0}, collection starts.  Initially only generation
+\code{0} is examined.  If generation \code{0} has been examined more
+than \var{threshold1} times since generation \code{1} has been
+examined, then generation \code{1} is examined as well.  Similarly,
+\var{threshold2} controls the number of collections of generation
+\code{1} before collecting generation \code{2}.
+\end{funcdesc}
+
+\begin{funcdesc}{get_count}{}
+Return the current collection  counts as a tuple of
+\code{(\var{count0}, \var{count1}, \var{count2})}.
+\versionadded{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{get_threshold}{}
+Return the current collection thresholds as a tuple of
+\code{(\var{threshold0}, \var{threshold1}, \var{threshold2})}.
+\end{funcdesc}
+
+\begin{funcdesc}{get_referrers}{*objs}
+Return the list of objects that directly refer to any of objs. This
+function will only locate those containers which support garbage
+collection; extension types which do refer to other objects but do not
+support garbage collection will not be found.
+
+Note that objects which have already been dereferenced, but which live
+in cycles and have not yet been collected by the garbage collector can
+be listed among the resulting referrers.  To get only currently live
+objects, call \function{collect()} before calling
+\function{get_referrers()}.
+
+Care must be taken when using objects returned by
+\function{get_referrers()} because some of them could still be under
+construction and hence in a temporarily invalid state. Avoid using
+\function{get_referrers()} for any purpose other than debugging.
+
+\versionadded{2.2}
+\end{funcdesc}
+
+\begin{funcdesc}{get_referents}{*objs}
+Return a list of objects directly referred to by any of the arguments.
+The referents returned are those objects visited by the arguments'
+C-level \member{tp_traverse} methods (if any), and may not be all
+objects actually directly reachable.  \member{tp_traverse} methods
+are supported only by objects that support garbage collection, and are
+only required to visit objects that may be involved in a cycle.  So,
+for example, if an integer is directly reachable from an argument, that
+integer object may or may not appear in the result list.
+
+\versionadded{2.3}
+\end{funcdesc}
+
+The following variable is provided for read-only access (you can
+mutate its value but should not rebind it):
+
+\begin{datadesc}{garbage}
+A list of objects which the collector found to be unreachable
+but could not be freed (uncollectable objects).  By default, this list
+contains only objects with \method{__del__()} methods.\footnote{Prior to
+  Python 2.2, the list contained all instance objects in unreachable
+  cycles,  not only those with \method{__del__()} methods.}
+Objects that have
+\method{__del__()} methods and are part of a reference cycle cause
+the entire reference cycle to be uncollectable, including objects
+not necessarily in the cycle but reachable only from it.  Python doesn't
+collect such cycles automatically because, in general, it isn't possible
+for Python to guess a safe order in which to run the \method{__del__()}
+methods.  If you know a safe order, you can force the issue by examining
+the \var{garbage} list, and explicitly breaking cycles due to your
+objects within the list.  Note that these objects are kept alive even
+so by virtue of being in the \var{garbage} list, so they should be
+removed from \var{garbage} too.  For example, after breaking cycles, do
+\code{del gc.garbage[:]} to empty the list.  It's generally better
+to avoid the issue by not creating cycles containing objects with
+\method{__del__()} methods, and \var{garbage} can be examined in that
+case to verify that no such cycles are being created.
+
+If \constant{DEBUG_SAVEALL} is set, then all unreachable objects will
+be added to this list rather than freed.
+\end{datadesc}
+
+
+The following constants are provided for use with
+\function{set_debug()}:
+
+\begin{datadesc}{DEBUG_STATS}
+Print statistics during collection.  This information can
+be useful when tuning the collection frequency.
+\end{datadesc}
+
+\begin{datadesc}{DEBUG_COLLECTABLE}
+Print information on collectable objects found.
+\end{datadesc}
+
+\begin{datadesc}{DEBUG_UNCOLLECTABLE}
+Print information of uncollectable objects found (objects which are
+not reachable but cannot be freed by the collector).  These objects
+will be added to the \code{garbage} list.
+\end{datadesc}
+
+\begin{datadesc}{DEBUG_INSTANCES}
+When \constant{DEBUG_COLLECTABLE} or \constant{DEBUG_UNCOLLECTABLE} is
+set, print information about instance objects found.
+\end{datadesc}
+
+\begin{datadesc}{DEBUG_OBJECTS}
+When \constant{DEBUG_COLLECTABLE} or \constant{DEBUG_UNCOLLECTABLE} is
+set, print information about objects other than instance objects found.
+\end{datadesc}
+
+\begin{datadesc}{DEBUG_SAVEALL}
+When set, all unreachable objects found will be appended to
+\var{garbage} rather than being freed.  This can be useful for debugging
+a leaking program.
+\end{datadesc}
+
+\begin{datadesc}{DEBUG_LEAK}
+The debugging flags necessary for the collector to print
+information about a leaking program (equal to \code{DEBUG_COLLECTABLE |
+DEBUG_UNCOLLECTABLE | DEBUG_INSTANCES | DEBUG_OBJECTS | DEBUG_SAVEALL}).
+\end{datadesc}

Added: vendor/Python/current/Doc/lib/libgdbm.tex
===================================================================
--- vendor/Python/current/Doc/lib/libgdbm.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libgdbm.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,100 @@
+\section{\module{gdbm} ---
+         GNU's reinterpretation of dbm}
+
+\declaremodule{builtin}{gdbm}
+  \platform{Unix}
+\modulesynopsis{GNU's reinterpretation of dbm.}
+
+
+This module is quite similar to the \refmodule{dbm}\refbimodindex{dbm}
+module, but uses \code{gdbm} instead to provide some additional
+functionality.  Please note that the file formats created by
+\code{gdbm} and \code{dbm} are incompatible.
+
+The \module{gdbm} module provides an interface to the GNU DBM
+library.  \code{gdbm} objects behave like mappings
+(dictionaries), except that keys and values are always strings.
+Printing a \code{gdbm} object doesn't print the keys and values, and
+the \method{items()} and \method{values()} methods are not supported.
+
+The module defines the following constant and functions:
+
+\begin{excdesc}{error}
+Raised on \code{gdbm}-specific errors, such as I/O errors.
+\exception{KeyError} is raised for general mapping errors like
+specifying an incorrect key.
+\end{excdesc}
+
+\begin{funcdesc}{open}{filename, \optional{flag, \optional{mode}}}
+Open a \code{gdbm} database and return a \code{gdbm} object.  The
+\var{filename} argument is the name of the database file.
+
+The optional \var{flag} argument can be
+\code{'r'} (to open an existing database for reading only --- default),
+\code{'w'} (to open an existing database for reading and writing),
+\code{'c'} (which creates the database if it doesn't exist), or
+\code{'n'} (which always creates a new empty database).
+
+The following additional characters may be appended to the flag to
+control how the database is opened:
+
+\begin{itemize}
+\item \code{'f'} --- Open the database in fast mode.  Writes to the database
+                     will not be synchronized.
+\item \code{'s'} --- Synchronized mode. This will cause changes to the database
+                     will be immediately written to the file.
+\item \code{'u'} --- Do not lock database. 
+\end{itemize}
+
+Not all flags are valid for all versions of \code{gdbm}.  The
+module constant \code{open_flags} is a string of supported flag
+characters.  The exception \exception{error} is raised if an invalid
+flag is specified.
+
+The optional \var{mode} argument is the \UNIX{} mode of the file, used
+only when the database has to be created.  It defaults to octal
+\code{0666}.
+\end{funcdesc}
+
+In addition to the dictionary-like methods, \code{gdbm} objects have the
+following methods:
+
+\begin{funcdesc}{firstkey}{}
+It's possible to loop over every key in the database using this method 
+and the \method{nextkey()} method.  The traversal is ordered by
+\code{gdbm}'s internal hash values, and won't be sorted by the key
+values.  This method returns the starting key.
+\end{funcdesc}
+
+\begin{funcdesc}{nextkey}{key}
+Returns the key that follows \var{key} in the traversal.  The
+following code prints every key in the database \code{db}, without
+having to create a list in memory that contains them all:
+
+\begin{verbatim}
+k = db.firstkey()
+while k != None:
+    print k
+    k = db.nextkey(k)
+\end{verbatim}
+\end{funcdesc}
+
+\begin{funcdesc}{reorganize}{}
+If you have carried out a lot of deletions and would like to shrink
+the space used by the \code{gdbm} file, this routine will reorganize
+the database.  \code{gdbm} will not shorten the length of a database
+file except by using this reorganization; otherwise, deleted file
+space will be kept and reused as new (key, value) pairs are added.
+\end{funcdesc}
+
+\begin{funcdesc}{sync}{}
+When the database has been opened in fast mode, this method forces any 
+unwritten data to be written to the disk.
+\end{funcdesc}
+
+
+\begin{seealso}
+  \seemodule{anydbm}{Generic interface to \code{dbm}-style databases.}
+  \seemodule{whichdb}{Utility module used to determine the type of an
+                      existing database.}
+\end{seealso}

Added: vendor/Python/current/Doc/lib/libgetopt.tex
===================================================================
--- vendor/Python/current/Doc/lib/libgetopt.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libgetopt.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,154 @@
+\section{\module{getopt} ---
+         Parser for command line options}
+
+\declaremodule{standard}{getopt}
+\modulesynopsis{Portable parser for command line options; support both
+                short and long option names.}
+
+
+This module helps scripts to parse the command line arguments in
+\code{sys.argv}.
+It supports the same conventions as the \UNIX{} \cfunction{getopt()}
+function (including the special meanings of arguments of the form
+`\code{-}' and `\code{-}\code{-}').
+% That's to fool latex2html into leaving the two hyphens alone!
+Long options similar to those supported by
+GNU software may be used as well via an optional third argument.
+This module provides a single function and an exception:
+
+\begin{funcdesc}{getopt}{args, options\optional{, long_options}}
+Parses command line options and parameter list.  \var{args} is the
+argument list to be parsed, without the leading reference to the
+running program. Typically, this means \samp{sys.argv[1:]}.
+\var{options} is the string of option letters that the script wants to
+recognize, with options that require an argument followed by a colon
+(\character{:}; i.e., the same format that \UNIX{}
+\cfunction{getopt()} uses).
+
+\note{Unlike GNU \cfunction{getopt()}, after a non-option
+argument, all further arguments are considered also non-options.
+This is similar to the way non-GNU \UNIX{} systems work.}
+
+\var{long_options}, if specified, must be a list of strings with the
+names of the long options which should be supported.  The leading
+\code{'-}\code{-'} characters should not be included in the option
+name.  Long options which require an argument should be followed by an
+equal sign (\character{=}).  To accept only long options,
+\var{options} should be an empty string.  Long options on the command
+line can be recognized so long as they provide a prefix of the option
+name that matches exactly one of the accepted options.  For example,
+if \var{long_options} is \code{['foo', 'frob']}, the option
+\longprogramopt{fo} will match as \longprogramopt{foo}, but
+\longprogramopt{f} will not match uniquely, so \exception{GetoptError}
+will be raised.
+
+The return value consists of two elements: the first is a list of
+\code{(\var{option}, \var{value})} pairs; the second is the list of
+program arguments left after the option list was stripped (this is a
+trailing slice of \var{args}).  Each option-and-value pair returned
+has the option as its first element, prefixed with a hyphen for short
+options (e.g., \code{'-x'}) or two hyphens for long options (e.g.,
+\code{'-}\code{-long-option'}), and the option argument as its second
+element, or an empty string if the option has no argument.  The
+options occur in the list in the same order in which they were found,
+thus allowing multiple occurrences.  Long and short options may be
+mixed.
+\end{funcdesc}
+
+\begin{funcdesc}{gnu_getopt}{args, options\optional{, long_options}}
+This function works like \function{getopt()}, except that GNU style
+scanning mode is used by default. This means that option and
+non-option arguments may be intermixed. The \function{getopt()}
+function stops processing options as soon as a non-option argument is
+encountered.
+
+If the first character of the option string is `+', or if the
+environment variable POSIXLY_CORRECT is set, then option processing
+stops as soon as a non-option argument is encountered.
+
+\versionadded{2.3}
+\end{funcdesc}
+
+\begin{excdesc}{GetoptError}
+This is raised when an unrecognized option is found in the argument
+list or when an option requiring an argument is given none.
+The argument to the exception is a string indicating the cause of the
+error.  For long options, an argument given to an option which does
+not require one will also cause this exception to be raised.  The
+attributes \member{msg} and \member{opt} give the error message and
+related option; if there is no specific option to which the exception
+relates, \member{opt} is an empty string.
+
+\versionchanged[Introduced \exception{GetoptError} as a synonym for
+                \exception{error}]{1.6}
+\end{excdesc}
+
+\begin{excdesc}{error}
+Alias for \exception{GetoptError}; for backward compatibility.
+\end{excdesc}
+
+
+An example using only \UNIX{} style options:
+
+\begin{verbatim}
+>>> import getopt
+>>> args = '-a -b -cfoo -d bar a1 a2'.split()
+>>> args
+['-a', '-b', '-cfoo', '-d', 'bar', 'a1', 'a2']
+>>> optlist, args = getopt.getopt(args, 'abc:d:')
+>>> optlist
+[('-a', ''), ('-b', ''), ('-c', 'foo'), ('-d', 'bar')]
+>>> args
+['a1', 'a2']
+\end{verbatim}
+
+Using long option names is equally easy:
+
+\begin{verbatim}
+>>> s = '--condition=foo --testing --output-file abc.def -x a1 a2'
+>>> args = s.split()
+>>> args
+['--condition=foo', '--testing', '--output-file', 'abc.def', '-x', 'a1', 'a2']
+>>> optlist, args = getopt.getopt(args, 'x', [
+...     'condition=', 'output-file=', 'testing'])
+>>> optlist
+[('--condition', 'foo'), ('--testing', ''), ('--output-file', 'abc.def'), ('-x',
+ '')]
+>>> args
+['a1', 'a2']
+\end{verbatim}
+
+In a script, typical usage is something like this:
+
+\begin{verbatim}
+import getopt, sys
+
+def main():
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], "ho:v", ["help", "output="])
+    except getopt.GetoptError, err:
+        # print help information and exit:
+        print str(err) # will print something like "option -a not recognized"
+        usage()
+        sys.exit(2)
+    output = None
+    verbose = False
+    for o, a in opts:
+        if o == "-v":
+            verbose = True
+        elif o in ("-h", "--help"):
+            usage()
+            sys.exit()
+        elif o in ("-o", "--output"):
+            output = a
+        else:
+            assert False, "unhandled option"
+    # ...
+
+if __name__ == "__main__":
+    main()
+\end{verbatim}
+
+\begin{seealso}
+  \seemodule{optparse}{More object-oriented command line option parsing.}
+\end{seealso}

Added: vendor/Python/current/Doc/lib/libgetpass.tex
===================================================================
--- vendor/Python/current/Doc/lib/libgetpass.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libgetpass.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,36 @@
+\section{\module{getpass}
+         --- Portable password input}
+
+\declaremodule{standard}{getpass}
+\modulesynopsis{Portable reading of passwords and retrieval of the userid.}
+\moduleauthor{Piers Lauder}{piers at cs.su.oz.au}
+% Windows (& Mac?) support by Guido van Rossum.
+\sectionauthor{Fred L. Drake, Jr.}{fdrake at acm.org}
+
+
+The \module{getpass} module provides two functions:
+
+
+\begin{funcdesc}{getpass}{\optional{prompt\optional{, stream}}}
+  Prompt the user for a password without echoing.  The user is
+  prompted using the string \var{prompt}, which defaults to
+  \code{'Password: '}. On \UNIX, the prompt is written to the
+  file-like object \var{stream}, which defaults to
+  \code{sys.stdout} (this argument is ignored on Windows).
+
+  Availability: Macintosh, \UNIX, Windows.
+  \versionchanged[The \var{stream} parameter was added]{2.5}
+\end{funcdesc}
+
+
+\begin{funcdesc}{getuser}{}
+  Return the ``login name'' of the user.
+  Availability: \UNIX, Windows.
+
+  This function checks the environment variables \envvar{LOGNAME},
+  \envvar{USER}, \envvar{LNAME} and \envvar{USERNAME}, in order, and
+  returns the value of the first one which is set to a non-empty
+  string.  If none are set, the login name from the password database
+  is returned on systems which support the \refmodule{pwd} module,
+  otherwise, an exception is raised.
+\end{funcdesc}

Added: vendor/Python/current/Doc/lib/libgettext.tex
===================================================================
--- vendor/Python/current/Doc/lib/libgettext.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libgettext.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,773 @@
+\section{\module{gettext} ---
+         Multilingual internationalization services}
+
+\declaremodule{standard}{gettext}
+\modulesynopsis{Multilingual internationalization services.}
+\moduleauthor{Barry A. Warsaw}{barry at zope.com}
+\sectionauthor{Barry A. Warsaw}{barry at zope.com}
+
+
+The \module{gettext} module provides internationalization (I18N) and
+localization (L10N) services for your Python modules and applications.
+It supports both the GNU \code{gettext} message catalog API and a
+higher level, class-based API that may be more appropriate for Python
+files.  The interface described below allows you to write your
+module and application messages in one natural language, and provide a
+catalog of translated messages for running under different natural
+languages.
+
+Some hints on localizing your Python modules and applications are also
+given.
+
+\subsection{GNU \program{gettext} API}
+
+The \module{gettext} module defines the following API, which is very
+similar to the GNU \program{gettext} API.  If you use this API you
+will affect the translation of your entire application globally.  Often
+this is what you want if your application is monolingual, with the choice
+of language dependent on the locale of your user.  If you are
+localizing a Python module, or if your application needs to switch
+languages on the fly, you probably want to use the class-based API
+instead.
+
+\begin{funcdesc}{bindtextdomain}{domain\optional{, localedir}}
+Bind the \var{domain} to the locale directory
+\var{localedir}.  More concretely, \module{gettext} will look for
+binary \file{.mo} files for the given domain using the path (on \UNIX):
+\file{\var{localedir}/\var{language}/LC_MESSAGES/\var{domain}.mo},
+where \var{languages} is searched for in the environment variables
+\envvar{LANGUAGE}, \envvar{LC_ALL}, \envvar{LC_MESSAGES}, and
+\envvar{LANG} respectively.
+
+If \var{localedir} is omitted or \code{None}, then the current binding
+for \var{domain} is returned.\footnote{
+        The default locale directory is system dependent; for example,
+        on RedHat Linux it is \file{/usr/share/locale}, but on Solaris
+        it is \file{/usr/lib/locale}.  The \module{gettext} module
+        does not try to support these system dependent defaults;
+        instead its default is \file{\code{sys.prefix}/share/locale}.
+        For this reason, it is always best to call
+        \function{bindtextdomain()} with an explicit absolute path at
+        the start of your application.}
+\end{funcdesc}
+
+\begin{funcdesc}{bind_textdomain_codeset}{domain\optional{, codeset}}
+Bind the \var{domain} to \var{codeset}, changing the encoding of
+strings returned by the \function{gettext()} family of functions.
+If \var{codeset} is omitted, then the current binding is returned.
+
+\versionadded{2.4}
+\end{funcdesc}
+
+\begin{funcdesc}{textdomain}{\optional{domain}}
+Change or query the current global domain.  If \var{domain} is
+\code{None}, then the current global domain is returned, otherwise the
+global domain is set to \var{domain}, which is returned.
+\end{funcdesc}
+
+\begin{funcdesc}{gettext}{message}
+Return the localized translation of \var{message}, based on the
+current global domain, language, and locale directory.  This function
+is usually aliased as \function{_} in the local namespace (see
+examples below).
+\end{funcdesc}
+
+\begin{funcdesc}{lgettext}{message}
+Equivalent to \function{gettext()}, but the translation is returned
+in the preferred system encoding, if no other encoding was explicitly
+set with \function{bind_textdomain_codeset()}.
+
+\versionadded{2.4}
+\end{funcdesc}
+
+\begin{funcdesc}{dgettext}{domain, message}
+Like \function{gettext()}, but look the message up in the specified
+\var{domain}.
+\end{funcdesc}
+
+\begin{funcdesc}{ldgettext}{domain, message}
+Equivalent to \function{dgettext()}, but the translation is returned
+in the preferred system encoding, if no other encoding was explicitly
+set with \function{bind_textdomain_codeset()}.
+
+\versionadded{2.4}
+\end{funcdesc}
+
+\begin{funcdesc}{ngettext}{singular, plural, n}
+
+Like \function{gettext()}, but consider plural forms. If a translation
+is found, apply the plural formula to \var{n}, and return the
+resulting message (some languages have more than two plural forms).
+If no translation is found, return \var{singular} if \var{n} is 1;
+return \var{plural} otherwise.
+
+The Plural formula is taken from the catalog header. It is a C or
+Python expression that has a free variable \var{n}; the expression evaluates
+to the index of the plural in the catalog. See the GNU gettext
+documentation for the precise syntax to be used in \file{.po} files and the
+formulas for a variety of languages.
+
+\versionadded{2.3}
+
+\end{funcdesc}
+
+\begin{funcdesc}{lngettext}{singular, plural, n}
+Equivalent to \function{ngettext()}, but the translation is returned
+in the preferred system encoding, if no other encoding was explicitly
+set with \function{bind_textdomain_codeset()}.
+
+\versionadded{2.4}
+\end{funcdesc}
+
+\begin{funcdesc}{dngettext}{domain, singular, plural, n}
+Like \function{ngettext()}, but look the message up in the specified
+\var{domain}.
+
+\versionadded{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{ldngettext}{domain, singular, plural, n}
+Equivalent to \function{dngettext()}, but the translation is returned
+in the preferred system encoding, if no other encoding was explicitly
+set with \function{bind_textdomain_codeset()}.
+
+\versionadded{2.4}
+\end{funcdesc}
+
+
+
+Note that GNU \program{gettext} also defines a \function{dcgettext()}
+method, but this was deemed not useful and so it is currently
+unimplemented.
+
+Here's an example of typical usage for this API:
+
+\begin{verbatim}
+import gettext
+gettext.bindtextdomain('myapplication', '/path/to/my/language/directory')
+gettext.textdomain('myapplication')
+_ = gettext.gettext
+# ...
+print _('This is a translatable string.')
+\end{verbatim}
+
+\subsection{Class-based API}
+
+The class-based API of the \module{gettext} module gives you more
+flexibility and greater convenience than the GNU \program{gettext}
+API.  It is the recommended way of localizing your Python applications and
+modules.  \module{gettext} defines a ``translations'' class which
+implements the parsing of GNU \file{.mo} format files, and has methods
+for returning either standard 8-bit strings or Unicode strings.
+Instances of this ``translations'' class can also install themselves 
+in the built-in namespace as the function \function{_()}.
+
+\begin{funcdesc}{find}{domain\optional{, localedir\optional{, 
+                        languages\optional{, all}}}}
+This function implements the standard \file{.mo} file search
+algorithm.  It takes a \var{domain}, identical to what
+\function{textdomain()} takes.  Optional \var{localedir} is as in
+\function{bindtextdomain()}  Optional \var{languages} is a list of
+strings, where each string is a language code.
+
+If \var{localedir} is not given, then the default system locale
+directory is used.\footnote{See the footnote for
+\function{bindtextdomain()} above.}  If \var{languages} is not given,
+then the following environment variables are searched: \envvar{LANGUAGE},
+\envvar{LC_ALL}, \envvar{LC_MESSAGES}, and \envvar{LANG}.  The first one
+returning a non-empty value is used for the \var{languages} variable.
+The environment variables should contain a colon separated list of
+languages, which will be split on the colon to produce the expected
+list of language code strings.
+
+\function{find()} then expands and normalizes the languages, and then
+iterates through them, searching for an existing file built of these
+components:
+
+\file{\var{localedir}/\var{language}/LC_MESSAGES/\var{domain}.mo}
+
+The first such file name that exists is returned by \function{find()}.
+If no such file is found, then \code{None} is returned. If \var{all}
+is given, it returns a list of all file names, in the order in which
+they appear in the languages list or the environment variables.
+\end{funcdesc}
+
+\begin{funcdesc}{translation}{domain\optional{, localedir\optional{,
+                              languages\optional{, class_\optional{,
+			      fallback\optional{, codeset}}}}}}
+Return a \class{Translations} instance based on the \var{domain},
+\var{localedir}, and \var{languages}, which are first passed to
+\function{find()} to get a list of the
+associated \file{.mo} file paths.  Instances with
+identical \file{.mo} file names are cached.  The actual class instantiated
+is either \var{class_} if provided, otherwise
+\class{GNUTranslations}.  The class's constructor must take a single
+file object argument. If provided, \var{codeset} will change the
+charset used to encode translated strings.
+
+If multiple files are found, later files are used as fallbacks for
+earlier ones. To allow setting the fallback, \function{copy.copy}
+is used to clone each translation object from the cache; the actual
+instance data is still shared with the cache.
+
+If no \file{.mo} file is found, this function raises
+\exception{IOError} if \var{fallback} is false (which is the default),
+and returns a \class{NullTranslations} instance if \var{fallback} is
+true.
+
+\versionchanged[Added the \var{codeset} parameter]{2.4}
+\end{funcdesc}
+
+\begin{funcdesc}{install}{domain\optional{, localedir\optional{, unicode
+			  \optional{, codeset\optional{, names}}}}}
+This installs the function \function{_} in Python's builtin namespace,
+based on \var{domain}, \var{localedir}, and \var{codeset} which are
+passed to the function \function{translation()}.  The \var{unicode}
+flag is passed to the resulting translation object's \method{install}
+method.
+
+For the \var{names} parameter, please see the description of the
+translation object's \method{install} method.
+
+As seen below, you usually mark the strings in your application that are
+candidates for translation, by wrapping them in a call to the
+\function{_()} function, like this:
+
+\begin{verbatim}
+print _('This string will be translated.')
+\end{verbatim}
+
+For convenience, you want the \function{_()} function to be installed in
+Python's builtin namespace, so it is easily accessible in all modules
+of your application.  
+
+\versionchanged[Added the \var{codeset} parameter]{2.4}
+\versionchanged[Added the \var{names} parameter]{2.5}
+\end{funcdesc}
+
+\subsubsection{The \class{NullTranslations} class}
+Translation classes are what actually implement the translation of
+original source file message strings to translated message strings.
+The base class used by all translation classes is
+\class{NullTranslations}; this provides the basic interface you can use
+to write your own specialized translation classes.  Here are the
+methods of \class{NullTranslations}:
+
+\begin{methoddesc}[NullTranslations]{__init__}{\optional{fp}}
+Takes an optional file object \var{fp}, which is ignored by the base
+class.  Initializes ``protected'' instance variables \var{_info} and
+\var{_charset} which are set by derived classes, as well as \var{_fallback},
+which is set through \method{add_fallback}.  It then calls
+\code{self._parse(fp)} if \var{fp} is not \code{None}.
+\end{methoddesc}
+
+\begin{methoddesc}[NullTranslations]{_parse}{fp}
+No-op'd in the base class, this method takes file object \var{fp}, and
+reads the data from the file, initializing its message catalog.  If
+you have an unsupported message catalog file format, you should
+override this method to parse your format.
+\end{methoddesc}
+
+\begin{methoddesc}[NullTranslations]{add_fallback}{fallback}
+Add \var{fallback} as the fallback object for the current translation
+object. A translation object should consult the fallback if it cannot
+provide a translation for a given message.
+\end{methoddesc}
+
+\begin{methoddesc}[NullTranslations]{gettext}{message}
+If a fallback has been set, forward \method{gettext()} to the fallback.
+Otherwise, return the translated message.  Overridden in derived classes.
+\end{methoddesc}
+
+\begin{methoddesc}[NullTranslations]{lgettext}{message}
+If a fallback has been set, forward \method{lgettext()} to the fallback.
+Otherwise, return the translated message.  Overridden in derived classes.
+
+\versionadded{2.4}
+\end{methoddesc}
+
+\begin{methoddesc}[NullTranslations]{ugettext}{message}
+If a fallback has been set, forward \method{ugettext()} to the fallback.
+Otherwise, return the translated message as a Unicode string.
+Overridden in derived classes.
+\end{methoddesc}
+
+\begin{methoddesc}[NullTranslations]{ngettext}{singular, plural, n}
+If a fallback has been set, forward \method{ngettext()} to the fallback.
+Otherwise, return the translated message.  Overridden in derived classes.
+
+\versionadded{2.3}
+\end{methoddesc}
+
+\begin{methoddesc}[NullTranslations]{lngettext}{singular, plural, n}
+If a fallback has been set, forward \method{ngettext()} to the fallback.
+Otherwise, return the translated message.  Overridden in derived classes.
+
+\versionadded{2.4}
+\end{methoddesc}
+
+\begin{methoddesc}[NullTranslations]{ungettext}{singular, plural, n}
+If a fallback has been set, forward \method{ungettext()} to the fallback.
+Otherwise, return the translated message as a Unicode string.
+Overridden in derived classes.
+
+\versionadded{2.3}
+\end{methoddesc}
+
+\begin{methoddesc}[NullTranslations]{info}{}
+Return the ``protected'' \member{_info} variable.
+\end{methoddesc}
+
+\begin{methoddesc}[NullTranslations]{charset}{}
+Return the ``protected'' \member{_charset} variable.
+\end{methoddesc}
+
+\begin{methoddesc}[NullTranslations]{output_charset}{}
+Return the ``protected'' \member{_output_charset} variable, which
+defines the encoding used to return translated messages.
+
+\versionadded{2.4}
+\end{methoddesc}
+
+\begin{methoddesc}[NullTranslations]{set_output_charset}{charset}
+Change the ``protected'' \member{_output_charset} variable, which
+defines the encoding used to return translated messages.
+
+\versionadded{2.4}
+\end{methoddesc}
+
+\begin{methoddesc}[NullTranslations]{install}{\optional{unicode
+                                              \optional{, names}}}
+If the \var{unicode} flag is false, this method installs
+\method{self.gettext()} into the built-in namespace, binding it to
+\samp{_}.  If \var{unicode} is true, it binds \method{self.ugettext()}
+instead.  By default, \var{unicode} is false.
+
+If the \var{names} parameter is given, it must be a sequence containing
+the names of functions you want to install in the builtin namespace in
+addition to \function{_()}. Supported names are \code{'gettext'} (bound
+to \method{self.gettext()} or \method{self.ugettext()} according to the
+\var{unicode} flag), \code{'ngettext'} (bound to \method{self.ngettext()}
+or \method{self.ungettext()} according to the \var{unicode} flag),
+\code{'lgettext'} and \code{'lngettext'}.
+
+Note that this is only one way, albeit the most convenient way, to
+make the \function{_} function available to your application.  Because it
+affects the entire application globally, and specifically the built-in
+namespace, localized modules should never install \function{_}.
+Instead, they should use this code to make \function{_} available to
+their module:
+
+\begin{verbatim}
+import gettext
+t = gettext.translation('mymodule', ...)
+_ = t.gettext
+\end{verbatim}
+
+This puts \function{_} only in the module's global namespace and so
+only affects calls within this module.
+
+\versionchanged[Added the \var{names} parameter]{2.5}
+\end{methoddesc}
+
+\subsubsection{The \class{GNUTranslations} class}
+
+The \module{gettext} module provides one additional class derived from
+\class{NullTranslations}: \class{GNUTranslations}.  This class
+overrides \method{_parse()} to enable reading GNU \program{gettext}
+format \file{.mo} files in both big-endian and little-endian format.
+It also coerces both message ids and message strings to Unicode.
+
+\class{GNUTranslations} parses optional meta-data out of the
+translation catalog.  It is convention with GNU \program{gettext} to
+include meta-data as the translation for the empty string.  This
+meta-data is in \rfc{822}-style \code{key: value} pairs, and should
+contain the \code{Project-Id-Version} key.  If the key
+\code{Content-Type} is found, then the \code{charset} property is used
+to initialize the ``protected'' \member{_charset} instance variable,
+defaulting to \code{None} if not found.  If the charset encoding is
+specified, then all message ids and message strings read from the
+catalog are converted to Unicode using this encoding.  The
+\method{ugettext()} method always returns a Unicode, while the
+\method{gettext()} returns an encoded 8-bit string.  For the message
+id arguments of both methods, either Unicode strings or 8-bit strings
+containing only US-ASCII characters are acceptable.  Note that the
+Unicode version of the methods (i.e. \method{ugettext()} and
+\method{ungettext()}) are the recommended interface to use for
+internationalized Python programs.
+
+The entire set of key/value pairs are placed into a dictionary and set
+as the ``protected'' \member{_info} instance variable.
+
+If the \file{.mo} file's magic number is invalid, or if other problems
+occur while reading the file, instantiating a \class{GNUTranslations} class
+can raise \exception{IOError}.
+
+The following methods are overridden from the base class implementation:
+
+\begin{methoddesc}[GNUTranslations]{gettext}{message}
+Look up the \var{message} id in the catalog and return the
+corresponding message string, as an 8-bit string encoded with the
+catalog's charset encoding, if known.  If there is no entry in the
+catalog for the \var{message} id, and a fallback has been set, the
+look up is forwarded to the fallback's \method{gettext()} method.
+Otherwise, the \var{message} id is returned.
+\end{methoddesc}
+
+\begin{methoddesc}[GNUTranslations]{lgettext}{message}
+Equivalent to \method{gettext()}, but the translation is returned
+in the preferred system encoding, if no other encoding was explicitly
+set with \method{set_output_charset()}.
+
+\versionadded{2.4}
+\end{methoddesc}
+
+\begin{methoddesc}[GNUTranslations]{ugettext}{message}
+Look up the \var{message} id in the catalog and return the
+corresponding message string, as a Unicode string.  If there is no
+entry in the catalog for the \var{message} id, and a fallback has been
+set, the look up is forwarded to the fallback's \method{ugettext()}
+method.  Otherwise, the \var{message} id is returned.
+\end{methoddesc}
+
+\begin{methoddesc}[GNUTranslations]{ngettext}{singular, plural, n}
+Do a plural-forms lookup of a message id.  \var{singular} is used as
+the message id for purposes of lookup in the catalog, while \var{n} is
+used to determine which plural form to use.  The returned message
+string is an 8-bit string encoded with the catalog's charset encoding,
+if known.
+
+If the message id is not found in the catalog, and a fallback is
+specified, the request is forwarded to the fallback's
+\method{ngettext()} method.  Otherwise, when \var{n} is 1 \var{singular} is
+returned, and \var{plural} is returned in all other cases.
+
+\versionadded{2.3}
+\end{methoddesc}
+
+\begin{methoddesc}[GNUTranslations]{lngettext}{singular, plural, n}
+Equivalent to \method{gettext()}, but the translation is returned
+in the preferred system encoding, if no other encoding was explicitly
+set with \method{set_output_charset()}.
+
+\versionadded{2.4}
+\end{methoddesc}
+
+\begin{methoddesc}[GNUTranslations]{ungettext}{singular, plural, n}
+Do a plural-forms lookup of a message id.  \var{singular} is used as
+the message id for purposes of lookup in the catalog, while \var{n} is
+used to determine which plural form to use.  The returned message
+string is a Unicode string.
+
+If the message id is not found in the catalog, and a fallback is
+specified, the request is forwarded to the fallback's
+\method{ungettext()} method.  Otherwise, when \var{n} is 1 \var{singular} is
+returned, and \var{plural} is returned in all other cases.
+
+Here is an example:
+
+\begin{verbatim}
+n = len(os.listdir('.'))
+cat = GNUTranslations(somefile)
+message = cat.ungettext(
+    'There is %(num)d file in this directory',
+    'There are %(num)d files in this directory',
+    n) % {'num': n}
+\end{verbatim}
+
+\versionadded{2.3}
+\end{methoddesc}
+
+\subsubsection{Solaris message catalog support}
+
+The Solaris operating system defines its own binary
+\file{.mo} file format, but since no documentation can be found on
+this format, it is not supported at this time.
+
+\subsubsection{The Catalog constructor}
+
+GNOME\index{GNOME} uses a version of the \module{gettext} module by
+James Henstridge, but this version has a slightly different API.  Its
+documented usage was:
+
+\begin{verbatim}
+import gettext
+cat = gettext.Catalog(domain, localedir)
+_ = cat.gettext
+print _('hello world')
+\end{verbatim}
+
+For compatibility with this older module, the function
+\function{Catalog()} is an alias for the \function{translation()}
+function described above.
+
+One difference between this module and Henstridge's: his catalog
+objects supported access through a mapping API, but this appears to be
+unused and so is not currently supported.
+
+\subsection{Internationalizing your programs and modules}
+Internationalization (I18N) refers to the operation by which a program
+is made aware of multiple languages.  Localization (L10N) refers to
+the adaptation of your program, once internationalized, to the local
+language and cultural habits.  In order to provide multilingual
+messages for your Python programs, you need to take the following
+steps:
+
+\begin{enumerate}
+    \item prepare your program or module by specially marking
+          translatable strings
+    \item run a suite of tools over your marked files to generate raw
+          messages catalogs
+    \item create language specific translations of the message catalogs
+    \item use the \module{gettext} module so that message strings are
+          properly translated
+\end{enumerate}
+
+In order to prepare your code for I18N, you need to look at all the
+strings in your files.  Any string that needs to be translated
+should be marked by wrapping it in \code{_('...')} --- that is, a call
+to the function \function{_()}.  For example:
+
+\begin{verbatim}
+filename = 'mylog.txt'
+message = _('writing a log message')
+fp = open(filename, 'w')
+fp.write(message)
+fp.close()
+\end{verbatim}
+
+In this example, the string \code{'writing a log message'} is marked as
+a candidate for translation, while the strings \code{'mylog.txt'} and
+\code{'w'} are not.
+
+The Python distribution comes with two tools which help you generate
+the message catalogs once you've prepared your source code.  These may
+or may not be available from a binary distribution, but they can be
+found in a source distribution, in the \file{Tools/i18n} directory.
+
+The \program{pygettext}\footnote{Fran\c cois Pinard has
+written a program called
+\program{xpot} which does a similar job.  It is available as part of
+his \program{po-utils} package at
+\url{http://po-utils.progiciels-bpi.ca/}.} program
+scans all your Python source code looking for the strings you
+previously marked as translatable.  It is similar to the GNU
+\program{gettext} program except that it understands all the
+intricacies of Python source code, but knows nothing about C or \Cpp
+source code.  You don't need GNU \code{gettext} unless you're also
+going to be translating C code (such as C extension modules).
+
+\program{pygettext} generates textual Uniforum-style human readable
+message catalog \file{.pot} files, essentially structured human
+readable files which contain every marked string in the source code,
+along with a placeholder for the translation strings.
+\program{pygettext} is a command line script that supports a similar
+command line interface as \program{xgettext}; for details on its use,
+run:
+
+\begin{verbatim}
+pygettext.py --help
+\end{verbatim}
+
+Copies of these \file{.pot} files are then handed over to the
+individual human translators who write language-specific versions for
+every supported natural language.  They send you back the filled in
+language-specific versions as a \file{.po} file.  Using the
+\program{msgfmt.py}\footnote{\program{msgfmt.py} is binary
+compatible with GNU \program{msgfmt} except that it provides a
+simpler, all-Python implementation.  With this and
+\program{pygettext.py}, you generally won't need to install the GNU
+\program{gettext} package to internationalize your Python
+applications.} program (in the \file{Tools/i18n} directory), you take the
+\file{.po} files from your translators and generate the
+machine-readable \file{.mo} binary catalog files.  The \file{.mo}
+files are what the \module{gettext} module uses for the actual
+translation processing during run-time.
+
+How you use the \module{gettext} module in your code depends on
+whether you are internationalizing a single module or your entire application.
+The next two sections will discuss each case.
+
+\subsubsection{Localizing your module}
+
+If you are localizing your module, you must take care not to make
+global changes, e.g. to the built-in namespace.  You should not use
+the GNU \code{gettext} API but instead the class-based API.  
+
+Let's say your module is called ``spam'' and the module's various
+natural language translation \file{.mo} files reside in
+\file{/usr/share/locale} in GNU \program{gettext} format.  Here's what
+you would put at the top of your module:
+
+\begin{verbatim}
+import gettext
+t = gettext.translation('spam', '/usr/share/locale')
+_ = t.lgettext
+\end{verbatim}
+
+If your translators were providing you with Unicode strings in their
+\file{.po} files, you'd instead do:
+
+\begin{verbatim}
+import gettext
+t = gettext.translation('spam', '/usr/share/locale')
+_ = t.ugettext
+\end{verbatim}
+
+\subsubsection{Localizing your application}
+
+If you are localizing your application, you can install the \function{_()}
+function globally into the built-in namespace, usually in the main driver file
+of your application.  This will let all your application-specific
+files just use \code{_('...')} without having to explicitly install it in
+each file.
+
+In the simple case then, you need only add the following bit of code
+to the main driver file of your application:
+
+\begin{verbatim}
+import gettext
+gettext.install('myapplication')
+\end{verbatim}
+
+If you need to set the locale directory or the \var{unicode} flag,
+you can pass these into the \function{install()} function:
+
+\begin{verbatim}
+import gettext
+gettext.install('myapplication', '/usr/share/locale', unicode=1)
+\end{verbatim}
+
+\subsubsection{Changing languages on the fly}
+
+If your program needs to support many languages at the same time, you
+may want to create multiple translation instances and then switch
+between them explicitly, like so:
+
+\begin{verbatim}
+import gettext
+
+lang1 = gettext.translation('myapplication', languages=['en'])
+lang2 = gettext.translation('myapplication', languages=['fr'])
+lang3 = gettext.translation('myapplication', languages=['de'])
+
+# start by using language1
+lang1.install()
+
+# ... time goes by, user selects language 2
+lang2.install()
+
+# ... more time goes by, user selects language 3
+lang3.install()
+\end{verbatim}
+
+\subsubsection{Deferred translations}
+
+In most coding situations, strings are translated where they are coded.
+Occasionally however, you need to mark strings for translation, but
+defer actual translation until later.  A classic example is:
+
+\begin{verbatim}
+animals = ['mollusk',
+           'albatross',
+	   'rat',
+	   'penguin',
+	   'python',
+	   ]
+# ...
+for a in animals:
+    print a
+\end{verbatim}
+
+Here, you want to mark the strings in the \code{animals} list as being
+translatable, but you don't actually want to translate them until they
+are printed.
+
+Here is one way you can handle this situation:
+
+\begin{verbatim}
+def _(message): return message
+
+animals = [_('mollusk'),
+           _('albatross'),
+	   _('rat'),
+	   _('penguin'),
+	   _('python'),
+	   ]
+
+del _
+
+# ...
+for a in animals:
+    print _(a)
+\end{verbatim}
+
+This works because the dummy definition of \function{_()} simply returns
+the string unchanged.  And this dummy definition will temporarily
+override any definition of \function{_()} in the built-in namespace
+(until the \keyword{del} command).
+Take care, though if you have a previous definition of \function{_} in
+the local namespace.
+
+Note that the second use of \function{_()} will not identify ``a'' as
+being translatable to the \program{pygettext} program, since it is not
+a string.
+
+Another way to handle this is with the following example:
+
+\begin{verbatim}
+def N_(message): return message
+
+animals = [N_('mollusk'),
+           N_('albatross'),
+	   N_('rat'),
+	   N_('penguin'),
+	   N_('python'),
+	   ]
+
+# ...
+for a in animals:
+    print _(a)
+\end{verbatim}
+
+In this case, you are marking translatable strings with the function
+\function{N_()},\footnote{The choice of \function{N_()} here is totally
+arbitrary; it could have just as easily been
+\function{MarkThisStringForTranslation()}.
+} which won't conflict with any definition of
+\function{_()}.  However, you will need to teach your message extraction
+program to look for translatable strings marked with \function{N_()}.
+\program{pygettext} and \program{xpot} both support this through the
+use of command line switches.
+
+\subsubsection{\function{gettext()} vs. \function{lgettext()}}
+In Python 2.4 the \function{lgettext()} family of functions were
+introduced. The intention of these functions is to provide an
+alternative which is more compliant with the current
+implementation of GNU gettext. Unlike \function{gettext()}, which
+returns strings encoded with the same codeset used in the
+translation file, \function{lgettext()} will return strings
+encoded with the preferred system encoding, as returned by
+\function{locale.getpreferredencoding()}. Also notice that
+Python 2.4 introduces new functions to explicitly choose
+the codeset used in translated strings. If a codeset is explicitly
+set, even \function{lgettext()} will return translated strings in
+the requested codeset, as would be expected in the GNU gettext
+implementation.
+
+\subsection{Acknowledgements}
+
+The following people contributed code, feedback, design suggestions,
+previous implementations, and valuable experience to the creation of
+this module:
+
+\begin{itemize}
+    \item Peter Funk
+    \item James Henstridge
+    \item Juan David Ib\'a\~nez Palomar
+    \item Marc-Andr\'e Lemburg
+    \item Martin von L\"owis
+    \item Fran\c cois Pinard
+    \item Barry Warsaw
+    \item Gustavo Niemeyer
+\end{itemize}

Added: vendor/Python/current/Doc/lib/libgl.tex
===================================================================
--- vendor/Python/current/Doc/lib/libgl.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libgl.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,224 @@
+\section{\module{gl} ---
+         \emph{Graphics Library} interface}
+
+\declaremodule{builtin}{gl}
+  \platform{IRIX}
+\modulesynopsis{Functions from the Silicon Graphics \emph{Graphics Library}.}
+
+
+This module provides access to the Silicon Graphics
+\emph{Graphics Library}.
+It is available only on Silicon Graphics machines.
+
+\warning{Some illegal calls to the GL library cause the Python
+interpreter to dump core.
+In particular, the use of most GL calls is unsafe before the first
+window is opened.}
+
+The module is too large to document here in its entirety, but the
+following should help you to get started.
+The parameter conventions for the C functions are translated to Python as
+follows:
+
+\begin{itemize}
+\item
+All (short, long, unsigned) int values are represented by Python
+integers.
+\item
+All float and double values are represented by Python floating point
+numbers.
+In most cases, Python integers are also allowed.
+\item
+All arrays are represented by one-dimensional Python lists.
+In most cases, tuples are also allowed.
+\item
+\begin{sloppypar}
+All string and character arguments are represented by Python strings,
+for instance,
+\code{winopen('Hi There!')}
+and
+\code{rotate(900, 'z')}.
+\end{sloppypar}
+\item
+All (short, long, unsigned) integer arguments or return values that are
+only used to specify the length of an array argument are omitted.
+For example, the C call
+
+\begin{verbatim}
+lmdef(deftype, index, np, props)
+\end{verbatim}
+
+is translated to Python as
+
+\begin{verbatim}
+lmdef(deftype, index, props)
+\end{verbatim}
+
+\item
+Output arguments are omitted from the argument list; they are
+transmitted as function return values instead.
+If more than one value must be returned, the return value is a tuple.
+If the C function has both a regular return value (that is not omitted
+because of the previous rule) and an output argument, the return value
+comes first in the tuple.
+Examples: the C call
+
+\begin{verbatim}
+getmcolor(i, &red, &green, &blue)
+\end{verbatim}
+
+is translated to Python as
+
+\begin{verbatim}
+red, green, blue = getmcolor(i)
+\end{verbatim}
+
+\end{itemize}
+
+The following functions are non-standard or have special argument
+conventions:
+
+\begin{funcdesc}{varray}{argument}
+%JHXXX the argument-argument added
+Equivalent to but faster than a number of
+\code{v3d()}
+calls.
+The \var{argument} is a list (or tuple) of points.
+Each point must be a tuple of coordinates
+\code{(\var{x}, \var{y}, \var{z})} or \code{(\var{x}, \var{y})}.
+The points may be 2- or 3-dimensional but must all have the
+same dimension.
+Float and int values may be mixed however.
+The points are always converted to 3D double precision points
+by assuming \code{\var{z} = 0.0} if necessary (as indicated in the man page),
+and for each point
+\code{v3d()}
+is called.
+\end{funcdesc}
+
+\begin{funcdesc}{nvarray}{}
+Equivalent to but faster than a number of
+\code{n3f}
+and
+\code{v3f}
+calls.
+The argument is an array (list or tuple) of pairs of normals and points.
+Each pair is a tuple of a point and a normal for that point.
+Each point or normal must be a tuple of coordinates
+\code{(\var{x}, \var{y}, \var{z})}.
+Three coordinates must be given.
+Float and int values may be mixed.
+For each pair,
+\code{n3f()}
+is called for the normal, and then
+\code{v3f()}
+is called for the point.
+\end{funcdesc}
+
+\begin{funcdesc}{vnarray}{}
+Similar to 
+\code{nvarray()}
+but the pairs have the point first and the normal second.
+\end{funcdesc}
+
+\begin{funcdesc}{nurbssurface}{s_k, t_k, ctl, s_ord, t_ord, type}
+% XXX s_k[], t_k[], ctl[][]
+Defines a nurbs surface.
+The dimensions of
+\code{\var{ctl}[][]}
+are computed as follows:
+\code{[len(\var{s_k}) - \var{s_ord}]},
+\code{[len(\var{t_k}) - \var{t_ord}]}.
+\end{funcdesc}
+
+\begin{funcdesc}{nurbscurve}{knots, ctlpoints, order, type}
+Defines a nurbs curve.
+The length of ctlpoints is
+\code{len(\var{knots}) - \var{order}}.
+\end{funcdesc}
+
+\begin{funcdesc}{pwlcurve}{points, type}
+Defines a piecewise-linear curve.
+\var{points}
+is a list of points.
+\var{type}
+must be
+\code{N_ST}.
+\end{funcdesc}
+
+\begin{funcdesc}{pick}{n}
+\funcline{select}{n}
+The only argument to these functions specifies the desired size of the
+pick or select buffer.
+\end{funcdesc}
+
+\begin{funcdesc}{endpick}{}
+\funcline{endselect}{}
+These functions have no arguments.
+They return a list of integers representing the used part of the
+pick/select buffer.
+No method is provided to detect buffer overrun.
+\end{funcdesc}
+
+Here is a tiny but complete example GL program in Python:
+
+\begin{verbatim}
+import gl, GL, time
+
+def main():
+    gl.foreground()
+    gl.prefposition(500, 900, 500, 900)
+    w = gl.winopen('CrissCross')
+    gl.ortho2(0.0, 400.0, 0.0, 400.0)
+    gl.color(GL.WHITE)
+    gl.clear()
+    gl.color(GL.RED)
+    gl.bgnline()
+    gl.v2f(0.0, 0.0)
+    gl.v2f(400.0, 400.0)
+    gl.endline()
+    gl.bgnline()
+    gl.v2f(400.0, 0.0)
+    gl.v2f(0.0, 400.0)
+    gl.endline()
+    time.sleep(5)
+
+main()
+\end{verbatim}
+
+
+\begin{seealso}
+  \seetitle[http://pyopengl.sourceforge.net/]
+           {PyOpenGL: The Python OpenGL Binding}
+           {An interface to OpenGL\index{OpenGL} is also available;
+            see information about the
+            \strong{PyOpenGL}\index{PyOpenGL} project online at
+            \url{http://pyopengl.sourceforge.net/}.  This may be a
+            better option if support for SGI hardware from before
+            about 1996 is not required.}
+\end{seealso}
+
+
+\section{\module{DEVICE} ---
+         Constants used with the \module{gl} module}
+
+\declaremodule{standard}{DEVICE}
+  \platform{IRIX}
+\modulesynopsis{Constants used with the \module{gl} module.}
+
+This modules defines the constants used by the Silicon Graphics
+\emph{Graphics Library} that C programmers find in the header file
+\code{<gl/device.h>}.
+Read the module source file for details.
+
+
+\section{\module{GL} ---
+         Constants used with the \module{gl} module}
+
+\declaremodule[gl-constants]{standard}{GL}
+  \platform{IRIX}
+\modulesynopsis{Constants used with the \module{gl} module.}
+
+This module contains constants used by the Silicon Graphics
+\emph{Graphics Library} from the C header file \code{<gl/gl.h>}.
+Read the module source file for details.

Added: vendor/Python/current/Doc/lib/libglob.tex
===================================================================
--- vendor/Python/current/Doc/lib/libglob.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libglob.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,51 @@
+\section{\module{glob} ---
+         \UNIX{} style pathname pattern expansion}
+
+\declaremodule{standard}{glob}
+\modulesynopsis{\UNIX\ shell style pathname pattern expansion.}
+
+
+The \module{glob} module finds all the pathnames matching a specified
+pattern according to the rules used by the \UNIX{} shell.  No tilde
+expansion is done, but \code{*}, \code{?}, and character ranges
+expressed with \code{[]} will be correctly matched.  This is done by
+using the \function{os.listdir()} and \function{fnmatch.fnmatch()}
+functions in concert, and not by actually invoking a subshell.  (For
+tilde and shell variable expansion, use \function{os.path.expanduser()}
+and \function{os.path.expandvars()}.)
+\index{filenames!pathname expansion}
+
+\begin{funcdesc}{glob}{pathname}
+Return a possibly-empty list of path names that match \var{pathname},
+which must be a string containing a path specification.
+\var{pathname} can be either absolute (like
+\file{/usr/src/Python-1.5/Makefile}) or relative (like
+\file{../../Tools/*/*.gif}), and can contain shell-style wildcards.
+Broken symlinks are included in the results (as in the shell).
+\end{funcdesc}
+
+\begin{funcdesc}{iglob}{pathname}
+Return an iterator which yields the same values as \function{glob()}
+without actually storing them all simultaneously.
+\versionadded{2.5}
+\end{funcdesc}
+
+For example, consider a directory containing only the following files:
+\file{1.gif}, \file{2.txt}, and \file{card.gif}.  \function{glob()}
+will produce the following results.  Notice how any leading components
+of the path are preserved.
+
+\begin{verbatim}
+>>> import glob
+>>> glob.glob('./[0-9].*')
+['./1.gif', './2.txt']
+>>> glob.glob('*.gif')
+['1.gif', 'card.gif']
+>>> glob.glob('?.gif')
+['1.gif']
+\end{verbatim}
+
+
+\begin{seealso}
+  \seemodule{fnmatch}{Shell-style filename (not path) expansion}
+\end{seealso}

Added: vendor/Python/current/Doc/lib/libgopherlib.tex
===================================================================
--- vendor/Python/current/Doc/lib/libgopherlib.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libgopherlib.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,36 @@
+\section{\module{gopherlib} ---
+         Gopher protocol client}
+
+\declaremodule{standard}{gopherlib}
+\modulesynopsis{Gopher protocol client (requires sockets).}
+
+\deprecated{2.5}{The \code{gopher} protocol is not in active use
+                 anymore.}
+
+\indexii{Gopher}{protocol}
+
+This module provides a minimal implementation of client side of the
+Gopher protocol.  It is used by the module \refmodule{urllib} to
+handle URLs that use the Gopher protocol.
+
+The module defines the following functions:
+
+\begin{funcdesc}{send_selector}{selector, host\optional{, port}}
+Send a \var{selector} string to the gopher server at \var{host} and
+\var{port} (default \code{70}).  Returns an open file object from
+which the returned document can be read.
+\end{funcdesc}
+
+\begin{funcdesc}{send_query}{selector, query, host\optional{, port}}
+Send a \var{selector} string and a \var{query} string to a gopher
+server at \var{host} and \var{port} (default \code{70}).  Returns an
+open file object from which the returned document can be read.
+\end{funcdesc}
+
+Note that the data returned by the Gopher server can be of any type,
+depending on the first character of the selector string.  If the data
+is text (first character of the selector is \samp{0}), lines are
+terminated by CRLF, and the data is terminated by a line consisting of
+a single \samp{.}, and a leading \samp{.} should be stripped from
+lines that begin with \samp{..}.  Directory listings (first character
+of the selector is \samp{1}) are transferred using the same protocol.

Added: vendor/Python/current/Doc/lib/libgrp.tex
===================================================================
--- vendor/Python/current/Doc/lib/libgrp.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libgrp.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,49 @@
+\section{\module{grp} ---
+         The group database}
+
+\declaremodule{builtin}{grp}
+  \platform{Unix}
+\modulesynopsis{The group database (\function{getgrnam()} and friends).}
+
+
+This module provides access to the \UNIX{} group database.
+It is available on all \UNIX{} versions.
+
+Group database entries are reported as a tuple-like object, whose
+attributes correspond to the members of the \code{group} structure
+(Attribute field below, see \code{<pwd.h>}):
+
+\begin{tableiii}{r|l|l}{textrm}{Index}{Attribute}{Meaning}
+  \lineiii{0}{gr_name}{the name of the group}
+  \lineiii{1}{gr_passwd}{the (encrypted) group password; often empty}
+  \lineiii{2}{gr_gid}{the numerical group ID}
+  \lineiii{3}{gr_mem}{all the group member's  user  names}
+\end{tableiii}
+
+The gid is an integer, name and password are strings, and the member
+list is a list of strings.
+(Note that most users are not explicitly listed as members of the
+group they are in according to the password database.  Check both
+databases to get complete membership information.)
+
+It defines the following items:
+
+\begin{funcdesc}{getgrgid}{gid}
+Return the group database entry for the given numeric group ID.
+\exception{KeyError} is raised if the entry asked for cannot be found.
+\end{funcdesc}
+
+\begin{funcdesc}{getgrnam}{name}
+Return the group database entry for the given group name.
+\exception{KeyError} is raised if the entry asked for cannot be found.
+\end{funcdesc}
+
+\begin{funcdesc}{getgrall}{}
+Return a list of all available group entries, in arbitrary order.
+\end{funcdesc}
+
+
+\begin{seealso}
+  \seemodule{pwd}{An interface to the user database, similar to this.}
+  \seemodule{spwd}{An interface to the shadow password database, similar to this.}
+\end{seealso}

Added: vendor/Python/current/Doc/lib/libgzip.tex
===================================================================
--- vendor/Python/current/Doc/lib/libgzip.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libgzip.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,70 @@
+\section{\module{gzip} ---
+         Support for \program{gzip} files}
+
+\declaremodule{standard}{gzip}
+\modulesynopsis{Interfaces for \program{gzip} compression and
+decompression using file objects.}
+
+
+The data compression provided by the \code{zlib} module is compatible
+with that used by the GNU compression program \program{gzip}.
+Accordingly, the \module{gzip} module provides the \class{GzipFile}
+class to read and write \program{gzip}-format files, automatically
+compressing or decompressing the data so it looks like an ordinary
+file object.  Note that additional file formats which can be
+decompressed by the \program{gzip} and \program{gunzip} programs, such 
+as those produced by \program{compress} and \program{pack}, are not
+supported by this module.
+
+The module defines the following items:
+
+\begin{classdesc}{GzipFile}{\optional{filename\optional{, mode\optional{,
+                            compresslevel\optional{, fileobj}}}}}
+Constructor for the \class{GzipFile} class, which simulates most of
+the methods of a file object, with the exception of the \method{readinto()}
+and \method{truncate()} methods.  At least one of
+\var{fileobj} and \var{filename} must be given a non-trivial value.
+
+The new class instance is based on \var{fileobj}, which can be a
+regular file, a \class{StringIO} object, or any other object which
+simulates a file.  It defaults to \code{None}, in which case
+\var{filename} is opened to provide a file object.
+
+When \var{fileobj} is not \code{None}, the \var{filename} argument is
+only used to be included in the \program{gzip} file header, which may
+includes the original filename of the uncompressed file.  It defaults
+to the filename of \var{fileobj}, if discernible; otherwise, it
+defaults to the empty string, and in this case the original filename
+is not included in the header.
+
+The \var{mode} argument can be any of \code{'r'}, \code{'rb'},
+\code{'a'}, \code{'ab'}, \code{'w'}, or \code{'wb'}, depending on
+whether the file will be read or written.  The default is the mode of
+\var{fileobj} if discernible; otherwise, the default is \code{'rb'}.
+If not given, the 'b' flag will be added to the mode to ensure the
+file is opened in binary mode for cross-platform portability.
+
+The \var{compresslevel} argument is an integer from \code{1} to
+\code{9} controlling the level of compression; \code{1} is fastest and
+produces the least compression, and \code{9} is slowest and produces
+the most compression.  The default is \code{9}.
+
+Calling a \class{GzipFile} object's \method{close()} method does not
+close \var{fileobj}, since you might wish to append more material
+after the compressed data.  This also allows you to pass a
+\class{StringIO} object opened for writing as \var{fileobj}, and
+retrieve the resulting memory buffer using the \class{StringIO}
+object's \method{getvalue()} method.
+\end{classdesc}
+
+\begin{funcdesc}{open}{filename\optional{, mode\optional{, compresslevel}}}
+This is a shorthand for \code{GzipFile(\var{filename},}
+\code{\var{mode},} \code{\var{compresslevel})}.  The \var{filename}
+argument is required; \var{mode} defaults to \code{'rb'} and
+\var{compresslevel} defaults to \code{9}.
+\end{funcdesc}
+
+\begin{seealso}
+  \seemodule{zlib}{The basic data compression module needed to support
+                   the \program{gzip} file format.}
+\end{seealso}

Added: vendor/Python/current/Doc/lib/libhashlib.tex
===================================================================
--- vendor/Python/current/Doc/lib/libhashlib.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libhashlib.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,114 @@
+\section{\module{hashlib} ---
+         Secure hashes and message digests}
+
+\declaremodule{builtin}{hashlib}
+\modulesynopsis{Secure hash and message digest algorithms.}
+\moduleauthor{Gregory P. Smith}{greg at users.sourceforge.net}
+\sectionauthor{Gregory P. Smith}{greg at users.sourceforge.net}
+
+\versionadded{2.5}
+
+\index{message digest, MD5}
+\index{secure hash algorithm, SHA1, SHA224, SHA256, SHA384, SHA512}
+
+This module implements a common interface to many different secure hash and
+message digest algorithms.  Included are the FIPS secure hash algorithms SHA1,
+SHA224, SHA256, SHA384, and SHA512 (defined in FIPS 180-2) as well as RSA's MD5
+algorithm (defined in Internet \rfc{1321}).
+The terms secure hash and message digest are interchangeable.  Older
+algorithms were called message digests.  The modern term is secure hash.
+
+\warning{Some algorithms have known hash collision weaknesses, see the FAQ at the end.}
+
+There is one constructor method named for each type of \dfn{hash}.  All return
+a hash object with the same simple interface.
+For example: use \function{sha1()} to create a SHA1 hash object.
+You can now feed this object with arbitrary strings using the \method{update()}
+method.  At any point you can ask it for the \dfn{digest} of the concatenation
+of the strings fed to it so far using the \method{digest()} or
+\method{hexdigest()} methods.
+
+Constructors for hash algorithms that are always present in this module are
+\function{md5()}, \function{sha1()}, \function{sha224()}, \function{sha256()},
+\function{sha384()}, and \function{sha512()}.  Additional algorithms may also
+be available depending upon the OpenSSL library that Python uses on your platform.
+\index{OpenSSL}
+
+For example, to obtain the digest of the string \code{'Nobody inspects
+the spammish repetition'}:
+
+\begin{verbatim}
+>>> import hashlib
+>>> m = hashlib.md5()
+>>> m.update("Nobody inspects")
+>>> m.update(" the spammish repetition")
+>>> m.digest()
+'\xbbd\x9c\x83\xdd\x1e\xa5\xc9\xd9\xde\xc9\xa1\x8d\xf0\xff\xe9'
+\end{verbatim}
+
+More condensed:
+
+\begin{verbatim}
+>>> hashlib.sha224("Nobody inspects the spammish repetition").hexdigest()
+'a4337bc45a8fc544c03f52dc550cd6e1e87021bc896588bd79e901e2'
+\end{verbatim}
+
+A generic \function{new()} constructor that takes the string name of the
+desired algorithm as its first parameter also exists to allow access to the
+above listed hashes as well as any other algorithms that your OpenSSL library
+may offer.  The named constructors are much faster than \function{new()} and
+should be preferred.
+
+Using \function{new()} with an algorithm provided by OpenSSL:
+
+\begin{verbatim}
+>>> h = hashlib.new('ripemd160')
+>>> h.update("Nobody inspects the spammish repetition")
+>>> h.hexdigest()
+'cc4a5ce1b3df48aec5d22d1f16b894a0b894eccc'
+\end{verbatim}
+
+The following values are provided as constant attributes of the hash objects
+returned by the constructors:
+
+\begin{datadesc}{digest_size}
+  The size of the resulting digest in bytes.
+\end{datadesc}
+
+A hash object has the following methods:
+
+\begin{methoddesc}[hash]{update}{arg}
+Update the hash object with the string \var{arg}.  Repeated calls are
+equivalent to a single call with the concatenation of all the
+arguments: \code{m.update(a); m.update(b)} is equivalent to
+\code{m.update(a+b)}.
+\end{methoddesc}
+
+\begin{methoddesc}[hash]{digest}{}
+Return the digest of the strings passed to the \method{update()}
+method so far.  This is a string of \member{digest_size} bytes which may
+contain non-\ASCII{} characters, including null bytes.
+\end{methoddesc}
+
+\begin{methoddesc}[hash]{hexdigest}{}
+Like \method{digest()} except the digest is returned as a string of
+double length, containing only hexadecimal digits.  This may 
+be used to exchange the value safely in email or other non-binary
+environments.
+\end{methoddesc}
+
+\begin{methoddesc}[hash]{copy}{}
+Return a copy (``clone'') of the hash object.  This can be used to
+efficiently compute the digests of strings that share a common initial
+substring.
+\end{methoddesc}
+
+\begin{seealso}
+  \seemodule{hmac}{A module to generate message authentication codes using hashes.}
+  \seemodule{base64}{Another way to encode binary hashes for non-binary environments.}
+  \seeurl{http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf}
+  {The FIPS 180-2 publication on Secure Hash Algorithms.}
+  \seeurl{http://www.cryptography.com/cnews/hash.html}
+  {Hash Collision FAQ with information on which algorithms have known issues and
+   what that means regarding their use.}
+\end{seealso}

Added: vendor/Python/current/Doc/lib/libheapq.tex
===================================================================
--- vendor/Python/current/Doc/lib/libheapq.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libheapq.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,214 @@
+\section{\module{heapq} ---
+         Heap queue algorithm}
+
+\declaremodule{standard}{heapq}
+\modulesynopsis{Heap queue algorithm (a.k.a. priority queue).}
+\moduleauthor{Kevin O'Connor}{}
+\sectionauthor{Guido van Rossum}{guido at python.org}
+% Theoretical explanation:
+\sectionauthor{Fran\c cois Pinard}{}
+\versionadded{2.3}
+
+
+This module provides an implementation of the heap queue algorithm,
+also known as the priority queue algorithm.
+
+Heaps are arrays for which
+\code{\var{heap}[\var{k}] <= \var{heap}[2*\var{k}+1]} and
+\code{\var{heap}[\var{k}] <= \var{heap}[2*\var{k}+2]}
+for all \var{k}, counting elements from zero.  For the sake of
+comparison, non-existing elements are considered to be infinite.  The
+interesting property of a heap is that \code{\var{heap}[0]} is always
+its smallest element.
+
+The API below differs from textbook heap algorithms in two aspects:
+(a) We use zero-based indexing.  This makes the relationship between the
+index for a node and the indexes for its children slightly less
+obvious, but is more suitable since Python uses zero-based indexing.
+(b) Our pop method returns the smallest item, not the largest (called a
+"min heap" in textbooks; a "max heap" is more common in texts because
+of its suitability for in-place sorting).
+
+These two make it possible to view the heap as a regular Python list
+without surprises: \code{\var{heap}[0]} is the smallest item, and
+\code{\var{heap}.sort()} maintains the heap invariant!
+
+To create a heap, use a list initialized to \code{[]}, or you can
+transform a populated list into a heap via function \function{heapify()}.
+
+The following functions are provided:
+
+\begin{funcdesc}{heappush}{heap, item}
+Push the value \var{item} onto the \var{heap}, maintaining the
+heap invariant.
+\end{funcdesc}
+
+\begin{funcdesc}{heappop}{heap}
+Pop and return the smallest item from the \var{heap}, maintaining the
+heap invariant.  If the heap is empty, \exception{IndexError} is raised.
+\end{funcdesc}
+
+\begin{funcdesc}{heapify}{x}
+Transform list \var{x} into a heap, in-place, in linear time.
+\end{funcdesc}
+
+\begin{funcdesc}{heapreplace}{heap, item}
+Pop and return the smallest item from the \var{heap}, and also push
+the new \var{item}.  The heap size doesn't change.
+If the heap is empty, \exception{IndexError} is raised.
+This is more efficient than \function{heappop()} followed
+by  \function{heappush()}, and can be more appropriate when using
+a fixed-size heap.  Note that the value returned may be larger
+than \var{item}!  That constrains reasonable uses of this routine
+unless written as part of a conditional replacement:
+\begin{verbatim}
+        if item > heap[0]:
+            item = heapreplace(heap, item)
+\end{verbatim}
+\end{funcdesc}
+
+Example of use:
+
+\begin{verbatim}
+>>> from heapq import heappush, heappop
+>>> heap = []
+>>> data = [1, 3, 5, 7, 9, 2, 4, 6, 8, 0]
+>>> for item in data:
+...     heappush(heap, item)
+...
+>>> ordered = []
+>>> while heap:
+...     ordered.append(heappop(heap))
+...
+>>> print ordered
+[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+>>> data.sort()
+>>> print data == ordered
+True
+>>>
+\end{verbatim}
+
+The module also offers two general purpose functions based on heaps.
+
+\begin{funcdesc}{nlargest}{n, iterable\optional{, key}}
+Return a list with the \var{n} largest elements from the dataset defined
+by \var{iterable}.  \var{key}, if provided, specifies a function of one
+argument that is used to extract a comparison key from each element
+in the iterable:  \samp{\var{key}=\function{str.lower}}
+Equivalent to:  \samp{sorted(iterable, key=key, reverse=True)[:n]}
+\versionadded{2.4}
+\versionchanged[Added the optional \var{key} argument]{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{nsmallest}{n, iterable\optional{, key}}
+Return a list with the \var{n} smallest elements from the dataset defined
+by \var{iterable}.  \var{key}, if provided, specifies a function of one
+argument that is used to extract a comparison key from each element
+in the iterable:  \samp{\var{key}=\function{str.lower}}
+Equivalent to:  \samp{sorted(iterable, key=key)[:n]}
+\versionadded{2.4}
+\versionchanged[Added the optional \var{key} argument]{2.5}
+\end{funcdesc}
+
+Both functions perform best for smaller values of \var{n}.  For larger
+values, it is more efficient to use the \function{sorted()} function.  Also,
+when \code{n==1}, it is more efficient to use the builtin \function{min()}
+and \function{max()} functions.
+
+
+\subsection{Theory}
+
+(This explanation is due to François Pinard.  The Python
+code for this module was contributed by Kevin O'Connor.)
+
+Heaps are arrays for which \code{a[\var{k}] <= a[2*\var{k}+1]} and
+\code{a[\var{k}] <= a[2*\var{k}+2]}
+for all \var{k}, counting elements from 0.  For the sake of comparison,
+non-existing elements are considered to be infinite.  The interesting
+property of a heap is that \code{a[0]} is always its smallest element.
+
+The strange invariant above is meant to be an efficient memory
+representation for a tournament.  The numbers below are \var{k}, not
+\code{a[\var{k}]}:
+
+\begin{verbatim}
+                                   0
+
+                  1                                 2
+
+          3               4                5               6
+
+      7       8       9       10      11      12      13      14
+
+    15 16   17 18   19 20   21 22   23 24   25 26   27 28   29 30
+\end{verbatim}
+
+In the tree above, each cell \var{k} is topping \code{2*\var{k}+1} and
+\code{2*\var{k}+2}.
+In an usual binary tournament we see in sports, each cell is the winner
+over the two cells it tops, and we can trace the winner down the tree
+to see all opponents s/he had.  However, in many computer applications
+of such tournaments, we do not need to trace the history of a winner.
+To be more memory efficient, when a winner is promoted, we try to
+replace it by something else at a lower level, and the rule becomes
+that a cell and the two cells it tops contain three different items,
+but the top cell "wins" over the two topped cells.
+
+If this heap invariant is protected at all time, index 0 is clearly
+the overall winner.  The simplest algorithmic way to remove it and
+find the "next" winner is to move some loser (let's say cell 30 in the
+diagram above) into the 0 position, and then percolate this new 0 down
+the tree, exchanging values, until the invariant is re-established.
+This is clearly logarithmic on the total number of items in the tree.
+By iterating over all items, you get an O(n log n) sort.
+
+A nice feature of this sort is that you can efficiently insert new
+items while the sort is going on, provided that the inserted items are
+not "better" than the last 0'th element you extracted.  This is
+especially useful in simulation contexts, where the tree holds all
+incoming events, and the "win" condition means the smallest scheduled
+time.  When an event schedule other events for execution, they are
+scheduled into the future, so they can easily go into the heap.  So, a
+heap is a good structure for implementing schedulers (this is what I
+used for my MIDI sequencer :-).
+
+Various structures for implementing schedulers have been extensively
+studied, and heaps are good for this, as they are reasonably speedy,
+the speed is almost constant, and the worst case is not much different
+than the average case.  However, there are other representations which
+are more efficient overall, yet the worst cases might be terrible.
+
+Heaps are also very useful in big disk sorts.  You most probably all
+know that a big sort implies producing "runs" (which are pre-sorted
+sequences, which size is usually related to the amount of CPU memory),
+followed by a merging passes for these runs, which merging is often
+very cleverly organised\footnote{The disk balancing algorithms which
+are current, nowadays, are
+more annoying than clever, and this is a consequence of the seeking
+capabilities of the disks.  On devices which cannot seek, like big
+tape drives, the story was quite different, and one had to be very
+clever to ensure (far in advance) that each tape movement will be the
+most effective possible (that is, will best participate at
+"progressing" the merge).  Some tapes were even able to read
+backwards, and this was also used to avoid the rewinding time.
+Believe me, real good tape sorts were quite spectacular to watch!
+From all times, sorting has always been a Great Art! :-)}.
+It is very important that the initial
+sort produces the longest runs possible.  Tournaments are a good way
+to that.  If, using all the memory available to hold a tournament, you
+replace and percolate items that happen to fit the current run, you'll
+produce runs which are twice the size of the memory for random input,
+and much better for input fuzzily ordered.
+
+Moreover, if you output the 0'th item on disk and get an input which
+may not fit in the current tournament (because the value "wins" over
+the last output value), it cannot fit in the heap, so the size of the
+heap decreases.  The freed memory could be cleverly reused immediately
+for progressively building a second heap, which grows at exactly the
+same rate the first heap is melting.  When the first heap completely
+vanishes, you switch heaps and start a new run.  Clever and quite
+effective!
+
+In a word, heaps are useful memory structures to know.  I use them in
+a few applications, and I think it is good to keep a `heap' module
+around. :-)

Added: vendor/Python/current/Doc/lib/libhmac.tex
===================================================================
--- vendor/Python/current/Doc/lib/libhmac.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libhmac.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,54 @@
+\section{\module{hmac} ---
+         Keyed-Hashing for Message Authentication}
+
+\declaremodule{standard}{hmac}
+\modulesynopsis{Keyed-Hashing for Message Authentication (HMAC)
+                implementation for Python.}
+\moduleauthor{Gerhard H{\"a}ring}{ghaering at users.sourceforge.net}
+\sectionauthor{Gerhard H{\"a}ring}{ghaering at users.sourceforge.net}
+
+\versionadded{2.2}
+
+This module implements the HMAC algorithm as described by \rfc{2104}.
+
+\begin{funcdesc}{new}{key\optional{, msg\optional{, digestmod}}}
+  Return a new hmac object.  If \var{msg} is present, the method call
+  \code{update(\var{msg})} is made. \var{digestmod} is the digest
+  constructor or module for the HMAC object to use. It defaults to 
+  the \code{\refmodule{hashlib}.md5} constructor.  \note{The md5 hash
+  has known weaknesses but remains the default for backwards compatibility.
+  Choose a better one for your application.}
+\end{funcdesc}
+
+An HMAC object has the following methods:
+
+\begin{methoddesc}[hmac]{update}{msg}
+  Update the hmac object with the string \var{msg}.  Repeated calls
+  are equivalent to a single call with the concatenation of all the
+  arguments: \code{m.update(a); m.update(b)} is equivalent to
+  \code{m.update(a + b)}.
+\end{methoddesc}
+
+\begin{methoddesc}[hmac]{digest}{}
+  Return the digest of the strings passed to the \method{update()}
+  method so far.  This string will be the same length as the
+  \var{digest_size} of the digest given to the constructor.  It
+  may contain non-\ASCII{} characters, including NUL bytes.
+\end{methoddesc}
+
+\begin{methoddesc}[hmac]{hexdigest}{}
+  Like \method{digest()} except the digest is returned as a string
+  twice the length containing
+  only hexadecimal digits.  This may be used to exchange the value
+  safely in email or other non-binary environments.
+\end{methoddesc}
+
+\begin{methoddesc}[hmac]{copy}{}
+  Return a copy (``clone'') of the hmac object.  This can be used to
+  efficiently compute the digests of strings that share a common
+  initial substring.
+\end{methoddesc}
+
+\begin{seealso}
+  \seemodule{hashlib}{The python module providing secure hash functions.}
+\end{seealso}

Added: vendor/Python/current/Doc/lib/libhotshot.tex
===================================================================
--- vendor/Python/current/Doc/lib/libhotshot.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libhotshot.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,137 @@
+\section{\module{hotshot} ---
+         High performance logging profiler}
+
+\declaremodule{standard}{hotshot}
+\modulesynopsis{High performance logging profiler, mostly written in C.}
+\moduleauthor{Fred L. Drake, Jr.}{fdrake at acm.org}
+\sectionauthor{Anthony Baxter}{anthony at interlink.com.au}
+
+\versionadded{2.2}
+
+
+This module provides a nicer interface to the \module{_hotshot} C module.
+Hotshot is a replacement for the existing \refmodule{profile} module. As it's
+written mostly in C, it should result in a much smaller performance impact
+than the existing \refmodule{profile} module.
+
+\begin{notice}[note]
+  The \module{hotshot} module focuses on minimizing the overhead
+  while profiling, at the expense of long data post-processing times.
+  For common usages it is recommended to use \module{cProfile} instead.
+  \module{hotshot} is not maintained and might be removed from the
+  standard library in the future.
+\end{notice}
+
+\versionchanged[the results should be more meaningful than in the
+past: the timing core contained a critical bug]{2.5}
+
+\begin{notice}[warning]
+  The \module{hotshot} profiler does not yet work well with threads.
+  It is useful to use an unthreaded script to run the profiler over
+  the code you're interested in measuring if at all possible.
+\end{notice}
+
+
+\begin{classdesc}{Profile}{logfile\optional{, lineevents\optional{,
+                           linetimings}}}
+The profiler object. The argument \var{logfile} is the name of a log
+file to use for logged profile data. The argument \var{lineevents}
+specifies whether to generate events for every source line, or just on
+function call/return. It defaults to \code{0} (only log function
+call/return). The argument \var{linetimings} specifies whether to
+record timing information. It defaults to \code{1} (store timing
+information).
+\end{classdesc}
+
+
+\subsection{Profile Objects \label{hotshot-objects}}
+
+Profile objects have the following methods:
+
+\begin{methoddesc}{addinfo}{key, value}
+Add an arbitrary labelled value to the profile output.
+\end{methoddesc}
+
+\begin{methoddesc}{close}{}
+Close the logfile and terminate the profiler.
+\end{methoddesc}
+
+\begin{methoddesc}{fileno}{}
+Return the file descriptor of the profiler's log file.
+\end{methoddesc}
+
+\begin{methoddesc}{run}{cmd}
+Profile an \keyword{exec}-compatible string in the script environment.
+The globals from the \refmodule[main]{__main__} module are used as
+both the globals and locals for the script.
+\end{methoddesc}
+
+\begin{methoddesc}{runcall}{func, *args, **keywords}
+Profile a single call of a callable.
+Additional positional and keyword arguments may be passed
+along; the result of the call is returned, and exceptions are
+allowed to propagate cleanly, while ensuring that profiling is
+disabled on the way out.
+\end{methoddesc}
+
+
+\begin{methoddesc}{runctx}{cmd, globals, locals}
+Evaluate an \keyword{exec}-compatible string in a specific environment.
+The string is compiled before profiling begins.
+\end{methoddesc}
+
+\begin{methoddesc}{start}{}
+Start the profiler.
+\end{methoddesc}
+
+\begin{methoddesc}{stop}{}
+Stop the profiler.
+\end{methoddesc}
+
+
+\subsection{Using hotshot data}
+
+\declaremodule{standard}{hotshot.stats}
+\modulesynopsis{Statistical analysis for Hotshot}
+
+\versionadded{2.2}
+
+This module loads hotshot profiling data into the standard \module{pstats}
+Stats objects.
+
+\begin{funcdesc}{load}{filename}
+Load hotshot data from \var{filename}. Returns an instance
+of the \class{pstats.Stats} class.
+\end{funcdesc}
+
+\begin{seealso}
+  \seemodule{profile}{The \module{profile} module's \class{Stats} class}
+\end{seealso}
+
+
+\subsection{Example Usage \label{hotshot-example}}
+
+Note that this example runs the python ``benchmark'' pystones.  It can
+take some time to run, and will produce large output files.
+
+\begin{verbatim}
+>>> import hotshot, hotshot.stats, test.pystone
+>>> prof = hotshot.Profile("stones.prof")
+>>> benchtime, stones = prof.runcall(test.pystone.pystones)
+>>> prof.close()
+>>> stats = hotshot.stats.load("stones.prof")
+>>> stats.strip_dirs()
+>>> stats.sort_stats('time', 'calls')
+>>> stats.print_stats(20)
+         850004 function calls in 10.090 CPU seconds
+
+   Ordered by: internal time, call count
+
+   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
+        1    3.295    3.295   10.090   10.090 pystone.py:79(Proc0)
+   150000    1.315    0.000    1.315    0.000 pystone.py:203(Proc7)
+    50000    1.313    0.000    1.463    0.000 pystone.py:229(Func2)
+ .
+ .
+ .
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/libhtmllib.tex
===================================================================
--- vendor/Python/current/Doc/lib/libhtmllib.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libhtmllib.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,181 @@
+\section{\module{htmllib} ---
+         A parser for HTML documents}
+
+\declaremodule{standard}{htmllib}
+\modulesynopsis{A parser for HTML documents.}
+
+\index{HTML}
+\index{hypertext}
+
+
+This module defines a class which can serve as a base for parsing text
+files formatted in the HyperText Mark-up Language (HTML).  The class
+is not directly concerned with I/O --- it must be provided with input
+in string form via a method, and makes calls to methods of a
+``formatter'' object in order to produce output.  The
+\class{HTMLParser} class is designed to be used as a base class for
+other classes in order to add functionality, and allows most of its
+methods to be extended or overridden.  In turn, this class is derived
+from and extends the \class{SGMLParser} class defined in module
+\refmodule{sgmllib}\refstmodindex{sgmllib}.  The \class{HTMLParser}
+implementation supports the HTML 2.0 language as described in
+\rfc{1866}.  Two implementations of formatter objects are provided in
+the \refmodule{formatter}\refstmodindex{formatter}\ module; refer to the
+documentation for that module for information on the formatter
+interface.
+\withsubitem{(in module sgmllib)}{\ttindex{SGMLParser}}
+
+The following is a summary of the interface defined by
+\class{sgmllib.SGMLParser}:
+
+\begin{itemize}
+
+\item
+The interface to feed data to an instance is through the \method{feed()}
+method, which takes a string argument.  This can be called with as
+little or as much text at a time as desired; \samp{p.feed(a);
+p.feed(b)} has the same effect as \samp{p.feed(a+b)}.  When the data
+contains complete HTML markup constructs, these are processed immediately;
+incomplete constructs are saved in a buffer.  To force processing of all
+unprocessed data, call the \method{close()} method.
+
+For example, to parse the entire contents of a file, use:
+\begin{verbatim}
+parser.feed(open('myfile.html').read())
+parser.close()
+\end{verbatim}
+
+\item
+The interface to define semantics for HTML tags is very simple: derive
+a class and define methods called \method{start_\var{tag}()},
+\method{end_\var{tag}()}, or \method{do_\var{tag}()}.  The parser will
+call these at appropriate moments: \method{start_\var{tag}} or
+\method{do_\var{tag}()} is called when an opening tag of the form
+\code{<\var{tag} ...>} is encountered; \method{end_\var{tag}()} is called
+when a closing tag of the form \code{<\var{tag}>} is encountered.  If
+an opening tag requires a corresponding closing tag, like \code{<H1>}
+... \code{</H1>}, the class should define the \method{start_\var{tag}()}
+method; if a tag requires no closing tag, like \code{<P>}, the class
+should define the \method{do_\var{tag}()} method.
+
+\end{itemize}
+
+The module defines a parser class and an exception:
+
+\begin{classdesc}{HTMLParser}{formatter}
+This is the basic HTML parser class.  It supports all entity names
+required by the XHTML 1.0 Recommendation (\url{http://www.w3.org/TR/xhtml1}).  
+It also defines handlers for all HTML 2.0 and many HTML 3.0 and 3.2 elements.
+\end{classdesc}
+
+\begin{excdesc}{HTMLParseError}
+Exception raised by the \class{HTMLParser} class when it encounters an
+error while parsing.
+\versionadded{2.4}
+\end{excdesc}
+
+
+\begin{seealso}
+  \seemodule{formatter}{Interface definition for transforming an
+                        abstract flow of formatting events into
+                        specific output events on writer objects.}
+  \seemodule{HTMLParser}{Alternate HTML parser that offers a slightly
+                         lower-level view of the input, but is
+                         designed to work with XHTML, and does not
+                         implement some of the SGML syntax not used in
+                         ``HTML as deployed'' and which isn't legal
+                         for XHTML.}
+  \seemodule{htmlentitydefs}{Definition of replacement text for XHTML 1.0 
+                             entities.}
+  \seemodule{sgmllib}{Base class for \class{HTMLParser}.}
+\end{seealso}
+
+
+\subsection{HTMLParser Objects \label{html-parser-objects}}
+
+In addition to tag methods, the \class{HTMLParser} class provides some
+additional methods and instance variables for use within tag methods.
+
+\begin{memberdesc}{formatter}
+This is the formatter instance associated with the parser.
+\end{memberdesc}
+
+\begin{memberdesc}{nofill}
+Boolean flag which should be true when whitespace should not be
+collapsed, or false when it should be.  In general, this should only
+be true when character data is to be treated as ``preformatted'' text,
+as within a \code{<PRE>} element.  The default value is false.  This
+affects the operation of \method{handle_data()} and \method{save_end()}.
+\end{memberdesc}
+
+
+\begin{methoddesc}{anchor_bgn}{href, name, type}
+This method is called at the start of an anchor region.  The arguments
+correspond to the attributes of the \code{<A>} tag with the same
+names.  The default implementation maintains a list of hyperlinks
+(defined by the \code{HREF} attribute for \code{<A>} tags) within the
+document.  The list of hyperlinks is available as the data attribute
+\member{anchorlist}.
+\end{methoddesc}
+
+\begin{methoddesc}{anchor_end}{}
+This method is called at the end of an anchor region.  The default
+implementation adds a textual footnote marker using an index into the
+list of hyperlinks created by \method{anchor_bgn()}.
+\end{methoddesc}
+
+\begin{methoddesc}{handle_image}{source, alt\optional{, ismap\optional{,
+                                 align\optional{, width\optional{, height}}}}}
+This method is called to handle images.  The default implementation
+simply passes the \var{alt} value to the \method{handle_data()}
+method.
+\end{methoddesc}
+
+\begin{methoddesc}{save_bgn}{}
+Begins saving character data in a buffer instead of sending it to the
+formatter object.  Retrieve the stored data via \method{save_end()}.
+Use of the \method{save_bgn()} / \method{save_end()} pair may not be
+nested.
+\end{methoddesc}
+
+\begin{methoddesc}{save_end}{}
+Ends buffering character data and returns all data saved since the
+preceding call to \method{save_bgn()}.  If the \member{nofill} flag is
+false, whitespace is collapsed to single spaces.  A call to this
+method without a preceding call to \method{save_bgn()} will raise a
+\exception{TypeError} exception.
+\end{methoddesc}
+
+
+
+\section{\module{htmlentitydefs} ---
+         Definitions of HTML general entities}
+
+\declaremodule{standard}{htmlentitydefs}
+\modulesynopsis{Definitions of HTML general entities.}
+\sectionauthor{Fred L. Drake, Jr.}{fdrake at acm.org}
+
+This module defines three dictionaries, \code{name2codepoint},
+\code{codepoint2name}, and \code{entitydefs}. \code{entitydefs} is
+used by the \refmodule{htmllib} module to provide the
+\member{entitydefs} member of the \class{HTMLParser} class.  The
+definition provided here contains all the entities defined by XHTML 1.0 
+that can be handled using simple textual substitution in the Latin-1
+character set (ISO-8859-1).
+
+
+\begin{datadesc}{entitydefs}
+  A dictionary mapping XHTML 1.0 entity definitions to their
+  replacement text in ISO Latin-1.
+
+\end{datadesc}
+
+\begin{datadesc}{name2codepoint}
+  A dictionary that maps HTML entity names to the Unicode codepoints.
+  \versionadded{2.3}
+\end{datadesc}
+
+\begin{datadesc}{codepoint2name}
+  A dictionary that maps Unicode codepoints to HTML entity names.
+  \versionadded{2.3}
+\end{datadesc}

Added: vendor/Python/current/Doc/lib/libhtmlparser.tex
===================================================================
--- vendor/Python/current/Doc/lib/libhtmlparser.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libhtmlparser.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,169 @@
+\section{\module{HTMLParser} ---
+         Simple HTML and XHTML parser}
+
+\declaremodule{standard}{HTMLParser}
+\modulesynopsis{A simple parser that can handle HTML and XHTML.}
+
+\versionadded{2.2}
+
+This module defines a class \class{HTMLParser} which serves as the
+basis for parsing text files formatted in HTML\index{HTML} (HyperText
+Mark-up Language) and XHTML.\index{XHTML}  Unlike the parser in
+\refmodule{htmllib}, this parser is not based on the SGML parser in
+\refmodule{sgmllib}.
+
+
+\begin{classdesc}{HTMLParser}{}
+The \class{HTMLParser} class is instantiated without arguments.
+
+An HTMLParser instance is fed HTML data and calls handler functions
+when tags begin and end.  The \class{HTMLParser} class is meant to be
+overridden by the user to provide a desired behavior.
+
+Unlike the parser in \refmodule{htmllib}, this parser does not check
+that end tags match start tags or call the end-tag handler for
+elements which are closed implicitly by closing an outer element.
+\end{classdesc}
+
+An exception is defined as well:
+
+\begin{excdesc}{HTMLParseError}
+Exception raised by the \class{HTMLParser} class when it encounters an
+error while parsing.  This exception provides three attributes:
+\member{msg} is a brief message explaining the error, \member{lineno}
+is the number of the line on which the broken construct was detected,
+and \member{offset} is the number of characters into the line at which
+the construct starts.
+\end{excdesc}
+
+
+\class{HTMLParser} instances have the following methods:
+
+\begin{methoddesc}{reset}{}
+Reset the instance.  Loses all unprocessed data.  This is called
+implicitly at instantiation time.
+\end{methoddesc}
+
+\begin{methoddesc}{feed}{data}
+Feed some text to the parser.  It is processed insofar as it consists
+of complete elements; incomplete data is buffered until more data is
+fed or \method{close()} is called.
+\end{methoddesc}
+
+\begin{methoddesc}{close}{}
+Force processing of all buffered data as if it were followed by an
+end-of-file mark.  This method may be redefined by a derived class to
+define additional processing at the end of the input, but the
+redefined version should always call the \class{HTMLParser} base class
+method \method{close()}.
+\end{methoddesc}
+
+\begin{methoddesc}{getpos}{}
+Return current line number and offset.
+\end{methoddesc}
+
+\begin{methoddesc}{get_starttag_text}{}
+Return the text of the most recently opened start tag.  This should
+not normally be needed for structured processing, but may be useful in
+dealing with HTML ``as deployed'' or for re-generating input with
+minimal changes (whitespace between attributes can be preserved,
+etc.).
+\end{methoddesc}
+
+\begin{methoddesc}{handle_starttag}{tag, attrs} 
+This method is called to handle the start of a tag.  It is intended to
+be overridden by a derived class; the base class implementation does
+nothing.  
+
+The \var{tag} argument is the name of the tag converted to
+lower case.  The \var{attrs} argument is a list of \code{(\var{name},
+\var{value})} pairs containing the attributes found inside the tag's
+\code{<>} brackets.  The \var{name} will be translated to lower case
+and double quotes and backslashes in the \var{value} have been
+interpreted.  For instance, for the tag \code{<A
+HREF="http://www.cwi.nl/">}, this method would be called as
+\samp{handle_starttag('a', [('href', 'http://www.cwi.nl/')])}.
+\end{methoddesc}
+
+\begin{methoddesc}{handle_startendtag}{tag, attrs}
+Similar to \method{handle_starttag()}, but called when the parser
+encounters an XHTML-style empty tag (\code{<a .../>}).  This method
+may be overridden by subclasses which require this particular lexical
+information; the default implementation simple calls
+\method{handle_starttag()} and \method{handle_endtag()}.
+\end{methoddesc}
+
+\begin{methoddesc}{handle_endtag}{tag}
+This method is called to handle the end tag of an element.  It is
+intended to be overridden by a derived class; the base class
+implementation does nothing.  The \var{tag} argument is the name of
+the tag converted to lower case.
+\end{methoddesc}
+
+\begin{methoddesc}{handle_data}{data}
+This method is called to process arbitrary data.  It is intended to be
+overridden by a derived class; the base class implementation does
+nothing.
+\end{methoddesc}
+
+\begin{methoddesc}{handle_charref}{name} This method is called to
+process a character reference of the form \samp{\&\#\var{ref};}.  It
+is intended to be overridden by a derived class; the base class
+implementation does nothing.  
+\end{methoddesc}
+
+\begin{methoddesc}{handle_entityref}{name} 
+This method is called to process a general entity reference of the
+form \samp{\&\var{name};} where \var{name} is an general entity
+reference.  It is intended to be overridden by a derived class; the
+base class implementation does nothing.
+\end{methoddesc}
+
+\begin{methoddesc}{handle_comment}{data}
+This method is called when a comment is encountered.  The
+\var{comment} argument is a string containing the text between the
+\samp{--} and \samp{--} delimiters, but not the delimiters
+themselves.  For example, the comment \samp{<!--text-->} will
+cause this method to be called with the argument \code{'text'}.  It is
+intended to be overridden by a derived class; the base class
+implementation does nothing.
+\end{methoddesc}
+
+\begin{methoddesc}{handle_decl}{decl}
+Method called when an SGML declaration is read by the parser.  The
+\var{decl} parameter will be the entire contents of the declaration
+inside the \code{<!}...\code{>} markup.  It is intended to be overridden
+by a derived class; the base class implementation does nothing.
+\end{methoddesc}
+
+\begin{methoddesc}{handle_pi}{data}
+Method called when a processing instruction is encountered.  The
+\var{data} parameter will contain the entire processing instruction.
+For example, for the processing instruction \code{<?proc color='red'>},
+this method would be called as \code{handle_pi("proc color='red'")}.  It
+is intended to be overridden by a derived class; the base class
+implementation does nothing.
+
+\note{The \class{HTMLParser} class uses the SGML syntactic rules for
+processing instructions.  An XHTML processing instruction using the
+trailing \character{?} will cause the \character{?} to be included in
+\var{data}.}
+\end{methoddesc}
+
+
+\subsection{Example HTML Parser Application \label{htmlparser-example}}
+
+As a basic example, below is a very basic HTML parser that uses the
+\class{HTMLParser} class to print out tags as they are encountered:
+
+\begin{verbatim}
+from HTMLParser import HTMLParser
+
+class MyHTMLParser(HTMLParser):
+
+    def handle_starttag(self, tag, attrs):
+        print "Encountered the beginning of a %s tag" % tag
+
+    def handle_endtag(self, tag):
+        print "Encountered the end of a %s tag" % tag
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/libhttplib.tex
===================================================================
--- vendor/Python/current/Doc/lib/libhttplib.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libhttplib.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,434 @@
+\section{\module{httplib} ---
+         HTTP protocol client}
+
+\declaremodule{standard}{httplib}
+\modulesynopsis{HTTP and HTTPS protocol client (requires sockets).}
+
+\indexii{HTTP}{protocol}
+\index{HTTP!\module{httplib} (standard module)}
+
+This module defines classes which implement the client side of the
+HTTP and HTTPS protocols.  It is normally not used directly --- the
+module \refmodule{urllib}\refstmodindex{urllib} uses it to handle URLs
+that use HTTP and HTTPS.
+
+\begin{notice}
+  HTTPS support is only available if the \refmodule{socket} module was
+  compiled with SSL support.
+\end{notice}
+
+\begin{notice}
+  The public interface for this module changed substantially in Python
+  2.0.  The \class{HTTP} class is retained only for backward
+  compatibility with 1.5.2.  It should not be used in new code.  Refer
+  to the online docstrings for usage.
+\end{notice}
+
+The module provides the following classes:
+
+\begin{classdesc}{HTTPConnection}{host\optional{, port}}
+An \class{HTTPConnection} instance represents one transaction with an HTTP
+server.  It should be instantiated passing it a host and optional port number.
+If no port number is passed, the port is extracted from the host string if it
+has the form \code{\var{host}:\var{port}}, else the default HTTP port (80) is
+used.  For example, the following calls all create instances that connect to
+the server at the same host and port:
+
+\begin{verbatim}
+>>> h1 = httplib.HTTPConnection('www.cwi.nl')
+>>> h2 = httplib.HTTPConnection('www.cwi.nl:80')
+>>> h3 = httplib.HTTPConnection('www.cwi.nl', 80)
+\end{verbatim}
+\versionadded{2.0}
+\end{classdesc}
+
+\begin{classdesc}{HTTPSConnection}{host\optional{, port, key_file, cert_file}}
+A subclass of \class{HTTPConnection} that uses SSL for communication with
+secure servers.  Default port is \code{443}.
+\var{key_file} is
+the name of a PEM formatted file that contains your private
+key. \var{cert_file} is a PEM formatted certificate chain file.
+
+\warning{This does not do any certificate verification!}
+
+\versionadded{2.0}
+\end{classdesc}
+
+\begin{classdesc}{HTTPResponse}{sock\optional{, debuglevel=0}\optional{, strict=0}}
+Class whose instances are returned upon successful connection.  Not
+instantiated directly by user.
+\versionadded{2.0}
+\end{classdesc}
+
+The following exceptions are raised as appropriate:
+
+\begin{excdesc}{HTTPException}
+The base class of the other exceptions in this module.  It is a
+subclass of \exception{Exception}.
+\versionadded{2.0}
+\end{excdesc}
+
+\begin{excdesc}{NotConnected}
+A subclass of \exception{HTTPException}.
+\versionadded{2.0}
+\end{excdesc}
+
+\begin{excdesc}{InvalidURL}
+A subclass of \exception{HTTPException}, raised if a port is given and is
+either non-numeric or empty.
+\versionadded{2.3}
+\end{excdesc}
+
+\begin{excdesc}{UnknownProtocol}
+A subclass of \exception{HTTPException}.
+\versionadded{2.0}
+\end{excdesc}
+
+\begin{excdesc}{UnknownTransferEncoding}
+A subclass of \exception{HTTPException}.
+\versionadded{2.0}
+\end{excdesc}
+
+\begin{excdesc}{UnimplementedFileMode}
+A subclass of \exception{HTTPException}.
+\versionadded{2.0}
+\end{excdesc}
+
+\begin{excdesc}{IncompleteRead}
+A subclass of \exception{HTTPException}.
+\versionadded{2.0}
+\end{excdesc}
+
+\begin{excdesc}{ImproperConnectionState}
+A subclass of \exception{HTTPException}.
+\versionadded{2.0}
+\end{excdesc}
+
+\begin{excdesc}{CannotSendRequest}
+A subclass of \exception{ImproperConnectionState}.
+\versionadded{2.0}
+\end{excdesc}
+
+\begin{excdesc}{CannotSendHeader}
+A subclass of \exception{ImproperConnectionState}.
+\versionadded{2.0}
+\end{excdesc}
+
+\begin{excdesc}{ResponseNotReady}
+A subclass of \exception{ImproperConnectionState}.
+\versionadded{2.0}
+\end{excdesc}
+
+\begin{excdesc}{BadStatusLine}
+A subclass of \exception{HTTPException}.  Raised if a server responds with a
+HTTP status code that we don't understand.
+\versionadded{2.0}
+\end{excdesc}
+
+The constants defined in this module are:
+
+\begin{datadesc}{HTTP_PORT}
+  The default port for the HTTP protocol (always \code{80}).
+\end{datadesc}
+
+\begin{datadesc}{HTTPS_PORT}
+  The default port for the HTTPS protocol (always \code{443}).
+\end{datadesc}
+
+and also the following constants for integer status codes:
+
+\begin{tableiii}{l|c|l}{constant}{Constant}{Value}{Definition}
+  \lineiii{CONTINUE}{\code{100}}
+    {HTTP/1.1, \ulink{RFC 2616, Section 10.1.1}
+      {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.1.1}}
+  \lineiii{SWITCHING_PROTOCOLS}{\code{101}}
+    {HTTP/1.1, \ulink{RFC 2616, Section 10.1.2}
+      {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.1.2}}
+  \lineiii{PROCESSING}{\code{102}}
+    {WEBDAV, \ulink{RFC 2518, Section 10.1}
+      {http://www.webdav.org/specs/rfc2518.html#STATUS_102}}
+
+  \lineiii{OK}{\code{200}}
+    {HTTP/1.1, \ulink{RFC 2616, Section 10.2.1}
+      {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.1}}
+  \lineiii{CREATED}{\code{201}}
+    {HTTP/1.1, \ulink{RFC 2616, Section 10.2.2}
+      {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.2}}
+  \lineiii{ACCEPTED}{\code{202}}
+    {HTTP/1.1, \ulink{RFC 2616, Section 10.2.3}
+      {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.3}}
+  \lineiii{NON_AUTHORITATIVE_INFORMATION}{\code{203}}
+    {HTTP/1.1, \ulink{RFC 2616, Section 10.2.4}
+      {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.4}}
+  \lineiii{NO_CONTENT}{\code{204}}
+    {HTTP/1.1, \ulink{RFC 2616, Section 10.2.5}
+      {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.5}}
+  \lineiii{RESET_CONTENT}{\code{205}}
+    {HTTP/1.1, \ulink{RFC 2616, Section 10.2.6}
+      {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.6}}
+  \lineiii{PARTIAL_CONTENT}{\code{206}}
+    {HTTP/1.1, \ulink{RFC 2616, Section 10.2.7}
+      {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.7}}
+  \lineiii{MULTI_STATUS}{\code{207}}
+    {WEBDAV \ulink{RFC 2518, Section 10.2}
+      {http://www.webdav.org/specs/rfc2518.html#STATUS_207}}
+  \lineiii{IM_USED}{\code{226}}
+    {Delta encoding in HTTP, \rfc{3229}, Section 10.4.1}
+
+  \lineiii{MULTIPLE_CHOICES}{\code{300}}
+    {HTTP/1.1, \ulink{RFC 2616, Section 10.3.1}
+      {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.1}}
+  \lineiii{MOVED_PERMANENTLY}{\code{301}}
+    {HTTP/1.1, \ulink{RFC 2616, Section 10.3.2}
+      {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.2}}
+  \lineiii{FOUND}{\code{302}}
+    {HTTP/1.1, \ulink{RFC 2616, Section 10.3.3}
+      {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.3}}
+  \lineiii{SEE_OTHER}{\code{303}}
+    {HTTP/1.1, \ulink{RFC 2616, Section 10.3.4}
+      {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.4}}
+  \lineiii{NOT_MODIFIED}{\code{304}}
+    {HTTP/1.1, \ulink{RFC 2616, Section 10.3.5}
+      {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.5}}
+  \lineiii{USE_PROXY}{\code{305}}
+    {HTTP/1.1, \ulink{RFC 2616, Section 10.3.6}
+      {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.6}}
+  \lineiii{TEMPORARY_REDIRECT}{\code{307}}
+    {HTTP/1.1, \ulink{RFC 2616, Section 10.3.8}
+      {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.8}}
+
+  \lineiii{BAD_REQUEST}{\code{400}}
+    {HTTP/1.1, \ulink{RFC 2616, Section 10.4.1}
+      {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.1}}
+  \lineiii{UNAUTHORIZED}{\code{401}}
+    {HTTP/1.1, \ulink{RFC 2616, Section 10.4.2}
+      {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2}}
+  \lineiii{PAYMENT_REQUIRED}{\code{402}}
+    {HTTP/1.1, \ulink{RFC 2616, Section 10.4.3}
+      {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.3}}
+  \lineiii{FORBIDDEN}{\code{403}}
+    {HTTP/1.1, \ulink{RFC 2616, Section 10.4.4}
+      {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.4}}
+  \lineiii{NOT_FOUND}{\code{404}}
+    {HTTP/1.1, \ulink{RFC 2616, Section 10.4.5}
+      {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.5}}
+  \lineiii{METHOD_NOT_ALLOWED}{\code{405}}
+    {HTTP/1.1, \ulink{RFC 2616, Section 10.4.6}
+      {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.6}}
+  \lineiii{NOT_ACCEPTABLE}{\code{406}}
+    {HTTP/1.1, \ulink{RFC 2616, Section 10.4.7}
+      {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.7}}
+  \lineiii{PROXY_AUTHENTICATION_REQUIRED}
+    {\code{407}}{HTTP/1.1, \ulink{RFC 2616, Section 10.4.8}
+      {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.8}}
+  \lineiii{REQUEST_TIMEOUT}{\code{408}}
+    {HTTP/1.1, \ulink{RFC 2616, Section 10.4.9}
+      {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.9}}
+  \lineiii{CONFLICT}{\code{409}}
+    {HTTP/1.1, \ulink{RFC 2616, Section 10.4.10}
+      {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.10}}
+  \lineiii{GONE}{\code{410}}
+    {HTTP/1.1, \ulink{RFC 2616, Section 10.4.11}
+      {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.11}}
+  \lineiii{LENGTH_REQUIRED}{\code{411}}
+    {HTTP/1.1, \ulink{RFC 2616, Section 10.4.12}
+      {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.12}}
+  \lineiii{PRECONDITION_FAILED}{\code{412}}
+    {HTTP/1.1, \ulink{RFC 2616, Section 10.4.13}
+      {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.13}}
+  \lineiii{REQUEST_ENTITY_TOO_LARGE}
+    {\code{413}}{HTTP/1.1, \ulink{RFC 2616, Section 10.4.14}
+      {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.14}}
+  \lineiii{REQUEST_URI_TOO_LONG}{\code{414}}
+    {HTTP/1.1, \ulink{RFC 2616, Section 10.4.15}
+      {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.15}}
+  \lineiii{UNSUPPORTED_MEDIA_TYPE}{\code{415}}
+    {HTTP/1.1, \ulink{RFC 2616, Section 10.4.16}
+      {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.16}}
+  \lineiii{REQUESTED_RANGE_NOT_SATISFIABLE}{\code{416}}
+    {HTTP/1.1, \ulink{RFC 2616, Section 10.4.17}
+      {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.17}}
+  \lineiii{EXPECTATION_FAILED}{\code{417}}
+    {HTTP/1.1, \ulink{RFC 2616, Section 10.4.18}
+      {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.18}}
+  \lineiii{UNPROCESSABLE_ENTITY}{\code{422}}
+    {WEBDAV, \ulink{RFC 2518, Section 10.3}
+      {http://www.webdav.org/specs/rfc2518.html#STATUS_422}}
+  \lineiii{LOCKED}{\code{423}}
+    {WEBDAV \ulink{RFC 2518, Section 10.4}
+      {http://www.webdav.org/specs/rfc2518.html#STATUS_423}}
+  \lineiii{FAILED_DEPENDENCY}{\code{424}}
+    {WEBDAV, \ulink{RFC 2518, Section 10.5}
+      {http://www.webdav.org/specs/rfc2518.html#STATUS_424}}
+  \lineiii{UPGRADE_REQUIRED}{\code{426}}
+    {HTTP Upgrade to TLS, \rfc{2817}, Section 6}
+
+  \lineiii{INTERNAL_SERVER_ERROR}{\code{500}}
+    {HTTP/1.1, \ulink{RFC 2616, Section 10.5.1}
+      {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.1}}
+  \lineiii{NOT_IMPLEMENTED}{\code{501}}
+    {HTTP/1.1, \ulink{RFC 2616, Section 10.5.2}
+      {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.2}}
+  \lineiii{BAD_GATEWAY}{\code{502}}
+    {HTTP/1.1 \ulink{RFC 2616, Section 10.5.3}
+      {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.3}}
+  \lineiii{SERVICE_UNAVAILABLE}{\code{503}}
+    {HTTP/1.1, \ulink{RFC 2616, Section 10.5.4}
+      {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.4}}
+  \lineiii{GATEWAY_TIMEOUT}{\code{504}}
+    {HTTP/1.1 \ulink{RFC 2616, Section 10.5.5}
+      {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.5}}
+  \lineiii{HTTP_VERSION_NOT_SUPPORTED}{\code{505}}
+    {HTTP/1.1, \ulink{RFC 2616, Section 10.5.6}
+      {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.6}}
+  \lineiii{INSUFFICIENT_STORAGE}{\code{507}}
+    {WEBDAV, \ulink{RFC 2518, Section 10.6}
+      {http://www.webdav.org/specs/rfc2518.html#STATUS_507}}
+  \lineiii{NOT_EXTENDED}{\code{510}}
+    {An HTTP Extension Framework, \rfc{2774}, Section 7}
+\end{tableiii}
+
+\begin{datadesc}{responses}
+This dictionary maps the HTTP 1.1 status codes to the W3C names.
+
+Example: \code{httplib.responses[httplib.NOT_FOUND]} is \code{'Not Found'}.
+\versionadded{2.5}
+\end{datadesc}
+
+
+\subsection{HTTPConnection Objects \label{httpconnection-objects}}
+
+\class{HTTPConnection} instances have the following methods:
+
+\begin{methoddesc}{request}{method, url\optional{, body\optional{, headers}}}
+This will send a request to the server using the HTTP request method
+\var{method} and the selector \var{url}.  If the \var{body} argument is
+present, it should be a string of data to send after the headers are finished.
+The header Content-Length is automatically set to the correct value.
+The \var{headers} argument should be a mapping of extra HTTP headers to send
+with the request.
+\end{methoddesc}
+
+\begin{methoddesc}{getresponse}{}
+Should be called after a request is sent to get the response from the server.
+Returns an \class{HTTPResponse} instance.
+\note{Note that you must have read the whole response before you can send a new
+request to the server.}
+\end{methoddesc}
+
+\begin{methoddesc}{set_debuglevel}{level}
+Set the debugging level (the amount of debugging output printed).
+The default debug level is \code{0}, meaning no debugging output is
+printed.
+\end{methoddesc}
+
+\begin{methoddesc}{connect}{}
+Connect to the server specified when the object was created.
+\end{methoddesc}
+
+\begin{methoddesc}{close}{}
+Close the connection to the server.
+\end{methoddesc}
+
+As an alternative to using the \method{request()} method described above,
+you can also send your request step by step, by using the four functions
+below.
+
+\begin{methoddesc}{putrequest}{request, selector\optional{,
+skip\_host\optional{, skip_accept_encoding}}}
+This should be the first call after the connection to the server has
+been made.  It sends a line to the server consisting of the
+\var{request} string, the \var{selector} string, and the HTTP version
+(\code{HTTP/1.1}).  To disable automatic sending of \code{Host:} or
+\code{Accept-Encoding:} headers (for example to accept additional
+content encodings), specify \var{skip_host} or \var{skip_accept_encoding}
+with non-False values.
+\versionchanged[\var{skip_accept_encoding} argument added]{2.4}
+\end{methoddesc}
+
+\begin{methoddesc}{putheader}{header, argument\optional{, ...}}
+Send an \rfc{822}-style header to the server.  It sends a line to the
+server consisting of the header, a colon and a space, and the first
+argument.  If more arguments are given, continuation lines are sent,
+each consisting of a tab and an argument.
+\end{methoddesc}
+
+\begin{methoddesc}{endheaders}{}
+Send a blank line to the server, signalling the end of the headers.
+\end{methoddesc}
+
+\begin{methoddesc}{send}{data}
+Send data to the server.  This should be used directly only after the
+\method{endheaders()} method has been called and before
+\method{getresponse()} is called.
+\end{methoddesc}
+
+\subsection{HTTPResponse Objects \label{httpresponse-objects}}
+
+\class{HTTPResponse} instances have the following methods and attributes:
+
+\begin{methoddesc}{read}{\optional{amt}}
+Reads and returns the response body, or up to the next \var{amt} bytes.
+\end{methoddesc}
+
+\begin{methoddesc}{getheader}{name\optional{, default}}
+Get the contents of the header \var{name}, or \var{default} if there is no
+matching header.
+\end{methoddesc}
+
+\begin{methoddesc}{getheaders}{}
+Return a list of (header, value) tuples. \versionadded{2.4}
+\end{methoddesc}
+
+\begin{datadesc}{msg}
+  A \class{mimetools.Message} instance containing the response headers.
+\end{datadesc}
+
+\begin{datadesc}{version}
+  HTTP protocol version used by server.  10 for HTTP/1.0, 11 for HTTP/1.1.
+\end{datadesc}
+
+\begin{datadesc}{status}
+  Status code returned by server.
+\end{datadesc}
+
+\begin{datadesc}{reason}
+  Reason phrase returned by server.
+\end{datadesc}
+
+
+\subsection{Examples \label{httplib-examples}}
+
+Here is an example session that uses the \samp{GET} method:
+
+\begin{verbatim}
+>>> import httplib
+>>> conn = httplib.HTTPConnection("www.python.org")
+>>> conn.request("GET", "/index.html")
+>>> r1 = conn.getresponse()
+>>> print r1.status, r1.reason
+200 OK
+>>> data1 = r1.read()
+>>> conn.request("GET", "/parrot.spam")
+>>> r2 = conn.getresponse()
+>>> print r2.status, r2.reason
+404 Not Found
+>>> data2 = r2.read()
+>>> conn.close()
+\end{verbatim}
+
+Here is an example session that shows how to \samp{POST} requests:
+
+\begin{verbatim}
+>>> import httplib, urllib
+>>> params = urllib.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})
+>>> headers = {"Content-type": "application/x-www-form-urlencoded",
+...            "Accept": "text/plain"}
+>>> conn = httplib.HTTPConnection("musi-cal.mojam.com:80")
+>>> conn.request("POST", "/cgi-bin/query", params, headers)
+>>> response = conn.getresponse()
+>>> print response.status, response.reason
+200 OK
+>>> data = response.read()
+>>> conn.close()
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/libimageop.tex
===================================================================
--- vendor/Python/current/Doc/lib/libimageop.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libimageop.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,100 @@
+\section{\module{imageop} ---
+         Manipulate raw image data}
+
+\declaremodule{builtin}{imageop}
+\modulesynopsis{Manipulate raw image data.}
+
+
+The \module{imageop} module contains some useful operations on images.
+It operates on images consisting of 8 or 32 bit pixels stored in
+Python strings.  This is the same format as used by
+\function{gl.lrectwrite()} and the \refmodule{imgfile} module.
+
+The module defines the following variables and functions:
+
+\begin{excdesc}{error}
+This exception is raised on all errors, such as unknown number of bits
+per pixel, etc.
+\end{excdesc}
+
+
+\begin{funcdesc}{crop}{image, psize, width, height, x0, y0, x1, y1}
+Return the selected part of \var{image}, which should be
+\var{width} by \var{height} in size and consist of pixels of
+\var{psize} bytes. \var{x0}, \var{y0}, \var{x1} and \var{y1} are like
+the \function{gl.lrectread()} parameters, i.e.\ the boundary is
+included in the new image.  The new boundaries need not be inside the
+picture.  Pixels that fall outside the old image will have their value
+set to zero.  If \var{x0} is bigger than \var{x1} the new image is
+mirrored.  The same holds for the y coordinates.
+\end{funcdesc}
+
+\begin{funcdesc}{scale}{image, psize, width, height, newwidth, newheight}
+Return \var{image} scaled to size \var{newwidth} by \var{newheight}.
+No interpolation is done, scaling is done by simple-minded pixel
+duplication or removal.  Therefore, computer-generated images or
+dithered images will not look nice after scaling.
+\end{funcdesc}
+
+\begin{funcdesc}{tovideo}{image, psize, width, height}
+Run a vertical low-pass filter over an image.  It does so by computing
+each destination pixel as the average of two vertically-aligned source
+pixels.  The main use of this routine is to forestall excessive
+flicker if the image is displayed on a video device that uses
+interlacing, hence the name.
+\end{funcdesc}
+
+\begin{funcdesc}{grey2mono}{image, width, height, threshold}
+Convert a 8-bit deep greyscale image to a 1-bit deep image by
+thresholding all the pixels.  The resulting image is tightly packed and
+is probably only useful as an argument to \function{mono2grey()}.
+\end{funcdesc}
+
+\begin{funcdesc}{dither2mono}{image, width, height}
+Convert an 8-bit greyscale image to a 1-bit monochrome image using a
+(simple-minded) dithering algorithm.
+\end{funcdesc}
+
+\begin{funcdesc}{mono2grey}{image, width, height, p0, p1}
+Convert a 1-bit monochrome image to an 8 bit greyscale or color image.
+All pixels that are zero-valued on input get value \var{p0} on output
+and all one-value input pixels get value \var{p1} on output.  To
+convert a monochrome black-and-white image to greyscale pass the
+values \code{0} and \code{255} respectively.
+\end{funcdesc}
+
+\begin{funcdesc}{grey2grey4}{image, width, height}
+Convert an 8-bit greyscale image to a 4-bit greyscale image without
+dithering.
+\end{funcdesc}
+
+\begin{funcdesc}{grey2grey2}{image, width, height}
+Convert an 8-bit greyscale image to a 2-bit greyscale image without
+dithering.
+\end{funcdesc}
+
+\begin{funcdesc}{dither2grey2}{image, width, height}
+Convert an 8-bit greyscale image to a 2-bit greyscale image with
+dithering.  As for \function{dither2mono()}, the dithering algorithm
+is currently very simple.
+\end{funcdesc}
+
+\begin{funcdesc}{grey42grey}{image, width, height}
+Convert a 4-bit greyscale image to an 8-bit greyscale image.
+\end{funcdesc}
+
+\begin{funcdesc}{grey22grey}{image, width, height}
+Convert a 2-bit greyscale image to an 8-bit greyscale image.
+\end{funcdesc}
+
+\begin{datadesc}{backward_compatible}
+If set to 0, the functions in this module use a non-backward
+compatible way of representing multi-byte pixels on little-endian
+systems.  The SGI for which this module was originally written is a
+big-endian system, so setting this variable will have no effect.
+However, the code wasn't originally intended to run on anything else,
+so it made assumptions about byte order which are not universal.
+Setting this variable to 0 will cause the byte order to be reversed on
+little-endian systems, so that it then is the same as on big-endian
+systems.
+\end{datadesc}

Added: vendor/Python/current/Doc/lib/libimaplib.tex
===================================================================
--- vendor/Python/current/Doc/lib/libimaplib.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libimaplib.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,507 @@
+\section{\module{imaplib} ---
+         IMAP4 protocol client}
+
+\declaremodule{standard}{imaplib}
+\modulesynopsis{IMAP4 protocol client (requires sockets).}
+\moduleauthor{Piers Lauder}{piers at communitysolutions.com.au}
+\sectionauthor{Piers Lauder}{piers at communitysolutions.com.au}
+
+% Based on HTML documentation by Piers Lauder
+% <piers at communitysolutions.com.au>;
+% converted by Fred L. Drake, Jr. <fdrake at acm.org>.
+% Revised by ESR, January 2000.
+% Changes for IMAP4_SSL by Tino Lange <Tino.Lange at isg.de>, March 2002 
+% Changes for IMAP4_stream by Piers Lauder
+% <piers at communitysolutions.com.au>, November 2002
+
+\indexii{IMAP4}{protocol}
+\indexii{IMAP4_SSL}{protocol}
+\indexii{IMAP4_stream}{protocol}
+
+This module defines three classes, \class{IMAP4}, \class{IMAP4_SSL}
+and \class{IMAP4_stream}, which encapsulate a
+connection to an IMAP4 server and implement a large subset of the
+IMAP4rev1 client protocol as defined in \rfc{2060}. It is backward
+compatible with IMAP4 (\rfc{1730}) servers, but note that the
+\samp{STATUS} command is not supported in IMAP4.
+
+Three classes are provided by the \module{imaplib} module,
+\class{IMAP4} is the base class:
+
+\begin{classdesc}{IMAP4}{\optional{host\optional{, port}}}
+This class implements the actual IMAP4 protocol.  The connection is
+created and protocol version (IMAP4 or IMAP4rev1) is determined when
+the instance is initialized.
+If \var{host} is not specified, \code{''} (the local host) is used.
+If \var{port} is omitted, the standard IMAP4 port (143) is used.
+\end{classdesc}
+
+Three exceptions are defined as attributes of the \class{IMAP4} class:
+
+\begin{excdesc}{IMAP4.error}
+Exception raised on any errors.  The reason for the exception is
+passed to the constructor as a string.
+\end{excdesc}
+
+\begin{excdesc}{IMAP4.abort}
+IMAP4 server errors cause this exception to be raised.  This is a
+sub-class of \exception{IMAP4.error}.  Note that closing the instance
+and instantiating a new one will usually allow recovery from this
+exception.
+\end{excdesc}
+
+\begin{excdesc}{IMAP4.readonly}
+This exception is raised when a writable mailbox has its status
+changed by the server.  This is a sub-class of
+\exception{IMAP4.error}.  Some other client now has write permission,
+and the mailbox will need to be re-opened to re-obtain write
+permission.
+\end{excdesc}
+
+There's also a subclass for secure connections:
+
+\begin{classdesc}{IMAP4_SSL}{\optional{host\optional{, port\optional{,
+                             keyfile\optional{, certfile}}}}}
+This is a subclass derived from \class{IMAP4} that connects over an
+SSL encrypted socket (to use this class you need a socket module that
+was compiled with SSL support).  If \var{host} is not specified,
+\code{''} (the local host) is used.  If \var{port} is omitted, the
+standard IMAP4-over-SSL port (993) is used.  \var{keyfile} and
+\var{certfile} are also optional - they can contain a PEM formatted
+private key and certificate chain file for the SSL connection.
+\end{classdesc}
+
+The second subclass allows for connections created by a child process:
+
+\begin{classdesc}{IMAP4_stream}{command}
+This is a subclass derived from \class{IMAP4} that connects
+to the \code{stdin/stdout} file descriptors created by passing
+\var{command} to \code{os.popen2()}.
+\versionadded{2.3}
+\end{classdesc}
+
+The following utility functions are defined:
+
+\begin{funcdesc}{Internaldate2tuple}{datestr}
+  Converts an IMAP4 INTERNALDATE string to Coordinated Universal
+  Time. Returns a \refmodule{time} module tuple.
+\end{funcdesc}
+
+\begin{funcdesc}{Int2AP}{num}
+  Converts an integer into a string representation using characters
+  from the set [\code{A} .. \code{P}].
+\end{funcdesc}
+
+\begin{funcdesc}{ParseFlags}{flagstr}
+  Converts an IMAP4 \samp{FLAGS} response to a tuple of individual
+  flags.
+\end{funcdesc}
+
+\begin{funcdesc}{Time2Internaldate}{date_time}
+  Converts a \refmodule{time} module tuple to an IMAP4
+  \samp{INTERNALDATE} representation.  Returns a string in the form:
+  \code{"DD-Mmm-YYYY HH:MM:SS +HHMM"} (including double-quotes).
+\end{funcdesc}
+
+
+Note that IMAP4 message numbers change as the mailbox changes; in
+particular, after an \samp{EXPUNGE} command performs deletions the
+remaining messages are renumbered. So it is highly advisable to use
+UIDs instead, with the UID command.
+
+At the end of the module, there is a test section that contains a more
+extensive example of usage.
+
+\begin{seealso}
+  \seetext{Documents describing the protocol, and sources and binaries 
+           for servers implementing it, can all be found at the
+           University of Washington's \emph{IMAP Information Center}
+           (\url{http://www.cac.washington.edu/imap/}).}
+\end{seealso}
+
+
+\subsection{IMAP4 Objects \label{imap4-objects}}
+
+All IMAP4rev1 commands are represented by methods of the same name,
+either upper-case or lower-case.
+
+All arguments to commands are converted to strings, except for
+\samp{AUTHENTICATE}, and the last argument to \samp{APPEND} which is
+passed as an IMAP4 literal.  If necessary (the string contains IMAP4
+protocol-sensitive characters and isn't enclosed with either
+parentheses or double quotes) each string is quoted. However, the
+\var{password} argument to the \samp{LOGIN} command is always quoted.
+If you want to avoid having an argument string quoted
+(eg: the \var{flags} argument to \samp{STORE}) then enclose the string in
+parentheses (eg: \code{r'(\e Deleted)'}).
+
+Each command returns a tuple: \code{(\var{type}, [\var{data},
+...])} where \var{type} is usually \code{'OK'} or \code{'NO'},
+and \var{data} is either the text from the command response, or
+mandated results from the command. Each \var{data}
+is either a string, or a tuple. If a tuple, then the first part
+is the header of the response, and the second part contains
+the data (ie: 'literal' value).
+
+The \var{message_set} options to commands below is a string specifying one
+or more messages to be acted upon.  It may be a simple message number
+(\code{'1'}), a range of message numbers (\code{'2:4'}), or a group of
+non-contiguous ranges separated by commas (\code{'1:3,6:9'}).  A range
+can contain an asterisk to indicate an infinite upper bound
+(\code{'3:*'}).
+
+An \class{IMAP4} instance has the following methods:
+
+
+\begin{methoddesc}{append}{mailbox, flags, date_time, message}
+  Append \var{message} to named mailbox. 
+\end{methoddesc}
+
+\begin{methoddesc}{authenticate}{mechanism, authobject}
+  Authenticate command --- requires response processing.
+
+  \var{mechanism} specifies which authentication mechanism is to be
+  used - it should appear in the instance variable \code{capabilities}
+  in the form \code{AUTH=mechanism}.
+
+  \var{authobject} must be a callable object:
+
+\begin{verbatim}
+data = authobject(response)
+\end{verbatim}
+
+  It will be called to process server continuation responses.
+  It should return \code{data} that will be encoded and sent to server.
+  It should return \code{None} if the client abort response \samp{*} should
+  be sent instead.
+\end{methoddesc}
+
+\begin{methoddesc}{check}{}
+  Checkpoint mailbox on server. 
+\end{methoddesc}
+
+\begin{methoddesc}{close}{}
+  Close currently selected mailbox. Deleted messages are removed from
+  writable mailbox. This is the recommended command before
+  \samp{LOGOUT}.
+\end{methoddesc}
+
+\begin{methoddesc}{copy}{message_set, new_mailbox}
+  Copy \var{message_set} messages onto end of \var{new_mailbox}. 
+\end{methoddesc}
+
+\begin{methoddesc}{create}{mailbox}
+  Create new mailbox named \var{mailbox}.
+\end{methoddesc}
+
+\begin{methoddesc}{delete}{mailbox}
+  Delete old mailbox named \var{mailbox}.
+\end{methoddesc}
+
+\begin{methoddesc}{deleteacl}{mailbox, who}
+  Delete the ACLs (remove any rights) set for who on mailbox.
+\versionadded{2.4}
+\end{methoddesc}
+
+\begin{methoddesc}{expunge}{}
+  Permanently remove deleted items from selected mailbox. Generates an
+  \samp{EXPUNGE} response for each deleted message. Returned data
+  contains a list of \samp{EXPUNGE} message numbers in order
+  received.
+\end{methoddesc}
+
+\begin{methoddesc}{fetch}{message_set, message_parts}
+  Fetch (parts of) messages.  \var{message_parts} should be
+  a string of message part names enclosed within parentheses,
+  eg: \samp{"(UID BODY[TEXT])"}.  Returned data are tuples
+  of message part envelope and data.
+\end{methoddesc}
+
+\begin{methoddesc}{getacl}{mailbox}
+  Get the \samp{ACL}s for \var{mailbox}.
+  The method is non-standard, but is supported by the \samp{Cyrus} server.
+\end{methoddesc}
+
+\begin{methoddesc}{getannotation}{mailbox, entry, attribute}
+  Retrieve the specified \samp{ANNOTATION}s for \var{mailbox}.
+  The method is non-standard, but is supported by the \samp{Cyrus} server.
+\versionadded{2.5}
+\end{methoddesc}
+
+\begin{methoddesc}{getquota}{root}
+  Get the \samp{quota} \var{root}'s resource usage and limits.
+  This method is part of the IMAP4 QUOTA extension defined in rfc2087.
+\versionadded{2.3}
+\end{methoddesc}
+
+\begin{methoddesc}{getquotaroot}{mailbox}
+  Get the list of \samp{quota} \samp{roots} for the named \var{mailbox}.
+  This method is part of the IMAP4 QUOTA extension defined in rfc2087.
+\versionadded{2.3}
+\end{methoddesc}
+
+\begin{methoddesc}{list}{\optional{directory\optional{, pattern}}}
+  List mailbox names in \var{directory} matching
+  \var{pattern}.  \var{directory} defaults to the top-level mail
+  folder, and \var{pattern} defaults to match anything.  Returned data
+  contains a list of \samp{LIST} responses.
+\end{methoddesc}
+
+\begin{methoddesc}{login}{user, password}
+  Identify the client using a plaintext password.
+  The \var{password} will be quoted.
+\end{methoddesc}
+
+\begin{methoddesc}{login_cram_md5}{user, password}
+  Force use of \samp{CRAM-MD5} authentication when identifying the
+  client to protect the password.  Will only work if the server
+  \samp{CAPABILITY} response includes the phrase \samp{AUTH=CRAM-MD5}.
+\versionadded{2.3}
+\end{methoddesc}
+
+\begin{methoddesc}{logout}{}
+  Shutdown connection to server. Returns server \samp{BYE} response.
+\end{methoddesc}
+
+\begin{methoddesc}{lsub}{\optional{directory\optional{, pattern}}}
+  List subscribed mailbox names in directory matching pattern.
+  \var{directory} defaults to the top level directory and
+  \var{pattern} defaults to match any mailbox.
+  Returned data are tuples of message part envelope and data.
+\end{methoddesc}
+
+\begin{methoddesc}{myrights}{mailbox}
+  Show my ACLs for a mailbox (i.e. the rights that I have on mailbox).
+\versionadded{2.4}
+\end{methoddesc}
+
+\begin{methoddesc}{namespace}{}
+  Returns IMAP namespaces as defined in RFC2342.
+\versionadded{2.3}
+\end{methoddesc}
+
+\begin{methoddesc}{noop}{}
+  Send \samp{NOOP} to server.
+\end{methoddesc}
+
+\begin{methoddesc}{open}{host, port}
+  Opens socket to \var{port} at \var{host}.
+  The connection objects established by this method
+  will be used in the \code{read}, \code{readline}, \code{send}, and
+  \code{shutdown} methods.
+  You may override this method.
+\end{methoddesc}
+
+\begin{methoddesc}{partial}{message_num, message_part, start, length}
+  Fetch truncated part of a message.
+  Returned data is a tuple of message part envelope and data.
+\end{methoddesc}
+
+\begin{methoddesc}{proxyauth}{user}
+  Assume authentication as \var{user}.
+  Allows an authorised administrator to proxy into any user's mailbox.
+\versionadded{2.3}
+\end{methoddesc}
+
+\begin{methoddesc}{read}{size}
+  Reads \var{size} bytes from the remote server.
+  You may override this method.
+\end{methoddesc}
+
+\begin{methoddesc}{readline}{}
+  Reads one line from the remote server.
+  You may override this method.
+\end{methoddesc}
+
+\begin{methoddesc}{recent}{}
+  Prompt server for an update. Returned data is \code{None} if no new
+  messages, else value of \samp{RECENT} response.
+\end{methoddesc}
+
+\begin{methoddesc}{rename}{oldmailbox, newmailbox}
+  Rename mailbox named \var{oldmailbox} to \var{newmailbox}.
+\end{methoddesc}
+
+\begin{methoddesc}{response}{code}
+  Return data for response \var{code} if received, or
+  \code{None}. Returns the given code, instead of the usual type.
+\end{methoddesc}
+
+\begin{methoddesc}{search}{charset, criterion\optional{, ...}}
+  Search mailbox for matching messages.  \var{charset} may be
+  \code{None}, in which case no \samp{CHARSET} will be specified in the
+  request to the server.  The IMAP protocol requires that at least one
+  criterion be specified; an exception will be raised when the server
+  returns an error.
+
+  Example:
+
+\begin{verbatim}
+# M is a connected IMAP4 instance...
+typ, msgnums = M.search(None, 'FROM', '"LDJ"')
+
+# or:
+typ, msgnums = M.search(None, '(FROM "LDJ")')
+\end{verbatim}
+\end{methoddesc}
+
+\begin{methoddesc}{select}{\optional{mailbox\optional{, readonly}}}
+  Select a mailbox. Returned data is the count of messages in
+  \var{mailbox} (\samp{EXISTS} response).  The default \var{mailbox}
+  is \code{'INBOX'}.  If the \var{readonly} flag is set, modifications
+  to the mailbox are not allowed.
+\end{methoddesc}
+
+\begin{methoddesc}{send}{data}
+  Sends \code{data} to the remote server.
+  You may override this method.
+\end{methoddesc}
+
+\begin{methoddesc}{setacl}{mailbox, who, what}
+  Set an \samp{ACL} for \var{mailbox}.
+  The method is non-standard, but is supported by the \samp{Cyrus} server.
+\end{methoddesc}
+
+\begin{methoddesc}{setannotation}{mailbox, entry, attribute\optional{, ...}}
+  Set \samp{ANNOTATION}s for \var{mailbox}.
+  The method is non-standard, but is supported by the \samp{Cyrus} server.
+\versionadded{2.5}
+\end{methoddesc}
+
+\begin{methoddesc}{setquota}{root, limits}
+  Set the \samp{quota} \var{root}'s resource \var{limits}.
+  This method is part of the IMAP4 QUOTA extension defined in rfc2087.
+\versionadded{2.3}
+\end{methoddesc}
+
+\begin{methoddesc}{shutdown}{}
+  Close connection established in \code{open}.
+  You may override this method.
+\end{methoddesc}
+
+\begin{methoddesc}{socket}{}
+  Returns socket instance used to connect to server.
+\end{methoddesc}
+
+\begin{methoddesc}{sort}{sort_criteria, charset, search_criterion\optional{, ...}}
+  The \code{sort} command is a variant of \code{search} with sorting
+  semantics for the results.  Returned data contains a space separated
+  list of matching message numbers.
+
+  Sort has two arguments before the \var{search_criterion}
+  argument(s); a parenthesized list of \var{sort_criteria}, and the
+  searching \var{charset}.  Note that unlike \code{search}, the
+  searching \var{charset} argument is mandatory.  There is also a
+  \code{uid sort} command which corresponds to \code{sort} the way
+  that \code{uid search} corresponds to \code{search}.  The
+  \code{sort} command first searches the mailbox for messages that
+  match the given searching criteria using the charset argument for
+  the interpretation of strings in the searching criteria.  It then
+  returns the numbers of matching messages.
+
+  This is an \samp{IMAP4rev1} extension command.
+\end{methoddesc}
+
+\begin{methoddesc}{status}{mailbox, names}
+  Request named status conditions for \var{mailbox}. 
+\end{methoddesc}
+
+\begin{methoddesc}{store}{message_set, command, flag_list}
+  Alters flag dispositions for messages in mailbox.  \var{command} is
+  specified by section 6.4.6 of \rfc{2060} as being one of "FLAGS", "+FLAGS",
+  or "-FLAGS", optionally with a suffix of ".SILENT".
+
+  For example, to set the delete flag on all messages:
+
+\begin{verbatim}
+typ, data = M.search(None, 'ALL')
+for num in data[0].split():
+   M.store(num, '+FLAGS', '\\Deleted')
+M.expunge()
+\end{verbatim}
+\end{methoddesc}
+
+\begin{methoddesc}{subscribe}{mailbox}
+  Subscribe to new mailbox.
+\end{methoddesc}
+
+\begin{methoddesc}{thread}{threading_algorithm, charset,
+                           search_criterion\optional{, ...}}
+  The \code{thread} command is a variant of \code{search} with
+  threading semantics for the results.  Returned data contains a space
+  separated list of thread members.
+
+  Thread members consist of zero or more messages numbers, delimited
+  by spaces, indicating successive parent and child.
+
+  Thread has two arguments before the \var{search_criterion}
+  argument(s); a \var{threading_algorithm}, and the searching
+  \var{charset}.  Note that unlike \code{search}, the searching
+  \var{charset} argument is mandatory.  There is also a \code{uid
+  thread} command which corresponds to \code{thread} the way that
+  \code{uid search} corresponds to \code{search}.  The \code{thread}
+  command first searches the mailbox for messages that match the given
+  searching criteria using the charset argument for the interpretation
+  of strings in the searching criteria. It then returns the matching
+  messages threaded according to the specified threading algorithm.
+
+  This is an \samp{IMAP4rev1} extension command. \versionadded{2.4}
+\end{methoddesc}
+
+\begin{methoddesc}{uid}{command, arg\optional{, ...}}
+  Execute command args with messages identified by UID, rather than
+  message number.  Returns response appropriate to command.  At least
+  one argument must be supplied; if none are provided, the server will
+  return an error and an exception will be raised.
+\end{methoddesc}
+
+\begin{methoddesc}{unsubscribe}{mailbox}
+  Unsubscribe from old mailbox.
+\end{methoddesc}
+
+\begin{methoddesc}{xatom}{name\optional{, arg\optional{, ...}}}
+  Allow simple extension commands notified by server in
+  \samp{CAPABILITY} response.
+\end{methoddesc}
+
+
+Instances of \class{IMAP4_SSL} have just one additional method:
+
+\begin{methoddesc}{ssl}{}
+  Returns SSLObject instance used for the secure connection with the server.
+\end{methoddesc}
+
+
+The following attributes are defined on instances of \class{IMAP4}:
+
+
+\begin{memberdesc}{PROTOCOL_VERSION}
+The most recent supported protocol in the
+\samp{CAPABILITY} response from the server.
+\end{memberdesc}
+
+\begin{memberdesc}{debug}
+Integer value to control debugging output.  The initialize value is
+taken from the module variable \code{Debug}.  Values greater than
+three trace each command.
+\end{memberdesc}
+
+
+\subsection{IMAP4 Example \label{imap4-example}}
+
+Here is a minimal example (without error checking) that opens a
+mailbox and retrieves and prints all messages:
+
+\begin{verbatim}
+import getpass, imaplib
+
+M = imaplib.IMAP4()
+M.login(getpass.getuser(), getpass.getpass())
+M.select()
+typ, data = M.search(None, 'ALL')
+for num in data[0].split():
+    typ, data = M.fetch(num, '(RFC822)')
+    print 'Message %s\n%s\n' % (num, data[0][1])
+M.close()
+M.logout()
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/libimgfile.tex
===================================================================
--- vendor/Python/current/Doc/lib/libimgfile.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libimgfile.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,66 @@
+\section{\module{imgfile} ---
+         Support for SGI imglib files}
+
+\declaremodule{builtin}{imgfile}
+  \platform{IRIX}
+\modulesynopsis{Support for SGI imglib files.}
+
+
+The \module{imgfile} module allows Python programs to access SGI imglib image
+files (also known as \file{.rgb} files).  The module is far from
+complete, but is provided anyway since the functionality that there is
+enough in some cases.  Currently, colormap files are not supported.
+
+The module defines the following variables and functions:
+
+\begin{excdesc}{error}
+This exception is raised on all errors, such as unsupported file type, etc.
+\end{excdesc}
+
+\begin{funcdesc}{getsizes}{file}
+This function returns a tuple \code{(\var{x}, \var{y}, \var{z})} where
+\var{x} and \var{y} are the size of the image in pixels and
+\var{z} is the number of
+bytes per pixel. Only 3 byte RGB pixels and 1 byte greyscale pixels
+are currently supported.
+\end{funcdesc}
+
+\begin{funcdesc}{read}{file}
+This function reads and decodes the image on the specified file, and
+returns it as a Python string. The string has either 1 byte greyscale
+pixels or 4 byte RGBA pixels. The bottom left pixel is the first in
+the string. This format is suitable to pass to \function{gl.lrectwrite()},
+for instance.
+\end{funcdesc}
+
+\begin{funcdesc}{readscaled}{file, x, y, filter\optional{, blur}}
+This function is identical to read but it returns an image that is
+scaled to the given \var{x} and \var{y} sizes. If the \var{filter} and
+\var{blur} parameters are omitted scaling is done by
+simply dropping or duplicating pixels, so the result will be less than
+perfect, especially for computer-generated images.
+
+Alternatively, you can specify a filter to use to smooth the image
+after scaling. The filter forms supported are \code{'impulse'},
+\code{'box'}, \code{'triangle'}, \code{'quadratic'} and
+\code{'gaussian'}. If a filter is specified \var{blur} is an optional
+parameter specifying the blurriness of the filter. It defaults to \code{1.0}.
+
+\function{readscaled()} makes no attempt to keep the aspect ratio
+correct, so that is the users' responsibility.
+\end{funcdesc}
+
+\begin{funcdesc}{ttob}{flag}
+This function sets a global flag which defines whether the scan lines
+of the image are read or written from bottom to top (flag is zero,
+compatible with SGI GL) or from top to bottom(flag is one,
+compatible with X).  The default is zero.
+\end{funcdesc}
+
+\begin{funcdesc}{write}{file, data, x, y, z}
+This function writes the RGB or greyscale data in \var{data} to image
+file \var{file}. \var{x} and \var{y} give the size of the image,
+\var{z} is 1 for 1 byte greyscale images or 3 for RGB images (which are
+stored as 4 byte values of which only the lower three bytes are used).
+These are the formats returned by \function{gl.lrectread()}.
+\end{funcdesc}

Added: vendor/Python/current/Doc/lib/libimghdr.tex
===================================================================
--- vendor/Python/current/Doc/lib/libimghdr.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libimghdr.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,60 @@
+\section{\module{imghdr} ---
+         Determine the type of an image}
+
+\declaremodule{standard}{imghdr}
+\modulesynopsis{Determine the type of image contained in a file or
+                byte stream.}
+
+
+The \module{imghdr} module determines the type of image contained in a
+file or byte stream.
+
+The \module{imghdr} module defines the following function:
+
+
+\begin{funcdesc}{what}{filename\optional{, h}}
+Tests the image data contained in the file named by \var{filename},
+and returns a string describing the image type.  If optional \var{h}
+is provided, the \var{filename} is ignored and \var{h} is assumed to
+contain the byte stream to test.
+\end{funcdesc}
+
+The following image types are recognized, as listed below with the
+return value from \function{what()}:
+
+\begin{tableii}{l|l}{code}{Value}{Image format}
+  \lineii{'rgb'}{SGI ImgLib Files}
+  \lineii{'gif'}{GIF 87a and 89a Files}
+  \lineii{'pbm'}{Portable Bitmap Files}
+  \lineii{'pgm'}{Portable Graymap Files}
+  \lineii{'ppm'}{Portable Pixmap Files}
+  \lineii{'tiff'}{TIFF Files}
+  \lineii{'rast'}{Sun Raster Files}
+  \lineii{'xbm'}{X Bitmap Files}
+  \lineii{'jpeg'}{JPEG data in JFIF or Exif formats}
+  \lineii{'bmp'}{BMP files}
+  \lineii{'png'}{Portable Network Graphics}
+\end{tableii}
+
+\versionadded[Exif detection]{2.5}
+
+You can extend the list of file types \module{imghdr} can recognize by
+appending to this variable:
+
+\begin{datadesc}{tests}
+A list of functions performing the individual tests.  Each function
+takes two arguments: the byte-stream and an open file-like object.
+When \function{what()} is called with a byte-stream, the file-like
+object will be \code{None}.
+
+The test function should return a string describing the image type if
+the test succeeded, or \code{None} if it failed.
+\end{datadesc}
+
+Example:
+
+\begin{verbatim}
+>>> import imghdr
+>>> imghdr.what('/tmp/bass.gif')
+'gif'
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/libimp.tex
===================================================================
--- vendor/Python/current/Doc/lib/libimp.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libimp.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,291 @@
+\section{\module{imp} ---
+         Access the \keyword{import} internals}
+
+\declaremodule{builtin}{imp}
+\modulesynopsis{Access the implementation of the \keyword{import} statement.}
+
+
+This\stindex{import} module provides an interface to the mechanisms
+used to implement the \keyword{import} statement.  It defines the
+following constants and functions:
+
+
+\begin{funcdesc}{get_magic}{}
+\indexii{file}{byte-code}
+Return the magic string value used to recognize byte-compiled code
+files (\file{.pyc} files).  (This value may be different for each
+Python version.)
+\end{funcdesc}
+
+\begin{funcdesc}{get_suffixes}{}
+Return a list of triples, each describing a particular type of module.
+Each triple has the form \code{(\var{suffix}, \var{mode},
+\var{type})}, where \var{suffix} is a string to be appended to the
+module name to form the filename to search for, \var{mode} is the mode
+string to pass to the built-in \function{open()} function to open the
+file (this can be \code{'r'} for text files or \code{'rb'} for binary
+files), and \var{type} is the file type, which has one of the values
+\constant{PY_SOURCE}, \constant{PY_COMPILED}, or
+\constant{C_EXTENSION}, described below.
+\end{funcdesc}
+
+\begin{funcdesc}{find_module}{name\optional{, path}}
+Try to find the module \var{name} on the search path \var{path}.  If
+\var{path} is a list of directory names, each directory is searched
+for files with any of the suffixes returned by \function{get_suffixes()}
+above.  Invalid names in the list are silently ignored (but all list
+items must be strings).  If \var{path} is omitted or \code{None}, the
+list of directory names given by \code{sys.path} is searched, but
+first it searches a few special places: it tries to find a built-in
+module with the given name (\constant{C_BUILTIN}), then a frozen module
+(\constant{PY_FROZEN}), and on some systems some other places are looked
+in as well (on the Mac, it looks for a resource (\constant{PY_RESOURCE});
+on Windows, it looks in the registry which may point to a specific
+file).
+
+If search is successful, the return value is a triple
+\code{(\var{file}, \var{pathname}, \var{description})} where
+\var{file} is an open file object positioned at the beginning,
+\var{pathname} is the pathname of the
+file found, and \var{description} is a triple as contained in the list
+returned by \function{get_suffixes()} describing the kind of module found.
+If the module does not live in a file, the returned \var{file} is
+\code{None}, \var{filename} is the empty string, and the
+\var{description} tuple contains empty strings for its suffix and
+mode; the module type is as indicate in parentheses above.  If the
+search is unsuccessful, \exception{ImportError} is raised.  Other
+exceptions indicate problems with the arguments or environment.
+
+This function does not handle hierarchical module names (names
+containing dots).  In order to find \var{P}.\var{M}, that is, submodule
+\var{M} of package \var{P}, use \function{find_module()} and
+\function{load_module()} to find and load package \var{P}, and then use
+\function{find_module()} with the \var{path} argument set to
+\code{\var{P}.__path__}.  When \var{P} itself has a dotted name, apply
+this recipe recursively.
+\end{funcdesc}
+
+\begin{funcdesc}{load_module}{name, file, filename, description}
+Load a module that was previously found by \function{find_module()} (or by
+an otherwise conducted search yielding compatible results).  This
+function does more than importing the module: if the module was
+already imported, it is equivalent to a
+\function{reload()}\bifuncindex{reload}!  The \var{name} argument
+indicates the full module name (including the package name, if this is
+a submodule of a package).  The \var{file} argument is an open file,
+and \var{filename} is the corresponding file name; these can be
+\code{None} and \code{''}, respectively, when the module is not being
+loaded from a file.  The \var{description} argument is a tuple, as
+would be returned by \function{get_suffixes()}, describing what kind
+of module must be loaded.
+
+If the load is successful, the return value is the module object;
+otherwise, an exception (usually \exception{ImportError}) is raised.
+
+\strong{Important:} the caller is responsible for closing the
+\var{file} argument, if it was not \code{None}, even when an exception
+is raised.  This is best done using a \keyword{try}
+... \keyword{finally} statement.
+\end{funcdesc}
+
+\begin{funcdesc}{new_module}{name}
+Return a new empty module object called \var{name}.  This object is
+\emph{not} inserted in \code{sys.modules}.
+\end{funcdesc}
+
+\begin{funcdesc}{lock_held}{}
+Return \code{True} if the import lock is currently held, else \code{False}.
+On platforms without threads, always return \code{False}.
+
+On platforms with threads, a thread executing an import holds an internal
+lock until the import is complete.
+This lock blocks other threads from doing an import until the original
+import completes, which in turn prevents other threads from seeing
+incomplete module objects constructed by the original thread while in
+the process of completing its import (and the imports, if any,
+triggered by that).
+\end{funcdesc}
+
+\begin{funcdesc}{acquire_lock}{}
+Acquires the interpreter's import lock for the current thread.  This lock
+should be used by import hooks to ensure thread-safety when importing modules.
+On platforms without threads, this function does nothing.
+\versionadded{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{release_lock}{}
+Release the interpreter's import lock.
+On platforms without threads, this function does nothing.
+\versionadded{2.3}
+\end{funcdesc}
+
+The following constants with integer values, defined in this module,
+are used to indicate the search result of \function{find_module()}.
+
+\begin{datadesc}{PY_SOURCE}
+The module was found as a source file.
+\end{datadesc}
+
+\begin{datadesc}{PY_COMPILED}
+The module was found as a compiled code object file.
+\end{datadesc}
+
+\begin{datadesc}{C_EXTENSION}
+The module was found as dynamically loadable shared library.
+\end{datadesc}
+
+\begin{datadesc}{PY_RESOURCE}
+The module was found as a Mac OS 9 resource.  This value can only be
+returned on a Mac OS 9 or earlier Macintosh.
+\end{datadesc}
+
+\begin{datadesc}{PKG_DIRECTORY}
+The module was found as a package directory.
+\end{datadesc}
+
+\begin{datadesc}{C_BUILTIN}
+The module was found as a built-in module.
+\end{datadesc}
+
+\begin{datadesc}{PY_FROZEN}
+The module was found as a frozen module (see \function{init_frozen()}).
+\end{datadesc}
+
+The following constant and functions are obsolete; their functionality
+is available through \function{find_module()} or \function{load_module()}.
+They are kept around for backward compatibility:
+
+\begin{datadesc}{SEARCH_ERROR}
+Unused.
+\end{datadesc}
+
+\begin{funcdesc}{init_builtin}{name}
+Initialize the built-in module called \var{name} and return its module
+object.  If the module was already initialized, it will be initialized
+\emph{again}.  A few modules cannot be initialized twice --- attempting
+to initialize these again will raise an \exception{ImportError}
+exception.  If there is no
+built-in module called \var{name}, \code{None} is returned.
+\end{funcdesc}
+
+\begin{funcdesc}{init_frozen}{name}
+Initialize the frozen module called \var{name} and return its module
+object.  If the module was already initialized, it will be initialized
+\emph{again}.  If there is no frozen module called \var{name},
+\code{None} is returned.  (Frozen modules are modules written in
+Python whose compiled byte-code object is incorporated into a
+custom-built Python interpreter by Python's \program{freeze} utility.
+See \file{Tools/freeze/} for now.)
+\end{funcdesc}
+
+\begin{funcdesc}{is_builtin}{name}
+Return \code{1} if there is a built-in module called \var{name} which
+can be initialized again.  Return \code{-1} if there is a built-in
+module called \var{name} which cannot be initialized again (see
+\function{init_builtin()}).  Return \code{0} if there is no built-in
+module called \var{name}.
+\end{funcdesc}
+
+\begin{funcdesc}{is_frozen}{name}
+Return \code{True} if there is a frozen module (see
+\function{init_frozen()}) called \var{name}, or \code{False} if there is
+no such module.
+\end{funcdesc}
+
+\begin{funcdesc}{load_compiled}{name, pathname, \optional{file}}
+\indexii{file}{byte-code}
+Load and initialize a module implemented as a byte-compiled code file
+and return its module object.  If the module was already initialized,
+it will be initialized \emph{again}.  The \var{name} argument is used
+to create or access a module object.  The \var{pathname} argument
+points to the byte-compiled code file.  The \var{file}
+argument is the byte-compiled code file, open for reading in binary
+mode, from the beginning.
+It must currently be a real file object, not a
+user-defined class emulating a file.
+\end{funcdesc}
+
+\begin{funcdesc}{load_dynamic}{name, pathname\optional{, file}}
+Load and initialize a module implemented as a dynamically loadable
+shared library and return its module object.  If the module was
+already initialized, it will be initialized \emph{again}.  Some modules
+don't like that and may raise an exception.  The \var{pathname}
+argument must point to the shared library.  The \var{name} argument is
+used to construct the name of the initialization function: an external
+C function called \samp{init\var{name}()} in the shared library is
+called.  The optional \var{file} argument is ignored.  (Note: using
+shared libraries is highly system dependent, and not all systems
+support it.)
+\end{funcdesc}
+
+\begin{funcdesc}{load_source}{name, pathname\optional{, file}}
+Load and initialize a module implemented as a Python source file and
+return its module object.  If the module was already initialized, it
+will be initialized \emph{again}.  The \var{name} argument is used to
+create or access a module object.  The \var{pathname} argument points
+to the source file.  The \var{file} argument is the source
+file, open for reading as text, from the beginning.
+It must currently be a real file
+object, not a user-defined class emulating a file.  Note that if a
+properly matching byte-compiled file (with suffix \file{.pyc} or
+\file{.pyo}) exists, it will be used instead of parsing the given
+source file.
+\end{funcdesc}
+
+\begin{classdesc}{NullImporter}{path_string}
+The \class{NullImporter} type is a \pep{302} import hook that handles
+non-directory path strings by failing to find any modules.  Calling this
+type with an existing directory or empty string raises
+\exception{ImportError}.  Otherwise, a \class{NullImporter} instance is
+returned.
+
+Python adds instances of this type to \code{sys.path_importer_cache} for
+any path entries that are not directories and are not handled by any other
+path hooks on \code{sys.path_hooks}.  Instances have only one method:
+
+\begin{methoddesc}{find_module}{fullname \optional{, path}}
+This method always returns \code{None}, indicating that the requested
+module could not be found.
+\end{methoddesc}
+
+\versionadded{2.5}
+\end{classdesc}
+
+\subsection{Examples}
+\label{examples-imp}
+
+The following function emulates what was the standard import statement
+up to Python 1.4 (no hierarchical module names).  (This
+\emph{implementation} wouldn't work in that version, since
+\function{find_module()} has been extended and
+\function{load_module()} has been added in 1.4.)
+
+\begin{verbatim}
+import imp
+import sys
+
+def __import__(name, globals=None, locals=None, fromlist=None):
+    # Fast path: see if the module has already been imported.
+    try:
+        return sys.modules[name]
+    except KeyError:
+        pass
+
+    # If any of the following calls raises an exception,
+    # there's a problem we can't handle -- let the caller handle it.
+
+    fp, pathname, description = imp.find_module(name)
+
+    try:
+        return imp.load_module(name, fp, pathname, description)
+    finally:
+        # Since we may exit via an exception, close fp explicitly.
+        if fp:
+            fp.close()
+\end{verbatim}
+
+A more complete example that implements hierarchical module names and
+includes a \function{reload()}\bifuncindex{reload} function can be
+found in the module \module{knee}\refmodindex{knee}.  The
+\module{knee} module can be found in \file{Demo/imputil/} in the
+Python source distribution.

Added: vendor/Python/current/Doc/lib/libinspect.tex
===================================================================
--- vendor/Python/current/Doc/lib/libinspect.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libinspect.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,393 @@
+\section{\module{inspect} ---
+         Inspect live objects}
+
+\declaremodule{standard}{inspect}
+\modulesynopsis{Extract information and source code from live objects.}
+\moduleauthor{Ka-Ping Yee}{ping at lfw.org}
+\sectionauthor{Ka-Ping Yee}{ping at lfw.org}
+
+\versionadded{2.1}
+
+The \module{inspect} module provides several useful functions
+to help get information about live objects such as modules,
+classes, methods, functions, tracebacks, frame objects, and
+code objects.  For example, it can help you examine the
+contents of a class, retrieve the source code of a method,
+extract and format the argument list for a function, or
+get all the information you need to display a detailed traceback.
+
+There are four main kinds of services provided by this module:
+type checking, getting source code, inspecting classes
+and functions, and examining the interpreter stack.
+
+\subsection{Types and members
+            \label{inspect-types}}
+
+The \function{getmembers()} function retrieves the members
+of an object such as a class or module.
+The eleven functions whose names begin with ``is'' are mainly
+provided as convenient choices for the second argument to
+\function{getmembers()}.  They also help you determine when
+you can expect to find the following special attributes:
+
+\begin{tableiv}{c|l|l|c}{}{Type}{Attribute}{Description}{Notes}
+  \lineiv{module}{__doc__}{documentation string}{}
+  \lineiv{}{__file__}{filename (missing for built-in modules)}{}
+  \hline
+  \lineiv{class}{__doc__}{documentation string}{}
+  \lineiv{}{__module__}{name of module in which this class was defined}{}
+  \hline
+  \lineiv{method}{__doc__}{documentation string}{}
+  \lineiv{}{__name__}{name with which this method was defined}{}
+  \lineiv{}{im_class}{class object that asked for this method}{(1)}
+  \lineiv{}{im_func}{function object containing implementation of method}{}
+  \lineiv{}{im_self}{instance to which this method is bound, or \code{None}}{}
+  \hline
+  \lineiv{function}{__doc__}{documentation string}{}
+  \lineiv{}{__name__}{name with which this function was defined}{}
+  \lineiv{}{func_code}{code object containing compiled function bytecode}{}
+  \lineiv{}{func_defaults}{tuple of any default values for arguments}{}
+  \lineiv{}{func_doc}{(same as __doc__)}{}
+  \lineiv{}{func_globals}{global namespace in which this function was defined}{}
+  \lineiv{}{func_name}{(same as __name__)}{}
+  \hline
+  \lineiv{traceback}{tb_frame}{frame object at this level}{}
+  \lineiv{}{tb_lasti}{index of last attempted instruction in bytecode}{}
+  \lineiv{}{tb_lineno}{current line number in Python source code}{}
+  \lineiv{}{tb_next}{next inner traceback object (called by this level)}{}
+  \hline
+  \lineiv{frame}{f_back}{next outer frame object (this frame's caller)}{}
+  \lineiv{}{f_builtins}{built-in namespace seen by this frame}{}
+  \lineiv{}{f_code}{code object being executed in this frame}{}
+  \lineiv{}{f_exc_traceback}{traceback if raised in this frame, or \code{None}}{}
+  \lineiv{}{f_exc_type}{exception type if raised in this frame, or \code{None}}{}
+  \lineiv{}{f_exc_value}{exception value if raised in this frame, or \code{None}}{}
+  \lineiv{}{f_globals}{global namespace seen by this frame}{}
+  \lineiv{}{f_lasti}{index of last attempted instruction in bytecode}{}
+  \lineiv{}{f_lineno}{current line number in Python source code}{}
+  \lineiv{}{f_locals}{local namespace seen by this frame}{}
+  \lineiv{}{f_restricted}{0 or 1 if frame is in restricted execution mode}{}
+  \lineiv{}{f_trace}{tracing function for this frame, or \code{None}}{}
+  \hline
+  \lineiv{code}{co_argcount}{number of arguments (not including * or ** args)}{}
+  \lineiv{}{co_code}{string of raw compiled bytecode}{}
+  \lineiv{}{co_consts}{tuple of constants used in the bytecode}{}
+  \lineiv{}{co_filename}{name of file in which this code object was created}{}
+  \lineiv{}{co_firstlineno}{number of first line in Python source code}{}
+  \lineiv{}{co_flags}{bitmap: 1=optimized \code{|} 2=newlocals \code{|} 4=*arg \code{|} 8=**arg}{}
+  \lineiv{}{co_lnotab}{encoded mapping of line numbers to bytecode indices}{}
+  \lineiv{}{co_name}{name with which this code object was defined}{}
+  \lineiv{}{co_names}{tuple of names of local variables}{}
+  \lineiv{}{co_nlocals}{number of local variables}{}
+  \lineiv{}{co_stacksize}{virtual machine stack space required}{}
+  \lineiv{}{co_varnames}{tuple of names of arguments and local variables}{}
+  \hline
+  \lineiv{builtin}{__doc__}{documentation string}{}
+  \lineiv{}{__name__}{original name of this function or method}{}
+  \lineiv{}{__self__}{instance to which a method is bound, or \code{None}}{}
+\end{tableiv}
+
+\noindent
+Note:
+\begin{description}
+\item[(1)]
+\versionchanged[\member{im_class} used to refer to the class that
+                defined the method]{2.2}
+\end{description}
+
+
+\begin{funcdesc}{getmembers}{object\optional{, predicate}}
+  Return all the members of an object in a list of (name, value) pairs
+  sorted by name.  If the optional \var{predicate} argument is supplied,
+  only members for which the predicate returns a true value are included.
+\end{funcdesc}
+
+\begin{funcdesc}{getmoduleinfo}{path}
+  Return a tuple of values that describe how Python will interpret the
+  file identified by \var{path} if it is a module, or \code{None} if
+  it would not be identified as a module.  The return tuple is
+  \code{(\var{name}, \var{suffix}, \var{mode}, \var{mtype})}, where
+  \var{name} is the name of the module without the name of any
+  enclosing package, \var{suffix} is the trailing part of the file
+  name (which may not be a dot-delimited extension), \var{mode} is the
+  \function{open()} mode that would be used (\code{'r'} or
+  \code{'rb'}), and \var{mtype} is an integer giving the type of the
+  module.  \var{mtype} will have a value which can be compared to the
+  constants defined in the \refmodule{imp} module; see the
+  documentation for that module for more information on module types.
+\end{funcdesc}
+
+\begin{funcdesc}{getmodulename}{path}
+  Return the name of the module named by the file \var{path}, without
+  including the names of enclosing packages.  This uses the same
+  algorithm as the interpreter uses when searching for modules.  If
+  the name cannot be matched according to the interpreter's rules,
+  \code{None} is returned.
+\end{funcdesc}
+
+\begin{funcdesc}{ismodule}{object}
+  Return true if the object is a module.
+\end{funcdesc}
+
+\begin{funcdesc}{isclass}{object}
+  Return true if the object is a class.
+\end{funcdesc}
+
+\begin{funcdesc}{ismethod}{object}
+  Return true if the object is a method.
+\end{funcdesc}
+
+\begin{funcdesc}{isfunction}{object}
+  Return true if the object is a Python function or unnamed (lambda) function.
+\end{funcdesc}
+
+\begin{funcdesc}{istraceback}{object}
+  Return true if the object is a traceback.
+\end{funcdesc}
+
+\begin{funcdesc}{isframe}{object}
+  Return true if the object is a frame.
+\end{funcdesc}
+
+\begin{funcdesc}{iscode}{object}
+  Return true if the object is a code.
+\end{funcdesc}
+
+\begin{funcdesc}{isbuiltin}{object}
+  Return true if the object is a built-in function.
+\end{funcdesc}
+
+\begin{funcdesc}{isroutine}{object}
+  Return true if the object is a user-defined or built-in function or method.
+\end{funcdesc}
+
+\begin{funcdesc}{ismethoddescriptor}{object}
+  Return true if the object is a method descriptor, but not if ismethod() or 
+  isclass() or isfunction() are true.
+
+  This is new as of Python 2.2, and, for example, is true of int.__add__.
+  An object passing this test has a __get__ attribute but not a __set__
+  attribute, but beyond that the set of attributes varies.  __name__ is
+  usually sensible, and __doc__ often is.
+
+  Methods implemented via descriptors that also pass one of the other
+  tests return false from the ismethoddescriptor() test, simply because
+  the other tests promise more -- you can, e.g., count on having the
+  im_func attribute (etc) when an object passes ismethod().
+\end{funcdesc}
+
+\begin{funcdesc}{isdatadescriptor}{object}
+  Return true if the object is a data descriptor.
+
+  Data descriptors have both a __get__ and a __set__ attribute.  Examples are
+  properties (defined in Python), getsets, and members.  The latter two are
+  defined in C and there are more specific tests available for those types,
+  which is robust across Python implementations.  Typically, data descriptors
+  will also have __name__ and __doc__ attributes (properties, getsets, and
+  members have both of these attributes), but this is not guaranteed.
+\versionadded{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{isgetsetdescriptor}{object}
+  Return true if the object is a getset descriptor.
+
+  getsets are attributes defined in extension modules via \code{PyGetSetDef}
+  structures.  For Python implementations without such types, this method will
+  always return \code{False}.
+\versionadded{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{ismemberdescriptor}{object}
+  Return true if the object is a member descriptor.
+
+  Member descriptors are attributes defined in extension modules via
+  \code{PyMemberDef} structures.  For Python implementations without such
+  types, this method will always return \code{False}.
+\versionadded{2.5}
+\end{funcdesc}
+
+\subsection{Retrieving source code
+            \label{inspect-source}}
+
+\begin{funcdesc}{getdoc}{object}
+  Get the documentation string for an object.
+  All tabs are expanded to spaces.  To clean up docstrings that are
+  indented to line up with blocks of code, any whitespace than can be
+  uniformly removed from the second line onwards is removed.
+\end{funcdesc}
+
+\begin{funcdesc}{getcomments}{object}
+  Return in a single string any lines of comments immediately preceding
+  the object's source code (for a class, function, or method), or at the
+  top of the Python source file (if the object is a module).
+\end{funcdesc}
+
+\begin{funcdesc}{getfile}{object}
+  Return the name of the (text or binary) file in which an object was
+  defined.  This will fail with a \exception{TypeError} if the object
+  is a built-in module, class, or function.
+\end{funcdesc}
+
+\begin{funcdesc}{getmodule}{object}
+  Try to guess which module an object was defined in.
+\end{funcdesc}
+
+\begin{funcdesc}{getsourcefile}{object}
+  Return the name of the Python source file in which an object was
+  defined.  This will fail with a \exception{TypeError} if the object
+  is a built-in module, class, or function.
+\end{funcdesc}
+
+\begin{funcdesc}{getsourcelines}{object}
+  Return a list of source lines and starting line number for an object.
+  The argument may be a module, class, method, function, traceback, frame,
+  or code object.  The source code is returned as a list of the lines
+  corresponding to the object and the line number indicates where in the
+  original source file the first line of code was found.  An
+  \exception{IOError} is raised if the source code cannot be retrieved.
+\end{funcdesc}
+
+\begin{funcdesc}{getsource}{object}
+  Return the text of the source code for an object.
+  The argument may be a module, class, method, function, traceback, frame,
+  or code object.  The source code is returned as a single string.  An
+  \exception{IOError} is raised if the source code cannot be retrieved.
+\end{funcdesc}
+
+\subsection{Classes and functions
+            \label{inspect-classes-functions}}
+
+\begin{funcdesc}{getclasstree}{classes\optional{, unique}}
+  Arrange the given list of classes into a hierarchy of nested lists.
+  Where a nested list appears, it contains classes derived from the class
+  whose entry immediately precedes the list.  Each entry is a 2-tuple
+  containing a class and a tuple of its base classes.  If the \var{unique}
+  argument is true, exactly one entry appears in the returned structure
+  for each class in the given list.  Otherwise, classes using multiple
+  inheritance and their descendants will appear multiple times.
+\end{funcdesc}
+
+\begin{funcdesc}{getargspec}{func}
+  Get the names and default values of a function's arguments.
+  A tuple of four things is returned: \code{(\var{args},
+    \var{varargs}, \var{varkw}, \var{defaults})}.
+  \var{args} is a list of the argument names (it may contain nested lists).
+  \var{varargs} and \var{varkw} are the names of the \code{*} and
+  \code{**} arguments or \code{None}.
+  \var{defaults} is a tuple of default argument values or None if there are no
+  default arguments; if this tuple has \var{n} elements, they correspond to
+  the last \var{n} elements listed in \var{args}.
+\end{funcdesc}
+
+\begin{funcdesc}{getargvalues}{frame}
+  Get information about arguments passed into a particular frame.
+  A tuple of four things is returned: \code{(\var{args},
+    \var{varargs}, \var{varkw}, \var{locals})}.
+  \var{args} is a list of the argument names (it may contain nested
+  lists).
+  \var{varargs} and \var{varkw} are the names of the \code{*} and
+  \code{**} arguments or \code{None}.
+  \var{locals} is the locals dictionary of the given frame.
+\end{funcdesc}
+
+\begin{funcdesc}{formatargspec}{args\optional{, varargs, varkw, defaults,
+      formatarg, formatvarargs, formatvarkw, formatvalue, join}}
+
+  Format a pretty argument spec from the four values returned by
+  \function{getargspec()}.  The format* arguments are the
+  corresponding optional formatting functions that are called to turn
+  names and values into strings.
+\end{funcdesc}
+
+\begin{funcdesc}{formatargvalues}{args\optional{, varargs, varkw, locals,
+      formatarg, formatvarargs, formatvarkw, formatvalue, join}}
+  Format a pretty argument spec from the four values returned by
+  \function{getargvalues()}.  The format* arguments are the
+  corresponding optional formatting functions that are called to turn
+  names and values into strings.
+\end{funcdesc}
+
+\begin{funcdesc}{getmro}{cls}
+  Return a tuple of class cls's base classes, including cls, in
+  method resolution order.  No class appears more than once in this tuple.
+  Note that the method resolution order depends on cls's type.  Unless a
+  very peculiar user-defined metatype is in use, cls will be the first
+  element of the tuple.
+\end{funcdesc}
+
+\subsection{The interpreter stack
+            \label{inspect-stack}}
+
+When the following functions return ``frame records,'' each record
+is a tuple of six items: the frame object, the filename,
+the line number of the current line, the function name, a list of
+lines of context from the source code, and the index of the current
+line within that list.
+
+\begin{notice}[warning]
+Keeping references to frame objects, as found in
+the first element of the frame records these functions return, can
+cause your program to create reference cycles.  Once a reference cycle
+has been created, the lifespan of all objects which can be accessed
+from the objects which form the cycle can become much longer even if
+Python's optional cycle detector is enabled.  If such cycles must be
+created, it is important to ensure they are explicitly broken to avoid
+the delayed destruction of objects and increased memory consumption
+which occurs.
+
+Though the cycle detector will catch these, destruction of the frames
+(and local variables) can be made deterministic by removing the cycle
+in a \keyword{finally} clause.  This is also important if the cycle
+detector was disabled when Python was compiled or using
+\function{\refmodule{gc}.disable()}.  For example:
+
+\begin{verbatim}
+def handle_stackframe_without_leak():
+    frame = inspect.currentframe()
+    try:
+        # do something with the frame
+    finally:
+        del frame
+\end{verbatim}
+\end{notice}
+
+The optional \var{context} argument supported by most of these
+functions specifies the number of lines of context to return, which
+are centered around the current line.
+
+\begin{funcdesc}{getframeinfo}{frame\optional{, context}}
+  Get information about a frame or traceback object.  A 5-tuple
+  is returned, the last five elements of the frame's frame record.
+\end{funcdesc}
+
+\begin{funcdesc}{getouterframes}{frame\optional{, context}}
+  Get a list of frame records for a frame and all outer frames.  These
+  frames represent the calls that lead to the creation of \var{frame}.
+  The first entry in the returned list represents \var{frame}; the
+  last entry represents the outermost call on \var{frame}'s stack.
+\end{funcdesc}
+
+\begin{funcdesc}{getinnerframes}{traceback\optional{, context}}
+  Get a list of frame records for a traceback's frame and all inner
+  frames.  These frames represent calls made as a consequence of
+  \var{frame}.  The first entry in the list represents
+  \var{traceback}; the last entry represents where the exception was
+  raised.
+\end{funcdesc}
+
+\begin{funcdesc}{currentframe}{}
+  Return the frame object for the caller's stack frame.
+\end{funcdesc}
+
+\begin{funcdesc}{stack}{\optional{context}}
+  Return a list of frame records for the caller's stack.  The first
+  entry in the returned list represents the caller; the last entry
+  represents the outermost call on the stack.
+\end{funcdesc}
+
+\begin{funcdesc}{trace}{\optional{context}}
+  Return a list of frame records for the stack between the current
+  frame and the frame in which an exception currently being handled
+  was raised in.  The first entry in the list represents the caller;
+  the last entry represents where the exception was raised.
+\end{funcdesc}

Added: vendor/Python/current/Doc/lib/libintro.tex
===================================================================
--- vendor/Python/current/Doc/lib/libintro.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libintro.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,53 @@
+\chapter{Introduction}
+\label{intro}
+
+The ``Python library'' contains several different kinds of components.
+
+It contains data types that would normally be considered part of the
+``core'' of a language, such as numbers and lists.  For these types,
+the Python language core defines the form of literals and places some
+constraints on their semantics, but does not fully define the
+semantics.  (On the other hand, the language core does define
+syntactic properties like the spelling and priorities of operators.)
+
+The library also contains built-in functions and exceptions ---
+objects that can be used by all Python code without the need of an
+\keyword{import} statement.  Some of these are defined by the core
+language, but many are not essential for the core semantics and are
+only described here.
+
+The bulk of the library, however, consists of a collection of modules.
+There are many ways to dissect this collection.  Some modules are
+written in C and built in to the Python interpreter; others are
+written in Python and imported in source form.  Some modules provide
+interfaces that are highly specific to Python, like printing a stack
+trace; some provide interfaces that are specific to particular
+operating systems, such as access to specific hardware; others provide
+interfaces that are
+specific to a particular application domain, like the World Wide Web.
+Some modules are available in all versions and ports of Python; others
+are only available when the underlying system supports or requires
+them; yet others are available only when a particular configuration
+option was chosen at the time when Python was compiled and installed.
+
+This manual is organized ``from the inside out:'' it first describes
+the built-in data types, then the built-in functions and exceptions,
+and finally the modules, grouped in chapters of related modules.  The
+ordering of the chapters as well as the ordering of the modules within
+each chapter is roughly from most relevant to least important.
+
+This means that if you start reading this manual from the start, and
+skip to the next chapter when you get bored, you will get a reasonable
+overview of the available modules and application areas that are
+supported by the Python library.  Of course, you don't \emph{have} to
+read it like a novel --- you can also browse the table of contents (in
+front of the manual), or look for a specific function, module or term
+in the index (in the back).  And finally, if you enjoy learning about
+random subjects, you choose a random page number (see module
+\refmodule{random}) and read a section or two.  Regardless of the
+order in which you read the sections of this manual, it helps to start 
+with chapter \ref{builtin}, ``Built-in Types, Exceptions and
+Functions,'' as the remainder of the manual assumes familiarity with
+this material.
+
+Let the show begin!

Added: vendor/Python/current/Doc/lib/libitertools.tex
===================================================================
--- vendor/Python/current/Doc/lib/libitertools.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libitertools.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,546 @@
+\section{\module{itertools} ---
+         Functions creating iterators for efficient looping}
+
+\declaremodule{standard}{itertools}
+\modulesynopsis{Functions creating iterators for efficient looping.}
+\moduleauthor{Raymond Hettinger}{python at rcn.com}
+\sectionauthor{Raymond Hettinger}{python at rcn.com}
+\versionadded{2.3}
+
+
+This module implements a number of iterator building blocks inspired
+by constructs from the Haskell and SML programming languages.  Each
+has been recast in a form suitable for Python.
+
+The module standardizes a core set of fast, memory efficient tools
+that are useful by themselves or in combination.  Standardization helps
+avoid the readability and reliability problems which arise when many
+different individuals create their own slightly varying implementations,
+each with their own quirks and naming conventions.
+
+The tools are designed to combine readily with one another.  This makes
+it easy to construct more specialized tools succinctly and efficiently
+in pure Python.
+
+For instance, SML provides a tabulation tool: \code{tabulate(f)}
+which produces a sequence \code{f(0), f(1), ...}.  This toolbox
+provides \function{imap()} and \function{count()} which can be combined
+to form \code{imap(f, count())} and produce an equivalent result.
+
+Likewise, the functional tools are designed to work well with the
+high-speed functions provided by the \refmodule{operator} module.
+
+The module author welcomes suggestions for other basic building blocks
+to be added to future versions of the module.
+
+Whether cast in pure python form or compiled code, tools that use iterators
+are more memory efficient (and faster) than their list based counterparts.
+Adopting the principles of just-in-time manufacturing, they create
+data when and where needed instead of consuming memory with the
+computer equivalent of ``inventory''.
+
+The performance advantage of iterators becomes more acute as the number
+of elements increases -- at some point, lists grow large enough to
+severely impact memory cache performance and start running slowly.
+
+\begin{seealso}
+  \seetext{The Standard ML Basis Library,
+           \citetitle[http://www.standardml.org/Basis/]
+           {The Standard ML Basis Library}.}
+
+  \seetext{Haskell, A Purely Functional Language,
+           \citetitle[http://www.haskell.org/definition/]
+           {Definition of Haskell and the Standard Libraries}.}
+\end{seealso}
+
+
+\subsection{Itertool functions \label{itertools-functions}}
+
+The following module functions all construct and return iterators.
+Some provide streams of infinite length, so they should only be accessed
+by functions or loops that truncate the stream.
+
+\begin{funcdesc}{chain}{*iterables}
+  Make an iterator that returns elements from the first iterable until
+  it is exhausted, then proceeds to the next iterable, until all of the
+  iterables are exhausted.  Used for treating consecutive sequences as
+  a single sequence.  Equivalent to:
+
+  \begin{verbatim}
+     def chain(*iterables):
+         for it in iterables:
+             for element in it:
+                 yield element
+  \end{verbatim}
+\end{funcdesc}
+
+\begin{funcdesc}{count}{\optional{n}}
+  Make an iterator that returns consecutive integers starting with \var{n}.
+  If not specified \var{n} defaults to zero.  
+  Does not currently support python long integers.  Often used as an
+  argument to \function{imap()} to generate consecutive data points.
+  Also, used with \function{izip()} to add sequence numbers.  Equivalent to:
+
+  \begin{verbatim}
+     def count(n=0):
+         while True:
+             yield n
+             n += 1
+  \end{verbatim}
+
+  Note, \function{count()} does not check for overflow and will return
+  negative numbers after exceeding \code{sys.maxint}.  This behavior
+  may change in the future.
+\end{funcdesc}
+
+\begin{funcdesc}{cycle}{iterable}
+  Make an iterator returning elements from the iterable and saving a
+  copy of each.  When the iterable is exhausted, return elements from
+  the saved copy.  Repeats indefinitely.  Equivalent to:
+
+  \begin{verbatim}
+     def cycle(iterable):
+         saved = []
+         for element in iterable:
+             yield element
+             saved.append(element)
+         while saved:
+             for element in saved:
+                   yield element
+  \end{verbatim}
+
+  Note, this member of the toolkit may require significant
+  auxiliary storage (depending on the length of the iterable).
+\end{funcdesc}
+
+\begin{funcdesc}{dropwhile}{predicate, iterable}
+  Make an iterator that drops elements from the iterable as long as
+  the predicate is true; afterwards, returns every element.  Note,
+  the iterator does not produce \emph{any} output until the predicate
+  is true, so it may have a lengthy start-up time.  Equivalent to:
+
+  \begin{verbatim}
+     def dropwhile(predicate, iterable):
+         iterable = iter(iterable)
+         for x in iterable:
+             if not predicate(x):
+                 yield x
+                 break
+         for x in iterable:
+             yield x
+  \end{verbatim}
+\end{funcdesc}
+
+\begin{funcdesc}{groupby}{iterable\optional{, key}}
+  Make an iterator that returns consecutive keys and groups from the
+  \var{iterable}. The \var{key} is a function computing a key value for each
+  element.  If not specified or is \code{None}, \var{key} defaults to an
+  identity function and returns  the element unchanged.  Generally, the
+  iterable needs to already be sorted on the same key function.
+
+  The returned group is itself an iterator that shares the underlying
+  iterable with \function{groupby()}.  Because the source is shared, when
+  the \function{groupby} object is advanced, the previous group is no
+  longer visible.  So, if that data is needed later, it should be stored
+  as a list:
+
+  \begin{verbatim}
+    groups = []
+    uniquekeys = []
+    for k, g in groupby(data, keyfunc):
+        groups.append(list(g))      # Store group iterator as a list
+        uniquekeys.append(k)
+  \end{verbatim}
+
+  \function{groupby()} is equivalent to:
+
+  \begin{verbatim}
+    class groupby(object):
+        def __init__(self, iterable, key=None):
+            if key is None:
+                key = lambda x: x
+            self.keyfunc = key
+            self.it = iter(iterable)
+            self.tgtkey = self.currkey = self.currvalue = xrange(0)
+        def __iter__(self):
+            return self
+        def next(self):
+            while self.currkey == self.tgtkey:
+                self.currvalue = self.it.next() # Exit on StopIteration
+                self.currkey = self.keyfunc(self.currvalue)
+            self.tgtkey = self.currkey
+            return (self.currkey, self._grouper(self.tgtkey))
+        def _grouper(self, tgtkey):
+            while self.currkey == tgtkey:
+                yield self.currvalue
+                self.currvalue = self.it.next() # Exit on StopIteration
+                self.currkey = self.keyfunc(self.currvalue)
+  \end{verbatim}
+  \versionadded{2.4}
+\end{funcdesc}
+
+\begin{funcdesc}{ifilter}{predicate, iterable}
+  Make an iterator that filters elements from iterable returning only
+  those for which the predicate is \code{True}.
+  If \var{predicate} is \code{None}, return the items that are true.
+  Equivalent to:
+
+  \begin{verbatim}
+     def ifilter(predicate, iterable):
+         if predicate is None:
+             predicate = bool
+         for x in iterable:
+             if predicate(x):
+                 yield x
+  \end{verbatim}
+\end{funcdesc}
+
+\begin{funcdesc}{ifilterfalse}{predicate, iterable}
+  Make an iterator that filters elements from iterable returning only
+  those for which the predicate is \code{False}.
+  If \var{predicate} is \code{None}, return the items that are false.
+  Equivalent to:
+
+  \begin{verbatim}
+     def ifilterfalse(predicate, iterable):
+         if predicate is None:
+             predicate = bool
+         for x in iterable:
+             if not predicate(x):
+                 yield x
+  \end{verbatim}
+\end{funcdesc}
+
+\begin{funcdesc}{imap}{function, *iterables}
+  Make an iterator that computes the function using arguments from
+  each of the iterables.  If \var{function} is set to \code{None}, then
+  \function{imap()} returns the arguments as a tuple.  Like
+  \function{map()} but stops when the shortest iterable is exhausted
+  instead of filling in \code{None} for shorter iterables.  The reason
+  for the difference is that infinite iterator arguments are typically
+  an error for \function{map()} (because the output is fully evaluated)
+  but represent a common and useful way of supplying arguments to
+  \function{imap()}.
+  Equivalent to:
+
+  \begin{verbatim}
+     def imap(function, *iterables):
+         iterables = map(iter, iterables)
+         while True:
+             args = [i.next() for i in iterables]
+             if function is None:
+                 yield tuple(args)
+             else:
+                 yield function(*args)
+  \end{verbatim}
+\end{funcdesc}
+
+\begin{funcdesc}{islice}{iterable, \optional{start,} stop \optional{, step}}
+  Make an iterator that returns selected elements from the iterable.
+  If \var{start} is non-zero, then elements from the iterable are skipped
+  until start is reached.  Afterward, elements are returned consecutively
+  unless \var{step} is set higher than one which results in items being
+  skipped.  If \var{stop} is \code{None}, then iteration continues until
+  the iterator is exhausted, if at all; otherwise, it stops at the specified
+  position.  Unlike regular slicing,
+  \function{islice()} does not support negative values for \var{start},
+  \var{stop}, or \var{step}.  Can be used to extract related fields
+  from data where the internal structure has been flattened (for
+  example, a multi-line report may list a name field on every
+  third line).  Equivalent to:
+
+  \begin{verbatim}
+     def islice(iterable, *args):
+         s = slice(*args)
+         it = iter(xrange(s.start or 0, s.stop or sys.maxint, s.step or 1))
+         nexti = it.next()
+         for i, element in enumerate(iterable):
+             if i == nexti:
+                 yield element
+                 nexti = it.next()          
+  \end{verbatim}
+
+  If \var{start} is \code{None}, then iteration starts at zero.
+  If \var{step} is \code{None}, then the step defaults to one.
+  \versionchanged[accept \code{None} values for default \var{start} and
+                  \var{step}]{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{izip}{*iterables}
+  Make an iterator that aggregates elements from each of the iterables.
+  Like \function{zip()} except that it returns an iterator instead of
+  a list.  Used for lock-step iteration over several iterables at a
+  time.  Equivalent to:
+
+  \begin{verbatim}
+     def izip(*iterables):
+         iterables = map(iter, iterables)
+         while iterables:
+             result = [it.next() for it in iterables]
+             yield tuple(result)
+  \end{verbatim}
+
+  \versionchanged[When no iterables are specified, returns a zero length
+                  iterator instead of raising a \exception{TypeError}
+		  exception]{2.4}
+
+  Note, the left-to-right evaluation order of the iterables is guaranteed.
+  This makes possible an idiom for clustering a data series into n-length
+  groups using \samp{izip(*[iter(s)]*n)}.  For data that doesn't fit
+  n-length groups exactly, the last tuple can be pre-padded with fill
+  values using \samp{izip(*[chain(s, [None]*(n-1))]*n)}.
+         
+  Note, when \function{izip()} is used with unequal length inputs, subsequent
+  iteration over the longer iterables cannot reliably be continued after
+  \function{izip()} terminates.  Potentially, up to one entry will be missing
+  from each of the left-over iterables. This occurs because a value is fetched
+  from each iterator in-turn, but the process ends when one of the iterators
+  terminates.  This leaves the last fetched values in limbo (they cannot be
+  returned in a final, incomplete tuple and they are cannot be pushed back
+  into the iterator for retrieval with \code{it.next()}).  In general,
+  \function{izip()} should only be used with unequal length inputs when you
+  don't care about trailing, unmatched values from the longer iterables.
+\end{funcdesc}
+
+\begin{funcdesc}{repeat}{object\optional{, times}}
+  Make an iterator that returns \var{object} over and over again.
+  Runs indefinitely unless the \var{times} argument is specified.
+  Used as argument to \function{imap()} for invariant parameters
+  to the called function.  Also used with \function{izip()} to create
+  an invariant part of a tuple record.  Equivalent to:
+
+  \begin{verbatim}
+     def repeat(object, times=None):
+         if times is None:
+             while True:
+                 yield object
+         else:
+             for i in xrange(times):
+                 yield object
+  \end{verbatim}
+\end{funcdesc}
+
+\begin{funcdesc}{starmap}{function, iterable}
+  Make an iterator that computes the function using arguments tuples
+  obtained from the iterable.  Used instead of \function{imap()} when
+  argument parameters are already grouped in tuples from a single iterable
+  (the data has been ``pre-zipped'').  The difference between
+  \function{imap()} and \function{starmap()} parallels the distinction
+  between \code{function(a,b)} and \code{function(*c)}.
+  Equivalent to:
+
+  \begin{verbatim}
+     def starmap(function, iterable):
+         iterable = iter(iterable)
+         while True:
+             yield function(*iterable.next())
+  \end{verbatim}
+\end{funcdesc}
+
+\begin{funcdesc}{takewhile}{predicate, iterable}
+  Make an iterator that returns elements from the iterable as long as
+  the predicate is true.  Equivalent to:
+
+  \begin{verbatim}
+     def takewhile(predicate, iterable):
+         for x in iterable:
+             if predicate(x):
+                 yield x
+             else:
+                 break
+  \end{verbatim}
+\end{funcdesc}
+
+\begin{funcdesc}{tee}{iterable\optional{, n=2}}
+  Return \var{n} independent iterators from a single iterable.
+  The case where \code{n==2} is equivalent to:
+
+  \begin{verbatim}
+     def tee(iterable):
+         def gen(next, data={}, cnt=[0]):
+             for i in count():
+                 if i == cnt[0]:
+                     item = data[i] = next()
+                     cnt[0] += 1
+                 else:
+                     item = data.pop(i)
+                 yield item
+         it = iter(iterable)
+         return (gen(it.next), gen(it.next))
+  \end{verbatim}
+
+  Note, once \function{tee()} has made a split, the original \var{iterable}
+  should not be used anywhere else; otherwise, the \var{iterable} could get
+  advanced without the tee objects being informed.
+
+  Note, this member of the toolkit may require significant auxiliary
+  storage (depending on how much temporary data needs to be stored).
+  In general, if one iterator is going to use most or all of the data before
+  the other iterator, it is faster to use \function{list()} instead of
+  \function{tee()}.
+  \versionadded{2.4}
+\end{funcdesc}
+
+
+\subsection{Examples \label{itertools-example}}
+
+The following examples show common uses for each tool and
+demonstrate ways they can be combined.
+
+\begin{verbatim}
+
+>>> amounts = [120.15, 764.05, 823.14]
+>>> for checknum, amount in izip(count(1200), amounts):
+...     print 'Check %d is for $%.2f' % (checknum, amount)
+...
+Check 1200 is for $120.15
+Check 1201 is for $764.05
+Check 1202 is for $823.14
+
+>>> import operator
+>>> for cube in imap(operator.pow, xrange(1,5), repeat(3)):
+...    print cube
+...
+1
+8
+27
+64
+
+>>> reportlines = ['EuroPython', 'Roster', '', 'alex', '', 'laura',
+                  '', 'martin', '', 'walter', '', 'mark']
+>>> for name in islice(reportlines, 3, None, 2):
+...    print name.title()
+...
+Alex
+Laura
+Martin
+Walter
+Mark
+
+# Show a dictionary sorted and grouped by value
+>>> from operator import itemgetter
+>>> d = dict(a=1, b=2, c=1, d=2, e=1, f=2, g=3)
+>>> di = sorted(d.iteritems(), key=itemgetter(1))
+>>> for k, g in groupby(di, key=itemgetter(1)):
+...     print k, map(itemgetter(0), g)
+...
+1 ['a', 'c', 'e']
+2 ['b', 'd', 'f']
+3 ['g']
+
+# Find runs of consecutive numbers using groupby.  The key to the solution
+# is differencing with a range so that consecutive numbers all appear in
+# same group.
+>>> data = [ 1,  4,5,6, 10, 15,16,17,18, 22, 25,26,27,28]
+>>> for k, g in groupby(enumerate(data), lambda (i,x):i-x):
+...     print map(operator.itemgetter(1), g)
+... 
+[1]
+[4, 5, 6]
+[10]
+[15, 16, 17, 18]
+[22]
+[25, 26, 27, 28]
+
+\end{verbatim}
+
+
+\subsection{Recipes \label{itertools-recipes}}
+
+This section shows recipes for creating an extended toolset using the
+existing itertools as building blocks.
+
+The extended tools offer the same high performance as the underlying
+toolset.  The superior memory performance is kept by processing elements one
+at a time rather than bringing the whole iterable into memory all at once.
+Code volume is kept small by linking the tools together in a functional style
+which helps eliminate temporary variables.  High speed is retained by
+preferring ``vectorized'' building blocks over the use of for-loops and
+generators which incur interpreter overhead.
+
+
+\begin{verbatim}
+def take(n, seq):
+    return list(islice(seq, n))
+
+def enumerate(iterable):
+    return izip(count(), iterable)
+
+def tabulate(function):
+    "Return function(0), function(1), ..."
+    return imap(function, count())
+
+def iteritems(mapping):
+    return izip(mapping.iterkeys(), mapping.itervalues())
+
+def nth(iterable, n):
+    "Returns the nth item or raise IndexError"
+    return list(islice(iterable, n, n+1))[0]
+
+def all(seq, pred=None):
+    "Returns True if pred(x) is true for every element in the iterable"
+    for elem in ifilterfalse(pred, seq):
+        return False
+    return True
+
+def any(seq, pred=None):
+    "Returns True if pred(x) is true for at least one element in the iterable"
+    for elem in ifilter(pred, seq):
+        return True
+    return False
+
+def no(seq, pred=None):
+    "Returns True if pred(x) is false for every element in the iterable"
+    for elem in ifilter(pred, seq):
+        return False
+    return True
+
+def quantify(seq, pred=None):
+    "Count how many times the predicate is true in the sequence"
+    return sum(imap(pred, seq))
+
+def padnone(seq):
+    """Returns the sequence elements and then returns None indefinitely.
+
+    Useful for emulating the behavior of the built-in map() function.
+    """
+    return chain(seq, repeat(None))
+
+def ncycles(seq, n):
+    "Returns the sequence elements n times"
+    return chain(*repeat(seq, n))
+
+def dotproduct(vec1, vec2):
+    return sum(imap(operator.mul, vec1, vec2))
+
+def flatten(listOfLists):
+    return list(chain(*listOfLists))
+
+def repeatfunc(func, times=None, *args):
+    """Repeat calls to func with specified arguments.
+    
+    Example:  repeatfunc(random.random)
+    """
+    if times is None:
+        return starmap(func, repeat(args))
+    else:
+        return starmap(func, repeat(args, times))
+
+def pairwise(iterable):
+    "s -> (s0,s1), (s1,s2), (s2, s3), ..."
+    a, b = tee(iterable)
+    try:
+        b.next()
+    except StopIteration:
+        pass
+    return izip(a, b)
+
+def grouper(n, iterable, padvalue=None):
+    "grouper(3, 'abcdefg', 'x') --> ('a','b','c'), ('d','e','f'), ('g','x','x')"
+    return izip(*[chain(iterable, repeat(padvalue, n-1))]*n)
+
+def reverse_map(d):
+    "Return a new dict with swapped keys and values"
+    return dict(izip(d.itervalues(), d))
+
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/libjpeg.tex
===================================================================
--- vendor/Python/current/Doc/lib/libjpeg.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libjpeg.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,80 @@
+\section{\module{jpeg} ---
+         Read and write JPEG files}
+
+\declaremodule{builtin}{jpeg}
+  \platform{IRIX}
+\modulesynopsis{Read and write image files in compressed JPEG format.}
+
+
+The module \module{jpeg} provides access to the jpeg compressor and
+decompressor written by the Independent JPEG Group
+\index{Independent JPEG Group}(IJG). JPEG is a standard for
+compressing pictures; it is defined in ISO 10918.  For details on JPEG
+or the Independent JPEG Group software refer to the JPEG standard or
+the documentation provided with the software.
+
+A portable interface to JPEG image files is available with the Python
+Imaging Library (PIL) by Fredrik Lundh.  Information on PIL is
+available at \url{http://www.pythonware.com/products/pil/}.
+\index{Python Imaging Library}
+\index{PIL (the Python Imaging Library)}
+\index{Lundh, Fredrik}
+
+The \module{jpeg} module defines an exception and some functions.
+
+\begin{excdesc}{error}
+Exception raised by \function{compress()} and \function{decompress()}
+in case of errors.
+\end{excdesc}
+
+\begin{funcdesc}{compress}{data, w, h, b}
+Treat data as a pixmap of width \var{w} and height \var{h}, with
+\var{b} bytes per pixel.  The data is in SGI GL order, so the first
+pixel is in the lower-left corner. This means that \function{gl.lrectread()}
+return data can immediately be passed to \function{compress()}.
+Currently only 1 byte and 4 byte pixels are allowed, the former being
+treated as greyscale and the latter as RGB color.
+\function{compress()} returns a string that contains the compressed
+picture, in JFIF\index{JFIF} format.
+\end{funcdesc}
+
+\begin{funcdesc}{decompress}{data}
+Data is a string containing a picture in JFIF\index{JFIF} format. It
+returns a tuple \code{(\var{data}, \var{width}, \var{height},
+\var{bytesperpixel})}.  Again, the data is suitable to pass to
+\function{gl.lrectwrite()}.
+\end{funcdesc}
+
+\begin{funcdesc}{setoption}{name, value}
+Set various options.  Subsequent \function{compress()} and
+\function{decompress()} calls will use these options.  The following
+options are available:
+
+\begin{tableii}{l|p{3in}}{code}{Option}{Effect}
+  \lineii{'forcegray'}{%
+    Force output to be grayscale, even if input is RGB.}
+  \lineii{'quality'}{%
+    Set the quality of the compressed image to a value between
+    \code{0} and \code{100} (default is \code{75}).  This only affects
+    compression.}
+  \lineii{'optimize'}{%
+    Perform Huffman table optimization.  Takes longer, but results in
+    smaller compressed image.  This only affects compression.}
+  \lineii{'smooth'}{%
+    Perform inter-block smoothing on uncompressed image.  Only useful
+    for low-quality images.  This only affects decompression.}
+\end{tableii}
+\end{funcdesc}
+
+
+\begin{seealso}
+  \seetitle{JPEG Still Image Data Compression Standard}{The 
+            canonical reference for the JPEG image format, by
+            Pennebaker and Mitchell.}
+
+  \seetitle[http://www.w3.org/Graphics/JPEG/itu-t81.pdf]{Information
+            Technology - Digital Compression and Coding of
+            Continuous-tone Still Images - Requirements and
+            Guidelines}{The ISO standard for JPEG is also published as
+            ITU T.81.  This is available online in PDF form.}
+\end{seealso}

Added: vendor/Python/current/Doc/lib/libkeyword.tex
===================================================================
--- vendor/Python/current/Doc/lib/libkeyword.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libkeyword.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,20 @@
+\section{\module{keyword} ---
+         Testing for Python keywords}
+
+\declaremodule{standard}{keyword}
+\modulesynopsis{Test whether a string is a keyword in Python.}
+
+
+This module allows a Python program to determine if a string is a
+keyword.
+
+\begin{funcdesc}{iskeyword}{s}
+Return true if \var{s} is a Python keyword.
+\end{funcdesc}
+
+\begin{datadesc}{kwlist}
+Sequence containing all the keywords defined for the interpreter.  If
+any keywords are defined to only be active when particular
+\module{__future__} statements are in effect, these will be included
+as well.
+\end{datadesc}

Added: vendor/Python/current/Doc/lib/liblinecache.tex
===================================================================
--- vendor/Python/current/Doc/lib/liblinecache.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/liblinecache.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,50 @@
+\section{\module{linecache} ---
+         Random access to text lines}
+
+\declaremodule{standard}{linecache}
+\sectionauthor{Moshe Zadka}{moshez at zadka.site.co.il}
+\modulesynopsis{This module provides random access to individual lines
+                from text files.}
+
+
+The \module{linecache} module allows one to get any line from any file,
+while attempting to optimize internally, using a cache, the common case
+where many lines are read from a single file.  This is used by the
+\refmodule{traceback} module to retrieve source lines for inclusion in 
+the formatted traceback.
+
+The \module{linecache} module defines the following functions:
+
+\begin{funcdesc}{getline}{filename, lineno\optional{, module_globals}}
+Get line \var{lineno} from file named \var{filename}. This function
+will never throw an exception --- it will return \code{''} on errors
+(the terminating newline character will be included for lines that are
+found).
+
+If a file named \var{filename} is not found, the function will look
+for it in the module\indexiii{module}{search}{path} search path,
+\code{sys.path}, after first checking for a \pep{302} \code{__loader__}
+in \var{module_globals}, in case the module was imported from a zipfile
+or other non-filesystem import source. 
+
+\versionadded[The \var{module_globals} parameter was added]{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{clearcache}{}
+Clear the cache.  Use this function if you no longer need lines from
+files previously read using \function{getline()}.
+\end{funcdesc}
+
+\begin{funcdesc}{checkcache}{\optional{filename}}
+Check the cache for validity.  Use this function if files in the cache 
+may have changed on disk, and you require the updated version.  If
+\var{filename} is omitted, it will check all the entries in the cache.
+\end{funcdesc}
+
+Example:
+
+\begin{verbatim}
+>>> import linecache
+>>> linecache.getline('/etc/passwd', 4)
+'sys:x:3:3:sys:/dev:/bin/sh\n'
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/liblocale.tex
===================================================================
--- vendor/Python/current/Doc/lib/liblocale.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/liblocale.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,527 @@
+\section{\module{locale} ---
+         Internationalization services}
+
+\declaremodule{standard}{locale}
+\modulesynopsis{Internationalization services.}
+\moduleauthor{Martin von L\"owis}{martin at v.loewis.de}
+\sectionauthor{Martin von L\"owis}{martin at v.loewis.de}
+
+
+The \module{locale} module opens access to the \POSIX{} locale
+database and functionality. The \POSIX{} locale mechanism allows
+programmers to deal with certain cultural issues in an application,
+without requiring the programmer to know all the specifics of each
+country where the software is executed.
+
+The \module{locale} module is implemented on top of the
+\module{_locale}\refbimodindex{_locale} module, which in turn uses an
+ANSI C locale implementation if available.
+
+The \module{locale} module defines the following exception and
+functions:
+
+
+\begin{excdesc}{Error}
+  Exception raised when \function{setlocale()} fails.
+\end{excdesc}
+
+\begin{funcdesc}{setlocale}{category\optional{, locale}}
+  If \var{locale} is specified, it may be a string, a tuple of the
+  form \code{(\var{language code}, \var{encoding})}, or \code{None}.
+  If it is a tuple, it is converted to a string using the locale
+  aliasing engine.  If \var{locale} is given and not \code{None},
+  \function{setlocale()} modifies the locale setting for the
+  \var{category}.  The available categories are listed in the data
+  description below.  The value is the name of a locale.  An empty
+  string specifies the user's default settings. If the modification of
+  the locale fails, the exception \exception{Error} is raised.  If
+  successful, the new locale setting is returned.
+
+  If \var{locale} is omitted or \code{None}, the current setting for
+  \var{category} is returned.
+
+  \function{setlocale()} is not thread safe on most systems.
+  Applications typically start with a call of
+
+\begin{verbatim}
+import locale
+locale.setlocale(locale.LC_ALL, '')
+\end{verbatim}
+
+  This sets the locale for all categories to the user's default
+  setting (typically specified in the \envvar{LANG} environment
+  variable).  If the locale is not changed thereafter, using
+  multithreading should not cause problems.
+
+  \versionchanged[Added support for tuple values of the \var{locale}
+                  parameter]{2.0}
+\end{funcdesc}
+
+\begin{funcdesc}{localeconv}{}
+  Returns the database of the local conventions as a dictionary.
+  This dictionary has the following strings as keys:
+
+  \begin{tableiii}{l|l|p{3in}}{constant}{Category}{Key}{Meaning}
+    \lineiii{LC_NUMERIC}{\code{'decimal_point'}}
+            {Decimal point character.}
+    \lineiii{}{\code{'grouping'}}
+            {Sequence of numbers specifying which relative positions
+             the \code{'thousands_sep'} is expected.  If the sequence is
+             terminated with \constant{CHAR_MAX}, no further grouping
+             is performed. If the sequence terminates with a \code{0}, 
+             the last group size is repeatedly used.}
+    \lineiii{}{\code{'thousands_sep'}}
+            {Character used between groups.}\hline
+    \lineiii{LC_MONETARY}{\code{'int_curr_symbol'}}
+            {International currency symbol.}
+    \lineiii{}{\code{'currency_symbol'}}
+            {Local currency symbol.}
+    \lineiii{}{\code{'p_cs_precedes/n_cs_precedes'}}
+            {Whether the currency symbol precedes the value (for positive resp.
+             negative values).}
+    \lineiii{}{\code{'p_sep_by_space/n_sep_by_space'}}
+            {Whether the currency symbol is separated from the value 
+             by a space (for positive resp. negative values).}
+    \lineiii{}{\code{'mon_decimal_point'}}
+            {Decimal point used for monetary values.}
+    \lineiii{}{\code{'frac_digits'}}
+            {Number of fractional digits used in local formatting
+             of monetary values.}
+    \lineiii{}{\code{'int_frac_digits'}}
+            {Number of fractional digits used in international
+             formatting of monetary values.}
+    \lineiii{}{\code{'mon_thousands_sep'}}
+            {Group separator used for monetary values.}
+    \lineiii{}{\code{'mon_grouping'}}
+            {Equivalent to \code{'grouping'}, used for monetary
+             values.}
+    \lineiii{}{\code{'positive_sign'}}
+            {Symbol used to annotate a positive monetary value.}
+    \lineiii{}{\code{'negative_sign'}}
+            {Symbol used to annotate a negative monetary value.}
+    \lineiii{}{\code{'p_sign_posn/n_sign_posn'}}
+            {The position of the sign (for positive resp. negative values), see below.}
+  \end{tableiii}
+  
+  All numeric values can be set to \constant{CHAR_MAX} to indicate that
+  there is no value specified in this locale.
+
+  The possible values for \code{'p_sign_posn'} and
+  \code{'n_sign_posn'} are given below.
+
+  \begin{tableii}{c|l}{code}{Value}{Explanation}
+    \lineii{0}{Currency and value are surrounded by parentheses.}
+    \lineii{1}{The sign should precede the value and currency symbol.}
+    \lineii{2}{The sign should follow the value and currency symbol.}
+    \lineii{3}{The sign should immediately precede the value.}
+    \lineii{4}{The sign should immediately follow the value.}
+    \lineii{\constant{CHAR_MAX}}{Nothing is specified in this locale.}
+  \end{tableii}
+\end{funcdesc}
+
+\begin{funcdesc}{nl_langinfo}{option}
+
+Return some locale-specific information as a string. This function is
+not available on all systems, and the set of possible options might
+also vary across platforms. The possible argument values are numbers,
+for which symbolic constants are available in the locale module.
+
+\end{funcdesc}
+
+\begin{funcdesc}{getdefaultlocale}{\optional{envvars}}
+  Tries to determine the default locale settings and returns
+  them as a tuple of the form \code{(\var{language code},
+  \var{encoding})}.
+
+  According to \POSIX, a program which has not called
+  \code{setlocale(LC_ALL, '')} runs using the portable \code{'C'}
+  locale.  Calling \code{setlocale(LC_ALL, '')} lets it use the
+  default locale as defined by the \envvar{LANG} variable.  Since we
+  do not want to interfere with the current locale setting we thus
+  emulate the behavior in the way described above.
+
+  To maintain compatibility with other platforms, not only the
+  \envvar{LANG} variable is tested, but a list of variables given as
+  envvars parameter.  The first found to be defined will be
+  used.  \var{envvars} defaults to the search path used in GNU gettext;
+  it must always contain the variable name \samp{LANG}.  The GNU
+  gettext search path contains \code{'LANGUAGE'}, \code{'LC_ALL'},
+  \code{'LC_CTYPE'}, and \code{'LANG'}, in that order.
+
+  Except for the code \code{'C'}, the language code corresponds to
+  \rfc{1766}.  \var{language code} and \var{encoding} may be
+  \code{None} if their values cannot be determined.
+  \versionadded{2.0}
+\end{funcdesc}
+
+\begin{funcdesc}{getlocale}{\optional{category}}
+  Returns the current setting for the given locale category as
+  sequence containing \var{language code}, \var{encoding}.
+  \var{category} may be one of the \constant{LC_*} values except
+  \constant{LC_ALL}.  It defaults to \constant{LC_CTYPE}.
+
+  Except for the code \code{'C'}, the language code corresponds to
+  \rfc{1766}.  \var{language code} and \var{encoding} may be
+  \code{None} if their values cannot be determined.
+  \versionadded{2.0}
+\end{funcdesc}
+
+\begin{funcdesc}{getpreferredencoding}{\optional{do_setlocale}}
+  Return the encoding used for text data, according to user
+  preferences.  User preferences are expressed differently on
+  different systems, and might not be available programmatically on
+  some systems, so this function only returns a guess.
+
+  On some systems, it is necessary to invoke \function{setlocale}
+  to obtain the user preferences, so this function is not thread-safe.
+  If invoking setlocale is not necessary or desired, \var{do_setlocale}
+  should be set to \code{False}.
+
+  \versionadded{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{normalize}{localename}
+  Returns a normalized locale code for the given locale name.  The
+  returned locale code is formatted for use with
+  \function{setlocale()}.  If normalization fails, the original name
+  is returned unchanged.
+
+  If the given encoding is not known, the function defaults to
+  the default encoding for the locale code just like
+  \function{setlocale()}.
+  \versionadded{2.0}
+\end{funcdesc}
+
+\begin{funcdesc}{resetlocale}{\optional{category}}
+  Sets the locale for \var{category} to the default setting.
+
+  The default setting is determined by calling
+  \function{getdefaultlocale()}.  \var{category} defaults to
+  \constant{LC_ALL}.
+  \versionadded{2.0}
+\end{funcdesc}
+
+\begin{funcdesc}{strcoll}{string1, string2}
+  Compares two strings according to the current
+  \constant{LC_COLLATE} setting. As any other compare function,
+  returns a negative, or a positive value, or \code{0}, depending on
+  whether \var{string1} collates before or after \var{string2} or is
+  equal to it.
+\end{funcdesc}
+
+\begin{funcdesc}{strxfrm}{string}
+  Transforms a string to one that can be used for the built-in
+  function \function{cmp()}\bifuncindex{cmp}, and still returns
+  locale-aware results.  This function can be used when the same
+  string is compared repeatedly, e.g. when collating a sequence of
+  strings.
+\end{funcdesc}
+
+\begin{funcdesc}{format}{format, val\optional{, grouping\optional{, monetary}}}
+  Formats a number \var{val} according to the current
+  \constant{LC_NUMERIC} setting.  The format follows the conventions
+  of the \code{\%} operator.  For floating point values, the decimal
+  point is modified if appropriate.  If \var{grouping} is true, also
+  takes the grouping into account.
+
+  If \var{monetary} is true, the conversion uses monetary thousands
+  separator and grouping strings.
+
+  Please note that this function will only work for exactly one \%char
+  specifier. For whole format strings, use \function{format_string()}.
+
+  \versionchanged[Added the \var{monetary} parameter]{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{format_string}{format, val\optional{, grouping}}
+  Processes formatting specifiers as in \code{format \% val},
+  but takes the current locale settings into account.
+
+  \versionadded{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{currency}{val\optional{, symbol\optional{, grouping\optional{, international}}}}
+  Formats a number \var{val} according to the current \constant{LC_MONETARY}
+  settings. 
+  
+  The returned string includes the currency symbol if \var{symbol} is true,
+  which is the default.
+  If \var{grouping} is true (which is not the default), grouping is done with
+  the value.
+  If \var{international} is true (which is not the default), the international
+  currency symbol is used.
+
+  Note that this function will not work with the `C' locale, so you have to set
+  a locale via \function{setlocale()} first.
+
+  \versionadded{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{str}{float}
+  Formats a floating point number using the same format as the
+  built-in function \code{str(\var{float})}, but takes the decimal
+  point into account.
+\end{funcdesc}
+
+\begin{funcdesc}{atof}{string}
+  Converts a string to a floating point number, following the
+  \constant{LC_NUMERIC} settings.
+\end{funcdesc}
+
+\begin{funcdesc}{atoi}{string}
+  Converts a string to an integer, following the
+  \constant{LC_NUMERIC} conventions.
+\end{funcdesc}
+
+\begin{datadesc}{LC_CTYPE}
+\refstmodindex{string}
+  Locale category for the character type functions.  Depending on the
+  settings of this category, the functions of module
+  \refmodule{string} dealing with case change their behaviour.
+\end{datadesc}
+
+\begin{datadesc}{LC_COLLATE}
+  Locale category for sorting strings.  The functions
+  \function{strcoll()} and \function{strxfrm()} of the
+  \module{locale} module are affected.
+\end{datadesc}
+
+\begin{datadesc}{LC_TIME}
+  Locale category for the formatting of time.  The function
+  \function{time.strftime()} follows these conventions.
+\end{datadesc}
+
+\begin{datadesc}{LC_MONETARY}
+  Locale category for formatting of monetary values.  The available
+  options are available from the \function{localeconv()} function.
+\end{datadesc}
+
+\begin{datadesc}{LC_MESSAGES}
+  Locale category for message display. Python currently does not
+  support application specific locale-aware messages.  Messages
+  displayed by the operating system, like those returned by
+  \function{os.strerror()} might be affected by this category.
+\end{datadesc}
+
+\begin{datadesc}{LC_NUMERIC}
+  Locale category for formatting numbers.  The functions
+  \function{format()}, \function{atoi()}, \function{atof()} and
+  \function{str()} of the \module{locale} module are affected by that
+  category.  All other numeric formatting operations are not
+  affected.
+\end{datadesc}
+
+\begin{datadesc}{LC_ALL}
+  Combination of all locale settings.  If this flag is used when the
+  locale is changed, setting the locale for all categories is
+  attempted. If that fails for any category, no category is changed at
+  all.  When the locale is retrieved using this flag, a string
+  indicating the setting for all categories is returned. This string
+  can be later used to restore the settings.
+\end{datadesc}
+
+\begin{datadesc}{CHAR_MAX}
+  This is a symbolic constant used for different values returned by
+  \function{localeconv()}.
+\end{datadesc}
+
+The \function{nl_langinfo} function accepts one of the following keys.
+Most descriptions are taken from the corresponding description in the
+GNU C library.
+
+\begin{datadesc}{CODESET}
+Return a string with the name of the character encoding used in the
+selected locale.
+\end{datadesc}
+
+\begin{datadesc}{D_T_FMT}
+Return a string that can be used as a format string for strftime(3) to
+represent time and date in a locale-specific way.
+\end{datadesc}
+
+\begin{datadesc}{D_FMT}
+Return a string that can be used as a format string for strftime(3) to
+represent a date in a locale-specific way.
+\end{datadesc}
+
+\begin{datadesc}{T_FMT}
+Return a string that can be used as a format string for strftime(3) to
+represent a time in a locale-specific way.
+\end{datadesc}
+
+\begin{datadesc}{T_FMT_AMPM}
+The return value can be used as a format string for `strftime' to
+represent time in the am/pm format.
+\end{datadesc}
+
+\begin{datadesc}{DAY_1 ... DAY_7}
+Return name of the n-th day of the week. \warning{This
+follows the US convention of \constant{DAY_1} being Sunday, not the
+international convention (ISO 8601) that Monday is the first day of
+the week.}
+\end{datadesc}
+
+\begin{datadesc}{ABDAY_1 ... ABDAY_7}
+Return abbreviated name of the n-th day of the week.
+\end{datadesc}
+
+\begin{datadesc}{MON_1 ... MON_12}
+Return name of the n-th month.
+\end{datadesc}
+
+\begin{datadesc}{ABMON_1 ... ABMON_12}
+Return abbreviated name of the n-th month.
+\end{datadesc}
+
+\begin{datadesc}{RADIXCHAR}
+Return radix character (decimal dot, decimal comma, etc.)
+\end{datadesc}
+
+\begin{datadesc}{THOUSEP}
+Return separator character for thousands (groups of three digits).
+\end{datadesc}
+
+\begin{datadesc}{YESEXPR}
+Return a regular expression that can be used with the regex
+function to recognize a positive response to a yes/no question.
+\warning{The expression is in the syntax suitable for the
+\cfunction{regex()} function from the C library, which might differ
+from the syntax used in \refmodule{re}.}
+\end{datadesc}
+
+\begin{datadesc}{NOEXPR}
+Return a regular expression that can be used with the regex(3)
+function to recognize a negative response to a yes/no question.
+\end{datadesc}
+
+\begin{datadesc}{CRNCYSTR}
+Return the currency symbol, preceded by "-" if the symbol should
+appear before the value, "+" if the symbol should appear after the
+value, or "." if the symbol should replace the radix character.
+\end{datadesc}
+
+\begin{datadesc}{ERA}
+The return value represents the era used in the current locale.
+
+Most locales do not define this value.  An example of a locale which
+does define this value is the Japanese one.  In Japan, the traditional
+representation of dates includes the name of the era corresponding to
+the then-emperor's reign.
+
+Normally it should not be necessary to use this value directly.
+Specifying the \code{E} modifier in their format strings causes the
+\function{strftime} function to use this information.  The format of the
+returned string is not specified, and therefore you should not assume
+knowledge of it on different systems.
+\end{datadesc}
+
+\begin{datadesc}{ERA_YEAR}
+The return value gives the year in the relevant era of the locale.
+\end{datadesc}
+
+\begin{datadesc}{ERA_D_T_FMT}
+This return value can be used as a format string for
+\function{strftime} to represent dates and times in a locale-specific
+era-based way.
+\end{datadesc}
+
+\begin{datadesc}{ERA_D_FMT}
+This return value can be used as a format string for
+\function{strftime} to represent time in a locale-specific era-based
+way.
+\end{datadesc}
+
+\begin{datadesc}{ALT_DIGITS}
+The return value is a representation of up to 100 values used to
+represent the values 0 to 99.
+\end{datadesc}
+
+Example:
+
+\begin{verbatim}
+>>> import locale
+>>> loc = locale.getlocale(locale.LC_ALL) # get current locale
+>>> locale.setlocale(locale.LC_ALL, 'de_DE') # use German locale; name might vary with platform
+>>> locale.strcoll('f\xe4n', 'foo') # compare a string containing an umlaut 
+>>> locale.setlocale(locale.LC_ALL, '') # use user's preferred locale
+>>> locale.setlocale(locale.LC_ALL, 'C') # use default (C) locale
+>>> locale.setlocale(locale.LC_ALL, loc) # restore saved locale
+\end{verbatim}
+
+
+\subsection{Background, details, hints, tips and caveats}
+
+The C standard defines the locale as a program-wide property that may
+be relatively expensive to change.  On top of that, some
+implementation are broken in such a way that frequent locale changes
+may cause core dumps.  This makes the locale somewhat painful to use
+correctly.
+
+Initially, when a program is started, the locale is the \samp{C} locale, no
+matter what the user's preferred locale is.  The program must
+explicitly say that it wants the user's preferred locale settings by
+calling \code{setlocale(LC_ALL, '')}.
+
+It is generally a bad idea to call \function{setlocale()} in some library
+routine, since as a side effect it affects the entire program.  Saving
+and restoring it is almost as bad: it is expensive and affects other
+threads that happen to run before the settings have been restored.
+
+If, when coding a module for general use, you need a locale
+independent version of an operation that is affected by the locale
+(such as \function{string.lower()}, or certain formats used with
+\function{time.strftime()}), you will have to find a way to do it
+without using the standard library routine.  Even better is convincing
+yourself that using locale settings is okay.  Only as a last resort
+should you document that your module is not compatible with
+non-\samp{C} locale settings.
+
+The case conversion functions in the
+\refmodule{string}\refstmodindex{string} module are affected by the
+locale settings.  When a call to the \function{setlocale()} function
+changes the \constant{LC_CTYPE} settings, the variables
+\code{string.lowercase}, \code{string.uppercase} and
+\code{string.letters} are recalculated.  Note that code that uses
+these variable through `\keyword{from} ... \keyword{import} ...',
+e.g.\ \code{from string import letters}, is not affected by subsequent
+\function{setlocale()} calls.
+
+The only way to perform numeric operations according to the locale
+is to use the special functions defined by this module:
+\function{atof()}, \function{atoi()}, \function{format()},
+\function{str()}.
+
+\subsection{For extension writers and programs that embed Python
+            \label{embedding-locale}}
+
+Extension modules should never call \function{setlocale()}, except to
+find out what the current locale is.  But since the return value can
+only be used portably to restore it, that is not very useful (except
+perhaps to find out whether or not the locale is \samp{C}).
+
+When Python code uses the \module{locale} module to change the locale,
+this also affects the embedding application.  If the embedding
+application doesn't want this to happen, it should remove the
+\module{_locale} extension module (which does all the work) from the
+table of built-in modules in the \file{config.c} file, and make sure
+that the \module{_locale} module is not accessible as a shared library.
+
+
+\subsection{Access to message catalogs \label{locale-gettext}}
+
+The locale module exposes the C library's gettext interface on systems
+that provide this interface.  It consists of the functions
+\function{gettext()}, \function{dgettext()}, \function{dcgettext()},
+\function{textdomain()}, \function{bindtextdomain()}, and
+\function{bind_textdomain_codeset()}.  These are similar to the same
+functions in the \refmodule{gettext} module, but use the C library's
+binary format for message catalogs, and the C library's search
+algorithms for locating message catalogs. 
+
+Python applications should normally find no need to invoke these
+functions, and should use \refmodule{gettext} instead.  A known
+exception to this rule are applications that link use additional C
+libraries which internally invoke \cfunction{gettext()} or
+\function{dcgettext()}.  For these applications, it may be necessary to
+bind the text domain, so that the libraries can properly locate their
+message catalogs.

Added: vendor/Python/current/Doc/lib/liblogging.tex
===================================================================
--- vendor/Python/current/Doc/lib/liblogging.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/liblogging.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1729 @@
+\section{\module{logging} ---
+         Logging facility for Python}
+
+\declaremodule{standard}{logging}
+
+% These apply to all modules, and may be given more than once:
+
+\moduleauthor{Vinay Sajip}{vinay_sajip at red-dove.com}
+\sectionauthor{Vinay Sajip}{vinay_sajip at red-dove.com}
+
+\modulesynopsis{Logging module for Python based on \pep{282}.}
+
+\indexii{Errors}{logging}
+
+\versionadded{2.3}
+This module defines functions and classes which implement a flexible
+error logging system for applications.
+
+Logging is performed by calling methods on instances of the
+\class{Logger} class (hereafter called \dfn{loggers}). Each instance has a
+name, and they are conceptually arranged in a name space hierarchy
+using dots (periods) as separators. For example, a logger named
+"scan" is the parent of loggers "scan.text", "scan.html" and "scan.pdf".
+Logger names can be anything you want, and indicate the area of an
+application in which a logged message originates.
+
+Logged messages also have levels of importance associated with them.
+The default levels provided are \constant{DEBUG}, \constant{INFO},
+\constant{WARNING}, \constant{ERROR} and \constant{CRITICAL}. As a
+convenience, you indicate the importance of a logged message by calling
+an appropriate method of \class{Logger}. The methods are
+\method{debug()}, \method{info()}, \method{warning()}, \method{error()} and
+\method{critical()}, which mirror the default levels. You are not
+constrained to use these levels: you can specify your own and use a
+more general \class{Logger} method, \method{log()}, which takes an
+explicit level argument.
+
+The numeric values of logging levels are given in the following table. These
+are primarily of interest if you want to define your own levels, and need
+them to have specific values relative to the predefined levels. If you
+define a level with the same numeric value, it overwrites the predefined
+value; the predefined name is lost.
+
+\begin{tableii}{l|l}{code}{Level}{Numeric value}
+  \lineii{CRITICAL}{50}
+  \lineii{ERROR}{40}
+  \lineii{WARNING}{30}
+  \lineii{INFO}{20}
+  \lineii{DEBUG}{10}
+  \lineii{NOTSET}{0}
+\end{tableii}
+
+Levels can also be associated with loggers, being set either by the
+developer or through loading a saved logging configuration. When a
+logging method is called on a logger, the logger compares its own
+level with the level associated with the method call. If the logger's
+level is higher than the method call's, no logging message is actually
+generated. This is the basic mechanism controlling the verbosity of
+logging output.
+
+Logging messages are encoded as instances of the \class{LogRecord} class.
+When a logger decides to actually log an event, a \class{LogRecord}
+instance is created from the logging message.
+
+Logging messages are subjected to a dispatch mechanism through the
+use of \dfn{handlers}, which are instances of subclasses of the
+\class{Handler} class. Handlers are responsible for ensuring that a logged
+message (in the form of a \class{LogRecord}) ends up in a particular
+location (or set of locations) which is useful for the target audience for
+that message (such as end users, support desk staff, system administrators,
+developers). Handlers are passed \class{LogRecord} instances intended for
+particular destinations. Each logger can have zero, one or more handlers
+associated with it (via the \method{addHandler()} method of \class{Logger}).
+In addition to any handlers directly associated with a logger,
+\emph{all handlers associated with all ancestors of the logger} are
+called to dispatch the message.
+
+Just as for loggers, handlers can have levels associated with them.
+A handler's level acts as a filter in the same way as a logger's level does.
+If a handler decides to actually dispatch an event, the \method{emit()} method
+is used to send the message to its destination. Most user-defined subclasses
+of \class{Handler} will need to override this \method{emit()}.
+
+In addition to the base \class{Handler} class, many useful subclasses
+are provided:
+
+\begin{enumerate}
+
+\item \class{StreamHandler} instances send error messages to
+streams (file-like objects).
+
+\item \class{FileHandler} instances send error messages to disk
+files.
+
+\item \class{BaseRotatingHandler} is the base class for handlers that
+rotate log files at a certain point. It is not meant to be  instantiated
+directly. Instead, use \class{RotatingFileHandler} or
+\class{TimedRotatingFileHandler}.
+
+\item \class{RotatingFileHandler} instances send error messages to disk
+files, with support for maximum log file sizes and log file rotation.
+
+\item \class{TimedRotatingFileHandler} instances send error messages to
+disk files rotating the log file at certain timed intervals.
+
+\item \class{SocketHandler} instances send error messages to
+TCP/IP sockets.
+
+\item \class{DatagramHandler} instances send error messages to UDP
+sockets.
+
+\item \class{SMTPHandler} instances send error messages to a
+designated email address.
+
+\item \class{SysLogHandler} instances send error messages to a
+\UNIX{} syslog daemon, possibly on a remote machine.
+
+\item \class{NTEventLogHandler} instances send error messages to a
+Windows NT/2000/XP event log.
+
+\item \class{MemoryHandler} instances send error messages to a
+buffer in memory, which is flushed whenever specific criteria are
+met.
+
+\item \class{HTTPHandler} instances send error messages to an
+HTTP server using either \samp{GET} or \samp{POST} semantics.
+
+\end{enumerate}
+
+The \class{StreamHandler} and \class{FileHandler} classes are defined
+in the core logging package. The other handlers are defined in a sub-
+module, \module{logging.handlers}. (There is also another sub-module,
+\module{logging.config}, for configuration functionality.)
+
+Logged messages are formatted for presentation through instances of the
+\class{Formatter} class. They are initialized with a format string
+suitable for use with the \% operator and a dictionary.
+
+For formatting multiple messages in a batch, instances of
+\class{BufferingFormatter} can be used. In addition to the format string
+(which is applied to each message in the batch), there is provision for
+header and trailer format strings.
+
+When filtering based on logger level and/or handler level is not enough,
+instances of \class{Filter} can be added to both \class{Logger} and
+\class{Handler} instances (through their \method{addFilter()} method).
+Before deciding to process a message further, both loggers and handlers
+consult all their filters for permission. If any filter returns a false
+value, the message is not processed further.
+
+The basic \class{Filter} functionality allows filtering by specific logger
+name. If this feature is used, messages sent to the named logger and its
+children are allowed through the filter, and all others dropped.
+
+In addition to the classes described above, there are a number of module-
+level functions.
+
+\begin{funcdesc}{getLogger}{\optional{name}}
+Return a logger with the specified name or, if no name is specified, return
+a logger which is the root logger of the hierarchy. If specified, the name
+is typically a dot-separated hierarchical name like \var{"a"}, \var{"a.b"}
+or \var{"a.b.c.d"}. Choice of these names is entirely up to the developer
+who is using logging.
+
+All calls to this function with a given name return the same logger instance.
+This means that logger instances never need to be passed between different
+parts of an application.
+\end{funcdesc}
+
+\begin{funcdesc}{getLoggerClass}{}
+Return either the standard \class{Logger} class, or the last class passed to
+\function{setLoggerClass()}. This function may be called from within a new
+class definition, to ensure that installing a customised \class{Logger} class
+will not undo customisations already applied by other code. For example:
+
+\begin{verbatim}
+ class MyLogger(logging.getLoggerClass()):
+     # ... override behaviour here
+\end{verbatim}
+
+\end{funcdesc}
+
+\begin{funcdesc}{debug}{msg\optional{, *args\optional{, **kwargs}}}
+Logs a message with level \constant{DEBUG} on the root logger.
+The \var{msg} is the message format string, and the \var{args} are the
+arguments which are merged into \var{msg} using the string formatting
+operator. (Note that this means that you can use keywords in the
+format string, together with a single dictionary argument.)
+
+There are two keyword arguments in \var{kwargs} which are inspected:
+\var{exc_info} which, if it does not evaluate as false, causes exception
+information to be added to the logging message. If an exception tuple (in the
+format returned by \function{sys.exc_info()}) is provided, it is used;
+otherwise, \function{sys.exc_info()} is called to get the exception
+information.
+
+The other optional keyword argument is \var{extra} which can be used to pass
+a dictionary which is used to populate the __dict__ of the LogRecord created
+for the logging event with user-defined attributes. These custom attributes
+can then be used as you like. For example, they could be incorporated into
+logged messages. For example:
+
+\begin{verbatim}
+ FORMAT = "%(asctime)-15s %(clientip)s %(user)-8s %(message)s"
+ logging.basicConfig(format=FORMAT)
+ dict = { 'clientip' : '192.168.0.1', 'user' : 'fbloggs' }
+ logging.warning("Protocol problem: %s", "connection reset", extra=d)
+\end{verbatim}
+
+would print something like
+\begin{verbatim}
+2006-02-08 22:20:02,165 192.168.0.1 fbloggs  Protocol problem: connection reset
+\end{verbatim}
+
+The keys in the dictionary passed in \var{extra} should not clash with the keys
+used by the logging system. (See the \class{Formatter} documentation for more
+information on which keys are used by the logging system.)
+
+If you choose to use these attributes in logged messages, you need to exercise
+some care. In the above example, for instance, the \class{Formatter} has been
+set up with a format string which expects 'clientip' and 'user' in the
+attribute dictionary of the LogRecord. If these are missing, the message will
+not be logged because a string formatting exception will occur. So in this
+case, you always need to pass the \var{extra} dictionary with these keys.
+
+While this might be annoying, this feature is intended for use in specialized
+circumstances, such as multi-threaded servers where the same code executes
+in many contexts, and interesting conditions which arise are dependent on this
+context (such as remote client IP address and authenticated user name, in the
+above example). In such circumstances, it is likely that specialized
+\class{Formatter}s would be used with particular \class{Handler}s.
+
+\versionchanged[\var{extra} was added]{2.5}
+
+\end{funcdesc}
+
+\begin{funcdesc}{info}{msg\optional{, *args\optional{, **kwargs}}}
+Logs a message with level \constant{INFO} on the root logger.
+The arguments are interpreted as for \function{debug()}.
+\end{funcdesc}
+
+\begin{funcdesc}{warning}{msg\optional{, *args\optional{, **kwargs}}}
+Logs a message with level \constant{WARNING} on the root logger.
+The arguments are interpreted as for \function{debug()}.
+\end{funcdesc}
+
+\begin{funcdesc}{error}{msg\optional{, *args\optional{, **kwargs}}}
+Logs a message with level \constant{ERROR} on the root logger.
+The arguments are interpreted as for \function{debug()}.
+\end{funcdesc}
+
+\begin{funcdesc}{critical}{msg\optional{, *args\optional{, **kwargs}}}
+Logs a message with level \constant{CRITICAL} on the root logger.
+The arguments are interpreted as for \function{debug()}.
+\end{funcdesc}
+
+\begin{funcdesc}{exception}{msg\optional{, *args}}
+Logs a message with level \constant{ERROR} on the root logger.
+The arguments are interpreted as for \function{debug()}. Exception info
+is added to the logging message. This function should only be called
+from an exception handler.
+\end{funcdesc}
+
+\begin{funcdesc}{log}{level, msg\optional{, *args\optional{, **kwargs}}}
+Logs a message with level \var{level} on the root logger.
+The other arguments are interpreted as for \function{debug()}.
+\end{funcdesc}
+
+\begin{funcdesc}{disable}{lvl}
+Provides an overriding level \var{lvl} for all loggers which takes
+precedence over the logger's own level. When the need arises to
+temporarily throttle logging output down across the whole application,
+this function can be useful.
+\end{funcdesc}
+
+\begin{funcdesc}{addLevelName}{lvl, levelName}
+Associates level \var{lvl} with text \var{levelName} in an internal
+dictionary, which is used to map numeric levels to a textual
+representation, for example when a \class{Formatter} formats a message.
+This function can also be used to define your own levels. The only
+constraints are that all levels used must be registered using this
+function, levels should be positive integers and they should increase
+in increasing order of severity.
+\end{funcdesc}
+
+\begin{funcdesc}{getLevelName}{lvl}
+Returns the textual representation of logging level \var{lvl}. If the
+level is one of the predefined levels \constant{CRITICAL},
+\constant{ERROR}, \constant{WARNING}, \constant{INFO} or \constant{DEBUG}
+then you get the corresponding string. If you have associated levels
+with names using \function{addLevelName()} then the name you have associated
+with \var{lvl} is returned. If a numeric value corresponding to one of the
+defined levels is passed in, the corresponding string representation is
+returned. Otherwise, the string "Level \%s" \% lvl is returned.
+\end{funcdesc}
+
+\begin{funcdesc}{makeLogRecord}{attrdict}
+Creates and returns a new \class{LogRecord} instance whose attributes are
+defined by \var{attrdict}. This function is useful for taking a pickled
+\class{LogRecord} attribute dictionary, sent over a socket, and reconstituting
+it as a \class{LogRecord} instance at the receiving end.
+\end{funcdesc}
+
+\begin{funcdesc}{basicConfig}{\optional{**kwargs}}
+Does basic configuration for the logging system by creating a
+\class{StreamHandler} with a default \class{Formatter} and adding it to
+the root logger. The functions \function{debug()}, \function{info()},
+\function{warning()}, \function{error()} and \function{critical()} will call
+\function{basicConfig()} automatically if no handlers are defined for the
+root logger.
+
+\versionchanged[Formerly, \function{basicConfig} did not take any keyword
+arguments]{2.4}
+
+The following keyword arguments are supported.
+
+\begin{tableii}{l|l}{code}{Format}{Description}
+\lineii{filename}{Specifies that a FileHandler be created, using the
+specified filename, rather than a StreamHandler.}
+\lineii{filemode}{Specifies the mode to open the file, if filename is
+specified (if filemode is unspecified, it defaults to 'a').}
+\lineii{format}{Use the specified format string for the handler.}
+\lineii{datefmt}{Use the specified date/time format.}
+\lineii{level}{Set the root logger level to the specified level.}
+\lineii{stream}{Use the specified stream to initialize the StreamHandler.
+Note that this argument is incompatible with 'filename' - if both
+are present, 'stream' is ignored.}
+\end{tableii}
+
+\end{funcdesc}
+
+\begin{funcdesc}{shutdown}{}
+Informs the logging system to perform an orderly shutdown by flushing and
+closing all handlers.
+\end{funcdesc}
+
+\begin{funcdesc}{setLoggerClass}{klass}
+Tells the logging system to use the class \var{klass} when instantiating a
+logger. The class should define \method{__init__()} such that only a name
+argument is required, and the \method{__init__()} should call
+\method{Logger.__init__()}. This function is typically called before any
+loggers are instantiated by applications which need to use custom logger
+behavior.
+\end{funcdesc}
+
+
+\begin{seealso}
+  \seepep{282}{A Logging System}
+         {The proposal which described this feature for inclusion in
+          the Python standard library.}
+  \seelink{http://www.red-dove.com/python_logging.html}
+          {Original Python \module{logging} package}
+          {This is the original source for the \module{logging}
+           package.  The version of the package available from this
+           site is suitable for use with Python 1.5.2, 2.1.x and 2.2.x,
+           which do not include the \module{logging} package in the standard
+           library.}
+\end{seealso}
+
+
+\subsection{Logger Objects}
+
+Loggers have the following attributes and methods. Note that Loggers are
+never instantiated directly, but always through the module-level function
+\function{logging.getLogger(name)}.
+
+\begin{datadesc}{propagate}
+If this evaluates to false, logging messages are not passed by this
+logger or by child loggers to higher level (ancestor) loggers. The
+constructor sets this attribute to 1.
+\end{datadesc}
+
+\begin{methoddesc}{setLevel}{lvl}
+Sets the threshold for this logger to \var{lvl}. Logging messages
+which are less severe than \var{lvl} will be ignored. When a logger is
+created, the level is set to \constant{NOTSET} (which causes all messages
+to be processed when the logger is the root logger, or delegation to the
+parent when the logger is a non-root logger). Note that the root logger
+is created with level \constant{WARNING}.
+
+The term "delegation to the parent" means that if a logger has a level
+of NOTSET, its chain of ancestor loggers is traversed until either an
+ancestor with a level other than NOTSET is found, or the root is
+reached.
+
+If an ancestor is found with a level other than NOTSET, then that
+ancestor's level is treated as the effective level of the logger where
+the ancestor search began, and is used to determine how a logging
+event is handled.
+
+If the root is reached, and it has a level of NOTSET, then all
+messages will be processed. Otherwise, the root's level will be used
+as the effective level.
+\end{methoddesc}
+
+\begin{methoddesc}{isEnabledFor}{lvl}
+Indicates if a message of severity \var{lvl} would be processed by
+this logger.  This method checks first the module-level level set by
+\function{logging.disable(lvl)} and then the logger's effective level as
+determined by \method{getEffectiveLevel()}.
+\end{methoddesc}
+
+\begin{methoddesc}{getEffectiveLevel}{}
+Indicates the effective level for this logger. If a value other than
+\constant{NOTSET} has been set using \method{setLevel()}, it is returned.
+Otherwise, the hierarchy is traversed towards the root until a value
+other than \constant{NOTSET} is found, and that value is returned.
+\end{methoddesc}
+
+\begin{methoddesc}{debug}{msg\optional{, *args\optional{, **kwargs}}}
+Logs a message with level \constant{DEBUG} on this logger.
+The \var{msg} is the message format string, and the \var{args} are the
+arguments which are merged into \var{msg} using the string formatting
+operator. (Note that this means that you can use keywords in the
+format string, together with a single dictionary argument.)
+
+There are two keyword arguments in \var{kwargs} which are inspected:
+\var{exc_info} which, if it does not evaluate as false, causes exception
+information to be added to the logging message. If an exception tuple (in the
+format returned by \function{sys.exc_info()}) is provided, it is used;
+otherwise, \function{sys.exc_info()} is called to get the exception
+information.
+
+The other optional keyword argument is \var{extra} which can be used to pass
+a dictionary which is used to populate the __dict__ of the LogRecord created
+for the logging event with user-defined attributes. These custom attributes
+can then be used as you like. For example, they could be incorporated into
+logged messages. For example:
+
+\begin{verbatim}
+ FORMAT = "%(asctime)-15s %(clientip)s %(user)-8s %(message)s"
+ logging.basicConfig(format=FORMAT)
+ dict = { 'clientip' : '192.168.0.1', 'user' : 'fbloggs' }
+ logger = logging.getLogger("tcpserver")
+ logger.warning("Protocol problem: %s", "connection reset", extra=d)
+\end{verbatim}
+
+would print something like
+\begin{verbatim}
+2006-02-08 22:20:02,165 192.168.0.1 fbloggs  Protocol problem: connection reset
+\end{verbatim}
+
+The keys in the dictionary passed in \var{extra} should not clash with the keys
+used by the logging system. (See the \class{Formatter} documentation for more
+information on which keys are used by the logging system.)
+
+If you choose to use these attributes in logged messages, you need to exercise
+some care. In the above example, for instance, the \class{Formatter} has been
+set up with a format string which expects 'clientip' and 'user' in the
+attribute dictionary of the LogRecord. If these are missing, the message will
+not be logged because a string formatting exception will occur. So in this
+case, you always need to pass the \var{extra} dictionary with these keys.
+
+While this might be annoying, this feature is intended for use in specialized
+circumstances, such as multi-threaded servers where the same code executes
+in many contexts, and interesting conditions which arise are dependent on this
+context (such as remote client IP address and authenticated user name, in the
+above example). In such circumstances, it is likely that specialized
+\class{Formatter}s would be used with particular \class{Handler}s.
+
+\versionchanged[\var{extra} was added]{2.5}
+
+\end{methoddesc}
+
+\begin{methoddesc}{info}{msg\optional{, *args\optional{, **kwargs}}}
+Logs a message with level \constant{INFO} on this logger.
+The arguments are interpreted as for \method{debug()}.
+\end{methoddesc}
+
+\begin{methoddesc}{warning}{msg\optional{, *args\optional{, **kwargs}}}
+Logs a message with level \constant{WARNING} on this logger.
+The arguments are interpreted as for \method{debug()}.
+\end{methoddesc}
+
+\begin{methoddesc}{error}{msg\optional{, *args\optional{, **kwargs}}}
+Logs a message with level \constant{ERROR} on this logger.
+The arguments are interpreted as for \method{debug()}.
+\end{methoddesc}
+
+\begin{methoddesc}{critical}{msg\optional{, *args\optional{, **kwargs}}}
+Logs a message with level \constant{CRITICAL} on this logger.
+The arguments are interpreted as for \method{debug()}.
+\end{methoddesc}
+
+\begin{methoddesc}{log}{lvl, msg\optional{, *args\optional{, **kwargs}}}
+Logs a message with integer level \var{lvl} on this logger.
+The other arguments are interpreted as for \method{debug()}.
+\end{methoddesc}
+
+\begin{methoddesc}{exception}{msg\optional{, *args}}
+Logs a message with level \constant{ERROR} on this logger.
+The arguments are interpreted as for \method{debug()}. Exception info
+is added to the logging message. This method should only be called
+from an exception handler.
+\end{methoddesc}
+
+\begin{methoddesc}{addFilter}{filt}
+Adds the specified filter \var{filt} to this logger.
+\end{methoddesc}
+
+\begin{methoddesc}{removeFilter}{filt}
+Removes the specified filter \var{filt} from this logger.
+\end{methoddesc}
+
+\begin{methoddesc}{filter}{record}
+Applies this logger's filters to the record and returns a true value if
+the record is to be processed.
+\end{methoddesc}
+
+\begin{methoddesc}{addHandler}{hdlr}
+Adds the specified handler \var{hdlr} to this logger.
+\end{methoddesc}
+
+\begin{methoddesc}{removeHandler}{hdlr}
+Removes the specified handler \var{hdlr} from this logger.
+\end{methoddesc}
+
+\begin{methoddesc}{findCaller}{}
+Finds the caller's source filename and line number. Returns the filename,
+line number and function name as a 3-element tuple.
+\versionchanged[The function name was added. In earlier versions, the
+filename and line number were returned as a 2-element tuple.]{2.5}
+\end{methoddesc}
+
+\begin{methoddesc}{handle}{record}
+Handles a record by passing it to all handlers associated with this logger
+and its ancestors (until a false value of \var{propagate} is found).
+This method is used for unpickled records received from a socket, as well
+as those created locally. Logger-level filtering is applied using
+\method{filter()}.
+\end{methoddesc}
+
+\begin{methoddesc}{makeRecord}{name, lvl, fn, lno, msg, args, exc_info
+                               \optional{, func, extra}}
+This is a factory method which can be overridden in subclasses to create
+specialized \class{LogRecord} instances.
+\versionchanged[\var{func} and \var{extra} were added]{2.5}
+\end{methoddesc}
+
+\subsection{Basic example \label{minimal-example}}
+
+\versionchanged[formerly \function{basicConfig} did not take any keyword
+arguments]{2.4}
+
+The \module{logging} package provides a lot of flexibility, and its
+configuration can appear daunting.  This section demonstrates that simple
+use of the logging package is possible.
+
+The simplest example shows logging to the console:
+
+\begin{verbatim}
+import logging
+
+logging.debug('A debug message')
+logging.info('Some information')
+logging.warning('A shot across the bows')
+\end{verbatim}
+
+If you run the above script, you'll see this:
+\begin{verbatim}
+WARNING:root:A shot across the bows
+\end{verbatim}
+
+Because no particular logger was specified, the system used the root logger.
+The debug and info messages didn't appear because by default, the root
+logger is configured to only handle messages with a severity of WARNING
+or above. The message format is also a configuration default, as is the output
+destination of the messages - \code{sys.stderr}. The severity level,
+the message format and destination can be easily changed, as shown in
+the example below:
+
+\begin{verbatim}
+import logging
+
+logging.basicConfig(level=logging.DEBUG,
+                    format='%(asctime)s %(levelname)s %(message)s',
+                    filename='/tmp/myapp.log',
+                    filemode='w')
+logging.debug('A debug message')
+logging.info('Some information')
+logging.warning('A shot across the bows')
+\end{verbatim}
+
+The \method{basicConfig()} method is used to change the configuration
+defaults, which results in output (written to \code{/tmp/myapp.log})
+which should look something like the following:
+
+\begin{verbatim}
+2004-07-02 13:00:08,743 DEBUG A debug message
+2004-07-02 13:00:08,743 INFO Some information
+2004-07-02 13:00:08,743 WARNING A shot across the bows
+\end{verbatim}
+
+This time, all messages with a severity of DEBUG or above were handled,
+and the format of the messages was also changed, and output went to the
+specified file rather than the console.
+
+Formatting uses standard Python string formatting - see section
+\ref{typesseq-strings}. The format string takes the following
+common specifiers. For a complete list of specifiers, consult the
+\class{Formatter} documentation.
+
+\begin{tableii}{l|l}{code}{Format}{Description}
+\lineii{\%(name)s}     {Name of the logger (logging channel).}
+\lineii{\%(levelname)s}{Text logging level for the message
+                        (\code{'DEBUG'}, \code{'INFO'},
+                        \code{'WARNING'}, \code{'ERROR'},
+                        \code{'CRITICAL'}).}
+\lineii{\%(asctime)s}  {Human-readable time when the \class{LogRecord}
+                        was created.  By default this is of the form
+                        ``2003-07-08 16:49:45,896'' (the numbers after the
+                        comma are millisecond portion of the time).}
+\lineii{\%(message)s}  {The logged message.}
+\end{tableii}
+
+To change the date/time format, you can pass an additional keyword parameter,
+\var{datefmt}, as in the following:
+
+\begin{verbatim}
+import logging
+
+logging.basicConfig(level=logging.DEBUG,
+                    format='%(asctime)s %(levelname)-8s %(message)s',
+                    datefmt='%a, %d %b %Y %H:%M:%S',
+                    filename='/temp/myapp.log',
+                    filemode='w')
+logging.debug('A debug message')
+logging.info('Some information')
+logging.warning('A shot across the bows')
+\end{verbatim}
+
+which would result in output like
+
+\begin{verbatim}
+Fri, 02 Jul 2004 13:06:18 DEBUG    A debug message
+Fri, 02 Jul 2004 13:06:18 INFO     Some information
+Fri, 02 Jul 2004 13:06:18 WARNING  A shot across the bows
+\end{verbatim}
+
+The date format string follows the requirements of \function{strftime()} -
+see the documentation for the \refmodule{time} module.
+
+If, instead of sending logging output to the console or a file, you'd rather
+use a file-like object which you have created separately, you can pass it
+to \function{basicConfig()} using the \var{stream} keyword argument. Note
+that if both \var{stream} and \var{filename} keyword arguments are passed,
+the \var{stream} argument is ignored.
+
+Of course, you can put variable information in your output. To do this,
+simply have the message be a format string and pass in additional arguments
+containing the variable information, as in the following example:
+
+\begin{verbatim}
+import logging
+
+logging.basicConfig(level=logging.DEBUG,
+                    format='%(asctime)s %(levelname)-8s %(message)s',
+                    datefmt='%a, %d %b %Y %H:%M:%S',
+                    filename='/temp/myapp.log',
+                    filemode='w')
+logging.error('Pack my box with %d dozen %s', 5, 'liquor jugs')
+\end{verbatim}
+
+which would result in
+
+\begin{verbatim}
+Wed, 21 Jul 2004 15:35:16 ERROR    Pack my box with 5 dozen liquor jugs
+\end{verbatim}
+
+\subsection{Logging to multiple destinations \label{multiple-destinations}}
+
+Let's say you want to log to console and file with different message formats
+and in differing circumstances. Say you want to log messages with levels
+of DEBUG and higher to file, and those messages at level INFO and higher to
+the console. Let's also assume that the file should contain timestamps, but
+the console messages should not. Here's how you can achieve this:
+
+\begin{verbatim}
+import logging
+
+# set up logging to file - see previous section for more details
+logging.basicConfig(level=logging.DEBUG,
+                    format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s',
+                    datefmt='%m-%d %H:%M',
+                    filename='/temp/myapp.log',
+                    filemode='w')
+# define a Handler which writes INFO messages or higher to the sys.stderr
+console = logging.StreamHandler()
+console.setLevel(logging.INFO)
+# set a format which is simpler for console use
+formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
+# tell the handler to use this format
+console.setFormatter(formatter)
+# add the handler to the root logger
+logging.getLogger('').addHandler(console)
+
+# Now, we can log to the root logger, or any other logger. First the root...
+logging.info('Jackdaws love my big sphinx of quartz.')
+
+# Now, define a couple of other loggers which might represent areas in your
+# application:
+
+logger1 = logging.getLogger('myapp.area1')
+logger2 = logging.getLogger('myapp.area2')
+
+logger1.debug('Quick zephyrs blow, vexing daft Jim.')
+logger1.info('How quickly daft jumping zebras vex.')
+logger2.warning('Jail zesty vixen who grabbed pay from quack.')
+logger2.error('The five boxing wizards jump quickly.')
+\end{verbatim}
+
+When you run this, on the console you will see
+
+\begin{verbatim}
+root        : INFO     Jackdaws love my big sphinx of quartz.
+myapp.area1 : INFO     How quickly daft jumping zebras vex.
+myapp.area2 : WARNING  Jail zesty vixen who grabbed pay from quack.
+myapp.area2 : ERROR    The five boxing wizards jump quickly.
+\end{verbatim}
+
+and in the file you will see something like
+
+\begin{verbatim}
+10-22 22:19 root         INFO     Jackdaws love my big sphinx of quartz.
+10-22 22:19 myapp.area1  DEBUG    Quick zephyrs blow, vexing daft Jim.
+10-22 22:19 myapp.area1  INFO     How quickly daft jumping zebras vex.
+10-22 22:19 myapp.area2  WARNING  Jail zesty vixen who grabbed pay from quack.
+10-22 22:19 myapp.area2  ERROR    The five boxing wizards jump quickly.
+\end{verbatim}
+
+As you can see, the DEBUG message only shows up in the file. The other
+messages are sent to both destinations.
+
+This example uses console and file handlers, but you can use any number and
+combination of handlers you choose.
+
+\subsection{Sending and receiving logging events across a network
+\label{network-logging}}
+
+Let's say you want to send logging events across a network, and handle them
+at the receiving end. A simple way of doing this is attaching a
+\class{SocketHandler} instance to the root logger at the sending end:
+
+\begin{verbatim}
+import logging, logging.handlers
+
+rootLogger = logging.getLogger('')
+rootLogger.setLevel(logging.DEBUG)
+socketHandler = logging.handlers.SocketHandler('localhost',
+                    logging.handlers.DEFAULT_TCP_LOGGING_PORT)
+# don't bother with a formatter, since a socket handler sends the event as
+# an unformatted pickle
+rootLogger.addHandler(socketHandler)
+
+# Now, we can log to the root logger, or any other logger. First the root...
+logging.info('Jackdaws love my big sphinx of quartz.')
+
+# Now, define a couple of other loggers which might represent areas in your
+# application:
+
+logger1 = logging.getLogger('myapp.area1')
+logger2 = logging.getLogger('myapp.area2')
+
+logger1.debug('Quick zephyrs blow, vexing daft Jim.')
+logger1.info('How quickly daft jumping zebras vex.')
+logger2.warning('Jail zesty vixen who grabbed pay from quack.')
+logger2.error('The five boxing wizards jump quickly.')
+\end{verbatim}
+
+At the receiving end, you can set up a receiver using the
+\module{SocketServer} module. Here is a basic working example:
+
+\begin{verbatim}
+import cPickle
+import logging
+import logging.handlers
+import SocketServer
+import struct
+
+
+class LogRecordStreamHandler(SocketServer.StreamRequestHandler):
+    """Handler for a streaming logging request.
+
+    This basically logs the record using whatever logging policy is
+    configured locally.
+    """
+
+    def handle(self):
+        """
+        Handle multiple requests - each expected to be a 4-byte length,
+        followed by the LogRecord in pickle format. Logs the record
+        according to whatever policy is configured locally.
+        """
+        while 1:
+            chunk = self.connection.recv(4)
+            if len(chunk) < 4:
+                break
+            slen = struct.unpack(">L", chunk)[0]
+            chunk = self.connection.recv(slen)
+            while len(chunk) < slen:
+                chunk = chunk + self.connection.recv(slen - len(chunk))
+            obj = self.unPickle(chunk)
+            record = logging.makeLogRecord(obj)
+            self.handleLogRecord(record)
+
+    def unPickle(self, data):
+        return cPickle.loads(data)
+
+    def handleLogRecord(self, record):
+        # if a name is specified, we use the named logger rather than the one
+        # implied by the record.
+        if self.server.logname is not None:
+            name = self.server.logname
+        else:
+            name = record.name
+        logger = logging.getLogger(name)
+        # N.B. EVERY record gets logged. This is because Logger.handle
+        # is normally called AFTER logger-level filtering. If you want
+        # to do filtering, do it at the client end to save wasting
+        # cycles and network bandwidth!
+        logger.handle(record)
+
+class LogRecordSocketReceiver(SocketServer.ThreadingTCPServer):
+    """simple TCP socket-based logging receiver suitable for testing.
+    """
+
+    allow_reuse_address = 1
+
+    def __init__(self, host='localhost',
+                 port=logging.handlers.DEFAULT_TCP_LOGGING_PORT,
+                 handler=LogRecordStreamHandler):
+        SocketServer.ThreadingTCPServer.__init__(self, (host, port), handler)
+        self.abort = 0
+        self.timeout = 1
+        self.logname = None
+
+    def serve_until_stopped(self):
+        import select
+        abort = 0
+        while not abort:
+            rd, wr, ex = select.select([self.socket.fileno()],
+                                       [], [],
+                                       self.timeout)
+            if rd:
+                self.handle_request()
+            abort = self.abort
+
+def main():
+    logging.basicConfig(
+        format="%(relativeCreated)5d %(name)-15s %(levelname)-8s %(message)s")
+    tcpserver = LogRecordSocketReceiver()
+    print "About to start TCP server..."
+    tcpserver.serve_until_stopped()
+
+if __name__ == "__main__":
+    main()
+\end{verbatim}
+
+First run the server, and then the client. On the client side, nothing is
+printed on the console; on the server side, you should see something like:
+
+\begin{verbatim}
+About to start TCP server...
+   59 root            INFO     Jackdaws love my big sphinx of quartz.
+   59 myapp.area1     DEBUG    Quick zephyrs blow, vexing daft Jim.
+   69 myapp.area1     INFO     How quickly daft jumping zebras vex.
+   69 myapp.area2     WARNING  Jail zesty vixen who grabbed pay from quack.
+   69 myapp.area2     ERROR    The five boxing wizards jump quickly.
+\end{verbatim}
+
+\subsection{Handler Objects}
+
+Handlers have the following attributes and methods. Note that
+\class{Handler} is never instantiated directly; this class acts as a
+base for more useful subclasses. However, the \method{__init__()}
+method in subclasses needs to call \method{Handler.__init__()}.
+
+\begin{methoddesc}{__init__}{level=\constant{NOTSET}}
+Initializes the \class{Handler} instance by setting its level, setting
+the list of filters to the empty list and creating a lock (using
+\method{createLock()}) for serializing access to an I/O mechanism.
+\end{methoddesc}
+
+\begin{methoddesc}{createLock}{}
+Initializes a thread lock which can be used to serialize access to
+underlying I/O functionality which may not be threadsafe.
+\end{methoddesc}
+
+\begin{methoddesc}{acquire}{}
+Acquires the thread lock created with \method{createLock()}.
+\end{methoddesc}
+
+\begin{methoddesc}{release}{}
+Releases the thread lock acquired with \method{acquire()}.
+\end{methoddesc}
+
+\begin{methoddesc}{setLevel}{lvl}
+Sets the threshold for this handler to \var{lvl}. Logging messages which are
+less severe than \var{lvl} will be ignored. When a handler is created, the
+level is set to \constant{NOTSET} (which causes all messages to be processed).
+\end{methoddesc}
+
+\begin{methoddesc}{setFormatter}{form}
+Sets the \class{Formatter} for this handler to \var{form}.
+\end{methoddesc}
+
+\begin{methoddesc}{addFilter}{filt}
+Adds the specified filter \var{filt} to this handler.
+\end{methoddesc}
+
+\begin{methoddesc}{removeFilter}{filt}
+Removes the specified filter \var{filt} from this handler.
+\end{methoddesc}
+
+\begin{methoddesc}{filter}{record}
+Applies this handler's filters to the record and returns a true value if
+the record is to be processed.
+\end{methoddesc}
+
+\begin{methoddesc}{flush}{}
+Ensure all logging output has been flushed. This version does
+nothing and is intended to be implemented by subclasses.
+\end{methoddesc}
+
+\begin{methoddesc}{close}{}
+Tidy up any resources used by the handler. This version does
+nothing and is intended to be implemented by subclasses.
+\end{methoddesc}
+
+\begin{methoddesc}{handle}{record}
+Conditionally emits the specified logging record, depending on
+filters which may have been added to the handler. Wraps the actual
+emission of the record with acquisition/release of the I/O thread
+lock.
+\end{methoddesc}
+
+\begin{methoddesc}{handleError}{record}
+This method should be called from handlers when an exception is
+encountered during an \method{emit()} call. By default it does nothing,
+which means that exceptions get silently ignored. This is what is
+mostly wanted for a logging system - most users will not care
+about errors in the logging system, they are more interested in
+application errors. You could, however, replace this with a custom
+handler if you wish. The specified record is the one which was being
+processed when the exception occurred.
+\end{methoddesc}
+
+\begin{methoddesc}{format}{record}
+Do formatting for a record - if a formatter is set, use it.
+Otherwise, use the default formatter for the module.
+\end{methoddesc}
+
+\begin{methoddesc}{emit}{record}
+Do whatever it takes to actually log the specified logging record.
+This version is intended to be implemented by subclasses and so
+raises a \exception{NotImplementedError}.
+\end{methoddesc}
+
+\subsubsection{StreamHandler}
+
+The \class{StreamHandler} class, located in the core \module{logging}
+package, sends logging output to streams such as \var{sys.stdout},
+\var{sys.stderr} or any file-like object (or, more precisely, any
+object which supports \method{write()} and \method{flush()} methods).
+
+\begin{classdesc}{StreamHandler}{\optional{strm}}
+Returns a new instance of the \class{StreamHandler} class. If \var{strm} is
+specified, the instance will use it for logging output; otherwise,
+\var{sys.stderr} will be used.
+\end{classdesc}
+
+\begin{methoddesc}{emit}{record}
+If a formatter is specified, it is used to format the record.
+The record is then written to the stream with a trailing newline.
+If exception information is present, it is formatted using
+\function{traceback.print_exception()} and appended to the stream.
+\end{methoddesc}
+
+\begin{methoddesc}{flush}{}
+Flushes the stream by calling its \method{flush()} method. Note that
+the \method{close()} method is inherited from \class{Handler} and
+so does nothing, so an explicit \method{flush()} call may be needed
+at times.
+\end{methoddesc}
+
+\subsubsection{FileHandler}
+
+The \class{FileHandler} class, located in the core \module{logging}
+package, sends logging output to a disk file.  It inherits the output
+functionality from \class{StreamHandler}.
+
+\begin{classdesc}{FileHandler}{filename\optional{, mode}}
+Returns a new instance of the \class{FileHandler} class. The specified
+file is opened and used as the stream for logging. If \var{mode} is
+not specified, \constant{'a'} is used. By default, the file grows
+indefinitely.
+\end{classdesc}
+
+\begin{methoddesc}{close}{}
+Closes the file.
+\end{methoddesc}
+
+\begin{methoddesc}{emit}{record}
+Outputs the record to the file.
+\end{methoddesc}
+
+\subsubsection{RotatingFileHandler}
+
+The \class{RotatingFileHandler} class, located in the \module{logging.handlers}
+module, supports rotation of disk log files.
+
+\begin{classdesc}{RotatingFileHandler}{filename\optional{, mode\optional{,
+                                       maxBytes\optional{, backupCount}}}}
+Returns a new instance of the \class{RotatingFileHandler} class. The
+specified file is opened and used as the stream for logging. If
+\var{mode} is not specified, \code{'a'} is used. By default, the
+file grows indefinitely.
+
+You can use the \var{maxBytes} and
+\var{backupCount} values to allow the file to \dfn{rollover} at a
+predetermined size. When the size is about to be exceeded, the file is
+closed and a new file is silently opened for output. Rollover occurs
+whenever the current log file is nearly \var{maxBytes} in length; if
+\var{maxBytes} is zero, rollover never occurs.  If \var{backupCount}
+is non-zero, the system will save old log files by appending the
+extensions ".1", ".2" etc., to the filename. For example, with
+a \var{backupCount} of 5 and a base file name of
+\file{app.log}, you would get \file{app.log},
+\file{app.log.1}, \file{app.log.2}, up to \file{app.log.5}. The file being
+written to is always \file{app.log}.  When this file is filled, it is
+closed and renamed to \file{app.log.1}, and if files \file{app.log.1},
+\file{app.log.2}, etc.  exist, then they are renamed to \file{app.log.2},
+\file{app.log.3} etc.  respectively.
+\end{classdesc}
+
+\begin{methoddesc}{doRollover}{}
+Does a rollover, as described above.
+\end{methoddesc}
+
+\begin{methoddesc}{emit}{record}
+Outputs the record to the file, catering for rollover as described previously.
+\end{methoddesc}
+
+\subsubsection{TimedRotatingFileHandler}
+
+The \class{TimedRotatingFileHandler} class, located in the
+\module{logging.handlers} module, supports rotation of disk log files
+at certain timed intervals.
+
+\begin{classdesc}{TimedRotatingFileHandler}{filename
+                                            \optional{,when
+                                            \optional{,interval
+                                            \optional{,backupCount}}}}
+
+Returns a new instance of the \class{TimedRotatingFileHandler} class. The
+specified file is opened and used as the stream for logging. On rotating
+it also sets the filename suffix. Rotating happens based on the product
+of \var{when} and \var{interval}.
+
+You can use the \var{when} to specify the type of \var{interval}. The
+list of possible values is, note that they are not case sensitive:
+
+\begin{tableii}{l|l}{}{Value}{Type of interval}
+  \lineii{S}{Seconds}
+  \lineii{M}{Minutes}
+  \lineii{H}{Hours}
+  \lineii{D}{Days}
+  \lineii{W}{Week day (0=Monday)}
+  \lineii{midnight}{Roll over at midnight}
+\end{tableii}
+
+If \var{backupCount} is non-zero, the system will save old log files by
+appending extensions to the filename. The extensions are date-and-time
+based, using the strftime format \code{\%Y-\%m-\%d_\%H-\%M-\%S} or a leading
+portion thereof, depending on the rollover interval. At most \var{backupCount}
+files will be kept, and if more would be created when rollover occurs, the
+oldest one is deleted.
+\end{classdesc}
+
+\begin{methoddesc}{doRollover}{}
+Does a rollover, as described above.
+\end{methoddesc}
+
+\begin{methoddesc}{emit}{record}
+Outputs the record to the file, catering for rollover as described
+above.
+\end{methoddesc}
+
+\subsubsection{SocketHandler}
+
+The \class{SocketHandler} class, located in the
+\module{logging.handlers} module, sends logging output to a network
+socket. The base class uses a TCP socket.
+
+\begin{classdesc}{SocketHandler}{host, port}
+Returns a new instance of the \class{SocketHandler} class intended to
+communicate with a remote machine whose address is given by \var{host}
+and \var{port}.
+\end{classdesc}
+
+\begin{methoddesc}{close}{}
+Closes the socket.
+\end{methoddesc}
+
+\begin{methoddesc}{handleError}{}
+\end{methoddesc}
+
+\begin{methoddesc}{emit}{}
+Pickles the record's attribute dictionary and writes it to the socket in
+binary format. If there is an error with the socket, silently drops the
+packet. If the connection was previously lost, re-establishes the connection.
+To unpickle the record at the receiving end into a \class{LogRecord}, use the
+\function{makeLogRecord()} function.
+\end{methoddesc}
+
+\begin{methoddesc}{handleError}{}
+Handles an error which has occurred during \method{emit()}. The
+most likely cause is a lost connection. Closes the socket so that
+we can retry on the next event.
+\end{methoddesc}
+
+\begin{methoddesc}{makeSocket}{}
+This is a factory method which allows subclasses to define the precise
+type of socket they want. The default implementation creates a TCP
+socket (\constant{socket.SOCK_STREAM}).
+\end{methoddesc}
+
+\begin{methoddesc}{makePickle}{record}
+Pickles the record's attribute dictionary in binary format with a length
+prefix, and returns it ready for transmission across the socket.
+\end{methoddesc}
+
+\begin{methoddesc}{send}{packet}
+Send a pickled string \var{packet} to the socket. This function allows
+for partial sends which can happen when the network is busy.
+\end{methoddesc}
+
+\subsubsection{DatagramHandler}
+
+The \class{DatagramHandler} class, located in the
+\module{logging.handlers} module, inherits from \class{SocketHandler}
+to support sending logging messages over UDP sockets.
+
+\begin{classdesc}{DatagramHandler}{host, port}
+Returns a new instance of the \class{DatagramHandler} class intended to
+communicate with a remote machine whose address is given by \var{host}
+and \var{port}.
+\end{classdesc}
+
+\begin{methoddesc}{emit}{}
+Pickles the record's attribute dictionary and writes it to the socket in
+binary format. If there is an error with the socket, silently drops the
+packet.
+To unpickle the record at the receiving end into a \class{LogRecord}, use the
+\function{makeLogRecord()} function.
+\end{methoddesc}
+
+\begin{methoddesc}{makeSocket}{}
+The factory method of \class{SocketHandler} is here overridden to create
+a UDP socket (\constant{socket.SOCK_DGRAM}).
+\end{methoddesc}
+
+\begin{methoddesc}{send}{s}
+Send a pickled string to a socket.
+\end{methoddesc}
+
+\subsubsection{SysLogHandler}
+
+The \class{SysLogHandler} class, located in the
+\module{logging.handlers} module, supports sending logging messages to
+a remote or local \UNIX{} syslog.
+
+\begin{classdesc}{SysLogHandler}{\optional{address\optional{, facility}}}
+Returns a new instance of the \class{SysLogHandler} class intended to
+communicate with a remote \UNIX{} machine whose address is given by
+\var{address} in the form of a \code{(\var{host}, \var{port})}
+tuple.  If \var{address} is not specified, \code{('localhost', 514)} is
+used.  The address is used to open a UDP socket.  If \var{facility} is
+not specified, \constant{LOG_USER} is used.
+\end{classdesc}
+
+\begin{methoddesc}{close}{}
+Closes the socket to the remote host.
+\end{methoddesc}
+
+\begin{methoddesc}{emit}{record}
+The record is formatted, and then sent to the syslog server. If
+exception information is present, it is \emph{not} sent to the server.
+\end{methoddesc}
+
+\begin{methoddesc}{encodePriority}{facility, priority}
+Encodes the facility and priority into an integer. You can pass in strings
+or integers - if strings are passed, internal mapping dictionaries are used
+to convert them to integers.
+\end{methoddesc}
+
+\subsubsection{NTEventLogHandler}
+
+The \class{NTEventLogHandler} class, located in the
+\module{logging.handlers} module, supports sending logging messages to
+a local Windows NT, Windows 2000 or Windows XP event log. Before you
+can use it, you need Mark Hammond's Win32 extensions for Python
+installed.
+
+\begin{classdesc}{NTEventLogHandler}{appname\optional{,
+                                     dllname\optional{, logtype}}}
+Returns a new instance of the \class{NTEventLogHandler} class. The
+\var{appname} is used to define the application name as it appears in the
+event log. An appropriate registry entry is created using this name.
+The \var{dllname} should give the fully qualified pathname of a .dll or .exe
+which contains message definitions to hold in the log (if not specified,
+\code{'win32service.pyd'} is used - this is installed with the Win32
+extensions and contains some basic placeholder message definitions.
+Note that use of these placeholders will make your event logs big, as the
+entire message source is held in the log. If you want slimmer logs, you have
+to pass in the name of your own .dll or .exe which contains the message
+definitions you want to use in the event log). The \var{logtype} is one of
+\code{'Application'}, \code{'System'} or \code{'Security'}, and
+defaults to \code{'Application'}.
+\end{classdesc}
+
+\begin{methoddesc}{close}{}
+At this point, you can remove the application name from the registry as a
+source of event log entries. However, if you do this, you will not be able
+to see the events as you intended in the Event Log Viewer - it needs to be
+able to access the registry to get the .dll name. The current version does
+not do this (in fact it doesn't do anything).
+\end{methoddesc}
+
+\begin{methoddesc}{emit}{record}
+Determines the message ID, event category and event type, and then logs the
+message in the NT event log.
+\end{methoddesc}
+
+\begin{methoddesc}{getEventCategory}{record}
+Returns the event category for the record. Override this if you
+want to specify your own categories. This version returns 0.
+\end{methoddesc}
+
+\begin{methoddesc}{getEventType}{record}
+Returns the event type for the record. Override this if you want
+to specify your own types. This version does a mapping using the
+handler's typemap attribute, which is set up in \method{__init__()}
+to a dictionary which contains mappings for \constant{DEBUG},
+\constant{INFO}, \constant{WARNING}, \constant{ERROR} and
+\constant{CRITICAL}. If you are using your own levels, you will either need
+to override this method or place a suitable dictionary in the
+handler's \var{typemap} attribute.
+\end{methoddesc}
+
+\begin{methoddesc}{getMessageID}{record}
+Returns the message ID for the record. If you are using your
+own messages, you could do this by having the \var{msg} passed to the
+logger being an ID rather than a format string. Then, in here,
+you could use a dictionary lookup to get the message ID. This
+version returns 1, which is the base message ID in
+\file{win32service.pyd}.
+\end{methoddesc}
+
+\subsubsection{SMTPHandler}
+
+The \class{SMTPHandler} class, located in the
+\module{logging.handlers} module, supports sending logging messages to
+an email address via SMTP.
+
+\begin{classdesc}{SMTPHandler}{mailhost, fromaddr, toaddrs, subject}
+Returns a new instance of the \class{SMTPHandler} class. The
+instance is initialized with the from and to addresses and subject
+line of the email. The \var{toaddrs} should be a list of strings. To specify a
+non-standard SMTP port, use the (host, port) tuple format for the
+\var{mailhost} argument. If you use a string, the standard SMTP port
+is used.
+\end{classdesc}
+
+\begin{methoddesc}{emit}{record}
+Formats the record and sends it to the specified addressees.
+\end{methoddesc}
+
+\begin{methoddesc}{getSubject}{record}
+If you want to specify a subject line which is record-dependent,
+override this method.
+\end{methoddesc}
+
+\subsubsection{MemoryHandler}
+
+The \class{MemoryHandler} class, located in the
+\module{logging.handlers} module, supports buffering of logging
+records in memory, periodically flushing them to a \dfn{target}
+handler. Flushing occurs whenever the buffer is full, or when an event
+of a certain severity or greater is seen.
+
+\class{MemoryHandler} is a subclass of the more general
+\class{BufferingHandler}, which is an abstract class. This buffers logging
+records in memory. Whenever each record is added to the buffer, a
+check is made by calling \method{shouldFlush()} to see if the buffer
+should be flushed.  If it should, then \method{flush()} is expected to
+do the needful.
+
+\begin{classdesc}{BufferingHandler}{capacity}
+Initializes the handler with a buffer of the specified capacity.
+\end{classdesc}
+
+\begin{methoddesc}{emit}{record}
+Appends the record to the buffer. If \method{shouldFlush()} returns true,
+calls \method{flush()} to process the buffer.
+\end{methoddesc}
+
+\begin{methoddesc}{flush}{}
+You can override this to implement custom flushing behavior. This version
+just zaps the buffer to empty.
+\end{methoddesc}
+
+\begin{methoddesc}{shouldFlush}{record}
+Returns true if the buffer is up to capacity. This method can be
+overridden to implement custom flushing strategies.
+\end{methoddesc}
+
+\begin{classdesc}{MemoryHandler}{capacity\optional{, flushLevel
+\optional{, target}}}
+Returns a new instance of the \class{MemoryHandler} class. The
+instance is initialized with a buffer size of \var{capacity}. If
+\var{flushLevel} is not specified, \constant{ERROR} is used. If no
+\var{target} is specified, the target will need to be set using
+\method{setTarget()} before this handler does anything useful.
+\end{classdesc}
+
+\begin{methoddesc}{close}{}
+Calls \method{flush()}, sets the target to \constant{None} and
+clears the buffer.
+\end{methoddesc}
+
+\begin{methoddesc}{flush}{}
+For a \class{MemoryHandler}, flushing means just sending the buffered
+records to the target, if there is one. Override if you want
+different behavior.
+\end{methoddesc}
+
+\begin{methoddesc}{setTarget}{target}
+Sets the target handler for this handler.
+\end{methoddesc}
+
+\begin{methoddesc}{shouldFlush}{record}
+Checks for buffer full or a record at the \var{flushLevel} or higher.
+\end{methoddesc}
+
+\subsubsection{HTTPHandler}
+
+The \class{HTTPHandler} class, located in the
+\module{logging.handlers} module, supports sending logging messages to
+a Web server, using either \samp{GET} or \samp{POST} semantics.
+
+\begin{classdesc}{HTTPHandler}{host, url\optional{, method}}
+Returns a new instance of the \class{HTTPHandler} class. The
+instance is initialized with a host address, url and HTTP method.
+The \var{host} can be of the form \code{host:port}, should you need to
+use a specific port number. If no \var{method} is specified, \samp{GET}
+is used.
+\end{classdesc}
+
+\begin{methoddesc}{emit}{record}
+Sends the record to the Web server as an URL-encoded dictionary.
+\end{methoddesc}
+
+\subsection{Formatter Objects}
+
+\class{Formatter}s have the following attributes and methods. They are
+responsible for converting a \class{LogRecord} to (usually) a string
+which can be interpreted by either a human or an external system. The
+base
+\class{Formatter} allows a formatting string to be specified. If none is
+supplied, the default value of \code{'\%(message)s'} is used.
+
+A Formatter can be initialized with a format string which makes use of
+knowledge of the \class{LogRecord} attributes - such as the default value
+mentioned above making use of the fact that the user's message and
+arguments are pre-formatted into a \class{LogRecord}'s \var{message}
+attribute.  This format string contains standard python \%-style
+mapping keys. See section \ref{typesseq-strings}, ``String Formatting
+Operations,'' for more information on string formatting.
+
+Currently, the useful mapping keys in a \class{LogRecord} are:
+
+\begin{tableii}{l|l}{code}{Format}{Description}
+\lineii{\%(name)s}     {Name of the logger (logging channel).}
+\lineii{\%(levelno)s}  {Numeric logging level for the message
+                        (\constant{DEBUG}, \constant{INFO},
+                        \constant{WARNING}, \constant{ERROR},
+                        \constant{CRITICAL}).}
+\lineii{\%(levelname)s}{Text logging level for the message
+                        (\code{'DEBUG'}, \code{'INFO'},
+                        \code{'WARNING'}, \code{'ERROR'},
+                        \code{'CRITICAL'}).}
+\lineii{\%(pathname)s} {Full pathname of the source file where the logging
+                        call was issued (if available).}
+\lineii{\%(filename)s} {Filename portion of pathname.}
+\lineii{\%(module)s}   {Module (name portion of filename).}
+\lineii{\%(funcName)s} {Name of function containing the logging call.}
+\lineii{\%(lineno)d}   {Source line number where the logging call was issued
+                        (if available).}
+\lineii{\%(created)f}  {Time when the \class{LogRecord} was created (as
+                        returned by \function{time.time()}).}
+\lineii{\%(relativeCreated)d}  {Time in milliseconds when the LogRecord was
+                        created, relative to the time the logging module was
+                        loaded.}
+\lineii{\%(asctime)s}  {Human-readable time when the \class{LogRecord}
+                        was created.  By default this is of the form
+                        ``2003-07-08 16:49:45,896'' (the numbers after the
+                        comma are millisecond portion of the time).}
+\lineii{\%(msecs)d}    {Millisecond portion of the time when the
+                        \class{LogRecord} was created.}
+\lineii{\%(thread)d}   {Thread ID (if available).}
+\lineii{\%(threadName)s}   {Thread name (if available).}
+\lineii{\%(process)d}  {Process ID (if available).}
+\lineii{\%(message)s}  {The logged message, computed as \code{msg \% args}.}
+\end{tableii}
+
+\versionchanged[\var{funcName} was added]{2.5}
+
+\begin{classdesc}{Formatter}{\optional{fmt\optional{, datefmt}}}
+Returns a new instance of the \class{Formatter} class. The
+instance is initialized with a format string for the message as a whole,
+as well as a format string for the date/time portion of a message. If
+no \var{fmt} is specified, \code{'\%(message)s'} is used. If no \var{datefmt}
+is specified, the ISO8601 date format is used.
+\end{classdesc}
+
+\begin{methoddesc}{format}{record}
+The record's attribute dictionary is used as the operand to a
+string formatting operation. Returns the resulting string.
+Before formatting the dictionary, a couple of preparatory steps
+are carried out. The \var{message} attribute of the record is computed
+using \var{msg} \% \var{args}. If the formatting string contains
+\code{'(asctime)'}, \method{formatTime()} is called to format the
+event time. If there is exception information, it is formatted using
+\method{formatException()} and appended to the message.
+\end{methoddesc}
+
+\begin{methoddesc}{formatTime}{record\optional{, datefmt}}
+This method should be called from \method{format()} by a formatter which
+wants to make use of a formatted time. This method can be overridden
+in formatters to provide for any specific requirement, but the
+basic behavior is as follows: if \var{datefmt} (a string) is specified,
+it is used with \function{time.strftime()} to format the creation time of the
+record. Otherwise, the ISO8601 format is used. The resulting
+string is returned.
+\end{methoddesc}
+
+\begin{methoddesc}{formatException}{exc_info}
+Formats the specified exception information (a standard exception tuple
+as returned by \function{sys.exc_info()}) as a string. This default
+implementation just uses \function{traceback.print_exception()}.
+The resulting string is returned.
+\end{methoddesc}
+
+\subsection{Filter Objects}
+
+\class{Filter}s can be used by \class{Handler}s and \class{Logger}s for
+more sophisticated filtering than is provided by levels. The base filter
+class only allows events which are below a certain point in the logger
+hierarchy. For example, a filter initialized with "A.B" will allow events
+logged by loggers "A.B", "A.B.C", "A.B.C.D", "A.B.D" etc. but not "A.BB",
+"B.A.B" etc. If initialized with the empty string, all events are passed.
+
+\begin{classdesc}{Filter}{\optional{name}}
+Returns an instance of the \class{Filter} class. If \var{name} is specified,
+it names a logger which, together with its children, will have its events
+allowed through the filter. If no name is specified, allows every event.
+\end{classdesc}
+
+\begin{methoddesc}{filter}{record}
+Is the specified record to be logged? Returns zero for no, nonzero for
+yes. If deemed appropriate, the record may be modified in-place by this
+method.
+\end{methoddesc}
+
+\subsection{LogRecord Objects}
+
+\class{LogRecord} instances are created every time something is logged. They
+contain all the information pertinent to the event being logged. The
+main information passed in is in msg and args, which are combined
+using msg \% args to create the message field of the record. The record
+also includes information such as when the record was created, the
+source line where the logging call was made, and any exception
+information to be logged.
+
+\begin{classdesc}{LogRecord}{name, lvl, pathname, lineno, msg, args,
+                             exc_info \optional{, func}}
+Returns an instance of \class{LogRecord} initialized with interesting
+information. The \var{name} is the logger name; \var{lvl} is the
+numeric level; \var{pathname} is the absolute pathname of the source
+file in which the logging call was made; \var{lineno} is the line
+number in that file where the logging call is found; \var{msg} is the
+user-supplied message (a format string); \var{args} is the tuple
+which, together with \var{msg}, makes up the user message; and
+\var{exc_info} is the exception tuple obtained by calling
+\function{sys.exc_info() }(or \constant{None}, if no exception information
+is available). The \var{func} is the name of the function from which the
+logging call was made. If not specified, it defaults to \var{None}.
+\versionchanged[\var{func} was added]{2.5}
+\end{classdesc}
+
+\begin{methoddesc}{getMessage}{}
+Returns the message for this \class{LogRecord} instance after merging any
+user-supplied arguments with the message.
+\end{methoddesc}
+
+\subsection{Thread Safety}
+
+The logging module is intended to be thread-safe without any special work
+needing to be done by its clients. It achieves this though using threading
+locks; there is one lock to serialize access to the module's shared data,
+and each handler also creates a lock to serialize access to its underlying
+I/O.
+
+\subsection{Configuration}
+
+
+\subsubsection{Configuration functions%
+               \label{logging-config-api}}
+
+The following functions configure the logging module. They are located in the
+\module{logging.config} module.  Their use is optional --- you can configure
+the logging module using these functions or by making calls to the
+main API (defined in \module{logging} itself) and defining handlers
+which are declared either in \module{logging} or
+\module{logging.handlers}.
+
+\begin{funcdesc}{fileConfig}{fname\optional{, defaults}}
+Reads the logging configuration from a ConfigParser-format file named
+\var{fname}. This function can be called several times from an application,
+allowing an end user the ability to select from various pre-canned
+configurations (if the developer provides a mechanism to present the
+choices and load the chosen configuration). Defaults to be passed to
+ConfigParser can be specified in the \var{defaults} argument.
+\end{funcdesc}
+
+\begin{funcdesc}{listen}{\optional{port}}
+Starts up a socket server on the specified port, and listens for new
+configurations. If no port is specified, the module's default
+\constant{DEFAULT_LOGGING_CONFIG_PORT} is used. Logging configurations
+will be sent as a file suitable for processing by \function{fileConfig()}.
+Returns a \class{Thread} instance on which you can call \method{start()}
+to start the server, and which you can \method{join()} when appropriate.
+To stop the server, call \function{stopListening()}. To send a configuration
+to the socket, read in the configuration file and send it to the socket
+as a string of bytes preceded by a four-byte length packed in binary using
+struct.\code{pack('>L', n)}.
+\end{funcdesc}
+
+\begin{funcdesc}{stopListening}{}
+Stops the listening server which was created with a call to
+\function{listen()}. This is typically called before calling \method{join()}
+on the return value from \function{listen()}.
+\end{funcdesc}
+
+\subsubsection{Configuration file format%
+               \label{logging-config-fileformat}}
+
+The configuration file format understood by \function{fileConfig()} is
+based on ConfigParser functionality. The file must contain sections
+called \code{[loggers]}, \code{[handlers]} and \code{[formatters]}
+which identify by name the entities of each type which are defined in
+the file. For each such entity, there is a separate section which
+identified how that entity is configured. Thus, for a logger named
+\code{log01} in the \code{[loggers]} section, the relevant
+configuration details are held in a section
+\code{[logger_log01]}. Similarly, a handler called \code{hand01} in
+the \code{[handlers]} section will have its configuration held in a
+section called \code{[handler_hand01]}, while a formatter called
+\code{form01} in the \code{[formatters]} section will have its
+configuration specified in a section called
+\code{[formatter_form01]}. The root logger configuration must be
+specified in a section called \code{[logger_root]}.
+
+Examples of these sections in the file are given below.
+
+\begin{verbatim}
+[loggers]
+keys=root,log02,log03,log04,log05,log06,log07
+
+[handlers]
+keys=hand01,hand02,hand03,hand04,hand05,hand06,hand07,hand08,hand09
+
+[formatters]
+keys=form01,form02,form03,form04,form05,form06,form07,form08,form09
+\end{verbatim}
+
+The root logger must specify a level and a list of handlers. An
+example of a root logger section is given below.
+
+\begin{verbatim}
+[logger_root]
+level=NOTSET
+handlers=hand01
+\end{verbatim}
+
+The \code{level} entry can be one of \code{DEBUG, INFO, WARNING,
+ERROR, CRITICAL} or \code{NOTSET}. For the root logger only,
+\code{NOTSET} means that all messages will be logged. Level values are
+\function{eval()}uated in the context of the \code{logging} package's
+namespace.
+
+The \code{handlers} entry is a comma-separated list of handler names,
+which must appear in the \code{[handlers]} section. These names must
+appear in the \code{[handlers]} section and have corresponding
+sections in the configuration file.
+
+For loggers other than the root logger, some additional information is
+required. This is illustrated by the following example.
+
+\begin{verbatim}
+[logger_parser]
+level=DEBUG
+handlers=hand01
+propagate=1
+qualname=compiler.parser
+\end{verbatim}
+
+The \code{level} and \code{handlers} entries are interpreted as for
+the root logger, except that if a non-root logger's level is specified
+as \code{NOTSET}, the system consults loggers higher up the hierarchy
+to determine the effective level of the logger. The \code{propagate}
+entry is set to 1 to indicate that messages must propagate to handlers
+higher up the logger hierarchy from this logger, or 0 to indicate that
+messages are \strong{not} propagated to handlers up the hierarchy. The
+\code{qualname} entry is the hierarchical channel name of the logger,
+that is to say the name used by the application to get the logger.
+
+Sections which specify handler configuration are exemplified by the
+following.
+
+\begin{verbatim}
+[handler_hand01]
+class=StreamHandler
+level=NOTSET
+formatter=form01
+args=(sys.stdout,)
+\end{verbatim}
+
+The \code{class} entry indicates the handler's class (as determined by
+\function{eval()} in the \code{logging} package's namespace). The
+\code{level} is interpreted as for loggers, and \code{NOTSET} is taken
+to mean "log everything".
+
+The \code{formatter} entry indicates the key name of the formatter for
+this handler. If blank, a default formatter
+(\code{logging._defaultFormatter}) is used. If a name is specified, it
+must appear in the \code{[formatters]} section and have a
+corresponding section in the configuration file.
+
+The \code{args} entry, when \function{eval()}uated in the context of
+the \code{logging} package's namespace, is the list of arguments to
+the constructor for the handler class. Refer to the constructors for
+the relevant handlers, or to the examples below, to see how typical
+entries are constructed.
+
+\begin{verbatim}
+[handler_hand02]
+class=FileHandler
+level=DEBUG
+formatter=form02
+args=('python.log', 'w')
+
+[handler_hand03]
+class=handlers.SocketHandler
+level=INFO
+formatter=form03
+args=('localhost', handlers.DEFAULT_TCP_LOGGING_PORT)
+
+[handler_hand04]
+class=handlers.DatagramHandler
+level=WARN
+formatter=form04
+args=('localhost', handlers.DEFAULT_UDP_LOGGING_PORT)
+
+[handler_hand05]
+class=handlers.SysLogHandler
+level=ERROR
+formatter=form05
+args=(('localhost', handlers.SYSLOG_UDP_PORT), handlers.SysLogHandler.LOG_USER)
+
+[handler_hand06]
+class=handlers.NTEventLogHandler
+level=CRITICAL
+formatter=form06
+args=('Python Application', '', 'Application')
+
+[handler_hand07]
+class=handlers.SMTPHandler
+level=WARN
+formatter=form07
+args=('localhost', 'from at abc', ['user1 at abc', 'user2 at xyz'], 'Logger Subject')
+
+[handler_hand08]
+class=handlers.MemoryHandler
+level=NOTSET
+formatter=form08
+target=
+args=(10, ERROR)
+
+[handler_hand09]
+class=handlers.HTTPHandler
+level=NOTSET
+formatter=form09
+args=('localhost:9022', '/log', 'GET')
+\end{verbatim}
+
+Sections which specify formatter configuration are typified by the following.
+
+\begin{verbatim}
+[formatter_form01]
+format=F1 %(asctime)s %(levelname)s %(message)s
+datefmt=
+class=logging.Formatter
+\end{verbatim}
+
+The \code{format} entry is the overall format string, and the
+\code{datefmt} entry is the \function{strftime()}-compatible date/time format
+string. If empty, the package substitutes ISO8601 format date/times, which
+is almost equivalent to specifying the date format string "%Y-%m-%d %H:%M:%S".
+The ISO8601 format also specifies milliseconds, which are appended to the
+result of using the above format string, with a comma separator. An example
+time in ISO8601 format is \code{2003-01-23 00:29:50,411}.
+
+The \code{class} entry is optional.  It indicates the name of the
+formatter's class (as a dotted module and class name.)  This option is
+useful for instantiating a \class{Formatter} subclass.  Subclasses of
+\class{Formatter} can present exception tracebacks in an expanded or
+condensed format.

Added: vendor/Python/current/Doc/lib/libmailbox.tex
===================================================================
--- vendor/Python/current/Doc/lib/libmailbox.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libmailbox.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1444 @@
+\section{\module{mailbox} ---
+          Manipulate mailboxes in various formats}
+
+\declaremodule{}{mailbox}
+\moduleauthor{Gregory K.~Johnson}{gkj at gregorykjohnson.com}
+\sectionauthor{Gregory K.~Johnson}{gkj at gregorykjohnson.com}
+\modulesynopsis{Manipulate mailboxes in various formats}
+
+
+This module defines two classes, \class{Mailbox} and \class{Message}, for
+accessing and manipulating on-disk mailboxes and the messages they contain.
+\class{Mailbox} offers a dictionary-like mapping from keys to messages.
+\class{Message} extends the \module{email.Message} module's \class{Message}
+class with format-specific state and behavior. Supported mailbox formats are
+Maildir, mbox, MH, Babyl, and MMDF.
+
+\begin{seealso}
+    \seemodule{email}{Represent and manipulate messages.}
+\end{seealso}
+
+\subsection{\class{Mailbox} objects}
+\label{mailbox-objects}
+
+\begin{classdesc*}{Mailbox}
+A mailbox, which may be inspected and modified.
+\end{classdesc*}
+
+The \class{Mailbox} class defines an interface and
+is not intended to be instantiated.  Instead, format-specific
+subclasses should inherit from \class{Mailbox} and your code
+should instantiate a particular subclass.
+
+The \class{Mailbox} interface is dictionary-like, with small keys
+corresponding to messages. Keys are issued by the \class{Mailbox}
+instance with which they will be used and are only meaningful to that
+\class{Mailbox} instance. A key continues to identify a message even
+if the corresponding message is modified, such as by replacing it with
+another message.
+
+Messages may be added to a \class{Mailbox} instance using the set-like
+method \method{add()} and removed using a \code{del} statement or the
+set-like methods \method{remove()} and \method{discard()}.
+
+\class{Mailbox} interface semantics differ from dictionary semantics in some
+noteworthy ways. Each time a message is requested, a new
+representation (typically a \class{Message} instance) is generated
+based upon the current state of the mailbox. Similarly, when a message
+is added to a \class{Mailbox} instance, the provided message
+representation's contents are copied. In neither case is a reference
+to the message representation kept by the \class{Mailbox} instance.
+
+The default \class{Mailbox} iterator iterates over message representations, not
+keys as the default dictionary iterator does. Moreover, modification of a
+mailbox during iteration is safe and well-defined. Messages added to the
+mailbox after an iterator is created will not be seen by the iterator. Messages
+removed from the mailbox before the iterator yields them will be silently
+skipped, though using a key from an iterator may result in a
+\exception{KeyError} exception if the corresponding message is subsequently
+removed.
+
+\begin{notice}[warning]
+Be very cautious when modifying mailboxes that might be
+simultaneously changed by some other process.  The safest mailbox
+format to use for such tasks is Maildir; try to avoid using
+single-file formats such as mbox for concurrent writing.  If you're
+modifying a mailbox, you
+\emph{must} lock it by calling the \method{lock()} and
+\method{unlock()} methods \emph{before} reading any messages in the file
+or making any changes by adding or deleting a message.  Failing to
+lock the mailbox runs the risk of losing messages or corrupting the entire
+mailbox.
+\end{notice}
+
+\class{Mailbox} instances have the following methods:
+
+\begin{methoddesc}{add}{message}
+Add \var{message} to the mailbox and return the key that has been assigned to
+it.
+
+Parameter \var{message} may be a \class{Message} instance, an
+\class{email.Message.Message} instance, a string, or a file-like object (which
+should be open in text mode). If \var{message} is an instance of the
+appropriate format-specific \class{Message} subclass (e.g., if it's an
+\class{mboxMessage} instance and this is an \class{mbox} instance), its
+format-specific information is used. Otherwise, reasonable defaults for
+format-specific information are used.
+\end{methoddesc}
+
+\begin{methoddesc}{remove}{key}
+\methodline{__delitem__}{key}
+\methodline{discard}{key}
+Delete the message corresponding to \var{key} from the mailbox.
+
+If no such message exists, a \exception{KeyError} exception is raised if the
+method was called as \method{remove()} or \method{__delitem__()} but no
+exception is raised if the method was called as \method{discard()}. The
+behavior of \method{discard()} may be preferred if the underlying mailbox
+format supports concurrent modification by other processes.
+\end{methoddesc}
+
+\begin{methoddesc}{__setitem__}{key, message}
+Replace the message corresponding to \var{key} with \var{message}. Raise a
+\exception{KeyError} exception if no message already corresponds to \var{key}.
+
+As with \method{add()}, parameter \var{message} may be a \class{Message}
+instance, an \class{email.Message.Message} instance, a string, or a file-like
+object (which should be open in text mode). If \var{message} is an instance of
+the appropriate format-specific \class{Message} subclass (e.g., if it's an
+\class{mboxMessage} instance and this is an \class{mbox} instance), its
+format-specific information is used. Otherwise, the format-specific information
+of the message that currently corresponds to \var{key} is left unchanged. 
+\end{methoddesc}
+
+\begin{methoddesc}{iterkeys}{}
+\methodline{keys}{}
+Return an iterator over all keys if called as \method{iterkeys()} or return a
+list of keys if called as \method{keys()}.
+\end{methoddesc}
+
+\begin{methoddesc}{itervalues}{}
+\methodline{__iter__}{}
+\methodline{values}{}
+Return an iterator over representations of all messages if called as
+\method{itervalues()} or \method{__iter__()} or return a list of such
+representations if called as \method{values()}. The messages are represented as
+instances of the appropriate format-specific \class{Message} subclass unless a
+custom message factory was specified when the \class{Mailbox} instance was
+initialized. \note{The behavior of \method{__iter__()} is unlike that of
+dictionaries, which iterate over keys.}
+\end{methoddesc}
+
+\begin{methoddesc}{iteritems}{}
+\methodline{items}{}
+Return an iterator over (\var{key}, \var{message}) pairs, where \var{key} is a
+key and \var{message} is a message representation, if called as
+\method{iteritems()} or return a list of such pairs if called as
+\method{items()}. The messages are represented as instances of the appropriate
+format-specific \class{Message} subclass unless a custom message factory was
+specified when the \class{Mailbox} instance was initialized.
+\end{methoddesc}
+
+\begin{methoddesc}{get}{key\optional{, default=None}}
+\methodline{__getitem__}{key}
+Return a representation of the message corresponding to \var{key}. If no such
+message exists, \var{default} is returned if the method was called as
+\method{get()} and a \exception{KeyError} exception is raised if the method was
+called as \method{__getitem__()}. The message is represented as an instance of
+the appropriate format-specific \class{Message} subclass unless a custom
+message factory was specified when the \class{Mailbox} instance was
+initialized.
+\end{methoddesc}
+
+\begin{methoddesc}{get_message}{key}
+Return a representation of the message corresponding to \var{key} as an
+instance of the appropriate format-specific \class{Message} subclass, or raise
+a \exception{KeyError} exception if no such message exists.
+\end{methoddesc}
+
+\begin{methoddesc}{get_string}{key}
+Return a string representation of the message corresponding to \var{key}, or
+raise a \exception{KeyError} exception if no such message exists.
+\end{methoddesc}
+
+\begin{methoddesc}{get_file}{key}
+Return a file-like representation of the message corresponding to \var{key},
+or raise a \exception{KeyError} exception if no such message exists. The
+file-like object behaves as if open in binary mode. This file should be closed
+once it is no longer needed.
+
+\note{Unlike other representations of messages, file-like representations are
+not necessarily independent of the \class{Mailbox} instance that created them
+or of the underlying mailbox. More specific documentation is provided by each
+subclass.}
+\end{methoddesc}
+
+\begin{methoddesc}{has_key}{key}
+\methodline{__contains__}{key}
+Return \code{True} if \var{key} corresponds to a message, \code{False}
+otherwise.
+\end{methoddesc}
+
+\begin{methoddesc}{__len__}{}
+Return a count of messages in the mailbox.
+\end{methoddesc}
+
+\begin{methoddesc}{clear}{}
+Delete all messages from the mailbox.
+\end{methoddesc}
+
+\begin{methoddesc}{pop}{key\optional{, default}}
+Return a representation of the message corresponding to \var{key} and delete
+the message. If no such message exists, return \var{default} if it was supplied
+or else raise a \exception{KeyError} exception. The message is represented as
+an instance of the appropriate format-specific \class{Message} subclass unless
+a custom message factory was specified when the \class{Mailbox} instance was
+initialized.
+\end{methoddesc}
+
+\begin{methoddesc}{popitem}{}
+Return an arbitrary (\var{key}, \var{message}) pair, where \var{key} is a key
+and \var{message} is a message representation, and delete the corresponding
+message. If the mailbox is empty, raise a \exception{KeyError} exception. The
+message is represented as an instance of the appropriate format-specific
+\class{Message} subclass unless a custom message factory was specified when the
+\class{Mailbox} instance was initialized.
+\end{methoddesc}
+
+\begin{methoddesc}{update}{arg}
+Parameter \var{arg} should be a \var{key}-to-\var{message} mapping or an
+iterable of (\var{key}, \var{message}) pairs. Updates the mailbox so that, for
+each given \var{key} and \var{message}, the message corresponding to \var{key}
+is set to \var{message} as if by using \method{__setitem__()}. As with
+\method{__setitem__()}, each \var{key} must already correspond to a message in
+the mailbox or else a \exception{KeyError} exception will be raised, so in
+general it is incorrect for \var{arg} to be a \class{Mailbox} instance.
+\note{Unlike with dictionaries, keyword arguments are not supported.}
+\end{methoddesc}
+
+\begin{methoddesc}{flush}{}
+Write any pending changes to the filesystem. For some \class{Mailbox}
+subclasses, changes are always written immediately and \method{flush()} does
+nothing, but you should still make a habit of calling this method.
+\end{methoddesc}
+
+\begin{methoddesc}{lock}{}
+Acquire an exclusive advisory lock on the mailbox so that other processes know
+not to modify it. An \exception{ExternalClashError} is raised if the lock is
+not available. The particular locking mechanisms used depend upon the mailbox
+format.  You should \emph{always} lock the mailbox before making any 
+modifications to its contents.
+\end{methoddesc}
+
+\begin{methoddesc}{unlock}{}
+Release the lock on the mailbox, if any.
+\end{methoddesc}
+
+\begin{methoddesc}{close}{}
+Flush the mailbox, unlock it if necessary, and close any open files. For some
+\class{Mailbox} subclasses, this method does nothing.
+\end{methoddesc}
+
+
+\subsubsection{\class{Maildir}}
+\label{mailbox-maildir}
+
+\begin{classdesc}{Maildir}{dirname\optional{, factory=rfc822.Message\optional{,
+create=True}}}
+A subclass of \class{Mailbox} for mailboxes in Maildir format. Parameter
+\var{factory} is a callable object that accepts a file-like message
+representation (which behaves as if opened in binary mode) and returns a custom
+representation. If \var{factory} is \code{None}, \class{MaildirMessage} is used
+as the default message representation. If \var{create} is \code{True}, the
+mailbox is created if it does not exist.
+
+It is for historical reasons that \var{factory} defaults to
+\class{rfc822.Message} and that \var{dirname} is named as such rather than
+\var{path}. For a \class{Maildir} instance that behaves like instances of other
+\class{Mailbox} subclasses, set \var{factory} to \code{None}.
+\end{classdesc}
+
+Maildir is a directory-based mailbox format invented for the qmail mail
+transfer agent and now widely supported by other programs. Messages in a
+Maildir mailbox are stored in separate files within a common directory
+structure. This design allows Maildir mailboxes to be accessed and modified by
+multiple unrelated programs without data corruption, so file locking is
+unnecessary.
+
+Maildir mailboxes contain three subdirectories, namely: \file{tmp}, \file{new},
+and \file{cur}. Messages are created momentarily in the \file{tmp} subdirectory
+and then moved to the \file{new} subdirectory to finalize delivery. A mail user
+agent may subsequently move the message to the \file{cur} subdirectory and
+store information about the state of the message in a special "info" section
+appended to its file name.
+
+Folders of the style introduced by the Courier mail transfer agent are also
+supported. Any subdirectory of the main mailbox is considered a folder if
+\character{.} is the first character in its name. Folder names are represented
+by \class{Maildir} without the leading \character{.}. Each folder is itself a
+Maildir mailbox but should not contain other folders. Instead, a logical
+nesting is indicated using \character{.} to delimit levels, e.g.,
+"Archived.2005.07".
+
+\begin{notice}
+The Maildir specification requires the use of a colon (\character{:}) in
+certain message file names. However, some operating systems do not permit this
+character in file names, If you wish to use a Maildir-like format on such an
+operating system, you should specify another character to use instead. The
+exclamation point (\character{!}) is a popular choice. For example:
+\begin{verbatim}
+import mailbox
+mailbox.Maildir.colon = '!'
+\end{verbatim}
+The \member{colon} attribute may also be set on a per-instance basis.
+\end{notice}
+
+\class{Maildir} instances have all of the methods of \class{Mailbox} in
+addition to the following:
+
+\begin{methoddesc}{list_folders}{}
+Return a list of the names of all folders.
+\end{methoddesc}
+
+\begin{methoddesc}{get_folder}{folder}
+Return a \class{Maildir} instance representing the folder whose name is
+\var{folder}. A \exception{NoSuchMailboxError} exception is raised if the
+folder does not exist.
+\end{methoddesc}
+
+\begin{methoddesc}{add_folder}{folder}
+Create a folder whose name is \var{folder} and return a \class{Maildir}
+instance representing it.
+\end{methoddesc}
+
+\begin{methoddesc}{remove_folder}{folder}
+Delete the folder whose name is \var{folder}. If the folder contains any
+messages, a \exception{NotEmptyError} exception will be raised and the folder
+will not be deleted.
+\end{methoddesc}
+
+\begin{methoddesc}{clean}{}
+Delete temporary files from the mailbox that have not been accessed in the
+last 36 hours. The Maildir specification says that mail-reading programs
+should do this occasionally.
+\end{methoddesc}
+
+Some \class{Mailbox} methods implemented by \class{Maildir} deserve special
+remarks:
+
+\begin{methoddesc}{add}{message}
+\methodline[Maildir]{__setitem__}{key, message}
+\methodline[Maildir]{update}{arg}
+\warning{These methods generate unique file names based upon the current
+process ID. When using multiple threads, undetected name clashes may occur and
+cause corruption of the mailbox unless threads are coordinated to avoid using
+these methods to manipulate the same mailbox simultaneously.}
+\end{methoddesc}
+
+\begin{methoddesc}{flush}{}
+All changes to Maildir mailboxes are immediately applied, so this method does
+nothing.
+\end{methoddesc}
+
+\begin{methoddesc}{lock}{}
+\methodline{unlock}{}
+Maildir mailboxes do not support (or require) locking, so these methods do
+nothing. 
+\end{methoddesc}
+
+\begin{methoddesc}{close}{}
+\class{Maildir} instances do not keep any open files and the underlying
+mailboxes do not support locking, so this method does nothing.
+\end{methoddesc}
+
+\begin{methoddesc}{get_file}{key}
+Depending upon the host platform, it may not be possible to modify or remove
+the underlying message while the returned file remains open.
+\end{methoddesc}
+
+\begin{seealso}
+    \seelink{http://www.qmail.org/man/man5/maildir.html}{maildir man page from
+    qmail}{The original specification of the format.}
+    \seelink{http://cr.yp.to/proto/maildir.html}{Using maildir format}{Notes
+    on Maildir by its inventor. Includes an updated name-creation scheme and
+    details on "info" semantics.}
+    \seelink{http://www.courier-mta.org/?maildir.html}{maildir man page from
+    Courier}{Another specification of the format. Describes a common extension
+    for supporting folders.}
+\end{seealso}
+
+\subsubsection{\class{mbox}}
+\label{mailbox-mbox}
+
+\begin{classdesc}{mbox}{path\optional{, factory=None\optional{, create=True}}}
+A subclass of \class{Mailbox} for mailboxes in mbox format. Parameter
+\var{factory} is a callable object that accepts a file-like message
+representation (which behaves as if opened in binary mode) and returns a custom
+representation. If \var{factory} is \code{None}, \class{mboxMessage} is used as
+the default message representation. If \var{create} is \code{True}, the mailbox
+is created if it does not exist.
+\end{classdesc}
+
+The mbox format is the classic format for storing mail on \UNIX{} systems. All
+messages in an mbox mailbox are stored in a single file with the beginning of
+each message indicated by a line whose first five characters are "From~".
+
+Several variations of the mbox format exist to address perceived shortcomings
+in the original. In the interest of compatibility, \class{mbox} implements the
+original format, which is sometimes referred to as \dfn{mboxo}. This means that
+the \mailheader{Content-Length} header, if present, is ignored and that any
+occurrences of "From~" at the beginning of a line in a message body are
+transformed to ">From~" when storing the message, although occurences of
+">From~" are not transformed to "From~" when reading the message.
+
+Some \class{Mailbox} methods implemented by \class{mbox} deserve special
+remarks:
+
+\begin{methoddesc}{get_file}{key}
+Using the file after calling \method{flush()} or \method{close()} on the
+\class{mbox} instance may yield unpredictable results or raise an exception.
+\end{methoddesc}
+
+\begin{methoddesc}{lock}{}
+\methodline{unlock}{}
+Three locking mechanisms are used---dot locking and, if available, the
+\cfunction{flock()} and \cfunction{lockf()} system calls.
+\end{methoddesc}
+
+\begin{seealso}
+    \seelink{http://www.qmail.org/man/man5/mbox.html}{mbox man page from
+    qmail}{A specification of the format and its variations.}
+    \seelink{http://www.tin.org/bin/man.cgi?section=5\&topic=mbox}{mbox man
+    page from tin}{Another specification of the format, with details on
+    locking.}
+    \seelink{http://home.netscape.com/eng/mozilla/2.0/relnotes/demo/content-length.html}
+    {Configuring Netscape Mail on \UNIX{}: Why The Content-Length Format is
+    Bad}{An argument for using the original mbox format rather than a
+    variation.}
+    \seelink{http://homepages.tesco.net./\tilde{}J.deBoynePollard/FGA/mail-mbox-formats.html}
+    {"mbox" is a family of several mutually incompatible mailbox formats}{A
+    history of mbox variations.}
+\end{seealso}
+
+\subsubsection{\class{MH}}
+\label{mailbox-mh}
+
+\begin{classdesc}{MH}{path\optional{, factory=None\optional{, create=True}}}
+A subclass of \class{Mailbox} for mailboxes in MH format. Parameter
+\var{factory} is a callable object that accepts a file-like message
+representation (which behaves as if opened in binary mode) and returns a custom
+representation. If \var{factory} is \code{None}, \class{MHMessage} is used as
+the default message representation. If \var{create} is \code{True}, the mailbox
+is created if it does not exist.
+\end{classdesc}
+
+MH is a directory-based mailbox format invented for the MH Message Handling
+System, a mail user agent. Each message in an MH mailbox resides in its own
+file. An MH mailbox may contain other MH mailboxes (called \dfn{folders}) in
+addition to messages. Folders may be nested indefinitely. MH mailboxes also
+support \dfn{sequences}, which are named lists used to logically group messages
+without moving them to sub-folders. Sequences are defined in a file called
+\file{.mh_sequences} in each folder.
+
+The \class{MH} class manipulates MH mailboxes, but it does not attempt to
+emulate all of \program{mh}'s behaviors. In particular, it does not modify and
+is not affected by the \file{context} or \file{.mh_profile} files that are used
+by \program{mh} to store its state and configuration.
+
+\class{MH} instances have all of the methods of \class{Mailbox} in addition to
+the following:
+
+\begin{methoddesc}{list_folders}{}
+Return a list of the names of all folders.
+\end{methoddesc}
+
+\begin{methoddesc}{get_folder}{folder}
+Return an \class{MH} instance representing the folder whose name is
+\var{folder}. A \exception{NoSuchMailboxError} exception is raised if the
+folder does not exist.
+\end{methoddesc}
+
+\begin{methoddesc}{add_folder}{folder}
+Create a folder whose name is \var{folder} and return an \class{MH} instance
+representing it.
+\end{methoddesc}
+
+\begin{methoddesc}{remove_folder}{folder}
+Delete the folder whose name is \var{folder}. If the folder contains any
+messages, a \exception{NotEmptyError} exception will be raised and the folder
+will not be deleted.
+\end{methoddesc}
+
+\begin{methoddesc}{get_sequences}{}
+Return a dictionary of sequence names mapped to key lists. If there are no
+sequences, the empty dictionary is returned.
+\end{methoddesc}
+
+\begin{methoddesc}{set_sequences}{sequences}
+Re-define the sequences that exist in the mailbox based upon \var{sequences}, a
+dictionary of names mapped to key lists, like returned by
+\method{get_sequences()}.
+\end{methoddesc}
+
+\begin{methoddesc}{pack}{}
+Rename messages in the mailbox as necessary to eliminate gaps in numbering.
+Entries in the sequences list are updated correspondingly. \note{Already-issued
+keys are invalidated by this operation and should not be subsequently used.}
+\end{methoddesc}
+
+Some \class{Mailbox} methods implemented by \class{MH} deserve special remarks:
+
+\begin{methoddesc}{remove}{key}
+\methodline{__delitem__}{key}
+\methodline{discard}{key}
+These methods immediately delete the message. The MH convention of marking a
+message for deletion by prepending a comma to its name is not used.
+\end{methoddesc}
+
+\begin{methoddesc}{lock}{}
+\methodline{unlock}{}
+Three locking mechanisms are used---dot locking and, if available, the
+\cfunction{flock()} and \cfunction{lockf()} system calls. For MH mailboxes,
+locking the mailbox means locking the \file{.mh_sequences} file and, only for
+the duration of any operations that affect them, locking individual message
+files.
+\end{methoddesc}
+
+\begin{methoddesc}{get_file}{key}
+Depending upon the host platform, it may not be possible to remove the
+underlying message while the returned file remains open.
+\end{methoddesc}
+
+\begin{methoddesc}{flush}{}
+All changes to MH mailboxes are immediately applied, so this method does
+nothing.
+\end{methoddesc}
+
+\begin{methoddesc}{close}{}
+\class{MH} instances do not keep any open files, so this method is equivelant
+to \method{unlock()}.
+\end{methoddesc}
+
+\begin{seealso}
+\seelink{http://www.nongnu.org/nmh/}{nmh - Message Handling System}{Home page
+of \program{nmh}, an updated version of the original \program{mh}.}
+\seelink{http://www.ics.uci.edu/\tilde{}mh/book/}{MH \& nmh: Email for Users \&
+Programmers}{A GPL-licensed book on \program{mh} and \program{nmh}, with some
+information on the mailbox format.}
+\end{seealso}
+
+\subsubsection{\class{Babyl}}
+\label{mailbox-babyl}
+
+\begin{classdesc}{Babyl}{path\optional{, factory=None\optional{, create=True}}}
+A subclass of \class{Mailbox} for mailboxes in Babyl format. Parameter
+\var{factory} is a callable object that accepts a file-like message
+representation (which behaves as if opened in binary mode) and returns a custom
+representation. If \var{factory} is \code{None}, \class{BabylMessage} is used
+as the default message representation. If \var{create} is \code{True}, the
+mailbox is created if it does not exist.
+\end{classdesc}
+
+Babyl is a single-file mailbox format used by the Rmail mail user agent
+included with Emacs. The beginning of a message is indicated by a line
+containing the two characters Control-Underscore
+(\character{\textbackslash037}) and Control-L (\character{\textbackslash014}).
+The end of a message is indicated by the start of the next message or, in the
+case of the last message, a line containing a Control-Underscore
+(\character{\textbackslash037}) character.
+
+Messages in a Babyl mailbox have two sets of headers, original headers and
+so-called visible headers. Visible headers are typically a subset of the
+original headers that have been reformatted or abridged to be more attractive.
+Each message in a Babyl mailbox also has an accompanying list of \dfn{labels},
+or short strings that record extra information about the message, and a list of
+all user-defined labels found in the mailbox is kept in the Babyl options
+section.
+
+\class{Babyl} instances have all of the methods of \class{Mailbox} in addition
+to the following:
+
+\begin{methoddesc}{get_labels}{}
+Return a list of the names of all user-defined labels used in the mailbox.
+\note{The actual messages are inspected to determine which labels exist in the
+mailbox rather than consulting the list of labels in the Babyl options section,
+but the Babyl section is updated whenever the mailbox is modified.}
+\end{methoddesc}
+
+Some \class{Mailbox} methods implemented by \class{Babyl} deserve special
+remarks:
+
+\begin{methoddesc}{get_file}{key}
+In Babyl mailboxes, the headers of a message are not stored contiguously with
+the body of the message. To generate a file-like representation, the headers
+and body are copied together into a \class{StringIO} instance (from the
+\module{StringIO} module), which has an API identical to that of a file. As a
+result, the file-like object is truly independent of the underlying mailbox but
+does not save memory compared to a string representation.
+\end{methoddesc}
+
+\begin{methoddesc}{lock}{}
+\methodline{unlock}{}
+Three locking mechanisms are used---dot locking and, if available, the
+\cfunction{flock()} and \cfunction{lockf()} system calls.
+\end{methoddesc}
+
+\begin{seealso}
+\seelink{http://quimby.gnus.org/notes/BABYL}{Format of Version 5 Babyl Files}{A
+specification of the Babyl format.}
+\seelink{http://www.gnu.org/software/emacs/manual/html_node/Rmail.html}{Reading
+Mail with Rmail}{The Rmail manual, with some information on Babyl semantics.}
+\end{seealso}
+
+\subsubsection{\class{MMDF}}
+\label{mailbox-mmdf}
+
+\begin{classdesc}{MMDF}{path\optional{, factory=None\optional{, create=True}}}
+A subclass of \class{Mailbox} for mailboxes in MMDF format. Parameter
+\var{factory} is a callable object that accepts a file-like message
+representation (which behaves as if opened in binary mode) and returns a custom
+representation. If \var{factory} is \code{None}, \class{MMDFMessage} is used as
+the default message representation. If \var{create} is \code{True}, the mailbox
+is created if it does not exist.
+\end{classdesc}
+
+MMDF is a single-file mailbox format invented for the Multichannel Memorandum
+Distribution Facility, a mail transfer agent. Each message is in the same form
+as an mbox message but is bracketed before and after by lines containing four
+Control-A (\character{\textbackslash001}) characters. As with the mbox format,
+the beginning of each message is indicated by a line whose first five
+characters are "From~", but additional occurrences of "From~" are not
+transformed to ">From~" when storing messages because the extra message
+separator lines prevent mistaking such occurrences for the starts of subsequent
+messages.
+
+Some \class{Mailbox} methods implemented by \class{MMDF} deserve special
+remarks:
+
+\begin{methoddesc}{get_file}{key}
+Using the file after calling \method{flush()} or \method{close()} on the
+\class{MMDF} instance may yield unpredictable results or raise an exception.
+\end{methoddesc}
+
+\begin{methoddesc}{lock}{}
+\methodline{unlock}{}
+Three locking mechanisms are used---dot locking and, if available, the
+\cfunction{flock()} and \cfunction{lockf()} system calls.
+\end{methoddesc}
+
+\begin{seealso}
+\seelink{http://www.tin.org/bin/man.cgi?section=5\&topic=mmdf}{mmdf man page
+from tin}{A specification of MMDF format from the documentation of tin, a
+newsreader.}
+\seelink{http://en.wikipedia.org/wiki/MMDF}{MMDF}{A Wikipedia article
+describing the Multichannel Memorandum Distribution Facility.}
+\end{seealso}
+
+\subsection{\class{Message} objects}
+\label{mailbox-message-objects}
+
+\begin{classdesc}{Message}{\optional{message}}
+A subclass of the \module{email.Message} module's \class{Message}. Subclasses
+of \class{mailbox.Message} add mailbox-format-specific state and behavior.
+
+If \var{message} is omitted, the new instance is created in a default, empty
+state. If \var{message} is an \class{email.Message.Message} instance, its
+contents are copied; furthermore, any format-specific information is converted
+insofar as possible if \var{message} is a \class{Message} instance. If
+\var{message} is a string or a file, it should contain an \rfc{2822}-compliant
+message, which is read and parsed.
+\end{classdesc}
+
+The format-specific state and behaviors offered by subclasses vary, but in
+general it is only the properties that are not specific to a particular mailbox
+that are supported (although presumably the properties are specific to a
+particular mailbox format). For example, file offsets for single-file mailbox
+formats and file names for directory-based mailbox formats are not retained,
+because they are only applicable to the original mailbox. But state such as
+whether a message has been read by the user or marked as important is retained,
+because it applies to the message itself.
+
+There is no requirement that \class{Message} instances be used to represent
+messages retrieved using \class{Mailbox} instances. In some situations, the
+time and memory required to generate \class{Message} representations might not
+not acceptable. For such situations, \class{Mailbox} instances also offer
+string and file-like representations, and a custom message factory may be
+specified when a \class{Mailbox} instance is initialized. 
+
+\subsubsection{\class{MaildirMessage}}
+\label{mailbox-maildirmessage}
+
+\begin{classdesc}{MaildirMessage}{\optional{message}}
+A message with Maildir-specific behaviors. Parameter \var{message}
+has the same meaning as with the \class{Message} constructor.
+\end{classdesc}
+
+Typically, a mail user agent application moves all of the messages in the
+\file{new} subdirectory to the \file{cur} subdirectory after the first time the
+user opens and closes the mailbox, recording that the messages are old whether
+or not they've actually been read. Each message in \file{cur} has an "info"
+section added to its file name to store information about its state. (Some mail
+readers may also add an "info" section to messages in \file{new}.) The "info"
+section may take one of two forms: it may contain "2," followed by a list of
+standardized flags (e.g., "2,FR") or it may contain "1," followed by so-called
+experimental information. Standard flags for Maildir messages are as follows:
+
+\begin{tableiii}{l|l|l}{textrm}{Flag}{Meaning}{Explanation}
+\lineiii{D}{Draft}{Under composition}
+\lineiii{F}{Flagged}{Marked as important}
+\lineiii{P}{Passed}{Forwarded, resent, or bounced}
+\lineiii{R}{Replied}{Replied to}
+\lineiii{S}{Seen}{Read}
+\lineiii{T}{Trashed}{Marked for subsequent deletion}
+\end{tableiii}
+
+\class{MaildirMessage} instances offer the following methods:
+
+\begin{methoddesc}{get_subdir}{}
+Return either "new" (if the message should be stored in the \file{new}
+subdirectory) or "cur" (if the message should be stored in the \file{cur}
+subdirectory). \note{A message is typically moved from \file{new} to \file{cur}
+after its mailbox has been accessed, whether or not the message is has been
+read. A message \code{msg} has been read if \code{"S" not in msg.get_flags()}
+is \code{True}.}
+\end{methoddesc}
+
+\begin{methoddesc}{set_subdir}{subdir}
+Set the subdirectory the message should be stored in. Parameter \var{subdir}
+must be either "new" or "cur".
+\end{methoddesc}
+
+\begin{methoddesc}{get_flags}{}
+Return a string specifying the flags that are currently set. If the message
+complies with the standard Maildir format, the result is the concatenation in
+alphabetical order of zero or one occurrence of each of \character{D},
+\character{F}, \character{P}, \character{R}, \character{S}, and \character{T}.
+The empty string is returned if no flags are set or if "info" contains
+experimental semantics.
+\end{methoddesc}
+
+\begin{methoddesc}{set_flags}{flags}
+Set the flags specified by \var{flags} and unset all others.
+\end{methoddesc}
+
+\begin{methoddesc}{add_flag}{flag}
+Set the flag(s) specified by \var{flag} without changing other flags. To add
+more than one flag at a time, \var{flag} may be a string of more than one
+character. The current "info" is overwritten whether or not it contains
+experimental information rather than
+flags.
+\end{methoddesc}
+
+\begin{methoddesc}{remove_flag}{flag}
+Unset the flag(s) specified by \var{flag} without changing other flags. To
+remove more than one flag at a time, \var{flag} maybe a string of more than one
+character. If "info" contains experimental information rather than flags, the
+current "info" is not modified.
+\end{methoddesc}
+
+\begin{methoddesc}{get_date}{}
+Return the delivery date of the message as a floating-point number representing
+seconds since the epoch.
+\end{methoddesc}
+
+\begin{methoddesc}{set_date}{date}
+Set the delivery date of the message to \var{date}, a floating-point number
+representing seconds since the epoch.
+\end{methoddesc}
+
+\begin{methoddesc}{get_info}{}
+Return a string containing the "info" for a message. This is useful for
+accessing and modifying "info" that is experimental (i.e., not a list of
+flags).
+\end{methoddesc}
+
+\begin{methoddesc}{set_info}{info}
+Set "info" to \var{info}, which should be a string.
+\end{methoddesc}
+
+When a \class{MaildirMessage} instance is created based upon an
+\class{mboxMessage} or \class{MMDFMessage} instance, the \mailheader{Status}
+and \mailheader{X-Status} headers are omitted and the following conversions
+take place:
+
+\begin{tableii}{l|l}{textrm}
+    {Resulting state}{\class{mboxMessage} or \class{MMDFMessage} state}
+\lineii{"cur" subdirectory}{O flag}
+\lineii{F flag}{F flag}
+\lineii{R flag}{A flag}
+\lineii{S flag}{R flag}
+\lineii{T flag}{D flag}
+\end{tableii}
+
+When a \class{MaildirMessage} instance is created based upon an
+\class{MHMessage} instance, the following conversions take place:
+
+\begin{tableii}{l|l}{textrm}
+    {Resulting state}{\class{MHMessage} state}
+\lineii{"cur" subdirectory}{"unseen" sequence}
+\lineii{"cur" subdirectory and S flag}{no "unseen" sequence}
+\lineii{F flag}{"flagged" sequence}
+\lineii{R flag}{"replied" sequence}
+\end{tableii}
+
+When a \class{MaildirMessage} instance is created based upon a
+\class{BabylMessage} instance, the following conversions take place:
+
+\begin{tableii}{l|l}{textrm}
+    {Resulting state}{\class{BabylMessage} state}
+\lineii{"cur" subdirectory}{"unseen" label}
+\lineii{"cur" subdirectory and S flag}{no "unseen" label}
+\lineii{P flag}{"forwarded" or "resent" label}
+\lineii{R flag}{"answered" label}
+\lineii{T flag}{"deleted" label}
+\end{tableii}
+
+\subsubsection{\class{mboxMessage}}
+\label{mailbox-mboxmessage}
+
+\begin{classdesc}{mboxMessage}{\optional{message}}
+A message with mbox-specific behaviors. Parameter \var{message} has the same
+meaning as with the \class{Message} constructor.
+\end{classdesc}
+
+Messages in an mbox mailbox are stored together in a single file. The sender's
+envelope address and the time of delivery are typically stored in a line
+beginning with "From~" that is used to indicate the start of a message, though
+there is considerable variation in the exact format of this data among mbox
+implementations. Flags that indicate the state of the message, such as whether
+it has been read or marked as important, are typically stored in
+\mailheader{Status} and \mailheader{X-Status} headers.
+
+Conventional flags for mbox messages are as follows:
+
+\begin{tableiii}{l|l|l}{textrm}{Flag}{Meaning}{Explanation}
+\lineiii{R}{Read}{Read}
+\lineiii{O}{Old}{Previously detected by MUA}
+\lineiii{D}{Deleted}{Marked for subsequent deletion}
+\lineiii{F}{Flagged}{Marked as important}
+\lineiii{A}{Answered}{Replied to}
+\end{tableiii}
+
+The "R" and "O" flags are stored in the \mailheader{Status} header, and the
+"D", "F", and "A" flags are stored in the \mailheader{X-Status} header. The
+flags and headers typically appear in the order mentioned.
+
+\class{mboxMessage} instances offer the following methods:
+
+\begin{methoddesc}{get_from}{}
+Return a string representing the "From~" line that marks the start of the
+message in an mbox mailbox. The leading "From~" and the trailing newline are
+excluded.
+\end{methoddesc}
+
+\begin{methoddesc}{set_from}{from_\optional{, time_=None}}
+Set the "From~" line to \var{from_}, which should be specified without a
+leading "From~" or trailing newline. For convenience, \var{time_} may be
+specified and will be formatted appropriately and appended to \var{from_}. If
+\var{time_} is specified, it should be a \class{struct_time} instance, a tuple
+suitable for passing to \method{time.strftime()}, or \code{True} (to use
+\method{time.gmtime()}).
+\end{methoddesc}
+
+\begin{methoddesc}{get_flags}{}
+Return a string specifying the flags that are currently set. If the message
+complies with the conventional format, the result is the concatenation in the
+following order of zero or one occurrence of each of \character{R},
+\character{O}, \character{D}, \character{F}, and \character{A}.
+\end{methoddesc}
+
+\begin{methoddesc}{set_flags}{flags}
+Set the flags specified by \var{flags} and unset all others. Parameter
+\var{flags} should be the concatenation in any order of zero or more
+occurrences of each of \character{R}, \character{O}, \character{D},
+\character{F}, and \character{A}.
+\end{methoddesc}
+
+\begin{methoddesc}{add_flag}{flag}
+Set the flag(s) specified by \var{flag} without changing other flags. To add
+more than one flag at a time, \var{flag} may be a string of more than one
+character.
+\end{methoddesc}
+
+\begin{methoddesc}{remove_flag}{flag}
+Unset the flag(s) specified by \var{flag} without changing other flags. To
+remove more than one flag at a time, \var{flag} maybe a string of more than one
+character.
+\end{methoddesc}
+
+When an \class{mboxMessage} instance is created based upon a
+\class{MaildirMessage} instance, a "From~" line is generated based upon the
+\class{MaildirMessage} instance's delivery date, and the following conversions
+take place:
+
+\begin{tableii}{l|l}{textrm}
+    {Resulting state}{\class{MaildirMessage} state}
+\lineii{R flag}{S flag}
+\lineii{O flag}{"cur" subdirectory}
+\lineii{D flag}{T flag}
+\lineii{F flag}{F flag}
+\lineii{A flag}{R flag}
+\end{tableii}
+
+When an \class{mboxMessage} instance is created based upon an \class{MHMessage}
+instance, the following conversions take place:
+
+\begin{tableii}{l|l}{textrm}
+    {Resulting state}{\class{MHMessage} state}
+\lineii{R flag and O flag}{no "unseen" sequence}
+\lineii{O flag}{"unseen" sequence}
+\lineii{F flag}{"flagged" sequence}
+\lineii{A flag}{"replied" sequence}
+\end{tableii}
+
+When an \class{mboxMessage} instance is created based upon a
+\class{BabylMessage} instance, the following conversions take place:
+
+\begin{tableii}{l|l}{textrm}
+    {Resulting state}{\class{BabylMessage} state}
+\lineii{R flag and O flag}{no "unseen" label}
+\lineii{O flag}{"unseen" label}
+\lineii{D flag}{"deleted" label}
+\lineii{A flag}{"answered" label}
+\end{tableii}
+
+When a \class{Message} instance is created based upon an \class{MMDFMessage}
+instance, the "From~" line is copied and all flags directly correspond:
+
+\begin{tableii}{l|l}{textrm}
+    {Resulting state}{\class{MMDFMessage} state}
+\lineii{R flag}{R flag}
+\lineii{O flag}{O flag}
+\lineii{D flag}{D flag}
+\lineii{F flag}{F flag}
+\lineii{A flag}{A flag}
+\end{tableii}
+
+\subsubsection{\class{MHMessage}}
+\label{mailbox-mhmessage}
+
+\begin{classdesc}{MHMessage}{\optional{message}}
+A message with MH-specific behaviors. Parameter \var{message} has the same
+meaning as with the \class{Message} constructor.
+\end{classdesc}
+
+MH messages do not support marks or flags in the traditional sense, but they do
+support sequences, which are logical groupings of arbitrary messages. Some mail
+reading programs (although not the standard \program{mh} and \program{nmh}) use
+sequences in much the same way flags are used with other formats, as follows:
+
+\begin{tableii}{l|l}{textrm}{Sequence}{Explanation}
+\lineii{unseen}{Not read, but previously detected by MUA}
+\lineii{replied}{Replied to}
+\lineii{flagged}{Marked as important}
+\end{tableii}
+
+\class{MHMessage} instances offer the following methods:
+
+\begin{methoddesc}{get_sequences}{}
+Return a list of the names of sequences that include this message.
+\end{methoddesc}
+
+\begin{methoddesc}{set_sequences}{sequences}
+Set the list of sequences that include this message.
+\end{methoddesc}
+
+\begin{methoddesc}{add_sequence}{sequence}
+Add \var{sequence} to the list of sequences that include this message.
+\end{methoddesc}
+
+\begin{methoddesc}{remove_sequence}{sequence}
+Remove \var{sequence} from the list of sequences that include this message.
+\end{methoddesc}
+
+When an \class{MHMessage} instance is created based upon a
+\class{MaildirMessage} instance, the following conversions take place:
+
+\begin{tableii}{l|l}{textrm}
+    {Resulting state}{\class{MaildirMessage} state}
+\lineii{"unseen" sequence}{no S flag}
+\lineii{"replied" sequence}{R flag}
+\lineii{"flagged" sequence}{F flag}
+\end{tableii}
+
+When an \class{MHMessage} instance is created based upon an \class{mboxMessage}
+or \class{MMDFMessage} instance, the \mailheader{Status} and
+\mailheader{X-Status} headers are omitted and the following conversions take
+place:
+
+\begin{tableii}{l|l}{textrm}
+    {Resulting state}{\class{mboxMessage} or \class{MMDFMessage} state}
+\lineii{"unseen" sequence}{no R flag}
+\lineii{"replied" sequence}{A flag}
+\lineii{"flagged" sequence}{F flag}
+\end{tableii}
+
+When an \class{MHMessage} instance is created based upon a \class{BabylMessage}
+instance, the following conversions take place:
+
+\begin{tableii}{l|l}{textrm}
+    {Resulting state}{\class{BabylMessage} state}
+\lineii{"unseen" sequence}{"unseen" label}
+\lineii{"replied" sequence}{"answered" label}
+\end{tableii}
+
+\subsubsection{\class{BabylMessage}}
+\label{mailbox-babylmessage}
+
+\begin{classdesc}{BabylMessage}{\optional{message}}
+A message with Babyl-specific behaviors. Parameter \var{message} has the same
+meaning as with the \class{Message} constructor.
+\end{classdesc}
+
+Certain message labels, called \dfn{attributes}, are defined by convention to
+have special meanings. The attributes are as follows:
+
+\begin{tableii}{l|l}{textrm}{Label}{Explanation}
+\lineii{unseen}{Not read, but previously detected by MUA}
+\lineii{deleted}{Marked for subsequent deletion}
+\lineii{filed}{Copied to another file or mailbox}
+\lineii{answered}{Replied to}
+\lineii{forwarded}{Forwarded}
+\lineii{edited}{Modified by the user}
+\lineii{resent}{Resent}
+\end{tableii}
+
+By default, Rmail displays only
+visible headers. The \class{BabylMessage} class, though, uses the original
+headers because they are more complete. Visible headers may be accessed
+explicitly if desired.
+
+\class{BabylMessage} instances offer the following methods:
+
+\begin{methoddesc}{get_labels}{}
+Return a list of labels on the message.
+\end{methoddesc}
+
+\begin{methoddesc}{set_labels}{labels}
+Set the list of labels on the message to \var{labels}.
+\end{methoddesc}
+
+\begin{methoddesc}{add_label}{label}
+Add \var{label} to the list of labels on the message.
+\end{methoddesc}
+
+\begin{methoddesc}{remove_label}{label}
+Remove \var{label} from the list of labels on the message.
+\end{methoddesc}
+
+\begin{methoddesc}{get_visible}{}
+Return an \class{Message} instance whose headers are the message's visible
+headers and whose body is empty.
+\end{methoddesc}
+
+\begin{methoddesc}{set_visible}{visible}
+Set the message's visible headers to be the same as the headers in
+\var{message}. Parameter \var{visible} should be a \class{Message} instance, an
+\class{email.Message.Message} instance, a string, or a file-like object (which
+should be open in text mode).
+\end{methoddesc}
+
+\begin{methoddesc}{update_visible}{}
+When a \class{BabylMessage} instance's original headers are modified, the
+visible headers are not automatically modified to correspond. This method
+updates the visible headers as follows: each visible header with a
+corresponding original header is set to the value of the original header, each
+visible header without a corresponding original header is removed, and any of
+\mailheader{Date}, \mailheader{From}, \mailheader{Reply-To}, \mailheader{To},
+\mailheader{CC}, and \mailheader{Subject} that are present in the original
+headers but not the visible headers are added to the visible headers.
+\end{methoddesc}
+
+When a \class{BabylMessage} instance is created based upon a
+\class{MaildirMessage} instance, the following conversions take place:
+
+\begin{tableii}{l|l}{textrm}
+    {Resulting state}{\class{MaildirMessage} state}
+\lineii{"unseen" label}{no S flag}
+\lineii{"deleted" label}{T flag}
+\lineii{"answered" label}{R flag}
+\lineii{"forwarded" label}{P flag}
+\end{tableii}
+
+When a \class{BabylMessage} instance is created based upon an
+\class{mboxMessage} or \class{MMDFMessage} instance, the \mailheader{Status}
+and \mailheader{X-Status} headers are omitted and the following conversions
+take place:
+
+\begin{tableii}{l|l}{textrm}
+    {Resulting state}{\class{mboxMessage} or \class{MMDFMessage} state}
+\lineii{"unseen" label}{no R flag}
+\lineii{"deleted" label}{D flag}
+\lineii{"answered" label}{A flag}
+\end{tableii}
+
+When a \class{BabylMessage} instance is created based upon an \class{MHMessage}
+instance, the following conversions take place:
+
+\begin{tableii}{l|l}{textrm}
+    {Resulting state}{\class{MHMessage} state}
+\lineii{"unseen" label}{"unseen" sequence}
+\lineii{"answered" label}{"replied" sequence}
+\end{tableii}
+
+\subsubsection{\class{MMDFMessage}}
+\label{mailbox-mmdfmessage}
+
+\begin{classdesc}{MMDFMessage}{\optional{message}}
+A message with MMDF-specific behaviors. Parameter \var{message} has the same
+meaning as with the \class{Message} constructor.
+\end{classdesc}
+
+As with message in an mbox mailbox, MMDF messages are stored with the sender's
+address and the delivery date in an initial line beginning with "From ".
+Likewise, flags that indicate the state of the message are typically stored in
+\mailheader{Status} and \mailheader{X-Status} headers.
+
+Conventional flags for MMDF messages are identical to those of mbox message and
+are as follows:
+
+\begin{tableiii}{l|l|l}{textrm}{Flag}{Meaning}{Explanation}
+\lineiii{R}{Read}{Read}
+\lineiii{O}{Old}{Previously detected by MUA}
+\lineiii{D}{Deleted}{Marked for subsequent deletion}
+\lineiii{F}{Flagged}{Marked as important}
+\lineiii{A}{Answered}{Replied to}
+\end{tableiii}
+
+The "R" and "O" flags are stored in the \mailheader{Status} header, and the
+"D", "F", and "A" flags are stored in the \mailheader{X-Status} header. The
+flags and headers typically appear in the order mentioned.
+
+\class{MMDFMessage} instances offer the following methods, which are identical
+to those offered by \class{mboxMessage}:
+
+\begin{methoddesc}{get_from}{}
+Return a string representing the "From~" line that marks the start of the
+message in an mbox mailbox. The leading "From~" and the trailing newline are
+excluded.
+\end{methoddesc}
+
+\begin{methoddesc}{set_from}{from_\optional{, time_=None}}
+Set the "From~" line to \var{from_}, which should be specified without a
+leading "From~" or trailing newline. For convenience, \var{time_} may be
+specified and will be formatted appropriately and appended to \var{from_}. If
+\var{time_} is specified, it should be a \class{struct_time} instance, a tuple
+suitable for passing to \method{time.strftime()}, or \code{True} (to use
+\method{time.gmtime()}).
+\end{methoddesc}
+
+\begin{methoddesc}{get_flags}{}
+Return a string specifying the flags that are currently set. If the message
+complies with the conventional format, the result is the concatenation in the
+following order of zero or one occurrence of each of \character{R},
+\character{O}, \character{D}, \character{F}, and \character{A}.
+\end{methoddesc}
+
+\begin{methoddesc}{set_flags}{flags}
+Set the flags specified by \var{flags} and unset all others. Parameter
+\var{flags} should be the concatenation in any order of zero or more
+occurrences of each of \character{R}, \character{O}, \character{D},
+\character{F}, and \character{A}.
+\end{methoddesc}
+
+\begin{methoddesc}{add_flag}{flag}
+Set the flag(s) specified by \var{flag} without changing other flags. To add
+more than one flag at a time, \var{flag} may be a string of more than one
+character.
+\end{methoddesc}
+
+\begin{methoddesc}{remove_flag}{flag}
+Unset the flag(s) specified by \var{flag} without changing other flags. To
+remove more than one flag at a time, \var{flag} maybe a string of more than one
+character.
+\end{methoddesc}
+
+When an \class{MMDFMessage} instance is created based upon a
+\class{MaildirMessage} instance, a "From~" line is generated based upon the
+\class{MaildirMessage} instance's delivery date, and the following conversions
+take place:
+
+\begin{tableii}{l|l}{textrm}
+    {Resulting state}{\class{MaildirMessage} state}
+\lineii{R flag}{S flag}
+\lineii{O flag}{"cur" subdirectory}
+\lineii{D flag}{T flag}
+\lineii{F flag}{F flag}
+\lineii{A flag}{R flag}
+\end{tableii}
+
+When an \class{MMDFMessage} instance is created based upon an \class{MHMessage}
+instance, the following conversions take place:
+
+\begin{tableii}{l|l}{textrm}
+    {Resulting state}{\class{MHMessage} state}
+\lineii{R flag and O flag}{no "unseen" sequence}
+\lineii{O flag}{"unseen" sequence}
+\lineii{F flag}{"flagged" sequence}
+\lineii{A flag}{"replied" sequence}
+\end{tableii}
+
+When an \class{MMDFMessage} instance is created based upon a
+\class{BabylMessage} instance, the following conversions take place:
+
+\begin{tableii}{l|l}{textrm}
+    {Resulting state}{\class{BabylMessage} state}
+\lineii{R flag and O flag}{no "unseen" label}
+\lineii{O flag}{"unseen" label}
+\lineii{D flag}{"deleted" label}
+\lineii{A flag}{"answered" label}
+\end{tableii}
+
+When an \class{MMDFMessage} instance is created based upon an
+\class{mboxMessage} instance, the "From~" line is copied and all flags directly
+correspond:
+
+\begin{tableii}{l|l}{textrm}
+    {Resulting state}{\class{mboxMessage} state}
+\lineii{R flag}{R flag}
+\lineii{O flag}{O flag}
+\lineii{D flag}{D flag}
+\lineii{F flag}{F flag}
+\lineii{A flag}{A flag}
+\end{tableii}
+
+\subsection{Exceptions}
+\label{mailbox-deprecated}
+
+The following exception classes are defined in the \module{mailbox} module:
+
+\begin{classdesc}{Error}{}
+The based class for all other module-specific exceptions.
+\end{classdesc}
+
+\begin{classdesc}{NoSuchMailboxError}{}
+Raised when a mailbox is expected but is not found, such as when instantiating
+a \class{Mailbox} subclass with a path that does not exist (and with the
+\var{create} parameter set to \code{False}), or when opening a folder that does
+not exist.
+\end{classdesc}
+
+\begin{classdesc}{NotEmptyErrorError}{}
+Raised when a mailbox is not empty but is expected to be, such as when deleting
+a folder that contains messages.
+\end{classdesc}
+
+\begin{classdesc}{ExternalClashError}{}
+Raised when some mailbox-related condition beyond the control of the program
+causes it to be unable to proceed, such as when failing to acquire a lock that
+another program already holds a lock, or when a uniquely-generated file name
+already exists.
+\end{classdesc}
+
+\begin{classdesc}{FormatError}{}
+Raised when the data in a file cannot be parsed, such as when an \class{MH}
+instance attempts to read a corrupted \file{.mh_sequences} file.
+\end{classdesc}
+
+\subsection{Deprecated classes and methods}
+\label{mailbox-deprecated}
+
+Older versions of the \module{mailbox} module do not support modification of
+mailboxes, such as adding or removing message, and do not provide classes to
+represent format-specific message properties. For backward compatibility, the
+older mailbox classes are still available, but the newer classes should be used
+in preference to them.
+
+Older mailbox objects support only iteration and provide a single public
+method:
+
+\begin{methoddesc}{next}{}
+Return the next message in the mailbox, created with the optional \var{factory}
+argument passed into the mailbox object's constructor. By default this is an
+\class{rfc822.Message} object (see the \refmodule{rfc822} module).  Depending
+on the mailbox implementation the \var{fp} attribute of this object may be a
+true file object or a class instance simulating a file object, taking care of
+things like message boundaries if multiple mail messages are contained in a
+single file, etc.  If no more messages are available, this method returns
+\code{None}.
+\end{methoddesc}
+
+Most of the older mailbox classes have names that differ from the current
+mailbox class names, except for \class{Maildir}. For this reason, the new
+\class{Maildir} class defines a \method{next()} method and its constructor
+differs slightly from those of the other new mailbox classes.
+
+The older mailbox classes whose names are not the same as their newer
+counterparts are as follows:
+
+\begin{classdesc}{UnixMailbox}{fp\optional{, factory}}
+Access to a classic \UNIX-style mailbox, where all messages are
+contained in a single file and separated by \samp{From }
+(a.k.a.\ \samp{From_}) lines.  The file object \var{fp} points to the
+mailbox file.  The optional \var{factory} parameter is a callable that
+should create new message objects.  \var{factory} is called with one
+argument, \var{fp} by the \method{next()} method of the mailbox
+object.  The default is the \class{rfc822.Message} class (see the
+\refmodule{rfc822} module -- and the note below).
+
+\begin{notice}
+  For reasons of this module's internal implementation, you will
+  probably want to open the \var{fp} object in binary mode.  This is
+  especially important on Windows.
+\end{notice}
+
+For maximum portability, messages in a \UNIX-style mailbox are
+separated by any line that begins exactly with the string \code{'From
+'} (note the trailing space) if preceded by exactly two newlines.
+Because of the wide-range of variations in practice, nothing else on
+the From_ line should be considered.  However, the current
+implementation doesn't check for the leading two newlines.  This is
+usually fine for most applications.
+
+The \class{UnixMailbox} class implements a more strict version of
+From_ line checking, using a regular expression that usually correctly
+matched From_ delimiters.  It considers delimiter line to be separated
+by \samp{From \var{name} \var{time}} lines.  For maximum portability,
+use the \class{PortableUnixMailbox} class instead.  This class is
+identical to \class{UnixMailbox} except that individual messages are
+separated by only \samp{From } lines.
+
+For more information, see
+\citetitle[http://home.netscape.com/eng/mozilla/2.0/relnotes/demo/content-length.html]{Configuring
+Netscape Mail on \UNIX: Why the Content-Length Format is Bad}.
+\end{classdesc}
+
+\begin{classdesc}{PortableUnixMailbox}{fp\optional{, factory}}
+A less-strict version of \class{UnixMailbox}, which considers only the
+\samp{From } at the beginning of the line separating messages.  The
+``\var{name} \var{time}'' portion of the From line is ignored, to
+protect against some variations that are observed in practice.  This
+works since lines in the message which begin with \code{'From '} are
+quoted by mail handling software at delivery-time.
+\end{classdesc}
+
+\begin{classdesc}{MmdfMailbox}{fp\optional{, factory}}
+Access an MMDF-style mailbox, where all messages are contained
+in a single file and separated by lines consisting of 4 control-A
+characters.  The file object \var{fp} points to the mailbox file.
+Optional \var{factory} is as with the \class{UnixMailbox} class.
+\end{classdesc}
+
+\begin{classdesc}{MHMailbox}{dirname\optional{, factory}}
+Access an MH mailbox, a directory with each message in a separate
+file with a numeric name.
+The name of the mailbox directory is passed in \var{dirname}.
+\var{factory} is as with the \class{UnixMailbox} class.
+\end{classdesc}
+
+\begin{classdesc}{BabylMailbox}{fp\optional{, factory}}
+Access a Babyl mailbox, which is similar to an MMDF mailbox.  In
+Babyl format, each message has two sets of headers, the
+\emph{original} headers and the \emph{visible} headers.  The original
+headers appear before a line containing only \code{'*** EOOH ***'}
+(End-Of-Original-Headers) and the visible headers appear after the
+\code{EOOH} line.  Babyl-compliant mail readers will show you only the
+visible headers, and \class{BabylMailbox} objects will return messages
+containing only the visible headers.  You'll have to do your own
+parsing of the mailbox file to get at the original headers.  Mail
+messages start with the EOOH line and end with a line containing only
+\code{'\e{}037\e{}014'}.  \var{factory} is as with the
+\class{UnixMailbox} class.
+\end{classdesc}
+
+If you wish to use the older mailbox classes with the \module{email} module
+rather than the deprecated \module{rfc822} module, you can do so as follows:
+
+\begin{verbatim}
+import email
+import email.Errors
+import mailbox
+
+def msgfactory(fp):
+    try:
+        return email.message_from_file(fp)
+    except email.Errors.MessageParseError:
+        # Don't return None since that will
+        # stop the mailbox iterator
+        return ''
+
+mbox = mailbox.UnixMailbox(fp, msgfactory)
+\end{verbatim}
+
+Alternatively, if you know your mailbox contains only well-formed MIME
+messages, you can simplify this to:
+
+\begin{verbatim}
+import email
+import mailbox
+
+mbox = mailbox.UnixMailbox(fp, email.message_from_file)
+\end{verbatim}
+
+\subsection{Examples}
+\label{mailbox-examples}
+
+A simple example of printing the subjects of all messages in a mailbox that
+seem interesting:
+
+\begin{verbatim}
+import mailbox
+for message in mailbox.mbox('~/mbox'):
+    subject = message['subject']       # Could possibly be None.
+    if subject and 'python' in subject.lower():
+        print subject
+\end{verbatim}
+
+To copy all mail from a Babyl mailbox to an MH mailbox, converting all
+of the format-specific information that can be converted:
+
+\begin{verbatim}
+import mailbox
+destination = mailbox.MH('~/Mail')
+destination.lock()
+for message in mailbox.Babyl('~/RMAIL'):
+    destination.add(MHMessage(message))
+destination.flush()
+destination.unlock()
+\end{verbatim}
+
+This example sorts mail from several mailing lists into different
+mailboxes, being careful to avoid mail corruption due to concurrent
+modification by other programs, mail loss due to interruption of the
+program, or premature termination due to malformed messages in the
+mailbox:
+
+\begin{verbatim}
+import mailbox
+import email.Errors
+
+list_names = ('python-list', 'python-dev', 'python-bugs')
+
+boxes = dict((name, mailbox.mbox('~/email/%s' % name)) for name in list_names)
+inbox = mailbox.Maildir('~/Maildir', factory=None)
+
+for key in inbox.iterkeys():
+    try:
+        message = inbox[key]
+    except email.Errors.MessageParseError:
+        continue                # The message is malformed. Just leave it.
+
+    for name in list_names:
+        list_id = message['list-id']
+        if list_id and name in list_id:
+            # Get mailbox to use
+            box = boxes[name]
+
+            # Write copy to disk before removing original.
+            # If there's a crash, you might duplicate a message, but
+            # that's better than losing a message completely.
+            box.lock()
+            box.add(message)
+            box.flush()         
+            box.unlock()
+
+            # Remove original message
+            inbox.lock()
+            inbox.discard(key)
+            inbox.flush()
+            inbox.unlock()
+            break               # Found destination, so stop looking.
+
+for box in boxes.itervalues():
+    box.close()
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/libmailcap.tex
===================================================================
--- vendor/Python/current/Doc/lib/libmailcap.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libmailcap.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,82 @@
+\section{\module{mailcap} ---
+         Mailcap file handling.}
+\declaremodule{standard}{mailcap}
+
+\modulesynopsis{Mailcap file handling.}
+
+
+Mailcap files are used to configure how MIME-aware applications such
+as mail readers and Web browsers react to files with different MIME
+types. (The name ``mailcap'' is derived from the phrase ``mail
+capability''.)  For example, a mailcap file might contain a line like
+\samp{video/mpeg; xmpeg \%s}.  Then, if the user encounters an email
+message or Web document with the MIME type \mimetype{video/mpeg},
+\samp{\%s} will be replaced by a filename (usually one belonging to a
+temporary file) and the \program{xmpeg} program can be automatically
+started to view the file.
+
+The mailcap format is documented in \rfc{1524}, ``A User Agent
+Configuration Mechanism For Multimedia Mail Format Information,'' but
+is not an Internet standard.  However, mailcap files are supported on
+most \UNIX{} systems.
+
+\begin{funcdesc}{findmatch}{caps, MIMEtype%
+                            \optional{, key\optional{,
+                            filename\optional{, plist}}}}
+Return a 2-tuple; the first element is a string containing the command
+line to be executed
+(which can be passed to \function{os.system()}), and the second element is
+the mailcap entry for a given MIME type.  If no matching MIME
+type can be found, \code{(None, None)} is returned.
+
+\var{key} is the name of the field desired, which represents the type
+of activity to be performed; the default value is 'view', since in the 
+most common case you simply want to view the body of the MIME-typed
+data.  Other possible values might be 'compose' and 'edit', if you
+wanted to create a new body of the given MIME type or alter the
+existing body data.  See \rfc{1524} for a complete list of these
+fields.
+
+\var{filename} is the filename to be substituted for \samp{\%s} in the
+command line; the default value is
+\code{'/dev/null'} which is almost certainly not what you want, so
+usually you'll override it by specifying a filename.
+
+\var{plist} can be a list containing named parameters; the default
+value is simply an empty list.  Each entry in the list must be a
+string containing the parameter name, an equals sign (\character{=}),
+and the parameter's value.  Mailcap entries can contain 
+named parameters like \code{\%\{foo\}}, which will be replaced by the
+value of the parameter named 'foo'.  For example, if the command line
+\samp{showpartial \%\{id\}\ \%\{number\}\ \%\{total\}}
+was in a mailcap file, and \var{plist} was set to \code{['id=1',
+'number=2', 'total=3']}, the resulting command line would be 
+\code{'showpartial 1 2 3'}.  
+
+In a mailcap file, the ``test'' field can optionally be specified to
+test some external condition (such as the machine architecture, or the
+window system in use) to determine whether or not the mailcap line
+applies.  \function{findmatch()} will automatically check such
+conditions and skip the entry if the check fails.
+\end{funcdesc}
+
+\begin{funcdesc}{getcaps}{}
+Returns a dictionary mapping MIME types to a list of mailcap file
+entries. This dictionary must be passed to the \function{findmatch()}
+function.  An entry is stored as a list of dictionaries, but it
+shouldn't be necessary to know the details of this representation.
+
+The information is derived from all of the mailcap files found on the
+system. Settings in the user's mailcap file \file{\$HOME/.mailcap}
+will override settings in the system mailcap files
+\file{/etc/mailcap}, \file{/usr/etc/mailcap}, and
+\file{/usr/local/etc/mailcap}.
+\end{funcdesc}
+
+An example usage:
+\begin{verbatim}
+>>> import mailcap
+>>> d=mailcap.getcaps()
+>>> mailcap.findmatch(d, 'video/mpeg', filename='/tmp/tmp1223')
+('xmpeg /tmp/tmp1223', {'view': 'xmpeg %s'})
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/libmain.tex
===================================================================
--- vendor/Python/current/Doc/lib/libmain.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libmain.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,16 @@
+\section{\module{__main__} ---
+         Top-level script environment}
+
+\declaremodule[main]{builtin}{__main__}
+\modulesynopsis{The environment where the top-level script is run.}
+
+This module represents the (otherwise anonymous) scope in which the
+interpreter's main program executes --- commands read either from
+standard input, from a script file, or from an interactive prompt.  It
+is this environment in which the idiomatic ``conditional script''
+stanza causes a script to run:
+
+\begin{verbatim}
+if __name__ == "__main__":
+    main()
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/libmarshal.tex
===================================================================
--- vendor/Python/current/Doc/lib/libmarshal.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libmarshal.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,117 @@
+\section{\module{marshal} ---
+         Internal Python object serialization}
+
+\declaremodule{builtin}{marshal}
+\modulesynopsis{Convert Python objects to streams of bytes and back
+                (with different constraints).}
+
+
+This module contains functions that can read and write Python
+values in a binary format.  The format is specific to Python, but
+independent of machine architecture issues (e.g., you can write a
+Python value to a file on a PC, transport the file to a Sun, and read
+it back there).  Details of the format are undocumented on purpose;
+it may change between Python versions (although it rarely
+does).\footnote{The name of this module stems from a bit of
+  terminology used by the designers of Modula-3 (amongst others), who
+  use the term ``marshalling'' for shipping of data around in a
+  self-contained form. Strictly speaking, ``to marshal'' means to
+  convert some data from internal to external form (in an RPC buffer for
+  instance) and ``unmarshalling'' for the reverse process.}
+
+This is not a general ``persistence'' module.  For general persistence
+and transfer of Python objects through RPC calls, see the modules
+\refmodule{pickle} and \refmodule{shelve}.  The \module{marshal} module exists
+mainly to support reading and writing the ``pseudo-compiled'' code for
+Python modules of \file{.pyc} files.  Therefore, the Python
+maintainers reserve the right to modify the marshal format in backward
+incompatible ways should the need arise.  If you're serializing and
+de-serializing Python objects, use the \module{pickle} module instead.  
+\refstmodindex{pickle}
+\refstmodindex{shelve}
+\obindex{code}
+
+\begin{notice}[warning]
+The \module{marshal} module is not intended to be secure against
+erroneous or maliciously constructed data.  Never unmarshal data
+received from an untrusted or unauthenticated source.
+\end{notice}
+
+Not all Python object types are supported; in general, only objects
+whose value is independent from a particular invocation of Python can
+be written and read by this module.  The following types are supported:
+\code{None}, integers, long integers, floating point numbers,
+strings, Unicode objects, tuples, lists, dictionaries, and code
+objects, where it should be understood that tuples, lists and
+dictionaries are only supported as long as the values contained
+therein are themselves supported; and recursive lists and dictionaries
+should not be written (they will cause infinite loops).
+
+\strong{Caveat:} On machines where C's \code{long int} type has more than
+32 bits (such as the DEC Alpha), it is possible to create plain Python
+integers that are longer than 32 bits.
+If such an integer is marshaled and read back in on a machine where
+C's \code{long int} type has only 32 bits, a Python long integer object
+is returned instead.  While of a different type, the numeric value is
+the same.  (This behavior is new in Python 2.2.  In earlier versions,
+all but the least-significant 32 bits of the value were lost, and a
+warning message was printed.)
+
+There are functions that read/write files as well as functions
+operating on strings.
+
+The module defines these functions:
+
+\begin{funcdesc}{dump}{value, file\optional{, version}}
+  Write the value on the open file.  The value must be a supported
+  type.  The file must be an open file object such as
+  \code{sys.stdout} or returned by \function{open()} or
+  \function{posix.popen()}.  It must be opened in binary mode
+  (\code{'wb'} or \code{'w+b'}).
+
+  If the value has (or contains an object that has) an unsupported type,
+  a \exception{ValueError} exception is raised --- but garbage data
+  will also be written to the file.  The object will not be properly
+  read back by \function{load()}.
+
+  \versionadded[The \var{version} argument indicates the data
+  format that \code{dump} should use (see below)]{2.4}
+\end{funcdesc}
+
+\begin{funcdesc}{load}{file}
+  Read one value from the open file and return it.  If no valid value
+  is read, raise \exception{EOFError}, \exception{ValueError} or
+  \exception{TypeError}.  The file must be an open file object opened
+  in binary mode (\code{'rb'} or \code{'r+b'}).
+
+  \warning{If an object containing an unsupported type was
+  marshalled with \function{dump()}, \function{load()} will substitute
+  \code{None} for the unmarshallable type.}
+\end{funcdesc}
+
+\begin{funcdesc}{dumps}{value\optional{, version}}
+  Return the string that would be written to a file by
+  \code{dump(\var{value}, \var{file})}.  The value must be a supported
+  type.  Raise a \exception{ValueError} exception if value has (or
+  contains an object that has) an unsupported type.
+
+  \versionadded[The \var{version} argument indicates the data
+  format that \code{dumps} should use (see below)]{2.4}
+\end{funcdesc}
+
+\begin{funcdesc}{loads}{string}
+  Convert the string to a value.  If no valid value is found, raise
+  \exception{EOFError}, \exception{ValueError} or
+  \exception{TypeError}.  Extra characters in the string are ignored.
+\end{funcdesc}
+
+In addition, the following constants are defined:
+
+\begin{datadesc}{version}
+  Indicates the format that the module uses. Version 0 is the
+  historical format, version 1 (added in Python 2.4) shares interned
+  strings and version 2 (added in Python 2.5) uses a binary format for
+  floating point numbers. The current version is 2.
+
+  \versionadded{2.4}
+\end{datadesc}

Added: vendor/Python/current/Doc/lib/libmath.tex
===================================================================
--- vendor/Python/current/Doc/lib/libmath.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libmath.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,209 @@
+\section{\module{math} ---
+         Mathematical functions}
+
+\declaremodule{builtin}{math}
+\modulesynopsis{Mathematical functions (\function{sin()} etc.).}
+
+This module is always available.  It provides access to the
+mathematical functions defined by the C standard.
+
+These functions cannot be used with complex numbers; use the functions
+of the same name from the \refmodule{cmath} module if you require
+support for complex numbers.  The distinction between functions which
+support complex numbers and those which don't is made since most users
+do not want to learn quite as much mathematics as required to
+understand complex numbers.  Receiving an exception instead of a
+complex result allows earlier detection of the unexpected complex
+number used as a parameter, so that the programmer can determine how
+and why it was generated in the first place.
+
+The following functions are provided by this module.  Except
+when explicitly noted otherwise, all return values are floats.
+
+Number-theoretic and representation functions:
+
+\begin{funcdesc}{ceil}{x}
+Return the ceiling of \var{x} as a float, the smallest integer value
+greater than or equal to \var{x}.
+\end{funcdesc}
+
+\begin{funcdesc}{fabs}{x}
+Return the absolute value of \var{x}.
+\end{funcdesc}
+
+\begin{funcdesc}{floor}{x}
+Return the floor of \var{x} as a float, the largest integer value
+less than or equal to \var{x}.
+\end{funcdesc}
+
+\begin{funcdesc}{fmod}{x, y}
+Return \code{fmod(\var{x}, \var{y})}, as defined by the platform C library.
+Note that the Python expression \code{\var{x} \%\ \var{y}} may not return
+the same result.  The intent of the C standard is that
+\code{fmod(\var{x}, \var{y})} be exactly (mathematically; to infinite
+precision) equal to \code{\var{x} - \var{n}*\var{y}} for some integer
+\var{n} such that the result has the same sign as \var{x} and
+magnitude less than \code{abs(\var{y})}.  Python's
+\code{\var{x} \%\ \var{y}} returns a result with the sign of
+\var{y} instead, and may not be exactly computable for float arguments.
+For example, \code{fmod(-1e-100, 1e100)} is \code{-1e-100}, but the
+result of Python's \code{-1e-100 \%\ 1e100} is \code{1e100-1e-100}, which
+cannot be represented exactly as a float, and rounds to the surprising
+\code{1e100}.  For this reason, function \function{fmod()} is generally
+preferred when working with floats, while Python's
+\code{\var{x} \%\ \var{y}} is preferred when working with integers.
+\end{funcdesc}
+
+\begin{funcdesc}{frexp}{x}
+Return the mantissa and exponent of \var{x} as the pair
+\code{(\var{m}, \var{e})}.  \var{m} is a float and \var{e} is an
+integer such that \code{\var{x} == \var{m} * 2**\var{e}} exactly.
+If \var{x} is zero, returns \code{(0.0, 0)}, otherwise
+\code{0.5 <= abs(\var{m}) < 1}.  This is used to "pick apart" the
+internal representation of a float in a portable way.
+\end{funcdesc}
+
+\begin{funcdesc}{ldexp}{x, i}
+Return \code{\var{x} * (2**\var{i})}.  This is essentially the inverse of
+function \function{frexp()}.
+\end{funcdesc}
+
+\begin{funcdesc}{modf}{x}
+Return the fractional and integer parts of \var{x}.  Both results
+carry the sign of \var{x}, and both are floats.
+\end{funcdesc}
+
+Note that \function{frexp()} and \function{modf()} have a different
+call/return pattern than their C equivalents: they take a single
+argument and return a pair of values, rather than returning their
+second return value through an `output parameter' (there is no such
+thing in Python).
+
+For the \function{ceil()}, \function{floor()}, and \function{modf()}
+functions, note that \emph{all} floating-point numbers of sufficiently
+large magnitude are exact integers.  Python floats typically carry no more
+than 53 bits of precision (the same as the platform C double type), in
+which case any float \var{x} with \code{abs(\var{x}) >= 2**52}
+necessarily has no fractional bits.
+
+
+Power and logarithmic functions:
+
+\begin{funcdesc}{exp}{x}
+Return \code{e**\var{x}}.
+\end{funcdesc}
+
+\begin{funcdesc}{log}{x\optional{, base}}
+Return the logarithm of \var{x} to the given \var{base}.
+If the \var{base} is not specified, return the natural logarithm of \var{x}
+(that is, the logarithm to base \emph{e}).
+\versionchanged[\var{base} argument added]{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{log10}{x}
+Return the base-10 logarithm of \var{x}.
+\end{funcdesc}
+
+\begin{funcdesc}{pow}{x, y}
+Return \code{\var{x}**\var{y}}.
+\end{funcdesc}
+
+\begin{funcdesc}{sqrt}{x}
+Return the square root of \var{x}.
+\end{funcdesc}
+
+Trigonometric functions:
+
+\begin{funcdesc}{acos}{x}
+Return the arc cosine of \var{x}, in radians.
+\end{funcdesc}
+
+\begin{funcdesc}{asin}{x}
+Return the arc sine of \var{x}, in radians.
+\end{funcdesc}
+
+\begin{funcdesc}{atan}{x}
+Return the arc tangent of \var{x}, in radians.
+\end{funcdesc}
+
+\begin{funcdesc}{atan2}{y, x}
+Return \code{atan(\var{y} / \var{x})}, in radians.
+The result is between \code{-pi} and \code{pi}.
+The vector in the plane from the origin to point \code{(\var{x}, \var{y})}
+makes this angle with the positive X axis.
+The point of \function{atan2()} is that the signs of both inputs are
+known to it, so it can compute the correct quadrant for the angle.
+For example, \code{atan(1}) and \code{atan2(1, 1)} are both \code{pi/4},
+but \code{atan2(-1, -1)} is \code{-3*pi/4}.
+\end{funcdesc}
+
+\begin{funcdesc}{cos}{x}
+Return the cosine of \var{x} radians.
+\end{funcdesc}
+
+\begin{funcdesc}{hypot}{x, y}
+Return the Euclidean norm, \code{sqrt(\var{x}*\var{x} + \var{y}*\var{y})}.
+This is the length of the vector from the origin to point
+\code{(\var{x}, \var{y})}.
+\end{funcdesc}
+
+\begin{funcdesc}{sin}{x}
+Return the sine of \var{x} radians.
+\end{funcdesc}
+
+\begin{funcdesc}{tan}{x}
+Return the tangent of \var{x} radians.
+\end{funcdesc}
+
+Angular conversion:
+
+\begin{funcdesc}{degrees}{x}
+Converts angle \var{x} from radians to degrees.
+\end{funcdesc}
+
+\begin{funcdesc}{radians}{x}
+Converts angle \var{x} from degrees to radians.
+\end{funcdesc}
+
+Hyperbolic functions:
+
+\begin{funcdesc}{cosh}{x}
+Return the hyperbolic cosine of \var{x}.
+\end{funcdesc}
+
+\begin{funcdesc}{sinh}{x}
+Return the hyperbolic sine of \var{x}.
+\end{funcdesc}
+
+\begin{funcdesc}{tanh}{x}
+Return the hyperbolic tangent of \var{x}.
+\end{funcdesc}
+
+The module also defines two mathematical constants:
+
+\begin{datadesc}{pi}
+The mathematical constant \emph{pi}.
+\end{datadesc}
+
+\begin{datadesc}{e}
+The mathematical constant \emph{e}.
+\end{datadesc}
+
+\begin{notice}
+  The \module{math} module consists mostly of thin wrappers around
+  the platform C math library functions.  Behavior in exceptional cases is
+  loosely specified by the C standards, and Python inherits much of its
+  math-function error-reporting behavior from the platform C
+  implementation.  As a result,
+  the specific exceptions raised in error cases (and even whether some
+  arguments are considered to be exceptional at all) are not defined in any
+  useful cross-platform or cross-release way.  For example, whether
+  \code{math.log(0)} returns \code{-Inf} or raises \exception{ValueError} or
+  \exception{OverflowError} isn't defined, and in
+  cases where \code{math.log(0)} raises \exception{OverflowError},
+  \code{math.log(0L)} may raise \exception{ValueError} instead.
+\end{notice}
+
+\begin{seealso}
+  \seemodule{cmath}{Complex number versions of many of these functions.}
+\end{seealso}

Added: vendor/Python/current/Doc/lib/libmd5.tex
===================================================================
--- vendor/Python/current/Doc/lib/libmd5.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libmd5.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,92 @@
+\section{\module{md5} ---
+         MD5 message digest algorithm}
+
+\declaremodule{builtin}{md5}
+\modulesynopsis{RSA's MD5 message digest algorithm.}
+
+\deprecated{2.5}{Use the \refmodule{hashlib} module instead.}
+
+This module implements the interface to RSA's MD5 message digest
+\index{message digest, MD5}
+algorithm (see also Internet \rfc{1321}).  Its use is quite
+straightforward:\ use \function{new()} to create an md5 object.
+You can now feed this object with arbitrary strings using the
+\method{update()} method, and at any point you can ask it for the
+\dfn{digest} (a strong kind of 128-bit checksum,
+a.k.a. ``fingerprint'') of the concatenation of the strings fed to it
+so far using the \method{digest()} method.
+\index{checksum!MD5}
+
+For example, to obtain the digest of the string \code{'Nobody inspects
+the spammish repetition'}:
+
+\begin{verbatim}
+>>> import md5
+>>> m = md5.new()
+>>> m.update("Nobody inspects")
+>>> m.update(" the spammish repetition")
+>>> m.digest()
+'\xbbd\x9c\x83\xdd\x1e\xa5\xc9\xd9\xde\xc9\xa1\x8d\xf0\xff\xe9'
+\end{verbatim}
+
+More condensed:
+
+\begin{verbatim}
+>>> md5.new("Nobody inspects the spammish repetition").digest()
+'\xbbd\x9c\x83\xdd\x1e\xa5\xc9\xd9\xde\xc9\xa1\x8d\xf0\xff\xe9'
+\end{verbatim}
+
+The following values are provided as constants in the module and as
+attributes of the md5 objects returned by \function{new()}:
+
+\begin{datadesc}{digest_size}
+  The size of the resulting digest in bytes.  This is always
+  \code{16}.
+\end{datadesc}
+
+The md5 module provides the following functions:
+
+\begin{funcdesc}{new}{\optional{arg}}
+Return a new md5 object.  If \var{arg} is present, the method call
+\code{update(\var{arg})} is made.
+\end{funcdesc}
+
+\begin{funcdesc}{md5}{\optional{arg}}
+For backward compatibility reasons, this is an alternative name for the
+\function{new()} function.
+\end{funcdesc}
+
+An md5 object has the following methods:
+
+\begin{methoddesc}[md5]{update}{arg}
+Update the md5 object with the string \var{arg}.  Repeated calls are
+equivalent to a single call with the concatenation of all the
+arguments: \code{m.update(a); m.update(b)} is equivalent to
+\code{m.update(a+b)}.
+\end{methoddesc}
+
+\begin{methoddesc}[md5]{digest}{}
+Return the digest of the strings passed to the \method{update()}
+method so far.  This is a 16-byte string which may contain
+non-\ASCII{} characters, including null bytes.
+\end{methoddesc}
+
+\begin{methoddesc}[md5]{hexdigest}{}
+Like \method{digest()} except the digest is returned as a string of
+length 32, containing only hexadecimal digits.  This may 
+be used to exchange the value safely in email or other non-binary
+environments.
+\end{methoddesc}
+
+\begin{methoddesc}[md5]{copy}{}
+Return a copy (``clone'') of the md5 object.  This can be used to
+efficiently compute the digests of strings that share a common initial
+substring.
+\end{methoddesc}
+
+
+\begin{seealso}
+  \seemodule{sha}{Similar module implementing the Secure Hash
+                  Algorithm (SHA).  The SHA algorithm is considered a
+                  more secure hash.}
+\end{seealso}

Added: vendor/Python/current/Doc/lib/libmhlib.tex
===================================================================
--- vendor/Python/current/Doc/lib/libmhlib.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libmhlib.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,168 @@
+\section{\module{mhlib} ---
+         Access to MH mailboxes}
+
+% LaTeX'ized from the comments in the module by Skip Montanaro
+% <skip at mojam.com>.
+
+\declaremodule{standard}{mhlib}
+\modulesynopsis{Manipulate MH mailboxes from Python.}
+
+
+The \module{mhlib} module provides a Python interface to MH folders and
+their contents.
+
+The module contains three basic classes, \class{MH}, which represents a
+particular collection of folders, \class{Folder}, which represents a single
+folder, and \class{Message}, which represents a single message.
+
+
+\begin{classdesc}{MH}{\optional{path\optional{, profile}}}
+\class{MH} represents a collection of MH folders.
+\end{classdesc}
+
+\begin{classdesc}{Folder}{mh, name}
+The \class{Folder} class represents a single folder and its messages.
+\end{classdesc}
+
+\begin{classdesc}{Message}{folder, number\optional{, name}}
+\class{Message} objects represent individual messages in a folder.  The
+Message class is derived from \class{mimetools.Message}.
+\end{classdesc}
+
+
+\subsection{MH Objects \label{mh-objects}}
+
+\class{MH} instances have the following methods:
+
+
+\begin{methoddesc}[MH]{error}{format\optional{, ...}}
+Print an error message -- can be overridden.
+\end{methoddesc}
+
+\begin{methoddesc}[MH]{getprofile}{key}
+Return a profile entry (\code{None} if not set).
+\end{methoddesc}
+
+\begin{methoddesc}[MH]{getpath}{}
+Return the mailbox pathname.
+\end{methoddesc}
+
+\begin{methoddesc}[MH]{getcontext}{}
+Return the current folder name.
+\end{methoddesc}
+
+\begin{methoddesc}[MH]{setcontext}{name}
+Set the current folder name.
+\end{methoddesc}
+
+\begin{methoddesc}[MH]{listfolders}{}
+Return a list of top-level folders.
+\end{methoddesc}
+
+\begin{methoddesc}[MH]{listallfolders}{}
+Return a list of all folders.
+\end{methoddesc}
+
+\begin{methoddesc}[MH]{listsubfolders}{name}
+Return a list of direct subfolders of the given folder.
+\end{methoddesc}
+
+\begin{methoddesc}[MH]{listallsubfolders}{name}
+Return a list of all subfolders of the given folder.
+\end{methoddesc}
+
+\begin{methoddesc}[MH]{makefolder}{name}
+Create a new folder.
+\end{methoddesc}
+
+\begin{methoddesc}[MH]{deletefolder}{name}
+Delete a folder -- must have no subfolders.
+\end{methoddesc}
+
+\begin{methoddesc}[MH]{openfolder}{name}
+Return a new open folder object.
+\end{methoddesc}
+
+
+
+\subsection{Folder Objects \label{mh-folder-objects}}
+
+\class{Folder} instances represent open folders and have the following
+methods:
+
+
+\begin{methoddesc}[Folder]{error}{format\optional{, ...}}
+Print an error message -- can be overridden.
+\end{methoddesc}
+
+\begin{methoddesc}[Folder]{getfullname}{}
+Return the folder's full pathname.
+\end{methoddesc}
+
+\begin{methoddesc}[Folder]{getsequencesfilename}{}
+Return the full pathname of the folder's sequences file.
+\end{methoddesc}
+
+\begin{methoddesc}[Folder]{getmessagefilename}{n}
+Return the full pathname of message \var{n} of the folder.
+\end{methoddesc}
+
+\begin{methoddesc}[Folder]{listmessages}{}
+Return a list of messages in the folder (as numbers).
+\end{methoddesc}
+
+\begin{methoddesc}[Folder]{getcurrent}{}
+Return the current message number.
+\end{methoddesc}
+
+\begin{methoddesc}[Folder]{setcurrent}{n}
+Set the current message number to \var{n}.
+\end{methoddesc}
+
+\begin{methoddesc}[Folder]{parsesequence}{seq}
+Parse msgs syntax into list of messages.
+\end{methoddesc}
+
+\begin{methoddesc}[Folder]{getlast}{}
+Get last message, or \code{0} if no messages are in the folder.
+\end{methoddesc}
+
+\begin{methoddesc}[Folder]{setlast}{n}
+Set last message (internal use only).
+\end{methoddesc}
+
+\begin{methoddesc}[Folder]{getsequences}{}
+Return dictionary of sequences in folder.  The sequence names are used 
+as keys, and the values are the lists of message numbers in the
+sequences.
+\end{methoddesc}
+
+\begin{methoddesc}[Folder]{putsequences}{dict}
+Return dictionary of sequences in folder {name: list}.
+\end{methoddesc}
+
+\begin{methoddesc}[Folder]{removemessages}{list}
+Remove messages in list from folder.
+\end{methoddesc}
+
+\begin{methoddesc}[Folder]{refilemessages}{list, tofolder}
+Move messages in list to other folder.
+\end{methoddesc}
+
+\begin{methoddesc}[Folder]{movemessage}{n, tofolder, ton}
+Move one message to a given destination in another folder.
+\end{methoddesc}
+
+\begin{methoddesc}[Folder]{copymessage}{n, tofolder, ton}
+Copy one message to a given destination in another folder.
+\end{methoddesc}
+
+
+\subsection{Message Objects \label{mh-message-objects}}
+
+The \class{Message} class adds one method to those of
+\class{mimetools.Message}:
+
+\begin{methoddesc}[Message]{openmessage}{n}
+Return a new open message object (costs a file descriptor).
+\end{methoddesc}

Added: vendor/Python/current/Doc/lib/libmimetools.tex
===================================================================
--- vendor/Python/current/Doc/lib/libmimetools.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libmimetools.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,120 @@
+\section{\module{mimetools} ---
+         Tools for parsing MIME messages}
+
+\declaremodule{standard}{mimetools}
+\modulesynopsis{Tools for parsing MIME-style message bodies.}
+
+\deprecated{2.3}{The \refmodule{email} package should be used in
+                 preference to the \module{mimetools} module.  This
+                 module is present only to maintain backward
+                 compatibility.}
+
+This module defines a subclass of the
+\refmodule{rfc822}\refstmodindex{rfc822} module's
+\class{Message} class and a number of utility functions that are
+useful for the manipulation for MIME multipart or encoded message.
+
+It defines the following items:
+
+\begin{classdesc}{Message}{fp\optional{, seekable}}
+Return a new instance of the \class{Message} class.  This is a
+subclass of the \class{rfc822.Message} class, with some additional
+methods (see below).  The \var{seekable} argument has the same meaning
+as for \class{rfc822.Message}.
+\end{classdesc}
+
+\begin{funcdesc}{choose_boundary}{}
+Return a unique string that has a high likelihood of being usable as a
+part boundary.  The string has the form
+\code{'\var{hostipaddr}.\var{uid}.\var{pid}.\var{timestamp}.\var{random}'}.
+\end{funcdesc}
+
+\begin{funcdesc}{decode}{input, output, encoding}
+Read data encoded using the allowed MIME \var{encoding} from open file
+object \var{input} and write the decoded data to open file object
+\var{output}.  Valid values for \var{encoding} include
+\code{'base64'}, \code{'quoted-printable'}, \code{'uuencode'},
+\code{'x-uuencode'}, \code{'uue'}, \code{'x-uue'}, \code{'7bit'}, and 
+\code{'8bit'}.  Decoding messages encoded in \code{'7bit'} or \code{'8bit'}
+has no effect.  The input is simply copied to the output.
+\end{funcdesc}
+
+\begin{funcdesc}{encode}{input, output, encoding}
+Read data from open file object \var{input} and write it encoded using
+the allowed MIME \var{encoding} to open file object \var{output}.
+Valid values for \var{encoding} are the same as for \method{decode()}.
+\end{funcdesc}
+
+\begin{funcdesc}{copyliteral}{input, output}
+Read lines from open file \var{input} until \EOF{} and write them to
+open file \var{output}.
+\end{funcdesc}
+
+\begin{funcdesc}{copybinary}{input, output}
+Read blocks until \EOF{} from open file \var{input} and write them to
+open file \var{output}.  The block size is currently fixed at 8192.
+\end{funcdesc}
+
+
+\begin{seealso}
+  \seemodule{email}{Comprehensive email handling package; supersedes
+                    the \module{mimetools} module.}
+  \seemodule{rfc822}{Provides the base class for
+                     \class{mimetools.Message}.}
+  \seemodule{multifile}{Support for reading files which contain
+                        distinct parts, such as MIME data.}
+  \seeurl{http://www.cs.uu.nl/wais/html/na-dir/mail/mime-faq/.html}{
+          The MIME Frequently Asked Questions document.  For an
+          overview of MIME, see the answer to question 1.1 in Part 1
+          of this document.}
+\end{seealso}
+
+
+\subsection{Additional Methods of Message Objects
+            \label{mimetools-message-objects}}
+
+The \class{Message} class defines the following methods in
+addition to the \class{rfc822.Message} methods:
+
+\begin{methoddesc}{getplist}{}
+Return the parameter list of the \mailheader{Content-Type} header.
+This is a list of strings.  For parameters of the form
+\samp{\var{key}=\var{value}}, \var{key} is converted to lower case but
+\var{value} is not.  For example, if the message contains the header
+\samp{Content-type: text/html; spam=1; Spam=2; Spam} then
+\method{getplist()} will return the Python list \code{['spam=1',
+'spam=2', 'Spam']}.
+\end{methoddesc}
+
+\begin{methoddesc}{getparam}{name}
+Return the \var{value} of the first parameter (as returned by
+\method{getplist()}) of the form \samp{\var{name}=\var{value}} for the
+given \var{name}.  If \var{value} is surrounded by quotes of the form
+`\code{<}...\code{>}' or `\code{"}...\code{"}', these are removed.
+\end{methoddesc}
+
+\begin{methoddesc}{getencoding}{}
+Return the encoding specified in the
+\mailheader{Content-Transfer-Encoding} message header.  If no such
+header exists, return \code{'7bit'}.  The encoding is converted to
+lower case.
+\end{methoddesc}
+
+\begin{methoddesc}{gettype}{}
+Return the message type (of the form \samp{\var{type}/\var{subtype}})
+as specified in the \mailheader{Content-Type} header.  If no such
+header exists, return \code{'text/plain'}.  The type is converted to
+lower case.
+\end{methoddesc}
+
+\begin{methoddesc}{getmaintype}{}
+Return the main type as specified in the \mailheader{Content-Type}
+header.  If no such header exists, return \code{'text'}.  The main
+type is converted to lower case.
+\end{methoddesc}
+
+\begin{methoddesc}{getsubtype}{}
+Return the subtype as specified in the \mailheader{Content-Type}
+header.  If no such header exists, return \code{'plain'}.  The subtype
+is converted to lower case.
+\end{methoddesc}

Added: vendor/Python/current/Doc/lib/libmimetypes.tex
===================================================================
--- vendor/Python/current/Doc/lib/libmimetypes.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libmimetypes.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,226 @@
+\section{\module{mimetypes} ---
+         Map filenames to MIME types}
+
+\declaremodule{standard}{mimetypes}
+\modulesynopsis{Mapping of filename extensions to MIME types.}
+\sectionauthor{Fred L. Drake, Jr.}{fdrake at acm.org}
+
+
+\indexii{MIME}{content type}
+
+The \module{mimetypes} module converts between a filename or URL and
+the MIME type associated with the filename extension.  Conversions are
+provided from filename to MIME type and from MIME type to filename
+extension; encodings are not supported for the latter conversion.
+
+The module provides one class and a number of convenience functions.
+The functions are the normal interface to this module, but some
+applications may be interested in the class as well.
+
+The functions described below provide the primary interface for this
+module.  If the module has not been initialized, they will call
+\function{init()} if they rely on the information \function{init()}
+sets up.
+
+
+\begin{funcdesc}{guess_type}{filename\optional{, strict}}
+Guess the type of a file based on its filename or URL, given by
+\var{filename}.  The return value is a tuple \code{(\var{type},
+\var{encoding})} where \var{type} is \code{None} if the type can't be
+guessed (missing or unknown suffix) or a string of the form
+\code{'\var{type}/\var{subtype}'}, usable for a MIME
+\mailheader{content-type} header\indexii{MIME}{headers}.
+
+\var{encoding} is \code{None} for no encoding or the name of the
+program used to encode (e.g. \program{compress} or \program{gzip}).
+The encoding is suitable for use as a \mailheader{Content-Encoding}
+header, \emph{not} as a \mailheader{Content-Transfer-Encoding} header.
+The mappings are table driven.  Encoding suffixes are case sensitive;
+type suffixes are first tried case sensitively, then case
+insensitively.
+
+Optional \var{strict} is a flag specifying whether the list of known
+MIME types is limited to only the official types \ulink{registered
+with IANA}{http://www.isi.edu/in-notes/iana/assignments/media-types}
+are recognized.  When \var{strict} is true (the default), only the
+IANA types are supported; when \var{strict} is false, some additional
+non-standard but commonly used MIME types are also recognized.
+\end{funcdesc}
+
+\begin{funcdesc}{guess_all_extensions}{type\optional{, strict}}
+Guess the extensions for a file based on its MIME type, given by
+\var{type}.
+The return value is a list of strings giving all possible filename extensions,
+including the leading dot (\character{.}).  The extensions are not guaranteed
+to have been associated with any particular data stream, but would be mapped
+to the MIME type \var{type} by \function{guess_type()}.
+
+Optional \var{strict} has the same meaning as with the
+\function{guess_type()} function.
+\end{funcdesc}
+
+
+\begin{funcdesc}{guess_extension}{type\optional{, strict}}
+Guess the extension for a file based on its MIME type, given by
+\var{type}.
+The return value is a string giving a filename extension, including the
+leading dot (\character{.}).  The extension is not guaranteed to have been
+associated with any particular data stream, but would be mapped to the 
+MIME type \var{type} by \function{guess_type()}.  If no extension can
+be guessed for \var{type}, \code{None} is returned.
+
+Optional \var{strict} has the same meaning as with the
+\function{guess_type()} function.
+\end{funcdesc}
+
+
+Some additional functions and data items are available for controlling
+the behavior of the module.
+
+
+\begin{funcdesc}{init}{\optional{files}}
+Initialize the internal data structures.  If given, \var{files} must
+be a sequence of file names which should be used to augment the
+default type map.  If omitted, the file names to use are taken from
+\constant{knownfiles}.  Each file named in \var{files} or
+\constant{knownfiles} takes precedence over those named before it.
+Calling \function{init()} repeatedly is allowed.
+\end{funcdesc}
+
+\begin{funcdesc}{read_mime_types}{filename}
+Load the type map given in the file \var{filename}, if it exists.  The 
+type map is returned as a dictionary mapping filename extensions,
+including the leading dot (\character{.}), to strings of the form
+\code{'\var{type}/\var{subtype}'}.  If the file \var{filename} does
+not exist or cannot be read, \code{None} is returned.
+\end{funcdesc}
+
+
+\begin{funcdesc}{add_type}{type, ext\optional{, strict}}
+Add a mapping from the mimetype \var{type} to the extension \var{ext}.
+When the extension is already known, the new type will replace the old
+one. When the type is already known the extension will be added
+to the list of known extensions.
+
+When \var{strict} is the mapping will added to the official
+MIME types, otherwise to the non-standard ones.
+\end{funcdesc}
+
+
+\begin{datadesc}{inited}
+Flag indicating whether or not the global data structures have been
+initialized.  This is set to true by \function{init()}.
+\end{datadesc}
+
+\begin{datadesc}{knownfiles}
+List of type map file names commonly installed.  These files are
+typically named \file{mime.types} and are installed in different
+locations by different packages.\index{file!mime.types}
+\end{datadesc}
+
+\begin{datadesc}{suffix_map}
+Dictionary mapping suffixes to suffixes.  This is used to allow
+recognition of encoded files for which the encoding and the type are
+indicated by the same extension.  For example, the \file{.tgz}
+extension is mapped to \file{.tar.gz} to allow the encoding and type
+to be recognized separately.
+\end{datadesc}
+
+\begin{datadesc}{encodings_map}
+Dictionary mapping filename extensions to encoding types.
+\end{datadesc}
+
+\begin{datadesc}{types_map}
+Dictionary mapping filename extensions to MIME types.
+\end{datadesc}
+
+\begin{datadesc}{common_types}
+Dictionary mapping filename extensions to non-standard, but commonly
+found MIME types.
+\end{datadesc}
+
+
+The \class{MimeTypes} class may be useful for applications which may
+want more than one MIME-type database:
+
+\begin{classdesc}{MimeTypes}{\optional{filenames}}
+  This class represents a MIME-types database.  By default, it
+  provides access to the same database as the rest of this module.
+  The initial database is a copy of that provided by the module, and
+  may be extended by loading additional \file{mime.types}-style files
+  into the database using the \method{read()} or \method{readfp()}
+  methods.  The mapping dictionaries may also be cleared before
+  loading additional data if the default data is not desired.
+
+  The optional \var{filenames} parameter can be used to cause
+  additional files to be loaded ``on top'' of the default database.
+
+  \versionadded{2.2}
+\end{classdesc}
+
+An example usage of the module:
+
+\begin{verbatim}
+>>> import mimetypes
+>>> mimetypes.init()
+>>> mimetypes.knownfiles
+['/etc/mime.types', '/etc/httpd/mime.types', ... ]
+>>> mimetypes.suffix_map['.tgz']
+'.tar.gz'
+>>> mimetypes.encodings_map['.gz']
+'gzip'
+>>> mimetypes.types_map['.tgz']
+'application/x-tar-gz'
+\end{verbatim}
+
+\subsection{MimeTypes Objects \label{mimetypes-objects}}
+
+\class{MimeTypes} instances provide an interface which is very like
+that of the \refmodule{mimetypes} module.
+
+\begin{datadesc}{suffix_map}
+  Dictionary mapping suffixes to suffixes.  This is used to allow
+  recognition of encoded files for which the encoding and the type are
+  indicated by the same extension.  For example, the \file{.tgz}
+  extension is mapped to \file{.tar.gz} to allow the encoding and type
+  to be recognized separately.  This is initially a copy of the global
+  \code{suffix_map} defined in the module.
+\end{datadesc}
+
+\begin{datadesc}{encodings_map}
+  Dictionary mapping filename extensions to encoding types.  This is
+  initially a copy of the global \code{encodings_map} defined in the
+  module.
+\end{datadesc}
+
+\begin{datadesc}{types_map}
+  Dictionary mapping filename extensions to MIME types.  This is
+  initially a copy of the global \code{types_map} defined in the
+  module.
+\end{datadesc}
+
+\begin{datadesc}{common_types}
+  Dictionary mapping filename extensions to non-standard, but commonly
+  found MIME types.  This is initially a copy of the global
+  \code{common_types} defined in the module.
+\end{datadesc}
+
+\begin{methoddesc}{guess_extension}{type\optional{, strict}}
+  Similar to the \function{guess_extension()} function, using the
+  tables stored as part of the object.
+\end{methoddesc}
+
+\begin{methoddesc}{guess_type}{url\optional{, strict}}
+  Similar to the \function{guess_type()} function, using the tables
+  stored as part of the object.
+\end{methoddesc}
+
+\begin{methoddesc}{read}{path}
+  Load MIME information from a file named \var{path}.  This uses
+  \method{readfp()} to parse the file.
+\end{methoddesc}
+
+\begin{methoddesc}{readfp}{file}
+  Load MIME type information from an open file.  The file must have
+  the format of the standard \file{mime.types} files.
+\end{methoddesc}

Added: vendor/Python/current/Doc/lib/libmimewriter.tex
===================================================================
--- vendor/Python/current/Doc/lib/libmimewriter.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libmimewriter.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,80 @@
+\section{\module{MimeWriter} ---
+         Generic MIME file writer}
+
+\declaremodule{standard}{MimeWriter}
+
+\modulesynopsis{Generic MIME file writer.}
+\sectionauthor{Christopher G. Petrilli}{petrilli at amber.org}
+
+\deprecated{2.3}{The \refmodule{email} package should be used in
+                 preference to the \module{MimeWriter} module.  This
+                 module is present only to maintain backward
+                 compatibility.}
+
+This module defines the class \class{MimeWriter}.  The
+\class{MimeWriter} class implements a basic formatter for creating
+MIME multi-part files.  It doesn't seek around the output file nor
+does it use large amounts of buffer space. You must write the parts
+out in the order that they should occur in the final
+file. \class{MimeWriter} does buffer the headers you add, allowing you 
+to rearrange their order.
+
+\begin{classdesc}{MimeWriter}{fp}
+Return a new instance of the \class{MimeWriter} class.  The only
+argument passed, \var{fp}, is a file object to be used for
+writing. Note that a \class{StringIO} object could also be used.
+\end{classdesc}
+
+
+\subsection{MimeWriter Objects \label{MimeWriter-objects}}
+
+
+\class{MimeWriter} instances have the following methods:
+
+\begin{methoddesc}{addheader}{key, value\optional{, prefix}}
+Add a header line to the MIME message. The \var{key} is the name of
+the header, where the \var{value} obviously provides the value of the
+header. The optional argument \var{prefix} determines where the header 
+is inserted; \samp{0} means append at the end, \samp{1} is insert at
+the start. The default is to append.
+\end{methoddesc}
+
+\begin{methoddesc}{flushheaders}{}
+Causes all headers accumulated so far to be written out (and
+forgotten). This is useful if you don't need a body part at all,
+e.g.\ for a subpart of type \mimetype{message/rfc822} that's (mis)used
+to store some header-like information.
+\end{methoddesc}
+
+\begin{methoddesc}{startbody}{ctype\optional{, plist\optional{, prefix}}}
+Returns a file-like object which can be used to write to the
+body of the message.  The content-type is set to the provided
+\var{ctype}, and the optional parameter \var{plist} provides
+additional parameters for the content-type declaration. \var{prefix}
+functions as in \method{addheader()} except that the default is to
+insert at the start.
+\end{methoddesc}
+
+\begin{methoddesc}{startmultipartbody}{subtype\optional{,
+                   boundary\optional{, plist\optional{, prefix}}}}
+Returns a file-like object which can be used to write to the
+body of the message.  Additionally, this method initializes the
+multi-part code, where \var{subtype} provides the multipart subtype,
+\var{boundary} may provide a user-defined boundary specification, and
+\var{plist} provides optional parameters for the subtype.
+\var{prefix} functions as in \method{startbody()}.  Subparts should be
+created using \method{nextpart()}.
+\end{methoddesc}
+
+\begin{methoddesc}{nextpart}{}
+Returns a new instance of \class{MimeWriter} which represents an
+individual part in a multipart message.  This may be used to write the 
+part as well as used for creating recursively complex multipart
+messages. The message must first be initialized with
+\method{startmultipartbody()} before using \method{nextpart()}.
+\end{methoddesc}
+
+\begin{methoddesc}{lastpart}{}
+This is used to designate the last part of a multipart message, and
+should \emph{always} be used when writing multipart messages.
+\end{methoddesc}

Added: vendor/Python/current/Doc/lib/libmimify.tex
===================================================================
--- vendor/Python/current/Doc/lib/libmimify.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libmimify.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,94 @@
+\section{\module{mimify} ---
+         MIME processing of mail messages}
+
+\declaremodule{standard}{mimify}
+\modulesynopsis{Mimification and unmimification of mail messages.}
+
+\deprecated{2.3}{The \refmodule{email} package should be used in
+                 preference to the \module{mimify} module.  This
+                 module is present only to maintain backward
+                 compatibility.}
+
+The \module{mimify} module defines two functions to convert mail messages to
+and from MIME format.  The mail message can be either a simple message
+or a so-called multipart message.  Each part is treated separately.
+Mimifying (a part of) a message entails encoding the message as
+quoted-printable if it contains any characters that cannot be
+represented using 7-bit \ASCII.  Unmimifying (a part of) a message
+entails undoing the quoted-printable encoding.  Mimify and unmimify
+are especially useful when a message has to be edited before being
+sent.  Typical use would be:
+
+\begin{verbatim}
+unmimify message
+edit message
+mimify message
+send message
+\end{verbatim}
+
+The modules defines the following user-callable functions and
+user-settable variables:
+
+\begin{funcdesc}{mimify}{infile, outfile}
+Copy the message in \var{infile} to \var{outfile}, converting parts to
+quoted-printable and adding MIME mail headers when necessary.
+\var{infile} and \var{outfile} can be file objects (actually, any
+object that has a \method{readline()} method (for \var{infile}) or a
+\method{write()} method (for \var{outfile})) or strings naming the files.
+If \var{infile} and \var{outfile} are both strings, they may have the
+same value.
+\end{funcdesc}
+
+\begin{funcdesc}{unmimify}{infile, outfile\optional{, decode_base64}}
+Copy the message in \var{infile} to \var{outfile}, decoding all
+quoted-printable parts.  \var{infile} and \var{outfile} can be file
+objects (actually, any object that has a \method{readline()} method (for
+\var{infile}) or a \method{write()} method (for \var{outfile})) or strings
+naming the files.  If \var{infile} and \var{outfile} are both strings,
+they may have the same value.
+If the \var{decode_base64} argument is provided and tests true, any
+parts that are coded in the base64 encoding are decoded as well.
+\end{funcdesc}
+
+\begin{funcdesc}{mime_decode_header}{line}
+Return a decoded version of the encoded header line in \var{line}.
+This only supports the ISO 8859-1 charset (Latin-1).
+\end{funcdesc}
+
+\begin{funcdesc}{mime_encode_header}{line}
+Return a MIME-encoded version of the header line in \var{line}.
+\end{funcdesc}
+
+\begin{datadesc}{MAXLEN}
+By default, a part will be encoded as quoted-printable when it
+contains any non-\ASCII{} characters (characters with the 8th bit
+set), or if there are any lines longer than \constant{MAXLEN} characters
+(default value 200).  
+\end{datadesc}
+
+\begin{datadesc}{CHARSET}
+When not specified in the mail headers, a character set must be filled
+in.  The string used is stored in \constant{CHARSET}, and the default
+value is ISO-8859-1 (also known as Latin1 (latin-one)).
+\end{datadesc}
+
+This module can also be used from the command line.  Usage is as
+follows:
+\begin{verbatim}
+mimify.py -e [-l length] [infile [outfile]]
+mimify.py -d [-b] [infile [outfile]]
+\end{verbatim}
+to encode (mimify) and decode (unmimify) respectively.  \var{infile}
+defaults to standard input, \var{outfile} defaults to standard output.
+The same file can be specified for input and output.
+
+If the \strong{-l} option is given when encoding, if there are any lines
+longer than the specified \var{length}, the containing part will be
+encoded.
+
+If the \strong{-b} option is given when decoding, any base64 parts will
+be decoded as well.
+
+\begin{seealso}
+  \seemodule{quopri}{Encode and decode MIME quoted-printable files.}
+\end{seealso}

Added: vendor/Python/current/Doc/lib/libmisc.tex
===================================================================
--- vendor/Python/current/Doc/lib/libmisc.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libmisc.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,7 @@
+\chapter{Miscellaneous Services}
+\label{misc}
+
+The modules described in this chapter provide miscellaneous services
+that are available in all Python versions.  Here's an overview:
+
+\localmoduletable

Added: vendor/Python/current/Doc/lib/libmm.tex
===================================================================
--- vendor/Python/current/Doc/lib/libmm.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libmm.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,8 @@
+\chapter{Multimedia Services}
+\label{mmedia}
+
+The modules described in this chapter implement various algorithms or
+interfaces that are mainly useful for multimedia applications.  They
+are available at the discretion of the installation.  Here's an overview:
+
+\localmoduletable

Added: vendor/Python/current/Doc/lib/libmmap.tex
===================================================================
--- vendor/Python/current/Doc/lib/libmmap.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libmmap.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,171 @@
+\section{\module{mmap} ---
+Memory-mapped file support}
+
+\declaremodule{builtin}{mmap}
+\modulesynopsis{Interface to memory-mapped files for \UNIX\ and Windows.}
+
+Memory-mapped file objects behave like both strings and like
+file objects.  Unlike normal string objects, however, these are
+mutable.  You can use mmap objects in most places where strings
+are expected; for example, you can use the \module{re} module to
+search through a memory-mapped file.  Since they're mutable, you can
+change a single character by doing \code{obj[\var{index}] = 'a'}, or
+change a substring by assigning to a slice:
+\code{obj[\var{i1}:\var{i2}] = '...'}.  You can also read and write
+data starting at the current file position, and \method{seek()}
+through the file to different positions.
+
+A memory-mapped file is created by the \function{mmap()} function,
+which is different on \UNIX{} and on Windows.  In either case you must
+provide a file descriptor for a file opened for update.
+If you wish to map an existing Python file object, use its
+\method{fileno()} method to obtain the correct value for the
+\var{fileno} parameter.  Otherwise, you can open the file using the
+\function{os.open()} function, which returns a file descriptor
+directly (the file still needs to be closed when done).
+
+For both the \UNIX{} and Windows versions of the function,
+\var{access} may be specified as an optional keyword parameter.
+\var{access} accepts one of three values: \constant{ACCESS_READ},
+\constant{ACCESS_WRITE}, or \constant{ACCESS_COPY} to specify
+readonly, write-through or copy-on-write memory respectively.
+\var{access} can be used on both \UNIX{} and Windows.  If
+\var{access} is not specified, Windows mmap returns a write-through
+mapping.  The initial memory values for all three access types are
+taken from the specified file.  Assignment to an
+\constant{ACCESS_READ} memory map raises a \exception{TypeError}
+exception.  Assignment to an \constant{ACCESS_WRITE} memory map
+affects both memory and the underlying file.  Assignment to an
+\constant{ACCESS_COPY} memory map affects memory but does not update
+the underlying file.  \versionchanged[To map anonymous memory,
+-1 should be passed as the fileno along with the length]{2.5}
+
+\begin{funcdesc}{mmap}{fileno, length\optional{, tagname\optional{, access}}}
+  \strong{(Windows version)} Maps \var{length} bytes from the file
+  specified by the file handle \var{fileno}, and returns a mmap
+  object.  If \var{length} is larger than the current size of the file,
+  the file is extended to contain \var{length} bytes.  If \var{length}
+  is \code{0}, the maximum length of the map is the current size
+  of the file, except that if the file is empty Windows raises an
+  exception (you cannot create an empty mapping on Windows).
+
+  \var{tagname}, if specified and not \code{None}, is a string giving
+  a tag name for the mapping.  Windows allows you to have many
+  different mappings against the same file.  If you specify the name
+  of an existing tag, that tag is opened, otherwise a new tag of this
+  name is created.  If this parameter is omitted or \code{None}, the
+  mapping is created without a name.  Avoiding the use of the tag
+  parameter will assist in keeping your code portable between \UNIX{}
+  and Windows.
+\end{funcdesc}
+
+\begin{funcdescni}{mmap}{fileno, length\optional{, flags\optional{,
+                         prot\optional{, access}}}}
+  \strong{(\UNIX{} version)} Maps \var{length} bytes from the file
+  specified by the file descriptor \var{fileno}, and returns a mmap
+  object.  If \var{length} is \code{0}, the maximum length of the map
+  will be the current size of the file when \function{mmap()} is
+  called.
+  
+  \var{flags} specifies the nature of the mapping.
+  \constant{MAP_PRIVATE} creates a private copy-on-write mapping, so
+  changes to the contents of the mmap object will be private to this
+  process, and \constant{MAP_SHARED} creates a mapping that's shared
+  with all other processes mapping the same areas of the file.  The
+  default value is \constant{MAP_SHARED}.
+
+  \var{prot}, if specified, gives the desired memory protection; the
+  two most useful values are \constant{PROT_READ} and
+  \constant{PROT_WRITE}, to specify that the pages may be read or
+  written.  \var{prot} defaults to \constant{PROT_READ | PROT_WRITE}.
+
+  \var{access} may be specified in lieu of \var{flags} and \var{prot}
+  as an optional keyword parameter.  It is an error to specify both
+  \var{flags}, \var{prot} and \var{access}.  See the description of
+  \var{access} above for information on how to use this parameter.
+\end{funcdescni}
+
+
+Memory-mapped file objects support the following methods:
+
+
+\begin{methoddesc}{close}{}
+  Close the file.  Subsequent calls to other methods of the object
+  will result in an exception being raised.
+\end{methoddesc}
+
+\begin{methoddesc}{find}{string\optional{, start}}
+  Returns the lowest index in the object where the substring
+  \var{string} is found.  Returns \code{-1} on failure.  \var{start}
+  is the index at which the search begins, and defaults to zero.
+\end{methoddesc}
+
+\begin{methoddesc}{flush}{\optional{offset, size}}
+  Flushes changes made to the in-memory copy of a file back to disk.
+  Without use of this call there is no guarantee that changes are
+  written back before the object is destroyed.  If \var{offset} and
+  \var{size} are specified, only changes to the given range of bytes
+  will be flushed to disk; otherwise, the whole extent of the mapping
+  is flushed.
+\end{methoddesc}
+
+\begin{methoddesc}{move}{\var{dest}, \var{src}, \var{count}}
+  Copy the \var{count} bytes starting at offset \var{src} to the
+  destination index \var{dest}.  If the mmap was created with
+  \constant{ACCESS_READ}, then calls to move will throw a
+  \exception{TypeError} exception.
+\end{methoddesc}
+
+\begin{methoddesc}{read}{\var{num}}
+  Return a string containing up to \var{num} bytes starting from the
+  current file position; the file position is updated to point after the
+  bytes that were returned.
+\end{methoddesc}
+
+\begin{methoddesc}{read_byte}{}
+  Returns a string of length 1 containing the character at the current
+  file position, and advances the file position by 1.
+\end{methoddesc}
+
+\begin{methoddesc}{readline}{}
+  Returns a single line, starting at the current file position and up to
+  the next newline.
+\end{methoddesc}
+
+\begin{methoddesc}{resize}{\var{newsize}}
+  Resizes the map and the underlying file, if any.
+  If the mmap was created with \constant{ACCESS_READ} or
+  \constant{ACCESS_COPY}, resizing the map will throw a \exception{TypeError} exception.
+\end{methoddesc}
+
+\begin{methoddesc}{seek}{pos\optional{, whence}}
+  Set the file's current position.  \var{whence} argument is optional
+  and defaults to \code{os.SEEK_SET} or \code{0} (absolute file
+  positioning); other values are \code{os.SEEK_CUR} or \code{1} (seek
+  relative to the current position) and \code{os.SEEK_END} or \code{2}
+  (seek relative to the file's end).
+\end{methoddesc}
+
+\begin{methoddesc}{size}{}
+  Return the length of the file, which can be larger than the size of
+  the memory-mapped area.
+\end{methoddesc}
+
+\begin{methoddesc}{tell}{}
+  Returns the current position of the file pointer.
+\end{methoddesc}
+
+\begin{methoddesc}{write}{\var{string}}
+  Write the bytes in \var{string} into memory at the current position
+  of the file pointer; the file position is updated to point after the
+  bytes that were written. If the mmap was created with
+  \constant{ACCESS_READ}, then writing to it will throw a
+  \exception{TypeError} exception.
+\end{methoddesc}
+
+\begin{methoddesc}{write_byte}{\var{byte}}
+  Write the single-character string \var{byte} into memory at the
+  current position of the file pointer; the file position is advanced
+  by \code{1}. If the mmap was created with \constant{ACCESS_READ},
+  then writing to it will throw a \exception{TypeError} exception.
+\end{methoddesc}

Added: vendor/Python/current/Doc/lib/libmodulefinder.tex
===================================================================
--- vendor/Python/current/Doc/lib/libmodulefinder.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libmodulefinder.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,51 @@
+\section{\module{modulefinder} ---
+         Find modules used by a script}
+\sectionauthor{A.M. Kuchling}{amk at amk.ca}
+
+\declaremodule{standard}{modulefinder}
+\modulesynopsis{Find modules used by a script.}
+
+\versionadded{2.3}
+
+This module provides a \class{ModuleFinder} class that can be used to
+determine the set of modules imported by a script.
+\code{modulefinder.py} can also be run as a script, giving the
+filename of a Python script as its argument, after which a report of
+the imported modules will be printed.
+
+\begin{funcdesc}{AddPackagePath}{pkg_name, path}
+Record that the package named \var{pkg_name} can be found in the specified \var{path}.
+\end{funcdesc}
+
+\begin{funcdesc}{ReplacePackage}{oldname, newname}
+Allows specifying that the module named \var{oldname} is in fact
+the package named \var{newname}.  The most common usage would be 
+to handle how the \module{_xmlplus} package replaces the \module{xml}
+package.
+\end{funcdesc}
+
+\begin{classdesc}{ModuleFinder}{\optional{path=None, debug=0, excludes=[], replace_paths=[]}}
+
+This class provides \method{run_script()} and \method{report()}
+methods to determine the set of modules imported by a script.
+\var{path} can be a list of directories to search for modules; if not
+specified, \code{sys.path} is used. 
+\var{debug} sets the debugging level; higher values make the class print 
+debugging messages about what it's doing.
+\var{excludes} is a list of module names to exclude from the analysis.
+\var{replace_paths} is a list of \code{(\var{oldpath}, \var{newpath})}
+tuples that will be replaced in module paths.
+\end{classdesc}
+
+\begin{methoddesc}[ModuleFinder]{report}{}
+Print a report to standard output that lists the modules imported by the script
+and their
+paths, as well as modules that are missing or seem to be missing.
+\end{methoddesc}
+
+\begin{methoddesc}[ModuleFinder]{run_script}{pathname}
+Analyze the contents of the \var{pathname} file, which must contain 
+Python code.
+\end{methoddesc}
+ 
+

Added: vendor/Python/current/Doc/lib/libmsilib.tex
===================================================================
--- vendor/Python/current/Doc/lib/libmsilib.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libmsilib.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,485 @@
+\section{\module{msilib} ---
+         Read and write Microsoft Installer files}
+
+\declaremodule{standard}{msilib}
+  \platform{Windows}
+\modulesynopsis{Creation of Microsoft Installer files, and CAB files.}
+\moduleauthor{Martin v. L\"owis}{martin at v.loewis.de}
+\sectionauthor{Martin v. L\"owis}{martin at v.loewis.de}
+
+\index{msi}
+
+\versionadded{2.5}
+
+The \module{msilib} supports the creation of Microsoft Installer
+(\code{.msi}) files.  Because these files often contain an embedded
+``cabinet'' file (\code{.cab}), it also exposes an API to create
+CAB files. Support for reading \code{.cab} files is currently not
+implemented; read support for the \code{.msi} database is possible.
+
+This package aims to provide complete access to all tables in an
+\code{.msi} file, therefore, it is a fairly low-level API. Two
+primary applications of this package are the \module{distutils}
+command \code{bdist_msi}, and the creation of Python installer
+package itself (although that currently uses a different version
+of \code{msilib}).
+
+The package contents can be roughly split into four parts:
+low-level CAB routines, low-level MSI routines, higher-level
+MSI routines, and standard table structures.
+
+\begin{funcdesc}{FCICreate}{cabname, files}
+  Create a new CAB file named \var{cabname}. \var{files} must
+  be a list of tuples, each containing the name of the file on
+  disk, and the name of the file inside the CAB file.
+
+  The files are added to the CAB file in the order they appear
+  in the list. All files are added into a single CAB file,
+  using the MSZIP compression algorithm.
+
+  Callbacks to Python for the various steps of MSI creation
+  are currently not exposed.
+\end{funcdesc}
+
+\begin{funcdesc}{UUIDCreate}{}
+  Return the string representation of a new unique identifier.
+  This wraps the Windows API functions \cfunction{UuidCreate} and
+  \cfunction{UuidToString}.
+\end{funcdesc}
+
+\begin{funcdesc}{OpenDatabase}{path, persist}
+  Return a new database object by calling MsiOpenDatabase.  
+  \var{path} is the file name of the
+  MSI file; \var{persist} can be one of the constants 
+  \code{MSIDBOPEN_CREATEDIRECT}, \code{MSIDBOPEN_CREATE},
+  \code{MSIDBOPEN_DIRECT}, \code{MSIDBOPEN_READONLY}, or
+  \code{MSIDBOPEN_TRANSACT}, and may include the flag
+  \code{MSIDBOPEN_PATCHFILE}. See the Microsoft documentation for
+  the meaning of these flags; depending on the flags,
+  an existing database is opened, or a new one created.
+\end{funcdesc}
+
+\begin{funcdesc}{CreateRecord}{count}
+  Return a new record object by calling \cfunction{MSICreateRecord}.
+  \var{count} is the number of fields of the record.
+\end{funcdesc}
+
+\begin{funcdesc}{init_database}{name, schema, ProductName, ProductCode, ProductVersion, Manufacturer}
+  Create and return a new database \var{name}, initialize it 
+  with \var{schema},  and set the properties \var{ProductName},
+  \var{ProductCode}, \var{ProductVersion}, and \var{Manufacturer}.
+
+  \var{schema} must be a module object containing \code{tables} and
+  \code{_Validation_records} attributes; typically,
+  \module{msilib.schema} should be used.
+
+  The database will contain just the schema and the validation
+  records when this function returns.
+\end{funcdesc}
+
+\begin{funcdesc}{add_data}{database, records}
+  Add all \var{records} to \var{database}.  \var{records} should
+  be a list of tuples, each one containing all fields of a record
+  according to the schema of the table.  For optional fields,
+  \code{None} can be passed.
+
+  Field values can be int or long numbers, strings, or instances
+  of the Binary class.
+\end{funcdesc}
+
+\begin{classdesc}{Binary}{filename}
+  Represents entries in the Binary table; inserting such
+  an object using \function{add_data} reads the file named
+  \var{filename} into the table.
+\end{classdesc}
+
+\begin{funcdesc}{add_tables}{database, module}
+  Add all table content from \var{module} to \var{database}.
+  \var{module} must contain an attribute \var{tables}
+  listing all tables for which content should be added,
+  and one attribute per table that has the actual content.
+
+  This is typically used to install the sequence tables.
+\end{funcdesc}
+
+\begin{funcdesc}{add_stream}{database, name, path}
+  Add the file \var{path} into the \code{_Stream} table
+  of \var{database}, with the stream name \var{name}.
+\end{funcdesc}
+
+\begin{funcdesc}{gen_uuid}{}
+  Return a new UUID, in the format that MSI typically
+  requires (i.e. in curly braces, and with all hexdigits
+  in upper-case).
+\end{funcdesc}
+
+\begin{seealso}
+  \seetitle[http://msdn.microsoft.com/library/default.asp?url=/library/en-us/devnotes/winprog/fcicreate.asp]{FCICreateFile}{}
+  \seetitle[http://msdn.microsoft.com/library/default.asp?url=/library/en-us/rpc/rpc/uuidcreate.asp]{UuidCreate}{}
+  \seetitle[http://msdn.microsoft.com/library/default.asp?url=/library/en-us/rpc/rpc/uuidtostring.asp]{UuidToString}{}
+\end{seealso}
+
+\subsection{Database Objects\label{database-objects}}
+
+\begin{methoddesc}{OpenView}{sql}
+  Return a view object, by calling \cfunction{MSIDatabaseOpenView}.
+  \var{sql} is the SQL statement to execute.
+\end{methoddesc}
+
+\begin{methoddesc}{Commit}{}
+  Commit the changes pending in the current transaction,
+  by calling \cfunction{MSIDatabaseCommit}.
+\end{methoddesc}
+
+\begin{methoddesc}{GetSummaryInformation}{count}
+  Return a new summary information object, by calling
+  \cfunction{MsiGetSummaryInformation}.  \var{count} is the maximum number of
+  updated values.
+\end{methoddesc}
+
+\begin{seealso}
+  \seetitle[http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msiopenview.asp]{MSIOpenView}{}
+  \seetitle[http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msidatabasecommit.asp]{MSIDatabaseCommit}{}
+  \seetitle[http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msigetsummaryinformation.asp]{MSIGetSummaryInformation}{}
+\end{seealso}
+
+\subsection{View Objects\label{view-objects}}
+
+\begin{methoddesc}{Execute}{\optional{params=None}}
+  Execute the SQL query of the view, through \cfunction{MSIViewExecute}.
+  \var{params} is an optional record describing actual values
+  of the parameter tokens in the query.
+\end{methoddesc}
+
+\begin{methoddesc}{GetColumnInfo}{kind}
+  Return a record describing the columns of the view, through
+  calling \cfunction{MsiViewGetColumnInfo}. \var{kind} can be either
+  \code{MSICOLINFO_NAMES} or \code{MSICOLINFO_TYPES}.
+\end{methoddesc}
+
+\begin{methoddesc}{Fetch}{}
+  Return a result record of the query, through calling
+  \cfunction{MsiViewFetch}.
+\end{methoddesc}
+
+\begin{methoddesc}{Modify}{kind, data}
+  Modify the view, by calling \cfunction{MsiViewModify}. \var{kind}
+  can be one of  \code{MSIMODIFY_SEEK}, \code{MSIMODIFY_REFRESH},
+  \code{MSIMODIFY_INSERT}, \code{MSIMODIFY_UPDATE}, \code{MSIMODIFY_ASSIGN},
+  \code{MSIMODIFY_REPLACE}, \code{MSIMODIFY_MERGE}, \code{MSIMODIFY_DELETE},
+  \code{MSIMODIFY_INSERT_TEMPORARY}, \code{MSIMODIFY_VALIDATE},
+  \code{MSIMODIFY_VALIDATE_NEW}, \code{MSIMODIFY_VALIDATE_FIELD}, or
+  \code{MSIMODIFY_VALIDATE_DELETE}.
+
+  \var{data} must be a record describing the new data.
+\end{methoddesc}
+
+\begin{methoddesc}{Close}{}
+  Close the view, through \cfunction{MsiViewClose}.
+\end{methoddesc}
+
+\begin{seealso}
+  \seetitle[http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msiviewexecute.asp]{MsiViewExecute}{}
+  \seetitle[http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msiviewgetcolumninfo.asp]{MSIViewGetColumnInfo}{}
+  \seetitle[http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msiviewfetch.asp]{MsiViewFetch}{}
+  \seetitle[http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msiviewmodify.asp]{MsiViewModify}{}
+  \seetitle[http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msiviewclose.asp]{MsiViewClose}{}
+\end{seealso}
+
+\subsection{Summary Information Objects\label{summary-objects}}
+
+\begin{methoddesc}{GetProperty}{field}
+  Return a property of the summary, through \cfunction{MsiSummaryInfoGetProperty}.
+  \var{field} is the name of the property, and can be one of the
+  constants
+  \code{PID_CODEPAGE}, \code{PID_TITLE}, \code{PID_SUBJECT},
+  \code{PID_AUTHOR}, \code{PID_KEYWORDS}, \code{PID_COMMENTS},
+  \code{PID_TEMPLATE}, \code{PID_LASTAUTHOR}, \code{PID_REVNUMBER},
+  \code{PID_LASTPRINTED}, \code{PID_CREATE_DTM}, \code{PID_LASTSAVE_DTM},
+  \code{PID_PAGECOUNT}, \code{PID_WORDCOUNT}, \code{PID_CHARCOUNT},
+  \code{PID_APPNAME}, or \code{PID_SECURITY}.
+\end{methoddesc}
+
+\begin{methoddesc}{GetPropertyCount}{}
+  Return the number of summary properties, through
+  \cfunction{MsiSummaryInfoGetPropertyCount}.
+\end{methoddesc}
+
+\begin{methoddesc}{SetProperty}{field, value}
+  Set a property through \cfunction{MsiSummaryInfoSetProperty}. \var{field}
+  can have the same values as in \method{GetProperty}, \var{value}
+  is the new value of the property. Possible value types are integer
+  and string.
+\end{methoddesc}
+
+\begin{methoddesc}{Persist}{}
+  Write the modified properties to the summary information stream,
+  using \cfunction{MsiSummaryInfoPersist}.
+\end{methoddesc}
+
+\begin{seealso}
+  \seetitle[http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msisummaryinfogetproperty.asp]{MsiSummaryInfoGetProperty}{}
+  \seetitle[http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msisummaryinfogetpropertycount.asp]{MsiSummaryInfoGetPropertyCount}{}
+  \seetitle[http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msisummaryinfosetproperty.asp]{MsiSummaryInfoSetProperty}{}
+  \seetitle[http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msisummaryinfopersist.asp]{MsiSummaryInfoPersist}{}
+\end{seealso}
+
+\subsection{Record Objects\label{record-objects}}
+
+\begin{methoddesc}{GetFieldCount}{}
+  Return the number of fields of the record, through \cfunction{MsiRecordGetFieldCount}.
+\end{methoddesc}
+
+\begin{methoddesc}{SetString}{field, value}
+  Set \var{field} to \var{value} through \cfunction{MsiRecordSetString}.
+  \var{field} must be an integer; \var{value} a string.
+\end{methoddesc}
+
+\begin{methoddesc}{SetStream}{field, value}
+  Set \var{field} to the contents of the file named \var{value},
+  through \cfunction{MsiRecordSetStream}.
+  \var{field} must be an integer; \var{value} a string.
+\end{methoddesc}
+
+\begin{methoddesc}{SetInteger}{field, value}
+  Set \var{field} to \var{value} through \cfunction{MsiRecordSetInteger}.
+  Both \var{field} and \var{value} must be an integer.
+\end{methoddesc}
+
+\begin{methoddesc}{ClearData}{}
+  Set all fields of the record to 0, through \cfunction{MsiRecordClearData}.
+\end{methoddesc}
+
+\begin{seealso}
+  \seetitle[http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msirecordgetfieldcount.asp]{MsiRecordGetFieldCount}{}
+  \seetitle[http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msirecordsetstring.asp]{MsiRecordSetString}{}
+  \seetitle[http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msirecordsetstream.asp]{MsiRecordSetStream}{}
+  \seetitle[http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msirecordsetinteger.asp]{MsiRecordSetInteger}{}
+  \seetitle[http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msirecordclear.asp]{MsiRecordClear}{}
+\end{seealso}
+
+\subsection{Errors\label{msi-errors}}
+
+All wrappers around MSI functions raise \exception{MsiError};
+the string inside the exception will contain more detail.
+
+\subsection{CAB Objects\label{cab}}
+
+\begin{classdesc}{CAB}{name}
+  The class \class{CAB} represents a CAB file. During MSI construction,
+  files will be added simultaneously to the \code{Files} table, and
+  to a CAB file. Then, when all files have been added, the CAB file
+  can be written, then added to the MSI file.
+
+  \var{name} is the name of the CAB file in the MSI file.
+\end{classdesc}
+
+\begin{methoddesc}[CAB]{append}{full, logical}
+  Add the file with the pathname \var{full} to the CAB file,
+  under the name \var{logical}. If there is already a file
+  named \var{logical}, a new file name is created.
+
+  Return the index of the file in the CAB file, and the
+  new name of the file inside the CAB file.
+\end{methoddesc}
+
+\begin{methoddesc}[CAB]{append}{database}
+  Generate a CAB file, add it as a stream to the MSI file,
+  put it into the \code{Media} table, and remove the generated
+  file from the disk.
+\end{methoddesc}
+
+\subsection{Directory Objects\label{msi-directory}}
+
+\begin{classdesc}{Directory}{database, cab, basedir, physical, 
+                  logical, default, component, \optional{componentflags}}
+  Create a new directory in the Directory table. There is a current
+  component at each point in time for the directory, which is either
+  explicitly created through \method{start_component}, or implicitly when files
+  are added for the first time. Files are added into the current
+  component, and into the cab file.  To create a directory, a base
+  directory object needs to be specified (can be \code{None}), the path to
+  the physical directory, and a logical directory name.  \var{default}
+  specifies the DefaultDir slot in the directory table. \var{componentflags}
+  specifies the default flags that new components get.
+\end{classdesc}
+
+\begin{methoddesc}[Directory]{start_component}{\optional{component\optional{,
+      feature\optional{, flags\optional{, keyfile\optional{, uuid}}}}}}
+  Add an entry to the Component table, and make this component the
+  current component for this directory. If no component name is given, the
+  directory name is used. If no \var{feature} is given, the current feature
+  is used. If no \var{flags} are given, the directory's default flags are
+  used. If no \var{keyfile} is given, the KeyPath is left null in the
+  Component table.
+\end{methoddesc}
+
+\begin{methoddesc}[Directory]{add_file}{file\optional{, src\optional{,
+      version\optional{, language}}}}
+  Add a file to the current component of the directory, starting a new
+  one if there is no current component. By default, the file name
+  in the source and the file table will be identical. If the \var{src} file
+  is specified, it is interpreted relative to the current
+  directory. Optionally, a \var{version} and a \var{language} can be specified for
+  the entry in the File table.
+\end{methoddesc}
+
+\begin{methoddesc}[Directory]{glob}{pattern\optional{, exclude}}
+  Add a list of files to the current component as specified in the glob
+  pattern. Individual files can be excluded in the \var{exclude} list.
+\end{methoddesc}
+
+\begin{methoddesc}[Directory]{remove_pyc}{}
+  Remove \code{.pyc}/\code{.pyo} files on uninstall.
+\end{methoddesc}
+
+\begin{seealso}
+  \seetitle[http://msdn.microsoft.com/library/en-us/msi/setup/directory_table.asp]{Directory Table}{}
+  \seetitle[http://msdn.microsoft.com/library/en-us/msi/setup/file_table.asp]{File Table}{}
+  \seetitle[http://msdn.microsoft.com/library/en-us/msi/setup/component_table.asp]{Component Table}{}
+  \seetitle[http://msdn.microsoft.com/library/en-us/msi/setup/featurecomponents_table.asp]{FeatureComponents Table}{}
+\end{seealso}
+
+
+\subsection{Features\label{features}}
+
+\begin{classdesc}{Feature}{database, id, title, desc, display\optional{,
+    level=1\optional{, parent\optional{, directory\optional{, 
+    attributes=0}}}}}
+
+  Add a new record to the \code{Feature} table, using the values
+  \var{id}, \var{parent.id}, \var{title}, \var{desc}, \var{display},
+  \var{level}, \var{directory}, and \var{attributes}. The resulting
+  feature object can be passed to the \method{start_component} method
+  of \class{Directory}.
+\end{classdesc}
+
+\begin{methoddesc}[Feature]{set_current}{}
+  Make this feature the current feature of \module{msilib}.
+  New components are automatically added to the default feature,
+  unless a feature is explicitly specified.
+\end{methoddesc}
+
+\begin{seealso}
+  \seetitle[http://msdn.microsoft.com/library/en-us/msi/setup/feature_table.asp]{Feature Table}{}
+\end{seealso}
+
+\subsection{GUI classes\label{msi-gui}}
+
+\module{msilib} provides several classes that wrap the GUI tables in
+an MSI database. However, no standard user interface is provided; use
+\module{bdist_msi} to create MSI files with a user-interface for
+installing Python packages.
+
+\begin{classdesc}{Control}{dlg, name}
+  Base class of the dialog controls. \var{dlg} is the dialog object
+  the control belongs to, and \var{name} is the control's name.
+\end{classdesc}
+
+\begin{methoddesc}[Control]{event}{event, argument\optional{, 
+   condition = ``1''\optional{, ordering}}}
+
+  Make an entry into the \code{ControlEvent} table for this control.
+\end{methoddesc}
+
+\begin{methoddesc}[Control]{mapping}{event, attribute}
+  Make an entry into the \code{EventMapping} table for this control.
+\end{methoddesc}
+
+\begin{methoddesc}[Control]{condition}{action, condition}
+  Make an entry into the \code{ControlCondition} table for this control.
+\end{methoddesc}
+
+
+\begin{classdesc}{RadioButtonGroup}{dlg, name, property}
+  Create a radio button control named \var{name}. \var{property}
+  is the installer property that gets set when a radio button
+  is selected.
+\end{classdesc}
+
+\begin{methoddesc}[RadioButtonGroup]{add}{name, x, y, width, height, text
+                                          \optional{, value}}
+  Add a radio button named \var{name} to the group, at the
+  coordinates \var{x}, \var{y}, \var{width}, \var{height}, and
+  with the label \var{text}. If \var{value} is omitted, it
+  defaults to \var{name}.
+\end{methoddesc}
+           
+\begin{classdesc}{Dialog}{db, name, x, y, w, h, attr, title, first, 
+    default, cancel}
+  Return a new \class{Dialog} object. An entry in the \code{Dialog} table
+  is made, with the specified coordinates, dialog attributes, title,
+  name of the first, default, and cancel controls.
+\end{classdesc}
+
+\begin{methoddesc}[Dialog]{control}{name, type, x, y, width, height, 
+                  attributes, property, text, control_next, help}
+  Return a new \class{Control} object. An entry in the \code{Control} table
+  is made with the specified parameters.
+
+  This is a generic method; for specific types, specialized methods
+  are provided.
+\end{methoddesc}
+
+
+\begin{methoddesc}[Dialog]{text}{name, x, y, width, height, attributes, text}
+  Add and return a \code{Text} control.
+\end{methoddesc}
+
+\begin{methoddesc}[Dialog]{bitmap}{name, x, y, width, height, text}
+  Add and return a \code{Bitmap} control.
+\end{methoddesc}
+
+\begin{methoddesc}[Dialog]{line}{name, x, y, width, height}
+  Add and return a \code{Line} control.
+\end{methoddesc}
+
+\begin{methoddesc}[Dialog]{pushbutton}{name, x, y, width, height, attributes, 
+                                 text, next_control}
+  Add and return a \code{PushButton} control.
+\end{methoddesc}
+
+\begin{methoddesc}[Dialog]{radiogroup}{name, x, y, width, height, 
+                                 attributes, property, text, next_control}
+  Add and return a \code{RadioButtonGroup} control.
+\end{methoddesc}
+
+\begin{methoddesc}[Dialog]{checkbox}{name, x, y, width, height, 
+                                 attributes, property, text, next_control}
+  Add and return a \code{CheckBox} control.
+\end{methoddesc}
+
+\begin{seealso}
+  \seetitle[http://msdn.microsoft.com/library/en-us/msi/setup/dialog_table.asp]{Dialog Table}{}
+  \seetitle[http://msdn.microsoft.com/library/en-us/msi/setup/control_table.asp]{Control Table}{}
+  \seetitle[http://msdn.microsoft.com/library/en-us/msi/setup/controls.asp]{Control Types}{}
+  \seetitle[http://msdn.microsoft.com/library/en-us/msi/setup/controlcondition_table.asp]{ControlCondition Table}{}
+  \seetitle[http://msdn.microsoft.com/library/en-us/msi/setup/controlevent_table.asp]{ControlEvent Table}{}
+  \seetitle[http://msdn.microsoft.com/library/en-us/msi/setup/eventmapping_table.asp]{EventMapping Table}{}
+  \seetitle[http://msdn.microsoft.com/library/en-us/msi/setup/radiobutton_table.asp]{RadioButton Table}{}
+\end{seealso}
+
+\subsection{Precomputed tables\label{msi-tables}}
+
+\module{msilib} provides a few subpackages that contain
+only schema and table definitions. Currently, these definitions
+are based on MSI version 2.0.
+
+\begin{datadesc}{schema}
+  This is the standard MSI schema for MSI 2.0, with the
+  \var{tables} variable providing a list of table definitions,
+  and \var{_Validation_records} providing the data for
+  MSI validation.
+\end{datadesc}
+
+\begin{datadesc}{sequence}
+  This module contains table contents for the standard sequence
+  tables: \var{AdminExecuteSequence}, \var{AdminUISequence},
+  \var{AdvtExecuteSequence}, \var{InstallExecuteSequence}, and
+  \var{InstallUISequence}.
+\end{datadesc}
+
+\begin{datadesc}{text}
+  This module contains definitions for the UIText and ActionText
+  tables, for the standard installer actions.
+\end{datadesc}

Added: vendor/Python/current/Doc/lib/libmsvcrt.tex
===================================================================
--- vendor/Python/current/Doc/lib/libmsvcrt.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libmsvcrt.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,109 @@
+\section{\module{msvcrt} --
+         Useful routines from the MS V\Cpp\ runtime}
+
+\declaremodule{builtin}{msvcrt}
+  \platform{Windows}
+\modulesynopsis{Miscellaneous useful routines from the MS V\Cpp\ runtime.}
+\sectionauthor{Fred L. Drake, Jr.}{fdrake at acm.org}
+
+
+These functions provide access to some useful capabilities on Windows
+platforms.  Some higher-level modules use these functions to build the 
+Windows implementations of their services.  For example, the
+\refmodule{getpass} module uses this in the implementation of the
+\function{getpass()} function.
+
+Further documentation on these functions can be found in the Platform
+API documentation.
+
+
+\subsection{File Operations \label{msvcrt-files}}
+
+\begin{funcdesc}{locking}{fd, mode, nbytes}
+  Lock part of a file based on file descriptor \var{fd} from the C
+  runtime.  Raises \exception{IOError} on failure.  The locked region
+  of the file extends from the current file position for \var{nbytes}
+  bytes, and may continue beyond the end of the file.  \var{mode} must
+  be one of the \constant{LK_\var{*}} constants listed below.
+  Multiple regions in a file may be locked at the same time, but may
+  not overlap.  Adjacent regions are not merged; they must be unlocked
+  individually.
+\end{funcdesc}
+
+\begin{datadesc}{LK_LOCK}
+\dataline{LK_RLCK}
+  Locks the specified bytes. If the bytes cannot be locked, the
+  program immediately tries again after 1 second.  If, after 10
+  attempts, the bytes cannot be locked, \exception{IOError} is
+  raised.
+\end{datadesc}
+
+\begin{datadesc}{LK_NBLCK}
+\dataline{LK_NBRLCK}
+  Locks the specified bytes. If the bytes cannot be locked,
+  \exception{IOError} is raised.
+\end{datadesc}
+
+\begin{datadesc}{LK_UNLCK}
+  Unlocks the specified bytes, which must have been previously locked. 
+\end{datadesc}
+
+\begin{funcdesc}{setmode}{fd, flags}
+  Set the line-end translation mode for the file descriptor \var{fd}.
+  To set it to text mode, \var{flags} should be \constant{os.O_TEXT};
+  for binary, it should be \constant{os.O_BINARY}.
+\end{funcdesc}
+
+\begin{funcdesc}{open_osfhandle}{handle, flags}
+  Create a C runtime file descriptor from the file handle
+  \var{handle}.  The \var{flags} parameter should be a bit-wise OR of
+  \constant{os.O_APPEND}, \constant{os.O_RDONLY}, and
+  \constant{os.O_TEXT}.  The returned file descriptor may be used as a
+  parameter to \function{os.fdopen()} to create a file object.
+\end{funcdesc}
+
+\begin{funcdesc}{get_osfhandle}{fd}
+  Return the file handle for the file descriptor \var{fd}.  Raises
+  \exception{IOError} if \var{fd} is not recognized.
+\end{funcdesc}
+
+
+\subsection{Console I/O \label{msvcrt-console}}
+
+\begin{funcdesc}{kbhit}{}
+  Return true if a keypress is waiting to be read.
+\end{funcdesc}
+
+\begin{funcdesc}{getch}{}
+  Read a keypress and return the resulting character.  Nothing is
+  echoed to the console.  This call will block if a keypress is not
+  already available, but will not wait for \kbd{Enter} to be pressed.
+  If the pressed key was a special function key, this will return
+  \code{'\e000'} or \code{'\e xe0'}; the next call will return the
+  keycode.  The \kbd{Control-C} keypress cannot be read with this
+  function.
+\end{funcdesc}
+
+\begin{funcdesc}{getche}{}
+  Similar to \function{getch()}, but the keypress will be echoed if it 
+  represents a printable character.
+\end{funcdesc}
+
+\begin{funcdesc}{putch}{char}
+  Print the character \var{char} to the console without buffering.
+\end{funcdesc}
+
+\begin{funcdesc}{ungetch}{char}
+  Cause the character \var{char} to be ``pushed back'' into the
+  console buffer; it will be the next character read by
+  \function{getch()} or \function{getche()}.
+\end{funcdesc}
+
+
+\subsection{Other Functions \label{msvcrt-other}}
+
+\begin{funcdesc}{heapmin}{}
+  Force the \cfunction{malloc()} heap to clean itself up and return
+  unused blocks to the operating system.  This only works on Windows
+  NT.  On failure, this raises \exception{IOError}.
+\end{funcdesc}

Added: vendor/Python/current/Doc/lib/libmultifile.tex
===================================================================
--- vendor/Python/current/Doc/lib/libmultifile.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libmultifile.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,175 @@
+\section{\module{multifile} ---
+         Support for files containing distinct parts}
+
+\declaremodule{standard}{multifile}
+\modulesynopsis{Support for reading files which contain distinct
+                parts, such as some MIME data.}
+\sectionauthor{Eric S. Raymond}{esr at snark.thyrsus.com}
+
+\deprecated{2.5}{The \refmodule{email} package should be used in
+                 preference to the \module{multifile} module.
+                 This module is present only to maintain backward
+                 compatibility.}
+
+The \class{MultiFile} object enables you to treat sections of a text
+file as file-like input objects, with \code{''} being returned by
+\method{readline()} when a given delimiter pattern is encountered.  The
+defaults of this class are designed to make it useful for parsing
+MIME multipart messages, but by subclassing it and overriding methods 
+it can be easily adapted for more general use.
+
+\begin{classdesc}{MultiFile}{fp\optional{, seekable}}
+Create a multi-file.  You must instantiate this class with an input
+object argument for the \class{MultiFile} instance to get lines from,
+such as a file object returned by \function{open()}.
+
+\class{MultiFile} only ever looks at the input object's
+\method{readline()}, \method{seek()} and \method{tell()} methods, and
+the latter two are only needed if you want random access to the
+individual MIME parts. To use \class{MultiFile} on a non-seekable
+stream object, set the optional \var{seekable} argument to false; this
+will prevent using the input object's \method{seek()} and
+\method{tell()} methods.
+\end{classdesc}
+
+It will be useful to know that in \class{MultiFile}'s view of the world, text
+is composed of three kinds of lines: data, section-dividers, and
+end-markers.  MultiFile is designed to support parsing of
+messages that may have multiple nested message parts, each with its
+own pattern for section-divider and end-marker lines.
+
+\begin{seealso}
+  \seemodule{email}{Comprehensive email handling package; supersedes
+                    the \module{multifile} module.}
+\end{seealso}
+
+
+\subsection{MultiFile Objects \label{MultiFile-objects}}
+
+A \class{MultiFile} instance has the following methods:
+
+\begin{methoddesc}{readline}{str}
+Read a line.  If the line is data (not a section-divider or end-marker
+or real EOF) return it.  If the line matches the most-recently-stacked
+boundary, return \code{''} and set \code{self.last} to 1 or 0 according as
+the match is or is not an end-marker.  If the line matches any other
+stacked boundary, raise an error.  On encountering end-of-file on the
+underlying stream object, the method raises \exception{Error} unless
+all boundaries have been popped.
+\end{methoddesc}
+
+\begin{methoddesc}{readlines}{str}
+Return all lines remaining in this part as a list of strings.
+\end{methoddesc}
+
+\begin{methoddesc}{read}{}
+Read all lines, up to the next section.  Return them as a single
+(multiline) string.  Note that this doesn't take a size argument!
+\end{methoddesc}
+
+\begin{methoddesc}{seek}{pos\optional{, whence}}
+Seek.  Seek indices are relative to the start of the current section.
+The \var{pos} and \var{whence} arguments are interpreted as for a file
+seek.
+\end{methoddesc}
+
+\begin{methoddesc}{tell}{}
+Return the file position relative to the start of the current section.
+\end{methoddesc}
+
+\begin{methoddesc}{next}{}
+Skip lines to the next section (that is, read lines until a
+section-divider or end-marker has been consumed).  Return true if
+there is such a section, false if an end-marker is seen.  Re-enable
+the most-recently-pushed boundary.
+\end{methoddesc}
+
+\begin{methoddesc}{is_data}{str}
+Return true if \var{str} is data and false if it might be a section
+boundary.  As written, it tests for a prefix other than \code{'-}\code{-'} at
+start of line (which all MIME boundaries have) but it is declared so
+it can be overridden in derived classes.
+
+Note that this test is used intended as a fast guard for the real
+boundary tests; if it always returns false it will merely slow
+processing, not cause it to fail.
+\end{methoddesc}
+
+\begin{methoddesc}{push}{str}
+Push a boundary string.  When a decorated version of this boundary 
+is found as an input line, it will be interpreted as a section-divider 
+or end-marker (depending on the decoration, see \rfc{2045}).  All subsequent
+reads will return the empty string to indicate end-of-file, until a
+call to \method{pop()} removes the boundary a or \method{next()} call
+reenables it.
+
+It is possible to push more than one boundary.  Encountering the
+most-recently-pushed boundary will return EOF; encountering any other
+boundary will raise an error.
+\end{methoddesc}
+
+\begin{methoddesc}{pop}{}
+Pop a section boundary.  This boundary will no longer be interpreted
+as EOF.
+\end{methoddesc}
+
+\begin{methoddesc}{section_divider}{str}
+Turn a boundary into a section-divider line.  By default, this
+method prepends \code{'-}\code{-'} (which MIME section boundaries have) but
+it is declared so it can be overridden in derived classes.  This
+method need not append LF or CR-LF, as comparison with the result
+ignores trailing whitespace. 
+\end{methoddesc}
+
+\begin{methoddesc}{end_marker}{str}
+Turn a boundary string into an end-marker line.  By default, this
+method prepends \code{'-}\code{-'} and appends \code{'-}\code{-'} (like a
+MIME-multipart end-of-message marker) but it is declared so it can be
+overridden in derived classes.  This method need not append LF or
+CR-LF, as comparison with the result ignores trailing whitespace.
+\end{methoddesc}
+
+Finally, \class{MultiFile} instances have two public instance variables:
+
+\begin{memberdesc}{level}
+Nesting depth of the current part.
+\end{memberdesc}
+
+\begin{memberdesc}{last}
+True if the last end-of-file was for an end-of-message marker. 
+\end{memberdesc}
+
+
+\subsection{\class{MultiFile} Example \label{multifile-example}}
+\sectionauthor{Skip Montanaro}{skip at mojam.com}
+
+\begin{verbatim}
+import mimetools
+import multifile
+import StringIO
+
+def extract_mime_part_matching(stream, mimetype):
+    """Return the first element in a multipart MIME message on stream
+    matching mimetype."""
+
+    msg = mimetools.Message(stream)
+    msgtype = msg.gettype()
+    params = msg.getplist()
+
+    data = StringIO.StringIO()
+    if msgtype[:10] == "multipart/":
+
+        file = multifile.MultiFile(stream)
+        file.push(msg.getparam("boundary"))
+        while file.next():
+            submsg = mimetools.Message(file)
+            try:
+                data = StringIO.StringIO()
+                mimetools.decode(file, data, submsg.getencoding())
+            except ValueError:
+                continue
+            if submsg.gettype() == mimetype:
+                break
+        file.pop()
+    return data.getvalue()
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/libmutex.tex
===================================================================
--- vendor/Python/current/Doc/lib/libmutex.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libmutex.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,57 @@
+\section{\module{mutex} ---
+         Mutual exclusion support}
+
+\declaremodule{standard}{mutex}
+\sectionauthor{Moshe Zadka}{moshez at zadka.site.co.il}
+\modulesynopsis{Lock and queue for mutual exclusion.}
+
+The \module{mutex} module defines a class that allows mutual-exclusion
+via acquiring and releasing locks. It does not require (or imply)
+threading or multi-tasking, though it could be useful for
+those purposes.
+
+The \module{mutex} module defines the following class:
+
+\begin{classdesc}{mutex}{}
+Create a new (unlocked) mutex.
+
+A mutex has two pieces of state --- a ``locked'' bit and a queue.
+When the mutex is not locked, the queue is empty.
+Otherwise, the queue contains zero or more 
+\code{(\var{function}, \var{argument})} pairs
+representing functions (or methods) waiting to acquire the lock.
+When the mutex is unlocked while the queue is not empty,
+the first queue entry is removed and its 
+\code{\var{function}(\var{argument})} pair called,
+implying it now has the lock.
+
+Of course, no multi-threading is implied -- hence the funny interface
+for \method{lock()}, where a function is called once the lock is
+acquired.
+\end{classdesc}
+
+
+\subsection{Mutex Objects \label{mutex-objects}}
+
+\class{mutex} objects have following methods:
+
+\begin{methoddesc}{test}{}
+Check whether the mutex is locked.
+\end{methoddesc}
+
+\begin{methoddesc}{testandset}{}
+``Atomic'' test-and-set, grab the lock if it is not set,
+and return \code{True}, otherwise, return \code{False}.
+\end{methoddesc}
+
+\begin{methoddesc}{lock}{function, argument}
+Execute \code{\var{function}(\var{argument})}, unless the mutex is locked.
+In the case it is locked, place the function and argument on the queue.
+See \method{unlock} for explanation of when
+\code{\var{function}(\var{argument})} is executed in that case.
+\end{methoddesc}
+
+\begin{methoddesc}{unlock}{}
+Unlock the mutex if queue is empty, otherwise execute the first element
+in the queue.
+\end{methoddesc}

Added: vendor/Python/current/Doc/lib/libnetrc.tex
===================================================================
--- vendor/Python/current/Doc/lib/libnetrc.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libnetrc.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,68 @@
+\section{\module{netrc} ---
+         netrc file processing}
+
+\declaremodule{standard}{netrc}
+% Note the \protect needed for \file... ;-(
+\modulesynopsis{Loading of \protect\file{.netrc} files.}
+\moduleauthor{Eric S. Raymond}{esr at snark.thyrsus.com}
+\sectionauthor{Eric S. Raymond}{esr at snark.thyrsus.com}
+
+
+\versionadded{1.5.2}
+
+The \class{netrc} class parses and encapsulates the netrc file format
+used by the \UNIX{} \program{ftp} program and other FTP clients.
+
+\begin{classdesc}{netrc}{\optional{file}}
+A \class{netrc} instance or subclass instance encapsulates data from 
+a netrc file.  The initialization argument, if present, specifies the
+file to parse.  If no argument is given, the file \file{.netrc} in the
+user's home directory will be read.  Parse errors will raise
+\exception{NetrcParseError} with diagnostic information including the
+file name, line number, and terminating token.
+\end{classdesc}
+
+\begin{excdesc}{NetrcParseError}
+Exception raised by the \class{netrc} class when syntactical errors
+are encountered in source text.  Instances of this exception provide
+three interesting attributes:  \member{msg} is a textual explanation
+of the error, \member{filename} is the name of the source file, and
+\member{lineno} gives the line number on which the error was found.
+\end{excdesc}
+
+
+\subsection{netrc Objects \label{netrc-objects}}
+
+A \class{netrc} instance has the following methods:
+
+\begin{methoddesc}{authenticators}{host}
+Return a 3-tuple \code{(\var{login}, \var{account}, \var{password})}
+of authenticators for \var{host}.  If the netrc file did not
+contain an entry for the given host, return the tuple associated with
+the `default' entry.  If neither matching host nor default entry is
+available, return \code{None}.
+\end{methoddesc}
+
+\begin{methoddesc}{__repr__}{}
+Dump the class data as a string in the format of a netrc file.
+(This discards comments and may reorder the entries.)
+\end{methoddesc}
+
+Instances of \class{netrc} have public instance variables:
+
+\begin{memberdesc}{hosts}
+Dictionary mapping host names to \code{(\var{login}, \var{account},
+\var{password})} tuples.  The `default' entry, if any, is represented
+as a pseudo-host by that name.
+\end{memberdesc}
+
+\begin{memberdesc}{macros}
+Dictionary mapping macro names to string lists.
+\end{memberdesc}
+
+\note{Passwords are limited to a subset of the ASCII character set.
+Versions of this module prior to 2.3 were extremely limited.  Starting with
+2.3, all ASCII punctuation is allowed in passwords.  However, note that
+whitespace and non-printable characters are not allowed in passwords.  This
+is a limitation of the way the .netrc file is parsed and may be removed in
+the future.}

Added: vendor/Python/current/Doc/lib/libnew.tex
===================================================================
--- vendor/Python/current/Doc/lib/libnew.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libnew.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,63 @@
+\section{\module{new} ---
+         Creation of runtime internal objects}
+
+\declaremodule{builtin}{new}
+\sectionauthor{Moshe Zadka}{moshez at zadka.site.co.il}
+\modulesynopsis{Interface to the creation of runtime implementation objects.}
+
+
+The \module{new} module allows an interface to the interpreter object
+creation functions. This is for use primarily in marshal-type functions,
+when a new object needs to be created ``magically'' and not by using the
+regular creation functions. This module provides a low-level interface
+to the interpreter, so care must be exercised when using this module.
+It is possible to supply non-sensical arguments which crash the
+interpreter when the object is used.
+
+The \module{new} module defines the following functions:
+
+\begin{funcdesc}{instance}{class\optional{, dict}}
+This function creates an instance of \var{class} with dictionary
+\var{dict} without calling the \method{__init__()} constructor.  If
+\var{dict} is omitted or \code{None}, a new, empty dictionary is
+created for the new instance.  Note that there are no guarantees that
+the object will be in a consistent state.
+\end{funcdesc}
+
+\begin{funcdesc}{instancemethod}{function, instance, class}
+This function will return a method object, bound to \var{instance}, or
+unbound if \var{instance} is \code{None}.  \var{function} must be
+callable.
+\end{funcdesc}
+
+\begin{funcdesc}{function}{code, globals\optional{, name\optional{,
+                           argdefs\optional{, closure}}}}
+Returns a (Python) function with the given code and globals. If
+\var{name} is given, it must be a string or \code{None}.  If it is a
+string, the function will have the given name, otherwise the function
+name will be taken from \code{\var{code}.co_name}.  If
+\var{argdefs} is given, it must be a tuple and will be used to
+determine the default values of parameters.  If \var{closure} is given,
+it must be \code{None} or a tuple of cell objects containing objects
+to bind to the names in \code{\var{code}.co_freevars}.
+\end{funcdesc}
+
+\begin{funcdesc}{code}{argcount, nlocals, stacksize, flags, codestring,
+                       constants, names, varnames, filename, name, firstlineno,
+                       lnotab}
+This function is an interface to the \cfunction{PyCode_New()} C
+function.
+%XXX This is still undocumented!!!!!!!!!!!
+\end{funcdesc}
+
+\begin{funcdesc}{module}{name[, doc]}
+This function returns a new module object with name \var{name}.
+\var{name} must be a string.
+The optional \var{doc} argument can have any type.
+\end{funcdesc}
+
+\begin{funcdesc}{classobj}{name, baseclasses, dict}
+This function returns a new class object, with name \var{name}, derived
+from \var{baseclasses} (which should be a tuple of classes) and with
+namespace \var{dict}.
+\end{funcdesc}

Added: vendor/Python/current/Doc/lib/libni.tex
===================================================================
--- vendor/Python/current/Doc/lib/libni.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libni.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,63 @@
+\section{\module{ni} ---
+         None}
+\declaremodule{standard}{ni}
+
+\modulesynopsis{None}
+
+
+\strong{Warning: This module is obsolete.}  As of Python 1.5a4,
+package support (with different semantics for \code{__init__} and no
+support for \code{__domain__} or \code{__}) is built in the
+interpreter.  The ni module is retained only for backward
+compatibility.  As of Python 1.5b2, it has been renamed to \code{ni1}; 
+if you really need it, you can use \code{import ni1}, but the
+recommended approach is to rely on the built-in package support,
+converting existing packages if needed.  Note that mixing \code{ni}
+and the built-in package support doesn't work: once you import
+\code{ni}, all packages use it.
+
+The \code{ni} module defines a new importing scheme, which supports
+packages containing several Python modules.  To enable package
+support, execute \code{import ni} before importing any packages.  Importing
+this module automatically installs the relevant import hooks.  There
+are no publicly-usable functions or variables in the \code{ni} module.
+
+To create a package named \code{spam} containing sub-modules \code{ham}, \code{bacon} and
+\code{eggs}, create a directory \file{spam} somewhere on Python's module search
+path, as given in \code{sys.path}.  Then, create files called \file{ham.py}, \file{bacon.py} and
+\file{eggs.py} inside \file{spam}.
+
+To import module \code{ham} from package \code{spam} and use function
+\code{hamneggs()} from that module, you can use any of the following
+possibilities:
+
+\begin{verbatim}
+import spam.ham		# *not* "import spam" !!!
+spam.ham.hamneggs()
+\end{verbatim}
+%
+\begin{verbatim}
+from spam import ham
+ham.hamneggs()
+\end{verbatim}
+%
+\begin{verbatim}
+from spam.ham import hamneggs
+hamneggs()
+\end{verbatim}
+%
+\code{import spam} creates an
+empty package named \code{spam} if one does not already exist, but it does
+\emph{not} automatically import \code{spam}'s submodules.  
+The only submodule that is guaranteed to be imported is
+\code{spam.__init__}, if it exists; it would be in a file named
+\file{__init__.py} in the \file{spam} directory.  Note that
+\code{spam.__init__} is a submodule of package spam.  It can refer to
+spam's namespace as \code{__} (two underscores):
+
+\begin{verbatim}
+__.spam_inited = 1		# Set a package-level variable
+\end{verbatim}
+%
+Additional initialization code (setting up variables, importing other
+submodules) can be performed in \file{spam/__init__.py}.

Added: vendor/Python/current/Doc/lib/libnis.tex
===================================================================
--- vendor/Python/current/Doc/lib/libnis.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libnis.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,63 @@
+\section{\module{nis} ---
+         Interface to Sun's NIS (Yellow Pages)}
+
+\declaremodule{extension}{nis}
+  \platform{UNIX}
+\moduleauthor{Fred Gansevles}{Fred.Gansevles at cs.utwente.nl}
+\sectionauthor{Moshe Zadka}{moshez at zadka.site.co.il}
+\modulesynopsis{Interface to Sun's NIS (Yellow Pages) library.}
+
+The \module{nis} module gives a thin wrapper around the NIS library, useful
+for central administration of several hosts.
+
+Because NIS exists only on \UNIX{} systems, this module is
+only available for \UNIX.
+
+The \module{nis} module defines the following functions:
+
+\begin{funcdesc}{match}{key, mapname[, domain=default_domain]}
+Return the match for \var{key} in map \var{mapname}, or raise an
+error (\exception{nis.error}) if there is none.
+Both should be strings, \var{key} is 8-bit clean.
+Return value is an arbitrary array of bytes (may contain \code{NULL}
+and other joys).
+
+Note that \var{mapname} is first checked if it is an alias to another
+name.
+
+\versionchanged[The \var{domain} argument allows to override
+the NIS domain used for the lookup. If unspecified, lookup is in the
+default NIS domain]{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{cat}{mapname[, domain=default_domain]}
+Return a dictionary mapping \var{key} to \var{value} such that
+\code{match(\var{key}, \var{mapname})==\var{value}}.
+Note that both keys and values of the dictionary are arbitrary
+arrays of bytes.
+
+Note that \var{mapname} is first checked if it is an alias to another
+name.
+
+\versionchanged[The \var{domain} argument allows to override
+the NIS domain used for the lookup. If unspecified, lookup is in the
+default NIS domain]{2.5}
+\end{funcdesc}
+
+ \begin{funcdesc}{maps}{[domain=default_domain]}
+Return a list of all valid maps.
+
+\versionchanged[The \var{domain} argument allows to override
+the NIS domain used for the lookup. If unspecified, lookup is in the
+default NIS domain]{2.5}
+\end{funcdesc}
+
+ \begin{funcdesc}{get_default_domain}{}
+Return the system default NIS domain. \versionadded{2.5}
+\end{funcdesc}
+
+The \module{nis} module defines the following exception:
+
+\begin{excdesc}{error}
+An error raised when a NIS function returns an error code.
+\end{excdesc}

Added: vendor/Python/current/Doc/lib/libnntplib.tex
===================================================================
--- vendor/Python/current/Doc/lib/libnntplib.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libnntplib.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,355 @@
+\section{\module{nntplib} ---
+         NNTP protocol client}
+
+\declaremodule{standard}{nntplib}
+\modulesynopsis{NNTP protocol client (requires sockets).}
+
+\indexii{NNTP}{protocol}
+\index{Network News Transfer Protocol}
+
+This module defines the class \class{NNTP} which implements the client
+side of the NNTP protocol.  It can be used to implement a news reader
+or poster, or automated news processors.  For more information on NNTP
+(Network News Transfer Protocol), see Internet \rfc{977}.
+
+Here are two small examples of how it can be used.  To list some
+statistics about a newsgroup and print the subjects of the last 10
+articles:
+
+\begin{verbatim}
+>>> s = NNTP('news.cwi.nl')
+>>> resp, count, first, last, name = s.group('comp.lang.python')
+>>> print 'Group', name, 'has', count, 'articles, range', first, 'to', last
+Group comp.lang.python has 59 articles, range 3742 to 3803
+>>> resp, subs = s.xhdr('subject', first + '-' + last)
+>>> for id, sub in subs[-10:]: print id, sub
+... 
+3792 Re: Removing elements from a list while iterating...
+3793 Re: Who likes Info files?
+3794 Emacs and doc strings
+3795 a few questions about the Mac implementation
+3796 Re: executable python scripts
+3797 Re: executable python scripts
+3798 Re: a few questions about the Mac implementation 
+3799 Re: PROPOSAL: A Generic Python Object Interface for Python C Modules
+3802 Re: executable python scripts 
+3803 Re: \POSIX{} wait and SIGCHLD
+>>> s.quit()
+'205 news.cwi.nl closing connection.  Goodbye.'
+\end{verbatim}
+
+To post an article from a file (this assumes that the article has
+valid headers):
+
+\begin{verbatim}
+>>> s = NNTP('news.cwi.nl')
+>>> f = open('/tmp/article')
+>>> s.post(f)
+'240 Article posted successfully.'
+>>> s.quit()
+'205 news.cwi.nl closing connection.  Goodbye.'
+\end{verbatim}
+
+The module itself defines the following items:
+
+\begin{classdesc}{NNTP}{host\optional{, port
+                        \optional{, user\optional{, password
+			\optional{, readermode}
+			\optional{, usenetrc}}}}}
+Return a new instance of the \class{NNTP} class, representing a
+connection to the NNTP server running on host \var{host}, listening at
+port \var{port}.  The default \var{port} is 119.  If the optional
+\var{user} and \var{password} are provided, 
+or if suitable credentials are present in \file{~/.netrc} and the
+optional flag \var{usenetrc} is true (the default),
+the \samp{AUTHINFO USER} and \samp{AUTHINFO PASS} commands are used to
+identify and authenticate the user to the server.  If the optional
+flag \var{readermode} is true, then a \samp{mode reader} command is
+sent before authentication is performed.  Reader mode is sometimes
+necessary if you are connecting to an NNTP server on the local machine
+and intend to call reader-specific commands, such as \samp{group}.  If
+you get unexpected \exception{NNTPPermanentError}s, you might need to set
+\var{readermode}.  \var{readermode} defaults to \code{None}.
+\var{usenetrc} defaults to \code{True}.
+
+\versionchanged[\var{usenetrc} argument added]{2.4}
+\end{classdesc}
+
+\begin{excdesc}{NNTPError}
+Derived from the standard exception \exception{Exception}, this is the
+base class for all exceptions raised by the \module{nntplib} module.
+\end{excdesc}
+
+\begin{excdesc}{NNTPReplyError}
+Exception raised when an unexpected reply is received from the
+server.  For backwards compatibility, the exception \code{error_reply}
+is equivalent to this class.
+\end{excdesc}
+
+\begin{excdesc}{NNTPTemporaryError}
+Exception raised when an error code in the range 400--499 is
+received.  For backwards compatibility, the exception
+\code{error_temp} is equivalent to this class.
+\end{excdesc}
+
+\begin{excdesc}{NNTPPermanentError}
+Exception raised when an error code in the range 500--599 is
+received.  For backwards compatibility, the exception
+\code{error_perm} is equivalent to this class.
+\end{excdesc}
+
+\begin{excdesc}{NNTPProtocolError}
+Exception raised when a reply is received from the server that does
+not begin with a digit in the range 1--5.  For backwards
+compatibility, the exception \code{error_proto} is equivalent to this
+class.
+\end{excdesc}
+
+\begin{excdesc}{NNTPDataError}
+Exception raised when there is some error in the response data.  For
+backwards compatibility, the exception \code{error_data} is
+equivalent to this class.
+\end{excdesc}
+
+
+\subsection{NNTP Objects \label{nntp-objects}}
+
+NNTP instances have the following methods.  The \var{response} that is
+returned as the first item in the return tuple of almost all methods
+is the server's response: a string beginning with a three-digit code.
+If the server's response indicates an error, the method raises one of
+the above exceptions.
+
+
+\begin{methoddesc}{getwelcome}{}
+Return the welcome message sent by the server in reply to the initial
+connection.  (This message sometimes contains disclaimers or help
+information that may be relevant to the user.)
+\end{methoddesc}
+
+\begin{methoddesc}{set_debuglevel}{level}
+Set the instance's debugging level.  This controls the amount of
+debugging output printed.  The default, \code{0}, produces no debugging
+output.  A value of \code{1} produces a moderate amount of debugging
+output, generally a single line per request or response.  A value of
+\code{2} or higher produces the maximum amount of debugging output,
+logging each line sent and received on the connection (including
+message text).
+\end{methoddesc}
+
+\begin{methoddesc}{newgroups}{date, time, \optional{file}}
+Send a \samp{NEWGROUPS} command.  The \var{date} argument should be a
+string of the form \code{'\var{yy}\var{mm}\var{dd}'} indicating the
+date, and \var{time} should be a string of the form
+\code{'\var{hh}\var{mm}\var{ss}'} indicating the time.  Return a pair
+\code{(\var{response}, \var{groups})} where \var{groups} is a list of
+group names that are new since the given date and time.
+If the \var{file} parameter is supplied, then the output of the 
+\samp{NEWGROUPS} command is stored in a file.  If \var{file} is a string, 
+then the method will open a file object with that name, write to it 
+then close it.  If \var{file} is a file object, then it will start
+calling \method{write()} on it to store the lines of the command output.
+If \var{file} is supplied, then the returned \var{list} is an empty list.
+\end{methoddesc}
+
+\begin{methoddesc}{newnews}{group, date, time, \optional{file}}
+Send a \samp{NEWNEWS} command.  Here, \var{group} is a group name or
+\code{'*'}, and \var{date} and \var{time} have the same meaning as for
+\method{newgroups()}.  Return a pair \code{(\var{response},
+\var{articles})} where \var{articles} is a list of message ids.
+If the \var{file} parameter is supplied, then the output of the 
+\samp{NEWNEWS} command is stored in a file.  If \var{file} is a string, 
+then the method will open a file object with that name, write to it 
+then close it.  If \var{file} is a file object, then it will start
+calling \method{write()} on it to store the lines of the command output.
+If \var{file} is supplied, then the returned \var{list} is an empty list.
+\end{methoddesc}
+
+\begin{methoddesc}{list}{\optional{file}}
+Send a \samp{LIST} command.  Return a pair \code{(\var{response},
+\var{list})} where \var{list} is a list of tuples.  Each tuple has the
+form \code{(\var{group}, \var{last}, \var{first}, \var{flag})}, where
+\var{group} is a group name, \var{last} and \var{first} are the last
+and first article numbers (as strings), and \var{flag} is
+\code{'y'} if posting is allowed, \code{'n'} if not, and \code{'m'} if
+the newsgroup is moderated.  (Note the ordering: \var{last},
+\var{first}.)
+If the \var{file} parameter is supplied, then the output of the 
+\samp{LIST} command is stored in a file.  If \var{file} is a string, 
+then the method will open a file object with that name, write to it 
+then close it.  If \var{file} is a file object, then it will start
+calling \method{write()} on it to store the lines of the command output.
+If \var{file} is supplied, then the returned \var{list} is an empty list.
+\end{methoddesc}
+
+\begin{methoddesc}{descriptions}{grouppattern}
+Send a \samp{LIST NEWSGROUPS} command, where \var{grouppattern} is a wildmat
+string as specified in RFC2980 (it's essentially the same as DOS or UNIX
+shell wildcard strings).  Return a pair \code{(\var{response},
+\var{list})}, where \var{list} is a list of tuples containing
+\code{(\var{name}, \var{title})}.
+
+\versionadded{2.4}
+\end{methoddesc}
+
+\begin{methoddesc}{description}{group}
+Get a description for a single group \var{group}.  If more than one group
+matches (if 'group' is a real wildmat string), return the first match.  
+If no group matches, return an empty string.
+
+This elides the response code from the server.  If the response code is
+needed, use \method{descriptions()}.
+
+\versionadded{2.4}
+\end{methoddesc}
+
+\begin{methoddesc}{group}{name}
+Send a \samp{GROUP} command, where \var{name} is the group name.
+Return a tuple \code{(\var{response}, \var{count}, \var{first},
+\var{last}, \var{name})} where \var{count} is the (estimated) number
+of articles in the group, \var{first} is the first article number in
+the group, \var{last} is the last article number in the group, and
+\var{name} is the group name.  The numbers are returned as strings.
+\end{methoddesc}
+
+\begin{methoddesc}{help}{\optional{file}}
+Send a \samp{HELP} command.  Return a pair \code{(\var{response},
+\var{list})} where \var{list} is a list of help strings.
+If the \var{file} parameter is supplied, then the output of the 
+\samp{HELP} command is stored in a file.  If \var{file} is a string, 
+then the method will open a file object with that name, write to it 
+then close it.  If \var{file} is a file object, then it will start
+calling \method{write()} on it to store the lines of the command output.
+If \var{file} is supplied, then the returned \var{list} is an empty list.
+\end{methoddesc}
+
+\begin{methoddesc}{stat}{id}
+Send a \samp{STAT} command, where \var{id} is the message id (enclosed
+in \character{<} and \character{>}) or an article number (as a string).
+Return a triple \code{(\var{response}, \var{number}, \var{id})} where
+\var{number} is the article number (as a string) and \var{id} is the
+message id  (enclosed in \character{<} and \character{>}).
+\end{methoddesc}
+
+\begin{methoddesc}{next}{}
+Send a \samp{NEXT} command.  Return as for \method{stat()}.
+\end{methoddesc}
+
+\begin{methoddesc}{last}{}
+Send a \samp{LAST} command.  Return as for \method{stat()}.
+\end{methoddesc}
+
+\begin{methoddesc}{head}{id}
+Send a \samp{HEAD} command, where \var{id} has the same meaning as for
+\method{stat()}.  Return a tuple
+\code{(\var{response}, \var{number}, \var{id}, \var{list})}
+where the first three are the same as for \method{stat()},
+and \var{list} is a list of the article's headers (an uninterpreted
+list of lines, without trailing newlines).
+\end{methoddesc}
+
+\begin{methoddesc}{body}{id,\optional{file}}
+Send a \samp{BODY} command, where \var{id} has the same meaning as for
+\method{stat()}.  If the \var{file} parameter is supplied, then
+the body is stored in a file.  If \var{file} is a string, then
+the method will open a file object with that name, write to it then close it.
+If \var{file} is a file object, then it will start calling
+\method{write()} on it to store the lines of the body.
+Return as for \method{head()}.  If \var{file} is supplied, then
+the returned \var{list} is an empty list.
+\end{methoddesc}
+
+\begin{methoddesc}{article}{id}
+Send an \samp{ARTICLE} command, where \var{id} has the same meaning as
+for \method{stat()}.  Return as for \method{head()}.
+\end{methoddesc}
+
+\begin{methoddesc}{slave}{}
+Send a \samp{SLAVE} command.  Return the server's \var{response}.
+\end{methoddesc}
+
+\begin{methoddesc}{xhdr}{header, string, \optional{file}}
+Send an \samp{XHDR} command.  This command is not defined in the RFC
+but is a common extension.  The \var{header} argument is a header
+keyword, e.g. \code{'subject'}.  The \var{string} argument should have
+the form \code{'\var{first}-\var{last}'} where \var{first} and
+\var{last} are the first and last article numbers to search.  Return a
+pair \code{(\var{response}, \var{list})}, where \var{list} is a list of
+pairs \code{(\var{id}, \var{text})}, where \var{id} is an article number
+(as a string) and \var{text} is the text of the requested header for
+that article.
+If the \var{file} parameter is supplied, then the output of the 
+\samp{XHDR} command is stored in a file.  If \var{file} is a string, 
+then the method will open a file object with that name, write to it 
+then close it.  If \var{file} is a file object, then it will start
+calling \method{write()} on it to store the lines of the command output.
+If \var{file} is supplied, then the returned \var{list} is an empty list.
+\end{methoddesc}
+
+\begin{methoddesc}{post}{file}
+Post an article using the \samp{POST} command.  The \var{file}
+argument is an open file object which is read until EOF using its
+\method{readline()} method.  It should be a well-formed news article,
+including the required headers.  The \method{post()} method
+automatically escapes lines beginning with \samp{.}.
+\end{methoddesc}
+
+\begin{methoddesc}{ihave}{id, file}
+Send an \samp{IHAVE} command. \var{id} is a message id (enclosed in 
+\character{<} and \character{>}).
+If the response is not an error, treat
+\var{file} exactly as for the \method{post()} method.
+\end{methoddesc}
+
+\begin{methoddesc}{date}{}
+Return a triple \code{(\var{response}, \var{date}, \var{time})},
+containing the current date and time in a form suitable for the
+\method{newnews()} and \method{newgroups()} methods.
+This is an optional NNTP extension, and may not be supported by all
+servers.
+\end{methoddesc}
+
+\begin{methoddesc}{xgtitle}{name, \optional{file}}
+Process an \samp{XGTITLE} command, returning a pair \code{(\var{response},
+\var{list})}, where \var{list} is a list of tuples containing
+\code{(\var{name}, \var{title})}.
+% XXX huh?  Should that be name, description?
+If the \var{file} parameter is supplied, then the output of the 
+\samp{XGTITLE} command is stored in a file.  If \var{file} is a string, 
+then the method will open a file object with that name, write to it 
+then close it.  If \var{file} is a file object, then it will start
+calling \method{write()} on it to store the lines of the command output.
+If \var{file} is supplied, then the returned \var{list} is an empty list.
+This is an optional NNTP extension, and may not be supported by all
+servers.
+
+RFC2980 says ``It is suggested that this extension be deprecated''.  Use
+\method{descriptions()} or \method{description()} instead.
+\end{methoddesc}
+
+\begin{methoddesc}{xover}{start, end, \optional{file}}
+Return a pair \code{(\var{resp}, \var{list})}.  \var{list} is a list
+of tuples, one for each article in the range delimited by the \var{start}
+and \var{end} article numbers.  Each tuple is of the form
+\code{(\var{article number}, \var{subject}, \var{poster}, \var{date},
+\var{id}, \var{references}, \var{size}, \var{lines})}.
+If the \var{file} parameter is supplied, then the output of the 
+\samp{XOVER} command is stored in a file.  If \var{file} is a string, 
+then the method will open a file object with that name, write to it 
+then close it.  If \var{file} is a file object, then it will start
+calling \method{write()} on it to store the lines of the command output.
+If \var{file} is supplied, then the returned \var{list} is an empty list.
+This is an optional NNTP extension, and may not be supported by all
+servers.
+\end{methoddesc}
+
+\begin{methoddesc}{xpath}{id}
+Return a pair \code{(\var{resp}, \var{path})}, where \var{path} is the
+directory path to the article with message ID \var{id}.  This is an
+optional NNTP extension, and may not be supported by all servers.
+\end{methoddesc}
+
+\begin{methoddesc}{quit}{}
+Send a \samp{QUIT} command and close the connection.  Once this method
+has been called, no other methods of the NNTP object should be called.
+\end{methoddesc}

Added: vendor/Python/current/Doc/lib/libobjs.tex
===================================================================
--- vendor/Python/current/Doc/lib/libobjs.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libobjs.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,24 @@
+\chapter{Built-in Objects \label{builtin}}
+
+Names for built-in exceptions and functions and a number of constants are
+found in a separate 
+symbol table.  This table is searched last when the interpreter looks
+up the meaning of a name, so local and global
+user-defined names can override built-in names.  Built-in types are
+described together here for easy reference.\footnote{
+	Most descriptions sorely lack explanations of the exceptions
+	that may be raised --- this will be fixed in a future version of
+	this manual.}
+\indexii{built-in}{types}
+\indexii{built-in}{exceptions}
+\indexii{built-in}{functions}
+\indexii{built-in}{constants}
+\index{symbol table}
+
+The tables in this chapter document the priorities of operators by
+listing them in order of ascending priority (within a table) and
+grouping operators that have the same priority in the same box.
+Binary operators of the same priority group from left to right.
+(Unary operators group from right to left, but there you have no real
+choice.)  See chapter 5 of the \citetitle[../ref/ref.html]{Python
+Reference Manual} for the complete picture on operator priorities.

Added: vendor/Python/current/Doc/lib/liboperator.tex
===================================================================
--- vendor/Python/current/Doc/lib/liboperator.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/liboperator.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,530 @@
+\section{\module{operator} ---
+         Standard operators as functions.}
+\declaremodule{builtin}{operator}
+\sectionauthor{Skip Montanaro}{skip at automatrix.com}
+
+\modulesynopsis{All Python's standard operators as built-in functions.}
+
+
+The \module{operator} module exports a set of functions implemented in C
+corresponding to the intrinsic operators of Python.  For example,
+\code{operator.add(x, y)} is equivalent to the expression \code{x+y}.  The
+function names are those used for special class methods; variants without
+leading and trailing \samp{__} are also provided for convenience.
+
+The functions fall into categories that perform object comparisons,
+logical operations, mathematical operations, sequence operations, and
+abstract type tests.
+
+The object comparison functions are useful for all objects, and are
+named after the rich comparison operators they support:
+
+\begin{funcdesc}{lt}{a, b}
+\funcline{le}{a, b}
+\funcline{eq}{a, b}
+\funcline{ne}{a, b}
+\funcline{ge}{a, b}
+\funcline{gt}{a, b}
+\funcline{__lt__}{a, b}
+\funcline{__le__}{a, b}
+\funcline{__eq__}{a, b}
+\funcline{__ne__}{a, b}
+\funcline{__ge__}{a, b}
+\funcline{__gt__}{a, b}
+Perform ``rich comparisons'' between \var{a} and \var{b}. Specifically,
+\code{lt(\var{a}, \var{b})} is equivalent to \code{\var{a} < \var{b}},
+\code{le(\var{a}, \var{b})} is equivalent to \code{\var{a} <= \var{b}},
+\code{eq(\var{a}, \var{b})} is equivalent to \code{\var{a} == \var{b}},
+\code{ne(\var{a}, \var{b})} is equivalent to \code{\var{a} != \var{b}},
+\code{gt(\var{a}, \var{b})} is equivalent to \code{\var{a} > \var{b}}
+and
+\code{ge(\var{a}, \var{b})} is equivalent to \code{\var{a} >= \var{b}}.
+Note that unlike the built-in \function{cmp()}, these functions can
+return any value, which may or may not be interpretable as a Boolean
+value.  See the \citetitle[../ref/ref.html]{Python Reference Manual}
+for more information about rich comparisons.
+\versionadded{2.2}
+\end{funcdesc}
+
+
+The logical operations are also generally applicable to all objects,
+and support truth tests, identity tests, and boolean operations:
+
+\begin{funcdesc}{not_}{o}
+\funcline{__not__}{o}
+Return the outcome of \keyword{not} \var{o}.  (Note that there is no
+\method{__not__()} method for object instances; only the interpreter
+core defines this operation.  The result is affected by the
+\method{__nonzero__()} and \method{__len__()} methods.)
+\end{funcdesc}
+
+\begin{funcdesc}{truth}{o}
+Return \constant{True} if \var{o} is true, and \constant{False}
+otherwise.  This is equivalent to using the \class{bool}
+constructor.
+\end{funcdesc}
+
+\begin{funcdesc}{is_}{a, b}
+Return \code{\var{a} is \var{b}}.  Tests object identity.
+\versionadded{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{is_not}{a, b}
+Return \code{\var{a} is not \var{b}}.  Tests object identity.
+\versionadded{2.3}
+\end{funcdesc}
+
+
+The mathematical and bitwise operations are the most numerous:
+
+\begin{funcdesc}{abs}{o}
+\funcline{__abs__}{o}
+Return the absolute value of \var{o}.
+\end{funcdesc}
+
+\begin{funcdesc}{add}{a, b}
+\funcline{__add__}{a, b}
+Return \var{a} \code{+} \var{b}, for \var{a} and \var{b} numbers.
+\end{funcdesc}
+
+\begin{funcdesc}{and_}{a, b}
+\funcline{__and__}{a, b}
+Return the bitwise and of \var{a} and \var{b}.
+\end{funcdesc}
+
+\begin{funcdesc}{div}{a, b}
+\funcline{__div__}{a, b}
+Return \var{a} \code{/} \var{b} when \code{__future__.division} is not
+in effect.  This is also known as ``classic'' division.
+\end{funcdesc}
+
+\begin{funcdesc}{floordiv}{a, b}
+\funcline{__floordiv__}{a, b}
+Return \var{a} \code{//} \var{b}.
+\versionadded{2.2}
+\end{funcdesc}
+
+\begin{funcdesc}{inv}{o}
+\funcline{invert}{o}
+\funcline{__inv__}{o}
+\funcline{__invert__}{o}
+Return the bitwise inverse of the number \var{o}.  This is equivalent
+to \code{\textasciitilde}\var{o}.  The names \function{invert()} and
+\function{__invert__()} were added in Python 2.0.
+\end{funcdesc}
+
+\begin{funcdesc}{lshift}{a, b}
+\funcline{__lshift__}{a, b}
+Return \var{a} shifted left by \var{b}.
+\end{funcdesc}
+
+\begin{funcdesc}{mod}{a, b}
+\funcline{__mod__}{a, b}
+Return \var{a} \code{\%} \var{b}.
+\end{funcdesc}
+
+\begin{funcdesc}{mul}{a, b}
+\funcline{__mul__}{a, b}
+Return \var{a} \code{*} \var{b}, for \var{a} and \var{b} numbers.
+\end{funcdesc}
+
+\begin{funcdesc}{neg}{o}
+\funcline{__neg__}{o}
+Return \var{o} negated.
+\end{funcdesc}
+
+\begin{funcdesc}{or_}{a, b}
+\funcline{__or__}{a, b}
+Return the bitwise or of \var{a} and \var{b}.
+\end{funcdesc}
+
+\begin{funcdesc}{pos}{o}
+\funcline{__pos__}{o}
+Return \var{o} positive.
+\end{funcdesc}
+
+\begin{funcdesc}{pow}{a, b}
+\funcline{__pow__}{a, b}
+Return \var{a} \code{**} \var{b}, for \var{a} and \var{b} numbers.
+\versionadded{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{rshift}{a, b}
+\funcline{__rshift__}{a, b}
+Return \var{a} shifted right by \var{b}.
+\end{funcdesc}
+
+\begin{funcdesc}{sub}{a, b}
+\funcline{__sub__}{a, b}
+Return \var{a} \code{-} \var{b}.
+\end{funcdesc}
+
+\begin{funcdesc}{truediv}{a, b}
+\funcline{__truediv__}{a, b}
+Return \var{a} \code{/} \var{b} when \code{__future__.division} is in
+effect.  This is also known as ``true'' division.
+\versionadded{2.2}
+\end{funcdesc}
+
+\begin{funcdesc}{xor}{a, b}
+\funcline{__xor__}{a, b}
+Return the bitwise exclusive or of \var{a} and \var{b}.
+\end{funcdesc}
+
+\begin{funcdesc}{index}{a}
+\funcline{__index__}{a}
+Return \var{a} converted to an integer.  Equivalent to \var{a}\code{.__index__()}.
+\versionadded{2.5}
+\end{funcdesc}
+
+Operations which work with sequences include:
+
+\begin{funcdesc}{concat}{a, b}
+\funcline{__concat__}{a, b}
+Return \var{a} \code{+} \var{b} for \var{a} and \var{b} sequences.
+\end{funcdesc}
+
+\begin{funcdesc}{contains}{a, b}
+\funcline{__contains__}{a, b}
+Return the outcome of the test \var{b} \code{in} \var{a}.
+Note the reversed operands.  The name \function{__contains__()} was
+added in Python 2.0.
+\end{funcdesc}
+
+\begin{funcdesc}{countOf}{a, b}
+Return the number of occurrences of \var{b} in \var{a}.
+\end{funcdesc}
+
+\begin{funcdesc}{delitem}{a, b}
+\funcline{__delitem__}{a, b}
+Remove the value of \var{a} at index \var{b}.
+\end{funcdesc}
+
+\begin{funcdesc}{delslice}{a, b, c}
+\funcline{__delslice__}{a, b, c}
+Delete the slice of \var{a} from index \var{b} to index \var{c}\code{-1}.
+\end{funcdesc}
+
+\begin{funcdesc}{getitem}{a, b}
+\funcline{__getitem__}{a, b}
+Return the value of \var{a} at index \var{b}.
+\end{funcdesc}
+
+\begin{funcdesc}{getslice}{a, b, c}
+\funcline{__getslice__}{a, b, c}
+Return the slice of \var{a} from index \var{b} to index \var{c}\code{-1}.
+\end{funcdesc}
+
+\begin{funcdesc}{indexOf}{a, b}
+Return the index of the first of occurrence of \var{b} in \var{a}.
+\end{funcdesc}
+
+\begin{funcdesc}{repeat}{a, b}
+\funcline{__repeat__}{a, b}
+Return \var{a} \code{*} \var{b} where \var{a} is a sequence and
+\var{b} is an integer.
+\end{funcdesc}
+
+\begin{funcdesc}{sequenceIncludes}{\unspecified}
+\deprecated{2.0}{Use \function{contains()} instead.}
+Alias for \function{contains()}.
+\end{funcdesc}
+
+\begin{funcdesc}{setitem}{a, b, c}
+\funcline{__setitem__}{a, b, c}
+Set the value of \var{a} at index \var{b} to \var{c}.
+\end{funcdesc}
+
+\begin{funcdesc}{setslice}{a, b, c, v}
+\funcline{__setslice__}{a, b, c, v}
+Set the slice of \var{a} from index \var{b} to index \var{c}\code{-1} to the
+sequence \var{v}.
+\end{funcdesc}
+
+
+Many operations have an ``in-place'' version.  The following functions
+provide a more primitive access to in-place operators than the usual
+syntax does; for example, the statement \code{x += y} is equivalent to
+\code{x = operator.iadd(x, y)}.  Another way to put it is to say that
+\code{z = operator.iadd(x, y)} is equivalent to the compound statement
+\code{z = x; z += y}.
+
+\begin{funcdesc}{iadd}{a, b}
+\funcline{__iadd__}{a, b}
+\code{a = iadd(a, b)} is equivalent to \code{a += b}.
+\versionadded{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{iand}{a, b}
+\funcline{__iand__}{a, b}
+\code{a = iand(a, b)} is equivalent to \code{a \&= b}.
+\versionadded{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{iconcat}{a, b}
+\funcline{__iconcat__}{a, b}
+\code{a = iconcat(a, b)} is equivalent to \code{a += b} for \var{a}
+and \var{b} sequences.
+\versionadded{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{idiv}{a, b}
+\funcline{__idiv__}{a, b}
+\code{a = idiv(a, b)} is equivalent to \code{a /= b} when
+\code{__future__.division} is not in effect.
+\versionadded{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{ifloordiv}{a, b}
+\funcline{__ifloordiv__}{a, b}
+\code{a = ifloordiv(a, b)} is equivalent to \code{a //= b}.
+\versionadded{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{ilshift}{a, b}
+\funcline{__ilshift__}{a, b}
+\code{a = ilshift(a, b)} is equivalent to \code{a <}\code{<= b}.
+\versionadded{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{imod}{a, b}
+\funcline{__imod__}{a, b}
+\code{a = imod(a, b)} is equivalent to \code{a \%= b}.
+\versionadded{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{imul}{a, b}
+\funcline{__imul__}{a, b}
+\code{a = imul(a, b)} is equivalent to \code{a *= b}.
+\versionadded{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{ior}{a, b}
+\funcline{__ior__}{a, b}
+\code{a = ior(a, b)} is equivalent to \code{a |= b}.
+\versionadded{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{ipow}{a, b}
+\funcline{__ipow__}{a, b}
+\code{a = ipow(a, b)} is equivalent to \code{a **= b}.
+\versionadded{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{irepeat}{a, b}
+\funcline{__irepeat__}{a, b}
+\code{a = irepeat(a, b)} is equivalent to \code{a *= b} where
+\var{a} is a sequence and \var{b} is an integer.
+\versionadded{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{irshift}{a, b}
+\funcline{__irshift__}{a, b}
+\code{a = irshift(a, b)} is equivalent to \code{a >>= b}.
+\versionadded{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{isub}{a, b}
+\funcline{__isub__}{a, b}
+\code{a = isub(a, b)} is equivalent to \code{a -= b}.
+\versionadded{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{itruediv}{a, b}
+\funcline{__itruediv__}{a, b}
+\code{a = itruediv(a, b)} is equivalent to \code{a /= b} when
+\code{__future__.division} is in effect.
+\versionadded{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{ixor}{a, b}
+\funcline{__ixor__}{a, b}
+\code{a = ixor(a, b)} is equivalent to \code{a \textasciicircum= b}.
+\versionadded{2.5}
+\end{funcdesc}
+
+
+The \module{operator} module also defines a few predicates to test the
+type of objects.  \note{Be careful not to misinterpret the
+results of these functions; only \function{isCallable()} has any
+measure of reliability with instance objects.  For example:}
+
+\begin{verbatim}
+>>> class C:
+...     pass
+... 
+>>> import operator
+>>> o = C()
+>>> operator.isMappingType(o)
+True
+\end{verbatim}
+
+\begin{funcdesc}{isCallable}{o}
+\deprecated{2.0}{Use the \function{callable()} built-in function instead.}
+Returns true if the object \var{o} can be called like a function,
+otherwise it returns false.  True is returned for functions, bound and
+unbound methods, class objects, and instance objects which support the
+\method{__call__()} method.
+\end{funcdesc}
+
+\begin{funcdesc}{isMappingType}{o}
+Returns true if the object \var{o} supports the mapping interface.
+This is true for dictionaries and all instance objects defining
+\method{__getitem__}.
+\warning{There is no reliable way to test if an instance
+supports the complete mapping protocol since the interface itself is
+ill-defined.  This makes this test less useful than it otherwise might
+be.}
+\end{funcdesc}
+
+\begin{funcdesc}{isNumberType}{o}
+Returns true if the object \var{o} represents a number.  This is true
+for all numeric types implemented in C.
+\warning{There is no reliable way to test if an instance
+supports the complete numeric interface since the interface itself is
+ill-defined.  This makes this test less useful than it otherwise might
+be.}
+\end{funcdesc}
+
+\begin{funcdesc}{isSequenceType}{o}
+Returns true if the object \var{o} supports the sequence protocol.
+This returns true for all objects which define sequence methods in C,
+and for all instance objects defining \method{__getitem__}.
+\warning{There is no reliable
+way to test if an instance supports the complete sequence interface
+since the interface itself is ill-defined.  This makes this test less
+useful than it otherwise might be.}
+\end{funcdesc}
+
+
+Example: Build a dictionary that maps the ordinals from \code{0} to
+\code{255} to their character equivalents.
+
+\begin{verbatim}
+>>> import operator
+>>> d = {}
+>>> keys = range(256)
+>>> vals = map(chr, keys)
+>>> map(operator.setitem, [d]*len(keys), keys, vals)
+\end{verbatim}
+
+
+The \module{operator} module also defines tools for generalized attribute
+and item lookups.  These are useful for making fast field extractors
+as arguments for \function{map()}, \function{sorted()},
+\method{itertools.groupby()}, or other functions that expect a
+function argument.
+
+\begin{funcdesc}{attrgetter}{attr\optional{, args...}}
+Return a callable object that fetches \var{attr} from its operand.
+If more than one attribute is requested, returns a tuple of attributes.
+After, \samp{f=attrgetter('name')}, the call \samp{f(b)} returns
+\samp{b.name}.  After, \samp{f=attrgetter('name', 'date')}, the call
+\samp{f(b)} returns \samp{(b.name, b.date)}. 
+\versionadded{2.4}
+\versionchanged[Added support for multiple attributes]{2.5}
+\end{funcdesc}
+    
+\begin{funcdesc}{itemgetter}{item\optional{, args...}}
+Return a callable object that fetches \var{item} from its operand.
+If more than one item is requested, returns a tuple of items.
+After, \samp{f=itemgetter(2)}, the call \samp{f(b)} returns
+\samp{b[2]}.
+After, \samp{f=itemgetter(2,5,3)}, the call \samp{f(b)} returns
+\samp{(b[2], b[5], b[3])}.		
+\versionadded{2.4}
+\versionchanged[Added support for multiple item extraction]{2.5}		
+\end{funcdesc}
+
+Examples:
+                
+\begin{verbatim}
+>>> from operator import itemgetter
+>>> inventory = [('apple', 3), ('banana', 2), ('pear', 5), ('orange', 1)]
+>>> getcount = itemgetter(1)
+>>> map(getcount, inventory)
+[3, 2, 5, 1]
+>>> sorted(inventory, key=getcount)
+[('orange', 1), ('banana', 2), ('apple', 3), ('pear', 5)]
+\end{verbatim}
+                
+
+\subsection{Mapping Operators to Functions \label{operator-map}}
+
+This table shows how abstract operations correspond to operator
+symbols in the Python syntax and the functions in the
+\refmodule{operator} module.
+
+
+\begin{tableiii}{l|c|l}{textrm}{Operation}{Syntax}{Function}
+  \lineiii{Addition}{\code{\var{a} + \var{b}}}
+          {\code{add(\var{a}, \var{b})}}
+  \lineiii{Concatenation}{\code{\var{seq1} + \var{seq2}}}
+          {\code{concat(\var{seq1}, \var{seq2})}}
+  \lineiii{Containment Test}{\code{\var{o} in \var{seq}}}
+          {\code{contains(\var{seq}, \var{o})}}
+  \lineiii{Division}{\code{\var{a} / \var{b}}}
+          {\code{div(\var{a}, \var{b}) \#} without \code{__future__.division}}
+  \lineiii{Division}{\code{\var{a} / \var{b}}}
+          {\code{truediv(\var{a}, \var{b}) \#} with \code{__future__.division}}
+  \lineiii{Division}{\code{\var{a} // \var{b}}}
+          {\code{floordiv(\var{a}, \var{b})}}
+  \lineiii{Bitwise And}{\code{\var{a} \&\ \var{b}}}
+          {\code{and_(\var{a}, \var{b})}}
+  \lineiii{Bitwise Exclusive Or}{\code{\var{a} \^\ \var{b}}}
+          {\code{xor(\var{a}, \var{b})}}
+  \lineiii{Bitwise Inversion}{\code{\~{} \var{a}}}
+          {\code{invert(\var{a})}}
+  \lineiii{Bitwise Or}{\code{\var{a} | \var{b}}}
+          {\code{or_(\var{a}, \var{b})}}
+  \lineiii{Exponentiation}{\code{\var{a} ** \var{b}}}
+          {\code{pow(\var{a}, \var{b})}}
+  \lineiii{Identity}{\code{\var{a} is \var{b}}}
+          {\code{is_(\var{a}, \var{b})}}
+  \lineiii{Identity}{\code{\var{a} is not \var{b}}}
+          {\code{is_not(\var{a}, \var{b})}}
+  \lineiii{Indexed Assignment}{\code{\var{o}[\var{k}] = \var{v}}}
+          {\code{setitem(\var{o}, \var{k}, \var{v})}}
+  \lineiii{Indexed Deletion}{\code{del \var{o}[\var{k}]}}
+          {\code{delitem(\var{o}, \var{k})}}
+  \lineiii{Indexing}{\code{\var{o}[\var{k}]}}
+          {\code{getitem(\var{o}, \var{k})}}
+  \lineiii{Left Shift}{\code{\var{a} <\code{<} \var{b}}}
+          {\code{lshift(\var{a}, \var{b})}}
+  \lineiii{Modulo}{\code{\var{a} \%\ \var{b}}}
+          {\code{mod(\var{a}, \var{b})}}
+  \lineiii{Multiplication}{\code{\var{a} * \var{b}}}
+          {\code{mul(\var{a}, \var{b})}}
+  \lineiii{Negation (Arithmetic)}{\code{- \var{a}}}
+          {\code{neg(\var{a})}}
+  \lineiii{Negation (Logical)}{\code{not \var{a}}}
+          {\code{not_(\var{a})}}
+  \lineiii{Right Shift}{\code{\var{a} >> \var{b}}}
+          {\code{rshift(\var{a}, \var{b})}}
+  \lineiii{Sequence Repitition}{\code{\var{seq} * \var{i}}}
+          {\code{repeat(\var{seq}, \var{i})}}
+  \lineiii{Slice Assignment}{\code{\var{seq}[\var{i}:\var{j}]} = \var{values}}
+          {\code{setslice(\var{seq}, \var{i}, \var{j}, \var{values})}}
+  \lineiii{Slice Deletion}{\code{del \var{seq}[\var{i}:\var{j}]}}
+          {\code{delslice(\var{seq}, \var{i}, \var{j})}}
+  \lineiii{Slicing}{\code{\var{seq}[\var{i}:\var{j}]}}
+          {\code{getslice(\var{seq}, \var{i}, \var{j})}}
+  \lineiii{String Formatting}{\code{\var{s} \%\ \var{o}}}
+          {\code{mod(\var{s}, \var{o})}}
+  \lineiii{Subtraction}{\code{\var{a} - \var{b}}}
+          {\code{sub(\var{a}, \var{b})}}
+  \lineiii{Truth Test}{\code{\var{o}}}
+          {\code{truth(\var{o})}}
+  \lineiii{Ordering}{\code{\var{a} < \var{b}}}
+          {\code{lt(\var{a}, \var{b})}}
+  \lineiii{Ordering}{\code{\var{a} <= \var{b}}}
+          {\code{le(\var{a}, \var{b})}}
+  \lineiii{Equality}{\code{\var{a} == \var{b}}}
+          {\code{eq(\var{a}, \var{b})}}
+  \lineiii{Difference}{\code{\var{a} != \var{b}}}
+          {\code{ne(\var{a}, \var{b})}}
+  \lineiii{Ordering}{\code{\var{a} >= \var{b}}}
+          {\code{ge(\var{a}, \var{b})}}
+  \lineiii{Ordering}{\code{\var{a} > \var{b}}}
+          {\code{gt(\var{a}, \var{b})}}
+\end{tableiii}

Added: vendor/Python/current/Doc/lib/liboptparse.tex
===================================================================
--- vendor/Python/current/Doc/lib/liboptparse.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/liboptparse.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1888 @@
+% THIS FILE IS AUTO-GENERATED!  DO NOT EDIT!
+% (Your changes will be lost the next time it is generated.)
+\section{\module{optparse} --- More powerful command line option parser}
+\declaremodule{standard}{optparse}
+\moduleauthor{Greg Ward}{gward at python.net}
+\modulesynopsis{More convenient, flexible, and powerful command-line parsing library.}
+\versionadded{2.3}
+\sectionauthor{Greg Ward}{gward at python.net}
+% An intro blurb used only when generating LaTeX docs for the Python
+% manual (based on README.txt). 
+
+\code{optparse} is a more convenient, flexible, and powerful library for
+parsing command-line options than \code{getopt}.  \code{optparse} uses a more
+declarative style of command-line parsing: you create an instance of
+\class{OptionParser}, populate it with options, and parse the command line.
+\code{optparse} allows users to specify options in the conventional GNU/POSIX
+syntax, and additionally generates usage and help messages for you.
+
+Here's an example of using \code{optparse} in a simple script:
+\begin{verbatim}
+from optparse import OptionParser
+[...]
+parser = OptionParser()
+parser.add_option("-f", "--file", dest="filename",
+                  help="write report to FILE", metavar="FILE")
+parser.add_option("-q", "--quiet",
+                  action="store_false", dest="verbose", default=True,
+                  help="don't print status messages to stdout")
+
+(options, args) = parser.parse_args()
+\end{verbatim}
+
+With these few lines of code, users of your script can now do the
+``usual thing'' on the command-line, for example:
+\begin{verbatim}
+<yourscript> --file=outfile -q
+\end{verbatim}
+
+As it parses the command line, \code{optparse} sets attributes of the
+\code{options} object returned by \method{parse{\_}args()} based on user-supplied
+command-line values.  When \method{parse{\_}args()} returns from parsing this
+command line, \code{options.filename} will be \code{"outfile"} and
+\code{options.verbose} will be \code{False}.  \code{optparse} supports both long
+and short options, allows short options to be merged together, and
+allows options to be associated with their arguments in a variety of
+ways.  Thus, the following command lines are all equivalent to the above
+example:
+\begin{verbatim}
+<yourscript> -f outfile --quiet
+<yourscript> --quiet --file outfile
+<yourscript> -q -foutfile
+<yourscript> -qfoutfile
+\end{verbatim}
+
+Additionally, users can run one of
+\begin{verbatim}
+<yourscript> -h
+<yourscript> --help
+\end{verbatim}
+
+and \code{optparse} will print out a brief summary of your script's
+options:
+\begin{verbatim}
+usage: <yourscript> [options]
+
+options:
+  -h, --help            show this help message and exit
+  -f FILE, --file=FILE  write report to FILE
+  -q, --quiet           don't print status messages to stdout
+\end{verbatim}
+
+where the value of \emph{yourscript} is determined at runtime (normally
+from \code{sys.argv{[}0]}).
+% $Id: intro.txt 413 2004-09-28 00:59:13Z greg $ 
+
+
+\subsection{Background\label{optparse-background}}
+
+\module{optparse} was explicitly designed to encourage the creation of programs with
+straightforward, conventional command-line interfaces.  To that end, it
+supports only the most common command-line syntax and semantics
+conventionally used under \UNIX{}.  If you are unfamiliar with these
+conventions, read this section to acquaint yourself with them.
+
+
+\subsubsection{Terminology\label{optparse-terminology}}
+\begin{description}
+\item[argument]
+a string entered on the command-line, and passed by the shell to
+\code{execl()} or \code{execv()}.  In Python, arguments are elements of
+\code{sys.argv{[}1:]} (\code{sys.argv{[}0]} is the name of the program being
+executed).  \UNIX{} shells also use the term ``word''.
+
+It is occasionally desirable to substitute an argument list other
+than \code{sys.argv{[}1:]}, so you should read ``argument'' as ``an element of
+\code{sys.argv{[}1:]}, or of some other list provided as a substitute for
+\code{sys.argv{[}1:]}''.
+\item[option   ]
+an argument used to supply extra information to guide or customize the
+execution of a program.  There are many different syntaxes for
+options; the traditional \UNIX{} syntax is a hyphen (``-'') followed by a
+single letter, e.g. \code{"-x"} or \code{"-F"}.  Also, traditional \UNIX{}
+syntax allows multiple options to be merged into a single argument,
+e.g.  \code{"-x -F"} is equivalent to \code{"-xF"}.  The GNU project
+introduced \code{"-{}-"} followed by a series of hyphen-separated words,
+e.g. \code{"-{}-file"} or \code{"-{}-dry-run"}.  These are the only two option
+syntaxes provided by \module{optparse}.
+
+Some other option syntaxes that the world has seen include:
+\begin{itemize}
+\item {} 
+a hyphen followed by a few letters, e.g. \code{"-pf"} (this is
+\emph{not} the same as multiple options merged into a single argument)
+
+\item {} 
+a hyphen followed by a whole word, e.g. \code{"-file"} (this is
+technically equivalent to the previous syntax, but they aren't
+usually seen in the same program)
+
+\item {} 
+a plus sign followed by a single letter, or a few letters,
+or a word, e.g. \code{"+f"}, \code{"+rgb"}
+
+\item {} 
+a slash followed by a letter, or a few letters, or a word, e.g.
+\code{"/f"}, \code{"/file"}
+
+\end{itemize}
+
+These option syntaxes are not supported by \module{optparse}, and they never will
+be.  This is deliberate: the first three are non-standard on any
+environment, and the last only makes sense if you're exclusively
+targeting VMS, MS-DOS, and/or Windows.
+\item[option argument]
+an argument that follows an option, is closely associated with that
+option, and is consumed from the argument list when that option is.
+With \module{optparse}, option arguments may either be in a separate argument
+from their option:
+\begin{verbatim}
+-f foo
+--file foo
+\end{verbatim}
+
+or included in the same argument:
+\begin{verbatim}
+-ffoo
+--file=foo
+\end{verbatim}
+
+Typically, a given option either takes an argument or it doesn't.
+Lots of people want an ``optional option arguments'' feature, meaning
+that some options will take an argument if they see it, and won't if
+they don't.  This is somewhat controversial, because it makes parsing
+ambiguous: if \code{"-a"} takes an optional argument and \code{"-b"} is
+another option entirely, how do we interpret \code{"-ab"}?  Because of
+this ambiguity, \module{optparse} does not support this feature.
+\item[positional argument]
+something leftover in the argument list after options have been
+parsed, i.e. after options and their arguments have been parsed and
+removed from the argument list.
+\item[required option]
+an option that must be supplied on the command-line; note that the
+phrase ``required option'' is self-contradictory in English.  \module{optparse}
+doesn't prevent you from implementing required options, but doesn't
+give you much help at it either.  See \code{examples/required{\_}1.py} and
+\code{examples/required{\_}2.py} in the \module{optparse} source distribution for two
+ways to implement required options with \module{optparse}.
+\end{description}
+
+For example, consider this hypothetical command-line:
+\begin{verbatim}
+prog -v --report /tmp/report.txt foo bar
+\end{verbatim}
+
+\code{"-v"} and \code{"-{}-report"} are both options.  Assuming that
+\longprogramopt{report} takes one argument, \code{"/tmp/report.txt"} is an option
+argument.  \code{"foo"} and \code{"bar"} are positional arguments.
+
+
+\subsubsection{What are options for?\label{optparse-what-options-for}}
+
+Options are used to provide extra information to tune or customize the
+execution of a program.  In case it wasn't clear, options are usually
+\emph{optional}.  A program should be able to run just fine with no options
+whatsoever.  (Pick a random program from the \UNIX{} or GNU toolsets.  Can
+it run without any options at all and still make sense?  The main
+exceptions are \code{find}, \code{tar}, and \code{dd}{---}all of which are mutant
+oddballs that have been rightly criticized for their non-standard syntax
+and confusing interfaces.)
+
+Lots of people want their programs to have ``required options''.  Think
+about it.  If it's required, then it's \emph{not optional}!  If there is a
+piece of information that your program absolutely requires in order to
+run successfully, that's what positional arguments are for.
+
+As an example of good command-line interface design, consider the humble
+\code{cp} utility, for copying files.  It doesn't make much sense to try to
+copy files without supplying a destination and at least one source.
+Hence, \code{cp} fails if you run it with no arguments.  However, it has a
+flexible, useful syntax that does not require any options at all:
+\begin{verbatim}
+cp SOURCE DEST
+cp SOURCE ... DEST-DIR
+\end{verbatim}
+
+You can get pretty far with just that.  Most \code{cp} implementations
+provide a bunch of options to tweak exactly how the files are copied:
+you can preserve mode and modification time, avoid following symlinks,
+ask before clobbering existing files, etc.  But none of this distracts
+from the core mission of \code{cp}, which is to copy either one file to
+another, or several files to another directory.
+
+
+\subsubsection{What are positional arguments for?\label{optparse-what-positional-arguments-for}}
+
+Positional arguments are for those pieces of information that your
+program absolutely, positively requires to run.
+
+A good user interface should have as few absolute requirements as
+possible.  If your program requires 17 distinct pieces of information in
+order to run successfully, it doesn't much matter \emph{how} you get that
+information from the user{---}most people will give up and walk away
+before they successfully run the program.  This applies whether the user
+interface is a command-line, a configuration file, or a GUI: if you make
+that many demands on your users, most of them will simply give up.
+
+In short, try to minimize the amount of information that users are
+absolutely required to supply{---}use sensible defaults whenever
+possible.  Of course, you also want to make your programs reasonably
+flexible.  That's what options are for.  Again, it doesn't matter if
+they are entries in a config file, widgets in the ``Preferences'' dialog
+of a GUI, or command-line options{---}the more options you implement, the
+more flexible your program is, and the more complicated its
+implementation becomes.  Too much flexibility has drawbacks as well, of
+course; too many options can overwhelm users and make your code much
+harder to maintain.
+% $Id: tao.txt 413 2004-09-28 00:59:13Z greg $ 
+
+
+\subsection{Tutorial\label{optparse-tutorial}}
+
+While \module{optparse} is quite flexible and powerful, it's also straightforward to
+use in most cases.  This section covers the code patterns that are
+common to any \module{optparse}-based program.
+
+First, you need to import the OptionParser class; then, early in the
+main program, create an OptionParser instance:
+\begin{verbatim}
+from optparse import OptionParser
+[...]
+parser = OptionParser()
+\end{verbatim}
+
+Then you can start defining options.  The basic syntax is:
+\begin{verbatim}
+parser.add_option(opt_str, ...,
+                  attr=value, ...)
+\end{verbatim}
+
+Each option has one or more option strings, such as \code{"-f"} or
+\code{"-{}-file"}, and several option attributes that tell \module{optparse} what to
+expect and what to do when it encounters that option on the command
+line.
+
+Typically, each option will have one short option string and one long
+option string, e.g.:
+\begin{verbatim}
+parser.add_option("-f", "--file", ...)
+\end{verbatim}
+
+You're free to define as many short option strings and as many long
+option strings as you like (including zero), as long as there is at
+least one option string overall.
+
+The option strings passed to \method{add{\_}option()} are effectively labels for
+the option defined by that call.  For brevity, we will frequently refer
+to \emph{encountering an option} on the command line; in reality, \module{optparse}
+encounters \emph{option strings} and looks up options from them.
+
+Once all of your options are defined, instruct \module{optparse} to parse your
+program's command line:
+\begin{verbatim}
+(options, args) = parser.parse_args()
+\end{verbatim}
+
+(If you like, you can pass a custom argument list to \method{parse{\_}args()},
+but that's rarely necessary: by default it uses \code{sys.argv{[}1:]}.)
+
+\method{parse{\_}args()} returns two values:
+\begin{itemize}
+\item {} 
+\code{options}, an object containing values for all of your options{---}e.g. if \code{"-{}-file"} takes a single string argument, then
+\code{options.file} will be the filename supplied by the user, or
+\code{None} if the user did not supply that option
+
+\item {} 
+\code{args}, the list of positional arguments leftover after parsing
+options
+
+\end{itemize}
+
+This tutorial section only covers the four most important option
+attributes: \member{action}, \member{type}, \member{dest} (destination), and \member{help}.
+Of these, \member{action} is the most fundamental.
+
+
+\subsubsection{Understanding option actions\label{optparse-understanding-option-actions}}
+
+Actions tell \module{optparse} what to do when it encounters an option on the
+command line.  There is a fixed set of actions hard-coded into \module{optparse};
+adding new actions is an advanced topic covered in section~\ref{optparse-extending-optparse}, Extending \module{optparse}.
+Most actions tell \module{optparse} to store a value in some variable{---}for
+example, take a string from the command line and store it in an
+attribute of \code{options}.
+
+If you don't specify an option action, \module{optparse} defaults to \code{store}.
+
+
+\subsubsection{The store action\label{optparse-store-action}}
+
+The most common option action is \code{store}, which tells \module{optparse} to take
+the next argument (or the remainder of the current argument), ensure
+that it is of the correct type, and store it to your chosen destination.
+
+For example:
+\begin{verbatim}
+parser.add_option("-f", "--file",
+                  action="store", type="string", dest="filename")
+\end{verbatim}
+
+Now let's make up a fake command line and ask \module{optparse} to parse it:
+\begin{verbatim}
+args = ["-f", "foo.txt"]
+(options, args) = parser.parse_args(args)
+\end{verbatim}
+
+When \module{optparse} sees the option string \code{"-f"}, it consumes the next
+argument, \code{"foo.txt"}, and stores it in \code{options.filename}.  So,
+after this call to \method{parse{\_}args()}, \code{options.filename} is
+\code{"foo.txt"}.
+
+Some other option types supported by \module{optparse} are \code{int} and \code{float}.
+Here's an option that expects an integer argument:
+\begin{verbatim}
+parser.add_option("-n", type="int", dest="num")
+\end{verbatim}
+
+Note that this option has no long option string, which is perfectly
+acceptable.  Also, there's no explicit action, since the default is
+\code{store}.
+
+Let's parse another fake command-line.  This time, we'll jam the option
+argument right up against the option: since \code{"-n42"} (one argument) is
+equivalent to \code{"-n 42"} (two arguments), the code
+\begin{verbatim}
+(options, args) = parser.parse_args(["-n42"])
+print options.num
+\end{verbatim}
+
+will print \code{"42"}.
+
+If you don't specify a type, \module{optparse} assumes \code{string}.  Combined with the
+fact that the default action is \code{store}, that means our first example
+can be a lot shorter:
+\begin{verbatim}
+parser.add_option("-f", "--file", dest="filename")
+\end{verbatim}
+
+If you don't supply a destination, \module{optparse} figures out a sensible default
+from the option strings: if the first long option string is
+\code{"-{}-foo-bar"}, then the default destination is \code{foo{\_}bar}.  If there
+are no long option strings, \module{optparse} looks at the first short option
+string: the default destination for \code{"-f"} is \code{f}.
+
+\module{optparse} also includes built-in \code{long} and \code{complex} types.  Adding
+types is covered in section~\ref{optparse-extending-optparse}, Extending \module{optparse}.
+
+
+\subsubsection{Handling boolean (flag) options\label{optparse-handling-boolean-options}}
+
+Flag options{---}set a variable to true or false when a particular option
+is seen{---}are quite common.  \module{optparse} supports them with two separate
+actions, \code{store{\_}true} and \code{store{\_}false}.  For example, you might have a
+\code{verbose} flag that is turned on with \code{"-v"} and off with \code{"-q"}:
+\begin{verbatim}
+parser.add_option("-v", action="store_true", dest="verbose")
+parser.add_option("-q", action="store_false", dest="verbose")
+\end{verbatim}
+
+Here we have two different options with the same destination, which is
+perfectly OK.  (It just means you have to be a bit careful when setting
+default values{---}see below.)
+
+When \module{optparse} encounters \code{"-v"} on the command line, it sets
+\code{options.verbose} to \code{True}; when it encounters \code{"-q"},
+\code{options.verbose} is set to \code{False}.
+
+
+\subsubsection{Other actions\label{optparse-other-actions}}
+
+Some other actions supported by \module{optparse} are:
+\begin{description}
+\item[\code{store{\_}const}]
+store a constant value
+\item[\code{append}]
+append this option's argument to a list
+\item[\code{count}]
+increment a counter by one
+\item[\code{callback}]
+call a specified function
+\end{description}
+
+These are covered in section~\ref{optparse-reference-guide}, Reference Guide and section~\ref{optparse-option-callbacks}, Option Callbacks.
+
+
+\subsubsection{Default values\label{optparse-default-values}}
+
+All of the above examples involve setting some variable (the
+``destination'') when certain command-line options are seen.  What happens
+if those options are never seen?  Since we didn't supply any defaults,
+they are all set to \code{None}.  This is usually fine, but sometimes you
+want more control.  \module{optparse} lets you supply a default value for each
+destination, which is assigned before the command line is parsed.
+
+First, consider the verbose/quiet example.  If we want \module{optparse} to set
+\code{verbose} to \code{True} unless \code{"-q"} is seen, then we can do this:
+\begin{verbatim}
+parser.add_option("-v", action="store_true", dest="verbose", default=True)
+parser.add_option("-q", action="store_false", dest="verbose")
+\end{verbatim}
+
+Since default values apply to the \emph{destination} rather than to any
+particular option, and these two options happen to have the same
+destination, this is exactly equivalent:
+\begin{verbatim}
+parser.add_option("-v", action="store_true", dest="verbose")
+parser.add_option("-q", action="store_false", dest="verbose", default=True)
+\end{verbatim}
+
+Consider this:
+\begin{verbatim}
+parser.add_option("-v", action="store_true", dest="verbose", default=False)
+parser.add_option("-q", action="store_false", dest="verbose", default=True)
+\end{verbatim}
+
+Again, the default value for \code{verbose} will be \code{True}: the last
+default value supplied for any particular destination is the one that
+counts.
+
+A clearer way to specify default values is the \method{set{\_}defaults()}
+method of OptionParser, which you can call at any time before calling
+\method{parse{\_}args()}:
+\begin{verbatim}
+parser.set_defaults(verbose=True)
+parser.add_option(...)
+(options, args) = parser.parse_args()
+\end{verbatim}
+
+As before, the last value specified for a given option destination is
+the one that counts.  For clarity, try to use one method or the other of
+setting default values, not both.
+
+
+\subsubsection{Generating help\label{optparse-generating-help}}
+
+\module{optparse}'s ability to generate help and usage text automatically is useful
+for creating user-friendly command-line interfaces.  All you have to do
+is supply a \member{help} value for each option, and optionally a short usage
+message for your whole program.  Here's an OptionParser populated with
+user-friendly (documented) options:
+\begin{verbatim}
+usage = "usage: %prog [options] arg1 arg2"
+parser = OptionParser(usage=usage)
+parser.add_option("-v", "--verbose",
+                  action="store_true", dest="verbose", default=True,
+                  help="make lots of noise [default]")
+parser.add_option("-q", "--quiet",
+                  action="store_false", dest="verbose", 
+                  help="be vewwy quiet (I'm hunting wabbits)")
+parser.add_option("-f", "--filename",
+                  metavar="FILE", help="write output to FILE"),
+parser.add_option("-m", "--mode",
+                  default="intermediate",
+                  help="interaction mode: novice, intermediate, "
+                       "or expert [default: %default]")
+\end{verbatim}
+
+If \module{optparse} encounters either \code{"-h"} or \code{"-{}-help"} on the command-line,
+or if you just call \method{parser.print{\_}help()}, it prints the following to
+standard output:
+\begin{verbatim}
+usage: <yourscript> [options] arg1 arg2
+
+options:
+  -h, --help            show this help message and exit
+  -v, --verbose         make lots of noise [default]
+  -q, --quiet           be vewwy quiet (I'm hunting wabbits)
+  -f FILE, --filename=FILE
+                        write output to FILE
+  -m MODE, --mode=MODE  interaction mode: novice, intermediate, or
+                        expert [default: intermediate]
+\end{verbatim}
+
+(If the help output is triggered by a help option, \module{optparse} exits after
+printing the help text.)
+
+There's a lot going on here to help \module{optparse} generate the best possible
+help message:
+\begin{itemize}
+\item {} 
+the script defines its own usage message:
+\begin{verbatim}
+usage = "usage: %prog [options] arg1 arg2"
+\end{verbatim}
+
+\module{optparse} expands \code{"{\%}prog"} in the usage string to the name of the current
+program, i.e. \code{os.path.basename(sys.argv{[}0])}.  The expanded string
+is then printed before the detailed option help.
+
+If you don't supply a usage string, \module{optparse} uses a bland but sensible
+default: ``\code{usage: {\%}prog {[}options]"}, which is fine if your script
+doesn't take any positional arguments.
+
+\item {} 
+every option defines a help string, and doesn't worry about line-
+wrapping{---}\module{optparse} takes care of wrapping lines and making the
+help output look good.
+
+\item {} 
+options that take a value indicate this fact in their
+automatically-generated help message, e.g. for the ``mode'' option:
+\begin{verbatim}
+-m MODE, --mode=MODE
+\end{verbatim}
+
+Here, ``MODE'' is called the meta-variable: it stands for the argument
+that the user is expected to supply to \programopt{-m}/\longprogramopt{mode}.  By default,
+\module{optparse} converts the destination variable name to uppercase and uses
+that for the meta-variable.  Sometimes, that's not what you want{---}for example, the \longprogramopt{filename} option explicitly sets
+\code{metavar="FILE"}, resulting in this automatically-generated option
+description:
+\begin{verbatim}
+-f FILE, --filename=FILE
+\end{verbatim}
+
+This is important for more than just saving space, though: the
+manually written help text uses the meta-variable ``FILE'' to clue the
+user in that there's a connection between the semi-formal syntax ``-f
+FILE'' and the informal semantic description ``write output to FILE''.
+This is a simple but effective way to make your help text a lot
+clearer and more useful for end users.
+
+\item {} 
+options that have a default value can include \code{{\%}default} in
+the help string{---}\module{optparse} will replace it with \function{str()} of the
+option's default value.  If an option has no default value (or the
+default value is \code{None}), \code{{\%}default} expands to \code{none}.
+
+\end{itemize}
+
+
+\subsubsection{Printing a version string\label{optparse-printing-version-string}}
+
+Similar to the brief usage string, \module{optparse} can also print a version string
+for your program.  You have to supply the string as the \code{version}
+argument to OptionParser:
+\begin{verbatim}
+parser = OptionParser(usage="%prog [-f] [-q]", version="%prog 1.0")
+\end{verbatim}
+
+\code{"{\%}prog"} is expanded just like it is in \code{usage}.  Apart
+from that, \code{version} can contain anything you like.  When you supply
+it, \module{optparse} automatically adds a \code{"-{}-version"} option to your parser.
+If it encounters this option on the command line, it expands your
+\code{version} string (by replacing \code{"{\%}prog"}), prints it to stdout, and
+exits.
+
+For example, if your script is called \code{/usr/bin/foo}:
+\begin{verbatim}
+$ /usr/bin/foo --version
+foo 1.0
+\end{verbatim}
+
+
+\subsubsection{How \module{optparse} handles errors\label{optparse-how-optparse-handles-errors}}
+
+There are two broad classes of errors that \module{optparse} has to worry about:
+programmer errors and user errors.  Programmer errors are usually
+erroneous calls to \code{parser.add{\_}option()}, e.g. invalid option strings,
+unknown option attributes, missing option attributes, etc.  These are
+dealt with in the usual way: raise an exception (either
+\code{optparse.OptionError} or \code{TypeError}) and let the program crash.
+
+Handling user errors is much more important, since they are guaranteed
+to happen no matter how stable your code is.  \module{optparse} can automatically
+detect some user errors, such as bad option arguments (passing \code{"-n
+4x"} where \programopt{-n} takes an integer argument), missing arguments
+(\code{"-n"} at the end of the command line, where \programopt{-n} takes an argument
+of any type).  Also, you can call \code{parser.error()} to signal an
+application-defined error condition:
+\begin{verbatim}
+(options, args) = parser.parse_args()
+[...]
+if options.a and options.b:
+    parser.error("options -a and -b are mutually exclusive")
+\end{verbatim}
+
+In either case, \module{optparse} handles the error the same way: it prints the
+program's usage message and an error message to standard error and
+exits with error status 2.
+
+Consider the first example above, where the user passes \code{"4x"} to an
+option that takes an integer:
+\begin{verbatim}
+$ /usr/bin/foo -n 4x
+usage: foo [options]
+
+foo: error: option -n: invalid integer value: '4x'
+\end{verbatim}
+
+Or, where the user fails to pass a value at all:
+\begin{verbatim}
+$ /usr/bin/foo -n
+usage: foo [options]
+
+foo: error: -n option requires an argument
+\end{verbatim}
+
+\module{optparse}-generated error messages take care always to mention the option
+involved in the error; be sure to do the same when calling
+\code{parser.error()} from your application code.
+
+If \module{optparse}'s default error-handling behaviour does not suite your needs,
+you'll need to subclass OptionParser and override \code{exit()} and/or
+\method{error()}.
+
+
+\subsubsection{Putting it all together\label{optparse-putting-it-all-together}}
+
+Here's what \module{optparse}-based scripts usually look like:
+\begin{verbatim}
+from optparse import OptionParser
+[...]
+def main():
+    usage = "usage: %prog [options] arg"
+    parser = OptionParser(usage)
+    parser.add_option("-f", "--file", dest="filename",
+                      help="read data from FILENAME")
+    parser.add_option("-v", "--verbose",
+                      action="store_true", dest="verbose")
+    parser.add_option("-q", "--quiet",
+                      action="store_false", dest="verbose")
+    [...]
+    (options, args) = parser.parse_args()
+    if len(args) != 1:
+        parser.error("incorrect number of arguments")
+    if options.verbose:
+        print "reading %s..." % options.filename
+    [...]
+
+if __name__ == "__main__":
+    main()
+\end{verbatim}
+% $Id: tutorial.txt 515 2006-06-10 15:37:45Z gward $ 
+
+
+\subsection{Reference Guide\label{optparse-reference-guide}}
+
+
+\subsubsection{Creating the parser\label{optparse-creating-parser}}
+
+The first step in using \module{optparse} is to create an OptionParser instance:
+\begin{verbatim}
+parser = OptionParser(...)
+\end{verbatim}
+
+The OptionParser constructor has no required arguments, but a number of
+optional keyword arguments.  You should always pass them as keyword
+arguments, i.e. do not rely on the order in which the arguments are
+declared.
+\begin{quote}
+\begin{description}
+\item[\code{usage} (default: \code{"{\%}prog {[}options]"})]
+The usage summary to print when your program is run incorrectly or
+with a help option.  When \module{optparse} prints the usage string, it expands
+\code{{\%}prog} to \code{os.path.basename(sys.argv{[}0])} (or to \code{prog} if
+you passed that keyword argument).  To suppress a usage message,
+pass the special value \code{optparse.SUPPRESS{\_}USAGE}.
+\item[\code{option{\_}list} (default: \code{{[}]})]
+A list of Option objects to populate the parser with.  The options
+in \code{option{\_}list} are added after any options in
+\code{standard{\_}option{\_}list} (a class attribute that may be set by
+OptionParser subclasses), but before any version or help options.
+Deprecated; use \method{add{\_}option()} after creating the parser instead.
+\item[\code{option{\_}class} (default: optparse.Option)]
+Class to use when adding options to the parser in \method{add{\_}option()}.
+\item[\code{version} (default: \code{None})]
+A version string to print when the user supplies a version option.
+If you supply a true value for \code{version}, \module{optparse} automatically adds
+a version option with the single option string \code{"-{}-version"}.  The
+substring \code{"{\%}prog"} is expanded the same as for \code{usage}.
+\item[\code{conflict{\_}handler} (default: \code{"error"})]
+Specifies what to do when options with conflicting option strings
+are added to the parser; see section~\ref{optparse-conflicts-between-options}, Conflicts between options.
+\item[\code{description} (default: \code{None})]
+A paragraph of text giving a brief overview of your program.  \module{optparse}
+reformats this paragraph to fit the current terminal width and
+prints it when the user requests help (after \code{usage}, but before
+the list of options).
+\item[\code{formatter} (default: a new IndentedHelpFormatter)]
+An instance of optparse.HelpFormatter that will be used for
+printing help text.  \module{optparse} provides two concrete classes for this
+purpose: IndentedHelpFormatter and TitledHelpFormatter.
+\item[\code{add{\_}help{\_}option} (default: \code{True})]
+If true, \module{optparse} will add a help option (with option strings \code{"-h"}
+and \code{"-{}-help"}) to the parser.
+\item[\code{prog}]
+The string to use when expanding \code{"{\%}prog"} in \code{usage} and
+\code{version} instead of \code{os.path.basename(sys.argv{[}0])}.
+\end{description}
+\end{quote}
+
+
+\subsubsection{Populating the parser\label{optparse-populating-parser}}
+
+There are several ways to populate the parser with options.  The
+preferred way is by using \code{OptionParser.add{\_}option()}, as shown in
+section~\ref{optparse-tutorial}, the tutorial.  \method{add{\_}option()} can be called in one of two
+ways:
+\begin{itemize}
+\item {} 
+pass it an Option instance (as returned by \function{make{\_}option()})
+
+\item {} 
+pass it any combination of positional and keyword arguments that are
+acceptable to \function{make{\_}option()} (i.e., to the Option constructor),
+and it will create the Option instance for you
+
+\end{itemize}
+
+The other alternative is to pass a list of pre-constructed Option
+instances to the OptionParser constructor, as in:
+\begin{verbatim}
+option_list = [
+    make_option("-f", "--filename",
+                action="store", type="string", dest="filename"),
+    make_option("-q", "--quiet",
+                action="store_false", dest="verbose"),
+    ]
+parser = OptionParser(option_list=option_list)
+\end{verbatim}
+
+(\function{make{\_}option()} is a factory function for creating Option instances;
+currently it is an alias for the Option constructor.  A future version
+of \module{optparse} may split Option into several classes, and \function{make{\_}option()}
+will pick the right class to instantiate.  Do not instantiate Option
+directly.)
+
+
+\subsubsection{Defining options\label{optparse-defining-options}}
+
+Each Option instance represents a set of synonymous command-line option
+strings, e.g. \programopt{-f} and \longprogramopt{file}.  You can
+specify any number of short or long option strings, but you must specify
+at least one overall option string.
+
+The canonical way to create an Option instance is with the
+\method{add{\_}option()} method of \class{OptionParser}:
+\begin{verbatim}
+parser.add_option(opt_str[, ...], attr=value, ...)
+\end{verbatim}
+
+To define an option with only a short option string:
+\begin{verbatim}
+parser.add_option("-f", attr=value, ...)
+\end{verbatim}
+
+And to define an option with only a long option string:
+\begin{verbatim}
+parser.add_option("--foo", attr=value, ...)
+\end{verbatim}
+
+The keyword arguments define attributes of the new Option object.  The
+most important option attribute is \member{action}, and it largely determines
+which other attributes are relevant or required.  If you pass irrelevant
+option attributes, or fail to pass required ones, \module{optparse} raises an
+OptionError exception explaining your mistake.
+
+An options's \emph{action} determines what \module{optparse} does when it encounters this
+option on the command-line.  The standard option actions hard-coded into
+\module{optparse} are:
+\begin{description}
+\item[\code{store}]
+store this option's argument (default)
+\item[\code{store{\_}const}]
+store a constant value
+\item[\code{store{\_}true}]
+store a true value
+\item[\code{store{\_}false}]
+store a false value
+\item[\code{append}]
+append this option's argument to a list
+\item[\code{append{\_}const}]
+append a constant value to a list
+\item[\code{count}]
+increment a counter by one
+\item[\code{callback}]
+call a specified function
+\item[\member{help}]
+print a usage message including all options and the
+documentation for them
+\end{description}
+
+(If you don't supply an action, the default is \code{store}.  For this
+action, you may also supply \member{type} and \member{dest} option attributes; see
+below.)
+
+As you can see, most actions involve storing or updating a value
+somewhere.  \module{optparse} always creates a special object for this,
+conventionally called \code{options} (it happens to be an instance of
+\code{optparse.Values}).  Option arguments (and various other values) are
+stored as attributes of this object, according to the \member{dest}
+(destination) option attribute.
+
+For example, when you call
+\begin{verbatim}
+parser.parse_args()
+\end{verbatim}
+
+one of the first things \module{optparse} does is create the \code{options} object:
+\begin{verbatim}
+options = Values()
+\end{verbatim}
+
+If one of the options in this parser is defined with
+\begin{verbatim}
+parser.add_option("-f", "--file", action="store", type="string", dest="filename")
+\end{verbatim}
+
+and the command-line being parsed includes any of the following:
+\begin{verbatim}
+-ffoo
+-f foo
+--file=foo
+--file foo
+\end{verbatim}
+
+then \module{optparse}, on seeing this option, will do the equivalent of
+\begin{verbatim}
+options.filename = "foo"
+\end{verbatim}
+
+The \member{type} and \member{dest} option attributes are almost as important as
+\member{action}, but \member{action} is the only one that makes sense for \emph{all}
+options.
+
+
+\subsubsection{Standard option actions\label{optparse-standard-option-actions}}
+
+The various option actions all have slightly different requirements and
+effects.  Most actions have several relevant option attributes which you
+may specify to guide \module{optparse}'s behaviour; a few have required attributes,
+which you must specify for any option using that action.
+\begin{itemize}
+\item {} 
+\code{store} {[}relevant: \member{type}, \member{dest}, \code{nargs}, \code{choices}]
+
+The option must be followed by an argument, which is
+converted to a value according to \member{type} and stored in
+\member{dest}.  If \code{nargs} {\textgreater} 1, multiple arguments will be consumed
+from the command line; all will be converted according to
+\member{type} and stored to \member{dest} as a tuple.  See the ``Option
+types'' section below.
+
+If \code{choices} is supplied (a list or tuple of strings), the type
+defaults to \code{choice}.
+
+If \member{type} is not supplied, it defaults to \code{string}.
+
+If \member{dest} is not supplied, \module{optparse} derives a destination from the
+first long option string (e.g., \code{"-{}-foo-bar"} implies \code{foo{\_}bar}).
+If there are no long option strings, \module{optparse} derives a destination from
+the first short option string (e.g., \code{"-f"} implies \code{f}).
+
+Example:
+\begin{verbatim}
+parser.add_option("-f")
+parser.add_option("-p", type="float", nargs=3, dest="point")
+\end{verbatim}
+
+As it parses the command line
+\begin{verbatim}
+-f foo.txt -p 1 -3.5 4 -fbar.txt
+\end{verbatim}
+
+\module{optparse} will set
+\begin{verbatim}
+options.f = "foo.txt"
+options.point = (1.0, -3.5, 4.0)
+options.f = "bar.txt"
+\end{verbatim}
+
+\item {} 
+\code{store{\_}const} {[}required: \code{const}; relevant: \member{dest}]
+
+The value \code{const} is stored in \member{dest}.
+
+Example:
+\begin{verbatim}
+parser.add_option("-q", "--quiet",
+                  action="store_const", const=0, dest="verbose")
+parser.add_option("-v", "--verbose",
+                  action="store_const", const=1, dest="verbose")
+parser.add_option("--noisy",
+                  action="store_const", const=2, dest="verbose")
+\end{verbatim}
+
+If \code{"-{}-noisy"} is seen, \module{optparse} will set
+\begin{verbatim}
+options.verbose = 2
+\end{verbatim}
+
+\item {} 
+\code{store{\_}true} {[}relevant: \member{dest}]
+
+A special case of \code{store{\_}const} that stores a true value
+to \member{dest}.
+
+\item {} 
+\code{store{\_}false} {[}relevant: \member{dest}]
+
+Like \code{store{\_}true}, but stores a false value.
+
+Example:
+\begin{verbatim}
+parser.add_option("--clobber", action="store_true", dest="clobber")
+parser.add_option("--no-clobber", action="store_false", dest="clobber")
+\end{verbatim}
+
+\item {} 
+\code{append} {[}relevant: \member{type}, \member{dest}, \code{nargs}, \code{choices}]
+
+The option must be followed by an argument, which is appended to the
+list in \member{dest}.  If no default value for \member{dest} is supplied, an
+empty list is automatically created when \module{optparse} first encounters this
+option on the command-line.  If \code{nargs} {\textgreater} 1, multiple arguments are
+consumed, and a tuple of length \code{nargs} is appended to \member{dest}.
+
+The defaults for \member{type} and \member{dest} are the same as for the
+\code{store} action.
+
+Example:
+\begin{verbatim}
+parser.add_option("-t", "--tracks", action="append", type="int")
+\end{verbatim}
+
+If \code{"-t3"} is seen on the command-line, \module{optparse} does the equivalent of:
+\begin{verbatim}
+options.tracks = []
+options.tracks.append(int("3"))
+\end{verbatim}
+
+If, a little later on, \code{"-{}-tracks=4"} is seen, it does:
+\begin{verbatim}
+options.tracks.append(int("4"))
+\end{verbatim}
+
+\item {} 
+\code{append{\_}const} {[}required: \code{const}; relevant: \member{dest}]
+
+Like \code{store{\_}const}, but the value \code{const} is appended to \member{dest};
+as with \code{append}, \member{dest} defaults to \code{None}, and an an empty list is
+automatically created the first time the option is encountered.
+
+\item {} 
+\code{count} {[}relevant: \member{dest}]
+
+Increment the integer stored at \member{dest}.  If no default value is
+supplied, \member{dest} is set to zero before being incremented the first
+time.
+
+Example:
+\begin{verbatim}
+parser.add_option("-v", action="count", dest="verbosity")
+\end{verbatim}
+
+The first time \code{"-v"} is seen on the command line, \module{optparse} does the
+equivalent of:
+\begin{verbatim}
+options.verbosity = 0
+options.verbosity += 1
+\end{verbatim}
+
+Every subsequent occurrence of \code{"-v"} results in
+\begin{verbatim}
+options.verbosity += 1
+\end{verbatim}
+
+\item {} 
+\code{callback} {[}required: \code{callback};
+relevant: \member{type}, \code{nargs}, \code{callback{\_}args}, \code{callback{\_}kwargs}]
+
+Call the function specified by \code{callback}, which is called as
+\begin{verbatim}
+func(option, opt_str, value, parser, *args, **kwargs)
+\end{verbatim}
+
+See section~\ref{optparse-option-callbacks}, Option Callbacks for more detail.
+
+\item {} 
+\member{help}
+
+Prints a complete help message for all the options in the
+current option parser.  The help message is constructed from
+the \code{usage} string passed to OptionParser's constructor and
+the \member{help} string passed to every option.
+
+If no \member{help} string is supplied for an option, it will still be
+listed in the help message.  To omit an option entirely, use
+the special value \code{optparse.SUPPRESS{\_}HELP}.
+
+\module{optparse} automatically adds a \member{help} option to all OptionParsers, so
+you do not normally need to create one.
+
+Example:
+\begin{verbatim}
+from optparse import OptionParser, SUPPRESS_HELP
+
+parser = OptionParser()
+parser.add_option("-h", "--help", action="help"),
+parser.add_option("-v", action="store_true", dest="verbose",
+                  help="Be moderately verbose")
+parser.add_option("--file", dest="filename",
+                  help="Input file to read data from"),
+parser.add_option("--secret", help=SUPPRESS_HELP)
+\end{verbatim}
+
+If \module{optparse} sees either \code{"-h"} or \code{"-{}-help"} on the command line, it
+will print something like the following help message to stdout
+(assuming \code{sys.argv{[}0]} is \code{"foo.py"}):
+\begin{verbatim}
+usage: foo.py [options]
+
+options:
+  -h, --help        Show this help message and exit
+  -v                Be moderately verbose
+  --file=FILENAME   Input file to read data from
+\end{verbatim}
+
+After printing the help message, \module{optparse} terminates your process
+with \code{sys.exit(0)}.
+
+\item {} 
+\code{version}
+
+Prints the version number supplied to the OptionParser to stdout and
+exits.  The version number is actually formatted and printed by the
+\code{print{\_}version()} method of OptionParser.  Generally only relevant
+if the \code{version} argument is supplied to the OptionParser
+constructor.  As with \member{help} options, you will rarely create
+\code{version} options, since \module{optparse} automatically adds them when needed.
+
+\end{itemize}
+
+
+\subsubsection{Option attributes\label{optparse-option-attributes}}
+
+The following option attributes may be passed as keyword arguments
+to \code{parser.add{\_}option()}.  If you pass an option attribute
+that is not relevant to a particular option, or fail to pass a required
+option attribute, \module{optparse} raises OptionError.
+\begin{itemize}
+\item {} 
+\member{action} (default: \code{"store"})
+
+Determines \module{optparse}'s behaviour when this option is seen on the command
+line; the available options are documented above.
+
+\item {} 
+\member{type} (default: \code{"string"})
+
+The argument type expected by this option (e.g., \code{"string"} or
+\code{"int"}); the available option types are documented below.
+
+\item {} 
+\member{dest} (default: derived from option strings)
+
+If the option's action implies writing or modifying a value somewhere,
+this tells \module{optparse} where to write it: \member{dest} names an attribute of the
+\code{options} object that \module{optparse} builds as it parses the command line.
+
+\item {} 
+\code{default} (deprecated)
+
+The value to use for this option's destination if the option is not
+seen on the command line.  Deprecated; use \code{parser.set{\_}defaults()}
+instead.
+
+\item {} 
+\code{nargs} (default: 1)
+
+How many arguments of type \member{type} should be consumed when this
+option is seen.  If {\textgreater} 1, \module{optparse} will store a tuple of values to
+\member{dest}.
+
+\item {} 
+\code{const}
+
+For actions that store a constant value, the constant value to store.
+
+\item {} 
+\code{choices}
+
+For options of type \code{"choice"}, the list of strings the user
+may choose from.
+
+\item {} 
+\code{callback}
+
+For options with action \code{"callback"}, the callable to call when this
+option is seen.  See section~\ref{optparse-option-callbacks}, Option Callbacks for detail on the arguments
+passed to \code{callable}.
+
+\item {} 
+\code{callback{\_}args}, \code{callback{\_}kwargs}
+
+Additional positional and keyword arguments to pass to \code{callback}
+after the four standard callback arguments.
+
+\item {} 
+\member{help}
+
+Help text to print for this option when listing all available options
+after the user supplies a \member{help} option (such as \code{"-{}-help"}).
+If no help text is supplied, the option will be listed without help
+text.  To hide this option, use the special value \code{SUPPRESS{\_}HELP}.
+
+\item {} 
+\code{metavar} (default: derived from option strings)
+
+Stand-in for the option argument(s) to use when printing help text.
+See section~\ref{optparse-tutorial}, the tutorial for an example.
+
+\end{itemize}
+
+
+\subsubsection{Standard option types\label{optparse-standard-option-types}}
+
+\module{optparse} has six built-in option types: \code{string}, \code{int}, \code{long},
+\code{choice}, \code{float} and \code{complex}.  If you need to add new option
+types, see section~\ref{optparse-extending-optparse}, Extending \module{optparse}.
+
+Arguments to string options are not checked or converted in any way: the
+text on the command line is stored in the destination (or passed to the
+callback) as-is.
+
+Integer arguments (type \code{int} or \code{long}) are parsed as follows:
+\begin{quote}
+\begin{itemize}
+\item {} 
+if the number starts with \code{0x}, it is parsed as a hexadecimal number
+
+\item {} 
+if the number starts with \code{0}, it is parsed as an octal number
+
+\item {} 
+if the number starts with \code{0b}, is is parsed as a binary number
+
+\item {} 
+otherwise, the number is parsed as a decimal number
+
+\end{itemize}
+\end{quote}
+
+The conversion is done by calling either \code{int()} or \code{long()} with
+the appropriate base (2, 8, 10, or 16).  If this fails, so will \module{optparse},
+although with a more useful error message.
+
+\code{float} and \code{complex} option arguments are converted directly with
+\code{float()} and \code{complex()}, with similar error-handling.
+
+\code{choice} options are a subtype of \code{string} options.  The \code{choices}
+option attribute (a sequence of strings) defines the set of allowed
+option arguments.  \code{optparse.check{\_}choice()} compares
+user-supplied option arguments against this master list and raises
+OptionValueError if an invalid string is given.
+
+
+\subsubsection{Parsing arguments\label{optparse-parsing-arguments}}
+
+The whole point of creating and populating an OptionParser is to call
+its \method{parse{\_}args()} method:
+\begin{verbatim}
+(options, args) = parser.parse_args(args=None, options=None)
+\end{verbatim}
+
+where the input parameters are
+\begin{description}
+\item[\code{args}]
+the list of arguments to process (default: \code{sys.argv{[}1:]})
+\item[\code{options}]
+object to store option arguments in (default: a new instance of
+optparse.Values)
+\end{description}
+
+and the return values are
+\begin{description}
+\item[\code{options}]
+the same object that was passed in as \code{options}, or the
+optparse.Values instance created by \module{optparse}
+\item[\code{args}]
+the leftover positional arguments after all options have been
+processed
+\end{description}
+
+The most common usage is to supply neither keyword argument.  If you
+supply \code{options}, it will be modified with repeated \code{setattr()}
+calls (roughly one for every option argument stored to an option
+destination) and returned by \method{parse{\_}args()}.
+
+If \method{parse{\_}args()} encounters any errors in the argument list, it calls
+the OptionParser's \method{error()} method with an appropriate end-user error
+message.  This ultimately terminates your process with an exit status of
+2 (the traditional \UNIX{} exit status for command-line errors).
+
+
+\subsubsection{Querying and manipulating your option parser\label{optparse-querying-manipulating-option-parser}}
+
+Sometimes, it's useful to poke around your option parser and see what's
+there.  OptionParser provides a couple of methods to help you out:
+\begin{description}
+\item[\code{has{\_}option(opt{\_}str)}]
+Return true if the OptionParser has an option with 
+option string \code{opt{\_}str} (e.g., \code{"-q"} or \code{"-{}-verbose"}).
+\item[\code{get{\_}option(opt{\_}str)}]
+Returns the Option instance with the option string \code{opt{\_}str}, or
+\code{None} if no options have that option string.
+\item[\code{remove{\_}option(opt{\_}str)}]
+If the OptionParser has an option corresponding to \code{opt{\_}str},
+that option is removed.  If that option provided any other
+option strings, all of those option strings become invalid.
+If \code{opt{\_}str} does not occur in any option belonging to this
+OptionParser, raises ValueError.
+\end{description}
+
+
+\subsubsection{Conflicts between options\label{optparse-conflicts-between-options}}
+
+If you're not careful, it's easy to define options with conflicting
+option strings:
+\begin{verbatim}
+parser.add_option("-n", "--dry-run", ...)
+[...]
+parser.add_option("-n", "--noisy", ...)
+\end{verbatim}
+
+(This is particularly true if you've defined your own OptionParser
+subclass with some standard options.)
+
+Every time you add an option, \module{optparse} checks for conflicts with existing
+options.  If it finds any, it invokes the current conflict-handling
+mechanism.  You can set the conflict-handling mechanism either in the
+constructor:
+\begin{verbatim}
+parser = OptionParser(..., conflict_handler=handler)
+\end{verbatim}
+
+or with a separate call:
+\begin{verbatim}
+parser.set_conflict_handler(handler)
+\end{verbatim}
+
+The available conflict handlers are:
+\begin{quote}
+\begin{description}
+\item[\code{error} (default)]
+assume option conflicts are a programming error and raise 
+OptionConflictError
+\item[\code{resolve}]
+resolve option conflicts intelligently (see below)
+\end{description}
+\end{quote}
+
+As an example, let's define an OptionParser that resolves conflicts
+intelligently and add conflicting options to it:
+\begin{verbatim}
+parser = OptionParser(conflict_handler="resolve")
+parser.add_option("-n", "--dry-run", ..., help="do no harm")
+parser.add_option("-n", "--noisy", ..., help="be noisy")
+\end{verbatim}
+
+At this point, \module{optparse} detects that a previously-added option is already
+using the \code{"-n"} option string.  Since \code{conflict{\_}handler} is
+\code{"resolve"}, it resolves the situation by removing \code{"-n"} from the
+earlier option's list of option strings.  Now \code{"-{}-dry-run"} is the
+only way for the user to activate that option.  If the user asks for
+help, the help message will reflect that:
+\begin{verbatim}
+options:
+  --dry-run     do no harm
+  [...]
+  -n, --noisy   be noisy
+\end{verbatim}
+
+It's possible to whittle away the option strings for a previously-added
+option until there are none left, and the user has no way of invoking
+that option from the command-line.  In that case, \module{optparse} removes that
+option completely, so it doesn't show up in help text or anywhere else.
+Carrying on with our existing OptionParser:
+\begin{verbatim}
+parser.add_option("--dry-run", ..., help="new dry-run option")
+\end{verbatim}
+
+At this point, the original \programopt{-n/-{}-dry-run} option is no longer
+accessible, so \module{optparse} removes it, leaving this help text:
+\begin{verbatim}
+options:
+  [...]
+  -n, --noisy   be noisy
+  --dry-run     new dry-run option
+\end{verbatim}
+
+
+\subsubsection{Cleanup\label{optparse-cleanup}}
+
+OptionParser instances have several cyclic references.  This should not
+be a problem for Python's garbage collector, but you may wish to break
+the cyclic references explicitly by calling \code{destroy()} on your
+OptionParser once you are done with it.  This is particularly useful in
+long-running applications where large object graphs are reachable from
+your OptionParser.
+
+
+\subsubsection{Other methods\label{optparse-other-methods}}
+
+OptionParser supports several other public methods:
+\begin{itemize}
+\item {} 
+\code{set{\_}usage(usage)}
+
+Set the usage string according to the rules described above for the
+\code{usage} constructor keyword argument.  Passing \code{None} sets the
+default usage string; use \code{SUPPRESS{\_}USAGE} to suppress a usage
+message.
+
+\item {} 
+\code{enable{\_}interspersed{\_}args()}, \code{disable{\_}interspersed{\_}args()}
+
+Enable/disable positional arguments interspersed with options, similar
+to GNU getopt (enabled by default).  For example, if \code{"-a"} and
+\code{"-b"} are both simple options that take no arguments, \module{optparse}
+normally accepts this syntax:
+\begin{verbatim}
+prog -a arg1 -b arg2
+\end{verbatim}
+
+and treats it as equivalent to
+\begin{verbatim}
+prog -a -b arg1 arg2
+\end{verbatim}
+
+To disable this feature, call \code{disable{\_}interspersed{\_}args()}.  This
+restores traditional \UNIX{} syntax, where option parsing stops with the
+first non-option argument.
+
+\item {} 
+\code{set{\_}defaults(dest=value, ...)}
+
+Set default values for several option destinations at once.  Using
+\method{set{\_}defaults()} is the preferred way to set default values for
+options, since multiple options can share the same destination.  For
+example, if several ``mode'' options all set the same destination, any
+one of them can set the default, and the last one wins:
+\begin{verbatim}
+parser.add_option("--advanced", action="store_const",
+                  dest="mode", const="advanced",
+                  default="novice")    # overridden below
+parser.add_option("--novice", action="store_const",
+                  dest="mode", const="novice",
+                  default="advanced")  # overrides above setting
+\end{verbatim}
+
+To avoid this confusion, use \method{set{\_}defaults()}:
+\begin{verbatim}
+parser.set_defaults(mode="advanced")
+parser.add_option("--advanced", action="store_const",
+                  dest="mode", const="advanced")
+parser.add_option("--novice", action="store_const",
+                  dest="mode", const="novice")
+\end{verbatim}
+
+\end{itemize}
+% $Id: reference.txt 519 2006-06-11 14:39:11Z gward $ 
+
+
+\subsection{Option Callbacks\label{optparse-option-callbacks}}
+
+When \module{optparse}'s built-in actions and types aren't quite enough for your
+needs, you have two choices: extend \module{optparse} or define a callback option.
+Extending \module{optparse} is more general, but overkill for a lot of simple
+cases.  Quite often a simple callback is all you need.
+
+There are two steps to defining a callback option:
+\begin{itemize}
+\item {} 
+define the option itself using the \code{callback} action
+
+\item {} 
+write the callback; this is a function (or method) that
+takes at least four arguments, as described below
+
+\end{itemize}
+
+
+\subsubsection{Defining a callback option\label{optparse-defining-callback-option}}
+
+As always, the easiest way to define a callback option is by using the
+\code{parser.add{\_}option()} method.  Apart from \member{action}, the only option
+attribute you must specify is \code{callback}, the function to call:
+\begin{verbatim}
+parser.add_option("-c", action="callback", callback=my_callback)
+\end{verbatim}
+
+\code{callback} is a function (or other callable object), so you must have
+already defined \code{my{\_}callback()} when you create this callback option.
+In this simple case, \module{optparse} doesn't even know if \programopt{-c} takes any
+arguments, which usually means that the option takes no arguments{---}the
+mere presence of \programopt{-c} on the command-line is all it needs to know.  In
+some circumstances, though, you might want your callback to consume an
+arbitrary number of command-line arguments.  This is where writing
+callbacks gets tricky; it's covered later in this section.
+
+\module{optparse} always passes four particular arguments to your callback, and it
+will only pass additional arguments if you specify them via
+\code{callback{\_}args} and \code{callback{\_}kwargs}.  Thus, the minimal callback
+function signature is:
+\begin{verbatim}
+def my_callback(option, opt, value, parser):
+\end{verbatim}
+
+The four arguments to a callback are described below.
+
+There are several other option attributes that you can supply when you
+define a callback option:
+\begin{description}
+\item[\member{type}]
+has its usual meaning: as with the \code{store} or \code{append} actions,
+it instructs \module{optparse} to consume one argument and convert it to
+\member{type}.  Rather than storing the converted value(s) anywhere,
+though, \module{optparse} passes it to your callback function.
+\item[\code{nargs}]
+also has its usual meaning: if it is supplied and {\textgreater} 1, \module{optparse} will
+consume \code{nargs} arguments, each of which must be convertible to
+\member{type}.  It then passes a tuple of converted values to your
+callback.
+\item[\code{callback{\_}args}]
+a tuple of extra positional arguments to pass to the callback
+\item[\code{callback{\_}kwargs}]
+a dictionary of extra keyword arguments to pass to the callback
+\end{description}
+
+
+\subsubsection{How callbacks are called\label{optparse-how-callbacks-called}}
+
+All callbacks are called as follows:
+\begin{verbatim}
+func(option, opt_str, value, parser, *args, **kwargs)
+\end{verbatim}
+
+where
+\begin{description}
+\item[\code{option}]
+is the Option instance that's calling the callback
+\item[\code{opt{\_}str}]
+is the option string seen on the command-line that's triggering the
+callback.  (If an abbreviated long option was used, \code{opt{\_}str} will
+be the full, canonical option string{---}e.g. if the user puts
+\code{"-{}-foo"} on the command-line as an abbreviation for
+\code{"-{}-foobar"}, then \code{opt{\_}str} will be \code{"-{}-foobar"}.)
+\item[\code{value}]
+is the argument to this option seen on the command-line.  \module{optparse} will
+only expect an argument if \member{type} is set; the type of \code{value}
+will be the type implied by the option's type.  If \member{type} for this
+option is \code{None} (no argument expected), then \code{value} will be
+\code{None}.  If \code{nargs} {\textgreater} 1, \code{value} will be a tuple of values of
+the appropriate type.
+\item[\code{parser}]
+is the OptionParser instance driving the whole thing, mainly
+useful because you can access some other interesting data through
+its instance attributes:
+\begin{description}
+\item[\code{parser.largs}]
+the current list of leftover arguments, ie. arguments that have
+been consumed but are neither options nor option arguments.
+Feel free to modify \code{parser.largs}, e.g. by adding more
+arguments to it.  (This list will become \code{args}, the second
+return value of \method{parse{\_}args()}.)
+\item[\code{parser.rargs}]
+the current list of remaining arguments, ie. with \code{opt{\_}str} and
+\code{value} (if applicable) removed, and only the arguments
+following them still there.  Feel free to modify
+\code{parser.rargs}, e.g. by consuming more arguments.
+\item[\code{parser.values}]
+the object where option values are by default stored (an
+instance of optparse.OptionValues).  This lets callbacks use the
+same mechanism as the rest of \module{optparse} for storing option values;
+you don't need to mess around with globals or closures.  You can
+also access or modify the value(s) of any options already
+encountered on the command-line.
+\end{description}
+\item[\code{args}]
+is a tuple of arbitrary positional arguments supplied via the
+\code{callback{\_}args} option attribute.
+\item[\code{kwargs}]
+is a dictionary of arbitrary keyword arguments supplied via
+\code{callback{\_}kwargs}.
+\end{description}
+
+
+\subsubsection{Raising errors in a callback\label{optparse-raising-errors-in-callback}}
+
+The callback function should raise OptionValueError if there are any
+problems with the option or its argument(s).  \module{optparse} catches this and
+terminates the program, printing the error message you supply to
+stderr.  Your message should be clear, concise, accurate, and mention
+the option at fault.  Otherwise, the user will have a hard time
+figuring out what he did wrong.
+
+
+\subsubsection{Callback example 1: trivial callback\label{optparse-callback-example-1}}
+
+Here's an example of a callback option that takes no arguments, and
+simply records that the option was seen:
+\begin{verbatim}
+def record_foo_seen(option, opt_str, value, parser):
+    parser.saw_foo = True
+
+parser.add_option("--foo", action="callback", callback=record_foo_seen)
+\end{verbatim}
+
+Of course, you could do that with the \code{store{\_}true} action.
+
+
+\subsubsection{Callback example 2: check option order\label{optparse-callback-example-2}}
+
+Here's a slightly more interesting example: record the fact that
+\code{"-a"} is seen, but blow up if it comes after \code{"-b"} in the
+command-line.
+\begin{verbatim}
+def check_order(option, opt_str, value, parser):
+    if parser.values.b:
+        raise OptionValueError("can't use -a after -b")
+    parser.values.a = 1
+[...]
+parser.add_option("-a", action="callback", callback=check_order)
+parser.add_option("-b", action="store_true", dest="b")
+\end{verbatim}
+
+
+\subsubsection{Callback example 3: check option order (generalized)\label{optparse-callback-example-3}}
+
+If you want to re-use this callback for several similar options (set a
+flag, but blow up if \code{"-b"} has already been seen), it needs a bit of
+work: the error message and the flag that it sets must be
+generalized.
+\begin{verbatim}
+def check_order(option, opt_str, value, parser):
+    if parser.values.b:
+        raise OptionValueError("can't use %s after -b" % opt_str)
+    setattr(parser.values, option.dest, 1)
+[...]
+parser.add_option("-a", action="callback", callback=check_order, dest='a')
+parser.add_option("-b", action="store_true", dest="b")
+parser.add_option("-c", action="callback", callback=check_order, dest='c')
+\end{verbatim}
+
+
+\subsubsection{Callback example 4: check arbitrary condition\label{optparse-callback-example-4}}
+
+Of course, you could put any condition in there{---}you're not limited
+to checking the values of already-defined options.  For example, if
+you have options that should not be called when the moon is full, all
+you have to do is this:
+\begin{verbatim}
+def check_moon(option, opt_str, value, parser):
+    if is_moon_full():
+        raise OptionValueError("%s option invalid when moon is full"
+                               % opt_str)
+    setattr(parser.values, option.dest, 1)
+[...]
+parser.add_option("--foo",
+                  action="callback", callback=check_moon, dest="foo")
+\end{verbatim}
+
+(The definition of \code{is{\_}moon{\_}full()} is left as an exercise for the
+reader.)
+
+
+\subsubsection{Callback example 5: fixed arguments\label{optparse-callback-example-5}}
+
+Things get slightly more interesting when you define callback options
+that take a fixed number of arguments.  Specifying that a callback
+option takes arguments is similar to defining a \code{store} or \code{append}
+option: if you define \member{type}, then the option takes one argument that
+must be convertible to that type; if you further define \code{nargs}, then
+the option takes \code{nargs} arguments.
+
+Here's an example that just emulates the standard \code{store} action:
+\begin{verbatim}
+def store_value(option, opt_str, value, parser):
+    setattr(parser.values, option.dest, value)
+[...]
+parser.add_option("--foo",
+                  action="callback", callback=store_value,
+                  type="int", nargs=3, dest="foo")
+\end{verbatim}
+
+Note that \module{optparse} takes care of consuming 3 arguments and converting them
+to integers for you; all you have to do is store them.  (Or whatever;
+obviously you don't need a callback for this example.)
+
+
+\subsubsection{Callback example 6: variable arguments\label{optparse-callback-example-6}}
+
+Things get hairy when you want an option to take a variable number of
+arguments.  For this case, you must write a callback, as \module{optparse} doesn't
+provide any built-in capabilities for it.  And you have to deal with
+certain intricacies of conventional \UNIX{} command-line parsing that \module{optparse}
+normally handles for you.  In particular, callbacks should implement
+the conventional rules for bare \code{"-{}-"} and \code{"-"} arguments:
+\begin{itemize}
+\item {} 
+either \code{"-{}-"} or \code{"-"} can be option arguments
+
+\item {} 
+bare \code{"-{}-"} (if not the argument to some option): halt command-line
+processing and discard the \code{"-{}-"}
+
+\item {} 
+bare \code{"-"} (if not the argument to some option): halt command-line
+processing but keep the \code{"-"} (append it to \code{parser.largs})
+
+\end{itemize}
+
+If you want an option that takes a variable number of arguments, there
+are several subtle, tricky issues to worry about.  The exact
+implementation you choose will be based on which trade-offs you're
+willing to make for your application (which is why \module{optparse} doesn't support
+this sort of thing directly).
+
+Nevertheless, here's a stab at a callback for an option with variable
+arguments:
+\begin{verbatim}
+def vararg_callback(option, opt_str, value, parser):
+    assert value is None
+    done = 0
+    value = []
+    rargs = parser.rargs
+    while rargs:
+        arg = rargs[0]
+
+        # Stop if we hit an arg like "--foo", "-a", "-fx", "--file=f",
+        # etc.  Note that this also stops on "-3" or "-3.0", so if
+        # your option takes numeric values, you will need to handle
+        # this.
+        if ((arg[:2] == "--" and len(arg) > 2) or
+            (arg[:1] == "-" and len(arg) > 1 and arg[1] != "-")):
+            break
+        else:
+            value.append(arg)
+            del rargs[0]
+
+     setattr(parser.values, option.dest, value)
+
+[...]
+parser.add_option("-c", "--callback",
+                  action="callback", callback=varargs)
+\end{verbatim}
+
+The main weakness with this particular implementation is that negative
+numbers in the arguments following \code{"-c"} will be interpreted as
+further options (probably causing an error), rather than as arguments to
+\code{"-c"}.  Fixing this is left as an exercise for the reader.
+% $Id: callbacks.txt 415 2004-09-30 02:26:17Z greg $ 
+
+
+\subsection{Extending \module{optparse}\label{optparse-extending-optparse}}
+
+Since the two major controlling factors in how \module{optparse} interprets
+command-line options are the action and type of each option, the most
+likely direction of extension is to add new actions and new types.
+
+
+\subsubsection{Adding new types\label{optparse-adding-new-types}}
+
+To add new types, you need to define your own subclass of \module{optparse}'s Option
+class.  This class has a couple of attributes that define \module{optparse}'s types:
+\member{TYPES} and \member{TYPE{\_}CHECKER}.
+
+\member{TYPES} is a tuple of type names; in your subclass, simply define a new
+tuple \member{TYPES} that builds on the standard one.
+
+\member{TYPE{\_}CHECKER} is a dictionary mapping type names to type-checking
+functions.  A type-checking function has the following signature:
+\begin{verbatim}
+def check_mytype(option, opt, value)
+\end{verbatim}
+
+where \code{option} is an \class{Option} instance, \code{opt} is an option string
+(e.g., \code{"-f"}), and \code{value} is the string from the command line that
+must be checked and converted to your desired type.  \code{check{\_}mytype()}
+should return an object of the hypothetical type \code{mytype}.  The value
+returned by a type-checking function will wind up in the OptionValues
+instance returned by \method{OptionParser.parse{\_}args()}, or be passed to a
+callback as the \code{value} parameter.
+
+Your type-checking function should raise OptionValueError if it
+encounters any problems.  OptionValueError takes a single string
+argument, which is passed as-is to OptionParser's \method{error()} method,
+which in turn prepends the program name and the string \code{"error:"} and
+prints everything to stderr before terminating the process.
+
+Here's a silly example that demonstrates adding a \code{complex} option
+type to parse Python-style complex numbers on the command line.  (This
+is even sillier than it used to be, because \module{optparse} 1.3 added built-in
+support for complex numbers, but never mind.)
+
+First, the necessary imports:
+\begin{verbatim}
+from copy import copy
+from optparse import Option, OptionValueError
+\end{verbatim}
+
+You need to define your type-checker first, since it's referred to later
+(in the \member{TYPE{\_}CHECKER} class attribute of your Option subclass):
+\begin{verbatim}
+def check_complex(option, opt, value):
+    try:
+        return complex(value)
+    except ValueError:
+        raise OptionValueError(
+            "option %s: invalid complex value: %r" % (opt, value))
+\end{verbatim}
+
+Finally, the Option subclass:
+\begin{verbatim}
+class MyOption (Option):
+    TYPES = Option.TYPES + ("complex",)
+    TYPE_CHECKER = copy(Option.TYPE_CHECKER)
+    TYPE_CHECKER["complex"] = check_complex
+\end{verbatim}
+
+(If we didn't make a \function{copy()} of \member{Option.TYPE{\_}CHECKER}, we would end
+up modifying the \member{TYPE{\_}CHECKER} attribute of \module{optparse}'s Option class.
+This being Python, nothing stops you from doing that except good manners
+and common sense.)
+
+That's it!  Now you can write a script that uses the new option type
+just like any other \module{optparse}-based script, except you have to instruct your
+OptionParser to use MyOption instead of Option:
+\begin{verbatim}
+parser = OptionParser(option_class=MyOption)
+parser.add_option("-c", type="complex")
+\end{verbatim}
+
+Alternately, you can build your own option list and pass it to
+OptionParser; if you don't use \method{add{\_}option()} in the above way, you
+don't need to tell OptionParser which option class to use:
+\begin{verbatim}
+option_list = [MyOption("-c", action="store", type="complex", dest="c")]
+parser = OptionParser(option_list=option_list)
+\end{verbatim}
+
+
+\subsubsection{Adding new actions\label{optparse-adding-new-actions}}
+
+Adding new actions is a bit trickier, because you have to understand
+that \module{optparse} has a couple of classifications for actions:
+\begin{description}
+\item[``store'' actions]
+actions that result in \module{optparse} storing a value to an attribute of the
+current OptionValues instance; these options require a \member{dest}
+attribute to be supplied to the Option constructor
+\item[``typed'' actions]
+actions that take a value from the command line and expect it to be
+of a certain type; or rather, a string that can be converted to a
+certain type.  These options require a \member{type} attribute to the
+Option constructor.
+\end{description}
+
+These are overlapping sets: some default ``store'' actions are \code{store},
+\code{store{\_}const}, \code{append}, and \code{count}, while the default ``typed''
+actions are \code{store}, \code{append}, and \code{callback}.
+
+When you add an action, you need to categorize it by listing it in at
+least one of the following class attributes of Option (all are lists of
+strings):
+\begin{description}
+\item[\member{ACTIONS}]
+all actions must be listed in ACTIONS
+\item[\member{STORE{\_}ACTIONS}]
+``store'' actions are additionally listed here
+\item[\member{TYPED{\_}ACTIONS}]
+``typed'' actions are additionally listed here
+\item[\code{ALWAYS{\_}TYPED{\_}ACTIONS}]
+actions that always take a type (i.e. whose options always take a
+value) are additionally listed here.  The only effect of this is
+that \module{optparse} assigns the default type, \code{string}, to options with no
+explicit type whose action is listed in \code{ALWAYS{\_}TYPED{\_}ACTIONS}.
+\end{description}
+
+In order to actually implement your new action, you must override
+Option's \method{take{\_}action()} method and add a case that recognizes your
+action.
+
+For example, let's add an \code{extend} action.  This is similar to the
+standard \code{append} action, but instead of taking a single value from
+the command-line and appending it to an existing list, \code{extend} will
+take multiple values in a single comma-delimited string, and extend an
+existing list with them.  That is, if \code{"-{}-names"} is an \code{extend}
+option of type \code{string}, the command line
+\begin{verbatim}
+--names=foo,bar --names blah --names ding,dong
+\end{verbatim}
+
+would result in a list
+\begin{verbatim}
+["foo", "bar", "blah", "ding", "dong"]
+\end{verbatim}
+
+Again we define a subclass of Option:
+\begin{verbatim}
+class MyOption (Option):
+
+    ACTIONS = Option.ACTIONS + ("extend",)
+    STORE_ACTIONS = Option.STORE_ACTIONS + ("extend",)
+    TYPED_ACTIONS = Option.TYPED_ACTIONS + ("extend",)
+    ALWAYS_TYPED_ACTIONS = Option.ALWAYS_TYPED_ACTIONS + ("extend",)
+
+    def take_action(self, action, dest, opt, value, values, parser):
+        if action == "extend":
+            lvalue = value.split(",")
+            values.ensure_value(dest, []).extend(lvalue)
+        else:
+            Option.take_action(
+                self, action, dest, opt, value, values, parser)
+\end{verbatim}
+
+Features of note:
+\begin{itemize}
+\item {} 
+\code{extend} both expects a value on the command-line and stores that
+value somewhere, so it goes in both \member{STORE{\_}ACTIONS} and
+\member{TYPED{\_}ACTIONS}
+
+\item {} 
+to ensure that \module{optparse} assigns the default type of \code{string} to
+\code{extend} actions, we put the \code{extend} action in
+\code{ALWAYS{\_}TYPED{\_}ACTIONS} as well
+
+\item {} 
+\method{MyOption.take{\_}action()} implements just this one new action, and
+passes control back to \method{Option.take{\_}action()} for the standard
+\module{optparse} actions
+
+\item {} 
+\code{values} is an instance of the optparse{\_}parser.Values class,
+which provides the very useful \method{ensure{\_}value()} method.
+\method{ensure{\_}value()} is essentially \function{getattr()} with a safety valve;
+it is called as
+\begin{verbatim}
+values.ensure_value(attr, value)
+\end{verbatim}
+
+If the \code{attr} attribute of \code{values} doesn't exist or is None, then
+ensure{\_}value() first sets it to \code{value}, and then returns 'value.
+This is very handy for actions like \code{extend}, \code{append}, and
+\code{count}, all of which accumulate data in a variable and expect that
+variable to be of a certain type (a list for the first two, an integer
+for the latter).  Using \method{ensure{\_}value()} means that scripts using
+your action don't have to worry about setting a default value for the
+option destinations in question; they can just leave the default as
+None and \method{ensure{\_}value()} will take care of getting it right when
+it's needed.
+
+\end{itemize}
+% $Id: extending.txt 517 2006-06-10 16:18:11Z gward $ 
+

Added: vendor/Python/current/Doc/lib/libos.tex
===================================================================
--- vendor/Python/current/Doc/lib/libos.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libos.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2006 @@
+\section{\module{os} ---
+         Miscellaneous operating system interfaces}
+
+\declaremodule{standard}{os}
+\modulesynopsis{Miscellaneous operating system interfaces.}
+
+
+This module provides a more portable way of using operating system
+dependent functionality than importing a operating system dependent
+built-in module like \refmodule{posix} or \module{nt}.
+
+This module searches for an operating system dependent built-in module like
+\module{mac} or \refmodule{posix} and exports the same functions and data
+as found there.  The design of all Python's built-in operating system dependent
+modules is such that as long as the same functionality is available,
+it uses the same interface; for example, the function
+\code{os.stat(\var{path})} returns stat information about \var{path} in
+the same format (which happens to have originated with the
+\POSIX{} interface).
+
+Extensions peculiar to a particular operating system are also
+available through the \module{os} module, but using them is of course a
+threat to portability!
+
+Note that after the first time \module{os} is imported, there is
+\emph{no} performance penalty in using functions from \module{os}
+instead of directly from the operating system dependent built-in module,
+so there should be \emph{no} reason not to use \module{os}!
+
+
+% Frank Stajano <fstajano at uk.research.att.com> complained that it
+% wasn't clear that the entries described in the subsections were all
+% available at the module level (most uses of subsections are
+% different); I think this is only a problem for the HTML version,
+% where the relationship may not be as clear.
+%
+\ifhtml
+The \module{os} module contains many functions and data values.
+The items below and in the following sub-sections are all available
+directly from the \module{os} module.
+\fi
+
+
+\begin{excdesc}{error}
+This exception is raised when a function returns a system-related
+error (not for illegal argument types or other incidental errors).
+This is also known as the built-in exception \exception{OSError}.  The
+accompanying value is a pair containing the numeric error code from
+\cdata{errno} and the corresponding string, as would be printed by the
+C function \cfunction{perror()}.  See the module
+\refmodule{errno}\refbimodindex{errno}, which contains names for the
+error codes defined by the underlying operating system.
+
+When exceptions are classes, this exception carries two attributes,
+\member{errno} and \member{strerror}.  The first holds the value of
+the C \cdata{errno} variable, and the latter holds the corresponding
+error message from \cfunction{strerror()}.  For exceptions that
+involve a file system path (such as \function{chdir()} or
+\function{unlink()}), the exception instance will contain a third
+attribute, \member{filename}, which is the file name passed to the
+function.
+\end{excdesc}
+
+\begin{datadesc}{name}
+The name of the operating system dependent module imported.  The
+following names have currently been registered: \code{'posix'},
+\code{'nt'}, \code{'mac'}, \code{'os2'}, \code{'ce'},
+\code{'java'}, \code{'riscos'}.
+\end{datadesc}
+
+\begin{datadesc}{path}
+The corresponding operating system dependent standard module for pathname
+operations, such as \module{posixpath} or \module{macpath}.  Thus,
+given the proper imports, \code{os.path.split(\var{file})} is
+equivalent to but more portable than
+\code{posixpath.split(\var{file})}.  Note that this is also an
+importable module: it may be imported directly as
+\refmodule{os.path}.
+\end{datadesc}
+
+
+
+\subsection{Process Parameters \label{os-procinfo}}
+
+These functions and data items provide information and operate on the
+current process and user.
+
+\begin{datadesc}{environ}
+A mapping object representing the string environment. For example,
+\code{environ['HOME']} is the pathname of your home directory (on some
+platforms), and is equivalent to \code{getenv("HOME")} in C.
+
+This mapping is captured the first time the \module{os} module is
+imported, typically during Python startup as part of processing
+\file{site.py}.  Changes to the environment made after this time are
+not reflected in \code{os.environ}, except for changes made by modifying
+\code{os.environ} directly.
+
+If the platform supports the \function{putenv()} function, this
+mapping may be used to modify the environment as well as query the
+environment.  \function{putenv()} will be called automatically when
+the mapping is modified.
+\note{Calling \function{putenv()} directly does not change
+\code{os.environ}, so it's better to modify \code{os.environ}.}
+\note{On some platforms, including FreeBSD and Mac OS X, setting
+\code{environ} may cause memory leaks.  Refer to the system documentation
+for \cfunction{putenv()}.}
+
+If \function{putenv()} is not provided, a modified copy of this mapping 
+may be passed to the appropriate process-creation functions to cause 
+child processes to use a modified environment.
+
+If the platform supports the \function{unsetenv()} function, you can 
+delete items in this mapping to unset environment variables.
+\function{unsetenv()} will be called automatically when an item is
+deleted from \code{os.environ}.
+
+\end{datadesc}
+
+\begin{funcdescni}{chdir}{path}
+\funclineni{fchdir}{fd}
+\funclineni{getcwd}{}
+These functions are described in ``Files and Directories'' (section
+\ref{os-file-dir}).
+\end{funcdescni}
+
+\begin{funcdesc}{ctermid}{}
+Return the filename corresponding to the controlling terminal of the
+process.
+Availability: \UNIX.
+\end{funcdesc}
+
+\begin{funcdesc}{getegid}{}
+Return the effective group id of the current process.  This
+corresponds to the `set id' bit on the file being executed in the
+current process.
+Availability: \UNIX.
+\end{funcdesc}
+
+\begin{funcdesc}{geteuid}{}
+\index{user!effective id}
+Return the current process' effective user id.
+Availability: \UNIX.
+\end{funcdesc}
+
+\begin{funcdesc}{getgid}{}
+\index{process!group}
+Return the real group id of the current process.
+Availability: \UNIX.
+\end{funcdesc}
+
+\begin{funcdesc}{getgroups}{}
+Return list of supplemental group ids associated with the current
+process.
+Availability: \UNIX.
+\end{funcdesc}
+
+\begin{funcdesc}{getlogin}{}
+Return the name of the user logged in on the controlling terminal of
+the process.  For most purposes, it is more useful to use the
+environment variable \envvar{LOGNAME} to find out who the user is,
+or \code{pwd.getpwuid(os.getuid())[0]} to get the login name
+of the currently effective user ID.
+Availability: \UNIX.
+\end{funcdesc}
+
+\begin{funcdesc}{getpgid}{pid}
+Return the process group id of the process with process id \var{pid}.
+If \var{pid} is 0, the process group id of the current process is
+returned. Availability: \UNIX.
+\versionadded{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{getpgrp}{}
+\index{process!group}
+Return the id of the current process group.
+Availability: \UNIX.
+\end{funcdesc}
+
+\begin{funcdesc}{getpid}{}
+\index{process!id}
+Return the current process id.
+Availability: \UNIX, Windows.
+\end{funcdesc}
+
+\begin{funcdesc}{getppid}{}
+\index{process!id of parent}
+Return the parent's process id.
+Availability: \UNIX.
+\end{funcdesc}
+
+\begin{funcdesc}{getuid}{}
+\index{user!id}
+Return the current process' user id.
+Availability: \UNIX.
+\end{funcdesc}
+
+\begin{funcdesc}{getenv}{varname\optional{, value}}
+Return the value of the environment variable \var{varname} if it
+exists, or \var{value} if it doesn't.  \var{value} defaults to
+\code{None}.
+Availability: most flavors of \UNIX, Windows.
+\end{funcdesc}
+
+\begin{funcdesc}{putenv}{varname, value}
+\index{environment variables!setting}
+Set the environment variable named \var{varname} to the string
+\var{value}.  Such changes to the environment affect subprocesses
+started with \function{os.system()}, \function{popen()} or
+\function{fork()} and \function{execv()}.
+Availability: most flavors of \UNIX, Windows.
+
+\note{On some platforms, including FreeBSD and Mac OS X,
+setting \code{environ} may cause memory leaks.
+Refer to the system documentation for putenv.}
+
+When \function{putenv()} is
+supported, assignments to items in \code{os.environ} are automatically
+translated into corresponding calls to \function{putenv()}; however,
+calls to \function{putenv()} don't update \code{os.environ}, so it is
+actually preferable to assign to items of \code{os.environ}.
+\end{funcdesc}
+
+\begin{funcdesc}{setegid}{egid}
+Set the current process's effective group id.
+Availability: \UNIX.
+\end{funcdesc}
+
+\begin{funcdesc}{seteuid}{euid}
+Set the current process's effective user id.
+Availability: \UNIX.
+\end{funcdesc}
+
+\begin{funcdesc}{setgid}{gid}
+Set the current process' group id.
+Availability: \UNIX.
+\end{funcdesc}
+
+\begin{funcdesc}{setgroups}{groups}
+Set the list of supplemental group ids associated with the current
+process to \var{groups}. \var{groups} must be a sequence, and each
+element must be an integer identifying a group. This operation is
+typical available only to the superuser.
+Availability: \UNIX.
+\versionadded{2.2}
+\end{funcdesc}
+
+\begin{funcdesc}{setpgrp}{}
+Calls the system call \cfunction{setpgrp()} or \cfunction{setpgrp(0,
+0)} depending on which version is implemented (if any).  See the
+\UNIX{} manual for the semantics.
+Availability: \UNIX.
+\end{funcdesc}
+
+\begin{funcdesc}{setpgid}{pid, pgrp} Calls the system call
+\cfunction{setpgid()} to set the process group id of the process with
+id \var{pid} to the process group with id \var{pgrp}.  See the \UNIX{}
+manual for the semantics.
+Availability: \UNIX.
+\end{funcdesc}
+
+\begin{funcdesc}{setreuid}{ruid, euid}
+Set the current process's real and effective user ids.
+Availability: \UNIX.
+\end{funcdesc}
+
+\begin{funcdesc}{setregid}{rgid, egid}
+Set the current process's real and effective group ids.
+Availability: \UNIX.
+\end{funcdesc}
+
+\begin{funcdesc}{getsid}{pid}
+Calls the system call \cfunction{getsid()}.  See the \UNIX{} manual
+for the semantics.
+Availability: \UNIX. \versionadded{2.4}
+\end{funcdesc}
+
+\begin{funcdesc}{setsid}{}
+Calls the system call \cfunction{setsid()}.  See the \UNIX{} manual
+for the semantics.
+Availability: \UNIX.
+\end{funcdesc}
+
+\begin{funcdesc}{setuid}{uid}
+\index{user!id, setting}
+Set the current process' user id.
+Availability: \UNIX.
+\end{funcdesc}
+
+% placed in this section since it relates to errno.... a little weak
+\begin{funcdesc}{strerror}{code}
+Return the error message corresponding to the error code in
+\var{code}.
+Availability: \UNIX, Windows.
+\end{funcdesc}
+
+\begin{funcdesc}{umask}{mask}
+Set the current numeric umask and returns the previous umask.
+Availability: \UNIX, Windows.
+\end{funcdesc}
+
+\begin{funcdesc}{uname}{}
+Return a 5-tuple containing information identifying the current
+operating system.  The tuple contains 5 strings:
+\code{(\var{sysname}, \var{nodename}, \var{release}, \var{version},
+\var{machine})}.  Some systems truncate the nodename to 8
+characters or to the leading component; a better way to get the
+hostname is \function{socket.gethostname()}
+\withsubitem{(in module socket)}{\ttindex{gethostname()}}
+or even
+\withsubitem{(in module socket)}{\ttindex{gethostbyaddr()}}
+\code{socket.gethostbyaddr(socket.gethostname())}.
+Availability: recent flavors of \UNIX.
+\end{funcdesc}
+
+\begin{funcdesc}{unsetenv}{varname}
+\index{environment variables!deleting}
+Unset (delete) the environment variable named \var{varname}. Such
+changes to the environment affect subprocesses started with
+\function{os.system()}, \function{popen()} or \function{fork()} and
+\function{execv()}. Availability: most flavors of \UNIX, Windows.
+
+When \function{unsetenv()} is
+supported, deletion of items in \code{os.environ} is automatically
+translated into a corresponding call to \function{unsetenv()}; however,
+calls to \function{unsetenv()} don't update \code{os.environ}, so it is
+actually preferable to delete items of \code{os.environ}.
+\end{funcdesc}
+
+\subsection{File Object Creation \label{os-newstreams}}
+
+These functions create new file objects.
+
+
+\begin{funcdesc}{fdopen}{fd\optional{, mode\optional{, bufsize}}}
+Return an open file object connected to the file descriptor \var{fd}.
+\index{I/O control!buffering}
+The \var{mode} and \var{bufsize} arguments have the same meaning as
+the corresponding arguments to the built-in \function{open()}
+function.
+Availability: Macintosh, \UNIX, Windows.
+
+\versionchanged[When specified, the \var{mode} argument must now start
+  with one of the letters \character{r}, \character{w}, or \character{a},
+  otherwise a \exception{ValueError} is raised]{2.3}
+\versionchanged[On \UNIX, when the \var{mode} argument starts with
+  \character{a}, the \var{O_APPEND} flag is set on the file descriptor
+  (which the \cfunction{fdopen()} implementation already does on most
+  platforms)]{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{popen}{command\optional{, mode\optional{, bufsize}}}
+Open a pipe to or from \var{command}.  The return value is an open
+file object connected to the pipe, which can be read or written
+depending on whether \var{mode} is \code{'r'} (default) or \code{'w'}.
+The \var{bufsize} argument has the same meaning as the corresponding
+argument to the built-in \function{open()} function.  The exit status of
+the command (encoded in the format specified for \function{wait()}) is
+available as the return value of the \method{close()} method of the file
+object, except that when the exit status is zero (termination without
+errors), \code{None} is returned.
+Availability: Macintosh, \UNIX, Windows.
+
+The \module{subprocess} module provides more powerful facilities for
+spawning new processes and retrieving their results; using that module
+is preferable to using this function.
+
+\versionchanged[This function worked unreliably under Windows in
+  earlier versions of Python.  This was due to the use of the
+  \cfunction{_popen()} function from the libraries provided with
+  Windows.  Newer versions of Python do not use the broken
+  implementation from the Windows libraries]{2.0}
+\end{funcdesc}
+
+\begin{funcdesc}{tmpfile}{}
+Return a new file object opened in update mode (\samp{w+b}).  The file
+has no directory entries associated with it and will be automatically
+deleted once there are no file descriptors for the file.
+Availability: Macintosh, \UNIX, Windows.
+\end{funcdesc}
+
+There are a number of different \function{popen*()} functions that
+provide slightly different ways to create subprocesses.  Note that the
+\module{subprocess} module is easier to use and more powerful;
+consider using that module before writing code using the
+lower-level \function{popen*()} functions.
+
+For each of the \function{popen*()} variants, if \var{bufsize} is
+specified, it specifies the buffer size for the I/O pipes.
+\var{mode}, if provided, should be the string \code{'b'} or
+\code{'t'}; on Windows this is needed to determine whether the file
+objects should be opened in binary or text mode.  The default value
+for \var{mode} is \code{'t'}.
+
+Also, for each of these variants, on \UNIX, \var{cmd} may be a sequence, in
+which case arguments will be passed directly to the program without shell
+intervention (as with \function{os.spawnv()}). If \var{cmd} is a string it will
+be passed to the shell (as with \function{os.system()}).
+
+These methods do not make it possible to retrieve the exit status from
+the child processes.  The only way to control the input and output
+streams and also retrieve the return codes is to use the
+\class{Popen3} and \class{Popen4} classes from the \refmodule{popen2}
+module; these are only available on \UNIX.
+
+For a discussion of possible deadlock conditions related to the use
+of these functions, see ``\ulink{Flow Control
+Issues}{popen2-flow-control.html}''
+(section~\ref{popen2-flow-control}).
+
+\begin{funcdesc}{popen2}{cmd\optional{, mode\optional{, bufsize}}}
+Executes \var{cmd} as a sub-process.  Returns the file objects
+\code{(\var{child_stdin}, \var{child_stdout})}.
+Availability: Macintosh, \UNIX, Windows.
+\versionadded{2.0}
+\end{funcdesc}
+
+\begin{funcdesc}{popen3}{cmd\optional{, mode\optional{, bufsize}}}
+Executes \var{cmd} as a sub-process.  Returns the file objects
+\code{(\var{child_stdin}, \var{child_stdout}, \var{child_stderr})}.
+Availability: Macintosh, \UNIX, Windows.
+\versionadded{2.0}
+\end{funcdesc}
+
+\begin{funcdesc}{popen4}{cmd\optional{, mode\optional{, bufsize}}}
+Executes \var{cmd} as a sub-process.  Returns the file objects
+\code{(\var{child_stdin}, \var{child_stdout_and_stderr})}.
+Availability: Macintosh, \UNIX, Windows.
+\versionadded{2.0}
+\end{funcdesc}
+
+(Note that \code{\var{child_stdin}, \var{child_stdout}, and
+\var{child_stderr}} are named from the point of view of the child
+process, so \var{child_stdin} is the child's standard input.)
+
+This functionality is also available in the \refmodule{popen2} module
+using functions of the same names, but the return values of those
+functions have a different order.
+
+
+\subsection{File Descriptor Operations \label{os-fd-ops}}
+
+These functions operate on I/O streams referenced using file
+descriptors.  
+
+File descriptors are small integers corresponding to a file that has
+been opened by the current process.  For example, standard input is
+usually file descriptor 0, standard output is 1, and standard error is
+2.  Further files opened by a process will then be assigned 3, 4, 5,
+and so forth.  The name ``file descriptor'' is slightly deceptive; on
+{\UNIX} platforms, sockets and pipes are also referenced by file descriptors.
+
+
+\begin{funcdesc}{close}{fd}
+Close file descriptor \var{fd}.
+Availability: Macintosh, \UNIX, Windows.
+
+\begin{notice}
+This function is intended for low-level I/O and must be applied
+to a file descriptor as returned by \function{open()} or
+\function{pipe()}.  To close a ``file object'' returned by the
+built-in function \function{open()} or by \function{popen()} or
+\function{fdopen()}, use its \method{close()} method.
+\end{notice}
+\end{funcdesc}
+
+\begin{funcdesc}{dup}{fd}
+Return a duplicate of file descriptor \var{fd}.
+Availability: Macintosh, \UNIX, Windows.
+\end{funcdesc}
+
+\begin{funcdesc}{dup2}{fd, fd2}
+Duplicate file descriptor \var{fd} to \var{fd2}, closing the latter
+first if necessary.
+Availability: Macintosh, \UNIX, Windows.
+\end{funcdesc}
+
+\begin{funcdesc}{fdatasync}{fd}
+Force write of file with filedescriptor \var{fd} to disk.
+Does not force update of metadata.
+Availability: \UNIX.
+\end{funcdesc}
+
+\begin{funcdesc}{fpathconf}{fd, name}
+Return system configuration information relevant to an open file.
+\var{name} specifies the configuration value to retrieve; it may be a
+string which is the name of a defined system value; these names are
+specified in a number of standards (\POSIX.1, \UNIX{} 95, \UNIX{} 98, and
+others).  Some platforms define additional names as well.  The names
+known to the host operating system are given in the
+\code{pathconf_names} dictionary.  For configuration variables not
+included in that mapping, passing an integer for \var{name} is also
+accepted.
+Availability: Macintosh, \UNIX.
+
+If \var{name} is a string and is not known, \exception{ValueError} is
+raised.  If a specific value for \var{name} is not supported by the
+host system, even if it is included in \code{pathconf_names}, an
+\exception{OSError} is raised with \constant{errno.EINVAL} for the
+error number.
+\end{funcdesc}
+
+\begin{funcdesc}{fstat}{fd}
+Return status for file descriptor \var{fd}, like \function{stat()}.
+Availability: Macintosh, \UNIX, Windows.
+\end{funcdesc}
+
+\begin{funcdesc}{fstatvfs}{fd}
+Return information about the filesystem containing the file associated
+with file descriptor \var{fd}, like \function{statvfs()}.
+Availability: \UNIX.
+\end{funcdesc}
+
+\begin{funcdesc}{fsync}{fd}
+Force write of file with filedescriptor \var{fd} to disk.  On \UNIX,
+this calls the native \cfunction{fsync()} function; on Windows, the
+MS \cfunction{_commit()} function.
+
+If you're starting with a Python file object \var{f}, first do
+\code{\var{f}.flush()}, and then do \code{os.fsync(\var{f}.fileno())},
+to ensure that all internal buffers associated with \var{f} are written
+to disk.
+Availability: Macintosh, \UNIX, and Windows starting in 2.2.3.
+\end{funcdesc}
+
+\begin{funcdesc}{ftruncate}{fd, length}
+Truncate the file corresponding to file descriptor \var{fd},
+so that it is at most \var{length} bytes in size.
+Availability: Macintosh, \UNIX.
+\end{funcdesc}
+
+\begin{funcdesc}{isatty}{fd}
+Return \code{True} if the file descriptor \var{fd} is open and
+connected to a tty(-like) device, else \code{False}.
+Availability: Macintosh, \UNIX.
+\end{funcdesc}
+
+\begin{funcdesc}{lseek}{fd, pos, how}
+Set the current position of file descriptor \var{fd} to position
+\var{pos}, modified by \var{how}: \code{0} to set the position
+relative to the beginning of the file; \code{1} to set it relative to
+the current position; \code{2} to set it relative to the end of the
+file.
+Availability: Macintosh, \UNIX, Windows.
+\end{funcdesc}
+
+\begin{funcdesc}{open}{file, flags\optional{, mode}}
+Open the file \var{file} and set various flags according to
+\var{flags} and possibly its mode according to \var{mode}.
+The default \var{mode} is \code{0777} (octal), and the current umask
+value is first masked out.  Return the file descriptor for the newly
+opened file.
+Availability: Macintosh, \UNIX, Windows.
+
+For a description of the flag and mode values, see the C run-time
+documentation; flag constants (like \constant{O_RDONLY} and
+\constant{O_WRONLY}) are defined in this module too (see below).
+
+\begin{notice}
+This function is intended for low-level I/O.  For normal usage,
+use the built-in function \function{open()}, which returns a ``file
+object'' with \method{read()} and \method{write()} methods (and many
+more).  To wrap a file descriptor in a ``file object'', use
+\function{fdopen()}.
+\end{notice}
+\end{funcdesc}
+
+\begin{funcdesc}{openpty}{}
+Open a new pseudo-terminal pair. Return a pair of file descriptors
+\code{(\var{master}, \var{slave})} for the pty and the tty,
+respectively. For a (slightly) more portable approach, use the
+\refmodule{pty}\refstmodindex{pty} module.
+Availability: Macintosh, Some flavors of \UNIX.
+\end{funcdesc}
+
+\begin{funcdesc}{pipe}{}
+Create a pipe.  Return a pair of file descriptors \code{(\var{r},
+\var{w})} usable for reading and writing, respectively.
+Availability: Macintosh, \UNIX, Windows.
+\end{funcdesc}
+
+\begin{funcdesc}{read}{fd, n}
+Read at most \var{n} bytes from file descriptor \var{fd}.
+Return a string containing the bytes read.  If the end of the file
+referred to by \var{fd} has been reached, an empty string is
+returned.
+Availability: Macintosh, \UNIX, Windows.
+
+\begin{notice}
+This function is intended for low-level I/O and must be applied
+to a file descriptor as returned by \function{open()} or
+\function{pipe()}.  To read a ``file object'' returned by the
+built-in function \function{open()} or by \function{popen()} or
+\function{fdopen()}, or \code{sys.stdin}, use its
+\method{read()} or \method{readline()} methods.
+\end{notice}
+\end{funcdesc}
+
+\begin{funcdesc}{tcgetpgrp}{fd}
+Return the process group associated with the terminal given by
+\var{fd} (an open file descriptor as returned by \function{open()}).
+Availability: Macintosh, \UNIX.
+\end{funcdesc}
+
+\begin{funcdesc}{tcsetpgrp}{fd, pg}
+Set the process group associated with the terminal given by
+\var{fd} (an open file descriptor as returned by \function{open()})
+to \var{pg}.
+Availability: Macintosh, \UNIX.
+\end{funcdesc}
+
+\begin{funcdesc}{ttyname}{fd}
+Return a string which specifies the terminal device associated with
+file-descriptor \var{fd}.  If \var{fd} is not associated with a terminal
+device, an exception is raised.
+Availability:Macintosh,  \UNIX.
+\end{funcdesc}
+
+\begin{funcdesc}{write}{fd, str}
+Write the string \var{str} to file descriptor \var{fd}.
+Return the number of bytes actually written.
+Availability: Macintosh, \UNIX, Windows.
+
+\begin{notice}
+This function is intended for low-level I/O and must be applied
+to a file descriptor as returned by \function{open()} or
+\function{pipe()}.  To write a ``file object'' returned by the
+built-in function \function{open()} or by \function{popen()} or
+\function{fdopen()}, or \code{sys.stdout} or \code{sys.stderr}, use
+its \method{write()} method.
+\end{notice}
+\end{funcdesc}
+
+
+The following data items are available for use in constructing the
+\var{flags} parameter to the \function{open()} function.  Some items will
+not be available on all platforms.  For descriptions of their availability
+and use, consult \manpage{open}{2}.
+
+\begin{datadesc}{O_RDONLY}
+\dataline{O_WRONLY}
+\dataline{O_RDWR}
+\dataline{O_APPEND}
+\dataline{O_CREAT}
+\dataline{O_EXCL}
+\dataline{O_TRUNC}
+Options for the \var{flag} argument to the \function{open()} function.
+These can be bit-wise OR'd together.
+Availability: Macintosh, \UNIX, Windows.
+\end{datadesc}
+
+\begin{datadesc}{O_DSYNC}
+\dataline{O_RSYNC}
+\dataline{O_SYNC}
+\dataline{O_NDELAY}
+\dataline{O_NONBLOCK}
+\dataline{O_NOCTTY}
+\dataline{O_SHLOCK}
+\dataline{O_EXLOCK}
+More options for the \var{flag} argument to the \function{open()} function.
+Availability: Macintosh, \UNIX.
+\end{datadesc}
+
+\begin{datadesc}{O_BINARY}
+Option for the \var{flag} argument to the \function{open()} function.
+This can be bit-wise OR'd together with those listed above.
+Availability: Windows.
+% XXX need to check on the availability of this one.
+\end{datadesc}
+
+\begin{datadesc}{O_NOINHERIT}
+\dataline{O_SHORT_LIVED}
+\dataline{O_TEMPORARY}
+\dataline{O_RANDOM}
+\dataline{O_SEQUENTIAL}
+\dataline{O_TEXT}
+Options for the \var{flag} argument to the \function{open()} function.
+These can be bit-wise OR'd together.
+Availability: Windows.
+\end{datadesc}
+
+\begin{datadesc}{SEEK_SET}
+\dataline{SEEK_CUR}
+\dataline{SEEK_END}
+Parameters to the \function{lseek()} function.
+Their values are 0, 1, and 2, respectively.
+Availability: Windows, Macintosh, \UNIX.
+\versionadded{2.5}
+\end{datadesc}
+
+\subsection{Files and Directories \label{os-file-dir}}
+
+\begin{funcdesc}{access}{path, mode}
+Use the real uid/gid to test for access to \var{path}.  Note that most
+operations will use the effective uid/gid, therefore this routine can
+be used in a suid/sgid environment to test if the invoking user has the
+specified access to \var{path}.  \var{mode} should be \constant{F_OK}
+to test the existence of \var{path}, or it can be the inclusive OR of
+one or more of \constant{R_OK}, \constant{W_OK}, and \constant{X_OK} to
+test permissions.  Return \constant{True} if access is allowed,
+\constant{False} if not.
+See the \UNIX{} man page \manpage{access}{2} for more information.
+Availability: Macintosh, \UNIX, Windows.
+
+\note{Using \function{access()} to check if a user is authorized to e.g.
+open a file before actually doing so using \function{open()} creates a 
+security hole, because the user might exploit the short time interval 
+between checking and opening the file to manipulate it.}
+
+\note{I/O operations may fail even when \function{access()}
+indicates that they would succeed, particularly for operations
+on network filesystems which may have permissions semantics
+beyond the usual \POSIX{} permission-bit model.}
+\end{funcdesc}
+
+\begin{datadesc}{F_OK}
+  Value to pass as the \var{mode} parameter of \function{access()} to
+  test the existence of \var{path}.
+\end{datadesc}
+
+\begin{datadesc}{R_OK}
+  Value to include in the \var{mode} parameter of \function{access()}
+  to test the readability of \var{path}.
+\end{datadesc}
+
+\begin{datadesc}{W_OK}
+  Value to include in the \var{mode} parameter of \function{access()}
+  to test the writability of \var{path}.
+\end{datadesc}
+
+\begin{datadesc}{X_OK}
+  Value to include in the \var{mode} parameter of \function{access()}
+  to determine if \var{path} can be executed.
+\end{datadesc}
+
+\begin{funcdesc}{chdir}{path}
+\index{directory!changing}
+Change the current working directory to \var{path}.
+Availability: Macintosh, \UNIX, Windows.
+\end{funcdesc}
+
+\begin{funcdesc}{fchdir}{fd}
+Change the current working directory to the directory represented by
+the file descriptor \var{fd}.  The descriptor must refer to an opened
+directory, not an open file.
+Availability: \UNIX.
+\versionadded{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{getcwd}{}
+Return a string representing the current working directory.
+Availability: Macintosh, \UNIX, Windows.
+\end{funcdesc}
+
+\begin{funcdesc}{getcwdu}{}
+Return a Unicode object representing the current working directory.
+Availability: Macintosh, \UNIX, Windows.
+\versionadded{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{chroot}{path}
+Change the root directory of the current process to \var{path}.
+Availability: Macintosh, \UNIX.
+\versionadded{2.2}
+\end{funcdesc}
+
+\begin{funcdesc}{chmod}{path, mode}
+Change the mode of \var{path} to the numeric \var{mode}.
+\var{mode} may take one of the following values
+(as defined in the \module{stat} module) or bitwise or-ed
+combinations of them:
+\begin{itemize}
+  \item \code{S_ISUID}
+  \item \code{S_ISGID}
+  \item \code{S_ENFMT}
+  \item \code{S_ISVTX}
+  \item \code{S_IREAD}
+  \item \code{S_IWRITE}
+  \item \code{S_IEXEC}
+  \item \code{S_IRWXU}
+  \item \code{S_IRUSR}
+  \item \code{S_IWUSR}
+  \item \code{S_IXUSR}
+  \item \code{S_IRWXG}
+  \item \code{S_IRGRP}
+  \item \code{S_IWGRP}
+  \item \code{S_IXGRP}
+  \item \code{S_IRWXO}
+  \item \code{S_IROTH}
+  \item \code{S_IWOTH}
+  \item \code{S_IXOTH}
+\end{itemize}
+Availability: Macintosh, \UNIX, Windows.
+
+\note{Although Windows supports \function{chmod()}, you can only 
+set the file's read-only flag with it (via the \code{S_IWRITE} 
+and \code{S_IREAD} constants or a corresponding integer value). 
+All other bits are ignored.}
+\end{funcdesc}
+
+\begin{funcdesc}{chown}{path, uid, gid}
+Change the owner and group id of \var{path} to the numeric \var{uid}
+and \var{gid}. To leave one of the ids unchanged, set it to -1.
+Availability: Macintosh, \UNIX.
+\end{funcdesc}
+
+\begin{funcdesc}{lchown}{path, uid, gid}
+Change the owner and group id of \var{path} to the numeric \var{uid}
+and gid. This function will not follow symbolic links.
+Availability: Macintosh, \UNIX.
+\versionadded{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{link}{src, dst}
+Create a hard link pointing to \var{src} named \var{dst}.
+Availability: Macintosh, \UNIX.
+\end{funcdesc}
+
+\begin{funcdesc}{listdir}{path}
+Return a list containing the names of the entries in the directory.
+The list is in arbitrary order.  It does not include the special
+entries \code{'.'} and \code{'..'} even if they are present in the
+directory.
+Availability: Macintosh, \UNIX, Windows.
+
+\versionchanged[On Windows NT/2k/XP and \UNIX, if \var{path} is a Unicode
+object, the result will be a list of Unicode objects]{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{lstat}{path}
+Like \function{stat()}, but do not follow symbolic links.
+Availability: Macintosh, \UNIX.
+\end{funcdesc}
+
+\begin{funcdesc}{mkfifo}{path\optional{, mode}}
+Create a FIFO (a named pipe) named \var{path} with numeric mode
+\var{mode}.  The default \var{mode} is \code{0666} (octal).  The current
+umask value is first masked out from the mode.
+Availability: Macintosh, \UNIX.
+
+FIFOs are pipes that can be accessed like regular files.  FIFOs exist
+until they are deleted (for example with \function{os.unlink()}).
+Generally, FIFOs are used as rendezvous between ``client'' and
+``server'' type processes: the server opens the FIFO for reading, and
+the client opens it for writing.  Note that \function{mkfifo()}
+doesn't open the FIFO --- it just creates the rendezvous point.
+\end{funcdesc}
+
+\begin{funcdesc}{mknod}{filename\optional{, mode=0600, device}}
+Create a filesystem node (file, device special file or named pipe)
+named \var{filename}. \var{mode} specifies both the permissions to use and
+the type of node to be created, being combined (bitwise OR) with one
+of S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO (those constants are
+available in \module{stat}). For S_IFCHR and S_IFBLK, \var{device}
+defines the newly created device special file (probably using
+\function{os.makedev()}), otherwise it is ignored.
+\versionadded{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{major}{device}
+Extracts the device major number from a raw device number (usually
+the \member{st_dev} or \member{st_rdev} field from \ctype{stat}).
+\versionadded{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{minor}{device}
+Extracts the device minor number from a raw device number (usually
+the \member{st_dev} or \member{st_rdev} field from \ctype{stat}).
+\versionadded{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{makedev}{major, minor}
+Composes a raw device number from the major and minor device numbers.
+\versionadded{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{mkdir}{path\optional{, mode}}
+Create a directory named \var{path} with numeric mode \var{mode}.
+The default \var{mode} is \code{0777} (octal).  On some systems,
+\var{mode} is ignored.  Where it is used, the current umask value is
+first masked out.
+Availability: Macintosh, \UNIX, Windows.
+\end{funcdesc}
+
+\begin{funcdesc}{makedirs}{path\optional{, mode}}
+Recursive directory creation function.\index{directory!creating}
+\index{UNC paths!and \function{os.makedirs()}}
+Like \function{mkdir()},
+but makes all intermediate-level directories needed to contain the
+leaf directory.  Throws an \exception{error} exception if the leaf
+directory already exists or cannot be created.  The default \var{mode}
+is \code{0777} (octal).  On some systems, \var{mode} is ignored.
+Where it is used, the current umask value is first masked out.
+\note{\function{makedirs()} will become confused if the path elements
+to create include \var{os.pardir}.}
+\versionadded{1.5.2}
+\versionchanged[This function now handles UNC paths correctly]{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{pathconf}{path, name}
+Return system configuration information relevant to a named file.
+\var{name} specifies the configuration value to retrieve; it may be a
+string which is the name of a defined system value; these names are
+specified in a number of standards (\POSIX.1, \UNIX{} 95, \UNIX{} 98, and
+others).  Some platforms define additional names as well.  The names
+known to the host operating system are given in the
+\code{pathconf_names} dictionary.  For configuration variables not
+included in that mapping, passing an integer for \var{name} is also
+accepted.
+Availability: Macintosh, \UNIX.
+
+If \var{name} is a string and is not known, \exception{ValueError} is
+raised.  If a specific value for \var{name} is not supported by the
+host system, even if it is included in \code{pathconf_names}, an
+\exception{OSError} is raised with \constant{errno.EINVAL} for the
+error number.
+\end{funcdesc}
+
+\begin{datadesc}{pathconf_names}
+Dictionary mapping names accepted by \function{pathconf()} and
+\function{fpathconf()} to the integer values defined for those names
+by the host operating system.  This can be used to determine the set
+of names known to the system.
+Availability: Macintosh, \UNIX.
+\end{datadesc}
+
+\begin{funcdesc}{readlink}{path}
+Return a string representing the path to which the symbolic link
+points.  The result may be either an absolute or relative pathname; if
+it is relative, it may be converted to an absolute pathname using
+\code{os.path.join(os.path.dirname(\var{path}), \var{result})}.
+Availability: Macintosh, \UNIX.
+\end{funcdesc}
+
+\begin{funcdesc}{remove}{path}
+Remove the file \var{path}.  If \var{path} is a directory,
+\exception{OSError} is raised; see \function{rmdir()} below to remove
+a directory.  This is identical to the \function{unlink()} function
+documented below.  On Windows, attempting to remove a file that is in
+use causes an exception to be raised; on \UNIX, the directory entry is
+removed but the storage allocated to the file is not made available
+until the original file is no longer in use.
+Availability: Macintosh, \UNIX, Windows.
+\end{funcdesc}
+
+\begin{funcdesc}{removedirs}{path}
+\index{directory!deleting}
+Removes directories recursively.  Works like
+\function{rmdir()} except that, if the leaf directory is
+successfully removed, \function{removedirs()} 
+tries to successively remove every parent directory mentioned in 
+\var{path} until an error is raised (which is ignored, because
+it generally means that a parent directory is not empty).
+For example, \samp{os.removedirs('foo/bar/baz')} will first remove
+the directory \samp{'foo/bar/baz'}, and then remove \samp{'foo/bar'}
+and \samp{'foo'} if they are empty.
+Raises \exception{OSError} if the leaf directory could not be 
+successfully removed.
+\versionadded{1.5.2}
+\end{funcdesc}
+
+\begin{funcdesc}{rename}{src, dst}
+Rename the file or directory \var{src} to \var{dst}.  If \var{dst} is
+a directory, \exception{OSError} will be raised.  On \UNIX, if
+\var{dst} exists and is a file, it will be removed silently if the
+user has permission.  The operation may fail on some \UNIX{} flavors
+if \var{src} and \var{dst} are on different filesystems.  If
+successful, the renaming will be an atomic operation (this is a
+\POSIX{} requirement).  On Windows, if \var{dst} already exists,
+\exception{OSError} will be raised even if it is a file; there may be
+no way to implement an atomic rename when \var{dst} names an existing
+file.
+Availability: Macintosh, \UNIX, Windows.
+\end{funcdesc}
+
+\begin{funcdesc}{renames}{old, new}
+Recursive directory or file renaming function.
+Works like \function{rename()}, except creation of any intermediate
+directories needed to make the new pathname good is attempted first.
+After the rename, directories corresponding to rightmost path segments
+of the old name will be pruned away using \function{removedirs()}.
+\versionadded{1.5.2}
+
+\begin{notice}
+This function can fail with the new directory structure made if
+you lack permissions needed to remove the leaf directory or file.
+\end{notice}
+\end{funcdesc}
+
+\begin{funcdesc}{rmdir}{path}
+Remove the directory \var{path}.
+Availability: Macintosh, \UNIX, Windows.
+\end{funcdesc}
+
+\begin{funcdesc}{stat}{path}
+Perform a \cfunction{stat()} system call on the given path.  The
+return value is an object whose attributes correspond to the members of
+the \ctype{stat} structure, namely:
+\member{st_mode} (protection bits),
+\member{st_ino} (inode number),
+\member{st_dev} (device),
+\member{st_nlink} (number of hard links),
+\member{st_uid} (user ID of owner),
+\member{st_gid} (group ID of owner),
+\member{st_size} (size of file, in bytes),
+\member{st_atime} (time of most recent access),
+\member{st_mtime} (time of most recent content modification),
+\member{st_ctime}
+(platform dependent; time of most recent metadata change on \UNIX, or
+the time of creation on Windows):
+
+\begin{verbatim}
+>>> import os
+>>> statinfo = os.stat('somefile.txt')
+>>> statinfo
+(33188, 422511L, 769L, 1, 1032, 100, 926L, 1105022698,1105022732, 1105022732)
+>>> statinfo.st_size
+926L
+>>>
+\end{verbatim}
+
+\versionchanged [If \function{stat_float_times} returns true, the time
+values are floats, measuring seconds. Fractions of a second may be
+reported if the system supports that. On Mac OS, the times are always
+floats. See \function{stat_float_times} for further discussion]{2.3}
+
+On some \UNIX{} systems (such as Linux), the following attributes may
+also be available:
+\member{st_blocks} (number of blocks allocated for file),
+\member{st_blksize} (filesystem blocksize),
+\member{st_rdev} (type of device if an inode device).
+\member{st_flags} (user defined flags for file).
+
+On other \UNIX{} systems (such as FreeBSD), the following attributes
+may be available (but may be only filled out if root tries to
+use them):
+\member{st_gen} (file generation number),
+\member{st_birthtime} (time of file creation).
+
+On Mac OS systems, the following attributes may also be available:
+\member{st_rsize},
+\member{st_creator},
+\member{st_type}.
+
+On RISCOS systems, the following attributes are also available:
+\member{st_ftype} (file type),
+\member{st_attrs} (attributes),
+\member{st_obtype} (object type).
+
+For backward compatibility, the return value of \function{stat()} is
+also accessible as a tuple of at least 10 integers giving the most
+important (and portable) members of the \ctype{stat} structure, in the
+order
+\member{st_mode},
+\member{st_ino},
+\member{st_dev},
+\member{st_nlink},
+\member{st_uid},
+\member{st_gid},
+\member{st_size},
+\member{st_atime},
+\member{st_mtime},
+\member{st_ctime}.
+More items may be added at the end by some implementations.
+The standard module \refmodule{stat}\refstmodindex{stat} defines
+functions and constants that are useful for extracting information
+from a \ctype{stat} structure.
+(On Windows, some items are filled with dummy values.)
+
+\note{The exact meaning and resolution of the \member{st_atime},
+ \member{st_mtime}, and \member{st_ctime} members depends on the
+ operating system and the file system.  For example, on Windows systems
+ using the FAT or FAT32 file systems, \member{st_mtime} has 2-second
+ resolution, and \member{st_atime} has only 1-day resolution.  See
+ your operating system documentation for details.}
+
+Availability: Macintosh, \UNIX, Windows.
+
+\versionchanged
+[Added access to values as attributes of the returned object]{2.2}
+\versionchanged[Added st_gen, st_birthtime]{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{stat_float_times}{\optional{newvalue}}
+Determine whether \class{stat_result} represents time stamps as float
+objects.  If \var{newvalue} is \code{True}, future calls to \function{stat()}
+return floats, if it is \code{False}, future calls return ints.
+If \var{newvalue} is omitted, return the current setting.
+
+For compatibility with older Python versions, accessing
+\class{stat_result} as a tuple always returns integers.
+
+\versionchanged[Python now returns float values by default. Applications
+which do not work correctly with floating point time stamps can use
+this function to restore the old behaviour]{2.5}
+
+The resolution of the timestamps (that is the smallest possible fraction)
+depends on the system. Some systems only support second resolution;
+on these systems, the fraction will always be zero.
+
+It is recommended that this setting is only changed at program startup
+time in the \var{__main__} module; libraries should never change this
+setting. If an application uses a library that works incorrectly if
+floating point time stamps are processed, this application should turn
+the feature off until the library has been corrected.
+
+\end{funcdesc}
+
+\begin{funcdesc}{statvfs}{path}
+Perform a \cfunction{statvfs()} system call on the given path.  The
+return value is an object whose attributes describe the filesystem on
+the given path, and correspond to the members of the
+\ctype{statvfs} structure, namely:
+\member{f_bsize},
+\member{f_frsize},
+\member{f_blocks},
+\member{f_bfree},
+\member{f_bavail},
+\member{f_files},
+\member{f_ffree},
+\member{f_favail},
+\member{f_flag},
+\member{f_namemax}.
+Availability: \UNIX.
+
+For backward compatibility, the return value is also accessible as a
+tuple whose values correspond to the attributes, in the order given above.
+The standard module \refmodule{statvfs}\refstmodindex{statvfs}
+defines constants that are useful for extracting information
+from a \ctype{statvfs} structure when accessing it as a sequence; this
+remains useful when writing code that needs to work with versions of
+Python that don't support accessing the fields as attributes.
+
+\versionchanged
+[Added access to values as attributes of the returned object]{2.2}
+\end{funcdesc}
+
+\begin{funcdesc}{symlink}{src, dst}
+Create a symbolic link pointing to \var{src} named \var{dst}.
+Availability: \UNIX.
+\end{funcdesc}
+
+\begin{funcdesc}{tempnam}{\optional{dir\optional{, prefix}}}
+Return a unique path name that is reasonable for creating a temporary
+file.  This will be an absolute path that names a potential directory
+entry in the directory \var{dir} or a common location for temporary
+files if \var{dir} is omitted or \code{None}.  If given and not
+\code{None}, \var{prefix} is used to provide a short prefix to the
+filename.  Applications are responsible for properly creating and
+managing files created using paths returned by \function{tempnam()};
+no automatic cleanup is provided.
+On \UNIX, the environment variable \envvar{TMPDIR} overrides
+\var{dir}, while on Windows the \envvar{TMP} is used.  The specific
+behavior of this function depends on the C library implementation;
+some aspects are underspecified in system documentation.
+\warning{Use of \function{tempnam()} is vulnerable to symlink attacks;
+consider using \function{tmpfile()} (section \ref{os-newstreams})
+instead.}  Availability: Macintosh, \UNIX, Windows.
+\end{funcdesc}
+
+\begin{funcdesc}{tmpnam}{}
+Return a unique path name that is reasonable for creating a temporary
+file.  This will be an absolute path that names a potential directory
+entry in a common location for temporary files.  Applications are
+responsible for properly creating and managing files created using
+paths returned by \function{tmpnam()}; no automatic cleanup is
+provided.
+\warning{Use of \function{tmpnam()} is vulnerable to symlink attacks;
+consider using \function{tmpfile()} (section \ref{os-newstreams})
+instead.}  Availability: \UNIX, Windows.  This function probably
+shouldn't be used on Windows, though: Microsoft's implementation of
+\function{tmpnam()} always creates a name in the root directory of the
+current drive, and that's generally a poor location for a temp file
+(depending on privileges, you may not even be able to open a file
+using this name).
+\end{funcdesc}
+
+\begin{datadesc}{TMP_MAX}
+The maximum number of unique names that \function{tmpnam()} will
+generate before reusing names.
+\end{datadesc}
+
+\begin{funcdesc}{unlink}{path}
+Remove the file \var{path}.  This is the same function as
+\function{remove()}; the \function{unlink()} name is its traditional
+\UNIX{} name.
+Availability: Macintosh, \UNIX, Windows.
+\end{funcdesc}
+
+\begin{funcdesc}{utime}{path, times}
+Set the access and modified times of the file specified by \var{path}.
+If \var{times} is \code{None}, then the file's access and modified
+times are set to the current time.  Otherwise, \var{times} must be a
+2-tuple of numbers, of the form \code{(\var{atime}, \var{mtime})}
+which is used to set the access and modified times, respectively.
+Whether a directory can be given for \var{path} depends on whether the
+operating system implements directories as files (for example, Windows
+does not).  Note that the exact times you set here may not be returned
+by a subsequent \function{stat()} call, depending on the resolution
+with which your operating system records access and modification times;
+see \function{stat()}.
+\versionchanged[Added support for \code{None} for \var{times}]{2.0}
+Availability: Macintosh, \UNIX, Windows.
+\end{funcdesc}
+
+\begin{funcdesc}{walk}{top\optional{, topdown\code{=True}
+                       \optional{, onerror\code{=None}}}}
+\index{directory!walking}
+\index{directory!traversal}
+\function{walk()} generates the file names in a directory tree, by
+walking the tree either top down or bottom up.
+For each directory in the tree rooted at directory \var{top} (including
+\var{top} itself), it yields a 3-tuple
+\code{(\var{dirpath}, \var{dirnames}, \var{filenames})}.
+
+\var{dirpath} is a string, the path to the directory.  \var{dirnames} is
+a list of the names of the subdirectories in \var{dirpath}
+(excluding \code{'.'} and \code{'..'}).  \var{filenames} is a list of
+the names of the non-directory files in \var{dirpath}.  Note that the
+names in the lists contain no path components.  To get a full
+path (which begins with \var{top}) to a file or directory in
+\var{dirpath}, do \code{os.path.join(\var{dirpath}, \var{name})}.
+
+If optional argument \var{topdown} is true or not specified, the triple
+for a directory is generated before the triples for any of its
+subdirectories (directories are generated top down).  If \var{topdown} is
+false, the triple for a directory is generated after the triples for all
+of its subdirectories (directories are generated bottom up).
+
+When \var{topdown} is true, the caller can modify the \var{dirnames} list
+in-place (perhaps using \keyword{del} or slice assignment), and
+\function{walk()} will only recurse into the subdirectories whose names
+remain in \var{dirnames}; this can be used to prune the search,
+impose a specific order of visiting, or even to inform \function{walk()}
+about directories the caller creates or renames before it resumes
+\function{walk()} again.  Modifying \var{dirnames} when \var{topdown} is
+false is ineffective, because in bottom-up mode the directories in
+\var{dirnames} are generated before \var{dirpath} itself is generated.
+
+By default errors from the \code{os.listdir()} call are ignored.  If
+optional argument \var{onerror} is specified, it should be a function;
+it will be called with one argument, an \exception{OSError} instance.  It can
+report the error to continue with the walk, or raise the exception
+to abort the walk.  Note that the filename is available as the
+\code{filename} attribute of the exception object.
+
+\begin{notice}
+If you pass a relative pathname, don't change the current working
+directory between resumptions of \function{walk()}.  \function{walk()}
+never changes the current directory, and assumes that its caller
+doesn't either.
+\end{notice}
+
+\begin{notice}
+On systems that support symbolic links, links to subdirectories appear
+in \var{dirnames} lists, but \function{walk()} will not visit them
+(infinite loops are hard to avoid when following symbolic links).
+To visit linked directories, you can identify them with
+\code{os.path.islink(\var{path})}, and invoke \code{walk(\var{path})}
+on each directly.
+\end{notice}
+
+This example displays the number of bytes taken by non-directory files
+in each directory under the starting directory, except that it doesn't
+look under any CVS subdirectory:
+
+\begin{verbatim}
+import os
+from os.path import join, getsize
+for root, dirs, files in os.walk('python/Lib/email'):
+    print root, "consumes",
+    print sum(getsize(join(root, name)) for name in files),
+    print "bytes in", len(files), "non-directory files"
+    if 'CVS' in dirs:
+        dirs.remove('CVS')  # don't visit CVS directories
+\end{verbatim}
+
+In the next example, walking the tree bottom up is essential:
+\function{rmdir()} doesn't allow deleting a directory before the
+directory is empty:
+
+\begin{verbatim}
+# Delete everything reachable from the directory named in 'top',
+# assuming there are no symbolic links.
+# CAUTION:  This is dangerous!  For example, if top == '/', it
+# could delete all your disk files.
+import os
+for root, dirs, files in os.walk(top, topdown=False):
+    for name in files:
+        os.remove(os.path.join(root, name))
+    for name in dirs:
+        os.rmdir(os.path.join(root, name))
+\end{verbatim}
+
+\versionadded{2.3}
+\end{funcdesc}
+
+\subsection{Process Management \label{os-process}}
+
+These functions may be used to create and manage processes.
+
+The various \function{exec*()} functions take a list of arguments for
+the new program loaded into the process.  In each case, the first of
+these arguments is passed to the new program as its own name rather
+than as an argument a user may have typed on a command line.  For the
+C programmer, this is the \code{argv[0]} passed to a program's
+\cfunction{main()}.  For example, \samp{os.execv('/bin/echo', ['foo',
+'bar'])} will only print \samp{bar} on standard output; \samp{foo}
+will seem to be ignored.
+
+
+\begin{funcdesc}{abort}{}
+Generate a \constant{SIGABRT} signal to the current process.  On
+\UNIX, the default behavior is to produce a core dump; on Windows, the
+process immediately returns an exit code of \code{3}.  Be aware that
+programs which use \function{signal.signal()} to register a handler
+for \constant{SIGABRT} will behave differently.
+Availability: Macintosh, \UNIX, Windows.
+\end{funcdesc}
+
+\begin{funcdesc}{execl}{path, arg0, arg1, \moreargs}
+\funcline{execle}{path, arg0, arg1, \moreargs, env}
+\funcline{execlp}{file, arg0, arg1, \moreargs}
+\funcline{execlpe}{file, arg0, arg1, \moreargs, env}
+\funcline{execv}{path, args}
+\funcline{execve}{path, args, env}
+\funcline{execvp}{file, args}
+\funcline{execvpe}{file, args, env}
+These functions all execute a new program, replacing the current
+process; they do not return.  On \UNIX, the new executable is loaded
+into the current process, and will have the same process ID as the
+caller.  Errors will be reported as \exception{OSError} exceptions.
+
+The \character{l} and \character{v} variants of the
+\function{exec*()} functions differ in how command-line arguments are
+passed.  The \character{l} variants are perhaps the easiest to work
+with if the number of parameters is fixed when the code is written;
+the individual parameters simply become additional parameters to the
+\function{execl*()} functions.  The \character{v} variants are good
+when the number of parameters is variable, with the arguments being
+passed in a list or tuple as the \var{args} parameter.  In either
+case, the arguments to the child process should start with the name of
+the command being run, but this is not enforced.
+
+The variants which include a \character{p} near the end
+(\function{execlp()}, \function{execlpe()}, \function{execvp()},
+and \function{execvpe()}) will use the \envvar{PATH} environment
+variable to locate the program \var{file}.  When the environment is
+being replaced (using one of the \function{exec*e()} variants,
+discussed in the next paragraph), the
+new environment is used as the source of the \envvar{PATH} variable.
+The other variants, \function{execl()}, \function{execle()},
+\function{execv()}, and \function{execve()}, will not use the
+\envvar{PATH} variable to locate the executable; \var{path} must
+contain an appropriate absolute or relative path.
+
+For \function{execle()}, \function{execlpe()}, \function{execve()},
+and \function{execvpe()} (note that these all end in \character{e}),
+the \var{env} parameter must be a mapping which is used to define the
+environment variables for the new process; the \function{execl()},
+\function{execlp()}, \function{execv()}, and \function{execvp()}
+all cause the new process to inherit the environment of the current
+process.
+Availability: Macintosh, \UNIX, Windows.
+\end{funcdesc}
+
+\begin{funcdesc}{_exit}{n}
+Exit to the system with status \var{n}, without calling cleanup
+handlers, flushing stdio buffers, etc.
+Availability: Macintosh, \UNIX, Windows.
+
+\begin{notice}
+The standard way to exit is \code{sys.exit(\var{n})}.
+\function{_exit()} should normally only be used in the child process
+after a \function{fork()}.
+\end{notice}
+\end{funcdesc}
+
+The following exit codes are a defined, and can be used with
+\function{_exit()}, although they are not required.  These are
+typically used for system programs written in Python, such as a
+mail server's external command delivery program.
+\note{Some of these may not be available on all \UNIX{} platforms,
+since there is some variation.  These constants are defined where they
+are defined by the underlying platform.}
+
+\begin{datadesc}{EX_OK}
+Exit code that means no error occurred.
+Availability: Macintosh, \UNIX.
+\versionadded{2.3}
+\end{datadesc}
+
+\begin{datadesc}{EX_USAGE}
+Exit code that means the command was used incorrectly, such as when
+the wrong number of arguments are given.
+Availability: Macintosh, \UNIX.
+\versionadded{2.3}
+\end{datadesc}
+
+\begin{datadesc}{EX_DATAERR}
+Exit code that means the input data was incorrect.
+Availability: Macintosh, \UNIX.
+\versionadded{2.3}
+\end{datadesc}
+
+\begin{datadesc}{EX_NOINPUT}
+Exit code that means an input file did not exist or was not readable.
+Availability: Macintosh, \UNIX.
+\versionadded{2.3}
+\end{datadesc}
+
+\begin{datadesc}{EX_NOUSER}
+Exit code that means a specified user did not exist.
+Availability: Macintosh, \UNIX.
+\versionadded{2.3}
+\end{datadesc}
+
+\begin{datadesc}{EX_NOHOST}
+Exit code that means a specified host did not exist.
+Availability: Macintosh, \UNIX.
+\versionadded{2.3}
+\end{datadesc}
+
+\begin{datadesc}{EX_UNAVAILABLE}
+Exit code that means that a required service is unavailable.
+Availability: Macintosh, \UNIX.
+\versionadded{2.3}
+\end{datadesc}
+
+\begin{datadesc}{EX_SOFTWARE}
+Exit code that means an internal software error was detected.
+Availability: Macintosh, \UNIX.
+\versionadded{2.3}
+\end{datadesc}
+
+\begin{datadesc}{EX_OSERR}
+Exit code that means an operating system error was detected, such as
+the inability to fork or create a pipe.
+Availability: Macintosh, \UNIX.
+\versionadded{2.3}
+\end{datadesc}
+
+\begin{datadesc}{EX_OSFILE}
+Exit code that means some system file did not exist, could not be
+opened, or had some other kind of error.
+Availability: Macintosh, \UNIX.
+\versionadded{2.3}
+\end{datadesc}
+
+\begin{datadesc}{EX_CANTCREAT}
+Exit code that means a user specified output file could not be created.
+Availability: Macintosh, \UNIX.
+\versionadded{2.3}
+\end{datadesc}
+
+\begin{datadesc}{EX_IOERR}
+Exit code that means that an error occurred while doing I/O on some file.
+Availability: Macintosh, \UNIX.
+\versionadded{2.3}
+\end{datadesc}
+
+\begin{datadesc}{EX_TEMPFAIL}
+Exit code that means a temporary failure occurred.  This indicates
+something that may not really be an error, such as a network
+connection that couldn't be made during a retryable operation.
+Availability: Macintosh, \UNIX.
+\versionadded{2.3}
+\end{datadesc}
+
+\begin{datadesc}{EX_PROTOCOL}
+Exit code that means that a protocol exchange was illegal, invalid, or
+not understood.
+Availability: Macintosh, \UNIX.
+\versionadded{2.3}
+\end{datadesc}
+
+\begin{datadesc}{EX_NOPERM}
+Exit code that means that there were insufficient permissions to
+perform the operation (but not intended for file system problems).
+Availability: Macintosh, \UNIX.
+\versionadded{2.3}
+\end{datadesc}
+
+\begin{datadesc}{EX_CONFIG}
+Exit code that means that some kind of configuration error occurred.
+Availability: Macintosh, \UNIX.
+\versionadded{2.3}
+\end{datadesc}
+
+\begin{datadesc}{EX_NOTFOUND}
+Exit code that means something like ``an entry was not found''.
+Availability: Macintosh, \UNIX.
+\versionadded{2.3}
+\end{datadesc}
+
+\begin{funcdesc}{fork}{}
+Fork a child process.  Return \code{0} in the child, the child's
+process id in the parent.
+Availability: Macintosh, \UNIX.
+\end{funcdesc}
+
+\begin{funcdesc}{forkpty}{}
+Fork a child process, using a new pseudo-terminal as the child's
+controlling terminal. Return a pair of \code{(\var{pid}, \var{fd})},
+where \var{pid} is \code{0} in the child, the new child's process id
+in the parent, and \var{fd} is the file descriptor of the master end
+of the pseudo-terminal.  For a more portable approach, use the
+\refmodule{pty} module.
+Availability: Macintosh, Some flavors of \UNIX.
+\end{funcdesc}
+
+\begin{funcdesc}{kill}{pid, sig}
+\index{process!killing}
+\index{process!signalling}
+Send signal \var{sig} to the process \var{pid}.  Constants for the
+specific signals available on the host platform are defined in the
+\refmodule{signal} module.
+Availability: Macintosh, \UNIX.
+\end{funcdesc}
+
+\begin{funcdesc}{killpg}{pgid, sig}
+\index{process!killing}
+\index{process!signalling}
+Send the signal \var{sig} to the process group \var{pgid}.
+Availability: Macintosh, \UNIX.
+\versionadded{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{nice}{increment}
+Add \var{increment} to the process's ``niceness''.  Return the new
+niceness.
+Availability: Macintosh, \UNIX.
+\end{funcdesc}
+
+\begin{funcdesc}{plock}{op}
+Lock program segments into memory.  The value of \var{op}
+(defined in \code{<sys/lock.h>}) determines which segments are locked.
+Availability: Macintosh, \UNIX.
+\end{funcdesc}
+
+\begin{funcdescni}{popen}{\unspecified}
+\funclineni{popen2}{\unspecified}
+\funclineni{popen3}{\unspecified}
+\funclineni{popen4}{\unspecified}
+Run child processes, returning opened pipes for communications.  These
+functions are described in section \ref{os-newstreams}.
+\end{funcdescni}
+
+\begin{funcdesc}{spawnl}{mode, path, \moreargs}
+\funcline{spawnle}{mode, path, \moreargs, env}
+\funcline{spawnlp}{mode, file, \moreargs}
+\funcline{spawnlpe}{mode, file, \moreargs, env}
+\funcline{spawnv}{mode, path, args}
+\funcline{spawnve}{mode, path, args, env}
+\funcline{spawnvp}{mode, file, args}
+\funcline{spawnvpe}{mode, file, args, env}
+Execute the program \var{path} in a new process.  
+
+(Note that the \module{subprocess} module provides more powerful
+facilities for spawning new processes and retrieving their results;
+using that module is preferable to using these functions.)
+
+If \var{mode} is
+\constant{P_NOWAIT}, this function returns the process ID of the new
+process; if \var{mode} is \constant{P_WAIT}, returns the process's
+exit code if it exits normally, or \code{-\var{signal}}, where
+\var{signal} is the signal that killed the process.  On Windows, the
+process ID will actually be the process handle, so can be used with
+the \function{waitpid()} function.
+
+The \character{l} and \character{v} variants of the
+\function{spawn*()} functions differ in how command-line arguments are
+passed.  The \character{l} variants are perhaps the easiest to work
+with if the number of parameters is fixed when the code is written;
+the individual parameters simply become additional parameters to the
+\function{spawnl*()} functions.  The \character{v} variants are good
+when the number of parameters is variable, with the arguments being
+passed in a list or tuple as the \var{args} parameter.  In either
+case, the arguments to the child process must start with the name of
+the command being run.
+
+The variants which include a second \character{p} near the end
+(\function{spawnlp()}, \function{spawnlpe()}, \function{spawnvp()},
+and \function{spawnvpe()}) will use the \envvar{PATH} environment
+variable to locate the program \var{file}.  When the environment is
+being replaced (using one of the \function{spawn*e()} variants,
+discussed in the next paragraph), the new environment is used as the
+source of the \envvar{PATH} variable.  The other variants,
+\function{spawnl()}, \function{spawnle()}, \function{spawnv()}, and
+\function{spawnve()}, will not use the \envvar{PATH} variable to
+locate the executable; \var{path} must contain an appropriate absolute
+or relative path.
+
+For \function{spawnle()}, \function{spawnlpe()}, \function{spawnve()},
+and \function{spawnvpe()} (note that these all end in \character{e}),
+the \var{env} parameter must be a mapping which is used to define the
+environment variables for the new process; the \function{spawnl()},
+\function{spawnlp()}, \function{spawnv()}, and \function{spawnvp()}
+all cause the new process to inherit the environment of the current
+process.
+
+As an example, the following calls to \function{spawnlp()} and
+\function{spawnvpe()} are equivalent:
+
+\begin{verbatim}
+import os
+os.spawnlp(os.P_WAIT, 'cp', 'cp', 'index.html', '/dev/null')
+
+L = ['cp', 'index.html', '/dev/null']
+os.spawnvpe(os.P_WAIT, 'cp', L, os.environ)
+\end{verbatim}
+
+Availability: \UNIX, Windows.  \function{spawnlp()},
+\function{spawnlpe()}, \function{spawnvp()} and \function{spawnvpe()}
+are not available on Windows.
+\versionadded{1.6}
+\end{funcdesc}
+
+\begin{datadesc}{P_NOWAIT}
+\dataline{P_NOWAITO}
+Possible values for the \var{mode} parameter to the \function{spawn*()}
+family of functions.  If either of these values is given, the
+\function{spawn*()} functions will return as soon as the new process
+has been created, with the process ID as the return value.
+Availability: Macintosh, \UNIX, Windows.
+\versionadded{1.6}
+\end{datadesc}
+
+\begin{datadesc}{P_WAIT}
+Possible value for the \var{mode} parameter to the \function{spawn*()}
+family of functions.  If this is given as \var{mode}, the
+\function{spawn*()} functions will not return until the new process
+has run to completion and will return the exit code of the process the
+run is successful, or \code{-\var{signal}} if a signal kills the
+process.
+Availability: Macintosh, \UNIX, Windows.
+\versionadded{1.6}
+\end{datadesc}
+
+\begin{datadesc}{P_DETACH}
+\dataline{P_OVERLAY}
+Possible values for the \var{mode} parameter to the
+\function{spawn*()} family of functions.  These are less portable than
+those listed above.
+\constant{P_DETACH} is similar to \constant{P_NOWAIT}, but the new
+process is detached from the console of the calling process.
+If \constant{P_OVERLAY} is used, the current process will be replaced;
+the \function{spawn*()} function will not return.
+Availability: Windows.
+\versionadded{1.6}
+\end{datadesc}
+
+\begin{funcdesc}{startfile}{path\optional{, operation}}
+Start a file with its associated application.
+
+When \var{operation} is not specified or \code{'open'}, this acts like
+double-clicking the file in Windows Explorer, or giving the file name
+as an argument to the \program{start} command from the interactive
+command shell: the file is opened with whatever application (if any)
+its extension is associated.
+
+When another \var{operation} is given, it must be a ``command verb''
+that specifies what should be done with the file.
+Common verbs documented by Microsoft are \code{'print'} and 
+\code{'edit'} (to be used on files) as well as \code{'explore'} and
+\code{'find'} (to be used on directories).
+
+\function{startfile()} returns as soon as the associated application
+is launched.  There is no option to wait for the application to close,
+and no way to retrieve the application's exit status.  The \var{path}
+parameter is relative to the current directory.  If you want to use an
+absolute path, make sure the first character is not a slash
+(\character{/}); the underlying Win32 \cfunction{ShellExecute()}
+function doesn't work if it is.  Use the \function{os.path.normpath()}
+function to ensure that the path is properly encoded for Win32.
+Availability: Windows.
+\versionadded{2.0}
+\versionadded[The \var{operation} parameter]{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{system}{command}
+Execute the command (a string) in a subshell.  This is implemented by
+calling the Standard C function \cfunction{system()}, and has the
+same limitations.  Changes to \code{posix.environ}, \code{sys.stdin},
+etc.\ are not reflected in the environment of the executed command.
+
+On \UNIX, the return value is the exit status of the process encoded in the
+format specified for \function{wait()}.  Note that \POSIX{} does not
+specify the meaning of the return value of the C \cfunction{system()}
+function, so the return value of the Python function is system-dependent.
+
+On Windows, the return value is that returned by the system shell after
+running \var{command}, given by the Windows environment variable
+\envvar{COMSPEC}: on \program{command.com} systems (Windows 95, 98 and ME)
+this is always \code{0}; on \program{cmd.exe} systems (Windows NT, 2000
+and XP) this is the exit status of the command run; on systems using
+a non-native shell, consult your shell documentation.
+
+Availability: Macintosh, \UNIX, Windows.
+
+The \module{subprocess} module provides more powerful facilities for
+spawning new processes and retrieving their results; using that module
+is preferable to using this function.
+\end{funcdesc}
+
+\begin{funcdesc}{times}{}
+Return a 5-tuple of floating point numbers indicating accumulated
+(processor or other)
+times, in seconds.  The items are: user time, system time, children's
+user time, children's system time, and elapsed real time since a fixed
+point in the past, in that order.  See the \UNIX{} manual page
+\manpage{times}{2} or the corresponding Windows Platform API
+documentation.
+Availability: Macintosh, \UNIX, Windows.
+\end{funcdesc}
+
+\begin{funcdesc}{wait}{}
+Wait for completion of a child process, and return a tuple containing
+its pid and exit status indication: a 16-bit number, whose low byte is
+the signal number that killed the process, and whose high byte is the
+exit status (if the signal number is zero); the high bit of the low
+byte is set if a core file was produced.
+Availability: Macintosh, \UNIX.
+\end{funcdesc}
+
+\begin{funcdesc}{waitpid}{pid, options}
+The details of this function differ on \UNIX{} and Windows.
+
+On \UNIX:
+Wait for completion of a child process given by process id \var{pid},
+and return a tuple containing its process id and exit status
+indication (encoded as for \function{wait()}).  The semantics of the
+call are affected by the value of the integer \var{options}, which
+should be \code{0} for normal operation.
+
+If \var{pid} is greater than \code{0}, \function{waitpid()} requests
+status information for that specific process.  If \var{pid} is
+\code{0}, the request is for the status of any child in the process
+group of the current process.  If \var{pid} is \code{-1}, the request
+pertains to any child of the current process.  If \var{pid} is less
+than \code{-1}, status is requested for any process in the process
+group \code{-\var{pid}} (the absolute value of \var{pid}).
+
+On Windows:
+Wait for completion of a process given by process handle \var{pid},
+and return a tuple containing \var{pid},
+and its exit status shifted left by 8 bits (shifting makes cross-platform
+use of the function easier).
+A \var{pid} less than or equal to \code{0} has no special meaning on
+Windows, and raises an exception.
+The value of integer \var{options} has no effect.
+\var{pid} can refer to any process whose id is known, not necessarily a
+child process.
+The \function{spawn()} functions called with \constant{P_NOWAIT}
+return suitable process handles.
+\end{funcdesc}
+
+\begin{funcdesc}{wait3}{\optional{options}}
+Similar to \function{waitpid()}, except no process id argument is given and
+a 3-element tuple containing the child's process id, exit status indication,
+and resource usage information is returned.  Refer to
+\module{resource}.\function{getrusage()}
+for details on resource usage information.  The option argument is the same
+as that provided to \function{waitpid()} and \function{wait4()}.
+Availability: \UNIX.
+\versionadded{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{wait4}{pid, options}
+Similar to \function{waitpid()}, except a 3-element tuple, containing the
+child's process id, exit status indication, and resource usage information
+is returned.  Refer to \module{resource}.\function{getrusage()} for details
+on resource usage information.  The arguments to \function{wait4()} are
+the same as those provided to \function{waitpid()}.
+Availability: \UNIX.
+\versionadded{2.5}
+\end{funcdesc}
+
+\begin{datadesc}{WNOHANG}
+The option for \function{waitpid()} to return immediately if no child
+process status is available immediately. The function returns
+\code{(0, 0)} in this case.
+Availability: Macintosh, \UNIX.
+\end{datadesc}
+
+\begin{datadesc}{WCONTINUED}
+This option causes child processes to be reported if they have been
+continued from a job control stop since their status was last
+reported.
+Availability: Some \UNIX{} systems.
+\versionadded{2.3}
+\end{datadesc}
+
+\begin{datadesc}{WUNTRACED}
+This option causes child processes to be reported if they have been
+stopped but their current state has not been reported since they were
+stopped.
+Availability: Macintosh, \UNIX.
+\versionadded{2.3}
+\end{datadesc}
+
+The following functions take a process status code as returned by
+\function{system()}, \function{wait()}, or \function{waitpid()} as a
+parameter.  They may be used to determine the disposition of a
+process.
+
+\begin{funcdesc}{WCOREDUMP}{status}
+Returns \code{True} if a core dump was generated for the process,
+otherwise it returns \code{False}.
+Availability: Macintosh, \UNIX.
+\versionadded{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{WIFCONTINUED}{status}
+Returns \code{True} if the process has been continued from a job
+control stop, otherwise it returns \code{False}.
+Availability: \UNIX.
+\versionadded{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{WIFSTOPPED}{status}
+Returns \code{True} if the process has been stopped, otherwise it
+returns \code{False}.
+Availability: \UNIX.
+\end{funcdesc}
+
+\begin{funcdesc}{WIFSIGNALED}{status}
+Returns \code{True} if the process exited due to a signal, otherwise
+it returns \code{False}.
+Availability: Macintosh, \UNIX.
+\end{funcdesc}
+
+\begin{funcdesc}{WIFEXITED}{status}
+Returns \code{True} if the process exited using the \manpage{exit}{2}
+system call, otherwise it returns \code{False}.
+Availability: Macintosh, \UNIX.
+\end{funcdesc}
+
+\begin{funcdesc}{WEXITSTATUS}{status}
+If \code{WIFEXITED(\var{status})} is true, return the integer
+parameter to the \manpage{exit}{2} system call.  Otherwise, the return
+value is meaningless.
+Availability: Macintosh, \UNIX.
+\end{funcdesc}
+
+\begin{funcdesc}{WSTOPSIG}{status}
+Return the signal which caused the process to stop.
+Availability: Macintosh, \UNIX.
+\end{funcdesc}
+
+\begin{funcdesc}{WTERMSIG}{status}
+Return the signal which caused the process to exit.
+Availability: Macintosh, \UNIX.
+\end{funcdesc}
+
+
+\subsection{Miscellaneous System Information \label{os-path}}
+
+
+\begin{funcdesc}{confstr}{name}
+Return string-valued system configuration values.
+\var{name} specifies the configuration value to retrieve; it may be a
+string which is the name of a defined system value; these names are
+specified in a number of standards (\POSIX, \UNIX{} 95, \UNIX{} 98, and
+others).  Some platforms define additional names as well.  The names
+known to the host operating system are given as the keys of the
+\code{confstr_names} dictionary.  For configuration variables not
+included in that mapping, passing an integer for \var{name} is also
+accepted.
+Availability: Macintosh, \UNIX.
+
+If the configuration value specified by \var{name} isn't defined,
+\code{None} is returned.
+
+If \var{name} is a string and is not known, \exception{ValueError} is
+raised.  If a specific value for \var{name} is not supported by the
+host system, even if it is included in \code{confstr_names}, an
+\exception{OSError} is raised with \constant{errno.EINVAL} for the
+error number.
+\end{funcdesc}
+
+\begin{datadesc}{confstr_names}
+Dictionary mapping names accepted by \function{confstr()} to the
+integer values defined for those names by the host operating system.
+This can be used to determine the set of names known to the system.
+Availability: Macintosh, \UNIX.
+\end{datadesc}
+
+\begin{funcdesc}{getloadavg}{}
+Return the number of processes in the system run queue averaged over
+the last 1, 5, and 15 minutes or raises \exception{OSError} if the load 
+average was unobtainable.
+
+\versionadded{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{sysconf}{name}
+Return integer-valued system configuration values.
+If the configuration value specified by \var{name} isn't defined,
+\code{-1} is returned.  The comments regarding the \var{name}
+parameter for \function{confstr()} apply here as well; the dictionary
+that provides information on the known names is given by
+\code{sysconf_names}.
+Availability: Macintosh, \UNIX.
+\end{funcdesc}
+
+\begin{datadesc}{sysconf_names}
+Dictionary mapping names accepted by \function{sysconf()} to the
+integer values defined for those names by the host operating system.
+This can be used to determine the set of names known to the system.
+Availability: Macintosh, \UNIX.
+\end{datadesc}
+
+
+The follow data values are used to support path manipulation
+operations.  These are defined for all platforms.
+
+Higher-level operations on pathnames are defined in the
+\refmodule{os.path} module.
+
+
+\begin{datadesc}{curdir}
+The constant string used by the operating system to refer to the current
+directory.
+For example: \code{'.'} for \POSIX{} or \code{':'} for Mac OS 9.
+Also available via \module{os.path}.
+\end{datadesc}
+
+\begin{datadesc}{pardir}
+The constant string used by the operating system to refer to the parent
+directory.
+For example: \code{'..'} for \POSIX{} or \code{'::'} for Mac OS 9.
+Also available via \module{os.path}.
+\end{datadesc}
+
+\begin{datadesc}{sep}
+The character used by the operating system to separate pathname components,
+for example, \character{/} for \POSIX{} or \character{:} for
+Mac OS 9.  Note that knowing this is not sufficient to be able to
+parse or concatenate pathnames --- use \function{os.path.split()} and
+\function{os.path.join()} --- but it is occasionally useful.
+Also available via \module{os.path}.
+\end{datadesc}
+
+\begin{datadesc}{altsep}
+An alternative character used by the operating system to separate pathname
+components, or \code{None} if only one separator character exists.  This is
+set to \character{/} on Windows systems where \code{sep} is a
+backslash.
+Also available via \module{os.path}.
+\end{datadesc}
+
+\begin{datadesc}{extsep}
+The character which separates the base filename from the extension;
+for example, the \character{.} in \file{os.py}.
+Also available via \module{os.path}.
+\versionadded{2.2}
+\end{datadesc}
+
+\begin{datadesc}{pathsep}
+The character conventionally used by the operating system to separate
+search path components (as in \envvar{PATH}), such as \character{:} for
+\POSIX{} or \character{;} for Windows.
+Also available via \module{os.path}.
+\end{datadesc}
+
+\begin{datadesc}{defpath}
+The default search path used by \function{exec*p*()} and
+\function{spawn*p*()} if the environment doesn't have a \code{'PATH'}
+key.
+Also available via \module{os.path}.
+\end{datadesc}
+
+\begin{datadesc}{linesep}
+The string used to separate (or, rather, terminate) lines on the
+current platform.  This may be a single character, such as \code{'\e
+n'} for \POSIX{} or \code{'\e r'} for Mac OS, or multiple characters,
+for example, \code{'\e r\e n'} for Windows.
+\end{datadesc}
+
+\begin{datadesc}{devnull}
+The file path of the null device.
+For example: \code{'/dev/null'} for \POSIX{} or \code{'Dev:Nul'} for
+Mac OS 9.
+Also available via \module{os.path}.
+\versionadded{2.4}
+\end{datadesc}
+
+
+\subsection{Miscellaneous Functions \label{os-miscfunc}}
+
+\begin{funcdesc}{urandom}{n}
+Return a string of \var{n} random bytes suitable for cryptographic use.
+
+This function returns random bytes from an OS-specific
+randomness source.  The returned data should be unpredictable enough for
+cryptographic applications, though its exact quality depends on the OS
+implementation.  On a UNIX-like system this will query /dev/urandom, and
+on Windows it will use CryptGenRandom.  If a randomness source is not
+found, \exception{NotImplementedError} will be raised.
+\versionadded{2.4}
+\end{funcdesc}
+
+
+
+

Added: vendor/Python/current/Doc/lib/libossaudiodev.tex
===================================================================
--- vendor/Python/current/Doc/lib/libossaudiodev.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libossaudiodev.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,401 @@
+\section{\module{ossaudiodev} ---
+         Access to OSS-compatible audio devices}
+
+\declaremodule{builtin}{ossaudiodev}
+\platform{Linux, FreeBSD}
+\modulesynopsis{Access to OSS-compatible audio devices.}
+
+\versionadded{2.3}
+
+This module allows you to access the OSS (Open Sound System) audio
+interface.  OSS is available for a wide range of open-source and
+commercial Unices, and is the standard audio interface for Linux and
+recent versions of FreeBSD.
+
+% Things will get more complicated for future Linux versions, since
+% ALSA is in the standard kernel as of 2.5.x.  Presumably if you
+% use ALSA, you'll have to make sure its OSS compatibility layer
+% is active to use ossaudiodev, but you're gonna need it for the vast
+% majority of Linux audio apps anyways.  
+%
+% Sounds like things are also complicated for other BSDs.  In response
+% to my python-dev query, Thomas Wouters said:
+%
+% > Likewise, googling shows OpenBSD also uses OSS/Free -- the commercial
+% > OSS installation manual tells you to remove references to OSS/Free from the
+% > kernel :)
+%
+% but Aleksander Piotrowsk actually has an OpenBSD box, and he quotes
+% from its <soundcard.h>:
+% >  * WARNING!  WARNING!
+% >  * This is an OSS (Linux) audio emulator.
+% >  * Use the Native NetBSD API for developing new code, and this
+% >  * only for compiling Linux programs.
+%
+% There's also an ossaudio manpage on OpenBSD that explains things
+% further.  Presumably NetBSD and OpenBSD have a different standard
+% audio interface.  That's the great thing about standards, there are so
+% many to choose from ... ;-)  
+%
+% This probably all warrants a footnote or two, but I don't understand
+% things well enough right now to write it!   --GPW
+
+\begin{seealso}
+\seetitle[http://www.opensound.com/pguide/oss.pdf]
+         {Open Sound System Programmer's Guide} {the official
+         documentation for the OSS C API}
+\seetext{The module defines a large number of constants supplied by
+         the OSS device driver; see \code{<sys/soundcard.h>} on either
+         Linux or FreeBSD for a listing .}
+\end{seealso}
+
+\module{ossaudiodev} defines the following variables and functions:
+
+\begin{excdesc}{OSSAudioError}
+This exception is raised on certain errors.  The argument is a string
+describing what went wrong.
+
+(If \module{ossaudiodev} receives an error from a system call such as
+\cfunction{open()}, \cfunction{write()}, or \cfunction{ioctl()}, it
+raises \exception{IOError}.  Errors detected directly by
+\module{ossaudiodev} result in \exception{OSSAudioError}.)
+
+(For backwards compatibility, the exception class is also available as
+\code{ossaudiodev.error}.)
+\end{excdesc}
+
+\begin{funcdesc}{open}{\optional{device, }mode}
+Open an audio device and return an OSS audio device object.  This
+object supports many file-like methods, such as \method{read()},
+\method{write()}, and \method{fileno()} (although there are subtle
+differences between conventional \UNIX{} read/write semantics and those of
+OSS audio devices).  It also supports a number of audio-specific
+methods; see below for the complete list of methods.
+
+\var{device} is the audio device filename to use.  If it is not
+specified, this module first looks in the environment variable
+\envvar{AUDIODEV} for a device to use.  If not found, it falls back to
+\file{/dev/dsp}.
+
+\var{mode} is one of \code{'r'} for read-only (record) access,
+\code{'w'} for write-only (playback) access and \code{'rw'} for both.
+Since many sound cards only allow one process to have the recorder or
+player open at a time, it is a good idea to open the device only for the
+activity needed.  Further, some sound cards are half-duplex: they can be
+opened for reading or writing, but not both at once.
+
+Note the unusual calling syntax: the \emph{first} argument is optional,
+and the second is required.  This is a historical artifact for
+compatibility with the older \module{linuxaudiodev} module which
+\module{ossaudiodev} supersedes.  % XXX it might also be motivated
+% by my unfounded-but-still-possibly-true belief that the default
+% audio device varies unpredictably across operating systems.  -GW
+\end{funcdesc}
+
+\begin{funcdesc}{openmixer}{\optional{device}}
+Open a mixer device and return an OSS mixer device object.  
+\var{device} is the mixer device filename to use.  If it is
+not specified, this module first looks in the environment variable
+\envvar{MIXERDEV} for a device to use.  If not found, it falls back to
+\file{/dev/mixer}.
+
+\end{funcdesc}
+
+\subsection{Audio Device Objects \label{ossaudio-device-objects}}
+
+Before you can write to or read from an audio device, you must call
+three methods in the correct order:
+\begin{enumerate}
+\item \method{setfmt()} to set the output format
+\item \method{channels()} to set the number of channels
+\item \method{speed()} to set the sample rate
+\end{enumerate}
+Alternately, you can use the \method{setparameters()} method to set all
+three audio parameters at once.  This is more convenient, but may not be
+as flexible in all cases.
+
+The audio device objects returned by \function{open()} define the
+following methods and (read-only) attributes:
+
+\begin{methoddesc}[audio device]{close}{}
+Explicitly close the audio device.  When you are done writing to or
+reading from an audio device, you should explicitly close it.  A closed
+device cannot be used again.
+\end{methoddesc}
+
+\begin{methoddesc}[audio device]{fileno}{}
+Return the file descriptor associated with the device.
+\end{methoddesc}
+
+\begin{methoddesc}[audio device]{read}{size}
+Read \var{size} bytes from the audio input and return them as a Python
+string.  Unlike most \UNIX{} device drivers, OSS audio devices in
+blocking mode (the default) will block \function{read()} until the
+entire requested amount of data is available.
+\end{methoddesc}
+
+\begin{methoddesc}[audio device]{write}{data}
+Write the Python string \var{data} to the audio device and return the
+number of bytes written.  If the audio device is in blocking mode (the
+default), the entire string is always written (again, this is different
+from usual \UNIX{} device semantics).  If the device is in non-blocking
+mode, some data may not be written---see \method{writeall()}.
+\end{methoddesc}
+
+\begin{methoddesc}[audio device]{writeall}{data}
+Write the entire Python string \var{data} to the audio device: waits
+until the audio device is able to accept data, writes as much data as it
+will accept, and repeats until \var{data} has been completely written.
+If the device is in blocking mode (the default), this has the same
+effect as \method{write()}; \method{writeall()} is only useful in
+non-blocking mode.  Has no return value, since the amount of data
+written is always equal to the amount of data supplied.
+\end{methoddesc}
+
+The following methods each map to exactly one
+\function{ioctl()} system call.  The correspondence is obvious: for
+example, \method{setfmt()} corresponds to the \code{SNDCTL_DSP_SETFMT}
+ioctl, and \method{sync()} to \code{SNDCTL_DSP_SYNC} (this can be useful
+when consulting the OSS documentation).  If the underlying
+\function{ioctl()} fails, they all raise \exception{IOError}.
+
+\begin{methoddesc}[audio device]{nonblock}{}
+Put the device into non-blocking mode.  Once in non-blocking mode, there
+is no way to return it to blocking mode.
+\end{methoddesc}
+
+\begin{methoddesc}[audio device]{getfmts}{}
+Return a bitmask of the audio output formats supported by the
+soundcard.  Some of the formats supported by OSS are:
+
+\begin{tableii}{l|l}{constant}{Format}{Description}
+\lineii{AFMT_MU_LAW}
+       {a logarithmic encoding (used by Sun \code{.au} files and
+        \filenq{/dev/audio})}
+\lineii{AFMT_A_LAW}
+       {a logarithmic encoding}
+\lineii{AFMT_IMA_ADPCM}
+       {a 4:1 compressed format defined by the Interactive Multimedia
+        Association} 
+\lineii{AFMT_U8}
+       {Unsigned, 8-bit audio}
+\lineii{AFMT_S16_LE}
+       {Signed, 16-bit audio, little-endian byte order (as used by
+        Intel processors)}
+\lineii{AFMT_S16_BE}
+       {Signed, 16-bit audio, big-endian byte order (as used by 68k,
+        PowerPC, Sparc)}
+\lineii{AFMT_S8}
+       {Signed, 8 bit audio}
+\lineii{AFMT_U16_LE}
+       {Unsigned, 16-bit little-endian audio}
+\lineii{AFMT_U16_BE}
+       {Unsigned, 16-bit big-endian audio}
+\end{tableii}
+Consult the OSS documentation for a full list of audio formats, and note
+that most devices support only a subset of these formats.  Some older
+devices only support \constant{AFMT_U8}; the most common format used
+today is \constant{AFMT_S16_LE}.
+\end{methoddesc}
+
+\begin{methoddesc}[audio device]{setfmt}{format}
+Try to set the current audio format to \var{format}---see
+\method{getfmts()} for a list.  Returns the audio format that the device
+was set to, which may not be the requested format.  May also be used to
+return the current audio format---do this by passing an ``audio format''
+of
+\constant{AFMT_QUERY}.  
+\end{methoddesc}
+
+\begin{methoddesc}[audio device]{channels}{nchannels}
+Set the number of output channels to \var{nchannels}.  A value of 1
+indicates monophonic sound, 2 stereophonic.  Some devices may have more
+than 2 channels, and some high-end devices may not support mono.
+Returns the number of channels the device was set to.
+\end{methoddesc}
+
+\begin{methoddesc}[audio device]{speed}{samplerate}
+Try to set the audio sampling rate to \var{samplerate} samples per
+second.  Returns the rate actually set.  Most sound devices don't
+support arbitrary sampling rates.  Common rates are:
+\begin{tableii}{l|l}{textrm}{Rate}{Description}
+\lineii{8000}{default rate for \filenq{/dev/audio}}
+\lineii{11025}{speech recording}
+\lineii{22050}{}
+\lineii{44100}{CD quality audio (at 16 bits/sample and 2 channels)}
+\lineii{96000}{DVD quality audio (at 24 bits/sample)}
+\end{tableii}
+\end{methoddesc}
+
+\begin{methoddesc}[audio device]{sync}{}
+Wait until the sound device has played every byte in its buffer.  (This
+happens implicitly when the device is closed.)  The OSS documentation
+recommends closing and re-opening the device rather than using
+\method{sync()}.
+\end{methoddesc}
+
+\begin{methoddesc}[audio device]{reset}{}
+Immediately stop playing or recording and return the device to a
+state where it can accept commands.  The OSS documentation recommends
+closing and re-opening the device after calling \method{reset()}.
+\end{methoddesc}
+
+\begin{methoddesc}[audio device]{post}{}
+Tell the driver that there is likely to be a pause in the output, making
+it possible for the device to handle the pause more intelligently.  You
+might use this after playing a spot sound effect, before waiting for
+user input, or before doing disk I/O.
+\end{methoddesc}
+
+The following convenience methods combine several ioctls, or one ioctl
+and some simple calculations.
+
+\begin{methoddesc}[audio device]{setparameters}
+  {format, nchannels, samplerate \optional{, strict=False}}
+
+Set the key audio sampling parameters---sample format, number of
+channels, and sampling rate---in one method call.  \var{format}, 
+\var{nchannels}, and \var{samplerate} should be as specified in the
+\method{setfmt()}, \method{channels()}, and \method{speed()} 
+methods.  If \var{strict} is true, \method{setparameters()} checks to
+see if each parameter was actually set to the requested value, and
+raises \exception{OSSAudioError} if not.  Returns a tuple (\var{format},
+\var{nchannels}, \var{samplerate}) indicating the parameter values that
+were actually set by the device driver (i.e., the same as the return
+values of \method{setfmt()}, \method{channels()}, and \method{speed()}).
+
+For example,
+\begin{verbatim}
+  (fmt, channels, rate) = dsp.setparameters(fmt, channels, rate)
+\end{verbatim}
+is equivalent to
+\begin{verbatim}
+  fmt = dsp.setfmt(fmt)
+  channels = dsp.channels(channels)
+  rate = dsp.rate(channels)
+\end{verbatim}
+\end{methoddesc}
+
+\begin{methoddesc}[audio device]{bufsize}{}
+Returns the size of the hardware buffer, in samples.
+\end{methoddesc}
+
+\begin{methoddesc}[audio device]{obufcount}{}
+Returns the number of samples that are in the hardware buffer yet to be
+played.
+\end{methoddesc}
+
+\begin{methoddesc}[audio device]{obuffree}{}
+Returns the number of samples that could be queued into the hardware
+buffer to be played without blocking.
+\end{methoddesc}
+
+Audio device objects also support several read-only attributes:
+
+\begin{memberdesc}[audio device]{closed}{}
+Boolean indicating whether the device has been closed.
+\end{memberdesc}
+
+\begin{memberdesc}[audio device]{name}{}
+String containing the name of the device file.
+\end{memberdesc}
+
+\begin{memberdesc}[audio device]{mode}{}
+The I/O mode for the file, either \code{"r"}, \code{"rw"}, or \code{"w"}.
+\end{memberdesc}
+
+
+\subsection{Mixer Device Objects \label{mixer-device-objects}}
+
+The mixer object provides two file-like methods:
+
+\begin{methoddesc}[mixer device]{close}{}
+This method closes the open mixer device file.  Any further attempts to
+use the mixer after this file is closed will raise an \exception{IOError}.
+\end{methoddesc}
+
+\begin{methoddesc}[mixer device]{fileno}{}
+Returns the file handle number of the open mixer device file.
+\end{methoddesc}
+
+The remaining methods are specific to audio mixing:
+
+\begin{methoddesc}[mixer device]{controls}{}
+This method returns a bitmask specifying the available mixer controls
+(``Control'' being a specific mixable ``channel'', such as
+\constant{SOUND_MIXER_PCM} or \constant{SOUND_MIXER_SYNTH}).  This
+bitmask indicates a subset of all available mixer controls---the
+\constant{SOUND_MIXER_*} constants defined at module level.  To determine if,
+for example, the current mixer object supports a PCM mixer, use the
+following Python code:
+
+\begin{verbatim}
+mixer=ossaudiodev.openmixer()
+if mixer.controls() & (1 << ossaudiodev.SOUND_MIXER_PCM):
+    # PCM is supported
+    ... code ...
+\end{verbatim}
+
+For most purposes, the \constant{SOUND_MIXER_VOLUME} (master volume) and
+\constant{SOUND_MIXER_PCM} controls should suffice---but code that uses the
+mixer should be flexible when it comes to choosing mixer controls.  On
+the Gravis Ultrasound, for example, \constant{SOUND_MIXER_VOLUME} does not
+exist.
+\end{methoddesc}
+
+\begin{methoddesc}[mixer device]{stereocontrols}{}
+Returns a bitmask indicating stereo mixer controls.  If a bit is set,
+the corresponding control is stereo; if it is unset, the control is
+either monophonic or not supported by the mixer (use in combination with
+\method{controls()} to determine which).
+
+See the code example for the \method{controls()} function for an example
+of getting data from a bitmask.
+\end{methoddesc}
+
+\begin{methoddesc}[mixer device]{reccontrols}{}
+Returns a bitmask specifying the mixer controls that may be used to
+record.  See the code example for \method{controls()} for an example of
+reading from a bitmask.
+\end{methoddesc}
+
+\begin{methoddesc}[mixer device]{get}{control}
+Returns the volume of a given mixer control.  The returned volume is a
+2-tuple \code{(left_volume,right_volume)}.  Volumes are specified as
+numbers from 0 (silent) to 100 (full volume).  If the control is
+monophonic, a 2-tuple is still returned, but both volumes are
+the same.
+
+Raises \exception{OSSAudioError} if an invalid control was is specified,
+or \exception{IOError} if an unsupported control is specified.
+\end{methoddesc}
+
+\begin{methoddesc}[mixer device]{set}{control, (left, right)}
+Sets the volume for a given mixer control to \code{(left,right)}.
+\code{left} and \code{right} must be ints and between 0 (silent) and 100
+(full volume).  On success, the new volume is returned as a 2-tuple.
+Note that this may not be exactly the same as the volume specified,
+because of the limited resolution of some soundcard's mixers.
+
+Raises \exception{OSSAudioError} if an invalid mixer control was
+specified, or if the specified volumes were out-of-range.
+\end{methoddesc}
+
+\begin{methoddesc}[mixer device]{get_recsrc}{}
+This method returns a bitmask indicating which control(s) are
+currently being used as a recording source.
+\end{methoddesc}
+
+\begin{methoddesc}[mixer device]{set_recsrc}{bitmask}
+Call this function to specify a recording source.  Returns a bitmask
+indicating the new recording source (or sources) if successful; raises
+\exception{IOError} if an invalid source was specified.  To set the current
+recording source to the microphone input:
+
+\begin{verbatim}
+mixer.setrecsrc (1 << ossaudiodev.SOUND_MIXER_MIC)
+\end{verbatim}
+\end{methoddesc}
+
+
+

Added: vendor/Python/current/Doc/lib/libpanel.tex
===================================================================
--- vendor/Python/current/Doc/lib/libpanel.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libpanel.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,74 @@
+\section{\module{panel} ---
+         None}
+\declaremodule{standard}{panel}
+
+\modulesynopsis{None}
+
+
+\strong{Please note:} The FORMS library, to which the
+\code{fl}\refbimodindex{fl} module described above interfaces, is a
+simpler and more accessible user interface library for use with GL
+than the \code{panel} module (besides also being by a Dutch author).
+
+This module should be used instead of the built-in module
+\code{pnl}\refbimodindex{pnl}
+to interface with the
+\emph{Panel Library}.
+
+The module is too large to document here in its entirety.
+One interesting function:
+
+\begin{funcdesc}{defpanellist}{filename}
+Parses a panel description file containing S-expressions written by the
+\emph{Panel Editor}
+that accompanies the Panel Library and creates the described panels.
+It returns a list of panel objects.
+\end{funcdesc}
+
+\warning{The Python interpreter will dump core if you don't create a
+GL window before calling
+\code{panel.mkpanel()}
+or
+\code{panel.defpanellist()}.}
+
+\section{\module{panelparser} ---
+         None}
+\declaremodule{standard}{panelparser}
+
+\modulesynopsis{None}
+
+
+This module defines a self-contained parser for S-expressions as output
+by the Panel Editor (which is written in Scheme so it can't help writing
+S-expressions).
+The relevant function is
+\code{panelparser.parse_file(\var{file})}
+which has a file object (not a filename!) as argument and returns a list
+of parsed S-expressions.
+Each S-expression is converted into a Python list, with atoms converted
+to Python strings and sub-expressions (recursively) to Python lists.
+For more details, read the module file.
+% XXXXJH should be funcdesc, I think
+
+\section{\module{pnl} ---
+         None}
+\declaremodule{builtin}{pnl}
+
+\modulesynopsis{None}
+
+
+This module provides access to the
+\emph{Panel Library}
+built by NASA Ames\index{NASA} (to get it, send email to
+\code{panel-request at nas.nasa.gov}).
+All access to it should be done through the standard module
+\code{panel}\refstmodindex{panel},
+which transparently exports most functions from
+\code{pnl}
+but redefines
+\code{pnl.dopanel()}.
+
+\warning{The Python interpreter will dump core if you don't create a
+GL window before calling \code{pnl.mkpanel()}.}
+
+The module is too large to document here in its entirety.

Added: vendor/Python/current/Doc/lib/libparser.tex
===================================================================
--- vendor/Python/current/Doc/lib/libparser.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libparser.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,711 @@
+\section{\module{parser} ---
+         Access Python parse trees}
+
+% Copyright 1995 Virginia Polytechnic Institute and State University
+% and Fred L. Drake, Jr.  This copyright notice must be distributed on
+% all copies, but this document otherwise may be distributed as part
+% of the Python distribution.  No fee may be charged for this document
+% in any representation, either on paper or electronically.  This
+% restriction does not affect other elements in a distributed package
+% in any way.
+
+\declaremodule{builtin}{parser}
+\modulesynopsis{Access parse trees for Python source code.}
+\moduleauthor{Fred L. Drake, Jr.}{fdrake at acm.org}
+\sectionauthor{Fred L. Drake, Jr.}{fdrake at acm.org}
+
+
+\index{parsing!Python source code}
+
+The \module{parser} module provides an interface to Python's internal
+parser and byte-code compiler.  The primary purpose for this interface
+is to allow Python code to edit the parse tree of a Python expression
+and create executable code from this.  This is better than trying
+to parse and modify an arbitrary Python code fragment as a string
+because parsing is performed in a manner identical to the code
+forming the application.  It is also faster.
+
+There are a few things to note about this module which are important
+to making use of the data structures created.  This is not a tutorial
+on editing the parse trees for Python code, but some examples of using
+the \module{parser} module are presented.
+
+Most importantly, a good understanding of the Python grammar processed
+by the internal parser is required.  For full information on the
+language syntax, refer to the \citetitle[../ref/ref.html]{Python
+Language Reference}.  The parser itself is created from a grammar
+specification defined in the file \file{Grammar/Grammar} in the
+standard Python distribution.  The parse trees stored in the AST
+objects created by this module are the actual output from the internal
+parser when created by the \function{expr()} or \function{suite()}
+functions, described below.  The AST objects created by
+\function{sequence2ast()} faithfully simulate those structures.  Be
+aware that the values of the sequences which are considered
+``correct'' will vary from one version of Python to another as the
+formal grammar for the language is revised.  However, transporting
+code from one Python version to another as source text will always
+allow correct parse trees to be created in the target version, with
+the only restriction being that migrating to an older version of the
+interpreter will not support more recent language constructs.  The
+parse trees are not typically compatible from one version to another,
+whereas source code has always been forward-compatible.
+
+Each element of the sequences returned by \function{ast2list()} or
+\function{ast2tuple()} has a simple form.  Sequences representing
+non-terminal elements in the grammar always have a length greater than
+one.  The first element is an integer which identifies a production in
+the grammar.  These integers are given symbolic names in the C header
+file \file{Include/graminit.h} and the Python module
+\refmodule{symbol}.  Each additional element of the sequence represents
+a component of the production as recognized in the input string: these
+are always sequences which have the same form as the parent.  An
+important aspect of this structure which should be noted is that
+keywords used to identify the parent node type, such as the keyword
+\keyword{if} in an \constant{if_stmt}, are included in the node tree without
+any special treatment.  For example, the \keyword{if} keyword is
+represented by the tuple \code{(1, 'if')}, where \code{1} is the
+numeric value associated with all \constant{NAME} tokens, including
+variable and function names defined by the user.  In an alternate form
+returned when line number information is requested, the same token
+might be represented as \code{(1, 'if', 12)}, where the \code{12}
+represents the line number at which the terminal symbol was found.
+
+Terminal elements are represented in much the same way, but without
+any child elements and the addition of the source text which was
+identified.  The example of the \keyword{if} keyword above is
+representative.  The various types of terminal symbols are defined in
+the C header file \file{Include/token.h} and the Python module
+\refmodule{token}.
+
+The AST objects are not required to support the functionality of this
+module, but are provided for three purposes: to allow an application
+to amortize the cost of processing complex parse trees, to provide a
+parse tree representation which conserves memory space when compared
+to the Python list or tuple representation, and to ease the creation
+of additional modules in C which manipulate parse trees.  A simple
+``wrapper'' class may be created in Python to hide the use of AST
+objects.
+
+The \module{parser} module defines functions for a few distinct
+purposes.  The most important purposes are to create AST objects and
+to convert AST objects to other representations such as parse trees
+and compiled code objects, but there are also functions which serve to
+query the type of parse tree represented by an AST object.
+
+
+\begin{seealso}
+  \seemodule{symbol}{Useful constants representing internal nodes of
+                     the parse tree.}
+  \seemodule{token}{Useful constants representing leaf nodes of the
+                    parse tree and functions for testing node values.}
+\end{seealso}
+
+
+\subsection{Creating AST Objects \label{Creating ASTs}}
+
+AST objects may be created from source code or from a parse tree.
+When creating an AST object from source, different functions are used
+to create the \code{'eval'} and \code{'exec'} forms.
+
+\begin{funcdesc}{expr}{source}
+The \function{expr()} function parses the parameter \var{source}
+as if it were an input to \samp{compile(\var{source}, 'file.py',
+'eval')}.  If the parse succeeds, an AST object is created to hold the
+internal parse tree representation, otherwise an appropriate exception
+is thrown.
+\end{funcdesc}
+
+\begin{funcdesc}{suite}{source}
+The \function{suite()} function parses the parameter \var{source}
+as if it were an input to \samp{compile(\var{source}, 'file.py',
+'exec')}.  If the parse succeeds, an AST object is created to hold the
+internal parse tree representation, otherwise an appropriate exception
+is thrown.
+\end{funcdesc}
+
+\begin{funcdesc}{sequence2ast}{sequence}
+This function accepts a parse tree represented as a sequence and
+builds an internal representation if possible.  If it can validate
+that the tree conforms to the Python grammar and all nodes are valid
+node types in the host version of Python, an AST object is created
+from the internal representation and returned to the called.  If there
+is a problem creating the internal representation, or if the tree
+cannot be validated, a \exception{ParserError} exception is thrown.  An AST
+object created this way should not be assumed to compile correctly;
+normal exceptions thrown by compilation may still be initiated when
+the AST object is passed to \function{compileast()}.  This may indicate
+problems not related to syntax (such as a \exception{MemoryError}
+exception), but may also be due to constructs such as the result of
+parsing \code{del f(0)}, which escapes the Python parser but is
+checked by the bytecode compiler.
+
+Sequences representing terminal tokens may be represented as either
+two-element lists of the form \code{(1, 'name')} or as three-element
+lists of the form \code{(1, 'name', 56)}.  If the third element is
+present, it is assumed to be a valid line number.  The line number
+may be specified for any subset of the terminal symbols in the input
+tree.
+\end{funcdesc}
+
+\begin{funcdesc}{tuple2ast}{sequence}
+This is the same function as \function{sequence2ast()}.  This entry point
+is maintained for backward compatibility.
+\end{funcdesc}
+
+
+\subsection{Converting AST Objects \label{Converting ASTs}}
+
+AST objects, regardless of the input used to create them, may be
+converted to parse trees represented as list- or tuple- trees, or may
+be compiled into executable code objects.  Parse trees may be
+extracted with or without line numbering information.
+
+\begin{funcdesc}{ast2list}{ast\optional{, line_info}}
+This function accepts an AST object from the caller in
+\var{ast} and returns a Python list representing the
+equivalent parse tree.  The resulting list representation can be used
+for inspection or the creation of a new parse tree in list form.  This
+function does not fail so long as memory is available to build the
+list representation.  If the parse tree will only be used for
+inspection, \function{ast2tuple()} should be used instead to reduce memory
+consumption and fragmentation.  When the list representation is
+required, this function is significantly faster than retrieving a
+tuple representation and converting that to nested lists.
+
+If \var{line_info} is true, line number information will be
+included for all terminal tokens as a third element of the list
+representing the token.  Note that the line number provided specifies
+the line on which the token \emph{ends}.  This information is
+omitted if the flag is false or omitted.
+\end{funcdesc}
+
+\begin{funcdesc}{ast2tuple}{ast\optional{, line_info}}
+This function accepts an AST object from the caller in
+\var{ast} and returns a Python tuple representing the
+equivalent parse tree.  Other than returning a tuple instead of a
+list, this function is identical to \function{ast2list()}.
+
+If \var{line_info} is true, line number information will be
+included for all terminal tokens as a third element of the list
+representing the token.  This information is omitted if the flag is
+false or omitted.
+\end{funcdesc}
+
+\begin{funcdesc}{compileast}{ast\optional{, filename\code{ = '<ast>'}}}
+The Python byte compiler can be invoked on an AST object to produce
+code objects which can be used as part of an \keyword{exec} statement or
+a call to the built-in \function{eval()}\bifuncindex{eval} function.
+This function provides the interface to the compiler, passing the
+internal parse tree from \var{ast} to the parser, using the
+source file name specified by the \var{filename} parameter.
+The default value supplied for \var{filename} indicates that
+the source was an AST object.
+
+Compiling an AST object may result in exceptions related to
+compilation; an example would be a \exception{SyntaxError} caused by the
+parse tree for \code{del f(0)}: this statement is considered legal
+within the formal grammar for Python but is not a legal language
+construct.  The \exception{SyntaxError} raised for this condition is
+actually generated by the Python byte-compiler normally, which is why
+it can be raised at this point by the \module{parser} module.  Most
+causes of compilation failure can be diagnosed programmatically by
+inspection of the parse tree.
+\end{funcdesc}
+
+
+\subsection{Queries on AST Objects \label{Querying ASTs}}
+
+Two functions are provided which allow an application to determine if
+an AST was created as an expression or a suite.  Neither of these
+functions can be used to determine if an AST was created from source
+code via \function{expr()} or \function{suite()} or from a parse tree
+via \function{sequence2ast()}.
+
+\begin{funcdesc}{isexpr}{ast}
+When \var{ast} represents an \code{'eval'} form, this function
+returns true, otherwise it returns false.  This is useful, since code
+objects normally cannot be queried for this information using existing
+built-in functions.  Note that the code objects created by
+\function{compileast()} cannot be queried like this either, and are
+identical to those created by the built-in
+\function{compile()}\bifuncindex{compile} function.
+\end{funcdesc}
+
+
+\begin{funcdesc}{issuite}{ast}
+This function mirrors \function{isexpr()} in that it reports whether an
+AST object represents an \code{'exec'} form, commonly known as a
+``suite.''  It is not safe to assume that this function is equivalent
+to \samp{not isexpr(\var{ast})}, as additional syntactic fragments may
+be supported in the future.
+\end{funcdesc}
+
+
+\subsection{Exceptions and Error Handling \label{AST Errors}}
+
+The parser module defines a single exception, but may also pass other
+built-in exceptions from other portions of the Python runtime
+environment.  See each function for information about the exceptions
+it can raise.
+
+\begin{excdesc}{ParserError}
+Exception raised when a failure occurs within the parser module.  This
+is generally produced for validation failures rather than the built in
+\exception{SyntaxError} thrown during normal parsing.
+The exception argument is either a string describing the reason of the
+failure or a tuple containing a sequence causing the failure from a parse
+tree passed to \function{sequence2ast()} and an explanatory string.  Calls to
+\function{sequence2ast()} need to be able to handle either type of exception,
+while calls to other functions in the module will only need to be
+aware of the simple string values.
+\end{excdesc}
+
+Note that the functions \function{compileast()}, \function{expr()}, and
+\function{suite()} may throw exceptions which are normally thrown by the
+parsing and compilation process.  These include the built in
+exceptions \exception{MemoryError}, \exception{OverflowError},
+\exception{SyntaxError}, and \exception{SystemError}.  In these cases, these
+exceptions carry all the meaning normally associated with them.  Refer
+to the descriptions of each function for detailed information.
+
+
+\subsection{AST Objects \label{AST Objects}}
+
+Ordered and equality comparisons are supported between AST objects.
+Pickling of AST objects (using the \refmodule{pickle} module) is also
+supported.
+
+\begin{datadesc}{ASTType}
+The type of the objects returned by \function{expr()},
+\function{suite()} and \function{sequence2ast()}.
+\end{datadesc}
+
+
+AST objects have the following methods:
+
+
+\begin{methoddesc}[AST]{compile}{\optional{filename}}
+Same as \code{compileast(\var{ast}, \var{filename})}.
+\end{methoddesc}
+
+\begin{methoddesc}[AST]{isexpr}{}
+Same as \code{isexpr(\var{ast})}.
+\end{methoddesc}
+
+\begin{methoddesc}[AST]{issuite}{}
+Same as \code{issuite(\var{ast})}.
+\end{methoddesc}
+
+\begin{methoddesc}[AST]{tolist}{\optional{line_info}}
+Same as \code{ast2list(\var{ast}, \var{line_info})}.
+\end{methoddesc}
+
+\begin{methoddesc}[AST]{totuple}{\optional{line_info}}
+Same as \code{ast2tuple(\var{ast}, \var{line_info})}.
+\end{methoddesc}
+
+
+\subsection{Examples \label{AST Examples}}
+
+The parser modules allows operations to be performed on the parse tree
+of Python source code before the bytecode is generated, and provides
+for inspection of the parse tree for information gathering purposes.
+Two examples are presented.  The simple example demonstrates emulation
+of the \function{compile()}\bifuncindex{compile} built-in function and
+the complex example shows the use of a parse tree for information
+discovery.
+
+\subsubsection{Emulation of \function{compile()}}
+
+While many useful operations may take place between parsing and
+bytecode generation, the simplest operation is to do nothing.  For
+this purpose, using the \module{parser} module to produce an
+intermediate data structure is equivalent to the code
+
+\begin{verbatim}
+>>> code = compile('a + 5', 'file.py', 'eval')
+>>> a = 5
+>>> eval(code)
+10
+\end{verbatim}
+
+The equivalent operation using the \module{parser} module is somewhat
+longer, and allows the intermediate internal parse tree to be retained
+as an AST object:
+
+\begin{verbatim}
+>>> import parser
+>>> ast = parser.expr('a + 5')
+>>> code = ast.compile('file.py')
+>>> a = 5
+>>> eval(code)
+10
+\end{verbatim}
+
+An application which needs both AST and code objects can package this
+code into readily available functions:
+
+\begin{verbatim}
+import parser
+
+def load_suite(source_string):
+    ast = parser.suite(source_string)
+    return ast, ast.compile()
+
+def load_expression(source_string):
+    ast = parser.expr(source_string)
+    return ast, ast.compile()
+\end{verbatim}
+
+\subsubsection{Information Discovery}
+
+Some applications benefit from direct access to the parse tree.  The
+remainder of this section demonstrates how the parse tree provides
+access to module documentation defined in
+docstrings\index{string!documentation}\index{docstrings} without
+requiring that the code being examined be loaded into a running
+interpreter via \keyword{import}.  This can be very useful for
+performing analyses of untrusted code.
+
+Generally, the example will demonstrate how the parse tree may be
+traversed to distill interesting information.  Two functions and a set
+of classes are developed which provide programmatic access to high
+level function and class definitions provided by a module.  The
+classes extract information from the parse tree and provide access to
+the information at a useful semantic level, one function provides a
+simple low-level pattern matching capability, and the other function
+defines a high-level interface to the classes by handling file
+operations on behalf of the caller.  All source files mentioned here
+which are not part of the Python installation are located in the
+\file{Demo/parser/} directory of the distribution.
+
+The dynamic nature of Python allows the programmer a great deal of
+flexibility, but most modules need only a limited measure of this when
+defining classes, functions, and methods.  In this example, the only
+definitions that will be considered are those which are defined in the
+top level of their context, e.g., a function defined by a \keyword{def}
+statement at column zero of a module, but not a function defined
+within a branch of an \keyword{if} ... \keyword{else} construct, though
+there are some good reasons for doing so in some situations.  Nesting
+of definitions will be handled by the code developed in the example.
+
+To construct the upper-level extraction methods, we need to know what
+the parse tree structure looks like and how much of it we actually
+need to be concerned about.  Python uses a moderately deep parse tree
+so there are a large number of intermediate nodes.  It is important to
+read and understand the formal grammar used by Python.  This is
+specified in the file \file{Grammar/Grammar} in the distribution.
+Consider the simplest case of interest when searching for docstrings:
+a module consisting of a docstring and nothing else.  (See file
+\file{docstring.py}.)
+
+\begin{verbatim}
+"""Some documentation.
+"""
+\end{verbatim}
+
+Using the interpreter to take a look at the parse tree, we find a
+bewildering mass of numbers and parentheses, with the documentation
+buried deep in nested tuples.
+
+\begin{verbatim}
+>>> import parser
+>>> import pprint
+>>> ast = parser.suite(open('docstring.py').read())
+>>> tup = ast.totuple()
+>>> pprint.pprint(tup)
+(257,
+ (264,
+  (265,
+   (266,
+    (267,
+     (307,
+      (287,
+       (288,
+        (289,
+         (290,
+          (292,
+           (293,
+            (294,
+             (295,
+              (296,
+               (297,
+                (298,
+                 (299,
+                  (300, (3, '"""Some documentation.\n"""'))))))))))))))))),
+   (4, ''))),
+ (4, ''),
+ (0, ''))
+\end{verbatim}
+
+The numbers at the first element of each node in the tree are the node
+types; they map directly to terminal and non-terminal symbols in the
+grammar.  Unfortunately, they are represented as integers in the
+internal representation, and the Python structures generated do not
+change that.  However, the \refmodule{symbol} and \refmodule{token} modules
+provide symbolic names for the node types and dictionaries which map
+from the integers to the symbolic names for the node types.
+
+In the output presented above, the outermost tuple contains four
+elements: the integer \code{257} and three additional tuples.  Node
+type \code{257} has the symbolic name \constant{file_input}.  Each of
+these inner tuples contains an integer as the first element; these
+integers, \code{264}, \code{4}, and \code{0}, represent the node types
+\constant{stmt}, \constant{NEWLINE}, and \constant{ENDMARKER},
+respectively.
+Note that these values may change depending on the version of Python
+you are using; consult \file{symbol.py} and \file{token.py} for
+details of the mapping.  It should be fairly clear that the outermost
+node is related primarily to the input source rather than the contents
+of the file, and may be disregarded for the moment.  The \constant{stmt}
+node is much more interesting.  In particular, all docstrings are
+found in subtrees which are formed exactly as this node is formed,
+with the only difference being the string itself.  The association
+between the docstring in a similar tree and the defined entity (class,
+function, or module) which it describes is given by the position of
+the docstring subtree within the tree defining the described
+structure.
+
+By replacing the actual docstring with something to signify a variable
+component of the tree, we allow a simple pattern matching approach to
+check any given subtree for equivalence to the general pattern for
+docstrings.  Since the example demonstrates information extraction, we
+can safely require that the tree be in tuple form rather than list
+form, allowing a simple variable representation to be
+\code{['variable_name']}.  A simple recursive function can implement
+the pattern matching, returning a Boolean and a dictionary of variable
+name to value mappings.  (See file \file{example.py}.)
+
+\begin{verbatim}
+from types import ListType, TupleType
+
+def match(pattern, data, vars=None):
+    if vars is None:
+        vars = {}
+    if type(pattern) is ListType:
+        vars[pattern[0]] = data
+        return 1, vars
+    if type(pattern) is not TupleType:
+        return (pattern == data), vars
+    if len(data) != len(pattern):
+        return 0, vars
+    for pattern, data in map(None, pattern, data):
+        same, vars = match(pattern, data, vars)
+        if not same:
+            break
+    return same, vars
+\end{verbatim}
+
+Using this simple representation for syntactic variables and the symbolic
+node types, the pattern for the candidate docstring subtrees becomes
+fairly readable.  (See file \file{example.py}.)
+
+\begin{verbatim}
+import symbol
+import token
+
+DOCSTRING_STMT_PATTERN = (
+    symbol.stmt,
+    (symbol.simple_stmt,
+     (symbol.small_stmt,
+      (symbol.expr_stmt,
+       (symbol.testlist,
+        (symbol.test,
+         (symbol.and_test,
+          (symbol.not_test,
+           (symbol.comparison,
+            (symbol.expr,
+             (symbol.xor_expr,
+              (symbol.and_expr,
+               (symbol.shift_expr,
+                (symbol.arith_expr,
+                 (symbol.term,
+                  (symbol.factor,
+                   (symbol.power,
+                    (symbol.atom,
+                     (token.STRING, ['docstring'])
+                     )))))))))))))))),
+     (token.NEWLINE, '')
+     ))
+\end{verbatim}
+
+Using the \function{match()} function with this pattern, extracting the
+module docstring from the parse tree created previously is easy:
+
+\begin{verbatim}
+>>> found, vars = match(DOCSTRING_STMT_PATTERN, tup[1])
+>>> found
+1
+>>> vars
+{'docstring': '"""Some documentation.\n"""'}
+\end{verbatim}
+
+Once specific data can be extracted from a location where it is
+expected, the question of where information can be expected
+needs to be answered.  When dealing with docstrings, the answer is
+fairly simple: the docstring is the first \constant{stmt} node in a code
+block (\constant{file_input} or \constant{suite} node types).  A module
+consists of a single \constant{file_input} node, and class and function
+definitions each contain exactly one \constant{suite} node.  Classes and
+functions are readily identified as subtrees of code block nodes which
+start with \code{(stmt, (compound_stmt, (classdef, ...} or
+\code{(stmt, (compound_stmt, (funcdef, ...}.  Note that these subtrees
+cannot be matched by \function{match()} since it does not support multiple
+sibling nodes to match without regard to number.  A more elaborate
+matching function could be used to overcome this limitation, but this
+is sufficient for the example.
+
+Given the ability to determine whether a statement might be a
+docstring and extract the actual string from the statement, some work
+needs to be performed to walk the parse tree for an entire module and
+extract information about the names defined in each context of the
+module and associate any docstrings with the names.  The code to
+perform this work is not complicated, but bears some explanation.
+
+The public interface to the classes is straightforward and should
+probably be somewhat more flexible.  Each ``major'' block of the
+module is described by an object providing several methods for inquiry
+and a constructor which accepts at least the subtree of the complete
+parse tree which it represents.  The \class{ModuleInfo} constructor
+accepts an optional \var{name} parameter since it cannot
+otherwise determine the name of the module.
+
+The public classes include \class{ClassInfo}, \class{FunctionInfo},
+and \class{ModuleInfo}.  All objects provide the
+methods \method{get_name()}, \method{get_docstring()},
+\method{get_class_names()}, and \method{get_class_info()}.  The
+\class{ClassInfo} objects support \method{get_method_names()} and
+\method{get_method_info()} while the other classes provide
+\method{get_function_names()} and \method{get_function_info()}.
+
+Within each of the forms of code block that the public classes
+represent, most of the required information is in the same form and is
+accessed in the same way, with classes having the distinction that
+functions defined at the top level are referred to as ``methods.''
+Since the difference in nomenclature reflects a real semantic
+distinction from functions defined outside of a class, the
+implementation needs to maintain the distinction.
+Hence, most of the functionality of the public classes can be
+implemented in a common base class, \class{SuiteInfoBase}, with the
+accessors for function and method information provided elsewhere.
+Note that there is only one class which represents function and method
+information; this parallels the use of the \keyword{def} statement to
+define both types of elements.
+
+Most of the accessor functions are declared in \class{SuiteInfoBase}
+and do not need to be overridden by subclasses.  More importantly, the
+extraction of most information from a parse tree is handled through a
+method called by the \class{SuiteInfoBase} constructor.  The example
+code for most of the classes is clear when read alongside the formal
+grammar, but the method which recursively creates new information
+objects requires further examination.  Here is the relevant part of
+the \class{SuiteInfoBase} definition from \file{example.py}:
+
+\begin{verbatim}
+class SuiteInfoBase:
+    _docstring = ''
+    _name = ''
+
+    def __init__(self, tree = None):
+        self._class_info = {}
+        self._function_info = {}
+        if tree:
+            self._extract_info(tree)
+
+    def _extract_info(self, tree):
+        # extract docstring
+        if len(tree) == 2:
+            found, vars = match(DOCSTRING_STMT_PATTERN[1], tree[1])
+        else:
+            found, vars = match(DOCSTRING_STMT_PATTERN, tree[3])
+        if found:
+            self._docstring = eval(vars['docstring'])
+        # discover inner definitions
+        for node in tree[1:]:
+            found, vars = match(COMPOUND_STMT_PATTERN, node)
+            if found:
+                cstmt = vars['compound']
+                if cstmt[0] == symbol.funcdef:
+                    name = cstmt[2][1]
+                    self._function_info[name] = FunctionInfo(cstmt)
+                elif cstmt[0] == symbol.classdef:
+                    name = cstmt[2][1]
+                    self._class_info[name] = ClassInfo(cstmt)
+\end{verbatim}
+
+After initializing some internal state, the constructor calls the
+\method{_extract_info()} method.  This method performs the bulk of the
+information extraction which takes place in the entire example.  The
+extraction has two distinct phases: the location of the docstring for
+the parse tree passed in, and the discovery of additional definitions
+within the code block represented by the parse tree.
+
+The initial \keyword{if} test determines whether the nested suite is of
+the ``short form'' or the ``long form.''  The short form is used when
+the code block is on the same line as the definition of the code
+block, as in
+
+\begin{verbatim}
+def square(x): "Square an argument."; return x ** 2
+\end{verbatim}
+
+while the long form uses an indented block and allows nested
+definitions:
+
+\begin{verbatim}
+def make_power(exp):
+    "Make a function that raises an argument to the exponent `exp'."
+    def raiser(x, y=exp):
+        return x ** y
+    return raiser
+\end{verbatim}
+
+When the short form is used, the code block may contain a docstring as
+the first, and possibly only, \constant{small_stmt} element.  The
+extraction of such a docstring is slightly different and requires only
+a portion of the complete pattern used in the more common case.  As
+implemented, the docstring will only be found if there is only
+one \constant{small_stmt} node in the \constant{simple_stmt} node.
+Since most functions and methods which use the short form do not
+provide a docstring, this may be considered sufficient.  The
+extraction of the docstring proceeds using the \function{match()} function
+as described above, and the value of the docstring is stored as an
+attribute of the \class{SuiteInfoBase} object.
+
+After docstring extraction, a simple definition discovery
+algorithm operates on the \constant{stmt} nodes of the
+\constant{suite} node.  The special case of the short form is not
+tested; since there are no \constant{stmt} nodes in the short form,
+the algorithm will silently skip the single \constant{simple_stmt}
+node and correctly not discover any nested definitions.
+
+Each statement in the code block is categorized as
+a class definition, function or method definition, or
+something else.  For the definition statements, the name of the
+element defined is extracted and a representation object
+appropriate to the definition is created with the defining subtree
+passed as an argument to the constructor.  The representation objects
+are stored in instance variables and may be retrieved by name using
+the appropriate accessor methods.
+
+The public classes provide any accessors required which are more
+specific than those provided by the \class{SuiteInfoBase} class, but
+the real extraction algorithm remains common to all forms of code
+blocks.  A high-level function can be used to extract the complete set
+of information from a source file.  (See file \file{example.py}.)
+
+\begin{verbatim}
+def get_docs(fileName):
+    import os
+    import parser
+
+    source = open(fileName).read()
+    basename = os.path.basename(os.path.splitext(fileName)[0])
+    ast = parser.suite(source)
+    return ModuleInfo(ast.totuple(), basename)
+\end{verbatim}
+
+This provides an easy-to-use interface to the documentation of a
+module.  If information is required which is not extracted by the code
+of this example, the code may be extended at clearly defined points to
+provide additional capabilities.

Added: vendor/Python/current/Doc/lib/libpdb.tex
===================================================================
--- vendor/Python/current/Doc/lib/libpdb.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libpdb.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,456 @@
+\chapter{The Python Debugger \label{debugger}}
+
+\declaremodule{standard}{pdb}
+\modulesynopsis{The Python debugger for interactive interpreters.}
+
+
+The module \module{pdb} defines an interactive source code
+debugger\index{debugging} for Python programs.  It supports setting
+(conditional) breakpoints and single stepping at the source line
+level, inspection of stack frames, source code listing, and evaluation
+of arbitrary Python code in the context of any stack frame.  It also
+supports post-mortem debugging and can be called under program
+control.
+
+The debugger is extensible --- it is actually defined as the class
+\class{Pdb}\withsubitem{(class in pdb)}{\ttindex{Pdb}}.
+This is currently undocumented but easily understood by reading the
+source.  The extension interface uses the modules
+\module{bdb}\refstmodindex{bdb} (undocumented) and
+\refmodule{cmd}\refstmodindex{cmd}.
+
+The debugger's prompt is \samp{(Pdb) }.
+Typical usage to run a program under control of the debugger is:
+
+\begin{verbatim}
+>>> import pdb
+>>> import mymodule
+>>> pdb.run('mymodule.test()')
+> <string>(0)?()
+(Pdb) continue
+> <string>(1)?()
+(Pdb) continue
+NameError: 'spam'
+> <string>(1)?()
+(Pdb) 
+\end{verbatim}
+
+\file{pdb.py} can also be invoked as
+a script to debug other scripts.  For example:
+
+\begin{verbatim}
+python -m pdb myscript.py
+\end{verbatim}
+
+When invoked as a script, pdb will automatically enter post-mortem debugging
+if the program being debugged exits abnormally. After post-mortem debugging
+(or after normal exit of the program), pdb will restart the program.
+Automatic restarting preserves pdb's state (such as breakpoints) and in most
+cases is more useful than quitting the debugger upon program's exit.
+\versionadded[Restarting post-mortem behavior added]{2.4}
+
+Typical usage to inspect a crashed program is:
+
+\begin{verbatim}
+>>> import pdb
+>>> import mymodule
+>>> mymodule.test()
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+  File "./mymodule.py", line 4, in test
+    test2()
+  File "./mymodule.py", line 3, in test2
+    print spam
+NameError: spam
+>>> pdb.pm()
+> ./mymodule.py(3)test2()
+-> print spam
+(Pdb) 
+\end{verbatim}
+
+The module defines the following functions; each enters the debugger
+in a slightly different way:
+
+\begin{funcdesc}{run}{statement\optional{, globals\optional{, locals}}}
+Execute the \var{statement} (given as a string) under debugger
+control.  The debugger prompt appears before any code is executed; you
+can set breakpoints and type \samp{continue}, or you can step through
+the statement using \samp{step} or \samp{next} (all these commands are
+explained below).  The optional \var{globals} and \var{locals}
+arguments specify the environment in which the code is executed; by
+default the dictionary of the module \refmodule[main]{__main__} is
+used.  (See the explanation of the \keyword{exec} statement or the
+\function{eval()} built-in function.)
+\end{funcdesc}
+
+\begin{funcdesc}{runeval}{expression\optional{, globals\optional{, locals}}}
+Evaluate the \var{expression} (given as a string) under debugger
+control.  When \function{runeval()} returns, it returns the value of the
+expression.  Otherwise this function is similar to
+\function{run()}.
+\end{funcdesc}
+
+\begin{funcdesc}{runcall}{function\optional{, argument, ...}}
+Call the \var{function} (a function or method object, not a string)
+with the given arguments.  When \function{runcall()} returns, it returns
+whatever the function call returned.  The debugger prompt appears as
+soon as the function is entered.
+\end{funcdesc}
+
+\begin{funcdesc}{set_trace}{}
+Enter the debugger at the calling stack frame.  This is useful to
+hard-code a breakpoint at a given point in a program, even if the code
+is not otherwise being debugged (e.g. when an assertion fails).
+\end{funcdesc}
+
+\begin{funcdesc}{post_mortem}{traceback}
+Enter post-mortem debugging of the given \var{traceback} object.
+\end{funcdesc}
+
+\begin{funcdesc}{pm}{}
+Enter post-mortem debugging of the traceback found in
+\code{sys.last_traceback}.
+\end{funcdesc}
+
+
+\section{Debugger Commands \label{debugger-commands}}
+
+The debugger recognizes the following commands.  Most commands can be
+abbreviated to one or two letters; e.g. \samp{h(elp)} means that
+either \samp{h} or \samp{help} can be used to enter the help
+command (but not \samp{he} or \samp{hel}, nor \samp{H} or
+\samp{Help} or \samp{HELP}).  Arguments to commands must be
+separated by whitespace (spaces or tabs).  Optional arguments are
+enclosed in square brackets (\samp{[]}) in the command syntax; the
+square brackets must not be typed.  Alternatives in the command syntax
+are separated by a vertical bar (\samp{|}).
+
+Entering a blank line repeats the last command entered.  Exception: if
+the last command was a \samp{list} command, the next 11 lines are
+listed.
+
+Commands that the debugger doesn't recognize are assumed to be Python
+statements and are executed in the context of the program being
+debugged.  Python statements can also be prefixed with an exclamation
+point (\samp{!}).  This is a powerful way to inspect the program
+being debugged; it is even possible to change a variable or call a
+function.  When an
+exception occurs in such a statement, the exception name is printed
+but the debugger's state is not changed.
+
+Multiple commands may be entered on a single line, separated by
+\samp{;;}.  (A single \samp{;} is not used as it is
+the separator for multiple commands in a line that is passed to
+the Python parser.)
+No intelligence is applied to separating the commands;
+the input is split at the first \samp{;;} pair, even if it is in
+the middle of a quoted string.
+
+The debugger supports aliases.  Aliases can have parameters which
+allows one a certain level of adaptability to the context under
+examination.
+
+If a file \file{.pdbrc}
+\indexii{.pdbrc}{file}\indexiii{debugger}{configuration}{file}
+exists in the user's home directory or in the current directory, it is
+read in and executed as if it had been typed at the debugger prompt.
+This is particularly useful for aliases.  If both files exist, the one
+in the home directory is read first and aliases defined there can be
+overridden by the local file.
+
+\begin{description}
+
+\item[h(elp) \optional{\var{command}}]
+
+Without argument, print the list of available commands.  With a
+\var{command} as argument, print help about that command.  \samp{help
+pdb} displays the full documentation file; if the environment variable
+\envvar{PAGER} is defined, the file is piped through that command
+instead.  Since the \var{command} argument must be an identifier,
+\samp{help exec} must be entered to get help on the \samp{!} command.
+
+\item[w(here)]
+
+Print a stack trace, with the most recent frame at the bottom.  An
+arrow indicates the current frame, which determines the context of
+most commands.
+
+\item[d(own)]
+
+Move the current frame one level down in the stack trace
+(to a newer frame).
+
+\item[u(p)]
+
+Move the current frame one level up in the stack trace
+(to an older frame).
+
+\item[b(reak) \optional{\optional{\var{filename}:}\var{lineno}\code{\Large{|}}\var{function}\optional{, \var{condition}}}]
+
+With a \var{lineno} argument, set a break there in the current
+file.  With a \var{function} argument, set a break at the first
+executable statement within that function.
+The line number may be prefixed with a filename and a colon,
+to specify a breakpoint in another file (probably one that
+hasn't been loaded yet).  The file is searched on \code{sys.path}.
+Note that each breakpoint is assigned a number to which all the other
+breakpoint commands refer.
+
+If a second argument is present, it is an expression which must
+evaluate to true before the breakpoint is honored.
+
+Without argument, list all breaks, including for each breakpoint,
+the number of times that breakpoint has been hit, the current
+ignore count, and the associated condition if any.
+
+\item[tbreak \optional{\optional{\var{filename}:}\var{lineno}\code{\Large{|}}\var{function}\optional{, \var{condition}}}]
+
+Temporary breakpoint, which is removed automatically when it is
+first hit.  The arguments are the same as break.
+
+\item[cl(ear) \optional{\var{bpnumber} \optional{\var{bpnumber ...}}}]
+
+With a space separated list of breakpoint numbers, clear those
+breakpoints.  Without argument, clear all breaks (but first
+ask confirmation).
+
+\item[disable \optional{\var{bpnumber} \optional{\var{bpnumber ...}}}]
+
+Disables the breakpoints given as a space separated list of
+breakpoint numbers.  Disabling a breakpoint means it cannot cause
+the program to stop execution, but unlike clearing a breakpoint, it
+remains in the list of breakpoints and can be (re-)enabled.
+
+\item[enable \optional{\var{bpnumber} \optional{\var{bpnumber ...}}}]
+
+Enables the breakpoints specified.
+
+\item[ignore \var{bpnumber} \optional{\var{count}}]
+
+Sets the ignore count for the given breakpoint number.  If
+count is omitted, the ignore count is set to 0.  A breakpoint
+becomes active when the ignore count is zero.  When non-zero,
+the count is decremented each time the breakpoint is reached
+and the breakpoint is not disabled and any associated condition
+evaluates to true.
+
+\item[condition \var{bpnumber} \optional{\var{condition}}]
+
+Condition is an expression which must evaluate to true before
+the breakpoint is honored.  If condition is absent, any existing
+condition is removed; i.e., the breakpoint is made unconditional.
+
+\item[commands \optional{\var{bpnumber}}]
+
+Specify a list of commands for breakpoint number \var{bpnumber}.  The
+commands themselves appear on the following lines.  Type a line
+containing just 'end' to terminate the commands. An example:
+
+\begin{verbatim}
+(Pdb) commands 1
+(com) print some_variable
+(com) end
+(Pdb)
+\end{verbatim}
+
+To remove all commands from a breakpoint, type commands and
+follow it immediately with  end; that is, give no commands.
+
+With no \var{bpnumber} argument, commands refers to the last
+breakpoint set.
+
+You can use breakpoint commands to start your program up again.
+Simply use the continue command, or step, or any other
+command that resumes execution.
+
+Specifying any command resuming execution (currently continue,
+step, next, return, jump, quit and their abbreviations) terminates
+the command list (as if that command was immediately followed by end).
+This is because any time you resume execution
+(even with a simple next or step), you may encounter·
+another breakpoint--which could have its own command list, leading to
+ambiguities about which list to execute.
+
+   If you use the 'silent' command in the command list, the
+usual message about stopping at a breakpoint is not printed.  This may
+be desirable for breakpoints that are to print a specific message and
+then continue.  If none of the other commands print anything, you
+see no sign that the breakpoint was reached.
+
+\versionadded{2.5}
+
+\item[s(tep)]
+
+Execute the current line, stop at the first possible occasion
+(either in a function that is called or on the next line in the
+current function).
+
+\item[n(ext)]
+
+Continue execution until the next line in the current function
+is reached or it returns.  (The difference between \samp{next} and
+\samp{step} is that \samp{step} stops inside a called function, while
+\samp{next} executes called functions at (nearly) full speed, only
+stopping at the next line in the current function.)
+
+\item[r(eturn)]
+
+Continue execution until the current function returns.
+
+\item[c(ont(inue))]
+
+Continue execution, only stop when a breakpoint is encountered.
+
+\item[j(ump) \var{lineno}]
+
+Set the next line that will be executed.  Only available in the
+bottom-most frame.  This lets you jump back and execute code
+again, or jump forward to skip code that you don't want to run.
+
+It should be noted that not all jumps are allowed --- for instance it
+is not possible to jump into the middle of a \keyword{for} loop or out
+of a \keyword{finally} clause.
+
+\item[l(ist) \optional{\var{first}\optional{, \var{last}}}]
+
+List source code for the current file.  Without arguments, list 11
+lines around the current line or continue the previous listing.  With
+one argument, list 11 lines around at that line.  With two arguments,
+list the given range; if the second argument is less than the first,
+it is interpreted as a count.
+
+\item[a(rgs)]
+
+Print the argument list of the current function.
+
+\item[p \var{expression}]
+
+Evaluate the \var{expression} in the current context and print its
+value.  \note{\samp{print} can also be used, but is not a debugger
+command --- this executes the Python \keyword{print} statement.}
+
+\item[pp \var{expression}]
+
+Like the \samp{p} command, except the value of the expression is
+pretty-printed using the \module{pprint} module.
+
+\item[alias \optional{\var{name} \optional{command}}]
+
+Creates an alias called \var{name} that executes \var{command}.  The
+command must \emph{not} be enclosed in quotes.  Replaceable parameters
+can be indicated by \samp{\%1}, \samp{\%2}, and so on, while \samp{\%*} is
+replaced by all the parameters.  If no command is given, the current
+alias for \var{name} is shown. If no arguments are given, all
+aliases are listed.
+
+Aliases may be nested and can contain anything that can be
+legally typed at the pdb prompt.  Note that internal pdb commands
+\emph{can} be overridden by aliases.  Such a command is
+then hidden until the alias is removed.  Aliasing is recursively
+applied to the first word of the command line; all other words
+in the line are left alone.
+
+As an example, here are two useful aliases (especially when placed
+in the \file{.pdbrc} file):
+
+\begin{verbatim}
+#Print instance variables (usage "pi classInst")
+alias pi for k in %1.__dict__.keys(): print "%1.",k,"=",%1.__dict__[k]
+#Print instance variables in self
+alias ps pi self
+\end{verbatim}
+                
+\item[unalias \var{name}]
+
+Deletes the specified alias.
+
+\item[\optional{!}\var{statement}]
+
+Execute the (one-line) \var{statement} in the context of
+the current stack frame.
+The exclamation point can be omitted unless the first word
+of the statement resembles a debugger command.
+To set a global variable, you can prefix the assignment
+command with a \samp{global} command on the same line, e.g.:
+
+\begin{verbatim}
+(Pdb) global list_options; list_options = ['-l']
+(Pdb)
+\end{verbatim}
+
+\item[q(uit)]
+
+Quit from the debugger.
+The program being executed is aborted.
+
+\end{description}
+
+\section{How It Works \label{debugger-hooks}}
+
+Some changes were made to the interpreter:
+
+\begin{itemize}
+\item \code{sys.settrace(\var{func})} sets the global trace function
+\item there can also a local trace function (see later)
+\end{itemize}
+
+Trace functions have three arguments: \var{frame}, \var{event}, and
+\var{arg}. \var{frame} is the current stack frame.  \var{event} is a
+string: \code{'call'}, \code{'line'}, \code{'return'}, \code{'exception'},
+ \code{'c_call'}, \code{'c_return'}, or \code{'c_exception'}. \var{arg}
+ depends on the event type.
+
+The global trace function is invoked (with \var{event} set to
+\code{'call'}) whenever a new local scope is entered; it should return
+a reference to the local trace function to be used that scope, or
+\code{None} if the scope shouldn't be traced.
+
+The local trace function should return a reference to itself (or to
+another function for further tracing in that scope), or \code{None} to
+turn off tracing in that scope.
+
+Instance methods are accepted (and very useful!) as trace functions.
+
+The events have the following meaning:
+
+\begin{description}
+
+\item[\code{'call'}]
+A function is called (or some other code block entered).  The global
+trace function is called; \var{arg} is \code{None};
+the return value specifies the local trace function.
+
+\item[\code{'line'}]
+The interpreter is about to execute a new line of code (sometimes
+multiple line events on one line exist).  The local trace function is
+called; \var{arg} is \code{None}; the return value specifies the new
+local trace function.
+
+\item[\code{'return'}]
+A function (or other code block) is about to return.  The local trace
+function is called; \var{arg} is the value that will be returned.  The
+trace function's return value is ignored.
+
+\item[\code{'exception'}]
+An exception has occurred.  The local trace function is called;
+\var{arg} is a triple \code{(\var{exception}, \var{value},
+\var{traceback})}; the return value specifies the new local trace
+function.
+
+\item[\code{'c_call'}]
+A C function is about to be called.  This may be an extension function
+or a builtin.  \var{arg} is the C function object.
+
+\item[\code{'c_return'}]
+A C function has returned. \var{arg} is \code{None}.
+
+\item[\code{'c_exception'}]
+A C function has thrown an exception.  \var{arg} is \code{None}.
+
+\end{description}
+
+Note that as an exception is propagated down the chain of callers, an
+\code{'exception'} event is generated at each level.
+
+For more information on code and frame objects, refer to the
+\citetitle[../ref/ref.html]{Python Reference Manual}.

Added: vendor/Python/current/Doc/lib/libpickle.tex
===================================================================
--- vendor/Python/current/Doc/lib/libpickle.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libpickle.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,888 @@
+\section{\module{pickle} --- Python object serialization}
+
+\declaremodule{standard}{pickle}
+\modulesynopsis{Convert Python objects to streams of bytes and back.}
+% Substantial improvements by Jim Kerr <jbkerr at sr.hp.com>.
+% Rewritten by Barry Warsaw <barry at zope.com>
+
+\index{persistence}
+\indexii{persistent}{objects}
+\indexii{serializing}{objects}
+\indexii{marshalling}{objects}
+\indexii{flattening}{objects}
+\indexii{pickling}{objects}
+
+The \module{pickle} module implements a fundamental, but powerful
+algorithm for serializing and de-serializing a Python object
+structure.  ``Pickling'' is the process whereby a Python object
+hierarchy is converted into a byte stream, and ``unpickling'' is the
+inverse operation, whereby a byte stream is converted back into an
+object hierarchy.  Pickling (and unpickling) is alternatively known as
+``serialization'', ``marshalling,''\footnote{Don't confuse this with
+the \refmodule{marshal} module} or ``flattening'',
+however, to avoid confusion, the terms used here are ``pickling'' and
+``unpickling''.
+
+This documentation describes both the \module{pickle} module and the 
+\refmodule{cPickle} module.
+
+\subsection{Relationship to other Python modules}
+
+The \module{pickle} module has an optimized cousin called the
+\module{cPickle} module.  As its name implies, \module{cPickle} is
+written in C, so it can be up to 1000 times faster than
+\module{pickle}.  However it does not support subclassing of the
+\function{Pickler()} and \function{Unpickler()} classes, because in
+\module{cPickle} these are functions, not classes.  Most applications
+have no need for this functionality, and can benefit from the improved
+performance of \module{cPickle}.  Other than that, the interfaces of
+the two modules are nearly identical; the common interface is
+described in this manual and differences are pointed out where
+necessary.  In the following discussions, we use the term ``pickle''
+to collectively describe the \module{pickle} and
+\module{cPickle} modules.
+
+The data streams the two modules produce are guaranteed to be
+interchangeable.
+
+Python has a more primitive serialization module called
+\refmodule{marshal}, but in general
+\module{pickle} should always be the preferred way to serialize Python
+objects.  \module{marshal} exists primarily to support Python's
+\file{.pyc} files.
+
+The \module{pickle} module differs from \refmodule{marshal} several
+significant ways:
+
+\begin{itemize}
+
+\item The \module{pickle} module keeps track of the objects it has
+      already serialized, so that later references to the same object
+      won't be serialized again.  \module{marshal} doesn't do this.
+
+      This has implications both for recursive objects and object
+      sharing.  Recursive objects are objects that contain references
+      to themselves.  These are not handled by marshal, and in fact,
+      attempting to marshal recursive objects will crash your Python
+      interpreter.  Object sharing happens when there are multiple
+      references to the same object in different places in the object
+      hierarchy being serialized.  \module{pickle} stores such objects
+      only once, and ensures that all other references point to the
+      master copy.  Shared objects remain shared, which can be very
+      important for mutable objects.
+
+\item \module{marshal} cannot be used to serialize user-defined
+      classes and their instances.  \module{pickle} can save and
+      restore class instances transparently, however the class
+      definition must be importable and live in the same module as
+      when the object was stored.
+
+\item The \module{marshal} serialization format is not guaranteed to
+      be portable across Python versions.  Because its primary job in
+      life is to support \file{.pyc} files, the Python implementers
+      reserve the right to change the serialization format in
+      non-backwards compatible ways should the need arise.  The
+      \module{pickle} serialization format is guaranteed to be
+      backwards compatible across Python releases.
+
+\end{itemize}
+
+\begin{notice}[warning]
+The \module{pickle} module is not intended to be secure against
+erroneous or maliciously constructed data.  Never unpickle data
+received from an untrusted or unauthenticated source.
+\end{notice}
+
+Note that serialization is a more primitive notion than persistence;
+although
+\module{pickle} reads and writes file objects, it does not handle the
+issue of naming persistent objects, nor the (even more complicated)
+issue of concurrent access to persistent objects.  The \module{pickle}
+module can transform a complex object into a byte stream and it can
+transform the byte stream into an object with the same internal
+structure.  Perhaps the most obvious thing to do with these byte
+streams is to write them onto a file, but it is also conceivable to
+send them across a network or store them in a database.  The module
+\refmodule{shelve} provides a simple interface
+to pickle and unpickle objects on DBM-style database files.
+
+\subsection{Data stream format}
+
+The data format used by \module{pickle} is Python-specific.  This has
+the advantage that there are no restrictions imposed by external
+standards such as XDR\index{XDR}\index{External Data Representation}
+(which can't represent pointer sharing); however it means that
+non-Python programs may not be able to reconstruct pickled Python
+objects.
+
+By default, the \module{pickle} data format uses a printable \ASCII{}
+representation.  This is slightly more voluminous than a binary
+representation.  The big advantage of using printable \ASCII{} (and of
+some other characteristics of \module{pickle}'s representation) is that
+for debugging or recovery purposes it is possible for a human to read
+the pickled file with a standard text editor.
+
+There are currently 3 different protocols which can be used for pickling.
+
+\begin{itemize}
+
+\item Protocol version 0 is the original ASCII protocol and is backwards
+compatible with earlier versions of Python.
+
+\item Protocol version 1 is the old binary format which is also compatible
+with earlier versions of Python.
+
+\item Protocol version 2 was introduced in Python 2.3.  It provides
+much more efficient pickling of new-style classes.
+
+\end{itemize}
+
+Refer to PEP 307 for more information.
+
+If a \var{protocol} is not specified, protocol 0 is used.
+If \var{protocol} is specified as a negative value
+or \constant{HIGHEST_PROTOCOL},
+the highest protocol version available will be used.
+
+\versionchanged[Introduced the \var{protocol} parameter]{2.3}
+
+A binary format, which is slightly more efficient, can be chosen by
+specifying a \var{protocol} version >= 1.
+
+\subsection{Usage}
+
+To serialize an object hierarchy, you first create a pickler, then you
+call the pickler's \method{dump()} method.  To de-serialize a data
+stream, you first create an unpickler, then you call the unpickler's
+\method{load()} method.  The \module{pickle} module provides the
+following constant:
+
+\begin{datadesc}{HIGHEST_PROTOCOL}
+The highest protocol version available.  This value can be passed
+as a \var{protocol} value.
+\versionadded{2.3}
+\end{datadesc}
+
+\note{Be sure to always open pickle files created with protocols >= 1 in
+      binary mode. For the old ASCII-based pickle protocol 0 you can use
+      either text mode or binary mode as long as you stay consistent.
+      
+      A pickle file written with protocol 0 in binary mode will contain
+      lone linefeeds as line terminators and therefore will look ``funny''
+      when viewed in Notepad or other editors which do not support this
+      format.}
+
+The \module{pickle} module provides the
+following functions to make the pickling process more convenient:
+
+\begin{funcdesc}{dump}{obj, file\optional{, protocol}}
+Write a pickled representation of \var{obj} to the open file object
+\var{file}.  This is equivalent to
+\code{Pickler(\var{file}, \var{protocol}).dump(\var{obj})}.
+
+If the \var{protocol} parameter is omitted, protocol 0 is used.
+If \var{protocol} is specified as a negative value
+or \constant{HIGHEST_PROTOCOL},
+the highest protocol version will be used.
+
+\versionchanged[Introduced the \var{protocol} parameter]{2.3}
+
+\var{file} must have a \method{write()} method that accepts a single
+string argument.  It can thus be a file object opened for writing, a
+\refmodule{StringIO} object, or any other custom
+object that meets this interface.
+\end{funcdesc}
+
+\begin{funcdesc}{load}{file}
+Read a string from the open file object \var{file} and interpret it as
+a pickle data stream, reconstructing and returning the original object
+hierarchy.  This is equivalent to \code{Unpickler(\var{file}).load()}.
+
+\var{file} must have two methods, a \method{read()} method that takes
+an integer argument, and a \method{readline()} method that requires no
+arguments.  Both methods should return a string.  Thus \var{file} can
+be a file object opened for reading, a
+\module{StringIO} object, or any other custom
+object that meets this interface.
+
+This function automatically determines whether the data stream was
+written in binary mode or not.
+\end{funcdesc}
+
+\begin{funcdesc}{dumps}{obj\optional{, protocol}}
+Return the pickled representation of the object as a string, instead
+of writing it to a file.
+
+If the \var{protocol} parameter is omitted, protocol 0 is used.
+If \var{protocol} is specified as a negative value
+or \constant{HIGHEST_PROTOCOL},
+the highest protocol version will be used.
+
+\versionchanged[The \var{protocol} parameter was added]{2.3}
+
+\end{funcdesc}
+
+\begin{funcdesc}{loads}{string}
+Read a pickled object hierarchy from a string.  Characters in the
+string past the pickled object's representation are ignored.
+\end{funcdesc}
+
+The \module{pickle} module also defines three exceptions:
+
+\begin{excdesc}{PickleError}
+A common base class for the other exceptions defined below.  This
+inherits from \exception{Exception}.
+\end{excdesc}
+
+\begin{excdesc}{PicklingError}
+This exception is raised when an unpicklable object is passed to
+the \method{dump()} method.
+\end{excdesc}
+
+\begin{excdesc}{UnpicklingError}
+This exception is raised when there is a problem unpickling an object.
+Note that other exceptions may also be raised during unpickling,
+including (but not necessarily limited to) \exception{AttributeError},
+\exception{EOFError}, \exception{ImportError}, and \exception{IndexError}.
+\end{excdesc}
+
+The \module{pickle} module also exports two callables\footnote{In the
+\module{pickle} module these callables are classes, which you could
+subclass to customize the behavior.  However, in the \refmodule{cPickle}
+module these callables are factory functions and so cannot be
+subclassed.  One common reason to subclass is to control what
+objects can actually be unpickled.  See section~\ref{pickle-sub} for
+more details.}, \class{Pickler} and \class{Unpickler}:
+
+\begin{classdesc}{Pickler}{file\optional{, protocol}}
+This takes a file-like object to which it will write a pickle data
+stream.  
+
+If the \var{protocol} parameter is omitted, protocol 0 is used.
+If \var{protocol} is specified as a negative value,
+the highest protocol version will be used.
+
+\versionchanged[Introduced the \var{protocol} parameter]{2.3}
+
+\var{file} must have a \method{write()} method that accepts a single
+string argument.  It can thus be an open file object, a
+\module{StringIO} object, or any other custom
+object that meets this interface.
+\end{classdesc}
+
+\class{Pickler} objects define one (or two) public methods:
+
+\begin{methoddesc}[Pickler]{dump}{obj}
+Write a pickled representation of \var{obj} to the open file object
+given in the constructor.  Either the binary or \ASCII{} format will
+be used, depending on the value of the \var{protocol} argument passed to the
+constructor.
+\end{methoddesc}
+
+\begin{methoddesc}[Pickler]{clear_memo}{}
+Clears the pickler's ``memo''.  The memo is the data structure that
+remembers which objects the pickler has already seen, so that shared
+or recursive objects pickled by reference and not by value.  This
+method is useful when re-using picklers.
+
+\begin{notice}
+Prior to Python 2.3, \method{clear_memo()} was only available on the
+picklers created by \refmodule{cPickle}.  In the \module{pickle} module,
+picklers have an instance variable called \member{memo} which is a
+Python dictionary.  So to clear the memo for a \module{pickle} module
+pickler, you could do the following:
+
+\begin{verbatim}
+mypickler.memo.clear()
+\end{verbatim}
+
+Code that does not need to support older versions of Python should
+simply use \method{clear_memo()}.
+\end{notice}
+\end{methoddesc}
+
+It is possible to make multiple calls to the \method{dump()} method of
+the same \class{Pickler} instance.  These must then be matched to the
+same number of calls to the \method{load()} method of the
+corresponding \class{Unpickler} instance.  If the same object is
+pickled by multiple \method{dump()} calls, the \method{load()} will
+all yield references to the same object.\footnote{\emph{Warning}: this
+is intended for pickling multiple objects without intervening
+modifications to the objects or their parts.  If you modify an object
+and then pickle it again using the same \class{Pickler} instance, the
+object is not pickled again --- a reference to it is pickled and the
+\class{Unpickler} will return the old value, not the modified one.
+There are two problems here: (1) detecting changes, and (2)
+marshalling a minimal set of changes.  Garbage Collection may also
+become a problem here.}
+
+\class{Unpickler} objects are defined as:
+
+\begin{classdesc}{Unpickler}{file}
+This takes a file-like object from which it will read a pickle data
+stream.  This class automatically determines whether the data stream
+was written in binary mode or not, so it does not need a flag as in
+the \class{Pickler} factory.
+
+\var{file} must have two methods, a \method{read()} method that takes
+an integer argument, and a \method{readline()} method that requires no
+arguments.  Both methods should return a string.  Thus \var{file} can
+be a file object opened for reading, a
+\module{StringIO} object, or any other custom
+object that meets this interface.
+\end{classdesc}
+
+\class{Unpickler} objects have one (or two) public methods:
+
+\begin{methoddesc}[Unpickler]{load}{}
+Read a pickled object representation from the open file object given
+in the constructor, and return the reconstituted object hierarchy
+specified therein.
+\end{methoddesc}
+
+\begin{methoddesc}[Unpickler]{noload}{}
+This is just like \method{load()} except that it doesn't actually
+create any objects.  This is useful primarily for finding what's
+called ``persistent ids'' that may be referenced in a pickle data
+stream.  See section~\ref{pickle-protocol} below for more details.
+
+\strong{Note:} the \method{noload()} method is currently only
+available on \class{Unpickler} objects created with the
+\module{cPickle} module.  \module{pickle} module \class{Unpickler}s do
+not have the \method{noload()} method.
+\end{methoddesc}
+
+\subsection{What can be pickled and unpickled?}
+
+The following types can be pickled:
+
+\begin{itemize}
+
+\item \code{None}, \code{True}, and \code{False}
+
+\item integers, long integers, floating point numbers, complex numbers
+
+\item normal and Unicode strings
+
+\item tuples, lists, sets, and dictionaries containing only picklable objects
+
+\item functions defined at the top level of a module
+
+\item built-in functions defined at the top level of a module
+
+\item classes that are defined at the top level of a module
+
+\item instances of such classes whose \member{__dict__} or
+\method{__setstate__()} is picklable  (see
+section~\ref{pickle-protocol} for details)
+
+\end{itemize}
+
+Attempts to pickle unpicklable objects will raise the
+\exception{PicklingError} exception; when this happens, an unspecified
+number of bytes may have already been written to the underlying file.
+Trying to pickle a highly recursive data structure may exceed the
+maximum recursion depth, a \exception{RuntimeError} will be raised
+in this case. You can carefully raise this limit with 
+\function{sys.setrecursionlimit()}.
+
+Note that functions (built-in and user-defined) are pickled by ``fully
+qualified'' name reference, not by value.  This means that only the
+function name is pickled, along with the name of module the function
+is defined in.  Neither the function's code, nor any of its function
+attributes are pickled.  Thus the defining module must be importable
+in the unpickling environment, and the module must contain the named
+object, otherwise an exception will be raised.\footnote{The exception
+raised will likely be an \exception{ImportError} or an
+\exception{AttributeError} but it could be something else.}
+
+Similarly, classes are pickled by named reference, so the same
+restrictions in the unpickling environment apply.  Note that none of
+the class's code or data is pickled, so in the following example the
+class attribute \code{attr} is not restored in the unpickling
+environment:
+
+\begin{verbatim}
+class Foo:
+    attr = 'a class attr'
+
+picklestring = pickle.dumps(Foo)
+\end{verbatim}
+
+These restrictions are why picklable functions and classes must be
+defined in the top level of a module.
+
+Similarly, when class instances are pickled, their class's code and
+data are not pickled along with them.  Only the instance data are
+pickled.  This is done on purpose, so you can fix bugs in a class or
+add methods to the class and still load objects that were created with
+an earlier version of the class.  If you plan to have long-lived
+objects that will see many versions of a class, it may be worthwhile
+to put a version number in the objects so that suitable conversions
+can be made by the class's \method{__setstate__()} method.
+
+\subsection{The pickle protocol
+\label{pickle-protocol}}\setindexsubitem{(pickle protocol)}
+
+This section describes the ``pickling protocol'' that defines the
+interface between the pickler/unpickler and the objects that are being
+serialized.  This protocol provides a standard way for you to define,
+customize, and control how your objects are serialized and
+de-serialized.  The description in this section doesn't cover specific
+customizations that you can employ to make the unpickling environment
+slightly safer from untrusted pickle data streams; see section~\ref{pickle-sub}
+for more details.
+
+\subsubsection{Pickling and unpickling normal class
+    instances\label{pickle-inst}}
+
+When a pickled class instance is unpickled, its \method{__init__()}
+method is normally \emph{not} invoked.  If it is desirable that the
+\method{__init__()} method be called on unpickling, an old-style class
+can define a method \method{__getinitargs__()}, which should return a
+\emph{tuple} containing the arguments to be passed to the class
+constructor (\method{__init__()} for example).  The
+\method{__getinitargs__()} method is called at
+pickle time; the tuple it returns is incorporated in the pickle for
+the instance.
+\withsubitem{(copy protocol)}{\ttindex{__getinitargs__()}}
+\withsubitem{(instance constructor)}{\ttindex{__init__()}}
+
+\withsubitem{(copy protocol)}{\ttindex{__getnewargs__()}}
+
+New-style types can provide a \method{__getnewargs__()} method that is
+used for protocol 2.  Implementing this method is needed if the type
+establishes some internal invariants when the instance is created, or
+if the memory allocation is affected by the values passed to the
+\method{__new__()} method for the type (as it is for tuples and
+strings).  Instances of a new-style type \class{C} are created using
+
+\begin{alltt}
+obj = C.__new__(C, *\var{args})
+\end{alltt}
+
+where \var{args} is the result of calling \method{__getnewargs__()} on
+the original object; if there is no \method{__getnewargs__()}, an
+empty tuple is assumed.
+
+\withsubitem{(copy protocol)}{
+  \ttindex{__getstate__()}\ttindex{__setstate__()}}
+\withsubitem{(instance attribute)}{
+  \ttindex{__dict__}}
+
+Classes can further influence how their instances are pickled; if the
+class defines the method \method{__getstate__()}, it is called and the
+return state is pickled as the contents for the instance, instead of
+the contents of the instance's dictionary.  If there is no
+\method{__getstate__()} method, the instance's \member{__dict__} is
+pickled.
+
+Upon unpickling, if the class also defines the method
+\method{__setstate__()}, it is called with the unpickled
+state.\footnote{These methods can also be used to implement copying
+class instances.}  If there is no \method{__setstate__()} method, the
+pickled state must be a dictionary and its items are assigned to the
+new instance's dictionary.  If a class defines both
+\method{__getstate__()} and \method{__setstate__()}, the state object
+needn't be a dictionary and these methods can do what they
+want.\footnote{This protocol is also used by the shallow and deep
+copying operations defined in the
+\refmodule{copy} module.}
+
+\begin{notice}[warning]
+  For new-style classes, if \method{__getstate__()} returns a false
+  value, the \method{__setstate__()} method will not be called.
+\end{notice}
+
+
+\subsubsection{Pickling and unpickling extension types}
+
+When the \class{Pickler} encounters an object of a type it knows
+nothing about --- such as an extension type --- it looks in two places
+for a hint of how to pickle it.  One alternative is for the object to
+implement a \method{__reduce__()} method.  If provided, at pickling
+time \method{__reduce__()} will be called with no arguments, and it
+must return either a string or a tuple.
+
+If a string is returned, it names a global variable whose contents are
+pickled as normal.  The string returned by \method{__reduce__} should
+be the object's local name relative to its module; the pickle module
+searches the module namespace to determine the object's module.
+
+When a tuple is returned, it must be between two and five elements
+long. Optional elements can either be omitted, or \code{None} can be provided 
+as their value.  The semantics of each element are:
+
+\begin{itemize}
+
+\item A callable object that will be called to create the initial
+version of the object.  The next element of the tuple will provide
+arguments for this callable, and later elements provide additional
+state information that will subsequently be used to fully reconstruct
+the pickled data.
+
+In the unpickling environment this object must be either a class, a
+callable registered as a ``safe constructor'' (see below), or it must
+have an attribute \member{__safe_for_unpickling__} with a true value.
+Otherwise, an \exception{UnpicklingError} will be raised in the
+unpickling environment.  Note that as usual, the callable itself is
+pickled by name.
+
+\item A tuple of arguments for the callable object.
+\versionchanged[Formerly, this argument could also be \code{None}]{2.5}
+
+\item Optionally, the object's state, which will be passed to
+      the object's \method{__setstate__()} method as described in
+      section~\ref{pickle-inst}.  If the object has no
+      \method{__setstate__()} method, then, as above, the value must
+      be a dictionary and it will be added to the object's
+      \member{__dict__}.
+
+\item Optionally, an iterator (and not a sequence) yielding successive
+list items.  These list items will be pickled, and appended to the
+object using either \code{obj.append(\var{item})} or
+\code{obj.extend(\var{list_of_items})}.  This is primarily used for
+list subclasses, but may be used by other classes as long as they have
+\method{append()} and \method{extend()} methods with the appropriate
+signature.  (Whether \method{append()} or \method{extend()} is used
+depends on which pickle protocol version is used as well as the number
+of items to append, so both must be supported.)
+
+\item Optionally, an iterator (not a sequence)
+yielding successive dictionary items, which should be tuples of the
+form \code{(\var{key}, \var{value})}.  These items will be pickled
+and stored to the object using \code{obj[\var{key}] = \var{value}}.
+This is primarily used for dictionary subclasses, but may be used by
+other classes as long as they implement \method{__setitem__}.
+
+\end{itemize}
+
+It is sometimes useful to know the protocol version when implementing
+\method{__reduce__}.  This can be done by implementing a method named
+\method{__reduce_ex__} instead of \method{__reduce__}.
+\method{__reduce_ex__}, when it exists, is called in preference over
+\method{__reduce__} (you may still provide \method{__reduce__} for
+backwards compatibility).  The \method{__reduce_ex__} method will be
+called with a single integer argument, the protocol version.
+
+The \class{object} class implements both \method{__reduce__} and
+\method{__reduce_ex__}; however, if a subclass overrides
+\method{__reduce__} but not \method{__reduce_ex__}, the
+\method{__reduce_ex__} implementation detects this and calls
+\method{__reduce__}.
+
+An alternative to implementing a \method{__reduce__()} method on the
+object to be pickled, is to register the callable with the
+\refmodule[copyreg]{copy_reg} module.  This module provides a way
+for programs to register ``reduction functions'' and constructors for
+user-defined types.   Reduction functions have the same semantics and
+interface as the \method{__reduce__()} method described above, except
+that they are called with a single argument, the object to be pickled.
+
+The registered constructor is deemed a ``safe constructor'' for purposes
+of unpickling as described above.
+
+
+\subsubsection{Pickling and unpickling external objects}
+
+For the benefit of object persistence, the \module{pickle} module
+supports the notion of a reference to an object outside the pickled
+data stream.  Such objects are referenced by a ``persistent id'',
+which is just an arbitrary string of printable \ASCII{} characters.
+The resolution of such names is not defined by the \module{pickle}
+module; it will delegate this resolution to user defined functions on
+the pickler and unpickler.\footnote{The actual mechanism for
+associating these user defined functions is slightly different for
+\module{pickle} and \module{cPickle}.  The description given here
+works the same for both implementations.  Users of the \module{pickle}
+module could also use subclassing to effect the same results,
+overriding the \method{persistent_id()} and \method{persistent_load()}
+methods in the derived classes.}
+
+To define external persistent id resolution, you need to set the
+\member{persistent_id} attribute of the pickler object and the
+\member{persistent_load} attribute of the unpickler object.
+
+To pickle objects that have an external persistent id, the pickler
+must have a custom \function{persistent_id()} method that takes an
+object as an argument and returns either \code{None} or the persistent
+id for that object.  When \code{None} is returned, the pickler simply
+pickles the object as normal.  When a persistent id string is
+returned, the pickler will pickle that string, along with a marker
+so that the unpickler will recognize the string as a persistent id.
+
+To unpickle external objects, the unpickler must have a custom
+\function{persistent_load()} function that takes a persistent id
+string and returns the referenced object.
+
+Here's a silly example that \emph{might} shed more light:
+
+\begin{verbatim}
+import pickle
+from cStringIO import StringIO
+
+src = StringIO()
+p = pickle.Pickler(src)
+
+def persistent_id(obj):
+    if hasattr(obj, 'x'):
+        return 'the value %d' % obj.x
+    else:
+        return None
+
+p.persistent_id = persistent_id
+
+class Integer:
+    def __init__(self, x):
+        self.x = x
+    def __str__(self):
+        return 'My name is integer %d' % self.x
+
+i = Integer(7)
+print i
+p.dump(i)
+
+datastream = src.getvalue()
+print repr(datastream)
+dst = StringIO(datastream)
+
+up = pickle.Unpickler(dst)
+
+class FancyInteger(Integer):
+    def __str__(self):
+        return 'I am the integer %d' % self.x
+
+def persistent_load(persid):
+    if persid.startswith('the value '):
+        value = int(persid.split()[2])
+        return FancyInteger(value)
+    else:
+        raise pickle.UnpicklingError, 'Invalid persistent id'
+
+up.persistent_load = persistent_load
+
+j = up.load()
+print j
+\end{verbatim}
+
+In the \module{cPickle} module, the unpickler's
+\member{persistent_load} attribute can also be set to a Python
+list, in which case, when the unpickler reaches a persistent id, the
+persistent id string will simply be appended to this list.  This
+functionality exists so that a pickle data stream can be ``sniffed''
+for object references without actually instantiating all the objects
+in a pickle.\footnote{We'll leave you with the image of Guido and Jim
+sitting around sniffing pickles in their living rooms.}  Setting
+\member{persistent_load} to a list is usually used in conjunction with
+the \method{noload()} method on the Unpickler.
+
+% BAW: Both pickle and cPickle support something called
+% inst_persistent_id() which appears to give unknown types a second
+% shot at producing a persistent id.  Since Jim Fulton can't remember
+% why it was added or what it's for, I'm leaving it undocumented.
+
+\subsection{Subclassing Unpicklers \label{pickle-sub}}
+
+By default, unpickling will import any class that it finds in the
+pickle data.  You can control exactly what gets unpickled and what
+gets called by customizing your unpickler.  Unfortunately, exactly how
+you do this is different depending on whether you're using
+\module{pickle} or \module{cPickle}.\footnote{A word of caution: the
+mechanisms described here use internal attributes and methods, which
+are subject to change in future versions of Python.  We intend to
+someday provide a common interface for controlling this behavior,
+which will work in either \module{pickle} or \module{cPickle}.}
+
+In the \module{pickle} module, you need to derive a subclass from
+\class{Unpickler}, overriding the \method{load_global()}
+method.  \method{load_global()} should read two lines from the pickle
+data stream where the first line will the name of the module
+containing the class and the second line will be the name of the
+instance's class.  It then looks up the class, possibly importing the
+module and digging out the attribute, then it appends what it finds to
+the unpickler's stack.  Later on, this class will be assigned to the
+\member{__class__} attribute of an empty class, as a way of magically
+creating an instance without calling its class's \method{__init__()}.
+Your job (should you choose to accept it), would be to have
+\method{load_global()} push onto the unpickler's stack, a known safe
+version of any class you deem safe to unpickle.  It is up to you to
+produce such a class.  Or you could raise an error if you want to
+disallow all unpickling of instances.  If this sounds like a hack,
+you're right.  Refer to the source code to make this work.
+
+Things are a little cleaner with \module{cPickle}, but not by much.
+To control what gets unpickled, you can set the unpickler's
+\member{find_global} attribute to a function or \code{None}.  If it is
+\code{None} then any attempts to unpickle instances will raise an
+\exception{UnpicklingError}.  If it is a function,
+then it should accept a module name and a class name, and return the
+corresponding class object.  It is responsible for looking up the
+class and performing any necessary imports, and it may raise an
+error to prevent instances of the class from being unpickled.
+
+The moral of the story is that you should be really careful about the
+source of the strings your application unpickles.
+
+\subsection{Example \label{pickle-example}}
+
+For the simplest code, use the \function{dump()} and \function{load()}
+functions.  Note that a self-referencing list is pickled and restored
+correctly.
+
+\begin{verbatim}
+import pickle
+
+data1 = {'a': [1, 2.0, 3, 4+6j],
+         'b': ('string', u'Unicode string'),
+         'c': None}
+
+selfref_list = [1, 2, 3]
+selfref_list.append(selfref_list)
+
+output = open('data.pkl', 'wb')
+
+# Pickle dictionary using protocol 0.
+pickle.dump(data1, output)
+
+# Pickle the list using the highest protocol available.
+pickle.dump(selfref_list, output, -1)
+
+output.close()
+\end{verbatim}
+
+The following example reads the resulting pickled data.  When reading
+a pickle-containing file, you should open the file in binary mode
+because you can't be sure if the ASCII or binary format was used.
+
+\begin{verbatim}
+import pprint, pickle
+
+pkl_file = open('data.pkl', 'rb')
+
+data1 = pickle.load(pkl_file)
+pprint.pprint(data1)
+
+data2 = pickle.load(pkl_file)
+pprint.pprint(data2)
+
+pkl_file.close()
+\end{verbatim}
+
+Here's a larger example that shows how to modify pickling behavior for a
+class.  The \class{TextReader} class opens a text file, and returns
+the line number and line contents each time its \method{readline()}
+method is called. If a \class{TextReader} instance is pickled, all
+attributes \emph{except} the file object member are saved. When the
+instance is unpickled, the file is reopened, and reading resumes from
+the last location. The \method{__setstate__()} and
+\method{__getstate__()} methods are used to implement this behavior.
+
+\begin{verbatim}
+class TextReader:
+    """Print and number lines in a text file."""
+    def __init__(self, file):
+        self.file = file
+        self.fh = open(file)
+        self.lineno = 0
+
+    def readline(self):
+        self.lineno = self.lineno + 1
+        line = self.fh.readline()
+        if not line:
+            return None
+        if line.endswith("\n"):
+            line = line[:-1]
+        return "%d: %s" % (self.lineno, line)
+
+    def __getstate__(self):
+        odict = self.__dict__.copy() # copy the dict since we change it
+        del odict['fh']              # remove filehandle entry
+        return odict
+
+    def __setstate__(self,dict):
+        fh = open(dict['file'])      # reopen file
+        count = dict['lineno']       # read from file...
+        while count:                 # until line count is restored
+            fh.readline()
+            count = count - 1
+        self.__dict__.update(dict)   # update attributes
+        self.fh = fh                 # save the file object
+\end{verbatim}
+
+A sample usage might be something like this:
+
+\begin{verbatim}
+>>> import TextReader
+>>> obj = TextReader.TextReader("TextReader.py")
+>>> obj.readline()
+'1: #!/usr/local/bin/python'
+>>> # (more invocations of obj.readline() here)
+... obj.readline()
+'7: class TextReader:'
+>>> import pickle
+>>> pickle.dump(obj,open('save.p','w'))
+\end{verbatim}
+
+If you want to see that \refmodule{pickle} works across Python
+processes, start another Python session, before continuing.  What
+follows can happen from either the same process or a new process.
+
+\begin{verbatim}
+>>> import pickle
+>>> reader = pickle.load(open('save.p'))
+>>> reader.readline()
+'8:     "Print and number lines in a text file."'
+\end{verbatim}
+
+
+\begin{seealso}
+  \seemodule[copyreg]{copy_reg}{Pickle interface constructor
+                                registration for extension types.}
+
+  \seemodule{shelve}{Indexed databases of objects; uses \module{pickle}.}
+
+  \seemodule{copy}{Shallow and deep object copying.}
+
+  \seemodule{marshal}{High-performance serialization of built-in types.}
+\end{seealso}
+
+
+\section{\module{cPickle} --- A faster \module{pickle}}
+
+\declaremodule{builtin}{cPickle}
+\modulesynopsis{Faster version of \refmodule{pickle}, but not subclassable.}
+\moduleauthor{Jim Fulton}{jim at zope.com}
+\sectionauthor{Fred L. Drake, Jr.}{fdrake at acm.org}
+
+The \module{cPickle} module supports serialization and
+de-serialization of Python objects, providing an interface and
+functionality nearly identical to the
+\refmodule{pickle}\refstmodindex{pickle} module.  There are several
+differences, the most important being performance and subclassability.
+
+First, \module{cPickle} can be up to 1000 times faster than
+\module{pickle} because the former is implemented in C.  Second, in
+the \module{cPickle} module the callables \function{Pickler()} and
+\function{Unpickler()} are functions, not classes.  This means that
+you cannot use them to derive custom pickling and unpickling
+subclasses.  Most applications have no need for this functionality and
+should benefit from the greatly improved performance of the
+\module{cPickle} module.
+
+The pickle data stream produced by \module{pickle} and
+\module{cPickle} are identical, so it is possible to use
+\module{pickle} and \module{cPickle} interchangeably with existing
+pickles.\footnote{Since the pickle data format is actually a tiny
+stack-oriented programming language, and some freedom is taken in the
+encodings of certain objects, it is possible that the two modules
+produce different data streams for the same input objects.  However it
+is guaranteed that they will always be able to read each other's
+data streams.}
+
+There are additional minor differences in API between \module{cPickle}
+and \module{pickle}, however for most applications, they are
+interchangeable.  More documentation is provided in the
+\module{pickle} module documentation, which
+includes a list of the documented differences.
+
+

Added: vendor/Python/current/Doc/lib/libpickletools.tex
===================================================================
--- vendor/Python/current/Doc/lib/libpickletools.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libpickletools.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,34 @@
+\section{\module{pickletools} --- Tools for pickle developers.}
+
+\declaremodule{standard}{pickletools}
+\modulesynopsis{Contains extensive comments about the pickle protocols and pickle-machine opcodes, as well as some useful functions.}
+
+\versionadded{2.3}
+
+This module contains various constants relating to the intimate
+details of the \refmodule{pickle} module, some lengthy comments about
+the implementation, and a few useful functions for analyzing pickled
+data.  The contents of this module are useful for Python core
+developers who are working on the \module{pickle} and \module{cPickle}
+implementations; ordinary users of the \module{pickle} module probably
+won't find the \module{pickletools} module relevant.
+
+\begin{funcdesc}{dis}{pickle\optional{, out=None, memo=None, indentlevel=4}}
+Outputs a symbolic disassembly of the pickle to the file-like object
+\var{out}, defaulting to \code{sys.stdout}.  \var{pickle} can be a
+string or a file-like object.  \var{memo} can be a Python dictionary
+that will be used as the pickle's memo; it can be used to perform
+disassemblies across multiple pickles created by the same pickler.
+Successive levels, indicated by \code{MARK} opcodes in the stream, are
+indented by \var{indentlevel} spaces.
+\end{funcdesc}
+
+\begin{funcdesc}{genops}{pickle}
+Provides an iterator over all of the opcodes in a pickle, returning a
+sequence of \code{(\var{opcode}, \var{arg}, \var{pos})} triples.
+\var{opcode} is an instance of an \class{OpcodeInfo} class; \var{arg} 
+is the decoded value, as a Python object, of the opcode's argument; 
+\var{pos} is the position at which this opcode is located.
+\var{pickle} can be a string or a file-like object.
+\end{funcdesc}
+

Added: vendor/Python/current/Doc/lib/libpipes.tex
===================================================================
--- vendor/Python/current/Doc/lib/libpipes.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libpipes.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,84 @@
+\section{\module{pipes} ---
+         Interface to shell pipelines}
+
+\declaremodule{standard}{pipes}
+  \platform{Unix}
+\sectionauthor{Moshe Zadka}{moshez at zadka.site.co.il}
+\modulesynopsis{A Python interface to \UNIX\ shell pipelines.}
+
+
+The \module{pipes} module defines a class to abstract the concept of
+a \emph{pipeline} --- a sequence of converters from one file to 
+another.
+
+Because the module uses \program{/bin/sh} command lines, a \POSIX{} or
+compatible shell for \function{os.system()} and \function{os.popen()}
+is required.
+
+The \module{pipes} module defines the following class:
+
+\begin{classdesc}{Template}{}
+An abstraction of a pipeline.
+\end{classdesc}
+
+Example:
+
+\begin{verbatim}
+>>> import pipes
+>>> t=pipes.Template()
+>>> t.append('tr a-z A-Z', '--')
+>>> f=t.open('/tmp/1', 'w')
+>>> f.write('hello world')
+>>> f.close()
+>>> open('/tmp/1').read()
+'HELLO WORLD'
+\end{verbatim}
+
+
+\subsection{Template Objects \label{template-objects}}
+
+Template objects following methods:
+
+\begin{methoddesc}{reset}{}
+Restore a pipeline template to its initial state.
+\end{methoddesc}
+
+\begin{methoddesc}{clone}{}
+Return a new, equivalent, pipeline template.
+\end{methoddesc}
+
+\begin{methoddesc}{debug}{flag}
+If \var{flag} is true, turn debugging on. Otherwise, turn debugging
+off. When debugging is on, commands to be executed are printed, and
+the shell is given \code{set -x} command to be more verbose.
+\end{methoddesc}
+
+\begin{methoddesc}{append}{cmd, kind}
+Append a new action at the end. The \var{cmd} variable must be a valid
+bourne shell command. The \var{kind} variable consists of two letters.
+
+The first letter can be either of \code{'-'} (which means the command
+reads its standard input), \code{'f'} (which means the commands reads
+a given file on the command line) or \code{'.'} (which means the commands
+reads no input, and hence must be first.)
+
+Similarly, the second letter can be either of \code{'-'} (which means 
+the command writes to standard output), \code{'f'} (which means the 
+command writes a file on the command line) or \code{'.'} (which means
+the command does not write anything, and hence must be last.)
+\end{methoddesc}
+
+\begin{methoddesc}{prepend}{cmd, kind}
+Add a new action at the beginning. See \method{append()} for explanations
+of the arguments.
+\end{methoddesc}
+
+\begin{methoddesc}{open}{file, mode}
+Return a file-like object, open to \var{file}, but read from or
+written to by the pipeline.  Note that only one of \code{'r'},
+\code{'w'} may be given.
+\end{methoddesc}
+
+\begin{methoddesc}{copy}{infile, outfile}
+Copy \var{infile} to \var{outfile} through the pipe.
+\end{methoddesc}

Added: vendor/Python/current/Doc/lib/libpkgutil.tex
===================================================================
--- vendor/Python/current/Doc/lib/libpkgutil.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libpkgutil.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,45 @@
+\section{\module{pkgutil} ---
+         Package extension utility}
+
+\declaremodule{standard}{pkgutil}
+\modulesynopsis{Utilities to support extension of packages.}
+
+\versionadded{2.3}
+
+This module provides a single function:
+
+\begin{funcdesc}{extend_path}{path, name}
+  Extend the search path for the modules which comprise a package.
+  Intended use is to place the following code in a package's
+  \file{__init__.py}:
+
+\begin{verbatim}
+from pkgutil import extend_path
+__path__ = extend_path(__path__, __name__)
+\end{verbatim}
+
+  This will add to the package's \code{__path__} all subdirectories of
+  directories on \code{sys.path} named after the package.  This is
+  useful if one wants to distribute different parts of a single
+  logical package as multiple directories.
+
+  It also looks for \file{*.pkg} files beginning where \code{*}
+  matches the \var{name} argument.  This feature is similar to
+  \file{*.pth} files (see the \refmodule{site} module for more
+  information), except that it doesn't special-case lines starting
+  with \code{import}.  A \file{*.pkg} file is trusted at face value:
+  apart from checking for duplicates, all entries found in a
+  \file{*.pkg} file are added to the path, regardless of whether they
+  exist on the filesystem.  (This is a feature.)
+
+  If the input path is not a list (as is the case for frozen
+  packages) it is returned unchanged.  The input path is not
+  modified; an extended copy is returned.  Items are only appended
+  to the copy at the end.
+
+  It is assumed that \code{sys.path} is a sequence.  Items of
+  \code{sys.path} that are not (Unicode or 8-bit) strings referring to
+  existing directories are ignored.  Unicode items on \code{sys.path}
+  that cause errors when used as filenames may cause this function to
+  raise an exception (in line with \function{os.path.isdir()} behavior).
+\end{funcdesc}

Added: vendor/Python/current/Doc/lib/libplatform.tex
===================================================================
--- vendor/Python/current/Doc/lib/libplatform.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libplatform.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,221 @@
+\section{\module{platform} --- 
+   Access to underlying platform's identifying data.}
+
+\declaremodule{standard}{platform}
+\modulesynopsis{Retrieves as much platform identifying data as possible.}
+\moduleauthor{Marc-Andre Lemburg}{mal at egenix.com}
+\sectionauthor{Bjorn Pettersen}{bpettersen at corp.fairisaac.com}
+
+\versionadded{2.3}
+
+\begin{notice}
+  Specific platforms listed alphabetically, with Linux included in the
+  \UNIX{} section.
+\end{notice}
+
+\subsection{Cross Platform}
+
+\begin{funcdesc}{architecture}{executable=sys.executable, bits='', linkage=''}
+  Queries the given executable (defaults to the Python interpreter
+  binary) for various architecture information.
+
+  Returns a tuple \code{(bits, linkage)} which contain information about
+  the bit architecture and the linkage format used for the
+  executable. Both values are returned as strings.
+
+  Values that cannot be determined are returned as given by the
+  parameter presets. If bits is given as \code{''}, the
+  \cfunction{sizeof(pointer)}
+  (or \cfunction{sizeof(long)} on Python version < 1.5.2) is used as
+  indicator for the supported pointer size.
+
+  The function relies on the system's \file{file} command to do the
+  actual work. This is available on most if not all \UNIX{} 
+  platforms and some non-\UNIX{} platforms and then only if the
+  executable points to the Python interpreter.  Reasonable defaults
+  are used when the above needs are not met.
+\end{funcdesc}
+
+\begin{funcdesc}{machine}{}
+  Returns the machine type, e.g. \code{'i386'}.
+  An empty string is returned if the value cannot be determined.
+\end{funcdesc}
+
+\begin{funcdesc}{node}{}
+  Returns the computer's network name (may not be fully qualified!).
+  An empty string is returned if the value cannot be determined.
+\end{funcdesc}
+
+\begin{funcdesc}{platform}{aliased=0, terse=0}
+  Returns a single string identifying the underlying platform
+  with as much useful information as possible.
+
+  The output is intended to be \emph{human readable} rather than
+  machine parseable. It may look different on different platforms and
+  this is intended.
+
+  If \var{aliased} is true, the function will use aliases for various
+  platforms that report system names which differ from their common
+  names, for example SunOS will be reported as Solaris.  The
+  \function{system_alias()} function is used to implement this.
+
+  Setting \var{terse} to true causes the function to return only the
+  absolute minimum information needed to identify the platform.
+\end{funcdesc}
+
+\begin{funcdesc}{processor}{}
+  Returns the (real) processor name, e.g. \code{'amdk6'}.
+
+  An empty string is returned if the value cannot be determined. Note
+  that many platforms do not provide this information or simply return
+  the same value as for \function{machine()}.  NetBSD does this.
+\end{funcdesc}
+
+\begin{funcdesc}{python_build}{}
+  Returns a tuple \code{(\var{buildno}, \var{builddate})} stating the
+  Python build number and date as strings.
+\end{funcdesc}
+
+\begin{funcdesc}{python_compiler}{}
+  Returns a string identifying the compiler used for compiling Python.
+\end{funcdesc}
+
+\begin{funcdesc}{python_version}{}
+  Returns the Python version as string \code{'major.minor.patchlevel'}
+
+  Note that unlike the Python \code{sys.version}, the returned value
+  will always include the patchlevel (it defaults to 0).
+\end{funcdesc}
+
+\begin{funcdesc}{python_version_tuple}{}
+  Returns the Python version as tuple \code{(\var{major}, \var{minor},
+  \var{patchlevel})} of strings.
+
+  Note that unlike the Python \code{sys.version}, the returned value
+  will always include the patchlevel (it defaults to \code{'0'}).
+\end{funcdesc}
+
+\begin{funcdesc}{release}{}
+  Returns the system's release, e.g. \code{'2.2.0'} or \code{'NT'}
+  An empty string is returned if the value cannot be determined.
+\end{funcdesc}
+
+\begin{funcdesc}{system}{}
+  Returns the system/OS name, e.g. \code{'Linux'}, \code{'Windows'},
+  or \code{'Java'}.
+  An empty string is returned if the value cannot be determined.
+\end{funcdesc}
+
+\begin{funcdesc}{system_alias}{system, release, version}
+  Returns \code{(\var{system}, \var{release}, \var{version})} aliased
+  to common marketing names used for some systems.  It also does some
+  reordering of the information in some cases where it would otherwise
+  cause confusion.
+\end{funcdesc}
+
+\begin{funcdesc}{version}{}
+  Returns the system's release version, e.g. \code{'\#3 on degas'}.
+  An empty string is returned if the value cannot be determined.
+\end{funcdesc}
+
+\begin{funcdesc}{uname}{}
+  Fairly portable uname interface. Returns a tuple of strings
+  \code{(\var{system}, \var{node}, \var{release}, \var{version},
+  \var{machine}, \var{processor})} identifying the underlying
+  platform.
+
+  Note that unlike the \function{os.uname()} function this also returns
+  possible processor information as additional tuple entry.
+
+  Entries which cannot be determined are set to \code{''}.
+\end{funcdesc}
+
+
+\subsection{Java Platform}
+
+\begin{funcdesc}{java_ver}{release='', vendor='', vminfo=('','',''),
+                           osinfo=('','','')}
+  Version interface for JPython.
+
+  Returns a tuple \code{(\var{release}, \var{vendor}, \var{vminfo},
+  \var{osinfo})} with \var{vminfo} being a tuple \code{(\var{vm_name},
+  \var{vm_release}, \var{vm_vendor})} and \var{osinfo} being a tuple
+  \code{(\var{os_name}, \var{os_version}, \var{os_arch})}.
+  Values which cannot be determined are set to the defaults
+  given as parameters (which all default to \code{''}).
+\end{funcdesc}
+
+
+\subsection{Windows Platform}
+
+\begin{funcdesc}{win32_ver}{release='', version='', csd='', ptype=''}
+  Get additional version information from the Windows Registry
+  and return a tuple \code{(\var{version}, \var{csd}, \var{ptype})}
+  referring to version number, CSD level and OS type (multi/single
+  processor).
+
+  As a hint: \var{ptype} is \code{'Uniprocessor Free'} on single
+  processor NT machines and \code{'Multiprocessor Free'} on multi
+  processor machines. The \emph{'Free'} refers to the OS version being
+  free of debugging code. It could also state \emph{'Checked'} which
+  means the OS version uses debugging code, i.e. code that
+  checks arguments, ranges, etc.
+
+  \begin{notice}[note]
+    This function only works if Mark Hammond's \module{win32all}
+    package is installed and (obviously) only runs on Win32
+    compatible platforms.
+  \end{notice}
+\end{funcdesc}
+
+\subsubsection{Win95/98 specific}
+
+\begin{funcdesc}{popen}{cmd, mode='r', bufsize=None}
+  Portable \function{popen()} interface.  Find a working popen
+  implementation preferring \function{win32pipe.popen()}.  On Windows
+  NT, \function{win32pipe.popen()} should work; on Windows 9x it hangs
+  due to bugs in the MS C library.
+  % This KnowledgeBase article appears to be missing...
+  %See also \ulink{MS KnowledgeBase article Q150956}{}.
+\end{funcdesc}
+
+
+\subsection{Mac OS Platform}
+
+\begin{funcdesc}{mac_ver}{release='', versioninfo=('','',''), machine=''}
+  Get Mac OS version information and return it as tuple
+  \code{(\var{release}, \var{versioninfo}, \var{machine})} with
+  \var{versioninfo} being a tuple \code{(\var{version},
+  \var{dev_stage}, \var{non_release_version})}.
+
+  Entries which cannot be determined are set to \code{''}.  All tuple
+  entries are strings.
+
+  Documentation for the underlying \cfunction{gestalt()} API is
+  available online at \url{http://www.rgaros.nl/gestalt/}.
+\end{funcdesc}
+
+
+\subsection{\UNIX{} Platforms}
+
+\begin{funcdesc}{dist}{distname='', version='', id='',
+                       supported_dists=('SuSE','debian','redhat','mandrake')}
+  Tries to determine the name of the OS distribution name
+  Returns a tuple \code{(\var{distname}, \var{version}, \var{id})}
+  which defaults to the args given as parameters.
+\end{funcdesc}
+
+
+\begin{funcdesc}{libc_ver}{executable=sys.executable, lib='',
+                           version='', chunksize=2048}
+  Tries to determine the libc version against which the file
+  executable (defaults to the Python interpreter) is linked.  Returns
+  a tuple of strings \code{(\var{lib}, \var{version})} which default
+  to the given parameters in case the lookup fails.
+
+  Note that this function has intimate knowledge of how different
+  libc versions add symbols to the executable is probably only
+  useable for executables compiled using \program{gcc}.
+
+  The file is read and scanned in chunks of \var{chunksize} bytes.
+\end{funcdesc}

Added: vendor/Python/current/Doc/lib/libpopen2.tex
===================================================================
--- vendor/Python/current/Doc/lib/libpopen2.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libpopen2.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,189 @@
+\section{\module{popen2} ---
+         Subprocesses with accessible I/O streams}
+
+\declaremodule{standard}{popen2}
+\modulesynopsis{Subprocesses with accessible standard I/O streams.}
+\sectionauthor{Drew Csillag}{drew_csillag at geocities.com}
+
+
+This module allows you to spawn processes and connect to their
+input/output/error pipes and obtain their return codes under
+\UNIX{} and Windows.
+
+The \module{subprocess} module provides more powerful facilities for
+spawning new processes and retrieving their results.  Using the
+\module{subprocess} module is preferable to using the \module{popen2}
+module.
+
+The primary interface offered by this module is a trio of factory
+functions.  For each of these, if \var{bufsize} is specified, 
+it specifies the buffer size for the I/O pipes.  \var{mode}, if
+provided, should be the string \code{'b'} or \code{'t'}; on Windows
+this is needed to determine whether the file objects should be opened
+in binary or text mode.  The default value for \var{mode} is
+\code{'t'}.
+
+On \UNIX, \var{cmd} may be a sequence, in which case arguments will be passed
+directly to the program without shell intervention (as with
+\function{os.spawnv()}). If \var{cmd} is a string it will be passed to the
+shell (as with \function{os.system()}).
+
+The only way to retrieve the return codes for the child processes is
+by using the \method{poll()} or \method{wait()} methods on the
+\class{Popen3} and \class{Popen4} classes; these are only available on
+\UNIX.  This information is not available when using the
+\function{popen2()}, \function{popen3()}, and \function{popen4()}
+functions, or the equivalent functions in the \refmodule{os} module.
+(Note that the tuples returned by the \refmodule{os} module's functions
+are in a different order from the ones returned by the \module{popen2}
+module.)
+
+\begin{funcdesc}{popen2}{cmd\optional{, bufsize\optional{, mode}}}
+Executes \var{cmd} as a sub-process.  Returns the file objects
+\code{(\var{child_stdout}, \var{child_stdin})}.
+\end{funcdesc}
+
+\begin{funcdesc}{popen3}{cmd\optional{, bufsize\optional{, mode}}}
+Executes \var{cmd} as a sub-process.  Returns the file objects
+\code{(\var{child_stdout}, \var{child_stdin}, \var{child_stderr})}.
+\end{funcdesc}
+
+\begin{funcdesc}{popen4}{cmd\optional{, bufsize\optional{, mode}}}
+Executes \var{cmd} as a sub-process.  Returns the file objects
+\code{(\var{child_stdout_and_stderr}, \var{child_stdin})}.
+\versionadded{2.0}
+\end{funcdesc}
+
+
+On \UNIX, a class defining the objects returned by the factory
+functions is also available.  These are not used for the Windows
+implementation, and are not available on that platform.
+
+\begin{classdesc}{Popen3}{cmd\optional{, capturestderr\optional{, bufsize}}}
+This class represents a child process.  Normally, \class{Popen3}
+instances are created using the \function{popen2()} and
+\function{popen3()} factory functions described above.
+
+If not using one of the helper functions to create \class{Popen3}
+objects, the parameter \var{cmd} is the shell command to execute in a
+sub-process.  The \var{capturestderr} flag, if true, specifies that
+the object should capture standard error output of the child process.
+The default is false.  If the \var{bufsize} parameter is specified, it
+specifies the size of the I/O buffers to/from the child process.
+\end{classdesc}
+
+\begin{classdesc}{Popen4}{cmd\optional{, bufsize}}
+Similar to \class{Popen3}, but always captures standard error into the
+same file object as standard output.  These are typically created
+using \function{popen4()}.
+\versionadded{2.0}
+\end{classdesc}
+
+\subsection{Popen3 and Popen4 Objects \label{popen3-objects}}
+
+Instances of the \class{Popen3} and \class{Popen4} classes have the
+following methods:
+
+\begin{methoddesc}{poll}{}
+Returns \code{-1} if child process hasn't completed yet, or its return 
+code otherwise.
+\end{methoddesc}
+
+\begin{methoddesc}{wait}{}
+Waits for and returns the status code of the child process.  The
+status code encodes both the return code of the process and
+information about whether it exited using the \cfunction{exit()}
+system call or died due to a signal.  Functions to help interpret the
+status code are defined in the \refmodule{os} module; see section
+\ref{os-process} for the \function{W\var{*}()} family of functions.
+\end{methoddesc}
+
+
+The following attributes are also available: 
+
+\begin{memberdesc}{fromchild}
+A file object that provides output from the child process.  For
+\class{Popen4} instances, this will provide both the standard output
+and standard error streams.
+\end{memberdesc}
+
+\begin{memberdesc}{tochild}
+A file object that provides input to the child process.
+\end{memberdesc}
+
+\begin{memberdesc}{childerr}
+A file object that provides error output from the child process, if
+\var{capturestderr} was true for the constructor, otherwise
+\code{None}.  This will always be \code{None} for \class{Popen4}
+instances.
+\end{memberdesc}
+
+\begin{memberdesc}{pid}
+The process ID of the child process.
+\end{memberdesc}
+
+
+\subsection{Flow Control Issues \label{popen2-flow-control}}
+
+Any time you are working with any form of inter-process communication,
+control flow needs to be carefully thought out.  This remains the case
+with the file objects provided by this module (or the \refmodule{os}
+module equivalents).
+
+% Example explanation and suggested work-arounds substantially stolen
+% from Martin von Löwis:
+% http://mail.python.org/pipermail/python-dev/2000-September/009460.html
+
+When reading output from a child process that writes a lot of data to
+standard error while the parent is reading from the child's standard
+output, a deadlock can occur.  A similar situation can occur with other
+combinations of reads and writes.  The essential factors are that more
+than \constant{_PC_PIPE_BUF} bytes are being written by one process in
+a blocking fashion, while the other process is reading from the other
+process, also in a blocking fashion.
+
+There are several ways to deal with this situation.
+
+The simplest application change, in many cases, will be to follow this
+model in the parent process:
+
+\begin{verbatim}
+import popen2
+
+r, w, e = popen2.popen3('python slave.py')
+e.readlines()
+r.readlines()
+r.close()
+e.close()
+w.close()
+\end{verbatim}
+
+with code like this in the child:
+
+\begin{verbatim}
+import os
+import sys
+
+# note that each of these print statements
+# writes a single long string
+
+print >>sys.stderr, 400 * 'this is a test\n'
+os.close(sys.stderr.fileno())
+print >>sys.stdout, 400 * 'this is another test\n'
+\end{verbatim}
+
+In particular, note that \code{sys.stderr} must be closed after
+writing all data, or \method{readlines()} won't return.  Also note
+that \function{os.close()} must be used, as \code{sys.stderr.close()}
+won't close \code{stderr} (otherwise assigning to \code{sys.stderr}
+will silently close it, so no further errors can be printed).
+
+Applications which need to support a more general approach should
+integrate I/O over pipes with their \function{select()} loops, or use
+separate threads to read each of the individual files provided by
+whichever \function{popen*()} function or \class{Popen*} class was
+used.
+
+\begin{seealso}
+  \seemodule{subprocess}{Module for spawning and managing subprocesses.}
+\end{seealso}

Added: vendor/Python/current/Doc/lib/libpoplib.tex
===================================================================
--- vendor/Python/current/Doc/lib/libpoplib.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libpoplib.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,181 @@
+\section{\module{poplib} ---
+         POP3 protocol client}
+
+\declaremodule{standard}{poplib}
+\modulesynopsis{POP3 protocol client (requires sockets).}
+
+%By Andrew T. Csillag
+%Even though I put it into LaTeX, I cannot really claim that I wrote
+%it since I just stole most of it from the poplib.py source code and
+%the imaplib ``chapter''.
+%Revised by ESR, January 2000
+
+\indexii{POP3}{protocol}
+
+This module defines a class, \class{POP3}, which encapsulates a
+connection to a POP3 server and implements the protocol as defined in
+\rfc{1725}.  The \class{POP3} class supports both the minimal and
+optional command sets. Additionally, this module provides a class
+\class{POP3_SSL}, which provides support for connecting to POP3
+servers that use SSL as an underlying protocol layer.
+
+
+Note that POP3, though widely supported, is obsolescent.  The
+implementation quality of POP3 servers varies widely, and too many are
+quite poor. If your mailserver supports IMAP, you would be better off
+using the \code{\refmodule{imaplib}.\class{IMAP4}} class, as IMAP
+servers tend to be better implemented.
+
+A single class is provided by the \module{poplib} module:
+
+\begin{classdesc}{POP3}{host\optional{, port}}
+This class implements the actual POP3 protocol.  The connection is
+created when the instance is initialized.
+If \var{port} is omitted, the standard POP3 port (110) is used.
+\end{classdesc}
+
+\begin{classdesc}{POP3_SSL}{host\optional{, port\optional{, keyfile\optional{, certfile}}}}
+This is a subclass of \class{POP3} that connects to the server over an
+SSL encrypted socket.  If \var{port} is not specified, 995, the
+standard POP3-over-SSL port is used.  \var{keyfile} and \var{certfile}
+are also optional - they can contain a PEM formatted private key and
+certificate chain file for the SSL connection.
+
+\versionadded{2.4}
+\end{classdesc}
+
+One exception is defined as an attribute of the \module{poplib} module:
+
+\begin{excdesc}{error_proto}
+Exception raised on any errors.  The reason for the exception is
+passed to the constructor as a string.
+\end{excdesc}
+
+\begin{seealso}
+  \seemodule{imaplib}{The standard Python IMAP module.}
+  \seetitle[http://www.catb.org/\~{}esr/fetchmail/fetchmail-FAQ.html]
+        {Frequently Asked Questions About Fetchmail}
+        {The FAQ for the \program{fetchmail} POP/IMAP client collects
+         information on POP3 server variations and RFC noncompliance
+         that may be useful if you need to write an application based
+         on the POP protocol.}
+\end{seealso}
+
+
+\subsection{POP3 Objects \label{pop3-objects}}
+
+All POP3 commands are represented by methods of the same name,
+in lower-case; most return the response text sent by the server.
+
+An \class{POP3} instance has the following methods:
+
+
+\begin{methoddesc}{set_debuglevel}{level}
+Set the instance's debugging level.  This controls the amount of
+debugging output printed.  The default, \code{0}, produces no
+debugging output.  A value of \code{1} produces a moderate amount of
+debugging output, generally a single line per request.  A value of
+\code{2} or higher produces the maximum amount of debugging output,
+logging each line sent and received on the control connection.
+\end{methoddesc}
+
+\begin{methoddesc}{getwelcome}{}
+Returns the greeting string sent by the POP3 server.
+\end{methoddesc}
+
+\begin{methoddesc}{user}{username}
+Send user command, response should indicate that a password is required.
+\end{methoddesc}
+
+\begin{methoddesc}{pass_}{password}
+Send password, response includes message count and mailbox size.
+Note: the mailbox on the server is locked until \method{quit()} is
+called.
+\end{methoddesc}
+
+\begin{methoddesc}{apop}{user, secret}
+Use the more secure APOP authentication to log into the POP3 server.
+\end{methoddesc}
+
+\begin{methoddesc}{rpop}{user}
+Use RPOP authentication (similar to UNIX r-commands) to log into POP3 server.
+\end{methoddesc}
+
+\begin{methoddesc}{stat}{}
+Get mailbox status.  The result is a tuple of 2 integers:
+\code{(\var{message count}, \var{mailbox size})}.
+\end{methoddesc}
+
+\begin{methoddesc}{list}{\optional{which}}
+Request message list, result is in the form
+\code{(\var{response}, ['mesg_num octets', ...], \var{octets})}.
+If \var{which} is set, it is the message to list.
+\end{methoddesc}
+
+\begin{methoddesc}{retr}{which}
+Retrieve whole message number \var{which}, and set its seen flag.
+Result is in form  \code{(\var{response}, ['line', ...], \var{octets})}.
+\end{methoddesc}
+
+\begin{methoddesc}{dele}{which}
+Flag message number \var{which} for deletion.  On most servers
+deletions are not actually performed until QUIT (the major exception is
+Eudora QPOP, which deliberately violates the RFCs by doing pending
+deletes on any disconnect).
+\end{methoddesc}
+
+\begin{methoddesc}{rset}{}
+Remove any deletion marks for the mailbox.
+\end{methoddesc}
+
+\begin{methoddesc}{noop}{}
+Do nothing.  Might be used as a keep-alive.
+\end{methoddesc}
+
+\begin{methoddesc}{quit}{}
+Signoff:  commit changes, unlock mailbox, drop connection.
+\end{methoddesc}
+
+\begin{methoddesc}{top}{which, howmuch}
+Retrieves the message header plus \var{howmuch} lines of the message
+after the header of message number \var{which}. Result is in form
+\code{(\var{response}, ['line', ...], \var{octets})}.
+
+The POP3 TOP command this method uses, unlike the RETR command,
+doesn't set the message's seen flag; unfortunately, TOP is poorly
+specified in the RFCs and is frequently broken in off-brand servers.
+Test this method by hand against the POP3 servers you will use before
+trusting it.
+\end{methoddesc}
+
+\begin{methoddesc}{uidl}{\optional{which}}
+Return message digest (unique id) list.
+If \var{which} is specified, result contains the unique id for that
+message in the form \code{'\var{response}\ \var{mesgnum}\ \var{uid}},
+otherwise result is list \code{(\var{response}, ['mesgnum uid', ...],
+\var{octets})}.
+\end{methoddesc}
+
+Instances of \class{POP3_SSL} have no additional methods. The
+interface of this subclass is identical to its parent.
+
+
+\subsection{POP3 Example \label{pop3-example}}
+
+Here is a minimal example (without error checking) that opens a
+mailbox and retrieves and prints all messages:
+
+\begin{verbatim}
+import getpass, poplib
+
+M = poplib.POP3('localhost')
+M.user(getpass.getuser())
+M.pass_(getpass.getpass())
+numMessages = len(M.list()[1])
+for i in range(numMessages):
+    for j in M.retr(i+1)[1]:
+        print j
+\end{verbatim}
+
+At the end of the module, there is a test section that contains a more
+extensive example of usage.

Added: vendor/Python/current/Doc/lib/libposix.tex
===================================================================
--- vendor/Python/current/Doc/lib/libposix.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libposix.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,97 @@
+\section{\module{posix} ---
+         The most common \POSIX{} system calls}
+
+\declaremodule{builtin}{posix}
+  \platform{Unix}
+\modulesynopsis{The most common \POSIX\ system calls (normally used
+                via module \refmodule{os}).}
+
+
+This module provides access to operating system functionality that is
+standardized by the C Standard and the \POSIX{} standard (a thinly
+disguised \UNIX{} interface).
+
+\strong{Do not import this module directly.}  Instead, import the
+module \refmodule{os}, which provides a \emph{portable} version of this
+interface.  On \UNIX, the \refmodule{os} module provides a superset of
+the \module{posix} interface.  On non-\UNIX{} operating systems the
+\module{posix} module is not available, but a subset is always
+available through the \refmodule{os} interface.  Once \refmodule{os} is
+imported, there is \emph{no} performance penalty in using it instead
+of \module{posix}.  In addition, \refmodule{os}\refstmodindex{os}
+provides some additional functionality, such as automatically calling
+\function{putenv()} when an entry in \code{os.environ} is changed.
+
+The descriptions below are very terse; refer to the corresponding
+\UNIX{} manual (or \POSIX{} documentation) entry for more information.
+Arguments called \var{path} refer to a pathname given as a string.
+
+Errors are reported as exceptions; the usual exceptions are given for
+type errors, while errors reported by the system calls raise
+\exception{error} (a synonym for the standard exception
+\exception{OSError}), described below.
+
+
+\subsection{Large File Support \label{posix-large-files}}
+\sectionauthor{Steve Clift}{clift at mail.anacapa.net}
+\index{large files}
+\index{file!large files}
+
+
+Several operating systems (including AIX, HPUX, Irix and Solaris)
+provide support for files that are larger than 2 Gb from a C
+programming model where \ctype{int} and \ctype{long} are 32-bit
+values. This is typically accomplished by defining the relevant size
+and offset types as 64-bit values. Such files are sometimes referred
+to as \dfn{large files}.
+
+Large file support is enabled in Python when the size of an
+\ctype{off_t} is larger than a \ctype{long} and the \ctype{long long}
+type is available and is at least as large as an \ctype{off_t}. Python
+longs are then used to represent file sizes, offsets and other values
+that can exceed the range of a Python int. It may be necessary to
+configure and compile Python with certain compiler flags to enable
+this mode. For example, it is enabled by default with recent versions
+of Irix, but with Solaris 2.6 and 2.7 you need to do something like:
+
+\begin{verbatim}
+CFLAGS="`getconf LFS_CFLAGS`" OPT="-g -O2 $CFLAGS" \
+        ./configure
+\end{verbatim} % $ <-- bow to font-lock
+
+On large-file-capable Linux systems, this might work:
+
+\begin{verbatim}
+CFLAGS='-D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64' OPT="-g -O2 $CFLAGS" \
+        ./configure
+\end{verbatim} % $ <-- bow to font-lock
+
+
+\subsection{Module Contents \label{posix-contents}}
+
+
+Module \module{posix} defines the following data item:
+
+\begin{datadesc}{environ}
+A dictionary representing the string environment at the time the
+interpreter was started. For example, \code{environ['HOME']} is the
+pathname of your home directory, equivalent to
+\code{getenv("HOME")} in C.
+
+Modifying this dictionary does not affect the string environment
+passed on by \function{execv()}, \function{popen()} or
+\function{system()}; if you need to change the environment, pass
+\code{environ} to \function{execve()} or add variable assignments and
+export statements to the command string for \function{system()} or
+\function{popen()}.
+
+\note{The \refmodule{os} module provides an alternate
+implementation of \code{environ} which updates the environment on
+modification.  Note also that updating \code{os.environ} will render
+this dictionary obsolete.  Use of the \refmodule{os} module version of
+this is recommended over direct access to the \module{posix} module.}
+\end{datadesc}
+
+Additional contents of this module should only be accessed via the
+\refmodule{os} module; refer to the documentation for that module for
+further information.

Added: vendor/Python/current/Doc/lib/libposixfile.tex
===================================================================
--- vendor/Python/current/Doc/lib/libposixfile.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libposixfile.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,175 @@
+% Manual text and implementation by Jaap Vermeulen
+\section{\module{posixfile} ---
+         File-like objects with locking support}
+
+\declaremodule{builtin}{posixfile}
+  \platform{Unix}
+\modulesynopsis{A file-like object with support for locking.}
+\moduleauthor{Jaap Vermeulen}{}
+\sectionauthor{Jaap Vermeulen}{}
+
+
+\indexii{\POSIX}{file object}
+
+\deprecated{1.5}{The locking operation that this module provides is
+done better and more portably by the
+\function{\refmodule{fcntl}.lockf()} call.
+\withsubitem{(in module fcntl)}{\ttindex{lockf()}}}
+
+This module implements some additional functionality over the built-in
+file objects.  In particular, it implements file locking, control over
+the file flags, and an easy interface to duplicate the file object.
+The module defines a new file object, the posixfile object.  It
+has all the standard file object methods and adds the methods
+described below.  This module only works for certain flavors of
+\UNIX, since it uses \function{fcntl.fcntl()} for file locking.%
+\withsubitem{(in module fcntl)}{\ttindex{fcntl()}}
+
+To instantiate a posixfile object, use the \function{open()} function
+in the \module{posixfile} module.  The resulting object looks and
+feels roughly the same as a standard file object.
+
+The \module{posixfile} module defines the following constants:
+
+
+\begin{datadesc}{SEEK_SET}
+Offset is calculated from the start of the file.
+\end{datadesc}
+
+\begin{datadesc}{SEEK_CUR}
+Offset is calculated from the current position in the file.
+\end{datadesc}
+
+\begin{datadesc}{SEEK_END}
+Offset is calculated from the end of the file.
+\end{datadesc}
+
+The \module{posixfile} module defines the following functions:
+
+
+\begin{funcdesc}{open}{filename\optional{, mode\optional{, bufsize}}}
+ Create a new posixfile object with the given filename and mode.  The
+ \var{filename}, \var{mode} and \var{bufsize} arguments are
+ interpreted the same way as by the built-in \function{open()}
+ function.
+\end{funcdesc}
+
+\begin{funcdesc}{fileopen}{fileobject}
+ Create a new posixfile object with the given standard file object.
+ The resulting object has the same filename and mode as the original
+ file object.
+\end{funcdesc}
+
+The posixfile object defines the following additional methods:
+
+\setindexsubitem{(posixfile method)}
+\begin{funcdesc}{lock}{fmt, \optional{len\optional{, start\optional{, whence}}}}
+ Lock the specified section of the file that the file object is
+ referring to.  The format is explained
+ below in a table.  The \var{len} argument specifies the length of the
+ section that should be locked. The default is \code{0}. \var{start}
+ specifies the starting offset of the section, where the default is
+ \code{0}.  The \var{whence} argument specifies where the offset is
+ relative to. It accepts one of the constants \constant{SEEK_SET},
+ \constant{SEEK_CUR} or \constant{SEEK_END}.  The default is
+ \constant{SEEK_SET}.  For more information about the arguments refer
+ to the \manpage{fcntl}{2} manual page on your system.
+\end{funcdesc}
+
+\begin{funcdesc}{flags}{\optional{flags}}
+ Set the specified flags for the file that the file object is referring
+ to.  The new flags are ORed with the old flags, unless specified
+ otherwise.  The format is explained below in a table.  Without
+ the \var{flags} argument
+ a string indicating the current flags is returned (this is
+ the same as the \samp{?} modifier).  For more information about the
+ flags refer to the \manpage{fcntl}{2} manual page on your system.
+\end{funcdesc}
+
+\begin{funcdesc}{dup}{}
+ Duplicate the file object and the underlying file pointer and file
+ descriptor.  The resulting object behaves as if it were newly
+ opened.
+\end{funcdesc}
+
+\begin{funcdesc}{dup2}{fd}
+ Duplicate the file object and the underlying file pointer and file
+ descriptor.  The new object will have the given file descriptor.
+ Otherwise the resulting object behaves as if it were newly opened.
+\end{funcdesc}
+
+\begin{funcdesc}{file}{}
+ Return the standard file object that the posixfile object is based
+ on.  This is sometimes necessary for functions that insist on a
+ standard file object.
+\end{funcdesc}
+
+All methods raise \exception{IOError} when the request fails.
+
+Format characters for the \method{lock()} method have the following
+meaning:
+
+\begin{tableii}{c|l}{samp}{Format}{Meaning}
+  \lineii{u}{unlock the specified region}
+  \lineii{r}{request a read lock for the specified section}
+  \lineii{w}{request a write lock for the specified section}
+\end{tableii}
+
+In addition the following modifiers can be added to the format:
+
+\begin{tableiii}{c|l|c}{samp}{Modifier}{Meaning}{Notes}
+  \lineiii{|}{wait until the lock has been granted}{}
+  \lineiii{?}{return the first lock conflicting with the requested lock, or
+              \code{None} if there is no conflict.}{(1)} 
+\end{tableiii}
+
+\noindent
+Note:
+
+\begin{description}
+\item[(1)] The lock returned is in the format \code{(\var{mode}, \var{len},
+\var{start}, \var{whence}, \var{pid})} where \var{mode} is a character
+representing the type of lock ('r' or 'w').  This modifier prevents a
+request from being granted; it is for query purposes only.
+\end{description}
+
+Format characters for the \method{flags()} method have the following
+meanings:
+
+\begin{tableii}{c|l}{samp}{Format}{Meaning}
+  \lineii{a}{append only flag}
+  \lineii{c}{close on exec flag}
+  \lineii{n}{no delay flag (also called non-blocking flag)}
+  \lineii{s}{synchronization flag}
+\end{tableii}
+
+In addition the following modifiers can be added to the format:
+
+\begin{tableiii}{c|l|c}{samp}{Modifier}{Meaning}{Notes}
+  \lineiii{!}{turn the specified flags 'off', instead of the default 'on'}{(1)}
+  \lineiii{=}{replace the flags, instead of the default 'OR' operation}{(1)}
+  \lineiii{?}{return a string in which the characters represent the flags that
+  are set.}{(2)}
+\end{tableiii}
+
+\noindent
+Notes:
+
+\begin{description}
+\item[(1)] The \samp{!} and \samp{=} modifiers are mutually exclusive.
+
+\item[(2)] This string represents the flags after they may have been altered
+by the same call.
+\end{description}
+
+Examples:
+
+\begin{verbatim}
+import posixfile
+
+file = posixfile.open('/tmp/test', 'w')
+file.lock('w|')
+...
+file.lock('u')
+file.close()
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/libposixpath.tex
===================================================================
--- vendor/Python/current/Doc/lib/libposixpath.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libposixpath.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,281 @@
+\section{\module{os.path} ---
+         Common pathname manipulations}
+\declaremodule{standard}{os.path}
+
+\modulesynopsis{Common pathname manipulations.}
+
+This module implements some useful functions on pathnames.
+\index{path!operations}
+
+\warning{On Windows, many of these functions do not properly
+support UNC pathnames.  \function{splitunc()} and \function{ismount()}
+do handle them correctly.}
+
+
+\begin{funcdesc}{abspath}{path}
+Return a normalized absolutized version of the pathname \var{path}.
+On most platforms, this is equivalent to
+\code{normpath(join(os.getcwd(), \var{path}))}.
+\versionadded{1.5.2}
+\end{funcdesc}
+
+\begin{funcdesc}{basename}{path}
+Return the base name of pathname \var{path}.  This is the second half
+of the pair returned by \code{split(\var{path})}.  Note that the
+result of this function is different from the
+\UNIX{} \program{basename} program; where \program{basename} for
+\code{'/foo/bar/'} returns \code{'bar'}, the \function{basename()}
+function returns an empty string (\code{''}).
+\end{funcdesc}
+
+\begin{funcdesc}{commonprefix}{list}
+Return the longest path prefix (taken character-by-character) that is a
+prefix of all paths in 
+\var{list}.  If \var{list} is empty, return the empty string
+(\code{''}).  Note that this may return invalid paths because it works a
+character at a time.
+\end{funcdesc}
+
+\begin{funcdesc}{dirname}{path}
+Return the directory name of pathname \var{path}.  This is the first
+half of the pair returned by \code{split(\var{path})}.
+\end{funcdesc}
+
+\begin{funcdesc}{exists}{path}
+Return \code{True} if \var{path} refers to an existing path.  Returns
+\code{False} for broken symbolic links. On some platforms, this
+function may return \code{False} if permission is not granted to
+execute \function{os.stat()} on the requested file, even if the
+\var{path} physically exists.
+\end{funcdesc}
+
+\begin{funcdesc}{lexists}{path}
+Return \code{True} if \var{path} refers to an existing path.
+Returns \code{True} for broken symbolic links.  
+Equivalent to \function{exists()} on platforms lacking
+\function{os.lstat()}.
+\versionadded{2.4}
+\end{funcdesc}
+
+\begin{funcdesc}{expanduser}{path}
+On \UNIX, return the argument with an initial component of \samp{\~} or
+\samp{\~\var{user}} replaced by that \var{user}'s home directory.
+An initial \samp{\~} is replaced by the environment variable
+\envvar{HOME} if it is set; otherwise the current user's home directory
+is looked up in the password directory through the built-in module
+\refmodule{pwd}\refbimodindex{pwd}.
+An initial \samp{\~\var{user}} is looked up directly in the
+password directory.
+
+On Windows, only \samp{\~} is supported; it is replaced by the
+environment variable \envvar{HOME} or by a combination of
+\envvar{HOMEDRIVE} and \envvar{HOMEPATH}.
+
+If the expansion fails or if the
+path does not begin with a tilde, the path is returned unchanged.
+\end{funcdesc}
+
+\begin{funcdesc}{expandvars}{path}
+Return the argument with environment variables expanded.  Substrings
+of the form \samp{\$\var{name}} or \samp{\$\{\var{name}\}} are
+replaced by the value of environment variable \var{name}.  Malformed
+variable names and references to non-existing variables are left
+unchanged.
+\end{funcdesc}
+
+\begin{funcdesc}{getatime}{path}
+Return the time of last access of \var{path}.  The return
+value is a number giving the number of seconds since the epoch (see the 
+\refmodule{time} module).  Raise \exception{os.error} if the file does
+not exist or is inaccessible.
+\versionadded{1.5.2}
+\versionchanged[If \function{os.stat_float_times()} returns True, the result is a floating point number]{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{getmtime}{path}
+Return the time of last modification of \var{path}.  The return
+value is a number giving the number of seconds since the epoch (see the 
+\refmodule{time} module).  Raise \exception{os.error} if the file does
+not exist or is inaccessible.
+\versionadded{1.5.2}
+\versionchanged[If \function{os.stat_float_times()} returns True, the result is a floating point number]{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{getctime}{path}
+Return the system's ctime which, on some systems (like \UNIX) is the
+time of the last change, and, on others (like Windows), is the
+creation time for \var{path}.  The return
+value is a number giving the number of seconds since the epoch (see the 
+\refmodule{time} module).  Raise \exception{os.error} if the file does
+not exist or is inaccessible.
+\versionadded{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{getsize}{path}
+Return the size, in bytes, of \var{path}.  Raise
+\exception{os.error} if the file does not exist or is inaccessible.
+\versionadded{1.5.2}
+\end{funcdesc}
+
+\begin{funcdesc}{isabs}{path}
+Return \code{True} if \var{path} is an absolute pathname (begins with a
+slash).
+\end{funcdesc}
+
+\begin{funcdesc}{isfile}{path}
+Return \code{True} if \var{path} is an existing regular file.  This follows
+symbolic links, so both \function{islink()} and \function{isfile()}
+can be true for the same path.
+\end{funcdesc}
+
+\begin{funcdesc}{isdir}{path}
+Return \code{True} if \var{path} is an existing directory.  This follows
+symbolic links, so both \function{islink()} and \function{isdir()} can
+be true for the same path.
+\end{funcdesc}
+
+\begin{funcdesc}{islink}{path}
+Return \code{True} if \var{path} refers to a directory entry that is a
+symbolic link.  Always \code{False} if symbolic links are not supported.
+\end{funcdesc}
+
+\begin{funcdesc}{ismount}{path}
+Return \code{True} if pathname \var{path} is a \dfn{mount point}: a point in
+a file system where a different file system has been mounted.  The
+function checks whether \var{path}'s parent, \file{\var{path}/..}, is
+on a different device than \var{path}, or whether \file{\var{path}/..}
+and \var{path} point to the same i-node on the same device --- this
+should detect mount points for all \UNIX{} and \POSIX{} variants.
+\end{funcdesc}
+
+\begin{funcdesc}{join}{path1\optional{, path2\optional{, ...}}}
+Join one or more path components intelligently.  If any component is
+an absolute path, all previous components (on Windows, including the
+previous drive letter, if there was one) are thrown away, and joining
+continues.  The return value is the concatenation of \var{path1}, and
+optionally \var{path2}, etc., with exactly one directory separator
+(\code{os.sep}) inserted between components, unless \var{path2} is
+empty.  Note that on Windows, since there is a current directory for
+each drive, \function{os.path.join("c:", "foo")} represents a path
+relative to the current directory on drive \file{C:} (\file{c:foo}), not
+\file{c:\textbackslash\textbackslash foo}.
+\end{funcdesc}
+
+\begin{funcdesc}{normcase}{path}
+Normalize the case of a pathname.  On \UNIX, this returns the path
+unchanged; on case-insensitive filesystems, it converts the path to
+lowercase.  On Windows, it also converts forward slashes to backward
+slashes.
+\end{funcdesc}
+
+\begin{funcdesc}{normpath}{path}
+Normalize a pathname.  This collapses redundant separators and
+up-level references so that \code{A//B}, \code{A/./B} and
+\code{A/foo/../B} all become \code{A/B}.  It does not normalize the
+case (use \function{normcase()} for that).  On Windows, it converts
+forward slashes to backward slashes. It should be understood that this may
+change the meaning of the path if it contains symbolic links! 
+\end{funcdesc}
+
+\begin{funcdesc}{realpath}{path}
+Return the canonical path of the specified filename, eliminating any
+symbolic links encountered in the path (if they are supported by the
+operating system).
+\versionadded{2.2}
+\end{funcdesc}
+
+\begin{funcdesc}{samefile}{path1, path2}
+Return \code{True} if both pathname arguments refer to the same file or
+directory (as indicated by device number and i-node number).
+Raise an exception if a \function{os.stat()} call on either pathname
+fails.
+Availability:  Macintosh, \UNIX.
+\end{funcdesc}
+
+\begin{funcdesc}{sameopenfile}{fp1, fp2}
+Return \code{True} if the file descriptors \var{fp1} and \var{fp2} refer
+to the same file.
+Availability:  Macintosh, \UNIX.
+\end{funcdesc}
+
+\begin{funcdesc}{samestat}{stat1, stat2}
+Return \code{True} if the stat tuples \var{stat1} and \var{stat2} refer to
+the same file.  These structures may have been returned by
+\function{fstat()}, \function{lstat()}, or \function{stat()}.  This
+function implements the underlying comparison used by
+\function{samefile()} and \function{sameopenfile()}.
+Availability:  Macintosh, \UNIX.
+\end{funcdesc}
+
+\begin{funcdesc}{split}{path}
+Split the pathname \var{path} into a pair, \code{(\var{head},
+\var{tail})} where \var{tail} is the last pathname component and
+\var{head} is everything leading up to that.  The \var{tail} part will
+never contain a slash; if \var{path} ends in a slash, \var{tail} will
+be empty.  If there is no slash in \var{path}, \var{head} will be
+empty.  If \var{path} is empty, both \var{head} and \var{tail} are
+empty.  Trailing slashes are stripped from \var{head} unless it is the
+root (one or more slashes only).  In nearly all cases,
+\code{join(\var{head}, \var{tail})} equals \var{path} (the only
+exception being when there were multiple slashes separating \var{head}
+from \var{tail}).
+\end{funcdesc}
+
+\begin{funcdesc}{splitdrive}{path}
+Split the pathname \var{path} into a pair \code{(\var{drive},
+\var{tail})} where \var{drive} is either a drive specification or the
+empty string.  On systems which do not use drive specifications,
+\var{drive} will always be the empty string.  In all cases,
+\code{\var{drive} + \var{tail}} will be the same as \var{path}.
+\versionadded{1.3}
+\end{funcdesc}
+
+\begin{funcdesc}{splitext}{path}
+Split the pathname \var{path} into a pair \code{(\var{root}, \var{ext})} 
+such that \code{\var{root} + \var{ext} == \var{path}},
+and \var{ext} is empty or begins with a period and contains
+at most one period.
+\end{funcdesc}
+
+\begin{funcdesc}{splitunc}{path}
+Split the pathname \var{path} into a pair \code{(\var{unc}, \var{rest})}
+so that \var{unc} is the UNC mount point (such as \code{r'\e\e host\e mount'}),
+if present, and \var{rest} the rest of the path (such as 
+\code{r'\e path\e file.ext'}).  For paths containing drive letters, \var{unc}
+will always be the empty string.
+Availability:  Windows.
+\end{funcdesc}
+
+\begin{funcdesc}{walk}{path, visit, arg}
+Calls the function \var{visit} with arguments
+\code{(\var{arg}, \var{dirname}, \var{names})} for each directory in the
+directory tree rooted at \var{path} (including \var{path} itself, if it
+is a directory).  The argument \var{dirname} specifies the visited
+directory, the argument \var{names} lists the files in the directory
+(gotten from \code{os.listdir(\var{dirname})}).
+The \var{visit} function may modify \var{names} to
+influence the set of directories visited below \var{dirname}, e.g. to
+avoid visiting certain parts of the tree.  (The object referred to by
+\var{names} must be modified in place, using \keyword{del} or slice
+assignment.)
+
+\begin{notice}
+Symbolic links to directories are not treated as subdirectories, and
+that \function{walk()} therefore will not visit them. To visit linked
+directories you must identify them with
+\code{os.path.islink(\var{file})} and
+\code{os.path.isdir(\var{file})}, and invoke \function{walk()} as
+necessary.
+\end{notice}
+
+\note{The newer \function{\refmodule{os}.walk()} generator supplies
+      similar functionality and can be easier to use.}
+\end{funcdesc}
+
+\begin{datadesc}{supports_unicode_filenames}
+True if arbitrary Unicode strings can be used as file names (within
+limitations imposed by the file system), and if
+\function{os.listdir()} returns Unicode strings for a Unicode
+argument.
+\versionadded{2.3}
+\end{datadesc}

Added: vendor/Python/current/Doc/lib/libpprint.tex
===================================================================
--- vendor/Python/current/Doc/lib/libpprint.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libpprint.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,210 @@
+\section{\module{pprint} ---
+         Data pretty printer}
+
+\declaremodule{standard}{pprint}
+\modulesynopsis{Data pretty printer.}
+\moduleauthor{Fred L. Drake, Jr.}{fdrake at acm.org}
+\sectionauthor{Fred L. Drake, Jr.}{fdrake at acm.org}
+
+
+The \module{pprint} module provides a capability to ``pretty-print''
+arbitrary Python data structures in a form which can be used as input
+to the interpreter.  If the formatted structures include objects which
+are not fundamental Python types, the representation may not be
+loadable.  This may be the case if objects such as files, sockets,
+classes, or instances are included, as well as many other builtin
+objects which are not representable as Python constants.
+
+The formatted representation keeps objects on a single line if it can,
+and breaks them onto multiple lines if they don't fit within the
+allowed width.  Construct \class{PrettyPrinter} objects explicitly if
+you need to adjust the width constraint.
+
+\versionchanged[Dictionaries are sorted by key before the display is
+computed; before 2.5, a dictionary was sorted only if its display
+required more than one line, although that wasn't documented]{2.5}
+
+The \module{pprint} module defines one class:
+
+
+% First the implementation class:
+
+\begin{classdesc}{PrettyPrinter}{...}
+Construct a \class{PrettyPrinter} instance.  This constructor
+understands several keyword parameters.  An output stream may be set
+using the \var{stream} keyword; the only method used on the stream
+object is the file protocol's \method{write()} method.  If not
+specified, the \class{PrettyPrinter} adopts \code{sys.stdout}.  Three
+additional parameters may be used to control the formatted
+representation.  The keywords are \var{indent}, \var{depth}, and
+\var{width}.  The amount of indentation added for each recursive level
+is specified by \var{indent}; the default is one.  Other values can
+cause output to look a little odd, but can make nesting easier to
+spot.  The number of levels which may be printed is controlled by
+\var{depth}; if the data structure being printed is too deep, the next
+contained level is replaced by \samp{...}.  By default, there is no
+constraint on the depth of the objects being formatted.  The desired
+output width is constrained using the \var{width} parameter; the
+default is eighty characters.  If a structure cannot be formatted
+within the constrained width, a best effort will be made.
+
+\begin{verbatim}
+>>> import pprint, sys
+>>> stuff = sys.path[:]
+>>> stuff.insert(0, stuff[:])
+>>> pp = pprint.PrettyPrinter(indent=4)
+>>> pp.pprint(stuff)
+[   [   '',
+        '/usr/local/lib/python1.5',
+        '/usr/local/lib/python1.5/test',
+        '/usr/local/lib/python1.5/sunos5',
+        '/usr/local/lib/python1.5/sharedmodules',
+        '/usr/local/lib/python1.5/tkinter'],
+    '',
+    '/usr/local/lib/python1.5',
+    '/usr/local/lib/python1.5/test',
+    '/usr/local/lib/python1.5/sunos5',
+    '/usr/local/lib/python1.5/sharedmodules',
+    '/usr/local/lib/python1.5/tkinter']
+>>>
+>>> import parser
+>>> tup = parser.ast2tuple(
+...     parser.suite(open('pprint.py').read()))[1][1][1]
+>>> pp = pprint.PrettyPrinter(depth=6)
+>>> pp.pprint(tup)
+(266, (267, (307, (287, (288, (...))))))
+\end{verbatim}
+\end{classdesc}
+
+
+% Now the derivative functions:
+
+The \class{PrettyPrinter} class supports several derivative functions:
+
+\begin{funcdesc}{pformat}{object\optional{, indent\optional{,
+width\optional{, depth}}}}
+Return the formatted representation of \var{object} as a string.  \var{indent},
+\var{width} and \var{depth} will be passed to the \class{PrettyPrinter}
+constructor as formatting parameters.
+\versionchanged[The parameters \var{indent}, \var{width} and \var{depth}
+were added]{2.4}
+\end{funcdesc}
+
+\begin{funcdesc}{pprint}{object\optional{, stream\optional{,
+indent\optional{, width\optional{, depth}}}}}
+Prints the formatted representation of \var{object} on \var{stream},
+followed by a newline.  If \var{stream} is omitted, \code{sys.stdout}
+is used.  This may be used in the interactive interpreter instead of a
+\keyword{print} statement for inspecting values.    \var{indent},
+\var{width} and \var{depth} will be passed to the \class{PrettyPrinter}
+constructor as formatting parameters.
+
+\begin{verbatim}
+>>> stuff = sys.path[:]
+>>> stuff.insert(0, stuff)
+>>> pprint.pprint(stuff)
+[<Recursion on list with id=869440>,
+ '',
+ '/usr/local/lib/python1.5',
+ '/usr/local/lib/python1.5/test',
+ '/usr/local/lib/python1.5/sunos5',
+ '/usr/local/lib/python1.5/sharedmodules',
+ '/usr/local/lib/python1.5/tkinter']
+\end{verbatim}
+\versionchanged[The parameters \var{indent}, \var{width} and \var{depth}
+were added]{2.4}
+\end{funcdesc}
+
+\begin{funcdesc}{isreadable}{object}
+Determine if the formatted representation of \var{object} is
+``readable,'' or can be used to reconstruct the value using
+\function{eval()}\bifuncindex{eval}.  This always returns false for
+recursive objects.
+
+\begin{verbatim}
+>>> pprint.isreadable(stuff)
+False
+\end{verbatim}
+\end{funcdesc}
+
+\begin{funcdesc}{isrecursive}{object}
+Determine if \var{object} requires a recursive representation.
+\end{funcdesc}
+
+
+One more support function is also defined:
+
+\begin{funcdesc}{saferepr}{object}
+Return a string representation of \var{object}, protected against
+recursive data structures.  If the representation of \var{object}
+exposes a recursive entry, the recursive reference will be represented
+as \samp{<Recursion on \var{typename} with id=\var{number}>}.  The
+representation is not otherwise formatted.
+\end{funcdesc}
+
+% This example is outside the {funcdesc} to keep it from running over
+% the right margin.
+\begin{verbatim}
+>>> pprint.saferepr(stuff)
+"[<Recursion on list with id=682968>, '', '/usr/local/lib/python1.5', '/usr/loca
+l/lib/python1.5/test', '/usr/local/lib/python1.5/sunos5', '/usr/local/lib/python
+1.5/sharedmodules', '/usr/local/lib/python1.5/tkinter']"
+\end{verbatim}
+
+
+\subsection{PrettyPrinter Objects}
+\label{PrettyPrinter Objects}
+
+\class{PrettyPrinter} instances have the following methods:
+
+
+\begin{methoddesc}{pformat}{object}
+Return the formatted representation of \var{object}.  This takes into
+account the options passed to the \class{PrettyPrinter} constructor.
+\end{methoddesc}
+
+\begin{methoddesc}{pprint}{object}
+Print the formatted representation of \var{object} on the configured
+stream, followed by a newline.
+\end{methoddesc}
+
+The following methods provide the implementations for the
+corresponding functions of the same names.  Using these methods on an
+instance is slightly more efficient since new \class{PrettyPrinter}
+objects don't need to be created.
+
+\begin{methoddesc}{isreadable}{object}
+Determine if the formatted representation of the object is
+``readable,'' or can be used to reconstruct the value using
+\function{eval()}\bifuncindex{eval}.  Note that this returns false for
+recursive objects.  If the \var{depth} parameter of the
+\class{PrettyPrinter} is set and the object is deeper than allowed,
+this returns false.
+\end{methoddesc}
+
+\begin{methoddesc}{isrecursive}{object}
+Determine if the object requires a recursive representation.
+\end{methoddesc}
+
+This method is provided as a hook to allow subclasses to modify the
+way objects are converted to strings.  The default implementation uses
+the internals of the \function{saferepr()} implementation.
+
+\begin{methoddesc}{format}{object, context, maxlevels, level}
+Returns three values: the formatted version of \var{object} as a
+string, a flag indicating whether the result is readable, and a flag
+indicating whether recursion was detected.  The first argument is the
+object to be presented.  The second is a dictionary which contains the
+\function{id()} of objects that are part of the current presentation
+context (direct and indirect containers for \var{object} that are
+affecting the presentation) as the keys; if an object needs to be
+presented which is already represented in \var{context}, the third
+return value should be true.  Recursive calls to the \method{format()}
+method should add additional entries for containers to this
+dictionary.  The third argument, \var{maxlevels}, gives the requested
+limit to recursion; this will be \code{0} if there is no requested
+limit.  This argument should be passed unmodified to recursive calls.
+The fourth argument, \var{level}, gives the current level; recursive
+calls should be passed a value less than that of the current call.
+\versionadded{2.3}
+\end{methoddesc}

Added: vendor/Python/current/Doc/lib/libprofile.tex
===================================================================
--- vendor/Python/current/Doc/lib/libprofile.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libprofile.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,722 @@
+\chapter{The Python Profilers \label{profile}}
+
+\sectionauthor{James Roskind}{}
+
+Copyright \copyright{} 1994, by InfoSeek Corporation, all rights reserved.
+\index{InfoSeek Corporation}
+
+Written by James Roskind.\footnote{
+  Updated and converted to \LaTeX\ by Guido van Rossum.
+  Further updated by Armin Rigo to integrate the documentation for the new
+  \module{cProfile} module of Python 2.5.}
+
+Permission to use, copy, modify, and distribute this Python software
+and its associated documentation for any purpose (subject to the
+restriction in the following sentence) without fee is hereby granted,
+provided that the above copyright notice appears in all copies, and
+that both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of InfoSeek not be used in
+advertising or publicity pertaining to distribution of the software
+without specific, written prior permission.  This permission is
+explicitly restricted to the copying and modification of the software
+to remain in Python, compiled Python, or other languages (such as C)
+wherein the modified or derived code is exclusively imported into a
+Python module.
+
+INFOSEEK CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS. IN NO EVENT SHALL INFOSEEK CORPORATION BE LIABLE FOR ANY
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+
+The profiler was written after only programming in Python for 3 weeks.
+As a result, it is probably clumsy code, but I don't know for sure yet
+'cause I'm a beginner :-).  I did work hard to make the code run fast,
+so that profiling would be a reasonable thing to do.  I tried not to
+repeat code fragments, but I'm sure I did some stuff in really awkward
+ways at times.  Please send suggestions for improvements to:
+\email{jar at netscape.com}.  I won't promise \emph{any} support.  ...but
+I'd appreciate the feedback.
+
+
+\section{Introduction to the profilers}
+\nodename{Profiler Introduction}
+
+A \dfn{profiler} is a program that describes the run time performance
+of a program, providing a variety of statistics.  This documentation
+describes the profiler functionality provided in the modules
+\module{profile} and \module{pstats}.  This profiler provides
+\dfn{deterministic profiling} of any Python programs.  It also
+provides a series of report generation tools to allow users to rapidly
+examine the results of a profile operation.
+\index{deterministic profiling}
+\index{profiling, deterministic}
+
+The Python standard library provides three different profilers:
+
+\begin{enumerate}
+\item \module{profile}, a pure Python module, described in the sequel.
+  Copyright \copyright{} 1994, by InfoSeek Corporation.
+  \versionchanged[also reports the time spent in calls to built-in
+  functions and methods]{2.4}
+
+\item \module{cProfile}, a module written in C, with a reasonable
+  overhead that makes it suitable for profiling long-running programs.
+  Based on \module{lsprof}, contributed by Brett Rosen and Ted Czotter.
+  \versionadded{2.5}
+
+\item \module{hotshot}, a C module focusing on minimizing the overhead
+  while profiling, at the expense of long data post-processing times.
+  \versionchanged[the results should be more meaningful than in the
+  past: the timing core contained a critical bug]{2.5}
+\end{enumerate}
+
+The \module{profile} and \module{cProfile} modules export the same
+interface, so they are mostly interchangeables; \module{cProfile} has a
+much lower overhead but is not so far as well-tested and might not be
+available on all systems.  \module{cProfile} is really a compatibility
+layer on top of the internal \module{_lsprof} module.  The
+\module{hotshot} module is reserved to specialized usages.
+
+%\section{How Is This Profiler Different From The Old Profiler?}
+%\nodename{Profiler Changes}
+%
+%(This section is of historical importance only; the old profiler
+%discussed here was last seen in Python 1.1.)
+%
+%The big changes from old profiling module are that you get more
+%information, and you pay less CPU time.  It's not a trade-off, it's a
+%trade-up.
+%
+%To be specific:
+%
+%\begin{description}
+%
+%\item[Bugs removed:]
+%Local stack frame is no longer molested, execution time is now charged
+%to correct functions.
+%
+%\item[Accuracy increased:]
+%Profiler execution time is no longer charged to user's code,
+%calibration for platform is supported, file reads are not done \emph{by}
+%profiler \emph{during} profiling (and charged to user's code!).
+%
+%\item[Speed increased:]
+%Overhead CPU cost was reduced by more than a factor of two (perhaps a
+%factor of five), lightweight profiler module is all that must be
+%loaded, and the report generating module (\module{pstats}) is not needed
+%during profiling.
+%
+%\item[Recursive functions support:]
+%Cumulative times in recursive functions are correctly calculated;
+%recursive entries are counted.
+%
+%\item[Large growth in report generating UI:]
+%Distinct profiles runs can be added together forming a comprehensive
+%report; functions that import statistics take arbitrary lists of
+%files; sorting criteria is now based on keywords (instead of 4 integer
+%options); reports shows what functions were profiled as well as what
+%profile file was referenced; output format has been improved.
+%
+%\end{description}
+
+
+\section{Instant User's Manual \label{profile-instant}}
+
+This section is provided for users that ``don't want to read the
+manual.'' It provides a very brief overview, and allows a user to
+rapidly perform profiling on an existing application.
+
+To profile an application with a main entry point of \function{foo()},
+you would add the following to your module:
+
+\begin{verbatim}
+import cProfile
+cProfile.run('foo()')
+\end{verbatim}
+
+(Use \module{profile} instead of \module{cProfile} if the latter is not
+available on your system.)
+
+The above action would cause \function{foo()} to be run, and a series of
+informative lines (the profile) to be printed.  The above approach is
+most useful when working with the interpreter.  If you would like to
+save the results of a profile into a file for later examination, you
+can supply a file name as the second argument to the \function{run()}
+function:
+
+\begin{verbatim}
+import cProfile
+cProfile.run('foo()', 'fooprof')
+\end{verbatim}
+
+The file \file{cProfile.py} can also be invoked as
+a script to profile another script.  For example:
+
+\begin{verbatim}
+python -m cProfile myscript.py
+\end{verbatim}
+
+\file{cProfile.py} accepts two optional arguments on the command line:
+
+\begin{verbatim}
+cProfile.py [-o output_file] [-s sort_order]
+\end{verbatim}
+
+\programopt{-s} only applies to standard output (\programopt{-o} is
+not supplied).  Look in the \class{Stats} documentation for valid sort
+values.
+
+When you wish to review the profile, you should use the methods in the
+\module{pstats} module.  Typically you would load the statistics data as
+follows:
+
+\begin{verbatim}
+import pstats
+p = pstats.Stats('fooprof')
+\end{verbatim}
+
+The class \class{Stats} (the above code just created an instance of
+this class) has a variety of methods for manipulating and printing the
+data that was just read into \code{p}.  When you ran
+\function{cProfile.run()} above, what was printed was the result of three
+method calls:
+
+\begin{verbatim}
+p.strip_dirs().sort_stats(-1).print_stats()
+\end{verbatim}
+
+The first method removed the extraneous path from all the module
+names. The second method sorted all the entries according to the
+standard module/line/name string that is printed.
+%(this is to comply with the semantics of the old profiler).
+The third method printed out
+all the statistics.  You might try the following sort calls:
+
+\begin{verbatim}
+p.sort_stats('name')
+p.print_stats()
+\end{verbatim}
+
+The first call will actually sort the list by function name, and the
+second call will print out the statistics.  The following are some
+interesting calls to experiment with:
+
+\begin{verbatim}
+p.sort_stats('cumulative').print_stats(10)
+\end{verbatim}
+
+This sorts the profile by cumulative time in a function, and then only
+prints the ten most significant lines.  If you want to understand what
+algorithms are taking time, the above line is what you would use.
+
+If you were looking to see what functions were looping a lot, and
+taking a lot of time, you would do:
+
+\begin{verbatim}
+p.sort_stats('time').print_stats(10)
+\end{verbatim}
+
+to sort according to time spent within each function, and then print
+the statistics for the top ten functions.
+
+You might also try:
+
+\begin{verbatim}
+p.sort_stats('file').print_stats('__init__')
+\end{verbatim}
+
+This will sort all the statistics by file name, and then print out
+statistics for only the class init methods (since they are spelled
+with \code{__init__} in them).  As one final example, you could try:
+
+\begin{verbatim}
+p.sort_stats('time', 'cum').print_stats(.5, 'init')
+\end{verbatim}
+
+This line sorts statistics with a primary key of time, and a secondary
+key of cumulative time, and then prints out some of the statistics.
+To be specific, the list is first culled down to 50\% (re: \samp{.5})
+of its original size, then only lines containing \code{init} are
+maintained, and that sub-sub-list is printed.
+
+If you wondered what functions called the above functions, you could
+now (\code{p} is still sorted according to the last criteria) do:
+
+\begin{verbatim}
+p.print_callers(.5, 'init')
+\end{verbatim}
+
+and you would get a list of callers for each of the listed functions.
+
+If you want more functionality, you're going to have to read the
+manual, or guess what the following functions do:
+
+\begin{verbatim}
+p.print_callees()
+p.add('fooprof')
+\end{verbatim}
+
+Invoked as a script, the \module{pstats} module is a statistics
+browser for reading and examining profile dumps.  It has a simple
+line-oriented interface (implemented using \refmodule{cmd}) and
+interactive help.
+
+\section{What Is Deterministic Profiling?}
+\nodename{Deterministic Profiling}
+
+\dfn{Deterministic profiling} is meant to reflect the fact that all
+\emph{function call}, \emph{function return}, and \emph{exception} events
+are monitored, and precise timings are made for the intervals between
+these events (during which time the user's code is executing).  In
+contrast, \dfn{statistical profiling} (which is not done by this
+module) randomly samples the effective instruction pointer, and
+deduces where time is being spent.  The latter technique traditionally
+involves less overhead (as the code does not need to be instrumented),
+but provides only relative indications of where time is being spent.
+
+In Python, since there is an interpreter active during execution, the
+presence of instrumented code is not required to do deterministic
+profiling.  Python automatically provides a \dfn{hook} (optional
+callback) for each event.  In addition, the interpreted nature of
+Python tends to add so much overhead to execution, that deterministic
+profiling tends to only add small processing overhead in typical
+applications.  The result is that deterministic profiling is not that
+expensive, yet provides extensive run time statistics about the
+execution of a Python program.
+
+Call count statistics can be used to identify bugs in code (surprising
+counts), and to identify possible inline-expansion points (high call
+counts).  Internal time statistics can be used to identify ``hot
+loops'' that should be carefully optimized.  Cumulative time
+statistics should be used to identify high level errors in the
+selection of algorithms.  Note that the unusual handling of cumulative
+times in this profiler allows statistics for recursive implementations
+of algorithms to be directly compared to iterative implementations.
+
+
+\section{Reference Manual -- \module{profile} and \module{cProfile}}
+
+\declaremodule{standard}{profile}
+\declaremodule{standard}{cProfile}
+\modulesynopsis{Python profiler}
+
+
+
+The primary entry point for the profiler is the global function
+\function{profile.run()} (resp. \function{cProfile.run()}).
+It is typically used to create any profile
+information.  The reports are formatted and printed using methods of
+the class \class{pstats.Stats}.  The following is a description of all
+of these standard entry points and functions.  For a more in-depth
+view of some of the code, consider reading the later section on
+Profiler Extensions, which includes discussion of how to derive
+``better'' profilers from the classes presented, or reading the source
+code for these modules.
+
+\begin{funcdesc}{run}{command\optional{, filename}}
+
+This function takes a single argument that can be passed to the
+\keyword{exec} statement, and an optional file name.  In all cases this
+routine attempts to \keyword{exec} its first argument, and gather profiling
+statistics from the execution. If no file name is present, then this
+function automatically prints a simple profiling report, sorted by the
+standard name string (file/line/function-name) that is presented in
+each line.  The following is a typical output from such a call:
+
+\begin{verbatim}
+      2706 function calls (2004 primitive calls) in 4.504 CPU seconds
+
+Ordered by: standard name
+
+ncalls  tottime  percall  cumtime  percall filename:lineno(function)
+     2    0.006    0.003    0.953    0.477 pobject.py:75(save_objects)
+  43/3    0.533    0.012    0.749    0.250 pobject.py:99(evaluate)
+ ...
+\end{verbatim}
+
+The first line indicates that 2706 calls were
+monitored.  Of those calls, 2004 were \dfn{primitive}.  We define
+\dfn{primitive} to mean that the call was not induced via recursion.
+The next line: \code{Ordered by:\ standard name}, indicates that
+the text string in the far right column was used to sort the output.
+The column headings include:
+
+\begin{description}
+
+\item[ncalls ]
+for the number of calls,
+
+\item[tottime ]
+for the total time spent in the given function (and excluding time
+made in calls to sub-functions),
+
+\item[percall ]
+is the quotient of \code{tottime} divided by \code{ncalls}
+
+\item[cumtime ]
+is the total time spent in this and all subfunctions (from invocation
+till exit). This figure is accurate \emph{even} for recursive
+functions.
+
+\item[percall ]
+is the quotient of \code{cumtime} divided by primitive calls
+
+\item[filename:lineno(function) ]
+provides the respective data of each function
+
+\end{description}
+
+When there are two numbers in the first column (for example,
+\samp{43/3}), then the latter is the number of primitive calls, and
+the former is the actual number of calls.  Note that when the function
+does not recurse, these two values are the same, and only the single
+figure is printed.
+
+\end{funcdesc}
+
+\begin{funcdesc}{runctx}{command, globals, locals\optional{, filename}}
+This function is similar to \function{run()}, with added
+arguments to supply the globals and locals dictionaries for the
+\var{command} string.
+\end{funcdesc}
+
+Analysis of the profiler data is done using the \class{Stats} class.
+
+\note{The \class{Stats} class is defined in the \module{pstats} module.}
+
+% now switch modules....
+% (This \stmodindex use may be hard to change ;-( )
+\stmodindex{pstats}
+
+\begin{classdesc}{Stats}{filename\optional{, stream=sys.stdout\optional{, \moreargs}}}
+This class constructor creates an instance of a ``statistics object''
+from a \var{filename} (or set of filenames).  \class{Stats} objects are
+manipulated by methods, in order to print useful reports.  You may specify
+an alternate output stream by giving the keyword argument, \code{stream}.
+
+The file selected by the above constructor must have been created by the
+corresponding version of \module{profile} or \module{cProfile}.  To be
+specific, there is \emph{no} file compatibility guaranteed with future
+versions of this profiler, and there is no compatibility with files produced
+by other profilers.
+%(such as the old system profiler).
+
+If several files are provided, all the statistics for identical
+functions will be coalesced, so that an overall view of several
+processes can be considered in a single report.  If additional files
+need to be combined with data in an existing \class{Stats} object, the
+\method{add()} method can be used.
+
+\versionchanged[The \var{stream} parameter was added]{2.5}
+\end{classdesc}
+
+
+\subsection{The \class{Stats} Class \label{profile-stats}}
+
+\class{Stats} objects have the following methods:
+
+\begin{methoddesc}[Stats]{strip_dirs}{}
+This method for the \class{Stats} class removes all leading path
+information from file names.  It is very useful in reducing the size
+of the printout to fit within (close to) 80 columns.  This method
+modifies the object, and the stripped information is lost.  After
+performing a strip operation, the object is considered to have its
+entries in a ``random'' order, as it was just after object
+initialization and loading.  If \method{strip_dirs()} causes two
+function names to be indistinguishable (they are on the same
+line of the same filename, and have the same function name), then the
+statistics for these two entries are accumulated into a single entry.
+\end{methoddesc}
+
+
+\begin{methoddesc}[Stats]{add}{filename\optional{, \moreargs}}
+This method of the \class{Stats} class accumulates additional
+profiling information into the current profiling object.  Its
+arguments should refer to filenames created by the corresponding
+version of \function{profile.run()} or \function{cProfile.run()}.
+Statistics for identically named
+(re: file, line, name) functions are automatically accumulated into
+single function statistics.
+\end{methoddesc}
+
+\begin{methoddesc}[Stats]{dump_stats}{filename}
+Save the data loaded into the \class{Stats} object to a file named
+\var{filename}.  The file is created if it does not exist, and is
+overwritten if it already exists.  This is equivalent to the method of
+the same name on the \class{profile.Profile} and
+\class{cProfile.Profile} classes.
+\versionadded{2.3}
+\end{methoddesc}
+
+\begin{methoddesc}[Stats]{sort_stats}{key\optional{, \moreargs}}
+This method modifies the \class{Stats} object by sorting it according
+to the supplied criteria.  The argument is typically a string
+identifying the basis of a sort (example: \code{'time'} or
+\code{'name'}).
+
+When more than one key is provided, then additional keys are used as
+secondary criteria when there is equality in all keys selected
+before them.  For example, \code{sort_stats('name', 'file')} will sort
+all the entries according to their function name, and resolve all ties
+(identical function names) by sorting by file name.
+
+Abbreviations can be used for any key names, as long as the
+abbreviation is unambiguous.  The following are the keys currently
+defined:
+
+\begin{tableii}{l|l}{code}{Valid Arg}{Meaning}
+  \lineii{'calls'}{call count}
+  \lineii{'cumulative'}{cumulative time}
+  \lineii{'file'}{file name}
+  \lineii{'module'}{file name}
+  \lineii{'pcalls'}{primitive call count}
+  \lineii{'line'}{line number}
+  \lineii{'name'}{function name}
+  \lineii{'nfl'}{name/file/line}
+  \lineii{'stdname'}{standard name}
+  \lineii{'time'}{internal time}
+\end{tableii}
+
+Note that all sorts on statistics are in descending order (placing
+most time consuming items first), where as name, file, and line number
+searches are in ascending order (alphabetical). The subtle
+distinction between \code{'nfl'} and \code{'stdname'} is that the
+standard name is a sort of the name as printed, which means that the
+embedded line numbers get compared in an odd way.  For example, lines
+3, 20, and 40 would (if the file names were the same) appear in the
+string order 20, 3 and 40.  In contrast, \code{'nfl'} does a numeric
+compare of the line numbers.  In fact, \code{sort_stats('nfl')} is the
+same as \code{sort_stats('name', 'file', 'line')}.
+
+%For compatibility with the old profiler,
+For backward-compatibility reasons, the numeric arguments
+\code{-1}, \code{0}, \code{1}, and \code{2} are permitted.  They are
+interpreted as \code{'stdname'}, \code{'calls'}, \code{'time'}, and
+\code{'cumulative'} respectively.  If this old style format (numeric)
+is used, only one sort key (the numeric key) will be used, and
+additional arguments will be silently ignored.
+\end{methoddesc}
+
+
+\begin{methoddesc}[Stats]{reverse_order}{}
+This method for the \class{Stats} class reverses the ordering of the basic
+list within the object.  %This method is provided primarily for
+%compatibility with the old profiler.
+Note that by default ascending vs descending order is properly selected
+based on the sort key of choice.
+\end{methoddesc}
+
+\begin{methoddesc}[Stats]{print_stats}{\optional{restriction, \moreargs}}
+This method for the \class{Stats} class prints out a report as described
+in the \function{profile.run()} definition.
+
+The order of the printing is based on the last \method{sort_stats()}
+operation done on the object (subject to caveats in \method{add()} and
+\method{strip_dirs()}).
+
+The arguments provided (if any) can be used to limit the list down to
+the significant entries.  Initially, the list is taken to be the
+complete set of profiled functions.  Each restriction is either an
+integer (to select a count of lines), or a decimal fraction between
+0.0 and 1.0 inclusive (to select a percentage of lines), or a regular
+expression (to pattern match the standard name that is printed; as of
+Python 1.5b1, this uses the Perl-style regular expression syntax
+defined by the \refmodule{re} module).  If several restrictions are
+provided, then they are applied sequentially.  For example:
+
+\begin{verbatim}
+print_stats(.1, 'foo:')
+\end{verbatim}
+
+would first limit the printing to first 10\% of list, and then only
+print functions that were part of filename \file{.*foo:}.  In
+contrast, the command:
+
+\begin{verbatim}
+print_stats('foo:', .1)
+\end{verbatim}
+
+would limit the list to all functions having file names \file{.*foo:},
+and then proceed to only print the first 10\% of them.
+\end{methoddesc}
+
+
+\begin{methoddesc}[Stats]{print_callers}{\optional{restriction, \moreargs}}
+This method for the \class{Stats} class prints a list of all functions
+that called each function in the profiled database.  The ordering is
+identical to that provided by \method{print_stats()}, and the definition
+of the restricting argument is also identical.  Each caller is reported on
+its own line.  The format differs slightly depending on the profiler that
+produced the stats:
+
+\begin{itemize}
+\item With \module{profile}, a number is shown in parentheses after each
+  caller to show how many times this specific call was made.  For
+  convenience, a second non-parenthesized number repeats the cumulative
+  time spent in the function at the right.
+
+\item With \module{cProfile}, each caller is preceeded by three numbers:
+  the number of times this specific call was made, and the total and
+  cumulative times spent in the current function while it was invoked by
+  this specific caller.
+\end{itemize}
+\end{methoddesc}
+
+\begin{methoddesc}[Stats]{print_callees}{\optional{restriction, \moreargs}}
+This method for the \class{Stats} class prints a list of all function
+that were called by the indicated function.  Aside from this reversal
+of direction of calls (re: called vs was called by), the arguments and
+ordering are identical to the \method{print_callers()} method.
+\end{methoddesc}
+
+
+\section{Limitations \label{profile-limits}}
+
+One limitation has to do with accuracy of timing information.
+There is a fundamental problem with deterministic profilers involving
+accuracy.  The most obvious restriction is that the underlying ``clock''
+is only ticking at a rate (typically) of about .001 seconds.  Hence no
+measurements will be more accurate than the underlying clock.  If
+enough measurements are taken, then the ``error'' will tend to average
+out. Unfortunately, removing this first error induces a second source
+of error.
+
+The second problem is that it ``takes a while'' from when an event is
+dispatched until the profiler's call to get the time actually
+\emph{gets} the state of the clock.  Similarly, there is a certain lag
+when exiting the profiler event handler from the time that the clock's
+value was obtained (and then squirreled away), until the user's code
+is once again executing.  As a result, functions that are called many
+times, or call many functions, will typically accumulate this error.
+The error that accumulates in this fashion is typically less than the
+accuracy of the clock (less than one clock tick), but it
+\emph{can} accumulate and become very significant.
+
+The problem is more important with \module{profile} than with the
+lower-overhead \module{cProfile}.  For this reason, \module{profile}
+provides a means of calibrating itself for a given platform so that
+this error can be probabilistically (on the average) removed.
+After the profiler is calibrated, it will be more accurate (in a least
+square sense), but it will sometimes produce negative numbers (when
+call counts are exceptionally low, and the gods of probability work
+against you :-). )  Do \emph{not} be alarmed by negative numbers in
+the profile.  They should \emph{only} appear if you have calibrated
+your profiler, and the results are actually better than without
+calibration.
+
+
+\section{Calibration \label{profile-calibration}}
+
+The profiler of the \module{profile} module subtracts a constant from each
+event handling time to compensate for the overhead of calling the time
+function, and socking away the results.  By default, the constant is 0.
+The following procedure can
+be used to obtain a better constant for a given platform (see discussion
+in section Limitations above).
+
+\begin{verbatim}
+import profile
+pr = profile.Profile()
+for i in range(5):
+    print pr.calibrate(10000)
+\end{verbatim}
+
+The method executes the number of Python calls given by the argument,
+directly and again under the profiler, measuring the time for both.
+It then computes the hidden overhead per profiler event, and returns
+that as a float.  For example, on an 800 MHz Pentium running
+Windows 2000, and using Python's time.clock() as the timer,
+the magical number is about 12.5e-6.
+
+The object of this exercise is to get a fairly consistent result.
+If your computer is \emph{very} fast, or your timer function has poor
+resolution, you might have to pass 100000, or even 1000000, to get
+consistent results.
+
+When you have a consistent answer,
+there are three ways you can use it:\footnote{Prior to Python 2.2, it
+  was necessary to edit the profiler source code to embed the bias as
+  a literal number.  You still can, but that method is no longer
+  described, because no longer needed.}
+
+\begin{verbatim}
+import profile
+
+# 1. Apply computed bias to all Profile instances created hereafter.
+profile.Profile.bias = your_computed_bias
+
+# 2. Apply computed bias to a specific Profile instance.
+pr = profile.Profile()
+pr.bias = your_computed_bias
+
+# 3. Specify computed bias in instance constructor.
+pr = profile.Profile(bias=your_computed_bias)
+\end{verbatim}
+
+If you have a choice, you are better off choosing a smaller constant, and
+then your results will ``less often'' show up as negative in profile
+statistics.
+
+
+\section{Extensions --- Deriving Better Profilers}
+\nodename{Profiler Extensions}
+
+The \class{Profile} class of both modules, \module{profile} and
+\module{cProfile}, were written so that
+derived classes could be developed to extend the profiler.  The details
+are not described here, as doing this successfully requires an expert
+understanding of how the \class{Profile} class works internally.  Study
+the source code of the module carefully if you want to
+pursue this.
+
+If all you want to do is change how current time is determined (for
+example, to force use of wall-clock time or elapsed process time),
+pass the timing function you want to the \class{Profile} class
+constructor:
+
+\begin{verbatim}
+pr = profile.Profile(your_time_func)
+\end{verbatim}
+
+The resulting profiler will then call \function{your_time_func()}.
+
+\begin{description}
+\item[\class{profile.Profile}]
+\function{your_time_func()} should return a single number, or a list of
+numbers whose sum is the current time (like what \function{os.times()}
+returns).  If the function returns a single time number, or the list of
+returned numbers has length 2, then you will get an especially fast
+version of the dispatch routine.
+
+Be warned that you should calibrate the profiler class for the
+timer function that you choose.  For most machines, a timer that
+returns a lone integer value will provide the best results in terms of
+low overhead during profiling.  (\function{os.times()} is
+\emph{pretty} bad, as it returns a tuple of floating point values).  If
+you want to substitute a better timer in the cleanest fashion,
+derive a class and hardwire a replacement dispatch method that best
+handles your timer call, along with the appropriate calibration
+constant.
+
+\item[\class{cProfile.Profile}]
+\function{your_time_func()} should return a single number.  If it returns
+plain integers, you can also invoke the class constructor with a second
+argument specifying the real duration of one unit of time.  For example,
+if \function{your_integer_time_func()} returns times measured in thousands
+of seconds, you would constuct the \class{Profile} instance as follows:
+
+\begin{verbatim}
+pr = profile.Profile(your_integer_time_func, 0.001)
+\end{verbatim}
+
+As the \module{cProfile.Profile} class cannot be calibrated, custom
+timer functions should be used with care and should be as fast as
+possible.  For the best results with a custom timer, it might be
+necessary to hard-code it in the C source of the internal
+\module{_lsprof} module.
+
+\end{description}

Added: vendor/Python/current/Doc/lib/libpty.tex
===================================================================
--- vendor/Python/current/Doc/lib/libpty.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libpty.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,44 @@
+\section{\module{pty} ---
+         Pseudo-terminal utilities}
+\declaremodule{standard}{pty}
+  \platform{IRIX, Linux}
+\modulesynopsis{Pseudo-Terminal Handling for SGI and Linux.}
+\moduleauthor{Steen Lumholt}{}
+\sectionauthor{Moshe Zadka}{moshez at zadka.site.co.il}
+
+
+The \module{pty} module defines operations for handling the
+pseudo-terminal concept: starting another process and being able to
+write to and read from its controlling terminal programmatically.
+
+Because pseudo-terminal handling is highly platform dependant, there
+is code to do it only for SGI and Linux. (The Linux code is supposed
+to work on other platforms, but hasn't been tested yet.)
+
+The \module{pty} module defines the following functions:
+
+\begin{funcdesc}{fork}{}
+Fork. Connect the child's controlling terminal to a pseudo-terminal.
+Return value is \code{(\var{pid}, \var{fd})}. Note that the child 
+gets \var{pid} 0, and the \var{fd} is \emph{invalid}. The parent's
+return value is the \var{pid} of the child, and \var{fd} is a file
+descriptor connected to the child's controlling terminal (and also
+to the child's standard input and output).
+\end{funcdesc}
+
+\begin{funcdesc}{openpty}{}
+Open a new pseudo-terminal pair, using \function{os.openpty()} if
+possible, or emulation code for SGI and generic \UNIX{} systems.
+Return a pair of file descriptors \code{(\var{master}, \var{slave})},
+for the master and the slave end, respectively.
+\end{funcdesc}
+
+\begin{funcdesc}{spawn}{argv\optional{, master_read\optional{, stdin_read}}}
+Spawn a process, and connect its controlling terminal with the current 
+process's standard io. This is often used to baffle programs which
+insist on reading from the controlling terminal.
+
+The functions \var{master_read} and \var{stdin_read} should be
+functions which read from a file-descriptor. The defaults try to read
+1024 bytes each time they are called.
+\end{funcdesc}

Added: vendor/Python/current/Doc/lib/libpwd.tex
===================================================================
--- vendor/Python/current/Doc/lib/libpwd.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libpwd.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,57 @@
+\section{\module{pwd} ---
+         The password database}
+
+\declaremodule{builtin}{pwd}
+  \platform{Unix}
+\modulesynopsis{The password database (\function{getpwnam()} and friends).}
+
+This module provides access to the \UNIX{} user account and password
+database.  It is available on all \UNIX{} versions.
+
+Password database entries are reported as a tuple-like object, whose
+attributes correspond to the members of the \code{passwd} structure
+(Attribute field below, see \code{<pwd.h>}):
+
+\begin{tableiii}{r|l|l}{textrm}{Index}{Attribute}{Meaning}
+  \lineiii{0}{\code{pw_name}}{Login name}
+  \lineiii{1}{\code{pw_passwd}}{Optional encrypted password}
+  \lineiii{2}{\code{pw_uid}}{Numerical user ID}
+  \lineiii{3}{\code{pw_gid}}{Numerical group ID}
+  \lineiii{4}{\code{pw_gecos}}{User name or comment field}
+  \lineiii{5}{\code{pw_dir}}{User home directory}
+  \lineiii{6}{\code{pw_shell}}{User command interpreter}
+\end{tableiii}
+
+The uid and gid items are integers, all others are strings.
+\exception{KeyError} is raised if the entry asked for cannot be found.
+
+\note{In traditional \UNIX{} the field \code{pw_passwd} usually
+contains a password encrypted with a DES derived algorithm (see module
+\refmodule{crypt}\refbimodindex{crypt}).  However most modern unices 
+use a so-called \emph{shadow password} system.  On those unices the
+\var{pw_passwd} field only contains an asterisk (\code{'*'}) or the 
+letter \character{x} where the encrypted password is stored in a file
+\file{/etc/shadow} which is not world readable.  Whether the \var{pw_passwd}
+field contains anything useful is system-dependent.  If available, the
+\module{spwd} module should be used where access to the encrypted password
+is required.}
+
+It defines the following items:
+
+\begin{funcdesc}{getpwuid}{uid}
+Return the password database entry for the given numeric user ID.
+\end{funcdesc}
+
+\begin{funcdesc}{getpwnam}{name}
+Return the password database entry for the given user name.
+\end{funcdesc}
+
+\begin{funcdesc}{getpwall}{}
+Return a list of all available password database entries, in arbitrary order.
+\end{funcdesc}
+
+
+\begin{seealso}
+  \seemodule{grp}{An interface to the group database, similar to this.}
+  \seemodule{spwd}{An interface to the shadow password database, similar to this.}
+\end{seealso}

Added: vendor/Python/current/Doc/lib/libpyclbr.tex
===================================================================
--- vendor/Python/current/Doc/lib/libpyclbr.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libpyclbr.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,102 @@
+\section{\module{pyclbr} ---
+         Python class browser support}
+
+\declaremodule{standard}{pyclbr}
+\modulesynopsis{Supports information extraction for a Python class
+                browser.}
+\sectionauthor{Fred L. Drake, Jr.}{fdrake at acm.org}
+
+
+The \module{pyclbr} can be used to determine some limited information
+about the classes, methods and top-level functions
+defined in a module.  The information
+provided is sufficient to implement a traditional three-pane class
+browser.  The information is extracted from the source code rather
+than by importing the module, so this module is safe to use with
+untrusted source code.  This restriction makes it impossible to use
+this module with modules not implemented in Python, including many
+standard and optional extension modules.
+
+
+\begin{funcdesc}{readmodule}{module\optional{, path}}
+  % The 'inpackage' parameter appears to be for internal use only....
+  Read a module and return a dictionary mapping class names to class
+  descriptor objects.  The parameter \var{module} should be the name
+  of a module as a string; it may be the name of a module within a
+  package.  The \var{path} parameter should be a sequence, and is used
+  to augment the value of \code{sys.path}, which is used to locate
+  module source code.
+\end{funcdesc}
+
+\begin{funcdesc}{readmodule_ex}{module\optional{, path}}
+  % The 'inpackage' parameter appears to be for internal use only....
+  Like \function{readmodule()}, but the returned dictionary, in addition
+  to mapping class names to class descriptor objects, also maps
+  top-level function names to function descriptor objects.  Moreover, if
+  the module being read is a package, the key \code{'__path__'} in the
+  returned dictionary has as its value a list which contains the package
+  search path.
+\end{funcdesc}
+
+
+\subsection{Class Descriptor Objects \label{pyclbr-class-objects}}
+
+The class descriptor objects used as values in the dictionary returned
+by \function{readmodule()} and \function{readmodule_ex()}
+provide the following data members:
+
+
+\begin{memberdesc}[class descriptor]{module}
+  The name of the module defining the class described by the class
+  descriptor.
+\end{memberdesc}
+
+\begin{memberdesc}[class descriptor]{name}
+  The name of the class.
+\end{memberdesc}
+
+\begin{memberdesc}[class descriptor]{super}
+  A list of class descriptors which describe the immediate base
+  classes of the class being described.  Classes which are named as
+  superclasses but which are not discoverable by
+  \function{readmodule()} are listed as a string with the class name
+  instead of class descriptors.
+\end{memberdesc}
+
+\begin{memberdesc}[class descriptor]{methods}
+  A dictionary mapping method names to line numbers.
+\end{memberdesc}
+
+\begin{memberdesc}[class descriptor]{file}
+  Name of the file containing the \code{class} statement defining the class.
+\end{memberdesc}
+
+\begin{memberdesc}[class descriptor]{lineno}
+  The line number of the \code{class} statement within the file named by
+  \member{file}.
+\end{memberdesc}
+
+\subsection{Function Descriptor Objects \label{pyclbr-function-objects}}
+
+The function descriptor objects used as values in the dictionary returned
+by \function{readmodule_ex()} provide the following data members:
+
+
+\begin{memberdesc}[function descriptor]{module}
+  The name of the module defining the function described by the function
+  descriptor.
+\end{memberdesc}
+
+\begin{memberdesc}[function descriptor]{name}
+  The name of the function.
+\end{memberdesc}
+
+\begin{memberdesc}[function descriptor]{file}
+  Name of the file containing the \code{def} statement defining the function.
+\end{memberdesc}
+
+\begin{memberdesc}[function descriptor]{lineno}
+  The line number of the \code{def} statement within the file named by
+  \member{file}.
+\end{memberdesc}
+

Added: vendor/Python/current/Doc/lib/libpycompile.tex
===================================================================
--- vendor/Python/current/Doc/lib/libpycompile.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libpycompile.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,53 @@
+\section{\module{py_compile} ---
+         Compile Python source files}
+
+% Documentation based on module docstrings, by Fred L. Drake, Jr.
+% <fdrake at acm.org>
+
+\declaremodule[pycompile]{standard}{py_compile}
+
+\modulesynopsis{Compile Python source files to byte-code files.}
+
+
+\indexii{file}{byte-code}
+The \module{py_compile} module provides a function to generate a
+byte-code file from a source file, and another function used when the
+module source file is invoked as a script.
+
+Though not often needed, this function can be useful when installing
+modules for shared use, especially if some of the users may not have
+permission to write the byte-code cache files in the directory
+containing the source code.
+
+\begin{excdesc}{PyCompileError}
+Exception raised when an error occurs while attempting to compile the file.
+\end{excdesc}
+
+\begin{funcdesc}{compile}{file\optional{, cfile\optional{, dfile\optional{, doraise}}}}
+  Compile a source file to byte-code and write out the byte-code cache 
+  file.  The source code is loaded from the file name \var{file}.  The 
+  byte-code is written to \var{cfile}, which defaults to \var{file}
+  \code{+} \code{'c'} (\code{'o'} if optimization is enabled in the
+  current interpreter).  If \var{dfile} is specified, it is used as
+  the name of the source file in error messages instead of \var{file}. 
+  If \var{doraise} is true, a \exception{PyCompileError} is raised when
+  an error is encountered while compiling \var{file}. If \var{doraise}
+  is false (the default), an error string is written to \code{sys.stderr},
+  but no exception is raised.
+\end{funcdesc}
+
+\begin{funcdesc}{main}{\optional{args}}
+  Compile several source files.  The files named in \var{args} (or on
+  the command line, if \var{args} is not specified) are compiled and
+  the resulting bytecode is cached in the normal manner.  This
+  function does not search a directory structure to locate source
+  files; it only compiles files named explicitly.
+\end{funcdesc}
+
+When this module is run as a script, the \function{main()} is used to
+compile all the files named on the command line.
+
+\begin{seealso}
+  \seemodule{compileall}{Utilities to compile all Python source files
+                         in a directory tree.}
+\end{seealso}

Added: vendor/Python/current/Doc/lib/libpydoc.tex
===================================================================
--- vendor/Python/current/Doc/lib/libpydoc.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libpydoc.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,67 @@
+\section{\module{pydoc} ---
+         Documentation generator and online help system}
+
+\declaremodule{standard}{pydoc}
+\modulesynopsis{Documentation generator and online help system.}
+\moduleauthor{Ka-Ping Yee}{ping at lfw.org}
+\sectionauthor{Ka-Ping Yee}{ping at lfw.org}
+
+\versionadded{2.1}
+\index{documentation!generation}
+\index{documentation!online}
+\index{help!online}
+
+The \module{pydoc} module automatically generates documentation from
+Python modules.  The documentation can be presented as pages of text
+on the console, served to a Web browser, or saved to HTML files.
+
+The built-in function \function{help()} invokes the online help system
+in the interactive interpreter, which uses \module{pydoc} to generate
+its documentation as text on the console.  The same text documentation
+can also be viewed from outside the Python interpreter by running
+\program{pydoc} as a script at the operating system's command prompt.
+For example, running
+
+\begin{verbatim}
+pydoc sys
+\end{verbatim}
+
+at a shell prompt will display documentation on the \refmodule{sys}
+module, in a style similar to the manual pages shown by the \UNIX{}
+\program{man} command.  The argument to \program{pydoc} can be the name
+of a function, module, or package, or a dotted reference to a class,
+method, or function within a module or module in a package.  If the
+argument to \program{pydoc} looks like a path (that is, it contains the
+path separator for your operating system, such as a slash in \UNIX),
+and refers to an existing Python source file, then documentation is
+produced for that file.
+
+Specifying a \programopt{-w} flag before the argument will cause HTML
+documentation to be written out to a file in the current directory,
+instead of displaying text on the console.
+
+Specifying a \programopt{-k} flag before the argument will search the
+synopsis lines of all available modules for the keyword given as the
+argument, again in a manner similar to the \UNIX{} \program{man}
+command.  The synopsis line of a module is the first line of its
+documentation string.
+
+You can also use \program{pydoc} to start an HTTP server on the local
+machine that will serve documentation to visiting Web browsers.
+\program{pydoc} \programopt{-p 1234} will start a HTTP server on port
+1234, allowing you to browse the documentation at
+\code{http://localhost:1234/} in your preferred Web browser.
+\program{pydoc} \programopt{-g} will start the server and additionally
+bring up a small \refmodule{Tkinter}-based graphical interface to help
+you search for documentation pages.
+
+When \program{pydoc} generates documentation, it uses the current
+environment and path to locate modules.  Thus, invoking
+\program{pydoc} \programopt{spam} documents precisely the version of
+the module you would get if you started the Python interpreter and
+typed \samp{import spam}.
+
+Module docs for core modules are assumed to reside in
+{}\url{http://www.python.org/doc/current/lib/}.  This can be overridden by
+setting the \envvar{PYTHONDOCS} environment variable to a different URL or
+to a local directory containing the Library Reference Manual pages.

Added: vendor/Python/current/Doc/lib/libpyexpat.tex
===================================================================
--- vendor/Python/current/Doc/lib/libpyexpat.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libpyexpat.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,777 @@
+\section{\module{xml.parsers.expat} ---
+         Fast XML parsing using Expat}
+
+% Markup notes:
+%
+% Many of the attributes of the XMLParser objects are callbacks.
+% Since signature information must be presented, these are described
+% using the methoddesc environment.  Since they are attributes which
+% are set by client code, in-text references to these attributes
+% should be marked using the \member macro and should not include the
+% parentheses used when marking functions and methods.
+
+\declaremodule{standard}{xml.parsers.expat}
+\modulesynopsis{An interface to the Expat non-validating XML parser.}
+\moduleauthor{Paul Prescod}{paul at prescod.net}
+
+\versionadded{2.0}
+
+The \module{xml.parsers.expat} module is a Python interface to the
+Expat\index{Expat} non-validating XML parser.
+The module provides a single extension type, \class{xmlparser}, that
+represents the current state of an XML parser.  After an
+\class{xmlparser} object has been created, various attributes of the object 
+can be set to handler functions.  When an XML document is then fed to
+the parser, the handler functions are called for the character data
+and markup in the XML document.
+
+This module uses the \module{pyexpat}\refbimodindex{pyexpat} module to
+provide access to the Expat parser.  Direct use of the
+\module{pyexpat} module is deprecated.
+
+This module provides one exception and one type object:
+
+\begin{excdesc}{ExpatError}
+  The exception raised when Expat reports an error.  See section
+  \ref{expaterror-objects}, ``ExpatError Exceptions,'' for more
+  information on interpreting Expat errors.
+\end{excdesc}
+
+\begin{excdesc}{error}
+  Alias for \exception{ExpatError}.
+\end{excdesc}
+
+\begin{datadesc}{XMLParserType}
+  The type of the return values from the \function{ParserCreate()}
+  function.
+\end{datadesc}
+
+
+The \module{xml.parsers.expat} module contains two functions:
+
+\begin{funcdesc}{ErrorString}{errno}
+Returns an explanatory string for a given error number \var{errno}.
+\end{funcdesc}
+
+\begin{funcdesc}{ParserCreate}{\optional{encoding\optional{,
+                               namespace_separator}}}
+Creates and returns a new \class{xmlparser} object.  
+\var{encoding}, if specified, must be a string naming the encoding 
+used by the XML data.  Expat doesn't support as many encodings as
+Python does, and its repertoire of encodings can't be extended; it
+supports UTF-8, UTF-16, ISO-8859-1 (Latin1), and ASCII.  If
+\var{encoding} is given it will override the implicit or explicit
+encoding of the document.
+
+Expat can optionally do XML namespace processing for you, enabled by
+providing a value for \var{namespace_separator}.  The value must be a
+one-character string; a \exception{ValueError} will be raised if the
+string has an illegal length (\code{None} is considered the same as
+omission).  When namespace processing is enabled, element type names
+and attribute names that belong to a namespace will be expanded.  The
+element name passed to the element handlers
+\member{StartElementHandler} and \member{EndElementHandler}
+will be the concatenation of the namespace URI, the namespace
+separator character, and the local part of the name.  If the namespace
+separator is a zero byte (\code{chr(0)}) then the namespace URI and
+the local part will be concatenated without any separator.
+
+For example, if \var{namespace_separator} is set to a space character
+(\character{ }) and the following document is parsed:
+
+\begin{verbatim}
+<?xml version="1.0"?>
+<root xmlns    = "http://default-namespace.org/"
+      xmlns:py = "http://www.python.org/ns/">
+  <py:elem1 />
+  <elem2 xmlns="" />
+</root>
+\end{verbatim}
+
+\member{StartElementHandler} will receive the following strings
+for each element:
+
+\begin{verbatim}
+http://default-namespace.org/ root
+http://www.python.org/ns/ elem1
+elem2
+\end{verbatim}
+\end{funcdesc}
+
+
+\begin{seealso}
+  \seetitle[http://www.libexpat.org/]{The Expat XML Parser}
+           {Home page of the Expat project.}
+\end{seealso}
+
+
+\subsection{XMLParser Objects \label{xmlparser-objects}}
+
+\class{xmlparser} objects have the following methods:
+
+\begin{methoddesc}[xmlparser]{Parse}{data\optional{, isfinal}}
+Parses the contents of the string \var{data}, calling the appropriate
+handler functions to process the parsed data.  \var{isfinal} must be
+true on the final call to this method.  \var{data} can be the empty
+string at any time.
+\end{methoddesc}
+
+\begin{methoddesc}[xmlparser]{ParseFile}{file}
+Parse XML data reading from the object \var{file}.  \var{file} only
+needs to provide the \method{read(\var{nbytes})} method, returning the
+empty string when there's no more data.
+\end{methoddesc}
+
+\begin{methoddesc}[xmlparser]{SetBase}{base}
+Sets the base to be used for resolving relative URIs in system
+identifiers in declarations.  Resolving relative identifiers is left
+to the application: this value will be passed through as the
+\var{base} argument to the \function{ExternalEntityRefHandler},
+\function{NotationDeclHandler}, and
+\function{UnparsedEntityDeclHandler} functions.
+\end{methoddesc}
+
+\begin{methoddesc}[xmlparser]{GetBase}{}
+Returns a string containing the base set by a previous call to
+\method{SetBase()}, or \code{None} if 
+\method{SetBase()} hasn't been called.
+\end{methoddesc}
+
+\begin{methoddesc}[xmlparser]{GetInputContext}{}
+Returns the input data that generated the current event as a string.
+The data is in the encoding of the entity which contains the text.
+When called while an event handler is not active, the return value is
+\code{None}.
+\versionadded{2.1}
+\end{methoddesc}
+
+\begin{methoddesc}[xmlparser]{ExternalEntityParserCreate}{context\optional{,
+                                                          encoding}}
+Create a ``child'' parser which can be used to parse an external
+parsed entity referred to by content parsed by the parent parser.  The
+\var{context} parameter should be the string passed to the
+\method{ExternalEntityRefHandler()} handler function, described below.
+The child parser is created with the \member{ordered_attributes},
+\member{returns_unicode} and \member{specified_attributes} set to the
+values of this parser.
+\end{methoddesc}
+
+\begin{methoddesc}[xmlparser]{UseForeignDTD}{\optional{flag}}
+Calling this with a true value for \var{flag} (the default) will cause
+Expat to call the \member{ExternalEntityRefHandler} with
+\constant{None} for all arguments to allow an alternate DTD to be
+loaded.  If the document does not contain a document type declaration,
+the \member{ExternalEntityRefHandler} will still be called, but the
+\member{StartDoctypeDeclHandler} and \member{EndDoctypeDeclHandler}
+will not be called.
+
+Passing a false value for \var{flag} will cancel a previous call that
+passed a true value, but otherwise has no effect.
+
+This method can only be called before the \method{Parse()} or
+\method{ParseFile()} methods are called; calling it after either of
+those have been called causes \exception{ExpatError} to be raised with
+the \member{code} attribute set to
+\constant{errors.XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING}.
+
+\versionadded{2.3}
+\end{methoddesc}
+
+
+\class{xmlparser} objects have the following attributes:
+
+\begin{memberdesc}[xmlparser]{buffer_size}
+The size of the buffer used when \member{buffer_text} is true.  This
+value cannot be changed at this time.
+\versionadded{2.3}
+\end{memberdesc}
+
+\begin{memberdesc}[xmlparser]{buffer_text}
+Setting this to true causes the \class{xmlparser} object to buffer
+textual content returned by Expat to avoid multiple calls to the
+\method{CharacterDataHandler()} callback whenever possible.  This can
+improve performance substantially since Expat normally breaks
+character data into chunks at every line ending.  This attribute is
+false by default, and may be changed at any time.
+\versionadded{2.3}
+\end{memberdesc}
+
+\begin{memberdesc}[xmlparser]{buffer_used}
+If \member{buffer_text} is enabled, the number of bytes stored in the
+buffer.  These bytes represent UTF-8 encoded text.  This attribute has
+no meaningful interpretation when \member{buffer_text} is false.
+\versionadded{2.3}
+\end{memberdesc}
+
+\begin{memberdesc}[xmlparser]{ordered_attributes}
+Setting this attribute to a non-zero integer causes the attributes to
+be reported as a list rather than a dictionary.  The attributes are
+presented in the order found in the document text.  For each
+attribute, two list entries are presented: the attribute name and the
+attribute value.  (Older versions of this module also used this
+format.)  By default, this attribute is false; it may be changed at
+any time.
+\versionadded{2.1}
+\end{memberdesc}
+
+\begin{memberdesc}[xmlparser]{returns_unicode} 
+If this attribute is set to a non-zero integer, the handler functions
+will be passed Unicode strings.  If \member{returns_unicode} is
+\constant{False}, 8-bit strings containing UTF-8 encoded data will be
+passed to the handlers.  This is \constant{True} by default when
+Python is built with Unicode support.
+\versionchanged[Can be changed at any time to affect the result
+  type]{1.6}
+\end{memberdesc}
+
+\begin{memberdesc}[xmlparser]{specified_attributes}
+If set to a non-zero integer, the parser will report only those
+attributes which were specified in the document instance and not those
+which were derived from attribute declarations.  Applications which
+set this need to be especially careful to use what additional
+information is available from the declarations as needed to comply
+with the standards for the behavior of XML processors.  By default,
+this attribute is false; it may be changed at any time.
+\versionadded{2.1}
+\end{memberdesc}
+
+The following attributes contain values relating to the most recent
+error encountered by an \class{xmlparser} object, and will only have
+correct values once a call to \method{Parse()} or \method{ParseFile()}
+has raised a \exception{xml.parsers.expat.ExpatError} exception.
+
+\begin{memberdesc}[xmlparser]{ErrorByteIndex} 
+Byte index at which an error occurred.
+\end{memberdesc} 
+
+\begin{memberdesc}[xmlparser]{ErrorCode} 
+Numeric code specifying the problem.  This value can be passed to the
+\function{ErrorString()} function, or compared to one of the constants
+defined in the \code{errors} object.
+\end{memberdesc}
+
+\begin{memberdesc}[xmlparser]{ErrorColumnNumber} 
+Column number at which an error occurred.
+\end{memberdesc}
+
+\begin{memberdesc}[xmlparser]{ErrorLineNumber}
+Line number at which an error occurred.
+\end{memberdesc}
+
+The following attributes contain values relating to the current parse
+location in an \class{xmlparser} object.  During a callback reporting
+a parse event they indicate the location of the first of the sequence
+of characters that generated the event.  When called outside of a
+callback, the position indicated will be just past the last parse
+event (regardless of whether there was an associated callback).
+\versionadded{2.4}
+
+\begin{memberdesc}[xmlparser]{CurrentByteIndex} 
+Current byte index in the parser input.
+\end{memberdesc} 
+
+\begin{memberdesc}[xmlparser]{CurrentColumnNumber} 
+Current column number in the parser input.
+\end{memberdesc}
+
+\begin{memberdesc}[xmlparser]{CurrentLineNumber}
+Current line number in the parser input.
+\end{memberdesc}
+
+Here is the list of handlers that can be set.  To set a handler on an
+\class{xmlparser} object \var{o}, use
+\code{\var{o}.\var{handlername} = \var{func}}.  \var{handlername} must
+be taken from the following list, and \var{func} must be a callable
+object accepting the correct number of arguments.  The arguments are
+all strings, unless otherwise stated.
+
+\begin{methoddesc}[xmlparser]{XmlDeclHandler}{version, encoding, standalone}
+Called when the XML declaration is parsed.  The XML declaration is the
+(optional) declaration of the applicable version of the XML
+recommendation, the encoding of the document text, and an optional
+``standalone'' declaration.  \var{version} and \var{encoding} will be
+strings of the type dictated by the \member{returns_unicode}
+attribute, and \var{standalone} will be \code{1} if the document is
+declared standalone, \code{0} if it is declared not to be standalone,
+or \code{-1} if the standalone clause was omitted.
+This is only available with Expat version 1.95.0 or newer.
+\versionadded{2.1}
+\end{methoddesc}
+
+\begin{methoddesc}[xmlparser]{StartDoctypeDeclHandler}{doctypeName,
+                                                       systemId, publicId,
+                                                       has_internal_subset}
+Called when Expat begins parsing the document type declaration
+(\code{<!DOCTYPE \ldots}).  The \var{doctypeName} is provided exactly
+as presented.  The \var{systemId} and \var{publicId} parameters give
+the system and public identifiers if specified, or \code{None} if
+omitted.  \var{has_internal_subset} will be true if the document
+contains and internal document declaration subset.
+This requires Expat version 1.2 or newer.
+\end{methoddesc}
+
+\begin{methoddesc}[xmlparser]{EndDoctypeDeclHandler}{}
+Called when Expat is done parsing the document type declaration.
+This requires Expat version 1.2 or newer.
+\end{methoddesc}
+
+\begin{methoddesc}[xmlparser]{ElementDeclHandler}{name, model}
+Called once for each element type declaration.  \var{name} is the name
+of the element type, and \var{model} is a representation of the
+content model.
+\end{methoddesc}
+
+\begin{methoddesc}[xmlparser]{AttlistDeclHandler}{elname, attname,
+                                                  type, default, required}
+Called for each declared attribute for an element type.  If an
+attribute list declaration declares three attributes, this handler is
+called three times, once for each attribute.  \var{elname} is the name
+of the element to which the declaration applies and \var{attname} is
+the name of the attribute declared.  The attribute type is a string
+passed as \var{type}; the possible values are \code{'CDATA'},
+\code{'ID'}, \code{'IDREF'}, ...
+\var{default} gives the default value for the attribute used when the
+attribute is not specified by the document instance, or \code{None} if
+there is no default value (\code{\#IMPLIED} values).  If the attribute
+is required to be given in the document instance, \var{required} will
+be true.
+This requires Expat version 1.95.0 or newer.
+\end{methoddesc}
+
+\begin{methoddesc}[xmlparser]{StartElementHandler}{name, attributes}
+Called for the start of every element.  \var{name} is a string
+containing the element name, and \var{attributes} is a dictionary
+mapping attribute names to their values.
+\end{methoddesc}
+
+\begin{methoddesc}[xmlparser]{EndElementHandler}{name}
+Called for the end of every element.
+\end{methoddesc}
+
+\begin{methoddesc}[xmlparser]{ProcessingInstructionHandler}{target, data}
+Called for every processing instruction.
+\end{methoddesc}
+
+\begin{methoddesc}[xmlparser]{CharacterDataHandler}{data}
+Called for character data.  This will be called for normal character
+data, CDATA marked content, and ignorable whitespace.  Applications
+which must distinguish these cases can use the
+\member{StartCdataSectionHandler}, \member{EndCdataSectionHandler},
+and \member{ElementDeclHandler} callbacks to collect the required
+information.
+\end{methoddesc}
+
+\begin{methoddesc}[xmlparser]{UnparsedEntityDeclHandler}{entityName, base,
+                                                         systemId, publicId,
+                                                         notationName}
+Called for unparsed (NDATA) entity declarations.  This is only present
+for version 1.2 of the Expat library; for more recent versions, use
+\member{EntityDeclHandler} instead.  (The underlying function in the
+Expat library has been declared obsolete.)
+\end{methoddesc}
+
+\begin{methoddesc}[xmlparser]{EntityDeclHandler}{entityName,
+                                                 is_parameter_entity, value,
+                                                 base, systemId,
+                                                 publicId,
+                                                 notationName}
+Called for all entity declarations.  For parameter and internal
+entities, \var{value} will be a string giving the declared contents
+of the entity; this will be \code{None} for external entities.  The
+\var{notationName} parameter will be \code{None} for parsed entities,
+and the name of the notation for unparsed entities.
+\var{is_parameter_entity} will be true if the entity is a parameter
+entity or false for general entities (most applications only need to
+be concerned with general entities).
+This is only available starting with version 1.95.0 of the Expat
+library.
+\versionadded{2.1}
+\end{methoddesc}
+
+\begin{methoddesc}[xmlparser]{NotationDeclHandler}{notationName, base,
+                                                   systemId, publicId}
+Called for notation declarations.  \var{notationName}, \var{base}, and
+\var{systemId}, and \var{publicId} are strings if given.  If the
+public identifier is omitted, \var{publicId} will be \code{None}.
+\end{methoddesc}
+
+\begin{methoddesc}[xmlparser]{StartNamespaceDeclHandler}{prefix, uri}
+Called when an element contains a namespace declaration.  Namespace
+declarations are processed before the \member{StartElementHandler} is
+called for the element on which declarations are placed.
+\end{methoddesc}
+
+\begin{methoddesc}[xmlparser]{EndNamespaceDeclHandler}{prefix}
+Called when the closing tag is reached for an element 
+that contained a namespace declaration.  This is called once for each
+namespace declaration on the element in the reverse of the order for
+which the \member{StartNamespaceDeclHandler} was called to indicate
+the start of each namespace declaration's scope.  Calls to this
+handler are made after the corresponding \member{EndElementHandler}
+for the end of the element.
+\end{methoddesc}
+
+\begin{methoddesc}[xmlparser]{CommentHandler}{data}
+Called for comments.  \var{data} is the text of the comment, excluding
+the leading `\code{<!-}\code{-}' and trailing `\code{-}\code{->}'.
+\end{methoddesc}
+
+\begin{methoddesc}[xmlparser]{StartCdataSectionHandler}{}
+Called at the start of a CDATA section.  This and
+\member{EndCdataSectionHandler} are needed to be able to identify
+the syntactical start and end for CDATA sections.
+\end{methoddesc}
+
+\begin{methoddesc}[xmlparser]{EndCdataSectionHandler}{}
+Called at the end of a CDATA section.
+\end{methoddesc}
+
+\begin{methoddesc}[xmlparser]{DefaultHandler}{data}
+Called for any characters in the XML document for
+which no applicable handler has been specified.  This means
+characters that are part of a construct which could be reported, but
+for which no handler has been supplied. 
+\end{methoddesc}
+
+\begin{methoddesc}[xmlparser]{DefaultHandlerExpand}{data}
+This is the same as the \function{DefaultHandler}, 
+but doesn't inhibit expansion of internal entities.
+The entity reference will not be passed to the default handler.
+\end{methoddesc}
+
+\begin{methoddesc}[xmlparser]{NotStandaloneHandler}{} Called if the
+XML document hasn't been declared as being a standalone document.
+This happens when there is an external subset or a reference to a
+parameter entity, but the XML declaration does not set standalone to
+\code{yes} in an XML declaration.  If this handler returns \code{0},
+then the parser will throw an \constant{XML_ERROR_NOT_STANDALONE}
+error.  If this handler is not set, no exception is raised by the
+parser for this condition.
+\end{methoddesc}
+
+\begin{methoddesc}[xmlparser]{ExternalEntityRefHandler}{context, base,
+                                                        systemId, publicId}
+Called for references to external entities.  \var{base} is the current
+base, as set by a previous call to \method{SetBase()}.  The public and
+system identifiers, \var{systemId} and \var{publicId}, are strings if
+given; if the public identifier is not given, \var{publicId} will be
+\code{None}.  The \var{context} value is opaque and should only be
+used as described below.
+
+For external entities to be parsed, this handler must be implemented.
+It is responsible for creating the sub-parser using
+\code{ExternalEntityParserCreate(\var{context})}, initializing it with
+the appropriate callbacks, and parsing the entity.  This handler
+should return an integer; if it returns \code{0}, the parser will
+throw an \constant{XML_ERROR_EXTERNAL_ENTITY_HANDLING} error,
+otherwise parsing will continue.
+
+If this handler is not provided, external entities are reported by the
+\member{DefaultHandler} callback, if provided.
+\end{methoddesc}
+
+
+\subsection{ExpatError Exceptions \label{expaterror-objects}}
+\sectionauthor{Fred L. Drake, Jr.}{fdrake at acm.org}
+
+\exception{ExpatError} exceptions have a number of interesting
+attributes:
+
+\begin{memberdesc}[ExpatError]{code}
+  Expat's internal error number for the specific error.  This will
+  match one of the constants defined in the \code{errors} object from
+  this module.
+  \versionadded{2.1}
+\end{memberdesc}
+
+\begin{memberdesc}[ExpatError]{lineno}
+  Line number on which the error was detected.  The first line is
+  numbered \code{1}.
+  \versionadded{2.1}
+\end{memberdesc}
+
+\begin{memberdesc}[ExpatError]{offset}
+  Character offset into the line where the error occurred.  The first
+  column is numbered \code{0}.
+  \versionadded{2.1}
+\end{memberdesc}
+
+
+\subsection{Example \label{expat-example}}
+
+The following program defines three handlers that just print out their
+arguments.
+
+\begin{verbatim}
+import xml.parsers.expat
+
+# 3 handler functions
+def start_element(name, attrs):
+    print 'Start element:', name, attrs
+def end_element(name):
+    print 'End element:', name
+def char_data(data):
+    print 'Character data:', repr(data)
+
+p = xml.parsers.expat.ParserCreate()
+
+p.StartElementHandler = start_element
+p.EndElementHandler = end_element
+p.CharacterDataHandler = char_data
+
+p.Parse("""<?xml version="1.0"?>
+<parent id="top"><child1 name="paul">Text goes here</child1>
+<child2 name="fred">More text</child2>
+</parent>""", 1)
+\end{verbatim}
+
+The output from this program is:
+
+\begin{verbatim}
+Start element: parent {'id': 'top'}
+Start element: child1 {'name': 'paul'}
+Character data: 'Text goes here'
+End element: child1
+Character data: '\n'
+Start element: child2 {'name': 'fred'}
+Character data: 'More text'
+End element: child2
+Character data: '\n'
+End element: parent
+\end{verbatim}
+
+
+\subsection{Content Model Descriptions \label{expat-content-models}}
+\sectionauthor{Fred L. Drake, Jr.}{fdrake at acm.org}
+
+Content modules are described using nested tuples.  Each tuple
+contains four values: the type, the quantifier, the name, and a tuple
+of children.  Children are simply additional content module
+descriptions.
+
+The values of the first two fields are constants defined in the
+\code{model} object of the \module{xml.parsers.expat} module.  These
+constants can be collected in two groups: the model type group and the
+quantifier group.
+
+The constants in the model type group are:
+
+\begin{datadescni}{XML_CTYPE_ANY}
+The element named by the model name was declared to have a content
+model of \code{ANY}.
+\end{datadescni}
+
+\begin{datadescni}{XML_CTYPE_CHOICE}
+The named element allows a choice from a number of options; this is
+used for content models such as \code{(A | B | C)}.
+\end{datadescni}
+
+\begin{datadescni}{XML_CTYPE_EMPTY}
+Elements which are declared to be \code{EMPTY} have this model type.
+\end{datadescni}
+
+\begin{datadescni}{XML_CTYPE_MIXED}
+\end{datadescni}
+
+\begin{datadescni}{XML_CTYPE_NAME}
+\end{datadescni}
+
+\begin{datadescni}{XML_CTYPE_SEQ}
+Models which represent a series of models which follow one after the
+other are indicated with this model type.  This is used for models
+such as \code{(A, B, C)}.
+\end{datadescni}
+
+
+The constants in the quantifier group are:
+
+\begin{datadescni}{XML_CQUANT_NONE}
+No modifier is given, so it can appear exactly once, as for \code{A}.
+\end{datadescni}
+
+\begin{datadescni}{XML_CQUANT_OPT}
+The model is optional: it can appear once or not at all, as for
+\code{A?}.
+\end{datadescni}
+
+\begin{datadescni}{XML_CQUANT_PLUS}
+The model must occur one or more times (like \code{A+}).
+\end{datadescni}
+
+\begin{datadescni}{XML_CQUANT_REP}
+The model must occur zero or more times, as for \code{A*}.
+\end{datadescni}
+
+
+\subsection{Expat error constants \label{expat-errors}}
+
+The following constants are provided in the \code{errors} object of
+the \refmodule{xml.parsers.expat} module.  These constants are useful
+in interpreting some of the attributes of the \exception{ExpatError}
+exception objects raised when an error has occurred.
+
+The \code{errors} object has the following attributes:
+
+\begin{datadescni}{XML_ERROR_ASYNC_ENTITY}
+\end{datadescni}
+
+\begin{datadescni}{XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF}
+An entity reference in an attribute value referred to an external
+entity instead of an internal entity.
+\end{datadescni}
+
+\begin{datadescni}{XML_ERROR_BAD_CHAR_REF}
+A character reference referred to a character which is illegal in XML
+(for example, character \code{0}, or `\code{\&\#0;}').
+\end{datadescni}
+
+\begin{datadescni}{XML_ERROR_BINARY_ENTITY_REF}
+An entity reference referred to an entity which was declared with a
+notation, so cannot be parsed.
+\end{datadescni}
+
+\begin{datadescni}{XML_ERROR_DUPLICATE_ATTRIBUTE}
+An attribute was used more than once in a start tag.
+\end{datadescni}
+
+\begin{datadescni}{XML_ERROR_INCORRECT_ENCODING}
+\end{datadescni}
+
+\begin{datadescni}{XML_ERROR_INVALID_TOKEN}
+Raised when an input byte could not properly be assigned to a
+character; for example, a NUL byte (value \code{0}) in a UTF-8 input
+stream.
+\end{datadescni}
+
+\begin{datadescni}{XML_ERROR_JUNK_AFTER_DOC_ELEMENT}
+Something other than whitespace occurred after the document element.
+\end{datadescni}
+
+\begin{datadescni}{XML_ERROR_MISPLACED_XML_PI}
+An XML declaration was found somewhere other than the start of the
+input data.
+\end{datadescni}
+
+\begin{datadescni}{XML_ERROR_NO_ELEMENTS}
+The document contains no elements (XML requires all documents to
+contain exactly one top-level element)..
+\end{datadescni}
+
+\begin{datadescni}{XML_ERROR_NO_MEMORY}
+Expat was not able to allocate memory internally.
+\end{datadescni}
+
+\begin{datadescni}{XML_ERROR_PARAM_ENTITY_REF}
+A parameter entity reference was found where it was not allowed.
+\end{datadescni}
+
+\begin{datadescni}{XML_ERROR_PARTIAL_CHAR}
+An incomplete character was found in the input.
+\end{datadescni}
+
+\begin{datadescni}{XML_ERROR_RECURSIVE_ENTITY_REF}
+An entity reference contained another reference to the same entity;
+possibly via a different name, and possibly indirectly.
+\end{datadescni}
+
+\begin{datadescni}{XML_ERROR_SYNTAX}
+Some unspecified syntax error was encountered.
+\end{datadescni}
+
+\begin{datadescni}{XML_ERROR_TAG_MISMATCH}
+An end tag did not match the innermost open start tag.
+\end{datadescni}
+
+\begin{datadescni}{XML_ERROR_UNCLOSED_TOKEN}
+Some token (such as a start tag) was not closed before the end of the
+stream or the next token was encountered.
+\end{datadescni}
+
+\begin{datadescni}{XML_ERROR_UNDEFINED_ENTITY}
+A reference was made to a entity which was not defined.
+\end{datadescni}
+
+\begin{datadescni}{XML_ERROR_UNKNOWN_ENCODING}
+The document encoding is not supported by Expat.
+\end{datadescni}
+
+\begin{datadescni}{XML_ERROR_UNCLOSED_CDATA_SECTION}
+A CDATA marked section was not closed.
+\end{datadescni}
+
+\begin{datadescni}{XML_ERROR_EXTERNAL_ENTITY_HANDLING}
+\end{datadescni}
+
+\begin{datadescni}{XML_ERROR_NOT_STANDALONE}
+The parser determined that the document was not ``standalone'' though
+it declared itself to be in the XML declaration, and the
+\member{NotStandaloneHandler} was set and returned \code{0}.
+\end{datadescni}
+
+\begin{datadescni}{XML_ERROR_UNEXPECTED_STATE}
+\end{datadescni}
+
+\begin{datadescni}{XML_ERROR_ENTITY_DECLARED_IN_PE}
+\end{datadescni}
+
+\begin{datadescni}{XML_ERROR_FEATURE_REQUIRES_XML_DTD}
+An operation was requested that requires DTD support to be compiled
+in, but Expat was configured without DTD support.  This should never
+be reported by a standard build of the \module{xml.parsers.expat}
+module.
+\end{datadescni}
+
+\begin{datadescni}{XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING}
+A behavioral change was requested after parsing started that can only
+be changed before parsing has started.  This is (currently) only
+raised by \method{UseForeignDTD()}.
+\end{datadescni}
+
+\begin{datadescni}{XML_ERROR_UNBOUND_PREFIX}
+An undeclared prefix was found when namespace processing was enabled.
+\end{datadescni}
+
+\begin{datadescni}{XML_ERROR_UNDECLARING_PREFIX}
+The document attempted to remove the namespace declaration associated
+with a prefix.
+\end{datadescni}
+
+\begin{datadescni}{XML_ERROR_INCOMPLETE_PE}
+A parameter entity contained incomplete markup.
+\end{datadescni}
+
+\begin{datadescni}{XML_ERROR_XML_DECL}
+The document contained no document element at all.
+\end{datadescni}
+
+\begin{datadescni}{XML_ERROR_TEXT_DECL}
+There was an error parsing a text declaration in an external entity.
+\end{datadescni}
+
+\begin{datadescni}{XML_ERROR_PUBLICID}
+Characters were found in the public id that are not allowed.
+\end{datadescni}
+
+\begin{datadescni}{XML_ERROR_SUSPENDED}
+The requested operation was made on a suspended parser, but isn't
+allowed.  This includes attempts to provide additional input or to
+stop the parser.
+\end{datadescni}
+
+\begin{datadescni}{XML_ERROR_NOT_SUSPENDED}
+An attempt to resume the parser was made when the parser had not been
+suspended.
+\end{datadescni}
+
+\begin{datadescni}{XML_ERROR_ABORTED}
+This should not be reported to Python applications.
+\end{datadescni}
+
+\begin{datadescni}{XML_ERROR_FINISHED}
+The requested operation was made on a parser which was finished
+parsing input, but isn't allowed.  This includes attempts to provide
+additional input or to stop the parser.
+\end{datadescni}
+
+\begin{datadescni}{XML_ERROR_SUSPEND_PE}
+\end{datadescni}

Added: vendor/Python/current/Doc/lib/libpython.tex
===================================================================
--- vendor/Python/current/Doc/lib/libpython.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libpython.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,8 @@
+\chapter{Python Runtime Services
+         \label{python}}
+
+The modules described in this chapter provide a wide range of services
+related to the Python interpreter and its interaction with its
+environment.  Here's an overview:
+
+\localmoduletable

Added: vendor/Python/current/Doc/lib/libqueue.tex
===================================================================
--- vendor/Python/current/Doc/lib/libqueue.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libqueue.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,145 @@
+
+\section{\module{Queue} ---
+         A synchronized queue class}
+
+\declaremodule{standard}{Queue}
+\modulesynopsis{A synchronized queue class.}
+
+
+The \module{Queue} module implements a multi-producer, multi-consumer
+FIFO queue.  It is especially useful in threads programming when
+information must be exchanged safely between multiple threads.  The
+\class{Queue} class in this module implements all the required locking
+semantics.  It depends on the availability of thread support in
+Python.
+
+The \module{Queue} module defines the following class and exception:
+
+
+\begin{classdesc}{Queue}{maxsize}
+Constructor for the class.  \var{maxsize} is an integer that sets the
+upperbound limit on the number of items that can be placed in the
+queue.  Insertion will block once this size has been reached, until
+queue items are consumed.  If \var{maxsize} is less than or equal to
+zero, the queue size is infinite.
+\end{classdesc}
+
+\begin{excdesc}{Empty}
+Exception raised when non-blocking \method{get()} (or
+\method{get_nowait()}) is called on a \class{Queue} object which is
+empty.
+\end{excdesc}
+
+\begin{excdesc}{Full}
+Exception raised when non-blocking \method{put()} (or
+\method{put_nowait()}) is called on a \class{Queue} object which is
+full.
+\end{excdesc}
+
+\subsection{Queue Objects}
+\label{QueueObjects}
+
+Class \class{Queue} implements queue objects and has the methods
+described below.  This class can be derived from in order to implement
+other queue organizations (e.g. stack) but the inheritable interface
+is not described here.  See the source code for details.  The public
+methods are:
+
+\begin{methoddesc}{qsize}{}
+Return the approximate size of the queue.  Because of multithreading
+semantics, this number is not reliable.
+\end{methoddesc}
+
+\begin{methoddesc}{empty}{}
+Return \code{True} if the queue is empty, \code{False} otherwise.
+Because of multithreading semantics, this is not reliable.
+\end{methoddesc}
+
+\begin{methoddesc}{full}{}
+Return \code{True} if the queue is full, \code{False} otherwise.
+Because of multithreading semantics, this is not reliable.
+\end{methoddesc}
+
+\begin{methoddesc}{put}{item\optional{, block\optional{, timeout}}}
+Put \var{item} into the queue. If optional args \var{block} is true
+and \var{timeout} is None (the default), block if necessary until a
+free slot is available. If \var{timeout} is a positive number, it
+blocks at most \var{timeout} seconds and raises the \exception{Full}
+exception if no free slot was available within that time.
+Otherwise (\var{block} is false), put an item on the queue if a free
+slot is immediately available, else raise the \exception{Full}
+exception (\var{timeout} is ignored in that case).
+
+\versionadded[the timeout parameter]{2.3}
+
+\end{methoddesc}
+
+\begin{methoddesc}{put_nowait}{item}
+Equivalent to \code{put(\var{item}, False)}.
+\end{methoddesc}
+
+\begin{methoddesc}{get}{\optional{block\optional{, timeout}}}
+Remove and return an item from the queue. If optional args
+\var{block} is true and \var{timeout} is None (the default),
+block if necessary until an item is available. If \var{timeout} is
+a positive number, it blocks at most \var{timeout} seconds and raises
+the \exception{Empty} exception if no item was available within that
+time. Otherwise (\var{block} is false), return an item if one is
+immediately available, else raise the \exception{Empty} exception
+(\var{timeout} is ignored in that case).
+
+\versionadded[the timeout parameter]{2.3}
+
+\end{methoddesc}
+
+\begin{methoddesc}{get_nowait}{}
+Equivalent to \code{get(False)}.
+\end{methoddesc}
+
+Two methods are offered to support tracking whether enqueued tasks have
+been fully processed by daemon consumer threads.
+
+\begin{methoddesc}{task_done}{}
+Indicate that a formerly enqueued task is complete.  Used by queue consumer
+threads.  For each \method{get()} used to fetch a task, a subsequent call to
+\method{task_done()} tells the queue that the processing on the task is complete.
+
+If a \method{join()} is currently blocking, it will resume when all items
+have been processed (meaning that a \method{task_done()} call was received
+for every item that had been \method{put()} into the queue).
+
+Raises a \exception{ValueError} if called more times than there were items
+placed in the queue.
+\versionadded{2.5}
+\end{methoddesc}
+
+\begin{methoddesc}{join}{}
+Blocks until all items in the queue have been gotten and processed.
+
+The count of unfinished tasks goes up whenever an item is added to the
+queue. The count goes down whenever a consumer thread calls \method{task_done()}
+to indicate that the item was retrieved and all work on it is complete.
+When the count of unfinished tasks drops to zero, join() unblocks.
+\versionadded{2.5}
+\end{methoddesc}
+
+Example of how to wait for enqueued tasks to be completed:
+
+\begin{verbatim}
+    def worker(): 
+        while True: 
+            item = q.get() 
+            do_work(item) 
+            q.task_done() 
+
+    q = Queue() 
+    for i in range(num_worker_threads): 
+         t = Thread(target=worker)
+         t.setDaemon(True)
+         t.start() 
+
+    for item in source():
+        q.put(item) 
+
+    q.join()       # block until all tasks are done
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/libquopri.tex
===================================================================
--- vendor/Python/current/Doc/lib/libquopri.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libquopri.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,61 @@
+\section{\module{quopri} ---
+         Encode and decode MIME quoted-printable data}
+
+\declaremodule{standard}{quopri}
+\modulesynopsis{Encode and decode files using the MIME
+                quoted-printable encoding.}
+
+
+This module performs quoted-printable transport encoding and decoding,
+as defined in \rfc{1521}: ``MIME (Multipurpose Internet Mail
+Extensions) Part One: Mechanisms for Specifying and Describing the
+Format of Internet Message Bodies''.  The quoted-printable encoding is
+designed for data where there are relatively few nonprintable
+characters; the base64 encoding scheme available via the
+\refmodule{base64} module is more compact if there are many such
+characters, as when sending a graphics file.
+\indexii{quoted-printable}{encoding}
+\index{MIME!quoted-printable encoding}
+
+
+\begin{funcdesc}{decode}{input, output\optional{,header}}
+Decode the contents of the \var{input} file and write the resulting
+decoded binary data to the \var{output} file.
+\var{input} and \var{output} must either be file objects or objects that
+mimic the file object interface. \var{input} will be read until
+\code{\var{input}.readline()} returns an empty string.
+If the optional argument \var{header} is present and true, underscore
+will be decoded as space. This is used to decode
+``Q''-encoded headers as described in \rfc{1522}: ``MIME (Multipurpose Internet Mail Extensions)
+Part Two: Message Header Extensions for Non-ASCII Text''.
+\end{funcdesc}
+
+\begin{funcdesc}{encode}{input, output, quotetabs}
+Encode the contents of the \var{input} file and write the resulting
+quoted-printable data to the \var{output} file.
+\var{input} and \var{output} must either be file objects or objects that
+mimic the file object interface. \var{input} will be read until
+\code{\var{input}.readline()} returns an empty string.
+\var{quotetabs} is a flag which controls whether to encode embedded
+spaces and tabs; when true it encodes such embedded whitespace, and
+when false it leaves them unencoded.  Note that spaces and tabs
+appearing at the end of lines are always encoded, as per \rfc{1521}.
+\end{funcdesc}
+
+\begin{funcdesc}{decodestring}{s\optional{,header}}
+Like \function{decode()}, except that it accepts a source string and
+returns the corresponding decoded string.
+\end{funcdesc}
+
+\begin{funcdesc}{encodestring}{s\optional{, quotetabs}}
+Like \function{encode()}, except that it accepts a source string and
+returns the corresponding encoded string.  \var{quotetabs} is optional
+(defaulting to 0), and is passed straight through to
+\function{encode()}.
+\end{funcdesc}
+
+
+\begin{seealso}
+  \seemodule{mimify}{General utilities for processing of MIME messages.}
+  \seemodule{base64}{Encode and decode MIME base64 data}
+\end{seealso}

Added: vendor/Python/current/Doc/lib/librandom.tex
===================================================================
--- vendor/Python/current/Doc/lib/librandom.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/librandom.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,309 @@
+\section{\module{random} ---
+         Generate pseudo-random numbers}
+
+\declaremodule{standard}{random}
+\modulesynopsis{Generate pseudo-random numbers with various common
+                distributions.}
+
+
+This module implements pseudo-random number generators for various
+distributions.
+
+For integers, uniform selection from a range.
+For sequences, uniform selection of a random element, a function to
+generate a random permutation of a list in-place, and a function for
+random sampling without replacement.
+
+On the real line, there are functions to compute uniform, normal (Gaussian),
+lognormal, negative exponential, gamma, and beta distributions.
+For generating distributions of angles, the von Mises distribution
+is available.
+
+Almost all module functions depend on the basic function
+\function{random()}, which generates a random float uniformly in
+the semi-open range [0.0, 1.0).  Python uses the Mersenne Twister as
+the core generator.  It produces 53-bit precision floats and has a
+period of 2**19937-1.  The underlying implementation in C
+is both fast and threadsafe.  The Mersenne Twister is one of the most
+extensively tested random number generators in existence.  However, being
+completely deterministic, it is not suitable for all purposes, and is
+completely unsuitable for cryptographic purposes.
+
+The functions supplied by this module are actually bound methods of a
+hidden instance of the \class{random.Random} class.  You can
+instantiate your own instances of \class{Random} to get generators
+that don't share state.  This is especially useful for multi-threaded
+programs, creating a different instance of \class{Random} for each
+thread, and using the \method{jumpahead()} method to make it likely that the
+generated sequences seen by each thread don't overlap.
+
+Class \class{Random} can also be subclassed if you want to use a
+different basic generator of your own devising: in that case, override
+the \method{random()}, \method{seed()}, \method{getstate()},
+\method{setstate()} and \method{jumpahead()} methods.
+Optionally, a new generator can supply a \method{getrandombits()}
+method --- this allows \method{randrange()} to produce selections
+over an arbitrarily large range.
+\versionadded[the \method{getrandombits()} method]{2.4}
+
+As an example of subclassing, the \module{random} module provides
+the \class{WichmannHill} class that implements an alternative generator
+in pure Python.  The class provides a backward compatible way to
+reproduce results from earlier versions of Python, which used the
+Wichmann-Hill algorithm as the core generator.  Note that this Wichmann-Hill
+generator can no longer be recommended:  its period is too short by
+contemporary standards, and the sequence generated is known to fail some
+stringent randomness tests.  See the references below for a recent
+variant that repairs these flaws.
+\versionchanged[Substituted MersenneTwister for Wichmann-Hill]{2.3}
+
+
+Bookkeeping functions:
+
+\begin{funcdesc}{seed}{\optional{x}}
+  Initialize the basic random number generator.
+  Optional argument \var{x} can be any hashable object.
+  If \var{x} is omitted or \code{None}, current system time is used;
+  current system time is also used to initialize the generator when the
+  module is first imported.  If randomness sources are provided by the
+  operating system, they are used instead of the system time (see the
+  \function{os.urandom()}
+  function for details on availability).  \versionchanged[formerly,
+  operating system resources were not used]{2.4}
+  If \var{x} is not \code{None} or an int or long,
+  \code{hash(\var{x})} is used instead.
+  If \var{x} is an int or long, \var{x} is used directly.
+\end{funcdesc}
+
+\begin{funcdesc}{getstate}{}
+  Return an object capturing the current internal state of the
+  generator.  This object can be passed to \function{setstate()} to
+  restore the state.
+  \versionadded{2.1}
+\end{funcdesc}
+
+\begin{funcdesc}{setstate}{state}
+  \var{state} should have been obtained from a previous call to
+  \function{getstate()}, and \function{setstate()} restores the
+  internal state of the generator to what it was at the time
+  \function{setstate()} was called.
+  \versionadded{2.1}
+\end{funcdesc}
+
+\begin{funcdesc}{jumpahead}{n}
+  Change the internal state to one different from and likely far away from
+  the current state.  \var{n} is a non-negative integer which is used to
+  scramble the current state vector.  This is most useful in multi-threaded
+  programs, in conjuction with multiple instances of the \class{Random}
+  class: \method{setstate()} or \method{seed()} can be used to force all
+  instances into the same internal state, and then \method{jumpahead()}
+  can be used to force the instances' states far apart.
+  \versionadded{2.1}
+  \versionchanged[Instead of jumping to a specific state, \var{n} steps
+  ahead, \method{jumpahead(\var{n})} jumps to another state likely to be
+  separated by many steps]{2.3}
+ \end{funcdesc}
+
+\begin{funcdesc}{getrandbits}{k}
+  Returns a python \class{long} int with \var{k} random bits.
+  This method is supplied with the MersenneTwister generator and some
+  other generators may also provide it as an optional part of the API.
+  When available, \method{getrandbits()} enables \method{randrange()}
+  to handle arbitrarily large ranges.
+  \versionadded{2.4}
+\end{funcdesc}
+
+Functions for integers:
+
+\begin{funcdesc}{randrange}{\optional{start,} stop\optional{, step}}
+  Return a randomly selected element from \code{range(\var{start},
+  \var{stop}, \var{step})}.  This is equivalent to
+  \code{choice(range(\var{start}, \var{stop}, \var{step}))},
+  but doesn't actually build a range object.
+  \versionadded{1.5.2}
+\end{funcdesc}
+
+\begin{funcdesc}{randint}{a, b}
+  Return a random integer \var{N} such that
+  \code{\var{a} <= \var{N} <= \var{b}}.
+\end{funcdesc}
+
+
+Functions for sequences:
+
+\begin{funcdesc}{choice}{seq}
+  Return a random element from the non-empty sequence \var{seq}.
+  If \var{seq} is empty, raises \exception{IndexError}.
+\end{funcdesc}
+
+\begin{funcdesc}{shuffle}{x\optional{, random}}
+  Shuffle the sequence \var{x} in place.
+  The optional argument \var{random} is a 0-argument function
+  returning a random float in [0.0, 1.0); by default, this is the
+  function \function{random()}.
+
+  Note that for even rather small \code{len(\var{x})}, the total
+  number of permutations of \var{x} is larger than the period of most
+  random number generators; this implies that most permutations of a
+  long sequence can never be generated.
+\end{funcdesc}
+
+\begin{funcdesc}{sample}{population, k}
+  Return a \var{k} length list of unique elements chosen from the
+  population sequence.  Used for random sampling without replacement.
+  \versionadded{2.3}
+
+  Returns a new list containing elements from the population while
+  leaving the original population unchanged.  The resulting list is
+  in selection order so that all sub-slices will also be valid random
+  samples.  This allows raffle winners (the sample) to be partitioned
+  into grand prize and second place winners (the subslices).
+
+  Members of the population need not be hashable or unique.  If the
+  population contains repeats, then each occurrence is a possible
+  selection in the sample.
+
+  To choose a sample from a range of integers, use an \function{xrange()}
+  object as an argument.  This is especially fast and space efficient for
+  sampling from a large population:  \code{sample(xrange(10000000), 60)}.
+\end{funcdesc}
+
+
+The following functions generate specific real-valued distributions.
+Function parameters are named after the corresponding variables in the
+distribution's equation, as used in common mathematical practice; most of
+these equations can be found in any statistics text.
+
+\begin{funcdesc}{random}{}
+  Return the next random floating point number in the range [0.0, 1.0).
+\end{funcdesc}
+
+\begin{funcdesc}{uniform}{a, b}
+  Return a random real number \var{N} such that
+  \code{\var{a} <= \var{N} < \var{b}}.
+\end{funcdesc}
+
+\begin{funcdesc}{betavariate}{alpha, beta}
+  Beta distribution.  Conditions on the parameters are
+  \code{\var{alpha} > 0} and \code{\var{beta} > 0}.
+  Returned values range between 0 and 1.
+\end{funcdesc}
+
+\begin{funcdesc}{expovariate}{lambd}
+  Exponential distribution.  \var{lambd} is 1.0 divided by the desired
+  mean.  (The parameter would be called ``lambda'', but that is a
+  reserved word in Python.)  Returned values range from 0 to
+  positive infinity.
+\end{funcdesc}
+
+\begin{funcdesc}{gammavariate}{alpha, beta}
+  Gamma distribution.  (\emph{Not} the gamma function!)  Conditions on
+  the parameters are \code{\var{alpha} > 0} and \code{\var{beta} > 0}.
+\end{funcdesc}
+
+\begin{funcdesc}{gauss}{mu, sigma}
+  Gaussian distribution.  \var{mu} is the mean, and \var{sigma} is the
+  standard deviation.  This is slightly faster than the
+  \function{normalvariate()} function defined below.
+\end{funcdesc}
+
+\begin{funcdesc}{lognormvariate}{mu, sigma}
+  Log normal distribution.  If you take the natural logarithm of this
+  distribution, you'll get a normal distribution with mean \var{mu}
+  and standard deviation \var{sigma}.  \var{mu} can have any value,
+  and \var{sigma} must be greater than zero.
+\end{funcdesc}
+
+\begin{funcdesc}{normalvariate}{mu, sigma}
+  Normal distribution.  \var{mu} is the mean, and \var{sigma} is the
+  standard deviation.
+\end{funcdesc}
+
+\begin{funcdesc}{vonmisesvariate}{mu, kappa}
+  \var{mu} is the mean angle, expressed in radians between 0 and
+  2*\emph{pi}, and \var{kappa} is the concentration parameter, which
+  must be greater than or equal to zero.  If \var{kappa} is equal to
+  zero, this distribution reduces to a uniform random angle over the
+  range 0 to 2*\emph{pi}.
+\end{funcdesc}
+
+\begin{funcdesc}{paretovariate}{alpha}
+  Pareto distribution.  \var{alpha} is the shape parameter.
+\end{funcdesc}
+
+\begin{funcdesc}{weibullvariate}{alpha, beta}
+  Weibull distribution.  \var{alpha} is the scale parameter and
+  \var{beta} is the shape parameter.
+\end{funcdesc}
+
+Alternative Generators:
+
+\begin{classdesc}{WichmannHill}{\optional{seed}}
+Class that implements the Wichmann-Hill algorithm as the core generator.
+Has all of the same methods as \class{Random} plus the \method{whseed()}
+method described below.  Because this class is implemented in pure
+Python, it is not threadsafe and may require locks between calls.  The
+period of the generator is 6,953,607,871,644 which is small enough to
+require care that two independent random sequences do not overlap.
+\end{classdesc}
+
+\begin{funcdesc}{whseed}{\optional{x}}
+  This is obsolete, supplied for bit-level compatibility with versions
+  of Python prior to 2.1.
+  See \function{seed()} for details.  \function{whseed()} does not guarantee
+  that distinct integer arguments yield distinct internal states, and can
+  yield no more than about 2**24 distinct internal states in all.
+\end{funcdesc}
+
+\begin{classdesc}{SystemRandom}{\optional{seed}}
+Class that uses the \function{os.urandom()} function for generating
+random numbers from sources provided by the operating system.
+Not available on all systems.
+Does not rely on software state and sequences are not reproducible.
+Accordingly, the \method{seed()} and \method{jumpahead()} methods
+have no effect and are ignored.  The \method{getstate()} and
+\method{setstate()} methods raise \exception{NotImplementedError} if
+called.
+\versionadded{2.4}
+\end{classdesc}
+
+Examples of basic usage:
+
+\begin{verbatim}
+>>> random.random()        # Random float x, 0.0 <= x < 1.0
+0.37444887175646646
+>>> random.uniform(1, 10)  # Random float x, 1.0 <= x < 10.0
+1.1800146073117523
+>>> random.randint(1, 10)  # Integer from 1 to 10, endpoints included
+7
+>>> random.randrange(0, 101, 2)  # Even integer from 0 to 100
+26
+>>> random.choice('abcdefghij')  # Choose a random element
+'c'
+
+>>> items = [1, 2, 3, 4, 5, 6, 7]
+>>> random.shuffle(items)
+>>> items
+[7, 3, 2, 5, 6, 4, 1]
+
+>>> random.sample([1, 2, 3, 4, 5],  3)  # Choose 3 elements
+[4, 1, 5]
+
+\end{verbatim}
+
+\begin{seealso}
+  \seetext{M. Matsumoto and T. Nishimura, ``Mersenne Twister: A
+	   623-dimensionally equidistributed uniform pseudorandom
+	   number generator'',
+	   \citetitle{ACM Transactions on Modeling and Computer Simulation}
+	   Vol. 8, No. 1, January pp.3-30 1998.}
+
+  \seetext{Wichmann, B. A. \& Hill, I. D., ``Algorithm AS 183:
+           An efficient and portable pseudo-random number generator'',
+           \citetitle{Applied Statistics} 31 (1982) 188-190.}
+
+  \seeurl{http://www.npl.co.uk/ssfm/download/abstracts.html\#196}{A modern
+          variation of the Wichmann-Hill generator that greatly increases
+          the period, and passes now-standard statistical tests that the
+          original generator failed.}
+\end{seealso}

Added: vendor/Python/current/Doc/lib/libre.tex
===================================================================
--- vendor/Python/current/Doc/lib/libre.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libre.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,954 @@
+\section{\module{re} ---
+         Regular expression operations}
+\declaremodule{standard}{re}
+\moduleauthor{Fredrik Lundh}{fredrik at pythonware.com}
+\sectionauthor{Andrew M. Kuchling}{amk at amk.ca}
+
+
+\modulesynopsis{Regular expression search and match operations with a
+                Perl-style expression syntax.}
+
+
+This module provides regular expression matching operations similar to
+those found in Perl.  Regular expression pattern strings may not
+contain null bytes, but can specify the null byte using the
+\code{\e\var{number}} notation.  Both patterns and strings to be
+searched can be Unicode strings as well as 8-bit strings.  The
+\module{re} module is always available.
+
+Regular expressions use the backslash character (\character{\e}) to
+indicate special forms or to allow special characters to be used
+without invoking their special meaning.  This collides with Python's
+usage of the same character for the same purpose in string literals;
+for example, to match a literal backslash, one might have to write
+\code{'\e\e\e\e'} as the pattern string, because the regular expression
+must be \samp{\e\e}, and each backslash must be expressed as
+\samp{\e\e} inside a regular Python string literal.
+
+The solution is to use Python's raw string notation for regular
+expression patterns; backslashes are not handled in any special way in
+a string literal prefixed with \character{r}.  So \code{r"\e n"} is a
+two-character string containing \character{\e} and \character{n},
+while \code{"\e n"} is a one-character string containing a newline.
+Usually patterns will be expressed in Python code using this raw
+string notation.
+
+\begin{seealso}
+  \seetitle{Mastering Regular Expressions}{Book on regular expressions
+            by Jeffrey Friedl, published by O'Reilly.  The second 
+            edition of the book no longer covers Python at all, 
+            but the first edition covered writing good regular expression
+            patterns in great detail.}
+\end{seealso}
+
+
+\subsection{Regular Expression Syntax \label{re-syntax}}
+
+A regular expression (or RE) specifies a set of strings that matches
+it; the functions in this module let you check if a particular string
+matches a given regular expression (or if a given regular expression
+matches a particular string, which comes down to the same thing).
+
+Regular expressions can be concatenated to form new regular
+expressions; if \emph{A} and \emph{B} are both regular expressions,
+then \emph{AB} is also a regular expression.  In general, if a string
+\emph{p} matches \emph{A} and another string \emph{q} matches \emph{B},
+the string \emph{pq} will match AB.  This holds unless \emph{A} or
+\emph{B} contain low precedence operations; boundary conditions between
+\emph{A} and \emph{B}; or have numbered group references.  Thus, complex
+expressions can easily be constructed from simpler primitive
+expressions like the ones described here.  For details of the theory
+and implementation of regular expressions, consult the Friedl book
+referenced above, or almost any textbook about compiler construction.
+
+A brief explanation of the format of regular expressions follows.  For
+further information and a gentler presentation, consult the Regular
+Expression HOWTO, accessible from \url{http://www.python.org/doc/howto/}.
+
+Regular expressions can contain both special and ordinary characters.
+Most ordinary characters, like \character{A}, \character{a}, or
+\character{0}, are the simplest regular expressions; they simply match
+themselves.  You can concatenate ordinary characters, so \regexp{last}
+matches the string \code{'last'}.  (In the rest of this section, we'll
+write RE's in \regexp{this special style}, usually without quotes, and
+strings to be matched \code{'in single quotes'}.)
+
+Some characters, like \character{|} or \character{(}, are special.
+Special characters either stand for classes of ordinary characters, or
+affect how the regular expressions around them are interpreted.
+
+The special characters are:
+%
+\begin{description}
+
+\item[\character{.}] (Dot.)  In the default mode, this matches any
+character except a newline.  If the \constant{DOTALL} flag has been
+specified, this matches any character including a newline.
+
+\item[\character{\textasciicircum}] (Caret.)  Matches the start of the
+string, and in \constant{MULTILINE} mode also matches immediately
+after each newline.
+
+\item[\character{\$}] Matches the end of the string or just before the
+newline at the end of the string, and in \constant{MULTILINE} mode
+also matches before a newline.  \regexp{foo} matches both 'foo' and
+'foobar', while the regular expression \regexp{foo\$} matches only
+'foo'.  More interestingly, searching for \regexp{foo.\$} in
+'foo1\textbackslash nfoo2\textbackslash n' matches 'foo2' normally,
+but 'foo1' in \constant{MULTILINE} mode.
+
+\item[\character{*}] Causes the resulting RE to
+match 0 or more repetitions of the preceding RE, as many repetitions
+as are possible.  \regexp{ab*} will
+match 'a', 'ab', or 'a' followed by any number of 'b's.
+
+\item[\character{+}] Causes the
+resulting RE to match 1 or more repetitions of the preceding RE.
+\regexp{ab+} will match 'a' followed by any non-zero number of 'b's; it
+will not match just 'a'.
+
+\item[\character{?}] Causes the resulting RE to
+match 0 or 1 repetitions of the preceding RE.  \regexp{ab?} will
+match either 'a' or 'ab'.
+
+\item[\code{*?}, \code{+?}, \code{??}] The \character{*},
+\character{+}, and \character{?} qualifiers are all \dfn{greedy}; they
+match as much text as possible.  Sometimes this behaviour isn't
+desired; if the RE \regexp{<.*>} is matched against
+\code{'<H1>title</H1>'}, it will match the entire string, and not just
+\code{'<H1>'}.  Adding \character{?} after the qualifier makes it
+perform the match in \dfn{non-greedy} or \dfn{minimal} fashion; as
+\emph{few} characters as possible will be matched.  Using \regexp{.*?}
+in the previous expression will match only \code{'<H1>'}.
+
+\item[\code{\{\var{m}\}}]
+Specifies that exactly \var{m} copies of the previous RE should be
+matched; fewer matches cause the entire RE not to match.  For example,
+\regexp{a\{6\}} will match exactly six \character{a} characters, but
+not five.
+
+\item[\code{\{\var{m},\var{n}\}}] Causes the resulting RE to match from
+\var{m} to \var{n} repetitions of the preceding RE, attempting to
+match as many repetitions as possible.  For example, \regexp{a\{3,5\}}
+will match from 3 to 5 \character{a} characters.  Omitting \var{m}
+specifies a lower bound of zero, 
+and omitting \var{n} specifies an infinite upper bound.  As an
+example, \regexp{a\{4,\}b} will match \code{aaaab} or a thousand
+\character{a} characters followed by a \code{b}, but not \code{aaab}.
+The comma may not be omitted or the modifier would be confused with
+the previously described form.
+
+\item[\code{\{\var{m},\var{n}\}?}] Causes the resulting RE to
+match from \var{m} to \var{n} repetitions of the preceding RE,
+attempting to match as \emph{few} repetitions as possible.  This is
+the non-greedy version of the previous qualifier.  For example, on the
+6-character string \code{'aaaaaa'}, \regexp{a\{3,5\}} will match 5
+\character{a} characters, while \regexp{a\{3,5\}?} will only match 3
+characters.
+
+\item[\character{\e}] Either escapes special characters (permitting
+you to match characters like \character{*}, \character{?}, and so
+forth), or signals a special sequence; special sequences are discussed
+below.
+
+If you're not using a raw string to
+express the pattern, remember that Python also uses the
+backslash as an escape sequence in string literals; if the escape
+sequence isn't recognized by Python's parser, the backslash and
+subsequent character are included in the resulting string.  However,
+if Python would recognize the resulting sequence, the backslash should
+be repeated twice.  This is complicated and hard to understand, so
+it's highly recommended that you use raw strings for all but the
+simplest expressions.
+
+\item[\code{[]}] Used to indicate a set of characters.  Characters can
+be listed individually, or a range of characters can be indicated by
+giving two characters and separating them by a \character{-}.  Special
+characters are not active inside sets.  For example, \regexp{[akm\$]}
+will match any of the characters \character{a}, \character{k},
+\character{m}, or \character{\$}; \regexp{[a-z]}
+will match any lowercase letter, and \code{[a-zA-Z0-9]} matches any
+letter or digit.  Character classes such as \code{\e w} or \code{\e S}
+(defined below) are also acceptable inside a range.  If you want to
+include a \character{]} or a \character{-} inside a set, precede it with a
+backslash, or place it as the first character.  The
+pattern \regexp{[]]} will match \code{']'}, for example.
+
+You can match the characters not within a range by \dfn{complementing}
+the set.  This is indicated by including a
+\character{\textasciicircum} as the first character of the set;
+\character{\textasciicircum} elsewhere will simply match the
+\character{\textasciicircum} character.  For example,
+\regexp{[{\textasciicircum}5]} will match
+any character except \character{5}, and
+\regexp{[\textasciicircum\code{\textasciicircum}]} will match any character
+except \character{\textasciicircum}.
+
+\item[\character{|}]\code{A|B}, where A and B can be arbitrary REs,
+creates a regular expression that will match either A or B.  An
+arbitrary number of REs can be separated by the \character{|} in this
+way.  This can be used inside groups (see below) as well.  As the target
+string is scanned, REs separated by \character{|} are tried from left to
+right. When one pattern completely matches, that branch is accepted.
+This means that once \code{A} matches, \code{B} will not be tested further,
+even if it would produce a longer overall match.  In other words, the
+\character{|} operator is never greedy.  To match a literal \character{|},
+use \regexp{\e|}, or enclose it inside a character class, as in \regexp{[|]}.
+
+\item[\code{(...)}] Matches whatever regular expression is inside the
+parentheses, and indicates the start and end of a group; the contents
+of a group can be retrieved after a match has been performed, and can
+be matched later in the string with the \regexp{\e \var{number}} special
+sequence, described below.  To match the literals \character{(} or
+\character{)}, use \regexp{\e(} or \regexp{\e)}, or enclose them
+inside a character class: \regexp{[(] [)]}.
+
+\item[\code{(?...)}] This is an extension notation (a \character{?}
+following a \character{(} is not meaningful otherwise).  The first
+character after the \character{?}
+determines what the meaning and further syntax of the construct is.
+Extensions usually do not create a new group;
+\regexp{(?P<\var{name}>...)} is the only exception to this rule.
+Following are the currently supported extensions.
+
+\item[\code{(?iLmsux)}] (One or more letters from the set \character{i},
+\character{L}, \character{m}, \character{s}, \character{u},
+\character{x}.)  The group matches the empty string; the letters set
+the corresponding flags (\constant{re.I}, \constant{re.L},
+\constant{re.M}, \constant{re.S}, \constant{re.U}, \constant{re.X})
+for the entire regular expression.  This is useful if you wish to
+include the flags as part of the regular expression, instead of
+passing a \var{flag} argument to the \function{compile()} function.
+
+Note that the \regexp{(?x)} flag changes how the expression is parsed.
+It should be used first in the expression string, or after one or more
+whitespace characters.  If there are non-whitespace characters before
+the flag, the results are undefined.
+
+\item[\code{(?:...)}] A non-grouping version of regular parentheses.
+Matches whatever regular expression is inside the parentheses, but the
+substring matched by the
+group \emph{cannot} be retrieved after performing a match or
+referenced later in the pattern.
+
+\item[\code{(?P<\var{name}>...)}] Similar to regular parentheses, but
+the substring matched by the group is accessible via the symbolic group
+name \var{name}.  Group names must be valid Python identifiers, and
+each group name must be defined only once within a regular expression.  A
+symbolic group is also a numbered group, just as if the group were not
+named.  So the group named 'id' in the example above can also be
+referenced as the numbered group 1.
+
+For example, if the pattern is
+\regexp{(?P<id>[a-zA-Z_]\e w*)}, the group can be referenced by its
+name in arguments to methods of match objects, such as
+\code{m.group('id')} or \code{m.end('id')}, and also by name in
+pattern text (for example, \regexp{(?P=id)}) and replacement text
+(such as \code{\e g<id>}).
+
+\item[\code{(?P=\var{name})}] Matches whatever text was matched by the
+earlier group named \var{name}.
+
+\item[\code{(?\#...)}] A comment; the contents of the parentheses are
+simply ignored.
+
+\item[\code{(?=...)}] Matches if \regexp{...} matches next, but doesn't
+consume any of the string.  This is called a lookahead assertion.  For
+example, \regexp{Isaac (?=Asimov)} will match \code{'Isaac~'} only if it's
+followed by \code{'Asimov'}.
+
+\item[\code{(?!...)}] Matches if \regexp{...} doesn't match next.  This
+is a negative lookahead assertion.  For example,
+\regexp{Isaac (?!Asimov)} will match \code{'Isaac~'} only if it's \emph{not}
+followed by \code{'Asimov'}.
+
+\item[\code{(?<=...)}] Matches if the current position in the string
+is preceded by a match for \regexp{...} that ends at the current
+position.  This is called a \dfn{positive lookbehind assertion}.
+\regexp{(?<=abc)def} will find a match in \samp{abcdef}, since the
+lookbehind will back up 3 characters and check if the contained
+pattern matches.  The contained pattern must only match strings of
+some fixed length, meaning that \regexp{abc} or \regexp{a|b} are
+allowed, but \regexp{a*} and \regexp{a\{3,4\}} are not.  Note that
+patterns which start with positive lookbehind assertions will never
+match at the beginning of the string being searched; you will most
+likely want to use the \function{search()} function rather than the
+\function{match()} function:
+
+\begin{verbatim}
+>>> import re
+>>> m = re.search('(?<=abc)def', 'abcdef')
+>>> m.group(0)
+'def'
+\end{verbatim}
+
+This example looks for a word following a hyphen:
+
+\begin{verbatim}
+>>> m = re.search('(?<=-)\w+', 'spam-egg')
+>>> m.group(0)
+'egg'
+\end{verbatim}
+
+\item[\code{(?<!...)}] Matches if the current position in the string
+is not preceded by a match for \regexp{...}.  This is called a
+\dfn{negative lookbehind assertion}.  Similar to positive lookbehind
+assertions, the contained pattern must only match strings of some
+fixed length.  Patterns which start with negative lookbehind
+assertions may match at the beginning of the string being searched.
+
+\item[\code{(?(\var{id/name})yes-pattern|no-pattern)}] Will try to match
+with \regexp{yes-pattern} if the group with given \var{id} or \var{name}
+exists, and with \regexp{no-pattern} if it doesn't. \regexp{|no-pattern}
+is optional and can be omitted. For example, 
+\regexp{(<)?(\e w+@\e w+(?:\e .\e w+)+)(?(1)>)} is a poor email matching
+pattern, which will match with \code{'<user at host.com>'} as well as
+\code{'user at host.com'}, but not with \code{'<user at host.com'}.
+\versionadded{2.4}
+
+\end{description}
+
+The special sequences consist of \character{\e} and a character from the
+list below.  If the ordinary character is not on the list, then the
+resulting RE will match the second character.  For example,
+\regexp{\e\$} matches the character \character{\$}.
+%
+\begin{description}
+
+\item[\code{\e \var{number}}] Matches the contents of the group of the
+same number.  Groups are numbered starting from 1.  For example,
+\regexp{(.+) \e 1} matches \code{'the the'} or \code{'55 55'}, but not
+\code{'the end'} (note
+the space after the group).  This special sequence can only be used to
+match one of the first 99 groups.  If the first digit of \var{number}
+is 0, or \var{number} is 3 octal digits long, it will not be interpreted
+as a group match, but as the character with octal value \var{number}.
+Inside the \character{[} and \character{]} of a character class, all numeric
+escapes are treated as characters.
+
+\item[\code{\e A}] Matches only at the start of the string.
+
+\item[\code{\e b}] Matches the empty string, but only at the
+beginning or end of a word.  A word is defined as a sequence of
+alphanumeric or underscore characters, so the end of a word is indicated by
+whitespace or a non-alphanumeric, non-underscore character.  Note that 
+{}\code{\e b} is defined as the boundary between \code{\e w} and \code{\e
+W}, so the precise set of characters deemed to be alphanumeric depends on the
+values of the \code{UNICODE} and \code{LOCALE} flags.  Inside a character
+range, \regexp{\e b} represents the backspace character, for compatibility
+with Python's string literals.
+
+\item[\code{\e B}] Matches the empty string, but only when it is \emph{not}
+at the beginning or end of a word.  This is just the opposite of {}\code{\e
+b}, so is also subject to the settings of \code{LOCALE} and \code{UNICODE}.
+
+\item[\code{\e d}]When the \constant{UNICODE} flag is not specified, matches
+any decimal digit; this is equivalent to the set \regexp{[0-9]}. 
+With \constant{UNICODE}, it will match whatever is classified as a digit
+in the Unicode character properties database.
+
+\item[\code{\e D}]When the \constant{UNICODE} flag is not specified, matches
+any non-digit character; this is equivalent to the set 
+\regexp{[{\textasciicircum}0-9]}.  With \constant{UNICODE}, it will match 
+anything other than character marked as digits in the Unicode character 
+properties database.
+
+\item[\code{\e s}]When the \constant{LOCALE} and \constant{UNICODE}
+flags are not specified, matches any whitespace character; this is
+equivalent to the set \regexp{[ \e t\e n\e r\e f\e v]}.
+With \constant{LOCALE}, it will match this set plus whatever characters
+are defined as space for the current locale. If \constant{UNICODE} is set,
+this will match the characters \regexp{[ \e t\e n\e r\e f\e v]} plus
+whatever is classified as space in the Unicode character properties
+database.
+
+\item[\code{\e S}]When the \constant{LOCALE} and \constant{UNICODE}
+flags are not specified, matches any non-whitespace character; this is
+equivalent to the set \regexp{[\textasciicircum\ \e t\e n\e r\e f\e v]}
+With \constant{LOCALE}, it will match any character not in this set,
+and not defined as space in the current locale. If \constant{UNICODE}
+is set, this will match anything other than \regexp{[ \e t\e n\e r\e f\e v]}
+and characters marked as space in the Unicode character properties database.
+
+\item[\code{\e w}]When the \constant{LOCALE} and \constant{UNICODE}
+flags are not specified, matches any alphanumeric character and the
+underscore; this is equivalent to the set
+\regexp{[a-zA-Z0-9_]}.  With \constant{LOCALE}, it will match the set
+\regexp{[0-9_]} plus whatever characters are defined as alphanumeric for
+the current locale.  If \constant{UNICODE} is set, this will match the
+characters \regexp{[0-9_]} plus whatever is classified as alphanumeric
+in the Unicode character properties database.
+
+\item[\code{\e W}]When the \constant{LOCALE} and \constant{UNICODE}
+flags are not specified, matches any non-alphanumeric character; this
+is equivalent to the set \regexp{[{\textasciicircum}a-zA-Z0-9_]}.   With
+\constant{LOCALE}, it will match any character not in the set
+\regexp{[0-9_]}, and not defined as alphanumeric for the current locale.
+If \constant{UNICODE} is set, this will match anything other than
+\regexp{[0-9_]} and characters marked as alphanumeric in the Unicode
+character properties database.
+
+\item[\code{\e Z}]Matches only at the end of the string.
+
+\end{description}
+
+Most of the standard escapes supported by Python string literals are
+also accepted by the regular expression parser:
+
+\begin{verbatim}
+\a      \b      \f      \n
+\r      \t      \v      \x
+\\
+\end{verbatim}
+
+Octal escapes are included in a limited form: If the first digit is a
+0, or if there are three octal digits, it is considered an octal
+escape. Otherwise, it is a group reference.  As for string literals,
+octal escapes are always at most three digits in length.
+
+
+% Note the lack of a period in the section title; it causes problems
+% with readers of the GNU info version.  See http://www.python.org/sf/581414.
+\subsection{Matching vs Searching \label{matching-searching}}
+\sectionauthor{Fred L. Drake, Jr.}{fdrake at acm.org}
+
+Python offers two different primitive operations based on regular
+expressions: match and search.  If you are accustomed to Perl's
+semantics, the search operation is what you're looking for.  See the
+\function{search()} function and corresponding method of compiled
+regular expression objects.
+
+Note that match may differ from search using a regular expression
+beginning with \character{\textasciicircum}:
+\character{\textasciicircum} matches only at the
+start of the string, or in \constant{MULTILINE} mode also immediately
+following a newline.  The ``match'' operation succeeds only if the
+pattern matches at the start of the string regardless of mode, or at
+the starting position given by the optional \var{pos} argument
+regardless of whether a newline precedes it.
+
+% Examples from Tim Peters:
+\begin{verbatim}
+re.compile("a").match("ba", 1)           # succeeds
+re.compile("^a").search("ba", 1)         # fails; 'a' not at start
+re.compile("^a").search("\na", 1)        # fails; 'a' not at start
+re.compile("^a", re.M).search("\na", 1)  # succeeds
+re.compile("^a", re.M).search("ba", 1)   # fails; no preceding \n
+\end{verbatim}
+
+
+\subsection{Module Contents}
+\nodename{Contents of Module re}
+
+The module defines several functions, constants, and an exception. Some of the
+functions are simplified versions of the full featured methods for compiled
+regular expressions.  Most non-trivial applications always use the compiled
+form.
+
+\begin{funcdesc}{compile}{pattern\optional{, flags}}
+  Compile a regular expression pattern into a regular expression
+  object, which can be used for matching using its \function{match()} and
+  \function{search()} methods, described below.
+
+  The expression's behaviour can be modified by specifying a
+  \var{flags} value.  Values can be any of the following variables,
+  combined using bitwise OR (the \code{|} operator).
+
+The sequence
+
+\begin{verbatim}
+prog = re.compile(pat)
+result = prog.match(str)
+\end{verbatim}
+
+is equivalent to
+
+\begin{verbatim}
+result = re.match(pat, str)
+\end{verbatim}
+
+but the version using \function{compile()} is more efficient when the
+expression will be used several times in a single program.
+%(The compiled version of the last pattern passed to
+%\function{re.match()} or \function{re.search()} is cached, so
+%programs that use only a single regular expression at a time needn't
+%worry about compiling regular expressions.)
+\end{funcdesc}
+
+\begin{datadesc}{I}
+\dataline{IGNORECASE}
+Perform case-insensitive matching; expressions like \regexp{[A-Z]}
+will match lowercase letters, too.  This is not affected by the
+current locale.
+\end{datadesc}
+
+\begin{datadesc}{L}
+\dataline{LOCALE}
+Make \regexp{\e w}, \regexp{\e W}, \regexp{\e b}, \regexp{\e B},
+\regexp{\e s} and \regexp{\e S} dependent on the current locale.
+\end{datadesc}
+
+\begin{datadesc}{M}
+\dataline{MULTILINE}
+When specified, the pattern character \character{\textasciicircum}
+matches at the beginning of the string and at the beginning of each
+line (immediately following each newline); and the pattern character
+\character{\$} matches at the end of the string and at the end of each
+line (immediately preceding each newline).  By default,
+\character{\textasciicircum} matches only at the beginning of the
+string, and \character{\$} only at the end of the string and
+immediately before the newline (if any) at the end of the string.
+\end{datadesc}
+
+\begin{datadesc}{S}
+\dataline{DOTALL}
+Make the \character{.} special character match any character at all,
+including a newline; without this flag, \character{.} will match
+anything \emph{except} a newline.
+\end{datadesc}
+
+\begin{datadesc}{U}
+\dataline{UNICODE}
+Make \regexp{\e w}, \regexp{\e W}, \regexp{\e b}, \regexp{\e B},
+\regexp{\e d}, \regexp{\e D}, \regexp{\e s} and \regexp{\e S}
+dependent on the Unicode character properties database.
+\versionadded{2.0}
+\end{datadesc}
+
+\begin{datadesc}{X}
+\dataline{VERBOSE}
+This flag allows you to write regular expressions that look nicer.
+Whitespace within the pattern is ignored,
+except when in a character class or preceded by an unescaped
+backslash, and, when a line contains a \character{\#} neither in a
+character class or preceded by an unescaped backslash, all characters
+from the leftmost such \character{\#} through the end of the line are
+ignored.
+% XXX should add an example here
+\end{datadesc}
+
+
+\begin{funcdesc}{search}{pattern, string\optional{, flags}}
+  Scan through \var{string} looking for a location where the regular
+  expression \var{pattern} produces a match, and return a
+  corresponding \class{MatchObject} instance.
+  Return \code{None} if no
+  position in the string matches the pattern; note that this is
+  different from finding a zero-length match at some point in the string.
+\end{funcdesc}
+
+\begin{funcdesc}{match}{pattern, string\optional{, flags}}
+  If zero or more characters at the beginning of \var{string} match
+  the regular expression \var{pattern}, return a corresponding
+  \class{MatchObject} instance.  Return \code{None} if the string does not
+  match the pattern; note that this is different from a zero-length
+  match.
+
+  \note{If you want to locate a match anywhere in
+  \var{string}, use \method{search()} instead.}
+\end{funcdesc}
+
+\begin{funcdesc}{split}{pattern, string\optional{, maxsplit\code{ = 0}}}
+  Split \var{string} by the occurrences of \var{pattern}.  If
+  capturing parentheses are used in \var{pattern}, then the text of all
+  groups in the pattern are also returned as part of the resulting list.
+  If \var{maxsplit} is nonzero, at most \var{maxsplit} splits
+  occur, and the remainder of the string is returned as the final
+  element of the list.  (Incompatibility note: in the original Python
+  1.5 release, \var{maxsplit} was ignored.  This has been fixed in
+  later releases.)
+
+\begin{verbatim}
+>>> re.split('\W+', 'Words, words, words.')
+['Words', 'words', 'words', '']
+>>> re.split('(\W+)', 'Words, words, words.')
+['Words', ', ', 'words', ', ', 'words', '.', '']
+>>> re.split('\W+', 'Words, words, words.', 1)
+['Words', 'words, words.']
+\end{verbatim}
+\end{funcdesc}
+
+\begin{funcdesc}{findall}{pattern, string\optional{, flags}}
+  Return a list of all non-overlapping matches of \var{pattern} in
+  \var{string}.  If one or more groups are present in the pattern,
+  return a list of groups; this will be a list of tuples if the
+  pattern has more than one group.  Empty matches are included in the
+  result unless they touch the beginning of another match.
+  \versionadded{1.5.2}
+  \versionchanged[Added the optional flags argument]{2.4}
+\end{funcdesc}
+
+\begin{funcdesc}{finditer}{pattern, string\optional{, flags}}
+  Return an iterator over all non-overlapping matches for the RE
+  \var{pattern} in \var{string}.  For each match, the iterator returns
+  a match object.  Empty matches are included in the result unless they
+  touch the beginning of another match.
+  \versionadded{2.2}
+  \versionchanged[Added the optional flags argument]{2.4}
+\end{funcdesc}
+
+\begin{funcdesc}{sub}{pattern, repl, string\optional{, count}}
+  Return the string obtained by replacing the leftmost non-overlapping
+  occurrences of \var{pattern} in \var{string} by the replacement
+  \var{repl}.  If the pattern isn't found, \var{string} is returned
+  unchanged.  \var{repl} can be a string or a function; if it is a
+  string, any backslash escapes in it are processed.  That is,
+  \samp{\e n} is converted to a single newline character, \samp{\e r}
+  is converted to a linefeed, and so forth.  Unknown escapes such as
+  \samp{\e j} are left alone.  Backreferences, such as \samp{\e6}, are
+  replaced with the substring matched by group 6 in the pattern.  For
+  example:
+
+\begin{verbatim}
+>>> re.sub(r'def\s+([a-zA-Z_][a-zA-Z_0-9]*)\s*\(\s*\):',
+...        r'static PyObject*\npy_\1(void)\n{',
+...        'def myfunc():')
+'static PyObject*\npy_myfunc(void)\n{'
+\end{verbatim}
+
+  If \var{repl} is a function, it is called for every non-overlapping
+  occurrence of \var{pattern}.  The function takes a single match
+  object argument, and returns the replacement string.  For example:
+
+\begin{verbatim}
+>>> def dashrepl(matchobj):
+...     if matchobj.group(0) == '-': return ' '
+...     else: return '-'
+>>> re.sub('-{1,2}', dashrepl, 'pro----gram-files')
+'pro--gram files'
+\end{verbatim}
+
+  The pattern may be a string or an RE object; if you need to specify
+  regular expression flags, you must use a RE object, or use embedded
+  modifiers in a pattern; for example, \samp{sub("(?i)b+", "x", "bbbb
+  BBBB")} returns \code{'x x'}.
+
+  The optional argument \var{count} is the maximum number of pattern
+  occurrences to be replaced; \var{count} must be a non-negative
+  integer.  If omitted or zero, all occurrences will be replaced.
+  Empty matches for the pattern are replaced only when not adjacent to
+  a previous match, so \samp{sub('x*', '-', 'abc')} returns
+  \code{'-a-b-c-'}.
+
+  In addition to character escapes and backreferences as described
+  above, \samp{\e g<name>} will use the substring matched by the group
+  named \samp{name}, as defined by the \regexp{(?P<name>...)} syntax.
+  \samp{\e g<number>} uses the corresponding group number;
+  \samp{\e g<2>} is therefore equivalent to \samp{\e 2}, but isn't
+  ambiguous in a replacement such as \samp{\e g<2>0}.  \samp{\e 20}
+  would be interpreted as a reference to group 20, not a reference to
+  group 2 followed by the literal character \character{0}.  The
+  backreference \samp{\e g<0>} substitutes in the entire substring
+  matched by the RE.
+\end{funcdesc}
+
+\begin{funcdesc}{subn}{pattern, repl, string\optional{, count}}
+  Perform the same operation as \function{sub()}, but return a tuple
+  \code{(\var{new_string}, \var{number_of_subs_made})}.
+\end{funcdesc}
+
+\begin{funcdesc}{escape}{string}
+  Return \var{string} with all non-alphanumerics backslashed; this is
+  useful if you want to match an arbitrary literal string that may have
+  regular expression metacharacters in it.
+\end{funcdesc}
+
+\begin{excdesc}{error}
+  Exception raised when a string passed to one of the functions here
+  is not a valid regular expression (for example, it might contain
+  unmatched parentheses) or when some other error occurs during
+  compilation or matching.  It is never an error if a string contains
+  no match for a pattern.
+\end{excdesc}
+
+
+\subsection{Regular Expression Objects \label{re-objects}}
+
+Compiled regular expression objects support the following methods and
+attributes:
+
+\begin{methoddesc}[RegexObject]{match}{string\optional{, pos\optional{,
+                                       endpos}}}
+  If zero or more characters at the beginning of \var{string} match
+  this regular expression, return a corresponding
+  \class{MatchObject} instance.  Return \code{None} if the string does not
+  match the pattern; note that this is different from a zero-length
+  match.
+
+  \note{If you want to locate a match anywhere in
+  \var{string}, use \method{search()} instead.}
+
+  The optional second parameter \var{pos} gives an index in the string
+  where the search is to start; it defaults to \code{0}.  This is not
+  completely equivalent to slicing the string; the
+  \code{'\textasciicircum'} pattern
+  character matches at the real beginning of the string and at positions
+  just after a newline, but not necessarily at the index where the search
+  is to start.
+
+  The optional parameter \var{endpos} limits how far the string will
+  be searched; it will be as if the string is \var{endpos} characters
+  long, so only the characters from \var{pos} to \code{\var{endpos} -
+  1} will be searched for a match.  If \var{endpos} is less than
+  \var{pos}, no match will be found, otherwise, if \var{rx} is a
+  compiled regular expression object,
+  \code{\var{rx}.match(\var{string}, 0, 50)} is equivalent to
+  \code{\var{rx}.match(\var{string}[:50], 0)}.
+\end{methoddesc}
+
+\begin{methoddesc}[RegexObject]{search}{string\optional{, pos\optional{,
+                                        endpos}}}
+  Scan through \var{string} looking for a location where this regular
+  expression produces a match, and return a
+  corresponding \class{MatchObject} instance.  Return \code{None} if no
+  position in the string matches the pattern; note that this is
+  different from finding a zero-length match at some point in the string.
+
+  The optional \var{pos} and \var{endpos} parameters have the same
+  meaning as for the \method{match()} method.
+\end{methoddesc}
+
+\begin{methoddesc}[RegexObject]{split}{string\optional{,
+                                       maxsplit\code{ = 0}}}
+Identical to the \function{split()} function, using the compiled pattern.
+\end{methoddesc}
+
+\begin{methoddesc}[RegexObject]{findall}{string\optional{, pos\optional{,
+                                        endpos}}}
+Identical to the \function{findall()} function, using the compiled pattern.
+\end{methoddesc}
+
+\begin{methoddesc}[RegexObject]{finditer}{string\optional{, pos\optional{,
+                                        endpos}}}
+Identical to the \function{finditer()} function, using the compiled pattern.
+\end{methoddesc}
+
+\begin{methoddesc}[RegexObject]{sub}{repl, string\optional{, count\code{ = 0}}}
+Identical to the \function{sub()} function, using the compiled pattern.
+\end{methoddesc}
+
+\begin{methoddesc}[RegexObject]{subn}{repl, string\optional{,
+                                      count\code{ = 0}}}
+Identical to the \function{subn()} function, using the compiled pattern.
+\end{methoddesc}
+
+
+\begin{memberdesc}[RegexObject]{flags}
+The flags argument used when the RE object was compiled, or
+\code{0} if no flags were provided.
+\end{memberdesc}
+
+\begin{memberdesc}[RegexObject]{groupindex}
+A dictionary mapping any symbolic group names defined by
+\regexp{(?P<\var{id}>)} to group numbers.  The dictionary is empty if no
+symbolic groups were used in the pattern.
+\end{memberdesc}
+
+\begin{memberdesc}[RegexObject]{pattern}
+The pattern string from which the RE object was compiled.
+\end{memberdesc}
+
+
+\subsection{Match Objects \label{match-objects}}
+
+\class{MatchObject} instances support the following methods and
+attributes:
+
+\begin{methoddesc}[MatchObject]{expand}{template}
+ Return the string obtained by doing backslash substitution on the
+template string \var{template}, as done by the \method{sub()} method.
+Escapes such as \samp{\e n} are converted to the appropriate
+characters, and numeric backreferences (\samp{\e 1}, \samp{\e 2}) and
+named backreferences (\samp{\e g<1>}, \samp{\e g<name>}) are replaced
+by the contents of the corresponding group.
+\end{methoddesc}
+
+\begin{methoddesc}[MatchObject]{group}{\optional{group1, \moreargs}}
+Returns one or more subgroups of the match.  If there is a single
+argument, the result is a single string; if there are
+multiple arguments, the result is a tuple with one item per argument.
+Without arguments, \var{group1} defaults to zero (the whole match
+is returned).
+If a \var{groupN} argument is zero, the corresponding return value is the
+entire matching string; if it is in the inclusive range [1..99], it is
+the string matching the corresponding parenthesized group.  If a
+group number is negative or larger than the number of groups defined
+in the pattern, an \exception{IndexError} exception is raised.
+If a group is contained in a part of the pattern that did not match,
+the corresponding result is \code{None}.  If a group is contained in a
+part of the pattern that matched multiple times, the last match is
+returned.
+
+If the regular expression uses the \regexp{(?P<\var{name}>...)} syntax,
+the \var{groupN} arguments may also be strings identifying groups by
+their group name.  If a string argument is not used as a group name in
+the pattern, an \exception{IndexError} exception is raised.
+
+A moderately complicated example:
+
+\begin{verbatim}
+m = re.match(r"(?P<int>\d+)\.(\d*)", '3.14')
+\end{verbatim}
+
+After performing this match, \code{m.group(1)} is \code{'3'}, as is
+\code{m.group('int')}, and \code{m.group(2)} is \code{'14'}.
+\end{methoddesc}
+
+\begin{methoddesc}[MatchObject]{groups}{\optional{default}}
+Return a tuple containing all the subgroups of the match, from 1 up to
+however many groups are in the pattern.  The \var{default} argument is
+used for groups that did not participate in the match; it defaults to
+\code{None}.  (Incompatibility note: in the original Python 1.5
+release, if the tuple was one element long, a string would be returned
+instead.  In later versions (from 1.5.1 on), a singleton tuple is
+returned in such cases.)
+\end{methoddesc}
+
+\begin{methoddesc}[MatchObject]{groupdict}{\optional{default}}
+Return a dictionary containing all the \emph{named} subgroups of the
+match, keyed by the subgroup name.  The \var{default} argument is
+used for groups that did not participate in the match; it defaults to
+\code{None}.
+\end{methoddesc}
+
+\begin{methoddesc}[MatchObject]{start}{\optional{group}}
+\methodline{end}{\optional{group}}
+Return the indices of the start and end of the substring
+matched by \var{group}; \var{group} defaults to zero (meaning the whole
+matched substring).
+Return \code{-1} if \var{group} exists but
+did not contribute to the match.  For a match object
+\var{m}, and a group \var{g} that did contribute to the match, the
+substring matched by group \var{g} (equivalent to
+\code{\var{m}.group(\var{g})}) is
+
+\begin{verbatim}
+m.string[m.start(g):m.end(g)]
+\end{verbatim}
+
+Note that
+\code{m.start(\var{group})} will equal \code{m.end(\var{group})} if
+\var{group} matched a null string.  For example, after \code{\var{m} =
+re.search('b(c?)', 'cba')}, \code{\var{m}.start(0)} is 1,
+\code{\var{m}.end(0)} is 2, \code{\var{m}.start(1)} and
+\code{\var{m}.end(1)} are both 2, and \code{\var{m}.start(2)} raises
+an \exception{IndexError} exception.
+\end{methoddesc}
+
+\begin{methoddesc}[MatchObject]{span}{\optional{group}}
+For \class{MatchObject} \var{m}, return the 2-tuple
+\code{(\var{m}.start(\var{group}), \var{m}.end(\var{group}))}.
+Note that if \var{group} did not contribute to the match, this is
+\code{(-1, -1)}.  Again, \var{group} defaults to zero.
+\end{methoddesc}
+
+\begin{memberdesc}[MatchObject]{pos}
+The value of \var{pos} which was passed to the \function{search()} or
+\function{match()} method of the \class{RegexObject}.  This is the
+index into the string at which the RE engine started looking for a
+match.
+\end{memberdesc}
+
+\begin{memberdesc}[MatchObject]{endpos}
+The value of \var{endpos} which was passed to the \function{search()}
+or \function{match()} method of the \class{RegexObject}.  This is the
+index into the string beyond which the RE engine will not go.
+\end{memberdesc}
+
+\begin{memberdesc}[MatchObject]{lastindex}
+The integer index of the last matched capturing group, or \code{None}
+if no group was matched at all. For example, the expressions
+\regexp{(a)b}, \regexp{((a)(b))}, and \regexp{((ab))} will have
+\code{lastindex == 1} if applied to the string \code{'ab'},
+while the expression \regexp{(a)(b)} will have \code{lastindex == 2},
+if applied to the same string.
+\end{memberdesc}
+
+\begin{memberdesc}[MatchObject]{lastgroup}
+The name of the last matched capturing group, or \code{None} if the
+group didn't have a name, or if no group was matched at all.
+\end{memberdesc}
+
+\begin{memberdesc}[MatchObject]{re}
+The regular expression object whose \method{match()} or
+\method{search()} method produced this \class{MatchObject} instance.
+\end{memberdesc}
+
+\begin{memberdesc}[MatchObject]{string}
+The string passed to \function{match()} or \function{search()}.
+\end{memberdesc}
+
+\subsection{Examples}
+
+\leftline{\strong{Simulating \cfunction{scanf()}}}
+
+Python does not currently have an equivalent to \cfunction{scanf()}.
+\ttindex{scanf()}
+Regular expressions are generally more powerful, though also more
+verbose, than \cfunction{scanf()} format strings.  The table below
+offers some more-or-less equivalent mappings between
+\cfunction{scanf()} format tokens and regular expressions.
+
+\begin{tableii}{l|l}{textrm}{\cfunction{scanf()} Token}{Regular Expression}
+  \lineii{\code{\%c}}
+         {\regexp{.}}
+  \lineii{\code{\%5c}}
+         {\regexp{.\{5\}}}
+  \lineii{\code{\%d}}
+         {\regexp{[-+]?\e d+}}
+  \lineii{\code{\%e}, \code{\%E}, \code{\%f}, \code{\%g}}
+         {\regexp{[-+]?(\e d+(\e.\e d*)?|\e.\e d+)([eE][-+]?\e d+)?}}
+  \lineii{\code{\%i}}
+         {\regexp{[-+]?(0[xX][\e dA-Fa-f]+|0[0-7]*|\e d+)}}
+  \lineii{\code{\%o}}
+         {\regexp{0[0-7]*}}
+  \lineii{\code{\%s}}
+         {\regexp{\e S+}}
+  \lineii{\code{\%u}}
+         {\regexp{\e d+}}
+  \lineii{\code{\%x}, \code{\%X}}
+         {\regexp{0[xX][\e dA-Fa-f]+}}
+\end{tableii}
+
+To extract the filename and numbers from a string like
+
+\begin{verbatim}
+    /usr/sbin/sendmail - 0 errors, 4 warnings
+\end{verbatim}
+
+you would use a \cfunction{scanf()} format like
+
+\begin{verbatim}
+    %s - %d errors, %d warnings
+\end{verbatim}
+
+The equivalent regular expression would be
+
+\begin{verbatim}
+    (\S+) - (\d+) errors, (\d+) warnings
+\end{verbatim}
+
+\leftline{\strong{Avoiding recursion}}
+
+If you create regular expressions that require the engine to perform a
+lot of recursion, you may encounter a \exception{RuntimeError} exception with
+the message \code{maximum recursion limit} exceeded. For example,
+
+\begin{verbatim}
+>>> import re
+>>> s = 'Begin ' + 1000*'a very long string ' + 'end'
+>>> re.match('Begin (\w| )*? end', s).end()
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+  File "/usr/local/lib/python2.5/re.py", line 132, in match
+    return _compile(pattern, flags).match(string)
+RuntimeError: maximum recursion limit exceeded
+\end{verbatim}
+
+You can often restructure your regular expression to avoid recursion.
+
+Starting with Python 2.3, simple uses of the \regexp{*?} pattern are
+special-cased to avoid recursion.  Thus, the above regular expression
+can avoid recursion by being recast as
+\regexp{Begin [a-zA-Z0-9_ ]*?end}.  As a further benefit, such regular
+expressions will run faster than their recursive equivalents.

Added: vendor/Python/current/Doc/lib/libreadline.tex
===================================================================
--- vendor/Python/current/Doc/lib/libreadline.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libreadline.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,196 @@
+\section{\module{readline} ---
+         GNU readline interface}
+
+\declaremodule{builtin}{readline}
+  \platform{Unix}
+\sectionauthor{Skip Montanaro}{skip at mojam.com}
+\modulesynopsis{GNU readline support for Python.}
+
+
+The \module{readline} module defines a number of functions to
+facilitate completion and reading/writing of history files from the
+Python interpreter.  This module can be used directly or via the
+\refmodule{rlcompleter} module.  Settings made using 
+this module affect the behaviour of both the interpreter's interactive prompt 
+and the prompts offered by the \function{raw_input()} and \function{input()}
+built-in functions.
+
+The \module{readline} module defines the following functions:
+
+
+\begin{funcdesc}{parse_and_bind}{string}
+Parse and execute single line of a readline init file.
+\end{funcdesc}
+
+\begin{funcdesc}{get_line_buffer}{}
+Return the current contents of the line buffer.
+\end{funcdesc}
+
+\begin{funcdesc}{insert_text}{string}
+Insert text into the command line.
+\end{funcdesc}
+
+\begin{funcdesc}{read_init_file}{\optional{filename}}
+Parse a readline initialization file.
+The default filename is the last filename used.
+\end{funcdesc}
+
+\begin{funcdesc}{read_history_file}{\optional{filename}}
+Load a readline history file.
+The default filename is \file{\~{}/.history}.
+\end{funcdesc}
+
+\begin{funcdesc}{write_history_file}{\optional{filename}}
+Save a readline history file.
+The default filename is \file{\~{}/.history}.
+\end{funcdesc}
+
+\begin{funcdesc}{clear_history}{}
+Clear the current history.  (Note: this function is not available if
+the installed version of GNU readline doesn't support it.)
+\versionadded{2.4}
+\end{funcdesc}
+
+\begin{funcdesc}{get_history_length}{}
+Return the desired length of the history file.  Negative values imply
+unlimited history file size.
+\end{funcdesc}
+
+\begin{funcdesc}{set_history_length}{length}
+Set the number of lines to save in the history file.
+\function{write_history_file()} uses this value to truncate the
+history file when saving.  Negative values imply unlimited history
+file size.
+\end{funcdesc}
+
+\begin{funcdesc}{get_current_history_length}{}
+Return the number of lines currently in the history.  (This is different
+from \function{get_history_length()}, which returns the maximum number of
+lines that will be written to a history file.)  \versionadded{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{get_history_item}{index}
+Return the current contents of history item at \var{index}.
+\versionadded{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{remove_history_item}{pos}
+Remove history item specified by its position from the history.
+\versionadded{2.4}
+\end{funcdesc}
+
+\begin{funcdesc}{replace_history_item}{pos, line}
+Replace history item specified by its position with the given line.
+\versionadded{2.4}
+\end{funcdesc}
+
+\begin{funcdesc}{redisplay}{}
+Change what's displayed on the screen to reflect the current contents
+of the line buffer.  \versionadded{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{set_startup_hook}{\optional{function}}
+Set or remove the startup_hook function.  If \var{function} is specified,
+it will be used as the new startup_hook function; if omitted or
+\code{None}, any hook function already installed is removed.  The
+startup_hook function is called with no arguments just
+before readline prints the first prompt.
+\end{funcdesc}
+
+\begin{funcdesc}{set_pre_input_hook}{\optional{function}}
+Set or remove the pre_input_hook function.  If \var{function} is specified,
+it will be used as the new pre_input_hook function; if omitted or
+\code{None}, any hook function already installed is removed.  The
+pre_input_hook function is called with no arguments after the first prompt
+has been printed and just before readline starts reading input characters.
+\end{funcdesc}
+
+\begin{funcdesc}{set_completer}{\optional{function}}
+Set or remove the completer function.  If \var{function} is specified,
+it will be used as the new completer function; if omitted or
+\code{None}, any completer function already installed is removed.  The
+completer function is called as \code{\var{function}(\var{text},
+\var{state})}, for \var{state} in \code{0}, \code{1}, \code{2}, ...,
+until it returns a non-string value.  It should return the next
+possible completion starting with \var{text}.
+\end{funcdesc}
+
+\begin{funcdesc}{get_completer}{}
+Get the completer function, or \code{None} if no completer function
+has been set.  \versionadded{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{get_begidx}{}
+Get the beginning index of the readline tab-completion scope.
+\end{funcdesc}
+
+\begin{funcdesc}{get_endidx}{}
+Get the ending index of the readline tab-completion scope.
+\end{funcdesc}
+
+\begin{funcdesc}{set_completer_delims}{string}
+Set the readline word delimiters for tab-completion.
+\end{funcdesc}
+
+\begin{funcdesc}{get_completer_delims}{}
+Get the readline word delimiters for tab-completion.
+\end{funcdesc}
+
+\begin{funcdesc}{add_history}{line}
+Append a line to the history buffer, as if it was the last line typed.
+\end{funcdesc}
+
+\begin{seealso}
+  \seemodule{rlcompleter}{Completion of Python identifiers at the
+                          interactive prompt.}
+\end{seealso}
+
+
+\subsection{Example \label{readline-example}}
+
+The following example demonstrates how to use the
+\module{readline} module's history reading and writing functions to
+automatically load and save a history file named \file{.pyhist} from
+the user's home directory.  The code below would normally be executed
+automatically during interactive sessions from the user's
+\envvar{PYTHONSTARTUP} file.
+
+\begin{verbatim}
+import os
+histfile = os.path.join(os.environ["HOME"], ".pyhist")
+try:
+    readline.read_history_file(histfile)
+except IOError:
+    pass
+import atexit
+atexit.register(readline.write_history_file, histfile)
+del os, histfile
+\end{verbatim}
+
+The following example extends the \class{code.InteractiveConsole} class to
+support history save/restore.
+
+\begin{verbatim}
+import code
+import readline
+import atexit
+import os
+
+class HistoryConsole(code.InteractiveConsole):
+    def __init__(self, locals=None, filename="<console>",
+                 histfile=os.path.expanduser("~/.console-history")):
+        code.InteractiveConsole.__init__(self)
+        self.init_history(histfile)
+
+    def init_history(self, histfile):
+        readline.parse_and_bind("tab: complete")
+        if hasattr(readline, "read_history_file"):
+            try:
+                readline.read_history_file(histfile)
+            except IOError:
+                pass
+            atexit.register(self.save_history, histfile)
+
+    def save_history(self, histfile):
+        readline.write_history_file(histfile)
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/librepr.tex
===================================================================
--- vendor/Python/current/Doc/lib/librepr.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/librepr.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,133 @@
+\section{\module{repr} ---
+         Alternate \function{repr()} implementation}
+
+\sectionauthor{Fred L. Drake, Jr.}{fdrake at acm.org}
+\declaremodule{standard}{repr}
+\modulesynopsis{Alternate \function{repr()} implementation with size limits.}
+
+
+The \module{repr} module provides a means for producing object
+representations with limits on the size of the resulting strings.
+This is used in the Python debugger and may be useful in other
+contexts as well.
+
+This module provides a class, an instance, and a function:
+
+
+\begin{classdesc}{Repr}{}
+  Class which provides formatting services useful in implementing
+  functions similar to the built-in \function{repr()}; size limits for 
+  different object types are added to avoid the generation of
+  representations which are excessively long.
+\end{classdesc}
+
+
+\begin{datadesc}{aRepr}
+  This is an instance of \class{Repr} which is used to provide the
+  \function{repr()} function described below.  Changing the attributes
+  of this object will affect the size limits used by \function{repr()}
+  and the Python debugger.
+\end{datadesc}
+
+
+\begin{funcdesc}{repr}{obj}
+  This is the \method{repr()} method of \code{aRepr}.  It returns a
+  string similar to that returned by the built-in function of the same 
+  name, but with limits on most sizes.
+\end{funcdesc}
+
+
+\subsection{Repr Objects \label{Repr-objects}}
+
+\class{Repr} instances provide several members which can be used to
+provide size limits for the representations of different object types, 
+and methods which format specific object types.
+
+
+\begin{memberdesc}{maxlevel}
+  Depth limit on the creation of recursive representations.  The
+  default is \code{6}.
+\end{memberdesc}
+
+\begin{memberdesc}{maxdict}
+\memberline{maxlist}
+\memberline{maxtuple}
+\memberline{maxset}
+\memberline{maxfrozenset}
+\memberline{maxdeque}
+\memberline{maxarray}
+  Limits on the number of entries represented for the named object
+  type.  The default is \code{4} for \member{maxdict}, \code{5} for
+  \member{maxarray}, and  \code{6} for the others.
+  \versionadded[\member{maxset}, \member{maxfrozenset},
+  and \member{set}]{2.4}.
+\end{memberdesc}
+
+\begin{memberdesc}{maxlong}
+  Maximum number of characters in the representation for a long
+  integer.  Digits are dropped from the middle.  The default is
+  \code{40}.
+\end{memberdesc}
+
+\begin{memberdesc}{maxstring}
+  Limit on the number of characters in the representation of the
+  string.  Note that the ``normal'' representation of the string is
+  used as the character source: if escape sequences are needed in the
+  representation, these may be mangled when the representation is
+  shortened.  The default is \code{30}.
+\end{memberdesc}
+
+\begin{memberdesc}{maxother}
+  This limit is used to control the size of object types for which no
+  specific formatting method is available on the \class{Repr} object.
+  It is applied in a similar manner as \member{maxstring}.  The
+  default is \code{20}.
+\end{memberdesc}
+
+\begin{methoddesc}{repr}{obj}
+  The equivalent to the built-in \function{repr()} that uses the
+  formatting imposed by the instance.
+\end{methoddesc}
+
+\begin{methoddesc}{repr1}{obj, level}
+  Recursive implementation used by \method{repr()}.  This uses the
+  type of \var{obj} to determine which formatting method to call,
+  passing it \var{obj} and \var{level}.  The type-specific methods
+  should call \method{repr1()} to perform recursive formatting, with
+  \code{\var{level} - 1} for the value of \var{level} in the recursive 
+  call.
+\end{methoddesc}
+
+\begin{methoddescni}{repr_\var{type}}{obj, level}
+  Formatting methods for specific types are implemented as methods
+  with a name based on the type name.  In the method name, \var{type}
+  is replaced by
+  \code{string.join(string.split(type(\var{obj}).__name__, '_'))}.
+  Dispatch to these methods is handled by \method{repr1()}.
+  Type-specific methods which need to recursively format a value
+  should call \samp{self.repr1(\var{subobj}, \var{level} - 1)}.
+\end{methoddescni}
+
+
+\subsection{Subclassing Repr Objects \label{subclassing-reprs}}
+
+The use of dynamic dispatching by \method{Repr.repr1()} allows
+subclasses of \class{Repr} to add support for additional built-in
+object types or to modify the handling of types already supported.
+This example shows how special support for file objects could be
+added:
+
+\begin{verbatim}
+import repr
+import sys
+
+class MyRepr(repr.Repr):
+    def repr_file(self, obj, level):
+        if obj.name in ['<stdin>', '<stdout>', '<stderr>']:
+            return obj.name
+        else:
+            return `obj`
+
+aRepr = MyRepr()
+print aRepr.repr(sys.stdin)          # prints '<stdin>'
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/libresource.tex
===================================================================
--- vendor/Python/current/Doc/lib/libresource.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libresource.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,215 @@
+\section{\module{resource} ---
+         Resource usage information}
+
+\declaremodule{builtin}{resource}
+  \platform{Unix}
+\modulesynopsis{An interface to provide resource usage information on
+  the current process.}
+\moduleauthor{Jeremy Hylton}{jeremy at alum.mit.edu}
+\sectionauthor{Jeremy Hylton}{jeremy at alum.mit.edu}
+
+
+This module provides basic mechanisms for measuring and controlling
+system resources utilized by a program.
+
+Symbolic constants are used to specify particular system resources and
+to request usage information about either the current process or its
+children.
+
+A single exception is defined for errors:
+
+
+\begin{excdesc}{error}
+  The functions described below may raise this error if the underlying
+  system call failures unexpectedly.
+\end{excdesc}
+
+\subsection{Resource Limits}
+
+Resources usage can be limited using the \function{setrlimit()} function
+described below. Each resource is controlled by a pair of limits: a
+soft limit and a hard limit. The soft limit is the current limit, and
+may be lowered or raised by a process over time. The soft limit can
+never exceed the hard limit. The hard limit can be lowered to any
+value greater than the soft limit, but not raised. (Only processes with
+the effective UID of the super-user can raise a hard limit.)
+
+The specific resources that can be limited are system dependent. They
+are described in the \manpage{getrlimit}{2} man page.  The resources
+listed below are supported when the underlying operating system
+supports them; resources which cannot be checked or controlled by the
+operating system are not defined in this module for those platforms.
+
+\begin{funcdesc}{getrlimit}{resource}
+  Returns a tuple \code{(\var{soft}, \var{hard})} with the current
+  soft and hard limits of \var{resource}. Raises \exception{ValueError} if
+  an invalid resource is specified, or \exception{error} if the
+  underlying system call fails unexpectedly.
+\end{funcdesc}
+
+\begin{funcdesc}{setrlimit}{resource, limits}
+  Sets new limits of consumption of \var{resource}. The \var{limits}
+  argument must be a tuple \code{(\var{soft}, \var{hard})} of two
+  integers describing the new limits. A value of \code{-1} can be used to
+  specify the maximum possible upper limit.
+
+  Raises \exception{ValueError} if an invalid resource is specified,
+  if the new soft limit exceeds the hard limit, or if a process tries
+  to raise its hard limit (unless the process has an effective UID of
+  super-user).  Can also raise \exception{error} if the underlying
+  system call fails.
+\end{funcdesc}
+
+These symbols define resources whose consumption can be controlled
+using the \function{setrlimit()} and \function{getrlimit()} functions
+described below. The values of these symbols are exactly the constants
+used by \C{} programs.
+
+The \UNIX{} man page for \manpage{getrlimit}{2} lists the available
+resources.  Note that not all systems use the same symbol or same
+value to denote the same resource.  This module does not attempt to
+mask platform differences --- symbols not defined for a platform will
+not be available from this module on that platform.
+
+\begin{datadesc}{RLIMIT_CORE}
+  The maximum size (in bytes) of a core file that the current process
+  can create.  This may result in the creation of a partial core file
+  if a larger core would be required to contain the entire process
+  image.
+\end{datadesc}
+
+\begin{datadesc}{RLIMIT_CPU}
+  The maximum amount of processor time (in seconds) that a process can
+  use. If this limit is exceeded, a \constant{SIGXCPU} signal is sent to
+  the process. (See the \refmodule{signal} module documentation for
+  information about how to catch this signal and do something useful,
+  e.g. flush open files to disk.)
+\end{datadesc}
+
+\begin{datadesc}{RLIMIT_FSIZE}
+  The maximum size of a file which the process may create.  This only
+  affects the stack of the main thread in a multi-threaded process.
+\end{datadesc}
+
+\begin{datadesc}{RLIMIT_DATA}
+  The maximum size (in bytes) of the process's heap.
+\end{datadesc}
+
+\begin{datadesc}{RLIMIT_STACK}
+  The maximum size (in bytes) of the call stack for the current
+  process.
+\end{datadesc}
+
+\begin{datadesc}{RLIMIT_RSS}
+  The maximum resident set size that should be made available to the
+  process.
+\end{datadesc}
+
+\begin{datadesc}{RLIMIT_NPROC}
+  The maximum number of processes the current process may create.
+\end{datadesc}
+
+\begin{datadesc}{RLIMIT_NOFILE}
+  The maximum number of open file descriptors for the current
+  process.
+\end{datadesc}
+
+\begin{datadesc}{RLIMIT_OFILE}
+  The BSD name for \constant{RLIMIT_NOFILE}.
+\end{datadesc}
+
+\begin{datadesc}{RLIMIT_MEMLOCK}
+  The maximum address space which may be locked in memory.
+\end{datadesc}
+
+\begin{datadesc}{RLIMIT_VMEM}
+  The largest area of mapped memory which the process may occupy.
+\end{datadesc}
+
+\begin{datadesc}{RLIMIT_AS}
+  The maximum area (in bytes) of address space which may be taken by
+  the process.
+\end{datadesc}
+
+\subsection{Resource Usage}
+
+These functions are used to retrieve resource usage information:
+
+\begin{funcdesc}{getrusage}{who}
+  This function returns an object that describes the resources
+  consumed by either the current process or its children, as specified
+  by the \var{who} parameter.  The \var{who} parameter should be
+  specified using one of the \constant{RUSAGE_*} constants described
+  below.
+
+  The fields of the return value each describe how a particular system
+  resource has been used, e.g. amount of time spent running is user mode
+  or number of times the process was swapped out of main memory. Some
+  values are dependent on the clock tick internal, e.g. the amount of
+  memory the process is using.
+
+  For backward compatibility, the return value is also accessible as
+  a tuple of 16 elements.
+
+  The fields \member{ru_utime} and \member{ru_stime} of the return value
+  are floating point values representing the amount of time spent
+  executing in user mode and the amount of time spent executing in system
+  mode, respectively. The remaining values are integers. Consult the
+  \manpage{getrusage}{2} man page for detailed information about these
+  values. A brief summary is presented here:
+
+\begin{tableiii}{r|l|l}{code}{Index}{Field}{Resource}
+  \lineiii{0}{\member{ru_utime}}{time in user mode (float)}
+  \lineiii{1}{\member{ru_stime}}{time in system mode (float)}
+  \lineiii{2}{\member{ru_maxrss}}{maximum resident set size}
+  \lineiii{3}{\member{ru_ixrss}}{shared memory size}
+  \lineiii{4}{\member{ru_idrss}}{unshared memory size}
+  \lineiii{5}{\member{ru_isrss}}{unshared stack size}
+  \lineiii{6}{\member{ru_minflt}}{page faults not requiring I/O}
+  \lineiii{7}{\member{ru_majflt}}{page faults requiring I/O}
+  \lineiii{8}{\member{ru_nswap}}{number of swap outs}
+  \lineiii{9}{\member{ru_inblock}}{block input operations}
+  \lineiii{10}{\member{ru_oublock}}{block output operations}
+  \lineiii{11}{\member{ru_msgsnd}}{messages sent}
+  \lineiii{12}{\member{ru_msgrcv}}{messages received}
+  \lineiii{13}{\member{ru_nsignals}}{signals received}
+  \lineiii{14}{\member{ru_nvcsw}}{voluntary context switches}
+  \lineiii{15}{\member{ru_nivcsw}}{involuntary context switches}
+\end{tableiii}
+
+  This function will raise a \exception{ValueError} if an invalid
+  \var{who} parameter is specified. It may also raise
+  \exception{error} exception in unusual circumstances.
+
+  \versionchanged[Added access to values as attributes of the
+  returned object]{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{getpagesize}{}
+  Returns the number of bytes in a system page. (This need not be the
+  same as the hardware page size.) This function is useful for
+  determining the number of bytes of memory a process is using. The
+  third element of the tuple returned by \function{getrusage()} describes
+  memory usage in pages; multiplying by page size produces number of
+  bytes. 
+\end{funcdesc}
+
+The following \constant{RUSAGE_*} symbols are passed to the
+\function{getrusage()} function to specify which processes information
+should be provided for.
+
+\begin{datadesc}{RUSAGE_SELF}
+  \constant{RUSAGE_SELF} should be used to
+  request information pertaining only to the process itself.
+\end{datadesc}
+
+\begin{datadesc}{RUSAGE_CHILDREN}
+  Pass to \function{getrusage()} to request resource information for
+  child processes of the calling process.
+\end{datadesc}
+
+\begin{datadesc}{RUSAGE_BOTH}
+  Pass to \function{getrusage()} to request resources consumed by both
+  the current process and child processes.  May not be available on all
+  systems.
+\end{datadesc}

Added: vendor/Python/current/Doc/lib/librestricted.tex
===================================================================
--- vendor/Python/current/Doc/lib/librestricted.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/librestricted.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,66 @@
+\chapter{Restricted Execution \label{restricted}}
+
+\begin{notice}[warning]
+   In Python 2.3 these modules have been disabled due to various known
+   and not readily fixable security holes.  The modules are still
+   documented here to help in reading old code that uses the
+   \module{rexec} and \module{Bastion} modules.
+\end{notice}
+
+\emph{Restricted execution} is the basic framework in Python that allows
+for the segregation of trusted and untrusted code.  The framework is based on the
+notion that trusted Python code (a \emph{supervisor}) can create a
+``padded cell' (or environment) with limited permissions, and run the
+untrusted code within this cell.  The untrusted code cannot break out
+of its cell, and can only interact with sensitive system resources
+through interfaces defined and managed by the trusted code.  The term
+``restricted execution'' is favored over ``safe-Python''
+since true safety is hard to define, and is determined by the way the
+restricted environment is created.  Note that the restricted
+environments can be nested, with inner cells creating subcells of
+lesser, but never greater, privilege.
+
+An interesting aspect of Python's restricted execution model is that
+the interfaces presented to untrusted code usually have the same names
+as those presented to trusted code.  Therefore no special interfaces
+need to be learned to write code designed to run in a restricted
+environment.  And because the exact nature of the padded cell is
+determined by the supervisor, different restrictions can be imposed,
+depending on the application.  For example, it might be deemed
+``safe'' for untrusted code to read any file within a specified
+directory, but never to write a file.  In this case, the supervisor
+may redefine the built-in \function{open()} function so that it raises
+an exception whenever the \var{mode} parameter is \code{'w'}.  It
+might also perform a \cfunction{chroot()}-like operation on the
+\var{filename} parameter, such that root is always relative to some
+safe ``sandbox'' area of the filesystem.  In this case, the untrusted
+code would still see an built-in \function{open()} function in its
+environment, with the same calling interface.  The semantics would be
+identical too, with \exception{IOError}s being raised when the
+supervisor determined that an unallowable parameter is being used.
+
+The Python run-time determines whether a particular code block is
+executing in restricted execution mode based on the identity of the
+\code{__builtins__} object in its global variables: if this is (the
+dictionary of) the standard \refmodule[builtin]{__builtin__} module,
+the code is deemed to be unrestricted, else it is deemed to be
+restricted.
+
+Python code executing in restricted mode faces a number of limitations
+that are designed to prevent it from escaping from the padded cell.
+For instance, the function object attribute \member{func_globals} and
+the class and instance object attribute \member{__dict__} are
+unavailable.
+
+Two modules provide the framework for setting up restricted execution
+environments:
+
+\localmoduletable
+
+\begin{seealso}
+  \seetitle[http://grail.sourceforge.net/]{Grail Home Page}
+           {Grail, an Internet browser written in Python, uses these
+            modules to support Python applets.  More
+            information on the use of Python's restricted execution
+            mode in Grail is available on the Web site.}
+\end{seealso}

Added: vendor/Python/current/Doc/lib/librexec.tex
===================================================================
--- vendor/Python/current/Doc/lib/librexec.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/librexec.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,275 @@
+\section{\module{rexec} ---
+         Restricted execution framework}
+
+\declaremodule{standard}{rexec}
+\modulesynopsis{Basic restricted execution framework.}
+\versionchanged[Disabled module]{2.3}
+
+\begin{notice}[warning]
+  The documentation has been left in place to help in reading old code
+  that uses the module.
+\end{notice}
+
+This module contains the \class{RExec} class, which supports
+\method{r_eval()}, \method{r_execfile()}, \method{r_exec()}, and
+\method{r_import()} methods, which are restricted versions of the standard
+Python functions \method{eval()}, \method{execfile()} and
+the \keyword{exec} and \keyword{import} statements.
+Code executed in this restricted environment will
+only have access to modules and functions that are deemed safe; you
+can subclass \class{RExec} to add or remove capabilities as desired.
+
+\begin{notice}[warning]
+  While the \module{rexec} module is designed to perform as described
+  below, it does have a few known vulnerabilities which could be
+  exploited by carefully written code.  Thus it should not be relied
+  upon in situations requiring ``production ready'' security.  In such
+  situations, execution via sub-processes or very careful
+  ``cleansing'' of both code and data to be processed may be
+  necessary.  Alternatively, help in patching known \module{rexec}
+  vulnerabilities would be welcomed.
+\end{notice}
+
+\begin{notice}
+  The \class{RExec} class can prevent code from performing unsafe
+  operations like reading or writing disk files, or using TCP/IP
+  sockets.  However, it does not protect against code using extremely
+  large amounts of memory or processor time.
+\end{notice}
+
+\begin{classdesc}{RExec}{\optional{hooks\optional{, verbose}}}
+Returns an instance of the \class{RExec} class.  
+
+\var{hooks} is an instance of the \class{RHooks} class or a subclass of it.
+If it is omitted or \code{None}, the default \class{RHooks} class is
+instantiated.
+Whenever the \module{rexec} module searches for a module (even a
+built-in one) or reads a module's code, it doesn't actually go out to
+the file system itself.  Rather, it calls methods of an \class{RHooks}
+instance that was passed to or created by its constructor.  (Actually,
+the \class{RExec} object doesn't make these calls --- they are made by
+a module loader object that's part of the \class{RExec} object.  This
+allows another level of flexibility, which can be useful when changing
+the mechanics of \keyword{import} within the restricted environment.)
+
+By providing an alternate \class{RHooks} object, we can control the
+file system accesses made to import a module, without changing the
+actual algorithm that controls the order in which those accesses are
+made.  For instance, we could substitute an \class{RHooks} object that
+passes all filesystem requests to a file server elsewhere, via some
+RPC mechanism such as ILU.  Grail's applet loader uses this to support
+importing applets from a URL for a directory.
+
+If \var{verbose} is true, additional debugging output may be sent to
+standard output.
+\end{classdesc}
+
+It is important to be aware that code running in a restricted
+environment can still call the \function{sys.exit()} function.  To
+disallow restricted code from exiting the interpreter, always protect
+calls that cause restricted code to run with a
+\keyword{try}/\keyword{except} statement that catches the
+\exception{SystemExit} exception.  Removing the \function{sys.exit()}
+function from the restricted environment is not sufficient --- the
+restricted code could still use \code{raise SystemExit}.  Removing
+\exception{SystemExit} is not a reasonable option; some library code
+makes use of this and would break were it not available.
+
+
+\begin{seealso}
+  \seetitle[http://grail.sourceforge.net/]{Grail Home Page}{Grail is a
+            Web browser written entirely in Python.  It uses the
+            \module{rexec} module as a foundation for supporting
+            Python applets, and can be used as an example usage of
+            this module.}
+\end{seealso}
+
+
+\subsection{RExec Objects \label{rexec-objects}}
+
+\class{RExec} instances support the following methods:
+
+\begin{methoddesc}{r_eval}{code}
+\var{code} must either be a string containing a Python expression, or
+a compiled code object, which will be evaluated in the restricted
+environment's \module{__main__} module.  The value of the expression or
+code object will be returned.
+\end{methoddesc}
+
+\begin{methoddesc}{r_exec}{code}
+\var{code} must either be a string containing one or more lines of
+Python code, or a compiled code object, which will be executed in the
+restricted environment's \module{__main__} module.
+\end{methoddesc}
+
+\begin{methoddesc}{r_execfile}{filename}
+Execute the Python code contained in the file \var{filename} in the
+restricted environment's \module{__main__} module.
+\end{methoddesc}
+
+Methods whose names begin with \samp{s_} are similar to the functions
+beginning with \samp{r_}, but the code will be granted access to
+restricted versions of the standard I/O streams \code{sys.stdin},
+\code{sys.stderr}, and \code{sys.stdout}.
+
+\begin{methoddesc}{s_eval}{code}
+\var{code} must be a string containing a Python expression, which will
+be evaluated in the restricted environment.  
+\end{methoddesc}
+
+\begin{methoddesc}{s_exec}{code}
+\var{code} must be a string containing one or more lines of Python code,
+which will be executed in the restricted environment.  
+\end{methoddesc}
+
+\begin{methoddesc}{s_execfile}{code}
+Execute the Python code contained in the file \var{filename} in the
+restricted environment.
+\end{methoddesc}
+
+\class{RExec} objects must also support various methods which will be
+implicitly called by code executing in the restricted environment.
+Overriding these methods in a subclass is used to change the policies
+enforced by a restricted environment.
+
+\begin{methoddesc}{r_import}{modulename\optional{, globals\optional{,
+                             locals\optional{, fromlist}}}}
+Import the module \var{modulename}, raising an \exception{ImportError}
+exception if the module is considered unsafe.
+\end{methoddesc}
+
+\begin{methoddesc}{r_open}{filename\optional{, mode\optional{, bufsize}}}
+Method called when \function{open()} is called in the restricted
+environment.  The arguments are identical to those of \function{open()},
+and a file object (or a class instance compatible with file objects)
+should be returned.  \class{RExec}'s default behaviour is allow opening
+any file for reading, but forbidding any attempt to write a file.  See
+the example below for an implementation of a less restrictive
+\method{r_open()}.
+\end{methoddesc}
+
+\begin{methoddesc}{r_reload}{module}
+Reload the module object \var{module}, re-parsing and re-initializing it.  
+\end{methoddesc}
+
+\begin{methoddesc}{r_unload}{module}
+Unload the module object \var{module} (remove it from the
+restricted environment's \code{sys.modules} dictionary).
+\end{methoddesc}
+
+And their equivalents with access to restricted standard I/O streams:
+
+\begin{methoddesc}{s_import}{modulename\optional{, globals\optional{,
+                             locals\optional{, fromlist}}}}
+Import the module \var{modulename}, raising an \exception{ImportError}
+exception if the module is considered unsafe.
+\end{methoddesc}
+
+\begin{methoddesc}{s_reload}{module}
+Reload the module object \var{module}, re-parsing and re-initializing it.  
+\end{methoddesc}
+
+\begin{methoddesc}{s_unload}{module}
+Unload the module object \var{module}.   
+% XXX what are the semantics of this?  
+\end{methoddesc}
+
+
+\subsection{Defining restricted environments \label{rexec-extension}}
+
+The \class{RExec} class has the following class attributes, which are
+used by the \method{__init__()} method.  Changing them on an existing
+instance won't have any effect; instead, create a subclass of
+\class{RExec} and assign them new values in the class definition.
+Instances of the new class will then use those new values.  All these
+attributes are tuples of strings.
+
+\begin{memberdesc}{nok_builtin_names}
+Contains the names of built-in functions which will \emph{not} be
+available to programs running in the restricted environment.  The
+value for \class{RExec} is \code{('open', 'reload', '__import__')}.
+(This gives the exceptions, because by far the majority of built-in
+functions are harmless.  A subclass that wants to override this
+variable should probably start with the value from the base class and
+concatenate additional forbidden functions --- when new dangerous
+built-in functions are added to Python, they will also be added to
+this module.)
+\end{memberdesc}
+
+\begin{memberdesc}{ok_builtin_modules}
+Contains the names of built-in modules which can be safely imported.
+The value for \class{RExec} is \code{('audioop', 'array', 'binascii',
+'cmath', 'errno', 'imageop', 'marshal', 'math', 'md5', 'operator',
+'parser', 'regex', 'select', 'sha', '_sre', 'strop',
+'struct', 'time')}.  A similar remark about overriding this variable
+applies --- use the value from the base class as a starting point.
+\end{memberdesc}
+
+\begin{memberdesc}{ok_path}
+Contains the directories which will be searched when an \keyword{import}
+is performed in the restricted environment.  
+The value for \class{RExec} is the same as \code{sys.path} (at the time
+the module is loaded) for unrestricted code.
+\end{memberdesc}
+
+\begin{memberdesc}{ok_posix_names}
+% Should this be called ok_os_names?
+Contains the names of the functions in the \refmodule{os} module which will be
+available to programs running in the restricted environment.  The
+value for \class{RExec} is \code{('error', 'fstat', 'listdir',
+'lstat', 'readlink', 'stat', 'times', 'uname', 'getpid', 'getppid',
+'getcwd', 'getuid', 'getgid', 'geteuid', 'getegid')}.
+\end{memberdesc}
+
+\begin{memberdesc}{ok_sys_names}
+Contains the names of the functions and variables in the \refmodule{sys}
+module which will be available to programs running in the restricted
+environment.  The value for \class{RExec} is \code{('ps1', 'ps2',
+'copyright', 'version', 'platform', 'exit', 'maxint')}.
+\end{memberdesc}
+
+\begin{memberdesc}{ok_file_types}
+Contains the file types from which modules are allowed to be loaded.
+Each file type is an integer constant defined in the \refmodule{imp} module.
+The meaningful values are \constant{PY_SOURCE}, \constant{PY_COMPILED}, and
+\constant{C_EXTENSION}.  The value for \class{RExec} is \code{(C_EXTENSION,
+PY_SOURCE)}.  Adding \constant{PY_COMPILED} in subclasses is not recommended;
+an attacker could exit the restricted execution mode by putting a forged
+byte-compiled file (\file{.pyc}) anywhere in your file system, for example
+by writing it to \file{/tmp} or uploading it to the \file{/incoming}
+directory of your public FTP server.
+\end{memberdesc}
+
+
+\subsection{An example}
+
+Let us say that we want a slightly more relaxed policy than the
+standard \class{RExec} class.  For example, if we're willing to allow
+files in \file{/tmp} to be written, we can subclass the \class{RExec}
+class:
+
+\begin{verbatim}
+class TmpWriterRExec(rexec.RExec):
+    def r_open(self, file, mode='r', buf=-1):
+        if mode in ('r', 'rb'):
+            pass
+        elif mode in ('w', 'wb', 'a', 'ab'):
+            # check filename : must begin with /tmp/
+            if file[:5]!='/tmp/': 
+                raise IOError, "can't write outside /tmp"
+            elif (string.find(file, '/../') >= 0 or
+                 file[:3] == '../' or file[-3:] == '/..'):
+                raise IOError, "'..' in filename forbidden"
+        else: raise IOError, "Illegal open() mode"
+        return open(file, mode, buf)
+\end{verbatim}
+%
+Notice that the above code will occasionally forbid a perfectly valid
+filename; for example, code in the restricted environment won't be
+able to open a file called \file{/tmp/foo/../bar}.  To fix this, the
+\method{r_open()} method would have to simplify the filename to
+\file{/tmp/bar}, which would require splitting apart the filename and
+performing various operations on it.  In cases where security is at
+stake, it may be preferable to write simple code which is sometimes
+overly restrictive, instead of more general code that is also more
+complex and may harbor a subtle security hole.

Added: vendor/Python/current/Doc/lib/librfc822.tex
===================================================================
--- vendor/Python/current/Doc/lib/librfc822.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/librfc822.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,336 @@
+\section{\module{rfc822} ---
+         Parse RFC 2822 mail headers}
+
+\declaremodule{standard}{rfc822}
+\modulesynopsis{Parse \rfc{2822} style mail messages.}
+
+\deprecated{2.3}{The \refmodule{email} package should be used in
+                 preference to the \module{rfc822} module.  This
+                 module is present only to maintain backward
+                 compatibility.}
+
+This module defines a class, \class{Message}, which represents an
+``email message'' as defined by the Internet standard
+\rfc{2822}.\footnote{This module originally conformed to \rfc{822},
+hence the name.  Since then, \rfc{2822} has been released as an
+update to \rfc{822}.  This module should be considered
+\rfc{2822}-conformant, especially in cases where the
+syntax or semantics have changed since \rfc{822}.}  Such messages
+consist of a collection of message headers, and a message body.  This
+module also defines a helper class
+\class{AddressList} for parsing \rfc{2822} addresses.  Please refer to
+the RFC for information on the specific syntax of \rfc{2822} messages.
+
+The \refmodule{mailbox}\refstmodindex{mailbox} module provides classes 
+to read mailboxes produced by various end-user mail programs.
+
+\begin{classdesc}{Message}{file\optional{, seekable}}
+A \class{Message} instance is instantiated with an input object as
+parameter.  Message relies only on the input object having a
+\method{readline()} method; in particular, ordinary file objects
+qualify.  Instantiation reads headers from the input object up to a
+delimiter line (normally a blank line) and stores them in the
+instance.  The message body, following the headers, is not consumed.
+
+This class can work with any input object that supports a
+\method{readline()} method.  If the input object has seek and tell
+capability, the \method{rewindbody()} method will work; also, illegal
+lines will be pushed back onto the input stream.  If the input object
+lacks seek but has an \method{unread()} method that can push back a
+line of input, \class{Message} will use that to push back illegal
+lines.  Thus this class can be used to parse messages coming from a
+buffered stream.
+
+The optional \var{seekable} argument is provided as a workaround for
+certain stdio libraries in which \cfunction{tell()} discards buffered
+data before discovering that the \cfunction{lseek()} system call
+doesn't work.  For maximum portability, you should set the seekable
+argument to zero to prevent that initial \method{tell()} when passing
+in an unseekable object such as a file object created from a socket
+object.
+
+Input lines as read from the file may either be terminated by CR-LF or
+by a single linefeed; a terminating CR-LF is replaced by a single
+linefeed before the line is stored.
+
+All header matching is done independent of upper or lower case;
+e.g.\ \code{\var{m}['From']}, \code{\var{m}['from']} and
+\code{\var{m}['FROM']} all yield the same result.
+\end{classdesc}
+
+\begin{classdesc}{AddressList}{field}
+You may instantiate the \class{AddressList} helper class using a single
+string parameter, a comma-separated list of \rfc{2822} addresses to be
+parsed.  (The parameter \code{None} yields an empty list.)
+\end{classdesc}
+
+\begin{funcdesc}{quote}{str}
+Return a new string with backslashes in \var{str} replaced by two
+backslashes and double quotes replaced by backslash-double quote.
+\end{funcdesc}
+
+\begin{funcdesc}{unquote}{str}
+Return a new string which is an \emph{unquoted} version of \var{str}.
+If \var{str} ends and begins with double quotes, they are stripped
+off.  Likewise if \var{str} ends and begins with angle brackets, they
+are stripped off.
+\end{funcdesc}
+
+\begin{funcdesc}{parseaddr}{address}
+Parse \var{address}, which should be the value of some
+address-containing field such as \mailheader{To} or \mailheader{Cc},
+into its constituent ``realname'' and ``email address'' parts.
+Returns a tuple of that information, unless the parse fails, in which
+case a 2-tuple \code{(None, None)} is returned.
+\end{funcdesc}
+
+\begin{funcdesc}{dump_address_pair}{pair}
+The inverse of \method{parseaddr()}, this takes a 2-tuple of the form
+\code{(\var{realname}, \var{email_address})} and returns the string
+value suitable for a \mailheader{To} or \mailheader{Cc} header.  If
+the first element of \var{pair} is false, then the second element is
+returned unmodified.
+\end{funcdesc}
+
+\begin{funcdesc}{parsedate}{date}
+Attempts to parse a date according to the rules in \rfc{2822}.
+however, some mailers don't follow that format as specified, so
+\function{parsedate()} tries to guess correctly in such cases. 
+\var{date} is a string containing an \rfc{2822} date, such as 
+\code{'Mon, 20 Nov 1995 19:12:08 -0500'}.  If it succeeds in parsing
+the date, \function{parsedate()} returns a 9-tuple that can be passed
+directly to \function{time.mktime()}; otherwise \code{None} will be
+returned.  Note that fields 6, 7, and 8 of the result tuple are not
+usable.
+\end{funcdesc}
+
+\begin{funcdesc}{parsedate_tz}{date}
+Performs the same function as \function{parsedate()}, but returns
+either \code{None} or a 10-tuple; the first 9 elements make up a tuple
+that can be passed directly to \function{time.mktime()}, and the tenth
+is the offset of the date's timezone from UTC (which is the official
+term for Greenwich Mean Time).  (Note that the sign of the timezone
+offset is the opposite of the sign of the \code{time.timezone}
+variable for the same timezone; the latter variable follows the
+\POSIX{} standard while this module follows \rfc{2822}.)  If the input
+string has no timezone, the last element of the tuple returned is
+\code{None}.  Note that fields 6, 7, and 8 of the result tuple are not
+usable.
+\end{funcdesc}
+
+\begin{funcdesc}{mktime_tz}{tuple}
+Turn a 10-tuple as returned by \function{parsedate_tz()} into a UTC
+timestamp.  If the timezone item in the tuple is \code{None}, assume
+local time.  Minor deficiency: this first interprets the first 8
+elements as a local time and then compensates for the timezone
+difference; this may yield a slight error around daylight savings time
+switch dates.  Not enough to worry about for common use.
+\end{funcdesc}
+
+
+\begin{seealso}
+  \seemodule{email}{Comprehensive email handling package; supersedes
+                    the \module{rfc822} module.}
+  \seemodule{mailbox}{Classes to read various mailbox formats produced 
+                      by end-user mail programs.}
+  \seemodule{mimetools}{Subclass of \class{rfc822.Message} that
+                        handles MIME encoded messages.} 
+\end{seealso}
+
+
+\subsection{Message Objects \label{message-objects}}
+
+A \class{Message} instance has the following methods:
+
+\begin{methoddesc}{rewindbody}{}
+Seek to the start of the message body.  This only works if the file
+object is seekable.
+\end{methoddesc}
+
+\begin{methoddesc}{isheader}{line}
+Returns a line's canonicalized fieldname (the dictionary key that will
+be used to index it) if the line is a legal \rfc{2822} header; otherwise
+returns \code{None} (implying that parsing should stop here and the
+line be pushed back on the input stream).  It is sometimes useful to
+override this method in a subclass.
+\end{methoddesc}
+
+\begin{methoddesc}{islast}{line}
+Return true if the given line is a delimiter on which Message should
+stop.  The delimiter line is consumed, and the file object's read
+location positioned immediately after it.  By default this method just
+checks that the line is blank, but you can override it in a subclass.
+\end{methoddesc}
+
+\begin{methoddesc}{iscomment}{line}
+Return \code{True} if the given line should be ignored entirely, just skipped.
+By default this is a stub that always returns \code{False}, but you can
+override it in a subclass.
+\end{methoddesc}
+
+\begin{methoddesc}{getallmatchingheaders}{name}
+Return a list of lines consisting of all headers matching
+\var{name}, if any.  Each physical line, whether it is a continuation
+line or not, is a separate list item.  Return the empty list if no
+header matches \var{name}.
+\end{methoddesc}
+
+\begin{methoddesc}{getfirstmatchingheader}{name}
+Return a list of lines comprising the first header matching
+\var{name}, and its continuation line(s), if any.  Return
+\code{None} if there is no header matching \var{name}.
+\end{methoddesc}
+
+\begin{methoddesc}{getrawheader}{name}
+Return a single string consisting of the text after the colon in the
+first header matching \var{name}.  This includes leading whitespace,
+the trailing linefeed, and internal linefeeds and whitespace if there
+any continuation line(s) were present.  Return \code{None} if there is
+no header matching \var{name}.
+\end{methoddesc}
+
+\begin{methoddesc}{getheader}{name\optional{, default}}
+Like \code{getrawheader(\var{name})}, but strip leading and trailing
+whitespace.  Internal whitespace is not stripped.  The optional
+\var{default} argument can be used to specify a different default to
+be returned when there is no header matching \var{name}.
+\end{methoddesc}
+
+\begin{methoddesc}{get}{name\optional{, default}}
+An alias for \method{getheader()}, to make the interface more compatible 
+with regular dictionaries.
+\end{methoddesc}
+
+\begin{methoddesc}{getaddr}{name}
+Return a pair \code{(\var{full name}, \var{email address})} parsed
+from the string returned by \code{getheader(\var{name})}.  If no
+header matching \var{name} exists, return \code{(None, None)};
+otherwise both the full name and the address are (possibly empty)
+strings.
+
+Example: If \var{m}'s first \mailheader{From} header contains the
+string \code{'jack at cwi.nl (Jack Jansen)'}, then
+\code{m.getaddr('From')} will yield the pair
+\code{('Jack Jansen', 'jack at cwi.nl')}.
+If the header contained
+\code{'Jack Jansen <jack at cwi.nl>'} instead, it would yield the
+exact same result.
+\end{methoddesc}
+
+\begin{methoddesc}{getaddrlist}{name}
+This is similar to \code{getaddr(\var{list})}, but parses a header
+containing a list of email addresses (e.g.\ a \mailheader{To} header) and
+returns a list of \code{(\var{full name}, \var{email address})} pairs
+(even if there was only one address in the header).  If there is no
+header matching \var{name}, return an empty list.
+
+If multiple headers exist that match the named header (e.g. if there
+are several \mailheader{Cc} headers), all are parsed for addresses.
+Any continuation lines the named headers contain are also parsed.
+\end{methoddesc}
+
+\begin{methoddesc}{getdate}{name}
+Retrieve a header using \method{getheader()} and parse it into a 9-tuple
+compatible with \function{time.mktime()}; note that fields 6, 7, and 8 
+are not usable.  If there is no header matching
+\var{name}, or it is unparsable, return \code{None}.
+
+Date parsing appears to be a black art, and not all mailers adhere to
+the standard.  While it has been tested and found correct on a large
+collection of email from many sources, it is still possible that this
+function may occasionally yield an incorrect result.
+\end{methoddesc}
+
+\begin{methoddesc}{getdate_tz}{name}
+Retrieve a header using \method{getheader()} and parse it into a
+10-tuple; the first 9 elements will make a tuple compatible with
+\function{time.mktime()}, and the 10th is a number giving the offset
+of the date's timezone from UTC.  Note that fields 6, 7, and 8 
+are not usable.  Similarly to \method{getdate()}, if
+there is no header matching \var{name}, or it is unparsable, return
+\code{None}. 
+\end{methoddesc}
+
+\class{Message} instances also support a limited mapping interface.
+In particular: \code{\var{m}[name]} is like
+\code{\var{m}.getheader(name)} but raises \exception{KeyError} if
+there is no matching header; and \code{len(\var{m})},
+\code{\var{m}.get(\var{name}\optional{, \var{default}})},
+\code{\var{m}.has_key(\var{name})}, \code{\var{m}.keys()},
+\code{\var{m}.values()} \code{\var{m}.items()}, and
+\code{\var{m}.setdefault(\var{name}\optional{, \var{default}})} act as
+expected, with the one difference that \method{setdefault()} uses
+an empty string as the default value.  \class{Message} instances
+also support the mapping writable interface \code{\var{m}[name] =
+value} and \code{del \var{m}[name]}.  \class{Message} objects do not
+support the \method{clear()}, \method{copy()}, \method{popitem()}, or
+\method{update()} methods of the mapping interface.  (Support for
+\method{get()} and \method{setdefault()} was only added in Python
+2.2.)
+
+Finally, \class{Message} instances have some public instance variables:
+
+\begin{memberdesc}{headers}
+A list containing the entire set of header lines, in the order in
+which they were read (except that setitem calls may disturb this
+order). Each line contains a trailing newline.  The
+blank line terminating the headers is not contained in the list.
+\end{memberdesc}
+
+\begin{memberdesc}{fp}
+The file or file-like object passed at instantiation time.  This can
+be used to read the message content.
+\end{memberdesc}
+
+\begin{memberdesc}{unixfrom}
+The \UNIX{} \samp{From~} line, if the message had one, or an empty
+string.  This is needed to regenerate the message in some contexts,
+such as an \code{mbox}-style mailbox file.
+\end{memberdesc}
+
+
+\subsection{AddressList Objects \label{addresslist-objects}}
+
+An \class{AddressList} instance has the following methods:
+
+\begin{methoddesc}{__len__}{}
+Return the number of addresses in the address list.
+\end{methoddesc}
+
+\begin{methoddesc}{__str__}{}
+Return a canonicalized string representation of the address list.
+Addresses are rendered in "name" <host at domain> form, comma-separated.
+\end{methoddesc}
+
+\begin{methoddesc}{__add__}{alist}
+Return a new \class{AddressList} instance that contains all addresses
+in both \class{AddressList} operands, with duplicates removed (set
+union).
+\end{methoddesc}
+
+\begin{methoddesc}{__iadd__}{alist}
+In-place version of \method{__add__()}; turns this \class{AddressList}
+instance into the union of itself and the right-hand instance,
+\var{alist}.
+\end{methoddesc}
+
+\begin{methoddesc}{__sub__}{alist}
+Return a new \class{AddressList} instance that contains every address
+in the left-hand \class{AddressList} operand that is not present in
+the right-hand address operand (set difference).
+\end{methoddesc}
+
+\begin{methoddesc}{__isub__}{alist}
+In-place version of \method{__sub__()}, removing addresses in this
+list which are also in \var{alist}.
+\end{methoddesc}
+
+
+Finally, \class{AddressList} instances have one public instance variable:
+
+\begin{memberdesc}{addresslist}
+A list of tuple string pairs, one per address.  In each member, the
+first is the canonicalized name part, the second is the
+actual route-address (\character{@}-separated username-host.domain
+pair).
+\end{memberdesc}

Added: vendor/Python/current/Doc/lib/librgbimg.tex
===================================================================
--- vendor/Python/current/Doc/lib/librgbimg.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/librgbimg.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,54 @@
+\section{\module{rgbimg} ---
+         Read and write ``SGI RGB'' files}
+
+\declaremodule{builtin}{rgbimg}
+\modulesynopsis{Read and write image files in ``SGI RGB'' format (the module
+                is \emph{not} SGI specific though!).}
+
+\deprecated{2.5}{This module is not maintained anymore and seems to be
+                 unused.}
+
+The \module{rgbimg} module allows Python programs to access SGI imglib image
+files (also known as \file{.rgb} files).  The module is far from
+complete, but is provided anyway since the functionality that there is
+enough in some cases.  Currently, colormap files are not supported.
+
+\note{This module is only built by default for 32-bit platforms; it is
+not expected to work properly on other systems.}
+
+The module defines the following variables and functions:
+
+\begin{excdesc}{error}
+This exception is raised on all errors, such as unsupported file type, etc.
+\end{excdesc}
+
+\begin{funcdesc}{sizeofimage}{file}
+This function returns a tuple \code{(\var{x}, \var{y})} where
+\var{x} and \var{y} are the size of the image in pixels.
+Only 4 byte RGBA pixels, 3 byte RGB pixels, and 1 byte greyscale pixels
+are currently supported.
+\end{funcdesc}
+
+\begin{funcdesc}{longimagedata}{file}
+This function reads and decodes the image on the specified file, and
+returns it as a Python string. The string has 4 byte RGBA pixels.
+The bottom left pixel is the first in
+the string. This format is suitable to pass to \function{gl.lrectwrite()},
+for instance.
+\end{funcdesc}
+
+\begin{funcdesc}{longstoimage}{data, x, y, z, file}
+This function writes the RGBA data in \var{data} to image
+file \var{file}. \var{x} and \var{y} give the size of the image.
+\var{z} is 1 if the saved image should be 1 byte greyscale, 3 if the
+saved image should be 3 byte RGB data, or 4 if the saved images should
+be 4 byte RGBA data.  The input data always contains 4 bytes per pixel.
+These are the formats returned by \function{gl.lrectread()}.
+\end{funcdesc}
+
+\begin{funcdesc}{ttob}{flag}
+This function sets a global flag which defines whether the scan lines
+of the image are read or written from bottom to top (flag is zero,
+compatible with SGI GL) or from top to bottom (flag is one,
+compatible with X).  The default is zero.
+\end{funcdesc}

Added: vendor/Python/current/Doc/lib/librlcompleter.tex
===================================================================
--- vendor/Python/current/Doc/lib/librlcompleter.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/librlcompleter.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,65 @@
+\section{\module{rlcompleter} ---
+         Completion function for GNU readline}
+
+\declaremodule{standard}{rlcompleter}
+\sectionauthor{Moshe Zadka}{moshez at zadka.site.co.il}
+\modulesynopsis{Python identifier completion, suitable for the GNU readline library.}
+
+The \module{rlcompleter} module defines a completion function suitable for
+the \refmodule{readline} module by completing valid Python identifiers
+and keywords.
+
+When this module is imported on a \UNIX\ platform with the \module{readline}
+module available, an instance of the \class{Completer} class is automatically
+created and its \method{complete} method is set as the \module{readline}
+completer.
+
+Example:
+
+\begin{verbatim}
+>>> import rlcompleter
+>>> import readline
+>>> readline.parse_and_bind("tab: complete")
+>>> readline. <TAB PRESSED>
+readline.__doc__          readline.get_line_buffer  readline.read_init_file
+readline.__file__         readline.insert_text      readline.set_completer
+readline.__name__         readline.parse_and_bind
+>>> readline.
+\end{verbatim}
+
+The \module{rlcompleter} module is designed for use with Python's
+interactive mode.  A user can add the following lines to his or her
+initialization file (identified by the \envvar{PYTHONSTARTUP}
+environment variable) to get automatic \kbd{Tab} completion:
+
+\begin{verbatim}
+try:
+    import readline
+except ImportError:
+    print "Module readline not available."
+else:
+    import rlcompleter
+    readline.parse_and_bind("tab: complete")
+\end{verbatim}
+
+
+On platforms without \module{readline}, the \class{Completer} class defined
+by this module can still be used for custom purposes.
+
+\subsection{Completer Objects \label{completer-objects}}
+
+Completer objects have the following method:
+
+\begin{methoddesc}[Completer]{complete}{text, state}
+Return the \var{state}th completion for \var{text}.
+
+If called for \var{text} that doesn't include a period character
+(\character{.}), it will complete from names currently defined in
+\refmodule[main]{__main__}, \refmodule[builtin]{__builtin__} and
+keywords (as defined by the \refmodule{keyword} module).
+
+If called for a dotted name, it will try to evaluate anything without
+obvious side-effects (functions will not be evaluated, but it
+can generate calls to \method{__getattr__()}) up to the last part, and
+find matches for the rest via the \function{dir()} function.
+\end{methoddesc}

Added: vendor/Python/current/Doc/lib/librobotparser.tex
===================================================================
--- vendor/Python/current/Doc/lib/librobotparser.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/librobotparser.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,66 @@
+\section{\module{robotparser} --- 
+         Parser for robots.txt}
+
+\declaremodule{standard}{robotparser}
+\modulesynopsis{Loads a \protect\file{robots.txt} file and
+                answers questions about fetchability of other URLs.}
+\sectionauthor{Skip Montanaro}{skip at mojam.com}
+
+\index{WWW}
+\index{World Wide Web}
+\index{URL}
+\index{robots.txt}
+
+This module provides a single class, \class{RobotFileParser}, which answers
+questions about whether or not a particular user agent can fetch a URL on
+the Web site that published the \file{robots.txt} file.  For more details on 
+the structure of \file{robots.txt} files, see
+\url{http://www.robotstxt.org/wc/norobots.html}. 
+
+\begin{classdesc}{RobotFileParser}{}
+
+This class provides a set of methods to read, parse and answer questions
+about a single \file{robots.txt} file.
+
+\begin{methoddesc}{set_url}{url}
+Sets the URL referring to a \file{robots.txt} file.
+\end{methoddesc}
+
+\begin{methoddesc}{read}{}
+Reads the \file{robots.txt} URL and feeds it to the parser.
+\end{methoddesc}
+
+\begin{methoddesc}{parse}{lines}
+Parses the lines argument.
+\end{methoddesc}
+
+\begin{methoddesc}{can_fetch}{useragent, url}
+Returns \code{True} if the \var{useragent} is allowed to fetch the \var{url}
+according to the rules contained in the parsed \file{robots.txt} file.
+\end{methoddesc}
+
+\begin{methoddesc}{mtime}{}
+Returns the time the \code{robots.txt} file was last fetched.  This is
+useful for long-running web spiders that need to check for new
+\code{robots.txt} files periodically.
+\end{methoddesc}
+
+\begin{methoddesc}{modified}{}
+Sets the time the \code{robots.txt} file was last fetched to the current
+time.
+\end{methoddesc}
+
+\end{classdesc}
+
+The following example demonstrates basic use of the RobotFileParser class.
+
+\begin{verbatim}
+>>> import robotparser
+>>> rp = robotparser.RobotFileParser()
+>>> rp.set_url("http://www.musi-cal.com/robots.txt")
+>>> rp.read()
+>>> rp.can_fetch("*", "http://www.musi-cal.com/cgi-bin/search?city=San+Francisco")
+False
+>>> rp.can_fetch("*", "http://www.musi-cal.com/")
+True
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/librunpy.tex
===================================================================
--- vendor/Python/current/Doc/lib/librunpy.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/librunpy.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,74 @@
+\section{\module{runpy} ---
+         Locating and executing Python modules.}
+
+\declaremodule{standard}{runpy}		% standard library, in Python
+
+\moduleauthor{Nick Coghlan}{ncoghlan at gmail.com}
+
+\modulesynopsis{Locate and execute Python modules as scripts}
+
+\versionadded{2.5}
+
+The \module{runpy} module is used to locate and run Python modules
+without importing them first. Its main use is to implement the
+\programopt{-m} command line switch that allows scripts to be located
+using the Python module namespace rather than the filesystem.
+
+When executed as a script, the module effectively operates as follows:
+\begin{verbatim}
+    del sys.argv[0]  # Remove the runpy module from the arguments
+    run_module(sys.argv[0], run_name="__main__", alter_sys=True)
+\end{verbatim}
+
+The \module{runpy} module provides a single function:
+
+\begin{funcdesc}{run_module}{mod_name\optional{, init_globals}
+\optional{, run_name}\optional{, alter_sys}}
+Execute the code of the specified module and return the resulting
+module globals dictionary. The module's code is first located using
+the standard import mechanism (refer to PEP 302 for details) and
+then executed in a fresh module namespace.
+
+The optional dictionary argument \var{init_globals} may be used to
+pre-populate the globals dictionary before the code is executed.
+The supplied dictionary will not be modified. If any of the special
+global variables below are defined in the supplied dictionary, those
+definitions are overridden by the \code{run_module} function.
+
+The special global variables \code{__name__}, \code{__file__},
+\code{__loader__} and \code{__builtins__} are set in the globals
+dictionary before the module code is executed.
+
+\code{__name__} is set to \var{run_name} if this optional argument is
+supplied, and the \var{mod_name} argument otherwise.
+
+\code{__loader__} is set to the PEP 302 module loader used to retrieve
+the code for the module (This loader may be a wrapper around the
+standard import mechanism).
+
+\code{__file__} is set to the name provided by the module loader. If
+the loader does not make filename information available, this
+variable is set to \code{None}.
+
+\code{__builtins__} is automatically initialised with a reference to
+the top level namespace of the \module{__builtin__} module.
+
+If the argument \var{alter_sys} is supplied and evaluates to
+\code{True}, then \code{sys.argv[0]} is updated with the value of
+\code{__file__} and \code{sys.modules[__name__]} is updated with a
+temporary module object for the module being executed. Both
+\code{sys.argv[0]} and \code{sys.modules[__name__]} are restored to
+their original values before the function returns.
+
+Note that this manipulation of \module{sys} is not thread-safe. Other
+threads may see the partially initialised module, as well as the
+altered list of arguments. It is recommended that the \module{sys}
+module be left alone when invoking this function from threaded code.
+\end{funcdesc}
+
+\begin{seealso}
+
+\seepep{338}{Executing modules as scripts}{PEP written and 
+implemented by Nick Coghlan.}
+
+\end{seealso}

Added: vendor/Python/current/Doc/lib/libsched.tex
===================================================================
--- vendor/Python/current/Doc/lib/libsched.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libsched.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,97 @@
+\section{\module{sched} ---
+         Event scheduler}
+
+% LaTeXed and enhanced from comments in file
+
+\declaremodule{standard}{sched}
+\sectionauthor{Moshe Zadka}{moshez at zadka.site.co.il}
+\modulesynopsis{General purpose event scheduler.}
+
+The \module{sched} module defines a class which implements a general
+purpose event scheduler:\index{event scheduling}
+
+\begin{classdesc}{scheduler}{timefunc, delayfunc}
+The \class{scheduler} class defines a generic interface to scheduling
+events. It needs two functions to actually deal with the ``outside world''
+--- \var{timefunc} should be callable without arguments, and return 
+a number (the ``time'', in any units whatsoever).  The \var{delayfunc}
+function should be callable with one argument, compatible with the output
+of \var{timefunc}, and should delay that many time units.
+\var{delayfunc} will also be called with the argument \code{0} after
+each event is run to allow other threads an opportunity to run in
+multi-threaded applications.
+\end{classdesc}
+
+Example:
+
+\begin{verbatim}
+>>> import sched, time
+>>> s=sched.scheduler(time.time, time.sleep)
+>>> def print_time(): print "From print_time", time.time()
+...
+>>> def print_some_times():
+...     print time.time()
+...     s.enter(5, 1, print_time, ())
+...     s.enter(10, 1, print_time, ())
+...     s.run()
+...     print time.time()
+...
+>>> print_some_times()
+930343690.257
+From print_time 930343695.274
+From print_time 930343700.273
+930343700.276
+\end{verbatim}
+
+
+\subsection{Scheduler Objects \label{scheduler-objects}}
+
+\class{scheduler} instances have the following methods:
+
+\begin{methoddesc}{enterabs}{time, priority, action, argument}
+Schedule a new event. The \var{time} argument should be a numeric type
+compatible with the return value of the \var{timefunc} function passed 
+to the constructor. Events scheduled for
+the same \var{time} will be executed in the order of their
+\var{priority}.
+
+Executing the event means executing
+\code{\var{action}(*\var{argument})}.  \var{argument} must be a
+sequence holding the parameters for \var{action}.
+
+Return value is an event which may be used for later cancellation of
+the event (see \method{cancel()}).
+\end{methoddesc}
+
+\begin{methoddesc}{enter}{delay, priority, action, argument}
+Schedule an event for \var{delay} more time units. Other then the
+relative time, the other arguments, the effect and the return value
+are the same as those for \method{enterabs()}.
+\end{methoddesc}
+
+\begin{methoddesc}{cancel}{event}
+Remove the event from the queue. If \var{event} is not an event
+currently in the queue, this method will raise a
+\exception{RuntimeError}.
+\end{methoddesc}
+
+\begin{methoddesc}{empty}{}
+Return true if the event queue is empty.
+\end{methoddesc}
+
+\begin{methoddesc}{run}{}
+Run all scheduled events. This function will wait 
+(using the \function{delayfunc} function passed to the constructor)
+for the next event, then execute it and so on until there are no more
+scheduled events.
+
+Either \var{action} or \var{delayfunc} can raise an exception.  In
+either case, the scheduler will maintain a consistent state and
+propagate the exception.  If an exception is raised by \var{action},
+the event will not be attempted in future calls to \method{run()}.
+
+If a sequence of events takes longer to run than the time available
+before the next event, the scheduler will simply fall behind.  No
+events will be dropped; the calling code is responsible for canceling 
+events which are no longer pertinent.
+\end{methoddesc}

Added: vendor/Python/current/Doc/lib/libselect.tex
===================================================================
--- vendor/Python/current/Doc/lib/libselect.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libselect.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,132 @@
+\section{\module{select} ---
+         Waiting for I/O completion}
+
+\declaremodule{builtin}{select}
+\modulesynopsis{Wait for I/O completion on multiple streams.}
+
+
+This module provides access to the \cfunction{select()}
+and \cfunction{poll()} functions
+available in most operating systems.  Note that on Windows, it only
+works for sockets; on other operating systems, it also works for other
+file types (in particular, on \UNIX, it works on pipes).  It cannot
+be used on regular files to determine whether a file has grown since
+it was last read.
+
+The module defines the following:
+
+\begin{excdesc}{error}
+The exception raised when an error occurs.  The accompanying value is
+a pair containing the numeric error code from \cdata{errno} and the
+corresponding string, as would be printed by the \C{} function
+\cfunction{perror()}.
+\end{excdesc}
+
+\begin{funcdesc}{poll}{}
+(Not supported by all operating systems.)  Returns a polling object,
+which supports registering and unregistering file descriptors, and
+then polling them for I/O events;
+see section~\ref{poll-objects} below for the methods supported by
+polling objects.
+\end{funcdesc}
+
+\begin{funcdesc}{select}{iwtd, owtd, ewtd\optional{, timeout}}
+This is a straightforward interface to the \UNIX{} \cfunction{select()}
+system call.  The first three arguments are sequences of `waitable
+objects': either integers representing file descriptors or
+objects with a parameterless method named \method{fileno()} returning
+such an integer.  The three sequences of waitable objects are for input,
+output and `exceptional conditions', respectively.  Empty sequences are
+allowed, but acceptance of three empty sequences is platform-dependent.
+(It is known to work on \UNIX{} but not on Windows.)  The optional
+\var{timeout} argument specifies a time-out as a floating point number
+in seconds.  When the \var{timeout} argument is omitted the function
+blocks until at least one file descriptor is ready.  A time-out value
+of zero specifies a poll and never blocks.
+
+The return value is a triple of lists of objects that are ready:
+subsets of the first three arguments.  When the time-out is reached
+without a file descriptor becoming ready, three empty lists are
+returned.
+
+Among the acceptable object types in the sequences are Python file
+objects (e.g. \code{sys.stdin}, or objects returned by
+\function{open()} or \function{os.popen()}), socket objects
+returned by \function{socket.socket()}.%
+\withsubitem{(in module socket)}{\ttindex{socket()}}
+\withsubitem{(in module os)}{\ttindex{popen()}}
+You may also define a \dfn{wrapper} class yourself, as long as it has
+an appropriate \method{fileno()} method (that really returns a file
+descriptor, not just a random integer).
+\note{File objects on Windows are not acceptable, but sockets
+are.\index{WinSock}  On Windows, the underlying \cfunction{select()}
+function is provided by the WinSock library, and does not handle file
+descriptors that don't originate from WinSock.}
+\end{funcdesc}
+
+\subsection{Polling Objects
+            \label{poll-objects}}
+
+The \cfunction{poll()} system call, supported on most \UNIX{} systems,
+provides better scalability for network servers that service many,
+many clients at the same time.
+\cfunction{poll()} scales better because the system call only
+requires listing the file descriptors of interest, while \cfunction{select()}
+builds a bitmap, turns on bits for the fds of interest, and then
+afterward the whole bitmap has to be linearly scanned again.
+\cfunction{select()} is O(highest file descriptor), while
+\cfunction{poll()} is O(number of file descriptors).
+
+\begin{methoddesc}{register}{fd\optional{, eventmask}}
+Register a file descriptor with the polling object.  Future calls to
+the \method{poll()} method will then check whether the file descriptor
+has any pending I/O events.  \var{fd} can be either an integer, or an
+object with a \method{fileno()} method that returns an integer.  File
+objects implement
+\method{fileno()}, so they can also be used as the argument.
+
+\var{eventmask} is an optional bitmask describing the type of events you
+want to check for, and can be a combination of the constants
+\constant{POLLIN}, \constant{POLLPRI}, and \constant{POLLOUT},
+described in the table below.  If not specified, the default value
+used will check for all 3 types of events.
+
+\begin{tableii}{l|l}{constant}{Constant}{Meaning}
+  \lineii{POLLIN}{There is data to read}
+  \lineii{POLLPRI}{There is urgent data to read}
+  \lineii{POLLOUT}{Ready for output: writing will not block}
+  \lineii{POLLERR}{Error condition of some sort}
+  \lineii{POLLHUP}{Hung up}
+  \lineii{POLLNVAL}{Invalid request: descriptor not open}
+\end{tableii}
+
+Registering a file descriptor that's already registered is not an
+error, and has the same effect as registering the descriptor exactly
+once.
+\end{methoddesc}
+
+\begin{methoddesc}{unregister}{fd}
+Remove a file descriptor being tracked by a polling object.  Just like
+the \method{register()} method, \var{fd} can be an integer or an
+object with a \method{fileno()} method that returns an integer.
+
+Attempting to remove a file descriptor that was never registered
+causes a \exception{KeyError} exception to be raised.
+\end{methoddesc}
+
+\begin{methoddesc}{poll}{\optional{timeout}}
+Polls the set of registered file descriptors, and returns a
+possibly-empty list containing \code{(\var{fd}, \var{event})} 2-tuples
+for the descriptors that have events or errors to report.
+\var{fd} is the file descriptor, and \var{event} is a bitmask
+with bits set for the reported events for that descriptor
+--- \constant{POLLIN} for waiting input,
+\constant{POLLOUT} to indicate that the descriptor can be written to, and
+so forth.
+An empty list indicates that the call timed out and no file
+descriptors had any events to report.
+If \var{timeout} is given, it specifies the length of time in
+milliseconds which the system will wait for events before returning.
+If \var{timeout} is omitted, negative, or \constant{None}, the call will
+block until there is an event for this poll object.
+\end{methoddesc}

Added: vendor/Python/current/Doc/lib/libsets.tex
===================================================================
--- vendor/Python/current/Doc/lib/libsets.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libsets.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,264 @@
+\section{\module{sets} ---
+         Unordered collections of unique elements}
+
+\declaremodule{standard}{sets}
+\modulesynopsis{Implementation of sets of unique elements.}
+\moduleauthor{Greg V. Wilson}{gvwilson at nevex.com}
+\moduleauthor{Alex Martelli}{aleax at aleax.it}
+\moduleauthor{Guido van Rossum}{guido at python.org}
+\sectionauthor{Raymond D. Hettinger}{python at rcn.com}
+
+\versionadded{2.3}
+
+The \module{sets} module provides classes for constructing and manipulating
+unordered collections of unique elements.  Common uses include membership
+testing, removing duplicates from a sequence, and computing standard math
+operations on sets such as intersection, union, difference, and symmetric
+difference.
+
+Like other collections, sets support \code{\var{x} in \var{set}},
+\code{len(\var{set})}, and \code{for \var{x} in \var{set}}.  Being an
+unordered collection, sets do not record element position or order of
+insertion.  Accordingly, sets do not support indexing, slicing, or
+other sequence-like behavior.
+
+Most set applications use the \class{Set} class which provides every set
+method except for \method{__hash__()}. For advanced applications requiring
+a hash method, the \class{ImmutableSet} class adds a \method{__hash__()}
+method but omits methods which alter the contents of the set. Both
+\class{Set} and \class{ImmutableSet} derive from \class{BaseSet}, an
+abstract class useful for determining whether something is a set:
+\code{isinstance(\var{obj}, BaseSet)}.
+
+The set classes are implemented using dictionaries.  Accordingly, the
+requirements for set elements are the same as those for dictionary keys;
+namely, that the element defines both \method{__eq__} and \method{__hash__}.
+As a result, sets
+cannot contain mutable elements such as lists or dictionaries.
+However, they can contain immutable collections such as tuples or
+instances of \class{ImmutableSet}.  For convenience in implementing
+sets of sets, inner sets are automatically converted to immutable
+form, for example, \code{Set([Set(['dog'])])} is transformed to
+\code{Set([ImmutableSet(['dog'])])}.
+
+\begin{classdesc}{Set}{\optional{iterable}}
+Constructs a new empty \class{Set} object.  If the optional \var{iterable}
+parameter is supplied, updates the set with elements obtained from iteration.
+All of the elements in \var{iterable} should be immutable or be transformable
+to an immutable using the protocol described in
+section~\ref{immutable-transforms}.
+\end{classdesc}
+
+\begin{classdesc}{ImmutableSet}{\optional{iterable}}
+Constructs a new empty \class{ImmutableSet} object.  If the optional
+\var{iterable} parameter is supplied, updates the set with elements obtained
+from iteration.  All of the elements in \var{iterable} should be immutable or
+be transformable to an immutable using the protocol described in
+section~\ref{immutable-transforms}.
+
+Because \class{ImmutableSet} objects provide a \method{__hash__()} method,
+they can be used as set elements or as dictionary keys.  \class{ImmutableSet}
+objects do not have methods for adding or removing elements, so all of the
+elements must be known when the constructor is called.
+\end{classdesc}
+
+
+\subsection{Set Objects \label{set-objects}}
+
+Instances of \class{Set} and \class{ImmutableSet} both provide
+the following operations:
+
+\begin{tableiii}{c|c|l}{code}{Operation}{Equivalent}{Result}
+  \lineiii{len(\var{s})}{}{cardinality of set \var{s}}
+
+  \hline
+  \lineiii{\var{x} in \var{s}}{}
+         {test \var{x} for membership in \var{s}}
+  \lineiii{\var{x} not in \var{s}}{}
+         {test \var{x} for non-membership in \var{s}}
+  \lineiii{\var{s}.issubset(\var{t})}{\code{\var{s} <= \var{t}}}
+         {test whether every element in \var{s} is in \var{t}}
+  \lineiii{\var{s}.issuperset(\var{t})}{\code{\var{s} >= \var{t}}}
+         {test whether every element in \var{t} is in \var{s}}
+
+  \hline
+  \lineiii{\var{s}.union(\var{t})}{\var{s} \textbar{} \var{t}}
+         {new set with elements from both \var{s} and \var{t}}
+  \lineiii{\var{s}.intersection(\var{t})}{\var{s} \&\ \var{t}}
+         {new set with elements common to \var{s} and \var{t}}
+  \lineiii{\var{s}.difference(\var{t})}{\var{s} - \var{t}}
+         {new set with elements in \var{s} but not in \var{t}}
+  \lineiii{\var{s}.symmetric_difference(\var{t})}{\var{s} \^\ \var{t}}
+         {new set with elements in either \var{s} or \var{t} but not both}
+  \lineiii{\var{s}.copy()}{}
+         {new set with a shallow copy of \var{s}}
+\end{tableiii}
+
+Note, the non-operator versions of \method{union()},
+\method{intersection()}, \method{difference()}, and
+\method{symmetric_difference()} will accept any iterable as an argument.
+In contrast, their operator based counterparts require their arguments to
+be sets.  This precludes error-prone constructions like
+\code{Set('abc') \&\ 'cbs'} in favor of the more readable
+\code{Set('abc').intersection('cbs')}.
+\versionchanged[Formerly all arguments were required to be sets]{2.3.1}
+
+In addition, both \class{Set} and \class{ImmutableSet}
+support set to set comparisons.  Two sets are equal if and only if
+every element of each set is contained in the other (each is a subset
+of the other).
+A set is less than another set if and only if the first set is a proper
+subset of the second set (is a subset, but is not equal).
+A set is greater than another set if and only if the first set is a proper
+superset of the second set (is a superset, but is not equal).
+
+The subset and equality comparisons do not generalize to a complete
+ordering function.  For example, any two disjoint sets are not equal and
+are not subsets of each other, so \emph{all} of the following return
+\code{False}:  \code{\var{a}<\var{b}}, \code{\var{a}==\var{b}}, or
+\code{\var{a}>\var{b}}.
+Accordingly, sets do not implement the \method{__cmp__} method.
+
+Since sets only define partial ordering (subset relationships), the output
+of the \method{list.sort()} method is undefined for lists of sets.
+
+The following table lists operations available in \class{ImmutableSet}
+but not found in \class{Set}:
+
+\begin{tableii}{c|l}{code}{Operation}{Result}
+  \lineii{hash(\var{s})}{returns a hash value for \var{s}}
+\end{tableii}
+
+The following table lists operations available in \class{Set}
+but not found in \class{ImmutableSet}:
+
+\begin{tableiii}{c|c|l}{code}{Operation}{Equivalent}{Result}
+  \lineiii{\var{s}.update(\var{t})}
+         {\var{s} \textbar= \var{t}}
+         {return set \var{s} with elements added from \var{t}}
+  \lineiii{\var{s}.intersection_update(\var{t})}
+         {\var{s} \&= \var{t}}
+         {return set \var{s} keeping only elements also found in \var{t}}
+  \lineiii{\var{s}.difference_update(\var{t})}
+         {\var{s} -= \var{t}}
+         {return set \var{s} after removing elements found in \var{t}}
+  \lineiii{\var{s}.symmetric_difference_update(\var{t})}
+         {\var{s} \textasciicircum= \var{t}}
+         {return set \var{s} with elements from \var{s} or \var{t}
+          but not both}
+
+  \hline
+  \lineiii{\var{s}.add(\var{x})}{}
+         {add element \var{x} to set \var{s}}
+  \lineiii{\var{s}.remove(\var{x})}{}
+         {remove \var{x} from set \var{s}; raises \exception{KeyError}
+	  if not present}
+  \lineiii{\var{s}.discard(\var{x})}{}
+         {removes \var{x} from set \var{s} if present}
+  \lineiii{\var{s}.pop()}{}
+         {remove and return an arbitrary element from \var{s}; raises
+	  \exception{KeyError} if empty}
+  \lineiii{\var{s}.clear()}{}
+         {remove all elements from set \var{s}}
+\end{tableiii}
+
+Note, the non-operator versions of \method{update()},
+\method{intersection_update()}, \method{difference_update()}, and
+\method{symmetric_difference_update()} will accept any iterable as
+an argument.
+\versionchanged[Formerly all arguments were required to be sets]{2.3.1}
+
+Also note, the module also includes a \method{union_update()} method
+which is an alias for \method{update()}.  The method is included for
+backwards compatibility.  Programmers should prefer the
+\method{update()} method because it is supported by the builtin
+\class{set()} and \class{frozenset()} types.
+
+\subsection{Example \label{set-example}}
+
+\begin{verbatim}
+>>> from sets import Set
+>>> engineers = Set(['John', 'Jane', 'Jack', 'Janice'])
+>>> programmers = Set(['Jack', 'Sam', 'Susan', 'Janice'])
+>>> managers = Set(['Jane', 'Jack', 'Susan', 'Zack'])
+>>> employees = engineers | programmers | managers           # union
+>>> engineering_management = engineers & managers            # intersection
+>>> fulltime_management = managers - engineers - programmers # difference
+>>> engineers.add('Marvin')                                  # add element
+>>> print engineers
+Set(['Jane', 'Marvin', 'Janice', 'John', 'Jack'])
+>>> employees.issuperset(engineers)           # superset test
+False
+>>> employees.union_update(engineers)         # update from another set
+>>> employees.issuperset(engineers)
+True
+>>> for group in [engineers, programmers, managers, employees]:
+...     group.discard('Susan')                # unconditionally remove element
+...     print group
+...
+Set(['Jane', 'Marvin', 'Janice', 'John', 'Jack'])
+Set(['Janice', 'Jack', 'Sam'])
+Set(['Jane', 'Zack', 'Jack'])
+Set(['Jack', 'Sam', 'Jane', 'Marvin', 'Janice', 'John', 'Zack'])
+\end{verbatim}
+
+
+\subsection{Protocol for automatic conversion to immutable
+            \label{immutable-transforms}}
+
+Sets can only contain immutable elements.  For convenience, mutable
+\class{Set} objects are automatically copied to an \class{ImmutableSet}
+before being added as a set element.
+
+The mechanism is to always add a hashable element, or if it is not
+hashable, the element is checked to see if it has an
+\method{__as_immutable__()} method which returns an immutable equivalent.
+
+Since \class{Set} objects have a \method{__as_immutable__()} method
+returning an instance of \class{ImmutableSet}, it is possible to
+construct sets of sets.
+
+A similar mechanism is needed by the \method{__contains__()} and
+\method{remove()} methods which need to hash an element to check
+for membership in a set.  Those methods check an element for hashability
+and, if not, check for a \method{__as_temporarily_immutable__()} method
+which returns the element wrapped by a class that provides temporary
+methods for \method{__hash__()}, \method{__eq__()}, and \method{__ne__()}.
+
+The alternate mechanism spares the need to build a separate copy of
+the original mutable object.
+
+\class{Set} objects implement the \method{__as_temporarily_immutable__()}
+method which returns the \class{Set} object wrapped by a new class
+\class{_TemporarilyImmutableSet}.
+
+The two mechanisms for adding hashability are normally invisible to the
+user; however, a conflict can arise in a multi-threaded environment
+where one thread is updating a set while another has temporarily wrapped it
+in \class{_TemporarilyImmutableSet}.  In other words, sets of mutable sets
+are not thread-safe.
+
+
+\subsection{Comparison to the built-in \class{set} types
+            \label{comparison-to-builtin-set}}
+
+The built-in \class{set} and \class{frozenset} types were designed based
+on lessons learned from the \module{sets} module.  The key differences are:
+
+\begin{itemize}
+\item \class{Set} and \class{ImmutableSet} were renamed to \class{set} and
+      \class{frozenset}.
+\item There is no equivalent to \class{BaseSet}.  Instead, use
+      \code{isinstance(x, (set, frozenset))}.
+\item The hash algorithm for the built-ins performs significantly better
+      (fewer collisions) for most datasets.
+\item The built-in versions have more space efficient pickles.
+\item The built-in versions do not have a \method{union_update()} method.
+      Instead, use the \method{update()} method which is equivalent.
+\item The built-in versions do not have a \method{_repr(sorted=True)} method.
+      Instead, use the built-in \function{repr()} and \function{sorted()}
+      functions:  \code{repr(sorted(s))}.
+\item The built-in version does not have a protocol for automatic conversion
+      to immutable.  Many found this feature to be confusing and no one
+      in the community reported having found real uses for it.
+\end{itemize}    

Added: vendor/Python/current/Doc/lib/libsgi.tex
===================================================================
--- vendor/Python/current/Doc/lib/libsgi.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libsgi.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,7 @@
+\chapter{SGI IRIX Specific Services}
+\label{sgi}
+
+The modules described in this chapter provide interfaces to features
+that are unique to SGI's IRIX operating system (versions 4 and 5).
+
+\localmoduletable

Added: vendor/Python/current/Doc/lib/libsgmllib.tex
===================================================================
--- vendor/Python/current/Doc/lib/libsgmllib.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libsgmllib.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,271 @@
+\section{\module{sgmllib} ---
+         Simple SGML parser}
+
+\declaremodule{standard}{sgmllib}
+\modulesynopsis{Only as much of an SGML parser as needed to parse HTML.}
+
+\index{SGML}
+
+This module defines a class \class{SGMLParser} which serves as the
+basis for parsing text files formatted in SGML (Standard Generalized
+Mark-up Language).  In fact, it does not provide a full SGML parser
+--- it only parses SGML insofar as it is used by HTML, and the module
+only exists as a base for the \refmodule{htmllib} module.  Another
+HTML parser which supports XHTML and offers a somewhat different
+interface is available in the \refmodule{HTMLParser} module.
+
+\begin{classdesc}{SGMLParser}{}
+The \class{SGMLParser} class is instantiated without arguments.
+The parser is hardcoded to recognize the following
+constructs:
+
+\begin{itemize}
+\item
+Opening and closing tags of the form
+\samp{<\var{tag} \var{attr}="\var{value}" ...>} and
+\samp{</\var{tag}>}, respectively.
+
+\item
+Numeric character references of the form \samp{\&\#\var{name};}.
+
+\item
+Entity references of the form \samp{\&\var{name};}.
+
+\item
+SGML comments of the form \samp{<!--\var{text}-->}.  Note that
+spaces, tabs, and newlines are allowed between the trailing
+\samp{>} and the immediately preceding \samp{--}.
+
+\end{itemize}
+\end{classdesc}
+
+A single exception is defined as well:
+
+\begin{excdesc}{SGMLParseError}
+Exception raised by the \class{SGMLParser} class when it encounters an
+error while parsing.
+\versionadded{2.1}
+\end{excdesc}
+
+
+\class{SGMLParser} instances have the following methods:
+
+
+\begin{methoddesc}{reset}{}
+Reset the instance.  Loses all unprocessed data.  This is called
+implicitly at instantiation time.
+\end{methoddesc}
+
+\begin{methoddesc}{setnomoretags}{}
+Stop processing tags.  Treat all following input as literal input
+(CDATA).  (This is only provided so the HTML tag
+\code{<PLAINTEXT>} can be implemented.)
+\end{methoddesc}
+
+\begin{methoddesc}{setliteral}{}
+Enter literal mode (CDATA mode).
+\end{methoddesc}
+
+\begin{methoddesc}{feed}{data}
+Feed some text to the parser.  It is processed insofar as it consists
+of complete elements; incomplete data is buffered until more data is
+fed or \method{close()} is called.
+\end{methoddesc}
+
+\begin{methoddesc}{close}{}
+Force processing of all buffered data as if it were followed by an
+end-of-file mark.  This method may be redefined by a derived class to
+define additional processing at the end of the input, but the
+redefined version should always call \method{close()}.
+\end{methoddesc}
+
+\begin{methoddesc}{get_starttag_text}{}
+Return the text of the most recently opened start tag.  This should
+not normally be needed for structured processing, but may be useful in
+dealing with HTML ``as deployed'' or for re-generating input with
+minimal changes (whitespace between attributes can be preserved,
+etc.).
+\end{methoddesc}
+
+\begin{methoddesc}{handle_starttag}{tag, method, attributes}
+This method is called to handle start tags for which either a
+\method{start_\var{tag}()} or \method{do_\var{tag}()} method has been
+defined.  The \var{tag} argument is the name of the tag converted to
+lower case, and the \var{method} argument is the bound method which
+should be used to support semantic interpretation of the start tag.
+The \var{attributes} argument is a list of \code{(\var{name},
+\var{value})} pairs containing the attributes found inside the tag's
+\code{<>} brackets.
+
+The \var{name} has been translated to lower case.
+Double quotes and backslashes in the \var{value} have been interpreted,
+as well as known character references and known entity references
+terminated by a semicolon (normally, entity references can be terminated
+by any non-alphanumerical character, but this would break the very
+common case of \code{<A HREF="url?spam=1\&eggs=2">} when \code{eggs}
+is a valid entity name).
+
+For instance, for the tag \code{<A HREF="http://www.cwi.nl/">}, this
+method would be called as \samp{unknown_starttag('a', [('href',
+'http://www.cwi.nl/')])}.  The base implementation simply calls
+\var{method} with \var{attributes} as the only argument.
+\versionadded[Handling of entity and character references within
+              attribute values]{2.5}
+\end{methoddesc}
+
+\begin{methoddesc}{handle_endtag}{tag, method}
+This method is called to handle endtags for which an
+\method{end_\var{tag}()} method has been defined.  The
+\var{tag} argument is the name of the tag converted to lower case, and
+the \var{method} argument is the bound method which should be used to
+support semantic interpretation of the end tag.  If no
+\method{end_\var{tag}()} method is defined for the closing element,
+this handler is not called.  The base implementation simply calls
+\var{method}.
+\end{methoddesc}
+
+\begin{methoddesc}{handle_data}{data}
+This method is called to process arbitrary data.  It is intended to be
+overridden by a derived class; the base class implementation does
+nothing.
+\end{methoddesc}
+
+\begin{methoddesc}{handle_charref}{ref}
+This method is called to process a character reference of the form
+\samp{\&\#\var{ref};}.  The base implementation uses
+\method{convert_charref()} to convert the reference to a string.  If
+that method returns a string, it is passed to \method{handle_data()},
+otherwise \method{unknown_charref(\var{ref})} is called to handle the
+error.
+\versionchanged[Use \method{convert_charref()} instead of hard-coding
+the conversion]{2.5}
+\end{methoddesc}
+
+\begin{methoddesc}{convert_charref}{ref}
+Convert a character reference to a string, or \code{None}.  \var{ref}
+is the reference passed in as a string.  In the base implementation,
+\var{ref} must be a decimal number in the range 0-255.  It converts
+the code point found using the \method{convert_codepoint()} method.
+If \var{ref} is invalid or out of range, this method returns
+\code{None}.  This method is called by the default
+\method{handle_charref()} implementation and by the attribute value
+parser.
+\versionadded{2.5}
+\end{methoddesc}
+
+\begin{methoddesc}{convert_codepoint}{codepoint}
+Convert a codepoint to a \class{str} value.  Encodings can be handled
+here if appropriate, though the rest of \module{sgmllib} is oblivious
+on this matter.
+\versionadded{2.5}
+\end{methoddesc}
+
+\begin{methoddesc}{handle_entityref}{ref}
+This method is called to process a general entity reference of the
+form \samp{\&\var{ref};} where \var{ref} is an general entity
+reference.  It converts \var{ref} by passing it to
+\method{convert_entityref()}.  If a translation is returned, it
+calls the method \method{handle_data()} with the translation;
+otherwise, it calls the method \code{unknown_entityref(\var{ref})}.
+The default \member{entitydefs} defines translations for
+\code{\&amp;}, \code{\&apos}, \code{\&gt;}, \code{\&lt;}, and
+\code{\&quot;}.
+\versionchanged[Use \method{convert_entityref()} instead of hard-coding
+the conversion]{2.5}
+\end{methoddesc}
+
+\begin{methoddesc}{convert_entityref}{ref}
+Convert a named entity reference to a \class{str} value, or
+\code{None}.  The resulting value will not be parsed.  \var{ref} will
+be only the name of the entity.  The default implementation looks for
+\var{ref} in the instance (or class) variable \member{entitydefs}
+which should be a mapping from entity names to corresponding
+translations.  If no translation is available for \var{ref}, this
+method returns \code{None}.  This method is called by the default
+\method{handle_entityref()} implementation and by the attribute value
+parser.
+\versionadded{2.5}
+\end{methoddesc}
+
+\begin{methoddesc}{handle_comment}{comment}
+This method is called when a comment is encountered.  The
+\var{comment} argument is a string containing the text between the
+\samp{<!--} and \samp{-->} delimiters, but not the delimiters
+themselves.  For example, the comment \samp{<!--text-->} will
+cause this method to be called with the argument \code{'text'}.  The
+default method does nothing.
+\end{methoddesc}
+
+\begin{methoddesc}{handle_decl}{data}
+Method called when an SGML declaration is read by the parser.  In
+practice, the \code{DOCTYPE} declaration is the only thing observed in
+HTML, but the parser does not discriminate among different (or broken)
+declarations.  Internal subsets in a \code{DOCTYPE} declaration are
+not supported.  The \var{data} parameter will be the entire contents
+of the declaration inside the \code{<!}...\code{>} markup.  The
+default implementation does nothing.
+\end{methoddesc}
+
+\begin{methoddesc}{report_unbalanced}{tag}
+This method is called when an end tag is found which does not
+correspond to any open element.
+\end{methoddesc}
+
+\begin{methoddesc}{unknown_starttag}{tag, attributes}
+This method is called to process an unknown start tag.  It is intended
+to be overridden by a derived class; the base class implementation
+does nothing.
+\end{methoddesc}
+
+\begin{methoddesc}{unknown_endtag}{tag}
+This method is called to process an unknown end tag.  It is intended
+to be overridden by a derived class; the base class implementation
+does nothing.
+\end{methoddesc}
+
+\begin{methoddesc}{unknown_charref}{ref}
+This method is called to process unresolvable numeric character
+references.  Refer to \method{handle_charref()} to determine what is
+handled by default.  It is intended to be overridden by a derived
+class; the base class implementation does nothing.
+\end{methoddesc}
+
+\begin{methoddesc}{unknown_entityref}{ref}
+This method is called to process an unknown entity reference.  It is
+intended to be overridden by a derived class; the base class
+implementation does nothing.
+\end{methoddesc}
+
+Apart from overriding or extending the methods listed above, derived
+classes may also define methods of the following form to define
+processing of specific tags.  Tag names in the input stream are case
+independent; the \var{tag} occurring in method names must be in lower
+case:
+
+\begin{methoddescni}{start_\var{tag}}{attributes}
+This method is called to process an opening tag \var{tag}.  It has
+preference over \method{do_\var{tag}()}.  The
+\var{attributes} argument has the same meaning as described for
+\method{handle_starttag()} above.
+\end{methoddescni}
+
+\begin{methoddescni}{do_\var{tag}}{attributes}
+This method is called to process an opening tag \var{tag} 
+for which no \method{start_\var{tag}} method is defined.  
+The \var{attributes} argument
+has the same meaning as described for \method{handle_starttag()} above.
+\end{methoddescni}
+
+\begin{methoddescni}{end_\var{tag}}{}
+This method is called to process a closing tag \var{tag}.
+\end{methoddescni}
+
+Note that the parser maintains a stack of open elements for which no
+end tag has been found yet.  Only tags processed by
+\method{start_\var{tag}()} are pushed on this stack.  Definition of an
+\method{end_\var{tag}()} method is optional for these tags.  For tags
+processed by \method{do_\var{tag}()} or by \method{unknown_tag()}, no
+\method{end_\var{tag}()} method must be defined; if defined, it will
+not be used.  If both \method{start_\var{tag}()} and
+\method{do_\var{tag}()} methods exist for a tag, the
+\method{start_\var{tag}()} method takes precedence.

Added: vendor/Python/current/Doc/lib/libsha.tex
===================================================================
--- vendor/Python/current/Doc/lib/libsha.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libsha.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,83 @@
+\section{\module{sha} ---
+         SHA-1 message digest algorithm}
+
+\declaremodule{builtin}{sha}
+\modulesynopsis{NIST's secure hash algorithm, SHA.}
+\sectionauthor{Fred L. Drake, Jr.}{fdrake at acm.org}
+
+\deprecated{2.5}{Use the \refmodule{hashlib} module instead.}
+
+
+This module implements the interface to NIST's\index{NIST} secure hash 
+algorithm,\index{Secure Hash Algorithm} known as SHA-1.  SHA-1 is an
+improved version of the original SHA hash algorithm.  It is used in
+the same way as the \refmodule{md5} module:\ use \function{new()}
+to create an sha object, then feed this object with arbitrary strings
+using the \method{update()} method, and at any point you can ask it
+for the \dfn{digest} of the concatenation of the strings fed to it
+so far.\index{checksum!SHA}  SHA-1 digests are 160 bits instead of
+MD5's 128 bits.
+
+
+\begin{funcdesc}{new}{\optional{string}}
+  Return a new sha object.  If \var{string} is present, the method
+  call \code{update(\var{string})} is made.
+\end{funcdesc}
+
+
+The following values are provided as constants in the module and as
+attributes of the sha objects returned by \function{new()}:
+
+\begin{datadesc}{blocksize}
+  Size of the blocks fed into the hash function; this is always
+  \code{1}.  This size is used to allow an arbitrary string to be
+  hashed.
+\end{datadesc}
+
+\begin{datadesc}{digest_size}
+  The size of the resulting digest in bytes.  This is always
+  \code{20}.
+\end{datadesc}
+
+
+An sha object has the same methods as md5 objects:
+
+\begin{methoddesc}[sha]{update}{arg}
+Update the sha object with the string \var{arg}.  Repeated calls are
+equivalent to a single call with the concatenation of all the
+arguments: \code{m.update(a); m.update(b)} is equivalent to
+\code{m.update(a+b)}.
+\end{methoddesc}
+
+\begin{methoddesc}[sha]{digest}{}
+Return the digest of the strings passed to the \method{update()}
+method so far.  This is a 20-byte string which may contain
+non-\ASCII{} characters, including null bytes.
+\end{methoddesc}
+
+\begin{methoddesc}[sha]{hexdigest}{}
+Like \method{digest()} except the digest is returned as a string of
+length 40, containing only hexadecimal digits.  This may 
+be used to exchange the value safely in email or other non-binary
+environments.
+\end{methoddesc}
+
+\begin{methoddesc}[sha]{copy}{}
+Return a copy (``clone'') of the sha object.  This can be used to
+efficiently compute the digests of strings that share a common initial
+substring.
+\end{methoddesc}
+
+\begin{seealso}
+  \seetitle[http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf]
+    {Secure Hash Standard}
+    {The Secure Hash Algorithm is defined by NIST document FIPS
+     PUB 180-2:
+     \citetitle[http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf]
+        {Secure Hash Standard}, published in August 2002.}
+
+  \seetitle[http://csrc.nist.gov/encryption/tkhash.html]
+           {Cryptographic Toolkit (Secure Hashing)}
+           {Links from NIST to various information on secure hashing.}
+\end{seealso}
+

Added: vendor/Python/current/Doc/lib/libshelve.tex
===================================================================
--- vendor/Python/current/Doc/lib/libshelve.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libshelve.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,174 @@
+\section{\module{shelve} ---
+         Python object persistence}
+
+\declaremodule{standard}{shelve}
+\modulesynopsis{Python object persistence.}
+
+
+A ``shelf'' is a persistent, dictionary-like object.  The difference
+with ``dbm'' databases is that the values (not the keys!) in a shelf
+can be essentially arbitrary Python objects --- anything that the
+\refmodule{pickle} module can handle.  This includes most class
+instances, recursive data types, and objects containing lots of shared 
+sub-objects.  The keys are ordinary strings.
+\refstmodindex{pickle}
+
+\begin{funcdesc}{open}{filename\optional{,flag='c'\optional{,protocol=\code{None}\optional{,writeback=\code{False}}}}}
+Open a persistent dictionary.  The filename specified is the base filename
+for the underlying database.  As a side-effect, an extension may be added to
+the filename and more than one file may be created.  By default, the
+underlying database file is opened for reading and writing.  The optional
+{}\var{flag} parameter has the same interpretation as the \var{flag}
+parameter of \function{anydbm.open}.  
+
+By default, version 0 pickles are used to serialize values. 
+The version of the pickle protocol can be specified with the
+\var{protocol} parameter. \versionchanged[The \var{protocol}
+parameter was added]{2.3}
+
+By default, mutations to persistent-dictionary mutable entries are not
+automatically written back.  If the optional \var{writeback} parameter
+is set to {}\var{True}, all entries accessed are cached in memory, and
+written back at close time; this can make it handier to mutate mutable
+entries in the persistent dictionary, but, if many entries are
+accessed, it can consume vast amounts of memory for the cache, and it
+can make the close operation very slow since all accessed entries are
+written back (there is no way to determine which accessed entries are
+mutable, nor which ones were actually mutated).
+
+\end{funcdesc}
+
+Shelve objects support all methods supported by dictionaries.  This eases
+the transition from dictionary based scripts to those requiring persistent
+storage.
+
+One additional method is supported:
+\begin{methoddesc}[Shelf]{sync}{}
+Write back all entries in the cache if the shelf was opened with
+\var{writeback} set to \var{True}. Also empty the cache and synchronize
+the persistent dictionary on disk, if feasible.  This is called automatically
+when the shelf is closed with \method{close()}.
+\end{methoddesc}
+
+\subsection{Restrictions}
+
+\begin{itemize}
+
+\item
+The choice of which database package will be used
+(such as \refmodule{dbm}, \refmodule{gdbm} or \refmodule{bsddb}) depends on
+which interface is available.  Therefore it is not safe to open the database
+directly using \refmodule{dbm}.  The database is also (unfortunately) subject
+to the limitations of \refmodule{dbm}, if it is used --- this means
+that (the pickled representation of) the objects stored in the
+database should be fairly small, and in rare cases key collisions may
+cause the database to refuse updates.
+\refbimodindex{dbm}
+\refbimodindex{gdbm}
+\refbimodindex{bsddb}
+
+\item
+Depending on the implementation, closing a persistent dictionary may
+or may not be necessary to flush changes to disk.  The \method{__del__}
+method of the \class{Shelf} class calls the \method{close} method, so the
+programmer generally need not do this explicitly.
+
+\item
+The \module{shelve} module does not support \emph{concurrent} read/write
+access to shelved objects.  (Multiple simultaneous read accesses are
+safe.)  When a program has a shelf open for writing, no other program
+should have it open for reading or writing.  \UNIX{} file locking can
+be used to solve this, but this differs across \UNIX{} versions and
+requires knowledge about the database implementation used.
+
+\end{itemize}
+
+\begin{classdesc}{Shelf}{dict\optional{, protocol=None\optional{, writeback=False}}}
+A subclass of \class{UserDict.DictMixin} which stores pickled values in the
+\var{dict} object.  
+
+By default, version 0 pickles are used to serialize values.  The
+version of the pickle protocol can be specified with the
+\var{protocol} parameter. See the \module{pickle} documentation for a
+discussion of the pickle protocols. \versionchanged[The \var{protocol}
+parameter was added]{2.3}
+
+If the \var{writeback} parameter is \code{True}, the object will hold a
+cache of all entries accessed and write them back to the \var{dict} at
+sync and close times.  This allows natural operations on mutable entries,
+but can consume much more memory and make sync and close take a long time.
+\end{classdesc}
+
+\begin{classdesc}{BsdDbShelf}{dict\optional{, protocol=None\optional{, writeback=False}}}
+
+A subclass of \class{Shelf} which exposes \method{first},
+\method{next}, \method{previous}, \method{last} and
+\method{set_location} which are available in the \module{bsddb} module
+but not in other database modules.  The \var{dict} object passed to
+the constructor must support those methods.  This is generally
+accomplished by calling one of \function{bsddb.hashopen},
+\function{bsddb.btopen} or \function{bsddb.rnopen}.  The optional
+\var{protocol} and \var{writeback} parameters have the
+same interpretation as for the \class{Shelf} class.
+
+\end{classdesc}
+
+\begin{classdesc}{DbfilenameShelf}{filename\optional{, flag='c'\optional{, protocol=None\optional{, writeback=False}}}}
+
+A subclass of \class{Shelf} which accepts a \var{filename} instead of
+a dict-like object.  The underlying file will be opened using
+{}\function{anydbm.open}.  By default, the file will be created and
+opened for both read and write.  The optional \var{flag} parameter has
+the same interpretation as for the \function{open} function.  The
+optional \var{protocol} and \var{writeback} parameters
+have the same interpretation as for the \class{Shelf} class.
+ 
+\end{classdesc}
+
+\subsection{Example}
+
+To summarize the interface (\code{key} is a string, \code{data} is an
+arbitrary object):
+
+\begin{verbatim}
+import shelve
+
+d = shelve.open(filename) # open -- file may get suffix added by low-level
+                          # library
+
+d[key] = data   # store data at key (overwrites old data if
+                # using an existing key)
+data = d[key]   # retrieve a COPY of data at key (raise KeyError if no
+                # such key)
+del d[key]      # delete data stored at key (raises KeyError
+                # if no such key)
+flag = d.has_key(key)   # true if the key exists
+klist = d.keys() # a list of all existing keys (slow!)
+
+# as d was opened WITHOUT writeback=True, beware:
+d['xx'] = range(4)  # this works as expected, but...
+d['xx'].append(5)   # *this doesn't!* -- d['xx'] is STILL range(4)!!!
+
+# having opened d without writeback=True, you need to code carefully:
+temp = d['xx']      # extracts the copy
+temp.append(5)      # mutates the copy
+d['xx'] = temp      # stores the copy right back, to persist it
+
+# or, d=shelve.open(filename,writeback=True) would let you just code
+# d['xx'].append(5) and have it work as expected, BUT it would also
+# consume more memory and make the d.close() operation slower.
+
+d.close()       # close it
+\end{verbatim}
+
+\begin{seealso}
+  \seemodule{anydbm}{Generic interface to \code{dbm}-style databases.}
+  \seemodule{bsddb}{BSD \code{db} database interface.}
+  \seemodule{dbhash}{Thin layer around the \module{bsddb} which provides an
+  \function{open} function like the other database modules.}
+  \seemodule{dbm}{Standard \UNIX{} database interface.}
+  \seemodule{dumbdbm}{Portable implementation of the \code{dbm} interface.}
+  \seemodule{gdbm}{GNU database interface, based on the \code{dbm} interface.}
+  \seemodule{pickle}{Object serialization used by \module{shelve}.}
+  \seemodule{cPickle}{High-performance version of \refmodule{pickle}.}
+\end{seealso}

Added: vendor/Python/current/Doc/lib/libshlex.tex
===================================================================
--- vendor/Python/current/Doc/lib/libshlex.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libshlex.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,274 @@
+\section{\module{shlex} ---
+         Simple lexical analysis}
+
+\declaremodule{standard}{shlex}
+\modulesynopsis{Simple lexical analysis for \UNIX\ shell-like languages.}
+\moduleauthor{Eric S. Raymond}{esr at snark.thyrsus.com}
+\moduleauthor{Gustavo Niemeyer}{niemeyer at conectiva.com}
+\sectionauthor{Eric S. Raymond}{esr at snark.thyrsus.com}
+\sectionauthor{Gustavo Niemeyer}{niemeyer at conectiva.com}
+
+\versionadded{1.5.2}
+
+The \class{shlex} class makes it easy to write lexical analyzers for
+simple syntaxes resembling that of the \UNIX{} shell.  This will often
+be useful for writing minilanguages, (for example, in run control
+files for Python applications) or for parsing quoted strings.
+
+\note{The \module{shlex} module currently does not support Unicode input.}
+
+The \module{shlex} module defines the following functions:
+
+\begin{funcdesc}{split}{s\optional{, comments}}
+Split the string \var{s} using shell-like syntax. If \var{comments} is
+\constant{False} (the default), the parsing of comments in the given
+string will be disabled (setting the \member{commenters} member of the
+\class{shlex} instance to the empty string).  This function operates
+in \POSIX{} mode.
+\versionadded{2.3}
+\end{funcdesc}
+
+The \module{shlex} module defines the following class:
+
+\begin{classdesc}{shlex}{\optional{instream\optional{,
+			 infile\optional{, posix}}}}
+A \class{shlex} instance or subclass instance is a lexical analyzer
+object.  The initialization argument, if present, specifies where to
+read characters from. It must be a file-/stream-like object with
+\method{read()} and \method{readline()} methods, or a string (strings
+are accepted since Python 2.3). If no argument is given, input will be
+taken from \code{sys.stdin}.  The second optional argument is a filename
+string, which sets the initial value of the \member{infile} member.  If
+the \var{instream} argument is omitted or equal to \code{sys.stdin},
+this second argument defaults to ``stdin''.  The \var{posix} argument
+was introduced in Python 2.3, and defines the operational mode.  When
+\var{posix} is not true (default), the \class{shlex} instance will
+operate in compatibility mode.  When operating in \POSIX{} mode,
+\class{shlex} will try to be as close as possible to the \POSIX{} shell
+parsing rules.  See section~\ref{shlex-objects}.
+\end{classdesc}
+
+\begin{seealso}
+  \seemodule{ConfigParser}{Parser for configuration files similar to the
+                           Windows \file{.ini} files.}
+\end{seealso}
+
+
+\subsection{shlex Objects \label{shlex-objects}}
+
+A \class{shlex} instance has the following methods:
+
+\begin{methoddesc}{get_token}{}
+Return a token.  If tokens have been stacked using
+\method{push_token()}, pop a token off the stack.  Otherwise, read one
+from the input stream.  If reading encounters an immediate
+end-of-file, \member{self.eof} is returned (the empty string (\code{''})
+in non-\POSIX{} mode, and \code{None} in \POSIX{} mode).
+\end{methoddesc}
+
+\begin{methoddesc}{push_token}{str}
+Push the argument onto the token stack.
+\end{methoddesc}
+
+\begin{methoddesc}{read_token}{}
+Read a raw token.  Ignore the pushback stack, and do not interpret source
+requests.  (This is not ordinarily a useful entry point, and is
+documented here only for the sake of completeness.)
+\end{methoddesc}
+
+\begin{methoddesc}{sourcehook}{filename}
+When \class{shlex} detects a source request (see
+\member{source} below) this method is given the following token as
+argument, and expected to return a tuple consisting of a filename and
+an open file-like object.
+
+Normally, this method first strips any quotes off the argument.  If
+the result is an absolute pathname, or there was no previous source
+request in effect, or the previous source was a stream
+(such as \code{sys.stdin}), the result is left alone.  Otherwise, if the
+result is a relative pathname, the directory part of the name of the
+file immediately before it on the source inclusion stack is prepended
+(this behavior is like the way the C preprocessor handles
+\code{\#include "file.h"}).
+
+The result of the manipulations is treated as a filename, and returned
+as the first component of the tuple, with
+\function{open()} called on it to yield the second component. (Note:
+this is the reverse of the order of arguments in instance initialization!)
+
+This hook is exposed so that you can use it to implement directory
+search paths, addition of file extensions, and other namespace hacks.
+There is no corresponding `close' hook, but a shlex instance will call
+the \method{close()} method of the sourced input stream when it
+returns \EOF.
+
+For more explicit control of source stacking, use the
+\method{push_source()} and \method{pop_source()} methods. 
+\end{methoddesc}
+
+\begin{methoddesc}{push_source}{stream\optional{, filename}}
+Push an input source stream onto the input stack.  If the filename
+argument is specified it will later be available for use in error
+messages.  This is the same method used internally by the
+\method{sourcehook} method.
+\versionadded{2.1}
+\end{methoddesc}
+
+\begin{methoddesc}{pop_source}{}
+Pop the last-pushed input source from the input stack.
+This is the same method used internally when the lexer reaches
+\EOF{} on a stacked input stream.
+\versionadded{2.1}
+\end{methoddesc}
+
+\begin{methoddesc}{error_leader}{\optional{file\optional{, line}}}
+This method generates an error message leader in the format of a
+\UNIX{} C compiler error label; the format is \code{'"\%s", line \%d: '},
+where the \samp{\%s} is replaced with the name of the current source
+file and the \samp{\%d} with the current input line number (the
+optional arguments can be used to override these).
+
+This convenience is provided to encourage \module{shlex} users to
+generate error messages in the standard, parseable format understood
+by Emacs and other \UNIX{} tools.
+\end{methoddesc}
+
+Instances of \class{shlex} subclasses have some public instance
+variables which either control lexical analysis or can be used for
+debugging:
+
+\begin{memberdesc}{commenters}
+The string of characters that are recognized as comment beginners.
+All characters from the comment beginner to end of line are ignored.
+Includes just \character{\#} by default.   
+\end{memberdesc}
+
+\begin{memberdesc}{wordchars}
+The string of characters that will accumulate into multi-character
+tokens.  By default, includes all \ASCII{} alphanumerics and
+underscore.
+\end{memberdesc}
+
+\begin{memberdesc}{whitespace}
+Characters that will be considered whitespace and skipped.  Whitespace
+bounds tokens.  By default, includes space, tab, linefeed and
+carriage-return.
+\end{memberdesc}
+
+\begin{memberdesc}{escape}
+Characters that will be considered as escape. This will be only used
+in \POSIX{} mode, and includes just \character{\textbackslash} by default.
+\versionadded{2.3}
+\end{memberdesc}
+
+\begin{memberdesc}{quotes}
+Characters that will be considered string quotes.  The token
+accumulates until the same quote is encountered again (thus, different
+quote types protect each other as in the shell.)  By default, includes
+\ASCII{} single and double quotes.
+\end{memberdesc}
+
+\begin{memberdesc}{escapedquotes}
+Characters in \member{quotes} that will interpret escape characters
+defined in \member{escape}.  This is only used in \POSIX{} mode, and
+includes just \character{"} by default.
+\versionadded{2.3}
+\end{memberdesc}
+
+\begin{memberdesc}{whitespace_split}
+If \code{True}, tokens will only be split in whitespaces. This is useful, for
+example, for parsing command lines with \class{shlex}, getting tokens
+in a similar way to shell arguments.
+\versionadded{2.3}
+\end{memberdesc}
+
+\begin{memberdesc}{infile}
+The name of the current input file, as initially set at class
+instantiation time or stacked by later source requests.  It may
+be useful to examine this when constructing error messages.
+\end{memberdesc}
+
+\begin{memberdesc}{instream}
+The input stream from which this \class{shlex} instance is reading
+characters.
+\end{memberdesc}
+
+\begin{memberdesc}{source}
+This member is \code{None} by default.  If you assign a string to it,
+that string will be recognized as a lexical-level inclusion request
+similar to the \samp{source} keyword in various shells.  That is, the
+immediately following token will opened as a filename and input taken
+from that stream until \EOF, at which point the \method{close()}
+method of that stream will be called and the input source will again
+become the original input stream. Source requests may be stacked any
+number of levels deep.
+\end{memberdesc}
+
+\begin{memberdesc}{debug}
+If this member is numeric and \code{1} or more, a \class{shlex}
+instance will print verbose progress output on its behavior.  If you
+need to use this, you can read the module source code to learn the
+details.
+\end{memberdesc}
+
+\begin{memberdesc}{lineno}
+Source line number (count of newlines seen so far plus one).
+\end{memberdesc}
+
+\begin{memberdesc}{token}
+The token buffer.  It may be useful to examine this when catching
+exceptions.
+\end{memberdesc}
+
+\begin{memberdesc}{eof}
+Token used to determine end of file. This will be set to the empty
+string (\code{''}), in non-\POSIX{} mode, and to \code{None} in
+\POSIX{} mode.
+\versionadded{2.3}
+\end{memberdesc}
+
+\subsection{Parsing Rules\label{shlex-parsing-rules}}
+
+When operating in non-\POSIX{} mode, \class{shlex} will try to obey to
+the following rules.
+
+\begin{itemize}
+\item Quote characters are not recognized within words
+      (\code{Do"Not"Separate} is parsed as the single word
+      \code{Do"Not"Separate});
+\item Escape characters are not recognized;
+\item Enclosing characters in quotes preserve the literal value of
+      all characters within the quotes;
+\item Closing quotes separate words (\code{"Do"Separate} is parsed
+      as \code{"Do"} and \code{Separate});
+\item If \member{whitespace_split} is \code{False}, any character not
+      declared to be a word character, whitespace, or a quote will be
+      returned as a single-character token. If it is \code{True},
+      \class{shlex} will only split words in whitespaces;
+\item EOF is signaled with an empty string (\code{''});
+\item It's not possible to parse empty strings, even if quoted.
+\end{itemize}
+
+When operating in \POSIX{} mode, \class{shlex} will try to obey to the
+following parsing rules.
+
+\begin{itemize}
+\item Quotes are stripped out, and do not separate words
+      (\code{"Do"Not"Separate"} is parsed as the single word
+      \code{DoNotSeparate});
+\item Non-quoted escape characters (e.g. \character{\textbackslash})
+      preserve the literal value of the next character that follows;
+\item Enclosing characters in quotes which are not part of
+      \member{escapedquotes} (e.g. \character{'}) preserve the literal
+      value of all characters within the quotes;
+\item Enclosing characters in quotes which are part of
+      \member{escapedquotes} (e.g. \character{"}) preserves the literal
+      value of all characters within the quotes, with the exception of
+      the characters mentioned in \member{escape}. The escape characters
+      retain its special meaning only when followed by the quote in use,
+      or the escape character itself. Otherwise the escape character
+      will be considered a normal character.
+\item EOF is signaled with a \constant{None} value;
+\item Quoted empty strings (\code{''}) are allowed;
+\end{itemize}
+

Added: vendor/Python/current/Doc/lib/libshutil.tex
===================================================================
--- vendor/Python/current/Doc/lib/libshutil.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libshutil.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,151 @@
+\section{\module{shutil} ---
+         High-level file operations}
+
+\declaremodule{standard}{shutil}
+\modulesynopsis{High-level file operations, including copying.}
+\sectionauthor{Fred L. Drake, Jr.}{fdrake at acm.org}
+% partly based on the docstrings
+
+
+The \module{shutil} module offers a number of high-level operations on
+files and collections of files.  In particular, functions are provided 
+which support file copying and removal.
+\index{file!copying}
+\index{copying files}
+
+\strong{Caveat:}  On MacOS, the resource fork and other metadata are
+not used.  For file copies, this means that resources will be lost and 
+file type and creator codes will not be correct.
+
+
+\begin{funcdesc}{copyfile}{src, dst}
+  Copy the contents of the file named \var{src} to a file named
+  \var{dst}.  The destination location must be writable; otherwise, 
+  an \exception{IOError} exception will be raised.
+  If \var{dst} already exists, it will be replaced.  
+  Special files such as character or block devices
+  and pipes cannot be copied with this function.  \var{src} and
+  \var{dst} are path names given as strings.
+\end{funcdesc}
+
+\begin{funcdesc}{copyfileobj}{fsrc, fdst\optional{, length}}
+  Copy the contents of the file-like object \var{fsrc} to the
+  file-like object \var{fdst}.  The integer \var{length}, if given,
+  is the buffer size. In particular, a negative \var{length} value
+  means to copy the data without looping over the source data in
+  chunks; by default the data is read in chunks to avoid uncontrolled
+  memory consumption. Note that if the current file position of the
+  \var{fsrc} object is not 0, only the contents from the current file
+  position to the end of the file will be copied.
+\end{funcdesc}
+
+\begin{funcdesc}{copymode}{src, dst}
+  Copy the permission bits from \var{src} to \var{dst}.  The file
+  contents, owner, and group are unaffected.  \var{src} and \var{dst}
+  are path names given as strings.
+\end{funcdesc}
+
+\begin{funcdesc}{copystat}{src, dst}
+  Copy the permission bits, last access time, and last modification
+  time from \var{src} to \var{dst}.  The file contents, owner, and
+  group are unaffected.  \var{src} and \var{dst} are path names given
+  as strings.
+\end{funcdesc}
+
+\begin{funcdesc}{copy}{src, dst}
+  Copy the file \var{src} to the file or directory \var{dst}.  If
+  \var{dst} is a directory, a file with the same basename as \var{src} 
+  is created (or overwritten) in the directory specified.  Permission
+  bits are copied.  \var{src} and \var{dst} are path names given as
+  strings.
+\end{funcdesc}
+
+\begin{funcdesc}{copy2}{src, dst}
+  Similar to \function{copy()}, but last access time and last
+  modification time are copied as well.  This is similar to the
+  \UNIX{} command \program{cp} \programopt{-p}.
+\end{funcdesc}
+
+\begin{funcdesc}{copytree}{src, dst\optional{, symlinks}}
+  Recursively copy an entire directory tree rooted at \var{src}.  The
+  destination directory, named by \var{dst}, must not already exist;
+  it will be created as well as missing parent directories.
+  Permissions and times of directories are copied with \function{copystat()},
+  individual files are copied using \function{copy2()}.  
+  If \var{symlinks} is true, symbolic links in
+  the source tree are represented as symbolic links in the new tree;
+  if false or omitted, the contents of the linked files are copied to
+  the new tree.  If exception(s) occur, an \exception{Error} is raised
+  with a list of reasons.
+
+  The source code for this should be considered an example rather than 
+  a tool.
+
+  \versionchanged[\exception{Error} is raised if any exceptions occur during
+                  copying, rather than printing a message]{2.3}
+
+  \versionchanged[Create intermediate directories needed to create \var{dst},
+                  rather than raising an error. Copy permissions and times of
+		  directories using \function{copystat()}]{2.5}
+
+\end{funcdesc}
+
+\begin{funcdesc}{rmtree}{path\optional{, ignore_errors\optional{, onerror}}}
+  Delete an entire directory tree.\index{directory!deleting}
+  If \var{ignore_errors} is true,
+  errors resulting from failed removals will be ignored; if false or
+  omitted, such errors are handled by calling a handler specified by
+  \var{onerror} or, if that is omitted, they raise an exception.
+
+  If \var{onerror} is provided, it must be a callable that accepts
+  three parameters: \var{function}, \var{path}, and \var{excinfo}.
+  The first parameter, \var{function}, is the function which raised
+  the exception; it will be \function{os.listdir()}, \function{os.remove()} or
+  \function{os.rmdir()}.  The second parameter, \var{path}, will be
+  the path name passed to \var{function}.  The third parameter,
+  \var{excinfo}, will be the exception information return by
+  \function{sys.exc_info()}.  Exceptions raised by \var{onerror} will
+  not be caught.
+\end{funcdesc}
+
+\begin{funcdesc}{move}{src, dst}
+Recursively move a file or directory to another location.
+
+If the destination is on our current filesystem, then simply use
+rename.  Otherwise, copy src to the dst and then remove src.
+
+\versionadded{2.3}
+\end{funcdesc}
+
+\begin{excdesc}{Error}
+This exception collects exceptions that raised during a mult-file
+operation. For \function{copytree}, the exception argument is a
+list of 3-tuples (\var{srcname}, \var{dstname}, \var{exception}).
+
+\versionadded{2.3}
+\end{excdesc}
+
+\subsection{Example \label{shutil-example}}
+
+This example is the implementation of the \function{copytree()}
+function, described above, with the docstring omitted.  It
+demonstrates many of the other functions provided by this module.
+
+\begin{verbatim}
+def copytree(src, dst, symlinks=0):
+    names = os.listdir(src)
+    os.mkdir(dst)
+    for name in names:
+        srcname = os.path.join(src, name)
+        dstname = os.path.join(dst, name)
+        try:
+            if symlinks and os.path.islink(srcname):
+                linkto = os.readlink(srcname)
+                os.symlink(linkto, dstname)
+            elif os.path.isdir(srcname):
+                copytree(srcname, dstname, symlinks)
+            else:
+                copy2(srcname, dstname)
+        except (IOError, os.error), why:
+            print "Can't copy %s to %s: %s" % (`srcname`, `dstname`, str(why))
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/libsignal.tex
===================================================================
--- vendor/Python/current/Doc/lib/libsignal.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libsignal.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,174 @@
+\section{\module{signal} ---
+         Set handlers for asynchronous events}
+
+\declaremodule{builtin}{signal}
+\modulesynopsis{Set handlers for asynchronous events.}
+
+
+This module provides mechanisms to use signal handlers in Python.
+Some general rules for working with signals and their handlers:
+
+\begin{itemize}
+
+\item
+A handler for a particular signal, once set, remains installed until
+it is explicitly reset (Python emulates the BSD style interface
+regardless of the underlying implementation), with the exception of
+the handler for \constant{SIGCHLD}, which follows the underlying
+implementation.
+
+\item
+There is no way to ``block'' signals temporarily from critical
+sections (since this is not supported by all \UNIX{} flavors).
+
+\item
+Although Python signal handlers are called asynchronously as far as
+the Python user is concerned, they can only occur between the
+``atomic'' instructions of the Python interpreter.  This means that
+signals arriving during long calculations implemented purely in C
+(such as regular expression matches on large bodies of text) may be
+delayed for an arbitrary amount of time.
+
+\item
+When a signal arrives during an I/O operation, it is possible that the
+I/O operation raises an exception after the signal handler returns.
+This is dependent on the underlying \UNIX{} system's semantics regarding
+interrupted system calls.
+
+\item
+Because the \C{} signal handler always returns, it makes little sense to
+catch synchronous errors like \constant{SIGFPE} or \constant{SIGSEGV}.
+
+\item
+Python installs a small number of signal handlers by default:
+\constant{SIGPIPE} is ignored (so write errors on pipes and sockets can be
+reported as ordinary Python exceptions) and \constant{SIGINT} is translated
+into a \exception{KeyboardInterrupt} exception.  All of these can be
+overridden.
+
+\item
+Some care must be taken if both signals and threads are used in the
+same program.  The fundamental thing to remember in using signals and
+threads simultaneously is:\ always perform \function{signal()} operations
+in the main thread of execution.  Any thread can perform an
+\function{alarm()}, \function{getsignal()}, or \function{pause()};
+only the main thread can set a new signal handler, and the main thread
+will be the only one to receive signals (this is enforced by the
+Python \module{signal} module, even if the underlying thread
+implementation supports sending signals to individual threads).  This
+means that signals can't be used as a means of inter-thread
+communication.  Use locks instead.
+
+\end{itemize}
+
+The variables defined in the \module{signal} module are:
+
+\begin{datadesc}{SIG_DFL}
+  This is one of two standard signal handling options; it will simply
+  perform the default function for the signal.  For example, on most
+  systems the default action for \constant{SIGQUIT} is to dump core
+  and exit, while the default action for \constant{SIGCLD} is to
+  simply ignore it.
+\end{datadesc}
+
+\begin{datadesc}{SIG_IGN}
+  This is another standard signal handler, which will simply ignore
+  the given signal.
+\end{datadesc}
+
+\begin{datadesc}{SIG*}
+  All the signal numbers are defined symbolically.  For example, the
+  hangup signal is defined as \constant{signal.SIGHUP}; the variable names
+  are identical to the names used in C programs, as found in
+  \code{<signal.h>}.
+  The \UNIX{} man page for `\cfunction{signal()}' lists the existing
+  signals (on some systems this is \manpage{signal}{2}, on others the
+  list is in \manpage{signal}{7}).
+  Note that not all systems define the same set of signal names; only
+  those names defined by the system are defined by this module.
+\end{datadesc}
+
+\begin{datadesc}{NSIG}
+  One more than the number of the highest signal number.
+\end{datadesc}
+
+The \module{signal} module defines the following functions:
+
+\begin{funcdesc}{alarm}{time}
+  If \var{time} is non-zero, this function requests that a
+  \constant{SIGALRM} signal be sent to the process in \var{time} seconds.
+  Any previously scheduled alarm is canceled (only one alarm can
+  be scheduled at any time).  The returned value is then the number of
+  seconds before any previously set alarm was to have been delivered.
+  If \var{time} is zero, no alarm is scheduled, and any scheduled
+  alarm is canceled.  The return value is the number of seconds
+  remaining before a previously scheduled alarm.  If the return value
+  is zero, no alarm is currently scheduled.  (See the \UNIX{} man page
+  \manpage{alarm}{2}.)
+  Availability: \UNIX.
+\end{funcdesc}
+
+\begin{funcdesc}{getsignal}{signalnum}
+  Return the current signal handler for the signal \var{signalnum}.
+  The returned value may be a callable Python object, or one of the
+  special values \constant{signal.SIG_IGN}, \constant{signal.SIG_DFL} or
+  \constant{None}.  Here, \constant{signal.SIG_IGN} means that the
+  signal was previously ignored, \constant{signal.SIG_DFL} means that the
+  default way of handling the signal was previously in use, and
+  \code{None} means that the previous signal handler was not installed
+  from Python.
+\end{funcdesc}
+
+\begin{funcdesc}{pause}{}
+  Cause the process to sleep until a signal is received; the
+  appropriate handler will then be called.  Returns nothing.  Not on
+  Windows. (See the \UNIX{} man page \manpage{signal}{2}.)
+\end{funcdesc}
+
+\begin{funcdesc}{signal}{signalnum, handler}
+  Set the handler for signal \var{signalnum} to the function
+  \var{handler}.  \var{handler} can be a callable Python object
+  taking two arguments (see below), or
+  one of the special values \constant{signal.SIG_IGN} or
+  \constant{signal.SIG_DFL}.  The previous signal handler will be returned
+  (see the description of \function{getsignal()} above).  (See the
+  \UNIX{} man page \manpage{signal}{2}.)
+
+  When threads are enabled, this function can only be called from the
+  main thread; attempting to call it from other threads will cause a
+  \exception{ValueError} exception to be raised.
+
+  The \var{handler} is called with two arguments: the signal number
+  and the current stack frame (\code{None} or a frame object;
+  for a description of frame objects, see the reference manual section
+  on the standard type hierarchy or see the attribute descriptions in
+  the \refmodule{inspect} module).
+\end{funcdesc}
+
+\subsection{Example}
+\nodename{Signal Example}
+
+Here is a minimal example program. It uses the \function{alarm()}
+function to limit the time spent waiting to open a file; this is
+useful if the file is for a serial device that may not be turned on,
+which would normally cause the \function{os.open()} to hang
+indefinitely.  The solution is to set a 5-second alarm before opening
+the file; if the operation takes too long, the alarm signal will be
+sent, and the handler raises an exception.
+
+\begin{verbatim}
+import signal, os
+
+def handler(signum, frame):
+    print 'Signal handler called with signal', signum
+    raise IOError, "Couldn't open device!"
+
+# Set the signal handler and a 5-second alarm
+signal.signal(signal.SIGALRM, handler)
+signal.alarm(5)
+
+# This open() may hang indefinitely
+fd = os.open('/dev/ttyS0', os.O_RDWR)  
+
+signal.alarm(0)          # Disable the alarm
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/libsimplehttp.tex
===================================================================
--- vendor/Python/current/Doc/lib/libsimplehttp.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libsimplehttp.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,86 @@
+\section{\module{SimpleHTTPServer} ---
+         Simple HTTP request handler}
+
+\declaremodule{standard}{SimpleHTTPServer}
+\sectionauthor{Moshe Zadka}{moshez at zadka.site.co.il}
+\modulesynopsis{This module provides a basic request handler for HTTP
+                servers.}
+
+
+The \module{SimpleHTTPServer} module defines a request-handler class,
+interface-compatible with \class{BaseHTTPServer.BaseHTTPRequestHandler},
+that serves files only from a base directory.
+
+The \module{SimpleHTTPServer} module defines the following class:
+
+\begin{classdesc}{SimpleHTTPRequestHandler}{request, client_address, server}
+This class is used to serve files from the current directory and below,
+directly mapping the directory structure to HTTP requests.
+
+A lot of the work, such as parsing the request, is done by the base
+class \class{BaseHTTPServer.BaseHTTPRequestHandler}.  This class
+implements the \function{do_GET()} and \function{do_HEAD()} functions.
+\end{classdesc}
+
+The \class{SimpleHTTPRequestHandler} defines the following member
+variables:
+
+\begin{memberdesc}{server_version}
+This will be \code{"SimpleHTTP/" + __version__}, where \code{__version__}
+is defined in the module.
+\end{memberdesc}
+
+\begin{memberdesc}{extensions_map}
+A dictionary mapping suffixes into MIME types. The default is signified
+by an empty string, and is considered to be \code{application/octet-stream}.
+The mapping is used case-insensitively, and so should contain only
+lower-cased keys.
+\end{memberdesc}
+
+The \class{SimpleHTTPRequestHandler} defines the following methods:
+
+\begin{methoddesc}{do_HEAD}{}
+This method serves the \code{'HEAD'} request type: it sends the
+headers it would send for the equivalent \code{GET} request. See the
+\method{do_GET()} method for a more complete explanation of the possible
+headers.
+\end{methoddesc}
+
+\begin{methoddesc}{do_GET}{}
+The request is mapped to a local file by interpreting the request as
+a path relative to the current working directory.
+
+If the request was mapped to a directory, the directory is checked for
+a file named \code{index.html} or \code{index.htm} (in that order).
+If found, the file's contents are returned; otherwise a directory
+listing is generated by calling the \method{list_directory()} method.
+This method uses \function{os.listdir()} to scan the directory, and
+returns a \code{404} error response if the \function{listdir()} fails.
+
+If the request was mapped to a file, it is opened and the contents are
+returned.  Any \exception{IOError} exception in opening the requested
+file is mapped to a \code{404}, \code{'File not found'}
+error. Otherwise, the content type is guessed by calling the
+\method{guess_type()} method, which in turn uses the
+\var{extensions_map} variable.
+
+A \code{'Content-type:'} header with the guessed content type is
+output, followed by a \code{'Content-Length:'} header with the file's
+size and a \code{'Last-Modified:'} header with the file's modification
+time.
+
+Then follows a blank line signifying the end of the headers,
+and then the contents of the file are output. If the file's MIME type
+starts with \code{text/} the file is opened in text mode; otherwise
+binary mode is used.
+
+For example usage, see the implementation of the \function{test()}
+function.
+\versionadded[The \code{'Last-Modified'} header]{2.5}
+\end{methoddesc}
+
+
+\begin{seealso}
+  \seemodule{BaseHTTPServer}{Base class implementation for Web server
+                             and request handler.}
+\end{seealso}

Added: vendor/Python/current/Doc/lib/libsimplexmlrpc.tex
===================================================================
--- vendor/Python/current/Doc/lib/libsimplexmlrpc.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libsimplexmlrpc.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,228 @@
+\section{\module{SimpleXMLRPCServer} ---
+         Basic XML-RPC server}
+
+\declaremodule{standard}{SimpleXMLRPCServer}
+\modulesynopsis{Basic XML-RPC server implementation.}
+\moduleauthor{Brian Quinlan}{brianq at activestate.com}
+\sectionauthor{Fred L. Drake, Jr.}{fdrake at acm.org}
+
+\versionadded{2.2}
+
+The \module{SimpleXMLRPCServer} module provides a basic server
+framework for XML-RPC servers written in Python.  Servers can either
+be free standing, using \class{SimpleXMLRPCServer}, or embedded in a
+CGI environment, using \class{CGIXMLRPCRequestHandler}.
+
+\begin{classdesc}{SimpleXMLRPCServer}{addr\optional{,
+                                      requestHandler\optional{,
+					logRequests\optional{, allow_none\optional{, encoding}}}}}
+
+  Create a new server instance.  This class
+  provides methods for registration of functions that can be called by
+  the XML-RPC protocol.  The \var{requestHandler} parameter
+  should be a factory for request handler instances; it defaults to
+  \class{SimpleXMLRPCRequestHandler}.  The \var{addr} and
+  \var{requestHandler} parameters are passed to the
+  \class{\refmodule{SocketServer}.TCPServer} constructor.  If
+  \var{logRequests} is true (the default), requests will be logged;
+  setting this parameter to false will turn off logging.  
+  The \var{allow_none} and \var{encoding} parameters are passed on to 
+  \module{xmlrpclib} and control the XML-RPC responses that will be returned 
+  from the server.
+  \versionchanged[The \var{allow_none} and \var{encoding} parameters were added]{2.5}
+\end{classdesc}
+
+\begin{classdesc}{CGIXMLRPCRequestHandler}{\optional{allow_none\optional{, encoding}}}
+  Create a new instance to handle XML-RPC requests in a CGI
+  environment. 
+  The \var{allow_none} and \var{encoding} parameters are passed on to 
+  \module{xmlrpclib} and control the XML-RPC responses that will be returned 
+  from the server.
+  \versionadded{2.3}
+  \versionchanged[The \var{allow_none} and \var{encoding} parameters were added]{2.5}
+\end{classdesc}
+
+\begin{classdesc}{SimpleXMLRPCRequestHandler}{}
+  Create a new request handler instance.  This request handler
+  supports \code{POST} requests and modifies logging so that the
+  \var{logRequests} parameter to the \class{SimpleXMLRPCServer}
+  constructor parameter is honored.
+\end{classdesc}
+
+
+\subsection{SimpleXMLRPCServer Objects \label{simple-xmlrpc-servers}}
+
+The \class{SimpleXMLRPCServer} class is based on
+\class{SocketServer.TCPServer} and provides a means of creating
+simple, stand alone XML-RPC servers.
+
+\begin{methoddesc}[SimpleXMLRPCServer]{register_function}{function\optional{,
+                                                          name}}
+  Register a function that can respond to XML-RPC requests.  If
+  \var{name} is given, it will be the method name associated with
+  \var{function}, otherwise \code{\var{function}.__name__} will be
+  used.  \var{name} can be either a normal or Unicode string, and may
+  contain characters not legal in Python identifiers, including the
+  period character.
+\end{methoddesc}
+
+\begin{methoddesc}[SimpleXMLRPCServer]{register_instance}{instance\optional{,
+                                       allow_dotted_names}}
+  Register an object which is used to expose method names which have
+  not been registered using \method{register_function()}.  If
+  \var{instance} contains a \method{_dispatch()} method, it is called
+  with the requested method name and the parameters from the request.  Its
+  API is \code{def \method{_dispatch}(self, method, params)} (note that
+  \var{params} does not represent a variable argument list).  If it calls an
+  underlying function to perform its task, that function is called as
+  \code{func(*params)}, expanding the parameter list.
+  The return value from \method{_dispatch()} is returned to the client as
+  the result.  If
+  \var{instance} does not have a \method{_dispatch()} method, it is
+  searched for an attribute matching the name of the requested method.
+
+  If the optional \var{allow_dotted_names} argument is true and the
+  instance does not have a \method{_dispatch()} method, then
+  if the requested method name contains periods, each component of the
+  method name is searched for individually, with the effect that a
+  simple hierarchical search is performed.  The value found from this
+  search is then called with the parameters from the request, and the
+  return value is passed back to the client.
+
+  \begin{notice}[warning]
+  Enabling the \var{allow_dotted_names} option allows intruders to access
+  your module's global variables and may allow intruders to execute
+  arbitrary code on your machine.  Only use this option on a secure,
+  closed network.
+  \end{notice}
+
+  \versionchanged[\var{allow_dotted_names} was added to plug a security hole;
+  prior versions are insecure]{2.3.5, 2.4.1}
+
+\end{methoddesc}
+
+\begin{methoddesc}{register_introspection_functions}{}
+  Registers the XML-RPC introspection functions \code{system.listMethods},
+  \code{system.methodHelp} and \code{system.methodSignature}. 
+  \versionadded{2.3}
+\end{methoddesc}
+
+\begin{methoddesc}{register_multicall_functions}{}
+  Registers the XML-RPC multicall function system.multicall.
+\end{methoddesc}
+
+\begin{memberdesc}[SimpleXMLRPCServer]{rpc_paths}
+An attribute value that must be a tuple listing valid path portions of
+the URL for receiving XML-RPC requests.  Requests posted to other
+paths will result in a 404 ``no such page'' HTTP error.  If this
+tuple is empty, all paths will be considered valid.
+The default value is \code{('/', '/RPC2')}.
+  \versionadded{2.5}
+\end{memberdesc}
+
+Example:
+
+\begin{verbatim}
+from SimpleXMLRPCServer import SimpleXMLRPCServer
+
+# Create server
+server = SimpleXMLRPCServer(("localhost", 8000))
+server.register_introspection_functions()
+
+# Register pow() function; this will use the value of 
+# pow.__name__ as the name, which is just 'pow'.
+server.register_function(pow)
+
+# Register a function under a different name
+def adder_function(x,y):
+    return x + y
+server.register_function(adder_function, 'add')
+
+# Register an instance; all the methods of the instance are 
+# published as XML-RPC methods (in this case, just 'div').
+class MyFuncs:
+    def div(self, x, y): 
+        return x // y
+    
+server.register_instance(MyFuncs())
+
+# Run the server's main loop
+server.serve_forever()
+\end{verbatim}
+
+The following client code will call the methods made available by 
+the preceding server:
+
+\begin{verbatim}
+import xmlrpclib
+
+s = xmlrpclib.Server('http://localhost:8000')
+print s.pow(2,3)  # Returns 2**3 = 8
+print s.add(2,3)  # Returns 5
+print s.div(5,2)  # Returns 5//2 = 2
+
+# Print list of available methods
+print s.system.listMethods()
+\end{verbatim}
+
+
+\subsection{CGIXMLRPCRequestHandler}
+
+The \class{CGIXMLRPCRequestHandler} class can be used to 
+handle XML-RPC requests sent to Python CGI scripts.
+
+\begin{methoddesc}{register_function}{function\optional{, name}}
+Register a function that can respond to XML-RPC requests. If 
+\var{name} is given, it will be the method name associated with 
+function, otherwise \var{function.__name__} will be used. \var{name}
+can be either a normal or Unicode string, and may contain 
+characters not legal in Python identifiers, including the period
+character. 
+\end{methoddesc}
+
+\begin{methoddesc}{register_instance}{instance}
+Register an object which is used to expose method names 
+which have not been registered using \method{register_function()}. If 
+instance contains a \method{_dispatch()} method, it is called with the 
+requested method name and the parameters from the 
+request; the return value is returned to the client as the result.
+If instance does not have a \method{_dispatch()} method, it is searched 
+for an attribute matching the name of the requested method; if 
+the requested method name contains periods, each 
+component of the method name is searched for individually, 
+with the effect that a simple hierarchical search is performed. 
+The value found from this search is then called with the 
+parameters from the request, and the return value is passed 
+back to the client. 
+\end{methoddesc}
+
+\begin{methoddesc}{register_introspection_functions}{}
+Register the XML-RPC introspection functions 
+\code{system.listMethods}, \code{system.methodHelp} and 
+\code{system.methodSignature}.
+\end{methoddesc}
+
+\begin{methoddesc}{register_multicall_functions}{}
+Register the XML-RPC multicall function \code{system.multicall}.
+\end{methoddesc}
+
+\begin{methoddesc}{handle_request}{\optional{request_text = None}}
+Handle a XML-RPC request. If \var{request_text} is given, it 
+should be the POST data provided by the HTTP server, 
+otherwise the contents of stdin will be used.
+\end{methoddesc}
+
+Example:
+
+\begin{verbatim}
+class MyFuncs:
+    def div(self, x, y) : return x // y
+
+
+handler = CGIXMLRPCRequestHandler()
+handler.register_function(pow)
+handler.register_function(lambda x,y: x+y, 'add')
+handler.register_introspection_functions()
+handler.register_instance(MyFuncs())
+handler.handle_request()
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/libsite.tex
===================================================================
--- vendor/Python/current/Doc/lib/libsite.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libsite.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,88 @@
+\section{\module{site} ---
+         Site-specific configuration hook}
+
+\declaremodule{standard}{site}
+\modulesynopsis{A standard way to reference site-specific modules.}
+
+
+\strong{This module is automatically imported during initialization.}
+The automatic import can be suppressed using the interpreter's
+\programopt{-S} option.
+
+Importing this module will append site-specific paths to the module
+search path.
+\indexiii{module}{search}{path}
+
+It starts by constructing up to four directories from a head and a
+tail part.  For the head part, it uses \code{sys.prefix} and
+\code{sys.exec_prefix}; empty heads are skipped.  For
+the tail part, it uses the empty string and then
+\file{lib/site-packages} (on Windows) or
+\file{lib/python\shortversion/site-packages} and then
+\file{lib/site-python} (on \UNIX{} and Macintosh).  For each of the
+distinct head-tail combinations, it sees if it refers to an existing
+directory, and if so, adds it to \code{sys.path} and also inspects
+the newly added path for configuration files.
+\indexii{site-python}{directory}
+\indexii{site-packages}{directory}
+
+A path configuration file is a file whose name has the form
+\file{\var{package}.pth} and exists in one of the four directories
+mentioned above; its contents are additional items (one
+per line) to be added to \code{sys.path}.  Non-existing items are
+never added to \code{sys.path}, but no check is made that the item
+refers to a directory (rather than a file).  No item is added to
+\code{sys.path} more than once.  Blank lines and lines beginning with
+\code{\#} are skipped.  Lines starting with \code{import} are executed.
+\index{package}
+\indexiii{path}{configuration}{file}
+
+For example, suppose \code{sys.prefix} and \code{sys.exec_prefix} are
+set to \file{/usr/local}.  The Python \version\ library is then
+installed in \file{/usr/local/lib/python\shortversion} (where only the
+first three characters of \code{sys.version} are used to form the
+installation path name).  Suppose this has a subdirectory
+\file{/usr/local/lib/python\shortversion/site-packages} with three
+subsubdirectories, \file{foo}, \file{bar} and \file{spam}, and two
+path configuration files, \file{foo.pth} and \file{bar.pth}.  Assume
+\file{foo.pth} contains the following:
+
+\begin{verbatim}
+# foo package configuration
+
+foo
+bar
+bletch
+\end{verbatim}
+
+and \file{bar.pth} contains:
+
+\begin{verbatim}
+# bar package configuration
+
+bar
+\end{verbatim}
+
+Then the following directories are added to \code{sys.path}, in this
+order:
+
+\begin{verbatim}
+/usr/local/lib/python2.3/site-packages/bar
+/usr/local/lib/python2.3/site-packages/foo
+\end{verbatim}
+
+Note that \file{bletch} is omitted because it doesn't exist; the
+\file{bar} directory precedes the \file{foo} directory because
+\file{bar.pth} comes alphabetically before \file{foo.pth}; and
+\file{spam} is omitted because it is not mentioned in either path
+configuration file.
+
+After these path manipulations, an attempt is made to import a module
+named \module{sitecustomize}\refmodindex{sitecustomize}, which can
+perform arbitrary site-specific customizations.  If this import fails
+with an \exception{ImportError} exception, it is silently ignored.
+
+Note that for some non-\UNIX{} systems, \code{sys.prefix} and
+\code{sys.exec_prefix} are empty, and the path manipulations are
+skipped; however the import of
+\module{sitecustomize}\refmodindex{sitecustomize} is still attempted.

Added: vendor/Python/current/Doc/lib/libsmtpd.tex
===================================================================
--- vendor/Python/current/Doc/lib/libsmtpd.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libsmtpd.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,63 @@
+\section{\module{smtpd} ---
+         SMTP Server}
+
+\declaremodule{standard}{smtpd}
+
+\moduleauthor{Barry Warsaw}{barry at zope.com}
+\sectionauthor{Moshe Zadka}{moshez at moshez.org}
+
+\modulesynopsis{Implement a flexible SMTP server}
+
+This module offers several classes to implement SMTP servers.  One is
+a generic do-nothing implementation, which can be overridden, while
+the other two offer specific mail-sending strategies.
+
+
+\subsection{SMTPServer Objects}
+
+\begin{classdesc}{SMTPServer}{localaddr, remoteaddr}
+Create a new \class{SMTPServer} object, which binds to local address
+\var{localaddr}.  It will treat \var{remoteaddr} as an upstream SMTP
+relayer.  It inherits from \class{asyncore.dispatcher}, and so will
+insert itself into \refmodule{asyncore}'s event loop on instantiation.
+\end{classdesc}
+
+\begin{methoddesc}[SMTPServer]{process_message}{peer, mailfrom, rcpttos, data}
+Raise \exception{NotImplementedError} exception. Override this in
+subclasses to do something useful with this message. Whatever was
+passed in the constructor as \var{remoteaddr} will be available as the
+\member{_remoteaddr} attribute. \var{peer} is the remote host's address,
+\var{mailfrom} is the envelope originator, \var{rcpttos} are the
+envelope recipients and \var{data} is a string containing the contents
+of the e-mail (which should be in \rfc{2822} format).
+\end{methoddesc}
+
+
+\subsection{DebuggingServer Objects}
+
+\begin{classdesc}{DebuggingServer}{localaddr, remoteaddr}
+Create a new debugging server.  Arguments are as per
+\class{SMTPServer}.  Messages will be discarded, and printed on
+stdout.
+\end{classdesc}
+
+
+\subsection{PureProxy Objects}
+
+\begin{classdesc}{PureProxy}{localaddr, remoteaddr}
+Create a new pure proxy server. Arguments are as per \class{SMTPServer}.
+Everything will be relayed to \var{remoteaddr}.  Note that running
+this has a good chance to make you into an open relay, so please be
+careful.
+\end{classdesc}
+
+
+\subsection{MailmanProxy Objects}
+
+\begin{classdesc}{MailmanProxy}{localaddr, remoteaddr}
+Create a new pure proxy server. Arguments are as per
+\class{SMTPServer}.  Everything will be relayed to \var{remoteaddr},
+unless local mailman configurations knows about an address, in which
+case it will be handled via mailman.  Note that running this has a
+good chance to make you into an open relay, so please be careful.
+\end{classdesc}

Added: vendor/Python/current/Doc/lib/libsmtplib.tex
===================================================================
--- vendor/Python/current/Doc/lib/libsmtplib.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libsmtplib.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,295 @@
+\section{\module{smtplib} ---
+         SMTP protocol client}
+
+\declaremodule{standard}{smtplib}
+\modulesynopsis{SMTP protocol client (requires sockets).}
+\sectionauthor{Eric S. Raymond}{esr at snark.thyrsus.com}
+
+\indexii{SMTP}{protocol}
+\index{Simple Mail Transfer Protocol}
+
+The \module{smtplib} module defines an SMTP client session object that
+can be used to send mail to any Internet machine with an SMTP or ESMTP
+listener daemon.  For details of SMTP and ESMTP operation, consult
+\rfc{821} (\citetitle{Simple Mail Transfer Protocol}) and \rfc{1869}
+(\citetitle{SMTP Service Extensions}).
+
+\begin{classdesc}{SMTP}{\optional{host\optional{, port\optional{,
+                        local_hostname}}}}
+A \class{SMTP} instance encapsulates an SMTP connection.  It has
+methods that support a full repertoire of SMTP and ESMTP
+operations. If the optional host and port parameters are given, the
+SMTP \method{connect()} method is called with those parameters during
+initialization.  An \exception{SMTPConnectError} is raised if the
+specified host doesn't respond correctly.
+
+For normal use, you should only require the initialization/connect,
+\method{sendmail()}, and \method{quit()} methods.  An example is
+included below.
+\end{classdesc}
+
+
+A nice selection of exceptions is defined as well:
+
+\begin{excdesc}{SMTPException}
+  Base exception class for all exceptions raised by this module.
+\end{excdesc}
+
+\begin{excdesc}{SMTPServerDisconnected}
+  This exception is raised when the server unexpectedly disconnects,
+  or when an attempt is made to use the \class{SMTP} instance before
+  connecting it to a server.
+\end{excdesc}
+
+\begin{excdesc}{SMTPResponseException}
+  Base class for all exceptions that include an SMTP error code.
+  These exceptions are generated in some instances when the SMTP
+  server returns an error code.  The error code is stored in the
+  \member{smtp_code} attribute of the error, and the
+  \member{smtp_error} attribute is set to the error message.
+\end{excdesc}
+
+\begin{excdesc}{SMTPSenderRefused}
+  Sender address refused.  In addition to the attributes set by on all
+  \exception{SMTPResponseException} exceptions, this sets `sender' to
+  the string that the SMTP server refused.
+\end{excdesc}
+
+\begin{excdesc}{SMTPRecipientsRefused}
+  All recipient addresses refused.  The errors for each recipient are
+  accessible through the attribute \member{recipients}, which is a
+  dictionary of exactly the same sort as \method{SMTP.sendmail()}
+  returns.
+\end{excdesc}
+
+\begin{excdesc}{SMTPDataError}
+  The SMTP server refused to accept the message data.
+\end{excdesc}
+
+\begin{excdesc}{SMTPConnectError}
+  Error occurred during establishment of a connection  with the server.
+\end{excdesc}
+
+\begin{excdesc}{SMTPHeloError}
+  The server refused our \samp{HELO} message.
+\end{excdesc}
+
+
+\begin{seealso}
+  \seerfc{821}{Simple Mail Transfer Protocol}{Protocol definition for
+          SMTP.  This document covers the model, operating procedure,
+          and protocol details for SMTP.}
+  \seerfc{1869}{SMTP Service Extensions}{Definition of the ESMTP
+          extensions for SMTP.  This describes a framework for
+          extending SMTP with new commands, supporting dynamic
+          discovery of the commands provided by the server, and
+          defines a few additional commands.}
+\end{seealso}
+
+
+\subsection{SMTP Objects \label{SMTP-objects}}
+
+An \class{SMTP} instance has the following methods:
+
+\begin{methoddesc}{set_debuglevel}{level}
+Set the debug output level.  A true value for \var{level} results in
+debug messages for connection and for all messages sent to and
+received from the server.
+\end{methoddesc}
+
+\begin{methoddesc}{connect}{\optional{host\optional{, port}}}
+Connect to a host on a given port.  The defaults are to connect to the
+local host at the standard SMTP port (25).
+If the hostname ends with a colon (\character{:}) followed by a
+number, that suffix will be stripped off and the number interpreted as
+the port number to use.
+This method is automatically invoked by the constructor if a
+host is specified during instantiation.
+\end{methoddesc}
+
+\begin{methoddesc}{docmd}{cmd, \optional{, argstring}}
+Send a command \var{cmd} to the server.  The optional argument
+\var{argstring} is simply concatenated to the command, separated by a
+space.
+
+This returns a 2-tuple composed of a numeric response code and the
+actual response line (multiline responses are joined into one long
+line.)
+
+In normal operation it should not be necessary to call this method
+explicitly.  It is used to implement other methods and may be useful
+for testing private extensions.
+
+If the connection to the server is lost while waiting for the reply,
+\exception{SMTPServerDisconnected} will be raised.
+\end{methoddesc}
+
+\begin{methoddesc}{helo}{\optional{hostname}}
+Identify yourself to the SMTP server using \samp{HELO}.  The hostname
+argument defaults to the fully qualified domain name of the local
+host.
+
+In normal operation it should not be necessary to call this method
+explicitly.  It will be implicitly called by the \method{sendmail()}
+when necessary.
+\end{methoddesc}
+
+\begin{methoddesc}{ehlo}{\optional{hostname}}
+Identify yourself to an ESMTP server using \samp{EHLO}.  The hostname
+argument defaults to the fully qualified domain name of the local
+host.  Examine the response for ESMTP option and store them for use by
+\method{has_extn()}.
+
+Unless you wish to use \method{has_extn()} before sending
+mail, it should not be necessary to call this method explicitly.  It
+will be implicitly called by \method{sendmail()} when necessary.
+\end{methoddesc}
+
+\begin{methoddesc}{has_extn}{name}
+Return \constant{True} if \var{name} is in the set of SMTP service
+extensions returned by the server, \constant{False} otherwise.
+Case is ignored.
+\end{methoddesc}
+
+\begin{methoddesc}{verify}{address}
+Check the validity of an address on this server using SMTP \samp{VRFY}.
+Returns a tuple consisting of code 250 and a full \rfc{822} address
+(including human name) if the user address is valid. Otherwise returns
+an SMTP error code of 400 or greater and an error string.
+
+\note{Many sites disable SMTP \samp{VRFY} in order to foil spammers.}
+\end{methoddesc}
+
+\begin{methoddesc}{login}{user, password}
+Log in on an SMTP server that requires authentication.
+The arguments are the username and the password to authenticate with.
+If there has been no previous \samp{EHLO} or \samp{HELO} command this
+session, this method tries ESMTP \samp{EHLO} first.
+This method will return normally if the authentication was successful,
+or may raise the following exceptions:
+
+\begin{description}
+  \item[\exception{SMTPHeloError}]
+    The server didn't reply properly to the \samp{HELO} greeting.
+  \item[\exception{SMTPAuthenticationError}]
+    The server didn't accept the username/password combination.
+  \item[\exception{SMTPException}]
+    No suitable authentication method was found.
+\end{description}
+\end{methoddesc}
+
+\begin{methoddesc}{starttls}{\optional{keyfile\optional{, certfile}}}
+Put the SMTP connection in TLS (Transport Layer Security) mode.  All
+SMTP commands that follow will be encrypted.  You should then call
+\method{ehlo()} again.
+
+If \var{keyfile} and \var{certfile} are provided, these are passed to
+the \refmodule{socket} module's \function{ssl()} function.
+\end{methoddesc}
+
+\begin{methoddesc}{sendmail}{from_addr, to_addrs, msg\optional{,
+                             mail_options, rcpt_options}}
+Send mail.  The required arguments are an \rfc{822} from-address
+string, a list of \rfc{822} to-address strings (a bare string will be
+treated as a list with 1 address), and a message string.  The caller
+may pass a list of ESMTP options (such as \samp{8bitmime}) to be used
+in \samp{MAIL FROM} commands as \var{mail_options}.  ESMTP options
+(such as \samp{DSN} commands) that should be used with all \samp{RCPT}
+commands can be passed as \var{rcpt_options}.  (If you need to use
+different ESMTP options to different recipients you have to use the
+low-level methods such as \method{mail}, \method{rcpt} and
+\method{data} to send the message.)
+
+\note{The \var{from_addr} and \var{to_addrs} parameters are
+used to construct the message envelope used by the transport agents.
+The \class{SMTP} does not modify the message headers in any way.}
+
+If there has been no previous \samp{EHLO} or \samp{HELO} command this
+session, this method tries ESMTP \samp{EHLO} first. If the server does
+ESMTP, message size and each of the specified options will be passed
+to it (if the option is in the feature set the server advertises).  If
+\samp{EHLO} fails, \samp{HELO} will be tried and ESMTP options
+suppressed.
+
+This method will return normally if the mail is accepted for at least
+one recipient. Otherwise it will throw an exception.  That is, if this
+method does not throw an exception, then someone should get your mail.
+If this method does not throw an exception, it returns a dictionary,
+with one entry for each recipient that was refused.  Each entry
+contains a tuple of the SMTP error code and the accompanying error
+message sent by the server.
+
+This method may raise the following exceptions:
+
+\begin{description}
+\item[\exception{SMTPRecipientsRefused}]
+All recipients were refused.  Nobody got the mail.  The
+\member{recipients} attribute of the exception object is a dictionary
+with information about the refused recipients (like the one returned
+when at least one recipient was accepted).
+
+\item[\exception{SMTPHeloError}]
+The server didn't reply properly to the \samp{HELO} greeting.
+
+\item[\exception{SMTPSenderRefused}]
+The server didn't accept the \var{from_addr}.
+
+\item[\exception{SMTPDataError}]
+The server replied with an unexpected error code (other than a refusal
+of a recipient).
+\end{description}
+
+Unless otherwise noted, the connection will be open even after
+an exception is raised.
+
+\end{methoddesc}
+
+\begin{methoddesc}{quit}{}
+Terminate the SMTP session and close the connection.
+\end{methoddesc}
+
+Low-level methods corresponding to the standard SMTP/ESMTP commands
+\samp{HELP}, \samp{RSET}, \samp{NOOP}, \samp{MAIL}, \samp{RCPT}, and
+\samp{DATA} are also supported.  Normally these do not need to be
+called directly, so they are not documented here.  For details,
+consult the module code.
+
+
+\subsection{SMTP Example \label{SMTP-example}}
+
+This example prompts the user for addresses needed in the message
+envelope (`To' and `From' addresses), and the message to be
+delivered.  Note that the headers to be included with the message must
+be included in the message as entered; this example doesn't do any
+processing of the \rfc{822} headers.  In particular, the `To' and
+`From' addresses must be included in the message headers explicitly.
+
+\begin{verbatim}
+import smtplib
+
+def prompt(prompt):
+    return raw_input(prompt).strip()
+
+fromaddr = prompt("From: ")
+toaddrs  = prompt("To: ").split()
+print "Enter message, end with ^D (Unix) or ^Z (Windows):"
+
+# Add the From: and To: headers at the start!
+msg = ("From: %s\r\nTo: %s\r\n\r\n"
+       % (fromaddr, ", ".join(toaddrs)))
+while 1:
+    try:
+        line = raw_input()
+    except EOFError:
+        break
+    if not line:
+        break
+    msg = msg + line
+
+print "Message length is " + repr(len(msg))
+
+server = smtplib.SMTP('localhost')
+server.set_debuglevel(1)
+server.sendmail(fromaddr, toaddrs, msg)
+server.quit()
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/libsndhdr.tex
===================================================================
--- vendor/Python/current/Doc/lib/libsndhdr.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libsndhdr.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,41 @@
+\section{\module{sndhdr} ---
+         Determine type of sound file}
+
+\declaremodule{standard}{sndhdr}
+\modulesynopsis{Determine type of a sound file.}
+\sectionauthor{Fred L. Drake, Jr.}{fdrake at acm.org}
+% Based on comments in the module source file.
+
+
+The \module{sndhdr} provides utility functions which attempt to
+determine the type of sound data which is in a file.  When these
+functions are able to determine what type of sound data is stored in a
+file, they return a tuple \code{(\var{type}, \var{sampling_rate},
+\var{channels}, \var{frames}, \var{bits_per_sample})}.  The value for
+\var{type} indicates the data type and will be one of the strings
+\code{'aifc'}, \code{'aiff'}, \code{'au'}, \code{'hcom'},
+\code{'sndr'}, \code{'sndt'}, \code{'voc'}, \code{'wav'},
+\code{'8svx'}, \code{'sb'}, \code{'ub'}, or \code{'ul'}.  The
+\var{sampling_rate} will be either the actual value or \code{0} if
+unknown or difficult to decode.  Similarly, \var{channels} will be
+either the number of channels or \code{0} if it cannot be determined
+or if the value is difficult to decode.  The value for \var{frames}
+will be either the number of frames or \code{-1}.  The last item in
+the tuple, \var{bits_per_sample}, will either be the sample size in
+bits or \code{'A'} for A-LAW\index{A-LAW} or \code{'U'} for
+u-LAW\index{u-LAW}.
+
+
+\begin{funcdesc}{what}{filename}
+  Determines the type of sound data stored in the file \var{filename}
+  using \function{whathdr()}.  If it succeeds, returns a tuple as
+  described above, otherwise \code{None} is returned.
+\end{funcdesc}
+
+
+\begin{funcdesc}{whathdr}{filename}
+  Determines the type of sound data stored in a file based on the file 
+  header.  The name of the file is given by \var{filename}.  This
+  function returns a tuple as described above on success, or
+  \code{None}.
+\end{funcdesc}

Added: vendor/Python/current/Doc/lib/libsocket.tex
===================================================================
--- vendor/Python/current/Doc/lib/libsocket.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libsocket.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,910 @@
+\section{\module{socket} ---
+         Low-level networking interface}
+
+\declaremodule{builtin}{socket}
+\modulesynopsis{Low-level networking interface.}
+
+
+This module provides access to the BSD \emph{socket} interface.
+It is available on all modern \UNIX{} systems, Windows, MacOS, BeOS,
+OS/2, and probably additional platforms.  \note{Some behavior may be
+platform dependent, since calls are made to the operating system socket APIs.}
+
+For an introduction to socket programming (in C), see the following
+papers: \citetitle{An Introductory 4.3BSD Interprocess Communication
+Tutorial}, by Stuart Sechrest and \citetitle{An Advanced 4.3BSD
+Interprocess Communication Tutorial}, by Samuel J.  Leffler et al,
+both in the \citetitle{\UNIX{} Programmer's Manual, Supplementary Documents 1}
+(sections PS1:7 and PS1:8).  The platform-specific reference material
+for the various socket-related system calls are also a valuable source
+of information on the details of socket semantics.  For \UNIX, refer
+to the manual pages; for Windows, see the WinSock (or Winsock 2)
+specification.
+For IPv6-ready APIs, readers may want to refer to \rfc{2553} titled
+\citetitle{Basic Socket Interface Extensions for IPv6}.
+
+The Python interface is a straightforward transliteration of the
+\UNIX{} system call and library interface for sockets to Python's
+object-oriented style: the \function{socket()} function returns a
+\dfn{socket object}\obindex{socket} whose methods implement the
+various socket system calls.  Parameter types are somewhat
+higher-level than in the C interface: as with \method{read()} and
+\method{write()} operations on Python files, buffer allocation on
+receive operations is automatic, and buffer length is implicit on send
+operations.
+
+Socket addresses are represented as follows:
+A single string is used for the \constant{AF_UNIX} address family.
+A pair \code{(\var{host}, \var{port})} is used for the
+\constant{AF_INET} address family, where \var{host} is a string
+representing either a hostname in Internet domain notation like
+\code{'daring.cwi.nl'} or an IPv4 address like \code{'100.50.200.5'},
+and \var{port} is an integral port number.
+For \constant{AF_INET6} address family, a four-tuple
+\code{(\var{host}, \var{port}, \var{flowinfo}, \var{scopeid})} is
+used, where \var{flowinfo} and \var{scopeid} represents
+\code{sin6_flowinfo} and \code{sin6_scope_id} member in
+\constant{struct sockaddr_in6} in C.
+For \module{socket} module methods, \var{flowinfo} and \var{scopeid}
+can be omitted just for backward compatibility. Note, however,
+omission of \var{scopeid} can cause problems in manipulating scoped
+IPv6 addresses. Other address families are currently not supported.
+The address format required by a particular socket object is
+automatically selected based on the address family specified when the
+socket object was created.
+
+For IPv4 addresses, two special forms are accepted instead of a host
+address: the empty string represents \constant{INADDR_ANY}, and the string
+\code{'<broadcast>'} represents \constant{INADDR_BROADCAST}.
+The behavior is not available for IPv6 for backward compatibility,
+therefore, you may want to avoid these if you intend to support IPv6 with
+your Python programs.
+
+If you use a hostname in the \var{host} portion of IPv4/v6 socket
+address, the program may show a nondeterministic behavior, as Python
+uses the first address returned from the DNS resolution.  The socket
+address will be resolved differently into an actual IPv4/v6 address,
+depending on the results from DNS resolution and/or the host
+configuration.  For deterministic behavior use a numeric address in
+\var{host} portion.
+
+\versionadded[AF_NETLINK sockets are represented as 
+pairs \code{\var{pid}, \var{groups}}]{2.5}
+
+All errors raise exceptions.  The normal exceptions for invalid
+argument types and out-of-memory conditions can be raised; errors
+related to socket or address semantics raise the error
+\exception{socket.error}.
+
+Non-blocking mode is supported through
+\method{setblocking()}.  A generalization of this based on timeouts
+is supported through \method{settimeout()}.
+
+The module \module{socket} exports the following constants and functions:
+
+
+\begin{excdesc}{error}
+This exception is raised for socket-related errors.
+The accompanying value is either a string telling what went wrong or a
+pair \code{(\var{errno}, \var{string})}
+representing an error returned by a system
+call, similar to the value accompanying \exception{os.error}.
+See the module \refmodule{errno}\refbimodindex{errno}, which contains
+names for the error codes defined by the underlying operating system.
+\end{excdesc}
+
+\begin{excdesc}{herror}
+This exception is raised for address-related errors, i.e. for
+functions that use \var{h_errno} in the C API, including
+\function{gethostbyname_ex()} and \function{gethostbyaddr()}.
+
+The accompanying value is a pair \code{(\var{h_errno}, \var{string})}
+representing an error returned by a library call. \var{string}
+represents the description of \var{h_errno}, as returned by
+the \cfunction{hstrerror()} C function.
+\end{excdesc}
+
+\begin{excdesc}{gaierror}
+This exception is raised for address-related errors, for
+\function{getaddrinfo()} and \function{getnameinfo()}.
+The accompanying value is a pair \code{(\var{error}, \var{string})}
+representing an error returned by a library call.
+\var{string} represents the description of \var{error}, as returned
+by the \cfunction{gai_strerror()} C function.
+The \var{error} value will match one of the \constant{EAI_*} constants
+defined in this module.
+\end{excdesc}
+
+\begin{excdesc}{timeout}
+This exception is raised when a timeout occurs on a socket which has
+had timeouts enabled via a prior call to \method{settimeout()}.  The
+accompanying value is a string whose value is currently always ``timed
+out''.
+\versionadded{2.3}
+\end{excdesc}
+
+\begin{datadesc}{AF_UNIX}
+\dataline{AF_INET}
+\dataline{AF_INET6}
+These constants represent the address (and protocol) families,
+used for the first argument to \function{socket()}.  If the
+\constant{AF_UNIX} constant is not defined then this protocol is
+unsupported.
+\end{datadesc}
+
+\begin{datadesc}{SOCK_STREAM}
+\dataline{SOCK_DGRAM}
+\dataline{SOCK_RAW}
+\dataline{SOCK_RDM}
+\dataline{SOCK_SEQPACKET}
+These constants represent the socket types,
+used for the second argument to \function{socket()}.
+(Only \constant{SOCK_STREAM} and
+\constant{SOCK_DGRAM} appear to be generally useful.)
+\end{datadesc}
+
+\begin{datadesc}{SO_*}
+\dataline{SOMAXCONN}
+\dataline{MSG_*}
+\dataline{SOL_*}
+\dataline{IPPROTO_*}
+\dataline{IPPORT_*}
+\dataline{INADDR_*}
+\dataline{IP_*}
+\dataline{IPV6_*}
+\dataline{EAI_*}
+\dataline{AI_*}
+\dataline{NI_*}
+\dataline{TCP_*}
+Many constants of these forms, documented in the \UNIX{} documentation on
+sockets and/or the IP protocol, are also defined in the socket module.
+They are generally used in arguments to the \method{setsockopt()} and
+\method{getsockopt()} methods of socket objects.  In most cases, only
+those symbols that are defined in the \UNIX{} header files are defined;
+for a few symbols, default values are provided.
+\end{datadesc}
+
+\begin{datadesc}{has_ipv6}
+This constant contains a boolean value which indicates if IPv6 is
+supported on this platform.
+\versionadded{2.3}
+\end{datadesc}
+
+\begin{funcdesc}{getaddrinfo}{host, port\optional{, family\optional{,
+                              socktype\optional{, proto\optional{,
+                              flags}}}}}
+Resolves the \var{host}/\var{port} argument, into a sequence of
+5-tuples that contain all the necessary argument for the sockets
+manipulation. \var{host} is a domain name, a string representation of
+IPv4/v6 address or \code{None}.
+\var{port} is a string service name (like \code{'http'}), a numeric
+port number or \code{None}.
+
+The rest of the arguments are optional and must be numeric if
+specified.  For \var{host} and \var{port}, by passing either an empty
+string or \code{None}, you can pass \code{NULL} to the C API.  The
+\function{getaddrinfo()} function returns a list of 5-tuples with
+the following structure:
+
+\code{(\var{family}, \var{socktype}, \var{proto}, \var{canonname},
+      \var{sockaddr})}
+
+\var{family}, \var{socktype}, \var{proto} are all integer and are meant to
+be passed to the \function{socket()} function.
+\var{canonname} is a string representing the canonical name of the \var{host}.
+It can be a numeric IPv4/v6 address when \constant{AI_CANONNAME} is specified
+for a numeric \var{host}.
+\var{sockaddr} is a tuple describing a socket address, as described above.
+See the source for the \refmodule{httplib} and other library modules
+for a typical usage of the function.
+\versionadded{2.2}
+\end{funcdesc}
+
+\begin{funcdesc}{getfqdn}{\optional{name}}
+Return a fully qualified domain name for \var{name}.
+If \var{name} is omitted or empty, it is interpreted as the local
+host.  To find the fully qualified name, the hostname returned by
+\function{gethostbyaddr()} is checked, then aliases for the host, if
+available.  The first name which includes a period is selected.  In
+case no fully qualified domain name is available, the hostname as
+returned by \function{gethostname()} is returned.
+\versionadded{2.0}
+\end{funcdesc}
+
+\begin{funcdesc}{gethostbyname}{hostname}
+Translate a host name to IPv4 address format.  The IPv4 address is
+returned as a string, such as  \code{'100.50.200.5'}.  If the host name
+is an IPv4 address itself it is returned unchanged.  See
+\function{gethostbyname_ex()} for a more complete interface.
+\function{gethostbyname()} does not support IPv6 name resolution, and
+\function{getaddrinfo()} should be used instead for IPv4/v6 dual stack support.
+\end{funcdesc}
+
+\begin{funcdesc}{gethostbyname_ex}{hostname}
+Translate a host name to IPv4 address format, extended interface.
+Return a triple \code{(\var{hostname}, \var{aliaslist},
+\var{ipaddrlist})} where
+\var{hostname} is the primary host name responding to the given
+\var{ip_address}, \var{aliaslist} is a (possibly empty) list of
+alternative host names for the same address, and \var{ipaddrlist} is
+a list of IPv4 addresses for the same interface on the same
+host (often but not always a single address).
+\function{gethostbyname_ex()} does not support IPv6 name resolution, and
+\function{getaddrinfo()} should be used instead for IPv4/v6 dual stack support.
+\end{funcdesc}
+
+\begin{funcdesc}{gethostname}{}
+Return a string containing the hostname of the machine where 
+the Python interpreter is currently executing.
+If you want to know the current machine's IP address, you may want to use
+\code{gethostbyname(gethostname())}.
+This operation assumes that there is a valid address-to-host mapping for
+the host, and the assumption does not always hold.
+Note: \function{gethostname()} doesn't always return the fully qualified
+domain name; use \code{getfqdn()}
+(see above).
+\end{funcdesc}
+
+\begin{funcdesc}{gethostbyaddr}{ip_address}
+Return a triple \code{(\var{hostname}, \var{aliaslist},
+\var{ipaddrlist})} where \var{hostname} is the primary host name
+responding to the given \var{ip_address}, \var{aliaslist} is a
+(possibly empty) list of alternative host names for the same address,
+and \var{ipaddrlist} is a list of IPv4/v6 addresses for the same interface
+on the same host (most likely containing only a single address).
+To find the fully qualified domain name, use the function
+\function{getfqdn()}.
+\function{gethostbyaddr} supports both IPv4 and IPv6.
+\end{funcdesc}
+
+\begin{funcdesc}{getnameinfo}{sockaddr, flags}
+Translate a socket address \var{sockaddr} into a 2-tuple
+\code{(\var{host}, \var{port})}.
+Depending on the settings of \var{flags}, the result can contain a
+fully-qualified domain name or numeric address representation in
+\var{host}.  Similarly, \var{port} can contain a string port name or a
+numeric port number.
+\versionadded{2.2}
+\end{funcdesc}
+
+\begin{funcdesc}{getprotobyname}{protocolname}
+Translate an Internet protocol name (for example, \code{'icmp'}) to a constant
+suitable for passing as the (optional) third argument to the
+\function{socket()} function.  This is usually only needed for sockets
+opened in ``raw'' mode (\constant{SOCK_RAW}); for the normal socket
+modes, the correct protocol is chosen automatically if the protocol is
+omitted or zero.
+\end{funcdesc}
+
+\begin{funcdesc}{getservbyname}{servicename\optional{, protocolname}}
+Translate an Internet service name and protocol name to a port number
+for that service.  The optional protocol name, if given, should be
+\code{'tcp'} or \code{'udp'}, otherwise any protocol will match.
+\end{funcdesc}
+
+\begin{funcdesc}{getservbyport}{port\optional{, protocolname}}
+Translate an Internet port number and protocol name to a service name
+for that service.  The optional protocol name, if given, should be
+\code{'tcp'} or \code{'udp'}, otherwise any protocol will match.
+\end{funcdesc}
+
+\begin{funcdesc}{socket}{\optional{family\optional{,
+                         type\optional{, proto}}}}
+Create a new socket using the given address family, socket type and
+protocol number.  The address family should be \constant{AF_INET} (the
+default), \constant{AF_INET6} or \constant{AF_UNIX}.  The socket type
+should be \constant{SOCK_STREAM} (the default), \constant{SOCK_DGRAM}
+or perhaps one of the other \samp{SOCK_} constants.  The protocol
+number is usually zero and may be omitted in that case.
+\end{funcdesc}
+
+\begin{funcdesc}{ssl}{sock\optional{, keyfile, certfile}}
+Initiate a SSL connection over the socket \var{sock}. \var{keyfile} is
+the name of a PEM formatted file that contains your private
+key. \var{certfile} is a PEM formatted certificate chain file. On
+success, a new \class{SSLObject} is returned.
+
+\warning{This does not do any certificate verification!}
+\end{funcdesc}
+
+\begin{funcdesc}{socketpair}{\optional{family\optional{, type\optional{, proto}}}}
+Build a pair of connected socket objects using the given address
+family, socket type, and protocol number.  Address family, socket type,
+and protocol number are as for the \function{socket()} function above.
+The default family is \constant{AF_UNIX} if defined on the platform;
+otherwise, the default is \constant{AF_INET}.
+Availability: \UNIX.  \versionadded{2.4}
+\end{funcdesc}
+
+\begin{funcdesc}{fromfd}{fd, family, type\optional{, proto}}
+Duplicate the file descriptor \var{fd} (an integer as returned by a file
+object's \method{fileno()} method) and build a socket object from the
+result.  Address family, socket type and protocol number are as for the
+\function{socket()} function above.
+The file descriptor should refer to a socket, but this is not
+checked --- subsequent operations on the object may fail if the file
+descriptor is invalid.  This function is rarely needed, but can be
+used to get or set socket options on a socket passed to a program as
+standard input or output (such as a server started by the \UNIX{} inet
+daemon).  The socket is assumed to be in blocking mode.
+Availability: \UNIX.
+\end{funcdesc}
+
+\begin{funcdesc}{ntohl}{x}
+Convert 32-bit integers from network to host byte order.  On machines
+where the host byte order is the same as network byte order, this is a
+no-op; otherwise, it performs a 4-byte swap operation.
+\end{funcdesc}
+
+\begin{funcdesc}{ntohs}{x}
+Convert 16-bit integers from network to host byte order.  On machines
+where the host byte order is the same as network byte order, this is a
+no-op; otherwise, it performs a 2-byte swap operation.
+\end{funcdesc}
+
+\begin{funcdesc}{htonl}{x}
+Convert 32-bit integers from host to network byte order.  On machines
+where the host byte order is the same as network byte order, this is a
+no-op; otherwise, it performs a 4-byte swap operation.
+\end{funcdesc}
+
+\begin{funcdesc}{htons}{x}
+Convert 16-bit integers from host to network byte order.  On machines
+where the host byte order is the same as network byte order, this is a
+no-op; otherwise, it performs a 2-byte swap operation.
+\end{funcdesc}
+
+\begin{funcdesc}{inet_aton}{ip_string}
+Convert an IPv4 address from dotted-quad string format (for example,
+'123.45.67.89') to 32-bit packed binary format, as a string four
+characters in length.  This is useful when conversing with a program
+that uses the standard C library and needs objects of type
+\ctype{struct in_addr}, which is the C type for the 32-bit packed
+binary this function returns.
+
+If the IPv4 address string passed to this function is invalid,
+\exception{socket.error} will be raised. Note that exactly what is
+valid depends on the underlying C implementation of
+\cfunction{inet_aton()}.
+
+\function{inet_aton()} does not support IPv6, and
+\function{getnameinfo()} should be used instead for IPv4/v6 dual stack
+support.
+\end{funcdesc}
+
+\begin{funcdesc}{inet_ntoa}{packed_ip}
+Convert a 32-bit packed IPv4 address (a string four characters in
+length) to its standard dotted-quad string representation (for
+example, '123.45.67.89').  This is useful when conversing with a
+program that uses the standard C library and needs objects of type
+\ctype{struct in_addr}, which is the C type for the 32-bit packed
+binary data this function takes as an argument.
+
+If the string passed to this function is not exactly 4 bytes in
+length, \exception{socket.error} will be raised.
+\function{inet_ntoa()} does not support IPv6, and
+\function{getnameinfo()} should be used instead for IPv4/v6 dual stack
+support.
+\end{funcdesc}
+
+\begin{funcdesc}{inet_pton}{address_family, ip_string}
+Convert an IP address from its family-specific string format to a packed,
+binary format.
+\function{inet_pton()} is useful when a library or network protocol calls for
+an object of type \ctype{struct in_addr} (similar to \function{inet_aton()})
+or \ctype{struct in6_addr}.
+
+Supported values for \var{address_family} are currently
+\constant{AF_INET} and \constant{AF_INET6}.
+If the IP address string \var{ip_string} is invalid,
+\exception{socket.error} will be raised. Note that exactly what is valid
+depends on both the value of \var{address_family} and the underlying
+implementation of \cfunction{inet_pton()}.
+
+Availability: \UNIX{} (maybe not all platforms).
+\versionadded{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{inet_ntop}{address_family, packed_ip}
+Convert a packed IP address (a string of some number of characters) to
+its standard, family-specific string representation (for example,
+\code{'7.10.0.5'} or \code{'5aef:2b::8'})
+\function{inet_ntop()} is useful when a library or network protocol returns
+an object of type \ctype{struct in_addr} (similar to \function{inet_ntoa()})
+or \ctype{struct in6_addr}.
+
+Supported values for \var{address_family} are currently
+\constant{AF_INET} and \constant{AF_INET6}.
+If the string \var{packed_ip} is not the correct length for the
+specified address family, \exception{ValueError} will be raised.  A
+\exception{socket.error} is raised for errors from the call to
+\function{inet_ntop()}.
+
+Availability: \UNIX{} (maybe not all platforms).
+\versionadded{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{getdefaulttimeout}{}
+Return the default timeout in floating seconds for new socket objects.
+A value of \code{None} indicates that new socket objects have no timeout.
+When the socket module is first imported, the default is \code{None}.
+\versionadded{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{setdefaulttimeout}{timeout}
+Set the default timeout in floating seconds for new socket objects.
+A value of \code{None} indicates that new socket objects have no timeout.
+When the socket module is first imported, the default is \code{None}.
+\versionadded{2.3}
+\end{funcdesc}
+
+\begin{datadesc}{SocketType}
+This is a Python type object that represents the socket object type.
+It is the same as \code{type(socket(...))}.
+\end{datadesc}
+
+
+\begin{seealso}
+  \seemodule{SocketServer}{Classes that simplify writing network servers.}
+\end{seealso}
+
+
+\subsection{Socket Objects \label{socket-objects}}
+
+Socket objects have the following methods.  Except for
+\method{makefile()} these correspond to \UNIX{} system calls
+applicable to sockets.
+
+\begin{methoddesc}[socket]{accept}{}
+Accept a connection.
+The socket must be bound to an address and listening for connections.
+The return value is a pair \code{(\var{conn}, \var{address})}
+where \var{conn} is a \emph{new} socket object usable to send and
+receive data on the connection, and \var{address} is the address bound
+to the socket on the other end of the connection.
+\end{methoddesc}
+
+\begin{methoddesc}[socket]{bind}{address}
+Bind the socket to \var{address}.  The socket must not already be bound.
+(The format of \var{address} depends on the address family --- see
+above.)  \note{This method has historically accepted a pair
+of parameters for \constant{AF_INET} addresses instead of only a
+tuple.  This was never intentional and is no longer available in
+Python 2.0 and later.}
+\end{methoddesc}
+
+\begin{methoddesc}[socket]{close}{}
+Close the socket.  All future operations on the socket object will fail.
+The remote end will receive no more data (after queued data is flushed).
+Sockets are automatically closed when they are garbage-collected.
+\end{methoddesc}
+
+\begin{methoddesc}[socket]{connect}{address}
+Connect to a remote socket at \var{address}.
+(The format of \var{address} depends on the address family --- see
+above.)  \note{This method has historically accepted a pair
+of parameters for \constant{AF_INET} addresses instead of only a
+tuple.  This was never intentional and is no longer available in
+Python 2.0 and later.}
+\end{methoddesc}
+
+\begin{methoddesc}[socket]{connect_ex}{address}
+Like \code{connect(\var{address})}, but return an error indicator
+instead of raising an exception for errors returned by the C-level
+\cfunction{connect()} call (other problems, such as ``host not found,''
+can still raise exceptions).  The error indicator is \code{0} if the
+operation succeeded, otherwise the value of the \cdata{errno}
+variable.  This is useful to support, for example, asynchronous connects.
+\note{This method has historically accepted a pair of
+parameters for \constant{AF_INET} addresses instead of only a tuple.
+This was never intentional and is no longer available in Python
+2.0 and later.}
+\end{methoddesc}
+
+\begin{methoddesc}[socket]{fileno}{}
+Return the socket's file descriptor (a small integer).  This is useful
+with \function{select.select()}.
+
+Under Windows the small integer returned by this method cannot be used where
+a file descriptor can be used (such as \function{os.fdopen()}).  \UNIX{} does
+not have this limitation.
+\end{methoddesc}
+
+\begin{methoddesc}[socket]{getpeername}{}
+Return the remote address to which the socket is connected.  This is
+useful to find out the port number of a remote IPv4/v6 socket, for instance.
+(The format of the address returned depends on the address family ---
+see above.)  On some systems this function is not supported.
+\end{methoddesc}
+
+\begin{methoddesc}[socket]{getsockname}{}
+Return the socket's own address.  This is useful to find out the port
+number of an IPv4/v6 socket, for instance.
+(The format of the address returned depends on the address family ---
+see above.)
+\end{methoddesc}
+
+\begin{methoddesc}[socket]{getsockopt}{level, optname\optional{, buflen}}
+Return the value of the given socket option (see the \UNIX{} man page
+\manpage{getsockopt}{2}).  The needed symbolic constants
+(\constant{SO_*} etc.) are defined in this module.  If \var{buflen}
+is absent, an integer option is assumed and its integer value
+is returned by the function.  If \var{buflen} is present, it specifies
+the maximum length of the buffer used to receive the option in, and
+this buffer is returned as a string.  It is up to the caller to decode
+the contents of the buffer (see the optional built-in module
+\refmodule{struct} for a way to decode C structures encoded as strings).
+\end{methoddesc}
+
+\begin{methoddesc}[socket]{listen}{backlog}
+Listen for connections made to the socket.  The \var{backlog} argument
+specifies the maximum number of queued connections and should be at
+least 1; the maximum value is system-dependent (usually 5).
+\end{methoddesc}
+
+\begin{methoddesc}[socket]{makefile}{\optional{mode\optional{, bufsize}}}
+Return a \dfn{file object} associated with the socket.  (File objects
+are described in \ref{bltin-file-objects}, ``File Objects.'')
+The file object references a \cfunction{dup()}ped version of the
+socket file descriptor, so the file object and socket object may be
+closed or garbage-collected independently.
+The socket must be in blocking mode.
+\index{I/O control!buffering}The optional \var{mode}
+and \var{bufsize} arguments are interpreted the same way as by the
+built-in \function{file()} function; see ``Built-in Functions''
+(section \ref{built-in-funcs}) for more information.
+\end{methoddesc}
+
+\begin{methoddesc}[socket]{recv}{bufsize\optional{, flags}}
+Receive data from the socket.  The return value is a string representing
+the data received.  The maximum amount of data to be received
+at once is specified by \var{bufsize}.  See the \UNIX{} manual page
+\manpage{recv}{2} for the meaning of the optional argument
+\var{flags}; it defaults to zero.
+\note{For best match with hardware and network realities, the value of 
+\var{bufsize} should be a relatively small power of 2, for example, 4096.}
+\end{methoddesc}
+
+\begin{methoddesc}[socket]{recvfrom}{bufsize\optional{, flags}}
+Receive data from the socket.  The return value is a pair
+\code{(\var{string}, \var{address})} where \var{string} is a string
+representing the data received and \var{address} is the address of the
+socket sending the data.  The optional \var{flags} argument has the
+same meaning as for \method{recv()} above.
+(The format of \var{address} depends on the address family --- see above.)
+\end{methoddesc}
+
+\begin{methoddesc}[socket]{recvfrom_into}{buffer\optional{, nbytes\optional{, flags}}}
+Receive data from the socket, writing it into \var{buffer} instead of 
+creating a new string.  The return value is a pair
+\code{(\var{nbytes}, \var{address})} where \var{nbytes} is the number
+of bytes received and \var{address} is the address of the socket
+sending the data.  See the \UNIX{} manual page
+\manpage{recv}{2} for the meaning of the optional argument
+\var{flags}; it defaults to zero.  (The format of \var{address}
+depends on the address family --- see above.)
+\versionadded{2.5}
+\end{methoddesc}
+
+\begin{methoddesc}[socket]{recv_into}{buffer\optional{, nbytes\optional{, flags}}}
+Receive up to \var{nbytes} bytes from the socket,
+storing the data into a buffer rather than creating a new string.    
+If \var{nbytes} is not specified (or 0), 
+receive up to the size available in the given buffer.
+See the \UNIX{} manual page \manpage{recv}{2} for the meaning of the
+optional argument \var{flags}; it defaults to zero.
+\versionadded{2.5}
+\end{methoddesc}
+
+\begin{methoddesc}[socket]{send}{string\optional{, flags}}
+Send data to the socket.  The socket must be connected to a remote
+socket.  The optional \var{flags} argument has the same meaning as for
+\method{recv()} above.  Returns the number of bytes sent.
+Applications are responsible for checking that all data has been sent;
+if only some of the data was transmitted, the application needs to
+attempt delivery of the remaining data.
+\end{methoddesc}
+
+\begin{methoddesc}[socket]{sendall}{string\optional{, flags}}
+Send data to the socket.  The socket must be connected to a remote
+socket.  The optional \var{flags} argument has the same meaning as for
+\method{recv()} above.  Unlike \method{send()}, this method continues
+to send data from \var{string} until either all data has been sent or
+an error occurs.  \code{None} is returned on success.  On error, an
+exception is raised, and there is no way to determine how much data,
+if any, was successfully sent.
+\end{methoddesc}
+
+\begin{methoddesc}[socket]{sendto}{string\optional{, flags}, address}
+Send data to the socket.  The socket should not be connected to a
+remote socket, since the destination socket is specified by
+\var{address}.  The optional \var{flags} argument has the same
+meaning as for \method{recv()} above.  Return the number of bytes sent.
+(The format of \var{address} depends on the address family --- see above.)
+\end{methoddesc}
+
+\begin{methoddesc}[socket]{setblocking}{flag}
+Set blocking or non-blocking mode of the socket: if \var{flag} is 0,
+the socket is set to non-blocking, else to blocking mode.  Initially
+all sockets are in blocking mode.  In non-blocking mode, if a
+\method{recv()} call doesn't find any data, or if a
+\method{send()} call can't immediately dispose of the data, a
+\exception{error} exception is raised; in blocking mode, the calls
+block until they can proceed.
+\code{s.setblocking(0)} is equivalent to \code{s.settimeout(0)};
+\code{s.setblocking(1)} is equivalent to \code{s.settimeout(None)}.
+\end{methoddesc}
+
+\begin{methoddesc}[socket]{settimeout}{value}
+Set a timeout on blocking socket operations.  The \var{value} argument
+can be a nonnegative float expressing seconds, or \code{None}.
+If a float is
+given, subsequent socket operations will raise an \exception{timeout}
+exception if the timeout period \var{value} has elapsed before the
+operation has completed.  Setting a timeout of \code{None} disables
+timeouts on socket operations.
+\code{s.settimeout(0.0)} is equivalent to \code{s.setblocking(0)};
+\code{s.settimeout(None)} is equivalent to \code{s.setblocking(1)}.
+\versionadded{2.3}
+\end{methoddesc}
+
+\begin{methoddesc}[socket]{gettimeout}{}
+Return the timeout in floating seconds associated with socket
+operations, or \code{None} if no timeout is set.  This reflects
+the last call to \method{setblocking()} or \method{settimeout()}.
+\versionadded{2.3}
+\end{methoddesc}
+
+Some notes on socket blocking and timeouts: A socket object can be in
+one of three modes: blocking, non-blocking, or timeout.  Sockets are
+always created in blocking mode.  In blocking mode, operations block
+until complete.  In non-blocking mode, operations fail (with an error
+that is unfortunately system-dependent) if they cannot be completed
+immediately.  In timeout mode, operations fail if they cannot be
+completed within the timeout specified for the socket.  The
+\method{setblocking()} method is simply a shorthand for certain
+\method{settimeout()} calls.
+
+Timeout mode internally sets the socket in non-blocking mode.  The
+blocking and timeout modes are shared between file descriptors and
+socket objects that refer to the same network endpoint.  A consequence
+of this is that file objects returned by the \method{makefile()}
+method must only be used when the socket is in blocking mode; in
+timeout or non-blocking mode file operations that cannot be completed
+immediately will fail.
+
+Note that the \method{connect()} operation is subject to the timeout
+setting, and in general it is recommended to call
+\method{settimeout()} before calling \method{connect()}.
+
+\begin{methoddesc}[socket]{setsockopt}{level, optname, value}
+Set the value of the given socket option (see the \UNIX{} manual page
+\manpage{setsockopt}{2}).  The needed symbolic constants are defined in
+the \module{socket} module (\constant{SO_*} etc.).  The value can be an
+integer or a string representing a buffer.  In the latter case it is
+up to the caller to ensure that the string contains the proper bits
+(see the optional built-in module
+\refmodule{struct}\refbimodindex{struct} for a way to encode C
+structures as strings). 
+\end{methoddesc}
+
+\begin{methoddesc}[socket]{shutdown}{how}
+Shut down one or both halves of the connection.  If \var{how} is
+\constant{SHUT_RD}, further receives are disallowed.  If \var{how} is \constant{SHUT_WR},
+further sends are disallowed.  If \var{how} is \constant{SHUT_RDWR}, further sends
+and receives are disallowed.
+\end{methoddesc}
+
+Note that there are no methods \method{read()} or \method{write()};
+use \method{recv()} and \method{send()} without \var{flags} argument
+instead.
+
+
+Socket objects also have these (read-only) attributes that correspond
+to the values given to the \class{socket} constructor.
+
+\begin{memberdesc}[socket]{family}
+The socket family.
+\versionadded{2.5}
+\end{memberdesc}
+
+\begin{memberdesc}[socket]{type}
+The socket type.
+\versionadded{2.5}
+\end{memberdesc}
+
+\begin{memberdesc}[socket]{proto}
+The socket protocol.
+\versionadded{2.5}
+\end{memberdesc}
+
+
+\subsection{SSL Objects \label{ssl-objects}}
+
+SSL objects have the following methods.
+
+\begin{methoddesc}{write}{s}
+Writes the string \var{s} to the on the object's SSL connection.
+The return value is the number of bytes written.
+\end{methoddesc}
+
+\begin{methoddesc}{read}{\optional{n}}
+If \var{n} is provided, read \var{n} bytes from the SSL connection, otherwise
+read until EOF. The return value is a string of the bytes read.
+\end{methoddesc}
+
+\begin{methoddesc}{server}{}
+Returns a string describing the server's certificate.
+Useful for debugging purposes; do not parse the content of this string
+because its format can't be parsed unambiguously.
+\end{methoddesc}
+
+\begin{methoddesc}{issuer}{}
+Returns a string describing the issuer of the server's certificate.
+Useful for debugging purposes; do not parse the content of this string
+because its format can't be parsed unambiguously.
+\end{methoddesc}
+
+\subsection{Example \label{socket-example}}
+
+Here are four minimal example programs using the TCP/IP protocol:\ a
+server that echoes all data that it receives back (servicing only one
+client), and a client using it.  Note that a server must perform the
+sequence \function{socket()}, \method{bind()}, \method{listen()},
+\method{accept()} (possibly repeating the \method{accept()} to service
+more than one client), while a client only needs the sequence
+\function{socket()}, \method{connect()}.  Also note that the server
+does not \method{send()}/\method{recv()} on the 
+socket it is listening on but on the new socket returned by
+\method{accept()}.
+
+The first two examples support IPv4 only.
+
+\begin{verbatim}
+# Echo server program
+import socket
+
+HOST = ''                 # Symbolic name meaning the local host
+PORT = 50007              # Arbitrary non-privileged port
+s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+s.bind((HOST, PORT))
+s.listen(1)
+conn, addr = s.accept()
+print 'Connected by', addr
+while 1:
+    data = conn.recv(1024)
+    if not data: break
+    conn.send(data)
+conn.close()
+\end{verbatim}
+
+\begin{verbatim}
+# Echo client program
+import socket
+
+HOST = 'daring.cwi.nl'    # The remote host
+PORT = 50007              # The same port as used by the server
+s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+s.connect((HOST, PORT))
+s.send('Hello, world')
+data = s.recv(1024)
+s.close()
+print 'Received', repr(data)
+\end{verbatim}
+
+The next two examples are identical to the above two, but support both
+IPv4 and IPv6.
+The server side will listen to the first address family available
+(it should listen to both instead).
+On most of IPv6-ready systems, IPv6 will take precedence
+and the server may not accept IPv4 traffic.
+The client side will try to connect to the all addresses returned as a result
+of the name resolution, and sends traffic to the first one connected
+successfully.
+
+\begin{verbatim}
+# Echo server program
+import socket
+import sys
+
+HOST = ''                 # Symbolic name meaning the local host
+PORT = 50007              # Arbitrary non-privileged port
+s = None
+for res in socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC, socket.SOCK_STREAM, 0, socket.AI_PASSIVE):
+    af, socktype, proto, canonname, sa = res
+    try:
+	s = socket.socket(af, socktype, proto)
+    except socket.error, msg:
+	s = None
+	continue
+    try:
+	s.bind(sa)
+	s.listen(1)
+    except socket.error, msg:
+	s.close()
+	s = None
+	continue
+    break
+if s is None:
+    print 'could not open socket'
+    sys.exit(1)
+conn, addr = s.accept()
+print 'Connected by', addr
+while 1:
+    data = conn.recv(1024)
+    if not data: break
+    conn.send(data)
+conn.close()
+\end{verbatim}
+
+\begin{verbatim}
+# Echo client program
+import socket
+import sys
+
+HOST = 'daring.cwi.nl'    # The remote host
+PORT = 50007              # The same port as used by the server
+s = None
+for res in socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC, socket.SOCK_STREAM):
+    af, socktype, proto, canonname, sa = res
+    try:
+	s = socket.socket(af, socktype, proto)
+    except socket.error, msg:
+	s = None
+	continue
+    try:
+	s.connect(sa)
+    except socket.error, msg:
+	s.close()
+	s = None
+	continue
+    break
+if s is None:
+    print 'could not open socket'
+    sys.exit(1)
+s.send('Hello, world')
+data = s.recv(1024)
+s.close()
+print 'Received', repr(data)
+\end{verbatim}
+
+This example connects to an SSL server, prints the 
+server and issuer's distinguished names, sends some bytes,
+and reads part of the response:
+
+\begin{verbatim}
+import socket
+
+s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+s.connect(('www.verisign.com', 443))
+
+ssl_sock = socket.ssl(s)
+
+print repr(ssl_sock.server())
+print repr(ssl_sock.issuer())
+
+# Set a simple HTTP request -- use httplib in actual code.
+ssl_sock.write("""GET / HTTP/1.0\r
+Host: www.verisign.com\r\n\r\n""")
+
+# Read a chunk of data.  Will not necessarily
+# read all the data returned by the server.
+data = ssl_sock.read()
+
+# Note that you need to close the underlying socket, not the SSL object.
+del ssl_sock
+s.close()
+\end{verbatim}
+
+At this writing, this SSL example prints the following output (line
+breaks inserted for readability):
+
+\begin{verbatim}
+'/C=US/ST=California/L=Mountain View/
+ O=VeriSign, Inc./OU=Production Services/
+ OU=Terms of use at www.verisign.com/rpa (c)00/
+ CN=www.verisign.com'
+'/O=VeriSign Trust Network/OU=VeriSign, Inc./
+ OU=VeriSign International Server CA - Class 3/
+ OU=www.verisign.com/CPS Incorp.by Ref. LIABILITY LTD.(c)97 VeriSign'
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/libsocksvr.tex
===================================================================
--- vendor/Python/current/Doc/lib/libsocksvr.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libsocksvr.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,293 @@
+\section{\module{SocketServer} ---
+         A framework for network servers}
+
+\declaremodule{standard}{SocketServer}
+\modulesynopsis{A framework for network servers.}
+
+
+The \module{SocketServer} module simplifies the task of writing network
+servers.
+
+There are four basic server classes: \class{TCPServer} uses the
+Internet TCP protocol, which provides for continuous streams of data
+between the client and server.  \class{UDPServer} uses datagrams, which
+are discrete packets of information that may arrive out of order or be
+lost while in transit.  The more infrequently used
+\class{UnixStreamServer} and \class{UnixDatagramServer} classes are
+similar, but use \UNIX{} domain sockets; they're not available on
+non-\UNIX{} platforms.  For more details on network programming, consult
+a book such as W. Richard Steven's \citetitle{UNIX Network Programming}
+or Ralph Davis's \citetitle{Win32 Network Programming}.
+
+These four classes process requests \dfn{synchronously}; each request
+must be completed before the next request can be started.  This isn't
+suitable if each request takes a long time to complete, because it
+requires a lot of computation, or because it returns a lot of data
+which the client is slow to process.  The solution is to create a
+separate process or thread to handle each request; the
+\class{ForkingMixIn} and \class{ThreadingMixIn} mix-in classes can be
+used to support asynchronous behaviour.
+
+Creating a server requires several steps.  First, you must create a
+request handler class by subclassing the \class{BaseRequestHandler}
+class and overriding its \method{handle()} method; this method will
+process incoming requests.  Second, you must instantiate one of the
+server classes, passing it the server's address and the request
+handler class.  Finally, call the \method{handle_request()} or
+\method{serve_forever()} method of the server object to process one or
+many requests.
+
+When inheriting from \class{ThreadingMixIn} for threaded connection
+behavior, you should explicitly declare how you want your threads
+to behave on an abrupt shutdown. The \class{ThreadingMixIn} class
+defines an attribute \var{daemon_threads}, which indicates whether
+or not the server should wait for thread termination. You should
+set the flag explicitly if you would like threads to behave
+autonomously; the default is \constant{False}, meaning that Python
+will not exit until all threads created by \class{ThreadingMixIn} have
+exited.
+
+Server classes have the same external methods and attributes, no
+matter what network protocol they use:
+
+\setindexsubitem{(SocketServer protocol)}
+
+\subsection{Server Creation Notes}
+
+There are five classes in an inheritance diagram, four of which represent
+synchronous servers of four types:
+
+\begin{verbatim}
+        +------------+
+        | BaseServer |
+        +------------+
+              |
+              v
+        +-----------+        +------------------+
+        | TCPServer |------->| UnixStreamServer |
+        +-----------+        +------------------+
+              |
+              v
+        +-----------+        +--------------------+
+        | UDPServer |------->| UnixDatagramServer |
+        +-----------+        +--------------------+
+\end{verbatim}
+
+Note that \class{UnixDatagramServer} derives from \class{UDPServer}, not
+from \class{UnixStreamServer} --- the only difference between an IP and a
+\UNIX{} stream server is the address family, which is simply repeated in both
+\UNIX{} server classes.
+
+Forking and threading versions of each type of server can be created using
+the \class{ForkingMixIn} and \class{ThreadingMixIn} mix-in classes.  For
+instance, a threading UDP server class is created as follows:
+
+\begin{verbatim}
+    class ThreadingUDPServer(ThreadingMixIn, UDPServer): pass
+\end{verbatim}
+
+The mix-in class must come first, since it overrides a method defined in
+\class{UDPServer}.  Setting the various member variables also changes the
+behavior of the underlying server mechanism.
+
+To implement a service, you must derive a class from
+\class{BaseRequestHandler} and redefine its \method{handle()} method.  You
+can then run various versions of the service by combining one of the server
+classes with your request handler class.  The request handler class must be
+different for datagram or stream services.  This can be hidden by using the
+handler subclasses \class{StreamRequestHandler} or \class{DatagramRequestHandler}.
+
+Of course, you still have to use your head!  For instance, it makes no sense
+to use a forking server if the service contains state in memory that can be
+modified by different requests, since the modifications in the child process
+would never reach the initial state kept in the parent process and passed to
+each child.  In this case, you can use a threading server, but you will
+probably have to use locks to protect the integrity of the shared data.
+
+On the other hand, if you are building an HTTP server where all data is
+stored externally (for instance, in the file system), a synchronous class
+will essentially render the service "deaf" while one request is being
+handled -- which may be for a very long time if a client is slow to receive
+all the data it has requested.  Here a threading or forking server is
+appropriate.
+
+In some cases, it may be appropriate to process part of a request
+synchronously, but to finish processing in a forked child depending on the
+request data.  This can be implemented by using a synchronous server and
+doing an explicit fork in the request handler class \method{handle()}
+method.
+
+Another approach to handling multiple simultaneous requests in an
+environment that supports neither threads nor \function{fork()} (or where
+these are too expensive or inappropriate for the service) is to maintain an
+explicit table of partially finished requests and to use \function{select()}
+to decide which request to work on next (or whether to handle a new incoming
+request).  This is particularly important for stream services where each
+client can potentially be connected for a long time (if threads or
+subprocesses cannot be used).
+
+%XXX should data and methods be intermingled, or separate?
+% how should the distinction between class and instance variables be
+% drawn?
+
+\subsection{Server Objects}
+
+\begin{funcdesc}{fileno}{}
+Return an integer file descriptor for the socket on which the server
+is listening.  This function is most commonly passed to
+\function{select.select()}, to allow monitoring multiple servers in the
+same process.
+\end{funcdesc}
+
+\begin{funcdesc}{handle_request}{}
+Process a single request.  This function calls the following methods
+in order: \method{get_request()}, \method{verify_request()}, and
+\method{process_request()}.  If the user-provided \method{handle()}
+method of the handler class raises an exception, the server's
+\method{handle_error()} method will be called.
+\end{funcdesc}
+
+\begin{funcdesc}{serve_forever}{}
+Handle an infinite number of requests.  This simply calls
+\method{handle_request()} inside an infinite loop.
+\end{funcdesc}
+
+\begin{datadesc}{address_family}
+The family of protocols to which the server's socket belongs.
+\constant{socket.AF_INET} and \constant{socket.AF_UNIX} are two
+possible values.
+\end{datadesc}
+
+\begin{datadesc}{RequestHandlerClass}
+The user-provided request handler class; an instance of this class is
+created for each request.
+\end{datadesc}
+
+\begin{datadesc}{server_address}
+The address on which the server is listening.  The format of addresses
+varies depending on the protocol family; see the documentation for the
+socket module for details.  For Internet protocols, this is a tuple
+containing a string giving the address, and an integer port number:
+\code{('127.0.0.1', 80)}, for example.
+\end{datadesc}
+
+\begin{datadesc}{socket}
+The socket object on which the server will listen for incoming requests.
+\end{datadesc}
+
+% XXX should class variables be covered before instance variables, or
+% vice versa?
+
+The server classes support the following class variables:
+
+\begin{datadesc}{allow_reuse_address}
+Whether the server will allow the reuse of an address. This defaults
+to \constant{False}, and can be set in subclasses to change the policy.
+\end{datadesc}
+
+\begin{datadesc}{request_queue_size}
+The size of the request queue.  If it takes a long time to process a
+single request, any requests that arrive while the server is busy are
+placed into a queue, up to \member{request_queue_size} requests.  Once
+the queue is full, further requests from clients will get a
+``Connection denied'' error.  The default value is usually 5, but this
+can be overridden by subclasses.
+\end{datadesc}
+
+\begin{datadesc}{socket_type}
+The type of socket used by the server; \constant{socket.SOCK_STREAM}
+and \constant{socket.SOCK_DGRAM} are two possible values.
+\end{datadesc}
+
+There are various server methods that can be overridden by subclasses
+of base server classes like \class{TCPServer}; these methods aren't
+useful to external users of the server object.
+
+% should the default implementations of these be documented, or should
+% it be assumed that the user will look at SocketServer.py?
+
+\begin{funcdesc}{finish_request}{}
+Actually processes the request by instantiating
+\member{RequestHandlerClass} and calling its \method{handle()} method.
+\end{funcdesc}
+
+\begin{funcdesc}{get_request}{}
+Must accept a request from the socket, and return a 2-tuple containing
+the \emph{new} socket object to be used to communicate with the
+client, and the client's address.
+\end{funcdesc}
+
+\begin{funcdesc}{handle_error}{request, client_address}
+This function is called if the \member{RequestHandlerClass}'s
+\method{handle()} method raises an exception.  The default action is
+to print the traceback to standard output and continue handling
+further requests.
+\end{funcdesc}
+
+\begin{funcdesc}{process_request}{request, client_address}
+Calls \method{finish_request()} to create an instance of the
+\member{RequestHandlerClass}.  If desired, this function can create a
+new process or thread to handle the request; the \class{ForkingMixIn}
+and \class{ThreadingMixIn} classes do this.
+\end{funcdesc}
+
+% Is there any point in documenting the following two functions?
+% What would the purpose of overriding them be: initializing server
+% instance variables, adding new network families?
+
+\begin{funcdesc}{server_activate}{}
+Called by the server's constructor to activate the server.  The default
+behavior just \method{listen}s to the server's socket.
+May be overridden.
+\end{funcdesc}
+
+\begin{funcdesc}{server_bind}{}
+Called by the server's constructor to bind the socket to the desired
+address.  May be overridden.
+\end{funcdesc}
+
+\begin{funcdesc}{verify_request}{request, client_address}
+Must return a Boolean value; if the value is \constant{True}, the request will be
+processed, and if it's \constant{False}, the request will be denied.
+This function can be overridden to implement access controls for a server.
+The default implementation always returns \constant{True}.
+\end{funcdesc}
+
+\subsection{RequestHandler Objects}
+
+The request handler class must define a new \method{handle()} method,
+and can override any of the following methods.  A new instance is
+created for each request.
+
+\begin{funcdesc}{finish}{}
+Called after the \method{handle()} method to perform any clean-up
+actions required.  The default implementation does nothing.  If
+\method{setup()} or \method{handle()} raise an exception, this
+function will not be called.
+\end{funcdesc}
+
+\begin{funcdesc}{handle}{}
+This function must do all the work required to service a request.
+The default implementation does nothing.
+Several instance attributes are available to it; the request is
+available as \member{self.request}; the client address as
+\member{self.client_address}; and the server instance as
+\member{self.server}, in case it needs access to per-server
+information.
+
+The type of \member{self.request} is different for datagram or stream
+services.  For stream services, \member{self.request} is a socket
+object; for datagram services, \member{self.request} is a string.
+However, this can be hidden by using the  request handler subclasses
+\class{StreamRequestHandler} or \class{DatagramRequestHandler}, which
+override the \method{setup()} and \method{finish()} methods, and
+provide \member{self.rfile} and \member{self.wfile} attributes.
+\member{self.rfile} and \member{self.wfile} can be read or written,
+respectively, to get the request data or return data to the client.
+\end{funcdesc}
+
+\begin{funcdesc}{setup}{}
+Called before the \method{handle()} method to perform any
+initialization actions required.  The default implementation does
+nothing.
+\end{funcdesc}

Added: vendor/Python/current/Doc/lib/libsomeos.tex
===================================================================
--- vendor/Python/current/Doc/lib/libsomeos.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libsomeos.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,10 @@
+\chapter{Optional Operating System Services}
+\label{someos}
+
+The modules described in this chapter provide interfaces to operating
+system features that are available on selected operating systems only.
+The interfaces are generally modeled after the \UNIX{} or \C{}
+interfaces but they are available on some other systems as well
+(e.g. Windows or NT).  Here's an overview:
+
+\localmoduletable

Added: vendor/Python/current/Doc/lib/libspwd.tex
===================================================================
--- vendor/Python/current/Doc/lib/libspwd.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libspwd.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,48 @@
+\section{\module{spwd} ---
+         The shadow password database}
+
+\declaremodule{builtin}{spwd}
+  \platform{Unix}
+\modulesynopsis{The shadow password database (\function{getspnam()} and friends).}
+\versionadded{2.5}
+
+This module provides access to the \UNIX{} shadow password database.
+It is available on various \UNIX{} versions.
+
+You must have enough privileges to access the shadow password database
+(this usually means you have to be root).
+
+Shadow password database entries are reported as a tuple-like object, whose
+attributes correspond to the members of the \code{spwd} structure
+(Attribute field below, see \code{<shadow.h>}):
+
+\begin{tableiii}{r|l|l}{textrm}{Index}{Attribute}{Meaning}
+  \lineiii{0}{\code{sp_nam}}{Login name}
+  \lineiii{1}{\code{sp_pwd}}{Encrypted password}
+  \lineiii{2}{\code{sp_lstchg}}{Date of last change}
+  \lineiii{3}{\code{sp_min}}{Minimal number of days between changes}
+  \lineiii{4}{\code{sp_max}}{Maximum number of days between changes}
+  \lineiii{5}{\code{sp_warn}}{Number of days before password expires to warn user about it}
+  \lineiii{6}{\code{sp_inact}}{Number of days after password expires until account is blocked}
+  \lineiii{7}{\code{sp_expire}}{Number of days since 1970-01-01 until account is disabled}
+  \lineiii{8}{\code{sp_flag}}{Reserved}
+\end{tableiii}
+
+The sp_nam and sp_pwd items are strings, all others are integers.
+\exception{KeyError} is raised if the entry asked for cannot be found.
+
+It defines the following items:
+
+\begin{funcdesc}{getspnam}{name}
+Return the shadow password database entry for the given user name.
+\end{funcdesc}
+
+\begin{funcdesc}{getspall}{}
+Return a list of all available shadow password database entries, in arbitrary order.
+\end{funcdesc}
+
+
+\begin{seealso}
+  \seemodule{grp}{An interface to the group database, similar to this.}
+  \seemodule{pwd}{An interface to the normal password database, similar to this.}
+\end{seealso}

Added: vendor/Python/current/Doc/lib/libsqlite3.tex
===================================================================
--- vendor/Python/current/Doc/lib/libsqlite3.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libsqlite3.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,642 @@
+\section{\module{sqlite3} ---
+         DB-API 2.0 interface for SQLite databases}
+
+\declaremodule{builtin}{sqlite3}
+\modulesynopsis{A DB-API 2.0 implementation using SQLite 3.x.}
+\sectionauthor{Gerhard Häring}{gh at ghaering.de}
+\versionadded{2.5}
+
+SQLite is a C library that provides a lightweight disk-based database
+that doesn't require a separate server process and allows accessing
+the database using a nonstandard variant of the SQL query language.
+Some applications can use SQLite for internal data storage.  It's also
+possible to prototype an application using SQLite and then port the
+code to a larger database such as PostgreSQL or Oracle.
+ 
+pysqlite was written by Gerhard H\"aring and provides a SQL interface
+compliant with the DB-API 2.0 specification described by
+\pep{249}. 
+
+To use the module, you must first create a \class{Connection} object
+that represents the database.  Here the data will be stored in the 
+\file{/tmp/example} file:
+
+\begin{verbatim}
+conn = sqlite3.connect('/tmp/example')
+\end{verbatim}
+
+You can also supply the special name \samp{:memory:} to create
+a database in RAM.
+
+Once you have a \class{Connection}, you can create a \class{Cursor} 
+object and call its \method{execute()} method to perform SQL commands:
+
+\begin{verbatim}
+c = conn.cursor()
+
+# Create table
+c.execute('''create table stocks
+(date text, trans text, symbol text,
+ qty real, price real)''')
+
+# Insert a row of data
+c.execute("""insert into stocks
+          values ('2006-01-05','BUY','RHAT',100,35.14)""")
+\end{verbatim}    
+
+Usually your SQL operations will need to use values from Python
+variables.  You shouldn't assemble your query using Python's string
+operations because doing so is insecure; it makes your program
+vulnerable to an SQL injection attack.  
+
+Instead, use the DB-API's parameter substitution.  Put \samp{?} as a
+placeholder wherever you want to use a value, and then provide a tuple
+of values as the second argument to the cursor's \method{execute()}
+method.  (Other database modules may use a different placeholder,
+such as \samp{\%s} or \samp{:1}.) For example:
+
+\begin{verbatim}    
+# Never do this -- insecure!
+symbol = 'IBM'
+c.execute("... where symbol = '%s'" % symbol)
+
+# Do this instead
+t = (symbol,)
+c.execute('select * from stocks where symbol=?', t)
+
+# Larger example
+for t in (('2006-03-28', 'BUY', 'IBM', 1000, 45.00),
+          ('2006-04-05', 'BUY', 'MSOFT', 1000, 72.00),
+          ('2006-04-06', 'SELL', 'IBM', 500, 53.00),
+         ):
+    c.execute('insert into stocks values (?,?,?,?,?)', t)
+\end{verbatim}
+
+To retrieve data after executing a SELECT statement, you can either 
+treat the cursor as an iterator, call the cursor's \method{fetchone()}
+method to retrieve a single matching row, 
+or call \method{fetchall()} to get a list of the matching rows.
+
+This example uses the iterator form:
+
+\begin{verbatim}
+>>> c = conn.cursor()
+>>> c.execute('select * from stocks order by price')
+>>> for row in c:
+...    print row
+...
+(u'2006-01-05', u'BUY', u'RHAT', 100, 35.140000000000001)
+(u'2006-03-28', u'BUY', u'IBM', 1000, 45.0)
+(u'2006-04-06', u'SELL', u'IBM', 500, 53.0)
+(u'2006-04-05', u'BUY', u'MSOFT', 1000, 72.0)
+>>>
+\end{verbatim}
+
+\begin{seealso}
+
+\seeurl{http://www.pysqlite.org}
+{The pysqlite web page.}
+
+\seeurl{http://www.sqlite.org}
+{The SQLite web page; the documentation describes the syntax and the
+available data types for the supported SQL dialect.}
+
+\seepep{249}{Database API Specification 2.0}{PEP written by
+Marc-Andr\'e Lemburg.}
+
+\end{seealso}
+
+
+\subsection{Module functions and constants\label{sqlite3-Module-Contents}}
+
+\begin{datadesc}{PARSE_DECLTYPES}
+This constant is meant to be used with the \var{detect_types} parameter of the
+\function{connect} function.
+
+Setting it makes the \module{sqlite3} module parse the declared type for each column it
+returns.  It will parse out the first word of the declared type, i. e. for
+"integer primary key", it will parse out "integer". Then for that column, it
+will look into the converters dictionary and use the converter function
+registered for that type there.  Converter names are case-sensitive!
+\end{datadesc}
+
+
+\begin{datadesc}{PARSE_COLNAMES}
+This constant is meant to be used with the \var{detect_types} parameter of the
+\function{connect} function.
+
+Setting this makes the SQLite interface parse the column name for each column
+it returns.  It will look for a string formed [mytype] in there, and then
+decide that 'mytype' is the type of the column. It will try to find an entry of
+'mytype' in the converters dictionary and then use the converter function found
+there to return the value. The column name found in \member{cursor.description} is only
+the first word of the column name, i.  e. if you use something like
+\code{'as "x [datetime]"'} in your SQL, then we will parse out everything until the
+first blank for the column name: the column name would simply be "x".
+\end{datadesc}
+
+\begin{funcdesc}{connect}{database\optional{, timeout, isolation_level, detect_types, factory}}
+Opens a connection to the SQLite database file \var{database}. You can use
+\code{":memory:"} to open a database connection to a database that resides in
+RAM instead of on disk.
+
+When a database is accessed by multiple connections, and one of the processes
+modifies the database, the SQLite database is locked until that transaction is
+committed. The \var{timeout} parameter specifies how long the connection should
+wait for the lock to go away until raising an exception. The default for the
+timeout parameter is 5.0 (five seconds). 
+
+For the \var{isolation_level} parameter, please see the \member{isolation_level}
+property of \class{Connection} objects in section~\ref{sqlite3-Connection-IsolationLevel}.
+
+SQLite natively supports only the types TEXT, INTEGER, FLOAT, BLOB and NULL. If
+you want to use other types, like you have to add support for them yourself.
+The \var{detect_types} parameter and the using custom \strong{converters} registered with
+the module-level \function{register_converter} function allow you to easily do that.
+
+\var{detect_types} defaults to 0 (i. e. off, no type detection), you can set it
+to any combination of \constant{PARSE_DECLTYPES} and \constant{PARSE_COLNAMES} to turn type
+detection on.
+
+By default, the \module{sqlite3} module uses its \class{Connection} class for the
+connect call.  You can, however, subclass the \class{Connection} class and make
+\function{connect} use your class instead by providing your class for the
+\var{factory} parameter.
+
+Consult the section \ref{sqlite3-Types} of this manual for details.
+
+The \module{sqlite3} module internally uses a statement cache to avoid SQL parsing
+overhead. If you want to explicitly set the number of statements that are
+cached for the connection, you can set the \var{cached_statements} parameter.
+The currently implemented default is to cache 100 statements.
+\end{funcdesc}
+
+\begin{funcdesc}{register_converter}{typename, callable}
+Registers a callable to convert a bytestring from the database into a custom
+Python type. The callable will be invoked for all database values that are of
+the type \var{typename}. Confer the parameter \var{detect_types} of the
+\function{connect} function for how the type detection works. Note that the case of
+\var{typename} and the name of the type in your query must match!
+\end{funcdesc}
+
+\begin{funcdesc}{register_adapter}{type, callable}
+Registers a callable to convert the custom Python type \var{type} into one of
+SQLite's supported types. The callable \var{callable} accepts as single
+parameter the Python value, and must return a value of the following types:
+int, long, float, str (UTF-8 encoded), unicode or buffer.
+\end{funcdesc}
+
+\begin{funcdesc}{complete_statement}{sql}
+Returns \constant{True} if the string \var{sql} contains one or more complete SQL
+statements terminated by semicolons. It does not verify that the SQL is
+syntactically correct, only that there are no unclosed string literals and the
+statement is terminated by a semicolon.
+
+This can be used to build a shell for SQLite, as in the following example:
+
+    \verbatiminput{sqlite3/complete_statement.py}
+\end{funcdesc}
+
+\begin{funcdesc}{enable_callback_tracebacks}{flag}
+By default you will not get any tracebacks in user-defined functions,
+aggregates, converters, authorizer callbacks etc. If you want to debug them,
+you can call this function with \var{flag} as True. Afterwards, you will get
+tracebacks from callbacks on \code{sys.stderr}. Use \constant{False} to disable
+the feature again.
+\end{funcdesc}
+
+\subsection{Connection Objects \label{sqlite3-Connection-Objects}}
+
+A \class{Connection} instance has the following attributes and methods:
+
+\label{sqlite3-Connection-IsolationLevel}
+\begin{memberdesc}{isolation_level}
+  Get or set the current isolation level. None for autocommit mode or one of
+  "DEFERRED", "IMMEDIATE" or "EXLUSIVE". See ``Controlling Transactions'', 
+  section~\ref{sqlite3-Controlling-Transactions}, for a more detailed explanation.
+\end{memberdesc}
+
+\begin{methoddesc}{cursor}{\optional{cursorClass}}
+  The cursor method accepts a single optional parameter \var{cursorClass}.
+  If supplied, this must be a custom cursor class that extends 
+  \class{sqlite3.Cursor}.
+\end{methoddesc}
+
+\begin{methoddesc}{execute}{sql, \optional{parameters}}
+This is a nonstandard shortcut that creates an intermediate cursor object by
+calling the cursor method, then calls the cursor's \method{execute} method with the
+parameters given.
+\end{methoddesc}
+
+\begin{methoddesc}{executemany}{sql, \optional{parameters}}
+This is a nonstandard shortcut that creates an intermediate cursor object by
+calling the cursor method, then calls the cursor's \method{executemany} method with the
+parameters given.
+\end{methoddesc}
+
+\begin{methoddesc}{executescript}{sql_script}
+This is a nonstandard shortcut that creates an intermediate cursor object by
+calling the cursor method, then calls the cursor's \method{executescript} method with the
+parameters given.
+\end{methoddesc}
+
+\begin{methoddesc}{create_function}{name, num_params, func}
+
+Creates a user-defined function that you can later use from within SQL
+statements under the function name \var{name}. \var{num_params} is the number
+of parameters the function accepts, and \var{func} is a Python callable that is
+called as the SQL function.
+
+The function can return any of the types supported by SQLite: unicode, str,
+int, long, float, buffer and None.
+
+Example:
+
+  \verbatiminput{sqlite3/md5func.py}
+\end{methoddesc}
+
+\begin{methoddesc}{create_aggregate}{name, num_params, aggregate_class}
+
+Creates a user-defined aggregate function.
+
+The aggregate class must implement a \code{step} method, which accepts the
+number of parameters \var{num_params}, and a \code{finalize} method which
+will return the final result of the aggregate.
+
+The \code{finalize} method can return any of the types supported by SQLite:
+unicode, str, int, long, float, buffer and None.
+
+Example:
+
+  \verbatiminput{sqlite3/mysumaggr.py}
+\end{methoddesc}
+
+\begin{methoddesc}{create_collation}{name, callable}
+
+Creates a collation with the specified \var{name} and \var{callable}. The
+callable will be passed two string arguments. It should return -1 if the first
+is ordered lower than the second, 0 if they are ordered equal and 1 if the
+first is ordered higher than the second.  Note that this controls sorting
+(ORDER BY in SQL) so your comparisons don't affect other SQL operations.
+
+Note that the callable will get its parameters as Python bytestrings, which
+will normally be encoded in UTF-8.
+
+The following example shows a custom collation that sorts "the wrong way":
+
+  \verbatiminput{sqlite3/collation_reverse.py}
+
+To remove a collation, call \code{create_collation} with None as callable:
+
+\begin{verbatim}
+    con.create_collation("reverse", None)
+\end{verbatim}
+\end{methoddesc}
+
+\begin{methoddesc}{interrupt}{}
+
+You can call this method from a different thread to abort any queries that
+might be executing on the connection. The query will then abort and the caller
+will get an exception.
+\end{methoddesc}
+
+\begin{methoddesc}{set_authorizer}{authorizer_callback}
+
+This routine registers a callback. The callback is invoked for each attempt to
+access a column of a table in the database. The callback should return
+\constant{SQLITE_OK} if access is allowed, \constant{SQLITE_DENY} if the entire
+SQL statement should be aborted with an error and \constant{SQLITE_IGNORE} if
+the column should be treated as a NULL value. These constants are available in
+the \module{sqlite3} module.
+
+The first argument to the callback signifies what kind of operation is to be
+authorized. The second and third argument will be arguments or \constant{None}
+depending on the first argument. The 4th argument is the name of the database
+("main", "temp", etc.) if applicable. The 5th argument is the name of the
+inner-most trigger or view that is responsible for the access attempt or
+\constant{None} if this access attempt is directly from input SQL code.
+
+Please consult the SQLite documentation about the possible values for the first
+argument and the meaning of the second and third argument depending on the
+first one. All necessary constants are available in the \module{sqlite3}
+module.
+\end{methoddesc}
+
+\begin{memberdesc}{row_factory}
+  You can change this attribute to a callable that accepts the cursor and
+  the original row as a tuple and will return the real result row.  This
+  way, you can implement more advanced ways of returning results, such 
+  as returning an object that can also access columns by name.
+
+  Example:
+
+  \verbatiminput{sqlite3/row_factory.py}
+
+  If returning a tuple doesn't suffice and you want name-based
+  access to columns, you should consider setting \member{row_factory} to the
+  highly-optimized \class{sqlite3.Row} type. \class{Row} provides both
+  index-based and case-insensitive name-based access to columns with almost
+  no memory overhead. It will probably be better than your own custom 
+  dictionary-based approach or even a db_row based solution.
+  % XXX what's a db_row-based solution?
+\end{memberdesc}
+
+\begin{memberdesc}{text_factory}
+  Using this attribute you can control what objects are returned for the
+  TEXT data type. By default, this attribute is set to \class{unicode} and
+  the \module{sqlite3} module will return Unicode objects for TEXT. If you want to return
+  bytestrings instead, you can set it to \class{str}.
+
+  For efficiency reasons, there's also a way to return Unicode objects only
+  for non-ASCII data, and bytestrings otherwise. To activate it, set this
+  attribute to \constant{sqlite3.OptimizedUnicode}.
+
+  You can also set it to any other callable that accepts a single bytestring
+  parameter and returns the resulting object.
+
+  See the following example code for illustration:
+
+  \verbatiminput{sqlite3/text_factory.py}
+\end{memberdesc}
+
+\begin{memberdesc}{total_changes}
+  Returns the total number of database rows that have been modified, inserted,
+  or deleted since the database connection was opened.
+\end{memberdesc}
+
+
+
+
+
+\subsection{Cursor Objects \label{sqlite3-Cursor-Objects}}
+
+A \class{Cursor} instance has the following attributes and methods:
+
+\begin{methoddesc}{execute}{sql, \optional{parameters}}
+
+Executes a SQL statement. The SQL statement may be parametrized (i. e.
+placeholders instead of SQL literals). The \module{sqlite3} module supports two kinds of
+placeholders: question marks (qmark style) and named placeholders (named
+style).
+
+This example shows how to use parameters with qmark style:
+
+    \verbatiminput{sqlite3/execute_1.py}
+
+This example shows how to use the named style:
+
+    \verbatiminput{sqlite3/execute_2.py}
+
+    \method{execute()} will only execute a single SQL statement. If you try to
+    execute more than one statement with it, it will raise a Warning. Use
+    \method{executescript()} if you want to execute multiple SQL statements with one
+    call.
+\end{methoddesc}
+
+
+\begin{methoddesc}{executemany}{sql, seq_of_parameters}
+Executes a SQL command against all parameter sequences or mappings found in the
+sequence \var{sql}. The \module{sqlite3} module also allows
+using an iterator yielding parameters instead of a sequence.
+
+\verbatiminput{sqlite3/executemany_1.py}
+
+Here's a shorter example using a generator:
+
+\verbatiminput{sqlite3/executemany_2.py}
+\end{methoddesc}
+
+\begin{methoddesc}{executescript}{sql_script}
+
+This is a nonstandard convenience method for executing multiple SQL statements
+at once. It issues a COMMIT statement first, then executes the SQL script it
+gets as a parameter.
+
+\var{sql_script} can be a bytestring or a Unicode string.
+
+Example:
+
+\verbatiminput{sqlite3/executescript.py}
+\end{methoddesc}
+
+\begin{memberdesc}{rowcount}
+  Although the \class{Cursor} class of the \module{sqlite3} module implements this
+  attribute, the database engine's own support for the determination of "rows
+  affected"/"rows selected" is quirky.
+
+  For \code{SELECT} statements, \member{rowcount} is always None because we cannot
+  determine the number of rows a query produced until all rows were fetched.
+
+  For \code{DELETE} statements, SQLite reports \member{rowcount} as 0 if you make a
+  \code{DELETE FROM table} without any condition.
+
+  For \method{executemany} statements, the number of modifications are summed
+  up into \member{rowcount}.
+
+  As required by the Python DB API Spec, the \member{rowcount} attribute "is -1
+  in case no executeXX() has been performed on the cursor or the rowcount
+  of the last operation is not determinable by the interface".
+\end{memberdesc}
+
+\subsection{SQLite and Python types\label{sqlite3-Types}}
+
+\subsubsection{Introduction}
+
+SQLite natively supports the following types: NULL, INTEGER, REAL, TEXT, BLOB.
+
+The following Python types can thus be sent to SQLite without any problem:
+
+\begin{tableii}  {c|l}{code}{Python type}{SQLite type}
+\lineii{None}{NULL}
+\lineii{int}{INTEGER}
+\lineii{long}{INTEGER}
+\lineii{float}{REAL}
+\lineii{str (UTF8-encoded)}{TEXT}
+\lineii{unicode}{TEXT}
+\lineii{buffer}{BLOB}
+\end{tableii}
+
+This is how SQLite types are converted to Python types by default:
+
+\begin{tableii}  {c|l}{code}{SQLite type}{Python type}
+\lineii{NULL}{None}
+\lineii{INTEGER}{int or long, depending on size}
+\lineii{REAL}{float}
+\lineii{TEXT}{depends on text_factory, unicode by default}
+\lineii{BLOB}{buffer}
+\end{tableii}
+
+The type system of the \module{sqlite3} module is extensible in two ways: you can store
+additional Python types in a SQLite database via object adaptation, and you can
+let the \module{sqlite3} module convert SQLite types to different Python types via
+converters.
+
+\subsubsection{Using adapters to store additional Python types in SQLite databases}
+
+As described before, SQLite supports only a limited set of types natively. To
+use other Python types with SQLite, you must \strong{adapt} them to one of the sqlite3
+module's supported types for SQLite: one of NoneType, int, long, float,
+str, unicode, buffer.
+
+The \module{sqlite3} module uses Python object adaptation, as described in \pep{246} for this.  The protocol to use is \class{PrepareProtocol}.
+
+There are two ways to enable the \module{sqlite3} module to adapt a custom Python type
+to one of the supported ones.
+
+\paragraph{Letting your object adapt itself}
+
+This is a good approach if you write the class yourself. Let's suppose you have
+a class like this:
+
+\begin{verbatim}
+class Point(object):
+    def __init__(self, x, y):
+        self.x, self.y = x, y
+\end{verbatim}
+
+Now you want to store the point in a single SQLite column.  First you'll have to
+choose one of the supported types first to be used for representing the point.
+Let's just use str and separate the coordinates using a semicolon. Then you
+need to give your class a method \code{__conform__(self, protocol)} which must
+return the converted value. The parameter \var{protocol} will be
+\class{PrepareProtocol}.
+
+\verbatiminput{sqlite3/adapter_point_1.py}
+
+\paragraph{Registering an adapter callable}
+
+The other possibility is to create a function that converts the type to the
+string representation and register the function with \method{register_adapter}.
+
+\begin{notice}
+The type/class to adapt must be a new-style class, i. e. it must have
+\class{object} as one of its bases.
+\end{notice}
+
+    \verbatiminput{sqlite3/adapter_point_2.py}
+
+The \module{sqlite3} module has two default adapters for Python's built-in
+\class{datetime.date} and \class{datetime.datetime} types.  Now let's suppose
+we want to store \class{datetime.datetime} objects not in ISO representation,
+but as a \UNIX{} timestamp.
+
+    \verbatiminput{sqlite3/adapter_datetime.py}
+
+\subsubsection{Converting SQLite values to custom Python types}
+
+Writing an adapter lets you send custom Python types to SQLite.
+But to make it really useful we need to make the Python to SQLite to Python
+roundtrip work.  
+
+Enter converters.
+
+Let's go back to the \class{Point} class. We stored the x and y
+coordinates separated via semicolons as strings in SQLite.
+
+First, we'll define a converter function that accepts the string as a
+parameter and constructs a \class{Point} object from it.
+
+\begin{notice}
+Converter functions \strong{always} get called with a string, no matter
+under which data type you sent the value to SQLite.
+\end{notice}
+
+\begin{notice}
+Converter names are looked up in a case-sensitive manner.
+\end{notice}
+
+
+\begin{verbatim}
+    def convert_point(s):
+        x, y = map(float, s.split(";"))
+        return Point(x, y)
+\end{verbatim}
+
+Now you need to make the \module{sqlite3} module know that what you select from the
+database is actually a point. There are two ways of doing this:
+
+\begin{itemize}
+ \item Implicitly via the declared type
+ \item Explicitly via the column name
+\end{itemize}
+
+Both ways are described in ``Module Constants'', section~\ref{sqlite3-Module-Contents}, in
+the entries for the constants \constant{PARSE_DECLTYPES} and
+\constant{PARSE_COLNAMES}.
+
+
+The following example illustrates both approaches.
+
+    \verbatiminput{sqlite3/converter_point.py}
+
+\subsubsection{Default adapters and converters}
+
+There are default adapters for the date and datetime types in the datetime
+module. They will be sent as ISO dates/ISO timestamps to SQLite.
+
+The default converters are registered under the name "date" for \class{datetime.date}
+and under the name "timestamp" for \class{datetime.datetime}.
+
+This way, you can use date/timestamps from Python without any additional
+fiddling in most cases. The format of the adapters is also compatible with the
+experimental SQLite date/time functions.
+
+The following example demonstrates this.
+
+    \verbatiminput{sqlite3/pysqlite_datetime.py}
+
+\subsection{Controlling Transactions \label{sqlite3-Controlling-Transactions}}
+
+By default, the \module{sqlite3} module opens transactions implicitly before a Data Modification Language (DML) 
+statement (i.e. INSERT/UPDATE/DELETE/REPLACE), and commits transactions implicitly
+before a non-DML, non-query statement (i. e. anything other than
+SELECT/INSERT/UPDATE/DELETE/REPLACE).
+
+So if you are within a transaction and issue a command like \code{CREATE TABLE
+...}, \code{VACUUM}, \code{PRAGMA}, the \module{sqlite3} module will commit implicitly
+before executing that command. There are two reasons for doing that. The first
+is that some of these commands don't work within transactions. The other reason
+is that pysqlite needs to keep track of the transaction state (if a transaction
+is active or not).
+
+You can control which kind of "BEGIN" statements pysqlite implicitly executes
+(or none at all) via the \var{isolation_level} parameter to the
+\function{connect} call, or via the \member{isolation_level} property of
+connections.
+
+If you want \strong{autocommit mode}, then set \member{isolation_level} to None.
+
+Otherwise leave it at its default, which will result in a plain "BEGIN"
+statement, or set it to one of SQLite's supported isolation levels: DEFERRED,
+IMMEDIATE or EXCLUSIVE.
+
+As the \module{sqlite3} module needs to keep track of the transaction state, you should
+not use \code{OR ROLLBACK} or \code{ON CONFLICT ROLLBACK} in your SQL. Instead,
+catch the \exception{IntegrityError} and call the \method{rollback} method of
+the connection yourself.
+
+\subsection{Using pysqlite efficiently}
+
+\subsubsection{Using shortcut methods}
+
+Using the nonstandard \method{execute}, \method{executemany} and
+\method{executescript} methods of the \class{Connection} object, your code can
+be written more concisely because you don't have to create the (often
+superfluous) \class{Cursor} objects explicitly. Instead, the \class{Cursor}
+objects are created implicitly and these shortcut methods return the cursor
+objects. This way, you can execute a SELECT statement and iterate
+over it directly using only a single call on the \class{Connection} object.
+
+    \verbatiminput{sqlite3/shortcut_methods.py}
+
+\subsubsection{Accessing columns by name instead of by index}
+
+One useful feature of the \module{sqlite3} module is the builtin \class{sqlite3.Row} class
+designed to be used as a row factory.
+
+Rows wrapped with this class can be accessed both by index (like tuples) and
+case-insensitively by name:
+
+    \verbatiminput{sqlite3/rowclass.py}
+
+

Added: vendor/Python/current/Doc/lib/libstat.tex
===================================================================
--- vendor/Python/current/Doc/lib/libstat.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libstat.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,157 @@
+\section{\module{stat} ---
+         Interpreting \function{stat()} results}
+
+\declaremodule{standard}{stat}
+\modulesynopsis{Utilities for interpreting the results of
+  \function{os.stat()}, \function{os.lstat()} and \function{os.fstat()}.}
+\sectionauthor{Skip Montanaro}{skip at automatrix.com}
+
+
+The \module{stat} module defines constants and functions for
+interpreting the results of \function{os.stat()},
+\function{os.fstat()} and \function{os.lstat()} (if they exist).  For
+complete details about the \cfunction{stat()}, \cfunction{fstat()} and
+\cfunction{lstat()} calls, consult the documentation for your system.
+
+The \module{stat} module defines the following functions to test for
+specific file types:
+
+
+\begin{funcdesc}{S_ISDIR}{mode}
+Return non-zero if the mode is from a directory.
+\end{funcdesc}
+
+\begin{funcdesc}{S_ISCHR}{mode}
+Return non-zero if the mode is from a character special device file.
+\end{funcdesc}
+
+\begin{funcdesc}{S_ISBLK}{mode}
+Return non-zero if the mode is from a block special device file.
+\end{funcdesc}
+
+\begin{funcdesc}{S_ISREG}{mode}
+Return non-zero if the mode is from a regular file.
+\end{funcdesc}
+
+\begin{funcdesc}{S_ISFIFO}{mode}
+Return non-zero if the mode is from a FIFO (named pipe).
+\end{funcdesc}
+
+\begin{funcdesc}{S_ISLNK}{mode}
+Return non-zero if the mode is from a symbolic link.
+\end{funcdesc}
+
+\begin{funcdesc}{S_ISSOCK}{mode}
+Return non-zero if the mode is from a socket.
+\end{funcdesc}
+
+Two additional functions are defined for more general manipulation of
+the file's mode:
+
+\begin{funcdesc}{S_IMODE}{mode}
+Return the portion of the file's mode that can be set by
+\function{os.chmod()}---that is, the file's permission bits, plus the
+sticky bit, set-group-id, and set-user-id bits (on systems that support
+them).
+\end{funcdesc}
+
+\begin{funcdesc}{S_IFMT}{mode}
+Return the portion of the file's mode that describes the file type (used
+by the \function{S_IS*()} functions above).
+\end{funcdesc}
+
+Normally, you would use the \function{os.path.is*()} functions for
+testing the type of a file; the functions here are useful when you are
+doing multiple tests of the same file and wish to avoid the overhead of
+the \cfunction{stat()} system call for each test.  These are also
+useful when checking for information about a file that isn't handled
+by \refmodule{os.path}, like the tests for block and character
+devices.
+
+All the variables below are simply symbolic indexes into the 10-tuple
+returned by \function{os.stat()}, \function{os.fstat()} or
+\function{os.lstat()}.
+
+\begin{datadesc}{ST_MODE}
+Inode protection mode.
+\end{datadesc}
+
+\begin{datadesc}{ST_INO}
+Inode number.
+\end{datadesc}
+
+\begin{datadesc}{ST_DEV}
+Device inode resides on.
+\end{datadesc}
+
+\begin{datadesc}{ST_NLINK}
+Number of links to the inode.
+\end{datadesc}
+
+\begin{datadesc}{ST_UID}
+User id of the owner.
+\end{datadesc}
+
+\begin{datadesc}{ST_GID}
+Group id of the owner.
+\end{datadesc}
+
+\begin{datadesc}{ST_SIZE}
+Size in bytes of a plain file; amount of data waiting on some special
+files.
+\end{datadesc}
+
+\begin{datadesc}{ST_ATIME}
+Time of last access.
+\end{datadesc}
+
+\begin{datadesc}{ST_MTIME}
+Time of last modification.
+\end{datadesc}
+
+\begin{datadesc}{ST_CTIME}
+The ``ctime'' as reported by the operating system.  On some systems
+(like \UNIX) is the time of the last metadata change, and, on others
+(like Windows), is the creation time (see platform documentation for
+details).
+\end{datadesc}
+
+The interpretation of ``file size'' changes according to the file
+type.  For plain files this is the size of the file in bytes.  For
+FIFOs and sockets under most flavors of \UNIX{} (including Linux in
+particular), the ``size'' is the number of bytes waiting to be read at
+the time of the call to \function{os.stat()}, \function{os.fstat()},
+or \function{os.lstat()}; this can sometimes be useful, especially for
+polling one of these special files after a non-blocking open.  The
+meaning of the size field for other character and block devices varies
+more, depending on the implementation of the underlying system call.
+
+Example:
+
+\begin{verbatim}
+import os, sys
+from stat import *
+
+def walktree(top, callback):
+    '''recursively descend the directory tree rooted at top,
+       calling the callback function for each regular file'''
+
+    for f in os.listdir(top):
+        pathname = os.path.join(top, f)
+        mode = os.stat(pathname)[ST_MODE]
+        if S_ISDIR(mode):
+            # It's a directory, recurse into it
+            walktree(pathname, callback)
+        elif S_ISREG(mode):
+            # It's a file, call the callback function
+            callback(pathname)
+        else:
+            # Unknown file type, print a message
+            print 'Skipping %s' % pathname
+
+def visitfile(file):
+    print 'visiting', file
+
+if __name__ == '__main__':
+    walktree(sys.argv[1], visitfile)
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/libstatvfs.tex
===================================================================
--- vendor/Python/current/Doc/lib/libstatvfs.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libstatvfs.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,55 @@
+\section{\module{statvfs} ---
+         Constants used with \function{os.statvfs()}}
+
+\declaremodule{standard}{statvfs}
+% LaTeX'ed from comments in module
+\sectionauthor{Moshe Zadka}{moshez at zadka.site.co.il}
+\modulesynopsis{Constants for interpreting the result of
+                \function{os.statvfs()}.}
+
+The \module{statvfs} module defines constants so interpreting the result
+if \function{os.statvfs()}, which returns a tuple, can be made without
+remembering ``magic numbers.''  Each of the constants defined in this
+module is the \emph{index} of the entry in the tuple returned by
+\function{os.statvfs()} that contains the specified information.
+
+
+\begin{datadesc}{F_BSIZE}
+Preferred file system block size.
+\end{datadesc}
+
+\begin{datadesc}{F_FRSIZE}
+Fundamental file system block size.
+\end{datadesc}
+
+\begin{datadesc}{F_BLOCKS}
+Total number of blocks in the filesystem.
+\end{datadesc}
+
+\begin{datadesc}{F_BFREE}
+Total number of free blocks.
+\end{datadesc}
+
+\begin{datadesc}{F_BAVAIL}
+Free blocks available to non-super user.
+\end{datadesc}
+
+\begin{datadesc}{F_FILES}
+Total number of file nodes.
+\end{datadesc}
+
+\begin{datadesc}{F_FFREE}
+Total number of free file nodes.
+\end{datadesc}
+
+\begin{datadesc}{F_FAVAIL}
+Free nodes available to non-super user.
+\end{datadesc}
+
+\begin{datadesc}{F_FLAG}
+Flags. System dependent: see \cfunction{statvfs()} man page.
+\end{datadesc}
+
+\begin{datadesc}{F_NAMEMAX}
+Maximum file name length.
+\end{datadesc}

Added: vendor/Python/current/Doc/lib/libstdtypes.tex
===================================================================
--- vendor/Python/current/Doc/lib/libstdtypes.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libstdtypes.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2095 @@
+\chapter{Built-in Types \label{types}}
+
+The following sections describe the standard types that are built into
+the interpreter.
+\note{Historically (until release 2.2), Python's built-in types have
+differed from user-defined types because it was not possible to use
+the built-in types as the basis for object-oriented inheritance.
+This limitation does not exist any longer.}
+
+The principal built-in types are numerics, sequences, mappings, files,
+classes, instances and exceptions.
+\indexii{built-in}{types}
+
+Some operations are supported by several object types; in particular,
+practically all objects can be compared, tested for truth value,
+and converted to a string (with
+the \function{repr()} function or the slightly different
+\function{str()} function).  The latter
+function is implicitly used when an object is written by the
+\keyword{print}\stindex{print} statement.
+(Information on the \ulink{\keyword{print} statement}{../ref/print.html}
+and other language statements can be found in the
+\citetitle[../ref/ref.html]{Python Reference Manual} and the
+\citetitle[../tut/tut.html]{Python Tutorial}.)
+
+
+\section{Truth Value Testing\label{truth}}
+
+Any object can be tested for truth value, for use in an \keyword{if} or
+\keyword{while} condition or as operand of the Boolean operations below.
+The following values are considered false:
+\stindex{if}
+\stindex{while}
+\indexii{truth}{value}
+\indexii{Boolean}{operations}
+\index{false}
+
+\begin{itemize}
+
+\item	\code{None}
+        \withsubitem{(Built-in object)}{\ttindex{None}}
+
+\item	\code{False}
+        \withsubitem{(Built-in object)}{\ttindex{False}}
+
+\item	zero of any numeric type, for example, \code{0}, \code{0L},
+        \code{0.0}, \code{0j}.
+
+\item	any empty sequence, for example, \code{''}, \code{()}, \code{[]}.
+
+\item	any empty mapping, for example, \code{\{\}}.
+
+\item	instances of user-defined classes, if the class defines a
+        \method{__nonzero__()} or \method{__len__()} method, when that
+        method returns the integer zero or \class{bool} value
+        \code{False}.\footnote{Additional 
+information on these special methods may be found in the
+\citetitle[../ref/ref.html]{Python Reference Manual}.}
+
+\end{itemize}
+
+All other values are considered true --- so objects of many types are
+always true.
+\index{true}
+
+Operations and built-in functions that have a Boolean result always
+return \code{0} or \code{False} for false and \code{1} or \code{True}
+for true, unless otherwise stated.  (Important exception: the Boolean
+operations \samp{or}\opindex{or} and \samp{and}\opindex{and} always
+return one of their operands.)
+\index{False}
+\index{True}
+
+\section{Boolean Operations ---
+	    \keyword{and}, \keyword{or}, \keyword{not}
+	    \label{boolean}}
+
+These are the Boolean operations, ordered by ascending priority:
+\indexii{Boolean}{operations}
+
+\begin{tableiii}{c|l|c}{code}{Operation}{Result}{Notes}
+  \lineiii{\var{x} or \var{y}}
+          {if \var{x} is false, then \var{y}, else \var{x}}{(1)}
+  \lineiii{\var{x} and \var{y}}
+          {if \var{x} is false, then \var{x}, else \var{y}}{(1)}
+  \hline
+  \lineiii{not \var{x}}
+          {if \var{x} is false, then \code{True}, else \code{False}}{(2)}
+\end{tableiii}
+\opindex{and}
+\opindex{or}
+\opindex{not}
+
+\noindent
+Notes:
+
+\begin{description}
+
+\item[(1)]
+These only evaluate their second argument if needed for their outcome.
+
+\item[(2)]
+\samp{not} has a lower priority than non-Boolean operators, so
+\code{not \var{a} == \var{b}} is interpreted as \code{not (\var{a} ==
+\var{b})}, and \code{\var{a} == not \var{b}} is a syntax error.
+
+\end{description}
+
+
+\section{Comparisons \label{comparisons}}
+
+Comparison operations are supported by all objects.  They all have the
+same priority (which is higher than that of the Boolean operations).
+Comparisons can be chained arbitrarily; for example, \code{\var{x} <
+\var{y} <= \var{z}} is equivalent to \code{\var{x} < \var{y} and
+\var{y} <= \var{z}}, except that \var{y} is evaluated only once (but
+in both cases \var{z} is not evaluated at all when \code{\var{x} <
+\var{y}} is found to be false).
+\indexii{chaining}{comparisons}
+
+This table summarizes the comparison operations:
+
+\begin{tableiii}{c|l|c}{code}{Operation}{Meaning}{Notes}
+  \lineiii{<}{strictly less than}{}
+  \lineiii{<=}{less than or equal}{}
+  \lineiii{>}{strictly greater than}{}
+  \lineiii{>=}{greater than or equal}{}
+  \lineiii{==}{equal}{}
+  \lineiii{!=}{not equal}{(1)}
+  \lineiii{<>}{not equal}{(1)}
+  \lineiii{is}{object identity}{}
+  \lineiii{is not}{negated object identity}{}
+\end{tableiii}
+\indexii{operator}{comparison}
+\opindex{==} % XXX *All* others have funny characters < ! >
+\opindex{is}
+\opindex{is not}
+
+\noindent
+Notes:
+
+\begin{description}
+
+\item[(1)]
+\code{<>} and \code{!=} are alternate spellings for the same operator.
+\code{!=} is the preferred spelling; \code{<>} is obsolescent.
+
+\end{description}
+
+Objects of different types, except different numeric types and different string types, never
+compare equal; such objects are ordered consistently but arbitrarily
+(so that sorting a heterogeneous array yields a consistent result).
+Furthermore, some types (for example, file objects) support only a
+degenerate notion of comparison where any two objects of that type are
+unequal.  Again, such objects are ordered arbitrarily but
+consistently. The \code{<}, \code{<=}, \code{>} and \code{>=}
+operators will raise a \exception{TypeError} exception when any operand
+is a complex number. 
+\indexii{object}{numeric}
+\indexii{objects}{comparing}
+
+Instances of a class normally compare as non-equal unless the class
+\withsubitem{(instance method)}{\ttindex{__cmp__()}}
+defines the \method{__cmp__()} method.  Refer to the
+\citetitle[../ref/customization.html]{Python Reference Manual} for
+information on the use of this method to effect object comparisons.
+
+\strong{Implementation note:} Objects of different types except
+numbers are ordered by their type names; objects of the same types
+that don't support proper comparison are ordered by their address.
+
+Two more operations with the same syntactic priority,
+\samp{in}\opindex{in} and \samp{not in}\opindex{not in}, are supported
+only by sequence types (below).
+
+
+\section{Numeric Types ---
+	    \class{int}, \class{float}, \class{long}, \class{complex}
+	    \label{typesnumeric}}
+
+There are four distinct numeric types: \dfn{plain integers},
+\dfn{long integers}, 
+\dfn{floating point numbers}, and \dfn{complex numbers}.
+In addition, Booleans are a subtype of plain integers.
+Plain integers (also just called \dfn{integers})
+are implemented using \ctype{long} in C, which gives them at least 32
+bits of precision (\code{sys.maxint} is always set to the maximum
+plain integer value for the current platform, the minimum value is 
+\code{-sys.maxint - 1}).  Long integers have unlimited precision.
+Floating point numbers are implemented using \ctype{double} in C.
+All bets on their precision are off unless you happen to know the
+machine you are working with.
+\obindex{numeric}
+\obindex{Boolean}
+\obindex{integer}
+\obindex{long integer}
+\obindex{floating point}
+\obindex{complex number}
+\indexii{C}{language}
+
+Complex numbers have a real and imaginary part, which are each
+implemented using \ctype{double} in C.  To extract these parts from
+a complex number \var{z}, use \code{\var{z}.real} and \code{\var{z}.imag}.
+
+Numbers are created by numeric literals or as the result of built-in
+functions and operators.  Unadorned integer literals (including hex
+and octal numbers) yield plain integers unless the value they denote
+is too large to be represented as a plain integer, in which case
+they yield a long integer.  Integer literals with an
+\character{L} or \character{l} suffix yield long integers
+(\character{L} is preferred because \samp{1l} looks too much like
+eleven!).  Numeric literals containing a decimal point or an exponent
+sign yield floating point numbers.  Appending \character{j} or
+\character{J} to a numeric literal yields a complex number with a
+zero real part. A complex numeric literal is the sum of a real and
+an imaginary part.
+\indexii{numeric}{literals}
+\indexii{integer}{literals}
+\indexiii{long}{integer}{literals}
+\indexii{floating point}{literals}
+\indexii{complex number}{literals}
+\indexii{hexadecimal}{literals}
+\indexii{octal}{literals}
+
+Python fully supports mixed arithmetic: when a binary arithmetic
+operator has operands of different numeric types, the operand with the
+``narrower'' type is widened to that of the other, where plain
+integer is narrower than long integer is narrower than floating point is
+narrower than complex.
+Comparisons between numbers of mixed type use the same rule.\footnote{
+	As a consequence, the list \code{[1, 2]} is considered equal
+        to \code{[1.0, 2.0]}, and similarly for tuples.
+} The constructors \function{int()}, \function{long()}, \function{float()},
+and \function{complex()} can be used
+to produce numbers of a specific type.
+\index{arithmetic}
+\bifuncindex{int}
+\bifuncindex{long}
+\bifuncindex{float}
+\bifuncindex{complex}
+
+All numeric types (except complex) support the following operations,
+sorted by ascending priority (operations in the same box have the same
+priority; all numeric operations have a higher priority than
+comparison operations):
+
+\begin{tableiii}{c|l|c}{code}{Operation}{Result}{Notes}
+  \lineiii{\var{x} + \var{y}}{sum of \var{x} and \var{y}}{}
+  \lineiii{\var{x} - \var{y}}{difference of \var{x} and \var{y}}{}
+  \hline
+  \lineiii{\var{x} * \var{y}}{product of \var{x} and \var{y}}{}
+  \lineiii{\var{x} / \var{y}}{quotient of \var{x} and \var{y}}{(1)}
+  \lineiii{\var{x} // \var{y}}{(floored) quotient of \var{x} and \var{y}}{(5)}
+  \lineiii{\var{x} \%{} \var{y}}{remainder of \code{\var{x} / \var{y}}}{(4)}
+  \hline
+  \lineiii{-\var{x}}{\var{x} negated}{}
+  \lineiii{+\var{x}}{\var{x} unchanged}{}
+  \hline
+  \lineiii{abs(\var{x})}{absolute value or magnitude of \var{x}}{}
+  \lineiii{int(\var{x})}{\var{x} converted to integer}{(2)}
+  \lineiii{long(\var{x})}{\var{x} converted to long integer}{(2)}
+  \lineiii{float(\var{x})}{\var{x} converted to floating point}{}
+  \lineiii{complex(\var{re},\var{im})}{a complex number with real part \var{re}, imaginary part \var{im}.  \var{im} defaults to zero.}{}
+  \lineiii{\var{c}.conjugate()}{conjugate of the complex number \var{c}}{}
+  \lineiii{divmod(\var{x}, \var{y})}{the pair \code{(\var{x} // \var{y}, \var{x} \%{} \var{y})}}{(3)(4)}
+  \lineiii{pow(\var{x}, \var{y})}{\var{x} to the power \var{y}}{}
+  \lineiii{\var{x} ** \var{y}}{\var{x} to the power \var{y}}{}
+\end{tableiii}
+\indexiii{operations on}{numeric}{types}
+\withsubitem{(complex number method)}{\ttindex{conjugate()}}
+
+\noindent
+Notes:
+\begin{description}
+
+\item[(1)]
+For (plain or long) integer division, the result is an integer.
+The result is always rounded towards minus infinity: 1/2 is 0,
+(-1)/2 is -1, 1/(-2) is -1, and (-1)/(-2) is 0.  Note that the result
+is a long integer if either operand is a long integer, regardless of
+the numeric value.
+\indexii{integer}{division}
+\indexiii{long}{integer}{division}
+
+\item[(2)]
+Conversion from floating point to (long or plain) integer may round or
+truncate as in C; see functions \function{floor()} and
+\function{ceil()} in the \refmodule{math}\refbimodindex{math} module
+for well-defined conversions.
+\withsubitem{(in module math)}{\ttindex{floor()}\ttindex{ceil()}}
+\indexii{numeric}{conversions}
+\indexii{C}{language}
+
+\item[(3)]
+See section \ref{built-in-funcs}, ``Built-in Functions,'' for a full
+description.
+
+\item[(4)]
+Complex floor division operator, modulo operator, and \function{divmod()}.
+
+\deprecated{2.3}{Instead convert to float using \function{abs()}
+if appropriate.}
+
+\item[(5)]
+Also referred to as integer division.  The resultant value is a whole integer,
+though the result's type is not necessarily int.
+\end{description}
+% XXXJH exceptions: overflow (when? what operations?) zerodivision
+
+\subsection{Bit-string Operations on Integer Types \label{bitstring-ops}}
+\nodename{Bit-string Operations}
+
+Plain and long integer types support additional operations that make
+sense only for bit-strings.  Negative numbers are treated as their 2's
+complement value (for long integers, this assumes a sufficiently large
+number of bits that no overflow occurs during the operation).
+
+The priorities of the binary bit-wise operations are all lower than
+the numeric operations and higher than the comparisons; the unary
+operation \samp{\~} has the same priority as the other unary numeric
+operations (\samp{+} and \samp{-}).
+
+This table lists the bit-string operations sorted in ascending
+priority (operations in the same box have the same priority):
+
+\begin{tableiii}{c|l|c}{code}{Operation}{Result}{Notes}
+  \lineiii{\var{x} | \var{y}}{bitwise \dfn{or} of \var{x} and \var{y}}{}
+  \lineiii{\var{x} \^{} \var{y}}{bitwise \dfn{exclusive or} of \var{x} and \var{y}}{}
+  \lineiii{\var{x} \&{} \var{y}}{bitwise \dfn{and} of \var{x} and \var{y}}{}
+  % The empty groups below prevent conversion to guillemets.
+  \lineiii{\var{x} <{}< \var{n}}{\var{x} shifted left by \var{n} bits}{(1), (2)}
+  \lineiii{\var{x} >{}> \var{n}}{\var{x} shifted right by \var{n} bits}{(1), (3)}
+  \hline
+  \lineiii{\~\var{x}}{the bits of \var{x} inverted}{}
+\end{tableiii}
+\indexiii{operations on}{integer}{types}
+\indexii{bit-string}{operations}
+\indexii{shifting}{operations}
+\indexii{masking}{operations}
+
+\noindent
+Notes:
+\begin{description}
+\item[(1)] Negative shift counts are illegal and cause a
+\exception{ValueError} to be raised.
+\item[(2)] A left shift by \var{n} bits is equivalent to
+multiplication by \code{pow(2, \var{n})} without overflow check.
+\item[(3)] A right shift by \var{n} bits is equivalent to
+division by \code{pow(2, \var{n})} without overflow check.
+\end{description}
+
+
+\section{Iterator Types \label{typeiter}}
+
+\versionadded{2.2}
+\index{iterator protocol}
+\index{protocol!iterator}
+\index{sequence!iteration}
+\index{container!iteration over}
+
+Python supports a concept of iteration over containers.  This is
+implemented using two distinct methods; these are used to allow
+user-defined classes to support iteration.  Sequences, described below
+in more detail, always support the iteration methods.
+
+One method needs to be defined for container objects to provide
+iteration support:
+
+\begin{methoddesc}[container]{__iter__}{}
+  Return an iterator object.  The object is required to support the
+  iterator protocol described below.  If a container supports
+  different types of iteration, additional methods can be provided to
+  specifically request iterators for those iteration types.  (An
+  example of an object supporting multiple forms of iteration would be
+  a tree structure which supports both breadth-first and depth-first
+  traversal.)  This method corresponds to the \member{tp_iter} slot of
+  the type structure for Python objects in the Python/C API.
+\end{methoddesc}
+
+The iterator objects themselves are required to support the following
+two methods, which together form the \dfn{iterator protocol}:
+
+\begin{methoddesc}[iterator]{__iter__}{}
+  Return the iterator object itself.  This is required to allow both
+  containers and iterators to be used with the \keyword{for} and
+  \keyword{in} statements.  This method corresponds to the
+  \member{tp_iter} slot of the type structure for Python objects in
+  the Python/C API.
+\end{methoddesc}
+
+\begin{methoddesc}[iterator]{next}{}
+  Return the next item from the container.  If there are no further
+  items, raise the \exception{StopIteration} exception.  This method
+  corresponds to the \member{tp_iternext} slot of the type structure
+  for Python objects in the Python/C API.
+\end{methoddesc}
+
+Python defines several iterator objects to support iteration over
+general and specific sequence types, dictionaries, and other more
+specialized forms.  The specific types are not important beyond their
+implementation of the iterator protocol.
+
+The intention of the protocol is that once an iterator's
+\method{next()} method raises \exception{StopIteration}, it will
+continue to do so on subsequent calls.  Implementations that
+do not obey this property are deemed broken.  (This constraint
+was added in Python 2.3; in Python 2.2, various iterators are
+broken according to this rule.)
+
+Python's generators provide a convenient way to implement the
+iterator protocol.  If a container object's \method{__iter__()}
+method is implemented as a generator, it will automatically
+return an iterator object (technically, a generator object)
+supplying the \method{__iter__()} and \method{next()} methods.
+
+
+\section{Sequence Types ---
+	    \class{str}, \class{unicode}, \class{list},
+	    \class{tuple}, \class{buffer}, \class{xrange}
+	    \label{typesseq}}
+
+There are six sequence types: strings, Unicode strings, lists,
+tuples, buffers, and xrange objects.
+
+String literals are written in single or double quotes:
+\code{'xyzzy'}, \code{"frobozz"}.  See chapter 2 of the
+\citetitle[../ref/strings.html]{Python Reference Manual} for more about
+string literals.  Unicode strings are much like strings, but are
+specified in the syntax using a preceding \character{u} character:
+\code{u'abc'}, \code{u"def"}.  Lists are constructed with square brackets,
+separating items with commas: \code{[a, b, c]}.  Tuples are
+constructed by the comma operator (not within square brackets), with
+or without enclosing parentheses, but an empty tuple must have the
+enclosing parentheses, such as \code{a, b, c} or \code{()}.  A single
+item tuple must have a trailing comma, such as \code{(d,)}.
+\obindex{sequence}
+\obindex{string}
+\obindex{Unicode}
+\obindex{tuple}
+\obindex{list}
+
+Buffer objects are not directly supported by Python syntax, but can be
+created by calling the builtin function
+\function{buffer()}.\bifuncindex{buffer}  They don't support
+concatenation or repetition.
+\obindex{buffer}
+
+Xrange objects are similar to buffers in that there is no specific
+syntax to create them, but they are created using the \function{xrange()}
+function.\bifuncindex{xrange}  They don't support slicing,
+concatenation or repetition, and using \code{in}, \code{not in},
+\function{min()} or \function{max()} on them is inefficient.
+\obindex{xrange}
+
+Most sequence types support the following operations.  The \samp{in} and
+\samp{not in} operations have the same priorities as the comparison
+operations.  The \samp{+} and \samp{*} operations have the same
+priority as the corresponding numeric operations.\footnote{They must
+have since the parser can't tell the type of the operands.}
+
+This table lists the sequence operations sorted in ascending priority
+(operations in the same box have the same priority).  In the table,
+\var{s} and \var{t} are sequences of the same type; \var{n}, \var{i}
+and \var{j} are integers:
+
+\begin{tableiii}{c|l|c}{code}{Operation}{Result}{Notes}
+  \lineiii{\var{x} in \var{s}}{\code{True} if an item of \var{s} is equal to \var{x}, else \code{False}}{(1)}
+  \lineiii{\var{x} not in \var{s}}{\code{False} if an item of \var{s} is
+equal to \var{x}, else \code{True}}{(1)}
+  \hline
+  \lineiii{\var{s} + \var{t}}{the concatenation of \var{s} and \var{t}}{(6)}
+  \lineiii{\var{s} * \var{n}\textrm{,} \var{n} * \var{s}}{\var{n} shallow copies of \var{s} concatenated}{(2)}
+  \hline
+  \lineiii{\var{s}[\var{i}]}{\var{i}'th item of \var{s}, origin 0}{(3)}
+  \lineiii{\var{s}[\var{i}:\var{j}]}{slice of \var{s} from \var{i} to \var{j}}{(3), (4)}
+  \lineiii{\var{s}[\var{i}:\var{j}:\var{k}]}{slice of \var{s} from \var{i} to \var{j} with step \var{k}}{(3), (5)}
+  \hline
+  \lineiii{len(\var{s})}{length of \var{s}}{}
+  \lineiii{min(\var{s})}{smallest item of \var{s}}{}
+  \lineiii{max(\var{s})}{largest item of \var{s}}{}
+\end{tableiii}
+\indexiii{operations on}{sequence}{types}
+\bifuncindex{len}
+\bifuncindex{min}
+\bifuncindex{max}
+\indexii{concatenation}{operation}
+\indexii{repetition}{operation}
+\indexii{subscript}{operation}
+\indexii{slice}{operation}
+\indexii{extended slice}{operation}
+\opindex{in}
+\opindex{not in}
+
+\noindent
+Notes:
+
+\begin{description}
+\item[(1)] When \var{s} is a string or Unicode string object the
+\code{in} and \code{not in} operations act like a substring test.  In
+Python versions before 2.3, \var{x} had to be a string of length 1.
+In Python 2.3 and beyond, \var{x} may be a string of any length.
+
+\item[(2)] Values of \var{n} less than \code{0} are treated as
+  \code{0} (which yields an empty sequence of the same type as
+  \var{s}).  Note also that the copies are shallow; nested structures
+  are not copied.  This often haunts new Python programmers; consider:
+
+\begin{verbatim}
+>>> lists = [[]] * 3
+>>> lists
+[[], [], []]
+>>> lists[0].append(3)
+>>> lists
+[[3], [3], [3]]
+\end{verbatim}
+
+  What has happened is that \code{[[]]} is a one-element list containing
+  an empty list, so all three elements of \code{[[]] * 3} are (pointers to)
+  this single empty list.  Modifying any of the elements of \code{lists}
+  modifies this single list.  You can create a list of different lists this
+  way:
+
+\begin{verbatim}
+>>> lists = [[] for i in range(3)]
+>>> lists[0].append(3)
+>>> lists[1].append(5)
+>>> lists[2].append(7)
+>>> lists
+[[3], [5], [7]]
+\end{verbatim}
+
+\item[(3)] If \var{i} or \var{j} is negative, the index is relative to
+  the end of the string: \code{len(\var{s}) + \var{i}} or
+  \code{len(\var{s}) + \var{j}} is substituted.  But note that \code{-0} is
+  still \code{0}.
+
+\item[(4)] The slice of \var{s} from \var{i} to \var{j} is defined as
+  the sequence of items with index \var{k} such that \code{\var{i} <=
+  \var{k} < \var{j}}.  If \var{i} or \var{j} is greater than
+  \code{len(\var{s})}, use \code{len(\var{s})}.  If \var{i} is omitted
+  or \code{None}, use \code{0}.  If \var{j} is omitted or \code{None},
+  use \code{len(\var{s})}.  If \var{i} is greater than or equal to \var{j},
+  the slice is empty.
+
+\item[(5)] The slice of \var{s} from \var{i} to \var{j} with step
+  \var{k} is defined as the sequence of items with index 
+  \code{\var{x} = \var{i} + \var{n}*\var{k}} such that
+  $0 \leq n < \frac{j-i}{k}$.  In other words, the indices
+  are \code{i}, \code{i+k}, \code{i+2*k}, \code{i+3*k} and so on, stopping when
+  \var{j} is reached (but never including \var{j}).  If \var{i} or \var{j}
+  is greater than \code{len(\var{s})}, use \code{len(\var{s})}.  If
+  \var{i} or \var{j} are omitted or \code{None}, they become ``end'' values
+  (which end depends on the sign of \var{k}).  Note, \var{k} cannot
+  be zero. If \var{k} is \code{None}, it is treated like \code{1}.
+
+\item[(6)] If \var{s} and \var{t} are both strings, some Python
+implementations such as CPython can usually perform an in-place optimization
+for assignments of the form \code{\var{s}=\var{s}+\var{t}} or
+\code{\var{s}+=\var{t}}.  When applicable, this optimization makes
+quadratic run-time much less likely.  This optimization is both version
+and implementation dependent.  For performance sensitive code, it is
+preferable to use the \method{str.join()} method which assures consistent
+linear concatenation performance across versions and implementations.
+\versionchanged[Formerly, string concatenation never occurred in-place]{2.4}
+
+\end{description}
+
+
+\subsection{String Methods \label{string-methods}}
+\indexii{string}{methods}
+
+These are the string methods which both 8-bit strings and Unicode
+objects support:
+
+\begin{methoddesc}[string]{capitalize}{}
+Return a copy of the string with only its first character capitalized.
+
+For 8-bit strings, this method is locale-dependent.
+\end{methoddesc}
+
+\begin{methoddesc}[string]{center}{width\optional{, fillchar}}
+Return centered in a string of length \var{width}. Padding is done
+using the specified \var{fillchar} (default is a space).
+\versionchanged[Support for the \var{fillchar} argument]{2.4}
+\end{methoddesc}
+
+\begin{methoddesc}[string]{count}{sub\optional{, start\optional{, end}}}
+Return the number of occurrences of substring \var{sub} in string
+S\code{[\var{start}:\var{end}]}.  Optional arguments \var{start} and
+\var{end} are interpreted as in slice notation.
+\end{methoddesc}
+
+\begin{methoddesc}[string]{decode}{\optional{encoding\optional{, errors}}}
+Decodes the string using the codec registered for \var{encoding}.
+\var{encoding} defaults to the default string encoding.  \var{errors}
+may be given to set a different error handling scheme.  The default is
+\code{'strict'}, meaning that encoding errors raise
+\exception{UnicodeError}.  Other possible values are \code{'ignore'},
+\code{'replace'} and any other name registered via
+\function{codecs.register_error}, see section~\ref{codec-base-classes}.
+\versionadded{2.2}
+\versionchanged[Support for other error handling schemes added]{2.3}
+\end{methoddesc}
+
+\begin{methoddesc}[string]{encode}{\optional{encoding\optional{,errors}}}
+Return an encoded version of the string.  Default encoding is the current
+default string encoding.  \var{errors} may be given to set a different
+error handling scheme.  The default for \var{errors} is
+\code{'strict'}, meaning that encoding errors raise a
+\exception{UnicodeError}.  Other possible values are \code{'ignore'},
+\code{'replace'}, \code{'xmlcharrefreplace'}, \code{'backslashreplace'}
+and any other name registered via \function{codecs.register_error},
+see section~\ref{codec-base-classes}.
+For a list of possible encodings, see section~\ref{standard-encodings}.
+\versionadded{2.0}
+\versionchanged[Support for \code{'xmlcharrefreplace'} and
+\code{'backslashreplace'} and other error handling schemes added]{2.3}
+\end{methoddesc}
+
+\begin{methoddesc}[string]{endswith}{suffix\optional{, start\optional{, end}}}
+Return \code{True} if the string ends with the specified \var{suffix},
+otherwise return \code{False}.  \var{suffix} can also be a tuple of
+suffixes to look for.  With optional \var{start}, test beginning at
+that position.  With optional \var{end}, stop comparing at that position.
+
+\versionchanged[Accept tuples as \var{suffix}]{2.5}
+\end{methoddesc}
+
+\begin{methoddesc}[string]{expandtabs}{\optional{tabsize}}
+Return a copy of the string where all tab characters are expanded
+using spaces.  If \var{tabsize} is not given, a tab size of \code{8}
+characters is assumed.
+\end{methoddesc}
+
+\begin{methoddesc}[string]{find}{sub\optional{, start\optional{, end}}}
+Return the lowest index in the string where substring \var{sub} is
+found, such that \var{sub} is contained in the range [\var{start},
+\var{end}].  Optional arguments \var{start} and \var{end} are
+interpreted as in slice notation.  Return \code{-1} if \var{sub} is
+not found.
+\end{methoddesc}
+
+\begin{methoddesc}[string]{index}{sub\optional{, start\optional{, end}}}
+Like \method{find()}, but raise \exception{ValueError} when the
+substring is not found.
+\end{methoddesc}
+
+\begin{methoddesc}[string]{isalnum}{}
+Return true if all characters in the string are alphanumeric and there
+is at least one character, false otherwise.
+
+For 8-bit strings, this method is locale-dependent.
+\end{methoddesc}
+
+\begin{methoddesc}[string]{isalpha}{}
+Return true if all characters in the string are alphabetic and there
+is at least one character, false otherwise.
+
+For 8-bit strings, this method is locale-dependent.
+\end{methoddesc}
+
+\begin{methoddesc}[string]{isdigit}{}
+Return true if all characters in the string are digits and there
+is at least one character, false otherwise.
+
+For 8-bit strings, this method is locale-dependent.
+\end{methoddesc}
+
+\begin{methoddesc}[string]{islower}{}
+Return true if all cased characters in the string are lowercase and
+there is at least one cased character, false otherwise.
+
+For 8-bit strings, this method is locale-dependent.
+\end{methoddesc}
+
+\begin{methoddesc}[string]{isspace}{}
+Return true if there are only whitespace characters in the string and
+there is at least one character, false otherwise.
+
+For 8-bit strings, this method is locale-dependent.
+\end{methoddesc}
+
+\begin{methoddesc}[string]{istitle}{}
+Return true if the string is a titlecased string and there is at least one
+character, for example uppercase characters may only follow uncased
+characters and lowercase characters only cased ones.  Return false
+otherwise.
+
+For 8-bit strings, this method is locale-dependent.
+\end{methoddesc}
+
+\begin{methoddesc}[string]{isupper}{}
+Return true if all cased characters in the string are uppercase and
+there is at least one cased character, false otherwise.
+
+For 8-bit strings, this method is locale-dependent.
+\end{methoddesc}
+
+\begin{methoddesc}[string]{join}{seq}
+Return a string which is the concatenation of the strings in the
+sequence \var{seq}.  The separator between elements is the string
+providing this method.
+\end{methoddesc}
+
+\begin{methoddesc}[string]{ljust}{width\optional{, fillchar}}
+Return the string left justified in a string of length \var{width}.
+Padding is done using the specified \var{fillchar} (default is a
+space).  The original string is returned if
+\var{width} is less than \code{len(\var{s})}.
+\versionchanged[Support for the \var{fillchar} argument]{2.4}
+\end{methoddesc}
+
+\begin{methoddesc}[string]{lower}{}
+Return a copy of the string converted to lowercase.
+
+For 8-bit strings, this method is locale-dependent.
+\end{methoddesc}
+
+\begin{methoddesc}[string]{lstrip}{\optional{chars}}
+Return a copy of the string with leading characters removed.  The
+\var{chars} argument is a string specifying the set of characters
+to be removed.  If omitted or \code{None}, the \var{chars} argument
+defaults to removing whitespace.  The \var{chars} argument is not
+a prefix; rather, all combinations of its values are stripped:
+\begin{verbatim}
+    >>> '   spacious   '.lstrip()
+    'spacious   '
+    >>> 'www.example.com'.lstrip('cmowz.')
+    'example.com'
+\end{verbatim}
+\versionchanged[Support for the \var{chars} argument]{2.2.2}
+\end{methoddesc}
+
+\begin{methoddesc}[string]{partition}{sep}
+Split the string at the first occurrence of \var{sep}, and return
+a 3-tuple containing the part before the separator, the separator
+itself, and the part after the separator.  If the separator is not
+found, return a 3-tuple containing the string itself, followed by
+two empty strings.
+\versionadded{2.5}
+\end{methoddesc}
+
+\begin{methoddesc}[string]{replace}{old, new\optional{, count}}
+Return a copy of the string with all occurrences of substring
+\var{old} replaced by \var{new}.  If the optional argument
+\var{count} is given, only the first \var{count} occurrences are
+replaced.
+\end{methoddesc}
+
+\begin{methoddesc}[string]{rfind}{sub \optional{,start \optional{,end}}}
+Return the highest index in the string where substring \var{sub} is
+found, such that \var{sub} is contained within s[start,end].  Optional
+arguments \var{start} and \var{end} are interpreted as in slice
+notation.  Return \code{-1} on failure.
+\end{methoddesc}
+
+\begin{methoddesc}[string]{rindex}{sub\optional{, start\optional{, end}}}
+Like \method{rfind()} but raises \exception{ValueError} when the
+substring \var{sub} is not found.
+\end{methoddesc}
+
+\begin{methoddesc}[string]{rjust}{width\optional{, fillchar}}
+Return the string right justified in a string of length \var{width}.
+Padding is done using the specified \var{fillchar} (default is a space).
+The original string is returned if
+\var{width} is less than \code{len(\var{s})}.
+\versionchanged[Support for the \var{fillchar} argument]{2.4}
+\end{methoddesc}
+
+\begin{methoddesc}[string]{rpartition}{sep}
+Split the string at the last occurrence of \var{sep}, and return
+a 3-tuple containing the part before the separator, the separator
+itself, and the part after the separator.  If the separator is not
+found, return a 3-tuple containing two empty strings, followed by
+the string itself.
+\versionadded{2.5}
+\end{methoddesc}
+
+\begin{methoddesc}[string]{rsplit}{\optional{sep \optional{,maxsplit}}}
+Return a list of the words in the string, using \var{sep} as the
+delimiter string.  If \var{maxsplit} is given, at most \var{maxsplit}
+splits are done, the \emph{rightmost} ones.  If \var{sep} is not specified
+or \code{None}, any whitespace string is a separator.  Except for splitting
+from the right, \method{rsplit()} behaves like \method{split()} which
+is described in detail below.
+\versionadded{2.4}
+\end{methoddesc}
+
+\begin{methoddesc}[string]{rstrip}{\optional{chars}}
+Return a copy of the string with trailing characters removed.  The
+\var{chars} argument is a string specifying the set of characters
+to be removed.  If omitted or \code{None}, the \var{chars} argument
+defaults to removing whitespace.  The \var{chars} argument is not
+a suffix; rather, all combinations of its values are stripped:
+\begin{verbatim}
+    >>> '   spacious   '.rstrip()
+    '   spacious'
+    >>> 'mississippi'.rstrip('ipz')
+    'mississ'
+\end{verbatim}
+\versionchanged[Support for the \var{chars} argument]{2.2.2}
+\end{methoddesc}
+
+\begin{methoddesc}[string]{split}{\optional{sep \optional{,maxsplit}}}
+Return a list of the words in the string, using \var{sep} as the
+delimiter string.  If \var{maxsplit} is given, at most \var{maxsplit}
+splits are done. (thus, the list will have at most \code{\var{maxsplit}+1}
+elements).  If \var{maxsplit} is not specified, then there
+is no limit on the number of splits (all possible splits are made).
+Consecutive delimiters are not grouped together and are
+deemed to delimit empty strings (for example, \samp{'1,,2'.split(',')}
+returns \samp{['1', '', '2']}).  The \var{sep} argument may consist of
+multiple characters (for example, \samp{'1, 2, 3'.split(', ')} returns
+\samp{['1', '2', '3']}).  Splitting an empty string with a specified
+separator returns \samp{['']}.
+
+If \var{sep} is not specified or is \code{None}, a different splitting
+algorithm is applied.  First, whitespace characters (spaces, tabs,
+newlines, returns, and formfeeds) are stripped from both ends.  Then,
+words are separated by arbitrary length strings of whitespace
+characters. Consecutive whitespace delimiters are treated as a single
+delimiter (\samp{'1  2  3'.split()} returns \samp{['1', '2', '3']}).
+Splitting an empty string or a string consisting of just whitespace
+returns an empty list.
+\end{methoddesc}
+
+\begin{methoddesc}[string]{splitlines}{\optional{keepends}}
+Return a list of the lines in the string, breaking at line
+boundaries.  Line breaks are not included in the resulting list unless
+\var{keepends} is given and true.
+\end{methoddesc}
+
+\begin{methoddesc}[string]{startswith}{prefix\optional{,
+                                       start\optional{, end}}}
+Return \code{True} if string starts with the \var{prefix}, otherwise
+return \code{False}.  \var{prefix} can also be a tuple of
+prefixes to look for.  With optional \var{start}, test string beginning at
+that position.  With optional \var{end}, stop comparing string at that
+position.
+
+\versionchanged[Accept tuples as \var{prefix}]{2.5}
+\end{methoddesc}
+
+\begin{methoddesc}[string]{strip}{\optional{chars}}
+Return a copy of the string with the leading and trailing characters
+removed.  The \var{chars} argument is a string specifying the set of
+characters to be removed.  If omitted or \code{None}, the \var{chars}
+argument defaults to removing whitespace.  The \var{chars} argument is not
+a prefix or suffix; rather, all combinations of its values are stripped:
+\begin{verbatim}
+    >>> '   spacious   '.strip()
+    'spacious'
+    >>> 'www.example.com'.strip('cmowz.')
+    'example'
+\end{verbatim}
+\versionchanged[Support for the \var{chars} argument]{2.2.2}
+\end{methoddesc}
+
+\begin{methoddesc}[string]{swapcase}{}
+Return a copy of the string with uppercase characters converted to
+lowercase and vice versa.
+
+For 8-bit strings, this method is locale-dependent.
+\end{methoddesc}
+
+\begin{methoddesc}[string]{title}{}
+Return a titlecased version of the string: words start with uppercase
+characters, all remaining cased characters are lowercase.
+
+For 8-bit strings, this method is locale-dependent.
+\end{methoddesc}
+
+\begin{methoddesc}[string]{translate}{table\optional{, deletechars}}
+Return a copy of the string where all characters occurring in the
+optional argument \var{deletechars} are removed, and the remaining
+characters have been mapped through the given translation table, which
+must be a string of length 256.
+
+You can use the \function{maketrans()} helper function in the
+\refmodule{string} module to create a translation table.
+
+For Unicode objects, the \method{translate()} method does not
+accept the optional \var{deletechars} argument.  Instead, it
+returns a copy of the \var{s} where all characters have been mapped
+through the given translation table which must be a mapping of
+Unicode ordinals to Unicode ordinals, Unicode strings or \code{None}.
+Unmapped characters are left untouched. Characters mapped to \code{None}
+are deleted.  Note, a more flexible approach is to create a custom
+character mapping codec using the \refmodule{codecs} module (see
+\module{encodings.cp1251} for an example).      
+\end{methoddesc}
+
+\begin{methoddesc}[string]{upper}{}
+Return a copy of the string converted to uppercase.
+
+For 8-bit strings, this method is locale-dependent.
+\end{methoddesc}
+
+\begin{methoddesc}[string]{zfill}{width}
+Return the numeric string left filled with zeros in a string
+of length \var{width}. The original string is returned if
+\var{width} is less than \code{len(\var{s})}.
+\versionadded{2.2.2}
+\end{methoddesc}
+
+
+\subsection{String Formatting Operations \label{typesseq-strings}}
+
+\index{formatting, string (\%{})}
+\index{interpolation, string (\%{})}
+\index{string!formatting}
+\index{string!interpolation}
+\index{printf-style formatting}
+\index{sprintf-style formatting}
+\index{\protect\%{} formatting}
+\index{\protect\%{} interpolation}
+
+String and Unicode objects have one unique built-in operation: the
+\code{\%} operator (modulo).  This is also known as the string
+\emph{formatting} or \emph{interpolation} operator.  Given
+\code{\var{format} \% \var{values}} (where \var{format} is a string or
+Unicode object), \code{\%} conversion specifications in \var{format}
+are replaced with zero or more elements of \var{values}.  The effect
+is similar to the using \cfunction{sprintf()} in the C language.  If
+\var{format} is a Unicode object, or if any of the objects being
+converted using the \code{\%s} conversion are Unicode objects, the
+result will also be a Unicode object.
+
+If \var{format} requires a single argument, \var{values} may be a
+single non-tuple object.\footnote{To format only a tuple you
+should therefore provide a singleton tuple whose only element
+is the tuple to be formatted.}  Otherwise, \var{values} must be a tuple with
+exactly the number of items specified by the format string, or a
+single mapping object (for example, a dictionary).
+
+A conversion specifier contains two or more characters and has the
+following components, which must occur in this order:
+
+\begin{enumerate}
+  \item  The \character{\%} character, which marks the start of the
+         specifier.
+  \item  Mapping key (optional), consisting of a parenthesised sequence
+         of characters (for example, \code{(somename)}).
+  \item  Conversion flags (optional), which affect the result of some
+         conversion types.
+  \item  Minimum field width (optional).  If specified as an
+         \character{*} (asterisk), the actual width is read from the
+         next element of the tuple in \var{values}, and the object to
+         convert comes after the minimum field width and optional
+         precision.
+  \item  Precision (optional), given as a \character{.} (dot) followed
+         by the precision.  If specified as \character{*} (an
+         asterisk), the actual width is read from the next element of
+         the tuple in \var{values}, and the value to convert comes after
+         the precision.
+  \item  Length modifier (optional).
+  \item  Conversion type.
+\end{enumerate}
+
+When the right argument is a dictionary (or other mapping type), then
+the formats in the string \emph{must} include a parenthesised mapping key into
+that dictionary inserted immediately after the \character{\%}
+character. The mapping key selects the value to be formatted from the
+mapping.  For example:
+
+\begin{verbatim}
+>>> print '%(language)s has %(#)03d quote types.' % \
+          {'language': "Python", "#": 2}
+Python has 002 quote types.
+\end{verbatim}
+
+In this case no \code{*} specifiers may occur in a format (since they
+require a sequential parameter list).
+
+The conversion flag characters are:
+
+\begin{tableii}{c|l}{character}{Flag}{Meaning}
+  \lineii{\#}{The value conversion will use the ``alternate form''
+              (where defined below).}
+  \lineii{0}{The conversion will be zero padded for numeric values.}
+  \lineii{-}{The converted value is left adjusted (overrides
+             the \character{0} conversion if both are given).}
+  \lineii{{~}}{(a space) A blank should be left before a positive number
+             (or empty string) produced by a signed conversion.}
+  \lineii{+}{A sign character (\character{+} or \character{-}) will
+             precede the conversion (overrides a "space" flag).}
+\end{tableii}
+
+A length modifier (\code{h}, \code{l}, or \code{L}) may be
+present, but is ignored as it is not necessary for Python.
+
+The conversion types are:
+
+\begin{tableiii}{c|l|c}{character}{Conversion}{Meaning}{Notes}
+  \lineiii{d}{Signed integer decimal.}{}
+  \lineiii{i}{Signed integer decimal.}{}
+  \lineiii{o}{Unsigned octal.}{(1)}
+  \lineiii{u}{Unsigned decimal.}{}
+  \lineiii{x}{Unsigned hexadecimal (lowercase).}{(2)}
+  \lineiii{X}{Unsigned hexadecimal (uppercase).}{(2)}
+  \lineiii{e}{Floating point exponential format (lowercase).}{(3)}
+  \lineiii{E}{Floating point exponential format (uppercase).}{(3)}
+  \lineiii{f}{Floating point decimal format.}{(3)}
+  \lineiii{F}{Floating point decimal format.}{(3)}
+  \lineiii{g}{Floating point format. Uses exponential format
+              if exponent is greater than -4 or less than precision,
+              decimal format otherwise.}{(4)}
+  \lineiii{G}{Floating point format. Uses exponential format
+              if exponent is greater than -4 or less than precision,
+              decimal format otherwise.}{(4)}
+  \lineiii{c}{Single character (accepts integer or single character
+              string).}{}
+  \lineiii{r}{String (converts any python object using
+              \function{repr()}).}{(5)}
+  \lineiii{s}{String (converts any python object using
+              \function{str()}).}{(6)}
+  \lineiii{\%}{No argument is converted, results in a \character{\%}
+               character in the result.}{}
+\end{tableiii}
+
+\noindent
+Notes:
+\begin{description}
+  \item[(1)]
+    The alternate form causes a leading zero (\character{0}) to be
+    inserted between left-hand padding and the formatting of the
+    number if the leading character of the result is not already a
+    zero.
+  \item[(2)]
+    The alternate form causes a leading \code{'0x'} or \code{'0X'}
+    (depending on whether the \character{x} or \character{X} format
+    was used) to be inserted between left-hand padding and the
+    formatting of the number if the leading character of the result is
+    not already a zero.
+  \item[(3)]
+    The alternate form causes the result to always contain a decimal
+    point, even if no digits follow it.
+
+    The precision determines the number of digits after the decimal
+    point and defaults to 6.
+  \item[(4)]
+    The alternate form causes the result to always contain a decimal
+    point, and trailing zeroes are not removed as they would
+    otherwise be.
+
+    The precision determines the number of significant digits before
+    and after the decimal point and defaults to 6.
+  \item[(5)]
+    The \code{\%r} conversion was added in Python 2.0.
+
+    The precision determines the maximal number of characters used.
+  \item[(6)]
+    If the object or format provided is a \class{unicode} string,
+    the resulting string will also be \class{unicode}.
+
+    The precision determines the maximal number of characters used.
+\end{description}
+
+% XXX Examples?
+
+Since Python strings have an explicit length, \code{\%s} conversions
+do not assume that \code{'\e0'} is the end of the string.
+
+For safety reasons, floating point precisions are clipped to 50;
+\code{\%f} conversions for numbers whose absolute value is over 1e25
+are replaced by \code{\%g} conversions.\footnote{
+  These numbers are fairly arbitrary.  They are intended to
+  avoid printing endless strings of meaningless digits without hampering
+  correct use and without having to know the exact precision of floating
+  point values on a particular machine.
+}  All other errors raise exceptions.
+
+Additional string operations are defined in standard modules
+\refmodule{string}\refstmodindex{string}\ and
+\refmodule{re}.\refstmodindex{re}
+
+
+\subsection{XRange Type \label{typesseq-xrange}}
+
+The \class{xrange}\obindex{xrange} type is an immutable sequence which
+is commonly used for looping.  The advantage of the \class{xrange}
+type is that an \class{xrange} object will always take the same amount
+of memory, no matter the size of the range it represents.  There are
+no consistent performance advantages.
+
+XRange objects have very little behavior: they only support indexing,
+iteration, and the \function{len()} function.
+
+
+\subsection{Mutable Sequence Types \label{typesseq-mutable}}
+
+List objects support additional operations that allow in-place
+modification of the object.
+Other mutable sequence types (when added to the language) should
+also support these operations.
+Strings and tuples are immutable sequence types: such objects cannot
+be modified once created.
+The following operations are defined on mutable sequence types (where
+\var{x} is an arbitrary object):
+\indexiii{mutable}{sequence}{types}
+\obindex{list}
+
+\begin{tableiii}{c|l|c}{code}{Operation}{Result}{Notes}
+  \lineiii{\var{s}[\var{i}] = \var{x}}
+	{item \var{i} of \var{s} is replaced by \var{x}}{}
+  \lineiii{\var{s}[\var{i}:\var{j}] = \var{t}}
+  	{slice of \var{s} from \var{i} to \var{j} 
+         is replaced by the contents of the iterable \var{t}}{}
+  \lineiii{del \var{s}[\var{i}:\var{j}]}
+	{same as \code{\var{s}[\var{i}:\var{j}] = []}}{}
+  \lineiii{\var{s}[\var{i}:\var{j}:\var{k}] = \var{t}}
+  	{the elements of \code{\var{s}[\var{i}:\var{j}:\var{k}]} are replaced by those of \var{t}}{(1)}
+  \lineiii{del \var{s}[\var{i}:\var{j}:\var{k}]}
+	{removes the elements of \code{\var{s}[\var{i}:\var{j}:\var{k}]} from the list}{}
+  \lineiii{\var{s}.append(\var{x})}
+	{same as \code{\var{s}[len(\var{s}):len(\var{s})] = [\var{x}]}}{(2)}
+  \lineiii{\var{s}.extend(\var{x})}
+        {same as \code{\var{s}[len(\var{s}):len(\var{s})] = \var{x}}}{(3)}
+  \lineiii{\var{s}.count(\var{x})}
+    {return number of \var{i}'s for which \code{\var{s}[\var{i}] == \var{x}}}{}
+  \lineiii{\var{s}.index(\var{x}\optional{, \var{i}\optional{, \var{j}}})}
+    {return smallest \var{k} such that \code{\var{s}[\var{k}] == \var{x}} and
+    \code{\var{i} <= \var{k} < \var{j}}}{(4)}
+  \lineiii{\var{s}.insert(\var{i}, \var{x})}
+	{same as \code{\var{s}[\var{i}:\var{i}] = [\var{x}]}}{(5)}
+  \lineiii{\var{s}.pop(\optional{\var{i}})}
+    {same as \code{\var{x} = \var{s}[\var{i}]; del \var{s}[\var{i}]; return \var{x}}}{(6)}
+  \lineiii{\var{s}.remove(\var{x})}
+	{same as \code{del \var{s}[\var{s}.index(\var{x})]}}{(4)}
+  \lineiii{\var{s}.reverse()}
+	{reverses the items of \var{s} in place}{(7)}
+  \lineiii{\var{s}.sort(\optional{\var{cmp}\optional{,
+                        \var{key}\optional{, \var{reverse}}}})}
+	{sort the items of \var{s} in place}{(7), (8), (9), (10)}
+\end{tableiii}
+\indexiv{operations on}{mutable}{sequence}{types}
+\indexiii{operations on}{sequence}{types}
+\indexiii{operations on}{list}{type}
+\indexii{subscript}{assignment}
+\indexii{slice}{assignment}
+\indexii{extended slice}{assignment}
+\stindex{del}
+\withsubitem{(list method)}{
+  \ttindex{append()}\ttindex{extend()}\ttindex{count()}\ttindex{index()}
+  \ttindex{insert()}\ttindex{pop()}\ttindex{remove()}\ttindex{reverse()}
+  \ttindex{sort()}}
+\noindent
+Notes:
+\begin{description}
+\item[(1)] \var{t} must have the same length as the slice it is 
+  replacing.
+
+\item[(2)] The C implementation of Python has historically accepted
+  multiple parameters and implicitly joined them into a tuple; this
+  no longer works in Python 2.0.  Use of this misfeature has been
+  deprecated since Python 1.4.
+
+\item[(3)] \var{x} can be any iterable object.
+
+\item[(4)] Raises \exception{ValueError} when \var{x} is not found in
+  \var{s}. When a negative index is passed as the second or third parameter
+  to the \method{index()} method, the list length is added, as for slice
+  indices.  If it is still negative, it is truncated to zero, as for
+  slice indices.  \versionchanged[Previously, \method{index()} didn't
+  have arguments for specifying start and stop positions]{2.3}
+
+\item[(5)] When a negative index is passed as the first parameter to
+  the \method{insert()} method, the list length is added, as for slice
+  indices.  If it is still negative, it is truncated to zero, as for
+  slice indices.  \versionchanged[Previously, all negative indices
+  were truncated to zero]{2.3}
+
+\item[(6)] The \method{pop()} method is only supported by the list and
+  array types.  The optional argument \var{i} defaults to \code{-1},
+  so that by default the last item is removed and returned.
+
+\item[(7)] The \method{sort()} and \method{reverse()} methods modify the
+  list in place for economy of space when sorting or reversing a large
+  list.  To remind you that they operate by side effect, they don't return
+  the sorted or reversed list.
+
+\item[(8)] The \method{sort()} method takes optional arguments for
+  controlling the comparisons.
+
+  \var{cmp} specifies a custom comparison function of two arguments
+     (list items) which should return a negative, zero or positive number
+     depending on whether the first argument is considered smaller than,
+     equal to, or larger than the second argument:
+     \samp{\var{cmp}=\keyword{lambda} \var{x},\var{y}:
+     \function{cmp}(x.lower(), y.lower())}
+     
+  \var{key} specifies a function of one argument that is used to
+     extract a comparison key from each list element:
+     \samp{\var{key}=\function{str.lower}}
+
+  \var{reverse} is a boolean value.  If set to \code{True}, then the
+     list elements are sorted as if each comparison were reversed.
+
+  In general, the \var{key} and \var{reverse} conversion processes are
+  much faster than specifying an equivalent \var{cmp} function.  This is
+  because \var{cmp} is called multiple times for each list element while
+  \var{key} and \var{reverse} touch each element only once.
+
+  \versionchanged[Support for \code{None} as an equivalent to omitting
+  \var{cmp} was added]{2.3}
+
+  \versionchanged[Support for \var{key} and \var{reverse} was added]{2.4}
+
+\item[(9)] Starting with Python 2.3, the \method{sort()} method is
+  guaranteed to be stable.  A sort is stable if it guarantees not to
+  change the relative order of elements that compare equal --- this is
+  helpful for sorting in multiple passes (for example, sort by
+  department, then by salary grade).
+
+\item[(10)] While a list is being sorted, the effect of attempting to
+  mutate, or even inspect, the list is undefined.  The C
+  implementation of Python 2.3 and newer makes the list appear empty
+  for the duration, and raises \exception{ValueError} if it can detect
+  that the list has been mutated during a sort.
+\end{description}
+
+\section{Set Types ---
+	    \class{set}, \class{frozenset}
+	    \label{types-set}}
+\obindex{set}
+
+A \dfn{set} object is an unordered collection of distinct hashable objects.
+Common uses include membership testing, removing duplicates from a sequence,
+and computing mathematical operations such as intersection, union, difference,
+and symmetric difference.
+\versionadded{2.4}     
+
+Like other collections, sets support \code{\var{x} in \var{set}},
+\code{len(\var{set})}, and \code{for \var{x} in \var{set}}.  Being an
+unordered collection, sets do not record element position or order of
+insertion.  Accordingly, sets do not support indexing, slicing, or
+other sequence-like behavior.     
+
+There are currently two builtin set types, \class{set} and \class{frozenset}.
+The \class{set} type is mutable --- the contents can be changed using methods
+like \method{add()} and \method{remove()}.  Since it is mutable, it has no
+hash value and cannot be used as either a dictionary key or as an element of
+another set.  The \class{frozenset} type is immutable and hashable --- its
+contents cannot be altered after is created; however, it can be used as
+a dictionary key or as an element of another set.
+
+Instances of \class{set} and \class{frozenset} provide the following operations:
+
+\begin{tableiii}{c|c|l}{code}{Operation}{Equivalent}{Result}
+  \lineiii{len(\var{s})}{}{cardinality of set \var{s}}
+
+  \hline
+  \lineiii{\var{x} in \var{s}}{}
+         {test \var{x} for membership in \var{s}}
+  \lineiii{\var{x} not in \var{s}}{}
+         {test \var{x} for non-membership in \var{s}}
+  \lineiii{\var{s}.issubset(\var{t})}{\code{\var{s} <= \var{t}}}
+         {test whether every element in \var{s} is in \var{t}}
+  \lineiii{\var{s}.issuperset(\var{t})}{\code{\var{s} >= \var{t}}}
+         {test whether every element in \var{t} is in \var{s}}
+
+  \hline
+  \lineiii{\var{s}.union(\var{t})}{\var{s} | \var{t}}
+         {new set with elements from both \var{s} and \var{t}}
+  \lineiii{\var{s}.intersection(\var{t})}{\var{s} \&\ \var{t}}
+         {new set with elements common to \var{s} and \var{t}}
+  \lineiii{\var{s}.difference(\var{t})}{\var{s} - \var{t}}
+         {new set with elements in \var{s} but not in \var{t}}
+  \lineiii{\var{s}.symmetric_difference(\var{t})}{\var{s} \^\ \var{t}}
+         {new set with elements in either \var{s} or \var{t} but not both}
+  \lineiii{\var{s}.copy()}{}
+         {new set with a shallow copy of \var{s}}
+\end{tableiii}
+
+Note, the non-operator versions of \method{union()}, \method{intersection()},
+\method{difference()}, and \method{symmetric_difference()},
+\method{issubset()}, and \method{issuperset()} methods will accept any
+iterable as an argument.  In contrast, their operator based counterparts
+require their arguments to be sets.  This precludes error-prone constructions
+like \code{set('abc') \&\ 'cbs'} in favor of the more readable
+\code{set('abc').intersection('cbs')}.
+
+Both \class{set} and \class{frozenset} support set to set comparisons.
+Two sets are equal if and only if every element of each set is contained in
+the other (each is a subset of the other).
+A set is less than another set if and only if the first set is a proper
+subset of the second set (is a subset, but is not equal).
+A set is greater than another set if and only if the first set is a proper
+superset of the second set (is a superset, but is not equal).
+
+Instances of \class{set} are compared to instances of \class{frozenset} based
+on their members.  For example, \samp{set('abc') == frozenset('abc')} returns
+\code{True}.     
+
+The subset and equality comparisons do not generalize to a complete
+ordering function.  For example, any two disjoint sets are not equal and
+are not subsets of each other, so \emph{all} of the following return
+\code{False}:  \code{\var{a}<\var{b}}, \code{\var{a}==\var{b}}, or
+\code{\var{a}>\var{b}}.
+Accordingly, sets do not implement the \method{__cmp__} method.
+
+Since sets only define partial ordering (subset relationships), the output
+of the \method{list.sort()} method is undefined for lists of sets.
+
+Set elements are like dictionary keys; they need to define both
+\method{__hash__} and \method{__eq__} methods.
+
+Binary operations that mix \class{set} instances with \class{frozenset}
+return the type of the first operand.  For example:
+\samp{frozenset('ab') | set('bc')} returns an instance of \class{frozenset}.
+
+The following table lists operations available for \class{set}
+that do not apply to immutable instances of \class{frozenset}:
+
+\begin{tableiii}{c|c|l}{code}{Operation}{Equivalent}{Result}
+  \lineiii{\var{s}.update(\var{t})}
+         {\var{s} |= \var{t}}
+         {update set \var{s}, adding elements from \var{t}}
+  \lineiii{\var{s}.intersection_update(\var{t})}
+         {\var{s} \&= \var{t}}
+         {update set \var{s}, keeping only elements found in both \var{s} and \var{t}}
+  \lineiii{\var{s}.difference_update(\var{t})}
+         {\var{s} -= \var{t}}
+         {update set \var{s}, removing elements found in \var{t}}
+  \lineiii{\var{s}.symmetric_difference_update(\var{t})}
+         {\var{s} \textasciicircum= \var{t}}
+         {update set \var{s}, keeping only elements found in either \var{s} or \var{t}
+          but not in both}
+
+  \hline
+  \lineiii{\var{s}.add(\var{x})}{}
+         {add element \var{x} to set \var{s}}
+  \lineiii{\var{s}.remove(\var{x})}{}
+         {remove \var{x} from set \var{s}; raises \exception{KeyError}
+	  if not present}
+  \lineiii{\var{s}.discard(\var{x})}{}
+         {removes \var{x} from set \var{s} if present}
+  \lineiii{\var{s}.pop()}{}
+         {remove and return an arbitrary element from \var{s}; raises
+	  \exception{KeyError} if empty}
+  \lineiii{\var{s}.clear()}{}
+         {remove all elements from set \var{s}}
+\end{tableiii}
+
+Note, the non-operator versions of the \method{update()},
+\method{intersection_update()}, \method{difference_update()}, and
+\method{symmetric_difference_update()} methods will accept any iterable
+as an argument.
+
+The design of the set types was based on lessons learned from the
+\module{sets} module.
+     
+\begin{seealso}     
+  \seelink{comparison-to-builtin-set.html}
+          {Comparison to the built-in set types}
+          {Differences between the \module{sets} module and the
+           built-in set types.}					      
+\end{seealso}
+     
+
+\section{Mapping Types --- \class{dict} \label{typesmapping}}
+\obindex{mapping}
+\obindex{dictionary}
+
+A \dfn{mapping} object maps  immutable values to
+arbitrary objects.  Mappings are mutable objects.  There is currently
+only one standard mapping type, the \dfn{dictionary}.  A dictionary's keys are
+almost arbitrary values.  Only values containing lists, dictionaries
+or other mutable types (that are compared by value rather than by
+object identity) may not be used as keys.
+Numeric types used for keys obey the normal rules for numeric
+comparison: if two numbers compare equal (such as \code{1} and
+\code{1.0}) then they can be used interchangeably to index the same
+dictionary entry.
+
+Dictionaries are created by placing a comma-separated list of
+\code{\var{key}: \var{value}} pairs within braces, for example:
+\code{\{'jack': 4098, 'sjoerd': 4127\}} or
+\code{\{4098: 'jack', 4127: 'sjoerd'\}}.
+
+The following operations are defined on mappings (where \var{a} and
+\var{b} are mappings, \var{k} is a key, and \var{v} and \var{x} are
+arbitrary objects):
+\indexiii{operations on}{mapping}{types}
+\indexiii{operations on}{dictionary}{type}
+\stindex{del}
+\bifuncindex{len}
+\withsubitem{(dictionary method)}{
+  \ttindex{clear()}
+  \ttindex{copy()}
+  \ttindex{has_key()}
+  \ttindex{fromkeys()}    
+  \ttindex{items()}
+  \ttindex{keys()}
+  \ttindex{update()}
+  \ttindex{values()}
+  \ttindex{get()}
+  \ttindex{setdefault()}
+  \ttindex{pop()}
+  \ttindex{popitem()}
+  \ttindex{iteritems()}
+  \ttindex{iterkeys()}
+  \ttindex{itervalues()}}
+
+\begin{tableiii}{c|l|c}{code}{Operation}{Result}{Notes}
+  \lineiii{len(\var{a})}{the number of items in \var{a}}{}
+  \lineiii{\var{a}[\var{k}]}{the item of \var{a} with key \var{k}}{(1), (10)}
+  \lineiii{\var{a}[\var{k}] = \var{v}}
+          {set \code{\var{a}[\var{k}]} to \var{v}}
+          {}
+  \lineiii{del \var{a}[\var{k}]}
+          {remove \code{\var{a}[\var{k}]} from \var{a}}
+          {(1)}
+  \lineiii{\var{a}.clear()}{remove all items from \code{a}}{}
+  \lineiii{\var{a}.copy()}{a (shallow) copy of \code{a}}{}
+  \lineiii{\var{k} in \var{a}}
+          {\code{True} if \var{a} has a key \var{k}, else \code{False}}
+          {(2)}
+  \lineiii{\var{k} not in \var{a}}
+          {Equivalent to \code{not} \var{k} in \var{a}}
+          {(2)}
+  \lineiii{\var{a}.has_key(\var{k})}
+          {Equivalent to \var{k} \code{in} \var{a}, use that form in new code}
+          {}
+  \lineiii{\var{a}.items()}
+          {a copy of \var{a}'s list of (\var{key}, \var{value}) pairs}
+          {(3)}
+  \lineiii{\var{a}.keys()}{a copy of \var{a}'s list of keys}{(3)}
+  \lineiii{\var{a}.update(\optional{\var{b}})}
+          {updates \var{a} with key/value pairs from \var{b}, overwriting
+	   existing keys, returns \code{None}}
+          {(9)}
+  \lineiii{\var{a}.fromkeys(\var{seq}\optional{, \var{value}})}
+          {Creates a new dictionary with keys from \var{seq} and values set to \var{value}}
+          {(7)}			   
+  \lineiii{\var{a}.values()}{a copy of \var{a}'s list of values}{(3)}
+  \lineiii{\var{a}.get(\var{k}\optional{, \var{x}})}
+          {\code{\var{a}[\var{k}]} if \code{\var{k} in \var{a}},
+           else \var{x}}
+          {(4)}
+  \lineiii{\var{a}.setdefault(\var{k}\optional{, \var{x}})}
+          {\code{\var{a}[\var{k}]} if \code{\var{k} in \var{a}},
+           else \var{x} (also setting it)}
+          {(5)}
+  \lineiii{\var{a}.pop(\var{k}\optional{, \var{x}})}
+          {\code{\var{a}[\var{k}]} if \code{\var{k} in \var{a}},
+           else \var{x} (and remove k)}
+          {(8)}
+  \lineiii{\var{a}.popitem()}
+          {remove and return an arbitrary (\var{key}, \var{value}) pair}
+          {(6)}
+  \lineiii{\var{a}.iteritems()}
+          {return an iterator over (\var{key}, \var{value}) pairs}
+          {(2), (3)}
+  \lineiii{\var{a}.iterkeys()}
+          {return an iterator over the mapping's keys}
+          {(2), (3)}
+  \lineiii{\var{a}.itervalues()}
+          {return an iterator over the mapping's values}
+          {(2), (3)}
+\end{tableiii}
+
+\noindent
+Notes:
+\begin{description}
+\item[(1)] Raises a \exception{KeyError} exception if \var{k} is not
+in the map.
+
+\item[(2)] \versionadded{2.2}
+
+\item[(3)] Keys and values are listed in an arbitrary order which is
+non-random, varies across Python implementations, and depends on the
+dictionary's history of insertions and deletions.
+If \method{items()}, \method{keys()}, \method{values()},
+\method{iteritems()}, \method{iterkeys()}, and \method{itervalues()}
+are called with no intervening modifications to the dictionary, the
+lists will directly correspond.  This allows the creation of
+\code{(\var{value}, \var{key})} pairs using \function{zip()}:
+\samp{pairs = zip(\var{a}.values(), \var{a}.keys())}.  The same
+relationship holds for the \method{iterkeys()} and
+\method{itervalues()} methods: \samp{pairs = zip(\var{a}.itervalues(),
+\var{a}.iterkeys())} provides the same value for \code{pairs}.
+Another way to create the same list is \samp{pairs = [(v, k) for (k,
+v) in \var{a}.iteritems()]}.
+
+\item[(4)] Never raises an exception if \var{k} is not in the map,
+instead it returns \var{x}.  \var{x} is optional; when \var{x} is not
+provided and \var{k} is not in the map, \code{None} is returned.
+
+\item[(5)] \function{setdefault()} is like \function{get()}, except
+that if \var{k} is missing, \var{x} is both returned and inserted into
+the dictionary as the value of \var{k}. \var{x} defaults to \var{None}.
+
+\item[(6)] \function{popitem()} is useful to destructively iterate
+over a dictionary, as often used in set algorithms.  If the dictionary
+is empty, calling \function{popitem()} raises a \exception{KeyError}.
+
+\item[(7)] \function{fromkeys()} is a class method that returns a
+new dictionary. \var{value} defaults to \code{None}.  \versionadded{2.3}
+
+\item[(8)] \function{pop()} raises a \exception{KeyError} when no default
+value is given and the key is not found.  \versionadded{2.3}
+
+\item[(9)] \function{update()} accepts either another mapping object
+or an iterable of key/value pairs (as a tuple or other iterable of
+length two).  If keyword arguments are specified, the mapping is
+then is updated with those key/value pairs:
+\samp{d.update(red=1, blue=2)}.
+\versionchanged[Allowed the argument to be an iterable of key/value
+                pairs and allowed keyword arguments]{2.4}
+
+\item[(10)] If a subclass of dict defines a method \method{__missing__},
+if the key \var{k} is not present, the \var{a}[\var{k}] operation calls
+that method with the key \var{k} as argument.  The \var{a}[\var{k}]
+operation then returns or raises whatever is returned or raised by the
+\function{__missing__}(\var{k}) call if the key is not present.
+No other operations or methods invoke \method{__missing__}().
+If \method{__missing__} is not defined, \exception{KeyError} is raised.
+\method{__missing__} must be a method; it cannot be an instance variable.
+For an example, see \module{collections}.\class{defaultdict}.
+\versionadded{2.5}
+
+\end{description}
+
+\section{File Objects
+            \label{bltin-file-objects}}
+
+File objects\obindex{file} are implemented using C's \code{stdio}
+package and can be created with the built-in constructor
+\function{file()}\bifuncindex{file} described in section
+\ref{built-in-funcs}, ``Built-in Functions.''\footnote{\function{file()}
+is new in Python 2.2.  The older built-in \function{open()} is an
+alias for \function{file()}.}  File objects are also returned
+by some other built-in functions and methods, such as
+\function{os.popen()} and \function{os.fdopen()} and the
+\method{makefile()} method of socket objects.
+\refstmodindex{os}
+\refbimodindex{socket}
+
+When a file operation fails for an I/O-related reason, the exception
+\exception{IOError} is raised.  This includes situations where the
+operation is not defined for some reason, like \method{seek()} on a tty
+device or writing a file opened for reading.
+
+Files have the following methods:
+
+
+\begin{methoddesc}[file]{close}{}
+  Close the file.  A closed file cannot be read or written any more.
+  Any operation which requires that the file be open will raise a
+  \exception{ValueError} after the file has been closed.  Calling
+  \method{close()} more than once is allowed.
+
+  As of Python 2.5, you can avoid having to call this method explicitly
+  if you use the \keyword{with} statement.  For example, the following
+  code will automatically close \code{f} when the \keyword{with} block
+  is exited:
+
+\begin{verbatim}
+from __future__ import with_statement
+
+with open("hello.txt") as f:
+    for line in f:
+        print line
+\end{verbatim}
+
+  In older versions of Python, you would have needed to do this to get
+  the same effect:
+
+\begin{verbatim}
+f = open("hello.txt")
+try:
+    for line in f:
+        print line
+finally:
+    f.close()
+\end{verbatim}
+
+  \note{Not all ``file-like'' types in Python support use as a context
+  manager for the \keyword{with} statement.  If your code is intended to
+  work with any file-like object, you can use the \function{closing()}
+  function in the \module{contextlib} module instead of using the object
+  directly.  See section~\ref{context-closing} for details.}
+  
+\end{methoddesc}
+
+\begin{methoddesc}[file]{flush}{}
+  Flush the internal buffer, like \code{stdio}'s
+  \cfunction{fflush()}.  This may be a no-op on some file-like
+  objects.
+\end{methoddesc}
+
+\begin{methoddesc}[file]{fileno}{}
+  \index{file descriptor}
+  \index{descriptor, file}
+  Return the integer ``file descriptor'' that is used by the
+  underlying implementation to request I/O operations from the
+  operating system.  This can be useful for other, lower level
+  interfaces that use file descriptors, such as the
+  \refmodule{fcntl}\refbimodindex{fcntl} module or
+  \function{os.read()} and friends.  \note{File-like objects
+  which do not have a real file descriptor should \emph{not} provide
+  this method!}
+\end{methoddesc}
+
+\begin{methoddesc}[file]{isatty}{}
+  Return \code{True} if the file is connected to a tty(-like) device, else
+  \code{False}.  \note{If a file-like object is not associated
+  with a real file, this method should \emph{not} be implemented.}
+\end{methoddesc}
+
+\begin{methoddesc}[file]{next}{}
+A file object is its own iterator, for example \code{iter(\var{f})} returns
+\var{f} (unless \var{f} is closed).  When a file is used as an
+iterator, typically in a \keyword{for} loop (for example,
+\code{for line in f: print line}), the \method{next()} method is
+called repeatedly.  This method returns the next input line, or raises
+\exception{StopIteration} when \EOF{} is hit.  In order to make a
+\keyword{for} loop the most efficient way of looping over the lines of
+a file (a very common operation), the \method{next()} method uses a
+hidden read-ahead buffer.  As a consequence of using a read-ahead
+buffer, combining \method{next()} with other file methods (like
+\method{readline()}) does not work right.  However, using
+\method{seek()} to reposition the file to an absolute position will
+flush the read-ahead buffer.
+\versionadded{2.3}
+\end{methoddesc}
+
+\begin{methoddesc}[file]{read}{\optional{size}}
+  Read at most \var{size} bytes from the file (less if the read hits
+  \EOF{} before obtaining \var{size} bytes).  If the \var{size}
+  argument is negative or omitted, read all data until \EOF{} is
+  reached.  The bytes are returned as a string object.  An empty
+  string is returned when \EOF{} is encountered immediately.  (For
+  certain files, like ttys, it makes sense to continue reading after
+  an \EOF{} is hit.)  Note that this method may call the underlying
+  C function \cfunction{fread()} more than once in an effort to
+  acquire as close to \var{size} bytes as possible. Also note that
+  when in non-blocking mode, less data than what was requested may
+  be returned, even if no \var{size} parameter was given.
+\end{methoddesc}
+
+\begin{methoddesc}[file]{readline}{\optional{size}}
+  Read one entire line from the file.  A trailing newline character is
+  kept in the string (but may be absent when a file ends with an
+  incomplete line).\footnote{
+	The advantage of leaving the newline on is that
+	returning an empty string is then an unambiguous \EOF{}
+	indication.  It is also possible (in cases where it might
+	matter, for example, if you
+	want to make an exact copy of a file while scanning its lines)
+	to tell whether the last line of a file ended in a newline
+	or not (yes this happens!).
+  }  If the \var{size} argument is present and
+  non-negative, it is a maximum byte count (including the trailing
+  newline) and an incomplete line may be returned.
+  An empty string is returned \emph{only} when \EOF{} is encountered
+  immediately.  \note{Unlike \code{stdio}'s \cfunction{fgets()}, the
+  returned string contains null characters (\code{'\e 0'}) if they
+  occurred in the input.}
+\end{methoddesc}
+
+\begin{methoddesc}[file]{readlines}{\optional{sizehint}}
+  Read until \EOF{} using \method{readline()} and return a list containing
+  the lines thus read.  If the optional \var{sizehint} argument is
+  present, instead of reading up to \EOF, whole lines totalling
+  approximately \var{sizehint} bytes (possibly after rounding up to an
+  internal buffer size) are read.  Objects implementing a file-like
+  interface may choose to ignore \var{sizehint} if it cannot be
+  implemented, or cannot be implemented efficiently.
+\end{methoddesc}
+
+\begin{methoddesc}[file]{xreadlines}{}
+  This method returns the same thing as \code{iter(f)}.
+  \versionadded{2.1}
+  \deprecated{2.3}{Use \samp{for \var{line} in \var{file}} instead.}
+\end{methoddesc}
+
+\begin{methoddesc}[file]{seek}{offset\optional{, whence}}
+  Set the file's current position, like \code{stdio}'s \cfunction{fseek()}.
+  The \var{whence} argument is optional and defaults to 
+  \code{os.SEEK_SET} or \code{0}
+  (absolute file positioning); other values are \code{os.SEEK_CUR} or \code{1}
+  (seek
+  relative to the current position) and \code{os.SEEK_END} or \code{2} 
+  (seek relative to the
+  file's end).  There is no return value.  Note that if the file is
+  opened for appending (mode \code{'a'} or \code{'a+'}), any
+  \method{seek()} operations will be undone at the next write.  If the
+  file is only opened for writing in append mode (mode \code{'a'}),
+  this method is essentially a no-op, but it remains useful for files
+  opened in append mode with reading enabled (mode \code{'a+'}).  If the
+  file is opened in text mode (without \code{'b'}), only offsets returned
+  by \method{tell()} are legal.  Use of other offsets causes undefined
+  behavior.
+
+  Note that not all file objects are seekable.
+\end{methoddesc}
+
+\begin{methoddesc}[file]{tell}{}
+  Return the file's current position, like \code{stdio}'s
+  \cfunction{ftell()}.
+
+  \note{On Windows, \method{tell()} can return illegal values (after an
+  \cfunction{fgets()}) when reading files with \UNIX{}-style line-endings.
+  Use binary mode (\code{'rb'}) to circumvent this problem.}
+\end{methoddesc}
+
+\begin{methoddesc}[file]{truncate}{\optional{size}}
+  Truncate the file's size.  If the optional \var{size} argument is
+  present, the file is truncated to (at most) that size.  The size
+  defaults to the current position.  The current file position is
+  not changed.  Note that if a specified size exceeds the file's
+  current size, the result is platform-dependent:  possibilities
+  include that the file may remain unchanged, increase to the specified
+  size as if zero-filled, or increase to the specified size with
+  undefined new content.
+  Availability:  Windows, many \UNIX{} variants.
+\end{methoddesc}
+
+\begin{methoddesc}[file]{write}{str}
+  Write a string to the file.  There is no return value.  Due to
+  buffering, the string may not actually show up in the file until
+  the \method{flush()} or \method{close()} method is called.
+\end{methoddesc}
+
+\begin{methoddesc}[file]{writelines}{sequence}
+  Write a sequence of strings to the file.  The sequence can be any
+  iterable object producing strings, typically a list of strings.
+  There is no return value.
+  (The name is intended to match \method{readlines()};
+  \method{writelines()} does not add line separators.)
+\end{methoddesc}
+
+
+Files support the iterator protocol.  Each iteration returns the same
+result as \code{\var{file}.readline()}, and iteration ends when the
+\method{readline()} method returns an empty string.
+
+
+File objects also offer a number of other interesting attributes.
+These are not required for file-like objects, but should be
+implemented if they make sense for the particular object.
+
+\begin{memberdesc}[file]{closed}
+bool indicating the current state of the file object.  This is a
+read-only attribute; the \method{close()} method changes the value.
+It may not be available on all file-like objects.
+\end{memberdesc}
+
+\begin{memberdesc}[file]{encoding}
+The encoding that this file uses. When Unicode strings are written
+to a file, they will be converted to byte strings using this encoding.
+In addition, when the file is connected to a terminal, the attribute
+gives the encoding that the terminal is likely to use (that 
+information might be incorrect if the user has misconfigured the 
+terminal). The attribute is read-only and may not be present on
+all file-like objects. It may also be \code{None}, in which case
+the file uses the system default encoding for converting Unicode
+strings.
+
+\versionadded{2.3}
+\end{memberdesc}
+
+\begin{memberdesc}[file]{mode}
+The I/O mode for the file.  If the file was created using the
+\function{open()} built-in function, this will be the value of the
+\var{mode} parameter.  This is a read-only attribute and may not be
+present on all file-like objects.
+\end{memberdesc}
+
+\begin{memberdesc}[file]{name}
+If the file object was created using \function{open()}, the name of
+the file.  Otherwise, some string that indicates the source of the
+file object, of the form \samp{<\mbox{\ldots}>}.  This is a read-only
+attribute and may not be present on all file-like objects.
+\end{memberdesc}
+
+\begin{memberdesc}[file]{newlines}
+If Python was built with the \longprogramopt{with-universal-newlines}
+option to \program{configure} (the default) this read-only attribute
+exists, and for files opened in
+universal newline read mode it keeps track of the types of newlines
+encountered while reading the file. The values it can take are
+\code{'\e r'}, \code{'\e n'}, \code{'\e r\e n'}, \code{None} (unknown,
+no newlines read yet) or a tuple containing all the newline
+types seen, to indicate that multiple
+newline conventions were encountered. For files not opened in universal
+newline read mode the value of this attribute will be \code{None}.
+\end{memberdesc}
+
+\begin{memberdesc}[file]{softspace}
+Boolean that indicates whether a space character needs to be printed
+before another value when using the \keyword{print} statement.
+Classes that are trying to simulate a file object should also have a
+writable \member{softspace} attribute, which should be initialized to
+zero.  This will be automatic for most classes implemented in Python
+(care may be needed for objects that override attribute access); types
+implemented in C will have to provide a writable
+\member{softspace} attribute.
+\note{This attribute is not used to control the
+\keyword{print} statement, but to allow the implementation of
+\keyword{print} to keep track of its internal state.}
+\end{memberdesc}
+
+
+\section{Context Manager Types \label{typecontextmanager}}
+
+\versionadded{2.5}
+\index{context manager}
+\index{context management protocol}
+\index{protocol!context management}
+
+Python's \keyword{with} statement supports the concept of a runtime
+context defined by a context manager.  This is implemented using
+two separate methods that allow user-defined classes to define
+a runtime context that is entered before the statement body is
+executed and exited when the statement ends.
+
+The \dfn{context management protocol} consists of a pair of
+methods that need to be provided for a context manager object to
+define a runtime context:
+
+\begin{methoddesc}[context manager]{__enter__}{}
+  Enter the runtime context and return either this object or another
+  object related to the runtime context. The value returned by this
+  method is bound to the identifier in the \keyword{as} clause of
+  \keyword{with} statements using this context manager.
+
+  An example of a context manager that returns itself is a file object.
+  File objects return themselves from __enter__() to allow
+  \function{open()} to be used as the context expression in a
+  \keyword{with} statement.
+
+  An example of a context manager that returns a related
+  object is the one returned by \code{decimal.Context.get_manager()}.
+  These managers set the active decimal context to a copy of the
+  original decimal context and then return the copy. This allows
+  changes to be made to the current decimal context in the body of
+  the \keyword{with} statement without affecting code outside
+  the \keyword{with} statement.
+\end{methoddesc}
+
+\begin{methoddesc}[context manager]{__exit__}{exc_type, exc_val, exc_tb}
+  Exit the runtime context and return a Boolean flag indicating if any
+  expection that occurred should be suppressed. If an exception
+  occurred while executing the body of the \keyword{with} statement, the
+  arguments contain the exception type, value and traceback information.
+  Otherwise, all three arguments are \var{None}.
+
+  Returning a true value from this method will cause the \keyword{with}
+  statement to suppress the exception and continue execution with the
+  statement immediately following the \keyword{with} statement. Otherwise
+  the exception continues propagating after this method has finished
+  executing. Exceptions that occur during execution of this method will
+  replace any exception that occurred in the body of the \keyword{with}
+  statement.
+
+  The exception passed in should never be reraised explicitly - instead,
+  this method should return a false value to indicate that the method
+  completed successfully and does not want to suppress the raised
+  exception. This allows context management code (such as
+  \code{contextlib.nested}) to easily detect whether or not an
+  \method{__exit__()} method has actually failed.
+\end{methoddesc}
+
+Python defines several context managers to support easy thread
+synchronisation, prompt closure of files or other objects, and
+simpler manipulation of the active decimal arithmetic
+context. The specific types are not treated specially beyond
+their implementation of the context management protocol.
+
+Python's generators and the \code{contextlib.contextfactory} decorator
+provide a convenient way to implement these protocols.  If a generator
+function is decorated with the \code{contextlib.contextfactory}
+decorator, it will return a context manager implementing the necessary
+\method{__enter__()} and \method{__exit__()} methods, rather than the
+iterator produced by an undecorated generator function.
+
+Note that there is no specific slot for any of these methods in the
+type structure for Python objects in the Python/C API. Extension
+types wanting to define these methods must provide them as a normal
+Python accessible method. Compared to the overhead of setting up the
+runtime context, the overhead of a single class dictionary lookup
+is negligible.
+
+
+\section{Other Built-in Types \label{typesother}}
+
+The interpreter supports several other kinds of objects.
+Most of these support only one or two operations.
+
+
+\subsection{Modules \label{typesmodules}}
+
+The only special operation on a module is attribute access:
+\code{\var{m}.\var{name}}, where \var{m} is a module and \var{name}
+accesses a name defined in \var{m}'s symbol table.  Module attributes
+can be assigned to.  (Note that the \keyword{import} statement is not,
+strictly speaking, an operation on a module object; \code{import
+\var{foo}} does not require a module object named \var{foo} to exist,
+rather it requires an (external) \emph{definition} for a module named
+\var{foo} somewhere.)
+
+A special member of every module is \member{__dict__}.
+This is the dictionary containing the module's symbol table.
+Modifying this dictionary will actually change the module's symbol
+table, but direct assignment to the \member{__dict__} attribute is not
+possible (you can write \code{\var{m}.__dict__['a'] = 1}, which
+defines \code{\var{m}.a} to be \code{1}, but you can't write
+\code{\var{m}.__dict__ = \{\}}).  Modifying \member{__dict__} directly
+is not recommended.
+
+Modules built into the interpreter are written like this:
+\code{<module 'sys' (built-in)>}.  If loaded from a file, they are
+written as \code{<module 'os' from
+'/usr/local/lib/python\shortversion/os.pyc'>}.
+
+
+\subsection{Classes and Class Instances \label{typesobjects}}
+\nodename{Classes and Instances}
+
+See chapters 3 and 7 of the \citetitle[../ref/ref.html]{Python
+Reference Manual} for these.
+
+
+\subsection{Functions \label{typesfunctions}}
+
+Function objects are created by function definitions.  The only
+operation on a function object is to call it:
+\code{\var{func}(\var{argument-list})}.
+
+There are really two flavors of function objects: built-in functions
+and user-defined functions.  Both support the same operation (to call
+the function), but the implementation is different, hence the
+different object types.
+
+See the \citetitle[../ref/ref.html]{Python Reference Manual} for more
+information.
+
+\subsection{Methods \label{typesmethods}}
+\obindex{method}
+
+Methods are functions that are called using the attribute notation.
+There are two flavors: built-in methods (such as \method{append()} on
+lists) and class instance methods.  Built-in methods are described
+with the types that support them.
+
+The implementation adds two special read-only attributes to class
+instance methods: \code{\var{m}.im_self} is the object on which the
+method operates, and \code{\var{m}.im_func} is the function
+implementing the method.  Calling \code{\var{m}(\var{arg-1},
+\var{arg-2}, \textrm{\ldots}, \var{arg-n})} is completely equivalent to
+calling \code{\var{m}.im_func(\var{m}.im_self, \var{arg-1},
+\var{arg-2}, \textrm{\ldots}, \var{arg-n})}.
+
+Class instance methods are either \emph{bound} or \emph{unbound},
+referring to whether the method was accessed through an instance or a
+class, respectively.  When a method is unbound, its \code{im_self}
+attribute will be \code{None} and if called, an explicit \code{self}
+object must be passed as the first argument.  In this case,
+\code{self} must be an instance of the unbound method's class (or a
+subclass of that class), otherwise a \exception{TypeError} is raised.
+
+Like function objects, methods objects support getting
+arbitrary attributes.  However, since method attributes are actually
+stored on the underlying function object (\code{meth.im_func}),
+setting method attributes on either bound or unbound methods is
+disallowed.  Attempting to set a method attribute results in a
+\exception{TypeError} being raised.  In order to set a method attribute,
+you need to explicitly set it on the underlying function object:
+
+\begin{verbatim}
+class C:
+    def method(self):
+        pass
+
+c = C()
+c.method.im_func.whoami = 'my name is c'
+\end{verbatim}
+
+See the \citetitle[../ref/ref.html]{Python Reference Manual} for more
+information.
+
+
+\subsection{Code Objects \label{bltin-code-objects}}
+\obindex{code}
+
+Code objects are used by the implementation to represent
+``pseudo-compiled'' executable Python code such as a function body.
+They differ from function objects because they don't contain a
+reference to their global execution environment.  Code objects are
+returned by the built-in \function{compile()} function and can be
+extracted from function objects through their \member{func_code}
+attribute.
+\bifuncindex{compile}
+\withsubitem{(function object attribute)}{\ttindex{func_code}}
+
+A code object can be executed or evaluated by passing it (instead of a
+source string) to the \keyword{exec} statement or the built-in
+\function{eval()} function.
+\stindex{exec}
+\bifuncindex{eval}
+
+See the \citetitle[../ref/ref.html]{Python Reference Manual} for more
+information.
+
+
+\subsection{Type Objects \label{bltin-type-objects}}
+
+Type objects represent the various object types.  An object's type is
+accessed by the built-in function \function{type()}.  There are no special
+operations on types.  The standard module \refmodule{types} defines names
+for all standard built-in types.
+\bifuncindex{type}
+\refstmodindex{types}
+
+Types are written like this: \code{<type 'int'>}.
+
+
+\subsection{The Null Object \label{bltin-null-object}}
+
+This object is returned by functions that don't explicitly return a
+value.  It supports no special operations.  There is exactly one null
+object, named \code{None} (a built-in name).
+
+It is written as \code{None}.
+
+
+\subsection{The Ellipsis Object \label{bltin-ellipsis-object}}
+
+This object is used by extended slice notation (see the
+\citetitle[../ref/ref.html]{Python Reference Manual}).  It supports no
+special operations.  There is exactly one ellipsis object, named
+\constant{Ellipsis} (a built-in name).
+
+It is written as \code{Ellipsis}.
+
+\subsection{Boolean Values}
+
+Boolean values are the two constant objects \code{False} and
+\code{True}.  They are used to represent truth values (although other
+values can also be considered false or true).  In numeric contexts
+(for example when used as the argument to an arithmetic operator),
+they behave like the integers 0 and 1, respectively.  The built-in
+function \function{bool()} can be used to cast any value to a Boolean,
+if the value can be interpreted as a truth value (see section Truth
+Value Testing above).
+
+They are written as \code{False} and \code{True}, respectively.
+\index{False}
+\index{True}
+\indexii{Boolean}{values}
+
+
+\subsection{Internal Objects \label{typesinternal}}
+
+See the \citetitle[../ref/ref.html]{Python Reference Manual} for this
+information.  It describes stack frame objects, traceback objects, and
+slice objects.
+
+
+\section{Special Attributes \label{specialattrs}}
+
+The implementation adds a few special read-only attributes to several
+object types, where they are relevant.  Some of these are not reported
+by the \function{dir()} built-in function.
+
+\begin{memberdesc}[object]{__dict__}
+A dictionary or other mapping object used to store an
+object's (writable) attributes.
+\end{memberdesc}
+
+\begin{memberdesc}[object]{__methods__}
+\deprecated{2.2}{Use the built-in function \function{dir()} to get a
+list of an object's attributes.  This attribute is no longer available.}
+\end{memberdesc}
+
+\begin{memberdesc}[object]{__members__}
+\deprecated{2.2}{Use the built-in function \function{dir()} to get a
+list of an object's attributes.  This attribute is no longer available.}
+\end{memberdesc}
+
+\begin{memberdesc}[instance]{__class__}
+The class to which a class instance belongs.
+\end{memberdesc}
+
+\begin{memberdesc}[class]{__bases__}
+The tuple of base classes of a class object.  If there are no base
+classes, this will be an empty tuple.
+\end{memberdesc}
+
+\begin{memberdesc}[class]{__name__}
+The name of the class or type.
+\end{memberdesc}

Added: vendor/Python/current/Doc/lib/libstdwin.tex
===================================================================
--- vendor/Python/current/Doc/lib/libstdwin.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libstdwin.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,832 @@
+\chapter{Standard Windowing Interface}
+
+The modules in this chapter are available only on those systems where
+the STDWIN library is available.  STDWIN runs on \UNIX{} under X11 and
+on the Macintosh.  See CWI report CS-R8817.
+
+\warning{Using STDWIN is not recommended for new
+applications.  It has never been ported to Microsoft Windows or
+Windows NT, and for X11 or the Macintosh it lacks important
+functionality --- in particular, it has no tools for the construction
+of dialogs.  For most platforms, alternative, native solutions exist
+(though none are currently documented in this manual): Tkinter for
+\UNIX{} under X11, native Xt with Motif or Athena widgets for \UNIX{}
+under X11, Win32 for Windows and Windows NT, and a collection of
+native toolkit interfaces for the Macintosh.}
+
+
+\section{\module{stdwin} ---
+         Platform-independent Graphical User Interface System}
+
+\declaremodule{builtin}{stdwin}
+\modulesynopsis{Older graphical user interface system for X11 and Macintosh.}
+
+
+This module defines several new object types and functions that
+provide access to the functionality of STDWIN.
+
+On \UNIX{} running X11, it can only be used if the \envvar{DISPLAY}
+environment variable is set or an explicit
+\programopt{-display} \var{displayname} argument is passed to the
+Python interpreter.
+
+Functions have names that usually resemble their C STDWIN counterparts
+with the initial `w' dropped.  Points are represented by pairs of
+integers; rectangles by pairs of points.  For a complete description
+of STDWIN please refer to the documentation of STDWIN for C
+programmers (aforementioned CWI report).
+
+\subsection{Functions Defined in Module \module{stdwin}}
+\nodename{STDWIN Functions}
+
+The following functions are defined in the \module{stdwin} module:
+
+\begin{funcdesc}{open}{title}
+Open a new window whose initial title is given by the string argument.
+Return a window object; window object methods are described
+below.\footnote{
+	The Python version of STDWIN does not support draw procedures;
+	all drawing requests are reported as draw events.}
+\end{funcdesc}
+
+\begin{funcdesc}{getevent}{}
+Wait for and return the next event.
+An event is returned as a triple: the first element is the event
+type, a small integer; the second element is the window object to which
+the event applies, or
+\code{None}
+if it applies to no window in particular;
+the third element is type-dependent.
+Names for event types and command codes are defined in the standard
+module \refmodule{stdwinevents}.
+\end{funcdesc}
+
+\begin{funcdesc}{pollevent}{}
+Return the next event, if one is immediately available.
+If no event is available, return \code{()}.
+\end{funcdesc}
+
+\begin{funcdesc}{getactive}{}
+Return the window that is currently active, or \code{None} if no
+window is currently active.  (This can be emulated by monitoring
+WE_ACTIVATE and WE_DEACTIVATE events.)
+\end{funcdesc}
+
+\begin{funcdesc}{listfontnames}{pattern}
+Return the list of font names in the system that match the pattern (a
+string).  The pattern should normally be \code{'*'}; returns all
+available fonts.  If the underlying window system is X11, other
+patterns follow the standard X11 font selection syntax (as used e.g.
+in resource definitions), i.e. the wildcard character \code{'*'}
+matches any sequence of characters (including none) and \code{'?'}
+matches any single character.
+On the Macintosh this function currently returns an empty list.
+\end{funcdesc}
+
+\begin{funcdesc}{setdefscrollbars}{hflag, vflag}
+Set the flags controlling whether subsequently opened windows will
+have horizontal and/or vertical scroll bars.
+\end{funcdesc}
+
+\begin{funcdesc}{setdefwinpos}{h, v}
+Set the default window position for windows opened subsequently.
+\end{funcdesc}
+
+\begin{funcdesc}{setdefwinsize}{width, height}
+Set the default window size for windows opened subsequently.
+\end{funcdesc}
+
+\begin{funcdesc}{getdefscrollbars}{}
+Return the flags controlling whether subsequently opened windows will
+have horizontal and/or vertical scroll bars.
+\end{funcdesc}
+
+\begin{funcdesc}{getdefwinpos}{}
+Return the default window position for windows opened subsequently.
+\end{funcdesc}
+
+\begin{funcdesc}{getdefwinsize}{}
+Return the default window size for windows opened subsequently.
+\end{funcdesc}
+
+\begin{funcdesc}{getscrsize}{}
+Return the screen size in pixels.
+\end{funcdesc}
+
+\begin{funcdesc}{getscrmm}{}
+Return the screen size in millimetres.
+\end{funcdesc}
+
+\begin{funcdesc}{fetchcolor}{colorname}
+Return the pixel value corresponding to the given color name.
+Return the default foreground color for unknown color names.
+Hint: the following code tests whether you are on a machine that
+supports more than two colors:
+\begin{verbatim}
+if stdwin.fetchcolor('black') <> \
+          stdwin.fetchcolor('red') <> \
+          stdwin.fetchcolor('white'):
+    print 'color machine'
+else:
+    print 'monochrome machine'
+\end{verbatim}
+\end{funcdesc}
+
+\begin{funcdesc}{setfgcolor}{pixel}
+Set the default foreground color.
+This will become the default foreground color of windows opened
+subsequently, including dialogs.
+\end{funcdesc}
+
+\begin{funcdesc}{setbgcolor}{pixel}
+Set the default background color.
+This will become the default background color of windows opened
+subsequently, including dialogs.
+\end{funcdesc}
+
+\begin{funcdesc}{getfgcolor}{}
+Return the pixel value of the current default foreground color.
+\end{funcdesc}
+
+\begin{funcdesc}{getbgcolor}{}
+Return the pixel value of the current default background color.
+\end{funcdesc}
+
+\begin{funcdesc}{setfont}{fontname}
+Set the current default font.
+This will become the default font for windows opened subsequently,
+and is also used by the text measuring functions \function{textwidth()},
+\function{textbreak()}, \function{lineheight()} and
+\function{baseline()} below.  This accepts two more optional
+parameters, size and style:  Size is the font size (in `points').
+Style is a single character specifying the style, as follows:
+\code{'b'} = bold,
+\code{'i'} = italic,
+\code{'o'} = bold + italic,
+\code{'u'} = underline;
+default style is roman.
+Size and style are ignored under X11 but used on the Macintosh.
+(Sorry for all this complexity --- a more uniform interface is being designed.)
+\end{funcdesc}
+
+\begin{funcdesc}{menucreate}{title}
+Create a menu object referring to a global menu (a menu that appears in
+all windows).
+Methods of menu objects are described below.
+Note: normally, menus are created locally; see the window method
+\method{menucreate()} below.
+\warning{The menu only appears in a window as long as the object
+returned by this call exists.}
+\end{funcdesc}
+
+\begin{funcdesc}{newbitmap}{width, height}
+Create a new bitmap object of the given dimensions.
+Methods of bitmap objects are described below.
+Not available on the Macintosh.
+\end{funcdesc}
+
+\begin{funcdesc}{fleep}{}
+Cause a beep or bell (or perhaps a `visual bell' or flash, hence the
+name).
+\end{funcdesc}
+
+\begin{funcdesc}{message}{string}
+Display a dialog box containing the string.
+The user must click OK before the function returns.
+\end{funcdesc}
+
+\begin{funcdesc}{askync}{prompt, default}
+Display a dialog that prompts the user to answer a question with yes or
+no.  Return 0 for no, 1 for yes.  If the user hits the Return key, the
+default (which must be 0 or 1) is returned.  If the user cancels the
+dialog, \exception{KeyboardInterrupt} is raised.
+\end{funcdesc}
+
+\begin{funcdesc}{askstr}{prompt, default}
+Display a dialog that prompts the user for a string.
+If the user hits the Return key, the default string is returned.
+If the user cancels the dialog, \exception{KeyboardInterrupt} is
+raised.
+\end{funcdesc}
+
+\begin{funcdesc}{askfile}{prompt, default, new}
+Ask the user to specify a filename.  If \var{new} is zero it must be
+an existing file; otherwise, it must be a new file.  If the user
+cancels the dialog, \exception{KeyboardInterrupt} is raised.
+\end{funcdesc}
+
+\begin{funcdesc}{setcutbuffer}{i, string}
+Store the string in the system's cut buffer number \var{i}, where it
+can be found (for pasting) by other applications.  On X11, there are 8
+cut buffers (numbered 0..7).  Cut buffer number 0 is the `clipboard'
+on the Macintosh.
+\end{funcdesc}
+
+\begin{funcdesc}{getcutbuffer}{i}
+Return the contents of the system's cut buffer number \var{i}.
+\end{funcdesc}
+
+\begin{funcdesc}{rotatecutbuffers}{n}
+On X11, rotate the 8 cut buffers by \var{n}.  Ignored on the
+Macintosh.
+\end{funcdesc}
+
+\begin{funcdesc}{getselection}{i}
+Return X11 selection number \var{i.}  Selections are not cut buffers.
+Selection numbers are defined in module \refmodule{stdwinevents}.
+Selection \constant{WS_PRIMARY} is the \dfn{primary} selection (used
+by \program{xterm}, for instance); selection \constant{WS_SECONDARY}
+is the \dfn{secondary} selection; selection \constant{WS_CLIPBOARD} is
+the \dfn{clipboard} selection (used by \program{xclipboard}).  On the
+Macintosh, this always returns an empty string.
+\end{funcdesc}
+
+\begin{funcdesc}{resetselection}{i}
+Reset selection number \var{i}, if this process owns it.  (See window
+method \method{setselection()}).
+\end{funcdesc}
+
+\begin{funcdesc}{baseline}{}
+Return the baseline of the current font (defined by STDWIN as the
+vertical distance between the baseline and the top of the
+characters).
+\end{funcdesc}
+
+\begin{funcdesc}{lineheight}{}
+Return the total line height of the current font.
+\end{funcdesc}
+
+\begin{funcdesc}{textbreak}{str, width}
+Return the number of characters of the string that fit into a space of
+\var{width}
+bits wide when drawn in the current font.
+\end{funcdesc}
+
+\begin{funcdesc}{textwidth}{str}
+Return the width in bits of the string when drawn in the current font.
+\end{funcdesc}
+
+\begin{funcdesc}{connectionnumber}{}
+\funcline{fileno}{}
+(X11 under \UNIX{} only) Return the ``connection number'' used by the
+underlying X11 implementation.  (This is normally the file number of
+the socket.)  Both functions return the same value;
+\method{connectionnumber()} is named after the corresponding function in
+X11 and STDWIN, while \method{fileno()} makes it possible to use the
+\module{stdwin} module as a ``file'' object parameter to
+\function{select.select()}.  Note that if \constant{select()} implies that
+input is possible on \module{stdwin}, this does not guarantee that an
+event is ready --- it may be some internal communication going on
+between the X server and the client library.  Thus, you should call
+\function{stdwin.pollevent()} until it returns \code{None} to check for
+events if you don't want your program to block.  Because of internal
+buffering in X11, it is also possible that \function{stdwin.pollevent()}
+returns an event while \function{select()} does not find \module{stdwin} to
+be ready, so you should read any pending events with
+\function{stdwin.pollevent()} until it returns \code{None} before entering
+a blocking \function{select()} call.
+\withsubitem{(in module select)}{\ttindex{select()}}
+\end{funcdesc}
+
+\subsection{Window Objects}
+\nodename{STDWIN Window Objects}
+
+Window objects are created by \function{stdwin.open()}.  They are closed
+by their \method{close()} method or when they are garbage-collected.
+Window objects have the following methods:
+
+\begin{methoddesc}[window]{begindrawing}{}
+Return a drawing object, whose methods (described below) allow drawing
+in the window.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{change}{rect}
+Invalidate the given rectangle; this may cause a draw event.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{gettitle}{}
+Returns the window's title string.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{getdocsize}{}
+\begin{sloppypar}
+Return a pair of integers giving the size of the document as set by
+\method{setdocsize()}.
+\end{sloppypar}
+\end{methoddesc}
+
+\begin{methoddesc}[window]{getorigin}{}
+Return a pair of integers giving the origin of the window with respect
+to the document.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{gettitle}{}
+Return the window's title string.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{getwinsize}{}
+Return a pair of integers giving the size of the window.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{getwinpos}{}
+Return a pair of integers giving the position of the window's upper
+left corner (relative to the upper left corner of the screen).
+\end{methoddesc}
+
+\begin{methoddesc}[window]{menucreate}{title}
+Create a menu object referring to a local menu (a menu that appears
+only in this window).
+Methods of menu objects are described below.
+\warning{The menu only appears as long as the object
+returned by this call exists.}
+\end{methoddesc}
+
+\begin{methoddesc}[window]{scroll}{rect, point}
+Scroll the given rectangle by the vector given by the point.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{setdocsize}{point}
+Set the size of the drawing document.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{setorigin}{point}
+Move the origin of the window (its upper left corner)
+to the given point in the document.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{setselection}{i, str}
+Attempt to set X11 selection number \var{i} to the string \var{str}.
+(See \module{stdwin} function \function{getselection()} for the
+meaning of \var{i}.)  Return true if it succeeds.
+If  succeeds, the window ``owns'' the selection until
+(a) another application takes ownership of the selection; or
+(b) the window is deleted; or
+(c) the application clears ownership by calling
+\function{stdwin.resetselection(\var{i})}.  When another application
+takes ownership of the selection, a \constant{WE_LOST_SEL} event is
+received for no particular window and with the selection number as
+detail.  Ignored on the Macintosh.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{settimer}{dsecs}
+Schedule a timer event for the window in \code{\var{dsecs}/10}
+seconds.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{settitle}{title}
+Set the window's title string.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{setwincursor}{name}
+\begin{sloppypar}
+Set the window cursor to a cursor of the given name.  It raises
+\exception{RuntimeError} if no cursor of the given name exists.
+Suitable names include
+\code{'ibeam'},
+\code{'arrow'},
+\code{'cross'},
+\code{'watch'}
+and
+\code{'plus'}.
+On X11, there are many more (see \code{<X11/cursorfont.h>}).
+\end{sloppypar}
+\end{methoddesc}
+
+\begin{methoddesc}[window]{setwinpos}{h, v}
+Set the position of the window's upper left corner (relative to
+the upper left corner of the screen).
+\end{methoddesc}
+
+\begin{methoddesc}[window]{setwinsize}{width, height}
+Set the window's size.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{show}{rect}
+Try to ensure that the given rectangle of the document is visible in
+the window.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{textcreate}{rect}
+Create a text-edit object in the document at the given rectangle.
+Methods of text-edit objects are described below.
+\end{methoddesc}
+
+\begin{methoddesc}[window]{setactive}{}
+Attempt to make this window the active window.  If successful, this
+will generate a WE_ACTIVATE event (and a WE_DEACTIVATE event in case
+another window in this application became inactive).
+\end{methoddesc}
+
+\begin{methoddesc}[window]{close}{}
+Discard the window object.  It should not be used again.
+\end{methoddesc}
+
+\subsection{Drawing Objects}
+
+Drawing objects are created exclusively by the window method
+\method{begindrawing()}.  Only one drawing object can exist at any
+given time; the drawing object must be deleted to finish drawing.  No
+drawing object may exist when \function{stdwin.getevent()} is called.
+Drawing objects have the following methods:
+
+\begin{methoddesc}[drawing]{box}{rect}
+Draw a box just inside a rectangle.
+\end{methoddesc}
+
+\begin{methoddesc}[drawing]{circle}{center, radius}
+Draw a circle with given center point and radius.
+\end{methoddesc}
+
+\begin{methoddesc}[drawing]{elarc}{center, (rh, rv), (a1, a2)}
+Draw an elliptical arc with given center point.
+\code{(\var{rh}, \var{rv})}
+gives the half sizes of the horizontal and vertical radii.
+\code{(\var{a1}, \var{a2})}
+gives the angles (in degrees) of the begin and end points.
+0 degrees is at 3 o'clock, 90 degrees is at 12 o'clock.
+\end{methoddesc}
+
+\begin{methoddesc}[drawing]{erase}{rect}
+Erase a rectangle.
+\end{methoddesc}
+
+\begin{methoddesc}[drawing]{fillcircle}{center, radius}
+Draw a filled circle with given center point and radius.
+\end{methoddesc}
+
+\begin{methoddesc}[drawing]{fillelarc}{center, (rh, rv), (a1, a2)}
+Draw a filled elliptical arc; arguments as for \method{elarc()}.
+\end{methoddesc}
+
+\begin{methoddesc}[drawing]{fillpoly}{points}
+Draw a filled polygon given by a list (or tuple) of points.
+\end{methoddesc}
+
+\begin{methoddesc}[drawing]{invert}{rect}
+Invert a rectangle.
+\end{methoddesc}
+
+\begin{methoddesc}[drawing]{line}{p1, p2}
+Draw a line from point
+\var{p1}
+to
+\var{p2}.
+\end{methoddesc}
+
+\begin{methoddesc}[drawing]{paint}{rect}
+Fill a rectangle.
+\end{methoddesc}
+
+\begin{methoddesc}[drawing]{poly}{points}
+Draw the lines connecting the given list (or tuple) of points.
+\end{methoddesc}
+
+\begin{methoddesc}[drawing]{shade}{rect, percent}
+Fill a rectangle with a shading pattern that is about
+\var{percent}
+percent filled.
+\end{methoddesc}
+
+\begin{methoddesc}[drawing]{text}{p, str}
+Draw a string starting at point p (the point specifies the
+top left coordinate of the string).
+\end{methoddesc}
+
+\begin{methoddesc}[drawing]{xorcircle}{center, radius}
+\funcline{xorelarc}{center, (rh, rv), (a1, a2)}
+\funcline{xorline}{p1, p2}
+\funcline{xorpoly}{points}
+Draw a circle, an elliptical arc, a line or a polygon, respectively,
+in XOR mode.
+\end{methoddesc}
+
+\begin{methoddesc}[drawing]{setfgcolor}{}
+\funcline{setbgcolor}{}
+\funcline{getfgcolor}{}
+\funcline{getbgcolor}{}
+These functions are similar to the corresponding functions described
+above for the \module{stdwin}
+module, but affect or return the colors currently used for drawing
+instead of the global default colors.
+When a drawing object is created, its colors are set to the window's
+default colors, which are in turn initialized from the global default
+colors when the window is created.
+\end{methoddesc}
+
+\begin{methoddesc}[drawing]{setfont}{}
+\funcline{baseline}{}
+\funcline{lineheight}{}
+\funcline{textbreak}{}
+\funcline{textwidth}{}
+These functions are similar to the corresponding functions described
+above for the \module{stdwin}
+module, but affect or use the current drawing font instead of
+the global default font.
+When a drawing object is created, its font is set to the window's
+default font, which is in turn initialized from the global default
+font when the window is created.
+\end{methoddesc}
+
+\begin{methoddesc}[drawing]{bitmap}{point, bitmap, mask}
+Draw the \var{bitmap} with its top left corner at \var{point}.
+If the optional \var{mask} argument is present, it should be either
+the same object as \var{bitmap}, to draw only those bits that are set
+in the bitmap, in the foreground color, or \code{None}, to draw all
+bits (ones are drawn in the foreground color, zeros in the background
+color).
+Not available on the Macintosh.
+\end{methoddesc}
+
+\begin{methoddesc}[drawing]{cliprect}{rect}
+Set the ``clipping region'' to a rectangle.
+The clipping region limits the effect of all drawing operations, until
+it is changed again or until the drawing object is closed.  When a
+drawing object is created the clipping region is set to the entire
+window.  When an object to be drawn falls partly outside the clipping
+region, the set of pixels drawn is the intersection of the clipping
+region and the set of pixels that would be drawn by the same operation
+in the absence of a clipping region.
+\end{methoddesc}
+
+\begin{methoddesc}[drawing]{noclip}{}
+Reset the clipping region to the entire window.
+\end{methoddesc}
+
+\begin{methoddesc}[drawing]{close}{}
+\funcline{enddrawing}{}
+Discard the drawing object.  It should not be used again.
+\end{methoddesc}
+
+\subsection{Menu Objects}
+
+A menu object represents a menu.
+The menu is destroyed when the menu object is deleted.
+The following methods are defined:
+
+
+\begin{methoddesc}[menu]{additem}{text, shortcut}
+Add a menu item with given text.
+The shortcut must be a string of length 1, or omitted (to specify no
+shortcut).
+\end{methoddesc}
+
+\begin{methoddesc}[menu]{setitem}{i, text}
+Set the text of item number \var{i}.
+\end{methoddesc}
+
+\begin{methoddesc}[menu]{enable}{i, flag}
+Enable or disables item \var{i}.
+\end{methoddesc}
+
+\begin{methoddesc}[menu]{check}{i, flag}
+Set or clear the \dfn{check mark} for item \var{i}.
+\end{methoddesc}
+
+\begin{methoddesc}[menu]{close}{}
+Discard the menu object.  It should not be used again.
+\end{methoddesc}
+
+\subsection{Bitmap Objects}
+
+A bitmap represents a rectangular array of bits.
+The top left bit has coordinate (0, 0).
+A bitmap can be drawn with the \method{bitmap()} method of a drawing object.
+Bitmaps are currently not available on the Macintosh.
+
+The following methods are defined:
+
+
+\begin{methoddesc}[bitmap]{getsize}{}
+Return a tuple representing the width and height of the bitmap.
+(This returns the values that have been passed to the
+\function{newbitmap()} function.)
+\end{methoddesc}
+
+\begin{methoddesc}[bitmap]{setbit}{point, bit}
+Set the value of the bit indicated by \var{point} to \var{bit}.
+\end{methoddesc}
+
+\begin{methoddesc}[bitmap]{getbit}{point}
+Return the value of the bit indicated by \var{point}.
+\end{methoddesc}
+
+\begin{methoddesc}[bitmap]{close}{}
+Discard the bitmap object.  It should not be used again.
+\end{methoddesc}
+
+\subsection{Text-edit Objects}
+
+A text-edit object represents a text-edit block.
+For semantics, see the STDWIN documentation for \C{} programmers.
+The following methods exist:
+
+
+\begin{methoddesc}[text-edit]{arrow}{code}
+Pass an arrow event to the text-edit block.
+The \var{code} must be one of \constant{WC_LEFT}, \constant{WC_RIGHT}, 
+\constant{WC_UP} or \constant{WC_DOWN} (see module
+\refmodule{stdwinevents}).
+\end{methoddesc}
+
+\begin{methoddesc}[text-edit]{draw}{rect}
+Pass a draw event to the text-edit block.
+The rectangle specifies the redraw area.
+\end{methoddesc}
+
+\begin{methoddesc}[text-edit]{event}{type, window, detail}
+Pass an event gotten from
+\function{stdwin.getevent()}
+to the text-edit block.
+Return true if the event was handled.
+\end{methoddesc}
+
+\begin{methoddesc}[text-edit]{getfocus}{}
+Return 2 integers representing the start and end positions of the
+focus, usable as slice indices on the string returned by
+\method{gettext()}.
+\end{methoddesc}
+
+\begin{methoddesc}[text-edit]{getfocustext}{}
+Return the text in the focus.
+\end{methoddesc}
+
+\begin{methoddesc}[text-edit]{getrect}{}
+Return a rectangle giving the actual position of the text-edit block.
+(The bottom coordinate may differ from the initial position because
+the block automatically shrinks or grows to fit.)
+\end{methoddesc}
+
+\begin{methoddesc}[text-edit]{gettext}{}
+Return the entire text buffer.
+\end{methoddesc}
+
+\begin{methoddesc}[text-edit]{move}{rect}
+Specify a new position for the text-edit block in the document.
+\end{methoddesc}
+
+\begin{methoddesc}[text-edit]{replace}{str}
+Replace the text in the focus by the given string.
+The new focus is an insert point at the end of the string.
+\end{methoddesc}
+
+\begin{methoddesc}[text-edit]{setfocus}{i, j}
+Specify the new focus.
+Out-of-bounds values are silently clipped.
+\end{methoddesc}
+
+\begin{methoddesc}[text-edit]{settext}{str}
+Replace the entire text buffer by the given string and set the focus
+to \code{(0, 0)}.
+\end{methoddesc}
+
+\begin{methoddesc}[text-edit]{setview}{rect}
+Set the view rectangle to \var{rect}.  If \var{rect} is \code{None},
+viewing mode is reset.  In viewing mode, all output from the text-edit
+object is clipped to the viewing rectangle.  This may be useful to
+implement your own scrolling text subwindow.
+\end{methoddesc}
+
+\begin{methoddesc}[text-edit]{close}{}
+Discard the text-edit object.  It should not be used again.
+\end{methoddesc}
+
+\subsection{Example}
+\nodename{STDWIN Example}
+
+Here is a minimal example of using STDWIN in Python.
+It creates a window and draws the string ``Hello world'' in the top
+left corner of the window.
+The window will be correctly redrawn when covered and re-exposed.
+The program quits when the close icon or menu item is requested.
+
+\begin{verbatim}
+import stdwin
+from stdwinevents import *
+
+def main():
+    mywin = stdwin.open('Hello')
+    #
+    while 1:
+        (type, win, detail) = stdwin.getevent()
+        if type == WE_DRAW:
+            draw = win.begindrawing()
+            draw.text((0, 0), 'Hello, world')
+            del draw
+        elif type == WE_CLOSE:
+            break
+
+main()
+\end{verbatim}
+
+
+\section{\module{stdwinevents} ---
+         Constants for use with \module{stdwin}}
+
+\declaremodule{standard}{stdwinevents}
+\modulesynopsis{Constant definitions for use with \module{stdwin}}
+
+
+This module defines constants used by STDWIN for event types
+(\constant{WE_ACTIVATE} etc.), command codes (\constant{WC_LEFT} etc.)
+and selection types (\constant{WS_PRIMARY} etc.).
+Read the file for details.
+Suggested usage is
+
+\begin{verbatim}
+>>> from stdwinevents import *
+>>> 
+\end{verbatim}
+
+
+\section{\module{rect} ---
+         Functions for use with \module{stdwin}}
+
+\declaremodule{standard}{rect}
+\modulesynopsis{Geometry-related utility function for use with
+                \module{stdwin}.}
+
+
+This module contains useful operations on rectangles.
+A rectangle is defined as in module \refmodule{stdwin}:
+a pair of points, where a point is a pair of integers.
+For example, the rectangle
+
+\begin{verbatim}
+(10, 20), (90, 80)
+\end{verbatim}
+
+is a rectangle whose left, top, right and bottom edges are 10, 20, 90
+and 80, respectively.  Note that the positive vertical axis points
+down (as in \refmodule{stdwin}).
+
+The module defines the following objects:
+
+\begin{excdesc}{error}
+The exception raised by functions in this module when they detect an
+error.  The exception argument is a string describing the problem in
+more detail.
+\end{excdesc}
+
+\begin{datadesc}{empty}
+The rectangle returned when some operations return an empty result.
+This makes it possible to quickly check whether a result is empty:
+
+\begin{verbatim}
+>>> import rect
+>>> r1 = (10, 20), (90, 80)
+>>> r2 = (0, 0), (10, 20)
+>>> r3 = rect.intersect([r1, r2])
+>>> if r3 is rect.empty: print 'Empty intersection'
+Empty intersection
+>>> 
+\end{verbatim}
+\end{datadesc}
+
+\begin{funcdesc}{is_empty}{r}
+Returns true if the given rectangle is empty.
+A rectangle
+\code{(\var{left}, \var{top}), (\var{right}, \var{bottom})}
+is empty if
+\begin{math}\var{left} \geq \var{right}\end{math} or
+\begin{math}\var{top} \geq \var{bottom}\end{math}.
+\end{funcdesc}
+
+\begin{funcdesc}{intersect}{list}
+Returns the intersection of all rectangles in the list argument.
+It may also be called with a tuple argument.  Raises
+\exception{rect.error} if the list is empty.  Returns
+\constant{rect.empty} if the intersection of the rectangles is empty.
+\end{funcdesc}
+
+\begin{funcdesc}{union}{list}
+Returns the smallest rectangle that contains all non-empty rectangles in
+the list argument.  It may also be called with a tuple argument or
+with two or more rectangles as arguments.  Returns
+\constant{rect.empty} if the list is empty or all its rectangles are
+empty.
+\end{funcdesc}
+
+\begin{funcdesc}{pointinrect}{point, rect}
+Returns true if the point is inside the rectangle.  By definition, a
+point \code{(\var{h}, \var{v})} is inside a rectangle
+\code{(\var{left}, \var{top}), (\var{right}, \var{bottom})} if
+\begin{math}\var{left} \leq \var{h} < \var{right}\end{math} and
+\begin{math}\var{top} \leq \var{v} < \var{bottom}\end{math}.
+\end{funcdesc}
+
+\begin{funcdesc}{inset}{rect, (dh, dv)}
+Returns a rectangle that lies inside the \var{rect} argument by
+\var{dh} pixels horizontally and \var{dv} pixels vertically.  If
+\var{dh} or \var{dv} is negative, the result lies outside \var{rect}.
+\end{funcdesc}
+
+\begin{funcdesc}{rect2geom}{rect}
+Converts a rectangle to geometry representation:
+\code{(\var{left}, \var{top}), (\var{width}, \var{height})}.
+\end{funcdesc}
+
+\begin{funcdesc}{geom2rect}{geom}
+Converts a rectangle given in geometry representation back to the
+standard rectangle representation
+\code{(\var{left}, \var{top}), (\var{right}, \var{bottom})}.
+\end{funcdesc}

Added: vendor/Python/current/Doc/lib/libstring.tex
===================================================================
--- vendor/Python/current/Doc/lib/libstring.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libstring.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,451 @@
+\section{\module{string} ---
+         Common string operations}
+
+\declaremodule{standard}{string}
+\modulesynopsis{Common string operations.}
+
+The \module{string} module contains a number of useful constants and classes,
+as well as some deprecated legacy functions that are also available as methods
+on strings.  See the module \refmodule{re}\refstmodindex{re} for string
+functions based on regular expressions.
+
+\subsection{String constants}
+
+The constants defined in this module are:
+
+\begin{datadesc}{ascii_letters}
+  The concatenation of the \constant{ascii_lowercase} and
+  \constant{ascii_uppercase} constants described below.  This value is
+  not locale-dependent.
+\end{datadesc}
+
+\begin{datadesc}{ascii_lowercase}
+  The lowercase letters \code{'abcdefghijklmnopqrstuvwxyz'}.  This
+  value is not locale-dependent and will not change.
+\end{datadesc}
+
+\begin{datadesc}{ascii_uppercase}
+  The uppercase letters \code{'ABCDEFGHIJKLMNOPQRSTUVWXYZ'}.  This
+  value is not locale-dependent and will not change.
+\end{datadesc}
+
+\begin{datadesc}{digits}
+  The string \code{'0123456789'}.
+\end{datadesc}
+
+\begin{datadesc}{hexdigits}
+  The string \code{'0123456789abcdefABCDEF'}.
+\end{datadesc}
+
+\begin{datadesc}{letters}
+  The concatenation of the strings \constant{lowercase} and
+  \constant{uppercase} described below.  The specific value is
+  locale-dependent, and will be updated when
+  \function{locale.setlocale()} is called.
+\end{datadesc}
+
+\begin{datadesc}{lowercase}
+  A string containing all the characters that are considered lowercase
+  letters.  On most systems this is the string
+  \code{'abcdefghijklmnopqrstuvwxyz'}.  Do not change its definition ---
+  the effect on the routines \function{upper()} and
+  \function{swapcase()} is undefined.  The specific value is
+  locale-dependent, and will be updated when
+  \function{locale.setlocale()} is called.
+\end{datadesc}
+
+\begin{datadesc}{octdigits}
+  The string \code{'01234567'}.
+\end{datadesc}
+
+\begin{datadesc}{punctuation}
+  String of \ASCII{} characters which are considered punctuation
+  characters in the \samp{C} locale.
+\end{datadesc}
+
+\begin{datadesc}{printable}
+  String of characters which are considered printable.  This is a
+  combination of \constant{digits}, \constant{letters},
+  \constant{punctuation}, and \constant{whitespace}.
+\end{datadesc}
+
+\begin{datadesc}{uppercase}
+  A string containing all the characters that are considered uppercase
+  letters.  On most systems this is the string
+  \code{'ABCDEFGHIJKLMNOPQRSTUVWXYZ'}.  Do not change its definition ---
+  the effect on the routines \function{lower()} and
+  \function{swapcase()} is undefined.  The specific value is
+  locale-dependent, and will be updated when
+  \function{locale.setlocale()} is called.
+\end{datadesc}
+
+\begin{datadesc}{whitespace}
+  A string containing all characters that are considered whitespace.
+  On most systems this includes the characters space, tab, linefeed,
+  return, formfeed, and vertical tab.  Do not change its definition ---
+  the effect on the routines \function{strip()} and \function{split()}
+  is undefined.
+\end{datadesc}
+
+\subsection{Template strings}
+
+Templates provide simpler string substitutions as described in \pep{292}.
+Instead of the normal \samp{\%}-based substitutions, Templates support
+\samp{\$}-based substitutions, using the following rules:
+
+\begin{itemize}
+\item \samp{\$\$} is an escape; it is replaced with a single \samp{\$}.
+
+\item \samp{\$identifier} names a substitution placeholder matching a mapping
+       key of "identifier".  By default, "identifier" must spell a Python
+       identifier.  The first non-identifier character after the \samp{\$}
+       character terminates this placeholder specification.
+
+\item \samp{\$\{identifier\}} is equivalent to \samp{\$identifier}.  It is
+      required when valid identifier characters follow the placeholder but are
+      not part of the placeholder, such as "\$\{noun\}ification".
+\end{itemize}
+
+Any other appearance of \samp{\$} in the string will result in a
+\exception{ValueError} being raised.
+
+\versionadded{2.4}
+
+The \module{string} module provides a \class{Template} class that implements
+these rules.  The methods of \class{Template} are:
+
+\begin{classdesc}{Template}{template}
+The constructor takes a single argument which is the template string.
+\end{classdesc}
+
+\begin{methoddesc}[Template]{substitute}{mapping\optional{, **kws}}
+Performs the template substitution, returning a new string.  \var{mapping} is
+any dictionary-like object with keys that match the placeholders in the
+template.  Alternatively, you can provide keyword arguments, where the
+keywords are the placeholders.  When both \var{mapping} and \var{kws} are
+given and there are duplicates, the placeholders from \var{kws} take
+precedence.
+\end{methoddesc}
+
+\begin{methoddesc}[Template]{safe_substitute}{mapping\optional{, **kws}}
+Like \method{substitute()}, except that if placeholders are missing from
+\var{mapping} and \var{kws}, instead of raising a \exception{KeyError}
+exception, the original placeholder will appear in the resulting string
+intact.  Also, unlike with \method{substitute()}, any other appearances of the
+\samp{\$} will simply return \samp{\$} instead of raising
+\exception{ValueError}.
+
+While other exceptions may still occur, this method is called ``safe'' because
+substitutions always tries to return a usable string instead of raising an
+exception.  In another sense, \method{safe_substitute()} may be anything other
+than safe, since it will silently ignore malformed templates containing
+dangling delimiters, unmatched braces, or placeholders that are not valid
+Python identifiers.
+\end{methoddesc}
+
+\class{Template} instances also provide one public data attribute:
+
+\begin{memberdesc}[string]{template}
+This is the object passed to the constructor's \var{template} argument.  In
+general, you shouldn't change it, but read-only access is not enforced.
+\end{memberdesc}
+
+Here is an example of how to use a Template:
+
+\begin{verbatim}
+>>> from string import Template
+>>> s = Template('$who likes $what')
+>>> s.substitute(who='tim', what='kung pao')
+'tim likes kung pao'
+>>> d = dict(who='tim')
+>>> Template('Give $who $100').substitute(d)
+Traceback (most recent call last):
+[...]
+ValueError: Invalid placeholder in string: line 1, col 10
+>>> Template('$who likes $what').substitute(d)
+Traceback (most recent call last):
+[...]
+KeyError: 'what'
+>>> Template('$who likes $what').safe_substitute(d)
+'tim likes $what'
+\end{verbatim}
+
+Advanced usage: you can derive subclasses of \class{Template} to customize the
+placeholder syntax, delimiter character, or the entire regular expression used
+to parse template strings.  To do this, you can override these class
+attributes:
+
+\begin{itemize}
+\item \var{delimiter} -- This is the literal string describing a placeholder
+      introducing delimiter.  The default value \samp{\$}.  Note that this
+      should \emph{not} be a regular expression, as the implementation will
+      call \method{re.escape()} on this string as needed.
+\item \var{idpattern} -- This is the regular expression describing the pattern
+      for non-braced placeholders (the braces will be added automatically as
+      appropriate).  The default value is the regular expression
+      \samp{[_a-z][_a-z0-9]*}.
+\end{itemize}
+
+Alternatively, you can provide the entire regular expression pattern by
+overriding the class attribute \var{pattern}.  If you do this, the value must
+be a regular expression object with four named capturing groups.  The
+capturing groups correspond to the rules given above, along with the invalid
+placeholder rule:
+
+\begin{itemize}
+\item \var{escaped} -- This group matches the escape sequence,
+      e.g. \samp{\$\$}, in the default pattern.
+\item \var{named} -- This group matches the unbraced placeholder name; it
+      should not include the delimiter in capturing group.
+\item \var{braced} -- This group matches the brace enclosed placeholder name;
+      it should not include either the delimiter or braces in the capturing
+      group.
+\item \var{invalid} -- This group matches any other delimiter pattern (usually
+      a single delimiter), and it should appear last in the regular
+      expression.
+\end{itemize}
+
+\subsection{String functions}
+
+The following functions are available to operate on string and Unicode
+objects.  They are not available as string methods.
+
+\begin{funcdesc}{capwords}{s}
+  Split the argument into words using \function{split()}, capitalize
+  each word using \function{capitalize()}, and join the capitalized
+  words using \function{join()}.  Note that this replaces runs of
+  whitespace characters by a single space, and removes leading and
+  trailing whitespace.
+\end{funcdesc}
+
+\begin{funcdesc}{maketrans}{from, to}
+  Return a translation table suitable for passing to
+  \function{translate()}, that will map
+  each character in \var{from} into the character at the same position
+  in \var{to}; \var{from} and \var{to} must have the same length.
+
+  \warning{Don't use strings derived from \constant{lowercase}
+  and \constant{uppercase} as arguments; in some locales, these don't have
+  the same length.  For case conversions, always use
+  \function{lower()} and \function{upper()}.}
+\end{funcdesc}
+
+\subsection{Deprecated string functions}
+
+The following list of functions are also defined as methods of string and
+Unicode objects; see ``String Methods'' (section
+\ref{string-methods}) for more information on those.  You should consider
+these functions as deprecated, although they will not be removed until Python
+3.0.  The functions defined in this module are:
+
+\begin{funcdesc}{atof}{s}
+  \deprecated{2.0}{Use the \function{float()} built-in function.}
+  Convert a string to a floating point number.  The string must have
+  the standard syntax for a floating point literal in Python,
+  optionally preceded by a sign (\samp{+} or \samp{-}).  Note that
+  this behaves identical to the built-in function
+  \function{float()}\bifuncindex{float} when passed a string.
+
+  \note{When passing in a string, values for NaN\index{NaN}
+  and Infinity\index{Infinity} may be returned, depending on the
+  underlying C library.  The specific set of strings accepted which
+  cause these values to be returned depends entirely on the C library
+  and is known to vary.}
+\end{funcdesc}
+
+\begin{funcdesc}{atoi}{s\optional{, base}}
+  \deprecated{2.0}{Use the \function{int()} built-in function.}
+  Convert string \var{s} to an integer in the given \var{base}.  The
+  string must consist of one or more digits, optionally preceded by a
+  sign (\samp{+} or \samp{-}).  The \var{base} defaults to 10.  If it
+  is 0, a default base is chosen depending on the leading characters
+  of the string (after stripping the sign): \samp{0x} or \samp{0X}
+  means 16, \samp{0} means 8, anything else means 10.  If \var{base}
+  is 16, a leading \samp{0x} or \samp{0X} is always accepted, though
+  not required.  This behaves identically to the built-in function
+  \function{int()} when passed a string.  (Also note: for a more
+  flexible interpretation of numeric literals, use the built-in
+  function \function{eval()}\bifuncindex{eval}.)
+\end{funcdesc}
+
+\begin{funcdesc}{atol}{s\optional{, base}}
+  \deprecated{2.0}{Use the \function{long()} built-in function.}
+  Convert string \var{s} to a long integer in the given \var{base}.
+  The string must consist of one or more digits, optionally preceded
+  by a sign (\samp{+} or \samp{-}).  The \var{base} argument has the
+  same meaning as for \function{atoi()}.  A trailing \samp{l} or
+  \samp{L} is not allowed, except if the base is 0.  Note that when
+  invoked without \var{base} or with \var{base} set to 10, this
+  behaves identical to the built-in function
+  \function{long()}\bifuncindex{long} when passed a string.
+\end{funcdesc}
+
+\begin{funcdesc}{capitalize}{word}
+  Return a copy of \var{word} with only its first character capitalized.
+\end{funcdesc}
+
+\begin{funcdesc}{expandtabs}{s\optional{, tabsize}}
+  Expand tabs in a string replacing them by one or more spaces,
+  depending on the current column and the given tab size.  The column
+  number is reset to zero after each newline occurring in the string.
+  This doesn't understand other non-printing characters or escape
+  sequences.  The tab size defaults to 8.
+\end{funcdesc}
+
+\begin{funcdesc}{find}{s, sub\optional{, start\optional{,end}}}
+  Return the lowest index in \var{s} where the substring \var{sub} is
+  found such that \var{sub} is wholly contained in
+  \code{\var{s}[\var{start}:\var{end}]}.  Return \code{-1} on failure.
+  Defaults for \var{start} and \var{end} and interpretation of
+  negative values is the same as for slices.
+\end{funcdesc}
+
+\begin{funcdesc}{rfind}{s, sub\optional{, start\optional{, end}}}
+  Like \function{find()} but find the highest index.
+\end{funcdesc}
+
+\begin{funcdesc}{index}{s, sub\optional{, start\optional{, end}}}
+  Like \function{find()} but raise \exception{ValueError} when the
+  substring is not found.
+\end{funcdesc}
+
+\begin{funcdesc}{rindex}{s, sub\optional{, start\optional{, end}}}
+  Like \function{rfind()} but raise \exception{ValueError} when the
+  substring is not found.
+\end{funcdesc}
+
+\begin{funcdesc}{count}{s, sub\optional{, start\optional{, end}}}
+  Return the number of (non-overlapping) occurrences of substring
+  \var{sub} in string \code{\var{s}[\var{start}:\var{end}]}.
+  Defaults for \var{start} and \var{end} and interpretation of
+  negative values are the same as for slices.
+\end{funcdesc}
+
+\begin{funcdesc}{lower}{s}
+  Return a copy of \var{s}, but with upper case letters converted to
+  lower case.
+\end{funcdesc}
+
+\begin{funcdesc}{split}{s\optional{, sep\optional{, maxsplit}}}
+  Return a list of the words of the string \var{s}.  If the optional
+  second argument \var{sep} is absent or \code{None}, the words are
+  separated by arbitrary strings of whitespace characters (space, tab, 
+  newline, return, formfeed).  If the second argument \var{sep} is
+  present and not \code{None}, it specifies a string to be used as the 
+  word separator.  The returned list will then have one more item
+  than the number of non-overlapping occurrences of the separator in
+  the string.  The optional third argument \var{maxsplit} defaults to
+  0.  If it is nonzero, at most \var{maxsplit} number of splits occur,
+  and the remainder of the string is returned as the final element of
+  the list (thus, the list will have at most \code{\var{maxsplit}+1}
+  elements).
+
+  The behavior of split on an empty string depends on the value of \var{sep}.
+  If \var{sep} is not specified, or specified as \code{None}, the result will
+  be an empty list.  If \var{sep} is specified as any string, the result will
+  be a list containing one element which is an empty string.
+\end{funcdesc}
+
+\begin{funcdesc}{rsplit}{s\optional{, sep\optional{, maxsplit}}}
+  Return a list of the words of the string \var{s}, scanning \var{s}
+  from the end.  To all intents and purposes, the resulting list of
+  words is the same as returned by \function{split()}, except when the
+  optional third argument \var{maxsplit} is explicitly specified and
+  nonzero.  When \var{maxsplit} is nonzero, at most \var{maxsplit}
+  number of splits -- the \emph{rightmost} ones -- occur, and the remainder
+  of the string is returned as the first element of the list (thus, the
+  list will have at most \code{\var{maxsplit}+1} elements).
+  \versionadded{2.4}
+\end{funcdesc}
+
+\begin{funcdesc}{splitfields}{s\optional{, sep\optional{, maxsplit}}}
+  This function behaves identically to \function{split()}.  (In the
+  past, \function{split()} was only used with one argument, while
+  \function{splitfields()} was only used with two arguments.)
+\end{funcdesc}
+
+\begin{funcdesc}{join}{words\optional{, sep}}
+  Concatenate a list or tuple of words with intervening occurrences of 
+  \var{sep}.  The default value for \var{sep} is a single space
+  character.  It is always true that
+  \samp{string.join(string.split(\var{s}, \var{sep}), \var{sep})}
+  equals \var{s}.
+\end{funcdesc}
+
+\begin{funcdesc}{joinfields}{words\optional{, sep}}
+  This function behaves identically to \function{join()}.  (In the past, 
+  \function{join()} was only used with one argument, while
+  \function{joinfields()} was only used with two arguments.)
+  Note that there is no \method{joinfields()} method on string
+  objects; use the \method{join()} method instead.
+\end{funcdesc}
+
+\begin{funcdesc}{lstrip}{s\optional{, chars}}
+Return a copy of the string with leading characters removed.  If
+\var{chars} is omitted or \code{None}, whitespace characters are
+removed.  If given and not \code{None}, \var{chars} must be a string;
+the characters in the string will be stripped from the beginning of
+the string this method is called on.
+\versionchanged[The \var{chars} parameter was added.  The \var{chars}
+parameter cannot be passed in earlier 2.2 versions]{2.2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{rstrip}{s\optional{, chars}}
+Return a copy of the string with trailing characters removed.  If
+\var{chars} is omitted or \code{None}, whitespace characters are
+removed.  If given and not \code{None}, \var{chars} must be a string;
+the characters in the string will be stripped from the end of the
+string this method is called on.
+\versionchanged[The \var{chars} parameter was added.  The \var{chars}
+parameter cannot be passed in earlier 2.2 versions]{2.2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{strip}{s\optional{, chars}}
+Return a copy of the string with leading and trailing characters
+removed.  If \var{chars} is omitted or \code{None}, whitespace
+characters are removed.  If given and not \code{None}, \var{chars}
+must be a string; the characters in the string will be stripped from
+the both ends of the string this method is called on.
+\versionchanged[The \var{chars} parameter was added.  The \var{chars}
+parameter cannot be passed in earlier 2.2 versions]{2.2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{swapcase}{s}
+  Return a copy of \var{s}, but with lower case letters
+  converted to upper case and vice versa.
+\end{funcdesc}
+
+\begin{funcdesc}{translate}{s, table\optional{, deletechars}}
+  Delete all characters from \var{s} that are in \var{deletechars} (if 
+  present), and then translate the characters using \var{table}, which 
+  must be a 256-character string giving the translation for each
+  character value, indexed by its ordinal.
+\end{funcdesc}
+
+\begin{funcdesc}{upper}{s}
+  Return a copy of \var{s}, but with lower case letters converted to
+  upper case.
+\end{funcdesc}
+
+\begin{funcdesc}{ljust}{s, width}
+\funcline{rjust}{s, width}
+\funcline{center}{s, width}
+  These functions respectively left-justify, right-justify and center
+  a string in a field of given width.  They return a string that is at
+  least \var{width} characters wide, created by padding the string
+  \var{s} with spaces until the given width on the right, left or both
+  sides.  The string is never truncated.
+\end{funcdesc}
+
+\begin{funcdesc}{zfill}{s, width}
+  Pad a numeric string on the left with zero digits until the given
+  width is reached.  Strings starting with a sign are handled
+  correctly.
+\end{funcdesc}
+
+\begin{funcdesc}{replace}{str, old, new\optional{, maxreplace}}
+  Return a copy of string \var{str} with all occurrences of substring
+  \var{old} replaced by \var{new}.  If the optional argument
+  \var{maxreplace} is given, the first \var{maxreplace} occurrences are
+  replaced.
+\end{funcdesc}

Added: vendor/Python/current/Doc/lib/libstringio.tex
===================================================================
--- vendor/Python/current/Doc/lib/libstringio.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libstringio.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,121 @@
+\section{\module{StringIO} ---
+         Read and write strings as files}
+
+\declaremodule{standard}{StringIO}
+\modulesynopsis{Read and write strings as if they were files.}
+
+
+This module implements a file-like class, \class{StringIO},
+that reads and writes a string buffer (also known as \emph{memory
+files}).  See the description of file objects for operations (section
+\ref{bltin-file-objects}).
+
+\begin{classdesc}{StringIO}{\optional{buffer}}
+When a \class{StringIO} object is created, it can be initialized
+to an existing string by passing the string to the constructor.
+If no string is given, the \class{StringIO} will start empty.
+In both cases, the initial file position starts at zero.
+
+The \class{StringIO} object can accept either Unicode or 8-bit
+strings, but mixing the two may take some care.  If both are used,
+8-bit strings that cannot be interpreted as 7-bit \ASCII{} (that
+use the 8th bit) will cause a \exception{UnicodeError} to be raised
+when \method{getvalue()} is called.
+\end{classdesc}
+
+The following methods of \class{StringIO} objects require special
+mention:
+
+\begin{methoddesc}{getvalue}{}
+Retrieve the entire contents of the ``file'' at any time before the
+\class{StringIO} object's \method{close()} method is called.  See the
+note above for information about mixing Unicode and 8-bit strings;
+such mixing can cause this method to raise \exception{UnicodeError}.
+\end{methoddesc}
+
+\begin{methoddesc}{close}{}
+Free the memory buffer.
+\end{methoddesc}
+
+Example usage:
+
+\begin{verbatim}
+import StringIO
+
+output = StringIO.StringIO()
+output.write('First line.\n')
+print >>output, 'Second line.'
+
+# Retrieve file contents -- this will be
+# 'First line.\nSecond line.\n'
+contents = output.getvalue()
+
+# Close object and discard memory buffer -- 
+# .getvalue() will now raise an exception.
+output.close()
+\end{verbatim}
+
+
+\section{\module{cStringIO} ---
+         Faster version of \module{StringIO}}
+
+\declaremodule{builtin}{cStringIO}
+\modulesynopsis{Faster version of \module{StringIO}, but not
+                subclassable.}
+\moduleauthor{Jim Fulton}{jim at zope.com}
+\sectionauthor{Fred L. Drake, Jr.}{fdrake at acm.org}
+
+The module \module{cStringIO} provides an interface similar to that of
+the \refmodule{StringIO} module.  Heavy use of \class{StringIO.StringIO}
+objects can be made more efficient by using the function
+\function{StringIO()} from this module instead.
+
+Since this module provides a factory function which returns objects of
+built-in types, there's no way to build your own version using
+subclassing.  Use the original \refmodule{StringIO} module in that case.
+
+Unlike the memory files implemented by the \refmodule{StringIO}
+module, those provided by this module are not able to accept Unicode
+strings that cannot be encoded as plain \ASCII{} strings.
+
+Another difference from the \refmodule{StringIO} module is that calling
+\function{StringIO()} with a string parameter creates a read-only object.
+Unlike an object created without a string parameter, it does not have
+write methods.  These objects are not generally visible.  They turn up in
+tracebacks as \class{StringI} and \class{StringO}.
+
+The following data objects are provided as well:
+
+
+\begin{datadesc}{InputType}
+  The type object of the objects created by calling
+  \function{StringIO} with a string parameter.
+\end{datadesc}
+
+\begin{datadesc}{OutputType}
+  The type object of the objects returned by calling
+  \function{StringIO} with no parameters.
+\end{datadesc}
+
+
+There is a C API to the module as well; refer to the module source for 
+more information.
+
+Example usage:
+
+\begin{verbatim}
+import cStringIO
+
+output = cStringIO.StringIO()
+output.write('First line.\n')
+print >>output, 'Second line.'
+
+# Retrieve file contents -- this will be
+# 'First line.\nSecond line.\n'
+contents = output.getvalue()
+
+# Close object and discard memory buffer -- 
+# .getvalue() will now raise an exception.
+output.close()
+\end{verbatim}
+

Added: vendor/Python/current/Doc/lib/libstringprep.tex
===================================================================
--- vendor/Python/current/Doc/lib/libstringprep.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libstringprep.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,136 @@
+\section{\module{stringprep} ---
+         Internet String Preparation}
+
+\declaremodule{standard}{stringprep}
+\modulesynopsis{String preparation, as per RFC 3453}
+\moduleauthor{Martin v. L\"owis}{martin at v.loewis.de}
+\sectionauthor{Martin v. L\"owis}{martin at v.loewis.de}
+
+\versionadded{2.3}
+
+When identifying things (such as host names) in the internet, it is
+often necessary to compare such identifications for
+``equality''. Exactly how this comparison is executed may depend on
+the application domain, e.g. whether it should be case-insensitive or
+not. It may be also necessary to restrict the possible
+identifications, to allow only identifications consisting of
+``printable'' characters.
+
+\rfc{3454} defines a procedure for ``preparing'' Unicode strings in
+internet protocols. Before passing strings onto the wire, they are
+processed with the preparation procedure, after which they have a
+certain normalized form. The RFC defines a set of tables, which can be
+combined into profiles. Each profile must define which tables it uses,
+and what other optional parts of the \code{stringprep} procedure are
+part of the profile. One example of a \code{stringprep} profile is
+\code{nameprep}, which is used for internationalized domain names.
+
+The module \module{stringprep} only exposes the tables from RFC
+3454. As these tables would be very large to represent them as
+dictionaries or lists, the module uses the Unicode character database
+internally. The module source code itself was generated using the
+\code{mkstringprep.py} utility.
+
+As a result, these tables are exposed as functions, not as data
+structures. There are two kinds of tables in the RFC: sets and
+mappings. For a set, \module{stringprep} provides the ``characteristic
+function'', i.e. a function that returns true if the parameter is part
+of the set. For mappings, it provides the mapping function: given the
+key, it returns the associated value. Below is a list of all functions
+available in the module.
+
+\begin{funcdesc}{in_table_a1}{code}
+Determine whether \var{code} is in table{A.1} (Unassigned code points
+in Unicode 3.2).
+\end{funcdesc}
+
+\begin{funcdesc}{in_table_b1}{code}
+Determine whether \var{code} is in table{B.1} (Commonly mapped to
+nothing).
+\end{funcdesc}
+
+\begin{funcdesc}{map_table_b2}{code}
+Return the mapped value for \var{code} according to table{B.2} 
+(Mapping for case-folding used with NFKC).
+\end{funcdesc}
+
+\begin{funcdesc}{map_table_b3}{code}
+Return the mapped value for \var{code} according to table{B.3} 
+(Mapping for case-folding used with no normalization).
+\end{funcdesc}
+
+\begin{funcdesc}{in_table_c11}{code}
+Determine whether \var{code} is in table{C.1.1} 
+(ASCII space characters).
+\end{funcdesc}
+
+\begin{funcdesc}{in_table_c12}{code}
+Determine whether \var{code} is in table{C.1.2} 
+(Non-ASCII space characters).
+\end{funcdesc}
+
+\begin{funcdesc}{in_table_c11_c12}{code}
+Determine whether \var{code} is in table{C.1} 
+(Space characters, union of C.1.1 and C.1.2).
+\end{funcdesc}
+
+\begin{funcdesc}{in_table_c21}{code}
+Determine whether \var{code} is in table{C.2.1} 
+(ASCII control characters).
+\end{funcdesc}
+
+\begin{funcdesc}{in_table_c22}{code}
+Determine whether \var{code} is in table{C.2.2} 
+(Non-ASCII control characters).
+\end{funcdesc}
+
+\begin{funcdesc}{in_table_c21_c22}{code}
+Determine whether \var{code} is in table{C.2} 
+(Control characters, union of C.2.1 and C.2.2).
+\end{funcdesc}
+
+\begin{funcdesc}{in_table_c3}{code}
+Determine whether \var{code} is in table{C.3} 
+(Private use).
+\end{funcdesc}
+
+\begin{funcdesc}{in_table_c4}{code}
+Determine whether \var{code} is in table{C.4} 
+(Non-character code points).
+\end{funcdesc}
+
+\begin{funcdesc}{in_table_c5}{code}
+Determine whether \var{code} is in table{C.5} 
+(Surrogate codes).
+\end{funcdesc}
+
+\begin{funcdesc}{in_table_c6}{code}
+Determine whether \var{code} is in table{C.6} 
+(Inappropriate for plain text).
+\end{funcdesc}
+
+\begin{funcdesc}{in_table_c7}{code}
+Determine whether \var{code} is in table{C.7} 
+(Inappropriate for canonical representation).
+\end{funcdesc}
+
+\begin{funcdesc}{in_table_c8}{code}
+Determine whether \var{code} is in table{C.8} 
+(Change display properties or are deprecated).
+\end{funcdesc}
+
+\begin{funcdesc}{in_table_c9}{code}
+Determine whether \var{code} is in table{C.9} 
+(Tagging characters).
+\end{funcdesc}
+
+\begin{funcdesc}{in_table_d1}{code}
+Determine whether \var{code} is in table{D.1} 
+(Characters with bidirectional property ``R'' or ``AL'').
+\end{funcdesc}
+
+\begin{funcdesc}{in_table_d2}{code}
+Determine whether \var{code} is in table{D.2} 
+(Characters with bidirectional property ``L'').
+\end{funcdesc}
+

Added: vendor/Python/current/Doc/lib/libstrings.tex
===================================================================
--- vendor/Python/current/Doc/lib/libstrings.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libstrings.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,10 @@
+\chapter{String Services}
+\label{strings}
+
+The modules described in this chapter provide a wide range of string
+manipulation operations.  Here's an overview:
+
+\localmoduletable
+
+Information on the methods of string objects can be found in
+section~\ref{string-methods}, ``String Methods.''

Added: vendor/Python/current/Doc/lib/libstruct.tex
===================================================================
--- vendor/Python/current/Doc/lib/libstruct.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libstruct.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,256 @@
+\section{\module{struct} ---
+         Interpret strings as packed binary data}
+\declaremodule{builtin}{struct}
+
+\modulesynopsis{Interpret strings as packed binary data.}
+
+\indexii{C}{structures}
+\indexiii{packing}{binary}{data}
+
+This module performs conversions between Python values and C
+structs represented as Python strings.  It uses \dfn{format strings}
+(explained below) as compact descriptions of the lay-out of the C
+structs and the intended conversion to/from Python values.  This can
+be used in handling binary data stored in files or from network
+connections, among other sources.
+
+The module defines the following exception and functions:
+
+
+\begin{excdesc}{error}
+  Exception raised on various occasions; argument is a string
+  describing what is wrong.
+\end{excdesc}
+
+\begin{funcdesc}{pack}{fmt, v1, v2, \textrm{\ldots}}
+  Return a string containing the values
+  \code{\var{v1}, \var{v2}, \textrm{\ldots}} packed according to the given
+  format.  The arguments must match the values required by the format
+  exactly.
+\end{funcdesc}
+
+\begin{funcdesc}{pack_into}{fmt, buffer, offset, v1, v2, \moreargs}
+  Pack the values \code{\var{v1}, \var{v2}, \textrm{\ldots}} according to the given
+  format, write the packed bytes into the writable \var{buffer} starting at
+  \var{offset}.
+  Note that the offset is not an optional argument.
+
+  \versionadded{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{unpack}{fmt, string}
+  Unpack the string (presumably packed by \code{pack(\var{fmt},
+  \textrm{\ldots})}) according to the given format.  The result is a
+  tuple even if it contains exactly one item.  The string must contain
+  exactly the amount of data required by the format
+  (\code{len(\var{string})} must equal \code{calcsize(\var{fmt})}).
+\end{funcdesc}
+
+\begin{funcdesc}{unpack_from}{fmt, buffer\optional{,offset \code{= 0}}}
+  Unpack the \var{buffer} according to tthe given format.
+  The result is a tuple even if it contains exactly one item. The
+  \var{buffer} must contain at least the amount of data required by the
+  format (\code{len(buffer[offset:])} must be at least
+  \code{calcsize(\var{fmt})}).
+
+  \versionadded{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{calcsize}{fmt}
+  Return the size of the struct (and hence of the string)
+  corresponding to the given format.
+\end{funcdesc}
+
+Format characters have the following meaning; the conversion between
+C and Python values should be obvious given their types:
+
+\begin{tableiv}{c|l|l|c}{samp}{Format}{C Type}{Python}{Notes}
+  \lineiv{x}{pad byte}{no value}{}
+  \lineiv{c}{\ctype{char}}{string of length 1}{}
+  \lineiv{b}{\ctype{signed char}}{integer}{}
+  \lineiv{B}{\ctype{unsigned char}}{integer}{}
+  \lineiv{h}{\ctype{short}}{integer}{}
+  \lineiv{H}{\ctype{unsigned short}}{integer}{}
+  \lineiv{i}{\ctype{int}}{integer}{}
+  \lineiv{I}{\ctype{unsigned int}}{long}{}
+  \lineiv{l}{\ctype{long}}{integer}{}
+  \lineiv{L}{\ctype{unsigned long}}{long}{}
+  \lineiv{q}{\ctype{long long}}{long}{(1)}
+  \lineiv{Q}{\ctype{unsigned long long}}{long}{(1)}
+  \lineiv{f}{\ctype{float}}{float}{}
+  \lineiv{d}{\ctype{double}}{float}{}
+  \lineiv{s}{\ctype{char[]}}{string}{}
+  \lineiv{p}{\ctype{char[]}}{string}{}
+  \lineiv{P}{\ctype{void *}}{integer}{}
+\end{tableiv}
+
+\noindent
+Notes:
+
+\begin{description}
+\item[(1)]
+  The \character{q} and \character{Q} conversion codes are available in
+  native mode only if the platform C compiler supports C \ctype{long long},
+  or, on Windows, \ctype{__int64}.  They are always available in standard
+  modes.
+  \versionadded{2.2}
+\end{description}
+
+
+A format character may be preceded by an integral repeat count.  For
+example, the format string \code{'4h'} means exactly the same as
+\code{'hhhh'}.
+
+Whitespace characters between formats are ignored; a count and its
+format must not contain whitespace though.
+
+For the \character{s} format character, the count is interpreted as the
+size of the string, not a repeat count like for the other format
+characters; for example, \code{'10s'} means a single 10-byte string, while
+\code{'10c'} means 10 characters.  For packing, the string is
+truncated or padded with null bytes as appropriate to make it fit.
+For unpacking, the resulting string always has exactly the specified
+number of bytes.  As a special case, \code{'0s'} means a single, empty
+string (while \code{'0c'} means 0 characters).
+
+The \character{p} format character encodes a "Pascal string", meaning
+a short variable-length string stored in a fixed number of bytes.
+The count is the total number of bytes stored.  The first byte stored is
+the length of the string, or 255, whichever is smaller.  The bytes
+of the string follow.  If the string passed in to \function{pack()} is too
+long (longer than the count minus 1), only the leading count-1 bytes of the
+string are stored.  If the string is shorter than count-1, it is padded
+with null bytes so that exactly count bytes in all are used.  Note that
+for \function{unpack()}, the \character{p} format character consumes count
+bytes, but that the string returned can never contain more than 255
+characters.
+
+For the \character{I}, \character{L}, \character{q} and \character{Q}
+format characters, the return value is a Python long integer.
+
+For the \character{P} format character, the return value is a Python
+integer or long integer, depending on the size needed to hold a
+pointer when it has been cast to an integer type.  A \NULL{} pointer will
+always be returned as the Python integer \code{0}. When packing pointer-sized
+values, Python integer or long integer objects may be used.  For
+example, the Alpha and Merced processors use 64-bit pointer values,
+meaning a Python long integer will be used to hold the pointer; other
+platforms use 32-bit pointers and will use a Python integer.
+
+By default, C numbers are represented in the machine's native format
+and byte order, and properly aligned by skipping pad bytes if
+necessary (according to the rules used by the C compiler).
+
+Alternatively, the first character of the format string can be used to
+indicate the byte order, size and alignment of the packed data,
+according to the following table:
+
+\begin{tableiii}{c|l|l}{samp}{Character}{Byte order}{Size and alignment}
+  \lineiii{@}{native}{native}
+  \lineiii{=}{native}{standard}
+  \lineiii{<}{little-endian}{standard}
+  \lineiii{>}{big-endian}{standard}
+  \lineiii{!}{network (= big-endian)}{standard}
+\end{tableiii}
+
+If the first character is not one of these, \character{@} is assumed.
+
+Native byte order is big-endian or little-endian, depending on the
+host system.  For example, Motorola and Sun processors are big-endian;
+Intel and DEC processors are little-endian.
+
+Native size and alignment are determined using the C compiler's
+\keyword{sizeof} expression.  This is always combined with native byte
+order.
+
+Standard size and alignment are as follows: no alignment is required
+for any type (so you have to use pad bytes);
+\ctype{short} is 2 bytes;
+\ctype{int} and \ctype{long} are 4 bytes;
+\ctype{long long} (\ctype{__int64} on Windows) is 8 bytes;
+\ctype{float} and \ctype{double} are 32-bit and 64-bit
+IEEE floating point numbers, respectively.
+
+Note the difference between \character{@} and \character{=}: both use
+native byte order, but the size and alignment of the latter is
+standardized.
+
+The form \character{!} is available for those poor souls who claim they
+can't remember whether network byte order is big-endian or
+little-endian.
+
+There is no way to indicate non-native byte order (force
+byte-swapping); use the appropriate choice of \character{<} or
+\character{>}.
+
+The \character{P} format character is only available for the native
+byte ordering (selected as the default or with the \character{@} byte
+order character). The byte order character \character{=} chooses to
+use little- or big-endian ordering based on the host system. The
+struct module does not interpret this as native ordering, so the
+\character{P} format is not available.
+
+Examples (all using native byte order, size and alignment, on a
+big-endian machine):
+
+\begin{verbatim}
+>>> from struct import *
+>>> pack('hhl', 1, 2, 3)
+'\x00\x01\x00\x02\x00\x00\x00\x03'
+>>> unpack('hhl', '\x00\x01\x00\x02\x00\x00\x00\x03')
+(1, 2, 3)
+>>> calcsize('hhl')
+8
+\end{verbatim}
+
+Hint: to align the end of a structure to the alignment requirement of
+a particular type, end the format with the code for that type with a
+repeat count of zero.  For example, the format \code{'llh0l'}
+specifies two pad bytes at the end, assuming longs are aligned on
+4-byte boundaries.  This only works when native size and alignment are
+in effect; standard size and alignment does not enforce any alignment.
+
+\begin{seealso}
+  \seemodule{array}{Packed binary storage of homogeneous data.}
+  \seemodule{xdrlib}{Packing and unpacking of XDR data.}
+\end{seealso}
+
+\subsection{Struct Objects \label{struct-objects}}
+
+The \module{struct} module also defines the following type:
+
+\begin{classdesc}{Struct}{format}
+  Return a new Struct object which writes and reads binary data according to
+  the format string \var{format}.  Creating a Struct object once and calling
+  its methods is more efficient than calling the \module{struct} functions
+  with the same format since the format string only needs to be compiled once.
+
+ \versionadded{2.5}
+\end{classdesc}
+
+Compiled Struct objects support the following methods and attributes:
+
+\begin{methoddesc}[Struct]{pack}{v1, v2, \moreargs}
+  Identical to the \function{pack()} function, using the compiled format.
+  (\code{len(result)} will equal \member{self.size}.)
+\end{methoddesc}
+
+\begin{methoddesc}[Struct]{pack_into}{buffer, offset, v1, v2, \moreargs}
+  Identical to the \function{pack_into()} function, using the compiled format.
+\end{methoddesc}
+
+\begin{methoddesc}[Struct]{unpack}{string}
+  Identical to the \function{unpack()} function, using the compiled format.
+  (\code{len(string)} must equal \member{self.size}).
+\end{methoddesc}
+
+\begin{methoddesc}[Struct]{unpack_from}{buffer\optional{,offset
+                                              \code{= 0}}}
+  Identical to the \function{unpack_from()} function, using the compiled format.
+  (\code{len(buffer[offset:])} must be at least \member{self.size}).
+\end{methoddesc}
+
+\begin{memberdesc}[Struct]{format}
+  The format string used to construct this Struct object.
+\end{memberdesc}
+

Added: vendor/Python/current/Doc/lib/libsubprocess.tex
===================================================================
--- vendor/Python/current/Doc/lib/libsubprocess.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libsubprocess.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,402 @@
+\section{\module{subprocess} --- Subprocess management}
+
+\declaremodule{standard}{subprocess}
+\modulesynopsis{Subprocess management.}
+\moduleauthor{Peter \AA strand}{astrand at lysator.liu.se}
+\sectionauthor{Peter \AA strand}{astrand at lysator.liu.se}
+
+\versionadded{2.4}
+
+The \module{subprocess} module allows you to spawn new processes,
+connect to their input/output/error pipes, and obtain their return
+codes.  This module intends to replace several other, older modules
+and functions, such as:
+
+\begin{verbatim}
+os.system
+os.spawn*
+os.popen*
+popen2.*
+commands.*
+\end{verbatim}
+
+Information about how the \module{subprocess} module can be used to
+replace these modules and functions can be found in the following
+sections.
+
+\subsection{Using the subprocess Module}
+
+This module defines one class called \class{Popen}:
+
+\begin{classdesc}{Popen}{args, bufsize=0, executable=None,
+            stdin=None, stdout=None, stderr=None,
+            preexec_fn=None, close_fds=False, shell=False,
+            cwd=None, env=None, universal_newlines=False,
+            startupinfo=None, creationflags=0}
+
+Arguments are:
+
+\var{args} should be a string, or a sequence of program arguments.  The
+program to execute is normally the first item in the args sequence or
+string, but can be explicitly set by using the executable argument.
+
+On \UNIX{}, with \var{shell=False} (default): In this case, the Popen
+class uses \method{os.execvp()} to execute the child program.
+\var{args} should normally be a sequence.  A string will be treated as a
+sequence with the string as the only item (the program to execute).
+
+On \UNIX{}, with \var{shell=True}: If args is a string, it specifies the
+command string to execute through the shell.  If \var{args} is a
+sequence, the first item specifies the command string, and any
+additional items will be treated as additional shell arguments.
+
+On Windows: the \class{Popen} class uses CreateProcess() to execute
+the child program, which operates on strings.  If \var{args} is a
+sequence, it will be converted to a string using the
+\method{list2cmdline} method.  Please note that not all MS Windows
+applications interpret the command line the same way:
+\method{list2cmdline} is designed for applications using the same
+rules as the MS C runtime.
+
+\var{bufsize}, if given, has the same meaning as the corresponding
+argument to the built-in open() function: \constant{0} means unbuffered,
+\constant{1} means line buffered, any other positive value means use a
+buffer of (approximately) that size.  A negative \var{bufsize} means to
+use the system default, which usually means fully buffered.  The default
+value for \var{bufsize} is \constant{0} (unbuffered).
+
+The \var{executable} argument specifies the program to execute. It is
+very seldom needed: Usually, the program to execute is defined by the
+\var{args} argument. If \code{shell=True}, the \var{executable}
+argument specifies which shell to use. On \UNIX{}, the default shell
+is \file{/bin/sh}.  On Windows, the default shell is specified by the
+\envvar{COMSPEC} environment variable.
+
+\var{stdin}, \var{stdout} and \var{stderr} specify the executed
+programs' standard input, standard output and standard error file
+handles, respectively.  Valid values are \code{PIPE}, an existing file
+descriptor (a positive integer), an existing file object, and
+\code{None}.  \code{PIPE} indicates that a new pipe to the child
+should be created.  With \code{None}, no redirection will occur; the
+child's file handles will be inherited from the parent.  Additionally,
+\var{stderr} can be \code{STDOUT}, which indicates that the stderr
+data from the applications should be captured into the same file
+handle as for stdout.
+
+If \var{preexec_fn} is set to a callable object, this object will be
+called in the child process just before the child is executed.
+(\UNIX{} only)
+
+If \var{close_fds} is true, all file descriptors except \constant{0},
+\constant{1} and \constant{2} will be closed before the child process is
+executed. (\UNIX{} only)
+
+If \var{shell} is \constant{True}, the specified command will be
+executed through the shell.
+
+If \var{cwd} is not \code{None}, the child's current directory will be
+changed to \var{cwd} before it is executed.  Note that this directory
+is not considered when searching the executable, so you can't specify
+the program's path relative to \var{cwd}.
+
+If \var{env} is not \code{None}, it defines the environment variables
+for the new process.
+
+If \var{universal_newlines} is \constant{True}, the file objects stdout
+and stderr are opened as text files, but lines may be terminated by
+any of \code{'\e n'}, the \UNIX{} end-of-line convention, \code{'\e r'},
+the Macintosh convention or \code{'\e r\e n'}, the Windows convention.
+All of these external representations are seen as \code{'\e n'} by the
+Python program.  \note{This feature is only available if Python is built
+with universal newline support (the default).  Also, the newlines
+attribute of the file objects \member{stdout}, \member{stdin} and
+\member{stderr} are not updated by the communicate() method.}
+
+The \var{startupinfo} and \var{creationflags}, if given, will be
+passed to the underlying CreateProcess() function.  They can specify
+things such as appearance of the main window and priority for the new
+process.  (Windows only)
+\end{classdesc}
+
+\subsubsection{Convenience Functions}
+
+This module also defines two shortcut functions:
+
+\begin{funcdesc}{call}{*popenargs, **kwargs}
+Run command with arguments.  Wait for command to complete, then
+return the \member{returncode} attribute.
+
+The arguments are the same as for the Popen constructor.  Example:
+
+\begin{verbatim}
+    retcode = call(["ls", "-l"])
+\end{verbatim}
+\end{funcdesc}
+
+\begin{funcdesc}{check_call}{*popenargs, **kwargs}
+Run command with arguments.  Wait for command to complete. If the exit
+code was zero then return, otherwise raise \exception{CalledProcessError.}
+The \exception{CalledProcessError} object will have the return code in the
+\member{returncode} attribute.
+
+The arguments are the same as for the Popen constructor.  Example:
+
+\begin{verbatim}
+    check_call(["ls", "-l"])
+\end{verbatim}
+\end{funcdesc}
+
+\subsubsection{Exceptions}
+
+Exceptions raised in the child process, before the new program has
+started to execute, will be re-raised in the parent.  Additionally,
+the exception object will have one extra attribute called
+\member{child_traceback}, which is a string containing traceback
+information from the childs point of view.
+
+The most common exception raised is \exception{OSError}.  This occurs,
+for example, when trying to execute a non-existent file.  Applications
+should prepare for \exception{OSError} exceptions.
+
+A \exception{ValueError} will be raised if \class{Popen} is called
+with invalid arguments.
+
+check_call() will raise \exception{CalledProcessError}, if the called
+process returns a non-zero return code.
+
+
+\subsubsection{Security}
+
+Unlike some other popen functions, this implementation will never call
+/bin/sh implicitly.  This means that all characters, including shell
+metacharacters, can safely be passed to child processes.
+
+
+\subsection{Popen Objects}
+
+Instances of the \class{Popen} class have the following methods:
+
+\begin{methoddesc}{poll}{}
+Check if child process has terminated.  Returns returncode
+attribute.
+\end{methoddesc}
+
+\begin{methoddesc}{wait}{}
+Wait for child process to terminate.  Returns returncode attribute.
+\end{methoddesc}
+
+\begin{methoddesc}{communicate}{input=None}
+Interact with process: Send data to stdin.  Read data from stdout and
+stderr, until end-of-file is reached.  Wait for process to terminate.
+The optional \var{input} argument should be a string to be sent to the
+child process, or \code{None}, if no data should be sent to the child.
+
+communicate() returns a tuple (stdout, stderr).
+
+\note{The data read is buffered in memory, so do not use this method
+if the data size is large or unlimited.}
+\end{methoddesc}
+
+The following attributes are also available:
+
+\begin{memberdesc}{stdin}
+If the \var{stdin} argument is \code{PIPE}, this attribute is a file
+object that provides input to the child process.  Otherwise, it is
+\code{None}.
+\end{memberdesc}
+
+\begin{memberdesc}{stdout}
+If the \var{stdout} argument is \code{PIPE}, this attribute is a file
+object that provides output from the child process.  Otherwise, it is
+\code{None}.
+\end{memberdesc}
+
+\begin{memberdesc}{stderr}
+If the \var{stderr} argument is \code{PIPE}, this attribute is file
+object that provides error output from the child process.  Otherwise,
+it is \code{None}.
+\end{memberdesc}
+
+\begin{memberdesc}{pid}
+The process ID of the child process.
+\end{memberdesc}
+
+\begin{memberdesc}{returncode}
+The child return code.  A \code{None} value indicates that the process
+hasn't terminated yet.  A negative value -N indicates that the child
+was terminated by signal N (\UNIX{} only).
+\end{memberdesc}
+
+
+\subsection{Replacing Older Functions with the subprocess Module}
+
+In this section, "a ==> b" means that b can be used as a replacement
+for a.
+
+\note{All functions in this section fail (more or less) silently if
+the executed program cannot be found; this module raises an
+\exception{OSError} exception.}
+
+In the following examples, we assume that the subprocess module is
+imported with "from subprocess import *".
+
+\subsubsection{Replacing /bin/sh shell backquote}
+
+\begin{verbatim}
+output=`mycmd myarg`
+==>
+output = Popen(["mycmd", "myarg"], stdout=PIPE).communicate()[0]
+\end{verbatim}
+
+\subsubsection{Replacing shell pipe line}
+
+\begin{verbatim}
+output=`dmesg | grep hda`
+==>
+p1 = Popen(["dmesg"], stdout=PIPE)
+p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
+output = p2.communicate()[0]
+\end{verbatim}
+
+\subsubsection{Replacing os.system()}
+
+\begin{verbatim}
+sts = os.system("mycmd" + " myarg")
+==>
+p = Popen("mycmd" + " myarg", shell=True)
+sts = os.waitpid(p.pid, 0)
+\end{verbatim}
+
+Notes:
+
+\begin{itemize}
+\item Calling the program through the shell is usually not required.
+\item It's easier to look at the \member{returncode} attribute than
+      the exit status.
+\end{itemize}
+
+A more realistic example would look like this:
+
+\begin{verbatim}
+try:
+    retcode = call("mycmd" + " myarg", shell=True)
+    if retcode < 0:
+        print >>sys.stderr, "Child was terminated by signal", -retcode
+    else:
+        print >>sys.stderr, "Child returned", retcode
+except OSError, e:
+    print >>sys.stderr, "Execution failed:", e
+\end{verbatim}
+
+\subsubsection{Replacing os.spawn*}
+
+P_NOWAIT example:
+
+\begin{verbatim}
+pid = os.spawnlp(os.P_NOWAIT, "/bin/mycmd", "mycmd", "myarg")
+==>
+pid = Popen(["/bin/mycmd", "myarg"]).pid
+\end{verbatim}
+
+P_WAIT example:
+
+\begin{verbatim}
+retcode = os.spawnlp(os.P_WAIT, "/bin/mycmd", "mycmd", "myarg")
+==>
+retcode = call(["/bin/mycmd", "myarg"])
+\end{verbatim}
+
+Vector example:
+
+\begin{verbatim}
+os.spawnvp(os.P_NOWAIT, path, args)
+==>
+Popen([path] + args[1:])
+\end{verbatim}
+
+Environment example:
+
+\begin{verbatim}
+os.spawnlpe(os.P_NOWAIT, "/bin/mycmd", "mycmd", "myarg", env)
+==>
+Popen(["/bin/mycmd", "myarg"], env={"PATH": "/usr/bin"})
+\end{verbatim}
+
+\subsubsection{Replacing os.popen*}
+
+\begin{verbatim}
+pipe = os.popen(cmd, mode='r', bufsize)
+==>
+pipe = Popen(cmd, shell=True, bufsize=bufsize, stdout=PIPE).stdout
+\end{verbatim}
+
+\begin{verbatim}
+pipe = os.popen(cmd, mode='w', bufsize)
+==>
+pipe = Popen(cmd, shell=True, bufsize=bufsize, stdin=PIPE).stdin
+\end{verbatim}
+
+\begin{verbatim}
+(child_stdin, child_stdout) = os.popen2(cmd, mode, bufsize)
+==>
+p = Popen(cmd, shell=True, bufsize=bufsize,
+          stdin=PIPE, stdout=PIPE, close_fds=True)
+(child_stdin, child_stdout) = (p.stdin, p.stdout)
+\end{verbatim}
+
+\begin{verbatim}
+(child_stdin,
+ child_stdout,
+ child_stderr) = os.popen3(cmd, mode, bufsize)
+==>
+p = Popen(cmd, shell=True, bufsize=bufsize,
+          stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True)
+(child_stdin,
+ child_stdout,
+ child_stderr) = (p.stdin, p.stdout, p.stderr)
+\end{verbatim}
+
+\begin{verbatim}
+(child_stdin, child_stdout_and_stderr) = os.popen4(cmd, mode, bufsize)
+==>
+p = Popen(cmd, shell=True, bufsize=bufsize,
+          stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True)
+(child_stdin, child_stdout_and_stderr) = (p.stdin, p.stdout)
+\end{verbatim}
+
+\subsubsection{Replacing popen2.*}
+
+\note{If the cmd argument to popen2 functions is a string, the command
+is executed through /bin/sh.  If it is a list, the command is directly
+executed.}
+
+\begin{verbatim}
+(child_stdout, child_stdin) = popen2.popen2("somestring", bufsize, mode)
+==>
+p = Popen(["somestring"], shell=True, bufsize=bufsize,
+          stdin=PIPE, stdout=PIPE, close_fds=True)
+(child_stdout, child_stdin) = (p.stdout, p.stdin)
+\end{verbatim}
+
+\begin{verbatim}
+(child_stdout, child_stdin) = popen2.popen2(["mycmd", "myarg"], bufsize, mode)
+==>
+p = Popen(["mycmd", "myarg"], bufsize=bufsize,
+          stdin=PIPE, stdout=PIPE, close_fds=True)
+(child_stdout, child_stdin) = (p.stdout, p.stdin)
+\end{verbatim}
+
+The popen2.Popen3 and popen2.Popen4 basically works as subprocess.Popen,
+except that:
+
+\begin{itemize}
+\item subprocess.Popen raises an exception if the execution fails
+
+\item the \var{capturestderr} argument is replaced with the \var{stderr}
+      argument.
+
+\item stdin=PIPE and stdout=PIPE must be specified.
+
+\item popen2 closes all file descriptors by default, but you have to
+      specify close_fds=True with subprocess.Popen.
+\end{itemize}

Added: vendor/Python/current/Doc/lib/libsun.tex
===================================================================
--- vendor/Python/current/Doc/lib/libsun.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libsun.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,5 @@
+\chapter{SunOS Specific Services}
+\label{sunos}
+
+The modules described in this chapter provide interfaces to features
+that are unique to SunOS 5 (also known as Solaris version 2).

Added: vendor/Python/current/Doc/lib/libsunau.tex
===================================================================
--- vendor/Python/current/Doc/lib/libsunau.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libsunau.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,218 @@
+\section{\module{sunau} ---
+         Read and write Sun AU files}
+
+\declaremodule{standard}{sunau}
+\sectionauthor{Moshe Zadka}{moshez at zadka.site.co.il}
+\modulesynopsis{Provide an interface to the Sun AU sound format.}
+
+The \module{sunau} module provides a convenient interface to the Sun
+AU sound format.  Note that this module is interface-compatible with
+the modules \refmodule{aifc} and \refmodule{wave}.
+
+An audio file consists of a header followed by the data.  The fields
+of the header are:
+
+\begin{tableii}{l|l}{textrm}{Field}{Contents}
+  \lineii{magic word}{The four bytes \samp{.snd}.}
+  \lineii{header size}{Size of the header, including info, in bytes.}
+  \lineii{data size}{Physical size of the data, in bytes.}
+  \lineii{encoding}{Indicates how the audio samples are encoded.}
+  \lineii{sample rate}{The sampling rate.}
+  \lineii{\# of channels}{The number of channels in the samples.}
+  \lineii{info}{\ASCII{} string giving a description of the audio
+                file (padded with null bytes).}
+\end{tableii}
+
+Apart from the info field, all header fields are 4 bytes in size.
+They are all 32-bit unsigned integers encoded in big-endian byte
+order.
+
+
+The \module{sunau} module defines the following functions:
+
+\begin{funcdesc}{open}{file, mode}
+If \var{file} is a string, open the file by that name, otherwise treat it
+as a seekable file-like object. \var{mode} can be any of
+\begin{description}
+	\item[\code{'r'}] Read only mode.
+	\item[\code{'w'}] Write only mode.
+\end{description}
+Note that it does not allow read/write files.
+
+A \var{mode} of \code{'r'} returns a \class{AU_read}
+object, while a \var{mode} of \code{'w'} or \code{'wb'} returns
+a \class{AU_write} object.
+\end{funcdesc}
+
+\begin{funcdesc}{openfp}{file, mode}
+A synonym for \function{open}, maintained for backwards compatibility.
+\end{funcdesc}
+
+The \module{sunau} module defines the following exception:
+
+\begin{excdesc}{Error}
+An error raised when something is impossible because of Sun AU specs or 
+implementation deficiency.
+\end{excdesc}
+
+The \module{sunau} module defines the following data items:
+
+\begin{datadesc}{AUDIO_FILE_MAGIC}
+An integer every valid Sun AU file begins with, stored in big-endian
+form.  This is the string \samp{.snd} interpreted as an integer.
+\end{datadesc}
+
+\begin{datadesc}{AUDIO_FILE_ENCODING_MULAW_8}
+\dataline{AUDIO_FILE_ENCODING_LINEAR_8}
+\dataline{AUDIO_FILE_ENCODING_LINEAR_16}
+\dataline{AUDIO_FILE_ENCODING_LINEAR_24}
+\dataline{AUDIO_FILE_ENCODING_LINEAR_32}
+\dataline{AUDIO_FILE_ENCODING_ALAW_8}
+Values of the encoding field from the AU header which are supported by
+this module.
+\end{datadesc}
+
+\begin{datadesc}{AUDIO_FILE_ENCODING_FLOAT}
+\dataline{AUDIO_FILE_ENCODING_DOUBLE}
+\dataline{AUDIO_FILE_ENCODING_ADPCM_G721}
+\dataline{AUDIO_FILE_ENCODING_ADPCM_G722}
+\dataline{AUDIO_FILE_ENCODING_ADPCM_G723_3}
+\dataline{AUDIO_FILE_ENCODING_ADPCM_G723_5}
+Additional known values of the encoding field from the AU header, but
+which are not supported by this module.
+\end{datadesc}
+
+
+\subsection{AU_read Objects \label{au-read-objects}}
+
+AU_read objects, as returned by \function{open()} above, have the
+following methods:
+
+\begin{methoddesc}[AU_read]{close}{}
+Close the stream, and make the instance unusable. (This is 
+called automatically on deletion.)
+\end{methoddesc}
+
+\begin{methoddesc}[AU_read]{getnchannels}{}
+Returns number of audio channels (1 for mone, 2 for stereo).
+\end{methoddesc}
+
+\begin{methoddesc}[AU_read]{getsampwidth}{}
+Returns sample width in bytes.
+\end{methoddesc}
+
+\begin{methoddesc}[AU_read]{getframerate}{}
+Returns sampling frequency.
+\end{methoddesc}
+
+\begin{methoddesc}[AU_read]{getnframes}{}
+Returns number of audio frames.
+\end{methoddesc}
+
+\begin{methoddesc}[AU_read]{getcomptype}{}
+Returns compression type.
+Supported compression types are \code{'ULAW'}, \code{'ALAW'} and \code{'NONE'}.
+\end{methoddesc}
+
+\begin{methoddesc}[AU_read]{getcompname}{}
+Human-readable version of \method{getcomptype()}. 
+The supported types have the respective names \code{'CCITT G.711
+u-law'}, \code{'CCITT G.711 A-law'} and \code{'not compressed'}.
+\end{methoddesc}
+
+\begin{methoddesc}[AU_read]{getparams}{}
+Returns a tuple \code{(\var{nchannels}, \var{sampwidth},
+\var{framerate}, \var{nframes}, \var{comptype}, \var{compname})},
+equivalent to output of the \method{get*()} methods.
+\end{methoddesc}
+
+\begin{methoddesc}[AU_read]{readframes}{n}
+Reads and returns at most \var{n} frames of audio, as a string of
+bytes.  The data will be returned in linear format.  If the original
+data is in u-LAW format, it will be converted.
+\end{methoddesc}
+
+\begin{methoddesc}[AU_read]{rewind}{}
+Rewind the file pointer to the beginning of the audio stream.
+\end{methoddesc}
+
+The following two methods define a term ``position'' which is compatible
+between them, and is otherwise implementation dependent.
+
+\begin{methoddesc}[AU_read]{setpos}{pos}
+Set the file pointer to the specified position.  Only values returned
+from \method{tell()} should be used for \var{pos}.
+\end{methoddesc}
+
+\begin{methoddesc}[AU_read]{tell}{}
+Return current file pointer position.  Note that the returned value
+has nothing to do with the actual position in the file.
+\end{methoddesc}
+
+The following two functions are defined for compatibility with the 
+\refmodule{aifc}, and don't do anything interesting.
+
+\begin{methoddesc}[AU_read]{getmarkers}{}
+Returns \code{None}.
+\end{methoddesc}
+
+\begin{methoddesc}[AU_read]{getmark}{id}
+Raise an error.
+\end{methoddesc}
+
+
+\subsection{AU_write Objects \label{au-write-objects}}
+
+AU_write objects, as returned by \function{open()} above, have the
+following methods:
+
+\begin{methoddesc}[AU_write]{setnchannels}{n}
+Set the number of channels.
+\end{methoddesc}
+
+\begin{methoddesc}[AU_write]{setsampwidth}{n}
+Set the sample width (in bytes.)
+\end{methoddesc}
+
+\begin{methoddesc}[AU_write]{setframerate}{n}
+Set the frame rate.
+\end{methoddesc}
+
+\begin{methoddesc}[AU_write]{setnframes}{n}
+Set the number of frames. This can be later changed, when and if more 
+frames are written.
+\end{methoddesc}
+
+
+\begin{methoddesc}[AU_write]{setcomptype}{type, name}
+Set the compression type and description.
+Only \code{'NONE'} and \code{'ULAW'} are supported on output.
+\end{methoddesc}
+
+\begin{methoddesc}[AU_write]{setparams}{tuple}
+The \var{tuple} should be \code{(\var{nchannels}, \var{sampwidth},
+\var{framerate}, \var{nframes}, \var{comptype}, \var{compname})}, with
+values valid for the \method{set*()} methods.  Set all parameters.
+\end{methoddesc}
+
+\begin{methoddesc}[AU_write]{tell}{}
+Return current position in the file, with the same disclaimer for
+the \method{AU_read.tell()} and \method{AU_read.setpos()} methods.
+\end{methoddesc}
+
+\begin{methoddesc}[AU_write]{writeframesraw}{data}
+Write audio frames, without correcting \var{nframes}.
+\end{methoddesc}
+
+\begin{methoddesc}[AU_write]{writeframes}{data}
+Write audio frames and make sure \var{nframes} is correct.
+\end{methoddesc}
+
+\begin{methoddesc}[AU_write]{close}{}
+Make sure \var{nframes} is correct, and close the file.
+
+This method is called upon deletion.
+\end{methoddesc}
+
+Note that it is invalid to set any parameters after calling 
+\method{writeframes()} or \method{writeframesraw()}. 

Added: vendor/Python/current/Doc/lib/libsunaudio.tex
===================================================================
--- vendor/Python/current/Doc/lib/libsunaudio.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libsunaudio.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,146 @@
+\section{\module{sunaudiodev} ---
+         Access to Sun audio hardware}
+
+\declaremodule{builtin}{sunaudiodev}
+  \platform{SunOS}
+\modulesynopsis{Access to Sun audio hardware.}
+
+
+This module allows you to access the Sun audio interface. The Sun
+audio hardware is capable of recording and playing back audio data
+in u-LAW\index{u-LAW} format with a sample rate of 8K per second. A
+full description can be found in the \manpage{audio}{7I} manual page.
+
+The module
+\refmodule[sunaudiodev-constants]{SUNAUDIODEV}\refstmodindex{SUNAUDIODEV} 
+defines constants which may be used with this module.
+
+This module defines the following variables and functions:
+
+\begin{excdesc}{error}
+This exception is raised on all errors. The argument is a string
+describing what went wrong.
+\end{excdesc}
+
+\begin{funcdesc}{open}{mode}
+This function opens the audio device and returns a Sun audio device
+object. This object can then be used to do I/O on. The \var{mode} parameter
+is one of \code{'r'} for record-only access, \code{'w'} for play-only
+access, \code{'rw'} for both and \code{'control'} for access to the
+control device. Since only one process is allowed to have the recorder
+or player open at the same time it is a good idea to open the device
+only for the activity needed. See \manpage{audio}{7I} for details.
+
+As per the manpage, this module first looks in the environment
+variable \code{AUDIODEV} for the base audio device filename.  If not
+found, it falls back to \file{/dev/audio}.  The control device is
+calculated by appending ``ctl'' to the base audio device.
+\end{funcdesc}
+
+
+\subsection{Audio Device Objects \label{audio-device-objects}}
+
+The audio device objects are returned by \function{open()} define the
+following methods (except \code{control} objects which only provide
+\method{getinfo()}, \method{setinfo()}, \method{fileno()}, and
+\method{drain()}):
+
+\begin{methoddesc}[audio device]{close}{}
+This method explicitly closes the device. It is useful in situations
+where deleting the object does not immediately close it since there
+are other references to it. A closed device should not be used again.
+\end{methoddesc}
+
+\begin{methoddesc}[audio device]{fileno}{}
+Returns the file descriptor associated with the device.  This can be
+used to set up \code{SIGPOLL} notification, as described below.
+\end{methoddesc}
+
+\begin{methoddesc}[audio device]{drain}{}
+This method waits until all pending output is processed and then returns.
+Calling this method is often not necessary: destroying the object will
+automatically close the audio device and this will do an implicit drain.
+\end{methoddesc}
+
+\begin{methoddesc}[audio device]{flush}{}
+This method discards all pending output. It can be used avoid the
+slow response to a user's stop request (due to buffering of up to one
+second of sound).
+\end{methoddesc}
+
+\begin{methoddesc}[audio device]{getinfo}{}
+This method retrieves status information like input and output volume,
+etc. and returns it in the form of
+an audio status object. This object has no methods but it contains a
+number of attributes describing the current device status. The names
+and meanings of the attributes are described in
+\code{<sun/audioio.h>} and in the \manpage{audio}{7I}
+manual page.  Member names
+are slightly different from their C counterparts: a status object is
+only a single structure. Members of the \cdata{play} substructure have
+\samp{o_} prepended to their name and members of the \cdata{record}
+structure have \samp{i_}. So, the C member \cdata{play.sample_rate} is
+accessed as \member{o_sample_rate}, \cdata{record.gain} as \member{i_gain}
+and \cdata{monitor_gain} plainly as \member{monitor_gain}.
+\end{methoddesc}
+
+\begin{methoddesc}[audio device]{ibufcount}{}
+This method returns the number of samples that are buffered on the
+recording side, i.e.\ the program will not block on a
+\function{read()} call of so many samples.
+\end{methoddesc}
+
+\begin{methoddesc}[audio device]{obufcount}{}
+This method returns the number of samples buffered on the playback
+side. Unfortunately, this number cannot be used to determine a number
+of samples that can be written without blocking since the kernel
+output queue length seems to be variable.
+\end{methoddesc}
+
+\begin{methoddesc}[audio device]{read}{size}
+This method reads \var{size} samples from the audio input and returns
+them as a Python string. The function blocks until enough data is available.
+\end{methoddesc}
+
+\begin{methoddesc}[audio device]{setinfo}{status}
+This method sets the audio device status parameters. The \var{status}
+parameter is an device status object as returned by \function{getinfo()} and
+possibly modified by the program.
+\end{methoddesc}
+
+\begin{methoddesc}[audio device]{write}{samples}
+Write is passed a Python string containing audio samples to be played.
+If there is enough buffer space free it will immediately return,
+otherwise it will block.
+\end{methoddesc}
+
+The audio device supports asynchronous notification of various events,
+through the SIGPOLL signal.  Here's an example of how you might enable
+this in Python:
+
+\begin{verbatim}
+def handle_sigpoll(signum, frame):
+    print 'I got a SIGPOLL update'
+
+import fcntl, signal, STROPTS
+
+signal.signal(signal.SIGPOLL, handle_sigpoll)
+fcntl.ioctl(audio_obj.fileno(), STROPTS.I_SETSIG, STROPTS.S_MSG)
+\end{verbatim}
+
+
+\section{\module{SUNAUDIODEV} ---
+         Constants used with \module{sunaudiodev}}
+
+\declaremodule[sunaudiodev-constants]{standard}{SUNAUDIODEV}
+  \platform{SunOS}
+\modulesynopsis{Constants for use with \refmodule{sunaudiodev}.}
+
+
+This is a companion module to
+\refmodule{sunaudiodev}\refbimodindex{sunaudiodev} which defines
+useful symbolic constants like \constant{MIN_GAIN},
+\constant{MAX_GAIN}, \constant{SPEAKER}, etc. The names of the
+constants are the same names as used in the C include file
+\code{<sun/audioio.h>}, with the leading string \samp{AUDIO_}
+stripped.

Added: vendor/Python/current/Doc/lib/libsymbol.tex
===================================================================
--- vendor/Python/current/Doc/lib/libsymbol.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libsymbol.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,30 @@
+\section{\module{symbol} ---
+         Constants used with Python parse trees}
+
+\declaremodule{standard}{symbol}
+\modulesynopsis{Constants representing internal nodes of the parse tree.}
+\sectionauthor{Fred L. Drake, Jr.}{fdrake at acm.org}
+
+
+This module provides constants which represent the numeric values of
+internal nodes of the parse tree.  Unlike most Python constants, these
+use lower-case names.  Refer to the file \file{Grammar/Grammar} in the
+Python distribution for the definitions of the names in the context of
+the language grammar.  The specific numeric values which the names map
+to may change between Python versions.
+
+This module also provides one additional data object:
+
+
+\begin{datadesc}{sym_name}
+  Dictionary mapping the numeric values of the constants defined in
+  this module back to name strings, allowing more human-readable
+  representation of parse trees to be generated.
+\end{datadesc}
+
+
+\begin{seealso}
+  \seemodule{parser}{The second example for the \refmodule{parser}
+                     module shows how to use the \module{symbol}
+                     module.}
+\end{seealso}

Added: vendor/Python/current/Doc/lib/libsys.tex
===================================================================
--- vendor/Python/current/Doc/lib/libsys.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libsys.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,617 @@
+\section{\module{sys} ---
+         System-specific parameters and functions}
+
+\declaremodule{builtin}{sys}
+\modulesynopsis{Access system-specific parameters and functions.}
+
+This module provides access to some variables used or maintained by the
+interpreter and to functions that interact strongly with the interpreter.
+It is always available.
+
+
+\begin{datadesc}{argv}
+  The list of command line arguments passed to a Python script.
+  \code{argv[0]} is the script name (it is operating system dependent
+  whether this is a full pathname or not).  If the command was
+  executed using the \programopt{-c} command line option to the
+  interpreter, \code{argv[0]} is set to the string \code{'-c'}.  If no
+  script name was passed to the Python interpreter, \code{argv} has
+  zero length.
+\end{datadesc}
+
+\begin{datadesc}{byteorder}
+  An indicator of the native byte order.  This will have the value
+  \code{'big'} on big-endian (most-significant byte first) platforms,
+  and \code{'little'} on little-endian (least-significant byte first)
+  platforms.
+  \versionadded{2.0}
+\end{datadesc}
+
+\begin{datadesc}{subversion}
+  A triple (repo, branch, version) representing the Subversion
+  information of the Python interpreter.
+  \var{repo} is the name of the repository, \code{'CPython'}.
+  \var{branch} is a string of one of the forms \code{'trunk'},
+  \code{'branches/name'} or \code{'tags/name'}.
+  \var{version} is the output of \code{svnversion}, if the
+  interpreter was built from a Subversion checkout; it contains
+  the revision number (range) and possibly a trailing 'M' if
+  there were local modifications. If the tree was exported
+  (or svnversion was not available), it is the revision of
+  \code{Include/patchlevel.h} if the branch is a tag. Otherwise,
+  it is \code{None}.
+  \versionadded{2.5}
+\end{datadesc}
+
+\begin{datadesc}{builtin_module_names}
+  A tuple of strings giving the names of all modules that are compiled
+  into this Python interpreter.  (This information is not available in
+  any other way --- \code{modules.keys()} only lists the imported
+  modules.)
+\end{datadesc}
+
+\begin{datadesc}{copyright}
+  A string containing the copyright pertaining to the Python
+  interpreter.
+\end{datadesc}
+
+\begin{funcdesc}{_current_frames}{}
+  Return a dictionary mapping each thread's identifier to the topmost stack
+  frame currently active in that thread at the time the function is called.
+  Note that functions in the \refmodule{traceback} module can build the
+  call stack given such a frame.
+
+  This is most useful for debugging deadlock:  this function does not
+  require the deadlocked threads' cooperation, and such threads' call stacks
+  are frozen for as long as they remain deadlocked.  The frame returned
+  for a non-deadlocked thread may bear no relationship to that thread's
+  current activity by the time calling code examines the frame.
+
+  This function should be used for internal and specialized purposes
+  only.
+  \versionadded{2.5}
+\end{funcdesc}
+
+\begin{datadesc}{dllhandle}
+  Integer specifying the handle of the Python DLL.
+  Availability: Windows.
+\end{datadesc}
+
+\begin{funcdesc}{displayhook}{\var{value}}
+  If \var{value} is not \code{None}, this function prints it to
+  \code{sys.stdout}, and saves it in \code{__builtin__._}.
+
+  \code{sys.displayhook} is called on the result of evaluating an
+  expression entered in an interactive Python session.  The display of
+  these values can be customized by assigning another one-argument
+  function to \code{sys.displayhook}.
+\end{funcdesc}
+
+\begin{funcdesc}{excepthook}{\var{type}, \var{value}, \var{traceback}}
+  This function prints out a given traceback and exception to
+  \code{sys.stderr}.
+
+  When an exception is raised and uncaught, the interpreter calls
+  \code{sys.excepthook} with three arguments, the exception class,
+  exception instance, and a traceback object.  In an interactive
+  session this happens just before control is returned to the prompt;
+  in a Python program this happens just before the program exits.  The
+  handling of such top-level exceptions can be customized by assigning
+  another three-argument function to \code{sys.excepthook}.
+\end{funcdesc}
+
+\begin{datadesc}{__displayhook__}
+\dataline{__excepthook__}
+  These objects contain the original values of \code{displayhook} and
+  \code{excepthook} at the start of the program.  They are saved so
+  that \code{displayhook} and \code{excepthook} can be restored in
+  case they happen to get replaced with broken objects.
+\end{datadesc}
+
+\begin{funcdesc}{exc_info}{}
+  This function returns a tuple of three values that give information
+  about the exception that is currently being handled.  The
+  information returned is specific both to the current thread and to
+  the current stack frame.  If the current stack frame is not handling
+  an exception, the information is taken from the calling stack frame,
+  or its caller, and so on until a stack frame is found that is
+  handling an exception.  Here, ``handling an exception'' is defined
+  as ``executing or having executed an except clause.''  For any stack
+  frame, only information about the most recently handled exception is
+  accessible.
+
+  If no exception is being handled anywhere on the stack, a tuple
+  containing three \code{None} values is returned.  Otherwise, the
+  values returned are \code{(\var{type}, \var{value},
+  \var{traceback})}.  Their meaning is: \var{type} gets the exception
+  type of the exception being handled (a class object);
+  \var{value} gets the exception parameter (its \dfn{associated value}
+  or the second argument to \keyword{raise}, which is always a class
+  instance if the exception type is a class object); \var{traceback}
+  gets a traceback object (see the Reference Manual) which
+  encapsulates the call stack at the point where the exception
+  originally occurred.  \obindex{traceback}
+
+  If \function{exc_clear()} is called, this function will return three
+  \code{None} values until either another exception is raised in the
+  current thread or the execution stack returns to a frame where
+  another exception is being handled.
+
+  \warning{Assigning the \var{traceback} return value to a
+  local variable in a function that is handling an exception will
+  cause a circular reference.  This will prevent anything referenced
+  by a local variable in the same function or by the traceback from
+  being garbage collected.  Since most functions don't need access to
+  the traceback, the best solution is to use something like
+  \code{exctype, value = sys.exc_info()[:2]} to extract only the
+  exception type and value.  If you do need the traceback, make sure
+  to delete it after use (best done with a \keyword{try}
+  ... \keyword{finally} statement) or to call \function{exc_info()} in
+  a function that does not itself handle an exception.} \note{Beginning
+  with Python 2.2, such cycles are automatically reclaimed when garbage
+  collection is enabled and they become unreachable, but it remains more
+  efficient to avoid creating cycles.}
+\end{funcdesc}
+
+\begin{funcdesc}{exc_clear}{}
+  This function clears all information relating to the current or last
+  exception that occurred in the current thread.  After calling this
+  function, \function{exc_info()} will return three \code{None} values until
+  another exception is raised in the current thread or the execution stack
+  returns to a frame where another exception is being handled.
+
+  This function is only needed in only a few obscure situations.  These
+  include logging and error handling systems that report information on the
+  last or current exception.  This function can also be used to try to free
+  resources and trigger object finalization, though no guarantee is made as
+  to what objects will be freed, if any.
+\versionadded{2.3}
+\end{funcdesc}
+
+\begin{datadesc}{exc_type}
+\dataline{exc_value}
+\dataline{exc_traceback}
+\deprecated {1.5}
+            {Use \function{exc_info()} instead.}
+  Since they are global variables, they are not specific to the
+  current thread, so their use is not safe in a multi-threaded
+  program.  When no exception is being handled, \code{exc_type} is set
+  to \code{None} and the other two are undefined.
+\end{datadesc}
+
+\begin{datadesc}{exec_prefix}
+  A string giving the site-specific directory prefix where the
+  platform-dependent Python files are installed; by default, this is
+  also \code{'/usr/local'}.  This can be set at build time with the
+  \longprogramopt{exec-prefix} argument to the \program{configure}
+  script.  Specifically, all configuration files (e.g. the
+  \file{pyconfig.h} header file) are installed in the directory
+  \code{exec_prefix + '/lib/python\var{version}/config'}, and shared
+  library modules are installed in \code{exec_prefix +
+  '/lib/python\var{version}/lib-dynload'}, where \var{version} is
+  equal to \code{version[:3]}.
+\end{datadesc}
+
+\begin{datadesc}{executable}
+  A string giving the name of the executable binary for the Python
+  interpreter, on systems where this makes sense.
+\end{datadesc}
+
+\begin{funcdesc}{exit}{\optional{arg}}
+  Exit from Python.  This is implemented by raising the
+  \exception{SystemExit} exception, so cleanup actions specified by
+  finally clauses of \keyword{try} statements are honored, and it is
+  possible to intercept the exit attempt at an outer level.  The
+  optional argument \var{arg} can be an integer giving the exit status
+  (defaulting to zero), or another type of object.  If it is an
+  integer, zero is considered ``successful termination'' and any
+  nonzero value is considered ``abnormal termination'' by shells and
+  the like.  Most systems require it to be in the range 0-127, and
+  produce undefined results otherwise.  Some systems have a convention
+  for assigning specific meanings to specific exit codes, but these
+  are generally underdeveloped; \UNIX{} programs generally use 2 for
+  command line syntax errors and 1 for all other kind of errors.  If
+  another type of object is passed, \code{None} is equivalent to
+  passing zero, and any other object is printed to \code{sys.stderr}
+  and results in an exit code of 1.  In particular,
+  \code{sys.exit("some error message")} is a quick way to exit a
+  program when an error occurs.
+\end{funcdesc}
+
+\begin{datadesc}{exitfunc}
+  This value is not actually defined by the module, but can be set by
+  the user (or by a program) to specify a clean-up action at program
+  exit.  When set, it should be a parameterless function.  This
+  function will be called when the interpreter exits.  Only one
+  function may be installed in this way; to allow multiple functions
+  which will be called at termination, use the \refmodule{atexit}
+  module.  \note{The exit function is not called when the program is
+  killed by a signal, when a Python fatal internal error is detected,
+  or when \code{os._exit()} is called.}
+  \deprecated{2.4}{Use \refmodule{atexit} instead.}
+\end{datadesc}
+
+\begin{funcdesc}{getcheckinterval}{}
+  Return the interpreter's ``check interval'';
+  see \function{setcheckinterval()}.
+  \versionadded{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{getdefaultencoding}{}
+  Return the name of the current default string encoding used by the
+  Unicode implementation.
+  \versionadded{2.0}
+\end{funcdesc}
+
+\begin{funcdesc}{getdlopenflags}{}
+  Return the current value of the flags that are used for
+  \cfunction{dlopen()} calls. The flag constants are defined in the
+  \refmodule{dl} and \module{DLFCN} modules.
+  Availability: \UNIX.
+  \versionadded{2.2}
+\end{funcdesc}
+
+\begin{funcdesc}{getfilesystemencoding}{}
+  Return the name of the encoding used to convert Unicode filenames
+  into system file names, or \code{None} if the system default encoding
+  is used. The result value depends on the operating system:
+\begin{itemize}
+\item On Windows 9x, the encoding is ``mbcs''.
+\item On Mac OS X, the encoding is ``utf-8''.
+\item On \UNIX, the encoding is the user's preference
+      according to the result of nl_langinfo(CODESET), or \constant{None}
+      if the \code{nl_langinfo(CODESET)} failed.
+\item On Windows NT+, file names are Unicode natively, so no conversion
+      is performed. \function{getfilesystemencoding()} still returns
+      \code{'mbcs'}, as this is the encoding that applications should use
+      when they explicitly want to convert Unicode strings to byte strings
+      that are equivalent when used as file names.
+\end{itemize}
+  \versionadded{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{getrefcount}{object}
+  Return the reference count of the \var{object}.  The count returned
+  is generally one higher than you might expect, because it includes
+  the (temporary) reference as an argument to
+  \function{getrefcount()}.
+\end{funcdesc}
+
+\begin{funcdesc}{getrecursionlimit}{}
+  Return the current value of the recursion limit, the maximum depth
+  of the Python interpreter stack.  This limit prevents infinite
+  recursion from causing an overflow of the C stack and crashing
+  Python.  It can be set by \function{setrecursionlimit()}.
+\end{funcdesc}
+
+\begin{funcdesc}{_getframe}{\optional{depth}}
+  Return a frame object from the call stack.  If optional integer
+  \var{depth} is given, return the frame object that many calls below
+  the top of the stack.  If that is deeper than the call stack,
+  \exception{ValueError} is raised.  The default for \var{depth} is
+  zero, returning the frame at the top of the call stack.
+
+  This function should be used for internal and specialized purposes
+  only.
+\end{funcdesc}
+
+\begin{funcdesc}{getwindowsversion}{}
+  Return a tuple containing five components, describing the Windows
+  version currently running.  The elements are \var{major}, \var{minor},
+  \var{build}, \var{platform}, and \var{text}.  \var{text} contains
+  a string while all other values are integers.
+
+  \var{platform} may be one of the following values:
+
+  \begin{tableii}{l|l}{constant}{Constant}{Platform}
+    \lineii{0 (VER_PLATFORM_WIN32s)}       {Win32s on Windows 3.1}
+    \lineii{1 (VER_PLATFORM_WIN32_WINDOWS)}{Windows 95/98/ME}
+    \lineii{2 (VER_PLATFORM_WIN32_NT)}     {Windows NT/2000/XP}
+    \lineii{3 (VER_PLATFORM_WIN32_CE)}     {Windows CE}
+  \end{tableii}
+
+  This function wraps the Win32 \cfunction{GetVersionEx()} function;
+  see the Microsoft documentation for more information about these
+  fields.
+
+  Availability: Windows.
+  \versionadded{2.3}
+\end{funcdesc}
+
+\begin{datadesc}{hexversion}
+  The version number encoded as a single integer.  This is guaranteed
+  to increase with each version, including proper support for
+  non-production releases.  For example, to test that the Python
+  interpreter is at least version 1.5.2, use:
+
+\begin{verbatim}
+if sys.hexversion >= 0x010502F0:
+    # use some advanced feature
+    ...
+else:
+    # use an alternative implementation or warn the user
+    ...
+\end{verbatim}
+
+  This is called \samp{hexversion} since it only really looks
+  meaningful when viewed as the result of passing it to the built-in
+  \function{hex()} function.  The \code{version_info} value may be
+  used for a more human-friendly encoding of the same information.
+  \versionadded{1.5.2}
+\end{datadesc}
+
+\begin{datadesc}{last_type}
+\dataline{last_value}
+\dataline{last_traceback}
+  These three variables are not always defined; they are set when an
+  exception is not handled and the interpreter prints an error message
+  and a stack traceback.  Their intended use is to allow an
+  interactive user to import a debugger module and engage in
+  post-mortem debugging without having to re-execute the command that
+  caused the error.  (Typical use is \samp{import pdb; pdb.pm()} to
+  enter the post-mortem debugger; see chapter~\ref{debugger}, ``The
+  Python Debugger,'' for more information.)
+
+  The meaning of the variables is the same as that of the return
+  values from \function{exc_info()} above.  (Since there is only one
+  interactive thread, thread-safety is not a concern for these
+  variables, unlike for \code{exc_type} etc.)
+\end{datadesc}
+
+\begin{datadesc}{maxint}
+  The largest positive integer supported by Python's regular integer
+  type.  This is at least 2**31-1.  The largest negative integer is
+  \code{-maxint-1} --- the asymmetry results from the use of 2's
+  complement binary arithmetic.
+\end{datadesc}
+
+\begin{datadesc}{maxunicode}
+  An integer giving the largest supported code point for a Unicode
+  character.  The value of this depends on the configuration option
+  that specifies whether Unicode characters are stored as UCS-2 or
+  UCS-4.
+\end{datadesc}
+
+\begin{datadesc}{modules}
+  This is a dictionary that maps module names to modules which have
+  already been loaded.  This can be manipulated to force reloading of
+  modules and other tricks.  Note that removing a module from this
+  dictionary is \emph{not} the same as calling
+  \function{reload()}\bifuncindex{reload} on the corresponding module
+  object.
+\end{datadesc}
+
+\begin{datadesc}{path}
+\indexiii{module}{search}{path}
+  A list of strings that specifies the search path for modules.
+  Initialized from the environment variable \envvar{PYTHONPATH}, plus an
+  installation-dependent default.
+
+  As initialized upon program startup,
+  the first item of this list, \code{path[0]}, is the directory
+  containing the script that was used to invoke the Python
+  interpreter.  If the script directory is not available (e.g.  if the
+  interpreter is invoked interactively or if the script is read from
+  standard input), \code{path[0]} is the empty string, which directs
+  Python to search modules in the current directory first.  Notice
+  that the script directory is inserted \emph{before} the entries
+  inserted as a result of \envvar{PYTHONPATH}.
+
+  A program is free to modify this list for its own purposes.
+
+  \versionchanged[Unicode strings are no longer ignored]{2.3}
+\end{datadesc}
+
+\begin{datadesc}{platform}
+  This string contains a platform identifier, e.g. \code{'sunos5'} or
+  \code{'linux1'}.  This can be used to append platform-specific
+  components to \code{path}, for instance.
+\end{datadesc}
+
+\begin{datadesc}{prefix}
+  A string giving the site-specific directory prefix where the
+  platform independent Python files are installed; by default, this is
+  the string \code{'/usr/local'}.  This can be set at build time with
+  the \longprogramopt{prefix} argument to the \program{configure}
+  script.  The main collection of Python library modules is installed
+  in the directory \code{prefix + '/lib/python\var{version}'} while
+  the platform independent header files (all except \file{pyconfig.h})
+  are stored in \code{prefix + '/include/python\var{version}'}, where
+  \var{version} is equal to \code{version[:3]}.
+\end{datadesc}
+
+\begin{datadesc}{ps1}
+\dataline{ps2}
+\index{interpreter prompts}
+\index{prompts, interpreter}
+  Strings specifying the primary and secondary prompt of the
+  interpreter.  These are only defined if the interpreter is in
+  interactive mode.  Their initial values in this case are
+  \code{'>>>~'} and \code{'...~'}.  If a non-string object is
+  assigned to either variable, its \function{str()} is re-evaluated
+  each time the interpreter prepares to read a new interactive
+  command; this can be used to implement a dynamic prompt.
+\end{datadesc}
+
+\begin{funcdesc}{setcheckinterval}{interval}
+  Set the interpreter's ``check interval''.  This integer value
+  determines how often the interpreter checks for periodic things such
+  as thread switches and signal handlers.  The default is \code{100},
+  meaning the check is performed every 100 Python virtual instructions.
+  Setting it to a larger value may increase performance for programs
+  using threads.  Setting it to a value \code{<=} 0 checks every
+  virtual instruction, maximizing responsiveness as well as overhead.
+\end{funcdesc}
+
+\begin{funcdesc}{setdefaultencoding}{name}
+  Set the current default string encoding used by the Unicode
+  implementation.  If \var{name} does not match any available
+  encoding, \exception{LookupError} is raised.  This function is only
+  intended to be used by the \refmodule{site} module implementation
+  and, where needed, by \module{sitecustomize}.  Once used by the
+  \refmodule{site} module, it is removed from the \module{sys}
+  module's namespace.
+%  Note that \refmodule{site} is not imported if
+%  the \programopt{-S} option is passed to the interpreter, in which
+%  case this function will remain available.
+  \versionadded{2.0}
+\end{funcdesc}
+
+\begin{funcdesc}{setdlopenflags}{n}
+  Set the flags used by the interpreter for \cfunction{dlopen()}
+  calls, such as when the interpreter loads extension modules.  Among
+  other things, this will enable a lazy resolving of symbols when
+  importing a module, if called as \code{sys.setdlopenflags(0)}.  To
+  share symbols across extension modules, call as
+  \code{sys.setdlopenflags(dl.RTLD_NOW | dl.RTLD_GLOBAL)}.  Symbolic
+  names for the flag modules can be either found in the \refmodule{dl}
+  module, or in the \module{DLFCN} module. If \module{DLFCN} is not
+  available, it can be generated from \file{/usr/include/dlfcn.h}
+  using the \program{h2py} script.
+  Availability: \UNIX.
+  \versionadded{2.2}
+\end{funcdesc}
+
+\begin{funcdesc}{setprofile}{profilefunc}
+  Set the system's profile function,\index{profile function} which
+  allows you to implement a Python source code profiler in
+  Python.\index{profiler}  See chapter~\ref{profile} for more
+  information on the Python profiler.  The system's profile function
+  is called similarly to the system's trace function (see
+  \function{settrace()}), but it isn't called for each executed line
+  of code (only on call and return, but the return event is reported
+  even when an exception has been set).  The function is
+  thread-specific, but there is no way for the profiler to know about
+  context switches between threads, so it does not make sense to use
+  this in the presence of multiple threads.
+  Also, its return value is not used, so it can simply return
+  \code{None}.
+\end{funcdesc}
+
+\begin{funcdesc}{setrecursionlimit}{limit}
+  Set the maximum depth of the Python interpreter stack to
+  \var{limit}.  This limit prevents infinite recursion from causing an
+  overflow of the C stack and crashing Python.
+
+  The highest possible limit is platform-dependent.  A user may need
+  to set the limit higher when she has a program that requires deep
+  recursion and a platform that supports a higher limit.  This should
+  be done with care, because a too-high limit can lead to a crash.
+\end{funcdesc}
+
+\begin{funcdesc}{settrace}{tracefunc}
+  Set the system's trace function,\index{trace function} which allows
+  you to implement a Python source code debugger in Python.  See
+  section \ref{debugger-hooks}, ``How It Works,'' in the chapter on
+  the Python debugger.\index{debugger}  The function is
+  thread-specific; for a debugger to support multiple threads, it must
+  be registered using \function{settrace()} for each thread being
+  debugged.  \note{The \function{settrace()} function is intended only
+  for implementing debuggers, profilers, coverage tools and the like.
+  Its behavior is part of the implementation platform, rather than
+  part of the language definition, and thus may not be available in
+  all Python implementations.}
+\end{funcdesc}
+
+\begin{funcdesc}{settscdump}{on_flag}
+  Activate dumping of VM measurements using the Pentium timestamp
+  counter, if \var{on_flag} is true. Deactivate these dumps if
+  \var{on_flag} is off. The function is available only if Python
+  was compiled with \longprogramopt{with-tsc}. To understand the
+  output of this dump, read \file{Python/ceval.c} in the Python
+  sources.
+  \versionadded{2.4}
+\end{funcdesc}
+
+\begin{datadesc}{stdin}
+\dataline{stdout}
+\dataline{stderr}
+  File objects corresponding to the interpreter's standard input,
+  output and error streams.  \code{stdin} is used for all interpreter
+  input except for scripts but including calls to
+  \function{input()}\bifuncindex{input} and
+  \function{raw_input()}\bifuncindex{raw_input}.  \code{stdout} is
+  used for the output of \keyword{print} and expression statements and
+  for the prompts of \function{input()} and \function{raw_input()}.
+  The interpreter's own prompts and (almost all of) its error messages
+  go to \code{stderr}.  \code{stdout} and \code{stderr} needn't be
+  built-in file objects: any object is acceptable as long as it has a
+  \method{write()} method that takes a string argument.  (Changing
+  these objects doesn't affect the standard I/O streams of processes
+  executed by \function{os.popen()}, \function{os.system()} or the
+  \function{exec*()} family of functions in the \refmodule{os}
+  module.)
+\end{datadesc}
+
+\begin{datadesc}{__stdin__}
+\dataline{__stdout__}
+\dataline{__stderr__}
+  These objects contain the original values of \code{stdin},
+  \code{stderr} and \code{stdout} at the start of the program.  They
+  are used during finalization, and could be useful to restore the
+  actual files to known working file objects in case they have been
+  overwritten with a broken object.
+\end{datadesc}
+
+\begin{datadesc}{tracebacklimit}
+  When this variable is set to an integer value, it determines the
+  maximum number of levels of traceback information printed when an
+  unhandled exception occurs.  The default is \code{1000}.  When set
+  to \code{0} or less, all traceback information is suppressed and
+  only the exception type and value are printed.
+\end{datadesc}
+
+\begin{datadesc}{version}
+  A string containing the version number of the Python interpreter
+  plus additional information on the build number and compiler used.
+  It has a value of the form \code{'\var{version}
+  (\#\var{build_number}, \var{build_date}, \var{build_time})
+  [\var{compiler}]'}.  The first three characters are used to identify
+  the version in the installation directories (where appropriate on
+  each platform).  An example:
+
+\begin{verbatim}
+>>> import sys
+>>> sys.version
+'1.5.2 (#0 Apr 13 1999, 10:51:12) [MSC 32 bit (Intel)]'
+\end{verbatim}
+\end{datadesc}
+
+\begin{datadesc}{api_version}
+  The C API version for this interpreter.  Programmers may find this useful
+  when debugging version conflicts between Python and extension
+  modules. \versionadded{2.3}
+\end{datadesc}
+
+\begin{datadesc}{version_info}
+  A tuple containing the five components of the version number:
+  \var{major}, \var{minor}, \var{micro}, \var{releaselevel}, and
+  \var{serial}.  All values except \var{releaselevel} are integers;
+  the release level is \code{'alpha'}, \code{'beta'},
+  \code{'candidate'}, or \code{'final'}.  The \code{version_info}
+  value corresponding to the Python version 2.0 is \code{(2, 0, 0,
+  'final', 0)}.
+  \versionadded{2.0}
+\end{datadesc}
+
+\begin{datadesc}{warnoptions}
+  This is an implementation detail of the warnings framework; do not
+  modify this value.  Refer to the \refmodule{warnings} module for
+  more information on the warnings framework.
+\end{datadesc}
+
+\begin{datadesc}{winver}
+  The version number used to form registry keys on Windows platforms.
+  This is stored as string resource 1000 in the Python DLL.  The value
+  is normally the first three characters of \constant{version}.  It is
+  provided in the \module{sys} module for informational purposes;
+  modifying this value has no effect on the registry keys used by
+  Python.
+  Availability: Windows.
+\end{datadesc}
+
+
+\begin{seealso}
+  \seemodule{site}
+    {This describes how to use .pth files to extend \code{sys.path}.}
+\end{seealso}

Added: vendor/Python/current/Doc/lib/libsyslog.tex
===================================================================
--- vendor/Python/current/Doc/lib/libsyslog.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libsyslog.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,76 @@
+\section{\module{syslog} ---
+         \UNIX{} syslog library routines}
+
+\declaremodule{builtin}{syslog}
+  \platform{Unix}
+\modulesynopsis{An interface to the \UNIX\ syslog library routines.}
+
+
+This module provides an interface to the \UNIX{} \code{syslog} library
+routines.  Refer to the \UNIX{} manual pages for a detailed description
+of the \code{syslog} facility.
+
+The module defines the following functions:
+
+
+\begin{funcdesc}{syslog}{\optional{priority,} message}
+Send the string \var{message} to the system logger.  A trailing
+newline is added if necessary.  Each message is tagged with a priority
+composed of a \var{facility} and a \var{level}.  The optional
+\var{priority} argument, which defaults to \constant{LOG_INFO},
+determines the message priority.  If the facility is not encoded in
+\var{priority} using logical-or (\code{LOG_INFO | LOG_USER}), the
+value given in the \function{openlog()} call is used.
+\end{funcdesc}
+
+\begin{funcdesc}{openlog}{ident\optional{, logopt\optional{, facility}}}
+Logging options other than the defaults can be set by explicitly
+opening the log file with \function{openlog()} prior to calling
+\function{syslog()}.  The defaults are (usually) \var{ident} =
+\code{'syslog'}, \var{logopt} = \code{0}, \var{facility} =
+\constant{LOG_USER}.  The \var{ident} argument is a string which is
+prepended to every message.  The optional \var{logopt} argument is a
+bit field - see below for possible values to combine.  The optional
+\var{facility} argument sets the default facility for messages which
+do not have a facility explicitly encoded.
+\end{funcdesc}
+
+\begin{funcdesc}{closelog}{}
+Close the log file.
+\end{funcdesc}
+
+\begin{funcdesc}{setlogmask}{maskpri}
+Set the priority mask to \var{maskpri} and return the
+previous mask value.  Calls to \function{syslog()} with a priority
+level not set in \var{maskpri} are ignored.  The default is to log all
+priorities.  The function \code{LOG_MASK(\var{pri})} calculates the
+mask for the individual priority \var{pri}.  The function
+\code{LOG_UPTO(\var{pri})} calculates the mask for all priorities up
+to and including \var{pri}.
+\end{funcdesc}
+
+
+The module defines the following constants:
+
+\begin{description}
+
+\item[Priority levels (high to low):]
+
+\constant{LOG_EMERG}, \constant{LOG_ALERT}, \constant{LOG_CRIT},
+\constant{LOG_ERR}, \constant{LOG_WARNING}, \constant{LOG_NOTICE},
+\constant{LOG_INFO}, \constant{LOG_DEBUG}.
+
+\item[Facilities:]
+
+\constant{LOG_KERN}, \constant{LOG_USER}, \constant{LOG_MAIL},
+\constant{LOG_DAEMON}, \constant{LOG_AUTH}, \constant{LOG_LPR},
+\constant{LOG_NEWS}, \constant{LOG_UUCP}, \constant{LOG_CRON} and
+\constant{LOG_LOCAL0} to \constant{LOG_LOCAL7}.
+
+\item[Log options:]
+
+\constant{LOG_PID}, \constant{LOG_CONS}, \constant{LOG_NDELAY},
+\constant{LOG_NOWAIT} and \constant{LOG_PERROR} if defined in
+\code{<syslog.h>}.
+
+\end{description}

Added: vendor/Python/current/Doc/lib/libtabnanny.tex
===================================================================
--- vendor/Python/current/Doc/lib/libtabnanny.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libtabnanny.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,62 @@
+\section{\module{tabnanny} ---
+         Detection of ambiguous indentation}
+
+% rudimentary documentation based on module comments, by Peter Funk
+% <pf at artcom-gmbh.de>
+
+\declaremodule{standard}{tabnanny}
+\modulesynopsis{Tool for detecting white space related problems
+                in Python source files in a directory tree.}
+\moduleauthor{Tim Peters}{tim_one at users.sourceforge.net}
+\sectionauthor{Peter Funk}{pf at artcom-gmbh.de}
+
+For the time being this module is intended to be called as a script.
+However it is possible to import it into an IDE and use the function
+\function{check()} described below.
+
+\warning{The API provided by this module is likely to change 
+in future releases; such changes may not be backward compatible.}
+
+\begin{funcdesc}{check}{file_or_dir}
+  If \var{file_or_dir} is a directory and not a symbolic link, then
+  recursively descend the directory tree named by \var{file_or_dir},
+  checking all \file{.py} files along the way.  If \var{file_or_dir}
+  is an ordinary Python source file, it is checked for whitespace
+  related problems.  The diagnostic messages are written to standard
+  output using the print statement.
+\end{funcdesc}
+
+
+\begin{datadesc}{verbose}
+  Flag indicating whether to print verbose messages.
+  This is incremented by the \code{-v} option if called as a script.
+\end{datadesc}
+
+
+\begin{datadesc}{filename_only}
+  Flag indicating whether to print only the filenames of files
+  containing whitespace related problems.  This is set to true by the
+  \code{-q} option if called as a script.
+\end{datadesc}
+
+
+\begin{excdesc}{NannyNag}
+  Raised by \function{tokeneater()} if detecting an ambiguous indent.
+  Captured and handled in \function{check()}.
+\end{excdesc}
+
+
+\begin{funcdesc}{tokeneater}{type, token, start, end, line}
+  This function is used by \function{check()} as a callback parameter to
+  the function \function{tokenize.tokenize()}.
+\end{funcdesc}
+
+% XXX FIXME: Document \function{errprint},
+%    \function{format_witnesses} \class{Whitespace}
+%    check_equal, indents
+%    \function{reset_globals}
+
+\begin{seealso}
+  \seemodule{tokenize}{Lexical scanner for Python source code.}
+  % XXX may be add a reference to IDLE?
+\end{seealso}

Added: vendor/Python/current/Doc/lib/libtarfile.tex
===================================================================
--- vendor/Python/current/Doc/lib/libtarfile.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libtarfile.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,497 @@
+\section{\module{tarfile} --- Read and write tar archive files}
+
+\declaremodule{standard}{tarfile}
+\modulesynopsis{Read and write tar-format archive files.}
+\versionadded{2.3}
+
+\moduleauthor{Lars Gust\"abel}{lars at gustaebel.de}
+\sectionauthor{Lars Gust\"abel}{lars at gustaebel.de}
+
+The \module{tarfile} module makes it possible to read and create tar archives.
+Some facts and figures:
+
+\begin{itemize}
+\item reads and writes \module{gzip} and \module{bzip2} compressed archives.
+\item creates \POSIX{} 1003.1-1990 compliant or GNU tar compatible archives.
+\item reads GNU tar extensions \emph{longname}, \emph{longlink} and
+      \emph{sparse}.
+\item stores pathnames of unlimited length using GNU tar extensions.
+\item handles directories, regular files, hardlinks, symbolic links, fifos,
+      character devices and block devices and is able to acquire and
+      restore file information like timestamp, access permissions and owner.
+\item can handle tape devices.
+\end{itemize}
+
+\begin{funcdesc}{open}{\optional{name\optional{, mode
+                       \optional{, fileobj\optional{, bufsize}}}}}
+    Return a \class{TarFile} object for the pathname \var{name}.
+    For detailed information on \class{TarFile} objects,
+    see \citetitle{TarFile Objects} (section \ref{tarfile-objects}).
+
+    \var{mode} has to be a string of the form \code{'filemode[:compression]'},
+    it defaults to \code{'r'}. Here is a full list of mode combinations:
+
+    \begin{tableii}{c|l}{code}{mode}{action}
+    \lineii{'r' or 'r:*'}{Open for reading with transparent compression (recommended).}
+    \lineii{'r:'}{Open for reading exclusively without compression.}
+    \lineii{'r:gz'}{Open for reading with gzip compression.}
+    \lineii{'r:bz2'}{Open for reading with bzip2 compression.}
+    \lineii{'a' or 'a:'}{Open for appending with no compression.}
+    \lineii{'w' or 'w:'}{Open for uncompressed writing.}
+    \lineii{'w:gz'}{Open for gzip compressed writing.}
+    \lineii{'w:bz2'}{Open for bzip2 compressed writing.}
+    \end{tableii}
+
+    Note that \code{'a:gz'} or \code{'a:bz2'} is not possible.
+    If \var{mode} is not suitable to open a certain (compressed) file for
+    reading, \exception{ReadError} is raised. Use \var{mode} \code{'r'} to
+    avoid this.  If a compression method is not supported,
+    \exception{CompressionError} is raised.
+
+    If \var{fileobj} is specified, it is used as an alternative to a file
+    object opened for \var{name}. It is supposed to be at position 0.
+
+    For special purposes, there is a second format for \var{mode}:
+    \code{'filemode|[compression]'}.  \function{open()} will return a
+    \class{TarFile} object that processes its data as a stream of
+    blocks.  No random seeking will be done on the file. If given,
+    \var{fileobj} may be any object that has a \method{read()} or
+    \method{write()} method (depending on the \var{mode}).
+    \var{bufsize} specifies the blocksize and defaults to \code{20 *
+    512} bytes. Use this variant in combination with
+    e.g. \code{sys.stdin}, a socket file object or a tape device.
+    However, such a \class{TarFile} object is limited in that it does
+    not allow to be accessed randomly, see ``Examples''
+    (section~\ref{tar-examples}).  The currently possible modes:
+
+    \begin{tableii}{c|l}{code}{Mode}{Action}
+    \lineii{'r|*'}{Open a \emph{stream} of tar blocks for reading with transparent compression.}
+    \lineii{'r|'}{Open a \emph{stream} of uncompressed tar blocks for reading.}
+    \lineii{'r|gz'}{Open a gzip compressed \emph{stream} for reading.}
+    \lineii{'r|bz2'}{Open a bzip2 compressed \emph{stream} for reading.}
+    \lineii{'w|'}{Open an uncompressed \emph{stream} for writing.}
+    \lineii{'w|gz'}{Open an gzip compressed \emph{stream} for writing.}
+    \lineii{'w|bz2'}{Open an bzip2 compressed \emph{stream} for writing.}
+    \end{tableii}
+\end{funcdesc}
+
+\begin{classdesc*}{TarFile}
+    Class for reading and writing tar archives. Do not use this
+    class directly, better use \function{open()} instead.
+    See ``TarFile Objects'' (section~\ref{tarfile-objects}).
+\end{classdesc*}
+
+\begin{funcdesc}{is_tarfile}{name}
+    Return \constant{True} if \var{name} is a tar archive file, that
+    the \module{tarfile} module can read.
+\end{funcdesc}
+
+\begin{classdesc}{TarFileCompat}{filename\optional{, mode\optional{,
+                                 compression}}}
+    Class for limited access to tar archives with a
+    \refmodule{zipfile}-like interface. Please consult the
+    documentation of the \refmodule{zipfile} module for more details.
+    \var{compression} must be one of the following constants:
+    \begin{datadesc}{TAR_PLAIN}
+        Constant for an uncompressed tar archive.
+    \end{datadesc}
+    \begin{datadesc}{TAR_GZIPPED}
+        Constant for a \refmodule{gzip} compressed tar archive.
+    \end{datadesc}
+\end{classdesc}
+
+\begin{excdesc}{TarError}
+    Base class for all \module{tarfile} exceptions.
+\end{excdesc}
+
+\begin{excdesc}{ReadError}
+    Is raised when a tar archive is opened, that either cannot be handled by
+    the \module{tarfile} module or is somehow invalid.
+\end{excdesc}
+
+\begin{excdesc}{CompressionError}
+    Is raised when a compression method is not supported or when the data
+    cannot be decoded properly.
+\end{excdesc}
+
+\begin{excdesc}{StreamError}
+    Is raised for the limitations that are typical for stream-like
+    \class{TarFile} objects.
+\end{excdesc}
+
+\begin{excdesc}{ExtractError}
+    Is raised for \emph{non-fatal} errors when using \method{extract()}, but
+    only if \member{TarFile.errorlevel}\code{ == 2}.
+\end{excdesc}
+
+\begin{seealso}
+    \seemodule{zipfile}{Documentation of the \refmodule{zipfile}
+    standard module.}
+
+    \seetitle[http://www.gnu.org/software/tar/manual/html_node/tar_134.html\#SEC134]
+    {GNU tar manual, Basic Tar Format}{Documentation for tar archive files,
+    including GNU tar extensions.}
+\end{seealso}
+
+%-----------------
+% TarFile Objects
+%-----------------
+
+\subsection{TarFile Objects \label{tarfile-objects}}
+
+The \class{TarFile} object provides an interface to a tar archive. A tar
+archive is a sequence of blocks. An archive member (a stored file) is made up
+of a header block followed by data blocks. It is possible, to store a file in a
+tar archive several times. Each archive member is represented by a
+\class{TarInfo} object, see \citetitle{TarInfo Objects} (section
+\ref{tarinfo-objects}) for details.
+
+\begin{classdesc}{TarFile}{\optional{name
+                           \optional{, mode\optional{, fileobj}}}}
+    Open an \emph{(uncompressed)} tar archive \var{name}.
+    \var{mode} is either \code{'r'} to read from an existing archive,
+    \code{'a'} to append data to an existing file or \code{'w'} to create a new
+    file overwriting an existing one. \var{mode} defaults to \code{'r'}.
+
+    If \var{fileobj} is given, it is used for reading or writing data.
+    If it can be determined, \var{mode} is overridden by \var{fileobj}'s mode.
+    \var{fileobj} will be used from position 0.
+    \begin{notice}
+        \var{fileobj} is not closed, when \class{TarFile} is closed.
+    \end{notice}
+\end{classdesc}
+
+\begin{methoddesc}{open}{...}
+    Alternative constructor. The \function{open()} function on module level is
+    actually a shortcut to this classmethod. See section~\ref{module-tarfile}
+    for details.
+\end{methoddesc}
+
+\begin{methoddesc}{getmember}{name}
+    Return a \class{TarInfo} object for member \var{name}. If \var{name} can
+    not be found in the archive, \exception{KeyError} is raised.
+    \begin{notice}
+        If a member occurs more than once in the archive, its last
+        occurrence is assumed to be the most up-to-date version.
+    \end{notice}
+\end{methoddesc}
+
+\begin{methoddesc}{getmembers}{}
+    Return the members of the archive as a list of \class{TarInfo} objects.
+    The list has the same order as the members in the archive.
+\end{methoddesc}
+
+\begin{methoddesc}{getnames}{}
+    Return the members as a list of their names. It has the same order as
+    the list returned by \method{getmembers()}.
+\end{methoddesc}
+
+\begin{methoddesc}{list}{verbose=True}
+    Print a table of contents to \code{sys.stdout}. If \var{verbose} is
+    \constant{False}, only the names of the members are printed. If it is
+    \constant{True}, output similar to that of \program{ls -l} is produced.
+\end{methoddesc}
+
+\begin{methoddesc}{next}{}
+    Return the next member of the archive as a \class{TarInfo} object, when
+    \class{TarFile} is opened for reading. Return \code{None} if there is no
+    more available.
+\end{methoddesc}
+
+\begin{methoddesc}{extractall}{\optional{path\optional{, members}}}
+    Extract all members from the archive to the current working directory
+    or directory \var{path}. If optional \var{members} is given, it must be
+    a subset of the list returned by \method{getmembers()}.
+    Directory informations like owner, modification time and permissions are
+    set after all members have been extracted. This is done to work around two
+    problems: A directory's modification time is reset each time a file is
+    created in it. And, if a directory's permissions do not allow writing,
+    extracting files to it will fail.
+    \versionadded{2.5}
+\end{methoddesc}
+
+\begin{methoddesc}{extract}{member\optional{, path}}
+    Extract a member from the archive to the current working directory,
+    using its full name. Its file information is extracted as accurately as
+    possible.
+    \var{member} may be a filename or a \class{TarInfo} object.
+    You can specify a different directory using \var{path}.
+    \begin{notice}
+    Because the \method{extract()} method allows random access to a tar
+    archive there are some issues you must take care of yourself. See the
+    description for \method{extractall()} above.
+    \end{notice}
+\end{methoddesc}
+
+\begin{methoddesc}{extractfile}{member}
+    Extract a member from the archive as a file object.
+    \var{member} may be a filename or a \class{TarInfo} object.
+    If \var{member} is a regular file, a file-like object is returned.
+    If \var{member} is a link, a file-like object is constructed from the
+    link's target.
+    If \var{member} is none of the above, \code{None} is returned.
+    \begin{notice}
+        The file-like object is read-only and provides the following methods:
+        \method{read()}, \method{readline()}, \method{readlines()},
+        \method{seek()}, \method{tell()}.
+    \end{notice}
+\end{methoddesc}
+
+\begin{methoddesc}{add}{name\optional{, arcname\optional{, recursive}}}
+    Add the file \var{name} to the archive. \var{name} may be any type
+    of file (directory, fifo, symbolic link, etc.).
+    If given, \var{arcname} specifies an alternative name for the file in the
+    archive. Directories are added recursively by default.
+    This can be avoided by setting \var{recursive} to \constant{False};
+    the default is \constant{True}.
+\end{methoddesc}
+
+\begin{methoddesc}{addfile}{tarinfo\optional{, fileobj}}
+    Add the \class{TarInfo} object \var{tarinfo} to the archive.
+    If \var{fileobj} is given, \code{\var{tarinfo}.size} bytes are read
+    from it and added to the archive.  You can create \class{TarInfo} objects
+    using \method{gettarinfo()}.
+    \begin{notice}
+    On Windows platforms, \var{fileobj} should always be opened with mode
+    \code{'rb'} to avoid irritation about the file size.
+    \end{notice}
+\end{methoddesc}
+
+\begin{methoddesc}{gettarinfo}{\optional{name\optional{,
+                               arcname\optional{, fileobj}}}}
+    Create a \class{TarInfo} object for either the file \var{name} or
+    the file object \var{fileobj} (using \function{os.fstat()} on its
+    file descriptor).  You can modify some of the \class{TarInfo}'s
+    attributes before you add it using \method{addfile()}.  If given,
+    \var{arcname} specifies an alternative name for the file in the
+    archive.
+\end{methoddesc}
+
+\begin{methoddesc}{close}{}
+    Close the \class{TarFile}. In write mode, two finishing zero
+    blocks are appended to the archive.
+\end{methoddesc}
+
+\begin{memberdesc}{posix}
+    If true, create a \POSIX{} 1003.1-1990 compliant archive. GNU
+    extensions are not used, because they are not part of the \POSIX{}
+    standard.  This limits the length of filenames to at most 256,
+    link names to 100 characters and the maximum file size to 8
+    gigabytes. A \exception{ValueError} is raised if a file exceeds
+    this limit.  If false, create a GNU tar compatible archive.  It
+    will not be \POSIX{} compliant, but can store files without any
+    of the above restrictions. 
+    \versionchanged[\var{posix} defaults to \constant{False}]{2.4}
+\end{memberdesc}
+
+\begin{memberdesc}{dereference}
+    If false, add symbolic and hard links to archive. If true, add the
+    content of the target files to the archive.  This has no effect on
+    systems that do not support symbolic links.
+\end{memberdesc}
+
+\begin{memberdesc}{ignore_zeros}
+    If false, treat an empty block as the end of the archive. If true,
+    skip empty (and invalid) blocks and try to get as many members as
+    possible. This is only useful for concatenated or damaged
+    archives.
+\end{memberdesc}
+
+\begin{memberdesc}{debug=0}
+    To be set from \code{0} (no debug messages; the default) up to
+    \code{3} (all debug messages). The messages are written to
+    \code{sys.stderr}.
+\end{memberdesc}
+
+\begin{memberdesc}{errorlevel}
+    If \code{0} (the default), all errors are ignored when using
+    \method{extract()}.  Nevertheless, they appear as error messages
+    in the debug output, when debugging is enabled.  If \code{1}, all
+    \emph{fatal} errors are raised as \exception{OSError} or
+    \exception{IOError} exceptions.  If \code{2}, all \emph{non-fatal}
+    errors are raised as \exception{TarError} exceptions as well.
+\end{memberdesc}
+
+%-----------------
+% TarInfo Objects
+%-----------------
+
+\subsection{TarInfo Objects \label{tarinfo-objects}}
+
+A \class{TarInfo} object represents one member in a
+\class{TarFile}. Aside from storing all required attributes of a file
+(like file type, size, time, permissions, owner etc.), it provides
+some useful methods to determine its type. It does \emph{not} contain
+the file's data itself.
+
+\class{TarInfo} objects are returned by \class{TarFile}'s methods
+\method{getmember()}, \method{getmembers()} and \method{gettarinfo()}.
+
+\begin{classdesc}{TarInfo}{\optional{name}}
+    Create a \class{TarInfo} object.
+\end{classdesc}
+
+\begin{methoddesc}{frombuf}{}
+    Create and return a \class{TarInfo} object from a string buffer.
+\end{methoddesc}
+
+\begin{methoddesc}{tobuf}{posix}
+    Create a string buffer from a \class{TarInfo} object.
+    See \class{TarFile}'s \member{posix} attribute for information
+    on the \var{posix} argument. It defaults to \constant{False}.
+
+    \versionadded[The \var{posix} parameter]{2.5}
+\end{methoddesc}
+
+A \code{TarInfo} object has the following public data attributes:
+
+\begin{memberdesc}{name}
+    Name of the archive member.
+\end{memberdesc}
+
+\begin{memberdesc}{size}
+    Size in bytes.
+\end{memberdesc}
+
+\begin{memberdesc}{mtime}
+    Time of last modification.
+\end{memberdesc}
+
+\begin{memberdesc}{mode}
+    Permission bits.
+\end{memberdesc}
+
+\begin{memberdesc}{type}
+    File type.  \var{type} is usually one of these constants:
+    \constant{REGTYPE}, \constant{AREGTYPE}, \constant{LNKTYPE},
+    \constant{SYMTYPE}, \constant{DIRTYPE}, \constant{FIFOTYPE},
+    \constant{CONTTYPE}, \constant{CHRTYPE}, \constant{BLKTYPE},
+    \constant{GNUTYPE_SPARSE}.  To determine the type of a
+    \class{TarInfo} object more conveniently, use the \code{is_*()}
+    methods below.
+\end{memberdesc}
+
+\begin{memberdesc}{linkname}
+    Name of the target file name, which is only present in
+    \class{TarInfo} objects of type \constant{LNKTYPE} and
+    \constant{SYMTYPE}.
+\end{memberdesc}
+
+\begin{memberdesc}{uid}
+    User ID of the user who originally stored this member.
+\end{memberdesc}
+
+\begin{memberdesc}{gid}
+    Group ID of the user who originally stored this member.
+\end{memberdesc}
+
+\begin{memberdesc}{uname}
+    User name.
+\end{memberdesc}
+
+\begin{memberdesc}{gname}
+    Group name.
+\end{memberdesc}
+
+A \class{TarInfo} object also provides some convenient query methods:
+
+\begin{methoddesc}{isfile}{}
+    Return \constant{True} if the \class{Tarinfo} object is a regular
+    file.
+\end{methoddesc}
+
+\begin{methoddesc}{isreg}{}
+    Same as \method{isfile()}.
+\end{methoddesc}
+
+\begin{methoddesc}{isdir}{}
+    Return \constant{True} if it is a directory.
+\end{methoddesc}
+
+\begin{methoddesc}{issym}{}
+    Return \constant{True} if it is a symbolic link.
+\end{methoddesc}
+
+\begin{methoddesc}{islnk}{}
+    Return \constant{True} if it is a hard link.
+\end{methoddesc}
+
+\begin{methoddesc}{ischr}{}
+    Return \constant{True} if it is a character device.
+\end{methoddesc}
+
+\begin{methoddesc}{isblk}{}
+    Return \constant{True} if it is a block device.
+\end{methoddesc}
+
+\begin{methoddesc}{isfifo}{}
+    Return \constant{True} if it is a FIFO.
+\end{methoddesc}
+
+\begin{methoddesc}{isdev}{}
+    Return \constant{True} if it is one of character device, block
+    device or FIFO.
+\end{methoddesc}
+
+%------------------------
+% Examples
+%------------------------
+
+\subsection{Examples \label{tar-examples}}
+
+How to extract an entire tar archive to the current working directory:
+\begin{verbatim}
+import tarfile
+tar = tarfile.open("sample.tar.gz")
+tar.extractall()
+tar.close()
+\end{verbatim}
+
+How to create an uncompressed tar archive from a list of filenames:
+\begin{verbatim}
+import tarfile
+tar = tarfile.open("sample.tar", "w")
+for name in ["foo", "bar", "quux"]:
+    tar.add(name)
+tar.close()
+\end{verbatim}
+
+How to read a gzip compressed tar archive and display some member information:
+\begin{verbatim}
+import tarfile
+tar = tarfile.open("sample.tar.gz", "r:gz")
+for tarinfo in tar:
+    print tarinfo.name, "is", tarinfo.size, "bytes in size and is",
+    if tarinfo.isreg():
+        print "a regular file."
+    elif tarinfo.isdir():
+        print "a directory."
+    else:
+        print "something else."
+tar.close()
+\end{verbatim}
+
+How to create a tar archive with faked information:
+\begin{verbatim}
+import tarfile
+tar = tarfile.open("sample.tar.gz", "w:gz")
+for name in namelist:
+    tarinfo = tar.gettarinfo(name, "fakeproj-1.0/" + name)
+    tarinfo.uid = 123
+    tarinfo.gid = 456
+    tarinfo.uname = "johndoe"
+    tarinfo.gname = "fake"
+    tar.addfile(tarinfo, file(name))
+tar.close()
+\end{verbatim}
+
+The \emph{only} way to extract an uncompressed tar stream from
+\code{sys.stdin}:
+\begin{verbatim}
+import sys
+import tarfile
+tar = tarfile.open(mode="r|", fileobj=sys.stdin)
+for tarinfo in tar:
+    tar.extract(tarinfo)
+tar.close()
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/libtelnetlib.tex
===================================================================
--- vendor/Python/current/Doc/lib/libtelnetlib.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libtelnetlib.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,215 @@
+\section{\module{telnetlib} ---
+         Telnet client}
+
+\declaremodule{standard}{telnetlib}
+\modulesynopsis{Telnet client class.}
+\sectionauthor{Skip Montanaro}{skip at mojam.com}
+
+\index{protocol!Telnet}
+
+The \module{telnetlib} module provides a \class{Telnet} class that
+implements the Telnet protocol.  See \rfc{854} for details about the
+protocol. In addition, it provides symbolic constants for the protocol
+characters (see below), and for the telnet options. The
+symbolic names of the telnet options follow the definitions in
+\code{arpa/telnet.h}, with the leading \code{TELOPT_} removed. For
+symbolic names of options which are traditionally not included in
+\code{arpa/telnet.h}, see the module source itself.
+
+The symbolic constants for the telnet commands are: IAC, DONT, DO,
+WONT, WILL, SE (Subnegotiation End), NOP (No Operation), DM (Data
+Mark), BRK (Break), IP (Interrupt process), AO (Abort output), AYT
+(Are You There), EC (Erase Character), EL (Erase Line), GA (Go Ahead),
+SB (Subnegotiation Begin).
+
+
+\begin{classdesc}{Telnet}{\optional{host\optional{, port}}}
+\class{Telnet} represents a connection to a Telnet server. The
+instance is initially not connected by default; the \method{open()}
+method must be used to establish a connection.  Alternatively, the
+host name and optional port number can be passed to the constructor,
+to, in which case the connection to the server will be established
+before the constructor returns.
+
+Do not reopen an already connected instance.
+
+This class has many \method{read_*()} methods.  Note that some of them 
+raise \exception{EOFError} when the end of the connection is read,
+because they can return an empty string for other reasons.  See the
+individual descriptions below.
+\end{classdesc}
+
+
+\begin{seealso}
+  \seerfc{854}{Telnet Protocol Specification}{
+          Definition of the Telnet protocol.}
+\end{seealso}
+
+
+
+\subsection{Telnet Objects \label{telnet-objects}}
+
+\class{Telnet} instances have the following methods:
+
+
+\begin{methoddesc}{read_until}{expected\optional{, timeout}}
+Read until a given string, \var{expected}, is encountered or until
+\var{timeout} seconds have passed.
+
+When no match is found, return whatever is available instead,
+possibly the empty string.  Raise \exception{EOFError} if the connection
+is closed and no cooked data is available.
+\end{methoddesc}
+
+\begin{methoddesc}{read_all}{}
+Read all data until \EOF; block until connection closed.
+\end{methoddesc}
+
+\begin{methoddesc}{read_some}{}
+Read at least one byte of cooked data unless \EOF{} is hit.
+Return \code{''} if \EOF{} is hit.  Block if no data is immediately
+available.
+\end{methoddesc}
+
+\begin{methoddesc}{read_very_eager}{}
+Read everything that can be without blocking in I/O (eager).
+
+Raise \exception{EOFError} if connection closed and no cooked data
+available.  Return \code{''} if no cooked data available otherwise.
+Do not block unless in the midst of an IAC sequence.
+\end{methoddesc}
+
+\begin{methoddesc}{read_eager}{}
+Read readily available data.
+
+Raise \exception{EOFError} if connection closed and no cooked data
+available.  Return \code{''} if no cooked data available otherwise.
+Do not block unless in the midst of an IAC sequence.
+\end{methoddesc}
+
+\begin{methoddesc}{read_lazy}{}
+Process and return data already in the queues (lazy).
+
+Raise \exception{EOFError} if connection closed and no data available.
+Return \code{''} if no cooked data available otherwise.  Do not block
+unless in the midst of an IAC sequence.
+\end{methoddesc}
+
+\begin{methoddesc}{read_very_lazy}{}
+Return any data available in the cooked queue (very lazy).
+
+Raise \exception{EOFError} if connection closed and no data available.
+Return \code{''} if no cooked data available otherwise.  This method
+never blocks.
+\end{methoddesc}
+
+\begin{methoddesc}{read_sb_data}{}
+Return the data collected between a SB/SE pair (suboption begin/end).
+The callback should access these data when it was invoked with a
+\code{SE} command. This method never blocks.
+
+\versionadded{2.3}
+\end{methoddesc}
+
+\begin{methoddesc}{open}{host\optional{, port}}
+Connect to a host.
+The optional second argument is the port number, which
+defaults to the standard Telnet port (23).
+
+Do not try to reopen an already connected instance.
+\end{methoddesc}
+
+\begin{methoddesc}{msg}{msg\optional{, *args}}
+Print a debug message when the debug level is \code{>} 0.
+If extra arguments are present, they are substituted in the
+message using the standard string formatting operator.
+\end{methoddesc}
+
+\begin{methoddesc}{set_debuglevel}{debuglevel}
+Set the debug level.  The higher the value of \var{debuglevel}, the
+more debug output you get (on \code{sys.stdout}).
+\end{methoddesc}
+
+\begin{methoddesc}{close}{}
+Close the connection.
+\end{methoddesc}
+
+\begin{methoddesc}{get_socket}{}
+Return the socket object used internally.
+\end{methoddesc}
+
+\begin{methoddesc}{fileno}{}
+Return the file descriptor of the socket object used internally.
+\end{methoddesc}
+
+\begin{methoddesc}{write}{buffer}
+Write a string to the socket, doubling any IAC characters.
+This can block if the connection is blocked.  May raise
+\exception{socket.error} if the connection is closed.
+\end{methoddesc}
+
+\begin{methoddesc}{interact}{}
+Interaction function, emulates a very dumb Telnet client.
+\end{methoddesc}
+
+\begin{methoddesc}{mt_interact}{}
+Multithreaded version of \method{interact()}.
+\end{methoddesc}
+
+\begin{methoddesc}{expect}{list\optional{, timeout}}
+Read until one from a list of a regular expressions matches.
+
+The first argument is a list of regular expressions, either
+compiled (\class{re.RegexObject} instances) or uncompiled (strings).
+The optional second argument is a timeout, in seconds; the default
+is to block indefinitely.
+
+Return a tuple of three items: the index in the list of the
+first regular expression that matches; the match object
+returned; and the text read up till and including the match.
+
+If end of file is found and no text was read, raise
+\exception{EOFError}.  Otherwise, when nothing matches, return
+\code{(-1, None, \var{text})} where \var{text} is the text received so
+far (may be the empty string if a timeout happened).
+
+If a regular expression ends with a greedy match (such as \regexp{.*})
+or if more than one expression can match the same input, the
+results are indeterministic, and may depend on the I/O timing.
+\end{methoddesc}
+
+\begin{methoddesc}{set_option_negotiation_callback}{callback}
+Each time a telnet option is read on the input flow, this
+\var{callback} (if set) is called with the following parameters :
+callback(telnet socket, command (DO/DONT/WILL/WONT), option).  No other
+action is done afterwards by telnetlib.
+\end{methoddesc}
+
+
+\subsection{Telnet Example \label{telnet-example}}
+\sectionauthor{Peter Funk}{pf at artcom-gmbh.de}
+
+A simple example illustrating typical use:
+
+\begin{verbatim}
+import getpass
+import sys
+import telnetlib
+
+HOST = "localhost"
+user = raw_input("Enter your remote account: ")
+password = getpass.getpass()
+
+tn = telnetlib.Telnet(HOST)
+
+tn.read_until("login: ")
+tn.write(user + "\n")
+if password:
+    tn.read_until("Password: ")
+    tn.write(password + "\n")
+
+tn.write("ls\n")
+tn.write("exit\n")
+
+print tn.read_all()
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/libtempfile.tex
===================================================================
--- vendor/Python/current/Doc/lib/libtempfile.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libtempfile.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,194 @@
+\section{\module{tempfile} ---
+         Generate temporary files and directories}
+\sectionauthor{Zack Weinberg}{zack at codesourcery.com}
+
+\declaremodule{standard}{tempfile}
+\modulesynopsis{Generate temporary files and directories.}
+
+\indexii{temporary}{file name}
+\indexii{temporary}{file}
+
+This module generates temporary files and directories.  It works on
+all supported platforms.
+
+In version 2.3 of Python, this module was overhauled for enhanced
+security.  It now provides three new functions,
+\function{NamedTemporaryFile()}, \function{mkstemp()}, and
+\function{mkdtemp()}, which should eliminate all remaining need to use
+the insecure \function{mktemp()} function.  Temporary file names created
+by this module no longer contain the process ID; instead a string of
+six random characters is used.
+
+Also, all the user-callable functions now take additional arguments
+which allow direct control over the location and name of temporary
+files.  It is no longer necessary to use the global \var{tempdir} and
+\var{template} variables.  To maintain backward compatibility, the
+argument order is somewhat odd; it is recommended to use keyword
+arguments for clarity.
+
+The module defines the following user-callable functions:
+
+\begin{funcdesc}{TemporaryFile}{\optional{mode=\code{'w+b'}\optional{,
+                                bufsize=\code{-1}\optional{,
+                                suffix\optional{, prefix\optional{, dir}}}}}}
+Return a file (or file-like) object that can be used as a temporary
+storage area.  The file is created using \function{mkstemp}. It will
+be destroyed as soon as it is closed (including an implicit close when
+the object is garbage collected).  Under \UNIX, the directory entry
+for the file is removed immediately after the file is created.  Other
+platforms do not support this; your code should not rely on a
+temporary file created using this function having or not having a
+visible name in the file system.
+
+The \var{mode} parameter defaults to \code{'w+b'} so that the file
+created can be read and written without being closed.  Binary mode is
+used so that it behaves consistently on all platforms without regard
+for the data that is stored.  \var{bufsize} defaults to \code{-1},
+meaning that the operating system default is used.
+
+The \var{dir}, \var{prefix} and \var{suffix} parameters are passed to
+\function{mkstemp()}.
+\end{funcdesc}
+
+\begin{funcdesc}{NamedTemporaryFile}{\optional{mode=\code{'w+b'}\optional{,
+                                     bufsize=\code{-1}\optional{,
+                                     suffix\optional{, prefix\optional{,
+                                     dir}}}}}}
+This function operates exactly as \function{TemporaryFile()} does,
+except that the file is guaranteed to have a visible name in the file
+system (on \UNIX, the directory entry is not unlinked).  That name can
+be retrieved from the \member{name} member of the file object.  Whether
+the name can be used to open the file a second time, while the
+named temporary file is still open, varies across platforms (it can
+be so used on \UNIX; it cannot on Windows NT or later).
+\versionadded{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{mkstemp}{\optional{suffix\optional{,
+                          prefix\optional{, dir\optional{, text}}}}}
+Creates a temporary file in the most secure manner possible.  There
+are no race conditions in the file's creation, assuming that the
+platform properly implements the \constant{O_EXCL} flag for
+\function{os.open()}.  The file is readable and writable only by the
+creating user ID.  If the platform uses permission bits to indicate
+whether a file is executable, the file is executable by no one.  The
+file descriptor is not inherited by child processes.
+
+Unlike \function{TemporaryFile()}, the user of \function{mkstemp()} is
+responsible for deleting the temporary file when done with it.
+
+If \var{suffix} is specified, the file name will end with that suffix,
+otherwise there will be no suffix.  \function{mkstemp()} does not put a
+dot between the file name and the suffix; if you need one, put it at
+the beginning of \var{suffix}.
+
+If \var{prefix} is specified, the file name will begin with that
+prefix; otherwise, a default prefix is used.
+
+If \var{dir} is specified, the file will be created in that directory;
+otherwise, a default directory is used.  The default directory is chosen
+from a platform-dependent list, but the user of the application can control
+the directory location by setting the \var{TMPDIR}, \var{TEMP} or \var{TMP}
+environment variables.  There is thus no guarantee that the generated
+filename will have any nice properties, such as not requiring quoting when
+passed to external commands via \code{os.popen()}.
+
+If \var{text} is specified, it indicates whether to open the file in
+binary mode (the default) or text mode.  On some platforms, this makes
+no difference.
+
+\function{mkstemp()} returns a tuple containing an OS-level handle to
+an open file (as would be returned by \function{os.open()}) and the
+absolute pathname of that file, in that order.
+\versionadded{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{mkdtemp}{\optional{suffix\optional{, prefix\optional{, dir}}}}
+Creates a temporary directory in the most secure manner possible.
+There are no race conditions in the directory's creation.  The
+directory is readable, writable, and searchable only by the
+creating user ID.
+
+The user of \function{mkdtemp()} is responsible for deleting the
+temporary directory and its contents when done with it.
+
+The \var{prefix}, \var{suffix}, and \var{dir} arguments are the same
+as for \function{mkstemp()}.
+
+\function{mkdtemp()} returns the absolute pathname of the new directory.
+\versionadded{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{mktemp}{\optional{suffix\optional{, prefix\optional{, dir}}}}
+\deprecated{2.3}{Use \function{mkstemp()} instead.}
+Return an absolute pathname of a file that did not exist at the time
+the call is made.  The \var{prefix}, \var{suffix}, and \var{dir}
+arguments are the same as for \function{mkstemp()}.
+
+\warning{Use of this function may introduce a security hole in your
+program.  By the time you get around to doing anything with the file
+name it returns, someone else may have beaten you to the punch.}
+\end{funcdesc}
+
+The module uses two global variables that tell it how to construct a
+temporary name.  They are initialized at the first call to any of the
+functions above.  The caller may change them, but this is discouraged;
+use the appropriate function arguments, instead.
+
+\begin{datadesc}{tempdir}
+When set to a value other than \code{None}, this variable defines the
+default value for the \var{dir} argument to all the functions defined
+in this module.
+
+If \code{tempdir} is unset or \code{None} at any call to any of the
+above functions, Python searches a standard list of directories and
+sets \var{tempdir} to the first one which the calling user can create
+files in.  The list is:
+
+\begin{enumerate}
+\item The directory named by the \envvar{TMPDIR} environment variable.
+\item The directory named by the \envvar{TEMP} environment variable.
+\item The directory named by the \envvar{TMP} environment variable.
+\item A platform-specific location:
+    \begin{itemize}
+    \item On RiscOS, the directory named by the
+          \envvar{Wimp\$ScrapDir} environment variable.
+    \item On Windows, the directories
+          \file{C:$\backslash$TEMP},
+          \file{C:$\backslash$TMP},
+          \file{$\backslash$TEMP}, and
+          \file{$\backslash$TMP}, in that order.
+    \item On all other platforms, the directories
+          \file{/tmp}, \file{/var/tmp}, and \file{/usr/tmp}, in that order.
+    \end{itemize}
+\item As a last resort, the current working directory.
+\end{enumerate}
+\end{datadesc}
+
+\begin{funcdesc}{gettempdir}{}
+Return the directory currently selected to create temporary files in.
+If \code{tempdir} is not \code{None}, this simply returns its contents;
+otherwise, the search described above is performed, and the result
+returned.
+\end{funcdesc}
+
+\begin{datadesc}{template}
+\deprecated{2.0}{Use \function{gettempprefix()} instead.}
+When set to a value other than \code{None}, this variable defines the
+prefix of the final component of the filenames returned by
+\function{mktemp()}.  A string of six random letters and digits is
+appended to the prefix to make the filename unique.  On Windows,
+the default prefix is \file{\textasciitilde{}T}; on all other systems
+it is \file{tmp}.
+
+Older versions of this module used to require that \code{template} be
+set to \code{None} after a call to \function{os.fork()}; this has not
+been necessary since version 1.5.2.
+\end{datadesc}
+
+\begin{funcdesc}{gettempprefix}{}
+Return the filename prefix used to create temporary files.  This does
+not contain the directory component.  Using this function is preferred
+over reading the \var{template} variable directly.
+\versionadded{1.5.2}
+\end{funcdesc}

Added: vendor/Python/current/Doc/lib/libtermios.tex
===================================================================
--- vendor/Python/current/Doc/lib/libtermios.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libtermios.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,106 @@
+\section{\module{termios} ---
+         \POSIX{} style tty control}
+
+\declaremodule{builtin}{termios}
+  \platform{Unix}
+\modulesynopsis{\POSIX\ style tty control.}
+
+\indexii{\POSIX}{I/O control}
+\indexii{tty}{I/O control}
+
+
+This module provides an interface to the \POSIX{} calls for tty I/O
+control.  For a complete description of these calls, see the \POSIX{} or
+\UNIX{} manual pages.  It is only available for those \UNIX{} versions
+that support \POSIX{} \emph{termios} style tty I/O control (and then
+only if configured at installation time).
+
+All functions in this module take a file descriptor \var{fd} as their
+first argument.  This can be an integer file descriptor, such as
+returned by \code{sys.stdin.fileno()}, or a file object, such as
+\code{sys.stdin} itself.
+
+This module also defines all the constants needed to work with the
+functions provided here; these have the same name as their
+counterparts in C.  Please refer to your system documentation for more
+information on using these terminal control interfaces.
+
+The module defines the following functions:
+
+\begin{funcdesc}{tcgetattr}{fd}
+Return a list containing the tty attributes for file descriptor
+\var{fd}, as follows: \code{[}\var{iflag}, \var{oflag}, \var{cflag},
+\var{lflag}, \var{ispeed}, \var{ospeed}, \var{cc}\code{]} where
+\var{cc} is a list of the tty special characters (each a string of
+length 1, except the items with indices \constant{VMIN} and
+\constant{VTIME}, which are integers when these fields are
+defined).  The interpretation of the flags and the speeds as well as
+the indexing in the \var{cc} array must be done using the symbolic
+constants defined in the \module{termios}
+module.
+\end{funcdesc}
+
+\begin{funcdesc}{tcsetattr}{fd, when, attributes}
+Set the tty attributes for file descriptor \var{fd} from the
+\var{attributes}, which is a list like the one returned by
+\function{tcgetattr()}.  The \var{when} argument determines when the
+attributes are changed: \constant{TCSANOW} to change immediately,
+\constant{TCSADRAIN} to change after transmitting all queued output,
+or \constant{TCSAFLUSH} to change after transmitting all queued
+output and discarding all queued input.
+\end{funcdesc}
+
+\begin{funcdesc}{tcsendbreak}{fd, duration}
+Send a break on file descriptor \var{fd}.  A zero \var{duration} sends
+a break for 0.25--0.5 seconds; a nonzero \var{duration} has a system
+dependent meaning.
+\end{funcdesc}
+
+\begin{funcdesc}{tcdrain}{fd}
+Wait until all output written to file descriptor \var{fd} has been
+transmitted.
+\end{funcdesc}
+
+\begin{funcdesc}{tcflush}{fd, queue}
+Discard queued data on file descriptor \var{fd}.  The \var{queue}
+selector specifies which queue: \constant{TCIFLUSH} for the input
+queue, \constant{TCOFLUSH} for the output queue, or
+\constant{TCIOFLUSH} for both queues.
+\end{funcdesc}
+
+\begin{funcdesc}{tcflow}{fd, action}
+Suspend or resume input or output on file descriptor \var{fd}.  The
+\var{action} argument can be \constant{TCOOFF} to suspend output,
+\constant{TCOON} to restart output, \constant{TCIOFF} to suspend
+input, or \constant{TCION} to restart input.
+\end{funcdesc}
+
+
+\begin{seealso}
+  \seemodule{tty}{Convenience functions for common terminal control
+                  operations.}
+\end{seealso}
+
+
+\subsection{Example}
+\nodename{termios Example}
+
+Here's a function that prompts for a password with echoing turned
+off.  Note the technique using a separate \function{tcgetattr()} call
+and a \keyword{try} ... \keyword{finally} statement to ensure that the
+old tty attributes are restored exactly no matter what happens:
+
+\begin{verbatim}
+def getpass(prompt = "Password: "):
+    import termios, sys
+    fd = sys.stdin.fileno()
+    old = termios.tcgetattr(fd)
+    new = termios.tcgetattr(fd)
+    new[3] = new[3] & ~termios.ECHO          # lflags
+    try:
+        termios.tcsetattr(fd, termios.TCSADRAIN, new)
+        passwd = raw_input(prompt)
+    finally:
+        termios.tcsetattr(fd, termios.TCSADRAIN, old)
+    return passwd
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/libtest.tex
===================================================================
--- vendor/Python/current/Doc/lib/libtest.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libtest.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,278 @@
+\section{\module{test} ---
+         Regression tests package for Python}
+
+\declaremodule{standard}{test}
+\sectionauthor{Brett Cannon}{brett at python.org}
+\modulesynopsis{Regression tests package containing the testing suite
+                for Python.}
+
+
+The \module{test} package contains all regression tests for Python as
+well as the modules \module{test.test_support} and
+\module{test.regrtest}.  \module{test.test_support} is used to enhance
+your tests while \module{test.regrtest} drives the testing suite.
+
+Each module in the \module{test} package whose name starts with
+\samp{test_} is a testing suite for a specific module or feature.
+All new tests should be written using the \refmodule{unittest} module;
+using \refmodule{unittest} is not required but makes the tests more
+flexible and maintenance of the tests easier.  Some older tests are
+written to use \refmodule{doctest} and a ``traditional'' testing
+style; these styles of tests will not be covered.
+
+\begin{seealso}
+\seemodule{unittest}{Writing PyUnit regression tests.}
+\seemodule{doctest}{Tests embedded in documentation strings.}
+\end{seealso}
+
+
+\subsection{Writing Unit Tests for the \module{test} package%
+            \label{writing-tests}}
+
+It is preferred that tests for the \module{test} package use the
+\refmodule{unittest} module and follow a few guidelines.
+One is to name the test module by starting it with \samp{test_} and end it with
+the name of the module being tested.
+The test methods in the test module should start with \samp{test_} and end with
+a description of what the method is testing.
+This is needed so that the methods are recognized by the test driver as
+test methods.
+Also, no documentation string for the method should be included.
+A comment (such as
+\samp{\# Tests function returns only True or False}) should be used to provide
+documentation for test methods.
+This is done because documentation strings get printed out if they exist and
+thus what test is being run is not stated.
+
+A basic boilerplate is often used:
+
+\begin{verbatim}
+import unittest
+from test import test_support
+
+class MyTestCase1(unittest.TestCase):
+
+    # Only use setUp() and tearDown() if necessary
+
+    def setUp(self):
+        ... code to execute in preparation for tests ...
+
+    def tearDown(self):
+        ... code to execute to clean up after tests ...
+
+    def test_feature_one(self):
+        # Test feature one.
+        ... testing code ...
+
+    def test_feature_two(self):
+        # Test feature two.
+        ... testing code ...
+
+    ... more test methods ...
+
+class MyTestCase2(unittest.TestCase):
+    ... same structure as MyTestCase1 ...
+
+... more test classes ...
+
+def test_main():
+    test_support.run_unittest(MyTestCase1,
+                              MyTestCase2,
+                              ... list other tests ...
+                             )
+
+if __name__ == '__main__':
+    test_main()
+\end{verbatim}
+
+This boilerplate code allows the testing suite to be run by
+\module{test.regrtest} as well as on its own as a script.
+
+The goal for regression testing is to try to break code.
+This leads to a few guidelines to be followed:
+
+\begin{itemize}
+\item The testing suite should exercise all classes, functions, and
+      constants.
+      This includes not just the external API that is to be presented to the
+      outside world but also "private" code.
+\item Whitebox testing (examining the code being tested when the tests are
+      being written) is preferred.
+      Blackbox testing (testing only the published user interface) is not
+      complete enough to make sure all boundary and edge cases are tested.
+\item Make sure all possible values are tested including invalid ones.
+      This makes sure that not only all valid values are acceptable but also
+      that improper values are handled correctly.
+\item Exhaust as many code paths as possible.
+      Test where branching occurs and thus tailor input to make sure as many
+      different paths through the code are taken.
+\item Add an explicit test for any bugs discovered for the tested code.
+      This will make sure that the error does not crop up again if the code is
+      changed in the future.
+\item Make sure to clean up after your tests (such as close and remove all
+      temporary files).
+\item If a test is dependent on a specific condition of the operating system
+      then verify the condition already exists before attempting the test.
+\item Import as few modules as possible and do it as soon as possible.
+      This minimizes external dependencies of tests and also minimizes possible
+      anomalous behavior from side-effects of importing a module.
+\item Try to maximize code reuse.
+      On occasion, tests will vary by something as small as what type
+      of input is used.
+      Minimize code duplication by subclassing a basic test class with a class
+      that specifies the input:
+\begin{verbatim}
+class TestFuncAcceptsSequences(unittest.TestCase):
+
+    func = mySuperWhammyFunction
+
+    def test_func(self):
+        self.func(self.arg)
+
+class AcceptLists(TestFuncAcceptsSequences):
+    arg = [1,2,3]
+
+class AcceptStrings(TestFuncAcceptsSequences):
+    arg = 'abc'
+
+class AcceptTuples(TestFuncAcceptsSequences):
+    arg = (1,2,3)
+\end{verbatim}
+\end{itemize}
+
+\begin{seealso}
+\seetitle{Test Driven Development}
+         {A book by Kent Beck on writing tests before code.}
+\end{seealso}
+
+
+\subsection{Running tests using \module{test.regrtest} \label{regrtest}}
+
+\module{test.regrtest} can be used as a script to drive Python's
+regression test suite.
+Running the script by itself automatically starts running all
+regression tests in the \module{test} package.
+It does this by finding all modules in the package whose name starts with
+\samp{test_}, importing them, and executing the function
+\function{test_main()} if present.
+The names of tests to execute may also be passed to the script.
+Specifying a single regression test (\program{python regrtest.py}
+\programopt{test_spam.py}) will minimize output and only print whether
+the test passed or failed and thus minimize output.
+
+Running \module{test.regrtest} directly allows what resources are
+available for tests to use to be set.
+You do this by using the \programopt{-u} command-line option.
+Run \program{python regrtest.py} \programopt{-uall} to turn on all
+resources; specifying \programopt{all} as an option for
+\programopt{-u} enables all possible resources.
+If all but one resource is desired (a more common case), a
+comma-separated list of resources that are not desired may be listed after
+\programopt{all}.
+The command \program{python regrtest.py}
+\programopt{-uall,-audio,-largefile} will run \module{test.regrtest}
+with all resources except the \programopt{audio} and
+\programopt{largefile} resources.
+For a list of all resources and more command-line options, run
+\program{python regrtest.py} \programopt{-h}.
+
+Some other ways to execute the regression tests depend on what platform the
+tests are being executed on.
+On \UNIX{}, you can run \program{make} \programopt{test} at the
+top-level directory where Python was built.
+On Windows, executing \program{rt.bat} from your \file{PCBuild}
+directory will run all regression tests.
+
+
+\section{\module{test.test_support} ---
+         Utility functions for tests}
+
+\declaremodule[test.testsupport]{standard}{test.test_support}
+\modulesynopsis{Support for Python regression tests.}
+
+The \module{test.test_support} module provides support for Python's
+regression tests.
+
+This module defines the following exceptions:
+
+\begin{excdesc}{TestFailed}
+Exception to be raised when a test fails.
+\end{excdesc}
+
+\begin{excdesc}{TestSkipped}
+Subclass of \exception{TestFailed}.
+Raised when a test is skipped.
+This occurs when a needed resource (such as a network connection) is not
+available at the time of testing.
+\end{excdesc}
+
+\begin{excdesc}{ResourceDenied}
+Subclass of \exception{TestSkipped}.
+Raised when a resource (such as a network connection) is not available.
+Raised by the \function{requires()} function.
+\end{excdesc}
+
+
+The \module{test.test_support} module defines the following constants:
+
+\begin{datadesc}{verbose}
+\constant{True} when verbose output is enabled.
+Should be checked when more detailed information is desired about a running
+test.
+\var{verbose} is set by \module{test.regrtest}.
+\end{datadesc}
+
+\begin{datadesc}{have_unicode}
+\constant{True} when Unicode support is available.
+\end{datadesc}
+
+\begin{datadesc}{is_jython}
+\constant{True} if the running interpreter is Jython.
+\end{datadesc}
+
+\begin{datadesc}{TESTFN}
+Set to the path that a temporary file may be created at.
+Any temporary that is created should be closed and unlinked (removed).
+\end{datadesc}
+
+
+The \module{test.test_support} module defines the following functions:
+
+\begin{funcdesc}{forget}{module_name}
+Removes the module named \var{module_name} from \code{sys.modules} and deletes
+any byte-compiled files of the module.
+\end{funcdesc}
+
+\begin{funcdesc}{is_resource_enabled}{resource}
+Returns \constant{True} if \var{resource} is enabled and available.
+The list of available resources is only set when \module{test.regrtest}
+is executing the tests.
+\end{funcdesc}
+
+\begin{funcdesc}{requires}{resource\optional{, msg}}
+Raises \exception{ResourceDenied} if \var{resource} is not available.
+\var{msg} is the argument to \exception{ResourceDenied} if it is raised.
+Always returns true if called by a function whose \code{__name__} is
+\code{'__main__'}.
+Used when tests are executed by \module{test.regrtest}.
+\end{funcdesc}
+
+\begin{funcdesc}{findfile}{filename}
+Return the path to the file named \var{filename}.
+If no match is found \var{filename} is returned.
+This does not equal a failure since it could be the path to the file.
+\end{funcdesc}
+
+\begin{funcdesc}{run_unittest}{*classes}
+Execute \class{unittest.TestCase} subclasses passed to the function.
+The function scans the classes for methods starting with the prefix
+\samp{test_} and executes the tests individually.
+This is the preferred way to execute tests.
+\end{funcdesc}
+
+\begin{funcdesc}{run_suite}{suite\optional{, testclass}}
+Execute the \class{unittest.TestSuite} instance \var{suite}.
+The optional argument \var{testclass} accepts one of the test classes in the
+suite so as to print out more detailed information on where the testing suite
+originated from.
+\end{funcdesc}

Added: vendor/Python/current/Doc/lib/libtextwrap.tex
===================================================================
--- vendor/Python/current/Doc/lib/libtextwrap.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libtextwrap.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,181 @@
+\section{\module{textwrap} ---
+         Text wrapping and filling}
+
+\declaremodule{standard}{textwrap}
+\modulesynopsis{Text wrapping and filling}
+\moduleauthor{Greg Ward}{gward at python.net}
+\sectionauthor{Greg Ward}{gward at python.net}
+
+\versionadded{2.3}
+
+The \module{textwrap} module provides two convenience functions,
+\function{wrap()} and \function{fill()}, as well as
+\class{TextWrapper}, the class that does all the work, and a utility function 
+\function{dedent()}.  If you're just wrapping or filling one or two 
+text strings, the convenience functions should be good enough; otherwise, 
+you should use an instance of \class{TextWrapper} for efficiency.
+
+\begin{funcdesc}{wrap}{text\optional{, width\optional{, \moreargs}}}
+Wraps the single paragraph in \var{text} (a string) so every line is at
+most \var{width} characters long.  Returns a list of output lines,
+without final newlines.
+
+Optional keyword arguments correspond to the instance attributes of
+\class{TextWrapper}, documented below.  \var{width} defaults to
+\code{70}.
+\end{funcdesc}
+
+\begin{funcdesc}{fill}{text\optional{, width\optional{, \moreargs}}}
+Wraps the single paragraph in \var{text}, and returns a single string
+containing the wrapped paragraph.  \function{fill()} is shorthand for
+\begin{verbatim}
+"\n".join(wrap(text, ...))
+\end{verbatim}
+
+In particular, \function{fill()} accepts exactly the same keyword
+arguments as \function{wrap()}.
+\end{funcdesc}
+
+Both \function{wrap()} and \function{fill()} work by creating a
+\class{TextWrapper} instance and calling a single method on it.  That
+instance is not reused, so for applications that wrap/fill many text
+strings, it will be more efficient for you to create your own
+\class{TextWrapper} object.
+
+An additional utility function, \function{dedent()}, is provided to
+remove indentation from strings that have unwanted whitespace to the
+left of the text.
+
+\begin{funcdesc}{dedent}{text} 
+Remove any common leading whitespace from every line in \var{text}.
+
+This can be used to make triple-quoted strings line up with the left
+edge of the display, while still presenting them in the source code
+in indented form.
+
+Note that tabs and spaces are both treated as whitespace, but they are
+not equal: the lines \code{" {} hello"} and \code{"\textbackslash{}thello"}
+are considered to have no common leading whitespace.  (This behaviour is
+new in Python 2.5; older versions of this module incorrectly expanded
+tabs before searching for common leading whitespace.)
+
+For example:
+\begin{verbatim}
+def test():
+    # end first line with \ to avoid the empty line!
+    s = '''\
+    hello
+      world
+    '''
+    print repr(s)          # prints '    hello\n      world\n    '
+    print repr(dedent(s))  # prints 'hello\n  world\n'
+\end{verbatim}
+\end{funcdesc}
+
+\begin{classdesc}{TextWrapper}{...}
+The \class{TextWrapper} constructor accepts a number of optional
+keyword arguments.  Each argument corresponds to one instance attribute,
+so for example
+\begin{verbatim}
+wrapper = TextWrapper(initial_indent="* ")
+\end{verbatim}
+is the same as
+\begin{verbatim}
+wrapper = TextWrapper()
+wrapper.initial_indent = "* "
+\end{verbatim}
+
+You can re-use the same \class{TextWrapper} object many times, and you
+can change any of its options through direct assignment to instance
+attributes between uses.
+\end{classdesc}
+
+The \class{TextWrapper} instance attributes (and keyword arguments to
+the constructor) are as follows:
+
+\begin{memberdesc}{width}
+(default: \code{70}) The maximum length of wrapped lines.  As long as
+there are no individual words in the input text longer than
+\member{width}, \class{TextWrapper} guarantees that no output line
+will be longer than \member{width} characters.
+\end{memberdesc}
+
+\begin{memberdesc}{expand_tabs}
+(default: \code{True}) If true, then all tab characters in \var{text}
+will be expanded to spaces using the \method{expandtabs()} method of
+\var{text}.
+\end{memberdesc}
+
+\begin{memberdesc}{replace_whitespace}
+(default: \code{True}) If true, each whitespace character (as defined
+by \code{string.whitespace}) remaining after tab expansion will be
+replaced by a single space.  \note{If \member{expand_tabs} is false
+and \member{replace_whitespace} is true, each tab character will be
+replaced by a single space, which is \emph{not} the same as tab
+expansion.}
+\end{memberdesc}
+
+\begin{memberdesc}{initial_indent}
+(default: \code{''}) String that will be prepended to the first line
+of wrapped output.  Counts towards the length of the first line.
+\end{memberdesc}
+
+\begin{memberdesc}{subsequent_indent}
+(default: \code{''}) String that will be prepended to all lines of
+wrapped output except the first.  Counts towards the length of each
+line except the first.
+\end{memberdesc}
+
+\begin{memberdesc}{fix_sentence_endings}
+(default: \code{False}) If true, \class{TextWrapper} attempts to detect
+sentence endings and ensure that sentences are always separated by
+exactly two spaces.  This is generally desired for text in a monospaced
+font.  However, the sentence detection algorithm is imperfect: it
+assumes that a sentence ending consists of a lowercase letter followed
+by one of \character{.},
+\character{!}, or \character{?}, possibly followed by one of
+\character{"} or \character{'}, followed by a space.  One problem
+with this is algorithm is that it is unable to detect the difference
+between ``Dr.'' in
+
+\begin{verbatim}
+[...] Dr. Frankenstein's monster [...]
+\end{verbatim}
+
+and ``Spot.'' in
+
+\begin{verbatim}
+[...] See Spot. See Spot run [...]
+\end{verbatim}
+
+\member{fix_sentence_endings} is false by default.
+
+Since the sentence detection algorithm relies on
+\code{string.lowercase} for the definition of ``lowercase letter,''
+and a convention of using two spaces after a period to separate
+sentences on the same line, it is specific to English-language texts.
+\end{memberdesc}
+
+\begin{memberdesc}{break_long_words}
+(default: \code{True}) If true, then words longer than
+\member{width} will be broken in order to ensure that no lines are
+longer than \member{width}.  If it is false, long words will not be
+broken, and some lines may be longer than \member{width}.  (Long words
+will be put on a line by themselves, in order to minimize the amount
+by which \member{width} is exceeded.)
+\end{memberdesc}
+
+\class{TextWrapper} also provides two public methods, analogous to the
+module-level convenience functions:
+
+\begin{methoddesc}{wrap}{text}
+Wraps the single paragraph in \var{text} (a string) so every line is
+at most \member{width} characters long.  All wrapping options are
+taken from instance attributes of the \class{TextWrapper} instance.
+Returns a list of output lines, without final newlines.
+\end{methoddesc}
+
+\begin{methoddesc}{fill}{text}
+Wraps the single paragraph in \var{text}, and returns a single string
+containing the wrapped paragraph.
+\end{methoddesc}

Added: vendor/Python/current/Doc/lib/libthread.tex
===================================================================
--- vendor/Python/current/Doc/lib/libthread.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libthread.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,173 @@
+\section{\module{thread} ---
+         Multiple threads of control}
+
+\declaremodule{builtin}{thread}
+\modulesynopsis{Create multiple threads of control within one interpreter.}
+
+
+This module provides low-level primitives for working with multiple
+threads (a.k.a.\ \dfn{light-weight processes} or \dfn{tasks}) --- multiple
+threads of control sharing their global data space.  For
+synchronization, simple locks (a.k.a.\ \dfn{mutexes} or \dfn{binary
+semaphores}) are provided.
+\index{light-weight processes}
+\index{processes, light-weight}
+\index{binary semaphores}
+\index{semaphores, binary}
+
+The module is optional.  It is supported on Windows, Linux, SGI
+IRIX, Solaris 2.x, as well as on systems that have a \POSIX{} thread
+(a.k.a. ``pthread'') implementation.  For systems lacking the \module{thread}
+module, the \refmodule[dummythread]{dummy_thread} module is available.
+It duplicates this module's interface and can be
+used as a drop-in replacement.
+\index{pthreads}
+\indexii{threads}{\POSIX}
+
+It defines the following constant and functions:
+
+\begin{excdesc}{error}
+Raised on thread-specific errors.
+\end{excdesc}
+
+\begin{datadesc}{LockType}
+This is the type of lock objects.
+\end{datadesc}
+
+\begin{funcdesc}{start_new_thread}{function, args\optional{, kwargs}}
+Start a new thread and return its identifier.  The thread executes the function
+\var{function} with the argument list \var{args} (which must be a tuple).  The
+optional \var{kwargs} argument specifies a dictionary of keyword arguments.
+When the function returns, the thread silently exits.  When the function
+terminates with an unhandled exception, a stack trace is printed and
+then the thread exits (but other threads continue to run).
+\end{funcdesc}
+
+\begin{funcdesc}{interrupt_main}{}
+Raise a \exception{KeyboardInterrupt} exception in the main thread.  A subthread
+can use this function to interrupt the main thread.
+\versionadded{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{exit}{}
+Raise the \exception{SystemExit} exception.  When not caught, this
+will cause the thread to exit silently.
+\end{funcdesc}
+
+%\begin{funcdesc}{exit_prog}{status}
+%Exit all threads and report the value of the integer argument
+%\var{status} as the exit status of the entire program.
+%\strong{Caveat:} code in pending \keyword{finally} clauses, in this thread
+%or in other threads, is not executed.
+%\end{funcdesc}
+
+\begin{funcdesc}{allocate_lock}{}
+Return a new lock object.  Methods of locks are described below.  The
+lock is initially unlocked.
+\end{funcdesc}
+
+\begin{funcdesc}{get_ident}{}
+Return the `thread identifier' of the current thread.  This is a
+nonzero integer.  Its value has no direct meaning; it is intended as a
+magic cookie to be used e.g. to index a dictionary of thread-specific
+data.  Thread identifiers may be recycled when a thread exits and
+another thread is created.
+\end{funcdesc}
+
+\begin{funcdesc}{stack_size}{\optional{size}}
+Return the thread stack size used when creating new threads.  The
+optional \var{size} argument specifies the stack size to be used for
+subsequently created threads, and must be 0 (use platform or
+configured default) or a positive integer value of at least 32,768 (32kB).
+If changing the thread stack size is unsupported, a \exception{ThreadError}
+is raised.  If the specified stack size is invalid, a \exception{ValueError}
+is raised and the stack size is unmodified.  32kB is currently the minimum
+supported stack size value to guarantee sufficient stack space for the
+interpreter itself.  Note that some platforms may have particular
+restrictions on values for the stack size, such as requiring a minimum
+stack size > 32kB or requiring allocation in multiples of the system
+memory page size - platform documentation should be referred to for
+more information (4kB pages are common; using multiples of 4096 for
+the stack size is the suggested approach in the absence of more
+specific information).
+Availability: Windows, systems with \POSIX{} threads.
+\versionadded{2.5}
+\end{funcdesc}
+
+
+Lock objects have the following methods:
+
+\begin{methoddesc}[lock]{acquire}{\optional{waitflag}}
+Without the optional argument, this method acquires the lock
+unconditionally, if necessary waiting until it is released by another
+thread (only one thread at a time can acquire a lock --- that's their
+reason for existence).  If the integer
+\var{waitflag} argument is present, the action depends on its
+value: if it is zero, the lock is only acquired if it can be acquired
+immediately without waiting, while if it is nonzero, the lock is
+acquired unconditionally as before.  The
+return value is \code{True} if the lock is acquired successfully,
+\code{False} if not.
+\end{methoddesc}
+
+\begin{methoddesc}[lock]{release}{}
+Releases the lock.  The lock must have been acquired earlier, but not
+necessarily by the same thread.
+\end{methoddesc}
+
+\begin{methoddesc}[lock]{locked}{}
+Return the status of the lock:\ \code{True} if it has been acquired by
+some thread, \code{False} if not.
+\end{methoddesc}
+
+In addition to these methods, lock objects can also be used via the
+\keyword{with} statement, e.g.:
+
+\begin{verbatim}
+from __future__ import with_statement
+import thread
+
+a_lock = thread.allocate_lock()
+
+with a_lock:
+    print "a_lock is locked while this executes"
+\end{verbatim}
+
+\strong{Caveats:}
+
+\begin{itemize}
+\item
+Threads interact strangely with interrupts: the
+\exception{KeyboardInterrupt} exception will be received by an
+arbitrary thread.  (When the \refmodule{signal}\refbimodindex{signal}
+module is available, interrupts always go to the main thread.)
+
+\item
+Calling \function{sys.exit()} or raising the \exception{SystemExit}
+exception is equivalent to calling \function{exit()}.
+
+\item
+Not all built-in functions that may block waiting for I/O allow other
+threads to run.  (The most popular ones (\function{time.sleep()},
+\method{\var{file}.read()}, \function{select.select()}) work as
+expected.)
+
+\item
+It is not possible to interrupt the \method{acquire()} method on a lock
+--- the \exception{KeyboardInterrupt} exception will happen after the
+lock has been acquired.
+
+\item
+When the main thread exits, it is system defined whether the other
+threads survive.  On SGI IRIX using the native thread implementation,
+they survive.  On most other systems, they are killed without
+executing \keyword{try} ... \keyword{finally} clauses or executing
+object destructors.
+\indexii{threads}{IRIX}
+
+\item
+When the main thread exits, it does not do any of its usual cleanup
+(except that \keyword{try} ... \keyword{finally} clauses are honored),
+and the standard I/O files are not flushed.
+
+\end{itemize}

Added: vendor/Python/current/Doc/lib/libthreading.tex
===================================================================
--- vendor/Python/current/Doc/lib/libthreading.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libthreading.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,716 @@
+\section{\module{threading} ---
+         Higher-level threading interface}
+
+\declaremodule{standard}{threading}
+\modulesynopsis{Higher-level threading interface.}
+
+
+This module constructs higher-level threading interfaces on top of the 
+lower level \refmodule{thread} module.
+
+The \refmodule[dummythreading]{dummy_threading} module is provided for
+situations where \module{threading} cannot be used because
+\refmodule{thread} is missing.
+
+This module defines the following functions and objects:
+
+\begin{funcdesc}{activeCount}{}
+Return the number of \class{Thread} objects currently alive.  The
+returned count is equal to the length of the list returned by
+\function{enumerate()}.
+\end{funcdesc}
+
+\begin{funcdesc}{Condition}{}
+A factory function that returns a new condition variable object.
+A condition variable allows one or more threads to wait until they
+are notified by another thread.
+\end{funcdesc}
+
+\begin{funcdesc}{currentThread}{}
+Return the current \class{Thread} object, corresponding to the
+caller's thread of control.  If the caller's thread of control was not
+created through the
+\module{threading} module, a dummy thread object with limited functionality
+is returned.
+\end{funcdesc}
+
+\begin{funcdesc}{enumerate}{}
+Return a list of all \class{Thread} objects currently alive.  The list
+includes daemonic threads, dummy thread objects created by
+\function{currentThread()}, and the main thread.  It excludes
+terminated threads and threads that have not yet been started.
+\end{funcdesc}
+
+\begin{funcdesc}{Event}{}
+A factory function that returns a new event object.  An event manages
+a flag that can be set to true with the \method{set()} method and
+reset to false with the \method{clear()} method.  The \method{wait()}
+method blocks until the flag is true.
+\end{funcdesc}
+
+\begin{classdesc*}{local}{}
+A class that represents thread-local data.  Thread-local data are data
+whose values are thread specific.  To manage thread-local data, just
+create an instance of \class{local} (or a subclass) and store
+attributes on it:
+
+\begin{verbatim}
+mydata = threading.local()
+mydata.x = 1
+\end{verbatim}
+
+The instance's values will be different for separate threads.
+
+For more details and extensive examples, see the documentation string
+of the \module{_threading_local} module.
+
+\versionadded{2.4}
+\end{classdesc*}
+
+\begin{funcdesc}{Lock}{}
+A factory function that returns a new primitive lock object.  Once
+a thread has acquired it, subsequent attempts to acquire it block,
+until it is released; any thread may release it.
+\end{funcdesc}
+
+\begin{funcdesc}{RLock}{}
+A factory function that returns a new reentrant lock object.
+A reentrant lock must be released by the thread that acquired it.
+Once a thread has acquired a reentrant lock, the same thread may
+acquire it again without blocking; the thread must release it once
+for each time it has acquired it.
+\end{funcdesc}
+
+\begin{funcdesc}{Semaphore}{\optional{value}}
+A factory function that returns a new semaphore object.  A
+semaphore manages a counter representing the number of \method{release()}
+calls minus the number of \method{acquire()} calls, plus an initial value.
+The \method{acquire()} method blocks if necessary until it can return
+without making the counter negative.  If not given, \var{value} defaults to
+1. 
+\end{funcdesc}
+
+\begin{funcdesc}{BoundedSemaphore}{\optional{value}}
+A factory function that returns a new bounded semaphore object.  A bounded
+semaphore checks to make sure its current value doesn't exceed its initial
+value.  If it does, \exception{ValueError} is raised. In most situations
+semaphores are used to guard resources with limited capacity.  If the
+semaphore is released too many times it's a sign of a bug.  If not given,
+\var{value} defaults to 1. 
+\end{funcdesc}
+
+\begin{classdesc*}{Thread}{}
+A class that represents a thread of control.  This class can be safely
+subclassed in a limited fashion.
+\end{classdesc*}
+
+\begin{classdesc*}{Timer}{}
+A thread that executes a function after a specified interval has passed.
+\end{classdesc*}
+
+\begin{funcdesc}{settrace}{func}
+Set a trace function\index{trace function} for all threads started
+from the \module{threading} module.  The \var{func} will be passed to 
+\function{sys.settrace()} for each thread, before its \method{run()}
+method is called.
+\versionadded{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{setprofile}{func}
+Set a profile function\index{profile function} for all threads started
+from the \module{threading} module.  The \var{func} will be passed to 
+\function{sys.setprofile()} for each thread, before its \method{run()}
+method is called.
+\versionadded{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{stack_size}{\optional{size}}
+Return the thread stack size used when creating new threads.  The
+optional \var{size} argument specifies the stack size to be used for
+subsequently created threads, and must be 0 (use platform or
+configured default) or a positive integer value of at least 32,768 (32kB).
+If changing the thread stack size is unsupported, a \exception{ThreadError}
+is raised.  If the specified stack size is invalid, a \exception{ValueError}
+is raised and the stack size is unmodified.  32kB is currently the minimum
+supported stack size value to guarantee sufficient stack space for the
+interpreter itself.  Note that some platforms may have particular
+restrictions on values for the stack size, such as requiring a minimum
+stack size > 32kB or requiring allocation in multiples of the system
+memory page size - platform documentation should be referred to for
+more information (4kB pages are common; using multiples of 4096 for
+the stack size is the suggested approach in the absence of more
+specific information).
+Availability: Windows, systems with \POSIX{} threads.
+\versionadded{2.5}
+\end{funcdesc}
+
+Detailed interfaces for the objects are documented below.  
+
+The design of this module is loosely based on Java's threading model.
+However, where Java makes locks and condition variables basic behavior
+of every object, they are separate objects in Python.  Python's \class{Thread}
+class supports a subset of the behavior of Java's Thread class;
+currently, there are no priorities, no thread groups, and threads
+cannot be destroyed, stopped, suspended, resumed, or interrupted.  The
+static methods of Java's Thread class, when implemented, are mapped to
+module-level functions.
+
+All of the methods described below are executed atomically.
+
+
+\subsection{Lock Objects \label{lock-objects}}
+
+A primitive lock is a synchronization primitive that is not owned
+by a particular thread when locked.  In Python, it is currently
+the lowest level synchronization primitive available, implemented
+directly by the \refmodule{thread} extension module.
+
+A primitive lock is in one of two states, ``locked'' or ``unlocked''.
+It is created in the unlocked state.  It has two basic methods,
+\method{acquire()} and \method{release()}.  When the state is
+unlocked, \method{acquire()} changes the state to locked and returns
+immediately.  When the state is locked, \method{acquire()} blocks
+until a call to \method{release()} in another thread changes it to
+unlocked, then the \method{acquire()} call resets it to locked and
+returns.  The \method{release()} method should only be called in the
+locked state; it changes the state to unlocked and returns
+immediately.  When more than one thread is blocked in
+\method{acquire()} waiting for the state to turn to unlocked, only one
+thread proceeds when a \method{release()} call resets the state to
+unlocked; which one of the waiting threads proceeds is not defined,
+and may vary across implementations.
+
+All methods are executed atomically.
+
+\begin{methoddesc}{acquire}{\optional{blocking\code{ = 1}}}
+Acquire a lock, blocking or non-blocking.
+
+When invoked without arguments, block until the lock is
+unlocked, then set it to locked, and return true.  
+
+When invoked with the \var{blocking} argument set to true, do the
+same thing as when called without arguments, and return true.
+
+When invoked with the \var{blocking} argument set to false, do not
+block.  If a call without an argument would block, return false
+immediately; otherwise, do the same thing as when called
+without arguments, and return true.
+\end{methoddesc}
+
+\begin{methoddesc}{release}{}
+Release a lock.
+
+When the lock is locked, reset it to unlocked, and return.  If
+any other threads are blocked waiting for the lock to become
+unlocked, allow exactly one of them to proceed.
+
+Do not call this method when the lock is unlocked.
+
+There is no return value.
+\end{methoddesc}
+
+
+\subsection{RLock Objects \label{rlock-objects}}
+
+A reentrant lock is a synchronization primitive that may be
+acquired multiple times by the same thread.  Internally, it uses
+the concepts of ``owning thread'' and ``recursion level'' in
+addition to the locked/unlocked state used by primitive locks.  In
+the locked state, some thread owns the lock; in the unlocked
+state, no thread owns it.
+
+To lock the lock, a thread calls its \method{acquire()} method; this
+returns once the thread owns the lock.  To unlock the lock, a
+thread calls its \method{release()} method.
+\method{acquire()}/\method{release()} call pairs may be nested; only
+the final \method{release()} (the \method{release()} of the outermost
+pair) resets the lock to unlocked and allows another thread blocked in
+\method{acquire()} to proceed.
+
+\begin{methoddesc}{acquire}{\optional{blocking\code{ = 1}}}
+Acquire a lock, blocking or non-blocking.
+
+When invoked without arguments: if this thread already owns
+the lock, increment the recursion level by one, and return
+immediately.  Otherwise, if another thread owns the lock,
+block until the lock is unlocked.  Once the lock is unlocked
+(not owned by any thread), then grab ownership, set the
+recursion level to one, and return.  If more than one thread
+is blocked waiting until the lock is unlocked, only one at a
+time will be able to grab ownership of the lock.  There is no
+return value in this case.
+
+When invoked with the \var{blocking} argument set to true, do the
+same thing as when called without arguments, and return true.
+
+When invoked with the \var{blocking} argument set to false, do not
+block.  If a call without an argument would block, return false
+immediately; otherwise, do the same thing as when called
+without arguments, and return true.
+\end{methoddesc}
+
+\begin{methoddesc}{release}{}
+Release a lock, decrementing the recursion level.  If after the
+decrement it is zero, reset the lock to unlocked (not owned by any
+thread), and if any other threads are blocked waiting for the lock to
+become unlocked, allow exactly one of them to proceed.  If after the
+decrement the recursion level is still nonzero, the lock remains
+locked and owned by the calling thread.
+
+Only call this method when the calling thread owns the lock.
+Do not call this method when the lock is unlocked.
+
+There is no return value.
+\end{methoddesc}
+
+
+\subsection{Condition Objects \label{condition-objects}}
+
+A condition variable is always associated with some kind of lock;
+this can be passed in or one will be created by default.  (Passing
+one in is useful when several condition variables must share the
+same lock.)
+
+A condition variable has \method{acquire()} and \method{release()}
+methods that call the corresponding methods of the associated lock.
+It also has a \method{wait()} method, and \method{notify()} and
+\method{notifyAll()} methods.  These three must only be called when
+the calling thread has acquired the lock.
+
+The \method{wait()} method releases the lock, and then blocks until it
+is awakened by a \method{notify()} or \method{notifyAll()} call for
+the same condition variable in another thread.  Once awakened, it
+re-acquires the lock and returns.  It is also possible to specify a
+timeout.
+
+The \method{notify()} method wakes up one of the threads waiting for
+the condition variable, if any are waiting.  The \method{notifyAll()}
+method wakes up all threads waiting for the condition variable.
+
+Note: the \method{notify()} and \method{notifyAll()} methods don't
+release the lock; this means that the thread or threads awakened will
+not return from their \method{wait()} call immediately, but only when
+the thread that called \method{notify()} or \method{notifyAll()}
+finally relinquishes ownership of the lock.
+
+Tip: the typical programming style using condition variables uses the
+lock to synchronize access to some shared state; threads that are
+interested in a particular change of state call \method{wait()}
+repeatedly until they see the desired state, while threads that modify
+the state call \method{notify()} or \method{notifyAll()} when they
+change the state in such a way that it could possibly be a desired
+state for one of the waiters.  For example, the following code is a
+generic producer-consumer situation with unlimited buffer capacity:
+
+\begin{verbatim}
+# Consume one item
+cv.acquire()
+while not an_item_is_available():
+    cv.wait()
+get_an_available_item()
+cv.release()
+
+# Produce one item
+cv.acquire()
+make_an_item_available()
+cv.notify()
+cv.release()
+\end{verbatim}
+
+To choose between \method{notify()} and \method{notifyAll()}, consider
+whether one state change can be interesting for only one or several
+waiting threads.  E.g. in a typical producer-consumer situation,
+adding one item to the buffer only needs to wake up one consumer
+thread.
+
+\begin{classdesc}{Condition}{\optional{lock}}
+If the \var{lock} argument is given and not \code{None}, it must be a
+\class{Lock} or \class{RLock} object, and it is used as the underlying
+lock.  Otherwise, a new \class{RLock} object is created and used as
+the underlying lock.
+\end{classdesc}
+
+\begin{methoddesc}{acquire}{*args}
+Acquire the underlying lock.
+This method calls the corresponding method on the underlying
+lock; the return value is whatever that method returns.
+\end{methoddesc}
+
+\begin{methoddesc}{release}{}
+Release the underlying lock.
+This method calls the corresponding method on the underlying
+lock; there is no return value.
+\end{methoddesc}
+
+\begin{methoddesc}{wait}{\optional{timeout}}
+Wait until notified or until a timeout occurs.
+This must only be called when the calling thread has acquired the
+lock.
+
+This method releases the underlying lock, and then blocks until it is
+awakened by a \method{notify()} or \method{notifyAll()} call for the
+same condition variable in another thread, or until the optional
+timeout occurs.  Once awakened or timed out, it re-acquires the lock
+and returns.
+
+When the \var{timeout} argument is present and not \code{None}, it
+should be a floating point number specifying a timeout for the
+operation in seconds (or fractions thereof).
+
+When the underlying lock is an \class{RLock}, it is not released using
+its \method{release()} method, since this may not actually unlock the
+lock when it was acquired multiple times recursively.  Instead, an
+internal interface of the \class{RLock} class is used, which really
+unlocks it even when it has been recursively acquired several times.
+Another internal interface is then used to restore the recursion level
+when the lock is reacquired.
+\end{methoddesc}
+
+\begin{methoddesc}{notify}{}
+Wake up a thread waiting on this condition, if any.
+This must only be called when the calling thread has acquired the
+lock.
+
+This method wakes up one of the threads waiting for the condition
+variable, if any are waiting; it is a no-op if no threads are waiting.
+
+The current implementation wakes up exactly one thread, if any are
+waiting.  However, it's not safe to rely on this behavior.  A future,
+optimized implementation may occasionally wake up more than one
+thread.
+
+Note: the awakened thread does not actually return from its
+\method{wait()} call until it can reacquire the lock.  Since
+\method{notify()} does not release the lock, its caller should.
+\end{methoddesc}
+
+\begin{methoddesc}{notifyAll}{}
+Wake up all threads waiting on this condition.  This method acts like
+\method{notify()}, but wakes up all waiting threads instead of one.
+\end{methoddesc}
+
+
+\subsection{Semaphore Objects \label{semaphore-objects}}
+
+This is one of the oldest synchronization primitives in the history of
+computer science, invented by the early Dutch computer scientist
+Edsger W. Dijkstra (he used \method{P()} and \method{V()} instead of
+\method{acquire()} and \method{release()}).
+
+A semaphore manages an internal counter which is decremented by each
+\method{acquire()} call and incremented by each \method{release()}
+call.  The counter can never go below zero; when \method{acquire()}
+finds that it is zero, it blocks, waiting until some other thread
+calls \method{release()}.
+
+\begin{classdesc}{Semaphore}{\optional{value}}
+The optional argument gives the initial value for the internal
+counter; it defaults to \code{1}.
+\end{classdesc}
+
+\begin{methoddesc}{acquire}{\optional{blocking}}
+Acquire a semaphore.
+
+When invoked without arguments: if the internal counter is larger than
+zero on entry, decrement it by one and return immediately.  If it is
+zero on entry, block, waiting until some other thread has called
+\method{release()} to make it larger than zero.  This is done with
+proper interlocking so that if multiple \method{acquire()} calls are
+blocked, \method{release()} will wake exactly one of them up.  The
+implementation may pick one at random, so the order in which blocked
+threads are awakened should not be relied on.  There is no return
+value in this case.
+
+When invoked with \var{blocking} set to true, do the same thing as
+when called without arguments, and return true.
+
+When invoked with \var{blocking} set to false, do not block.  If a
+call without an argument would block, return false immediately;
+otherwise, do the same thing as when called without arguments, and
+return true.
+\end{methoddesc}
+
+\begin{methoddesc}{release}{}
+Release a semaphore,
+incrementing the internal counter by one.  When it was zero on
+entry and another thread is waiting for it to become larger
+than zero again, wake up that thread.
+\end{methoddesc}
+
+
+\subsubsection{\class{Semaphore} Example \label{semaphore-examples}}
+
+Semaphores are often used to guard resources with limited capacity, for
+example, a database server.  In any situation where the size of the resource
+size is fixed, you should use a bounded semaphore.  Before spawning any
+worker threads, your main thread would initialize the semaphore:
+
+\begin{verbatim}
+maxconnections = 5
+...
+pool_sema = BoundedSemaphore(value=maxconnections)
+\end{verbatim}
+
+Once spawned, worker threads call the semaphore's acquire and release
+methods when they need to connect to the server:
+
+\begin{verbatim}
+pool_sema.acquire()
+conn = connectdb()
+... use connection ...
+conn.close()
+pool_sema.release()
+\end{verbatim}
+
+The use of a bounded semaphore reduces the chance that a programming error
+which causes the semaphore to be released more than it's acquired will go
+undetected.
+
+
+\subsection{Event Objects \label{event-objects}}
+
+This is one of the simplest mechanisms for communication between
+threads: one thread signals an event and other threads wait for it.
+
+An event object manages an internal flag that can be set to true with
+the \method{set()} method and reset to false with the \method{clear()}
+method.  The \method{wait()} method blocks until the flag is true.
+
+
+\begin{classdesc}{Event}{}
+The internal flag is initially false.
+\end{classdesc}
+
+\begin{methoddesc}{isSet}{}
+Return true if and only if the internal flag is true.
+\end{methoddesc}
+
+\begin{methoddesc}{set}{}
+Set the internal flag to true.
+All threads waiting for it to become true are awakened.
+Threads that call \method{wait()} once the flag is true will not block
+at all.
+\end{methoddesc}
+
+\begin{methoddesc}{clear}{}
+Reset the internal flag to false.
+Subsequently, threads calling \method{wait()} will block until
+\method{set()} is called to set the internal flag to true again.
+\end{methoddesc}
+
+\begin{methoddesc}{wait}{\optional{timeout}}
+Block until the internal flag is true.
+If the internal flag is true on entry, return immediately.  Otherwise,
+block until another thread calls \method{set()} to set the flag to
+true, or until the optional timeout occurs.
+
+When the timeout argument is present and not \code{None}, it should be a
+floating point number specifying a timeout for the operation in
+seconds (or fractions thereof).
+\end{methoddesc}
+
+
+\subsection{Thread Objects \label{thread-objects}}
+
+This class represents an activity that is run in a separate thread
+of control.  There are two ways to specify the activity: by
+passing a callable object to the constructor, or by overriding the
+\method{run()} method in a subclass.  No other methods (except for the
+constructor) should be overridden in a subclass.  In other words, 
+\emph{only}  override the \method{__init__()} and \method{run()}
+methods of this class.
+
+Once a thread object is created, its activity must be started by
+calling the thread's \method{start()} method.  This invokes the
+\method{run()} method in a separate thread of control.
+
+Once the thread's activity is started, the thread is considered
+'alive'. It stops being alive when its \method{run()} method terminates
+-- either normally, or by raising an unhandled exception.  The
+\method{isAlive()} method tests whether the thread is alive.
+
+Other threads can call a thread's \method{join()} method.  This blocks
+the calling thread until the thread whose \method{join()} method is
+called is terminated.
+
+A thread has a name.  The name can be passed to the constructor,
+set with the \method{setName()} method, and retrieved with the
+\method{getName()} method.
+
+A thread can be flagged as a ``daemon thread''.  The significance
+of this flag is that the entire Python program exits when only
+daemon threads are left.  The initial value is inherited from the
+creating thread.  The flag can be set with the \method{setDaemon()}
+method and retrieved with the \method{isDaemon()} method.
+
+There is a ``main thread'' object; this corresponds to the
+initial thread of control in the Python program.  It is not a
+daemon thread.
+
+There is the possibility that ``dummy thread objects'' are created.
+These are thread objects corresponding to ``alien threads'', which
+are threads of control started outside the threading module, such as
+directly from C code.  Dummy thread objects have limited
+functionality; they are always considered alive and daemonic, and
+cannot be \method{join()}ed.  They are never deleted, since it is
+impossible to detect the termination of alien threads.
+
+
+\begin{classdesc}{Thread}{group=None, target=None, name=None,
+                          args=(), kwargs=\{\}}
+This constructor should always be called with keyword
+arguments.  Arguments are:
+
+\var{group} should be \code{None}; reserved for future extension when
+a \class{ThreadGroup} class is implemented.
+
+\var{target} is the callable object to be invoked by the
+\method{run()} method.  Defaults to \code{None}, meaning nothing is
+called.
+
+\var{name} is the thread name.  By default, a unique name is
+constructed of the form ``Thread-\var{N}'' where \var{N} is a small
+decimal number.
+
+\var{args} is the argument tuple for the target invocation.  Defaults
+to \code{()}.
+
+\var{kwargs} is a dictionary of keyword arguments for the target
+invocation.  Defaults to \code{\{\}}.
+
+If the subclass overrides the constructor, it must make sure
+to invoke the base class constructor (\code{Thread.__init__()})
+before doing anything else to the thread.
+\end{classdesc}
+
+\begin{methoddesc}{start}{}
+Start the thread's activity.
+
+This must be called at most once per thread object.  It
+arranges for the object's \method{run()} method to be invoked in a
+separate thread of control.
+\end{methoddesc}
+
+\begin{methoddesc}{run}{}
+Method representing the thread's activity.
+
+You may override this method in a subclass.  The standard
+\method{run()} method invokes the callable object passed to the
+object's constructor as the \var{target} argument, if any, with
+sequential and keyword arguments taken from the \var{args} and
+\var{kwargs} arguments, respectively.
+\end{methoddesc}
+
+\begin{methoddesc}{join}{\optional{timeout}}
+Wait until the thread terminates.
+This blocks the calling thread until the thread whose \method{join()}
+method is called terminates -- either normally or through an
+unhandled exception -- or until the optional timeout occurs.
+
+When the \var{timeout} argument is present and not \code{None}, it
+should be a floating point number specifying a timeout for the
+operation in seconds (or fractions thereof). As \method{join()} always 
+returns \code{None}, you must call \method{isAlive()} to decide whether 
+a timeout happened.
+
+When the \var{timeout} argument is not present or \code{None}, the
+operation will block until the thread terminates.
+
+A thread can be \method{join()}ed many times.
+
+A thread cannot join itself because this would cause a
+deadlock.
+
+It is an error to attempt to \method{join()} a thread before it has
+been started.
+\end{methoddesc}
+
+\begin{methoddesc}{getName}{}
+Return the thread's name.
+\end{methoddesc}
+
+\begin{methoddesc}{setName}{name}
+Set the thread's name.
+
+The name is a string used for identification purposes only.
+It has no semantics.  Multiple threads may be given the same
+name.  The initial name is set by the constructor.
+\end{methoddesc}
+
+\begin{methoddesc}{isAlive}{}
+Return whether the thread is alive.
+
+Roughly, a thread is alive from the moment the \method{start()} method
+returns until its \method{run()} method terminates. The module
+function \function{enumerate()} returns a list of all alive threads.
+\end{methoddesc}
+
+\begin{methoddesc}{isDaemon}{}
+Return the thread's daemon flag.
+\end{methoddesc}
+
+\begin{methoddesc}{setDaemon}{daemonic}
+Set the thread's daemon flag to the Boolean value \var{daemonic}.
+This must be called before \method{start()} is called.
+
+The initial value is inherited from the creating thread.
+
+The entire Python program exits when no alive non-daemon threads are
+left.
+\end{methoddesc}
+
+
+\subsection{Timer Objects \label{timer-objects}}
+
+This class represents an action that should be run only after a
+certain amount of time has passed --- a timer.  \class{Timer} is a
+subclass of \class{Thread} and as such also functions as an example of
+creating custom threads.
+
+Timers are started, as with threads, by calling their \method{start()}
+method.  The timer can be stopped (before its action has begun) by
+calling the \method{cancel()} method.  The interval the timer will
+wait before executing its action may not be exactly the same as the
+interval specified by the user.
+
+For example:
+\begin{verbatim}
+def hello():
+    print "hello, world"
+
+t = Timer(30.0, hello)
+t.start() # after 30 seconds, "hello, world" will be printed
+\end{verbatim}
+
+\begin{classdesc}{Timer}{interval, function, args=[], kwargs=\{\}}
+Create a timer that will run \var{function} with arguments \var{args} and 
+keyword arguments \var{kwargs}, after \var{interval} seconds have passed.
+\end{classdesc}
+
+\begin{methoddesc}{cancel}{}
+Stop the timer, and cancel the execution of the timer's action.  This
+will only work if the timer is still in its waiting stage.
+\end{methoddesc}
+
+\subsection{Using locks, conditions, and semaphores in the \keyword{with}
+statement \label{with-locks}}
+
+All of the objects provided by this module that have \method{acquire()} and
+\method{release()} methods can be used as context managers for a \keyword{with}
+statement.  The \method{acquire()} method will be called when the block is
+entered, and \method{release()} will be called when the block is exited.
+
+Currently, \class{Lock}, \class{RLock}, \class{Condition}, \class{Semaphore},
+and \class{BoundedSemaphore} objects may be used as \keyword{with}
+statement context managers.  For example:
+
+\begin{verbatim}
+from __future__ import with_statement
+import threading
+
+some_rlock = threading.RLock()
+
+with some_rlock:
+    print "some_rlock is locked while this executes"
+\end{verbatim}
+

Added: vendor/Python/current/Doc/lib/libtime.tex
===================================================================
--- vendor/Python/current/Doc/lib/libtime.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libtime.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,461 @@
+\section{\module{time} ---
+         Time access and conversions}
+
+\declaremodule{builtin}{time}
+\modulesynopsis{Time access and conversions.}
+
+
+This module provides various time-related functions.  It is always
+available, but not all functions are available on all platforms.  Most
+of the functions defined in this module call platform C library
+functions with the same name.  It may sometimes be helpful to consult
+the platform documentation, because the semantics of these functions
+varies among platforms.
+
+An explanation of some terminology and conventions is in order.
+
+\begin{itemize}
+
+\item
+The \dfn{epoch}\index{epoch} is the point where the time starts.  On
+January 1st of that year, at 0 hours, the ``time since the epoch'' is
+zero.  For \UNIX, the epoch is 1970.  To find out what the epoch is,
+look at \code{gmtime(0)}.
+
+\item
+The functions in this module do not handle dates and times before the
+epoch or far in the future.  The cut-off point in the future is
+determined by the C library; for \UNIX, it is typically in
+2038\index{Year 2038}.
+
+\item
+\strong{Year 2000 (Y2K) issues}:\index{Year 2000}\index{Y2K}  Python
+depends on the platform's C library, which generally doesn't have year
+2000 issues, since all dates and times are represented internally as
+seconds since the epoch.  Functions accepting a \class{struct_time}
+(see below) generally require a 4-digit year.  For backward
+compatibility, 2-digit years are supported if the module variable
+\code{accept2dyear} is a non-zero integer; this variable is
+initialized to \code{1} unless the environment variable
+\envvar{PYTHONY2K} is set to a non-empty string, in which case it is
+initialized to \code{0}.  Thus, you can set
+\envvar{PYTHONY2K} to a non-empty string in the environment to require 4-digit
+years for all year input.  When 2-digit years are accepted, they are
+converted according to the \POSIX{} or X/Open standard: values 69-99
+are mapped to 1969-1999, and values 0--68 are mapped to 2000--2068.
+Values 100--1899 are always illegal.  Note that this is new as of
+Python 1.5.2(a2); earlier versions, up to Python 1.5.1 and 1.5.2a1,
+would add 1900 to year values below 1900.
+
+\item
+UTC\index{UTC} is Coordinated Universal Time\index{Coordinated
+Universal Time} (formerly known as Greenwich Mean
+Time,\index{Greenwich Mean Time} or GMT).  The acronym UTC is not a
+mistake but a compromise between English and French.
+
+\item
+DST is Daylight Saving Time,\index{Daylight Saving Time} an adjustment
+of the timezone by (usually) one hour during part of the year.  DST
+rules are magic (determined by local law) and can change from year to
+year.  The C library has a table containing the local rules (often it
+is read from a system file for flexibility) and is the only source of
+True Wisdom in this respect.
+
+\item
+The precision of the various real-time functions may be less than
+suggested by the units in which their value or argument is expressed.
+E.g.\ on most \UNIX{} systems, the clock ``ticks'' only 50 or 100 times a
+second, and on the Mac, times are only accurate to whole seconds.
+
+\item
+On the other hand, the precision of \function{time()} and
+\function{sleep()} is better than their \UNIX{} equivalents: times are
+expressed as floating point numbers, \function{time()} returns the
+most accurate time available (using \UNIX{} \cfunction{gettimeofday()}
+where available), and \function{sleep()} will accept a time with a
+nonzero fraction (\UNIX{} \cfunction{select()} is used to implement
+this, where available).
+
+\item
+The time value as returned by \function{gmtime()},
+\function{localtime()}, and \function{strptime()}, and accepted by
+\function{asctime()}, \function{mktime()} and \function{strftime()},
+is a sequence of 9 integers.  The return values of \function{gmtime()},
+\function{localtime()}, and \function{strptime()} also offer attribute
+names for individual fields.
+
+\begin{tableiii}{c|l|l}{textrm}{Index}{Attribute}{Values}
+  \lineiii{0}{\member{tm_year}}{(for example, 1993)}
+  \lineiii{1}{\member{tm_mon}}{range [1,12]}
+  \lineiii{2}{\member{tm_mday}}{range [1,31]}
+  \lineiii{3}{\member{tm_hour}}{range [0,23]}
+  \lineiii{4}{\member{tm_min}}{range [0,59]}
+  \lineiii{5}{\member{tm_sec}}{range [0,61]; see \strong{(1)} in \function{strftime()} description}
+  \lineiii{6}{\member{tm_wday}}{range [0,6], Monday is 0}
+  \lineiii{7}{\member{tm_yday}}{range [1,366]}
+  \lineiii{8}{\member{tm_isdst}}{0, 1 or -1; see below}
+\end{tableiii}
+
+Note that unlike the C structure, the month value is a
+range of 1-12, not 0-11.  A year value will be handled as described
+under ``Year 2000 (Y2K) issues'' above.  A \code{-1} argument as the
+daylight savings flag, passed to \function{mktime()} will usually
+result in the correct daylight savings state to be filled in.
+
+When a tuple with an incorrect length is passed to a function
+expecting a \class{struct_time}, or having elements of the wrong type, a
+\exception{TypeError} is raised.
+
+\versionchanged[The time value sequence was changed from a tuple to a
+                \class{struct_time}, with the addition of attribute names
+                for the fields]{2.2}
+\end{itemize}
+
+The module defines the following functions and data items:
+
+
+\begin{datadesc}{accept2dyear}
+Boolean value indicating whether two-digit year values will be
+accepted.  This is true by default, but will be set to false if the
+environment variable \envvar{PYTHONY2K} has been set to a non-empty
+string.  It may also be modified at run time.
+\end{datadesc}
+
+\begin{datadesc}{altzone}
+The offset of the local DST timezone, in seconds west of UTC, if one
+is defined.  This is negative if the local DST timezone is east of UTC
+(as in Western Europe, including the UK).  Only use this if
+\code{daylight} is nonzero.
+\end{datadesc}
+
+\begin{funcdesc}{asctime}{\optional{t}}
+Convert a tuple or \class{struct_time} representing a time as returned
+by \function{gmtime()}
+or \function{localtime()} to a 24-character string of the following form:
+\code{'Sun Jun 20 23:21:05 1993'}.  If \var{t} is not provided, the
+current time as returned by \function{localtime()} is used.
+Locale information is not used by \function{asctime()}.
+\note{Unlike the C function of the same name, there is no trailing
+newline.}
+\versionchanged[Allowed \var{t} to be omitted]{2.1}
+\end{funcdesc}
+
+\begin{funcdesc}{clock}{}
+On \UNIX, return
+the current processor time as a floating point number expressed in
+seconds.  The precision, and in fact the very definition of the meaning
+of ``processor time''\index{CPU time}\index{processor time}, depends
+on that of the C function of the same name, but in any case, this is
+the function to use for benchmarking\index{benchmarking} Python or
+timing algorithms.
+
+On Windows, this function returns wall-clock seconds elapsed since the
+first call to this function, as a floating point number,
+based on the Win32 function \cfunction{QueryPerformanceCounter()}.
+The resolution is typically better than one microsecond.
+\end{funcdesc}
+
+\begin{funcdesc}{ctime}{\optional{secs}}
+Convert a time expressed in seconds since the epoch to a string
+representing local time. If \var{secs} is not provided or
+\constant{None}, the current time as returned by \function{time()} is
+used.  \code{ctime(\var{secs})} is equivalent to
+\code{asctime(localtime(\var{secs}))}.
+Locale information is not used by \function{ctime()}.
+\versionchanged[Allowed \var{secs} to be omitted]{2.1}
+\versionchanged[If \var{secs} is \constant{None}, the current time is
+                used]{2.4}
+\end{funcdesc}
+
+\begin{datadesc}{daylight}
+Nonzero if a DST timezone is defined.
+\end{datadesc}
+
+\begin{funcdesc}{gmtime}{\optional{secs}}
+Convert a time expressed in seconds since the epoch to a \class{struct_time}
+in UTC in which the dst flag is always zero.  If \var{secs} is not
+provided or \constant{None}, the current time as returned by
+\function{time()} is used.  Fractions of a second are ignored.  See
+above for a description of the \class{struct_time} object. See
+\function{calendar.timegm()} for the inverse of this function.
+\versionchanged[Allowed \var{secs} to be omitted]{2.1}
+\versionchanged[If \var{secs} is \constant{None}, the current time is
+                used]{2.4}
+\end{funcdesc}
+
+\begin{funcdesc}{localtime}{\optional{secs}}
+Like \function{gmtime()} but converts to local time.  If \var{secs} is
+not provided or \constant{None}, the current time as returned by
+\function{time()} is used.  The dst flag is set to \code{1} when DST
+applies to the given time.
+\versionchanged[Allowed \var{secs} to be omitted]{2.1}
+\versionchanged[If \var{secs} is \constant{None}, the current time is
+                used]{2.4}
+\end{funcdesc}
+
+\begin{funcdesc}{mktime}{t}
+This is the inverse function of \function{localtime()}.  Its argument
+is the \class{struct_time} or full 9-tuple (since the dst flag is
+needed; use \code{-1} as the dst flag if it is unknown) which
+expresses the time in
+\emph{local} time, not UTC.  It returns a floating point number, for
+compatibility with \function{time()}.  If the input value cannot be
+represented as a valid time, either \exception{OverflowError} or
+\exception{ValueError} will be raised (which depends on whether the
+invalid value is caught by Python or the underlying C libraries).  The
+earliest date for which it can generate a time is platform-dependent.
+\end{funcdesc}
+
+\begin{funcdesc}{sleep}{secs}
+Suspend execution for the given number of seconds.  The argument may
+be a floating point number to indicate a more precise sleep time.
+The actual suspension time may be less than that requested because any
+caught signal will terminate the \function{sleep()} following
+execution of that signal's catching routine.  Also, the suspension
+time may be longer than requested by an arbitrary amount because of
+the scheduling of other activity in the system.
+\end{funcdesc}
+
+\begin{funcdesc}{strftime}{format\optional{, t}}
+Convert a tuple or \class{struct_time} representing a time as returned
+by \function{gmtime()} or \function{localtime()} to a string as
+specified by the \var{format} argument.  If \var{t} is not
+provided, the current time as returned by \function{localtime()} is
+used.  \var{format} must be a string.  \exception{ValueError} is raised
+if any field in \var{t} is outside of the allowed range.
+\versionchanged[Allowed \var{t} to be omitted]{2.1}
+\versionchanged[\exception{ValueError} raised if a field in \var{t} is
+out of range]{2.4}
+\versionchanged[0 is now a legal argument for any position in the time tuple;
+if it is normally illegal the value is forced to a correct one.]{2.5}
+
+
+The following directives can be embedded in the \var{format} string.
+They are shown without the optional field width and precision
+specification, and are replaced by the indicated characters in the
+\function{strftime()} result:
+
+\begin{tableiii}{c|p{24em}|c}{code}{Directive}{Meaning}{Notes}
+  \lineiii{\%a}{Locale's abbreviated weekday name.}{}
+  \lineiii{\%A}{Locale's full weekday name.}{}
+  \lineiii{\%b}{Locale's abbreviated month name.}{}
+  \lineiii{\%B}{Locale's full month name.}{}
+  \lineiii{\%c}{Locale's appropriate date and time representation.}{}
+  \lineiii{\%d}{Day of the month as a decimal number [01,31].}{}
+  \lineiii{\%H}{Hour (24-hour clock) as a decimal number [00,23].}{}
+  \lineiii{\%I}{Hour (12-hour clock) as a decimal number [01,12].}{}
+  \lineiii{\%j}{Day of the year as a decimal number [001,366].}{}
+  \lineiii{\%m}{Month as a decimal number [01,12].}{}
+  \lineiii{\%M}{Minute as a decimal number [00,59].}{}
+  \lineiii{\%p}{Locale's equivalent of either AM or PM.}{(1)}
+  \lineiii{\%S}{Second as a decimal number [00,61].}{(2)}
+  \lineiii{\%U}{Week number of the year (Sunday as the first day of the
+                week) as a decimal number [00,53].  All days in a new year
+                preceding the first Sunday are considered to be in week 0.}{(3)}
+  \lineiii{\%w}{Weekday as a decimal number [0(Sunday),6].}{}
+  \lineiii{\%W}{Week number of the year (Monday as the first day of the
+                week) as a decimal number [00,53].  All days in a new year
+                preceding the first Monday are considered to be in week 0.}{(3)}
+  \lineiii{\%x}{Locale's appropriate date representation.}{}
+  \lineiii{\%X}{Locale's appropriate time representation.}{}
+  \lineiii{\%y}{Year without century as a decimal number [00,99].}{}
+  \lineiii{\%Y}{Year with century as a decimal number.}{}
+  \lineiii{\%Z}{Time zone name (no characters if no time zone exists).}{}
+  \lineiii{\%\%}{A literal \character{\%} character.}{}
+\end{tableiii}
+
+\noindent
+Notes:
+
+\begin{description}
+  \item[(1)]
+    When used with the \function{strptime()} function, the \code{\%p}
+    directive only affects the output hour field if the \code{\%I} directive
+    is used to parse the hour.
+  \item[(2)]
+    The range really is \code{0} to \code{61}; this accounts for leap
+    seconds and the (very rare) double leap seconds.
+  \item[(3)]
+    When used with the \function{strptime()} function, \code{\%U} and \code{\%W}
+    are only used in calculations when the day of the week and the year are
+    specified.
+\end{description}
+
+Here is an example, a format for dates compatible with that specified 
+in the \rfc{2822} Internet email standard.
+	\footnote{The use of \code{\%Z} is now
+	deprecated, but the \code{\%z} escape that expands to the preferred 
+	hour/minute offset is not supported by all ANSI C libraries. Also,
+	a strict reading of the original 1982 \rfc{822} standard calls for
+	a two-digit year (\%y rather than \%Y), but practice moved to
+	4-digit years long before the year 2000.  The 4-digit year has
+        been mandated by \rfc{2822}, which obsoletes \rfc{822}.}
+
+\begin{verbatim}
+>>> from time import gmtime, strftime
+>>> strftime("%a, %d %b %Y %H:%M:%S +0000", gmtime())
+'Thu, 28 Jun 2001 14:17:15 +0000'
+\end{verbatim}
+
+Additional directives may be supported on certain platforms, but
+only the ones listed here have a meaning standardized by ANSI C.
+
+On some platforms, an optional field width and precision
+specification can immediately follow the initial \character{\%} of a
+directive in the following order; this is also not portable.
+The field width is normally 2 except for \code{\%j} where it is 3.
+\end{funcdesc}
+
+\begin{funcdesc}{strptime}{string\optional{, format}}
+Parse a string representing a time according to a format.  The return 
+value is a \class{struct_time} as returned by \function{gmtime()} or
+\function{localtime()}.  The \var{format} parameter uses the same
+directives as those used by \function{strftime()}; it defaults to
+\code{"\%a \%b \%d \%H:\%M:\%S \%Y"} which matches the formatting
+returned by \function{ctime()}.  If \var{string} cannot be parsed
+according to \var{format}, \exception{ValueError} is raised.  If the
+string to be parsed has excess data after parsing,
+\exception{ValueError} is raised.  The default values used to fill in
+any missing data when more accurate values cannot be inferred are
+\code{(1900, 1, 1, 0, 0, 0, 0, 1, -1)} .
+
+Support for the \code{\%Z} directive is based on the values contained in
+\code{tzname} and whether \code{daylight} is true.  Because of this,
+it is platform-specific except for recognizing UTC and GMT which are
+always known (and are considered to be non-daylight savings
+timezones).
+\end{funcdesc}
+
+\begin{datadesc}{struct_time}
+The type of the time value sequence returned by \function{gmtime()},
+\function{localtime()}, and \function{strptime()}.
+\versionadded{2.2}
+\end{datadesc}
+
+\begin{funcdesc}{time}{}
+Return the time as a floating point number expressed in seconds since
+the epoch, in UTC.  Note that even though the time is always returned
+as a floating point number, not all systems provide time with a better
+precision than 1 second.  While this function normally returns
+non-decreasing values, it can return a lower value than a previous
+call if the system clock has been set back between the two calls.
+\end{funcdesc}
+
+\begin{datadesc}{timezone}
+The offset of the local (non-DST) timezone, in seconds west of UTC
+(negative in most of Western Europe, positive in the US, zero in the
+UK).
+\end{datadesc}
+
+\begin{datadesc}{tzname}
+A tuple of two strings: the first is the name of the local non-DST
+timezone, the second is the name of the local DST timezone.  If no DST
+timezone is defined, the second string should not be used.
+\end{datadesc}
+
+\begin{funcdesc}{tzset}{}
+Resets the time conversion rules used by the library routines.
+The environment variable \envvar{TZ} specifies how this is done.
+\versionadded{2.3}
+
+Availability: \UNIX.
+
+\begin{notice}
+Although in many cases, changing the \envvar{TZ} environment variable
+may affect the output of functions like \function{localtime} without calling 
+\function{tzset}, this behavior should not be relied on.
+
+The \envvar{TZ} environment variable should contain no whitespace.
+\end{notice}
+
+The standard format of the \envvar{TZ} environment variable is:
+(whitespace added for clarity)
+\begin{itemize}
+    \item[std offset [dst [offset] [,start[/time], end[/time]]]]
+\end{itemize}
+
+Where:
+
+\begin{itemize}
+  \item[std and dst]
+    Three or more alphanumerics giving the timezone abbreviations.
+    These will be propagated into time.tzname
+
+  \item[offset]
+    The offset has the form: \plusminus{} hh[:mm[:ss]].
+    This indicates the value added the local time to arrive at UTC. 
+    If preceded by a '-', the timezone is east of the Prime 
+    Meridian; otherwise, it is west. If no offset follows
+    dst, summer time is assumed to be one hour ahead of standard time.
+
+  \item[start[/time],end[/time]]
+    Indicates when to change to and back from DST. The format of the
+    start and end dates are one of the following:
+
+    \begin{itemize}
+      \item[J\var{n}]
+        The Julian day \var{n} (1 <= \var{n} <= 365). Leap days are not 
+        counted, so in all years February 28 is day 59 and
+        March 1 is day 60.
+
+    \item[\var{n}]
+        The zero-based Julian day (0 <= \var{n} <= 365). Leap days are
+        counted, and it is possible to refer to February 29.
+
+      \item[M\var{m}.\var{n}.\var{d}]
+        The \var{d}'th day (0 <= \var{d} <= 6) or week \var{n} 
+        of month \var{m} of the year (1 <= \var{n} <= 5, 
+        1 <= \var{m} <= 12, where week 5 means "the last \var{d} day
+        in month \var{m}" which may occur in either the fourth or 
+        the fifth week). Week 1 is the first week in which the 
+        \var{d}'th day occurs. Day zero is Sunday.
+    \end{itemize}
+
+    time has the same format as offset except that no leading sign ('-' or
+    '+') is allowed. The default, if time is not given, is 02:00:00.
+\end{itemize}
+
+
+\begin{verbatim}
+>>> os.environ['TZ'] = 'EST+05EDT,M4.1.0,M10.5.0'
+>>> time.tzset()
+>>> time.strftime('%X %x %Z')
+'02:07:36 05/08/03 EDT'
+>>> os.environ['TZ'] = 'AEST-10AEDT-11,M10.5.0,M3.5.0'
+>>> time.tzset()
+>>> time.strftime('%X %x %Z')
+'16:08:12 05/08/03 AEST'
+\end{verbatim}
+
+On many \UNIX{} systems (including *BSD, Linux, Solaris, and Darwin), it
+is more convenient to use the system's zoneinfo (\manpage{tzfile}{5}) 
+database to specify the timezone rules. To do this, set the 
+\envvar{TZ} environment variable to the path of the required timezone 
+datafile, relative to the root of the systems 'zoneinfo' timezone database,
+usually located at \file{/usr/share/zoneinfo}. For example, 
+\code{'US/Eastern'}, \code{'Australia/Melbourne'}, \code{'Egypt'} or 
+\code{'Europe/Amsterdam'}.
+
+\begin{verbatim}
+>>> os.environ['TZ'] = 'US/Eastern'
+>>> time.tzset()
+>>> time.tzname
+('EST', 'EDT')
+>>> os.environ['TZ'] = 'Egypt'
+>>> time.tzset()
+>>> time.tzname
+('EET', 'EEST')
+\end{verbatim}
+
+\end{funcdesc}
+
+
+\begin{seealso}
+  \seemodule{datetime}{More object-oriented interface to dates and times.}
+  \seemodule{locale}{Internationalization services.  The locale
+                     settings can affect the return values for some of 
+                     the functions in the \module{time} module.}
+  \seemodule{calendar}{General calendar-related functions.  
+                       \function{timegm()} is the inverse of
+                       \function{gmtime()} from this module.}
+\end{seealso}

Added: vendor/Python/current/Doc/lib/libtimeit.tex
===================================================================
--- vendor/Python/current/Doc/lib/libtimeit.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libtimeit.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,224 @@
+\section{\module{timeit} ---
+         Measure execution time of small code snippets}
+
+\declaremodule{standard}{timeit}
+\modulesynopsis{Measure the execution time of small code snippets.}
+
+\versionadded{2.3}
+\index{Benchmarking}
+\index{Performance}
+
+This module provides a simple way to time small bits of Python code.
+It has both command line as well as callable interfaces.  It avoids a
+number of common traps for measuring execution times.  See also Tim
+Peters' introduction to the ``Algorithms'' chapter in the
+\citetitle{Python Cookbook}, published by O'Reilly.
+
+The module defines the following public class:
+
+\begin{classdesc}{Timer}{\optional{stmt=\code{'pass'}
+                         \optional{, setup=\code{'pass'}
+                         \optional{, timer=<timer function>}}}}
+Class for timing execution speed of small code snippets.
+
+The constructor takes a statement to be timed, an additional statement
+used for setup, and a timer function.  Both statements default to
+\code{'pass'}; the timer function is platform-dependent (see the
+module doc string).  The statements may contain newlines, as long as
+they don't contain multi-line string literals.
+
+To measure the execution time of the first statement, use the
+\method{timeit()} method.  The \method{repeat()} method is a
+convenience to call \method{timeit()} multiple times and return a list
+of results.
+\end{classdesc}
+
+\begin{methoddesc}{print_exc}{\optional{file=\constant{None}}}
+Helper to print a traceback from the timed code.
+
+Typical use:
+
+\begin{verbatim}
+    t = Timer(...)       # outside the try/except
+    try:
+        t.timeit(...)    # or t.repeat(...)
+    except:
+        t.print_exc()
+\end{verbatim}
+
+The advantage over the standard traceback is that source lines in the
+compiled template will be displayed.
+The optional \var{file} argument directs where the traceback is sent;
+it defaults to \code{sys.stderr}.
+\end{methoddesc}
+
+\begin{methoddesc}{repeat}{\optional{repeat\code{=3} \optional{,
+                           number\code{=1000000}}}}
+Call \method{timeit()} a few times.
+
+This is a convenience function that calls the \method{timeit()}
+repeatedly, returning a list of results.  The first argument specifies
+how many times to call \method{timeit()}.  The second argument
+specifies the \var{number} argument for \function{timeit()}.
+
+\begin{notice}
+It's tempting to calculate mean and standard deviation from the result
+vector and report these.  However, this is not very useful.  In a typical
+case, the lowest value gives a lower bound for how fast your machine can run
+the given code snippet; higher values in the result vector are typically not
+caused by variability in Python's speed, but by other processes interfering
+with your timing accuracy.  So the \function{min()} of the result is
+probably the only number you should be interested in.  After that, you
+should look at the entire vector and apply common sense rather than
+statistics.
+\end{notice}
+\end{methoddesc}
+
+\begin{methoddesc}{timeit}{\optional{number\code{=1000000}}}
+Time \var{number} executions of the main statement.
+This executes the setup statement once, and then
+returns the time it takes to execute the main statement a number of
+times, measured in seconds as a float.  The argument is the number of
+times through the loop, defaulting to one million.  The main
+statement, the setup statement and the timer function to be used are
+passed to the constructor.
+
+\begin{notice}
+By default, \method{timeit()} temporarily turns off garbage collection
+during the timing.  The advantage of this approach is that it makes
+independent timings more comparable.  This disadvantage is that GC
+may be an important component of the performance of the function being
+measured.  If so, GC can be re-enabled as the first statement in the
+\var{setup} string.  For example:
+\begin{verbatim}
+    timeit.Timer('for i in xrange(10): oct(i)', 'gc.enable()').timeit()
+\end{verbatim}
+\end{notice}
+\end{methoddesc}
+
+
+\subsection{Command Line Interface}
+
+When called as a program from the command line, the following form is used:
+
+\begin{verbatim}
+python -m timeit [-n N] [-r N] [-s S] [-t] [-c] [-h] [statement ...]
+\end{verbatim}
+
+where the following options are understood:
+
+\begin{description}
+\item[-n N/\longprogramopt{number=N}] how many times to execute 'statement'
+\item[-r N/\longprogramopt{repeat=N}] how many times to repeat the timer (default 3)
+\item[-s S/\longprogramopt{setup=S}] statement to be executed once initially (default
+\code{'pass'})
+\item[-t/\longprogramopt{time}] use \function{time.time()}
+(default on all platforms but Windows)
+\item[-c/\longprogramopt{clock}] use \function{time.clock()} (default on Windows)
+\item[-v/\longprogramopt{verbose}] print raw timing results; repeat for more digits
+precision
+\item[-h/\longprogramopt{help}] print a short usage message and exit
+\end{description}
+
+A multi-line statement may be given by specifying each line as a
+separate statement argument; indented lines are possible by enclosing
+an argument in quotes and using leading spaces.  Multiple
+\programopt{-s} options are treated similarly.
+
+If \programopt{-n} is not given, a suitable number of loops is
+calculated by trying successive powers of 10 until the total time is
+at least 0.2 seconds.
+
+The default timer function is platform dependent.  On Windows,
+\function{time.clock()} has microsecond granularity but
+\function{time.time()}'s granularity is 1/60th of a second; on \UNIX,
+\function{time.clock()} has 1/100th of a second granularity and
+\function{time.time()} is much more precise.  On either platform, the
+default timer functions measure wall clock time, not the CPU time.
+This means that other processes running on the same computer may
+interfere with the timing.  The best thing to do when accurate timing
+is necessary is to repeat the timing a few times and use the best
+time.  The \programopt{-r} option is good for this; the default of 3
+repetitions is probably enough in most cases.  On \UNIX, you can use
+\function{time.clock()} to measure CPU time.
+
+\begin{notice}
+  There is a certain baseline overhead associated with executing a
+  pass statement.  The code here doesn't try to hide it, but you
+  should be aware of it.  The baseline overhead can be measured by
+  invoking the program without arguments.
+\end{notice}
+
+The baseline overhead differs between Python versions!  Also, to
+fairly compare older Python versions to Python 2.3, you may want to
+use Python's \programopt{-O} option for the older versions to avoid
+timing \code{SET_LINENO} instructions.
+
+\subsection{Examples}
+
+Here are two example sessions (one using the command line, one using
+the module interface) that compare the cost of using
+\function{hasattr()} vs. \keyword{try}/\keyword{except} to test for
+missing and present object attributes.
+
+\begin{verbatim}
+% timeit.py 'try:' '  str.__nonzero__' 'except AttributeError:' '  pass'
+100000 loops, best of 3: 15.7 usec per loop
+% timeit.py 'if hasattr(str, "__nonzero__"): pass'
+100000 loops, best of 3: 4.26 usec per loop
+% timeit.py 'try:' '  int.__nonzero__' 'except AttributeError:' '  pass'
+1000000 loops, best of 3: 1.43 usec per loop
+% timeit.py 'if hasattr(int, "__nonzero__"): pass'
+100000 loops, best of 3: 2.23 usec per loop
+\end{verbatim}
+
+\begin{verbatim}
+>>> import timeit
+>>> s = """\
+... try:
+...     str.__nonzero__
+... except AttributeError:
+...     pass
+... """
+>>> t = timeit.Timer(stmt=s)
+>>> print "%.2f usec/pass" % (1000000 * t.timeit(number=100000)/100000)
+17.09 usec/pass
+>>> s = """\
+... if hasattr(str, '__nonzero__'): pass
+... """
+>>> t = timeit.Timer(stmt=s)
+>>> print "%.2f usec/pass" % (1000000 * t.timeit(number=100000)/100000)
+4.85 usec/pass
+>>> s = """\
+... try:
+...     int.__nonzero__
+... except AttributeError:
+...     pass
+... """
+>>> t = timeit.Timer(stmt=s)
+>>> print "%.2f usec/pass" % (1000000 * t.timeit(number=100000)/100000)
+1.97 usec/pass
+>>> s = """\
+... if hasattr(int, '__nonzero__'): pass
+... """
+>>> t = timeit.Timer(stmt=s)
+>>> print "%.2f usec/pass" % (1000000 * t.timeit(number=100000)/100000)
+3.15 usec/pass
+\end{verbatim}
+
+To give the \module{timeit} module access to functions you
+define, you can pass a \code{setup} parameter which contains an import
+statement:
+
+\begin{verbatim}
+def test():
+    "Stupid test function"
+    L = []
+    for i in range(100):
+        L.append(i)
+
+if __name__=='__main__':
+    from timeit import Timer
+    t = Timer("test()", "from __main__ import test")
+    print t.timeit()
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/libtoken.tex
===================================================================
--- vendor/Python/current/Doc/lib/libtoken.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libtoken.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,44 @@
+\section{\module{token} ---
+         Constants used with Python parse trees}
+
+\declaremodule{standard}{token}
+\modulesynopsis{Constants representing terminal nodes of the parse tree.}
+\sectionauthor{Fred L. Drake, Jr.}{fdrake at acm.org}
+
+
+This module provides constants which represent the numeric values of
+leaf nodes of the parse tree (terminal tokens).  Refer to the file
+\file{Grammar/Grammar} in the Python distribution for the definitions
+of the names in the context of the language grammar.  The specific
+numeric values which the names map to may change between Python
+versions.
+
+This module also provides one data object and some functions.  The
+functions mirror definitions in the Python C header files.
+
+
+
+\begin{datadesc}{tok_name}
+Dictionary mapping the numeric values of the constants defined in this
+module back to name strings, allowing more human-readable
+representation of parse trees to be generated.
+\end{datadesc}
+
+\begin{funcdesc}{ISTERMINAL}{x}
+Return true for terminal token values.
+\end{funcdesc}
+
+\begin{funcdesc}{ISNONTERMINAL}{x}
+Return true for non-terminal token values.
+\end{funcdesc}
+
+\begin{funcdesc}{ISEOF}{x}
+Return true if \var{x} is the marker indicating the end of input.
+\end{funcdesc}
+
+
+\begin{seealso}
+  \seemodule{parser}{The second example for the \refmodule{parser}
+                     module shows how to use the \module{symbol}
+                     module.}
+\end{seealso}

Added: vendor/Python/current/Doc/lib/libtokenize.tex
===================================================================
--- vendor/Python/current/Doc/lib/libtokenize.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libtokenize.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,119 @@
+\section{\module{tokenize} ---
+         Tokenizer for Python source}
+
+\declaremodule{standard}{tokenize}
+\modulesynopsis{Lexical scanner for Python source code.}
+\moduleauthor{Ka Ping Yee}{}
+\sectionauthor{Fred L. Drake, Jr.}{fdrake at acm.org}
+
+
+The \module{tokenize} module provides a lexical scanner for Python
+source code, implemented in Python.  The scanner in this module
+returns comments as tokens as well, making it useful for implementing
+``pretty-printers,'' including colorizers for on-screen displays.
+
+The primary entry point is a generator:
+
+\begin{funcdesc}{generate_tokens}{readline}
+  The \function{generate_tokens()} generator requires one argment,
+  \var{readline}, which must be a callable object which
+  provides the same interface as the \method{readline()} method of
+  built-in file objects (see section~\ref{bltin-file-objects}).  Each
+  call to the function should return one line of input as a string.
+
+  The generator produces 5-tuples with these members:
+  the token type;
+  the token string;
+  a 2-tuple \code{(\var{srow}, \var{scol})} of ints specifying the
+  row and column where the token begins in the source;
+  a 2-tuple \code{(\var{erow}, \var{ecol})} of ints specifying the
+  row and column where the token ends in the source;
+  and the line on which the token was found.
+  The line passed is the \emph{logical} line;
+  continuation lines are included.
+  \versionadded{2.2}
+\end{funcdesc}
+
+An older entry point is retained for backward compatibility:
+
+\begin{funcdesc}{tokenize}{readline\optional{, tokeneater}}
+  The \function{tokenize()} function accepts two parameters: one
+  representing the input stream, and one providing an output mechanism
+  for \function{tokenize()}.
+
+  The first parameter, \var{readline}, must be a callable object which
+  provides the same interface as the \method{readline()} method of
+  built-in file objects (see section~\ref{bltin-file-objects}).  Each
+  call to the function should return one line of input as a string.
+  Alternately, \var{readline} may be a callable object that signals
+  completion by raising \exception{StopIteration}.
+  \versionchanged[Added \exception{StopIteration} support]{2.5}
+
+  The second parameter, \var{tokeneater}, must also be a callable
+  object.  It is called once for each token, with five arguments,
+  corresponding to the tuples generated by \function{generate_tokens()}.
+\end{funcdesc}
+
+
+All constants from the \refmodule{token} module are also exported from
+\module{tokenize}, as are two additional token type values that might be
+passed to the \var{tokeneater} function by \function{tokenize()}:
+
+\begin{datadesc}{COMMENT}
+  Token value used to indicate a comment.
+\end{datadesc}
+\begin{datadesc}{NL}
+  Token value used to indicate a non-terminating newline.  The NEWLINE
+  token indicates the end of a logical line of Python code; NL tokens
+  are generated when a logical line of code is continued over multiple
+  physical lines.
+\end{datadesc}
+
+Another function is provided to reverse the tokenization process.
+This is useful for creating tools that tokenize a script, modify
+the token stream, and write back the modified script.
+
+\begin{funcdesc}{untokenize}{iterable}
+  Converts tokens back into Python source code.  The \var{iterable}
+  must return sequences with at least two elements, the token type and
+  the token string.  Any additional sequence elements are ignored.
+
+  The reconstructed script is returned as a single string.  The
+  result is guaranteed to tokenize back to match the input so that
+  the conversion is lossless and round-trips are assured.  The
+  guarantee applies only to the token type and token string as
+  the spacing between tokens (column positions) may change.
+  \versionadded{2.5}
+\end{funcdesc}
+
+Example of a script re-writer that transforms float literals into
+Decimal objects:
+\begin{verbatim}
+def decistmt(s):
+    """Substitute Decimals for floats in a string of statements.
+
+    >>> from decimal import Decimal
+    >>> s = 'print +21.3e-5*-.1234/81.7'
+    >>> decistmt(s)
+    "print +Decimal ('21.3e-5')*-Decimal ('.1234')/Decimal ('81.7')"
+
+    >>> exec(s)
+    -3.21716034272e-007
+    >>> exec(decistmt(s))
+    -3.217160342717258261933904529E-7
+
+    """
+    result = []
+    g = generate_tokens(StringIO(s).readline)   # tokenize the string
+    for toknum, tokval, _, _, _  in g:
+        if toknum == NUMBER and '.' in tokval:  # replace NUMBER tokens
+            result.extend([
+                (NAME, 'Decimal'),
+                (OP, '('),
+                (STRING, repr(tokval)),
+                (OP, ')')
+            ])
+        else:
+            result.append((toknum, tokval))
+    return untokenize(result)
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/libtrace.tex
===================================================================
--- vendor/Python/current/Doc/lib/libtrace.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libtrace.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,125 @@
+\section{\module{trace} ---
+         Trace or track Python statement execution}
+
+\declaremodule{standard}{trace}
+\modulesynopsis{Trace or track Python statement execution.}
+
+The \module{trace} module allows you to trace program execution, generate
+annotated statement coverage listings, print caller/callee relationships and
+list functions executed during a program run.  It can be used in another
+program or from the command line.
+
+\subsection{Command Line Usage\label{trace-cli}}
+
+The \module{trace} module can be invoked from the command line.  It can be
+as simple as
+
+\begin{verbatim}
+python -m trace --count somefile.py ...
+\end{verbatim}
+
+The above will generate annotated listings of all Python modules imported
+during the execution of \file{somefile.py}.
+
+The following command-line arguments are supported:
+
+\begin{description}
+\item[\longprogramopt{trace}, \programopt{-t}]
+Display lines as they are executed.
+
+\item[\longprogramopt{count}, \programopt{-c}]
+Produce a set of  annotated listing files upon program
+completion that shows how many times each statement was executed.
+
+\item[\longprogramopt{report}, \programopt{-r}]
+Produce an annotated list from an earlier program run that
+used the \longprogramopt{count} and \longprogramopt{file} arguments.
+
+\item[\longprogramopt{no-report}, \programopt{-R}]
+Do not generate annotated listings.  This is useful if you intend to make
+several runs with \longprogramopt{count} then produce a single set
+of annotated listings at the end.
+
+\item[\longprogramopt{listfuncs}, \programopt{-l}]
+List the functions executed by running the program.
+
+\item[\longprogramopt{trackcalls}, \programopt{-T}]
+Generate calling relationships exposed by running the program.
+
+\item[\longprogramopt{file}, \programopt{-f}]
+Name a file containing (or to contain) counts.
+
+\item[\longprogramopt{coverdir}, \programopt{-C}]
+Name a directory in which to save annotated listing files.
+
+\item[\longprogramopt{missing}, \programopt{-m}]
+When generating annotated listings, mark lines which
+were not executed with `\code{>>>>>>}'.
+
+\item[\longprogramopt{summary}, \programopt{-s}]
+When using \longprogramopt{count} or \longprogramopt{report}, write a
+brief summary to stdout for each file processed.
+
+\item[\longprogramopt{ignore-module}]
+Ignore the named module and its submodules (if it is
+a package).  May be given multiple times.
+
+\item[\longprogramopt{ignore-dir}]
+Ignore all modules and packages in the named directory
+and subdirectories.  May be given multiple times.
+\end{description}
+
+\subsection{Programming Interface\label{trace-api}}
+
+\begin{classdesc}{Trace}{\optional{count=1\optional{, trace=1\optional{,
+                         countfuncs=0\optional{, countcallers=0\optional{,
+                         ignoremods=()\optional{, ignoredirs=()\optional{,
+                         infile=None\optional{, outfile=None}}}}}}}}}
+Create an object to trace execution of a single statement or expression.
+All parameters are optional.  \var{count} enables counting of line numbers.
+\var{trace} enables line execution tracing.  \var{countfuncs} enables
+listing of the functions called during the run.  \var{countcallers} enables
+call relationship tracking.  \var{ignoremods} is a list of modules or
+packages to ignore.  \var{ignoredirs} is a list of directories whose modules
+or packages should be ignored.  \var{infile} is the file from which to read
+stored count information.  \var{outfile} is a file in which to write updated
+count information.
+\end{classdesc}
+
+\begin{methoddesc}[Trace]{run}{cmd}
+Run \var{cmd} under control of the Trace object with the current tracing
+parameters.
+\end{methoddesc}
+
+\begin{methoddesc}[Trace]{runctx}{cmd\optional{, globals=None\optional{,
+                                  locals=None}}}
+Run \var{cmd} under control of the Trace object with the current tracing
+parameters in the defined global and local environments.  If not defined,
+\var{globals} and \var{locals} default to empty dictionaries.
+\end{methoddesc}
+
+\begin{methoddesc}[Trace]{runfunc}{func, *args, **kwds}
+Call \var{func} with the given arguments under control of the
+\class{Trace} object with the current tracing parameters.
+\end{methoddesc}
+
+This is a simple example showing the use of this module:
+
+\begin{verbatim}
+import sys
+import trace
+
+# create a Trace object, telling it what to ignore, and whether to
+# do tracing or line-counting or both.
+tracer = trace.Trace(
+    ignoredirs=[sys.prefix, sys.exec_prefix],
+    trace=0,
+    count=1)
+
+# run the new command using the given tracer
+tracer.run('main()')
+
+# make a report, placing output in /tmp
+r = tracer.results()
+r.write_results(show_missing=True, coverdir="/tmp")
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/libtraceback.tex
===================================================================
--- vendor/Python/current/Doc/lib/libtraceback.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libtraceback.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,157 @@
+\section{\module{traceback} ---
+         Print or retrieve a stack traceback}
+
+\declaremodule{standard}{traceback}
+\modulesynopsis{Print or retrieve a stack traceback.}
+
+
+This module provides a standard interface to extract, format and print
+stack traces of Python programs.  It exactly mimics the behavior of
+the Python interpreter when it prints a stack trace.  This is useful
+when you want to print stack traces under program control, such as in a
+``wrapper'' around the interpreter.
+
+The module uses traceback objects --- this is the object type that is
+stored in the variables \code{sys.exc_traceback} (deprecated) and
+\code{sys.last_traceback} and returned as the third item from
+\function{sys.exc_info()}.
+\obindex{traceback}
+
+The module defines the following functions:
+
+\begin{funcdesc}{print_tb}{traceback\optional{, limit\optional{, file}}}
+Print up to \var{limit} stack trace entries from \var{traceback}.  If
+\var{limit} is omitted or \code{None}, all entries are printed.
+If \var{file} is omitted or \code{None}, the output goes to
+\code{sys.stderr}; otherwise it should be an open file or file-like
+object to receive the output.
+\end{funcdesc}
+
+\begin{funcdesc}{print_exception}{type, value, traceback\optional{,
+                                  limit\optional{, file}}}
+Print exception information and up to \var{limit} stack trace entries
+from \var{traceback} to \var{file}.
+This differs from \function{print_tb()} in the
+following ways: (1) if \var{traceback} is not \code{None}, it prints a
+header \samp{Traceback (most recent call last):}; (2) it prints the
+exception \var{type} and \var{value} after the stack trace; (3) if
+\var{type} is \exception{SyntaxError} and \var{value} has the
+appropriate format, it prints the line where the syntax error occurred
+with a caret indicating the approximate position of the error.
+\end{funcdesc}
+
+\begin{funcdesc}{print_exc}{\optional{limit\optional{, file}}}
+This is a shorthand for \code{print_exception(sys.exc_type,
+sys.exc_value, sys.exc_traceback, \var{limit}, \var{file})}.  (In
+fact, it uses \function{sys.exc_info()} to retrieve the same
+information in a thread-safe way instead of using the deprecated
+variables.)
+\end{funcdesc}
+
+\begin{funcdesc}{format_exc}{\optional{limit}}
+This is like \code{print_exc(\var{limit})} but returns a string
+instead of printing to a file.
+\versionadded{2.4}
+\end{funcdesc}
+
+\begin{funcdesc}{print_last}{\optional{limit\optional{, file}}}
+This is a shorthand for \code{print_exception(sys.last_type,
+sys.last_value, sys.last_traceback, \var{limit}, \var{file})}.
+\end{funcdesc}
+
+\begin{funcdesc}{print_stack}{\optional{f\optional{, limit\optional{, file}}}}
+This function prints a stack trace from its invocation point.  The
+optional \var{f} argument can be used to specify an alternate stack
+frame to start.  The optional \var{limit} and \var{file} arguments have the
+same meaning as for \function{print_exception()}.
+\end{funcdesc}
+
+\begin{funcdesc}{extract_tb}{traceback\optional{, limit}}
+Return a list of up to \var{limit} ``pre-processed'' stack trace
+entries extracted from the traceback object \var{traceback}.  It is
+useful for alternate formatting of stack traces.  If \var{limit} is
+omitted or \code{None}, all entries are extracted.  A
+``pre-processed'' stack trace entry is a quadruple (\var{filename},
+\var{line number}, \var{function name}, \var{text}) representing
+the information that is usually printed for a stack trace.  The
+\var{text} is a string with leading and trailing whitespace
+stripped; if the source is not available it is \code{None}.
+\end{funcdesc}
+
+\begin{funcdesc}{extract_stack}{\optional{f\optional{, limit}}}
+Extract the raw traceback from the current stack frame.  The return
+value has the same format as for \function{extract_tb()}.  The
+optional \var{f} and \var{limit} arguments have the same meaning as
+for \function{print_stack()}.
+\end{funcdesc}
+
+\begin{funcdesc}{format_list}{list}
+Given a list of tuples as returned by \function{extract_tb()} or
+\function{extract_stack()}, return a list of strings ready for
+printing.  Each string in the resulting list corresponds to the item
+with the same index in the argument list.  Each string ends in a
+newline; the strings may contain internal newlines as well, for those
+items whose source text line is not \code{None}.
+\end{funcdesc}
+
+\begin{funcdesc}{format_exception_only}{type, value}
+Format the exception part of a traceback.  The arguments are the
+exception type and value such as given by \code{sys.last_type} and
+\code{sys.last_value}.  The return value is a list of strings, each
+ending in a newline.  Normally, the list contains a single string;
+however, for \exception{SyntaxError} exceptions, it contains several
+lines that (when printed) display detailed information about where the
+syntax error occurred.  The message indicating which exception
+occurred is the always last string in the list.
+\end{funcdesc}
+
+\begin{funcdesc}{format_exception}{type, value, tb\optional{, limit}}
+Format a stack trace and the exception information.  The arguments 
+have the same meaning as the corresponding arguments to
+\function{print_exception()}.  The return value is a list of strings,
+each ending in a newline and some containing internal newlines.  When
+these lines are concatenated and printed, exactly the same text is
+printed as does \function{print_exception()}.
+\end{funcdesc}
+
+\begin{funcdesc}{format_tb}{tb\optional{, limit}}
+A shorthand for \code{format_list(extract_tb(\var{tb}, \var{limit}))}.
+\end{funcdesc}
+
+\begin{funcdesc}{format_stack}{\optional{f\optional{, limit}}}
+A shorthand for \code{format_list(extract_stack(\var{f}, \var{limit}))}.
+\end{funcdesc}
+
+\begin{funcdesc}{tb_lineno}{tb}
+This function returns the current line number set in the traceback
+object.  This function was necessary because in versions of Python
+prior to 2.3 when the \programopt{-O} flag was passed to Python the
+\code{\var{tb}.tb_lineno} was not updated correctly.  This function
+has no use in versions past 2.3.
+\end{funcdesc}
+
+
+\subsection{Traceback Example \label{traceback-example}}
+
+This simple example implements a basic read-eval-print loop, similar
+to (but less useful than) the standard Python interactive interpreter
+loop.  For a more complete implementation of the interpreter loop,
+refer to the \refmodule{code} module.
+
+\begin{verbatim}
+import sys, traceback
+
+def run_user_code(envdir):
+    source = raw_input(">>> ")
+    try:
+        exec source in envdir
+    except:
+        print "Exception in user code:"
+        print '-'*60
+        traceback.print_exc(file=sys.stdout)
+        print '-'*60
+
+envdir = {}
+while 1:
+    run_user_code(envdir)
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/libtty.tex
===================================================================
--- vendor/Python/current/Doc/lib/libtty.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libtty.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,34 @@
+\section{\module{tty} ---
+         Terminal control functions}
+
+\declaremodule{standard}{tty}
+  \platform{Unix}
+\moduleauthor{Steen Lumholt}{}
+\sectionauthor{Moshe Zadka}{moshez at zadka.site.co.il}
+\modulesynopsis{Utility functions that perform common terminal control
+                operations.}
+
+The \module{tty} module defines functions for putting the tty into
+cbreak and raw modes.
+
+Because it requires the \refmodule{termios} module, it will work
+only on \UNIX.
+
+The \module{tty} module defines the following functions:
+
+\begin{funcdesc}{setraw}{fd\optional{, when}}
+Change the mode of the file descriptor \var{fd} to raw. If \var{when}
+is omitted, it defaults to \constant{termios.TCSAFLUSH}, and is passed
+to \function{termios.tcsetattr()}.
+\end{funcdesc}
+
+\begin{funcdesc}{setcbreak}{fd\optional{, when}}
+Change the mode of file descriptor \var{fd} to cbreak. If \var{when}
+is omitted, it defaults to \constant{termios.TCSAFLUSH}, and is passed
+to \function{termios.tcsetattr()}.
+\end{funcdesc}
+
+
+\begin{seealso}
+  \seemodule{termios}{Low-level terminal control interface.}
+\end{seealso}

Added: vendor/Python/current/Doc/lib/libturtle.tex
===================================================================
--- vendor/Python/current/Doc/lib/libturtle.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libturtle.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,268 @@
+\section{\module{turtle} ---
+         Turtle graphics for Tk}
+
+\declaremodule{standard}{turtle}
+   \platform{Tk}
+\moduleauthor{Guido van Rossum}{guido at python.org}
+\modulesynopsis{An environment for turtle graphics.}
+
+\sectionauthor{Moshe Zadka}{moshez at zadka.site.co.il}
+
+
+The \module{turtle} module provides turtle graphics primitives, in both an
+object-oriented and procedure-oriented ways. Because it uses \module{Tkinter}
+for the underlying graphics, it needs a version of python installed with
+Tk support.
+
+The procedural interface uses a pen and a canvas which are automagically
+created when any of the functions are called.
+
+The \module{turtle} module defines the following functions:
+
+\begin{funcdesc}{degrees}{}
+Set angle measurement units to degrees.
+\end{funcdesc}
+
+\begin{funcdesc}{radians}{}
+Set angle measurement units to radians.
+\end{funcdesc}
+
+\begin{funcdesc}{setup}{**kwargs}
+Sets the size and position of the main window.  Keywords are:
+\begin{itemize}
+  \item \code{width}: either a size in pixels or a fraction of the screen.
+   The default is 50\% of the screen.
+  \item \code{height}: either a size in pixels or a fraction of the screen.
+   The default is 50\% of the screen.
+  \item \code{startx}: starting position in pixels from the left edge
+      of the screen. \code{None} is the default value and 
+      centers the window horizontally on screen.
+  \item \code{starty}: starting position in pixels from the top edge
+      of the screen. \code{None} is the default value and 
+      centers the window vertically on screen.
+\end{itemize}
+
+   Examples:
+
+\begin{verbatim}
+# Uses default geometry: 50% x 50% of screen, centered.
+setup()  
+
+# Sets window to 200x200 pixels, in upper left of screen
+setup (width=200, height=200, startx=0, starty=0)
+
+# Sets window to 75% of screen by 50% of screen, and centers it.
+setup(width=.75, height=0.5, startx=None, starty=None)
+\end{verbatim}
+
+\end{funcdesc}
+
+\begin{funcdesc}{title}{title_str}
+Set the window's title to \var{title}.
+\end{funcdesc}
+
+\begin{funcdesc}{done}{}
+Enters the Tk main loop.  The window will continue to 
+be displayed until the user closes it or the process is killed.
+\end{funcdesc}
+
+\begin{funcdesc}{reset}{}
+Clear the screen, re-center the pen, and set variables to the default
+values.
+\end{funcdesc}
+
+\begin{funcdesc}{clear}{}
+Clear the screen.
+\end{funcdesc}
+
+\begin{funcdesc}{tracer}{flag}
+Set tracing on/off (according to whether flag is true or not). Tracing
+means line are drawn more slowly, with an animation of an arrow along the 
+line.
+\end{funcdesc}
+
+\begin{funcdesc}{speed}{speed}
+Set the speed of the turtle. Valid values for the parameter
+\var{speed} are \code{'fastest'} (no delay), \code{'fast'},
+(delay 5ms), \code{'normal'} (delay 10ms), \code{'slow'}
+(delay 15ms), and \code{'slowest'} (delay 20ms).
+\versionadded{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{delay}{delay}
+Set the speed of the turtle to \var{delay}, which is given
+in ms. \versionadded{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{forward}{distance}
+Go forward \var{distance} steps.
+\end{funcdesc}
+
+\begin{funcdesc}{backward}{distance}
+Go backward \var{distance} steps.
+\end{funcdesc}
+
+\begin{funcdesc}{left}{angle}
+Turn left \var{angle} units. Units are by default degrees, but can be
+set via the \function{degrees()} and \function{radians()} functions.
+\end{funcdesc}
+
+\begin{funcdesc}{right}{angle}
+Turn right \var{angle} units. Units are by default degrees, but can be
+set via the \function{degrees()} and \function{radians()} functions.
+\end{funcdesc}
+
+\begin{funcdesc}{up}{}
+Move the pen up --- stop drawing.
+\end{funcdesc}
+
+\begin{funcdesc}{down}{}
+Move the pen down --- draw when moving.
+\end{funcdesc}
+
+\begin{funcdesc}{width}{width}
+Set the line width to \var{width}.
+\end{funcdesc}
+
+\begin{funcdesc}{color}{s}
+\funclineni{color}{(r, g, b)}
+\funclineni{color}{r, g, b}
+Set the pen color.  In the first form, the color is specified as a
+Tk color specification as a string.  The second form specifies the
+color as a tuple of the RGB values, each in the range [0..1].  For the
+third form, the color is specified giving the RGB values as three
+separate parameters (each in the range [0..1]).
+\end{funcdesc}
+
+\begin{funcdesc}{write}{text\optional{, move}}
+Write \var{text} at the current pen position. If \var{move} is true,
+the pen is moved to the bottom-right corner of the text. By default,
+\var{move} is false.
+\end{funcdesc}
+
+\begin{funcdesc}{fill}{flag}
+The complete specifications are rather complex, but the recommended 
+usage is: call \code{fill(1)} before drawing a path you want to fill,
+and call \code{fill(0)} when you finish to draw the path.
+\end{funcdesc}
+
+\begin{funcdesc}{begin\_fill}{}
+Switch turtle into filling mode; 
+Must eventually be followed by a corresponding end_fill() call.
+Otherwise it will be ignored.
+\versionadded{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{end\_fill}{}
+End filling mode, and fill the shape; equivalent to \code{fill(0)}.
+\versionadded{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{circle}{radius\optional{, extent}}
+Draw a circle with radius \var{radius} whose center-point is
+\var{radius} units left of the turtle.
+\var{extent} determines which part of a circle is drawn: if
+not given it defaults to a full circle.
+
+If \var{extent} is not a full circle, one endpoint of the arc is the
+current pen position. The arc is drawn in a counter clockwise
+direction if \var{radius} is positive, otherwise in a clockwise
+direction.  In the process, the direction of the turtle is changed
+by the amount of the \var{extent}.
+\end{funcdesc}
+
+\begin{funcdesc}{goto}{x, y}
+\funclineni{goto}{(x, y)}
+Go to co-ordinates \var{x}, \var{y}.  The co-ordinates may be
+specified either as two separate arguments or as a 2-tuple.
+\end{funcdesc}
+
+\begin{funcdesc}{towards}{x, y}
+Return the angle of the line from the turtle's position
+to the point \var{x}, \var{y}. The co-ordinates may be
+specified either as two separate arguments, as a 2-tuple,
+or as another pen object.
+\versionadded{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{heading}{}
+Return the current orientation of the turtle.
+\versionadded{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{setheading}{angle}
+Set the orientation of the turtle to \var{angle}.
+\versionadded{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{position}{}
+Return the current location of the turtle as an \code{(x,y)} pair.
+\versionadded{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{setx}{x}
+Set the x coordinate of the turtle to \var{x}.
+\versionadded{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{sety}{y}
+Set the y coordinate of the turtle to \var{y}.
+\versionadded{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{window\_width}{}
+Return the width of the canvas window.
+\versionadded{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{window\_height}{}
+Return the height of the canvas window.
+\versionadded{2.3}
+\end{funcdesc}
+
+This module also does \code{from math import *}, so see the
+documentation for the \refmodule{math} module for additional constants
+and functions useful for turtle graphics.
+
+\begin{funcdesc}{demo}{}
+Exercise the module a bit.
+\end{funcdesc}
+
+\begin{excdesc}{Error}
+Exception raised on any error caught by this module.
+\end{excdesc}
+
+For examples, see the code of the \function{demo()} function.
+
+This module defines the following classes:
+
+\begin{classdesc}{Pen}{}
+Define a pen. All above functions can be called as a methods on the given
+pen. The constructor automatically creates a canvas do be drawn on.
+\end{classdesc}
+
+\begin{classdesc}{Turtle}{}
+Define a pen. This is essentially a synonym for \code{Pen()};
+\class{Turtle} is an empty subclass of \class{Pen}.
+\end{classdesc}
+
+\begin{classdesc}{RawPen}{canvas}
+Define a pen which draws on a canvas \var{canvas}. This is useful if 
+you want to use the module to create graphics in a ``real'' program.
+\end{classdesc}
+
+\subsection{Turtle, Pen and RawPen Objects \label{pen-rawpen-objects}}
+
+Most of the global functions available in the module are also
+available as methods of the \class{Turtle}, \class{Pen} and
+\class{RawPen} classes, affecting only the state of the given pen.
+
+The only method which is more powerful as a method is
+\function{degrees()}, which takes an optional argument letting 
+you specify the number of units corresponding to a full circle:
+
+\begin{methoddesc}{degrees}{\optional{fullcircle}}
+\var{fullcircle} is by default 360. This can cause the pen to have any
+angular units whatever: give \var{fullcircle} 2*$\pi$ for radians, or
+400 for gradians.
+\end{methoddesc}

Added: vendor/Python/current/Doc/lib/libtypes.tex
===================================================================
--- vendor/Python/current/Doc/lib/libtypes.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libtypes.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,215 @@
+\section{\module{types} ---
+         Names for built-in types}
+
+\declaremodule{standard}{types}
+\modulesynopsis{Names for built-in types.}
+
+
+This module defines names for some object types that are used by
+the standard Python interpreter, but not for the types defined by various
+extension modules.  Also, it does not include some of the types that
+arise during processing such as the \code{listiterator} type.
+It is safe to use \samp{from types import *} ---
+the module does not export any names besides the ones listed here.
+New names exported by future versions of this module will all end in
+\samp{Type}.
+
+Typical use is for functions that do different things depending on
+their argument types, like the following:
+
+\begin{verbatim}
+from types import *
+def delete(mylist, item):
+    if type(item) is IntType:
+       del mylist[item]
+    else:
+       mylist.remove(item)
+\end{verbatim}
+
+Starting in Python 2.2, built-in factory functions such as
+\function{int()} and \function{str()} are also names for the
+corresponding types.  This is now the preferred way to access
+the type instead of using the \module{types} module.  Accordingly,
+the example above should be written as follows:
+
+\begin{verbatim}
+def delete(mylist, item):
+    if isinstance(item, int):
+       del mylist[item]
+    else:
+       mylist.remove(item)
+\end{verbatim}
+
+The module defines the following names:
+
+\begin{datadesc}{NoneType}
+The type of \code{None}.
+\end{datadesc}
+
+\begin{datadesc}{TypeType}
+The type of type objects (such as returned by
+\function{type()}\bifuncindex{type}).
+\end{datadesc}
+
+\begin{datadesc}{BooleanType}
+The type of the \class{bool} values \code{True} and \code{False}; this
+is an alias of the built-in \function{bool()} function.
+\versionadded{2.3}
+\end{datadesc}
+
+\begin{datadesc}{IntType}
+The type of integers (e.g. \code{1}).
+\end{datadesc}
+
+\begin{datadesc}{LongType}
+The type of long integers (e.g. \code{1L}).
+\end{datadesc}
+
+\begin{datadesc}{FloatType}
+The type of floating point numbers (e.g. \code{1.0}).
+\end{datadesc}
+
+\begin{datadesc}{ComplexType}
+The type of complex numbers (e.g. \code{1.0j}).  This is not defined
+if Python was built without complex number support.
+\end{datadesc}
+
+\begin{datadesc}{StringType}
+The type of character strings (e.g. \code{'Spam'}).
+\end{datadesc}
+
+\begin{datadesc}{UnicodeType}
+The type of Unicode character strings (e.g. \code{u'Spam'}).  This is
+not defined if Python was built without Unicode support.
+\end{datadesc}
+
+\begin{datadesc}{TupleType}
+The type of tuples (e.g. \code{(1, 2, 3, 'Spam')}).
+\end{datadesc}
+
+\begin{datadesc}{ListType}
+The type of lists (e.g. \code{[0, 1, 2, 3]}).
+\end{datadesc}
+
+\begin{datadesc}{DictType}
+The type of dictionaries (e.g. \code{\{'Bacon': 1, 'Ham': 0\}}).
+\end{datadesc}
+
+\begin{datadesc}{DictionaryType}
+An alternate name for \code{DictType}.
+\end{datadesc}
+
+\begin{datadesc}{FunctionType}
+The type of user-defined functions and lambdas.
+\end{datadesc}
+
+\begin{datadesc}{LambdaType}
+An alternate name for \code{FunctionType}.
+\end{datadesc}
+
+\begin{datadesc}{GeneratorType}
+The type of generator-iterator objects, produced by calling a
+generator function.
+\versionadded{2.2}
+\end{datadesc}
+
+\begin{datadesc}{CodeType}
+The type for code objects such as returned by
+\function{compile()}\bifuncindex{compile}.
+\end{datadesc}
+
+\begin{datadesc}{ClassType}
+The type of user-defined classes.
+\end{datadesc}
+
+\begin{datadesc}{InstanceType}
+The type of instances of user-defined classes.
+\end{datadesc}
+
+\begin{datadesc}{MethodType}
+The type of methods of user-defined class instances.
+\end{datadesc}
+
+\begin{datadesc}{UnboundMethodType}
+An alternate name for \code{MethodType}.
+\end{datadesc}
+
+\begin{datadesc}{BuiltinFunctionType}
+The type of built-in functions like \function{len()} or
+\function{sys.exit()}.
+\end{datadesc}
+
+\begin{datadesc}{BuiltinMethodType}
+An alternate name for \code{BuiltinFunction}.
+\end{datadesc}
+
+\begin{datadesc}{ModuleType}
+The type of modules.
+\end{datadesc}
+
+\begin{datadesc}{FileType}
+The type of open file objects such as \code{sys.stdout}.
+\end{datadesc}
+
+\begin{datadesc}{XRangeType}
+The type of range objects returned by
+\function{xrange()}\bifuncindex{xrange}.
+\end{datadesc}
+
+\begin{datadesc}{SliceType}
+The type of objects returned by
+\function{slice()}\bifuncindex{slice}.
+\end{datadesc}
+
+\begin{datadesc}{EllipsisType}
+The type of \code{Ellipsis}.
+\end{datadesc}
+
+\begin{datadesc}{TracebackType}
+The type of traceback objects such as found in
+\code{sys.exc_traceback}.
+\end{datadesc}
+
+\begin{datadesc}{FrameType}
+The type of frame objects such as found in \code{tb.tb_frame} if
+\code{tb} is a traceback object.
+\end{datadesc}
+
+\begin{datadesc}{BufferType}
+The type of buffer objects created by the
+\function{buffer()}\bifuncindex{buffer} function.
+\end{datadesc}
+
+\begin{datadesc}{DictProxyType}
+The type of dict proxies, such as \code{TypeType.__dict__}.
+\end{datadesc}
+
+\begin{datadesc}{NotImplementedType}
+The type of \code{NotImplemented}
+\end{datadesc}
+
+\begin{datadesc}{GetSetDescriptorType}
+The type of objects defined in extension modules with \code{PyGetSetDef}, such
+as \code{FrameType.f_locals} or \code{array.array.typecode}.  This constant is
+not defined in implementations of Python that do not have such extension
+types, so for portable code use \code{hasattr(types, 'GetSetDescriptorType')}.
+\versionadded{2.5}
+\end{datadesc}
+
+\begin{datadesc}{MemberDescriptorType}
+The type of objects defined in extension modules with \code{PyMemberDef}, such
+as \code {datetime.timedelta.days}.  This constant is not defined in
+implementations of Python that do not have such extension types, so for
+portable code use \code{hasattr(types, 'MemberDescriptorType')}.
+\versionadded{2.5}
+\end{datadesc}
+
+\begin{datadesc}{StringTypes}
+A sequence containing \code{StringType} and \code{UnicodeType} used to
+facilitate easier checking for any string object.  Using this is more
+portable than using a sequence of the two string types constructed
+elsewhere since it only contains \code{UnicodeType} if it has been
+built in the running version of Python.  For example:
+\code{isinstance(s, types.StringTypes)}.
+\versionadded{2.2}
+\end{datadesc}

Added: vendor/Python/current/Doc/lib/libundoc.tex
===================================================================
--- vendor/Python/current/Doc/lib/libundoc.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libundoc.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,113 @@
+\chapter{Undocumented Modules \label{undoc}}
+
+Here's a quick listing of modules that are currently undocumented, but
+that should be documented.  Feel free to contribute documentation for
+them!  (Send via email to \email{docs at python.org}.)
+
+The idea and original contents for this chapter were taken
+from a posting by Fredrik Lundh; the specific contents of this chapter
+have been substantially revised.
+
+
+\section{Frameworks}
+
+Frameworks tend to be harder to document, but are well worth the
+effort spent.
+
+\begin{description}
+\item None at this time.
+\end{description}
+
+
+\section{Miscellaneous useful utilities}
+
+Some of these are very old and/or not very robust; marked with ``hmm.''
+
+\begin{description}
+\item[\module{bdb}]
+--- A generic Python debugger base class (used by pdb).
+
+\item[\module{ihooks}]
+--- Import hook support (for \refmodule{rexec}; may become obsolete).
+\end{description}
+
+
+
+\section{Platform specific modules}
+
+These modules are used to implement the \refmodule{os.path} module,
+and are not documented beyond this mention.  There's little need to
+document these.
+
+\begin{description}
+\item[\module{ntpath}]
+--- Implementation of \module{os.path} on Win32, Win64, WinCE, and
+    OS/2 platforms.
+
+\item[\module{posixpath}]
+--- Implementation of \module{os.path} on \POSIX.
+
+\item[\module{bsddb185}]
+--- Backwards compatibility module for systems which still use the Berkeley
+    DB 1.85 module.  It is normally only available on certain BSD \UNIX-based
+    systems.  It should never be used directly.
+\end{description}
+
+
+\section{Multimedia}
+
+\begin{description}
+\item[\module{audiodev}]
+--- Platform-independent API for playing audio data.
+
+\item[\module{linuxaudiodev}]
+--- Play audio data on the Linux audio device.  Replaced in Python 2.3
+    by the \module{ossaudiodev} module.
+
+\item[\module{sunaudio}]
+--- Interpret Sun audio headers (may become obsolete or a tool/demo).
+
+\item[\module{toaiff}]
+--- Convert "arbitrary" sound files to AIFF files; should probably
+    become a tool or demo.  Requires the external program \program{sox}.
+\end{description}
+
+
+\section{Obsolete \label{obsolete-modules}}
+
+These modules are not normally available for import; additional work
+must be done to make them available.
+
+%%% lib-old is empty as of Python 2.5
+% Those which are written in Python will be installed into the directory 
+% \file{lib-old/} installed as part of the standard library.  To use
+% these, the directory must be added to \code{sys.path}, possibly using
+% \envvar{PYTHONPATH}.
+
+These extension modules written in C are not built by default.
+Under \UNIX, these must be enabled by uncommenting the appropriate
+lines in \file{Modules/Setup} in the build tree and either rebuilding
+Python if the modules are statically linked, or building and
+installing the shared object if using dynamically-loaded extensions.
+
+% XXX need Windows instructions!
+
+\begin{description}
+\item[\module{timing}]
+--- Measure time intervals to high resolution (use \function{time.clock()}
+    instead).
+\end{description}
+
+\section{SGI-specific Extension modules}
+
+The following are SGI specific, and may be out of touch with the
+current version of reality.
+
+\begin{description}
+\item[\module{cl}]
+--- Interface to the SGI compression library.
+
+\item[\module{sv}]
+--- Interface to the ``simple video'' board on SGI Indigo
+    (obsolete hardware).
+\end{description}

Added: vendor/Python/current/Doc/lib/libunicodedata.tex
===================================================================
--- vendor/Python/current/Doc/lib/libunicodedata.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libunicodedata.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,160 @@
+\section{\module{unicodedata} ---
+         Unicode Database}
+
+\declaremodule{standard}{unicodedata}
+\modulesynopsis{Access the Unicode Database.}
+\moduleauthor{Marc-Andre Lemburg}{mal at lemburg.com}
+\sectionauthor{Marc-Andre Lemburg}{mal at lemburg.com}
+\sectionauthor{Martin v. L\"owis}{martin at v.loewis.de}
+
+\index{Unicode}
+\index{character}
+\indexii{Unicode}{database}
+
+This module provides access to the Unicode Character Database which
+defines character properties for all Unicode characters. The data in
+this database is based on the \file{UnicodeData.txt} file version
+4.1.0 which is publicly available from \url{ftp://ftp.unicode.org/}.
+
+The module uses the same names and symbols as defined by the
+UnicodeData File Format 4.1.0 (see
+\url{http://www.unicode.org/Public/4.1.0/ucd/UCD.html}).  It
+defines the following functions:
+
+\begin{funcdesc}{lookup}{name}
+  Look up character by name.  If a character with the
+  given name is found, return the corresponding Unicode
+  character.  If not found, \exception{KeyError} is raised.
+\end{funcdesc}
+
+\begin{funcdesc}{name}{unichr\optional{, default}}
+  Returns the name assigned to the Unicode character
+  \var{unichr} as a string. If no name is defined,
+  \var{default} is returned, or, if not given,
+  \exception{ValueError} is raised.
+\end{funcdesc}
+
+\begin{funcdesc}{decimal}{unichr\optional{, default}}
+  Returns the decimal value assigned to the Unicode character
+  \var{unichr} as integer. If no such value is defined,
+  \var{default} is returned, or, if not given,
+  \exception{ValueError} is raised.
+\end{funcdesc}
+
+\begin{funcdesc}{digit}{unichr\optional{, default}}
+  Returns the digit value assigned to the Unicode character
+  \var{unichr} as integer. If no such value is defined,
+  \var{default} is returned, or, if not given,
+  \exception{ValueError} is raised.
+\end{funcdesc}
+
+\begin{funcdesc}{numeric}{unichr\optional{, default}}
+  Returns the numeric value assigned to the Unicode character
+  \var{unichr} as float. If no such value is defined, \var{default} is
+  returned, or, if not given, \exception{ValueError} is raised.
+\end{funcdesc}
+
+\begin{funcdesc}{category}{unichr}
+  Returns the general category assigned to the Unicode character
+  \var{unichr} as string.
+\end{funcdesc}
+
+\begin{funcdesc}{bidirectional}{unichr}
+  Returns the bidirectional category assigned to the Unicode character
+  \var{unichr} as string. If no such value is defined, an empty string
+  is returned.
+\end{funcdesc}
+
+\begin{funcdesc}{combining}{unichr}
+  Returns the canonical combining class assigned to the Unicode
+  character \var{unichr} as integer. Returns \code{0} if no combining
+  class is defined.
+\end{funcdesc}
+
+\begin{funcdesc}{east_asian_width}{unichr}
+  Returns the east asian width assigned to the Unicode character
+  \var{unichr} as string.
+\versionadded{2.4}
+\end{funcdesc}
+
+\begin{funcdesc}{mirrored}{unichr}
+  Returns the mirrored property assigned to the Unicode character
+  \var{unichr} as integer. Returns \code{1} if the character has been
+  identified as a ``mirrored'' character in bidirectional text,
+  \code{0} otherwise.
+\end{funcdesc}
+
+\begin{funcdesc}{decomposition}{unichr}
+  Returns the character decomposition mapping assigned to the Unicode
+  character \var{unichr} as string. An empty string is returned in case
+  no such mapping is defined.
+\end{funcdesc}
+
+\begin{funcdesc}{normalize}{form, unistr}
+
+Return the normal form \var{form} for the Unicode string \var{unistr}.
+Valid values for \var{form} are 'NFC', 'NFKC', 'NFD', and 'NFKD'.
+
+The Unicode standard defines various normalization forms of a Unicode
+string, based on the definition of canonical equivalence and
+compatibility equivalence. In Unicode, several characters can be
+expressed in various way. For example, the character U+00C7 (LATIN
+CAPITAL LETTER C WITH CEDILLA) can also be expressed as the sequence
+U+0043 (LATIN CAPITAL LETTER C) U+0327 (COMBINING CEDILLA).
+
+For each character, there are two normal forms: normal form C and
+normal form D. Normal form D (NFD) is also known as canonical
+decomposition, and translates each character into its decomposed form.
+Normal form C (NFC) first applies a canonical decomposition, then
+composes pre-combined characters again.
+
+In addition to these two forms, there are two additional normal forms
+based on compatibility equivalence. In Unicode, certain characters are
+supported which normally would be unified with other characters. For
+example, U+2160 (ROMAN NUMERAL ONE) is really the same thing as U+0049
+(LATIN CAPITAL LETTER I). However, it is supported in Unicode for
+compatibility with existing character sets (e.g. gb2312).
+
+The normal form KD (NFKD) will apply the compatibility decomposition,
+i.e. replace all compatibility characters with their equivalents. The
+normal form KC (NFKC) first applies the compatibility decomposition,
+followed by the canonical composition.
+
+\versionadded{2.3}
+\end{funcdesc}
+
+In addition, the module exposes the following constant:
+
+\begin{datadesc}{unidata_version}
+The version of the Unicode database used in this module.
+
+\versionadded{2.3}
+\end{datadesc}
+
+\begin{datadesc}{ucd_3_2_0}
+This is an object that has the same methods as the entire
+module, but uses the Unicode database version 3.2 instead,
+for applications that require this specific version of
+the Unicode database (such as IDNA).
+
+\versionadded{2.5}
+\end{datadesc}
+
+Examples:
+
+\begin{verbatim}
+>>> unicodedata.lookup('LEFT CURLY BRACKET')
+u'{'
+>>> unicodedata.name(u'/')
+'SOLIDUS'
+>>> unicodedata.decimal(u'9')
+9
+>>> unicodedata.decimal(u'a')
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+ValueError: not a decimal
+>>> unicodedata.category(u'A')  # 'L'etter, 'u'ppercase
+'Lu'   
+>>> unicodedata.bidirectional(u'\u0660') # 'A'rabic, 'N'umber
+'AN'
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/libunittest.tex
===================================================================
--- vendor/Python/current/Doc/lib/libunittest.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libunittest.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,974 @@
+\section{\module{unittest} ---
+         Unit testing framework}
+
+\declaremodule{standard}{unittest}
+\modulesynopsis{Unit testing framework for Python.}
+\moduleauthor{Steve Purcell}{stephen\textunderscore{}purcell at yahoo.com}
+\sectionauthor{Steve Purcell}{stephen\textunderscore{}purcell at yahoo.com}
+\sectionauthor{Fred L. Drake, Jr.}{fdrake at acm.org}
+\sectionauthor{Raymond Hettinger}{python at rcn.com}
+
+\versionadded{2.1}
+
+The Python unit testing framework, sometimes referred to as ``PyUnit,'' is
+a Python language version of JUnit, by Kent Beck and Erich Gamma.
+JUnit is, in turn, a Java version of Kent's Smalltalk testing
+framework.  Each is the de facto standard unit testing framework for
+its respective language.
+
+\module{unittest} supports test automation, sharing of setup and shutdown
+code for tests, aggregation of tests into collections, and independence of
+the tests from the reporting framework.  The \module{unittest} module
+provides classes that make it easy to support these qualities for a
+set of tests.
+
+To achieve this, \module{unittest} supports some important concepts:
+
+\begin{definitions}
+\term{test fixture}
+A \dfn{test fixture} represents the preparation needed to perform one
+or more tests, and any associate cleanup actions.  This may involve,
+for example, creating temporary or proxy databases, directories, or
+starting a server process.
+
+\term{test case}
+A \dfn{test case} is the smallest unit of testing.  It checks for a
+specific response to a particular set of inputs.  \module{unittest}
+provides a base class, \class{TestCase}, which may be used to create
+new test cases.
+
+\term{test suite}
+A \dfn{test suite} is a collection of test cases, test suites, or
+both.  It is used to aggregate tests that should be executed
+together.
+
+\term{test runner}
+A \dfn{test runner} is a component which orchestrates the execution of
+tests and provides the outcome to the user.  The runner may use a
+graphical interface, a textual interface, or return a special value to
+indicate the results of executing the tests.
+\end{definitions}
+
+
+The test case and test fixture concepts are supported through the
+\class{TestCase} and \class{FunctionTestCase} classes; the former
+should be used when creating new tests, and the latter can be used when
+integrating existing test code with a \module{unittest}-driven framework.
+When building test fixtures using \class{TestCase}, the \method{setUp()}
+and \method{tearDown()} methods can be overridden to provide
+initialization and cleanup for the fixture.  With
+\class{FunctionTestCase}, existing functions can be passed to the
+constructor for these purposes.  When the test is run, the
+fixture initialization is run first; if it succeeds, the cleanup
+method is run after the test has been executed, regardless of the
+outcome of the test.  Each instance of the \class{TestCase} will only
+be used to run a single test method, so a new fixture is created for
+each test.
+
+Test suites are implemented by the \class{TestSuite} class.  This
+class allows individual tests and test suites to be aggregated; when
+the suite is executed, all tests added directly to the suite and in
+``child'' test suites are run.
+
+A test runner is an object that provides a single method,
+\method{run()}, which accepts a \class{TestCase} or \class{TestSuite}
+object as a parameter, and returns a result object.  The class
+\class{TestResult} is provided for use as the result object.
+\module{unittest} provides the \class{TextTestRunner} as an example
+test runner which reports test results on the standard error stream by
+default.  Alternate runners can be implemented for other environments
+(such as graphical environments) without any need to derive from a
+specific class.
+
+
+\begin{seealso}
+  \seemodule{doctest}{Another test-support module with a very
+                      different flavor.}
+  \seetitle[http://www.XProgramming.com/testfram.htm]{Simple Smalltalk
+            Testing: With Patterns}{Kent Beck's original paper on
+            testing frameworks using the pattern shared by
+            \module{unittest}.}
+\end{seealso}
+
+
+\subsection{Basic example \label{minimal-example}}
+
+The \module{unittest} module provides a rich set of tools for
+constructing and running tests.  This section demonstrates that a
+small subset of the tools suffice to meet the needs of most users.
+
+Here is a short script to test three functions from the
+\refmodule{random} module:
+
+\begin{verbatim}
+import random
+import unittest
+
+class TestSequenceFunctions(unittest.TestCase):
+    
+    def setUp(self):
+        self.seq = range(10)
+
+    def testshuffle(self):
+        # make sure the shuffled sequence does not lose any elements
+        random.shuffle(self.seq)
+        self.seq.sort()
+        self.assertEqual(self.seq, range(10))
+
+    def testchoice(self):
+        element = random.choice(self.seq)
+        self.assert_(element in self.seq)
+
+    def testsample(self):
+        self.assertRaises(ValueError, random.sample, self.seq, 20)
+        for element in random.sample(self.seq, 5):
+            self.assert_(element in self.seq)
+
+if __name__ == '__main__':
+    unittest.main()
+\end{verbatim}
+
+A testcase is created by subclassing \class{unittest.TestCase}.
+The three individual tests are defined with methods whose names start with
+the letters \samp{test}.  This naming convention informs the test runner
+about which methods represent tests.
+
+The crux of each test is a call to \method{assertEqual()} to
+check for an expected result; \method{assert_()} to verify a condition;
+or \method{assertRaises()} to verify that an expected exception gets
+raised.  These methods are used instead of the \keyword{assert} statement
+so the test runner can accumulate all test results and produce a report.
+
+When a \method{setUp()} method is defined, the test runner will run that
+method prior to each test.  Likewise, if a \method{tearDown()} method is
+defined, the test runner will invoke that method after each test.  In the
+example, \method{setUp()} was used to create a fresh sequence for each test.
+
+The final block shows a simple way to run the tests.
+\function{unittest.main()} provides a command line interface to the
+test script.  When run from the command line, the above script
+produces an output that looks like this:
+
+\begin{verbatim}
+...
+----------------------------------------------------------------------
+Ran 3 tests in 0.000s
+
+OK
+\end{verbatim}
+
+Instead of \function{unittest.main()}, there are other ways to run the tests
+with a finer level of control, less terse output, and no requirement to be
+run from the command line.  For example, the last two lines may be replaced
+with:
+
+\begin{verbatim}
+suite = unittest.TestLoader().loadTestsFromTestCase(TestSequenceFunctions)
+unittest.TextTestRunner(verbosity=2).run(suite)
+\end{verbatim}
+
+Running the revised script from the interpreter or another script
+produces the following output:
+
+\begin{verbatim}
+testchoice (__main__.TestSequenceFunctions) ... ok
+testsample (__main__.TestSequenceFunctions) ... ok
+testshuffle (__main__.TestSequenceFunctions) ... ok
+
+----------------------------------------------------------------------
+Ran 3 tests in 0.110s
+
+OK
+\end{verbatim}
+
+The above examples show the most commonly used \module{unittest} features
+which are sufficient to meet many everyday testing needs.  The remainder
+of the documentation explores the full feature set from first principles.
+
+
+\subsection{Organizing test code
+            \label{organizing-tests}}
+
+The basic building blocks of unit testing are \dfn{test cases} ---
+single scenarios that must be set up and checked for correctness.  In
+\module{unittest}, test cases are represented by instances of
+\module{unittest}'s \class{TestCase} class. To make
+your own test cases you must write subclasses of \class{TestCase}, or
+use \class{FunctionTestCase}.
+
+An instance of a \class{TestCase}-derived class is an object that can
+completely run a single test method, together with optional set-up
+and tidy-up code.
+
+The testing code of a \class{TestCase} instance should be entirely
+self contained, such that it can be run either in isolation or in
+arbitrary combination with any number of other test cases.
+
+The simplest \class{TestCase} subclass will simply override the
+\method{runTest()} method in order to perform specific testing code:
+
+\begin{verbatim}
+import unittest
+
+class DefaultWidgetSizeTestCase(unittest.TestCase):
+    def runTest(self):
+        widget = Widget('The widget')
+        self.assertEqual(widget.size(), (50, 50), 'incorrect default size')
+\end{verbatim}
+
+Note that in order to test something, we use the one of the
+\method{assert*()} or \method{fail*()} methods provided by the
+\class{TestCase} base class.  If the test fails, an exception will be
+raised, and \module{unittest} will identify the test case as a
+\dfn{failure}.  Any other exceptions will be treated as \dfn{errors}.
+This helps you identify where the problem is: \dfn{failures} are caused by
+incorrect results - a 5 where you expected a 6. \dfn{Errors} are caused by
+incorrect code - e.g., a \exception{TypeError} caused by an incorrect
+function call.
+
+The way to run a test case will be described later.  For now, note
+that to construct an instance of such a test case, we call its
+constructor without arguments:
+
+\begin{verbatim}
+testCase = DefaultWidgetSizeTestCase()
+\end{verbatim}
+
+Now, such test cases can be numerous, and their set-up can be
+repetitive.  In the above case, constructing a \class{Widget} in each of
+100 Widget test case subclasses would mean unsightly duplication.
+
+Luckily, we can factor out such set-up code by implementing a method
+called \method{setUp()}, which the testing framework will
+automatically call for us when we run the test:
+
+\begin{verbatim}
+import unittest
+
+class SimpleWidgetTestCase(unittest.TestCase):
+    def setUp(self):
+        self.widget = Widget('The widget')
+
+class DefaultWidgetSizeTestCase(SimpleWidgetTestCase):
+    def runTest(self):
+        self.failUnless(self.widget.size() == (50,50),
+                        'incorrect default size')
+
+class WidgetResizeTestCase(SimpleWidgetTestCase):
+    def runTest(self):
+        self.widget.resize(100,150)
+        self.failUnless(self.widget.size() == (100,150),
+                        'wrong size after resize')
+\end{verbatim}
+
+If the \method{setUp()} method raises an exception while the test is
+running, the framework will consider the test to have suffered an
+error, and the \method{runTest()} method will not be executed.
+
+Similarly, we can provide a \method{tearDown()} method that tidies up
+after the \method{runTest()} method has been run:
+
+\begin{verbatim}
+import unittest
+
+class SimpleWidgetTestCase(unittest.TestCase):
+    def setUp(self):
+        self.widget = Widget('The widget')
+
+    def tearDown(self):
+        self.widget.dispose()
+        self.widget = None
+\end{verbatim}
+
+If \method{setUp()} succeeded, the \method{tearDown()} method will be
+run whether \method{runTest()} succeeded or not.
+
+Such a working environment for the testing code is called a
+\dfn{fixture}.
+
+Often, many small test cases will use the same fixture.  In this case,
+we would end up subclassing \class{SimpleWidgetTestCase} into many
+small one-method classes such as
+\class{DefaultWidgetSizeTestCase}.  This is time-consuming and
+discouraging, so in the same vein as JUnit, \module{unittest} provides
+a simpler mechanism:
+
+\begin{verbatim}
+import unittest
+
+class WidgetTestCase(unittest.TestCase):
+    def setUp(self):
+        self.widget = Widget('The widget')
+
+    def tearDown(self):
+        self.widget.dispose()
+        self.widget = None
+
+    def testDefaultSize(self):
+        self.failUnless(self.widget.size() == (50,50),
+                        'incorrect default size')
+
+    def testResize(self):
+        self.widget.resize(100,150)
+        self.failUnless(self.widget.size() == (100,150),
+                        'wrong size after resize')
+\end{verbatim}
+
+Here we have not provided a \method{runTest()} method, but have
+instead provided two different test methods.  Class instances will now
+each run one of the \method{test*()}  methods, with \code{self.widget}
+created and destroyed separately for each instance.  When creating an
+instance we must specify the test method it is to run.  We do this by
+passing the method name in the constructor:
+
+\begin{verbatim}
+defaultSizeTestCase = WidgetTestCase('testDefaultSize')
+resizeTestCase = WidgetTestCase('testResize')
+\end{verbatim}
+
+Test case instances are grouped together according to the features
+they test.  \module{unittest} provides a mechanism for this: the
+\dfn{test suite}, represented by \module{unittest}'s \class{TestSuite}
+class:
+
+\begin{verbatim}
+widgetTestSuite = unittest.TestSuite()
+widgetTestSuite.addTest(WidgetTestCase('testDefaultSize'))
+widgetTestSuite.addTest(WidgetTestCase('testResize'))
+\end{verbatim}
+
+For the ease of running tests, as we will see later, it is a good
+idea to provide in each test module a callable object that returns a
+pre-built test suite:
+
+\begin{verbatim}
+def suite():
+    suite = unittest.TestSuite()
+    suite.addTest(WidgetTestCase('testDefaultSize'))
+    suite.addTest(WidgetTestCase('testResize'))
+    return suite
+\end{verbatim}
+
+or even:
+
+\begin{verbatim}
+def suite():
+    tests = ['testDefaultSize', 'testResize']
+
+    return unittest.TestSuite(map(WidgetTestCase, tests))
+\end{verbatim}
+
+Since it is a common pattern to create a \class{TestCase} subclass
+with many similarly named test functions, \module{unittest} provides a
+\class{TestLoader} class that can be used to automate the process of
+creating a test suite and populating it with individual tests.
+For example,
+
+\begin{verbatim}
+suite = unittest.TestLoader().loadTestsFromTestCase(WidgetTestCase)
+\end{verbatim}
+
+will create a test suite that will run
+\code{WidgetTestCase.testDefaultSize()} and \code{WidgetTestCase.testResize}.
+\class{TestLoader} uses the \code{'test'} method name prefix to identify
+test methods automatically.
+
+Note that the order in which the various test cases will be run is
+determined by sorting the test function names with the built-in
+\function{cmp()} function.
+
+Often it is desirable to group suites of test cases together, so as to
+run tests for the whole system at once.  This is easy, since
+\class{TestSuite} instances can be added to a \class{TestSuite} just
+as \class{TestCase} instances can be added to a \class{TestSuite}:
+
+\begin{verbatim}
+suite1 = module1.TheTestSuite()
+suite2 = module2.TheTestSuite()
+alltests = unittest.TestSuite([suite1, suite2])
+\end{verbatim}
+
+You can place the definitions of test cases and test suites in the
+same modules as the code they are to test (such as \file{widget.py}),
+but there are several advantages to placing the test code in a
+separate module, such as \file{test_widget.py}:
+
+\begin{itemize}
+  \item The test module can be run standalone from the command line.
+  \item The test code can more easily be separated from shipped code.
+  \item There is less temptation to change test code to fit the code
+        it tests without a good reason.
+  \item Test code should be modified much less frequently than the
+        code it tests.
+  \item Tested code can be refactored more easily.
+  \item Tests for modules written in C must be in separate modules
+        anyway, so why not be consistent?
+  \item If the testing strategy changes, there is no need to change
+        the source code.
+\end{itemize}
+
+
+\subsection{Re-using old test code
+            \label{legacy-unit-tests}}
+
+Some users will find that they have existing test code that they would
+like to run from \module{unittest}, without converting every old test
+function to a \class{TestCase} subclass.
+
+For this reason, \module{unittest} provides a \class{FunctionTestCase}
+class.  This subclass of \class{TestCase} can be used to wrap an existing
+test function.  Set-up and tear-down functions can also be provided.
+
+Given the following test function:
+
+\begin{verbatim}
+def testSomething():
+    something = makeSomething()
+    assert something.name is not None
+    # ...
+\end{verbatim}
+
+one can create an equivalent test case instance as follows:
+
+\begin{verbatim}
+testcase = unittest.FunctionTestCase(testSomething)
+\end{verbatim}
+
+If there are additional set-up and tear-down methods that should be
+called as part of the test case's operation, they can also be provided
+like so:
+
+\begin{verbatim}
+testcase = unittest.FunctionTestCase(testSomething,
+                                     setUp=makeSomethingDB,
+                                     tearDown=deleteSomethingDB)
+\end{verbatim}
+
+To make migrating existing test suites easier, \module{unittest}
+supports tests raising \exception{AssertionError} to indicate test failure.
+However, it is recommended that you use the explicit
+\method{TestCase.fail*()} and \method{TestCase.assert*()} methods instead,
+as future versions of \module{unittest} may treat \exception{AssertionError}
+differently.
+
+\note{Even though \class{FunctionTestCase} can be used to quickly convert
+an existing test base over to a \module{unittest}-based system, this
+approach is not recommended.  Taking the time to set up proper
+\class{TestCase} subclasses will make future test refactorings infinitely
+easier.}
+
+
+
+\subsection{Classes and functions
+            \label{unittest-contents}}
+
+\begin{classdesc}{TestCase}{\optional{methodName}}
+  Instances of the \class{TestCase} class represent the smallest
+  testable units in the \module{unittest} universe.  This class is
+  intended to be used as a base class, with specific tests being
+  implemented by concrete subclasses.  This class implements the
+  interface needed by the test runner to allow it to drive the
+  test, and methods that the test code can use to check for and
+  report various kinds of failure.
+  
+  Each instance of \class{TestCase} will run a single test method:
+  the method named \var{methodName}.  If you remember, we had an
+  earlier example that went something like this:
+  
+  \begin{verbatim}
+  def suite():
+      suite = unittest.TestSuite()
+      suite.addTest(WidgetTestCase('testDefaultSize'))
+      suite.addTest(WidgetTestCase('testResize'))
+      return suite
+  \end{verbatim}
+  
+  Here, we create two instances of \class{WidgetTestCase}, each of
+  which runs a single test.
+  
+  \var{methodName} defaults to \code{'runTest'}.
+\end{classdesc}
+
+\begin{classdesc}{FunctionTestCase}{testFunc\optional{,
+                  setUp\optional{, tearDown\optional{, description}}}}
+  This class implements the portion of the \class{TestCase} interface
+  which allows the test runner to drive the test, but does not provide
+  the methods which test code can use to check and report errors.
+  This is used to create test cases using legacy test code, allowing
+  it to be integrated into a \refmodule{unittest}-based test
+  framework.
+\end{classdesc}
+
+\begin{classdesc}{TestSuite}{\optional{tests}}
+  This class represents an aggregation of individual tests cases and
+  test suites.  The class presents the interface needed by the test
+  runner to allow it to be run as any other test case.  Running a
+  \class{TestSuite} instance is the same as iterating over the suite,
+  running each test individually.
+  
+  If \var{tests} is given, it must be an iterable of individual test cases or
+  other test suites that will be used to build the suite initially.
+  Additional methods are provided to add test cases and suites to the
+  collection later on.
+\end{classdesc}
+
+\begin{classdesc}{TestLoader}{}
+  This class is responsible for loading tests according to various
+  criteria and returning them wrapped in a \class{TestSuite}.
+  It can load all tests within a given module or \class{TestCase}
+  subclass.
+\end{classdesc}
+
+\begin{classdesc}{TestResult}{}
+  This class is used to compile information about which tests have succeeded
+  and which have failed.
+\end{classdesc}
+
+\begin{datadesc}{defaultTestLoader}
+  Instance of the \class{TestLoader} class intended to be shared.  If no
+  customization of the \class{TestLoader} is needed, this instance can
+  be used instead of repeatedly creating new instances.
+\end{datadesc}
+
+\begin{classdesc}{TextTestRunner}{\optional{stream\optional{,
+                  descriptions\optional{, verbosity}}}}
+  A basic test runner implementation which prints results on standard
+  error.  It has a few configurable parameters, but is essentially
+  very simple.  Graphical applications which run test suites should
+  provide alternate implementations.
+\end{classdesc}
+
+\begin{funcdesc}{main}{\optional{module\optional{,
+                 defaultTest\optional{, argv\optional{,
+                 testRunner\optional{, testLoader}}}}}}
+  A command-line program that runs a set of tests; this is primarily
+  for making test modules conveniently executable.  The simplest use
+  for this function is to include the following line at the end of a
+  test script:
+
+\begin{verbatim}
+if __name__ == '__main__':
+    unittest.main()
+\end{verbatim}
+\end{funcdesc}
+
+In some cases, the existing tests may have been written using the
+\refmodule{doctest} module.  If so, that module provides a 
+\class{DocTestSuite} class that can automatically build
+\class{unittest.TestSuite} instances from the existing
+\module{doctest}-based tests.
+\versionadded{2.3}
+
+
+\subsection{TestCase Objects
+            \label{testcase-objects}}
+
+Each \class{TestCase} instance represents a single test, but each
+concrete subclass may be used to define multiple tests --- the
+concrete class represents a single test fixture.  The fixture is
+created and cleaned up for each test case.
+
+\class{TestCase} instances provide three groups of methods: one group
+used to run the test, another used by the test implementation to
+check conditions and report failures, and some inquiry methods
+allowing information about the test itself to be gathered.
+
+Methods in the first group (running the test) are:
+
+\begin{methoddesc}[TestCase]{setUp}{}
+  Method called to prepare the test fixture.  This is called
+  immediately before calling the test method; any exception raised by
+  this method will be considered an error rather than a test failure.
+  The default implementation does nothing.
+\end{methoddesc}
+
+\begin{methoddesc}[TestCase]{tearDown}{}
+  Method called immediately after the test method has been called and
+  the result recorded.  This is called even if the test method raised
+  an exception, so the implementation in subclasses may need to be
+  particularly careful about checking internal state.  Any exception
+  raised by this method will be considered an error rather than a test
+  failure.  This method will only be called if the \method{setUp()}
+  succeeds, regardless of the outcome of the test method.
+  The default implementation does nothing.  
+\end{methoddesc}
+
+\begin{methoddesc}[TestCase]{run}{\optional{result}}
+  Run the test, collecting the result into the test result object
+  passed as \var{result}.  If \var{result} is omitted or \constant{None},
+  a temporary result object is created (by calling the
+  \method{defaultTestCase()} method) and used; this result object is not
+  returned to \method{run()}'s caller.
+  
+  The same effect may be had by simply calling the \class{TestCase}
+  instance.
+\end{methoddesc}
+
+\begin{methoddesc}[TestCase]{debug}{}
+  Run the test without collecting the result.  This allows exceptions
+  raised by the test to be propagated to the caller, and can be used
+  to support running tests under a debugger.
+\end{methoddesc}
+
+
+The test code can use any of the following methods to check for and
+report failures.
+
+\begin{methoddesc}[TestCase]{assert_}{expr\optional{, msg}}
+\methodline{failUnless}{expr\optional{, msg}}
+  Signal a test failure if \var{expr} is false; the explanation for
+  the error will be \var{msg} if given, otherwise it will be
+  \constant{None}.
+\end{methoddesc}
+
+\begin{methoddesc}[TestCase]{assertEqual}{first, second\optional{, msg}}
+\methodline{failUnlessEqual}{first, second\optional{, msg}}
+  Test that \var{first} and \var{second} are equal.  If the values do
+  not compare equal, the test will fail with the explanation given by
+  \var{msg}, or \constant{None}.  Note that using \method{failUnlessEqual()}
+  improves upon doing the comparison as the first parameter to
+  \method{failUnless()}:  the default value for \var{msg} can be
+  computed to include representations of both \var{first} and
+  \var{second}.
+\end{methoddesc}
+
+\begin{methoddesc}[TestCase]{assertNotEqual}{first, second\optional{, msg}}
+\methodline{failIfEqual}{first, second\optional{, msg}}
+  Test that \var{first} and \var{second} are not equal.  If the values
+  do compare equal, the test will fail with the explanation given by
+  \var{msg}, or \constant{None}.  Note that using \method{failIfEqual()}
+  improves upon doing the comparison as the first parameter to
+  \method{failUnless()} is that the default value for \var{msg} can be
+  computed to include representations of both \var{first} and
+  \var{second}.
+\end{methoddesc}
+
+\begin{methoddesc}[TestCase]{assertAlmostEqual}{first, second\optional{,
+						places\optional{, msg}}}
+\methodline{failUnlessAlmostEqual}{first, second\optional{,
+						places\optional{, msg}}}
+  Test that \var{first} and \var{second} are approximately equal
+  by computing the difference, rounding to the given number of \var{places},
+  and comparing to zero.  Note that comparing a given number of decimal places
+  is not the same as comparing a given number of significant digits.
+  If the values do not compare equal, the test will fail with the explanation
+  given by \var{msg}, or \constant{None}.  
+\end{methoddesc}
+
+\begin{methoddesc}[TestCase]{assertNotAlmostEqual}{first, second\optional{,
+						places\optional{, msg}}}
+\methodline{failIfAlmostEqual}{first, second\optional{,
+						places\optional{, msg}}}
+  Test that \var{first} and \var{second} are not approximately equal
+  by computing the difference, rounding to the given number of \var{places},
+  and comparing to zero.  Note that comparing a given number of decimal places
+  is not the same as comparing a given number of significant digits.
+  If the values do not compare equal, the test will fail with the explanation
+  given by \var{msg}, or \constant{None}.  
+\end{methoddesc}
+
+\begin{methoddesc}[TestCase]{assertRaises}{exception, callable, \moreargs}
+\methodline{failUnlessRaises}{exception, callable, \moreargs}
+  Test that an exception is raised when \var{callable} is called with
+  any positional or keyword arguments that are also passed to
+  \method{assertRaises()}.  The test passes if \var{exception} is
+  raised, is an error if another exception is raised, or fails if no
+  exception is raised.  To catch any of a group of exceptions, a tuple
+  containing the exception classes may be passed as \var{exception}.
+\end{methoddesc}
+
+\begin{methoddesc}[TestCase]{failIf}{expr\optional{, msg}}
+  The inverse of the \method{failUnless()} method is the
+  \method{failIf()} method.  This signals a test failure if \var{expr}
+  is true, with \var{msg} or \constant{None} for the error message.
+\end{methoddesc}
+
+\begin{methoddesc}[TestCase]{fail}{\optional{msg}}
+  Signals a test failure unconditionally, with \var{msg} or
+  \constant{None} for the error message.
+\end{methoddesc}
+
+\begin{memberdesc}[TestCase]{failureException}
+  This class attribute gives the exception raised by the
+  \method{test()} method.  If a test framework needs to use a
+  specialized exception, possibly to carry additional information, it
+  must subclass this exception in order to ``play fair'' with the
+  framework.  The initial value of this attribute is
+  \exception{AssertionError}.
+\end{memberdesc}
+
+
+Testing frameworks can use the following methods to collect
+information on the test:
+
+\begin{methoddesc}[TestCase]{countTestCases}{}
+  Return the number of tests represented by this test object.  For
+  \class{TestCase} instances, this will always be \code{1}.
+\end{methoddesc}
+
+\begin{methoddesc}[TestCase]{defaultTestResult}{}
+  Return an instance of the test result class that should be used
+  for this test case class (if no other result instance is provided
+  to the \method{run()} method).
+  
+  For \class{TestCase} instances, this will always be an instance of
+  \class{TestResult};  subclasses of \class{TestCase} should
+  override this as necessary.
+\end{methoddesc}
+
+\begin{methoddesc}[TestCase]{id}{}
+  Return a string identifying the specific test case.  This is usually
+  the full name of the test method, including the module and class
+  name.
+\end{methoddesc}
+
+\begin{methoddesc}[TestCase]{shortDescription}{}
+  Returns a one-line description of the test, or \constant{None} if no
+  description has been provided.  The default implementation of this
+  method returns the first line of the test method's docstring, if
+  available, or \constant{None}.
+\end{methoddesc}
+
+
+\subsection{TestSuite Objects
+            \label{testsuite-objects}}
+
+\class{TestSuite} objects behave much like \class{TestCase} objects,
+except they do not actually implement a test.  Instead, they are used
+to aggregate tests into groups of tests that should be run together.
+Some additional methods are available to add tests to \class{TestSuite}
+instances:
+
+\begin{methoddesc}[TestSuite]{addTest}{test}
+  Add a \class{TestCase} or \class{TestSuite} to the suite.
+\end{methoddesc}
+
+\begin{methoddesc}[TestSuite]{addTests}{tests}
+  Add all the tests from an iterable of \class{TestCase} and
+  \class{TestSuite} instances to this test suite.
+  
+  This is equivalent to iterating over \var{tests}, calling
+  \method{addTest()} for each element.
+\end{methoddesc}
+
+\class{TestSuite} shares the following methods with \class{TestCase}:
+
+\begin{methoddesc}[TestSuite]{run}{result}
+  Run the tests associated with this suite, collecting the result into
+  the test result object passed as \var{result}.  Note that unlike
+  \method{TestCase.run()}, \method{TestSuite.run()} requires the
+  result object to be passed in.
+\end{methoddesc}
+
+\begin{methoddesc}[TestSuite]{debug}{}
+  Run the tests associated with this suite without collecting the result.
+  This allows exceptions raised by the test to be propagated to the caller
+  and can be used to support running tests under a debugger.
+\end{methoddesc}
+
+\begin{methoddesc}[TestSuite]{countTestCases}{}
+  Return the number of tests represented by this test object, including
+  all individual tests and sub-suites.
+\end{methoddesc}
+
+In the typical usage of a \class{TestSuite} object, the \method{run()}
+method is invoked by a \class{TestRunner} rather than by the end-user
+test harness.
+
+
+\subsection{TestResult Objects
+            \label{testresult-objects}}
+
+A \class{TestResult} object stores the results of a set of tests.  The
+\class{TestCase} and \class{TestSuite} classes ensure that results are
+properly recorded; test authors do not need to worry about recording the
+outcome of tests.
+
+Testing frameworks built on top of \refmodule{unittest} may want
+access to the \class{TestResult} object generated by running a set of
+tests for reporting purposes; a \class{TestResult} instance is
+returned by the \method{TestRunner.run()} method for this purpose.
+
+\class{TestResult} instances have the following attributes that will
+be of interest when inspecting the results of running a set of tests:
+
+\begin{memberdesc}[TestResult]{errors}
+  A list containing 2-tuples of \class{TestCase} instances and
+  strings holding formatted tracebacks. Each tuple represents a test which
+  raised an unexpected exception.
+  \versionchanged[Contains formatted tracebacks instead of
+                  \function{sys.exc_info()} results]{2.2}
+\end{memberdesc}
+
+\begin{memberdesc}[TestResult]{failures}
+  A list containing 2-tuples of \class{TestCase} instances and strings
+  holding formatted tracebacks. Each tuple represents a test where a failure
+  was explicitly signalled using the \method{TestCase.fail*()} or
+  \method{TestCase.assert*()} methods.
+  \versionchanged[Contains formatted tracebacks instead of
+                  \function{sys.exc_info()} results]{2.2}
+\end{memberdesc}
+
+\begin{memberdesc}[TestResult]{testsRun}
+  The total number of tests run so far.
+\end{memberdesc}
+
+\begin{methoddesc}[TestResult]{wasSuccessful}{}
+  Returns \constant{True} if all tests run so far have passed,
+  otherwise returns \constant{False}.
+\end{methoddesc}
+
+\begin{methoddesc}[TestResult]{stop}{}
+  This method can be called to signal that the set of tests being run
+  should be aborted by setting the \class{TestResult}'s \code{shouldStop}
+  attribute to \constant{True}.  \class{TestRunner} objects should respect
+  this flag and return without running any additional tests.
+  
+  For example, this feature is used by the \class{TextTestRunner} class
+  to stop the test framework when the user signals an interrupt from
+  the keyboard.  Interactive tools which provide \class{TestRunner}
+  implementations can use this in a similar manner.
+\end{methoddesc}
+
+
+The following methods of the \class{TestResult} class are used to
+maintain the internal data structures, and may be extended in
+subclasses to support additional reporting requirements.  This is
+particularly useful in building tools which support interactive
+reporting while tests are being run.
+
+\begin{methoddesc}[TestResult]{startTest}{test}
+  Called when the test case \var{test} is about to be run.
+  
+  The default implementation simply increments the instance's
+  \code{testsRun} counter.
+\end{methoddesc}
+
+\begin{methoddesc}[TestResult]{stopTest}{test}
+  Called after the test case \var{test} has been executed, regardless
+  of the outcome.
+  
+  The default implementation does nothing.
+\end{methoddesc}
+
+\begin{methoddesc}[TestResult]{addError}{test, err}
+  Called when the test case \var{test} raises an unexpected exception
+  \var{err} is a tuple of the form returned by \function{sys.exc_info()}:
+  \code{(\var{type}, \var{value}, \var{traceback})}.
+  
+  The default implementation appends \code{(\var{test}, \var{err})} to
+  the instance's \code{errors} attribute.
+\end{methoddesc}
+
+\begin{methoddesc}[TestResult]{addFailure}{test, err}
+  Called when the test case \var{test} signals a failure.
+  \var{err} is a tuple of the form returned by
+  \function{sys.exc_info()}:  \code{(\var{type}, \var{value},
+  \var{traceback})}.
+  
+  The default implementation appends \code{(\var{test}, \var{err})} to
+  the instance's \code{failures} attribute.
+\end{methoddesc}
+
+\begin{methoddesc}[TestResult]{addSuccess}{test}
+  Called when the test case \var{test} succeeds.
+  
+  The default implementation does nothing.
+\end{methoddesc}
+
+
+
+\subsection{TestLoader Objects
+            \label{testloader-objects}}
+
+The \class{TestLoader} class is used to create test suites from
+classes and modules.  Normally, there is no need to create an instance
+of this class; the \refmodule{unittest} module provides an instance
+that can be shared as \code{unittest.defaultTestLoader}.
+Using a subclass or instance, however, allows customization of some
+configurable properties.
+
+\class{TestLoader} objects have the following methods:
+
+\begin{methoddesc}[TestLoader]{loadTestsFromTestCase}{testCaseClass}
+  Return a suite of all tests cases contained in the
+  \class{TestCase}-derived \class{testCaseClass}.
+\end{methoddesc}
+
+\begin{methoddesc}[TestLoader]{loadTestsFromModule}{module}
+  Return a suite of all tests cases contained in the given module.
+  This method searches \var{module} for classes derived from
+  \class{TestCase} and creates an instance of the class for each test
+  method defined for the class.
+
+  \warning{While using a hierarchy of
+  \class{TestCase}-derived classes can be convenient in sharing
+  fixtures and helper functions, defining test methods on base classes
+  that are not intended to be instantiated directly does not play well
+  with this method.  Doing so, however, can be useful when the
+  fixtures are different and defined in subclasses.}
+\end{methoddesc}
+
+\begin{methoddesc}[TestLoader]{loadTestsFromName}{name\optional{, module}}
+  Return a suite of all tests cases given a string specifier.
+
+  The specifier \var{name} is a ``dotted name'' that may resolve
+  either to a module, a test case class, a test method within a test
+  case class, a \class{TestSuite} instance, or a callable object which
+  returns a \class{TestCase} or \class{TestSuite} instance.  These checks
+  are applied in the order listed here; that is, a method on a possible
+  test case class will be picked up as ``a test method within a test
+  case class'', rather than ``a callable object''.
+
+  For example, if you have a module \module{SampleTests} containing a
+  \class{TestCase}-derived class \class{SampleTestCase} with three test
+  methods (\method{test_one()}, \method{test_two()}, and
+  \method{test_three()}), the specifier \code{'SampleTests.SampleTestCase'}
+  would cause this method to return a suite which will run all three test
+  methods.  Using the specifier \code{'SampleTests.SampleTestCase.test_two'}
+  would cause it to return a test suite which will run only the
+  \method{test_two()} test method.  The specifier can refer to modules
+  and packages which have not been imported; they will be imported as
+  a side-effect.
+
+  The method optionally resolves \var{name} relative to the given
+  \var{module}.
+\end{methoddesc}
+
+\begin{methoddesc}[TestLoader]{loadTestsFromNames}{names\optional{, module}}
+  Similar to \method{loadTestsFromName()}, but takes a sequence of
+  names rather than a single name.  The return value is a test suite
+  which supports all the tests defined for each name.
+\end{methoddesc}
+
+\begin{methoddesc}[TestLoader]{getTestCaseNames}{testCaseClass}
+  Return a sorted sequence of method names found within
+  \var{testCaseClass}; this should be a subclass of \class{TestCase}.
+\end{methoddesc}
+
+
+The following attributes of a \class{TestLoader} can be configured
+either by subclassing or assignment on an instance:
+
+\begin{memberdesc}[TestLoader]{testMethodPrefix}
+  String giving the prefix of method names which will be interpreted
+  as test methods.  The default value is \code{'test'}.
+  
+  This affects \method{getTestCaseNames()} and all the
+  \method{loadTestsFrom*()} methods.
+\end{memberdesc}
+
+\begin{memberdesc}[TestLoader]{sortTestMethodsUsing}
+  Function to be used to compare method names when sorting them in
+  \method{getTestCaseNames()} and all the \method{loadTestsFrom*()} methods.
+  The default value is the built-in \function{cmp()} function; the attribute
+  can also be set to \constant{None} to disable the sort.
+\end{memberdesc}
+
+\begin{memberdesc}[TestLoader]{suiteClass}
+  Callable object that constructs a test suite from a list of tests.
+  No methods on the resulting object are needed.  The default value is
+  the \class{TestSuite} class.
+  
+  This affects all the \method{loadTestsFrom*()} methods.
+\end{memberdesc}

Added: vendor/Python/current/Doc/lib/libunix.tex
===================================================================
--- vendor/Python/current/Doc/lib/libunix.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libunix.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,8 @@
+\chapter{Unix Specific Services}
+\label{unix}
+
+The modules described in this chapter provide interfaces to features
+that are unique to the \UNIX{} operating system, or in some cases to
+some or many variants of it.  Here's an overview:
+
+\localmoduletable

Added: vendor/Python/current/Doc/lib/liburllib.tex
===================================================================
--- vendor/Python/current/Doc/lib/liburllib.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/liburllib.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,497 @@
+\section{\module{urllib} ---
+         Open arbitrary resources by URL}
+
+\declaremodule{standard}{urllib}
+\modulesynopsis{Open an arbitrary network resource by URL (requires sockets).}
+
+\index{WWW}
+\index{World Wide Web}
+\index{URL}
+
+
+This module provides a high-level interface for fetching data across
+the World Wide Web.  In particular, the \function{urlopen()} function
+is similar to the built-in function \function{open()}, but accepts
+Universal Resource Locators (URLs) instead of filenames.  Some
+restrictions apply --- it can only open URLs for reading, and no seek
+operations are available.
+
+It defines the following public functions:
+
+\begin{funcdesc}{urlopen}{url\optional{, data\optional{, proxies}}}
+Open a network object denoted by a URL for reading.  If the URL does
+not have a scheme identifier, or if it has \file{file:} as its scheme
+identifier, this opens a local file (without universal newlines);
+otherwise it opens a socket to a server somewhere on the network.  If
+the connection cannot be made
+the \exception{IOError} exception is raised.  If all went well, a
+file-like object is returned.  This supports the following methods:
+\method{read()}, \method{readline()}, \method{readlines()}, \method{fileno()},
+\method{close()}, \method{info()} and \method{geturl()}.  It also has
+proper support for the iterator protocol.
+One caveat: the \method{read()} method, if the size argument is
+omitted or negative, may not read until the end of the data stream;
+there is no good way to determine that the entire stream from a socket
+has been read in the general case.
+
+Except for the \method{info()} and \method{geturl()} methods,
+these methods have the same interface as for
+file objects --- see section \ref{bltin-file-objects} in this
+manual.  (It is not a built-in file object, however, so it can't be
+used at those few places where a true built-in file object is
+required.)
+
+The \method{info()} method returns an instance of the class
+\class{mimetools.Message} containing meta-information associated
+with the URL.  When the method is HTTP, these headers are those
+returned by the server at the head of the retrieved HTML page
+(including Content-Length and Content-Type).  When the method is FTP,
+a Content-Length header will be present if (as is now usual) the
+server passed back a file length in response to the FTP retrieval
+request. A Content-Type header will be present if the MIME type can
+be guessed.  When the method is local-file, returned headers will include
+a Date representing the file's last-modified time, a Content-Length
+giving file size, and a Content-Type containing a guess at the file's
+type. See also the description of the
+\refmodule{mimetools}\refstmodindex{mimetools} module.
+
+The \method{geturl()} method returns the real URL of the page.  In
+some cases, the HTTP server redirects a client to another URL.  The
+\function{urlopen()} function handles this transparently, but in some
+cases the caller needs to know which URL the client was redirected
+to.  The \method{geturl()} method can be used to get at this
+redirected URL.
+
+If the \var{url} uses the \file{http:} scheme identifier, the optional
+\var{data} argument may be given to specify a \code{POST} request
+(normally the request type is \code{GET}).  The \var{data} argument
+must be in standard \mimetype{application/x-www-form-urlencoded} format;
+see the \function{urlencode()} function below.
+
+The \function{urlopen()} function works transparently with proxies
+which do not require authentication.  In a \UNIX{} or Windows
+environment, set the \envvar{http_proxy}, \envvar{ftp_proxy} or
+\envvar{gopher_proxy} environment variables to a URL that identifies
+the proxy server before starting the Python interpreter.  For example
+(the \character{\%} is the command prompt):
+
+\begin{verbatim}
+% http_proxy="http://www.someproxy.com:3128"
+% export http_proxy
+% python
+...
+\end{verbatim}
+
+In a Windows environment, if no proxy environment variables are set,
+proxy settings are obtained from the registry's Internet Settings
+section.
+
+In a Macintosh environment, \function{urlopen()} will retrieve proxy
+information from Internet\index{Internet Config} Config.
+
+Alternatively, the optional \var{proxies} argument may be used to
+explicitly specify proxies.  It must be a dictionary mapping scheme
+names to proxy URLs, where an empty dictionary causes no proxies to be
+used, and \code{None} (the default value) causes environmental proxy
+settings to be used as discussed above.  For example:
+
+\begin{verbatim}
+# Use http://www.someproxy.com:3128 for http proxying
+proxies = {'http': 'http://www.someproxy.com:3128'}
+filehandle = urllib.urlopen(some_url, proxies=proxies)
+# Don't use any proxies
+filehandle = urllib.urlopen(some_url, proxies={})
+# Use proxies from environment - both versions are equivalent
+filehandle = urllib.urlopen(some_url, proxies=None)
+filehandle = urllib.urlopen(some_url)
+\end{verbatim}
+
+The \function{urlopen()} function does not support explicit proxy
+specification.  If you need to override environmental proxy settings,
+use \class{URLopener}, or a subclass such as \class{FancyURLopener}.
+
+Proxies which require authentication for use are not currently
+supported; this is considered an implementation limitation.
+
+\versionchanged[Added the \var{proxies} support]{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{urlretrieve}{url\optional{, filename\optional{,
+                              reporthook\optional{, data}}}}
+Copy a network object denoted by a URL to a local file, if necessary.
+If the URL points to a local file, or a valid cached copy of the
+object exists, the object is not copied.  Return a tuple
+\code{(\var{filename}, \var{headers})} where \var{filename} is the
+local file name under which the object can be found, and \var{headers}
+is whatever the \method{info()} method of the object returned by
+\function{urlopen()} returned (for a remote object, possibly cached).
+Exceptions are the same as for \function{urlopen()}.
+
+The second argument, if present, specifies the file location to copy
+to (if absent, the location will be a tempfile with a generated name).
+The third argument, if present, is a hook function that will be called
+once on establishment of the network connection and once after each
+block read thereafter.  The hook will be passed three arguments; a
+count of blocks transferred so far, a block size in bytes, and the
+total size of the file.  The third argument may be \code{-1} on older
+FTP servers which do not return a file size in response to a retrieval
+request.
+
+If the \var{url} uses the \file{http:} scheme identifier, the optional
+\var{data} argument may be given to specify a \code{POST} request
+(normally the request type is \code{GET}).  The \var{data} argument
+must in standard \mimetype{application/x-www-form-urlencoded} format;
+see the \function{urlencode()} function below.
+
+\versionchanged[
+\function{urlretrieve()} will raise \exception{ContentTooShortError}
+when it detects that the amount of data available 
+was less than the expected amount (which is the size reported by a 
+\var{Content-Length} header). This can occur, for example, when the 
+download is interrupted.
+
+The \var{Content-Length} is treated as a lower bound: if there's more data 
+to read, urlretrieve reads more data, but if less data is available, 
+it raises the exception.
+
+You can still retrieve the downloaded data in this case, it is stored 
+in the \member{content} attribute of the exception instance.
+
+If no \var{Content-Length} header was supplied, urlretrieve can
+not check the size of the data it has downloaded, and just returns it. 
+In this case you just have to assume that the download was successful]{2.5}
+
+\end{funcdesc}
+
+\begin{datadesc}{_urlopener}
+The public functions \function{urlopen()} and
+\function{urlretrieve()} create an instance of the
+\class{FancyURLopener} class and use it to perform their requested
+actions.  To override this functionality, programmers can create a
+subclass of \class{URLopener} or \class{FancyURLopener}, then assign
+an instance of that class to the
+\code{urllib._urlopener} variable before calling the desired function.
+For example, applications may want to specify a different
+\mailheader{User-Agent} header than \class{URLopener} defines.  This
+can be accomplished with the following code:
+
+\begin{verbatim}
+import urllib
+
+class AppURLopener(urllib.FancyURLopener):
+    version = "App/1.7"
+
+urllib._urlopener = AppURLopener()
+\end{verbatim}
+\end{datadesc}
+
+\begin{funcdesc}{urlcleanup}{}
+Clear the cache that may have been built up by previous calls to
+\function{urlretrieve()}.
+\end{funcdesc}
+
+\begin{funcdesc}{quote}{string\optional{, safe}}
+Replace special characters in \var{string} using the \samp{\%xx} escape.
+Letters, digits, and the characters \character{_.-} are never quoted.
+The optional \var{safe} parameter specifies additional characters
+that should not be quoted --- its default value is \code{'/'}.
+
+Example: \code{quote('/\~{}connolly/')} yields \code{'/\%7econnolly/'}.
+\end{funcdesc}
+
+\begin{funcdesc}{quote_plus}{string\optional{, safe}}
+Like \function{quote()}, but also replaces spaces by plus signs, as
+required for quoting HTML form values.  Plus signs in the original
+string are escaped unless they are included in \var{safe}.  It also
+does not have \var{safe} default to \code{'/'}.
+\end{funcdesc}
+
+\begin{funcdesc}{unquote}{string}
+Replace \samp{\%xx} escapes by their single-character equivalent.
+
+Example: \code{unquote('/\%7Econnolly/')} yields \code{'/\~{}connolly/'}.
+\end{funcdesc}
+
+\begin{funcdesc}{unquote_plus}{string}
+Like \function{unquote()}, but also replaces plus signs by spaces, as
+required for unquoting HTML form values.
+\end{funcdesc}
+
+\begin{funcdesc}{urlencode}{query\optional{, doseq}}
+Convert a mapping object or a sequence of two-element tuples  to a
+``url-encoded'' string, suitable to pass to
+\function{urlopen()} above as the optional \var{data} argument.  This
+is useful to pass a dictionary of form fields to a \code{POST}
+request.  The resulting string is a series of
+\code{\var{key}=\var{value}} pairs separated by \character{\&}
+characters, where both \var{key} and \var{value} are quoted using
+\function{quote_plus()} above.  If the optional parameter \var{doseq} is
+present and evaluates to true, individual \code{\var{key}=\var{value}} pairs
+are generated for each element of the sequence.
+When a sequence of two-element tuples is used as the \var{query} argument,
+the first element of each tuple is a key and the second is a value.  The
+order of parameters in the encoded string will match the order of parameter
+tuples in the sequence.
+The \refmodule{cgi} module provides the functions
+\function{parse_qs()} and \function{parse_qsl()} which are used to
+parse query strings into Python data structures.
+\end{funcdesc}
+
+\begin{funcdesc}{pathname2url}{path}
+Convert the pathname \var{path} from the local syntax for a path to
+the form used in the path component of a URL.  This does not produce a
+complete URL.  The return value will already be quoted using the
+\function{quote()} function.
+\end{funcdesc}
+
+\begin{funcdesc}{url2pathname}{path}
+Convert the path component \var{path} from an encoded URL to the local
+syntax for a path.  This does not accept a complete URL.  This
+function uses \function{unquote()} to decode \var{path}.
+\end{funcdesc}
+
+\begin{classdesc}{URLopener}{\optional{proxies\optional{, **x509}}}
+Base class for opening and reading URLs.  Unless you need to support
+opening objects using schemes other than \file{http:}, \file{ftp:},
+\file{gopher:} or \file{file:}, you probably want to use
+\class{FancyURLopener}.
+
+By default, the \class{URLopener} class sends a
+\mailheader{User-Agent} header of \samp{urllib/\var{VVV}}, where
+\var{VVV} is the \module{urllib} version number.  Applications can
+define their own \mailheader{User-Agent} header by subclassing
+\class{URLopener} or \class{FancyURLopener} and setting the class
+attribute \member{version} to an appropriate string value in the
+subclass definition.
+
+The optional \var{proxies} parameter should be a dictionary mapping
+scheme names to proxy URLs, where an empty dictionary turns proxies
+off completely.  Its default value is \code{None}, in which case
+environmental proxy settings will be used if present, as discussed in
+the definition of \function{urlopen()}, above.
+
+Additional keyword parameters, collected in \var{x509}, may be used for
+authentication of the client when using the \file{https:} scheme.  The keywords
+\var{key_file} and \var{cert_file} are supported to provide an 
+SSL key and certificate; both are needed to support client authentication.
+
+\class{URLopener} objects will raise an \exception{IOError} exception
+if the server returns an error code.
+\end{classdesc}
+
+\begin{classdesc}{FancyURLopener}{...}
+\class{FancyURLopener} subclasses \class{URLopener} providing default
+handling for the following HTTP response codes: 301, 302, 303, 307 and
+401.  For the 30x response codes listed above, the
+\mailheader{Location} header is used to fetch the actual URL.  For 401
+response codes (authentication required), basic HTTP authentication is
+performed.  For the 30x response codes, recursion is bounded by the
+value of the \var{maxtries} attribute, which defaults to 10.
+
+For all other response codes, the method \method{http_error_default()}
+is called which you can override in subclasses to handle the error
+appropriately.
+
+\note{According to the letter of \rfc{2616}, 301 and 302 responses to
+  POST requests must not be automatically redirected without
+  confirmation by the user.  In reality, browsers do allow automatic
+  redirection of these responses, changing the POST to a GET, and
+  \module{urllib} reproduces this behaviour.}
+
+The parameters to the constructor are the same as those for
+\class{URLopener}.
+
+\note{When performing basic authentication, a
+\class{FancyURLopener} instance calls its
+\method{prompt_user_passwd()} method.  The default implementation asks
+the users for the required information on the controlling terminal.  A
+subclass may override this method to support more appropriate behavior
+if needed.}
+\end{classdesc}
+
+\begin{excclassdesc}{ContentTooShortError}{msg\optional{, content}}
+This exception is raised when the \function{urlretrieve()} function
+detects that the amount of the downloaded data is less than the 
+expected amount (given by the \var{Content-Length} header). The
+\member{content} attribute stores the downloaded (and supposedly
+truncated) data.
+\versionadded{2.5}
+\end{excclassdesc}
+
+Restrictions:
+
+\begin{itemize}
+
+\item
+Currently, only the following protocols are supported: HTTP, (versions
+0.9 and 1.0), Gopher (but not Gopher-+), FTP, and local files.
+\indexii{HTTP}{protocol}
+\indexii{Gopher}{protocol}
+\indexii{FTP}{protocol}
+
+\item
+The caching feature of \function{urlretrieve()} has been disabled
+until I find the time to hack proper processing of Expiration time
+headers.
+
+\item
+There should be a function to query whether a particular URL is in
+the cache.
+
+\item
+For backward compatibility, if a URL appears to point to a local file
+but the file can't be opened, the URL is re-interpreted using the FTP
+protocol.  This can sometimes cause confusing error messages.
+
+\item
+The \function{urlopen()} and \function{urlretrieve()} functions can
+cause arbitrarily long delays while waiting for a network connection
+to be set up.  This means that it is difficult to build an interactive
+Web client using these functions without using threads.
+
+\item
+The data returned by \function{urlopen()} or \function{urlretrieve()}
+is the raw data returned by the server.  This may be binary data
+(such as an image), plain text or (for example) HTML\index{HTML}.  The
+HTTP\indexii{HTTP}{protocol} protocol provides type information in the
+reply header, which can be inspected by looking at the
+\mailheader{Content-Type} header.  For the
+Gopher\indexii{Gopher}{protocol} protocol, type information is encoded
+in the URL; there is currently no easy way to extract it.  If the
+returned data is HTML, you can use the module
+\refmodule{htmllib}\refstmodindex{htmllib} to parse it.
+
+\item
+The code handling the FTP\index{FTP} protocol cannot differentiate
+between a file and a directory.  This can lead to unexpected behavior
+when attempting to read a URL that points to a file that is not
+accessible.  If the URL ends in a \code{/}, it is assumed to refer to
+a directory and will be handled accordingly.  But if an attempt to
+read a file leads to a 550 error (meaning the URL cannot be found or
+is not accessible, often for permission reasons), then the path is
+treated as a directory in order to handle the case when a directory is
+specified by a URL but the trailing \code{/} has been left off.  This can
+cause misleading results when you try to fetch a file whose read
+permissions make it inaccessible; the FTP code will try to read it,
+fail with a 550 error, and then perform a directory listing for the
+unreadable file. If fine-grained control is needed, consider using the
+\module{ftplib} module, subclassing \class{FancyURLOpener}, or changing
+\var{_urlopener} to meet your needs.
+
+\item
+This module does not support the use of proxies which require
+authentication.  This may be implemented in the future.
+
+\item
+Although the \module{urllib} module contains (undocumented) routines
+to parse and unparse URL strings, the recommended interface for URL
+manipulation is in module \refmodule{urlparse}\refstmodindex{urlparse}.
+
+\end{itemize}
+
+
+\subsection{URLopener Objects \label{urlopener-objs}}
+\sectionauthor{Skip Montanaro}{skip at mojam.com}
+
+\class{URLopener} and \class{FancyURLopener} objects have the
+following attributes.
+
+\begin{methoddesc}[URLopener]{open}{fullurl\optional{, data}}
+Open \var{fullurl} using the appropriate protocol.  This method sets
+up cache and proxy information, then calls the appropriate open method with
+its input arguments.  If the scheme is not recognized,
+\method{open_unknown()} is called.  The \var{data} argument
+has the same meaning as the \var{data} argument of \function{urlopen()}.
+\end{methoddesc}
+
+\begin{methoddesc}[URLopener]{open_unknown}{fullurl\optional{, data}}
+Overridable interface to open unknown URL types.
+\end{methoddesc}
+
+\begin{methoddesc}[URLopener]{retrieve}{url\optional{,
+                                        filename\optional{,
+                                        reporthook\optional{, data}}}}
+Retrieves the contents of \var{url} and places it in \var{filename}.  The
+return value is a tuple consisting of a local filename and either a
+\class{mimetools.Message} object containing the response headers (for remote
+URLs) or \code{None} (for local URLs).  The caller must then open and read the
+contents of \var{filename}.  If \var{filename} is not given and the URL
+refers to a local file, the input filename is returned.  If the URL is
+non-local and \var{filename} is not given, the filename is the output of
+\function{tempfile.mktemp()} with a suffix that matches the suffix of the last
+path component of the input URL.  If \var{reporthook} is given, it must be
+a function accepting three numeric parameters.  It will be called after each
+chunk of data is read from the network.  \var{reporthook} is ignored for
+local URLs.
+
+If the \var{url} uses the \file{http:} scheme identifier, the optional
+\var{data} argument may be given to specify a \code{POST} request
+(normally the request type is \code{GET}).  The \var{data} argument
+must in standard \mimetype{application/x-www-form-urlencoded} format;
+see the \function{urlencode()} function below.
+\end{methoddesc}
+
+\begin{memberdesc}[URLopener]{version}
+Variable that specifies the user agent of the opener object.  To get
+\refmodule{urllib} to tell servers that it is a particular user agent,
+set this in a subclass as a class variable or in the constructor
+before calling the base constructor.
+\end{memberdesc}
+
+The \class{FancyURLopener} class offers one additional method that
+should be overloaded to provide the appropriate behavior:
+
+\begin{methoddesc}[FancyURLopener]{prompt_user_passwd}{host, realm}
+Return information needed to authenticate the user at the given host
+in the specified security realm.  The return value should be a tuple,
+\code{(\var{user}, \var{password})}, which can be used for basic
+authentication.
+
+The implementation prompts for this information on the terminal; an
+application should override this method to use an appropriate
+interaction model in the local environment.
+\end{methoddesc}
+
+
+\subsection{Examples}
+\nodename{Urllib Examples}
+
+Here is an example session that uses the \samp{GET} method to retrieve
+a URL containing parameters:
+
+\begin{verbatim}
+>>> import urllib
+>>> params = urllib.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})
+>>> f = urllib.urlopen("http://www.musi-cal.com/cgi-bin/query?%s" % params)
+>>> print f.read()
+\end{verbatim}
+
+The following example uses the \samp{POST} method instead:
+
+\begin{verbatim}
+>>> import urllib
+>>> params = urllib.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})
+>>> f = urllib.urlopen("http://www.musi-cal.com/cgi-bin/query", params)
+>>> print f.read()
+\end{verbatim}
+
+The following example uses an explicitly specified HTTP proxy,
+overriding environment settings:
+
+\begin{verbatim}
+>>> import urllib
+>>> proxies = {'http': 'http://proxy.example.com:8080/'}
+>>> opener = urllib.FancyURLopener(proxies)
+>>> f = opener.open("http://www.python.org")
+>>> f.read()
+\end{verbatim}
+
+The following example uses no proxies at all, overriding environment
+settings:
+
+\begin{verbatim}
+>>> import urllib
+>>> opener = urllib.FancyURLopener({})
+>>> f = opener.open("http://www.python.org/")
+>>> f.read()
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/liburllib2.tex
===================================================================
--- vendor/Python/current/Doc/lib/liburllib2.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/liburllib2.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,872 @@
+\section{\module{urllib2} ---
+         extensible library for opening URLs}
+
+\declaremodule{standard}{urllib2}
+\moduleauthor{Jeremy Hylton}{jhylton at users.sourceforge.net}
+\sectionauthor{Moshe Zadka}{moshez at users.sourceforge.net}
+
+\modulesynopsis{An extensible library for opening URLs using a variety of 
+                protocols}
+
+The \module{urllib2} module defines functions and classes which help
+in opening URLs (mostly HTTP) in a complex world --- basic and digest
+authentication, redirections, cookies and more.
+
+The \module{urllib2} module defines the following functions:
+
+\begin{funcdesc}{urlopen}{url\optional{, data}}
+Open the URL \var{url}, which can be either a string or a \class{Request}
+object.
+
+\var{data} may be a string specifying additional data to send to the
+server, or \code{None} if no such data is needed. 
+Currently HTTP requests are the only ones that use \var{data};
+the HTTP request will be a POST instead of a GET when the \var{data}
+parameter is provided.  \var{data} should be a buffer in the standard
+\mimetype{application/x-www-form-urlencoded} format.  The
+\function{urllib.urlencode()} function takes a mapping or sequence of
+2-tuples and returns a string in this format.
+
+This function returns a file-like object with two additional methods:
+
+\begin{itemize}
+  \item \method{geturl()} --- return the URL of the resource retrieved
+  \item \method{info()} --- return the meta-information of the page, as
+                            a dictionary-like object
+\end{itemize}
+
+Raises \exception{URLError} on errors.
+
+Note that \code{None} may be returned if no handler handles the
+request (though the default installed global \class{OpenerDirector}
+uses \class{UnknownHandler} to ensure this never happens).
+\end{funcdesc}
+
+\begin{funcdesc}{install_opener}{opener}
+Install an \class{OpenerDirector} instance as the default global
+opener.  Installing an opener is only necessary if you want urlopen to
+use that opener; otherwise, simply call \method{OpenerDirector.open()}
+instead of \function{urlopen()}.  The code does not check for a real
+\class{OpenerDirector}, and any class with the appropriate interface
+will work.
+\end{funcdesc}
+
+\begin{funcdesc}{build_opener}{\optional{handler, \moreargs}}
+Return an \class{OpenerDirector} instance, which chains the
+handlers in the order given. \var{handler}s can be either instances
+of \class{BaseHandler}, or subclasses of \class{BaseHandler} (in
+which case it must be possible to call the constructor without
+any parameters).  Instances of the following classes will be in
+front of the \var{handler}s, unless the \var{handler}s contain
+them, instances of them or subclasses of them:
+\class{ProxyHandler}, \class{UnknownHandler}, \class{HTTPHandler},
+\class{HTTPDefaultErrorHandler}, \class{HTTPRedirectHandler},
+\class{FTPHandler}, \class{FileHandler}, \class{HTTPErrorProcessor}.
+
+If the Python installation has SSL support (\function{socket.ssl()}
+exists), \class{HTTPSHandler} will also be added.
+
+Beginning in Python 2.3, a \class{BaseHandler} subclass may also
+change its \member{handler_order} member variable to modify its
+position in the handlers list.
+\end{funcdesc}
+
+
+The following exceptions are raised as appropriate:
+
+\begin{excdesc}{URLError}
+The handlers raise this exception (or derived exceptions) when they
+run into a problem.  It is a subclass of \exception{IOError}.
+\end{excdesc}
+
+\begin{excdesc}{HTTPError}
+A subclass of \exception{URLError}, it can also function as a 
+non-exceptional file-like return value (the same thing that
+\function{urlopen()} returns).  This is useful when handling exotic
+HTTP errors, such as requests for authentication.
+\end{excdesc}
+
+\begin{excdesc}{GopherError}
+A subclass of \exception{URLError}, this is the error raised by the
+Gopher handler.
+\end{excdesc}
+
+
+The following classes are provided:
+
+\begin{classdesc}{Request}{url\optional{, data}\optional{, headers}
+    \optional{, origin_req_host}\optional{, unverifiable}}
+This class is an abstraction of a URL request.
+
+\var{url} should be a string containing a valid URL.  
+
+\var{data} may be a string specifying additional data to send to the
+server, or \code{None} if no such data is needed. 
+Currently HTTP requests are the only ones that use \var{data};
+the HTTP request will be a POST instead of a GET when the \var{data}
+parameter is provided.  \var{data} should be a buffer in the standard
+\mimetype{application/x-www-form-urlencoded} format.  The
+\function{urllib.urlencode()} function takes a mapping or sequence of
+2-tuples and returns a string in this format.
+
+\var{headers} should be a dictionary, and will be treated as if
+\method{add_header()} was called with each key and value as arguments.
+
+The final two arguments are only of interest for correct handling of
+third-party HTTP cookies:
+
+\var{origin_req_host} should be the request-host of the origin
+transaction, as defined by \rfc{2965}.  It defaults to
+\code{cookielib.request_host(self)}.  This is the host name or IP
+address of the original request that was initiated by the user.  For
+example, if the request is for an image in an HTML document, this
+should be the request-host of the request for the page containing the
+image.
+
+\var{unverifiable} should indicate whether the request is
+unverifiable, as defined by RFC 2965.  It defaults to False.  An
+unverifiable request is one whose URL the user did not have the option
+to approve.  For example, if the request is for an image in an HTML
+document, and the user had no option to approve the automatic fetching
+of the image, this should be true.
+\end{classdesc}
+
+\begin{classdesc}{OpenerDirector}{}
+The \class{OpenerDirector} class opens URLs via \class{BaseHandler}s
+chained together. It manages the chaining of handlers, and recovery
+from errors.
+\end{classdesc}
+
+\begin{classdesc}{BaseHandler}{}
+This is the base class for all registered handlers --- and handles only
+the simple mechanics of registration.
+\end{classdesc}
+
+\begin{classdesc}{HTTPDefaultErrorHandler}{}
+A class which defines a default handler for HTTP error responses; all
+responses are turned into \exception{HTTPError} exceptions.
+\end{classdesc}
+
+\begin{classdesc}{HTTPRedirectHandler}{}
+A class to handle redirections.
+\end{classdesc}
+
+\begin{classdesc}{HTTPCookieProcessor}{\optional{cookiejar}}
+A class to handle HTTP Cookies.
+\end{classdesc}
+
+\begin{classdesc}{ProxyHandler}{\optional{proxies}}
+Cause requests to go through a proxy.
+If \var{proxies} is given, it must be a dictionary mapping
+protocol names to URLs of proxies.
+The default is to read the list of proxies from the environment
+variables \envvar{<protocol>_proxy}.
+\end{classdesc}
+
+\begin{classdesc}{HTTPPasswordMgr}{}
+Keep a database of 
+\code{(\var{realm}, \var{uri}) -> (\var{user}, \var{password})}
+mappings.
+\end{classdesc}
+
+\begin{classdesc}{HTTPPasswordMgrWithDefaultRealm}{}
+Keep a database of 
+\code{(\var{realm}, \var{uri}) -> (\var{user}, \var{password})} mappings.
+A realm of \code{None} is considered a catch-all realm, which is searched
+if no other realm fits.
+\end{classdesc}
+
+\begin{classdesc}{AbstractBasicAuthHandler}{\optional{password_mgr}}
+This is a mixin class that helps with HTTP authentication, both
+to the remote host and to a proxy.
+\var{password_mgr}, if given, should be something that is compatible
+with \class{HTTPPasswordMgr}; refer to section~\ref{http-password-mgr}
+for information on the interface that must be supported.
+\end{classdesc}
+
+\begin{classdesc}{HTTPBasicAuthHandler}{\optional{password_mgr}}
+Handle authentication with the remote host.
+\var{password_mgr}, if given, should be something that is compatible
+with \class{HTTPPasswordMgr}; refer to section~\ref{http-password-mgr}
+for information on the interface that must be supported.
+\end{classdesc}
+
+\begin{classdesc}{ProxyBasicAuthHandler}{\optional{password_mgr}}
+Handle authentication with the proxy.
+\var{password_mgr}, if given, should be something that is compatible
+with \class{HTTPPasswordMgr}; refer to section~\ref{http-password-mgr}
+for information on the interface that must be supported.
+\end{classdesc}
+
+\begin{classdesc}{AbstractDigestAuthHandler}{\optional{password_mgr}}
+This is a mixin class that helps with HTTP authentication, both
+to the remote host and to a proxy.
+\var{password_mgr}, if given, should be something that is compatible
+with \class{HTTPPasswordMgr}; refer to section~\ref{http-password-mgr}
+for information on the interface that must be supported.
+\end{classdesc}
+
+\begin{classdesc}{HTTPDigestAuthHandler}{\optional{password_mgr}}
+Handle authentication with the remote host.
+\var{password_mgr}, if given, should be something that is compatible
+with \class{HTTPPasswordMgr}; refer to section~\ref{http-password-mgr}
+for information on the interface that must be supported.
+\end{classdesc}
+
+\begin{classdesc}{ProxyDigestAuthHandler}{\optional{password_mgr}}
+Handle authentication with the proxy.
+\var{password_mgr}, if given, should be something that is compatible
+with \class{HTTPPasswordMgr}; refer to section~\ref{http-password-mgr}
+for information on the interface that must be supported.
+\end{classdesc}
+
+\begin{classdesc}{HTTPHandler}{}
+A class to handle opening of HTTP URLs.
+\end{classdesc}
+
+\begin{classdesc}{HTTPSHandler}{}
+A class to handle opening of HTTPS URLs.
+\end{classdesc}
+
+\begin{classdesc}{FileHandler}{}
+Open local files.
+\end{classdesc}
+
+\begin{classdesc}{FTPHandler}{}
+Open FTP URLs.
+\end{classdesc}
+
+\begin{classdesc}{CacheFTPHandler}{}
+Open FTP URLs, keeping a cache of open FTP connections to minimize
+delays.
+\end{classdesc}
+
+\begin{classdesc}{GopherHandler}{}
+Open gopher URLs.
+\end{classdesc}
+
+\begin{classdesc}{UnknownHandler}{}
+A catch-all class to handle unknown URLs.
+\end{classdesc}
+
+
+\subsection{Request Objects \label{request-objects}}
+
+The following methods describe all of \class{Request}'s public interface,
+and so all must be overridden in subclasses.
+
+\begin{methoddesc}[Request]{add_data}{data}
+Set the \class{Request} data to \var{data}.  This is ignored by all
+handlers except HTTP handlers --- and there it should be a byte
+string, and will change the request to be \code{POST} rather than
+\code{GET}.
+\end{methoddesc}
+
+\begin{methoddesc}[Request]{get_method}{}
+Return a string indicating the HTTP request method.  This is only
+meaningful for HTTP requests, and currently always returns
+\code{'GET'} or \code{'POST'}.
+\end{methoddesc}
+
+\begin{methoddesc}[Request]{has_data}{}
+Return whether the instance has a non-\code{None} data.
+\end{methoddesc}
+
+\begin{methoddesc}[Request]{get_data}{}
+Return the instance's data.
+\end{methoddesc}
+
+\begin{methoddesc}[Request]{add_header}{key, val}
+Add another header to the request.  Headers are currently ignored by
+all handlers except HTTP handlers, where they are added to the list
+of headers sent to the server.  Note that there cannot be more than
+one header with the same name, and later calls will overwrite
+previous calls in case the \var{key} collides.  Currently, this is
+no loss of HTTP functionality, since all headers which have meaning
+when used more than once have a (header-specific) way of gaining the
+same functionality using only one header.
+\end{methoddesc}
+
+\begin{methoddesc}[Request]{add_unredirected_header}{key, header}
+Add a header that will not be added to a redirected request.
+\versionadded{2.4}
+\end{methoddesc}
+
+\begin{methoddesc}[Request]{has_header}{header}
+Return whether the instance has the named header (checks both regular
+and unredirected).
+\versionadded{2.4}
+\end{methoddesc}
+
+\begin{methoddesc}[Request]{get_full_url}{}
+Return the URL given in the constructor.
+\end{methoddesc}
+
+\begin{methoddesc}[Request]{get_type}{}
+Return the type of the URL --- also known as the scheme.
+\end{methoddesc}
+
+\begin{methoddesc}[Request]{get_host}{}
+Return the host to which a connection will be made.
+\end{methoddesc}
+
+\begin{methoddesc}[Request]{get_selector}{}
+Return the selector --- the part of the URL that is sent to
+the server.
+\end{methoddesc}
+
+\begin{methoddesc}[Request]{set_proxy}{host, type}
+Prepare the request by connecting to a proxy server. The \var{host}
+and \var{type} will replace those of the instance, and the instance's
+selector will be the original URL given in the constructor.
+\end{methoddesc}
+
+\begin{methoddesc}[Request]{get_origin_req_host}{}
+Return the request-host of the origin transaction, as defined by
+\rfc{2965}.  See the documentation for the \class{Request}
+constructor.
+\end{methoddesc}
+
+\begin{methoddesc}[Request]{is_unverifiable}{}
+Return whether the request is unverifiable, as defined by RFC 2965.
+See the documentation for the \class{Request} constructor.
+\end{methoddesc}
+
+
+\subsection{OpenerDirector Objects \label{opener-director-objects}}
+
+\class{OpenerDirector} instances have the following methods:
+
+\begin{methoddesc}[OpenerDirector]{add_handler}{handler}
+\var{handler} should be an instance of \class{BaseHandler}.  The
+following methods are searched, and added to the possible chains (note
+that HTTP errors are a special case).
+
+\begin{itemize}
+  \item \method{\var{protocol}_open()} ---
+    signal that the handler knows how to open \var{protocol} URLs.
+  \item \method{http_error_\var{type}()} ---
+    signal that the handler knows how to handle HTTP errors with HTTP
+    error code \var{type}.
+  \item \method{\var{protocol}_error()} ---
+    signal that the handler knows how to handle errors from
+    (non-\code{http}) \var{protocol}.
+  \item \method{\var{protocol}_request()} ---
+    signal that the handler knows how to pre-process \var{protocol}
+    requests.
+  \item \method{\var{protocol}_response()} ---
+    signal that the handler knows how to post-process \var{protocol}
+    responses.
+\end{itemize}
+\end{methoddesc}
+
+\begin{methoddesc}[OpenerDirector]{open}{url\optional{, data}}
+Open the given \var{url} (which can be a request object or a string),
+optionally passing the given \var{data}.
+Arguments, return values and exceptions raised are the same as those
+of \function{urlopen()} (which simply calls the \method{open()} method
+on the currently installed global \class{OpenerDirector}).
+\end{methoddesc}
+
+\begin{methoddesc}[OpenerDirector]{error}{proto\optional{,
+                                          arg\optional{, \moreargs}}}
+Handle an error of the given protocol.  This will call the registered
+error handlers for the given protocol with the given arguments (which
+are protocol specific).  The HTTP protocol is a special case which
+uses the HTTP response code to determine the specific error handler;
+refer to the \method{http_error_*()} methods of the handler classes.
+
+Return values and exceptions raised are the same as those
+of \function{urlopen()}.
+\end{methoddesc}
+
+OpenerDirector objects open URLs in three stages:
+
+The order in which these methods are called within each stage is
+determined by sorting the handler instances.
+
+\begin{enumerate}
+  \item Every handler with a method named like
+    \method{\var{protocol}_request()} has that method called to
+    pre-process the request.
+
+  \item Handlers with a method named like
+    \method{\var{protocol}_open()} are called to handle the request.
+    This stage ends when a handler either returns a
+    non-\constant{None} value (ie. a response), or raises an exception
+    (usually \exception{URLError}).  Exceptions are allowed to propagate.
+
+    In fact, the above algorithm is first tried for methods named
+    \method{default_open}.  If all such methods return
+    \constant{None}, the algorithm is repeated for methods named like
+    \method{\var{protocol}_open()}.  If all such methods return
+    \constant{None}, the algorithm is repeated for methods named
+    \method{unknown_open()}.
+
+    Note that the implementation of these methods may involve calls of
+    the parent \class{OpenerDirector} instance's \method{.open()} and
+    \method{.error()} methods.
+
+  \item Every handler with a method named like
+    \method{\var{protocol}_response()} has that method called to
+    post-process the response.
+
+\end{enumerate}
+
+\subsection{BaseHandler Objects \label{base-handler-objects}}
+
+\class{BaseHandler} objects provide a couple of methods that are
+directly useful, and others that are meant to be used by derived
+classes.  These are intended for direct use:
+
+\begin{methoddesc}[BaseHandler]{add_parent}{director}
+Add a director as parent.
+\end{methoddesc}
+
+\begin{methoddesc}[BaseHandler]{close}{}
+Remove any parents.
+\end{methoddesc}
+
+The following members and methods should only be used by classes
+derived from \class{BaseHandler}.  \note{The convention has been
+adopted that subclasses defining \method{\var{protocol}_request()} or
+\method{\var{protocol}_response()} methods are named
+\class{*Processor}; all others are named \class{*Handler}.}
+
+
+\begin{memberdesc}[BaseHandler]{parent}
+A valid \class{OpenerDirector}, which can be used to open using a
+different protocol, or handle errors.
+\end{memberdesc}
+
+\begin{methoddesc}[BaseHandler]{default_open}{req}
+This method is \emph{not} defined in \class{BaseHandler}, but
+subclasses should define it if they want to catch all URLs.
+
+This method, if implemented, will be called by the parent
+\class{OpenerDirector}.  It should return a file-like object as
+described in the return value of the \method{open()} of
+\class{OpenerDirector}, or \code{None}.  It should raise
+\exception{URLError}, unless a truly exceptional thing happens (for
+example, \exception{MemoryError} should not be mapped to
+\exception{URLError}).
+
+This method will be called before any protocol-specific open method.
+\end{methoddesc}
+
+\begin{methoddescni}[BaseHandler]{\var{protocol}_open}{req}
+This method is \emph{not} defined in \class{BaseHandler}, but
+subclasses should define it if they want to handle URLs with the given
+protocol.
+
+This method, if defined, will be called by the parent
+\class{OpenerDirector}.  Return values should be the same as for 
+\method{default_open()}.
+\end{methoddescni}
+
+\begin{methoddesc}[BaseHandler]{unknown_open}{req}
+This method is \var{not} defined in \class{BaseHandler}, but
+subclasses should define it if they want to catch all URLs with no
+specific registered handler to open it.
+
+This method, if implemented, will be called by the \member{parent} 
+\class{OpenerDirector}.  Return values should be the same as for 
+\method{default_open()}.
+\end{methoddesc}
+
+\begin{methoddesc}[BaseHandler]{http_error_default}{req, fp, code, msg, hdrs}
+This method is \emph{not} defined in \class{BaseHandler}, but
+subclasses should override it if they intend to provide a catch-all
+for otherwise unhandled HTTP errors.  It will be called automatically
+by the  \class{OpenerDirector} getting the error, and should not
+normally be called in other circumstances.
+
+\var{req} will be a \class{Request} object, \var{fp} will be a
+file-like object with the HTTP error body, \var{code} will be the
+three-digit code of the error, \var{msg} will be the user-visible
+explanation of the code and \var{hdrs} will be a mapping object with
+the headers of the error.
+
+Return values and exceptions raised should be the same as those
+of \function{urlopen()}.
+\end{methoddesc}
+
+\begin{methoddesc}[BaseHandler]{http_error_\var{nnn}}{req, fp, code, msg, hdrs}
+\var{nnn} should be a three-digit HTTP error code.  This method is
+also not defined in \class{BaseHandler}, but will be called, if it
+exists, on an instance of a subclass, when an HTTP error with code
+\var{nnn} occurs.
+
+Subclasses should override this method to handle specific HTTP
+errors.
+
+Arguments, return values and exceptions raised should be the same as
+for \method{http_error_default()}.
+\end{methoddesc}
+
+\begin{methoddescni}[BaseHandler]{\var{protocol}_request}{req}
+This method is \emph{not} defined in \class{BaseHandler}, but
+subclasses should define it if they want to pre-process requests of
+the given protocol.
+
+This method, if defined, will be called by the parent
+\class{OpenerDirector}.  \var{req} will be a \class{Request} object.
+The return value should be a \class{Request} object.
+\end{methoddescni}
+
+\begin{methoddescni}[BaseHandler]{\var{protocol}_response}{req, response}
+This method is \emph{not} defined in \class{BaseHandler}, but
+subclasses should define it if they want to post-process responses of
+the given protocol.
+
+This method, if defined, will be called by the parent
+\class{OpenerDirector}.  \var{req} will be a \class{Request} object.
+\var{response} will be an object implementing the same interface as
+the return value of \function{urlopen()}.  The return value should
+implement the same interface as the return value of
+\function{urlopen()}.
+\end{methoddescni}
+
+\subsection{HTTPRedirectHandler Objects \label{http-redirect-handler}}
+
+\note{Some HTTP redirections require action from this module's client
+  code.  If this is the case, \exception{HTTPError} is raised.  See
+  \rfc{2616} for details of the precise meanings of the various
+  redirection codes.}
+
+\begin{methoddesc}[HTTPRedirectHandler]{redirect_request}{req,
+                                                  fp, code, msg, hdrs}
+Return a \class{Request} or \code{None} in response to a redirect.
+This is called by the default implementations of the
+\method{http_error_30*()} methods when a redirection is received from
+the server.  If a redirection should take place, return a new
+\class{Request} to allow \method{http_error_30*()} to perform the
+redirect.  Otherwise, raise \exception{HTTPError} if no other handler
+should try to handle this URL, or return \code{None} if you can't but
+another handler might.
+
+\begin{notice}
+ The default implementation of this method does not strictly
+ follow \rfc{2616}, which says that 301 and 302 responses to \code{POST}
+ requests must not be automatically redirected without confirmation by
+ the user.  In reality, browsers do allow automatic redirection of
+ these responses, changing the POST to a \code{GET}, and the default
+ implementation reproduces this behavior.
+\end{notice}
+\end{methoddesc}
+
+
+\begin{methoddesc}[HTTPRedirectHandler]{http_error_301}{req,
+                                                  fp, code, msg, hdrs}
+Redirect to the \code{Location:} URL.  This method is called by
+the parent \class{OpenerDirector} when getting an HTTP
+`moved permanently' response.
+\end{methoddesc}
+
+\begin{methoddesc}[HTTPRedirectHandler]{http_error_302}{req,
+                                                  fp, code, msg, hdrs}
+The same as \method{http_error_301()}, but called for the
+`found' response.
+\end{methoddesc}
+
+\begin{methoddesc}[HTTPRedirectHandler]{http_error_303}{req,
+                                                  fp, code, msg, hdrs}
+The same as \method{http_error_301()}, but called for the
+`see other' response.
+\end{methoddesc}
+
+\begin{methoddesc}[HTTPRedirectHandler]{http_error_307}{req,
+                                                  fp, code, msg, hdrs}
+The same as \method{http_error_301()}, but called for the
+`temporary redirect' response.
+\end{methoddesc}
+
+
+\subsection{HTTPCookieProcessor Objects \label{http-cookie-processor}}
+
+\versionadded{2.4}
+
+\class{HTTPCookieProcessor} instances have one attribute:
+
+\begin{memberdesc}{cookiejar}
+The \class{cookielib.CookieJar} in which cookies are stored.
+\end{memberdesc}
+
+
+\subsection{ProxyHandler Objects \label{proxy-handler}}
+
+\begin{methoddescni}[ProxyHandler]{\var{protocol}_open}{request}
+The \class{ProxyHandler} will have a method
+\method{\var{protocol}_open()} for every \var{protocol} which has a
+proxy in the \var{proxies} dictionary given in the constructor.  The
+method will modify requests to go through the proxy, by calling
+\code{request.set_proxy()}, and call the next handler in the chain to
+actually execute the protocol.
+\end{methoddescni}
+
+
+\subsection{HTTPPasswordMgr Objects \label{http-password-mgr}}
+
+These methods are available on \class{HTTPPasswordMgr} and
+\class{HTTPPasswordMgrWithDefaultRealm} objects.
+
+\begin{methoddesc}[HTTPPasswordMgr]{add_password}{realm, uri, user, passwd}
+\var{uri} can be either a single URI, or a sequence of URIs. \var{realm},
+\var{user} and \var{passwd} must be strings. This causes
+\code{(\var{user}, \var{passwd})} to be used as authentication tokens
+when authentication for \var{realm} and a super-URI of any of the
+given URIs is given.
+\end{methoddesc}  
+
+\begin{methoddesc}[HTTPPasswordMgr]{find_user_password}{realm, authuri}
+Get user/password for given realm and URI, if any.  This method will
+return \code{(None, None)} if there is no matching user/password.
+
+For \class{HTTPPasswordMgrWithDefaultRealm} objects, the realm
+\code{None} will be searched if the given \var{realm} has no matching
+user/password.
+\end{methoddesc}
+
+
+\subsection{AbstractBasicAuthHandler Objects
+            \label{abstract-basic-auth-handler}}
+
+\begin{methoddesc}[AbstractBasicAuthHandler]{http_error_auth_reqed}
+                                            {authreq, host, req, headers}
+Handle an authentication request by getting a user/password pair, and
+re-trying the request.  \var{authreq} should be the name of the header
+where the information about the realm is included in the request,
+\var{host} specifies the URL and path to authenticate for, \var{req}
+should be the (failed) \class{Request} object, and \var{headers}
+should be the error headers.
+
+\var{host} is either an authority (e.g. \code{"python.org"}) or a URL
+containing an authority component (e.g. \code{"http://python.org/"}).
+In either case, the authority must not contain a userinfo component
+(so, \code{"python.org"} and \code{"python.org:80"} are fine,
+\code{"joe:password at python.org"} is not).
+\end{methoddesc}
+
+
+\subsection{HTTPBasicAuthHandler Objects
+            \label{http-basic-auth-handler}}
+
+\begin{methoddesc}[HTTPBasicAuthHandler]{http_error_401}{req, fp, code, 
+                                                        msg, hdrs}
+Retry the request with authentication information, if available.
+\end{methoddesc}
+
+
+\subsection{ProxyBasicAuthHandler Objects
+            \label{proxy-basic-auth-handler}}
+
+\begin{methoddesc}[ProxyBasicAuthHandler]{http_error_407}{req, fp, code, 
+                                                        msg, hdrs}
+Retry the request with authentication information, if available.
+\end{methoddesc}
+
+
+\subsection{AbstractDigestAuthHandler Objects
+            \label{abstract-digest-auth-handler}}
+
+\begin{methoddesc}[AbstractDigestAuthHandler]{http_error_auth_reqed}
+                                            {authreq, host, req, headers}
+\var{authreq} should be the name of the header where the information about
+the realm is included in the request, \var{host} should be the host to
+authenticate to, \var{req} should be the (failed) \class{Request}
+object, and \var{headers} should be the error headers.
+\end{methoddesc}
+
+
+\subsection{HTTPDigestAuthHandler Objects
+            \label{http-digest-auth-handler}}
+
+\begin{methoddesc}[HTTPDigestAuthHandler]{http_error_401}{req, fp, code, 
+                                                        msg, hdrs}
+Retry the request with authentication information, if available.
+\end{methoddesc}
+
+
+\subsection{ProxyDigestAuthHandler Objects
+            \label{proxy-digest-auth-handler}}
+
+\begin{methoddesc}[ProxyDigestAuthHandler]{http_error_407}{req, fp, code, 
+                                                        msg, hdrs}
+Retry the request with authentication information, if available.
+\end{methoddesc}
+
+
+\subsection{HTTPHandler Objects \label{http-handler-objects}}
+
+\begin{methoddesc}[HTTPHandler]{http_open}{req}
+Send an HTTP request, which can be either GET or POST, depending on
+\code{\var{req}.has_data()}.
+\end{methoddesc}
+
+
+\subsection{HTTPSHandler Objects \label{https-handler-objects}}
+
+\begin{methoddesc}[HTTPSHandler]{https_open}{req}
+Send an HTTPS request, which can be either GET or POST, depending on
+\code{\var{req}.has_data()}.
+\end{methoddesc}
+
+
+\subsection{FileHandler Objects \label{file-handler-objects}}
+
+\begin{methoddesc}[FileHandler]{file_open}{req}
+Open the file locally, if there is no host name, or
+the host name is \code{'localhost'}. Change the
+protocol to \code{ftp} otherwise, and retry opening
+it using \member{parent}.
+\end{methoddesc}
+
+
+\subsection{FTPHandler Objects \label{ftp-handler-objects}}
+
+\begin{methoddesc}[FTPHandler]{ftp_open}{req}
+Open the FTP file indicated by \var{req}.
+The login is always done with empty username and password.
+\end{methoddesc}
+
+
+\subsection{CacheFTPHandler Objects \label{cacheftp-handler-objects}}
+
+\class{CacheFTPHandler} objects are \class{FTPHandler} objects with
+the following additional methods:
+
+\begin{methoddesc}[CacheFTPHandler]{setTimeout}{t}
+Set timeout of connections to \var{t} seconds.
+\end{methoddesc}
+
+\begin{methoddesc}[CacheFTPHandler]{setMaxConns}{m}
+Set maximum number of cached connections to \var{m}.
+\end{methoddesc}
+
+
+\subsection{GopherHandler Objects \label{gopher-handler}}
+
+\begin{methoddesc}[GopherHandler]{gopher_open}{req}
+Open the gopher resource indicated by \var{req}.
+\end{methoddesc}
+
+
+\subsection{UnknownHandler Objects \label{unknown-handler-objects}}
+
+\begin{methoddesc}[UnknownHandler]{unknown_open}{}
+Raise a \exception{URLError} exception.
+\end{methoddesc}
+
+
+\subsection{HTTPErrorProcessor Objects \label{http-error-processor-objects}}
+
+\versionadded{2.4}
+
+\begin{methoddesc}[HTTPErrorProcessor]{unknown_open}{}
+Process HTTP error responses.
+
+For 200 error codes, the response object is returned immediately.
+
+For non-200 error codes, this simply passes the job on to the
+\method{\var{protocol}_error_\var{code}()} handler methods, via
+\method{OpenerDirector.error()}.  Eventually,
+\class{urllib2.HTTPDefaultErrorHandler} will raise an
+\exception{HTTPError} if no other handler handles the error.
+\end{methoddesc}
+
+
+\subsection{Examples \label{urllib2-examples}}
+
+This example gets the python.org main page and displays the first 100
+bytes of it:
+
+\begin{verbatim}
+>>> import urllib2
+>>> f = urllib2.urlopen('http://www.python.org/')
+>>> print f.read(100)
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<?xml-stylesheet href="./css/ht2html
+\end{verbatim}
+
+Here we are sending a data-stream to the stdin of a CGI and reading
+the data it returns to us. Note that this example will only work when the
+Python installation supports SSL.
+
+\begin{verbatim}
+>>> import urllib2
+>>> req = urllib2.Request(url='https://localhost/cgi-bin/test.cgi',
+...                       data='This data is passed to stdin of the CGI')
+>>> f = urllib2.urlopen(req)
+>>> print f.read()
+Got Data: "This data is passed to stdin of the CGI"
+\end{verbatim}
+
+The code for the sample CGI used in the above example is:
+
+\begin{verbatim}
+#!/usr/bin/env python
+import sys
+data = sys.stdin.read()
+print 'Content-type: text-plain\n\nGot Data: "%s"' % data
+\end{verbatim}
+
+
+Use of Basic HTTP Authentication:
+
+\begin{verbatim}
+import urllib2
+# Create an OpenerDirector with support for Basic HTTP Authentication...
+auth_handler = urllib2.HTTPBasicAuthHandler()
+auth_handler.add_password('realm', 'host', 'username', 'password')
+opener = urllib2.build_opener(auth_handler)
+# ...and install it globally so it can be used with urlopen.
+urllib2.install_opener(opener)
+urllib2.urlopen('http://www.example.com/login.html')
+\end{verbatim}
+
+\function{build_opener()} provides many handlers by default, including a
+\class{ProxyHandler}.  By default, \class{ProxyHandler} uses the
+environment variables named \code{<scheme>_proxy}, where \code{<scheme>}
+is the URL scheme involved.  For example, the \envvar{http_proxy}
+environment variable is read to obtain the HTTP proxy's URL.
+
+This example replaces the default \class{ProxyHandler} with one that uses
+programatically-supplied proxy URLs, and adds proxy authorization support
+with \class{ProxyBasicAuthHandler}.
+
+\begin{verbatim}
+proxy_handler = urllib2.ProxyHandler({'http': 'http://www.example.com:3128/'})
+proxy_auth_handler = urllib2.HTTPBasicAuthHandler()
+proxy_auth_handler.add_password('realm', 'host', 'username', 'password')
+
+opener = build_opener(proxy_handler, proxy_auth_handler)
+# This time, rather than install the OpenerDirector, we use it directly:
+opener.open('http://www.example.com/login.html')
+\end{verbatim}
+
+
+Adding HTTP headers:
+
+Use the \var{headers} argument to the \class{Request} constructor, or:
+
+\begin{verbatim}
+import urllib2
+req = urllib2.Request('http://www.example.com/')
+req.add_header('Referer', 'http://www.python.org/')
+r = urllib2.urlopen(req)
+\end{verbatim}
+
+\class{OpenerDirector} automatically adds a \mailheader{User-Agent}
+header to every \class{Request}.  To change this:
+
+\begin{verbatim}
+import urllib2
+opener = urllib2.build_opener()
+opener.addheaders = [('User-agent', 'Mozilla/5.0')]
+opener.open('http://www.example.com/')
+\end{verbatim}
+
+Also, remember that a few standard headers
+(\mailheader{Content-Length}, \mailheader{Content-Type} and
+\mailheader{Host}) are added when the \class{Request} is passed to
+\function{urlopen()} (or \method{OpenerDirector.open()}).

Added: vendor/Python/current/Doc/lib/liburlparse.tex
===================================================================
--- vendor/Python/current/Doc/lib/liburlparse.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/liburlparse.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,253 @@
+\section{\module{urlparse} ---
+         Parse URLs into components}
+\declaremodule{standard}{urlparse}
+
+\modulesynopsis{Parse URLs into components.}
+
+\index{WWW}
+\index{World Wide Web}
+\index{URL}
+\indexii{URL}{parsing}
+\indexii{relative}{URL}
+
+
+This module defines a standard interface to break Uniform Resource
+Locator (URL) strings up in components (addressing scheme, network
+location, path etc.), to combine the components back into a URL
+string, and to convert a ``relative URL'' to an absolute URL given a
+``base URL.''
+
+The module has been designed to match the Internet RFC on Relative
+Uniform Resource Locators (and discovered a bug in an earlier
+draft!). It supports the following URL schemes:
+\code{file}, \code{ftp}, \code{gopher}, \code{hdl}, \code{http}, 
+\code{https}, \code{imap}, \code{mailto}, \code{mms}, \code{news}, 
+\code{nntp}, \code{prospero}, \code{rsync}, \code{rtsp}, \code{rtspu}, 
+\code{sftp}, \code{shttp}, \code{sip}, \code{sips}, \code{snews}, \code{svn}, 
+\code{svn+ssh}, \code{telnet}, \code{wais}.
+
+\versionadded[Support for the \code{sftp} and \code{sips} schemes]{2.5}
+
+The \module{urlparse} module defines the following functions:
+
+\begin{funcdesc}{urlparse}{urlstring\optional{,
+                           default_scheme\optional{, allow_fragments}}}
+Parse a URL into six components, returning a 6-tuple.  This
+corresponds to the general structure of a URL:
+\code{\var{scheme}://\var{netloc}/\var{path};\var{parameters}?\var{query}\#\var{fragment}}.
+Each tuple item is a string, possibly empty.
+The components are not broken up in smaller parts (for example, the network
+location is a single string), and \% escapes are not expanded.
+The delimiters as shown above are not part of the result,
+except for a leading slash in the \var{path} component, which is
+retained if present.  For example:
+
+\begin{verbatim}
+>>> from urlparse import urlparse
+>>> o = urlparse('http://www.cwi.nl:80/%7Eguido/Python.html')
+>>> o
+('http', 'www.cwi.nl:80', '/%7Eguido/Python.html', '', '', '')
+>>> o.scheme
+'http'
+>>> o.port
+80
+>>> o.geturl()
+'http://www.cwi.nl:80/%7Eguido/Python.html'
+\end{verbatim}
+
+If the \var{default_scheme} argument is specified, it gives the
+default addressing scheme, to be used only if the URL does not
+specify one.  The default value for this argument is the empty string.
+
+If the \var{allow_fragments} argument is false, fragment identifiers
+are not allowed, even if the URL's addressing scheme normally does
+support them.  The default value for this argument is \constant{True}.
+
+The return value is actually an instance of a subclass of
+\pytype{tuple}.  This class has the following additional read-only
+convenience attributes:
+
+\begin{tableiv}{l|c|l|c}{member}{Attribute}{Index}{Value}{Value if not present}
+  \lineiv{scheme}  {0} {URL scheme specifier}             {empty string}
+  \lineiv{netloc}  {1} {Network location part}            {empty string}
+  \lineiv{path}    {2} {Hierarchical path}                {empty string}
+  \lineiv{params}  {3} {Parameters for last path element} {empty string}
+  \lineiv{query}   {4} {Query component}                  {empty string}
+  \lineiv{fragment}{5} {Fragment identifier}              {empty string}
+  \lineiv{username}{ } {User name}                        {\constant{None}}
+  \lineiv{password}{ } {Password}                         {\constant{None}}
+  \lineiv{hostname}{ } {Host name (lower case)}           {\constant{None}}
+  \lineiv{port}    { } {Port number as integer, if present} {\constant{None}}
+\end{tableiv}
+
+See section~\ref{urlparse-result-object}, ``Results of
+\function{urlparse()} and \function{urlsplit()},'' for more
+information on the result object.
+
+\versionchanged[Added attributes to return value]{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{urlunparse}{parts}
+Construct a URL from a tuple as returned by \code{urlparse()}.
+The \var{parts} argument can be any six-item iterable.
+This may result in a slightly different, but equivalent URL, if the
+URL that was parsed originally had unnecessary delimiters (for example,
+a ? with an empty query; the RFC states that these are equivalent).
+\end{funcdesc}
+
+\begin{funcdesc}{urlsplit}{urlstring\optional{,
+                           default_scheme\optional{, allow_fragments}}}
+This is similar to \function{urlparse()}, but does not split the
+params from the URL.  This should generally be used instead of
+\function{urlparse()} if the more recent URL syntax allowing
+parameters to be applied to each segment of the \var{path} portion of
+the URL (see \rfc{2396}) is wanted.  A separate function is needed to
+separate the path segments and parameters.  This function returns a
+5-tuple: (addressing scheme, network location, path, query, fragment
+identifier).
+
+The return value is actually an instance of a subclass of
+\pytype{tuple}.  This class has the following additional read-only
+convenience attributes:
+
+\begin{tableiv}{l|c|l|c}{member}{Attribute}{Index}{Value}{Value if not present}
+  \lineiv{scheme}   {0} {URL scheme specifier}   {empty string}
+  \lineiv{netloc}   {1} {Network location part}  {empty string}
+  \lineiv{path}     {2} {Hierarchical path}      {empty string}
+  \lineiv{query}    {3} {Query component}        {empty string}
+  \lineiv{fragment} {4} {Fragment identifier}    {empty string}
+  \lineiv{username} { } {User name}              {\constant{None}}
+  \lineiv{password} { } {Password}               {\constant{None}}
+  \lineiv{hostname} { } {Host name (lower case)} {\constant{None}}
+  \lineiv{port}     { } {Port number as integer, if present} {\constant{None}}
+\end{tableiv}
+
+See section~\ref{urlparse-result-object}, ``Results of
+\function{urlparse()} and \function{urlsplit()},'' for more
+information on the result object.
+
+\versionadded{2.2}
+\versionchanged[Added attributes to return value]{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{urlunsplit}{parts}
+Combine the elements of a tuple as returned by \function{urlsplit()}
+into a complete URL as a string.
+The \var{parts} argument can be any five-item iterable.
+This may result in a slightly different, but equivalent URL, if the
+URL that was parsed originally had unnecessary delimiters (for example,
+a ? with an empty query; the RFC states that these are equivalent).
+\versionadded{2.2}
+\end{funcdesc}
+
+\begin{funcdesc}{urljoin}{base, url\optional{, allow_fragments}}
+Construct a full (``absolute'') URL by combining a ``base URL''
+(\var{base}) with another URL (\var{url}).  Informally, this
+uses components of the base URL, in particular the addressing scheme,
+the network location and (part of) the path, to provide missing
+components in the relative URL.  For example:
+
+\begin{verbatim}
+>>> from urlparse import urljoin
+>>> urljoin('http://www.cwi.nl/%7Eguido/Python.html', 'FAQ.html')
+'http://www.cwi.nl/%7Eguido/FAQ.html'
+\end{verbatim}
+
+The \var{allow_fragments} argument has the same meaning and default as
+for \function{urlparse()}.
+
+\note{If \var{url} is an absolute URL (that is, starting with \code{//}
+      or \code{scheme://}, the \var{url}'s host name and/or scheme
+      will be present in the result.  For example:}
+
+\begin{verbatim}
+>>> urljoin('http://www.cwi.nl/%7Eguido/Python.html',
+...         '//www.python.org/%7Eguido')
+'http://www.python.org/%7Eguido'
+\end{verbatim}
+      
+If you do not want that behavior, preprocess
+the \var{url} with \function{urlsplit()} and \function{urlunsplit()},
+removing possible \emph{scheme} and \emph{netloc} parts.
+\end{funcdesc}
+
+\begin{funcdesc}{urldefrag}{url}
+If \var{url} contains a fragment identifier, returns a modified
+version of \var{url} with no fragment identifier, and the fragment
+identifier as a separate string.  If there is no fragment identifier
+in \var{url}, returns \var{url} unmodified and an empty string.
+\end{funcdesc}
+
+
+\begin{seealso}
+  \seerfc{1738}{Uniform Resource Locators (URL)}{
+        This specifies the formal syntax and semantics of absolute
+        URLs.}
+  \seerfc{1808}{Relative Uniform Resource Locators}{
+        This Request For Comments includes the rules for joining an
+        absolute and a relative URL, including a fair number of
+        ``Abnormal Examples'' which govern the treatment of border
+        cases.}
+  \seerfc{2396}{Uniform Resource Identifiers (URI): Generic Syntax}{
+        Document describing the generic syntactic requirements for
+        both Uniform Resource Names (URNs) and Uniform Resource
+        Locators (URLs).}
+\end{seealso}
+
+
+\subsection{Results of \function{urlparse()} and \function{urlsplit()}
+            \label{urlparse-result-object}}
+
+The result objects from the \function{urlparse()} and
+\function{urlsplit()} functions are subclasses of the \pytype{tuple}
+type.  These subclasses add the attributes described in those
+functions, as well as provide an additional method:
+
+\begin{methoddesc}[ParseResult]{geturl}{}
+  Return the re-combined version of the original URL as a string.
+  This may differ from the original URL in that the scheme will always
+  be normalized to lower case and empty components may be dropped.
+  Specifically, empty parameters, queries, and fragment identifiers
+  will be removed.
+
+  The result of this method is a fixpoint if passed back through the
+  original parsing function:
+
+\begin{verbatim}
+>>> import urlparse
+>>> url = 'HTTP://www.Python.org/doc/#'
+
+>>> r1 = urlparse.urlsplit(url)
+>>> r1.geturl()
+'http://www.Python.org/doc/'
+
+>>> r2 = urlparse.urlsplit(r1.geturl())
+>>> r2.geturl()
+'http://www.Python.org/doc/'
+\end{verbatim}
+
+\versionadded{2.5}
+\end{methoddesc}
+
+The following classes provide the implementations of the parse results::
+
+\begin{classdesc*}{BaseResult}
+  Base class for the concrete result classes.  This provides most of
+  the attribute definitions.  It does not provide a \method{geturl()}
+  method.  It is derived from \class{tuple}, but does not override the
+  \method{__init__()} or \method{__new__()} methods.
+\end{classdesc*}
+
+
+\begin{classdesc}{ParseResult}{scheme, netloc, path, params, query, fragment}
+  Concrete class for \function{urlparse()} results.  The
+  \method{__new__()} method is overridden to support checking that the
+  right number of arguments are passed.
+\end{classdesc}
+
+
+\begin{classdesc}{SplitResult}{scheme, netloc, path, query, fragment}
+  Concrete class for \function{urlsplit()} results.  The
+  \method{__new__()} method is overridden to support checking that the
+  right number of arguments are passed.
+\end{classdesc}

Added: vendor/Python/current/Doc/lib/libuser.tex
===================================================================
--- vendor/Python/current/Doc/lib/libuser.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libuser.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,71 @@
+\section{\module{user} ---
+         User-specific configuration hook}
+
+\declaremodule{standard}{user}
+\modulesynopsis{A standard way to reference user-specific modules.}
+
+
+\indexii{.pythonrc.py}{file}
+\indexiii{user}{configuration}{file}
+
+As a policy, Python doesn't run user-specified code on startup of
+Python programs.  (Only interactive sessions execute the script
+specified in the \envvar{PYTHONSTARTUP} environment variable if it
+exists).
+
+However, some programs or sites may find it convenient to allow users
+to have a standard customization file, which gets run when a program
+requests it.  This module implements such a mechanism.  A program
+that wishes to use the mechanism must execute the statement
+
+\begin{verbatim}
+import user
+\end{verbatim}
+
+The \module{user} module looks for a file \file{.pythonrc.py} in the user's
+home directory and if it can be opened, executes it (using
+\function{execfile()}\bifuncindex{execfile}) in its own (the
+module \module{user}'s) global namespace.  Errors during this phase
+are not caught; that's up to the program that imports the
+\module{user} module, if it wishes.  The home directory is assumed to
+be named by the \envvar{HOME} environment variable; if this is not set,
+the current directory is used.
+
+The user's \file{.pythonrc.py} could conceivably test for
+\code{sys.version} if it wishes to do different things depending on
+the Python version.
+
+A warning to users: be very conservative in what you place in your
+\file{.pythonrc.py} file.  Since you don't know which programs will
+use it, changing the behavior of standard modules or functions is
+generally not a good idea.
+
+A suggestion for programmers who wish to use this mechanism: a simple
+way to let users specify options for your package is to have them
+define variables in their \file{.pythonrc.py} file that you test in
+your module.  For example, a module \module{spam} that has a verbosity
+level can look for a variable \code{user.spam_verbose}, as follows:
+
+\begin{verbatim}
+import user
+
+verbose = bool(getattr(user, "spam_verbose", 0))
+\end{verbatim}
+
+(The three-argument form of \function{getattr()} is used in case
+the user has not defined \code{spam_verbose} in their
+\file{.pythonrc.py} file.)
+
+Programs with extensive customization needs are better off reading a
+program-specific customization file.
+
+Programs with security or privacy concerns should \emph{not} import
+this module; a user can easily break into a program by placing
+arbitrary code in the \file{.pythonrc.py} file.
+
+Modules for general use should \emph{not} import this module; it may
+interfere with the operation of the importing program.
+
+\begin{seealso}
+  \seemodule{site}{Site-wide customization mechanism.}
+\end{seealso}

Added: vendor/Python/current/Doc/lib/libuserdict.tex
===================================================================
--- vendor/Python/current/Doc/lib/libuserdict.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libuserdict.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,181 @@
+\section{\module{UserDict} ---
+         Class wrapper for dictionary objects}
+
+\declaremodule{standard}{UserDict}
+\modulesynopsis{Class wrapper for dictionary objects.}
+
+
+The module defines a mixin,  \class{DictMixin}, defining all dictionary
+methods for classes that already have a minimum mapping interface.  This
+greatly simplifies writing classes that need to be substitutable for
+dictionaries (such as the shelve module).
+
+This also module defines a class, \class{UserDict}, that acts as a wrapper
+around dictionary objects.  The need for this class has been largely
+supplanted by the ability to subclass directly from \class{dict} (a feature
+that became available starting with Python version 2.2).  Prior to the
+introduction of \class{dict}, the \class{UserDict} class was used to
+create dictionary-like sub-classes that obtained new behaviors by overriding
+existing methods or adding new ones.
+
+The \module{UserDict} module defines the \class{UserDict} class
+and \class{DictMixin}:
+
+\begin{classdesc}{UserDict}{\optional{initialdata}} 
+Class that simulates a dictionary.  The instance's contents are kept
+in a regular dictionary, which is accessible via the \member{data}
+attribute of \class{UserDict} instances.  If \var{initialdata} is
+provided, \member{data} is initialized with its contents; note that a
+reference to \var{initialdata} will not be kept, allowing it be used
+for other purposes. \note{For backward compatibility, instances of
+\class{UserDict} are not iterable.}
+\end{classdesc}
+
+\begin{classdesc}{IterableUserDict}{\optional{initialdata}}
+Subclass of \class{UserDict} that supports direct iteration (e.g. 
+\code{for key in myDict}).
+\end{classdesc}
+
+In addition to supporting the methods and operations of mappings (see
+section \ref{typesmapping}), \class{UserDict} and
+\class{IterableUserDict} instances provide the following attribute:
+
+\begin{memberdesc}{data}
+A real dictionary used to store the contents of the \class{UserDict}
+class.
+\end{memberdesc}
+
+\begin{classdesc}{DictMixin}{}
+Mixin defining all dictionary methods for classes that already have
+a minimum dictionary interface including \method{__getitem__()},
+\method{__setitem__()}, \method{__delitem__()}, and \method{keys()}.
+
+This mixin should be used as a superclass.  Adding each of the
+above methods adds progressively more functionality.  For instance,
+defining all but \method{__delitem__} will preclude only \method{pop}
+and \method{popitem} from the full interface.
+
+In addition to the four base methods, progressively more efficiency
+comes with defining \method{__contains__()}, \method{__iter__()}, and
+\method{iteritems()}.
+
+Since the mixin has no knowledge of the subclass constructor, it
+does not define \method{__init__()} or \method{copy()}.
+\end{classdesc}
+
+
+\section{\module{UserList} ---
+         Class wrapper for list objects}
+
+\declaremodule{standard}{UserList}
+\modulesynopsis{Class wrapper for list objects.}
+
+
+\note{This module is available for backward compatibility only.  If
+you are writing code that does not need to work with versions of
+Python earlier than Python 2.2, please consider subclassing directly
+from the built-in \class{list} type.}
+
+This module defines a class that acts as a wrapper around
+list objects.  It is a useful base class for
+your own list-like classes, which can inherit from
+them and override existing methods or add new ones.  In this way one
+can add new behaviors to lists.
+
+The \module{UserList} module defines the \class{UserList} class:
+
+\begin{classdesc}{UserList}{\optional{list}}
+Class that simulates a list.  The instance's
+contents are kept in a regular list, which is accessible via the
+\member{data} attribute of \class{UserList} instances.  The instance's
+contents are initially set to a copy of \var{list}, defaulting to the
+empty list \code{[]}.  \var{list} can be either a regular Python list,
+or an instance of \class{UserList} (or a subclass).
+\end{classdesc}
+
+In addition to supporting the methods and operations of mutable
+sequences (see section \ref{typesseq}), \class{UserList} instances
+provide the following attribute:
+
+\begin{memberdesc}{data}
+A real Python list object used to store the contents of the
+\class{UserList} class.
+\end{memberdesc}
+
+\strong{Subclassing requirements:}
+Subclasses of \class{UserList} are expect to offer a constructor which
+can be called with either no arguments or one argument.  List
+operations which return a new sequence attempt to create an instance
+of the actual implementation class.  To do so, it assumes that the
+constructor can be called with a single parameter, which is a sequence
+object used as a data source.
+
+If a derived class does not wish to comply with this requirement, all
+of the special methods supported by this class will need to be
+overridden; please consult the sources for information about the
+methods which need to be provided in that case.
+
+\versionchanged[Python versions 1.5.2 and 1.6 also required that the
+                constructor be callable with no parameters, and offer
+                a mutable \member{data} attribute.  Earlier versions
+                of Python did not attempt to create instances of the
+                derived class]{2.0}
+
+
+\section{\module{UserString} ---
+         Class wrapper for string objects}
+
+\declaremodule{standard}{UserString}
+\modulesynopsis{Class wrapper for string objects.}
+\moduleauthor{Peter Funk}{pf at artcom-gmbh.de}
+\sectionauthor{Peter Funk}{pf at artcom-gmbh.de}
+
+\note{This \class{UserString} class from this module is available for
+backward compatibility only.  If you are writing code that does not
+need to work with versions of Python earlier than Python 2.2, please
+consider subclassing directly from the built-in \class{str} type
+instead of using \class{UserString} (there is no built-in equivalent
+to \class{MutableString}).}
+
+This module defines a class that acts as a wrapper around string
+objects.  It is a useful base class for your own string-like classes,
+which can inherit from them and override existing methods or add new
+ones.  In this way one can add new behaviors to strings.
+
+It should be noted that these classes are highly inefficient compared
+to real string or Unicode objects; this is especially the case for
+\class{MutableString}.
+
+The \module{UserString} module defines the following classes:
+
+\begin{classdesc}{UserString}{\optional{sequence}}
+Class that simulates a string or a Unicode string
+object.  The instance's content is kept in a regular string or Unicode
+string object, which is accessible via the \member{data} attribute of
+\class{UserString} instances.  The instance's contents are initially
+set to a copy of \var{sequence}.  \var{sequence} can be either a
+regular Python string or Unicode string, an instance of
+\class{UserString} (or a subclass) or an arbitrary sequence which can
+be converted into a string using the built-in \function{str()} function.
+\end{classdesc}
+
+\begin{classdesc}{MutableString}{\optional{sequence}}
+This class is derived from the \class{UserString} above and redefines
+strings to be \emph{mutable}.  Mutable strings can't be used as
+dictionary keys, because dictionaries require \emph{immutable} objects as
+keys.  The main intention of this class is to serve as an educational
+example for inheritance and necessity to remove (override) the
+\method{__hash__()} method in order to trap attempts to use a
+mutable object as dictionary key, which would be otherwise very
+error prone and hard to track down.
+\end{classdesc}
+
+In addition to supporting the methods and operations of string and
+Unicode objects (see section \ref{string-methods}, ``String
+Methods''), \class{UserString} instances provide the following
+attribute:
+
+\begin{memberdesc}{data}
+A real Python string or Unicode object used to store the content of the
+\class{UserString} class.
+\end{memberdesc}

Added: vendor/Python/current/Doc/lib/libuu.tex
===================================================================
--- vendor/Python/current/Doc/lib/libuu.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libuu.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,58 @@
+\section{\module{uu} ---
+         Encode and decode uuencode files}
+
+\declaremodule{standard}{uu}
+\modulesynopsis{Encode and decode files in uuencode format.}
+\moduleauthor{Lance Ellinghouse}{}
+
+
+This module encodes and decodes files in uuencode format, allowing
+arbitrary binary data to be transferred over ASCII-only connections.
+Wherever a file argument is expected, the methods accept a file-like
+object.  For backwards compatibility, a string containing a pathname
+is also accepted, and the corresponding file will be opened for
+reading and writing; the pathname \code{'-'} is understood to mean the
+standard input or output.  However, this interface is deprecated; it's
+better for the caller to open the file itself, and be sure that, when
+required, the mode is \code{'rb'} or \code{'wb'} on Windows.
+
+This code was contributed by Lance Ellinghouse, and modified by Jack
+Jansen.
+\index{Jansen, Jack}
+\index{Ellinghouse, Lance}
+
+The \module{uu} module defines the following functions:
+
+\begin{funcdesc}{encode}{in_file, out_file\optional{, name\optional{, mode}}}
+  Uuencode file \var{in_file} into file \var{out_file}.  The uuencoded
+  file will have the header specifying \var{name} and \var{mode} as
+  the defaults for the results of decoding the file. The default
+  defaults are taken from \var{in_file}, or \code{'-'} and \code{0666}
+  respectively.
+\end{funcdesc}
+
+\begin{funcdesc}{decode}{in_file\optional{, out_file\optional{, mode\optional{, quiet}}}}
+  This call decodes uuencoded file \var{in_file} placing the result on
+  file \var{out_file}. If \var{out_file} is a pathname, \var{mode} is
+  used to set the permission bits if the file must be
+  created. Defaults for \var{out_file} and \var{mode} are taken from
+  the uuencode header.  However, if the file specified in the header
+  already exists, a \exception{uu.Error} is raised.
+
+  \function{decode()} may print a warning to standard error if the
+  input was produced by an incorrect uuencoder and Python could
+  recover from that error.  Setting \var{quiet} to a true value
+  silences this warning.
+\end{funcdesc}
+
+\begin{excclassdesc}{Error}{}
+  Subclass of \exception{Exception}, this can be raised by
+  \function{uu.decode()} under various situations, such as described
+  above, but also including a badly formatted header, or truncated
+  input file.
+\end{excclassdesc}
+
+\begin{seealso}
+  \seemodule{binascii}{Support module containing \ASCII-to-binary
+                       and binary-to-\ASCII{} conversions.}
+\end{seealso}

Added: vendor/Python/current/Doc/lib/libuuid.tex
===================================================================
--- vendor/Python/current/Doc/lib/libuuid.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libuuid.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,233 @@
+\section{\module{uuid} ---
+         UUID objects according to RFC 4122}
+\declaremodule{builtin}{uuid}
+\modulesynopsis{UUID objects (universally unique identifiers) according to RFC 4122}
+\moduleauthor{Ka-Ping Yee}{ping at zesty.ca}
+\sectionauthor{George Yoshida}{quiver at users.sourceforge.net}
+
+\versionadded{2.5}
+
+This module provides immutable \class{UUID} objects (the \class{UUID} class)
+and the functions \function{uuid1()}, \function{uuid3()},
+\function{uuid4()}, \function{uuid5()} for generating version 1, 3, 4,
+and 5 UUIDs as specified in \rfc{4122}.
+
+If all you want is a unique ID, you should probably call
+\function{uuid1()} or \function{uuid4()}.  Note that \function{uuid1()}
+may compromise privacy since it creates a UUID containing the computer's
+network address.  \function{uuid4()} creates a random UUID.
+
+\begin{classdesc}{UUID}{\optional{hex\optional{, bytes\optional{,
+bytes_le\optional{, fields\optional{, int\optional{, version}}}}}}}
+
+Create a UUID from either a string of 32 hexadecimal digits,
+a string of 16 bytes as the \var{bytes} argument, a string of 16 bytes
+in little-endian order as the \var{bytes_le} argument, a tuple of six
+integers (32-bit \var{time_low}, 16-bit \var{time_mid},
+16-bit \var{time_hi_version},
+8-bit \var{clock_seq_hi_variant}, 8-bit \var{clock_seq_low}, 48-bit \var{node})
+as the \var{fields} argument, or a single 128-bit integer as the \var{int}
+argument.  When a string of hex digits is given, curly braces,
+hyphens, and a URN prefix are all optional.  For example, these
+expressions all yield the same UUID:
+
+\begin{verbatim}
+UUID('{12345678-1234-5678-1234-567812345678}')
+UUID('12345678123456781234567812345678')
+UUID('urn:uuid:12345678-1234-5678-1234-567812345678')
+UUID(bytes='\x12\x34\x56\x78'*4)
+UUID(bytes_le='\x78\x56\x34\x12\x34\x12\x78\x56' +
+              '\x12\x34\x56\x78\x12\x34\x56\x78')
+UUID(fields=(0x12345678, 0x1234, 0x5678, 0x12, 0x34, 0x567812345678))
+UUID(int=0x12345678123456781234567812345678)
+\end{verbatim}
+
+Exactly one of \var{hex}, \var{bytes}, \var{bytes_le}, \var{fields},
+or \var{int} must
+be given.  The \var{version} argument is optional; if given, the
+resulting UUID will have its variant and version number set according to
+RFC 4122, overriding bits in the given \var{hex}, \var{bytes},
+\var{bytes_le}, \var{fields}, or \var{int}.
+
+\end{classdesc}
+
+\class{UUID} instances have these read-only attributes:
+
+\begin{memberdesc}{bytes}
+The UUID as a 16-byte string (containing the six
+integer fields in big-endian byte order).
+\end{memberdesc}
+
+\begin{memberdesc}{bytes_le}
+The UUID as a 16-byte string (with \var{time_low}, \var{time_mid},
+and \var{time_hi_version} in little-endian byte order).
+\end{memberdesc}
+
+\begin{memberdesc}{fields}
+A tuple of the six integer fields of the UUID, which are also available
+as six individual attributes and two derived attributes:
+
+\begin{tableii}{l|l}{member}{Field}{Meaning}
+  \lineii{time_low}{the first 32 bits of the UUID}
+  \lineii{time_mid}{the next 16 bits of the UUID}
+  \lineii{time_hi_version}{the next 16 bits of the UUID}
+  \lineii{clock_seq_hi_variant}{the next 8 bits of the UUID}
+  \lineii{clock_seq_low}{the next 8 bits of the UUID}
+  \lineii{node}{the last 48 bits of the UUID}
+  \lineii{time}{the 60-bit timestamp}
+  \lineii{clock_seq}{the 14-bit sequence number}
+\end{tableii}
+
+
+\end{memberdesc}
+
+\begin{memberdesc}{hex}
+The UUID as a 32-character hexadecimal string.
+\end{memberdesc}
+
+\begin{memberdesc}{int}
+The UUID as a 128-bit integer.
+\end{memberdesc}
+
+\begin{memberdesc}{urn}
+The UUID as a URN as specified in RFC 4122.
+\end{memberdesc}
+
+\begin{memberdesc}{variant}
+The UUID variant, which determines the internal layout of the UUID.
+This will be one of the integer constants
+\constant{RESERVED_NCS},
+\constant{RFC_4122}, \constant{RESERVED_MICROSOFT}, or
+\constant{RESERVED_FUTURE}.
+\end{memberdesc}
+
+\begin{memberdesc}{version}
+The UUID version number (1 through 5, meaningful only
+when the variant is \constant{RFC_4122}).
+\end{memberdesc}
+
+The \module{uuid} module defines the following functions:
+
+\begin{funcdesc}{getnode}{}
+Get the hardware address as a 48-bit positive integer.  The first time this
+runs, it may launch a separate program, which could be quite slow.  If all
+attempts to obtain the hardware address fail, we choose a random 48-bit
+number with its eighth bit set to 1 as recommended in RFC 4122.  "Hardware
+address" means the MAC address of a network interface, and on a machine
+with multiple network interfaces the MAC address of any one of them may
+be returned.
+\end{funcdesc}
+\index{getnode}
+
+\begin{funcdesc}{uuid1}{\optional{node\optional{, clock_seq}}}
+Generate a UUID from a host ID, sequence number, and the current time.
+If \var{node} is not given, \function{getnode()} is used to obtain the
+hardware address.
+If \var{clock_seq} is given, it is used as the sequence number;
+otherwise a random 14-bit sequence number is chosen.
+\end{funcdesc}
+\index{uuid1}
+
+\begin{funcdesc}{uuid3}{namespace, name}
+Generate a UUID based on the MD5 hash
+of a namespace identifier (which is a UUID) and a name (which is a string).
+\end{funcdesc}
+\index{uuid3}
+
+\begin{funcdesc}{uuid4}{}
+Generate a random UUID.
+\end{funcdesc}
+\index{uuid4}
+
+\begin{funcdesc}{uuid5}{namespace, name}
+Generate a UUID based on the SHA-1 hash
+of a namespace identifier (which is a UUID) and a name (which is a string).
+\end{funcdesc}
+\index{uuid5}
+
+The \module{uuid} module defines the following namespace identifiers
+for use with \function{uuid3()} or \function{uuid5()}.
+
+\begin{datadesc}{NAMESPACE_DNS}
+When this namespace is specified,
+the \var{name} string is a fully-qualified domain name.
+\end{datadesc}
+
+\begin{datadesc}{NAMESPACE_URL}
+When this namespace is specified,
+the \var{name} string is a URL.
+\end{datadesc}
+
+\begin{datadesc}{NAMESPACE_OID}
+When this namespace is specified,
+the \var{name} string is an ISO OID.
+\end{datadesc}
+
+\begin{datadesc}{NAMESPACE_X500}
+When this namespace is specified,
+the \var{name} string is an X.500 DN in DER or a text output format.
+\end{datadesc}
+
+The \module{uuid} module defines the following constants
+for the possible values of the \member{variant} attribute:
+
+\begin{datadesc}{RESERVED_NCS}
+Reserved for NCS compatibility.
+\end{datadesc}
+
+\begin{datadesc}{RFC_4122}
+Specifies the UUID layout given in \rfc{4122}.
+\end{datadesc}
+
+\begin{datadesc}{RESERVED_MICROSOFT}
+Reserved for Microsoft compatibility.
+\end{datadesc}
+
+\begin{datadesc}{RESERVED_FUTURE}
+Reserved for future definition.
+\end{datadesc}
+
+
+\begin{seealso}
+  \seerfc{4122}{A Universally Unique IDentifier (UUID) URN Namespace}{
+This specification defines a Uniform Resource Name namespace for UUIDs,
+the internal format of UUIDs, and methods of generating UUIDs.}
+\end{seealso}
+
+\subsection{Example \label{uuid-example}}
+
+Here are some examples of typical usage of the \module{uuid} module:
+\begin{verbatim}
+>>> import uuid
+
+# make a UUID based on the host ID and current time
+>>> uuid.uuid1()
+UUID('a8098c1a-f86e-11da-bd1a-00112444be1e')
+
+# make a UUID using an MD5 hash of a namespace UUID and a name
+>>> uuid.uuid3(uuid.NAMESPACE_DNS, 'python.org')
+UUID('6fa459ea-ee8a-3ca4-894e-db77e160355e')
+
+# make a random UUID
+>>> uuid.uuid4()
+UUID('16fd2706-8baf-433b-82eb-8c7fada847da')
+
+# make a UUID using a SHA-1 hash of a namespace UUID and a name
+>>> uuid.uuid5(uuid.NAMESPACE_DNS, 'python.org')
+UUID('886313e1-3b8a-5372-9b90-0c9aee199e5d')
+
+# make a UUID from a string of hex digits (braces and hyphens ignored)
+>>> x = uuid.UUID('{00010203-0405-0607-0809-0a0b0c0d0e0f}')
+
+# convert a UUID to a string of hex digits in standard form
+>>> str(x)
+'00010203-0405-0607-0809-0a0b0c0d0e0f'
+
+# get the raw 16 bytes of the UUID
+>>> x.bytes
+'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f'
+
+# make a UUID from a 16-byte string
+>>> uuid.UUID(bytes=x.bytes)
+UUID('00010203-0405-0607-0809-0a0b0c0d0e0f')
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/libwarnings.tex
===================================================================
--- vendor/Python/current/Doc/lib/libwarnings.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libwarnings.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,253 @@
+\section{\module{warnings} ---
+         Warning control}
+
+\declaremodule{standard}{warnings}
+\modulesynopsis{Issue warning messages and control their disposition.}
+\index{warnings}
+
+\versionadded{2.1}
+
+Warning messages are typically issued in situations where it is useful
+to alert the user of some condition in a program, where that condition
+(normally) doesn't warrant raising an exception and terminating the
+program.  For example, one might want to issue a warning when a
+program uses an obsolete module.
+
+Python programmers issue warnings by calling the \function{warn()}
+function defined in this module.  (C programmers use
+\cfunction{PyErr_Warn()}; see the
+\citetitle[../api/exceptionHandling.html]{Python/C API Reference
+Manual} for details).
+
+Warning messages are normally written to \code{sys.stderr}, but their
+disposition can be changed flexibly, from ignoring all warnings to
+turning them into exceptions.  The disposition of warnings can vary
+based on the warning category (see below), the text of the warning
+message, and the source location where it is issued.  Repetitions of a
+particular warning for the same source location are typically
+suppressed.
+
+There are two stages in warning control: first, each time a warning is
+issued, a determination is made whether a message should be issued or
+not; next, if a message is to be issued, it is formatted and printed
+using a user-settable hook.
+
+The determination whether to issue a warning message is controlled by
+the warning filter, which is a sequence of matching rules and actions.
+Rules can be added to the filter by calling
+\function{filterwarnings()} and reset to its default state by calling
+\function{resetwarnings()}.
+
+The printing of warning messages is done by calling
+\function{showwarning()}, which may be overridden; the default
+implementation of this function formats the message by calling
+\function{formatwarning()}, which is also available for use by custom
+implementations.
+
+
+\subsection{Warning Categories \label{warning-categories}}
+
+There are a number of built-in exceptions that represent warning
+categories.  This categorization is useful to be able to filter out
+groups of warnings.  The following warnings category classes are
+currently defined:
+
+\begin{tableii}{l|l}{exception}{Class}{Description}
+
+\lineii{Warning}{This is the base class of all warning category
+classes.  It is a subclass of \exception{Exception}.}
+
+\lineii{UserWarning}{The default category for \function{warn()}.}
+
+\lineii{DeprecationWarning}{Base category for warnings about
+deprecated features.}
+
+\lineii{SyntaxWarning}{Base category for warnings about dubious
+syntactic features.}
+
+\lineii{RuntimeWarning}{Base category for warnings about dubious
+runtime features.}
+
+\lineii{FutureWarning}{Base category for warnings about constructs
+that will change semantically in the future.}
+
+\lineii{PendingDeprecationWarning}{Base category for warnings about
+features that will be deprecated in the future (ignored by default).}
+
+\lineii{ImportWarning}{Base category for warnings triggered during the
+process of importing a module (ignored by default).}
+
+\lineii{UnicodeWarning}{Base category for warnings related to Unicode.}
+
+\end{tableii}
+
+While these are technically built-in exceptions, they are documented
+here, because conceptually they belong to the warnings mechanism.
+
+User code can define additional warning categories by subclassing one
+of the standard warning categories.  A warning category must always be
+a subclass of the \exception{Warning} class.
+
+
+\subsection{The Warnings Filter \label{warning-filter}}
+
+The warnings filter controls whether warnings are ignored, displayed,
+or turned into errors (raising an exception).
+
+Conceptually, the warnings filter maintains an ordered list of filter
+specifications; any specific warning is matched against each filter
+specification in the list in turn until a match is found; the match
+determines the disposition of the match.  Each entry is a tuple of the
+form (\var{action}, \var{message}, \var{category}, \var{module},
+\var{lineno}), where:
+
+\begin{itemize}
+
+\item \var{action} is one of the following strings:
+
+    \begin{tableii}{l|l}{code}{Value}{Disposition}
+
+    \lineii{"error"}{turn matching warnings into exceptions}
+
+    \lineii{"ignore"}{never print matching warnings}
+
+    \lineii{"always"}{always print matching warnings}
+
+    \lineii{"default"}{print the first occurrence of matching
+    warnings for each location where the warning is issued}
+
+    \lineii{"module"}{print the first occurrence of matching
+    warnings for each module where the warning is issued}
+
+    \lineii{"once"}{print only the first occurrence of matching
+    warnings, regardless of location}
+
+    \end{tableii}
+
+\item \var{message} is a string containing a regular expression that
+the warning message must match (the match is compiled to always be 
+case-insensitive) 
+
+\item \var{category} is a class (a subclass of \exception{Warning}) of
+      which the warning category must be a subclass in order to match
+
+\item \var{module} is a string containing a regular expression that the module
+      name must match (the match is compiled to be case-sensitive)
+
+\item \var{lineno} is an integer that the line number where the
+      warning occurred must match, or \code{0} to match all line
+      numbers
+
+\end{itemize}
+
+Since the \exception{Warning} class is derived from the built-in
+\exception{Exception} class, to turn a warning into an error we simply
+raise \code{category(message)}.
+
+The warnings filter is initialized by \programopt{-W} options passed
+to the Python interpreter command line.  The interpreter saves the
+arguments for all \programopt{-W} options without interpretation in
+\code{sys.warnoptions}; the \module{warnings} module parses these when
+it is first imported (invalid options are ignored, after printing a
+message to \code{sys.stderr}).
+
+The warnings that are ignored by default may be enabled by passing
+ \programopt{-Wd} to the interpreter. This enables default handling
+for all warnings, including those that are normally ignored by
+default. This is particular useful for enabling ImportWarning when
+debugging problems importing a developed package. ImportWarning can
+also be enabled explicitly in Python code using:
+
+\begin{verbatim}
+    warnings.simplefilter('default', ImportWarning)
+\end{verbatim}
+
+
+\subsection{Available Functions \label{warning-functions}}
+
+\begin{funcdesc}{warn}{message\optional{, category\optional{, stacklevel}}}
+Issue a warning, or maybe ignore it or raise an exception.  The
+\var{category} argument, if given, must be a warning category class
+(see above); it defaults to \exception{UserWarning}.  Alternatively
+\var{message} can be a \exception{Warning} instance, in which case
+\var{category} will be ignored and \code{message.__class__} will be used.
+In this case the message text will be \code{str(message)}. This function
+raises an exception if the particular warning issued is changed
+into an error by the warnings filter see above.  The \var{stacklevel}
+argument can be used by wrapper functions written in Python, like
+this:
+
+\begin{verbatim}
+def deprecation(message):
+    warnings.warn(message, DeprecationWarning, stacklevel=2)
+\end{verbatim}
+
+This makes the warning refer to \function{deprecation()}'s caller,
+rather than to the source of \function{deprecation()} itself (since
+the latter would defeat the purpose of the warning message).
+\end{funcdesc}
+
+\begin{funcdesc}{warn_explicit}{message, category, filename,
+ lineno\optional{, module\optional{, registry\optional{,
+ module_globals}}}}
+This is a low-level interface to the functionality of
+\function{warn()}, passing in explicitly the message, category,
+filename and line number, and optionally the module name and the
+registry (which should be the \code{__warningregistry__} dictionary of
+the module).  The module name defaults to the filename with \code{.py}
+stripped; if no registry is passed, the warning is never suppressed.
+\var{message} must be a string and \var{category} a subclass of
+\exception{Warning} or \var{message} may be a \exception{Warning} instance,
+in which case \var{category} will be ignored.
+
+\var{module_globals}, if supplied, should be the global namespace in use
+by the code for which the warning is issued.  (This argument is used to
+support displaying source for modules found in zipfiles or other
+non-filesystem import sources, and was added in Python 2.5.)
+\end{funcdesc}
+
+\begin{funcdesc}{showwarning}{message, category, filename,
+			     lineno\optional{, file}}
+Write a warning to a file.  The default implementation calls
+\code{formatwarning(\var{message}, \var{category}, \var{filename},
+\var{lineno})} and writes the resulting string to \var{file}, which
+defaults to \code{sys.stderr}.  You may replace this function with an
+alternative implementation by assigning to
+\code{warnings.showwarning}.
+\end{funcdesc}
+
+\begin{funcdesc}{formatwarning}{message, category, filename, lineno}
+Format a warning the standard way.  This returns a string  which may
+contain embedded newlines and ends in a newline.
+\end{funcdesc}
+
+\begin{funcdesc}{filterwarnings}{action\optional{,
+                 message\optional{, category\optional{,
+                 module\optional{, lineno\optional{, append}}}}}}
+Insert an entry into the list of warnings filters.  The entry is
+inserted at the front by default; if \var{append} is true, it is
+inserted at the end.
+This checks the types of the arguments, compiles the message and
+module regular expressions, and inserts them as a tuple in the 
+list of warnings filters.  Entries closer to the front of the list
+override entries later in the list, if both match a particular
+warning.  Omitted arguments default to a value that matches
+everything.
+\end{funcdesc}
+
+\begin{funcdesc}{simplefilter}{action\optional{,
+                 category\optional{,
+                 lineno\optional{, append}}}}
+Insert a simple entry into the list of warnings filters. The meaning
+of the function parameters is as for \function{filterwarnings()}, but
+regular expressions are not needed as the filter inserted always
+matches any message in any module as long as the category and line
+number match.
+\end{funcdesc}
+
+\begin{funcdesc}{resetwarnings}{}
+Reset the warnings filter.  This discards the effect of all previous
+calls to \function{filterwarnings()}, including that of the
+\programopt{-W} command line options and calls to
+\function{simplefilter()}.
+\end{funcdesc}

Added: vendor/Python/current/Doc/lib/libwave.tex
===================================================================
--- vendor/Python/current/Doc/lib/libwave.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libwave.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,169 @@
+% Documentations stolen and LaTeX'ed from comments in file.
+\section{\module{wave} ---
+         Read and write WAV files}
+
+\declaremodule{standard}{wave}
+\sectionauthor{Moshe Zadka}{moshez at zadka.site.co.il}
+\modulesynopsis{Provide an interface to the WAV sound format.}
+
+The \module{wave} module provides a convenient interface to the WAV sound
+format. It does not support compression/decompression, but it does support
+mono/stereo.
+
+The \module{wave} module defines the following function and exception:
+
+\begin{funcdesc}{open}{file\optional{, mode}}
+If \var{file} is a string, open the file by that name, other treat it
+as a seekable file-like object. \var{mode} can be any of
+\begin{description}
+        \item[\code{'r'}, \code{'rb'}] Read only mode.
+        \item[\code{'w'}, \code{'wb'}] Write only mode.
+\end{description}
+Note that it does not allow read/write WAV files.
+
+A \var{mode} of \code{'r'} or \code{'rb'} returns a \class{Wave_read}
+object, while a \var{mode} of \code{'w'} or \code{'wb'} returns
+a \class{Wave_write} object.  If \var{mode} is omitted and a file-like 
+object is passed as \var{file}, \code{\var{file}.mode} is used as the
+default value for \var{mode} (the \character{b} flag is still added if 
+necessary).
+\end{funcdesc}
+
+\begin{funcdesc}{openfp}{file, mode}
+A synonym for \function{open()}, maintained for backwards compatibility.
+\end{funcdesc}
+
+\begin{excdesc}{Error}
+An error raised when something is impossible because it violates the
+WAV specification or hits an implementation deficiency.
+\end{excdesc}
+
+
+\subsection{Wave_read Objects \label{Wave-read-objects}}
+
+Wave_read objects, as returned by \function{open()}, have the
+following methods:
+
+\begin{methoddesc}[Wave_read]{close}{}
+Close the stream, and make the instance unusable. This is
+called automatically on object collection.
+\end{methoddesc}
+
+\begin{methoddesc}[Wave_read]{getnchannels}{}
+Returns number of audio channels (\code{1} for mono, \code{2} for
+stereo).
+\end{methoddesc}
+
+\begin{methoddesc}[Wave_read]{getsampwidth}{}
+Returns sample width in bytes.
+\end{methoddesc}
+
+\begin{methoddesc}[Wave_read]{getframerate}{}
+Returns sampling frequency.
+\end{methoddesc}
+
+\begin{methoddesc}[Wave_read]{getnframes}{}
+Returns number of audio frames.
+\end{methoddesc}
+
+\begin{methoddesc}[Wave_read]{getcomptype}{}
+Returns compression type (\code{'NONE'} is the only supported type).
+\end{methoddesc}
+
+\begin{methoddesc}[Wave_read]{getcompname}{}
+Human-readable version of \method{getcomptype()}.
+Usually \code{'not compressed'} parallels \code{'NONE'}.
+\end{methoddesc}
+
+\begin{methoddesc}[Wave_read]{getparams}{}
+Returns a tuple
+\code{(\var{nchannels}, \var{sampwidth}, \var{framerate},
+\var{nframes}, \var{comptype}, \var{compname})}, equivalent to output
+of the \method{get*()} methods.
+\end{methoddesc}
+
+\begin{methoddesc}[Wave_read]{readframes}{n}
+Reads and returns at most \var{n} frames of audio, as a string of bytes.
+\end{methoddesc}
+
+\begin{methoddesc}[Wave_read]{rewind}{}
+Rewind the file pointer to the beginning of the audio stream.
+\end{methoddesc}
+
+The following two methods are defined for compatibility with the
+\refmodule{aifc} module, and don't do anything interesting.
+
+\begin{methoddesc}[Wave_read]{getmarkers}{}
+Returns \code{None}.
+\end{methoddesc}
+
+\begin{methoddesc}[Wave_read]{getmark}{id}
+Raise an error.
+\end{methoddesc}
+
+The following two methods define a term ``position'' which is compatible
+between them, and is otherwise implementation dependent.
+
+\begin{methoddesc}[Wave_read]{setpos}{pos}
+Set the file pointer to the specified position.
+\end{methoddesc}
+
+\begin{methoddesc}[Wave_read]{tell}{}
+Return current file pointer position.
+\end{methoddesc}
+
+
+\subsection{Wave_write Objects \label{Wave-write-objects}}
+
+Wave_write objects, as returned by \function{open()}, have the
+following methods:
+
+\begin{methoddesc}[Wave_write]{close}{}
+Make sure \var{nframes} is correct, and close the file.
+This method is called upon deletion.
+\end{methoddesc}
+
+\begin{methoddesc}[Wave_write]{setnchannels}{n}
+Set the number of channels.
+\end{methoddesc}
+
+\begin{methoddesc}[Wave_write]{setsampwidth}{n}
+Set the sample width to \var{n} bytes.
+\end{methoddesc}
+
+\begin{methoddesc}[Wave_write]{setframerate}{n}
+Set the frame rate to \var{n}.
+\end{methoddesc}
+
+\begin{methoddesc}[Wave_write]{setnframes}{n}
+Set the number of frames to \var{n}. This will be changed later if
+more frames are written.
+\end{methoddesc}
+
+\begin{methoddesc}[Wave_write]{setcomptype}{type, name}
+Set the compression type and description.
+\end{methoddesc}
+
+\begin{methoddesc}[Wave_write]{setparams}{tuple}
+The \var{tuple} should be \code{(\var{nchannels}, \var{sampwidth},
+\var{framerate}, \var{nframes}, \var{comptype}, \var{compname})}, with
+values valid for the \method{set*()} methods.  Sets all parameters.
+\end{methoddesc}
+
+\begin{methoddesc}[Wave_write]{tell}{}
+Return current position in the file, with the same disclaimer for
+the \method{Wave_read.tell()} and \method{Wave_read.setpos()}
+methods.
+\end{methoddesc}
+
+\begin{methoddesc}[Wave_write]{writeframesraw}{data}
+Write audio frames, without correcting \var{nframes}.
+\end{methoddesc}
+
+\begin{methoddesc}[Wave_write]{writeframes}{data}
+Write audio frames and make sure \var{nframes} is correct.
+\end{methoddesc}
+
+Note that it is invalid to set any parameters after calling
+\method{writeframes()} or \method{writeframesraw()}, and any attempt
+to do so will raise \exception{wave.Error}.

Added: vendor/Python/current/Doc/lib/libweakref.tex
===================================================================
--- vendor/Python/current/Doc/lib/libweakref.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libweakref.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,336 @@
+\section{\module{weakref} ---
+         Weak references}
+
+\declaremodule{extension}{weakref}
+\modulesynopsis{Support for weak references and weak dictionaries.}
+\moduleauthor{Fred L. Drake, Jr.}{fdrake at acm.org}
+\moduleauthor{Neil Schemenauer}{nas at arctrix.com}
+\moduleauthor{Martin von L\"owis}{martin at loewis.home.cs.tu-berlin.de}
+\sectionauthor{Fred L. Drake, Jr.}{fdrake at acm.org}
+
+\versionadded{2.1}
+
+% When making changes to the examples in this file, be sure to update
+% Lib/test/test_weakref.py::libreftest too!
+
+The \module{weakref} module allows the Python programmer to create
+\dfn{weak references} to objects.
+
+In the following, the term \dfn{referent} means the
+object which is referred to by a weak reference.
+
+A weak reference to an object is not enough to keep the object alive:
+when the only remaining references to a referent are weak references,
+garbage collection is free to destroy the referent and reuse its memory
+for something else.  A primary use for weak references is to implement
+caches or mappings holding large objects, where it's desired that a
+large object not be kept alive solely because it appears in a cache or
+mapping.  For example, if you have a number of large binary image objects,
+you may wish to associate a name with each.  If you used a Python
+dictionary to map names to images, or images to names, the image objects
+would remain alive just because they appeared as values or keys in the
+dictionaries.  The \class{WeakKeyDictionary} and
+\class{WeakValueDictionary} classes supplied by the \module{weakref}
+module are an alternative, using weak references to construct mappings
+that don't keep objects alive solely because they appear in the mapping
+objects.  If, for example, an image object is a value in a
+\class{WeakValueDictionary}, then when the last remaining
+references to that image object are the weak references held by weak
+mappings, garbage collection can reclaim the object, and its corresponding
+entries in weak mappings are simply deleted.
+
+\class{WeakKeyDictionary} and \class{WeakValueDictionary} use weak
+references in their implementation, setting up callback functions on
+the weak references that notify the weak dictionaries when a key or value
+has been reclaimed by garbage collection.  Most programs should find that
+using one of these weak dictionary types is all they need -- it's
+not usually necessary to create your own weak references directly.  The
+low-level machinery used by the weak dictionary implementations is exposed
+by the \module{weakref} module for the benefit of advanced uses.
+
+Not all objects can be weakly referenced; those objects which can
+include class instances, functions written in Python (but not in C),
+methods (both bound and unbound), sets, frozensets, file objects,
+generators, type objects, DBcursor objects from the \module{bsddb} module,
+sockets, arrays, deques, and regular expression pattern objects.
+\versionchanged[Added support for files, sockets, arrays, and patterns]{2.4}
+
+Several builtin types such as \class{list} and \class{dict} do not
+directly support weak references but can add support through subclassing:
+
+\begin{verbatim}
+class Dict(dict):
+    pass
+
+obj = Dict(red=1, green=2, blue=3)   # this object is weak referencable
+\end{verbatim}
+
+Extension types can easily be made to support weak references; see
+``\ulink{Weak Reference Support}{../ext/weakref-support.html}'' in
+\citetitle[../ext/ext.html]{Extending and Embedding the Python
+Interpreter}.
+% The referenced section used to appear in this document with the
+% \label weakref-extension.  It would be good to be able to generate a
+% redirect for the corresponding HTML page (weakref-extension.html)
+% for on-line versions of this document.
+
+\begin{classdesc}{ref}{object\optional{, callback}}
+  Return a weak reference to \var{object}.  The original object can be
+  retrieved by calling the reference object if the referent is still
+  alive; if the referent is no longer alive, calling the reference
+  object will cause \constant{None} to be returned.  If \var{callback} is
+  provided and not \constant{None}, and the returned weakref object is
+  still alive, the callback will be called when the object is about to be
+  finalized; the weak reference object will be passed as the only
+  parameter to the callback; the referent will no longer be available.
+
+  It is allowable for many weak references to be constructed for the
+  same object.  Callbacks registered for each weak reference will be
+  called from the most recently registered callback to the oldest
+  registered callback.
+
+  Exceptions raised by the callback will be noted on the standard
+  error output, but cannot be propagated; they are handled in exactly
+  the same way as exceptions raised from an object's
+  \method{__del__()} method.
+
+  Weak references are hashable if the \var{object} is hashable.  They
+  will maintain their hash value even after the \var{object} was
+  deleted.  If \function{hash()} is called the first time only after
+  the \var{object} was deleted, the call will raise
+  \exception{TypeError}.
+
+  Weak references support tests for equality, but not ordering.  If
+  the referents are still alive, two references have the same
+  equality relationship as their referents (regardless of the
+  \var{callback}).  If either referent has been deleted, the
+  references are equal only if the reference objects are the same
+  object.
+
+  \versionchanged[This is now a subclassable type rather than a
+                  factory function; it derives from \class{object}]
+                  {2.4}
+\end{classdesc}
+
+\begin{funcdesc}{proxy}{object\optional{, callback}}
+  Return a proxy to \var{object} which uses a weak reference.  This
+  supports use of the proxy in most contexts instead of requiring the
+  explicit dereferencing used with weak reference objects.  The
+  returned object will have a type of either \code{ProxyType} or
+  \code{CallableProxyType}, depending on whether \var{object} is
+  callable.  Proxy objects are not hashable regardless of the
+  referent; this avoids a number of problems related to their
+  fundamentally mutable nature, and prevent their use as dictionary
+  keys.  \var{callback} is the same as the parameter of the same name
+  to the \function{ref()} function.
+\end{funcdesc}
+
+\begin{funcdesc}{getweakrefcount}{object}
+  Return the number of weak references and proxies which refer to
+  \var{object}.
+\end{funcdesc}
+
+\begin{funcdesc}{getweakrefs}{object}
+  Return a list of all weak reference and proxy objects which refer to
+  \var{object}.
+\end{funcdesc}
+
+\begin{classdesc}{WeakKeyDictionary}{\optional{dict}}
+  Mapping class that references keys weakly.  Entries in the
+  dictionary will be discarded when there is no longer a strong
+  reference to the key.  This can be used to associate additional data
+  with an object owned by other parts of an application without adding
+  attributes to those objects.  This can be especially useful with
+  objects that override attribute accesses.
+
+  \note{Caution:  Because a \class{WeakKeyDictionary} is built on top
+        of a Python dictionary, it must not change size when iterating
+        over it.  This can be difficult to ensure for a
+        \class{WeakKeyDictionary} because actions performed by the
+        program during iteration may cause items in the dictionary
+        to vanish "by magic" (as a side effect of garbage collection).}
+\end{classdesc}
+
+\class{WeakKeyDictionary} objects have the following additional
+methods.  These expose the internal references directly.  The
+references are not guaranteed to be ``live'' at the time they are
+used, so the result of calling the references needs to be checked
+before being used.  This can be used to avoid creating references that
+will cause the garbage collector to keep the keys around longer than
+needed.
+
+\begin{methoddesc}{iterkeyrefs}{}
+  Return an iterator that yields the weak references to the keys.
+  \versionadded{2.5}
+\end{methoddesc}
+
+\begin{methoddesc}{keyrefs}{}
+  Return a list of weak references to the keys.
+  \versionadded{2.5}
+\end{methoddesc}
+
+\begin{classdesc}{WeakValueDictionary}{\optional{dict}}
+  Mapping class that references values weakly.  Entries in the
+  dictionary will be discarded when no strong reference to the value
+  exists any more.
+
+  \note{Caution:  Because a \class{WeakValueDictionary} is built on top
+        of a Python dictionary, it must not change size when iterating
+        over it.  This can be difficult to ensure for a
+        \class{WeakValueDictionary} because actions performed by the
+        program during iteration may cause items in the dictionary
+        to vanish "by magic" (as a side effect of garbage collection).}
+\end{classdesc}
+
+\class{WeakValueDictionary} objects have the following additional
+methods.  These method have the same issues as the
+\method{iterkeyrefs()} and \method{keyrefs()} methods of
+\class{WeakKeyDictionary} objects.
+
+\begin{methoddesc}{itervaluerefs}{}
+  Return an iterator that yields the weak references to the values.
+  \versionadded{2.5}
+\end{methoddesc}
+
+\begin{methoddesc}{valuerefs}{}
+  Return a list of weak references to the values.
+  \versionadded{2.5}
+\end{methoddesc}
+
+\begin{datadesc}{ReferenceType}
+  The type object for weak references objects.
+\end{datadesc}
+
+\begin{datadesc}{ProxyType}
+  The type object for proxies of objects which are not callable.
+\end{datadesc}
+
+\begin{datadesc}{CallableProxyType}
+  The type object for proxies of callable objects.
+\end{datadesc}
+
+\begin{datadesc}{ProxyTypes}
+  Sequence containing all the type objects for proxies.  This can make
+  it simpler to test if an object is a proxy without being dependent
+  on naming both proxy types.
+\end{datadesc}
+
+\begin{excdesc}{ReferenceError}
+  Exception raised when a proxy object is used but the underlying
+  object has been collected.  This is the same as the standard
+  \exception{ReferenceError} exception.
+\end{excdesc}
+
+
+\begin{seealso}
+  \seepep{0205}{Weak References}{The proposal and rationale for this
+                feature, including links to earlier implementations
+                and information about similar features in other
+                languages.}
+\end{seealso}
+
+
+\subsection{Weak Reference Objects
+            \label{weakref-objects}}
+
+Weak reference objects have no attributes or methods, but do allow the
+referent to be obtained, if it still exists, by calling it:
+
+\begin{verbatim}
+>>> import weakref
+>>> class Object:
+...     pass
+...
+>>> o = Object()
+>>> r = weakref.ref(o)
+>>> o2 = r()
+>>> o is o2
+True
+\end{verbatim}
+
+If the referent no longer exists, calling the reference object returns
+\constant{None}:
+
+\begin{verbatim}
+>>> del o, o2
+>>> print r()
+None
+\end{verbatim}
+
+Testing that a weak reference object is still live should be done
+using the expression \code{\var{ref}() is not None}.  Normally,
+application code that needs to use a reference object should follow
+this pattern:
+
+\begin{verbatim}
+# r is a weak reference object
+o = r()
+if o is None:
+    # referent has been garbage collected
+    print "Object has been deallocated; can't frobnicate."
+else:
+    print "Object is still live!"
+    o.do_something_useful()
+\end{verbatim}
+
+Using a separate test for ``liveness'' creates race conditions in
+threaded applications; another thread can cause a weak reference to
+become invalidated before the weak reference is called; the
+idiom shown above is safe in threaded applications as well as
+single-threaded applications.
+
+Specialized versions of \class{ref} objects can be created through
+subclassing.  This is used in the implementation of the
+\class{WeakValueDictionary} to reduce the memory overhead for each
+entry in the mapping.  This may be most useful to associate additional
+information with a reference, but could also be used to insert
+additional processing on calls to retrieve the referent.
+
+This example shows how a subclass of \class{ref} can be used to store
+additional information about an object and affect the value that's
+returned when the referent is accessed:
+
+\begin{verbatim}
+import weakref
+
+class ExtendedRef(weakref.ref):
+    def __init__(self, ob, callback=None, **annotations):
+        super(ExtendedRef, self).__init__(ob, callback)
+        self.__counter = 0
+        for k, v in annotations.iteritems():
+            setattr(self, k, v)
+
+    def __call__(self):
+        """Return a pair containing the referent and the number of
+        times the reference has been called.
+        """
+        ob = super(ExtendedRef, self).__call__()
+        if ob is not None:
+            self.__counter += 1
+            ob = (ob, self.__counter)
+        return ob
+\end{verbatim}
+
+
+\subsection{Example \label{weakref-example}}
+
+This simple example shows how an application can use objects IDs to
+retrieve objects that it has seen before.  The IDs of the objects can
+then be used in other data structures without forcing the objects to
+remain alive, but the objects can still be retrieved by ID if they
+do.
+
+% Example contributed by Tim Peters.
+\begin{verbatim}
+import weakref
+
+_id2obj_dict = weakref.WeakValueDictionary()
+
+def remember(obj):
+    oid = id(obj)
+    _id2obj_dict[oid] = obj
+    return oid
+
+def id2obj(oid):
+    return _id2obj_dict[oid]
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/libwebbrowser.tex
===================================================================
--- vendor/Python/current/Doc/lib/libwebbrowser.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libwebbrowser.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,173 @@
+\section{\module{webbrowser} ---
+         Convenient Web-browser controller}
+
+\declaremodule{standard}{webbrowser}
+\modulesynopsis{Easy-to-use controller for Web browsers.}
+\moduleauthor{Fred L. Drake, Jr.}{fdrake at acm.org}
+\sectionauthor{Fred L. Drake, Jr.}{fdrake at acm.org}
+
+The \module{webbrowser} module provides a high-level interface to
+allow displaying Web-based documents to users. Under most
+circumstances, simply calling the \function{open()} function from this
+module will do the right thing.
+
+Under \UNIX{}, graphical browsers are preferred under X11, but text-mode
+browsers will be used if graphical browsers are not available or an X11
+display isn't available.  If text-mode browsers are used, the calling
+process will block until the user exits the browser.
+
+If the environment variable \envvar{BROWSER} exists, it
+is interpreted to override the platform default list of browsers, as a
+os.pathsep-separated list of browsers to try in order.  When the value of
+a list part contains the string \code{\%s}, then it is 
+interpreted as a literal browser command line to be used with the argument URL
+substituted for \code{\%s}; if the part does not contain
+\code{\%s}, it is simply interpreted as the name of the browser to
+launch.
+
+For non-\UNIX{} platforms, or when a remote browser is available on
+\UNIX{}, the controlling process will not wait for the user to finish
+with the browser, but allow the remote browser to maintain its own
+windows on the display.  If remote browsers are not available on \UNIX{},
+the controlling process will launch a new browser and wait.
+
+The script \program{webbrowser} can be used as a command-line interface
+for the module. It accepts an URL as the argument. It accepts the following
+optional parameters: \programopt{-n} opens the URL in a new browser window,
+if possible; \programopt{-t} opens the URL in a new browser page ("tab"). The
+options are, naturally, mutually exclusive.
+
+The following exception is defined:
+
+\begin{excdesc}{Error}
+  Exception raised when a browser control error occurs.
+\end{excdesc}
+
+The following functions are defined:
+
+\begin{funcdesc}{open}{url\optional{, new=0\optional{, autoraise=1}}}
+  Display \var{url} using the default browser. If \var{new} is 0, the
+  \var{url} is opened in the same browser window.  If \var{new} is 1,
+  a new browser window is opened if possible.  If \var{new} is 2,
+  a new browser page ("tab") is opened if possible.  If \var{autoraise} is
+  true, the window is raised if possible (note that under many window
+  managers this will occur regardless of the setting of this variable).
+\versionchanged[\var{new} can now be 2]{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{open_new}{url}
+  Open \var{url} in a new window of the default browser, if possible,
+  otherwise, open \var{url} in the only browser window.
+\end{funcdesc}
+
+\begin{funcdesc}{open_new_tab}{url}
+  Open \var{url} in a new page ("tab") of the default browser, if possible,
+  otherwise equivalent to \function{open_new}.
+\versionadded{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{get}{\optional{name}}
+  Return a controller object for the browser type \var{name}.  If
+  \var{name} is empty, return a controller for a default browser
+  appropriate to the caller's environment.
+\end{funcdesc}
+
+\begin{funcdesc}{register}{name, constructor\optional{, instance}}
+  Register the browser type \var{name}.  Once a browser type is
+  registered, the \function{get()} function can return a controller
+  for that browser type.  If \var{instance} is not provided, or is
+  \code{None}, \var{constructor} will be called without parameters to
+  create an instance when needed.  If \var{instance} is provided,
+  \var{constructor} will never be called, and may be \code{None}.
+
+  This entry point is only useful if you plan to either set the
+  \envvar{BROWSER} variable or call \function{get} with a nonempty
+  argument matching the name of a handler you declare.
+\end{funcdesc}
+
+A number of browser types are predefined.  This table gives the type
+names that may be passed to the \function{get()} function and the
+corresponding instantiations for the controller classes, all defined
+in this module.
+
+\begin{tableiii}{l|l|c}{code}{Type Name}{Class Name}{Notes}
+  \lineiii{'mozilla'}{\class{Mozilla('mozilla')}}{}
+  \lineiii{'firefox'}{\class{Mozilla('mozilla')}}{}
+  \lineiii{'netscape'}{\class{Mozilla('netscape')}}{}
+  \lineiii{'galeon'}{\class{Galeon('galeon')}}{}
+  \lineiii{'epiphany'}{\class{Galeon('epiphany')}}{}
+  \lineiii{'skipstone'}{\class{BackgroundBrowser('skipstone')}}{}
+  \lineiii{'kfmclient'}{\class{Konqueror()}}{(1)}
+  \lineiii{'konqueror'}{\class{Konqueror()}}{(1)}
+  \lineiii{'kfm'}{\class{Konqueror()}}{(1)}
+  \lineiii{'mosaic'}{\class{BackgroundBrowser('mosaic')}}{}
+  \lineiii{'opera'}{\class{Opera()}}{}
+  \lineiii{'grail'}{\class{Grail()}}{}
+  \lineiii{'links'}{\class{GenericBrowser('links')}}{}
+  \lineiii{'elinks'}{\class{Elinks('elinks')}}{}
+  \lineiii{'lynx'}{\class{GenericBrowser('lynx')}}{}
+  \lineiii{'w3m'}{\class{GenericBrowser('w3m')}}{}
+  \lineiii{'windows-default'}{\class{WindowsDefault}}{(2)}
+  \lineiii{'internet-config'}{\class{InternetConfig}}{(3)}
+  \lineiii{'macosx'}{\class{MacOSX('default')}}{(4)}
+\end{tableiii}
+
+\noindent
+Notes:
+
+\begin{description}
+\item[(1)]
+``Konqueror'' is the file manager for the KDE desktop environment for
+\UNIX{}, and only makes sense to use if KDE is running.  Some way of
+reliably detecting KDE would be nice; the \envvar{KDEDIR} variable is
+not sufficient.  Note also that the name ``kfm'' is used even when
+using the \program{konqueror} command with KDE 2 --- the
+implementation selects the best strategy for running Konqueror.
+
+\item[(2)]
+Only on Windows platforms.
+
+\item[(3)]
+Only on MacOS platforms; requires the standard MacPython \module{ic}
+module, described in the \citetitle[../mac/module-ic.html]{Macintosh
+Library Modules} manual.
+
+\item[(4)]
+Only on MacOS X platform.
+\end{description}
+
+Here are some simple examples:
+
+\begin{verbatim}
+url = 'http://www.python.org'
+
+# Open URL in a new tab, if a browser window is already open. 
+webbrowser.open_new_tab(url + '/doc')
+
+# Open URL in new window, raising the window if possible.
+webbrowser.open_new(url)
+\end{verbatim}
+
+
+\subsection{Browser Controller Objects \label{browser-controllers}}
+
+Browser controllers provide two methods which parallel two of the
+module-level convenience functions:
+
+\begin{funcdesc}{open}{url\optional{, new\optional{, autoraise=1}}}
+  Display \var{url} using the browser handled by this controller.
+  If \var{new} is 1, a new browser window is opened if possible.
+  If \var{new} is 2, a new browser page ("tab") is opened if possible.
+\end{funcdesc}
+
+\begin{funcdesc}{open_new}{url}
+  Open \var{url} in a new window of the browser handled by this
+  controller, if possible, otherwise, open \var{url} in the only
+  browser window.  Alias \function{open_new}.
+\end{funcdesc}
+
+\begin{funcdesc}{open_new_tab}{url}
+  Open \var{url} in a new page ("tab") of the browser handled by this
+  controller, if possible, otherwise equivalent to \function{open_new}.
+\versionadded{2.5}
+\end{funcdesc}

Added: vendor/Python/current/Doc/lib/libwhichdb.tex
===================================================================
--- vendor/Python/current/Doc/lib/libwhichdb.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libwhichdb.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,20 @@
+\section{\module{whichdb} ---
+         Guess which DBM module created a database}
+
+\declaremodule{standard}{whichdb}
+\modulesynopsis{Guess which DBM-style module created a given database.}
+
+
+The single function in this module attempts to guess which of the
+several simple database modules available--\refmodule{dbm},
+\refmodule{gdbm}, or \refmodule{dbhash}--should be used to open a
+given file.
+
+\begin{funcdesc}{whichdb}{filename}
+Returns one of the following values: \code{None} if the file can't be
+opened because it's unreadable or doesn't exist; the empty string
+(\code{''}) if the file's format can't be guessed; or a string
+containing the required module name, such as \code{'dbm'} or
+\code{'gdbm'}.
+\end{funcdesc}
+

Added: vendor/Python/current/Doc/lib/libwinreg.tex
===================================================================
--- vendor/Python/current/Doc/lib/libwinreg.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libwinreg.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,414 @@
+\section{\module{_winreg} --
+         Windows registry access}
+
+\declaremodule[-winreg]{extension}{_winreg}
+  \platform{Windows}
+\modulesynopsis{Routines and objects for manipulating the Windows registry.}
+\sectionauthor{Mark Hammond}{MarkH at ActiveState.com}
+
+\versionadded{2.0}
+
+These functions expose the Windows registry API to Python.  Instead of
+using an integer as the registry handle, a handle object is used to
+ensure that the handles are closed correctly, even if the programmer
+neglects to explicitly close them.
+
+This module exposes a very low-level interface to the Windows
+registry; it is expected that in the future a new \code{winreg} 
+module will be created offering a higher-level interface to the
+registry API.
+
+This module offers the following functions:
+
+
+\begin{funcdesc}{CloseKey}{hkey}
+ Closes a previously opened registry key.
+ The hkey argument specifies a previously opened key.
+
+ Note that if \var{hkey} is not closed using this method (or via
+ \method{handle.Close()}), it is closed when the \var{hkey} object
+ is destroyed by Python.
+\end{funcdesc}
+
+
+\begin{funcdesc}{ConnectRegistry}{computer_name, key}
+  Establishes a connection to a predefined registry handle on 
+  another computer, and returns a \dfn{handle object}
+
+ \var{computer_name} is the name of the remote computer, of the 
+ form \code{r"\e\e computername"}.  If \code{None}, the local computer
+ is used.
+ 
+ \var{key} is the predefined handle to connect to.
+
+ The return value is the handle of the opened key.
+ If the function fails, an \exception{EnvironmentError} exception is 
+ raised.
+\end{funcdesc}
+
+
+\begin{funcdesc}{CreateKey}{key, sub_key}
+ Creates or opens the specified key, returning a \dfn{handle object}
+ 
+ \var{key} is an already open key, or one of the predefined 
+ \constant{HKEY_*} constants.
+ 
+ \var{sub_key} is a string that names the key this method opens 
+ or creates.
+ 
+ If \var{key} is one of the predefined keys, \var{sub_key} may 
+ be \code{None}. In that case, the handle returned is the same key handle 
+ passed in to the function.
+
+ If the key already exists, this function opens the existing key.
+
+ The return value is the handle of the opened key.
+ If the function fails, an \exception{EnvironmentError} exception is 
+ raised.
+\end{funcdesc}
+
+\begin{funcdesc}{DeleteKey}{key, sub_key}
+ Deletes the specified key.
+
+ \var{key} is an already open key, or any one of the predefined 
+ \constant{HKEY_*} constants.
+ 
+ \var{sub_key} is a string that must be a subkey of the key 
+ identified by the \var{key} parameter.  This value must not be 
+ \code{None}, and the key may not have subkeys.
+
+ \emph{This method can not delete keys with subkeys.}
+
+ If the method succeeds, the entire key, including all of its values,
+ is removed.  If the method fails, an \exception{EnvironmentError} 
+ exception is raised.
+\end{funcdesc}
+
+
+\begin{funcdesc}{DeleteValue}{key, value}
+  Removes a named value from a registry key.
+  
+ \var{key} is an already open key, or one of the predefined 
+ \constant{HKEY_*} constants.
+  
+ \var{value} is a string that identifies the value to remove.
+\end{funcdesc}
+
+
+\begin{funcdesc}{EnumKey}{key, index}
+  Enumerates subkeys of an open registry key, returning a string.
+
+ \var{key} is an already open key, or any one of the predefined 
+ \constant{HKEY_*} constants.
+
+ \var{index} is an integer that identifies the index of the key to 
+ retrieve.
+
+ The function retrieves the name of one subkey each time it 
+ is called.  It is typically called repeatedly until an 
+ \exception{EnvironmentError} exception 
+ is raised, indicating, no more values are available.
+\end{funcdesc}
+
+
+\begin{funcdesc}{EnumValue}{key, index}
+  Enumerates values of an open registry key, returning a tuple.
+  
+ \var{key} is an already open key, or any one of the predefined 
+ \constant{HKEY_*} constants.
+ 
+ \var{index} is an integer that identifies the index of the value 
+ to retrieve.
+ 
+ The function retrieves the name of one subkey each time it is 
+ called. It is typically called repeatedly, until an 
+ \exception{EnvironmentError} exception is raised, indicating 
+ no more values.
+ 
+ The result is a tuple of 3 items:
+
+ \begin{tableii}{c|p{3in}}{code}{Index}{Meaning}
+   \lineii{0}{A string that identifies the value name}
+   \lineii{1}{An object that holds the value data, and whose
+              type depends on the underlying registry type}
+   \lineii{2}{An integer that identifies the type of the value data}
+ \end{tableii}
+
+\end{funcdesc}
+
+
+\begin{funcdesc}{FlushKey}{key}
+  Writes all the attributes of a key to the registry.
+
+ \var{key} is an already open key, or one of the predefined 
+ \constant{HKEY_*} constants.
+
+ It is not necessary to call RegFlushKey to change a key.
+ Registry changes are flushed to disk by the registry using its lazy 
+ flusher.  Registry changes are also flushed to disk at system 
+ shutdown.  Unlike \function{CloseKey()}, the \function{FlushKey()} method 
+ returns only when all the data has been written to the registry.
+ An application should only call \function{FlushKey()} if it requires absolute 
+ certainty that registry changes are on disk.
+ 
+ \emph{If you don't know whether a \function{FlushKey()} call is required, it 
+ probably isn't.}
+ 
+\end{funcdesc}
+
+
+\begin{funcdesc}{RegLoadKey}{key, sub_key, file_name}
+ Creates a subkey under the specified key and stores registration 
+ information from a specified file into that subkey.
+
+ \var{key} is an already open key, or any of the predefined
+ \constant{HKEY_*} constants.
+ 
+ \var{sub_key} is a string that identifies the sub_key to load.
+ 
+ \var {file_name} is the name of the file to load registry data from.
+  This file must have been created with the \function{SaveKey()} function.
+  Under the file allocation table (FAT) file system, the filename may not
+  have an extension.
+
+ A call to LoadKey() fails if the calling process does not have the
+ \constant{SE_RESTORE_PRIVILEGE} privilege. Note that privileges
+ are different than permissions - see the Win32 documentation for
+ more details.
+
+ If \var{key} is a handle returned by \function{ConnectRegistry()}, 
+ then the path specified in \var{fileName} is relative to the 
+ remote computer.
+
+ The Win32 documentation implies \var{key} must be in the 
+ \constant{HKEY_USER} or \constant{HKEY_LOCAL_MACHINE} tree.
+ This may or may not be true.
+\end{funcdesc}
+
+
+\begin{funcdesc}{OpenKey}{key, sub_key\optional{, res\code{ = 0}}\optional{, sam\code{ = \constant{KEY_READ}}}}
+  Opens the specified key, returning a \dfn{handle object}
+
+ \var{key} is an already open key, or any one of the predefined
+ \constant{HKEY_*} constants.
+
+ \var{sub_key} is a string that identifies the sub_key to open.
+ 
+ \var{res} is a reserved integer, and must be zero.  The default is zero.
+ 
+ \var{sam} is an integer that specifies an access mask that describes 
+ the desired security access for the key.  Default is \constant{KEY_READ}
+ 
+ The result is a new handle to the specified key.
+ 
+ If the function fails, \exception{EnvironmentError} is raised.
+\end{funcdesc}
+
+
+\begin{funcdesc}{OpenKeyEx}{}
+  The functionality of \function{OpenKeyEx()} is provided via
+  \function{OpenKey()}, by the use of default arguments.
+\end{funcdesc}
+
+
+\begin{funcdesc}{QueryInfoKey}{key}
+ Returns information about a key, as a tuple.
+
+ \var{key} is an already open key, or one of the predefined 
+ \constant{HKEY_*} constants.
+
+ The result is a tuple of 3 items:
+
+ \begin{tableii}{c|p{3in}}{code}{Index}{Meaning}
+   \lineii{0}{An integer giving the number of sub keys this key has.}
+   \lineii{1}{An integer giving the number of values this key has.}
+   \lineii{2}{A long integer giving when the key was last modified (if
+              available) as 100's of nanoseconds since Jan 1, 1600.}
+ \end{tableii}
+\end{funcdesc}
+
+
+\begin{funcdesc}{QueryValue}{key, sub_key}
+ Retrieves the unnamed value for a key, as a string
+
+ \var{key} is an already open key, or one of the predefined 
+ \constant{HKEY_*} constants.
+
+ \var{sub_key} is a string that holds the name of the subkey with which 
+ the value is associated.  If this parameter is \code{None} or empty, the 
+ function retrieves the value set by the \function{SetValue()} method 
+ for the key identified by \var{key}.
+
+ Values in the registry have name, type, and data components. This 
+ method retrieves the data for a key's first value that has a NULL name.
+ But the underlying API call doesn't return the type, Lame Lame Lame,
+ DO NOT USE THIS!!!
+\end{funcdesc}
+
+
+\begin{funcdesc}{QueryValueEx}{key, value_name}
+  Retrieves the type and data for a specified value name associated with 
+  an open registry key.
+  
+ \var{key} is an already open key, or one of the predefined 
+ \constant{HKEY_*} constants.
+
+ \var{value_name} is a string indicating the value to query.
+
+ The result is a tuple of 2 items:
+
+ \begin{tableii}{c|p{3in}}{code}{Index}{Meaning}
+   \lineii{0}{The value of the registry item.}
+   \lineii{1}{An integer giving the registry type for this value.}
+ \end{tableii}
+\end{funcdesc}
+
+
+\begin{funcdesc}{SaveKey}{key, file_name}
+  Saves the specified key, and all its subkeys to the specified file.
+
+ \var{key} is an already open key, or one of the predefined 
+ \constant{HKEY_*} constants.
+
+ \var{file_name} is the name of the file to save registry data to.
+  This file cannot already exist. If this filename includes an extension,
+  it cannot be used on file allocation table (FAT) file systems by the
+  \method{LoadKey()}, \method{ReplaceKey()} or 
+  \method{RestoreKey()} methods.
+
+ If \var{key} represents a key on a remote computer, the path 
+ described by \var{file_name} is relative to the remote computer.
+ The caller of this method must possess the \constant{SeBackupPrivilege} 
+ security privilege.  Note that privileges are different than permissions 
+ - see the Win32 documentation for more details.
+ 
+ This function passes NULL for \var{security_attributes} to the API.
+\end{funcdesc}
+
+
+\begin{funcdesc}{SetValue}{key, sub_key, type, value}
+ Associates a value with a specified key.
+ 
+ \var{key} is an already open key, or one of the predefined 
+ \constant{HKEY_*} constants.
+
+ \var{sub_key} is a string that names the subkey with which the value 
+ is associated.
+ 
+ \var{type} is an integer that specifies the type of the data.
+ Currently this must be \constant{REG_SZ}, meaning only strings are
+ supported.  Use the \function{SetValueEx()} function for support for
+ other data types.
+ 
+ \var{value} is a string that specifies the new value.
+
+ If the key specified by the \var{sub_key} parameter does not exist,
+ the SetValue function creates it.
+
+ Value lengths are limited by available memory. Long values (more than
+ 2048 bytes) should be stored as files with the filenames stored in
+ the configuration registry.  This helps the registry perform
+ efficiently.
+
+ The key identified by the \var{key} parameter must have been 
+ opened with \constant{KEY_SET_VALUE} access.
+\end{funcdesc}
+
+
+\begin{funcdesc}{SetValueEx}{key, value_name, reserved, type, value}
+ Stores data in the value field of an open registry key.
+
+ \var{key} is an already open key, or one of the predefined 
+ \constant{HKEY_*} constants.
+
+ \var{sub_key} is a string that names the subkey with which the 
+ value is associated.
+
+ \var{type} is an integer that specifies the type of the data.  
+ This should be one of the following constants defined in this module:
+
+ \begin{tableii}{l|p{3in}}{constant}{Constant}{Meaning}
+   \lineii{REG_BINARY}{Binary data in any form.}
+   \lineii{REG_DWORD}{A 32-bit number.}
+   \lineii{REG_DWORD_LITTLE_ENDIAN}{A 32-bit number in little-endian format.}
+   \lineii{REG_DWORD_BIG_ENDIAN}{A 32-bit number in big-endian format.}
+   \lineii{REG_EXPAND_SZ}{Null-terminated string containing references
+                          to environment variables (\samp{\%PATH\%}).}
+   \lineii{REG_LINK}{A Unicode symbolic link.}
+   \lineii{REG_MULTI_SZ}{A sequence of null-terminated strings, 
+	terminated by two null characters.  (Python handles 
+	this termination automatically.)}
+   \lineii{REG_NONE}{No defined value type.}
+   \lineii{REG_RESOURCE_LIST}{A device-driver resource list.}
+   \lineii{REG_SZ}{A null-terminated string.}
+ \end{tableii}
+
+ \var{reserved} can be anything - zero is always passed to the 
+ API.
+
+ \var{value} is a string that specifies the new value.
+
+ This method can also set additional value and type information for the
+ specified key.  The key identified by the key parameter must have been
+ opened with \constant{KEY_SET_VALUE} access.
+
+ To open the key, use the \function{CreateKeyEx()} or 
+ \function{OpenKey()} methods.
+
+ Value lengths are limited by available memory. Long values (more than
+ 2048 bytes) should be stored as files with the filenames stored in
+ the configuration registry.  This helps the registry perform efficiently.
+\end{funcdesc}
+
+
+
+\subsection{Registry Handle Objects \label{handle-object}}
+
+ This object wraps a Windows HKEY object, automatically closing it when
+ the object is destroyed.  To guarantee cleanup, you can call either
+ the \method{Close()} method on the object, or the 
+ \function{CloseKey()} function.
+
+ All registry functions in this module return one of these objects.
+
+ All registry functions in this module which accept a handle object 
+ also accept an integer, however, use of the handle object is 
+ encouraged.
+ 
+ Handle objects provide semantics for \method{__nonzero__()} - thus
+\begin{verbatim}
+    if handle:
+        print "Yes"
+\end{verbatim}
+ will print \code{Yes} if the handle is currently valid (has not been
+ closed or detached).
+
+ The object also support comparison semantics, so handle
+ objects will compare true if they both reference the same
+ underlying Windows handle value.
+
+ Handle objects can be converted to an integer (e.g., using the
+ builtin \function{int()} function), in which case the underlying
+ Windows handle value is returned.  You can also use the 
+ \method{Detach()} method to return the integer handle, and
+ also disconnect the Windows handle from the handle object.
+
+\begin{methoddesc}{Close}{}
+  Closes the underlying Windows handle.
+
+  If the handle is already closed, no error is raised.
+\end{methoddesc}
+
+
+\begin{methoddesc}{Detach}{}
+  Detaches the Windows handle from the handle object.
+
+ The result is an integer (or long on 64 bit Windows) that holds
+ the value of the handle before it is detached.  If the
+ handle is already detached or closed, this will return zero.
+
+ After calling this function, the handle is effectively invalidated,
+ but the handle is not closed.  You would call this function when 
+ you need the underlying Win32 handle to exist beyond the lifetime 
+ of the handle object.
+\end{methoddesc}

Added: vendor/Python/current/Doc/lib/libwinsound.tex
===================================================================
--- vendor/Python/current/Doc/lib/libwinsound.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libwinsound.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,142 @@
+\section{\module{winsound} ---
+         Sound-playing interface for Windows}
+
+\declaremodule{builtin}{winsound}
+  \platform{Windows}
+\modulesynopsis{Access to the sound-playing machinery for Windows.}
+\moduleauthor{Toby Dickenson}{htrd90 at zepler.org}
+\sectionauthor{Fred L. Drake, Jr.}{fdrake at acm.org}
+
+\versionadded{1.5.2}
+
+The \module{winsound} module provides access to the basic
+sound-playing machinery provided by Windows platforms.  It includes
+functions and several constants.
+
+
+\begin{funcdesc}{Beep}{frequency, duration}
+  Beep the PC's speaker.
+  The \var{frequency} parameter specifies frequency, in hertz, of the
+  sound, and must be in the range 37 through 32,767.
+  The \var{duration} parameter specifies the number of milliseconds the
+  sound should last.  If the system is not
+  able to beep the speaker, \exception{RuntimeError} is raised.
+  \note{Under Windows 95 and 98, the Windows \cfunction{Beep()}
+  function exists but is useless (it ignores its arguments).  In that
+  case Python simulates it via direct port manipulation (added in version
+  2.1).  It's unknown whether that will work on all systems.}
+  \versionadded{1.6}
+\end{funcdesc}
+
+\begin{funcdesc}{PlaySound}{sound, flags}
+  Call the underlying \cfunction{PlaySound()} function from the
+  Platform API.  The \var{sound} parameter may be a filename, audio
+  data as a string, or \code{None}.  Its interpretation depends on the
+  value of \var{flags}, which can be a bit-wise ORed combination of
+  the constants described below.  If the system indicates an error,
+  \exception{RuntimeError} is raised.
+\end{funcdesc}
+
+\begin{funcdesc}{MessageBeep}{\optional{type=\code{MB_OK}}}
+  Call the underlying \cfunction{MessageBeep()} function from the
+  Platform API.  This plays a sound as specified in the registry.  The
+  \var{type} argument specifies which sound to play; possible values
+  are \code{-1}, \code{MB_ICONASTERISK}, \code{MB_ICONEXCLAMATION},
+  \code{MB_ICONHAND}, \code{MB_ICONQUESTION}, and \code{MB_OK}, all
+  described below.  The value \code{-1} produces a ``simple beep'';
+  this is the final fallback if a sound cannot be played otherwise.
+  \versionadded{2.3}
+\end{funcdesc}
+
+\begin{datadesc}{SND_FILENAME}
+  The \var{sound} parameter is the name of a WAV file.
+  Do not use with \constant{SND_ALIAS}.
+\end{datadesc}
+
+\begin{datadesc}{SND_ALIAS}
+  The \var{sound} parameter is a sound association name from the
+  registry.  If the registry contains no such name, play the system
+  default sound unless \constant{SND_NODEFAULT} is also specified.
+  If no default sound is registered, raise \exception{RuntimeError}.
+  Do not use with \constant{SND_FILENAME}.
+
+  All Win32 systems support at least the following; most systems support
+  many more:
+
+\begin{tableii}{l|l}{code}
+               {\function{PlaySound()} \var{name}}
+               {Corresponding Control Panel Sound name}
+  \lineii{'SystemAsterisk'}   {Asterisk}
+  \lineii{'SystemExclamation'}{Exclamation}
+  \lineii{'SystemExit'}       {Exit Windows}
+  \lineii{'SystemHand'}       {Critical Stop}
+  \lineii{'SystemQuestion'}   {Question}
+\end{tableii}
+
+  For example:
+
+\begin{verbatim}
+import winsound
+# Play Windows exit sound.
+winsound.PlaySound("SystemExit", winsound.SND_ALIAS)
+
+# Probably play Windows default sound, if any is registered (because
+# "*" probably isn't the registered name of any sound).
+winsound.PlaySound("*", winsound.SND_ALIAS)
+\end{verbatim}
+\end{datadesc}
+
+\begin{datadesc}{SND_LOOP}
+  Play the sound repeatedly.  The \constant{SND_ASYNC} flag must also
+  be used to avoid blocking.  Cannot be used with \constant{SND_MEMORY}.
+\end{datadesc}
+
+\begin{datadesc}{SND_MEMORY}
+  The \var{sound} parameter to \function{PlaySound()} is a memory
+  image of a WAV file, as a string.
+
+  \note{This module does not support playing from a memory
+  image asynchronously, so a combination of this flag and
+  \constant{SND_ASYNC} will raise \exception{RuntimeError}.}
+\end{datadesc}
+
+\begin{datadesc}{SND_PURGE}
+  Stop playing all instances of the specified sound.
+\end{datadesc}
+
+\begin{datadesc}{SND_ASYNC}
+  Return immediately, allowing sounds to play asynchronously.
+\end{datadesc}
+
+\begin{datadesc}{SND_NODEFAULT}
+  If the specified sound cannot be found, do not play the system default
+  sound.
+\end{datadesc}
+
+\begin{datadesc}{SND_NOSTOP}
+  Do not interrupt sounds currently playing.
+\end{datadesc}
+
+\begin{datadesc}{SND_NOWAIT}
+  Return immediately if the sound driver is busy.
+\end{datadesc}
+
+\begin{datadesc}{MB_ICONASTERISK}
+  Play the \code{SystemDefault} sound.
+\end{datadesc}
+
+\begin{datadesc}{MB_ICONEXCLAMATION}
+  Play the \code{SystemExclamation} sound.
+\end{datadesc}
+
+\begin{datadesc}{MB_ICONHAND}
+  Play the \code{SystemHand} sound.
+\end{datadesc}
+
+\begin{datadesc}{MB_ICONQUESTION}
+  Play the \code{SystemQuestion} sound.
+\end{datadesc}
+
+\begin{datadesc}{MB_OK}
+  Play the \code{SystemDefault} sound.
+\end{datadesc}

Added: vendor/Python/current/Doc/lib/libwsgiref.tex
===================================================================
--- vendor/Python/current/Doc/lib/libwsgiref.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libwsgiref.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,782 @@
+\section{\module{wsgiref} --- WSGI Utilities and Reference
+Implementation}
+\declaremodule{}{wsgiref}
+\moduleauthor{Phillip J. Eby}{pje at telecommunity.com}
+\sectionauthor{Phillip J. Eby}{pje at telecommunity.com}
+\modulesynopsis{WSGI Utilities and Reference Implementation}
+
+\versionadded{2.5}
+
+The Web Server Gateway Interface (WSGI) is a standard interface
+between web server software and web applications written in Python.
+Having a standard interface makes it easy to use an application
+that supports WSGI with a number of different web servers.
+
+Only authors of web servers and programming frameworks need to know
+every detail and corner case of the WSGI design.  You don't need to
+understand every detail of WSGI just to install a WSGI application or
+to write a web application using an existing framework.
+
+\module{wsgiref} is a reference implementation of the WSGI specification
+that can be used to add WSGI support to a web server or framework.  It
+provides utilities for manipulating WSGI environment variables and
+response headers, base classes for implementing WSGI servers, a demo
+HTTP server that serves WSGI applications, and a validation tool that
+checks WSGI servers and applications for conformance to the
+WSGI specification (\pep{333}).
+
+% XXX If you're just trying to write a web application...
+
+See \url{http://www.wsgi.org} for more information about WSGI,
+and links to tutorials and other resources.
+
+
+
+
+
+
+
+
+
+
+
+
+
+\subsection{\module{wsgiref.util} -- WSGI environment utilities}
+\declaremodule{}{wsgiref.util}
+
+This module provides a variety of utility functions for working with
+WSGI environments.  A WSGI environment is a dictionary containing
+HTTP request variables as described in \pep{333}.  All of the functions
+taking an \var{environ} parameter expect a WSGI-compliant dictionary to
+be supplied; please see \pep{333} for a detailed specification.
+
+\begin{funcdesc}{guess_scheme}{environ}
+Return a guess for whether \code{wsgi.url_scheme} should be ``http'' or
+``https'', by checking for a \code{HTTPS} environment variable in the
+\var{environ} dictionary.  The return value is a string.
+
+This function is useful when creating a gateway that wraps CGI or a
+CGI-like protocol such as FastCGI.  Typically, servers providing such
+protocols will include a \code{HTTPS} variable with a value of ``1''
+``yes'', or ``on'' when a request is received via SSL.  So, this
+function returns ``https'' if such a value is found, and ``http''
+otherwise.
+\end{funcdesc}
+
+\begin{funcdesc}{request_uri}{environ \optional{, include_query=1}}
+Return the full request URI, optionally including the query string,
+using the algorithm found in the ``URL Reconstruction'' section of
+\pep{333}.  If \var{include_query} is false, the query string is
+not included in the resulting URI.
+\end{funcdesc}
+
+\begin{funcdesc}{application_uri}{environ}
+Similar to \function{request_uri}, except that the \code{PATH_INFO} and
+\code{QUERY_STRING} variables are ignored.  The result is the base URI
+of the application object addressed by the request.
+\end{funcdesc}
+
+\begin{funcdesc}{shift_path_info}{environ}
+Shift a single name from \code{PATH_INFO} to \code{SCRIPT_NAME} and
+return the name.  The \var{environ} dictionary is \emph{modified}
+in-place; use a copy if you need to keep the original \code{PATH_INFO}
+or \code{SCRIPT_NAME} intact.
+
+If there are no remaining path segments in \code{PATH_INFO}, \code{None}
+is returned.
+
+Typically, this routine is used to process each portion of a request
+URI path, for example to treat the path as a series of dictionary keys.
+This routine modifies the passed-in environment to make it suitable for
+invoking another WSGI application that is located at the target URI.
+For example, if there is a WSGI application at \code{/foo}, and the
+request URI path is \code{/foo/bar/baz}, and the WSGI application at
+\code{/foo} calls \function{shift_path_info}, it will receive the string
+``bar'', and the environment will be updated to be suitable for passing
+to a WSGI application at \code{/foo/bar}.  That is, \code{SCRIPT_NAME}
+will change from \code{/foo} to \code{/foo/bar}, and \code{PATH_INFO}
+will change from \code{/bar/baz} to \code{/baz}.
+
+When \code{PATH_INFO} is just a ``/'', this routine returns an empty
+string and appends a trailing slash to \code{SCRIPT_NAME}, even though
+empty path segments are normally ignored, and \code{SCRIPT_NAME} doesn't
+normally end in a slash.  This is intentional behavior, to ensure that
+an application can tell the difference between URIs ending in \code{/x}
+from ones ending in \code{/x/} when using this routine to do object
+traversal.
+
+\end{funcdesc}
+
+\begin{funcdesc}{setup_testing_defaults}{environ}
+Update \var{environ} with trivial defaults for testing purposes.
+
+This routine adds various parameters required for WSGI, including
+\code{HTTP_HOST}, \code{SERVER_NAME}, \code{SERVER_PORT},
+\code{REQUEST_METHOD}, \code{SCRIPT_NAME}, \code{PATH_INFO}, and all of
+the \pep{333}-defined \code{wsgi.*} variables.  It only supplies default
+values, and does not replace any existing settings for these variables.
+
+This routine is intended to make it easier for unit tests of WSGI
+servers and applications to set up dummy environments.  It should NOT
+be used by actual WSGI servers or applications, since the data is fake!
+\end{funcdesc}
+
+
+
+In addition to the environment functions above, the
+\module{wsgiref.util} module also provides these miscellaneous
+utilities:
+
+\begin{funcdesc}{is_hop_by_hop}{header_name}
+Return true if 'header_name' is an HTTP/1.1 ``Hop-by-Hop'' header, as
+defined by \rfc{2616}.
+\end{funcdesc}
+
+\begin{classdesc}{FileWrapper}{filelike \optional{, blksize=8192}}
+A wrapper to convert a file-like object to an iterator.  The resulting
+objects support both \method{__getitem__} and \method{__iter__}
+iteration styles, for compatibility with Python 2.1 and Jython.
+As the object is iterated over, the optional \var{blksize} parameter
+will be repeatedly passed to the \var{filelike} object's \method{read()}
+method to obtain strings to yield.  When \method{read()} returns an
+empty string, iteration is ended and is not resumable.
+
+If \var{filelike} has a \method{close()} method, the returned object
+will also have a \method{close()} method, and it will invoke the
+\var{filelike} object's \method{close()} method when called.
+\end{classdesc}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+\subsection{\module{wsgiref.headers} -- WSGI response header tools}
+\declaremodule{}{wsgiref.headers}
+
+This module provides a single class, \class{Headers}, for convenient
+manipulation of WSGI response headers using a mapping-like interface.
+
+\begin{classdesc}{Headers}{headers}
+Create a mapping-like object wrapping \var{headers}, which must be a
+list of header name/value tuples as described in \pep{333}.  Any changes
+made to the new \class{Headers} object will directly update the
+\var{headers} list it was created with.
+
+\class{Headers} objects support typical mapping operations including
+\method{__getitem__}, \method{get}, \method{__setitem__},
+\method{setdefault}, \method{__delitem__}, \method{__contains__} and
+\method{has_key}.  For each of these methods, the key is the header name
+(treated case-insensitively), and the value is the first value
+associated with that header name.  Setting a header deletes any existing
+values for that header, then adds a new value at the end of the wrapped
+header list.  Headers' existing order is generally maintained, with new
+headers added to the end of the wrapped list.
+
+Unlike a dictionary, \class{Headers} objects do not raise an error when
+you try to get or delete a key that isn't in the wrapped header list.
+Getting a nonexistent header just returns \code{None}, and deleting
+a nonexistent header does nothing.
+
+\class{Headers} objects also support \method{keys()}, \method{values()},
+and \method{items()} methods.  The lists returned by \method{keys()}
+and \method{items()} can include the same key more than once if there
+is a multi-valued header.  The \code{len()} of a \class{Headers} object
+is the same as the length of its \method{items()}, which is the same
+as the length of the wrapped header list.  In fact, the \method{items()}
+method just returns a copy of the wrapped header list.
+
+Calling \code{str()} on a \class{Headers} object returns a formatted
+string suitable for transmission as HTTP response headers.  Each header
+is placed on a line with its value, separated by a colon and a space.
+Each line is terminated by a carriage return and line feed, and the
+string is terminated with a blank line.
+
+In addition to their mapping interface and formatting features,
+\class{Headers} objects also have the following methods for querying
+and adding multi-valued headers, and for adding headers with MIME
+parameters:
+
+\begin{methoddesc}{get_all}{name}
+Return a list of all the values for the named header.
+
+The returned list will be sorted in the order they appeared in the
+original header list or were added to this instance, and may contain
+duplicates.  Any fields deleted and re-inserted are always appended to
+the header list.  If no fields exist with the given name, returns an
+empty list.
+\end{methoddesc}
+
+
+\begin{methoddesc}{add_header}{name, value, **_params}
+Add a (possibly multi-valued) header, with optional MIME parameters
+specified via keyword arguments.
+
+\var{name} is the header field to add.  Keyword arguments can be used to
+set MIME parameters for the header field.  Each parameter must be a
+string or \code{None}.  Underscores in parameter names are converted to
+dashes, since dashes are illegal in Python identifiers, but many MIME
+parameter names include dashes.  If the parameter value is a string, it
+is added to the header value parameters in the form \code{name="value"}.
+If it is \code{None}, only the parameter name is added.  (This is used
+for MIME parameters without a value.)  Example usage:
+
+\begin{verbatim}
+h.add_header('content-disposition', 'attachment', filename='bud.gif')
+\end{verbatim}
+
+The above will add a header that looks like this:
+
+\begin{verbatim}
+Content-Disposition: attachment; filename="bud.gif"
+\end{verbatim}
+\end{methoddesc}
+\end{classdesc}
+
+\subsection{\module{wsgiref.simple_server} -- a simple WSGI HTTP server}
+\declaremodule[wsgiref.simpleserver]{}{wsgiref.simple_server}
+
+This module implements a simple HTTP server (based on
+\module{BaseHTTPServer}) that serves WSGI applications.  Each server
+instance serves a single WSGI application on a given host and port.  If
+you want to serve multiple applications on a single host and port, you
+should create a WSGI application that parses \code{PATH_INFO} to select
+which application to invoke for each request.  (E.g., using the
+\function{shift_path_info()} function from \module{wsgiref.util}.)
+
+
+\begin{funcdesc}{make_server}{host, port, app
+\optional{, server_class=\class{WSGIServer} \optional{,
+handler_class=\class{WSGIRequestHandler}}}}
+Create a new WSGI server listening on \var{host} and \var{port},
+accepting connections for \var{app}.  The return value is an instance of
+the supplied \var{server_class}, and will process requests using the
+specified \var{handler_class}.  \var{app} must be a WSGI application
+object, as defined by \pep{333}.
+
+Example usage:
+\begin{verbatim}from wsgiref.simple_server import make_server, demo_app
+
+httpd = make_server('', 8000, demo_app)
+print "Serving HTTP on port 8000..."
+
+# Respond to requests until process is killed
+httpd.serve_forever()
+
+# Alternative: serve one request, then exit
+##httpd.handle_request()
+\end{verbatim}
+
+\end{funcdesc}
+
+
+
+
+
+
+\begin{funcdesc}{demo_app}{environ, start_response}
+This function is a small but complete WSGI application that
+returns a text page containing the message ``Hello world!''
+and a list of the key/value pairs provided in the
+\var{environ} parameter.  It's useful for verifying that a WSGI server
+(such as \module{wsgiref.simple_server}) is able to run a simple WSGI
+application correctly.
+\end{funcdesc}
+
+
+\begin{classdesc}{WSGIServer}{server_address, RequestHandlerClass}
+Create a \class{WSGIServer} instance.  \var{server_address} should be
+a \code{(host,port)} tuple, and \var{RequestHandlerClass} should be
+the subclass of \class{BaseHTTPServer.BaseHTTPRequestHandler} that will
+be used to process requests.
+
+You do not normally need to call this constructor, as the
+\function{make_server()} function can handle all the details for you.
+
+\class{WSGIServer} is a subclass
+of \class{BaseHTTPServer.HTTPServer}, so all of its methods (such as
+\method{serve_forever()} and \method{handle_request()}) are available.
+\class{WSGIServer} also provides these WSGI-specific methods:
+
+\begin{methoddesc}{set_app}{application}
+Sets the callable \var{application} as the WSGI application that will
+receive requests.
+\end{methoddesc}
+
+\begin{methoddesc}{get_app}{}
+Returns the currently-set application callable.
+\end{methoddesc}
+
+Normally, however, you do not need to use these additional methods, as
+\method{set_app()} is normally called by \function{make_server()}, and
+the \method{get_app()} exists mainly for the benefit of request handler
+instances.
+\end{classdesc}
+
+
+
+\begin{classdesc}{WSGIRequestHandler}{request, client_address, server}
+Create an HTTP handler for the given \var{request} (i.e. a socket),
+\var{client_address} (a \code{(\var{host},\var{port})} tuple), and
+\var{server} (\class{WSGIServer} instance).
+
+You do not need to create instances of this class directly; they are
+automatically created as needed by \class{WSGIServer} objects.  You
+can, however, subclass this class and supply it as a \var{handler_class}
+to the \function{make_server()} function.  Some possibly relevant
+methods for overriding in subclasses:
+
+\begin{methoddesc}{get_environ}{}
+Returns a dictionary containing the WSGI environment for a request.  The
+default implementation copies the contents of the \class{WSGIServer}
+object's \member{base_environ} dictionary attribute and then adds
+various headers derived from the HTTP request.  Each call to this method
+should return a new dictionary containing all of the relevant CGI
+environment variables as specified in \pep{333}.
+\end{methoddesc}
+
+\begin{methoddesc}{get_stderr}{}
+Return the object that should be used as the \code{wsgi.errors} stream.
+The default implementation just returns \code{sys.stderr}.
+\end{methoddesc}
+
+\begin{methoddesc}{handle}{}
+Process the HTTP request.  The default implementation creates a handler
+instance using a \module{wsgiref.handlers} class to implement the actual
+WSGI application interface.
+\end{methoddesc}
+
+\end{classdesc}
+
+
+
+
+
+
+
+
+
+\subsection{\module{wsgiref.validate} -- WSGI conformance checker}
+\declaremodule{}{wsgiref.validate}
+When creating new WSGI application objects, frameworks, servers, or
+middleware, it can be useful to validate the new code's conformance
+using \module{wsgiref.validate}.  This module provides a function that
+creates WSGI application objects that validate communications between
+a WSGI server or gateway and a WSGI application object, to check both
+sides for protocol conformance.
+
+Note that this utility does not guarantee complete \pep{333} compliance;
+an absence of errors from this module does not necessarily mean that
+errors do not exist.  However, if this module does produce an error,
+then it is virtually certain that either the server or application is
+not 100\% compliant.
+
+This module is based on the \module{paste.lint} module from Ian
+Bicking's ``Python Paste'' library.
+
+\begin{funcdesc}{validator}{application}
+Wrap \var{application} and return a new WSGI application object.  The
+returned application will forward all requests to the original
+\var{application}, and will check that both the \var{application} and
+the server invoking it are conforming to the WSGI specification and to
+RFC 2616.
+
+Any detected nonconformance results in an \exception{AssertionError}
+being raised; note, however, that how these errors are handled is
+server-dependent.  For example, \module{wsgiref.simple_server} and other
+servers based on \module{wsgiref.handlers} (that don't override the
+error handling methods to do something else) will simply output a
+message that an error has occurred, and dump the traceback to
+\code{sys.stderr} or some other error stream.
+
+This wrapper may also generate output using the \module{warnings} module
+to indicate behaviors that are questionable but which may not actually
+be prohibited by \pep{333}.  Unless they are suppressed using Python
+command-line options or the \module{warnings} API, any such warnings
+will be written to \code{sys.stderr} (\emph{not} \code{wsgi.errors},
+unless they happen to be the same object).
+\end{funcdesc}
+
+\subsection{\module{wsgiref.handlers} -- server/gateway base classes}
+\declaremodule{}{wsgiref.handlers}
+
+This module provides base handler classes for implementing WSGI servers
+and gateways.  These base classes handle most of the work of
+communicating with a WSGI application, as long as they are given a
+CGI-like environment, along with input, output, and error streams.
+
+
+\begin{classdesc}{CGIHandler}{}
+CGI-based invocation via \code{sys.stdin}, \code{sys.stdout},
+\code{sys.stderr} and \code{os.environ}.  This is useful when you have
+a WSGI application and want to run it as a CGI script.  Simply invoke
+\code{CGIHandler().run(app)}, where \code{app} is the WSGI application
+object you wish to invoke.
+
+This class is a subclass of \class{BaseCGIHandler} that sets
+\code{wsgi.run_once} to true, \code{wsgi.multithread} to false, and
+\code{wsgi.multiprocess} to true, and always uses \module{sys} and
+\module{os} to obtain the necessary CGI streams and environment.
+\end{classdesc}
+
+
+\begin{classdesc}{BaseCGIHandler}{stdin, stdout, stderr, environ
+\optional{, multithread=True \optional{, multiprocess=False}}}
+
+Similar to \class{CGIHandler}, but instead of using the \module{sys} and
+\module{os} modules, the CGI environment and I/O streams are specified
+explicitly.  The \var{multithread} and \var{multiprocess} values are
+used to set the \code{wsgi.multithread} and \code{wsgi.multiprocess}
+flags for any applications run by the handler instance.
+
+This class is a subclass of \class{SimpleHandler} intended for use with
+software other than HTTP ``origin servers''.  If you are writing a
+gateway protocol implementation (such as CGI, FastCGI, SCGI, etc.) that
+uses a \code{Status:} header to send an HTTP status, you probably want
+to subclass this instead of \class{SimpleHandler}.
+\end{classdesc}
+
+
+
+\begin{classdesc}{SimpleHandler}{stdin, stdout, stderr, environ
+\optional{,multithread=True \optional{, multiprocess=False}}}
+
+Similar to \class{BaseCGIHandler}, but designed for use with HTTP origin
+servers.  If you are writing an HTTP server implementation, you will
+probably want to subclass this instead of \class{BaseCGIHandler}
+
+This class is a subclass of \class{BaseHandler}.  It overrides the
+\method{__init__()}, \method{get_stdin()}, \method{get_stderr()},
+\method{add_cgi_vars()}, \method{_write()}, and \method{_flush()}
+methods to support explicitly setting the environment and streams via
+the constructor.  The supplied environment and streams are stored in
+the \member{stdin}, \member{stdout}, \member{stderr}, and
+\member{environ} attributes.
+\end{classdesc}
+
+\begin{classdesc}{BaseHandler}{}
+This is an abstract base class for running WSGI applications.  Each
+instance will handle a single HTTP request, although in principle you
+could create a subclass that was reusable for multiple requests.
+
+\class{BaseHandler} instances have only one method intended for external
+use:
+
+\begin{methoddesc}{run}{app}
+Run the specified WSGI application, \var{app}.
+\end{methoddesc}
+
+All of the other \class{BaseHandler} methods are invoked by this method
+in the process of running the application, and thus exist primarily to
+allow customizing the process.
+
+The following methods MUST be overridden in a subclass:
+
+\begin{methoddesc}{_write}{data}
+Buffer the string \var{data} for transmission to the client.  It's okay
+if this method actually transmits the data; \class{BaseHandler}
+just separates write and flush operations for greater efficiency
+when the underlying system actually has such a distinction.
+\end{methoddesc}
+
+\begin{methoddesc}{_flush}{}
+Force buffered data to be transmitted to the client.  It's okay if this
+method is a no-op (i.e., if \method{_write()} actually sends the data).
+\end{methoddesc}
+
+\begin{methoddesc}{get_stdin}{}
+Return an input stream object suitable for use as the \code{wsgi.input}
+of the request currently being processed.
+\end{methoddesc}
+
+\begin{methoddesc}{get_stderr}{}
+Return an output stream object suitable for use as the
+\code{wsgi.errors} of the request currently being processed.
+\end{methoddesc}
+
+\begin{methoddesc}{add_cgi_vars}{}
+Insert CGI variables for the current request into the \member{environ}
+attribute.
+\end{methoddesc}
+
+Here are some other methods and attributes you may wish to override.
+This list is only a summary, however, and does not include every method
+that can be overridden.  You should consult the docstrings and source
+code for additional information before attempting to create a customized
+\class{BaseHandler} subclass.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Attributes and methods for customizing the WSGI environment:
+
+\begin{memberdesc}{wsgi_multithread}
+The value to be used for the \code{wsgi.multithread} environment
+variable.  It defaults to true in \class{BaseHandler}, but may have
+a different default (or be set by the constructor) in the other
+subclasses.
+\end{memberdesc}
+
+\begin{memberdesc}{wsgi_multiprocess}
+The value to be used for the \code{wsgi.multiprocess} environment
+variable.  It defaults to true in \class{BaseHandler}, but may have
+a different default (or be set by the constructor) in the other
+subclasses.
+\end{memberdesc}
+
+\begin{memberdesc}{wsgi_run_once}
+The value to be used for the \code{wsgi.run_once} environment
+variable.  It defaults to false in \class{BaseHandler}, but
+\class{CGIHandler} sets it to true by default.
+\end{memberdesc}
+
+\begin{memberdesc}{os_environ}
+The default environment variables to be included in every request's
+WSGI environment.  By default, this is a copy of \code{os.environ} at
+the time that \module{wsgiref.handlers} was imported, but subclasses can
+either create their own at the class or instance level.  Note that the
+dictionary should be considered read-only, since the default value is
+shared between multiple classes and instances.
+\end{memberdesc}
+
+\begin{memberdesc}{server_software}
+If the \member{origin_server} attribute is set, this attribute's value
+is used to set the default \code{SERVER_SOFTWARE} WSGI environment
+variable, and also to set a default \code{Server:} header in HTTP
+responses.  It is ignored for handlers (such as \class{BaseCGIHandler}
+and \class{CGIHandler}) that are not HTTP origin servers.
+\end{memberdesc}
+
+
+
+\begin{methoddesc}{get_scheme}{}
+Return the URL scheme being used for the current request.  The default
+implementation uses the \function{guess_scheme()} function from
+\module{wsgiref.util} to guess whether the scheme should be ``http'' or
+``https'', based on the current request's \member{environ} variables.
+\end{methoddesc}
+
+\begin{methoddesc}{setup_environ}{}
+Set the \member{environ} attribute to a fully-populated WSGI
+environment.  The default implementation uses all of the above methods
+and attributes, plus the \method{get_stdin()}, \method{get_stderr()},
+and \method{add_cgi_vars()} methods and the \member{wsgi_file_wrapper}
+attribute.  It also inserts a \code{SERVER_SOFTWARE} key if not present,
+as long as the \member{origin_server} attribute is a true value and the
+\member{server_software} attribute is set.
+\end{methoddesc}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Methods and attributes for customizing exception handling:
+
+\begin{methoddesc}{log_exception}{exc_info}
+Log the \var{exc_info} tuple in the server log.  \var{exc_info} is a
+\code{(\var{type}, \var{value}, \var{traceback})} tuple.  The default
+implementation simply writes the traceback to the request's
+\code{wsgi.errors} stream and flushes it.  Subclasses can override this
+method to change the format or retarget the output, mail the traceback
+to an administrator, or whatever other action may be deemed suitable.
+\end{methoddesc}
+
+\begin{memberdesc}{traceback_limit}
+The maximum number of frames to include in tracebacks output by the
+default \method{log_exception()} method.  If \code{None}, all frames
+are included.
+\end{memberdesc}
+
+\begin{methoddesc}{error_output}{environ, start_response}
+This method is a WSGI application to generate an error page for the
+user.  It is only invoked if an error occurs before headers are sent
+to the client.
+
+This method can access the current error information using
+\code{sys.exc_info()}, and should pass that information to
+\var{start_response} when calling it (as described in the ``Error
+Handling'' section of \pep{333}).
+
+The default implementation just uses the \member{error_status},
+\member{error_headers}, and \member{error_body} attributes to generate
+an output page.  Subclasses can override this to produce more dynamic
+error output.
+
+Note, however, that it's not recommended from a security perspective to
+spit out diagnostics to any old user; ideally, you should have to do
+something special to enable diagnostic output, which is why the default
+implementation doesn't include any.
+\end{methoddesc}
+
+
+
+
+\begin{memberdesc}{error_status}
+The HTTP status used for error responses.  This should be a status
+string as defined in \pep{333}; it defaults to a 500 code and message.
+\end{memberdesc}
+
+\begin{memberdesc}{error_headers}
+The HTTP headers used for error responses.  This should be a list of
+WSGI response headers (\code{(\var{name}, \var{value})} tuples), as
+described in \pep{333}.  The default list just sets the content type
+to \code{text/plain}.
+\end{memberdesc}
+
+\begin{memberdesc}{error_body}
+The error response body.  This should be an HTTP response body string.
+It defaults to the plain text, ``A server error occurred.  Please
+contact the administrator.''
+\end{memberdesc}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Methods and attributes for \pep{333}'s ``Optional Platform-Specific File
+Handling'' feature:
+
+\begin{memberdesc}{wsgi_file_wrapper}
+A \code{wsgi.file_wrapper} factory, or \code{None}.  The default value
+of this attribute is the \class{FileWrapper} class from
+\module{wsgiref.util}.
+\end{memberdesc}
+
+\begin{methoddesc}{sendfile}{}
+Override to implement platform-specific file transmission.  This method
+is called only if the application's return value is an instance of
+the class specified by the \member{wsgi_file_wrapper} attribute.  It
+should return a true value if it was able to successfully transmit the
+file, so that the default transmission code will not be executed.
+The default implementation of this method just returns a false value.
+\end{methoddesc}
+
+
+Miscellaneous methods and attributes:
+
+\begin{memberdesc}{origin_server}
+This attribute should be set to a true value if the handler's
+\method{_write()} and \method{_flush()} are being used to communicate
+directly to the client, rather than via a CGI-like gateway protocol that
+wants the HTTP status in a special \code{Status:} header.
+
+This attribute's default value is true in \class{BaseHandler}, but
+false in \class{BaseCGIHandler} and \class{CGIHandler}.
+\end{memberdesc}
+
+\begin{memberdesc}{http_version}
+If \member{origin_server} is true, this string attribute is used to
+set the HTTP version of the response set to the client.  It defaults to
+\code{"1.0"}.
+\end{memberdesc}
+
+
+
+
+
+\end{classdesc}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


Property changes on: vendor/Python/current/Doc/lib/libwsgiref.tex
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Doc/lib/libxdrlib.tex
===================================================================
--- vendor/Python/current/Doc/lib/libxdrlib.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libxdrlib.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,251 @@
+\section{\module{xdrlib} ---
+         Encode and decode XDR data}
+
+\declaremodule{standard}{xdrlib}
+\modulesynopsis{Encoders and decoders for the External Data
+                Representation (XDR).}
+
+\index{XDR}
+\index{External Data Representation}
+
+The \module{xdrlib} module supports the External Data Representation
+Standard as described in \rfc{1014}, written by Sun Microsystems,
+Inc. June 1987.  It supports most of the data types described in the
+RFC.
+
+The \module{xdrlib} module defines two classes, one for packing
+variables into XDR representation, and another for unpacking from XDR
+representation.  There are also two exception classes.
+
+\begin{classdesc}{Packer}{}
+\class{Packer} is the class for packing data into XDR representation.
+The \class{Packer} class is instantiated with no arguments.
+\end{classdesc}
+
+\begin{classdesc}{Unpacker}{data}
+\code{Unpacker} is the complementary class which unpacks XDR data
+values from a string buffer.  The input buffer is given as
+\var{data}.
+\end{classdesc}
+
+
+\begin{seealso}
+  \seerfc{1014}{XDR: External Data Representation Standard}{This RFC
+                defined the encoding of data which was XDR at the time
+                this module was originally written.  It has
+                apparently been obsoleted by \rfc{1832}.}
+
+  \seerfc{1832}{XDR: External Data Representation Standard}{Newer RFC
+                that provides a revised definition of XDR.}
+\end{seealso}
+
+
+\subsection{Packer Objects \label{xdr-packer-objects}}
+
+\class{Packer} instances have the following methods:
+
+\begin{methoddesc}[Packer]{get_buffer}{}
+Returns the current pack buffer as a string.
+\end{methoddesc}
+
+\begin{methoddesc}[Packer]{reset}{}
+Resets the pack buffer to the empty string.
+\end{methoddesc}
+
+In general, you can pack any of the most common XDR data types by
+calling the appropriate \code{pack_\var{type}()} method.  Each method
+takes a single argument, the value to pack.  The following simple data
+type packing methods are supported: \method{pack_uint()},
+\method{pack_int()}, \method{pack_enum()}, \method{pack_bool()},
+\method{pack_uhyper()}, and \method{pack_hyper()}.
+
+\begin{methoddesc}[Packer]{pack_float}{value}
+Packs the single-precision floating point number \var{value}.
+\end{methoddesc}
+
+\begin{methoddesc}[Packer]{pack_double}{value}
+Packs the double-precision floating point number \var{value}.
+\end{methoddesc}
+
+The following methods support packing strings, bytes, and opaque data:
+
+\begin{methoddesc}[Packer]{pack_fstring}{n, s}
+Packs a fixed length string, \var{s}.  \var{n} is the length of the
+string but it is \emph{not} packed into the data buffer.  The string
+is padded with null bytes if necessary to guaranteed 4 byte alignment.
+\end{methoddesc}
+
+\begin{methoddesc}[Packer]{pack_fopaque}{n, data}
+Packs a fixed length opaque data stream, similarly to
+\method{pack_fstring()}.
+\end{methoddesc}
+
+\begin{methoddesc}[Packer]{pack_string}{s}
+Packs a variable length string, \var{s}.  The length of the string is
+first packed as an unsigned integer, then the string data is packed
+with \method{pack_fstring()}.
+\end{methoddesc}
+
+\begin{methoddesc}[Packer]{pack_opaque}{data}
+Packs a variable length opaque data string, similarly to
+\method{pack_string()}.
+\end{methoddesc}
+
+\begin{methoddesc}[Packer]{pack_bytes}{bytes}
+Packs a variable length byte stream, similarly to \method{pack_string()}.
+\end{methoddesc}
+
+The following methods support packing arrays and lists:
+
+\begin{methoddesc}[Packer]{pack_list}{list, pack_item}
+Packs a \var{list} of homogeneous items.  This method is useful for
+lists with an indeterminate size; i.e. the size is not available until
+the entire list has been walked.  For each item in the list, an
+unsigned integer \code{1} is packed first, followed by the data value
+from the list.  \var{pack_item} is the function that is called to pack
+the individual item.  At the end of the list, an unsigned integer
+\code{0} is packed.
+
+For example, to pack a list of integers, the code might appear like
+this:
+
+\begin{verbatim}
+import xdrlib
+p = xdrlib.Packer()
+p.pack_list([1, 2, 3], p.pack_int)
+\end{verbatim}
+\end{methoddesc}
+
+\begin{methoddesc}[Packer]{pack_farray}{n, array, pack_item}
+Packs a fixed length list (\var{array}) of homogeneous items.  \var{n}
+is the length of the list; it is \emph{not} packed into the buffer,
+but a \exception{ValueError} exception is raised if
+\code{len(\var{array})} is not equal to \var{n}.  As above,
+\var{pack_item} is the function used to pack each element.
+\end{methoddesc}
+
+\begin{methoddesc}[Packer]{pack_array}{list, pack_item}
+Packs a variable length \var{list} of homogeneous items.  First, the
+length of the list is packed as an unsigned integer, then each element
+is packed as in \method{pack_farray()} above.
+\end{methoddesc}
+
+
+\subsection{Unpacker Objects \label{xdr-unpacker-objects}}
+
+The \class{Unpacker} class offers the following methods:
+
+\begin{methoddesc}[Unpacker]{reset}{data}
+Resets the string buffer with the given \var{data}.
+\end{methoddesc}
+
+\begin{methoddesc}[Unpacker]{get_position}{}
+Returns the current unpack position in the data buffer.
+\end{methoddesc}
+
+\begin{methoddesc}[Unpacker]{set_position}{position}
+Sets the data buffer unpack position to \var{position}.  You should be
+careful about using \method{get_position()} and \method{set_position()}.
+\end{methoddesc}
+
+\begin{methoddesc}[Unpacker]{get_buffer}{}
+Returns the current unpack data buffer as a string.
+\end{methoddesc}
+
+\begin{methoddesc}[Unpacker]{done}{}
+Indicates unpack completion.  Raises an \exception{Error} exception
+if all of the data has not been unpacked.
+\end{methoddesc}
+
+In addition, every data type that can be packed with a \class{Packer},
+can be unpacked with an \class{Unpacker}.  Unpacking methods are of the
+form \code{unpack_\var{type}()}, and take no arguments.  They return the
+unpacked object.
+
+\begin{methoddesc}[Unpacker]{unpack_float}{}
+Unpacks a single-precision floating point number.
+\end{methoddesc}
+
+\begin{methoddesc}[Unpacker]{unpack_double}{}
+Unpacks a double-precision floating point number, similarly to
+\method{unpack_float()}.
+\end{methoddesc}
+
+In addition, the following methods unpack strings, bytes, and opaque
+data:
+
+\begin{methoddesc}[Unpacker]{unpack_fstring}{n}
+Unpacks and returns a fixed length string.  \var{n} is the number of
+characters expected.  Padding with null bytes to guaranteed 4 byte
+alignment is assumed.
+\end{methoddesc}
+
+\begin{methoddesc}[Unpacker]{unpack_fopaque}{n}
+Unpacks and returns a fixed length opaque data stream, similarly to
+\method{unpack_fstring()}.
+\end{methoddesc}
+
+\begin{methoddesc}[Unpacker]{unpack_string}{}
+Unpacks and returns a variable length string.  The length of the
+string is first unpacked as an unsigned integer, then the string data
+is unpacked with \method{unpack_fstring()}.
+\end{methoddesc}
+
+\begin{methoddesc}[Unpacker]{unpack_opaque}{}
+Unpacks and returns a variable length opaque data string, similarly to
+\method{unpack_string()}.
+\end{methoddesc}
+
+\begin{methoddesc}[Unpacker]{unpack_bytes}{}
+Unpacks and returns a variable length byte stream, similarly to
+\method{unpack_string()}.
+\end{methoddesc}
+
+The following methods support unpacking arrays and lists:
+
+\begin{methoddesc}[Unpacker]{unpack_list}{unpack_item}
+Unpacks and returns a list of homogeneous items.  The list is unpacked
+one element at a time
+by first unpacking an unsigned integer flag.  If the flag is \code{1},
+then the item is unpacked and appended to the list.  A flag of
+\code{0} indicates the end of the list.  \var{unpack_item} is the
+function that is called to unpack the items.
+\end{methoddesc}
+
+\begin{methoddesc}[Unpacker]{unpack_farray}{n, unpack_item}
+Unpacks and returns (as a list) a fixed length array of homogeneous
+items.  \var{n} is number of list elements to expect in the buffer.
+As above, \var{unpack_item} is the function used to unpack each element.
+\end{methoddesc}
+
+\begin{methoddesc}[Unpacker]{unpack_array}{unpack_item}
+Unpacks and returns a variable length \var{list} of homogeneous items.
+First, the length of the list is unpacked as an unsigned integer, then
+each element is unpacked as in \method{unpack_farray()} above.
+\end{methoddesc}
+
+
+\subsection{Exceptions \label{xdr-exceptions}}
+
+Exceptions in this module are coded as class instances:
+
+\begin{excdesc}{Error}
+The base exception class.  \exception{Error} has a single public data
+member \member{msg} containing the description of the error.
+\end{excdesc}
+
+\begin{excdesc}{ConversionError}
+Class derived from \exception{Error}.  Contains no additional instance
+variables.
+\end{excdesc}
+
+Here is an example of how you would catch one of these exceptions:
+
+\begin{verbatim}
+import xdrlib
+p = xdrlib.Packer()
+try:
+    p.pack_double(8.01)
+except xdrlib.ConversionError, instance:
+    print 'packing the double failed:', instance.msg
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/libxmllib.tex
===================================================================
--- vendor/Python/current/Doc/lib/libxmllib.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libxmllib.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,287 @@
+\section{\module{xmllib} ---
+         A parser for XML documents}
+
+\declaremodule{standard}{xmllib}
+\modulesynopsis{A parser for XML documents.}
+\moduleauthor{Sjoerd Mullender}{Sjoerd.Mullender at cwi.nl}
+\sectionauthor{Sjoerd Mullender}{Sjoerd.Mullender at cwi.nl}
+
+
+\index{XML}
+\index{Extensible Markup Language}
+
+\deprecated{2.0}{Use \refmodule{xml.sax} instead.  The newer XML
+                 package includes full support for XML 1.0.}
+
+\versionchanged[Added namespace support]{1.5.2}
+
+This module defines a class \class{XMLParser} which serves as the basis 
+for parsing text files formatted in XML (Extensible Markup Language).
+
+\begin{classdesc}{XMLParser}{}
+The \class{XMLParser} class must be instantiated without
+arguments.\footnote{Actually, a number of keyword arguments are
+recognized which influence the parser to accept certain non-standard
+constructs.  The following keyword arguments are currently
+recognized.  The defaults for all of these is \code{0} (false) except
+for the last one for which the default is \code{1} (true).
+\var{accept_unquoted_attributes} (accept certain attribute values
+without requiring quotes), \var{accept_missing_endtag_name} (accept
+end tags that look like \code{</>}), \var{map_case} (map upper case to
+lower case in tags and attributes), \var{accept_utf8} (allow UTF-8
+characters in input; this is required according to the XML standard,
+but Python does not as yet deal properly with these characters, so
+this is not the default), \var{translate_attribute_references} (don't
+attempt to translate character and entity references in attribute values).}
+\end{classdesc}
+
+This class provides the following interface methods and instance variables:
+
+\begin{memberdesc}{attributes}
+A mapping of element names to mappings.  The latter mapping maps
+attribute names that are valid for the element to the default value of 
+the attribute, or if there is no default to \code{None}.  The default
+value is the empty dictionary.  This variable is meant to be
+overridden, not extended since the default is shared by all instances
+of \class{XMLParser}.
+\end{memberdesc}
+
+\begin{memberdesc}{elements} 
+A mapping of element names to tuples.  The tuples contain a function
+for handling the start and end tag respectively of the element, or
+\code{None} if the method \method{unknown_starttag()} or
+\method{unknown_endtag()} is to be called.  The default value is the
+empty dictionary.  This variable is meant to be overridden, not
+extended since the default is shared by all instances of
+\class{XMLParser}.
+\end{memberdesc}
+
+\begin{memberdesc}{entitydefs}
+A mapping of entitynames to their values.  The default value contains
+definitions for \code{'lt'}, \code{'gt'}, \code{'amp'}, \code{'quot'}, 
+and \code{'apos'}.
+\end{memberdesc}
+
+\begin{methoddesc}{reset}{}
+Reset the instance.  Loses all unprocessed data.  This is called
+implicitly at the instantiation time.
+\end{methoddesc}
+
+\begin{methoddesc}{setnomoretags}{}
+Stop processing tags.  Treat all following input as literal input
+(CDATA).
+\end{methoddesc}
+
+\begin{methoddesc}{setliteral}{}
+Enter literal mode (CDATA mode).  This mode is automatically exited
+when the close tag matching the last unclosed open tag is encountered.
+\end{methoddesc}
+
+\begin{methoddesc}{feed}{data}
+Feed some text to the parser.  It is processed insofar as it consists
+of complete tags; incomplete data is buffered until more data is
+fed or \method{close()} is called.
+\end{methoddesc}
+
+\begin{methoddesc}{close}{}
+Force processing of all buffered data as if it were followed by an
+end-of-file mark.  This method may be redefined by a derived class to
+define additional processing at the end of the input, but the
+redefined version should always call \method{close()}.
+\end{methoddesc}
+
+\begin{methoddesc}{translate_references}{data}
+Translate all entity and character references in \var{data} and
+return the translated string.
+\end{methoddesc}
+
+\begin{methoddesc}{getnamespace}{}
+Return a mapping of namespace abbreviations to namespace URIs that are
+currently in effect.
+\end{methoddesc}
+
+\begin{methoddesc}{handle_xml}{encoding, standalone}
+This method is called when the \samp{<?xml ...?>} tag is processed.
+The arguments are the values of the encoding and standalone attributes 
+in the tag.  Both encoding and standalone are optional.  The values
+passed to \method{handle_xml()} default to \code{None} and the string
+\code{'no'} respectively.
+\end{methoddesc}
+
+\begin{methoddesc}{handle_doctype}{tag, pubid, syslit, data}
+This\index{DOCTYPE declaration} method is called when the
+\samp{<!DOCTYPE...>} declaration is processed.  The arguments are the
+tag name of the root element, the Formal Public\index{Formal Public
+Identifier} Identifier (or \code{None} if not specified), the system
+identifier, and the uninterpreted contents of the internal DTD subset
+as a string (or \code{None} if not present).
+\end{methoddesc}
+
+\begin{methoddesc}{handle_starttag}{tag, method, attributes}
+This method is called to handle start tags for which a start tag
+handler is defined in the instance variable \member{elements}.  The
+\var{tag} argument is the name of the tag, and the
+\var{method} argument is the function (method) which should be used to
+support semantic interpretation of the start tag.  The
+\var{attributes} argument is a dictionary of attributes, the key being
+the \var{name} and the value being the \var{value} of the attribute
+found inside the tag's \code{<>} brackets.  Character and entity
+references in the \var{value} have been interpreted.  For instance,
+for the start tag \code{<A HREF="http://www.cwi.nl/">}, this method
+would be called as \code{handle_starttag('A', self.elements['A'][0],
+\{'HREF': 'http://www.cwi.nl/'\})}.  The base implementation simply
+calls \var{method} with \var{attributes} as the only argument.
+\end{methoddesc}
+
+\begin{methoddesc}{handle_endtag}{tag, method}
+This method is called to handle endtags for which an end tag handler
+is defined in the instance variable \member{elements}.  The \var{tag}
+argument is the name of the tag, and the \var{method} argument is the
+function (method) which should be used to support semantic
+interpretation of the end tag.  For instance, for the endtag
+\code{</A>}, this method would be called as \code{handle_endtag('A',
+self.elements['A'][1])}.  The base implementation simply calls
+\var{method}.
+\end{methoddesc}
+
+\begin{methoddesc}{handle_data}{data}
+This method is called to process arbitrary data.  It is intended to be
+overridden by a derived class; the base class implementation does
+nothing.
+\end{methoddesc}
+
+\begin{methoddesc}{handle_charref}{ref}
+This method is called to process a character reference of the form
+\samp{\&\#\var{ref};}.  \var{ref} can either be a decimal number,
+or a hexadecimal number when preceded by an \character{x}.
+In the base implementation, \var{ref} must be a number in the
+range 0-255.  It translates the character to \ASCII{} and calls the
+method \method{handle_data()} with the character as argument.  If
+\var{ref} is invalid or out of range, the method
+\code{unknown_charref(\var{ref})} is called to handle the error.  A
+subclass must override this method to provide support for character
+references outside of the \ASCII{} range.
+\end{methoddesc}
+
+\begin{methoddesc}{handle_comment}{comment}
+This method is called when a comment is encountered.  The
+\var{comment} argument is a string containing the text between the
+\samp{<!--} and \samp{-->} delimiters, but not the delimiters
+themselves.  For example, the comment \samp{<!--text-->} will
+cause this method to be called with the argument \code{'text'}.  The
+default method does nothing.
+\end{methoddesc}
+
+\begin{methoddesc}{handle_cdata}{data}
+This method is called when a CDATA element is encountered.  The
+\var{data} argument is a string containing the text between the
+\samp{<![CDATA[} and \samp{]]>} delimiters, but not the delimiters
+themselves.  For example, the entity \samp{<![CDATA[text]]>} will
+cause this method to be called with the argument \code{'text'}.  The
+default method does nothing, and is intended to be overridden.
+\end{methoddesc}
+
+\begin{methoddesc}{handle_proc}{name, data}
+This method is called when a processing instruction (PI) is
+encountered.  The \var{name} is the PI target, and the \var{data}
+argument is a string containing the text between the PI target and the
+closing delimiter, but not the delimiter itself.  For example, the
+instruction \samp{<?XML text?>} will cause this method to be called
+with the arguments \code{'XML'} and \code{'text'}.  The default method
+does nothing.  Note that if a document starts with \samp{<?xml
+..?>}, \method{handle_xml()} is called to handle it.
+\end{methoddesc}
+
+\begin{methoddesc}{handle_special}{data}
+This method is called when a declaration is encountered.  The
+\var{data} argument is a string containing the text between the
+\samp{<!} and \samp{>} delimiters, but not the delimiters
+themselves.  For example, the \index{ENTITY declaration}entity
+declaration \samp{<!ENTITY text>} will cause this method to be called
+with the argument \code{'ENTITY text'}.  The default method does
+nothing.  Note that \samp{<!DOCTYPE ...>} is handled separately if it
+is located at the start of the document.
+\end{methoddesc}
+
+\begin{methoddesc}{syntax_error}{message}
+This method is called when a syntax error is encountered.  The
+\var{message} is a description of what was wrong.  The default method 
+raises a \exception{RuntimeError} exception.  If this method is
+overridden, it is permissible for it to return.  This method is only
+called when the error can be recovered from.  Unrecoverable errors
+raise a \exception{RuntimeError} without first calling
+\method{syntax_error()}.
+\end{methoddesc}
+
+\begin{methoddesc}{unknown_starttag}{tag, attributes}
+This method is called to process an unknown start tag.  It is intended
+to be overridden by a derived class; the base class implementation
+does nothing.
+\end{methoddesc}
+
+\begin{methoddesc}{unknown_endtag}{tag}
+This method is called to process an unknown end tag.  It is intended
+to be overridden by a derived class; the base class implementation
+does nothing.
+\end{methoddesc}
+
+\begin{methoddesc}{unknown_charref}{ref}
+This method is called to process unresolvable numeric character
+references.  It is intended to be overridden by a derived class; the
+base class implementation does nothing.
+\end{methoddesc}
+
+\begin{methoddesc}{unknown_entityref}{ref}
+This method is called to process an unknown entity reference.  It is
+intended to be overridden by a derived class; the base class
+implementation calls \method{syntax_error()} to signal an error.
+\end{methoddesc}
+
+
+\begin{seealso}
+  \seetitle[http://www.w3.org/TR/REC-xml]{Extensible Markup Language
+            (XML) 1.0}{The XML specification, published by the World
+            Wide Web Consortium (W3C), defines the syntax and
+            processor requirements for XML.  References to additional
+            material on XML, including translations of the
+            specification, are available at
+            \url{http://www.w3.org/XML/}.}
+
+  \seetitle[http://www.python.org/topics/xml/]{Python and XML
+            Processing}{The Python XML Topic Guide provides a great
+            deal of information on using XML from Python and links to
+            other sources of information on XML.}
+
+  \seetitle[http://www.python.org/sigs/xml-sig/]{SIG for XML
+            Processing in Python}{The Python XML Special Interest
+            Group is developing substantial support for processing XML
+            from Python.}
+\end{seealso}
+
+
+\subsection{XML Namespaces \label{xml-namespace}}
+
+This module has support for XML namespaces as defined in the XML
+Namespaces proposed recommendation.
+\indexii{XML}{namespaces}
+
+Tag and attribute names that are defined in an XML namespace are
+handled as if the name of the tag or element consisted of the
+namespace (the URL that defines the namespace) followed by a
+space and the name of the tag or attribute.  For instance, the tag
+\code{<html xmlns='http://www.w3.org/TR/REC-html40'>} is treated as if 
+the tag name was \code{'http://www.w3.org/TR/REC-html40 html'}, and
+the tag \code{<html:a href='http://frob.com'>} inside the above
+mentioned element is treated as if the tag name were
+\code{'http://www.w3.org/TR/REC-html40 a'} and the attribute name as
+if it were \code{'http://www.w3.org/TR/REC-html40 href'}.
+
+An older draft of the XML Namespaces proposal is also recognized, but
+triggers a warning.
+
+\begin{seealso}
+  \seetitle[http://www.w3.org/TR/REC-xml-names/]{Namespaces in XML}{
+           This World Wide Web Consortium recommendation describes the
+           proper syntax and processing requirements for namespaces in
+           XML.}
+\end{seealso}

Added: vendor/Python/current/Doc/lib/libxmlrpclib.tex
===================================================================
--- vendor/Python/current/Doc/lib/libxmlrpclib.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libxmlrpclib.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,383 @@
+\section{\module{xmlrpclib} --- XML-RPC client access}
+
+\declaremodule{standard}{xmlrpclib}
+\modulesynopsis{XML-RPC client access.}
+\moduleauthor{Fredrik Lundh}{fredrik at pythonware.com}
+\sectionauthor{Eric S. Raymond}{esr at snark.thyrsus.com}
+
+% Not everything is documented yet.  It might be good to describe 
+% Marshaller, Unmarshaller, getparser, dumps, loads, and Transport.
+
+\versionadded{2.2}
+
+XML-RPC is a Remote Procedure Call method that uses XML passed via
+HTTP as a transport.  With it, a client can call methods with
+parameters on a remote server (the server is named by a URI) and get back
+structured data.  This module supports writing XML-RPC client code; it
+handles all the details of translating between conformable Python
+objects and XML on the wire.
+
+\begin{classdesc}{ServerProxy}{uri\optional{, transport\optional{,
+                               encoding\optional{, verbose\optional{, 
+                               allow_none\optional{, use_datetime}}}}}}
+A \class{ServerProxy} instance is an object that manages communication
+with a remote XML-RPC server.  The required first argument is a URI
+(Uniform Resource Indicator), and will normally be the URL of the
+server.  The optional second argument is a transport factory instance;
+by default it is an internal \class{SafeTransport} instance for https:
+URLs and an internal HTTP \class{Transport} instance otherwise.  The
+optional third argument is an encoding, by default UTF-8. The optional
+fourth argument is a debugging flag.  If \var{allow_none} is true, 
+the Python constant \code{None} will be translated into XML; the
+default behaviour is for \code{None} to raise a \exception{TypeError}.
+This is a commonly-used extension to the XML-RPC specification, but isn't
+supported by all clients and servers; see
+\url{http://ontosys.com/xml-rpc/extensions.php} for a description. 
+The \var{use_datetime} flag can be used to cause date/time values to be
+presented as \class{\refmodule{datetime}.datetime} objects; this is false
+by default.  \class{\refmodule{datetime}.datetime},
+\class{\refmodule{datetime}.date} and \class{\refmodule{datetime}.time}
+objects may be passed to calls.  \class{\refmodule{datetime}.date} objects
+are converted with a time of ``00:00:00''.
+\class{\refmodule{datetime}.time} objects are converted using today's date.
+
+Both the HTTP and HTTPS transports support the URL syntax extension for
+HTTP Basic Authentication: \code{http://user:pass@host:port/path}.  The 
+\code{user:pass} portion will be base64-encoded as an HTTP `Authorization'
+header, and sent to the remote server as part of the connection process
+when invoking an XML-RPC method.  You only need to use this if the
+remote server requires a Basic Authentication user and password.
+
+The returned instance is a proxy object with methods that can be used
+to invoke corresponding RPC calls on the remote server.  If the remote
+server supports the introspection API, the proxy can also be used to query
+the remote server for the methods it supports (service discovery) and
+fetch other server-associated metadata.
+
+\class{ServerProxy} instance methods take Python basic types and objects as 
+arguments and return Python basic types and classes.  Types that are
+conformable (e.g. that can be marshalled through XML), include the
+following (and except where noted, they are unmarshalled as the same
+Python type):
+
+\begin{tableii}{l|l}{constant}{Name}{Meaning}
+  \lineii{boolean}{The \constant{True} and \constant{False} constants}
+  \lineii{integers}{Pass in directly}
+  \lineii{floating-point numbers}{Pass in directly}
+  \lineii{strings}{Pass in directly}
+  \lineii{arrays}{Any Python sequence type containing conformable
+                  elements. Arrays are returned as lists}
+  \lineii{structures}{A Python dictionary. Keys must be strings,
+                      values may be any conformable type.}
+  \lineii{dates}{in seconds since the epoch (pass in an instance of the
+                 \class{DateTime} class) or a
+                 \class{\refmodule{datetime}.datetime},
+                 \class{\refmodule{datetime}.date} or
+                 \class{\refmodule{datetime}.time} instance} 
+  \lineii{binary data}{pass in an instance of the \class{Binary}
+                       wrapper class}
+\end{tableii}
+
+This is the full set of data types supported by XML-RPC.  Method calls
+may also raise a special \exception{Fault} instance, used to signal
+XML-RPC server errors, or \exception{ProtocolError} used to signal an
+error in the HTTP/HTTPS transport layer.  Both \exception{Fault} and
+\exception{ProtocolError} derive from a base class called
+\exception{Error}.  Note that even though starting with Python 2.2 you
+can subclass builtin types, the xmlrpclib module currently does not
+marshal instances of such subclasses.
+
+When passing strings, characters special to XML such as \samp{<},
+\samp{>}, and \samp{\&} will be automatically escaped.  However, it's
+the caller's responsibility to ensure that the string is free of
+characters that aren't allowed in XML, such as the control characters
+with ASCII values between 0 and 31; failing to do this will result in
+an XML-RPC request that isn't well-formed XML.  If you have to pass
+arbitrary strings via XML-RPC, use the \class{Binary} wrapper class
+described below.
+
+\class{Server} is retained as an alias for \class{ServerProxy} for backwards
+compatibility.  New code should use \class{ServerProxy}.
+
+\versionchanged[The \var{use_datetime} flag was added]{2.5}
+\end{classdesc}
+
+
+\begin{seealso}
+  \seetitle[http://www.tldp.org/HOWTO/XML-RPC-HOWTO/index.html]
+           {XML-RPC HOWTO}{A good description of XML operation and
+            client software in several languages.  Contains pretty much
+            everything an XML-RPC client developer needs to know.}
+  \seetitle[http://xmlrpc-c.sourceforge.net/hacks.php]
+           {XML-RPC Hacks page}{Extensions for various open-source
+            libraries to support introspection and multicall.}
+\end{seealso}
+
+
+\subsection{ServerProxy Objects \label{serverproxy-objects}}
+
+A \class{ServerProxy} instance has a method corresponding to
+each remote procedure call accepted by the XML-RPC server.  Calling
+the method performs an RPC, dispatched by both name and argument
+signature (e.g. the same method name can be overloaded with multiple
+argument signatures).  The RPC finishes by returning a value, which
+may be either returned data in a conformant type or a \class{Fault} or
+\class{ProtocolError} object indicating an error.
+
+Servers that support the XML introspection API support some common
+methods grouped under the reserved \member{system} member:
+
+\begin{methoddesc}{system.listMethods}{}
+This method returns a list of strings, one for each (non-system)
+method supported by the XML-RPC server.
+\end{methoddesc}
+
+\begin{methoddesc}{system.methodSignature}{name}
+This method takes one parameter, the name of a method implemented by
+the XML-RPC server.It returns an array of possible signatures for this
+method. A signature is an array of types. The first of these types is
+the return type of the method, the rest are parameters.
+
+Because multiple signatures (ie. overloading) is permitted, this method
+returns a list of signatures rather than a singleton.
+
+Signatures themselves are restricted to the top level parameters
+expected by a method. For instance if a method expects one array of
+structs as a parameter, and it returns a string, its signature is
+simply "string, array". If it expects three integers and returns a
+string, its signature is "string, int, int, int".
+
+If no signature is defined for the method, a non-array value is
+returned. In Python this means that the type of the returned 
+value will be something other that list.
+\end{methoddesc}
+
+\begin{methoddesc}{system.methodHelp}{name}
+This method takes one parameter, the name of a method implemented by
+the XML-RPC server.  It returns a documentation string describing the
+use of that method. If no such string is available, an empty string is
+returned. The documentation string may contain HTML markup.  
+\end{methoddesc}
+
+Introspection methods are currently supported by servers written in
+PHP, C and Microsoft .NET. Partial introspection support is included
+in recent updates to UserLand Frontier. Introspection support for
+Perl, Python and Java is available at the \ulink{XML-RPC
+Hacks}{http://xmlrpc-c.sourceforge.net/hacks.php} page.
+
+
+\subsection{Boolean Objects \label{boolean-objects}}
+
+This class may be initialized from any Python value; the instance
+returned depends only on its truth value.  It supports various Python
+operators through \method{__cmp__()}, \method{__repr__()},
+\method{__int__()}, and \method{__nonzero__()} methods, all
+implemented in the obvious ways.
+
+It also has the following method, supported mainly for internal use by
+the unmarshalling code:
+
+\begin{methoddesc}{encode}{out}
+Write the XML-RPC encoding of this Boolean item to the out stream object.
+\end{methoddesc}
+
+
+\subsection{DateTime Objects \label{datetime-objects}}
+
+This class may be initialized with seconds since the epoch, a time tuple, an
+ISO 8601 time/date string, or a {}\class{\refmodule{datetime}.datetime},
+{}\class{\refmodule{datetime}.date} or {}\class{\refmodule{datetime}.time}
+instance.  It has the following methods, supported mainly for internal use
+by the marshalling/unmarshalling code:
+
+\begin{methoddesc}{decode}{string}
+Accept a string as the instance's new time value.
+\end{methoddesc}
+
+\begin{methoddesc}{encode}{out}
+Write the XML-RPC encoding of this \class{DateTime} item to the
+\var{out} stream object.
+\end{methoddesc}
+
+It also supports certain of Python's built-in operators through 
+\method{__cmp__()} and \method{__repr__()} methods.
+
+
+\subsection{Binary Objects \label{binary-objects}}
+
+This class may be initialized from string data (which may include NULs).
+The primary access to the content of a \class{Binary} object is
+provided by an attribute:
+
+\begin{memberdesc}[Binary]{data}
+The binary data encapsulated by the \class{Binary} instance.  The data
+is provided as an 8-bit string.
+\end{memberdesc}
+
+\class{Binary} objects have the following methods, supported mainly
+for internal use by the marshalling/unmarshalling code:
+
+\begin{methoddesc}[Binary]{decode}{string}
+Accept a base64 string and decode it as the instance's new data.
+\end{methoddesc}
+
+\begin{methoddesc}[Binary]{encode}{out}
+Write the XML-RPC base 64 encoding of this binary item to the out
+stream object.
+\end{methoddesc}
+
+It also supports certain of Python's built-in operators through a
+\method{__cmp__()} method.
+
+
+\subsection{Fault Objects \label{fault-objects}}
+
+A \class{Fault} object encapsulates the content of an XML-RPC fault tag.
+Fault objects have the following members:
+
+\begin{memberdesc}{faultCode}
+A string indicating the fault type.
+\end{memberdesc}
+
+\begin{memberdesc}{faultString}
+A string containing a diagnostic message associated with the fault.
+\end{memberdesc}
+
+
+\subsection{ProtocolError Objects \label{protocol-error-objects}}
+
+A \class{ProtocolError} object describes a protocol error in the
+underlying transport layer (such as a 404 `not found' error if the
+server named by the URI does not exist).  It has the following
+members:
+
+\begin{memberdesc}{url}
+The URI or URL that triggered the error.
+\end{memberdesc}
+
+\begin{memberdesc}{errcode}
+The error code.
+\end{memberdesc}
+
+\begin{memberdesc}{errmsg}
+The error message or diagnostic string.
+\end{memberdesc}
+
+\begin{memberdesc}{headers}
+A string containing the headers of the HTTP/HTTPS request that
+triggered the error.
+\end{memberdesc}
+
+\subsection{MultiCall Objects}
+
+\versionadded{2.4}
+
+In \url{http://www.xmlrpc.com/discuss/msgReader\%241208}, an approach
+is presented to encapsulate multiple calls to a remote server into a
+single request.
+
+\begin{classdesc}{MultiCall}{server}
+
+Create an object used to boxcar method calls. \var{server} is the
+eventual target of the call. Calls can be made to the result object,
+but they will immediately return \var{None}, and only store the
+call name and parameters in the \class{MultiCall} object. Calling
+the object itself causes all stored calls to be transmitted as
+a single \code{system.multicall} request. The result of this call
+is a generator; iterating over this generator yields the individual
+results.
+
+\end{classdesc}
+
+A usage example of this class is
+
+\begin{verbatim}
+multicall = MultiCall(server_proxy)
+multicall.add(2,3)
+multicall.get_address("Guido")
+add_result, address = multicall()
+\end{verbatim}
+
+\subsection{Convenience Functions}
+
+\begin{funcdesc}{boolean}{value}
+Convert any Python value to one of the XML-RPC Boolean constants,
+\code{True} or \code{False}.
+\end{funcdesc}
+
+\begin{funcdesc}{dumps}{params\optional{, methodname\optional{, 
+	                methodresponse\optional{, encoding\optional{,
+	                allow_none}}}}}
+Convert \var{params} into an XML-RPC request.
+or into a response if \var{methodresponse} is true.
+\var{params} can be either a tuple of arguments or an instance of the 
+\exception{Fault} exception class.  If \var{methodresponse} is true,
+only a single value can be returned, meaning that \var{params} must be of length 1.
+\var{encoding}, if supplied, is the encoding to use in the generated
+XML; the default is UTF-8.  Python's \constant{None} value cannot be
+used in standard XML-RPC; to allow using it via an extension, 
+provide a true value for \var{allow_none}.
+\end{funcdesc}
+
+\begin{funcdesc}{loads}{data\optional{, use_datetime}}
+Convert an XML-RPC request or response into Python objects, a
+\code{(\var{params}, \var{methodname})}.  \var{params} is a tuple of argument; \var{methodname}
+is a string, or \code{None} if no method name is present in the packet.
+If the XML-RPC packet represents a fault condition, this
+function will raise a \exception{Fault} exception.
+The \var{use_datetime} flag can be used to cause date/time values to be
+presented as \class{\refmodule{datetime}.datetime} objects; this is false
+by default.
+Note that even if you call an XML-RPC method with
+\class{\refmodule{datetime}.date} or \class{\refmodule{datetime}.time}
+objects, they are converted to \class{DateTime} objects internally, so only
+{}\class{\refmodule{datetime}.datetime} objects will be returned.
+
+\versionchanged[The \var{use_datetime} flag was added]{2.5}
+\end{funcdesc}
+
+
+
+\subsection{Example of Client Usage \label{xmlrpc-client-example}}
+
+\begin{verbatim}
+# simple test program (from the XML-RPC specification)
+from xmlrpclib import ServerProxy, Error
+
+# server = ServerProxy("http://localhost:8000") # local server
+server = ServerProxy("http://betty.userland.com")
+
+print server
+
+try:
+    print server.examples.getStateName(41)
+except Error, v:
+    print "ERROR", v
+\end{verbatim}
+
+To access an XML-RPC server through a proxy, you need to define 
+a custom transport.  The following example, 
+written by NoboNobo, % fill in original author's name if we ever learn it
+shows how:
+
+% Example taken from http://lowlife.jp/nobonobo/wiki/xmlrpcwithproxy.html
+\begin{verbatim}
+import xmlrpclib, httplib
+
+class ProxiedTransport(xmlrpclib.Transport):
+    def set_proxy(self, proxy):
+        self.proxy = proxy
+    def make_connection(self, host):
+        self.realhost = host
+	h = httplib.HTTP(self.proxy)
+	return h
+    def send_request(self, connection, handler, request_body):
+        connection.putrequest("POST", 'http://%s%s' % (self.realhost, handler))
+    def send_host(self, connection, host):
+        connection.putheader('Host', self.realhost)
+
+p = ProxiedTransport()
+p.set_proxy('proxy-server:8080')
+server = xmlrpclib.Server('http://time.xmlrpc.com/RPC2', transport=p)
+print server.currentTime.getCurrentTime()
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/libzipfile.tex
===================================================================
--- vendor/Python/current/Doc/lib/libzipfile.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libzipfile.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,309 @@
+\section{\module{zipfile} ---
+         Work with ZIP archives}
+
+\declaremodule{standard}{zipfile}
+\modulesynopsis{Read and write ZIP-format archive files.}
+\moduleauthor{James C. Ahlstrom}{jim at interet.com}
+\sectionauthor{James C. Ahlstrom}{jim at interet.com}
+% LaTeX markup by Fred L. Drake, Jr. <fdrake at acm.org>
+
+\versionadded{1.6}
+
+The ZIP file format is a common archive and compression standard.
+This module provides tools to create, read, write, append, and list a
+ZIP file.  Any advanced use of this module will require an
+understanding of the format, as defined in
+\citetitle[http://www.pkware.com/business_and_developers/developer/appnote/]
+{PKZIP Application Note}.
+
+This module does not currently handle ZIP files which have appended
+comments, or multi-disk ZIP files. It can handle ZIP files that use the 
+ZIP64 extensions (that is ZIP files that are more than 4 GByte in size).
+
+The available attributes of this module are:
+
+\begin{excdesc}{error}
+  The error raised for bad ZIP files.
+\end{excdesc}
+
+\begin{excdesc}{LargeZipFile}
+  The error raised when a ZIP file would require ZIP64 functionality but that
+  has not been enabled.
+\end{excdesc}
+
+\begin{classdesc*}{ZipFile}
+  The class for reading and writing ZIP files.  See
+  ``\citetitle{ZipFile Objects}'' (section \ref{zipfile-objects}) for
+  constructor details.
+\end{classdesc*}
+
+\begin{classdesc*}{PyZipFile}
+  Class for creating ZIP archives containing Python libraries.
+\end{classdesc*}
+
+\begin{classdesc}{ZipInfo}{\optional{filename\optional{, date_time}}}
+  Class used to represent information about a member of an archive.
+  Instances of this class are returned by the \method{getinfo()} and
+  \method{infolist()} methods of \class{ZipFile} objects.  Most users
+  of the \module{zipfile} module will not need to create these, but
+  only use those created by this module.
+  \var{filename} should be the full name of the archive member, and
+  \var{date_time} should be a tuple containing six fields which
+  describe the time of the last modification to the file; the fields
+  are described in section \ref{zipinfo-objects}, ``ZipInfo Objects.''
+\end{classdesc}
+
+\begin{funcdesc}{is_zipfile}{filename}
+  Returns \code{True} if \var{filename} is a valid ZIP file based on its magic
+  number, otherwise returns \code{False}.  This module does not currently
+  handle ZIP files which have appended comments.
+\end{funcdesc}
+
+\begin{datadesc}{ZIP_STORED}
+  The numeric constant for an uncompressed archive member.
+\end{datadesc}
+
+\begin{datadesc}{ZIP_DEFLATED}
+  The numeric constant for the usual ZIP compression method.  This
+  requires the zlib module.  No other compression methods are
+  currently supported.
+\end{datadesc}
+
+
+\begin{seealso}
+  \seetitle[http://www.pkware.com/business_and_developers/developer/appnote/]
+           {PKZIP Application Note}{Documentation on the ZIP file format by
+            Phil Katz, the creator of the format and algorithms used.}
+
+  \seetitle[http://www.info-zip.org/pub/infozip/]{Info-ZIP Home Page}{
+            Information about the Info-ZIP project's ZIP archive
+            programs and development libraries.}
+\end{seealso}
+
+
+\subsection{ZipFile Objects \label{zipfile-objects}}
+
+\begin{classdesc}{ZipFile}{file\optional{, mode\optional{, compression\optional{, allowZip64}}}} 
+  Open a ZIP file, where \var{file} can be either a path to a file
+  (a string) or a file-like object.  The \var{mode} parameter
+  should be \code{'r'} to read an existing file, \code{'w'} to
+  truncate and write a new file, or \code{'a'} to append to an
+  existing file.  For \var{mode} is \code{'a'} and \var{file}
+  refers to an existing ZIP file, then additional files are added to
+  it.  If \var{file} does not refer to a ZIP file, then a new ZIP
+  archive is appended to the file.  This is meant for adding a ZIP
+  archive to another file, such as \file{python.exe}.  Using
+
+\begin{verbatim}
+cat myzip.zip >> python.exe
+\end{verbatim}
+
+  also works, and at least \program{WinZip} can read such files.
+  \var{compression} is the ZIP compression method to use when writing
+  the archive, and should be \constant{ZIP_STORED} or
+  \constant{ZIP_DEFLATED}; unrecognized values will cause
+  \exception{RuntimeError} to be raised.  If \constant{ZIP_DEFLATED}
+  is specified but the \refmodule{zlib} module is not available,
+  \exception{RuntimeError} is also raised.  The default is
+  \constant{ZIP_STORED}. 
+  If \var{allowZip64} is \code{True} zipfile will create ZIP files that use
+  the ZIP64 extensions when the zipfile is larger than 2 GB. If it is 
+  false (the default) \module{zipfile} will raise an exception when the
+  ZIP file would require ZIP64 extensions. ZIP64 extensions are disabled by
+  default because the default \program{zip} and \program{unzip} commands on
+  \UNIX{} (the InfoZIP utilities) don't support these extensions.
+\end{classdesc}
+
+\begin{methoddesc}{close}{}
+  Close the archive file.  You must call \method{close()} before
+  exiting your program or essential records will not be written. 
+\end{methoddesc}
+
+\begin{methoddesc}{getinfo}{name}
+  Return a \class{ZipInfo} object with information about the archive
+  member \var{name}.
+\end{methoddesc}
+
+\begin{methoddesc}{infolist}{}
+  Return a list containing a \class{ZipInfo} object for each member of
+  the archive.  The objects are in the same order as their entries in
+  the actual ZIP file on disk if an existing archive was opened.
+\end{methoddesc}
+
+\begin{methoddesc}{namelist}{}
+  Return a list of archive members by name.
+\end{methoddesc}
+
+\begin{methoddesc}{printdir}{}
+  Print a table of contents for the archive to \code{sys.stdout}.
+\end{methoddesc}
+
+\begin{methoddesc}{read}{name}
+  Return the bytes of the file in the archive.  The archive must be
+  open for read or append.
+\end{methoddesc}
+
+\begin{methoddesc}{testzip}{}
+  Read all the files in the archive and check their CRC's and file
+  headers.  Return the name of the first bad file, or else return \code{None}.
+\end{methoddesc}
+
+\begin{methoddesc}{write}{filename\optional{, arcname\optional{,
+                          compress_type}}}
+  Write the file named \var{filename} to the archive, giving it the
+  archive name \var{arcname} (by default, this will be the same as
+  \var{filename}, but without a drive letter and with leading path
+  separators removed).  If given, \var{compress_type} overrides the
+  value given for the \var{compression} parameter to the constructor
+  for the new entry.  The archive must be open with mode \code{'w'}
+  or \code{'a'}.
+  
+  \note{There is no official file name encoding for ZIP files.
+  If you have unicode file names, please convert them to byte strings
+  in your desired encoding before passing them to \method{write()}.
+  WinZip interprets all file names as encoded in CP437, also known
+  as DOS Latin.}
+
+  \note{Archive names should be relative to the archive root, that is,
+        they should not start with a path separator.}
+\end{methoddesc}
+
+\begin{methoddesc}{writestr}{zinfo_or_arcname, bytes}
+  Write the string \var{bytes} to the archive; \var{zinfo_or_arcname}
+  is either the file name it will be given in the archive, or a
+  \class{ZipInfo} instance.  If it's an instance, at least the
+  filename, date, and time must be given.  If it's a name, the date
+  and time is set to the current date and time. The archive must be
+  opened with mode \code{'w'} or \code{'a'}.
+\end{methoddesc}
+
+
+The following data attribute is also available:
+
+\begin{memberdesc}{debug}
+  The level of debug output to use.  This may be set from \code{0}
+  (the default, no output) to \code{3} (the most output).  Debugging
+  information is written to \code{sys.stdout}.
+\end{memberdesc}
+
+
+\subsection{PyZipFile Objects \label{pyzipfile-objects}}
+
+The \class{PyZipFile} constructor takes the same parameters as the
+\class{ZipFile} constructor.  Instances have one method in addition to
+those of \class{ZipFile} objects.
+
+\begin{methoddesc}[PyZipFile]{writepy}{pathname\optional{, basename}}
+  Search for files \file{*.py} and add the corresponding file to the
+  archive.  The corresponding file is a \file{*.pyo} file if
+  available, else a \file{*.pyc} file, compiling if necessary.  If the
+  pathname is a file, the filename must end with \file{.py}, and just
+  the (corresponding \file{*.py[co]}) file is added at the top level
+  (no path information).  If it is a directory, and the directory is
+  not a package directory, then all the files \file{*.py[co]} are
+  added at the top level.  If the directory is a package directory,
+  then all \file{*.py[oc]} are added under the package name as a file
+  path, and if any subdirectories are package directories, all of
+  these are added recursively.  \var{basename} is intended for
+  internal use only.  The \method{writepy()} method makes archives
+  with file names like this:
+
+\begin{verbatim}
+    string.pyc                                # Top level name 
+    test/__init__.pyc                         # Package directory 
+    test/testall.pyc                          # Module test.testall
+    test/bogus/__init__.pyc                   # Subpackage directory 
+    test/bogus/myfile.pyc                     # Submodule test.bogus.myfile
+\end{verbatim}
+\end{methoddesc}
+
+
+\subsection{ZipInfo Objects \label{zipinfo-objects}}
+
+Instances of the \class{ZipInfo} class are returned by the
+\method{getinfo()} and \method{infolist()} methods of
+\class{ZipFile} objects.  Each object stores information about a
+single member of the ZIP archive.
+
+Instances have the following attributes:
+
+\begin{memberdesc}[ZipInfo]{filename}
+  Name of the file in the archive.
+\end{memberdesc}
+
+\begin{memberdesc}[ZipInfo]{date_time}
+  The time and date of the last modification to the archive
+  member.  This is a tuple of six values:
+
+\begin{tableii}{c|l}{code}{Index}{Value}
+  \lineii{0}{Year}
+  \lineii{1}{Month (one-based)}
+  \lineii{2}{Day of month (one-based)}
+  \lineii{3}{Hours (zero-based)}
+  \lineii{4}{Minutes (zero-based)}
+  \lineii{5}{Seconds (zero-based)}
+\end{tableii}
+\end{memberdesc}
+
+\begin{memberdesc}[ZipInfo]{compress_type}
+  Type of compression for the archive member.
+\end{memberdesc}
+
+\begin{memberdesc}[ZipInfo]{comment}
+  Comment for the individual archive member.
+\end{memberdesc}
+
+\begin{memberdesc}[ZipInfo]{extra}
+  Expansion field data.  The
+  \citetitle[http://www.pkware.com/business_and_developers/developer/appnote/]
+  {PKZIP Application Note} contains some comments on the internal
+  structure of the data contained in this string.
+\end{memberdesc}
+
+\begin{memberdesc}[ZipInfo]{create_system}
+  System which created ZIP archive.
+\end{memberdesc}
+
+\begin{memberdesc}[ZipInfo]{create_version}
+  PKZIP version which created ZIP archive.
+\end{memberdesc}
+
+\begin{memberdesc}[ZipInfo]{extract_version}
+  PKZIP version needed to extract archive.
+\end{memberdesc}
+
+\begin{memberdesc}[ZipInfo]{reserved}
+  Must be zero.
+\end{memberdesc}
+
+\begin{memberdesc}[ZipInfo]{flag_bits}
+  ZIP flag bits.
+\end{memberdesc}
+
+\begin{memberdesc}[ZipInfo]{volume}
+  Volume number of file header.
+\end{memberdesc}
+
+\begin{memberdesc}[ZipInfo]{internal_attr}
+  Internal attributes.
+\end{memberdesc}
+
+\begin{memberdesc}[ZipInfo]{external_attr}
+ External file attributes.
+\end{memberdesc}
+
+\begin{memberdesc}[ZipInfo]{header_offset}
+  Byte offset to the file header.
+\end{memberdesc}
+
+\begin{memberdesc}[ZipInfo]{CRC}
+  CRC-32 of the uncompressed file.
+\end{memberdesc}
+
+\begin{memberdesc}[ZipInfo]{compress_size}
+  Size of the compressed data.
+\end{memberdesc}
+
+\begin{memberdesc}[ZipInfo]{file_size}
+  Size of the uncompressed file.
+\end{memberdesc}

Added: vendor/Python/current/Doc/lib/libzipimport.tex
===================================================================
--- vendor/Python/current/Doc/lib/libzipimport.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libzipimport.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,133 @@
+\section{\module{zipimport} ---
+         Import modules from Zip archives}
+
+\declaremodule{standard}{zipimport}
+\modulesynopsis{support for importing Python modules from ZIP archives.}
+\moduleauthor{Just van Rossum}{just at letterror.com}
+
+\versionadded{2.3}
+
+This module adds the ability to import Python modules (\file{*.py},
+\file{*.py[co]}) and packages from ZIP-format archives. It is usually
+not needed to use the \module{zipimport} module explicitly; it is
+automatically used by the builtin \keyword{import} mechanism for
+\code{sys.path} items that are paths to ZIP archives.
+
+Typically, \code{sys.path} is a list of directory names as strings.  This
+module also allows an item of \code{sys.path} to be a string naming a ZIP
+file archive. The ZIP archive can contain a subdirectory structure to
+support package imports, and a path within the archive can be specified to
+only import from a subdirectory.  For example, the path
+\file{/tmp/example.zip/lib/} would only import from the
+\file{lib/} subdirectory within the archive.
+
+Any files may be present in the ZIP archive, but only files \file{.py} and
+\file{.py[co]} are available for import.  ZIP import of dynamic modules
+(\file{.pyd}, \file{.so}) is disallowed. Note that if an archive only
+contains \file{.py} files, Python will not attempt to modify the archive
+by adding the corresponding \file{.pyc} or \file{.pyo} file, meaning that
+if a ZIP archive doesn't contain \file{.pyc} files, importing may be rather
+slow.
+
+Using the built-in \function{reload()} function will
+fail if called on a module loaded from a ZIP archive; it is unlikely that
+\function{reload()} would be needed, since this would imply that the ZIP
+has been altered during runtime.
+
+The available attributes of this module are:
+
+\begin{excdesc}{ZipImportError}
+  Exception raised by zipimporter objects. It's a subclass of
+  \exception{ImportError}, so it can be caught as \exception{ImportError},
+  too.
+\end{excdesc}
+
+\begin{classdesc*}{zipimporter}
+  The class for importing ZIP files.  See
+  ``\citetitle{zipimporter Objects}'' (section \ref{zipimporter-objects})
+  for constructor details.
+\end{classdesc*}
+
+
+\begin{seealso}
+  \seetitle[http://www.pkware.com/business_and_developers/developer/appnote/]
+           {PKZIP Application Note}{Documentation on the ZIP file format by
+            Phil Katz, the creator of the format and algorithms used.}
+
+  \seepep{0273}{Import Modules from Zip Archives}{Written by James C.
+          Ahlstrom, who also provided an implementation. Python 2.3
+          follows the specification in PEP 273, but uses an
+          implementation written by Just van Rossum that uses the import
+          hooks described in PEP 302.}
+
+  \seepep{0302}{New Import Hooks}{The PEP to add the import hooks that help
+          this module work.}
+\end{seealso}
+
+
+\subsection{zipimporter Objects \label{zipimporter-objects}}
+
+\begin{classdesc}{zipimporter}{archivepath} 
+  Create a new zipimporter instance. \var{archivepath} must be a path to
+  a zipfile.  \exception{ZipImportError} is raised if \var{archivepath}
+  doesn't point to a valid ZIP archive.
+\end{classdesc}
+
+\begin{methoddesc}{find_module}{fullname\optional{, path}}
+  Search for a module specified by \var{fullname}. \var{fullname} must be
+  the fully qualified (dotted) module name. It returns the zipimporter
+  instance itself if the module was found, or \constant{None} if it wasn't.
+  The optional \var{path} argument is ignored---it's there for 
+  compatibility with the importer protocol.
+\end{methoddesc}
+
+\begin{methoddesc}{get_code}{fullname}
+  Return the code object for the specified module. Raise
+  \exception{ZipImportError} if the module couldn't be found.
+\end{methoddesc}
+
+\begin{methoddesc}{get_data}{pathname}
+  Return the data associated with \var{pathname}. Raise \exception{IOError}
+  if the file wasn't found.
+\end{methoddesc}
+
+\begin{methoddesc}{get_source}{fullname}
+  Return the source code for the specified module. Raise
+  \exception{ZipImportError} if the module couldn't be found, return
+  \constant{None} if the archive does contain the module, but has
+  no source for it.
+\end{methoddesc}
+
+\begin{methoddesc}{is_package}{fullname}
+  Return True if the module specified by \var{fullname} is a package.
+  Raise \exception{ZipImportError} if the module couldn't be found.
+\end{methoddesc}
+
+\begin{methoddesc}{load_module}{fullname}
+  Load the module specified by \var{fullname}. \var{fullname} must be the
+  fully qualified (dotted) module name. It returns the imported
+  module, or raises \exception{ZipImportError} if it wasn't found.
+\end{methoddesc}
+
+\subsection{Examples}
+\nodename{zipimport Examples}
+
+Here is an example that imports a module from a ZIP archive - note that
+the \module{zipimport} module is not explicitly used.
+
+\begin{verbatim}
+$ unzip -l /tmp/example.zip
+Archive:  /tmp/example.zip
+  Length     Date   Time    Name
+ --------    ----   ----    ----
+     8467  11-26-02 22:30   jwzthreading.py
+ --------                   -------
+     8467                   1 file
+$ ./python
+Python 2.3 (#1, Aug 1 2003, 19:54:32) 
+>>> import sys
+>>> sys.path.insert(0, '/tmp/example.zip')  # Add .zip file to front of path
+>>> import jwzthreading
+>>> jwzthreading.__file__
+'/tmp/example.zip/jwzthreading.py'
+\end{verbatim}

Added: vendor/Python/current/Doc/lib/libzlib.tex
===================================================================
--- vendor/Python/current/Doc/lib/libzlib.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/libzlib.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,197 @@
+\section{\module{zlib} ---
+         Compression compatible with \program{gzip}}
+
+\declaremodule{builtin}{zlib}
+\modulesynopsis{Low-level interface to compression and decompression
+                routines compatible with \program{gzip}.}
+
+
+For applications that require data compression, the functions in this
+module allow compression and decompression, using the zlib library.
+The zlib library has its own home page at \url{http://www.zlib.net}.  
+There are known incompatibilities between the Python module and
+versions of the zlib library earlier than 1.1.3; 1.1.3 has a security
+vulnerability, so we recommend using 1.1.4 or later.
+
+zlib's functions have many options and often need to be used in a
+particular order.  This documentation doesn't attempt to cover all of
+the permutations; consult the zlib manual at
+\url{http://www.zlib.net/manual.html} for authoritative information.
+
+The available exception and functions in this module are:
+
+\begin{excdesc}{error}
+  Exception raised on compression and decompression errors.
+\end{excdesc}
+
+
+\begin{funcdesc}{adler32}{string\optional{, value}}
+   Computes a Adler-32 checksum of \var{string}.  (An Adler-32
+   checksum is almost as reliable as a CRC32 but can be computed much
+   more quickly.)  If \var{value} is present, it is used as the
+   starting value of the checksum; otherwise, a fixed default value is
+   used.  This allows computing a running checksum over the
+   concatenation of several input strings.  The algorithm is not
+   cryptographically strong, and should not be used for
+   authentication or digital signatures.  Since the algorithm is
+   designed for use as a checksum algorithm, it is not suitable for
+   use as a general hash algorithm.
+\end{funcdesc}
+
+\begin{funcdesc}{compress}{string\optional{, level}}
+  Compresses the data in \var{string}, returning a string contained
+  compressed data.  \var{level} is an integer from \code{1} to
+  \code{9} controlling the level of compression; \code{1} is fastest
+  and produces the least compression, \code{9} is slowest and produces
+  the most.  The default value is \code{6}.  Raises the
+  \exception{error} exception if any error occurs.
+\end{funcdesc}
+
+\begin{funcdesc}{compressobj}{\optional{level}}
+  Returns a compression object, to be used for compressing data streams
+  that won't fit into memory at once.  \var{level} is an integer from
+  \code{1} to \code{9} controlling the level of compression; \code{1} is
+  fastest and produces the least compression, \code{9} is slowest and
+  produces the most.  The default value is \code{6}.
+\end{funcdesc}
+
+\begin{funcdesc}{crc32}{string\optional{, value}}
+  Computes a CRC (Cyclic Redundancy Check)%
+  \index{Cyclic Redundancy Check}
+  \index{checksum!Cyclic Redundancy Check}
+  checksum of \var{string}. If
+  \var{value} is present, it is used as the starting value of the
+  checksum; otherwise, a fixed default value is used.  This allows
+  computing a running checksum over the concatenation of several
+  input strings.  The algorithm is not cryptographically strong, and
+  should not be used for authentication or digital signatures.  Since
+  the algorithm is designed for use as a checksum algorithm, it is not
+  suitable for use as a general hash algorithm.
+\end{funcdesc}
+
+\begin{funcdesc}{decompress}{string\optional{, wbits\optional{, bufsize}}}
+  Decompresses the data in \var{string}, returning a string containing
+  the uncompressed data.  The \var{wbits} parameter controls the size of
+  the window buffer.  If \var{bufsize} is given, it is used as the
+  initial size of the output buffer.  Raises the \exception{error}
+  exception if any error occurs.
+
+The absolute value of \var{wbits} is the base two logarithm of the
+size of the history buffer (the ``window size'') used when compressing
+data.  Its absolute value should be between 8 and 15 for the most
+recent versions of the zlib library, larger values resulting in better
+compression at the expense of greater memory usage.  The default value
+is 15.  When \var{wbits} is negative, the standard
+\program{gzip} header is suppressed; this is an undocumented feature
+of the zlib library, used for compatibility with \program{unzip}'s
+compression file format.
+
+\var{bufsize} is the initial size of the buffer used to hold
+decompressed data.  If more space is required, the buffer size will be
+increased as needed, so you don't have to get this value exactly
+right; tuning it will only save a few calls to \cfunction{malloc()}.  The
+default size is 16384.
+   
+\end{funcdesc}
+
+\begin{funcdesc}{decompressobj}{\optional{wbits}}
+  Returns a decompression object, to be used for decompressing data
+  streams that won't fit into memory at once.  The \var{wbits}
+  parameter controls the size of the window buffer.
+\end{funcdesc}
+
+Compression objects support the following methods:
+
+\begin{methoddesc}[Compress]{compress}{string}
+Compress \var{string}, returning a string containing compressed data
+for at least part of the data in \var{string}.  This data should be
+concatenated to the output produced by any preceding calls to the
+\method{compress()} method.  Some input may be kept in internal buffers
+for later processing.
+\end{methoddesc}
+
+\begin{methoddesc}[Compress]{flush}{\optional{mode}}
+All pending input is processed, and a string containing the remaining
+compressed output is returned.  \var{mode} can be selected from the
+constants \constant{Z_SYNC_FLUSH},  \constant{Z_FULL_FLUSH},  or 
+\constant{Z_FINISH}, defaulting to \constant{Z_FINISH}.  \constant{Z_SYNC_FLUSH} and 
+\constant{Z_FULL_FLUSH} allow compressing further strings of data, while
+\constant{Z_FINISH} finishes the compressed stream and 
+prevents compressing any more data.  After calling
+\method{flush()} with \var{mode} set to \constant{Z_FINISH}, the
+\method{compress()} method cannot be called again; the only realistic
+action is to delete the object.  
+\end{methoddesc}
+
+\begin{methoddesc}[Compress]{copy}{}
+Returns a copy of the compression object.  This can be used to efficiently
+compress a set of data that share a common initial prefix.
+\versionadded{2.5}
+\end{methoddesc}
+
+Decompression objects support the following methods, and two attributes:
+
+\begin{memberdesc}{unused_data}
+A string which contains any bytes past the end of the compressed data.
+That is, this remains \code{""} until the last byte that contains
+compression data is available.  If the whole string turned out to
+contain compressed data, this is \code{""}, the empty string.
+
+The only way to determine where a string of compressed data ends is by
+actually decompressing it.  This means that when compressed data is
+contained part of a larger file, you can only find the end of it by
+reading data and feeding it followed by some non-empty string into a
+decompression object's \method{decompress} method until the
+\member{unused_data} attribute is no longer the empty string.
+\end{memberdesc}
+
+\begin{memberdesc}{unconsumed_tail}
+A string that contains any data that was not consumed by the last
+\method{decompress} call because it exceeded the limit for the
+uncompressed data buffer.  This data has not yet been seen by the zlib
+machinery, so you must feed it (possibly with further data
+concatenated to it) back to a subsequent \method{decompress} method
+call in order to get correct output.
+\end{memberdesc}
+
+
+\begin{methoddesc}[Decompress]{decompress}{string\optional{, max_length}}
+Decompress \var{string}, returning a string containing the
+uncompressed data corresponding to at least part of the data in
+\var{string}.  This data should be concatenated to the output produced
+by any preceding calls to the
+\method{decompress()} method.  Some of the input data may be preserved
+in internal buffers for later processing.
+
+If the optional parameter \var{max_length} is supplied then the return value
+will be no longer than \var{max_length}. This may mean that not all of the
+compressed input can be processed; and unconsumed data will be stored
+in the attribute \member{unconsumed_tail}. This string must be passed
+to a subsequent call to \method{decompress()} if decompression is to
+continue.  If \var{max_length} is not supplied then the whole input is
+decompressed, and \member{unconsumed_tail} is an empty string.
+\end{methoddesc}
+
+\begin{methoddesc}[Decompress]{flush}{\optional{length}}
+All pending input is processed, and a string containing the remaining
+uncompressed output is returned.  After calling \method{flush()}, the
+\method{decompress()} method cannot be called again; the only realistic
+action is to delete the object.
+
+The optional parameter \var{length} sets the initial size of the
+output buffer.
+\end{methoddesc}
+
+\begin{methoddesc}[Decompress]{copy}{}
+Returns a copy of the decompression object.  This can be used to save the
+state of the decompressor midway through the data stream in order to speed up
+random seeks into the stream at a future point.
+\versionadded{2.5}
+\end{methoddesc}
+
+\begin{seealso}
+  \seemodule{gzip}{Reading and writing \program{gzip}-format files.}
+  \seeurl{http://www.zlib.net}{The zlib library home page.}
+  \seeurl{http://www.zlib.net/manual.html}{The zlib manual explains 
+    the semantics and usage of the library's many functions.}
+\end{seealso}

Added: vendor/Python/current/Doc/lib/markup.tex
===================================================================
--- vendor/Python/current/Doc/lib/markup.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/markup.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,29 @@
+\chapter{Structured Markup Processing Tools
+         \label{markup}}
+
+Python supports a variety of modules to work with various forms of
+structured data markup.  This includes modules to work with the
+Standard Generalized Markup Language (SGML) and the Hypertext Markup
+Language (HTML), and several interfaces for working with the
+Extensible Markup Language (XML).
+
+It is important to note that modules in the \module{xml} package
+require that there be at least one SAX-compliant XML parser available.
+Starting with Python 2.3, the Expat parser is included with Python, so
+the \refmodule{xml.parsers.expat} module will always be available.
+You may still want to be aware of the \ulink{PyXML add-on
+package}{http://pyxml.sourceforge.net/}; that package provides an
+extended set of XML libraries for Python.
+
+The documentation for the \module{xml.dom} and \module{xml.sax}
+packages are the definition of the Python bindings for the DOM and SAX
+interfaces.
+
+\localmoduletable
+
+\begin{seealso}
+  \seetitle[http://pyxml.sourceforge.net/]
+           {Python/XML Libraries}
+           {Home page for the PyXML package, containing an extension
+            of \module{xml} package bundled with Python.}
+\end{seealso}

Added: vendor/Python/current/Doc/lib/mimelib.tex
===================================================================
--- vendor/Python/current/Doc/lib/mimelib.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/mimelib.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,65 @@
+% This document is largely a stub used to allow the email package docs
+% to be formatted separately from the rest of the Python
+% documentation.  This allows the documentation to be released
+% independently of the rest of Python since the email package is being
+% maintained for multiple Python versions, and on an accelerated
+% schedule.
+
+\documentclass{howto}
+
+\title{email Package Reference}
+\author{Barry Warsaw}
+\authoraddress{\email{barry at python.org}}
+
+\date{\today}
+\release{4.0}			% software release, not documentation
+\setreleaseinfo{}		% empty for final release
+\setshortversion{4.0}		% major.minor only for software
+
+\begin{document}
+
+\maketitle
+
+\begin{abstract}
+  The \module{email} package provides classes and utilities to create,
+  parse, generate, and modify email messages, conforming to all the
+  relevant email and MIME related RFCs.
+\end{abstract}
+
+% The ugly "%begin{latexonly}" pseudo-environment suppresses the table
+% of contents for HTML generation.
+%
+%begin{latexonly}
+\tableofcontents
+%end{latexonly}
+
+\section{Introduction}
+The \module{email} package provides classes and utilities to create,
+parse, generate, and modify email messages, conforming to all the
+relevant email and MIME related RFCs.
+
+This document describes version 4.0 of the \module{email} package, which is
+distributed with Python 2.5 and is available as a standalone distutils-based
+package for use with earlier Python versions.  \module{email} 4.0 is not
+compatible with Python versions earlier than 2.3.  For more information about
+the \module{email} package, including download links and mailing lists, see
+\ulink{Python's email SIG}{http://www.python.org/sigs/email-sig}.
+
+The documentation that follows was written for the Python project, so
+if you're reading this as part of the standalone \module{email}
+package documentation, there are a few notes to be aware of:
+
+\begin{itemize}
+\item Deprecation and ``version added'' notes are relative to the
+      Python version a feature was added or deprecated.  See
+      the package history in section \ref{email-pkg-history} for details.
+
+\item If you're reading this documentation as part of the
+      standalone \module{email} package, some of the internal links to
+      other sections of the Python standard library may not resolve.
+
+\end{itemize}
+
+\input{email}
+
+\end{document}

Added: vendor/Python/current/Doc/lib/minidom-example.py
===================================================================
--- vendor/Python/current/Doc/lib/minidom-example.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/minidom-example.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,64 @@
+import xml.dom.minidom
+
+document = """\
+<slideshow>
+<title>Demo slideshow</title>
+<slide><title>Slide title</title>
+<point>This is a demo</point>
+<point>Of a program for processing slides</point>
+</slide>
+
+<slide><title>Another demo slide</title>
+<point>It is important</point>
+<point>To have more than</point>
+<point>one slide</point>
+</slide>
+</slideshow>
+"""
+
+dom = xml.dom.minidom.parseString(document)
+
+def getText(nodelist):
+    rc = ""
+    for node in nodelist:
+        if node.nodeType == node.TEXT_NODE:
+            rc = rc + node.data
+    return rc
+
+def handleSlideshow(slideshow):
+    print "<html>"
+    handleSlideshowTitle(slideshow.getElementsByTagName("title")[0])
+    slides = slideshow.getElementsByTagName("slide")
+    handleToc(slides)
+    handleSlides(slides)
+    print "</html>"
+
+def handleSlides(slides):
+    for slide in slides:
+        handleSlide(slide)
+
+def handleSlide(slide):
+    handleSlideTitle(slide.getElementsByTagName("title")[0])
+    handlePoints(slide.getElementsByTagName("point"))
+
+def handleSlideshowTitle(title):
+    print "<title>%s</title>" % getText(title.childNodes)
+
+def handleSlideTitle(title):
+    print "<h2>%s</h2>" % getText(title.childNodes)
+
+def handlePoints(points):
+    print "<ul>"
+    for point in points:
+        handlePoint(point)
+    print "</ul>"
+
+def handlePoint(point):
+    print "<li>%s</li>" % getText(point.childNodes)
+
+def handleToc(slides):
+    for slide in slides:
+        title = slide.getElementsByTagName("title")[0]
+        print "<p>%s</p>" % getText(title.childNodes)
+
+handleSlideshow(dom)

Added: vendor/Python/current/Doc/lib/modules.tex
===================================================================
--- vendor/Python/current/Doc/lib/modules.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/modules.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,9 @@
+\chapter{Importing Modules}
+\label{modules}
+
+The modules described in this chapter provide new ways to import other
+Python modules and hooks for customizing the import process.
+
+The full list of modules described in this chapter is:
+
+\localmoduletable

Added: vendor/Python/current/Doc/lib/netdata.tex
===================================================================
--- vendor/Python/current/Doc/lib/netdata.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/netdata.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,6 @@
+\chapter{Internet Data Handling \label{netdata}}
+
+This chapter describes modules which support handling data formats
+commonly used on the Internet.
+
+\localmoduletable

Added: vendor/Python/current/Doc/lib/numeric.tex
===================================================================
--- vendor/Python/current/Doc/lib/numeric.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/numeric.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,13 @@
+\chapter{Numeric and Mathematical Modules}
+\label{numeric}
+
+The modules described in this chapter provide
+numeric and math-related functions and data types.
+The \module{math} and \module{cmath} contain 
+various mathematical functions for floating-point and complex numbers.
+For users more interested in decimal accuracy than in speed, the 
+\module{decimal} module supports exact representations of  decimal numbers.
+
+The following modules are documented in this chapter:
+
+\localmoduletable

Added: vendor/Python/current/Doc/lib/persistence.tex
===================================================================
--- vendor/Python/current/Doc/lib/persistence.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/persistence.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,15 @@
+\chapter{Data Persistence}
+\label{persistence}
+
+The modules described in this chapter support storing Python data in a
+persistent form on disk.  The \module{pickle} and \module{marshal}
+modules can turn many Python data types into a stream of bytes and
+then recreate the objects from the bytes.  The various DBM-related
+modules support a family of hash-based file formats that store a
+mapping of strings to other strings.  The \module{bsddb} module also
+provides such disk-based string-to-string mappings based on hashing,
+and also supports B-Tree and record-based formats.
+
+The list of modules described in this chapter is:
+
+\localmoduletable

Added: vendor/Python/current/Doc/lib/required_1.py
===================================================================
--- vendor/Python/current/Doc/lib/required_1.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/required_1.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,20 @@
+import optparse
+
+class OptionParser (optparse.OptionParser):
+
+    def check_required (self, opt):
+        option = self.get_option(opt)
+
+        # Assumes the option's 'default' is set to None!
+        if getattr(self.values, option.dest) is None:
+            self.error("%s option not supplied" % option)
+
+
+parser = OptionParser()
+parser.add_option("-v", action="count", dest="verbose")
+parser.add_option("-f", "--file", default=None)
+(options, args) = parser.parse_args()
+
+print "verbose:", options.verbose
+print "file:", options.file
+parser.check_required("-f")


Property changes on: vendor/Python/current/Doc/lib/required_1.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Doc/lib/required_2.py
===================================================================
--- vendor/Python/current/Doc/lib/required_2.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/required_2.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,41 @@
+import optparse
+
+class Option (optparse.Option):
+    ATTRS = optparse.Option.ATTRS + ['required']
+
+    def _check_required (self):
+        if self.required and not self.takes_value():
+            raise OptionError(
+                "required flag set for option that doesn't take a value",
+                 self)
+
+    # Make sure _check_required() is called from the constructor!
+    CHECK_METHODS = optparse.Option.CHECK_METHODS + [_check_required]
+
+    def process (self, opt, value, values, parser):
+        optparse.Option.process(self, opt, value, values, parser)
+        parser.option_seen[self] = 1
+
+
+class OptionParser (optparse.OptionParser):
+
+    def _init_parsing_state (self):
+        optparse.OptionParser._init_parsing_state(self)
+        self.option_seen = {}
+
+    def check_values (self, values, args):
+        for option in self.option_list:
+            if (isinstance(option, Option) and
+                option.required and
+                not self.option_seen.has_key(option)):
+                self.error("%s not supplied" % option)
+        return (values, args)
+
+
+parser = OptionParser(option_list=[
+    Option("-v", action="count", dest="verbose"),
+    Option("-f", "--file", required=1)])
+(options, args) = parser.parse_args()
+
+print "verbose:", options.verbose
+print "file:", options.file


Property changes on: vendor/Python/current/Doc/lib/required_2.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Doc/lib/sqlite3/adapter_datetime.py
===================================================================
--- vendor/Python/current/Doc/lib/sqlite3/adapter_datetime.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/sqlite3/adapter_datetime.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,14 @@
+import sqlite3
+import datetime, time
+
+def adapt_datetime(ts):
+    return time.mktime(ts.timetuple())
+
+sqlite3.register_adapter(datetime.datetime, adapt_datetime)
+
+con = sqlite3.connect(":memory:")
+cur = con.cursor()
+
+now = datetime.datetime.now()
+cur.execute("select ?", (now,))
+print cur.fetchone()[0]

Added: vendor/Python/current/Doc/lib/sqlite3/adapter_point_1.py
===================================================================
--- vendor/Python/current/Doc/lib/sqlite3/adapter_point_1.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/sqlite3/adapter_point_1.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,16 @@
+import sqlite3
+
+class Point(object):
+    def __init__(self, x, y):
+        self.x, self.y = x, y
+
+    def __conform__(self, protocol):
+        if protocol is sqlite3.PrepareProtocol:
+            return "%f;%f" % (self.x, self.y)
+
+con = sqlite3.connect(":memory:")
+cur = con.cursor()
+
+p = Point(4.0, -3.2)
+cur.execute("select ?", (p,))
+print cur.fetchone()[0]

Added: vendor/Python/current/Doc/lib/sqlite3/adapter_point_2.py
===================================================================
--- vendor/Python/current/Doc/lib/sqlite3/adapter_point_2.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/sqlite3/adapter_point_2.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,17 @@
+import sqlite3
+
+class Point(object):
+    def __init__(self, x, y):
+        self.x, self.y = x, y
+
+def adapt_point(point):
+    return "%f;%f" % (point.x, point.y)
+
+sqlite3.register_adapter(Point, adapt_point)
+
+con = sqlite3.connect(":memory:")
+cur = con.cursor()
+
+p = Point(4.0, -3.2)
+cur.execute("select ?", (p,))
+print cur.fetchone()[0]

Added: vendor/Python/current/Doc/lib/sqlite3/collation_reverse.py
===================================================================
--- vendor/Python/current/Doc/lib/sqlite3/collation_reverse.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/sqlite3/collation_reverse.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,15 @@
+import sqlite3
+
+def collate_reverse(string1, string2):
+    return -cmp(string1, string2)
+
+con = sqlite3.connect(":memory:")
+con.create_collation("reverse", collate_reverse)
+
+cur = con.cursor()
+cur.execute("create table test(x)")
+cur.executemany("insert into test(x) values (?)", [("a",), ("b",)])
+cur.execute("select x from test order by x collate reverse")
+for row in cur:
+    print row
+con.close()

Added: vendor/Python/current/Doc/lib/sqlite3/complete_statement.py
===================================================================
--- vendor/Python/current/Doc/lib/sqlite3/complete_statement.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/sqlite3/complete_statement.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,30 @@
+# A minimal SQLite shell for experiments
+
+import sqlite3
+
+con = sqlite3.connect(":memory:")
+con.isolation_level = None
+cur = con.cursor()
+
+buffer = ""
+
+print "Enter your SQL commands to execute in sqlite3."
+print "Enter a blank line to exit."
+
+while True:
+    line = raw_input()
+    if line == "":
+        break
+    buffer += line
+    if sqlite3.complete_statement(buffer):
+        try:
+            buffer = buffer.strip()
+            cur.execute(buffer)
+
+            if buffer.lstrip().upper().startswith("SELECT"):
+                print cur.fetchall()
+        except sqlite3.Error, e:
+            print "An error occurred:", e.args[0]
+        buffer = ""
+
+con.close()

Added: vendor/Python/current/Doc/lib/sqlite3/connect_db_1.py
===================================================================
--- vendor/Python/current/Doc/lib/sqlite3/connect_db_1.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/sqlite3/connect_db_1.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,3 @@
+import sqlite3
+
+con = sqlite3.connect("mydb")

Added: vendor/Python/current/Doc/lib/sqlite3/connect_db_2.py
===================================================================
--- vendor/Python/current/Doc/lib/sqlite3/connect_db_2.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/sqlite3/connect_db_2.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,3 @@
+import sqlite3
+
+con = sqlite3.connect(":memory:")

Added: vendor/Python/current/Doc/lib/sqlite3/converter_point.py
===================================================================
--- vendor/Python/current/Doc/lib/sqlite3/converter_point.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/sqlite3/converter_point.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,47 @@
+import sqlite3
+
+class Point(object):
+    def __init__(self, x, y):
+        self.x, self.y = x, y
+
+    def __repr__(self):
+        return "(%f;%f)" % (self.x, self.y)
+
+def adapt_point(point):
+    return "%f;%f" % (point.x, point.y)
+
+def convert_point(s):
+    x, y = map(float, s.split(";"))
+    return Point(x, y)
+
+# Register the adapter
+sqlite3.register_adapter(Point, adapt_point)
+
+# Register the converter
+sqlite3.register_converter("point", convert_point)
+
+p = Point(4.0, -3.2)
+
+#########################
+# 1) Using declared types
+con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_DECLTYPES)
+cur = con.cursor()
+cur.execute("create table test(p point)")
+
+cur.execute("insert into test(p) values (?)", (p,))
+cur.execute("select p from test")
+print "with declared types:", cur.fetchone()[0]
+cur.close()
+con.close()
+
+#######################
+# 1) Using column names
+con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_COLNAMES)
+cur = con.cursor()
+cur.execute("create table test(p)")
+
+cur.execute("insert into test(p) values (?)", (p,))
+cur.execute('select p as "p [point]" from test')
+print "with column names:", cur.fetchone()[0]
+cur.close()
+con.close()

Added: vendor/Python/current/Doc/lib/sqlite3/countcursors.py
===================================================================
--- vendor/Python/current/Doc/lib/sqlite3/countcursors.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/sqlite3/countcursors.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,15 @@
+import sqlite3
+
+class CountCursorsConnection(sqlite3.Connection):
+    def __init__(self, *args, **kwargs):
+        sqlite3.Connection.__init__(self, *args, **kwargs)
+        self.numcursors = 0
+
+    def cursor(self, *args, **kwargs):
+        self.numcursors += 1
+        return sqlite3.Connection.cursor(self, *args, **kwargs)
+
+con = sqlite3.connect(":memory:", factory=CountCursorsConnection)
+cur1 = con.cursor()
+cur2 = con.cursor()
+print con.numcursors

Added: vendor/Python/current/Doc/lib/sqlite3/createdb.py
===================================================================
--- vendor/Python/current/Doc/lib/sqlite3/createdb.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/sqlite3/createdb.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,28 @@
+# Not referenced from the documentation, but builds the database file the other
+# code snippets expect.
+
+import sqlite3
+import os
+
+DB_FILE = "mydb"
+
+if os.path.exists(DB_FILE):
+    os.remove(DB_FILE)
+
+con = sqlite3.connect(DB_FILE)
+cur = con.cursor()
+cur.execute("""
+        create table people
+        (
+          name_last      varchar(20),
+          age            integer
+        )
+        """)
+
+cur.execute("insert into people (name_last, age) values ('Yeltsin',   72)")
+cur.execute("insert into people (name_last, age) values ('Putin',     51)")
+
+con.commit()
+
+cur.close()
+con.close()

Added: vendor/Python/current/Doc/lib/sqlite3/execsql_fetchonerow.py
===================================================================
--- vendor/Python/current/Doc/lib/sqlite3/execsql_fetchonerow.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/sqlite3/execsql_fetchonerow.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,17 @@
+import sqlite3
+
+con = sqlite3.connect("mydb")
+
+cur = con.cursor()
+SELECT = "select name_last, age from people order by age, name_last"
+
+# 1. Iterate over the rows available from the cursor, unpacking the
+# resulting sequences to yield their elements (name_last, age):
+cur.execute(SELECT)
+for (name_last, age) in cur:
+    print '%s is %d years old.' % (name_last, age)
+
+# 2. Equivalently:
+cur.execute(SELECT)
+for row in cur:
+    print '%s is %d years old.' % (row[0], row[1])

Added: vendor/Python/current/Doc/lib/sqlite3/execsql_printall_1.py
===================================================================
--- vendor/Python/current/Doc/lib/sqlite3/execsql_printall_1.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/sqlite3/execsql_printall_1.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,13 @@
+import sqlite3
+
+# Create a connection to the database file "mydb":
+con = sqlite3.connect("mydb")
+
+# Get a Cursor object that operates in the context of Connection con:
+cur = con.cursor()
+
+# Execute the SELECT statement:
+cur.execute("select * from people order by age")
+
+# Retrieve all rows as a sequence and print that sequence:
+print cur.fetchall()

Added: vendor/Python/current/Doc/lib/sqlite3/execute_1.py
===================================================================
--- vendor/Python/current/Doc/lib/sqlite3/execute_1.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/sqlite3/execute_1.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,11 @@
+import sqlite3
+
+con = sqlite3.connect("mydb")
+
+cur = con.cursor()
+
+who = "Yeltsin"
+age = 72
+
+cur.execute("select name_last, age from people where name_last=? and age=?", (who, age))
+print cur.fetchone()

Added: vendor/Python/current/Doc/lib/sqlite3/execute_2.py
===================================================================
--- vendor/Python/current/Doc/lib/sqlite3/execute_2.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/sqlite3/execute_2.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,12 @@
+import sqlite3
+
+con = sqlite3.connect("mydb")
+
+cur = con.cursor()
+
+who = "Yeltsin"
+age = 72
+
+cur.execute("select name_last, age from people where name_last=:who and age=:age",
+    {"who": who, "age": age})
+print cur.fetchone()

Added: vendor/Python/current/Doc/lib/sqlite3/execute_3.py
===================================================================
--- vendor/Python/current/Doc/lib/sqlite3/execute_3.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/sqlite3/execute_3.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,12 @@
+import sqlite3
+
+con = sqlite3.connect("mydb")
+
+cur = con.cursor()
+
+who = "Yeltsin"
+age = 72
+
+cur.execute("select name_last, age from people where name_last=:who and age=:age",
+    locals())
+print cur.fetchone()

Added: vendor/Python/current/Doc/lib/sqlite3/executemany_1.py
===================================================================
--- vendor/Python/current/Doc/lib/sqlite3/executemany_1.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/sqlite3/executemany_1.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,24 @@
+import sqlite3
+
+class IterChars:
+    def __init__(self):
+        self.count = ord('a')
+
+    def __iter__(self):
+        return self
+
+    def next(self):
+        if self.count > ord('z'):
+            raise StopIteration
+        self.count += 1
+        return (chr(self.count - 1),) # this is a 1-tuple
+
+con = sqlite3.connect(":memory:")
+cur = con.cursor()
+cur.execute("create table characters(c)")
+
+theIter = IterChars()
+cur.executemany("insert into characters(c) values (?)", theIter)
+
+cur.execute("select c from characters")
+print cur.fetchall()

Added: vendor/Python/current/Doc/lib/sqlite3/executemany_2.py
===================================================================
--- vendor/Python/current/Doc/lib/sqlite3/executemany_2.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/sqlite3/executemany_2.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,15 @@
+import sqlite3
+
+def char_generator():
+    import string
+    for c in string.letters[:26]:
+        yield (c,)
+
+con = sqlite3.connect(":memory:")
+cur = con.cursor()
+cur.execute("create table characters(c)")
+
+cur.executemany("insert into characters(c) values (?)", char_generator())
+
+cur.execute("select c from characters")
+print cur.fetchall()

Added: vendor/Python/current/Doc/lib/sqlite3/executescript.py
===================================================================
--- vendor/Python/current/Doc/lib/sqlite3/executescript.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/sqlite3/executescript.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,24 @@
+import sqlite3
+
+con = sqlite3.connect(":memory:")
+cur = con.cursor()
+cur.executescript("""
+    create table person(
+        firstname,
+        lastname,
+        age
+    );
+
+    create table book(
+        title,
+        author,
+        published
+    );
+
+    insert into book(title, author, published)
+    values (
+        'Dirk Gently''s Holistic Detective Agency',
+        'Douglas Adams',
+        1987
+    );
+    """)

Added: vendor/Python/current/Doc/lib/sqlite3/insert_more_people.py
===================================================================
--- vendor/Python/current/Doc/lib/sqlite3/insert_more_people.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/sqlite3/insert_more_people.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,16 @@
+import sqlite3
+
+con = sqlite3.connect("mydb")
+
+cur = con.cursor()
+
+newPeople = (
+    ('Lebed'       , 53),
+    ('Zhirinovsky' , 57),
+  )
+
+for person in newPeople:
+    cur.execute("insert into people (name_last, age) values (?, ?)", person)
+
+# The changes will not be saved unless the transaction is committed explicitly:
+con.commit()

Added: vendor/Python/current/Doc/lib/sqlite3/md5func.py
===================================================================
--- vendor/Python/current/Doc/lib/sqlite3/md5func.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/sqlite3/md5func.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,11 @@
+import sqlite3
+import md5
+
+def md5sum(t):
+    return md5.md5(t).hexdigest()
+
+con = sqlite3.connect(":memory:")
+con.create_function("md5", 1, md5sum)
+cur = con.cursor()
+cur.execute("select md5(?)", ("foo",))
+print cur.fetchone()[0]

Added: vendor/Python/current/Doc/lib/sqlite3/mysumaggr.py
===================================================================
--- vendor/Python/current/Doc/lib/sqlite3/mysumaggr.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/sqlite3/mysumaggr.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,20 @@
+import sqlite3
+
+class MySum:
+    def __init__(self):
+        self.count = 0
+
+    def step(self, value):
+        self.count += value
+
+    def finalize(self):
+        return self.count
+
+con = sqlite3.connect(":memory:")
+con.create_aggregate("mysum", 1, MySum)
+cur = con.cursor()
+cur.execute("create table test(i)")
+cur.execute("insert into test(i) values (1)")
+cur.execute("insert into test(i) values (2)")
+cur.execute("select mysum(i) from test")
+print cur.fetchone()[0]

Added: vendor/Python/current/Doc/lib/sqlite3/parse_colnames.py
===================================================================
--- vendor/Python/current/Doc/lib/sqlite3/parse_colnames.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/sqlite3/parse_colnames.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,8 @@
+import sqlite3
+import datetime
+
+con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_COLNAMES)
+cur = con.cursor()
+cur.execute('select ? as "x [timestamp]"', (datetime.datetime.now(),))
+dt = cur.fetchone()[0]
+print dt, type(dt)

Added: vendor/Python/current/Doc/lib/sqlite3/pysqlite_datetime.py
===================================================================
--- vendor/Python/current/Doc/lib/sqlite3/pysqlite_datetime.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/sqlite3/pysqlite_datetime.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,20 @@
+import sqlite3
+import datetime
+
+con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
+cur = con.cursor()
+cur.execute("create table test(d date, ts timestamp)")
+
+today = datetime.date.today()
+now = datetime.datetime.now()
+
+cur.execute("insert into test(d, ts) values (?, ?)", (today, now))
+cur.execute("select d, ts from test")
+row = cur.fetchone()
+print today, "=>", row[0], type(row[0])
+print now, "=>", row[1], type(row[1])
+
+cur.execute('select current_date as "d [date]", current_timestamp as "ts [timestamp]"')
+row = cur.fetchone()
+print "current_date", row[0], type(row[0])
+print "current_timestamp", row[1], type(row[1])

Added: vendor/Python/current/Doc/lib/sqlite3/row_factory.py
===================================================================
--- vendor/Python/current/Doc/lib/sqlite3/row_factory.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/sqlite3/row_factory.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,13 @@
+import sqlite3
+
+def dict_factory(cursor, row):
+    d = {}
+    for idx, col in enumerate(cursor.description):
+        d[col[0]] = row[idx]
+    return d
+
+con = sqlite3.connect(":memory:")
+con.row_factory = dict_factory
+cur = con.cursor()
+cur.execute("select 1 as a")
+print cur.fetchone()["a"]

Added: vendor/Python/current/Doc/lib/sqlite3/rowclass.py
===================================================================
--- vendor/Python/current/Doc/lib/sqlite3/rowclass.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/sqlite3/rowclass.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,12 @@
+import sqlite3
+
+con = sqlite3.connect("mydb")
+con.row_factory = sqlite3.Row
+
+cur = con.cursor()
+cur.execute("select name_last, age from people")
+for row in cur:
+    assert row[0] == row["name_last"]
+    assert row["name_last"] == row["nAmE_lAsT"]
+    assert row[1] == row["age"]
+    assert row[1] == row["AgE"]

Added: vendor/Python/current/Doc/lib/sqlite3/shared_cache.py
===================================================================
--- vendor/Python/current/Doc/lib/sqlite3/shared_cache.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/sqlite3/shared_cache.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,6 @@
+import sqlite3
+
+# The shared cache is only available in SQLite versions 3.3.3 or later
+# See the SQLite documentaton for details.
+
+sqlite3.enable_shared_cache(True)

Added: vendor/Python/current/Doc/lib/sqlite3/shortcut_methods.py
===================================================================
--- vendor/Python/current/Doc/lib/sqlite3/shortcut_methods.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/sqlite3/shortcut_methods.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,21 @@
+import sqlite3
+
+persons = [
+    ("Hugo", "Boss"),
+    ("Calvin", "Klein")
+    ]
+
+con = sqlite3.connect(":memory:")
+
+# Create the table
+con.execute("create table person(firstname, lastname)")
+
+# Fill the table
+con.executemany("insert into person(firstname, lastname) values (?, ?)", persons)
+
+# Print the table contents
+for row in con.execute("select firstname, lastname from person"):
+    print row
+
+# Using a dummy WHERE clause to not let SQLite take the shortcut table deletes.
+print "I just deleted", con.execute("delete from person where 1=1").rowcount, "rows"

Added: vendor/Python/current/Doc/lib/sqlite3/simple_tableprinter.py
===================================================================
--- vendor/Python/current/Doc/lib/sqlite3/simple_tableprinter.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/sqlite3/simple_tableprinter.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,26 @@
+import sqlite3
+
+FIELD_MAX_WIDTH = 20
+TABLE_NAME = 'people'
+SELECT = 'select * from %s order by age, name_last' % TABLE_NAME
+
+con = sqlite3.connect("mydb")
+
+cur = con.cursor()
+cur.execute(SELECT)
+
+# Print a header.
+for fieldDesc in cur.description:
+    print fieldDesc[0].ljust(FIELD_MAX_WIDTH) ,
+print # Finish the header with a newline.
+print '-' * 78
+
+# For each row, print the value of each field left-justified within
+# the maximum possible width of that field.
+fieldIndices = range(len(cur.description))
+for row in cur:
+    for fieldIndex in fieldIndices:
+        fieldValue = str(row[fieldIndex])
+        print fieldValue.ljust(FIELD_MAX_WIDTH) ,
+
+    print # Finish the row with a newline.

Added: vendor/Python/current/Doc/lib/sqlite3/text_factory.py
===================================================================
--- vendor/Python/current/Doc/lib/sqlite3/text_factory.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/sqlite3/text_factory.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,42 @@
+import sqlite3
+
+con = sqlite3.connect(":memory:")
+cur = con.cursor()
+
+# Create the table
+con.execute("create table person(lastname, firstname)")
+
+AUSTRIA = u"\xd6sterreich"
+
+# by default, rows are returned as Unicode
+cur.execute("select ?", (AUSTRIA,))
+row = cur.fetchone()
+assert row[0] == AUSTRIA
+
+# but we can make pysqlite always return bytestrings ...
+con.text_factory = str
+cur.execute("select ?", (AUSTRIA,))
+row = cur.fetchone()
+assert type(row[0]) == str
+# the bytestrings will be encoded in UTF-8, unless you stored garbage in the
+# database ...
+assert row[0] == AUSTRIA.encode("utf-8")
+
+# we can also implement a custom text_factory ...
+# here we implement one that will ignore Unicode characters that cannot be
+# decoded from UTF-8
+con.text_factory = lambda x: unicode(x, "utf-8", "ignore")
+cur.execute("select ?", ("this is latin1 and would normally create errors" + u"\xe4\xf6\xfc".encode("latin1"),))
+row = cur.fetchone()
+assert type(row[0]) == unicode
+
+# pysqlite offers a builtin optimized text_factory that will return bytestring
+# objects, if the data is in ASCII only, and otherwise return unicode objects
+con.text_factory = sqlite3.OptimizedUnicode
+cur.execute("select ?", (AUSTRIA,))
+row = cur.fetchone()
+assert type(row[0]) == unicode
+
+cur.execute("select ?", ("Germany",))
+row = cur.fetchone()
+assert type(row[0]) == str

Added: vendor/Python/current/Doc/lib/tkinter.tex
===================================================================
--- vendor/Python/current/Doc/lib/tkinter.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/tkinter.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1873 @@
+\chapter{Graphical User Interfaces with Tk \label{tkinter}}
+
+\index{GUI}
+\index{Graphical User Interface}
+\index{Tkinter}
+\index{Tk}
+
+Tk/Tcl has long been an integral part of Python.  It provides a robust
+and platform independent windowing toolkit, that is available to
+Python programmers using the \refmodule{Tkinter} module, and its
+extension, the \refmodule{Tix} module.
+
+The \refmodule{Tkinter} module is a thin object-oriented layer on top of
+Tcl/Tk. To use \refmodule{Tkinter}, you don't need to write Tcl code,
+but you will need to consult the Tk documentation, and occasionally
+the Tcl documentation.  \refmodule{Tkinter} is a set of wrappers that
+implement the Tk widgets as Python classes.  In addition, the internal
+module \module{\_tkinter} provides a threadsafe mechanism which allows
+Python and Tcl to interact.
+
+Tk is not the only GUI for Python; see
+section~\ref{other-gui-packages}, ``Other User Interface Modules and
+Packages,'' for more information on other GUI toolkits for Python.
+
+% Other sections I have in mind are
+% Tkinter internals
+% Freezing Tkinter applications
+
+\localmoduletable
+
+
+\section{\module{Tkinter} ---
+         Python interface to Tcl/Tk}
+
+\declaremodule{standard}{Tkinter}
+\modulesynopsis{Interface to Tcl/Tk for graphical user interfaces}
+\moduleauthor{Guido van Rossum}{guido at Python.org}
+
+The \module{Tkinter} module (``Tk interface'') is the standard Python
+interface to the Tk GUI toolkit.  Both Tk and \module{Tkinter} are
+available on most \UNIX{} platforms, as well as on Windows and
+Macintosh systems.  (Tk itself is not part of Python; it is maintained
+at ActiveState.)
+
+\begin{seealso}
+\seetitle[http://www.python.org/topics/tkinter/]
+         {Python Tkinter Resources}
+         {The Python Tkinter Topic Guide provides a great
+            deal of information on using Tk from Python and links to
+            other sources of information on Tk.}
+
+\seetitle[http://www.pythonware.com/library/an-introduction-to-tkinter.htm]
+         {An Introduction to Tkinter}
+         {Fredrik Lundh's on-line reference material.}
+
+\seetitle[http://www.nmt.edu/tcc/help/pubs/lang.html]
+         {Tkinter reference: a GUI for Python}
+         {On-line reference material.}
+        
+\seetitle[http://jtkinter.sourceforge.net]
+         {Tkinter for JPython}
+         {The Jython interface to Tkinter.}
+
+\seetitle[http://www.amazon.com/exec/obidos/ASIN/1884777813]
+         {Python and Tkinter Programming}
+         {The book by John Grayson (ISBN 1-884777-81-3).}
+\end{seealso}
+
+
+\subsection{Tkinter Modules}
+
+Most of the time, the \refmodule{Tkinter} module is all you really
+need, but a number of additional modules are available as well.  The
+Tk interface is located in a binary module named \module{_tkinter}.
+This module contains the low-level interface to Tk, and should never
+be used directly by application programmers. It is usually a shared
+library (or DLL), but might in some cases be statically linked with
+the Python interpreter.
+
+In addition to the Tk interface module, \refmodule{Tkinter} includes a
+number of Python modules. The two most important modules are the
+\refmodule{Tkinter} module itself, and a module called
+\module{Tkconstants}. The former automatically imports the latter, so
+to use Tkinter, all you need to do is to import one module:
+
+\begin{verbatim}
+import Tkinter
+\end{verbatim}
+
+Or, more often:
+
+\begin{verbatim}
+from Tkinter import *
+\end{verbatim}
+
+\begin{classdesc}{Tk}{screenName=None, baseName=None, className='Tk', useTk=1}
+The \class{Tk} class is instantiated without arguments.
+This creates a toplevel widget of Tk which usually is the main window
+of an application. Each instance has its own associated Tcl interpreter.
+% FIXME: The following keyword arguments are currently recognized:
+\versionchanged[The \var{useTk} parameter was added]{2.4}
+\end{classdesc}
+
+\begin{funcdesc}{Tcl}{screenName=None, baseName=None, className='Tk', useTk=0}
+The \function{Tcl} function is a factory function which creates an
+object much like that created by the \class{Tk} class, except that it
+does not initialize the Tk subsystem.  This is most often useful when
+driving the Tcl interpreter in an environment where one doesn't want
+to create extraneous toplevel windows, or where one cannot (such as
+\UNIX/Linux systems without an X server).  An object created by the
+\function{Tcl} object can have a Toplevel window created (and the Tk
+subsystem initialized) by calling its \method{loadtk} method.
+\versionadded{2.4}
+\end{funcdesc}
+
+Other modules that provide Tk support include:
+
+\begin{description}
+% \declaremodule{standard}{Tkconstants}
+% \modulesynopsis{Constants used by Tkinter}
+% FIXME 
+
+\item[\refmodule{ScrolledText}]
+Text widget with a vertical scroll bar built in.
+
+\item[\module{tkColorChooser}]
+Dialog to let the user choose a color.
+
+\item[\module{tkCommonDialog}]
+Base class for the dialogs defined in the other modules listed here.
+
+\item[\module{tkFileDialog}]
+Common dialogs to allow the user to specify a file to open or save.
+
+\item[\module{tkFont}]
+Utilities to help work with fonts.
+
+\item[\module{tkMessageBox}]
+Access to standard Tk dialog boxes.
+
+\item[\module{tkSimpleDialog}]
+Basic dialogs and convenience functions.
+
+\item[\module{Tkdnd}]
+Drag-and-drop support for \refmodule{Tkinter}.
+This is experimental and should become deprecated when it is replaced 
+with the Tk DND.
+
+\item[\refmodule{turtle}]
+Turtle graphics in a Tk window.
+
+\end{description}
+
+\subsection{Tkinter Life Preserver}
+\sectionauthor{Matt Conway}{}
+% Converted to LaTeX by Mike Clarkson.
+
+This section is not designed to be an exhaustive tutorial on either
+Tk or Tkinter.  Rather, it is intended as a stop gap, providing some
+introductory orientation on the system.
+
+Credits:
+\begin{itemize}
+\item   Tkinter was written by Steen Lumholt and Guido van Rossum.
+\item   Tk was written by John Ousterhout while at Berkeley.
+\item   This Life Preserver was written by Matt Conway at
+the University of Virginia.
+\item   The html rendering, and some liberal editing, was
+produced from a FrameMaker version by Ken Manheimer.
+\item   Fredrik Lundh elaborated and revised the class interface descriptions,
+to get them current with Tk 4.2.
+\item  Mike Clarkson converted the documentation to \LaTeX, and compiled the 
+User Interface chapter of the reference manual.
+\end{itemize}
+
+
+\subsubsection{How To Use This Section}
+
+This section is designed in two parts: the first half (roughly) covers
+background material, while the second half can be taken to the
+keyboard as a handy reference.
+
+When trying to answer questions of the form ``how do I do blah'', it
+is often best to find out how to do``blah'' in straight Tk, and then
+convert this back into the corresponding \refmodule{Tkinter} call.
+Python programmers can often guess at the correct Python command by
+looking at the Tk documentation. This means that in order to use
+Tkinter, you will have to know a little bit about Tk. This document
+can't fulfill that role, so the best we can do is point you to the
+best documentation that exists. Here are some hints:
+
+\begin{itemize}
+\item   The authors strongly suggest getting a copy of the Tk man
+pages. Specifically, the man pages in the \code{mann} directory are most
+useful. The \code{man3} man pages describe the C interface to the Tk
+library and thus are not especially helpful for script writers.  
+
+\item   Addison-Wesley publishes a book called \citetitle{Tcl and the
+Tk Toolkit} by John Ousterhout (ISBN 0-201-63337-X) which is a good
+introduction to Tcl and Tk for the novice.  The book is not
+exhaustive, and for many details it defers to the man pages. 
+
+\item   \file{Tkinter.py} is a last resort for most, but can be a good
+place to go when nothing else makes sense.  
+\end{itemize}
+
+\begin{seealso}
+\seetitle[http://tcl.activestate.com/]
+        {ActiveState Tcl Home Page}
+        {The Tk/Tcl development is largely taking place at
+         ActiveState.}
+\seetitle[http://www.amazon.com/exec/obidos/ASIN/020163337X]
+        {Tcl and the Tk Toolkit}
+        {The book by John Ousterhout, the inventor of Tcl .}
+\seetitle[http://www.amazon.com/exec/obidos/ASIN/0130220280]
+        {Practical Programming in Tcl and Tk}
+        {Brent Welch's encyclopedic book.}
+\end{seealso}
+
+
+\subsubsection{A Simple Hello World Program} % HelloWorld.html
+
+%begin{latexonly}
+%\begin{figure}[hbtp]
+%\centerline{\epsfig{file=HelloWorld.gif,width=.9\textwidth}}
+%\vspace{.5cm}
+%\caption{HelloWorld gadget image}
+%\end{figure}
+%See also the hello-world \ulink{notes}{classes/HelloWorld-notes.html} and
+%\ulink{summary}{classes/HelloWorld-summary.html}.
+%end{latexonly}
+
+
+\begin{verbatim}
+from Tkinter import *
+
+class Application(Frame):
+    def say_hi(self):
+        print "hi there, everyone!"
+
+    def createWidgets(self):
+        self.QUIT = Button(self)
+        self.QUIT["text"] = "QUIT"
+        self.QUIT["fg"]   = "red"
+        self.QUIT["command"] =  self.quit
+
+        self.QUIT.pack({"side": "left"})
+
+        self.hi_there = Button(self)
+        self.hi_there["text"] = "Hello",
+        self.hi_there["command"] = self.say_hi
+
+        self.hi_there.pack({"side": "left"})
+
+    def __init__(self, master=None):
+        Frame.__init__(self, master)
+        self.pack()
+        self.createWidgets()
+
+root = Tk()
+app = Application(master=root)
+app.mainloop()
+root.destroy()
+\end{verbatim}
+
+
+\subsection{A (Very) Quick Look at Tcl/Tk} % BriefTclTk.html
+
+The class hierarchy looks complicated, but in actual practice,
+application programmers almost always refer to the classes at the very
+bottom of the hierarchy. 
+
+Notes:
+\begin{itemize}
+\item   These classes are provided for the purposes of
+organizing certain functions under one namespace. They aren't meant to
+be instantiated independently.
+
+\item    The \class{Tk} class is meant to be instantiated only once in
+an application. Application programmers need not instantiate one
+explicitly, the system creates one whenever any of the other classes
+are instantiated.
+
+\item    The \class{Widget} class is not meant to be instantiated, it
+is meant only for subclassing to make ``real'' widgets (in \Cpp, this
+is called an `abstract class').
+\end{itemize}
+
+To make use of this reference material, there will be times when you
+will need to know how to read short passages of Tk and how to identify
+the various parts of a Tk command.  
+(See section~\ref{tkinter-basic-mapping} for the
+\refmodule{Tkinter} equivalents of what's below.)
+
+Tk scripts are Tcl programs.  Like all Tcl programs, Tk scripts are
+just lists of tokens separated by spaces.  A Tk widget is just its
+\emph{class}, the \emph{options} that help configure it, and the
+\emph{actions} that make it do useful things. 
+
+To make a widget in Tk, the command is always of the form: 
+
+\begin{verbatim}
+                classCommand newPathname options
+\end{verbatim}
+
+\begin{description}
+\item[\var{classCommand}]
+denotes which kind of widget to make (a button, a label, a menu...)
+
+\item[\var{newPathname}]
+is the new name for this widget.  All names in Tk must be unique.  To
+help enforce this, widgets in Tk are named with \emph{pathnames}, just
+like files in a file system.  The top level widget, the \emph{root},
+is called \code{.} (period) and children are delimited by more
+periods.  For example, \code{.myApp.controlPanel.okButton} might be
+the name of a widget.
+
+\item[\var{options}]
+configure the widget's appearance and in some cases, its
+behavior.  The options come in the form of a list of flags and values.
+Flags are preceded by a `-', like \UNIX{} shell command flags, and
+values are put in quotes if they are more than one word.
+\end{description}
+
+For example: 
+
+\begin{verbatim}
+    button   .fred   -fg red -text "hi there"
+       ^       ^     \_____________________/
+       |       |                |
+     class    new            options
+    command  widget  (-opt val -opt val ...)
+\end{verbatim} 
+
+Once created, the pathname to the widget becomes a new command.  This
+new \var{widget command} is the programmer's handle for getting the new
+widget to perform some \var{action}.  In C, you'd express this as
+someAction(fred, someOptions), in \Cpp, you would express this as
+fred.someAction(someOptions), and in Tk, you say: 
+
+\begin{verbatim}
+    .fred someAction someOptions 
+\end{verbatim} 
+
+Note that the object name, \code{.fred}, starts with a dot.
+
+As you'd expect, the legal values for \var{someAction} will depend on
+the widget's class: \code{.fred disable} works if fred is a
+button (fred gets greyed out), but does not work if fred is a label
+(disabling of labels is not supported in Tk). 
+
+The legal values of \var{someOptions} is action dependent.  Some
+actions, like \code{disable}, require no arguments, others, like
+a text-entry box's \code{delete} command, would need arguments
+to specify what range of text to delete.  
+
+
+\subsection{Mapping Basic Tk into Tkinter
+            \label{tkinter-basic-mapping}}
+
+Class commands in Tk correspond to class constructors in Tkinter.
+
+\begin{verbatim}
+    button .fred                =====>  fred = Button()
+\end{verbatim}
+
+The master of an object is implicit in the new name given to it at
+creation time.  In Tkinter, masters are specified explicitly.
+
+\begin{verbatim}
+    button .panel.fred          =====>  fred = Button(panel)
+\end{verbatim}
+
+The configuration options in Tk are given in lists of hyphened tags
+followed by values.  In Tkinter, options are specified as
+keyword-arguments in the instance constructor, and keyword-args for
+configure calls or as instance indices, in dictionary style, for
+established instances.  See section~\ref{tkinter-setting-options} on
+setting options.
+
+\begin{verbatim}
+    button .fred -fg red        =====>  fred = Button(panel, fg = "red")
+    .fred configure -fg red     =====>  fred["fg"] = red
+                                OR ==>  fred.config(fg = "red")
+\end{verbatim}
+
+In Tk, to perform an action on a widget, use the widget name as a
+command, and follow it with an action name, possibly with arguments
+(options).  In Tkinter, you call methods on the class instance to
+invoke actions on the widget.  The actions (methods) that a given
+widget can perform are listed in the Tkinter.py module.
+
+\begin{verbatim}
+    .fred invoke                =====>  fred.invoke()
+\end{verbatim}
+
+To give a widget to the packer (geometry manager), you call pack with
+optional arguments.  In Tkinter, the Pack class holds all this
+functionality, and the various forms of the pack command are
+implemented as methods.  All widgets in \refmodule{Tkinter} are
+subclassed from the Packer, and so inherit all the packing
+methods. See the \refmodule{Tix} module documentation for additional
+information on the Form geometry manager.
+
+\begin{verbatim}
+    pack .fred -side left       =====>  fred.pack(side = "left")
+\end{verbatim}
+
+
+\subsection{How Tk and Tkinter are Related} % Relationship.html
+
+\note{This was derived from a graphical image; the image will be used
+      more directly in a subsequent version of this document.}
+
+From the top down:
+\begin{description}
+\item[\b{Your App Here (Python)}]
+A Python application makes a \refmodule{Tkinter} call.
+
+\item[\b{Tkinter (Python Module)}]
+This call (say, for example, creating a button widget), is
+implemented in the \emph{Tkinter} module, which is written in
+Python.  This Python function will parse the commands and the
+arguments and convert them into a form that makes them look as if they
+had come from a Tk script instead of a Python script.
+
+\item[\b{tkinter (C)}]
+These commands and their arguments will be passed to a C function
+in the \emph{tkinter} - note the lowercase - extension module.
+
+\item[\b{Tk Widgets} (C and Tcl)]
+This C function is able to make calls into other C modules,
+including the C functions that make up the Tk library.  Tk is
+implemented in C and some Tcl.  The Tcl part of the Tk widgets is used
+to bind certain default behaviors to widgets, and is executed once at
+the point where the Python \refmodule{Tkinter} module is
+imported. (The user never sees this stage).
+
+\item[\b{Tk (C)}]
+The Tk part of the Tk Widgets implement the final mapping to ...
+
+\item[\b{Xlib (C)}]
+the Xlib library to draw graphics on the screen.
+\end{description}
+
+
+\subsection{Handy Reference}
+
+\subsubsection{Setting Options
+               \label{tkinter-setting-options}}
+
+Options control things like the color and border width of a widget.
+Options can be set in three ways:
+
+\begin{description}
+\item[At object creation time, using keyword arguments]:
+\begin{verbatim}
+fred = Button(self, fg = "red", bg = "blue")
+\end{verbatim}
+\item[After object creation, treating the option name like a dictionary index]:
+\begin{verbatim}
+fred["fg"] = "red"
+fred["bg"] = "blue"
+\end{verbatim}
+\item[Use the config() method to update multiple attrs subsequent to
+object creation]:
+\begin{verbatim}
+fred.config(fg = "red", bg = "blue")
+\end{verbatim}
+\end{description}
+
+For a complete explanation of a given option and its behavior, see the
+Tk man pages for the widget in question.
+
+Note that the man pages list "STANDARD OPTIONS" and "WIDGET SPECIFIC
+OPTIONS" for each widget.  The former is a list of options that are
+common to many widgets, the latter are the options that are
+idiosyncratic to that particular widget.  The Standard Options are
+documented on the \manpage{options}{3} man page.
+
+No distinction between standard and widget-specific options is made in
+this document.  Some options don't apply to some kinds of widgets.
+Whether a given widget responds to a particular option depends on the
+class of the widget; buttons have a \code{command} option, labels do not. 
+
+The options supported by a given widget are listed in that widget's
+man page, or can be queried at runtime by calling the
+\method{config()} method without arguments, or by calling the
+\method{keys()} method on that widget.  The return value of these
+calls is a dictionary whose key is the name of the option as a string
+(for example, \code{'relief'}) and whose values are 5-tuples.
+
+Some options, like \code{bg} are synonyms for common options with long
+names (\code{bg} is shorthand for "background"). Passing the
+\code{config()} method the name of a shorthand option will return a
+2-tuple, not 5-tuple. The 2-tuple passed back will contain the name of
+the synonym and the ``real'' option (such as \code{('bg',
+'background')}).
+
+\begin{tableiii}{c|l|l}{textrm}{Index}{Meaning}{Example}
+  \lineiii{0}{option name}                       {\code{'relief'}}
+  \lineiii{1}{option name for database lookup}   {\code{'relief'}}
+  \lineiii{2}{option class for database lookup}  {\code{'Relief'}}
+  \lineiii{3}{default value}                     {\code{'raised'}}
+  \lineiii{4}{current value}                     {\code{'groove'}}
+\end{tableiii}
+
+
+Example:
+
+\begin{verbatim}
+>>> print fred.config()
+{'relief' : ('relief', 'relief', 'Relief', 'raised', 'groove')}
+\end{verbatim}
+
+Of course, the dictionary printed will include all the options
+available and their values.  This is meant only as an example.
+
+
+\subsubsection{The Packer} % Packer.html
+\index{packing (widgets)}
+
+The packer is one of Tk's geometry-management mechanisms.  
+% See also \citetitle[classes/ClassPacker.html]{the Packer class interface}.
+
+Geometry managers are used to specify the relative positioning of the
+positioning of widgets within their container - their mutual
+\emph{master}.  In contrast to the more cumbersome \emph{placer}
+(which is used less commonly, and we do not cover here), the packer
+takes qualitative relationship specification - \emph{above}, \emph{to
+the left of}, \emph{filling}, etc - and works everything out to
+determine the exact placement coordinates for you. 
+
+The size of any \emph{master} widget is determined by the size of
+the "slave widgets" inside.  The packer is used to control where slave
+widgets appear inside the master into which they are packed.  You can
+pack widgets into frames, and frames into other frames, in order to
+achieve the kind of layout you desire.  Additionally, the arrangement
+is dynamically adjusted to accommodate incremental changes to the
+configuration, once it is packed.
+
+Note that widgets do not appear until they have had their geometry
+specified with a geometry manager.  It's a common early mistake to
+leave out the geometry specification, and then be surprised when the
+widget is created but nothing appears.  A widget will appear only
+after it has had, for example, the packer's \method{pack()} method
+applied to it.
+
+The pack() method can be called with keyword-option/value pairs that
+control where the widget is to appear within its container, and how it
+is to behave when the main application window is resized.  Here are
+some examples:
+
+\begin{verbatim}
+    fred.pack()                     # defaults to side = "top"
+    fred.pack(side = "left")
+    fred.pack(expand = 1)
+\end{verbatim}
+
+
+\subsubsection{Packer Options}
+
+For more extensive information on the packer and the options that it
+can take, see the man pages and page 183 of John Ousterhout's book.
+
+\begin{description}
+\item[\b{anchor }]
+Anchor type.  Denotes where the packer is to place each slave in its
+parcel.
+
+\item[\b{expand}]
+Boolean, \code{0} or \code{1}.
+
+\item[\b{fill}]
+Legal values: \code{'x'}, \code{'y'}, \code{'both'}, \code{'none'}.
+
+\item[\b{ipadx} and \b{ipady}]
+A distance - designating internal padding on each side of the slave
+widget.
+
+\item[\b{padx} and \b{pady}]
+A distance - designating external padding on each side of the slave
+widget.
+
+\item[\b{side}]
+Legal values are: \code{'left'}, \code{'right'}, \code{'top'},
+\code{'bottom'}.
+\end{description}
+
+
+\subsubsection{Coupling Widget Variables} % VarCouplings.html
+
+The current-value setting of some widgets (like text entry widgets)
+can be connected directly to application variables by using special
+options.  These options are \code{variable}, \code{textvariable},
+\code{onvalue}, \code{offvalue}, and \code{value}.  This
+connection works both ways: if the variable changes for any reason,
+the widget it's connected to will be updated to reflect the new value. 
+
+Unfortunately, in the current implementation of \refmodule{Tkinter} it is
+not possible to hand over an arbitrary Python variable to a widget
+through a \code{variable} or \code{textvariable} option.  The only
+kinds of variables for which this works are variables that are
+subclassed from a class called Variable, defined in the
+\refmodule{Tkinter} module.
+
+There are many useful subclasses of Variable already defined:
+\class{StringVar}, \class{IntVar}, \class{DoubleVar}, and
+\class{BooleanVar}.  To read the current value of such a variable,
+call the \method{get()} method on
+it, and to change its value you call the \method{set()} method.  If
+you follow this protocol, the widget will always track the value of
+the variable, with no further intervention on your part.
+
+For example: 
+\begin{verbatim}
+class App(Frame):
+    def __init__(self, master=None):
+        Frame.__init__(self, master)
+        self.pack()
+        
+        self.entrythingy = Entry()
+        self.entrythingy.pack()
+        
+        # here is the application variable
+        self.contents = StringVar()
+        # set it to some value
+        self.contents.set("this is a variable")
+        # tell the entry widget to watch this variable
+        self.entrythingy["textvariable"] = self.contents
+        
+        # and here we get a callback when the user hits return.
+        # we will have the program print out the value of the
+        # application variable when the user hits return
+        self.entrythingy.bind('<Key-Return>',
+                              self.print_contents)
+
+    def print_contents(self, event):
+        print "hi. contents of entry is now ---->", \
+              self.contents.get()
+\end{verbatim}
+
+
+\subsubsection{The Window Manager} % WindowMgr.html
+\index{window manager (widgets)}
+
+In Tk, there is a utility command, \code{wm}, for interacting with the
+window manager.  Options to the \code{wm} command allow you to control
+things like titles, placement, icon bitmaps, and the like.  In
+\refmodule{Tkinter}, these commands have been implemented as methods
+on the \class{Wm} class.  Toplevel widgets are subclassed from the
+\class{Wm} class, and so can call the \class{Wm} methods directly.
+
+%See also \citetitle[classes/ClassWm.html]{the Wm class interface}.
+
+To get at the toplevel window that contains a given widget, you can
+often just refer to the widget's master.  Of course if the widget has
+been packed inside of a frame, the master won't represent a toplevel
+window.  To get at the toplevel window that contains an arbitrary
+widget, you can call the \method{_root()} method.  This
+method begins with an underscore to denote the fact that this function
+is part of the implementation, and not an interface to Tk functionality.
+
+Here are some examples of typical usage:
+
+\begin{verbatim}
+from Tkinter import *
+class App(Frame):
+    def __init__(self, master=None):
+        Frame.__init__(self, master)
+        self.pack()
+
+
+# create the application
+myapp = App()
+
+#
+# here are method calls to the window manager class
+#
+myapp.master.title("My Do-Nothing Application")
+myapp.master.maxsize(1000, 400)
+
+# start the program
+myapp.mainloop()
+\end{verbatim}
+
+
+\subsubsection{Tk Option Data Types} % OptionTypes.html
+
+\index{Tk Option Data Types}
+
+\begin{description}
+\item[anchor]
+Legal values are points of the compass: \code{"n"},
+\code{"ne"}, \code{"e"}, \code{"se"}, \code{"s"},
+\code{"sw"}, \code{"w"}, \code{"nw"}, and also
+\code{"center"}.
+
+\item[bitmap]
+There are eight built-in, named bitmaps: \code{'error'}, \code{'gray25'},
+\code{'gray50'}, \code{'hourglass'}, \code{'info'}, \code{'questhead'},
+\code{'question'}, \code{'warning'}.  To specify an X bitmap
+filename, give the full path to the file, preceded with an \code{@},
+as in \code{"@/usr/contrib/bitmap/gumby.bit"}.
+
+\item[boolean]
+You can pass integers 0 or 1 or the strings \code{"yes"} or \code{"no"} .
+
+\item[callback]
+This is any Python function that takes no arguments.  For example: 
+\begin{verbatim}
+    def print_it():
+            print "hi there"
+    fred["command"] = print_it
+\end{verbatim}
+
+\item[color]
+Colors can be given as the names of X colors in the rgb.txt file,
+or as strings representing RGB values in 4 bit: \code{"\#RGB"}, 8
+bit: \code{"\#RRGGBB"}, 12 bit" \code{"\#RRRGGGBBB"}, or 16 bit
+\code{"\#RRRRGGGGBBBB"} ranges, where R,G,B here represent any
+legal hex digit.  See page 160 of Ousterhout's book for details.  
+
+\item[cursor]
+The standard X cursor names from \file{cursorfont.h} can be used,
+without the \code{XC_} prefix.  For example to get a hand cursor
+(\constant{XC_hand2}), use the string \code{"hand2"}.  You can also
+specify a bitmap and mask file of your own.  See page 179 of
+Ousterhout's book.
+
+\item[distance]
+Screen distances can be specified in either pixels or absolute
+distances.  Pixels are given as numbers and absolute distances as
+strings, with the trailing character denoting units: \code{c}
+for centimetres, \code{i} for inches, \code{m} for millimetres,
+\code{p} for printer's points.  For example, 3.5 inches is expressed
+as \code{"3.5i"}.
+
+\item[font]
+Tk uses a list font name format, such as \code{\{courier 10 bold\}}.
+Font sizes with positive numbers are measured in points;
+sizes with negative numbers are measured in pixels.
+
+\item[geometry]
+This is a string of the form \samp{\var{width}x\var{height}}, where
+width and height are measured in pixels for most widgets (in
+characters for widgets displaying text).  For example:
+\code{fred["geometry"] = "200x100"}.
+
+\item[justify]
+Legal values are the strings: \code{"left"},
+\code{"center"}, \code{"right"}, and \code{"fill"}.
+
+\item[region]
+This is a string with four space-delimited elements, each of
+which is a legal distance (see above).  For example: \code{"2 3 4
+5"} and \code{"3i 2i 4.5i 2i"} and \code{"3c 2c 4c 10.43c"} 
+are all legal regions.
+
+\item[relief]
+Determines what the border style of a widget will be.  Legal
+values are: \code{"raised"}, \code{"sunken"},
+\code{"flat"}, \code{"groove"}, and \code{"ridge"}.
+
+\item[scrollcommand]
+This is almost always the \method{set()} method of some scrollbar
+widget, but can be any widget method that takes a single argument.  
+Refer to the file \file{Demo/tkinter/matt/canvas-with-scrollbars.py}
+in the Python source distribution for an example.
+
+\item[wrap:]
+Must be one of: \code{"none"}, \code{"char"}, or \code{"word"}.
+\end{description}
+
+
+\subsubsection{Bindings and Events} % Bindings.html
+
+\index{bind (widgets)}
+\index{events (widgets)}
+
+The bind method from the widget command allows you to watch for
+certain events and to have a callback function trigger when that event
+type occurs.  The form of the bind method is:
+
+\begin{verbatim}
+    def bind(self, sequence, func, add=''):
+\end{verbatim}
+where:
+
+\begin{description}
+\item[sequence]
+is a string that denotes the target kind of event.  (See the bind
+man page and page 201 of John Ousterhout's book for details).
+
+\item[func]
+is a Python function, taking one argument, to be invoked when the
+event occurs.  An Event instance will be passed as the argument.
+(Functions deployed this way are commonly known as \var{callbacks}.)
+
+\item[add]
+is optional, either \samp{} or \samp{+}.  Passing an empty string
+denotes that this binding is to replace any other bindings that this
+event is associated with.  Preceeding with a \samp{+} means that this
+function is to be added to the list of functions bound to this event type.
+\end{description}
+
+For example:
+\begin{verbatim}
+    def turnRed(self, event):
+        event.widget["activeforeground"] = "red"
+
+    self.button.bind("<Enter>", self.turnRed)
+\end{verbatim}
+
+Notice how the widget field of the event is being accessed in the
+\method{turnRed()} callback.  This field contains the widget that
+caught the X event.  The following table lists the other event fields
+you can access, and how they are denoted in Tk, which can be useful
+when referring to the Tk man pages.
+
+\begin{verbatim}
+Tk      Tkinter Event Field             Tk      Tkinter Event Field 
+--      -------------------             --      -------------------
+%f      focus                           %A      char
+%h      height                          %E      send_event
+%k      keycode                         %K      keysym
+%s      state                           %N      keysym_num
+%t      time                            %T      type
+%w      width                           %W      widget
+%x      x                               %X      x_root
+%y      y                               %Y      y_root
+\end{verbatim}
+
+
+\subsubsection{The index Parameter} % Index.html
+
+A number of widgets require``index'' parameters to be passed.  These
+are used to point at a specific place in a Text widget, or to
+particular characters in an Entry widget, or to particular menu items
+in a Menu widget.
+
+\begin{description}
+\item[\b{Entry widget indexes (index, view index, etc.)}]
+Entry widgets have options that refer to character positions in the
+text being displayed.  You can use these \refmodule{Tkinter} functions
+to access these special points in text widgets:
+
+\begin{description}
+\item[AtEnd()]
+refers to the last position in the text
+
+\item[AtInsert()]
+refers to the point where the text cursor is
+
+\item[AtSelFirst()]
+indicates the beginning point of the selected text
+
+\item[AtSelLast()]
+denotes the last point of the selected text and finally
+
+\item[At(x\optional{, y})]
+refers to the character at pixel location \var{x}, \var{y} (with
+\var{y} not used in the case of a text entry widget, which contains a
+single line of text).
+\end{description}
+
+\item[\b{Text widget indexes}]
+The index notation for Text widgets is very rich and is best described
+in the Tk man pages.
+
+\item[\b{Menu indexes (menu.invoke(), menu.entryconfig(), etc.)}]
+
+Some options and methods for menus manipulate specific menu entries.
+Anytime a menu index is needed for an option or a parameter, you may
+pass in: 
+\begin{itemize}
+\item   an integer which refers to the numeric position of the entry in
+the widget, counted from the top, starting with 0; 
+\item   the string \code{'active'}, which refers to the menu position that is
+currently under the cursor;
+\item   the string \code{"last"} which refers to the last menu
+item;  
+\item   An integer preceded by \code{@}, as in \code{@6}, where the integer is
+interpreted as a y pixel coordinate in the menu's coordinate system;
+\item   the string \code{"none"}, which indicates no menu entry at all, most
+often used with menu.activate() to deactivate all entries, and
+finally,
+\item   a text string that is pattern matched against the label of the
+menu entry, as scanned from the top of the menu to the bottom.  Note
+that this index type is considered after all the others, which means
+that matches for menu items labelled \code{last}, \code{active}, or
+\code{none} may be interpreted as the above literals, instead.
+\end{itemize}
+\end{description}
+
+\subsubsection{Images}
+
+Bitmap/Pixelmap images can be created through the subclasses of
+\class{Tkinter.Image}:
+
+\begin{itemize}
+\item  \class{BitmapImage} can be used for X11 bitmap data.
+\item  \class{PhotoImage} can be used for GIF and PPM/PGM color bitmaps.
+\end{itemize}
+
+Either type of image is created through either the \code{file} or the
+\code{data} option (other options are available as well).
+
+The image object can then be used wherever an \code{image} option is
+supported by some widget (e.g. labels, buttons, menus). In these
+cases, Tk will not keep a reference to the image. When the last Python
+reference to the image object is deleted, the image data is deleted as
+well, and Tk will display an empty box wherever the image was used.
+
+\section{\module{Tix} ---
+         Extension widgets for Tk}
+
+\declaremodule{standard}{Tix}
+\modulesynopsis{Tk Extension Widgets for Tkinter}
+\sectionauthor{Mike Clarkson}{mikeclarkson at users.sourceforge.net}
+
+\index{Tix}
+
+The \module{Tix} (Tk Interface Extension) module provides an
+additional rich set of widgets. Although the standard Tk library has
+many useful widgets, they are far from complete. The \module{Tix}
+library provides most of the commonly needed widgets that are missing
+from standard Tk: \class{HList}, \class{ComboBox}, \class{Control}
+(a.k.a. SpinBox) and an assortment of scrollable widgets. \module{Tix}
+also includes many more widgets that are generally useful in a wide
+range of applications: \class{NoteBook}, \class{FileEntry},
+\class{PanedWindow}, etc; there are more than 40 of them.
+
+With all these new widgets, you can introduce new interaction
+techniques into applications, creating more useful and more intuitive
+user interfaces. You can design your application by choosing the most
+appropriate widgets to match the special needs of your application and
+users. 
+
+\begin{seealso}
+\seetitle[http://tix.sourceforge.net/]
+        {Tix Homepage}
+        {The home page for \module{Tix}.  This includes links to
+         additional documentation and downloads.}
+\seetitle[http://tix.sourceforge.net/dist/current/man/]
+        {Tix Man Pages}
+        {On-line version of the man pages and reference material.}
+\seetitle[http://tix.sourceforge.net/dist/current/docs/tix-book/tix.book.html]
+        {Tix Programming Guide}
+        {On-line version of the programmer's reference material.}
+\seetitle[http://tix.sourceforge.net/Tide/]
+        {Tix Development Applications}
+        {Tix applications for development of Tix and Tkinter programs.
+         Tide applications work under Tk or Tkinter, and include
+         \program{TixInspect}, an inspector to remotely modify and
+         debug Tix/Tk/Tkinter applications.}
+\end{seealso}
+
+
+\subsection{Using Tix}
+
+\begin{classdesc}{Tix}{screenName\optional{, baseName\optional{, className}}}
+    Toplevel widget of Tix which represents mostly the main window
+    of an application. It has an associated Tcl interpreter.
+
+Classes in the \refmodule{Tix} module subclasses the classes in the
+\refmodule{Tkinter} module. The former imports the latter, so to use
+\refmodule{Tix} with Tkinter, all you need to do is to import one
+module. In general, you can just import \refmodule{Tix}, and replace
+the toplevel call to \class{Tkinter.Tk} with \class{Tix.Tk}:
+\begin{verbatim}
+import Tix
+from Tkconstants import *
+root = Tix.Tk()
+\end{verbatim}
+\end{classdesc}
+
+To use \refmodule{Tix}, you must have the \refmodule{Tix} widgets installed,
+usually alongside your installation of the Tk widgets.
+To test your installation, try the following:
+\begin{verbatim}
+import Tix
+root = Tix.Tk()
+root.tk.eval('package require Tix')
+\end{verbatim}
+
+If this fails, you have a Tk installation problem which must be
+resolved before proceeding. Use the environment variable \envvar{TIX_LIBRARY}
+to point to the installed \refmodule{Tix} library directory, and
+make sure you have the dynamic object library (\file{tix8183.dll} or
+\file{libtix8183.so}) in  the same directory that contains your Tk
+dynamic object library (\file{tk8183.dll} or \file{libtk8183.so}). The
+directory with the dynamic object library should also have a file
+called \file{pkgIndex.tcl} (case sensitive), which contains the line:
+
+\begin{verbatim}
+package ifneeded Tix 8.1 [list load "[file join $dir tix8183.dll]" Tix]
+\end{verbatim} % $ <-- bow to font-lock
+
+
+\subsection{Tix Widgets}
+
+\ulink{Tix}
+{http://tix.sourceforge.net/dist/current/man/html/TixCmd/TixIntro.htm}
+introduces over 40 widget classes to the \refmodule{Tkinter} 
+repertoire.  There is a demo of all the \refmodule{Tix} widgets in the
+\file{Demo/tix} directory of the standard distribution.
+
+
+% The Python sample code is still being added to Python, hence commented out
+
+
+\subsubsection{Basic Widgets}
+
+\begin{classdesc}{Balloon}{}
+A \ulink{Balloon}
+{http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixBalloon.htm}
+that pops up over a widget to provide help.  When the user moves the
+cursor inside a widget to which a Balloon widget has been bound, a
+small pop-up window with a descriptive message will be shown on the
+screen.
+\end{classdesc}
+
+% Python Demo of:
+% \ulink{Balloon}{http://tix.sourceforge.net/dist/current/demos/samples/Balloon.tcl}
+
+\begin{classdesc}{ButtonBox}{}
+The \ulink{ButtonBox}
+{http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixButtonBox.htm}
+widget creates a box of buttons, such as is commonly used for \code{Ok
+Cancel}.
+\end{classdesc}
+
+% Python Demo of:
+% \ulink{ButtonBox}{http://tix.sourceforge.net/dist/current/demos/samples/BtnBox.tcl}
+
+\begin{classdesc}{ComboBox}{}
+The \ulink{ComboBox}
+{http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixComboBox.htm}
+widget is similar to the combo box control in MS Windows. The user can
+select a choice by either typing in the entry subwdget or selecting
+from the listbox subwidget.
+\end{classdesc}
+
+% Python Demo of:
+% \ulink{ComboBox}{http://tix.sourceforge.net/dist/current/demos/samples/ComboBox.tcl}
+
+\begin{classdesc}{Control}{}
+The \ulink{Control}
+{http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixControl.htm}
+widget is also known as the \class{SpinBox} widget. The user can
+adjust the value by pressing the two arrow buttons or by entering the
+value directly into the entry. The new value will be checked against
+the user-defined upper and lower limits.
+\end{classdesc}
+
+% Python Demo of:
+% \ulink{Control}{http://tix.sourceforge.net/dist/current/demos/samples/Control.tcl}
+
+\begin{classdesc}{LabelEntry}{}
+The \ulink{LabelEntry}
+{http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixLabelEntry.htm}
+widget packages an entry widget and a label into one mega widget. It
+can be used be used to simplify the creation of ``entry-form'' type of
+interface.
+\end{classdesc}
+
+% Python Demo of:
+% \ulink{LabelEntry}{http://tix.sourceforge.net/dist/current/demos/samples/LabEntry.tcl}
+
+\begin{classdesc}{LabelFrame}{}
+The \ulink{LabelFrame}
+{http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixLabelFrame.htm}
+widget packages a frame widget and a label into one mega widget.  To
+create widgets inside a LabelFrame widget, one creates the new widgets
+relative to the \member{frame} subwidget and manage them inside the
+\member{frame} subwidget.
+\end{classdesc}
+
+% Python Demo of:
+% \ulink{LabelFrame}{http://tix.sourceforge.net/dist/current/demos/samples/LabFrame.tcl}
+
+\begin{classdesc}{Meter}{}
+The \ulink{Meter}
+{http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixMeter.htm}
+widget can be used to show the progress of a background job which may
+take a long time to execute.
+\end{classdesc}
+
+% Python Demo of:
+% \ulink{Meter}{http://tix.sourceforge.net/dist/current/demos/samples/Meter.tcl}
+
+\begin{classdesc}{OptionMenu}{}
+The \ulink{OptionMenu}
+{http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixOptionMenu.htm}
+creates a menu button of options.
+\end{classdesc}
+
+% Python Demo of:
+% \ulink{OptionMenu}{http://tix.sourceforge.net/dist/current/demos/samples/OptMenu.tcl}
+
+\begin{classdesc}{PopupMenu}{}
+The \ulink{PopupMenu}
+{http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixPopupMenu.htm}
+widget can be used as a replacement of the \code{tk_popup}
+command. The advantage of the \refmodule{Tix} \class{PopupMenu} widget
+is it requires less application code to manipulate.
+\end{classdesc}
+
+% Python Demo of:
+% \ulink{PopupMenu}{http://tix.sourceforge.net/dist/current/demos/samples/PopMenu.tcl}
+
+\begin{classdesc}{Select}{}
+The \ulink{Select}
+{http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixSelect.htm}
+widget is a container of button subwidgets. It can be used to provide
+radio-box or check-box style of selection options for the user.
+\end{classdesc}
+
+% Python Demo of:
+% \ulink{Select}{http://tix.sourceforge.net/dist/current/demos/samples/Select.tcl}
+
+\begin{classdesc}{StdButtonBox}{}
+The \ulink{StdButtonBox}
+{http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixStdButtonBox.htm}
+widget is a group of standard buttons for Motif-like dialog boxes.
+\end{classdesc}
+
+% Python Demo of:
+% \ulink{StdButtonBox}{http://tix.sourceforge.net/dist/current/demos/samples/StdBBox.tcl}
+
+
+\subsubsection{File Selectors}
+
+\begin{classdesc}{DirList}{}
+The \ulink{DirList}
+{http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixDirList.htm} widget
+displays a list view of a directory, its previous directories and its
+sub-directories. The user can choose one of the directories displayed
+in the list or change to another directory.
+\end{classdesc}
+
+% Python Demo of:
+% \ulink{DirList}{http://tix.sourceforge.net/dist/current/demos/samples/DirList.tcl}
+
+\begin{classdesc}{DirTree}{}
+The \ulink{DirTree}
+{http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixDirTree.htm}
+widget displays a tree view of a directory, its previous directories
+and its sub-directories. The user can choose one of the directories
+displayed in the list or change to another directory.
+\end{classdesc}
+
+% Python Demo of:
+% \ulink{DirTree}{http://tix.sourceforge.net/dist/current/demos/samples/DirTree.tcl}
+
+\begin{classdesc}{DirSelectDialog}{}
+The \ulink{DirSelectDialog}
+{http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixDirSelectDialog.htm}
+widget presents the directories in the file system in a dialog
+window.  The user can use this dialog window to navigate through the
+file system to select the desired directory.
+\end{classdesc}
+
+% Python Demo of:
+% \ulink{DirSelectDialog}{http://tix.sourceforge.net/dist/current/demos/samples/DirDlg.tcl}
+
+\begin{classdesc}{DirSelectBox}{}
+The \class{DirSelectBox} is similar
+to the standard Motif(TM) directory-selection box. It is generally used for
+the user to choose a directory. DirSelectBox stores the directories mostly
+recently selected into a ComboBox widget so that they can be quickly
+selected again.
+\end{classdesc}
+
+\begin{classdesc}{ExFileSelectBox}{}
+The \ulink{ExFileSelectBox}
+{http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixExFileSelectBox.htm}
+widget is usually embedded in a tixExFileSelectDialog widget. It
+provides an convenient method for the user to select files. The style
+of the \class{ExFileSelectBox} widget is very similar to the standard
+file dialog on MS Windows 3.1.
+\end{classdesc}
+
+% Python Demo of:
+%\ulink{ExFileSelectDialog}{http://tix.sourceforge.net/dist/current/demos/samples/EFileDlg.tcl}
+
+\begin{classdesc}{FileSelectBox}{}
+The \ulink{FileSelectBox}
+{http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixFileSelectBox.htm}
+is similar to the standard Motif(TM) file-selection box. It is
+generally used for the user to choose a file. FileSelectBox stores the
+files mostly recently selected into a \class{ComboBox} widget so that
+they can be quickly selected again.
+\end{classdesc}
+
+% Python Demo of:
+% \ulink{FileSelectDialog}{http://tix.sourceforge.net/dist/current/demos/samples/FileDlg.tcl}
+
+\begin{classdesc}{FileEntry}{}
+The \ulink{FileEntry}
+{http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixFileEntry.htm}
+widget can be used to input a filename. The user can type in the
+filename manually. Alternatively, the user can press the button widget
+that sits next to the entry, which will bring up a file selection
+dialog.
+\end{classdesc}
+
+% Python Demo of:
+% \ulink{FileEntry}{http://tix.sourceforge.net/dist/current/demos/samples/FileEnt.tcl}
+
+
+\subsubsection{Hierachical ListBox}
+
+\begin{classdesc}{HList}{}
+The \ulink{HList}
+{http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixHList.htm}
+widget can be used to display any data that have a hierarchical
+structure, for example, file system directory trees. The list entries
+are indented and connected by branch lines according to their places
+in the hierarchy.
+\end{classdesc}
+
+% Python Demo of:
+% \ulink{HList}{http://tix.sourceforge.net/dist/current/demos/samples/HList1.tcl}
+
+\begin{classdesc}{CheckList}{}
+The \ulink{CheckList}
+{http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixCheckList.htm}
+widget displays a list of items to be selected by the user. CheckList
+acts similarly to the Tk checkbutton or radiobutton widgets, except it
+is capable of handling many more items than checkbuttons or
+radiobuttons.
+\end{classdesc}
+
+% Python Demo of:
+% \ulink{ CheckList}{http://tix.sourceforge.net/dist/current/demos/samples/ChkList.tcl}
+% Python Demo of:
+% \ulink{ScrolledHList (1)}{http://tix.sourceforge.net/dist/current/demos/samples/SHList.tcl}
+% Python Demo of:
+% \ulink{ScrolledHList (2)}{http://tix.sourceforge.net/dist/current/demos/samples/SHList2.tcl}
+
+\begin{classdesc}{Tree}{}
+The \ulink{Tree}
+{http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixTree.htm}
+widget can be used to display hierarchical data in a tree form. The
+user can adjust the view of the tree by opening or closing parts of
+the tree.
+\end{classdesc}
+
+% Python Demo of:
+% \ulink{Tree}{http://tix.sourceforge.net/dist/current/demos/samples/Tree.tcl}
+
+% Python Demo of:
+% \ulink{Tree (Dynamic)}{http://tix.sourceforge.net/dist/current/demos/samples/DynTree.tcl}
+
+
+\subsubsection{Tabular ListBox}
+
+\begin{classdesc}{TList}{}
+The \ulink{TList}
+{http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixTList.htm}
+widget can be used to display data in a tabular format. The list
+entries of a \class{TList} widget are similar to the entries in the Tk
+listbox widget.  The main differences are (1) the \class{TList} widget
+can display the list entries in a two dimensional format and (2) you
+can use graphical images as well as multiple colors and fonts for the
+list entries.
+\end{classdesc}
+
+% Python Demo of:
+% \ulink{ScrolledTList (1)}{http://tix.sourceforge.net/dist/current/demos/samples/STList1.tcl}
+% Python Demo of:
+% \ulink{ScrolledTList (2)}{http://tix.sourceforge.net/dist/current/demos/samples/STList2.tcl}
+
+% Grid has yet to be added to Python
+% \subsubsection{Grid Widget}
+% Python Demo of:
+% \ulink{Simple Grid}{http://tix.sourceforge.net/dist/current/demos/samples/SGrid0.tcl}
+% Python Demo of:
+% \ulink{ScrolledGrid}{http://tix.sourceforge.net/dist/current/demos/samples/SGrid1.tcl}
+% Python Demo of:
+% \ulink{Editable Grid}{http://tix.sourceforge.net/dist/current/demos/samples/EditGrid.tcl}
+
+
+\subsubsection{Manager Widgets}
+
+\begin{classdesc}{PanedWindow}{}
+The \ulink{PanedWindow}
+{http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixPanedWindow.htm}
+widget allows the user to interactively manipulate the sizes of
+several panes.  The panes can be arranged either vertically or
+horizontally.  The user changes the sizes of the panes by dragging the
+resize handle between two panes.
+\end{classdesc}
+
+% Python Demo of:
+% \ulink{PanedWindow}{http://tix.sourceforge.net/dist/current/demos/samples/PanedWin.tcl}
+
+\begin{classdesc}{ListNoteBook}{}
+The \ulink{ListNoteBook}
+{http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixListNoteBook.htm}
+widget is very similar to the \class{TixNoteBook} widget: it can be
+used to display many windows in a limited space using a notebook
+metaphor. The notebook is divided into a stack of pages (windows). At
+one time only one of these pages can be shown. The user can navigate
+through these pages by choosing the name of the desired page in the
+\member{hlist} subwidget.
+\end{classdesc}
+
+% Python Demo of:
+% \ulink{ListNoteBook}{http://tix.sourceforge.net/dist/current/demos/samples/ListNBK.tcl}
+
+\begin{classdesc}{NoteBook}{}
+The \ulink{NoteBook}
+{http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixNoteBook.htm}
+widget can be used to display many windows in a limited space using a
+notebook metaphor. The notebook is divided into a stack of pages. At
+one time only one of these pages can be shown. The user can navigate
+through these pages by choosing the visual ``tabs'' at the top of the
+NoteBook widget.
+\end{classdesc}
+
+% Python Demo of:
+% \ulink{NoteBook}{http://tix.sourceforge.net/dist/current/demos/samples/NoteBook.tcl}
+
+
+% \subsubsection{Scrolled Widgets}
+% Python Demo of:
+% \ulink{ScrolledListBox}{http://tix.sourceforge.net/dist/current/demos/samples/SListBox.tcl}
+% Python Demo of:
+% \ulink{ScrolledText}{http://tix.sourceforge.net/dist/current/demos/samples/SText.tcl}
+% Python Demo of:
+% \ulink{ScrolledWindow}{http://tix.sourceforge.net/dist/current/demos/samples/SWindow.tcl}
+% Python Demo of:
+% \ulink{Canvas Object View}{http://tix.sourceforge.net/dist/current/demos/samples/CObjView.tcl}
+
+
+\subsubsection{Image Types}
+
+The \refmodule{Tix} module adds:
+\begin{itemize}
+\item 
+\ulink{pixmap}
+{http://tix.sourceforge.net/dist/current/man/html/TixCmd/pixmap.htm}
+capabilities to all \refmodule{Tix} and \refmodule{Tkinter} widgets to
+create color images from XPM files.
+
+% Python Demo of:
+% \ulink{XPM Image In Button}{http://tix.sourceforge.net/dist/current/demos/samples/Xpm.tcl}
+
+% Python Demo of:
+% \ulink{XPM Image In Menu}{http://tix.sourceforge.net/dist/current/demos/samples/Xpm1.tcl}
+
+\item
+\ulink{Compound}
+{http://tix.sourceforge.net/dist/current/man/html/TixCmd/compound.htm}
+image types can be used to create images that consists of multiple
+horizontal lines; each line is composed of a series of items (texts,
+bitmaps, images or spaces) arranged from left to right. For example, a
+compound image can be used to display a bitmap and a text string
+simultaneously in a Tk \class{Button} widget.
+
+% Python Demo of:
+% \ulink{Compound Image In Buttons}{http://tix.sourceforge.net/dist/current/demos/samples/CmpImg.tcl}
+
+% Python Demo of:
+% \ulink{Compound Image In NoteBook}{http://tix.sourceforge.net/dist/current/demos/samples/CmpImg2.tcl}
+
+% Python Demo of:
+% \ulink{Compound Image Notebook Color Tabs}{http://tix.sourceforge.net/dist/current/demos/samples/CmpImg4.tcl}
+
+% Python Demo of:
+% \ulink{Compound Image Icons}{http://tix.sourceforge.net/dist/current/demos/samples/CmpImg3.tcl}
+\end{itemize}
+
+
+\subsubsection{Miscellaneous Widgets}
+
+\begin{classdesc}{InputOnly}{}
+The \ulink{InputOnly}
+{http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixInputOnly.htm}
+widgets are to accept inputs from the user, which can be done with the
+\code{bind} command (\UNIX{} only).
+\end{classdesc}
+
+\subsubsection{Form Geometry Manager}
+
+In addition, \refmodule{Tix} augments \refmodule{Tkinter} by providing:
+
+\begin{classdesc}{Form}{}
+The \ulink{Form}
+{http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixForm.htm}
+geometry manager based on attachment rules for all Tk widgets.
+\end{classdesc}
+
+
+%begin{latexonly}
+%\subsection{Tix Class Structure}
+%
+%\begin{figure}[hbtp]
+%\centerline{\epsfig{file=hierarchy.png,width=.9\textwidth}}
+%\vspace{.5cm}
+%\caption{The Class Hierarchy of Tix Widgets}
+%\end{figure}
+%end{latexonly}
+
+\subsection{Tix Commands}
+
+\begin{classdesc}{tixCommand}{}
+The \ulink{tix commands}
+{http://tix.sourceforge.net/dist/current/man/html/TixCmd/tix.htm}
+provide access to miscellaneous elements of \refmodule{Tix}'s internal
+state and the  \refmodule{Tix} application context.  Most of the information
+manipulated by these methods pertains to the application as a whole,
+or to a screen or display, rather than to a particular window.
+
+To view the current settings, the common usage is:
+\begin{verbatim}
+import Tix
+root = Tix.Tk()
+print root.tix_configure()
+\end{verbatim}
+\end{classdesc}
+
+\begin{methoddesc}{tix_configure}{\optional{cnf,} **kw}
+Query or modify the configuration options of the Tix application
+context. If no option is specified, returns a dictionary all of the
+available options.  If option is specified with no value, then the
+method 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 method modifies the given option(s) to have the
+given value(s); in this case the method returns an empty string.
+Option may be any of the configuration options.
+\end{methoddesc}
+
+\begin{methoddesc}{tix_cget}{option}
+Returns the current value of the configuration option given by
+\var{option}. Option may be any of the configuration options.
+\end{methoddesc}
+
+\begin{methoddesc}{tix_getbitmap}{name}
+Locates a bitmap file of the name \code{name.xpm} or \code{name} in
+one of the bitmap directories (see the \method{tix_addbitmapdir()}
+method).  By using \method{tix_getbitmap()}, you can avoid hard
+coding the pathnames of the bitmap files in your application. When
+successful, it returns the complete pathname of the bitmap file,
+prefixed with the character \samp{@}.  The returned value can be used to
+configure the \code{bitmap} option of the Tk and Tix widgets.
+\end{methoddesc}
+
+\begin{methoddesc}{tix_addbitmapdir}{directory}
+Tix maintains a list of directories under which the
+\method{tix_getimage()} and \method{tix_getbitmap()} methods will
+search for image files.  The standard bitmap directory is
+\file{\$TIX_LIBRARY/bitmaps}. The \method{tix_addbitmapdir()} method
+adds \var{directory} into this list. By using this method, the image
+files of an applications can also be located using the
+\method{tix_getimage()} or \method{tix_getbitmap()} method.
+\end{methoddesc}
+
+\begin{methoddesc}{tix_filedialog}{\optional{dlgclass}}
+Returns the file selection dialog that may be shared among different
+calls from this application.  This method will create a file selection
+dialog widget when it is called the first time. This dialog will be
+returned by all subsequent calls to \method{tix_filedialog()}.  An
+optional dlgclass parameter can be passed as a string to specified
+what type of file selection dialog widget is desired.  Possible
+options are \code{tix}, \code{FileSelectDialog} or
+\code{tixExFileSelectDialog}.
+\end{methoddesc}
+
+
+\begin{methoddesc}{tix_getimage}{self, name}
+Locates an image file of the name \file{name.xpm}, \file{name.xbm} or
+\file{name.ppm} in one of the bitmap directories (see the
+\method{tix_addbitmapdir()} method above). If more than one file with
+the same name (but different extensions) exist, then the image type is
+chosen according to the depth of the X display: xbm images are chosen
+on monochrome displays and color images are chosen on color
+displays. By using \method{tix_getimage()}, you can avoid hard coding
+the pathnames of the image files in your application. When successful,
+this method returns the name of the newly created image, which can be
+used to configure the \code{image} option of the Tk and Tix widgets.
+\end{methoddesc}
+
+\begin{methoddesc}{tix_option_get}{name}
+Gets the options maintained by the Tix scheme mechanism.
+\end{methoddesc}
+
+\begin{methoddesc}{tix_resetoptions}{newScheme, newFontSet\optional{,
+                                     newScmPrio}}
+Resets the scheme and fontset of the Tix application to
+\var{newScheme} and \var{newFontSet}, respectively.  This affects only
+those widgets created after this call.  Therefore, it is best to call
+the resetoptions method before the creation of any widgets in a Tix
+application.
+
+The optional parameter \var{newScmPrio} can be given to reset the
+priority level of the Tk options set by the Tix schemes.
+
+Because of the way Tk handles the X option database, after Tix has
+been has imported and inited, it is not possible to reset the color
+schemes and font sets using the \method{tix_config()} method.
+Instead, the \method{tix_resetoptions()} method must be used.
+\end{methoddesc}
+
+
+
+\section{\module{ScrolledText} ---
+         Scrolled Text Widget}
+
+\declaremodule{standard}{ScrolledText}
+   \platform{Tk}
+\modulesynopsis{Text widget with a vertical scroll bar.}
+\sectionauthor{Fred L. Drake, Jr.}{fdrake at acm.org}
+
+The \module{ScrolledText} module provides a class of the same name
+which implements a basic text widget which has a vertical scroll bar
+configured to do the ``right thing.''  Using the \class{ScrolledText}
+class is a lot easier than setting up a text widget and scroll bar
+directly.  The constructor is the same as that of the
+\class{Tkinter.Text} class.
+
+The text widget and scrollbar are packed together in a \class{Frame},
+and the methods of the \class{Grid} and \class{Pack} geometry managers
+are acquired from the \class{Frame} object.  This allows the
+\class{ScrolledText} widget to be used directly to achieve most normal
+geometry management behavior.
+
+Should more specific control be necessary, the following attributes
+are available:
+
+\begin{memberdesc}[ScrolledText]{frame}
+  The frame which surrounds the text and scroll bar widgets.
+\end{memberdesc}
+
+\begin{memberdesc}[ScrolledText]{vbar}
+  The scroll bar widget.
+\end{memberdesc}
+
+
+\input{libturtle}
+
+
+\section{Idle \label{idle}}
+
+%\declaremodule{standard}{idle}
+%\modulesynopsis{A Python Integrated Development Environment}
+\moduleauthor{Guido van Rossum}{guido at Python.org}
+
+Idle is the Python IDE built with the \refmodule{Tkinter} GUI toolkit.  
+\index{Idle}
+\index{Python Editor}
+\index{Integrated Development Environment}
+
+
+IDLE has the following features:
+
+\begin{itemize}
+\item   coded in 100\% pure Python, using the \refmodule{Tkinter} GUI toolkit
+
+\item   cross-platform: works on Windows and \UNIX{} (on Mac OS, there are
+currently problems with Tcl/Tk)
+
+\item   multi-window text editor with multiple undo, Python colorizing
+and many other features, e.g. smart indent and call tips
+
+\item   Python shell window (a.k.a. interactive interpreter)
+
+\item   debugger (not complete, but you can set breakpoints, view  and step)
+\end{itemize}
+
+
+\subsection{Menus}
+
+\subsubsection{File menu}
+
+\begin{description}
+\item[New window]     create a new editing window
+\item[Open...]        open an existing file
+\item[Open module...] open an existing module (searches sys.path)
+\item[Class browser]  show classes and methods in current file
+\item[Path browser]   show sys.path directories, modules, classes and methods
+\end{description}
+\index{Class browser}
+\index{Path browser}
+
+\begin{description}
+\item[Save]   save current window to the associated file (unsaved
+windows have a * before and after the window title)
+
+\item[Save As...]     save current window to new file, which becomes
+the associated file
+\item[Save Copy As...]        save current window to different file
+without changing the associated file
+\end{description}
+
+\begin{description}
+\item[Close]  close current window (asks to save if unsaved)
+\item[Exit]   close all windows and quit IDLE (asks to save if unsaved)
+\end{description}
+
+
+\subsubsection{Edit menu}
+
+\begin{description}
+\item[Undo]   Undo last change to current window (max 1000 changes)
+\item[Redo]   Redo last undone change to current window
+\end{description}
+
+\begin{description}
+\item[Cut]    Copy selection into system-wide clipboard; then delete selection
+\item[Copy]   Copy selection into system-wide clipboard
+\item[Paste]  Insert system-wide clipboard into window
+\item[Select All]     Select the entire contents of the edit buffer
+\end{description}
+
+\begin{description}
+\item[Find...]        Open a search dialog box with many options
+\item[Find again]     Repeat last search
+\item[Find selection] Search for the string in the selection
+\item[Find in Files...]       Open a search dialog box for searching files
+\item[Replace...]     Open a search-and-replace dialog box
+\item[Go to line]     Ask for a line number and show that line
+\end{description}
+
+\begin{description}
+\item[Indent region]  Shift selected lines right 4 spaces
+\item[Dedent region]  Shift selected lines left 4 spaces
+\item[Comment out region]     Insert \#\# in front of selected lines
+\item[Uncomment region]       Remove leading \# or \#\# from selected lines
+\item[Tabify region]  Turns \emph{leading} stretches of spaces into tabs
+\item[Untabify region]        Turn \emph{all} tabs into the right number of spaces
+\item[Expand word]    Expand the word you have typed to match another
+                word in the same buffer; repeat to get a different expansion
+\item[Format Paragraph]       Reformat the current blank-line-separated paragraph
+\end{description}
+
+\begin{description}
+\item[Import module]  Import or reload the current module
+\item[Run script]     Execute the current file in the __main__ namespace
+\end{description}
+
+\index{Import module}
+\index{Run script}
+
+
+\subsubsection{Windows menu}
+
+\begin{description}
+\item[Zoom Height]    toggles the window between normal size (24x80)
+        and maximum height.
+\end{description}
+
+The rest of this menu lists the names of all open windows; select one
+to bring it to the foreground (deiconifying it if necessary).
+
+
+\subsubsection{Debug menu (in the Python Shell window only)}
+
+\begin{description}
+\item[Go to file/line]        look around the insert point for a filename
+                and linenumber, open the file, and show the line.
+\item[Open stack viewer]      show the stack traceback of the last exception
+\item[Debugger toggle]        Run commands in the shell under the debugger
+\item[JIT Stack viewer toggle]        Open stack viewer on traceback
+\end{description}
+
+\index{stack viewer}
+\index{debugger}
+
+
+\subsection{Basic editing and navigation}
+
+\begin{itemize}
+\item   \kbd{Backspace} deletes to the left; \kbd{Del} deletes to the right
+\item   Arrow keys and \kbd{Page Up}/\kbd{Page Down} to move around
+\item   \kbd{Home}/\kbd{End} go to begin/end of line
+\item   \kbd{C-Home}/\kbd{C-End} go to begin/end of file
+\item   Some \program{Emacs} bindings may also work, including \kbd{C-B},
+        \kbd{C-P}, \kbd{C-A}, \kbd{C-E}, \kbd{C-D}, \kbd{C-L}
+\end{itemize}
+
+
+\subsubsection{Automatic indentation}
+
+After a block-opening statement, the next line is indented by 4 spaces
+(in the Python Shell window by one tab).  After certain keywords
+(break, return etc.) the next line is dedented.  In leading
+indentation, \kbd{Backspace} deletes up to 4 spaces if they are there.
+\kbd{Tab} inserts 1-4 spaces (in the Python Shell window one tab).
+See also the indent/dedent region commands in the edit menu.
+
+
+\subsubsection{Python Shell window}
+
+\begin{itemize}
+\item   \kbd{C-C} interrupts executing command
+\item   \kbd{C-D} sends end-of-file; closes window if typed at
+a \samp{>>>~} prompt
+\end{itemize}
+
+\begin{itemize}
+\item   \kbd{Alt-p} retrieves previous command matching what you have typed
+\item   \kbd{Alt-n} retrieves next
+\item   \kbd{Return} while on any previous command retrieves that command
+\item   \kbd{Alt-/} (Expand word) is also useful here
+\end{itemize}
+
+\index{indentation}
+
+
+\subsection{Syntax colors}
+
+The coloring is applied in a background ``thread,'' so you may
+occasionally see uncolorized text.  To change the color
+scheme, edit the \code{[Colors]} section in \file{config.txt}.
+
+\begin{description}
+\item[Python syntax colors:]
+
+\begin{description}
+\item[Keywords]       orange
+\item[Strings ]       green
+\item[Comments]       red
+\item[Definitions]    blue
+\end{description}
+
+\item[Shell colors:]
+\begin{description}
+\item[Console output] brown
+\item[stdout]         blue
+\item[stderr]       dark green
+\item[stdin]       black
+\end{description}
+\end{description}
+
+
+\subsubsection{Command line usage}
+
+\begin{verbatim}
+idle.py [-c command] [-d] [-e] [-s] [-t title] [arg] ...
+
+-c command  run this command
+-d          enable debugger
+-e          edit mode; arguments are files to be edited
+-s          run $IDLESTARTUP or $PYTHONSTARTUP first
+-t title    set title of shell window
+\end{verbatim}
+
+If there are arguments:
+
+\begin{enumerate}
+\item   If \programopt{-e} is used, arguments are files opened for
+        editing and \code{sys.argv} reflects the arguments passed to
+        IDLE itself.
+
+\item   Otherwise, if \programopt{-c} is used, all arguments are
+        placed in \code{sys.argv[1:...]}, with \code{sys.argv[0]} set
+        to \code{'-c'}.
+
+\item   Otherwise, if neither \programopt{-e} nor \programopt{-c} is
+        used, the first argument is a script which is executed with
+        the remaining arguments in \code{sys.argv[1:...]}  and
+        \code{sys.argv[0]} set to the script name.  If the script name
+        is '-', no script is executed but an interactive Python
+        session is started; the arguments are still available in
+        \code{sys.argv}.
+\end{enumerate}
+
+
+\section{Other Graphical User Interface Packages
+         \label{other-gui-packages}}
+
+
+There are an number of extension widget sets to \refmodule{Tkinter}.
+
+\begin{seealso*}
+\seetitle[http://pmw.sourceforge.net/]{Python megawidgets}{is a
+toolkit for building high-level compound widgets in Python using the
+\refmodule{Tkinter} module.  It consists of a set of base classes and
+a library of flexible and extensible megawidgets built on this
+foundation. These megawidgets include notebooks, comboboxes, selection
+widgets, paned widgets, scrolled widgets, dialog windows, etc.  Also,
+with the Pmw.Blt interface to BLT, the busy, graph, stripchart, tabset
+and vector commands are be available.
+
+The initial ideas for Pmw were taken from the Tk \code{itcl}
+extensions \code{[incr Tk]} by Michael McLennan and \code{[incr
+Widgets]} by Mark Ulferts. Several of the megawidgets are direct
+translations from the itcl to Python. It offers most of the range of
+widgets that \code{[incr Widgets]} does, and is almost as complete as
+Tix, lacking however Tix's fast \class{HList} widget for drawing trees.
+}
+
+\seetitle[http://tkinter.effbot.org/]{Tkinter3000 Widget Construction
+          Kit (WCK)}{%
+is a library that allows you to write new Tkinter widgets in pure
+Python.  The WCK framework gives you full control over widget
+creation, configuration, screen appearance, and event handling.  WCK
+widgets can be very fast and light-weight, since they can operate
+directly on Python data structures, without having to transfer data
+through the Tk/Tcl layer.}
+\end{seealso*}
+
+Other GUI packages are also available for Python:
+
+\begin{seealso*}
+\seetitle[http://www.wxpython.org]{wxPython}{
+wxPython is a cross-platform GUI toolkit for Python that is built
+around the popular \ulink{wxWidgets}{http://www.wxwidgets.org/} \Cpp{}
+toolkit.  It provides a native look and feel for applications on
+Windows, Mac OS X, and \UNIX{} systems by using each platform's native
+widgets where ever possible, (GTK+ on \UNIX-like systems).  In
+addition to an extensive set of widgets, wxPython provides classes for
+online documentation and context sensitive help, printing, HTML
+viewing, low-level device context drawing, drag and drop, system
+clipboard access, an XML-based resource format and more, including an
+ever growing library of user-contributed modules.  Both the wxWidgets
+and wxPython projects are under active development and continuous
+improvement, and have active and helpful user and developer
+communities.
+}
+\seetitle[http://www.amazon.com/exec/obidos/ASIN/1932394621]
+{wxPython in Action}{
+The wxPython book, by Noel Rappin and Robin Dunn.
+}
+\seetitle{PyQt}{
+PyQt is a \program{sip}-wrapped binding to the Qt toolkit.  Qt is an
+extensive \Cpp{} GUI toolkit that is available for \UNIX, Windows and
+Mac OS X.  \program{sip} is a tool for generating bindings for \Cpp{}
+libraries as Python classes, and is specifically designed for Python.
+An online manual is available at
+\url{http://www.opendocspublishing.com/pyqt/} (errata are located at
+\url{http://www.valdyas.org/python/book.html}). 
+}
+\seetitle[http://www.riverbankcomputing.co.uk/pykde/index.php]{PyKDE}{
+PyKDE is a \program{sip}-wrapped interface to the KDE desktop
+libraries.  KDE is a desktop environment for \UNIX{} computers; the
+graphical components are based on Qt.
+}
+\seetitle[http://fxpy.sourceforge.net/]{FXPy}{
+is a Python extension module which provides an interface to the 
+\citetitle[http://www.cfdrc.com/FOX/fox.html]{FOX} GUI.
+FOX is a \Cpp{} based Toolkit for developing Graphical User Interfaces
+easily and effectively. It offers a wide, and growing, collection of
+Controls, and provides state of the art facilities such as drag and
+drop, selection, as well as OpenGL widgets for 3D graphical
+manipulation.  FOX also implements icons, images, and user-convenience
+features such as status line help, and tooltips.  
+
+Even though FOX offers a large collection of controls already, FOX
+leverages \Cpp{} to allow programmers to easily build additional Controls
+and GUI elements, simply by taking existing controls, and creating a
+derived class which simply adds or redefines the desired behavior.
+}
+\seetitle[http://www.daa.com.au/\textasciitilde james/software/pygtk/]{PyGTK}{
+is a set of bindings for the \ulink{GTK}{http://www.gtk.org/} widget set.
+It provides an object oriented interface that is slightly higher
+level than the C one. It automatically does all the type casting and
+reference counting that you would have to do normally with the C
+API. There are also
+\ulink{bindings}{http://www.daa.com.au/\textasciitilde james/gnome/}
+to  \ulink{GNOME}{http://www.gnome.org}, and a 
+\ulink{tutorial}
+{http://laguna.fmedic.unam.mx/\textasciitilde daniel/pygtutorial/pygtutorial/index.html}
+is available.
+}
+\end{seealso*}
+
+% XXX Reference URLs that compare the different UI packages

Added: vendor/Python/current/Doc/lib/tzinfo-examples.py
===================================================================
--- vendor/Python/current/Doc/lib/tzinfo-examples.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/tzinfo-examples.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,139 @@
+from datetime import tzinfo, timedelta, datetime
+
+ZERO = timedelta(0)
+HOUR = timedelta(hours=1)
+
+# A UTC class.
+
+class UTC(tzinfo):
+    """UTC"""
+
+    def utcoffset(self, dt):
+        return ZERO
+
+    def tzname(self, dt):
+        return "UTC"
+
+    def dst(self, dt):
+        return ZERO
+
+utc = UTC()
+
+# A class building tzinfo objects for fixed-offset time zones.
+# Note that FixedOffset(0, "UTC") is a different way to build a
+# UTC tzinfo object.
+
+class FixedOffset(tzinfo):
+    """Fixed offset in minutes east from UTC."""
+
+    def __init__(self, offset, name):
+        self.__offset = timedelta(minutes = offset)
+        self.__name = name
+
+    def utcoffset(self, dt):
+        return self.__offset
+
+    def tzname(self, dt):
+        return self.__name
+
+    def dst(self, dt):
+        return ZERO
+
+# A class capturing the platform's idea of local time.
+
+import time as _time
+
+STDOFFSET = timedelta(seconds = -_time.timezone)
+if _time.daylight:
+    DSTOFFSET = timedelta(seconds = -_time.altzone)
+else:
+    DSTOFFSET = STDOFFSET
+
+DSTDIFF = DSTOFFSET - STDOFFSET
+
+class LocalTimezone(tzinfo):
+
+    def utcoffset(self, dt):
+        if self._isdst(dt):
+            return DSTOFFSET
+        else:
+            return STDOFFSET
+
+    def dst(self, dt):
+        if self._isdst(dt):
+            return DSTDIFF
+        else:
+            return ZERO
+
+    def tzname(self, dt):
+        return _time.tzname[self._isdst(dt)]
+
+    def _isdst(self, dt):
+        tt = (dt.year, dt.month, dt.day,
+              dt.hour, dt.minute, dt.second,
+              dt.weekday(), 0, -1)
+        stamp = _time.mktime(tt)
+        tt = _time.localtime(stamp)
+        return tt.tm_isdst > 0
+
+Local = LocalTimezone()
+
+
+# A complete implementation of current DST rules for major US time zones.
+
+def first_sunday_on_or_after(dt):
+    days_to_go = 6 - dt.weekday()
+    if days_to_go:
+        dt += timedelta(days_to_go)
+    return dt
+
+# In the US, DST starts at 2am (standard time) on the first Sunday in April.
+DSTSTART = datetime(1, 4, 1, 2)
+# and ends at 2am (DST time; 1am standard time) on the last Sunday of Oct.
+# which is the first Sunday on or after Oct 25.
+DSTEND = datetime(1, 10, 25, 1)
+
+class USTimeZone(tzinfo):
+
+    def __init__(self, hours, reprname, stdname, dstname):
+        self.stdoffset = timedelta(hours=hours)
+        self.reprname = reprname
+        self.stdname = stdname
+        self.dstname = dstname
+
+    def __repr__(self):
+        return self.reprname
+
+    def tzname(self, dt):
+        if self.dst(dt):
+            return self.dstname
+        else:
+            return self.stdname
+
+    def utcoffset(self, dt):
+        return self.stdoffset + self.dst(dt)
+
+    def dst(self, dt):
+        if dt is None or dt.tzinfo is None:
+            # An exception may be sensible here, in one or both cases.
+            # It depends on how you want to treat them.  The default
+            # fromutc() implementation (called by the default astimezone()
+            # implementation) passes a datetime with dt.tzinfo is self.
+            return ZERO
+        assert dt.tzinfo is self
+
+        # Find first Sunday in April & the last in October.
+        start = first_sunday_on_or_after(DSTSTART.replace(year=dt.year))
+        end = first_sunday_on_or_after(DSTEND.replace(year=dt.year))
+
+        # Can't compare naive to aware objects, so strip the timezone from
+        # dt first.
+        if start <= dt.replace(tzinfo=None) < end:
+            return HOUR
+        else:
+            return ZERO
+
+Eastern  = USTimeZone(-5, "Eastern",  "EST", "EDT")
+Central  = USTimeZone(-6, "Central",  "CST", "CDT")
+Mountain = USTimeZone(-7, "Mountain", "MST", "MDT")
+Pacific  = USTimeZone(-8, "Pacific",  "PST", "PDT")

Added: vendor/Python/current/Doc/lib/windows.tex
===================================================================
--- vendor/Python/current/Doc/lib/windows.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/windows.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,8 @@
+\chapter{MS Windows Specific Services}
+
+
+This chapter describes modules that are only available on MS Windows
+platforms.
+
+
+\localmoduletable

Added: vendor/Python/current/Doc/lib/xmldom.tex
===================================================================
--- vendor/Python/current/Doc/lib/xmldom.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/xmldom.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,928 @@
+\section{\module{xml.dom} ---
+         The Document Object Model API}
+
+\declaremodule{standard}{xml.dom}
+\modulesynopsis{Document Object Model API for Python.}
+\sectionauthor{Paul Prescod}{paul at prescod.net}
+\sectionauthor{Martin v. L\"owis}{martin at v.loewis.de}
+
+\versionadded{2.0}
+
+The Document Object Model, or ``DOM,'' is a cross-language API from
+the World Wide Web Consortium (W3C) for accessing and modifying XML
+documents.  A DOM implementation presents an XML document as a tree
+structure, or allows client code to build such a structure from
+scratch.  It then gives access to the structure through a set of
+objects which provided well-known interfaces.
+
+The DOM is extremely useful for random-access applications.  SAX only
+allows you a view of one bit of the document at a time.  If you are
+looking at one SAX element, you have no access to another.  If you are
+looking at a text node, you have no access to a containing element.
+When you write a SAX application, you need to keep track of your
+program's position in the document somewhere in your own code.  SAX
+does not do it for you.  Also, if you need to look ahead in the XML
+document, you are just out of luck.
+
+Some applications are simply impossible in an event driven model with
+no access to a tree.  Of course you could build some sort of tree
+yourself in SAX events, but the DOM allows you to avoid writing that
+code.  The DOM is a standard tree representation for XML data.
+
+%What if your needs are somewhere between SAX and the DOM?  Perhaps
+%you cannot afford to load the entire tree in memory but you find the
+%SAX model somewhat cumbersome and low-level.  There is also a module
+%called xml.dom.pulldom that allows you to build trees of only the
+%parts of a document that you need structured access to.  It also has
+%features that allow you to find your way around the DOM.
+% See http://www.prescod.net/python/pulldom
+
+The Document Object Model is being defined by the W3C in stages, or
+``levels'' in their terminology.  The Python mapping of the API is
+substantially based on the DOM Level~2 recommendation.  The mapping of
+the Level~3 specification, currently only available in draft form, is
+being developed by the \ulink{Python XML Special Interest
+Group}{http://www.python.org/sigs/xml-sig/} as part of the
+\ulink{PyXML package}{http://pyxml.sourceforge.net/}.  Refer to the
+documentation bundled with that package for information on the current
+state of DOM Level~3 support.
+
+DOM applications typically start by parsing some XML into a DOM.  How
+this is accomplished is not covered at all by DOM Level~1, and Level~2
+provides only limited improvements: There is a
+\class{DOMImplementation} object class which provides access to
+\class{Document} creation methods, but no way to access an XML
+reader/parser/Document builder in an implementation-independent way.
+There is also no well-defined way to access these methods without an
+existing \class{Document} object.  In Python, each DOM implementation
+will provide a function \function{getDOMImplementation()}. DOM Level~3
+adds a Load/Store specification, which defines an interface to the
+reader, but this is not yet available in the Python standard library.
+
+Once you have a DOM document object, you can access the parts of your
+XML document through its properties and methods.  These properties are
+defined in the DOM specification; this portion of the reference manual
+describes the interpretation of the specification in Python.
+
+The specification provided by the W3C defines the DOM API for Java,
+ECMAScript, and OMG IDL.  The Python mapping defined here is based in
+large part on the IDL version of the specification, but strict
+compliance is not required (though implementations are free to support
+the strict mapping from IDL).  See section \ref{dom-conformance},
+``Conformance,'' for a detailed discussion of mapping requirements.
+
+
+\begin{seealso}
+  \seetitle[http://www.w3.org/TR/DOM-Level-2-Core/]{Document Object
+            Model (DOM) Level~2 Specification}
+           {The W3C recommendation upon which the Python DOM API is
+            based.}
+  \seetitle[http://www.w3.org/TR/REC-DOM-Level-1/]{Document Object
+            Model (DOM) Level~1 Specification}
+           {The W3C recommendation for the
+            DOM supported by \module{xml.dom.minidom}.}
+  \seetitle[http://pyxml.sourceforge.net]{PyXML}{Users that require a
+            full-featured implementation of DOM should use the PyXML
+            package.}
+  \seetitle[http://www.omg.org/docs/formal/02-11-05.pdf]{Python
+            Language Mapping Specification}
+           {This specifies the mapping from OMG IDL to Python.}
+\end{seealso}
+
+\subsection{Module Contents}
+
+The \module{xml.dom} contains the following functions:
+
+\begin{funcdesc}{registerDOMImplementation}{name, factory}
+Register the \var{factory} function with the name \var{name}.  The
+factory function should return an object which implements the
+\class{DOMImplementation} interface.  The factory function can return
+the same object every time, or a new one for each call, as appropriate
+for the specific implementation (e.g. if that implementation supports
+some customization).
+\end{funcdesc}
+
+\begin{funcdesc}{getDOMImplementation}{\optional{name\optional{, features}}}
+Return a suitable DOM implementation. The \var{name} is either
+well-known, the module name of a DOM implementation, or
+\code{None}. If it is not \code{None}, imports the corresponding
+module and returns a \class{DOMImplementation} object if the import
+succeeds.  If no name is given, and if the environment variable
+\envvar{PYTHON_DOM} is set, this variable is used to find the
+implementation.
+
+If name is not given, this examines the available implementations to
+find one with the required feature set.  If no implementation can be
+found, raise an \exception{ImportError}.  The features list must be a
+sequence of \code{(\var{feature}, \var{version})} pairs which are
+passed to the \method{hasFeature()} method on available
+\class{DOMImplementation} objects.
+\end{funcdesc}
+
+
+Some convenience constants are also provided:
+
+\begin{datadesc}{EMPTY_NAMESPACE}
+  The value used to indicate that no namespace is associated with a
+  node in the DOM.  This is typically found as the
+  \member{namespaceURI} of a node, or used as the \var{namespaceURI}
+  parameter to a namespaces-specific method.
+  \versionadded{2.2}
+\end{datadesc}
+
+\begin{datadesc}{XML_NAMESPACE}
+  The namespace URI associated with the reserved prefix \code{xml}, as
+  defined by
+  \citetitle[http://www.w3.org/TR/REC-xml-names/]{Namespaces in XML}
+  (section~4).
+  \versionadded{2.2}
+\end{datadesc}
+
+\begin{datadesc}{XMLNS_NAMESPACE}
+  The namespace URI for namespace declarations, as defined by
+  \citetitle[http://www.w3.org/TR/DOM-Level-2-Core/core.html]{Document
+  Object Model (DOM) Level~2 Core Specification} (section~1.1.8).
+  \versionadded{2.2}
+\end{datadesc}
+
+\begin{datadesc}{XHTML_NAMESPACE}
+  The URI of the XHTML namespace as defined by
+  \citetitle[http://www.w3.org/TR/xhtml1/]{XHTML 1.0: The Extensible
+  HyperText Markup Language} (section~3.1.1).
+  \versionadded{2.2}
+\end{datadesc}
+
+
+% Should the Node documentation go here?
+
+In addition, \module{xml.dom} contains a base \class{Node} class and
+the DOM exception classes.  The \class{Node} class provided by this
+module does not implement any of the methods or attributes defined by
+the DOM specification; concrete DOM implementations must provide
+those.  The \class{Node} class provided as part of this module does
+provide the constants used for the \member{nodeType} attribute on
+concrete \class{Node} objects; they are located within the class
+rather than at the module level to conform with the DOM
+specifications.
+
+
+\subsection{Objects in the DOM \label{dom-objects}}
+
+The definitive documentation for the DOM is the DOM specification from
+the W3C.
+
+Note that DOM attributes may also be manipulated as nodes instead of
+as simple strings.  It is fairly rare that you must do this, however,
+so this usage is not yet documented.
+
+
+\begin{tableiii}{l|l|l}{class}{Interface}{Section}{Purpose}
+  \lineiii{DOMImplementation}{\ref{dom-implementation-objects}}
+          {Interface to the underlying implementation.}
+  \lineiii{Node}{\ref{dom-node-objects}}
+          {Base interface for most objects in a document.}
+  \lineiii{NodeList}{\ref{dom-nodelist-objects}}
+          {Interface for a sequence of nodes.}
+  \lineiii{DocumentType}{\ref{dom-documenttype-objects}}
+          {Information about the declarations needed to process a document.}
+  \lineiii{Document}{\ref{dom-document-objects}}
+          {Object which represents an entire document.}
+  \lineiii{Element}{\ref{dom-element-objects}}
+          {Element nodes in the document hierarchy.}
+  \lineiii{Attr}{\ref{dom-attr-objects}}
+          {Attribute value nodes on element nodes.}
+  \lineiii{Comment}{\ref{dom-comment-objects}}
+          {Representation of comments in the source document.}
+  \lineiii{Text}{\ref{dom-text-objects}}
+          {Nodes containing textual content from the document.}
+  \lineiii{ProcessingInstruction}{\ref{dom-pi-objects}}
+          {Processing instruction representation.}
+\end{tableiii}
+
+An additional section describes the exceptions defined for working
+with the DOM in Python.
+
+
+\subsubsection{DOMImplementation Objects
+               \label{dom-implementation-objects}}
+
+The \class{DOMImplementation} interface provides a way for
+applications to determine the availability of particular features in
+the DOM they are using.  DOM Level~2 added the ability to create new
+\class{Document} and \class{DocumentType} objects using the
+\class{DOMImplementation} as well.
+
+\begin{methoddesc}[DOMImplementation]{hasFeature}{feature, version}
+Return true if the feature identified by the pair of strings
+\var{feature} and \var{version} is implemented.
+\end{methoddesc}
+
+\begin{methoddesc}[DOMImplementation]{createDocument}{namespaceUri, qualifiedName, doctype}
+Return a new \class{Document} object (the root of the DOM), with a
+child \class{Element} object having the given \var{namespaceUri} and
+\var{qualifiedName}. The \var{doctype} must be a \class{DocumentType}
+object created by \method{createDocumentType()}, or \code{None}.
+In the Python DOM API, the first two arguments can also be \code{None}
+in order to indicate that no \class{Element} child is to be created.
+\end{methoddesc}
+
+\begin{methoddesc}[DOMImplementation]{createDocumentType}{qualifiedName, publicId, systemId}
+Return a new \class{DocumentType} object that encapsulates the given
+\var{qualifiedName}, \var{publicId}, and \var{systemId} strings,
+representing the information contained in an XML document type
+declaration.
+\end{methoddesc}
+
+
+\subsubsection{Node Objects \label{dom-node-objects}}
+
+All of the components of an XML document are subclasses of
+\class{Node}.
+
+\begin{memberdesc}[Node]{nodeType}
+An integer representing the node type.  Symbolic constants for the
+types are on the \class{Node} object:
+\constant{ELEMENT_NODE}, \constant{ATTRIBUTE_NODE},
+\constant{TEXT_NODE}, \constant{CDATA_SECTION_NODE},
+\constant{ENTITY_NODE}, \constant{PROCESSING_INSTRUCTION_NODE},
+\constant{COMMENT_NODE}, \constant{DOCUMENT_NODE},
+\constant{DOCUMENT_TYPE_NODE}, \constant{NOTATION_NODE}.
+This is a read-only attribute.
+\end{memberdesc}
+
+\begin{memberdesc}[Node]{parentNode}
+The parent of the current node, or \code{None} for the document node.
+The value is always a \class{Node} object or \code{None}.  For
+\class{Element} nodes, this will be the parent element, except for the
+root element, in which case it will be the \class{Document} object.
+For \class{Attr} nodes, this is always \code{None}.
+This is a read-only attribute.
+\end{memberdesc}
+
+\begin{memberdesc}[Node]{attributes}
+A \class{NamedNodeMap} of attribute objects.  Only elements have
+actual values for this; others provide \code{None} for this attribute.
+This is a read-only attribute.
+\end{memberdesc}
+
+\begin{memberdesc}[Node]{previousSibling}
+The node that immediately precedes this one with the same parent.  For
+instance the element with an end-tag that comes just before the
+\var{self} element's start-tag.  Of course, XML documents are made
+up of more than just elements so the previous sibling could be text, a
+comment, or something else.  If this node is the first child of the
+parent, this attribute will be \code{None}.
+This is a read-only attribute.
+\end{memberdesc}
+
+\begin{memberdesc}[Node]{nextSibling}
+The node that immediately follows this one with the same parent.  See
+also \member{previousSibling}.  If this is the last child of the
+parent, this attribute will be \code{None}.
+This is a read-only attribute.
+\end{memberdesc}
+
+\begin{memberdesc}[Node]{childNodes}
+A list of nodes contained within this node.
+This is a read-only attribute.
+\end{memberdesc}
+
+\begin{memberdesc}[Node]{firstChild}
+The first child of the node, if there are any, or \code{None}.
+This is a read-only attribute.
+\end{memberdesc}
+
+\begin{memberdesc}[Node]{lastChild}
+The last child of the node, if there are any, or \code{None}.
+This is a read-only attribute.
+\end{memberdesc}
+
+\begin{memberdesc}[Node]{localName}
+The part of the \member{tagName} following the colon if there is one,
+else the entire \member{tagName}.  The value is a string.
+\end{memberdesc}
+
+\begin{memberdesc}[Node]{prefix}
+The part of the \member{tagName} preceding the colon if there is one,
+else the empty string.  The value is a string, or \code{None}
+\end{memberdesc}
+
+\begin{memberdesc}[Node]{namespaceURI}
+The namespace associated with the element name.  This will be a
+string or \code{None}.  This is a read-only attribute.
+\end{memberdesc}
+
+\begin{memberdesc}[Node]{nodeName}
+This has a different meaning for each node type; see the DOM
+specification for details.  You can always get the information you
+would get here from another property such as the \member{tagName}
+property for elements or the \member{name} property for attributes.
+For all node types, the value of this attribute will be either a
+string or \code{None}.  This is a read-only attribute.
+\end{memberdesc}
+
+\begin{memberdesc}[Node]{nodeValue}
+This has a different meaning for each node type; see the DOM
+specification for details.  The situation is similar to that with
+\member{nodeName}.  The value is a string or \code{None}.
+\end{memberdesc}
+
+\begin{methoddesc}[Node]{hasAttributes}{}
+Returns true if the node has any attributes.
+\end{methoddesc}
+
+\begin{methoddesc}[Node]{hasChildNodes}{}
+Returns true if the node has any child nodes.
+\end{methoddesc}
+
+\begin{methoddesc}[Node]{isSameNode}{other}
+Returns true if \var{other} refers to the same node as this node.
+This is especially useful for DOM implementations which use any sort
+of proxy architecture (because more than one object can refer to the
+same node).
+
+\begin{notice}
+  This is based on a proposed DOM Level~3 API which is still in the
+  ``working draft'' stage, but this particular interface appears
+  uncontroversial.  Changes from the W3C will not necessarily affect
+  this method in the Python DOM interface (though any new W3C API for
+  this would also be supported).
+\end{notice}
+\end{methoddesc}
+
+\begin{methoddesc}[Node]{appendChild}{newChild}
+Add a new child node to this node at the end of the list of children,
+returning \var{newChild}.
+\end{methoddesc}
+
+\begin{methoddesc}[Node]{insertBefore}{newChild, refChild}
+Insert a new child node before an existing child.  It must be the case
+that \var{refChild} is a child of this node; if not,
+\exception{ValueError} is raised.  \var{newChild} is returned. If
+\var{refChild} is \code{None}, it inserts \var{newChild} at the end of
+the children's list.
+\end{methoddesc}
+
+\begin{methoddesc}[Node]{removeChild}{oldChild}
+Remove a child node.  \var{oldChild} must be a child of this node; if
+not, \exception{ValueError} is raised.  \var{oldChild} is returned on
+success.  If \var{oldChild} will not be used further, its
+\method{unlink()} method should be called.
+\end{methoddesc}
+
+\begin{methoddesc}[Node]{replaceChild}{newChild, oldChild}
+Replace an existing node with a new node. It must be the case that 
+\var{oldChild} is a child of this node; if not,
+\exception{ValueError} is raised.
+\end{methoddesc}
+
+\begin{methoddesc}[Node]{normalize}{}
+Join adjacent text nodes so that all stretches of text are stored as
+single \class{Text} instances.  This simplifies processing text from a
+DOM tree for many applications.
+\versionadded{2.1}
+\end{methoddesc}
+
+\begin{methoddesc}[Node]{cloneNode}{deep}
+Clone this node.  Setting \var{deep} means to clone all child nodes as
+well.  This returns the clone.
+\end{methoddesc}
+
+
+\subsubsection{NodeList Objects \label{dom-nodelist-objects}}
+
+A \class{NodeList} represents a sequence of nodes.  These objects are
+used in two ways in the DOM Core recommendation:  the
+\class{Element} objects provides one as its list of child nodes, and
+the \method{getElementsByTagName()} and
+\method{getElementsByTagNameNS()} methods of \class{Node} return
+objects with this interface to represent query results.
+
+The DOM Level~2 recommendation defines one method and one attribute
+for these objects:
+
+\begin{methoddesc}[NodeList]{item}{i}
+  Return the \var{i}'th item from the sequence, if there is one, or
+  \code{None}.  The index \var{i} is not allowed to be less then zero
+  or greater than or equal to the length of the sequence.
+\end{methoddesc}
+
+\begin{memberdesc}[NodeList]{length}
+  The number of nodes in the sequence.
+\end{memberdesc}
+
+In addition, the Python DOM interface requires that some additional
+support is provided to allow \class{NodeList} objects to be used as
+Python sequences.  All \class{NodeList} implementations must include
+support for \method{__len__()} and \method{__getitem__()}; this allows
+iteration over the \class{NodeList} in \keyword{for} statements and
+proper support for the \function{len()} built-in function.
+
+If a DOM implementation supports modification of the document, the
+\class{NodeList} implementation must also support the
+\method{__setitem__()} and \method{__delitem__()} methods.
+
+
+\subsubsection{DocumentType Objects \label{dom-documenttype-objects}}
+
+Information about the notations and entities declared by a document
+(including the external subset if the parser uses it and can provide
+the information) is available from a \class{DocumentType} object.  The
+\class{DocumentType} for a document is available from the
+\class{Document} object's \member{doctype} attribute; if there is no
+\code{DOCTYPE} declaration for the document, the document's
+\member{doctype} attribute will be set to \code{None} instead of an
+instance of this interface.
+
+\class{DocumentType} is a specialization of \class{Node}, and adds the
+following attributes:
+
+\begin{memberdesc}[DocumentType]{publicId}
+  The public identifier for the external subset of the document type
+  definition.  This will be a string or \code{None}.
+\end{memberdesc}
+
+\begin{memberdesc}[DocumentType]{systemId}
+  The system identifier for the external subset of the document type
+  definition.  This will be a URI as a string, or \code{None}.
+\end{memberdesc}
+
+\begin{memberdesc}[DocumentType]{internalSubset}
+  A string giving the complete internal subset from the document.
+  This does not include the brackets which enclose the subset.  If the
+  document has no internal subset, this should be \code{None}.
+\end{memberdesc}
+
+\begin{memberdesc}[DocumentType]{name}
+  The name of the root element as given in the \code{DOCTYPE}
+  declaration, if present.
+\end{memberdesc}
+
+\begin{memberdesc}[DocumentType]{entities}
+  This is a \class{NamedNodeMap} giving the definitions of external
+  entities.  For entity names defined more than once, only the first
+  definition is provided (others are ignored as required by the XML
+  recommendation).  This may be \code{None} if the information is not
+  provided by the parser, or if no entities are defined.
+\end{memberdesc}
+
+\begin{memberdesc}[DocumentType]{notations}
+  This is a \class{NamedNodeMap} giving the definitions of notations.
+  For notation names defined more than once, only the first definition
+  is provided (others are ignored as required by the XML
+  recommendation).  This may be \code{None} if the information is not
+  provided by the parser, or if no notations are defined.
+\end{memberdesc}
+
+
+\subsubsection{Document Objects \label{dom-document-objects}}
+
+A \class{Document} represents an entire XML document, including its
+constituent elements, attributes, processing instructions, comments
+etc.  Remeber that it inherits properties from \class{Node}.
+
+\begin{memberdesc}[Document]{documentElement}
+The one and only root element of the document.
+\end{memberdesc}
+
+\begin{methoddesc}[Document]{createElement}{tagName}
+Create and return a new element node.  The element is not inserted
+into the document when it is created.  You need to explicitly insert
+it with one of the other methods such as \method{insertBefore()} or
+\method{appendChild()}.
+\end{methoddesc}
+
+\begin{methoddesc}[Document]{createElementNS}{namespaceURI, tagName}
+Create and return a new element with a namespace.  The
+\var{tagName} may have a prefix.  The element is not inserted into the
+document when it is created.  You need to explicitly insert it with
+one of the other methods such as \method{insertBefore()} or
+\method{appendChild()}.
+\end{methoddesc}
+
+\begin{methoddesc}[Document]{createTextNode}{data}
+Create and return a text node containing the data passed as a
+parameter.  As with the other creation methods, this one does not
+insert the node into the tree.
+\end{methoddesc}
+
+\begin{methoddesc}[Document]{createComment}{data}
+Create and return a comment node containing the data passed as a
+parameter.  As with the other creation methods, this one does not
+insert the node into the tree.
+\end{methoddesc}
+
+\begin{methoddesc}[Document]{createProcessingInstruction}{target, data}
+Create and return a processing instruction node containing the
+\var{target} and \var{data} passed as parameters.  As with the other
+creation methods, this one does not insert the node into the tree.
+\end{methoddesc}
+
+\begin{methoddesc}[Document]{createAttribute}{name}
+Create and return an attribute node.  This method does not associate
+the attribute node with any particular element.  You must use
+\method{setAttributeNode()} on the appropriate \class{Element} object
+to use the newly created attribute instance.
+\end{methoddesc}
+
+\begin{methoddesc}[Document]{createAttributeNS}{namespaceURI, qualifiedName}
+Create and return an attribute node with a namespace.  The
+\var{tagName} may have a prefix.  This method does not associate the
+attribute node with any particular element.  You must use
+\method{setAttributeNode()} on the appropriate \class{Element} object
+to use the newly created attribute instance.
+\end{methoddesc}
+
+\begin{methoddesc}[Document]{getElementsByTagName}{tagName}
+Search for all descendants (direct children, children's children,
+etc.) with a particular element type name.
+\end{methoddesc}
+
+\begin{methoddesc}[Document]{getElementsByTagNameNS}{namespaceURI, localName}
+Search for all descendants (direct children, children's children,
+etc.) with a particular namespace URI and localname.  The localname is
+the part of the namespace after the prefix.
+\end{methoddesc}
+
+
+\subsubsection{Element Objects \label{dom-element-objects}}
+
+\class{Element} is a subclass of \class{Node}, so inherits all the
+attributes of that class.
+
+\begin{memberdesc}[Element]{tagName}
+The element type name.  In a namespace-using document it may have
+colons in it.  The value is a string.
+\end{memberdesc}
+
+\begin{methoddesc}[Element]{getElementsByTagName}{tagName}
+Same as equivalent method in the \class{Document} class.
+\end{methoddesc}
+
+\begin{methoddesc}[Element]{getElementsByTagNameNS}{tagName}
+Same as equivalent method in the \class{Document} class.
+\end{methoddesc}
+
+\begin{methoddesc}[Element]{hasAttribute}{name}
+Returns true if the element has an attribute named by \var{name}.
+\end{methoddesc}
+
+\begin{methoddesc}[Element]{hasAttributeNS}{namespaceURI, localName}
+Returns true if the element has an attribute named by
+\var{namespaceURI} and \var{localName}.
+\end{methoddesc}
+
+\begin{methoddesc}[Element]{getAttribute}{name}
+Return the value of the attribute named by \var{name} as a
+string. If no such attribute exists, an empty string is returned,
+as if the attribute had no value.
+\end{methoddesc}
+
+\begin{methoddesc}[Element]{getAttributeNode}{attrname}
+Return the \class{Attr} node for the attribute named by
+\var{attrname}.
+\end{methoddesc}
+
+\begin{methoddesc}[Element]{getAttributeNS}{namespaceURI, localName}
+Return the value of the attribute named by \var{namespaceURI} and
+\var{localName} as a string. If no such attribute exists, an empty
+string is returned, as if the attribute had no value.
+\end{methoddesc}
+
+\begin{methoddesc}[Element]{getAttributeNodeNS}{namespaceURI, localName}
+Return an attribute value as a node, given a \var{namespaceURI} and
+\var{localName}.
+\end{methoddesc}
+
+\begin{methoddesc}[Element]{removeAttribute}{name}
+Remove an attribute by name.  No exception is raised if there is no
+matching attribute.
+\end{methoddesc}
+
+\begin{methoddesc}[Element]{removeAttributeNode}{oldAttr}
+Remove and return \var{oldAttr} from the attribute list, if present.
+If \var{oldAttr} is not present, \exception{NotFoundErr} is raised.
+\end{methoddesc}
+
+\begin{methoddesc}[Element]{removeAttributeNS}{namespaceURI, localName}
+Remove an attribute by name.  Note that it uses a localName, not a
+qname.  No exception is raised if there is no matching attribute.
+\end{methoddesc}
+
+\begin{methoddesc}[Element]{setAttribute}{name, value}
+Set an attribute value from a string.
+\end{methoddesc}
+
+\begin{methoddesc}[Element]{setAttributeNode}{newAttr}
+Add a new attribute node to the element, replacing an existing
+attribute if necessary if the \member{name} attribute matches.  If a
+replacement occurs, the old attribute node will be returned.  If
+\var{newAttr} is already in use, \exception{InuseAttributeErr} will be
+raised.
+\end{methoddesc}
+
+\begin{methoddesc}[Element]{setAttributeNodeNS}{newAttr}
+Add a new attribute node to the element, replacing an existing
+attribute if necessary if the \member{namespaceURI} and
+\member{localName} attributes match.  If a replacement occurs, the old
+attribute node will be returned.  If \var{newAttr} is already in use,
+\exception{InuseAttributeErr} will be raised.
+\end{methoddesc}
+
+\begin{methoddesc}[Element]{setAttributeNS}{namespaceURI, qname, value}
+Set an attribute value from a string, given a \var{namespaceURI} and a
+\var{qname}.  Note that a qname is the whole attribute name.  This is
+different than above.
+\end{methoddesc}
+
+
+\subsubsection{Attr Objects \label{dom-attr-objects}}
+
+\class{Attr} inherits from \class{Node}, so inherits all its
+attributes.
+
+\begin{memberdesc}[Attr]{name}
+The attribute name.  In a namespace-using document it may have colons
+in it.
+\end{memberdesc}
+
+\begin{memberdesc}[Attr]{localName}
+The part of the name following the colon if there is one, else the
+entire name.  This is a read-only attribute.
+\end{memberdesc}
+
+\begin{memberdesc}[Attr]{prefix}
+The part of the name preceding the colon if there is one, else the
+empty string.
+\end{memberdesc}
+
+
+\subsubsection{NamedNodeMap Objects \label{dom-attributelist-objects}}
+
+\class{NamedNodeMap} does \emph{not} inherit from \class{Node}.
+
+\begin{memberdesc}[NamedNodeMap]{length}
+The length of the attribute list.
+\end{memberdesc}
+
+\begin{methoddesc}[NamedNodeMap]{item}{index}
+Return an attribute with a particular index.  The order you get the
+attributes in is arbitrary but will be consistent for the life of a
+DOM.  Each item is an attribute node.  Get its value with the
+\member{value} attribute.
+\end{methoddesc}
+
+There are also experimental methods that give this class more mapping
+behavior.  You can use them or you can use the standardized
+\method{getAttribute*()} family of methods on the \class{Element}
+objects.
+
+
+\subsubsection{Comment Objects \label{dom-comment-objects}}
+
+\class{Comment} represents a comment in the XML document.  It is a
+subclass of \class{Node}, but cannot have child nodes.
+
+\begin{memberdesc}[Comment]{data}
+The content of the comment as a string.  The attribute contains all
+characters between the leading \code{<!-}\code{-} and trailing
+\code{-}\code{->}, but does not include them.
+\end{memberdesc}
+
+
+\subsubsection{Text and CDATASection Objects \label{dom-text-objects}}
+
+The \class{Text} interface represents text in the XML document.  If
+the parser and DOM implementation support the DOM's XML extension,
+portions of the text enclosed in CDATA marked sections are stored in
+\class{CDATASection} objects.  These two interfaces are identical, but
+provide different values for the \member{nodeType} attribute.
+
+These interfaces extend the \class{Node} interface.  They cannot have
+child nodes.
+
+\begin{memberdesc}[Text]{data}
+The content of the text node as a string.
+\end{memberdesc}
+
+\begin{notice}
+  The use of a \class{CDATASection} node does not indicate that the
+  node represents a complete CDATA marked section, only that the
+  content of the node was part of a CDATA section.  A single CDATA
+  section may be represented by more than one node in the document
+  tree.  There is no way to determine whether two adjacent
+  \class{CDATASection} nodes represent different CDATA marked
+  sections.
+\end{notice}
+
+
+\subsubsection{ProcessingInstruction Objects \label{dom-pi-objects}}
+
+Represents a processing instruction in the XML document; this inherits
+from the \class{Node} interface and cannot have child nodes.
+
+\begin{memberdesc}[ProcessingInstruction]{target}
+The content of the processing instruction up to the first whitespace
+character.  This is a read-only attribute.
+\end{memberdesc}
+
+\begin{memberdesc}[ProcessingInstruction]{data}
+The content of the processing instruction following the first
+whitespace character.
+\end{memberdesc}
+
+
+\subsubsection{Exceptions \label{dom-exceptions}}
+
+\versionadded{2.1}
+
+The DOM Level~2 recommendation defines a single exception,
+\exception{DOMException}, and a number of constants that allow
+applications to determine what sort of error occurred.
+\exception{DOMException} instances carry a \member{code} attribute
+that provides the appropriate value for the specific exception.
+
+The Python DOM interface provides the constants, but also expands the
+set of exceptions so that a specific exception exists for each of the
+exception codes defined by the DOM.  The implementations must raise
+the appropriate specific exception, each of which carries the
+appropriate value for the \member{code} attribute.
+
+\begin{excdesc}{DOMException}
+  Base exception class used for all specific DOM exceptions.  This
+  exception class cannot be directly instantiated.
+\end{excdesc}
+
+\begin{excdesc}{DomstringSizeErr}
+  Raised when a specified range of text does not fit into a string.
+  This is not known to be used in the Python DOM implementations, but
+  may be received from DOM implementations not written in Python.
+\end{excdesc}
+
+\begin{excdesc}{HierarchyRequestErr}
+  Raised when an attempt is made to insert a node where the node type
+  is not allowed.
+\end{excdesc}
+
+\begin{excdesc}{IndexSizeErr}
+  Raised when an index or size parameter to a method is negative or
+  exceeds the allowed values.
+\end{excdesc}
+
+\begin{excdesc}{InuseAttributeErr}
+  Raised when an attempt is made to insert an \class{Attr} node that
+  is already present elsewhere in the document.
+\end{excdesc}
+
+\begin{excdesc}{InvalidAccessErr}
+  Raised if a parameter or an operation is not supported on the
+  underlying object.
+\end{excdesc}
+
+\begin{excdesc}{InvalidCharacterErr}
+  This exception is raised when a string parameter contains a
+  character that is not permitted in the context it's being used in by
+  the XML 1.0 recommendation.  For example, attempting to create an
+  \class{Element} node with a space in the element type name will
+  cause this error to be raised.
+\end{excdesc}
+
+\begin{excdesc}{InvalidModificationErr}
+  Raised when an attempt is made to modify the type of a node.
+\end{excdesc}
+
+\begin{excdesc}{InvalidStateErr}
+  Raised when an attempt is made to use an object that is not defined or is no
+  longer usable.
+\end{excdesc}
+
+\begin{excdesc}{NamespaceErr}
+  If an attempt is made to change any object in a way that is not
+  permitted with regard to the
+  \citetitle[http://www.w3.org/TR/REC-xml-names/]{Namespaces in XML}
+  recommendation, this exception is raised.
+\end{excdesc}
+
+\begin{excdesc}{NotFoundErr}
+  Exception when a node does not exist in the referenced context.  For
+  example, \method{NamedNodeMap.removeNamedItem()} will raise this if
+  the node passed in does not exist in the map.
+\end{excdesc}
+
+\begin{excdesc}{NotSupportedErr}
+  Raised when the implementation does not support the requested type
+  of object or operation.
+\end{excdesc}
+
+\begin{excdesc}{NoDataAllowedErr}
+  This is raised if data is specified for a node which does not
+  support data.
+  % XXX  a better explanation is needed!
+\end{excdesc}
+
+\begin{excdesc}{NoModificationAllowedErr}
+  Raised on attempts to modify an object where modifications are not
+  allowed (such as for read-only nodes).
+\end{excdesc}
+
+\begin{excdesc}{SyntaxErr}
+  Raised when an invalid or illegal string is specified.
+  % XXX  how is this different from InvalidCharacterErr ???
+\end{excdesc}
+
+\begin{excdesc}{WrongDocumentErr}
+  Raised when a node is inserted in a different document than it
+  currently belongs to, and the implementation does not support
+  migrating the node from one document to the other.
+\end{excdesc}
+
+The exception codes defined in the DOM recommendation map to the
+exceptions described above according to this table:
+
+\begin{tableii}{l|l}{constant}{Constant}{Exception}
+  \lineii{DOMSTRING_SIZE_ERR}{\exception{DomstringSizeErr}}
+  \lineii{HIERARCHY_REQUEST_ERR}{\exception{HierarchyRequestErr}}
+  \lineii{INDEX_SIZE_ERR}{\exception{IndexSizeErr}}
+  \lineii{INUSE_ATTRIBUTE_ERR}{\exception{InuseAttributeErr}}
+  \lineii{INVALID_ACCESS_ERR}{\exception{InvalidAccessErr}}
+  \lineii{INVALID_CHARACTER_ERR}{\exception{InvalidCharacterErr}}
+  \lineii{INVALID_MODIFICATION_ERR}{\exception{InvalidModificationErr}}
+  \lineii{INVALID_STATE_ERR}{\exception{InvalidStateErr}}
+  \lineii{NAMESPACE_ERR}{\exception{NamespaceErr}}
+  \lineii{NOT_FOUND_ERR}{\exception{NotFoundErr}}
+  \lineii{NOT_SUPPORTED_ERR}{\exception{NotSupportedErr}}
+  \lineii{NO_DATA_ALLOWED_ERR}{\exception{NoDataAllowedErr}}
+  \lineii{NO_MODIFICATION_ALLOWED_ERR}{\exception{NoModificationAllowedErr}}
+  \lineii{SYNTAX_ERR}{\exception{SyntaxErr}}
+  \lineii{WRONG_DOCUMENT_ERR}{\exception{WrongDocumentErr}}
+\end{tableii}
+
+
+\subsection{Conformance \label{dom-conformance}}
+
+This section describes the conformance requirements and relationships
+between the Python DOM API, the W3C DOM recommendations, and the OMG
+IDL mapping for Python.
+
+
+\subsubsection{Type Mapping \label{dom-type-mapping}}
+
+The primitive IDL types used in the DOM specification are mapped to
+Python types according to the following table.
+
+\begin{tableii}{l|l}{code}{IDL Type}{Python Type}
+  \lineii{boolean}{\code{IntegerType} (with a value of \code{0} or \code{1})}
+  \lineii{int}{\code{IntegerType}}
+  \lineii{long int}{\code{IntegerType}}
+  \lineii{unsigned int}{\code{IntegerType}}
+\end{tableii}
+
+Additionally, the \class{DOMString} defined in the recommendation is
+mapped to a Python string or Unicode string.  Applications should
+be able to handle Unicode whenever a string is returned from the DOM.
+
+The IDL \keyword{null} value is mapped to \code{None}, which may be
+accepted or provided by the implementation whenever \keyword{null} is
+allowed by the API.
+
+
+\subsubsection{Accessor Methods \label{dom-accessor-methods}}
+
+The mapping from OMG IDL to Python defines accessor functions for IDL
+\keyword{attribute} declarations in much the way the Java mapping
+does.  Mapping the IDL declarations
+
+\begin{verbatim}
+readonly attribute string someValue;
+         attribute string anotherValue;
+\end{verbatim}
+
+yields three accessor functions:  a ``get'' method for
+\member{someValue} (\method{_get_someValue()}), and ``get'' and
+``set'' methods for
+\member{anotherValue} (\method{_get_anotherValue()} and
+\method{_set_anotherValue()}).  The mapping, in particular, does not
+require that the IDL attributes are accessible as normal Python
+attributes:  \code{\var{object}.someValue} is \emph{not} required to
+work, and may raise an \exception{AttributeError}.
+
+The Python DOM API, however, \emph{does} require that normal attribute
+access work.  This means that the typical surrogates generated by
+Python IDL compilers are not likely to work, and wrapper objects may
+be needed on the client if the DOM objects are accessed via CORBA.
+While this does require some additional consideration for CORBA DOM
+clients, the implementers with experience using DOM over CORBA from
+Python do not consider this a problem.  Attributes that are declared
+\keyword{readonly} may not restrict write access in all DOM
+implementations.
+
+In the Python DOM API, accessor functions are not required.  If provided,
+they should take the form defined by the Python IDL mapping, but
+these methods are considered unnecessary since the attributes are
+accessible directly from Python.  ``Set'' accessors should never be
+provided for \keyword{readonly} attributes.
+
+The IDL definitions do not fully embody the requirements of the W3C DOM
+API, such as the notion of certain objects, such as the return value of
+\method{getElementsByTagName()}, being ``live''.  The Python DOM API
+does not require implementations to enforce such requirements.

Added: vendor/Python/current/Doc/lib/xmldomminidom.tex
===================================================================
--- vendor/Python/current/Doc/lib/xmldomminidom.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/xmldomminidom.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,285 @@
+\section{\module{xml.dom.minidom} ---
+         Lightweight DOM implementation}
+
+\declaremodule{standard}{xml.dom.minidom}
+\modulesynopsis{Lightweight Document Object Model (DOM) implementation.}
+\moduleauthor{Paul Prescod}{paul at prescod.net}
+\sectionauthor{Paul Prescod}{paul at prescod.net}
+\sectionauthor{Martin v. L\"owis}{martin at v.loewis.de}
+
+\versionadded{2.0}
+
+\module{xml.dom.minidom} is a light-weight implementation of the
+Document Object Model interface.  It is intended to be
+simpler than the full DOM and also significantly smaller.
+
+DOM applications typically start by parsing some XML into a DOM.  With
+\module{xml.dom.minidom}, this is done through the parse functions:
+
+\begin{verbatim}
+from xml.dom.minidom import parse, parseString
+
+dom1 = parse('c:\\temp\\mydata.xml') # parse an XML file by name
+
+datasource = open('c:\\temp\\mydata.xml')
+dom2 = parse(datasource)   # parse an open file
+
+dom3 = parseString('<myxml>Some data<empty/> some more data</myxml>')
+\end{verbatim}
+
+The \function{parse()} function can take either a filename or an open
+file object.
+
+\begin{funcdesc}{parse}{filename_or_file{, parser}}
+  Return a \class{Document} from the given input. \var{filename_or_file}
+  may be either a file name, or a file-like object. \var{parser}, if
+  given, must be a SAX2 parser object. This function will change the
+  document handler of the parser and activate namespace support; other
+  parser configuration (like setting an entity resolver) must have been
+  done in advance.
+\end{funcdesc}
+
+If you have XML in a string, you can use the
+\function{parseString()} function instead:
+
+\begin{funcdesc}{parseString}{string\optional{, parser}}
+  Return a \class{Document} that represents the \var{string}. This
+  method creates a \class{StringIO} object for the string and passes
+  that on to \function{parse}.
+\end{funcdesc}
+
+Both functions return a \class{Document} object representing the
+content of the document.
+
+What the \function{parse()} and \function{parseString()} functions do
+is connect an XML parser with a ``DOM builder'' that can accept parse
+events from any SAX parser and convert them into a DOM tree.  The name
+of the functions are perhaps misleading, but are easy to grasp when
+learning the interfaces.  The parsing of the document will be
+completed before these functions return; it's simply that these
+functions do not provide a parser implementation themselves.
+
+You can also create a \class{Document} by calling a method on a ``DOM
+Implementation'' object.  You can get this object either by calling
+the \function{getDOMImplementation()} function in the
+\refmodule{xml.dom} package or the \module{xml.dom.minidom} module.
+Using the implementation from the \module{xml.dom.minidom} module will
+always return a \class{Document} instance from the minidom
+implementation, while the version from \refmodule{xml.dom} may provide
+an alternate implementation (this is likely if you have the
+\ulink{PyXML package}{http://pyxml.sourceforge.net/} installed).  Once
+you have a \class{Document}, you can add child nodes to it to populate
+the DOM:
+
+\begin{verbatim}
+from xml.dom.minidom import getDOMImplementation
+
+impl = getDOMImplementation()
+
+newdoc = impl.createDocument(None, "some_tag", None)
+top_element = newdoc.documentElement
+text = newdoc.createTextNode('Some textual content.')
+top_element.appendChild(text)
+\end{verbatim}
+
+Once you have a DOM document object, you can access the parts of your
+XML document through its properties and methods.  These properties are
+defined in the DOM specification.  The main property of the document
+object is the \member{documentElement} property.  It gives you the
+main element in the XML document: the one that holds all others.  Here
+is an example program:
+
+\begin{verbatim}
+dom3 = parseString("<myxml>Some data</myxml>")
+assert dom3.documentElement.tagName == "myxml"
+\end{verbatim}
+
+When you are finished with a DOM, you should clean it up.  This is
+necessary because some versions of Python do not support garbage
+collection of objects that refer to each other in a cycle.  Until this
+restriction is removed from all versions of Python, it is safest to
+write your code as if cycles would not be cleaned up.
+
+The way to clean up a DOM is to call its \method{unlink()} method:
+
+\begin{verbatim}
+dom1.unlink()
+dom2.unlink()
+dom3.unlink()
+\end{verbatim}
+
+\method{unlink()} is a \module{xml.dom.minidom}-specific extension to
+the DOM API.  After calling \method{unlink()} on a node, the node and
+its descendants are essentially useless.
+
+\begin{seealso}
+  \seetitle[http://www.w3.org/TR/REC-DOM-Level-1/]{Document Object
+            Model (DOM) Level 1 Specification}
+           {The W3C recommendation for the
+            DOM supported by \module{xml.dom.minidom}.}
+\end{seealso}
+
+
+\subsection{DOM Objects \label{dom-objects}}
+
+The definition of the DOM API for Python is given as part of the
+\refmodule{xml.dom} module documentation.  This section lists the
+differences between the API and \refmodule{xml.dom.minidom}.
+
+
+\begin{methoddesc}[Node]{unlink}{}
+Break internal references within the DOM so that it will be garbage
+collected on versions of Python without cyclic GC.  Even when cyclic
+GC is available, using this can make large amounts of memory available
+sooner, so calling this on DOM objects as soon as they are no longer
+needed is good practice.  This only needs to be called on the
+\class{Document} object, but may be called on child nodes to discard
+children of that node.
+\end{methoddesc}
+
+\begin{methoddesc}[Node]{writexml}{writer\optional{,indent=""\optional{,addindent=""\optional{,newl=""}}}}
+Write XML to the writer object.  The writer should have a
+\method{write()} method which matches that of the file object
+interface.  The \var{indent} parameter is the indentation of the current
+node.  The \var{addindent} parameter is the incremental indentation to use
+for subnodes of the current one.  The \var{newl} parameter specifies the
+string to use to terminate newlines.
+
+\versionchanged[The optional keyword parameters
+\var{indent}, \var{addindent}, and \var{newl} were added to support pretty
+output]{2.1}
+
+\versionchanged[For the \class{Document} node, an additional keyword
+argument \var{encoding} can be used to specify the encoding field of the XML
+header]{2.3}
+\end{methoddesc}
+
+\begin{methoddesc}[Node]{toxml}{\optional{encoding}}
+Return the XML that the DOM represents as a string.
+
+With no argument, the XML header does not specify an encoding, and the
+result is Unicode string if the default encoding cannot represent all
+characters in the document. Encoding this string in an encoding other
+than UTF-8 is likely incorrect, since UTF-8 is the default encoding of
+XML.
+
+With an explicit \var{encoding} argument, the result is a byte string
+in the specified encoding. It is recommended that this argument is
+always specified. To avoid \exception{UnicodeError} exceptions in case of
+unrepresentable text data, the encoding argument should be specified
+as "utf-8".
+
+\versionchanged[the \var{encoding} argument was introduced]{2.3}
+\end{methoddesc}
+
+\begin{methoddesc}[Node]{toprettyxml}{\optional{indent\optional{, newl}}}
+Return a pretty-printed version of the document. \var{indent} specifies
+the indentation string and defaults to a tabulator; \var{newl} specifies
+the string emitted at the end of each line and defaults to \code{\e n}.
+
+\versionadded{2.1}
+\versionchanged[the encoding argument; see \method{toxml()}]{2.3}
+\end{methoddesc}
+
+The following standard DOM methods have special considerations with
+\refmodule{xml.dom.minidom}:
+
+\begin{methoddesc}[Node]{cloneNode}{deep}
+Although this method was present in the version of
+\refmodule{xml.dom.minidom} packaged with Python 2.0, it was seriously
+broken.  This has been corrected for subsequent releases.
+\end{methoddesc}
+
+
+\subsection{DOM Example \label{dom-example}}
+
+This example program is a fairly realistic example of a simple
+program. In this particular case, we do not take much advantage
+of the flexibility of the DOM.
+
+\verbatiminput{minidom-example.py}
+
+
+\subsection{minidom and the DOM standard \label{minidom-and-dom}}
+
+The \refmodule{xml.dom.minidom} module is essentially a DOM
+1.0-compatible DOM with some DOM 2 features (primarily namespace
+features).
+
+Usage of the DOM interface in Python is straight-forward.  The
+following mapping rules apply:
+
+\begin{itemize}
+\item Interfaces are accessed through instance objects. Applications
+      should not instantiate the classes themselves; they should use
+      the creator functions available on the \class{Document} object.
+      Derived interfaces support all operations (and attributes) from
+      the base interfaces, plus any new operations.
+
+\item Operations are used as methods. Since the DOM uses only
+      \keyword{in} parameters, the arguments are passed in normal
+      order (from left to right).   There are no optional
+      arguments. \keyword{void} operations return \code{None}.
+
+\item IDL attributes map to instance attributes. For compatibility
+      with the OMG IDL language mapping for Python, an attribute
+      \code{foo} can also be accessed through accessor methods
+      \method{_get_foo()} and \method{_set_foo()}.  \keyword{readonly}
+      attributes must not be changed; this is not enforced at
+      runtime.
+
+\item The types \code{short int}, \code{unsigned int}, \code{unsigned
+      long long}, and \code{boolean} all map to Python integer
+      objects.
+
+\item The type \code{DOMString} maps to Python strings.
+      \refmodule{xml.dom.minidom} supports either byte or Unicode
+      strings, but will normally produce Unicode strings.  Values
+      of type \code{DOMString} may also be \code{None} where allowed
+      to have the IDL \code{null} value by the DOM specification from
+      the W3C.
+
+\item \keyword{const} declarations map to variables in their
+      respective scope
+      (e.g. \code{xml.dom.minidom.Node.PROCESSING_INSTRUCTION_NODE});
+      they must not be changed.
+
+\item \code{DOMException} is currently not supported in
+      \refmodule{xml.dom.minidom}.  Instead,
+      \refmodule{xml.dom.minidom} uses standard Python exceptions such
+      as \exception{TypeError} and \exception{AttributeError}.
+
+\item \class{NodeList} objects are implemented using Python's built-in
+      list type.  Starting with Python 2.2, these objects provide the
+      interface defined in the DOM specification, but with earlier
+      versions of Python they do not support the official API.  They
+      are, however, much more ``Pythonic'' than the interface defined
+      in the W3C recommendations.
+\end{itemize}
+
+
+The following interfaces have no implementation in
+\refmodule{xml.dom.minidom}:
+
+\begin{itemize}
+\item \class{DOMTimeStamp}
+
+\item \class{DocumentType} (added in Python 2.1)
+
+\item \class{DOMImplementation} (added in Python 2.1)
+
+\item \class{CharacterData}
+
+\item \class{CDATASection}
+
+\item \class{Notation}
+
+\item \class{Entity}
+
+\item \class{EntityReference}
+
+\item \class{DocumentFragment}
+\end{itemize}
+
+Most of these reflect information in the XML document that is not of
+general utility to most DOM users.

Added: vendor/Python/current/Doc/lib/xmldompulldom.tex
===================================================================
--- vendor/Python/current/Doc/lib/xmldompulldom.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/xmldompulldom.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,61 @@
+\section{\module{xml.dom.pulldom} ---
+         Support for building partial DOM trees}
+
+\declaremodule{standard}{xml.dom.pulldom}
+\modulesynopsis{Support for building partial DOM trees from SAX events.}
+\moduleauthor{Paul Prescod}{paul at prescod.net}
+
+\versionadded{2.0}
+
+\module{xml.dom.pulldom} allows building only selected portions of a
+Document Object Model representation of a document from SAX events.
+
+
+\begin{classdesc}{PullDOM}{\optional{documentFactory}}
+  \class{xml.sax.handler.ContentHandler} implementation that ...
+\end{classdesc}
+
+
+\begin{classdesc}{DOMEventStream}{stream, parser, bufsize}
+  ...
+\end{classdesc}
+
+
+\begin{classdesc}{SAX2DOM}{\optional{documentFactory}}
+  \class{xml.sax.handler.ContentHandler} implementation that ...
+\end{classdesc}
+
+
+\begin{funcdesc}{parse}{stream_or_string\optional{,
+                        parser\optional{, bufsize}}}
+  ...
+\end{funcdesc}
+
+
+\begin{funcdesc}{parseString}{string\optional{, parser}}
+  ...
+\end{funcdesc}
+
+
+\begin{datadesc}{default_bufsize}
+  Default value for the \var{bufsize} parameter to \function{parse()}.
+  \versionchanged[The value of this variable can be changed before
+                  calling \function{parse()} and the new value will
+                  take effect]{2.1}
+\end{datadesc}
+
+
+\subsection{DOMEventStream Objects \label{domeventstream-objects}}
+
+
+\begin{methoddesc}[DOMEventStream]{getEvent}{}
+  ...
+\end{methoddesc}
+
+\begin{methoddesc}[DOMEventStream]{expandNode}{node}
+  ...
+\end{methoddesc}
+
+\begin{methoddesc}[DOMEventStream]{reset}{}
+  ...
+\end{methoddesc}

Added: vendor/Python/current/Doc/lib/xmletree.tex
===================================================================
--- vendor/Python/current/Doc/lib/xmletree.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/xmletree.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,27 @@
+\section{\module{xml.etree} ---
+         The ElementTree API for XML}
+
+\declaremodule{standard}{xml.etree}
+\modulesynopsis{Package containing common ElementTree modules.}
+\moduleauthor{Fredrik Lundh}{fredrik at pythonware.com}
+
+\versionadded{2.5}
+
+The ElementTree package is a simple, efficient, and quite popular
+library for XML manipulation in Python.
+
+The \module{xml.etree} package contains the most common components
+from the ElementTree API library.
+In the current release, this package contains the \module{ElementTree},
+\module{ElementPath}, and \module{ElementInclude} modules from the full
+ElementTree distribution.
+
+% XXX To be continued!
+
+\begin{seealso}
+\seetitle[http://effbot.org/tag/elementtree]
+        {ElementTree Overview}
+        {The home page for \module{ElementTree}.  This includes links
+         to additional documentation, alternative implementations, and
+         other add-ons.}
+\end{seealso}

Added: vendor/Python/current/Doc/lib/xmlsax.tex
===================================================================
--- vendor/Python/current/Doc/lib/xmlsax.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/xmlsax.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,143 @@
+\section{\module{xml.sax} ---
+         Support for SAX2 parsers}
+
+\declaremodule{standard}{xml.sax}
+\modulesynopsis{Package containing SAX2 base classes and convenience
+                functions.}
+\moduleauthor{Lars Marius Garshol}{larsga at garshol.priv.no}
+\sectionauthor{Fred L. Drake, Jr.}{fdrake at acm.org}
+\sectionauthor{Martin v. L\"owis}{martin at v.loewis.de}
+
+\versionadded{2.0}
+
+
+The \module{xml.sax} package provides a number of modules which
+implement the Simple API for XML (SAX) interface for Python.  The
+package itself provides the SAX exceptions and the convenience
+functions which will be most used by users of the SAX API.
+
+The convenience functions are:
+
+\begin{funcdesc}{make_parser}{\optional{parser_list}}
+  Create and return a SAX \class{XMLReader} object.  The first parser
+  found will be used.  If \var{parser_list} is provided, it must be a
+  sequence of strings which name modules that have a function named
+  \function{create_parser()}.  Modules listed in \var{parser_list}
+  will be used before modules in the default list of parsers.
+\end{funcdesc}
+
+\begin{funcdesc}{parse}{filename_or_stream, handler\optional{, error_handler}}
+  Create a SAX parser and use it to parse a document.  The document,
+  passed in as \var{filename_or_stream}, can be a filename or a file
+  object.  The \var{handler} parameter needs to be a SAX
+  \class{ContentHandler} instance.  If \var{error_handler} is given,
+  it must be a SAX \class{ErrorHandler} instance; if omitted, 
+  \exception{SAXParseException} will be raised on all errors.  There
+  is no return value; all work must be done by the \var{handler}
+  passed in.
+\end{funcdesc}
+
+\begin{funcdesc}{parseString}{string, handler\optional{, error_handler}}
+  Similar to \function{parse()}, but parses from a buffer \var{string}
+  received as a parameter.
+\end{funcdesc}
+
+A typical SAX application uses three kinds of objects: readers,
+handlers and input sources.  ``Reader'' in this context is another
+term for parser, i.e.\ some piece of code that reads the bytes or
+characters from the input source, and produces a sequence of events.
+The events then get distributed to the handler objects, i.e.\ the
+reader invokes a method on the handler.  A SAX application must
+therefore obtain a reader object, create or open the input sources,
+create the handlers, and connect these objects all together.  As the
+final step of preparation, the reader is called to parse the input.
+During parsing, methods on the handler objects are called based on
+structural and syntactic events from the input data.
+
+For these objects, only the interfaces are relevant; they are normally
+not instantiated by the application itself.  Since Python does not have
+an explicit notion of interface, they are formally introduced as
+classes, but applications may use implementations which do not inherit
+from the provided classes.  The \class{InputSource}, \class{Locator},
+\class{Attributes}, \class{AttributesNS}, and
+\class{XMLReader} interfaces are defined in the module
+\refmodule{xml.sax.xmlreader}.  The handler interfaces are defined in
+\refmodule{xml.sax.handler}.  For convenience, \class{InputSource}
+(which is often instantiated directly) and the handler classes are
+also available from \module{xml.sax}.  These interfaces are described
+below.
+
+In addition to these classes, \module{xml.sax} provides the following
+exception classes.
+
+\begin{excclassdesc}{SAXException}{msg\optional{, exception}}
+  Encapsulate an XML error or warning.  This class can contain basic
+  error or warning information from either the XML parser or the
+  application: it can be subclassed to provide additional
+  functionality or to add localization.  Note that although the
+  handlers defined in the \class{ErrorHandler} interface receive
+  instances of this exception, it is not required to actually raise
+  the exception --- it is also useful as a container for information.
+
+  When instantiated, \var{msg} should be a human-readable description
+  of the error.  The optional \var{exception} parameter, if given,
+  should be \code{None} or an exception that was caught by the parsing
+  code and is being passed along as information.
+
+  This is the base class for the other SAX exception classes.
+\end{excclassdesc}
+
+\begin{excclassdesc}{SAXParseException}{msg, exception, locator}
+  Subclass of \exception{SAXException} raised on parse errors.
+  Instances of this class are passed to the methods of the SAX
+  \class{ErrorHandler} interface to provide information about the
+  parse error.  This class supports the SAX \class{Locator} interface
+  as well as the \class{SAXException} interface.
+\end{excclassdesc}
+
+\begin{excclassdesc}{SAXNotRecognizedException}{msg\optional{, exception}}
+  Subclass of \exception{SAXException} raised when a SAX
+  \class{XMLReader} is confronted with an unrecognized feature or
+  property.  SAX applications and extensions may use this class for
+  similar purposes.
+\end{excclassdesc}
+
+\begin{excclassdesc}{SAXNotSupportedException}{msg\optional{, exception}}
+  Subclass of \exception{SAXException} raised when a SAX
+  \class{XMLReader} is asked to enable a feature that is not
+  supported, or to set a property to a value that the implementation
+  does not support.  SAX applications and extensions may use this
+  class for similar purposes.
+\end{excclassdesc}
+
+
+\begin{seealso}
+  \seetitle[http://www.saxproject.org/]{SAX: The Simple API for
+            XML}{This site is the focal point for the definition of
+            the SAX API.  It provides a Java implementation and online
+            documentation.  Links to implementations and historical
+            information are also available.}
+
+  \seemodule{xml.sax.handler}{Definitions of the interfaces for
+             application-provided objects.}
+
+  \seemodule{xml.sax.saxutils}{Convenience functions for use in SAX
+             applications.}
+
+  \seemodule{xml.sax.xmlreader}{Definitions of the interfaces for
+             parser-provided objects.}
+\end{seealso}
+
+
+\subsection{SAXException Objects \label{sax-exception-objects}}
+
+The \class{SAXException} exception class supports the following
+methods:
+
+\begin{methoddesc}[SAXException]{getMessage}{}
+  Return a human-readable message describing the error condition.
+\end{methoddesc}
+
+\begin{methoddesc}[SAXException]{getException}{}
+  Return an encapsulated exception object, or \code{None}.
+\end{methoddesc}

Added: vendor/Python/current/Doc/lib/xmlsaxhandler.tex
===================================================================
--- vendor/Python/current/Doc/lib/xmlsaxhandler.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/xmlsaxhandler.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,381 @@
+\section{\module{xml.sax.handler} ---
+         Base classes for SAX handlers}
+
+\declaremodule{standard}{xml.sax.handler}
+\modulesynopsis{Base classes for SAX event handlers.}
+\sectionauthor{Martin v. L\"owis}{martin at v.loewis.de}
+\moduleauthor{Lars Marius Garshol}{larsga at garshol.priv.no}
+
+\versionadded{2.0}
+
+
+The SAX API defines four kinds of handlers: content handlers, DTD
+handlers, error handlers, and entity resolvers. Applications normally
+only need to implement those interfaces whose events they are
+interested in; they can implement the interfaces in a single object or
+in multiple objects. Handler implementations should inherit from the
+base classes provided in the module \module{xml.sax.handler}, so that all
+methods get default implementations.
+
+\begin{classdesc*}{ContentHandler}
+  This is the main callback interface in SAX, and the one most
+  important to applications. The order of events in this interface
+  mirrors the order of the information in the document.
+\end{classdesc*}
+
+\begin{classdesc*}{DTDHandler}
+  Handle DTD events.
+
+  This interface specifies only those DTD events required for basic
+  parsing (unparsed entities and attributes).
+\end{classdesc*}
+
+\begin{classdesc*}{EntityResolver}
+ Basic interface for resolving entities. If you create an object
+ implementing this interface, then register the object with your
+ Parser, the parser will call the method in your object to resolve all
+ external entities.
+\end{classdesc*}
+
+\begin{classdesc*}{ErrorHandler}
+  Interface used by the parser to present error and warning messages
+  to the application.  The methods of this object control whether errors
+  are immediately converted to exceptions or are handled in some other
+  way.
+\end{classdesc*}
+
+In addition to these classes, \module{xml.sax.handler} provides
+symbolic constants for the feature and property names.
+
+\begin{datadesc}{feature_namespaces}
+  Value: \code{"http://xml.org/sax/features/namespaces"}\\
+  true: Perform Namespace processing.\\
+  false: Optionally do not perform Namespace processing
+         (implies namespace-prefixes; default).\\
+  access: (parsing) read-only; (not parsing) read/write
+\end{datadesc}
+
+\begin{datadesc}{feature_namespace_prefixes}
+  Value: \code{"http://xml.org/sax/features/namespace-prefixes"}\\
+  true: Report the original prefixed names and attributes used for Namespace
+        declarations.\\
+  false: Do not report attributes used for Namespace declarations, and
+         optionally do not report original prefixed names (default).\\
+  access: (parsing) read-only; (not parsing) read/write  
+\end{datadesc}
+
+\begin{datadesc}{feature_string_interning}
+  Value: \code{"http://xml.org/sax/features/string-interning"}\\
+  true: All element names, prefixes, attribute names, Namespace URIs, and
+        local names are interned using the built-in intern function.\\
+  false: Names are not necessarily interned, although they may be (default).\\
+  access: (parsing) read-only; (not parsing) read/write
+\end{datadesc}
+
+\begin{datadesc}{feature_validation}
+  Value: \code{"http://xml.org/sax/features/validation"}\\
+  true: Report all validation errors (implies external-general-entities and
+        external-parameter-entities).\\
+  false: Do not report validation errors.\\
+  access: (parsing) read-only; (not parsing) read/write
+\end{datadesc}
+
+\begin{datadesc}{feature_external_ges}
+  Value: \code{"http://xml.org/sax/features/external-general-entities"}\\
+  true: Include all external general (text) entities.\\
+  false: Do not include external general entities.\\
+  access: (parsing) read-only; (not parsing) read/write
+\end{datadesc}
+
+\begin{datadesc}{feature_external_pes}
+  Value: \code{"http://xml.org/sax/features/external-parameter-entities"}\\
+  true: Include all external parameter entities, including the external
+        DTD subset.\\
+  false: Do not include any external parameter entities, even the external
+         DTD subset.\\
+  access: (parsing) read-only; (not parsing) read/write
+\end{datadesc}
+
+\begin{datadesc}{all_features}
+  List of all features.
+\end{datadesc}
+
+\begin{datadesc}{property_lexical_handler}
+  Value: \code{"http://xml.org/sax/properties/lexical-handler"}\\
+  data type: xml.sax.sax2lib.LexicalHandler (not supported in Python 2)\\
+  description: An optional extension handler for lexical events like comments.\\
+  access: read/write
+\end{datadesc}
+
+\begin{datadesc}{property_declaration_handler}
+  Value: \code{"http://xml.org/sax/properties/declaration-handler"}\\
+  data type: xml.sax.sax2lib.DeclHandler (not supported in Python 2)\\
+  description: An optional extension handler for DTD-related events other
+               than notations and unparsed entities.\\
+  access: read/write
+\end{datadesc}
+
+\begin{datadesc}{property_dom_node}
+  Value: \code{"http://xml.org/sax/properties/dom-node"}\\
+  data type: org.w3c.dom.Node (not supported in Python 2) \\
+  description: When parsing, the current DOM node being visited if this is
+               a DOM iterator; when not parsing, the root DOM node for
+               iteration.\\
+  access: (parsing) read-only; (not parsing) read/write  
+\end{datadesc}
+
+\begin{datadesc}{property_xml_string}
+  Value: \code{"http://xml.org/sax/properties/xml-string"}\\
+  data type: String\\
+  description: The literal string of characters that was the source for
+               the current event.\\
+  access: read-only
+\end{datadesc}
+
+\begin{datadesc}{all_properties}
+  List of all known property names.
+\end{datadesc}
+
+
+\subsection{ContentHandler Objects \label{content-handler-objects}}
+
+Users are expected to subclass \class{ContentHandler} to support their
+application.  The following methods are called by the parser on the
+appropriate events in the input document:
+
+\begin{methoddesc}[ContentHandler]{setDocumentLocator}{locator}
+  Called by the parser to give the application a locator for locating
+  the origin of document events.
+  
+  SAX parsers are strongly encouraged (though not absolutely required)
+  to supply a locator: if it does so, it must supply the locator to
+  the application by invoking this method before invoking any of the
+  other methods in the DocumentHandler interface.
+  
+  The locator allows the application to determine the end position of
+  any document-related event, even if the parser is not reporting an
+  error. Typically, the application will use this information for
+  reporting its own errors (such as character content that does not
+  match an application's business rules). The information returned by
+  the locator is probably not sufficient for use with a search engine.
+  
+  Note that the locator will return correct information only during
+  the invocation of the events in this interface. The application
+  should not attempt to use it at any other time.
+\end{methoddesc}
+
+\begin{methoddesc}[ContentHandler]{startDocument}{}
+  Receive notification of the beginning of a document.
+        
+  The SAX parser will invoke this method only once, before any other
+  methods in this interface or in DTDHandler (except for
+  \method{setDocumentLocator()}).
+\end{methoddesc}
+
+\begin{methoddesc}[ContentHandler]{endDocument}{}
+  Receive notification of the end of a document.
+        
+  The SAX parser will invoke this method only once, and it will be the
+  last method invoked during the parse. The parser shall not invoke
+  this method until it has either abandoned parsing (because of an
+  unrecoverable error) or reached the end of input.
+\end{methoddesc}
+
+\begin{methoddesc}[ContentHandler]{startPrefixMapping}{prefix, uri}
+  Begin the scope of a prefix-URI Namespace mapping.
+        
+  The information from this event is not necessary for normal
+  Namespace processing: the SAX XML reader will automatically replace
+  prefixes for element and attribute names when the
+  \code{feature_namespaces} feature is enabled (the default).
+
+%% XXX This is not really the default, is it? MvL
+  
+  There are cases, however, when applications need to use prefixes in
+  character data or in attribute values, where they cannot safely be
+  expanded automatically; the \method{startPrefixMapping()} and
+  \method{endPrefixMapping()} events supply the information to the
+  application to expand prefixes in those contexts itself, if
+  necessary.
+  
+  Note that \method{startPrefixMapping()} and
+  \method{endPrefixMapping()} events are not guaranteed to be properly
+  nested relative to each-other: all \method{startPrefixMapping()}
+  events will occur before the corresponding \method{startElement()}
+  event, and all \method{endPrefixMapping()} events will occur after
+  the corresponding \method{endElement()} event, but their order is
+  not guaranteed.
+\end{methoddesc}
+
+\begin{methoddesc}[ContentHandler]{endPrefixMapping}{prefix}
+  End the scope of a prefix-URI mapping.
+
+  See \method{startPrefixMapping()} for details. This event will
+  always occur after the corresponding \method{endElement()} event,
+  but the order of \method{endPrefixMapping()} events is not otherwise
+  guaranteed.
+\end{methoddesc}
+
+\begin{methoddesc}[ContentHandler]{startElement}{name, attrs}
+  Signals the start of an element in non-namespace mode.
+
+  The \var{name} parameter contains the raw XML 1.0 name of the
+  element type as a string and the \var{attrs} parameter holds an
+  object of the \ulink{\class{Attributes}
+  interface}{attributes-objects.html} containing the attributes of the
+  element.  The object passed as \var{attrs} may be re-used by the
+  parser; holding on to a reference to it is not a reliable way to
+  keep a copy of the attributes.  To keep a copy of the attributes,
+  use the \method{copy()} method of the \var{attrs} object.
+\end{methoddesc}
+
+\begin{methoddesc}[ContentHandler]{endElement}{name}
+  Signals the end of an element in non-namespace mode.
+
+  The \var{name} parameter contains the name of the element type, just
+  as with the \method{startElement()} event.
+\end{methoddesc}
+
+\begin{methoddesc}[ContentHandler]{startElementNS}{name, qname, attrs}
+  Signals the start of an element in namespace mode.
+
+  The \var{name} parameter contains the name of the element type as a
+  \code{(\var{uri}, \var{localname})} tuple, the \var{qname} parameter
+  contains the raw XML 1.0 name used in the source document, and the
+  \var{attrs} parameter holds an instance of the
+  \ulink{\class{AttributesNS} interface}{attributes-ns-objects.html}
+  containing the attributes of the element.  If no namespace is
+  associated with the element, the \var{uri} component of \var{name}
+  will be \code{None}.  The object passed as \var{attrs} may be
+  re-used by the parser; holding on to a reference to it is not a
+  reliable way to keep a copy of the attributes.  To keep a copy of
+  the attributes, use the \method{copy()} method of the \var{attrs}
+  object.
+
+  Parsers may set the \var{qname} parameter to \code{None}, unless the
+  \code{feature_namespace_prefixes} feature is activated.
+\end{methoddesc}
+
+\begin{methoddesc}[ContentHandler]{endElementNS}{name, qname}
+  Signals the end of an element in namespace mode.
+
+  The \var{name} parameter contains the name of the element type, just
+  as with the \method{startElementNS()} method, likewise the
+  \var{qname} parameter.
+\end{methoddesc}
+
+\begin{methoddesc}[ContentHandler]{characters}{content}
+  Receive notification of character data.
+        
+  The Parser will call this method to report each chunk of character
+  data. SAX parsers may return all contiguous character data in a
+  single chunk, or they may split it into several chunks; however, all
+  of the characters in any single event must come from the same
+  external entity so that the Locator provides useful information.
+
+  \var{content} may be a Unicode string or a byte string; the
+  \code{expat} reader module produces always Unicode strings.
+
+  \note{The earlier SAX 1 interface provided by the Python
+  XML Special Interest Group used a more Java-like interface for this
+  method.  Since most parsers used from Python did not take advantage
+  of the older interface, the simpler signature was chosen to replace
+  it.  To convert old code to the new interface, use \var{content}
+  instead of slicing content with the old \var{offset} and
+  \var{length} parameters.}
+\end{methoddesc}
+
+\begin{methoddesc}[ContentHandler]{ignorableWhitespace}{whitespace}
+  Receive notification of ignorable whitespace in element content.
+        
+  Validating Parsers must use this method to report each chunk
+  of ignorable whitespace (see the W3C XML 1.0 recommendation,
+  section 2.10): non-validating parsers may also use this method
+  if they are capable of parsing and using content models.
+  
+  SAX parsers may return all contiguous whitespace in a single
+  chunk, or they may split it into several chunks; however, all
+  of the characters in any single event must come from the same
+  external entity, so that the Locator provides useful
+  information.
+\end{methoddesc}
+
+\begin{methoddesc}[ContentHandler]{processingInstruction}{target, data}
+  Receive notification of a processing instruction.
+        
+  The Parser will invoke this method once for each processing
+  instruction found: note that processing instructions may occur
+  before or after the main document element.
+
+  A SAX parser should never report an XML declaration (XML 1.0,
+  section 2.8) or a text declaration (XML 1.0, section 4.3.1) using
+  this method.
+\end{methoddesc}
+
+\begin{methoddesc}[ContentHandler]{skippedEntity}{name}
+  Receive notification of a skipped entity.
+        
+  The Parser will invoke this method once for each entity
+  skipped. Non-validating processors may skip entities if they have
+  not seen the declarations (because, for example, the entity was
+  declared in an external DTD subset). All processors may skip
+  external entities, depending on the values of the
+  \code{feature_external_ges} and the
+  \code{feature_external_pes} properties.
+\end{methoddesc}
+
+
+\subsection{DTDHandler Objects \label{dtd-handler-objects}}
+
+\class{DTDHandler} instances provide the following methods:
+
+\begin{methoddesc}[DTDHandler]{notationDecl}{name, publicId, systemId}
+  Handle a notation declaration event.
+\end{methoddesc}
+
+\begin{methoddesc}[DTDHandler]{unparsedEntityDecl}{name, publicId,
+                                                   systemId, ndata}
+  Handle an unparsed entity declaration event.
+\end{methoddesc}
+
+
+\subsection{EntityResolver Objects \label{entity-resolver-objects}}
+
+\begin{methoddesc}[EntityResolver]{resolveEntity}{publicId, systemId}
+  Resolve the system identifier of an entity and return either the
+  system identifier to read from as a string, or an InputSource to
+  read from. The default implementation returns \var{systemId}.
+\end{methoddesc}
+
+
+\subsection{ErrorHandler Objects \label{sax-error-handler}}
+
+Objects with this interface are used to receive error and warning
+information from the \class{XMLReader}.  If you create an object that
+implements this interface, then register the object with your
+\class{XMLReader}, the parser will call the methods in your object to
+report all warnings and errors. There are three levels of errors
+available: warnings, (possibly) recoverable errors, and unrecoverable
+errors.  All methods take a \exception{SAXParseException} as the only
+parameter.  Errors and warnings may be converted to an exception by
+raising the passed-in exception object.
+
+\begin{methoddesc}[ErrorHandler]{error}{exception}
+  Called when the parser encounters a recoverable error.  If this method
+  does not raise an exception, parsing may continue, but further document
+  information should not be expected by the application.  Allowing the
+  parser to continue may allow additional errors to be discovered in the
+  input document.
+\end{methoddesc}
+
+\begin{methoddesc}[ErrorHandler]{fatalError}{exception}
+  Called when the parser encounters an error it cannot recover from;
+  parsing is expected to terminate when this method returns.
+\end{methoddesc}
+
+\begin{methoddesc}[ErrorHandler]{warning}{exception}
+  Called when the parser presents minor warning information to the
+  application.  Parsing is expected to continue when this method returns,
+  and document information will continue to be passed to the application.
+  Raising an exception in this method will cause parsing to end.
+\end{methoddesc}

Added: vendor/Python/current/Doc/lib/xmlsaxreader.tex
===================================================================
--- vendor/Python/current/Doc/lib/xmlsaxreader.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/xmlsaxreader.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,351 @@
+\section{\module{xml.sax.xmlreader} ---
+         Interface for XML parsers}
+
+\declaremodule{standard}{xml.sax.xmlreader}
+\modulesynopsis{Interface which SAX-compliant XML parsers must implement.}
+\sectionauthor{Martin v. L\"owis}{martin at v.loewis.de}
+\moduleauthor{Lars Marius Garshol}{larsga at garshol.priv.no}
+
+\versionadded{2.0}
+
+
+SAX parsers implement the \class{XMLReader} interface. They are
+implemented in a Python module, which must provide a function
+\function{create_parser()}. This function is invoked by 
+\function{xml.sax.make_parser()} with no arguments to create a new 
+parser object.
+
+\begin{classdesc}{XMLReader}{}
+  Base class which can be inherited by SAX parsers.
+\end{classdesc}
+
+\begin{classdesc}{IncrementalParser}{}
+  In some cases, it is desirable not to parse an input source at once,
+  but to feed chunks of the document as they get available. Note that
+  the reader will normally not read the entire file, but read it in
+  chunks as well; still \method{parse()} won't return until the entire
+  document is processed. So these interfaces should be used if the
+  blocking behaviour of \method{parse()} is not desirable.
+
+  When the parser is instantiated it is ready to begin accepting data
+  from the feed method immediately. After parsing has been finished
+  with a call to close the reset method must be called to make the
+  parser ready to accept new data, either from feed or using the parse
+  method.
+
+  Note that these methods must \emph{not} be called during parsing,
+  that is, after parse has been called and before it returns.
+
+  By default, the class also implements the parse method of the
+  XMLReader interface using the feed, close and reset methods of the
+  IncrementalParser interface as a convenience to SAX 2.0 driver
+  writers.
+\end{classdesc}
+
+\begin{classdesc}{Locator}{}
+  Interface for associating a SAX event with a document location. A
+  locator object will return valid results only during calls to
+  DocumentHandler methods; at any other time, the results are
+  unpredictable. If information is not available, methods may return
+  \code{None}.
+\end{classdesc}
+
+\begin{classdesc}{InputSource}{\optional{systemId}}
+  Encapsulation of the information needed by the \class{XMLReader} to
+  read entities.
+
+  This class may include information about the public identifier,
+  system identifier, byte stream (possibly with character encoding
+  information) and/or the character stream of an entity.
+
+  Applications will create objects of this class for use in the
+  \method{XMLReader.parse()} method and for returning from
+  EntityResolver.resolveEntity.
+
+  An \class{InputSource} belongs to the application, the
+  \class{XMLReader} is not allowed to modify \class{InputSource} objects
+  passed to it from the application, although it may make copies and
+  modify those.
+\end{classdesc}
+
+\begin{classdesc}{AttributesImpl}{attrs}
+  This is an implementation of the \ulink{\class{Attributes}
+  interface}{attributes-objects.html} (see
+  section~\ref{attributes-objects}).  This is a dictionary-like
+  object which represents the element attributes in a
+  \method{startElement()} call. In addition to the most useful
+  dictionary operations, it supports a number of other methods as
+  described by the interface. Objects of this class should be
+  instantiated by readers; \var{attrs} must be a dictionary-like
+  object containing a mapping from attribute names to attribute
+  values.
+\end{classdesc}
+
+\begin{classdesc}{AttributesNSImpl}{attrs, qnames}
+  Namespace-aware variant of \class{AttributesImpl}, which will be
+  passed to \method{startElementNS()}. It is derived from
+  \class{AttributesImpl}, but understands attribute names as
+  two-tuples of \var{namespaceURI} and \var{localname}. In addition,
+  it provides a number of methods expecting qualified names as they
+  appear in the original document.  This class implements the
+  \ulink{\class{AttributesNS} interface}{attributes-ns-objects.html}
+  (see section~\ref{attributes-ns-objects}).
+\end{classdesc}
+
+
+\subsection{XMLReader Objects \label{xmlreader-objects}}
+
+The \class{XMLReader} interface supports the following methods:
+
+\begin{methoddesc}[XMLReader]{parse}{source}
+  Process an input source, producing SAX events. The \var{source}
+  object can be a system identifier (a string identifying the
+  input source -- typically a file name or an URL), a file-like
+  object, or an \class{InputSource} object. When \method{parse()}
+  returns, the input is completely processed, and the parser object
+  can be discarded or reset. As a limitation, the current implementation
+  only accepts byte streams; processing of character streams is for
+  further study.
+\end{methoddesc}
+
+\begin{methoddesc}[XMLReader]{getContentHandler}{}
+  Return the current \class{ContentHandler}.
+\end{methoddesc}
+
+\begin{methoddesc}[XMLReader]{setContentHandler}{handler}
+  Set the current \class{ContentHandler}.  If no
+  \class{ContentHandler} is set, content events will be discarded.
+\end{methoddesc}
+
+\begin{methoddesc}[XMLReader]{getDTDHandler}{}
+  Return the current \class{DTDHandler}.
+\end{methoddesc}
+
+\begin{methoddesc}[XMLReader]{setDTDHandler}{handler}
+  Set the current \class{DTDHandler}.  If no \class{DTDHandler} is
+  set, DTD events will be discarded.
+\end{methoddesc}
+
+\begin{methoddesc}[XMLReader]{getEntityResolver}{}
+  Return the current \class{EntityResolver}.
+\end{methoddesc}
+
+\begin{methoddesc}[XMLReader]{setEntityResolver}{handler}
+  Set the current \class{EntityResolver}.  If no
+  \class{EntityResolver} is set, attempts to resolve an external
+  entity will result in opening the system identifier for the entity,
+  and fail if it is not available. 
+\end{methoddesc}
+
+\begin{methoddesc}[XMLReader]{getErrorHandler}{}
+  Return the current \class{ErrorHandler}.
+\end{methoddesc}
+
+\begin{methoddesc}[XMLReader]{setErrorHandler}{handler}
+  Set the current error handler.  If no \class{ErrorHandler} is set,
+  errors will be raised as exceptions, and warnings will be printed.
+\end{methoddesc}
+
+\begin{methoddesc}[XMLReader]{setLocale}{locale}
+  Allow an application to set the locale for errors and warnings. 
+   
+  SAX parsers are not required to provide localization for errors and
+  warnings; if they cannot support the requested locale, however, they
+  must throw a SAX exception.  Applications may request a locale change
+  in the middle of a parse.
+\end{methoddesc}
+
+\begin{methoddesc}[XMLReader]{getFeature}{featurename}
+  Return the current setting for feature \var{featurename}.  If the
+  feature is not recognized, \exception{SAXNotRecognizedException} is
+  raised. The well-known featurenames are listed in the module
+  \module{xml.sax.handler}.
+\end{methoddesc}
+
+\begin{methoddesc}[XMLReader]{setFeature}{featurename, value}
+  Set the \var{featurename} to \var{value}. If the feature is not
+  recognized, \exception{SAXNotRecognizedException} is raised. If the
+  feature or its setting is not supported by the parser,
+  \var{SAXNotSupportedException} is raised.
+\end{methoddesc}
+
+\begin{methoddesc}[XMLReader]{getProperty}{propertyname}
+  Return the current setting for property \var{propertyname}. If the
+  property is not recognized, a \exception{SAXNotRecognizedException}
+  is raised. The well-known propertynames are listed in the module
+  \module{xml.sax.handler}.
+\end{methoddesc}
+
+\begin{methoddesc}[XMLReader]{setProperty}{propertyname, value}
+  Set the \var{propertyname} to \var{value}. If the property is not
+  recognized, \exception{SAXNotRecognizedException} is raised. If the
+  property or its setting is not supported by the parser,
+  \var{SAXNotSupportedException} is raised.
+\end{methoddesc}
+
+
+\subsection{IncrementalParser Objects
+            \label{incremental-parser-objects}}
+
+Instances of \class{IncrementalParser} offer the following additional
+methods:
+
+\begin{methoddesc}[IncrementalParser]{feed}{data}
+  Process a chunk of \var{data}.
+\end{methoddesc}
+
+\begin{methoddesc}[IncrementalParser]{close}{}
+  Assume the end of the document. That will check well-formedness
+  conditions that can be checked only at the end, invoke handlers, and
+  may clean up resources allocated during parsing.
+\end{methoddesc}
+
+\begin{methoddesc}[IncrementalParser]{reset}{}
+  This method is called after close has been called to reset the
+  parser so that it is ready to parse new documents. The results of
+  calling parse or feed after close without calling reset are
+  undefined.
+\end{methoddesc}
+
+
+\subsection{Locator Objects \label{locator-objects}}
+
+Instances of \class{Locator} provide these methods:
+
+\begin{methoddesc}[Locator]{getColumnNumber}{}
+  Return the column number where the current event ends.
+\end{methoddesc}
+
+\begin{methoddesc}[Locator]{getLineNumber}{}
+  Return the line number where the current event ends.
+\end{methoddesc}
+
+\begin{methoddesc}[Locator]{getPublicId}{}
+  Return the public identifier for the current event.
+\end{methoddesc}
+
+\begin{methoddesc}[Locator]{getSystemId}{}
+  Return the system identifier for the current event.
+\end{methoddesc}
+
+
+\subsection{InputSource Objects \label{input-source-objects}}
+
+\begin{methoddesc}[InputSource]{setPublicId}{id}
+  Sets the public identifier of this \class{InputSource}.
+\end{methoddesc}
+
+\begin{methoddesc}[InputSource]{getPublicId}{}
+  Returns the public identifier of this \class{InputSource}.
+\end{methoddesc}
+
+\begin{methoddesc}[InputSource]{setSystemId}{id}
+  Sets the system identifier of this \class{InputSource}.
+\end{methoddesc}
+
+\begin{methoddesc}[InputSource]{getSystemId}{}
+  Returns the system identifier of this \class{InputSource}.
+\end{methoddesc}
+
+\begin{methoddesc}[InputSource]{setEncoding}{encoding}
+  Sets the character encoding of this \class{InputSource}.
+
+  The encoding must be a string acceptable for an XML encoding
+  declaration (see section 4.3.3 of the XML recommendation).
+ 
+  The encoding attribute of the \class{InputSource} is ignored if the
+  \class{InputSource} also contains a character stream.
+\end{methoddesc}
+
+\begin{methoddesc}[InputSource]{getEncoding}{}
+  Get the character encoding of this InputSource.
+\end{methoddesc}
+
+\begin{methoddesc}[InputSource]{setByteStream}{bytefile}
+  Set the byte stream (a Python file-like object which does not
+  perform byte-to-character conversion) for this input source.
+  
+  The SAX parser will ignore this if there is also a character stream
+  specified, but it will use a byte stream in preference to opening a
+  URI connection itself.
+  
+  If the application knows the character encoding of the byte stream,
+  it should set it with the setEncoding method.
+\end{methoddesc}
+
+\begin{methoddesc}[InputSource]{getByteStream}{}
+  Get the byte stream for this input source.
+        
+  The getEncoding method will return the character encoding for this
+  byte stream, or None if unknown.
+\end{methoddesc}
+
+\begin{methoddesc}[InputSource]{setCharacterStream}{charfile}
+  Set the character stream for this input source. (The stream must be
+  a Python 1.6 Unicode-wrapped file-like that performs conversion to
+  Unicode strings.)
+  
+  If there is a character stream specified, the SAX parser will ignore
+  any byte stream and will not attempt to open a URI connection to the
+  system identifier.
+\end{methoddesc}
+
+\begin{methoddesc}[InputSource]{getCharacterStream}{}
+  Get the character stream for this input source.
+\end{methoddesc}
+
+
+\subsection{The \class{Attributes} Interface \label{attributes-objects}}
+
+\class{Attributes} objects implement a portion of the mapping
+protocol, including the methods \method{copy()}, \method{get()},
+\method{has_key()}, \method{items()}, \method{keys()}, and
+\method{values()}.  The following methods are also provided:
+
+\begin{methoddesc}[Attributes]{getLength}{}
+  Return the number of attributes.
+\end{methoddesc}
+
+\begin{methoddesc}[Attributes]{getNames}{}
+  Return the names of the attributes.
+\end{methoddesc}
+
+\begin{methoddesc}[Attributes]{getType}{name}
+  Returns the type of the attribute \var{name}, which is normally
+  \code{'CDATA'}.
+\end{methoddesc}
+
+\begin{methoddesc}[Attributes]{getValue}{name}
+  Return the value of attribute \var{name}.
+\end{methoddesc}
+
+% getValueByQName, getNameByQName, getQNameByName, getQNames available
+% here already, but documented only for derived class.
+
+
+\subsection{The \class{AttributesNS} Interface \label{attributes-ns-objects}}
+
+This interface is a subtype of the \ulink{\class{Attributes}
+interface}{attributes-objects.html} (see
+section~\ref{attributes-objects}).  All methods supported by that
+interface are also available on \class{AttributesNS} objects.
+
+The following methods are also available:
+
+\begin{methoddesc}[AttributesNS]{getValueByQName}{name}
+  Return the value for a qualified name.
+\end{methoddesc}
+
+\begin{methoddesc}[AttributesNS]{getNameByQName}{name}
+  Return the \code{(\var{namespace}, \var{localname})} pair for a
+  qualified \var{name}.
+\end{methoddesc}
+
+\begin{methoddesc}[AttributesNS]{getQNameByName}{name}
+  Return the qualified name for a \code{(\var{namespace},
+  \var{localname})} pair.
+\end{methoddesc}
+
+\begin{methoddesc}[AttributesNS]{getQNames}{}
+  Return the qualified names of all attributes.
+\end{methoddesc}

Added: vendor/Python/current/Doc/lib/xmlsaxutils.tex
===================================================================
--- vendor/Python/current/Doc/lib/xmlsaxutils.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/lib/xmlsaxutils.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,81 @@
+\section{\module{xml.sax.saxutils} ---
+         SAX Utilities}
+
+\declaremodule{standard}{xml.sax.saxutils}
+\modulesynopsis{Convenience functions and classes for use with SAX.}
+\sectionauthor{Martin v. L\"owis}{martin at v.loewis.de}
+\moduleauthor{Lars Marius Garshol}{larsga at garshol.priv.no}
+
+\versionadded{2.0}
+
+
+The module \module{xml.sax.saxutils} contains a number of classes and
+functions that are commonly useful when creating SAX applications,
+either in direct use, or as base classes.
+
+\begin{funcdesc}{escape}{data\optional{, entities}}
+  Escape \character{\&}, \character{<}, and \character{>} in a string
+  of data.
+
+  You can escape other strings of data by passing a dictionary as the
+  optional \var{entities} parameter.  The keys and values must all be
+  strings; each key will be replaced with its corresponding value.
+\end{funcdesc}
+
+\begin{funcdesc}{unescape}{data\optional{, entities}}
+  Unescape \character{\&amp;}, \character{\&lt;}, and \character{\&gt;}
+  in a string of data.
+
+  You can unescape other strings of data by passing a dictionary as the
+  optional \var{entities} parameter.  The keys and values must all be
+  strings; each key will be replaced with its corresponding value.
+
+  \versionadded{2.3}
+\end{funcdesc}
+
+\begin{funcdesc}{quoteattr}{data\optional{, entities}}
+  Similar to \function{escape()}, but also prepares \var{data} to be
+  used as an attribute value.  The return value is a quoted version of
+  \var{data} with any additional required replacements.
+  \function{quoteattr()} will select a quote character based on the
+  content of \var{data}, attempting to avoid encoding any quote
+  characters in the string.  If both single- and double-quote
+  characters are already in \var{data}, the double-quote characters
+  will be encoded and \var{data} will be wrapped in double-quotes.  The
+  resulting string can be used directly as an attribute value:
+
+\begin{verbatim}
+>>> print "<element attr=%s>" % quoteattr("ab ' cd \" ef")
+<element attr="ab ' cd &quot; ef">
+\end{verbatim}
+
+  This function is useful when generating attribute values for HTML or
+  any SGML using the reference concrete syntax.
+  \versionadded{2.2}
+\end{funcdesc}
+
+\begin{classdesc}{XMLGenerator}{\optional{out\optional{, encoding}}}
+  This class implements the \class{ContentHandler} interface by
+  writing SAX events back into an XML document. In other words, using
+  an \class{XMLGenerator} as the content handler will reproduce the
+  original document being parsed. \var{out} should be a file-like
+  object which will default to \var{sys.stdout}. \var{encoding} is the
+  encoding of the output stream which defaults to \code{'iso-8859-1'}.
+\end{classdesc}
+
+\begin{classdesc}{XMLFilterBase}{base}
+  This class is designed to sit between an \class{XMLReader} and the
+  client application's event handlers.  By default, it does nothing
+  but pass requests up to the reader and events on to the handlers
+  unmodified, but subclasses can override specific methods to modify
+  the event stream or the configuration requests as they pass through.
+\end{classdesc}
+
+\begin{funcdesc}{prepare_input_source}{source\optional{, base}}
+  This function takes an input source and an optional base URL and
+  returns a fully resolved \class{InputSource} object ready for
+  reading.  The input source can be given as a string, a file-like
+  object, or an \class{InputSource} object; parsers will use this
+  function to implement the polymorphic \var{source} argument to their
+  \method{parse()} method.
+\end{funcdesc}

Added: vendor/Python/current/Doc/mac/libaepack.tex
===================================================================
--- vendor/Python/current/Doc/mac/libaepack.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/mac/libaepack.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,82 @@
+\section{\module{aepack} ---
+         Conversion between Python variables and AppleEvent data containers}
+
+\declaremodule{standard}{aepack}
+  \platform{Mac}
+%\moduleauthor{Jack Jansen?}{email}
+\modulesynopsis{Conversion between Python variables and AppleEvent
+                data containers.}
+\sectionauthor{Vincent Marchetti}{vincem at en.com}
+
+
+The \module{aepack} module defines functions for converting (packing)
+Python variables to AppleEvent descriptors and back (unpacking).
+Within Python the AppleEvent descriptor is handled by Python objects
+of built-in type \class{AEDesc}, defined in module \refmodule{Carbon.AE}.
+
+The \module{aepack} module defines the following functions:
+
+
+\begin{funcdesc}{pack}{x\optional{, forcetype}}
+Returns an \class{AEDesc} object  containing a conversion of Python
+value x. If \var{forcetype} is provided it specifies the descriptor
+type of the result. Otherwise, a default mapping of Python types to
+Apple Event descriptor types is used, as follows:
+
+\begin{tableii}{l|l}{textrm}{Python type}{descriptor type}
+  \lineii{\class{FSSpec}}{typeFSS}
+  \lineii{\class{FSRef}}{typeFSRef}
+  \lineii{\class{Alias}}{typeAlias}
+  \lineii{integer}{typeLong (32 bit integer)}
+  \lineii{float}{typeFloat (64 bit floating point)}
+  \lineii{string}{typeText}
+  \lineii{unicode}{typeUnicodeText}
+  \lineii{list}{typeAEList}
+  \lineii{dictionary}{typeAERecord}
+  \lineii{instance}{\emph{see below}}
+\end{tableii}  
+ 
+If \var{x} is a Python instance then this function attempts to call an
+\method{__aepack__()} method.  This method should return an
+\class{AEDesc} object.
+
+If the conversion \var{x} is not defined above, this function returns
+the Python string representation of a value (the repr() function)
+encoded as a text descriptor.
+\end{funcdesc}
+
+\begin{funcdesc}{unpack}{x\optional{, formodulename}}
+  \var{x} must be an object of type \class{AEDesc}. This function
+  returns a Python object representation of the data in the Apple
+  Event descriptor \var{x}. Simple AppleEvent data types (integer,
+  text, float) are returned as their obvious Python counterparts.
+  Apple Event lists are returned as Python lists, and the list
+  elements are recursively unpacked.  Object references
+  (ex. \code{line 3 of document 1}) are returned as instances of
+  \class{aetypes.ObjectSpecifier}, unless \code{formodulename}
+  is specified.  AppleEvent descriptors with
+  descriptor type typeFSS are returned as \class{FSSpec}
+  objects.  AppleEvent record descriptors are returned as Python
+  dictionaries, with 4-character string keys and elements recursively
+  unpacked.
+  
+  The optional \code{formodulename} argument is used by the stub packages
+  generated by \module{gensuitemodule}, and ensures that the OSA classes
+  for object specifiers are looked up in the correct module. This ensures
+  that if, say, the Finder returns an object specifier for a window
+  you get an instance of \code{Finder.Window} and not a generic
+  \code{aetypes.Window}. The former knows about all the properties
+  and elements a window has in the Finder, while the latter knows
+  no such things.
+\end{funcdesc}
+
+
+\begin{seealso}
+  \seemodule{Carbon.AE}{Built-in access to Apple Event Manager routines.}
+  \seemodule{aetypes}{Python definitions of codes for Apple Event
+                      descriptor types.}
+  \seetitle[http://developer.apple.com/techpubs/mac/IAC/IAC-2.html]{
+            Inside Macintosh: Interapplication
+            Communication}{Information about inter-process
+            communications on the Macintosh.}
+\end{seealso}

Added: vendor/Python/current/Doc/mac/libaetools.tex
===================================================================
--- vendor/Python/current/Doc/mac/libaetools.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/mac/libaetools.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,83 @@
+\section{\module{aetools} ---
+         OSA client support}
+
+\declaremodule{standard}{aetools}
+  \platform{Mac}
+%\moduleauthor{Jack Jansen?}{email}
+\modulesynopsis{Basic support for sending Apple Events}
+\sectionauthor{Jack Jansen}{Jack.Jansen at cwi.nl}
+
+
+The \module{aetools} module contains the basic functionality
+on which Python AppleScript client support is built. It also
+imports and re-exports the core functionality of the
+\module{aetypes} and \module{aepack} modules. The stub packages
+generated by \module{gensuitemodule} import the relevant
+portions of \module{aetools}, so usually you do not need to
+import it yourself. The exception to this is when you
+cannot use a generated suite package and need lower-level
+access to scripting.
+
+The \module{aetools} module itself uses the AppleEvent support
+provided by the \module{Carbon.AE} module. This has one drawback:
+you need access to the window manager, see section \ref{osx-gui-scripts}
+for details. This restriction may be lifted in future releases.
+
+
+The \module{aetools} module defines the following functions:
+
+\begin{funcdesc}{packevent}{ae, parameters, attributes}
+Stores parameters and attributes in a pre-created \code{Carbon.AE.AEDesc}
+object. \code{parameters} and \code{attributes} are 
+dictionaries mapping 4-character OSA parameter keys to Python objects. The
+objects are packed using \code{aepack.pack()}.
+\end{funcdesc}
+
+\begin{funcdesc}{unpackevent}{ae\optional{, formodulename}}
+Recursively unpacks a \code{Carbon.AE.AEDesc} event to Python objects.
+The function returns the parameter dictionary and the attribute dictionary.
+The \code{formodulename} argument is used by generated stub packages to
+control where AppleScript classes are looked up.
+\end{funcdesc}
+
+\begin{funcdesc}{keysubst}{arguments, keydict}
+Converts a Python keyword argument dictionary \code{arguments} to
+the format required by \code{packevent} by replacing the keys,
+which are Python identifiers, by the four-character OSA keys according
+to the mapping specified in \code{keydict}. Used by the generated suite
+packages.
+\end{funcdesc}
+
+\begin{funcdesc}{enumsubst}{arguments, key, edict}
+If the \code{arguments} dictionary contains an entry for \code{key}
+convert the value for that entry according to dictionary \code{edict}.
+This converts human-readable Python enumeration names to the OSA 4-character
+codes.
+Used by the generated suite
+packages.
+\end{funcdesc}
+
+The \module{aetools} module defines the following class:
+
+\begin{classdesc}{TalkTo}{\optional{signature=None, start=0, timeout=0}}
+
+Base class for the proxy used to talk to an application. \code{signature}
+overrides the class attribute \code{_signature} (which is usually set by subclasses)
+and is the 4-char creator code defining the application to talk to.
+\code{start} can be set to true to enable running the application on
+class instantiation. \code{timeout} can be specified to change the
+default timeout used while waiting for an AppleEvent reply.
+\end{classdesc}
+
+\begin{methoddesc}{_start}{}
+Test whether the application is running, and attempt to start it if not.
+\end{methoddesc}
+
+\begin{methoddesc}{send}{code, subcode\optional{, parameters, attributes}}
+Create the AppleEvent \code{Carbon.AE.AEDesc} for the verb with
+the OSA designation \code{code, subcode} (which are the usual 4-character
+strings), pack the \code{parameters} and \code{attributes} into it, send it
+to the target application, wait for the reply, unpack the reply with
+\code{unpackevent} and return the reply appleevent, the unpacked return values
+as a dictionary and the return attributes.
+\end{methoddesc}

Added: vendor/Python/current/Doc/mac/libaetypes.tex
===================================================================
--- vendor/Python/current/Doc/mac/libaetypes.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/mac/libaetypes.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,135 @@
+\section{\module{aetypes} ---
+         AppleEvent objects}
+
+\declaremodule{standard}{aetypes}
+  \platform{Mac}
+%\moduleauthor{Jack Jansen?}{email}
+\modulesynopsis{Python representation of the Apple Event Object Model.}
+\sectionauthor{Vincent Marchetti}{vincem at en.com}
+
+
+The \module{aetypes} defines classes used to represent Apple Event data
+descriptors and Apple Event object specifiers.
+
+Apple Event data is contained in descriptors, and these descriptors
+are typed. For many descriptors the Python representation is simply the
+corresponding Python type: \code{typeText} in OSA is a Python string,
+\code{typeFloat} is a float, etc. For OSA types that have no direct
+Python counterpart this module declares classes. Packing and unpacking
+instances of these classes is handled automatically by \module{aepack}.
+
+An object specifier is essentially an address of an object implemented
+in a Apple Event server. An Apple Event specifier is used as the direct
+object for an Apple Event or as the argument of an optional parameter.
+The \module{aetypes} module contains the base classes for OSA classes
+and properties, which are used by the packages generated by
+\module{gensuitemodule} to populate the classes and properties in a
+given suite.
+
+For reasons of backward compatibility, and for cases where you need to
+script an application for which you have not generated the stub package
+this module also contains object specifiers for a number of common OSA
+classes such as \code{Document}, \code{Window}, \code{Character}, etc.
+
+
+
+The \module{AEObjects} module defines the following classes to represent
+Apple Event descriptor data:
+
+\begin{classdesc}{Unknown}{type, data}
+The representation of OSA descriptor data for which the \module{aepack}
+and \module{aetypes} modules have no support, i.e. anything that is not
+represented by the other classes here and that is not equivalent to a
+simple Python value.
+\end{classdesc}
+
+\begin{classdesc}{Enum}{enum}
+An enumeration value with the given 4-character string value.
+\end{classdesc}
+
+\begin{classdesc}{InsertionLoc}{of, pos}
+Position \code{pos} in object \code{of}.
+\end{classdesc}
+
+\begin{classdesc}{Boolean}{bool}
+A boolean.
+\end{classdesc}
+
+\begin{classdesc}{StyledText}{style, text}
+Text with style information (font, face, etc) included.
+\end{classdesc}
+
+\begin{classdesc}{AEText}{script, style, text}
+Text with script system and style information included.
+\end{classdesc}
+
+\begin{classdesc}{IntlText}{script, language, text}
+Text with script system and language information included.
+\end{classdesc}
+
+\begin{classdesc}{IntlWritingCode}{script, language}
+Script system and language information.
+\end{classdesc}
+
+\begin{classdesc}{QDPoint}{v, h}
+A quickdraw point.
+\end{classdesc}
+
+\begin{classdesc}{QDRectangle}{v0, h0, v1, h1}
+A quickdraw rectangle.
+\end{classdesc}
+
+\begin{classdesc}{RGBColor}{r, g, b}
+A color.
+\end{classdesc}
+
+\begin{classdesc}{Type}{type}
+An OSA type value with the given 4-character name.
+\end{classdesc}
+
+\begin{classdesc}{Keyword}{name}
+An OSA keyword with the given 4-character name.
+\end{classdesc}
+
+\begin{classdesc}{Range}{start, stop}
+A range.
+\end{classdesc}
+
+\begin{classdesc}{Ordinal}{abso}
+Non-numeric absolute positions, such as \code{"firs"}, first, or \code{"midd"},
+middle.
+\end{classdesc}
+
+\begin{classdesc}{Logical}{logc, term}
+The logical expression of applying operator \code{logc} to
+\code{term}.
+\end{classdesc}
+
+\begin{classdesc}{Comparison}{obj1, relo, obj2}
+The comparison \code{relo} of \code{obj1} to \code{obj2}.
+\end{classdesc}
+
+The following classes are used as base classes by the generated stub
+packages to represent AppleScript classes and properties in Python:
+
+\begin{classdesc}{ComponentItem}{which\optional{, fr}}
+Abstract baseclass for an OSA class. The subclass should set the class
+attribute \code{want} to the 4-character OSA class code. Instances of
+subclasses of this class are equivalent to AppleScript Object
+Specifiers. Upon instantiation you should pass a selector in
+\code{which}, and optionally a parent object in \code{fr}.
+\end{classdesc}
+
+\begin{classdesc}{NProperty}{fr}
+Abstract baseclass for an OSA property. The subclass should set the class
+attributes \code{want} and \code{which} to designate which property we
+are talking about. Instances of subclasses of this class are Object
+Specifiers.
+\end{classdesc}
+
+\begin{classdesc}{ObjectSpecifier}{want, form, seld\optional{, fr}}
+Base class of \code{ComponentItem} and \code{NProperty}, a general
+OSA Object Specifier. See the Apple Open Scripting Architecture
+documentation for the parameters. Note that this class is not abstract.
+\end{classdesc}
+

Added: vendor/Python/current/Doc/mac/libautogil.tex
===================================================================
--- vendor/Python/current/Doc/mac/libautogil.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/mac/libautogil.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,26 @@
+\section{\module{autoGIL} ---
+         Global Interpreter Lock handling in event loops}
+
+\declaremodule{extension}{autoGIL}
+  \platform{Mac}
+\modulesynopsis{Global Interpreter Lock handling in event loops.}
+\moduleauthor{Just van Rossum}{just at letterror.com}
+
+
+The \module{autoGIL} module provides a function \function{installAutoGIL} that
+automatically locks and unlocks Python's Global Interpreter Lock
+when running an event loop.
+
+\begin{excdesc}{AutoGILError}
+Raised if the observer callback cannot be installed, for example because
+the current thread does not have a run loop.
+\end{excdesc}
+
+\begin{funcdesc}{installAutoGIL}{}
+	Install an observer callback in the event loop (CFRunLoop) for the
+	current thread, that will lock and unlock the Global Interpreter Lock
+	(GIL) at appropriate times, allowing other Python threads to run while
+	the event loop is idle.
+	
+	Availability: OSX 10.1 or later.
+\end{funcdesc}

Added: vendor/Python/current/Doc/mac/libcolorpicker.tex
===================================================================
--- vendor/Python/current/Doc/mac/libcolorpicker.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/mac/libcolorpicker.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,23 @@
+\section{\module{ColorPicker} ---
+         Color selection dialog}
+
+\declaremodule{extension}{ColorPicker}
+  \platform{Mac}
+\modulesynopsis{Interface to the standard color selection dialog.}
+\moduleauthor{Just van Rossum}{just at letterror.com}
+\sectionauthor{Fred L. Drake, Jr.}{fdrake at acm.org}
+
+
+The \module{ColorPicker} module provides access to the standard color
+picker dialog.
+
+
+\begin{funcdesc}{GetColor}{prompt, rgb}
+  Show a standard color selection dialog and allow the user to select
+  a color.  The user is given instruction by the \var{prompt} string,
+  and the default color is set to \var{rgb}.  \var{rgb} must be a
+  tuple giving the red, green, and blue components of the color.
+  \function{GetColor()} returns a tuple giving the user's selected
+  color and a flag indicating whether they accepted the selection of
+  cancelled.
+\end{funcdesc}

Added: vendor/Python/current/Doc/mac/libframework.tex
===================================================================
--- vendor/Python/current/Doc/mac/libframework.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/mac/libframework.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,314 @@
+\section{\module{FrameWork} ---
+         Interactive application framework}
+
+\declaremodule{standard}{FrameWork}
+  \platform{Mac}
+\modulesynopsis{Interactive application framework.}
+
+
+The \module{FrameWork} module contains classes that together provide a
+framework for an interactive Macintosh application. The programmer
+builds an application by creating subclasses that override various
+methods of the bases classes, thereby implementing the functionality
+wanted. Overriding functionality can often be done on various
+different levels, i.e. to handle clicks in a single dialog window in a
+non-standard way it is not necessary to override the complete event
+handling.
+
+Work on the \module{FrameWork} has pretty much stopped, now that
+\module{PyObjC} is available for full Cocoa access from Python, and the
+documentation describes only the most important functionality, and not
+in the most logical manner at that. Examine the source or the examples
+for more details.  The following are some comments posted on the
+MacPython newsgroup about the strengths and limitations of
+\module{FrameWork}:
+
+\begin{quotation}
+The strong point of \module{FrameWork} is that it allows you to break
+into the control-flow at many different places. \refmodule{W}, for
+instance, uses a different way to enable/disable menus and that plugs
+right in leaving the rest intact.  The weak points of
+\module{FrameWork} are that it has no abstract command interface (but
+that shouldn't be difficult), that its dialog support is minimal and
+that its control/toolbar support is non-existent.
+\end{quotation}
+
+
+The \module{FrameWork} module defines the following functions:
+
+
+\begin{funcdesc}{Application}{}
+An object representing the complete application. See below for a
+description of the methods. The default \method{__init__()} routine
+creates an empty window dictionary and a menu bar with an apple menu.
+\end{funcdesc}
+
+\begin{funcdesc}{MenuBar}{}
+An object representing the menubar. This object is usually not created
+by the user.
+\end{funcdesc}
+
+\begin{funcdesc}{Menu}{bar, title\optional{, after}}
+An object representing a menu. Upon creation you pass the
+\code{MenuBar} the menu appears in, the \var{title} string and a
+position (1-based) \var{after} where the menu should appear (default:
+at the end).
+\end{funcdesc}
+
+\begin{funcdesc}{MenuItem}{menu, title\optional{, shortcut, callback}}
+Create a menu item object. The arguments are the menu to create, the
+item title string and optionally the keyboard shortcut
+and a callback routine. The callback is called with the arguments
+menu-id, item number within menu (1-based), current front window and
+the event record.
+
+Instead of a callable object the callback can also be a string. In
+this case menu selection causes the lookup of a method in the topmost
+window and the application. The method name is the callback string
+with \code{'domenu_'} prepended.
+
+Calling the \code{MenuBar} \method{fixmenudimstate()} method sets the
+correct dimming for all menu items based on the current front window.
+\end{funcdesc}
+
+\begin{funcdesc}{Separator}{menu}
+Add a separator to the end of a menu.
+\end{funcdesc}
+
+\begin{funcdesc}{SubMenu}{menu, label}
+Create a submenu named \var{label} under menu \var{menu}. The menu
+object is returned.
+\end{funcdesc}
+
+\begin{funcdesc}{Window}{parent}
+Creates a (modeless) window. \var{Parent} is the application object to
+which the window belongs. The window is not displayed until later.
+\end{funcdesc}
+
+\begin{funcdesc}{DialogWindow}{parent}
+Creates a modeless dialog window.
+\end{funcdesc}
+
+\begin{funcdesc}{windowbounds}{width, height}
+Return a \code{(\var{left}, \var{top}, \var{right}, \var{bottom})}
+tuple suitable for creation of a window of given width and height. The
+window will be staggered with respect to previous windows, and an
+attempt is made to keep the whole window on-screen. However, the window will
+however always be the exact size given, so parts may be offscreen.
+\end{funcdesc}
+
+\begin{funcdesc}{setwatchcursor}{}
+Set the mouse cursor to a watch.
+\end{funcdesc}
+
+\begin{funcdesc}{setarrowcursor}{}
+Set the mouse cursor to an arrow.
+\end{funcdesc}
+
+
+\subsection{Application Objects \label{application-objects}}
+
+Application objects have the following methods, among others:
+
+
+\begin{methoddesc}[Application]{makeusermenus}{}
+Override this method if you need menus in your application. Append the
+menus to the attribute \member{menubar}.
+\end{methoddesc}
+
+\begin{methoddesc}[Application]{getabouttext}{}
+Override this method to return a text string describing your
+application.  Alternatively, override the \method{do_about()} method
+for more elaborate ``about'' messages.
+\end{methoddesc}
+
+\begin{methoddesc}[Application]{mainloop}{\optional{mask\optional{, wait}}}
+This routine is the main event loop, call it to set your application
+rolling. \var{Mask} is the mask of events you want to handle,
+\var{wait} is the number of ticks you want to leave to other
+concurrent application (default 0, which is probably not a good
+idea). While raising \var{self} to exit the mainloop is still
+supported it is not recommended: call \code{self._quit()} instead.
+
+The event loop is split into many small parts, each of which can be
+overridden. The default methods take care of dispatching events to
+windows and dialogs, handling drags and resizes, Apple Events, events
+for non-FrameWork windows, etc.
+
+In general, all event handlers should return \code{1} if the event is fully
+handled and \code{0} otherwise (because the front window was not a FrameWork
+window, for instance). This is needed so that update events and such
+can be passed on to other windows like the Sioux console window.
+Calling \function{MacOS.HandleEvent()} is not allowed within
+\var{our_dispatch} or its callees, since this may result in an
+infinite loop if the code is called through the Python inner-loop
+event handler.
+\end{methoddesc}
+
+\begin{methoddesc}[Application]{asyncevents}{onoff}
+Call this method with a nonzero parameter to enable
+asynchronous event handling. This will tell the inner interpreter loop
+to call the application event handler \var{async_dispatch} whenever events
+are available. This will cause FrameWork window updates and the user
+interface to remain working during long computations, but will slow the
+interpreter down and may cause surprising results in non-reentrant code
+(such as FrameWork itself). By default \var{async_dispatch} will immediately
+call \var{our_dispatch} but you may override this to handle only certain
+events asynchronously. Events you do not handle will be passed to Sioux
+and such.
+
+The old on/off value is returned.
+\end{methoddesc}
+
+\begin{methoddesc}[Application]{_quit}{}
+Terminate the running \method{mainloop()} call at the next convenient
+moment.
+\end{methoddesc}
+
+\begin{methoddesc}[Application]{do_char}{c, event}
+The user typed character \var{c}. The complete details of the event
+can be found in the \var{event} structure. This method can also be
+provided in a \code{Window} object, which overrides the
+application-wide handler if the window is frontmost.
+\end{methoddesc}
+
+\begin{methoddesc}[Application]{do_dialogevent}{event}
+Called early in the event loop to handle modeless dialog events. The
+default method simply dispatches the event to the relevant dialog (not
+through the \code{DialogWindow} object involved). Override if you
+need special handling of dialog events (keyboard shortcuts, etc).
+\end{methoddesc}
+
+\begin{methoddesc}[Application]{idle}{event}
+Called by the main event loop when no events are available. The
+null-event is passed (so you can look at mouse position, etc).
+\end{methoddesc}
+
+
+\subsection{Window Objects \label{window-objects}}
+
+Window objects have the following methods, among others:
+
+\setindexsubitem{(Window method)}
+
+\begin{methoddesc}[Window]{open}{}
+Override this method to open a window. Store the MacOS window-id in
+\member{self.wid} and call the \method{do_postopen()} method to
+register the window with the parent application.
+\end{methoddesc}
+
+\begin{methoddesc}[Window]{close}{}
+Override this method to do any special processing on window
+close. Call the \method{do_postclose()} method to cleanup the parent
+state.
+\end{methoddesc}
+
+\begin{methoddesc}[Window]{do_postresize}{width, height, macoswindowid}
+Called after the window is resized. Override if more needs to be done
+than calling \code{InvalRect}.
+\end{methoddesc}
+
+\begin{methoddesc}[Window]{do_contentclick}{local, modifiers, event}
+The user clicked in the content part of a window. The arguments are
+the coordinates (window-relative), the key modifiers and the raw
+event.
+\end{methoddesc}
+
+\begin{methoddesc}[Window]{do_update}{macoswindowid, event}
+An update event for the window was received. Redraw the window.
+\end{methoddesc}
+
+\begin{methoddesc}{do_activate}{activate, event}
+The window was activated (\code{\var{activate} == 1}) or deactivated
+(\code{\var{activate} == 0}). Handle things like focus highlighting,
+etc.
+\end{methoddesc}
+
+
+\subsection{ControlsWindow Object \label{controlswindow-object}}
+
+ControlsWindow objects have the following methods besides those of
+\code{Window} objects:
+
+
+\begin{methoddesc}[ControlsWindow]{do_controlhit}{window, control,
+                                                  pcode, event}
+Part \var{pcode} of control \var{control} was hit by the
+user. Tracking and such has already been taken care of.
+\end{methoddesc}
+
+
+\subsection{ScrolledWindow Object \label{scrolledwindow-object}}
+
+ScrolledWindow objects are ControlsWindow objects with the following
+extra methods:
+
+
+\begin{methoddesc}[ScrolledWindow]{scrollbars}{\optional{wantx\optional{,
+                                               wanty}}}
+Create (or destroy) horizontal and vertical scrollbars. The arguments
+specify which you want (default: both). The scrollbars always have
+minimum \code{0} and maximum \code{32767}.
+\end{methoddesc}
+
+\begin{methoddesc}[ScrolledWindow]{getscrollbarvalues}{}
+You must supply this method. It should return a tuple \code{(\var{x},
+\var{y})} giving the current position of the scrollbars (between
+\code{0} and \code{32767}). You can return \code{None} for either to
+indicate the whole document is visible in that direction.
+\end{methoddesc}
+
+\begin{methoddesc}[ScrolledWindow]{updatescrollbars}{}
+Call this method when the document has changed. It will call
+\method{getscrollbarvalues()} and update the scrollbars.
+\end{methoddesc}
+
+\begin{methoddesc}[ScrolledWindow]{scrollbar_callback}{which, what, value}
+Supplied by you and called after user interaction. \var{which} will
+be \code{'x'} or \code{'y'}, \var{what} will be \code{'-'},
+\code{'--'}, \code{'set'}, \code{'++'} or \code{'+'}. For
+\code{'set'}, \var{value} will contain the new scrollbar position.
+\end{methoddesc}
+
+\begin{methoddesc}[ScrolledWindow]{scalebarvalues}{absmin, absmax,
+                                                   curmin, curmax}
+Auxiliary method to help you calculate values to return from
+\method{getscrollbarvalues()}. You pass document minimum and maximum value
+and topmost (leftmost) and bottommost (rightmost) visible values and
+it returns the correct number or \code{None}.
+\end{methoddesc}
+
+\begin{methoddesc}[ScrolledWindow]{do_activate}{onoff, event}
+Takes care of dimming/highlighting scrollbars when a window becomes
+frontmost. If you override this method, call this one at the end of
+your method.
+\end{methoddesc}
+
+\begin{methoddesc}[ScrolledWindow]{do_postresize}{width, height, window}
+Moves scrollbars to the correct position. Call this method initially
+if you override it.
+\end{methoddesc}
+
+\begin{methoddesc}[ScrolledWindow]{do_controlhit}{window, control,
+                                                  pcode, event}
+Handles scrollbar interaction. If you override it call this method
+first, a nonzero return value indicates the hit was in the scrollbars
+and has been handled.
+\end{methoddesc}
+
+
+\subsection{DialogWindow Objects \label{dialogwindow-objects}}
+
+DialogWindow objects have the following methods besides those of
+\code{Window} objects:
+
+
+\begin{methoddesc}[DialogWindow]{open}{resid}
+Create the dialog window, from the DLOG resource with id
+\var{resid}. The dialog object is stored in \member{self.wid}.
+\end{methoddesc}
+
+\begin{methoddesc}[DialogWindow]{do_itemhit}{item, event}
+Item number \var{item} was hit. You are responsible for redrawing
+toggle buttons, etc.
+\end{methoddesc}

Added: vendor/Python/current/Doc/mac/libgensuitemodule.tex
===================================================================
--- vendor/Python/current/Doc/mac/libgensuitemodule.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/mac/libgensuitemodule.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,64 @@
+\section{\module{gensuitemodule} ---
+         Generate OSA stub packages}
+
+\declaremodule{standard}{gensuitemodule}
+  \platform{Mac}
+%\moduleauthor{Jack Jansen?}{email}
+\modulesynopsis{Create a stub package from an OSA dictionary}
+\sectionauthor{Jack Jansen}{Jack.Jansen at cwi.nl}
+
+The \module{gensuitemodule} module creates a Python package implementing
+stub code for the AppleScript suites that are implemented by a specific
+application, according to its AppleScript dictionary.
+
+It is usually invoked by the user through the \program{PythonIDE}, but
+it can also be run as a script from the command line (pass
+\longprogramopt{help} for help on the options) or imported from Python
+code. For an example of its use see \file{Mac/scripts/genallsuites.py}
+in a source distribution, which generates the stub packages that are
+included in the standard library.
+
+It defines the following public functions:
+
+\begin{funcdesc}{is_scriptable}{application}
+Returns true if \code{application}, which should be passed as a pathname,
+appears to be scriptable. Take the return value with a grain of salt:
+\program{Internet Explorer} appears not to be scriptable but definitely is.
+\end{funcdesc}
+
+\begin{funcdesc}{processfile}{application\optional{, output, basepkgname, 
+        edit_modnames, creatorsignature, dump, verbose}}
+Create a stub package for \code{application}, which should be passed as
+a full pathname. For a \file{.app} bundle this is the pathname to the
+bundle, not to the executable inside the bundle; for an unbundled CFM
+application you pass the filename of the application binary.
+
+This function asks the application for its OSA terminology resources,
+decodes these resources and uses the resultant data to create the Python
+code for the package implementing the client stubs.
+
+\code{output} is the pathname where the resulting package is stored, if
+not specified a standard "save file as" dialog is presented to
+the user. \code{basepkgname} is the base package on which this package
+will build, and defaults to \module{StdSuites}. Only when generating
+\module{StdSuites} itself do you need to specify this.
+\code{edit_modnames} is a dictionary that can be used to change
+modulenames that are too ugly after name mangling.
+\code{creator_signature} can be used to override the 4-char creator
+code, which is normally obtained from the \file{PkgInfo} file in the
+package or from the CFM file creator signature. When \code{dump} is
+given it should refer to a file object, and \code{processfile} will stop
+after decoding the resources and dump the Python representation of the
+terminology resources to this file. \code{verbose} should also be a file
+object, and specifying it will cause \code{processfile} to tell you what
+it is doing.
+\end{funcdesc}
+
+\begin{funcdesc}{processfile_fromresource}{application\optional{, output, 
+	basepkgname, edit_modnames, creatorsignature, dump, verbose}}
+This function does the same as \code{processfile}, except that it uses a
+different method to get the terminology resources. It opens \code{application}
+as a resource file and reads all \code{"aete"} and \code{"aeut"} resources
+from this file.
+\end{funcdesc}
+

Added: vendor/Python/current/Doc/mac/libmac.tex
===================================================================
--- vendor/Python/current/Doc/mac/libmac.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/mac/libmac.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,29 @@
+
+\section{\module{macpath} ---
+         MacOS path manipulation functions}
+
+\declaremodule{standard}{macpath}
+% Could be labeled \platform{Mac}, but the module should work anywhere and
+% is distributed with the standard library.
+\modulesynopsis{MacOS path manipulation functions.}
+
+
+This module is the Mac OS 9 (and earlier) implementation of the \module{os.path}
+module. It can be used to manipulate old-style Macintosh pathnames on Mac OS
+X (or any other platform).
+Refer to the
+\citetitle[../lib/lib.html]{Python Library Reference} for
+documentation of \module{os.path}.
+
+The following functions are available in this module:
+\function{normcase()},
+\function{normpath()},
+\function{isabs()},
+\function{join()},
+\function{split()},
+\function{isdir()},
+\function{isfile()},
+\function{walk()},
+\function{exists()}.
+For other functions available in \module{os.path} dummy counterparts
+are available.

Added: vendor/Python/current/Doc/mac/libmacfs.tex
===================================================================
--- vendor/Python/current/Doc/mac/libmacfs.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/mac/libmacfs.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,241 @@
+\section{\module{macfs} ---
+         Various file system services}
+
+\declaremodule{standard}{macfs}
+  \platform{Mac}
+\modulesynopsis{Support for FSSpec, the Alias Manager,
+                \program{finder} aliases, and the Standard File package.}
+
+\deprecated{2.3}{The macfs module should be considered obsolete. For
+\class{FSSpec}, \class{FSRef} and \class{Alias} handling use the
+\module{Carbon.File} or \refmodule{Carbon.Folder} module. For file
+dialogs use the \refmodule{EasyDialogs} module.  Also, this module is
+known to not work correctly with UFS partitions.}
+
+This module provides access to Macintosh \class{FSSpec} handling, the
+Alias Manager, \program{finder} aliases and the Standard File package.
+\index{Macintosh Alias Manager}
+\index{Alias Manager, Macintosh}
+\index{Standard File}
+
+Whenever a function or method expects a \var{file} argument, this
+argument can be one of three things:\ (1) a full or partial Macintosh
+pathname, (2) an \class{FSSpec} object or (3) a 3-tuple
+\code{(\var{wdRefNum}, \var{parID}, \var{name})} as described in
+\citetitle{Inside Macintosh:\ Files}.  An \class{FSSpec} can point to
+a non-existing file, as long as the folder containing the file exists.
+Under MacPython the same is true for a pathname, but not under \UNIX-Python
+because of the way pathnames and FSRefs works.  See Apple's documentation
+for details.
+
+A description of aliases and the
+Standard File package can also be found there.
+
+\begin{funcdesc}{FSSpec}{file}
+Create an \class{FSSpec} object for the specified file.
+\end{funcdesc}
+
+\begin{funcdesc}{RawFSSpec}{data}
+Create an \class{FSSpec} object given the raw data for the \C{}
+structure for the \class{FSSpec} as a string.  This is mainly useful
+if you have obtained an \class{FSSpec} structure over a network.
+\end{funcdesc}
+
+\begin{funcdesc}{RawAlias}{data}
+Create an \class{Alias} object given the raw data for the \C{}
+structure for the alias as a string.  This is mainly useful if you
+have obtained an \class{FSSpec} structure over a network.
+\end{funcdesc}
+
+\begin{funcdesc}{FInfo}{}
+Create a zero-filled \class{FInfo} object.
+\end{funcdesc}
+
+\begin{funcdesc}{ResolveAliasFile}{file}
+Resolve an alias file. Returns a 3-tuple \code{(\var{fsspec},
+\var{isfolder}, \var{aliased})} where \var{fsspec} is the resulting
+\class{FSSpec} object, \var{isfolder} is true if \var{fsspec} points
+to a folder and \var{aliased} is true if the file was an alias in the
+first place (otherwise the \class{FSSpec} object for the file itself
+is returned).
+\end{funcdesc}
+
+\begin{funcdesc}{StandardGetFile}{\optional{type, \moreargs}}
+Present the user with a standard ``open input file''
+dialog. Optionally, you can pass up to four 4-character file types to limit
+the files the user can choose from. The function returns an \class{FSSpec}
+object and a flag indicating that the user completed the dialog
+without cancelling.
+\end{funcdesc}
+
+\begin{funcdesc}{PromptGetFile}{prompt\optional{, type, \moreargs}}
+Similar to \function{StandardGetFile()} but allows you to specify a
+prompt which will be displayed at the top of the dialog.
+\end{funcdesc}
+
+\begin{funcdesc}{StandardPutFile}{prompt\optional{, default}}
+Present the user with a standard ``open output file''
+dialog. \var{prompt} is the prompt string, and the optional
+\var{default} argument initializes the output file name. The function
+returns an \class{FSSpec} object and a flag indicating that the user
+completed the dialog without cancelling.
+\end{funcdesc}
+
+\begin{funcdesc}{GetDirectory}{\optional{prompt}}
+Present the user with a non-standard ``select a directory'' dialog.  You
+have to first open the directory before clicking on the ``select current
+directory'' button. \var{prompt} is the prompt string which will be
+displayed at the top of the dialog. Return an \class{FSSpec} object and
+a success-indicator.
+\end{funcdesc}
+
+\begin{funcdesc}{SetFolder}{\optional{fsspec}}
+Set the folder that is initially presented to the user when one of
+the file selection dialogs is presented. \var{fsspec} should point to
+a file in the folder, not the folder itself (the file need not exist,
+though). If no argument is passed the folder will be set to the
+current directory, i.e. what \function{os.getcwd()} returns.
+
+Note that starting with System 7.5 the user can change Standard File
+behaviour with the ``general controls'' control panel, thereby making
+this call inoperative.
+\end{funcdesc}
+
+\begin{funcdesc}{FindFolder}{where, which, create}
+Locates one of the ``special'' folders that Mac OS knows about, such as
+the trash or the Preferences folder. \var{where} is the disk to
+search, \var{which} is the 4-character string specifying which folder to
+locate. Setting \var{create} causes the folder to be created if it
+does not exist. Returns a \code{(\var{vrefnum}, \var{dirid})} tuple.
+
+The constants for \var{where} and \var{which} can be obtained from the
+standard module \var{Carbon.Folders}.
+\end{funcdesc}
+
+\begin{funcdesc}{NewAliasMinimalFromFullPath}{pathname}
+Return a minimal \class{alias} object that points to the given file, which
+must be specified as a full pathname. This is the only way to create an
+\class{Alias} pointing to a non-existing file.
+
+\end{funcdesc}
+
+\begin{funcdesc}{FindApplication}{creator}
+Locate the application with 4-character creator code \var{creator}. The
+function returns an \class{FSSpec} object pointing to the application.
+\end{funcdesc}
+
+
+\subsection{FSSpec Objects \label{fsspec-objects}}
+
+\begin{memberdesc}[FSSpec]{data}
+The raw data from the FSSpec object, suitable for passing
+to other applications, for instance.
+\end{memberdesc}
+
+\begin{methoddesc}[FSSpec]{as_pathname}{}
+Return the full pathname of the file described by the \class{FSSpec}
+object.
+\end{methoddesc}
+
+\begin{methoddesc}[FSSpec]{as_tuple}{}
+Return the \code{(\var{wdRefNum}, \var{parID}, \var{name})} tuple of
+the file described by the \class{FSSpec} object.
+\end{methoddesc}
+
+\begin{methoddesc}[FSSpec]{NewAlias}{\optional{file}}
+Create an Alias object pointing to the file described by this
+FSSpec. If the optional \var{file} parameter is present the alias
+will be relative to that file, otherwise it will be absolute.
+\end{methoddesc}
+
+\begin{methoddesc}[FSSpec]{NewAliasMinimal}{}
+Create a minimal alias pointing to this file.
+\end{methoddesc}
+
+\begin{methoddesc}[FSSpec]{GetCreatorType}{}
+Return the 4-character creator and type of the file.
+\end{methoddesc}
+
+\begin{methoddesc}[FSSpec]{SetCreatorType}{creator, type}
+Set the 4-character creator and type of the file.
+\end{methoddesc}
+
+\begin{methoddesc}[FSSpec]{GetFInfo}{}
+Return a \class{FInfo} object describing the finder info for the file.
+\end{methoddesc}
+
+\begin{methoddesc}[FSSpec]{SetFInfo}{finfo}
+Set the finder info for the file to the values given as \var{finfo}
+(an \class{FInfo} object).
+\end{methoddesc}
+
+\begin{methoddesc}[FSSpec]{GetDates}{}
+Return a tuple with three floating point values representing the
+creation date, modification date and backup date of the file.
+\end{methoddesc}
+
+\begin{methoddesc}[FSSpec]{SetDates}{crdate, moddate, backupdate}
+Set the creation, modification and backup date of the file. The values
+are in the standard floating point format used for times throughout
+Python.
+\end{methoddesc}
+
+
+\subsection{Alias Objects \label{alias-objects}}
+
+\begin{memberdesc}[Alias]{data}
+The raw data for the Alias record, suitable for storing in a resource
+or transmitting to other programs.
+\end{memberdesc}
+
+\begin{methoddesc}[Alias]{Resolve}{\optional{file}}
+Resolve the alias. If the alias was created as a relative alias you
+should pass the file relative to which it is. Return the FSSpec for
+the file pointed to and a flag indicating whether the \class{Alias} object
+itself was modified during the search process. If the file does
+not exist but the path leading up to it does exist a valid fsspec
+is returned.
+\end{methoddesc}
+
+\begin{methoddesc}[Alias]{GetInfo}{num}
+An interface to the \C{} routine \cfunction{GetAliasInfo()}.
+\end{methoddesc}
+
+\begin{methoddesc}[Alias]{Update}{file\optional{, file2}}
+Update the alias to point to the \var{file} given. If \var{file2} is
+present a relative alias will be created.
+\end{methoddesc}
+
+Note that it is currently not possible to directly manipulate a
+resource as an \class{Alias} object. Hence, after calling
+\method{Update()} or after \method{Resolve()} indicates that the alias
+has changed the Python program is responsible for getting the
+\member{data} value from the \class{Alias} object and modifying the
+resource.
+
+
+\subsection{FInfo Objects \label{finfo-objects}}
+
+See \citetitle{Inside Macintosh: Files} for a complete description of what
+the various fields mean.
+
+\begin{memberdesc}[FInfo]{Creator}
+The 4-character creator code of the file.
+\end{memberdesc}
+
+\begin{memberdesc}[FInfo]{Type}
+The 4-character type code of the file.
+\end{memberdesc}
+
+\begin{memberdesc}[FInfo]{Flags}
+The finder flags for the file as 16-bit integer. The bit values in
+\var{Flags} are defined in standard module \module{MACFS}.
+\end{memberdesc}
+
+\begin{memberdesc}[FInfo]{Location}
+A Point giving the position of the file's icon in its folder.
+\end{memberdesc}
+
+\begin{memberdesc}[FInfo]{Fldr}
+The folder the file is in (as an integer).
+\end{memberdesc}

Added: vendor/Python/current/Doc/mac/libmacic.tex
===================================================================
--- vendor/Python/current/Doc/mac/libmacic.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/mac/libmacic.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,123 @@
+\section{\module{ic} ---
+         Access to Internet Config}
+
+\declaremodule{builtin}{ic}
+  \platform{Mac}
+\modulesynopsis{Access to Internet Config.}
+
+
+This module provides access to various internet-related preferences
+set through \program{System Preferences} or the \program{Finder}.
+
+There is a low-level companion module
+\module{icglue}\refbimodindex{icglue} which provides the basic
+Internet Config access functionality.  This low-level module is not
+documented, but the docstrings of the routines document the parameters
+and the routine names are the same as for the Pascal or \C{} API to
+Internet Config, so the standard IC programmers' documentation can be
+used if this module is needed.
+
+The \module{ic} module defines the \exception{error} exception and
+symbolic names for all error codes Internet Config can produce; see
+the source for details.
+
+\begin{excdesc}{error}
+Exception raised on errors in the \module{ic} module.
+\end{excdesc}
+
+
+The \module{ic} module defines the following class and function:
+
+\begin{classdesc}{IC}{\optional{signature\optional{, ic}}}
+Create an Internet Config object. The signature is a 4-character creator
+code of the current application (default \code{'Pyth'}) which may
+influence some of ICs settings. The optional \var{ic} argument is a
+low-level \code{icglue.icinstance} created beforehand, this may be
+useful if you want to get preferences from a different config file,
+etc.
+\end{classdesc}
+
+\begin{funcdesc}{launchurl}{url\optional{, hint}}
+\funcline{parseurl}{data\optional{, start\optional{, end\optional{, hint}}}}
+\funcline{mapfile}{file}
+\funcline{maptypecreator}{type, creator\optional{, filename}}
+\funcline{settypecreator}{file}
+These functions are ``shortcuts'' to the methods of the same name,
+described below.
+\end{funcdesc}
+
+
+\subsection{IC Objects}
+
+\class{IC} objects have a mapping interface, hence to obtain the mail
+address you simply get \code{\var{ic}['MailAddress']}. Assignment also
+works, and changes the option in the configuration file.
+
+The module knows about various datatypes, and converts the internal IC
+representation to a ``logical'' Python data structure. Running the
+\module{ic} module standalone will run a test program that lists all
+keys and values in your IC database, this will have to serve as
+documentation.
+
+If the module does not know how to represent the data it returns an
+instance of the \code{ICOpaqueData} type, with the raw data in its
+\member{data} attribute. Objects of this type are also acceptable values
+for assignment.
+
+Besides the dictionary interface, \class{IC} objects have the
+following methods:
+
+
+\begin{methoddesc}{launchurl}{url\optional{, hint}}
+Parse the given URL, launch the correct application and pass it the
+URL. The optional \var{hint} can be a scheme name such as
+\code{'mailto:'}, in which case incomplete URLs are completed with this
+scheme.  If \var{hint} is not provided, incomplete URLs are invalid.
+\end{methoddesc}
+
+\begin{methoddesc}{parseurl}{data\optional{, start\optional{, end\optional{, hint}}}}
+Find an URL somewhere in \var{data} and return start position, end
+position and the URL. The optional \var{start} and \var{end} can be
+used to limit the search, so for instance if a user clicks in a long
+text field you can pass the whole text field and the click-position in
+\var{start} and this routine will return the whole URL in which the
+user clicked.  As above, \var{hint} is an optional scheme used to
+complete incomplete URLs.
+\end{methoddesc}
+
+\begin{methoddesc}{mapfile}{file}
+Return the mapping entry for the given \var{file}, which can be passed
+as either a filename or an \function{FSSpec()} result, and which
+need not exist.
+
+The mapping entry is returned as a tuple \code{(\var{version},
+\var{type}, \var{creator}, \var{postcreator}, \var{flags},
+\var{extension}, \var{appname}, \var{postappname}, \var{mimetype},
+\var{entryname})}, where \var{version} is the entry version
+number, \var{type} is the 4-character filetype, \var{creator} is the
+4-character creator type, \var{postcreator} is the 4-character creator
+code of an
+optional application to post-process the file after downloading,
+\var{flags} are various bits specifying whether to transfer in binary
+or ascii and such, \var{extension} is the filename extension for this
+file type, \var{appname} is the printable name of the application to
+which this file belongs, \var{postappname} is the name of the
+postprocessing application, \var{mimetype} is the MIME type of this
+file and \var{entryname} is the name of this entry.
+\end{methoddesc}
+
+\begin{methoddesc}{maptypecreator}{type, creator\optional{, filename}}
+Return the mapping entry for files with given 4-character \var{type} and
+\var{creator} codes. The optional \var{filename} may be specified to
+further help finding the correct entry (if the creator code is
+\code{'????'}, for instance).
+
+The mapping entry is returned in the same format as for \var{mapfile}.
+\end{methoddesc}
+
+\begin{methoddesc}{settypecreator}{file}
+Given an existing \var{file}, specified either as a filename or as an
+\function{FSSpec()} result, set its creator and type correctly based
+on its extension.  The finder is told about the change, so the finder
+icon will be updated quickly.
+\end{methoddesc}

Added: vendor/Python/current/Doc/mac/libmacos.tex
===================================================================
--- vendor/Python/current/Doc/mac/libmacos.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/mac/libmacos.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,90 @@
+\section{\module{MacOS} ---
+         Access to Mac OS interpreter features}
+
+\declaremodule{builtin}{MacOS}
+  \platform{Mac}
+\modulesynopsis{Access to Mac OS-specific interpreter features.}
+
+
+This module provides access to MacOS specific functionality in the
+Python interpreter, such as how the interpreter eventloop functions
+and the like. Use with care.
+
+Note the capitalization of the module name; this is a historical
+artifact.
+
+\begin{datadesc}{runtimemodel}
+Always \code{'macho'}, from Python 2.4 on.
+In earlier versions of Python the value could
+also be \code{'ppc'} for the classic Mac OS 8 runtime model or
+\code{'carbon'} for the Mac OS 9 runtime model.
+\end{datadesc}
+
+\begin{datadesc}{linkmodel}
+The way the interpreter has been linked. As extension modules may be
+incompatible between linking models, packages could use this information to give
+more decent error messages. The value is one of \code{'static'} for a
+statically linked Python, \code{'framework'} for Python in a Mac OS X framework,
+\code{'shared'} for Python in a standard \UNIX{} shared library.
+Older Pythons could also have the value
+\code{'cfm'} for Mac OS 9-compatible Python.
+\end{datadesc}
+
+\begin{excdesc}{Error}
+This exception is raised on MacOS generated errors, either from
+functions in this module or from other mac-specific modules like the
+toolbox interfaces. The arguments are the integer error code (the
+\cdata{OSErr} value) and a textual description of the error code.
+Symbolic names for all known error codes are defined in the standard
+module \refmodule{macerrors}.\refstmodindex{macerrors}
+\end{excdesc}
+
+
+\begin{funcdesc}{GetErrorString}{errno}
+Return the textual description of MacOS error code \var{errno}.
+\end{funcdesc}
+
+\begin{funcdesc}{DebugStr}{message \optional{, object}}
+On Mac OS X the string is simply printed to stderr (on older
+Mac OS systems more elaborate functionality was available),
+but it provides a convenient location to attach a breakpoint
+in a low-level debugger like \program{gdb}.
+\end{funcdesc}
+
+\begin{funcdesc}{SysBeep}{}
+Ring the bell.
+\end{funcdesc}
+
+\begin{funcdesc}{GetTicks}{}
+Get the number of clock ticks (1/60th of a second) since system boot.
+\end{funcdesc}
+
+\begin{funcdesc}{GetCreatorAndType}{file}
+Return the file creator and file type as two four-character strings.
+The \var{file} parameter can be a pathname or an \code{FSSpec} or 
+\code{FSRef} object.
+\end{funcdesc}
+
+\begin{funcdesc}{SetCreatorAndType}{file, creator, type}
+Set the file creator and file type.
+The \var{file} parameter can be a pathname or an \code{FSSpec} or 
+\code{FSRef} object. \var{creator} and \var{type} must be four character
+strings.
+\end{funcdesc}
+
+\begin{funcdesc}{openrf}{name \optional{, mode}}
+Open the resource fork of a file. Arguments are the same as for the
+built-in function \function{open()}. The object returned has file-like
+semantics, but it is not a Python file object, so there may be subtle
+differences.
+\end{funcdesc}
+
+\begin{funcdesc}{WMAvailable}{}
+Checks whether the current process has access to the window manager.
+The method will return \code{False} if the window manager is not available,
+for instance when running on Mac OS X Server or when logged in via ssh,
+or when the current interpreter is not running from a fullblown application
+bundle. A script runs from an application bundle either when it has been
+started with \program{pythonw} instead of \program{python} or when running 
+as an applet.
+\end{funcdesc}

Added: vendor/Python/current/Doc/mac/libmacostools.tex
===================================================================
--- vendor/Python/current/Doc/mac/libmacostools.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/mac/libmacostools.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,105 @@
+\section{\module{macostools} ---
+         Convenience routines for file manipulation}
+
+\declaremodule{standard}{macostools}
+  \platform{Mac}
+\modulesynopsis{Convenience routines for file manipulation.}
+
+
+This module contains some convenience routines for file-manipulation
+on the Macintosh. All file parameters can be specified as
+pathnames, \class{FSRef} or \class{FSSpec} objects.  This module
+expects a filesystem which supports forked files, so it should not
+be used on UFS partitions.
+
+The \module{macostools} module defines the following functions:
+
+
+\begin{funcdesc}{copy}{src, dst\optional{, createpath\optional{, copytimes}}}
+Copy file \var{src} to \var{dst}.  If \var{createpath} is non-zero
+the folders leading to \var{dst} are created if necessary.
+The method copies data and
+resource fork and some finder information (creator, type, flags) and
+optionally the creation, modification and backup times (default is to
+copy them). Custom icons, comments and icon position are not copied.
+\end{funcdesc}
+
+\begin{funcdesc}{copytree}{src, dst}
+Recursively copy a file tree from \var{src} to \var{dst}, creating
+folders as needed. \var{src} and \var{dst} should be specified as
+pathnames.
+\end{funcdesc}
+
+\begin{funcdesc}{mkalias}{src, dst}
+Create a finder alias \var{dst} pointing to \var{src}.
+\end{funcdesc}
+
+\begin{funcdesc}{touched}{dst}
+Tell the finder that some bits of finder-information such as creator
+or type for file \var{dst} has changed. The file can be specified by
+pathname or fsspec. This call should tell the finder to redraw the
+files icon.
+\end{funcdesc}
+
+\begin{datadesc}{BUFSIZ}
+The buffer size for \code{copy}, default 1 megabyte.
+\end{datadesc}
+
+Note that the process of creating finder aliases is not specified in
+the Apple documentation. Hence, aliases created with \function{mkalias()}
+could conceivably have incompatible behaviour in some cases.
+
+
+\section{\module{findertools} ---
+         The \program{finder}'s Apple Events interface}
+
+\declaremodule{standard}{findertools}
+  \platform{Mac}
+\modulesynopsis{Wrappers around the \program{finder}'s Apple Events interface.}
+
+
+This module contains routines that give Python programs access to some
+functionality provided by the finder. They are implemented as wrappers
+around the AppleEvent\index{AppleEvents} interface to the finder.
+
+All file and folder parameters can be specified either as full
+pathnames, or as \class{FSRef} or \class{FSSpec} objects.
+
+The \module{findertools} module defines the following functions:
+
+
+\begin{funcdesc}{launch}{file}
+Tell the finder to launch \var{file}. What launching means depends on the file:
+applications are started, folders are opened and documents are opened
+in the correct application.
+\end{funcdesc}
+
+\begin{funcdesc}{Print}{file}
+Tell the finder to print a file. The behaviour is identical to selecting the file and using
+the print command in the finder's file menu.
+\end{funcdesc}
+
+\begin{funcdesc}{copy}{file, destdir}
+Tell the finder to copy a file or folder \var{file} to folder
+\var{destdir}. The function returns an \class{Alias} object pointing to
+the new file.
+\end{funcdesc}
+
+\begin{funcdesc}{move}{file, destdir}
+Tell the finder to move a file or folder \var{file} to folder
+\var{destdir}. The function returns an \class{Alias} object pointing to
+the new file.
+\end{funcdesc}
+
+\begin{funcdesc}{sleep}{}
+Tell the finder to put the Macintosh to sleep, if your machine
+supports it.
+\end{funcdesc}
+
+\begin{funcdesc}{restart}{}
+Tell the finder to perform an orderly restart of the machine.
+\end{funcdesc}
+
+\begin{funcdesc}{shutdown}{}
+Tell the finder to perform an orderly shutdown of the machine.
+\end{funcdesc}

Added: vendor/Python/current/Doc/mac/libmacui.tex
===================================================================
--- vendor/Python/current/Doc/mac/libmacui.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/mac/libmacui.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,266 @@
+\section{\module{EasyDialogs} ---
+         Basic Macintosh dialogs}
+
+\declaremodule{standard}{EasyDialogs}
+  \platform{Mac}
+\modulesynopsis{Basic Macintosh dialogs.}
+
+The \module{EasyDialogs} module contains some simple dialogs for the
+Macintosh. All routines take an optional resource ID parameter \var{id}
+with which one can override the \constant{DLOG} resource used for the
+dialog, provided that the dialog items correspond (both type and item
+number) to those in the default \constant{DLOG} resource. See source
+code for details.
+
+The \module{EasyDialogs} module defines the following functions:
+
+
+\begin{funcdesc}{Message}{str\optional{, id\optional{, ok}}}
+Displays a modal dialog with the message text \var{str}, which should be
+at most 255 characters long. The button text defaults to ``OK'', but is
+set to the string argument \var{ok} if the latter is supplied. Control
+is returned when the user clicks the ``OK'' button.
+\end{funcdesc}
+
+
+\begin{funcdesc}{AskString}{prompt\optional{, default\optional{,
+    id\optional{, ok\optional{, cancel}}}}}
+Asks the user to input a string value via a modal dialog. \var{prompt}
+is the prompt message, and the optional \var{default} supplies the
+initial value for the string (otherwise \code{""} is used). The text of
+the ``OK'' and ``Cancel'' buttons can be changed with the \var{ok} and
+\var{cancel} arguments. All strings can be at most 255 bytes long.
+\function{AskString()} returns the string entered or \constant{None}
+in case the user cancelled.
+\end{funcdesc}
+
+
+\begin{funcdesc}{AskPassword}{prompt\optional{, default\optional{,
+    id\optional{, ok\optional{, cancel}}}}}
+Asks the user to input a string value via a modal dialog. Like
+\function{AskString()}, but with the text shown as bullets. The
+arguments have the same meaning as for \function{AskString()}.
+\end{funcdesc}
+
+
+\begin{funcdesc}{AskYesNoCancel}{question\optional{, default\optional{,
+    yes\optional{, no\optional{, cancel\optional{, id}}}}}}
+Presents a dialog with prompt \var{question} and three buttons labelled
+``Yes'', ``No'', and ``Cancel''. Returns \code{1} for ``Yes'', \code{0}
+for ``No'' and \code{-1} for ``Cancel''. The value of \var{default} (or
+\code{0} if \var{default} is not supplied) is returned when the
+\kbd{RETURN} key is pressed. The text of the buttons can be changed with
+the \var{yes}, \var{no}, and \var{cancel} arguments; to prevent a button
+from appearing, supply \code{""} for the corresponding argument.
+\end{funcdesc}
+
+
+\begin{funcdesc}{ProgressBar}{\optional{title\optional{, maxval\optional{,
+    label\optional{, id}}}}}
+Displays a modeless progress-bar dialog. This is the constructor for the
+\class{ProgressBar} class described below. \var{title} is the text
+string displayed (default ``Working...''), \var{maxval} is the value at
+which progress is complete (default \code{0}, indicating that an
+indeterminate amount of work remains to be done), and \var{label} is
+the text that is displayed above the progress bar itself.
+\end{funcdesc}
+
+
+\begin{funcdesc}{GetArgv}{\optional{optionlist\optional{
+    commandlist\optional{, addoldfile\optional{, addnewfile\optional{,
+    addfolder\optional{, id}}}}}}}
+Displays a dialog which aids the user in constructing a command-line
+argument list.  Returns the list in \code{sys.argv} format, suitable for
+passing as an argument to \function{getopt.getopt()}.  \var{addoldfile},
+\var{addnewfile}, and \var{addfolder} are boolean arguments.  When
+nonzero, they enable the user to insert into the command line paths to
+an existing file, a (possibly) not-yet-existent file, and a folder,
+respectively.  (Note: Option arguments must appear in the command line
+before file and folder arguments in order to be recognized by
+\function{getopt.getopt()}.)  Arguments containing spaces can be
+specified by enclosing them within single or double quotes.  A
+\exception{SystemExit} exception is raised if the user presses the
+``Cancel'' button.
+
+\var{optionlist} is a list that determines a popup menu from which the
+allowed options are selected.  Its items can take one of two forms:
+\var{optstr} or \code{(\var{optstr}, \var{descr})}.  When present,
+\var{descr} is a short descriptive string that is displayed in the
+dialog while this option is selected in the popup menu.  The
+correspondence between \var{optstr}s and command-line arguments is:
+
+\begin{tableii}{l|l}{textrm}{\var{optstr} format}{Command-line format}
+\lineii{\code{x}}
+       {\programopt{-x} (short option)}
+\lineii{\code{x:} or \code{x=}}
+       {\programopt{-x} (short option with value)}
+\lineii{\code{xyz}}
+       {\longprogramopt{xyz} (long option)}
+\lineii{\code{xyz:} or \code{xyz=}}
+       {\longprogramopt{xyz} (long option with value)}
+\end{tableii}
+
+\var{commandlist} is a list of items of the form \var{cmdstr} or
+\code{(\var{cmdstr}, \var{descr})}, where \var{descr} is as above.  The
+\var{cmdstr}s will appear in a popup menu.  When chosen, the text of
+\var{cmdstr} will be appended to the command line as is, except that a
+trailing \character{:} or \character{=} (if present) will be trimmed
+off.
+
+\versionadded{2.0}
+\end{funcdesc}
+
+\begin{funcdesc}{AskFileForOpen}{
+	\optional{message}
+	\optional{, typeList}
+	\optional{, defaultLocation}
+	\optional{, defaultOptionFlags}
+	\optional{, location}
+	\optional{, clientName}
+	\optional{, windowTitle}
+	\optional{, actionButtonLabel}
+	\optional{, cancelButtonLabel}
+	\optional{, preferenceKey}
+	\optional{, popupExtension}
+	\optional{, eventProc}
+	\optional{, previewProc}
+	\optional{, filterProc}
+	\optional{, wanted}
+	}
+Post a dialog asking the user for a file to open, and return the file
+selected or \constant{None} if the user cancelled.
+\var{message} is a text message to display,
+\var{typeList} is a list of 4-char filetypes allowable,
+\var{defaultLocation} is the pathname, \class{FSSpec} or \class{FSRef}
+of the folder to show initially,
+\var{location} is the \code{(x, y)} position on the screen where the
+dialog is shown,
+\var{actionButtonLabel} is a string to show instead of ``Open'' in the
+OK button,
+\var{cancelButtonLabel} is a string to show instead of ``Cancel'' in the
+cancel button,
+\var{wanted} is the type of value wanted as a return: \class{str},
+\class{unicode}, \class{FSSpec}, \class{FSRef} and subtypes thereof are
+acceptable.
+
+\index{Navigation Services}
+For a description of the other arguments please see the Apple Navigation
+Services documentation and the \module{EasyDialogs} source code.
+\end{funcdesc}
+
+\begin{funcdesc}{AskFileForSave}{
+	\optional{message}
+	\optional{, savedFileName}
+	\optional{, defaultLocation}
+	\optional{, defaultOptionFlags}
+	\optional{, location}
+	\optional{, clientName}
+	\optional{, windowTitle}
+	\optional{, actionButtonLabel}
+	\optional{, cancelButtonLabel}
+	\optional{, preferenceKey}
+	\optional{, popupExtension}
+	\optional{, fileType}
+	\optional{, fileCreator}
+	\optional{, eventProc}
+	\optional{, wanted}
+	}
+Post a dialog asking the user for a file to save to, and return the
+file selected or \constant{None} if the user cancelled.
+\var{savedFileName} is the default for the file name to save to (the
+return value). See \function{AskFileForOpen()} for a description of
+the other arguments.
+\end{funcdesc}
+
+\begin{funcdesc}{AskFolder}{
+	\optional{message}
+	\optional{, defaultLocation}
+	\optional{, defaultOptionFlags}
+	\optional{, location}
+	\optional{, clientName}
+	\optional{, windowTitle}
+	\optional{, actionButtonLabel}
+	\optional{, cancelButtonLabel}
+	\optional{, preferenceKey}
+	\optional{, popupExtension}
+	\optional{, eventProc}
+	\optional{, filterProc}
+	\optional{, wanted}
+	}
+Post a dialog asking the user to select a folder, and return the
+folder selected or \constant{None} if the user cancelled. See
+\function{AskFileForOpen()} for a description of the arguments.
+\end{funcdesc}
+
+
+\begin{seealso}
+  \seetitle
+  [http://developer.apple.com/documentation/Carbon/Reference/Navigation_Services_Ref/]
+  {Navigation Services Reference}{Programmer's reference documentation
+  for the Navigation Services, a part of the Carbon framework.}
+\end{seealso}
+
+
+\subsection{ProgressBar Objects \label{progressbar-objects}}
+
+\class{ProgressBar} objects provide support for modeless progress-bar
+dialogs.  Both determinate (thermometer style) and indeterminate
+(barber-pole style) progress bars are supported.  The bar will be
+determinate if its maximum value is greater than zero; otherwise it
+will be indeterminate.
+\versionchanged[Support for indeterminate-style progress bars was
+                added]{2.2}
+
+The dialog is displayed immediately after creation. If the dialog's
+``Cancel'' button is pressed, or if \kbd{Cmd-.} or \kbd{ESC} is typed,
+the dialog window is hidden and \exception{KeyboardInterrupt} is
+raised (but note that this response does not occur until the progress
+bar is next updated, typically via a call to \method{inc()} or
+\method{set()}).  Otherwise, the bar remains visible until the
+\class{ProgressBar} object is discarded.
+
+\class{ProgressBar} objects possess the following attributes and
+methods:
+
+\begin{memberdesc}[ProgressBar]{curval}
+The current value (of type integer or long integer) of the progress
+bar.  The normal access methods coerce \member{curval} between
+\code{0} and \member{maxval}.  This attribute should not be altered
+directly.
+\end{memberdesc}
+
+\begin{memberdesc}[ProgressBar]{maxval}
+The maximum value (of type integer or long integer) of the progress
+bar; the progress bar (thermometer style) is full when \member{curval}
+equals \member{maxval}.  If \member{maxval} is \code{0}, the bar will
+be indeterminate (barber-pole).  This attribute should not be altered
+directly.
+\end{memberdesc}
+
+\begin{methoddesc}[ProgressBar]{title}{\optional{newstr}}
+Sets the text in the title bar of the progress dialog to
+\var{newstr}.
+\end{methoddesc}
+
+\begin{methoddesc}[ProgressBar]{label}{\optional{newstr}}
+Sets the text in the progress box of the progress dialog to
+\var{newstr}.
+\end{methoddesc}
+
+\begin{methoddesc}[ProgressBar]{set}{value\optional{, max}}
+Sets the progress bar's \member{curval} to \var{value}, and also
+\member{maxval} to \var{max} if the latter is provided.  \var{value}
+is first coerced between 0 and \member{maxval}.  The thermometer bar
+is updated to reflect the changes, including a change from
+indeterminate to determinate or vice versa.
+\end{methoddesc}
+
+\begin{methoddesc}[ProgressBar]{inc}{\optional{n}}
+Increments the progress bar's \member{curval} by \var{n}, or by \code{1}
+if \var{n} is not provided.  (Note that \var{n} may be negative, in
+which case the effect is a decrement.)  The progress bar is updated to
+reflect the change.  If the bar is indeterminate, this causes one
+``spin'' of the barber pole.  The resulting \member{curval} is coerced
+between 0 and \member{maxval} if incrementing causes it to fall
+outside this range.
+\end{methoddesc}

Added: vendor/Python/current/Doc/mac/libminiae.tex
===================================================================
--- vendor/Python/current/Doc/mac/libminiae.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/mac/libminiae.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,65 @@
+\section{\module{MiniAEFrame} ---
+         Open Scripting Architecture server support}
+
+\declaremodule{standard}{MiniAEFrame}
+  \platform{Mac}
+\modulesynopsis{Support to act as an Open Scripting Architecture (OSA) server
+(``Apple Events'').}
+
+
+The module \module{MiniAEFrame} provides a framework for an application
+that can function as an Open Scripting Architecture
+\index{Open Scripting Architecture}
+(OSA) server, i.e. receive and process
+AppleEvents\index{AppleEvents}. It can be used in conjunction with
+\refmodule{FrameWork}\refstmodindex{FrameWork} or standalone. As an
+example, it is used in \program{PythonCGISlave}.
+
+
+The \module{MiniAEFrame} module defines the following classes:
+
+
+\begin{classdesc}{AEServer}{}
+A class that handles AppleEvent dispatch. Your application should
+subclass this class together with either
+\class{MiniApplication} or
+\class{FrameWork.Application}. Your \method{__init__()} method should
+call the \method{__init__()} method for both classes.
+\end{classdesc}
+
+\begin{classdesc}{MiniApplication}{}
+A class that is more or less compatible with
+\class{FrameWork.Application} but with less functionality. Its
+event loop supports the apple menu, command-dot and AppleEvents; other
+events are passed on to the Python interpreter and/or Sioux.
+Useful if your application wants to use \class{AEServer} but does not
+provide its own windows, etc.
+\end{classdesc}
+
+
+\subsection{AEServer Objects \label{aeserver-objects}}
+
+\begin{methoddesc}[AEServer]{installaehandler}{classe, type, callback}
+Installs an AppleEvent handler. \var{classe} and \var{type} are the
+four-character OSA Class and Type designators, \code{'****'} wildcards
+are allowed. When a matching AppleEvent is received the parameters are
+decoded and your callback is invoked.
+\end{methoddesc}
+
+\begin{methoddesc}[AEServer]{callback}{_object, **kwargs}
+Your callback is called with the OSA Direct Object as first positional
+parameter. The other parameters are passed as keyword arguments, with
+the 4-character designator as name. Three extra keyword parameters are
+passed: \code{_class} and \code{_type} are the Class and Type
+designators and \code{_attributes} is a dictionary with the AppleEvent
+attributes.
+
+The return value of your method is packed with
+\function{aetools.packevent()} and sent as reply.
+\end{methoddesc}
+
+Note that there are some serious problems with the current
+design. AppleEvents which have non-identifier 4-character designators
+for arguments are not implementable, and it is not possible to return
+an error to the originator. This will be addressed in a future
+release.

Added: vendor/Python/current/Doc/mac/libscrap.tex
===================================================================
--- vendor/Python/current/Doc/mac/libscrap.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/mac/libscrap.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,42 @@
+\section{\module{Carbon.Scrap} --- Scrap Manager}
+\declaremodule{standard}{Carbon.Scrap}
+  \platform{Mac}
+\modulesynopsis{The Scrap Manager provides basic services for
+                implementing cut \&\ paste and clipboard operations.}
+
+
+This module is only fully available on MacOS9 and earlier under
+classic PPC MacPython.  Very limited functionality is available under
+Carbon MacPython.
+
+The Scrap\index{Scrap Manager} Manager supports the simplest form of
+cut \&\ paste operations on the Macintosh.  It can be use for both
+inter- and intra-application clipboard operations.
+
+The \module{Scrap} module provides low-level access to the functions
+of the Scrap Manager.  It contains the following functions:
+
+
+\begin{funcdesc}{InfoScrap}{}
+  Return current information about the scrap.  The information is
+  encoded as a tuple containing the fields \code{(\var{size},
+  \var{handle}, \var{count}, \var{state}, \var{path})}.
+
+  \begin{tableii}{l|l}{var}{Field}{Meaning}
+    \lineii{size}{Size of the scrap in bytes.}
+    \lineii{handle}{Resource object representing the scrap.}
+    \lineii{count}{Serial number of the scrap contents.}
+    \lineii{state}{Integer; positive if in memory, \code{0} if on
+                   disk, negative if uninitialized.}
+    \lineii{path}{Filename of the scrap when stored on disk.}
+  \end{tableii}
+\end{funcdesc}
+
+
+
+\begin{seealso}
+  \seetitle[http://developer.apple.com/documentation/mac/MoreToolbox/MoreToolbox-109.html]
+           {Scrap Manager}{Apple's documentation for the Scrap Manager
+            gives a lot of useful information about using the Scrap
+            Manager in applications.}
+\end{seealso}

Added: vendor/Python/current/Doc/mac/mac.tex
===================================================================
--- vendor/Python/current/Doc/mac/mac.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/mac/mac.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,89 @@
+\documentclass{manual}
+
+\title{Macintosh Library Modules}
+
+\input{boilerplate}
+
+\makeindex              % tell \index to actually write the .idx file
+\makemodindex           % ... and the module index as well.
+
+
+\begin{document}
+
+\maketitle
+
+\ifhtml
+\chapter*{Front Matter\label{front}}
+\fi
+
+\input{copyright}
+
+\begin{abstract}
+
+\noindent
+This library reference manual documents Python's extensions for the
+Macintosh.  It should be used in conjunction with the
+\citetitle[../lib/lib.html]{Python Library Reference}, which documents
+the standard library and built-in types.
+
+This manual assumes basic knowledge about the Python language.  For an
+informal introduction to Python, see the
+\citetitle[../tut/tut.html]{Python Tutorial}; the
+\citetitle[../ref/ref.html]{Python Reference Manual} remains the
+highest authority on syntactic and semantic questions.  Finally, the
+manual entitled \citetitle[../ext/ext.html]{Extending and Embedding
+the Python Interpreter} describes how to add new extensions to Python
+and how to embed it in other applications.
+
+\end{abstract}
+
+\tableofcontents
+
+
+\input{using.tex}                       % Using Python on the Macintosh
+
+
+\chapter{MacPython Modules \label{macpython-modules}}
+
+The following modules are only available on the Macintosh, and are
+documented here:
+
+\localmoduletable
+
+\input{libmac}
+\input{libmacfs}
+\input{libmacic}
+\input{libmacos}
+\input{libmacostools}
+\input{libmacui}
+\input{libframework}
+\input{libautogil}
+
+\input{scripting}
+
+\input{toolbox}                         % MacOS Toolbox Modules
+\input{libcolorpicker}
+
+\input{undoc}                           % Undocumented Modules
+
+\appendix
+\chapter{History and License}
+\input{license}
+
+%
+%  The ugly "%begin{latexonly}" pseudo-environments are really just to
+%  keep LaTeX2HTML quiet during the \renewcommand{} macros; they're
+%  not really valuable.
+%
+
+%begin{latexonly}
+\renewcommand{\indexname}{Module Index}
+%end{latexonly}
+\input{modmac.ind}      % Module Index
+
+%begin{latexonly}
+\renewcommand{\indexname}{Index}
+%end{latexonly}
+\input{mac.ind}         % Index
+
+\end{document}

Added: vendor/Python/current/Doc/mac/scripting.tex
===================================================================
--- vendor/Python/current/Doc/mac/scripting.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/mac/scripting.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,101 @@
+\chapter{MacPython OSA Modules \label{scripting}}
+
+This chapter describes the current implementation of the Open Scripting
+Architecure (OSA, also commonly referred to as AppleScript) for Python, allowing
+you to control scriptable applications from your Python program,
+and with a fairly pythonic interface. Development on this set of modules
+has stopped, and a replacement is expected for Python 2.5.
+
+For a description of the various components of AppleScript and OSA, and
+to get an understanding of the architecture and terminology, you should
+read Apple's documentation. The "Applescript Language Guide" explains
+the conceptual model and the terminology, and documents the standard
+suite. The "Open Scripting Architecture" document explains how to use
+OSA from an application programmers point of view. In the Apple Help
+Viewer these books are located in the Developer Documentation, Core
+Technologies section.
+
+
+As an example of scripting an application, the following piece of
+AppleScript will get the name of the frontmost \program{Finder} window
+and print it:
+	
+\begin{verbatim}
+tell application "Finder"
+    get name of window 1
+end tell
+\end{verbatim}
+
+In Python, the following code fragment will do the same:
+
+\begin{verbatim}
+import Finder
+
+f = Finder.Finder()
+print f.get(f.window(1).name)
+\end{verbatim}
+
+As distributed the Python library includes packages that implement the
+standard suites, plus packages that interface to a small number of
+common applications.
+
+To send AppleEvents to an application you must first create the Python
+package interfacing to the terminology of the application (what
+\program{Script Editor} calls the "Dictionary"). This can be done from
+within the \program{PythonIDE} or by running the
+\file{gensuitemodule.py} module as a standalone program from the command
+line.
+
+The generated output is a package with a number of modules, one for
+every suite used in the program plus an \module{__init__} module to glue
+it all together. The Python inheritance graph follows the AppleScript
+inheritance graph, so if a program's dictionary specifies that it
+includes support for the Standard Suite, but extends one or two verbs
+with extra arguments then the output suite will contain a module
+\module{Standard_Suite} that imports and re-exports everything from
+\module{StdSuites.Standard_Suite} but overrides the methods that have
+extra functionality. The output of \module{gensuitemodule} is pretty
+readable, and contains the documentation that was in the original
+AppleScript dictionary in Python docstrings, so reading it is a good
+source of documentation.
+
+The output package implements a main class with the same name as the
+package which contains all the AppleScript verbs as methods, with the
+direct object as the first argument and all optional parameters as
+keyword arguments. AppleScript classes are also implemented as Python
+classes, as are comparisons and all the other thingies.
+
+The main
+Python class implementing the verbs also allows access to the properties
+and elements declared in the AppleScript class "application". In the
+current release that is as far as the object orientation goes, so
+in the example above we need to use
+\code{f.get(f.window(1).name)} instead of the more Pythonic
+\code{f.window(1).name.get()}.
+
+
+If an AppleScript identifier is not a Python identifier the name is
+mangled according to a small number of rules:
+\begin{itemize}
+    \item spaces are replaced with underscores
+    \item other non-alphanumeric characters are replaced with
+    \code{_xx_} where \code{xx} is the hexadecimal character value
+    \item any Python reserved word gets an underscore appended
+\end{itemize}
+
+Python also has support for creating scriptable applications
+in Python, but
+The following modules are relevant to MacPython AppleScript support:
+
+\localmoduletable
+
+In addition, support modules have been pre-generated for
+\module{Finder}, \module{Terminal}, \module{Explorer},
+\module{Netscape}, \module{CodeWarrior}, \module{SystemEvents} and
+\module{StdSuites}.
+
+\input{libgensuitemodule}
+\input{libaetools}
+\input{libaepack}
+\input{libaetypes}
+\input{libminiae}

Added: vendor/Python/current/Doc/mac/toolbox.tex
===================================================================
--- vendor/Python/current/Doc/mac/toolbox.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/mac/toolbox.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,173 @@
+\chapter{MacOS Toolbox Modules \label{toolbox}}
+
+There are a set of modules that provide interfaces to various MacOS
+toolboxes.  If applicable the module will define a number of Python
+objects for the various structures declared by the toolbox, and
+operations will be implemented as methods of the object.  Other
+operations will be implemented as functions in the module.  Not all
+operations possible in C will also be possible in Python (callbacks
+are often a problem), and parameters will occasionally be different in
+Python (input and output buffers, especially).  All methods and
+functions have a \member{__doc__} string describing their arguments
+and return values, and for additional description you are referred to
+\citetitle[http://developer.apple.com/documentation/macos8/mac8.html]{Inside
+Macintosh} or similar works.
+
+These modules all live in a package called \module{Carbon}. Despite that name
+they are not all part of the Carbon framework: CF is really in the CoreFoundation
+framework and Qt is in the QuickTime framework.
+The normal use pattern is
+
+\begin{verbatim}
+from Carbon import AE
+\end{verbatim}
+
+\strong{Warning!}  These modules are not yet documented.  If you
+wish to contribute documentation of any of these modules, please get
+in touch with \email{docs at python.org}.
+
+\localmoduletable
+
+
+%\section{Argument Handling for Toolbox Modules}
+
+
+\section{\module{Carbon.AE} --- Apple Events}
+\declaremodule{standard}{Carbon.AE}
+  \platform{Mac}
+\modulesynopsis{Interface to the Apple Events toolbox.}
+
+\section{\module{Carbon.AH} --- Apple Help}
+\declaremodule{standard}{Carbon.AH}
+  \platform{Mac}
+\modulesynopsis{Interface to the Apple Help manager.}
+
+
+\section{\module{Carbon.App} --- Appearance Manager}
+\declaremodule{standard}{Carbon.App}
+  \platform{Mac}
+\modulesynopsis{Interface to the Appearance Manager.}
+
+
+\section{\module{Carbon.CF} --- Core Foundation}
+\declaremodule{standard}{Carbon.CF}
+  \platform{Mac}
+\modulesynopsis{Interface to the Core Foundation.}
+
+The
+\code{CFBase}, \code{CFArray}, \code{CFData}, \code{CFDictionary},
+\code{CFString} and \code{CFURL} objects are supported, some
+only partially.
+
+\section{\module{Carbon.CG} --- Core Graphics}
+\declaremodule{standard}{Carbon.CG}
+  \platform{Mac}
+\modulesynopsis{Interface to the Component Manager.}
+
+\section{\module{Carbon.CarbonEvt} --- Carbon Event Manager}
+\declaremodule{standard}{Carbon.CarbonEvt}
+  \platform{Mac}
+\modulesynopsis{Interface to the Carbon Event Manager.}
+
+\section{\module{Carbon.Cm} --- Component Manager}
+\declaremodule{standard}{Carbon.Cm}
+  \platform{Mac}
+\modulesynopsis{Interface to the Component Manager.}
+
+
+\section{\module{Carbon.Ctl} --- Control Manager}
+\declaremodule{standard}{Carbon.Ctl}
+  \platform{Mac}
+\modulesynopsis{Interface to the Control Manager.}
+
+
+\section{\module{Carbon.Dlg} --- Dialog Manager}
+\declaremodule{standard}{Carbon.Dlg}
+  \platform{Mac}
+\modulesynopsis{Interface to the Dialog Manager.}
+
+
+\section{\module{Carbon.Evt} --- Event Manager}
+\declaremodule{standard}{Carbon.Evt}
+  \platform{Mac}
+\modulesynopsis{Interface to the classic Event Manager.}
+
+
+\section{\module{Carbon.Fm} --- Font Manager}
+\declaremodule{standard}{Carbon.Fm}
+  \platform{Mac}
+\modulesynopsis{Interface to the Font Manager.}
+
+\section{\module{Carbon.Folder} --- Folder Manager}
+\declaremodule{standard}{Carbon.Folder}
+  \platform{Mac}
+\modulesynopsis{Interface to the Folder Manager.}
+
+
+\section{\module{Carbon.Help} --- Help Manager}
+\declaremodule{standard}{Carbon.Help}
+  \platform{Mac}
+\modulesynopsis{Interface to the Carbon Help Manager.}
+
+\section{\module{Carbon.List} --- List Manager}
+\declaremodule{standard}{Carbon.List}
+  \platform{Mac}
+\modulesynopsis{Interface to the List Manager.}
+
+
+\section{\module{Carbon.Menu} --- Menu Manager}
+\declaremodule{standard}{Carbon.Menu}
+  \platform{Mac}
+\modulesynopsis{Interface to the Menu Manager.}
+
+
+\section{\module{Carbon.Mlte} --- MultiLingual Text Editor}
+\declaremodule{standard}{Carbon.Mlte}
+  \platform{Mac}
+\modulesynopsis{Interface to the MultiLingual Text Editor.}
+
+
+\section{\module{Carbon.Qd} --- QuickDraw}
+\declaremodule{builtin}{Carbon.Qd}
+  \platform{Mac}
+\modulesynopsis{Interface to the QuickDraw toolbox.}
+
+
+\section{\module{Carbon.Qdoffs} --- QuickDraw Offscreen}
+\declaremodule{builtin}{Carbon.Qdoffs}
+  \platform{Mac}
+\modulesynopsis{Interface to the QuickDraw Offscreen APIs.}
+
+
+\section{\module{Carbon.Qt} --- QuickTime}
+\declaremodule{standard}{Carbon.Qt}
+  \platform{Mac}
+\modulesynopsis{Interface to the QuickTime toolbox.}
+
+
+\section{\module{Carbon.Res} --- Resource Manager and Handles}
+\declaremodule{standard}{Carbon.Res}
+  \platform{Mac}
+\modulesynopsis{Interface to the Resource Manager and Handles.}
+
+\section{\module{Carbon.Scrap} --- Scrap Manager}
+\declaremodule{standard}{Carbon.Scrap}
+  \platform{Mac}
+\modulesynopsis{Interface to the Carbon Scrap Manager.}
+
+\section{\module{Carbon.Snd} --- Sound Manager}
+\declaremodule{standard}{Carbon.Snd}
+  \platform{Mac}
+\modulesynopsis{Interface to the Sound Manager.}
+
+
+\section{\module{Carbon.TE} --- TextEdit}
+\declaremodule{standard}{Carbon.TE}
+  \platform{Mac}
+\modulesynopsis{Interface to TextEdit.}
+
+
+\section{\module{Carbon.Win} --- Window Manager}
+\declaremodule{standard}{Carbon.Win}
+  \platform{Mac}
+\modulesynopsis{Interface to the Window Manager.}

Added: vendor/Python/current/Doc/mac/undoc.tex
===================================================================
--- vendor/Python/current/Doc/mac/undoc.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/mac/undoc.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,97 @@
+\chapter{Undocumented Modules \label{undocumented-modules}}
+
+
+The modules in this chapter are poorly documented (if at all).  If you
+wish to contribute documentation of any of these modules, please get in
+touch with
+\ulink{\email{docs at python.org}}{mailto:docs at python.org}.
+
+\localmoduletable
+
+
+\section{\module{applesingle} --- AppleSingle decoder}
+\declaremodule{standard}{applesingle}
+  \platform{Mac}
+\modulesynopsis{Rudimentary decoder for AppleSingle format files.}
+
+
+\section{\module{buildtools} --- Helper module for BuildApplet and Friends}
+\declaremodule{standard}{buildtools}
+  \platform{Mac}
+\modulesynopsis{Helper module for BuildApplet, BuildApplication and
+                macfreeze.}
+
+\deprecated{2.4}
+
+\section{\module{cfmfile} --- Code Fragment Resource module}
+\declaremodule{standard}{cfmfile}
+  \platform{Mac}
+\modulesynopsis{Code Fragment Resource module.}
+
+\module{cfmfile} is a module that understands Code Fragments and the
+accompanying ``cfrg'' resources. It can parse them and merge them, and is
+used by BuildApplication to combine all plugin modules to a single
+executable.
+
+\deprecated{2.4}
+
+\section{\module{icopen} --- Internet Config replacement for \method{open()}}
+\declaremodule{standard}{icopen}
+  \platform{Mac}
+\modulesynopsis{Internet Config replacement for \method{open()}.}
+
+Importing \module{icopen} will replace the builtin \method{open()}
+with a version that uses Internet Config to set file type and creator
+for new files.
+
+
+\section{\module{macerrors} --- Mac OS Errors}
+\declaremodule{standard}{macerrors}
+  \platform{Mac}
+\modulesynopsis{Constant definitions for many Mac OS error codes.}
+
+\module{macerrors} contains constant definitions for many Mac OS error
+codes.
+
+
+\section{\module{macresource} --- Locate script resources}
+\declaremodule{standard}{macresource}
+  \platform{Mac}
+\modulesynopsis{Locate script resources.}
+
+\module{macresource} helps scripts finding their resources, such as
+dialogs and menus, without requiring special case code for when the
+script is run under MacPython, as a MacPython applet or under OSX Python.
+
+\section{\module{Nav} --- NavServices calls}
+\declaremodule{standard}{Nav}
+  \platform{Mac}
+\modulesynopsis{Interface to Navigation Services.}
+
+A low-level interface to Navigation Services. 
+
+\section{\module{PixMapWrapper} --- Wrapper for PixMap objects}
+\declaremodule{standard}{PixMapWrapper}
+  \platform{Mac}
+\modulesynopsis{Wrapper for PixMap objects.}
+
+\module{PixMapWrapper} wraps a PixMap object with a Python object that
+allows access to the fields by name. It also has methods to convert
+to and from \module{PIL} images.
+
+\section{\module{videoreader} --- Read QuickTime movies}
+\declaremodule{standard}{videoreader}
+  \platform{Mac}
+\modulesynopsis{Read QuickTime movies frame by frame for further processing.}
+
+\module{videoreader} reads and decodes QuickTime movies and passes
+a stream of images to your program. It also provides some support for
+audio tracks.
+
+\section{\module{W} --- Widgets built on \module{FrameWork}}
+\declaremodule{standard}{W}
+  \platform{Mac}
+\modulesynopsis{Widgets for the Mac, built on top of \refmodule{FrameWork}.}
+
+The \module{W} widgets are used extensively in the \program{IDE}.
+

Added: vendor/Python/current/Doc/mac/using.tex
===================================================================
--- vendor/Python/current/Doc/mac/using.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/mac/using.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,218 @@
+\chapter{Using Python on a Macintosh \label{using}}
+\sectionauthor{Bob Savage}{bobsavage at mac.com}
+
+Python on a Macintosh running Mac OS X is in principle very similar to
+Python on any other \UNIX platform, but there are a number of additional
+features such as the IDE and the Package Manager that are worth pointing out.
+
+Python on Mac OS 9 or earlier can be quite different from Python on
+\UNIX{} or Windows, but is beyond the scope of this manual, as that platform
+is no longer supported, starting with Python 2.4. See
+\url{http://www.cwi.nl/\textasciitilde jack/macpython} for installers
+for the latest 2.3 release for Mac OS 9 and related documentation.
+
+\section{Getting and Installing MacPython \label{getting-OSX}}
+
+Mac OS X 10.3 comes with Python 2.3 pre-installed by Apple.
+This installation does not come with the IDE and other additions, however,
+so to get these you need to install the \program{MacPython for Panther additions}
+from the MacPython website, \url{http://www.cwi.nl/\textasciitilde jack/macpython}.
+
+For MacPython 2.4, or for any MacPython on earlier releases of Mac OS X,
+you need to install a full distribution from the same website.
+
+What you get after installing is a number of things:
+
+\begin{itemize}
+    \item A \file{MacPython-2.3} folder in your \file{Applications}
+    folder. In here you find the PythonIDE Integrated Development Environment;
+    PythonLauncher, which handles double-clicking Python scripts from
+    the Finder; and the Package Manager.
+    
+    \item A fairly standard \UNIX{} commandline Python interpreter in
+    \file{/usr/local/bin/python}, but without the usual
+    \file{/usr/local/lib/python}.
+    
+    \item A framework \file{/Library/Frameworks/Python.framework}, where
+    all the action really is, but which you usually do not have to be aware of.
+\end{itemize}
+
+To uninstall MacPython you can simply remove these three things.
+
+If you use the ``additions'' installer to install on top of an existing
+Apple-Python you will not get the framework and the commandline interpreter,
+as they have been installed by Apple already, in
+\file{/System/Library/Frameworks/Python.framework} and
+\file{/usr/bin/python}, respectively. You should in principle never modify
+or delete these, as they are Apple-controlled and may be used by Apple- or
+third-party software.
+
+PythonIDE contains an Apple Help Viewer book called "MacPython Help"
+which you can access through its help menu. If you are completely new to
+Python you should start reading the IDE introduction in that document.
+
+If you are familiar with Python on other \UNIX{} platforms you should
+read the section on running Python scripts from the \UNIX{} shell.
+
+\subsection{How to run a Python script}
+
+Your best way to get started with Python on Mac OS X is through the PythonIDE
+integrated development environment, see section \ref{IDE} and use the Help
+menu when the IDE is running.
+
+If you want to run Python scripts from the Terminal window command line
+or from the Finder you first need an editor to create your script.
+Mac OS X comes with a number of standard \UNIX{} command line editors,
+\program{vim} and \program{emacs} among them. If you want a more Mac-like
+editor \program{BBEdit} or \program{TextWrangler} from Bare Bones Software
+(see \url{http://www.barebones.com/products/bbedit/index.shtml}) are
+good choices.  \program{AppleWorks} or any other
+word processor that can save files in ASCII is also a possibility, including
+\program{TextEdit} which is included with OS X.
+
+To run your script from the Terminal window you must make sure that
+\file{/usr/local/bin} is in your shell search path. 
+
+To run your script from the Finder you have two options:
+\begin{itemize}
+    \item Drag it to \program{PythonLauncher}
+    \item Select \program{PythonLauncher} as the default application
+    to open your script (or any .py script) through the finder Info window
+    and double-click it.
+\end{itemize}
+
+PythonLauncher has various preferences to control how your script is launched.
+Option-dragging allows you to change these for one invocation, or use its
+Preferences menu to change things globally.
+
+\subsection{Running scripts with a GUI \label{osx-gui-scripts}}
+
+There is one Mac OS X quirk that you need to be aware of: programs
+that talk to the Aqua window manager (in other words, anything that has a GUI)
+need to be run in a special way. Use \program{pythonw} instead of \program{python}
+to start such scripts.
+
+\subsection{configuration}
+
+MacPython honours all standard \UNIX{} environment variables such as
+\envvar{PYTHONPATH}, but setting these variables for programs started
+from the Finder is non-standard
+as the Finder does not read your \file{.profile} or \file{.cshrc} at startup.
+You need to create a file \file{\textasciitilde /.MacOSX/environment.plist}.
+See Apple's Technical Document QA1067 for details.
+
+Installing additional Python packages is most easily done through the
+Package Manager, see the MacPython Help Book for details.
+
+
+\section{The IDE\label{IDE}}
+
+The \program{Python IDE} (Integrated Development Environment) is a
+separate application that acts as a text editor for your Python code,
+a class browser, a graphical debugger, and more.
+
+The online Python Help contains a quick walkthrough of the IDE that
+shows the major features and how to use them.
+
+\subsection{Using the ``Python Interactive'' window}
+
+Use this window like you would use a normal \UNIX{} command line
+interpreter.
+
+\subsection{Writing a Python Script \label{IDEwrite}}
+
+In addition to using the \program{Python IDE} interactively, you can
+also type out a complete Python program, saving it incrementally, and
+execute it or smaller selections of it.
+
+You can create a new script, open a previously saved script, and save
+your currently open script by selecting the appropriate item in the
+``File'' menu. Dropping a Python script onto the
+\program{Python IDE} will open it for editing.
+
+When the \program{Python IDE} saves a script, it uses the creator code
+settings which are available by clicking on the small black triangle
+on the top right of the document window, and selecting ``save
+options''. The default is to save the file with the \program{Python
+IDE} as the creator, this means that you can open the file for editing
+by simply double-clicking on its icon. You might want to change this
+behaviour so that it will be opened by the
+\program{PythonLauncher}, and run. To do this simply choose
+``PythonLauncher'' from the ``save options''. Note that these
+options are associated with the \emph{file} not the application.
+
+
+\subsection{Executing a script from within the IDE
+            \label{IDEexecution}}
+
+You can run the script in the frontmost window of the \program{Python
+IDE} by hitting the run all button.  You should be aware, however that
+if you use the Python convention \samp{if __name__ == "__main__":} the
+script will \emph{not} be ``__main__'' by default. To get that
+behaviour you must select the ``Run as __main__'' option from the
+small black triangle on the top right of the document window.  Note
+that this option is associated with the \emph{file} not the
+application. It \emph{will} stay active after a save, however; to shut
+this feature off simply select it again.
+ 
+
+\subsection{``Save as'' versus ``Save as Applet''
+            \label{IDEapplet}}
+
+When you are done writing your Python script you have the option of
+saving it as an ``applet'' (by selecting ``Save as applet'' from the
+``File'' menu). This has a significant advantage in that you can drop
+files or folders onto it, to pass them to the applet the way
+command-line users would type them onto the command-line to pass them
+as arguments to the script. However, you should make sure to save the
+applet as a separate file, do not overwrite the script you are
+writing, because you will not be able to edit it again.
+
+Accessing the items passed to the applet via ``drag-and-drop'' is done
+using the standard \member{sys.argv} mechanism. See the general
+documentation for more
+% need to link to the appropriate place in non-Mac docs
+
+Note that saving a script as an applet will not make it runnable on a
+system without a Python installation.
+
+%\subsection{Debugger}
+% **NEED INFO HERE**
+ 
+%\subsection{Module Browser}
+% **NEED INFO HERE**
+ 
+%\subsection{Profiler}
+% **NEED INFO HERE**
+% end IDE
+
+%\subsection{The ``Scripts'' menu}
+% **NEED INFO HERE**
+
+\section{The Package Manager}
+
+Historically MacPython came with a number of useful extension packages
+included, because most Macintosh users do not have access to a development
+environment and C compiler. For Mac OS X that bundling is no longer done,
+but a new mechanism has been made available to allow easy access to
+extension packages.
+
+The Python Package Manager helps you installing additional packages
+that enhance Python. It determines the exact MacOS version  and Python
+version you have and uses that information to download  a database that
+has packages that are tested and tried on that combination. In other
+words: if something is in your Package Manager  window but does not work
+you are free to blame the database maintainer.
+
+PackageManager then checks which of the packages you have installed  and
+which ones are not. This should also work when you have installed packages 
+outside of PackageManager.  You can select packages and install them,
+and PackageManager will work out the requirements and install these too.
+
+Often PackageManager will list a package in two flavors: binary  and
+source. Binary should always work, source will only work if  you have
+installed the Apple Developer Tools. PackageManager will warn  you about
+this, and also about other external dependencies.
+
+PackageManager is available as a separate application and also  as a
+function of the IDE, through the File->Package Manager menu  entry.

Added: vendor/Python/current/Doc/paper-a4/pypaper.sty
===================================================================
--- vendor/Python/current/Doc/paper-a4/pypaper.sty	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/paper-a4/pypaper.sty	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,17 @@
+%
+%  Change this to say a4paper instead of letterpaper if you want A4.
+%
+\newcommand{\py at paper}{a4paper}
+\newcommand{\py at ptsize}{10pt}
+
+%  These set up the fonts for the documents.
+%
+%  The "times" package makes the default font the PostScript Times
+%  font, which makes for smaller PostScript and a font that more people 
+%  like.
+%
+%  The "avant" package causes the AvantGarde font to be used for
+%  sans-serif text, instead of the uglier Helvetica set up by the "times"
+%  package.
+%
+\RequirePackage{times}\typeout{Using Times instead of Computer Modern.}

Added: vendor/Python/current/Doc/perl/SynopsisTable.pm
===================================================================
--- vendor/Python/current/Doc/perl/SynopsisTable.pm	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/perl/SynopsisTable.pm	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,95 @@
+package SynopsisTable;
+
+sub new{
+    return bless {names=>'', info=>{}, file=>''};
+}
+
+sub declare{
+    my($self,$name,$key,$type) = @_;
+    if ($self->{names}) {
+        $self->{names} .= ",$name";
+    }
+    else {
+        $self->{names} .= "$name";
+    }
+    $self->{info}{$name} = "$key,$type,";
+}
+
+# The 'file' attribute is used to store the filename of the node in which
+# the table will be presented; this assumes that each table will be presented
+# only once, which works for the current use of this object.
+
+sub set_file{
+    my($self, $filename) = @_;
+    $self->{file} = "$filename";
+}
+
+sub get_file{
+    my $self = shift;
+    return $self->{file};
+}
+
+sub set_synopsis{
+    my($self,$name,$synopsis) = @_;
+    my($key,$type,$unused) = split ',', $self->{info}{$name}, 3;
+    $self->{info}{$name} = "$key,$type,$synopsis";
+}
+
+sub get{
+    my($self,$name) = @_;
+    return split /,/, $self->{info}{$name}, 3;
+}
+
+sub show{
+    my $self = shift;
+    my $name;
+    print "names: ", $self->{names}, "\n\n";
+    foreach $name (split /,/, $self->{names}) {
+        my($key,$type,$synopsis) = $self->get($name);
+        print "$name($key) is $type: $synopsis\n";
+    }
+}
+
+sub tohtml{
+    my $self = shift;
+    my $oddrow = 1;
+    my $data = "<table class='synopsistable' valign='baseline'>\n";
+    my $name;
+    foreach $name (split /,/, $self->{names}) {
+        my($key,$type,$synopsis) = $self->get($name);
+        my $link = "<a href='module-$key.html'>";
+        $synopsis =~ s/<tex2html_percent_mark>/%/g;
+        $synopsis =~ s/<tex2html_ampersand_mark>/\&amp;/g;
+        $data .= ('  <tr'
+                  . ($oddrow ? " class='oddrow'>\n      " : '>')
+                  . "<td><b><tt class='module'>$link$name</a></tt></b></td>\n"
+                  . "      <td>\&nbsp;</td>\n"
+                  . "      <td class='synopsis'>$synopsis</td></tr>\n");
+        $oddrow = !$oddrow;
+    }
+    $data .= "</table>\n";
+    $data;
+}
+
+
+package testSynopsisTable;
+
+sub test{
+    # this little test is mostly to debug the stuff above, since this is
+    # my first Perl "object".
+    my $st = SynopsisTable->new();
+    $st->declare("sample", "sample", "standard");
+    $st->set_synopsis("sample", "This is a little synopsis....");
+    $st->declare("copy_reg", "copyreg", "standard");
+    $st->set_synopsis("copy_reg", "pickle support stuff");
+    $st->show();
+
+    print "\n\n";
+
+    my $st2 = SynopsisTable->new();
+    $st2->declare("st2module", "st2module", "built-in");
+    $st2->set_synopsis("st2module", "silly little synopsis");
+    $st2->show();
+}
+
+1;      # This must be the last line -- Perl is bogus!

Added: vendor/Python/current/Doc/perl/distutils.perl
===================================================================
--- vendor/Python/current/Doc/perl/distutils.perl	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/perl/distutils.perl	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,21 @@
+# LaTeX2HTML support for distutils.sty.
+
+package main;
+
+sub do_cmd_command {
+    return use_wrappers(@_[0], '<code class="du-command">', '</code>');
+}
+
+sub do_cmd_option {
+    return use_wrappers(@_[0], '<span class="du-option">', '</span>');
+}
+
+sub do_cmd_filevar {
+    return use_wrappers(@_[0], '<span class="du-filevar">', '</span>');
+}
+
+sub do_cmd_XXX {
+    return use_wrappers(@_[0], '<b class="du-xxx">', '</b>');
+}
+
+1;  # Bad Perl.

Added: vendor/Python/current/Doc/perl/howto.perl
===================================================================
--- vendor/Python/current/Doc/perl/howto.perl	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/perl/howto.perl	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,12 @@
+# -*- perl -*-
+#
+# This implements the Python howto class.  All it really needs to do it
+# load the "python" style.
+
+package main;
+
+do_require_package("article");
+do_require_package("alltt");
+do_require_package("python");
+
+1;				# sheesh....

Added: vendor/Python/current/Doc/perl/isilo.perl
===================================================================
--- vendor/Python/current/Doc/perl/isilo.perl	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/perl/isilo.perl	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,12 @@
+package main;
+
+$USING_STYLES = 0;
+$NO_NAVIGATION = 1;
+$INDEX_COLUMNS = 1;
+$MODULE_INDEX_COLUMNS = 1;
+
+sub child_line {
+    return '';
+}
+
+1;      # stupid perl...

Added: vendor/Python/current/Doc/perl/l2hinit.perl
===================================================================
--- vendor/Python/current/Doc/perl/l2hinit.perl	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/perl/l2hinit.perl	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,801 @@
+# LaTeX2HTML support base for use with Python documentation.
+
+package main;
+
+use L2hos;
+
+$HTML_VERSION = 4.01;
+$LOWER_CASE_TAGS = 1;
+$NO_FRENCH_QUOTES = 1;
+
+# '' in \code{...} is still converted, so we can't use this yet.
+#$USE_CURLY_QUOTES = 1;
+
+# Force Unicode support to be loaded; request UTF-8 output.
+do_require_extension('unicode');
+do_require_extension('utf8');
+$HTML_OPTIONS = 'utf8';
+
+$MAX_LINK_DEPTH = 2;
+$ADDRESS = '';
+
+$NO_FOOTNODE = 1;
+$NUMBERED_FOOTNOTES = 1;
+
+# Python documentation uses section numbers to support references to match
+# in the printed and online versions.
+#
+$SHOW_SECTION_NUMBERS = 1;
+
+$ICONSERVER = '.';
+$IMAGE_TYPE = 'gif';
+
+# Control where the navigation bars should show up:
+$TOP_NAVIGATION = 1;
+$BOTTOM_NAVIGATION = 1;
+$AUTO_NAVIGATION = 0;
+
+$BODYTEXT = '';
+$CHILDLINE = "\n<p><br /></p><hr class='online-navigation' />\n";
+$VERBOSITY = 0;
+
+# default # of columns for the indexes
+$INDEX_COLUMNS = 2;
+$MODULE_INDEX_COLUMNS = 4;
+
+$HAVE_MODULE_INDEX = 0;
+$HAVE_GENERAL_INDEX = 0;
+$HAVE_TABLE_OF_CONTENTS = 0;
+
+$AESOP_META_TYPE = 'information';
+
+
+# A little painful, but lets us clean up the top level directory a little,
+# and not be tied to the current directory (as far as I can tell).  Testing
+# an existing definition of $mydir is needed since it cannot be computed when
+# run under mkhowto with recent versions of LaTeX2HTML, since this file is
+# not read directly by LaTeX2HTML any more.  mkhowto is required to prepend
+# the required definition at the top of the actual input file.
+#
+if (!defined $mydir) {
+    use Cwd;
+    use File::Basename;
+    ($myname, $mydir, $myext) = fileparse(__FILE__, '\..*');
+    chop $mydir;                        # remove trailing '/'
+    $mydir = getcwd() . "$dd$mydir"
+        unless $mydir =~ s|^/|/|;
+}
+$LATEX2HTMLSTYLES = "$mydir$envkey$LATEX2HTMLSTYLES";
+push (@INC, $mydir);
+
+($myrootname, $myrootdir, $myext) = fileparse($mydir, '\..*');
+chop $myrootdir;
+
+
+# Hackish way to get the appropriate paper-*/ directory into $TEXINPUTS;
+# pass in the paper size (a4 or letter) as the environment variable PAPER
+# to add the right directory.  If not given, the current directory is
+# added instead for use with HOWTO processing.
+#
+if (defined $ENV{'PAPER'}) {
+    $mytexinputs = "$myrootdir${dd}paper-$ENV{'PAPER'}$envkey";
+}
+else {
+    $mytexinputs = getcwd() . $envkey;
+}
+$mytexinputs .= "$myrootdir${dd}texinputs";
+
+
+# Change this variable to change the text added in "About this document...";
+# this should be an absolute pathname to get it right.
+#
+$ABOUT_FILE = "$myrootdir${dd}html${dd}stdabout.dat";
+
+
+sub custom_driver_hook {
+    #
+    # This adds the directory of the main input file to $TEXINPUTS; it
+    # seems to be sufficiently general that it should be fine for HOWTO
+    # processing.
+    #
+    # XXX This still isn't quite right; we should actually be inserting
+    # $mytexinputs just before any empty entry in TEXINPUTS is one
+    # exists instead of just concatenating the pieces like we do here.
+    #
+    my $file = $_[0];
+    my($jobname, $dir, $ext) = fileparse($file, '\..*');
+    $dir = L2hos->Make_directory_absolute($dir);
+    $dir =~ s/$dd$//;
+    $TEXINPUTS = "$dir$envkey$mytexinputs";
+    # Push everything into $TEXINPUTS since LaTeX2HTML doesn't pick
+    # this up on its own; we clear $ENV{'TEXINPUTS'} so the value set
+    # for this by the main LaTeX2HTML script doesn't contain duplicate
+    # directories.
+    if ($ENV{'TEXINPUTS'}) {
+        $TEXINPUTS .= "$envkey$ENV{'TEXINPUTS'}";
+        $ENV{'TEXINPUTS'} = undef;
+    }
+    print "\nSetting \$TEXINPUTS to $TEXINPUTS\n";
+
+    # Not sure why we need to deal with this both here and at the top,
+    # but this is needed to actually make it work.
+    do_require_extension('utf8');
+    $charset = $utf8_str;
+    $CHARSET = $utf8_str;
+    $USE_UTF = 1;
+}
+
+
+# $CUSTOM_BUTTONS is only used for the module index link.
+$CUSTOM_BUTTONS = '';
+
+sub make_nav_sectref($$$) {
+    my($label, $linktype, $title) = @_;
+    if ($title) {
+        if ($title =~ /\<[aA] /) {
+            $title =~ s/\<[aA] /<a class="sectref" rel="$linktype" /;
+            $title =~ s/ HREF=/ href=/;
+        }
+        else {
+            $title = "<span class=\"sectref\">$title</span>";
+        }
+        return "<b class=\"navlabel\">$label:</b>\n$title\n";
+    }
+    return '';
+}
+
+ at my_icon_tags = ();
+$my_icon_tags{'next'} = 'Next Page';
+$my_icon_tags{'next_page'} = 'Next Page';
+$my_icon_tags{'previous'} = 'Previous Page';
+$my_icon_tags{'previous_page'} = 'Previous Page';
+$my_icon_tags{'up'} = 'Up One Level';
+$my_icon_tags{'contents'} = 'Contents';
+$my_icon_tags{'index'} = 'Index';
+$my_icon_tags{'modules'} = 'Module Index';
+
+ at my_icon_names = ();
+$my_icon_names{'previous_page'} = 'previous';
+$my_icon_names{'next_page'} = 'next';
+
+sub get_my_icon($) {
+    my $name = $_[0];
+    my $text = $my_icon_tags{$name};
+    if ($my_icon_names{$name}) {
+        $name = $my_icon_names{$name};
+    }
+    if ($text eq '') {
+        $name = 'blank';
+    }
+    my $iconserver = ($ICONSERVER eq '.') ? '' : "$ICONSERVER/";
+    return "<img src='$iconserver$name.$IMAGE_TYPE'\n  border='0'"
+           . " height='32'  alt='$text' width='32' />";
+}
+
+sub unlinkify($) {
+    my $text = "$_[0]";
+    $text =~ s|</[aA]>||;
+    $text =~ s|<a\s+[^>]*>||i;
+    return $text;
+}
+
+sub use_icon($$$) {
+    my($rel,$str,$title) = @_;
+    if ($str) {
+        my $s = "$str";
+        if ($s =~ /\<tex2html_([a-z_]+)_visible_mark\>/) {
+            my $r = get_my_icon($1);
+            $s =~ s/\<tex2html_[a-z_]+_visible_mark\>/$r/;
+        }
+        $s =~ s/<[aA] /<a rel="$rel" title="$title"\n  /;
+        $s =~ s/ HREF=/ href=/;
+        return $s;
+    }
+    else {
+        return get_my_icon('blank');
+    }
+}
+
+sub make_nav_panel() {
+    my $s;
+    # new iconic         rel         iconic     page title
+    my $next     = use_icon('next',     $NEXT,     unlinkify($NEXT_TITLE));
+    my $up       = use_icon('parent',   $UP,       unlinkify($UP_TITLE));
+    my $previous = use_icon('prev',     $PREVIOUS, unlinkify($PREVIOUS_TITLE));
+    my $contents = use_icon('contents', $CONTENTS, 'Table of Contents');
+    my $index    = use_icon('index',    $INDEX,    'Index');
+    if (!$CUSTOM_BUTTONS) {
+        $CUSTOM_BUTTONS = get_my_icon('blank');
+    }
+    $s = ('<table align="center" width="100%" cellpadding="0" cellspacing="2">'
+          . "\n<tr>"
+          # left-hand side
+          . "\n<td class='online-navigation'>$previous</td>"
+          . "\n<td class='online-navigation'>$up</td>"
+          . "\n<td class='online-navigation'>$next</td>"
+          # title box
+          . "\n<td align=\"center\" width=\"100%\">$t_title</td>"
+          # right-hand side
+          . "\n<td class='online-navigation'>$contents</td>"
+          # module index
+          . "\n<td class='online-navigation'>$CUSTOM_BUTTONS</td>"
+          . "\n<td class='online-navigation'>$index</td>"
+          . "\n</tr></table>\n"
+          # textual navigation
+          . "<div class='online-navigation'>\n"
+          . make_nav_sectref("Previous", "prev", $PREVIOUS_TITLE)
+          . make_nav_sectref("Up", "parent", $UP_TITLE)
+          . make_nav_sectref("Next", "next", $NEXT_TITLE)
+          . "</div>\n"
+          );
+    # remove these; they are unnecessary and cause errors from validation
+    $s =~ s/ NAME="tex2html\d+"\n */ /g;
+    return $s;
+}
+
+sub add_child_links {
+    my $toc = add_real_child_links(@_);
+    $toc =~ s|\s*</[aA]>|</a>|g;
+    $toc =~ s/ NAME=\"tex2html\d+\"\s*href=/ href=/gi;
+    $toc =~ s|</UL>(\s*<BR( /)?>)?|</ul>|gi;
+    if ($toc =~ / NAME=["']CHILD_LINKS["']/) {
+        return "<div class='online-navigation'>\n$toc</div>\n";
+    }
+    return $toc;
+}
+
+sub get_version_text() {
+    if ($PACKAGE_VERSION ne '' && $t_date) {
+        return ("<span class=\"release-info\">"
+                . "Release $PACKAGE_VERSION$RELEASE_INFO,"
+                . " documentation updated on $t_date.</span>");
+    }
+    if ($PACKAGE_VERSION ne '') {
+        return ("<span class=\"release-info\">"
+                . "Release $PACKAGE_VERSION$RELEASE_INFO.</span>");
+    }
+    if ($t_date) {
+        return ("<span class=\"release-info\">Documentation released on "
+                . "$t_date.</span>");
+    }
+    return '';
+}
+
+
+sub top_navigation_panel() {
+    return "\n<div id='top-navigation-panel' xml:id='top-navigation-panel'>\n"
+           . make_nav_panel()
+           . "<hr /></div>\n";
+}
+
+sub bot_navigation_panel() {
+    return "\n<div class='online-navigation'>\n"
+           . "<p></p><hr />\n"
+           . make_nav_panel()
+           . "</div>\n"
+           . "<hr />\n"
+           . get_version_text()
+           . "\n";
+}
+
+sub add_link {
+    # Returns a pair (iconic link, textual link)
+    my($icon, $current_file, @link) = @_;
+    my($dummy, $file, $title) = split($delim,
+                                      $section_info{join(' ', at link)});
+    if ($icon =~ /\<tex2html_([_a-z]+)_visible_mark\>/) {
+        my $r = get_my_icon($1);
+        $icon =~ s/\<tex2html_[_a-z]+_visible_mark\>/$r/;
+    }
+    if ($title && ($file ne $current_file)) {
+        $title = purify($title);
+        $title = get_first_words($title, $WORDS_IN_NAVIGATION_PANEL_TITLES);
+        return (make_href($file, $icon), make_href($file, "$title"))
+        }
+    elsif ($icon eq get_my_icon('up') && $EXTERNAL_UP_LINK) {
+        return (make_href($EXTERNAL_UP_LINK, $icon),
+                make_href($EXTERNAL_UP_LINK, "$EXTERNAL_UP_TITLE"))
+        }
+    elsif ($icon eq get_my_icon('previous')
+           && $EXTERNAL_PREV_LINK && $EXTERNAL_PREV_TITLE) {
+        return (make_href($EXTERNAL_PREV_LINK, $icon),
+                make_href($EXTERNAL_PREV_LINK, "$EXTERNAL_PREV_TITLE"))
+        }
+    elsif ($icon eq get_my_icon('next')
+           && $EXTERNAL_DOWN_LINK && $EXTERNAL_DOWN_TITLE) {
+        return (make_href($EXTERNAL_DOWN_LINK, $icon),
+                make_href($EXTERNAL_DOWN_LINK, "$EXTERNAL_DOWN_TITLE"))
+        }
+    return (&inactive_img($icon), "");
+}
+
+sub add_special_link($$$) {
+    my($icon, $file, $current_file) = @_;
+    if ($icon =~ /\<tex2html_([_a-z]+)_visible_mark\>/) {
+        my $r = get_my_icon($1);
+        $icon =~ s/\<tex2html_[_a-z]+_visible_mark\>/$r/;
+    }
+    return (($file && ($file ne $current_file))
+            ? make_href($file, $icon)
+            : undef)
+}
+
+# The img_tag() function seems only to be called with the parameter
+# 'anchor_invisible_mark', which we want to turn into ''.  Since
+# replace_icon_marks() is the only interesting caller, and all it really
+# does is call img_tag(), we can just define the hook alternative to be
+# a no-op instead.
+#
+sub replace_icons_hook {}
+
+sub do_cmd_arabic {
+    # get rid of that nasty <SPAN CLASS="arabic">...</SPAN>
+    my($ctr, $val, $id, $text) = &read_counter_value($_[0]);
+    return ($val ? farabic($val) : "0") . $text;
+}
+
+
+sub gen_index_id($$) {
+    # this is used to ensure common index key generation and a stable sort
+    my($str, $extra) = @_;
+    sprintf('%s###%s%010d', $str, $extra, ++$global{'max_id'});
+}
+
+sub insert_index($$$$$) {
+    my($mark, $datafile, $columns, $letters, $prefix) = @_;
+    my $prog = "$myrootdir/tools/buildindex.py";
+    my $index;
+    if ($letters) {
+        $index = `$prog --columns $columns --letters $datafile`;
+    }
+    else {
+        $index = `$prog --columns $columns $datafile`;
+    }
+    if (!s/$mark/$prefix$index/) {
+        print "\nCould not locate index mark: $mark";
+    }
+}
+
+sub add_idx() {
+    print "\nBuilding HTML for the index ...";
+    close(IDXFILE);
+    insert_index($idx_mark, 'index.dat', $INDEX_COLUMNS, 1, '');
+}
+
+
+$idx_module_mark = '<tex2html_idx_module_mark>';
+$idx_module_title = 'Module Index';
+
+sub add_module_idx() {
+    print "\nBuilding HTML for the module index ...";
+    my $key;
+    my $first = 1;
+    my $prevplat = '';
+    my $allthesame = 1;
+    my $prefix = '';
+    foreach $key (keys %Modules) {
+        $key =~ s/<tt>([a-zA-Z0-9._]*)<\/tt>/$1/;
+        my $plat = "$ModulePlatforms{$key}";
+        $plat = ''
+          if ($plat eq $IGNORE_PLATFORM_ANNOTATION);
+        if (!$first) {
+            $allthesame = 0
+              if ($prevplat ne $plat);
+        }
+        else { $first = 0; }
+        $prevplat = $plat;
+    }
+    open(MODIDXFILE, '>modindex.dat') || die "\n$!\n";
+    foreach $key (keys %Modules) {
+        # dump the line in the data file; just use a dummy seqno field
+        my $nkey = $1;
+        my $moditem = "$Modules{$key}";
+        my $plat = '';
+        $key =~ s/<tt>([a-zA-Z0-9._]*)<\/tt>/$1/;
+        if ($ModulePlatforms{$key} && !$allthesame) {
+            $plat = (" <em>(<span class=\"platform\">$ModulePlatforms{$key}"
+                     . '</span>)</em>');
+        }
+        print MODIDXFILE $moditem . $IDXFILE_FIELD_SEP
+              . "<tt class=\"module\">$key</tt>$plat###\n";
+    }
+    close(MODIDXFILE);
+
+    if ($GLOBAL_MODULE_INDEX) {
+        $prefix = <<MODULE_INDEX_PREFIX;
+
+<p> This index only lists modules documented in this manual.
+  The <em class="citetitle"><a href="$GLOBAL_MODULE_INDEX">Global Module
+     Index</a></em> lists all modules that are documented in this set
+  of manuals.</p>
+MODULE_INDEX_PREFIX
+    }
+    if (!$allthesame) {
+        $prefix .= <<PLAT_DISCUSS;
+
+<p> Some module names are followed by an annotation indicating what
+platform they are available on.</p>
+
+PLAT_DISCUSS
+    }
+    insert_index($idx_module_mark, 'modindex.dat', $MODULE_INDEX_COLUMNS, 0,
+                 $prefix);
+}
+
+# replace both indexes as needed:
+sub add_idx_hook {
+    add_idx() if (/$idx_mark/);
+    process_python_state();
+    if ($MODULE_INDEX_FILE) {
+        local ($_);
+        open(MYFILE, "<$MODULE_INDEX_FILE");
+        sysread(MYFILE, $_, 1024*1024);
+        close(MYFILE);
+        add_module_idx();
+        open(MYFILE,">$MODULE_INDEX_FILE");
+        print MYFILE $_;
+        close(MYFILE);
+    }
+}
+
+
+# In addition to the standard stuff, add label to allow named node files and
+# support suppression of the page complete (for HTML Help use).
+$MY_CONTENTS_PAGE = '';
+sub do_cmd_tableofcontents {
+    local($_) = @_;
+    $TITLE = $toc_title;
+    $tocfile = $CURRENT_FILE;
+    my($closures, $reopens) = preserve_open_tags();
+    anchor_label('contents', $CURRENT_FILE, $_);        # this is added
+    $MY_CONTENTS_PAGE = "$CURRENT_FILE";
+    join('', "\\tableofchildlinks[off]", $closures
+         , make_section_heading($toc_title, 'h2'), $toc_mark
+         , $reopens, $_);
+}
+# In addition to the standard stuff, add label to allow named node files.
+sub do_cmd_listoffigures {
+    local($_) = @_;
+    $TITLE = $lof_title;
+    $loffile = $CURRENT_FILE;
+    my($closures, $reopens) = preserve_open_tags();
+    anchor_label('lof', $CURRENT_FILE, $_);             # this is added
+    join('', "<br />\n", $closures
+         , make_section_heading($lof_title, 'h2'), $lof_mark
+         , $reopens, $_);
+}
+# In addition to the standard stuff, add label to allow named node files.
+sub do_cmd_listoftables {
+    local($_) = @_;
+    $TITLE = $lot_title;
+    $lotfile = $CURRENT_FILE;
+    my($closures, $reopens) = preserve_open_tags();
+    anchor_label('lot', $CURRENT_FILE, $_);             # this is added
+    join('', "<br />\n", $closures
+         , make_section_heading($lot_title, 'h2'), $lot_mark
+         , $reopens, $_);
+}
+# In addition to the standard stuff, add label to allow named node files.
+sub do_cmd_textohtmlinfopage {
+    local($_) = @_;
+    if ($INFO) {                                        #
+        anchor_label("about",$CURRENT_FILE,$_);         # this is added
+    }                                                   #
+    my $the_version = '';                               # and the rest is
+    if ($t_date) {                                      # mostly ours
+        $the_version = ",\n$t_date";
+        if ($PACKAGE_VERSION) {
+            $the_version .= ", Release $PACKAGE_VERSION$RELEASE_INFO";
+        }
+    }
+    my $about;
+    open(ABOUT, "<$ABOUT_FILE") || die "\n$!\n";
+    sysread(ABOUT, $about, 1024*1024);
+    close(ABOUT);
+    $_ = (($INFO == 1)
+          ? join('',
+                 $close_all,
+                 "<strong>$t_title</strong>$the_version\n",
+                 $about,
+                 $open_all, $_)
+          : join('', $close_all, $INFO,"\n", $open_all, $_));
+    $_;
+}
+
+$GENERAL_INDEX_FILE = '';
+$MODULE_INDEX_FILE = '';
+
+# $idx_mark will be replaced with the real index at the end
+sub do_cmd_textohtmlindex {
+    local($_) = @_;
+    $TITLE = $idx_title;
+    $idxfile = $CURRENT_FILE;
+    $GENERAL_INDEX_FILE = "$CURRENT_FILE";
+    if (%index_labels) { make_index_labels(); }
+    if (($SHORT_INDEX) && (%index_segment)) { make_preindex(); }
+    else { $preindex = ''; }
+    my $heading = make_section_heading($idx_title, 'h2') . $idx_mark;
+    my($pre, $post) = minimize_open_tags($heading);
+    anchor_label('genindex',$CURRENT_FILE,$_);          # this is added
+    return "<br />\n" . $pre . $_;
+}
+
+# $idx_module_mark will be replaced with the real index at the end
+sub do_cmd_textohtmlmoduleindex {
+    local($_) = @_;
+    $TITLE = $idx_module_title;
+    anchor_label('modindex', $CURRENT_FILE, $_);
+    $MODULE_INDEX_FILE = "$CURRENT_FILE";
+    $_ = ('<p></p>' . make_section_heading($idx_module_title, 'h2')
+          . $idx_module_mark . $_);
+    return $_;
+}
+
+# The bibliography and the index should be treated as separate
+# sections in their own HTML files. The \bibliography{} command acts
+# as a sectioning command that has the desired effect. But when the
+# bibliography is constructed manually using the thebibliography
+# environment, or when using the theindex environment it is not
+# possible to use the normal sectioning mechanism. This subroutine
+# inserts a \bibliography{} or a dummy \textohtmlindex command just
+# before the appropriate environments to force sectioning.
+
+# XXX   This *assumes* that if there are two {theindex} environments,
+#       the first is the module index and the second is the standard
+#       index.  This is sufficient for the current Python documentation,
+#       but that's about it.
+
+sub add_bbl_and_idx_dummy_commands {
+    my $id = $global{'max_id'};
+
+    if (/[\\]tableofcontents/) {
+        $HAVE_TABLE_OF_CONTENTS = 1;
+    }
+    s/([\\]begin\s*$O\d+$C\s*thebibliography)/$bbl_cnt++; $1/eg;
+    s/([\\]begin\s*$O\d+$C\s*thebibliography)/$id++; "\\bibliography$O$id$C$O$id$C $1"/geo;
+    my(@parts) = split(/\\begin\s*$O\d+$C\s*theindex/);
+    if (scalar(@parts) == 3) {
+        # Be careful to re-write the string in place, since $_ is *not*
+        # returned explicity;  *** nasty side-effect dependency! ***
+        print "\nadd_bbl_and_idx_dummy_commands ==> adding general index";
+        print "\nadd_bbl_and_idx_dummy_commands ==> adding module index";
+        my $rx = "([\\\\]begin\\s*$O\\d+$C\\s*theindex[\\s\\S]*)"
+          . "([\\\\]begin\\s*$O\\d+$C\\s*theindex)";
+        s/$rx/\\textohtmlmoduleindex $1 \\textohtmlindex $2/o;
+        # Add a button to the navigation areas:
+        $CUSTOM_BUTTONS .= ('<a href="modindex.html" title="Module Index">'
+                            . get_my_icon('modules')
+                            . '</a>');
+        $HAVE_MODULE_INDEX = 1;
+        $HAVE_GENERAL_INDEX = 1;
+    }
+    elsif (scalar(@parts) == 2) {
+        print "\nadd_bbl_and_idx_dummy_commands ==> adding general index";
+        my $rx = "([\\\\]begin\\s*$O\\d+$C\\s*theindex)";
+        s/$rx/\\textohtmlindex $1/o;
+        $HAVE_GENERAL_INDEX = 1;
+    }
+    elsif (scalar(@parts) == 1) {
+        print "\nadd_bbl_and_idx_dummy_commands ==> no index found";
+        $CUSTOM_BUTTONS .= get_my_icon('blank');
+        $global{'max_id'} = $id; # not sure why....
+        s/([\\]begin\s*$O\d+$C\s*theindex)/\\textohtmlindex $1/o;
+            s/[\\]printindex/\\textohtmlindex /o;
+    }
+    else {
+        die "\n\nBad number of index environments!\n\n";
+    }
+    #----------------------------------------------------------------------
+    lib_add_bbl_and_idx_dummy_commands()
+        if defined(&lib_add_bbl_and_idx_dummy_commands);
+}
+
+# The bibliographic references, the appendices, the lists of figures
+# and tables etc. must appear in the contents table at the same level
+# as the outermost sectioning command. This subroutine finds what is
+# the outermost level and sets the above to the same level;
+
+sub set_depth_levels {
+    # Sets $outermost_level
+    my $level;
+    #RRM:  do not alter user-set value for  $MAX_SPLIT_DEPTH
+    foreach $level ("part", "chapter", "section", "subsection",
+                    "subsubsection", "paragraph") {
+        last if (($outermost_level) = /\\($level)$delimiter_rx/);
+    }
+    $level = ($outermost_level ? $section_commands{$outermost_level} :
+              do {$outermost_level = 'section'; 3;});
+
+    #RRM:  but calculate value for $MAX_SPLIT_DEPTH when a $REL_DEPTH was given
+    if ($REL_DEPTH && $MAX_SPLIT_DEPTH) {
+        $MAX_SPLIT_DEPTH = $level + $MAX_SPLIT_DEPTH;
+    } elsif (!($MAX_SPLIT_DEPTH)) { $MAX_SPLIT_DEPTH = 1 };
+
+    %unnumbered_section_commands = ('tableofcontents' => $level,
+                                    'listoffigures' => $level,
+                                    'listoftables' => $level,
+                                    'bibliography' => $level,
+                                    'textohtmlindex' => $level,
+                                    'textohtmlmoduleindex' => $level);
+    $section_headings{'textohtmlmoduleindex'} = 'h1';
+
+    %section_commands = (%unnumbered_section_commands,
+                         %section_commands);
+
+    make_sections_rx();
+}
+
+
+# This changes the markup used for {verbatim} environments, and is the
+# best way I've found that ensures the <dl> goes on the outside of the
+# <pre>...</pre>.
+#
+# Note that this *must* be done in the init file, not the python.perl
+# style support file.  The %declarations must be set before
+# initialize() is called in the main LaTeX2HTML script (which happens
+# before style files are loaded).
+#
+%declarations = ('preform' => '<div class="verbatim"><pre></pre></div>',
+                 %declarations);
+
+
+# This is a modified version of what's provided by LaTeX2HTML; see the
+# comment on the middle stanza for an explanation of why we keep our
+# own version.
+#
+# This routine must be called once on the text only,
+# else it will "eat up" sensitive constructs.
+sub text_cleanup {
+    # MRO: replaced $* with /m
+    s/(\s*\n){3,}/\n\n/gom;	# Replace consecutive blank lines with one
+    s/<(\/?)P>\s*(\w)/<$1P>\n$2/gom;      # clean up paragraph starts and ends
+    s/$O\d+$C//go;		# Get rid of bracket id's
+    s/$OP\d+$CP//go;		# Get rid of processed bracket id's
+    s/(<!)?--?(>)?/(length($1) || length($2)) ? "$1--$2" : "-"/ge;
+    # Spacing commands
+    s/\\( |$)/ /go;
+    #JKR: There should be no more comments in the source now.
+    #s/([^\\]?)%/$1/go;        # Remove the comment character
+    # Cannot treat \, as a command because , is a delimiter ...
+    s/\\,/ /go;
+    # Replace tilde's with non-breaking spaces
+    s/ *~/&nbsp;/g;
+
+    # This is why we have this copy of this routine; the following
+    # isn't so desirable as the author/maintainers of LaTeX2HTML seem
+    # to think.  It's not commented out in the main script, so we have
+    # to override the whole thing.  In particular, we don't want empty
+    # table cells to disappear.
+
+    ### DANGEROUS ?? ###
+    # remove redundant (not <P></P>) empty tags, incl. with attributes
+    #s/\n?<([^PD >][^>]*)>\s*<\/\1>//g;
+    #s/\n?<([^PD >][^>]*)>\s*<\/\1>//g;
+    # remove redundant empty tags (not </P><P> or <TD> or <TH>)
+    #s/<\/(TT|[^PTH][A-Z]+)><\1>//g;
+    #s/<([^PD ]+)(\s[^>]*)?>\n*<\/\1>//g;
+
+    #JCL(jcl-hex)
+    # Replace ^^ special chars (according to p.47 of the TeX book)
+    # Useful when coming from the .aux file (german umlauts, etc.)
+    s/\^\^([^0-9a-f])/chr((64+ord($1))&127)/ge;
+    s/\^\^([0-9a-f][0-9a-f])/chr(hex($1))/ge;
+}
+
+# This is used to map the link rel attributes LaTeX2HTML uses to those
+# currently recommended by the W3C.
+sub custom_REL_hook {
+    my($rel,$junk) = @_;
+    return 'parent' if $rel eq 'up';
+    return 'prev' if $rel eq 'previous';
+    return $rel;
+}
+
+# This is added to get rid of the long comment that follows the
+# doctype declaration; MSIE5 on NT4 SP4 barfs on it and drops the
+# content of the page.
+$MY_PARTIAL_HEADER = '';
+sub make_head_and_body($$) {
+    my($title, $body) = @_;
+    $body = " $body" unless ($body eq '');
+    my $DTDcomment = '';
+    my($version, $isolanguage) = ($HTML_VERSION, 'EN');
+    my %isolanguages = (  'english',  'EN'   , 'USenglish', 'EN.US'
+                        , 'original', 'EN'   , 'german'   , 'DE'
+                        , 'austrian', 'DE.AT', 'french'   , 'FR'
+                        , 'spanish',  'ES');
+    $isolanguage = $isolanguages{$default_language};
+    $isolanguage = 'EN' unless $isolanguage;
+    $title = &purify($title,1);
+    eval("\$title = ". $default_title ) unless ($title);
+
+    # allow user-modification of the <title> tag; thanks Dan Young
+    if (defined &custom_TITLE_hook) {
+        $title = &custom_TITLE_hook($title, $toc_sec_title);
+    }
+
+    if ($DOCTYPE =~ /\/\/[\w\.]+\s*$/) { # language spec included
+        $DTDcomment = "<!DOCTYPE html PUBLIC \"$DOCTYPE\">\n";
+    } else {
+        $DTDcomment = "<!DOCTYPE html PUBLIC \"$DOCTYPE//"
+            . ($ISO_LANGUAGE ? $ISO_LANGUAGE : $isolanguage) . "\">\n";
+    }
+    if ($MY_PARTIAL_HEADER eq '') {
+        my $favicon = '';
+        if ($FAVORITES_ICON) {
+            my($myname, $mydir, $myext) = fileparse($FAVORITES_ICON, '\..*');
+            my $favtype = '';
+            if ($myext eq '.gif' || $myext eq '.png') {
+                $myext =~ s/^[.]//;
+                $favtype = " type=\"image/$myext\"";
+            }
+            $favicon = (
+                "\n<link rel=\"SHORTCUT ICON\" href=\"$FAVORITES_ICON\""
+                . "$favtype />");
+        }
+        $STYLESHEET = $FILE.".css" unless $STYLESHEET;
+        $MY_PARTIAL_HEADER = join('',
+            ($DOCTYPE ? $DTDcomment : ''),
+            "<html>\n<head>",
+            ($BASE ? "\n<base href=\"$BASE\" />" : ''),
+            "\n<link rel=\"STYLESHEET\" href=\"$STYLESHEET\" type='text/css'",
+            " />",
+            $favicon,
+            ($EXTERNAL_UP_LINK
+             ? ("\n<link rel='start' href='" . $EXTERNAL_UP_LINK
+                . ($EXTERNAL_UP_TITLE ?
+                   "' title='$EXTERNAL_UP_TITLE' />" : "' />"))
+             : ''),
+            "\n<link rel=\"first\" href=\"$FILE.html\"",
+            ($t_title ? " title='$t_title'" : ''),
+            ' />',
+            ($HAVE_TABLE_OF_CONTENTS
+             ? ("\n<link rel='contents' href='$MY_CONTENTS_PAGE'"
+                . ' title="Contents" />')
+             : ''),
+            ($HAVE_GENERAL_INDEX
+             ? ("\n<link rel='index' href='$GENERAL_INDEX_FILE'"
+                . " title='Index' />")
+             : ''),
+            # disable for now -- Mozilla doesn't do well with multiple indexes
+            # ($HAVE_MODULE_INDEX
+            #  ? ("<link rel="index" href='$MODULE_INDEX_FILE'"
+            #     . " title='Module Index' />\n")
+            #  : ''),
+            ($INFO
+             # XXX We can do this with the Python tools since the About...
+             # page always gets copied to about.html, even when we use the
+             # generated node###.html page names.  Won't work with the
+             # rest of the Python doc tools.
+             ? ("\n<link rel='last' href='about.html'"
+                . " title='About this document...' />"
+                . "\n<link rel='help' href='about.html'"
+                . " title='About this document...' />")
+             : ''),
+            $more_links_mark,
+            "\n",
+            ($CHARSET && $HTML_VERSION ge "2.1"
+             ? ('<meta http-equiv="Content-Type" content="text/html; '
+                . "charset=$CHARSET\" />\n")
+             : ''),
+            ($AESOP_META_TYPE
+             ? "<meta name='aesop' content='$AESOP_META_TYPE' />\n" : ''));
+    }
+    if (!$charset && $CHARSET) {
+        $charset = $CHARSET;
+        $charset =~ s/_/\-/go;
+    }
+    join('',
+         $MY_PARTIAL_HEADER,
+         "<title>", $title, "</title>\n</head>\n<body$body>");
+}
+
+sub replace_morelinks {
+    $more_links =~ s/ REL=/ rel=/g;
+    $more_links =~ s/ HREF=/ href=/g;
+    $more_links =~ s/<LINK /<link /g;
+    $more_links =~ s/">/" \/>/g;
+    $_ =~ s/$more_links_mark/$more_links/e;
+}
+
+1;      # This must be the last line

Added: vendor/Python/current/Doc/perl/ltxmarkup.perl
===================================================================
--- vendor/Python/current/Doc/perl/ltxmarkup.perl	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/perl/ltxmarkup.perl	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,67 @@
+# LaTeX2HTML support for the ltxmarkup package.  Doesn't do indexing.
+
+package main;
+
+
+sub ltx_next_argument{
+    my $param;
+    $param = missing_braces()
+      unless ((s/$next_pair_pr_rx/$param=$2;''/eo)
+	      ||(s/$next_pair_rx/$param=$2;''/eo));
+    return $param;
+}
+
+
+sub do_cmd_macro{
+    local($_) = @_;
+    my $macro = ltx_next_argument();
+    return "<tt class='macro'>&#92;$macro</tt>" . $_;
+}
+
+sub do_cmd_env{
+    local($_) = @_;
+    my $env = ltx_next_argument();
+    return "<tt class='environment'>&#92;$env</tt>" . $_;
+}
+
+sub ltx_process_params{
+    # Handle processing of \p and \op for parameter specifications for
+    # envdesc and macrodesc.  It's done this way to avoid defining do_cmd_p()
+    # and do_cmd_op() functions, which would be interpreted outside the context
+    # in which these commands are legal, and cause LaTeX2HTML to think they're
+    # defined.  This way, other uses of \p and \op are properly flagged as
+    # unknown macros.
+    my $s = @_[0];
+    $s =~ s%\\op<<(\d+)>>(.+)<<\1>>%<tt>[</tt><var>$2</var><tt>]</tt>%;
+    while ($s =~ /\\p<<(\d+)>>(.+)<<\1>>/) {
+	$s =~ s%\\p<<(\d+)>>(.+)<<\1>>%<tt>{</tt><var>$2</var><tt>}</tt>%;
+    }
+    return $s;
+}
+
+sub do_env_macrodesc{
+    local($_) = @_;
+    my $macro = ltx_next_argument();
+    my $params = ltx_process_params(ltx_next_argument());
+    return "\n<dl class='macrodesc'>"
+         . "\n<dt><b><tt class='macro'>&#92;$macro</tt></b>"
+         . "\n    $params</dt>"
+	 . "\n<dd>"
+	 . $_
+	 . '</dd></dl>';
+}
+
+sub do_env_envdesc{
+    local($_) = @_;
+    my $env = ltx_next_argument();
+    my $params = ltx_process_params(ltx_next_argument());
+    return "\n<dl class='envdesc'>"
+         . "\n<dt><tt>&#92;begin{<b class='environment'>$env</b>}</tt>"
+         . "\n    $params"
+         . "\n<br /><tt>&#92;end{<b class='environment'>$env</b>}</tt></dt>"
+	 . "\n<dd>"
+	 . $_
+	 . '</dd></dl>';
+}
+
+1;				# Must end with this, because Perl is bogus.

Added: vendor/Python/current/Doc/perl/manual.perl
===================================================================
--- vendor/Python/current/Doc/perl/manual.perl	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/perl/manual.perl	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,15 @@
+# -*- perl -*-
+#
+# This implements the Python manual class.  All it really needs to do it
+# load the "python" style.  The style code is not moved into the class code
+# at this time, since we expect additional document class to be developed
+# for the Python documentation in the future.  Appropriate relocations will
+# be made at that time.
+
+package main;
+
+do_require_package("report");
+do_require_package("alltt");
+do_require_package("python");
+
+1;				# sheesh....

Added: vendor/Python/current/Doc/perl/python.perl
===================================================================
--- vendor/Python/current/Doc/perl/python.perl	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/perl/python.perl	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2172 @@
+# python.perl by Fred L. Drake, Jr. <fdrake at acm.org>            -*- perl -*-
+#
+# Heavily based on Guido van Rossum's myformat.perl (now obsolete).
+#
+# Extension to LaTeX2HTML for documents using myformat.sty.
+# Subroutines of the form do_cmd_<name> here define translations
+# for LaTeX commands \<name> defined in the corresponding .sty file.
+
+package main;
+
+use warnings;
+use File::Basename;
+
+
+sub next_argument{
+    my $param;
+    $param = missing_braces()
+      unless ((s/$next_pair_pr_rx/$param=$2;''/eo)
+              ||(s/$next_pair_rx/$param=$2;''/eo));
+    return $param;
+}
+
+sub next_optional_argument{
+    my($param, $rx) = ('', "^\\s*(\\[([^]]*)\\])?");
+    s/$rx/$param=$2;''/eo;
+    return $param;
+}
+
+sub make_icon_filename($){
+    my($myname, $mydir, $myext) = fileparse($_[0], '\..*');
+    chop $mydir;
+    if ($mydir eq '.') {
+        $mydir = $ICONSERVER;
+    }
+    $myext = ".$IMAGE_TYPE"
+      unless $myext;
+    return "$mydir$dd$myname$myext";
+}
+
+sub get_link_icon($){
+    my $url = $_[0];
+    if ($OFF_SITE_LINK_ICON && ($url =~ /^[-a-zA-Z0-9.]+:/)) {
+        # absolute URL; assume it points off-site
+        my $icon = make_icon_filename($OFF_SITE_LINK_ICON);
+        return (" <img src=\"$icon\"\n"
+                . '  border="0" class="offsitelink"'
+                . ($OFF_SITE_LINK_ICON_HEIGHT
+                   ? " height=\"$OFF_SITE_LINK_ICON_HEIGHT\""
+                   : '')
+                . ($OFF_SITE_LINK_ICON_WIDTH
+                   ? " width=\"$OFF_SITE_LINK_ICON_WIDTH\""
+                   : '')
+                . " alt=\"[off-site link]\"\n"
+                . "  />");
+    }
+    return '';
+}
+
+# This is a fairly simple hack; it supports \let when it is used to create
+# (or redefine) a macro to exactly be some other macro: \let\newname=\oldname.
+# Many possible uses of \let aren't supported or aren't supported correctly.
+#
+sub do_cmd_let{
+    local($_) = @_;
+    my $matched = 0;
+    s/[\\]([a-zA-Z]+)\s*(=\s*)?[\\]([a-zA-Z]*)/$matched=1; ''/e;
+    if ($matched) {
+        my($new, $old) = ($1, $3);
+        eval "sub do_cmd_$new { do_cmd_$old" . '(@_); }';
+        print "\ndefining handler for \\$new using \\$old\n";
+    }
+    else {
+        s/[\\]([a-zA-Z]+)\s*(=\s*)?([^\\])/$matched=1; ''/es;
+        if ($matched) {
+            my($new, $char) = ($1, $3);
+            eval "sub do_cmd_$new { \"\\$char\" . \$_[0]; }";
+            print "\ndefining handler for \\$new to insert '$char'\n";
+        }
+        else {
+            write_warnings("Could not interpret \\let construct...");
+        }
+    }
+    return $_;
+}
+
+
+# the older version of LaTeX2HTML we use doesn't support this, but we use it:
+
+sub do_cmd_textasciitilde{ '&#126;' . $_[0]; }
+sub do_cmd_textasciicircum{ '^' . $_[0]; }
+sub do_cmd_textbar{ '|' . $_[0]; }
+sub do_cmd_texteuro { '&#8364;' . $_[0]; }
+sub do_cmd_textgreater{ '&gt;' . $_[0]; }
+sub do_cmd_textless{ '&lt;' . $_[0]; }
+sub do_cmd_textunderscore{ '_' . $_[0]; }
+sub do_cmd_infinity{ '&infin;' . $_[0]; }
+sub do_cmd_plusminus{ '&plusmn;' . $_[0]; }
+sub do_cmd_guilabel{
+    return use_wrappers($_[0]. '<span class="guilabel">', '</span>'); }
+sub do_cmd_menuselection{
+    return use_wrappers($_[0], '<span class="guilabel">', '</span>'); }
+sub do_cmd_sub{
+    return '</span> &gt; <span class="guilabel">' . $_[0]; }
+
+
+# words typeset in a special way (not in HTML though)
+
+sub do_cmd_ABC{ 'ABC' . $_[0]; }
+sub do_cmd_UNIX{ '<span class="Unix">Unix</span>' . $_[0]; }
+sub do_cmd_LaTeX{ '<span class="LaTeX">LaTeX</span>' . $_[0]; }
+sub do_cmd_TeX{ '<span class="TeX">TeX</span>' . $_[0]; }
+sub do_cmd_ASCII{ 'ASCII' . $_[0]; }
+sub do_cmd_POSIX{ 'POSIX' . $_[0]; }
+sub do_cmd_C{ 'C' . $_[0]; }
+sub do_cmd_Cpp{ 'C++' . $_[0]; }
+sub do_cmd_EOF{ 'EOF' . $_[0]; }
+sub do_cmd_NULL{ '<tt class="constant">NULL</tt>' . $_[0]; }
+
+sub do_cmd_e{ '&#92;' . $_[0]; }
+
+$DEVELOPER_ADDRESS = '';
+$SHORT_VERSION = '';
+$RELEASE_INFO = '';
+$PACKAGE_VERSION = '';
+
+sub do_cmd_version{ $PACKAGE_VERSION . $_[0]; }
+sub do_cmd_shortversion{ $SHORT_VERSION . $_[0]; }
+sub do_cmd_release{
+    local($_) = @_;
+    $PACKAGE_VERSION = next_argument();
+    return $_;
+}
+
+sub do_cmd_setreleaseinfo{
+    local($_) = @_;
+    $RELEASE_INFO = next_argument();
+    return $_;
+}
+
+sub do_cmd_setshortversion{
+    local($_) = @_;
+    $SHORT_VERSION = next_argument();
+    return $_;
+}
+
+sub do_cmd_authoraddress{
+    local($_) = @_;
+    $DEVELOPER_ADDRESS = next_argument();
+    return $_;
+}
+
+sub do_cmd_hackscore{
+    local($_) = @_;
+    next_argument();
+    return '_' . $_;
+}
+
+# Helper used in many places that arbitrary code-like text appears:
+
+sub codetext($){
+    my $text = "$_[0]";
+    # Make sure that "---" is not converted to "--" later when
+    # LaTeX2HTML tries converting em-dashes based on the conventional
+    # TeX font ligatures:
+    $text =~ s/--/-\&#45;/go;
+    return $text;
+}
+
+sub use_wrappers($$$){
+    local($_,$before,$after) = @_;
+    my $stuff = next_argument();
+    return $before . $stuff . $after . $_;
+}
+
+sub use_code_wrappers($$$){
+    local($_,$before,$after) = @_;
+    my $stuff = codetext(next_argument());
+    return $before . $stuff . $after . $_;
+}
+
+$IN_DESC_HANDLER = 0;
+sub do_cmd_optional{
+    if ($IN_DESC_HANDLER) {
+        return use_wrappers($_[0], "</var><big>\[</big><var>",
+                            "</var><big>\]</big><var>");
+    }
+    else {
+        return use_wrappers($_[0], "<big>\[</big>", "<big>\]</big>");
+    }
+}
+
+# Logical formatting (some based on texinfo), needs to be converted to
+# minimalist HTML.  The "minimalist" is primarily to reduce the size of
+# output files for users that read them over the network rather than
+# from local repositories.
+
+sub do_cmd_pytype{ return $_[0]; }
+sub do_cmd_makevar{
+    return use_wrappers($_[0], '<span class="makevar">', '</span>'); }
+sub do_cmd_code{
+    return use_code_wrappers($_[0], '<code>', '</code>'); }
+sub do_cmd_module{
+    return use_wrappers($_[0], '<tt class="module">', '</tt>'); }
+sub do_cmd_keyword{
+    return use_wrappers($_[0], '<tt class="keyword">', '</tt>'); }
+sub do_cmd_exception{
+    return use_wrappers($_[0], '<tt class="exception">', '</tt>'); }
+sub do_cmd_class{
+    return use_wrappers($_[0], '<tt class="class">', '</tt>'); }
+sub do_cmd_function{
+    return use_wrappers($_[0], '<tt class="function">', '</tt>'); }
+sub do_cmd_constant{
+    return use_wrappers($_[0], '<tt class="constant">', '</tt>'); }
+sub do_cmd_member{
+    return use_wrappers($_[0], '<tt class="member">', '</tt>'); }
+sub do_cmd_method{
+    return use_wrappers($_[0], '<tt class="method">', '</tt>'); }
+sub do_cmd_cfunction{
+    return use_wrappers($_[0], '<tt class="cfunction">', '</tt>'); }
+sub do_cmd_cdata{
+    return use_wrappers($_[0], '<tt class="cdata">', '</tt>'); }
+sub do_cmd_ctype{
+    return use_wrappers($_[0], '<tt class="ctype">', '</tt>'); }
+sub do_cmd_regexp{
+    return use_code_wrappers($_[0], '<tt class="regexp">', '</tt>'); }
+sub do_cmd_character{
+    return use_code_wrappers($_[0], '"<tt class="character">', '</tt>"'); }
+sub do_cmd_program{
+    return use_wrappers($_[0], '<b class="program">', '</b>'); }
+sub do_cmd_programopt{
+    return use_wrappers($_[0], '<b class="programopt">', '</b>'); }
+sub do_cmd_longprogramopt{
+    # note that the --- will be later converted to -- by LaTeX2HTML
+    return use_wrappers($_[0], '<b class="programopt">---', '</b>'); }
+sub do_cmd_email{
+    return use_wrappers($_[0], '<span class="email">', '</span>'); }
+sub do_cmd_mailheader{
+    return use_wrappers($_[0], '<span class="mailheader">', ':</span>'); }
+sub do_cmd_mimetype{
+    return use_wrappers($_[0], '<span class="mimetype">', '</span>'); }
+sub do_cmd_var{
+    return use_wrappers($_[0], "<var>", "</var>"); }
+sub do_cmd_dfn{
+    return use_wrappers($_[0], '<i class="dfn">', '</i>'); }
+sub do_cmd_emph{
+    return use_wrappers($_[0], '<em>', '</em>'); }
+sub do_cmd_file{
+    return use_wrappers($_[0], '<span class="file">', '</span>'); }
+sub do_cmd_filenq{
+    return do_cmd_file($_[0]); }
+sub do_cmd_samp{
+    return use_code_wrappers($_[0], '"<tt class="samp">', '</tt>"'); }
+sub do_cmd_kbd{
+    return use_wrappers($_[0], '<kbd>', '</kbd>'); }
+sub do_cmd_strong{
+    return use_wrappers($_[0], '<strong>', '</strong>'); }
+sub do_cmd_textbf{
+    return use_wrappers($_[0], '<b>', '</b>'); }
+sub do_cmd_textit{
+    return use_wrappers($_[0], '<i>', '</i>'); }
+# This can be changed/overridden for translations:
+%NoticeNames = ('note' => 'Note:',
+                'warning' => 'Warning:',
+                );
+
+sub do_cmd_note{
+    my $label = $NoticeNames{'note'};
+    return use_wrappers(
+        $_[0],
+        "<span class=\"note\"><b class=\"label\">$label</b>\n",
+        '</span>'); }
+sub do_cmd_warning{
+    my $label = $NoticeNames{'warning'};
+    return use_wrappers(
+        $_[0],
+        "<span class=\"warning\"><b class=\"label\">$label</b>\n",
+        '</span>'); }
+
+sub do_env_notice{
+    local($_) = @_;
+    my $notice = next_optional_argument();
+    if (!$notice) {
+        $notice = 'note';
+    }
+    my $label = $NoticeNames{$notice};
+    return ("<div class=\"$notice\"><b class=\"label\">$label</b>\n"
+            . $_
+            . '</div>');
+}
+
+sub do_cmd_moreargs{
+    return '...' . $_[0]; }
+sub do_cmd_unspecified{
+    return '...' . $_[0]; }
+
+
+sub do_cmd_refmodule{
+    # Insert the right magic to jump to the module definition.
+    local($_) = @_;
+    my $key = next_optional_argument();
+    my $module = next_argument();
+    $key = $module
+        unless $key;
+    return "<tt class=\"module\"><a href=\"module-$key.html\">$module</a></tt>"
+      . $_;
+}
+
+sub do_cmd_newsgroup{
+    local($_) = @_;
+    my $newsgroup = next_argument();
+    my $icon = get_link_icon("news:$newsgroup");
+    my $stuff = ("<a class=\"newsgroup\" href=\"news:$newsgroup\">"
+                 . "$newsgroup$icon</a>");
+    return $stuff . $_;
+}
+
+sub do_cmd_envvar{
+    local($_) = @_;
+    my $envvar = next_argument();
+    my($name, $aname, $ahref) = new_link_info();
+    # The <tt> here is really to keep buildindex.py from making
+    # the variable name case-insensitive.
+    add_index_entry("environment variables!$envvar@<tt>$envvar</tt>",
+                    $ahref);
+    add_index_entry("$envvar (environment variable)", $ahref);
+    $aname =~ s/<a/<a class="envvar"/;
+    return "$aname$envvar</a>" . $_;
+}
+
+sub do_cmd_url{
+    # use the URL as both text and hyperlink
+    local($_) = @_;
+    my $url = next_argument();
+    my $icon = get_link_icon($url);
+    $url =~ s/~/&#126;/g;
+    return "<a class=\"url\" href=\"$url\">$url$icon</a>" . $_;
+}
+
+sub do_cmd_manpage{
+    # two parameters:  \manpage{name}{section}
+    local($_) = @_;
+    my $page = next_argument();
+    my $section = next_argument();
+    return "<span class=\"manpage\"><i>$page</i>($section)</span>" . $_;
+}
+
+$PEP_FORMAT = "http://www.python.org/peps/pep-%04d.html";
+#$RFC_FORMAT = "http://www.ietf.org/rfc/rfc%04d.txt";
+$RFC_FORMAT = "http://www.faqs.org/rfcs/rfc%d.html";
+
+sub get_rfc_url($$){
+    my($rfcnum, $format) = @_;
+    return sprintf($format, $rfcnum);
+}
+
+sub do_cmd_pep{
+    local($_) = @_;
+    my $rfcnumber = next_argument();
+    my $id = "rfcref-" . ++$global{'max_id'};
+    my $href = get_rfc_url($rfcnumber, $PEP_FORMAT);
+    my $icon = get_link_icon($href);
+    # Save the reference
+    my $nstr = gen_index_id("Python Enhancement Proposals!PEP $rfcnumber", '');
+    $index{$nstr} .= make_half_href("$CURRENT_FILE#$id");
+    return ("<a class=\"rfc\" id='$id' xml:id='$id'\n"
+            . "href=\"$href\">PEP $rfcnumber$icon</a>" . $_);
+}
+
+sub do_cmd_rfc{
+    local($_) = @_;
+    my $rfcnumber = next_argument();
+    my $id = "rfcref-" . ++$global{'max_id'};
+    my $href = get_rfc_url($rfcnumber, $RFC_FORMAT);
+    my $icon = get_link_icon($href);
+    # Save the reference
+    my $nstr = gen_index_id("RFC!RFC $rfcnumber", '');
+    $index{$nstr} .= make_half_href("$CURRENT_FILE#$id");
+    return ("<a class=\"rfc\" id='$id' xml:id='$id'\nhref=\"$href\">"
+            . "RFC $rfcnumber$icon</a>" . $_);
+}
+
+sub do_cmd_ulink{
+    local($_) = @_;
+    my $text = next_argument();
+    my $url = next_argument();
+    return "<a class=\"ulink\" href=\"$url\"\n  >$text</a>" . $_;
+}
+
+sub do_cmd_citetitle{
+    local($_) = @_;
+    my $url = next_optional_argument();
+    my $title = next_argument();
+    my $icon = get_link_icon($url);
+    my $repl = '';
+    if ($url) {
+        my $titletext = strip_html_markup("$title");
+        $repl = ("<em class=\"citetitle\"><a\n"
+                 . " href=\"$url\"\n"
+                 . " title=\"$titletext\"\n"
+                 . " >$title$icon</a></em>");
+    }
+    else {
+        $repl = "<em class=\"citetitle\"\n >$title</em>";
+    }
+    return $repl . $_;
+}
+
+sub do_cmd_deprecated{
+    # two parameters:  \deprecated{version}{whattodo}
+    local($_) = @_;
+    my $release = next_argument();
+    my $reason = next_argument();
+    return ('<div class="versionnote">'
+            . "<b>Deprecated since release $release.</b>"
+            . "\n$reason</div><p></p>"
+            . $_);
+}
+
+sub versionnote($$){
+    # one or two parameters:  \versionnote[explanation]{version}
+    my $type = $_[0];
+    local $_ = $_[1];
+    my $explanation = next_optional_argument();
+    my $release = next_argument();
+    my $text = "$type in version $release.";
+    if ($explanation) {
+        $text = "$type in version $release:\n$explanation.";
+    }
+    return "\n<span class=\"versionnote\">$text</span>\n" . $_;
+}
+
+sub do_cmd_versionadded{
+    return versionnote('New', $_[0]);
+}
+
+sub do_cmd_versionchanged{
+    return versionnote('Changed', $_[0]);
+}
+
+#
+# These function handle platform dependency tracking.
+#
+sub do_cmd_platform{
+    local($_) = @_;
+    my $platform = next_argument();
+    $ModulePlatforms{"<tt class=\"module\">$THIS_MODULE</tt>"} = $platform;
+    $platform = "Macintosh"
+      if $platform eq 'Mac';
+    return "\n<p class=\"availability\">Availability: <span"
+      . "\n class=\"platform\">$platform</span>.</p>\n" . $_;
+}
+
+$IGNORE_PLATFORM_ANNOTATION = '';
+sub do_cmd_ignorePlatformAnnotation{
+    local($_) = @_;
+    $IGNORE_PLATFORM_ANNOTATION = next_argument();
+    return $_;
+}
+
+
+# index commands
+
+$INDEX_SUBITEM = "";
+
+sub get_indexsubitem(){
+    return $INDEX_SUBITEM ? " $INDEX_SUBITEM" : '';
+}
+
+sub do_cmd_setindexsubitem{
+    local($_) = @_;
+    $INDEX_SUBITEM = next_argument();
+    return $_;
+}
+
+sub do_cmd_withsubitem{
+    # We can't really do the right thing, because LaTeX2HTML doesn't
+    # do things in the right order, but we need to at least strip this stuff
+    # out, and leave anything that the second argument expanded out to.
+    #
+    local($_) = @_;
+    my $oldsubitem = $INDEX_SUBITEM;
+    $INDEX_SUBITEM = next_argument();
+    my $stuff = next_argument();
+    my $br_id = ++$globals{'max_id'};
+    my $marker = "$O$br_id$C";
+    $stuff =~ s/^\s+//;
+    return
+      $stuff
+      . "\\setindexsubitem$marker$oldsubitem$marker"
+      . $_;
+}
+
+# This is the prologue macro which is required to start writing the
+# mod\jobname.idx file; we can just ignore it.  (Defining this suppresses
+# a warning that \makemodindex is unknown.)
+#
+sub do_cmd_makemodindex{ return $_[0]; }
+
+# We're in the document subdirectory when this happens!
+#
+open(IDXFILE, '>index.dat') || die "\n$!\n";
+open(INTLABELS, '>intlabels.pl') || die "\n$!\n";
+print INTLABELS "%internal_labels = ();\n";
+print INTLABELS "1;             # hack in case there are no entries\n\n";
+
+# Using \0 for this is bad because we can't use common tools to work with the
+# resulting files.  Things like grep can be useful with this stuff!
+#
+$IDXFILE_FIELD_SEP = "\1";
+
+sub write_idxfile($$){
+    my($ahref, $str) = @_;
+    print IDXFILE $ahref, $IDXFILE_FIELD_SEP, $str, "\n";
+}
+
+
+sub gen_link($$){
+    my($node, $target) = @_;
+    print INTLABELS "\$internal_labels{\"$target\"} = \"/$node\";\n";
+    return "<a href=\"$node#$target\">";
+}
+
+sub add_index_entry($$){
+    # add an entry to the index structures; ignore the return value
+    my($str, $ahref) = @_;
+    $str = gen_index_id($str, '');
+    $index{$str} .= $ahref;
+    write_idxfile($ahref, $str);
+}
+
+sub new_link_name_info(){
+    my $name = "l2h-" . ++$globals{'max_id'};
+    my $ahref = gen_link($CURRENT_FILE, $name);
+    return ($name, $ahref);
+}
+
+sub new_link_info(){
+    my($name, $ahref) = new_link_name_info();
+    my $aname = "<a id='$name' xml:id='$name'>";
+    return ($name, $aname, $ahref);
+}
+
+$IndexMacroPattern = '';
+sub define_indexing_macro(@){
+    my $count = @_;
+    my $i = 0;
+    for (; $i < $count; ++$i) {
+        my $name = $_[$i];
+        my $cmd = "idx_cmd_$name";
+        die "\nNo function $cmd() defined!\n"
+          if (!defined &$cmd);
+        eval ("sub do_cmd_$name { return process_index_macros("
+              . "\$_[0], '$name'); }");
+        if (length($IndexMacroPattern) == 0) {
+            $IndexMacroPattern = "$name";
+        }
+        else {
+            $IndexMacroPattern .= "|$name";
+        }
+    }
+}
+
+$DEBUG_INDEXING = 0;
+sub process_index_macros($$){
+    local($_) = @_;
+    my $cmdname = $_[1];        # This is what triggered us in the first place;
+                                # we know it's real, so just process it.
+    my($name, $aname, $ahref) = new_link_info();
+    my $cmd = "idx_cmd_$cmdname";
+    print "\nIndexing: \\$cmdname"
+      if $DEBUG_INDEXING;
+    &$cmd($ahref);              # modifies $_ and adds index entries
+    while (/^[\s\n]*\\($IndexMacroPattern)</) {
+        $cmdname = "$1";
+        print " \\$cmdname"
+          if $DEBUG_INDEXING;
+        $cmd = "idx_cmd_$cmdname";
+        if (!defined &$cmd) {
+            last;
+        }
+        else {
+            s/^[\s\n]*\\$cmdname//;
+            &$cmd($ahref);
+        }
+    }
+# XXX I don't remember why I added this to begin with.
+#     if (/^[ \t\r\n]/) {
+#         $_ = substr($_, 1);
+#     }
+    return "$aname$anchor_invisible_mark</a>" . $_;
+}
+
+define_indexing_macro('index');
+sub idx_cmd_index($){
+    my $str = next_argument();
+    add_index_entry("$str", $_[0]);
+}
+
+define_indexing_macro('kwindex');
+sub idx_cmd_kwindex($){
+    my $str = next_argument();
+    add_index_entry("<tt>$str</tt>!keyword", $_[0]);
+    add_index_entry("keyword!<tt>$str</tt>", $_[0]);
+}
+
+define_indexing_macro('indexii');
+sub idx_cmd_indexii($){
+    my $str1 = next_argument();
+    my $str2 = next_argument();
+    add_index_entry("$str1!$str2", $_[0]);
+    add_index_entry("$str2!$str1", $_[0]);
+}
+
+define_indexing_macro('indexiii');
+sub idx_cmd_indexiii($){
+    my $str1 = next_argument();
+    my $str2 = next_argument();
+    my $str3 = next_argument();
+    add_index_entry("$str1!$str2 $str3", $_[0]);
+    add_index_entry("$str2!$str3, $str1", $_[0]);
+    add_index_entry("$str3!$str1 $str2", $_[0]);
+}
+
+define_indexing_macro('indexiv');
+sub idx_cmd_indexiv($){
+    my $str1 = next_argument();
+    my $str2 = next_argument();
+    my $str3 = next_argument();
+    my $str4 = next_argument();
+    add_index_entry("$str1!$str2 $str3 $str4", $_[0]);
+    add_index_entry("$str2!$str3 $str4, $str1", $_[0]);
+    add_index_entry("$str3!$str4, $str1 $str2", $_[0]);
+    add_index_entry("$str4!$str1 $str2 $str3", $_[0]);
+}
+
+define_indexing_macro('ttindex');
+sub idx_cmd_ttindex($){
+    my $str = codetext(next_argument());
+    my $entry = $str . get_indexsubitem();
+    add_index_entry($entry, $_[0]);
+}
+
+sub my_typed_index_helper($$){
+    my($word, $ahref) = @_;
+    my $str = next_argument();
+    add_index_entry("$str $word", $ahref);
+    add_index_entry("$word!$str", $ahref);
+}
+
+define_indexing_macro('stindex', 'opindex', 'exindex', 'obindex');
+sub idx_cmd_stindex($){ my_typed_index_helper('statement', $_[0]); }
+sub idx_cmd_opindex($){ my_typed_index_helper('operator', $_[0]); }
+sub idx_cmd_exindex($){ my_typed_index_helper('exception', $_[0]); }
+sub idx_cmd_obindex($){ my_typed_index_helper('object', $_[0]); }
+
+define_indexing_macro('bifuncindex');
+sub idx_cmd_bifuncindex($){
+    my $str = next_argument();
+    add_index_entry("<tt class=\"function\">$str()</tt> (built-in function)",
+                    $_[0]);
+}
+
+
+sub make_mod_index_entry($$){
+    my($str, $define) = @_;
+    my($name, $aname, $ahref) = new_link_info();
+    # equivalent of add_index_entry() using $define instead of ''
+    $ahref =~ s/\#[-_a-zA-Z0-9]*\"/\"/
+      if ($define eq 'DEF');
+    $str = gen_index_id($str, $define);
+    $index{$str} .= $ahref;
+    write_idxfile($ahref, $str);
+
+    if ($define eq 'DEF') {
+        # add to the module index
+        $str =~ /(<tt.*<\/tt>)/;
+        my $nstr = $1;
+        $Modules{$nstr} .= $ahref;
+    }
+    return "$aname$anchor_invisible_mark2</a>";
+}
+
+
+$THIS_MODULE = '';
+$THIS_CLASS = '';
+
+sub define_module($$){
+    my($word, $name) = @_;
+    my $section_tag = join('', @curr_sec_id);
+    if ($word ne "built-in" && $word ne "extension"
+        && $word ne "standard" && $word ne "") {
+        write_warnings("Bad module type '$word'"
+                       . " for \\declaremodule (module $name)");
+        $word = "";
+    }
+    $word = "$word " if $word;
+    $THIS_MODULE = "$name";
+    $INDEX_SUBITEM = "(in module $name)";
+    print "[$name]";
+    return make_mod_index_entry(
+        "<tt class=\"module\">$name</tt> (${word}module)", 'DEF');
+}
+
+sub my_module_index_helper($$){
+    local($word, $_) = @_;
+    my $name = next_argument();
+    return define_module($word, $name) . $_;
+}
+
+sub do_cmd_modindex{ return my_module_index_helper('', $_[0]); }
+sub do_cmd_bimodindex{ return my_module_index_helper('built-in', $_[0]); }
+sub do_cmd_exmodindex{ return my_module_index_helper('extension', $_[0]); }
+sub do_cmd_stmodindex{ return my_module_index_helper('standard', $_[0]); }
+#     local($_) = @_;
+#     my $name = next_argument();
+#     return define_module('standard', $name) . $_;
+# }
+
+sub ref_module_index_helper($$){
+    my($word, $ahref) = @_;
+    my $str = next_argument();
+    $word = "$word " if $word;
+    $str = "<tt class=\"module\">$str</tt> (${word}module)";
+    # can't use add_index_entry() since the 2nd arg to gen_index_id() is used;
+    # just inline it all here
+    $str = gen_index_id($str, 'REF');
+    $index{$str} .= $ahref;
+    write_idxfile($ahref, $str);
+}
+
+# these should be adjusted a bit....
+define_indexing_macro('refmodindex', 'refbimodindex',
+                      'refexmodindex', 'refstmodindex');
+sub idx_cmd_refmodindex($){
+    return ref_module_index_helper('', $_[0]); }
+sub idx_cmd_refbimodindex($){
+    return ref_module_index_helper('built-in', $_[0]); }
+sub idx_cmd_refexmodindex($){
+    return ref_module_index_helper('extension', $_[0]);}
+sub idx_cmd_refstmodindex($){
+    return ref_module_index_helper('standard', $_[0]); }
+
+sub do_cmd_nodename{ return do_cmd_label($_[0]); }
+
+sub init_myformat(){
+    # This depends on the override of text_cleanup() in l2hinit.perl;
+    # if that function cleans out empty tags, the first three of these
+    # variables must be set to comments.
+    #
+    # Thanks to Dave Kuhlman for figuring why some named anchors were
+    # being lost.
+    $anchor_invisible_mark = '';
+    $anchor_invisible_mark2 = '';
+    $anchor_mark = '';
+    $icons{'anchor_mark'} = '';
+}
+init_myformat();
+
+# Create an index entry, but include the string in the target anchor
+# instead of the dummy filler.
+#
+sub make_str_index_entry($){
+    my $str = $_[0];
+    my($name, $ahref) = new_link_name_info();
+    add_index_entry($str, $ahref);
+    if ($str =~ /^<[a-z]+\b/) {
+        my $s = "$str";
+        $s =~ s/^<([a-z]+)\b/<$1 id='$name' xml:id='$name'/;
+        return $s;
+    }
+    else {
+        return "<a id='$name' xml:id='$name'>$str</a>";
+    }
+}
+
+
+%TokenToTargetMapping = ();     # language:token -> link target
+%DefinedGrammars = ();          # language -> full grammar text
+%BackpatchGrammarFiles = ();    # file -> 1 (hash of files to fixup)
+
+sub do_cmd_token{
+    local($_) = @_;
+    my $token = next_argument();
+    my $target = $TokenToTargetMapping{"$CURRENT_GRAMMAR:$token"};
+    if ($token eq $CURRENT_TOKEN || $CURRENT_GRAMMAR eq '*') {
+        # recursive definition or display-only productionlist
+        return "$token";
+    }
+    if ($target eq '') {
+        $target = "<pyGrammarToken><$CURRENT_GRAMMAR><$token>";
+        if (! $BackpatchGrammarFiles{"$CURRENT_FILE"}) {
+            print "Adding '$CURRENT_FILE' to back-patch list.\n";
+        }
+        $BackpatchGrammarFiles{"$CURRENT_FILE"} = 1;
+    }
+    return "<a class='grammartoken' href=\"$target\">$token</a>" . $_;
+}
+
+sub do_cmd_grammartoken{
+    return do_cmd_token(@_);
+}
+
+sub do_env_productionlist{
+    local($_) = @_;
+    my $lang = next_optional_argument();
+    my $filename = "grammar-$lang.txt";
+    if ($lang eq '') {
+        $filename = 'grammar.txt';
+    }
+    local($CURRENT_GRAMMAR) = $lang;
+    $DefinedGrammars{$lang} .= $_;
+    return ("<dl><dd class=\"grammar\">\n"
+            . "<div class=\"productions\">\n"
+            . "<table>\n"
+            . translate_commands(translate_environments($_))
+            . "</table>\n"
+            . "</div>\n"
+            . (($lang eq '*')
+               ? ''
+               : ("<a class=\"grammar-footer\"\n"
+                  . "  href=\"$filename\" type=\"text/plain\"\n"
+                  . "  >Download entire grammar as text.</a>\n"))
+            . "</dd></dl>");
+}
+
+sub do_cmd_production{
+    local($_) = @_;
+    my $token = next_argument();
+    my $defn = next_argument();
+    my $lang = $CURRENT_GRAMMAR;
+    local($CURRENT_TOKEN) = $token;
+    if ($lang eq '*') {
+        return ("<tr>\n"
+                . "    <td>$token</td>\n"
+                . "    <td>::=</td>\n"
+                . "    <td>"
+                . translate_commands($defn)
+                . "</td></tr>"
+                . $_);
+    }
+    my $target;
+    if ($lang eq '') {
+        $target = "$CURRENT_FILE\#tok-$token";
+    }
+    else {
+        $target = "$CURRENT_FILE\#tok-$lang-$token";
+    }
+    $TokenToTargetMapping{"$CURRENT_GRAMMAR:$token"} = $target;
+    return ("<tr>\n"
+            . "    <td><a id='tok-$token' xml:id='tok-$token'>"
+            . "$token</a></td>\n"
+            . "    <td>::=</td>\n"
+            . "    <td>"
+            . translate_commands($defn)
+            . "</td></tr>"
+            . $_);
+}
+
+sub do_cmd_productioncont{
+    local($_) = @_;
+    my $defn = next_argument();
+    $defn =~ s/^( +)/'&nbsp;' x length $1/e;
+    return ("<tr>\n"
+            . "    <td></td>\n"
+            . "    <td></td>\n"
+            . "    <td><code>"
+            . translate_commands($defn)
+            . "</code></td></tr>"
+            . $_);
+}
+
+sub process_grammar_files(){
+    my $lang;
+    my $filename;
+    local($_);
+    print "process_grammar_files()\n";
+    foreach $lang (keys %DefinedGrammars) {
+        $filename = "grammar-$lang.txt";
+        if ($lang eq '*') {
+            next;
+        }
+        if ($lang eq '') {
+            $filename = 'grammar.txt';
+        }
+        open(GRAMMAR, ">$filename") || die "\n$!\n";
+        print GRAMMAR strip_grammar_markup($DefinedGrammars{$lang});
+        close(GRAMMAR);
+        print "Wrote grammar file $filename\n";
+    }
+    my $PATTERN = '<pyGrammarToken><([^>]*)><([^>]*)>';
+    foreach $filename (keys %BackpatchGrammarFiles) {
+        print "\nBack-patching grammar links in $filename\n";
+        my $buffer;
+        open(GRAMMAR, "<$filename") || die "\n$!\n";
+        # read all of the file into the buffer
+        sysread(GRAMMAR, $buffer, 1024*1024);
+        close(GRAMMAR);
+        while ($buffer =~ /$PATTERN/) {
+            my($lang, $token) = ($1, $2);
+            my $target = $TokenToTargetMapping{"$lang:$token"};
+            my $source = "<pyGrammarToken><$lang><$token>";
+            $buffer =~ s/$source/$target/g;
+        }
+        open(GRAMMAR, ">$filename") || die "\n$!\n";
+        print GRAMMAR $buffer;
+        close(GRAMMAR);
+    }
+}
+
+sub strip_grammar_markup($){
+    local($_) = @_;
+    s/\\productioncont/              /g;
+    s/\\production(<<\d+>>)(.+)\1/\n$2 ::= /g;
+    s/\\token(<<\d+>>)(.+)\1/$2/g;
+    s/\\e([^a-zA-Z])/\\$1/g;
+    s/<<\d+>>//g;
+    s/;SPMgt;/>/g;
+    s/;SPMlt;/</g;
+    s/;SPMquot;/\"/g;
+    return $_;
+}
+
+
+$REFCOUNTS_LOADED = 0;
+
+sub load_refcounts(){
+    $REFCOUNTS_LOADED = 1;
+
+    my($myname, $mydir, $myext) = fileparse(__FILE__, '\..*');
+    chop $mydir;                        # remove trailing '/'
+    ($myname, $mydir, $myext) = fileparse($mydir, '\..*');
+    chop $mydir;                        # remove trailing '/'
+    $mydir = getcwd() . "$dd$mydir"
+      unless $mydir =~ s|^/|/|;
+    local $_;
+    my $filename = "$mydir${dd}api${dd}refcounts.dat";
+    open(REFCOUNT_FILE, "<$filename") || die "\n$!\n";
+    print "[loading API refcount data]";
+    while (<REFCOUNT_FILE>) {
+        if (/([a-zA-Z0-9_]+):PyObject\*:([a-zA-Z0-9_]*):(0|[-+]1|null):(.*)$/) {
+            my($func, $param, $count, $comment) = ($1, $2, $3, $4);
+            #print "\n$func($param) --> $count";
+            $REFCOUNTS{"$func:$param"} = $count;
+        }
+    }
+}
+
+sub get_refcount($$){
+    my($func, $param) = @_;
+    load_refcounts()
+        unless $REFCOUNTS_LOADED;
+    return $REFCOUNTS{"$func:$param"};
+}
+
+
+$TLSTART = '<span class="typelabel">';
+$TLEND   = '</span>&nbsp;';
+
+sub cfuncline_helper($$$){
+    my($type, $name, $args) = @_;
+    my $idx = make_str_index_entry(
+        "<tt class=\"cfunction\">$name()</tt>" . get_indexsubitem());
+    $idx =~ s/ \(.*\)//;
+    $idx =~ s/\(\)//;           # ???? - why both of these?
+    $args =~ s/(\s|\*)([a-z_][a-z_0-9]*),/$1<var>$2<\/var>,/g;
+    $args =~ s/(\s|\*)([a-z_][a-z_0-9]*)$/$1<var>$2<\/var>/s;
+    return ('<table cellpadding="0" cellspacing="0"><tr valign="baseline">'
+            . "<td><nobr>$type\&nbsp;<b>$idx</b>(</nobr></td>"
+            . "<td>$args)</td>"
+            . '</tr></table>');
+}
+sub do_cmd_cfuncline{
+    local($_) = @_;
+    my $type = next_argument();
+    my $name = next_argument();
+    my $args = next_argument();
+    my $siginfo = cfuncline_helper($type, $name, $args);
+    return "<dt>$siginfo\n<dd>" . $_;
+}
+sub do_env_cfuncdesc{
+    local($_) = @_;
+    my $type = next_argument();
+    my $name = next_argument();
+    my $args = next_argument();
+    my $siginfo = cfuncline_helper($type, $name, $args);
+    my $result_rc = get_refcount($name, '');
+    my $rcinfo = '';
+    if ($result_rc eq '+1') {
+        $rcinfo = 'New reference';
+    }
+    elsif ($result_rc eq '0') {
+        $rcinfo = 'Borrowed reference';
+    }
+    elsif ($result_rc eq 'null') {
+        $rcinfo = 'Always <tt class="constant">NULL</tt>';
+    }
+    if ($rcinfo ne '') {
+        $rcinfo = (  "\n<div class=\"refcount-info\">"
+                   . "\n  <span class=\"label\">Return value:</span>"
+                   . "\n  <span class=\"value\">$rcinfo.</span>"
+                   . "\n</div>");
+    }
+    return "<dl><dt>$siginfo</dt>\n<dd>"
+           . $rcinfo
+           . $_
+           . '</dd></dl>';
+}
+
+sub do_cmd_cmemberline{
+    local($_) = @_;
+    my $container = next_argument();
+    my $type = next_argument();
+    my $name = next_argument();
+    my $idx = make_str_index_entry("<tt class=\"cmember\">$name</tt>"
+                                   . " ($container member)");
+    $idx =~ s/ \(.*\)//;
+    return "<dt>$type <b>$idx</b></dt>\n<dd>"
+           . $_;
+}
+sub do_env_cmemberdesc{
+    local($_) = @_;
+    my $container = next_argument();
+    my $type = next_argument();
+    my $name = next_argument();
+    my $idx = make_str_index_entry("<tt class=\"cmember\">$name</tt>"
+                                   . " ($container member)");
+    $idx =~ s/ \(.*\)//;
+    return "<dl><dt>$type <b>$idx</b></dt>\n<dd>"
+           . $_
+           . '</dl>';
+}
+
+sub do_env_csimplemacrodesc{
+    local($_) = @_;
+    my $name = next_argument();
+    my $idx = make_str_index_entry("<tt class=\"macro\">$name</tt>");
+    return "<dl><dt><b>$idx</b></dt>\n<dd>"
+           . $_
+           . '</dl>'
+}
+
+sub do_env_ctypedesc{
+    local($_) = @_;
+    my $index_name = next_optional_argument();
+    my $type_name = next_argument();
+    $index_name = $type_name
+      unless $index_name;
+    my($name, $aname, $ahref) = new_link_info();
+    add_index_entry("<tt class=\"ctype\">$index_name</tt> (C type)", $ahref);
+    return "<dl><dt><b><tt class=\"ctype\">$aname$type_name</a></tt></b></dt>"
+           . "\n<dd>"
+           . $_
+           . '</dl>'
+}
+
+sub do_env_cvardesc{
+    local($_) = @_;
+    my $var_type = next_argument();
+    my $var_name = next_argument();
+    my $idx = make_str_index_entry("<tt class=\"cdata\">$var_name</tt>"
+                                   . get_indexsubitem());
+    $idx =~ s/ \(.*\)//;
+    return "<dl><dt>$var_type <b>$idx</b></dt>\n"
+           . '<dd>'
+           . $_
+           . '</dd></dl>';
+}
+
+sub convert_args($){
+    local($IN_DESC_HANDLER) = 1;
+    local($_) = @_;
+    return translate_commands($_);
+}
+
+sub funcline_helper($$$){
+    my($first, $idxitem, $arglist) = @_;
+    return (($first ? '<dl>' : '')
+            . '<dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">'
+            . "\n  <td><nobr><b>$idxitem</b>(</nobr></td>"
+            . "\n  <td><var>$arglist</var>)</td></tr></table></dt>\n<dd>");
+}
+
+sub do_env_funcdesc{
+    local($_) = @_;
+    my $function_name = next_argument();
+    my $arg_list = convert_args(next_argument());
+    my $idx = make_str_index_entry("<tt class=\"function\">$function_name()"
+                                   . '</tt>'
+                                   . get_indexsubitem());
+    $idx =~ s/ \(.*\)//;
+    $idx =~ s/\(\)<\/tt>/<\/tt>/;
+    return funcline_helper(1, $idx, $arg_list) . $_ . '</dl>';
+}
+
+sub do_env_funcdescni{
+    local($_) = @_;
+    my $function_name = next_argument();
+    my $arg_list = convert_args(next_argument());
+    my $prefix = "<tt class=\"function\">$function_name</tt>";
+    return funcline_helper(1, $prefix, $arg_list) . $_ . '</dl>';
+}
+
+sub do_cmd_funcline{
+    local($_) = @_;
+    my $function_name = next_argument();
+    my $arg_list = convert_args(next_argument());
+    my $prefix = "<tt class=\"function\">$function_name()</tt>";
+    my $idx = make_str_index_entry($prefix . get_indexsubitem());
+    $prefix =~ s/\(\)//;
+
+    return funcline_helper(0, $prefix, $arg_list) . $_;
+}
+
+sub do_cmd_funclineni{
+    local($_) = @_;
+    my $function_name = next_argument();
+    my $arg_list = convert_args(next_argument());
+    my $prefix = "<tt class=\"function\">$function_name</tt>";
+
+    return funcline_helper(0, $prefix, $arg_list) . $_;
+}
+
+# Change this flag to index the opcode entries.  I don't think it's very
+# useful to index them, since they're only presented to describe the dis
+# module.
+#
+$INDEX_OPCODES = 0;
+
+sub do_env_opcodedesc{
+    local($_) = @_;
+    my $opcode_name = next_argument();
+    my $arg_list = next_argument();
+    my $idx;
+    if ($INDEX_OPCODES) {
+        $idx = make_str_index_entry("<tt class=\"opcode\">$opcode_name</tt>"
+                                    . ' (byte code instruction)');
+        $idx =~ s/ \(byte code instruction\)//;
+    }
+    else {
+        $idx = "<tt class=\"opcode\">$opcode_name</tt>";
+    }
+    my $stuff = "<dl><dt><b>$idx</b>";
+    if ($arg_list) {
+        $stuff .= "&nbsp;&nbsp;&nbsp;&nbsp;<var>$arg_list</var>";
+    }
+    return $stuff . "</dt>\n<dd>" . $_ . '</dt></dl>';
+}
+
+sub do_env_datadesc{
+    local($_) = @_;
+    my $dataname = next_argument();
+    my $idx = make_str_index_entry("<tt>$dataname</tt>" . get_indexsubitem());
+    $idx =~ s/ \(.*\)//;
+    return "<dl><dt><b>$idx</b></dt>\n<dd>"
+           . $_
+           . '</dd></dl>';
+}
+
+sub do_env_datadescni{
+    local($_) = @_;
+    my $idx = next_argument();
+    if (! $STRING_INDEX_TT) {
+        $idx = "<tt>$idx</tt>";
+    }
+    return "<dl><dt><b>$idx</b></dt>\n<dd>" . $_ . '</dd></dl>';
+}
+
+sub do_cmd_dataline{
+    local($_) = @_;
+    my $data_name = next_argument();
+    my $idx = make_str_index_entry("<tt>$data_name</tt>" . get_indexsubitem());
+    $idx =~ s/ \(.*\)//;
+    return "<dt><b>$idx</b></dt><dd>" . $_;
+}
+
+sub do_cmd_datalineni{
+    local($_) = @_;
+    my $data_name = next_argument();
+    return "<dt><b><tt>$data_name</tt></b></dt><dd>" . $_;
+}
+
+sub do_env_excdesc{
+    local($_) = @_;
+    my $excname = next_argument();
+    my $idx = make_str_index_entry("<tt class=\"exception\">$excname</tt>");
+    return ("<dl><dt><b>${TLSTART}exception$TLEND$idx</b></dt>"
+            . "\n<dd>"
+            . $_
+            . '</dd></dl>');
+}
+
+sub do_env_fulllineitems{ return do_env_itemize(@_); }
+
+
+sub handle_classlike_descriptor($$){
+    local($_, $what) = @_;
+    $THIS_CLASS = next_argument();
+    my $arg_list = convert_args(next_argument());
+    $idx = make_str_index_entry(
+        "<tt class=\"$what\">$THIS_CLASS</tt> ($what in $THIS_MODULE)" );
+    $idx =~ s/ \(.*\)//;
+    my $prefix = "$TLSTART$what$TLEND$idx";
+    return funcline_helper(1, $prefix, $arg_list) . $_ . '</dl>';
+}
+
+sub do_env_classdesc{
+    return handle_classlike_descriptor($_[0], "class");
+}
+
+sub do_env_classdescstar{
+    local($_) = @_;
+    $THIS_CLASS = next_argument();
+    $idx = make_str_index_entry(
+        "<tt class=\"class\">$THIS_CLASS</tt> (class in $THIS_MODULE)");
+    $idx =~ s/ \(.*\)//;
+    my $prefix = "${TLSTART}class$TLEND$idx";
+    # Can't use funcline_helper() since there is no args list.
+    return "<dl><dt><b>$prefix</b>\n<dd>" . $_ . '</dl>';
+}
+
+sub do_env_excclassdesc{
+    return handle_classlike_descriptor($_[0], "exception");
+}
+
+
+sub do_env_methoddesc{
+    local($_) = @_;
+    my $class_name = next_optional_argument();
+    $class_name = $THIS_CLASS
+        unless $class_name;
+    my $method = next_argument();
+    my $arg_list = convert_args(next_argument());
+    my $extra = '';
+    if ($class_name) {
+        $extra = " ($class_name method)";
+    }
+    my $idx = make_str_index_entry(
+        "<tt class=\"method\">$method()</tt>$extra");
+    $idx =~ s/ \(.*\)//;
+    $idx =~ s/\(\)//;
+    return funcline_helper(1, $idx, $arg_list) . $_ . '</dl>';
+}
+
+
+sub do_cmd_methodline{
+    local($_) = @_;
+    my $class_name = next_optional_argument();
+    $class_name = $THIS_CLASS
+        unless $class_name;
+    my $method = next_argument();
+    my $arg_list = convert_args(next_argument());
+    my $extra = '';
+    if ($class_name) {
+        $extra = " ($class_name method)";
+    }
+    my $idx = make_str_index_entry(
+        "<tt class=\"method\">$method()</tt>$extra");
+    $idx =~ s/ \(.*\)//;
+    $idx =~ s/\(\)//;
+    return funcline_helper(0, $idx, $arg_list) . $_;
+}
+
+
+sub do_cmd_methodlineni{
+    local($_) = @_;
+    next_optional_argument();
+    my $method = next_argument();
+    my $arg_list = convert_args(next_argument());
+    return funcline_helper(0, $method, $arg_list) . $_;
+}
+
+sub do_env_methoddescni{
+    local($_) = @_;
+    next_optional_argument();
+    my $method = next_argument();
+    my $arg_list = convert_args(next_argument());
+    return funcline_helper(1, $method, $arg_list) . $_ . '</dl>';
+}
+
+
+sub do_env_memberdesc{
+    local($_) = @_;
+    my $class = next_optional_argument();
+    my $member = next_argument();
+    $class = $THIS_CLASS
+        unless $class;
+    my $extra = '';
+    $extra = " ($class attribute)"
+        if ($class ne '');
+    my $idx = make_str_index_entry("<tt class=\"member\">$member</tt>$extra");
+    $idx =~ s/ \(.*\)//;
+    $idx =~ s/\(\)//;
+    return "<dl><dt><b>$idx</b></dt>\n<dd>" . $_ . '</dl>';
+}
+
+
+sub do_cmd_memberline{
+    local($_) = @_;
+    my $class = next_optional_argument();
+    my $member = next_argument();
+    $class = $THIS_CLASS
+        unless $class;
+    my $extra = '';
+    $extra = " ($class attribute)"
+        if ($class ne '');
+    my $idx = make_str_index_entry("<tt class=\"member\">$member</tt>$extra");
+    $idx =~ s/ \(.*\)//;
+    $idx =~ s/\(\)//;
+    return "<dt><b>$idx</b></dt><dd>" . $_;
+}
+
+
+sub do_env_memberdescni{
+    local($_) = @_;
+    next_optional_argument();
+    my $member = next_argument();
+    return "<dl><dt><b><tt class=\"member\">$member</tt></b></dt>\n<dd>"
+           . $_
+           . '</dd></dl>';
+}
+
+
+sub do_cmd_memberlineni{
+    local($_) = @_;
+    next_optional_argument();
+    my $member = next_argument();
+    return "<dt><b><tt class=\"member\">$member</tt></b></dt>\n<dd>" . $_;
+}
+
+
+# For tables, we include a class on every cell to allow the CSS to set
+# the text-align property; this is because support for styling columns
+# via the <col> element appears nearly non-existant on even the latest
+# browsers (Mozilla 1.7 is stable at the time of this writing).
+# Hopefully this can be improved as browsers evolve.
+
+ at col_aligns = ('<td>', '<td>', '<td>', '<td>', '<td>');
+
+%FontConversions = ('cdata' => 'tt class="cdata"',
+                    'character' => 'tt class="character"',
+                    'class' => 'tt class="class"',
+                    'command' => 'code',
+                    'constant' => 'tt class="constant"',
+                    'exception' => 'tt class="exception"',
+                    'file' => 'tt class="file"',
+                    'filenq' => 'tt class="file"',
+                    'kbd' => 'kbd',
+                    'member' => 'tt class="member"',
+                    'programopt' => 'b',
+                    'textrm' => '',
+                    );
+
+sub fix_font($){
+    # do a little magic on a font name to get the right behavior in the first
+    # column of the output table
+    my $font = $_[0];
+    if (defined $FontConversions{$font}) {
+        $font = $FontConversions{$font};
+    }
+    return $font;
+}
+
+sub figure_column_alignment($){
+    my $a = $_[0];
+    if (!defined $a) {
+        return '';
+    }
+    my $mark = substr($a, 0, 1);
+    my $r = '';
+    if ($mark eq 'c')
+      { $r = ' class="center"'; }
+    elsif ($mark eq 'r')
+      { $r = ' class="right" '; }
+    elsif ($mark eq 'l')
+      { $r = ' class="left"  '; }
+    elsif ($mark eq 'p')
+      { $r = ' class="left"  '; }
+    return $r;
+}
+
+sub setup_column_alignments($){
+    local($_) = @_;
+    my($s1, $s2, $s3, $s4, $s5) = split(/[|]/,$_);
+    my $a1 = figure_column_alignment($s1);
+    my $a2 = figure_column_alignment($s2);
+    my $a3 = figure_column_alignment($s3);
+    my $a4 = figure_column_alignment($s4);
+    my $a5 = figure_column_alignment($s5);
+    $col_aligns[0] = "<td$a1 valign=\"baseline\">";
+    $col_aligns[1] = "<td$a2>";
+    $col_aligns[2] = "<td$a3>";
+    $col_aligns[3] = "<td$a4>";
+    $col_aligns[4] = "<td$a5>";
+    # return the aligned header start tags
+    return ("<th$a1>", "<th$a2>", "<th$a3>", "<th$a4>", "<th$a5>");
+}
+
+sub get_table_col1_fonts(){
+    my $font = $globals{'lineifont'};
+    my($sfont, $efont) = ('', '');
+    if ($font) {
+        $sfont = "<$font>";
+        $efont = "</$font>";
+        $efont =~ s/ .*>/>/;
+    }
+    return ($sfont, $efont);
+}
+
+sub do_env_tableii{
+    local($_) = @_;
+    my $arg = next_argument();
+    my($th1, $th2, $th3, $th4, $th5) = setup_column_alignments($arg);
+    my $font = fix_font(next_argument());
+    my $h1 = next_argument();
+    my $h2 = next_argument();
+    s/[\s\n]+//;
+    $globals{'lineifont'} = $font;
+    my $a1 = $col_aligns[0];
+    my $a2 = $col_aligns[1];
+    s/\\lineii</\\lineii[$a1|$a2]</g;
+    return '<div class="center"><table class="realtable">'
+           . "\n  <thead>"
+           . "\n    <tr>"
+           . "\n      $th1$h1</th>"
+           . "\n      $th2$h2</th>"
+           . "\n      </tr>"
+           . "\n    </thead>"
+           . "\n  <tbody>"
+           . $_
+           . "\n    </tbody>"
+           . "\n</table></div>";
+}
+
+sub do_env_longtableii{
+    return do_env_tableii(@_);
+}
+
+sub do_cmd_lineii{
+    local($_) = @_;
+    my $aligns = next_optional_argument();
+    my $c1 = next_argument();
+    my $c2 = next_argument();
+    s/[\s\n]+//;
+    my($sfont, $efont) = get_table_col1_fonts();
+    my($c1align, $c2align) = split('\|', $aligns);
+    return "\n    <tr>$c1align$sfont$c1$efont</td>\n"
+           . "        $c2align$c2</td></tr>"
+           . $_;
+}
+
+sub do_env_tableiii{
+    local($_) = @_;
+    my $arg = next_argument();
+    my($th1, $th2, $th3, $th4, $th5) = setup_column_alignments($arg);
+    my $font = fix_font(next_argument());
+    my $h1 = next_argument();
+    my $h2 = next_argument();
+    my $h3 = next_argument();
+    s/[\s\n]+//;
+    $globals{'lineifont'} = $font;
+    my $a1 = $col_aligns[0];
+    my $a2 = $col_aligns[1];
+    my $a3 = $col_aligns[2];
+    s/\\lineiii</\\lineiii[$a1|$a2|$a3]</g;
+    return '<div class="center"><table class="realtable">'
+           . "\n  <thead>"
+           . "\n    <tr>"
+           . "\n      $th1$h1</th>"
+           . "\n      $th2$h2</th>"
+           . "\n      $th3$h3</th>"
+           . "\n      </tr>"
+           . "\n    </thead>"
+           . "\n  <tbody>"
+           . $_
+           . "\n    </tbody>"
+           . "\n</table></div>";
+}
+
+sub do_env_longtableiii{
+    return do_env_tableiii(@_);
+}
+
+sub do_cmd_lineiii{
+    local($_) = @_;
+    my $aligns = next_optional_argument();
+    my $c1 = next_argument();
+    my $c2 = next_argument();
+    my $c3 = next_argument();
+    s/[\s\n]+//;
+    my($sfont, $efont) = get_table_col1_fonts();
+    my($c1align, $c2align, $c3align) = split('\|', $aligns);
+    return "\n    <tr>$c1align$sfont$c1$efont</td>\n"
+           . "        $c2align$c2</td>\n"
+           . "        $c3align$c3</td></tr>"
+           . $_;
+}
+
+sub do_env_tableiv{
+    local($_) = @_;
+    my $arg = next_argument();
+    my($th1, $th2, $th3, $th4, $th5) = setup_column_alignments($arg);
+    my $font = fix_font(next_argument());
+    my $h1 = next_argument();
+    my $h2 = next_argument();
+    my $h3 = next_argument();
+    my $h4 = next_argument();
+    s/[\s\n]+//;
+    $globals{'lineifont'} = $font;
+    my $a1 = $col_aligns[0];
+    my $a2 = $col_aligns[1];
+    my $a3 = $col_aligns[2];
+    my $a4 = $col_aligns[3];
+    s/\\lineiv</\\lineiv[$a1|$a2|$a3|$a4]</g;
+    return '<div class="center"><table class="realtable">'
+           . "\n  <thead>"
+           . "\n    <tr>"
+           . "\n      $th1$h1</th>"
+           . "\n      $th2$h2</th>"
+           . "\n      $th3$h3</th>"
+           . "\n      $th4$h4</th>"
+           . "\n      </tr>"
+           . "\n    </thead>"
+           . "\n  <tbody>"
+           . $_
+           . "\n    </tbody>"
+           . "\n</table></div>";
+}
+
+sub do_env_longtableiv{
+    return do_env_tableiv(@_);
+}
+
+sub do_cmd_lineiv{
+    local($_) = @_;
+    my $aligns = next_optional_argument();
+    my $c1 = next_argument();
+    my $c2 = next_argument();
+    my $c3 = next_argument();
+    my $c4 = next_argument();
+    s/[\s\n]+//;
+    my($sfont, $efont) = get_table_col1_fonts();
+    my($c1align, $c2align, $c3align, $c4align) = split('\|', $aligns);
+    return "\n    <tr>$c1align$sfont$c1$efont</td>\n"
+           . "        $c2align$c2</td>\n"
+           . "        $c3align$c3</td>\n"
+           . "        $c4align$c4</td></tr>"
+           . $_;
+}
+
+sub do_env_tablev{
+    local($_) = @_;
+    my $arg = next_argument();
+    my($th1, $th2, $th3, $th4, $th5) = setup_column_alignments($arg);
+    my $font = fix_font(next_argument());
+    my $h1 = next_argument();
+    my $h2 = next_argument();
+    my $h3 = next_argument();
+    my $h4 = next_argument();
+    my $h5 = next_argument();
+    s/[\s\n]+//;
+    $globals{'lineifont'} = $font;
+    my $a1 = $col_aligns[0];
+    my $a2 = $col_aligns[1];
+    my $a3 = $col_aligns[2];
+    my $a4 = $col_aligns[3];
+    my $a5 = $col_aligns[4];
+    s/\\linev</\\linev[$a1|$a2|$a3|$a4|$a5]</g;
+    return '<div class="center"><table class="realtable">'
+           . "\n  <thead>"
+           . "\n    <tr>"
+           . "\n      $th1$h1</th>"
+           . "\n      $th2$h2</th>"
+           . "\n      $th3$h3</th>"
+           . "\n      $th4$h4</th>"
+           . "\n      $th5$h5</th>"
+           . "\n      </tr>"
+           . "\n    </thead>"
+           . "\n  <tbody>"
+           . $_
+           . "\n    </tbody>"
+           . "\n</table></div>";
+}
+
+sub do_env_longtablev{
+    return do_env_tablev(@_);
+}
+
+sub do_cmd_linev{
+    local($_) = @_;
+    my $aligns = next_optional_argument();
+    my $c1 = next_argument();
+    my $c2 = next_argument();
+    my $c3 = next_argument();
+    my $c4 = next_argument();
+    my $c5 = next_argument();
+    s/[\s\n]+//;
+    my($sfont, $efont) = get_table_col1_fonts();
+    my($c1align, $c2align, $c3align, $c4align, $c5align) = split('\|',$aligns);
+    return "\n    <tr>$c1align$sfont$c1$efont</td>\n"
+           . "        $c2align$c2</td>\n"
+           . "        $c3align$c3</td>\n"
+           . "        $c4align$c4</td>\n"
+           . "        $c5align$c5</td></tr>"
+           . $_;
+}
+
+
+# These can be used to control the title page appearance;
+# they need a little bit of documentation.
+#
+# If $TITLE_PAGE_GRAPHIC is set, it should be the name of a file in the
+# $ICONSERVER directory, or include path information (other than "./").  The
+# default image type will be assumed if an extension is not provided.
+#
+# If specified, the "title page" will contain two colums: one containing the
+# title/author/etc., and the other containing the graphic.  Use the other
+# four variables listed here to control specific details of the layout; all
+# are optional.
+#
+# $TITLE_PAGE_GRAPHIC = "my-company-logo";
+# $TITLE_PAGE_GRAPHIC_COLWIDTH = "30%";
+# $TITLE_PAGE_GRAPHIC_WIDTH = 150;
+# $TITLE_PAGE_GRAPHIC_HEIGHT = 150;
+# $TITLE_PAGE_GRAPHIC_ON_RIGHT = 0;
+
+sub make_my_titlepage(){
+    my $the_title = "";
+    if ($t_title) {
+        $the_title .= "\n<h1>$t_title</h1>";
+    }
+    else {
+        write_warnings("\nThis document has no title.");
+    }
+    if ($t_author) {
+        if ($t_authorURL) {
+            my $href = translate_commands($t_authorURL);
+            $href = make_named_href('author', $href,
+                                    "<b><font size=\"+2\">$t_author"
+                                    . '</font></b>');
+            $the_title .= "\n<p>$href</p>";
+        }
+        else {
+            $the_title .= ("\n<p><b><font size=\"+2\">$t_author"
+                           . '</font></b></p>');
+        }
+    }
+    else {
+        write_warnings("\nThere is no author for this document.");
+    }
+    if ($t_institute) {
+        $the_title .= "\n<p>$t_institute</p>";
+    }
+    if ($DEVELOPER_ADDRESS) {
+        $the_title .= "\n<p>$DEVELOPER_ADDRESS</p>";
+    }
+    if ($t_affil) {
+        $the_title .= "\n<p><i>$t_affil</i></p>";
+    }
+    if ($t_date) {
+        $the_title .= "\n<p>";
+        if ($PACKAGE_VERSION) {
+            $the_title .= ('<strong>Release '
+                           . "$PACKAGE_VERSION$RELEASE_INFO</strong><br />\n");
+        }
+        $the_title .= "<strong>$t_date</strong></p>"
+    }
+    if ($t_address) {
+        $the_title .= "\n<p>$t_address</p>";
+    }
+    else {
+        $the_title .= "\n<p></p>";
+    }
+    if ($t_email) {
+        $the_title .= "\n<p>$t_email</p>";
+    }
+    return $the_title;
+}
+
+sub make_my_titlegraphic(){
+    my $filename = make_icon_filename($TITLE_PAGE_GRAPHIC);
+    my $graphic = "<td class=\"titlegraphic\"";
+    $graphic .= " width=\"$TITLE_PAGE_GRAPHIC_COLWIDTH\""
+      if ($TITLE_PAGE_GRAPHIC_COLWIDTH);
+    $graphic .= "><img";
+    $graphic .= " width=\"$TITLE_PAGE_GRAPHIC_WIDTH\""
+      if ($TITLE_PAGE_GRAPHIC_WIDTH);
+    $graphic .= " height=\"$TITLE_PAGE_GRAPHIC_HEIGHT\""
+      if ($TITLE_PAGE_GRAPHIC_HEIGHT);
+    $graphic .= "\n  src=\"$filename\" /></td>\n";
+    return $graphic;
+}
+
+sub do_cmd_maketitle{
+    local($_) = @_;
+    my $the_title = "\n";
+    if ($EXTERNAL_UP_LINK) {
+        # This generates a <link> element in the wrong place (the
+        # body), but I don't see any other way to get this generated
+        # at all.  Browsers like Mozilla, that support navigation
+        # links, can make use of this.
+        $the_title .= ("<link rel='up' href='$EXTERNAL_UP_LINK'"
+                       . ($EXTERNAL_UP_TITLE
+                          ? " title='$EXTERNAL_UP_TITLE'" : '')
+                       . " />\n");
+    }
+    $the_title .= '<div class="titlepage">';
+    if ($TITLE_PAGE_GRAPHIC) {
+        if ($TITLE_PAGE_GRAPHIC_ON_RIGHT) {
+            $the_title .= ("\n<table border=\"0\" width=\"100%\">"
+                           . "<tr align=\"right\">\n<td>"
+                           . make_my_titlepage()
+                           . "</td>\n"
+                           . make_my_titlegraphic()
+                           . "</tr>\n</table>");
+        }
+        else {
+            $the_title .= ("\n<table border=\"0\" width=\"100%\"><tr>\n"
+                           . make_my_titlegraphic()
+                           . "<td>"
+                           . make_my_titlepage()
+                           . "</td></tr>\n</table>");
+        }
+    }
+    else {
+        $the_title .= ("\n<div class='center'>"
+                       . make_my_titlepage()
+                       . "\n</div>");
+    }
+    $the_title .= "\n</div>";
+    return $the_title . $_;
+}
+
+
+#
+#  Module synopsis support
+#
+
+require SynopsisTable;
+
+sub get_chapter_id(){
+    my $id = do_cmd_thechapter('');
+    $id =~ s/<SPAN CLASS="arabic">(\d+)<\/SPAN>/$1/;
+    $id =~ s/\.//;
+    return $id;
+}
+
+# 'chapter' => 'SynopsisTable instance'
+%ModuleSynopses = ();
+
+sub get_synopsis_table($){
+    my $chap = $_[0];
+    my $key;
+    foreach $key (keys %ModuleSynopses) {
+        if ($key eq $chap) {
+            return $ModuleSynopses{$chap};
+        }
+    }
+    my $st = SynopsisTable->new();
+    $ModuleSynopses{$chap} = $st;
+    return $st;
+}
+
+sub do_cmd_moduleauthor{
+    local($_) = @_;
+    next_argument();
+    next_argument();
+    return $_;
+}
+
+sub do_cmd_sectionauthor{
+    local($_) = @_;
+    next_argument();
+    next_argument();
+    return $_;
+}
+
+sub do_cmd_declaremodule{
+    local($_) = @_;
+    my $key = next_optional_argument();
+    my $type = next_argument();
+    my $name = next_argument();
+    my $st = get_synopsis_table(get_chapter_id());
+    #
+    $key = $name unless $key;
+    $type = 'built-in' if $type eq 'builtin';
+    $st->declare($name, $key, $type);
+    define_module($type, $name);
+    return anchor_label("module-$key",$CURRENT_FILE,$_)
+}
+
+sub do_cmd_modulesynopsis{
+    local($_) = @_;
+    my $st = get_synopsis_table(get_chapter_id());
+    $st->set_synopsis($THIS_MODULE, translate_commands(next_argument()));
+    return $_;
+}
+
+sub do_cmd_localmoduletable{
+    local($_) = @_;
+    my $chap = get_chapter_id();
+    my $st = get_synopsis_table($chap);
+    $st->set_file("$CURRENT_FILE");
+    return "<tex2html-localmoduletable><$chap>\\tableofchildlinks[off]" . $_;
+}
+
+sub process_all_localmoduletables(){
+    my $key;
+    foreach $key (keys %ModuleSynopses) {
+        my $st = $ModuleSynopses{$key};
+        my $file = $st->get_file();
+        if ($file) {
+            process_localmoduletables_in_file($file);
+        }
+        else {
+            print "\nsynopsis table $key has no file association\n";
+        }
+    }
+}
+
+sub process_localmoduletables_in_file($){
+    my $file = $_[0];
+    open(MYFILE, "<$file");
+    local($_);
+    sysread(MYFILE, $_, 1024*1024);
+    close(MYFILE);
+    # need to get contents of file in $_
+    while (/<tex2html-localmoduletable><(\d+)>/) {
+        my $match = $&;
+        my $chap = $1;
+        my $st = get_synopsis_table($chap);
+        my $data = $st->tohtml();
+        s/$match/$data/;
+    }
+    open(MYFILE,">$file");
+    print MYFILE $_;
+    close(MYFILE);
+}
+sub process_python_state(){
+    process_all_localmoduletables();
+    process_grammar_files();
+}
+
+
+#
+#  "See also:" -- references placed at the end of a \section
+#
+
+sub do_env_seealso{
+    return ("<div class=\"seealso\">\n  "
+            . "<p class=\"heading\">See Also:</p>\n"
+            . $_[0]
+            . '</div>');
+}
+
+sub do_env_seealsostar{
+    return ("<div class=\"seealso-simple\">\n  "
+            . $_[0]
+            . '</div>');
+}
+
+sub do_cmd_seemodule{
+    # Insert the right magic to jump to the module definition.  This should
+    # work most of the time, at least for repeat builds....
+    local($_) = @_;
+    my $key = next_optional_argument();
+    my $module = next_argument();
+    my $text = next_argument();
+    my $period = '.';
+    $key = $module
+        unless $key;
+    if ($text =~ /\.$/) {
+        $period = '';
+    }
+    return ('<dl compact="compact" class="seemodule">'
+            . "\n    <dt>Module <b><tt class=\"module\">"
+            . "<a href=\"module-$key.html\">$module</a></tt>:</b>"
+            . "\n    <dd>$text$period\n  </dl>"
+            . $_);
+}
+
+sub strip_html_markup($){
+    my $str = $_[0];
+    my $s = "$str";
+    $s =~ s/<[a-zA-Z0-9]+(\s+[a-zA-Z0-9]+(\s*=\s*(\'[^\']*\'|\"[^\"]*\"|[a-zA-Z0-9]+))?)*\s*>//g;
+    $s =~ s/<\/[a-zA-Z0-9]+>//g;
+    return $s;
+}
+
+sub handle_rfclike_reference($$$){
+    local($_, $what, $format) = @_;
+    my $rfcnum = next_argument();
+    my $title = next_argument();
+    my $text = next_argument();
+    my $url = get_rfc_url($rfcnum, $format);
+    my $icon = get_link_icon($url);
+    my $attrtitle = strip_html_markup($title);
+    return '<dl compact="compact" class="seerfc">'
+      . "\n    <dt><a href=\"$url\""
+      . "\n        title=\"$attrtitle\""
+      . "\n        >$what $rfcnum, <em>$title</em>$icon</a>"
+      . "\n    <dd>$text\n  </dl>"
+      . $_;
+}
+
+sub do_cmd_seepep{
+    return handle_rfclike_reference($_[0], "PEP", $PEP_FORMAT);
+}
+
+sub do_cmd_seerfc{
+    # XXX Would be nice to add links to the text/plain and PDF versions.
+    return handle_rfclike_reference($_[0], "RFC", $RFC_FORMAT);
+}
+
+sub do_cmd_seetitle{
+    local($_) = @_;
+    my $url = next_optional_argument();
+    my $title = next_argument();
+    my $text = next_argument();
+    if ($url) {
+        my $icon = get_link_icon($url);
+        return '<dl compact="compact" class="seetitle">'
+          . "\n    <dt><em class=\"citetitle\"><a href=\"$url\""
+          . "\n        >$title$icon</a></em></dt>"
+          . "\n    <dd>$text</dd>\n  </dl>"
+          . $_;
+    }
+    return '<dl compact="compact" class="seetitle">'
+      . "\n    <dt><em class=\"citetitle\""
+      . "\n        >$title</em></dt>"
+      . "\n    <dd>$text</dd>\n  </dl>"
+      . $_;
+}
+
+sub do_cmd_seelink{
+    local($_) = @_;
+    my $url = next_argument();
+    my $linktext = next_argument();
+    my $text = next_argument();
+    my $icon = get_link_icon($url);
+    return '<dl compact="compact" class="seeurl">'
+      . "\n    <dt><a href='$url'"
+      . "\n        >$linktext$icon</a></dt>"
+      . "\n    <dd>$text</dd>\n  </dl>"
+      . $_;
+}
+
+sub do_cmd_seeurl{
+    local($_) = @_;
+    my $url = next_argument();
+    my $text = next_argument();
+    my $icon = get_link_icon($url);
+    return '<dl compact="compact" class="seeurl">'
+      . "\n    <dt><a href=\"$url\""
+      . "\n        class=\"url\">$url$icon</a></dt>"
+      . "\n    <dd>$text</dd>\n  </dl>"
+      . $_;
+}
+
+sub do_cmd_seetext{
+    local($_) = @_;
+    my $content = next_argument();
+    return '<div class="seetext"><p>' . $content . '</p></div>' . $_;
+}
+
+
+#
+#  Definition list support.
+#
+
+sub do_env_definitions{
+    return '<dl class="definitions">' . $_[0] . "</dl>\n";
+}
+
+sub do_cmd_term{
+    local($_) = @_;
+    my $term = next_argument();
+    my($name, $aname, $ahref) = new_link_info();
+    # could easily add an index entry here...
+    return "<dt><b>$aname" . $term . "</a></b></dt>\n<dd>" . $_;
+}
+
+
+# Commands listed here have process-order dependencies; these often
+# are related to indexing operations.
+# XXX Not sure why funclineni, methodlineni, and samp are here.
+#
+process_commands_wrap_deferred(<<_RAW_ARG_DEFERRED_CMDS_);
+declaremodule # [] # {} # {}
+funcline # {} # {}
+funclineni # {} # {}
+memberline # [] # {}
+methodline # [] # {} # {}
+methodlineni # [] # {} # {}
+modulesynopsis # {}
+bifuncindex # {}
+exindex # {}
+indexii # {} # {}
+indexiii # {} # {} # {}
+indexiv # {} # {} # {} # {}
+kwindex # {}
+obindex # {}
+opindex # {}
+stindex # {}
+platform # {}
+samp # {}
+setindexsubitem # {}
+withsubitem # {} # {}
+_RAW_ARG_DEFERRED_CMDS_
+
+
+$alltt_start = '<div class="verbatim"><pre>';
+$alltt_end = '</pre></div>';
+
+sub do_env_alltt{
+    local ($_) = @_;
+    local($closures,$reopens, at open_block_tags);
+
+    # get the tag-strings for all open tags
+    local(@keep_open_tags) = @$open_tags_R;
+    ($closures,$reopens) = &preserve_open_tags() if (@$open_tags_R);
+
+    # get the tags for text-level tags only
+    $open_tags_R = [ @keep_open_tags ];
+    local($local_closures, $local_reopens);
+    ($local_closures, $local_reopens, at open_block_tags)
+      = &preserve_open_block_tags
+        if (@$open_tags_R);
+
+    $open_tags_R = [ @open_block_tags ];
+
+    do {
+        local($open_tags_R) = [ @open_block_tags ];
+        local(@save_open_tags) = ();
+
+        local($cnt) = ++$global{'max_id'};
+        $_ = join('',"$O$cnt$C\\tt$O", ++$global{'max_id'}, $C
+                , $_ , $O, $global{'max_id'}, "$C$O$cnt$C");
+
+        $_ = &translate_environments($_);
+        $_ = &translate_commands($_) if (/\\/);
+
+        # remove spurious <BR> someone sticks in; not sure where they
+        # actually come from
+        # XXX the replacement space is there to accomodate something
+        # broken that inserts a space in front of the first line of
+        # the environment
+        s/<BR>/ /gi;
+
+        $_ = join('', $closures, $alltt_start, $local_reopens
+                , $_
+                , &balance_tags() #, $local_closures
+                , $alltt_end, $reopens);
+        undef $open_tags_R; undef @save_open_tags;
+    };
+    $open_tags_R = [ @keep_open_tags ];
+    return codetext($_);
+}
+
+# List of all filenames produced by do_cmd_verbatiminput()
+%VerbatimFiles = ();
+ at VerbatimOutputs = ();
+
+sub get_verbatim_output_name($){
+    my $file = $_[0];
+    #
+    # Re-write the source filename to always use a .txt extension
+    # so that Web servers will present it as text/plain.  This is
+    # needed since there is no other even moderately reliable way
+    # to get the right Content-Type header on text files for
+    # servers which we can't configure (like python.org mirrors).
+    #
+    if (defined $VerbatimFiles{$file}) {
+        # We've seen this one before; re-use the same output file.
+        return $VerbatimFiles{$file};
+    }
+    my($srcname, $srcdir, $srcext) = fileparse($file, '\..*');
+    $filename = "$srcname.txt";
+    #
+    # We need to determine if our default filename is already
+    # being used, and find a new one it it is.  If the name is in
+    # used, this algorithm will first attempt to include the
+    # source extension as part of the name, and if that is also in
+    # use (if the same file is included multiple times, or if
+    # another source file has that as the base name), a counter is
+    # used instead.
+    #
+    my $found = 1;
+  FIND:
+    while ($found) {
+        foreach $fn (@VerbatimOutputs) {
+            if ($fn eq $filename) {
+                if ($found == 1) {
+                    $srcext =~ s/^[.]//;  # Remove '.' from extension
+                    $filename = "$srcname-$srcext.txt";
+                }
+                else {
+                    $filename = "$srcname-$found.txt";
+                }
+                ++$found;
+                next FIND;
+            }
+        }
+        $found = 0;
+    }
+    push @VerbatimOutputs, $filename;
+    $VerbatimFiles{$file} = $filename;
+    return $filename;
+}
+
+sub do_cmd_verbatiminput{
+    local($_) = @_;
+    my $fname = next_argument();
+    my $file;
+    my $found = 0;
+    my $texpath;
+    # Search TEXINPUTS for the input file, the way we're supposed to:
+    foreach $texpath (split /$envkey/, $TEXINPUTS) {
+        $file = "$texpath$dd$fname";
+        last if ($found = (-f $file));
+    }
+    my $filename = '';
+    my $text;
+    if ($found) {
+        open(MYFILE, "<$file") || die "\n$!\n";
+        read(MYFILE, $text, 1024*1024);
+        close(MYFILE);
+        $filename = get_verbatim_output_name($file);
+        # Now that we have a filename, write it out.
+        open(MYFILE, ">$filename");
+        print MYFILE $text;
+        close(MYFILE);
+        #
+        # These rewrites convert the raw text to something that will
+        # be properly visible as HTML and also will pass through the
+        # vagaries of conversion through LaTeX2HTML.  The order in
+        # which the specific rewrites are performed is significant.
+        #
+        $text =~ s/\&/\&amp;/g;
+        # These need to happen before the normal < and > re-writes,
+        # since we need to avoid LaTeX2HTML's attempt to perform
+        # ligature processing without regard to context (since it
+        # doesn't have font information).
+        $text =~ s/--/-&\#45;/g;
+        $text =~ s/<</\&lt;\&\#60;/g;
+        $text =~ s/>>/\&gt;\&\#62;/g;
+        # Just normal re-writes...
+        $text =~ s/</\&lt;/g;
+        $text =~ s/>/\&gt;/g;
+        # These last isn't needed for the HTML, but is needed to get
+        # past LaTeX2HTML processing TeX macros.  We use &#92; instead
+        # of &sol; since many browsers don't support that.
+        $text =~ s/\\/\&\#92;/g;
+    }
+    else {
+        return '<b>Could not locate requested file <i>$fname</i>!</b>\n';
+    }
+    my $note = 'Download as text.';
+    if ($file ne $filename) {
+        $note = ('Download as text (original file name: <span class="file">'
+                 . $fname
+                 . '</span>).');
+    }
+    return ("<div class=\"verbatim\">\n<pre>"
+            . $text
+            . "</pre>\n<div class=\"footer\">\n"
+            . "<a href=\"$filename\" type=\"text/plain\""
+            . ">$note</a>"
+            . "\n</div></div>"
+            . $_);
+}
+
+1;                              # This must be the last line

Added: vendor/Python/current/Doc/python-docs.txt
===================================================================
--- vendor/Python/current/Doc/python-docs.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/python-docs.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,183 @@
+This message is being sent in response to your message to the Python
+documentation maintainers (docs at python.org).  Your message will
+be handled by a human, but this message serves to answer the most
+common questions sent to this address.
+
+You will only receive this message if it has not been sent to you for
+at least three months.
+
+If your question is answered below, you may not receive an additional
+message from the documentation maintainers.  If you feel the answers
+below are not sufficient and you do not receive an additional response
+within a week, please do send a note letting us know that your
+question has not been properly answered, and be specific regarding
+what additional information you are looking for.
+
+
+  -Fred
+
+
+Frequently Asked Questions about the Python Documentation
+---------------------------------------------------------
+
+  1.  Can I download HTML/PDF/PostScript versions of the docs?
+  2.  Where can I download Python?
+  3.  I can't unpack a downloaded copy on Windows; what should I do?
+  4.  I can't unpack a downloaded copy on Mac OS; what should I do?
+  5.  What can I use Python for?
+  6.  How do I use module/function/whatever XXX?
+  7.  What about JPython?
+  8.  I found a bug in the documentation, who should I tell?
+  9.  Can I get an algorithm to do THIS in language THAT?
+ 10.  How do I decode an XXX file from my email on a YYY computer?
+ 11.  Acrobat Reader won't print the PDF.  What's wrong?
+ 12.  Where can I find documentation in my native language?
+ 13.  Why is Python installed on my computer?
+
+
+Answers to the Questions
+------------------------
+
+  1.  Can I download HTML/PDF/PostScript/<other> versions of the docs?
+
+      Yes.  These are available via the Web and traditional FTP.  For
+      Web access to the latest version, see:
+
+	  http://www.python.org/doc/
+
+      For FTP access to the latest version and archives of previous
+      versions, see:
+
+          ftp.python.org:/pub/python/doc/
+
+  2.  Where can I download Python?
+
+      You can get Python in source form and as a Windows installer
+      from the main Python website.  You can also find information
+      about pre-built packages for other platforms there as well.
+
+      Downloading information at the website is at the URL:
+
+          http://www.python.org/download/
+
+      The sources and Windows installer can be downloaded from the FTP
+      site as well:
+
+          ftp://ftp.python.org/pub/python/
+
+  3.  I can't unpack a downloaded archive on Windows; what should I do?
+
+      Make sure the archive was saved with the .tgz extension; you may 
+      need to watch carefully when telling the browser where to save
+      the file, as the default may change the extension to .tar or
+      even .exe.
+
+      Once you're sure the file has the right extension, use a recent
+      version of WinZip to upack the file (version 7.0 works).  Get
+      WinZip from:
+
+	  http://www.winzip.com/
+
+  4.  I can't unpack a downloaded archive on Mac OS; what should I do?
+
+      Stuffit Expander 4.5 (and probably other versions) cannot handle 
+      the "tar" archive, although it can decompress it from the .tgz
+      file.  Expander Enhancer, which you have to pay for, can handle
+      the tar archive.
+
+  5.  What can I use Python for?
+
+      Python is a general purpose programming language.  See the
+      Python home page at http://www.python.org/ for more information; 
+      introductory material is available at:
+
+	  http://www.python.org/doc/Intros.html
+
+  6.  How do I use module/function/whatever XXX?
+
+      Start by reading the documentation for XXX.  If the
+      documentation doesn't make sense or seems incomplete, please
+      file a specific bug report to docs at python.org (the
+      address you sent your question to).  Otherwise, you probably
+      sent your question to the wrong place (which does not preclude
+      an answer, if I know it).
+
+      If you're looking for examples or tutorial information on how to
+      use a particular Python library component, check the Demo/
+      directory of the source distribution or Windows installation;
+      there might be an example.  If that doesn't help, point your Web
+      browser to http://www.python.org/doc/ and look around; there may
+      be a link to some interesting examples online.  After that, try
+      searching the Python Web site at http://www.python.org/search/.
+
+      If your question still hasn't been answered, you may send your
+      query to the Python newsgroup (comp.lang.python) or the mailing
+      list (see http://www.python.org/mailman/listinfo/python-list).
+      If you'd rather not send you message to a public forum, you can
+      try sending it to python-help at python.org.  (This is typically
+      slower than sending your question to the public list, however.)
+
+  7.  What about Jython and JPython?
+
+      If your question is specific to Jython or JPython, you should
+      consult the Jython website at:
+
+	  http://www.jython.org/
+
+      Chances are very good that the person who answers questions
+      posted to docs at python.org doesn't use Jython very often, 
+      and won't be able to give you a meaningful answer beyond "Look
+      at the Jython website."  Sorry, I don't have *all* the answers!
+
+  8.  I found a bug in the documentation, who should I tell?
+
+      If you're reading this, you've found the right address!  Send
+      all documentation bug reports to docs at python.org.  If
+      you prefer to use a Web-based reporting mechanism, you can use
+      the bug database at http://www.python.org/python-bugs/.
+
+  9.  Can I get an algorithm to do THIS in language THAT?
+
+      If THAT is Python, look in the standard library.  If THAT isn't
+      Python, use your favorite Internet search engine.
+
+ 10.  How do I decode an XXX file from my email on a YYY computer?
+
+      I really, honestly do not know.  I don't even know why this
+      question gets asked here.  Since I don't have a YYY computer,
+      I couldn't even try a few things out for you.
+
+ 11.  Acrobat Reader won't print the PDF.  What's wrong?
+
+      Adobe has reportedly admitted that there is a bug in Acrobat Reader
+      5.0 which causes it not to print at least some PDF files
+      generated by pdfTeX.  This software is used to produce the PDF
+      version of the Python documentation, and our documents
+      definately trigger this bug in Acrobat Reader.  To print the PDF
+      files, use Acrobat Reader 4.x, ghostscript, or xpdf.
+
+      Information on ghostscript can be found at:
+
+          http://www.ghostscript.com/
+
+      Information on xpdf can be found at:
+
+          http://www.foolabs.com/xpdf/
+
+ 12.  Where can I find documentation in my native language?
+
+      There is a lot of contributed documentation in languages other
+      than English.  Some of the documents are translations of English
+      documents, and others were originally authored in other
+      languages.  If we know about it, it will be listed at:
+
+          http://www.python.org/doc/NonEnglish.html
+
+ 13.  Why is Python installed on my computer?
+
+      We're increasingly seeing Python being installed on computers
+      as delivered by vendors.  For more information on why, and
+      whether it's safe to remove, see the "Why is Python Installed on
+      my Computer?" FAQ, found at:
+
+          http://www.python.org/doc/faq/installed/

Added: vendor/Python/current/Doc/ref/ref.tex
===================================================================
--- vendor/Python/current/Doc/ref/ref.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/ref/ref.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,68 @@
+\documentclass{manual}
+
+\title{Python Reference Manual}
+
+\input{boilerplate}
+
+\makeindex
+
+\begin{document}
+
+\maketitle
+
+\ifhtml
+\chapter*{Front Matter\label{front}}
+\fi
+
+\input{copyright}
+
+\begin{abstract}
+
+\noindent
+Python is an interpreted, object-oriented, high-level programming
+language with dynamic semantics.  Its high-level built in data
+structures, combined with dynamic typing and dynamic binding, make it
+very attractive for rapid application development, as well as for use
+as a scripting or glue language to connect existing components
+together.  Python's simple, easy to learn syntax emphasizes
+readability and therefore reduces the cost of program
+maintenance.  Python supports modules and packages, which encourages
+program modularity and code reuse.  The Python interpreter and the
+extensive standard library are available in source or binary form
+without charge for all major platforms, and can be freely distributed.
+
+This reference manual describes the syntax and ``core semantics'' of
+the language.  It is terse, but attempts to be exact and complete.
+The semantics of non-essential built-in object types and of the
+built-in functions and modules are described in the
+\citetitle[../lib/lib.html]{Python Library Reference}.  For an
+informal introduction to the language, see the
+\citetitle[../tut/tut.html]{Python Tutorial}.  For C or
+\Cpp{} programmers, two additional manuals exist:
+\citetitle[../ext/ext.html]{Extending and Embedding the Python
+Interpreter} describes the high-level picture of how to write a Python
+extension module, and the \citetitle[../api/api.html]{Python/C API
+Reference Manual} describes the interfaces available to
+C/\Cpp{} programmers in detail.
+
+\end{abstract}
+
+\tableofcontents
+
+\input{ref1}		% Introduction
+\input{ref2}		% Lexical analysis
+\input{ref3}		% Data model
+\input{ref4}		% Execution model
+\input{ref5}		% Expressions and conditions
+\input{ref6}		% Simple statements
+\input{ref7}		% Compound statements
+\input{ref8}		% Top-level components
+
+\appendix
+
+\chapter{History and License}
+\input{license}
+
+\input{ref.ind}
+
+\end{document}

Added: vendor/Python/current/Doc/ref/ref1.tex
===================================================================
--- vendor/Python/current/Doc/ref/ref1.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/ref/ref1.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,136 @@
+\chapter{Introduction\label{introduction}}
+
+This reference manual describes the Python programming language.
+It is not intended as a tutorial.
+
+While I am trying to be as precise as possible, I chose to use English
+rather than formal specifications for everything except syntax and
+lexical analysis.  This should make the document more understandable
+to the average reader, but will leave room for ambiguities.
+Consequently, if you were coming from Mars and tried to re-implement
+Python from this document alone, you might have to guess things and in
+fact you would probably end up implementing quite a different language.
+On the other hand, if you are using
+Python and wonder what the precise rules about a particular area of
+the language are, you should definitely be able to find them here.
+If you would like to see a more formal definition of the language,
+maybe you could volunteer your time --- or invent a cloning machine
+:-).
+
+It is dangerous to add too many implementation details to a language
+reference document --- the implementation may change, and other
+implementations of the same language may work differently.  On the
+other hand, there is currently only one Python implementation in
+widespread use (although alternate implementations exist), and
+its particular quirks are sometimes worth being mentioned, especially
+where the implementation imposes additional limitations.  Therefore,
+you'll find short ``implementation notes'' sprinkled throughout the
+text.
+
+Every Python implementation comes with a number of built-in and
+standard modules.  These are not documented here, but in the separate
+\citetitle[../lib/lib.html]{Python Library Reference} document.  A few
+built-in modules are mentioned when they interact in a significant way
+with the language definition.
+
+
+\section{Alternate Implementations\label{implementations}}
+
+Though there is one Python implementation which is by far the most
+popular, there are some alternate implementations which are of
+particular interest to different audiences.
+
+Known implementations include:
+
+\begin{itemize}
+\item[CPython]
+This is the original and most-maintained implementation of Python,
+written in C.  New language features generally appear here first.
+
+\item[Jython]
+Python implemented in Java.  This implementation can be used as a
+scripting language for Java applications, or can be used to create
+applications using the Java class libraries.  It is also often used to
+create tests for Java libraries.  More information can be found at
+\ulink{the Jython website}{http://www.jython.org/}.
+
+\item[Python for .NET]
+This implementation actually uses the CPython implementation, but is a
+managed .NET application and makes .NET libraries available.  This was
+created by Brian Lloyd.  For more information, see the \ulink{Python
+for .NET home page}{http://www.zope.org/Members/Brian/PythonNet}.
+
+\item[IronPython]
+An alternate Python for\ .NET.  Unlike Python.NET, this is a complete
+Python implementation that generates IL, and compiles Python code
+directly to\ .NET assemblies.  It was created by Jim Hugunin, the
+original creator of Jython.  For more information, see \ulink{the
+IronPython website}{http://workspaces.gotdotnet.com/ironpython}.
+
+\item[PyPy]
+An implementation of Python written in Python; even the bytecode
+interpreter is written in Python.  This is executed using CPython as
+the underlying interpreter.  One of the goals of the project is to
+encourage experimentation with the language itself by making it easier
+to modify the interpreter (since it is written in Python).  Additional
+information is available on \ulink{the PyPy project's home
+page}{http://codespeak.net/pypy/}.
+\end{itemize}
+
+Each of these implementations varies in some way from the language as
+documented in this manual, or introduces specific information beyond
+what's covered in the standard Python documentation.  Please refer to
+the implementation-specific documentation to determine what else you
+need to know about the specific implementation you're using.
+
+
+\section{Notation\label{notation}}
+
+The descriptions of lexical analysis and syntax use a modified BNF
+grammar notation.  This uses the following style of definition:
+\index{BNF}
+\index{grammar}
+\index{syntax}
+\index{notation}
+
+\begin{productionlist}[*]
+  \production{name}{\token{lc_letter} (\token{lc_letter} | "_")*}
+  \production{lc_letter}{"a"..."z"}
+\end{productionlist}
+
+The first line says that a \code{name} is an \code{lc_letter} followed by
+a sequence of zero or more \code{lc_letter}s and underscores.  An
+\code{lc_letter} in turn is any of the single characters \character{a}
+through \character{z}.  (This rule is actually adhered to for the
+names defined in lexical and grammar rules in this document.)
+
+Each rule begins with a name (which is the name defined by the rule)
+and \code{::=}.  A vertical bar (\code{|}) is used to separate
+alternatives; it is the least binding operator in this notation.  A
+star (\code{*}) means zero or more repetitions of the preceding item;
+likewise, a plus (\code{+}) means one or more repetitions, and a
+phrase enclosed in square brackets (\code{[ ]}) means zero or one
+occurrences (in other words, the enclosed phrase is optional).  The
+\code{*} and \code{+} operators bind as tightly as possible;
+parentheses are used for grouping.  Literal strings are enclosed in
+quotes.  White space is only meaningful to separate tokens.
+Rules are normally contained on a single line; rules with many
+alternatives may be formatted alternatively with each line after the
+first beginning with a vertical bar.
+
+In lexical definitions (as the example above), two more conventions
+are used: Two literal characters separated by three dots mean a choice
+of any single character in the given (inclusive) range of \ASCII{}
+characters.  A phrase between angular brackets (\code{<...>}) gives an
+informal description of the symbol defined; e.g., this could be used
+to describe the notion of `control character' if needed.
+\index{lexical definitions}
+\index{ASCII@\ASCII}
+
+Even though the notation used is almost the same, there is a big
+difference between the meaning of lexical and syntactic definitions:
+a lexical definition operates on the individual characters of the
+input source, while a syntax definition operates on the stream of
+tokens generated by the lexical analysis.  All uses of BNF in the next
+chapter (``Lexical Analysis'') are lexical definitions; uses in
+subsequent chapters are syntactic definitions.

Added: vendor/Python/current/Doc/ref/ref2.tex
===================================================================
--- vendor/Python/current/Doc/ref/ref2.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/ref/ref2.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,731 @@
+\chapter{Lexical analysis\label{lexical}}
+
+A Python program is read by a \emph{parser}.  Input to the parser is a
+stream of \emph{tokens}, generated by the \emph{lexical analyzer}.  This
+chapter describes how the lexical analyzer breaks a file into tokens.
+\index{lexical analysis}
+\index{parser}
+\index{token}
+
+Python uses the 7-bit \ASCII{} character set for program text.
+\versionadded[An encoding declaration can be used to indicate that 
+string literals and comments use an encoding different from ASCII]{2.3}
+For compatibility with older versions, Python only warns if it finds
+8-bit characters; those warnings should be corrected by either declaring
+an explicit encoding, or using escape sequences if those bytes are binary
+data, instead of characters.
+
+
+The run-time character set depends on the I/O devices connected to the
+program but is generally a superset of \ASCII.
+
+\strong{Future compatibility note:} It may be tempting to assume that the
+character set for 8-bit characters is ISO Latin-1 (an \ASCII{}
+superset that covers most western languages that use the Latin
+alphabet), but it is possible that in the future Unicode text editors
+will become common.  These generally use the UTF-8 encoding, which is
+also an \ASCII{} superset, but with very different use for the
+characters with ordinals 128-255.  While there is no consensus on this
+subject yet, it is unwise to assume either Latin-1 or UTF-8, even
+though the current implementation appears to favor Latin-1.  This
+applies both to the source character set and the run-time character
+set.
+
+
+\section{Line structure\label{line-structure}}
+
+A Python program is divided into a number of \emph{logical lines}.
+\index{line structure}
+
+
+\subsection{Logical lines\label{logical}}
+
+The end of
+a logical line is represented by the token NEWLINE.  Statements cannot
+cross logical line boundaries except where NEWLINE is allowed by the
+syntax (e.g., between statements in compound statements).
+A logical line is constructed from one or more \emph{physical lines}
+by following the explicit or implicit \emph{line joining} rules.
+\index{logical line}
+\index{physical line}
+\index{line joining}
+\index{NEWLINE token}
+
+
+\subsection{Physical lines\label{physical}}
+
+A physical line is a sequence of characters terminated by an end-of-line
+sequence.  In source files, any of the standard platform line
+termination sequences can be used - the \UNIX{} form using \ASCII{} LF
+(linefeed), the Windows form using the \ASCII{} sequence CR LF (return
+followed by linefeed), or the Macintosh form using the \ASCII{} CR
+(return) character.  All of these forms can be used equally, regardless
+of platform.
+
+When embedding Python, source code strings should be passed to Python
+APIs using the standard C conventions for newline characters (the
+\code{\e n} character, representing \ASCII{} LF, is the line
+terminator).
+
+
+\subsection{Comments\label{comments}}
+
+A comment starts with a hash character (\code{\#}) that is not part of
+a string literal, and ends at the end of the physical line.  A comment
+signifies the end of the logical line unless the implicit line joining
+rules are invoked.
+Comments are ignored by the syntax; they are not tokens.
+\index{comment}
+\index{hash character}
+
+
+\subsection{Encoding declarations\label{encodings}}
+\index{source character set}
+\index{encodings}
+
+If a comment in the first or second line of the Python script matches
+the regular expression \regexp{coding[=:]\e s*([-\e w.]+)}, this comment is
+processed as an encoding declaration; the first group of this
+expression names the encoding of the source code file. The recommended
+forms of this expression are
+
+\begin{verbatim}
+# -*- coding: <encoding-name> -*-
+\end{verbatim}
+
+which is recognized also by GNU Emacs, and
+
+\begin{verbatim}
+# vim:fileencoding=<encoding-name>
+\end{verbatim}
+
+which is recognized by Bram Moolenaar's VIM. In addition, if the first
+bytes of the file are the UTF-8 byte-order mark
+(\code{'\e xef\e xbb\e xbf'}), the declared file encoding is UTF-8
+(this is supported, among others, by Microsoft's \program{notepad}).
+
+If an encoding is declared, the encoding name must be recognized by
+Python. % XXX there should be a list of supported encodings.
+The encoding is used for all lexical analysis, in particular to find
+the end of a string, and to interpret the contents of Unicode literals.
+String literals are converted to Unicode for syntactical analysis,
+then converted back to their original encoding before interpretation
+starts. The encoding declaration must appear on a line of its own.
+
+\subsection{Explicit line joining\label{explicit-joining}}
+
+Two or more physical lines may be joined into logical lines using
+backslash characters (\code{\e}), as follows: when a physical line ends
+in a backslash that is not part of a string literal or comment, it is
+joined with the following forming a single logical line, deleting the
+backslash and the following end-of-line character.  For example:
+\index{physical line}
+\index{line joining}
+\index{line continuation}
+\index{backslash character}
+%
+\begin{verbatim}
+if 1900 < year < 2100 and 1 <= month <= 12 \
+   and 1 <= day <= 31 and 0 <= hour < 24 \
+   and 0 <= minute < 60 and 0 <= second < 60:   # Looks like a valid date
+        return 1
+\end{verbatim}
+
+A line ending in a backslash cannot carry a comment.  A backslash does
+not continue a comment.  A backslash does not continue a token except
+for string literals (i.e., tokens other than string literals cannot be
+split across physical lines using a backslash).  A backslash is
+illegal elsewhere on a line outside a string literal.
+
+
+\subsection{Implicit line joining\label{implicit-joining}}
+
+Expressions in parentheses, square brackets or curly braces can be
+split over more than one physical line without using backslashes.
+For example:
+
+\begin{verbatim}
+month_names = ['Januari', 'Februari', 'Maart',      # These are the
+               'April',   'Mei',      'Juni',       # Dutch names
+               'Juli',    'Augustus', 'September',  # for the months
+               'Oktober', 'November', 'December']   # of the year
+\end{verbatim}
+
+Implicitly continued lines can carry comments.  The indentation of the
+continuation lines is not important.  Blank continuation lines are
+allowed.  There is no NEWLINE token between implicit continuation
+lines.  Implicitly continued lines can also occur within triple-quoted
+strings (see below); in that case they cannot carry comments.
+
+
+\subsection{Blank lines \label{blank-lines}}
+
+\index{blank line}
+A logical line that contains only spaces, tabs, formfeeds and possibly
+a comment, is ignored (i.e., no NEWLINE token is generated).  During
+interactive input of statements, handling of a blank line may differ
+depending on the implementation of the read-eval-print loop.  In the
+standard implementation, an entirely blank logical line (i.e.\ one
+containing not even whitespace or a comment) terminates a multi-line
+statement.
+
+
+\subsection{Indentation\label{indentation}}
+
+Leading whitespace (spaces and tabs) at the beginning of a logical
+line is used to compute the indentation level of the line, which in
+turn is used to determine the grouping of statements.
+\index{indentation}
+\index{whitespace}
+\index{leading whitespace}
+\index{space}
+\index{tab}
+\index{grouping}
+\index{statement grouping}
+
+First, tabs are replaced (from left to right) by one to eight spaces
+such that the total number of characters up to and including the
+replacement is a multiple of
+eight (this is intended to be the same rule as used by \UNIX).  The
+total number of spaces preceding the first non-blank character then
+determines the line's indentation.  Indentation cannot be split over
+multiple physical lines using backslashes; the whitespace up to the
+first backslash determines the indentation.
+
+\strong{Cross-platform compatibility note:} because of the nature of
+text editors on non-UNIX platforms, it is unwise to use a mixture of
+spaces and tabs for the indentation in a single source file.  It
+should also be noted that different platforms may explicitly limit the
+maximum indentation level.
+
+A formfeed character may be present at the start of the line; it will
+be ignored for the indentation calculations above.  Formfeed
+characters occurring elsewhere in the leading whitespace have an
+undefined effect (for instance, they may reset the space count to
+zero).
+
+The indentation levels of consecutive lines are used to generate
+INDENT and DEDENT tokens, using a stack, as follows.
+\index{INDENT token}
+\index{DEDENT token}
+
+Before the first line of the file is read, a single zero is pushed on
+the stack; this will never be popped off again.  The numbers pushed on
+the stack will always be strictly increasing from bottom to top.  At
+the beginning of each logical line, the line's indentation level is
+compared to the top of the stack.  If it is equal, nothing happens.
+If it is larger, it is pushed on the stack, and one INDENT token is
+generated.  If it is smaller, it \emph{must} be one of the numbers
+occurring on the stack; all numbers on the stack that are larger are
+popped off, and for each number popped off a DEDENT token is
+generated.  At the end of the file, a DEDENT token is generated for
+each number remaining on the stack that is larger than zero.
+
+Here is an example of a correctly (though confusingly) indented piece
+of Python code:
+
+\begin{verbatim}
+def perm(l):
+        # Compute the list of all permutations of l
+    if len(l) <= 1:
+                  return [l]
+    r = []
+    for i in range(len(l)):
+             s = l[:i] + l[i+1:]
+             p = perm(s)
+             for x in p:
+              r.append(l[i:i+1] + x)
+    return r
+\end{verbatim}
+
+The following example shows various indentation errors:
+
+\begin{verbatim}
+ def perm(l):                       # error: first line indented
+for i in range(len(l)):             # error: not indented
+    s = l[:i] + l[i+1:]
+        p = perm(l[:i] + l[i+1:])   # error: unexpected indent
+        for x in p:
+                r.append(l[i:i+1] + x)
+            return r                # error: inconsistent dedent
+\end{verbatim}
+
+(Actually, the first three errors are detected by the parser; only the
+last error is found by the lexical analyzer --- the indentation of
+\code{return r} does not match a level popped off the stack.)
+
+
+\subsection{Whitespace between tokens\label{whitespace}}
+
+Except at the beginning of a logical line or in string literals, the
+whitespace characters space, tab and formfeed can be used
+interchangeably to separate tokens.  Whitespace is needed between two
+tokens only if their concatenation could otherwise be interpreted as a
+different token (e.g., ab is one token, but a b is two tokens).
+
+
+\section{Other tokens\label{other-tokens}}
+
+Besides NEWLINE, INDENT and DEDENT, the following categories of tokens
+exist: \emph{identifiers}, \emph{keywords}, \emph{literals},
+\emph{operators}, and \emph{delimiters}.
+Whitespace characters (other than line terminators, discussed earlier)
+are not tokens, but serve to delimit tokens.
+Where
+ambiguity exists, a token comprises the longest possible string that
+forms a legal token, when read from left to right.
+
+
+\section{Identifiers and keywords\label{identifiers}}
+
+Identifiers (also referred to as \emph{names}) are described by the following
+lexical definitions:
+\index{identifier}
+\index{name}
+
+\begin{productionlist}
+  \production{identifier}
+             {(\token{letter}|"_") (\token{letter} | \token{digit} | "_")*}
+  \production{letter}
+             {\token{lowercase} | \token{uppercase}}
+  \production{lowercase}
+             {"a"..."z"}
+  \production{uppercase}
+             {"A"..."Z"}
+  \production{digit}
+             {"0"..."9"}
+\end{productionlist}
+
+Identifiers are unlimited in length.  Case is significant.
+
+
+\subsection{Keywords\label{keywords}}
+
+The following identifiers are used as reserved words, or
+\emph{keywords} of the language, and cannot be used as ordinary
+identifiers.  They must be spelled exactly as written here:%
+\index{keyword}%
+\index{reserved word}
+
+\begin{verbatim}
+and       del       from      not       while    
+as        elif      global    or        with     
+assert    else      if        pass      yield    
+break     except    import    print              
+class     exec      in        raise              
+continue  finally   is        return             
+def       for       lambda    try 
+\end{verbatim}
+
+% When adding keywords, use reswords.py for reformatting
+
+\versionchanged[\constant{None} became a constant and is now
+recognized by the compiler as a name for the built-in object
+\constant{None}.  Although it is not a keyword, you cannot assign
+a different object to it]{2.4}
+
+\versionchanged[Both \keyword{as} and \keyword{with} are only recognized
+when the \code{with_statement} future feature has been enabled.
+It will always be enabled in Python 2.6.  See section~\ref{with} for
+details.  Note that using \keyword{as} and \keyword{with} as identifiers
+will always issue a warning, even when the \code{with_statement} future
+directive is not in effect]{2.5}
+
+
+\subsection{Reserved classes of identifiers\label{id-classes}}
+
+Certain classes of identifiers (besides keywords) have special
+meanings.  These classes are identified by the patterns of leading and
+trailing underscore characters:
+
+\begin{description}
+
+\item[\code{_*}]
+  Not imported by \samp{from \var{module} import *}.  The special
+  identifier \samp{_} is used in the interactive interpreter to store
+  the result of the last evaluation; it is stored in the
+  \module{__builtin__} module.  When not in interactive mode, \samp{_}
+  has no special meaning and is not defined.
+  See section~\ref{import}, ``The \keyword{import} statement.''
+
+  \note{The name \samp{_} is often used in conjunction with
+  internationalization; refer to the documentation for the
+  \ulink{\module{gettext} module}{../lib/module-gettext.html} for more
+  information on this convention.}
+
+\item[\code{__*__}]
+  System-defined names.  These names are defined by the interpreter
+  and its implementation (including the standard library);
+  applications should not expect to define additional names using this
+  convention.  The set of names of this class defined by Python may be
+  extended in future versions.
+  See section~\ref{specialnames}, ``Special method names.''
+
+\item[\code{__*}]
+  Class-private names.  Names in this category, when used within the
+  context of a class definition, are re-written to use a mangled form
+  to help avoid name clashes between ``private'' attributes of base
+  and derived classes.
+  See section~\ref{atom-identifiers}, ``Identifiers (Names).''
+
+\end{description}
+
+
+\section{Literals\label{literals}}
+
+Literals are notations for constant values of some built-in types.
+\index{literal}
+\index{constant}
+
+
+\subsection{String literals\label{strings}}
+
+String literals are described by the following lexical definitions:
+\index{string literal}
+
+\index{ASCII@\ASCII}
+\begin{productionlist}
+  \production{stringliteral}
+             {[\token{stringprefix}](\token{shortstring} | \token{longstring})}
+  \production{stringprefix}
+             {"r" | "u" | "ur" | "R" | "U" | "UR" | "Ur" | "uR"}
+  \production{shortstring}
+             {"'" \token{shortstringitem}* "'"
+              | '"' \token{shortstringitem}* '"'}
+  \production{longstring}
+             {"'''" \token{longstringitem}* "'''"}
+  \productioncont{| '"""' \token{longstringitem}* '"""'}
+  \production{shortstringitem}
+             {\token{shortstringchar} | \token{escapeseq}}
+  \production{longstringitem}
+             {\token{longstringchar} | \token{escapeseq}}
+  \production{shortstringchar}
+             {<any source character except "\e" or newline or the quote>}
+  \production{longstringchar}
+             {<any source character except "\e">}
+  \production{escapeseq}
+             {"\e" <any ASCII character>}
+\end{productionlist}
+
+One syntactic restriction not indicated by these productions is that
+whitespace is not allowed between the \grammartoken{stringprefix} and
+the rest of the string literal. The source character set is defined
+by the encoding declaration; it is \ASCII{} if no encoding declaration
+is given in the source file; see section~\ref{encodings}.
+
+\index{triple-quoted string}
+\index{Unicode Consortium}
+\index{string!Unicode}
+In plain English: String literals can be enclosed in matching single
+quotes (\code{'}) or double quotes (\code{"}).  They can also be
+enclosed in matching groups of three single or double quotes (these
+are generally referred to as \emph{triple-quoted strings}).  The
+backslash (\code{\e}) character is used to escape characters that
+otherwise have a special meaning, such as newline, backslash itself,
+or the quote character.  String literals may optionally be prefixed
+with a letter \character{r} or \character{R}; such strings are called
+\dfn{raw strings}\index{raw string} and use different rules for interpreting
+backslash escape sequences.  A prefix of \character{u} or \character{U}
+makes the string a Unicode string.  Unicode strings use the Unicode character
+set as defined by the Unicode Consortium and ISO~10646.  Some additional
+escape sequences, described below, are available in Unicode strings.
+The two prefix characters may be combined; in this case, \character{u} must
+appear before \character{r}.
+
+In triple-quoted strings,
+unescaped newlines and quotes are allowed (and are retained), except
+that three unescaped quotes in a row terminate the string.  (A
+``quote'' is the character used to open the string, i.e. either
+\code{'} or \code{"}.)
+
+Unless an \character{r} or \character{R} prefix is present, escape
+sequences in strings are interpreted according to rules similar
+to those used by Standard C.  The recognized escape sequences are:
+\index{physical line}
+\index{escape sequence}
+\index{Standard C}
+\index{C}
+
+\begin{tableiii}{l|l|c}{code}{Escape Sequence}{Meaning}{Notes}
+\lineiii{\e\var{newline}} {Ignored}{}
+\lineiii{\e\e}	{Backslash (\code{\e})}{}
+\lineiii{\e'}	{Single quote (\code{'})}{}
+\lineiii{\e"}	{Double quote (\code{"})}{}
+\lineiii{\e a}	{\ASCII{} Bell (BEL)}{}
+\lineiii{\e b}	{\ASCII{} Backspace (BS)}{}
+\lineiii{\e f}	{\ASCII{} Formfeed (FF)}{}
+\lineiii{\e n}	{\ASCII{} Linefeed (LF)}{}
+\lineiii{\e N\{\var{name}\}}
+        {Character named \var{name} in the Unicode database (Unicode only)}{}
+\lineiii{\e r}	{\ASCII{} Carriage Return (CR)}{}
+\lineiii{\e t}	{\ASCII{} Horizontal Tab (TAB)}{}
+\lineiii{\e u\var{xxxx}}
+        {Character with 16-bit hex value \var{xxxx} (Unicode only)}{(1)}
+\lineiii{\e U\var{xxxxxxxx}}
+        {Character with 32-bit hex value \var{xxxxxxxx} (Unicode only)}{(2)}
+\lineiii{\e v}	{\ASCII{} Vertical Tab (VT)}{}
+\lineiii{\e\var{ooo}} {Character with octal value \var{ooo}}{(3,5)}
+\lineiii{\e x\var{hh}} {Character with hex value \var{hh}}{(4,5)}
+\end{tableiii}
+\index{ASCII@\ASCII}
+
+\noindent
+Notes:
+
+\begin{itemize}
+\item[(1)]
+  Individual code units which form parts of a surrogate pair can be
+  encoded using this escape sequence.
+\item[(2)]
+  Any Unicode character can be encoded this way, but characters
+  outside the Basic Multilingual Plane (BMP) will be encoded using a
+  surrogate pair if Python is compiled to use 16-bit code units (the
+  default).  Individual code units which form parts of a surrogate
+  pair can be encoded using this escape sequence.
+\item[(3)]
+  As in Standard C, up to three octal digits are accepted.
+\item[(4)]
+  Unlike in Standard C, at most two hex digits are accepted.
+\item[(5)]
+  In a string literal, hexadecimal and octal escapes denote the
+  byte with the given value; it is not necessary that the byte
+  encodes a character in the source character set. In a Unicode
+  literal, these escapes denote a Unicode character with the given
+  value.
+\end{itemize}
+
+
+Unlike Standard \index{unrecognized escape sequence}C,
+all unrecognized escape sequences are left in the string unchanged,
+i.e., \emph{the backslash is left in the string}.  (This behavior is
+useful when debugging: if an escape sequence is mistyped, the
+resulting output is more easily recognized as broken.)  It is also
+important to note that the escape sequences marked as ``(Unicode
+only)'' in the table above fall into the category of unrecognized
+escapes for non-Unicode string literals.
+
+When an \character{r} or \character{R} prefix is present, a character
+following a backslash is included in the string without change, and \emph{all
+backslashes are left in the string}.  For example, the string literal
+\code{r"\e n"} consists of two characters: a backslash and a lowercase
+\character{n}.  String quotes can be escaped with a backslash, but the
+backslash remains in the string; for example, \code{r"\e""} is a valid string
+literal consisting of two characters: a backslash and a double quote;
+\code{r"\e"} is not a valid string literal (even a raw string cannot
+end in an odd number of backslashes).  Specifically, \emph{a raw
+string cannot end in a single backslash} (since the backslash would
+escape the following quote character).  Note also that a single
+backslash followed by a newline is interpreted as those two characters
+as part of the string, \emph{not} as a line continuation.
+
+When an \character{r} or \character{R} prefix is used in conjunction
+with a \character{u} or \character{U} prefix, then the \code{\e uXXXX}
+and \code{\e UXXXXXXXX} escape sequences are processed while 
+\emph{all other backslashes are left in the string}.
+For example, the string literal
+\code{ur"\e{}u0062\e n"} consists of three Unicode characters: `LATIN
+SMALL LETTER B', `REVERSE SOLIDUS', and `LATIN SMALL LETTER N'.
+Backslashes can be escaped with a preceding backslash; however, both
+remain in the string.  As a result, \code{\e uXXXX} escape sequences
+are only recognized when there are an odd number of backslashes.
+
+\subsection{String literal concatenation\label{string-catenation}}
+
+Multiple adjacent string literals (delimited by whitespace), possibly
+using different quoting conventions, are allowed, and their meaning is
+the same as their concatenation.  Thus, \code{"hello" 'world'} is
+equivalent to \code{"helloworld"}.  This feature can be used to reduce
+the number of backslashes needed, to split long strings conveniently
+across long lines, or even to add comments to parts of strings, for
+example:
+
+\begin{verbatim}
+re.compile("[A-Za-z_]"       # letter or underscore
+           "[A-Za-z0-9_]*"   # letter, digit or underscore
+          )
+\end{verbatim}
+
+Note that this feature is defined at the syntactical level, but
+implemented at compile time.  The `+' operator must be used to
+concatenate string expressions at run time.  Also note that literal
+concatenation can use different quoting styles for each component
+(even mixing raw strings and triple quoted strings).
+
+
+\subsection{Numeric literals\label{numbers}}
+
+There are four types of numeric literals: plain integers, long
+integers, floating point numbers, and imaginary numbers.  There are no
+complex literals (complex numbers can be formed by adding a real
+number and an imaginary number).
+\index{number}
+\index{numeric literal}
+\index{integer literal}
+\index{plain integer literal}
+\index{long integer literal}
+\index{floating point literal}
+\index{hexadecimal literal}
+\index{octal literal}
+\index{decimal literal}
+\index{imaginary literal}
+\index{complex!literal}
+
+Note that numeric literals do not include a sign; a phrase like
+\code{-1} is actually an expression composed of the unary operator
+`\code{-}' and the literal \code{1}.
+
+
+\subsection{Integer and long integer literals\label{integers}}
+
+Integer and long integer literals are described by the following
+lexical definitions:
+
+\begin{productionlist}
+  \production{longinteger}
+             {\token{integer} ("l" | "L")}
+  \production{integer}
+             {\token{decimalinteger} | \token{octinteger} | \token{hexinteger}}
+  \production{decimalinteger}
+             {\token{nonzerodigit} \token{digit}* | "0"}
+  \production{octinteger}
+             {"0" \token{octdigit}+}
+  \production{hexinteger}
+             {"0" ("x" | "X") \token{hexdigit}+}
+  \production{nonzerodigit}
+             {"1"..."9"}
+  \production{octdigit}
+             {"0"..."7"}
+  \production{hexdigit}
+             {\token{digit} | "a"..."f" | "A"..."F"}
+\end{productionlist}
+
+Although both lower case \character{l} and upper case \character{L} are
+allowed as suffix for long integers, it is strongly recommended to always
+use \character{L}, since the letter \character{l} looks too much like the
+digit \character{1}.
+
+Plain integer literals that are above the largest representable plain
+integer (e.g., 2147483647 when using 32-bit arithmetic) are accepted
+as if they were long integers instead.\footnote{In versions of Python
+prior to 2.4, octal and hexadecimal literals in the range just above
+the largest representable plain integer but below the largest unsigned
+32-bit number (on a machine using 32-bit arithmetic), 4294967296, were
+taken as the negative plain integer obtained by subtracting 4294967296
+from their unsigned value.}  There is no limit for long integer
+literals apart from what can be stored in available memory.
+
+Some examples of plain integer literals (first row) and long integer
+literals (second and third rows):
+
+\begin{verbatim}
+7     2147483647                        0177
+3L    79228162514264337593543950336L    0377L   0x100000000L
+      79228162514264337593543950336             0xdeadbeef						    
+\end{verbatim}
+
+
+\subsection{Floating point literals\label{floating}}
+
+Floating point literals are described by the following lexical
+definitions:
+
+\begin{productionlist}
+  \production{floatnumber}
+             {\token{pointfloat} | \token{exponentfloat}}
+  \production{pointfloat}
+             {[\token{intpart}] \token{fraction} | \token{intpart} "."}
+  \production{exponentfloat}
+             {(\token{intpart} | \token{pointfloat})
+              \token{exponent}}
+  \production{intpart}
+             {\token{digit}+}
+  \production{fraction}
+             {"." \token{digit}+}
+  \production{exponent}
+             {("e" | "E") ["+" | "-"] \token{digit}+}
+\end{productionlist}
+
+Note that the integer and exponent parts of floating point numbers
+can look like octal integers, but are interpreted using radix 10.  For
+example, \samp{077e010} is legal, and denotes the same number
+as \samp{77e10}.
+The allowed range of floating point literals is
+implementation-dependent.
+Some examples of floating point literals:
+
+\begin{verbatim}
+3.14    10.    .001    1e100    3.14e-10    0e0
+\end{verbatim}
+
+Note that numeric literals do not include a sign; a phrase like
+\code{-1} is actually an expression composed of the unary operator
+\code{-} and the literal \code{1}.
+
+
+\subsection{Imaginary literals\label{imaginary}}
+
+Imaginary literals are described by the following lexical definitions:
+
+\begin{productionlist}
+  \production{imagnumber}{(\token{floatnumber} | \token{intpart}) ("j" | "J")}
+\end{productionlist}
+
+An imaginary literal yields a complex number with a real part of
+0.0.  Complex numbers are represented as a pair of floating point
+numbers and have the same restrictions on their range.  To create a
+complex number with a nonzero real part, add a floating point number
+to it, e.g., \code{(3+4j)}.  Some examples of imaginary literals:
+
+\begin{verbatim}
+3.14j   10.j    10j     .001j   1e100j  3.14e-10j 
+\end{verbatim}
+
+
+\section{Operators\label{operators}}
+
+The following tokens are operators:
+\index{operators}
+
+\begin{verbatim}
++       -       *       **      /       //      %
+<<      >>      &       |       ^       ~
+<       >       <=      >=      ==      !=      <>
+\end{verbatim}
+
+The comparison operators \code{<>} and \code{!=} are alternate
+spellings of the same operator.  \code{!=} is the preferred spelling;
+\code{<>} is obsolescent.
+
+
+\section{Delimiters\label{delimiters}}
+
+The following tokens serve as delimiters in the grammar:
+\index{delimiters}
+
+\begin{verbatim}
+(       )       [       ]       {       }      @
+,       :       .       `       =       ;
++=      -=      *=      /=      //=     %=
+&=      |=      ^=      >>=     <<=     **=
+\end{verbatim}
+
+The period can also occur in floating-point and imaginary literals.  A
+sequence of three periods has a special meaning as an ellipsis in slices.
+The second half of the list, the augmented assignment operators, serve
+lexically as delimiters, but also perform an operation.
+
+The following printing \ASCII{} characters have special meaning as part
+of other tokens or are otherwise significant to the lexical analyzer:
+
+\begin{verbatim}
+'       "       #       \
+\end{verbatim}
+
+The following printing \ASCII{} characters are not used in Python.  Their
+occurrence outside string literals and comments is an unconditional
+error:
+\index{ASCII@\ASCII}
+
+\begin{verbatim}
+$       ?
+\end{verbatim}

Added: vendor/Python/current/Doc/ref/ref3.tex
===================================================================
--- vendor/Python/current/Doc/ref/ref3.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/ref/ref3.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2225 @@
+\chapter{Data model\label{datamodel}}
+
+
+\section{Objects, values and types\label{objects}}
+
+\dfn{Objects} are Python's abstraction for data.  All data in a Python
+program is represented by objects or by relations between objects.
+(In a sense, and in conformance to Von Neumann's model of a
+``stored program computer,'' code is also represented by objects.)
+\index{object}
+\index{data}
+
+Every object has an identity, a type and a value.  An object's
+\emph{identity} never changes once it has been created; you may think
+of it as the object's address in memory.  The `\keyword{is}' operator
+compares the identity of two objects; the
+\function{id()}\bifuncindex{id} function returns an integer
+representing its identity (currently implemented as its address).
+An object's \dfn{type} is
+also unchangeable.\footnote{Since Python 2.2, a gradual merging of
+types and classes has been started that makes this and a few other
+assertions made in this manual not 100\% accurate and complete:
+for example, it \emph{is} now possible in some cases to change an
+object's type, under certain controlled conditions.  Until this manual
+undergoes extensive revision, it must now be taken as authoritative
+only regarding ``classic classes'', that are still the default, for
+compatibility purposes, in Python 2.2 and 2.3.  For more information,
+see \url{http://www.python.org/doc/newstyle.html}.}
+An object's type determines the operations that the object
+supports (e.g., ``does it have a length?'') and also defines the
+possible values for objects of that type.  The
+\function{type()}\bifuncindex{type} function returns an object's type
+(which is an object itself).  The \emph{value} of some
+objects can change.  Objects whose value can change are said to be
+\emph{mutable}; objects whose value is unchangeable once they are
+created are called \emph{immutable}.
+(The value of an immutable container object that contains a reference
+to a mutable object can change when the latter's value is changed;
+however the container is still considered immutable, because the
+collection of objects it contains cannot be changed.  So, immutability
+is not strictly the same as having an unchangeable value, it is more
+subtle.)
+An object's mutability is determined by its type; for instance,
+numbers, strings and tuples are immutable, while dictionaries and
+lists are mutable.
+\index{identity of an object}
+\index{value of an object}
+\index{type of an object}
+\index{mutable object}
+\index{immutable object}
+
+Objects are never explicitly destroyed; however, when they become
+unreachable they may be garbage-collected.  An implementation is
+allowed to postpone garbage collection or omit it altogether --- it is
+a matter of implementation quality how garbage collection is
+implemented, as long as no objects are collected that are still
+reachable.  (Implementation note: the current implementation uses a
+reference-counting scheme with (optional) delayed detection of
+cyclically linked garbage, which collects most objects as soon as they
+become unreachable, but is not guaranteed to collect garbage
+containing circular references.  See the
+\citetitle[../lib/module-gc.html]{Python Library Reference} for
+information on controlling the collection of cyclic garbage.)
+\index{garbage collection}
+\index{reference counting}
+\index{unreachable object}
+
+Note that the use of the implementation's tracing or debugging
+facilities may keep objects alive that would normally be collectable.
+Also note that catching an exception with a
+`\keyword{try}...\keyword{except}' statement may keep objects alive.
+
+Some objects contain references to ``external'' resources such as open
+files or windows.  It is understood that these resources are freed
+when the object is garbage-collected, but since garbage collection is
+not guaranteed to happen, such objects also provide an explicit way to
+release the external resource, usually a \method{close()} method.
+Programs are strongly recommended to explicitly close such
+objects.  The `\keyword{try}...\keyword{finally}' statement provides
+a convenient way to do this.
+
+Some objects contain references to other objects; these are called
+\emph{containers}.  Examples of containers are tuples, lists and
+dictionaries.  The references are part of a container's value.  In
+most cases, when we talk about the value of a container, we imply the
+values, not the identities of the contained objects; however, when we
+talk about the mutability of a container, only the identities of
+the immediately contained objects are implied.  So, if an immutable
+container (like a tuple)
+contains a reference to a mutable object, its value changes
+if that mutable object is changed.
+\index{container}
+
+Types affect almost all aspects of object behavior.  Even the importance
+of object identity is affected in some sense: for immutable types,
+operations that compute new values may actually return a reference to
+any existing object with the same type and value, while for mutable
+objects this is not allowed.  E.g., after
+\samp{a = 1; b = 1},
+\code{a} and \code{b} may or may not refer to the same object with the
+value one, depending on the implementation, but after
+\samp{c = []; d = []}, \code{c} and \code{d}
+are guaranteed to refer to two different, unique, newly created empty
+lists.
+(Note that \samp{c = d = []} assigns the same object to both
+\code{c} and \code{d}.)
+
+
+\section{The standard type hierarchy\label{types}}
+
+Below is a list of the types that are built into Python.  Extension
+modules (written in C, Java, or other languages, depending on
+the implementation) can define additional types.  Future versions of
+Python may add types to the type hierarchy (e.g., rational
+numbers, efficiently stored arrays of integers, etc.).
+\index{type}
+\indexii{data}{type}
+\indexii{type}{hierarchy}
+\indexii{extension}{module}
+\indexii{C}{language}
+
+Some of the type descriptions below contain a paragraph listing
+`special attributes.'  These are attributes that provide access to the
+implementation and are not intended for general use.  Their definition
+may change in the future.
+\index{attribute}
+\indexii{special}{attribute}
+\indexiii{generic}{special}{attribute}
+
+\begin{description}
+
+\item[None]
+This type has a single value.  There is a single object with this value.
+This object is accessed through the built-in name \code{None}.
+It is used to signify the absence of a value in many situations, e.g.,
+it is returned from functions that don't explicitly return anything.
+Its truth value is false.
+\obindex{None}
+
+\item[NotImplemented]
+This type has a single value.  There is a single object with this value.
+This object is accessed through the built-in name \code{NotImplemented}.
+Numeric methods and rich comparison methods may return this value if
+they do not implement the operation for the operands provided.  (The
+interpreter will then try the reflected operation, or some other
+fallback, depending on the operator.)  Its truth value is true.
+\obindex{NotImplemented}
+
+\item[Ellipsis]
+This type has a single value.  There is a single object with this value.
+This object is accessed through the built-in name \code{Ellipsis}.
+It is used to indicate the presence of the \samp{...} syntax in a
+slice.  Its truth value is true.
+\obindex{Ellipsis}
+
+\item[Numbers]
+These are created by numeric literals and returned as results by
+arithmetic operators and arithmetic built-in functions.  Numeric
+objects are immutable; once created their value never changes.  Python
+numbers are of course strongly related to mathematical numbers, but
+subject to the limitations of numerical representation in computers.
+\obindex{numeric}
+
+Python distinguishes between integers, floating point numbers, and
+complex numbers:
+
+\begin{description}
+\item[Integers]
+These represent elements from the mathematical set of integers
+(positive and negative).
+\obindex{integer}
+
+There are three types of integers:
+
+\begin{description}
+
+\item[Plain integers]
+These represent numbers in the range -2147483648 through 2147483647.
+(The range may be larger on machines with a larger natural word
+size, but not smaller.)
+When the result of an operation would fall outside this range, the
+result is normally returned as a long integer (in some cases, the
+exception \exception{OverflowError} is raised instead).
+For the purpose of shift and mask operations, integers are assumed to
+have a binary, 2's complement notation using 32 or more bits, and
+hiding no bits from the user (i.e., all 4294967296 different bit
+patterns correspond to different values).
+\obindex{plain integer}
+\withsubitem{(built-in exception)}{\ttindex{OverflowError}}
+
+\item[Long integers]
+These represent numbers in an unlimited range, subject to available
+(virtual) memory only.  For the purpose of shift and mask operations,
+a binary representation is assumed, and negative numbers are
+represented in a variant of 2's complement which gives the illusion of
+an infinite string of sign bits extending to the left.
+\obindex{long integer}
+
+\item[Booleans]
+These represent the truth values False and True.  The two objects
+representing the values False and True are the only Boolean objects.
+The Boolean type is a subtype of plain integers, and Boolean values
+behave like the values 0 and 1, respectively, in almost all contexts,
+the exception being that when converted to a string, the strings
+\code{"False"} or \code{"True"} are returned, respectively.
+\obindex{Boolean}
+\ttindex{False}
+\ttindex{True}
+
+\end{description} % Integers
+
+The rules for integer representation are intended to give the most
+meaningful interpretation of shift and mask operations involving
+negative integers and the least surprises when switching between the
+plain and long integer domains.  Any operation except left shift,
+if it yields a result in the plain integer domain without causing
+overflow, will yield the same result in the long integer domain or
+when using mixed operands.
+\indexii{integer}{representation}
+
+\item[Floating point numbers]
+These represent machine-level double precision floating point numbers.  
+You are at the mercy of the underlying machine architecture (and
+C or Java implementation) for the accepted range and handling of overflow.
+Python does not support single-precision floating point numbers; the
+savings in processor and memory usage that are usually the reason for using
+these is dwarfed by the overhead of using objects in Python, so there
+is no reason to complicate the language with two kinds of floating
+point numbers.
+\obindex{floating point}
+\indexii{floating point}{number}
+\indexii{C}{language}
+\indexii{Java}{language}
+
+\item[Complex numbers]
+These represent complex numbers as a pair of machine-level double
+precision floating point numbers.  The same caveats apply as for
+floating point numbers.  The real and imaginary parts of a complex
+number \code{z} can be retrieved through the read-only attributes
+\code{z.real} and \code{z.imag}.
+\obindex{complex}
+\indexii{complex}{number}
+
+\end{description} % Numbers
+
+
+\item[Sequences]
+These represent finite ordered sets indexed by non-negative numbers.
+The built-in function \function{len()}\bifuncindex{len} returns the
+number of items of a sequence.
+When the length of a sequence is \var{n}, the
+index set contains the numbers 0, 1, \ldots, \var{n}-1.  Item
+\var{i} of sequence \var{a} is selected by \code{\var{a}[\var{i}]}.
+\obindex{sequence}
+\index{index operation}
+\index{item selection}
+\index{subscription}
+
+Sequences also support slicing: \code{\var{a}[\var{i}:\var{j}]}
+selects all items with index \var{k} such that \var{i} \code{<=}
+\var{k} \code{<} \var{j}.  When used as an expression, a slice is a
+sequence of the same type.  This implies that the index set is
+renumbered so that it starts at 0.
+\index{slicing}
+
+Some sequences also support ``extended slicing'' with a third ``step''
+parameter: \code{\var{a}[\var{i}:\var{j}:\var{k}]} selects all items
+of \var{a} with index \var{x} where \code{\var{x} = \var{i} +
+\var{n}*\var{k}}, \var{n} \code{>=} \code{0} and \var{i} \code{<=}
+\var{x} \code{<} \var{j}.
+\index{extended slicing}
+
+Sequences are distinguished according to their mutability:
+
+\begin{description}
+
+\item[Immutable sequences]
+An object of an immutable sequence type cannot change once it is
+created.  (If the object contains references to other objects,
+these other objects may be mutable and may be changed; however,
+the collection of objects directly referenced by an immutable object
+cannot change.)
+\obindex{immutable sequence}
+\obindex{immutable}
+
+The following types are immutable sequences:
+
+\begin{description}
+
+\item[Strings]
+The items of a string are characters.  There is no separate
+character type; a character is represented by a string of one item.
+Characters represent (at least) 8-bit bytes.  The built-in
+functions \function{chr()}\bifuncindex{chr} and
+\function{ord()}\bifuncindex{ord} convert between characters and
+nonnegative integers representing the byte values.  Bytes with the
+values 0-127 usually represent the corresponding \ASCII{} values, but
+the interpretation of values is up to the program.  The string
+data type is also used to represent arrays of bytes, e.g., to hold data
+read from a file.
+\obindex{string}
+\index{character}
+\index{byte}
+\index{ASCII@\ASCII}
+
+(On systems whose native character set is not \ASCII, strings may use
+EBCDIC in their internal representation, provided the functions
+\function{chr()} and \function{ord()} implement a mapping between \ASCII{} and
+EBCDIC, and string comparison preserves the \ASCII{} order.
+Or perhaps someone can propose a better rule?)
+\index{ASCII@\ASCII}
+\index{EBCDIC}
+\index{character set}
+\indexii{string}{comparison}
+\bifuncindex{chr}
+\bifuncindex{ord}
+
+\item[Unicode]
+The items of a Unicode object are Unicode code units.  A Unicode code
+unit is represented by a Unicode object of one item and can hold
+either a 16-bit or 32-bit value representing a Unicode ordinal (the
+maximum value for the ordinal is given in \code{sys.maxunicode}, and
+depends on how Python is configured at compile time).  Surrogate pairs
+may be present in the Unicode object, and will be reported as two
+separate items.  The built-in functions
+\function{unichr()}\bifuncindex{unichr} and
+\function{ord()}\bifuncindex{ord} convert between code units and
+nonnegative integers representing the Unicode ordinals as defined in
+the Unicode Standard 3.0. Conversion from and to other encodings are
+possible through the Unicode method \method{encode()} and the built-in
+function \function{unicode()}.\bifuncindex{unicode}
+\obindex{unicode}
+\index{character}
+\index{integer}
+\index{Unicode}
+
+\item[Tuples]
+The items of a tuple are arbitrary Python objects.
+Tuples of two or more items are formed by comma-separated lists
+of expressions.  A tuple of one item (a `singleton') can be formed
+by affixing a comma to an expression (an expression by itself does
+not create a tuple, since parentheses must be usable for grouping of
+expressions).  An empty tuple can be formed by an empty pair of
+parentheses.
+\obindex{tuple}
+\indexii{singleton}{tuple}
+\indexii{empty}{tuple}
+
+\end{description} % Immutable sequences
+
+\item[Mutable sequences]
+Mutable sequences can be changed after they are created.  The
+subscription and slicing notations can be used as the target of
+assignment and \keyword{del} (delete) statements.
+\obindex{mutable sequence}
+\obindex{mutable}
+\indexii{assignment}{statement}
+\index{delete}
+\stindex{del}
+\index{subscription}
+\index{slicing}
+
+There is currently a single intrinsic mutable sequence type:
+
+\begin{description}
+
+\item[Lists]
+The items of a list are arbitrary Python objects.  Lists are formed
+by placing a comma-separated list of expressions in square brackets.
+(Note that there are no special cases needed to form lists of length 0
+or 1.)
+\obindex{list}
+
+\end{description} % Mutable sequences
+
+The extension module \module{array}\refstmodindex{array} provides an
+additional example of a mutable sequence type.
+
+
+\end{description} % Sequences
+
+
+\item[Set types]
+These represent unordered, finite sets of unique, immutable objects.
+As such, they cannot be indexed by any subscript. However, they can be
+iterated over, and the built-in function \function{len()} returns the
+number of items in a set. Common uses for sets are
+fast membership testing, removing duplicates from a sequence, and
+computing mathematical operations such as intersection, union, difference,
+and symmetric difference.
+\bifuncindex{len}
+\obindex{set type}
+
+For set elements, the same immutability rules apply as for dictionary
+keys. Note that numeric types obey the normal rules for numeric
+comparison: if two numbers compare equal (e.g., \code{1} and
+\code{1.0}), only one of them can be contained in a set.
+
+There are currently two intrinsic set types:
+
+\begin{description}
+
+\item[Sets]
+These\obindex{set} represent a mutable set. They are created by the
+built-in \function{set()} constructor and can be modified afterwards
+by several methods, such as \method{add()}.
+
+\item[Frozen sets]
+These\obindex{frozenset} represent an immutable set. They are created by
+the built-in \function{frozenset()} constructor. As a frozenset is
+immutable and hashable, it can be used again as an element of another set,
+or as a dictionary key.
+
+\end{description} % Set types
+
+
+\item[Mappings]
+These represent finite sets of objects indexed by arbitrary index sets.
+The subscript notation \code{a[k]} selects the item indexed
+by \code{k} from the mapping \code{a}; this can be used in
+expressions and as the target of assignments or \keyword{del} statements.
+The built-in function \function{len()} returns the number of items
+in a mapping.
+\bifuncindex{len}
+\index{subscription}
+\obindex{mapping}
+
+There is currently a single intrinsic mapping type:
+
+\begin{description}
+
+\item[Dictionaries]
+These\obindex{dictionary} represent finite sets of objects indexed by
+nearly arbitrary values.  The only types of values not acceptable as
+keys are values containing lists or dictionaries or other mutable
+types that are compared by value rather than by object identity, the
+reason being that the efficient implementation of dictionaries
+requires a key's hash value to remain constant.
+Numeric types used for keys obey the normal rules for numeric
+comparison: if two numbers compare equal (e.g., \code{1} and
+\code{1.0}) then they can be used interchangeably to index the same
+dictionary entry.
+
+Dictionaries are mutable; they can be created by the
+\code{\{...\}} notation (see section~\ref{dict}, ``Dictionary
+Displays'').
+
+The extension modules \module{dbm}\refstmodindex{dbm},
+\module{gdbm}\refstmodindex{gdbm}, and
+\module{bsddb}\refstmodindex{bsddb} provide additional examples of
+mapping types.
+
+\end{description} % Mapping types
+
+\item[Callable types]
+These\obindex{callable} are the types to which the function call
+operation (see section~\ref{calls}, ``Calls'') can be applied:
+\indexii{function}{call}
+\index{invocation}
+\indexii{function}{argument}
+
+\begin{description}
+
+\item[User-defined functions]
+A user-defined function object is created by a function definition
+(see section~\ref{function}, ``Function definitions'').  It should be
+called with an argument
+list containing the same number of items as the function's formal
+parameter list.
+\indexii{user-defined}{function}
+\obindex{function}
+\obindex{user-defined function}
+
+Special attributes: 
+
+\begin{tableiii}{lll}{member}{Attribute}{Meaning}{}
+  \lineiii{func_doc}{The function's documentation string, or
+    \code{None} if unavailable}{Writable}
+
+  \lineiii{__doc__}{Another way of spelling
+    \member{func_doc}}{Writable}
+
+  \lineiii{func_name}{The function's name}{Writable}
+
+  \lineiii{__name__}{Another way of spelling
+    \member{func_name}}{Writable}
+
+  \lineiii{__module__}{The name of the module the function was defined
+    in, or \code{None} if unavailable.}{Writable}
+
+  \lineiii{func_defaults}{A tuple containing default argument values
+    for those arguments that have defaults, or \code{None} if no
+    arguments have a default value}{Writable}
+
+  \lineiii{func_code}{The code object representing the compiled
+    function body.}{Writable}
+
+  \lineiii{func_globals}{A reference to the dictionary that holds the
+    function's global variables --- the global namespace of the module
+    in which the function was defined.}{Read-only}
+
+  \lineiii{func_dict}{The namespace supporting arbitrary function
+    attributes.}{Writable}
+
+  \lineiii{func_closure}{\code{None} or a tuple of cells that contain
+    bindings for the function's free variables.}{Read-only}
+\end{tableiii}
+
+Most of the attributes labelled ``Writable'' check the type of the
+assigned value.
+
+\versionchanged[\code{func_name} is now writable]{2.4}
+
+Function objects also support getting and setting arbitrary
+attributes, which can be used, for example, to attach metadata to
+functions.  Regular attribute dot-notation is used to get and set such
+attributes. \emph{Note that the current implementation only supports
+function attributes on user-defined functions.  Function attributes on
+built-in functions may be supported in the future.}
+
+Additional information about a function's definition can be retrieved
+from its code object; see the description of internal types below.
+
+\withsubitem{(function attribute)}{
+  \ttindex{func_doc}
+  \ttindex{__doc__}
+  \ttindex{__name__}
+  \ttindex{__module__}
+  \ttindex{__dict__}
+  \ttindex{func_defaults}
+  \ttindex{func_closure}
+  \ttindex{func_code}
+  \ttindex{func_globals}
+  \ttindex{func_dict}}
+\indexii{global}{namespace}
+
+\item[User-defined methods]
+A user-defined method object combines a class, a class instance (or
+\code{None}) and any callable object (normally a user-defined
+function).
+\obindex{method}
+\obindex{user-defined method}
+\indexii{user-defined}{method}
+
+Special read-only attributes: \member{im_self} is the class instance
+object, \member{im_func} is the function object;
+\member{im_class} is the class of \member{im_self} for bound methods
+or the class that asked for the method for unbound methods;
+\member{__doc__} is the method's documentation (same as
+\code{im_func.__doc__}); \member{__name__} is the method name (same as
+\code{im_func.__name__}); \member{__module__} is the name of the
+module the method was defined in, or \code{None} if unavailable.
+\versionchanged[\member{im_self} used to refer to the class that
+                defined the method]{2.2}
+\withsubitem{(method attribute)}{
+  \ttindex{__doc__}
+  \ttindex{__name__}
+  \ttindex{__module__}
+  \ttindex{im_func}
+  \ttindex{im_self}}
+
+Methods also support accessing (but not setting) the arbitrary
+function attributes on the underlying function object.
+
+User-defined method objects may be created when getting an attribute
+of a class (perhaps via an instance of that class), if that attribute
+is a user-defined function object, an unbound user-defined method object,
+or a class method object.
+When the attribute is a user-defined method object, a new
+method object is only created if the class from which it is being
+retrieved is the same as, or a derived class of, the class stored
+in the original method object; otherwise, the original method object
+is used as it is.
+
+When a user-defined method object is created by retrieving
+a user-defined function object from a class, its \member{im_self}
+attribute is \code{None} and the method object is said to be unbound.
+When one is created by retrieving a user-defined function object
+from a class via one of its instances, its \member{im_self} attribute
+is the instance, and the method object is said to be bound.
+In either case, the new method's \member{im_class} attribute
+is the class from which the retrieval takes place, and
+its \member{im_func} attribute is the original function object.
+\withsubitem{(method attribute)}{
+  \ttindex{im_class}\ttindex{im_func}\ttindex{im_self}}
+
+When a user-defined method object is created by retrieving another
+method object from a class or instance, the behaviour is the same
+as for a function object, except that the \member{im_func} attribute
+of the new instance is not the original method object but its
+\member{im_func} attribute.
+\withsubitem{(method attribute)}{
+  \ttindex{im_func}}
+
+When a user-defined method object is created by retrieving a
+class method object from a class or instance, its \member{im_self}
+attribute is the class itself (the same as the \member{im_class}
+attribute), and its \member{im_func} attribute is the function
+object underlying the class method.
+\withsubitem{(method attribute)}{
+  \ttindex{im_class}\ttindex{im_func}\ttindex{im_self}}
+
+When an unbound user-defined method object is called, the underlying
+function (\member{im_func}) is called, with the restriction that the
+first argument must be an instance of the proper class
+(\member{im_class}) or of a derived class thereof.
+
+When a bound user-defined method object is called, the underlying
+function (\member{im_func}) is called, inserting the class instance
+(\member{im_self}) in front of the argument list.  For instance, when
+\class{C} is a class which contains a definition for a function
+\method{f()}, and \code{x} is an instance of \class{C}, calling
+\code{x.f(1)} is equivalent to calling \code{C.f(x, 1)}.
+
+When a user-defined method object is derived from a class method object,
+the ``class instance'' stored in \member{im_self} will actually be the
+class itself, so that calling either \code{x.f(1)} or \code{C.f(1)} is
+equivalent to calling \code{f(C,1)} where \code{f} is the underlying
+function.
+
+Note that the transformation from function object to (unbound or
+bound) method object happens each time the attribute is retrieved from
+the class or instance.  In some cases, a fruitful optimization is to
+assign the attribute to a local variable and call that local variable.
+Also notice that this transformation only happens for user-defined
+functions; other callable objects (and all non-callable objects) are
+retrieved without transformation.  It is also important to note that
+user-defined functions which are attributes of a class instance are
+not converted to bound methods; this \emph{only} happens when the
+function is an attribute of the class.
+
+\item[Generator functions\index{generator!function}\index{generator!iterator}]
+A function or method which uses the \keyword{yield} statement (see
+section~\ref{yield}, ``The \keyword{yield} statement'') is called a
+\dfn{generator function}.  Such a function, when called, always
+returns an iterator object which can be used to execute the body of
+the function:  calling the iterator's \method{next()} method will
+cause the function to execute until it provides a value using the
+\keyword{yield} statement.  When the function executes a
+\keyword{return} statement or falls off the end, a
+\exception{StopIteration} exception is raised and the iterator will
+have reached the end of the set of values to be returned.
+
+\item[Built-in functions]
+A built-in function object is a wrapper around a C function.  Examples
+of built-in functions are \function{len()} and \function{math.sin()}
+(\module{math} is a standard built-in module).
+The number and type of the arguments are
+determined by the C function.
+Special read-only attributes: \member{__doc__} is the function's
+documentation string, or \code{None} if unavailable; \member{__name__}
+is the function's name; \member{__self__} is set to \code{None} (but see
+the next item); \member{__module__} is the name of the module the
+function was defined in or \code{None} if unavailable.
+\obindex{built-in function}
+\obindex{function}
+\indexii{C}{language}
+
+\item[Built-in methods]
+This is really a different disguise of a built-in function, this time
+containing an object passed to the C function as an implicit extra
+argument.  An example of a built-in method is
+\code{\var{alist}.append()}, assuming
+\var{alist} is a list object.
+In this case, the special read-only attribute \member{__self__} is set
+to the object denoted by \var{list}.
+\obindex{built-in method}
+\obindex{method}
+\indexii{built-in}{method}
+
+\item[Class Types]
+Class types, or ``new-style classes,'' are callable.  These objects
+normally act as factories for new instances of themselves, but
+variations are possible for class types that override
+\method{__new__()}.  The arguments of the call are passed to
+\method{__new__()} and, in the typical case, to \method{__init__()} to
+initialize the new instance.
+
+\item[Classic Classes]
+Class objects are described below.  When a class object is called,
+a new class instance (also described below) is created and
+returned.  This implies a call to the class's \method{__init__()} method
+if it has one.  Any arguments are passed on to the \method{__init__()}
+method.  If there is no \method{__init__()} method, the class must be called
+without arguments.
+\withsubitem{(object method)}{\ttindex{__init__()}}
+\obindex{class}
+\obindex{class instance}
+\obindex{instance}
+\indexii{class object}{call}
+
+\item[Class instances]
+Class instances are described below.  Class instances are callable
+only when the class has a \method{__call__()} method; \code{x(arguments)}
+is a shorthand for \code{x.__call__(arguments)}.
+
+\end{description}
+
+\item[Modules]
+Modules are imported by the \keyword{import} statement (see
+section~\ref{import}, ``The \keyword{import} statement'').%
+\stindex{import}\obindex{module}
+A module object has a namespace implemented by a dictionary object
+(this is the dictionary referenced by the func_globals attribute of
+functions defined in the module).  Attribute references are translated
+to lookups in this dictionary, e.g., \code{m.x} is equivalent to
+\code{m.__dict__["x"]}.
+A module object does not contain the code object used to
+initialize the module (since it isn't needed once the initialization
+is done).
+
+Attribute assignment updates the module's namespace dictionary,
+e.g., \samp{m.x = 1} is equivalent to \samp{m.__dict__["x"] = 1}.
+
+Special read-only attribute: \member{__dict__} is the module's
+namespace as a dictionary object.
+\withsubitem{(module attribute)}{\ttindex{__dict__}}
+
+Predefined (writable) attributes: \member{__name__}
+is the module's name; \member{__doc__} is the
+module's documentation string, or
+\code{None} if unavailable; \member{__file__} is the pathname of the
+file from which the module was loaded, if it was loaded from a file.
+The \member{__file__} attribute is not present for C{} modules that are
+statically linked into the interpreter; for extension modules loaded
+dynamically from a shared library, it is the pathname of the shared
+library file.
+\withsubitem{(module attribute)}{
+  \ttindex{__name__}
+  \ttindex{__doc__}
+  \ttindex{__file__}}
+\indexii{module}{namespace}
+
+\item[Classes]
+Class objects are created by class definitions (see
+section~\ref{class}, ``Class definitions'').
+A class has a namespace implemented by a dictionary object.
+Class attribute references are translated to
+lookups in this dictionary,
+e.g., \samp{C.x} is translated to \samp{C.__dict__["x"]}.
+When the attribute name is not found
+there, the attribute search continues in the base classes.  The search
+is depth-first, left-to-right in the order of occurrence in the
+base class list.
+
+When a class attribute reference (for class \class{C}, say)
+would yield a user-defined function object or
+an unbound user-defined method object whose associated class is either
+\class{C} or one of its base classes, it is transformed into an unbound
+user-defined method object whose \member{im_class} attribute is~\class{C}.
+When it would yield a class method object, it is transformed into
+a bound user-defined method object whose \member{im_class} and
+\member{im_self} attributes are both~\class{C}.  When it would yield
+a static method object, it is transformed into the object wrapped
+by the static method object. See section~\ref{descriptors} for another
+way in which attributes retrieved from a class may differ from those
+actually contained in its \member{__dict__}.
+\obindex{class}
+\obindex{class instance}
+\obindex{instance}
+\indexii{class object}{call}
+\index{container}
+\obindex{dictionary}
+\indexii{class}{attribute}
+
+Class attribute assignments update the class's dictionary, never the
+dictionary of a base class.
+\indexiii{class}{attribute}{assignment}
+
+A class object can be called (see above) to yield a class instance (see
+below).
+\indexii{class object}{call}
+
+Special attributes: \member{__name__} is the class name;
+\member{__module__} is the module name in which the class was defined;
+\member{__dict__} is the dictionary containing the class's namespace;
+\member{__bases__} is a tuple (possibly empty or a singleton)
+containing the base classes, in the order of their occurrence in the
+base class list; \member{__doc__} is the class's documentation string,
+or None if undefined.
+\withsubitem{(class attribute)}{
+  \ttindex{__name__}
+  \ttindex{__module__}
+  \ttindex{__dict__}
+  \ttindex{__bases__}
+  \ttindex{__doc__}}
+
+\item[Class instances]
+A class instance is created by calling a class object (see above).
+A class instance has a namespace implemented as a dictionary which
+is the first place in which
+attribute references are searched.  When an attribute is not found
+there, and the instance's class has an attribute by that name,
+the search continues with the class attributes.  If a class attribute
+is found that is a user-defined function object or an unbound
+user-defined method object whose associated class is the class
+(call it~\class{C}) of the instance for which the attribute reference
+was initiated or one of its bases,
+it is transformed into a bound user-defined method object whose
+\member{im_class} attribute is~\class{C} and whose \member{im_self} attribute
+is the instance. Static method and class method objects are also
+transformed, as if they had been retrieved from class~\class{C};
+see above under ``Classes''. See section~\ref{descriptors} for
+another way in which attributes of a class retrieved via its
+instances may differ from the objects actually stored in the
+class's \member{__dict__}.
+If no class attribute is found, and the object's class has a
+\method{__getattr__()} method, that is called to satisfy the lookup.
+\obindex{class instance}
+\obindex{instance}
+\indexii{class}{instance}
+\indexii{class instance}{attribute}
+
+Attribute assignments and deletions update the instance's dictionary,
+never a class's dictionary.  If the class has a \method{__setattr__()} or
+\method{__delattr__()} method, this is called instead of updating the
+instance dictionary directly.
+\indexiii{class instance}{attribute}{assignment}
+
+Class instances can pretend to be numbers, sequences, or mappings if
+they have methods with certain special names.  See
+section~\ref{specialnames}, ``Special method names.''
+\obindex{numeric}
+\obindex{sequence}
+\obindex{mapping}
+
+Special attributes: \member{__dict__} is the attribute
+dictionary; \member{__class__} is the instance's class.
+\withsubitem{(instance attribute)}{
+  \ttindex{__dict__}
+  \ttindex{__class__}}
+
+\item[Files]
+A file\obindex{file} object represents an open file.  File objects are
+created by the \function{open()}\bifuncindex{open} built-in function,
+and also by
+\withsubitem{(in module os)}{\ttindex{popen()}}\function{os.popen()},
+\function{os.fdopen()}, and the
+\method{makefile()}\withsubitem{(socket method)}{\ttindex{makefile()}}
+method of socket objects (and perhaps by other functions or methods
+provided by extension modules).  The objects
+\ttindex{sys.stdin}\code{sys.stdin},
+\ttindex{sys.stdout}\code{sys.stdout} and
+\ttindex{sys.stderr}\code{sys.stderr} are initialized to file objects
+corresponding to the interpreter's standard\index{stdio} input, output
+and error streams.  See the \citetitle[../lib/lib.html]{Python Library
+Reference} for complete documentation of file objects.
+\withsubitem{(in module sys)}{
+  \ttindex{stdin}
+  \ttindex{stdout}
+  \ttindex{stderr}}
+
+
+\item[Internal types]
+A few types used internally by the interpreter are exposed to the user.
+Their definitions may change with future versions of the interpreter,
+but they are mentioned here for completeness.
+\index{internal type}
+\index{types, internal}
+
+\begin{description}
+
+\item[Code objects]
+Code objects represent \emph{byte-compiled} executable Python code, or 
+\emph{bytecode}.
+The difference between a code
+object and a function object is that the function object contains an
+explicit reference to the function's globals (the module in which it
+was defined), while a code object contains no context; 
+also the default argument values are stored in the function object,
+not in the code object (because they represent values calculated at
+run-time).  Unlike function objects, code objects are immutable and
+contain no references (directly or indirectly) to mutable objects.
+\index{bytecode}
+\obindex{code}
+
+Special read-only attributes: \member{co_name} gives the function
+name; \member{co_argcount} is the number of positional arguments
+(including arguments with default values); \member{co_nlocals} is the
+number of local variables used by the function (including arguments);
+\member{co_varnames} is a tuple containing the names of the local
+variables (starting with the argument names); \member{co_cellvars} is
+a tuple containing the names of local variables that are referenced by
+nested functions; \member{co_freevars} is a tuple containing the names
+of free variables; \member{co_code} is a string representing the
+sequence of bytecode instructions;
+\member{co_consts} is a tuple containing the literals used by the
+bytecode; \member{co_names} is a tuple containing the names used by
+the bytecode; \member{co_filename} is the filename from which the code
+was compiled; \member{co_firstlineno} is the first line number of the
+function; \member{co_lnotab} is a string encoding the mapping from
+byte code offsets to line numbers (for details see the source code of
+the interpreter); \member{co_stacksize} is the required stack size
+(including local variables); \member{co_flags} is an integer encoding
+a number of flags for the interpreter.
+
+\withsubitem{(code object attribute)}{
+  \ttindex{co_argcount}
+  \ttindex{co_code}
+  \ttindex{co_consts}
+  \ttindex{co_filename}
+  \ttindex{co_firstlineno}
+  \ttindex{co_flags}
+  \ttindex{co_lnotab}
+  \ttindex{co_name}
+  \ttindex{co_names}
+  \ttindex{co_nlocals}
+  \ttindex{co_stacksize}
+  \ttindex{co_varnames}
+  \ttindex{co_cellvars}
+  \ttindex{co_freevars}}
+
+The following flag bits are defined for \member{co_flags}: bit
+\code{0x04} is set if the function uses the \samp{*arguments} syntax
+to accept an arbitrary number of positional arguments; bit
+\code{0x08} is set if the function uses the \samp{**keywords} syntax
+to accept arbitrary keyword arguments; bit \code{0x20} is set if the
+function is a generator.
+\obindex{generator}
+
+Future feature declarations (\samp{from __future__ import division})
+also use bits in \member{co_flags} to indicate whether a code object
+was compiled with a particular feature enabled: bit \code{0x2000} is
+set if the function was compiled with future division enabled; bits
+\code{0x10} and \code{0x1000} were used in earlier versions of Python.
+
+Other bits in \member{co_flags} are reserved for internal use.
+
+If\index{documentation string} a code object represents a function,
+the first item in
+\member{co_consts} is the documentation string of the function, or
+\code{None} if undefined.
+
+\item[Frame objects]
+Frame objects represent execution frames.  They may occur in traceback
+objects (see below).
+\obindex{frame}
+
+Special read-only attributes: \member{f_back} is to the previous
+stack frame (towards the caller), or \code{None} if this is the bottom
+stack frame; \member{f_code} is the code object being executed in this
+frame; \member{f_locals} is the dictionary used to look up local
+variables; \member{f_globals} is used for global variables;
+\member{f_builtins} is used for built-in (intrinsic) names;
+\member{f_restricted} is a flag indicating whether the function is
+executing in restricted execution mode; \member{f_lasti} gives the
+precise instruction (this is an index into the bytecode string of
+the code object).
+\withsubitem{(frame attribute)}{
+  \ttindex{f_back}
+  \ttindex{f_code}
+  \ttindex{f_globals}
+  \ttindex{f_locals}
+  \ttindex{f_lasti}
+  \ttindex{f_builtins}
+  \ttindex{f_restricted}}
+
+Special writable attributes: \member{f_trace}, if not \code{None}, is
+a function called at the start of each source code line (this is used
+by the debugger); \member{f_exc_type}, \member{f_exc_value},
+\member{f_exc_traceback} represent the last exception raised in the
+parent frame provided another exception was ever raised in the current
+frame (in all other cases they are None); \member{f_lineno} is the
+current line number of the frame --- writing to this from within a
+trace function jumps to the given line (only for the bottom-most
+frame).  A debugger can implement a Jump command (aka Set Next
+Statement) by writing to f_lineno.
+\withsubitem{(frame attribute)}{
+  \ttindex{f_trace}
+  \ttindex{f_exc_type}
+  \ttindex{f_exc_value}
+  \ttindex{f_exc_traceback}
+  \ttindex{f_lineno}}
+
+\item[Traceback objects] \label{traceback}
+Traceback objects represent a stack trace of an exception.  A
+traceback object is created when an exception occurs.  When the search
+for an exception handler unwinds the execution stack, at each unwound
+level a traceback object is inserted in front of the current
+traceback.  When an exception handler is entered, the stack trace is
+made available to the program.
+(See section~\ref{try}, ``The \code{try} statement.'')
+It is accessible as \code{sys.exc_traceback}, and also as the third
+item of the tuple returned by \code{sys.exc_info()}.  The latter is
+the preferred interface, since it works correctly when the program is
+using multiple threads.
+When the program contains no suitable handler, the stack trace is written
+(nicely formatted) to the standard error stream; if the interpreter is
+interactive, it is also made available to the user as
+\code{sys.last_traceback}.
+\obindex{traceback}
+\indexii{stack}{trace}
+\indexii{exception}{handler}
+\indexii{execution}{stack}
+\withsubitem{(in module sys)}{
+  \ttindex{exc_info}
+  \ttindex{exc_traceback}
+  \ttindex{last_traceback}}
+\ttindex{sys.exc_info}
+\ttindex{sys.exc_traceback}
+\ttindex{sys.last_traceback}
+
+Special read-only attributes: \member{tb_next} is the next level in the
+stack trace (towards the frame where the exception occurred), or
+\code{None} if there is no next level; \member{tb_frame} points to the
+execution frame of the current level; \member{tb_lineno} gives the line
+number where the exception occurred; \member{tb_lasti} indicates the
+precise instruction.  The line number and last instruction in the
+traceback may differ from the line number of its frame object if the
+exception occurred in a \keyword{try} statement with no matching
+except clause or with a finally clause.
+\withsubitem{(traceback attribute)}{
+  \ttindex{tb_next}
+  \ttindex{tb_frame}
+  \ttindex{tb_lineno}
+  \ttindex{tb_lasti}}
+\stindex{try}
+
+\item[Slice objects]
+Slice objects are used to represent slices when \emph{extended slice
+syntax} is used.  This is a slice using two colons, or multiple slices
+or ellipses separated by commas, e.g., \code{a[i:j:step]}, \code{a[i:j,
+k:l]}, or \code{a[..., i:j]}.  They are also created by the built-in
+\function{slice()}\bifuncindex{slice} function.
+
+Special read-only attributes: \member{start} is the lower bound;
+\member{stop} is the upper bound; \member{step} is the step value; each is
+\code{None} if omitted. These attributes can have any type.
+\withsubitem{(slice object attribute)}{
+  \ttindex{start}
+  \ttindex{stop}
+  \ttindex{step}}
+
+Slice objects support one method:
+
+\begin{methoddesc}[slice]{indices}{self, length}
+This method takes a single integer argument \var{length} and computes
+information about the extended slice that the slice object would
+describe if applied to a sequence of \var{length} items.  It returns a
+tuple of three integers; respectively these are the \var{start} and
+\var{stop} indices and the \var{step} or stride length of the slice.
+Missing or out-of-bounds indices are handled in a manner consistent
+with regular slices.
+\versionadded{2.3}
+\end{methoddesc}
+
+\item[Static method objects]
+Static method objects provide a way of defeating the transformation
+of function objects to method objects described above. A static method
+object is a wrapper around any other object, usually a user-defined
+method object. When a static method object is retrieved from a class
+or a class instance, the object actually returned is the wrapped object,
+which is not subject to any further transformation. Static method
+objects are not themselves callable, although the objects they
+wrap usually are. Static method objects are created by the built-in
+\function{staticmethod()} constructor.
+
+\item[Class method objects]
+A class method object, like a static method object, is a wrapper
+around another object that alters the way in which that object
+is retrieved from classes and class instances. The behaviour of
+class method objects upon such retrieval is described above,
+under ``User-defined methods''. Class method objects are created
+by the built-in \function{classmethod()} constructor.
+
+\end{description} % Internal types
+
+\end{description} % Types
+
+%=========================================================================
+\section{New-style and classic classes}
+
+Classes and instances come in two flavors: old-style or classic, and new-style.  
+
+Up to Python 2.1, old-style classes were the only flavour available to the
+user.  The concept of (old-style) class is unrelated to the concept of type: if
+\var{x} is an instance of an old-style class, then \code{x.__class__}
+designates the class of \var{x}, but \code{type(x)} is always \code{<type
+'instance'>}.  This reflects the fact that all old-style instances,
+independently of their class, are implemented with a single built-in type,
+called \code{instance}.
+
+New-style classes were introduced in Python 2.2 to unify classes and types.  A
+new-style class neither more nor less than a user-defined type.  If \var{x} is
+an instance of a new-style class, then \code{type(x)} is the same as
+\code{x.__class__}.
+
+The major motivation for introducing new-style classes is to provide a unified
+object model with a full meta-model.  It also has a number of immediate
+benefits, like the ability to subclass most built-in types, or the introduction
+of "descriptors", which enable computed properties.
+
+For compatibility reasons, classes are still old-style by default.  New-style
+classes are created by specifying another new-style class (i.e.\ a type) as a
+parent class, or the "top-level type" \class{object} if no other parent is
+needed.  The behaviour of new-style classes differs from that of old-style
+classes in a number of important details in addition to what \function{type}
+returns.  Some of these changes are fundamental to the new object model, like
+the way special methods are invoked.  Others are "fixes" that could not be
+implemented before for compatibility concerns, like the method resolution order
+in case of multiple inheritance.
+
+This manual is not up-to-date with respect to new-style classes.  For now,
+please see \url{http://www.python.org/doc/newstyle.html} for more information.
+
+The plan is to eventually drop old-style classes, leaving only the semantics of
+new-style classes.  This change will probably only be feasible in Python 3.0.
+\index{class}{new-style}
+\index{class}{classic}
+\index{class}{old-style}
+
+%=========================================================================
+\section{Special method names\label{specialnames}}
+
+A class can implement certain operations that are invoked by special
+syntax (such as arithmetic operations or subscripting and slicing) by
+defining methods with special names.\indexii{operator}{overloading}
+This is Python's approach to \dfn{operator overloading}, allowing
+classes to define their own behavior with respect to language
+operators.  For instance, if a class defines
+a method named \method{__getitem__()}, and \code{x} is an instance of
+this class, then \code{x[i]} is equivalent\footnote{This, and other
+statements, are only roughly true for instances of new-style
+classes.} to
+\code{x.__getitem__(i)}.  Except where mentioned, attempts to execute
+an operation raise an exception when no appropriate method is defined.
+\withsubitem{(mapping object method)}{\ttindex{__getitem__()}}
+
+When implementing a class that emulates any built-in type, it is
+important that the emulation only be implemented to the degree that it
+makes sense for the object being modelled.  For example, some
+sequences may work well with retrieval of individual elements, but
+extracting a slice may not make sense.  (One example of this is the
+\class{NodeList} interface in the W3C's Document Object Model.)
+
+
+\subsection{Basic customization\label{customization}}
+
+\begin{methoddesc}[object]{__new__}{cls\optional{, \moreargs}}
+Called to create a new instance of class \var{cls}.  \method{__new__()}
+is a static method (special-cased so you need not declare it as such)
+that takes the class of which an instance was requested as its first
+argument.  The remaining arguments are those passed to the object
+constructor expression (the call to the class).  The return value of
+\method{__new__()} should be the new object instance (usually an
+instance of \var{cls}).
+
+Typical implementations create a new instance of the class by invoking
+the superclass's \method{__new__()} method using
+\samp{super(\var{currentclass}, \var{cls}).__new__(\var{cls}[, ...])}
+with appropriate arguments and then modifying the newly-created instance
+as necessary before returning it.
+
+If \method{__new__()} returns an instance of \var{cls}, then the new
+instance's \method{__init__()} method will be invoked like
+\samp{__init__(\var{self}[, ...])}, where \var{self} is the new instance
+and the remaining arguments are the same as were passed to
+\method{__new__()}.
+
+If \method{__new__()} does not return an instance of \var{cls}, then the
+new instance's \method{__init__()} method will not be invoked.
+
+\method{__new__()} is intended mainly to allow subclasses of
+immutable types (like int, str, or tuple) to customize instance
+creation.
+\end{methoddesc}
+
+\begin{methoddesc}[object]{__init__}{self\optional{, \moreargs}}
+Called\indexii{class}{constructor} when the instance is created.  The
+arguments are those passed to the class constructor expression.  If a
+base class has an \method{__init__()} method, the derived class's
+\method{__init__()} method, if any, must explicitly call it to ensure proper
+initialization of the base class part of the instance; for example:
+\samp{BaseClass.__init__(\var{self}, [\var{args}...])}.  As a special
+constraint on constructors, no value may be returned; doing so will
+cause a \exception{TypeError} to be raised at runtime.
+\end{methoddesc}
+
+
+\begin{methoddesc}[object]{__del__}{self}
+Called when the instance is about to be destroyed.  This is also
+called a destructor\index{destructor}.  If a base class
+has a \method{__del__()} method, the derived class's \method{__del__()}
+method, if any,
+must explicitly call it to ensure proper deletion of the base class
+part of the instance.  Note that it is possible (though not recommended!)
+for the \method{__del__()}
+method to postpone destruction of the instance by creating a new
+reference to it.  It may then be called at a later time when this new
+reference is deleted.  It is not guaranteed that
+\method{__del__()} methods are called for objects that still exist when
+the interpreter exits.
+\stindex{del}
+
+\begin{notice}
+\samp{del x} doesn't directly call
+\code{x.__del__()} --- the former decrements the reference count for
+\code{x} by one, and the latter is only called when \code{x}'s reference
+count reaches zero.  Some common situations that may prevent the
+reference count of an object from going to zero include: circular
+references between objects (e.g., a doubly-linked list or a tree data
+structure with parent and child pointers); a reference to the object
+on the stack frame of a function that caught an exception (the
+traceback stored in \code{sys.exc_traceback} keeps the stack frame
+alive); or a reference to the object on the stack frame that raised an
+unhandled exception in interactive mode (the traceback stored in
+\code{sys.last_traceback} keeps the stack frame alive).  The first
+situation can only be remedied by explicitly breaking the cycles; the
+latter two situations can be resolved by storing \code{None} in
+\code{sys.exc_traceback} or \code{sys.last_traceback}.  Circular
+references which are garbage are detected when the option cycle
+detector is enabled (it's on by default), but can only be cleaned up
+if there are no Python-level \method{__del__()} methods involved.
+Refer to the documentation for the \ulink{\module{gc}
+module}{../lib/module-gc.html} for more information about how
+\method{__del__()} methods are handled by the cycle detector,
+particularly the description of the \code{garbage} value.
+\end{notice}
+
+\begin{notice}[warning]
+Due to the precarious circumstances under which
+\method{__del__()} methods are invoked, exceptions that occur during their
+execution are ignored, and a warning is printed to \code{sys.stderr}
+instead.  Also, when \method{__del__()} is invoked in response to a module
+being deleted (e.g., when execution of the program is done), other
+globals referenced by the \method{__del__()} method may already have been
+deleted.  For this reason, \method{__del__()} methods should do the
+absolute minimum needed to maintain external invariants.  Starting with
+version 1.5, Python guarantees that globals whose name begins with a single
+underscore are deleted from their module before other globals are deleted;
+if no other references to such globals exist, this may help in assuring that
+imported modules are still available at the time when the
+\method{__del__()} method is called.
+\end{notice}
+\end{methoddesc}
+
+\begin{methoddesc}[object]{__repr__}{self}
+Called by the \function{repr()}\bifuncindex{repr} built-in function
+and by string conversions (reverse quotes) to compute the ``official''
+string representation of an object.  If at all possible, this should
+look like a valid Python expression that could be used to recreate an
+object with the same value (given an appropriate environment).  If
+this is not possible, a string of the form \samp{<\var{...some useful
+description...}>} should be returned.  The return value must be a
+string object.
+If a class defines \method{__repr__()} but not \method{__str__()},
+then \method{__repr__()} is also used when an ``informal'' string
+representation of instances of that class is required.		     
+
+This is typically used for debugging, so it is important that the
+representation is information-rich and unambiguous.
+\indexii{string}{conversion}
+\indexii{reverse}{quotes}
+\indexii{backward}{quotes}
+\index{back-quotes}
+\end{methoddesc}
+
+\begin{methoddesc}[object]{__str__}{self}
+Called by the \function{str()}\bifuncindex{str} built-in function and
+by the \keyword{print}\stindex{print} statement to compute the
+``informal'' string representation of an object.  This differs from
+\method{__repr__()} in that it does not have to be a valid Python
+expression: a more convenient or concise representation may be used
+instead.  The return value must be a string object.
+\end{methoddesc}
+
+\begin{methoddesc}[object]{__lt__}{self, other}
+\methodline[object]{__le__}{self, other}
+\methodline[object]{__eq__}{self, other}
+\methodline[object]{__ne__}{self, other}
+\methodline[object]{__gt__}{self, other}
+\methodline[object]{__ge__}{self, other}
+\versionadded{2.1}
+These are the so-called ``rich comparison'' methods, and are called
+for comparison operators in preference to \method{__cmp__()} below.
+The correspondence between operator symbols and method names is as
+follows:
+\code{\var{x}<\var{y}} calls \code{\var{x}.__lt__(\var{y})},
+\code{\var{x}<=\var{y}} calls \code{\var{x}.__le__(\var{y})},
+\code{\var{x}==\var{y}} calls \code{\var{x}.__eq__(\var{y})},
+\code{\var{x}!=\var{y}} and \code{\var{x}<>\var{y}} call
+\code{\var{x}.__ne__(\var{y})},
+\code{\var{x}>\var{y}} calls \code{\var{x}.__gt__(\var{y})}, and
+\code{\var{x}>=\var{y}} calls \code{\var{x}.__ge__(\var{y})}.
+
+A rich comparison method may return the singleton \code{NotImplemented} if it
+does not implement the operation for a given pair of arguments.
+By convention, \code{False} and \code{True} are returned for a successful
+comparison. However, these methods can return any value, so if the
+comparison operator is used in a Boolean context (e.g., in the condition
+of an \code{if} statement), Python will call \function{bool()} on the
+value to determine if the result is true or false.
+
+There are no implied relationships among the comparison operators.
+The truth of \code{\var{x}==\var{y}} does not imply that \code{\var{x}!=\var{y}}
+is false.  Accordingly, when defining \method{__eq__()}, one should also
+define \method{__ne__()} so that the operators will behave as expected.
+
+There are no reflected (swapped-argument) versions of these methods
+(to be used when the left argument does not support the operation but
+the right argument does); rather, \method{__lt__()} and
+\method{__gt__()} are each other's reflection, \method{__le__()} and
+\method{__ge__()} are each other's reflection, and \method{__eq__()}
+and \method{__ne__()} are their own reflection.
+
+Arguments to rich comparison methods are never coerced.
+\end{methoddesc}
+
+\begin{methoddesc}[object]{__cmp__}{self, other}
+Called by comparison operations if rich comparison (see above) is not
+defined.  Should return a negative integer if \code{self < other},
+zero if \code{self == other}, a positive integer if \code{self >
+other}.  If no \method{__cmp__()}, \method{__eq__()} or
+\method{__ne__()} operation is defined, class instances are compared
+by object identity (``address'').  See also the description of
+\method{__hash__()} for some important notes on creating objects which
+support custom comparison operations and are usable as dictionary
+keys.
+(Note: the restriction that exceptions are not propagated by
+\method{__cmp__()} has been removed since Python 1.5.)
+\bifuncindex{cmp}
+\index{comparisons}
+\end{methoddesc}
+
+\begin{methoddesc}[object]{__rcmp__}{self, other}
+  \versionchanged[No longer supported]{2.1}
+\end{methoddesc}
+
+\begin{methoddesc}[object]{__hash__}{self}
+Called for the key object for dictionary \obindex{dictionary}
+operations, and by the built-in function
+\function{hash()}\bifuncindex{hash}.  Should return a 32-bit integer
+usable as a hash value
+for dictionary operations.  The only required property is that objects
+which compare equal have the same hash value; it is advised to somehow
+mix together (e.g., using exclusive or) the hash values for the
+components of the object that also play a part in comparison of
+objects.  If a class does not define a \method{__cmp__()} method it should
+not define a \method{__hash__()} operation either; if it defines
+\method{__cmp__()} or \method{__eq__()} but not \method{__hash__()},
+its instances will not be usable as dictionary keys.  If a class
+defines mutable objects and implements a \method{__cmp__()} or
+\method{__eq__()} method, it should not implement \method{__hash__()},
+since the dictionary implementation requires that a key's hash value
+is immutable (if the object's hash value changes, it will be in the
+wrong hash bucket).
+
+\versionchanged[\method{__hash__()} may now also return a long
+integer object; the 32-bit integer is then derived from the hash
+of that object]{2.5}
+
+\withsubitem{(object method)}{\ttindex{__cmp__()}}
+\end{methoddesc}
+
+\begin{methoddesc}[object]{__nonzero__}{self}
+Called to implement truth value testing, and the built-in operation
+\code{bool()}; should return \code{False} or \code{True}, or their
+integer equivalents \code{0} or \code{1}.
+When this method is not defined, \method{__len__()} is
+called, if it is defined (see below).  If a class defines neither
+\method{__len__()} nor \method{__nonzero__()}, all its instances are
+considered true.
+\withsubitem{(mapping object method)}{\ttindex{__len__()}}
+\end{methoddesc}
+
+\begin{methoddesc}[object]{__unicode__}{self}
+Called to implement \function{unicode()}\bifuncindex{unicode} builtin;
+should return a Unicode object. When this method is not defined, string
+conversion is attempted, and the result of string conversion is converted
+to Unicode using the system default encoding.
+\end{methoddesc}
+
+
+\subsection{Customizing attribute access\label{attribute-access}}
+
+The following methods can be defined to customize the meaning of
+attribute access (use of, assignment to, or deletion of \code{x.name})
+for class instances.
+
+\begin{methoddesc}[object]{__getattr__}{self, name}
+Called when an attribute lookup has not found the attribute in the
+usual places (i.e. it is not an instance attribute nor is it found in
+the class tree for \code{self}).  \code{name} is the attribute name.
+This method should return the (computed) attribute value or raise an
+\exception{AttributeError} exception.
+
+Note that if the attribute is found through the normal mechanism,
+\method{__getattr__()} is not called.  (This is an intentional
+asymmetry between \method{__getattr__()} and \method{__setattr__()}.)
+This is done both for efficiency reasons and because otherwise
+\method{__setattr__()} would have no way to access other attributes of
+the instance.  Note that at least for instance variables, you can fake
+total control by not inserting any values in the instance attribute
+dictionary (but instead inserting them in another object).  See the
+\method{__getattribute__()} method below for a way to actually get
+total control in new-style classes.
+\withsubitem{(object method)}{\ttindex{__setattr__()}}
+\end{methoddesc}
+
+\begin{methoddesc}[object]{__setattr__}{self, name, value}
+Called when an attribute assignment is attempted.  This is called
+instead of the normal mechanism (i.e.\ store the value in the instance
+dictionary).  \var{name} is the attribute name, \var{value} is the
+value to be assigned to it.
+
+If \method{__setattr__()} wants to assign to an instance attribute, it 
+should not simply execute \samp{self.\var{name} = value} --- this
+would cause a recursive call to itself.  Instead, it should insert the
+value in the dictionary of instance attributes, e.g.,
+\samp{self.__dict__[\var{name}] = value}.  For new-style classes,
+rather than accessing the instance dictionary, it should call the base
+class method with the same name, for example,
+\samp{object.__setattr__(self, name, value)}.
+\withsubitem{(instance attribute)}{\ttindex{__dict__}}
+\end{methoddesc}
+
+\begin{methoddesc}[object]{__delattr__}{self, name}
+Like \method{__setattr__()} but for attribute deletion instead of
+assignment.  This should only be implemented if \samp{del
+obj.\var{name}} is meaningful for the object.
+\end{methoddesc}
+
+\subsubsection{More attribute access for new-style classes \label{new-style-attribute-access}}
+
+The following methods only apply to new-style classes.
+
+\begin{methoddesc}[object]{__getattribute__}{self, name}
+Called unconditionally to implement attribute accesses for instances
+of the class. If the class also defines \method{__getattr__()}, the latter 
+will not be called unless \method{__getattribute__()} either calls it 
+explicitly or raises an \exception{AttributeError}.
+This method should return the (computed) attribute
+value or raise an \exception{AttributeError} exception.
+In order to avoid infinite recursion in this method, its
+implementation should always call the base class method with the same
+name to access any attributes it needs, for example,
+\samp{object.__getattribute__(self, name)}.
+\end{methoddesc}
+
+\subsubsection{Implementing Descriptors \label{descriptors}}
+
+The following methods only apply when an instance of the class
+containing the method (a so-called \emph{descriptor} class) appears in
+the class dictionary of another new-style class, known as the
+\emph{owner} class. In the examples below, ``the attribute'' refers to
+the attribute whose name is the key of the property in the owner
+class' \code{__dict__}.  Descriptors can only be implemented as
+new-style classes themselves.
+
+\begin{methoddesc}[object]{__get__}{self, instance, owner}
+Called to get the attribute of the owner class (class attribute access)
+or of an instance of that class (instance attribute access).
+\var{owner} is always the owner class, while \var{instance} is the
+instance that the attribute was accessed through, or \code{None} when
+the attribute is accessed through the \var{owner}.  This method should
+return the (computed) attribute value or raise an
+\exception{AttributeError} exception.
+\end{methoddesc}
+
+\begin{methoddesc}[object]{__set__}{self, instance, value}
+Called to set the attribute on an instance \var{instance} of the owner
+class to a new value, \var{value}.
+\end{methoddesc}
+
+\begin{methoddesc}[object]{__delete__}{self, instance}
+Called to delete the attribute on an instance \var{instance} of the
+owner class.
+\end{methoddesc}
+
+
+\subsubsection{Invoking Descriptors \label{descriptor-invocation}}
+
+In general, a descriptor is an object attribute with ``binding behavior'',
+one whose attribute access has been overridden by methods in the descriptor
+protocol:  \method{__get__()}, \method{__set__()}, and \method{__delete__()}.
+If any of those methods are defined for an object, it is said to be a
+descriptor.
+
+The default behavior for attribute access is to get, set, or delete the
+attribute from an object's dictionary. For instance, \code{a.x} has a
+lookup chain starting with \code{a.__dict__['x']}, then
+\code{type(a).__dict__['x']}, and continuing 
+through the base classes of \code{type(a)} excluding metaclasses.
+
+However, if the looked-up value is an object defining one of the descriptor
+methods, then Python may override the default behavior and invoke the
+descriptor method instead.  Where this occurs in the precedence chain depends
+on which descriptor methods were defined and how they were called.  Note that
+descriptors are only invoked for new style objects or classes
+(ones that subclass \class{object()} or \class{type()}).
+
+The starting point for descriptor invocation is a binding, \code{a.x}.
+How the arguments are assembled depends on \code{a}:
+
+\begin{itemize}
+                      
+  \item[Direct Call] The simplest and least common call is when user code
+    directly invokes a descriptor method:    \code{x.__get__(a)}.
+
+  \item[Instance Binding]  If binding to a new-style object instance,
+    \code{a.x} is transformed into the call:
+    \code{type(a).__dict__['x'].__get__(a, type(a))}.
+                     
+  \item[Class Binding]  If binding to a new-style class, \code{A.x}
+    is transformed into the call: \code{A.__dict__['x'].__get__(None, A)}.
+
+  \item[Super Binding] If \code{a} is an instance of \class{super},
+    then the binding \code{super(B, obj).m()} searches
+    \code{obj.__class__.__mro__} for the base class \code{A} immediately
+    preceding \code{B} and then invokes the descriptor with the call:
+    \code{A.__dict__['m'].__get__(obj, A)}.
+                     
+\end{itemize}
+
+For instance bindings, the precedence of descriptor invocation depends
+on the which descriptor methods are defined.  Data descriptors define
+both \method{__get__()} and \method{__set__()}.  Non-data descriptors have
+just the \method{__get__()} method.  Data descriptors always override
+a redefinition in an instance dictionary.  In contrast, non-data
+descriptors can be overridden by instances.
+
+Python methods (including \function{staticmethod()} and \function{classmethod()})
+are implemented as non-data descriptors.  Accordingly, instances can
+redefine and override methods.  This allows individual instances to acquire
+behaviors that differ from other instances of the same class.                     
+
+The \function{property()} function is implemented as a data descriptor.
+Accordingly, instances cannot override the behavior of a property.
+
+
+\subsubsection{__slots__\label{slots}}
+
+By default, instances of both old and new-style classes have a dictionary
+for attribute storage.  This wastes space for objects having very few instance
+variables.  The space consumption can become acute when creating large numbers
+of instances.
+
+The default can be overridden by defining \var{__slots__} in a new-style class
+definition.  The \var{__slots__} declaration takes a sequence of instance
+variables and reserves just enough space in each instance to hold a value
+for each variable.  Space is saved because \var{__dict__} is not created for
+each instance.
+    
+\begin{datadesc}{__slots__}
+This class variable can be assigned a string, iterable, or sequence of strings
+with variable names used by instances.  If defined in a new-style class,
+\var{__slots__} reserves space for the declared variables
+and prevents the automatic creation of \var{__dict__} and \var{__weakref__}
+for each instance.
+\versionadded{2.2}                     
+\end{datadesc}
+
+\noindent
+Notes on using \var{__slots__}
+
+\begin{itemize}
+
+\item Without a \var{__dict__} variable, instances cannot be assigned new
+variables not listed in the \var{__slots__} definition.  Attempts to assign
+to an unlisted variable name raises \exception{AttributeError}. If dynamic
+assignment of new variables is desired, then add \code{'__dict__'} to the
+sequence of strings in the \var{__slots__} declaration.                                     
+\versionchanged[Previously, adding \code{'__dict__'} to the \var{__slots__}
+declaration would not enable the assignment of new attributes not
+specifically listed in the sequence of instance variable names]{2.3}                     
+
+\item Without a \var{__weakref__} variable for each instance, classes
+defining \var{__slots__} do not support weak references to its instances.
+If weak reference support is needed, then add \code{'__weakref__'} to the
+sequence of strings in the \var{__slots__} declaration.                    
+\versionchanged[Previously, adding \code{'__weakref__'} to the \var{__slots__}
+declaration would not enable support for weak references]{2.3}                                            
+
+\item \var{__slots__} are implemented at the class level by creating
+descriptors (\ref{descriptors}) for each variable name.  As a result,
+class attributes cannot be used to set default values for instance
+variables defined by \var{__slots__}; otherwise, the class attribute would
+overwrite the descriptor assignment. 
+
+\item If a class defines a slot also defined in a base class, the instance
+variable defined by the base class slot is inaccessible (except by retrieving
+its descriptor directly from the base class). This renders the meaning of the
+program undefined.  In the future, a check may be added to prevent this.
+
+\item The action of a \var{__slots__} declaration is limited to the class
+where it is defined.  As a result, subclasses will have a \var{__dict__}
+unless they also define  \var{__slots__}.                     
+
+\item \var{__slots__} do not work for classes derived from ``variable-length''
+built-in types such as \class{long}, \class{str} and \class{tuple}. 
+
+\item Any non-string iterable may be assigned to \var{__slots__}.
+Mappings may also be used; however, in the future, special meaning may
+be assigned to the values corresponding to each key.                      
+
+\end{itemize}
+
+
+\subsection{Customizing class creation\label{metaclasses}}
+
+By default, new-style classes are constructed using \function{type()}.
+A class definition is read into a separate namespace and the value
+of class name is bound to the result of \code{type(name, bases, dict)}.
+
+When the class definition is read, if \var{__metaclass__} is defined
+then the callable assigned to it will be called instead of \function{type()}.
+The allows classes or functions to be written which monitor or alter the class
+creation process:
+
+\begin{itemize}
+\item Modifying the class dictionary prior to the class being created.
+\item Returning an instance of another class -- essentially performing
+the role of a factory function.
+\end{itemize}
+
+\begin{datadesc}{__metaclass__}
+This variable can be any callable accepting arguments for \code{name},
+\code{bases}, and \code{dict}.  Upon class creation, the callable is
+used instead of the built-in \function{type()}.
+\versionadded{2.2}                     
+\end{datadesc}
+
+The appropriate metaclass is determined by the following precedence rules:
+
+\begin{itemize}
+
+\item If \code{dict['__metaclass__']} exists, it is used.
+
+\item Otherwise, if there is at least one base class, its metaclass is used
+(this looks for a \var{__class__} attribute first and if not found, uses its
+type).
+
+\item Otherwise, if a global variable named __metaclass__ exists, it is used.
+
+\item Otherwise, the old-style, classic metaclass (types.ClassType) is used.
+
+\end{itemize}      
+
+The potential uses for metaclasses are boundless. Some ideas that have
+been explored including logging, interface checking, automatic delegation,
+automatic property creation, proxies, frameworks, and automatic resource
+locking/synchronization.
+
+
+\subsection{Emulating callable objects\label{callable-types}}
+
+\begin{methoddesc}[object]{__call__}{self\optional{, args...}}
+Called when the instance is ``called'' as a function; if this method
+is defined, \code{\var{x}(arg1, arg2, ...)} is a shorthand for
+\code{\var{x}.__call__(arg1, arg2, ...)}.
+\indexii{call}{instance}
+\end{methoddesc}
+
+
+\subsection{Emulating container types\label{sequence-types}}
+
+The following methods can be defined to implement container
+objects.  Containers usually are sequences (such as lists or tuples)
+or mappings (like dictionaries), but can represent other containers as
+well.  The first set of methods is used either to emulate a
+sequence or to emulate a mapping; the difference is that for a
+sequence, the allowable keys should be the integers \var{k} for which
+\code{0 <= \var{k} < \var{N}} where \var{N} is the length of the
+sequence, or slice objects, which define a range of items. (For backwards
+compatibility, the method \method{__getslice__()} (see below) can also be
+defined to handle simple, but not extended slices.) It is also recommended
+that mappings provide the methods \method{keys()}, \method{values()},
+\method{items()}, \method{has_key()}, \method{get()}, \method{clear()},
+\method{setdefault()}, \method{iterkeys()}, \method{itervalues()},
+\method{iteritems()}, \method{pop()}, \method{popitem()},		     
+\method{copy()}, and \method{update()} behaving similar to those for
+Python's standard dictionary objects.  The \module{UserDict} module
+provides a \class{DictMixin} class to help create those methods
+from a base set of \method{__getitem__()}, \method{__setitem__()},
+\method{__delitem__()}, and \method{keys()}.		     
+Mutable sequences should provide
+methods \method{append()}, \method{count()}, \method{index()},
+\method{extend()},		     
+\method{insert()}, \method{pop()}, \method{remove()}, \method{reverse()}
+and \method{sort()}, like Python standard list objects.  Finally,
+sequence types should implement addition (meaning concatenation) and
+multiplication (meaning repetition) by defining the methods
+\method{__add__()}, \method{__radd__()}, \method{__iadd__()},
+\method{__mul__()}, \method{__rmul__()} and \method{__imul__()} described
+below; they should not define \method{__coerce__()} or other numerical
+operators.  It is recommended that both mappings and sequences
+implement the \method{__contains__()} method to allow efficient use of
+the \code{in} operator; for mappings, \code{in} should be equivalent
+of \method{has_key()}; for sequences, it should search through the
+values.  It is further recommended that both mappings and sequences
+implement the \method{__iter__()} method to allow efficient iteration
+through the container; for mappings, \method{__iter__()} should be
+the same as \method{iterkeys()}; for sequences, it should iterate
+through the values.
+\withsubitem{(mapping object method)}{
+  \ttindex{keys()}
+  \ttindex{values()}
+  \ttindex{items()}
+  \ttindex{iterkeys()}
+  \ttindex{itervalues()}
+  \ttindex{iteritems()}    
+  \ttindex{has_key()}
+  \ttindex{get()}
+  \ttindex{setdefault()}
+  \ttindex{pop()}      
+  \ttindex{popitem()}    
+  \ttindex{clear()}
+  \ttindex{copy()}
+  \ttindex{update()}
+  \ttindex{__contains__()}}
+\withsubitem{(sequence object method)}{
+  \ttindex{append()}
+  \ttindex{count()}
+  \ttindex{extend()}    
+  \ttindex{index()}
+  \ttindex{insert()}
+  \ttindex{pop()}
+  \ttindex{remove()}
+  \ttindex{reverse()}
+  \ttindex{sort()}
+  \ttindex{__add__()}
+  \ttindex{__radd__()}
+  \ttindex{__iadd__()}
+  \ttindex{__mul__()}
+  \ttindex{__rmul__()}
+  \ttindex{__imul__()}
+  \ttindex{__contains__()}
+  \ttindex{__iter__()}}		     
+\withsubitem{(numeric object method)}{\ttindex{__coerce__()}}
+
+\begin{methoddesc}[container object]{__len__}{self}
+Called to implement the built-in function
+\function{len()}\bifuncindex{len}.  Should return the length of the
+object, an integer \code{>=} 0.  Also, an object that doesn't define a
+\method{__nonzero__()} method and whose \method{__len__()} method
+returns zero is considered to be false in a Boolean context.
+\withsubitem{(object method)}{\ttindex{__nonzero__()}}
+\end{methoddesc}
+
+\begin{methoddesc}[container object]{__getitem__}{self, key}
+Called to implement evaluation of \code{\var{self}[\var{key}]}.
+For sequence types, the accepted keys should be integers and slice
+objects.\obindex{slice}  Note that
+the special interpretation of negative indexes (if the class wishes to
+emulate a sequence type) is up to the \method{__getitem__()} method.
+If \var{key} is of an inappropriate type, \exception{TypeError} may be
+raised; if of a value outside the set of indexes for the sequence
+(after any special interpretation of negative values),
+\exception{IndexError} should be raised.
+For mapping types, if \var{key} is missing (not in the container),
+\exception{KeyError} should be raised.                     
+\note{\keyword{for} loops expect that an
+\exception{IndexError} will be raised for illegal indexes to allow
+proper detection of the end of the sequence.}
+\end{methoddesc}
+
+\begin{methoddesc}[container object]{__setitem__}{self, key, value}
+Called to implement assignment to \code{\var{self}[\var{key}]}.  Same
+note as for \method{__getitem__()}.  This should only be implemented
+for mappings if the objects support changes to the values for keys, or
+if new keys can be added, or for sequences if elements can be
+replaced.  The same exceptions should be raised for improper
+\var{key} values as for the \method{__getitem__()} method.
+\end{methoddesc}
+
+\begin{methoddesc}[container object]{__delitem__}{self, key}
+Called to implement deletion of \code{\var{self}[\var{key}]}.  Same
+note as for \method{__getitem__()}.  This should only be implemented
+for mappings if the objects support removal of keys, or for sequences
+if elements can be removed from the sequence.  The same exceptions
+should be raised for improper \var{key} values as for the
+\method{__getitem__()} method.
+\end{methoddesc}
+
+\begin{methoddesc}[container object]{__iter__}{self}
+This method is called when an iterator is required for a container.
+This method should return a new iterator object that can iterate over
+all the objects in the container.  For mappings, it should iterate
+over the keys of the container, and should also be made available as
+the method \method{iterkeys()}.
+
+Iterator objects also need to implement this method; they are required
+to return themselves.  For more information on iterator objects, see
+``\ulink{Iterator Types}{../lib/typeiter.html}'' in the
+\citetitle[../lib/lib.html]{Python Library Reference}.
+\end{methoddesc}
+
+The membership test operators (\keyword{in} and \keyword{not in}) are
+normally implemented as an iteration through a sequence.  However,
+container objects can supply the following special method with a more
+efficient implementation, which also does not require the object be a
+sequence.
+
+\begin{methoddesc}[container object]{__contains__}{self, item}
+Called to implement membership test operators.  Should return true if
+\var{item} is in \var{self}, false otherwise.  For mapping objects,
+this should consider the keys of the mapping rather than the values or
+the key-item pairs.
+\end{methoddesc}
+
+
+\subsection{Additional methods for emulation of sequence types
+  \label{sequence-methods}}
+
+The following optional methods can be defined to further emulate sequence
+objects.  Immutable sequences methods should at most only define
+\method{__getslice__()}; mutable sequences might define all three
+methods.
+
+\begin{methoddesc}[sequence object]{__getslice__}{self, i, j}
+\deprecated{2.0}{Support slice objects as parameters to the
+\method{__getitem__()} method.}
+Called to implement evaluation of \code{\var{self}[\var{i}:\var{j}]}.
+The returned object should be of the same type as \var{self}.  Note
+that missing \var{i} or \var{j} in the slice expression are replaced
+by zero or \code{sys.maxint}, respectively.  If negative indexes are
+used in the slice, the length of the sequence is added to that index.
+If the instance does not implement the \method{__len__()} method, an
+\exception{AttributeError} is raised.
+No guarantee is made that indexes adjusted this way are not still
+negative.  Indexes which are greater than the length of the sequence
+are not modified.
+If no \method{__getslice__()} is found, a slice
+object is created instead, and passed to \method{__getitem__()} instead.
+\end{methoddesc}
+
+\begin{methoddesc}[sequence object]{__setslice__}{self, i, j, sequence}
+Called to implement assignment to \code{\var{self}[\var{i}:\var{j}]}.
+Same notes for \var{i} and \var{j} as for \method{__getslice__()}.
+
+This method is deprecated. If no \method{__setslice__()} is found,
+or for extended slicing of the form
+\code{\var{self}[\var{i}:\var{j}:\var{k}]}, a
+slice object is created, and passed to \method{__setitem__()},
+instead of \method{__setslice__()} being called.
+\end{methoddesc}
+
+\begin{methoddesc}[sequence object]{__delslice__}{self, i, j}
+Called to implement deletion of \code{\var{self}[\var{i}:\var{j}]}.
+Same notes for \var{i} and \var{j} as for \method{__getslice__()}.
+This method is deprecated. If no \method{__delslice__()} is found,
+or for extended slicing of the form
+\code{\var{self}[\var{i}:\var{j}:\var{k}]}, a
+slice object is created, and passed to \method{__delitem__()},
+instead of \method{__delslice__()} being called.
+\end{methoddesc}
+
+Notice that these methods are only invoked when a single slice with a
+single colon is used, and the slice method is available.  For slice
+operations involving extended slice notation, or in absence of the
+slice methods, \method{__getitem__()}, \method{__setitem__()} or
+\method{__delitem__()} is called with a slice object as argument.
+
+The following example demonstrate how to make your program or module
+compatible with earlier versions of Python (assuming that methods
+\method{__getitem__()}, \method{__setitem__()} and \method{__delitem__()}
+support slice objects as arguments):
+
+\begin{verbatim}
+class MyClass:
+    ...
+    def __getitem__(self, index):
+        ...
+    def __setitem__(self, index, value):
+        ...
+    def __delitem__(self, index):
+        ...
+
+    if sys.version_info < (2, 0):
+        # They won't be defined if version is at least 2.0 final
+
+        def __getslice__(self, i, j):
+            return self[max(0, i):max(0, j):]
+        def __setslice__(self, i, j, seq):
+            self[max(0, i):max(0, j):] = seq
+        def __delslice__(self, i, j):
+            del self[max(0, i):max(0, j):]
+    ...
+\end{verbatim}
+
+Note the calls to \function{max()}; these are necessary because of
+the handling of negative indices before the
+\method{__*slice__()} methods are called.  When negative indexes are
+used, the \method{__*item__()} methods receive them as provided, but
+the \method{__*slice__()} methods get a ``cooked'' form of the index
+values.  For each negative index value, the length of the sequence is
+added to the index before calling the method (which may still result
+in a negative index); this is the customary handling of negative
+indexes by the built-in sequence types, and the \method{__*item__()}
+methods are expected to do this as well.  However, since they should
+already be doing that, negative indexes cannot be passed in; they must
+be constrained to the bounds of the sequence before being passed to
+the \method{__*item__()} methods.
+Calling \code{max(0, i)} conveniently returns the proper value.
+
+
+\subsection{Emulating numeric types\label{numeric-types}}
+
+The following methods can be defined to emulate numeric objects.
+Methods corresponding to operations that are not supported by the
+particular kind of number implemented (e.g., bitwise operations for
+non-integral numbers) should be left undefined.
+
+\begin{methoddesc}[numeric object]{__add__}{self, other}
+\methodline[numeric object]{__sub__}{self, other}
+\methodline[numeric object]{__mul__}{self, other}
+\methodline[numeric object]{__floordiv__}{self, other}
+\methodline[numeric object]{__mod__}{self, other}
+\methodline[numeric object]{__divmod__}{self, other}
+\methodline[numeric object]{__pow__}{self, other\optional{, modulo}}
+\methodline[numeric object]{__lshift__}{self, other}
+\methodline[numeric object]{__rshift__}{self, other}
+\methodline[numeric object]{__and__}{self, other}
+\methodline[numeric object]{__xor__}{self, other}
+\methodline[numeric object]{__or__}{self, other}
+These methods are
+called to implement the binary arithmetic operations (\code{+},
+\code{-}, \code{*}, \code{//}, \code{\%},
+\function{divmod()}\bifuncindex{divmod},
+\function{pow()}\bifuncindex{pow}, \code{**}, \code{<<},
+\code{>>}, \code{\&}, \code{\^}, \code{|}).  For instance, to
+evaluate the expression \var{x}\code{+}\var{y}, where \var{x} is an
+instance of a class that has an \method{__add__()} method,
+\code{\var{x}.__add__(\var{y})} is called.  The \method{__divmod__()}
+method should be the equivalent to using \method{__floordiv__()} and
+\method{__mod__()}; it should not be related to \method{__truediv__()}
+(described below).  Note that
+\method{__pow__()} should be defined to accept an optional third
+argument if the ternary version of the built-in
+\function{pow()}\bifuncindex{pow} function is to be supported.
+
+If one of those methods does not support the operation with the
+supplied arguments, it should return \code{NotImplemented}.
+\end{methoddesc}
+
+\begin{methoddesc}[numeric object]{__div__}{self, other}
+\methodline[numeric object]{__truediv__}{self, other}
+The division operator (\code{/}) is implemented by these methods.  The
+\method{__truediv__()} method is used when \code{__future__.division}
+is in effect, otherwise \method{__div__()} is used.  If only one of
+these two methods is defined, the object will not support division in
+the alternate context; \exception{TypeError} will be raised instead.
+\end{methoddesc}
+
+\begin{methoddesc}[numeric object]{__radd__}{self, other}
+\methodline[numeric object]{__rsub__}{self, other}
+\methodline[numeric object]{__rmul__}{self, other}
+\methodline[numeric object]{__rdiv__}{self, other}
+\methodline[numeric object]{__rtruediv__}{self, other}
+\methodline[numeric object]{__rfloordiv__}{self, other}	     
+\methodline[numeric object]{__rmod__}{self, other}
+\methodline[numeric object]{__rdivmod__}{self, other}
+\methodline[numeric object]{__rpow__}{self, other}
+\methodline[numeric object]{__rlshift__}{self, other}
+\methodline[numeric object]{__rrshift__}{self, other}
+\methodline[numeric object]{__rand__}{self, other}
+\methodline[numeric object]{__rxor__}{self, other}
+\methodline[numeric object]{__ror__}{self, other}
+These methods are
+called to implement the binary arithmetic operations (\code{+},
+\code{-}, \code{*}, \code{/}, \code{\%},
+\function{divmod()}\bifuncindex{divmod},
+\function{pow()}\bifuncindex{pow}, \code{**}, \code{<<},
+\code{>>}, \code{\&}, \code{\^}, \code{|}) with reflected
+(swapped) operands.  These functions are only called if the left
+operand does not support the corresponding operation and the
+operands are of different types.\footnote{
+    For operands of the same type, it is assumed that if the
+    non-reflected method (such as \method{__add__()}) fails the
+    operation is not supported, which is why the reflected method
+    is not called.} 
+For instance, to evaluate the expression \var{x}\code{-}\var{y},
+where \var{y} is an instance of a class that has an
+\method{__rsub__()} method, \code{\var{y}.__rsub__(\var{x})}
+is called if \code{\var{x}.__sub__(\var{y})} returns
+\var{NotImplemented}.
+
+Note that ternary
+\function{pow()}\bifuncindex{pow} will not try calling
+\method{__rpow__()} (the coercion rules would become too
+complicated).
+
+\note{If the right operand's type is a subclass of the left operand's
+      type and that subclass provides the reflected method for the
+      operation, this method will be called before the left operand's
+      non-reflected method.  This behavior allows subclasses to
+      override their ancestors' operations.}
+\end{methoddesc}
+
+\begin{methoddesc}[numeric object]{__iadd__}{self, other}
+\methodline[numeric object]{__isub__}{self, other}
+\methodline[numeric object]{__imul__}{self, other}
+\methodline[numeric object]{__idiv__}{self, other}
+\methodline[numeric object]{__itruediv__}{self, other}
+\methodline[numeric object]{__ifloordiv__}{self, other}
+\methodline[numeric object]{__imod__}{self, other}		     
+\methodline[numeric object]{__ipow__}{self, other\optional{, modulo}}
+\methodline[numeric object]{__ilshift__}{self, other}
+\methodline[numeric object]{__irshift__}{self, other}
+\methodline[numeric object]{__iand__}{self, other}
+\methodline[numeric object]{__ixor__}{self, other}
+\methodline[numeric object]{__ior__}{self, other}
+These methods are called to implement the augmented arithmetic
+operations (\code{+=}, \code{-=}, \code{*=}, \code{/=}, \code{//=},
+\code{\%=}, \code{**=}, \code{<<=}, \code{>>=}, \code{\&=},
+\code{\textasciicircum=}, \code{|=}).  These methods should attempt to do the
+operation in-place (modifying \var{self}) and return the result (which
+could be, but does not have to be, \var{self}).  If a specific method
+is not defined, the augmented operation falls back to the normal
+methods.  For instance, to evaluate the expression
+\var{x}\code{+=}\var{y}, where \var{x} is an instance of a class that
+has an \method{__iadd__()} method, \code{\var{x}.__iadd__(\var{y})} is
+called.  If \var{x} is an instance of a class that does not define a
+\method{__iadd__()} method, \code{\var{x}.__add__(\var{y})} and
+\code{\var{y}.__radd__(\var{x})} are considered, as with the
+evaluation of \var{x}\code{+}\var{y}.
+\end{methoddesc}
+
+\begin{methoddesc}[numeric object]{__neg__}{self}
+\methodline[numeric object]{__pos__}{self}
+\methodline[numeric object]{__abs__}{self}
+\methodline[numeric object]{__invert__}{self}
+Called to implement the unary arithmetic operations (\code{-},
+\code{+}, \function{abs()}\bifuncindex{abs} and \code{\~{}}).
+\end{methoddesc}
+
+\begin{methoddesc}[numeric object]{__complex__}{self}
+\methodline[numeric object]{__int__}{self}
+\methodline[numeric object]{__long__}{self}
+\methodline[numeric object]{__float__}{self}
+Called to implement the built-in functions
+\function{complex()}\bifuncindex{complex},
+\function{int()}\bifuncindex{int}, \function{long()}\bifuncindex{long},
+and \function{float()}\bifuncindex{float}.  Should return a value of
+the appropriate type.
+\end{methoddesc}
+
+\begin{methoddesc}[numeric object]{__oct__}{self}
+\methodline[numeric object]{__hex__}{self}
+Called to implement the built-in functions
+\function{oct()}\bifuncindex{oct} and
+\function{hex()}\bifuncindex{hex}.  Should return a string value.
+\end{methoddesc}
+
+\begin{methoddesc}[numeric object]{__index__}{self}
+Called to implement \function{operator.index()}.  Also called whenever
+Python needs an integer object (such as in slicing).  Must return an
+integer (int or long).
+\versionadded{2.5}
+\end{methoddesc}
+
+\begin{methoddesc}[numeric object]{__coerce__}{self, other}
+Called to implement ``mixed-mode'' numeric arithmetic.  Should either
+return a 2-tuple containing \var{self} and \var{other} converted to
+a common numeric type, or \code{None} if conversion is impossible.  When
+the common type would be the type of \code{other}, it is sufficient to
+return \code{None}, since the interpreter will also ask the other
+object to attempt a coercion (but sometimes, if the implementation of
+the other type cannot be changed, it is useful to do the conversion to
+the other type here).  A return value of \code{NotImplemented} is
+equivalent to returning \code{None}.
+\end{methoddesc}
+
+\subsection{Coercion rules\label{coercion-rules}}
+
+This section used to document the rules for coercion.  As the language
+has evolved, the coercion rules have become hard to document
+precisely; documenting what one version of one particular
+implementation does is undesirable.  Instead, here are some informal
+guidelines regarding coercion.  In Python 3.0, coercion will not be
+supported.
+
+\begin{itemize}
+
+\item
+
+If the left operand of a \% operator is a string or Unicode object, no
+coercion takes place and the string formatting operation is invoked
+instead.
+
+\item
+
+It is no longer recommended to define a coercion operation.
+Mixed-mode operations on types that don't define coercion pass the
+original arguments to the operation.
+
+\item
+
+New-style classes (those derived from \class{object}) never invoke the
+\method{__coerce__()} method in response to a binary operator; the only
+time \method{__coerce__()} is invoked is when the built-in function
+\function{coerce()} is called.
+
+\item
+
+For most intents and purposes, an operator that returns
+\code{NotImplemented} is treated the same as one that is not
+implemented at all.
+
+\item
+
+Below, \method{__op__()} and \method{__rop__()} are used to signify
+the generic method names corresponding to an operator;
+\method{__iop__()} is used for the corresponding in-place operator.  For
+example, for the operator `\code{+}', \method{__add__()} and
+\method{__radd__()} are used for the left and right variant of the
+binary operator, and \method{__iadd__()} for the in-place variant.
+
+\item
+
+For objects \var{x} and \var{y}, first \code{\var{x}.__op__(\var{y})}
+is tried.  If this is not implemented or returns \code{NotImplemented},
+\code{\var{y}.__rop__(\var{x})} is tried.  If this is also not
+implemented or returns \code{NotImplemented}, a \exception{TypeError}
+exception is raised.  But see the following exception:
+
+\item
+
+Exception to the previous item: if the left operand is an instance of
+a built-in type or a new-style class, and the right operand is an instance
+of a proper subclass of that type or class and overrides the base's
+\method{__rop__()} method, the right operand's \method{__rop__()} method
+is tried \emph{before} the left operand's \method{__op__()} method.
+
+This is done so that a subclass can completely override binary operators.
+Otherwise, the left operand's \method{__op__()} method would always
+accept the right operand: when an instance of a given class is expected,
+an instance of a subclass of that class is always acceptable.
+
+\item
+
+When either operand type defines a coercion, this coercion is called
+before that type's \method{__op__()} or \method{__rop__()} method is
+called, but no sooner.  If the coercion returns an object of a
+different type for the operand whose coercion is invoked, part of the
+process is redone using the new object.
+
+\item
+
+When an in-place operator (like `\code{+=}') is used, if the left
+operand implements \method{__iop__()}, it is invoked without any
+coercion.  When the operation falls back to \method{__op__()} and/or
+\method{__rop__()}, the normal coercion rules apply.
+
+\item
+
+In \var{x}\code{+}\var{y}, if \var{x} is a sequence that implements
+sequence concatenation, sequence concatenation is invoked.
+
+\item
+
+In \var{x}\code{*}\var{y}, if one operator is a sequence that
+implements sequence repetition, and the other is an integer
+(\class{int} or \class{long}), sequence repetition is invoked.
+
+\item
+
+Rich comparisons (implemented by methods \method{__eq__()} and so on)
+never use coercion.  Three-way comparison (implemented by
+\method{__cmp__()}) does use coercion under the same conditions as
+other binary operations use it.
+
+\item
+
+In the current implementation, the built-in numeric types \class{int},
+\class{long} and \class{float} do not use coercion; the type
+\class{complex} however does use it.  The difference can become
+apparent when subclassing these types.  Over time, the type
+\class{complex} may be fixed to avoid coercion.  All these types
+implement a \method{__coerce__()} method, for use by the built-in
+\function{coerce()} function.
+
+\end{itemize}
+
+\subsection{With Statement Context Managers\label{context-managers}}
+
+\versionadded{2.5}
+
+A \dfn{context manager} is an object that defines the runtime
+context to be established when executing a \keyword{with}
+statement. The context manager handles the entry into,
+and the exit from, the desired runtime context for the execution
+of the block of code.  Context managers are normally invoked using
+the \keyword{with} statement (described in section~\ref{with}), but
+can also be used by directly invoking their methods.
+
+\stindex{with}
+\index{context manager}
+
+Typical uses of context managers include saving and
+restoring various kinds of global state, locking and unlocking
+resources, closing opened files, etc.
+
+For more information on context managers, see
+``\ulink{Context Types}{../lib/typecontextmanager.html}'' in the
+\citetitle[../lib/lib.html]{Python Library Reference}.
+
+\begin{methoddesc}[context manager]{__enter__}{self}
+Enter the runtime context related to this object. The \keyword{with}
+statement will bind this method's return value to the target(s)
+specified in the \keyword{as} clause of the statement, if any.
+\end{methoddesc}
+
+\begin{methoddesc}[context manager]{__exit__}
+{self, exc_type, exc_value, traceback}
+Exit the runtime context related to this object. The parameters
+describe the exception that caused the context to be exited. If
+the context was exited without an exception, all three arguments
+will be \constant{None}.
+
+If an exception is supplied, and the method wishes to suppress the
+exception (i.e., prevent it from being propagated), it should return a
+true value. Otherwise, the exception will be processed normally upon
+exit from this method.
+
+Note that \method{__exit__} methods should not reraise the passed-in
+exception; this is the caller's responsibility.
+\end{methoddesc}
+
+\begin{seealso}
+  \seepep{0343}{The "with" statement}
+         {The specification, background, and examples for the
+          Python \keyword{with} statement.}
+\end{seealso}
+

Added: vendor/Python/current/Doc/ref/ref4.tex
===================================================================
--- vendor/Python/current/Doc/ref/ref4.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/ref/ref4.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,219 @@
+\chapter{Execution model \label{execmodel}}
+\index{execution model}
+
+
+\section{Naming and binding \label{naming}}
+\indexii{code}{block}
+\index{namespace}
+\index{scope}
+
+\dfn{Names}\index{name} refer to objects.  Names are introduced by
+name binding operations.  Each occurrence of a name in the program
+text refers to the \dfn{binding}\indexii{binding}{name} of that name
+established in the innermost function block containing the use.
+
+A \dfn{block}\index{block} is a piece of Python program text that is
+executed as a unit.  The following are blocks: a module, a function
+body, and a class definition.  Each command typed interactively is a
+block.  A script file (a file given as standard input to the
+interpreter or specified on the interpreter command line the first
+argument) is a code block.  A script command (a command specified on
+the interpreter command line with the `\strong{-c}' option) is a code
+block.  The file read by the built-in function \function{execfile()}
+is a code block.  The string argument passed to the built-in function
+\function{eval()} and to the \keyword{exec} statement is a code block.
+The expression read and evaluated by the built-in function
+\function{input()} is a code block.
+
+A code block is executed in an \dfn{execution
+frame}\indexii{execution}{frame}.  A frame contains some
+administrative information (used for debugging) and determines where
+and how execution continues after the code block's execution has
+completed.
+
+A \dfn{scope}\index{scope} defines the visibility of a name within a
+block.  If a local variable is defined in a block, its scope includes
+that block.  If the definition occurs in a function block, the scope
+extends to any blocks contained within the defining one, unless a
+contained block introduces a different binding for the name.  The
+scope of names defined in a class block is limited to the class block;
+it does not extend to the code blocks of methods.
+
+When a name is used in a code block, it is resolved using the nearest
+enclosing scope.  The set of all such scopes visible to a code block
+is called the block's \dfn{environment}\index{environment}.  
+
+If a name is bound in a block, it is a local variable of that block.
+If a name is bound at the module level, it is a global variable.  (The
+variables of the module code block are local and global.)  If a
+variable is used in a code block but not defined there, it is a
+\dfn{free variable}\indexii{free}{variable}.
+
+When a name is not found at all, a
+\exception{NameError}\withsubitem{(built-in
+exception)}{\ttindex{NameError}} exception is raised.  If the name
+refers to a local variable that has not been bound, a
+\exception{UnboundLocalError}\ttindex{UnboundLocalError} exception is
+raised.  \exception{UnboundLocalError} is a subclass of
+\exception{NameError}.
+
+The following constructs bind names: formal parameters to functions,
+\keyword{import} statements, class and function definitions (these
+bind the class or function name in the defining block), and targets
+that are identifiers if occurring in an assignment, \keyword{for} loop
+header, or in the second position of an \keyword{except} clause
+header.  The \keyword{import} statement of the form ``\samp{from
+\ldots import *}''\stindex{from} binds all names defined in the
+imported module, except those beginning with an underscore.  This form
+may only be used at the module level.
+
+A target occurring in a \keyword{del} statement is also considered bound
+for this purpose (though the actual semantics are to unbind the
+name).  It is illegal to unbind a name that is referenced by an
+enclosing scope; the compiler will report a \exception{SyntaxError}.
+
+Each assignment or import statement occurs within a block defined by a
+class or function definition or at the module level (the top-level
+code block).
+
+If a name binding operation occurs anywhere within a code block, all
+uses of the name within the block are treated as references to the
+current block.  This can lead to errors when a name is used within a
+block before it is bound.
+This rule is subtle.  Python lacks declarations and allows
+name binding operations to occur anywhere within a code block.  The
+local variables of a code block can be determined by scanning the
+entire text of the block for name binding operations.
+
+If the global statement occurs within a block, all uses of the name
+specified in the statement refer to the binding of that name in the
+top-level namespace.  Names are resolved in the top-level namespace by
+searching the global namespace, i.e. the namespace of the module
+containing the code block, and the builtin namespace, the namespace of
+the module \module{__builtin__}.  The global namespace is searched
+first.  If the name is not found there, the builtin namespace is
+searched.  The global statement must precede all uses of the name.
+
+The built-in namespace associated with the execution of a code block
+is actually found by looking up the name \code{__builtins__} in its
+global namespace; this should be a dictionary or a module (in the
+latter case the module's dictionary is used).  By default, when in the
+\module{__main__} module, \code{__builtins__} is the built-in module
+\module{__builtin__} (note: no `s'); when in any other module,
+\code{__builtins__} is an alias for the dictionary of the
+\module{__builtin__} module itself.  \code{__builtins__} can be set
+to a user-created dictionary to create a weak form of restricted
+execution\indexii{restricted}{execution}.
+
+\begin{notice}
+  Users should not touch \code{__builtins__}; it is strictly an
+  implementation detail.  Users wanting to override values in the
+  built-in namespace should \keyword{import} the \module{__builtin__}
+  (no `s') module and modify its attributes appropriately.
+\end{notice}
+
+The namespace for a module is automatically created the first time a
+module is imported.  The main module for a script is always called
+\module{__main__}\refbimodindex{__main__}.
+
+The global statement has the same scope as a name binding operation
+in the same block.  If the nearest enclosing scope for a free variable
+contains a global statement, the free variable is treated as a global.
+
+A class definition is an executable statement that may use and define
+names.  These references follow the normal rules for name resolution.
+The namespace of the class definition becomes the attribute dictionary
+of the class.  Names defined at the class scope are not visible in
+methods. 
+
+\subsection{Interaction with dynamic features \label{dynamic-features}}
+
+There are several cases where Python statements are illegal when
+used in conjunction with nested scopes that contain free
+variables.
+
+If a variable is referenced in an enclosing scope, it is illegal
+to delete the name.  An error will be reported at compile time.
+
+If the wild card form of import --- \samp{import *} --- is used in a
+function and the function contains or is a nested block with free
+variables, the compiler will raise a \exception{SyntaxError}.
+
+If \keyword{exec} is used in a function and the function contains or
+is a nested block with free variables, the compiler will raise a
+\exception{SyntaxError} unless the exec explicitly specifies the local
+namespace for the \keyword{exec}.  (In other words, \samp{exec obj}
+would be illegal, but \samp{exec obj in ns} would be legal.)
+
+The \function{eval()}, \function{execfile()}, and \function{input()}
+functions and the \keyword{exec} statement do not have access to the
+full environment for resolving names.  Names may be resolved in the
+local and global namespaces of the caller.  Free variables are not
+resolved in the nearest enclosing namespace, but in the global
+namespace.\footnote{This limitation occurs because the code that is
+    executed by these operations is not available at the time the
+    module is compiled.}
+The \keyword{exec} statement and the \function{eval()} and
+\function{execfile()} functions have optional arguments to override
+the global and local namespace.  If only one namespace is specified,
+it is used for both.
+
+\section{Exceptions \label{exceptions}}
+\index{exception}
+
+Exceptions are a means of breaking out of the normal flow of control
+of a code block in order to handle errors or other exceptional
+conditions.  An exception is
+\emph{raised}\index{raise an exception} at the point where the error
+is detected; it may be \emph{handled}\index{handle an exception} by
+the surrounding code block or by any code block that directly or
+indirectly invoked the code block where the error occurred.
+\index{exception handler}
+\index{errors}
+\index{error handling}
+
+The Python interpreter raises an exception when it detects a run-time
+error (such as division by zero).  A Python program can also
+explicitly raise an exception with the \keyword{raise} statement.
+Exception handlers are specified with the \keyword{try} ... \keyword{except}
+statement.  The \keyword{try} ... \keyword{finally} statement
+specifies cleanup code which does not handle the exception, but is
+executed whether an exception occurred or not in the preceding code.
+
+Python uses the ``termination''\index{termination model} model of
+error handling: an exception handler can find out what happened and
+continue execution at an outer level, but it cannot repair the cause
+of the error and retry the failing operation (except by re-entering
+the offending piece of code from the top).
+
+When an exception is not handled at all, the interpreter terminates
+execution of the program, or returns to its interactive main loop.  In
+either case, it prints a stack backtrace, except when the exception is 
+\exception{SystemExit}\withsubitem{(built-in
+exception)}{\ttindex{SystemExit}}.
+
+Exceptions are identified by class instances.  The \keyword{except}
+clause is selected depending on the class of the instance: it must
+reference the class of the instance or a base class thereof.  The
+instance can be received by the handler and can carry additional
+information about the exceptional condition.
+
+Exceptions can also be identified by strings, in which case the
+\keyword{except} clause is selected by object identity.  An arbitrary
+value can be raised along with the identifying string which can be
+passed to the handler.
+
+\deprecated{2.5}{String exceptions should not be used in new code.
+They will not be supported in a future version of Python.  Old code
+should be rewritten to use class exceptions instead.}
+
+\begin{notice}[warning]
+Messages to exceptions are not part of the Python API.  Their contents may
+change from one version of Python to the next without warning and should not
+be relied on by code which will run under multiple versions of the
+interpreter.
+\end{notice}
+
+See also the description of the \keyword{try} statement in
+section~\ref{try} and \keyword{raise} statement in
+section~\ref{raise}.

Added: vendor/Python/current/Doc/ref/ref5.tex
===================================================================
--- vendor/Python/current/Doc/ref/ref5.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/ref/ref5.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1325 @@
+\chapter{Expressions\label{expressions}}
+\index{expression}
+
+This chapter explains the meaning of the elements of expressions in
+Python.
+
+\strong{Syntax Notes:} In this and the following chapters, extended
+BNF\index{BNF} notation will be used to describe syntax, not lexical
+analysis.  When (one alternative of) a syntax rule has the form
+
+\begin{productionlist}[*]
+  \production{name}{\token{othername}}
+\end{productionlist}
+
+and no semantics are given, the semantics of this form of \code{name}
+are the same as for \code{othername}.
+\index{syntax}
+
+
+\section{Arithmetic conversions\label{conversions}}
+\indexii{arithmetic}{conversion}
+
+When a description of an arithmetic operator below uses the phrase
+``the numeric arguments are converted to a common type,'' the
+arguments are coerced using the coercion rules listed at
+~\ref{coercion-rules}.  If both arguments are standard numeric types,
+the following coercions are applied:
+
+\begin{itemize}
+\item	If either argument is a complex number, the other is converted
+	to complex;
+\item	otherwise, if either argument is a floating point number,
+	the other is converted to floating point;
+\item	otherwise, if either argument is a long integer,
+	the other is converted to long integer;
+\item	otherwise, both must be plain integers and no conversion
+	is necessary.
+\end{itemize}
+
+Some additional rules apply for certain operators (e.g., a string left
+argument to the `\%' operator). Extensions can define their own
+coercions.
+
+
+\section{Atoms\label{atoms}}
+\index{atom}
+
+Atoms are the most basic elements of expressions.  The simplest atoms
+are identifiers or literals.  Forms enclosed in
+reverse quotes or in parentheses, brackets or braces are also
+categorized syntactically as atoms.  The syntax for atoms is:
+
+\begin{productionlist}
+  \production{atom}
+             {\token{identifier} | \token{literal} | \token{enclosure}}
+  \production{enclosure}
+             {\token{parenth_form} | \token{list_display}}
+  \productioncont{| \token{generator_expression} | \token{dict_display}}
+  \productioncont{| \token{string_conversion} | \token{yield_atom}}
+\end{productionlist}
+
+
+\subsection{Identifiers (Names)\label{atom-identifiers}}
+\index{name}
+\index{identifier}
+
+An identifier occurring as an atom is a name.  See
+section \ref{identifiers} for lexical definition and
+section~\ref{naming} for documentation of naming and binding.
+
+When the name is bound to an object, evaluation of the atom yields
+that object.  When a name is not bound, an attempt to evaluate it
+raises a \exception{NameError} exception.
+\exindex{NameError}
+
+\strong{Private name mangling:}
+\indexii{name}{mangling}%
+\indexii{private}{names}%
+When an identifier that textually occurs in a class definition begins
+with two or more underscore characters and does not end in two or more
+underscores, it is considered a \dfn{private name} of that class.
+Private names are transformed to a longer form before code is
+generated for them.  The transformation inserts the class name in
+front of the name, with leading underscores removed, and a single
+underscore inserted in front of the class name.  For example, the
+identifier \code{__spam} occurring in a class named \code{Ham} will be
+transformed to \code{_Ham__spam}.  This transformation is independent
+of the syntactical context in which the identifier is used.  If the
+transformed name is extremely long (longer than 255 characters),
+implementation defined truncation may happen.  If the class name
+consists only of underscores, no transformation is done.
+
+
+\subsection{Literals\label{atom-literals}}
+\index{literal}
+
+Python supports string literals and various numeric literals:
+
+\begin{productionlist}
+  \production{literal}
+             {\token{stringliteral} | \token{integer} | \token{longinteger}}
+  \productioncont{| \token{floatnumber} | \token{imagnumber}}
+\end{productionlist}
+
+Evaluation of a literal yields an object of the given type (string,
+integer, long integer, floating point number, complex number) with the
+given value.  The value may be approximated in the case of floating
+point and imaginary (complex) literals.  See section \ref{literals}
+for details.
+
+All literals correspond to immutable data types, and hence the
+object's identity is less important than its value.  Multiple
+evaluations of literals with the same value (either the same
+occurrence in the program text or a different occurrence) may obtain
+the same object or a different object with the same value.
+\indexiii{immutable}{data}{type}
+\indexii{immutable}{object}
+
+
+\subsection{Parenthesized forms\label{parenthesized}}
+\index{parenthesized form}
+
+A parenthesized form is an optional expression list enclosed in
+parentheses:
+
+\begin{productionlist}
+  \production{parenth_form}
+             {"(" [\token{expression_list}] ")"}
+\end{productionlist}
+
+A parenthesized expression list yields whatever that expression list
+yields: if the list contains at least one comma, it yields a tuple;
+otherwise, it yields the single expression that makes up the
+expression list.
+
+An empty pair of parentheses yields an empty tuple object.  Since
+tuples are immutable, the rules for literals apply (i.e., two
+occurrences of the empty tuple may or may not yield the same object).
+\indexii{empty}{tuple}
+
+Note that tuples are not formed by the parentheses, but rather by use
+of the comma operator.  The exception is the empty tuple, for which
+parentheses \emph{are} required --- allowing unparenthesized ``nothing''
+in expressions would cause ambiguities and allow common typos to
+pass uncaught.
+\index{comma}
+\indexii{tuple}{display}
+
+
+\subsection{List displays\label{lists}}
+\indexii{list}{display}
+\indexii{list}{comprehensions}
+
+A list display is a possibly empty series of expressions enclosed in
+square brackets:
+
+\begin{productionlist}
+  \production{list_display}
+             {"[" [\token{expression_list} | \token{list_comprehension}] "]"}
+  \production{list_comprehension}
+             {\token{expression} \token{list_for}}
+  \production{list_for}
+             {"for" \token{target_list} "in" \token{old_expression_list}
+              [\token{list_iter}]}
+  \production{old_expression_list}
+             {\token{old_expression}
+              [("," \token{old_expression})+ [","]]}
+  \production{list_iter}
+             {\token{list_for} | \token{list_if}}
+  \production{list_if}
+             {"if" \token{old_expression} [\token{list_iter}]}
+\end{productionlist}
+
+A list display yields a new list object.  Its contents are specified
+by providing either a list of expressions or a list comprehension.
+\indexii{list}{comprehensions}
+When a comma-separated list of expressions is supplied, its elements are
+evaluated from left to right and placed into the list object in that
+order.  When a list comprehension is supplied, it consists of a
+single expression followed by at least one \keyword{for} clause and zero or
+more \keyword{for} or \keyword{if} clauses.  In this
+case, the elements of the new list are those that would be produced
+by considering each of the \keyword{for} or \keyword{if} clauses a block,
+nesting from
+left to right, and evaluating the expression to produce a list element
+each time the innermost block is reached\footnote{In Python 2.3, a
+list comprehension "leaks" the control variables of each
+\samp{for} it contains into the containing scope.  However, this
+behavior is deprecated, and relying on it will not work once this
+bug is fixed in a future release}.
+\obindex{list}
+\indexii{empty}{list}
+
+
+\subsection{Generator expressions\label{genexpr}}
+\indexii{generator}{expression}
+
+A generator expression is a compact generator notation in parentheses:
+
+\begin{productionlist}
+  \production{generator_expression}
+             {"(" \token{expression} \token{genexpr_for} ")"}
+  \production{genexpr_for}
+             {"for" \token{target_list} "in" \token{or_test}
+              [\token{genexpr_iter}]}
+  \production{genexpr_iter}
+             {\token{genexpr_for} | \token{genexpr_if}}
+  \production{genexpr_if}
+             {"if" \token{old_expression} [\token{genexpr_iter}]}
+\end{productionlist}
+
+A generator expression yields a new generator object.
+\obindex{generator}
+It consists of a single expression followed by at least one
+\keyword{for} clause and zero or more \keyword{for} or \keyword{if}
+clauses.  The iterating values of the new generator are those that
+would be produced by considering each of the \keyword{for} or
+\keyword{if} clauses a block, nesting from left to right, and
+evaluating the expression to yield a value that is reached the
+innermost block for each iteration.
+
+Variables used in the generator expression are evaluated lazily
+when the \method{next()} method is called for generator object
+(in the same fashion as normal generators). However, the leftmost
+\keyword{for} clause is immediately evaluated so that error produced
+by it can be seen before any other possible error in the code that
+handles the generator expression.
+Subsequent \keyword{for} clauses cannot be evaluated immediately since
+they may depend on the previous \keyword{for} loop.
+For example: \samp{(x*y for x in range(10) for y in bar(x))}.
+
+The parentheses can be omitted on calls with only one argument.
+See section \ref{calls} for the detail.
+
+
+\subsection{Dictionary displays\label{dict}}
+\indexii{dictionary}{display}
+
+A dictionary display is a possibly empty series of key/datum pairs
+enclosed in curly braces:
+\index{key}
+\index{datum}
+\index{key/datum pair}
+
+\begin{productionlist}
+  \production{dict_display}
+             {"\{" [\token{key_datum_list}] "\}"}
+  \production{key_datum_list}
+             {\token{key_datum} ("," \token{key_datum})* [","]}
+  \production{key_datum}
+             {\token{expression} ":" \token{expression}}
+\end{productionlist}
+
+A dictionary display yields a new dictionary object.
+\obindex{dictionary}
+
+The key/datum pairs are evaluated from left to right to define the
+entries of the dictionary: each key object is used as a key into the
+dictionary to store the corresponding datum.
+
+Restrictions on the types of the key values are listed earlier in
+section \ref{types}.  (To summarize, the key type should be hashable,
+which excludes all mutable objects.)  Clashes between duplicate keys
+are not detected; the last datum (textually rightmost in the display)
+stored for a given key value prevails.
+\indexii{immutable}{object}
+
+
+\subsection{String conversions\label{string-conversions}}
+\indexii{string}{conversion}
+\indexii{reverse}{quotes}
+\indexii{backward}{quotes}
+\index{back-quotes}
+
+A string conversion is an expression list enclosed in reverse (a.k.a.
+backward) quotes:
+
+\begin{productionlist}
+  \production{string_conversion}
+             {"`" \token{expression_list} "`"}
+\end{productionlist}
+
+A string conversion evaluates the contained expression list and
+converts the resulting object into a string according to rules
+specific to its type.
+
+If the object is a string, a number, \code{None}, or a tuple, list or
+dictionary containing only objects whose type is one of these, the
+resulting string is a valid Python expression which can be passed to
+the built-in function \function{eval()} to yield an expression with the
+same value (or an approximation, if floating point numbers are
+involved).
+
+(In particular, converting a string adds quotes around it and converts
+``funny'' characters to escape sequences that are safe to print.)
+
+Recursive objects (for example, lists or dictionaries that contain a
+reference to themselves, directly or indirectly) use \samp{...} to
+indicate a recursive reference, and the result cannot be passed to
+\function{eval()} to get an equal value (\exception{SyntaxError} will
+be raised instead).
+\obindex{recursive}
+
+The built-in function \function{repr()} performs exactly the same
+conversion in its argument as enclosing it in parentheses and reverse
+quotes does.  The built-in function \function{str()} performs a
+similar but more user-friendly conversion.
+\bifuncindex{repr}
+\bifuncindex{str}
+
+
+\subsection{Yield expressions\label{yieldexpr}}
+\kwindex{yield}
+\indexii{yield}{expression}
+\indexii{generator}{function}
+
+\begin{productionlist}
+  \production{yield_atom}
+             {"(" \token{yield_expression} ")"}
+  \production{yield_expression}
+             {"yield" [\token{expression_list}]}
+\end{productionlist}
+
+\versionadded{2.5}
+
+The \keyword{yield} expression is only used when defining a generator
+function, and can only be used in the body of a function definition.
+Using a \keyword{yield} expression in a function definition is
+sufficient to cause that definition to create a generator function
+instead of a normal function.
+
+When a generator function is called, it returns an iterator known as a
+generator.  That generator then controls the execution of a generator
+function.  The execution starts when one of the generator's methods is
+called.  At that time, the execution proceeds to the first
+\keyword{yield} expression, where it is suspended again, returning the
+value of \grammartoken{expression_list} to generator's caller.  By
+suspended we mean that all local state is retained, including the
+current bindings of local variables, the instruction pointer, and the
+internal evaluation stack.  When the execution is resumed by calling
+one of the generator's methods, the function can proceed exactly as
+if the \keyword{yield} expression was just another external call.
+The value of the \keyword{yield} expression after resuming depends on
+the method which resumed the execution.
+
+\index{coroutine}
+
+All of this makes generator functions quite similar to coroutines; they
+yield multiple times, they have more than one entry point and their
+execution can be suspended.  The only difference is that a generator
+function cannot control where should the execution continue after it
+yields; the control is always transfered to the generator's caller.
+
+\obindex{generator}
+
+The following generator's methods can be used to control the execution
+of a generator function:
+
+\exindex{StopIteration}
+
+\begin{methoddesc}[generator]{next}{}
+  Starts the execution of a generator function or resumes it at the
+  last executed \keyword{yield} expression.  When a generator function
+  is resumed with a \method{next()} method, the current \keyword{yield}
+  expression always evaluates to \constant{None}.  The execution then
+  continues to the next \keyword{yield} expression, where the generator
+  is suspended again, and the value of the
+  \grammartoken{expression_list} is returned to \method{next()}'s
+  caller. If the generator exits without yielding another value, a
+  \exception{StopIteration} exception is raised.
+\end{methoddesc}
+
+\begin{methoddesc}[generator]{send}{value}
+  Resumes the execution and ``sends'' a value into the generator
+  function.  The \code{value} argument becomes the result of the
+  current \keyword{yield} expression.  The \method{send()} method
+  returns the next value yielded by the generator, or raises
+  \exception{StopIteration} if the generator exits without yielding
+  another value.
+  When \method{send()} is called to start the generator, it must be
+  called with \constant{None} as the argument, because there is no
+  \keyword{yield} expression that could receieve the value.
+\end{methoddesc}
+
+\begin{methoddesc}[generator]{throw}
+                  {type\optional{, value\optional{, traceback}}}
+  Raises an exception of type \code{type} at the point where generator
+  was paused, and returns the next value yielded by the generator
+  function.  If the generator exits without yielding another value, a
+  \exception{StopIteration} exception is raised.  If the generator
+  function does not catch the passed-in exception, or raises a
+  different exception, then that exception propagates to the caller.
+\end{methoddesc}
+
+\exindex{GeneratorExit}
+
+\begin{methoddesc}[generator]{close}{}
+  Raises a \exception{GeneratorExit} at the point where the generator
+  function was paused.  If the generator function then raises
+  \exception{StopIteration} (by exiting normally, or due to already
+  being closed) or \exception{GeneratorExit} (by not catching the
+  exception), close returns to its caller.  If the generator yields a
+  value, a \exception{RuntimeError} is raised.  If the generator raises
+  any other exception, it is propagated to the caller.  \method{close}
+  does nothing if the generator has already exited due to an exception
+  or normal exit.
+\end{methoddesc}
+
+Here is a simple example that demonstrates the behavior of generators
+and generator functions:
+
+\begin{verbatim}
+>>> def echo(value=None):
+...     print "Execution starts when 'next()' is called for the first time."
+...     try:
+...         while True:
+...             try:
+...                 value = (yield value)
+...             except GeneratorExit:
+...                 # never catch GeneratorExit
+...                 raise
+...             except Exception, e:
+...                 value = e
+...     finally:
+...         print "Don't forget to clean up when 'close()' is called."
+...
+>>> generator = echo(1)
+>>> print generator.next()
+Execution starts when 'next()' is called for the first time.
+1
+>>> print generator.next()
+None
+>>> print generator.send(2)
+2
+>>> generator.throw(TypeError, "spam")
+TypeError('spam',)
+>>> generator.close()
+Don't forget to clean up when 'close()' is called.
+\end{verbatim}
+
+\begin{seealso}
+  \seepep{0342}{Coroutines via Enhanced Generators}
+         {The proposal to enhance the API and syntax of generators,
+          making them usable as simple coroutines.}
+\end{seealso}
+
+
+\section{Primaries\label{primaries}}
+\index{primary}
+
+Primaries represent the most tightly bound operations of the language.
+Their syntax is:
+
+\begin{productionlist}
+  \production{primary}
+             {\token{atom} | \token{attributeref}
+              | \token{subscription} | \token{slicing} | \token{call}}
+\end{productionlist}
+
+
+\subsection{Attribute references\label{attribute-references}}
+\indexii{attribute}{reference}
+
+An attribute reference is a primary followed by a period and a name:
+
+\begin{productionlist}
+  \production{attributeref}
+             {\token{primary} "." \token{identifier}}
+\end{productionlist}
+
+The primary must evaluate to an object of a type that supports
+attribute references, e.g., a module, list, or an instance.  This
+object is then asked to produce the attribute whose name is the
+identifier.  If this attribute is not available, the exception
+\exception{AttributeError}\exindex{AttributeError} is raised.
+Otherwise, the type and value of the object produced is determined by
+the object.  Multiple evaluations of the same attribute reference may
+yield different objects.
+\obindex{module}
+\obindex{list}
+
+
+\subsection{Subscriptions\label{subscriptions}}
+\index{subscription}
+
+A subscription selects an item of a sequence (string, tuple or list)
+or mapping (dictionary) object:
+\obindex{sequence}
+\obindex{mapping}
+\obindex{string}
+\obindex{tuple}
+\obindex{list}
+\obindex{dictionary}
+\indexii{sequence}{item}
+
+\begin{productionlist}
+  \production{subscription}
+             {\token{primary} "[" \token{expression_list} "]"}
+\end{productionlist}
+
+The primary must evaluate to an object of a sequence or mapping type.
+
+If the primary is a mapping, the expression list must evaluate to an
+object whose value is one of the keys of the mapping, and the
+subscription selects the value in the mapping that corresponds to that
+key.  (The expression list is a tuple except if it has exactly one
+item.)
+
+If the primary is a sequence, the expression (list) must evaluate to a
+plain integer.  If this value is negative, the length of the sequence
+is added to it (so that, e.g., \code{x[-1]} selects the last item of
+\code{x}.)  The resulting value must be a nonnegative integer less
+than the number of items in the sequence, and the subscription selects
+the item whose index is that value (counting from zero).
+
+A string's items are characters.  A character is not a separate data
+type but a string of exactly one character.
+\index{character}
+\indexii{string}{item}
+
+
+\subsection{Slicings\label{slicings}}
+\index{slicing}
+\index{slice}
+
+A slicing selects a range of items in a sequence object (e.g., a
+string, tuple or list).  Slicings may be used as expressions or as
+targets in assignment or \keyword{del} statements.  The syntax for a
+slicing:
+\obindex{sequence}
+\obindex{string}
+\obindex{tuple}
+\obindex{list}
+
+\begin{productionlist}
+  \production{slicing}
+             {\token{simple_slicing} | \token{extended_slicing}}
+  \production{simple_slicing}
+             {\token{primary} "[" \token{short_slice} "]"}
+  \production{extended_slicing}
+             {\token{primary} "[" \token{slice_list} "]" }
+  \production{slice_list}
+             {\token{slice_item} ("," \token{slice_item})* [","]}
+  \production{slice_item}
+             {\token{expression} | \token{proper_slice} | \token{ellipsis}}
+  \production{proper_slice}
+             {\token{short_slice} | \token{long_slice}}
+  \production{short_slice}
+             {[\token{lower_bound}] ":" [\token{upper_bound}]}
+  \production{long_slice}
+             {\token{short_slice} ":" [\token{stride}]}
+  \production{lower_bound}
+             {\token{expression}}
+  \production{upper_bound}
+             {\token{expression}}
+  \production{stride}
+             {\token{expression}}
+  \production{ellipsis}
+             {"..."}
+\end{productionlist}
+
+There is ambiguity in the formal syntax here: anything that looks like
+an expression list also looks like a slice list, so any subscription
+can be interpreted as a slicing.  Rather than further complicating the
+syntax, this is disambiguated by defining that in this case the
+interpretation as a subscription takes priority over the
+interpretation as a slicing (this is the case if the slice list
+contains no proper slice nor ellipses).  Similarly, when the slice
+list has exactly one short slice and no trailing comma, the
+interpretation as a simple slicing takes priority over that as an
+extended slicing.\indexii{extended}{slicing}
+
+The semantics for a simple slicing are as follows.  The primary must
+evaluate to a sequence object.  The lower and upper bound expressions,
+if present, must evaluate to plain integers; defaults are zero and the
+\code{sys.maxint}, respectively.  If either bound is negative, the
+sequence's length is added to it.  The slicing now selects all items
+with index \var{k} such that
+\code{\var{i} <= \var{k} < \var{j}} where \var{i}
+and \var{j} are the specified lower and upper bounds.  This may be an
+empty sequence.  It is not an error if \var{i} or \var{j} lie outside the
+range of valid indexes (such items don't exist so they aren't
+selected).
+
+The semantics for an extended slicing are as follows.  The primary
+must evaluate to a mapping object, and it is indexed with a key that
+is constructed from the slice list, as follows.  If the slice list
+contains at least one comma, the key is a tuple containing the
+conversion of the slice items; otherwise, the conversion of the lone
+slice item is the key.  The conversion of a slice item that is an
+expression is that expression.  The conversion of an ellipsis slice
+item is the built-in \code{Ellipsis} object.  The conversion of a
+proper slice is a slice object (see section \ref{types}) whose
+\member{start}, \member{stop} and \member{step} attributes are the
+values of the expressions given as lower bound, upper bound and
+stride, respectively, substituting \code{None} for missing
+expressions.
+\withsubitem{(slice object attribute)}{\ttindex{start}
+  \ttindex{stop}\ttindex{step}}
+
+
+\subsection{Calls\label{calls}}
+\index{call}
+
+A call calls a callable object (e.g., a function) with a possibly empty
+series of arguments:
+\obindex{callable}
+
+\begin{productionlist}
+  \production{call}
+             {\token{primary} "(" [\token{argument_list} [","]}
+  \productioncont{            | \token{expression} \token{genexpr_for}] ")"}
+  \production{argument_list}
+             {\token{positional_arguments} ["," \token{keyword_arguments}]}
+  \productioncont{                     ["," "*" \token{expression}]}
+  \productioncont{                     ["," "**" \token{expression}]}
+  \productioncont{| \token{keyword_arguments} ["," "*" \token{expression}]}
+  \productioncont{                    ["," "**" \token{expression}]}
+  \productioncont{| "*" \token{expression} ["," "**" \token{expression}]}
+  \productioncont{| "**" \token{expression}}
+  \production{positional_arguments}
+             {\token{expression} ("," \token{expression})*}
+  \production{keyword_arguments}
+             {\token{keyword_item} ("," \token{keyword_item})*}
+  \production{keyword_item}
+             {\token{identifier} "=" \token{expression}}
+\end{productionlist}
+
+A trailing comma may be present after the positional and keyword
+arguments but does not affect the semantics.
+
+The primary must evaluate to a callable object (user-defined
+functions, built-in functions, methods of built-in objects, class
+objects, methods of class instances, and certain class instances
+themselves are callable; extensions may define additional callable
+object types).  All argument expressions are evaluated before the call
+is attempted.  Please refer to section \ref{function} for the syntax
+of formal parameter lists.
+
+If keyword arguments are present, they are first converted to
+positional arguments, as follows.  First, a list of unfilled slots is
+created for the formal parameters.  If there are N positional
+arguments, they are placed in the first N slots.  Next, for each
+keyword argument, the identifier is used to determine the
+corresponding slot (if the identifier is the same as the first formal
+parameter name, the first slot is used, and so on).  If the slot is
+already filled, a \exception{TypeError} exception is raised.
+Otherwise, the value of the argument is placed in the slot, filling it
+(even if the expression is \code{None}, it fills the slot).  When all
+arguments have been processed, the slots that are still unfilled are
+filled with the corresponding default value from the function
+definition.  (Default values are calculated, once, when the function
+is defined; thus, a mutable object such as a list or dictionary used
+as default value will be shared by all calls that don't specify an
+argument value for the corresponding slot; this should usually be
+avoided.)  If there are any unfilled slots for which no default value
+is specified, a \exception{TypeError} exception is raised.  Otherwise,
+the list of filled slots is used as the argument list for the call.
+
+If there are more positional arguments than there are formal parameter
+slots, a \exception{TypeError} exception is raised, unless a formal
+parameter using the syntax \samp{*identifier} is present; in this
+case, that formal parameter receives a tuple containing the excess
+positional arguments (or an empty tuple if there were no excess
+positional arguments).
+
+If any keyword argument does not correspond to a formal parameter
+name, a \exception{TypeError} exception is raised, unless a formal
+parameter using the syntax \samp{**identifier} is present; in this
+case, that formal parameter receives a dictionary containing the
+excess keyword arguments (using the keywords as keys and the argument
+values as corresponding values), or a (new) empty dictionary if there
+were no excess keyword arguments.
+
+If the syntax \samp{*expression} appears in the function call,
+\samp{expression} must evaluate to a sequence.  Elements from this
+sequence are treated as if they were additional positional arguments;
+if there are postional arguments \var{x1},...,\var{xN} , and
+\samp{expression} evaluates to a sequence \var{y1},...,\var{yM}, this
+is equivalent to a call with M+N positional arguments
+\var{x1},...,\var{xN},\var{y1},...,\var{yM}.
+
+A consequence of this is that although the \samp{*expression} syntax
+appears \emph{after} any keyword arguments, it is processed
+\emph{before} the keyword arguments (and the
+\samp{**expression} argument, if any -- see below).  So:
+
+\begin{verbatim}
+>>> def f(a, b):
+...  print a, b
+...
+>>> f(b=1, *(2,))
+2 1
+>>> f(a=1, *(2,))
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+TypeError: f() got multiple values for keyword argument 'a'
+>>> f(1, *(2,))
+1 2
+\end{verbatim}
+
+It is unusual for both keyword arguments and the
+\samp{*expression} syntax to be used in the same call, so in practice
+this confusion does not arise.
+
+If the syntax \samp{**expression} appears in the function call,
+\samp{expression} must evaluate to a (subclass of) dictionary, the
+contents of which are treated as additional keyword arguments.  In the
+case of a keyword appearing in both \samp{expression} and as an
+explicit keyword argument, a \exception{TypeError} exception is
+raised.
+
+Formal parameters using the syntax \samp{*identifier} or
+\samp{**identifier} cannot be used as positional argument slots or
+as keyword argument names.  Formal parameters using the syntax
+\samp{(sublist)} cannot be used as keyword argument names; the
+outermost sublist corresponds to a single unnamed argument slot, and
+the argument value is assigned to the sublist using the usual tuple
+assignment rules after all other parameter processing is done.
+
+A call always returns some value, possibly \code{None}, unless it
+raises an exception.  How this value is computed depends on the type
+of the callable object.
+
+If it is---
+
+\begin{description}
+
+\item[a user-defined function:] The code block for the function is
+executed, passing it the argument list.  The first thing the code
+block will do is bind the formal parameters to the arguments; this is
+described in section \ref{function}.  When the code block executes a
+\keyword{return} statement, this specifies the return value of the
+function call.
+\indexii{function}{call}
+\indexiii{user-defined}{function}{call}
+\obindex{user-defined function}
+\obindex{function}
+
+\item[a built-in function or method:] The result is up to the
+interpreter; see the \citetitle[../lib/built-in-funcs.html]{Python
+Library Reference} for the descriptions of built-in functions and
+methods.
+\indexii{function}{call}
+\indexii{built-in function}{call}
+\indexii{method}{call}
+\indexii{built-in method}{call}
+\obindex{built-in method}
+\obindex{built-in function}
+\obindex{method}
+\obindex{function}
+
+\item[a class object:] A new instance of that class is returned.
+\obindex{class}
+\indexii{class object}{call}
+
+\item[a class instance method:] The corresponding user-defined
+function is called, with an argument list that is one longer than the
+argument list of the call: the instance becomes the first argument.
+\obindex{class instance}
+\obindex{instance}
+\indexii{class instance}{call}
+
+\item[a class instance:] The class must define a \method{__call__()}
+method; the effect is then the same as if that method was called.
+\indexii{instance}{call}
+\withsubitem{(object method)}{\ttindex{__call__()}}
+
+\end{description}
+
+
+\section{The power operator\label{power}}
+
+The power operator binds more tightly than unary operators on its
+left; it binds less tightly than unary operators on its right.  The
+syntax is:
+
+\begin{productionlist}
+  \production{power}
+             {\token{primary} ["**" \token{u_expr}]}
+\end{productionlist}
+
+Thus, in an unparenthesized sequence of power and unary operators, the
+operators are evaluated from right to left (this does not constrain
+the evaluation order for the operands).
+
+The power operator has the same semantics as the built-in
+\function{pow()} function, when called with two arguments: it yields
+its left argument raised to the power of its right argument.  The
+numeric arguments are first converted to a common type.  The result
+type is that of the arguments after coercion.
+
+With mixed operand types, the coercion rules for binary arithmetic
+operators apply. For int and long int operands, the result has the
+same type as the operands (after coercion) unless the second argument
+is negative; in that case, all arguments are converted to float and a
+float result is delivered. For example, \code{10**2} returns \code{100},
+but \code{10**-2} returns \code{0.01}. (This last feature was added in
+Python 2.2. In Python 2.1 and before, if both arguments were of integer
+types and the second argument was negative, an exception was raised).
+
+Raising \code{0.0} to a negative power results in a
+\exception{ZeroDivisionError}.  Raising a negative number to a
+fractional power results in a \exception{ValueError}.
+
+
+\section{Unary arithmetic operations \label{unary}}
+\indexiii{unary}{arithmetic}{operation}
+\indexiii{unary}{bit-wise}{operation}
+
+All unary arithmetic (and bit-wise) operations have the same priority:
+
+\begin{productionlist}
+  \production{u_expr}
+             {\token{power} | "-" \token{u_expr}
+              | "+" \token{u_expr} | "{\~}" \token{u_expr}}
+\end{productionlist}
+
+The unary \code{-} (minus) operator yields the negation of its
+numeric argument.
+\index{negation}
+\index{minus}
+
+The unary \code{+} (plus) operator yields its numeric argument
+unchanged.
+\index{plus}
+
+The unary \code{\~} (invert) operator yields the bit-wise inversion
+of its plain or long integer argument.  The bit-wise inversion of
+\code{x} is defined as \code{-(x+1)}.  It only applies to integral
+numbers.
+\index{inversion}
+
+In all three cases, if the argument does not have the proper type,
+a \exception{TypeError} exception is raised.
+\exindex{TypeError}
+
+
+\section{Binary arithmetic operations\label{binary}}
+\indexiii{binary}{arithmetic}{operation}
+
+The binary arithmetic operations have the conventional priority
+levels.  Note that some of these operations also apply to certain
+non-numeric types.  Apart from the power operator, there are only two
+levels, one for multiplicative operators and one for additive
+operators:
+
+\begin{productionlist}
+  \production{m_expr}
+             {\token{u_expr} | \token{m_expr} "*" \token{u_expr}
+              | \token{m_expr} "//" \token{u_expr}
+              | \token{m_expr} "/" \token{u_expr}}
+  \productioncont{| \token{m_expr} "\%" \token{u_expr}}
+  \production{a_expr}
+             {\token{m_expr} | \token{a_expr} "+" \token{m_expr}
+              | \token{a_expr} "-" \token{m_expr}}
+\end{productionlist}
+
+The \code{*} (multiplication) operator yields the product of its
+arguments.  The arguments must either both be numbers, or one argument
+must be an integer (plain or long) and the other must be a sequence.
+In the former case, the numbers are converted to a common type and
+then multiplied together.  In the latter case, sequence repetition is
+performed; a negative repetition factor yields an empty sequence.
+\index{multiplication}
+
+The \code{/} (division) and \code{//} (floor division) operators yield
+the quotient of their arguments.  The numeric arguments are first
+converted to a common type.  Plain or long integer division yields an
+integer of the same type; the result is that of mathematical division
+with the `floor' function applied to the result.  Division by zero
+raises the
+\exception{ZeroDivisionError} exception.
+\exindex{ZeroDivisionError}
+\index{division}
+
+The \code{\%} (modulo) operator yields the remainder from the
+division of the first argument by the second.  The numeric arguments
+are first converted to a common type.  A zero right argument raises
+the \exception{ZeroDivisionError} exception.  The arguments may be floating
+point numbers, e.g., \code{3.14\%0.7} equals \code{0.34} (since
+\code{3.14} equals \code{4*0.7 + 0.34}.)  The modulo operator always
+yields a result with the same sign as its second operand (or zero);
+the absolute value of the result is strictly smaller than the absolute
+value of the second operand\footnote{
+    While \code{abs(x\%y) < abs(y)} is true mathematically, for
+    floats it may not be true numerically due to roundoff.  For
+    example, and assuming a platform on which a Python float is an
+    IEEE 754 double-precision number, in order that \code{-1e-100 \% 1e100}
+    have the same sign as \code{1e100}, the computed result is
+    \code{-1e-100 + 1e100}, which is numerically exactly equal
+    to \code{1e100}.  Function \function{fmod()} in the \module{math}
+    module returns a result whose sign matches the sign of the
+    first argument instead, and so returns \code{-1e-100} in this case.
+    Which approach is more appropriate depends on the application.
+}.
+\index{modulo}
+
+The integer division and modulo operators are connected by the
+following identity: \code{x == (x/y)*y + (x\%y)}.  Integer division and
+modulo are also connected with the built-in function \function{divmod()}:
+\code{divmod(x, y) == (x/y, x\%y)}.  These identities don't hold for
+floating point numbers; there similar identities hold
+approximately where \code{x/y} is replaced by \code{floor(x/y)} or
+\code{floor(x/y) - 1}\footnote{
+    If x is very close to an exact integer multiple of y, it's
+    possible for \code{floor(x/y)} to be one larger than
+    \code{(x-x\%y)/y} due to rounding.  In such cases, Python returns
+    the latter result, in order to preserve that \code{divmod(x,y)[0]
+    * y + x \%{} y} be very close to \code{x}.
+}.
+
+In addition to performing the modulo operation on numbers, the \code{\%}
+operator is also overloaded by string and unicode objects to perform
+string formatting (also known as interpolation). The syntax for string
+formatting is described in the
+\citetitle[../lib/typesseq-strings.html]{Python Library Reference},
+section ``Sequence Types''.
+
+\deprecated{2.3}{The floor division operator, the modulo operator,
+and the \function{divmod()} function are no longer defined for complex
+numbers.  Instead, convert to a floating point number using the
+\function{abs()} function if appropriate.}
+
+The \code{+} (addition) operator yields the sum of its arguments.
+The arguments must either both be numbers or both sequences of the
+same type.  In the former case, the numbers are converted to a common
+type and then added together.  In the latter case, the sequences are
+concatenated.
+\index{addition}
+
+The \code{-} (subtraction) operator yields the difference of its
+arguments.  The numeric arguments are first converted to a common
+type.
+\index{subtraction}
+
+
+\section{Shifting operations\label{shifting}}
+\indexii{shifting}{operation}
+
+The shifting operations have lower priority than the arithmetic
+operations:
+
+\begin{productionlist}
+  \production{shift_expr}
+             {\token{a_expr}
+              | \token{shift_expr} ( "<<" | ">>" ) \token{a_expr}}
+\end{productionlist}
+
+These operators accept plain or long integers as arguments.  The
+arguments are converted to a common type.  They shift the first
+argument to the left or right by the number of bits given by the
+second argument.
+
+A right shift by \var{n} bits is defined as division by
+\code{pow(2,\var{n})}.  A left shift by \var{n} bits is defined as
+multiplication with \code{pow(2,\var{n})}; for plain integers there is
+no overflow check so in that case the operation drops bits and flips
+the sign if the result is not less than \code{pow(2,31)} in absolute
+value.  Negative shift counts raise a \exception{ValueError}
+exception.
+\exindex{ValueError}
+
+
+\section{Binary bit-wise operations\label{bitwise}}
+\indexiii{binary}{bit-wise}{operation}
+
+Each of the three bitwise operations has a different priority level:
+
+\begin{productionlist}
+  \production{and_expr}
+             {\token{shift_expr} | \token{and_expr} "\&" \token{shift_expr}}
+  \production{xor_expr}
+             {\token{and_expr} | \token{xor_expr} "\textasciicircum" \token{and_expr}}
+  \production{or_expr}
+             {\token{xor_expr} | \token{or_expr} "|" \token{xor_expr}}
+\end{productionlist}
+
+The \code{\&} operator yields the bitwise AND of its arguments, which
+must be plain or long integers.  The arguments are converted to a
+common type.
+\indexii{bit-wise}{and}
+
+The \code{\^} operator yields the bitwise XOR (exclusive OR) of its
+arguments, which must be plain or long integers.  The arguments are
+converted to a common type.
+\indexii{bit-wise}{xor}
+\indexii{exclusive}{or}
+
+The \code{|} operator yields the bitwise (inclusive) OR of its
+arguments, which must be plain or long integers.  The arguments are
+converted to a common type.
+\indexii{bit-wise}{or}
+\indexii{inclusive}{or}
+
+
+\section{Comparisons\label{comparisons}}
+\index{comparison}
+
+Unlike C, all comparison operations in Python have the same priority,
+which is lower than that of any arithmetic, shifting or bitwise
+operation.  Also unlike C, expressions like \code{a < b < c} have the
+interpretation that is conventional in mathematics:
+\indexii{C}{language}
+
+\begin{productionlist}
+  \production{comparison}
+             {\token{or_expr} ( \token{comp_operator} \token{or_expr} )*}
+  \production{comp_operator}
+             {"<" | ">" | "==" | ">=" | "<=" | "<>" | "!="}
+  \productioncont{| "is" ["not"] | ["not"] "in"}
+\end{productionlist}
+
+Comparisons yield boolean values: \code{True} or \code{False}.
+
+Comparisons can be chained arbitrarily, e.g., \code{x < y <= z} is
+equivalent to \code{x < y and y <= z}, except that \code{y} is
+evaluated only once (but in both cases \code{z} is not evaluated at all
+when \code{x < y} is found to be false).
+\indexii{chaining}{comparisons}
+
+Formally, if \var{a}, \var{b}, \var{c}, \ldots, \var{y}, \var{z} are
+expressions and \var{opa}, \var{opb}, \ldots, \var{opy} are comparison
+operators, then \var{a opa b opb c} \ldots \var{y opy z} is equivalent
+to \var{a opa b} \keyword{and} \var{b opb c} \keyword{and} \ldots
+\var{y opy z}, except that each expression is evaluated at most once.
+
+Note that \var{a opa b opb c} doesn't imply any kind of comparison
+between \var{a} and \var{c}, so that, e.g., \code{x < y > z} is
+perfectly legal (though perhaps not pretty).
+
+The forms \code{<>} and \code{!=} are equivalent; for consistency with
+C, \code{!=} is preferred; where \code{!=} is mentioned below
+\code{<>} is also accepted.  The \code{<>} spelling is considered
+obsolescent.
+
+The operators \code{<}, \code{>}, \code{==}, \code{>=}, \code{<=}, and
+\code{!=} compare
+the values of two objects.  The objects need not have the same type.
+If both are numbers, they are converted to a common type.  Otherwise,
+objects of different types \emph{always} compare unequal, and are
+ordered consistently but arbitrarily.  You can control comparison
+behavior of objects of non-builtin types by defining a \code{__cmp__}
+method or rich comparison methods like \code{__gt__}, described in
+section~\ref{specialnames}.
+
+(This unusual definition of comparison was used to simplify the
+definition of operations like sorting and the \keyword{in} and
+\keyword{not in} operators.  In the future, the comparison rules for
+objects of different types are likely to change.)
+
+Comparison of objects of the same type depends on the type:
+
+\begin{itemize}
+
+\item
+Numbers are compared arithmetically.
+
+\item
+Strings are compared lexicographically using the numeric equivalents
+(the result of the built-in function \function{ord()}) of their
+characters.  Unicode and 8-bit strings are fully interoperable in this
+behavior.
+
+\item
+Tuples and lists are compared lexicographically using comparison of
+corresponding elements.  This means that to compare equal, each
+element must compare equal and the two sequences must be of the same
+type and have the same length.
+
+If not equal, the sequences are ordered the same as their first
+differing elements.  For example, \code{cmp([1,2,x], [1,2,y])} returns
+the same as \code{cmp(x,y)}.  If the corresponding element does not
+exist, the shorter sequence is ordered first (for example,
+\code{[1,2] < [1,2,3]}).
+
+\item
+Mappings (dictionaries) compare equal if and only if their sorted
+(key, value) lists compare equal.\footnote{The implementation computes
+   this efficiently, without constructing lists or sorting.}
+Outcomes other than equality are resolved consistently, but are not
+otherwise defined.\footnote{Earlier versions of Python used
+  lexicographic comparison of the sorted (key, value) lists, but this
+  was very expensive for the common case of comparing for equality.  An
+  even earlier version of Python compared dictionaries by identity only,
+  but this caused surprises because people expected to be able to test
+  a dictionary for emptiness by comparing it to \code{\{\}}.}
+
+\item
+Most other objects of builtin types compare unequal unless they are
+the same object;
+the choice whether one object is considered smaller or larger than
+another one is made arbitrarily but consistently within one
+execution of a program.
+
+\end{itemize}
+
+The operators \keyword{in} and \keyword{not in} test for set
+membership.  \code{\var{x} in \var{s}} evaluates to true if \var{x}
+is a member of the set \var{s}, and false otherwise.  \code{\var{x}
+not in \var{s}} returns the negation of \code{\var{x} in \var{s}}.
+The set membership test has traditionally been bound to sequences; an
+object is a member of a set if the set is a sequence and contains an
+element equal to that object.  However, it is possible for an object
+to support membership tests without being a sequence.  In particular,
+dictionaries support membership testing as a nicer way of spelling
+\code{\var{key} in \var{dict}}; other mapping types may follow suit.
+
+For the list and tuple types, \code{\var{x} in \var{y}} is true if and
+only if there exists an index \var{i} such that
+\code{\var{x} == \var{y}[\var{i}]} is true.
+
+For the Unicode and string types, \code{\var{x} in \var{y}} is true if
+and only if \var{x} is a substring of \var{y}.  An equivalent test is
+\code{y.find(x) != -1}.  Note, \var{x} and \var{y} need not be the
+same type; consequently, \code{u'ab' in 'abc'} will return \code{True}.
+Empty strings are always considered to be a substring of any other string,
+so \code{"" in "abc"} will return \code{True}.
+\versionchanged[Previously, \var{x} was required to be a string of
+length \code{1}]{2.3}
+
+For user-defined classes which define the \method{__contains__()} method,
+\code{\var{x} in \var{y}} is true if and only if
+\code{\var{y}.__contains__(\var{x})} is true.
+
+For user-defined classes which do not define \method{__contains__()} and
+do define \method{__getitem__()}, \code{\var{x} in \var{y}} is true if
+and only if there is a non-negative integer index \var{i} such that
+\code{\var{x} == \var{y}[\var{i}]}, and all lower integer indices
+do not raise \exception{IndexError} exception. (If any other exception
+is raised, it is as if \keyword{in} raised that exception).
+
+The operator \keyword{not in} is defined to have the inverse true value
+of \keyword{in}.
+\opindex{in}
+\opindex{not in}
+\indexii{membership}{test}
+\obindex{sequence}
+
+The operators \keyword{is} and \keyword{is not} test for object identity:
+\code{\var{x} is \var{y}} is true if and only if \var{x} and \var{y}
+are the same object.  \code{\var{x} is not \var{y}} yields the inverse
+truth value.
+\opindex{is}
+\opindex{is not}
+\indexii{identity}{test}
+
+
+\section{Boolean operations\label{Booleans}}
+\indexii{Conditional}{expression}
+\indexii{Boolean}{operation}
+
+Boolean operations have the lowest priority of all Python operations:
+
+\begin{productionlist}
+  \production{expression}
+             {\token{conditional_expression} | \token{lambda_form}}
+  \production{old_expression}
+             {\token{or_test} | \token{old_lambda_form}}
+  \production{conditional_expression}
+             {\token{or_test} ["if" \token{or_test} "else" \token{expression}]}
+  \production{or_test}
+             {\token{and_test} | \token{or_test} "or" \token{and_test}}
+  \production{and_test}
+             {\token{not_test} | \token{and_test} "and" \token{not_test}}
+  \production{not_test}
+             {\token{comparison} | "not" \token{not_test}}
+\end{productionlist}
+
+In the context of Boolean operations, and also when expressions are
+used by control flow statements, the following values are interpreted
+as false: \code{False}, \code{None}, numeric zero of all types, and empty
+strings and containers (including strings, tuples, lists, dictionaries,
+sets and frozensets).  All other values are interpreted as true.
+
+The operator \keyword{not} yields \code{True} if its argument is false,
+\code{False} otherwise.
+\opindex{not}
+
+The expression \code{\var{x} if \var{C} else \var{y}} first evaluates
+\var{C} (\emph{not} \var{x}); if \var{C} is true, \var{x} is evaluated and
+its value is returned; otherwise, \var{y} is evaluated and its value is
+returned.  \versionadded{2.5}
+
+The expression \code{\var{x} and \var{y}} first evaluates \var{x}; if
+\var{x} is false, its value is returned; otherwise, \var{y} is
+evaluated and the resulting value is returned.
+\opindex{and}
+
+The expression \code{\var{x} or \var{y}} first evaluates \var{x}; if
+\var{x} is true, its value is returned; otherwise, \var{y} is
+evaluated and the resulting value is returned.
+\opindex{or}
+
+(Note that neither \keyword{and} nor \keyword{or} restrict the value
+and type they return to \code{False} and \code{True}, but rather return the
+last evaluated argument.
+This is sometimes useful, e.g., if \code{s} is a string that should be
+replaced by a default value if it is empty, the expression
+\code{s or 'foo'} yields the desired value.  Because \keyword{not} has to
+invent a value anyway, it does not bother to return a value of the
+same type as its argument, so e.g., \code{not 'foo'} yields \code{False},
+not \code{''}.)
+
+\section{Lambdas\label{lambdas}}
+\indexii{lambda}{expression}
+\indexii{lambda}{form}
+\indexii{anonymous}{function}
+
+\begin{productionlist}
+  \production{lambda_form}
+             {"lambda" [\token{parameter_list}]: \token{expression}}
+  \production{old_lambda_form}
+             {"lambda" [\token{parameter_list}]: \token{old_expression}}
+\end{productionlist}
+
+Lambda forms (lambda expressions) have the same syntactic position as
+expressions.  They are a shorthand to create anonymous functions; the
+expression \code{lambda \var{arguments}: \var{expression}}
+yields a function object.  The unnamed object behaves like a function
+object defined with
+
+\begin{verbatim}
+def name(arguments):
+    return expression
+\end{verbatim}
+
+See section \ref{function} for the syntax of parameter lists.  Note
+that functions created with lambda forms cannot contain statements.
+\label{lambda}
+
+\section{Expression lists\label{exprlists}}
+\indexii{expression}{list}
+
+\begin{productionlist}
+  \production{expression_list}
+             {\token{expression} ( "," \token{expression} )* [","]}
+\end{productionlist}
+
+An expression list containing at least one comma yields a
+tuple.  The length of the tuple is the number of expressions in the
+list.  The expressions are evaluated from left to right.
+\obindex{tuple}
+
+The trailing comma is required only to create a single tuple (a.k.a. a
+\emph{singleton}); it is optional in all other cases.  A single
+expression without a trailing comma doesn't create a
+tuple, but rather yields the value of that expression.
+(To create an empty tuple, use an empty pair of parentheses:
+\code{()}.)
+\indexii{trailing}{comma}
+
+\section{Evaluation order\label{evalorder}}
+\indexii{evaluation}{order}
+
+Python evaluates expressions from left to right. Notice that while
+evaluating an assignment, the right-hand side is evaluated before
+the left-hand side.
+
+In the following lines, expressions will be evaluated in the
+arithmetic order of their suffixes:
+
+\begin{verbatim}
+expr1, expr2, expr3, expr4
+(expr1, expr2, expr3, expr4)
+{expr1: expr2, expr3: expr4}
+expr1 + expr2 * (expr3 - expr4)
+func(expr1, expr2, *expr3, **expr4)
+expr3, expr4 = expr1, expr2
+\end{verbatim}
+
+\section{Summary\label{summary}}
+
+The following table summarizes the operator
+precedences\indexii{operator}{precedence} in Python, from lowest
+precedence (least binding) to highest precedence (most binding).
+Operators in the same box have the same precedence.  Unless the syntax
+is explicitly given, operators are binary.  Operators in the same box
+group left to right (except for comparisons, including tests, which all
+have the same precedence and chain from left to right --- see section
+\ref{comparisons} -- and exponentiation, which groups from right to left).
+
+\begin{tableii}{c|l}{textrm}{Operator}{Description}
+    \lineii{\keyword{lambda}}			{Lambda expression}
+  \hline
+    \lineii{\keyword{or}}			{Boolean OR}
+  \hline
+    \lineii{\keyword{and}}			{Boolean AND}
+  \hline
+    \lineii{\keyword{not} \var{x}}		{Boolean NOT}
+  \hline
+    \lineii{\keyword{in}, \keyword{not} \keyword{in}}{Membership tests}
+    \lineii{\keyword{is}, \keyword{is not}}{Identity tests}
+    \lineii{\code{<}, \code{<=}, \code{>}, \code{>=},
+            \code{<>}, \code{!=}, \code{==}}
+	   {Comparisons}
+  \hline
+    \lineii{\code{|}}				{Bitwise OR}
+  \hline
+    \lineii{\code{\^}}				{Bitwise XOR}
+  \hline
+    \lineii{\code{\&}}				{Bitwise AND}
+  \hline
+    \lineii{\code{<<}, \code{>>}}		{Shifts}
+  \hline
+    \lineii{\code{+}, \code{-}}{Addition and subtraction}
+  \hline
+    \lineii{\code{*}, \code{/}, \code{\%}}
+           {Multiplication, division, remainder}
+  \hline
+    \lineii{\code{+\var{x}}, \code{-\var{x}}}	{Positive, negative}
+    \lineii{\code{\~\var{x}}}			{Bitwise not}
+  \hline
+    \lineii{\code{**}}				{Exponentiation}
+  \hline
+    \lineii{\code{\var{x}.\var{attribute}}}	{Attribute reference}
+    \lineii{\code{\var{x}[\var{index}]}}	{Subscription}
+    \lineii{\code{\var{x}[\var{index}:\var{index}]}}	{Slicing}
+    \lineii{\code{\var{f}(\var{arguments}...)}}	{Function call}
+  \hline
+    \lineii{\code{(\var{expressions}\ldots)}}	{Binding or tuple display}
+    \lineii{\code{[\var{expressions}\ldots]}}	{List display}
+    \lineii{\code{\{\var{key}:\var{datum}\ldots\}}}{Dictionary display}
+    \lineii{\code{`\var{expressions}\ldots`}}	{String conversion}
+\end{tableii}

Added: vendor/Python/current/Doc/ref/ref6.tex
===================================================================
--- vendor/Python/current/Doc/ref/ref6.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/ref/ref6.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,928 @@
+\chapter{Simple statements \label{simple}}
+\indexii{simple}{statement}
+
+Simple statements are comprised within a single logical line.
+Several simple statements may occur on a single line separated
+by semicolons.  The syntax for simple statements is:
+
+\begin{productionlist}
+  \production{simple_stmt}{\token{expression_stmt}}
+  \productioncont{| \token{assert_stmt}}
+  \productioncont{| \token{assignment_stmt}}
+  \productioncont{| \token{augmented_assignment_stmt}}
+  \productioncont{| \token{pass_stmt}}
+  \productioncont{| \token{del_stmt}}
+  \productioncont{| \token{print_stmt}}
+  \productioncont{| \token{return_stmt}}
+  \productioncont{| \token{yield_stmt}}
+  \productioncont{| \token{raise_stmt}}
+  \productioncont{| \token{break_stmt}}
+  \productioncont{| \token{continue_stmt}}
+  \productioncont{| \token{import_stmt}}
+  \productioncont{| \token{global_stmt}}
+  \productioncont{| \token{exec_stmt}}
+\end{productionlist}
+
+
+\section{Expression statements \label{exprstmts}}
+\indexii{expression}{statement}
+
+Expression statements are used (mostly interactively) to compute and
+write a value, or (usually) to call a procedure (a function that
+returns no meaningful result; in Python, procedures return the value
+\code{None}).  Other uses of expression statements are allowed and
+occasionally useful.  The syntax for an expression statement is:
+
+\begin{productionlist}
+  \production{expression_stmt}
+             {\token{expression_list}}
+\end{productionlist}
+
+An expression statement evaluates the expression list (which may be a
+single expression).
+\indexii{expression}{list}
+
+In interactive mode, if the value is not \code{None}, it is converted
+to a string using the built-in \function{repr()}\bifuncindex{repr}
+function and the resulting string is written to standard output (see
+section~\ref{print}) on a line by itself.  (Expression statements
+yielding \code{None} are not written, so that procedure calls do not
+cause any output.)
+\obindex{None}
+\indexii{string}{conversion}
+\index{output}
+\indexii{standard}{output}
+\indexii{writing}{values}
+\indexii{procedure}{call}
+
+
+\section{Assert statements \label{assert}}
+
+Assert statements\stindex{assert} are a convenient way to insert
+debugging assertions\indexii{debugging}{assertions} into a program:
+
+\begin{productionlist}
+  \production{assert_stmt}
+             {"assert" \token{expression} ["," \token{expression}]}
+\end{productionlist}
+
+The simple form, \samp{assert expression}, is equivalent to
+
+\begin{verbatim}
+if __debug__:
+   if not expression: raise AssertionError
+\end{verbatim}
+
+The extended form, \samp{assert expression1, expression2}, is
+equivalent to
+
+\begin{verbatim}
+if __debug__:
+   if not expression1: raise AssertionError, expression2
+\end{verbatim}
+
+These equivalences assume that \code{__debug__}\ttindex{__debug__} and
+\exception{AssertionError}\exindex{AssertionError} refer to the built-in
+variables with those names.  In the current implementation, the
+built-in variable \code{__debug__} is \code{True} under normal
+circumstances, \code{False} when optimization is requested (command line
+option -O).  The current code generator emits no code for an assert
+statement when optimization is requested at compile time.  Note that it
+is unnecessary to include the source code for the expression that failed
+in the error message;
+it will be displayed as part of the stack trace.
+
+Assignments to \code{__debug__} are illegal.  The value for the
+built-in variable is determined when the interpreter starts.
+
+
+\section{Assignment statements \label{assignment}}
+
+Assignment statements\indexii{assignment}{statement} are used to
+(re)bind names to values and to modify attributes or items of mutable
+objects:
+\indexii{binding}{name}
+\indexii{rebinding}{name}
+\obindex{mutable}
+\indexii{attribute}{assignment}
+
+\begin{productionlist}
+  \production{assignment_stmt}
+             {(\token{target_list} "=")+
+              (\token{expression_list} | \token{yield_expression})}
+  \production{target_list}
+             {\token{target} ("," \token{target})* [","]}
+  \production{target}
+             {\token{identifier}}
+  \productioncont{| "(" \token{target_list} ")"}
+  \productioncont{| "[" \token{target_list} "]"}
+  \productioncont{| \token{attributeref}}
+  \productioncont{| \token{subscription}}
+  \productioncont{| \token{slicing}}
+\end{productionlist}
+
+(See section~\ref{primaries} for the syntax definitions for the last
+three symbols.)
+
+An assignment statement evaluates the expression list (remember that
+this can be a single expression or a comma-separated list, the latter
+yielding a tuple) and assigns the single resulting object to each of
+the target lists, from left to right.
+\indexii{expression}{list}
+
+Assignment is defined recursively depending on the form of the target
+(list).  When a target is part of a mutable object (an attribute
+reference, subscription or slicing), the mutable object must
+ultimately perform the assignment and decide about its validity, and
+may raise an exception if the assignment is unacceptable.  The rules
+observed by various types and the exceptions raised are given with the
+definition of the object types (see section~\ref{types}).
+\index{target}
+\indexii{target}{list}
+
+Assignment of an object to a target list is recursively defined as
+follows.
+\indexiii{target}{list}{assignment}
+
+\begin{itemize}
+\item
+If the target list is a single target: The object is assigned to that
+target.
+
+\item
+If the target list is a comma-separated list of targets: The object
+must be a sequence with the same number of items as there are
+targets in the target list, and the items are assigned, from left to
+right, to the corresponding targets.  (This rule is relaxed as of
+Python 1.5; in earlier versions, the object had to be a tuple.  Since
+strings are sequences, an assignment like \samp{a, b = "xy"} is
+now legal as long as the string has the right length.)
+
+\end{itemize}
+
+Assignment of an object to a single target is recursively defined as
+follows.
+
+\begin{itemize} % nested
+
+\item
+If the target is an identifier (name):
+
+\begin{itemize}
+
+\item
+If the name does not occur in a \keyword{global} statement in the current
+code block: the name is bound to the object in the current local
+namespace.
+\stindex{global}
+
+\item
+Otherwise: the name is bound to the object in the current global
+namespace.
+
+\end{itemize} % nested
+
+The name is rebound if it was already bound.  This may cause the
+reference count for the object previously bound to the name to reach
+zero, causing the object to be deallocated and its
+destructor\index{destructor} (if it has one) to be called.
+
+\item
+If the target is a target list enclosed in parentheses or in square
+brackets: The object must be a sequence with the same number of items
+as there are targets in the target list, and its items are assigned,
+from left to right, to the corresponding targets.
+
+\item
+If the target is an attribute reference: The primary expression in the
+reference is evaluated.  It should yield an object with assignable
+attributes; if this is not the case, \exception{TypeError} is raised.  That
+object is then asked to assign the assigned object to the given
+attribute; if it cannot perform the assignment, it raises an exception
+(usually but not necessarily \exception{AttributeError}).
+\indexii{attribute}{assignment}
+
+\item
+If the target is a subscription: The primary expression in the
+reference is evaluated.  It should yield either a mutable sequence
+object (such as a list) or a mapping object (such as a dictionary). Next,
+the subscript expression is evaluated.
+\indexii{subscription}{assignment}
+\obindex{mutable}
+
+If the primary is a mutable sequence object (such as a list), the subscript
+must yield a plain integer.  If it is negative, the sequence's length
+is added to it.  The resulting value must be a nonnegative integer
+less than the sequence's length, and the sequence is asked to assign
+the assigned object to its item with that index.  If the index is out
+of range, \exception{IndexError} is raised (assignment to a subscripted
+sequence cannot add new items to a list).
+\obindex{sequence}
+\obindex{list}
+
+If the primary is a mapping object (such as a dictionary), the subscript must
+have a type compatible with the mapping's key type, and the mapping is
+then asked to create a key/datum pair which maps the subscript to
+the assigned object.  This can either replace an existing key/value
+pair with the same key value, or insert a new key/value pair (if no
+key with the same value existed).
+\obindex{mapping}
+\obindex{dictionary}
+
+\item
+If the target is a slicing: The primary expression in the reference is
+evaluated.  It should yield a mutable sequence object (such as a list).  The
+assigned object should be a sequence object of the same type.  Next,
+the lower and upper bound expressions are evaluated, insofar they are
+present; defaults are zero and the sequence's length.  The bounds
+should evaluate to (small) integers.  If either bound is negative, the
+sequence's length is added to it.  The resulting bounds are clipped to
+lie between zero and the sequence's length, inclusive.  Finally, the
+sequence object is asked to replace the slice with the items of the
+assigned sequence.  The length of the slice may be different from the
+length of the assigned sequence, thus changing the length of the
+target sequence, if the object allows it.
+\indexii{slicing}{assignment}
+
+\end{itemize}
+        
+(In the current implementation, the syntax for targets is taken
+to be the same as for expressions, and invalid syntax is rejected
+during the code generation phase, causing less detailed error
+messages.)
+
+WARNING: Although the definition of assignment implies that overlaps
+between the left-hand side and the right-hand side are `safe' (for example
+\samp{a, b = b, a} swaps two variables), overlaps \emph{within} the
+collection of assigned-to variables are not safe!  For instance, the
+following program prints \samp{[0, 2]}:
+
+\begin{verbatim}
+x = [0, 1]
+i = 0
+i, x[i] = 1, 2
+print x
+\end{verbatim}
+
+
+\subsection{Augmented assignment statements \label{augassign}}
+
+Augmented assignment is the combination, in a single statement, of a binary
+operation and an assignment statement:
+\indexii{augmented}{assignment}
+\index{statement!assignment, augmented}
+
+\begin{productionlist}
+  \production{augmented_assignment_stmt}
+             {\token{target} \token{augop}
+              (\token{expression_list} | \token{yield_expression})}
+  \production{augop}
+             {"+=" | "-=" | "*=" | "/=" | "\%=" | "**="}
+  \productioncont{| ">>=" | "<<=" | "\&=" | "\textasciicircum=" | "|="}
+\end{productionlist}
+
+(See section~\ref{primaries} for the syntax definitions for the last
+three symbols.)
+
+An augmented assignment evaluates the target (which, unlike normal
+assignment statements, cannot be an unpacking) and the expression
+list, performs the binary operation specific to the type of assignment
+on the two operands, and assigns the result to the original
+target.  The target is only evaluated once.
+
+An augmented assignment expression like \code{x += 1} can be rewritten as
+\code{x = x + 1} to achieve a similar, but not exactly equal effect. In the
+augmented version, \code{x} is only evaluated once. Also, when possible, the
+actual operation is performed \emph{in-place}, meaning that rather than
+creating a new object and assigning that to the target, the old object is
+modified instead.
+
+With the exception of assigning to tuples and multiple targets in a single
+statement, the assignment done by augmented assignment statements is handled
+the same way as normal assignments. Similarly, with the exception of the
+possible \emph{in-place} behavior, the binary operation performed by
+augmented assignment is the same as the normal binary operations.
+
+For targets which are attribute references, the initial value is
+retrieved with a \method{getattr()} and the result is assigned with a
+\method{setattr()}.  Notice that the two methods do not necessarily
+refer to the same variable.  When \method{getattr()} refers to a class
+variable, \method{setattr()} still writes to an instance variable.
+For example:
+
+\begin{verbatim}
+class A:
+    x = 3    # class variable
+a = A()
+a.x += 1     # writes a.x as 4 leaving A.x as 3
+\end{verbatim}
+
+
+\section{The \keyword{pass} statement \label{pass}}
+\stindex{pass}
+
+\begin{productionlist}
+  \production{pass_stmt}
+             {"pass"}
+\end{productionlist}
+
+\keyword{pass} is a null operation --- when it is executed, nothing
+happens.  It is useful as a placeholder when a statement is
+required syntactically, but no code needs to be executed, for example:
+\indexii{null}{operation}
+
+\begin{verbatim}
+def f(arg): pass    # a function that does nothing (yet)
+
+class C: pass       # a class with no methods (yet)
+\end{verbatim}
+
+
+\section{The \keyword{del} statement \label{del}}
+\stindex{del}
+
+\begin{productionlist}
+  \production{del_stmt}
+             {"del" \token{target_list}}
+\end{productionlist}
+
+Deletion is recursively defined very similar to the way assignment is
+defined. Rather that spelling it out in full details, here are some
+hints.
+\indexii{deletion}{target}
+\indexiii{deletion}{target}{list}
+
+Deletion of a target list recursively deletes each target, from left
+to right.
+
+Deletion of a name removes the binding of that name 
+from the local or global namespace, depending on whether the name
+occurs in a \keyword{global} statement in the same code block.  If the
+name is unbound, a \exception{NameError} exception will be raised.
+\stindex{global}
+\indexii{unbinding}{name}
+
+It is illegal to delete a name from the local namespace if it occurs
+as a free variable\indexii{free}{variable} in a nested block.
+
+Deletion of attribute references, subscriptions and slicings
+is passed to the primary object involved; deletion of a slicing
+is in general equivalent to assignment of an empty slice of the
+right type (but even this is determined by the sliced object).
+\indexii{attribute}{deletion}
+
+
+\section{The \keyword{print} statement \label{print}}
+\stindex{print}
+
+\begin{productionlist}
+  \production{print_stmt}
+             {"print" ([\token{expression} ("," \token{expression})* [","]}
+  \productioncont{| ">>" \token{expression}
+                  [("," \token{expression})+ [","])}
+\end{productionlist}
+
+\keyword{print} evaluates each expression in turn and writes the
+resulting object to standard output (see below).  If an object is not
+a string, it is first converted to a string using the rules for string
+conversions.  The (resulting or original) string is then written.  A
+space is written before each object is (converted and) written, unless
+the output system believes it is positioned at the beginning of a
+line.  This is the case (1) when no characters have yet been written
+to standard output, (2) when the last character written to standard
+output is \character{\e n}, or (3) when the last write operation on
+standard output was not a \keyword{print} statement.  (In some cases
+it may be functional to write an empty string to standard output for
+this reason.)  \note{Objects which act like file objects but which are
+not the built-in file objects often do not properly emulate this
+aspect of the file object's behavior, so it is best not to rely on
+this.}
+\index{output}
+\indexii{writing}{values}
+
+A \character{\e n} character is written at the end, unless the
+\keyword{print} statement ends with a comma.  This is the only action
+if the statement contains just the keyword \keyword{print}.
+\indexii{trailing}{comma}
+\indexii{newline}{suppression}
+
+Standard output is defined as the file object named \code{stdout}
+in the built-in module \module{sys}.  If no such object exists, or if
+it does not have a \method{write()} method, a \exception{RuntimeError}
+exception is raised.
+\indexii{standard}{output}
+\refbimodindex{sys}
+\withsubitem{(in module sys)}{\ttindex{stdout}}
+\exindex{RuntimeError}
+
+\keyword{print} also has an extended\index{extended print statement}
+form, defined by the second portion of the syntax described above.
+This form is sometimes referred to as ``\keyword{print} chevron.''
+In this form, the first expression after the \code{>>} must
+evaluate to a ``file-like'' object, specifically an object that has a
+\method{write()} method as described above.  With this extended form,
+the subsequent expressions are printed to this file object.  If the
+first expression evaluates to \code{None}, then \code{sys.stdout} is
+used as the file for output.
+
+
+\section{The \keyword{return} statement \label{return}}
+\stindex{return}
+
+\begin{productionlist}
+  \production{return_stmt}
+             {"return" [\token{expression_list}]}
+\end{productionlist}
+
+\keyword{return} may only occur syntactically nested in a function
+definition, not within a nested class definition.
+\indexii{function}{definition}
+\indexii{class}{definition}
+
+If an expression list is present, it is evaluated, else \code{None}
+is substituted.
+
+\keyword{return} leaves the current function call with the expression
+list (or \code{None}) as return value.
+
+When \keyword{return} passes control out of a \keyword{try} statement
+with a \keyword{finally} clause, that \keyword{finally} clause is executed
+before really leaving the function.
+\kwindex{finally}
+
+In a generator function, the \keyword{return} statement is not allowed
+to include an \grammartoken{expression_list}.  In that context, a bare
+\keyword{return} indicates that the generator is done and will cause
+\exception{StopIteration} to be raised.
+
+
+\section{The \keyword{yield} statement \label{yield}}
+\stindex{yield}
+
+\begin{productionlist}
+  \production{yield_stmt}
+             {\token{yield_expression}}
+\end{productionlist}
+
+\index{generator!function}
+\index{generator!iterator}
+\index{function!generator}
+\exindex{StopIteration}
+
+The \keyword{yield} statement is only used when defining a generator
+function, and is only used in the body of the generator function.
+Using a \keyword{yield} statement in a function definition is
+sufficient to cause that definition to create a generator function
+instead of a normal function.
+
+When a generator function is called, it returns an iterator known as a
+generator iterator, or more commonly, a generator.  The body of the
+generator function is executed by calling the generator's
+\method{next()} method repeatedly until it raises an exception.
+
+When a \keyword{yield} statement is executed, the state of the
+generator is frozen and the value of \grammartoken{expression_list} is
+returned to \method{next()}'s caller.  By ``frozen'' we mean that all
+local state is retained, including the current bindings of local
+variables, the instruction pointer, and the internal evaluation stack:
+enough information is saved so that the next time \method{next()} is
+invoked, the function can proceed exactly as if the \keyword{yield}
+statement were just another external call.
+
+As of Python version 2.5, the \keyword{yield} statement is now
+allowed in the \keyword{try} clause of a \keyword{try} ...\ 
+\keyword{finally} construct.  If the generator is not resumed before
+it is finalized (by reaching a zero reference count or by being garbage
+collected), the generator-iterator's \method{close()} method will be
+called, allowing any pending \keyword{finally} clauses to execute.
+
+\begin{notice}
+In Python 2.2, the \keyword{yield} statement is only allowed
+when the \code{generators} feature has been enabled.  It will always
+be enabled in Python 2.3.  This \code{__future__} import statement can
+be used to enable the feature:
+
+\begin{verbatim}
+from __future__ import generators
+\end{verbatim}
+\end{notice}
+
+
+\begin{seealso}
+  \seepep{0255}{Simple Generators}
+         {The proposal for adding generators and the \keyword{yield}
+          statement to Python.}
+
+  \seepep{0342}{Coroutines via Enhanced Generators}
+         {The proposal that, among other generator enhancements,
+          proposed allowing \keyword{yield} to appear inside a
+          \keyword{try} ... \keyword{finally} block.}
+\end{seealso}
+
+
+\section{The \keyword{raise} statement \label{raise}}
+\stindex{raise}
+
+\begin{productionlist}
+  \production{raise_stmt}
+             {"raise" [\token{expression} ["," \token{expression}
+              ["," \token{expression}]]]}
+\end{productionlist}
+
+If no expressions are present, \keyword{raise} re-raises the last
+exception that was active in the current scope.  If no exception is
+active in the current scope, a \exception{TypeError} exception is
+raised indicating that this is an error (if running under IDLE, a
+\exception{Queue.Empty} exception is raised instead).
+\index{exception}
+\indexii{raising}{exception}
+
+Otherwise, \keyword{raise} evaluates the expressions to get three
+objects, using \code{None} as the value of omitted expressions.  The
+first two objects are used to determine the \emph{type} and
+\emph{value} of the exception.
+
+If the first object is an instance, the type of the exception is the
+class of the instance, the instance itself is the value, and the
+second object must be \code{None}.
+
+If the first object is a class, it becomes the type of the exception.
+The second object is used to determine the exception value: If it is
+an instance of the class, the instance becomes the exception value.
+If the second object is a tuple, it is used as the argument list for
+the class constructor; if it is \code{None}, an empty argument list is
+used, and any other object is treated as a single argument to the
+constructor.  The instance so created by calling the constructor is
+used as the exception value.
+
+If a third object is present and not \code{None}, it must be a
+traceback\obindex{traceback} object (see section~\ref{traceback}), and
+it is substituted instead of the current location as the place where
+the exception occurred.  If the third object is present and not a
+traceback object or \code{None}, a \exception{TypeError} exception is
+raised.  The three-expression form of \keyword{raise} is useful to
+re-raise an exception transparently in an except clause, but
+\keyword{raise} with no expressions should be preferred if the
+exception to be re-raised was the most recently active exception in
+the current scope.
+
+Additional information on exceptions can be found in
+section~\ref{exceptions}, and information about handling exceptions is
+in section~\ref{try}.
+
+
+\section{The \keyword{break} statement \label{break}}
+\stindex{break}
+
+\begin{productionlist}
+  \production{break_stmt}
+             {"break"}
+\end{productionlist}
+
+\keyword{break} may only occur syntactically nested in a \keyword{for}
+or \keyword{while} loop, but not nested in a function or class definition
+within that loop.
+\stindex{for}
+\stindex{while}
+\indexii{loop}{statement}
+
+It terminates the nearest enclosing loop, skipping the optional
+\keyword{else} clause if the loop has one.
+\kwindex{else}
+
+If a \keyword{for} loop is terminated by \keyword{break}, the loop control
+target keeps its current value.
+\indexii{loop control}{target}
+
+When \keyword{break} passes control out of a \keyword{try} statement
+with a \keyword{finally} clause, that \keyword{finally} clause is executed
+before really leaving the loop.
+\kwindex{finally}
+
+
+\section{The \keyword{continue} statement \label{continue}}
+\stindex{continue}
+
+\begin{productionlist}
+  \production{continue_stmt}
+             {"continue"}
+\end{productionlist}
+
+\keyword{continue} may only occur syntactically nested in a \keyword{for} or
+\keyword{while} loop, but not nested in a function or class definition or
+\keyword{finally} statement within that loop.\footnote{It may
+occur within an \keyword{except} or \keyword{else} clause.  The
+restriction on occurring in the \keyword{try} clause is implementor's
+laziness and will eventually be lifted.}
+It continues with the next cycle of the nearest enclosing loop.
+\stindex{for}
+\stindex{while}
+\indexii{loop}{statement}
+\kwindex{finally}
+
+
+\section{The \keyword{import} statement \label{import}}
+\stindex{import}
+\index{module!importing}
+\indexii{name}{binding}
+\kwindex{from}
+
+\begin{productionlist}
+  \production{import_stmt}
+             {"import" \token{module} ["as" \token{name}]
+                ( "," \token{module} ["as" \token{name}] )*}
+  \productioncont{| "from" \token{relative_module} "import" \token{identifier}
+                    ["as" \token{name}]}
+  \productioncont{  ( "," \token{identifier} ["as" \token{name}] )*}
+  \productioncont{| "from" \token{relative_module} "import" "("
+                    \token{identifier} ["as" \token{name}]}
+  \productioncont{  ( "," \token{identifier} ["as" \token{name}] )* [","] ")"}
+  \productioncont{| "from" \token{module} "import" "*"}
+  \production{module}
+             {(\token{identifier} ".")* \token{identifier}}
+  \production{relative_module}
+             {"."* \token{module} | "."+}
+  \production{name}
+             {\token{identifier}}
+\end{productionlist}
+
+Import statements are executed in two steps: (1) find a module, and
+initialize it if necessary; (2) define a name or names in the local
+namespace (of the scope where the \keyword{import} statement occurs).
+The first form (without \keyword{from}) repeats these steps for each
+identifier in the list.  The form with \keyword{from} performs step
+(1) once, and then performs step (2) repeatedly.
+
+In this context, to ``initialize'' a built-in or extension module means to
+call an initialization function that the module must provide for the purpose
+(in the reference implementation, the function's name is obtained by
+prepending string ``init'' to the module's name); to ``initialize'' a
+Python-coded module means to execute the module's body.
+  
+The system maintains a table of modules that have been or are being
+initialized,
+indexed by module name.  This table is
+accessible as \code{sys.modules}.  When a module name is found in
+this table, step (1) is finished.  If not, a search for a module
+definition is started.  When a module is found, it is loaded.  Details
+of the module searching and loading process are implementation and
+platform specific.  It generally involves searching for a ``built-in''
+module with the given name and then searching a list of locations
+given as \code{sys.path}.
+\withsubitem{(in module sys)}{\ttindex{modules}}
+\ttindex{sys.modules}
+\indexii{module}{name}
+\indexii{built-in}{module}
+\indexii{user-defined}{module}
+\refbimodindex{sys}
+\indexii{filename}{extension}
+\indexiii{module}{search}{path}
+
+If a built-in module is found,\indexii{module}{initialization} its
+built-in initialization code is executed and step (1) is finished.  If
+no matching file is found,
+\exception{ImportError}\exindex{ImportError} is raised.
+\index{code block}If a file is found, it is parsed,
+yielding an executable code block.  If a syntax error occurs,
+\exception{SyntaxError}\exindex{SyntaxError} is raised.  Otherwise, an
+empty module of the given name is created and inserted in the module
+table, and then the code block is executed in the context of this
+module.  Exceptions during this execution terminate step (1).
+
+When step (1) finishes without raising an exception, step (2) can
+begin.
+
+The first form of \keyword{import} statement binds the module name in
+the local namespace to the module object, and then goes on to import
+the next identifier, if any.  If the module name is followed by
+\keyword{as}, the name following \keyword{as} is used as the local
+name for the module. 
+
+The \keyword{from} form does not bind the module name: it goes through the
+list of identifiers, looks each one of them up in the module found in step
+(1), and binds the name in the local namespace to the object thus found. 
+As with the first form of \keyword{import}, an alternate local name can be
+supplied by specifying "\keyword{as} localname".  If a name is not found,
+\exception{ImportError} is raised.  If the list of identifiers is replaced
+by a star (\character{*}), all public names defined in the module are
+bound in the local namespace of the \keyword{import} statement..
+\indexii{name}{binding}
+\exindex{ImportError}
+
+The \emph{public names} defined by a module are determined by checking
+the module's namespace for a variable named \code{__all__}; if
+defined, it must be a sequence of strings which are names defined or
+imported by that module.  The names given in \code{__all__} are all
+considered public and are required to exist.  If \code{__all__} is not
+defined, the set of public names includes all names found in the
+module's namespace which do not begin with an underscore character
+(\character{_}).  \code{__all__} should contain the entire public API.
+It is intended to avoid accidentally exporting items that are not part
+of the API (such as library modules which were imported and used within
+the module).
+\withsubitem{(optional module attribute)}{\ttindex{__all__}}
+
+The \keyword{from} form with \samp{*} may only occur in a module
+scope.  If the wild card form of import --- \samp{import *} --- is
+used in a function and the function contains or is a nested block with
+free variables, the compiler will raise a \exception{SyntaxError}.
+
+\kwindex{from}
+\stindex{from}
+
+\strong{Hierarchical module names:}\indexiii{hierarchical}{module}{names}
+when the module names contains one or more dots, the module search
+path is carried out differently.  The sequence of identifiers up to
+the last dot is used to find a ``package''\index{packages}; the final
+identifier is then searched inside the package.  A package is
+generally a subdirectory of a directory on \code{sys.path} that has a
+file \file{__init__.py}.\ttindex{__init__.py}
+%
+[XXX Can't be bothered to spell this out right now; see the URL
+\url{http://www.python.org/doc/essays/packages.html} for more details, also
+about how the module search works from inside a package.]
+
+The built-in function \function{__import__()} is provided to support
+applications that determine which modules need to be loaded
+dynamically; refer to \ulink{Built-in
+Functions}{../lib/built-in-funcs.html} in the
+\citetitle[../lib/lib.html]{Python Library Reference} for additional
+information.
+\bifuncindex{__import__}
+
+\subsection{Future statements \label{future}}
+
+A \dfn{future statement}\indexii{future}{statement} is a directive to
+the compiler that a particular module should be compiled using syntax
+or semantics that will be available in a specified future release of
+Python.  The future statement is intended to ease migration to future
+versions of Python that introduce incompatible changes to the
+language.  It allows use of the new features on a per-module basis
+before the release in which the feature becomes standard.
+
+\begin{productionlist}[*]
+  \production{future_statement}
+             {"from" "__future__" "import" feature ["as" name]}
+  \productioncont{  ("," feature ["as" name])*}
+  \productioncont{| "from" "__future__" "import" "(" feature ["as" name]}
+  \productioncont{  ("," feature ["as" name])* [","] ")"}
+  \production{feature}{identifier}
+  \production{name}{identifier}
+\end{productionlist}
+
+A future statement must appear near the top of the module.  The only
+lines that can appear before a future statement are:
+
+\begin{itemize}
+
+\item the module docstring (if any),
+\item comments,
+\item blank lines, and
+\item other future statements.
+
+\end{itemize}
+
+The features recognized by Python 2.5 are \samp{absolute_import},
+\samp{division}, \samp{generators}, \samp{nested_scopes} and
+\samp{with_statement}.  \samp{generators} and \samp{nested_scopes} 
+are redundant in Python version 2.3 and above because they are always
+enabled. 
+
+A future statement is recognized and treated specially at compile
+time: Changes to the semantics of core constructs are often
+implemented by generating different code.  It may even be the case
+that a new feature introduces new incompatible syntax (such as a new
+reserved word), in which case the compiler may need to parse the
+module differently.  Such decisions cannot be pushed off until
+runtime.
+
+For any given release, the compiler knows which feature names have been
+defined, and raises a compile-time error if a future statement contains
+a feature not known to it.
+
+The direct runtime semantics are the same as for any import statement:
+there is a standard module \module{__future__}, described later, and
+it will be imported in the usual way at the time the future statement
+is executed.
+
+The interesting runtime semantics depend on the specific feature
+enabled by the future statement.
+
+Note that there is nothing special about the statement:
+
+\begin{verbatim}
+import __future__ [as name]
+\end{verbatim}
+
+That is not a future statement; it's an ordinary import statement with
+no special semantics or syntax restrictions.
+
+Code compiled by an \keyword{exec} statement or calls to the builtin functions
+\function{compile()} and \function{execfile()} that occur in a module
+\module{M} containing a future statement will, by default, use the new 
+syntax or semantics associated with the future statement.  This can,
+starting with Python 2.2 be controlled by optional arguments to
+\function{compile()} --- see the documentation of that function in the
+\citetitle[../lib/built-in-funcs.html]{Python Library Reference} for
+details.
+
+A future statement typed at an interactive interpreter prompt will
+take effect for the rest of the interpreter session.  If an
+interpreter is started with the \programopt{-i} option, is passed a
+script name to execute, and the script includes a future statement, it
+will be in effect in the interactive session started after the script
+is executed.
+
+\section{The \keyword{global} statement \label{global}}
+\stindex{global}
+
+\begin{productionlist}
+  \production{global_stmt}
+             {"global" \token{identifier} ("," \token{identifier})*}
+\end{productionlist}
+
+The \keyword{global} statement is a declaration which holds for the
+entire current code block.  It means that the listed identifiers are to be
+interpreted as globals.  It would be impossible to assign to a global
+variable without \keyword{global}, although free variables may refer
+to globals without being declared global.
+\indexiii{global}{name}{binding}
+
+Names listed in a \keyword{global} statement must not be used in the same
+code block textually preceding that \keyword{global} statement.
+
+Names listed in a \keyword{global} statement must not be defined as formal
+parameters or in a \keyword{for} loop control target, \keyword{class}
+definition, function definition, or \keyword{import} statement.
+
+(The current implementation does not enforce the latter two
+restrictions, but programs should not abuse this freedom, as future
+implementations may enforce them or silently change the meaning of the
+program.)
+
+\strong{Programmer's note:}
+the \keyword{global} is a directive to the parser.  It
+applies only to code parsed at the same time as the \keyword{global}
+statement.  In particular, a \keyword{global} statement contained in an
+\keyword{exec} statement does not affect the code block \emph{containing}
+the \keyword{exec} statement, and code contained in an \keyword{exec}
+statement is unaffected by \keyword{global} statements in the code
+containing the \keyword{exec} statement.  The same applies to the
+\function{eval()}, \function{execfile()} and \function{compile()} functions.
+\stindex{exec}
+\bifuncindex{eval}
+\bifuncindex{execfile}
+\bifuncindex{compile}
+
+
+\section{The \keyword{exec} statement \label{exec}}
+\stindex{exec}
+
+\begin{productionlist}
+  \production{exec_stmt}
+             {"exec" \token{or_expr}
+              ["in" \token{expression} ["," \token{expression}]]}
+\end{productionlist}
+
+This statement supports dynamic execution of Python code.  The first
+expression should evaluate to either a string, an open file object, or
+a code object.  If it is a string, the string is parsed as a suite of
+Python statements which is then executed (unless a syntax error
+occurs).  If it is an open file, the file is parsed until \EOF{} and
+executed.  If it is a code object, it is simply executed.  In all
+cases, the code that's executed is expected to be valid as file
+input (see section~\ref{file-input}, ``File input'').  Be aware that
+the \keyword{return} and \keyword{yield} statements may not be used
+outside of function definitions even within the context of code passed
+to the \keyword{exec} statement.
+
+In all cases, if the optional parts are omitted, the code is executed
+in the current scope.  If only the first expression after \keyword{in}
+is specified, it should be a dictionary, which will be used for both
+the global and the local variables.  If two expressions are given,
+they are used for the global and local variables, respectively.
+If provided, \var{locals} can be any mapping object.
+\versionchanged[formerly \var{locals} was required to be a dictionary]{2.4}
+
+As a side effect, an implementation may insert additional keys into
+the dictionaries given besides those corresponding to variable names
+set by the executed code.  For example, the current implementation
+may add a reference to the dictionary of the built-in module
+\module{__builtin__} under the key \code{__builtins__} (!).
+\ttindex{__builtins__}
+\refbimodindex{__builtin__}
+
+\strong{Programmer's hints:}
+dynamic evaluation of expressions is supported by the built-in
+function \function{eval()}.  The built-in functions
+\function{globals()} and \function{locals()} return the current global
+and local dictionary, respectively, which may be useful to pass around
+for use by \keyword{exec}.
+\bifuncindex{eval}
+\bifuncindex{globals}
+\bifuncindex{locals}
+
+  
+
+
+

Added: vendor/Python/current/Doc/ref/ref7.tex
===================================================================
--- vendor/Python/current/Doc/ref/ref7.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/ref/ref7.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,544 @@
+\chapter{Compound statements\label{compound}}
+\indexii{compound}{statement}
+
+Compound statements contain (groups of) other statements; they affect
+or control the execution of those other statements in some way.  In
+general, compound statements span multiple lines, although in simple
+incarnations a whole compound statement may be contained in one line.
+
+The \keyword{if}, \keyword{while} and \keyword{for} statements implement
+traditional control flow constructs.  \keyword{try} specifies exception
+handlers and/or cleanup code for a group of statements.  Function and
+class definitions are also syntactically compound statements.
+
+Compound statements consist of one or more `clauses.'  A clause
+consists of a header and a `suite.'  The clause headers of a
+particular compound statement are all at the same indentation level.
+Each clause header begins with a uniquely identifying keyword and ends
+with a colon.  A suite is a group of statements controlled by a
+clause.  A suite can be one or more semicolon-separated simple
+statements on the same line as the header, following the header's
+colon, or it can be one or more indented statements on subsequent
+lines.  Only the latter form of suite can contain nested compound
+statements; the following is illegal, mostly because it wouldn't be
+clear to which \keyword{if} clause a following \keyword{else} clause would
+belong:
+\index{clause}
+\index{suite}
+
+\begin{verbatim}
+if test1: if test2: print x
+\end{verbatim}
+
+Also note that the semicolon binds tighter than the colon in this
+context, so that in the following example, either all or none of the
+\keyword{print} statements are executed:
+
+\begin{verbatim}
+if x < y < z: print x; print y; print z
+\end{verbatim}
+
+Summarizing:
+
+\begin{productionlist}
+  \production{compound_stmt}
+             {\token{if_stmt}}
+  \productioncont{| \token{while_stmt}}
+  \productioncont{| \token{for_stmt}}
+  \productioncont{| \token{try_stmt}}
+  \productioncont{| \token{with_stmt}}
+  \productioncont{| \token{funcdef}}
+  \productioncont{| \token{classdef}}
+  \production{suite}
+             {\token{stmt_list} NEWLINE
+              | NEWLINE INDENT \token{statement}+ DEDENT}
+  \production{statement}
+             {\token{stmt_list} NEWLINE | \token{compound_stmt}}
+  \production{stmt_list}
+             {\token{simple_stmt} (";" \token{simple_stmt})* [";"]}
+\end{productionlist}
+
+Note that statements always end in a
+\code{NEWLINE}\index{NEWLINE token} possibly followed by a
+\code{DEDENT}.\index{DEDENT token} Also note that optional
+continuation clauses always begin with a keyword that cannot start a
+statement, thus there are no ambiguities (the `dangling
+\keyword{else}' problem is solved in Python by requiring nested
+\keyword{if} statements to be indented).
+\indexii{dangling}{else}
+
+The formatting of the grammar rules in the following sections places
+each clause on a separate line for clarity.
+
+
+\section{The \keyword{if} statement\label{if}}
+\stindex{if}
+
+The \keyword{if} statement is used for conditional execution:
+
+\begin{productionlist}
+  \production{if_stmt}
+             {"if" \token{expression} ":" \token{suite}}
+  \productioncont{( "elif" \token{expression} ":" \token{suite} )*}
+  \productioncont{["else" ":" \token{suite}]}
+\end{productionlist}
+
+It selects exactly one of the suites by evaluating the expressions one
+by one until one is found to be true (see section~\ref{Booleans} for
+the definition of true and false); then that suite is executed (and no
+other part of the \keyword{if} statement is executed or evaluated).  If
+all expressions are false, the suite of the \keyword{else} clause, if
+present, is executed.
+\kwindex{elif}
+\kwindex{else}
+
+
+\section{The \keyword{while} statement\label{while}}
+\stindex{while}
+\indexii{loop}{statement}
+
+The \keyword{while} statement is used for repeated execution as long
+as an expression is true:
+
+\begin{productionlist}
+  \production{while_stmt}
+             {"while" \token{expression} ":" \token{suite}}
+  \productioncont{["else" ":" \token{suite}]}
+\end{productionlist}
+
+This repeatedly tests the expression and, if it is true, executes the
+first suite; if the expression is false (which may be the first time it
+is tested) the suite of the \keyword{else} clause, if present, is
+executed and the loop terminates.
+\kwindex{else}
+
+A \keyword{break} statement executed in the first suite terminates the
+loop without executing the \keyword{else} clause's suite.  A
+\keyword{continue} statement executed in the first suite skips the rest
+of the suite and goes back to testing the expression.
+\stindex{break}
+\stindex{continue}
+
+
+\section{The \keyword{for} statement\label{for}}
+\stindex{for}
+\indexii{loop}{statement}
+
+The \keyword{for} statement is used to iterate over the elements of a
+sequence (such as a string, tuple or list) or other iterable object:
+\obindex{sequence}
+
+\begin{productionlist}
+  \production{for_stmt}
+             {"for" \token{target_list} "in" \token{expression_list}
+              ":" \token{suite}}
+  \productioncont{["else" ":" \token{suite}]}
+\end{productionlist}
+
+The expression list is evaluated once; it should yield an iterable
+object.  An iterator is created for the result of the
+{}\code{expression_list}.  The suite is then executed once for each
+item provided by the iterator, in the
+order of ascending indices.  Each item in turn is assigned to the
+target list using the standard rules for assignments, and then the
+suite is executed.  When the items are exhausted (which is immediately
+when the sequence is empty), the suite in the \keyword{else} clause, if
+present, is executed, and the loop terminates.
+\kwindex{in}
+\kwindex{else}
+\indexii{target}{list}
+
+A \keyword{break} statement executed in the first suite terminates the
+loop without executing the \keyword{else} clause's suite.  A
+\keyword{continue} statement executed in the first suite skips the rest
+of the suite and continues with the next item, or with the \keyword{else}
+clause if there was no next item.
+\stindex{break}
+\stindex{continue}
+
+The suite may assign to the variable(s) in the target list; this does
+not affect the next item assigned to it.
+
+The target list is not deleted when the loop is finished, but if the
+sequence is empty, it will not have been assigned to at all by the
+loop.  Hint: the built-in function \function{range()} returns a
+sequence of integers suitable to emulate the effect of Pascal's
+\code{for i := a to b do};
+e.g., \code{range(3)} returns the list \code{[0, 1, 2]}.
+\bifuncindex{range}
+\indexii{Pascal}{language}
+
+\warning{There is a subtlety when the sequence is being modified
+by the loop (this can only occur for mutable sequences, i.e. lists).
+An internal counter is used to keep track of which item is used next,
+and this is incremented on each iteration.  When this counter has
+reached the length of the sequence the loop terminates.  This means that
+if the suite deletes the current (or a previous) item from the
+sequence, the next item will be skipped (since it gets the index of
+the current item which has already been treated).  Likewise, if the
+suite inserts an item in the sequence before the current item, the
+current item will be treated again the next time through the loop.
+This can lead to nasty bugs that can be avoided by making a temporary
+copy using a slice of the whole sequence, e.g.,
+\index{loop!over mutable sequence}
+\index{mutable sequence!loop over}}
+
+\begin{verbatim}
+for x in a[:]:
+    if x < 0: a.remove(x)
+\end{verbatim}
+
+
+\section{The \keyword{try} statement\label{try}}
+\stindex{try}
+
+The \keyword{try} statement specifies exception handlers and/or cleanup
+code for a group of statements:
+
+\begin{productionlist}
+  \production{try_stmt} {try1_stmt | try2_stmt}
+  \production{try1_stmt}
+             {"try" ":" \token{suite}}
+  \productioncont{("except" [\token{expression}
+                             ["," \token{target}]] ":" \token{suite})+}
+  \productioncont{["else" ":" \token{suite}]}
+  \productioncont{["finally" ":" \token{suite}]}
+  \production{try2_stmt}
+             {"try" ":" \token{suite}}
+  \productioncont{"finally" ":" \token{suite}}
+\end{productionlist}
+
+\versionchanged[In previous versions of Python,
+\keyword{try}...\keyword{except}...\keyword{finally} did not work.
+\keyword{try}...\keyword{except} had to be nested in
+\keyword{try}...\keyword{finally}]{2.5}
+
+The \keyword{except} clause(s) specify one or more exception handlers.
+When no exception occurs in the
+\keyword{try} clause, no exception handler is executed.  When an
+exception occurs in the \keyword{try} suite, a search for an exception
+handler is started.  This search inspects the except clauses in turn until
+one is found that matches the exception.  An expression-less except
+clause, if present, must be last; it matches any exception.  For an
+except clause with an expression, that expression is evaluated, and the
+clause matches the exception if the resulting object is ``compatible''
+with the exception.  An object is compatible with an exception if it
+is the class or a base class of the exception object, a tuple
+containing an item compatible with the exception, or, in the
+(deprecated) case of string exceptions, is the raised string itself
+(note that the object identities must match, i.e. it must be the same
+string object, not just a string with the same value).
+\kwindex{except}
+
+If no except clause matches the exception, the search for an exception
+handler continues in the surrounding code and on the invocation stack.
+\footnote{The exception is propogated to the invocation stack only if
+there is no \keyword{finally} clause that negates the exception.}
+
+If the evaluation of an expression in the header of an except clause
+raises an exception, the original search for a handler is canceled
+and a search starts for the new exception in the surrounding code and
+on the call stack (it is treated as if the entire \keyword{try} statement
+raised the exception).
+
+When a matching except clause is found, the exception is assigned to
+the target specified in that except clause, if present, and the except
+clause's suite is executed.  All except clauses must have an
+executable block.  When the end of this block is reached, execution
+continues normally after the entire try statement.  (This means that
+if two nested handlers exist for the same exception, and the exception
+occurs in the try clause of the inner handler, the outer handler will
+not handle the exception.)
+
+Before an except clause's suite is executed, details about the
+exception are assigned to three variables in the
+\module{sys}\refbimodindex{sys} module: \code{sys.exc_type} receives
+the object identifying the exception; \code{sys.exc_value} receives
+the exception's parameter; \code{sys.exc_traceback} receives a
+traceback object\obindex{traceback} (see section~\ref{traceback})
+identifying the point in the program where the exception occurred.
+These details are also available through the \function{sys.exc_info()}
+function, which returns a tuple \code{(\var{exc_type}, \var{exc_value},
+\var{exc_traceback})}.  Use of the corresponding variables is
+deprecated in favor of this function, since their use is unsafe in a
+threaded program.  As of Python 1.5, the variables are restored to
+their previous values (before the call) when returning from a function
+that handled an exception.
+\withsubitem{(in module sys)}{\ttindex{exc_type}
+  \ttindex{exc_value}\ttindex{exc_traceback}}
+
+The optional \keyword{else} clause is executed if and when control
+flows off the end of the \keyword{try} clause.\footnote{
+  Currently, control ``flows off the end'' except in the case of an
+  exception or the execution of a \keyword{return},
+  \keyword{continue}, or \keyword{break} statement.
+} Exceptions in the \keyword{else} clause are not handled by the
+preceding \keyword{except} clauses.
+\kwindex{else}
+\stindex{return}
+\stindex{break}
+\stindex{continue}
+
+If \keyword{finally} is present, it specifies a `cleanup' handler.  The
+\keyword{try} clause is executed, including any \keyword{except} and
+\keyword{else} clauses.  If an exception occurs in any of the clauses
+and is not handled, the exception is temporarily saved. The
+\keyword{finally} clause is executed.  If there is a saved exception,
+it is re-raised at the end of the \keyword{finally} clause.
+If the \keyword{finally} clause raises another exception or
+executes a \keyword{return} or \keyword{break} statement, the saved
+exception is lost.  The exception information is not available to the
+program during execution of the \keyword{finally} clause.
+\kwindex{finally}
+
+When a \keyword{return}, \keyword{break} or \keyword{continue} statement is
+executed in the \keyword{try} suite of a \keyword{try}...\keyword{finally}
+statement, the \keyword{finally} clause is also executed `on the way out.' A
+\keyword{continue} statement is illegal in the \keyword{finally} clause.
+(The reason is a problem with the current implementation --- this
+restriction may be lifted in the future).
+\stindex{return}
+\stindex{break}
+\stindex{continue}
+
+Additional information on exceptions can be found in
+section~\ref{exceptions}, and information on using the \keyword{raise}
+statement to generate exceptions may be found in section~\ref{raise}.
+
+
+\section{The \keyword{with} statement\label{with}}
+\stindex{with}
+
+\versionadded{2.5}
+
+The \keyword{with} statement is used to wrap the execution of a block
+with methods defined by a context manager (see
+section~\ref{context-managers}). This allows common
+\keyword{try}...\keyword{except}...\keyword{finally} usage patterns to
+be encapsulated for convenient reuse.
+
+\begin{productionlist}
+  \production{with_stmt}
+  {"with" \token{expression} ["as" \token{target}] ":" \token{suite}}
+\end{productionlist}
+
+The execution of the \keyword{with} statement proceeds as follows:
+
+\begin{enumerate}
+
+\item The context expression is evaluated to obtain a context manager.
+
+\item The context manager's \method{__enter__()} method is invoked.
+
+\item If a target was included in the \keyword{with}
+statement, the return value from \method{__enter__()} is assigned to it.
+
+\note{The \keyword{with} statement guarantees that if the
+\method{__enter__()} method returns without an error, then
+\method{__exit__()} will always be called. Thus, if an error occurs
+during the assignment to the target list, it will be treated the same as
+an error occurring within the suite would be. See step 5 below.}
+
+\item The suite is executed.
+
+\item The context manager's \method{__exit__()} method is invoked. If
+an exception caused the suite to be exited, its type, value, and
+traceback are passed as arguments to \method{__exit__()}. Otherwise,
+three \constant{None} arguments are supplied.
+
+If the suite was exited due to an exception, and the return
+value from the \method{__exit__()} method was false, the exception is
+reraised. If the return value was true, the exception is suppressed, and
+execution continues with the statement following the \keyword{with}
+statement.
+
+If the suite was exited for any reason other than an exception, the
+return value from \method{__exit__()} is ignored, and execution proceeds
+at the normal location for the kind of exit that was taken.
+
+\end{enumerate}
+
+\begin{notice}
+In Python 2.5, the \keyword{with} statement is only allowed
+when the \code{with_statement} feature has been enabled.  It will always
+be enabled in Python 2.6.  This \code{__future__} import statement can
+be used to enable the feature:
+
+\begin{verbatim}
+from __future__ import with_statement
+\end{verbatim}
+\end{notice}
+
+\begin{seealso}
+  \seepep{0343}{The "with" statement}
+         {The specification, background, and examples for the
+          Python \keyword{with} statement.}
+\end{seealso}
+
+\section{Function definitions\label{function}}
+\indexii{function}{definition}
+\stindex{def}
+
+A function definition defines a user-defined function object (see
+section~\ref{types}):
+\obindex{user-defined function}
+\obindex{function}
+
+\begin{productionlist}
+  \production{funcdef}
+             {[\token{decorators}] "def" \token{funcname} "(" [\token{parameter_list}] ")"
+              ":" \token{suite}}
+  \production{decorators}
+             {\token{decorator}+}
+  \production{decorator}
+             {"@" \token{dotted_name} ["(" [\token{argument_list} [","]] ")"] NEWLINE}
+  \production{dotted_name}
+             {\token{identifier} ("." \token{identifier})*}
+  \production{parameter_list}
+                 {(\token{defparameter} ",")*}
+  \productioncont{(~~"*" \token{identifier} [, "**" \token{identifier}]}
+  \productioncont{ | "**" \token{identifier}}
+  \productioncont{ | \token{defparameter} [","] )}
+  \production{defparameter}
+             {\token{parameter} ["=" \token{expression}]}
+  \production{sublist}
+             {\token{parameter} ("," \token{parameter})* [","]}
+  \production{parameter}
+             {\token{identifier} | "(" \token{sublist} ")"}
+  \production{funcname}
+             {\token{identifier}}
+\end{productionlist}
+
+A function definition is an executable statement.  Its execution binds
+the function name in the current local namespace to a function object
+(a wrapper around the executable code for the function).  This
+function object contains a reference to the current global namespace
+as the global namespace to be used when the function is called.
+\indexii{function}{name}
+\indexii{name}{binding}
+
+The function definition does not execute the function body; this gets
+executed only when the function is called.
+
+A function definition may be wrapped by one or more decorator expressions.
+Decorator expressions are evaluated when the function is defined, in the scope
+that contains the function definition.  The result must be a callable,
+which is invoked with the function object as the only argument.
+The returned value is bound to the function name instead of the function
+object.  Multiple decorators are applied in nested fashion.
+For example, the following code:
+
+\begin{verbatim}
+ at f1(arg)
+ at f2
+def func(): pass
+\end{verbatim}
+
+is equivalent to:
+
+\begin{verbatim}
+def func(): pass
+func = f1(arg)(f2(func))
+\end{verbatim}
+
+When one or more top-level parameters have the form \var{parameter}
+\code{=} \var{expression}, the function is said to have ``default
+parameter values.''  For a parameter with a
+default value, the corresponding argument may be omitted from a call,
+in which case the parameter's default value is substituted.  If a
+parameter has a default value, all following parameters must also have
+a default value --- this is a syntactic restriction that is not
+expressed by the grammar.
+\indexiii{default}{parameter}{value}
+
+\strong{Default parameter values are evaluated when the function
+definition is executed.}  This means that the expression is evaluated
+once, when the function is defined, and that that same
+``pre-computed'' value is used for each call.  This is especially
+important to understand when a default parameter is a mutable object,
+such as a list or a dictionary: if the function modifies the object
+(e.g. by appending an item to a list), the default value is in effect
+modified.  This is generally not what was intended.  A way around this 
+is to use \code{None} as the default, and explicitly test for it in
+the body of the function, e.g.:
+
+\begin{verbatim}
+def whats_on_the_telly(penguin=None):
+    if penguin is None:
+        penguin = []
+    penguin.append("property of the zoo")
+    return penguin
+\end{verbatim}
+
+Function call semantics are described in more detail in
+section~\ref{calls}.
+A function call always assigns values to all parameters mentioned in
+the parameter list, either from position arguments, from keyword
+arguments, or from default values.  If the form ``\code{*identifier}''
+is present, it is initialized to a tuple receiving any excess
+positional parameters, defaulting to the empty tuple.  If the form
+``\code{**identifier}'' is present, it is initialized to a new
+dictionary receiving any excess keyword arguments, defaulting to a
+new empty dictionary.
+
+It is also possible to create anonymous functions (functions not bound
+to a name), for immediate use in expressions.  This uses lambda forms,
+described in section~\ref{lambda}.  Note that the lambda form is
+merely a shorthand for a simplified function definition; a function
+defined in a ``\keyword{def}'' statement can be passed around or
+assigned to another name just like a function defined by a lambda
+form.  The ``\keyword{def}'' form is actually more powerful since it
+allows the execution of multiple statements.
+\indexii{lambda}{form}
+
+\strong{Programmer's note:} Functions are first-class objects.  A
+``\code{def}'' form executed inside a function definition defines a
+local function that can be returned or passed around.  Free variables
+used in the nested function can access the local variables of the
+function containing the def.  See section~\ref{naming} for details.
+
+
+\section{Class definitions\label{class}}
+\indexii{class}{definition}
+\stindex{class}
+
+A class definition defines a class object (see section~\ref{types}):
+\obindex{class}
+
+\begin{productionlist}
+  \production{classdef}
+             {"class" \token{classname} [\token{inheritance}] ":"
+              \token{suite}}
+  \production{inheritance}
+             {"(" [\token{expression_list}] ")"}
+  \production{classname}
+             {\token{identifier}}
+\end{productionlist}
+
+A class definition is an executable statement.  It first evaluates the
+inheritance list, if present.  Each item in the inheritance list
+should evaluate to a class object or class type which allows
+subclassing.  The class's suite is then executed
+in a new execution frame (see section~\ref{naming}), using a newly
+created local namespace and the original global namespace.
+(Usually, the suite contains only function definitions.)  When the
+class's suite finishes execution, its execution frame is discarded but
+its local namespace is saved.  A class object is then created using
+the inheritance list for the base classes and the saved local
+namespace for the attribute dictionary.  The class name is bound to this
+class object in the original local namespace.
+\index{inheritance}
+\indexii{class}{name}
+\indexii{name}{binding}
+\indexii{execution}{frame}
+
+\strong{Programmer's note:} Variables defined in the class definition
+are class variables; they are shared by all instances.  To define
+instance variables, they must be given a value in the
+\method{__init__()} method or in another method.  Both class and
+instance variables are accessible through the notation
+``\code{self.name}'', and an instance variable hides a class variable
+with the same name when accessed in this way.  Class variables with
+immutable values can be used as defaults for instance variables.
+For new-style classes, descriptors can be used to create instance
+variables with different implementation details.

Added: vendor/Python/current/Doc/ref/ref8.tex
===================================================================
--- vendor/Python/current/Doc/ref/ref8.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/ref/ref8.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,112 @@
+\chapter{Top-level components\label{top-level}}
+
+The Python interpreter can get its input from a number of sources:
+from a script passed to it as standard input or as program argument,
+typed in interactively, from a module source file, etc.  This chapter
+gives the syntax used in these cases.
+\index{interpreter}
+
+
+\section{Complete Python programs\label{programs}}
+\index{program}
+
+While a language specification need not prescribe how the language
+interpreter is invoked, it is useful to have a notion of a complete
+Python program.  A complete Python program is executed in a minimally
+initialized environment: all built-in and standard modules are
+available, but none have been initialized, except for \module{sys}
+(various system services), \module{__builtin__} (built-in functions,
+exceptions and \code{None}) and \module{__main__}.  The latter is used
+to provide the local and global namespace for execution of the
+complete program.
+\refbimodindex{sys}
+\refbimodindex{__main__}
+\refbimodindex{__builtin__}
+
+The syntax for a complete Python program is that for file input,
+described in the next section.
+
+The interpreter may also be invoked in interactive mode; in this case,
+it does not read and execute a complete program but reads and executes
+one statement (possibly compound) at a time.  The initial environment
+is identical to that of a complete program; each statement is executed
+in the namespace of \module{__main__}.
+\index{interactive mode}
+\refbimodindex{__main__}
+
+Under \UNIX, a complete program can be passed to the interpreter in
+three forms: with the \programopt{-c} \var{string} command line option, as a
+file passed as the first command line argument, or as standard input.
+If the file or standard input is a tty device, the interpreter enters
+interactive mode; otherwise, it executes the file as a complete
+program.
+\index{UNIX}
+\index{command line}
+\index{standard input}
+
+
+\section{File input\label{file-input}}
+
+All input read from non-interactive files has the same form:
+
+\begin{productionlist}
+  \production{file_input}
+             {(NEWLINE | \token{statement})*}
+\end{productionlist}
+
+This syntax is used in the following situations:
+
+\begin{itemize}
+
+\item when parsing a complete Python program (from a file or from a string);
+
+\item when parsing a module;
+
+\item when parsing a string passed to the \keyword{exec} statement;
+
+\end{itemize}
+
+
+\section{Interactive input\label{interactive}}
+
+Input in interactive mode is parsed using the following grammar:
+
+\begin{productionlist}
+  \production{interactive_input}
+             {[\token{stmt_list}] NEWLINE | \token{compound_stmt} NEWLINE}
+\end{productionlist}
+
+Note that a (top-level) compound statement must be followed by a blank
+line in interactive mode; this is needed to help the parser detect the
+end of the input.
+
+
+\section{Expression input\label{expression-input}}
+\index{input}
+
+There are two forms of expression input.  Both ignore leading
+whitespace.
+The string argument to \function{eval()} must have the following form:
+\bifuncindex{eval}
+
+\begin{productionlist}
+  \production{eval_input}
+             {\token{expression_list} NEWLINE*}
+\end{productionlist}
+
+The input line read by \function{input()} must have the following form:
+\bifuncindex{input}
+
+\begin{productionlist}
+  \production{input_input}
+             {\token{expression_list} NEWLINE}
+\end{productionlist}
+
+Note: to read `raw' input line without interpretation, you can use the
+built-in function \function{raw_input()} or the \method{readline()} method
+of file objects.
+\obindex{file}
+\index{input!raw}
+\index{raw input}
+\bifuncindex{raw_input}
+\withsubitem{(file method)}{\ttindex{readline()}}

Added: vendor/Python/current/Doc/ref/reswords.py
===================================================================
--- vendor/Python/current/Doc/ref/reswords.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/ref/reswords.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,23 @@
+"""Spit out the Python reserved words table."""
+
+import keyword
+
+ncols = 5
+
+def main():
+    words = keyword.kwlist[:]
+    words.sort()
+    colwidth = 1 + max(map(len, words))
+    nwords = len(words)
+    nrows = (nwords + ncols - 1) / ncols
+    for irow in range(nrows):
+        for icol in range(ncols):
+            i = irow + icol * nrows
+            if 0 <= i < nwords:
+                word = words[i]
+            else:
+                word = ""
+            print "%-*s" % (colwidth, word),
+        print
+
+main()

Added: vendor/Python/current/Doc/templates/howto.tex
===================================================================
--- vendor/Python/current/Doc/templates/howto.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/templates/howto.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,112 @@
+% Complete documentation on the extended LaTeX markup used for Python
+% documentation is available in ``Documenting Python'', which is part
+% of the standard documentation for Python.  It may be found online
+% at:
+%
+%     http://www.python.org/doc/current/doc/doc.html
+
+\documentclass{howto}
+
+%  This is a template for short or medium-size Python-related documents, 
+% mostly notably the series of HOWTOs, but it can be used for any
+% document you like.   
+
+% The title should be descriptive enough for people to be able to find
+% the relevant document. 
+\title{Spammifying Sprockets in Python}
+
+% Increment the release number whenever significant changes are made.
+% The author and/or editor can define 'significant' however they like.
+\release{0.00}
+
+% At minimum, give your name and an email address.  You can include a
+% snail-mail address if you like.
+\author{Me, 'cause I wrote it}
+\authoraddress{Me, 'cause I'm self-employed.}
+
+\begin{document}
+\maketitle
+
+% This makes the Abstract go on a separate page in the HTML version;
+% if a copyright notice is used, it should go immediately after this.
+%
+\ifhtml
+\chapter*{Front Matter\label{front}}
+\fi
+
+% Copyright statement should go here, if needed.
+% ...
+
+% The abstract should be a paragraph or two long, and describe the
+% scope of the document.
+\begin{abstract}
+\noindent
+This document describes how to spammify sprockets.  It is a useful
+example of a Python HOWTO document.  It is not dependent on any
+particular sprocket implementation, and includes a Python-based
+implementation in the \module{sprunkit} module.
+\end{abstract}
+
+\tableofcontents
+
+Spammifying sprockets from Python is both fun and entertaining.
+Applying the techniques described here, you can also fill your hard
+disk quite effectively.
+
+\section{What is Sprocket Spammification?}
+
+You have to ask?  It's the only thing to do to your sprockets!
+
+
+\section{Why Use Python?}
+
+Python is an excellent language from which to spammify your sprockets
+since you can do it on any platform.
+
+
+\section{Software Requirements}
+
+You need to have the following software installed:
+
+% The {itemize} environment uses a bullet for each \item.  If you want the 
+% \item's numbered, use the {enumerate} environment instead.
+\begin{itemize}
+  \item  Python 1.9.
+  \item  Some sprocket definition files.
+  \item  At least one sprocket system implementation.
+\end{itemize}
+
+Note that the \module{sprunkit} is provided with this package and
+implements ActiveSprockets in Python.
+
+
+% The preceding sections will have been written in a gentler,
+% introductory style.  You may also wish to include a reference
+% section, documenting all the functions/exceptions/constants.
+% Often, these will be placed in separate files and input like this:
+
+\input{module}
+
+
+\appendix
+
+\section{This is an Appendix}
+
+To create an appendix in a Python HOWTO document, use markup like
+this:
+
+\begin{verbatim}
+\appendix
+
+\section{This is an Appendix}
+
+To create an appendix in a Python HOWTO document, ....
+
+
+\section{This is another}
+
+Just add another \section{}, but don't say \appendix again.
+\end{verbatim}
+
+
+\end{document}

Added: vendor/Python/current/Doc/templates/manual.tex
===================================================================
--- vendor/Python/current/Doc/templates/manual.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/templates/manual.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,89 @@
+% Complete documentation on the extended LaTeX markup used for Python
+% documentation is available in ``Documenting Python'', which is part
+% of the standard documentation for Python.  It may be found online
+% at:
+%
+%     http://www.python.org/doc/current/doc/doc.html
+
+\documentclass{manual}
+
+\title{Big Python Manual}
+
+\author{Your Name Here}
+
+% Please at least include a long-lived email address;
+% the rest is at your discretion.
+\authoraddress{
+	Organization name, if applicable \\
+	Street address, if you want to use it \\
+	Email: \email{your-email at your.domain}
+}
+
+\date{April 30, 1999}		% update before release!
+				% Use an explicit date so that reformatting
+				% doesn't cause a new date to be used.  Setting
+				% the date to \today can be used during draft
+				% stages to make it easier to handle versions.
+
+\release{x.y}			% release version; this is used to define the
+				% \version macro
+
+\makeindex			% tell \index to actually write the .idx file
+\makemodindex			% If this contains a lot of module sections.
+
+
+\begin{document}
+
+\maketitle
+
+% This makes the contents more accessible from the front page of the HTML.
+\ifhtml
+\chapter*{Front Matter\label{front}}
+\fi
+
+%\input{copyright}
+
+\begin{abstract}
+
+\noindent
+Big Python is a special version of Python for users who require larger 
+keys on their keyboards.  It accommodates their special needs by ...
+
+\end{abstract}
+
+\tableofcontents
+
+
+\chapter{...}
+
+My chapter.
+
+
+\appendix
+\chapter{...}
+
+My appendix.
+
+The \code{\e appendix} markup need not be repeated for additional
+appendices.
+
+
+%
+%  The ugly "%begin{latexonly}" pseudo-environments are really just to
+%  keep LaTeX2HTML quiet during the \renewcommand{} macros; they're
+%  not really valuable.
+%
+%  If you don't want the Module Index, you can remove all of this up
+%  until the second \input line.
+%
+%begin{latexonly}
+\renewcommand{\indexname}{Module Index}
+%end{latexonly}
+\input{mod\jobname.ind}		% Module Index
+
+%begin{latexonly}
+\renewcommand{\indexname}{Index}
+%end{latexonly}
+\input{\jobname.ind}			% Index
+
+\end{document}

Added: vendor/Python/current/Doc/templates/module.tex
===================================================================
--- vendor/Python/current/Doc/templates/module.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/templates/module.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,170 @@
+% Template for a library manual section.
+% PLEASE REMOVE THE COMMENTS AFTER USING THE TEMPLATE
+%
+% Complete documentation on the extended LaTeX markup used for Python
+% documentation is available in ``Documenting Python'', which is part
+% of the standard documentation for Python.  It may be found online
+% at:
+%
+%     http://www.python.org/doc/current/doc/doc.html
+
+% ==== 0. ====
+% Copy this file to <mydir>/lib<mymodule>.tex, and edit that file
+% according to the instructions below.
+
+
+% ==== 1. ====
+% The section prologue.  Give the section a title and provide some
+% meta-information.  References to the module should use
+% \refbimodindex, \refstmodindex, \refexmodindex or \refmodindex, as
+% appropriate.
+
+\section{\module{spam} ---
+         Short description, for section title and table of contents}
+
+% Choose one of these to specify the module module name.  If there's
+% an underscore in the name, use
+% \declaremodule[modname]{...}{mod_name} instead.
+%
+\declaremodule{builtin}{spam}		% standard library, in C
+\declaremodule{standard}{spam}		% standard library, in Python
+\declaremodule{extension}{spam}		% not standard, in C
+\declaremodule{}{spam}			% not standard, in Python
+
+% Portability statement:  Uncomment and fill in the parameter to specify the
+% availability of the module.  The parameter can be Unix, IRIX, SunOS, Mac,
+% Windows, or lots of other stuff.  When ``Mac'' is specified, the availability
+% statement will say ``Macintosh'' and the Module Index may say ``Mac''.
+% Please use a name that has already been used whenever applicable.  If this
+% is omitted, no availability statement is produced or implied.
+%
+%   \platform{Unix}
+
+% These apply to all modules, and may be given more than once:
+
+\moduleauthor{name}{email}		% Author of the module code;
+					% omit if not known.
+\sectionauthor{name}{email}		% Author of the documentation,
+					% even if not a module section.
+
+
+% Leave at least one blank line after this, to simplify ad-hoc tools
+% that are sometimes used to massage these files.
+\modulesynopsis{This is a one-line description, for the chapter header.}
+
+
+% ==== 2. ====
+% Give a short overview of what the module does.
+% If it is platform specific, mention this.
+% Mention other important restrictions or general operating principles.
+% For example:
+
+The \module{spam} module defines operations for handling cans of Spam.
+It knows the four generally available Spam varieties and understands
+both can sizes.
+
+Because spamification requires \UNIX{} process management, the module
+is only available on genuine \UNIX{} systems.
+
+
+% ==== 3. ====
+% List the public functions defined by the module.  Begin with a
+% standard phrase.  You may also list the exceptions and other data
+% items defined in the module, insofar as they are important for the
+% user.
+
+The \module{spam} module defines the following functions:
+
+% ---- 3.1. ----
+% For each function, use a ``funcdesc'' block.  This has exactly two
+% parameters (each parameters is contained in a set of curly braces):
+% the first parameter is the function name (this automatically
+% generates an index entry); the second parameter is the function's
+% argument list.  If there are no arguments, use an empty pair of
+% curly braces.  If there is more than one argument, separate the
+% arguments with backslash-comma.  Optional parts of the parameter
+% list are contained in \optional{...} (this generates a set of square
+% brackets around its parameter).  Arguments are automatically set in
+% italics in the parameter list.  Each argument should be mentioned at
+% least once in the description; each usage (even inside \code{...})
+% should be enclosed in \var{...}.
+
+\begin{funcdesc}{open}{filename\optional{, mode\optional{, buffersize}}}
+Open the file \var{filename} as a can of Spam.  The optional
+\var{mode} and \var{buffersize} arguments specify the read/write mode
+(\code{'r'} (default) or \code{'w'}) and the buffer size (default:
+system dependent).
+\end{funcdesc}
+
+% ---- 3.2. ----
+% Data items are described using a ``datadesc'' block.  This has only
+% one parameter: the item's name.
+
+\begin{datadesc}{cansize}
+The default can size, in ounces.  Legal values are 7 and 12.  The
+default varies per supermarket.  This variable should not be changed
+once the \function{open()} function has been called.
+\end{datadesc}
+
+% --- 3.3. ---
+% Exceptions are described using a ``excdesc'' block.  This has only
+% one parameter: the exception name.  Exceptions defined as classes in
+% the source code should be documented using this environment, but
+% constructor parameters must be omitted.
+
+\begin{excdesc}{error}
+Exception raised when an operation fails for a Spam specific reason.
+The exception argument is a string describing the reason of the
+failure.
+\end{excdesc}
+
+% ---- 3.4. ----
+% Other standard environments:
+%
+%  classdesc	- Python classes; same arguments are funcdesc
+%  methoddesc	- methods, like funcdesc but has an optional parameter 
+%		  to give the type name: \begin{methoddesc}[mytype]{name}{args}
+%		  By default, the type name will be the name of the
+%		  last class defined using classdesc.  The type name
+%		  is required if the type is implemented in C (because 
+%		  there's no classdesc) or if the class isn't directly 
+%		  documented (if it's private).
+%  memberdesc	- data members, like datadesc, but with an optional
+%		  type name like methoddesc.
+
+
+% ==== 4. ====
+% Now is probably a good time for a complete example.  (Alternatively,
+% an example giving the flavor of the module may be given before the
+% detailed list of functions.)
+
+\subsection{Example \label{spam-example}}
+
+The following example demonstrates how to open a can of spam using the
+\module{spam} module.
+
+\begin{verbatim}
+>>> import spam
+>>> can = spam.open('/etc/passwd')
+>>> can.empty()
+>>> can.close()
+\end{verbatim}
+% Note that there is no trailing ">>> " prompt shown.
+
+% ==== 5. ====
+% If your module defines new object types (for a built-in module) or
+% classes (for a module written in Python), you should list the
+% methods and instance variables (if any) of each type or class in a
+% separate subsection.
+
+\subsection{Spam Objects}
+\label{spam-objects}
+% This label is generally useful for referencing this section, but is
+% also used to give a filename when generating HTML.
+
+Spam objects, as returned by \function{open()} above, have the
+following methods:
+
+\begin{methoddesc}[spam]{empty}{}
+Empty the can into the trash.
+\end{methoddesc}

Added: vendor/Python/current/Doc/templates/whatsnewXY.tex
===================================================================
--- vendor/Python/current/Doc/templates/whatsnewXY.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/templates/whatsnewXY.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,149 @@
+\documentclass{howto}
+\usepackage{distutils}
+% $Id: whatsnewXY.tex 33728 2003-07-31 01:17:22Z montanaro $
+
+% When creating a new ``What's New'' document, copy this to
+% ../whatsnew/whatsnewXY.tex, where X is replaced by the major version
+% number and Y, by the minor version number for the release of Python
+% being described.
+%
+% The following replacements need to be made in the text:
+%
+% X.Y   -- the version of Python this document describes
+% X.Y-1 -- previous minor release (not a maintenance release)
+% X.Y-2 -- minor release before that one (optional; search the
+%          template to see the usage
+%
+% Once done, write and edit to your heart's content!
+
+\title{What's New in Python X.Y}
+\release{0.0}
+\author{Young Author}
+\authoraddress{\email{ya at example.com}}
+
+\begin{document}
+\maketitle
+\tableofcontents
+
+This article explains the new features in Python X.Y.  No release date
+for Python X.Y has been set; expect that this will happen next year.
+
+% Compare with previous release in 2 - 3 sentences here.
+
+This article doesn't attempt to provide a complete specification of
+the new features, but instead provides a convenient overview.  For
+full details, you should refer to the documentation for Python X.Y.
+% add hyperlink when the documentation becomes available online.
+If you want to understand the complete implementation and design
+rationale, refer to the PEP for a particular new feature.
+
+
+%======================================================================
+
+% Large, PEP-level features and changes should be described here.
+
+
+%======================================================================
+\section{Other Language Changes}
+
+Here are all of the changes that Python X.Y makes to the core Python
+language.
+
+\begin{itemize}
+\item TBD
+
+\end{itemize}
+
+
+%======================================================================
+\subsection{Optimizations}
+
+\begin{itemize}
+
+\item Optimizations should be described here.
+
+\end{itemize}
+
+The net result of the X.Y optimizations is that Python X.Y runs the
+pystone benchmark around XX\% faster than Python X.Y-1.%
+% only use the next line if you want to do the extra work ;) :
+% and YY\% faster than Python X.Y-2.
+
+
+%======================================================================
+\section{New, Improved, and Deprecated Modules}
+
+As usual, Python's standard library received a number of enhancements and
+bug fixes.  Here's a partial list of the most notable changes, sorted
+alphabetically by module name. Consult the
+\file{Misc/NEWS} file in the source tree for a more
+complete list of changes, or look through the CVS logs for all the
+details.
+
+\begin{itemize}
+
+\item Descriptions go here.
+
+\end{itemize}
+
+
+%======================================================================
+% whole new modules get described in \subsections here
+
+
+% ======================================================================
+\section{Build and C API Changes}
+
+Changes to Python's build process and to the C API include:
+
+\begin{itemize}
+
+\item Detailed changes are listed here.
+
+\end{itemize}
+
+
+%======================================================================
+\subsection{Port-Specific Changes}
+
+Platform-specific changes go here.
+
+
+%======================================================================
+\section{Other Changes and Fixes \label{section-other}}
+
+As usual, there were a bunch of other improvements and bugfixes
+scattered throughout the source tree.  A search through the CVS change
+logs finds there were XXX patches applied and YYY bugs fixed between
+Python X.Y-1 and X.Y.  Both figures are likely to be underestimates.
+
+Some of the more notable changes are:
+
+\begin{itemize}
+
+\item Details go here.
+
+\end{itemize}
+
+
+%======================================================================
+\section{Porting to Python X.Y}
+
+This section lists previously described changes that may require
+changes to your code:
+
+\begin{itemize}
+
+\item Everything is all in the details!
+
+\end{itemize}
+
+
+%======================================================================
+\section{Acknowledgements \label{acks}}
+
+The author would like to thank the following people for offering
+suggestions, corrections and assistance with various drafts of this
+article: .
+
+\end{document}

Added: vendor/Python/current/Doc/tests/math.tex
===================================================================
--- vendor/Python/current/Doc/tests/math.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/tests/math.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,16 @@
+\documentclass{howto}
+
+\title{Test of python.sty with math}
+
+\begin{document}
+
+\maketitle
+
+\section{Subscripts in Math Mode}
+
+This contains an inline formula containing a subscript: $H_20$.
+This display doesn't make sense, but contains a subscript as well:
+
+$$\sum_1^2 = a_x$$
+
+\end{document}

Added: vendor/Python/current/Doc/texinputs/distutils.sty
===================================================================
--- vendor/Python/current/Doc/texinputs/distutils.sty	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/texinputs/distutils.sty	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,33 @@
+%
+% LaTeX commands and macros needed for the two Distutils manuals,
+% inst.tex and dist.tex.
+%
+% $Id: distutils.sty 15178 2000-04-19 22:40:34Z gward $
+%
+
+% My gripe list about the Python style files:
+%  * I want italics in verbatim environments for variable
+%    text (verbatim.sty?)
+%  * I hate escaping underscores (url.sty fixes this)
+
+% '\command' is for Distutils commands which, depending on your
+% perspective, are just arguments to the setup script, or sub-
+% commands of the setup script, or the classes that implement
+% each "command".
+\newcommand{\command}[1]{\code{#1}}
+
+% '\option' is for Distutils options *in* the setup script.  Command-
+% line options *to* the setup script are marked up in the usual
+% way, ie. with '\programopt' or '\longprogramopt'
+\newcommand{\option}[1]{\textsf{\small{#1}}}
+
+% '\filevar' is for variable components of file/path names -- eg.
+% when you put 'prefix' in a pathname, you mark it up with
+% '\filevar' so that it still looks pathname-ish, but is
+% distinguished from the literal part of the path.  Fred says
+% this can be accomplished just fine with '\var', but I violently
+% disagree.  Pistols at dawn will sort this one out.
+\newcommand{\filevar}[1]{{\textsl{\filenq{#1}}}}
+
+% Just while the code and docs are still under development.
+\newcommand{\XXX}[1]{\textbf{**#1**}}

Added: vendor/Python/current/Doc/texinputs/fancyhdr.sty
===================================================================
--- vendor/Python/current/Doc/texinputs/fancyhdr.sty	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/texinputs/fancyhdr.sty	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,329 @@
+% fancyhdr.sty version 1.99d
+% Fancy headers and footers for LaTeX.
+% Piet van Oostrum, Dept of Computer Science, University of Utrecht
+% Padualaan 14, P.O. Box 80.089, 3508 TB Utrecht, The Netherlands
+% Telephone: +31 30 2532180. Email: piet at cs.ruu.nl
+% ========================================================================
+% LICENCE: This is free software. You are allowed to use and distribute
+% this software in any way you like. You are also allowed to make modified
+% versions of it, but you can distribute a modified version only if you
+% clearly indicate that it is a modified version and the person(s) who
+% modified it. This indication should be in a prominent place, e.g. in the
+% top of the file. If possible a contact address, preferably by email,
+% should be given for these persons. If that is feasible the modifications
+% should be indicated in the source code.
+% ========================================================================
+% MODIFICATION HISTORY:
+% Sep 16, 1994
+% version 1.4: Correction for use with \reversemargin
+% Sep 29, 1994:
+% version 1.5: Added the \iftopfloat, \ifbotfloat and \iffloatpage commands
+% Oct 4, 1994:
+% version 1.6: Reset single spacing in headers/footers for use with
+% setspace.sty or doublespace.sty
+% Oct 4, 1994:
+% version 1.7: changed \let\@mkboth\markboth to
+% \def\@mkboth{\protect\markboth} to make it more robust
+% Dec 5, 1994:
+% version 1.8: corrections for amsbook/amsart: define \@chapapp and (more
+% importantly) use the \chapter/sectionmark definitions from ps at headings if
+% they exist (which should be true for all standard classes).
+% May 31, 1995:
+% version 1.9: The proposed \renewcommand{\headrulewidth}{\iffloatpage...
+% construction in the doc did not work properly with the fancyplain style. 
+% June 1, 1995:
+% version 1.91: The definition of \@mkboth wasn't restored on subsequent
+% \pagestyle{fancy}'s.
+% June 1, 1995:
+% version 1.92: The sequence \pagestyle{fancyplain} \pagestyle{plain}
+% \pagestyle{fancy} would erroneously select the plain version.
+% June 1, 1995:
+% version 1.93: \fancypagestyle command added.
+% Dec 11, 1995:
+% version 1.94: suggested by Conrad Hughes <chughes at maths.tcd.ie>
+% CJCH, Dec 11, 1995: added \footruleskip to allow control over footrule
+% position (old hardcoded value of .3\normalbaselineskip is far too high
+% when used with very small footer fonts).
+% Jan 31, 1996:
+% version 1.95: call \@normalsize in the reset code if that is defined,
+% otherwise \normalsize.
+% this is to solve a problem with ucthesis.cls, as this doesn't
+% define \@currsize. Unfortunately for latex209 calling \normalsize doesn't
+% work as this is optimized to do very little, so there \@normalsize should
+% be called. Hopefully this code works for all versions of LaTeX known to
+% mankind.  
+% April 25, 1996:
+% version 1.96: initialize \headwidth to a magic (negative) value to catch
+% most common cases that people change it before calling \pagestyle{fancy}.
+% Note it can't be initialized when reading in this file, because
+% \textwidth could be changed afterwards. This is quite probable.
+% We also switch to \MakeUppercase rather than \uppercase and introduce a
+% \nouppercase command for use in headers. and footers.
+% May 3, 1996:
+% version 1.97: Two changes:
+% 1. Undo the change in version 1.8 (using the pagestyle{headings} defaults
+% for the chapter and section marks. The current version of amsbook and
+% amsart classes don't seem to need them anymore. Moreover the standard
+% latex classes don't use \markboth if twoside isn't selected, and this is
+% confusing as \leftmark doesn't work as expected.
+% 2. include a call to \ps at empty in ps@@fancy. This is to solve a problem
+% in the amsbook and amsart classes, that make global changes to \topskip,
+% which are reset in \ps at empty. Hopefully this doesn't break other things.
+% May 7, 1996:
+% version 1.98:
+% Added % after the line  \def\nouppercase
+% May 7, 1996:
+% version 1.99: This is the alpha version of fancyhdr 2.0
+% Introduced the new commands \fancyhead, \fancyfoot, and \fancyhf.
+% Changed \headrulewidth, \footrulewidth, \footruleskip to
+% macros rather than length parameters, In this way they can be
+% conditionalized and they don't consume length registers. There is no need
+% to have them as length registers unless you want to do calculations with
+% them, which is unlikely. Note that this may make some uses of them
+% incompatible (i.e. if you have a file that uses \setlength or \xxxx=)
+% May 10, 1996:
+% version 1.99a:
+% Added a few more % signs
+% May 10, 1996:
+% version 1.99b:
+% Changed the syntax of \f at nfor to be resistent to catcode changes of :=
+% Removed the [1] from the defs of \lhead etc. because the parameter is
+% consumed by the \@[xy]lhead etc. macros.
+% June 24, 1997:
+% version 1.99c:
+% corrected \nouppercase to also include the protected form of \MakeUppercase
+% \global added to manipulation of \headwidth.
+% \iffootnote command added.
+% Some comments added about \@fancyhead and \@fancyfoot.
+% Aug 24, 1998
+% version 1.99d
+% Changed the default \ps at empty to \ps@@empty in order to allow
+% \fancypagestyle{empty} redefinition.
+
+\let\fancy at def\gdef
+
+\def\if at mpty#1#2#3{\def\temp at ty{#1}\ifx\@empty\temp at ty #2\else#3\fi}
+
+% Usage: \@forc \var{charstring}{command to be executed for each char}
+% This is similar to LaTeX's \@tfor, but expands the charstring.
+
+\def\@forc#1#2#3{\expandafter\f at rc\expandafter#1\expandafter{#2}{#3}}
+\def\f at rc#1#2#3{\def\temp at ty{#2}\ifx\@empty\temp at ty\else
+                                    \f@@rc#1#2\f@@rc{#3}\fi}
+\def\f@@rc#1#2#3\f@@rc#4{\def#1{#2}#4\f at rc#1{#3}{#4}}
+
+% Usage: \f at nfor\name:=list\do{body}
+% Like LaTeX's \@for but an empty list is treated as a list with an empty
+% element
+
+\newcommand{\f at nfor}[3]{\edef\@fortmp{#2}%
+    \expandafter\@forloop#2,\@nil,\@nil\@@#1{#3}}
+
+% Usage: \def at ult \cs{defaults}{argument}
+% sets \cs to the characters from defaults appearing in argument
+% or defaults if it would be empty. All characters are lowercased.
+
+\newcommand\def at ult[3]{%
+    \edef\temp at a{\lowercase{\edef\noexpand\temp at a{#3}}}\temp at a
+    \def#1{}%
+    \@forc\tmpf at ra{#2}%
+        {\expandafter\if at in\tmpf at ra\temp at a{\edef#1{#1\tmpf at ra}}{}}%
+    \ifx\@empty#1\def#1{#2}\fi}
+% 
+% \if at in <char><set><truecase><falsecase>
+%
+\newcommand{\if at in}[4]{%
+    \edef\temp at a{#2}\def\temp at b##1#1##2\temp at b{\def\temp at b{##1}}%
+    \expandafter\temp at b#2#1\temp at b\ifx\temp at a\temp at b #4\else #3\fi}
+
+\newcommand{\fancyhead}{\@ifnextchar[{\f at ncyhf h}{\f at ncyhf h[]}}
+\newcommand{\fancyfoot}{\@ifnextchar[{\f at ncyhf f}{\f at ncyhf f[]}}
+\newcommand{\fancyhf}{\@ifnextchar[{\f at ncyhf {}}{\f at ncyhf {}[]}}
+
+% The header and footer fields are stored in command sequences with
+% names of the form: \f at ncy<x><y><z> with <x> for [eo], <y> form [lcr]
+% and <z> from [hf].
+
+\def\f at ncyhf#1[#2]#3{%
+    \def\temp at c{}%
+    \@forc\tmpf at ra{#2}%
+        {\expandafter\if at in\tmpf at ra{eolcrhf,EOLCRHF}%
+            {}{\edef\temp at c{\temp at c\tmpf at ra}}}%
+    \ifx\@empty\temp at c\else
+        \ifx\PackageError\undefined
+        \errmessage{Illegal char `\temp at c' in fancyhdr argument:
+          [#2]}\else
+        \PackageError{Fancyhdr}{Illegal char `\temp at c' in fancyhdr argument:
+          [#2]}{}\fi
+    \fi
+    \f at nfor\temp at c{#2}%
+        {\def at ult\f@@@eo{eo}\temp at c
+         \def at ult\f@@@lcr{lcr}\temp at c
+         \def at ult\f@@@hf{hf}{#1\temp at c}%
+         \@forc\f@@eo\f@@@eo
+             {\@forc\f@@lcr\f@@@lcr
+                 {\@forc\f@@hf\f@@@hf
+                     {\expandafter\fancy at def\csname
+                      f at ncy\f@@eo\f@@lcr\f@@hf\endcsname
+                      {#3}}}}}}
+
+% Fancyheadings version 1 commands. These are more or less deprecated,
+% but they continue to work.
+
+\newcommand{\lhead}{\@ifnextchar[{\@xlhead}{\@ylhead}}
+\def\@xlhead[#1]#2{\fancy at def\f at ncyelh{#1}\fancy at def\f at ncyolh{#2}}
+\def\@ylhead#1{\fancy at def\f at ncyelh{#1}\fancy at def\f at ncyolh{#1}}
+
+\newcommand{\chead}{\@ifnextchar[{\@xchead}{\@ychead}}
+\def\@xchead[#1]#2{\fancy at def\f at ncyech{#1}\fancy at def\f at ncyoch{#2}}
+\def\@ychead#1{\fancy at def\f at ncyech{#1}\fancy at def\f at ncyoch{#1}}
+
+\newcommand{\rhead}{\@ifnextchar[{\@xrhead}{\@yrhead}}
+\def\@xrhead[#1]#2{\fancy at def\f at ncyerh{#1}\fancy at def\f at ncyorh{#2}}
+\def\@yrhead#1{\fancy at def\f at ncyerh{#1}\fancy at def\f at ncyorh{#1}}
+
+\newcommand{\lfoot}{\@ifnextchar[{\@xlfoot}{\@ylfoot}}
+\def\@xlfoot[#1]#2{\fancy at def\f at ncyelf{#1}\fancy at def\f at ncyolf{#2}}
+\def\@ylfoot#1{\fancy at def\f at ncyelf{#1}\fancy at def\f at ncyolf{#1}}
+
+\newcommand{\cfoot}{\@ifnextchar[{\@xcfoot}{\@ycfoot}}
+\def\@xcfoot[#1]#2{\fancy at def\f at ncyecf{#1}\fancy at def\f at ncyocf{#2}}
+\def\@ycfoot#1{\fancy at def\f at ncyecf{#1}\fancy at def\f at ncyocf{#1}}
+
+\newcommand{\rfoot}{\@ifnextchar[{\@xrfoot}{\@yrfoot}}
+\def\@xrfoot[#1]#2{\fancy at def\f at ncyerf{#1}\fancy at def\f at ncyorf{#2}}
+\def\@yrfoot#1{\fancy at def\f at ncyerf{#1}\fancy at def\f at ncyorf{#1}}
+
+\newdimen\headwidth
+\newcommand{\headrulewidth}{0.4pt}
+\newcommand{\footrulewidth}{\z at skip}
+\newcommand{\footruleskip}{.3\normalbaselineskip}
+
+% Fancyplain stuff shouldn't be used anymore (rather
+% \fancypagestyle{plain} should be used), but it must be present for
+% compatibility reasons.
+
+\newcommand{\plainheadrulewidth}{\z at skip}
+\newcommand{\plainfootrulewidth}{\z at skip}
+\newif\if at fancyplain \@fancyplainfalse
+\def\fancyplain#1#2{\if at fancyplain#1\else#2\fi}
+
+\headwidth=-123456789sp %magic constant
+
+% Command to reset various things in the headers:
+% a.o.  single spacing (taken from setspace.sty)
+% and the catcode of ^^M (so that epsf files in the header work if a
+% verbatim crosses a page boundary)
+% It also defines a \nouppercase command that disables \uppercase and
+% \Makeuppercase. It can only be used in the headers and footers.
+\def\fancy at reset{\restorecr
+ \def\baselinestretch{1}%
+ \def\nouppercase##1{{\let\uppercase\relax\let\MakeUppercase\relax
+     \expandafter\let\csname MakeUppercase \endcsname\relax##1}}%
+ \ifx\undefined\@newbaseline% NFSS not present; 2.09 or 2e
+   \ifx\@normalsize\undefined \normalsize % for ucthesis.cls
+   \else \@normalsize \fi
+ \else% NFSS (2.09) present
+  \@newbaseline%
+ \fi}
+
+% Initialization of the head and foot text.
+
+% The default values still contain \fancyplain for compatibility.
+\fancyhf{} % clear all
+% lefthead empty on ``plain'' pages, \rightmark on even, \leftmark on odd pages
+% evenhead empty on ``plain'' pages, \leftmark on even, \rightmark on odd pages
+\fancyhead[el,or]{\fancyplain{}{\sl\rightmark}}
+\fancyhead[er,ol]{\fancyplain{}{\sl\leftmark}}
+\fancyfoot[c]{\rm\thepage} % page number
+
+% Put together a header or footer given the left, center and
+% right text, fillers at left and right and a rule.
+% The \lap commands put the text into an hbox of zero size,
+% so overlapping text does not generate an errormessage.
+% These macros have 5 parameters:
+% 1. \@lodd or \@rodd % This determines at which side the header will stick
+%    out.
+% 2. \f at ncyolh, \f at ncyelh, \f at ncyolf or \f at ncyelf. This is the left component.
+% 3. \f at ncyoch, \f at ncyech, \f at ncyocf or \f at ncyecf. This is the middle comp.
+% 4. \f at ncyorh, \f at ncyerh, \f at ncyorf or \f at ncyerf. This is the right component.
+% 5. \@lodd or \@rodd % This determines at which side the header will stick
+%    out. This is the reverse of parameter nr. 1. One of them is always
+%    \relax and the other one is \hss (after expansion).
+
+\def\@fancyhead#1#2#3#4#5{#1\hbox to\headwidth{\fancy at reset\vbox{\hbox
+{\rlap{\parbox[b]{\headwidth}{\raggedright#2\strut}}\hfill
+\parbox[b]{\headwidth}{\centering#3\strut}\hfill
+\llap{\parbox[b]{\headwidth}{\raggedleft#4\strut}}}\headrule}}#5}
+
+\def\@fancyfoot#1#2#3#4#5{#1\hbox to\headwidth{\fancy at reset\vbox{\footrule
+\hbox{\rlap{\parbox[t]{\headwidth}{\raggedright#2\strut}}\hfill
+\parbox[t]{\headwidth}{\centering#3\strut}\hfill
+\llap{\parbox[t]{\headwidth}{\raggedleft#4\strut}}}}}#5}
+
+\def\headrule{{\if at fancyplain\let\headrulewidth\plainheadrulewidth\fi
+\hrule\@height\headrulewidth\@width\headwidth \vskip-\headrulewidth}}
+
+\def\footrule{{\if at fancyplain\let\footrulewidth\plainfootrulewidth\fi
+\vskip-\footruleskip\vskip-\footrulewidth
+\hrule\@width\headwidth\@height\footrulewidth\vskip\footruleskip}}
+
+\def\ps at fancy{%
+\@ifundefined{@chapapp}{\let\@chapapp\chaptername}{}%for amsbook
+%
+% Define \MakeUppercase for old LaTeXen.
+% Note: we used \def rather than \let, so that \let\uppercase\relax (from
+% the version 1 documentation) will still work.
+%
+\@ifundefined{MakeUppercase}{\def\MakeUppercase{\uppercase}}{}%
+\@ifundefined{chapter}{\def\sectionmark##1{\markboth
+{\MakeUppercase{\ifnum \c at secnumdepth>\z@
+ \thesection\hskip 1em\relax \fi ##1}}{}}%
+\def\subsectionmark##1{\markright {\ifnum \c at secnumdepth >\@ne
+ \thesubsection\hskip 1em\relax \fi ##1}}}%
+{\def\chaptermark##1{\markboth {\MakeUppercase{\ifnum \c at secnumdepth>\m at ne
+ \@chapapp\ \thechapter. \ \fi ##1}}{}}%
+\def\sectionmark##1{\markright{\MakeUppercase{\ifnum \c at secnumdepth >\z@
+ \thesection. \ \fi ##1}}}}%
+%\csname ps at headings\endcsname % use \ps at headings defaults if they exist
+\ps@@fancy
+\gdef\ps at fancy{\@fancyplainfalse\ps@@fancy}%
+% Initialize \headwidth if the user didn't
+%
+\ifdim\headwidth<0sp
+%
+% This catches the case that \headwidth hasn't been initialized and the
+% case that the user added something to \headwidth in the expectation that
+% it was initialized to \textwidth. We compensate this now. This loses if
+% the user intended to multiply it by a factor. But that case is more
+% likely done by saying something like \headwidth=1.2\textwidth. 
+% The doc says you have to change \headwidth after the first call to
+% \pagestyle{fancy}. This code is just to catch the most common cases were
+% that requirement is violated.
+%
+    \global\advance\headwidth123456789sp\global\advance\headwidth\textwidth
+\fi}
+\def\ps at fancyplain{\ps at fancy \let\ps at plain\ps at plain@fancy}
+\def\ps at plain@fancy{\@fancyplaintrue\ps@@fancy}
+\let\ps@@empty\ps at empty
+\def\ps@@fancy{%
+\ps@@empty % This is for amsbook/amsart, which do strange things with \topskip
+\def\@mkboth{\protect\markboth}%
+\def\@oddhead{\@fancyhead\@lodd\f at ncyolh\f at ncyoch\f at ncyorh\@rodd}%
+\def\@oddfoot{\@fancyfoot\@lodd\f at ncyolf\f at ncyocf\f at ncyorf\@rodd}%
+\def\@evenhead{\@fancyhead\@rodd\f at ncyelh\f at ncyech\f at ncyerh\@lodd}%
+\def\@evenfoot{\@fancyfoot\@rodd\f at ncyelf\f at ncyecf\f at ncyerf\@lodd}%
+}
+\def\@lodd{\if at reversemargin\hss\else\relax\fi}
+\def\@rodd{\if at reversemargin\relax\else\hss\fi}
+
+\newif\iffootnote
+\let\latex at makecol\@makecol
+\def\@makecol{\ifvoid\footins\footnotetrue\else\footnotefalse\fi
+\let\topfloat\@toplist\let\botfloat\@botlist\latex at makecol}
+\def\iftopfloat#1#2{\ifx\topfloat\empty #2\else #1\fi}
+\def\ifbotfloat#1#2{\ifx\botfloat\empty #2\else #1\fi}
+\def\iffloatpage#1#2{\if at fcolmade #1\else #2\fi}
+
+\newcommand{\fancypagestyle}[2]{%
+  \@namedef{ps@#1}{\let\fancy at def\def#2\relax\ps at fancy}}

Added: vendor/Python/current/Doc/texinputs/fncychap.sty
===================================================================
--- vendor/Python/current/Doc/texinputs/fncychap.sty	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/texinputs/fncychap.sty	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,433 @@
+%%% Derived from the original fncychap.sty,
+%%% but changed ``TWELV'' to ``TWELVE''.
+
+%%% Copyright   Ulf A. Lindgren
+%%%             Department of Applied Electronics
+%%%             Chalmers University of Technology
+%%%             S-412 96 Gothenburg, Sweden
+%%%             E-mail lindgren at ae.chalmers.se
+%%%
+%%% Note        Permission is granted to modify this file under
+%%%             the condition that it is saved using another
+%%%             file and package name.
+%%%
+%%% Revision    1.1
+%%%
+%%%             Jan. 8th Modified package name base date option
+%%%             Jan. 22th Modified FmN and FmTi for error in book.cls
+%%%                  \MakeUppercase{#}->{\MakeUppercase#}
+%%%             Apr. 6th Modified Lenny option to prevent undesired 
+%%%                  skip of line.
+%%%             Nov. 8th Fixed \@chapapp for AMS
+%%%             Feb. 11th Fixed appendix problem related to Bjarne
+%%% Last modified    Feb. 11th 1998
+
+\NeedsTeXFormat{LaTeX2e}[1995/12/01]
+\ProvidesPackage{fncychap}
+             [1997/04/06 v1.11
+                 LaTeX package (Revised chapters)]
+
+%%%% DEFINITION OF Chapapp variables
+\newcommand{\CNV}{\huge\bfseries}
+\newcommand{\ChNameVar}[1]{\renewcommand{\CNV}{#1}}
+
+
+%%%% DEFINITION OF TheChapter variables
+\newcommand{\CNoV}{\huge\bfseries}
+\newcommand{\ChNumVar}[1]{\renewcommand{\CNoV}{#1}}
+
+\newif\ifUCN
+\UCNfalse
+\newif\ifLCN
+\LCNfalse
+\def\ChNameLowerCase{\LCNtrue\UCNfalse}
+\def\ChNameUpperCase{\UCNtrue\LCNfalse}
+\def\ChNameAsIs{\UCNfalse\LCNfalse}
+
+%%%%% Fix for AMSBook 971008
+
+\@ifundefined{@chapapp}{\let\@chapapp\chaptername}{}
+
+
+%%%%% Fix for Bjarne and appendix 980211
+
+\newif\ifinapp
+\inappfalse
+\renewcommand\appendix{\par
+  \setcounter{chapter}{0}%
+  \setcounter{section}{0}%
+  \inapptrue%
+  \renewcommand\@chapapp{\appendixname}%
+  \renewcommand\thechapter{\@Alph\c at chapter}}
+
+%%%%%
+
+\newcommand{\FmN}[1]{%
+\ifUCN
+   {\MakeUppercase#1}\LCNfalse
+\else
+   \ifLCN
+      {\MakeLowercase#1}\UCNfalse
+   \else #1
+   \fi
+\fi}
+
+
+%%%% DEFINITION OF Title variables
+\newcommand{\CTV}{\Huge\bfseries}
+\newcommand{\ChTitleVar}[1]{\renewcommand{\CTV}{#1}}
+
+%%%% DEFINITION OF the basic rule width
+\newlength{\RW}
+\setlength{\RW}{1pt}
+\newcommand{\ChRuleWidth}[1]{\setlength{\RW}{#1}}
+
+\newif\ifUCT
+\UCTfalse
+\newif\ifLCT
+\LCTfalse
+\def\ChTitleLowerCase{\LCTtrue\UCTfalse}
+\def\ChTitleUpperCase{\UCTtrue\LCTfalse}
+\def\ChTitleAsIs{\UCTfalse\LCTfalse}
+\newcommand{\FmTi}[1]{%
+\ifUCT
+
+   {\MakeUppercase#1}\LCTfalse
+\else
+   \ifLCT
+      {\MakeLowercase#1}\UCTfalse
+   \else #1
+   \fi
+\fi}
+
+
+
+\newlength{\mylen}
+\newlength{\myhi}
+\newlength{\px}
+\newlength{\py}
+\newlength{\pyy}
+\newlength{\pxx}
+
+
+\def\mghrulefill#1{\leavevmode\leaders\hrule\@height #1\hfill\kern\z@}
+
+\newcommand{\DOCH}{%
+  \CNV\FmN{\@chapapp}\space \CNoV\thechapter
+  \par\nobreak
+  \vskip 20\p@
+  }
+\newcommand{\DOTI}[1]{%
+    \CTV\FmTi{#1}\par\nobreak
+    \vskip 40\p@
+    }
+\newcommand{\DOTIS}[1]{%
+    \CTV\FmTi{#1}\par\nobreak
+    \vskip 40\p@
+    }
+
+%%%%%% SONNY DEF
+
+\DeclareOption{Sonny}{%
+  \ChNameVar{\Large\sf}
+  \ChNumVar{\Huge}
+  \ChTitleVar{\Large\sf}
+  \ChRuleWidth{0.5pt}
+  \ChNameUpperCase
+  \renewcommand{\DOCH}{%
+    \raggedleft
+    \CNV\FmN{\@chapapp}\space \CNoV\thechapter
+    \par\nobreak
+    \vskip 40\p@}
+  \renewcommand{\DOTI}[1]{%
+    \CTV\raggedleft\mghrulefill{\RW}\par\nobreak
+    \vskip 5\p@
+    \CTV\FmTi{#1}\par\nobreak
+    \mghrulefill{\RW}\par\nobreak
+    \vskip 40\p@}
+  \renewcommand{\DOTIS}[1]{%
+    \CTV\raggedleft\mghrulefill{\RW}\par\nobreak
+    \vskip 5\p@
+    \CTV\FmTi{#1}\par\nobreak
+    \mghrulefill{\RW}\par\nobreak
+    \vskip 40\p@}
+}
+
+%%%%%% LENNY DEF
+
+\DeclareOption{Lenny}{%
+
+  \ChNameVar{\fontsize{14}{16}\usefont{OT1}{phv}{m}{n}\selectfont}
+  \ChNumVar{\fontsize{60}{62}\usefont{OT1}{ptm}{m}{n}\selectfont}
+  \ChTitleVar{\Huge\bfseries\rm}
+  \ChRuleWidth{1pt}
+  \renewcommand{\DOCH}{%
+    \settowidth{\px}{\CNV\FmN{\@chapapp}}
+    \addtolength{\px}{2pt}
+    \settoheight{\py}{\CNV\FmN{\@chapapp}}
+    \addtolength{\py}{1pt}
+
+    \settowidth{\mylen}{\CNV\FmN{\@chapapp}\space\CNoV\thechapter}
+    \addtolength{\mylen}{1pt}
+    \settowidth{\pxx}{\CNoV\thechapter}
+    \addtolength{\pxx}{-1pt}
+
+    \settoheight{\pyy}{\CNoV\thechapter}
+    \addtolength{\pyy}{-2pt}
+    \setlength{\myhi}{\pyy}
+    \addtolength{\myhi}{-1\py}
+    \par
+    \parbox[b]{\textwidth}{%
+    \rule[\py]{\RW}{\myhi}%
+    \hskip -\RW%
+    \rule[\pyy]{\px}{\RW}%
+    \hskip -\px%
+    \raggedright%
+    \CNV\FmN{\@chapapp}\space\CNoV\thechapter%
+    \hskip1pt%
+    \mghrulefill{\RW}%
+    \rule{\RW}{\pyy}\par\nobreak%
+    \vskip -\baselineskip%
+    \vskip -\pyy%
+    \hskip \mylen%
+    \mghrulefill{\RW}\par\nobreak%
+    \vskip \pyy}%
+    \vskip 20\p@}
+ 
+
+  \renewcommand{\DOTI}[1]{%
+    \raggedright
+    \CTV\FmTi{#1}\par\nobreak
+    \vskip 40\p@}
+
+  \renewcommand{\DOTIS}[1]{%
+    \raggedright
+    \CTV\FmTi{#1}\par\nobreak
+    \vskip 40\p@}
+ }
+
+
+%%%%%%% GLENN DEF
+
+
+\DeclareOption{Glenn}{%
+  \ChNameVar{\bfseries\Large\sf}
+  \ChNumVar{\Huge}
+  \ChTitleVar{\bfseries\Large\rm}
+  \ChRuleWidth{1pt}
+  \ChNameUpperCase
+  \ChTitleUpperCase
+  \renewcommand{\DOCH}{%
+    \settoheight{\myhi}{\CTV\FmTi{Test}}
+    \setlength{\py}{\baselineskip}
+    \addtolength{\py}{\RW}
+    \addtolength{\py}{\myhi}
+    \setlength{\pyy}{\py}
+    \addtolength{\pyy}{-1\RW}
+     
+    \raggedright
+    \CNV\FmN{\@chapapp}\space\CNoV\thechapter
+    \hskip 3pt\mghrulefill{\RW}\rule[-1\pyy]{2\RW}{\py}\par\nobreak}
+
+  \renewcommand{\DOTI}[1]{%
+    \addtolength{\pyy}{-4pt}
+    \settoheight{\myhi}{\CTV\FmTi{#1}}
+    \addtolength{\myhi}{\py}
+    \addtolength{\myhi}{-1\RW}
+    \vskip -1\pyy
+    \rule{2\RW}{\myhi}\mghrulefill{\RW}\hskip 2pt
+    \raggedleft\CTV\FmTi{#1}\par\nobreak
+    \vskip 80\p@}
+
+  \renewcommand{\DOTIS}[1]{%
+    \setlength{\py}{10pt}
+    \setlength{\pyy}{\py}
+    \addtolength{\pyy}{\RW}
+    \setlength{\myhi}{\baselineskip}
+    \addtolength{\myhi}{\pyy}
+    \mghrulefill{\RW}\rule[-1\py]{2\RW}{\pyy}\par\nobreak
+%    \addtolength{}{}
+\vskip -1\baselineskip
+    \rule{2\RW}{\myhi}\mghrulefill{\RW}\hskip 2pt
+    \raggedleft\CTV\FmTi{#1}\par\nobreak
+    \vskip 60\p@}
+  }
+
+%%%%%%% CONNY DEF
+
+\DeclareOption{Conny}{%
+  \ChNameUpperCase
+  \ChTitleUpperCase  
+  \ChNameVar{\centering\Huge\rm\bfseries}
+  \ChNumVar{\Huge}
+  \ChTitleVar{\centering\Huge\rm}
+  \ChRuleWidth{2pt}
+
+  \renewcommand{\DOCH}{%
+    \mghrulefill{3\RW}\par\nobreak
+    \vskip -0.5\baselineskip
+    \mghrulefill{\RW}\par\nobreak
+    \CNV\FmN{\@chapapp}\space \CNoV\thechapter
+    \par\nobreak
+    \vskip -0.5\baselineskip
+   }
+  \renewcommand{\DOTI}[1]{%
+    \mghrulefill{\RW}\par\nobreak
+    \CTV\FmTi{#1}\par\nobreak
+    \vskip 60\p@
+    }
+  \renewcommand{\DOTIS}[1]{%
+    \mghrulefill{\RW}\par\nobreak
+    \CTV\FmTi{#1}\par\nobreak
+    \vskip 60\p@
+    }
+  }
+
+%%%%%%% REJNE DEF
+
+\DeclareOption{Rejne}{%
+
+  \ChNameUpperCase
+  \ChTitleUpperCase  
+  \ChNameVar{\centering\Large\rm}
+  \ChNumVar{\Huge}
+  \ChTitleVar{\centering\Huge\rm}
+  \ChRuleWidth{1pt}
+  \renewcommand{\DOCH}{%
+    \settoheight{\py}{\CNoV\thechapter}
+    \addtolength{\py}{-1pt}
+    \CNV\FmN{\@chapapp}\par\nobreak
+    \vskip 20\p@
+    \setlength{\myhi}{2\baselineskip}
+    \setlength{\px}{\myhi}
+    \addtolength{\px}{-1\RW}
+    \rule[-1\px]{\RW}{\myhi}\mghrulefill{\RW}\hskip
+    10pt\raisebox{-0.5\py}{\CNoV\thechapter}\hskip
+10pt\mghrulefill{\RW}\rule[-1\px]{\RW}{\myhi}\par\nobreak
+     \vskip -1\p@
+    }
+  \renewcommand{\DOTI}[1]{%
+    \setlength{\mylen}{\textwidth}
+    \addtolength{\mylen}{-2\RW}
+    {\vrule width\RW}\parbox{\mylen}{\CTV\FmTi{#1}}{\vrule
+width\RW}\par\nobreak
+    \vskip
+-1pt\rule{\RW}{2\baselineskip}\mghrulefill{\RW}\rule{\RW}{2\baselineskip}
+    \vskip 60\p@
+    }
+  \renewcommand{\DOTIS}[1]{%
+    \setlength{\py}{\fboxrule}
+    \setlength{\fboxrule}{\RW}
+    \setlength{\mylen}{\textwidth}
+    \addtolength{\mylen}{-2\RW}
+    \fbox{\parbox{\mylen}{\vskip
+2\baselineskip\CTV\FmTi{#1}\par\nobreak\vskip \baselineskip}} 
+    \setlength{\fboxrule}{\py}
+    \vskip 60\p@
+    }
+  }
+
+
+%%%%%%% BJARNE DEF
+
+\DeclareOption{Bjarne}{%
+  \ChNameUpperCase
+  \ChTitleUpperCase  
+  \ChNameVar{\raggedleft\normalsize\rm}
+  \ChNumVar{\raggedleft \bfseries\Large}
+  \ChTitleVar{\raggedleft \Large\rm}
+  \ChRuleWidth{1pt}
+
+
+%% Note thechapter -> c at chapter fix appendix bug
+
+  \newcounter{AlphaCnt}
+  \newcounter{AlphaDecCnt}
+  \newcommand{\AlphaNo}{%
+    \ifcase\number\theAlphaCnt
+      \ifnum\c at chapter=0
+        ZERO\else{}\fi
+    \or ONE\or TWO\or THREE\or FOUR\or FIVE
+    \or SIX\or SEVEN\or EIGHT\or NINE\or TEN
+    \or ELEVEN\or TWELVE\or THIRTEEN\or FOURTEEN\or FIFTEEN
+    \or SIXTEEN\or SEVENTEEN\or EIGHTEEN\or NINETEEN\fi
+}
+
+  \newcommand{\AlphaDecNo}{%
+    \setcounter{AlphaDecCnt}{0}
+    \@whilenum\number\theAlphaCnt>0\do
+      {\addtocounter{AlphaCnt}{-10}
+       \addtocounter{AlphaDecCnt}{1}}
+     \ifnum\number\theAlphaCnt=0
+     \else
+       \addtocounter{AlphaDecCnt}{-1}
+       \addtocounter{AlphaCnt}{10}
+     \fi
+     
+     
+    \ifcase\number\theAlphaDecCnt\or TEN\or TWENTY\or THIRTY\or
+    FORTY\or FIFTY\or SIXTY\or SEVENTY\or EIGHTY\or NINETY\fi
+    }
+  \newcommand{\TheAlphaChapter}{%
+    
+    \ifinapp 
+      \thechapter
+    \else
+      \setcounter{AlphaCnt}{\c at chapter}
+      \ifnum\c at chapter<20
+        \AlphaNo
+      \else
+        \AlphaDecNo\AlphaNo
+      \fi
+    \fi
+    }  
+  \renewcommand{\DOCH}{%
+    \mghrulefill{\RW}\par\nobreak
+    \CNV\FmN{\@chapapp}\par\nobreak 
+    \CNoV\TheAlphaChapter\par\nobreak
+    \vskip -1\baselineskip\vskip 5pt\mghrulefill{\RW}\par\nobreak
+    \vskip 20\p@
+    }
+  \renewcommand{\DOTI}[1]{%
+    \CTV\FmTi{#1}\par\nobreak
+    \vskip 40\p@
+    }
+  \renewcommand{\DOTIS}[1]{%
+    \CTV\FmTi{#1}\par\nobreak
+    \vskip 40\p@
+    }
+}
+
+\DeclareOption*{%
+  \PackageWarning{fancychapter}{unknown style option}
+  }
+
+\ProcessOptions* \relax
+
+\def\@makechapterhead#1{%
+  \vspace*{50\p@}%
+  {\parindent \z@ \raggedright \normalfont
+    \ifnum \c at secnumdepth >\m at ne
+      \DOCH
+    \fi
+    \interlinepenalty\@M
+    \DOTI{#1}
+  }}
+\def\@schapter#1{\if at twocolumn
+                   \@topnewpage[\@makeschapterhead{#1}]%
+                 \else
+                   \@makeschapterhead{#1}%
+                   \@afterheading
+                 \fi}
+\def\@makeschapterhead#1{%
+  \vspace*{50\p@}%
+  {\parindent \z@ \raggedright
+    \normalfont
+    \interlinepenalty\@M
+    \DOTIS{#1}
+    \vskip 40\p@
+  }}
+
+\endinput
+
+

Added: vendor/Python/current/Doc/texinputs/howto.cls
===================================================================
--- vendor/Python/current/Doc/texinputs/howto.cls	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/texinputs/howto.cls	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,109 @@
+%
+% howto.cls for the Python documentation
+%
+
+\NeedsTeXFormat{LaTeX2e}[1995/12/01]
+\ProvidesClass{howto}
+             [1998/02/25 Document class (Python HOWTO)]
+
+\RequirePackage{pypaper}
+\RequirePackage{fancybox}
+
+% Change the options here to get a different set of basic options,  This
+% is where to add things like "a4paper" or "10pt".
+%
+\LoadClass[\py at paper,\py at ptsize,twoside]{article}
+
+\setcounter{secnumdepth}{1}
+
+% Optional packages:
+%
+% If processing of these documents fails at your TeX installation,
+% these may be commented out (independently) to make things work.
+% These are both supplied with the current version of the teTeX
+% distribution.
+%
+% The "fancyhdr" package makes nicer page footers reasonable to
+% implement, and is used to put the chapter and section information in 
+% the footers.
+%
+\RequirePackage{fancyhdr}\typeout{Using fancier footers than usual.}
+
+
+% Required package:
+%
+% This gives us all the Python-specific markup that we really want.
+% This should come last.  Do not change this.
+%
+\RequirePackage{python}
+
+% support for module synopsis sections:
+\newcommand{\py at ModSynopsisFilename}{\jobname.syn}
+
+
+% need to do one of these....
+\newcommand{\py at doHorizontalRule}{\rule{\textwidth}{1pt}}
+
+
+% Change the title page to look a bit better, and fit in with the
+% fncychap ``Bjarne'' style a bit better.
+%
+\renewcommand{\maketitle}{
+  \py at doHorizontalRule
+  \ifpdf
+    \begingroup
+    % This \def is required to deal with multi-line authors; it
+    % changes \\ to ', ' (comma-space), making it pass muster for
+    % generating document info in the PDF file.
+    \def\\{, }
+    \pdfinfo{
+      /Author (\@author)
+      /Title (\@title)
+    }
+    \endgroup
+  \fi
+  \begin{flushright}
+    {\rm\Huge\py at HeaderFamily \@title} \par
+    {\em\large\py at HeaderFamily \py at release\releaseinfo} \par
+    \vspace{25pt}
+    {\Large\py at HeaderFamily \@author} \par
+    \vspace{25pt}
+    \@date \par
+    \py at authoraddress \par
+  \end{flushright}
+  \@thanks
+  \setcounter{footnote}{0}
+  \let\thanks\relax\let\maketitle\relax
+  \gdef\@thanks{}\gdef\@author{}\gdef\@title{}
+}
+
+
+\let\py at OldTableofcontents=\tableofcontents
+\renewcommand{\tableofcontents}{
+  \begingroup
+    \parskip = 0mm
+    \py at OldTableofcontents
+  \endgroup
+  \py at doHorizontalRule
+  \vspace{12pt}
+  \py at doing@page at targetstrue
+}  
+
+% Fix the theindex environment to add an entry to the Table of
+% Contents; this is much nicer than just having to jump to the end of
+% the book and flip around, especially with multiple indexes.
+%
+\let\py at OldTheindex=\theindex
+\renewcommand{\theindex}{
+  \clearpage
+  \py at OldTheindex
+  \addcontentsline{toc}{section}{\indexname}
+}
+
+\@ifundefined{fancyhf}{
+  \pagestyle{plain}}{
+  \pagestyle{normal}}		% start this way; change for
+\pagenumbering{arabic}		% ToC & chapters
+\setcounter{secnumdepth}{2}
+
+\thispagestyle{empty}

Added: vendor/Python/current/Doc/texinputs/ltxmarkup.sty
===================================================================
--- vendor/Python/current/Doc/texinputs/ltxmarkup.sty	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/texinputs/ltxmarkup.sty	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,40 @@
+% Created by Fred L. Drake, Jr. <fdrake at acm.org>, as part of the
+% Python Documentation Project.
+%
+% Define some simple markup for the LaTeX command documentation:
+
+\ProvidesPackage{ltxmarkup}
+\RequirePackage{python}      % fulllineitems environment
+
+% These two macros are used in constructing the last parameter to the
+% envdesc and macrodesc environments.
+
+\newcommand{\py at ltx@optparam}[1]{{[}\var{#1}{]}}
+\newcommand{\py at ltx@param}[1]{\{\var{#1}\}}
+
+\newenvironment{envdesc}[2]{
+  \begin{fulllineitems}
+    \item[\code{\e begin\{{\bfseries #1}\}{%
+      \let\op=\py at ltx@optparam%
+      \let\p=\py at ltx@param%
+      \let\unspecified=\py at unspecified%
+      \let\moreargs=\py at moreargs%
+         #2}}]
+    \item[\code{\e end\{{\bfseries #1}\}}]
+    \index{#1 environment@\py at idxcode{#1} environment}
+    \index{environments!#1@\py at idxcode{#1}}
+}{\end{fulllineitems}}
+
+\newenvironment{macrodesc}[2]{
+  \begin{fulllineitems}
+    \item[\code{{\e\bfseries#1}{%
+      \let\op=\py at ltx@optparam%
+      \let\p=\py at ltx@param%
+      \let\unspecified=\py at unspecified%
+      \let\moreargs=\py at moreargs%
+      #2}}]
+    \index{#1@\py at idxcode{#1}}
+}{\end{fulllineitems}}
+
+\newcommand{\env}[1]{\code{#1}}
+\newcommand{\macro}[1]{\code{\e#1}}

Added: vendor/Python/current/Doc/texinputs/manual.cls
===================================================================
--- vendor/Python/current/Doc/texinputs/manual.cls	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/texinputs/manual.cls	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,155 @@
+%
+% manual.cls for the Python documentation
+%
+
+\NeedsTeXFormat{LaTeX2e}[1995/12/01]
+\ProvidesClass{manual}
+             [1998/03/03 Document class (Python manual)]
+
+\RequirePackage{pypaper}
+\RequirePackage{fancybox}
+
+% Change the options here to get a different set of basic options, but only
+% if you have to.  Paper and font size should be adjusted in pypaper.sty.
+%
+\LoadClass[\py at paper,\py at ptsize,twoside,openright]{report}
+
+\setcounter{secnumdepth}{2}
+
+% Optional packages:
+%
+% If processing of these documents fails at your TeX installation,
+% these may be commented out (independently) to make things work.
+% These are both supplied with the current version of the teTeX
+% distribution.
+%
+% The "fancyhdr" package makes nicer page footers reasonable to
+% implement, and is used to put the chapter and section information in 
+% the footers.
+%
+\RequirePackage{fancyhdr}\typeout{Using fancier footers than usual.}
+
+
+% Required packages:
+%
+% The "fncychap" package is used to get the nice chapter headers.  The
+% .sty file is distributed with Python, so you should not need to disable
+% it.  You'd also end up with a mixed page style; uglier than stock LaTeX!
+%
+\RequirePackage[Bjarne]{fncychap}\typeout{Using fancy chapter headings.}
+% Do horizontal rules it this way to match:
+\newcommand{\py at doHorizontalRule}{\mghrulefill{\RW}}
+%
+%
+% This gives us all the Python-specific markup that we really want.
+% This should come last.  Do not change this.
+%
+\RequirePackage{python}
+
+% support for module synopsis sections:
+\newcommand{\py at ModSynopsisFilename}{\jobname\thechapter.syn}
+\let\py at OldChapter=\chapter
+\renewcommand{\chapter}{
+  \py at ProcessModSynopsis
+  \py at closeModSynopsisFile
+  \py at OldChapter
+}
+
+
+% Change the title page to look a bit better, and fit in with the
+% fncychap ``Bjarne'' style a bit better.
+%
+\renewcommand{\maketitle}{%
+  \begin{titlepage}%
+    \let\footnotesize\small
+    \let\footnoterule\relax
+    \py at doHorizontalRule%
+    \ifpdf
+      \begingroup
+      % This \def is required to deal with multi-line authors; it
+      % changes \\ to ', ' (comma-space), making it pass muster for
+      % generating document info in the PDF file.
+      \def\\{, }
+      \pdfinfo{
+        /Author (\@author)
+        /Title (\@title)
+      }
+      \endgroup
+    \fi
+    \begin{flushright}%
+      {\rm\Huge\py at HeaderFamily \@title \par}%
+      {\em\LARGE\py at HeaderFamily \py at release\releaseinfo \par}
+      \vfill
+      {\LARGE\py at HeaderFamily \@author \par}
+      \vfill\vfill
+      {\large
+       \@date \par
+       \vfill
+       \py at authoraddress \par
+      }%
+    \end{flushright}%\par
+    \@thanks
+  \end{titlepage}%
+  \setcounter{footnote}{0}%
+  \let\thanks\relax\let\maketitle\relax
+  \gdef\@thanks{}\gdef\@author{}\gdef\@title{}
+}
+
+
+% Catch the end of the {abstract} environment, but here make sure the
+% abstract is followed by a blank page if the 'openright' option is used.
+%
+\let\py at OldEndAbstract=\endabstract
+\renewcommand{\endabstract}{
+  \if at openright
+    \ifodd\value{page}
+      \typeout{Adding blank page after the abstract.}
+      \vfil\pagebreak
+    \fi
+  \fi
+  \py at OldEndAbstract
+}
+
+% This wraps the \tableofcontents macro with all the magic to get the
+% spacing right and have the right number of pages if the 'openright'
+% option has been used.  This eliminates a fair amount of crud in the
+% individual document files.
+%
+\let\py at OldTableofcontents=\tableofcontents
+\renewcommand{\tableofcontents}{%
+  \setcounter{page}{1}%
+  \pagebreak%
+  \pagestyle{plain}%
+  {%
+    \parskip = 0mm%
+    \py at OldTableofcontents%
+    \if at openright%
+      \ifodd\value{page}%
+        \typeout{Adding blank page after the table of contents.}%
+        \pagebreak\hspace{0pt}%
+      \fi%
+    \fi%
+    \cleardoublepage%
+  }%
+  \pagenumbering{arabic}%
+  \@ifundefined{fancyhf}{}{\pagestyle{normal}}%
+  \py at doing@page at targetstrue%
+}
+% This is needed to get the width of the section # area wide enough in the
+% library reference.  Doing it here keeps it the same for all the manuals.
+%
+\renewcommand*\l at section{\@dottedtocline{1}{1.5em}{2.6em}}
+\renewcommand*\l at subsection{\@dottedtocline{2}{4.1em}{3.5em}}
+\setcounter{tocdepth}{1}
+
+
+% Fix the theindex environment to add an entry to the Table of
+% Contents; this is much nicer than just having to jump to the end of
+% the book and flip around, especially with multiple indexes.
+%
+\let\py at OldTheindex=\theindex
+\renewcommand{\theindex}{
+  \cleardoublepage
+  \py at OldTheindex
+  \addcontentsline{toc}{chapter}{\indexname}
+}

Added: vendor/Python/current/Doc/texinputs/pypaper.sty
===================================================================
--- vendor/Python/current/Doc/texinputs/pypaper.sty	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/texinputs/pypaper.sty	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,18 @@
+%
+%  Change this to say a4paper instead of letterpaper if you want A4.  These
+%  are the latex defaults.
+%
+\newcommand{\py at paper}{letterpaper}
+\newcommand{\py at ptsize}{10pt}
+
+%  These set up the fonts for the documents.
+%
+%  The "times" package makes the default font the PostScript Times
+%  font, which makes for smaller PostScript and a font that more people 
+%  like.
+%
+%  The "avant" package causes the AvantGarde font to be used for
+%  sans-serif text, instead of the uglier Helvetica set up by the "times"
+%  package.
+%
+\RequirePackage{times}\typeout{Using Times instead of Computer Modern.}

Added: vendor/Python/current/Doc/texinputs/python.ist
===================================================================
--- vendor/Python/current/Doc/texinputs/python.ist	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/texinputs/python.ist	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,11 @@
+line_max 100
+headings_flag 1
+heading_prefix "  \\bigletter "
+
+preamble "\\begin{theindex}
+\\def\\bigletter#1{{\\Large\\sffamily#1}\\nopagebreak\\vspace{1mm}}
+
+"
+
+symhead_positive "{Symbols}"
+numhead_positive "{Numbers}"

Added: vendor/Python/current/Doc/texinputs/python.sty
===================================================================
--- vendor/Python/current/Doc/texinputs/python.sty	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/texinputs/python.sty	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1327 @@
+%
+% python.sty for the Python docummentation  [works only with Latex2e]
+%
+
+\NeedsTeXFormat{LaTeX2e}[1995/12/01]
+\ProvidesPackage{python}
+             [1998/01/11 LaTeX package (Python markup)]
+
+\RequirePackage{longtable}
+\RequirePackage{underscore}
+
+% Uncomment these two lines to ignore the paper size and make the page 
+% size more like a typical published manual.
+%\renewcommand{\paperheight}{9in}
+%\renewcommand{\paperwidth}{8.5in}   % typical squarish manual
+%\renewcommand{\paperwidth}{7in}     % O'Reilly ``Programmming Python''
+
+% These packages can be used to add marginal annotations which indicate
+% index entries and labels; useful for reviewing this messy documentation!
+%
+%\RequirePackage{showkeys}
+%\RequirePackage{showidx}
+
+% If we ever want to indent paragraphs, this needs to be changed.
+% This is used inside the macros defined here instead of coding
+% \noindent directly.
+\let\py at parindent=\noindent
+
+% for PDF output, use maximal compression & a lot of other stuff
+% (test for PDF recommended by Tanmoy Bhattacharya <tanmoy at qcd.lanl.gov>)
+%
+\newif\ifpy at doing@page at targets
+\py at doing@page at targetsfalse
+
+\newif\ifpdf\pdffalse
+\ifx\pdfoutput\undefined\else\ifcase\pdfoutput
+\else
+  \pdftrue
+  \input{pdfcolor}
+  \let\py at LinkColor=\NavyBlue
+  \let\py at NormalColor=\Black
+  \pdfcompresslevel=9
+  \pdfpagewidth=\paperwidth    % page width of PDF output
+  \pdfpageheight=\paperheight  % page height of PDF output
+  %
+  % Pad the number with '0' to 3 digits wide so no page name is a prefix
+  % of any other.
+  %
+  \newcommand{\py at targetno}[1]{\ifnum#1<100 0\fi\ifnum#1<10 0\fi#1}
+  \newcommand{\py at pageno}{\py at targetno\thepage}
+  %
+  % This definition allows the entries in the page-view of the ToC to be
+  % active links.  Some work, some don't.
+  %
+  \let\py at OldContentsline=\contentsline
+  %
+  % Backward compatibility hack: pdfTeX 0.13 defined \pdfannotlink,
+  % but it changed to \pdfstartlink in 0.14.  This let's us use either
+  % version and still get useful behavior.
+  %
+  \@ifundefined{pdfstartlink}{
+    \let\pdfstartlink=\pdfannotlink
+  }{}
+  %
+  % The \py at parindent here is a hack -- we're forcing pdfTeX into
+  % horizontal mode since \pdfstartlink requires that.
+  \def\py at pdfstartlink{%
+    \ifvmode\py at parindent\fi%
+    \pdfstartlink%
+  }
+  %
+  % Macro that takes two args: the name to link to and the content of
+  % the link.  This takes care of the PDF magic, getting the colors
+  % the same for each link, and avoids having lots of garbage all over 
+  % this style file.
+  \newcommand{\py at linkToName}[2]{%
+    \py at pdfstartlink attr{/Border [0 0 0]} goto name{#1}%
+      \py at LinkColor#2\py at NormalColor%
+    \pdfendlink%
+  }
+  % Compute the padded page number separately since we end up with a pair of
+  % \relax tokens; this gets the right string computed and works.
+  \renewcommand{\contentsline}[3]{%
+    \def\my at pageno{\py at targetno{#3}}%
+    \py at OldContentsline{#1}{\py at linkToName{page\my at pageno}{#2}}{#3}%
+  }
+  \AtEndDocument{
+    \def\_{\string_}
+    \InputIfFileExists{\jobname.bkm}{\pdfcatalog{/PageMode /UseOutlines}}{}
+  }
+  \newcommand{\py at target}[1]{%
+    \ifpy at doing@page at targets%
+      {\pdfdest name{#1} xyz}%
+    \fi%
+  }
+  \let\py at OldLabel=\label
+  \renewcommand{\label}[1]{%
+    \py at OldLabel{#1}%
+    \py at target{label-#1}%
+  }
+  % This stuff adds a page# destination to every PDF page, where # is three
+  % digits wide, padded with leading zeros.  This doesn't really help with
+  % the frontmatter, but does fine with the body.
+  %
+  % This is *heavily* based on the hyperref package.
+  %
+  \def\@begindvi{%
+    \unvbox \@begindvibox
+    \@hyperfixhead
+  }
+  \def\@hyperfixhead{%
+   \let\H at old@thehead\@thehead
+       \global\def\@foo{\py at target{page\py at pageno}}%
+     \expandafter\ifx\expandafter\@empty\H at old@thehead
+       \def\H at old@thehead{\hfil}\fi
+    \def\@thehead{\@foo\relax\H at old@thehead}%
+  }
+\fi\fi
+
+% Increase printable page size (copied from fullpage.sty)
+\topmargin 0pt
+\advance \topmargin by -\headheight
+\advance \topmargin by -\headsep
+
+% attempt to work a little better for A4 users
+\textheight \paperheight
+\advance\textheight by -2in
+
+\oddsidemargin 0pt
+\evensidemargin 0pt
+%\evensidemargin -.25in  % for ``manual size'' documents
+\marginparwidth 0.5in
+
+\textwidth \paperwidth
+\advance\textwidth by -2in
+
+
+% Style parameters and macros used by most documents here
+\raggedbottom
+\sloppy
+\parindent = 0mm
+\parskip = 2mm
+\hbadness = 5000                % don't print trivial gripes
+
+\pagestyle{empty}               % start this way; change for
+\pagenumbering{roman}           % ToC & chapters
+
+% Use this to set the font family for headers and other decor:
+\newcommand{\py at HeaderFamily}{\sffamily}
+
+% Set up abstract ways to get the normal and smaller font sizes that
+% work even in footnote context.
+\newif\ifpy at infootnote \py at infootnotefalse
+\let\py at oldmakefntext\@makefntext
+\def\@makefntext#1{%
+  \bgroup%
+    \py at infootnotetrue
+    \py at oldmakefntext{#1}%
+  \egroup%
+}
+\def\py at defaultsize{%
+  \ifpy at infootnote\footnotesize\else\normalsize\fi%
+}
+\def\py at smallsize{%
+  \ifpy at infootnote\scriptsize\else\small\fi%
+}
+
+% Redefine the 'normal' header/footer style when using "fancyhdr" package:
+\@ifundefined{fancyhf}{}{
+  % Use \pagestyle{normal} as the primary pagestyle for text.
+  \fancypagestyle{normal}{
+    \fancyhf{}
+    \fancyfoot[LE,RO]{{\py at HeaderFamily\thepage}}
+    \fancyfoot[LO]{{\py at HeaderFamily\nouppercase{\rightmark}}}
+    \fancyfoot[RE]{{\py at HeaderFamily\nouppercase{\leftmark}}}
+    \renewcommand{\headrulewidth}{0pt}
+    \renewcommand{\footrulewidth}{0.4pt}
+  }
+  % Update the plain style so we get the page number & footer line,
+  % but not a chapter or section title.  This is to keep the first
+  % page of a chapter and the blank page between chapters `clean.'
+  \fancypagestyle{plain}{
+    \fancyhf{}
+    \fancyfoot[LE,RO]{{\py at HeaderFamily\thepage}}
+    \renewcommand{\headrulewidth}{0pt}
+    \renewcommand{\footrulewidth}{0.4pt}
+  }
+  % Redefine \cleardoublepage so that the blank page between chapters
+  % gets the plain style and not the fancy style.  This is described
+  % in the documentation for the fancyhdr package by Piet von Oostrum.
+  \@ifundefined{chapter}{}{
+    \renewcommand{\cleardoublepage}{
+      \clearpage\if at openright \ifodd\c at page\else
+      \hbox{}
+      \thispagestyle{plain}
+      \newpage
+      \if at twocolumn\hbox{}\newpage\fi\fi\fi
+    }
+  }
+}
+
+% This sets up the {verbatim} environment to be indented and a minipage,
+% and to have all the other mostly nice properties that we want for
+% code samples.
+
+\let\py at OldVerbatim=\verbatim
+\let\py at OldEndVerbatim=\endverbatim
+\RequirePackage{verbatim}
+\let\py at OldVerbatimInput=\verbatiminput
+
+% Variable used by begin code command
+\newlength{\py at codewidth}
+
+\renewcommand{\verbatim}{%
+  \setlength{\parindent}{1cm}%
+  % Calculate the text width for the minipage:
+  \setlength{\py at codewidth}{\linewidth}%
+  \addtolength{\py at codewidth}{-\parindent}%
+  %
+  \par\indent%
+  \begin{minipage}[t]{\py at codewidth}%
+    \small%
+    \py at OldVerbatim%
+}
+\renewcommand{\endverbatim}{%
+    \py at OldEndVerbatim%
+  \end{minipage}%
+}
+\renewcommand{\verbatiminput}[1]{%
+  {\setlength{\parindent}{1cm}%
+   % Calculate the text width for the minipage:
+   \setlength{\py at codewidth}{\linewidth}%
+   \addtolength{\py at codewidth}{-\parindent}%
+   %
+   \small%
+   \begin{list}{}{\setlength{\leftmargin}{1cm}}
+     \item%
+     \py at OldVerbatimInput{#1}%
+   \end{list}
+  }%
+}
+
+% This does a similar thing for the {alltt} environment:
+\RequirePackage{alltt}
+\let\py at OldAllTT=\alltt
+\let\py at OldEndAllTT=\endalltt
+
+\renewcommand{\alltt}{%
+  \setlength{\parindent}{1cm}%
+  % Calculate the text width for the minipage:
+  \setlength{\py at codewidth}{\linewidth}%
+  \addtolength{\py at codewidth}{-\parindent}%
+  \let\e=\textbackslash%
+  %
+  \par\indent%
+  \begin{minipage}[t]{\py at codewidth}%
+    \small%
+    \py at OldAllTT%
+}
+\renewcommand{\endalltt}{%
+    \py at OldEndAllTT%
+  \end{minipage}%
+}
+
+
+\newcommand{\py at modulebadkey}{{--just-some-junk--}}
+
+
+%%  Lots of index-entry generation support.
+
+% Command to wrap around stuff that refers to function / module /
+% attribute names  in the index.  Default behavior: like \code{}.  To
+% just keep the index entries in the roman font, uncomment the second
+% definition; it matches O'Reilly style more.
+%
+\newcommand{\py at idxcode}[1]{\texttt{#1}}
+%\renewcommand{\py at idxcode}[1]{#1}
+
+% Command to generate two index entries (using subentries)
+\newcommand{\indexii}[2]{\index{#1!#2}\index{#2!#1}}
+
+% And three entries (using only one level of subentries)
+\newcommand{\indexiii}[3]{\index{#1!#2 #3}\index{#2!#3, #1}\index{#3!#1 #2}}
+
+% And four (again, using only one level of subentries)
+\newcommand{\indexiv}[4]{
+\index{#1!#2 #3 #4}
+\index{#2!#3 #4, #1}
+\index{#3!#4, #1 #2}
+\index{#4!#1 #2 #3}
+}
+
+% Command to generate a reference to a function, statement, keyword,
+% operator.
+\newcommand{\kwindex}[1]{\indexii{keyword}{#1@{\py at idxcode{#1}}}}
+\newcommand{\stindex}[1]{\indexii{statement}{#1@{\py at idxcode{#1}}}}
+\newcommand{\opindex}[1]{\indexii{operator}{#1@{\py at idxcode{#1}}}}
+\newcommand{\exindex}[1]{\indexii{exception}{#1@{\py at idxcode{#1}}}}
+\newcommand{\obindex}[1]{\indexii{object}{#1}}
+\newcommand{\bifuncindex}[1]{%
+  \index{#1@{\py at idxcode{#1()}} (built-in function)}}
+
+% Add an index entry for a module
+\newcommand{\py at refmodule}[2]{\index{#1@{\py at idxcode{#1}} (#2module)}}
+\newcommand{\refmodindex}[1]{\py at refmodule{#1}{}}
+\newcommand{\refbimodindex}[1]{\py at refmodule{#1}{built-in }}
+\newcommand{\refexmodindex}[1]{\py at refmodule{#1}{extension }}
+\newcommand{\refstmodindex}[1]{\py at refmodule{#1}{standard }}
+
+% Refer to a module's documentation using a hyperlink of the module's
+% name, at least if we're building PDF:
+\ifpdf
+  \newcommand{\refmodule}[2][\py at modulebadkey]{%
+    \ifx\py at modulebadkey#1\def\py at modulekey{#2}\else\def\py at modulekey{#1}\fi%
+    \py at linkToName{label-module-\py at modulekey}{\module{#2}}%
+  }
+\else
+  \newcommand{\refmodule}[2][\py at modulebadkey]{\module{#2}}
+\fi
+
+% support for the module index
+\newif\ifpy at UseModuleIndex
+\py at UseModuleIndexfalse
+
+\newcommand{\makemodindex}{
+  \newwrite\modindexfile
+  \openout\modindexfile=mod\jobname.idx
+  \py at UseModuleIndextrue
+}
+
+% Add the defining entry for a module
+\newcommand{\py at modindex}[2]{%
+  \renewcommand{\py at thismodule}{#1}
+  \setindexsubitem{(in module #1)}%
+  \index{#1@{\py at idxcode{#1}} (#2module)|textbf}%
+  \ifpy at UseModuleIndex%
+    \@ifundefined{py at modplat@\py at thismodulekey}{
+      \write\modindexfile{\protect\indexentry{#1@{\texttt{#1}}}{\thepage}}%
+    }{\write\modindexfile{\protect\indexentry{#1@{\texttt{#1} %
+        \emph{(\py at platformof[\py at thismodulekey]{})}}}{\thepage}}%
+    }
+  \fi%
+}
+
+% *** XXX *** THE NEXT FOUR MACROS ARE NOW OBSOLETE !!! ***
+
+% built-in & Python modules in the main distribution
+\newcommand{\bimodindex}[1]{\py at modindex{#1}{built-in }%
+  \typeout{*** MACRO bimodindex IS OBSOLETE -- USE declaremodule INSTEAD!}}
+\newcommand{\stmodindex}[1]{\py at modindex{#1}{standard }%
+  \typeout{*** MACRO stmodindex IS OBSOLETE -- USE declaremodule INSTEAD!}}
+
+% Python & extension modules outside the main distribution
+\newcommand{\modindex}[1]{\py at modindex{#1}{}%
+  \typeout{*** MACRO modindex IS OBSOLETE -- USE declaremodule INSTEAD!}}
+\newcommand{\exmodindex}[1]{\py at modindex{#1}{extension }%
+  \typeout{*** MACRO exmodindex IS OBSOLETE -- USE declaremodule INSTEAD!}}
+
+% Additional string for an index entry
+\newif\ifpy at usingsubitem\py at usingsubitemfalse
+\newcommand{\py at indexsubitem}{}
+\newcommand{\setindexsubitem}[1]{\renewcommand{\py at indexsubitem}{ #1}%
+                                 \py at usingsubitemtrue}
+\newcommand{\ttindex}[1]{%
+  \ifpy at usingsubitem
+    \index{#1@{\py at idxcode{#1}}\py at indexsubitem}%
+  \else%
+    \index{#1@{\py at idxcode{#1}}}%
+  \fi%
+}
+\newcommand{\withsubitem}[2]{%
+  \begingroup%
+    \def\ttindex##1{\index{##1@{\py at idxcode{##1}} #1}}%
+    #2%
+  \endgroup%
+}
+
+
+% Module synopsis processing -----------------------------------------------
+%
+\newcommand{\py at thisclass}{}
+\newcommand{\py at thismodule}{}
+\newcommand{\py at thismodulekey}{}
+\newcommand{\py at thismoduletype}{}
+
+\newcommand{\py at standardIndexModule}[1]{\py at modindex{#1}{standard }}
+\newcommand{\py at builtinIndexModule}[1]{\py at modindex{#1}{built-in }}
+\newcommand{\py at extensionIndexModule}[1]{\py at modindex{#1}{extension }}
+\newcommand{\py at IndexModule}[1]{\py at modindex{#1}{}}
+
+\newif\ifpy at HaveModSynopsis       \py at HaveModSynopsisfalse
+\newif\ifpy at ModSynopsisFileIsOpen \py at ModSynopsisFileIsOpenfalse
+\newif\ifpy at HaveModPlatform       \py at HaveModPlatformfalse
+
+% \declaremodule[key]{type}{name}
+\newcommand{\declaremodule}[3][\py at modulebadkey]{
+  \py at openModSynopsisFile
+  \renewcommand{\py at thismoduletype}{#2}
+  \ifx\py at modulebadkey#1
+    \renewcommand{\py at thismodulekey}{#3}
+  \else
+    \renewcommand{\py at thismodulekey}{#1}
+  \fi
+  \@ifundefined{py@#2IndexModule}{%
+    \typeout{*** MACRO declaremodule called with unknown module type: `#2'}
+    \py at IndexModule{#3}%
+  }{%
+    \csname py@#2IndexModule\endcsname{#3}%
+  }
+  \label{module-\py at thismodulekey}
+}
+\newif\ifpy at ModPlatformFileIsOpen \py at ModPlatformFileIsOpenfalse
+\newcommand{\py at ModPlatformFilename}{\jobname.pla}
+\newcommand{\platform}[1]{
+  \ifpy at ModPlatformFileIsOpen\else
+    \newwrite\py at ModPlatformFile
+    \openout\py at ModPlatformFile=\py at ModPlatformFilename
+    \py at ModPlatformFileIsOpentrue
+  \fi
+}
+\InputIfFileExists{\jobname.pla}{}{}
+\newcommand{\py at platformof}[2][\py at modulebadkey]{%
+  \ifx\py at modulebadkey#1 \def\py at key{#2}%
+  \else \def\py at key{#1}%
+  \fi%
+  \csname py at modplat@\py at key\endcsname%
+}
+\newcommand{\ignorePlatformAnnotation}[1]{}
+
+% \moduleauthor{name}{email}
+\newcommand{\moduleauthor}[2]{}
+
+% \sectionauthor{name}{email}
+\newcommand{\sectionauthor}[2]{}
+
+
+\newcommand{\py at defsynopsis}{Module has no synopsis.}
+\newcommand{\py at modulesynopsis}{\py at defsynopsis}
+\newcommand{\modulesynopsis}[1]{
+  \py at HaveModSynopsistrue
+  \renewcommand{\py at modulesynopsis}{#1}
+}
+
+% define the file
+\newwrite\py at ModSynopsisFile
+
+% hacked from \addtocontents from latex.ltx:
+\long\def\py at writeModSynopsisFile#1{%
+  \protected at write\py at ModSynopsisFile%
+      {\let\label\@gobble \let\index\@gobble \let\glossary\@gobble}%
+      {\string#1}%
+}
+\newcommand{\py at closeModSynopsisFile}{
+  \ifpy at ModSynopsisFileIsOpen
+    \closeout\py at ModSynopsisFile
+    \py at ModSynopsisFileIsOpenfalse
+  \fi
+}
+\newcommand{\py at openModSynopsisFile}{
+  \ifpy at ModSynopsisFileIsOpen\else
+    \openout\py at ModSynopsisFile=\py at ModSynopsisFilename
+    \py at ModSynopsisFileIsOpentrue
+  \fi
+}
+
+\newcommand{\py at ProcessModSynopsis}{
+  \ifpy at HaveModSynopsis
+    \py at writeModSynopsisFile{\modulesynopsis%
+      {\py at thismodulekey}{\py at thismodule}%
+      {\py at thismoduletype}{\py at modulesynopsis}}%
+    \py at HaveModSynopsisfalse
+  \fi
+  \renewcommand{\py at modulesynopsis}{\py at defsynopsis}
+}
+\AtEndDocument{\py at ProcessModSynopsis\py at closeModSynopsisFile}
+
+
+\long\def\py at writeModPlatformFile#1{%
+  \protected at write\py at ModPlatformFile%
+    {\let\label\@gobble \let\index\@gobble \let\glossary\@gobble}%
+    {\string#1}%
+}
+
+
+\newcommand{\localmoduletable}{
+  \IfFileExists{\py at ModSynopsisFilename}{
+    \begin{synopsistable}
+      \input{\py at ModSynopsisFilename}
+    \end{synopsistable}
+  }{}
+}
+
+\ifpdf
+  \newcommand{\py at ModSynopsisSummary}[4]{%
+    \py at linkToName{label-module-#1}{\bfcode{#2}} & #4\\
+  }
+\else
+  \newcommand{\py at ModSynopsisSummary}[4]{\bfcode{#2} & #4\\}
+\fi
+\newenvironment{synopsistable}{
+  % key, name, type, synopsis
+  \let\modulesynopsis=\py at ModSynopsisSummary
+  \begin{tabular}{ll}
+}{
+  \end{tabular}
+}
+%
+% --------------------------------------------------------------------------
+
+
+\newcommand{\py at reset}{
+  \py at usingsubitemfalse
+  \py at ProcessModSynopsis
+  \renewcommand{\py at thisclass}{}
+  \renewcommand{\py at thismodule}{}
+  \renewcommand{\py at thismodulekey}{}
+  \renewcommand{\py at thismoduletype}{}
+}
+
+% Augment the sectioning commands used to get our own font family in place,
+% and reset some internal data items:
+\renewcommand{\section}{\py at reset%
+                        \@startsection{section}{1}{\z@}%
+                                    {-3.5ex \@plus -1ex \@minus -.2ex}%
+                                    {2.3ex \@plus.2ex}%
+                                    {\reset at font\Large\py at HeaderFamily}}
+\renewcommand{\subsection}{\@startsection{subsection}{2}{\z@}%
+                                    {-3.25ex\@plus -1ex \@minus -.2ex}%
+                                    {1.5ex \@plus .2ex}%
+                                    {\reset at font\large\py at HeaderFamily}}
+\renewcommand{\subsubsection}{\@startsection{subsubsection}{3}{\z@}%
+                                    {-3.25ex\@plus -1ex \@minus -.2ex}%
+                                    {1.5ex \@plus .2ex}%
+                                    {\reset at font\normalsize\py at HeaderFamily}}
+\renewcommand{\paragraph}{\@startsection{paragraph}{4}{\z@}%
+                                    {3.25ex \@plus1ex \@minus.2ex}%
+                                    {-1em}%
+                                    {\reset at font\normalsize\py at HeaderFamily}}
+\renewcommand{\subparagraph}{\@startsection{subparagraph}{5}{\parindent}%
+                                    {3.25ex \@plus1ex \@minus .2ex}%
+                                    {-1em}%
+                                    {\reset at font\normalsize\py at HeaderFamily}}
+
+
+% Now for a lot of semantically-loaded environments that do a ton of magical
+% things to get the right formatting and index entries for the stuff in
+% Python modules and C API.
+
+
+% {fulllineitems} is used in one place in libregex.tex, but is really for
+% internal use in this file.
+%
+\newcommand{\py at itemnewline}[1]{%
+  \@tempdima\linewidth%
+  \advance\@tempdima \leftmargin\makebox[\@tempdima][l]{#1}%
+}
+
+\newenvironment{fulllineitems}{
+  \begin{list}{}{\labelwidth \leftmargin \labelsep 0pt
+                 \rightmargin 0pt \topsep -\parskip \partopsep \parskip
+                 \itemsep -\parsep
+                 \let\makelabel=\py at itemnewline}
+}{\end{list}}
+
+% \optional is mostly for use in the arguments parameters to the various
+% {*desc} environments defined below, but may be used elsewhere.  Known to
+% be used in the debugger chapter.
+%
+% Typical usage:
+%
+%     \begin{funcdesc}{myfunc}{reqparm\optional{, optparm}}
+%                                    ^^^       ^^^
+%                          No space here       No space here
+%
+% When a function has multiple optional parameters, \optional should be
+% nested, not chained.  This is right:
+%
+%     \begin{funcdesc}{myfunc}{\optional{parm1\optional{, parm2}}}
+%
+\let\py at badkey=\@undefined
+
+\newcommand{\optional}[1]{%
+  {\textnormal{\Large[}}{#1}\hspace{0.5mm}{\textnormal{\Large]}}}
+
+% This can be used when a function or method accepts an varying number 
+% of arguments, such as by using the *args syntax in the parameter list.
+\newcommand{\py at moreargs}{...}
+
+% This can be used when you don't want to document the parameters to a 
+% function or method, but simply state that it's an alias for
+% something else.
+\newcommand{\py at unspecified}{...}
+
+
+\newlength{\py at argswidth}
+\newcommand{\py at sigparams}[1]{%
+  \parbox[t]{\py at argswidth}{\py at varvars{#1}\code{)}}}
+\newcommand{\py at sigline}[2]{%
+  \settowidth{\py at argswidth}{#1\code{(}}%
+  \addtolength{\py at argswidth}{-2\py at argswidth}%
+  \addtolength{\py at argswidth}{\textwidth}%
+  \item[#1\code{(}\py at sigparams{#2}]}
+
+% C functions ------------------------------------------------------------
+% \begin{cfuncdesc}[refcount]{type}{name}{arglist}
+% Note that the [refcount] slot should only be filled in by
+% tools/anno-api.py; it pulls the value from the refcounts database.
+\newcommand{\cfuncline}[3]{
+  \py at sigline{\code{#1 \bfcode{#2}}}{#3}%
+  \index{#2@{\py at idxcode{#2()}}}
+}
+\newenvironment{cfuncdesc}[4][\py at badkey]{
+  \begin{fulllineitems}
+    \cfuncline{#2}{#3}{#4}
+    \ifx#1\@undefined\else%
+      \emph{Return value: \textbf{#1}.}\\
+    \fi
+}{\end{fulllineitems}}
+
+% C variables ------------------------------------------------------------
+% \begin{cvardesc}{type}{name}
+\newenvironment{cvardesc}[2]{
+  \begin{fulllineitems}
+    \item[\code{#1 \bfcode{#2}}\index{#2@{\py at idxcode{#2}}}]
+}{\end{fulllineitems}}
+
+% C data types -----------------------------------------------------------
+% \begin{ctypedesc}[index name]{typedef name}
+\newenvironment{ctypedesc}[2][\py at badkey]{
+  \begin{fulllineitems}
+    \item[\bfcode{#2}%
+    \ifx#1\@undefined%
+      \index{#2@{\py at idxcode{#2}} (C type)}
+    \else%
+      \index{#2@{\py at idxcode{#1}} (C type)}
+    \fi]
+}{\end{fulllineitems}}
+
+% C type fields ----------------------------------------------------------
+% \begin{cmemberdesc}{container type}{ctype}{membername}
+\newcommand{\cmemberline}[3]{
+  \item[\code{#2 \bfcode{#3}}]
+  \index{#3@{\py at idxcode{#3}} (#1 member)}
+}
+\newenvironment{cmemberdesc}[3]{
+  \begin{fulllineitems}
+    \cmemberline{#1}{#2}{#3}
+}{\end{fulllineitems}}
+
+% Funky macros -----------------------------------------------------------
+% \begin{csimplemacrodesc}{name}
+% -- "simple" because it has no args; NOT for constant definitions!
+\newenvironment{csimplemacrodesc}[1]{
+  \begin{fulllineitems}
+    \item[\bfcode{#1}\index{#1@{\py at idxcode{#1}} (macro)}]
+}{\end{fulllineitems}}
+
+% simple functions (not methods) -----------------------------------------
+% \begin{funcdesc}{name}{args}
+\newcommand{\funcline}[2]{%
+  \funclineni{#1}{#2}%
+  \index{#1@{\py at idxcode{#1()}} (in module \py at thismodule)}}
+\newenvironment{funcdesc}[2]{
+  \begin{fulllineitems}
+    \funcline{#1}{#2}
+}{\end{fulllineitems}}
+
+% similar to {funcdesc}, but doesn't add to the index
+\newcommand{\funclineni}[2]{%
+  \py at sigline{\bfcode{#1}}{#2}}
+\newenvironment{funcdescni}[2]{
+  \begin{fulllineitems}
+    \funclineni{#1}{#2}
+}{\end{fulllineitems}}
+
+% classes ----------------------------------------------------------------
+% \begin{classdesc}{name}{constructor args}
+\newenvironment{classdesc}[2]{
+  % Using \renewcommand doesn't work for this, for unknown reasons:
+  \global\def\py at thisclass{#1}
+  \begin{fulllineitems}
+    \py at sigline{\strong{class }\bfcode{#1}}{#2}%
+    \index{#1@{\py at idxcode{#1}} (class in \py at thismodule)}
+}{\end{fulllineitems}}
+
+% \begin{classdesc*}{name}
+\newenvironment{classdesc*}[1]{
+  % Using \renewcommand doesn't work for this, for unknown reasons:
+  \global\def\py at thisclass{#1}
+  \begin{fulllineitems}
+    \item[\strong{class }\code{\bfcode{#1}}%
+      \index{#1@{\py at idxcode{#1}} (class in \py at thismodule)}]
+}{\end{fulllineitems}}
+
+% \begin{excclassdesc}{name}{constructor args}
+% but indexes as an exception
+\newenvironment{excclassdesc}[2]{
+  % Using \renewcommand doesn't work for this, for unknown reasons:
+  \global\def\py at thisclass{#1}
+  \begin{fulllineitems}
+    \py at sigline{\strong{exception }\bfcode{#1}}{#2}%
+    \index{#1@{\py at idxcode{#1}} (exception in \py at thismodule)}
+}{\end{fulllineitems}}
+
+% There is no corresponding {excclassdesc*} environment.  To describe
+% a class exception without parameters, use the {excdesc} environment.
+
+
+\let\py at classbadkey=\@undefined
+
+% object method ----------------------------------------------------------
+% \begin{methoddesc}[classname]{methodname}{args}
+\newcommand{\methodline}[3][\@undefined]{
+  \methodlineni{#2}{#3}
+  \ifx#1\@undefined
+    \index{#2@{\py at idxcode{#2()}} (\py at thisclass\ method)}
+  \else
+    \index{#2@{\py at idxcode{#2()}} (#1 method)}
+  \fi
+}
+\newenvironment{methoddesc}[3][\@undefined]{
+  \begin{fulllineitems}
+    \ifx#1\@undefined
+      \methodline{#2}{#3}
+    \else
+      \def\py at thisclass{#1}
+      \methodline{#2}{#3}
+    \fi
+}{\end{fulllineitems}}
+
+% similar to {methoddesc}, but doesn't add to the index
+% (never actually uses the optional argument)
+\newcommand{\methodlineni}[3][\py at classbadkey]{%
+  \py at sigline{\bfcode{#2}}{#3}}
+\newenvironment{methoddescni}[3][\py at classbadkey]{
+  \begin{fulllineitems}
+    \methodlineni{#2}{#3}
+}{\end{fulllineitems}}
+
+% object data attribute --------------------------------------------------
+% \begin{memberdesc}[classname]{membername}
+\newcommand{\memberline}[2][\py at classbadkey]{%
+  \ifx#1\@undefined
+    \memberlineni{#2}
+    \index{#2@{\py at idxcode{#2}} (\py at thisclass\ attribute)}
+  \else
+    \memberlineni{#2}
+    \index{#2@{\py at idxcode{#2}} (#1 attribute)}
+  \fi
+}
+\newenvironment{memberdesc}[2][\py at classbadkey]{
+  \begin{fulllineitems}
+    \ifx#1\@undefined
+      \memberline{#2}
+    \else
+      \def\py at thisclass{#1}
+      \memberline{#2}
+    \fi
+}{\end{fulllineitems}}
+
+% similar to {memberdesc}, but doesn't add to the index
+% (never actually uses the optional argument)
+\newcommand{\memberlineni}[2][\py at classbadkey]{\item[\bfcode{#2}]}
+\newenvironment{memberdescni}[2][\py at classbadkey]{
+  \begin{fulllineitems}
+    \memberlineni{#2}
+}{\end{fulllineitems}}
+
+% For exceptions: --------------------------------------------------------
+% \begin{excdesc}{name}
+%  -- for constructor information, use excclassdesc instead
+\newenvironment{excdesc}[1]{
+  \begin{fulllineitems}
+    \item[\strong{exception }\bfcode{#1}%
+          \index{#1@{\py at idxcode{#1}} (exception in \py at thismodule)}]
+}{\end{fulllineitems}}
+
+% Module data or constants: ----------------------------------------------
+% \begin{datadesc}{name}
+\newcommand{\dataline}[1]{%
+  \datalineni{#1}\index{#1@{\py at idxcode{#1}} (data in \py at thismodule)}}
+\newenvironment{datadesc}[1]{
+  \begin{fulllineitems}
+    \dataline{#1}
+}{\end{fulllineitems}}
+
+% similar to {datadesc}, but doesn't add to the index
+\newcommand{\datalineni}[1]{\item[\bfcode{#1}]\nopagebreak}
+\newenvironment{datadescni}[1]{
+  \begin{fulllineitems}
+    \datalineni{#1}
+}{\end{fulllineitems}}
+
+% bytecode instruction ---------------------------------------------------
+% \begin{opcodedesc}{name}{var}
+% -- {var} may be {}
+\newenvironment{opcodedesc}[2]{
+  \begin{fulllineitems}
+    \item[\bfcode{#1}\quad\var{#2}]
+}{\end{fulllineitems}}
+
+
+\newcommand{\nodename}[1]{\label{#1}}
+
+% For these commands, use \command{} to get the typography right, not 
+% {\command}.  This works better with the texinfo translation.
+\newcommand{\ABC}{{\sc abc}}
+\newcommand{\UNIX}{{\sc Unix}}
+\newcommand{\POSIX}{POSIX}
+\newcommand{\ASCII}{{\sc ascii}}
+\newcommand{\Cpp}{C\protect\raisebox{.18ex}{++}}
+\newcommand{\C}{C}
+\newcommand{\EOF}{{\sc eof}}
+\newcommand{\NULL}{\constant{NULL}}
+\newcommand{\infinity}{\ensuremath{\infty}}
+\newcommand{\plusminus}{\ensuremath{\pm}}
+
+% \guilabel{Start}
+\newcommand{\guilabel}[1]{\textsf{#1}}
+% \menuselection{Start \sub Programs \sub Python}
+\newcommand{\menuselection}[1]{\guilabel{{\def\sub{ \ensuremath{>} }#1}}}
+
+% Also for consistency: spell Python "Python", not "python"!
+
+% code is the most difficult one...
+\newcommand{\code}[1]{\textrm{\@vobeyspaces\@noligs\def\{{\char`\{}\def\}{\char`\}}\def\~{\char`\~}\def\^{\char`\^}\def\e{\char`\\}\def\${\char`\$}\def\#{\char`\#}\def\&{\char`\&}\def\%{\char`\%}%
+\texttt{#1}}}
+
+\newcommand{\bfcode}[1]{\code{\bfseries#1}} % bold-faced code font
+\newcommand{\csimplemacro}[1]{\code{#1}}
+\newcommand{\kbd}[1]{\code{#1}}
+\newcommand{\samp}[1]{`\code{#1}'}
+\newcommand{\var}[1]{%
+  \ifmmode%
+    \hbox{\py at defaultsize\textrm{\textit{#1\/}}}%
+  \else%
+    \py at defaultsize\textrm{\textit{#1\/}}%
+  \fi%
+}
+\renewcommand{\emph}[1]{{\em #1}}
+\newcommand{\dfn}[1]{\emph{#1}}
+\newcommand{\strong}[1]{{\bf #1}}
+% let's experiment with a new font:
+\newcommand{\file}[1]{`\filenq{#1}'}
+\newcommand{\filenq}[1]{{\py at smallsize\textsf{\let\e=\textbackslash#1}}}
+
+% Use this def/redef approach for \url{} since hyperref defined this already,
+% but only if we actually used hyperref:
+\ifpdf
+  \newcommand{\url}[1]{{%
+    \py at pdfstartlink%
+    attr{ /Border [0 0 0] }%
+    user{%
+      /Subtype/Link%
+      /A<<%
+      /Type/Action%
+      /S/URI%
+      /URI(#1)%
+      >>%
+    }%
+    \py at LinkColor%                      color of the link text
+    \py at smallsize\sf #1%
+    \py at NormalColor%                    Turn it back off; these are declarative
+    \pdfendlink}%                       and don't appear bound to the current
+  }%                                    formatting "box".
+\else
+  \newcommand{\url}[1]{\mbox{\py at smallsize\textsf{#1}}}
+\fi
+\newcommand{\email}[1]{{\py at smallsize\textsf{#1}}}
+\newcommand{\newsgroup}[1]{{\py at smallsize\textsf{#1}}}
+
+\newcommand{\py at varvars}[1]{{%
+  {\let\unspecified=\py at unspecified%
+   \let\moreargs=\py at moreargs%
+   \var{#1}}}}
+
+% I'd really like to get rid of this!
+\newif\iftexi\texifalse
+
+% This is used to get l2h to put the copyright and abstract on
+% a separate HTML page.
+\newif\ifhtml\htmlfalse
+
+
+% These should be used for all references to identifiers which are
+% used to refer to instances of specific language constructs.  See the
+% names for specific semantic assignments.
+%
+% For now, don't do anything really fancy with them; just use them as
+% logical markup.  This might change in the future.
+%
+\newcommand{\module}[1]{\texttt{#1}}
+\newcommand{\keyword}[1]{\texttt{#1}}
+\newcommand{\exception}[1]{\texttt{#1}}
+\newcommand{\class}[1]{\texttt{#1}}
+\newcommand{\function}[1]{\texttt{#1}}
+\newcommand{\member}[1]{\texttt{#1}}
+\newcommand{\method}[1]{\texttt{#1}}
+
+\newcommand{\pytype}[1]{#1}             % built-in Python type
+
+\newcommand{\cfunction}[1]{\texttt{#1}}
+\newcommand{\ctype}[1]{\texttt{#1}}     % C struct or typedef name
+\newcommand{\cdata}[1]{\texttt{#1}}     % C variable, typically global
+
+\newcommand{\mailheader}[1]{{\py at smallsize\textsf{#1:}}}
+\newcommand{\mimetype}[1]{{\py at smallsize\textsf{#1}}}
+% The \! is a "negative thin space" in math mode.
+\newcommand{\regexp}[1]{%
+  {\tiny$^{^\lceil}\!\!$%
+   {\py at defaultsize\code{#1}}%
+   $\!\rfloor\!$%
+  }}
+\newcommand{\envvar}[1]{%
+  #1%
+  \index{#1}%
+  \index{environment variables!{#1}}%
+}
+\newcommand{\makevar}[1]{#1}            % variable in a Makefile
+\newcommand{\character}[1]{\samp{#1}}
+
+% constants defined in Python modules or C headers, not language constants:
+\newcommand{\constant}[1]{\code{#1}}    % manifest constant, not syntactic
+
+\newcommand{\manpage}[2]{{\emph{#1}(#2)}}
+\newcommand{\pep}[1]{PEP #1\index{Python Enhancement Proposals!PEP #1}}
+\newcommand{\rfc}[1]{RFC #1\index{RFC!RFC #1}}
+\newcommand{\program}[1]{\strong{#1}}
+\newcommand{\programopt}[1]{\strong{#1}}
+% Note that \longprogramopt provides the '--'!
+\newcommand{\longprogramopt}[1]{\strong{-{}-#1}}
+
+% \ulink{link text}{URL}
+\ifpdf
+  \newcommand{\ulink}[2]{{%
+    % For PDF, we *should* only generate a link when the URL is absolute.
+    \py at pdfstartlink%
+    attr{ /Border [0 0 0] }%
+    user{%
+      /Subtype/Link%
+      /A<<%
+      /Type/Action%
+      /S/URI%
+      /URI(#2)%
+      >>%
+    }%
+    \py at LinkColor%                              color of the link text
+    #1%
+    \py at NormalColor%                    Turn it back off; these are declarative
+    \pdfendlink}%                       and don't appear bound to the current
+  }%                                    formatting "box".
+\else
+  \newcommand{\ulink}[2]{#1}
+\fi
+
+% cited titles:  \citetitle{Title of Work}
+%       online:  \citetitle[url-to-resource]{Title of Work}
+\ifpdf
+  \newcommand{\citetitle}[2][\py at modulebadkey]{%
+    \ifx\py at modulebadkey#1\emph{#2}\else\ulink{\emph{#2}}{#1}\fi%
+  }
+\else
+  \newcommand{\citetitle}[2][URL]{\emph{#2}}
+\fi
+
+
+
+% This version is being checked in for the historical record; it shows
+% how I've managed to get some aspects of this to work.  It will not
+% be used in practice, so a subsequent revision will change things
+% again.  This version has problems, but shows how to do something
+% that proved more tedious than I'd expected, so I don't want to lose
+% the example completely.
+%
+\newcommand{\grammartoken}[1]{\texttt{#1}}
+\newenvironment{productionlist}[1][\py at badkey]{
+  \def\optional##1{{\Large[}##1{\Large]}}
+  \def\production##1##2{\code{##1}&::=&\code{##2}\\}
+  \def\productioncont##1{& &\code{##1}\\}
+  \def\token##1{##1}
+  \let\grammartoken=\token
+  \parindent=2em
+  \indent
+  \begin{tabular}{lcl}
+}{%
+  \end{tabular}
+}
+
+\newlength{\py at noticelength}
+
+\newcommand{\py at heavybox}{
+  \setlength{\fboxrule}{2pt}
+  \setlength{\fboxsep}{7pt}
+  \setlength{\py at noticelength}{\linewidth}
+  \addtolength{\py at noticelength}{-2\fboxsep}
+  \addtolength{\py at noticelength}{-2\fboxrule}
+  \setlength{\shadowsize}{3pt}
+  \Sbox
+  \minipage{\py at noticelength}
+}
+\newcommand{\py at endheavybox}{
+  \endminipage
+  \endSbox
+  \fbox{\TheSbox}
+}
+
+% a 'note' is as plain as it gets:
+\newcommand{\py at noticelabel@note}{Note:}
+\newcommand{\py at noticestart@note}{}
+\newcommand{\py at noticeend@note}{}
+
+% a 'warning' gets more visible distinction:
+\newcommand{\py at noticelabel@warning}{Warning:}
+\newcommand{\py at noticestart@warning}{\py at heavybox}
+\newcommand{\py at noticeend@warning}{\py at endheavybox}
+
+\newenvironment{notice}[1][note]{
+  \def\py at noticetype{#1}
+  \csname py at noticestart@#1\endcsname
+  \par\strong{\csname py at noticelabel@#1\endcsname}
+}{\csname py at noticeend@\py at noticetype\endcsname}
+\newcommand{\note}[1]{\strong{\py at noticelabel@note} #1}
+\newcommand{\warning}[1]{\strong{\py at noticelabel@warning} #1}
+
+% Deprecation stuff.
+% Should be extended to allow an index / list of deprecated stuff.  But
+% there's a lot of stuff that needs to be done to make that automatable.
+%
+% First parameter is the release number that deprecates the feature, the
+% second is the action the should be taken by users of the feature.
+%
+% Example:
+%  \deprecated{1.5.1}{Use \method{frobnicate()} instead.}
+%
+\newcommand{\deprecated}[2]{%
+  \strong{Deprecated since release #1.}  #2\par}
+
+% New stuff.
+% This should be used to mark things which have been added to the
+% development tree but that aren't in the release, but are documented.
+% This allows release of documentation that already includes updated
+% descriptions.  Place at end of descriptor environment.
+%
+% Example:
+%  \versionadded{1.5.2}
+%  \versionchanged[short explanation]{2.0}
+%
+\newcommand{\versionadded}[2][\py at badkey]{%
+  \ifx#1\@undefined%
+    {  New in version #2.  }%
+  \else%
+    {  New in version #2:\ #1.  }%
+  \fi%
+}
+\newcommand{\versionchanged}[2][\py at badkey]{%
+  \ifx#1\@undefined%
+    {  Changed in version #2.  }%
+  \else%
+    {  Changed in version #2:\ #1.  }%
+  \fi%
+}
+
+
+% Tables.
+%
+\newenvironment{tableii}[4]{%
+  \begin{center}%
+    \def\lineii##1##2{\csname#2\endcsname{##1}&##2\\}%
+    \begin{tabular}{#1}\strong{#3}&\strong{#4} \\* \hline%
+}{%
+    \end{tabular}%
+  \end{center}%
+}
+
+\newenvironment{longtableii}[4]{%
+  \begin{center}%
+    \def\lineii##1##2{\csname#2\endcsname{##1}&##2\\}%
+    \begin{longtable}[c]{#1}\strong{#3}&\strong{#4} \\* \hline\endhead%
+}{%
+    \end{longtable}%
+  \end{center}%
+}
+
+\newenvironment{tableiii}[5]{%
+  \begin{center}%
+    \def\lineiii##1##2##3{\csname#2\endcsname{##1}&##2&##3\\}%
+    \begin{tabular}{#1}\strong{#3}&\strong{#4}&\strong{#5} \\%
+      \hline%
+}{%
+    \end{tabular}%
+  \end{center}%
+}
+
+\newenvironment{longtableiii}[5]{%
+  \begin{center}%
+    \def\lineiii##1##2##3{\csname#2\endcsname{##1}&##2&##3\\}%
+    \begin{longtable}[c]{#1}\strong{#3}&\strong{#4}&\strong{#5} \\%
+      \hline\endhead%
+}{%
+    \end{longtable}%
+  \end{center}%
+}
+
+\newenvironment{tableiv}[6]{%
+  \begin{center}%
+    \def\lineiv##1##2##3##4{\csname#2\endcsname{##1}&##2&##3&##4\\}%
+    \begin{tabular}{#1}\strong{#3}&\strong{#4}&\strong{#5}&\strong{#6} \\%
+      \hline%
+}{%
+    \end{tabular}%
+  \end{center}%
+}
+
+\newenvironment{longtableiv}[6]{%
+  \begin{center}%
+    \def\lineiv##1##2##3##4{\csname#2\endcsname{##1}&##2&##3&##4\\}%
+    \begin{longtable}[c]{#1}\strong{#3}&\strong{#4}&\strong{#5}&\strong{#6}%
+      \\%
+      \hline\endhead%
+}{%
+    \end{longtable}%
+  \end{center}%
+}
+
+\newenvironment{tablev}[7]{%
+  \begin{center}%
+    \def\linev##1##2##3##4##5{\csname#2\endcsname{##1}&##2&##3&##4&##5\\}%
+    \begin{tabular}{#1}\strong{#3}&\strong{#4}&\strong{#5}&\strong{#6}&\strong{#7} \\%
+      \hline%
+}{%
+    \end{tabular}%
+  \end{center}%
+}
+
+\newenvironment{longtablev}[7]{%
+  \begin{center}%
+    \def\linev##1##2##3##4##5{\csname#2\endcsname{##1}&##2&##3&##4&##5\\}%
+    \begin{longtable}[c]{#1}\strong{#3}&\strong{#4}&\strong{#5}&\strong{#6}&\strong{#7}%
+      \\%
+      \hline\endhead%
+}{%
+    \end{longtable}%
+  \end{center}%
+}
+
+% XXX Don't think we can use this yet, though it cleans up some
+% tedious markup.  There's no equivalent for the HTML transform yet,
+% and that needs to exist.  I don't know how to write it.
+%
+% This should really have something that makes it easier to bind a
+% table's ``Notes'' column and an associated tablenotes environment,
+% and generates the right magic for getting the numbers right in the
+% table.
+%
+% So this is quite incomplete.
+%
+\newcounter{py at tablenotescounter}
+\newenvironment{tablenotes}{%
+  \noindent Notes:
+  \par
+  \setcounter{py at tablenotescounter}{0}
+  \begin{list}{(\arabic{py at tablenotescounter})}%
+              {\usecounter{py at tablenotescounter}}
+}{\end{list}}
+
+
+% Cross-referencing (AMK, new impl. FLD)
+% Sample usage:
+%  \begin{seealso}
+%    \seemodule{rand}{Uniform random number generator.}; % Module xref
+%    \seetext{\emph{Encyclopedia Britannica}}.           % Ref to a book
+% 
+%    % A funky case: module name contains '_'; have to supply an optional key
+%    \seemodule[copyreg]{copy_reg}{Interface constructor registration for
+%                                  \module{pickle}.}
+%  \end{seealso}
+%
+% Note that the last parameter for \seemodule and \seetext should be complete
+% sentences and be terminated with the proper punctuation.
+
+\ifpdf
+  \newcommand{\py at seemodule}[3][\py at modulebadkey]{%
+    \par%
+    \ifx\py at modulebadkey#1\def\py at modulekey{#2}\else\def\py at modulekey{#1}\fi%
+    \begin{fulllineitems}
+      \item[\py at linkToName{label-module-\py at modulekey}{Module \module{#2}}
+            (section \ref{module-\py at modulekey}):]
+      #3
+    \end{fulllineitems}
+  }
+\else
+  \newcommand{\py at seemodule}[3][\py at modulebadkey]{%
+    \par%
+    \ifx\py at modulebadkey#1\def\py at modulekey{#2}\else\def\py at modulekey{#1}\fi%
+    \begin{fulllineitems}
+      \item[Module \module{#2} (section \ref{module-\py at modulekey}):]
+      #3
+    \end{fulllineitems}
+  }
+\fi
+
+% \seelink{url}{link text}{why it's interesting}
+\newcommand{\py at seelink}[3]{%
+  \par
+  \begin{fulllineitems}
+    \item[\ulink{#2}{#1}]
+    #3
+  \end{fulllineitems}
+}
+% \seetitle[url]{title}{why it's interesting}
+\newcommand{\py at seetitle}[3][\py at modulebadkey]{%
+  \par
+  \begin{fulllineitems}
+    \item[\citetitle{#2}]
+    \ifx\py at modulebadkey#1\else
+      \item[{\small{(\url{#1})}}]
+    \fi
+    #3
+  \end{fulllineitems}
+}
+% \seepep{number}{title}{why it's interesting}
+\newcommand{\py at seepep}[3]{%
+  \par%
+  \begin{fulllineitems}
+    \item[\pep{#1}, ``\emph{#2}'']
+    #3
+  \end{fulllineitems}
+}
+% \seerfc{number}{title}{why it's interesting}
+\newcommand{\py at seerfc}[3]{%
+  \par%
+  \begin{fulllineitems}
+    \item[\rfc{#1}, ``\emph{#2}'']
+    #3
+  \end{fulllineitems}
+}
+% \seeurl{url}{why it's interesting}
+\newcommand{\py at seeurl}[2]{%
+  \par%
+  \begin{fulllineitems}
+    \item[\url{#1}]
+    #2
+  \end{fulllineitems}
+}
+
+\newenvironment{seealso*}{
+  \par
+  \def\seetext##1{\par{##1}}
+  \let\seemodule=\py at seemodule
+  \let\seepep=\py at seepep
+  \let\seerfc=\py at seerfc
+  \let\seetitle=\py at seetitle
+  \let\seeurl=\py at seeurl
+  \let\seelink=\py at seelink
+}{\par}
+\newenvironment{seealso}{
+  \par
+  \strong{See Also:}
+  \par
+  \def\seetext##1{\par{##1}}
+  \let\seemodule=\py at seemodule
+  \let\seepep=\py at seepep
+  \let\seerfc=\py at seerfc
+  \let\seetitle=\py at seetitle
+  \let\seeurl=\py at seeurl
+  \let\seelink=\py at seelink
+}{\par}
+
+% Allow the Python release number to be specified independently of the
+% \date{}.  This allows the date to reflect the document's date and
+% release to specify the Python release that is documented.
+%
+\newcommand{\py at release}{}
+\newcommand{\version}{}
+\newcommand{\shortversion}{}
+\newcommand{\releaseinfo}{}
+\newcommand{\releasename}{Release}
+\newcommand{\release}[1]{%
+  \renewcommand{\py at release}{\releasename\space\version}%
+  \renewcommand{\version}{#1}}
+\newcommand{\setshortversion}[1]{%
+  \renewcommand{\shortversion}{#1}}
+\newcommand{\setreleaseinfo}[1]{%
+  \renewcommand{\releaseinfo}{#1}}
+
+% Allow specification of the author's address separately from the
+% author's name.  This can be used to format them differently, which
+% is a good thing.
+%
+\newcommand{\py at authoraddress}{}
+\newcommand{\authoraddress}[1]{\renewcommand{\py at authoraddress}{#1}}
+\let\developersaddress=\authoraddress
+\let\developer=\author
+\let\developers=\author
+
+% This sets up the fancy chapter headings that make the documents look
+% at least a little better than the usual LaTeX output.
+%
+\@ifundefined{ChTitleVar}{}{
+  \ChNameVar{\raggedleft\normalsize\py at HeaderFamily}
+  \ChNumVar{\raggedleft \bfseries\Large\py at HeaderFamily}
+  \ChTitleVar{\raggedleft \rm\Huge\py at HeaderFamily}
+  % This creates chapter heads without the leading \vspace*{}:
+  \def\@makechapterhead#1{%
+    {\parindent \z@ \raggedright \normalfont
+      \ifnum \c at secnumdepth >\m at ne
+        \DOCH
+      \fi
+      \interlinepenalty\@M
+      \DOTI{#1}
+    }
+  }
+}
+
+
+% Definition lists; requested by AMK for HOWTO documents.  Probably useful
+% elsewhere as well, so keep in in the general style support.
+%
+\newenvironment{definitions}{%
+  \begin{description}%
+  \def\term##1{\item[##1]\mbox{}\\*[0mm]}
+}{%
+  \end{description}%
+}
+
+% Tell TeX about pathological hyphenation cases:
+\hyphenation{Base-HTTP-Re-quest-Hand-ler}

Added: vendor/Python/current/Doc/texinputs/underscore.sty
===================================================================
--- vendor/Python/current/Doc/texinputs/underscore.sty	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/texinputs/underscore.sty	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,232 @@
+% underscore.sty     12-Oct-2001   Donald Arseneau   asnd at triumf.ca
+% Make the "_" character print as "\textunderscore" in text.
+% Copyright 1998,2001 Donald Arseneau;  Distribute freely if unchanged.
+% Instructions follow after the definitions.
+
+\ProvidesPackage{underscore}[2001/10/12]
+
+\begingroup
+ \catcode`\_=\active
+ \gdef_{% \relax % No relax gives a small vulnerability in alignments
+   \ifx\if at safe@actives\iftrue % must be outermost test!
+      \string_%
+   \else
+      \ifx\protect\@typeset at protect
+         \ifmmode \sb \else \BreakableUnderscore \fi
+      \else
+         \ifx\protect\@unexpandable at protect \noexpand_%
+         \else \protect_%
+      \fi\fi
+    \fi}
+\endgroup
+
+% At begin: set catcode; fix \long \ttdefault so I can use it in comparisons; 
+\AtBeginDocument{%
+  {\immediate\write\@auxout{\catcode\number\string`\_ \string\active}}%
+  \catcode\string`\_\string=\active
+  \edef\ttdefault{\ttdefault}%
+}
+
+\newcommand{\BreakableUnderscore}{\leavevmode\nobreak\hskip\z at skip
+ \ifx\f at family\ttdefault \string_\else \textunderscore\fi
+ \usc at dischyph\nobreak\hskip\z at skip}
+
+\DeclareRobustCommand{\_}{%
+  \ifmmode \nfss at text{\textunderscore}\else \BreakableUnderscore \fi}
+
+\let\usc at dischyph\@dischyph
+\DeclareOption{nohyphen}{\def\usc at dischyph{\discretionary{}{}{}}}
+\DeclareOption{strings}{\catcode`\_=\active}
+
+\ProcessOptions
+\ifnum\catcode`\_=\active\else \endinput \fi
+
+%%%%%%%%   Redefine commands that use character strings   %%%%%%%%
+
+\@ifundefined{UnderscoreCommands}{\let\UnderscoreCommands\@empty}{}
+\expandafter\def\expandafter\UnderscoreCommands\expandafter{%
+  \UnderscoreCommands
+  \do\include \do\includeonly
+  \do\@input \do\@iinput \do\InputIfFileExists
+  \do\ref \do\pageref \do\newlabel
+  \do\bibitem \do\@bibitem \do\cite \do\nocite \do\bibcite
+}
+
+% Macro to redefine a macro to pre-process its string argument
+% with \protect -> \string.
+\def\do#1{% Avoid double processing if user includes command twice!
+ \@ifundefined{US\string_\expandafter\@gobble\string#1}{%
+   \edef\@tempb{\meaning#1}% Check if macro is just a protection shell...
+   \def\@tempc{\protect}%
+   \edef\@tempc{\meaning\@tempc\string#1\space\space}%
+   \ifx\@tempb\@tempc % just a shell: hook into the protected inner command
+     \expandafter\do
+       \csname \expandafter\@gobble\string#1 \expandafter\endcsname
+   \else % Check if macro takes an optional argument
+     \def\@tempc{\@ifnextchar[}%
+     \edef\@tempa{\def\noexpand\@tempa####1\meaning\@tempc}%
+     \@tempa##2##3\@tempa{##2\relax}%
+     \edef\@tempb{\meaning#1\meaning\@tempc}%
+     \edef\@tempc{\noexpand\@tempd \csname
+        US\string_\expandafter\@gobble\string#1\endcsname}%
+     \if \expandafter\@tempa\@tempb \relax 12\@tempa % then no optional arg
+       \@tempc #1\US at prot
+     \else  % There is optional arg
+       \@tempc #1\US at protopt
+     \fi
+   \fi
+ }{}}
+
+\def\@tempd#1#2#3{\let#1#2\def#2{#3#1}}
+
+\def\US at prot#1#2{\let\@@protect\protect \let\protect\string
+  \edef\US at temp##1{##1{#2}}\restore at protect\US at temp#1}
+\def\US at protopt#1{\@ifnextchar[{\US at protarg#1}{\US at prot#1}}
+\def\US at protarg #1[#2]{\US at prot{{#1[#2]}}}
+
+\UnderscoreCommands
+\let\do\relax \let\@tempd\relax  % un-do
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\endinput
+
+underscore.sty    12-Oct-2001  Donald Arseneau
+
+Features:
+~~~~~~~~~
+\_ prints an underscore so that the hyphenation of constituent words
+is not affected and hyphenation is permitted after the underscore.
+For example, "compound\_fracture" hyphenates as com- pound_- frac- ture.
+If you prefer the underscore to break without a hyphen (but still with 
+the same rules for explicit hyphen-breaks) then use the [nohyphen]
+package option.
+
+A simple _  acts just like \_ in text mode, but makes a subscript in 
+math mode: activation_energy $E_a$
+
+Both forms use an underscore character if the font encoding contains
+one (e.g., "\usepackage[T1]{fontenc}" or typewriter fonts in any encoding),
+but they use a rule if the there is no proper character.
+
+Deficiencies:
+~~~~~~~~~~~~~
+The skips and penalties ruin any kerning with the underscore character
+(when a character is used).  However, there doesn't seem to be much, if
+any, such kerning in the ec fonts, and there is never any kerning with
+a rule.
+
+You must avoid "_" in file names and in cite or ref tags, or you must use 
+the babel package, with its active-character controls, or you must give 
+the [strings] option, which attempts to redefine several commands (and 
+may not work perfectly).  Even without the [strings] option or babel, you 
+can use occasional underscores like: "\include{file\string_name}".
+
+Option: [strings]
+~~~~~~~~~~~~~~~~~
+The default operation is quite simple and needs no customization; but
+you must avoid using "_" in any place where LaTeX uses an argument as
+a string of characters for some control function or as a name.  These
+include the tags for \cite and \ref, file names for \input, \include,
+and \includegraphics, environment names, counter names, and placement
+parameters (like "[t]").  The problem with these contexts is that they
+are `moving arguments' but LaTeX does not `switch on' the \protect
+mechanism for them.
+
+If you need to use the underscore character in these places, the package
+option [strings] is provided to redefine commands taking a string argument
+so that the argument is protected (with \protect -> \string).  The list
+of commands is given in "\UnderscoreCommands", with "\do" before each,
+covering \cite, \ref, \input, and their variants.  Not included are many
+commands regarding font names, everything with counter names, environment
+names, page styles, and versions of \ref and \cite defined by external
+packages (e.g. \vref and \citeyear).
+
+You can add to the list of supported commands by defining \UnderscoreCommands
+before loading this package; e.g.
+
+   \usepackage{chicago}
+   \newcommand{\UnderscoreCommands}{%   (\cite already done)
+     \do\citeNP \do\citeA \do\citeANP \do\citeN \do\shortcite
+     \do\shortciteNP \do\shortciteA \do\shortciteANP \do\shortciteN
+     \do\citeyear \do\citeyearNP
+   }
+   \usepackage[strings]{underscore}
+
+Not all commands can be supported this way!  Only commands that take a
+string argument *first* can be protected.  One optional argument before
+the string argument is also permitted, as exemplified by \cite: both
+\cite{tags} and \cite[text]{tags} are allowed.  A command like
+\@addtoreset which takes two counter names as arguments could not
+be protected by adding it to \UnderscoreCommands.
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!! When you use the [strings] option, you must load this package !!
+!! last (or nearly last).                                        !!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+There are two reasons: 1) The redefinitions done for protection must come
+after other packages define their customized versions of those commands.
+2) The [strings] option requires the _ character to be activated immediately
+in order for the cite and ref tags to be read properly from the .aux file
+as plain strings, and this catcode setting might disrupt other packages.
+
+The babel package implements a protection mechanism for many commands,
+and will be a complete fix for most documents without the [strings] option.
+Many add-on packages are compatible with babel, so they will get the
+strings protection also.  However, there are several commands that are 
+not covered by babel, but can easily be supported by the [strings] and 
+\UnderscoreCommands mechanism.  Beware that using both [strings] and babel 
+may lead to conflicts, but does appear to work (load babel last).
+
+Implementation Notes:
+~~~~~~~~~~~~~~~~~~~~~
+The first setting of "_" to be an active character is performed in a local
+group so as to not interfere with other packages.  The catcode setting
+is repeated with \AtBeginDocument so the definition is in effect for the
+text.  However, the catcode setting is repeated immediately when the
+[strings] option is detected.
+
+The definition of the active "_" is essentially:
+       \ifmmode \sb \else \BreakableUnderscore \fi
+where "\sb" retains the normal subscript meaning of "_" and where
+"\BreakableUnderscore" is essentially "\_".  The rest of the definition
+handles the "\protect"ion without causing \relax to be inserted before
+the character.
+
+\BreakableUnderscore uses "\nobreak\hskip\z at skip" to separate the
+underscore from surrounding words, thus allowing TeX to hyphenate them,
+but preventing free breaks around the underscore. Next, it checks the
+current font family, and uses the underscore character from tt fonts or
+otherwise \textunderscore (which is a character or rule depending on
+the font encoding).  After the underscore, it inserts a discretionary
+hyphenation point as "\usc at dischyph", which is usually just "\-"
+except that it still works in the tabbing environment, although it
+will give "\discretionary{}{}{}" under the [nohyphen] option.  After
+that, another piece of non-breaking interword glue is inserted. 
+Ordinarily, the comparison "\ifx\f at family\ttdefault" will always fail 
+because \ttdefault is `long' where \f at family is not (boooo hisss), but 
+\ttdefault is redefined to be non-long by "\AtBeginDocument".
+
+The "\_" command is then defined to use "\BreakableUnderscore".
+
+If the [strings] option is not given, then that is all!
+
+Under the [strings] option, the list of special commands is processed to:
+- retain the original command as \US_command (\US_ref)
+- redefine the command as \US at prot\US_command for ordinary commands
+  (\ref -> \US at prot\US_ref) or as \US at protopt\US_command when an optional
+  argument is possible (\bibitem -> \US at protopt\US_bibitem).
+- self-protecting commands (\cite) retain their self-protection.
+Diagnosing the state of the pre-existing command is done by painful
+contortions involving \meaning.
+
+\US at prot and \US at protopt read the argument, process it with \protect
+enabled, then invoke the saved \US_command.
+
+Modifications:
+~~~~~~~~~~~~~~
+12-Oct-2001  Babel (safe at actives) compatibility and [nohyphen] option.
+
+Test file integrity:  ASCII 32-57, 58-126:  !"#$%&'()*+,-./0123456789
+:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~

Added: vendor/Python/current/Doc/tools/anno-api.py
===================================================================
--- vendor/Python/current/Doc/tools/anno-api.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/tools/anno-api.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,71 @@
+#! /usr/bin/env python
+"""Add reference count annotations to the Python/C API Reference."""
+__version__ = '$Revision: 17623 $'
+
+import getopt
+import os
+import sys
+
+import refcounts
+
+
+PREFIX_1 = r"\begin{cfuncdesc}{PyObject*}{"
+PREFIX_2 = r"\begin{cfuncdesc}{PyVarObject*}{"
+
+
+def main():
+    rcfile = os.path.join(os.path.dirname(refcounts.__file__), os.pardir,
+                          "api", "refcounts.dat")
+    outfile = "-"
+    opts, args = getopt.getopt(sys.argv[1:], "o:r:", ["output=", "refcounts="])
+    for opt, arg in opts:
+        if opt in ("-o", "--output"):
+            outfile = arg
+        elif opt in ("-r", "--refcounts"):
+            rcfile = arg
+    rcdict = refcounts.load(rcfile)
+    if outfile == "-":
+        output = sys.stdout
+    else:
+        output = open(outfile, "w")
+    if not args:
+        args = ["-"]
+    for infile in args:
+        if infile == "-":
+            input = sys.stdin
+        else:
+            input = open(infile)
+        while 1:
+            line = input.readline()
+            if not line:
+                break
+            prefix = None
+            if line.startswith(PREFIX_1):
+                prefix = PREFIX_1
+            elif line.startswith(PREFIX_2):
+                prefix = PREFIX_2
+            if prefix:
+                s = line[len(prefix):].split('}', 1)[0]
+                try:
+                    info = rcdict[s]
+                except KeyError:
+                    sys.stderr.write("No refcount data for %s\n" % s)
+                else:
+                    if info.result_type in ("PyObject*", "PyVarObject*"):
+                        if info.result_refs is None:
+                            rc = "Always \NULL{}"
+                        else:
+                            rc = info.result_refs and "New" or "Borrowed"
+                            rc = rc + " reference"
+                        line = (r"\begin{cfuncdesc}[%s]{%s}{"
+                                % (rc, info.result_type)) \
+                                + line[len(prefix):]
+            output.write(line)
+        if infile != "-":
+            input.close()
+    if outfile != "-":
+        output.close()
+
+
+if __name__ == "__main__":
+    main()


Property changes on: vendor/Python/current/Doc/tools/anno-api.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Doc/tools/buildindex.py
===================================================================
--- vendor/Python/current/Doc/tools/buildindex.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/tools/buildindex.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,388 @@
+#! /usr/bin/env python
+
+__version__ = '$Revision: 36356 $'
+
+import os.path
+import re
+import string
+import sys
+
+from xml.sax.saxutils import quoteattr
+
+
+bang_join = "!".join
+null_join = "".join
+
+REPLACEMENTS = [
+    # Hackish way to deal with macros replaced with simple text
+    (re.compile(r"\\ABC\b"), "ABC"),
+    (re.compile(r"\\ASCII\b"), "ASCII"),
+    (re.compile(r"\\Cpp\b"), "C++"),
+    (re.compile(r"\\EOF\b"), "EOF"),
+    (re.compile(r"\\NULL\b"), "NULL"),
+    (re.compile(r"\\POSIX\b"), "POSIX"),
+    (re.compile(r"\\UNIX\b"), "Unix"),
+    # deal with turds left over from LaTeX2HTML
+    (re.compile(r"<#\d+#>"), ""),
+    ]
+
+class Node:
+    continuation = 0
+
+    def __init__(self, link, str, seqno):
+        self.links = [link]
+        self.seqno = seqno
+        for pattern, replacement in REPLACEMENTS:
+            str = pattern.sub(replacement, str)
+        # build up the text
+        self.text = split_entry_text(str)
+        self.key = split_entry_key(str)
+
+    def __cmp__(self, other):
+        """Comparison operator includes sequence number, for use with
+        list.sort()."""
+        return self.cmp_entry(other) or cmp(self.seqno, other.seqno)
+
+    def cmp_entry(self, other):
+        """Comparison 'operator' that ignores sequence number."""
+        c = 0
+        for i in range(min(len(self.key), len(other.key))):
+            c = (cmp_part(self.key[i], other.key[i])
+                 or cmp_part(self.text[i], other.text[i]))
+            if c:
+                break
+        return c or cmp(self.key, other.key) or cmp(self.text, other.text)
+
+    def __repr__(self):
+        return "<Node for %s (%s)>" % (bang_join(self.text), self.seqno)
+
+    def __str__(self):
+        return bang_join(self.key)
+
+    def dump(self):
+        return "%s\1%s###%s\n" \
+               % ("\1".join(self.links),
+                  bang_join(self.text),
+                  self.seqno)
+
+
+def cmp_part(s1, s2):
+    result = cmp(s1, s2)
+    if result == 0:
+        return 0
+    l1 = s1.lower()
+    l2 = s2.lower()
+    minlen = min(len(s1), len(s2))
+    if len(s1) < len(s2) and l1 == l2[:len(s1)]:
+        result = -1
+    elif len(s2) < len(s1) and l2 == l1[:len(s2)]:
+        result = 1
+    else:
+        result = cmp(l1, l2) or cmp(s1, s2)
+    return result
+
+
+def split_entry(str, which):
+    stuff = []
+    parts = str.split('!')
+    parts = [part.split('@') for part in parts]
+    for entry in parts:
+        if len(entry) != 1:
+            key = entry[which]
+        else:
+            key = entry[0]
+        stuff.append(key)
+    return stuff
+
+
+_rmtt = re.compile(r"""(.*)<tt(?: class=['"][a-z0-9]+["'])?>(.*)</tt>(.*)$""",
+                   re.IGNORECASE)
+_rmparens = re.compile(r"\(\)")
+
+def split_entry_key(str):
+    parts = split_entry(str, 1)
+    for i in range(len(parts)):
+        m = _rmtt.match(parts[i])
+        if m:
+            parts[i] = null_join(m.group(1, 2, 3))
+        else:
+            parts[i] = parts[i].lower()
+        # remove '()' from the key:
+        parts[i] = _rmparens.sub('', parts[i])
+    return map(trim_ignored_letters, parts)
+
+
+def split_entry_text(str):
+    if '<' in str:
+        m = _rmtt.match(str)
+        if m:
+            str = null_join(m.group(1, 2, 3))
+    return split_entry(str, 1)
+
+
+def load(fp):
+    nodes = []
+    rx = re.compile("(.*)\1(.*)###(.*)$")
+    while 1:
+        line = fp.readline()
+        if not line:
+            break
+        m = rx.match(line)
+        if m:
+            link, str, seqno = m.group(1, 2, 3)
+            nodes.append(Node(link, str, seqno))
+    return nodes
+
+
+def trim_ignored_letters(s):
+    # ignore $ to keep environment variables with the
+    # leading letter from the name
+    if s.startswith("$"):
+        return s[1:].lower()
+    else:
+        return s.lower()
+
+def get_first_letter(s):
+    if s.startswith("<tex2html_percent_mark>"):
+        return "%"
+    else:
+        return trim_ignored_letters(s)[0]
+
+
+def split_letters(nodes):
+    letter_groups = []
+    if nodes:
+        group = []
+        append = group.append
+        letter = get_first_letter(nodes[0].text[0])
+        letter_groups.append((letter, group))
+        for node in nodes:
+            nletter = get_first_letter(node.text[0])
+            if letter != nletter:
+                letter = nletter
+                group = []
+                letter_groups.append((letter, group))
+                append = group.append
+            append(node)
+    return letter_groups
+
+
+def group_symbols(groups):
+    entries = []
+    ident_letters = string.ascii_letters + "_"
+    while groups[0][0] not in ident_letters:
+        entries += groups[0][1]
+        del groups[0]
+    if entries:
+        groups.insert(0, ("Symbols", entries))
+
+
+# need a function to separate the nodes into columns...
+def split_columns(nodes, columns=1):
+    if columns <= 1:
+        return [nodes]
+    # This is a rough height; we may have to increase to avoid breaks before
+    # a subitem.
+    colheight = int(len(nodes) / columns)
+    numlong = int(len(nodes) % columns)
+    if numlong:
+        colheight = colheight + 1
+    else:
+        numlong = columns
+    cols = []
+    for i in range(numlong):
+        start = i * colheight
+        end = start + colheight
+        cols.append(nodes[start:end])
+    del nodes[:end]
+    colheight = colheight - 1
+    try:
+        numshort = int(len(nodes) / colheight)
+    except ZeroDivisionError:
+        cols = cols + (columns - len(cols)) * [[]]
+    else:
+        for i in range(numshort):
+            start = i * colheight
+            end = start + colheight
+            cols.append(nodes[start:end])
+    #
+    # If items continue across columns, make sure they are marked
+    # as continuations so the user knows to look at the previous column.
+    #
+    for i in range(len(cols) - 1):
+        try:
+            prev = cols[i][-1]
+            next = cols[i + 1][0]
+        except IndexError:
+            return cols
+        else:
+            n = min(len(prev.key), len(next.key))
+            for j in range(n):
+                if prev.key[j] != next.key[j]:
+                    break
+                next.continuation = j + 1
+    return cols
+
+
+DL_LEVEL_INDENT = "  "
+
+def format_column(nodes):
+    strings = ["<dl compact='compact'>"]
+    append = strings.append
+    level = 0
+    previous = []
+    for node in nodes:
+        current = node.text
+        count = 0
+        for i in range(min(len(current), len(previous))):
+            if previous[i] != current[i]:
+                break
+            count = i + 1
+        if count > level:
+            append("<dl compact='compact'>" * (count - level) + "\n")
+            level = count
+        elif level > count:
+            append("\n")
+            append(level * DL_LEVEL_INDENT)
+            append("</dl>" * (level - count))
+            level = count
+        # else: level == count
+        for i in range(count, len(current) - 1):
+            term = node.text[i]
+            level = level + 1
+            if node.continuation > i:
+                extra = " (continued)"
+            else:
+                extra = ""
+            append("\n<dt>%s%s\n<dd>\n%s<dl compact='compact'>"
+                   % (term, extra, level * DL_LEVEL_INDENT))
+        append("\n%s<dt>%s%s</a>"
+               % (level * DL_LEVEL_INDENT, node.links[0], node.text[-1]))
+        for link in node.links[1:]:
+            append(",\n%s    %s[Link]</a>" % (level * DL_LEVEL_INDENT, link))
+        previous = current
+    append("\n")
+    append("</dl>" * (level + 1))
+    return null_join(strings)
+
+
+def format_nodes(nodes, columns=1):
+    strings = []
+    append = strings.append
+    if columns > 1:
+        colnos = range(columns)
+        colheight = int(len(nodes) / columns)
+        if len(nodes) % columns:
+            colheight = colheight + 1
+        colwidth = int(100 / columns)
+        append('<table width="100%"><tr valign="top">')
+        for col in split_columns(nodes, columns):
+            append('<td width="%d%%">\n' % colwidth)
+            append(format_column(col))
+            append("\n</td>")
+        append("\n</tr></table>")
+    else:
+        append(format_column(nodes))
+    return null_join(strings)
+
+
+def format_letter(letter):
+    if letter == '.':
+        lettername = ". (dot)"
+    elif letter == '_':
+        lettername = "_ (underscore)"
+    else:
+        lettername = letter.capitalize()
+    return "\n<hr />\n<h2 id=%s>%s</h2>\n\n" \
+           % (quoteattr("letter-" + letter), lettername)
+
+
+def format_html_letters(nodes, columns, group_symbol_nodes):
+    letter_groups = split_letters(nodes)
+    if group_symbol_nodes:
+        group_symbols(letter_groups)
+    items = []
+    for letter, nodes in letter_groups:
+        s = "<b><a href=\"#letter-%s\">%s</a></b>" % (letter, letter)
+        items.append(s)
+    s = ["<hr /><center>\n%s</center>\n" % " |\n".join(items)]
+    for letter, nodes in letter_groups:
+        s.append(format_letter(letter))
+        s.append(format_nodes(nodes, columns))
+    return null_join(s)
+
+def format_html(nodes, columns):
+    return format_nodes(nodes, columns)
+
+
+def collapse(nodes):
+    """Collapse sequences of nodes with matching keys into a single node.
+    Destructive."""
+    if len(nodes) < 2:
+        return
+    prev = nodes[0]
+    i = 1
+    while i < len(nodes):
+        node = nodes[i]
+        if not node.cmp_entry(prev):
+            prev.links.append(node.links[0])
+            del nodes[i]
+        else:
+            i = i + 1
+            prev = node
+
+
+def dump(nodes, fp):
+    for node in nodes:
+        fp.write(node.dump())
+
+
+def process_nodes(nodes, columns, letters=0, group_symbol_nodes=0):
+    nodes.sort()
+    collapse(nodes)
+    if letters:
+        return format_html_letters(nodes, columns, group_symbol_nodes)
+    else:
+        return format_html(nodes, columns)
+
+
+def main():
+    import getopt
+    ifn = "-"
+    ofn = "-"
+    columns = 1
+    letters = 0
+    group_symbol_nodes = 1
+    opts, args = getopt.getopt(sys.argv[1:], "c:lo:",
+                               ["columns=", "dont-group-symbols",
+                                "group-symbols", "letters", "output="])
+    for opt, val in opts:
+        if opt in ("-o", "--output"):
+            ofn = val
+        elif opt in ("-c", "--columns"):
+            columns = int(val, 10)
+        elif opt in ("-l", "--letters"):
+            letters = 1
+        elif opt == "--group-symbols":
+            group_symbol_nodes = 1
+        elif opt == "--dont-group-symbols":
+            group_symbol_nodes = 0
+    if not args:
+        args = [ifn]
+    nodes = []
+    for fn in args:
+        nodes = nodes + load(open(fn))
+    num_nodes = len(nodes)
+    html = process_nodes(nodes, columns, letters, group_symbol_nodes)
+    program = os.path.basename(sys.argv[0])
+    if ofn == "-":
+        sys.stdout.write(html)
+        sys.stderr.write("\n%s: %d index nodes" % (program, num_nodes))
+    else:
+        open(ofn, "w").write(html)
+        print
+        print "%s: %d index nodes" % (program, num_nodes)
+
+
+if __name__ == "__main__":
+    main()


Property changes on: vendor/Python/current/Doc/tools/buildindex.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Doc/tools/checkargs.pm
===================================================================
--- vendor/Python/current/Doc/tools/checkargs.pm	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/tools/checkargs.pm	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,112 @@
+#! /usr/bin/perl
+
+package checkargs;
+require 5.004;			# uses "for my $var"
+require Exporter;
+ at ISA = qw(Exporter);
+ at EXPORT = qw(check_args check_args_range check_args_at_least);
+use strict;
+use Carp;
+
+=head1 NAME
+
+checkargs -- Provide rudimentary argument checking for perl5 functions
+
+=head1 SYNOPSIS
+
+  check_args(cArgsExpected, @_)
+  check_args_range(cArgsMin, cArgsMax, @_)
+  check_args_at_least(cArgsMin, @_)
+where "@_" should be supplied literally.
+
+=head1 DESCRIPTION
+
+As the first line of user-written subroutine foo, do one of the following:
+
+  my ($arg1, $arg2) = check_args(2, @_);
+  my ($arg1, @rest) = check_args_range(1, 4, @_);
+  my ($arg1, @rest) = check_args_at_least(1, @_);
+  my @args = check_args_at_least(0, @_);
+
+These functions may also be called for side effect (put a call to one
+of the functions near the beginning of the subroutine), but using the
+argument checkers to set the argument list is the recommended usage.
+
+The number of arguments and their definedness are checked; if the wrong
+number are received, the program exits with an error message.
+
+=head1 AUTHOR
+
+Michael D. Ernst <F<mernst at cs.washington.edu>>
+
+=cut
+
+## Need to check that use of caller(1) really gives desired results.
+## Need to give input chunk information.
+## Is this obviated by Perl 5.003's declarations?  Not entirely, I think.
+
+sub check_args ( $@ )
+{
+  my ($num_formals, @args) = @_;
+  my ($pack, $file_arg, $line_arg, $subname, $hasargs, $wantarr) = caller(1);
+  if (@_ < 1) { croak "check_args needs at least 7 args, got ", scalar(@_), ": @_\n "; }
+  if ((!wantarray) && ($num_formals != 0))
+    { croak "check_args called in scalar context"; }
+  # Can't use croak below here: it would only go out to caller, not its caller
+  my $num_actuals = @args;
+  if ($num_actuals != $num_formals)
+    { die "$file_arg:$line_arg: function $subname expected $num_formals argument",
+      (($num_formals == 1) ? "" : "s"),
+      ", got $num_actuals",
+      (($num_actuals == 0) ? "" : ": @args"),
+      "\n"; }
+  for my $index (0..$#args)
+    { if (!defined($args[$index]))
+	{ die "$file_arg:$line_arg: function $subname undefined argument ", $index+1, ": @args[0..$index-1]\n"; } }
+  return @args;
+}
+
+sub check_args_range ( $$@ )
+{
+  my ($min_formals, $max_formals, @args) = @_;
+  my ($pack, $file_arg, $line_arg, $subname, $hasargs, $wantarr) = caller(1);
+  if (@_ < 2) { croak "check_args_range needs at least 8 args, got ", scalar(@_), ": @_"; }
+  if ((!wantarray) && ($max_formals != 0) && ($min_formals !=0) )
+    { croak "check_args_range called in scalar context"; }
+  # Can't use croak below here: it would only go out to caller, not its caller
+  my $num_actuals = @args;
+  if (($num_actuals < $min_formals) || ($num_actuals > $max_formals))
+    { die "$file_arg:$line_arg: function $subname expected $min_formals-$max_formals arguments, got $num_actuals",
+      ($num_actuals == 0) ? "" : ": @args", "\n"; }
+  for my $index (0..$#args)
+    { if (!defined($args[$index]))
+	{ die "$file_arg:$line_arg: function $subname undefined argument ", $index+1, ": @args[0..$index-1]\n"; } }
+  return @args;
+}
+
+sub check_args_at_least ( $@ )
+{
+  my ($min_formals, @args) = @_;
+  my ($pack, $file_arg, $line_arg, $subname, $hasargs, $wantarr) = caller(1);
+  # Don't do this, because we want every sub to start with a call to check_args*
+  # if ($min_formals == 0)
+  #   { die "Isn't it pointless to check for at least zero args to $subname?\n"; }
+  if (scalar(@_) < 1)
+    { croak "check_args_at_least needs at least 1 arg, got ", scalar(@_), ": @_"; }
+  if ((!wantarray) && ($min_formals != 0))
+    { croak "check_args_at_least called in scalar context"; }
+  # Can't use croak below here: it would only go out to caller, not its caller
+  my $num_actuals = @args;
+  if ($num_actuals < $min_formals)
+    { die "$file_arg:$line_arg: function $subname expected at least $min_formals argument",
+      ($min_formals == 1) ? "" : "s",
+      ", got $num_actuals",
+      ($num_actuals == 0) ? "" : ": @args", "\n"; }
+  for my $index (0..$#args)
+    { if (!defined($args[$index]))
+	{ warn "$file_arg:$line_arg: function $subname undefined argument ", $index+1, ": @args[0..$index-1]\n"; last; } }
+  return @args;
+}
+
+1;				# successful import
+__END__

Added: vendor/Python/current/Doc/tools/cklatex
===================================================================
--- vendor/Python/current/Doc/tools/cklatex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/tools/cklatex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,26 @@
+#! /bin/sh
+#  -*- ksh -*-
+
+# This script *helps* locate lines of normal content that end in '}';
+# this is useful since LaTeX2HTML (at least the old version that we
+# use) breaks on many lines that end that way.
+#
+# Usage: cklatex files... | less
+#
+# *Read* the output looking for suspicious lines!
+
+grep -n "[^ 	]}\$" $@ | \
+ grep -v '\\begin{' | \
+ grep -v '\\end{' | \
+ grep -v '\\input{' | \
+ grep -v '\\documentclass{' | \
+ grep -v '\\title{' | \
+ grep -v '\\chapter{' | \
+ grep -v '\\chapter\*{' | \
+ grep -v '\\section{' | \
+ grep -v '\\subsection{' | \
+ grep -v '\\subsubsection{' | \
+ grep -v '\\sectionauthor{' | \
+ grep -v '\\moduleauthor{'
+
+exit $?


Property changes on: vendor/Python/current/Doc/tools/cklatex
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Doc/tools/cmpcsyms
===================================================================
--- vendor/Python/current/Doc/tools/cmpcsyms	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/tools/cmpcsyms	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,157 @@
+#! /usr/bin/env python
+from __future__ import with_statement
+import errno
+import os
+import re
+import sys
+import string
+
+if __name__ == "__main__":
+    _base = sys.argv[0]
+else:
+    _base = __file__
+
+_script_home = os.path.abspath(os.path.dirname(_base))
+
+srcdir = os.path.dirname(os.path.dirname(_script_home))
+
+EXCLUDES = ["bitset.h", "cStringIO.h", "graminit.h", "grammar.h",
+            "longintrepr.h", "metagrammar.h",
+            "node.h", "opcode.h", "osdefs.h", "pgenheaders.h",
+            "py_curses.h", "parsetok.h", "symtable.h", "token.h"]
+
+
+def list_headers():
+    """Return a list of headers."""
+    incdir = os.path.join(srcdir, "Include")
+    return [os.path.join(incdir, fn) for fn in os.listdir(incdir)
+            if fn.endswith(".h") and fn not in EXCLUDES]
+
+
+def matcher(pattern):
+    return re.compile(pattern).search
+
+MATCHERS = [
+    # XXX this should also deal with ctypedesc, cvardesc and cmemberdesc
+    matcher(r"\\begin\{cfuncdesc\}\{(?P<result>[^}]*)\}\{(?P<sym>[^}]*)\}{(?P<params>[^}]*)\}"),
+    matcher(r"\\cfuncline\{(?P<result>[^})]*)\}\{(?P<sym>[^}]*)\}{(?P<params>[^}]*)\}"),
+    ]
+
+def list_documented_items():
+    """Return a list of everything that's already documented."""
+    apidir = os.path.join(srcdir, "Doc", "api")
+    files = [fn for fn in os.listdir(apidir) if fn.endswith(".tex")]
+    L = []
+    for fn in files:
+        fullname = os.path.join(apidir, fn)
+	data = open(fullname).read()
+        for matcher in MATCHERS:
+            pos = 0
+            while 1:
+                m = matcher(data, pos)
+                if not m: break
+                pos = m.end()
+                sym = m.group("sym")
+                result = m.group("result")
+                params = m.group("params")
+		# replace all whitespace with a single one
+		params = " ".join(params.split()) 
+                L.append((sym, result, params, fn))
+    return L
+
+def normalize_type(t):
+    t = t.strip()
+    s = t.rfind("*")
+    if s != -1:
+        # strip everything after the pointer name
+        t = t[:s+1]
+    # Drop the variable name
+    s = t.split()
+    typenames = 1
+    if len(s)>1 and s[0]=='unsigned' and s[1]=='int':
+        typenames = 2
+    if len(s) > typenames and s[-1][0] in string.letters:
+        del s[-1]
+    if not s:
+       print "XXX", t
+       return ""
+    # Drop register
+    if s[0] == "register":
+        del s[0]
+    # discard all spaces
+    return ''.join(s)
+    
+def compare_type(t1, t2):
+    t1 = normalize_type(t1)
+    t2 = normalize_type(t2)
+    if t1 == r'\moreargs' and t2 == '...':
+        return False
+    if t1 != t2:
+        #print "different:", t1, t2
+        return False
+    return True
+
+
+def compare_types(ret, params, hret, hparams):
+    if not compare_type(ret, hret):
+        return False
+    params = params.split(",")
+    hparams = hparams.split(",")
+    if not params and hparams == ['void']:
+        return True
+    if not hparams and params == ['void']:
+        return True
+    if len(params) != len(hparams):
+        return False
+    for p1, p2 in zip(params, hparams):
+        if not compare_type(p1, p2):
+            return False
+    return True
+
+def main():
+    headers = list_headers()
+    documented = list_documented_items()
+
+    lines = []
+    for h in headers:
+        data = open(h).read()
+        data, n = re.subn(r"PyAPI_FUNC\(([^)]*)\)", r"\1", data)
+        name = os.path.basename(h)
+        with open(name, "w") as f:
+            f.write(data)
+        cmd = ("ctags -f - --file-scope=no --c-kinds=p --fields=S "
+               "-Istaticforward -Istatichere=static " + name)
+        with os.popen(cmd) as f:
+            lines.extend(f.readlines())
+        os.unlink(name)
+    L = {}
+    prevsym = None
+    for line in lines:
+        if not line:
+            break
+        sym, filename, signature = line.split(None, 2)
+        if sym == prevsym:
+            continue
+	expr = "\^(.*)%s" % sym
+	m = re.search(expr, signature)
+        if not m:
+    	    print "Could not split",signature, "using",expr
+	rettype = m.group(1).strip()
+	m = re.search("signature:\(([^)]*)\)", signature)
+	if not m:
+	    print "Could not get signature from", signature
+	params = m.group(1)
+	L[sym] = (rettype, params)
+
+    for sym, ret, params, fn in documented:
+        if sym not in L:
+           print "No declaration for '%s'" % sym
+           continue
+        hret, hparams = L[sym]
+        if not compare_types(ret, params, hret, hparams):
+           print "Declaration error for %s (%s):" % (sym, fn)
+           print ret+": "+params
+           print hret+": "+hparams
+
+if __name__ == "__main__":
+    main()


Property changes on: vendor/Python/current/Doc/tools/cmpcsyms
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Doc/tools/custlib.py
===================================================================
--- vendor/Python/current/Doc/tools/custlib.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/tools/custlib.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,78 @@
+# Generate custlib.tex, which is a site-specific library document.
+
+# Phase I: list all the things that can be imported
+
+import glob
+import os.path
+import sys
+
+modules = {}
+
+for modname in sys.builtin_module_names:
+    modules[modname] = modname
+
+for dir in sys.path:
+    # Look for *.py files
+    filelist = glob.glob(os.path.join(dir, '*.py'))
+    for file in filelist:
+        path, file = os.path.split(file)
+        base, ext = os.path.splitext(file)
+        modules[base.lower()] = base
+
+    # Look for shared library files
+    filelist = (glob.glob(os.path.join(dir, '*.so')) +
+                glob.glob(os.path.join(dir, '*.sl')) +
+                glob.glob(os.path.join(dir, '*.o')) )
+    for file in filelist:
+        path, file = os.path.split(file)
+        base, ext = os.path.splitext(file)
+        if base[-6:] == 'module':
+            base = base[:-6]
+        modules[base.lower()] = base
+
+# Minor oddity: the types module is documented in libtypes2.tex
+if modules.has_key('types'):
+    del modules['types']
+    modules['types2'] = None
+
+# Phase II: find all documentation files (lib*.tex)
+#           and eliminate modules that don't have one.
+
+docs = {}
+filelist = glob.glob('lib*.tex')
+for file in filelist:
+    modname = file[3:-4]
+    docs[modname] = modname
+
+mlist = modules.keys()
+mlist = filter(lambda x, docs=docs: docs.has_key(x), mlist)
+mlist.sort()
+mlist = map(lambda x, docs=docs: docs[x], mlist)
+
+modules = mlist
+
+# Phase III: write custlib.tex
+
+# Write the boilerplate
+# XXX should be fancied up.
+print """\documentstyle[twoside,11pt,myformat]{report}
+\\title{Python Library Reference}
+\\input{boilerplate}
+\\makeindex                     % tell \\index to actually write the .idx file
+\\begin{document}
+\\pagenumbering{roman}
+\\maketitle
+\\input{copyright}
+\\begin{abstract}
+\\noindent This is a customized version of the Python Library Reference.
+\\end{abstract}
+\\pagebreak
+{\\parskip = 0mm \\tableofcontents}
+\\pagebreak\\pagenumbering{arabic}"""
+
+for modname in mlist:
+    print "\\input{lib%s}" % (modname,)
+
+# Write the end
+print """\\input{custlib.ind}                   % Index
+\\end{document}"""

Added: vendor/Python/current/Doc/tools/findcsyms
===================================================================
--- vendor/Python/current/Doc/tools/findcsyms	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/tools/findcsyms	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,136 @@
+#! /usr/bin/env python
+
+import errno
+import os
+import re
+import sys
+
+if __name__ == "__main__":
+    _base = sys.argv[0]
+else:
+    _base = __file__
+
+_script_home = os.path.abspath(os.path.dirname(_base))
+
+srcdir = os.path.dirname(os.path.dirname(_script_home))
+
+EXCLUDES = ["bitset.h", "cStringIO.h", "graminit.h", "grammar.h",
+            "longintrepr.h", "metagrammar.h",
+            "node.h", "opcode.h", "osdefs.h", "pgenheaders.h",
+            "py_curses.h", "parsetok.h", "symtable.h", "token.h"]
+
+
+def list_headers():
+    """Return a list of headers."""
+    incdir = os.path.join(srcdir, "Include")
+    return [fn for fn in os.listdir(incdir)
+            if fn.endswith(".h") and fn not in EXCLUDES]
+
+
+def matcher(pattern):
+    return re.compile(pattern).match
+
+MATCHERS = [
+    matcher(r"\\begin\{cfuncdesc\}\{[^{]*\}\{(?P<sym>[^{]*)\}"),
+    matcher(r"\\cfuncline\{[^{]*\}\{(?P<sym>[^{]*)\}"),
+    matcher(r"\\begin\{ctypedesc\}(\[[^{]*\])?\{(?P<sym>[^{]*)\}"),
+    matcher(r"\\begin\{cvardesc\}\{[^{]*\}\{(?P<sym>[^{]*)\}"),
+    matcher(r"\\begin\{cmemberdesc\}\{[^{]*\}\{(?P<sym>[^{]*)\}"),
+    matcher(r"\\cmemberline\{[^{]*\}\{(?P<sym>[^{]*)\}"),
+    matcher(r"\\begin\{csimplemacrodesc\}\{(?P<sym>[^{]*)\}"),
+    ]
+
+
+def list_documented_items():
+    """Return a list of everything that's already documented."""
+    apidir = os.path.join(srcdir, "Doc", "api")
+    files = [fn for fn in os.listdir(apidir) if fn.endswith(".tex")]
+    L = []
+    for fn in files:
+        fullname = os.path.join(apidir, fn)
+        for line in open(fullname):
+            line = line.lstrip()
+            if not line.startswith("\\"):
+                continue
+            for matcher in MATCHERS:
+                m = matcher(line)
+                if m:
+                    L.append(m.group("sym"))
+                    break
+    return L
+
+def split_documented(all, documented):
+    """Split the list of all symbols into documented and undocumented
+    categories."""
+    doc = []
+    undoc = []
+    for t in all:
+        if t[0] in documented:
+            doc.append(t)
+        else:
+            undoc.append(t)
+    return doc, undoc
+
+def print_list(L, title=None):
+    """Dump a list to stdout."""
+    if title:
+        print title + ":"
+        print "-" * (len(title) + 1)
+    w = 0
+    for sym, filename in L:
+        w = max(w, len(sym))
+    if w % 4 == 0:
+        w += 4
+    else:
+        w += (4 - (w % 4))
+    for sym, filename in L:
+        print "%-*s%s" % (w, sym, filename)
+
+
+_spcjoin = ' '.join
+
+def main():
+    args = sys.argv[1:]
+    if args:
+        headers = args
+        documented = []
+    else:
+        os.chdir(os.path.join(srcdir, "Include"))
+        headers = list_headers()
+        documented = list_documented_items()
+
+    cmd = ("ctags -f - --file-scope=no --c-types=dgpstux "
+           "-Istaticforward -Istatichere=static "
+           + _spcjoin(headers))
+    fp = os.popen(cmd)
+    L = []
+    prevsym = None
+    while 1:
+        line = fp.readline()
+        if not line:
+            break
+        sym, filename = line.split()[:2]
+        if sym == prevsym:
+            continue
+        if not sym.endswith("_H"):
+            L.append((sym, filename))
+            prevsym = sym
+    L.sort()
+    fp.close()
+
+    try:
+        if documented:
+            documented, undocumented = split_documented(L, documented)
+            print_list(documented, "Documented symbols")
+            if undocumented:
+                print
+                print_list(undocumented, "Undocumented symbols")
+        else:
+            print_list(L)
+    except IOError, e:
+        if e.errno != errno.EPIPE:
+            raise
+
+
+if __name__ == "__main__":
+    main()


Property changes on: vendor/Python/current/Doc/tools/findcsyms
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Doc/tools/findmodrefs
===================================================================
--- vendor/Python/current/Doc/tools/findmodrefs	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/tools/findmodrefs	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,63 @@
+#! /usr/bin/env python
+#  -*- Python -*-
+
+import fileinput
+import getopt
+import glob
+import os
+import re
+import sys
+
+
+declare_rx = re.compile(
+    r"\\declaremodule(?:\[[a-zA-Z0-9]*\]*)?{[a-zA-Z_0-9]+}{([a-zA-Z_0-9]+)}")
+
+module_rx = re.compile(r"\\module{([a-zA-Z_0-9]+)}")
+
+def main():
+    try:
+        just_list = 0
+        print_lineno = 0
+        opts, args = getopt.getopt(sys.argv[1:], "ln", ["list", "number"])
+        for opt, arg in opts:
+            if opt in ("-l", "--list"):
+                just_list = 1
+            elif opt in ("-n", "--number"):
+                print_lineno = 1
+        files = args
+        if not files:
+            files = glob.glob("*.tex")
+            files.sort()
+        modulename = None
+        for line in fileinput.input(files):
+            if line[:9] == r"\section{":
+                modulename = None
+                continue
+            if line[:16] == r"\modulesynopsys{":
+                continue
+            m = declare_rx.match(line)
+            if m:
+                modulename = m.group(1)
+                continue
+            if not modulename:
+                continue
+            m = module_rx.search(line)
+            if m:
+                name = m.group(1)
+                if name != modulename:
+                    filename = fileinput.filename()
+                    if just_list:
+                        print filename
+                        fileinput.nextfile()
+                        modulename = None
+                    elif print_lineno:
+                        print "%s(%d):%s" \
+                              % (filename, fileinput.filelineno(), line[:-1])
+                    else:
+                        print "%s:%s" % (filename, line[:-1])
+    except KeyboardInterrupt:
+        sys.exit(1)
+
+
+if __name__ == "__main__":
+    main()


Property changes on: vendor/Python/current/Doc/tools/findmodrefs
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Doc/tools/findsyms
===================================================================
--- vendor/Python/current/Doc/tools/findsyms	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/tools/findsyms	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,128 @@
+#!/usr/bin/env python
+
+# Released to the public domain by Skip Montanaro, 28 March 2002
+
+"""
+findsyms.py - try to identify undocumented symbols exported by modules
+
+Usage:    findsyms.py librefdir
+
+For each lib*.tex file in the libref manual source directory, identify which
+module is documented, import the module if possible, then search the LaTeX
+source for the symbols global to that module.  Report any that don't seem to
+be documented.
+
+Certain exceptions are made to the list of undocumented symbols:
+
+    * don't mention symbols in which all letters are upper case on the
+      assumption they are manifest constants
+
+    * don't mention symbols that are themselves modules
+
+    * don't mention symbols that match those exported by os, math, string,
+      types, or __builtin__ modules
+
+Finally, if a name is exported by the module but fails a getattr() lookup,
+that anomaly is reported.
+"""
+
+import __builtin__
+import getopt
+import glob
+import math
+import os
+import re
+import string
+import sys
+import types
+import warnings
+
+def usage():
+    print >> sys.stderr, """
+usage: %s dir
+where 'dir' is the Library Reference Manual source directory.
+""" % os.path.basename(sys.argv[0])
+    
+def main():
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], "")
+    except getopt.error:
+        usage()
+        return
+
+    if not args:
+        usage()
+        return
+
+    libdir = args[0]
+    
+    warnings.filterwarnings("error")
+
+    pat = re.compile(r"\\declaremodule\s*{[^}]*}\s*{([^}]*)}")
+
+    missing = []
+    filelist = glob.glob(os.path.join(libdir, "lib*.tex"))
+    filelist.sort()
+    for f in filelist:
+        mod = f[3:-4]
+        if not mod: continue
+        data = open(f).read()
+        mods = re.findall(pat, data)
+        if not mods:
+            print "No module declarations found in", f
+            continue
+        for modname in mods:
+            # skip special modules
+            if modname.startswith("__"):
+                continue
+            try:
+                mod = __import__(modname)
+            except ImportError:
+                missing.append(modname)
+                continue
+            except DeprecationWarning:
+                print "Deprecated module:", modname
+                continue
+            if hasattr(mod, "__all__"):
+                all = mod.__all__
+            else:
+                all = [k for k in dir(mod) if k[0] != "_"]
+            mentioned = 0
+            all.sort()
+            for name in all:
+                if data.find(name) == -1:
+                    # certain names are predominantly used for testing
+                    if name in ("main","test","_test"):
+                        continue
+                    # is it some sort of manifest constant?
+                    if name.upper() == name:
+                        continue
+                    try:
+                        item = getattr(mod, name)
+                    except AttributeError:
+                        print "  ", name, "exposed, but not an attribute"
+                        continue
+                    # don't care about modules that might be exposed
+                    if type(item) == types.ModuleType:
+                        continue
+                    # check a few modules which tend to be import *'d
+                    isglobal = 0
+                    for m in (os, math, string, __builtin__, types):
+                        if hasattr(m, name) and item == getattr(m, name):
+                            isglobal = 1
+                            break
+                    if isglobal: continue
+                    if not mentioned:
+                        print "Not mentioned in", modname, "docs:"
+                        mentioned = 1
+                    print "  ", name
+    if missing:
+        missing.sort()
+        print "Could not import:"
+        print "  ", ", ".join(missing)
+
+if __name__ == "__main__":
+    try:
+        main()
+    except KeyboardInterrupt:
+        pass


Property changes on: vendor/Python/current/Doc/tools/findsyms
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Doc/tools/fix_hack
===================================================================
--- vendor/Python/current/Doc/tools/fix_hack	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/tools/fix_hack	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2 @@
+#!/bin/sh
+sed -e 's/{\\ptt[ 	]*\\char[ 	]*'"'"'137}/_/g' <"$1" > "@$1" && mv "@$1" $1


Property changes on: vendor/Python/current/Doc/tools/fix_hack
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Doc/tools/fix_libaux.sed
===================================================================
--- vendor/Python/current/Doc/tools/fix_libaux.sed	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/tools/fix_libaux.sed	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,3 @@
+#! /bin/sed -f
+s/{\\tt  \\hackscore  {}\\hackscore  {}/\\sectcode{__/
+s/\\hackscore  {}\\hackscore  {}/__/


Property changes on: vendor/Python/current/Doc/tools/fix_libaux.sed
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Doc/tools/fixinfo.el
===================================================================
--- vendor/Python/current/Doc/tools/fixinfo.el	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/tools/fixinfo.el	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,15 @@
+(defun fix-python-texinfo ()
+  (goto-char (point-min))
+  (replace-regexp "\\(@setfilename \\)\\([-a-z]*\\)$"
+		  "\\1python-\\2.info")
+  (replace-string "@node Front Matter\n at chapter Abstract\n"
+		  "@node Abstract\n at section Abstract\n")
+  (mark-whole-buffer)
+  (texinfo-master-menu 'update-all-nodes)
+  (save-buffer)
+  )	;; fix-python-texinfo
+
+;; now really do it:
+(find-file (car command-line-args-left))
+(fix-python-texinfo)
+(kill-emacs)

Added: vendor/Python/current/Doc/tools/getpagecounts
===================================================================
--- vendor/Python/current/Doc/tools/getpagecounts	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/tools/getpagecounts	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,97 @@
+#! /usr/bin/env python
+
+"""Generate a page count report of the PostScript version of the manuals."""
+
+__version__ = '$Revision: 39598 $'
+
+import getopt
+import sys
+
+
+class PageCounter:
+    def __init__(self):
+        self.doclist = []
+        self.total = 0
+        self.title_width = 0
+        self.version = ""
+
+    def add_document(self, prefix, title):
+        count = count_pages(prefix + ".ps")
+        self.doclist.append((title, prefix, count))
+        self.title_width = max(self.title_width, len(title))
+        self.total = self.total + count
+
+    def dump(self):
+        fmt = "%%-%ds  (%%s.ps, %%d pages)" % self.title_width
+        for item in self.doclist:
+            print fmt % item
+        print
+        print "  Total page count:  %d" % self.total
+
+    def parse_options(self):
+        opts, args = getopt.getopt(sys.argv[1:], "r:", ["release="])
+        assert not args
+        for opt, arg in opts:
+            if opt in ("-r", "--release"):
+                self.version = arg
+
+    def run(self):
+        self.parse_options()
+        if self.version:
+            version = self.version[:3]
+            self.add_document("whatsnew" + version.replace(".", ""),
+                              "What's New in Python " + version)
+        for prefix, title in [
+            ("api", "Python/C API"),
+            ("ext", "Extending and Embedding the Python Interpreter"),
+            ("lib", "Python Library Reference"),
+            ("mac", "Macintosh Module Reference"),
+            ("ref", "Python Reference Manual"),
+            ("tut", "Python Tutorial"),
+            ("doc", "Documenting Python"),
+            ("inst", "Installing Python Modules"),
+            ("dist", "Distributing Python Modules"),
+            ]:
+            self.add_document(prefix, title)
+        print self.PREFIX
+        self.dump()
+        print self.SUFFIX
+
+    PREFIX = """\
+This is the PostScript version of the standard Python documentation.
+If you plan to print this, be aware that some of the documents are
+long.  It is formatted for printing on two-sided paper; if you do plan
+to print this, *please* print two-sided if you have a printer capable
+of it!  To locate published copies of the larger manuals, or other
+Python reference material, consult the Python Bookstore at:
+
+    http://wiki.python.org/moin/PythonBooks
+
+The following manuals are included in this package:
+"""
+    SUFFIX = """\
+
+
+If you have any questions, comments, or suggestions regarding these
+documents, please send them via email to docs at python.org.
+"""
+
+def count_pages(filename):
+    fp = open(filename)
+    count = 0
+    while 1:
+        lines = fp.readlines(1024*40)
+        if not lines:
+            break
+        for line in lines:
+            if line[:7] == "%%Page:":
+                count = count + 1
+    fp.close()
+    return count
+
+
+def main():
+    PageCounter().run()
+
+if __name__ == "__main__":
+    main()


Property changes on: vendor/Python/current/Doc/tools/getpagecounts
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Doc/tools/getversioninfo
===================================================================
--- vendor/Python/current/Doc/tools/getversioninfo	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/tools/getversioninfo	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,71 @@
+#! /usr/bin/env python
+
+import os
+import re
+import sys
+
+try:
+    __file__
+except NameError:
+    __file__ = sys.argv[0]
+
+tools = os.path.dirname(os.path.abspath(__file__))
+Doc = os.path.dirname(tools)
+src = os.path.dirname(Doc)
+patchlevel_h = os.path.join(src, "Include", "patchlevel.h")
+
+# This won't pick out all #defines, but it will pick up the ones we
+# care about.
+rx = re.compile(r"\s*#define\s+([a-zA-Z][a-zA-Z_0-9]*)\s+([a-zA-Z_0-9]+)")
+
+d = {}
+f = open(patchlevel_h)
+for line in f:
+    m = rx.match(line)
+    if m is not None:
+        name, value = m.group(1, 2)
+        d[name] = value
+f.close()
+
+release = "%s.%s" % (d["PY_MAJOR_VERSION"], d["PY_MINOR_VERSION"])
+micro = int(d["PY_MICRO_VERSION"])
+shortversion = release
+if micro != 0:
+    release += "." + str(micro)
+level = d["PY_RELEASE_LEVEL"]
+
+suffixes = {
+    "PY_RELEASE_LEVEL_ALPHA": "a",
+    "PY_RELEASE_LEVEL_BETA":  "b",
+    "PY_RELEASE_LEVEL_GAMMA": "c",
+    }
+
+releaseinfo = ""
+if level != "PY_RELEASE_LEVEL_FINAL":
+    releaseinfo = suffixes[level] + str(int(d["PY_RELEASE_SERIAL"]))
+
+def write_file(name, text):
+    """Write text to a file if the file doesn't exist or if text
+    differs from any existing content."""
+    if os.path.exists(name):
+        f = open(name, "r")
+        s = f.read()
+        f.close()
+        if s == text:
+            return
+    f = open(name, "w")
+    f.write(text)
+    f.close()
+
+patchlevel_tex = os.path.join(Doc, "commontex", "patchlevel.tex")
+
+write_file(patchlevel_tex,
+           "%% This file is generated by ../tools/getversioninfo;\n"
+           "%% do not edit manually.\n"
+           "\n"
+           "\\release{%s}\n"
+           "\\setreleaseinfo{%s}\n"
+           "\\setshortversion{%s}\n"
+           % (release, releaseinfo, shortversion))
+
+print release + releaseinfo


Property changes on: vendor/Python/current/Doc/tools/getversioninfo
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Doc/tools/html2texi.pl
===================================================================
--- vendor/Python/current/Doc/tools/html2texi.pl	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/tools/html2texi.pl	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1750 @@
+#! /usr/bin/env perl
+# html2texi.pl -- Convert HTML documentation to Texinfo format
+# Michael Ernst <mernst at cs.washington.edu>
+# Time-stamp: <1999-01-12 21:34:27 mernst>
+
+# This program converts HTML documentation trees into Texinfo format.
+# Given the name of a main (or contents) HTML file, it processes that file,
+# and other files (transitively) referenced by it, into a Texinfo file
+# (whose name is chosen from the file or directory name of the argument).
+# For instance:
+#   html2texi.pl api/index.html
+# produces file "api.texi".
+
+# Texinfo format can be easily converted to Info format (for browsing in
+# Emacs or the standalone Info browser), to a printed manual, or to HTML.
+# Thus, html2texi.pl permits conversion of HTML files to Info format, and
+# secondarily enables producing printed versions of Web page hierarchies.
+
+# Unlike HTML, Info format is searchable.  Since Info is integrated into
+# Emacs, one can read documentation without starting a separate Web
+# browser.  Additionally, Info browsers (including Emacs) contain
+# convenient features missing from Web browsers, such as easy index lookup
+# and mouse-free browsing.
+
+# Limitations:
+# html2texi.pl is currently tuned to latex2html output (and it corrects
+# several latex2html bugs), but should be extensible to arbitrary HTML
+# documents.  It will be most useful for HTML with a hierarchical structure
+# and an index, and it recognizes those features as created by latex2html
+# (and possibly by some other tools).  The HTML tree to be traversed must
+# be on local disk, rather than being accessed via HTTP.
+# This script requires the use of "checkargs.pm".  To eliminate that
+# dependence, replace calls to check_args* by @_ (which is always the last
+# argument to those functions).
+# Also see the "to do" section, below.
+# Comments, suggestions, bug fixes, and enhancements are welcome.
+
+# Troubleshooting:
+# Malformed HTML can cause this program to abort, so
+# you should check your HTML files to make sure they are legal.
+
+
+###
+### Typical usage for the Python documentation:
+###
+
+# (Actually, most of this is in a Makefile instead.)
+# The resulting Info format Python documentation is currently available at
+# ftp://ftp.cs.washington.edu/homes/mernst/python-info.tar.gz
+
+# Fix up HTML problems, eg <DT><DL COMPACT><DD> should be <DT><DL COMPACT><DD>.
+
+# html2texi.pl /homes/fish/mernst/tmp/python-doc/html/api/index.html
+# html2texi.pl /homes/fish/mernst/tmp/python-doc/html/ext/index.html
+# html2texi.pl /homes/fish/mernst/tmp/python-doc/html/lib/index.html
+# html2texi.pl /homes/fish/mernst/tmp/python-doc/html/mac/index.html
+# html2texi.pl /homes/fish/mernst/tmp/python-doc/html/ref/index.html
+# html2texi.pl /homes/fish/mernst/tmp/python-doc/html/tut/index.html
+
+# Edit the generated .texi files:
+#   * change @setfilename to prefix "python-"
+#   * fix up any sectioning, such as for Abstract
+#   * make Texinfo menus
+#   * perhaps remove the @detailmenu ... @end detailmenu
+# In Emacs, to do all this:
+#   (progn (goto-char (point-min)) (replace-regexp "\\(@setfilename \\)\\([-a-z]*\\)$" "\\1python-\\2.info") (replace-string "@node Front Matter\n at chapter Abstract\n" "@node Abstract\n at section Abstract\n") (progn (mark-whole-buffer) (texinfo-master-menu 'update-all-nodes)) (save-buffer))
+
+# makeinfo api.texi
+# makeinfo ext.texi
+# makeinfo lib.texi
+# makeinfo mac.texi
+# makeinfo ref.texi
+# makeinfo tut.texi
+
+
+###
+### Structure of the code
+###
+
+# To be written...
+
+
+###
+### Design decisions
+###
+
+# Source and destination languages
+# --------------------------------
+# 
+# The goal is Info files; I create Texinfo, so I don't have to worry about
+# the finer details of Info file creation.  (I'm not even sure of its exact
+# format.)
+# 
+# Why not start from LaTeX rather than HTML?
+# I could hack latex2html itself to produce Texinfo instead, or fix up
+# partparse.py (which already translates LaTeX to Teinfo).
+#  Pros:
+#   * has high-level information such as index entries, original formatting
+#  Cons:
+#   * those programs are complicated to read and understand
+#   * those programs try to handle arbitrary LaTeX input, track catcodes,
+#     and more:  I don't want to go to that effort.  HTML isn't as powerful
+#     as LaTeX, so there are fewer subtleties.
+#   * the result wouldn't work for arbitrary HTML documents; it would be
+#     nice to eventually extend this program to HTML produced from Docbook,
+#     Frame, and more.
+
+# Parsing
+# -------
+# 
+# I don't want to view the text as a linear stream; I'd rather parse the
+# whole thing and then do pattern matching over the parsed representation (to
+# find idioms such as indices, lists of child nodes, etc.).
+#  * Perl provides HTML::TreeBuilder, which does just what I want.
+#     * libwww-perl: http://www.linpro.no/lwp/
+#     * TreeBuilder: HTML-Tree-0.51.tar.gz
+#  * Python Parsers, Formatters, and Writers don't really provide the right
+#    interface (and the version in Grail doesn't correspond to another
+#    distributed version, so I'm confused about which to be using).  I could
+#    write something in Python that creates a parse tree, but why bother?
+
+# Other implementation language issues:
+#  * Python lacks variable declarations, reasonable scoping, and static
+#    checking tools.  I've written some of the latter for myself that make
+#    my Perl programming a lot safer than my Python programming will be until
+#    I have a similar suite for that language.
+
+
+###########################################################################
+### To do
+###
+
+# Section names:
+#   Fix the problem with multiple sections in a single file (eg, Abstract in
+#     Front Matter section).
+#   Deal with cross-references, as in /homes/fish/mernst/tmp/python-doc/html/ref/types.html:310
+# Index:
+#   Perhaps double-check that every tag mentioned in the index is found
+#     in the text.
+# Python:  email to docs at python.org, to get their feedback.
+#   Compare to existing lib/ Info manual
+#   Write the hooks into info-look; replace pyliblookup1-1.tar.gz.
+#   Postpass to remove extra quotation marks around typography already in
+#     a different font (to avoid double delimiters as in "`code'"); or
+#     perhaps consider using only font-based markup so that we don't get
+#     the extra *bold* and `code' markup in Info.
+
+## Perhaps don't rely on automatic means for adding up, next, prev; I have
+## all that info available to me already, so it's not so much trouble to
+## add it.  (Right?)  But it is *so* easy to use Emacs instead...
+
+
+###########################################################################
+### Strictures
+###
+
+# man HTML::TreeBuilder
+# man HTML::Parser
+# man HTML::Element
+
+# require HTML::ParserWComment;
+require HTML::Parser;
+require HTML::TreeBuilder;
+require HTML::Element;
+
+use File::Basename;
+
+use strict;
+# use Carp;
+
+use checkargs;
+
+
+###########################################################################
+### Variables
+###
+
+my @section_stack = ();		# elements are chapter/section/subsec nodetitles (I think)
+my $current_ref_tdf;		# for the file currently being processed;
+				#  used in error messages
+my $html_directory;
+my %footnotes;
+
+# First element should not be used.
+my @sectionmarker = ("manual", "chapter", "section", "subsection", "subsubsection");
+
+my %inline_markup = ("b" => "strong",
+		     "code" => "code",
+		     "i" => "emph",
+		     "kbd" => "kbd",
+		     "samp" => "samp",
+		     "strong" => "strong",
+		     "tt" => "code",
+		     "var" => "var");
+
+my @deferred_index_entries = ();
+
+my @index_titles = ();		# list of (filename, type) lists
+my %index_info = ("Index" => ["\@blindex", "bl"],
+		  "Concept Index" => ["\@cindex", "cp"],
+		  "Module Index" => ["\@mdindex", "md"]);
+
+
+###########################################################################
+### Main/contents page
+###
+
+# Process first-level page on its own, or just a contents page?  Well, I do
+# want the title, author, etc., and the front matter...  For now, just add
+# that by hand at the end.
+
+
+# data structure possibilities:
+#  * tree-like (need some kind of stack when processing (or parent pointers))
+#  * list of name and depth; remember old and new depths.
+
+# Each element is a reference to a list of (nodetitle, depth, filename).
+my @contents_list = ();
+
+# The problem with doing fixups on the fly is that some sections may have
+# already been processed (and no longer available) by the time we notice
+# others with the same name.  It's probably better to fully construct the
+# contents list (reading in all files of interest) upfront; that will also
+# let me do a better job with cross-references, because again, all files
+# will already be read in.
+my %contents_hash = ();
+my %contents_fixups = ();
+
+my @current_contents_list = ();
+
+# Merge @current_contents_list into @contents_list,
+# and set @current_contents_list to be empty.
+sub merge_contents_lists ( )
+{ check_args(0, @_);
+
+  # Three possibilities:
+  #  * @contents_list is empty: replace it by @current_contents_list.
+  #  * prefixes of the two lists are identical: do nothing
+  #  * @current_contents_list is all at lower level than $contents_list[0];
+  #    prefix @contents_list by @current_contents_list
+
+  if (scalar(@current_contents_list) == 0)
+    { die "empty current_contents_list"; }
+
+  #   if (scalar(@contents_list) == 0)
+  #     { @contents_list = @current_contents_list;
+  #       @current_contents_list = ();
+  #       return; }
+
+  #   if (($ {$contents_list[0]}[1]) < ($ {$current_contents_list[0]}[1]))
+  #     { unshift @contents_list, @current_contents_list;
+  #       @current_contents_list = ();
+  #       return; }
+
+  for (my $i=0; $i<scalar(@current_contents_list); $i++)
+    { my $ref_c_tdf = $current_contents_list[$i];
+      if ($i >= scalar(@contents_list))
+	{ push @contents_list, $ref_c_tdf;
+	  my $title = $ {$ref_c_tdf}[0];
+	  if (defined $contents_hash{$title})
+	    { $contents_fixups{$title} = 1; }
+	  else
+	    { $contents_hash{$title} = 1; }
+	  next; }
+      my $ref_tdf = $contents_list[$i];
+      my ($title, $depth, $file) = @{$ref_tdf};
+      my ($c_title, $c_depth, $c_file) = @{$ref_c_tdf};
+
+      if (($title ne $c_title)
+	  && ($depth < $c_depth)
+	  && ($file ne $c_file))
+	{ splice @contents_list, $i, 0, $ref_c_tdf;
+	  if (defined $contents_hash{$c_title})
+	    { $contents_fixups{$c_title} = 1; }
+	  else
+	    { $contents_hash{$c_title} = 1; }
+	  next; }
+
+      if (($title ne $c_title)
+	  || ($depth != $c_depth)
+	  || ($file ne $c_file))
+	{ die ("while processing $ {$current_ref_tdf}[2] at depth $ {$current_ref_tdf}[1], mismatch at index $i:",
+	       "\n  main:  <<<$title>>> $depth $file",
+	       "\n  curr:  <<<$c_title>>> $c_depth $c_file"); }
+    }
+  @current_contents_list = ();
+}
+
+
+
+# Set @current_contents_list to a list of (title, href, sectionlevel);
+#  then merge that list into @contents_list.
+# Maybe this function should also produce a map
+#  from title (or href) to sectionlevel (eg "chapter"?).
+sub process_child_links ( $ )
+{ my ($he) = check_args(1, @_);
+
+  # $he->dump();
+  if (scalar(@current_contents_list) != 0)
+    { die "current_contents_list nonempty: @current_contents_list"; }
+  $he->traverse(\&increment_current_contents_list, 'ignore text');
+
+  # Normalize the depths; for instance, convert 1,3,5 into 0,1,2.
+  my %depths = ();
+  for my $ref_tdf (@current_contents_list)
+    { $depths{$ {$ref_tdf}[1]} = 1; }
+  my @sorted_depths = sort keys %depths;
+  my $current_depth = scalar(@section_stack)-1;
+  my $current_depth_2 = $ {$current_ref_tdf}[1];
+  if ($current_depth != $current_depth_2)
+    { die "mismatch in current depths: $current_depth $current_depth_2; ", join(", ", @section_stack); }
+  for (my $i=0; $i<scalar(@sorted_depths); $i++)
+    { $depths{$sorted_depths[$i]} = $i + $current_depth+1; }
+  for my $ref_tdf (@current_contents_list)
+    { $ {$ref_tdf}[1] = $depths{$ {$ref_tdf}[1]}; }
+
+  # Eliminate uninteresting sections.  Hard-coded hack for now.
+  if ($ {$current_contents_list[-1]}[0] eq "About this document ...")
+    { pop @current_contents_list; }
+  if ((scalar(@current_contents_list) > 1)
+      && ($ {$current_contents_list[1]}[0] eq "Contents"))
+    { my $ref_first_tdf = shift @current_contents_list;
+      $current_contents_list[0] = $ref_first_tdf; }
+
+  for (my $i=0; $i<scalar(@current_contents_list); $i++)
+    { my $ref_tdf = $current_contents_list[$i];
+      my $title = $ {$ref_tdf}[0];
+      if (exists $index_info{$title})
+	{ my $index_file = $ {$ref_tdf}[2];
+	  my ($indexing_command, $suffix) = @{$index_info{$title}};
+	  process_index_file($index_file, $indexing_command);
+	  print TEXI "\n\@defindex $suffix\n";
+	  push @index_titles, $title;
+	  splice @current_contents_list, $i, 1;
+	  $i--; }
+      elsif ($title =~ /\bIndex$/)
+	{ print STDERR "Warning: \"$title\" might be an index; if so, edit \%index_info.\n"; } }
+
+  merge_contents_lists();
+
+  # print_contents_list();
+  # print_index_info();
+}
+
+
+sub increment_current_contents_list ( $$$ )
+{ my ($he, $startflag, $depth) = check_args(3, @_);
+  if (!$startflag)
+    { return; }
+
+  if ($he->tag eq "li")
+    { my @li_content = @{$he->content};
+      if ($li_content[0]->tag ne "a")
+	{ die "first element of <LI> should be <A>"; }
+      my ($name, $href, @content) = anchor_info($li_content[0]);
+      # unused $name
+      my $title = join("", collect_texts($li_content[0]));
+      $title = texi_remove_punctuation($title);
+      # The problem with these is that they are formatted differently in
+      # @menu and @node!
+      $title =~ s/``/\"/g;
+      $title =~ s/''/\"/g;
+      $title =~ s/ -- / /g;
+      push @current_contents_list, [ $title, $depth, $href ]; }
+  return 1;
+}
+
+# Simple version for section titles
+sub html_to_texi ( $ )
+{ my ($he) = check_args(1, @_);
+  if (!ref $he)
+    { return $he; }
+
+  my $tag = $he->tag;
+  if (exists $inline_markup{$tag})
+    { my $result = "\@$inline_markup{$tag}\{";
+      for my $elt (@{$he->content})
+	{ $result .= html_to_texi($elt); }
+      $result .= "\}";
+      return $result; }
+  else
+    { $he->dump();
+      die "html_to_texi confused by <$tag>"; }
+}
+
+
+
+sub print_contents_list ()
+{ check_args(0, @_);
+  print STDERR "Contents list:\n";
+  for my $ref_tdf (@contents_list)
+    { my ($title, $depth, $file) = @{$ref_tdf};
+      print STDERR "$title $depth $file\n"; }
+}
+
+
+
+###########################################################################
+### Index
+###
+
+my $l2h_broken_link_name = "l2h-";
+
+
+# map from file to (map from anchor name to (list of index texts))
+# (The list is needed when a single LaTeX command like \envvar
+# expands to multiple \index commands.)
+my %file_index_entries = ();
+my %this_index_entries;		# map from anchor name to (list of index texts)
+
+my %file_index_entries_broken = (); # map from file to (list of index texts)
+my @this_index_entries_broken;
+
+my $index_prefix = "";
+my @index_prefixes = ();
+
+my $this_indexing_command;
+
+sub print_index_info ()
+{ check_args(0, @_);
+  my ($key, $val);
+  for my $file (sort keys %file_index_entries)
+    { my %index_entries = %{$file_index_entries{$file}};
+      print STDERR "file: $file\n";
+      for my $aname (sort keys %index_entries)
+	{ my @entries = @{$index_entries{$aname}};
+	  if (scalar(@entries) == 1)
+	    { print STDERR "  $aname : $entries[0]\n"; }
+	  else
+	    { print STDERR "  $aname : ", join("\n     " . (" " x length($aname)), @entries), "\n"; } } }
+  for my $file (sort keys %file_index_entries_broken)
+    { my @entries = @{$file_index_entries_broken{$file}};
+      print STDERR "file: $file\n";
+      for my $entry (@entries)
+	{ print STDERR "  $entry\n"; }
+    }
+}
+
+
+sub process_index_file ( $$ )
+{ my ($file, $indexing_command) = check_args(2, @_);
+  # print "process_index_file $file $indexing_command\n";
+
+  my $he = file_to_tree($html_directory . $file);
+  # $he->dump();
+
+  $this_indexing_command = $indexing_command;
+  $he->traverse(\&process_if_index_dl_compact, 'ignore text');
+  undef $this_indexing_command;
+  # print "process_index_file done\n";
+}
+
+
+sub process_if_index_dl_compact ( $$$ )
+{ my ($he, $startflag) = (check_args(3, @_))[0,1]; #  ignore depth argument
+  if (!$startflag)
+    { return; }
+
+  if (($he->tag() eq "dl") && (defined $he->attr('compact')))
+    { process_index_dl_compact($he);
+      return 0; }
+  else
+    { return 1; }
+}
+
+
+# The elements of a <DL COMPACT> list from a LaTeX2HTML index:
+#  * a single space: text to be ignored
+#  * <DT> elements with an optional <DD> element following each one
+#    Two types of <DT> elements:
+#     * Followed by a <DD> element:  the <DT> contains a single
+#       string, and the <DD> contains a whitespace string to be ignored, a
+#       <DL COMPACT> to be recursively processed (with the <DT> string as a
+#       prefix), and a whitespace string to be ignored.
+#     * Not followed by a <DD> element:  contains a list of anchors
+#       and texts (ignore the texts, which are only whitespace and commas).
+#       Optionally contains a <DL COMPACT> to be recursively processed (with
+#       the <DT> string as a prefix)
+sub process_index_dl_compact ( $ )
+{ my ($h) = check_args(1, @_);
+  my @content = @{$h->content()};
+  for (my $i = 0; $i < scalar(@content); $i++)
+    { my $this_he = $content[$i];
+      if ($this_he->tag ne "dt")
+	{ $this_he->dump();
+	  die "Expected <DT> tag: " . $this_he->tag; }
+      if (($i < scalar(@content) - 1) && ($content[$i+1]->tag eq "dd"))
+	{ process_index_dt_and_dd($this_he, $content[$i+1]);
+	  $i++;	}
+      else
+	{ process_index_lone_dt($this_he); } } }
+
+
+
+# Argument is a <DT> element.  If it contains more than one anchor, then
+# the texts of all subsequent ones are "[Link]".  Example:
+#       <DT>
+#         <A HREF="embedding.html#l2h-201">
+#           "$PATH"
+#         ", "
+#         <A HREF="embedding.html#l2h-205">
+#           "[Link]"
+# Optionally contains a <DL COMPACT> as well.  Example:
+# <DT>
+#   <A HREF="types.html#l2h-616">
+#     "attribute"
+#   <DL COMPACT>
+#     <DT>
+#       <A HREF="assignment.html#l2h-3074">
+#         "assignment"
+#       ", "
+#       <A HREF="assignment.html#l2h-3099">
+#         "[Link]"
+#     <DT>
+#       <A HREF="types.html#l2h-">
+#         "assignment, class"
+
+sub process_index_lone_dt ( $ )
+{ my ($dt) = check_args(1, @_);
+  my @dtcontent = @{$dt->content()};
+  my $acontent;
+  my $acontent_suffix;
+  for my $a (@dtcontent)
+    { if ($a eq ", ")
+	{ next; }
+      if (!ref $a)
+	{ $dt->dump;
+	  die "Unexpected <DT> string element: $a"; }
+
+      if ($a->tag eq "dl")
+	{ push @index_prefixes, $index_prefix;
+	  if (!defined $acontent_suffix)
+	    { die "acontent_suffix not yet defined"; }
+	  $index_prefix .= $acontent_suffix . ", ";
+	  process_index_dl_compact($a);
+	  $index_prefix = pop(@index_prefixes);
+	  return; }
+
+      if ($a->tag ne "a")
+	{ $dt->dump;
+	  $a->dump;
+	  die "Expected anchor in lone <DT>"; }
+
+      my ($aname, $ahref, @acontent) = anchor_info($a);
+      # unused $aname
+      if (scalar(@acontent) != 1)
+	{ die "Expected just one content of <A> in <DT>: @acontent"; }
+      if (ref $acontent[0])
+	{ $acontent[0]->dump;
+	  die "Expected string content of <A> in <DT>: $acontent[0]"; }
+      if (!defined($acontent))
+	{ $acontent = $index_prefix . $acontent[0];
+	  $acontent_suffix = $acontent[0]; }
+      elsif (($acontent[0] ne "[Link]") && ($acontent ne ($index_prefix . $acontent[0])))
+	{ die "Differing content: <<<$acontent>>>, <<<$acontent[0]>>>"; }
+
+      if (!defined $ahref)
+	{ $dt->dump;
+	  die "no HREF in nachor in <DT>"; }
+      my ($ahref_file, $ahref_name) = split(/\#/, $ahref);
+      if (!defined $ahref_name)
+	{ # Reference to entire file
+	  $ahref_name = ""; }
+
+      if ($ahref_name eq $l2h_broken_link_name)
+	{ if (!exists $file_index_entries_broken{$ahref_file})
+	    { $file_index_entries_broken{$ahref_file} = []; }
+	  push @{$file_index_entries_broken{$ahref_file}}, "$this_indexing_command $acontent";
+	  next; }
+
+      if (!exists $file_index_entries{$ahref_file})
+	{ $file_index_entries{$ahref_file} = {}; }
+      # Don't do this!  It appears to make a copy, which is not desired.
+      # my %index_entries = %{$file_index_entries{$ahref_file}};
+      if (!exists $ {$file_index_entries{$ahref_file}}{$ahref_name})
+	{ $ {$file_index_entries{$ahref_file}}{$ahref_name} = []; }
+      # 	{ my $oldcontent = $ {$file_index_entries{$ahref_file}}{$ahref_name};
+      # 	  if ($acontent eq $oldcontent)
+      # 	    { die "Multiple identical index entries?"; }
+      # 	  die "Trying to add $acontent, but already have index entry pointing at $ahref_file\#$ahref_name: ${$file_index_entries{$ahref_file}}{$ahref_name}"; }
+
+      push @{$ {$file_index_entries{$ahref_file}}{$ahref_name}}, "$this_indexing_command $acontent";
+      # print STDERR "keys: ", keys %{$file_index_entries{$ahref_file}}, "\n";
+    }
+}
+
+sub process_index_dt_and_dd ( $$ )
+{ my ($dt, $dd) = check_args(2, @_);
+  my $dtcontent;
+  { my @dtcontent = @{$dt->content()};
+    if ((scalar(@dtcontent) != 1) || (ref $dtcontent[0]))
+      { $dd->dump;
+	$dt->dump;
+	die "Expected single string (actual size = " . scalar(@dtcontent) . ") in content of <DT>: @dtcontent"; }
+    $dtcontent = $dtcontent[0];
+    $dtcontent =~ s/ +$//; }
+  my $ddcontent;
+  { my @ddcontent = @{$dd->content()};
+    if (scalar(@ddcontent) != 1)
+      { die "Expected single <DD> content, got ", scalar(@ddcontent), " elements:\n", join("\n", @ddcontent), "\n "; }
+    $ddcontent = $ddcontent[0]; }
+  if ($ddcontent->tag ne "dl")
+    { die "Expected <DL> as content of <DD>, but saw: $ddcontent"; }
+
+  push @index_prefixes, $index_prefix;
+  $index_prefix .= $dtcontent . ", ";
+  process_index_dl_compact($ddcontent);
+  $index_prefix = pop(@index_prefixes);
+}
+
+
+###########################################################################
+### Ordinary sections
+###
+
+sub process_section_file ( $$$ )
+{ my ($file, $depth, $nodetitle) = check_args(3, @_);
+  my $he = file_to_tree(($file =~ /^\//) ? $file : $html_directory . $file);
+
+  # print STDERR "process_section_file: $file $depth $nodetitle\n";
+
+  # Equivalently:
+  #   while ($depth >= scalar(@section_stack)) { pop(@section_stack); }
+  @section_stack = @section_stack[0..$depth-1];
+
+  # Not a great nodename fixup scheme; need a more global view
+  if ((defined $contents_fixups{$nodetitle})
+      && (scalar(@section_stack) > 0))
+    { my $up_title = $section_stack[$#section_stack];
+      # hack for Python Standard Library
+      $up_title =~ s/^(Built-in|Standard) Module //g;
+      my ($up_first_word) = split(/ /, $up_title);
+      $nodetitle = "$up_first_word $nodetitle";
+    }
+
+  push @section_stack, $nodetitle;
+  # print STDERR "new section_stack: ", join(", ", @section_stack), "\n";
+
+  $he->traverse(\&process_if_child_links, 'ignore text');
+  %footnotes = ();
+  # $he->dump;
+  $he->traverse(\&process_if_footnotes, 'ignore text');
+
+  # $he->dump;
+
+  if (exists $file_index_entries{$file})
+    { %this_index_entries = %{$file_index_entries{$file}};
+      # print STDERR "this_index_entries:\n ", join("\n ", keys %this_index_entries), "\n";
+    }
+  else
+    { # print STDERR "Warning: no index entries for file $file\n";
+      %this_index_entries = (); }
+
+  if (exists $file_index_entries_broken{$file})
+    { @this_index_entries_broken = @{$file_index_entries_broken{$file}}; }
+  else
+    { # print STDERR "Warning: no index entries for file $file\n";
+      @this_index_entries_broken = (); }
+
+
+  if ($he->tag() ne "html")
+    { die "Expected <HTML> at top level"; }
+  my @content = @{$he->content()};
+  if ((!ref $content[0]) or ($content[0]->tag ne "head"))
+    { $he->dump;
+      die "<HEAD> not first element of <HTML>"; }
+  if ((!ref $content[1]) or ($content[1]->tag ne "body"))
+    { $he->dump;
+      die "<BODY> not second element of <HTML>"; }
+
+  $content[1]->traverse(\&output_body);
+}
+
+# stack of things we're inside that are preventing indexing from occurring now.
+# These are "h1", "h2", "h3", "h4", "h5", "h6", "dt" (and possibly others?)
+my @index_deferrers = ();
+
+sub push_or_pop_index_deferrers ( $$ )
+{ my ($tag, $startflag) = check_args(2, @_);
+  if ($startflag)
+    { push @index_deferrers, $tag; }
+  else
+    { my $old_deferrer = pop @index_deferrers;
+      if ($tag ne $old_deferrer)
+	{ die "Expected $tag at top of index_deferrers but saw $old_deferrer; remainder = ", join(" ", @index_deferrers); }
+      do_deferred_index_entries(); }
+}
+
+
+sub label_add_index_entries ( $;$ )
+{ my ($label, $he) = check_args_range(1, 2, @_);
+  # print ((exists $this_index_entries{$label}) ? "*" : " "), " label_add_index_entries $label\n";
+  # $he is the anchor element
+  if (exists $this_index_entries{$label})
+    { push @deferred_index_entries, @{$this_index_entries{$label}};
+      return; }
+
+  if ($label eq $l2h_broken_link_name)
+    { # Try to find some text to use in guessing which links should point here
+      # I should probably only look at the previous element, or if that is
+      # all punctuation, the one before it; collecting all the previous texts
+      # is a bit of overkill.
+      my @anchor_texts = collect_texts($he);
+      my @previous_texts = collect_texts($he->parent, $he);
+      # 4 elements is arbitrary; ought to filter out punctuation and small words
+      # first, then perhaps keep fewer.  Perhaps also filter out formatting so
+      # that we can see a larger chunk of text?  (Probably not.)
+      # Also perhaps should do further chunking into words, in case the
+      # index term isn't a chunk of its own (eg, was in <tt>...</tt>.
+      my @candidate_texts = (@anchor_texts, (reverse(@previous_texts))[0..min(3,$#previous_texts)]);
+
+      my $guessed = 0;
+      for my $text (@candidate_texts)
+	{ # my $orig_text = $text;
+	  if ($text =~ /^[\"\`\'().?! ]*$/)
+	    { next; }
+	  if (length($text) <= 2)
+	    { next; }
+	  # hack for Python manual; maybe defer until failure first time around?
+	  $text =~ s/^sys\.//g;
+	  for my $iterm (@this_index_entries_broken)
+	    { # I could test for zero:  LaTeX2HTML's failures in the Python
+	      # documentation are only for items of the form "... (built-in...)"
+	      if (index($iterm, $text) != -1)
+		{ push @deferred_index_entries, $iterm;
+		  # print STDERR "Guessing index term `$iterm' for text `$orig_text'\n";
+		  $guessed = 1;
+		} } }
+      if (!$guessed)
+	{ # print STDERR "No guess in `", join("'; `", @this_index_entries_broken), "' for texts:\n `", join("'\n `", @candidate_texts), "'\n";
+	}
+    }
+}
+
+
+# Need to add calls to this at various places.
+# Perhaps add HTML::Element argument and do the check for appropriateness
+# here (ie, no action if inside <H1>, etc.).
+sub do_deferred_index_entries ()
+{ check_args(0, @_);
+  if ((scalar(@deferred_index_entries) > 0)
+      && (scalar(@index_deferrers) == 0))
+    { print TEXI "\n", join("\n", @deferred_index_entries), "\n";
+      @deferred_index_entries = (); }
+}
+
+my $table_columns;		# undefined if not in a table
+my $table_first_column;		# boolean
+
+sub output_body ( $$$ )
+{ my ($he, $startflag) = (check_args(3, @_))[0,1]; #  ignore depth argument
+
+  if (!ref $he)
+    { my $space_index = index($he, " ");
+      if ($space_index != -1)
+	{ # Why does
+	  #   print TEXI texi_quote(substr($he, 0, $space_index+1));
+	  # give:  Can't locate object method "TEXI" via package "texi_quote"
+	  # (Because the definition texi_quote hasn't been seen yet.)
+	  print TEXI &texi_quote(substr($he, 0, $space_index+1));
+	  do_deferred_index_entries();
+	  print TEXI &texi_quote(substr($he, $space_index+1)); }
+      else
+	{ print TEXI &texi_quote($he); }
+      return; }
+
+  my $tag = $he->tag();
+
+  # Ordinary text markup first
+  if (exists $inline_markup{$tag})
+    { if ($startflag)
+	{ print TEXI "\@$inline_markup{$tag}\{"; }
+      else
+	{ print TEXI "\}"; } }
+  elsif ($tag eq "a")
+    { my ($name, $href, @content) = anchor_info($he);
+      if (!$href)
+	{ # This anchor is only here for indexing/cross referencing purposes.
+	  if ($startflag)
+	    { label_add_index_entries($name, $he); }
+	}
+      elsif ($href =~ "^(ftp|http|news):")
+	{ if ($startflag)
+	    { # Should avoid second argument if it's identical to the URL.
+	      print TEXI "\@uref\{$href, "; }
+	  else
+	    { print TEXI "\}"; }
+	}
+      elsif ($href =~ /^\#(foot[0-9]+)$/)
+	{ # Footnote
+	  if ($startflag)
+	    { # Could double-check name and content, but I'm not
+	      # currently storing that information.
+	      print TEXI "\@footnote\{";
+	      $footnotes{$1}->traverse(\&output_body);
+	      print TEXI "\}";
+	      return 0; } }
+      else
+	{ if ($startflag)
+	    { # cross-references are not active Info links, but no text is lost
+	      print STDERR "Can't deal with internal HREF anchors yet:\n";
+	      $he->dump; }
+	}
+    }
+  elsif ($tag eq "br")
+    { print TEXI "\@\n"; }
+  elsif ($tag eq "body")
+    { }
+  elsif ($tag eq "center")
+    { if (has_single_content_string($he)
+	  && ($ {$he->content}[0] =~ /^ *$/))
+	{ return 0; }
+      if ($startflag)
+	{ print TEXI "\n\@center\n"; }
+      else
+	{ print TEXI "\n\@end center\n"; }
+    }
+  elsif ($tag eq "div")
+    { my $align = $he->attr('align');
+      if (defined($align) && ($align eq "center"))
+	{ if (has_single_content_string($he)
+	      && ($ {$he->content}[0] =~ /^ *$/))
+	    { return 0; }
+	  if ($startflag)
+	    { print TEXI "\n\@center\n"; }
+	  else
+	    { print TEXI "\n\@end center\n"; } }
+    }
+  elsif ($tag eq "dl")
+    { # Recognize "<dl><dd><pre> ... </pre></dl>" paradigm for "@example"
+      if (has_single_content_with_tag($he, "dd"))
+	{ my $he_dd = $ {$he->content}[0];
+	  if (has_single_content_with_tag($he_dd, "pre"))
+	    { my $he_pre = $ {$he_dd->content}[0];
+	      print_pre($he_pre);
+	      return 0; } }
+      if ($startflag)
+	{ # Could examine the elements, to be cleverer about formatting.
+	  # (Also to use ftable, vtable...)
+	  print TEXI "\n\@table \@asis\n"; }
+      else
+	{ print TEXI "\n\@end table\n"; }
+    }
+  elsif ($tag eq "dt")
+    { push_or_pop_index_deferrers($tag, $startflag);
+      if ($startflag)
+	{ print TEXI "\n\@item "; }
+      else
+	{ } }
+  elsif ($tag eq "dd")
+    { if ($startflag)
+	{ print TEXI "\n"; }
+      else
+	{ }
+      if (scalar(@index_deferrers) != 0)
+	{ $he->dump;
+	  die "Unexpected <$tag> while inside: (" . join(" ", @index_deferrers) . "); bad HTML?"; }
+      do_deferred_index_entries();
+    }
+  elsif ($tag =~ /^(font|big|small)$/)
+    { # Do nothing for now.
+    }
+  elsif ($tag =~ /^h[1-6]$/)
+    { # We don't need this because we never recursively enter the heading content.
+      # push_or_pop_index_deferrers($tag, $startflag);
+      my $secname = "";
+      my @seclabels = ();
+      for my $elt (@{$he->content})
+	{ if (!ref $elt)
+	    { $secname .= $elt; }
+	  elsif ($elt->tag eq "br")
+	    { }
+	  elsif ($elt->tag eq "a")
+	    { my ($name, $href, @acontent) = anchor_info($elt);
+              if ($href)
+                { $he->dump;
+                  $elt->dump;
+                  die "Nonsimple anchor in <$tag>"; }
+	      if (!defined $name)
+		{ die "No NAME for anchor in $tag"; }
+	      push @seclabels, $name;
+	      for my $subelt (@acontent)
+		{ $secname .= html_to_texi($subelt); } }
+	  else
+	    { $secname .= html_to_texi($elt); } }
+      if ($secname eq "")
+	{ die "No section name in <$tag>"; }
+      if (scalar(@section_stack) == 1)
+	{ if ($section_stack[-1] ne "Top")
+	    { die "Not top? $section_stack[-1]"; }
+	  print TEXI "\@settitle $secname\n";
+	  print TEXI "\@c %**end of header\n";
+	  print TEXI "\n";
+	  print TEXI "\@node Top\n";
+	  print TEXI "\n"; }
+      else
+	{ print TEXI "\n\@node $section_stack[-1]\n";
+	  print TEXI "\@$sectionmarker[scalar(@section_stack)-1] ", texi_remove_punctuation($secname), "\n"; }
+      for my $seclabel (@seclabels)
+	{ label_add_index_entries($seclabel); }
+      # This should only happen once per file.
+      label_add_index_entries("");
+      if (scalar(@index_deferrers) != 0)
+	{ $he->dump;
+	  die "Unexpected <$tag> while inside: (" . join(" ", @index_deferrers) . "); bad HTML?"; }
+      do_deferred_index_entries();
+      return 0;
+    }
+  elsif ($tag eq "hr")
+    { }
+  elsif ($tag eq "ignore")
+    { # Hack for ignored elements
+      return 0;
+    }
+  elsif ($tag eq "li")
+    { if ($startflag)
+	{ print TEXI "\n\n\@item\n";
+	  do_deferred_index_entries(); } }
+  elsif ($tag eq "ol")
+    { if ($startflag)
+	{ print TEXI "\n\@enumerate \@bullet\n"; }
+      else
+	{ print TEXI "\n\@end enumerate\n"; } }
+  elsif ($tag eq "p")
+    { if ($startflag)
+	{ print TEXI "\n\n"; }
+      if (scalar(@index_deferrers) != 0)
+	{ $he->dump;
+	  die "Unexpected <$tag> while inside: (" . join(" ", @index_deferrers) . "); bad HTML?"; }
+      do_deferred_index_entries(); }
+  elsif ($tag eq "pre")
+    { print_pre($he);
+      return 0; }
+  elsif ($tag eq "table")
+    { # Could also indicate common formatting for first column, or
+      # determine relative widths for columns (or determine a prototype row)
+      if ($startflag)
+	{ if (defined $table_columns)
+	    { $he->dump;
+	      die "Can't deal with table nested inside $table_columns-column table"; }
+	  $table_columns = table_columns($he);
+	  if ($table_columns < 2)
+	    { $he->dump;
+	      die "Column with $table_columns columns?"; }
+	  elsif ($table_columns == 2)
+	    { print TEXI "\n\@table \@asis\n"; }
+	  else
+	    { print TEXI "\n\@multitable \@columnfractions";
+	      for (my $i=0; $i<$table_columns; $i++)
+		{ print TEXI " ", 1.0/$table_columns; }
+	      print TEXI "\n"; } }
+      else
+	{ if ($table_columns == 2)
+	    { print TEXI "\n\@end table\n"; }
+	  else
+	    { print TEXI "\n\@end multitable\n"; }
+	  undef $table_columns; } }
+  elsif (($tag eq "td") || ($tag eq "th"))
+    { if ($startflag)
+	{ if ($table_first_column)
+	    { print TEXI "\n\@item ";
+	      $table_first_column = 0; }
+	  elsif ($table_columns > 2)
+	    { print TEXI "\n\@tab "; } }
+      else
+	{ print TEXI "\n"; } }
+  elsif ($tag eq "tr")
+    { if ($startflag)
+	{ $table_first_column = 1; } }
+  elsif ($tag eq "ul")
+    { if ($startflag)
+	{ print TEXI "\n\@itemize \@bullet\n"; }
+      else
+	{ print TEXI "\n\@end itemize\n"; } }
+  else
+    { # I used to have a newline before "output_body" here.
+      print STDERR "output_body: ignoring <$tag> tag\n";
+      $he->dump;
+      return 0; }
+
+  return 1;
+}
+
+sub print_pre ( $ )
+{ my ($he_pre) = check_args(1, @_);
+  if (!has_single_content_string($he_pre))
+    { die "Multiple or non-string content for <PRE>: ", @{$he_pre->content}; }
+  my $pre_content = $ {$he_pre->content}[0];
+  print TEXI "\n\@example";
+  print TEXI &texi_quote($pre_content);
+  print TEXI "\@end example\n";
+}
+
+sub table_columns ( $ )
+{ my ($table) = check_args(1, @_);
+  my $result = 0;
+  for my $row (@{$table->content})
+    { if ($row->tag ne "tr")
+	{ $table->dump;
+	  $row->dump;
+	  die "Expected <TR> as table row."; }
+      $result = max($result, scalar(@{$row->content})); }
+  return $result;
+}
+
+
+###########################################################################
+### Utilities
+###
+
+sub min ( $$ )
+{ my ($x, $y) = check_args(2, @_);
+  return ($x < $y) ? $x : $y;
+}
+
+sub max ( $$ )
+{ my ($x, $y) = check_args(2, @_);
+  return ($x > $y) ? $x : $y;
+}
+
+sub file_to_tree ( $ )
+{ my ($file) = check_args(1, @_);
+
+  my $tree = new HTML::TreeBuilder;
+  $tree->ignore_unknown(1);
+  # $tree->warn(1);
+  $tree->parse_file($file);
+  cleanup_parse_tree($tree);
+  return $tree
+}
+
+
+sub has_single_content ( $ )
+{ my ($he) = check_args(1, @_);
+  if (!ref $he)
+    { # return 0;
+      die "Non-reference argument: $he"; }
+  my $ref_content = $he->content;
+  if (!defined $ref_content)
+    { return 0; }
+  my @content = @{$ref_content};
+  if (scalar(@content) != 1)
+    { return 0; }
+  return 1;
+}
+
+
+# Return true if the content of the element contains only one element itself,
+# and that inner element has the specified tag.
+sub has_single_content_with_tag ( $$ )
+{ my ($he, $tag) = check_args(2, @_);
+  if (!has_single_content($he))
+    { return 0; }
+  my $content = $ {$he->content}[0];
+  if (!ref $content)
+    { return 0; }
+  my $content_tag = $content->tag;
+  if (!defined $content_tag)
+    { return 0; }
+  return $content_tag eq $tag;
+}
+
+sub has_single_content_string ( $ )
+{ my ($he) = check_args(1, @_);
+  if (!has_single_content($he))
+    { return 0; }
+  my $content = $ {$he->content}[0];
+  if (ref $content)
+    { return 0; }
+  return 1;
+}
+
+
+# Return name, href, content.  First two may be undefined; third is an array.
+# I don't see how to determine if there are more attributes.
+sub anchor_info ( $ )
+{ my ($he) = check_args(1, @_);
+  if ($he->tag ne "a")
+    { $he->dump;
+      die "passed non-anchor to anchor_info"; }
+  my $name = $he->attr('name');
+  my $href = $he->attr('href');
+  my @content = ();
+  { my $ref_content = $he->content;
+    if (defined $ref_content)
+      { @content = @{$ref_content}; } }
+  return ($name, $href, @content);
+}
+
+
+sub texi_quote ( $ )
+{ my ($text) = check_args(1, @_);
+  $text =~ s/([\@\{\}])/\@$1/g;
+  $text =~ s/ -- / --- /g;
+  return $text;
+}
+
+# Eliminate bad punctuation (that confuses Makeinfo or Info) for section titles.
+sub texi_remove_punctuation ( $ )
+{ my ($text) = check_args(1, @_);
+
+  $text =~ s/^ +//g;
+  $text =~ s/[ :]+$//g;
+  $text =~ s/^[1-9][0-9.]* +//g;
+  $text =~ s/,//g;
+  # Both embedded colons and " -- " confuse makeinfo.  (Perhaps " -- "
+  # gets converted into " - ", just as "---" would be converted into " -- ",
+  # so the names end up differing.)
+  # $text =~ s/:/ -- /g;
+  $text =~ s/://g;
+  return $text;
+}
+
+
+## Do not use this inside `traverse':  it throws off the traversal.  Use
+## html_replace_by_ignore or html_replace_by_meta instead.
+# Returns 1 if success, 0 if failure.
+sub html_remove ( $;$ )
+{ my ($he, $parent) = check_args_range(1, 2, @_);
+  if (!defined $parent)
+    { $parent = $he->parent; }
+  my $ref_pcontent = $parent->content;
+  my @pcontent = @{$ref_pcontent};
+  for (my $i=0; $i<scalar(@pcontent); $i++)
+    { if ($pcontent[$i] eq $he)
+	{ splice @{$ref_pcontent}, $i, 1;
+	  $he->parent(undef);
+	  return 1; } }
+  die "Didn't find $he in $parent";
+}
+
+
+sub html_replace ( $$;$ )
+{ my ($orig, $new, $parent) = check_args_range(2, 3, @_);
+  if (!defined $parent)
+    { $parent = $orig->parent; }
+  my $ref_pcontent = $parent->content;
+  my @pcontent = @{$ref_pcontent};
+  for (my $i=0; $i<scalar(@pcontent); $i++)
+    { if ($pcontent[$i] eq $orig)
+	{ $ {$ref_pcontent}[$i] = $new;
+	  $new->parent($parent);
+	  $orig->parent(undef);
+	  return 1; } }
+  die "Didn't find $orig in $parent";
+}
+
+sub html_replace_by_meta ( $;$ )
+{ my ($orig, $parent) = check_args_range(1, 2, @_);
+  my $meta = new HTML::Element "meta";
+  if (!defined $parent)
+    { $parent = $orig->parent; }
+  return html_replace($orig, $meta, $parent);
+}
+
+sub html_replace_by_ignore ( $;$ )
+{ my ($orig, $parent) = check_args_range(1, 2, @_);
+  my $ignore = new HTML::Element "ignore";
+  if (!defined $parent)
+    { $parent = $orig->parent; }
+  return html_replace($orig, $ignore, $parent);
+}
+
+
+
+###
+### Collect text elements
+###
+
+my @collected_texts;
+my $collect_texts_stoppoint;
+my $done_collecting;
+
+sub collect_texts ( $;$ )
+{ my ($root, $stop) = check_args_range(1, 2, @_);
+  # print STDERR "collect_texts: $root $stop\n";
+  $collect_texts_stoppoint = $stop;
+  $done_collecting = 0;
+  @collected_texts = ();
+  $root->traverse(\&collect_if_text); # process texts
+  # print STDERR "collect_texts => ", join(";;;", @collected_texts), "\n";
+  return @collected_texts;
+}
+
+sub collect_if_text ( $$$ )
+{ my $he = (check_args(3, @_))[0]; #  ignore depth and startflag arguments
+  if ($done_collecting)
+    { return 0; }
+  if (!defined $he)
+    { return 0; }
+  if (!ref $he)
+    { push @collected_texts, $he;
+      return 0; }
+  if ((defined $collect_texts_stoppoint) && ($he eq $collect_texts_stoppoint))
+    { $done_collecting = 1;
+      return 0; }
+  return 1;
+}
+
+
+###########################################################################
+### Clean up parse tree
+###
+
+sub cleanup_parse_tree ( $ )
+{ my ($he) = check_args(1, @_);
+  $he->traverse(\&delete_if_navigation, 'ignore text');
+  $he->traverse(\&delete_extra_spaces, 'ignore text');
+  $he->traverse(\&merge_dl, 'ignore text');
+  $he->traverse(\&reorder_dt_and_dl, 'ignore text');
+  return $he;
+}
+
+
+## Simpler version that deletes contents but not the element itself.
+# sub delete_if_navigation ( $$$ )
+# { my $he = (check_args(3, @_))[0]; # ignore startflag and depth
+#   if (($he->tag() eq "div") && ($he->attr('class') eq 'navigation'))
+#     { $he->delete();
+#       return 0; }
+#   else
+#     { return 1; }
+# }
+
+sub delete_if_navigation ( $$$ )
+{ my ($he, $startflag) = (check_args(3, @_))[0,1]; #  ignore depth argument
+  if (!$startflag)
+    { return; }
+
+  if (($he->tag() eq "div") && (defined $he->attr('class')) && ($he->attr('class') eq 'navigation'))
+    { my $ref_pcontent = $he->parent()->content();
+      # Don't try to modify @pcontent, which appears to be a COPY.
+      # my @pcontent = @{$ref_pcontent};
+      for (my $i = 0; $i<scalar(@{$ref_pcontent}); $i++)
+	{ if (${$ref_pcontent}[$i] eq $he)
+	    { splice(@{$ref_pcontent}, $i, 1);
+	      last; } }
+      $he->delete();
+      return 0; }
+  else
+    { return 1; }
+}
+
+sub delete_extra_spaces ( $$$ )
+{ my ($he, $startflag) = (check_args(3, @_))[0,1]; #  ignore depth argument
+  if (!$startflag)
+    { return; }
+
+  my $tag = $he->tag;
+  if ($tag =~ /^(head|html|table|tr|ul)$/)
+    { delete_child_spaces($he); }
+  delete_trailing_spaces($he);
+  return 1;
+}
+
+
+sub delete_child_spaces ( $ )
+{ my ($he) = check_args(1, @_);
+  my $ref_content = $he->content();
+  for (my $i = 0; $i<scalar(@{$ref_content}); $i++)
+    { if ($ {$ref_content}[$i] =~ /^ *$/)
+	{ splice(@{$ref_content}, $i, 1);
+	  $i--; } }
+}
+
+sub delete_trailing_spaces ( $ )
+{ my ($he) = check_args(1, @_);
+  my $ref_content = $he->content();
+  if (! defined $ref_content)
+    { return; }
+  # Could also check for previous element = /^h[1-6]$/.
+  for (my $i = 0; $i<scalar(@{$ref_content})-1; $i++)
+    { if ($ {$ref_content}[$i] =~ /^ *$/)
+	{ my $next_elt = $ {$ref_content}[$i+1];
+	  if ((ref $next_elt) && ($next_elt->tag =~ /^(br|dd|dl|dt|hr|p|ul)$/))
+	    { splice(@{$ref_content}, $i, 1);
+	      $i--; } } }
+  if ($he->tag =~ /^(dd|dt|^h[1-6]|li|p)$/)
+    { my $last_elt = $ {$ref_content}[$#{$ref_content}];
+      if ((defined $last_elt) && ($last_elt =~ /^ *$/))
+	{ pop @{$ref_content}; } }
+}
+
+
+# LaTeX2HTML sometimes creates
+#   <DT>text
+#   <DL COMPACT><DD>text
+# which should actually be:
+#   <DL COMPACT>
+#   <DT>text
+#   <DD>text
+# Since a <DL> gets added, this ends up looking like
+# <P>
+#   <DL>
+#     <DT>
+#       text1...
+#       <DL COMPACT>
+#         <DD>
+#           text2...
+#         dt_or_dd1...
+#     dt_or_dd2...
+# which should become
+# <P>
+#   <DL COMPACT>
+#     <DT>
+#       text1...
+#     <DD>
+#       text2...
+#     dt_or_dd1...
+#     dt_or_dd2...
+
+sub reorder_dt_and_dl ( $$$ )
+{ my ($he, $startflag) = (check_args(3, @_))[0,1]; #  ignore depth argument
+  if (!$startflag)
+    { return; }
+
+  if ($he->tag() eq "p")
+    { my $ref_pcontent = $he->content();
+      if (defined $ref_pcontent)
+	{ my @pcontent = @{$ref_pcontent};
+	  # print "reorder_dt_and_dl found a <p>\n"; $he->dump();
+	  if ((scalar(@pcontent) >= 1)
+	      && (ref $pcontent[0]) && ($pcontent[0]->tag() eq "dl")
+	      && $pcontent[0]->implicit())
+	    { my $ref_dlcontent = $pcontent[0]->content();
+	      # print "reorder_dt_and_dl found a <p> and implicit <dl>\n";
+	      if (defined $ref_dlcontent)
+		{ my @dlcontent = @{$ref_dlcontent};
+		  if ((scalar(@dlcontent) >= 1)
+		      && (ref $dlcontent[0]) && ($dlcontent[0]->tag() eq "dt"))
+		    { my $ref_dtcontent = $dlcontent[0]->content();
+		      # print "reorder_dt_and_dl found a <p>, implicit <dl>, and <dt>\n";
+		      if (defined $ref_dtcontent)
+			{ my @dtcontent = @{$ref_dtcontent};
+			  if ((scalar(@dtcontent) > 0)
+			      && (ref $dtcontent[$#dtcontent])
+			      && ($dtcontent[$#dtcontent]->tag() eq "dl"))
+			    { my $ref_dl2content = $dtcontent[$#dtcontent]->content();
+			      # print "reorder_dt_and_dl found a <p>, implicit <dl>, <dt>, and <dl>\n";
+			      if (defined $ref_dl2content)
+				{ my @dl2content = @{$ref_dl2content};
+				  if ((scalar(@dl2content) > 0)
+				      && (ref ($dl2content[0]))
+				      && ($dl2content[0]->tag() eq "dd"))
+			    {
+			      # print "reorder_dt_and_dl found a <p>, implicit <dl>, <dt>, <dl>, and <dd>\n";
+			      # print STDERR "CHANGING\n"; $he->dump();
+			      html_replace_by_ignore($dtcontent[$#dtcontent]);
+			      splice(@{$ref_dlcontent}, 1, 0, @dl2content);
+			      # print STDERR "CHANGED TO:\n"; $he->dump();
+			      return 0; # don't traverse children
+			    } } } } } } } } }
+  return 1;
+}
+
+
+# If we find a paragraph that looks like
+# <P>
+#   <HR>
+#   <UL>
+# then accumulate its links into a contents_list and delete the paragraph.
+sub process_if_child_links ( $$$ )
+{ my ($he, $startflag) = (check_args(3, @_))[0,1]; #  ignore depth argument
+  if (!$startflag)
+    { return; }
+
+  if ($he->tag() eq "p")
+    { my $ref_content = $he->content();
+      if (defined $ref_content)
+	{ my @content = @{$ref_content};
+	  if ((scalar(@content) == 2)
+	      && (ref $content[0]) && $content[0]->tag() eq "hr"
+	      && (ref $content[1]) && $content[1]->tag() eq "ul")
+	    { process_child_links($he);
+	      $he->delete();
+	      return 0; } } }
+  return 1;
+}
+
+
+# If we find
+#     <H4>
+#       "Footnotes"
+#     <DL>
+#       <DT>
+#         <A NAME="foot560">
+#           "...borrow"
+#         <A HREF="refcountsInPython.html#tex2html2" NAME="foot560">
+#           "1.2"
+#       <DD>
+#         "The metaphor of ``borrowing'' a reference is not completely correct: the owner still has a copy of the reference. "
+#       ...
+# then record the footnote information and delete the section and list.
+
+my $process_if_footnotes_expect_dl_next = 0;
+
+sub process_if_footnotes ( $$$ )
+{ my ($he, $startflag) = (check_args(3, @_))[0,1]; #  ignore depth argument
+  if (!$startflag)
+    { return; }
+
+  if (($he->tag() eq "h4")
+      && has_single_content_string($he)
+      && ($ {$he->content}[0] eq "Footnotes"))
+    { html_replace_by_ignore($he);
+      $process_if_footnotes_expect_dl_next = 1;
+      return 0; }
+
+  if ($process_if_footnotes_expect_dl_next && ($he->tag() eq "dl"))
+    { my $ref_content = $he->content();
+      if (defined $ref_content)
+	{ $process_if_footnotes_expect_dl_next = 0;
+	  my @content = @{$ref_content};
+	  for (my $i=0; $i<$#content; $i+=2)
+	    { my $he_dt = $content[$i];
+	      my $he_dd = $content[$i+1];
+	      if (($he_dt->tag ne "dt") || ($he_dd->tag ne "dd"))
+		{ $he->dump;
+		  die "expected <DT> and <DD> at positions $i and ", $i+1; }
+	      my @dt_content = @{$he_dt->content()};
+	      if ((scalar(@dt_content) != 2)
+		  || ($dt_content[0]->tag ne "a")
+		  || ($dt_content[1]->tag ne "a"))
+		{ $he_dt->dump;
+		  die "Expected 2 anchors as content of <DT>"; }
+	      my ($dt1_name, $dt1_href, $dt1_content) = anchor_info($dt_content[0]);
+	      my ($dt2_name, $dt2_href, $dt2_content) = anchor_info($dt_content[0]);
+	      # unused: $dt1_href, $dt1_content, $dt2_href, $dt2_content
+	      if ($dt1_name ne $dt2_name)
+		{ $he_dt->dump;
+		  die "Expected identical names for anchors"; }
+	      html_replace_by_ignore($he_dd);
+	      $he_dd->tag("div"); # has no effect
+	      $footnotes{$dt1_name} = $he_dd; }
+	  html_replace_by_ignore($he);
+	  return 0; } }
+
+  if ($process_if_footnotes_expect_dl_next)
+    { $he->dump;
+      die "Expected <DL> for footnotes next"; }
+
+  return 1;
+}
+
+
+
+## Merge two adjacent paragraphs containing <DL> items, such as:
+#     <P>
+#       <DL>
+#         <DT>
+#           ...
+#         <DD>
+#           ...
+#     <P>
+#       <DL>
+#         <DT>
+#           ...
+#         <DD>
+#           ...
+
+sub merge_dl ( $$$ )
+{ my ($he, $startflag) = (check_args(3, @_))[0,1]; #  ignore depth argument
+  if (!$startflag)
+    { return; }
+
+  my $ref_content = $he->content;
+  if (!defined $ref_content)
+    { return; }
+  my $i = 0;
+  while ($i < scalar(@{$ref_content})-1)
+    { my $p1 = $ {$ref_content}[$i];
+      if ((ref $p1) && ($p1->tag eq "p")
+	  && has_single_content_with_tag($p1, "dl"))
+	{ my $dl1 = $ {$p1->content}[0];
+	  # In this loop, rhs, not lhs, of < comparison changes,
+	  # because we are removing elements from the content of $he.
+	  while ($i < scalar(@{$ref_content})-1)
+	    { my $p2 = $ {$ref_content}[$i+1];
+	      if (!((ref $p2) && ($p2->tag eq "p")
+		    && has_single_content_with_tag($p2, "dl")))
+		{ last; }
+	      # Merge these two elements.
+	      splice(@{$ref_content}, $i+1, 1); # remove $p2
+	      my $dl2 = $ {$p2->content}[0];
+	      $dl1->push_content(@{$dl2->content}); # put $dl2's content in $dl1
+	    }
+	  # extra increment because next element isn't a candidate for $p1
+	  $i++; }
+      $i++; }
+  return 1;
+}
+
+
+
+###########################################################################
+### Testing
+###
+
+sub test ( $$ )
+{ my ($action, $file) = check_args(2, @_);
+
+  # General testing
+  if (($action eq "view") || ($action eq ""))
+    { # # $file = "/homes/gws/mernst/www/links.html";
+      # # $file = "/homes/gws/mernst/www/index.html";
+      # # $file = "/homes/fish/mernst/java/gud/doc/manual.html";
+      # # $file = "/projects/cecil/cecil/doc/manuals/stdlib-man/stdlib/stdlib.html";
+      # # $file = "/homes/fish/mernst/tmp/python-doc/html/index.html";
+      # $file = "/homes/fish/mernst/tmp/python-doc/html/api/complexObjects.html";
+      my $tree = file_to_tree($file);
+
+      ## Testing
+      # print STDERR $tree->as_HTML;
+      $tree->dump();
+
+      # print STDERR $tree->tag(), "\n";
+      # print STDERR @{$tree->content()}, "\n";
+      # 
+      # for (@{ $tree->extract_links(qw(a img)) }) {
+      #   my ($link, $linkelem) = @$_;
+      #   print STDERR "$link ", $linkelem->as_HTML;
+      #   }
+      # 
+      # print STDERR @{$tree->extract_links()}, "\n";
+
+      # my @top_level_elts = @{$tree->content()};
+
+      # if scalar(@{$tree->content()})
+      return;
+    }
+
+  elsif ($action eq "raw")
+    { my $tree = new HTML::TreeBuilder;
+      $tree->ignore_unknown(1);
+      # $tree->warn(1);
+      $tree->parse_file($file);
+
+      $tree->dump();
+
+      # cleanup_parse_tree($tree);
+      # $tree->dump();
+      return;
+    }
+
+  # Test dealing with a section.
+  elsif ($action eq "section")
+    { # my $file;
+      # $file = "/homes/fish/mernst/tmp/python-doc/html/api/intro.html";
+      # $file = "/homes/fish/mernst/tmp/python-doc/html/api/includes.html";
+      # $file = "/homes/fish/mernst/tmp/python-doc/html/api/complexObjects.html";
+      process_section_file($file, 0, "Title");
+    }
+
+  # Test dealing with many sections
+  elsif (0)
+    { my @files = ("/homes/fish/mernst/tmp/python-doc/html/api/about.html",
+		   "/homes/fish/mernst/tmp/python-doc/html/api/abstract.html",
+		   "/homes/fish/mernst/tmp/python-doc/html/api/api.html",
+		   "/homes/fish/mernst/tmp/python-doc/html/api/cObjects.html",
+		   "/homes/fish/mernst/tmp/python-doc/html/api/complexObjects.html",
+		   "/homes/fish/mernst/tmp/python-doc/html/api/concrete.html",
+		   # "/homes/fish/mernst/tmp/python-doc/html/api/contents.html",
+		   "/homes/fish/mernst/tmp/python-doc/html/api/countingRefs.html",
+		   "/homes/fish/mernst/tmp/python-doc/html/api/debugging.html",
+		   "/homes/fish/mernst/tmp/python-doc/html/api/dictObjects.html",
+		   "/homes/fish/mernst/tmp/python-doc/html/api/embedding.html",
+		   "/homes/fish/mernst/tmp/python-doc/html/api/exceptionHandling.html",
+		   "/homes/fish/mernst/tmp/python-doc/html/api/exceptions.html",
+		   "/homes/fish/mernst/tmp/python-doc/html/api/fileObjects.html",
+		   "/homes/fish/mernst/tmp/python-doc/html/api/floatObjects.html",
+		   "/homes/fish/mernst/tmp/python-doc/html/api/front.html",
+		   "/homes/fish/mernst/tmp/python-doc/html/api/fundamental.html",
+		   # "/homes/fish/mernst/tmp/python-doc/html/api/genindex.html",
+		   "/homes/fish/mernst/tmp/python-doc/html/api/importing.html",
+		   "/homes/fish/mernst/tmp/python-doc/html/api/includes.html",
+		   "/homes/fish/mernst/tmp/python-doc/html/api/index.html",
+		   "/homes/fish/mernst/tmp/python-doc/html/api/initialization.html",
+		   "/homes/fish/mernst/tmp/python-doc/html/api/intObjects.html",
+		   "/homes/fish/mernst/tmp/python-doc/html/api/intro.html",
+		   "/homes/fish/mernst/tmp/python-doc/html/api/listObjects.html",
+		   "/homes/fish/mernst/tmp/python-doc/html/api/longObjects.html",
+		   "/homes/fish/mernst/tmp/python-doc/html/api/mapObjects.html",
+		   "/homes/fish/mernst/tmp/python-doc/html/api/mapping.html",
+		   "/homes/fish/mernst/tmp/python-doc/html/api/newTypes.html",
+		   "/homes/fish/mernst/tmp/python-doc/html/api/node24.html",
+		   "/homes/fish/mernst/tmp/python-doc/html/api/noneObject.html",
+		   "/homes/fish/mernst/tmp/python-doc/html/api/number.html",
+		   "/homes/fish/mernst/tmp/python-doc/html/api/numericObjects.html",
+		   "/homes/fish/mernst/tmp/python-doc/html/api/object.html",
+		   "/homes/fish/mernst/tmp/python-doc/html/api/objects.html",
+		   "/homes/fish/mernst/tmp/python-doc/html/api/os.html",
+		   "/homes/fish/mernst/tmp/python-doc/html/api/otherObjects.html",
+		   "/homes/fish/mernst/tmp/python-doc/html/api/processControl.html",
+		   "/homes/fish/mernst/tmp/python-doc/html/api/refcountDetails.html",
+		   "/homes/fish/mernst/tmp/python-doc/html/api/refcounts.html",
+		   "/homes/fish/mernst/tmp/python-doc/html/api/sequence.html",
+		   "/homes/fish/mernst/tmp/python-doc/html/api/sequenceObjects.html",
+		   "/homes/fish/mernst/tmp/python-doc/html/api/standardExceptions.html",
+		   "/homes/fish/mernst/tmp/python-doc/html/api/stringObjects.html",
+		   "/homes/fish/mernst/tmp/python-doc/html/api/threads.html",
+		   "/homes/fish/mernst/tmp/python-doc/html/api/tupleObjects.html",
+		   "/homes/fish/mernst/tmp/python-doc/html/api/typeObjects.html",
+		   "/homes/fish/mernst/tmp/python-doc/html/api/types.html",
+		   "/homes/fish/mernst/tmp/python-doc/html/api/utilities.html",
+		   "/homes/fish/mernst/tmp/python-doc/html/api/veryhigh.html");
+      for my $file (@files)
+	{ print STDERR "\n", "=" x 75, "\n", "$file:\n";
+	  process_section_file($file, 0, "Title");
+	}
+    }
+
+  # Test dealing with index.
+  elsif ($action eq "index")
+    { # my $file;
+      # $file = "/homes/fish/mernst/tmp/python-doc/html/api/genindex.html";
+
+      process_index_file($file, "\@cindex");
+      print_index_info();
+    }
+
+  else
+    { die "Unrecognized action `$action'"; }
+}
+
+
+###########################################################################
+### Main loop
+###
+
+sub process_contents_file ( $ )
+{ my ($file) = check_args(1, @_);
+
+  # could also use File::Basename
+  my $info_file = $file;
+  $info_file =~ s/(\/?index)?\.html$//;
+  if ($info_file eq "")
+    { chomp($info_file = `pwd`); }
+  $info_file =~ s/^.*\///;	# not the most efficient way to remove dirs
+
+  $html_directory = $file;
+  $html_directory =~ s/(\/|^)[^\/]+$/$1/;
+
+  my $texi_file = "$info_file.texi";
+  open(TEXI, ">$texi_file");
+
+  print TEXI "\\input texinfo   \@c -*-texinfo-*-\n";
+  print TEXI "\@c %**start of header\n";
+  print TEXI "\@setfilename $info_file\n";
+
+  # 2. Summary Description and Copyright
+  #      The "Summary Description and Copyright" segment describes the
+  #      document and contains the copyright notice and copying permissions
+  #      for the Info file.  The segment must be enclosed between `@ifinfo'
+  #      and `@end ifinfo' commands so that the formatters place it only in
+  #      the Info file.
+  # 
+  # The summary description and copyright segment does not appear in the
+  # printed document.
+  # 
+  #      @ifinfo
+  #      This is a short example of a complete Texinfo file.
+  #      
+  #      Copyright @copyright{} 1990 Free Software Foundation, Inc.
+  #      @end ifinfo
+
+
+  # 3. Title and Copyright
+  #      The "Title and Copyright" segment contains the title and copyright
+  #      pages and copying permissions for the printed manual.  The segment
+  #      must be enclosed between `@titlepage' and `@end titlepage'
+  #      commands.  The title and copyright page appear only in the printed
+  #      manual.
+  # 
+  # The titlepage segment does not appear in the Info file.
+  # 
+  #      @titlepage
+  #      @sp 10
+  #      @comment The title is printed in a large font.
+  #      @center @titlefont{Sample Title}
+  #      
+  #      @c The following two commands start the copyright page.
+  #      @page
+  #      @vskip 0pt plus 1filll
+  #      Copyright @copyright{} 1990 Free Software Foundation, Inc.
+  #      @end titlepage
+
+
+  # 4. `Top' Node and Master Menu
+  #      The "Master Menu" contains a complete menu of all the nodes in the
+  #      whole Info file.  It appears only in the Info file, in the `Top'
+  #      node.
+  # 
+  # The `Top' node contains the master menu for the Info file.  Since a
+  # printed manual uses a table of contents rather than a menu, the master
+  # menu appears only in the Info file.
+  # 
+  #      @node    Top,       First Chapter, ,         (dir)
+  #      @comment node-name, next,          previous, up
+  # 
+  #      @menu
+  #      * First Chapter::    The first chapter is the
+  #                           only chapter in this sample.
+  #      * Concept Index::    This index has two entries.
+  #      @end menu
+
+
+
+  $current_ref_tdf = [ "Top", 0, $ARGV[0] ];
+  process_section_file($file, 0, "Top");
+  while (scalar(@contents_list))
+  { $current_ref_tdf = shift @contents_list;
+    process_section_file($ {$current_ref_tdf}[2], $ {$current_ref_tdf}[1], $ {$current_ref_tdf}[0]);
+  }
+
+  print TEXI "\n";
+  for my $indextitle (@index_titles)
+    { print TEXI "\@node $indextitle\n";
+      print TEXI "\@unnumbered $indextitle\n";
+      print TEXI "\@printindex $ {$index_info{$indextitle}}[1]\n";
+      print TEXI "\n"; }
+
+  print TEXI "\@contents\n";
+  print TEXI "\@bye\n";
+  close(TEXI);
+}
+
+# This needs to be last so global variable initializations are reached.
+
+if (scalar(@ARGV) == 0)
+{ die "No arguments supplied to html2texi.pl"; }
+
+if ($ARGV[0] eq "-test")
+{ my @test_args = @ARGV[1..$#ARGV];
+  if (scalar(@test_args) == 0)
+    { test("", "index.html"); }
+  elsif (scalar(@test_args) == 1)
+    { test("", $test_args[0]); }
+  elsif (scalar(@test_args) == 2)
+    { test($test_args[0], $test_args[1]); }
+  else
+    { die "Too many test arguments passed to html2texi: ", join(" ", @ARGV); }
+  exit();
+}
+
+if (scalar(@ARGV) != 1)
+{ die "Pass one argument, the main/contents page"; }
+
+process_contents_file($ARGV[0]);
+
+# end of html2texi.pl


Property changes on: vendor/Python/current/Doc/tools/html2texi.pl
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Doc/tools/indfix.py
===================================================================
--- vendor/Python/current/Doc/tools/indfix.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/tools/indfix.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,100 @@
+#! /usr/bin/env python
+
+"""Combine similar index entries into an entry and subentries.
+
+For example:
+
+    \item {foobar} (in module flotz), 23
+    \item {foobar} (in module whackit), 4323
+
+becomes
+
+    \item {foobar}
+      \subitem in module flotz, 23
+      \subitem in module whackit, 4323
+
+Note that an item which matches the format of a collapsable item but which
+isn't part of a group of similar items is not modified.
+"""
+__version__ = '$Revision: 29268 $'
+
+import re
+import StringIO
+import sys
+
+
+def cmp_entries(e1, e2):
+    return cmp(e1[1].lower(), e2[1].lower()) or cmp(e1, e2)
+
+
+def dump_entries(write, entries):
+    if len(entries) == 1:
+        write("  \\item %s (%s)%s\n" % entries[0])
+        return
+    write("  \item %s\n" % entries[0][0])
+    # now sort these in a case insensitive manner:
+    if len(entries) > 0:
+        entries.sort(cmp_entries)
+    for xxx, subitem, pages in entries:
+        write("    \subitem %s%s\n" % (subitem, pages))
+
+
+breakable_re = re.compile(
+    r"  \\item (.*) [(](.*)[)]((?:(?:, \d+)|(?:, \\[a-z]*\{\d+\}))+)")
+
+
+def process(ifn, ofn=None):
+    if ifn == "-":
+        ifp = sys.stdin
+    else:
+        ifp = open(ifn)
+    if ofn is None:
+        ofn = ifn
+    ofp = StringIO.StringIO()
+    entries = []
+    match = breakable_re.match
+    write = ofp.write
+    while 1:
+        line = ifp.readline()
+        if not line:
+            break
+        m = match(line)
+        if m:
+            entry = m.group(1, 2, 3)
+            if entries and entries[-1][0] != entry[0]:
+                dump_entries(write, entries)
+                entries = []
+            entries.append(entry)
+        elif entries:
+            dump_entries(write, entries)
+            entries = []
+            write(line)
+        else:
+            write(line)
+    del write
+    del match
+    ifp.close()
+    data = ofp.getvalue()
+    ofp.close()
+    if ofn == "-":
+        ofp = sys.stdout
+    else:
+        ofp = open(ofn, "w")
+    ofp.write(data)
+    ofp.close()
+
+
+def main():
+    import getopt
+    outfile = None
+    opts, args = getopt.getopt(sys.argv[1:], "o:")
+    for opt, val in opts:
+        if opt in ("-o", "--output"):
+            outfile = val
+    filename = args[0]
+    outfile = outfile or filename
+    process(filename, outfile)
+
+
+if __name__ == "__main__":
+    main()


Property changes on: vendor/Python/current/Doc/tools/indfix.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Doc/tools/keywords.py
===================================================================
--- vendor/Python/current/Doc/tools/keywords.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/tools/keywords.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,19 @@
+#! /usr/bin/env python
+
+# This Python program sorts and reformats the table of keywords in ref2.tex
+
+l = []
+try:
+    while 1:
+        l = l + raw_input().split()
+except EOFError:
+    pass
+l.sort()
+for x in l[:]:
+    while l.count(x) > 1: l.remove(x)
+ncols = 5
+nrows = (len(l)+ncols-1)/ncols
+for i in range(nrows):
+    for j in range(i, len(l), nrows):
+        print l[j].ljust(10),
+    print

Added: vendor/Python/current/Doc/tools/listmodules
===================================================================
--- vendor/Python/current/Doc/tools/listmodules	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/tools/listmodules	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,183 @@
+#! /usr/bin/env python
+#  -*- Python -*-
+#
+#  This script can be used to identify undocumented modules in the Python
+#  standard library.  Use it like this:
+#
+#  .../Doc/tools/listmodules --ignore-from .../Doc/paper-<paper>/modlib.idx
+
+"""%(program)s - list modules in the Python standard library
+
+-a, --annotate	  Annotate the module names with the subdirectory they
+                  live in
+-c, --categorize  Group the modules by subdirectory
+-i <file>,
+
+--ignore-from <file>	Ignore the modules listed in <file>.  <file> may
+                  contain a list of module names or a module index file
+                  as produced when formatting the Python documentation
+                  (.idx or .html flavor).
+
+If neither -a nor -c are given, the modules are listed in alphabetical
+order.
+
+Note that -a and -c are mutually exclusive.
+
+Limitation: Modules loadable as shared objects may not be listed,
+though this script attempts to locate such modules.
+
+"""
+
+__version__ = '$Revision: 18276 $'
+
+import getopt
+import glob
+import os
+import re
+import string
+import sys
+
+
+REMOVE_DIRS = ["dos-8x3", "encodings", "distutils",
+               "lib-old", "lib-stdwin", "test"]
+
+
+def main():
+    args = sys.argv[1:]
+    annotate = 0
+    builtin = 0
+    categorize = 0
+    ignore_dict = {}
+    ignore = ignore_dict.has_key
+    try:
+        opts, args = getopt.getopt(
+            args, "abchi:",
+            ["annotate", "built-in", "categorize", "help", "ignore-from="])
+    except getopt.error, msg:
+        sys.stdout = sys.stderr
+        print msg
+        print
+        usage()
+        sys.exit(2)
+    for opt, arg in opts:
+        if opt in ("-a", "--annotate"):
+            annotate = 1
+        elif opt in ("-b", "--built-in"):
+            builtin = 1
+        elif opt in ("-c", "--categorize"):
+            categorize = 1
+        elif opt in ("-h", "--help"):
+            usage()
+            sys.exit()
+        elif opt in ("-i", "--ignore-from"):
+            data = open(arg).read()
+            if data[:1] == "\\":
+                ignore_from_idx(data, ignore_dict)
+            else:
+                ignore_from_modulelist(data, ignore_dict)
+    if args or (annotate and categorize):
+        usage()
+        sys.exit(2)
+    #
+    # Populate the database:
+    #
+    srcdir = os.path.normpath(os.path.join(
+        os.path.dirname(sys.argv[0]), os.pardir, os.pardir))
+    os.chdir(srcdir)
+    modules_by_name = {}
+    modules_by_dir = {}
+    if builtin:
+        l = []
+        modules_by_dir["<builtin>"] = l
+        for name in sys.builtin_module_names:
+            if not ignore(name):
+                modules_by_name[name] = "<built-in>"
+                l.append(name)
+    rx = re.compile("Lib/plat-[a-zA-Z0-9]*/")
+    fp = os.popen("find Lib -name \*.py -print", "r")
+    while 1:
+        line = fp.readline()
+        if not line:
+            break
+        m = rx.match(line)
+        if m:
+            line = "Lib/plat-*/" + line[m.end():]
+        line = line[4:-4]                # strip off 'Lib/' and '.py\n'
+        dir, name = os.path.split(line)
+        dir = dir or "<standard>"
+        if ignore(name):
+            continue
+        if dir not in REMOVE_DIRS:
+            modules_by_name[name] = dir
+            l = modules_by_dir.get(dir, [])
+            modules_by_dir[dir] = l
+            if name not in l:
+                l.append(name)
+    # load up extension modules:
+    pwd = os.getcwd()
+    try:
+        os.chdir("Modules")
+        dir = "<extension>"
+        for line in glob.glob("*module.c"):
+            name = line[:-8]
+            if ignore(name) or modules_by_name.has_key(name) or name == "xx":
+                continue
+            modules_by_name[name] = dir
+            l = modules_by_dir.get(dir, [])
+            modules_by_dir[dir] = l
+            if name not in l:
+                l.append(name)
+    finally:
+        os.chdir(pwd)
+    #
+    # Dump the results:
+    #
+    if annotate:
+        modules = modules_by_name.items()
+        modules.sort()
+        width = max(map(len, modules_by_name.keys()))
+        format = "%%-%ds  %%s" % width
+        for name, dir in modules:
+            if dir and dir[0] != "<":
+                print format % (name, dir)
+            else:
+                print name
+    elif categorize:
+        modules = modules_by_dir.items()
+        modules.sort()
+        width = max(map(len, modules_by_dir.keys()))
+        format = "%%-%ds  %%s" % width
+        for dir, names in modules:
+            names.sort()
+            print format % (dir, names[0])
+            for name in names[1:]:
+                print format % ('', name)
+            print
+    else:
+        modules = modules_by_name.keys()
+        modules.sort()
+        print string.join(modules, "\n")
+
+
+def ignore_from_modulelist(data, ignore_dict):
+    for name in string.split(data):
+        ignore_dict[name] = name
+
+def ignore_from_idx(data, ignore_dict):
+    data = string.replace(data, r"\hackscore  {}", "_")
+    rx = re.compile(r"\\indexentry\s*{([^@]*)@")
+    for line in string.split(data, "\n"):
+        m = rx.match(line)
+        if m:
+            name = m.group(1)
+            ignore_dict[name] = name
+
+
+def usage():
+    vars = {}
+    vars["program"] = os.path.basename(sys.argv[0])
+    print __doc__ % vars
+
+
+if __name__ == "__main__":
+    main()


Property changes on: vendor/Python/current/Doc/tools/listmodules
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Doc/tools/listmodules.py
===================================================================
--- vendor/Python/current/Doc/tools/listmodules.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/tools/listmodules.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,126 @@
+# $Id: listmodules.py 42172 2006-01-24 16:16:19Z fredrik.lundh $
+#
+# Locate all standard modules available in this build.
+#
+# This script is designed to run on Python 1.5.2 and newer.
+#
+# Written by Fredrik Lundh, January 2005
+#
+
+import imp, sys, os, re, time
+
+identifier = "python-%s-%s" % (sys.version[:3], sys.platform)
+timestamp = time.strftime("%Y%m%dT%H%M%SZ", time.gmtime(time.time()))
+
+# known test packages
+TEST_PACKAGES = "test.", "bsddb.test.", "distutils.tests."
+
+try:
+    import platform
+    platform = platform.platform()
+except:
+    platform = None # unknown
+
+suffixes = imp.get_suffixes()
+
+def get_suffix(file):
+    for suffix in suffixes:
+        if file[-len(suffix[0]):] == suffix[0]:
+            return suffix
+    return None
+
+def main():
+
+    path = getpath()
+
+    modules = {}
+    for m in sys.builtin_module_names:
+        modules[m] = None
+
+    for p in path:
+        modules.update(getmodules(p))
+
+    keys = modules.keys()
+    keys.sort()
+
+    # filter out known test packages
+    def cb(m):
+        for d in TEST_PACKAGES:
+            if m[:len(d)] == d:
+                return 0
+        return 1
+    keys = filter(cb, keys)
+
+    try:
+        outfile = sys.argv[1]
+        if outfile == "-":
+            outfile = None
+        elif outfile == "-f":
+            outfile = "modules-" + identifier + ".txt"
+    except IndexError:
+        outfile = None
+
+    if not outfile:
+        out = sys.stdout
+    else:
+        out = open(outfile, "w")
+
+    out.write("# module list (generated by listmodules.py)\n")
+    out.write("#\n")
+    out.write("# timestamp=%s\n" % repr(timestamp))
+    out.write("# sys.version=%s\n" % repr(sys.version))
+    out.write("# sys.platform=%s\n" % repr(sys.platform))
+    if platform:
+        out.write("# platform=%s\n" % repr(platform))
+    out.write("#\n")
+
+    for k in keys:
+        out.write(k + "\n")
+
+    if out is not sys.stdout:
+        out.close()
+        print out.name, "ok (%d modules)" % len(modules)
+
+def getmodules(p):
+    # get modules in a given directory
+    modules = {}
+    for f in os.listdir(p):
+        f = os.path.join(p, f)
+        if os.path.isfile(f):
+            m, e = os.path.splitext(f)
+            suffix = get_suffix(f)
+            if not suffix:
+                continue
+            m = os.path.basename(m)
+            if re.compile("(?i)[a-z_]\w*$").match(m):
+                if suffix[2] == imp.C_EXTENSION:
+                    # check that this extension can be imported
+                    try:
+                        __import__(m)
+                    except ImportError:
+                        continue
+                modules[m] = f
+        elif os.path.isdir(f):
+            m = os.path.basename(f)
+            if os.path.isfile(os.path.join(f, "__init__.py")):
+                for mm, f in getmodules(f).items():
+                    modules[m + "." + mm] = f
+    return modules
+
+def getpath():
+    path = map(os.path.normcase, map(os.path.abspath, sys.path[:]))
+    # get rid of site packages
+    for p in path:
+        if p[-13:] == "site-packages":
+            def cb(p, site_package_path=os.path.abspath(p)):
+                return p[:len(site_package_path)] != site_package_path
+            path = filter(cb, path)
+            break
+    # get rid of non-existent directories and the current directory
+    def cb(p, cwd=os.path.normcase(os.getcwd())):
+        return os.path.isdir(p) and p != cwd
+    path = filter(cb, path)
+    return path
+
+if __name__ == "__main__":
+    main()

Added: vendor/Python/current/Doc/tools/makesec.sh
===================================================================
--- vendor/Python/current/Doc/tools/makesec.sh	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/tools/makesec.sh	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,129 @@
+#!/bin/sh
+
+# Simple little checker for individual libref manual sections
+#
+# usage: makesec.sh section
+#
+
+# This script builds the minimal file necessary to run a single section
+# through latex, does so, then converts the resulting dvi file to ps or pdf
+# and feeds the result into a viewer.  It's by no means foolproof, but seems
+# to work okay for me (knock wood).  It sure beats manually commenting out
+# most of the man lib.tex file and running everything manually.
+
+# It attempts to locate an appropriate dvi converter and viewer for the
+# selected output format.  It understands the following environment
+# variables:
+#
+#	PYSRC - refers to the root of your build tree (dir containing Doc)
+#	DVICVT - refers to a dvi converter like dvips or dvipdf
+#	VIEWER - refers to an appropriate viewer for the ps/pdf file
+#
+# Of the three, only PYSRC is currently required.  The other two can be set
+# to specify unusual tools which perform those tasks.
+
+# Known issues:
+#   - It would be nice if the script could determine PYSRC on its own.
+#   - Something about \seealso{}s blows the latex stack, so they need
+#     to be commented out for now.
+
+if [ x$PYSRC = x ] ; then
+    echo "PYSRC must refer to the Python source tree" 1>&2
+    exit 1
+fi
+
+if [ ! -d $PYSRC/Doc ] ; then
+    echo "Can't find a Doc subdirectory in $PYSRC" 1>&2
+    exit 1
+fi
+
+if [ "$#" -ne 1 ] ; then
+    echo "Must specify a single libref manual section on cmd line" 1>&2
+    exit 1
+fi
+
+# settle on a dvi converter
+if [ x$DVICVT != x ] ; then
+    converter=$DVICVT
+    ext=`echo $DVICVT | sed -e 's/^dvi//'`
+    result=lib.$ext
+elif [ x`which dvipdf` != x ] ; then
+    converter=`which dvipdf`
+    ext=.pdf
+elif [ x`which dvips` != x ] ; then
+    converter=`which dvips`
+    ext=.ps
+else
+    echo "Can't find a reasonable dvi converter" 1>&2
+    echo "Set DVICVT to refer to one" 1>&2
+    exit 1
+fi
+
+# how about a viewer?
+if [ x$VIEWER != x ] ; then
+    viewer=$VIEWER
+elif [ $ext = ".ps" -a x`which gv` != x ] ; then
+    viewer=gv
+elif [ $ext = ".ps" -a x`which gs` != x ] ; then
+    viewer=gs
+elif [ $ext = ".pdf" -a x`which acroread` != x ] ; then
+    viewer=acroread
+elif [ $ext = ".pdf" -a "`uname`" = "Darwin" -a x`which open` != x ] ; then
+    viewer=open
+elif [ $ext = ".pdf" -a x`which acroread` != x ] ; then
+    viewer=acroread
+else
+    echo "Can't find a reasonable viewer" 1>&2
+    echo "Set VIEWER to refer to one" 1>&2
+    exit 1
+fi
+
+# make sure necessary links are in place
+for f in howto.cls pypaper.sty ; do
+    rm -f $f
+    ln -s $PYSRC/Doc/$f
+done
+
+export TEXINPUTS=.:$PYSRC/Doc/texinputs:
+
+# strip extension in case they gave full filename
+inp=`basename $1 .tex`
+
+# create the minimal framework necessary to run section through latex
+tmpf=lib.tex
+cat > $tmpf <<EOF
+\documentclass{manual}
+
+% NOTE: this file controls which chapters/sections of the library
+% manual are actually printed.  It is easy to customize your manual
+% by commenting out sections that you are not interested in.
+
+\title{Python Library Reference}
+
+\input{boilerplate}
+
+\makeindex                      % tell \index to actually write the
+                                % .idx file
+\makemodindex                   % ... and the module index as well.
+
+
+\begin{document}
+
+\maketitle
+
+\ifhtml
+\chapter*{Front Matter\label{front}}
+\fi
+
+\input{$inp}
+\end{document}
+EOF
+
+latex $tmpf
+
+$converter lib
+
+$viewer lib.pdf
+
+rm -f $tmpf howto.cls pypaper.sty *.idx *.syn
+rm -f lib.aux lib.log


Property changes on: vendor/Python/current/Doc/tools/makesec.sh
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Doc/tools/mkackshtml
===================================================================
--- vendor/Python/current/Doc/tools/mkackshtml	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/tools/mkackshtml	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,66 @@
+#! /usr/bin/env python
+#  -*- Python -*-
+
+import string
+import support
+import sys
+
+
+def collect(fp):
+    names = []
+    while 1:
+        line = fp.readline()
+        if not line:
+            break
+        line = string.strip(line)
+        if line:
+            names.append(line)
+        else:
+            names = []
+    return names
+
+
+def main():
+    options = support.Options()
+    options.columns = 4
+    options.variables["title"] = "Acknowledgements"
+    options.parse(sys.argv[1:])
+    names = collect(sys.stdin)
+    percol = (len(names) + options.columns - 1) / options.columns
+    colnums = []
+    for i in range(options.columns):
+        colnums.append(percol*i)
+    options.aesop_type = "information"
+    fp = options.get_output_file()
+    fp.write(string.rstrip(options.get_header()) + "\n")
+    fp.write(THANKS + "\n")
+    fp.write('<table width="100%" align="center">\n')
+    for i in range(percol):
+        fp.write("  <tr>\n")
+        for j in colnums:
+            try:
+                fp.write("    <td>%s</td>\n" % names[i + j])
+            except IndexError:
+                pass
+        fp.write("  </tr>\n")
+    fp.write("</table>\n")
+    fp.write(string.rstrip(options.get_footer()) + "\n")
+    fp.close()
+
+THANKS = '''\
+
+<p>These people have contributed in some way to the Python
+documentation.  This list is probably not complete -- if you feel that
+you or anyone else should be on this list, please let us know (send
+email to <a
+href="mailto:docs at python.org">docs at python.org</a>), and
+we will be glad to correct the problem.</p>
+
+<p>It is only with the input and contributions of the Python community
+that Python has such wonderful documentation -- <b>Thank You!</b></p>
+
+'''
+
+
+if __name__ == "__main__":
+    main()


Property changes on: vendor/Python/current/Doc/tools/mkackshtml
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Doc/tools/mkhowto
===================================================================
--- vendor/Python/current/Doc/tools/mkhowto	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/tools/mkhowto	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,659 @@
+#! /usr/bin/env python
+#  -*- Python -*-
+"""usage: %(program)s [options...] file ...
+
+Options specifying formats to build:
+    --html		HyperText Markup Language (default)
+    --pdf		Portable Document Format
+    --ps		PostScript
+    --dvi		'DeVice Indepentent' format from TeX
+    --text		ASCII text (requires lynx)
+
+    More than one output format may be specified, or --all.
+
+HTML options:
+    --address, -a	Specify an address for page footers.
+    --dir		Specify the directory for HTML output.
+    --link		Specify the number of levels to include on each page.
+    --split, -s		Specify a section level for page splitting, default: %(max_split_depth)s.
+    --iconserver, -i	Specify location of icons (default: ./).
+    --image-type	Specify the image type to use in HTML output;
+                        values: gif, png (default).
+    --numeric           Don't rename the HTML files; just keep node#.html for
+                        the filenames.
+    --style             Specify the CSS file to use for the output (filename,
+                        not a URL).
+    --up-link           URL to a parent document.
+    --up-title          Title of a parent document.
+    --favicon           Icon to display in the browsers location bar.
+
+Other options:
+    --a4		Format for A4 paper.
+    --letter		Format for US letter paper (the default).
+    --help, -H		Show this text.
+    --logging, -l	Log stdout and stderr to a file (*.how).
+    --debugging, -D	Echo commands as they are executed.
+    --keep, -k		Keep temporary files around.
+    --quiet, -q		Do not print command output to stdout.
+			(stderr is also lost,  sorry; see *.how for errors)
+"""
+
+import getopt
+import glob
+import os
+import re
+import shutil
+import sys
+
+
+MYDIR = os.path.abspath(sys.path[0])
+TOPDIR = os.path.dirname(MYDIR)
+
+ISTFILE = os.path.join(TOPDIR, "texinputs", "python.ist")
+NODE2LABEL_SCRIPT = os.path.join(MYDIR, "node2label.pl")
+L2H_INIT_FILE = os.path.join(TOPDIR, "perl", "l2hinit.perl")
+
+BIBTEX_BINARY = "bibtex"
+DVIPS_BINARY = "dvips"
+LATEX_BINARY = "latex"
+LATEX2HTML_BINARY = "latex2html"
+LYNX_BINARY = "lynx"
+MAKEINDEX_BINARY = "makeindex"
+PDFLATEX_BINARY = "pdflatex"
+PERL_BINARY = "perl"
+PYTHON_BINARY = "python"
+
+
+def usage(options, file):
+    print >>file, __doc__ % options
+
+def error(options, message, err=2):
+    print >>sys.stderr, message
+    print >>sys.stderr
+    usage(options, sys.stderr)
+    sys.exit(2)
+
+
+class Options:
+    program = os.path.basename(sys.argv[0])
+    #
+    address = ''
+    builddir = None
+    debugging = 0
+    discard_temps = 1
+    have_temps = 0
+    icon_server = "."
+    image_type = "png"
+    logging = 0
+    max_link_depth = 3
+    max_split_depth = 6
+    paper = "letter"
+    quiet = 0
+    runs = 0
+    numeric = 0
+    global_module_index = None
+    style_file = os.path.join(TOPDIR, "html", "style.css")
+    about_file = os.path.join(TOPDIR, "html", "about.dat")
+    up_link = None
+    up_title = None
+    favicon = None
+    #
+    # 'dvips_safe' is a weird option.  It is used mostly to make
+    # LaTeX2HTML not try to be too smart about protecting the user
+    # from a bad version of dvips -- some versions would core dump if
+    # the path to the source DVI contained a dot, and it's appearantly
+    # difficult to determine if the version available has that bug.
+    # This option gets set when PostScript output is requested
+    # (because we're going to run dvips regardless, and we'll either
+    # know it succeeds before LaTeX2HTML is run, or we'll have
+    # detected the failure and bailed), or the user asserts that it's
+    # safe from the command line.
+    #
+    # So, why does LaTeX2HTML think it appropriate to protect the user
+    # from a dvips that's only potentially going to core dump?  Only
+    # because they want to avoid doing a lot of work just to have to
+    # bail later with no useful intermediates.  Unfortunately, they
+    # bail *before* they know whether dvips will be needed at all.
+    # I've gone around the bush a few times with the LaTeX2HTML
+    # developers over whether this is appropriate behavior, and they
+    # don't seem interested in changing their position.
+    #
+    dvips_safe = 0
+    #
+    DEFAULT_FORMATS = ("html",)
+    ALL_FORMATS = ("dvi", "html", "pdf", "ps", "text")
+
+    def __init__(self):
+        self.formats = []
+        self.l2h_init_files = []
+
+    def __getitem__(self, key):
+        # This is used when formatting the usage message.
+        try:
+            return getattr(self, key)
+        except AttributeError:
+            raise KeyError, key
+
+    def parse(self, args):
+        opts, args = getopt.getopt(args, "Hi:a:s:lDkqr:",
+                                   ["all", "postscript", "help", "iconserver=",
+                                    "address=", "a4", "letter", "l2h-init=",
+                                    "link=", "split=", "logging", "debugging",
+                                    "keep", "quiet", "runs=", "image-type=",
+                                    "about=", "numeric", "style=", "paper=",
+                                    "up-link=", "up-title=", "dir=",
+                                    "global-module-index=", "dvips-safe",
+                                    "favicon="]
+                                   + list(self.ALL_FORMATS))
+        for opt, arg in opts:
+            if opt == "--all":
+                self.formats = list(self.ALL_FORMATS)
+                self.dvips_safe = "ps" in self.formats
+            elif opt in ("-H", "--help"):
+                usage(self, sys.stdout)
+                sys.exit()
+            elif opt == "--iconserver":
+                self.icon_server = arg
+            elif opt in ("-a", "--address"):
+                self.address = arg
+            elif opt == "--a4":
+                self.paper = "a4"
+            elif opt == "--letter":
+                self.paper = "letter"
+            elif opt == "--link":
+                self.max_link_depth = int(arg)
+            elif opt in ("-s", "--split"):
+                self.max_split_depth = int(arg)
+            elif opt in ("-l", "--logging"):
+                self.logging = self.logging + 1
+            elif opt in ("-D", "--debugging"):
+                self.debugging = self.debugging + 1
+            elif opt in ("-k", "--keep"):
+                self.discard_temps = 0
+            elif opt in ("-q", "--quiet"):
+                self.quiet = 1
+            elif opt in ("-r", "--runs"):
+                self.runs = int(arg)
+            elif opt == "--image-type":
+                self.image_type = arg
+            elif opt == "--about":
+                # always make this absolute:
+                self.about_file = os.path.normpath(
+                    os.path.abspath(arg))
+            elif opt == "--numeric":
+                self.numeric = 1
+            elif opt == "--style":
+                self.style_file = os.path.abspath(arg)
+            elif opt == "--l2h-init":
+                self.l2h_init_files.append(os.path.abspath(arg))
+            elif opt == "--favicon":
+                self.favicon = arg
+            elif opt == "--up-link":
+                self.up_link = arg
+            elif opt == "--up-title":
+                self.up_title = arg
+            elif opt == "--global-module-index":
+                self.global_module_index = arg
+            elif opt == "--dir":
+                if os.sep == "\\":
+                    arg = re.sub("/", "\\\\", arg)
+                self.builddir = os.path.expanduser(arg)
+            elif opt == "--paper":
+                self.paper = arg
+            elif opt == "--dvips-safe":
+                self.dvips_safe = 1
+            #
+            # Format specifiers:
+            #
+            elif opt[2:] in self.ALL_FORMATS:
+                self.add_format(opt[2:])
+            elif opt == "--postscript":
+                # synonym for --ps
+                self.add_format("ps")
+        self.initialize()
+        #
+        # return the args to allow the caller access:
+        #
+        return args
+
+    def add_format(self, format):
+        """Add a format to the formats list if not present."""
+        if not format in self.formats:
+            if format == "ps":
+                # assume this is safe since we're going to run it anyway
+                self.dvips_safe = 1
+            self.formats.append(format)
+
+    def initialize(self):
+        """Complete initialization.  This is needed if parse() isn't used."""
+        # add the default format if no formats were specified:
+        if not self.formats:
+            self.formats = self.DEFAULT_FORMATS
+        # determine the base set of texinputs directories:
+        texinputs = os.environ.get("TEXINPUTS", "").split(os.pathsep)
+        if not texinputs:
+            texinputs = ['']
+        mydirs = [os.path.join(TOPDIR, "paper-" + self.paper),
+                  os.path.join(TOPDIR, "texinputs"),
+                  ]
+        if '' in texinputs:
+            i = texinputs.index('')
+            texinputs[i:i] = mydirs
+        else:
+            texinputs += mydirs
+        self.base_texinputs = texinputs
+        if self.builddir:
+            self.builddir = os.path.abspath(self.builddir)
+
+
+class Job:
+    latex_runs = 0
+
+    def __init__(self, options, path):
+        self.options = options
+        self.doctype = get_doctype(path)
+        self.filedir, self.doc = split_pathname(path)
+        self.builddir = os.path.abspath(options.builddir or self.doc)
+        if ("html" in options.formats or "text" in options.formats):
+            if not os.path.exists(self.builddir):
+                os.mkdir(self.builddir)
+            self.log_filename = os.path.join(self.builddir, self.doc + ".how")
+        else:
+            self.log_filename = os.path.abspath(self.doc + ".how")
+        if os.path.exists(self.log_filename):
+            os.unlink(self.log_filename)
+        l2hconf = self.doc + ".l2h"
+        if os.path.exists(l2hconf):
+            if os.path.exists(l2hconf + "~"):
+                os.unlink(l2hconf + "~")
+            os.rename(l2hconf, l2hconf + "~")
+        self.l2h_aux_init_file = self.doc + ".l2h"
+        self.write_l2h_aux_init_file()
+
+    def build(self):
+        self.setup_texinputs()
+        formats = self.options.formats
+        if "dvi" in formats or "ps" in formats:
+            self.build_dvi()
+        if "pdf" in formats:
+            self.build_pdf()
+        if "ps" in formats:
+            self.build_ps()
+        if "html" in formats:
+            self.require_temps()
+            self.build_html(self.builddir)
+            if self.options.icon_server == ".":
+                pattern = os.path.join(TOPDIR, "html", "icons",
+                                       "*." + self.options.image_type)
+                imgs = glob.glob(pattern)
+                if not imgs:
+                    self.warning(
+                        "Could not locate support images of type %s."
+                        % `self.options.image_type`)
+                for fn in imgs:
+                    new_fn = os.path.join(self.builddir, os.path.basename(fn))
+                    shutil.copyfile(fn, new_fn)
+        if "text" in formats:
+            self.require_temps()
+            tempdir = self.doc
+            need_html = "html" not in formats
+            if self.options.max_split_depth != 1:
+                fp = open(self.l2h_aux_init_file, "a")
+                fp.write("# re-hack this file for --text:\n")
+                l2hoption(fp, "MAX_SPLIT_DEPTH", "1")
+                fp.write("1;\n")
+                fp.close()
+                tempdir = self.doc + "-temp-html"
+                need_html = 1
+            if need_html:
+                self.build_html(tempdir, max_split_depth=1)
+            self.build_text(tempdir)
+        if self.options.discard_temps:
+            self.cleanup()
+
+    def setup_texinputs(self):
+        texinputs = [self.filedir] + self.options.base_texinputs
+        os.environ["TEXINPUTS"] = os.pathsep.join(texinputs)
+        self.message("TEXINPUTS=" + os.environ["TEXINPUTS"])
+
+    def build_aux(self, binary=None):
+        if binary is None:
+            binary = LATEX_BINARY
+        new_index(   "%s.ind" % self.doc, "genindex")
+        new_index("mod%s.ind" % self.doc, "modindex")
+        self.run("%s %s" % (binary, self.doc))
+        self.use_bibtex = check_for_bibtex(self.doc + ".aux")
+        self.latex_runs = 1
+
+    def build_dvi(self):
+        self.use_latex(LATEX_BINARY)
+
+    def build_pdf(self):
+        self.use_latex(PDFLATEX_BINARY)
+
+    def use_latex(self, binary):
+        self.require_temps(binary=binary)
+        if self.latex_runs < 2:
+            if os.path.isfile("mod%s.idx" % self.doc):
+                self.run("%s mod%s.idx" % (MAKEINDEX_BINARY, self.doc))
+            use_indfix = 0
+            if os.path.isfile(self.doc + ".idx"):
+                use_indfix = 1
+                # call to Doc/tools/fix_hack omitted; doesn't appear necessary
+                self.run("%s %s.idx" % (MAKEINDEX_BINARY, self.doc))
+                import indfix
+                indfix.process(self.doc + ".ind")
+            if self.use_bibtex:
+                self.run("%s %s" % (BIBTEX_BINARY, self.doc))
+            self.process_synopsis_files()
+            self.run("%s %s" % (binary, self.doc))
+            self.latex_runs = self.latex_runs + 1
+            if os.path.isfile("mod%s.idx" % self.doc):
+                self.run("%s -s %s mod%s.idx"
+                         % (MAKEINDEX_BINARY, ISTFILE, self.doc))
+            if use_indfix:
+                self.run("%s -s %s %s.idx"
+                         % (MAKEINDEX_BINARY, ISTFILE, self.doc))
+                indfix.process(self.doc + ".ind")
+            self.process_synopsis_files()
+        #
+        # and now finish it off:
+        #
+        if os.path.isfile(self.doc + ".toc") and binary == PDFLATEX_BINARY:
+            import toc2bkm
+            if self.doctype == "manual":
+                bigpart = "chapter"
+            else:
+                bigpart = "section"
+            toc2bkm.process(self.doc + ".toc", self.doc + ".bkm", bigpart)
+        if self.use_bibtex:
+            self.run("%s %s" % (BIBTEX_BINARY, self.doc))
+        self.run("%s %s" % (binary, self.doc))
+        self.latex_runs = self.latex_runs + 1
+
+    def process_synopsis_files(self):
+        synopsis_files = glob.glob(self.doc + "*.syn")
+        for path in synopsis_files:
+            uniqify_module_table(path)
+
+    def build_ps(self):
+        self.run("%s -N0 -o %s.ps %s" % (DVIPS_BINARY, self.doc, self.doc))
+
+    def build_html(self, builddir, max_split_depth=None):
+        if max_split_depth is None:
+            max_split_depth = self.options.max_split_depth
+        texfile = None
+        for p in os.environ["TEXINPUTS"].split(os.pathsep):
+            fn = os.path.join(p, self.doc + ".tex")
+            if os.path.isfile(fn):
+                texfile = fn
+                break
+        if not texfile:
+            self.warning("Could not locate %s.tex; aborting." % self.doc)
+            sys.exit(1)
+        # remove leading ./ (or equiv.); might avoid problems w/ dvips
+        if texfile[:2] == os.curdir + os.sep:
+            texfile = texfile[2:]
+        # build the command line and run LaTeX2HTML:
+        if not os.path.isdir(builddir):
+            os.mkdir(builddir)
+        else:
+            for fname in glob.glob(os.path.join(builddir, "*.html")):
+                os.unlink(fname)
+        args = [LATEX2HTML_BINARY,
+                "-init_file", self.l2h_aux_init_file,
+                "-dir", builddir,
+                texfile
+                ]
+        self.run(" ".join(args))     # XXX need quoting!
+        # ... postprocess
+        shutil.copyfile(self.options.style_file,
+                        os.path.join(builddir, self.doc + ".css"))
+        shutil.copyfile(os.path.join(builddir, self.doc + ".html"),
+                        os.path.join(builddir, "index.html"))
+        if max_split_depth != 1:
+            label_file = os.path.join(builddir, "labels.pl")
+            fp = open(label_file)
+            about_node = None
+            target = " = q/about/;\n"
+            x = len(target)
+            while 1:
+                line = fp.readline()
+                if not line:
+                    break
+                if line[-x:] == target:
+                    line = fp.readline()
+                    m = re.search(r"\|(node\d+\.[a-z]+)\|", line)
+                    about_node = m.group(1)
+                    shutil.copyfile(os.path.join(builddir, about_node),
+                                    os.path.join(builddir, "about.html"))
+                    break
+            if not self.options.numeric:
+                pwd = os.getcwd()
+                try:
+                    os.chdir(builddir)
+                    self.run("%s %s *.html" % (PERL_BINARY, NODE2LABEL_SCRIPT))
+                finally:
+                    os.chdir(pwd)
+        # These files need to be cleaned up here since builddir there
+        # can be more than one, so we clean each of them.
+        if self.options.discard_temps:
+            for fn in ("images.tex", "images.log", "images.aux"):
+                safe_unlink(os.path.join(builddir, fn))
+
+    def build_text(self, tempdir=None):
+        if tempdir is None:
+            tempdir = self.doc
+        indexfile = os.path.join(tempdir, "index.html")
+        self.run("%s -nolist -dump %s >%s.txt"
+                 % (LYNX_BINARY, indexfile, self.doc))
+
+    def require_temps(self, binary=None):
+        if not self.latex_runs:
+            self.build_aux(binary=binary)
+
+    def write_l2h_aux_init_file(self):
+        options = self.options
+        fp = open(self.l2h_aux_init_file, "w")
+        d = string_to_perl(os.path.dirname(L2H_INIT_FILE))
+        fp.write("package main;\n"
+                 "push (@INC, '%s');\n"
+                 "$mydir = '%s';\n"
+                 % (d, d))
+        fp.write(open(L2H_INIT_FILE).read())
+        for filename in options.l2h_init_files:
+            fp.write("\n# initialization code incorporated from:\n# ")
+            fp.write(filename)
+            fp.write("\n")
+            fp.write(open(filename).read())
+        fp.write("\n"
+                 "# auxillary init file for latex2html\n"
+                 "# generated by mkhowto\n"
+                 "$NO_AUTO_LINK = 1;\n"
+                 )
+        l2hoption(fp, "ABOUT_FILE", options.about_file)
+        l2hoption(fp, "ICONSERVER", options.icon_server)
+        l2hoption(fp, "IMAGE_TYPE", options.image_type)
+        l2hoption(fp, "ADDRESS", options.address)
+        l2hoption(fp, "MAX_LINK_DEPTH", options.max_link_depth)
+        l2hoption(fp, "MAX_SPLIT_DEPTH", options.max_split_depth)
+        l2hoption(fp, "EXTERNAL_UP_LINK", options.up_link)
+        l2hoption(fp, "EXTERNAL_UP_TITLE", options.up_title)
+        l2hoption(fp, "FAVORITES_ICON", options.favicon)
+        l2hoption(fp, "GLOBAL_MODULE_INDEX", options.global_module_index)
+        l2hoption(fp, "DVIPS_SAFE", options.dvips_safe)
+        fp.write("1;\n")
+        fp.close()
+
+    def cleanup(self):
+        self.__have_temps = 0
+        for pattern in ("%s.aux", "%s.log", "%s.out", "%s.toc", "%s.bkm",
+                        "%s.idx", "%s.ilg", "%s.ind", "%s.pla",
+                        "%s.bbl", "%s.blg",
+                        "mod%s.idx", "mod%s.ind", "mod%s.ilg",
+                        ):
+            safe_unlink(pattern % self.doc)
+        map(safe_unlink, glob.glob(self.doc + "*.syn"))
+        for spec in ("IMG*", "*.pl", "WARNINGS", "index.dat", "modindex.dat"):
+            pattern = os.path.join(self.doc, spec)
+            map(safe_unlink, glob.glob(pattern))
+        if "dvi" not in self.options.formats:
+            safe_unlink(self.doc + ".dvi")
+        if os.path.isdir(self.doc + "-temp-html"):
+            shutil.rmtree(self.doc + "-temp-html", ignore_errors=1)
+        if not self.options.logging:
+            os.unlink(self.log_filename)
+        if not self.options.debugging:
+            os.unlink(self.l2h_aux_init_file)
+
+    def run(self, command):
+        self.message(command)
+        if sys.platform.startswith("win"):
+            rc = os.system(command)
+        else:
+            rc = os.system("(%s) </dev/null >>%s 2>&1"
+                           % (command, self.log_filename))
+        if rc:
+            self.warning(
+                "Session transcript and error messages are in %s."
+                % self.log_filename)
+            result = 1
+            if hasattr(os, "WIFEXITED"):
+                if os.WIFEXITED(rc):
+                    result = os.WEXITSTATUS(rc)
+                    self.warning("Exited with status %s." % result)
+                else:
+                    self.warning("Killed by signal %s." % os.WSTOPSIG(rc))
+            else:
+                self.warning("Return code: %s" % rc)
+            sys.stderr.write("The relevant lines from the transcript are:\n")
+            sys.stderr.write("-" * 72 + "\n")
+            sys.stderr.writelines(get_run_transcript(self.log_filename))
+            sys.exit(result)
+
+    def message(self, msg):
+        msg = "+++ " + msg
+        if not self.options.quiet:
+            print msg
+        self.log(msg + "\n")
+
+    def warning(self, msg):
+        msg = "*** %s\n" % msg
+        sys.stderr.write(msg)
+        self.log(msg)
+
+    def log(self, msg):
+        fp = open(self.log_filename, "a")
+        fp.write(msg)
+        fp.close()
+
+
+def get_run_transcript(filename):
+    """Return lines from the transcript file for the most recent run() call."""
+    fp = open(filename)
+    lines = fp.readlines()
+    fp.close()
+    lines.reverse()
+    L = []
+    for line in lines:
+        L.append(line)
+        if line[:4] == "+++ ":
+            break
+    L.reverse()
+    return L
+
+
+def safe_unlink(path):
+    """Unlink a file without raising an error if it doesn't exist."""
+    try:
+        os.unlink(path)
+    except os.error:
+        pass
+
+
+def split_pathname(path):
+    path = os.path.abspath(path)
+    dirname, basename = os.path.split(path)
+    if basename[-4:] == ".tex":
+        basename = basename[:-4]
+    return dirname, basename
+
+
+_doctype_rx = re.compile(r"\\documentclass(?:\[[^]]*\])?{([a-zA-Z]*)}")
+def get_doctype(path):
+    fp = open(path)
+    doctype = None
+    while 1:
+        line = fp.readline()
+        if not line:
+            break
+        m = _doctype_rx.match(line)
+        if m:
+            doctype = m.group(1)
+            break
+    fp.close()
+    return doctype
+
+
+def main():
+    options = Options()
+    try:
+        args = options.parse(sys.argv[1:])
+    except getopt.error, msg:
+        error(options, msg)
+    if not args:
+        # attempt to locate single .tex file in current directory:
+        args = glob.glob("*.tex")
+        if not args:
+            error(options, "No file to process.")
+        if len(args) > 1:
+            error(options, "Could not deduce which files should be processed.")
+    #
+    # parameters are processed, let's go!
+    #
+    for path in args:
+        Job(options, path).build()
+
+
+def l2hoption(fp, option, value):
+    if value:
+        fp.write('$%s = "%s";\n' % (option, string_to_perl(str(value))))
+
+
+_to_perl = {}
+for c in map(chr, range(1, 256)):
+    _to_perl[c] = c
+_to_perl["@"] = "\\@"
+_to_perl["$"] = "\\$"
+_to_perl['"'] = '\\"'
+
+def string_to_perl(s):
+    return ''.join(map(_to_perl.get, s))
+
+
+def check_for_bibtex(filename):
+    fp = open(filename)
+    pos = fp.read().find(r"\bibdata{")
+    fp.close()
+    return pos >= 0
+
+def uniqify_module_table(filename):
+    lines = open(filename).readlines()
+    if len(lines) > 1:
+        if lines[-1] == lines[-2]:
+            del lines[-1]
+    open(filename, "w").writelines(lines)
+
+
+def new_index(filename, label="genindex"):
+    fp = open(filename, "w")
+    fp.write(r"""\
+\begin{theindex}
+\label{%s}
+\end{theindex}
+""" % label)
+    fp.close()
+
+
+if __name__ == "__main__":
+    main()


Property changes on: vendor/Python/current/Doc/tools/mkhowto
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Doc/tools/mkinfo
===================================================================
--- vendor/Python/current/Doc/tools/mkinfo	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/tools/mkinfo	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,65 @@
+#! /bin/sh
+#  -*- Ksh -*-
+
+#  Script to drive the HTML-info conversion process.
+#  Pass in upto three parameters:
+#  - the name of the main tex file
+#  - the name of the output file in texi format (optional)
+#  - the name of the output file in info format (optional)
+#
+#  Written by Fred L. Drake, Jr. <fdrake at acm.org>
+
+EMACS=${EMACS:-emacs}
+MAKEINFO=${MAKEINFO:-makeinfo}
+
+
+# Normalize file name since something called by html2texi.pl seems to
+# screw up with relative path names.
+FILENAME="$1"
+DOCDIR=`dirname "$FILENAME"`
+DOCFILE=`basename "$FILENAME"`
+DOCNAME=`basename "$FILENAME" .tex`
+if [ $# -gt 1 ]; then
+    TEXINAME="$2"
+else
+    TEXINAME="python-$DOCNAME.texi"
+fi
+if [ $# -gt 2 ]; then
+    INFONAME="$3"
+else
+    INFONAME="python-$DOCNAME.info"
+fi
+
+# Now build the real directory names, and locate our support stuff:
+WORKDIR=`pwd`
+cd `dirname $0`
+TOOLSDIR=`pwd`
+cd $DOCDIR
+DOCDIR=`pwd`
+cd $WORKDIR
+
+COMMONDIR="`dirname $DOCDIR`/commontex"
+
+
+run() {
+    # show what we're doing, like make does:
+    echo "$*"
+    "$@" || exit $?
+}
+
+
+# generate the Texinfo file:
+
+run $EMACS -batch -q --no-site-file -l $TOOLSDIR/py2texi.el \
+    --eval "(setq py2texi-dirs '(\"$DOCDIR\" \"$COMMONDIR\" \"../texinputs\"))" \
+    --eval "(setq py2texi-texi-file-name \"$TEXINAME\")" \
+    --eval "(setq py2texi-info-file-name \"$INFONAME\")" \
+    --eval "(py2texi \"$DOCDIR/$DOCFILE\")" \
+    -f kill-emacs
+echo Done
+
+
+# generate the .info files:
+
+run $MAKEINFO --footnote-style end --fill-column 72 \
+	      --paragraph-indent 0 --output=$INFONAME $TEXINAME


Property changes on: vendor/Python/current/Doc/tools/mkinfo
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Doc/tools/mkmodindex
===================================================================
--- vendor/Python/current/Doc/tools/mkmodindex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/tools/mkmodindex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,158 @@
+#! /usr/bin/env python
+#  -*- Python -*-
+
+"""usage: %(program)s [options] file...
+
+Supported options:
+
+    --address addr
+    -a addr         Set the address text to include at the end of the generated
+                    HTML; this should be used for contact information.
+    --columns cols
+    -c cols         Set the number of columns each index section should be
+                    displayed in.  The default is 1.
+    --help
+    -h              Display this help message.
+    --letters
+    -l              Split the output into sections by letter.
+    --output file
+    -o file         Write output to 'file' instead of standard out.
+    --iconserver is Use 'is' as the directory containing icons for the
+                    navigation bar.  The default is 'icons'.
+    --title str     Set the page title to 'str'.  The default is 'Global
+                    Module Index'.
+    --uplink url    Set the upward link URL.  The default is './'.
+    --uptitle str   Set the upward link title.  The default is 'Python
+                    Documentation Index'.
+"""
+import os
+import re
+import sys
+
+from xml.sax.saxutils import quoteattr
+
+import buildindex
+import support
+
+
+class IndexOptions(support.Options):
+    aesop_type = "links"
+
+    def __init__(self):
+        support.Options.__init__(self)
+        self.add_args("l", ["letters"])
+        self.letters = 0
+
+    def handle_option(self, opt, val):
+        if opt in ("-l", "--letters"):
+            self.letters = 1
+
+    def usage(self):
+        program = os.path.basename(sys.argv[0])
+        print __doc__ % {"program": program}
+
+    links = [
+        ('author', 'acks.html',  'Acknowledgements'),
+        ('help',   'about.html', 'About the Python Documentation'),
+        ]
+
+    def get_header(self):
+        header = support.Options.get_header(self)
+        s = ''
+        for rel, href, title in self.links:
+            s += '<link rel="%s" href="%s"' % (rel, href)
+            if title:
+                s += ' title=' + quoteattr(title)
+            s += '>\n  '
+        return header.replace("<link ", s + "<link ", 1)
+
+
+class Node(buildindex.Node):
+    def __init__(self, link, str, seqno, platinfo):
+        self.annotation = platinfo or None
+        if str[0][-5:] == "</tt>":
+            str = str[:-5]
+        self.modname = str
+        buildindex.Node.__init__(self, link, self.modname, seqno)
+        if platinfo:
+            s = '<tt class="module">%s</tt> %s' \
+                % (self.modname, self.annotation)
+        else:
+            s = '<tt class="module">%s</tt>' % str
+        self.text = [s]
+
+    def __str__(self):
+        if self.annotation:
+            return '<tt class="module">%s</tt> %s' \
+                   % (self.modname, self.annotation)
+        else:
+            return '<tt class="module">%s</tt>' % self.modname
+
+_rx = re.compile(
+    "<dt><a href=['\"](module-.*\.html)(?:#l2h-\d+)?['\"]>"
+    "<tt class=['\"]module['\"]>([a-zA-Z_][a-zA-Z0-9_.]*)</tt>\s*(<em>"
+    "\(<span class=['\"]platform['\"]>.*</span>\)</em>)?</a>")
+
+def main():
+    options = IndexOptions()
+    options.variables["title"] = "Global Module Index"
+    options.parse(sys.argv[1:])
+    args = options.args
+    if not args:
+        args = ["-"]
+    #
+    # Collect the input data:
+    #
+    nodes = []
+    has_plat_flag = 0
+    for ifn in args:
+        if ifn == "-":
+            ifp = sys.stdin
+            dirname = ''
+        else:
+            ifp = open(ifn)
+            dirname = os.path.dirname(ifn)
+        while 1:
+            line = ifp.readline()
+            if not line:
+                break
+            m = _rx.match(line)
+            if m:
+                # This line specifies a module!
+                basename, modname, platinfo = m.group(1, 2, 3)
+                has_plat_flag = has_plat_flag or platinfo
+                linkfile = os.path.join(dirname, basename)
+                nodes.append(Node('<a href="%s">' % linkfile, modname,
+                                  len(nodes), platinfo))
+        ifp.close()
+    #
+    # Generate all output:
+    #
+    num_nodes = len(nodes)
+    # Here's the HTML generation:
+    parts = [options.get_header(),
+             buildindex.process_nodes(nodes, options.columns, options.letters),
+             options.get_footer(),
+             ]
+    if has_plat_flag:
+        parts.insert(1, PLAT_DISCUSS)
+    html = ''.join(parts)
+    program = os.path.basename(sys.argv[0])
+    fp = options.get_output_file()
+    fp.write(html.rstrip() + "\n")
+    if options.outputfile == "-":
+        sys.stderr.write("%s: %d index nodes\n" % (program, num_nodes))
+    else:
+        print
+        print "%s: %d index nodes" % (program, num_nodes)
+
+
+PLAT_DISCUSS = """
+<p> Some module names are followed by an annotation indicating what
+platform they are available on.</p>
+
+"""
+
+
+if __name__ == "__main__":
+    main()


Property changes on: vendor/Python/current/Doc/tools/mkmodindex
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Doc/tools/mkpkglist
===================================================================
--- vendor/Python/current/Doc/tools/mkpkglist	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/tools/mkpkglist	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,85 @@
+#! /usr/bin/env python
+#
+# Simple script to create the table that lists the packages available
+# for download.  This expects the downloadable files and the Makefile
+# to be in the current directory.
+#
+# The output of this script can be pasted directly into the download
+# page for the documentation.
+
+import os
+import sys
+
+from os.path import isfile
+
+
+PKG_TYPES = [
+    # human name, filename prefix
+    ("HTML", "html"),
+    ("PDF (US-Letter)", "pdf-letter"),
+    ("PDF (A4)", "pdf-a4"),
+    ("PostScript (US-Letter)", "postscript-letter"),
+    ("PostScript (A4)", "postscript-a4"),
+    ("GNU info", "info"),
+    ("iSilo", "isilo"),
+    ("LaTeX", "latex"),
+    ]
+
+getversioninfo = os.path.join(os.path.dirname(__file__), "getversioninfo")
+fp = os.popen('"%s" "%s"' % (sys.executable, getversioninfo), "r")
+release = fp.readline().strip()
+fp.close()
+
+print '''\
+<table border="1" cellpadding="3" align="center">
+  <thead>
+    <tr bgcolor="#99ccff"><th rowspan="2">Content</th>
+                          <th colspan="3">Format</th></tr>
+    <tr bgcolor="#99ccff"><th>ZIP</th><th>GZip</th><th>BZip2</th></tr>
+    </thead>
+  <tbody>'''
+
+# formatted using FILE_TEMPLATE % (release, prefix, release, extension)
+FILE_TEMPLATE = '''\
+        <td><a href="../../ftp/python/doc/%s/%s-%s%s"
+            >%dK</a></td>'''
+
+NO_FILE_TEMPLATE = '''\
+        <td>&nbsp;</td>'''
+
+def get_size(prefix, ext):
+    fn = "%s-%s%s" % (prefix, release, ext)
+    return int(round(os.path.getsize(fn) / 1024.0))
+
+def get_file_cell(prefix, ext, have):
+    if have:
+        kb = get_size(prefix, ext)
+        return FILE_TEMPLATE % (release, prefix, release, ext, kb)
+    else:
+        return NO_FILE_TEMPLATE
+
+for name, prefix in PKG_TYPES:
+    zip_fn = "%s-%s.zip" % (prefix, release)
+    tgz_fn = "%s-%s.tgz" % (prefix, release)
+    bz2_fn = "%s-%s.tar.bz2" % (prefix, release)
+
+    have_zip = isfile(zip_fn)
+    have_tgz = isfile(tgz_fn)
+    have_bz2 = isfile(bz2_fn)
+
+    have_some = have_zip or have_tgz or have_bz2
+
+    if not have_some:
+        print "    <!--"
+    print "    <tr><td>%s</td>" % name
+    print get_file_cell(prefix, ".zip", have_zip)
+    print get_file_cell(prefix, ".tgz", have_tgz)
+    print get_file_cell(prefix, ".tar.bz2", have_bz2)
+    print "      </tr>"
+    if not have_some:
+        print "      -->"
+
+print '''\
+    </tbody>
+</table>
+'''


Property changes on: vendor/Python/current/Doc/tools/mkpkglist
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Doc/tools/mksourcepkg
===================================================================
--- vendor/Python/current/Doc/tools/mksourcepkg	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/tools/mksourcepkg	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,164 @@
+#! /usr/bin/env python
+#  -*- Python -*-
+
+"""%(program)s - script to create the latex source distribution
+
+usage:
+     %(program)s [-t|--tools] release [tag]
+
+with -t|--tools:  doesn't include the documents, only the framework
+
+without [tag]:  generate from the current version that's checked in
+     	   (*NOT* what's in the current directory!)
+
+with [tag]:  generate from the named tag
+"""
+#* should be modified to get the Python version number automatically
+#  from the Makefile or someplace.
+
+import getopt
+import glob
+import os
+import re
+import shutil
+import sys
+import tempfile
+
+try:
+    __file__
+except NameError:
+    __file__ = sys.argv[0]
+
+tools = os.path.dirname(os.path.abspath(__file__))
+Doc = os.path.dirname(tools)
+patchlevel_tex = os.path.join(Doc, "commontex", "patchlevel.tex")
+
+quiet = 0
+rx = re.compile(r":ext:(?:[a-zA-Z0-9]+@)?cvs\.([a-zA-Z0-9]+).sourceforge.net:"
+                r"/cvsroot/\1")
+
+
+def main():
+     global quiet
+     anonymous = False
+     try:
+          opts, args = getopt.getopt(sys.argv[1:], "Aabgtzq",
+                                     ["all", "bzip2", "gzip", "tools", "zip",
+                                      "quiet", "anonymous"])
+     except getopt.error, e:
+          usage(warning=str(e))
+          sys.exit(2)
+     if len(args) not in (1, 2):
+          usage(warning="wrong number of parameters")
+          sys.exit(2)
+     tools = 0
+     formats = {}
+     for opt, arg in opts:
+          if opt in ("-t", "--tools"):
+               tools = 1
+          elif opt in ("-q", "--quiet"):
+               quiet = quiet + 1
+          elif opt in ("-b", "--bzip2"):
+               formats["bzip2"] = 1
+          elif opt in ("-g", "--gzip"):
+               formats["gzip"] = 1
+          elif opt in ("-z", "--zip"):
+               formats["zip"] = 1
+          elif opt in ("-a", "--all"):
+               formats["bzip2"] = 1
+               formats["gzip"] = 1
+               formats["zip"] = 1
+          elif opt in ("-A", "--anonymous"):
+               anonymous = True
+     if formats:
+          # make order human-predictable
+          formats = formats.keys()
+          formats.sort()
+     else:
+          formats = ["gzip"]
+     release = args[0]
+     svntag = None
+     if len(args) > 1:
+          svntag = args[1]
+     tempdir = tempfile.mktemp()
+     os.mkdir(tempdir)
+     pkgdir = os.path.join(tempdir, "Python-Docs-" + release)
+     pwd = os.getcwd()
+     mydir = os.path.abspath(os.path.dirname(sys.argv[0]))
+     os.chdir(tempdir)
+     if not quiet:
+          print "--- current directory is:", tempdir
+     if not svntag:
+         svntag = "trunk"
+     svnbase = "http://svn.python.org/projects/python"
+     run("svn export %s/%s/Doc Python-Docs-%s"
+         % (svnbase, svntag, release))
+
+     # Copy in the version informtation, if we're not just going to
+     # rip it back out:
+     if not tools:
+          if not os.path.exists(patchlevel_tex):
+               run(os.path.join(here, "getversioninfo"))
+          dest = os.path.join("Python-Docs-" + release, "commontex",
+                              "patchlevel.tex")
+          shutil.copyfile(patchlevel_tex, dest)
+
+     # Copy in the license file:
+     LICENSE = os.path.normpath(
+          os.path.join(mydir, os.pardir, os.pardir, "LICENSE"))
+     shutil.copyfile(LICENSE, "LICENSE")
+     if tools:
+          archive = "doctools-" + release
+          # we don't want the actual documents in this case:
+          for d in ("api", "dist", "doc", "ext", "inst",
+                    "lib", "mac", "ref", "tut", "commontex"):
+               shutil.rmtree(os.path.join(pkgdir, d))
+     else:
+          archive = "latex-" + release
+
+     # XXX should also remove the .cvsignore files at this point
+
+     os.chdir(tempdir)
+     archive = os.path.join(pwd, archive)
+     for format in formats:
+          if format == "bzip2":
+               run("tar cf - Python-Docs-%s | bzip2 -9 >%s.tar.bz2"
+                   % (release, archive))
+          elif format == "gzip":
+               run("tar cf - Python-Docs-%s | gzip -9 >%s.tgz"
+                   % (release, archive))
+          elif format == "zip":
+               if os.path.exists(archive + ".zip"):
+                    os.unlink(archive + ".zip")
+               run("zip -q -r9 %s.zip Python-Docs-%s"
+                   % (archive, release))
+
+     # clean up the work area:
+     os.chdir(pwd)
+     shutil.rmtree(tempdir)
+
+
+def run(cmd):
+     if quiet < 2:
+          print "+++", cmd
+     if quiet:
+          cmd = "%s >/dev/null" % cmd
+     rc = os.system(cmd)
+     if rc:
+          sys.exit(rc)
+
+
+def usage(warning=None):
+     stdout = sys.stdout
+     sys.stdout = sys.stderr
+     program = os.path.basename(sys.argv[0])
+     try:
+          if warning:
+               print "%s: %s\n" % (program, warning)
+          print __doc__ % {"program": program}
+     finally:
+          sys.stdout = stdout
+
+
+if __name__ == "__main__":
+     main()


Property changes on: vendor/Python/current/Doc/tools/mksourcepkg
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Doc/tools/node2label.pl
===================================================================
--- vendor/Python/current/Doc/tools/node2label.pl	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/tools/node2label.pl	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,71 @@
+#! /usr/bin/env perl
+
+# On Cygwin, we actually have to generate a temporary file when doing
+# the inplace edit, or we'll get permission errors.  Not sure who's
+# bug this is, except that it isn't ours.  To deal with this, we
+# generate backups during the edit phase and remove them at the end.
+#
+use English;
+$INPLACE_EDIT = '.bak';
+
+# read the labels, then reverse the mappings
+require "labels.pl";
+
+%nodes = ();
+my $key;
+# sort so that we get a consistent assignment for nodes with multiple labels 
+foreach $label (sort keys %external_labels) {
+  #
+  # If the label can't be used as a filename on non-Unix platforms,
+  # skip it.  Such labels may be used internally within the documentation,
+  # but will never be used for filename generation.
+  #
+  if ($label =~ /^([-.a-zA-Z0-9]+)$/) {
+    $key = $external_labels{$label};
+    $key =~ s|^/||;
+    $nodes{$key} = $label;
+  }
+}
+
+# This adds the "internal" labels added for indexing.  These labels will not
+# be used for file names.
+require "intlabels.pl";
+foreach $label (keys %internal_labels) {
+  $key = $internal_labels{$label};
+  $key =~ s|^/||;
+  if (defined($nodes{$key})) {
+    $nodes{$label} = $nodes{$key};
+  }
+}
+
+# collect labels that have been used
+%newnames = ();
+
+while (<>) {
+  # don't want to do one s/// per line per node
+  # so look for lines with hrefs, then do s/// on nodes present
+  if (/(HREF|href)=[\"\']node\d+\.html[\#\"\']/) {
+    @parts = split(/(HREF|href)\=[\"\']/);
+    shift @parts;
+    for $node (@parts) {
+      $node =~ s/[\#\"\'].*$//g;
+      chomp($node);
+      if (defined($nodes{$node})) {
+	$label = $nodes{$node};
+	if (s/(HREF|href)=([\"\'])$node([\#\"\'])/href=$2$label.html$3/g) {
+	  s/(HREF|href)=([\"\'])$label.html/href=$2$label.html/g;
+	  $newnames{$node} = "$label.html";
+	}
+      }
+    }
+  }
+  print;
+}
+
+foreach $oldname (keys %newnames) {
+  rename($oldname, $newnames{$oldname});
+}
+
+foreach $filename (glob('*.bak')) {
+  unlink($filename);
+}


Property changes on: vendor/Python/current/Doc/tools/node2label.pl
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Doc/tools/prechm.py
===================================================================
--- vendor/Python/current/Doc/tools/prechm.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/tools/prechm.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,519 @@
+"""
+    Makes the necesary files to convert from plain html of
+    Python 1.5 and 1.5.x Documentation to
+    Microsoft HTML Help format version 1.1
+    Doesn't change the html's docs.
+
+    by hernan.foffani at iname.com
+    no copyright and no responsabilities.
+
+    modified by Dale Nagata for Python 1.5.2
+
+    Renamed from make_chm.py to prechm.py, and checked into the Python
+    project, 19-Apr-2002 by Tim Peters.  Assorted modifications by Tim
+    and Fred Drake.  Obtained from Robin Dunn's .chm packaging of the
+    Python 2.2 docs, at <http://alldunn.com/python/>.
+"""
+
+import sys
+import os
+from formatter import NullWriter, AbstractFormatter
+from htmllib import HTMLParser
+import getopt
+import cgi
+
+usage_mode = '''
+Usage: prechm.py [-c] [-k] [-p] [-v 1.5[.x]] filename
+    -c: does not build filename.hhc (Table of Contents)
+    -k: does not build filename.hhk (Index)
+    -p: does not build filename.hhp (Project File)
+    -v 1.5[.x]: makes help for the python 1.5[.x] docs
+        (default is python 1.5.2 docs)
+'''
+
+# Project file (*.hhp) template.  'arch' is the file basename (like
+# the pythlp in pythlp.hhp); 'version' is the doc version number (like
+# the 2.2 in Python 2.2).
+# The magical numbers in the long line under [WINDOWS] set most of the
+# user-visible features (visible buttons, tabs, etc).
+# About 0x10384e:  This defines the buttons in the help viewer.  The
+# following defns are taken from htmlhelp.h.  Not all possibilities
+# actually work, and not all those that work are available from the Help
+# Workshop GUI.  In particular, the Zoom/Font button works and is not
+# available from the GUI.  The ones we're using are marked with 'x':
+#
+#    0x000002   Hide/Show   x
+#    0x000004   Back        x
+#    0x000008   Forward     x
+#    0x000010   Stop
+#    0x000020   Refresh
+#    0x000040   Home        x
+#    0x000080   Forward
+#    0x000100   Back
+#    0x000200   Notes
+#    0x000400   Contents
+#    0x000800   Locate      x
+#    0x001000   Options     x
+#    0x002000   Print       x
+#    0x004000   Index
+#    0x008000   Search
+#    0x010000   History
+#    0x020000   Favorites
+#    0x040000   Jump 1
+#    0x080000   Jump 2
+#    0x100000   Zoom/Font   x
+#    0x200000   TOC Next
+#    0x400000   TOC Prev
+
+project_template = '''
+[OPTIONS]
+Compiled file=%(arch)s.chm
+Contents file=%(arch)s.hhc
+Default Window=%(arch)s
+Default topic=index.html
+Display compile progress=No
+Full text search stop list file=%(arch)s.stp
+Full-text search=Yes
+Index file=%(arch)s.hhk
+Language=0x409
+Title=Python %(version)s Documentation
+
+[WINDOWS]
+%(arch)s="Python %(version)s Documentation","%(arch)s.hhc","%(arch)s.hhk",\
+"index.html","index.html",,,,,0x63520,220,0x10384e,[0,0,1024,768],,,,,,,0
+
+[FILES]
+'''
+
+contents_header = '''\
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<HTML>
+<HEAD>
+<meta name="GENERATOR" content="Microsoft&reg; HTML Help Workshop 4.1">
+<!-- Sitemap 1.0 -->
+</HEAD><BODY>
+<OBJECT type="text/site properties">
+        <param name="Window Styles" value="0x801227">
+        <param name="ImageType" value="Folder">
+</OBJECT>
+<UL>
+'''
+
+contents_footer = '''\
+</UL></BODY></HTML>
+'''
+
+object_sitemap = '''\
+<OBJECT type="text/sitemap">
+    <param name="Name" value="%s">
+    <param name="Local" value="%s">
+</OBJECT>
+'''
+
+# List of words the full text search facility shouldn't index.  This
+# becomes file ARCH.stp.  Note that this list must be pretty small!
+# Different versions of the MS docs claim the file has a maximum size of
+# 256 or 512 bytes (including \r\n at the end of each line).
+# Note that "and", "or", "not" and "near" are operators in the search
+# language, so no point indexing them even if we wanted to.
+stop_list = '''
+a  and  are  as  at
+be  but  by
+for
+if  in  into  is  it
+near  no  not
+of  on  or
+such
+that  the  their  then  there  these  they  this  to
+was  will  with
+'''
+
+# s is a string or None.  If None or empty, return None.  Else tack '.html'
+# on to the end, unless it's already there.
+def addhtml(s):
+    if s:
+        if not s.endswith('.html'):
+            s += '.html'
+    return s
+
+# Convenience class to hold info about "a book" in HTMLHelp terms == a doc
+# directory in Python terms.
+class Book:
+    def __init__(self, directory, title, firstpage,
+                 contentpage=None, indexpage=None):
+        self.directory   = directory
+        self.title       = title
+        self.firstpage   = addhtml(firstpage)
+        self.contentpage = addhtml(contentpage)
+        self.indexpage   = addhtml(indexpage)
+
+# Library Doc list of books:
+# each 'book' : (Dir, Title, First page, Content page, Index page)
+supported_libraries = {
+    '2.5':
+    [
+        Book('.', 'Main page', 'index'),
+        Book('.', 'Global Module Index', 'modindex'),
+        Book('whatsnew', "What's New", 'index', 'contents'),
+        Book('tut','Tutorial','tut','node2'),
+        Book('lib','Library Reference','lib','contents','genindex'),
+        Book('ref','Language Reference','ref','contents','genindex'),
+        Book('mac','Macintosh Reference','mac','contents','genindex'),
+        Book('ext','Extending and Embedding','ext','contents'),
+        Book('api','Python/C API','api','contents','genindex'),
+        Book('doc','Documenting Python','doc','contents'),
+        Book('inst','Installing Python Modules', 'inst', 'index'),
+        Book('dist','Distributing Python Modules', 'dist', 'index', 'genindex'),
+    ],
+
+    '2.4':
+    [
+        Book('.', 'Main page', 'index'),
+        Book('.', 'Global Module Index', 'modindex'),
+        Book('whatsnew', "What's New", 'index', 'contents'),
+        Book('tut','Tutorial','tut','node2'),
+        Book('lib','Library Reference','lib','contents','genindex'),
+        Book('ref','Language Reference','ref','contents','genindex'),
+        Book('mac','Macintosh Reference','mac','contents','genindex'),
+        Book('ext','Extending and Embedding','ext','contents'),
+        Book('api','Python/C API','api','contents','genindex'),
+        Book('doc','Documenting Python','doc','contents'),
+        Book('inst','Installing Python Modules', 'inst', 'index'),
+        Book('dist','Distributing Python Modules', 'dist', 'index', 'genindex'),
+    ],
+
+    '2.3':
+    [
+        Book('.', 'Main page', 'index'),
+        Book('.', 'Global Module Index', 'modindex'),
+        Book('whatsnew', "What's New", 'index', 'contents'),
+        Book('tut','Tutorial','tut','node2'),
+        Book('lib','Library Reference','lib','contents','genindex'),
+        Book('ref','Language Reference','ref','contents','genindex'),
+        Book('mac','Macintosh Reference','mac','contents','genindex'),
+        Book('ext','Extending and Embedding','ext','contents'),
+        Book('api','Python/C API','api','contents','genindex'),
+        Book('doc','Documenting Python','doc','contents'),
+        Book('inst','Installing Python Modules', 'inst', 'index'),
+        Book('dist','Distributing Python Modules', 'dist', 'index'),
+    ],
+
+    '2.2':
+    [
+        Book('.', 'Main page', 'index'),
+        Book('.', 'Global Module Index', 'modindex'),
+        Book('whatsnew', "What's New", 'index', 'contents'),
+        Book('tut','Tutorial','tut','node2'),
+        Book('lib','Library Reference','lib','contents','genindex'),
+        Book('ref','Language Reference','ref','contents','genindex'),
+        Book('mac','Macintosh Reference','mac','contents','genindex'),
+        Book('ext','Extending and Embedding','ext','contents'),
+        Book('api','Python/C API','api','contents','genindex'),
+        Book('doc','Documenting Python','doc','contents'),
+        Book('inst','Installing Python Modules', 'inst', 'index'),
+        Book('dist','Distributing Python Modules', 'dist', 'index'),
+    ],
+
+    '2.1.1':
+    [
+        Book('.', 'Main page', 'index'),
+        Book('.', 'Global Module Index', 'modindex'),
+        Book('tut','Tutorial','tut','node2'),
+        Book('lib','Library Reference','lib','contents','genindex'),
+        Book('ref','Language Reference','ref','contents','genindex'),
+        Book('mac','Macintosh Reference','mac','contents','genindex'),
+        Book('ext','Extending and Embedding','ext','contents'),
+        Book('api','Python/C API','api','contents','genindex'),
+        Book('doc','Documenting Python','doc','contents'),
+        Book('inst','Installing Python Modules', 'inst', 'index'),
+        Book('dist','Distributing Python Modules', 'dist', 'index'),
+    ],
+
+    '2.0.0':
+    [
+        Book('.', 'Global Module Index', 'modindex'),
+        Book('tut','Tutorial','tut','node2'),
+        Book('lib','Library Reference','lib','contents','genindex'),
+        Book('ref','Language Reference','ref','contents','genindex'),
+        Book('mac','Macintosh Reference','mac','contents','genindex'),
+        Book('ext','Extending and Embedding','ext','contents'),
+        Book('api','Python/C API','api','contents','genindex'),
+        Book('doc','Documenting Python','doc','contents'),
+        Book('inst','Installing Python Modules', 'inst', 'contents'),
+        Book('dist','Distributing Python Modules', 'dist', 'contents'),
+    ],
+
+    # <dnagata at creo.com> Apr 17/99: library for 1.5.2 version:
+    # <hernan.foffani at iname.com> May 01/99: library for 1.5.2 (04/30/99):
+    '1.5.2':
+    [
+        Book('tut','Tutorial','tut','node2'),
+        Book('lib','Library Reference','lib','contents','genindex'),
+        Book('ref','Language Reference','ref','contents','genindex'),
+        Book('mac','Macintosh Reference','mac','contents','genindex'),
+        Book('ext','Extending and Embedding','ext','contents'),
+        Book('api','Python/C API','api','contents','genindex'),
+        Book('doc','Documenting Python','doc','contents')
+    ],
+
+    # library for 1.5.1 version:
+    '1.5.1':
+    [
+        Book('tut','Tutorial','tut','contents'),
+        Book('lib','Library Reference','lib','contents','genindex'),
+        Book('ref','Language Reference','ref-1','ref-2','ref-11'),
+        Book('ext','Extending and Embedding','ext','contents'),
+        Book('api','Python/C API','api','contents','genindex')
+    ],
+
+    # library for 1.5 version:
+    '1.5':
+    [
+        Book('tut','Tutorial','tut','node1'),
+        Book('lib','Library Reference','lib','node1','node268'),
+        Book('ref','Language Reference','ref-1','ref-2','ref-11'),
+        Book('ext','Extending and Embedding','ext','node1'),
+        Book('api','Python/C API','api','node1','node48')
+    ]
+}
+
+# AlmostNullWriter doesn't print anything; it just arranges to save the
+# text sent to send_flowing_data().  This is used to capture the text
+# between an anchor begin/end pair, e.g. for TOC entries.
+
+class AlmostNullWriter(NullWriter):
+
+    def __init__(self):
+        NullWriter.__init__(self)
+        self.saved_clear()
+
+    def send_flowing_data(self, data):
+        stripped = data.strip()
+        if stripped:    # don't bother to save runs of whitespace
+            self.saved.append(stripped)
+
+    # Forget all saved text.
+    def saved_clear(self):
+        self.saved = []
+
+    # Return all saved text as a string.
+    def saved_get(self):
+        return ' '.join(self.saved)
+
+class HelpHtmlParser(HTMLParser):
+
+    def __init__(self, formatter, path, output):
+        HTMLParser.__init__(self, formatter)
+        self.path = path    # relative path
+        self.ft = output    # output file
+        self.indent = 0     # number of tabs for pretty printing of files
+        self.proc = False   # True when actively processing, else False
+                            # (headers, footers, etc)
+        # XXX This shouldn't need to be a stack -- anchors shouldn't nest.
+        # XXX See SF bug <http://www.python.org/sf/546579>.
+        self.hrefstack = [] # stack of hrefs from anchor begins
+
+    def begin_group(self):
+        self.indent += 1
+        self.proc = True
+
+    def finish_group(self):
+        self.indent -= 1
+        # stop processing when back to top level
+        self.proc = self.indent > 0
+
+    def anchor_bgn(self, href, name, type):
+        if self.proc:
+            # XXX See SF bug <http://www.python.org/sf/546579>.
+            # XXX index.html for the 2.2.1 language reference manual contains
+            # XXX nested <a></a> tags in the entry for the section on blank
+            # XXX lines.  We want to ignore the nested part completely.
+            if len(self.hrefstack) == 0:
+                self.saved_clear()
+                self.hrefstack.append(href)
+
+    def anchor_end(self):
+        if self.proc:
+            # XXX See XXX above.
+            if self.hrefstack:
+                title = cgi.escape(self.saved_get(), True)
+                path = self.path + '/' + self.hrefstack.pop()
+                self.tab(object_sitemap % (title, path))
+
+    def start_dl(self, atr_val):
+        self.begin_group()
+
+    def end_dl(self):
+        self.finish_group()
+
+    def do_dt(self, atr_val):
+        # no trailing newline on purpose!
+        self.tab("<LI>")
+
+    # Write text to output file.
+    def write(self, text):
+        self.ft.write(text)
+
+    # Write text to output file after indenting by self.indent tabs.
+    def tab(self, text=''):
+        self.write('\t' * self.indent)
+        if text:
+            self.write(text)
+
+    # Forget all saved text.
+    def saved_clear(self):
+        self.formatter.writer.saved_clear()
+
+    # Return all saved text as a string.
+    def saved_get(self):
+        return self.formatter.writer.saved_get()
+
+class IdxHlpHtmlParser(HelpHtmlParser):
+    # nothing special here, seems enough with parent class
+    pass
+
+class TocHlpHtmlParser(HelpHtmlParser):
+
+    def start_dl(self, atr_val):
+        self.begin_group()
+        self.tab('<UL>\n')
+
+    def end_dl(self):
+        self.finish_group()
+        self.tab('</UL>\n')
+
+    def start_ul(self, atr_val):
+        self.begin_group()
+        self.tab('<UL>\n')
+
+    def end_ul(self):
+        self.finish_group()
+        self.tab('</UL>\n')
+
+    def do_li(self, atr_val):
+        # no trailing newline on purpose!
+        self.tab("<LI>")
+
+def index(path, indexpage, output):
+    parser = IdxHlpHtmlParser(AbstractFormatter(AlmostNullWriter()),
+                              path, output)
+    f = open(path + '/' + indexpage)
+    parser.feed(f.read())
+    parser.close()
+    f.close()
+
+def content(path, contentpage, output):
+    parser = TocHlpHtmlParser(AbstractFormatter(AlmostNullWriter()),
+                              path, output)
+    f = open(path + '/' + contentpage)
+    parser.feed(f.read())
+    parser.close()
+    f.close()
+
+def do_index(library, output):
+    output.write('<UL>\n')
+    for book in library:
+        print '\t', book.title, '-', book.indexpage
+        if book.indexpage:
+            index(book.directory, book.indexpage, output)
+    output.write('</UL>\n')
+
+def do_content(library, version, output):
+    output.write(contents_header)
+    for book in library:
+        print '\t', book.title, '-', book.firstpage
+        path = book.directory + "/" + book.firstpage
+        output.write('<LI>')
+        output.write(object_sitemap % (book.title, path))
+        if book.contentpage:
+            content(book.directory, book.contentpage, output)
+    output.write(contents_footer)
+
+# Fill in the [FILES] section of the project (.hhp) file.
+# 'library' is the list of directory description tuples from
+# supported_libraries for the version of the docs getting generated.
+def do_project(library, output, arch, version):
+    output.write(project_template % locals())
+    pathseen = {}
+    for book in library:
+        directory = book.directory
+        path = directory + '\\%s\n'
+        for page in os.listdir(directory):
+            if page.endswith('.html') or page.endswith('.css'):
+                fullpath = path % page
+                if fullpath not in pathseen:
+                    output.write(fullpath)
+                    pathseen[fullpath] = True
+
+def openfile(file):
+    try:
+        p = open(file, "w")
+    except IOError, msg:
+        print file, ":", msg
+        sys.exit(1)
+    return p
+
+def usage():
+    print usage_mode
+    sys.exit(0)
+
+def do_it(args = None):
+    if not args:
+        args = sys.argv[1:]
+
+    if not args:
+        usage()
+
+    try:
+        optlist, args = getopt.getopt(args, 'ckpv:')
+    except getopt.error, msg:
+        print msg
+        usage()
+
+    if not args or len(args) > 1:
+        usage()
+    arch = args[0]
+
+    version = None
+    for opt in optlist:
+        if opt[0] == '-v':
+            version = opt[1]
+            break
+    if not version:
+        usage()
+
+    library = supported_libraries[version]
+
+    if not (('-p','') in optlist):
+        fname = arch + '.stp'
+        f = openfile(fname)
+        print "Building stoplist", fname, "..."
+        words = stop_list.split()
+        words.sort()
+        for word in words:
+            print >> f, word
+        f.close()
+
+        f = openfile(arch + '.hhp')
+        print "Building Project..."
+        do_project(library, f, arch, version)
+        if version == '2.0.0':
+            for image in os.listdir('icons'):
+                f.write('icons'+ '\\' + image + '\n')
+
+        f.close()
+
+    if not (('-c','') in optlist):
+        f = openfile(arch + '.hhc')
+        print "Building Table of Content..."
+        do_content(library, version, f)
+        f.close()
+
+    if not (('-k','') in optlist):
+        f = openfile(arch + '.hhk')
+        print "Building Index..."
+        do_index(library, f)
+        f.close()
+
+if __name__ == '__main__':
+    do_it()

Added: vendor/Python/current/Doc/tools/push-docs.sh
===================================================================
--- vendor/Python/current/Doc/tools/push-docs.sh	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/tools/push-docs.sh	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,138 @@
+#! /bin/sh
+
+#  Script to push docs from my development area to SourceForge, where the
+#  update-docs.sh script unpacks them into their final destination.
+
+TARGETHOST=www.python.org
+TARGETDIR=/usr/home/fdrake/tmp
+
+PKGTYPE="bzip"  # must be one of: bzip, tar, zip  ("tar" implies gzip)
+
+TARGET="$TARGETHOST:$TARGETDIR"
+
+ADDRESSES='python-dev at python.org doc-sig at python.org python-list at python.org'
+
+TOOLDIR="`dirname $0`"
+VERSION=`$TOOLDIR/getversioninfo`
+
+# Set $EXTRA to something non-empty if this is a non-trunk version:
+EXTRA=`echo "$VERSION" | sed 's/^[0-9][0-9]*\.[0-9][0-9]*//'`
+
+if echo "$EXTRA" | grep -q '[.]' ; then
+    DOCLABEL="maintenance"
+    DOCTYPE="maint"
+else
+    DOCLABEL="development"
+    DOCTYPE="devel"
+fi
+
+DOCTYPE_SPECIFIED=false
+EXPLANATION=''
+ANNOUNCE=true
+
+getopt -T >/dev/null
+if [ $? -eq 4 ] ; then
+    # We have a sufficiently useful getopt(1) implementation.
+    eval "set -- `getopt -ssh m:p:qt:F: \"$@\"`"
+else
+    # This version of getopt doesn't support quoting of long options
+    # with spaces, so let's not rely on it at all.
+    :
+fi
+
+while [ "$#" -gt 0 ] ; do
+  case "$1" in
+      -m)
+          EXPLANATION="$2"
+          shift 2
+          ;;
+      -p)
+          PKGTYPE="$2"
+          shift 1
+          ;;
+      -q)
+          ANNOUNCE=false
+          shift 1
+          ;;
+      -t)
+          DOCTYPE="$2"
+          DOCTYPE_SPECIFIED=true
+          shift 2
+          ;;
+      -F)
+          EXPLANATION="`cat $2`"
+          shift 2
+          ;;
+      --)
+          shift 1
+          break
+          ;;
+      -*)
+          echo "Unknown option: $1" >&2
+          exit 2
+          ;;
+      *)
+          break
+          ;;
+  esac
+done
+if [ "$1" ] ; then
+    if [ "$EXPLANATION" ] ; then
+        echo "Explanation may only be given once!" >&2
+        exit 2
+    fi
+    EXPLANATION="$1"
+    shift
+fi
+
+START="`pwd`"
+MYDIR="`dirname $0`"
+cd "$MYDIR"
+MYDIR="`pwd`"
+
+if [ "$PKGTYPE" = bzip ] ; then
+    PKGEXT=tar.bz2
+elif [ "$PKGTYPE" = tar ] ; then
+    PKGEXT=tgz
+elif [ "$PKGTYPE" = zip ] ; then
+    PKGEXT=zip
+else
+    echo 1>&2 "unsupported package type: $PKGTYPE"
+    exit 2
+fi
+
+# switch to .../Doc/
+cd ..
+
+# If $DOCTYPE was not specified explicitly, look for .doctype in
+# .../Doc/ and use the content of that file if present.
+if $DOCTYPE_SPECIFIED ; then
+    :
+elif [ -f .doctype ] ; then
+    DOCTYPE="`cat .doctype`"
+fi
+
+make --no-print-directory ${PKGTYPE}html || exit $?
+PACKAGE="html-$VERSION.$PKGEXT"
+scp "$PACKAGE" tools/update-docs.sh $TARGET/ || exit $?
+ssh "$TARGETHOST" tmp/update-docs.sh $DOCTYPE $PACKAGE '&&' rm tmp/update-docs.sh || exit $?
+
+if $ANNOUNCE ; then
+    sendmail $ADDRESSES <<EOF
+To: $ADDRESSES
+From: "Fred L. Drake" <fdrake at acm.org>
+Subject: [$DOCLABEL doc updates]
+X-No-Archive: yes
+
+The $DOCLABEL version of the documentation has been updated:
+
+    http://$TARGETHOST/dev/doc/$DOCTYPE/
+
+$EXPLANATION
+
+A downloadable package containing the HTML is also available:
+
+    http://$TARGETHOST/dev/doc/python-docs-$DOCTYPE.$PKGEXT
+EOF
+    exit $?
+fi


Property changes on: vendor/Python/current/Doc/tools/push-docs.sh
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Doc/tools/py2texi.el
===================================================================
--- vendor/Python/current/Doc/tools/py2texi.el	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/tools/py2texi.el	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,970 @@
+;;; py2texi.el -- Conversion of Python LaTeX documentation to Texinfo
+
+;; Copyright (C) 2006  Jeroen Dekkers <jeroen at dekkers.cx>
+;; Copyright (C) 1998, 1999, 2001, 2002 Milan Zamazal
+
+;; Author: Milan Zamazal <pdm at zamazal.org>
+;; Version: $Id: py2texi.el 52974 2006-12-09 12:13:02Z matthias.klose $
+;; Keywords: python
+
+;; COPYRIGHT NOTICE
+;;
+;; This program is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published by the Free
+;; Software Foundation; either version 2, or (at your option) any later
+;; version.
+;;
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+;; for more details.
+;;
+;; You can find the GNU General Public License at
+;; http://www.gnu.org/copyleft/gpl.html
+;; or you can write to the Free Software Foundation, Inc., 59 Temple Place,
+;; Suite 330, Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;; This is a Q&D hack for conversion of Python manuals to on-line help format.
+;; I desperately needed usable online documenta for Python, so I wrote this.
+;; The result code is ugly and need not contain complete information from
+;; Python manuals.  I apologize for my ignorance, especially ignorance to
+;; python.sty.  Improvements of this convertor are welcomed.
+
+;; How to use it:
+;; Load this file and apply `M-x py2texi'.  You will be asked for name of a
+;; file to be converted.
+
+;; Where to find it:
+;; New versions of this code might be found at
+;; http://www.zamazal.org/software/python/py2texi/ .
+
+;;; Code:
+
+
+(require 'texinfo)
+(eval-when-compile
+  (require 'cl))
+
+
+(defvar py2texi-python-version "2.2"
+  "What to substitute for the \\version macro.")
+
+(defvar py2texi-python-short-version
+  (progn
+    (string-match "[0-9]+\\.[0-9]+" py2texi-python-version)
+    (match-string 0 py2texi-python-version))
+  "Short version number, usually set by the LaTeX commands.")
+
+(defvar py2texi-texi-file-name nil
+  "If non-nil, that string is used as the name of the Texinfo file.
+Otherwise a generated Texinfo file name is used.")
+
+(defvar py2texi-info-file-name nil
+  "If non-nil, that string is used as the name of the Info file.
+Otherwise a generated Info file name is used.")
+
+(defvar py2texi-stop-on-problems nil
+  "*If non-nil, stop when you encouter soft problem.")
+
+(defconst py2texi-environments
+  '(("abstract" 0 "@quotation" "@end quotation\n")
+    ("center" 0 "" "")
+    ("cfuncdesc" 3
+     (progn (setq findex t)
+	    "\n at table @code\n at item \\1 \\2(\\3)\n at findex \\2\n")
+     "@end table\n")
+    ("cmemberdesc" 3
+     "\n at table @code\n at item \\2 \\3\n"
+     "@end table\n")
+    ("classdesc" 2
+     (progn (setq obindex t)
+	    "\n at table @code\n at item \\1(\\2)\n at obindex \\1\n")
+     "@end table\n")
+    ("classdesc*" 1
+     (progn (setq obindex t)
+	    "\n at table @code\n at item \\1\n at obindex \\1\n")
+     "@end table\n")
+    ("comment" 0 "\n at ignore\n" "\n at end ignore\n")
+    ("csimplemacrodesc" 1
+     (progn (setq cindex t)
+	    "\n at table @code\n at item \\1\n at cindex \\1\n")
+     "@end table\n")     
+    ("ctypedesc" 1
+     (progn (setq cindex t)
+	    "\n at table @code\n at item \\1\n at cindex \\1\n")
+     "@end table\n")
+    ("cvardesc" 2
+     (progn (setq findex t)
+	    "\n at table @code\n at item \\1 \\2\n at findex \\2\n")
+     "@end table\n")
+    ("datadesc" 1
+     (progn (setq findex t)
+	    "\n at table @code\n at item \\1\n at findex \\1\n")
+     "@end table\n")
+    ("datadescni" 1 "\n at table @code\n at item \\1\n" "@end table\n")
+    ("definitions" 0 "@table @dfn" "@end table\n")
+    ("description" 0 "@table @samp" "@end table\n")
+    ("displaymath" 0 "" "")
+    ("document" 0
+     (concat "@defcodeindex mo\n"
+	     "@defcodeindex ob\n"
+	     "@titlepage\n"
+	     (format "@title " title "\n")
+	     (format "@author " author "\n")
+	     "@page\n"
+	     author-address
+	     "@end titlepage\n"
+	     "@node Top, , , (dir)\n")
+     (concat "@indices\n"
+	     "@contents\n"
+	     "@bye\n"))
+    ("enumerate" 0 "@enumerate" "@end enumerate")
+    ("envdesc" 2 (concat "\n at table @code"
+                         "\n at item @backslash{}begin@{\\1@}\\2")
+     "@end table\n")
+    ("excdesc" 1
+     (progn (setq obindex t)
+	    "\n at table @code\n at item \\1\n at obindex \\1\n")
+     "@end table\n")
+    ("excclassdesc" 2
+     (progn (setq obindex t)
+	    "\n at table @code\n at item \\1(\\2)\n at obindex \\1\n")
+     "@end table\n")
+    ("flushleft" 0 "" "")
+    ("fulllineitems" 0 "\n at table @code\n" "@end table\n")
+    ("funcdesc" 2
+     (progn (setq findex t)
+	    "\n at table @code\n at item \\1(\\2)\n at findex \\1\n")
+     "@end table\n")
+    ("funcdescni" 2 "\n at table @code\n at item \\1(\\2)\n" "@end table\n")
+    ("itemize" 0 "@itemize @bullet" "@end itemize\n")
+    ("list" 2 "\n at table @code\n" "@end table\n")
+    ("longtableii" 4 (concat "@multitable @columnfractions .5 .5\n"
+			     "@item \\3 @tab \\4\n"
+			     "@item ------- @tab ------ \n")
+     "@end multitable\n")
+    ("longtableiii" 5 (concat "@multitable @columnfractions .33 .33 .33\n"
+			      "@item \\3 @tab \\4 @tab \\5\n"
+			      "@item ------- @tab ------ @tab ------\n")
+     "@end multitable\n")
+    ("macrodesc" 2 (concat "\n at table @code"
+                           "\n at item \\1@{\\2@}")
+     "@end table\n")
+    ("memberdesc" 1
+     (progn (setq findex t)
+	    "\n at table @code\n at item \\1\n at findex \\1\n")
+     "@end table\n")
+    ("memberdescni" 1 "\n at table @code\n at item \\1\n" "@end table\n")
+    ("methoddesc" 2
+     (progn (setq findex t)
+	    "\n at table @code\n at item \\1(\\2)\n at findex \\1\n")
+     "@end table\n")
+    ("methoddescni" 2 "\n at table @code\n at item \\1(\\2)\n" "@end table\n")
+    ("notice" 0 "@emph{Notice:} " "")
+    ("opcodedesc" 2
+     (progn (setq findex t)
+	    "\n at table @code\n at item \\1 \\2\n at findex \\1\n")
+     "@end table\n")
+    ("productionlist" 0 "\n at table @code\n" "@end table\n")
+    ("quotation" 0 "@quotation" "@end quotation")
+    ("quote" 0 "@quotation" "@end quotation")
+    ("seealso" 0 "See also:\n at table @emph\n" "@end table\n")
+    ("seealso*" 0 "@table @emph\n" "@end table\n")
+    ("sloppypar" 0 "" "")
+    ("small" 0 "" "")
+    ("tableii" 4 (concat "@multitable @columnfractions .5 .5\n"
+			 "@item \\3 @tab \\4\n"
+			 "@item ------- @tab ------ \n")
+     "@end multitable\n")
+    ("tableiii" 5 (concat "@multitable @columnfractions .33 .33 .33\n"
+			 "@item \\3 @tab \\4 @tab \\5\n"
+			 "@item ------- @tab ------ @tab ------\n")
+     "@end multitable\n")
+    ("tableiv" 6 (concat
+		  "@multitable @columnfractions .25 .25 .25 .25\n"
+		  "@item \\3 @tab \\4 @tab \\5 @tab \\6\n"
+		  "@item ------- @tab ------- @tab ------- @tab -------\n")
+     "@end multitable\n")
+    ("tablev" 7 (concat
+		 "@multitable @columnfractions .20 .20 .20 .20 .20\n"
+		 "@item \\3 @tab \\4 @tab \\5 @tab \\6 @tab \\7\n"
+		 "@item ------- @tab ------- @tab ------- @tab ------- @tab -------\n")
+     "@end multitable\n")
+    ("alltt" 0 "@example" "@end example")
+    )
+  "Associative list defining substitutions for environments.
+Each list item is of the form (ENVIRONMENT ARGNUM BEGIN END) where:
+- ENVIRONMENT is LaTeX environment name
+- ARGNUM is number of (required) macro arguments
+- BEGIN is substitution for \begin{ENVIRONMENT}
+- END is substitution for \end{ENVIRONMENT}
+Both BEGIN and END are evaled.  Moreover, you can reference arguments through
+\N regular expression notation in strings of BEGIN.")
+
+(defconst py2texi-commands
+  '(("AA" 0 "@AA{}")
+    ("aa" 0 "@aa{}")
+    ("ABC" 0 "ABC")
+    ("appendix" 0 (progn (setq appendix t) ""))
+    ("ASCII" 0 "ASCII")
+    ("author" 1 (progn (setq author (match-string 1 string)) ""))
+    ("authoraddress" 1
+     (progn (setq author-address (match-string 1 string)) ""))
+    ("b" 1 "@w{\\1}")
+    ("backslash" 0 "@backslash{}")
+    ("bf" 0 "@destroy")
+    ("bifuncindex" 1 (progn (setq findex t) "@findex{\\1}"))
+    ("C" 0 "C")
+    ("c" 0 "@,")
+    ("catcode" 0 "")
+    ("cdata" 1 "@code{\\1}")
+    ("centerline" 1 "@center \\1")
+    ("cfuncline" 3 "@itemx \\1 \\2(\\3)\n at findex \\2")
+    ("cfunction" 1 "@code{\\1}")
+    ("chapter" 1 (format "@node \\1\n@%s \\1\n"
+			 (if appendix "appendix" "chapter")))
+    ("chapter*" 1 "@node \\1\n at unnumbered \\1\n")
+    ("character" 1 "@samp{\\1}")
+    ("citetitle" 1 "@ref{Top,,,\\1}")
+    ("class" 1 "@code{\\1}")
+    ("cmemberline" 3 "@itemx \\2 \\3\n")
+    ("code" 1 "@code{\\1}")
+    ("command" 1 "@command{\\1}")
+    ("constant" 1 "@code{\\1}")
+    ("copyright" 1 "@copyright{}")
+    ("Cpp" 0 "C++")
+    ("csimplemacro" 1 "@code{\\1}")
+    ("ctype" 1 "@code{\\1}")
+    ("dataline" 1 (progn (setq findex t) "@item \\1\n at findex \\1\n"))
+    ("date" 1 "\\1")
+    ("declaremodule" 2 (progn (setq cindex t) "@label{\\2}@cindex{\\2}"))
+    ("deprecated" 2 "@emph{This is deprecated in Python \\1.  \\2}\n\n")
+    ("dfn" 1 "@dfn{\\1}")
+    ("documentclass" 1 py2texi-magic)
+    ("e" 0 "@backslash{}")
+    ("else" 0 (concat "@end ifinfo\n@" (setq last-if "iftex")))
+    ("env" 1 "@code{\\1}")
+    ("EOF" 0 "@code{EOF}")
+    ("email" 1 "@email{\\1}")
+    ("em" 1 "@emph{\\1}")
+    ("emph" 1 "@emph{\\1}")
+    ("envvar" 1 "@env{\\1}")
+    ("exception" 1 "@code{\\1}")
+    ("exindex" 1 (progn (setq obindex t) "@obindex{\\1}"))
+    ("fi" 0 (if (equal last-if "ifx") "" (concat "@end " last-if)))
+    ("file" 1 "@file{\\1}")
+    ("filenq" 1 "@file{\\1}")
+    ("filevar" 1 "@file{@var{\\1}}")
+    ("footnote" 1 "@footnote{\\1}")
+    ("frac" 0 "")
+    ("funcline" 2 (progn (setq findex t) "@item \\1 \\2\n at findex \\1"))
+    ("funclineni" 2 "@item \\1 \\2")
+    ("function" 1 "@code{\\1}")
+    ("grammartoken" 1 "@code{\\1}")
+    ("guilabel" 1 "@strong{\\1}")
+    ("hline" 0 "")
+    ("ifx" 0 (progn (setq last-if "ifx") ""))
+    ("ifhtml" 0 (concat "@" (setq last-if "ifinfo")))
+    ("iftexi" 0 (concat "@" (setq last-if "ifinfo")))
+    ("index" 1 (progn (setq cindex t) "@cindex{\\1}"))
+    ("indexii" 2 (progn (setq cindex t) "@cindex{\\1 \\2}"))
+    ("indexiii" 3 (progn (setq cindex t) "@cindex{\\1 \\2 \\3}"))
+    ("indexiv" 3 (progn (setq cindex t) "@cindex{\\1 \\2 \\3 \\4}"))
+    ("infinity" 0 "@emph{infinity}")
+    ("it" 0 "@destroy")
+    ("kbd" 1 "@key{\\1}")
+    ("keyword" 1 "@code{\\1}")
+    ("kwindex" 1 (progn (setq cindex t) "@cindex{\\1}"))
+    ("label" 1 "@label{\\1}")
+    ("Large" 0 "")
+    ("LaTeX" 0 "La at TeX{}")
+    ("large" 0 "")
+    ("ldots" 0 "@dots{}")
+    ("leftline" 1 "\\1")
+    ("leq" 0 "<=")
+    ("lineii" 2 "@item \\1 @tab \\2")
+    ("lineiii" 3 "@item \\1 @tab \\2 @tab \\3")
+    ("lineiv" 4 "@item \\1 @tab \\2 @tab \\3 @tab \\4")
+    ("linev" 5 "@item \\1 @tab \\2 @tab \\3 @tab \\4 @tab \\5")
+    ("locallinewidth" 0 "")
+    ("localmoduletable" 0 "")
+    ("longprogramopt" 1 "@option{--\\1}")
+    ("macro" 1 "@code{@backslash{}\\1}")
+    ("mailheader" 1 "@code{\\1}")
+    ("makeindex" 0 "")
+    ("makemodindex" 0 "")
+    ("maketitle" 0 (concat "@top " title "\n"))
+    ("makevar" 1 "@code{\\1}")
+    ("manpage" 2 "@samp{\\1(\\2)}")
+    ("mbox" 1 "@w{\\1}")
+    ("member" 1 "@code{\\1}")
+    ("memberline" 1 "@item \\1\n at findex \\1\n")
+    ("menuselection" 1 "@samp{\\1}")
+    ("method" 1 "@code{\\1}")
+    ("methodline" 2 (progn (setq moindex t) "@item \\1(\\2)\n at moindex \\1\n"))
+    ("methodlineni" 2 "@item \\1(\\2)\n")
+    ("mimetype" 1 "@samp{\\1}")
+    ("module" 1 "@samp{\\1}")
+    ("moduleauthor" 2 "")
+    ("modulesynopsis" 1 "\\1")
+    ("moreargs" 0 "@dots{}")
+    ("n" 0 "@backslash{}n")
+    ("newcommand" 2 "")
+    ("newlength" 1 "")
+    ("newsgroup" 1 "@samp{\\1}")
+    ("nodename" 1
+     (save-excursion
+       (save-match-data
+	 (re-search-backward "^@node "))
+       (delete-region (point) (save-excursion (end-of-line) (point)))
+       (insert "@node " (match-string 1 string))
+       ""))
+    ("noindent" 0 "@noindent ")
+    ("note" 1 "@emph{Note:} \\1")
+    ("NULL" 0 "@code{NULL}")
+    ("obindex" 1 (progn (setq obindex t) "@obindex{\\1}"))
+    ("opindex" 1 (progn (setq cindex t) "@cindex{\\1}"))
+    ("option" 1 "@option{\\1}")
+    ("optional" 1 "[\\1]")
+    ("paragraph" 1 "@subsubheading \\1")
+    ("pep" 1 (progn (setq cindex t) "PEP@ \\1 at cindex PEP \\1\n"))
+    ("pi" 0 "pi")
+    ("platform" 1 "")
+    ("plusminus" 0 "+-")
+    ("POSIX" 0 "POSIX")
+    ("production" 2 "@item \\1 \\2")
+    ("productioncont" 1 "@item @w{} \\1")
+    ("program" 1 "@command{\\1}")
+    ("programopt" 1 "@option{\\1}")
+    ("protect" 0 "")
+    ("pytype" 1 "@code{\\1}")
+    ("ref" 1 "@ref{\\1}")
+    ("refbimodindex" 1 (progn (setq moindex t) "@moindex{\\1}"))
+    ("refmodindex" 1 (progn (setq moindex t) "@moindex{\\1}"))
+    ("refmodule" 1 "@samp{\\1}")
+    ("refstmodindex" 1 (progn (setq moindex t) "@moindex{\\1}"))
+    ("regexp" 1 "\"\\1\"")
+    ("release" 1
+     (progn (setq py2texi-python-version (match-string 1 string)) ""))
+    ("renewcommand" 2 "")
+    ("rfc" 1 (progn (setq cindex t) "RFC@ \\1 at cindex RFC \\1\n"))
+    ("rm" 0 "@destroy")
+    ("samp" 1 "@samp{\\1}")
+    ("section" 1 (let ((str (match-string 1 string)))
+		   (save-match-data
+		     (if (string-match "\\(.*\\)[ \t\n]*---[ \t\n]*\\(.*\\)"
+				       str)
+			 (format
+			  "@node %s\n at section %s\n"
+			  (py2texi-backslash-quote (match-string 1 str))
+			  (py2texi-backslash-quote (match-string 2 str)))
+		       "@node \\1\n at section \\1\n"))))
+    ("sectionauthor" 2 "")
+    ("seelink" 3 "\n at table @url\n at item @strong{\\1}\n(\\2)\n\\3\n at end table\n")
+    ("seemodule" 2 "@ref{\\1} \\2")
+    ("seepep" 3 "\n at table @strong\n at item PEP\\1 \\2\n\\3\n at end table\n")
+    ("seerfc" 3 "\n at table @strong\n at item RFC\\1 \\2\n\\3\n at end table\n")
+    ("seetext" 1 "\\1")
+    ("seetitle" 1 "@cite{\\1}")
+    ("seeurl" 2 "\n at table @url\n at item \\1\n\\2\n at end table\n")
+    ("setindexsubitem" 1 (progn (setq cindex t) "@cindex \\1"))
+    ("setlength" 2 "")
+    ("setreleaseinfo" 1 (progn (setq py2texi-releaseinfo "")))
+    ("setshortversion" 1
+     (progn (setq py2texi-python-short-version (match-string 1 string)) ""))
+    ("shortversion" 0 py2texi-python-short-version)
+    ("sqrt" 0 "")
+    ("stindex" 1 (progn (setq cindex t) "@cindex{\\1}"))
+    ("stmodindex" 1 (progn (setq moindex t) "@moindex{\\1}"))
+    ("strong" 1 "@strong{\\1}")
+    ("sub" 0 "/")
+    ("subsection" 1 "@node \\1\n at subsection \\1\n")
+    ("subsubsection" 1 "@node \\1\n at subsubsection \\1\n")
+    ("sum" 0 "")
+    ("tableofcontents" 0 "")
+    ("term" 1 "@item \\1")
+    ("TeX" 0 "@TeX{}")
+    ("textasciitilde" 0 "~")
+    ("textasciicircum" 0 "^")
+    ("textbackslash" 0 "@backslash{}")
+    ("textbar" 0 "|")
+    ("textbf" 1 "@strong{\\1}")
+    ("texteuro" 0 "@euro{}")
+    ; Unfortunately, this alternate spelling doesn't actually apply to
+    ; the usage found in Python Tutorial, which actually requires a
+    ; Euro symbol to make sense, so this is commented out as well.
+    ; ("texteuro" 0 "Euro ")
+    ("textgreater" 0 ">")
+    ("textit" 1 "@i{\\1}")
+    ("textless" 0 "<")
+    ("textrm" 1 "\\1")
+    ("texttt" 1 "@code{\\1}")
+    ("textunderscore" 0 "_")
+    ("tilde" 0 "~")
+    ("title" 1 (progn (setq title (match-string 1 string)) "@settitle \\1"))
+    ("today" 0 "@today{}")
+    ("token" 1 "@code{\\1}")
+    ("tt" 0 "@destroy")
+    ("ttindex" 1 (progn (setq cindex t) "@cindex{\\1}"))
+    ("u" 0 "@backslash{}u")
+    ("ulink" 2 "\\1")
+    ("UNIX" 0 "UNIX")
+    ("undefined" 0 "")
+    ("unspecified" 0 "@dots{}")
+    ("url" 1 "@url{\\1}")
+    ("usepackage" 1 "")
+    ("var" 1 "@var{\\1}")
+    ("verbatiminput" 1 "@code{\\1}")
+    ("version" 0 py2texi-python-version)
+    ("versionadded" 1 "@emph{Added in Python version \\1}")
+    ("versionchanged" 1 "@emph{Changed in Python version \\1}")
+    ("vskip" 1 "")
+    ("vspace" 1 "")
+    ("warning" 1 "@emph{\\1}")
+    ("withsubitem" 2 "\\2")
+    ("XXX" 1 "@strong{\\1}"))
+  "Associative list of command substitutions.
+Each list item is of the form (COMMAND ARGNUM SUBSTITUTION) where:
+- COMMAND is LaTeX command name
+- ARGNUM is number of (required) command arguments
+- SUBSTITUTION substitution for the command.  It is evaled and you can
+  reference command arguments through the \\N regexp notation in strings.")
+
+(defvar py2texi-magic "@documentclass\n"
+  "\"Magic\" string for auxiliary insertion at the beginning of document.")
+
+(defvar py2texi-dirs '("./" "../texinputs/")
+  "Where to search LaTeX input files.")
+
+(defvar py2texi-buffer "*py2texi*"
+  "The name of a buffer where Texinfo is generated.")
+
+(defconst py2texi-xemacs (string-match "^XEmacs" (emacs-version))
+  "Running under XEmacs?")
+
+
+(defmacro py2texi-search (regexp &rest body)
+  `(progn
+     (goto-char (point-min))
+     (while (re-search-forward ,regexp nil t)
+       , at body)))
+
+(defmacro py2texi-search-safe (regexp &rest body)
+  `(py2texi-search ,regexp
+    (unless (py2texi-protected)
+      , at body)))
+
+
+(defun py2texi-message (message)
+  "Report message and stop if `py2texi-stop-on-problems' is non-nil."
+  (if py2texi-stop-on-problems
+      (error message)
+    (message message)))
+
+
+(defun py2texi-backslash-quote (string)
+  "Double backslahes in STRING."
+  (let ((i 0))
+    (save-match-data
+      (while (setq i (string-match "\\\\" string i))
+	(setq string (replace-match "\\\\\\\\" t nil string))
+	(setq i (+ i 2))))
+    string))
+
+
+(defun py2texi (file)
+  "Convert Python LaTeX documentation FILE to Texinfo."
+  (interactive "fFile to convert: ")
+  (switch-to-buffer (get-buffer-create py2texi-buffer))
+  (erase-buffer)
+  (insert-file file)
+  (let ((case-fold-search nil)
+	(title "")
+	(author "")
+	(author-address "")
+	(appendix nil)
+	(findex nil)
+	(obindex nil)
+	(cindex nil)
+	(moindex nil)
+	last-if)
+    (py2texi-process-verbatims)
+    (py2texi-process-comments)
+    (py2texi-process-includes)
+    (py2texi-process-funnyas)
+    (py2texi-process-environments)
+    (py2texi-process-commands)
+    (py2texi-fix-indentation)
+    (py2texi-fix-nodes)
+    (py2texi-fix-references)
+    (py2texi-fix-indices)
+    (py2texi-process-simple-commands)
+    (py2texi-fix-fonts)
+    (py2texi-fix-braces)
+    (py2texi-fix-backslashes)
+    (py2texi-destroy-empties)
+    (py2texi-fix-newlines)
+    (py2texi-adjust-level))
+  (let* ((texi-file-name (or py2texi-texi-file-name
+			     (py2texi-texi-file-name file)))
+	 (info-file-name (or py2texi-info-file-name
+			     (py2texi-info-file-name texi-file-name))))
+    (goto-char (point-min))
+    (when (looking-at py2texi-magic)
+      (delete-region (point) (progn (beginning-of-line 2) (point)))
+      (insert "\\input texinfo @c -*-texinfo-*-\n")
+      (insert "@setfilename " info-file-name))
+    (when (re-search-forward "@chapter" nil t)
+      (texinfo-all-menus-update t))
+    (goto-char (point-min))
+    (write-file texi-file-name)
+    (message (format "You can apply `makeinfo %s' now." texi-file-name))))
+
+
+(defun py2texi-texi-file-name (filename)
+  "Generate name of Texinfo file from original file name FILENAME."
+  (concat filename
+	  (if (string-match "\\.tex$" filename) "i" ".texi")))
+
+
+(defun py2texi-info-file-name (filename)
+  "Generate name of info file from original file name FILENAME."
+  (setq filename (expand-file-name filename))
+  (let ((directory (file-name-directory filename))
+	(basename (file-name-nondirectory filename)))
+    (concat directory "python-"
+	    (substring basename 0 (- (length basename) 4)) "info")))
+
+
+(defun py2texi-process-verbatims ()
+  "Process and protect verbatim environments."
+  (let (delimiter
+	beg
+	end)
+    (py2texi-search-safe "\\\\begin{\\(verbatim\\|displaymath\\)}"
+      (when (save-excursion
+	      ; Make sure we aren't looking at a commented out version
+	      ; of a verbatim environment
+	      (beginning-of-line)
+	      (not (looking-at "%")))
+	(replace-match "@example ")
+	(setq beg (copy-marker (point) nil))
+	(re-search-forward "\\\\end{\\(verbatim\\|displaymath\\)}")
+	(setq end (copy-marker (match-beginning 0) nil))
+	(replace-match "@end example")
+	(py2texi-texinfo-escape beg end)
+	(put-text-property (- beg (length "@example "))
+			   (+ end (length "@end example"))
+			   'py2texi-protected t)))
+    (py2texi-search-safe "\\\\verb\\([^a-z]\\)"
+      (setq delimiter (match-string 1))
+      (replace-match "@code{")
+      (setq beg (copy-marker (point) nil))
+      (re-search-forward (regexp-quote delimiter))
+      (setq end (copy-marker (match-beginning 0) nil))
+      (replace-match "}")
+      (put-text-property (- beg (length "@code{")) (+ end (length "}"))
+			 'py2texi-protected t)
+      (py2texi-texinfo-escape beg end))))
+
+
+(defun py2texi-process-comments ()
+  "Remove comments."
+  (let (point)
+    (py2texi-search-safe "%"
+      (setq point (point))
+      (when (save-excursion
+	      (re-search-backward "\\(^\\|[^\\]\\(\\\\\\\\\\)*\\)%\\=" nil t))
+	(delete-region (1- point)
+		       (save-excursion (beginning-of-line 2) (point)))))))
+
+
+(defun py2texi-process-includes ()
+  "Include LaTeX input files.
+Do not include .ind files."
+  (let ((path (file-name-directory file))
+	filename
+	dirs
+	includefile)
+    (py2texi-search-safe "\\\\input{\\([^}]+\\)}"
+      (setq filename (match-string 1))
+      (unless (save-match-data (string-match "\\.tex$" filename))
+	(setq filename (concat filename ".tex")))
+      (setq includefile (save-match-data
+			  (string-match "\\.ind\\.tex$" filename)))
+      (setq dirs py2texi-dirs)
+      (while (and (not includefile) dirs)
+	(setq includefile
+              (concat (file-name-as-directory (car dirs)) filename))
+        (if (not (file-name-absolute-p includefile))
+            (setq includefile
+                  (concat (file-name-as-directory path) includefile)))
+	(unless (file-exists-p includefile)
+          (setq includefile nil)
+	  (setq dirs (cdr dirs))))
+      (if includefile
+	  (save-restriction
+	    (narrow-to-region (match-beginning 0) (match-end 0))
+	    (delete-region (point-min) (point-max))
+	    (when (stringp includefile)
+	      (insert-file-contents includefile)
+	      (goto-char (point-min))
+	      (insert "\n")
+	      (py2texi-process-verbatims)
+	      (py2texi-process-comments)
+	      (py2texi-process-includes)))
+	(replace-match (format "\\\\emph{Included file %s}" filename))
+	(py2texi-message (format "Input file %s not found" filename))))))
+
+
+(defun py2texi-process-funnyas ()
+  "Convert @s."
+  (py2texi-search-safe "@"
+    (replace-match "@@")))
+
+
+(defun py2texi-process-environments ()
+  "Process LaTeX environments."
+  (let ((stack ())
+	kind
+	environment
+	parameter
+	arguments
+	n
+	string
+	description)
+    (py2texi-search-safe (concat "\\\\\\(begin\\|end\\|item\\)"
+				 "\\({\\([^}]*\\)}\\|[[]\\([^]]*\\)[]]\\|\\)")
+      (setq kind (match-string 1)
+	    environment (match-string 3)
+	    parameter (match-string 4))
+      (replace-match "")
+      (cond
+       ((string= kind "begin")
+	(setq description (assoc environment py2texi-environments))
+	(if description
+	    (progn
+	      (setq n (cadr description))
+	      (setq description (cddr description))
+	      (setq string (py2texi-tex-arguments n))
+	      (string-match (py2texi-regexp n) string)
+				      ; incorrect but sufficient
+	      (insert (replace-match (eval (car description))
+				     t nil string))
+	      (setq stack (cons (cadr description) stack)))
+	  (py2texi-message (format "Unknown environment: %s" environment))
+	  (setq stack (cons "" stack))))
+       ((string= kind "end")
+	(insert (eval (car stack)))
+	(setq stack (cdr stack)))
+       ((string= kind "item")
+	(insert "\n at item " (or parameter "") "\n"))))
+    (when stack
+      (py2texi-message (format "Unclosed environment: %s" (car stack))))))
+
+
+(defun py2texi-process-commands ()
+  "Process LaTeX commands."
+  (let (done
+	command
+	command-info
+	string
+	n)
+    (while (not done)
+      (setq done t)
+      (py2texi-search-safe "\\\\\\([a-zA-Z*]+\\)\\(\\[[^]]*\\]\\)?"
+	(setq command (match-string 1))
+	(setq command-info (assoc command py2texi-commands))
+	(if command-info
+	    (progn
+	      (setq done nil)
+	      (replace-match "")
+	      (setq command-info (cdr command-info))
+	      (setq n (car command-info))
+	      (setq string (py2texi-tex-arguments n))
+	      (string-match (py2texi-regexp n) string)
+				      ; incorrect but sufficient
+	      (insert (replace-match (eval (cadr command-info))
+				     t nil string)))
+	  (py2texi-message (format "Unknown command: %s (not processed)"
+				   command)))))))
+
+
+(defun py2texi-argument-pattern (count)
+  (let ((filler "\\(?:[^{}]\\|\\\\{\\|\\\\}\\)*"))
+    (if (<= count 0)
+	filler
+      (concat filler "\\(?:{"
+	      (py2texi-argument-pattern (1- count))
+	      "}" filler "\\)*" filler))))
+(defconst py2texi-tex-argument
+  (concat
+   "{\\("
+   (py2texi-argument-pattern 10)	;really at least 10!
+   "\\)}[ \t%@c\n]*")
+  "Regexp describing LaTeX command argument including argument separators.")
+
+
+(defun py2texi-regexp (n)
+  "Make regexp matching N LaTeX command arguments."
+  (if (= n 0)
+      ""
+    (let ((regexp "^[^{]*"))
+      (while (> n 0)
+	(setq regexp (concat regexp py2texi-tex-argument))
+	(setq n (1- n)))
+      regexp)))
+
+
+(defun py2texi-tex-arguments (n)
+  "Remove N LaTeX command arguments and return them as a string."
+  (let ((point (point))
+	(i 0)
+	result
+	match)
+    (if (= n 0)
+	(progn
+	  (when (re-search-forward "\\=\\({}\\| *\\)" nil t)
+	    (replace-match ""))
+	  "")
+      (while (> n 0)
+	(unless (re-search-forward
+		 "\\(\\=\\|[^\\\\]\\)\\(\\\\\\\\\\)*\\([{}]\\)" nil t)
+	  (debug))
+	(if (string= (match-string 3) "{")
+	    (setq i (1+ i))
+	  (setq i (1- i))
+	  (when (<= i 0)
+	    (setq n (1- n)))))
+      (setq result (buffer-substring-no-properties point (point)))
+      (while (string-match "\n[ \t]*" result)
+	(setq result (replace-match " " t nil result)))
+      (delete-region point (point))
+      result)))
+
+
+(defun py2texi-process-simple-commands ()
+  "Replace single character LaTeX commands."
+  (let (char)
+    (py2texi-search-safe "\\\\\\([^a-z]\\)"
+      (setq char (match-string 1))
+      (replace-match (format "%s%s"
+			     (if (or (string= char "{")
+				     (string= char "}")
+				     (string= char " "))
+				 "@"
+			       "")
+			     (if (string= char "\\")
+				 "\\\\"
+			       char))))))
+
+
+(defun py2texi-fix-indentation ()
+  "Remove white space at the beginning of lines."
+  (py2texi-search-safe "^[ \t]+"
+    (replace-match "")))
+
+
+(defun py2texi-fix-nodes ()
+  "Remove unwanted characters from nodes and make nodes unique."
+  (let ((nodes (make-hash-table :test 'equal))
+	id
+	counter
+	string
+	label
+	index)
+    (py2texi-search "^@node +\\(.*\\)$"
+      (setq string (match-string 1))
+      (if py2texi-xemacs
+	  (replace-match "@node " t)
+	(replace-match "" t nil nil 1))
+      (while (string-match "@label{[^}]*}" string)
+	(setq label (match-string 0 string))
+	(setq string (replace-match "" t nil string)))
+      (while (string-match "@..?index{[^}]*}" string)
+	(setq index (match-string 0 string))
+	(setq string (replace-match "" t nil string)))
+      (while (string-match "@[a-zA-Z]+\\|[{}():]\\|``\\|''" string)
+	(setq string (replace-match "" t nil string)))
+      (while (string-match " -- " string)
+	(setq string (replace-match " - " t nil string)))
+      (while (string-match "\\." string)
+	(setq string (replace-match "" t nil string)))
+      (when (string-match " +$" string)
+	(setq string (replace-match "" t nil string)))
+      (when (string-match "^\\(Built-in\\|Standard\\) Module \\|The " string)
+	(setq string (replace-match "" t nil string)))
+      (string-match "^[^,]+" string)
+      (setq id (match-string 0 string))
+      (setq counter (gethash id nodes))
+      (if counter
+	  (progn
+	    (setq counter (1+ counter))
+	    (setq string (replace-match (format "\\& %d" counter)
+					t nil string)))
+	(setq counter 1))
+      (setf (gethash id nodes) counter)
+      (insert string)
+      (beginning-of-line 3)
+      (when label
+	(insert label "\n"))
+      (when index
+	(insert index "\n")))))
+
+
+(defun py2texi-fix-references ()
+  "Process labels and make references to point to appropriate nodes."
+  (let ((labels ())
+	node)
+    (py2texi-search-safe "@label{\\([^}]*\\)}"
+      (setq node (save-excursion
+		   (save-match-data
+		     (and (re-search-backward "@node +\\([^,\n]+\\)" nil t)
+			  (match-string 1)))))
+      (when node
+	(setq labels (cons (cons (match-string 1) node) labels)))
+      (replace-match ""))
+    (py2texi-search-safe "@ref{\\([^}]*\\)}"
+      (setq node (assoc (match-string 1) labels))
+      (replace-match "")
+      (when node
+	(insert (format "@ref{%s}" (cdr node)))))))
+
+
+(defun py2texi-fix-indices ()
+  "Remove unwanted characters from @*index commands and create final indices."
+  (py2texi-search-safe "@..?index\\>[^\n]*\\(\\)\n"
+    (replace-match "" t nil nil 1))
+  (py2texi-search-safe "@..?index\\>[^\n]*\\(\\)"
+    (replace-match "\n" t nil nil 1))
+  (py2texi-search-safe "@..?index\\({\\)\\([^}]+\\)\\(}+\\)"
+    (replace-match " " t nil nil 1)
+    (replace-match "" t nil nil 3)
+    (let ((string (match-string 2)))
+      (save-match-data
+	(while (string-match "@[a-z]+{" string)
+	  (setq string (replace-match "" nil nil string)))
+	(while (string-match "{" string)
+	  (setq string (replace-match "" nil nil string))))
+      (replace-match string t t nil 2)))
+  (py2texi-search-safe "@..?index\\>.*\\([{}]\\|@[a-z]*\\)"
+    (replace-match "" t nil nil 1)
+    (goto-char (match-beginning 0)))
+  (py2texi-search-safe "[^\n]\\(\\)@..?index\\>"
+    (replace-match "\n" t nil nil 1))
+  (goto-char (point-max))
+  (re-search-backward "@indices")
+  (replace-match "")
+  (insert (if moindex
+	      (concat "@node Module Index\n"
+		      "@unnumbered Module Index\n"
+		      "@printindex mo\n")
+	    "")
+	  (if obindex
+	      (concat "@node Class-Exception-Object Index\n"
+		      "@unnumbered Class, Exception, and Object Index\n"
+		      "@printindex ob\n")
+	    "")
+	  (if findex
+	      (concat "@node Function-Method-Variable Index\n"
+		      "@unnumbered Function, Method, and Variable Index\n"
+		      "@printindex fn\n")
+	    "")
+	  (if cindex
+	      (concat "@node Miscellaneous Index\n"
+		      "@unnumbered Miscellaneous Index\n"
+		      "@printindex cp\n")
+	    "")))
+
+
+(defun py2texi-fix-backslashes ()
+  "Make backslashes from auxiliary commands."
+  (py2texi-search-safe "@backslash{}"
+    (replace-match "\\\\")))
+
+
+(defun py2texi-fix-fonts ()
+  "Remove garbage after unstructured font commands."
+  (let (string)
+    (py2texi-search-safe "@destroy"
+      (replace-match "")
+      (when (eq (preceding-char) ?{)
+	(forward-char -1)
+	(setq string (py2texi-tex-arguments 1))
+	(insert (substring string 1 (1- (length string))))))))
+
+
+(defun py2texi-fix-braces ()
+  "Escape braces for Texinfo."
+  (py2texi-search "{@{}"
+    (replace-match "@{"))
+  (py2texi-search "{@}}"
+    (replace-match "@}"))
+  (let (string)
+    (py2texi-search "{"
+       (unless (or (py2texi-protected)
+		   (save-excursion
+		     (re-search-backward
+		      "@\\([a-zA-Z]*\\|multitable.*\\){\\=" nil t)))
+	 (forward-char -1)
+	 (setq string (py2texi-tex-arguments 1))
+	 (insert "@" (substring string 0 (1- (length string))) "@}")))))
+
+
+(defun py2texi-fix-newlines ()
+  "Remove extra newlines."
+  (py2texi-search "\n\n\n+"
+    (replace-match "\n\n"))
+  (py2texi-search-safe "@item.*\n\n"
+    (delete-backward-char 1))
+  (py2texi-search "@end example"
+    (unless (looking-at "\n\n")
+      (insert "\n"))))
+
+
+(defun py2texi-destroy-empties ()
+  "Remove all comments.
+This avoids some makeinfo errors."
+  (py2texi-search "@c\\>"
+    (unless (eq (py2texi-protected) t)
+      (delete-region (- (point) 2) (save-excursion (end-of-line) (point)))
+      (cond
+       ((looking-at "\n\n")
+	(delete-char 1))
+       ((save-excursion (re-search-backward "^[ \t]*\\=" nil t))
+	(delete-region (save-excursion (beginning-of-line) (point))
+		       (1+ (point))))))))
+
+
+(defun py2texi-adjust-level ()
+  "Increase heading level to @chapter, if needed.
+This is only needed for distutils, so it has a very simple form only."
+  (goto-char (point-min))
+  (unless (re-search-forward "@chapter\\>" nil t)
+    (py2texi-search-safe "@section\\>"
+      (replace-match "@chapter" t))
+    (py2texi-search-safe "@\\(sub\\)\\(sub\\)?section\\>"
+      (replace-match "" nil nil nil 1))))
+
+
+(defun py2texi-texinfo-escape (beg end)
+  "Escape Texinfo special characters in region."
+  (save-excursion
+    (goto-char beg)
+    (while (re-search-forward "[@{}]" end t)
+      (replace-match "@\\&"))))
+
+
+(defun py2texi-protected ()
+  "Return protection status of the point before current point."
+  (get-text-property (1- (point)) 'py2texi-protected))
+
+
+;;; Announce
+
+(provide 'py2texi)
+
+
+;;; py2texi.el ends here

Added: vendor/Python/current/Doc/tools/refcounts.py
===================================================================
--- vendor/Python/current/Doc/tools/refcounts.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/tools/refcounts.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,98 @@
+"""Support functions for loading the reference count data file."""
+__version__ = '$Revision: 35267 $'
+
+import os
+import sys
+
+
+# Determine the expected location of the reference count file:
+try:
+    p = os.path.dirname(__file__)
+except NameError:
+    p = os.path.dirname(sys.argv[0])
+p = os.path.normpath(os.path.join(os.getcwd(), p, os.pardir,
+                                  "api", "refcounts.dat"))
+DEFAULT_PATH = p
+del p
+
+
+def load(path=DEFAULT_PATH):
+    return loadfile(open(path))
+
+
+def loadfile(fp):
+    d = {}
+    while 1:
+        line = fp.readline()
+        if not line:
+            break
+        line = line.strip()
+        if line[:1] in ("", "#"):
+            # blank lines and comments
+            continue
+        parts = line.split(":", 4)
+        if len(parts) != 5:
+            raise ValueError("Not enough fields in %r" % line)
+        function, type, arg, refcount, comment = parts
+        if refcount == "null":
+            refcount = None
+        elif refcount:
+            refcount = int(refcount)
+        else:
+            refcount = None
+        #
+        # Get the entry, creating it if needed:
+        #
+        try:
+            entry = d[function]
+        except KeyError:
+            entry = d[function] = Entry(function)
+        #
+        # Update the entry with the new parameter or the result information.
+        #
+        if arg:
+            entry.args.append((arg, type, refcount))
+        else:
+            entry.result_type = type
+            entry.result_refs = refcount
+    return d
+
+
+class Entry:
+    def __init__(self, name):
+        self.name = name
+        self.args = []
+        self.result_type = ''
+        self.result_refs = None
+
+
+def dump(d):
+    """Dump the data in the 'canonical' format, with functions in
+    sorted order."""
+    items = d.items()
+    items.sort()
+    first = 1
+    for k, entry in items:
+        if first:
+            first = 0
+        else:
+            print
+        s = entry.name + ":%s:%s:%s:"
+        if entry.result_refs is None:
+            r = ""
+        else:
+            r = entry.result_refs
+        print s % (entry.result_type, "", r)
+        for t, n, r in entry.args:
+            if r is None:
+                r = ""
+            print s % (t, n, r)
+
+
+def main():
+    d = load()
+    dump(d)
+
+
+if __name__ == "__main__":
+    main()

Added: vendor/Python/current/Doc/tools/rewrite.py
===================================================================
--- vendor/Python/current/Doc/tools/rewrite.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/tools/rewrite.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,54 @@
+"""Simple script to replace @DATE@ and friends with real information.
+
+Usage:  rewrite.py boilerplate.tex [VAR=value] ... <template >output
+"""
+
+import sys
+import time
+
+
+def get_info(fp):
+    s = fp.read()
+
+    d = {}
+    start = s.find(r"\date{")
+    if start >= 0:
+        end = s.find("}", start)
+        date = s[start+6:end]
+        if date == r"\today":
+            date = time.strftime("%B %d, %Y", time.localtime(time.time()))
+        d["DATE"] = date
+    return d
+
+
+def main():
+    s = sys.stdin.read()
+    if "@" in s:
+        # yes, we actully need to load the replacement values
+        d = get_info(open(sys.argv[1]))
+        for arg in sys.argv[2:]:
+            name, value = arg.split("=", 1)
+            d[name] = value
+        start = 0
+        while 1:
+            start = s.find("@", start)
+            if start < 0:
+                break
+            end = s.find("@", start+1)
+            name = s[start+1:end]
+            if name:
+                value = d.get(name)
+                if value is None:
+                    start = end + 1
+                else:
+                    s = s[:start] + value + s[end+1:]
+                    start = start + len(value)
+            else:
+                # "@@" --> "@"
+                s = s[:start] + s[end:]
+                start = end
+    sys.stdout.write(s)
+
+
+if __name__ == "__main__":
+    main()

Added: vendor/Python/current/Doc/tools/sgmlconv/README
===================================================================
--- vendor/Python/current/Doc/tools/sgmlconv/README	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/tools/sgmlconv/README	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,58 @@
+These scripts and Makefile fragment are used to convert the Python
+documentation in LaTeX format to XML.
+
+This material is preliminary and incomplete.  Python 2.0 is required.
+
+To convert all documents to XML:
+
+	cd Doc/
+	make -f tools/sgmlconv/Makefile
+
+To convert one document to XML:
+
+	cd Doc/<document-dir>
+	make -f ../tools/sgmlconv/make.rules TOOLSDIR=../tools
+
+Please send comments and bug reports to docs at python.org.
+
+
+What do the tools do?
+---------------------
+
+latex2esis.py
+    Reads in a conversion specification written in XML
+    (conversion.xml), reads a LaTeX document fragment, and interprets
+    the markup according to the specification.  The output is a stream
+    of ESIS events like those created by the nsgmls SGML parser, but
+    is *not* guaranteed to represent a single tree!  This is done to
+    allow conversion per entity rather than per document.  Since many
+    of the LaTeX files for the Python documentation contain two
+    sections on closely related modules, it is important to allow both
+    of the resulting <section> elements to exist in the same output
+    stream.  Additionally, since comments are not supported in ESIS,
+    comments are converted to <COMMENT> elements, which might exist at
+    the same level as the top-level content elements.
+
+    The output of latex2esis.py gets saved as <filename>.esis1.
+
+docfixer.py
+    This is the really painful part of the conversion.  Well, it's the 
+    second really painful part, but more of the pain is specific to
+    the structure of the Python documentation and desired output
+    rather than to the parsing of LaTeX markup.
+
+    This script loads the ESIS data created by latex2esis.py into a
+    DOM document *fragment* (remember, the latex2esis.py output may
+    not be well-formed).  Once loaded, it walks over the tree many
+    times looking for a variety of possible specific
+    micro-conversions.  Most of the code is not in any way "general".
+    After processing the fragment, a new ESIS data stream is written
+    out.  Like the input, it may not represent a well-formed
+    document, but does represent a parsed entity.
+
+    The output of docfixer.py is what gets saved in <filename>.esis.
+
+esis2sgml.py
+    Reads an ESIS stream and convert to SGML or XML.  This also
+    converts <COMMENT> elements to real comments.  This works quickly
+    because there's not much to actually do.

Added: vendor/Python/current/Doc/tools/sgmlconv/conversion.xml
===================================================================
--- vendor/Python/current/Doc/tools/sgmlconv/conversion.xml	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/tools/sgmlconv/conversion.xml	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,914 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<conversion>
+  <!-- Miscellaneous. -->
+  <macro name="declaremodule">
+    <attribute name="id" optional="yes"/>
+    <attribute name="type"/>
+    <attribute name="name"/>
+    </macro>
+  <macro name="modulesynopsis">
+    <content/>
+    </macro>
+  <macro name="platform">
+    <content/>
+    </macro>
+  <macro name="deprecated">
+    <attribute name="version"/>
+    <content/>
+    </macro>
+  <macro name="label">
+    <attribute name="id"/>
+    </macro>
+  <macro name="nodename" outputname="label">
+    <attribute name="id"/>
+    </macro>
+  <macro name="localmoduletable"/>
+  <macro name="manpage">
+    <attribute name="name"/>
+    <attribute name="section"/>
+    </macro>
+  <macro name="module">
+    <content/>
+    </macro>
+  <macro name="moduleauthor">
+    <attribute name="name"/>
+    <attribute name="email"/>
+    </macro>
+  <macro name="citetitle">
+    <attribute name="href" optional="yes"/>
+    <content/>
+    </macro>
+  <macro name="pep">
+    <attribute name="num"/>
+    </macro>
+  <macro name="rfc">
+    <attribute name="num"/>
+    </macro>
+  <macro name="sectionauthor" outputname="author">
+    <attribute name="name"/>
+    <attribute name="email"/>
+    </macro>
+  <macro name="author">
+    <attribute name="name"/>
+    </macro>
+  <macro name="authoraddress">
+    <content/>
+    </macro>
+  <macro name="shortversion"/>
+  <macro name="note">
+    <content/>
+    </macro>
+  <macro name="warning">
+    <content/>
+    </macro>
+  <environment name="notice">
+    <attribute name="role" optional="yes"/>
+    </environment>
+
+  <macro name="menuselection">
+    <content/>
+    </macro>
+  <macro name="sub"/>
+
+  <!-- These are broken:  we need to re-order the optional and required
+       parameters, making the optional parameter the content for the
+       element.  latex2esis.py is not powerful enough to handle this.
+    -->
+  <macro name="versionadded">
+    <attribute name="info" optional="yes"/>
+    <attribute name="version"/>
+    </macro>
+  <macro name="versionchanged">
+    <attribute name="info" optional="yes"/>
+    <attribute name="version"/>
+    </macro>
+
+  <!-- Module referencing. -->
+  <macro name="refmodule" outputname="module">
+    <!-- this causes the optional parameter to \refmodule to be
+         discarded -->
+    <attribute name="" optional="yes"/>
+    <content/>
+    </macro>
+
+  <!-- Information units. -->
+  <!-- C things. -->
+  <environment name="cfuncdesc">
+    <attribute name="type"/>
+    <attribute name="name"/>
+    <child name="args"/>
+    </environment>
+  <environment name="csimplemacrodesc">
+    <attribute name="name"/>
+    </environment>
+  <environment name="ctypedesc">
+    <attribute name="tag" optional="yes"/>
+    <attribute name="name"/>
+    </environment>
+  <environment name="cvardesc">
+    <attribute name="type"/>
+    <attribute name="name"/>
+    </environment>
+
+  <!-- Python things. -->
+  <macro name="optional">
+    <content/>
+    </macro>
+  <macro name="unspecified"/>
+  <macro name="moreargs"/>
+  <environment name="classdesc">
+    <attribute name="name"/>
+    <child name="args"/>
+    </environment>
+  <environment name="classdesc*" outputname="classdesc">
+    <attribute name="name"/>
+    </environment>
+  <environment name="datadesc">
+    <attribute name="name"/>
+    </environment>
+  <environment name="datadescni" outputname="datadesc">
+    <attribute name="index">no</attribute>
+    <attribute name="name"/>
+    </environment>
+  <macro name="dataline">
+    <attribute name="name"/>
+    </macro>
+  <environment name="excclassdesc">
+    <attribute name="name"/>
+    <child name="args"/>
+    </environment>
+  <environment name="excdesc">
+    <attribute name="name"/>
+    </environment>
+
+  <environment name="funcdesc">
+    <attribute name="name"/>
+    <child name="args"/>
+    </environment>
+  <macro name="funcline">
+    <attribute name="name"/>
+    <child name="args"/>
+    </macro>
+  <environment name="funcdescni" outputname="funcdesc">
+    <attribute name="index">no</attribute>
+    <attribute name="name"/>
+    <child name="args"/>
+    </environment>
+  <macro name="funclineni" outputname="funcline">
+    <attribute name="index">no</attribute>
+    <attribute name="name"/>
+    <child name="args"/>
+    </macro>
+
+  <environment name="memberdesc">
+    <attribute name="class" optional="yes"/>
+    <attribute name="name"/>
+    </environment>
+  <environment name="memberdescni" outputname="memberdesc">
+    <attribute name="index">no</attribute>
+    <attribute name="class" optional="yes"/>
+    <attribute name="name"/>
+    </environment>
+  <macro name="memberline">
+    <attribute name="name"/>
+    </macro>
+
+  <environment name="methoddesc">
+    <attribute name="class" optional="yes"/>
+    <attribute name="name"/>
+    <child name="args"/>
+    </environment>
+  <macro name="methodline">
+    <attribute name="class" optional="yes"/>
+    <attribute name="name"/>
+    <child name="args"/>
+    </macro>
+  <environment name="methoddescni">
+    <attribute name="index">no</attribute>
+    <attribute name="class" optional="yes"/>
+    <attribute name="name"/>
+    <child name="args"/>
+    </environment>
+  <macro name="methodlineni" outputname="methodline">
+    <attribute name="index">no</attribute>
+    <attribute name="class" optional="yes"/>
+    <attribute name="name"/>
+    <child name="args"/>
+    </macro>
+
+  <environment name="opcodedesc">
+    <attribute name="name"/>
+    <attribute name="var"/>
+    </environment>
+
+  <!-- "See also:" sections. -->
+  <environment name="seealso*" outputname="seealso">
+    <attribute name="sidebar">no</attribute>
+    </environment>
+  <macro name="seemodule">
+    <!-- this causes the optional parameter to \seemodule to be
+         discarded -->
+    <attribute name="" optional="yes"/>
+    <attribute name="name"/>
+    <child name="description"/>
+    </macro>
+  <macro name="seepep">
+    <attribute name="number"/>
+    <child name="title"/>
+    <child name="description"/>
+    </macro>
+  <macro name="seerfc">
+    <attribute name="number"/>
+    <child name="title"/>
+    <child name="description"/>
+    </macro>
+  <macro name="seetext">
+    <child name="description"/>
+    </macro>
+  <macro name="seetitle">
+    <attribute name="href" optional="yes"/>
+    <child name="title"/>
+    <child name="description"/>
+    </macro>
+  <macro name="seeurl">
+    <attribute name="href"/>
+    <child name="description"/>
+    </macro>
+
+  <!-- Index-generating markup. -->
+  <macro name="index" outputname="indexterm">
+    <attribute name="term1"/>
+    </macro>
+  <macro name="indexii" outputname="indexterm">
+    <attribute name="term1"/>
+    <attribute name="term2"/>
+    </macro>
+  <macro name="indexiii" outputname="indexterm">
+    <attribute name="term1"/>
+    <attribute name="term2"/>
+    <attribute name="term3"/>
+    </macro>
+  <macro name="indexiv" outputname="indexterm">
+    <attribute name="term1"/>
+    <attribute name="term2"/>
+    <attribute name="term3"/>
+    <attribute name="term4"/>
+    </macro>
+
+  <macro name="ttindex" outputname="indexterm">
+    <attribute name="style">tt</attribute>
+    <attribute name="term1"/>
+    </macro>
+
+  <macro name="refmodindex">
+    <attribute name="module"/>
+    </macro>
+  <macro name="stmodindex">
+    <attribute name="module"/>
+    </macro>
+  <macro name="refbimodindex" outputname="refmodindex">
+    <attribute name="module"/>
+    </macro>
+  <macro name="refexmodindex" outputname="refmodindex">
+    <attribute name="module"/>
+    </macro>
+  <macro name="refstmodindex" outputname="refmodindex">
+    <attribute name="module"/>
+    </macro>
+
+  <macro name="bifuncindex">
+    <attribute name="name"/>
+    </macro>
+  <macro name="exindex">
+    <attribute name="name"/>
+    </macro>
+  <macro name="obindex">
+    <attribute name="name"/>
+    </macro>
+  <macro name="kwindex">
+    <attribute name="name"/>
+    </macro>
+  <macro name="opindex">
+    <attribute name="type"/>
+    </macro>
+  <macro name="stindex">
+    <attribute name="type"/>
+    </macro>
+  <macro name="withsubitem">
+    <attribute name="text"/>
+    <content/>
+    </macro>
+  <macro name="setindexsubitem">
+    <attribute name="text"/>
+    </macro>
+
+  <!-- Entity management. -->
+  <macro name="include" outputname="xi:include">
+    <attribute name="href"/>
+    </macro>
+  <macro name="input" outputname="xi:include">
+    <attribute name="href"/>
+    </macro>
+
+  <!-- Large-scale document structure. -->
+  <macro name="documentclass">
+    <attribute name="classname"/>
+    </macro>
+
+  <macro name="usepackage">
+    <attribute name="options" optional="yes"/>
+    <attribute name="pkg"/>
+    </macro>
+
+  <environment name="document"
+               endcloses="chapter chapter* section section*
+                          subsection subsection*
+                          subsubsection subsubsection*
+                          paragraph paragraph* subparagraph
+                          subparagraph*">
+    <attribute name="xmlns:xi"
+      >http://www.w3.org/2001/XInclude</attribute>
+    </environment>
+
+  <macro name="chapter"
+         closes="chapter chapter* section section* subsection subsection*
+                 subsubsection subsubsection*
+                 paragraph paragraph* subparagraph subparagraph*">
+    <text>
+</text>
+    <child name="title"/>
+    <content implied="yes"/>
+    </macro>
+  <macro name="chapter*" outputname="chapter"
+         closes="chapter chapter* section section* subsection subsection*
+                 subsubsection subsubsection*
+                 paragraph paragraph* subparagraph subparagraph*">
+    <attribute name="numbered">no</attribute>
+    <text>
+</text>
+    <child name="title"/>
+    <content implied="yes"/>
+    </macro>
+
+  <macro name="section"
+         closes="section section* subsection subsection*
+                 subsubsection subsubsection*
+                 paragraph paragraph* subparagraph subparagraph*">
+    <text>
+</text>
+    <child name="title"/>
+    <content implied="yes"/>
+    </macro>
+  <macro name="section*" outputname="section"
+         closes="section section* subsection subsection*
+                 subsubsection subsubsection*
+                 paragraph paragraph* subparagraph subparagraph*">
+    <attribute name="numbered">no</attribute>
+    <text>
+</text>
+    <child name="title"/>
+    <content implied="yes"/>
+    </macro>
+
+  <macro name="subsection"
+         closes="subsection subsection* subsubsection subsubsection*
+                 paragraph paragraph* subparagraph subparagraph*">
+    <text>
+</text>
+    <child name="title"/>
+    <content implied="yes"/>
+    </macro>
+  <macro name="subsection*" outputname="subsection"
+         closes="subsection subsection* subsubsection subsubsection*
+                 paragraph paragraph* subparagraph subparagraph*">
+    <attribute name="numbered">no</attribute>
+    <text>
+</text>
+    <child name="title"/>
+    <content implied="yes"/>
+    </macro>
+
+  <macro name="subsubsection"
+         closes="subsubsection subsubsection*
+                 paragraph paragraph* subparagraph subparagraph*">
+    <text>
+</text>
+    <child name="title"/>
+    <content implied="yes"/>
+    </macro>
+  <macro name="subsubsection*" outputname="subsubsection"
+         closes="subsubsection subsubsection*
+                 paragraph paragraph* subparagraph subparagraph*">
+    <attribute name="numbered">no</attribute>
+    <text>
+</text>
+    <child name="title"/>
+    <content implied="yes"/>
+    </macro>
+
+  <macro name="paragraph"
+         closes="paragraph paragraph* subparagraph subparagraph*">
+    <text>
+</text>
+    <child name="title"/>
+    <content implied="yes"/>
+    </macro>
+  <macro name="paragraph*" outputname="paragraph"
+         closes="paragraph paragraph* subparagraph subparagraph*">
+    <attribute name="numbered">no</attribute>
+    <text>
+</text>
+    <child name="title"/>
+    <content implied="yes"/>
+    </macro>
+
+  <macro name="subparagraph"
+         closes="subparagraph subparagraph*">
+    <text>
+</text>
+    <child name="title"/>
+    <content implied="yes"/>
+    </macro>
+  <macro name="subparagraph*" outputname="subparagraph"
+         closes="subparagraph subparagraph*">
+    <attribute name="numbered">no</attribute>
+    <text>
+</text>
+    <child name="title"/>
+    <content implied="yes"/>
+    </macro>
+  <macro name="title">
+    <content/>
+    </macro>
+
+  <macro name="appendix" outputname="back-matter"
+         closes="chapter chapter* section subsection subsubsection
+                 paragraph subparagraph"/>
+
+  <environment name="list"
+               endcloses="item">
+    <attribute name="bullet"/>
+    <attribute name="init"/>
+    </environment>
+  <macro name="item" closes="item">
+    <child name="leader" optional="yes"/>
+    <content implied="yes"/>
+    </macro>
+
+  <macro name="ref">
+    <attribute name="ref"/>
+    </macro>
+
+  <environment name="description" outputname="descriptionlist"
+               endcloses="item"/>
+
+  <environment name="enumerate" outputname="enumeration"
+               endcloses="item"/>
+
+  <environment name="fulllineitems"
+               endcloses="item"/>
+
+  <environment name="itemize"
+               endcloses="item"/>
+
+  <environment name="definitions" outputname="definitionlist"
+               encloses="term"/>
+  <macro name="term" closes="definition">
+    <!-- not really optional, but uses the [] syntax -->
+    <child name="term" optional="yes"/>
+    <child name="definition" implied="yes"/>
+    </macro>
+
+  <environment name="alltt" outputname="verbatim"/>
+  <environment name="comment" verbatim="yes"/>
+  <environment name="verbatim" verbatim="yes"/>
+  <environment name="verbatim*" verbatim="yes">
+    <!-- not used anywhere, but it's a standard LaTeXism -->
+    <attribute name="spaces">visible</attribute>
+    </environment>
+  <macro name="verbatiminput" ouptutname="xi:include">
+    <attribute name="parse">text</attribute>
+    <attribute name="href"/>
+    </macro>
+
+  <!-- Table markup. -->
+  <macro name="hline"/>
+  <environment name="tableii" outputname="table">
+    <attribute name="cols">2</attribute>
+    <attribute name="colspec"/>
+    <attribute name="style"/>
+    <child name="entry"/>
+    <text>
+         </text>
+    <child name="entry"/>
+    </environment>
+  <environment name="longtableii" outputname="table">
+    <attribute name="cols">2</attribute>
+    <attribute name="colspec"/>
+    <attribute name="style"/>
+    <child name="entry"/>
+    <text>
+         </text>
+    <child name="entry"/>
+    </environment>
+  <macro name="lineii" outputname="row">
+    <child name="entry"/>
+    <text>
+         </text>
+    <child name="entry"/>
+    </macro>
+
+  <environment name="tableiii" outputname="table">
+    <attribute name="cols">3</attribute>
+    <attribute name="colspec"/>
+    <attribute name="style"/>
+    <child name="entry"/>
+    <text>
+         </text>
+    <child name="entry"/>
+    <text>
+         </text>
+    <child name="entry"/>
+    </environment>
+  <environment name="longtableiii" outputname="table">
+    <attribute name="cols">3</attribute>
+    <attribute name="colspec"/>
+    <attribute name="style"/>
+    <child name="entry"/>
+    <text>
+         </text>
+    <child name="entry"/>
+    <text>
+         </text>
+    <child name="entry"/>
+    </environment>
+  <macro name="lineiii" outputname="row">
+    <child name="entry"/>
+    <text>
+         </text>
+    <child name="entry"/>
+    <text>
+         </text>
+    <child name="entry"/>
+    </macro>
+
+  <environment name="tableiv" outputname="table">
+    <attribute name="cols">4</attribute>
+    <attribute name="colspec"/>
+    <attribute name="style"/>
+    <child name="entry"/>
+    <text>
+         </text>
+    <child name="entry"/>
+    <text>
+         </text>
+    <child name="entry"/>
+    <text>
+         </text>
+    <child name="entry"/>
+    </environment>
+  <environment name="longtableiv" outputname="table">
+    <attribute name="cols">4</attribute>
+    <attribute name="colspec"/>
+    <attribute name="style"/>
+    <child name="entry"/>
+    <text>
+         </text>
+    <child name="entry"/>
+    <text>
+         </text>
+    <child name="entry"/>
+    <text>
+         </text>
+    <child name="entry"/>
+    </environment>
+  <macro name="lineiv" outputname="row">
+    <child name="entry"/>
+    <text>
+         </text>
+    <child name="entry"/>
+    <text>
+         </text>
+    <child name="entry"/>
+    <text>
+         </text>
+    <child name="entry"/>
+    </macro>
+
+  <environment name="tablev" outputname="table">
+    <attribute name="cols">4</attribute>
+    <attribute name="colspec"/>
+    <attribute name="style"/>
+    <child name="entry"/>
+    <text>
+         </text>
+    <child name="entry"/>
+    <text>
+         </text>
+    <child name="entry"/>
+    <text>
+         </text>
+    <child name="entry"/>
+    </environment>
+  <environment name="longtablev" outputname="table">
+    <attribute name="cols">4</attribute>
+    <attribute name="colspec"/>
+    <attribute name="style"/>
+    <child name="entry"/>
+    <text>
+         </text>
+    <child name="entry"/>
+    <text>
+         </text>
+    <child name="entry"/>
+    <text>
+         </text>
+    <child name="entry"/>
+    <text>
+         </text>
+    <child name="entry"/>
+    </environment>
+  <macro name="linev" outputname="row">
+    <child name="entry"/>
+    <text>
+         </text>
+    <child name="entry"/>
+    <text>
+         </text>
+    <child name="entry"/>
+    <text>
+         </text>
+    <child name="entry"/>
+    <text>
+         </text>
+    <child name="entry"/>
+    </macro>
+
+  <!-- These are handled at a later translation stage, at least for now. -->
+  <macro name="Cpp" outputname="">
+    <text>C++</text>
+    </macro>
+  <macro name="geq" outputname="">
+    <entityref name="geq"/>
+    </macro>
+  <macro name="infinity" outputname="">
+    <entityref name="infin"/>
+    </macro>
+  <macro name="LaTeX" outputname="">
+    <text>LaTeX</text>
+    </macro>
+  <macro name="ldots" outputname="">
+    <text>...</text>
+    </macro>
+  <macro name="leq" outputname="">
+    <entityref name="leq"/>
+    </macro>
+  <macro name="plusminus" outputname="">
+    <entityref name="plusmn"/>
+    </macro>
+  <macro name="TeX" outputname="">
+    <text>TeX</text>
+    </macro>
+  <macro name="version"/>
+
+  <!-- Distutils things. -->
+  <macro name="command">
+    <content/>
+    </macro>
+  <macro name="option">
+    <content/>
+    </macro>
+  <macro name="filevar" outputname="var">
+    <content/>
+    </macro>
+  <macro name="XXX" outputname="editorial-comment">
+    <content/>
+    </macro>
+
+  <!-- Grammar production lists -->
+  <environment name="productionlist">
+    <attribute name="grammar" optional="yes"/>
+    </environment>
+  <macro name="production">
+    <attribute name="token"/>
+    <content/>
+    </macro>
+  <macro name="productioncont">
+    <content/>
+    </macro>
+  <macro name="token" outputname="grammartoken">
+    <content/>
+    </macro>
+  <macro name="grammartoken">
+    <content/>
+    </macro>
+
+  <!-- Misc. -->
+  <macro name="emph">
+    <content/>
+    </macro>
+  <macro name="strong">
+    <content/>
+    </macro>
+  <macro name="textrm">
+    <content/>
+    </macro>
+  <macro name="texttt">
+    <content/>
+    </macro>
+  <macro name="code">
+    <content/>
+    </macro>
+  <macro name="exception">
+    <content/>
+    </macro>
+  <macro name="keyword">
+    <content/>
+    </macro>
+  <macro name="samp">
+    <content/>
+    </macro>
+  <macro name="class">
+    <content/>
+    </macro>
+  <macro name="cdata">
+    <content/>
+    </macro>
+  <macro name="cfunction">
+    <content/>
+    </macro>
+  <macro name="csimplemacro">
+    <content/>
+    </macro>
+  <macro name="ctype">
+    <content/>
+    </macro>
+  <macro name="pytype">
+    <content/>
+    </macro>
+  <macro name="character">
+    <content/>
+    </macro>
+  <macro name="constant">
+    <content/>
+    </macro>
+  <macro name="envvar" outputname="envar">
+    <content/>
+    </macro>
+  <macro name="file" outputname="filename">
+    <content/>
+    </macro>
+  <macro name="filenq" outputname="filename">
+    <attribute name="quote">no</attribute>
+    <content/>
+    </macro>
+  <macro name="function">
+    <content/>
+    </macro>
+  <macro name="kbd" outputname="keysym">
+    <content/>
+    </macro>
+  <macro name="mailheader">
+    <content/>
+    </macro>
+  <macro name="makevar">
+    <content/>
+    </macro>
+  <macro name="method">
+    <content/>
+    </macro>
+  <macro name="member">
+    <content/>
+    </macro>
+  <macro name="mimetype">
+    <content/>
+    </macro>
+  <macro name="newsgroup">
+    <content/>
+    </macro>
+  <macro name="program" outputname="command">
+    <content/>
+    </macro>
+  <macro name="programopt" outputname="option">
+    <content/>
+    </macro>
+  <macro name="longprogramopt" outputname="longoption">
+    <content/>
+    </macro>
+  <macro name="regexp">
+    <content/>
+    </macro>
+  <macro name="var">
+    <content/>
+    </macro>
+  <macro name="email">
+    <content/>
+    </macro>
+  <macro name="ulink">
+    <!-- order of the parameters makes this difficult;
+         we'll need to fix it up to <ulink href="...">...</ulink>
+         in docfixer.py.
+      -->
+    <child name="text"/>
+    <child name="href"/>
+    </macro>
+  <macro name="url">
+    <content/>
+    </macro>
+  <macro name="footnote">
+    <content/>
+    </macro>
+  <macro name="dfn" outputname="definedterm">
+    <content/>
+    </macro>
+
+  <macro name="mbox">
+    <content/>
+    </macro>
+
+  <!-- minimal math stuff to get by -->
+  <macro name="pi"/>
+  <macro name="sqrt">
+    <content/>
+    </macro>
+  <macro name="frac" outputname="fraction">
+    <child name="numerator"/>
+    <child name="denominator"/>
+    </macro>
+  <macro name="sum">
+    <content/>
+    </macro>
+
+  <macro name="leftline" outputname="">
+    <content/>
+    </macro>
+
+  <!-- Conversions to text; perhaps could be different?  There's -->
+  <!-- no way for a style sheet to work with these this way.	 -->
+  <macro name="ABC" outputname="">
+    <text>ABC</text>
+    </macro>
+  <macro name="ASCII" outputname="">
+    <text>ASCII</text>
+    </macro>
+  <macro name="C" outputname="">
+    <text>C</text>
+    </macro>
+  <macro name="EOF" outputname="">
+    <text>EOF</text>
+    </macro>
+  <macro name="e" outputname="">
+    <text>\</text>
+    </macro>
+  <macro name="NULL" outputname="constant">
+    <text>NULL</text>
+    </macro>
+  <macro name="POSIX" outputname="">
+    <text>POSIX</text>
+    </macro>
+  <macro name="UNIX" outputname="">
+    <text>Unix</text>
+    </macro>
+  <macro name="textasciicircum" outputname="">
+    <text>^</text>
+    </macro>
+  <macro name="textasciitilde" outputname="">
+    <text>~</text>
+    </macro>
+  <macro name="textbackslash" outputname="">
+    <text>\</text>
+    </macro>
+  <macro name="textbar" outputname="">
+    <text>|</text>
+    </macro>
+  <macro name="textgreater" outputname="">
+    <text>&gt;</text>
+    </macro>
+  <macro name="textless" outputname="">
+    <text>&lt;</text>
+    </macro>
+
+  <!-- These will end up disappearing as well! -->
+  <macro name="catcode" outputname=""/>
+  <macro name="fi" outputname=""/>
+  <macro name="ifhtml" outputname=""/>
+  <macro name="indexname" outputname=""/>
+  <macro name="labelwidth" outputname=""/>
+  <macro name="large" outputname=""/>
+  <macro name="leftmargin" outputname=""/>
+  <macro name="makeindex" outputname=""/>
+  <macro name="makemodindex" outputname=""/>
+  <macro name="maketitle" outputname=""/>
+  <macro name="noindent" outputname=""/>
+  <macro name="protect" outputname=""/>
+  <macro name="textwidth"/>
+  <macro name="renewcommand">
+    <attribute name="macro"/>
+    <attribute name="nargs" optional="yes"/>
+    <content/>
+    </macro>
+  <macro name="tableofcontents" outputname=""/>
+  <macro name="vspace">
+    <attribute name="size"/>
+    </macro>
+</conversion>

Added: vendor/Python/current/Doc/tools/sgmlconv/docfixer.py
===================================================================
--- vendor/Python/current/Doc/tools/sgmlconv/docfixer.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/tools/sgmlconv/docfixer.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1073 @@
+#! /usr/bin/env python
+
+"""Perform massive transformations on a document tree created from the LaTeX
+of the Python documentation, and dump the ESIS data for the transformed tree.
+"""
+
+
+import errno
+import esistools
+import re
+import sys
+import xml.dom
+import xml.dom.minidom
+
+ELEMENT = xml.dom.Node.ELEMENT_NODE
+ENTITY_REFERENCE = xml.dom.Node.ENTITY_REFERENCE_NODE
+TEXT = xml.dom.Node.TEXT_NODE
+
+
+class ConversionError(Exception):
+    pass
+
+
+ewrite = sys.stderr.write
+try:
+    # We can only do this trick on Unix (if tput is on $PATH)!
+    if sys.platform != "posix" or not sys.stderr.isatty():
+        raise ImportError
+    import commands
+except ImportError:
+    bwrite = ewrite
+else:
+    def bwrite(s, BOLDON=commands.getoutput("tput bold"),
+               BOLDOFF=commands.getoutput("tput sgr0")):
+        ewrite("%s%s%s" % (BOLDON, s, BOLDOFF))
+
+
+PARA_ELEMENT = "para"
+
+DEBUG_PARA_FIXER = 0
+
+if DEBUG_PARA_FIXER:
+    def para_msg(s):
+        ewrite("*** %s\n" % s)
+else:
+    def para_msg(s):
+        pass
+
+
+def get_first_element(doc, gi):
+    for n in doc.childNodes:
+        if n.nodeName == gi:
+            return n
+
+def extract_first_element(doc, gi):
+    node = get_first_element(doc, gi)
+    if node is not None:
+        doc.removeChild(node)
+    return node
+
+
+def get_documentElement(node):
+    result = None
+    for child in node.childNodes:
+        if child.nodeType == ELEMENT:
+            result = child
+    return result
+
+
+def set_tagName(elem, gi):
+    elem.nodeName = elem.tagName = gi
+
+
+def find_all_elements(doc, gi):
+    nodes = []
+    if doc.nodeName == gi:
+        nodes.append(doc)
+    for child in doc.childNodes:
+        if child.nodeType == ELEMENT:
+            if child.tagName == gi:
+                nodes.append(child)
+            for node in child.getElementsByTagName(gi):
+                nodes.append(node)
+    return nodes
+
+def find_all_child_elements(doc, gi):
+    nodes = []
+    for child in doc.childNodes:
+        if child.nodeName == gi:
+            nodes.append(child)
+    return nodes
+
+
+def find_all_elements_from_set(doc, gi_set):
+    return __find_all_elements_from_set(doc, gi_set, [])
+
+def __find_all_elements_from_set(doc, gi_set, nodes):
+    if doc.nodeName in gi_set:
+        nodes.append(doc)
+    for child in doc.childNodes:
+        if child.nodeType == ELEMENT:
+            __find_all_elements_from_set(child, gi_set, nodes)
+    return nodes
+
+
+def simplify(doc, fragment):
+    # Try to rationalize the document a bit, since these things are simply
+    # not valid SGML/XML documents as they stand, and need a little work.
+    documentclass = "document"
+    inputs = []
+    node = extract_first_element(fragment, "documentclass")
+    if node is not None:
+        documentclass = node.getAttribute("classname")
+    node = extract_first_element(fragment, "title")
+    if node is not None:
+        inputs.append(node)
+    # update the name of the root element
+    node = get_first_element(fragment, "document")
+    if node is not None:
+        set_tagName(node, documentclass)
+        # Move everything that comes before this node into this node;
+        # this will be the document element.
+        nodelist = fragment.childNodes
+        point = node.firstChild
+        while not nodelist[0].isSameNode(node):
+            node.insertBefore(nodelist[0], point)
+    while 1:
+        node = extract_first_element(fragment, "input")
+        if node is None:
+            break
+        inputs.append(node)
+    if inputs:
+        docelem = get_documentElement(fragment)
+        inputs.reverse()
+        for node in inputs:
+            text = doc.createTextNode("\n")
+            docelem.insertBefore(text, docelem.firstChild)
+            docelem.insertBefore(node, text)
+        docelem.insertBefore(doc.createTextNode("\n"), docelem.firstChild)
+    while fragment.firstChild and fragment.firstChild.nodeType == TEXT:
+        fragment.removeChild(fragment.firstChild)
+
+
+def cleanup_root_text(doc):
+    discards = []
+    skip = 0
+    for n in doc.childNodes:
+        prevskip = skip
+        skip = 0
+        if n.nodeType == TEXT and not prevskip:
+            discards.append(n)
+        elif n.nodeName == "COMMENT":
+            skip = 1
+    for node in discards:
+        doc.removeChild(node)
+
+
+DESCRIPTOR_ELEMENTS = (
+    "cfuncdesc", "cvardesc", "ctypedesc",
+    "classdesc", "memberdesc", "memberdescni", "methoddesc", "methoddescni",
+    "excdesc", "funcdesc", "funcdescni", "opcodedesc",
+    "datadesc", "datadescni",
+    )
+
+def fixup_descriptors(doc, fragment):
+    sections = find_all_elements(fragment, "section")
+    for section in sections:
+        find_and_fix_descriptors(doc, section)
+
+
+def find_and_fix_descriptors(doc, container):
+    children = container.childNodes
+    for child in children:
+        if child.nodeType == ELEMENT:
+            tagName = child.tagName
+            if tagName in DESCRIPTOR_ELEMENTS:
+                rewrite_descriptor(doc, child)
+            elif tagName == "subsection":
+                find_and_fix_descriptors(doc, child)
+
+
+def rewrite_descriptor(doc, descriptor):
+    #
+    # Do these things:
+    #   1. Add an "index='no'" attribute to the element if the tagName
+    #      ends in 'ni', removing the 'ni' from the name.
+    #   2. Create a <signature> from the name attribute
+    #   2a.Create an <args> if it appears to be available.
+    #   3. Create additional <signature>s from <*line{,ni}> elements,
+    #      if found.
+    #   4. If a <versionadded> is found, move it to an attribute on the
+    #      descriptor.
+    #   5. Move remaining child nodes to a <description> element.
+    #   6. Put it back together.
+    #
+    # 1.
+    descname = descriptor.tagName
+    index = descriptor.getAttribute("name") != "no"
+    desctype = descname[:-4] # remove 'desc'
+    linename = desctype + "line"
+    if not index:
+        linename = linename + "ni"
+    # 2.
+    signature = doc.createElement("signature")
+    name = doc.createElement("name")
+    signature.appendChild(doc.createTextNode("\n    "))
+    signature.appendChild(name)
+    name.appendChild(doc.createTextNode(descriptor.getAttribute("name")))
+    descriptor.removeAttribute("name")
+    # 2a.
+    if descriptor.hasAttribute("var"):
+        if descname != "opcodedesc":
+            raise RuntimeError, \
+                  "got 'var' attribute on descriptor other than opcodedesc"
+        variable = descriptor.getAttribute("var")
+        if variable:
+            args = doc.createElement("args")
+            args.appendChild(doc.createTextNode(variable))
+            signature.appendChild(doc.createTextNode("\n    "))
+            signature.appendChild(args)
+        descriptor.removeAttribute("var")
+    newchildren = [signature]
+    children = descriptor.childNodes
+    pos = skip_leading_nodes(children)
+    if pos < len(children):
+        child = children[pos]
+        if child.nodeName == "args":
+            # move <args> to <signature>, or remove if empty:
+            child.parentNode.removeChild(child)
+            if len(child.childNodes):
+                signature.appendChild(doc.createTextNode("\n    "))
+                signature.appendChild(child)
+    signature.appendChild(doc.createTextNode("\n  "))
+    # 3, 4.
+    pos = skip_leading_nodes(children, pos)
+    while pos < len(children) \
+          and children[pos].nodeName in (linename, "versionadded"):
+        if children[pos].tagName == linename:
+            # this is really a supplemental signature, create <signature>
+            oldchild = children[pos].cloneNode(1)
+            try:
+                sig = methodline_to_signature(doc, children[pos])
+            except KeyError:
+                print oldchild.toxml()
+                raise
+            newchildren.append(sig)
+        else:
+            # <versionadded added=...>
+            descriptor.setAttribute(
+                "added", children[pos].getAttribute("version"))
+        pos = skip_leading_nodes(children, pos + 1)
+    # 5.
+    description = doc.createElement("description")
+    description.appendChild(doc.createTextNode("\n"))
+    newchildren.append(description)
+    move_children(descriptor, description, pos)
+    last = description.childNodes[-1]
+    if last.nodeType == TEXT:
+        last.data = last.data.rstrip() + "\n  "
+    # 6.
+    # should have nothing but whitespace and signature lines in <descriptor>;
+    # discard them
+    while descriptor.childNodes:
+        descriptor.removeChild(descriptor.childNodes[0])
+    for node in newchildren:
+        descriptor.appendChild(doc.createTextNode("\n  "))
+        descriptor.appendChild(node)
+    descriptor.appendChild(doc.createTextNode("\n"))
+
+
+def methodline_to_signature(doc, methodline):
+    signature = doc.createElement("signature")
+    signature.appendChild(doc.createTextNode("\n    "))
+    name = doc.createElement("name")
+    name.appendChild(doc.createTextNode(methodline.getAttribute("name")))
+    methodline.removeAttribute("name")
+    signature.appendChild(name)
+    if len(methodline.childNodes):
+        args = doc.createElement("args")
+        signature.appendChild(doc.createTextNode("\n    "))
+        signature.appendChild(args)
+        move_children(methodline, args)
+    signature.appendChild(doc.createTextNode("\n  "))
+    return signature
+
+
+def move_children(origin, dest, start=0):
+    children = origin.childNodes
+    while start < len(children):
+        node = children[start]
+        origin.removeChild(node)
+        dest.appendChild(node)
+
+
+def handle_appendix(doc, fragment):
+    # must be called after simplfy() if document is multi-rooted to begin with
+    docelem = get_documentElement(fragment)
+    toplevel = docelem.tagName == "manual" and "chapter" or "section"
+    appendices = 0
+    nodes = []
+    for node in docelem.childNodes:
+        if appendices:
+            nodes.append(node)
+        elif node.nodeType == ELEMENT:
+            appnodes = node.getElementsByTagName("appendix")
+            if appnodes:
+                appendices = 1
+                parent = appnodes[0].parentNode
+                parent.removeChild(appnodes[0])
+                parent.normalize()
+    if nodes:
+        map(docelem.removeChild, nodes)
+        docelem.appendChild(doc.createTextNode("\n\n\n"))
+        back = doc.createElement("back-matter")
+        docelem.appendChild(back)
+        back.appendChild(doc.createTextNode("\n"))
+        while nodes and nodes[0].nodeType == TEXT \
+              and not nodes[0].data.strip():
+            del nodes[0]
+        map(back.appendChild, nodes)
+        docelem.appendChild(doc.createTextNode("\n"))
+
+
+def handle_labels(doc, fragment):
+    for label in find_all_elements(fragment, "label"):
+        id = label.getAttribute("id")
+        if not id:
+            continue
+        parent = label.parentNode
+        parentTagName = parent.tagName
+        if parentTagName == "title":
+            parent.parentNode.setAttribute("id", id)
+        else:
+            parent.setAttribute("id", id)
+        # now, remove <label id="..."/> from parent:
+        parent.removeChild(label)
+        if parentTagName == "title":
+            parent.normalize()
+            children = parent.childNodes
+            if children[-1].nodeType == TEXT:
+                children[-1].data = children[-1].data.rstrip()
+
+
+def fixup_trailing_whitespace(doc, fragment, wsmap):
+    queue = [fragment]
+    fixups = []
+    while queue:
+        node = queue[0]
+        del queue[0]
+        if wsmap.has_key(node.nodeName):
+            fixups.append(node)
+        for child in node.childNodes:
+            if child.nodeType == ELEMENT:
+                queue.append(child)
+
+    # reverse the list to process from the inside out
+    fixups.reverse()
+    for node in fixups:
+        node.parentNode.normalize()
+        lastchild = node.lastChild
+        before, after = wsmap[node.tagName]
+        if lastchild.nodeType == TEXT:
+            data = lastchild.data.rstrip() + before
+            lastchild.data = data
+        norm = 0
+        if wsmap[node.tagName]:
+            nextnode = node.nextSibling
+            if nextnode and nextnode.nodeType == TEXT:
+                nextnode.data = after + nextnode.data.lstrip()
+            else:
+                wsnode = doc.createTextNode(after)
+                node.parentNode.insertBefore(wsnode, nextnode)
+        # hack to get the title in place:
+        if node.tagName == "title" \
+           and node.parentNode.firstChild.nodeType == ELEMENT:
+            node.parentNode.insertBefore(doc.createTextNode("\n  "),
+                                         node.parentNode.firstChild)
+            node.parentNode.normalize()
+
+
+def normalize(doc):
+    for node in doc.childNodes:
+        if node.nodeType == ELEMENT:
+            node.normalize()
+
+
+def cleanup_trailing_parens(doc, element_names):
+    d = {}
+    for gi in element_names:
+        d[gi] = gi
+    rewrite_element = d.has_key
+    queue = [node for node in doc.childNodes if node.nodeType == ELEMENT]
+    while queue:
+        node = queue[0]
+        del queue[0]
+        if rewrite_element(node.tagName):
+            lastchild = node.lastChild
+            if lastchild and lastchild.nodeType == TEXT:
+                data = lastchild.data
+                if data.endswith("()"):
+                    lastchild.data = data[:-2]
+        else:
+            for child in node.childNodes:
+                if child.nodeType == ELEMENT:
+                    queue.append(child)
+
+
+def contents_match(left, right):
+    left_children = left.childNodes
+    right_children = right.childNodes
+    if len(left_children) != len(right_children):
+        return 0
+    for l, r in map(None, left_children, right_children):
+        nodeType = l.nodeType
+        if nodeType != r.nodeType:
+            return 0
+        if nodeType == ELEMENT:
+            if l.tagName != r.tagName:
+                return 0
+            # should check attributes, but that's not a problem here
+            if not contents_match(l, r):
+                return 0
+        elif nodeType == TEXT:
+            if l.data != r.data:
+                return 0
+        else:
+            # not quite right, but good enough
+            return 0
+    return 1
+
+
+def create_module_info(doc, section):
+    # Heavy.
+    node = extract_first_element(section, "modulesynopsis")
+    if node is None:
+        return
+    set_tagName(node, "synopsis")
+    lastchild = node.childNodes[-1]
+    if lastchild.nodeType == TEXT \
+       and lastchild.data[-1:] == ".":
+        lastchild.data = lastchild.data[:-1]
+    modauthor = extract_first_element(section, "moduleauthor")
+    if modauthor:
+        set_tagName(modauthor, "author")
+        modauthor.appendChild(doc.createTextNode(
+            modauthor.getAttribute("name")))
+        modauthor.removeAttribute("name")
+    platform = extract_first_element(section, "platform")
+    if section.tagName == "section":
+        modinfo_pos = 2
+        modinfo = doc.createElement("moduleinfo")
+        moddecl = extract_first_element(section, "declaremodule")
+        name = None
+        if moddecl:
+            modinfo.appendChild(doc.createTextNode("\n    "))
+            name = moddecl.attributes["name"].value
+            namenode = doc.createElement("name")
+            namenode.appendChild(doc.createTextNode(name))
+            modinfo.appendChild(namenode)
+            type = moddecl.attributes.get("type")
+            if type:
+                type = type.value
+                modinfo.appendChild(doc.createTextNode("\n    "))
+                typenode = doc.createElement("type")
+                typenode.appendChild(doc.createTextNode(type))
+                modinfo.appendChild(typenode)
+        versionadded = extract_first_element(section, "versionadded")
+        if versionadded:
+            modinfo.setAttribute("added", versionadded.getAttribute("version"))
+        title = get_first_element(section, "title")
+        if title:
+            children = title.childNodes
+            if len(children) >= 2 \
+               and children[0].nodeName == "module" \
+               and children[0].childNodes[0].data == name:
+                # this is it; morph the <title> into <short-synopsis>
+                first_data = children[1]
+                if first_data.data[:4] == " ---":
+                    first_data.data = first_data.data[4:].lstrip()
+                set_tagName(title, "short-synopsis")
+                if children[-1].nodeType == TEXT \
+                   and children[-1].data[-1:] == ".":
+                    children[-1].data = children[-1].data[:-1]
+                section.removeChild(title)
+                section.removeChild(section.childNodes[0])
+                title.removeChild(children[0])
+                modinfo_pos = 0
+            else:
+                ewrite("module name in title doesn't match"
+                       " <declaremodule/>; no <short-synopsis/>\n")
+        else:
+            ewrite("Unexpected condition: <section/> without <title/>\n")
+        modinfo.appendChild(doc.createTextNode("\n    "))
+        modinfo.appendChild(node)
+        if title and not contents_match(title, node):
+            # The short synopsis is actually different,
+            # and needs to be stored:
+            modinfo.appendChild(doc.createTextNode("\n    "))
+            modinfo.appendChild(title)
+        if modauthor:
+            modinfo.appendChild(doc.createTextNode("\n    "))
+            modinfo.appendChild(modauthor)
+        if platform:
+            modinfo.appendChild(doc.createTextNode("\n    "))
+            modinfo.appendChild(platform)
+        modinfo.appendChild(doc.createTextNode("\n  "))
+        section.insertBefore(modinfo, section.childNodes[modinfo_pos])
+        section.insertBefore(doc.createTextNode("\n  "), modinfo)
+        #
+        # The rest of this removes extra newlines from where we cut out
+        # a lot of elements.  A lot of code for minimal value, but keeps
+        # keeps the generated *ML from being too funny looking.
+        #
+        section.normalize()
+        children = section.childNodes
+        for i in range(len(children)):
+            node = children[i]
+            if node.nodeName == "moduleinfo":
+                nextnode = children[i+1]
+                if nextnode.nodeType == TEXT:
+                    data = nextnode.data
+                    s = data.lstrip()
+                    if len(s) < (len(data) - 4):
+                        nextnode.data = "\n\n\n" + s
+
+
+def cleanup_synopses(doc, fragment):
+    for node in find_all_elements(fragment, "section"):
+        create_module_info(doc, node)
+
+
+def fixup_table_structures(doc, fragment):
+    for table in find_all_elements(fragment, "table"):
+        fixup_table(doc, table)
+
+
+def fixup_table(doc, table):
+    # create the table head
+    thead = doc.createElement("thead")
+    row = doc.createElement("row")
+    move_elements_by_name(doc, table, row, "entry")
+    thead.appendChild(doc.createTextNode("\n    "))
+    thead.appendChild(row)
+    thead.appendChild(doc.createTextNode("\n    "))
+    # create the table body
+    tbody = doc.createElement("tbody")
+    prev_row = None
+    last_was_hline = 0
+    children = table.childNodes
+    for child in children:
+        if child.nodeType == ELEMENT:
+            tagName = child.tagName
+            if tagName == "hline" and prev_row is not None:
+                prev_row.setAttribute("rowsep", "1")
+            elif tagName == "row":
+                prev_row = child
+    # save the rows:
+    tbody.appendChild(doc.createTextNode("\n    "))
+    move_elements_by_name(doc, table, tbody, "row", sep="\n    ")
+    # and toss the rest:
+    while children:
+        child = children[0]
+        nodeType = child.nodeType
+        if nodeType == TEXT:
+            if child.data.strip():
+                raise ConversionError("unexpected free data in <%s>: %r"
+                                      % (table.tagName, child.data))
+            table.removeChild(child)
+            continue
+        if nodeType == ELEMENT:
+            if child.tagName != "hline":
+                raise ConversionError(
+                    "unexpected <%s> in table" % child.tagName)
+            table.removeChild(child)
+            continue
+        raise ConversionError(
+            "unexpected %s node in table" % child.__class__.__name__)
+    # nothing left in the <table>; add the <thead> and <tbody>
+    tgroup = doc.createElement("tgroup")
+    tgroup.appendChild(doc.createTextNode("\n  "))
+    tgroup.appendChild(thead)
+    tgroup.appendChild(doc.createTextNode("\n  "))
+    tgroup.appendChild(tbody)
+    tgroup.appendChild(doc.createTextNode("\n  "))
+    table.appendChild(tgroup)
+    # now make the <entry>s look nice:
+    for row in table.getElementsByTagName("row"):
+        fixup_row(doc, row)
+
+
+def fixup_row(doc, row):
+    entries = []
+    map(entries.append, row.childNodes[1:])
+    for entry in entries:
+        row.insertBefore(doc.createTextNode("\n         "), entry)
+#    row.appendChild(doc.createTextNode("\n      "))
+
+
+def move_elements_by_name(doc, source, dest, name, sep=None):
+    nodes = []
+    for child in source.childNodes:
+        if child.nodeName == name:
+            nodes.append(child)
+    for node in nodes:
+        source.removeChild(node)
+        dest.appendChild(node)
+        if sep:
+            dest.appendChild(doc.createTextNode(sep))
+
+
+RECURSE_INTO_PARA_CONTAINERS = (
+    "chapter", "abstract", "enumerate",
+    "section", "subsection", "subsubsection",
+    "paragraph", "subparagraph", "back-matter",
+    "howto", "manual",
+    "item", "itemize", "fulllineitems", "enumeration", "descriptionlist",
+    "definitionlist", "definition",
+    )
+
+PARA_LEVEL_ELEMENTS = (
+    "moduleinfo", "title", "verbatim", "enumerate", "item",
+    "interpreter-session", "back-matter", "interactive-session",
+    "opcodedesc", "classdesc", "datadesc",
+    "cfuncdesc", "ctypedesc", "cvardesc",
+    "funcdesc", "methoddesc", "excdesc", "memberdesc", "membderdescni",
+    "funcdescni", "methoddescni", "excdescni",
+    "tableii", "tableiii", "tableiv", "localmoduletable",
+    "sectionauthor", "seealso", "itemize",
+    # include <para>, so we can just do it again to get subsequent paras:
+    PARA_ELEMENT,
+    )
+
+PARA_LEVEL_PRECEEDERS = (
+    "setindexsubitem", "author",
+    "stindex", "obindex", "COMMENT", "label", "xi:include", "title",
+    "versionadded", "versionchanged", "declaremodule", "modulesynopsis",
+    "moduleauthor", "indexterm", "leader",
+    )
+
+
+def fixup_paras(doc, fragment):
+    for child in fragment.childNodes:
+        if child.nodeName in RECURSE_INTO_PARA_CONTAINERS:
+            fixup_paras_helper(doc, child)
+    descriptions = find_all_elements(fragment, "description")
+    for description in descriptions:
+        fixup_paras_helper(doc, description)
+
+
+def fixup_paras_helper(doc, container, depth=0):
+    # document is already normalized
+    children = container.childNodes
+    start = skip_leading_nodes(children)
+    while len(children) > start:
+        if children[start].nodeName in RECURSE_INTO_PARA_CONTAINERS:
+            # Something to recurse into:
+            fixup_paras_helper(doc, children[start])
+        else:
+            # Paragraph material:
+            build_para(doc, container, start, len(children))
+            if DEBUG_PARA_FIXER and depth == 10:
+                sys.exit(1)
+        start = skip_leading_nodes(children, start + 1)
+
+
+def build_para(doc, parent, start, i):
+    children = parent.childNodes
+    after = start + 1
+    have_last = 0
+    BREAK_ELEMENTS = PARA_LEVEL_ELEMENTS + RECURSE_INTO_PARA_CONTAINERS
+    # Collect all children until \n\n+ is found in a text node or a
+    # member of BREAK_ELEMENTS is found.
+    for j in range(start, i):
+        after = j + 1
+        child = children[j]
+        nodeType = child.nodeType
+        if nodeType == ELEMENT:
+            if child.tagName in BREAK_ELEMENTS:
+                after = j
+                break
+        elif nodeType == TEXT:
+            pos = child.data.find("\n\n")
+            if pos == 0:
+                after = j
+                break
+            if pos >= 1:
+                child.splitText(pos)
+                break
+    else:
+        have_last = 1
+    if (start + 1) > after:
+        raise ConversionError(
+            "build_para() could not identify content to turn into a paragraph")
+    if children[after - 1].nodeType == TEXT:
+        # we may need to split off trailing white space:
+        child = children[after - 1]
+        data = child.data
+        if data.rstrip() != data:
+            have_last = 0
+            child.splitText(len(data.rstrip()))
+    para = doc.createElement(PARA_ELEMENT)
+    prev = None
+    indexes = range(start, after)
+    indexes.reverse()
+    for j in indexes:
+        node = parent.childNodes[j]
+        parent.removeChild(node)
+        para.insertBefore(node, prev)
+        prev = node
+    if have_last:
+        parent.appendChild(para)
+        parent.appendChild(doc.createTextNode("\n\n"))
+        return len(parent.childNodes)
+    else:
+        nextnode = parent.childNodes[start]
+        if nextnode.nodeType == TEXT:
+            if nextnode.data and nextnode.data[0] != "\n":
+                nextnode.data = "\n" + nextnode.data
+        else:
+            newnode = doc.createTextNode("\n")
+            parent.insertBefore(newnode, nextnode)
+            nextnode = newnode
+            start = start + 1
+        parent.insertBefore(para, nextnode)
+        return start + 1
+
+
+def skip_leading_nodes(children, start=0):
+    """Return index into children of a node at which paragraph building should
+    begin or a recursive call to fixup_paras_helper() should be made (for
+    subsections, etc.).
+
+    When the return value >= len(children), we've built all the paras we can
+    from this list of children.
+    """
+    i = len(children)
+    while i > start:
+        # skip over leading comments and whitespace:
+        child = children[start]
+        nodeType = child.nodeType
+        if nodeType == TEXT:
+            data = child.data
+            shortened = data.lstrip()
+            if shortened:
+                if data != shortened:
+                    # break into two nodes: whitespace and non-whitespace
+                    child.splitText(len(data) - len(shortened))
+                    return start + 1
+                return start
+            # all whitespace, just skip
+        elif nodeType == ELEMENT:
+            tagName = child.tagName
+            if tagName in RECURSE_INTO_PARA_CONTAINERS:
+                return start
+            if tagName not in PARA_LEVEL_ELEMENTS + PARA_LEVEL_PRECEEDERS:
+                return start
+        start = start + 1
+    return start
+
+
+def fixup_rfc_references(doc, fragment):
+    for rfcnode in find_all_elements_from_set(fragment, ("pep", "rfc")):
+        rfcnode.appendChild(doc.createTextNode(
+            rfcnode.tagName.upper() + " " + rfcnode.getAttribute("num")))
+
+
+def fixup_signatures(doc, fragment):
+    for child in fragment.childNodes:
+        if child.nodeType == ELEMENT:
+            args = child.getElementsByTagName("args")
+            for arg in args:
+                rewrite_args(doc, arg)
+            args = child.getElementsByTagName("constructor-args")
+            for arg in args:
+                rewrite_args(doc, arg)
+
+def rewrite_args(doc, arglist):
+    fixup_args(doc, arglist)
+    arglist.normalize()
+    if arglist.childNodes.length == 1 and arglist.firstChild.nodeType == TEXT:
+        node = arglist.firstChild
+        node.data = ' '.join(node.data.split())
+
+def fixup_args(doc, arglist):
+    for child in arglist.childNodes:
+        if child.nodeName == "optional":
+            # found it; fix and return
+            arglist.insertBefore(doc.createTextNode("["), child)
+            optkids = child.childNodes
+            while optkids:
+                arglist.insertBefore(child.firstChild, child)
+            arglist.insertBefore(doc.createTextNode("]"), child)
+            arglist.removeChild(child)
+            return fixup_args(doc, arglist)
+
+
+def fixup_sectionauthors(doc, fragment):
+    for sectauth in find_all_elements(fragment, "sectionauthor"):
+        section = sectauth.parentNode
+        section.removeChild(sectauth)
+        set_tagName(sectauth, "author")
+        sectauth.appendChild(doc.createTextNode(
+            sectauth.getAttribute("name")))
+        sectauth.removeAttribute("name")
+        after = section.childNodes[2]
+        title = section.childNodes[1]
+        if title.nodeName != "title":
+            after = section.childNodes[0]
+        section.insertBefore(doc.createTextNode("\n  "), after)
+        section.insertBefore(sectauth, after)
+
+
+def fixup_verbatims(doc):
+    for verbatim in find_all_elements(doc, "verbatim"):
+        child = verbatim.childNodes[0]
+        if child.nodeType == TEXT \
+           and child.data.lstrip().startswith(">>>"):
+            set_tagName(verbatim, "interactive-session")
+
+
+def add_node_ids(fragment, counter=0):
+    fragment.node_id = counter
+    for node in fragment.childNodes:
+        counter = counter + 1
+        if node.nodeType == ELEMENT:
+            counter = add_node_ids(node, counter)
+        else:
+            node.node_id = counter
+    return counter + 1
+
+
+def fixup_ulink(doc, fragment):
+    for ulink in find_all_elements(fragment, "ulink"):
+        children = ulink.childNodes
+        assert len(children) == 2
+        text = children[0]
+        href = children[1]
+        href.normalize()
+        assert len(href.childNodes) == 1
+        assert href.childNodes[0].nodeType == TEXT
+        url = href.childNodes[0].data
+        ulink.setAttribute("href", url)
+        ulink.removeChild(href)
+        content = text.childNodes
+        while len(content):
+            ulink.appendChild(content[0])
+        ulink.removeChild(text)
+
+
+REFMODINDEX_ELEMENTS = ('refmodindex', 'refbimodindex',
+                        'refexmodindex', 'refstmodindex')
+
+def fixup_refmodindexes(fragment):
+    # Locate <ref*modindex>...</> co-located with <module>...</>, and
+    # remove the <ref*modindex>, replacing it with index=index on the
+    # <module> element.
+    nodes = find_all_elements_from_set(fragment, REFMODINDEX_ELEMENTS)
+    d = {}
+    for node in nodes:
+        parent = node.parentNode
+        d[parent.node_id] = parent
+    del nodes
+    map(fixup_refmodindexes_chunk, d.values())
+
+
+def fixup_refmodindexes_chunk(container):
+    # node is probably a <para>; let's see how often it isn't:
+    if container.tagName != PARA_ELEMENT:
+        bwrite("--- fixup_refmodindexes_chunk(%s)\n" % container)
+    module_entries = find_all_elements(container, "module")
+    if not module_entries:
+        return
+    index_entries = find_all_elements_from_set(container, REFMODINDEX_ELEMENTS)
+    removes = []
+    for entry in index_entries:
+        children = entry.childNodes
+        if len(children) != 0:
+            bwrite("--- unexpected number of children for %s node:\n"
+                   % entry.tagName)
+            ewrite(entry.toxml() + "\n")
+            continue
+        found = 0
+        module_name = entry.getAttribute("module")
+        for node in module_entries:
+            if len(node.childNodes) != 1:
+                continue
+            this_name = node.childNodes[0].data
+            if this_name == module_name:
+                found = 1
+                node.setAttribute("index", "yes")
+        if found:
+            removes.append(entry)
+    for node in removes:
+        container.removeChild(node)
+
+
+def fixup_bifuncindexes(fragment):
+    nodes = find_all_elements(fragment, 'bifuncindex')
+    d = {}
+    # make sure that each parent is only processed once:
+    for node in nodes:
+        parent = node.parentNode
+        d[parent.node_id] = parent
+    del nodes
+    map(fixup_bifuncindexes_chunk, d.values())
+
+
+def fixup_bifuncindexes_chunk(container):
+    removes = []
+    entries = find_all_child_elements(container, "bifuncindex")
+    function_entries = find_all_child_elements(container, "function")
+    for entry in entries:
+        function_name = entry.getAttribute("name")
+        found = 0
+        for func_entry in function_entries:
+            t2 = func_entry.childNodes[0].data
+            if t2[-2:] != "()":
+                continue
+            t2 = t2[:-2]
+            if t2 == function_name:
+                func_entry.setAttribute("index", "yes")
+                func_entry.setAttribute("module", "__builtin__")
+                if not found:
+                    found = 1
+                    removes.append(entry)
+    for entry in removes:
+        container.removeChild(entry)
+
+
+def join_adjacent_elements(container, gi):
+    queue = [container]
+    while queue:
+        parent = queue.pop()
+        i = 0
+        children = parent.childNodes
+        nchildren = len(children)
+        while i < (nchildren - 1):
+            child = children[i]
+            if child.nodeName == gi:
+                if children[i+1].nodeName == gi:
+                    ewrite("--- merging two <%s/> elements\n" % gi)
+                    child = children[i]
+                    nextchild = children[i+1]
+                    nextchildren = nextchild.childNodes
+                    while len(nextchildren):
+                        node = nextchildren[0]
+                        nextchild.removeChild(node)
+                        child.appendChild(node)
+                    parent.removeChild(nextchild)
+                    continue
+            if child.nodeType == ELEMENT:
+                queue.append(child)
+            i = i + 1
+
+
+_token_rx = re.compile(r"[a-zA-Z][a-zA-Z0-9.-]*$")
+
+def write_esis(doc, ofp, knownempty):
+    for node in doc.childNodes:
+        nodeType = node.nodeType
+        if nodeType == ELEMENT:
+            gi = node.tagName
+            if knownempty(gi):
+                if node.hasChildNodes():
+                    raise ValueError, \
+                          "declared-empty node <%s> has children" % gi
+                ofp.write("e\n")
+            for k, value in node.attributes.items():
+                if _token_rx.match(value):
+                    dtype = "TOKEN"
+                else:
+                    dtype = "CDATA"
+                ofp.write("A%s %s %s\n" % (k, dtype, esistools.encode(value)))
+            ofp.write("(%s\n" % gi)
+            write_esis(node, ofp, knownempty)
+            ofp.write(")%s\n" % gi)
+        elif nodeType == TEXT:
+            ofp.write("-%s\n" % esistools.encode(node.data))
+        elif nodeType == ENTITY_REFERENCE:
+            ofp.write("&%s\n" % node.nodeName)
+        else:
+            raise RuntimeError, "unsupported node type: %s" % nodeType
+
+
+def convert(ifp, ofp):
+    events = esistools.parse(ifp)
+    toktype, doc = events.getEvent()
+    fragment = doc.createDocumentFragment()
+    events.expandNode(fragment)
+
+    normalize(fragment)
+    simplify(doc, fragment)
+    handle_labels(doc, fragment)
+    handle_appendix(doc, fragment)
+    fixup_trailing_whitespace(doc, fragment, {
+        # element -> (before-end-tag, after-end-tag)
+        "abstract": ("\n", "\n"),
+        "title": ("", "\n"),
+        "chapter": ("\n", "\n\n\n"),
+        "section": ("\n", "\n\n\n"),
+        "subsection": ("\n", "\n\n"),
+        "subsubsection": ("\n", "\n\n"),
+        "paragraph": ("\n", "\n\n"),
+        "subparagraph": ("\n", "\n\n"),
+        "description": ("\n", "\n\n"),
+        "enumeration": ("\n", "\n\n"),
+        "item": ("\n", "\n\n"),
+        })
+    cleanup_root_text(doc)
+    cleanup_trailing_parens(fragment, ["function", "method", "cfunction"])
+    cleanup_synopses(doc, fragment)
+    fixup_descriptors(doc, fragment)
+    fixup_verbatims(fragment)
+    normalize(fragment)
+    fixup_paras(doc, fragment)
+    fixup_sectionauthors(doc, fragment)
+    fixup_table_structures(doc, fragment)
+    fixup_rfc_references(doc, fragment)
+    fixup_signatures(doc, fragment)
+    fixup_ulink(doc, fragment)
+    add_node_ids(fragment)
+    fixup_refmodindexes(fragment)
+    fixup_bifuncindexes(fragment)
+    # Take care of ugly hacks in the LaTeX markup to avoid LaTeX and
+    # LaTeX2HTML screwing with GNU-style long options (the '--' problem).
+    join_adjacent_elements(fragment, "option")
+    # Attempt to avoid trailing blank lines:
+    fragment.normalize()
+    if fragment.lastChild.data[-1:] == "\n":
+        fragment.lastChild.data = fragment.lastChild.data.rstrip() + "\n"
+    #
+    d = {}
+    for gi in events.parser.get_empties():
+        d[gi] = gi
+    for key in ("author", "pep", "rfc"):
+        if d.has_key(key):
+            del d[key]
+    knownempty = d.has_key
+    #
+    try:
+        write_esis(fragment, ofp, knownempty)
+    except IOError, (err, msg):
+        # Ignore EPIPE; it just means that whoever we're writing to stopped
+        # reading.  The rest of the output would be ignored.  All other errors
+        # should still be reported,
+        if err != errno.EPIPE:
+            raise
+
+
+def main():
+    if len(sys.argv) == 1:
+        ifp = sys.stdin
+        ofp = sys.stdout
+    elif len(sys.argv) == 2:
+        ifp = open(sys.argv[1])
+        ofp = sys.stdout
+    elif len(sys.argv) == 3:
+        ifp = open(sys.argv[1])
+        import StringIO
+        ofp = StringIO.StringIO()
+    else:
+        usage()
+        sys.exit(2)
+    convert(ifp, ofp)
+    if len(sys.argv) == 3:
+        fp = open(sys.argv[2], "w")
+        fp.write(ofp.getvalue())
+        fp.close()
+        ofp.close()
+
+
+if __name__ == "__main__":
+    main()


Property changes on: vendor/Python/current/Doc/tools/sgmlconv/docfixer.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Doc/tools/sgmlconv/esis2sgml.py
===================================================================
--- vendor/Python/current/Doc/tools/sgmlconv/esis2sgml.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/tools/sgmlconv/esis2sgml.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,264 @@
+#! /usr/bin/env python
+
+"""Convert ESIS events to SGML or XML markup.
+
+This is limited, but seems sufficient for the ESIS generated by the
+latex2esis.py script when run over the Python documentation.
+"""
+
+# This should have an explicit option to indicate whether the *INPUT* was
+# generated from an SGML or an XML application.
+
+import errno
+import os
+import re
+import string
+
+from xml.sax.saxutils import escape
+
+import esistools
+
+
+AUTOCLOSE = ()
+
+EMPTIES_FILENAME = "../sgml/empties.dat"
+LIST_EMPTIES = 0
+
+
+_elem_map = {}
+_attr_map = {}
+_token_map = {}
+
+_normalize_case = str
+
+def map_gi(sgmlgi, map):
+    uncased = _normalize_case(sgmlgi)
+    try:
+        return map[uncased]
+    except IndexError:
+        map[uncased] = sgmlgi
+        return sgmlgi
+
+def null_map_gi(sgmlgi, map):
+    return sgmlgi
+
+
+def format_attrs(attrs, xml=0):
+    attrs = attrs.items()
+    attrs.sort()
+    parts = []
+    append = parts.append
+    for name, value in attrs:
+        if xml:
+            append('%s="%s"' % (name, escape(value)))
+        else:
+            # this is a little bogus, but should do for now
+            if name == value and isnmtoken(value):
+                append(value)
+            elif istoken(value):
+                if value == "no" + name:
+                    append(value)
+                else:
+                    append("%s=%s" % (name, value))
+            else:
+                append('%s="%s"' % (name, escape(value)))
+    if parts:
+        parts.insert(0, '')
+    return " ".join(parts)
+
+
+_nmtoken_rx = re.compile("[a-z][-._a-z0-9]*$", re.IGNORECASE)
+def isnmtoken(s):
+    return _nmtoken_rx.match(s) is not None
+
+_token_rx = re.compile("[a-z0-9][-._a-z0-9]*$", re.IGNORECASE)
+def istoken(s):
+    return _token_rx.match(s) is not None
+
+
+def convert(ifp, ofp, xml=0, autoclose=(), verbatims=()):
+    if xml:
+        autoclose = ()
+    attrs = {}
+    lastopened = None
+    knownempties = []
+    knownempty = 0
+    lastempty = 0
+    inverbatim = 0
+    while 1:
+        line = ifp.readline()
+        if not line:
+            break
+
+        type = line[0]
+        data = line[1:]
+        if data and data[-1] == "\n":
+            data = data[:-1]
+        if type == "-":
+            data = esistools.decode(data)
+            data = escape(data)
+            if not inverbatim:
+                data = data.replace("---", "&mdash;")
+            ofp.write(data)
+            if "\n" in data:
+                lastopened = None
+            knownempty = 0
+            lastempty = 0
+        elif type == "(":
+            if data == "COMMENT":
+                ofp.write("<!--")
+                continue
+            data = map_gi(data, _elem_map)
+            if knownempty and xml:
+                ofp.write("<%s%s/>" % (data, format_attrs(attrs, xml)))
+            else:
+                ofp.write("<%s%s>" % (data, format_attrs(attrs, xml)))
+            if knownempty and data not in knownempties:
+                # accumulate knowledge!
+                knownempties.append(data)
+            attrs = {}
+            lastopened = data
+            lastempty = knownempty
+            knownempty = 0
+            inverbatim = data in verbatims
+        elif type == ")":
+            if data == "COMMENT":
+                ofp.write("-->")
+                continue
+            data = map_gi(data, _elem_map)
+            if xml:
+                if not lastempty:
+                    ofp.write("</%s>" % data)
+            elif data not in knownempties:
+                if data in autoclose:
+                    pass
+                elif lastopened == data:
+                    ofp.write("</>")
+                else:
+                    ofp.write("</%s>" % data)
+            lastopened = None
+            lastempty = 0
+            inverbatim = 0
+        elif type == "A":
+            name, type, value = data.split(" ", 2)
+            name = map_gi(name, _attr_map)
+            attrs[name] = esistools.decode(value)
+        elif type == "e":
+            knownempty = 1
+        elif type == "&":
+            ofp.write("&%s;" % data)
+            knownempty = 0
+        else:
+            raise RuntimeError, "unrecognized ESIS event type: '%s'" % type
+
+    if LIST_EMPTIES:
+        dump_empty_element_names(knownempties)
+
+
+def dump_empty_element_names(knownempties):
+    d = {}
+    for gi in knownempties:
+        d[gi] = gi
+    knownempties.append("")
+    if os.path.isfile(EMPTIES_FILENAME):
+        fp = open(EMPTIES_FILENAME)
+        while 1:
+            line = fp.readline()
+            if not line:
+                break
+            gi = line.strip()
+            if gi:
+                d[gi] = gi
+    fp = open(EMPTIES_FILENAME, "w")
+    gilist = d.keys()
+    gilist.sort()
+    fp.write("\n".join(gilist))
+    fp.write("\n")
+    fp.close()
+
+
+def update_gi_map(map, names, fromsgml=1):
+    for name in names.split(","):
+        if fromsgml:
+            uncased = name.lower()
+        else:
+            uncased = name
+        map[uncased] = name
+
+
+def main():
+    import getopt
+    import sys
+    #
+    autoclose = AUTOCLOSE
+    xml = 1
+    xmldecl = 0
+    elem_names = ''
+    attr_names = ''
+    value_names = ''
+    verbatims = ('verbatim', 'interactive-session')
+    opts, args = getopt.getopt(sys.argv[1:], "adesx",
+                               ["autoclose=", "declare", "sgml", "xml",
+                                "elements-map=", "attributes-map",
+                                "values-map="])
+    for opt, arg in opts:
+        if opt in ("-d", "--declare"):
+            xmldecl = 1
+        elif opt == "-e":
+            global LIST_EMPTIES
+            LIST_EMPTIES = 1
+        elif opt in ("-s", "--sgml"):
+            xml = 0
+        elif opt in ("-x", "--xml"):
+            xml = 1
+        elif opt in ("-a", "--autoclose"):
+            autoclose = arg.split(",")
+        elif opt == "--elements-map":
+            elem_names = ("%s,%s" % (elem_names, arg))[1:]
+        elif opt == "--attributes-map":
+            attr_names = ("%s,%s" % (attr_names, arg))[1:]
+        elif opt == "--values-map":
+            value_names = ("%s,%s" % (value_names, arg))[1:]
+    #
+    # open input streams:
+    #
+    if len(args) == 0:
+        ifp = sys.stdin
+        ofp = sys.stdout
+    elif len(args) == 1:
+        ifp = open(args[0])
+        ofp = sys.stdout
+    elif len(args) == 2:
+        ifp = open(args[0])
+        ofp = open(args[1], "w")
+    else:
+        usage()
+        sys.exit(2)
+    #
+    # setup the name maps:
+    #
+    if elem_names or attr_names or value_names:
+        # assume the origin was SGML; ignore case of the names from the ESIS
+        # stream but set up conversion tables to get the case right on output
+        global _normalize_case
+        _normalize_case = string.lower
+        update_gi_map(_elem_map, elem_names.split(","))
+        update_gi_map(_attr_map, attr_names.split(","))
+        update_gi_map(_values_map, value_names.split(","))
+    else:
+        global map_gi
+        map_gi = null_map_gi
+    #
+    # run the conversion:
+    #
+    try:
+        if xml and xmldecl:
+            opf.write('<?xml version="1.0" encoding="iso8859-1"?>\n')
+        convert(ifp, ofp, xml=xml, autoclose=autoclose, verbatims=verbatims)
+    except IOError, (err, msg):
+        if err != errno.EPIPE:
+            raise
+
+
+if __name__ == "__main__":
+    main()


Property changes on: vendor/Python/current/Doc/tools/sgmlconv/esis2sgml.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Doc/tools/sgmlconv/esistools.py
===================================================================
--- vendor/Python/current/Doc/tools/sgmlconv/esistools.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/tools/sgmlconv/esistools.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,312 @@
+"""Miscellaneous utility functions useful for dealing with ESIS streams."""
+
+import re
+
+import xml.dom.pulldom
+
+import xml.sax
+import xml.sax.handler
+import xml.sax.xmlreader
+
+
+_data_match = re.compile(r"[^\\][^\\]*").match
+
+def decode(s):
+    r = ''
+    while s:
+        m = _data_match(s)
+        if m:
+            r = r + m.group()
+            s = s[m.end():]
+        elif s[1] == "\\":
+            r = r + "\\"
+            s = s[2:]
+        elif s[1] == "n":
+            r = r + "\n"
+            s = s[2:]
+        elif s[1] == "%":
+            s = s[2:]
+            n, s = s.split(";", 1)
+            r = r + unichr(int(n))
+        else:
+            raise ValueError, "can't handle %r" % s
+    return r
+
+
+_charmap = {}
+for c in range(128):
+    _charmap[chr(c)] = chr(c)
+    _charmap[unichr(c + 128)] = chr(c + 128)
+_charmap["\n"] = r"\n"
+_charmap["\\"] = r"\\"
+del c
+
+_null_join = ''.join
+def encode(s):
+    try:
+        return _null_join(map(_charmap.get, s))
+    except TypeError:
+        raise Exception("could not encode %r: %r" % (s, map(_charmap.get, s)))
+
+
+class ESISReader(xml.sax.xmlreader.XMLReader):
+    """SAX Reader which reads from an ESIS stream.
+
+    No verification of the document structure is performed by the
+    reader; a general verifier could be used as the target
+    ContentHandler instance.
+
+    """
+    _decl_handler = None
+    _lexical_handler = None
+
+    _public_id = None
+    _system_id = None
+
+    _buffer = ""
+    _is_empty = 0
+    _lineno = 0
+    _started = 0
+
+    def __init__(self, contentHandler=None, errorHandler=None):
+        xml.sax.xmlreader.XMLReader.__init__(self)
+        self._attrs = {}
+        self._attributes = Attributes(self._attrs)
+        self._locator = Locator()
+        self._empties = {}
+        if contentHandler:
+            self.setContentHandler(contentHandler)
+        if errorHandler:
+            self.setErrorHandler(errorHandler)
+
+    def get_empties(self):
+        return self._empties.keys()
+
+    #
+    #  XMLReader interface
+    #
+
+    def parse(self, source):
+        raise RuntimeError
+        self._locator._public_id = source.getPublicId()
+        self._locator._system_id = source.getSystemId()
+        fp = source.getByteStream()
+        handler = self.getContentHandler()
+        if handler:
+            handler.startDocument()
+        lineno = 0
+        while 1:
+            token, data = self._get_token(fp)
+            if token is None:
+                break
+            lineno = lineno + 1
+            self._locator._lineno = lineno
+            self._handle_token(token, data)
+        handler = self.getContentHandler()
+        if handler:
+            handler.startDocument()
+
+    def feed(self, data):
+        if not self._started:
+            handler = self.getContentHandler()
+            if handler:
+                handler.startDocument()
+            self._started = 1
+        data = self._buffer + data
+        self._buffer = None
+        lines = data.split("\n")
+        if lines:
+            for line in lines[:-1]:
+                self._lineno = self._lineno + 1
+                self._locator._lineno = self._lineno
+                if not line:
+                    e = xml.sax.SAXParseException(
+                        "ESIS input line contains no token type mark",
+                        None, self._locator)
+                    self.getErrorHandler().error(e)
+                else:
+                    self._handle_token(line[0], line[1:])
+            self._buffer = lines[-1]
+        else:
+            self._buffer = ""
+
+    def close(self):
+        handler = self.getContentHandler()
+        if handler:
+            handler.endDocument()
+        self._buffer = ""
+
+    def _get_token(self, fp):
+        try:
+            line = fp.readline()
+        except IOError, e:
+            e = SAXException("I/O error reading input stream", e)
+            self.getErrorHandler().fatalError(e)
+            return
+        if not line:
+            return None, None
+        if line[-1] == "\n":
+            line = line[:-1]
+        if not line:
+            e = xml.sax.SAXParseException(
+                "ESIS input line contains no token type mark",
+                None, self._locator)
+            self.getErrorHandler().error(e)
+            return
+        return line[0], line[1:]
+
+    def _handle_token(self, token, data):
+        handler = self.getContentHandler()
+        if token == '-':
+            if data and handler:
+                handler.characters(decode(data))
+        elif token == ')':
+            if handler:
+                handler.endElement(decode(data))
+        elif token == '(':
+            if self._is_empty:
+                self._empties[data] = 1
+                self._is_empty = 0
+            if handler:
+                handler.startElement(data, self._attributes)
+            self._attrs.clear()
+        elif token == 'A':
+            name, value = data.split(' ', 1)
+            if value != "IMPLIED":
+                type, value = value.split(' ', 1)
+                self._attrs[name] = (decode(value), type)
+        elif token == '&':
+            # entity reference in SAX?
+            pass
+        elif token == '?':
+            if handler:
+                if ' ' in data:
+                    target, data = data.split(None, 1)
+                else:
+                    target, data = data, ""
+                handler.processingInstruction(target, decode(data))
+        elif token == 'N':
+            handler = self.getDTDHandler()
+            if handler:
+                handler.notationDecl(data, self._public_id, self._system_id)
+            self._public_id = None
+            self._system_id = None
+        elif token == 'p':
+            self._public_id = decode(data)
+        elif token == 's':
+            self._system_id = decode(data)
+        elif token == 'e':
+            self._is_empty = 1
+        elif token == 'C':
+            pass
+        else:
+            e = SAXParseException("unknown ESIS token in event stream",
+                                  None, self._locator)
+            self.getErrorHandler().error(e)
+
+    def setContentHandler(self, handler):
+        old = self.getContentHandler()
+        if old:
+            old.setDocumentLocator(None)
+        if handler:
+            handler.setDocumentLocator(self._locator)
+        xml.sax.xmlreader.XMLReader.setContentHandler(self, handler)
+
+    def getProperty(self, property):
+        if property == xml.sax.handler.property_lexical_handler:
+            return self._lexical_handler
+
+        elif property == xml.sax.handler.property_declaration_handler:
+            return self._decl_handler
+
+        else:
+            raise xml.sax.SAXNotRecognizedException("unknown property %r"
+                                                    % (property, ))
+
+    def setProperty(self, property, value):
+        if property == xml.sax.handler.property_lexical_handler:
+            if self._lexical_handler:
+                self._lexical_handler.setDocumentLocator(None)
+            if value:
+                value.setDocumentLocator(self._locator)
+            self._lexical_handler = value
+
+        elif property == xml.sax.handler.property_declaration_handler:
+            if self._decl_handler:
+                self._decl_handler.setDocumentLocator(None)
+            if value:
+                value.setDocumentLocator(self._locator)
+            self._decl_handler = value
+
+        else:
+            raise xml.sax.SAXNotRecognizedException()
+
+    def getFeature(self, feature):
+        if feature == xml.sax.handler.feature_namespaces:
+            return 1
+        else:
+            return xml.sax.xmlreader.XMLReader.getFeature(self, feature)
+
+    def setFeature(self, feature, enabled):
+        if feature == xml.sax.handler.feature_namespaces:
+            pass
+        else:
+            xml.sax.xmlreader.XMLReader.setFeature(self, feature, enabled)
+
+
+class Attributes(xml.sax.xmlreader.AttributesImpl):
+    # self._attrs has the form {name: (value, type)}
+
+    def getType(self, name):
+        return self._attrs[name][1]
+
+    def getValue(self, name):
+        return self._attrs[name][0]
+
+    def getValueByQName(self, name):
+        return self._attrs[name][0]
+
+    def __getitem__(self, name):
+        return self._attrs[name][0]
+
+    def get(self, name, default=None):
+        if self._attrs.has_key(name):
+            return self._attrs[name][0]
+        return default
+
+    def items(self):
+        L = []
+        for name, (value, type) in self._attrs.items():
+            L.append((name, value))
+        return L
+
+    def values(self):
+        L = []
+        for value, type in self._attrs.values():
+            L.append(value)
+        return L
+
+
+class Locator(xml.sax.xmlreader.Locator):
+    _lineno = -1
+    _public_id = None
+    _system_id = None
+
+    def getLineNumber(self):
+        return self._lineno
+
+    def getPublicId(self):
+        return self._public_id
+
+    def getSystemId(self):
+        return self._system_id
+
+
+def parse(stream_or_string, parser=None):
+    if type(stream_or_string) in [type(""), type(u"")]:
+        stream = open(stream_or_string)
+    else:
+        stream = stream_or_string
+    if not parser:
+        parser = ESISReader()
+    return xml.dom.pulldom.DOMEventStream(stream, parser, (2 ** 14) - 20)

Added: vendor/Python/current/Doc/tools/sgmlconv/latex2esis.py
===================================================================
--- vendor/Python/current/Doc/tools/sgmlconv/latex2esis.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/tools/sgmlconv/latex2esis.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,565 @@
+#! /usr/bin/env python
+
+"""Generate ESIS events based on a LaTeX source document and
+configuration data.
+
+The conversion is not strong enough to work with arbitrary LaTeX
+documents; it has only been designed to work with the highly stylized
+markup used in the standard Python documentation.  A lot of
+information about specific markup is encoded in the control table
+passed to the convert() function; changing this table can allow this
+tool to support additional LaTeX markups.
+
+The format of the table is largely undocumented; see the commented
+headers where the table is specified in main().  There is no provision
+to load an alternate table from an external file.
+"""
+
+import errno
+import getopt
+import os
+import re
+import sys
+import xml.sax
+import xml.sax.saxutils
+
+from esistools import encode
+
+
+DEBUG = 0
+
+
+class LaTeXFormatError(Exception):
+    pass
+
+
+class LaTeXStackError(LaTeXFormatError):
+    def __init__(self, found, stack):
+        msg = "environment close for %s doesn't match;\n  stack = %s" \
+              % (found, stack)
+        self.found = found
+        self.stack = stack[:]
+        LaTeXFormatError.__init__(self, msg)
+
+
+_begin_env_rx = re.compile(r"[\\]begin{([^}]*)}")
+_end_env_rx = re.compile(r"[\\]end{([^}]*)}")
+_begin_macro_rx = re.compile(r"[\\]([a-zA-Z]+[*]?) ?({|\s*\n?)")
+_comment_rx = re.compile("%+ ?(.*)\n[ \t]*")
+_text_rx = re.compile(r"[^]~%\\{}]+")
+_optional_rx = re.compile(r"\s*[[]([^]]*)[]]", re.MULTILINE)
+# _parameter_rx is this complicated to allow {...} inside a parameter;
+# this is useful to match tabular layout specifications like {c|p{24pt}}
+_parameter_rx = re.compile("[ \n]*{(([^{}}]|{[^}]*})*)}")
+_token_rx = re.compile(r"[a-zA-Z][a-zA-Z0-9.-]*$")
+_start_group_rx = re.compile("[ \n]*{")
+_start_optional_rx = re.compile("[ \n]*[[]")
+
+
+ESCAPED_CHARS = "$%#^ {}&~"
+
+
+def dbgmsg(msg):
+    if DEBUG:
+        sys.stderr.write(msg + "\n")
+
+def pushing(name, point, depth):
+    dbgmsg("pushing <%s> at %s" % (name, point))
+
+def popping(name, point, depth):
+    dbgmsg("popping </%s> at %s" % (name, point))
+
+
+class _Stack(list):
+    def append(self, entry):
+        if not isinstance(entry, str):
+            raise LaTeXFormatError("cannot push non-string on stack: %r"
+                                   % (entry, ))
+        #dbgmsg("%s<%s>" % (" "*len(self.data), entry))
+        list.append(self, entry)
+
+    def pop(self, index=-1):
+        entry = self[index]
+        del self[index]
+        #dbgmsg("%s</%s>" % (" " * len(self), entry))
+
+    def __delitem__(self, index):
+        entry = self[index]
+        list.__delitem__(self, index)
+        #dbgmsg("%s</%s>" % (" " * len(self), entry))
+
+
+def new_stack():
+    if DEBUG:
+        return _Stack()
+    else:
+        return []
+
+
+class Conversion:
+    def __init__(self, ifp, ofp, table):
+        self.write = ofp.write
+        self.ofp = ofp
+        self.table = table
+        L = [s.rstrip() for s in ifp.readlines()]
+        L.append("")
+        self.line = "\n".join(L)
+        self.preamble = 1
+
+    def convert(self):
+        self.subconvert()
+
+    def subconvert(self, endchar=None, depth=0):
+        #
+        # Parses content, including sub-structures, until the character
+        # 'endchar' is found (with no open structures), or until the end
+        # of the input data is endchar is None.
+        #
+        stack = new_stack()
+        line = self.line
+        while line:
+            if line[0] == endchar and not stack:
+                self.line = line
+                return line
+            m = _comment_rx.match(line)
+            if m:
+                text = m.group(1)
+                if text:
+                    self.write("(COMMENT\n- %s \n)COMMENT\n-\\n\n"
+                               % encode(text))
+                line = line[m.end():]
+                continue
+            m = _begin_env_rx.match(line)
+            if m:
+                name = m.group(1)
+                entry = self.get_env_entry(name)
+                # re-write to use the macro handler
+                line = r"\%s %s" % (name, line[m.end():])
+                continue
+            m = _end_env_rx.match(line)
+            if m:
+                # end of environment
+                envname = m.group(1)
+                entry = self.get_entry(envname)
+                while stack and envname != stack[-1] \
+                      and stack[-1] in entry.endcloses:
+                    self.write(")%s\n" % stack.pop())
+                if stack and envname == stack[-1]:
+                    self.write(")%s\n" % entry.outputname)
+                    del stack[-1]
+                else:
+                    raise LaTeXStackError(envname, stack)
+                line = line[m.end():]
+                continue
+            m = _begin_macro_rx.match(line)
+            if m:
+                # start of macro
+                macroname = m.group(1)
+                if macroname == "c":
+                    # Ugh!  This is a combining character...
+                    endpos = m.end()
+                    self.combining_char("c", line[endpos])
+                    line = line[endpos + 1:]
+                    continue
+                entry = self.get_entry(macroname)
+                if entry.verbatim:
+                    # magic case!
+                    pos = line.find("\\end{%s}" % macroname)
+                    text = line[m.end(1):pos]
+                    stack.append(entry.name)
+                    self.write("(%s\n" % entry.outputname)
+                    self.write("-%s\n" % encode(text))
+                    self.write(")%s\n" % entry.outputname)
+                    stack.pop()
+                    line = line[pos + len("\\end{%s}" % macroname):]
+                    continue
+                while stack and stack[-1] in entry.closes:
+                    top = stack.pop()
+                    topentry = self.get_entry(top)
+                    if topentry.outputname:
+                        self.write(")%s\n-\\n\n" % topentry.outputname)
+                #
+                if entry.outputname and entry.empty:
+                    self.write("e\n")
+                #
+                params, optional, empty = self.start_macro(macroname)
+                # rip off the macroname
+                if params:
+                    line = line[m.end(1):]
+                elif empty:
+                    line = line[m.end(1):]
+                else:
+                    line = line[m.end():]
+                opened = 0
+                implied_content = 0
+
+                # handle attribute mappings here:
+                for pentry in params:
+                    if pentry.type == "attribute":
+                        if pentry.optional:
+                            m = _optional_rx.match(line)
+                            if m and entry.outputname:
+                                line = line[m.end():]
+                                self.dump_attr(pentry, m.group(1))
+                        elif pentry.text and entry.outputname:
+                            # value supplied by conversion spec:
+                            self.dump_attr(pentry, pentry.text)
+                        else:
+                            m = _parameter_rx.match(line)
+                            if not m:
+                                raise LaTeXFormatError(
+                                    "could not extract parameter %s for %s: %r"
+                                    % (pentry.name, macroname, line[:100]))
+                            if entry.outputname:
+                                self.dump_attr(pentry, m.group(1))
+                            line = line[m.end():]
+                    elif pentry.type == "child":
+                        if pentry.optional:
+                            m = _optional_rx.match(line)
+                            if m:
+                                line = line[m.end():]
+                                if entry.outputname and not opened:
+                                    opened = 1
+                                    self.write("(%s\n" % entry.outputname)
+                                    stack.append(macroname)
+                                stack.append(pentry.name)
+                                self.write("(%s\n" % pentry.name)
+                                self.write("-%s\n" % encode(m.group(1)))
+                                self.write(")%s\n" % pentry.name)
+                                stack.pop()
+                        else:
+                            if entry.outputname and not opened:
+                                opened = 1
+                                self.write("(%s\n" % entry.outputname)
+                                stack.append(entry.name)
+                            self.write("(%s\n" % pentry.name)
+                            stack.append(pentry.name)
+                            self.line = skip_white(line)[1:]
+                            line = self.subconvert(
+                                "}", len(stack) + depth + 1)[1:]
+                            self.write(")%s\n" % stack.pop())
+                    elif pentry.type == "content":
+                        if pentry.implied:
+                            implied_content = 1
+                        else:
+                            if entry.outputname and not opened:
+                                opened = 1
+                                self.write("(%s\n" % entry.outputname)
+                                stack.append(entry.name)
+                            line = skip_white(line)
+                            if line[0] != "{":
+                                raise LaTeXFormatError(
+                                    "missing content for " + macroname)
+                            self.line = line[1:]
+                            line = self.subconvert("}", len(stack) + depth + 1)
+                            if line and line[0] == "}":
+                                line = line[1:]
+                    elif pentry.type == "text" and pentry.text:
+                        if entry.outputname and not opened:
+                            opened = 1
+                            stack.append(entry.name)
+                            self.write("(%s\n" % entry.outputname)
+                        #dbgmsg("--- text: %r" % pentry.text)
+                        self.write("-%s\n" % encode(pentry.text))
+                    elif pentry.type == "entityref":
+                        self.write("&%s\n" % pentry.name)
+                if entry.outputname:
+                    if not opened:
+                        self.write("(%s\n" % entry.outputname)
+                        stack.append(entry.name)
+                    if not implied_content:
+                        self.write(")%s\n" % entry.outputname)
+                        stack.pop()
+                continue
+            if line[0] == endchar and not stack:
+                self.line = line[1:]
+                return self.line
+            if line[0] == "}":
+                # end of macro or group
+                macroname = stack[-1]
+                if macroname:
+                    conversion = self.table[macroname]
+                    if conversion.outputname:
+                        # otherwise, it was just a bare group
+                        self.write(")%s\n" % conversion.outputname)
+                del stack[-1]
+                line = line[1:]
+                continue
+            if line[0] == "~":
+                # don't worry about the "tie" aspect of this command
+                line = line[1:]
+                self.write("- \n")
+                continue
+            if line[0] == "{":
+                stack.append("")
+                line = line[1:]
+                continue
+            if line[0] == "\\" and line[1] in ESCAPED_CHARS:
+                self.write("-%s\n" % encode(line[1]))
+                line = line[2:]
+                continue
+            if line[:2] == r"\\":
+                self.write("(BREAK\n)BREAK\n")
+                line = line[2:]
+                continue
+            if line[:2] == r"\_":
+                line = "_" + line[2:]
+                continue
+            if line[:2] in (r"\'", r'\"'):
+                # combining characters...
+                self.combining_char(line[1], line[2])
+                line = line[3:]
+                continue
+            m = _text_rx.match(line)
+            if m:
+                text = encode(m.group())
+                self.write("-%s\n" % text)
+                line = line[m.end():]
+                continue
+            # special case because of \item[]
+            # XXX can we axe this???
+            if line[0] == "]":
+                self.write("-]\n")
+                line = line[1:]
+                continue
+            # avoid infinite loops
+            extra = ""
+            if len(line) > 100:
+                extra = "..."
+            raise LaTeXFormatError("could not identify markup: %r%s"
+                                   % (line[:100], extra))
+        while stack:
+            entry = self.get_entry(stack[-1])
+            if entry.closes:
+                self.write(")%s\n-%s\n" % (entry.outputname, encode("\n")))
+                del stack[-1]
+            else:
+                break
+        if stack:
+            raise LaTeXFormatError("elements remain on stack: "
+                                   + ", ".join(stack))
+        # otherwise we just ran out of input here...
+
+    # This is a really limited table of combinations, but it will have
+    # to do for now.
+    _combinations = {
+        ("c", "c"): 0x00E7,
+        ("'", "e"): 0x00E9,
+        ('"', "o"): 0x00F6,
+        }
+
+    def combining_char(self, prefix, char):
+        ordinal = self._combinations[(prefix, char)]
+        self.write("-\\%%%d;\n" % ordinal)
+
+    def start_macro(self, name):
+        conversion = self.get_entry(name)
+        parameters = conversion.parameters
+        optional = parameters and parameters[0].optional
+        return parameters, optional, conversion.empty
+
+    def get_entry(self, name):
+        entry = self.table.get(name)
+        if entry is None:
+            dbgmsg("get_entry(%r) failing; building default entry!" % (name, ))
+            # not defined; build a default entry:
+            entry = TableEntry(name)
+            entry.has_content = 1
+            entry.parameters.append(Parameter("content"))
+            self.table[name] = entry
+        return entry
+
+    def get_env_entry(self, name):
+        entry = self.table.get(name)
+        if entry is None:
+            # not defined; build a default entry:
+            entry = TableEntry(name, 1)
+            entry.has_content = 1
+            entry.parameters.append(Parameter("content"))
+            entry.parameters[-1].implied = 1
+            self.table[name] = entry
+        elif not entry.environment:
+            raise LaTeXFormatError(
+                name + " is defined as a macro; expected environment")
+        return entry
+
+    def dump_attr(self, pentry, value):
+        if not (pentry.name and value):
+            return
+        if _token_rx.match(value):
+            dtype = "TOKEN"
+        else:
+            dtype = "CDATA"
+        self.write("A%s %s %s\n" % (pentry.name, dtype, encode(value)))
+
+
+def convert(ifp, ofp, table):
+    c = Conversion(ifp, ofp, table)
+    try:
+        c.convert()
+    except IOError, (err, msg):
+        if err != errno.EPIPE:
+            raise
+
+
+def skip_white(line):
+    while line and line[0] in " %\n\t\r":
+        line = line[1:].lstrip()
+    return line
+
+
+
+class TableEntry:
+    def __init__(self, name, environment=0):
+        self.name = name
+        self.outputname = name
+        self.environment = environment
+        self.empty = not environment
+        self.has_content = 0
+        self.verbatim = 0
+        self.auto_close = 0
+        self.parameters = []
+        self.closes = []
+        self.endcloses = []
+
+class Parameter:
+    def __init__(self, type, name=None, optional=0):
+        self.type = type
+        self.name = name
+        self.optional = optional
+        self.text = ''
+        self.implied = 0
+
+
+class TableHandler(xml.sax.handler.ContentHandler):
+    def __init__(self):
+        self.__table = {}
+        self.__buffer = ''
+        self.__methods = {}
+
+    def get_table(self):
+        for entry in self.__table.values():
+            if entry.environment and not entry.has_content:
+                p = Parameter("content")
+                p.implied = 1
+                entry.parameters.append(p)
+                entry.has_content = 1
+        return self.__table
+
+    def startElement(self, tag, attrs):
+        try:
+            start, end = self.__methods[tag]
+        except KeyError:
+            start = getattr(self, "start_" + tag, None)
+            end = getattr(self, "end_" + tag, None)
+            self.__methods[tag] = (start, end)
+        if start:
+            start(attrs)
+
+    def endElement(self, tag):
+        start, end = self.__methods[tag]
+        if end:
+            end()
+
+    def endDocument(self):
+        self.__methods.clear()
+
+    def characters(self, data):
+        self.__buffer += data
+
+    def start_environment(self, attrs):
+        name = attrs["name"]
+        self.__current = TableEntry(name, environment=1)
+        self.__current.verbatim = attrs.get("verbatim") == "yes"
+        if attrs.has_key("outputname"):
+            self.__current.outputname = attrs.get("outputname")
+        self.__current.endcloses = attrs.get("endcloses", "").split()
+    def end_environment(self):
+        self.end_macro()
+
+    def start_macro(self, attrs):
+        name = attrs["name"]
+        self.__current = TableEntry(name)
+        self.__current.closes = attrs.get("closes", "").split()
+        if attrs.has_key("outputname"):
+            self.__current.outputname = attrs.get("outputname")
+    def end_macro(self):
+        name = self.__current.name
+        if self.__table.has_key(name):
+            raise ValueError("name %r already in use" % (name,))
+        self.__table[name] = self.__current
+        self.__current = None
+
+    def start_attribute(self, attrs):
+        name = attrs.get("name")
+        optional = attrs.get("optional") == "yes"
+        if name:
+            p = Parameter("attribute", name, optional=optional)
+        else:
+            p = Parameter("attribute", optional=optional)
+        self.__current.parameters.append(p)
+        self.__buffer = ''
+    def end_attribute(self):
+        self.__current.parameters[-1].text = self.__buffer
+
+    def start_entityref(self, attrs):
+        name = attrs["name"]
+        p = Parameter("entityref", name)
+        self.__current.parameters.append(p)
+
+    def start_child(self, attrs):
+        name = attrs["name"]
+        p = Parameter("child", name, attrs.get("optional") == "yes")
+        self.__current.parameters.append(p)
+        self.__current.empty = 0
+
+    def start_content(self, attrs):
+        p = Parameter("content")
+        p.implied = attrs.get("implied") == "yes"
+        if self.__current.environment:
+            p.implied = 1
+        self.__current.parameters.append(p)
+        self.__current.has_content = 1
+        self.__current.empty = 0
+
+    def start_text(self, attrs):
+        self.__current.empty = 0
+        self.__buffer = ''
+    def end_text(self):
+        p = Parameter("text")
+        p.text = self.__buffer
+        self.__current.parameters.append(p)
+
+
+def load_table(fp):
+    ch = TableHandler()
+    xml.sax.parse(fp, ch)
+    return ch.get_table()
+
+
+def main():
+    global DEBUG
+    #
+    opts, args = getopt.getopt(sys.argv[1:], "D", ["debug"])
+    for opt, arg in opts:
+        if opt in ("-D", "--debug"):
+            DEBUG += 1
+    if len(args) == 0:
+        ifp = sys.stdin
+        ofp = sys.stdout
+    elif len(args) == 1:
+        ifp = open(args[0])
+        ofp = sys.stdout
+    elif len(args) == 2:
+        ifp = open(args[0])
+        ofp = open(args[1], "w")
+    else:
+        usage()
+        sys.exit(2)
+
+    table = load_table(open(os.path.join(sys.path[0], 'conversion.xml')))
+    convert(ifp, ofp, table)
+
+
+if __name__ == "__main__":
+    main()


Property changes on: vendor/Python/current/Doc/tools/sgmlconv/latex2esis.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Doc/tools/sgmlconv/make.rules
===================================================================
--- vendor/Python/current/Doc/tools/sgmlconv/make.rules	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/tools/sgmlconv/make.rules	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,48 @@
+# -*- makefile -*-
+#
+# Extra magic needed by the LaTeX->XML conversion process.  This requires
+# $(TOOLSDIR) to be properly defined.
+
+DOCFIXER=	$(TOOLSDIR)/sgmlconv/docfixer.py
+ESIS2ML=	$(TOOLSDIR)/sgmlconv/esis2sgml.py
+LATEX2ESIS=	$(TOOLSDIR)/sgmlconv/latex2esis.py
+CONVERSION=	$(TOOLSDIR)/sgmlconv/conversion.xml
+
+ESISTARGETS=	$(patsubst %.tex,%.esis,$(wildcard *.tex))
+ESIS1TARGETS=	$(patsubst %.tex,%.esis1,$(wildcard *.tex))
+XMLTARGETS=	$(patsubst %.tex,%.xml,$(wildcard *.tex))
+
+L2EFLAGS=
+
+all:	xml
+
+esis:	$(ESISTARGETS)
+esis1:	$(ESIS1TARGETS)
+xml:	$(XMLTARGETS)
+
+ESISTOOLS=	$(TOOLSDIR)/sgmlconv/esistools.py
+
+$(ESISTARGETS): $(LATEX2ESIS) $(DOCFIXER) $(ESISTOOLS) $(CONVERSION)
+$(ESIS1TARGETS): $(LATEX2ESIS) $(CONVERSION)
+# This variant is easier to work with while debugging the conversion spec:
+#$(ESISTARGETS): $(LATEX2ESIS) $(DOCFIXER) $(ESISTOOLS)
+$(XMLTARGETS): $(ESIS2ML)
+
+
+.SUFFIXES: .esis .esis1 .tex .xml
+
+.tex.esis1:
+	$(LATEX2ESIS) $(L2EFLAGS) $< $@
+
+.esis1.esis:
+	$(DOCFIXER) $< $@
+
+.esis.xml:
+	$(ESIS2ML) --xml $< $@
+
+
+clean:
+	rm -f *.esis *.esis1
+
+clobber: clean
+	rm -f *.xml

Added: vendor/Python/current/Doc/tools/support.py
===================================================================
--- vendor/Python/current/Doc/tools/support.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/tools/support.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,202 @@
+"""Miscellaneous support code shared by some of the tool scripts.
+
+This includes option parsing code, HTML formatting code, and a couple of
+useful helpers.
+
+"""
+__version__ = '$Revision: 37764 $'
+
+
+import getopt
+import os.path
+import sys
+
+
+class Options:
+    __short_args = "a:c:ho:"
+    __long_args = [
+        # script controls
+        "columns=", "help", "output=",
+
+        # content components
+        "address=", "iconserver=", "favicon=",
+        "title=", "uplink=", "uptitle=",
+        "image-type=",
+        ]
+
+    outputfile = "-"
+    columns = 1
+    letters = 0
+    uplink = "index.html"
+    uptitle = "Python Documentation Index"
+    favicon = None
+
+    # The "Aesop Meta Tag" is poorly described, and may only be used
+    # by the Aesop search engine (www.aesop.com), but doesn't hurt.
+    #
+    # There are a number of values this may take to roughly categorize
+    # a page.  A page should be marked according to its primary
+    # category.  Known values are:
+    #   'personal'    -- personal-info
+    #   'information' -- information
+    #   'interactive' -- interactive media
+    #   'multimedia'  -- multimedia presenetation (non-sales)
+    #   'sales'       -- sales material
+    #   'links'       -- links to other information pages
+    #
+    # Setting the aesop_type value to one of these strings will cause
+    # get_header() to add the appropriate <meta> tag to the <head>.
+    #
+    aesop_type = None
+
+    def __init__(self):
+        self.args = []
+        self.variables = {"address": "",
+                          "iconserver": "icons",
+                          "imgtype": "png",
+                          "title": "Global Module Index",
+                          }
+
+    def add_args(self, short=None, long=None):
+        if short:
+            self.__short_args = self.__short_args + short
+        if long:
+            self.__long_args = self.__long_args + long
+
+    def parse(self, args):
+        try:
+            opts, args = getopt.getopt(args, self.__short_args,
+                                       self.__long_args)
+        except getopt.error:
+            sys.stdout = sys.stderr
+            self.usage()
+            sys.exit(2)
+        self.args = self.args + args
+        for opt, val in opts:
+            if opt in ("-a", "--address"):
+                val = val.strip()
+                if val:
+                    val = "<address>\n%s\n</address>\n" % val
+                    self.variables["address"] = val
+            elif opt in ("-h", "--help"):
+                self.usage()
+                sys.exit()
+            elif opt in ("-o", "--output"):
+                self.outputfile = val
+            elif opt in ("-c", "--columns"):
+                self.columns = int(val)
+            elif opt == "--title":
+                self.variables["title"] = val.strip()
+            elif opt == "--uplink":
+                self.uplink = val.strip()
+            elif opt == "--uptitle":
+                self.uptitle = val.strip()
+            elif opt == "--iconserver":
+                self.variables["iconserver"] = val.strip() or "."
+            elif opt == "--favicon":
+                self.favicon = val.strip()
+            elif opt == "--image-type":
+                self.variables["imgtype"] = val.strip()
+            else:
+                self.handle_option(opt, val)
+        if self.uplink and self.uptitle:
+            self.variables["uplinkalt"] = "up"
+            self.variables["uplinkicon"] = "up"
+        else:
+            self.variables["uplinkalt"] = ""
+            self.variables["uplinkicon"] = "blank"
+        self.variables["uplink"] = self.uplink
+        self.variables["uptitle"] = self.uptitle
+
+    def handle_option(self, opt, val):
+        raise getopt.error("option %s not recognized" % opt)
+
+    def get_header(self):
+        s = HEAD % self.variables
+        if self.uplink:
+            if self.uptitle:
+                link = ('<link rel="up" href="%s" title="%s">\n  '
+                        '<link rel="start" href="%s" title="%s">'
+                        % (self.uplink, self.uptitle,
+                           self.uplink, self.uptitle))
+            else:
+                link = ('<link rel="up" href="%s">\n  '
+                        '<link rel="start" href="%s">'
+                        % (self.uplink, self.uplink))
+            repl = "  %s\n</head>" % link
+            s = s.replace("</head>", repl, 1)
+        if self.aesop_type:
+            meta = '<meta name="aesop" content="%s">\n  ' % self.aesop_type
+            # Insert this in the middle of the head that's been
+            # generated so far, keeping <meta> and <link> elements in
+            # neat groups:
+            s = s.replace("<link ", meta + "<link ", 1)
+        if self.favicon:
+            ext = os.path.splitext(self.favicon)[1]
+            if ext in (".gif", ".png"):
+                type = ' type="image/%s"' % ext[1:]
+            else:
+                type = ''
+            link = ('<link rel="SHORTCUT ICON" href="%s"%s>\n  '
+                    % (self.favicon, type))
+            s = s.replace("<link ", link + "<link ", 1)
+        return s
+
+    def get_footer(self):
+        return TAIL % self.variables
+
+    def get_output_file(self, filename=None):
+        if filename is None:
+            filename = self.outputfile
+        if filename == "-":
+            return sys.stdout
+        else:
+            return open(filename, "w")
+
+
+NAVIGATION = '''\
+<div class="navigation">
+<table width="100%%" cellpadding="0" cellspacing="2">
+<tr>
+<td><img width="32" height="32" align="bottom" border="0" alt=""
+ src="%(iconserver)s/blank.%(imgtype)s"></td>
+<td><a href="%(uplink)s"
+ title="%(uptitle)s"><img width="32" height="32" align="bottom" border="0"
+ alt="%(uplinkalt)s"
+ src="%(iconserver)s/%(uplinkicon)s.%(imgtype)s"></a></td>
+<td><img width="32" height="32" align="bottom" border="0" alt=""
+ src="%(iconserver)s/blank.%(imgtype)s"></td>
+<td align="center" width="100%%">%(title)s</td>
+<td><img width="32" height="32" align="bottom" border="0" alt=""
+ src="%(iconserver)s/blank.%(imgtype)s"></td>
+<td><img width="32" height="32" align="bottom" border="0" alt=""
+ src="%(iconserver)s/blank.%(imgtype)s"></td>
+<td><img width="32" height="32" align="bottom" border="0" alt=""
+ src="%(iconserver)s/blank.%(imgtype)s"></td>
+</tr></table>
+<b class="navlabel">Up:</b> <span class="sectref"><a href="%(uplink)s"
+ title="%(uptitle)s">%(uptitle)s</A></span>
+<br></div>
+'''
+
+HEAD = '''\
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+  <title>%(title)s</title>
+  <meta name="description" content="%(title)s">
+  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+  <link rel="STYLESHEET" href="lib/lib.css">
+</head>
+<body>
+''' + NAVIGATION + '''\
+<hr>
+
+<h2>%(title)s</h2>
+
+'''
+
+TAIL = "<hr>\n" + NAVIGATION + '''\
+%(address)s</body>
+</html>
+'''

Added: vendor/Python/current/Doc/tools/toc2bkm.py
===================================================================
--- vendor/Python/current/Doc/tools/toc2bkm.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/tools/toc2bkm.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,160 @@
+#! /usr/bin/env python
+
+"""Convert a LaTeX .toc file to some PDFTeX magic to create that neat outline.
+
+The output file has an extension of '.bkm' instead of '.out', since hyperref
+already uses that extension.
+"""
+
+import getopt
+import os
+import re
+import string
+import sys
+
+
+# Ench item in an entry is a tuple of:
+#
+#   Section #,  Title String,  Page #,  List of Sub-entries
+#
+# The return value of parse_toc() is such a tuple.
+
+cline_re = r"""^
+\\contentsline\ \{([a-z]*)}             # type of section in $1
+\{(?:\\numberline\ \{([0-9.A-Z]+)})?     # section number
+(.*)}                                   # title string
+\{(\d+)}$"""                            # page number
+
+cline_rx = re.compile(cline_re, re.VERBOSE)
+
+OUTER_TO_INNER = -1
+
+_transition_map = {
+    ('chapter', 'section'): OUTER_TO_INNER,
+    ('section', 'subsection'): OUTER_TO_INNER,
+    ('subsection', 'subsubsection'): OUTER_TO_INNER,
+    ('subsubsection', 'subsection'): 1,
+    ('subsection', 'section'): 1,
+    ('section', 'chapter'): 1,
+    ('subsection', 'chapter'): 2,
+    ('subsubsection', 'section'): 2,
+    ('subsubsection', 'chapter'): 3,
+    }
+
+INCLUDED_LEVELS = ("chapter", "section", "subsection", "subsubsection")
+
+
+class BadSectionNesting(Exception):
+    """Raised for unsupported section level transitions."""
+
+    def __init__(self, level, newsection, path, lineno):
+        self.level = level
+        self.newsection = newsection
+        self.path = path
+        self.lineno = lineno
+
+    def __str__(self):
+        return ("illegal transition from %s to %s at %s (line %s)"
+                % (self.level, self.newsection, self.path, self.lineno))
+
+
+def parse_toc(fp, bigpart=None):
+    toc = top = []
+    stack = [toc]
+    level = bigpart or 'chapter'
+    lineno = 0
+    while 1:
+        line = fp.readline()
+        if not line:
+            break
+        lineno = lineno + 1
+        m = cline_rx.match(line)
+        if m:
+            stype, snum, title, pageno = m.group(1, 2, 3, 4)
+            title = clean_title(title)
+            entry = (stype, snum, title, int(pageno), [])
+            if stype == level:
+                toc.append(entry)
+            else:
+                if stype not in INCLUDED_LEVELS:
+                    # we don't want paragraphs & subparagraphs
+                    continue
+                try:
+                    direction = _transition_map[(level, stype)]
+                except KeyError:
+                    raise BadSectionNesting(level, stype, fp.name, lineno)
+                if direction == OUTER_TO_INNER:
+                    toc = toc[-1][-1]
+                    stack.insert(0, toc)
+                    toc.append(entry)
+                else:
+                    for i in range(direction):
+                        del stack[0]
+                        toc = stack[0]
+                    toc.append(entry)
+                level = stype
+        else:
+            sys.stderr.write("l.%s: " + line)
+    return top
+
+
+hackscore_rx = re.compile(r"\\hackscore\s*{[^}]*}")
+raisebox_rx = re.compile(r"\\raisebox\s*{[^}]*}")
+title_rx = re.compile(r"\\([a-zA-Z])+\s+")
+title_trans = string.maketrans("", "")
+
+def clean_title(title):
+    title = raisebox_rx.sub("", title)
+    title = hackscore_rx.sub(r"\\_", title)
+    pos = 0
+    while 1:
+        m = title_rx.search(title, pos)
+        if m:
+            start = m.start()
+            if title[start:start+15] != "\\textunderscore":
+                title = title[:start] + title[m.end():]
+            pos = start + 1
+        else:
+            break
+    title = title.translate(title_trans, "{}")
+    return title
+
+
+def write_toc(toc, fp):
+    for entry in toc:
+        write_toc_entry(entry, fp, 0)
+
+def write_toc_entry(entry, fp, layer):
+    stype, snum, title, pageno, toc = entry
+    s = "\\pdfoutline goto name{page%03d}" % pageno
+    if toc:
+        s = "%s count -%d" % (s, len(toc))
+    if snum:
+        title = "%s %s" % (snum, title)
+    s = "%s {%s}\n" % (s, title)
+    fp.write(s)
+    for entry in toc:
+        write_toc_entry(entry, fp, layer + 1)
+
+
+def process(ifn, ofn, bigpart=None):
+    toc = parse_toc(open(ifn), bigpart)
+    write_toc(toc, open(ofn, "w"))
+
+
+def main():
+    bigpart = None
+    opts, args = getopt.getopt(sys.argv[1:], "c:")
+    if opts:
+        bigpart = opts[0][1]
+    if not args:
+        usage()
+        sys.exit(2)
+    for filename in args:
+        base, ext = os.path.splitext(filename)
+        ext = ext or ".toc"
+        process(base + ext, base + ".bkm", bigpart)
+
+
+if __name__ == "__main__":
+    main()


Property changes on: vendor/Python/current/Doc/tools/toc2bkm.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Doc/tools/undoc_symbols.py
===================================================================
--- vendor/Python/current/Doc/tools/undoc_symbols.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/tools/undoc_symbols.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,94 @@
+#! /usr/bin/env python
+
+"""\
+This script prints out a list of undocumented symbols found in
+Python include files, prefixed by their tag kind.
+
+Pass Python's include files to ctags, parse the output into a
+dictionary mapping symbol names to tag kinds.
+
+Then, the .tex files from Python docs are read into a giant string.
+
+Finally all symbols not found in the docs are written to standard
+output, prefixed with their tag kind.
+"""
+
+# Which kind of tags do we need?
+TAG_KINDS = "dpst"
+
+# Doc sections to use
+DOCSECTIONS = ["api"]# ["api", "ext"]
+
+# Only print symbols starting with this prefix,
+# to get all symbols, use an empty string
+PREFIXES = ("Py", "PY")
+
+INCLUDEPATTERN = "*.h"
+
+# end of customization section
+
+
+# Tested with EXUBERANT CTAGS
+# see http://ctags.sourceforge.net
+#
+# ctags fields are separated by tabs.
+# The first field is the name, the last field the type:
+# d macro definitions (and #undef names)
+# e enumerators
+# f function definitions
+# g enumeration names
+# m class, struct, or union members
+# n namespaces
+# p function prototypes and declarations
+# s structure names
+# t typedefs
+# u union names
+# v variable definitions
+# x extern and forward variable declarations
+
+import os, glob, re, sys
+
+def findnames(file, prefixes=()):
+    names = {}
+    for line in file.xreadlines():
+        if line[0] == '!':
+            continue
+        fields = line.split()
+        name, tag = fields[0], fields[-1]
+        if tag == 'd' and name.endswith('_H'):
+            continue
+        if prefixes:
+            sw = name.startswith
+            for prefix in prefixes:
+                if sw(prefix):
+                    names[name] = tag
+        else:
+            names[name] = tag
+    return names
+
+def print_undoc_symbols(prefix, docdir, incdir):
+    docs = []
+
+    for sect in DOCSECTIONS:
+        for file in glob.glob(os.path.join(docdir, sect, "*.tex")):
+            docs.append(open(file).read())
+
+    docs = "\n".join(docs)
+
+    incfiles = os.path.join(incdir, INCLUDEPATTERN)
+
+    fp = os.popen("ctags -IPyAPI_FUNC -IPy_GCC_ATTRIBUTE --c-types=%s -f - %s"
+                  % (TAG_KINDS, incfiles))
+    dict = findnames(fp, prefix)
+    names = dict.keys()
+    names.sort()
+    for name in names:
+        if not re.search("%s\\W" % name, docs):
+            print dict[name], name
+
+if __name__ == '__main__':
+    srcdir = os.path.dirname(sys.argv[0])
+    incdir = os.path.normpath(os.path.join(srcdir, "../../Include"))
+    docdir = os.path.normpath(os.path.join(srcdir, ".."))
+
+    print_undoc_symbols(PREFIXES, docdir, incdir)

Added: vendor/Python/current/Doc/tools/update-docs.sh
===================================================================
--- vendor/Python/current/Doc/tools/update-docs.sh	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/tools/update-docs.sh	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,31 @@
+#! /bin/sh
+
+# Script which installs a development snapshot of the documentation
+# into the development website.
+#
+# The push-docs.sh script pushes this to the server when needed
+# and removes it when done.
+
+if [ -z "$HOME" ] ; then
+    HOME=`grep "$LOGNAME" /etc/passwd | sed 's|^.*:\([^:]*\):[^:]*$|\1|'`
+    export HOME
+fi
+
+DOCTYPE="$1"
+UPDATES="$HOME/tmp/$2"
+
+TMPDIR="$$-docs"
+
+cd /ftp/ftp.python.org/pub/www.python.org/dev/doc/ || exit $?
+mkdir $TMPDIR || exit $?
+cd $TMPDIR || exit $?
+(bzip2 -dc "$UPDATES" | tar xf -) || exit $?
+cd .. || exit $?
+
+if [ -d $DOCTYPE ] ; then
+    mv $DOCTYPE $DOCTYPE-temp
+fi
+mv $TMPDIR/Python-Docs-* $DOCTYPE
+rmdir $TMPDIR
+rm -rf $DOCTYPE-temp || exit $?
+mv "$UPDATES" python-docs-$DOCTYPE.tar.bz2 || exit $?


Property changes on: vendor/Python/current/Doc/tools/update-docs.sh
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Doc/tools/whichlibs
===================================================================
--- vendor/Python/current/Doc/tools/whichlibs	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/tools/whichlibs	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2 @@
+#!/bin/sh
+sed -n 's%^\\input{\(lib[a-zA-Z0-9_]*\)}.*%../lib/\1.tex%p' ../lib/lib.tex


Property changes on: vendor/Python/current/Doc/tools/whichlibs
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Doc/tut/glossary.tex
===================================================================
--- vendor/Python/current/Doc/tut/glossary.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/tut/glossary.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,352 @@
+\chapter{Glossary\label{glossary}}
+
+%%% keep the entries sorted and include at least one \index{} item for each
+%%% cross-references are marked with \emph{entry}
+
+\begin{description}
+
+
+\index{>>>}
+\item[\code{>>>}]
+The typical Python prompt of the interactive shell.  Often seen for
+code examples that can be tried right away in the interpreter.
+
+\index{...}
+\item[\code{.\code{.}.}]
+The typical Python prompt of the interactive shell when entering code
+for an indented code block.
+
+\index{BDFL}
+\item[BDFL]
+Benevolent Dictator For Life, a.k.a. \ulink{Guido van
+Rossum}{http://www.python.org/\textasciitilde{}guido/}, Python's creator.
+
+\index{byte code}
+\item[byte code]
+The internal representation of a Python program in the interpreter.
+The byte code is also cached in \code{.pyc} and \code{.pyo}
+files so that executing the same file is faster the second time
+(recompilation from source to byte code can be avoided).  This
+``intermediate language'' is said to run on a ``virtual
+machine'' that calls the subroutines corresponding to each bytecode.
+
+\index{classic class}
+\item[classic class]
+Any class which does not inherit from \class{object}.  See
+\emph{new-style class}.
+
+\index{coercion}
+\item[coercion]
+The implicit conversion of an instance of one type to another during an
+operation which involves two arguments of the same type.  For example,
+{}\code{int(3.15)} converts the floating point number to the integer
+{}\code{3}, but in {}\code{3+4.5}, each argument is of a different type (one
+int, one float), and both must be converted to the same type before they can
+be added or it will raise a {}\code{TypeError}.  Coercion between two
+operands can be performed with the {}\code{coerce} builtin function; thus,
+{}\code{3+4.5} is equivalent to calling {}\code{operator.add(*coerce(3,
+4.5))} and results in {}\code{operator.add(3.0, 4.5)}.  Without coercion,
+all arguments of even compatible types would have to be normalized to the
+same value by the programmer, e.g., {}\code{float(3)+4.5} rather than just
+{}\code{3+4.5}.
+
+\index{complex number}
+\item[complex number]
+An extension of the familiar real number system in which all numbers are
+expressed as a sum of a real part and an imaginary part.  Imaginary numbers
+are real multiples of the imaginary unit (the square root of {}\code{-1}),
+often written {}\code{i} in mathematics or {}\code{j} in engineering.
+Python has builtin support for complex numbers, which are written with this
+latter notation; the imaginary part is written with a {}\code{j} suffix,
+e.g., {}\code{3+1j}.  To get access to complex equivalents of the
+{}\module{math} module, use {}\module{cmath}.  Use of complex numbers is a
+fairly advanced mathematical feature.  If you're not aware of a need for them,
+it's almost certain you can safely ignore them.
+
+\index{descriptor}
+\item[descriptor]
+Any \emph{new-style} object that defines the methods
+{}\method{__get__()}, \method{__set__()}, or \method{__delete__()}.
+When a class attribute is a descriptor, its special binding behavior
+is triggered upon attribute lookup.  Normally, writing \var{a.b} looks
+up the object \var{b} in the class dictionary for \var{a}, but if
+{}\var{b} is a descriptor, the defined method gets called.
+Understanding descriptors is a key to a deep understanding of Python
+because they are the basis for many features including functions,
+methods, properties, class methods, static methods, and reference to
+super classes.
+
+\index{dictionary}
+\item[dictionary]
+An associative array, where arbitrary keys are mapped to values.  The
+use of \class{dict} much resembles that for \class{list}, but the keys
+can be any object with a \method{__hash__()} function, not just
+integers starting from zero.  Called a hash in Perl.
+
+\index{duck-typing}
+\item[duck-typing]
+Pythonic programming style that determines an object's type by inspection
+of its method or attribute signature rather than by explicit relationship
+to some type object ("If it looks like a duck and quacks like a duck, it
+must be a duck.")  By emphasizing interfaces rather than specific types,
+well-designed code improves its flexibility by allowing polymorphic
+substitution.  Duck-typing avoids tests using \function{type()} or
+\function{isinstance()}. Instead, it typically employs
+\function{hasattr()} tests or {}\emph{EAFP} programming.
+
+\index{EAFP}
+\item[EAFP]
+Easier to ask for forgiveness than permission.  This common Python
+coding style assumes the existence of valid keys or attributes and
+catches exceptions if the assumption proves false.  This clean and
+fast style is characterized by the presence of many \keyword{try} and
+{}\keyword{except} statements.  The technique contrasts with the
+{}\emph{LBYL} style that is common in many other languages such as C.
+
+\index{__future__}
+\item[__future__]
+A pseudo module which programmers can use to enable new language
+features which are not compatible with the current interpreter.  For
+example, the expression \code{11/4} currently evaluates to \code{2}.
+If the module in which it is executed had enabled \emph{true division}
+by executing:
+
+\begin{verbatim}
+from __future__ import division
+\end{verbatim}
+
+the expression \code{11/4} would evaluate to \code{2.75}.  By
+importing the \ulink{\module{__future__}}{../lib/module-future.html}
+module and evaluating its variables, you can see when a new feature
+was first added to the language and when it will become the default:
+
+\begin{verbatim}
+>>> import __future__
+>>> __future__.division
+_Feature((2, 2, 0, 'alpha', 2), (3, 0, 0, 'alpha', 0), 8192)
+\end{verbatim}
+
+\index{generator}
+\item[generator]
+A function that returns an iterator.  It looks like a normal function except
+that values are returned to the caller using a \keyword{yield} statement
+instead of a {}\keyword{return} statement.  Generator functions often
+contain one or more {}\keyword{for} or \keyword{while} loops that
+\keyword{yield} elements back to the caller.  The function execution is
+stopped at the {}\keyword{yield} keyword (returning the result) and is
+resumed there when the next element is requested by calling the
+\method{next()} method of the returned iterator.
+
+\index{generator expression}
+\item[generator expression]
+An expression that returns a generator.  It looks like a normal expression
+followed by a \keyword{for} expression defining a loop variable, range, and
+an optional \keyword{if} expression.  The combined expression generates
+values for an enclosing function:
+
+\begin{verbatim}
+>>> sum(i*i for i in range(10))         # sum of squares 0, 1, 4, ... 81
+285
+\end{verbatim}
+
+\index{GIL}
+\item[GIL]
+See \emph{global interpreter lock}.
+
+\index{global interpreter lock}
+\item[global interpreter lock]
+The lock used by Python threads to assure that only one thread can be
+run at a time.  This simplifies Python by assuring that no two
+processes can access the same memory at the same time.  Locking the
+entire interpreter makes it easier for the interpreter to be
+multi-threaded, at the expense of some parallelism on multi-processor
+machines.  Efforts have been made in the past to create a
+``free-threaded'' interpreter (one which locks shared data at a much
+finer granularity), but performance suffered in the common
+single-processor case.
+
+\index{IDLE}
+\item[IDLE]
+An Integrated Development Environment for Python.  IDLE is a
+basic editor and interpreter environment that ships with the standard
+distribution of Python.  Good for beginners, it also serves as clear
+example code for those wanting to implement a moderately
+sophisticated, multi-platform GUI application.
+
+\index{immutable}
+\item[immutable]
+An object with fixed value.  Immutable objects are numbers, strings or
+tuples (and more).  Such an object cannot be altered.  A new object
+has to be created if a different value has to be stored.  They play an
+important role in places where a constant hash value is needed, for
+example as a key in a dictionary.
+
+\index{integer division}
+\item[integer division]
+Mathematical division discarding any remainder.  For example, the
+expression \code{11/4} currently evaluates to \code{2} in contrast
+to the \code{2.75} returned by float division.  Also called
+{}\emph{floor division}.  When dividing two integers the outcome will
+always be another integer (having the floor function applied to it).
+However, if one of the operands is another numeric type (such as a
+{}\class{float}), the result will be coerced (see \emph{coercion}) to
+a common type.  For example, an integer divided by a float will result
+in a float value, possibly with a decimal fraction.  Integer division
+can be forced by using the \code{//} operator instead of the \code{/}
+operator.  See also \emph{__future__}.
+
+\index{interactive}
+\item[interactive]
+Python has an interactive interpreter which means that you can try out
+things and immediately see their results.  Just launch \code{python} with no
+arguments (possibly by selecting it from your computer's main menu).
+It is a very powerful way to test out new ideas or inspect modules and
+packages (remember \code{help(x)}).
+
+\index{interpreted}
+\item[interpreted]
+Python is an interpreted language, as opposed to a compiled one.  This means
+that the source files can be run directly without first creating an
+executable which is then run.  Interpreted languages typically have a
+shorter development/debug cycle than compiled ones, though their programs
+generally also run more slowly.  See also {}\emph{interactive}.
+
+\index{iterable}
+\item[iterable]
+A container object capable of returning its members one at a time.
+Examples of iterables include all sequence types (such as \class{list},
+{}\class{str}, and \class{tuple}) and some non-sequence types like
+{}\class{dict} and \class{file} and objects of any classes you define
+with an \method{__iter__()} or \method{__getitem__()} method.  Iterables
+can be used in a \keyword{for} loop and in many other places where a
+sequence is needed (\function{zip()}, \function{map()}, ...).  When an
+iterable object is passed as an argument to the builtin function
+{}\function{iter()}, it returns an iterator for the object.  This
+iterator is good for one pass over the set of values.  When using
+iterables, it is usually not necessary to call \function{iter()} or
+deal with iterator objects yourself.  The \code{for} statement does
+that automatically for you, creating a temporary unnamed variable to
+hold the iterator for the duration of the loop.  See also
+{}\emph{iterator}, \emph{sequence}, and \emph{generator}.
+
+\index{iterator}
+\item[iterator]
+An object representing a stream of data.  Repeated calls to the
+iterator's \method{next()} method return successive items in the
+stream.  When no more data is available a \exception{StopIteration}
+exception is raised instead.  At this point, the iterator object is
+exhausted and any further calls to its \method{next()} method just
+raise \exception{StopIteration} again.  Iterators are required to have
+an \method{__iter__()} method that returns the iterator object
+itself so every iterator is also iterable and may be used in most
+places where other iterables are accepted.  One notable exception is
+code that attempts multiple iteration passes.  A container object
+(such as a \class{list}) produces a fresh new iterator each time you
+pass it to the \function{iter()} function or use it in a
+{}\keyword{for} loop.  Attempting this with an iterator will just
+return the same exhausted iterator object used in the previous iteration
+pass, making it appear like an empty container.
+
+\index{LBYL}
+\item[LBYL]
+Look before you leap.  This coding style explicitly tests for
+pre-conditions before making calls or lookups.  This style contrasts
+with the \emph{EAFP} approach and is characterized by the presence of
+many \keyword{if} statements.
+
+\index{list comprehension}
+\item[list comprehension]
+A compact way to process all or a subset of elements in a sequence and
+return a list with the results.  \code{result = ["0x\%02x"
+\% x for x in range(256) if x \% 2 == 0]} generates a list of strings
+containing hex numbers (0x..) that are even and in the range from 0 to 255.
+The \keyword{if} clause is optional.  If omitted, all elements in
+{}\code{range(256)} are processed.
+
+\index{mapping}
+\item[mapping]
+A container object (such as \class{dict}) that supports arbitrary key
+lookups using the special method \method{__getitem__()}.
+
+\index{metaclass}
+\item[metaclass]
+The class of a class.  Class definitions create a class name, a class
+dictionary, and a list of base classes.  The metaclass is responsible
+for taking those three arguments and creating the class.  Most object
+oriented programming languages provide a default implementation.  What
+makes Python special is that it is possible to create custom
+metaclasses.  Most users never need this tool, but when the need
+arises, metaclasses can provide powerful, elegant solutions.  They
+have been used for logging attribute access, adding thread-safety,
+tracking object creation, implementing singletons, and many other
+tasks.
+
+\index{mutable}
+\item[mutable]
+Mutable objects can change their value but keep their \function{id()}.
+See also \emph{immutable}.
+
+\index{namespace}
+\item[namespace]
+The place where a variable is stored.  Namespaces are implemented as
+dictionaries.  There are the local, global and builtin namespaces
+as well as nested namespaces in objects (in methods).  Namespaces support
+modularity by preventing naming conflicts.  For instance, the
+functions \function{__builtin__.open()} and \function{os.open()} are
+distinguished by their namespaces.  Namespaces also aid readability
+and maintainability by making it clear which module implements a
+function.  For instance, writing \function{random.seed()} or
+{}\function{itertools.izip()} makes it clear that those functions are
+implemented by the \ulink{\module{random}}{../lib/module-random.html}
+and \ulink{\module{itertools}}{../lib/module-itertools.html} modules
+respectively.
+
+\index{nested scope}
+\item[nested scope]
+The ability to refer to a variable in an enclosing definition.  For
+instance, a function defined inside another function can refer to
+variables in the outer function.  Note that nested scopes work only
+for reference and not for assignment which will always write to the
+innermost scope.  In contrast, local variables both read and write in
+the innermost scope.  Likewise, global variables read and write to the
+global namespace.
+
+\index{new-style class}
+\item[new-style class]
+Any class that inherits from \class{object}.  This includes all
+built-in types like \class{list} and \class{dict}.  Only new-style
+classes can use Python's newer, versatile features like
+{}\method{__slots__}, descriptors, properties,
+\method{__getattribute__()}, class methods, and static methods.
+
+\index{Python3000}
+\item[Python3000]
+A mythical python release, not required to be backward compatible, with
+telepathic interface.
+
+\index{__slots__}
+\item[__slots__]
+A declaration inside a \emph{new-style class} that saves memory by
+pre-declaring space for instance attributes and eliminating instance
+dictionaries.  Though popular, the technique is somewhat tricky to get
+right and is best reserved for rare cases where there are large
+numbers of instances in a memory-critical application.
+
+\index{sequence}
+\item[sequence]
+An \emph{iterable} which supports efficient element access using
+integer indices via the \method{__getitem__()} and
+{}\method{__len__()} special methods.  Some built-in sequence types
+are \class{list}, \class{str}, \class{tuple}, and \class{unicode}.
+Note that \class{dict} also supports \method{__getitem__()} and
+{}\method{__len__()}, but is considered a mapping rather than a
+sequence because the lookups use arbitrary \emph{immutable} keys
+rather than integers.
+
+\index{Zen of Python}
+\item[Zen of Python]
+Listing of Python design principles and philosophies that are helpful
+in understanding and using the language.  The listing can be found by
+typing ``\code{import this}'' at the interactive prompt.
+
+\end{description}

Added: vendor/Python/current/Doc/tut/tut.tex
===================================================================
--- vendor/Python/current/Doc/tut/tut.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/tut/tut.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,5907 @@
+\documentclass{manual}
+\usepackage[T1]{fontenc}
+\usepackage{textcomp}
+
+% Things to do:
+% Should really move the Python startup file info to an appendix
+
+\title{Python Tutorial}
+
+\input{boilerplate}
+
+\makeindex
+
+\begin{document}
+
+\maketitle
+
+\ifhtml
+\chapter*{Front Matter\label{front}}
+\fi
+
+\input{copyright}
+
+\begin{abstract}
+
+\noindent
+Python is an easy to learn, powerful programming language.  It has
+efficient high-level data structures and a simple but effective
+approach to object-oriented programming.  Python's elegant syntax and
+dynamic typing, together with its interpreted nature, make it an ideal 
+language for scripting and rapid application development in many areas 
+on most platforms.
+
+The Python interpreter and the extensive standard library are freely
+available in source or binary form for all major platforms from the
+Python Web site, \url{http://www.python.org/}, and may be freely
+distributed.  The same site also contains distributions of and
+pointers to many free third party Python modules, programs and tools,
+and additional documentation.
+
+The Python interpreter is easily extended with new functions and data
+types implemented in C or \Cpp{} (or other languages callable from C).
+Python is also suitable as an extension language for customizable
+applications.
+
+This tutorial introduces the reader informally to the basic concepts
+and features of the Python language and system.  It helps to have a
+Python interpreter handy for hands-on experience, but all examples are
+self-contained, so the tutorial can be read off-line as well.
+
+For a description of standard objects and modules, see the
+\citetitle[../lib/lib.html]{Python Library Reference} document.  The
+\citetitle[../ref/ref.html]{Python Reference Manual} gives a more
+formal definition of the language.  To write extensions in C or
+\Cpp, read \citetitle[../ext/ext.html]{Extending and Embedding the
+Python Interpreter} and \citetitle[../api/api.html]{Python/C API
+Reference}.  There are also several books covering Python in depth.
+
+This tutorial does not attempt to be comprehensive and cover every
+single feature, or even every commonly used feature.  Instead, it
+introduces many of Python's most noteworthy features, and will give
+you a good idea of the language's flavor and style.  After reading it,
+you will be able to read and write Python modules and programs, and
+you will be ready to learn more about the various Python library
+modules described in the \citetitle[../lib/lib.html]{Python Library
+Reference}.
+
+\end{abstract}
+
+\tableofcontents
+
+
+\chapter{Whetting Your Appetite \label{intro}}
+
+If you do much work on computers, eventually you find that there's
+some task you'd like to automate.  For example, you may wish to
+perform a search-and-replace over a large number of text files, or
+rename and rearrange a bunch of photo files in a complicated way.
+Perhaps you'd like to write a small custom database, or a specialized
+GUI application, or a simple game.
+
+If you're a professional software developer, you may have to work with
+several C/\Cpp/Java libraries but find the usual
+write/compile/test/re-compile cycle is too slow.  Perhaps you're
+writing a test suite for such a library and find writing the testing
+code a tedious task.  Or maybe you've written a program that could use
+an extension language, and you don't want to design and implement a
+whole new language for your application.
+
+Python is just the language for you.
+
+You could write a {\UNIX} shell script or Windows batch files for some
+of these tasks, but shell scripts are best at moving around files and
+changing text data, not well-suited for GUI applications or games.
+You could write a C/{\Cpp}/Java program, but it can take a lot of
+development time to get even a first-draft program.  Python is simpler
+to use, available on Windows, MacOS X, and {\UNIX} operating systems,
+and will help you get the job done more quickly.
+
+Python is simple to use, but it is a real programming language,
+offering much more structure and support for large programs than shell
+scripts or batch files can offer.  On the other hand, Python also
+offers much more error checking than C, and, being a
+\emph{very-high-level language}, it has high-level data types built
+in, such as flexible arrays and dictionaries.  Because of its more
+general data types Python is applicable to a much larger problem
+domain than Awk or even Perl, yet many things are at
+least as easy in Python as in those languages.
+
+Python allows you to split your program into modules that can be
+reused in other Python programs.  It comes with a large collection of
+standard modules that you can use as the basis of your programs --- or
+as examples to start learning to program in Python.  Some of these
+modules provide things like file I/O, system calls,
+sockets, and even interfaces to graphical user interface toolkits like Tk.  
+
+Python is an interpreted language, which can save you considerable time
+during program development because no compilation and linking is
+necessary.  The interpreter can be used interactively, which makes it
+easy to experiment with features of the language, to write throw-away
+programs, or to test functions during bottom-up program development.
+It is also a handy desk calculator.
+
+Python enables programs to be written compactly and readably.  Programs
+written in Python are typically much shorter than equivalent C, 
+\Cpp{}, or Java programs, for several reasons:
+\begin{itemize}
+\item
+the high-level data types allow you to express complex operations in a
+single statement;
+\item
+statement grouping is done by indentation instead of beginning and ending
+brackets;
+\item
+no variable or argument declarations are necessary.
+\end{itemize}
+
+Python is \emph{extensible}: if you know how to program in C it is easy
+to add a new built-in function or module to the interpreter, either to
+perform critical operations at maximum speed, or to link Python
+programs to libraries that may only be available in binary form (such
+as a vendor-specific graphics library).  Once you are really hooked,
+you can link the Python interpreter into an application written in C
+and use it as an extension or command language for that application.
+
+By the way, the language is named after the BBC show ``Monty Python's
+Flying Circus'' and has nothing to do with nasty reptiles.  Making
+references to Monty Python skits in documentation is not only allowed,
+it is encouraged!
+
+%\section{Where From Here \label{where}}
+
+Now that you are all excited about Python, you'll want to examine it
+in some more detail.  Since the best way to learn a language is
+to use it, the tutorial invites you to play with the Python interpreter
+as you read.
+
+In the next chapter, the mechanics of using the interpreter are
+explained.  This is rather mundane information, but essential for
+trying out the examples shown later.
+
+The rest of the tutorial introduces various features of the Python
+language and system through examples, beginning with simple
+expressions, statements and data types, through functions and modules,
+and finally touching upon advanced concepts like exceptions
+and user-defined classes.
+
+\chapter{Using the Python Interpreter \label{using}}
+
+\section{Invoking the Interpreter \label{invoking}}
+
+The Python interpreter is usually installed as
+\file{/usr/local/bin/python} on those machines where it is available;
+putting \file{/usr/local/bin} in your \UNIX{} shell's search path
+makes it possible to start it by typing the command
+
+\begin{verbatim}
+python
+\end{verbatim}
+
+to the shell.  Since the choice of the directory where the interpreter
+lives is an installation option, other places are possible; check with
+your local Python guru or system administrator.  (E.g.,
+\file{/usr/local/python} is a popular alternative location.)
+
+On Windows machines, the Python installation is usually placed in
+\file{C:\e Python24}, though you can change this when you're running
+the installer.  To add this directory to your path, 
+you can type the following command into the command prompt in a DOS box:
+
+\begin{verbatim}
+set path=%path%;C:\python24
+\end{verbatim}
+
+
+Typing an end-of-file character (\kbd{Control-D} on \UNIX,
+\kbd{Control-Z} on Windows) at the primary prompt causes the
+interpreter to exit with a zero exit status.  If that doesn't work,
+you can exit the interpreter by typing the following commands:
+\samp{import sys; sys.exit()}.
+
+The interpreter's line-editing features usually aren't very
+sophisticated.  On \UNIX, whoever installed the interpreter may have
+enabled support for the GNU readline library, which adds more
+elaborate interactive editing and history features. Perhaps the
+quickest check to see whether command line editing is supported is
+typing Control-P to the first Python prompt you get.  If it beeps, you
+have command line editing; see Appendix \ref{interacting} for an
+introduction to the keys.  If nothing appears to happen, or if
+\code{\^P} is echoed, command line editing isn't available; you'll
+only be able to use backspace to remove characters from the current
+line.
+
+The interpreter operates somewhat like the \UNIX{} shell: when called
+with standard input connected to a tty device, it reads and executes
+commands interactively; when called with a file name argument or with
+a file as standard input, it reads and executes a \emph{script} from
+that file. 
+
+A second way of starting the interpreter is
+\samp{\program{python} \programopt{-c} \var{command} [arg] ...}, which
+executes the statement(s) in \var{command}, analogous to the shell's
+\programopt{-c} option.  Since Python statements often contain spaces
+or other characters that are special to the shell, it is best to quote 
+\var{command} in its entirety with double quotes.
+
+Some Python modules are also useful as scripts.  These can be invoked using
+\samp{\program{python} \programopt{-m} \var{module} [arg] ...}, which
+executes the source file for \var{module} as if you had spelled out its
+full name on the command line.
+
+Note that there is a difference between \samp{python file} and
+\samp{python <file}.  In the latter case, input requests from the
+program, such as calls to \function{input()} and \function{raw_input()}, are
+satisfied from \emph{file}.  Since this file has already been read
+until the end by the parser before the program starts executing, the
+program will encounter end-of-file immediately.  In the former case
+(which is usually what you want) they are satisfied from whatever file
+or device is connected to standard input of the Python interpreter.
+
+When a script file is used, it is sometimes useful to be able to run
+the script and enter interactive mode afterwards.  This can be done by
+passing \programopt{-i} before the script.  (This does not work if the
+script is read from standard input, for the same reason as explained
+in the previous paragraph.)
+
+\subsection{Argument Passing \label{argPassing}}
+
+When known to the interpreter, the script name and additional
+arguments thereafter are passed to the script in the variable
+\code{sys.argv}, which is a list of strings.  Its length is at least
+one; when no script and no arguments are given, \code{sys.argv[0]} is
+an empty string.  When the script name is given as \code{'-'} (meaning 
+standard input), \code{sys.argv[0]} is set to \code{'-'}.  When
+\programopt{-c} \var{command} is used, \code{sys.argv[0]} is set to
+\code{'-c'}.  When \programopt{-m} \var{module} is used, \code{sys.argv[0]} 
+is set to the full name of the located module.  Options found after 
+\programopt{-c} \var{command} or \programopt{-m} \var{module} are not consumed 
+by the Python interpreter's option processing but left in \code{sys.argv} for 
+the command or module to handle.
+
+\subsection{Interactive Mode \label{interactive}}
+
+When commands are read from a tty, the interpreter is said to be in
+\emph{interactive mode}.  In this mode it prompts for the next command
+with the \emph{primary prompt}, usually three greater-than signs
+(\samp{>>>~}); for continuation lines it prompts with the
+\emph{secondary prompt}, by default three dots (\samp{...~}).
+The interpreter prints a welcome message stating its version number
+and a copyright notice before printing the first prompt:
+
+\begin{verbatim}
+python
+Python 1.5.2b2 (#1, Feb 28 1999, 00:02:06)  [GCC 2.8.1] on sunos5
+Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
+>>>
+\end{verbatim}
+
+Continuation lines are needed when entering a multi-line construct.
+As an example, take a look at this \keyword{if} statement:
+
+\begin{verbatim}
+>>> the_world_is_flat = 1
+>>> if the_world_is_flat:
+...     print "Be careful not to fall off!"
+... 
+Be careful not to fall off!
+\end{verbatim}
+
+
+\section{The Interpreter and Its Environment \label{interp}}
+
+\subsection{Error Handling \label{error}}
+
+When an error occurs, the interpreter prints an error
+message and a stack trace.  In interactive mode, it then returns to
+the primary prompt; when input came from a file, it exits with a
+nonzero exit status after printing
+the stack trace.  (Exceptions handled by an \keyword{except} clause in a
+\keyword{try} statement are not errors in this context.)  Some errors are
+unconditionally fatal and cause an exit with a nonzero exit; this
+applies to internal inconsistencies and some cases of running out of
+memory.  All error messages are written to the standard error stream;
+normal output from executed commands is written to standard
+output.
+
+Typing the interrupt character (usually Control-C or DEL) to the
+primary or secondary prompt cancels the input and returns to the
+primary prompt.\footnote{
+        A problem with the GNU Readline package may prevent this.
+}
+Typing an interrupt while a command is executing raises the
+\exception{KeyboardInterrupt} exception, which may be handled by a
+\keyword{try} statement.
+
+\subsection{Executable Python Scripts \label{scripts}}
+
+On BSD'ish \UNIX{} systems, Python scripts can be made directly
+executable, like shell scripts, by putting the line
+
+\begin{verbatim}
+#! /usr/bin/env python
+\end{verbatim}
+
+(assuming that the interpreter is on the user's \envvar{PATH}) at the
+beginning of the script and giving the file an executable mode.  The
+\samp{\#!} must be the first two characters of the file.  On some
+platforms, this first line must end with a \UNIX-style line ending
+(\character{\e n}), not a Mac OS (\character{\e r}) or Windows
+(\character{\e r\e n}) line ending.  Note that
+the hash, or pound, character, \character{\#}, is used to start a
+comment in Python.
+
+The script can be given an executable mode, or permission, using the
+\program{chmod} command:
+
+\begin{verbatim}
+$ chmod +x myscript.py
+\end{verbatim} % $ <-- bow to font-lock
+
+
+\subsection{Source Code Encoding}
+
+It is possible to use encodings different than \ASCII{} in Python source
+files. The best way to do it is to put one more special comment line
+right after the \code{\#!} line to define the source file encoding:
+
+\begin{alltt}
+# -*- coding: \var{encoding} -*- 
+\end{alltt}
+
+With that declaration, all characters in the source file will be treated as
+having the encoding \var{encoding}, and it will be
+possible to directly write Unicode string literals in the selected
+encoding.  The list of possible encodings can be found in the
+\citetitle[../lib/lib.html]{Python Library Reference}, in the section
+on \ulink{\module{codecs}}{../lib/module-codecs.html}.
+
+For example, to write Unicode literals including the Euro currency
+symbol, the ISO-8859-15 encoding can be used, with the Euro symbol
+having the ordinal value 164.  This script will print the value 8364
+(the Unicode codepoint corresponding to the Euro symbol) and then
+exit:
+
+\begin{alltt}
+# -*- coding: iso-8859-15 -*-
+
+currency = u"\texteuro"
+print ord(currency)
+\end{alltt}
+
+If your editor supports saving files as \code{UTF-8} with a UTF-8
+\emph{byte order mark} (aka BOM), you can use that instead of an
+encoding declaration. IDLE supports this capability if
+\code{Options/General/Default Source Encoding/UTF-8} is set. Notice
+that this signature is not understood in older Python releases (2.2
+and earlier), and also not understood by the operating system for
+script files with \code{\#!} lines (only used on \UNIX{} systems).
+
+By using UTF-8 (either through the signature or an encoding
+declaration), characters of most languages in the world can be used
+simultaneously in string literals and comments.  Using non-\ASCII{}
+characters in identifiers is not supported. To display all these
+characters properly, your editor must recognize that the file is
+UTF-8, and it must use a font that supports all the characters in the
+file.
+
+\subsection{The Interactive Startup File \label{startup}}
+
+% XXX This should probably be dumped in an appendix, since most people
+% don't use Python interactively in non-trivial ways.
+
+When you use Python interactively, it is frequently handy to have some
+standard commands executed every time the interpreter is started.  You
+can do this by setting an environment variable named
+\envvar{PYTHONSTARTUP} to the name of a file containing your start-up
+commands.  This is similar to the \file{.profile} feature of the
+\UNIX{} shells.
+
+This file is only read in interactive sessions, not when Python reads
+commands from a script, and not when \file{/dev/tty} is given as the
+explicit source of commands (which otherwise behaves like an
+interactive session).  It is executed in the same namespace where
+interactive commands are executed, so that objects that it defines or
+imports can be used without qualification in the interactive session.
+You can also change the prompts \code{sys.ps1} and \code{sys.ps2} in
+this file.
+
+If you want to read an additional start-up file from the current
+directory, you can program this in the global start-up file using code
+like \samp{if os.path.isfile('.pythonrc.py'):
+execfile('.pythonrc.py')}.  If you want to use the startup file in a
+script, you must do this explicitly in the script:
+
+\begin{verbatim}
+import os
+filename = os.environ.get('PYTHONSTARTUP')
+if filename and os.path.isfile(filename):
+    execfile(filename)
+\end{verbatim}
+
+
+\chapter{An Informal Introduction to Python \label{informal}}
+
+In the following examples, input and output are distinguished by the
+presence or absence of prompts (\samp{>>>~} and \samp{...~}): to repeat
+the example, you must type everything after the prompt, when the
+prompt appears; lines that do not begin with a prompt are output from
+the interpreter. %
+%\footnote{
+%        I'd prefer to use different fonts to distinguish input
+%        from output, but the amount of LaTeX hacking that would require
+%        is currently beyond my ability.
+%}
+Note that a secondary prompt on a line by itself in an example means
+you must type a blank line; this is used to end a multi-line command.
+
+Many of the examples in this manual, even those entered at the
+interactive prompt, include comments.  Comments in Python start with
+the hash character, \character{\#}, and extend to the end of the
+physical line.  A comment may appear at the start of a line or
+following whitespace or code, but not within a string literal.  A hash 
+character within a string literal is just a hash character.
+
+Some examples:
+
+\begin{verbatim}
+# this is the first comment
+SPAM = 1                 # and this is the second comment
+                         # ... and now a third!
+STRING = "# This is not a comment."
+\end{verbatim}
+
+
+\section{Using Python as a Calculator \label{calculator}}
+
+Let's try some simple Python commands.  Start the interpreter and wait
+for the primary prompt, \samp{>>>~}.  (It shouldn't take long.)
+
+\subsection{Numbers \label{numbers}}
+
+The interpreter acts as a simple calculator: you can type an
+expression at it and it will write the value.  Expression syntax is
+straightforward: the operators \code{+}, \code{-}, \code{*} and
+\code{/} work just like in most other languages (for example, Pascal
+or C); parentheses can be used for grouping.  For example:
+
+\begin{verbatim}
+>>> 2+2
+4
+>>> # This is a comment
+... 2+2
+4
+>>> 2+2  # and a comment on the same line as code
+4
+>>> (50-5*6)/4
+5
+>>> # Integer division returns the floor:
+... 7/3
+2
+>>> 7/-3
+-3
+\end{verbatim}
+
+The equal sign (\character{=}) is used to assign a value to a variable.
+Afterwards, no result is displayed before the next interactive prompt:
+
+\begin{verbatim}
+>>> width = 20
+>>> height = 5*9
+>>> width * height
+900
+\end{verbatim}
+
+A value can be assigned to several variables simultaneously:
+
+\begin{verbatim}
+>>> x = y = z = 0  # Zero x, y and z
+>>> x
+0
+>>> y
+0
+>>> z
+0
+\end{verbatim}
+
+There is full support for floating point; operators with mixed type
+operands convert the integer operand to floating point:
+
+\begin{verbatim}
+>>> 3 * 3.75 / 1.5
+7.5
+>>> 7.0 / 2
+3.5
+\end{verbatim}
+
+Complex numbers are also supported; imaginary numbers are written with
+a suffix of \samp{j} or \samp{J}.  Complex numbers with a nonzero
+real component are written as \samp{(\var{real}+\var{imag}j)}, or can
+be created with the \samp{complex(\var{real}, \var{imag})} function.
+
+\begin{verbatim}
+>>> 1j * 1J
+(-1+0j)
+>>> 1j * complex(0,1)
+(-1+0j)
+>>> 3+1j*3
+(3+3j)
+>>> (3+1j)*3
+(9+3j)
+>>> (1+2j)/(1+1j)
+(1.5+0.5j)
+\end{verbatim}
+
+Complex numbers are always represented as two floating point numbers,
+the real and imaginary part.  To extract these parts from a complex
+number \var{z}, use \code{\var{z}.real} and \code{\var{z}.imag}.  
+
+\begin{verbatim}
+>>> a=1.5+0.5j
+>>> a.real
+1.5
+>>> a.imag
+0.5
+\end{verbatim}
+
+The conversion functions to floating point and integer
+(\function{float()}, \function{int()} and \function{long()}) don't
+work for complex numbers --- there is no one correct way to convert a
+complex number to a real number.  Use \code{abs(\var{z})} to get its
+magnitude (as a float) or \code{z.real} to get its real part.
+
+\begin{verbatim}
+>>> a=3.0+4.0j
+>>> float(a)
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+TypeError: can't convert complex to float; use abs(z)
+>>> a.real
+3.0
+>>> a.imag
+4.0
+>>> abs(a)  # sqrt(a.real**2 + a.imag**2)
+5.0
+>>>
+\end{verbatim}
+
+In interactive mode, the last printed expression is assigned to the
+variable \code{_}.  This means that when you are using Python as a
+desk calculator, it is somewhat easier to continue calculations, for
+example:
+
+\begin{verbatim}
+>>> tax = 12.5 / 100
+>>> price = 100.50
+>>> price * tax
+12.5625
+>>> price + _
+113.0625
+>>> round(_, 2)
+113.06
+>>>
+\end{verbatim}
+
+This variable should be treated as read-only by the user.  Don't
+explicitly assign a value to it --- you would create an independent
+local variable with the same name masking the built-in variable with
+its magic behavior.
+
+\subsection{Strings \label{strings}}
+
+Besides numbers, Python can also manipulate strings, which can be
+expressed in several ways.  They can be enclosed in single quotes or
+double quotes:
+
+\begin{verbatim}
+>>> 'spam eggs'
+'spam eggs'
+>>> 'doesn\'t'
+"doesn't"
+>>> "doesn't"
+"doesn't"
+>>> '"Yes," he said.'
+'"Yes," he said.'
+>>> "\"Yes,\" he said."
+'"Yes," he said.'
+>>> '"Isn\'t," she said.'
+'"Isn\'t," she said.'
+\end{verbatim}
+
+String literals can span multiple lines in several ways.  Continuation
+lines can be used, with a backslash as the last character on the line
+indicating that the next line is a logical continuation of the line:
+
+\begin{verbatim}
+hello = "This is a rather long string containing\n\
+several lines of text just as you would do in C.\n\
+    Note that whitespace at the beginning of the line is\
+ significant."
+
+print hello
+\end{verbatim}
+
+Note that newlines still need to be embedded in the string using
+\code{\e n}; the newline following the trailing backslash is
+discarded.  This example would print the following:
+
+\begin{verbatim}
+This is a rather long string containing
+several lines of text just as you would do in C.
+    Note that whitespace at the beginning of the line is significant.
+\end{verbatim}
+
+If we make the string literal a ``raw'' string, however, the
+\code{\e n} sequences are not converted to newlines, but the backslash
+at the end of the line, and the newline character in the source, are
+both included in the string as data.  Thus, the example:
+
+\begin{verbatim}
+hello = r"This is a rather long string containing\n\
+several lines of text much as you would do in C."
+
+print hello
+\end{verbatim}
+
+would print:
+
+\begin{verbatim}
+This is a rather long string containing\n\
+several lines of text much as you would do in C.
+\end{verbatim}
+
+Or, strings can be surrounded in a pair of matching triple-quotes:
+\code{"""} or \code{'\code{'}'}.  End of lines do not need to be escaped
+when using triple-quotes, but they will be included in the string.
+
+\begin{verbatim}
+print """
+Usage: thingy [OPTIONS] 
+     -h                        Display this usage message
+     -H hostname               Hostname to connect to
+"""
+\end{verbatim}
+
+produces the following output:
+
+\begin{verbatim}
+Usage: thingy [OPTIONS] 
+     -h                        Display this usage message
+     -H hostname               Hostname to connect to
+\end{verbatim}
+
+The interpreter prints the result of string operations in the same way
+as they are typed for input: inside quotes, and with quotes and other
+funny characters escaped by backslashes, to show the precise
+value.  The string is enclosed in double quotes if the string contains
+a single quote and no double quotes, else it's enclosed in single
+quotes.  (The \keyword{print} statement, described later, can be used
+to write strings without quotes or escapes.)
+
+Strings can be concatenated (glued together) with the
+\code{+} operator, and repeated with \code{*}:
+
+\begin{verbatim}
+>>> word = 'Help' + 'A'
+>>> word
+'HelpA'
+>>> '<' + word*5 + '>'
+'<HelpAHelpAHelpAHelpAHelpA>'
+\end{verbatim}
+
+Two string literals next to each other are automatically concatenated;
+the first line above could also have been written \samp{word = 'Help'
+'A'}; this only works with two literals, not with arbitrary string
+expressions:
+
+\begin{verbatim}
+>>> 'str' 'ing'                   #  <-  This is ok
+'string'
+>>> 'str'.strip() + 'ing'   #  <-  This is ok
+'string'
+>>> 'str'.strip() 'ing'     #  <-  This is invalid
+  File "<stdin>", line 1, in ?
+    'str'.strip() 'ing'
+                      ^
+SyntaxError: invalid syntax
+\end{verbatim}
+
+Strings can be subscripted (indexed); like in C, the first character
+of a string has subscript (index) 0.  There is no separate character
+type; a character is simply a string of size one.  Like in Icon,
+substrings can be specified with the \emph{slice notation}: two indices
+separated by a colon.
+
+\begin{verbatim}
+>>> word[4]
+'A'
+>>> word[0:2]
+'He'
+>>> word[2:4]
+'lp'
+\end{verbatim}
+
+Slice indices have useful defaults; an omitted first index defaults to
+zero, an omitted second index defaults to the size of the string being
+sliced.
+
+\begin{verbatim}
+>>> word[:2]    # The first two characters
+'He'
+>>> word[2:]    # Everything except the first two characters
+'lpA'
+\end{verbatim}
+
+Unlike a C string, Python strings cannot be changed.  Assigning to an 
+indexed position in the string results in an error:
+
+\begin{verbatim}
+>>> word[0] = 'x'
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+TypeError: object doesn't support item assignment
+>>> word[:1] = 'Splat'
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+TypeError: object doesn't support slice assignment
+\end{verbatim}
+
+However, creating a new string with the combined content is easy and
+efficient:
+
+\begin{verbatim}
+>>> 'x' + word[1:]
+'xelpA'
+>>> 'Splat' + word[4]
+'SplatA'
+\end{verbatim}
+
+Here's a useful invariant of slice operations:
+\code{s[:i] + s[i:]} equals \code{s}.
+
+\begin{verbatim}
+>>> word[:2] + word[2:]
+'HelpA'
+>>> word[:3] + word[3:]
+'HelpA'
+\end{verbatim}
+
+Degenerate slice indices are handled gracefully: an index that is too
+large is replaced by the string size, an upper bound smaller than the
+lower bound returns an empty string.
+
+\begin{verbatim}
+>>> word[1:100]
+'elpA'
+>>> word[10:]
+''
+>>> word[2:1]
+''
+\end{verbatim}
+
+Indices may be negative numbers, to start counting from the right.
+For example:
+
+\begin{verbatim}
+>>> word[-1]     # The last character
+'A'
+>>> word[-2]     # The last-but-one character
+'p'
+>>> word[-2:]    # The last two characters
+'pA'
+>>> word[:-2]    # Everything except the last two characters
+'Hel'
+\end{verbatim}
+
+But note that -0 is really the same as 0, so it does not count from
+the right!
+
+\begin{verbatim}
+>>> word[-0]     # (since -0 equals 0)
+'H'
+\end{verbatim}
+
+Out-of-range negative slice indices are truncated, but don't try this
+for single-element (non-slice) indices:
+
+\begin{verbatim}
+>>> word[-100:]
+'HelpA'
+>>> word[-10]    # error
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+IndexError: string index out of range
+\end{verbatim}
+
+The best way to remember how slices work is to think of the indices as
+pointing \emph{between} characters, with the left edge of the first
+character numbered 0.  Then the right edge of the last character of a
+string of \var{n} characters has index \var{n}, for example:
+
+\begin{verbatim}
+ +---+---+---+---+---+ 
+ | H | e | l | p | A |
+ +---+---+---+---+---+ 
+ 0   1   2   3   4   5 
+-5  -4  -3  -2  -1
+\end{verbatim}
+
+The first row of numbers gives the position of the indices 0...5 in
+the string; the second row gives the corresponding negative indices.
+The slice from \var{i} to \var{j} consists of all characters between
+the edges labeled \var{i} and \var{j}, respectively.
+
+For non-negative indices, the length of a slice is the difference of
+the indices, if both are within bounds.  For example, the length of
+\code{word[1:3]} is 2.
+
+The built-in function \function{len()} returns the length of a string:
+
+\begin{verbatim}
+>>> s = 'supercalifragilisticexpialidocious'
+>>> len(s)
+34
+\end{verbatim}
+
+
+\begin{seealso}
+  \seetitle[../lib/typesseq.html]{Sequence Types}%
+           {Strings, and the Unicode strings described in the next
+            section, are examples of \emph{sequence types}, and
+            support the common operations supported by such types.}
+  \seetitle[../lib/string-methods.html]{String Methods}%
+           {Both strings and Unicode strings support a large number of
+            methods for basic transformations and searching.}
+  \seetitle[../lib/typesseq-strings.html]{String Formatting Operations}%
+           {The formatting operations invoked when strings and Unicode
+            strings are the left operand of the \code{\%} operator are
+            described in more detail here.}
+\end{seealso}
+
+
+\subsection{Unicode Strings \label{unicodeStrings}}
+\sectionauthor{Marc-Andre Lemburg}{mal at lemburg.com}
+
+Starting with Python 2.0 a new data type for storing text data is
+available to the programmer: the Unicode object. It can be used to
+store and manipulate Unicode data (see \url{http://www.unicode.org/})
+and integrates well with the existing string objects, providing
+auto-conversions where necessary.
+
+Unicode has the advantage of providing one ordinal for every character
+in every script used in modern and ancient texts. Previously, there
+were only 256 possible ordinals for script characters. Texts were
+typically bound to a code page which mapped the ordinals to script
+characters. This lead to very much confusion especially with respect
+to internationalization (usually written as \samp{i18n} ---
+\character{i} + 18 characters + \character{n}) of software.  Unicode
+solves these problems by defining one code page for all scripts.
+
+Creating Unicode strings in Python is just as simple as creating
+normal strings:
+
+\begin{verbatim}
+>>> u'Hello World !'
+u'Hello World !'
+\end{verbatim}
+
+The small \character{u} in front of the quote indicates that a
+Unicode string is supposed to be created. If you want to include
+special characters in the string, you can do so by using the Python
+\emph{Unicode-Escape} encoding. The following example shows how:
+
+\begin{verbatim}
+>>> u'Hello\u0020World !'
+u'Hello World !'
+\end{verbatim}
+
+The escape sequence \code{\e u0020} indicates to insert the Unicode
+character with the ordinal value 0x0020 (the space character) at the
+given position.
+
+Other characters are interpreted by using their respective ordinal
+values directly as Unicode ordinals.  If you have literal strings
+in the standard Latin-1 encoding that is used in many Western countries,
+you will find it convenient that the lower 256 characters
+of Unicode are the same as the 256 characters of Latin-1.
+
+For experts, there is also a raw mode just like the one for normal
+strings. You have to prefix the opening quote with 'ur' to have
+Python use the \emph{Raw-Unicode-Escape} encoding. It will only apply
+the above \code{\e uXXXX} conversion if there is an uneven number of
+backslashes in front of the small 'u'.
+
+\begin{verbatim}
+>>> ur'Hello\u0020World !'
+u'Hello World !'
+>>> ur'Hello\\u0020World !'
+u'Hello\\\\u0020World !'
+\end{verbatim}
+
+The raw mode is most useful when you have to enter lots of
+backslashes, as can be necessary in regular expressions.
+
+Apart from these standard encodings, Python provides a whole set of
+other ways of creating Unicode strings on the basis of a known
+encoding. 
+
+The built-in function \function{unicode()}\bifuncindex{unicode} provides
+access to all registered Unicode codecs (COders and DECoders). Some of
+the more well known encodings which these codecs can convert are
+\emph{Latin-1}, \emph{ASCII}, \emph{UTF-8}, and \emph{UTF-16}.
+The latter two are variable-length encodings that store each Unicode
+character in one or more bytes. The default encoding is
+normally set to \ASCII, which passes through characters in the range
+0 to 127 and rejects any other characters with an error.
+When a Unicode string is printed, written to a file, or converted
+with \function{str()}, conversion takes place using this default encoding.
+
+\begin{verbatim}
+>>> u"abc"
+u'abc'
+>>> str(u"abc")
+'abc'
+>>> u"äöü"
+u'\xe4\xf6\xfc'
+>>> str(u"äöü")
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-2: ordinal not in range(128)
+\end{verbatim}
+
+To convert a Unicode string into an 8-bit string using a specific
+encoding, Unicode objects provide an \function{encode()} method
+that takes one argument, the name of the encoding.  Lowercase names
+for encodings are preferred.
+
+\begin{verbatim}
+>>> u"äöü".encode('utf-8')
+'\xc3\xa4\xc3\xb6\xc3\xbc'
+\end{verbatim}
+
+If you have data in a specific encoding and want to produce a
+corresponding Unicode string from it, you can use the
+\function{unicode()} function with the encoding name as the second
+argument.
+
+\begin{verbatim}
+>>> unicode('\xc3\xa4\xc3\xb6\xc3\xbc', 'utf-8')
+u'\xe4\xf6\xfc'
+\end{verbatim}
+
+\subsection{Lists \label{lists}}
+
+Python knows a number of \emph{compound} data types, used to group
+together other values.  The most versatile is the \emph{list}, which
+can be written as a list of comma-separated values (items) between
+square brackets.  List items need not all have the same type.
+
+\begin{verbatim}
+>>> a = ['spam', 'eggs', 100, 1234]
+>>> a
+['spam', 'eggs', 100, 1234]
+\end{verbatim}
+
+Like string indices, list indices start at 0, and lists can be sliced,
+concatenated and so on:
+
+\begin{verbatim}
+>>> a[0]
+'spam'
+>>> a[3]
+1234
+>>> a[-2]
+100
+>>> a[1:-1]
+['eggs', 100]
+>>> a[:2] + ['bacon', 2*2]
+['spam', 'eggs', 'bacon', 4]
+>>> 3*a[:3] + ['Boo!']
+['spam', 'eggs', 100, 'spam', 'eggs', 100, 'spam', 'eggs', 100, 'Boo!']
+\end{verbatim}
+
+Unlike strings, which are \emph{immutable}, it is possible to change
+individual elements of a list:
+
+\begin{verbatim}
+>>> a
+['spam', 'eggs', 100, 1234]
+>>> a[2] = a[2] + 23
+>>> a
+['spam', 'eggs', 123, 1234]
+\end{verbatim}
+
+Assignment to slices is also possible, and this can even change the size
+of the list or clear it entirely:
+
+\begin{verbatim}
+>>> # Replace some items:
+... a[0:2] = [1, 12]
+>>> a
+[1, 12, 123, 1234]
+>>> # Remove some:
+... a[0:2] = []
+>>> a
+[123, 1234]
+>>> # Insert some:
+... a[1:1] = ['bletch', 'xyzzy']
+>>> a
+[123, 'bletch', 'xyzzy', 1234]
+>>> # Insert (a copy of) itself at the beginning
+>>> a[:0] = a
+>>> a
+[123, 'bletch', 'xyzzy', 1234, 123, 'bletch', 'xyzzy', 1234]
+>>> # Clear the list: replace all items with an empty list
+>>> a[:] = []
+>>> a
+[]
+\end{verbatim}
+
+The built-in function \function{len()} also applies to lists:
+
+\begin{verbatim}
+>>> len(a)
+8
+\end{verbatim}
+
+It is possible to nest lists (create lists containing other lists),
+for example:
+
+\begin{verbatim}
+>>> q = [2, 3]
+>>> p = [1, q, 4]
+>>> len(p)
+3
+>>> p[1]
+[2, 3]
+>>> p[1][0]
+2
+>>> p[1].append('xtra')     # See section 5.1
+>>> p
+[1, [2, 3, 'xtra'], 4]
+>>> q
+[2, 3, 'xtra']
+\end{verbatim}
+
+Note that in the last example, \code{p[1]} and \code{q} really refer to
+the same object!  We'll come back to \emph{object semantics} later.
+
+\section{First Steps Towards Programming \label{firstSteps}}
+
+Of course, we can use Python for more complicated tasks than adding
+two and two together.  For instance, we can write an initial
+sub-sequence of the \emph{Fibonacci} series as follows:
+
+\begin{verbatim}
+>>> # Fibonacci series:
+... # the sum of two elements defines the next
+... a, b = 0, 1
+>>> while b < 10:
+...       print b
+...       a, b = b, a+b
+... 
+1
+1
+2
+3
+5
+8
+\end{verbatim}
+
+This example introduces several new features.
+
+\begin{itemize}
+
+\item
+The first line contains a \emph{multiple assignment}: the variables
+\code{a} and \code{b} simultaneously get the new values 0 and 1.  On the
+last line this is used again, demonstrating that the expressions on
+the right-hand side are all evaluated first before any of the
+assignments take place.  The right-hand side expressions are evaluated 
+from the left to the right.
+
+\item
+The \keyword{while} loop executes as long as the condition (here:
+\code{b < 10}) remains true.  In Python, like in C, any non-zero
+integer value is true; zero is false.  The condition may also be a
+string or list value, in fact any sequence; anything with a non-zero
+length is true, empty sequences are false.  The test used in the
+example is a simple comparison.  The standard comparison operators are
+written the same as in C: \code{<} (less than), \code{>} (greater than),
+\code{==} (equal to), \code{<=} (less than or equal to),
+\code{>=} (greater than or equal to) and \code{!=} (not equal to).
+
+\item
+The \emph{body} of the loop is \emph{indented}: indentation is Python's
+way of grouping statements.  Python does not (yet!) provide an
+intelligent input line editing facility, so you have to type a tab or
+space(s) for each indented line.  In practice you will prepare more
+complicated input for Python with a text editor; most text editors have
+an auto-indent facility.  When a compound statement is entered
+interactively, it must be followed by a blank line to indicate
+completion (since the parser cannot guess when you have typed the last
+line).  Note that each line within a basic block must be indented by
+the same amount.
+
+\item
+The \keyword{print} statement writes the value of the expression(s) it is
+given.  It differs from just writing the expression you want to write
+(as we did earlier in the calculator examples) in the way it handles
+multiple expressions and strings.  Strings are printed without quotes,
+and a space is inserted between items, so you can format things nicely,
+like this:
+
+\begin{verbatim}
+>>> i = 256*256
+>>> print 'The value of i is', i
+The value of i is 65536
+\end{verbatim}
+
+A trailing comma avoids the newline after the output:
+
+\begin{verbatim}
+>>> a, b = 0, 1
+>>> while b < 1000:
+...     print b,
+...     a, b = b, a+b
+... 
+1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
+\end{verbatim}
+
+Note that the interpreter inserts a newline before it prints the next
+prompt if the last line was not completed.
+
+\end{itemize}
+
+
+\chapter{More Control Flow Tools \label{moreControl}}
+
+Besides the \keyword{while} statement just introduced, Python knows
+the usual control flow statements known from other languages, with
+some twists.
+
+\section{\keyword{if} Statements \label{if}}
+
+Perhaps the most well-known statement type is the
+\keyword{if} statement.  For example:
+
+\begin{verbatim}
+>>> x = int(raw_input("Please enter an integer: "))
+>>> if x < 0:
+...      x = 0
+...      print 'Negative changed to zero'
+... elif x == 0:
+...      print 'Zero'
+... elif x == 1:
+...      print 'Single'
+... else:
+...      print 'More'
+... 
+\end{verbatim}
+
+There can be zero or more \keyword{elif} parts, and the
+\keyword{else} part is optional.  The keyword `\keyword{elif}' is
+short for `else if', and is useful to avoid excessive indentation.  An 
+\keyword{if} \ldots\ \keyword{elif} \ldots\ \keyword{elif} \ldots\ sequence
+%    Weird spacings happen here if the wrapping of the source text
+%    gets changed in the wrong way.
+is a substitute for the \keyword{switch} or
+\keyword{case} statements found in other languages.
+
+
+\section{\keyword{for} Statements \label{for}}
+
+The \keyword{for}\stindex{for} statement in Python differs a bit from
+what you may be used to in C or Pascal.  Rather than always
+iterating over an arithmetic progression of numbers (like in Pascal),
+or giving the user the ability to define both the iteration step and
+halting condition (as C), Python's
+\keyword{for}\stindex{for} statement iterates over the items of any
+sequence (a list or a string), in the order that they appear in
+the sequence.  For example (no pun intended):
+% One suggestion was to give a real C example here, but that may only
+% serve to confuse non-C programmers.
+
+\begin{verbatim}
+>>> # Measure some strings:
+... a = ['cat', 'window', 'defenestrate']
+>>> for x in a:
+...     print x, len(x)
+... 
+cat 3
+window 6
+defenestrate 12
+\end{verbatim}
+
+It is not safe to modify the sequence being iterated over in the loop
+(this can only happen for mutable sequence types, such as lists).  If
+you need to modify the list you are iterating over (for example, to
+duplicate selected items) you must iterate over a copy.  The slice
+notation makes this particularly convenient:
+
+\begin{verbatim}
+>>> for x in a[:]: # make a slice copy of the entire list
+...    if len(x) > 6: a.insert(0, x)
+... 
+>>> a
+['defenestrate', 'cat', 'window', 'defenestrate']
+\end{verbatim}
+
+
+\section{The \function{range()} Function \label{range}}
+
+If you do need to iterate over a sequence of numbers, the built-in
+function \function{range()} comes in handy.  It generates lists
+containing arithmetic progressions:
+
+\begin{verbatim}
+>>> range(10)
+[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+\end{verbatim}
+
+The given end point is never part of the generated list;
+\code{range(10)} generates a list of 10 values, the legal
+indices for items of a sequence of length 10.  It is possible to let
+the range start at another number, or to specify a different increment
+(even negative; sometimes this is called the `step'):
+
+\begin{verbatim}
+>>> range(5, 10)
+[5, 6, 7, 8, 9]
+>>> range(0, 10, 3)
+[0, 3, 6, 9]
+>>> range(-10, -100, -30)
+[-10, -40, -70]
+\end{verbatim}
+
+To iterate over the indices of a sequence, combine
+\function{range()} and \function{len()} as follows:
+
+\begin{verbatim}
+>>> a = ['Mary', 'had', 'a', 'little', 'lamb']
+>>> for i in range(len(a)):
+...     print i, a[i]
+... 
+0 Mary
+1 had
+2 a
+3 little
+4 lamb
+\end{verbatim}
+
+
+\section{\keyword{break} and \keyword{continue} Statements, and
+         \keyword{else} Clauses on Loops
+         \label{break}}
+
+The \keyword{break} statement, like in C, breaks out of the smallest
+enclosing \keyword{for} or \keyword{while} loop.
+
+The \keyword{continue} statement, also borrowed from C, continues
+with the next iteration of the loop.
+
+Loop statements may have an \code{else} clause; it is executed when
+the loop terminates through exhaustion of the list (with
+\keyword{for}) or when the condition becomes false (with
+\keyword{while}), but not when the loop is terminated by a
+\keyword{break} statement.  This is exemplified by the following loop,
+which searches for prime numbers:
+
+\begin{verbatim}
+>>> for n in range(2, 10):
+...     for x in range(2, n):
+...         if n % x == 0:
+...             print n, 'equals', x, '*', n/x
+...             break
+...     else:
+...         # loop fell through without finding a factor
+...         print n, 'is a prime number'
+... 
+2 is a prime number
+3 is a prime number
+4 equals 2 * 2
+5 is a prime number
+6 equals 2 * 3
+7 is a prime number
+8 equals 2 * 4
+9 equals 3 * 3
+\end{verbatim}
+
+
+\section{\keyword{pass} Statements \label{pass}}
+
+The \keyword{pass} statement does nothing.
+It can be used when a statement is required syntactically but the
+program requires no action.
+For example:
+
+\begin{verbatim}
+>>> while True:
+...       pass # Busy-wait for keyboard interrupt
+... 
+\end{verbatim}
+
+
+\section{Defining Functions \label{functions}}
+
+We can create a function that writes the Fibonacci series to an
+arbitrary boundary:
+
+\begin{verbatim}
+>>> def fib(n):    # write Fibonacci series up to n
+...     """Print a Fibonacci series up to n."""
+...     a, b = 0, 1
+...     while b < n:
+...         print b,
+...         a, b = b, a+b
+... 
+>>> # Now call the function we just defined:
+... fib(2000)
+1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597
+\end{verbatim}
+
+The keyword \keyword{def} introduces a function \emph{definition}.  It
+must be followed by the function name and the parenthesized list of
+formal parameters.  The statements that form the body of the function
+start at the next line, and must be indented.  The first statement of
+the function body can optionally be a string literal; this string
+literal is the function's \index{documentation strings}documentation
+string, or \dfn{docstring}.\index{docstrings}\index{strings, documentation}
+
+There are tools which use docstrings to automatically produce online
+or printed documentation, or to let the user interactively browse
+through code; it's good practice to include docstrings in code that
+you write, so try to make a habit of it.
+
+The \emph{execution} of a function introduces a new symbol table used
+for the local variables of the function.  More precisely, all variable
+assignments in a function store the value in the local symbol table;
+whereas variable references first look in the local symbol table, then
+in the global symbol table, and then in the table of built-in names.
+Thus,  global variables cannot be directly assigned a value within a
+function (unless named in a \keyword{global} statement), although
+they may be referenced.
+
+The actual parameters (arguments) to a function call are introduced in
+the local symbol table of the called function when it is called; thus,
+arguments are passed using \emph{call by value} (where the
+\emph{value} is always an object \emph{reference}, not the value of
+the object).\footnote{
+         Actually, \emph{call by object reference} would be a better
+         description, since if a mutable object is passed, the caller
+         will see any changes the callee makes to it (items
+         inserted into a list).
+} When a function calls another function, a new local symbol table is
+created for that call.
+
+A function definition introduces the function name in the current
+symbol table.  The value of the function name
+has a type that is recognized by the interpreter as a user-defined
+function.  This value can be assigned to another name which can then
+also be used as a function.  This serves as a general renaming
+mechanism:
+
+\begin{verbatim}
+>>> fib
+<function fib at 10042ed0>
+>>> f = fib
+>>> f(100)
+1 1 2 3 5 8 13 21 34 55 89
+\end{verbatim}
+
+You might object that \code{fib} is not a function but a procedure.  In
+Python, like in C, procedures are just functions that don't return a
+value.  In fact, technically speaking, procedures do return a value,
+albeit a rather boring one.  This value is called \code{None} (it's a
+built-in name).  Writing the value \code{None} is normally suppressed by
+the interpreter if it would be the only value written.  You can see it
+if you really want to:
+
+\begin{verbatim}
+>>> print fib(0)
+None
+\end{verbatim}
+
+It is simple to write a function that returns a list of the numbers of
+the Fibonacci series, instead of printing it:
+
+\begin{verbatim}
+>>> def fib2(n): # return Fibonacci series up to n
+...     """Return a list containing the Fibonacci series up to n."""
+...     result = []
+...     a, b = 0, 1
+...     while b < n:
+...         result.append(b)    # see below
+...         a, b = b, a+b
+...     return result
+... 
+>>> f100 = fib2(100)    # call it
+>>> f100                # write the result
+[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
+\end{verbatim}
+
+This example, as usual, demonstrates some new Python features:
+
+\begin{itemize}
+
+\item
+The \keyword{return} statement returns with a value from a function.
+\keyword{return} without an expression argument returns \code{None}.
+Falling off the end of a procedure also returns \code{None}.
+
+\item
+The statement \code{result.append(b)} calls a \emph{method} of the list
+object \code{result}.  A method is a function that `belongs' to an
+object and is named \code{obj.methodname}, where \code{obj} is some
+object (this may be an expression), and \code{methodname} is the name
+of a method that is defined by the object's type.  Different types
+define different methods.  Methods of different types may have the
+same name without causing ambiguity.  (It is possible to define your
+own object types and methods, using \emph{classes}, as discussed later
+in this tutorial.)
+The method \method{append()} shown in the example is defined for
+list objects; it adds a new element at the end of the list.  In this
+example it is equivalent to \samp{result = result + [b]}, but more
+efficient.
+
+\end{itemize}
+
+\section{More on Defining Functions \label{defining}}
+
+It is also possible to define functions with a variable number of
+arguments.  There are three forms, which can be combined.
+
+\subsection{Default Argument Values \label{defaultArgs}}
+
+The most useful form is to specify a default value for one or more
+arguments.  This creates a function that can be called with fewer
+arguments than it is defined to allow.  For example:
+
+\begin{verbatim}
+def ask_ok(prompt, retries=4, complaint='Yes or no, please!'):
+    while True:
+        ok = raw_input(prompt)
+        if ok in ('y', 'ye', 'yes'): return True
+        if ok in ('n', 'no', 'nop', 'nope'): return False
+        retries = retries - 1
+        if retries < 0: raise IOError, 'refusenik user'
+        print complaint
+\end{verbatim}
+
+This function can be called either like this:
+\code{ask_ok('Do you really want to quit?')} or like this:
+\code{ask_ok('OK to overwrite the file?', 2)}.
+
+This example also introduces the \keyword{in} keyword. This tests
+whether or not a sequence contains a certain value.
+
+The default values are evaluated at the point of function definition
+in the \emph{defining} scope, so that
+
+\begin{verbatim}
+i = 5
+
+def f(arg=i):
+    print arg
+
+i = 6
+f()
+\end{verbatim}
+
+will print \code{5}.
+
+\strong{Important warning:}  The default value is evaluated only once.
+This makes a difference when the default is a mutable object such as a
+list, dictionary, or instances of most classes.  For example, the
+following function accumulates the arguments passed to it on
+subsequent calls:
+
+\begin{verbatim}
+def f(a, L=[]):
+    L.append(a)
+    return L
+
+print f(1)
+print f(2)
+print f(3)
+\end{verbatim}
+
+This will print
+
+\begin{verbatim}
+[1]
+[1, 2]
+[1, 2, 3]
+\end{verbatim}
+
+If you don't want the default to be shared between subsequent calls,
+you can write the function like this instead:
+
+\begin{verbatim}
+def f(a, L=None):
+    if L is None:
+        L = []
+    L.append(a)
+    return L
+\end{verbatim}
+
+\subsection{Keyword Arguments \label{keywordArgs}}
+
+Functions can also be called using
+keyword arguments of the form \samp{\var{keyword} = \var{value}}.  For
+instance, the following function:
+
+\begin{verbatim}
+def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):
+    print "-- This parrot wouldn't", action,
+    print "if you put", voltage, "volts through it."
+    print "-- Lovely plumage, the", type
+    print "-- It's", state, "!"
+\end{verbatim}
+
+could be called in any of the following ways:
+
+\begin{verbatim}
+parrot(1000)
+parrot(action = 'VOOOOOM', voltage = 1000000)
+parrot('a thousand', state = 'pushing up the daisies')
+parrot('a million', 'bereft of life', 'jump')
+\end{verbatim}
+
+but the following calls would all be invalid:
+
+\begin{verbatim}
+parrot()                     # required argument missing
+parrot(voltage=5.0, 'dead')  # non-keyword argument following keyword
+parrot(110, voltage=220)     # duplicate value for argument
+parrot(actor='John Cleese')  # unknown keyword
+\end{verbatim}
+
+In general, an argument list must have any positional arguments
+followed by any keyword arguments, where the keywords must be chosen
+from the formal parameter names.  It's not important whether a formal
+parameter has a default value or not.  No argument may receive a
+value more than once --- formal parameter names corresponding to
+positional arguments cannot be used as keywords in the same calls.
+Here's an example that fails due to this restriction:
+
+\begin{verbatim}
+>>> def function(a):
+...     pass
+... 
+>>> function(0, a=0)
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+TypeError: function() got multiple values for keyword argument 'a'
+\end{verbatim}
+
+When a final formal parameter of the form \code{**\var{name}} is
+present, it receives a \ulink{dictionary}{../lib/typesmapping.html}
+containing all keyword arguments except for those corresponding to
+a formal parameter.  This may be
+combined with a formal parameter of the form
+\code{*\var{name}} (described in the next subsection) which receives a
+tuple containing the positional arguments beyond the formal parameter
+list.  (\code{*\var{name}} must occur before \code{**\var{name}}.)
+For example, if we define a function like this:
+
+\begin{verbatim}
+def cheeseshop(kind, *arguments, **keywords):
+    print "-- Do you have any", kind, '?'
+    print "-- I'm sorry, we're all out of", kind
+    for arg in arguments: print arg
+    print '-'*40
+    keys = keywords.keys()
+    keys.sort()
+    for kw in keys: print kw, ':', keywords[kw]
+\end{verbatim}
+
+It could be called like this:
+
+\begin{verbatim}
+cheeseshop('Limburger', "It's very runny, sir.",
+           "It's really very, VERY runny, sir.",
+           client='John Cleese',
+           shopkeeper='Michael Palin',
+           sketch='Cheese Shop Sketch')
+\end{verbatim}
+
+and of course it would print:
+
+\begin{verbatim}
+-- Do you have any Limburger ?
+-- I'm sorry, we're all out of Limburger
+It's very runny, sir.
+It's really very, VERY runny, sir.
+----------------------------------------
+client : John Cleese
+shopkeeper : Michael Palin
+sketch : Cheese Shop Sketch
+\end{verbatim}
+
+Note that the \method{sort()} method of the list of keyword argument
+names is called before printing the contents of the \code{keywords}
+dictionary; if this is not done, the order in which the arguments are
+printed is undefined.
+
+
+\subsection{Arbitrary Argument Lists \label{arbitraryArgs}}
+
+Finally, the least frequently used option is to specify that a
+function can be called with an arbitrary number of arguments.  These
+arguments will be wrapped up in a tuple.  Before the variable number
+of arguments, zero or more normal arguments may occur.
+
+\begin{verbatim}
+def fprintf(file, format, *args):
+    file.write(format % args)
+\end{verbatim}
+
+
+\subsection{Unpacking Argument Lists \label{unpacking-arguments}}
+
+The reverse situation occurs when the arguments are already in a list
+or tuple but need to be unpacked for a function call requiring separate
+positional arguments.  For instance, the built-in \function{range()}
+function expects separate \var{start} and \var{stop} arguments.  If they
+are not available separately, write the function call with the 
+\code{*}-operator to unpack the arguments out of a list or tuple:
+
+\begin{verbatim}
+>>> range(3, 6)             # normal call with separate arguments
+[3, 4, 5]
+>>> args = [3, 6]
+>>> range(*args)            # call with arguments unpacked from a list
+[3, 4, 5]
+\end{verbatim}
+
+In the same fashion, dictionaries can deliver keyword arguments with the
+\code{**}-operator:
+
+\begin{verbatim}
+>>> def parrot(voltage, state='a stiff', action='voom'):
+...     print "-- This parrot wouldn't", action,
+...     print "if you put", voltage, "volts through it.",
+...     print "E's", state, "!"
+...
+>>> d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"}
+>>> parrot(**d)
+-- This parrot wouldn't VOOM if you put four million volts through it. E's bleedin' demised !
+\end{verbatim}
+
+
+\subsection{Lambda Forms \label{lambda}}
+
+By popular demand, a few features commonly found in functional
+programming languages like Lisp have been added to Python.  With the
+\keyword{lambda} keyword, small anonymous functions can be created.
+Here's a function that returns the sum of its two arguments:
+\samp{lambda a, b: a+b}.  Lambda forms can be used wherever function
+objects are required.  They are syntactically restricted to a single
+expression.  Semantically, they are just syntactic sugar for a normal
+function definition.  Like nested function definitions, lambda forms
+can reference variables from the containing scope:
+
+\begin{verbatim}
+>>> def make_incrementor(n):
+...     return lambda x: x + n
+...
+>>> f = make_incrementor(42)
+>>> f(0)
+42
+>>> f(1)
+43
+\end{verbatim}
+
+
+\subsection{Documentation Strings \label{docstrings}}
+
+There are emerging conventions about the content and formatting of
+documentation strings.
+\index{docstrings}\index{documentation strings}
+\index{strings, documentation}
+
+The first line should always be a short, concise summary of the
+object's purpose.  For brevity, it should not explicitly state the
+object's name or type, since these are available by other means
+(except if the name happens to be a verb describing a function's
+operation).  This line should begin with a capital letter and end with
+a period.
+
+If there are more lines in the documentation string, the second line
+should be blank, visually separating the summary from the rest of the
+description.  The following lines should be one or more paragraphs
+describing the object's calling conventions, its side effects, etc.
+
+The Python parser does not strip indentation from multi-line string
+literals in Python, so tools that process documentation have to strip
+indentation if desired.  This is done using the following convention.
+The first non-blank line \emph{after} the first line of the string
+determines the amount of indentation for the entire documentation
+string.  (We can't use the first line since it is generally adjacent
+to the string's opening quotes so its indentation is not apparent in
+the string literal.)  Whitespace ``equivalent'' to this indentation is
+then stripped from the start of all lines of the string.  Lines that
+are indented less should not occur, but if they occur all their
+leading whitespace should be stripped.  Equivalence of whitespace
+should be tested after expansion of tabs (to 8 spaces, normally).
+
+Here is an example of a multi-line docstring:
+
+\begin{verbatim}
+>>> def my_function():
+...     """Do nothing, but document it.
+... 
+...     No, really, it doesn't do anything.
+...     """
+...     pass
+... 
+>>> print my_function.__doc__
+Do nothing, but document it.
+
+    No, really, it doesn't do anything.
+    
+\end{verbatim}
+
+
+
+\chapter{Data Structures \label{structures}}
+
+This chapter describes some things you've learned about already in
+more detail, and adds some new things as well.
+
+
+\section{More on Lists \label{moreLists}}
+
+The list data type has some more methods.  Here are all of the methods
+of list objects:
+
+\begin{methoddesc}[list]{append}{x}
+Add an item to the end of the list;
+equivalent to \code{a[len(a):] = [\var{x}]}.
+\end{methoddesc}
+
+\begin{methoddesc}[list]{extend}{L}
+Extend the list by appending all the items in the given list;
+equivalent to \code{a[len(a):] = \var{L}}.
+\end{methoddesc}
+
+\begin{methoddesc}[list]{insert}{i, x}
+Insert an item at a given position.  The first argument is the index
+of the element before which to insert, so \code{a.insert(0, \var{x})}
+inserts at the front of the list, and \code{a.insert(len(a), \var{x})}
+is equivalent to \code{a.append(\var{x})}.
+\end{methoddesc}
+
+\begin{methoddesc}[list]{remove}{x}
+Remove the first item from the list whose value is \var{x}.
+It is an error if there is no such item.
+\end{methoddesc}
+
+\begin{methoddesc}[list]{pop}{\optional{i}}
+Remove the item at the given position in the list, and return it.  If
+no index is specified, \code{a.pop()} removes and returns the last item
+in the list.  (The square brackets
+around the \var{i} in the method signature denote that the parameter
+is optional, not that you should type square brackets at that
+position.  You will see this notation frequently in the
+\citetitle[../lib/lib.html]{Python Library Reference}.)
+\end{methoddesc}
+
+\begin{methoddesc}[list]{index}{x}
+Return the index in the list of the first item whose value is \var{x}.
+It is an error if there is no such item.
+\end{methoddesc}
+
+\begin{methoddesc}[list]{count}{x}
+Return the number of times \var{x} appears in the list.
+\end{methoddesc}
+
+\begin{methoddesc}[list]{sort}{}
+Sort the items of the list, in place.
+\end{methoddesc}
+
+\begin{methoddesc}[list]{reverse}{}
+Reverse the elements of the list, in place.
+\end{methoddesc}
+
+An example that uses most of the list methods:
+
+\begin{verbatim}
+>>> a = [66.25, 333, 333, 1, 1234.5]
+>>> print a.count(333), a.count(66.25), a.count('x')
+2 1 0
+>>> a.insert(2, -1)
+>>> a.append(333)
+>>> a
+[66.25, 333, -1, 333, 1, 1234.5, 333]
+>>> a.index(333)
+1
+>>> a.remove(333)
+>>> a
+[66.25, -1, 333, 1, 1234.5, 333]
+>>> a.reverse()
+>>> a
+[333, 1234.5, 1, 333, -1, 66.25]
+>>> a.sort()
+>>> a
+[-1, 1, 66.25, 333, 333, 1234.5]
+\end{verbatim}
+
+
+\subsection{Using Lists as Stacks \label{lists-as-stacks}}
+\sectionauthor{Ka-Ping Yee}{ping at lfw.org}
+
+The list methods make it very easy to use a list as a stack, where the
+last element added is the first element retrieved (``last-in,
+first-out'').  To add an item to the top of the stack, use
+\method{append()}.  To retrieve an item from the top of the stack, use
+\method{pop()} without an explicit index.  For example:
+
+\begin{verbatim}
+>>> stack = [3, 4, 5]
+>>> stack.append(6)
+>>> stack.append(7)
+>>> stack
+[3, 4, 5, 6, 7]
+>>> stack.pop()
+7
+>>> stack
+[3, 4, 5, 6]
+>>> stack.pop()
+6
+>>> stack.pop()
+5
+>>> stack
+[3, 4]
+\end{verbatim}
+
+
+\subsection{Using Lists as Queues \label{lists-as-queues}}
+\sectionauthor{Ka-Ping Yee}{ping at lfw.org}
+
+You can also use a list conveniently as a queue, where the first
+element added is the first element retrieved (``first-in,
+first-out'').  To add an item to the back of the queue, use
+\method{append()}.  To retrieve an item from the front of the queue,
+use \method{pop()} with \code{0} as the index.  For example:
+
+\begin{verbatim}
+>>> queue = ["Eric", "John", "Michael"]
+>>> queue.append("Terry")           # Terry arrives
+>>> queue.append("Graham")          # Graham arrives
+>>> queue.pop(0)
+'Eric'
+>>> queue.pop(0)
+'John'
+>>> queue
+['Michael', 'Terry', 'Graham']
+\end{verbatim}
+
+
+\subsection{Functional Programming Tools \label{functional}}
+
+There are three built-in functions that are very useful when used with
+lists: \function{filter()}, \function{map()}, and \function{reduce()}.
+
+\samp{filter(\var{function}, \var{sequence})} returns a sequence
+consisting of those items from the
+sequence for which \code{\var{function}(\var{item})} is true.
+If \var{sequence} is a \class{string} or \class{tuple}, the result will
+be of the same type; otherwise, it is always a \class{list}.
+For example, to compute some primes:
+
+\begin{verbatim}
+>>> def f(x): return x % 2 != 0 and x % 3 != 0
+...
+>>> filter(f, range(2, 25))
+[5, 7, 11, 13, 17, 19, 23]
+\end{verbatim}
+
+\samp{map(\var{function}, \var{sequence})} calls
+\code{\var{function}(\var{item})} for each of the sequence's items and
+returns a list of the return values.  For example, to compute some
+cubes:
+
+\begin{verbatim}
+>>> def cube(x): return x*x*x
+...
+>>> map(cube, range(1, 11))
+[1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]
+\end{verbatim}
+
+More than one sequence may be passed; the function must then have as
+many arguments as there are sequences and is called with the
+corresponding item from each sequence (or \code{None} if some sequence
+is shorter than another).  For example:
+
+\begin{verbatim}
+>>> seq = range(8)
+>>> def add(x, y): return x+y
+...
+>>> map(add, seq, seq)
+[0, 2, 4, 6, 8, 10, 12, 14]
+\end{verbatim}
+
+\samp{reduce(\var{function}, \var{sequence})} returns a single value
+constructed by calling the binary function \var{function} on the first two
+items of the sequence, then on the result and the next item, and so
+on.  For example, to compute the sum of the numbers 1 through 10:
+
+\begin{verbatim}
+>>> def add(x,y): return x+y
+...
+>>> reduce(add, range(1, 11))
+55
+\end{verbatim}
+
+If there's only one item in the sequence, its value is returned; if
+the sequence is empty, an exception is raised.
+
+A third argument can be passed to indicate the starting value.  In this
+case the starting value is returned for an empty sequence, and the
+function is first applied to the starting value and the first sequence
+item, then to the result and the next item, and so on.  For example,
+
+\begin{verbatim}
+>>> def sum(seq):
+...     def add(x,y): return x+y
+...     return reduce(add, seq, 0)
+... 
+>>> sum(range(1, 11))
+55
+>>> sum([])
+0
+\end{verbatim}
+
+Don't use this example's definition of \function{sum()}: since summing
+numbers is such a common need, a built-in function
+\code{sum(\var{sequence})} is already provided, and works exactly like
+this.
+\versionadded{2.3}
+
+\subsection{List Comprehensions}
+
+List comprehensions provide a concise way to create lists without resorting
+to use of \function{map()}, \function{filter()} and/or \keyword{lambda}.
+The resulting list definition tends often to be clearer than lists built
+using those constructs.  Each list comprehension consists of an expression
+followed by a \keyword{for} clause, then zero or more \keyword{for} or
+\keyword{if} clauses.  The result will be a list resulting from evaluating
+the expression in the context of the \keyword{for} and \keyword{if} clauses
+which follow it.  If the expression would evaluate to a tuple, it must be
+parenthesized.
+
+\begin{verbatim}
+>>> freshfruit = ['  banana', '  loganberry ', 'passion fruit  ']
+>>> [weapon.strip() for weapon in freshfruit]
+['banana', 'loganberry', 'passion fruit']
+>>> vec = [2, 4, 6]
+>>> [3*x for x in vec]
+[6, 12, 18]
+>>> [3*x for x in vec if x > 3]
+[12, 18]
+>>> [3*x for x in vec if x < 2]
+[]
+>>> [[x,x**2] for x in vec]
+[[2, 4], [4, 16], [6, 36]]
+>>> [x, x**2 for x in vec]	# error - parens required for tuples
+  File "<stdin>", line 1, in ?
+    [x, x**2 for x in vec]
+               ^
+SyntaxError: invalid syntax
+>>> [(x, x**2) for x in vec]
+[(2, 4), (4, 16), (6, 36)]
+>>> vec1 = [2, 4, 6]
+>>> vec2 = [4, 3, -9]
+>>> [x*y for x in vec1 for y in vec2]
+[8, 6, -18, 16, 12, -36, 24, 18, -54]
+>>> [x+y for x in vec1 for y in vec2]
+[6, 5, -7, 8, 7, -5, 10, 9, -3]
+>>> [vec1[i]*vec2[i] for i in range(len(vec1))]
+[8, 12, -54]
+\end{verbatim}
+
+List comprehensions are much more flexible than \function{map()} and can be
+applied to complex expressions and nested functions:
+
+\begin{verbatim}
+>>> [str(round(355/113.0, i)) for i in range(1,6)]
+['3.1', '3.14', '3.142', '3.1416', '3.14159']
+\end{verbatim}
+
+
+\section{The \keyword{del} statement \label{del}}
+
+There is a way to remove an item from a list given its index instead
+of its value: the \keyword{del} statement.  This differs from the
+\method{pop()} method which returns a value.  The \keyword{del}
+statement can also be used to remove slices from a list or clear the
+entire list (which we did earlier by assignment of an empty list to
+the slice).  For example:
+
+\begin{verbatim}
+>>> a = [-1, 1, 66.25, 333, 333, 1234.5]
+>>> del a[0]
+>>> a
+[1, 66.25, 333, 333, 1234.5]
+>>> del a[2:4]
+>>> a
+[1, 66.25, 1234.5]
+>>> del a[:]
+>>> a
+[]
+\end{verbatim}
+
+\keyword{del} can also be used to delete entire variables:
+
+\begin{verbatim}
+>>> del a
+\end{verbatim}
+
+Referencing the name \code{a} hereafter is an error (at least until
+another value is assigned to it).  We'll find other uses for
+\keyword{del} later.
+
+
+\section{Tuples and Sequences \label{tuples}}
+
+We saw that lists and strings have many common properties, such as
+indexing and slicing operations.  They are two examples of
+\ulink{\emph{sequence} data types}{../lib/typesseq.html}.  Since
+Python is an evolving language, other sequence data types may be
+added.  There is also another standard sequence data type: the
+\emph{tuple}.
+
+A tuple consists of a number of values separated by commas, for
+instance:
+
+\begin{verbatim}
+>>> t = 12345, 54321, 'hello!'
+>>> t[0]
+12345
+>>> t
+(12345, 54321, 'hello!')
+>>> # Tuples may be nested:
+... u = t, (1, 2, 3, 4, 5)
+>>> u
+((12345, 54321, 'hello!'), (1, 2, 3, 4, 5))
+\end{verbatim}
+
+As you see, on output tuples are always enclosed in parentheses, so
+that nested tuples are interpreted correctly; they may be input with
+or without surrounding parentheses, although often parentheses are
+necessary anyway (if the tuple is part of a larger expression).
+
+Tuples have many uses.  For example: (x, y) coordinate pairs, employee
+records from a database, etc.  Tuples, like strings, are immutable: it
+is not possible to assign to the individual items of a tuple (you can
+simulate much of the same effect with slicing and concatenation,
+though).  It is also possible to create tuples which contain mutable
+objects, such as lists.
+
+A special problem is the construction of tuples containing 0 or 1
+items: the syntax has some extra quirks to accommodate these.  Empty
+tuples are constructed by an empty pair of parentheses; a tuple with
+one item is constructed by following a value with a comma
+(it is not sufficient to enclose a single value in parentheses).
+Ugly, but effective.  For example:
+
+\begin{verbatim}
+>>> empty = ()
+>>> singleton = 'hello',    # <-- note trailing comma
+>>> len(empty)
+0
+>>> len(singleton)
+1
+>>> singleton
+('hello',)
+\end{verbatim}
+
+The statement \code{t = 12345, 54321, 'hello!'} is an example of
+\emph{tuple packing}: the values \code{12345}, \code{54321} and
+\code{'hello!'} are packed together in a tuple.  The reverse operation
+is also possible:
+
+\begin{verbatim}
+>>> x, y, z = t
+\end{verbatim}
+
+This is called, appropriately enough, \emph{sequence unpacking}.
+Sequence unpacking requires the list of variables on the left to
+have the same number of elements as the length of the sequence.  Note
+that multiple assignment is really just a combination of tuple packing
+and sequence unpacking!
+
+There is a small bit of asymmetry here:  packing multiple values
+always creates a tuple, and unpacking works for any sequence.
+
+% XXX Add a bit on the difference between tuples and lists.
+
+
+\section{Sets \label{sets}}
+
+Python also includes a data type for \emph{sets}.  A set is an unordered
+collection with no duplicate elements.  Basic uses include membership
+testing and eliminating duplicate entries.  Set objects also support
+mathematical operations like union, intersection, difference, and
+symmetric difference.
+
+Here is a brief demonstration:
+
+\begin{verbatim}
+>>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']
+>>> fruit = set(basket)               # create a set without duplicates
+>>> fruit
+set(['orange', 'pear', 'apple', 'banana'])
+>>> 'orange' in fruit                 # fast membership testing
+True
+>>> 'crabgrass' in fruit
+False
+
+>>> # Demonstrate set operations on unique letters from two words
+...
+>>> a = set('abracadabra')
+>>> b = set('alacazam')
+>>> a                                  # unique letters in a
+set(['a', 'r', 'b', 'c', 'd'])
+>>> a - b                              # letters in a but not in b
+set(['r', 'd', 'b'])
+>>> a | b                              # letters in either a or b
+set(['a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'])
+>>> a & b                              # letters in both a and b
+set(['a', 'c'])
+>>> a ^ b                              # letters in a or b but not both
+set(['r', 'd', 'b', 'm', 'z', 'l'])
+\end{verbatim}
+
+
+\section{Dictionaries \label{dictionaries}}
+
+Another useful data type built into Python is the
+\ulink{\emph{dictionary}}{../lib/typesmapping.html}.
+Dictionaries are sometimes found in other languages as ``associative
+memories'' or ``associative arrays''.  Unlike sequences, which are
+indexed by a range of numbers, dictionaries are indexed by \emph{keys},
+which can be any immutable type; strings and numbers can always be
+keys.  Tuples can be used as keys if they contain only strings,
+numbers, or tuples; if a tuple contains any mutable object either
+directly or indirectly, it cannot be used as a key.  You can't use
+lists as keys, since lists can be modified in place using
+index assignments, slice assignments, or methods like
+\method{append()} and \method{extend()}.
+
+It is best to think of a dictionary as an unordered set of
+\emph{key: value} pairs, with the requirement that the keys are unique
+(within one dictionary).
+A pair of braces creates an empty dictionary: \code{\{\}}.
+Placing a comma-separated list of key:value pairs within the
+braces adds initial key:value pairs to the dictionary; this is also the
+way dictionaries are written on output.
+
+The main operations on a dictionary are storing a value with some key
+and extracting the value given the key.  It is also possible to delete
+a key:value pair
+with \code{del}.
+If you store using a key that is already in use, the old value
+associated with that key is forgotten.  It is an error to extract a
+value using a non-existent key.
+
+The \method{keys()} method of a dictionary object returns a list of all
+the keys used in the dictionary, in arbitrary order (if you want it
+sorted, just apply the \method{sort()} method to the list of keys).  To
+check whether a single key is in the dictionary, either use the dictionary's
+\method{has_key()} method or the \keyword{in} keyword.
+
+Here is a small example using a dictionary:
+
+\begin{verbatim}
+>>> tel = {'jack': 4098, 'sape': 4139}
+>>> tel['guido'] = 4127
+>>> tel
+{'sape': 4139, 'guido': 4127, 'jack': 4098}
+>>> tel['jack']
+4098
+>>> del tel['sape']
+>>> tel['irv'] = 4127
+>>> tel
+{'guido': 4127, 'irv': 4127, 'jack': 4098}
+>>> tel.keys()
+['guido', 'irv', 'jack']
+>>> tel.has_key('guido')
+True
+>>> 'guido' in tel
+True
+\end{verbatim}
+
+The \function{dict()} constructor builds dictionaries directly from
+lists of key-value pairs stored as tuples.  When the pairs form a
+pattern, list comprehensions can compactly specify the key-value list.
+
+\begin{verbatim}
+>>> dict([('sape', 4139), ('guido', 4127), ('jack', 4098)])
+{'sape': 4139, 'jack': 4098, 'guido': 4127}
+>>> dict([(x, x**2) for x in (2, 4, 6)])     # use a list comprehension
+{2: 4, 4: 16, 6: 36}
+\end{verbatim}
+
+Later in the tutorial, we will learn about Generator Expressions
+which are even better suited for the task of supplying key-values pairs to
+the \function{dict()} constructor.
+
+When the keys are simple strings, it is sometimes easier to specify
+pairs using keyword arguments:
+
+\begin{verbatim}
+>>> dict(sape=4139, guido=4127, jack=4098)
+{'sape': 4139, 'jack': 4098, 'guido': 4127}
+\end{verbatim}
+
+
+\section{Looping Techniques \label{loopidioms}}
+
+When looping through dictionaries, the key and corresponding value can
+be retrieved at the same time using the \method{iteritems()} method.
+
+\begin{verbatim}
+>>> knights = {'gallahad': 'the pure', 'robin': 'the brave'}
+>>> for k, v in knights.iteritems():
+...     print k, v
+...
+gallahad the pure
+robin the brave
+\end{verbatim}
+ 
+When looping through a sequence, the position index and corresponding
+value can be retrieved at the same time using the
+\function{enumerate()} function.
+
+\begin{verbatim} 
+>>> for i, v in enumerate(['tic', 'tac', 'toe']):
+...     print i, v
+...
+0 tic
+1 tac
+2 toe
+\end{verbatim}
+
+To loop over two or more sequences at the same time, the entries
+can be paired with the \function{zip()} function.
+
+\begin{verbatim}
+>>> questions = ['name', 'quest', 'favorite color']
+>>> answers = ['lancelot', 'the holy grail', 'blue']
+>>> for q, a in zip(questions, answers):
+...     print 'What is your %s?  It is %s.' % (q, a)
+...	
+What is your name?  It is lancelot.
+What is your quest?  It is the holy grail.
+What is your favorite color?  It is blue.
+\end{verbatim}
+
+To loop over a sequence in reverse, first specify the sequence
+in a forward direction and then call the \function{reversed()}
+function.
+
+\begin{verbatim}
+>>> for i in reversed(xrange(1,10,2)):
+...     print i
+...
+9
+7
+5
+3
+1
+\end{verbatim}
+
+To loop over a sequence in sorted order, use the \function{sorted()}
+function which returns a new sorted list while leaving the source
+unaltered.
+
+\begin{verbatim}
+>>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']
+>>> for f in sorted(set(basket)):
+...     print f
+... 	
+apple
+banana
+orange
+pear
+\end{verbatim}
+
+\section{More on Conditions \label{conditions}}
+
+The conditions used in \code{while} and \code{if} statements can
+contain any operators, not just comparisons.
+
+The comparison operators \code{in} and \code{not in} check whether a value
+occurs (does not occur) in a sequence.  The operators \code{is} and
+\code{is not} compare whether two objects are really the same object; this
+only matters for mutable objects like lists.  All comparison operators
+have the same priority, which is lower than that of all numerical
+operators.
+
+Comparisons can be chained.  For example, \code{a < b == c} tests
+whether \code{a} is less than \code{b} and moreover \code{b} equals
+\code{c}.
+
+Comparisons may be combined using the Boolean operators \code{and} and
+\code{or}, and the outcome of a comparison (or of any other Boolean
+expression) may be negated with \code{not}.  These have lower
+priorities than comparison operators; between them, \code{not} has
+the highest priority and \code{or} the lowest, so that
+\code{A and not B or C} is equivalent to \code{(A and (not B)) or C}.
+As always, parentheses can be used to express the desired composition.
+
+The Boolean operators \code{and} and \code{or} are so-called
+\emph{short-circuit} operators: their arguments are evaluated from
+left to right, and evaluation stops as soon as the outcome is
+determined.  For example, if \code{A} and \code{C} are true but
+\code{B} is false, \code{A and B and C} does not evaluate the
+expression \code{C}.  When used as a general value and not as a
+Boolean, the return value of a short-circuit operator is the last
+evaluated argument.
+
+It is possible to assign the result of a comparison or other Boolean
+expression to a variable.  For example,
+
+\begin{verbatim}
+>>> string1, string2, string3 = '', 'Trondheim', 'Hammer Dance'
+>>> non_null = string1 or string2 or string3
+>>> non_null
+'Trondheim'
+\end{verbatim}
+
+Note that in Python, unlike C, assignment cannot occur inside expressions.
+C programmers may grumble about this, but it avoids a common class of
+problems encountered in C programs: typing \code{=} in an expression when
+\code{==} was intended.
+
+
+\section{Comparing Sequences and Other Types \label{comparing}}
+
+Sequence objects may be compared to other objects with the same
+sequence type.  The comparison uses \emph{lexicographical} ordering:
+first the first two items are compared, and if they differ this
+determines the outcome of the comparison; if they are equal, the next
+two items are compared, and so on, until either sequence is exhausted.
+If two items to be compared are themselves sequences of the same type,
+the lexicographical comparison is carried out recursively.  If all
+items of two sequences compare equal, the sequences are considered
+equal.  If one sequence is an initial sub-sequence of the other, the
+shorter sequence is the smaller (lesser) one.  Lexicographical
+ordering for strings uses the \ASCII{} ordering for individual
+characters.  Some examples of comparisons between sequences of the
+same type:
+
+\begin{verbatim}
+(1, 2, 3)              < (1, 2, 4)
+[1, 2, 3]              < [1, 2, 4]
+'ABC' < 'C' < 'Pascal' < 'Python'
+(1, 2, 3, 4)           < (1, 2, 4)
+(1, 2)                 < (1, 2, -1)
+(1, 2, 3)             == (1.0, 2.0, 3.0)
+(1, 2, ('aa', 'ab'))   < (1, 2, ('abc', 'a'), 4)
+\end{verbatim}
+
+Note that comparing objects of different types is legal.  The outcome
+is deterministic but arbitrary: the types are ordered by their name.
+Thus, a list is always smaller than a string, a string is always
+smaller than a tuple, etc.  \footnote{
+        The rules for comparing objects of different types should
+        not be relied upon; they may change in a future version of
+        the language.
+} Mixed numeric types are compared according to their numeric value, so
+0 equals 0.0, etc.
+
+
+\chapter{Modules \label{modules}}
+
+If you quit from the Python interpreter and enter it again, the
+definitions you have made (functions and variables) are lost.
+Therefore, if you want to write a somewhat longer program, you are
+better off using a text editor to prepare the input for the interpreter
+and running it with that file as input instead.  This is known as creating a
+\emph{script}.  As your program gets longer, you may want to split it
+into several files for easier maintenance.  You may also want to use a
+handy function that you've written in several programs without copying
+its definition into each program.
+
+To support this, Python has a way to put definitions in a file and use
+them in a script or in an interactive instance of the interpreter.
+Such a file is called a \emph{module}; definitions from a module can be
+\emph{imported} into other modules or into the \emph{main} module (the
+collection of variables that you have access to in a script
+executed at the top level
+and in calculator mode).
+
+A module is a file containing Python definitions and statements.  The
+file name is the module name with the suffix \file{.py} appended.  Within
+a module, the module's name (as a string) is available as the value of
+the global variable \code{__name__}.  For instance, use your favorite text
+editor to create a file called \file{fibo.py} in the current directory
+with the following contents:
+
+\begin{verbatim}
+# Fibonacci numbers module
+
+def fib(n):    # write Fibonacci series up to n
+    a, b = 0, 1
+    while b < n:
+        print b,
+        a, b = b, a+b
+
+def fib2(n): # return Fibonacci series up to n
+    result = []
+    a, b = 0, 1
+    while b < n:
+        result.append(b)
+        a, b = b, a+b
+    return result
+\end{verbatim}
+
+Now enter the Python interpreter and import this module with the
+following command:
+
+\begin{verbatim}
+>>> import fibo
+\end{verbatim}
+
+This does not enter the names of the functions defined in \code{fibo} 
+directly in the current symbol table; it only enters the module name
+\code{fibo} there.
+Using the module name you can access the functions:
+
+\begin{verbatim}
+>>> fibo.fib(1000)
+1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
+>>> fibo.fib2(100)
+[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
+>>> fibo.__name__
+'fibo'
+\end{verbatim}
+
+If you intend to use a function often you can assign it to a local name:
+
+\begin{verbatim}
+>>> fib = fibo.fib
+>>> fib(500)
+1 1 2 3 5 8 13 21 34 55 89 144 233 377
+\end{verbatim}
+
+
+\section{More on Modules \label{moreModules}}
+
+A module can contain executable statements as well as function
+definitions.
+These statements are intended to initialize the module.
+They are executed only the
+\emph{first} time the module is imported somewhere.\footnote{
+        In fact function definitions are also `statements' that are
+        `executed'; the execution enters the function name in the
+        module's global symbol table.
+}
+
+Each module has its own private symbol table, which is used as the
+global symbol table by all functions defined in the module.
+Thus, the author of a module can use global variables in the module
+without worrying about accidental clashes with a user's global
+variables.
+On the other hand, if you know what you are doing you can touch a
+module's global variables with the same notation used to refer to its
+functions,
+\code{modname.itemname}.
+
+Modules can import other modules.  It is customary but not required to
+place all \keyword{import} statements at the beginning of a module (or
+script, for that matter).  The imported module names are placed in the
+importing module's global symbol table.
+
+There is a variant of the \keyword{import} statement that imports
+names from a module directly into the importing module's symbol
+table.  For example:
+
+\begin{verbatim}
+>>> from fibo import fib, fib2
+>>> fib(500)
+1 1 2 3 5 8 13 21 34 55 89 144 233 377
+\end{verbatim}
+
+This does not introduce the module name from which the imports are taken
+in the local symbol table (so in the example, \code{fibo} is not
+defined).
+
+There is even a variant to import all names that a module defines:
+
+\begin{verbatim}
+>>> from fibo import *
+>>> fib(500)
+1 1 2 3 5 8 13 21 34 55 89 144 233 377
+\end{verbatim}
+
+This imports all names except those beginning with an underscore
+(\code{_}).
+
+
+\subsection{The Module Search Path \label{searchPath}}
+
+\indexiii{module}{search}{path}
+When a module named \module{spam} is imported, the interpreter searches
+for a file named \file{spam.py} in the current directory,
+and then in the list of directories specified by
+the environment variable \envvar{PYTHONPATH}.  This has the same syntax as
+the shell variable \envvar{PATH}, that is, a list of
+directory names.  When \envvar{PYTHONPATH} is not set, or when the file
+is not found there, the search continues in an installation-dependent
+default path; on \UNIX, this is usually \file{.:/usr/local/lib/python}.
+
+Actually, modules are searched in the list of directories given by the 
+variable \code{sys.path} which is initialized from the directory 
+containing the input script (or the current directory),
+\envvar{PYTHONPATH} and the installation-dependent default.  This allows
+Python programs that know what they're doing to modify or replace the 
+module search path.  Note that because the directory containing the
+script being run is on the search path, it is important that the
+script not have the same name as a standard module, or Python will
+attempt to load the script as a module when that module is imported.
+This will generally be an error.  See section~\ref{standardModules},
+``Standard Modules,'' for more information.
+
+
+\subsection{``Compiled'' Python files}
+
+As an important speed-up of the start-up time for short programs that
+use a lot of standard modules, if a file called \file{spam.pyc} exists
+in the directory where \file{spam.py} is found, this is assumed to
+contain an already-``byte-compiled'' version of the module \module{spam}.
+The modification time of the version of \file{spam.py} used to create
+\file{spam.pyc} is recorded in \file{spam.pyc}, and the
+\file{.pyc} file is ignored if these don't match.
+
+Normally, you don't need to do anything to create the
+\file{spam.pyc} file.  Whenever \file{spam.py} is successfully
+compiled, an attempt is made to write the compiled version to
+\file{spam.pyc}.  It is not an error if this attempt fails; if for any
+reason the file is not written completely, the resulting
+\file{spam.pyc} file will be recognized as invalid and thus ignored
+later.  The contents of the \file{spam.pyc} file are platform
+independent, so a Python module directory can be shared by machines of
+different architectures.
+
+Some tips for experts:
+
+\begin{itemize}
+
+\item
+When the Python interpreter is invoked with the \programopt{-O} flag,
+optimized code is generated and stored in \file{.pyo} files.  The
+optimizer currently doesn't help much; it only removes
+\keyword{assert} statements.  When \programopt{-O} is used, \emph{all}
+bytecode is optimized; \code{.pyc} files are ignored and \code{.py}
+files are compiled to optimized bytecode.
+
+\item
+Passing two \programopt{-O} flags to the Python interpreter
+(\programopt{-OO}) will cause the bytecode compiler to perform
+optimizations that could in some rare cases result in malfunctioning
+programs.  Currently only \code{__doc__} strings are removed from the
+bytecode, resulting in more compact \file{.pyo} files.  Since some
+programs may rely on having these available, you should only use this
+option if you know what you're doing.
+
+\item
+A program doesn't run any faster when it is read from a \file{.pyc} or
+\file{.pyo} file than when it is read from a \file{.py} file; the only
+thing that's faster about \file{.pyc} or \file{.pyo} files is the
+speed with which they are loaded.
+
+\item
+When a script is run by giving its name on the command line, the
+bytecode for the script is never written to a \file{.pyc} or
+\file{.pyo} file.  Thus, the startup time of a script may be reduced
+by moving most of its code to a module and having a small bootstrap
+script that imports that module.  It is also possible to name a
+\file{.pyc} or \file{.pyo} file directly on the command line.
+
+\item
+It is possible to have a file called \file{spam.pyc} (or
+\file{spam.pyo} when \programopt{-O} is used) without a file
+\file{spam.py} for the same module.  This can be used to distribute a
+library of Python code in a form that is moderately hard to reverse
+engineer.
+
+\item
+The module \ulink{\module{compileall}}{../lib/module-compileall.html}%
+{} \refstmodindex{compileall} can create \file{.pyc} files (or
+\file{.pyo} files when \programopt{-O} is used) for all modules in a
+directory.
+
+\end{itemize}
+
+
+\section{Standard Modules \label{standardModules}}
+
+Python comes with a library of standard modules, described in a separate
+document, the \citetitle[../lib/lib.html]{Python Library Reference}
+(``Library Reference'' hereafter).  Some modules are built into the
+interpreter; these provide access to operations that are not part of
+the core of the language but are nevertheless built in, either for
+efficiency or to provide access to operating system primitives such as
+system calls.  The set of such modules is a configuration option which
+also depends on the underlying platform  For example,
+the \module{amoeba} module is only provided on systems that somehow
+support Amoeba primitives.  One particular module deserves some
+attention: \ulink{\module{sys}}{../lib/module-sys.html}%
+\refstmodindex{sys}, which is built into every 
+Python interpreter.  The variables \code{sys.ps1} and
+\code{sys.ps2} define the strings used as primary and secondary
+prompts:
+
+\begin{verbatim}
+>>> import sys
+>>> sys.ps1
+'>>> '
+>>> sys.ps2
+'... '
+>>> sys.ps1 = 'C> '
+C> print 'Yuck!'
+Yuck!
+C>
+
+\end{verbatim}
+
+These two variables are only defined if the interpreter is in
+interactive mode.
+
+The variable \code{sys.path} is a list of strings that determines the
+interpreter's search path for modules. It is initialized to a default
+path taken from the environment variable \envvar{PYTHONPATH}, or from
+a built-in default if \envvar{PYTHONPATH} is not set.  You can modify
+it using standard list operations: 
+
+\begin{verbatim}
+>>> import sys
+>>> sys.path.append('/ufs/guido/lib/python')
+\end{verbatim}
+
+\section{The \function{dir()} Function \label{dir}}
+
+The built-in function \function{dir()} is used to find out which names
+a module defines.  It returns a sorted list of strings:
+
+\begin{verbatim}
+>>> import fibo, sys
+>>> dir(fibo)
+['__name__', 'fib', 'fib2']
+>>> dir(sys)
+['__displayhook__', '__doc__', '__excepthook__', '__name__', '__stderr__',
+ '__stdin__', '__stdout__', '_getframe', 'api_version', 'argv', 
+ 'builtin_module_names', 'byteorder', 'callstats', 'copyright',
+ 'displayhook', 'exc_clear', 'exc_info', 'exc_type', 'excepthook',
+ 'exec_prefix', 'executable', 'exit', 'getdefaultencoding', 'getdlopenflags',
+ 'getrecursionlimit', 'getrefcount', 'hexversion', 'maxint', 'maxunicode',
+ 'meta_path', 'modules', 'path', 'path_hooks', 'path_importer_cache',
+ 'platform', 'prefix', 'ps1', 'ps2', 'setcheckinterval', 'setdlopenflags',
+ 'setprofile', 'setrecursionlimit', 'settrace', 'stderr', 'stdin', 'stdout',
+ 'version', 'version_info', 'warnoptions']
+\end{verbatim}
+
+Without arguments, \function{dir()} lists the names you have defined
+currently:
+
+\begin{verbatim}
+>>> a = [1, 2, 3, 4, 5]
+>>> import fibo
+>>> fib = fibo.fib
+>>> dir()
+['__builtins__', '__doc__', '__file__', '__name__', 'a', 'fib', 'fibo', 'sys']
+\end{verbatim}
+
+Note that it lists all types of names: variables, modules, functions, etc.
+
+\function{dir()} does not list the names of built-in functions and
+variables.  If you want a list of those, they are defined in the
+standard module \module{__builtin__}\refbimodindex{__builtin__}:
+
+\begin{verbatim}
+>>> import __builtin__
+>>> dir(__builtin__)
+['ArithmeticError', 'AssertionError', 'AttributeError', 'DeprecationWarning',
+ 'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False',
+ 'FloatingPointError', 'FutureWarning', 'IOError', 'ImportError',
+ 'IndentationError', 'IndexError', 'KeyError', 'KeyboardInterrupt',
+ 'LookupError', 'MemoryError', 'NameError', 'None', 'NotImplemented',
+ 'NotImplementedError', 'OSError', 'OverflowError', 
+ 'PendingDeprecationWarning', 'ReferenceError', 'RuntimeError',
+ 'RuntimeWarning', 'StandardError', 'StopIteration', 'SyntaxError',
+ 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'True',
+ 'TypeError', 'UnboundLocalError', 'UnicodeDecodeError',
+ 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError',
+ 'UserWarning', 'ValueError', 'Warning', 'WindowsError',
+ 'ZeroDivisionError', '_', '__debug__', '__doc__', '__import__',
+ '__name__', 'abs', 'apply', 'basestring', 'bool', 'buffer',
+ 'callable', 'chr', 'classmethod', 'cmp', 'coerce', 'compile',
+ 'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'divmod',
+ 'enumerate', 'eval', 'execfile', 'exit', 'file', 'filter', 'float',
+ 'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex',
+ 'id', 'input', 'int', 'intern', 'isinstance', 'issubclass', 'iter',
+ 'len', 'license', 'list', 'locals', 'long', 'map', 'max', 'min',
+ 'object', 'oct', 'open', 'ord', 'pow', 'property', 'quit', 'range',
+ 'raw_input', 'reduce', 'reload', 'repr', 'reversed', 'round', 'set',
+ 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super',
+ 'tuple', 'type', 'unichr', 'unicode', 'vars', 'xrange', 'zip']
+\end{verbatim}
+
+
+\section{Packages \label{packages}}
+
+Packages are a way of structuring Python's module namespace
+by using ``dotted module names''.  For example, the module name
+\module{A.B} designates a submodule named \samp{B} in a package named
+\samp{A}.  Just like the use of modules saves the authors of different
+modules from having to worry about each other's global variable names,
+the use of dotted module names saves the authors of multi-module
+packages like NumPy or the Python Imaging Library from having to worry
+about each other's module names.
+
+Suppose you want to design a collection of modules (a ``package'') for
+the uniform handling of sound files and sound data.  There are many
+different sound file formats (usually recognized by their extension,
+for example: \file{.wav}, \file{.aiff}, \file{.au}), so you may need
+to create and maintain a growing collection of modules for the
+conversion between the various file formats.  There are also many
+different operations you might want to perform on sound data (such as
+mixing, adding echo, applying an equalizer function, creating an
+artificial stereo effect), so in addition you will be writing a
+never-ending stream of modules to perform these operations.  Here's a
+possible structure for your package (expressed in terms of a
+hierarchical filesystem):
+
+\begin{verbatim}
+Sound/                          Top-level package
+      __init__.py               Initialize the sound package
+      Formats/                  Subpackage for file format conversions
+              __init__.py
+              wavread.py
+              wavwrite.py
+              aiffread.py
+              aiffwrite.py
+              auread.py
+              auwrite.py
+              ...
+      Effects/                  Subpackage for sound effects
+              __init__.py
+              echo.py
+              surround.py
+              reverse.py
+              ...
+      Filters/                  Subpackage for filters
+              __init__.py
+              equalizer.py
+              vocoder.py
+              karaoke.py
+              ...
+\end{verbatim}
+
+When importing the package, Python searches through the directories
+on \code{sys.path} looking for the package subdirectory.
+
+The \file{__init__.py} files are required to make Python treat the
+directories as containing packages; this is done to prevent
+directories with a common name, such as \samp{string}, from
+unintentionally hiding valid modules that occur later on the module
+search path. In the simplest case, \file{__init__.py} can just be an
+empty file, but it can also execute initialization code for the
+package or set the \code{__all__} variable, described later.
+
+Users of the package can import individual modules from the
+package, for example:
+
+\begin{verbatim}
+import Sound.Effects.echo
+\end{verbatim}
+
+This loads the submodule \module{Sound.Effects.echo}.  It must be referenced
+with its full name.
+
+\begin{verbatim}
+Sound.Effects.echo.echofilter(input, output, delay=0.7, atten=4)
+\end{verbatim}
+
+An alternative way of importing the submodule is:
+
+\begin{verbatim}
+from Sound.Effects import echo
+\end{verbatim}
+
+This also loads the submodule \module{echo}, and makes it available without
+its package prefix, so it can be used as follows:
+
+\begin{verbatim}
+echo.echofilter(input, output, delay=0.7, atten=4)
+\end{verbatim}
+
+Yet another variation is to import the desired function or variable directly:
+
+\begin{verbatim}
+from Sound.Effects.echo import echofilter
+\end{verbatim}
+
+Again, this loads the submodule \module{echo}, but this makes its function
+\function{echofilter()} directly available:
+
+\begin{verbatim}
+echofilter(input, output, delay=0.7, atten=4)
+\end{verbatim}
+
+Note that when using \code{from \var{package} import \var{item}}, the
+item can be either a submodule (or subpackage) of the package, or some 
+other name defined in the package, like a function, class or
+variable.  The \code{import} statement first tests whether the item is
+defined in the package; if not, it assumes it is a module and attempts
+to load it.  If it fails to find it, an
+\exception{ImportError} exception is raised.
+
+Contrarily, when using syntax like \code{import
+\var{item.subitem.subsubitem}}, each item except for the last must be
+a package; the last item can be a module or a package but can't be a
+class or function or variable defined in the previous item.
+
+\subsection{Importing * From a Package \label{pkg-import-star}}
+%The \code{__all__} Attribute
+
+\ttindex{__all__}
+Now what happens when the user writes \code{from Sound.Effects import
+*}?  Ideally, one would hope that this somehow goes out to the
+filesystem, finds which submodules are present in the package, and
+imports them all.  Unfortunately, this operation does not work very
+well on Windows platforms, where the filesystem does not
+always have accurate information about the case of a filename!  On
+these platforms, there is no guaranteed way to know whether a file
+\file{ECHO.PY} should be imported as a module \module{echo},
+\module{Echo} or \module{ECHO}.  (For example, Windows 95 has the
+annoying practice of showing all file names with a capitalized first
+letter.)  The DOS 8+3 filename restriction adds another interesting
+problem for long module names.
+
+The only solution is for the package author to provide an explicit
+index of the package.  The import statement uses the following
+convention: if a package's \file{__init__.py} code defines a list
+named \code{__all__}, it is taken to be the list of module names that
+should be imported when \code{from \var{package} import *} is
+encountered.  It is up to the package author to keep this list
+up-to-date when a new version of the package is released.  Package
+authors may also decide not to support it, if they don't see a use for
+importing * from their package.  For example, the file
+\file{Sounds/Effects/__init__.py} could contain the following code:
+
+\begin{verbatim}
+__all__ = ["echo", "surround", "reverse"]
+\end{verbatim}
+
+This would mean that \code{from Sound.Effects import *} would
+import the three named submodules of the \module{Sound} package.
+
+If \code{__all__} is not defined, the statement \code{from Sound.Effects
+import *} does \emph{not} import all submodules from the package
+\module{Sound.Effects} into the current namespace; it only ensures that the
+package \module{Sound.Effects} has been imported (possibly running any
+initialization code in \file{__init__.py}) and then imports whatever names are
+defined in the package.  This includes any names defined (and
+submodules explicitly loaded) by \file{__init__.py}.  It also includes any
+submodules of the package that were explicitly loaded by previous
+import statements.  Consider this code:
+
+\begin{verbatim}
+import Sound.Effects.echo
+import Sound.Effects.surround
+from Sound.Effects import *
+\end{verbatim}
+
+In this example, the echo and surround modules are imported in the
+current namespace because they are defined in the
+\module{Sound.Effects} package when the \code{from...import} statement
+is executed.  (This also works when \code{__all__} is defined.)
+
+Note that in general the practice of importing \code{*} from a module or
+package is frowned upon, since it often causes poorly readable code.
+However, it is okay to use it to save typing in interactive sessions,
+and certain modules are designed to export only names that follow
+certain patterns.
+
+Remember, there is nothing wrong with using \code{from Package
+import specific_submodule}!  In fact, this is the
+recommended notation unless the importing module needs to use
+submodules with the same name from different packages.
+
+
+\subsection{Intra-package References}
+
+The submodules often need to refer to each other.  For example, the
+\module{surround} module might use the \module{echo} module.  In fact,
+such references are so common that the \keyword{import} statement
+first looks in the containing package before looking in the standard
+module search path. Thus, the \module{surround} module can simply use
+\code{import echo} or \code{from echo import echofilter}.  If the
+imported module is not found in the current package (the package of
+which the current module is a submodule), the \keyword{import}
+statement looks for a top-level module with the given name.
+
+When packages are structured into subpackages (as with the
+\module{Sound} package in the example), there's no shortcut to refer
+to submodules of sibling packages - the full name of the subpackage
+must be used.  For example, if the module
+\module{Sound.Filters.vocoder} needs to use the \module{echo} module
+in the \module{Sound.Effects} package, it can use \code{from
+Sound.Effects import echo}.
+
+Starting with Python 2.5, in addition to the implicit relative imports
+described above, you can write explicit relative imports with the
+\code{from module import name} form of import statement. These explicit
+relative imports use leading dots to indicate the current and parent
+packages involved in the relative import. From the \module{surround}
+module for example, you might use:
+
+\begin{verbatim}
+from . import echo
+from .. import Formats
+from ..Filters import equalizer
+\end{verbatim}
+
+Note that both explicit and implicit relative imports are based on the
+name of the current module. Since the name of the main module is always
+\code{"__main__"}, modules intended for use as the main module of a
+Python application should always use absolute imports.
+
+\subsection{Packages in Multiple Directories}
+
+Packages support one more special attribute, \member{__path__}.  This
+is initialized to be a list containing the name of the directory
+holding the package's \file{__init__.py} before the code in that file
+is executed.  This variable can be modified; doing so affects future
+searches for modules and subpackages contained in the package.
+
+While this feature is not often needed, it can be used to extend the
+set of modules found in a package.
+
+
+
+\chapter{Input and Output \label{io}}
+
+There are several ways to present the output of a program; data can be
+printed in a human-readable form, or written to a file for future use.
+This chapter will discuss some of the possibilities.
+
+
+\section{Fancier Output Formatting \label{formatting}}
+
+So far we've encountered two ways of writing values: \emph{expression
+statements} and the \keyword{print} statement.  (A third way is using
+the \method{write()} method of file objects; the standard output file
+can be referenced as \code{sys.stdout}.  See the Library Reference for
+more information on this.)
+
+Often you'll want more control over the formatting of your output than
+simply printing space-separated values.  There are two ways to format
+your output; the first way is to do all the string handling yourself;
+using string slicing and concatenation operations you can create any
+layout you can imagine.  The standard module
+\module{string}\refstmodindex{string} contains some useful operations
+for padding strings to a given column width; these will be discussed
+shortly.  The second way is to use the \code{\%} operator with a
+string as the left argument.  The \code{\%} operator interprets the
+left argument much like a \cfunction{sprintf()}-style format
+string to be applied to the right argument, and returns the string
+resulting from this formatting operation.
+
+One question remains, of course: how do you convert values to strings?
+Luckily, Python has ways to convert any value to a string: pass it to
+the \function{repr()}  or \function{str()} functions.  Reverse quotes
+(\code{``}) are equivalent to \function{repr()}, but they are no
+longer used in modern Python code and will likely not be in future
+versions of the language.
+
+The \function{str()} function is meant to return representations of
+values which are fairly human-readable, while \function{repr()} is
+meant to generate representations which can be read by the interpreter
+(or will force a \exception{SyntaxError} if there is not equivalent
+syntax).  For objects which don't have a particular representation for
+human consumption, \function{str()} will return the same value as
+\function{repr()}.  Many values, such as numbers or structures like
+lists and dictionaries, have the same representation using either
+function.  Strings and floating point numbers, in particular, have two
+distinct representations.
+
+Some examples:
+
+\begin{verbatim}
+>>> s = 'Hello, world.'
+>>> str(s)
+'Hello, world.'
+>>> repr(s)
+"'Hello, world.'"
+>>> str(0.1)
+'0.1'
+>>> repr(0.1)
+'0.10000000000000001'
+>>> x = 10 * 3.25
+>>> y = 200 * 200
+>>> s = 'The value of x is ' + repr(x) + ', and y is ' + repr(y) + '...'
+>>> print s
+The value of x is 32.5, and y is 40000...
+>>> # The repr() of a string adds string quotes and backslashes:
+... hello = 'hello, world\n'
+>>> hellos = repr(hello)
+>>> print hellos
+'hello, world\n'
+>>> # The argument to repr() may be any Python object:
+... repr((x, y, ('spam', 'eggs')))
+"(32.5, 40000, ('spam', 'eggs'))"
+>>> # reverse quotes are convenient in interactive sessions:
+... `x, y, ('spam', 'eggs')`
+"(32.5, 40000, ('spam', 'eggs'))"
+\end{verbatim}
+
+Here are two ways to write a table of squares and cubes:
+
+\begin{verbatim}
+>>> for x in range(1, 11):
+...     print repr(x).rjust(2), repr(x*x).rjust(3),
+...     # Note trailing comma on previous line
+...     print repr(x*x*x).rjust(4)
+...
+ 1   1    1
+ 2   4    8
+ 3   9   27
+ 4  16   64
+ 5  25  125
+ 6  36  216
+ 7  49  343
+ 8  64  512
+ 9  81  729
+10 100 1000
+
+>>> for x in range(1,11):
+...     print '%2d %3d %4d' % (x, x*x, x*x*x)
+... 
+ 1   1    1
+ 2   4    8
+ 3   9   27
+ 4  16   64
+ 5  25  125
+ 6  36  216
+ 7  49  343
+ 8  64  512
+ 9  81  729
+10 100 1000
+\end{verbatim}
+
+(Note that in the first example, one space between each column was
+added by the way \keyword{print} works: it always adds spaces between
+its arguments.)
+
+This example demonstrates the \method{rjust()} method of string objects,
+which right-justifies a string in a field of a given width by padding
+it with spaces on the left.  There are similar methods
+\method{ljust()} and \method{center()}.  These
+methods do not write anything, they just return a new string.  If
+the input string is too long, they don't truncate it, but return it
+unchanged; this will mess up your column lay-out but that's usually
+better than the alternative, which would be lying about a value.  (If
+you really want truncation you can always add a slice operation, as in
+\samp{x.ljust(n)[:n]}.)
+
+There is another method, \method{zfill()}, which pads a
+numeric string on the left with zeros.  It understands about plus and
+minus signs:
+
+\begin{verbatim}
+>>> '12'.zfill(5)
+'00012'
+>>> '-3.14'.zfill(7)
+'-003.14'
+>>> '3.14159265359'.zfill(5)
+'3.14159265359'
+\end{verbatim}
+
+Using the \code{\%} operator looks like this:
+
+\begin{verbatim}
+>>> import math
+>>> print 'The value of PI is approximately %5.3f.' % math.pi
+The value of PI is approximately 3.142.
+\end{verbatim}
+
+If there is more than one format in the string, you need to pass a
+tuple as right operand, as in this example:
+
+\begin{verbatim}
+>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 7678}
+>>> for name, phone in table.items():
+...     print '%-10s ==> %10d' % (name, phone)
+... 
+Jack       ==>       4098
+Dcab       ==>       7678
+Sjoerd     ==>       4127
+\end{verbatim}
+
+Most formats work exactly as in C and require that you pass the proper
+type; however, if you don't you get an exception, not a core dump.
+The \code{\%s} format is more relaxed: if the corresponding argument is
+not a string object, it is converted to string using the
+\function{str()} built-in function.  Using \code{*} to pass the width
+or precision in as a separate (integer) argument is supported.  The
+C formats \code{\%n} and \code{\%p} are not supported.
+
+If you have a really long format string that you don't want to split
+up, it would be nice if you could reference the variables to be
+formatted by name instead of by position.  This can be done by using
+form \code{\%(name)format}, as shown here:
+
+\begin{verbatim}
+>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678}
+>>> print 'Jack: %(Jack)d; Sjoerd: %(Sjoerd)d; Dcab: %(Dcab)d' % table
+Jack: 4098; Sjoerd: 4127; Dcab: 8637678
+\end{verbatim}
+
+This is particularly useful in combination with the new built-in
+\function{vars()} function, which returns a dictionary containing all
+local variables.
+
+\section{Reading and Writing Files \label{files}}
+
+% Opening files 
+\function{open()}\bifuncindex{open} returns a file
+object\obindex{file}, and is most commonly used with two arguments:
+\samp{open(\var{filename}, \var{mode})}.
+
+\begin{verbatim}
+>>> f=open('/tmp/workfile', 'w')
+>>> print f
+<open file '/tmp/workfile', mode 'w' at 80a0960>
+\end{verbatim}
+
+The first argument is a string containing the filename.  The second
+argument is another string containing a few characters describing the
+way in which the file will be used.  \var{mode} can be \code{'r'} when
+the file will only be read, \code{'w'} for only writing (an existing
+file with the same name will be erased), and \code{'a'} opens the file
+for appending; any data written to the file is automatically added to
+the end.  \code{'r+'} opens the file for both reading and writing.
+The \var{mode} argument is optional; \code{'r'} will be assumed if
+it's omitted.
+
+On Windows and the Macintosh, \code{'b'} appended to the
+mode opens the file in binary mode, so there are also modes like
+\code{'rb'}, \code{'wb'}, and \code{'r+b'}.  Windows makes a
+distinction between text and binary files; the end-of-line characters
+in text files are automatically altered slightly when data is read or
+written.  This behind-the-scenes modification to file data is fine for
+\ASCII{} text files, but it'll corrupt binary data like that in \file{JPEG} or
+\file{EXE} files.  Be very careful to use binary mode when reading and
+writing such files.
+
+\subsection{Methods of File Objects \label{fileMethods}}
+
+The rest of the examples in this section will assume that a file
+object called \code{f} has already been created.
+
+To read a file's contents, call \code{f.read(\var{size})}, which reads
+some quantity of data and returns it as a string.  \var{size} is an
+optional numeric argument.  When \var{size} is omitted or negative,
+the entire contents of the file will be read and returned; it's your
+problem if the file is twice as large as your machine's memory.
+Otherwise, at most \var{size} bytes are read and returned.  If the end
+of the file has been reached, \code{f.read()} will return an empty
+string (\code {""}).
+\begin{verbatim}
+>>> f.read()
+'This is the entire file.\n'
+>>> f.read()
+''
+\end{verbatim}
+
+\code{f.readline()} reads a single line from the file; a newline
+character (\code{\e n}) is left at the end of the string, and is only
+omitted on the last line of the file if the file doesn't end in a
+newline.  This makes the return value unambiguous; if
+\code{f.readline()} returns an empty string, the end of the file has
+been reached, while a blank line is represented by \code{'\e n'}, a
+string containing only a single newline.  
+
+\begin{verbatim}
+>>> f.readline()
+'This is the first line of the file.\n'
+>>> f.readline()
+'Second line of the file\n'
+>>> f.readline()
+''
+\end{verbatim}
+
+\code{f.readlines()} returns a list containing all the lines of data
+in the file.  If given an optional parameter \var{sizehint}, it reads
+that many bytes from the file and enough more to complete a line, and
+returns the lines from that.  This is often used to allow efficient
+reading of a large file by lines, but without having to load the
+entire file in memory.  Only complete lines will be returned.
+
+\begin{verbatim}
+>>> f.readlines()
+['This is the first line of the file.\n', 'Second line of the file\n']
+\end{verbatim}
+
+An alternate approach to reading lines is to loop over the file object.
+This is memory efficient, fast, and leads to simpler code:
+
+\begin{verbatim}
+>>> for line in f:
+        print line,
+        
+This is the first line of the file.
+Second line of the file
+\end{verbatim}
+
+The alternative approach is simpler but does not provide as fine-grained
+control.  Since the two approaches manage line buffering differently,
+they should not be mixed.
+
+\code{f.write(\var{string})} writes the contents of \var{string} to
+the file, returning \code{None}.  
+
+\begin{verbatim}
+>>> f.write('This is a test\n')
+\end{verbatim}
+
+To write something other than a string, it needs to be converted to a
+string first:
+
+\begin{verbatim}
+>>> value = ('the answer', 42)
+>>> s = str(value)
+>>> f.write(s)
+\end{verbatim}
+
+\code{f.tell()} returns an integer giving the file object's current
+position in the file, measured in bytes from the beginning of the
+file.  To change the file object's position, use
+\samp{f.seek(\var{offset}, \var{from_what})}.  The position is
+computed from adding \var{offset} to a reference point; the reference
+point is selected by the \var{from_what} argument.  A
+\var{from_what} value of 0 measures from the beginning of the file, 1
+uses the current file position, and 2 uses the end of the file as the
+reference point.  \var{from_what} can be omitted and defaults to 0,
+using the beginning of the file as the reference point.
+
+\begin{verbatim}
+>>> f = open('/tmp/workfile', 'r+')
+>>> f.write('0123456789abcdef')
+>>> f.seek(5)     # Go to the 6th byte in the file
+>>> f.read(1)        
+'5'
+>>> f.seek(-3, 2) # Go to the 3rd byte before the end
+>>> f.read(1)
+'d'
+\end{verbatim}
+
+When you're done with a file, call \code{f.close()} to close it and
+free up any system resources taken up by the open file.  After calling
+\code{f.close()}, attempts to use the file object will automatically fail.
+
+\begin{verbatim}
+>>> f.close()
+>>> f.read()
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+ValueError: I/O operation on closed file
+\end{verbatim}
+
+File objects have some additional methods, such as
+\method{isatty()} and \method{truncate()} which are less frequently
+used; consult the Library Reference for a complete guide to file
+objects.
+
+\subsection{The \module{pickle} Module \label{pickle}}
+\refstmodindex{pickle}
+
+Strings can easily be written to and read from a file. Numbers take a
+bit more effort, since the \method{read()} method only returns
+strings, which will have to be passed to a function like
+\function{int()}, which takes a string like \code{'123'} and
+returns its numeric value 123.  However, when you want to save more
+complex data types like lists, dictionaries, or class instances,
+things get a lot more complicated.
+
+Rather than have users be constantly writing and debugging code to
+save complicated data types, Python provides a standard module called
+\ulink{\module{pickle}}{../lib/module-pickle.html}.  This is an
+amazing module that can take almost
+any Python object (even some forms of Python code!), and convert it to
+a string representation; this process is called \dfn{pickling}.  
+Reconstructing the object from the string representation is called
+\dfn{unpickling}.  Between pickling and unpickling, the string
+representing the object may have been stored in a file or data, or
+sent over a network connection to some distant machine.
+
+If you have an object \code{x}, and a file object \code{f} that's been
+opened for writing, the simplest way to pickle the object takes only
+one line of code:
+
+\begin{verbatim}
+pickle.dump(x, f)
+\end{verbatim}
+
+To unpickle the object again, if \code{f} is a file object which has
+been opened for reading:
+
+\begin{verbatim}
+x = pickle.load(f)
+\end{verbatim}
+
+(There are other variants of this, used when pickling many objects or
+when you don't want to write the pickled data to a file; consult the
+complete documentation for
+\ulink{\module{pickle}}{../lib/module-pickle.html} in the
+\citetitle[../lib/]{Python Library Reference}.)
+
+\ulink{\module{pickle}}{../lib/module-pickle.html} is the standard way
+to make Python objects which can be stored and reused by other
+programs or by a future invocation of the same program; the technical
+term for this is a \dfn{persistent} object.  Because
+\ulink{\module{pickle}}{../lib/module-pickle.html} is so widely used,
+many authors who write Python extensions take care to ensure that new
+data types such as matrices can be properly pickled and unpickled.
+
+
+
+\chapter{Errors and Exceptions \label{errors}}
+
+Until now error messages haven't been more than mentioned, but if you
+have tried out the examples you have probably seen some.  There are
+(at least) two distinguishable kinds of errors:
+\emph{syntax errors} and \emph{exceptions}.
+
+\section{Syntax Errors \label{syntaxErrors}}
+
+Syntax errors, also known as parsing errors, are perhaps the most common
+kind of complaint you get while you are still learning Python:
+
+\begin{verbatim}
+>>> while True print 'Hello world'
+  File "<stdin>", line 1, in ?
+    while True print 'Hello world'
+                   ^
+SyntaxError: invalid syntax
+\end{verbatim}
+
+The parser repeats the offending line and displays a little `arrow'
+pointing at the earliest point in the line where the error was
+detected.  The error is caused by (or at least detected at) the token
+\emph{preceding} the arrow: in the example, the error is detected at
+the keyword \keyword{print}, since a colon (\character{:}) is missing
+before it.  File name and line number are printed so you know where to
+look in case the input came from a script.
+
+\section{Exceptions \label{exceptions}}
+
+Even if a statement or expression is syntactically correct, it may
+cause an error when an attempt is made to execute it.
+Errors detected during execution are called \emph{exceptions} and are
+not unconditionally fatal: you will soon learn how to handle them in
+Python programs.  Most exceptions are not handled by programs,
+however, and result in error messages as shown here:
+
+\begin{verbatim}
+>>> 10 * (1/0)
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+ZeroDivisionError: integer division or modulo by zero
+>>> 4 + spam*3
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+NameError: name 'spam' is not defined
+>>> '2' + 2
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+TypeError: cannot concatenate 'str' and 'int' objects
+\end{verbatim}
+
+The last line of the error message indicates what happened.
+Exceptions come in different types, and the type is printed as part of
+the message: the types in the example are
+\exception{ZeroDivisionError}, \exception{NameError} and
+\exception{TypeError}.
+The string printed as the exception type is the name of the built-in
+exception that occurred.  This is true for all built-in
+exceptions, but need not be true for user-defined exceptions (although
+it is a useful convention).
+Standard exception names are built-in identifiers (not reserved
+keywords).
+
+The rest of the line provides detail based on the type of exception
+and what caused it.
+
+The preceding part of the error message shows the context where the
+exception happened, in the form of a stack traceback.
+In general it contains a stack traceback listing source lines; however,
+it will not display lines read from standard input.
+
+The \citetitle[../lib/module-exceptions.html]{Python Library
+Reference} lists the built-in exceptions and their meanings.
+
+
+\section{Handling Exceptions \label{handling}}
+
+It is possible to write programs that handle selected exceptions.
+Look at the following example, which asks the user for input until a
+valid integer has been entered, but allows the user to interrupt the
+program (using \kbd{Control-C} or whatever the operating system
+supports); note that a user-generated interruption is signalled by
+raising the \exception{KeyboardInterrupt} exception.
+
+\begin{verbatim}
+>>> while True:
+...     try:
+...         x = int(raw_input("Please enter a number: "))
+...         break
+...     except ValueError:
+...         print "Oops!  That was no valid number.  Try again..."
+...     
+\end{verbatim}
+
+The \keyword{try} statement works as follows.
+
+\begin{itemize}
+\item
+First, the \emph{try clause} (the statement(s) between the
+\keyword{try} and \keyword{except} keywords) is executed.
+
+\item
+If no exception occurs, the \emph{except\ clause} is skipped and
+execution of the \keyword{try} statement is finished.
+
+\item
+If an exception occurs during execution of the try clause, the rest of
+the clause is skipped.  Then if its type matches the exception named
+after the \keyword{except} keyword, the except clause is executed, and
+then execution continues after the \keyword{try} statement.
+
+\item
+If an exception occurs which does not match the exception named in the
+except clause, it is passed on to outer \keyword{try} statements; if
+no handler is found, it is an \emph{unhandled exception} and execution
+stops with a message as shown above.
+
+\end{itemize}
+
+A \keyword{try} statement may have more than one except clause, to
+specify handlers for different exceptions.  At most one handler will
+be executed.  Handlers only handle exceptions that occur in the
+corresponding try clause, not in other handlers of the same
+\keyword{try} statement.  An except clause may name multiple exceptions
+as a parenthesized tuple, for example:
+
+\begin{verbatim}
+... except (RuntimeError, TypeError, NameError):
+...     pass
+\end{verbatim}
+
+The last except clause may omit the exception name(s), to serve as a
+wildcard.  Use this with extreme caution, since it is easy to mask a
+real programming error in this way!  It can also be used to print an
+error message and then re-raise the exception (allowing a caller to
+handle the exception as well):
+
+\begin{verbatim}
+import sys
+
+try:
+    f = open('myfile.txt')
+    s = f.readline()
+    i = int(s.strip())
+except IOError, (errno, strerror):
+    print "I/O error(%s): %s" % (errno, strerror)
+except ValueError:
+    print "Could not convert data to an integer."
+except:
+    print "Unexpected error:", sys.exc_info()[0]
+    raise
+\end{verbatim}
+
+The \keyword{try} \ldots\ \keyword{except} statement has an optional
+\emph{else clause}, which, when present, must follow all except
+clauses.  It is useful for code that must be executed if the try
+clause does not raise an exception.  For example:
+
+\begin{verbatim}
+for arg in sys.argv[1:]:
+    try:
+        f = open(arg, 'r')
+    except IOError:
+        print 'cannot open', arg
+    else:
+        print arg, 'has', len(f.readlines()), 'lines'
+        f.close()
+\end{verbatim}
+
+The use of the \keyword{else} clause is better than adding additional
+code to the \keyword{try} clause because it avoids accidentally
+catching an exception that wasn't raised by the code being protected
+by the \keyword{try} \ldots\ \keyword{except} statement.
+
+
+When an exception occurs, it may have an associated value, also known as
+the exception's \emph{argument}.
+The presence and type of the argument depend on the exception type.
+
+The except clause may specify a variable after the exception name (or tuple).
+The variable is bound to an exception instance with the arguments stored
+in \code{instance.args}.  For convenience, the exception instance
+defines \method{__getitem__} and \method{__str__} so the arguments can
+be accessed or printed directly without having to reference \code{.args}.
+
+But use of \code{.args} is discouraged.  Instead, the preferred use is to pass
+a single argument to an exception (which can be a tuple if multiple arguments
+are needed) and have it bound to the \code{message} attribute.  One may also
+instantiate an exception first before raising it and add any attributes to it
+as desired.
+
+\begin{verbatim}
+>>> try:
+...    raise Exception('spam', 'eggs')
+... except Exception, inst:
+...    print type(inst)     # the exception instance
+...    print inst.args      # arguments stored in .args
+...    print inst           # __str__ allows args to printed directly
+...    x, y = inst          # __getitem__ allows args to be unpacked directly
+...    print 'x =', x
+...    print 'y =', y
+...
+<type 'instance'>
+('spam', 'eggs')
+('spam', 'eggs')
+x = spam
+y = eggs
+\end{verbatim}
+
+If an exception has an argument, it is printed as the last part
+(`detail') of the message for unhandled exceptions.
+
+Exception handlers don't just handle exceptions if they occur
+immediately in the try clause, but also if they occur inside functions
+that are called (even indirectly) in the try clause.
+For example:
+
+\begin{verbatim}
+>>> def this_fails():
+...     x = 1/0
+... 
+>>> try:
+...     this_fails()
+... except ZeroDivisionError, detail:
+...     print 'Handling run-time error:', detail
+... 
+Handling run-time error: integer division or modulo by zero
+\end{verbatim}
+
+
+\section{Raising Exceptions \label{raising}}
+
+The \keyword{raise} statement allows the programmer to force a
+specified exception to occur.
+For example:
+
+\begin{verbatim}
+>>> raise NameError, 'HiThere'
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+NameError: HiThere
+\end{verbatim}
+
+The first argument to \keyword{raise} names the exception to be
+raised.  The optional second argument specifies the exception's
+argument.  Alternatively, the above could be written as
+\code{raise NameError('HiThere')}.  Either form works fine, but there
+seems to be a growing stylistic preference for the latter.
+
+If you need to determine whether an exception was raised but don't
+intend to handle it, a simpler form of the \keyword{raise} statement
+allows you to re-raise the exception:
+
+\begin{verbatim}
+>>> try:
+...     raise NameError, 'HiThere'
+... except NameError:
+...     print 'An exception flew by!'
+...     raise
+...
+An exception flew by!
+Traceback (most recent call last):
+  File "<stdin>", line 2, in ?
+NameError: HiThere
+\end{verbatim}
+
+
+\section{User-defined Exceptions \label{userExceptions}}
+
+Programs may name their own exceptions by creating a new exception
+class.  Exceptions should typically be derived from the
+\exception{Exception} class, either directly or indirectly.  For
+example:
+
+\begin{verbatim}
+>>> class MyError(Exception):
+...     def __init__(self, value):
+...         self.value = value
+...     def __str__(self):
+...         return repr(self.value)
+... 
+>>> try:
+...     raise MyError(2*2)
+... except MyError, e:
+...     print 'My exception occurred, value:', e.value
+... 
+My exception occurred, value: 4
+>>> raise MyError, 'oops!'
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+__main__.MyError: 'oops!'
+\end{verbatim}
+
+In this example, the default \method{__init__} of \class{Exception}
+has been overridden.  The new behavior simply creates the \var{value}
+attribute.  This replaces the default behavior of creating the
+\var{args} attribute.
+
+Exception classes can be defined which do anything any other class can
+do, but are usually kept simple, often only offering a number of
+attributes that allow information about the error to be extracted by
+handlers for the exception.  When creating a module that can raise
+several distinct errors, a common practice is to create a base class
+for exceptions defined by that module, and subclass that to create
+specific exception classes for different error conditions:
+
+\begin{verbatim}
+class Error(Exception):
+    """Base class for exceptions in this module."""
+    pass
+
+class InputError(Error):
+    """Exception raised for errors in the input.
+
+    Attributes:
+        expression -- input expression in which the error occurred
+        message -- explanation of the error
+    """
+
+    def __init__(self, expression, message):
+        self.expression = expression
+        self.message = message
+
+class TransitionError(Error):
+    """Raised when an operation attempts a state transition that's not
+    allowed.
+
+    Attributes:
+        previous -- state at beginning of transition
+        next -- attempted new state
+        message -- explanation of why the specific transition is not allowed
+    """
+
+    def __init__(self, previous, next, message):
+        self.previous = previous
+        self.next = next
+        self.message = message
+\end{verbatim}
+
+Most exceptions are defined with names that end in ``Error,'' similar
+to the naming of the standard exceptions.
+
+Many standard modules define their own exceptions to report errors
+that may occur in functions they define.  More information on classes
+is presented in chapter \ref{classes}, ``Classes.''
+
+
+\section{Defining Clean-up Actions \label{cleanup}}
+
+The \keyword{try} statement has another optional clause which is
+intended to define clean-up actions that must be executed under all
+circumstances.  For example:
+
+\begin{verbatim}
+>>> try:
+...     raise KeyboardInterrupt
+... finally:
+...     print 'Goodbye, world!'
+... 
+Goodbye, world!
+Traceback (most recent call last):
+  File "<stdin>", line 2, in ?
+KeyboardInterrupt
+\end{verbatim}
+
+A \emph{finally clause} is always executed before leaving the
+\keyword{try} statement, whether an exception has occurred or not.
+When an exception has occurred in the \keyword{try} clause and has not
+been handled by an \keyword{except} clause (or it has occurred in a
+\keyword{except} or \keyword{else} clause), it is re-raised after the
+\keyword{finally} clause has been executed.  The \keyword{finally} clause
+is also executed ``on the way out'' when any other clause of the
+\keyword{try} statement is left via a \keyword{break}, \keyword{continue}
+or \keyword{return} statement.  A more complicated example:
+
+\begin{verbatim}
+>>> def divide(x, y):
+...     try:
+...         result = x / y
+...     except ZeroDivisionError:
+...         print "division by zero!"
+...     else:
+...         print "result is", result
+...     finally:
+...         print "executing finally clause"
+...
+>>> divide(2, 1)
+result is 2
+executing finally clause
+>>> divide(2, 0)
+division by zero!
+executing finally clause
+>>> divide("2", "1")
+executing finally clause
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+  File "<stdin>", line 3, in divide
+TypeError: unsupported operand type(s) for /: 'str' and 'str'
+\end{verbatim}
+
+As you can see, the \keyword{finally} clause is executed in any
+event.  The \exception{TypeError} raised by dividing two strings
+is not handled by the \keyword{except} clause and therefore
+re-raised after the \keyword{finally} clauses has been executed.
+
+In real world applications, the \keyword{finally} clause is useful
+for releasing external resources (such as files or network connections),
+regardless of whether the use of the resource was successful.
+
+
+\section{Predefined Clean-up Actions \label{cleanup-with}}
+
+Some objects define standard clean-up actions to be undertaken when
+the object is no longer needed, regardless of whether or not the
+operation using the object succeeded or failed.
+Look at the following example, which tries to open a file and print
+its contents to the screen.
+
+\begin{verbatim}
+for line in open("myfile.txt"):
+    print line
+\end{verbatim}
+
+The problem with this code is that it leaves the file open for an
+indeterminate amount of time after the code has finished executing.
+This is not an issue in simple scripts, but can be a problem for
+larger applications. The \keyword{with} statement allows
+objects like files to be used in a way that ensures they are
+always cleaned up promptly and correctly.
+
+\begin{verbatim}
+with open("myfile.txt") as f:
+    for line in f:
+        print line
+\end{verbatim}
+
+After the statement is executed, the file \var{f} is always closed,
+even if a problem was encountered while processing the lines. Other
+objects which provide predefined clean-up actions will indicate
+this in their documentation.
+
+
+\chapter{Classes \label{classes}}
+
+Python's class mechanism adds classes to the language with a minimum
+of new syntax and semantics.  It is a mixture of the class mechanisms
+found in \Cpp{} and Modula-3.  As is true for modules, classes in Python
+do not put an absolute barrier between definition and user, but rather
+rely on the politeness of the user not to ``break into the
+definition.''  The most important features of classes are retained
+with full power, however: the class inheritance mechanism allows
+multiple base classes, a derived class can override any methods of its
+base class or classes, and a method can call the method of a base class with the
+same name.  Objects can contain an arbitrary amount of private data.
+
+In \Cpp{} terminology, all class members (including the data members) are
+\emph{public}, and all member functions are \emph{virtual}.  There are
+no special constructors or destructors.  As in Modula-3, there are no
+shorthands for referencing the object's members from its methods: the
+method function is declared with an explicit first argument
+representing the object, which is provided implicitly by the call.  As
+in Smalltalk, classes themselves are objects, albeit in the wider
+sense of the word: in Python, all data types are objects.  This
+provides semantics for importing and renaming.  Unlike 
+\Cpp{} and Modula-3, built-in types can be used as base classes for
+extension by the user.  Also, like in \Cpp{} but unlike in Modula-3, most
+built-in operators with special syntax (arithmetic operators,
+subscripting etc.) can be redefined for class instances.
+
+\section{A Word About Terminology \label{terminology}}
+
+Lacking universally accepted terminology to talk about classes, I will
+make occasional use of Smalltalk and \Cpp{} terms.  (I would use Modula-3
+terms, since its object-oriented semantics are closer to those of
+Python than \Cpp, but I expect that few readers have heard of it.)
+
+Objects have individuality, and multiple names (in multiple scopes)
+can be bound to the same object.  This is known as aliasing in other
+languages.  This is usually not appreciated on a first glance at
+Python, and can be safely ignored when dealing with immutable basic
+types (numbers, strings, tuples).  However, aliasing has an
+(intended!) effect on the semantics of Python code involving mutable
+objects such as lists, dictionaries, and most types representing
+entities outside the program (files, windows, etc.).  This is usually
+used to the benefit of the program, since aliases behave like pointers
+in some respects.  For example, passing an object is cheap since only
+a pointer is passed by the implementation; and if a function modifies
+an object passed as an argument, the caller will see the change --- this
+eliminates the need for two different argument passing mechanisms as in
+Pascal.
+
+
+\section{Python Scopes and Name Spaces \label{scopes}}
+
+Before introducing classes, I first have to tell you something about
+Python's scope rules.  Class definitions play some neat tricks with
+namespaces, and you need to know how scopes and namespaces work to
+fully understand what's going on.  Incidentally, knowledge about this
+subject is useful for any advanced Python programmer.
+
+Let's begin with some definitions.
+
+A \emph{namespace} is a mapping from names to objects.  Most
+namespaces are currently implemented as Python dictionaries, but
+that's normally not noticeable in any way (except for performance),
+and it may change in the future.  Examples of namespaces are: the set
+of built-in names (functions such as \function{abs()}, and built-in
+exception names); the global names in a module; and the local names in
+a function invocation.  In a sense the set of attributes of an object
+also form a namespace.  The important thing to know about namespaces
+is that there is absolutely no relation between names in different
+namespaces; for instance, two different modules may both define a
+function ``maximize'' without confusion --- users of the modules must
+prefix it with the module name.
+
+By the way, I use the word \emph{attribute} for any name following a
+dot --- for example, in the expression \code{z.real}, \code{real} is
+an attribute of the object \code{z}.  Strictly speaking, references to
+names in modules are attribute references: in the expression
+\code{modname.funcname}, \code{modname} is a module object and
+\code{funcname} is an attribute of it.  In this case there happens to
+be a straightforward mapping between the module's attributes and the
+global names defined in the module: they share the same namespace!
+\footnote{
+        Except for one thing.  Module objects have a secret read-only
+        attribute called \member{__dict__} which returns the dictionary
+        used to implement the module's namespace; the name
+        \member{__dict__} is an attribute but not a global name.
+        Obviously, using this violates the abstraction of namespace
+        implementation, and should be restricted to things like
+        post-mortem debuggers.
+}
+
+Attributes may be read-only or writable.  In the latter case,
+assignment to attributes is possible.  Module attributes are writable:
+you can write \samp{modname.the_answer = 42}.  Writable attributes may
+also be deleted with the \keyword{del} statement.  For example,
+\samp{del modname.the_answer} will remove the attribute
+\member{the_answer} from the object named by \code{modname}.
+
+Name spaces are created at different moments and have different
+lifetimes.  The namespace containing the built-in names is created
+when the Python interpreter starts up, and is never deleted.  The
+global namespace for a module is created when the module definition
+is read in; normally, module namespaces also last until the
+interpreter quits.  The statements executed by the top-level
+invocation of the interpreter, either read from a script file or
+interactively, are considered part of a module called
+\module{__main__}, so they have their own global namespace.  (The
+built-in names actually also live in a module; this is called
+\module{__builtin__}.)
+
+The local namespace for a function is created when the function is
+called, and deleted when the function returns or raises an exception
+that is not handled within the function.  (Actually, forgetting would
+be a better way to describe what actually happens.)  Of course,
+recursive invocations each have their own local namespace.
+
+A \emph{scope} is a textual region of a Python program where a
+namespace is directly accessible.  ``Directly accessible'' here means
+that an unqualified reference to a name attempts to find the name in
+the namespace.
+
+Although scopes are determined statically, they are used dynamically.
+At any time during execution, there are at least three nested scopes whose
+namespaces are directly accessible: the innermost scope, which is searched
+first, contains the local names; the namespaces of any enclosing
+functions, which are searched starting with the nearest enclosing scope;
+the middle scope, searched next, contains the current module's global names;
+and the outermost scope (searched last) is the namespace containing built-in
+names.
+
+If a name is declared global, then all references and assignments go
+directly to the middle scope containing the module's global names.
+Otherwise, all variables found outside of the innermost scope are read-only
+(an attempt to write to such a variable will simply create a \emph{new}
+local variable in the innermost scope, leaving the identically named
+outer variable unchanged).
+
+Usually, the local scope references the local names of the (textually)
+current function.  Outside functions, the local scope references
+the same namespace as the global scope: the module's namespace.
+Class definitions place yet another namespace in the local scope.
+
+It is important to realize that scopes are determined textually: the
+global scope of a function defined in a module is that module's
+namespace, no matter from where or by what alias the function is
+called.  On the other hand, the actual search for names is done
+dynamically, at run time --- however, the language definition is
+evolving towards static name resolution, at ``compile'' time, so don't
+rely on dynamic name resolution!  (In fact, local variables are
+already determined statically.)
+
+A special quirk of Python is that assignments always go into the
+innermost scope.  Assignments do not copy data --- they just
+bind names to objects.  The same is true for deletions: the statement
+\samp{del x} removes the binding of \code{x} from the namespace
+referenced by the local scope.  In fact, all operations that introduce
+new names use the local scope: in particular, import statements and
+function definitions bind the module or function name in the local
+scope.  (The \keyword{global} statement can be used to indicate that
+particular variables live in the global scope.)
+
+
+\section{A First Look at Classes \label{firstClasses}}
+
+Classes introduce a little bit of new syntax, three new object types,
+and some new semantics.
+
+
+\subsection{Class Definition Syntax \label{classDefinition}}
+
+The simplest form of class definition looks like this:
+
+\begin{verbatim}
+class ClassName:
+    <statement-1>
+    .
+    .
+    .
+    <statement-N>
+\end{verbatim}
+
+Class definitions, like function definitions
+(\keyword{def} statements) must be executed before they have any
+effect.  (You could conceivably place a class definition in a branch
+of an \keyword{if} statement, or inside a function.)
+
+In practice, the statements inside a class definition will usually be
+function definitions, but other statements are allowed, and sometimes
+useful --- we'll come back to this later.  The function definitions
+inside a class normally have a peculiar form of argument list,
+dictated by the calling conventions for methods --- again, this is
+explained later.
+
+When a class definition is entered, a new namespace is created, and
+used as the local scope --- thus, all assignments to local variables
+go into this new namespace.  In particular, function definitions bind
+the name of the new function here.
+
+When a class definition is left normally (via the end), a \emph{class
+object} is created.  This is basically a wrapper around the contents
+of the namespace created by the class definition; we'll learn more
+about class objects in the next section.  The original local scope
+(the one in effect just before the class definition was entered) is
+reinstated, and the class object is bound here to the class name given
+in the class definition header (\class{ClassName} in the example).
+
+
+\subsection{Class Objects \label{classObjects}}
+
+Class objects support two kinds of operations: attribute references
+and instantiation.
+
+\emph{Attribute references} use the standard syntax used for all
+attribute references in Python: \code{obj.name}.  Valid attribute
+names are all the names that were in the class's namespace when the
+class object was created.  So, if the class definition looked like
+this:
+
+\begin{verbatim}
+class MyClass:
+    "A simple example class"
+    i = 12345
+    def f(self):
+        return 'hello world'
+\end{verbatim}
+
+then \code{MyClass.i} and \code{MyClass.f} are valid attribute
+references, returning an integer and a function object, respectively.
+Class attributes can also be assigned to, so you can change the value
+of \code{MyClass.i} by assignment.  \member{__doc__} is also a valid
+attribute, returning the docstring belonging to the class: \code{"A
+simple example class"}. 
+
+Class \emph{instantiation} uses function notation.  Just pretend that
+the class object is a parameterless function that returns a new
+instance of the class.  For example (assuming the above class):
+
+\begin{verbatim}
+x = MyClass()
+\end{verbatim}
+
+creates a new \emph{instance} of the class and assigns this object to
+the local variable \code{x}.
+
+The instantiation operation (``calling'' a class object) creates an
+empty object.  Many classes like to create objects with instances
+customized to a specific initial state.
+Therefore a class may define a special method named
+\method{__init__()}, like this:
+
+\begin{verbatim}
+    def __init__(self):
+        self.data = []
+\end{verbatim}
+
+When a class defines an \method{__init__()} method, class
+instantiation automatically invokes \method{__init__()} for the
+newly-created class instance.  So in this example, a new, initialized
+instance can be obtained by:
+
+\begin{verbatim}
+x = MyClass()
+\end{verbatim}
+
+Of course, the \method{__init__()} method may have arguments for
+greater flexibility.  In that case, arguments given to the class
+instantiation operator are passed on to \method{__init__()}.  For
+example,
+
+\begin{verbatim}
+>>> class Complex:
+...     def __init__(self, realpart, imagpart):
+...         self.r = realpart
+...         self.i = imagpart
+... 
+>>> x = Complex(3.0, -4.5)
+>>> x.r, x.i
+(3.0, -4.5)
+\end{verbatim}
+
+
+\subsection{Instance Objects \label{instanceObjects}}
+
+Now what can we do with instance objects?  The only operations
+understood by instance objects are attribute references.  There are
+two kinds of valid attribute names, data attributes and methods.
+
+\emph{data attributes} correspond to
+``instance variables'' in Smalltalk, and to ``data members'' in
+\Cpp.  Data attributes need not be declared; like local variables,
+they spring into existence when they are first assigned to.  For
+example, if \code{x} is the instance of \class{MyClass} created above,
+the following piece of code will print the value \code{16}, without
+leaving a trace:
+
+\begin{verbatim}
+x.counter = 1
+while x.counter < 10:
+    x.counter = x.counter * 2
+print x.counter
+del x.counter
+\end{verbatim}
+
+The other kind of instance attribute reference is a \emph{method}.
+A method is a function that ``belongs to'' an
+object.  (In Python, the term method is not unique to class instances:
+other object types can have methods as well.  For example, list objects have
+methods called append, insert, remove, sort, and so on.  However,
+in the following discussion, we'll use the term method exclusively to mean
+methods of class instance objects, unless explicitly stated otherwise.)
+
+Valid method names of an instance object depend on its class.  By
+definition, all attributes of a class that are function 
+objects define corresponding methods of its instances.  So in our
+example, \code{x.f} is a valid method reference, since
+\code{MyClass.f} is a function, but \code{x.i} is not, since
+\code{MyClass.i} is not.  But \code{x.f} is not the same thing as
+\code{MyClass.f} --- it is a \obindex{method}\emph{method object}, not
+a function object.
+
+
+\subsection{Method Objects \label{methodObjects}}
+
+Usually, a method is called right after it is bound:
+
+\begin{verbatim}
+x.f()
+\end{verbatim}
+
+In the \class{MyClass} example, this will return the string \code{'hello world'}.
+However, it is not necessary to call a method right away:
+\code{x.f} is a method object, and can be stored away and called at a
+later time.  For example:
+
+\begin{verbatim}
+xf = x.f
+while True:
+    print xf()
+\end{verbatim}
+
+will continue to print \samp{hello world} until the end of time.
+
+What exactly happens when a method is called?  You may have noticed
+that \code{x.f()} was called without an argument above, even though
+the function definition for \method{f} specified an argument.  What
+happened to the argument?  Surely Python raises an exception when a
+function that requires an argument is called without any --- even if
+the argument isn't actually used...
+
+Actually, you may have guessed the answer: the special thing about
+methods is that the object is passed as the first argument of the
+function.  In our example, the call \code{x.f()} is exactly equivalent
+to \code{MyClass.f(x)}.  In general, calling a method with a list of
+\var{n} arguments is equivalent to calling the corresponding function
+with an argument list that is created by inserting the method's object
+before the first argument.
+
+If you still don't understand how methods work, a look at the
+implementation can perhaps clarify matters.  When an instance
+attribute is referenced that isn't a data attribute, its class is
+searched.  If the name denotes a valid class attribute that is a
+function object, a method object is created by packing (pointers to)
+the instance object and the function object just found together in an
+abstract object: this is the method object.  When the method object is
+called with an argument list, it is unpacked again, a new argument
+list is constructed from the instance object and the original argument
+list, and the function object is called with this new argument list.
+
+
+\section{Random Remarks \label{remarks}}
+
+% [These should perhaps be placed more carefully...]
+
+
+Data attributes override method attributes with the same name; to
+avoid accidental name conflicts, which may cause hard-to-find bugs in
+large programs, it is wise to use some kind of convention that
+minimizes the chance of conflicts.  Possible conventions include
+capitalizing method names, prefixing data attribute names with a small
+unique string (perhaps just an underscore), or using verbs for methods
+and nouns for data attributes.
+
+
+Data attributes may be referenced by methods as well as by ordinary
+users (``clients'') of an object.  In other words, classes are not
+usable to implement pure abstract data types.  In fact, nothing in
+Python makes it possible to enforce data hiding --- it is all based
+upon convention.  (On the other hand, the Python implementation,
+written in C, can completely hide implementation details and control
+access to an object if necessary; this can be used by extensions to
+Python written in C.)
+
+
+Clients should use data attributes with care --- clients may mess up
+invariants maintained by the methods by stamping on their data
+attributes.  Note that clients may add data attributes of their own to
+an instance object without affecting the validity of the methods, as
+long as name conflicts are avoided --- again, a naming convention can
+save a lot of headaches here.
+
+
+There is no shorthand for referencing data attributes (or other
+methods!) from within methods.  I find that this actually increases
+the readability of methods: there is no chance of confusing local
+variables and instance variables when glancing through a method.
+
+
+Often, the first argument of a method is called
+\code{self}.  This is nothing more than a convention: the name
+\code{self} has absolutely no special meaning to Python.  (Note,
+however, that by not following the convention your code may be less
+readable to other Python programmers, and it is also conceivable that
+a \emph{class browser} program might be written that relies upon such a
+convention.)
+
+
+Any function object that is a class attribute defines a method for
+instances of that class.  It is not necessary that the function
+definition is textually enclosed in the class definition: assigning a
+function object to a local variable in the class is also ok.  For
+example:
+
+\begin{verbatim}
+# Function defined outside the class
+def f1(self, x, y):
+    return min(x, x+y)
+
+class C:
+    f = f1
+    def g(self):
+        return 'hello world'
+    h = g
+\end{verbatim}
+
+Now \code{f}, \code{g} and \code{h} are all attributes of class
+\class{C} that refer to function objects, and consequently they are all
+methods of instances of \class{C} --- \code{h} being exactly equivalent
+to \code{g}.  Note that this practice usually only serves to confuse
+the reader of a program.
+
+
+Methods may call other methods by using method attributes of the
+\code{self} argument:
+
+\begin{verbatim}
+class Bag:
+    def __init__(self):
+        self.data = []
+    def add(self, x):
+        self.data.append(x)
+    def addtwice(self, x):
+        self.add(x)
+        self.add(x)
+\end{verbatim}
+
+Methods may reference global names in the same way as ordinary
+functions.  The global scope associated with a method is the module
+containing the class definition.  (The class itself is never used as a
+global scope!)  While one rarely encounters a good reason for using
+global data in a method, there are many legitimate uses of the global
+scope: for one thing, functions and modules imported into the global
+scope can be used by methods, as well as functions and classes defined
+in it.  Usually, the class containing the method is itself defined in
+this global scope, and in the next section we'll find some good
+reasons why a method would want to reference its own class!
+
+
+\section{Inheritance \label{inheritance}}
+
+Of course, a language feature would not be worthy of the name ``class''
+without supporting inheritance.  The syntax for a derived class
+definition looks like this:
+
+\begin{verbatim}
+class DerivedClassName(BaseClassName):
+    <statement-1>
+    .
+    .
+    .
+    <statement-N>
+\end{verbatim}
+
+The name \class{BaseClassName} must be defined in a scope containing
+the derived class definition.  In place of a base class name, other
+arbitrary expressions are also allowed.  This can be useful, for
+example, when the base class is defined in another module:
+
+\begin{verbatim}
+class DerivedClassName(modname.BaseClassName):
+\end{verbatim}
+
+Execution of a derived class definition proceeds the same as for a
+base class.  When the class object is constructed, the base class is
+remembered.  This is used for resolving attribute references: if a
+requested attribute is not found in the class, the search proceeds to look in the
+base class.  This rule is applied recursively if the base class itself
+is derived from some other class.
+
+There's nothing special about instantiation of derived classes:
+\code{DerivedClassName()} creates a new instance of the class.  Method
+references are resolved as follows: the corresponding class attribute
+is searched, descending down the chain of base classes if necessary,
+and the method reference is valid if this yields a function object.
+
+Derived classes may override methods of their base classes.  Because
+methods have no special privileges when calling other methods of the
+same object, a method of a base class that calls another method
+defined in the same base class may end up calling a method of
+a derived class that overrides it.  (For \Cpp{} programmers: all methods
+in Python are effectively \keyword{virtual}.)
+
+An overriding method in a derived class may in fact want to extend
+rather than simply replace the base class method of the same name.
+There is a simple way to call the base class method directly: just
+call \samp{BaseClassName.methodname(self, arguments)}.  This is
+occasionally useful to clients as well.  (Note that this only works if
+the base class is defined or imported directly in the global scope.)
+
+
+\subsection{Multiple Inheritance \label{multiple}}
+
+Python supports a limited form of multiple inheritance as well.  A
+class definition with multiple base classes looks like this:
+
+\begin{verbatim}
+class DerivedClassName(Base1, Base2, Base3):
+    <statement-1>
+    .
+    .
+    .
+    <statement-N>
+\end{verbatim}
+
+For old-style classes, the only rule is depth-first,
+left-to-right.  Thus, if an attribute is not found in
+\class{DerivedClassName}, it is searched in \class{Base1}, then
+(recursively) in the base classes of \class{Base1}, and only if it is
+not found there, it is searched in \class{Base2}, and so on.
+
+(To some people breadth first --- searching \class{Base2} and
+\class{Base3} before the base classes of \class{Base1} --- looks more
+natural.  However, this would require you to know whether a particular
+attribute of \class{Base1} is actually defined in \class{Base1} or in
+one of its base classes before you can figure out the consequences of
+a name conflict with an attribute of \class{Base2}.  The depth-first
+rule makes no differences between direct and inherited attributes of
+\class{Base1}.)
+
+For new-style classes, the method resolution order changes dynamically
+to support cooperative calls to \function{super()}.  This approach
+is known in some other multiple-inheritance languages as call-next-method
+and is more powerful than the super call found in single-inheritance languages.
+
+With new-style classes, dynamic ordering is necessary because all 
+cases of multiple inheritance exhibit one or more diamond relationships
+(where one at least one of the parent classes can be accessed through
+multiple paths from the bottommost class).  For example, all new-style
+classes inherit from \class{object}, so any case of multiple inheritance
+provides more than one path to reach \class{object}.  To keep the
+base classes from being accessed more than once, the dynamic algorithm
+linearizes the search order in a way that preserves the left-to-right
+ordering specified in each class, that calls each parent only once, and
+that is monotonic (meaning that a class can be subclassed without affecting
+the precedence order of its parents).  Taken together, these properties
+make it possible to design reliable and extensible classes with
+multiple inheritance.  For more detail, see 
+\url{http://www.python.org/download/releases/2.3/mro/}.
+
+
+\section{Private Variables \label{private}}
+
+There is limited support for class-private
+identifiers.  Any identifier of the form \code{__spam} (at least two
+leading underscores, at most one trailing underscore) is textually
+replaced with \code{_classname__spam}, where \code{classname} is the
+current class name with leading underscore(s) stripped.  This mangling
+is done without regard to the syntactic position of the identifier, so
+it can be used to define class-private instance and class variables,
+methods, variables stored in globals, and even variables stored in instances.
+private to this class on instances of \emph{other} classes.  Truncation
+may occur when the mangled name would be longer than 255 characters.
+Outside classes, or when the class name consists of only underscores,
+no mangling occurs.
+
+Name mangling is intended to give classes an easy way to define
+``private'' instance variables and methods, without having to worry
+about instance variables defined by derived classes, or mucking with
+instance variables by code outside the class.  Note that the mangling
+rules are designed mostly to avoid accidents; it still is possible for
+a determined soul to access or modify a variable that is considered
+private.  This can even be useful in special circumstances, such as in
+the debugger, and that's one reason why this loophole is not closed.
+(Buglet: derivation of a class with the same name as the base class
+makes use of private variables of the base class possible.)
+
+Notice that code passed to \code{exec}, \code{eval()} or
+\code{execfile()} does not consider the classname of the invoking 
+class to be the current class; this is similar to the effect of the 
+\code{global} statement, the effect of which is likewise restricted to 
+code that is byte-compiled together.  The same restriction applies to
+\code{getattr()}, \code{setattr()} and \code{delattr()}, as well as
+when referencing \code{__dict__} directly.
+
+
+\section{Odds and Ends \label{odds}}
+
+Sometimes it is useful to have a data type similar to the Pascal
+``record'' or C ``struct'', bundling together a few named data
+items.  An empty class definition will do nicely:
+
+\begin{verbatim}
+class Employee:
+    pass
+
+john = Employee() # Create an empty employee record
+
+# Fill the fields of the record
+john.name = 'John Doe'
+john.dept = 'computer lab'
+john.salary = 1000
+\end{verbatim}
+
+A piece of Python code that expects a particular abstract data type
+can often be passed a class that emulates the methods of that data
+type instead.  For instance, if you have a function that formats some
+data from a file object, you can define a class with methods
+\method{read()} and \method{readline()} that get the data from a string
+buffer instead, and pass it as an argument.%  (Unfortunately, this
+%technique has its limitations: a class can't define operations that
+%are accessed by special syntax such as sequence subscripting or
+%arithmetic operators, and assigning such a ``pseudo-file'' to
+%\code{sys.stdin} will not cause the interpreter to read further input
+%from it.)
+
+
+Instance method objects have attributes, too: \code{m.im_self} is the
+instance object with the method \method{m}, and \code{m.im_func} is the
+function object corresponding to the method.
+
+
+\section{Exceptions Are Classes Too\label{exceptionClasses}}
+
+User-defined exceptions are identified by classes as well.  Using this
+mechanism it is possible to create extensible hierarchies of exceptions.
+
+There are two new valid (semantic) forms for the raise statement:
+
+\begin{verbatim}
+raise Class, instance
+
+raise instance
+\end{verbatim}
+
+In the first form, \code{instance} must be an instance of
+\class{Class} or of a class derived from it.  The second form is a
+shorthand for:
+
+\begin{verbatim}
+raise instance.__class__, instance
+\end{verbatim}
+
+A class in an except clause is compatible with an exception if it is the same
+class or a base class thereof (but not the other way around --- an
+except clause listing a derived class is not compatible with a base
+class).  For example, the following code will print B, C, D in that
+order:
+
+\begin{verbatim}
+class B:
+    pass
+class C(B):
+    pass
+class D(C):
+    pass
+
+for c in [B, C, D]:
+    try:
+        raise c()
+    except D:
+        print "D"
+    except C:
+        print "C"
+    except B:
+        print "B"
+\end{verbatim}
+
+Note that if the except clauses were reversed (with
+\samp{except B} first), it would have printed B, B, B --- the first
+matching except clause is triggered.
+
+When an error message is printed for an unhandled exception, the
+exception's class name is printed, then a colon and a space, and
+finally the instance converted to a string using the built-in function
+\function{str()}.
+
+
+\section{Iterators\label{iterators}}
+
+By now you have probably noticed that most container objects can be looped
+over using a \keyword{for} statement:
+
+\begin{verbatim}
+for element in [1, 2, 3]:
+    print element
+for element in (1, 2, 3):
+    print element
+for key in {'one':1, 'two':2}:
+    print key
+for char in "123":
+    print char
+for line in open("myfile.txt"):
+    print line
+\end{verbatim}
+
+This style of access is clear, concise, and convenient.  The use of iterators
+pervades and unifies Python.  Behind the scenes, the \keyword{for}
+statement calls \function{iter()} on the container object.  The
+function returns an iterator object that defines the method
+\method{next()} which accesses elements in the container one at a
+time.  When there are no more elements, \method{next()} raises a
+\exception{StopIteration} exception which tells the \keyword{for} loop
+to terminate.  This example shows how it all works:
+
+\begin{verbatim}
+>>> s = 'abc'
+>>> it = iter(s)
+>>> it
+<iterator object at 0x00A1DB50>
+>>> it.next()
+'a'
+>>> it.next()
+'b'
+>>> it.next()
+'c'
+>>> it.next()
+
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+    it.next()
+StopIteration
+\end{verbatim}
+
+Having seen the mechanics behind the iterator protocol, it is easy to add
+iterator behavior to your classes.  Define a \method{__iter__()} method
+which returns an object with a \method{next()} method.  If the class defines
+\method{next()}, then \method{__iter__()} can just return \code{self}:
+
+\begin{verbatim}
+class Reverse:
+    "Iterator for looping over a sequence backwards"
+    def __init__(self, data):
+        self.data = data
+        self.index = len(data)
+    def __iter__(self):
+        return self
+    def next(self):
+        if self.index == 0:
+            raise StopIteration
+        self.index = self.index - 1
+        return self.data[self.index]
+
+>>> for char in Reverse('spam'):
+...     print char
+...
+m
+a
+p
+s
+\end{verbatim}
+
+
+\section{Generators\label{generators}}
+
+Generators are a simple and powerful tool for creating iterators.  They are
+written like regular functions but use the \keyword{yield} statement whenever
+they want to return data.  Each time \method{next()} is called, the
+generator resumes where it left-off (it remembers all the data values and
+which statement was last executed).  An example shows that generators can
+be trivially easy to create:
+
+\begin{verbatim}
+def reverse(data):
+    for index in range(len(data)-1, -1, -1):
+        yield data[index]
+	
+>>> for char in reverse('golf'):
+...     print char
+...
+f
+l
+o
+g	
+\end{verbatim}
+
+Anything that can be done with generators can also be done with class based
+iterators as described in the previous section.  What makes generators so
+compact is that the \method{__iter__()} and \method{next()} methods are
+created automatically.
+
+Another key feature is that the local variables and execution state
+are automatically saved between calls.  This made the function easier to write
+and much more clear than an approach using instance variables like
+\code{self.index} and \code{self.data}.
+
+In addition to automatic method creation and saving program state, when
+generators terminate, they automatically raise \exception{StopIteration}.
+In combination, these features make it easy to create iterators with no
+more effort than writing a regular function.
+
+\section{Generator Expressions\label{genexps}}
+
+Some simple generators can be coded succinctly as expressions using a syntax
+similar to list comprehensions but with parentheses instead of brackets.  These
+expressions are designed for situations where the generator is used right
+away by an enclosing function.  Generator expressions are more compact but
+less versatile than full generator definitions and tend to be more memory
+friendly than equivalent list comprehensions.
+
+Examples:
+
+\begin{verbatim}
+>>> sum(i*i for i in range(10))                 # sum of squares
+285
+
+>>> xvec = [10, 20, 30]
+>>> yvec = [7, 5, 3]
+>>> sum(x*y for x,y in zip(xvec, yvec))         # dot product
+260
+
+>>> from math import pi, sin
+>>> sine_table = dict((x, sin(x*pi/180)) for x in range(0, 91))
+
+>>> unique_words = set(word  for line in page  for word in line.split())
+
+>>> valedictorian = max((student.gpa, student.name) for student in graduates)
+
+>>> data = 'golf'
+>>> list(data[i] for i in range(len(data)-1,-1,-1))
+['f', 'l', 'o', 'g']
+
+\end{verbatim}
+
+
+
+\chapter{Brief Tour of the Standard Library \label{briefTour}}
+
+
+\section{Operating System Interface\label{os-interface}}
+
+The \ulink{\module{os}}{../lib/module-os.html}
+module provides dozens of functions for interacting with the
+operating system:
+
+\begin{verbatim}
+>>> import os
+>>> os.system('time 0:02')
+0
+>>> os.getcwd()      # Return the current working directory
+'C:\\Python24'
+>>> os.chdir('/server/accesslogs')
+\end{verbatim}
+
+Be sure to use the \samp{import os} style instead of
+\samp{from os import *}.  This will keep \function{os.open()} from
+shadowing the builtin \function{open()} function which operates much
+differently.
+
+\bifuncindex{help}
+The builtin \function{dir()} and \function{help()} functions are useful
+as interactive aids for working with large modules like \module{os}:
+
+\begin{verbatim}
+>>> import os
+>>> dir(os)
+<returns a list of all module functions>
+>>> help(os)
+<returns an extensive manual page created from the module's docstrings>
+\end{verbatim}
+
+For daily file and directory management tasks, the 
+\ulink{\module{shutil}}{../lib/module-shutil.html}
+module provides a higher level interface that is easier to use:
+
+\begin{verbatim}
+>>> import shutil
+>>> shutil.copyfile('data.db', 'archive.db')
+>>> shutil.move('/build/executables', 'installdir')
+\end{verbatim}
+
+
+\section{File Wildcards\label{file-wildcards}}
+
+The \ulink{\module{glob}}{../lib/module-glob.html}
+module provides a function for making file lists from directory
+wildcard searches:
+
+\begin{verbatim}
+>>> import glob
+>>> glob.glob('*.py')
+['primes.py', 'random.py', 'quote.py']
+\end{verbatim}
+
+
+\section{Command Line Arguments\label{command-line-arguments}}
+
+Common utility scripts often need to process command line arguments.
+These arguments are stored in the
+\ulink{\module{sys}}{../lib/module-sys.html}\ module's \var{argv}
+attribute as a list.  For instance the following output results from
+running \samp{python demo.py one two three} at the command line:
+
+\begin{verbatim}
+>>> import sys
+>>> print sys.argv
+['demo.py', 'one', 'two', 'three']
+\end{verbatim}
+
+The \ulink{\module{getopt}}{../lib/module-getopt.html}
+module processes \var{sys.argv} using the conventions of the \UNIX{}
+\function{getopt()} function.  More powerful and flexible command line
+processing is provided by the
+\ulink{\module{optparse}}{../lib/module-optparse.html} module.
+
+
+\section{Error Output Redirection and Program Termination\label{stderr}}
+
+The \ulink{\module{sys}}{../lib/module-sys.html}
+module also has attributes for \var{stdin}, \var{stdout}, and
+\var{stderr}.  The latter is useful for emitting warnings and error
+messages to make them visible even when \var{stdout} has been redirected:
+
+\begin{verbatim}
+>>> sys.stderr.write('Warning, log file not found starting a new one\n')
+Warning, log file not found starting a new one
+\end{verbatim}
+
+The most direct way to terminate a script is to use \samp{sys.exit()}.
+
+
+\section{String Pattern Matching\label{string-pattern-matching}}
+
+The \ulink{\module{re}}{../lib/module-re.html}
+module provides regular expression tools for advanced string processing.
+For complex matching and manipulation, regular expressions offer succinct,
+optimized solutions:
+
+\begin{verbatim}
+>>> import re
+>>> re.findall(r'\bf[a-z]*', 'which foot or hand fell fastest')
+['foot', 'fell', 'fastest']
+>>> re.sub(r'(\b[a-z]+) \1', r'\1', 'cat in the the hat')
+'cat in the hat'
+\end{verbatim}
+
+When only simple capabilities are needed, string methods are preferred
+because they are easier to read and debug:
+
+\begin{verbatim}
+>>> 'tea for too'.replace('too', 'two')
+'tea for two'
+\end{verbatim}
+
+\section{Mathematics\label{mathematics}}
+
+The \ulink{\module{math}}{../lib/module-math.html} module gives
+access to the underlying C library functions for floating point math:
+
+\begin{verbatim}
+>>> import math
+>>> math.cos(math.pi / 4.0)
+0.70710678118654757
+>>> math.log(1024, 2)
+10.0
+\end{verbatim}
+
+The \ulink{\module{random}}{../lib/module-random.html}
+module provides tools for making random selections:
+
+\begin{verbatim}
+>>> import random
+>>> random.choice(['apple', 'pear', 'banana'])
+'apple'
+>>> random.sample(xrange(100), 10)   # sampling without replacement
+[30, 83, 16, 4, 8, 81, 41, 50, 18, 33]
+>>> random.random()    # random float
+0.17970987693706186
+>>> random.randrange(6)    # random integer chosen from range(6)
+4   
+\end{verbatim}
+
+
+\section{Internet Access\label{internet-access}}
+
+There are a number of modules for accessing the internet and processing
+internet protocols. Two of the simplest are
+\ulink{\module{urllib2}}{../lib/module-urllib2.html}
+for retrieving data from urls and
+\ulink{\module{smtplib}}{../lib/module-smtplib.html} 
+for sending mail:
+
+\begin{verbatim}
+>>> import urllib2
+>>> for line in urllib2.urlopen('http://tycho.usno.navy.mil/cgi-bin/timer.pl'):
+...     if 'EST' in line or 'EDT' in line:  # look for Eastern Time
+...         print line
+    
+<BR>Nov. 25, 09:43:32 PM EST
+
+>>> import smtplib
+>>> server = smtplib.SMTP('localhost')
+>>> server.sendmail('soothsayer at example.org', 'jcaesar at example.org',
+"""To: jcaesar at example.org
+From: soothsayer at example.org
+
+Beware the Ides of March.
+""")
+>>> server.quit()
+\end{verbatim}
+
+
+\section{Dates and Times\label{dates-and-times}}
+
+The \ulink{\module{datetime}}{../lib/module-datetime.html} module
+supplies classes for manipulating dates and times in both simple
+and complex ways. While date and time arithmetic is supported, the
+focus of the implementation is on efficient member extraction for
+output formatting and manipulation.  The module also supports objects
+that are timezone aware.
+
+\begin{verbatim}
+# dates are easily constructed and formatted
+>>> from datetime import date
+>>> now = date.today()
+>>> now
+datetime.date(2003, 12, 2)
+>>> now.strftime("%m-%d-%y. %d %b %Y is a %A on the %d day of %B.")
+'12-02-03. 02 Dec 2003 is a Tuesday on the 02 day of December.'
+
+# dates support calendar arithmetic
+>>> birthday = date(1964, 7, 31)
+>>> age = now - birthday
+>>> age.days
+14368
+\end{verbatim}
+
+
+\section{Data Compression\label{data-compression}}
+
+Common data archiving and compression formats are directly supported
+by modules including:
+\ulink{\module{zlib}}{../lib/module-zlib.html},
+\ulink{\module{gzip}}{../lib/module-gzip.html},
+\ulink{\module{bz2}}{../lib/module-bz2.html},
+\ulink{\module{zipfile}}{../lib/module-zipfile.html}, and
+\ulink{\module{tarfile}}{../lib/module-tarfile.html}.
+
+\begin{verbatim}
+>>> import zlib
+>>> s = 'witch which has which witches wrist watch'
+>>> len(s)
+41
+>>> t = zlib.compress(s)
+>>> len(t)
+37
+>>> zlib.decompress(t)
+'witch which has which witches wrist watch'
+>>> zlib.crc32(s)
+226805979
+\end{verbatim}
+
+
+\section{Performance Measurement\label{performance-measurement}}
+
+Some Python users develop a deep interest in knowing the relative
+performance of different approaches to the same problem.
+Python provides a measurement tool that answers those questions
+immediately.
+
+For example, it may be tempting to use the tuple packing and unpacking
+feature instead of the traditional approach to swapping arguments.
+The \ulink{\module{timeit}}{../lib/module-timeit.html} module
+quickly demonstrates a modest performance advantage:
+
+\begin{verbatim}
+>>> from timeit import Timer
+>>> Timer('t=a; a=b; b=t', 'a=1; b=2').timeit()
+0.57535828626024577
+>>> Timer('a,b = b,a', 'a=1; b=2').timeit()
+0.54962537085770791
+\end{verbatim}
+
+In contrast to \module{timeit}'s fine level of granularity, the
+\ulink{\module{profile}}{../lib/module-profile.html} and \module{pstats}
+modules provide tools for identifying time critical sections in larger blocks
+of code.
+
+
+\section{Quality Control\label{quality-control}}
+
+One approach for developing high quality software is to write tests for
+each function as it is developed and to run those tests frequently during
+the development process.
+
+The \ulink{\module{doctest}}{../lib/module-doctest.html} module provides
+a tool for scanning a module and validating tests embedded in a program's
+docstrings.  Test construction is as simple as cutting-and-pasting a
+typical call along with its results into the docstring.  This improves
+the documentation by providing the user with an example and it allows the
+doctest module to make sure the code remains true to the documentation:
+
+\begin{verbatim}
+def average(values):
+    """Computes the arithmetic mean of a list of numbers.
+
+    >>> print average([20, 30, 70])
+    40.0
+    """
+    return sum(values, 0.0) / len(values)
+
+import doctest
+doctest.testmod()   # automatically validate the embedded tests
+\end{verbatim}
+
+The \ulink{\module{unittest}}{../lib/module-unittest.html} module is not
+as effortless as the \module{doctest} module, but it allows a more
+comprehensive set of tests to be maintained in a separate file:
+
+\begin{verbatim}
+import unittest
+
+class TestStatisticalFunctions(unittest.TestCase):
+
+    def test_average(self):
+        self.assertEqual(average([20, 30, 70]), 40.0)
+        self.assertEqual(round(average([1, 5, 7]), 1), 4.3)
+        self.assertRaises(ZeroDivisionError, average, [])
+        self.assertRaises(TypeError, average, 20, 30, 70)
+
+unittest.main() # Calling from the command line invokes all tests
+\end{verbatim}
+
+\section{Batteries Included\label{batteries-included}}
+
+Python has a ``batteries included'' philosophy.  This is best seen
+through the sophisticated and robust capabilities of its larger
+packages. For example:
+
+\begin{itemize}
+\item The \ulink{\module{xmlrpclib}}{../lib/module-xmlrpclib.html} and
+  \ulink{\module{SimpleXMLRPCServer}}{../lib/module-SimpleXMLRPCServer.html}
+  modules make implementing remote procedure calls into an almost trivial task.
+  Despite the modules names, no direct knowledge or handling of XML is needed.
+\item The \ulink{\module{email}}{../lib/module-email.html} package is a library
+  for managing email messages, including MIME and other RFC 2822-based message
+  documents. Unlike \module{smtplib} and \module{poplib} which actually send
+  and receive messages, the email package has a complete toolset for building
+  or decoding complex message structures (including attachments) and for
+  implementing internet encoding and header protocols.
+\item The \ulink{\module{xml.dom}}{../lib/module-xml.dom.html} and
+  \ulink{\module{xml.sax}}{../lib/module-xml.sax.html} packages provide robust
+  support for parsing this popular data interchange format. Likewise, the
+  \ulink{\module{csv}}{../lib/module-csv.html} module supports direct reads and
+  writes in a common database format. Together, these modules and packages
+  greatly simplify data interchange between python applications and other
+  tools.
+\item Internationalization is supported by a number of modules including
+  \ulink{\module{gettext}}{../lib/module-gettext.html},
+  \ulink{\module{locale}}{../lib/module-locale.html}, and the
+  \ulink{\module{codecs}}{../lib/module-codecs.html} package.
+\end{itemize}
+
+\chapter{Brief Tour of the Standard Library -- Part II\label{briefTourTwo}}
+
+This second tour covers more advanced modules that support professional
+programming needs.  These modules rarely occur in small scripts.
+
+
+\section{Output Formatting\label{output-formatting}}
+
+The \ulink{\module{repr}}{../lib/module-repr.html} module provides a
+version of \function{repr()} customized for abbreviated displays of large
+or deeply nested containers:
+
+\begin{verbatim}
+    >>> import repr   
+    >>> repr.repr(set('supercalifragilisticexpialidocious'))
+    "set(['a', 'c', 'd', 'e', 'f', 'g', ...])"
+\end{verbatim}
+
+The \ulink{\module{pprint}}{../lib/module-pprint.html} module offers
+more sophisticated control over printing both built-in and user defined
+objects in a way that is readable by the interpreter.  When the result
+is longer than one line, the ``pretty printer'' adds line breaks and
+indentation to more clearly reveal data structure:
+
+\begin{verbatim}
+    >>> import pprint
+    >>> t = [[[['black', 'cyan'], 'white', ['green', 'red']], [['magenta',
+    ...     'yellow'], 'blue']]]
+    ...
+    >>> pprint.pprint(t, width=30)
+    [[[['black', 'cyan'],
+       'white',
+       ['green', 'red']],
+      [['magenta', 'yellow'],
+       'blue']]]
+\end{verbatim}
+
+The \ulink{\module{textwrap}}{../lib/module-textwrap.html} module
+formats paragraphs of text to fit a given screen width:
+
+\begin{verbatim}
+    >>> import textwrap
+    >>> doc = """The wrap() method is just like fill() except that it returns
+    ... a list of strings instead of one big string with newlines to separate
+    ... the wrapped lines."""
+    ...
+    >>> print textwrap.fill(doc, width=40)
+    The wrap() method is just like fill()
+    except that it returns a list of strings
+    instead of one big string with newlines
+    to separate the wrapped lines.
+\end{verbatim}
+
+The \ulink{\module{locale}}{../lib/module-locale.html} module accesses
+a database of culture specific data formats.  The grouping attribute
+of locale's format function provides a direct way of formatting numbers
+with group separators:
+
+\begin{verbatim}
+    >>> import locale
+    >>> locale.setlocale(locale.LC_ALL, 'English_United States.1252')
+    'English_United States.1252'
+    >>> conv = locale.localeconv()          # get a mapping of conventions
+    >>> x = 1234567.8
+    >>> locale.format("%d", x, grouping=True)
+    '1,234,567'
+    >>> locale.format("%s%.*f", (conv['currency_symbol'],
+    ...	      conv['frac_digits'], x), grouping=True)
+    '$1,234,567.80'
+\end{verbatim}
+
+
+\section{Templating\label{templating}}
+
+The \ulink{\module{string}}{../lib/module-string.html} module includes a
+versatile \class{Template} class with a simplified syntax suitable for
+editing by end-users.  This allows users to customize their applications
+without having to alter the application.
+
+The format uses placeholder names formed by \samp{\$} with valid Python
+identifiers (alphanumeric characters and underscores).  Surrounding the
+placeholder with braces allows it to be followed by more alphanumeric letters
+with no intervening spaces.  Writing \samp{\$\$} creates a single escaped
+\samp{\$}:
+
+\begin{verbatim}
+>>> from string import Template
+>>> t = Template('${village}folk send $$10 to $cause.')
+>>> t.substitute(village='Nottingham', cause='the ditch fund')
+'Nottinghamfolk send $10 to the ditch fund.'
+\end{verbatim}
+
+The \method{substitute} method raises a \exception{KeyError} when a
+placeholder is not supplied in a dictionary or a keyword argument. For
+mail-merge style applications, user supplied data may be incomplete and the
+\method{safe_substitute} method may be more appropriate --- it will leave
+placeholders unchanged if data is missing:
+
+\begin{verbatim}
+>>> t = Template('Return the $item to $owner.')
+>>> d = dict(item='unladen swallow')
+>>> t.substitute(d)
+Traceback (most recent call last):
+  . . .
+KeyError: 'owner'
+>>> t.safe_substitute(d)
+'Return the unladen swallow to $owner.'
+\end{verbatim}
+
+Template subclasses can specify a custom delimiter.  For example, a batch
+renaming utility for a photo browser may elect to use percent signs for
+placeholders such as the current date, image sequence number, or file format:
+
+\begin{verbatim}
+>>> import time, os.path
+>>> photofiles = ['img_1074.jpg', 'img_1076.jpg', 'img_1077.jpg']
+>>> class BatchRename(Template):
+...     delimiter = '%'
+>>> fmt = raw_input('Enter rename style (%d-date %n-seqnum %f-format):  ')
+Enter rename style (%d-date %n-seqnum %f-format):  Ashley_%n%f
+
+>>> t = BatchRename(fmt)
+>>> date = time.strftime('%d%b%y')
+>>> for i, filename in enumerate(photofiles):
+...     base, ext = os.path.splitext(filename)
+...     newname = t.substitute(d=date, n=i, f=ext)
+...     print '%s --> %s' % (filename, newname)
+
+img_1074.jpg --> Ashley_0.jpg
+img_1076.jpg --> Ashley_1.jpg
+img_1077.jpg --> Ashley_2.jpg
+\end{verbatim}
+
+Another application for templating is separating program logic from the
+details of multiple output formats.  This makes it possible to substitute
+custom templates for XML files, plain text reports, and HTML web reports.
+
+
+\section{Working with Binary Data Record Layouts\label{binary-formats}}
+
+The \ulink{\module{struct}}{../lib/module-struct.html} module provides
+\function{pack()} and \function{unpack()} functions for working with
+variable length binary record formats.  The following example shows how
+to loop through header information in a ZIP file (with pack codes
+\code{"H"} and \code{"L"} representing two and four byte unsigned
+numbers respectively):
+
+\begin{verbatim}
+    import struct
+
+    data = open('myfile.zip', 'rb').read()
+    start = 0
+    for i in range(3):                      # show the first 3 file headers
+        start += 14
+        fields = struct.unpack('LLLHH', data[start:start+16])
+        crc32, comp_size, uncomp_size, filenamesize, extra_size = fields
+
+        start += 16
+        filename = data[start:start+filenamesize]
+        start += filenamesize
+        extra = data[start:start+extra_size]
+        print filename, hex(crc32), comp_size, uncomp_size
+
+        start += extra_size + comp_size     # skip to the next header
+\end{verbatim}
+
+
+\section{Multi-threading\label{multi-threading}}
+
+Threading is a technique for decoupling tasks which are not sequentially
+dependent.  Threads can be used to improve the responsiveness of
+applications that accept user input while other tasks run in the
+background.  A related use case is running I/O in parallel with
+computations in another thread.
+
+The following code shows how the high level
+\ulink{\module{threading}}{../lib/module-threading.html} module can run
+tasks in background while the main program continues to run:
+
+\begin{verbatim}
+    import threading, zipfile
+
+    class AsyncZip(threading.Thread):
+        def __init__(self, infile, outfile):
+            threading.Thread.__init__(self)        
+            self.infile = infile
+            self.outfile = outfile
+        def run(self):
+            f = zipfile.ZipFile(self.outfile, 'w', zipfile.ZIP_DEFLATED)
+            f.write(self.infile)
+            f.close()
+            print 'Finished background zip of: ', self.infile
+
+    background = AsyncZip('mydata.txt', 'myarchive.zip')
+    background.start()
+    print 'The main program continues to run in foreground.'
+    
+    background.join()    # Wait for the background task to finish
+    print 'Main program waited until background was done.'
+\end{verbatim}
+
+The principal challenge of multi-threaded applications is coordinating
+threads that share data or other resources.  To that end, the threading
+module provides a number of synchronization primitives including locks,
+events, condition variables, and semaphores.
+
+While those tools are powerful, minor design errors can result in
+problems that are difficult to reproduce.  So, the preferred approach
+to task coordination is to concentrate all access to a resource
+in a single thread and then use the
+\ulink{\module{Queue}}{../lib/module-Queue.html} module to feed that
+thread with requests from other threads.  Applications using
+\class{Queue} objects for inter-thread communication and coordination
+are easier to design, more readable, and more reliable.
+
+
+\section{Logging\label{logging}}
+
+The \ulink{\module{logging}}{../lib/module-logging.html} module offers
+a full featured and flexible logging system.  At its simplest, log
+messages are sent to a file or to \code{sys.stderr}:
+
+\begin{verbatim}
+    import logging
+    logging.debug('Debugging information')
+    logging.info('Informational message')
+    logging.warning('Warning:config file %s not found', 'server.conf')
+    logging.error('Error occurred')
+    logging.critical('Critical error -- shutting down')
+\end{verbatim}
+
+This produces the following output: 
+
+\begin{verbatim}
+    WARNING:root:Warning:config file server.conf not found
+    ERROR:root:Error occurred
+    CRITICAL:root:Critical error -- shutting down
+\end{verbatim}
+
+By default, informational and debugging messages are suppressed and the
+output is sent to standard error.  Other output options include routing
+messages through email, datagrams, sockets, or to an HTTP Server.  New
+filters can select different routing based on message priority:
+\constant{DEBUG}, \constant{INFO}, \constant{WARNING}, \constant{ERROR},
+and \constant{CRITICAL}.
+
+The logging system can be configured directly from Python or can be
+loaded from a user editable configuration file for customized logging
+without altering the application.
+
+
+\section{Weak References\label{weak-references}}
+
+Python does automatic memory management (reference counting for most
+objects and garbage collection to eliminate cycles).  The memory is
+freed shortly after the last reference to it has been eliminated.
+
+This approach works fine for most applications but occasionally there
+is a need to track objects only as long as they are being used by
+something else.  Unfortunately, just tracking them creates a reference
+that makes them permanent.  The
+\ulink{\module{weakref}}{../lib/module-weakref.html} module provides
+tools for tracking objects without creating a reference.  When the
+object is no longer needed, it is automatically removed from a weakref
+table and a callback is triggered for weakref objects.  Typical
+applications include caching objects that are expensive to create:
+
+\begin{verbatim}
+    >>> import weakref, gc
+    >>> class A:
+    ...     def __init__(self, value):
+    ...             self.value = value
+    ...     def __repr__(self):
+    ...             return str(self.value)
+    ...
+    >>> a = A(10)                   # create a reference
+    >>> d = weakref.WeakValueDictionary()
+    >>> d['primary'] = a            # does not create a reference
+    >>> d['primary']                # fetch the object if it is still alive
+    10
+    >>> del a                       # remove the one reference
+    >>> gc.collect()                # run garbage collection right away
+    0
+    >>> d['primary']                # entry was automatically removed
+    Traceback (most recent call last):
+      File "<pyshell#108>", line 1, in -toplevel-
+        d['primary']                # entry was automatically removed
+      File "C:/PY24/lib/weakref.py", line 46, in __getitem__
+        o = self.data[key]()
+    KeyError: 'primary'
+\end{verbatim}
+
+\section{Tools for Working with Lists\label{list-tools}}
+
+Many data structure needs can be met with the built-in list type.
+However, sometimes there is a need for alternative implementations
+with different performance trade-offs.
+
+The \ulink{\module{array}}{../lib/module-array.html} module provides an
+\class{array()} object that is like a list that stores only homogenous
+data and stores it more compactly.  The following example shows an array
+of numbers stored as two byte unsigned binary numbers (typecode
+\code{"H"}) rather than the usual 16 bytes per entry for regular lists
+of python int objects:
+
+\begin{verbatim}
+    >>> from array import array
+    >>> a = array('H', [4000, 10, 700, 22222])
+    >>> sum(a)
+    26932
+    >>> a[1:3]
+    array('H', [10, 700])
+\end{verbatim}
+
+The \ulink{\module{collections}}{../lib/module-collections.html} module
+provides a \class{deque()} object that is like a list with faster
+appends and pops from the left side but slower lookups in the middle.
+These objects are well suited for implementing queues and breadth first
+tree searches:
+
+\begin{verbatim}
+    >>> from collections import deque
+    >>> d = deque(["task1", "task2", "task3"])
+    >>> d.append("task4")
+    >>> print "Handling", d.popleft()
+    Handling task1
+
+    unsearched = deque([starting_node])
+    def breadth_first_search(unsearched):
+        node = unsearched.popleft()
+        for m in gen_moves(node):
+            if is_goal(m):
+                return m
+            unsearched.append(m)
+\end{verbatim}
+
+In addition to alternative list implementations, the library also offers
+other tools such as the \ulink{\module{bisect}}{../lib/module-bisect.html}
+module with functions for manipulating sorted lists:
+
+\begin{verbatim}
+    >>> import bisect
+    >>> scores = [(100, 'perl'), (200, 'tcl'), (400, 'lua'), (500, 'python')]
+    >>> bisect.insort(scores, (300, 'ruby'))
+    >>> scores
+    [(100, 'perl'), (200, 'tcl'), (300, 'ruby'), (400, 'lua'), (500, 'python')]
+\end{verbatim}
+
+The \ulink{\module{heapq}}{../lib/module-heapq.html} module provides
+functions for implementing heaps based on regular lists.  The lowest
+valued entry is always kept at position zero.  This is useful for
+applications which repeatedly access the smallest element but do not
+want to run a full list sort:
+
+\begin{verbatim}
+    >>> from heapq import heapify, heappop, heappush
+    >>> data = [1, 3, 5, 7, 9, 2, 4, 6, 8, 0]
+    >>> heapify(data)                      # rearrange the list into heap order
+    >>> heappush(data, -5)                 # add a new entry
+    >>> [heappop(data) for i in range(3)]  # fetch the three smallest entries
+    [-5, 0, 1]
+\end{verbatim}
+
+
+\section{Decimal Floating Point Arithmetic\label{decimal-fp}}
+
+The \ulink{\module{decimal}}{../lib/module-decimal.html} module offers a
+\class{Decimal} datatype for decimal floating point arithmetic.  Compared to
+the built-in \class{float} implementation of binary floating point, the new
+class is especially helpful for financial applications and other uses which
+require exact decimal representation, control over precision, control over
+rounding to meet legal or regulatory requirements, tracking of significant
+decimal places, or for applications where the user expects the results to
+match calculations done by hand.
+
+For example, calculating a 5\%{} tax on a 70 cent phone charge gives
+different results in decimal floating point and binary floating point.
+The difference becomes significant if the results are rounded to the
+nearest cent:
+
+\begin{verbatim}
+>>> from decimal import *       
+>>> Decimal('0.70') * Decimal('1.05')
+Decimal("0.7350")
+>>> .70 * 1.05
+0.73499999999999999       
+\end{verbatim}
+
+The \class{Decimal} result keeps a trailing zero, automatically inferring four
+place significance from multiplicands with two place significance.  Decimal reproduces
+mathematics as done by hand and avoids issues that can arise when binary
+floating point cannot exactly represent decimal quantities.
+
+Exact representation enables the \class{Decimal} class to perform
+modulo calculations and equality tests that are unsuitable for binary
+floating point:
+
+\begin{verbatim}
+>>> Decimal('1.00') % Decimal('.10')
+Decimal("0.00")
+>>> 1.00 % 0.10
+0.09999999999999995
+       
+>>> sum([Decimal('0.1')]*10) == Decimal('1.0')
+True
+>>> sum([0.1]*10) == 1.0
+False      
+\end{verbatim}
+
+The \module{decimal} module provides arithmetic with as much precision as
+needed:
+
+\begin{verbatim}
+>>> getcontext().prec = 36
+>>> Decimal(1) / Decimal(7)
+Decimal("0.142857142857142857142857142857142857")
+\end{verbatim}
+
+
+
+\chapter{What Now? \label{whatNow}}
+
+Reading this tutorial has probably reinforced your interest in using
+Python --- you should be eager to apply Python to solving your
+real-world problems. Where should you go to learn more?
+
+This tutorial is part of Python's documentation set.  
+Some other documents in the set are:
+
+\begin{itemize}
+
+\item \citetitle[../lib/lib.html]{Python Library Reference}:
+
+You should browse through this manual, which gives complete (though
+terse) reference material about types, functions, and the modules in
+the standard library.  The standard Python distribution includes a
+\emph{lot} of additional code.  There are modules to read \UNIX{}
+mailboxes, retrieve documents via HTTP, generate random numbers, parse
+command-line options, write CGI programs, compress data, and many other tasks.
+Skimming through the Library Reference will give you an idea of
+what's available.
+
+\item \citetitle[../inst/inst.html]{Installing Python Modules}
+explains how to install external modules written by other Python
+users.
+
+\item \citetitle[../ref/ref.html]{Language Reference}: A detailed 
+explanation of Python's syntax and semantics.  It's heavy reading, 
+but is useful as a complete guide to the language itself.
+
+\end{itemize}
+
+More Python resources:
+
+\begin{itemize}
+
+\item \url{http://www.python.org}:  The major Python Web site.  It contains
+code, documentation, and pointers to Python-related pages around the
+Web.  This Web site is mirrored in various places around the
+world, such as Europe, Japan, and Australia; a mirror may be faster
+than the main site, depending on your geographical location. 
+
+\item \url{http://docs.python.org}:  Fast access to Python's 
+documentation.
+
+\item \url{http://cheeseshop.python.org}: 
+The Python Package Index, nicknamed the Cheese Shop, 
+is an index of user-created Python modules that are available for 
+download.  Once you begin releasing code, you can register it 
+here so that others can find it.
+
+\item \url{http://aspn.activestate.com/ASPN/Python/Cookbook/}: The
+Python Cookbook is a sizable collection of code examples, larger
+modules, and useful scripts.  Particularly notable contributions are
+collected in a book also titled \citetitle{Python Cookbook} (O'Reilly
+\& Associates, ISBN 0-596-00797-3.)
+
+\end{itemize}
+
+
+For Python-related questions and problem reports, you can post to the
+newsgroup \newsgroup{comp.lang.python}, or send them to the mailing
+list at \email{python-list at python.org}.  The newsgroup and mailing list
+are gatewayed, so messages posted to one will automatically be
+forwarded to the other.  There are around 120 postings a day (with peaks
+up to several hundred),
+% Postings figure based on average of last six months activity as
+% reported by www.egroups.com; Jan. 2000 - June 2000: 21272 msgs / 182
+% days = 116.9 msgs / day and steadily increasing.
+asking (and answering) questions, suggesting new features, and
+announcing new modules.  Before posting, be sure to check the list of
+\ulink{Frequently Asked Questions}{http://www.python.org/doc/faq/} (also called the FAQ), or look for it in the
+\file{Misc/} directory of the Python source distribution.  Mailing
+list archives are available at \url{http://mail.python.org/pipermail/}.
+The FAQ answers many of the questions that come up again and again,
+and may already contain the solution for your problem.
+
+
+\appendix
+
+\chapter{Interactive Input Editing and History Substitution\label{interacting}}
+
+Some versions of the Python interpreter support editing of the current
+input line and history substitution, similar to facilities found in
+the Korn shell and the GNU Bash shell.  This is implemented using the
+\emph{GNU Readline} library, which supports Emacs-style and vi-style
+editing.  This library has its own documentation which I won't
+duplicate here; however, the basics are easily explained.  The
+interactive editing and history described here are optionally
+available in the \UNIX{} and Cygwin versions of the interpreter.
+
+This chapter does \emph{not} document the editing facilities of Mark
+Hammond's PythonWin package or the Tk-based environment, IDLE,
+distributed with Python.  The command line history recall which
+operates within DOS boxes on NT and some other DOS and Windows flavors 
+is yet another beast.
+
+\section{Line Editing \label{lineEditing}}
+
+If supported, input line editing is active whenever the interpreter
+prints a primary or secondary prompt.  The current line can be edited
+using the conventional Emacs control characters.  The most important
+of these are: \kbd{C-A} (Control-A) moves the cursor to the beginning
+of the line, \kbd{C-E} to the end, \kbd{C-B} moves it one position to
+the left, \kbd{C-F} to the right.  Backspace erases the character to
+the left of the cursor, \kbd{C-D} the character to its right.
+\kbd{C-K} kills (erases) the rest of the line to the right of the
+cursor, \kbd{C-Y} yanks back the last killed string.
+\kbd{C-underscore} undoes the last change you made; it can be repeated
+for cumulative effect.
+
+\section{History Substitution \label{history}}
+
+History substitution works as follows.  All non-empty input lines
+issued are saved in a history buffer, and when a new prompt is given
+you are positioned on a new line at the bottom of this buffer.
+\kbd{C-P} moves one line up (back) in the history buffer,
+\kbd{C-N} moves one down.  Any line in the history buffer can be
+edited; an asterisk appears in front of the prompt to mark a line as
+modified.  Pressing the \kbd{Return} key passes the current line to
+the interpreter.  \kbd{C-R} starts an incremental reverse search;
+\kbd{C-S} starts a forward search.
+
+\section{Key Bindings \label{keyBindings}}
+
+The key bindings and some other parameters of the Readline library can
+be customized by placing commands in an initialization file called
+\file{\~{}/.inputrc}.  Key bindings have the form
+
+\begin{verbatim}
+key-name: function-name
+\end{verbatim}
+
+or
+
+\begin{verbatim}
+"string": function-name
+\end{verbatim}
+
+and options can be set with
+
+\begin{verbatim}
+set option-name value
+\end{verbatim}
+
+For example:
+
+\begin{verbatim}
+# I prefer vi-style editing:
+set editing-mode vi
+
+# Edit using a single line:
+set horizontal-scroll-mode On
+
+# Rebind some keys:
+Meta-h: backward-kill-word
+"\C-u": universal-argument
+"\C-x\C-r": re-read-init-file
+\end{verbatim}
+
+Note that the default binding for \kbd{Tab} in Python is to insert a
+\kbd{Tab} character instead of Readline's default filename completion
+function.  If you insist, you can override this by putting
+
+\begin{verbatim}
+Tab: complete
+\end{verbatim}
+
+in your \file{\~{}/.inputrc}.  (Of course, this makes it harder to
+type indented continuation lines if you're accustomed to using
+\kbd{Tab} for that purpose.)
+
+Automatic completion of variable and module names is optionally
+available.  To enable it in the interpreter's interactive mode, add
+the following to your startup file:\footnote{
+  Python will execute the contents of a file identified by the
+  \envvar{PYTHONSTARTUP} environment variable when you start an
+  interactive interpreter.}
+\refstmodindex{rlcompleter}\refbimodindex{readline}
+
+\begin{verbatim}
+import rlcompleter, readline
+readline.parse_and_bind('tab: complete')
+\end{verbatim}
+
+This binds the \kbd{Tab} key to the completion function, so hitting
+the \kbd{Tab} key twice suggests completions; it looks at Python
+statement names, the current local variables, and the available module
+names.  For dotted expressions such as \code{string.a}, it will
+evaluate the expression up to the final \character{.} and then
+suggest completions from the attributes of the resulting object.  Note
+that this may execute application-defined code if an object with a
+\method{__getattr__()} method is part of the expression.
+
+A more capable startup file might look like this example.  Note that
+this deletes the names it creates once they are no longer needed; this
+is done since the startup file is executed in the same namespace as
+the interactive commands, and removing the names avoids creating side
+effects in the interactive environment.  You may find it convenient
+to keep some of the imported modules, such as
+\ulink{\module{os}}{../lib/module-os.html}, which turn
+out to be needed in most sessions with the interpreter.
+
+\begin{verbatim}
+# Add auto-completion and a stored history file of commands to your Python
+# interactive interpreter. Requires Python 2.0+, readline. Autocomplete is
+# bound to the Esc key by default (you can change it - see readline docs).
+#
+# Store the file in ~/.pystartup, and set an environment variable to point
+# to it:  "export PYTHONSTARTUP=/max/home/itamar/.pystartup" in bash.
+#
+# Note that PYTHONSTARTUP does *not* expand "~", so you have to put in the
+# full path to your home directory.
+
+import atexit
+import os
+import readline
+import rlcompleter
+
+historyPath = os.path.expanduser("~/.pyhistory")
+
+def save_history(historyPath=historyPath):
+    import readline
+    readline.write_history_file(historyPath)
+
+if os.path.exists(historyPath):
+    readline.read_history_file(historyPath)
+
+atexit.register(save_history)
+del os, atexit, readline, rlcompleter, save_history, historyPath
+\end{verbatim}
+
+
+\section{Commentary \label{commentary}}
+
+This facility is an enormous step forward compared to earlier versions
+of the interpreter; however, some wishes are left: It would be nice if
+the proper indentation were suggested on continuation lines (the
+parser knows if an indent token is required next).  The completion
+mechanism might use the interpreter's symbol table.  A command to
+check (or even suggest) matching parentheses, quotes, etc., would also
+be useful.
+
+
+\chapter{Floating Point Arithmetic:  Issues and Limitations\label{fp-issues}}
+\sectionauthor{Tim Peters}{tim_one at users.sourceforge.net}
+
+Floating-point numbers are represented in computer hardware as
+base 2 (binary) fractions.  For example, the decimal fraction
+
+\begin{verbatim}
+0.125
+\end{verbatim}
+
+has value 1/10 + 2/100 + 5/1000, and in the same way the binary fraction
+
+\begin{verbatim}
+0.001
+\end{verbatim}
+
+has value 0/2 + 0/4 + 1/8.  These two fractions have identical values,
+the only real difference being that the first is written in base 10
+fractional notation, and the second in base 2.
+
+Unfortunately, most decimal fractions cannot be represented exactly as
+binary fractions.  A consequence is that, in general, the decimal
+floating-point numbers you enter are only approximated by the binary
+floating-point numbers actually stored in the machine.
+
+The problem is easier to understand at first in base 10.  Consider the
+fraction 1/3.  You can approximate that as a base 10 fraction:
+
+\begin{verbatim}
+0.3
+\end{verbatim}
+
+or, better,
+
+\begin{verbatim}
+0.33
+\end{verbatim}
+
+or, better,
+
+\begin{verbatim}
+0.333
+\end{verbatim}
+
+and so on.  No matter how many digits you're willing to write down, the
+result will never be exactly 1/3, but will be an increasingly better
+approximation of 1/3.
+
+In the same way, no matter how many base 2 digits you're willing to
+use, the decimal value 0.1 cannot be represented exactly as a base 2
+fraction.  In base 2, 1/10 is the infinitely repeating fraction
+
+\begin{verbatim}
+0.0001100110011001100110011001100110011001100110011...
+\end{verbatim}
+
+Stop at any finite number of bits, and you get an approximation.  This
+is why you see things like:
+
+\begin{verbatim}
+>>> 0.1
+0.10000000000000001
+\end{verbatim}
+
+On most machines today, that is what you'll see if you enter 0.1 at
+a Python prompt.  You may not, though, because the number of bits
+used by the hardware to store floating-point values can vary across
+machines, and Python only prints a decimal approximation to the true
+decimal value of the binary approximation stored by the machine.  On
+most machines, if Python were to print the true decimal value of
+the binary approximation stored for 0.1, it would have to display
+
+\begin{verbatim}
+>>> 0.1
+0.1000000000000000055511151231257827021181583404541015625
+\end{verbatim}
+
+instead!  The Python prompt uses the builtin
+\function{repr()} function to obtain a string version of everything it
+displays.  For floats, \code{repr(\var{float})} rounds the true
+decimal value to 17 significant digits, giving
+
+\begin{verbatim}
+0.10000000000000001
+\end{verbatim}
+
+\code{repr(\var{float})} produces 17 significant digits because it
+turns out that's enough (on most machines) so that
+\code{eval(repr(\var{x})) == \var{x}} exactly for all finite floats
+\var{x}, but rounding to 16 digits is not enough to make that true.
+
+Note that this is in the very nature of binary floating-point: this is
+not a bug in Python, and it is not a bug in your code either.  You'll
+see the same kind of thing in all languages that support your
+hardware's floating-point arithmetic (although some languages may
+not \emph{display} the difference by default, or in all output modes).
+
+Python's builtin \function{str()} function produces only 12
+significant digits, and you may wish to use that instead.  It's
+unusual for \code{eval(str(\var{x}))} to reproduce \var{x}, but the
+output may be more pleasant to look at:
+
+\begin{verbatim}
+>>> print str(0.1)
+0.1
+\end{verbatim}
+
+It's important to realize that this is, in a real sense, an illusion:
+the value in the machine is not exactly 1/10, you're simply rounding
+the \emph{display} of the true machine value.
+
+Other surprises follow from this one.  For example, after seeing
+
+\begin{verbatim}
+>>> 0.1
+0.10000000000000001
+\end{verbatim}
+
+you may be tempted to use the \function{round()} function to chop it
+back to the single digit you expect.  But that makes no difference:
+
+\begin{verbatim}
+>>> round(0.1, 1)
+0.10000000000000001
+\end{verbatim}
+
+The problem is that the binary floating-point value stored for "0.1"
+was already the best possible binary approximation to 1/10, so trying
+to round it again can't make it better:  it was already as good as it
+gets.
+
+Another consequence is that since 0.1 is not exactly 1/10,
+summing ten values of 0.1 may not yield exactly 1.0, either:
+
+\begin{verbatim}
+>>> sum = 0.0
+>>> for i in range(10):
+...     sum += 0.1
+...
+>>> sum
+0.99999999999999989
+\end{verbatim}
+
+Binary floating-point arithmetic holds many surprises like this.  The
+problem with "0.1" is explained in precise detail below, in the
+"Representation Error" section.  See
+\citetitle[http://www.lahey.com/float.htm]{The Perils of Floating
+Point} for a more complete account of other common surprises.
+
+As that says near the end, ``there are no easy answers.''  Still,
+don't be unduly wary of floating-point!  The errors in Python float
+operations are inherited from the floating-point hardware, and on most
+machines are on the order of no more than 1 part in 2**53 per
+operation.  That's more than adequate for most tasks, but you do need
+to keep in mind that it's not decimal arithmetic, and that every float
+operation can suffer a new rounding error.
+
+While pathological cases do exist, for most casual use of
+floating-point arithmetic you'll see the result you expect in the end
+if you simply round the display of your final results to the number of
+decimal digits you expect.  \function{str()} usually suffices, and for
+finer control see the discussion of Python's \code{\%} format
+operator: the \code{\%g}, \code{\%f} and \code{\%e} format codes
+supply flexible and easy ways to round float results for display.
+
+
+\section{Representation Error
+         \label{fp-error}}
+
+This section explains the ``0.1'' example in detail, and shows how
+you can perform an exact analysis of cases like this yourself.  Basic
+familiarity with binary floating-point representation is assumed.
+
+\dfn{Representation error} refers to the fact that some (most, actually)
+decimal fractions cannot be represented exactly as binary (base 2)
+fractions.  This is the chief reason why Python (or Perl, C, \Cpp,
+Java, Fortran, and many others) often won't display the exact decimal
+number you expect:
+
+\begin{verbatim}
+>>> 0.1
+0.10000000000000001
+\end{verbatim}
+
+Why is that?  1/10 is not exactly representable as a binary fraction.
+Almost all machines today (November 2000) use IEEE-754 floating point
+arithmetic, and almost all platforms map Python floats to IEEE-754
+"double precision".  754 doubles contain 53 bits of precision, so on
+input the computer strives to convert 0.1 to the closest fraction it can
+of the form \var{J}/2**\var{N} where \var{J} is an integer containing
+exactly 53 bits.  Rewriting
+
+\begin{verbatim}
+ 1 / 10 ~= J / (2**N)
+\end{verbatim}
+
+as
+
+\begin{verbatim}
+J ~= 2**N / 10
+\end{verbatim}
+
+and recalling that \var{J} has exactly 53 bits (is \code{>= 2**52} but
+\code{< 2**53}), the best value for \var{N} is 56:
+
+\begin{verbatim}
+>>> 2**52
+4503599627370496L
+>>> 2**53
+9007199254740992L
+>>> 2**56/10
+7205759403792793L
+\end{verbatim}
+
+That is, 56 is the only value for \var{N} that leaves \var{J} with
+exactly 53 bits.  The best possible value for \var{J} is then that
+quotient rounded:
+
+\begin{verbatim}
+>>> q, r = divmod(2**56, 10)
+>>> r
+6L
+\end{verbatim}
+
+Since the remainder is more than half of 10, the best approximation is
+obtained by rounding up:
+
+\begin{verbatim}
+>>> q+1
+7205759403792794L
+\end{verbatim}
+
+Therefore the best possible approximation to 1/10 in 754 double
+precision is that over 2**56, or
+
+\begin{verbatim}
+7205759403792794 / 72057594037927936
+\end{verbatim}
+
+Note that since we rounded up, this is actually a little bit larger than
+1/10; if we had not rounded up, the quotient would have been a little
+bit smaller than 1/10.  But in no case can it be \emph{exactly} 1/10!
+
+So the computer never ``sees'' 1/10:  what it sees is the exact
+fraction given above, the best 754 double approximation it can get:
+
+\begin{verbatim}
+>>> .1 * 2**56
+7205759403792794.0
+\end{verbatim}
+
+If we multiply that fraction by 10**30, we can see the (truncated)
+value of its 30 most significant decimal digits:
+
+\begin{verbatim}
+>>> 7205759403792794 * 10**30 / 2**56
+100000000000000005551115123125L
+\end{verbatim}
+
+meaning that the exact number stored in the computer is approximately
+equal to the decimal value 0.100000000000000005551115123125.  Rounding
+that to 17 significant digits gives the 0.10000000000000001 that Python
+displays (well, will display on any 754-conforming platform that does
+best-possible input and output conversions in its C library --- yours may
+not!).
+
+\chapter{History and License}
+\input{license}
+
+\input{glossary}
+
+\input{tut.ind}
+
+\end{document}

Added: vendor/Python/current/Doc/whatsnew/whatsnew20.tex
===================================================================
--- vendor/Python/current/Doc/whatsnew/whatsnew20.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/whatsnew/whatsnew20.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1337 @@
+\documentclass{howto}
+
+% $Id: whatsnew20.tex 50964 2006-07-30 03:03:43Z fred.drake $
+
+\title{What's New in Python 2.0}
+\release{1.02}
+\author{A.M. Kuchling and Moshe Zadka}
+\authoraddress{
+	\strong{Python Software Foundation}\\
+	Email: \email{amk at amk.ca}, \email{moshez at twistedmatrix.com}
+}
+\begin{document}
+\maketitle\tableofcontents
+
+\section{Introduction}
+
+A new release of Python, version 2.0, was released on October 16, 2000. This
+article covers the exciting new features in 2.0, highlights some other
+useful changes, and points out a few incompatible changes that may require
+rewriting code.
+
+Python's development never completely stops between releases, and a
+steady flow of bug fixes and improvements are always being submitted.
+A host of minor fixes, a few optimizations, additional docstrings, and
+better error messages went into 2.0; to list them all would be
+impossible, but they're certainly significant.  Consult the
+publicly-available CVS logs if you want to see the full list.  This
+progress is due to the five developers working for 
+PythonLabs are now getting paid to spend their days fixing bugs,
+and also due to the improved communication resulting 
+from moving to SourceForge.
+
+% ======================================================================
+\section{What About Python 1.6?}
+
+Python 1.6 can be thought of as the Contractual Obligations Python
+release.  After the core development team left CNRI in May 2000, CNRI
+requested that a 1.6 release be created, containing all the work on
+Python that had been performed at CNRI.  Python 1.6 therefore
+represents the state of the CVS tree as of May 2000, with the most
+significant new feature being Unicode support.  Development continued
+after May, of course, so the 1.6 tree received a few fixes to ensure
+that it's forward-compatible with Python 2.0.  1.6 is therefore part
+of Python's evolution, and not a side branch.
+
+So, should you take much interest in Python 1.6?  Probably not.  The
+1.6final and 2.0beta1 releases were made on the same day (September 5,
+2000), the plan being to finalize Python 2.0 within a month or so.  If
+you have applications to maintain, there seems little point in
+breaking things by moving to 1.6, fixing them, and then having another
+round of breakage within a month by moving to 2.0; you're better off
+just going straight to 2.0.  Most of the really interesting features
+described in this document are only in 2.0, because a lot of work was
+done between May and September.  
+
+% ======================================================================
+\section{New Development Process}
+
+The most important change in Python 2.0 may not be to the code at all,
+but to how Python is developed: in May 2000 the Python developers
+began using the tools made available by SourceForge for storing 
+source code, tracking bug reports, and managing the queue of patch
+submissions.  To report bugs or submit patches for Python 2.0, use the
+bug tracking and patch manager tools available from Python's project
+page, located at \url{http://sourceforge.net/projects/python/}.
+
+The most important of the services now hosted at SourceForge is the
+Python CVS tree, the version-controlled repository containing the
+source code for Python.  Previously, there were roughly 7 or so people
+who had write access to the CVS tree, and all patches had to be
+inspected and checked in by one of the people on this short list.
+Obviously, this wasn't very scalable.  By moving the CVS tree to
+SourceForge, it became possible to grant write access to more people;
+as of September 2000 there were 27 people able to check in changes, a
+fourfold increase.  This makes possible large-scale changes that
+wouldn't be attempted if they'd have to be filtered through the small
+group of core developers.  For example, one day Peter Schneider-Kamp
+took it into his head to drop K\&R C compatibility and convert the C
+source for Python to ANSI C. After getting approval on the python-dev
+mailing list, he launched into a flurry of checkins that lasted about
+a week, other developers joined in to help, and the job was done.  If
+there were only 5 people with write access, probably that task would
+have been viewed as ``nice, but not worth the time and effort needed''
+and it would never have gotten done.
+
+The shift to using SourceForge's services has resulted in a remarkable
+increase in the speed of development.  Patches now get submitted,
+commented on, revised by people other than the original submitter, and
+bounced back and forth between people until the patch is deemed worth
+checking in.  Bugs are tracked in one central location and can be
+assigned to a specific person for fixing, and we can count the number
+of open bugs to measure progress.  This didn't come without a cost:
+developers now have more e-mail to deal with, more mailing lists to
+follow, and special tools had to be written for the new environment.
+For example, SourceForge sends default patch and bug notification
+e-mail messages that are completely unhelpful, so Ka-Ping Yee wrote an
+HTML screen-scraper that sends more useful messages.
+
+The ease of adding code caused a few initial growing pains, such as
+code was checked in before it was ready or without getting clear
+agreement from the developer group.  The approval process that has
+emerged is somewhat similar to that used by the Apache group.
+Developers can vote +1, +0, -0, or -1 on a patch; +1 and -1 denote
+acceptance or rejection, while +0 and -0 mean the developer is mostly
+indifferent to the change, though with a slight positive or negative
+slant.  The most significant change from the Apache model is that the
+voting is essentially advisory, letting Guido van Rossum, who has
+Benevolent Dictator For Life status, know what the general opinion is.
+He can still ignore the result of a vote, and approve or
+reject a change even if the community disagrees with him.
+
+Producing an actual patch is the last step in adding a new feature,
+and is usually easy compared to the earlier task of coming up with a
+good design.  Discussions of new features can often explode into
+lengthy mailing list threads, making the discussion hard to follow,
+and no one can read every posting to python-dev.  Therefore, a
+relatively formal process has been set up to write Python Enhancement
+Proposals (PEPs), modelled on the Internet RFC process.  PEPs are
+draft documents that describe a proposed new feature, and are
+continually revised until the community reaches a consensus, either
+accepting or rejecting the proposal.  Quoting from the introduction to
+PEP 1, ``PEP Purpose and Guidelines'':
+
+\begin{quotation}
+    PEP stands for Python Enhancement Proposal.  A PEP is a design
+    document providing information to the Python community, or
+    describing a new feature for Python.  The PEP should provide a
+    concise technical specification of the feature and a rationale for
+    the feature.
+
+    We intend PEPs to be the primary mechanisms for proposing new
+    features, for collecting community input on an issue, and for
+    documenting the design decisions that have gone into Python.  The
+    PEP author is responsible for building consensus within the
+    community and documenting dissenting opinions.
+\end{quotation}
+
+Read the rest of PEP 1 for the details of the PEP editorial process,
+style, and format.  PEPs are kept in the Python CVS tree on
+SourceForge, though they're not part of the Python 2.0 distribution,
+and are also available in HTML form from
+\url{http://www.python.org/peps/}.  As of September 2000,
+there are 25 PEPS, ranging from PEP 201, ``Lockstep Iteration'', to
+PEP 225, ``Elementwise/Objectwise Operators''.
+
+% ======================================================================
+\section{Unicode}
+
+The largest new feature in Python 2.0 is a new fundamental data type:
+Unicode strings.  Unicode uses 16-bit numbers to represent characters
+instead of the 8-bit number used by ASCII, meaning that 65,536
+distinct characters can be supported.
+
+The final interface for Unicode support was arrived at through
+countless often-stormy discussions on the python-dev mailing list, and
+mostly implemented by Marc-Andr\'e Lemburg, based on a Unicode string
+type implementation by Fredrik Lundh.  A detailed explanation of the
+interface was written up as \pep{100}, ``Python Unicode Integration''.
+This article will simply cover the most significant points about the
+Unicode interfaces.
+
+In Python source code, Unicode strings are written as
+\code{u"string"}.  Arbitrary Unicode characters can be written using a
+new escape sequence, \code{\e u\var{HHHH}}, where \var{HHHH} is a
+4-digit hexadecimal number from 0000 to FFFF.  The existing
+\code{\e x\var{HHHH}} escape sequence can also be used, and octal
+escapes can be used for characters up to U+01FF, which is represented
+by \code{\e 777}.
+
+Unicode strings, just like regular strings, are an immutable sequence
+type.  They can be indexed and sliced, but not modified in place.
+Unicode strings have an \method{encode( \optional{encoding} )} method
+that returns an 8-bit string in the desired encoding.  Encodings are
+named by strings, such as \code{'ascii'}, \code{'utf-8'},
+\code{'iso-8859-1'}, or whatever.  A codec API is defined for
+implementing and registering new encodings that are then available
+throughout a Python program.  If an encoding isn't specified, the
+default encoding is usually 7-bit ASCII, though it can be changed for
+your Python installation by calling the
+\function{sys.setdefaultencoding(\var{encoding})} function in a
+customised version of \file{site.py}.
+
+Combining 8-bit and Unicode strings always coerces to Unicode, using
+the default ASCII encoding; the result of \code{'a' + u'bc'} is
+\code{u'abc'}.
+
+New built-in functions have been added, and existing built-ins
+modified to support Unicode:
+
+\begin{itemize}
+\item \code{unichr(\var{ch})} returns a Unicode string 1 character
+long, containing the character \var{ch}.
+
+\item \code{ord(\var{u})}, where \var{u} is a 1-character regular or Unicode string, returns the number of the character as an integer.
+
+\item \code{unicode(\var{string} \optional{, \var{encoding}} 
+\optional{, \var{errors}} ) } creates a Unicode string from an 8-bit
+string.  \code{encoding} is a string naming the encoding to use.
+The \code{errors} parameter specifies the treatment of characters that
+are invalid for the current encoding; passing \code{'strict'} as the
+value causes an exception to be raised on any encoding error, while
+\code{'ignore'} causes errors to be silently ignored and
+\code{'replace'} uses U+FFFD, the official replacement character, in
+case of any problems.
+
+\item The \keyword{exec} statement, and various built-ins such as
+\code{eval()}, \code{getattr()}, and \code{setattr()} will also
+accept Unicode strings as well as regular strings.  (It's possible
+that the process of fixing this missed some built-ins; if you find a
+built-in function that accepts strings but doesn't accept Unicode
+strings at all, please report it as a bug.)
+
+\end{itemize}
+
+A new module, \module{unicodedata}, provides an interface to Unicode
+character properties.  For example, \code{unicodedata.category(u'A')}
+returns the 2-character string 'Lu', the 'L' denoting it's a letter,
+and 'u' meaning that it's uppercase.
+\code{unicodedata.bidirectional(u'\e u0660')} returns 'AN', meaning that U+0660 is
+an Arabic number.
+
+The \module{codecs} module contains functions to look up existing encodings
+and register new ones.  Unless you want to implement a
+new encoding, you'll most often use the
+\function{codecs.lookup(\var{encoding})} function, which returns a
+4-element tuple: \code{(\var{encode_func},
+\var{decode_func}, \var{stream_reader}, \var{stream_writer})}.
+
+\begin{itemize}
+\item \var{encode_func} is a function that takes a Unicode string, and
+returns a 2-tuple \code{(\var{string}, \var{length})}.  \var{string}
+is an 8-bit string containing a portion (perhaps all) of the Unicode
+string converted into the given encoding, and \var{length} tells you
+how much of the Unicode string was converted.
+
+\item \var{decode_func} is the opposite of \var{encode_func}, taking
+an 8-bit string and returning a 2-tuple \code{(\var{ustring},
+\var{length})}, consisting of the resulting Unicode string
+\var{ustring} and the integer \var{length} telling how much of the
+8-bit string was consumed.
+
+\item \var{stream_reader} is a class that supports decoding input from
+a stream.  \var{stream_reader(\var{file_obj})} returns an object that
+supports the \method{read()}, \method{readline()}, and
+\method{readlines()} methods.  These methods will all translate from
+the given encoding and return Unicode strings.
+
+\item \var{stream_writer}, similarly, is a class that supports
+encoding output to a stream.  \var{stream_writer(\var{file_obj})}
+returns an object that supports the \method{write()} and
+\method{writelines()} methods.  These methods expect Unicode strings,
+translating them to the given encoding on output.
+\end{itemize}
+
+For example, the following code writes a Unicode string into a file, 
+encoding it as UTF-8:
+
+\begin{verbatim}
+import codecs
+
+unistr = u'\u0660\u2000ab ...'
+
+(UTF8_encode, UTF8_decode,
+ UTF8_streamreader, UTF8_streamwriter) = codecs.lookup('UTF-8')
+
+output = UTF8_streamwriter( open( '/tmp/output', 'wb') )
+output.write( unistr )
+output.close()
+\end{verbatim}
+
+The following code would then read UTF-8 input from the file:
+
+\begin{verbatim}
+input = UTF8_streamreader( open( '/tmp/output', 'rb') )
+print repr(input.read())
+input.close()
+\end{verbatim}
+
+Unicode-aware regular expressions are available through the
+\module{re} module, which has a new underlying implementation called
+SRE written by Fredrik Lundh of Secret Labs AB. 
+
+A \code{-U} command line option was added which causes the Python
+compiler to interpret all string literals as Unicode string literals.
+This is intended to be used in testing and future-proofing your Python
+code, since some future version of Python may drop support for 8-bit
+strings and provide only Unicode strings.
+
+% ======================================================================
+\section{List Comprehensions}
+
+Lists are a workhorse data type in Python, and many programs
+manipulate a list at some point.  Two common operations on lists are
+to loop over them, and either pick out the elements that meet a
+certain criterion, or apply some function to each element.  For
+example, given a list of strings, you might want to pull out all the
+strings containing a given substring, or strip off trailing whitespace
+from each line.  
+
+The existing \function{map()} and \function{filter()} functions can be
+used for this purpose, but they require a function as one of their
+arguments.  This is fine if there's an existing built-in function that
+can be passed directly, but if there isn't, you have to create a
+little function to do the required work, and Python's scoping rules
+make the result ugly if the little function needs additional
+information.  Take the first example in the previous paragraph,
+finding all the strings in the list containing a given substring.  You
+could write the following to do it:
+
+\begin{verbatim}
+# Given the list L, make a list of all strings 
+# containing the substring S.
+sublist = filter( lambda s, substring=S: 
+                     string.find(s, substring) != -1,
+	          L)
+\end{verbatim}
+
+Because of Python's scoping rules, a default argument is used so that
+the anonymous function created by the \keyword{lambda} statement knows
+what substring is being searched for.  List comprehensions make this
+cleaner:
+
+\begin{verbatim}
+sublist = [ s for s in L if string.find(s, S) != -1 ]
+\end{verbatim}
+
+List comprehensions have the form:
+
+\begin{verbatim}
+[ expression for expr in sequence1 
+             for expr2 in sequence2 ...
+	     for exprN in sequenceN
+             if condition ]
+\end{verbatim}
+
+The \keyword{for}...\keyword{in} clauses contain the sequences to be
+iterated over.  The sequences do not have to be the same length,
+because they are \emph{not} iterated over in parallel, but
+from left to right; this is explained more clearly in the following
+paragraphs.  The elements of the generated list will be the successive
+values of \var{expression}.  The final \keyword{if} clause is
+optional; if present, \var{expression} is only evaluated and added to
+the result if \var{condition} is true.
+
+To make the semantics very clear, a list comprehension is equivalent
+to the following Python code:
+
+\begin{verbatim}
+for expr1 in sequence1:
+    for expr2 in sequence2:
+    ...
+        for exprN in sequenceN:
+             if (condition):
+                  # Append the value of 
+                  # the expression to the 
+                  # resulting list.
+\end{verbatim}
+
+This means that when there are multiple \keyword{for}...\keyword{in} clauses,
+the resulting list will be equal to the product of the lengths of all
+the sequences.  If you have two lists of length 3, the output list is
+9 elements long:
+
+\begin{verbatim}
+seq1 = 'abc'
+seq2 = (1,2,3)
+>>> [ (x,y) for x in seq1 for y in seq2]
+[('a', 1), ('a', 2), ('a', 3), ('b', 1), ('b', 2), ('b', 3), ('c', 1),
+('c', 2), ('c', 3)]
+\end{verbatim}
+
+To avoid introducing an ambiguity into Python's grammar, if
+\var{expression} is creating a tuple, it must be surrounded with
+parentheses.  The first list comprehension below is a syntax error,
+while the second one is correct:
+
+\begin{verbatim}
+# Syntax error
+[ x,y for x in seq1 for y in seq2]
+# Correct
+[ (x,y) for x in seq1 for y in seq2]
+\end{verbatim}
+
+The idea of list comprehensions originally comes from the functional
+programming language Haskell (\url{http://www.haskell.org}).  Greg
+Ewing argued most effectively for adding them to Python and wrote the
+initial list comprehension patch, which was then discussed for a
+seemingly endless time on the python-dev mailing list and kept
+up-to-date by Skip Montanaro.
+
+% ======================================================================
+\section{Augmented Assignment}
+
+Augmented assignment operators, another long-requested feature, have
+been added to Python 2.0.  Augmented assignment operators include
+\code{+=}, \code{-=}, \code{*=}, and so forth.  For example, the
+statement \code{a += 2} increments the value of the variable 
+\code{a} by 2, equivalent to the slightly lengthier \code{a = a + 2}.
+
+% The empty groups below prevent conversion to guillemets.
+The full list of supported assignment operators is \code{+=},
+\code{-=}, \code{*=}, \code{/=}, \code{\%=}, \code{**=}, \code{\&=},
+\code{|=}, \verb|^=|, \code{>>=}, and \code{<<=}.  Python classes can
+override the augmented assignment operators by defining methods named
+\method{__iadd__}, \method{__isub__}, etc.  For example, the following
+\class{Number} class stores a number and supports using += to create a
+new instance with an incremented value.
+
+\begin{verbatim}
+class Number:
+    def __init__(self, value):
+        self.value = value
+    def __iadd__(self, increment):
+	return Number( self.value + increment)
+
+n = Number(5)
+n += 3
+print n.value
+\end{verbatim}
+
+The \method{__iadd__} special method is called with the value of the
+increment, and should return a new instance with an appropriately
+modified value; this return value is bound as the new value of the
+variable on the left-hand side. 
+
+Augmented assignment operators were first introduced in the C
+programming language, and most C-derived languages, such as
+\program{awk}, \Cpp, Java, Perl, and PHP also support them.  The augmented
+assignment patch was implemented by Thomas Wouters.
+
+% ======================================================================
+\section{String Methods}
+
+Until now string-manipulation functionality was in the \module{string}
+module, which was usually a front-end for the \module{strop}
+module written in C.  The addition of Unicode posed a difficulty for
+the \module{strop} module, because the functions would all need to be
+rewritten in order to accept either 8-bit or Unicode strings.  For
+functions such as \function{string.replace()}, which takes 3 string
+arguments, that means eight possible permutations, and correspondingly
+complicated code.
+
+Instead, Python 2.0 pushes the problem onto the string type, making
+string manipulation functionality available through methods on both
+8-bit strings and Unicode strings.  
+
+\begin{verbatim}
+>>> 'andrew'.capitalize()
+'Andrew'
+>>> 'hostname'.replace('os', 'linux')
+'hlinuxtname'
+>>> 'moshe'.find('sh')
+2
+\end{verbatim}
+
+One thing that hasn't changed, a noteworthy April Fools' joke
+notwithstanding, is that Python strings are immutable. Thus, the
+string methods return new strings, and do not modify the string on
+which they operate.
+
+The old \module{string} module is still around for backwards
+compatibility, but it mostly acts as a front-end to the new string
+methods.
+
+Two methods which have no parallel in pre-2.0 versions, although they
+did exist in JPython for quite some time, are \method{startswith()}
+and \method{endswith}.  \code{s.startswith(t)} is equivalent to \code{s[:len(t)]
+== t}, while \code{s.endswith(t)} is equivalent to \code{s[-len(t):] == t}.
+
+One other method which deserves special mention is \method{join}.  The
+\method{join} method of a string receives one parameter, a sequence of
+strings, and is equivalent to the \function{string.join} function from
+the old \module{string} module, with the arguments reversed. In other
+words, \code{s.join(seq)} is equivalent to the old
+\code{string.join(seq, s)}.
+
+% ======================================================================
+\section{Garbage Collection of Cycles}
+
+The C implementation of Python uses reference counting to implement
+garbage collection.  Every Python object maintains a count of the
+number of references pointing to itself, and adjusts the count as
+references are created or destroyed.  Once the reference count reaches
+zero, the object is no longer accessible, since you need to have a
+reference to an object to access it, and if the count is zero, no
+references exist any longer.  
+
+Reference counting has some pleasant properties: it's easy to
+understand and implement, and the resulting implementation is
+portable, fairly fast, and reacts well with other libraries that
+implement their own memory handling schemes.  The major problem with
+reference counting is that it sometimes doesn't realise that objects
+are no longer accessible, resulting in a memory leak.  This happens
+when there are cycles of references.
+
+Consider the simplest possible cycle, 
+a class instance which has a reference to itself:
+
+\begin{verbatim}
+instance = SomeClass()
+instance.myself = instance
+\end{verbatim}
+
+After the above two lines of code have been executed, the reference
+count of \code{instance} is 2; one reference is from the variable
+named \samp{'instance'}, and the other is from the \samp{myself}
+attribute of the instance.  
+
+If the next line of code is \code{del instance}, what happens?  The
+reference count of \code{instance} is decreased by 1, so it has a
+reference count of 1; the reference in the \samp{myself} attribute
+still exists.  Yet the instance is no longer accessible through Python
+code, and it could be deleted.  Several objects can participate in a
+cycle if they have references to each other, causing all of the
+objects to be leaked.
+
+Python 2.0 fixes this problem by periodically executing a cycle
+detection algorithm which looks for inaccessible cycles and deletes
+the objects involved.  A new \module{gc} module provides functions to
+perform a garbage collection, obtain debugging statistics, and tuning
+the collector's parameters.
+
+Running the cycle detection algorithm takes some time, and therefore
+will result in some additional overhead.  It is hoped that after we've
+gotten experience with the cycle collection from using 2.0, Python 2.1
+will be able to minimize the overhead with careful tuning.  It's not
+yet obvious how much performance is lost, because benchmarking this is
+tricky and depends crucially on how often the program creates and
+destroys objects.  The detection of cycles can be disabled when Python
+is compiled, if you can't afford even a tiny speed penalty or suspect
+that the cycle collection is buggy, by specifying the
+\longprogramopt{without-cycle-gc} switch when running the
+\program{configure} script.
+
+Several people tackled this problem and contributed to a solution.  An
+early implementation of the cycle detection approach was written by
+Toby Kelsey.  The current algorithm was suggested by Eric Tiedemann
+during a visit to CNRI, and Guido van Rossum and Neil Schemenauer
+wrote two different implementations, which were later integrated by
+Neil.  Lots of other people offered suggestions along the way; the
+March 2000 archives of the python-dev mailing list contain most of the
+relevant discussion, especially in the threads titled ``Reference
+cycle collection for Python'' and ``Finalization again''.
+
+% ======================================================================
+\section{Other Core Changes}
+
+Various minor changes have been made to Python's syntax and built-in
+functions.  None of the changes are very far-reaching, but they're
+handy conveniences.
+
+\subsection{Minor Language Changes}
+
+A new syntax makes it more convenient to call a given function
+with a tuple of arguments and/or a dictionary of keyword arguments.
+In Python 1.5 and earlier, you'd use the \function{apply()}
+built-in function: \code{apply(f, \var{args}, \var{kw})} calls the
+function \function{f()} with the argument tuple \var{args} and the
+keyword arguments in the dictionary \var{kw}.  \function{apply()} 
+is the same in 2.0, but thanks to a patch from
+Greg Ewing, \code{f(*\var{args}, **\var{kw})} as a shorter
+and clearer way to achieve the same effect.  This syntax is
+symmetrical with the syntax for defining functions:
+
+\begin{verbatim}
+def f(*args, **kw):
+    # args is a tuple of positional args,
+    # kw is a dictionary of keyword args
+    ...
+\end{verbatim}
+
+The \keyword{print} statement can now have its output directed to a
+file-like object by following the \keyword{print} with 
+\verb|>> file|, similar to the redirection operator in \UNIX{} shells.
+Previously you'd either have to use the \method{write()} method of the
+file-like object, which lacks the convenience and simplicity of
+\keyword{print}, or you could assign a new value to 
+\code{sys.stdout} and then restore the old value.  For sending output to standard error,
+it's much easier to write this:
+
+\begin{verbatim}
+print >> sys.stderr, "Warning: action field not supplied"
+\end{verbatim}
+
+Modules can now be renamed on importing them, using the syntax
+\code{import \var{module} as \var{name}} or \code{from \var{module}
+import \var{name} as \var{othername}}.  The patch was submitted by
+Thomas Wouters.
+
+A new format style is available when using the \code{\%} operator;
+'\%r' will insert the \function{repr()} of its argument.  This was
+also added from symmetry considerations, this time for symmetry with
+the existing '\%s' format style, which inserts the \function{str()} of
+its argument.  For example, \code{'\%r \%s' \% ('abc', 'abc')} returns a
+string containing \verb|'abc' abc|.
+
+Previously there was no way to implement a class that overrode
+Python's built-in \keyword{in} operator and implemented a custom
+version.  \code{\var{obj} in \var{seq}} returns true if \var{obj} is
+present in the sequence \var{seq}; Python computes this by simply
+trying every index of the sequence until either \var{obj} is found or
+an \exception{IndexError} is encountered.  Moshe Zadka contributed a
+patch which adds a \method{__contains__} magic method for providing a
+custom implementation for \keyword{in}. Additionally, new built-in
+objects written in C can define what \keyword{in} means for them via a
+new slot in the sequence protocol.
+
+Earlier versions of Python used a recursive algorithm for deleting
+objects.  Deeply nested data structures could cause the interpreter to
+fill up the C stack and crash; Christian Tismer rewrote the deletion
+logic to fix this problem.  On a related note, comparing recursive
+objects recursed infinitely and crashed; Jeremy Hylton rewrote the
+code to no longer crash, producing a useful result instead.  For
+example, after this code:
+
+\begin{verbatim}
+a = []
+b = []
+a.append(a)
+b.append(b)
+\end{verbatim}
+
+The comparison \code{a==b} returns true, because the two recursive
+data structures are isomorphic. See the thread ``trashcan
+and PR\#7'' in the April 2000 archives of the python-dev mailing list
+for the discussion leading up to this implementation, and some useful
+relevant links.  
+% Starting URL:
+% http://www.python.org/pipermail/python-dev/2000-April/004834.html
+
+Note that comparisons can now also raise exceptions. In earlier
+versions of Python, a comparison operation such as \code{cmp(a,b)}
+would always produce an answer, even if a user-defined
+\method{__cmp__} method encountered an error, since the resulting
+exception would simply be silently swallowed.
+
+Work has been done on porting Python to 64-bit Windows on the Itanium
+processor, mostly by Trent Mick of ActiveState.  (Confusingly,
+\code{sys.platform} is still \code{'win32'} on Win64 because it seems
+that for ease of porting, MS Visual \Cpp{} treats code as 32 bit on Itanium.)
+PythonWin also supports Windows CE; see the Python CE page at
+\url{http://starship.python.net/crew/mhammond/ce/} for more
+information.
+
+Another new platform is Darwin/MacOS X; initial support for it is in
+Python 2.0.  Dynamic loading works, if you specify ``configure
+--with-dyld --with-suffix=.x''.  Consult the README in the Python
+source distribution for more instructions.
+
+An attempt has been made to alleviate one of Python's warts, the
+often-confusing \exception{NameError} exception when code refers to a
+local variable before the variable has been assigned a value.  For
+example, the following code raises an exception on the \keyword{print}
+statement in both 1.5.2 and 2.0; in 1.5.2 a \exception{NameError}
+exception is raised, while 2.0 raises a new
+\exception{UnboundLocalError} exception.
+\exception{UnboundLocalError} is a subclass of \exception{NameError},
+so any existing code that expects \exception{NameError} to be raised
+should still work.
+
+\begin{verbatim}
+def f():
+    print "i=",i
+    i = i + 1 
+f()
+\end{verbatim}
+
+Two new exceptions, \exception{TabError} and
+\exception{IndentationError}, have been introduced.  They're both
+subclasses of \exception{SyntaxError}, and are raised when Python code
+is found to be improperly indented.
+
+\subsection{Changes to Built-in Functions}
+
+A new built-in, \function{zip(\var{seq1}, \var{seq2}, ...)}, has been
+added.  \function{zip()} returns a list of tuples where each tuple
+contains the i-th element from each of the argument sequences.  The
+difference between \function{zip()} and \code{map(None, \var{seq1},
+\var{seq2})} is that \function{map()} pads the sequences with
+\code{None} if the sequences aren't all of the same length, while
+\function{zip()} truncates the returned list to the length of the
+shortest argument sequence.
+
+The \function{int()} and \function{long()} functions now accept an
+optional ``base'' parameter when the first argument is a string.
+\code{int('123', 10)} returns 123, while \code{int('123', 16)} returns
+291.  \code{int(123, 16)} raises a \exception{TypeError} exception
+with the message ``can't convert non-string with explicit base''.
+
+A new variable holding more detailed version information has been
+added to the \module{sys} module.  \code{sys.version_info} is a tuple
+\code{(\var{major}, \var{minor}, \var{micro}, \var{level},
+\var{serial})} For example, in a hypothetical 2.0.1beta1,
+\code{sys.version_info} would be \code{(2, 0, 1, 'beta', 1)}.
+\var{level} is a string such as \code{"alpha"}, \code{"beta"}, or
+\code{"final"} for a final release.
+
+Dictionaries have an odd new method, \method{setdefault(\var{key},
+\var{default})}, which behaves similarly to the existing
+\method{get()} method.  However, if the key is missing,
+\method{setdefault()} both returns the value of \var{default} as
+\method{get()} would do, and also inserts it into the dictionary as
+the value for \var{key}.  Thus, the following lines of code:
+
+\begin{verbatim}
+if dict.has_key( key ): return dict[key]
+else: 
+    dict[key] = []
+    return dict[key]
+\end{verbatim}
+
+can be reduced to a single \code{return dict.setdefault(key, [])} statement.
+
+The interpreter sets a maximum recursion depth in order to catch
+runaway recursion before filling the C stack and causing a core dump
+or GPF..  Previously this limit was fixed when you compiled Python,
+but in 2.0 the maximum recursion depth can be read and modified using
+\function{sys.getrecursionlimit} and \function{sys.setrecursionlimit}.
+The default value is 1000, and a rough maximum value for a given
+platform can be found by running a new script,
+\file{Misc/find_recursionlimit.py}.
+
+% ======================================================================
+\section{Porting to 2.0}
+
+New Python releases try hard to be compatible with previous releases,
+and the record has been pretty good.  However, some changes are
+considered useful enough, usually because they fix initial design decisions that
+turned out to be actively mistaken, that breaking backward compatibility
+can't always be avoided.  This section lists the changes in Python 2.0
+that may cause old Python code to break.
+
+The change which will probably break the most code is tightening up
+the arguments accepted by some methods.  Some methods would take
+multiple arguments and treat them as a tuple, particularly various
+list methods such as \method{.append()} and \method{.insert()}.
+In earlier versions of Python, if \code{L} is a list, \code{L.append(
+1,2 )} appends the tuple \code{(1,2)} to the list.  In Python 2.0 this
+causes a \exception{TypeError} exception to be raised, with the
+message: 'append requires exactly 1 argument; 2 given'.  The fix is to
+simply add an extra set of parentheses to pass both values as a tuple: 
+\code{L.append( (1,2) )}.
+
+The earlier versions of these methods were more forgiving because they
+used an old function in Python's C interface to parse their arguments;
+2.0 modernizes them to use \function{PyArg_ParseTuple}, the current
+argument parsing function, which provides more helpful error messages
+and treats multi-argument calls as errors.  If you absolutely must use
+2.0 but can't fix your code, you can edit \file{Objects/listobject.c}
+and define the preprocessor symbol \code{NO_STRICT_LIST_APPEND} to
+preserve the old behaviour; this isn't recommended.
+
+Some of the functions in the \module{socket} module are still
+forgiving in this way.  For example, \function{socket.connect(
+('hostname', 25) )} is the correct form, passing a tuple representing
+an IP address, but \function{socket.connect( 'hostname', 25 )} also
+works. \function{socket.connect_ex()} and \function{socket.bind()} are
+similarly easy-going.  2.0alpha1 tightened these functions up, but
+because the documentation actually used the erroneous multiple
+argument form, many people wrote code which would break with the
+stricter checking.  GvR backed out the changes in the face of public
+reaction, so for the \module{socket} module, the documentation was
+fixed and the multiple argument form is simply marked as deprecated;
+it \emph{will} be tightened up again in a future Python version.
+
+The \code{\e x} escape in string literals now takes exactly 2 hex
+digits.  Previously it would consume all the hex digits following the
+'x' and take the lowest 8 bits of the result, so \code{\e x123456} was
+equivalent to \code{\e x56}.
+
+The \exception{AttributeError} and \exception{NameError} exceptions
+have a more friendly error message, whose text will be something like
+\code{'Spam' instance has no attribute 'eggs'} or \code{name 'eggs' is
+not defined}.  Previously the error message was just the missing
+attribute name \code{eggs}, and code written to take advantage of this
+fact will break in 2.0.
+
+Some work has been done to make integers and long integers a bit more
+interchangeable.  In 1.5.2, large-file support was added for Solaris,
+to allow reading files larger than 2~GiB; this made the \method{tell()}
+method of file objects return a long integer instead of a regular
+integer.  Some code would subtract two file offsets and attempt to use
+the result to multiply a sequence or slice a string, but this raised a
+\exception{TypeError}.  In 2.0, long integers can be used to multiply
+or slice a sequence, and it'll behave as you'd intuitively expect it
+to; \code{3L * 'abc'} produces 'abcabcabc', and \code{
+(0,1,2,3)[2L:4L]} produces (2,3). Long integers can also be used in
+various contexts where previously only integers were accepted, such
+as in the \method{seek()} method of file objects, and in the formats
+supported by the \verb|%| operator (\verb|%d|, \verb|%i|, \verb|%x|,
+etc.).  For example, \code{"\%d" \% 2L**64} will produce the string
+\samp{18446744073709551616}.
+
+The subtlest long integer change of all is that the \function{str()}
+of a long integer no longer has a trailing 'L' character, though
+\function{repr()} still includes it.  The 'L' annoyed many people who
+wanted to print long integers that looked just like regular integers,
+since they had to go out of their way to chop off the character.  This
+is no longer a problem in 2.0, but code which does \code{str(longval)[:-1]} and assumes the 'L' is there, will now lose
+the final digit.
+
+Taking the \function{repr()} of a float now uses a different
+formatting precision than \function{str()}.  \function{repr()} uses
+\code{\%.17g} format string for C's \function{sprintf()}, while
+\function{str()} uses \code{\%.12g} as before.  The effect is that 
+\function{repr()} may occasionally show more decimal places than 
+\function{str()}, for certain numbers. 
+For example, the number 8.1 can't be represented exactly in binary, so
+\code{repr(8.1)} is \code{'8.0999999999999996'}, while str(8.1) is
+\code{'8.1'}.
+
+The \code{-X} command-line option, which turned all standard
+exceptions into strings instead of classes, has been removed; the
+standard exceptions will now always be classes.  The
+\module{exceptions} module containing the standard exceptions was
+translated from Python to a built-in C module, written by Barry Warsaw
+and Fredrik Lundh.
+
+% Commented out for now -- I don't think anyone will care.
+%The pattern and match objects provided by SRE are C types, not Python
+%class instances as in 1.5.  This means you can no longer inherit from
+%\class{RegexObject} or \class{MatchObject}, but that shouldn't be much
+%of a problem since no one should have been doing that in the first
+%place.
+
+% ======================================================================
+\section{Extending/Embedding Changes}
+
+Some of the changes are under the covers, and will only be apparent to
+people writing C extension modules or embedding a Python interpreter
+in a larger application.  If you aren't dealing with Python's C API,
+you can safely skip this section.
+
+The version number of the Python C API was incremented, so C
+extensions compiled for 1.5.2 must be recompiled in order to work with
+2.0.  On Windows, it's not possible for Python 2.0 to import a third
+party extension built for Python 1.5.x due to how Windows DLLs work,
+so Python will raise an exception and the import will fail.
+
+Users of Jim Fulton's ExtensionClass module will be pleased to find
+out that hooks have been added so that ExtensionClasses are now
+supported by \function{isinstance()} and \function{issubclass()}.
+This means you no longer have to remember to write code such as
+\code{if type(obj) == myExtensionClass}, but can use the more natural
+\code{if isinstance(obj, myExtensionClass)}.
+
+The \file{Python/importdl.c} file, which was a mass of \#ifdefs to
+support dynamic loading on many different platforms, was cleaned up
+and reorganised by Greg Stein.  \file{importdl.c} is now quite small,
+and platform-specific code has been moved into a bunch of
+\file{Python/dynload_*.c} files.  Another cleanup: there were also a
+number of \file{my*.h} files in the Include/ directory that held
+various portability hacks; they've been merged into a single file,
+\file{Include/pyport.h}.
+
+Vladimir Marangozov's long-awaited malloc restructuring was completed,
+to make it easy to have the Python interpreter use a custom allocator
+instead of C's standard \function{malloc()}.  For documentation, read
+the comments in \file{Include/pymem.h} and
+\file{Include/objimpl.h}.  For the lengthy discussions during which
+the interface was hammered out, see the Web archives of the 'patches'
+and 'python-dev' lists at python.org.
+
+Recent versions of the GUSI development environment for MacOS support
+POSIX threads.  Therefore, Python's POSIX threading support now works
+on the Macintosh.  Threading support using the user-space GNU \texttt{pth}
+library was also contributed.
+
+Threading support on Windows was enhanced, too.  Windows supports
+thread locks that use kernel objects only in case of contention; in
+the common case when there's no contention, they use simpler functions
+which are an order of magnitude faster.  A threaded version of Python
+1.5.2 on NT is twice as slow as an unthreaded version; with the 2.0
+changes, the difference is only 10\%.  These improvements were
+contributed by Yakov Markovitch.
+
+Python 2.0's source now uses only ANSI C prototypes, so compiling Python now
+requires an ANSI C compiler, and can no longer be done using a compiler that
+only supports K\&R C.  
+
+Previously the Python virtual machine used 16-bit numbers in its
+bytecode, limiting the size of source files.  In particular, this
+affected the maximum size of literal lists and dictionaries in Python
+source; occasionally people who are generating Python code would run
+into this limit.  A patch by Charles G. Waldman raises the limit from
+\verb|2^16| to \verb|2^{32}|.
+
+Three new convenience functions intended for adding constants to a
+module's dictionary at module initialization time were added:
+\function{PyModule_AddObject()}, \function{PyModule_AddIntConstant()},
+and \function{PyModule_AddStringConstant()}.  Each of these functions
+takes a module object, a null-terminated C string containing the name
+to be added, and a third argument for the value to be assigned to the
+name.  This third argument is, respectively, a Python object, a C
+long, or a C string.
+
+A wrapper API was added for \UNIX-style signal handlers.
+\function{PyOS_getsig()} gets a signal handler and
+\function{PyOS_setsig()} will set a new handler.
+
+% ======================================================================
+\section{Distutils: Making Modules Easy to Install}
+
+Before Python 2.0, installing modules was a tedious affair -- there
+was no way to figure out automatically where Python is installed, or
+what compiler options to use for extension modules.  Software authors
+had to go through an arduous ritual of editing Makefiles and
+configuration files, which only really work on \UNIX{} and leave Windows
+and MacOS unsupported.  Python users faced wildly differing
+installation instructions which varied between different extension
+packages, which made administering a Python installation something of 
+a chore.
+
+The SIG for distribution utilities, shepherded by Greg Ward, has
+created the Distutils, a system to make package installation much
+easier.  They form the \module{distutils} package, a new part of
+Python's standard library. In the best case, installing a Python
+module from source will require the same steps: first you simply mean
+unpack the tarball or zip archive, and the run ``\code{python setup.py
+install}''.  The platform will be automatically detected, the compiler
+will be recognized, C extension modules will be compiled, and the
+distribution installed into the proper directory.  Optional
+command-line arguments provide more control over the installation
+process, the distutils package offers many places to override defaults
+-- separating the build from the install, building or installing in
+non-default directories, and more.
+
+In order to use the Distutils, you need to write a \file{setup.py}
+script.  For the simple case, when the software contains only .py
+files, a minimal \file{setup.py} can be just a few lines long:
+
+\begin{verbatim}
+from distutils.core import setup
+setup (name = "foo", version = "1.0", 
+       py_modules = ["module1", "module2"])
+\end{verbatim}
+
+The \file{setup.py} file isn't much more complicated if the software
+consists of a few packages:
+
+\begin{verbatim}
+from distutils.core import setup
+setup (name = "foo", version = "1.0", 
+       packages = ["package", "package.subpackage"])
+\end{verbatim}
+
+A C extension can be the most complicated case; here's an example taken from 
+the PyXML package:
+
+
+\begin{verbatim}
+from distutils.core import setup, Extension
+
+expat_extension = Extension('xml.parsers.pyexpat',
+	define_macros = [('XML_NS', None)],
+	include_dirs = [ 'extensions/expat/xmltok',
+	                 'extensions/expat/xmlparse' ],
+	sources = [ 'extensions/pyexpat.c',
+	            'extensions/expat/xmltok/xmltok.c',
+ 		    'extensions/expat/xmltok/xmlrole.c',
+                  ]
+       )
+setup (name = "PyXML", version = "0.5.4", 
+       ext_modules =[ expat_extension ] )
+\end{verbatim}
+
+The Distutils can also take care of creating source and binary
+distributions.  The ``sdist'' command, run by ``\code{python setup.py
+sdist}', builds a source distribution such as \file{foo-1.0.tar.gz}.
+Adding new commands isn't difficult, ``bdist_rpm'' and
+``bdist_wininst'' commands have already been contributed to create an
+RPM distribution and a Windows installer for the software,
+respectively.  Commands to create other distribution formats such as
+Debian packages and Solaris \file{.pkg} files are in various stages of
+development.
+
+All this is documented in a new manual, \textit{Distributing Python
+Modules}, that joins the basic set of Python documentation.
+
+% ======================================================================
+\section{XML Modules}
+
+Python 1.5.2 included a simple XML parser in the form of the
+\module{xmllib} module, contributed by Sjoerd Mullender.  Since
+1.5.2's release, two different interfaces for processing XML have
+become common: SAX2 (version 2 of the Simple API for XML) provides an
+event-driven interface with some similarities to \module{xmllib}, and
+the DOM (Document Object Model) provides a tree-based interface,
+transforming an XML document into a tree of nodes that can be
+traversed and modified.  Python 2.0 includes a SAX2 interface and a
+stripped-down DOM interface as part of the \module{xml} package.
+Here we will give a brief overview of these new interfaces; consult
+the Python documentation or the source code for complete details.
+The Python XML SIG is also working on improved documentation.
+
+\subsection{SAX2 Support}
+
+SAX defines an event-driven interface for parsing XML.  To use SAX,
+you must write a SAX handler class.  Handler classes inherit from
+various classes provided by SAX, and override various methods that
+will then be called by the XML parser.  For example, the
+\method{startElement} and \method{endElement} methods are called for
+every starting and end tag encountered by the parser, the
+\method{characters()} method is called for every chunk of character
+data, and so forth.
+
+The advantage of the event-driven approach is that the whole
+document doesn't have to be resident in memory at any one time, which
+matters if you are processing really huge documents.  However, writing
+the SAX handler class can get very complicated if you're trying to
+modify the document structure in some elaborate way.
+
+For example, this little example program defines a handler that prints
+a message for every starting and ending tag, and then parses the file
+\file{hamlet.xml} using it:
+
+\begin{verbatim}
+from xml import sax
+
+class SimpleHandler(sax.ContentHandler):
+    def startElement(self, name, attrs):
+        print 'Start of element:', name, attrs.keys()
+
+    def endElement(self, name):
+        print 'End of element:', name
+
+# Create a parser object
+parser = sax.make_parser()
+
+# Tell it what handler to use
+handler = SimpleHandler()
+parser.setContentHandler( handler )
+
+# Parse a file!
+parser.parse( 'hamlet.xml' )
+\end{verbatim}
+
+For more information, consult the Python documentation, or the XML
+HOWTO at \url{http://pyxml.sourceforge.net/topics/howto/xml-howto.html}.
+
+\subsection{DOM Support}
+
+The Document Object Model is a tree-based representation for an XML
+document.  A top-level \class{Document} instance is the root of the
+tree, and has a single child which is the top-level \class{Element}
+instance. This \class{Element} has children nodes representing
+character data and any sub-elements, which may have further children
+of their own, and so forth.  Using the DOM you can traverse the
+resulting tree any way you like, access element and attribute values,
+insert and delete nodes, and convert the tree back into XML.
+
+The DOM is useful for modifying XML documents, because you can create
+a DOM tree, modify it by adding new nodes or rearranging subtrees, and
+then produce a new XML document as output.  You can also construct a
+DOM tree manually and convert it to XML, which can be a more flexible
+way of producing XML output than simply writing
+\code{<tag1>}...\code{</tag1>} to a file.
+
+The DOM implementation included with Python lives in the
+\module{xml.dom.minidom} module.  It's a lightweight implementation of
+the Level 1 DOM with support for XML namespaces.  The 
+\function{parse()} and \function{parseString()} convenience
+functions are provided for generating a DOM tree:
+
+\begin{verbatim}
+from xml.dom import minidom
+doc = minidom.parse('hamlet.xml')
+\end{verbatim}
+
+\code{doc} is a \class{Document} instance.  \class{Document}, like all
+the other DOM classes such as \class{Element} and \class{Text}, is a
+subclass of the \class{Node} base class.  All the nodes in a DOM tree
+therefore support certain common methods, such as \method{toxml()}
+which returns a string containing the XML representation of the node
+and its children.  Each class also has special methods of its own; for
+example, \class{Element} and \class{Document} instances have a method
+to find all child elements with a given tag name.  Continuing from the
+previous 2-line example:
+
+\begin{verbatim}
+perslist = doc.getElementsByTagName( 'PERSONA' )
+print perslist[0].toxml()
+print perslist[1].toxml()
+\end{verbatim}
+
+For the \textit{Hamlet} XML file, the above few lines output:
+
+\begin{verbatim}
+<PERSONA>CLAUDIUS, king of Denmark. </PERSONA>
+<PERSONA>HAMLET, son to the late, and nephew to the present king.</PERSONA>
+\end{verbatim}
+
+The root element of the document is available as
+\code{doc.documentElement}, and its children can be easily modified
+by deleting, adding, or removing nodes:
+
+\begin{verbatim}
+root = doc.documentElement
+
+# Remove the first child
+root.removeChild( root.childNodes[0] )
+
+# Move the new first child to the end
+root.appendChild( root.childNodes[0] )
+
+# Insert the new first child (originally,
+# the third child) before the 20th child.
+root.insertBefore( root.childNodes[0], root.childNodes[20] )
+\end{verbatim}
+
+Again, I will refer you to the Python documentation for a complete
+listing of the different \class{Node} classes and their various methods.
+
+\subsection{Relationship to PyXML}
+
+The XML Special Interest Group has been working on XML-related Python
+code for a while.  Its code distribution, called PyXML, is available
+from the SIG's Web pages at \url{http://www.python.org/sigs/xml-sig/}.
+The PyXML distribution also used the package name \samp{xml}.  If
+you've written programs that used PyXML, you're probably wondering
+about its compatibility with the 2.0 \module{xml} package.
+
+The answer is that Python 2.0's \module{xml} package isn't compatible
+with PyXML, but can be made compatible by installing a recent version
+PyXML.  Many applications can get by with the XML support that is
+included with Python 2.0, but more complicated applications will
+require that the full PyXML package will be installed.  When
+installed, PyXML versions 0.6.0 or greater will replace the
+\module{xml} package shipped with Python, and will be a strict
+superset of the standard package, adding a bunch of additional
+features.  Some of the additional features in PyXML include:
+
+\begin{itemize}
+\item 4DOM, a full DOM implementation
+from FourThought, Inc.
+\item The xmlproc validating parser, written by Lars Marius Garshol.
+\item The \module{sgmlop} parser accelerator module, written by Fredrik Lundh.
+\end{itemize}
+
+% ======================================================================
+\section{Module changes}
+
+Lots of improvements and bugfixes were made to Python's extensive
+standard library; some of the affected modules include
+\module{readline}, \module{ConfigParser}, \module{cgi},
+\module{calendar}, \module{posix}, \module{readline}, \module{xmllib},
+\module{aifc}, \module{chunk, wave}, \module{random}, \module{shelve},
+and \module{nntplib}.  Consult the CVS logs for the exact
+patch-by-patch details.  
+
+Brian Gallew contributed OpenSSL support for the \module{socket}
+module.  OpenSSL is an implementation of the Secure Socket Layer,
+which encrypts the data being sent over a socket.  When compiling
+Python, you can edit \file{Modules/Setup} to include SSL support,
+which adds an additional function to the \module{socket} module:
+\function{socket.ssl(\var{socket}, \var{keyfile}, \var{certfile})},
+which takes a socket object and returns an SSL socket.  The
+\module{httplib} and \module{urllib} modules were also changed to
+support ``https://'' URLs, though no one has implemented FTP or SMTP
+over SSL.  
+
+The \module{httplib} module has been rewritten by Greg Stein to
+support HTTP/1.1.  Backward compatibility with the 1.5 version of
+\module{httplib} is provided, though using HTTP/1.1 features such as
+pipelining will require rewriting code to use a different set of
+interfaces.
+
+The \module{Tkinter} module now supports Tcl/Tk version 8.1, 8.2, or
+8.3, and support for the older 7.x versions has been dropped.  The
+Tkinter module now supports displaying Unicode strings in Tk widgets.
+Also, Fredrik Lundh contributed an optimization which makes operations
+like \code{create_line} and \code{create_polygon} much faster,
+especially when using lots of coordinates.
+
+The \module{curses} module has been greatly extended, starting from
+Oliver Andrich's enhanced version, to provide many additional
+functions from ncurses and SYSV curses, such as colour, alternative
+character set support, pads, and mouse support.  This means the module
+is no longer compatible with operating systems that only have BSD
+curses, but there don't seem to be any currently maintained OSes that
+fall into this category.
+
+As mentioned in the earlier discussion of 2.0's Unicode support, the
+underlying implementation of the regular expressions provided by the
+\module{re} module has been changed.  SRE, a new regular expression
+engine written by Fredrik Lundh and partially funded by Hewlett
+Packard, supports matching against both 8-bit strings and Unicode
+strings.
+
+% ======================================================================
+\section{New modules}
+
+A number of new modules were added.  We'll simply list them with brief
+descriptions; consult the 2.0 documentation for the details of a
+particular module.
+
+\begin{itemize}
+
+\item{\module{atexit}}: 
+For registering functions to be called before the Python interpreter exits.
+Code that currently sets
+\code{sys.exitfunc} directly should be changed to 
+use the \module{atexit} module instead, importing \module{atexit}
+and calling \function{atexit.register()} with 
+the function to be called on exit.
+(Contributed by Skip Montanaro.)
+
+\item{\module{codecs}, \module{encodings}, \module{unicodedata}:}  Added as part of the new Unicode support. 
+
+\item{\module{filecmp}:} Supersedes the old \module{cmp}, \module{cmpcache} and
+\module{dircmp} modules, which have now become deprecated.
+(Contributed by Gordon MacMillan and Moshe Zadka.)
+
+\item{\module{gettext}:} This module provides internationalization
+(I18N) and localization (L10N) support for Python programs by
+providing an interface to the GNU gettext message catalog library.
+(Integrated by Barry Warsaw, from separate contributions by Martin 
+von~L\"owis, Peter Funk, and James Henstridge.)
+
+\item{\module{linuxaudiodev}:} Support for the \file{/dev/audio}
+device on Linux, a twin to the existing \module{sunaudiodev} module.
+(Contributed by Peter Bosch, with fixes by Jeremy Hylton.)
+
+\item{\module{mmap}:} An interface to memory-mapped files on both
+Windows and \UNIX.  A file's contents can be mapped directly into
+memory, at which point it behaves like a mutable string, so its
+contents can be read and modified.  They can even be passed to
+functions that expect ordinary strings, such as the \module{re}
+module. (Contributed by Sam Rushing, with some extensions by
+A.M. Kuchling.)
+
+\item{\module{pyexpat}:} An interface to the Expat XML parser.
+(Contributed by Paul Prescod.)
+
+\item{\module{robotparser}:} Parse a \file{robots.txt} file, which is
+used for writing Web spiders that politely avoid certain areas of a
+Web site.  The parser accepts the contents of a \file{robots.txt} file,
+builds a set of rules from it, and can then answer questions about
+the fetchability of a given URL.  (Contributed by Skip Montanaro.)
+
+\item{\module{tabnanny}:} A module/script to 
+check Python source code for ambiguous indentation.
+(Contributed by Tim Peters.)
+
+\item{\module{UserString}:} A base class useful for deriving objects that behave like strings.  
+
+\item{\module{webbrowser}:} A module that provides a platform independent
+way to launch a web browser on a specific URL. For each platform, various
+browsers are tried in a specific order. The user can alter which browser
+is launched by setting the \var{BROWSER} environment variable. 
+(Originally inspired by Eric S. Raymond's patch to \module{urllib}
+which added similar functionality, but
+the final module comes from code originally 
+implemented by Fred Drake as \file{Tools/idle/BrowserControl.py},
+and adapted for the standard library by Fred.)
+
+\item{\module{_winreg}:} An interface to the
+Windows registry.  \module{_winreg} is an adaptation of functions that
+have been part of PythonWin since 1995, but has now been added to the core 
+distribution, and enhanced to support Unicode.  
+\module{_winreg} was written by Bill Tutt and Mark Hammond.
+
+\item{\module{zipfile}:} A module for reading and writing ZIP-format
+archives.  These are archives produced by \program{PKZIP} on
+DOS/Windows or \program{zip} on \UNIX, not to be confused with
+\program{gzip}-format files (which are supported by the \module{gzip}
+module)
+(Contributed by James C. Ahlstrom.)
+
+\item{\module{imputil}:} A module that provides a simpler way for
+writing customised import hooks, in comparison to the existing
+\module{ihooks} module.  (Implemented by Greg Stein, with much
+discussion on python-dev along the way.)
+
+\end{itemize}
+
+% ======================================================================
+\section{IDLE Improvements}
+
+IDLE is the official Python cross-platform IDE, written using Tkinter.
+Python 2.0 includes IDLE 0.6, which adds a number of new features and
+improvements.  A partial list:
+
+\begin{itemize}
+\item  UI improvements and optimizations,
+especially in the area of syntax highlighting and auto-indentation.
+
+\item The class browser now shows more information, such as the top
+level functions in a module.
+
+\item Tab width is now a user settable option. When opening an existing Python
+file, IDLE automatically detects the indentation conventions, and adapts.
+
+\item There is now support for calling browsers on various platforms,
+used to open the Python documentation in a browser.
+
+\item IDLE now has a command line, which is largely similar to 
+the vanilla Python interpreter.
+
+\item Call tips were added in many places.
+
+\item IDLE can now be installed as a package.
+
+\item In the editor window, there is now a line/column bar at the bottom.
+
+\item Three new keystroke commands: Check module (Alt-F5), Import
+module (F5) and Run script (Ctrl-F5).
+
+\end{itemize}
+
+% ======================================================================
+\section{Deleted and Deprecated Modules}
+
+A few modules have been dropped because they're obsolete, or because
+there are now better ways to do the same thing.  The \module{stdwin}
+module is gone; it was for a platform-independent windowing toolkit
+that's no longer developed.  
+
+A number of modules have been moved to the
+\file{lib-old} subdirectory:
+\module{cmp}, \module{cmpcache}, \module{dircmp}, \module{dump}, 
+\module{find}, \module{grep}, \module{packmail}, 
+\module{poly}, \module{util}, \module{whatsound}, \module{zmod}. 
+If you have code which relies on a module  that's been moved to
+\file{lib-old}, you can simply add that directory to \code{sys.path}  
+to get them back, but you're encouraged to update any code that uses
+these modules.
+
+\section{Acknowledgements}
+
+The authors would like to thank the following people for offering
+suggestions on various drafts of this article: David Bolen, Mark
+Hammond, Gregg Hauser, Jeremy Hylton, Fredrik Lundh, Detlef Lannert,
+Aahz Maruch, Skip Montanaro, Vladimir Marangozov, Tobias Polzin, Guido
+van Rossum, Neil Schemenauer, and Russ Schmidt.
+
+\end{document}

Added: vendor/Python/current/Doc/whatsnew/whatsnew21.tex
===================================================================
--- vendor/Python/current/Doc/whatsnew/whatsnew21.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/whatsnew/whatsnew21.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,868 @@
+\documentclass{howto}
+
+\usepackage{distutils}
+
+% $Id: whatsnew21.tex 50964 2006-07-30 03:03:43Z fred.drake $
+
+\title{What's New in Python 2.1}
+\release{1.01}
+\author{A.M. Kuchling}
+\authoraddress{
+	\strong{Python Software Foundation}\\
+	Email: \email{amk at amk.ca}
+}
+\begin{document}
+\maketitle\tableofcontents
+
+\section{Introduction}
+
+This article explains the new features in Python 2.1.  While there aren't as
+many changes in 2.1 as there were in Python 2.0, there are still some
+pleasant surprises in store.  2.1 is the first release to be steered
+through the use of Python Enhancement Proposals, or PEPs, so most of
+the sizable changes have accompanying PEPs that provide more complete
+documentation and a design rationale for the change.  This article
+doesn't attempt to document the new features completely, but simply
+provides an overview of the new features for Python programmers.
+Refer to the Python 2.1 documentation, or to the specific PEP, for
+more details about any new feature that particularly interests you.
+
+One recent goal of the Python development team has been to accelerate
+the pace of new releases, with a new release coming every 6 to 9
+months. 2.1 is the first release to come out at this faster pace, with
+the first alpha appearing in January, 3 months after the final version
+of 2.0 was released.
+
+The final release of Python 2.1 was made on April 17, 2001.
+
+%======================================================================
+\section{PEP 227: Nested Scopes}
+
+The largest change in Python 2.1 is to Python's scoping rules.  In
+Python 2.0, at any given time there are at most three namespaces used
+to look up variable names: local, module-level, and the built-in
+namespace.  This often surprised people because it didn't match their
+intuitive expectations.  For example, a nested recursive function
+definition doesn't work:
+
+\begin{verbatim}
+def f():
+    ...
+    def g(value):
+        ...
+        return g(value-1) + 1
+    ...
+\end{verbatim}
+
+The function \function{g()} will always raise a \exception{NameError}
+exception, because the binding of the name \samp{g} isn't in either
+its local namespace or in the module-level namespace.  This isn't much
+of a problem in practice (how often do you recursively define interior
+functions like this?), but this also made using the \keyword{lambda}
+statement clumsier, and this was a problem in practice.  In code which
+uses \keyword{lambda} you can often find local variables being copied
+by passing them as the default values of arguments.
+
+\begin{verbatim}
+def find(self, name):
+    "Return list of any entries equal to 'name'"
+    L = filter(lambda x, name=name: x == name,
+               self.list_attribute)
+    return L
+\end{verbatim}
+
+The readability of Python code written in a strongly functional style
+suffers greatly as a result.
+
+The most significant change to Python 2.1 is that static scoping has
+been added to the language to fix this problem.  As a first effect,
+the \code{name=name} default argument is now unnecessary in the above
+example.  Put simply, when a given variable name is not assigned a
+value within a function (by an assignment, or the \keyword{def},
+\keyword{class}, or \keyword{import} statements), references to the
+variable will be looked up in the local namespace of the enclosing
+scope.  A more detailed explanation of the rules, and a dissection of
+the implementation, can be found in the PEP.
+
+This change may cause some compatibility problems for code where the
+same variable name is used both at the module level and as a local
+variable within a function that contains further function definitions.
+This seems rather unlikely though, since such code would have been
+pretty confusing to read in the first place.  
+
+One side effect of the change is that the \code{from \var{module}
+import *} and \keyword{exec} statements have been made illegal inside
+a function scope under certain conditions.  The Python reference
+manual has said all along that \code{from \var{module} import *} is
+only legal at the top level of a module, but the CPython interpreter
+has never enforced this before.  As part of the implementation of
+nested scopes, the compiler which turns Python source into bytecodes
+has to generate different code to access variables in a containing
+scope.  \code{from \var{module} import *} and \keyword{exec} make it
+impossible for the compiler to figure this out, because they add names
+to the local namespace that are unknowable at compile time.
+Therefore, if a function contains function definitions or
+\keyword{lambda} expressions with free variables, the compiler will
+flag this by raising a \exception{SyntaxError} exception.
+
+To make the preceding explanation a bit clearer, here's an example:
+
+\begin{verbatim}
+x = 1
+def f():
+    # The next line is a syntax error
+    exec 'x=2'  
+    def g():
+        return x
+\end{verbatim}
+
+Line 4 containing the \keyword{exec} statement is a syntax error,
+since \keyword{exec} would define a new local variable named \samp{x}
+whose value should be accessed by \function{g()}.  
+
+This shouldn't be much of a limitation, since \keyword{exec} is rarely
+used in most Python code (and when it is used, it's often a sign of a
+poor design anyway).
+
+Compatibility concerns have led to nested scopes being introduced
+gradually; in Python 2.1, they aren't enabled by default, but can be
+turned on within a module by using a future statement as described in
+PEP 236.  (See the following section for further discussion of PEP
+236.)  In Python 2.2, nested scopes will become the default and there
+will be no way to turn them off, but users will have had all of 2.1's
+lifetime to fix any breakage resulting from their introduction.
+
+\begin{seealso}
+
+\seepep{227}{Statically Nested Scopes}{Written and implemented by
+Jeremy Hylton.}
+
+\end{seealso}
+
+
+%======================================================================
+\section{PEP 236: __future__ Directives}
+
+The reaction to nested scopes was widespread concern about the dangers
+of breaking code with the 2.1 release, and it was strong enough to
+make the Pythoneers take a more conservative approach.  This approach
+consists of introducing a convention for enabling optional
+functionality in release N that will become compulsory in release N+1.  
+
+The syntax uses a \code{from...import} statement using the reserved
+module name \module{__future__}.  Nested scopes can be enabled by the
+following statement:
+
+\begin{verbatim}
+from __future__ import nested_scopes
+\end{verbatim}
+
+While it looks like a normal \keyword{import} statement, it's not;
+there are strict rules on where such a future statement can be put.
+They can only be at the top of a module, and must precede any Python
+code or regular \keyword{import} statements.  This is because such
+statements can affect how the Python bytecode compiler parses code and
+generates bytecode, so they must precede any statement that will
+result in bytecodes being produced.
+
+\begin{seealso}
+
+\seepep{236}{Back to the \module{__future__}}{Written by Tim Peters,
+and primarily implemented by Jeremy Hylton.}
+
+\end{seealso}
+
+%======================================================================
+\section{PEP 207: Rich Comparisons}
+
+In earlier versions, Python's support for implementing comparisons on
+user-defined classes and extension types was quite simple. Classes
+could implement a \method{__cmp__} method that was given two instances
+of a class, and could only return 0 if they were equal or +1 or -1 if
+they weren't; the method couldn't raise an exception or return
+anything other than a Boolean value.  Users of Numeric Python often
+found this model too weak and restrictive, because in the
+number-crunching programs that numeric Python is used for, it would be
+more useful to be able to perform elementwise comparisons of two
+matrices, returning a matrix containing the results of a given
+comparison for each element.  If the two matrices are of different
+sizes, then the compare has to be able to raise an exception to signal
+the error.
+
+In Python 2.1, rich comparisons were added in order to support this
+need.  Python classes can now individually overload each of the
+\code{<}, \code{<=}, \code{>}, \code{>=}, \code{==}, and \code{!=}
+operations.  The new magic method names are:
+
+\begin{tableii}{c|l}{code}{Operation}{Method name}
+  \lineii{<}{\method{__lt__}} \lineii{<=}{\method{__le__}}
+  \lineii{>}{\method{__gt__}} \lineii{>=}{\method{__ge__}}
+  \lineii{==}{\method{__eq__}} \lineii{!=}{\method{__ne__}}
+  \end{tableii}
+
+(The magic methods are named after the corresponding Fortran operators
+\code{.LT.}. \code{.LE.}, \&c.  Numeric programmers are almost
+certainly quite familiar with these names and will find them easy to
+remember.)
+ 
+Each of these magic methods is of the form \code{\var{method}(self,
+other)}, where \code{self} will be the object on the left-hand side of
+the operator, while \code{other} will be the object on the right-hand
+side.  For example, the expression \code{A < B} will cause
+\code{A.__lt__(B)} to be called.
+
+Each of these magic methods can return anything at all: a Boolean, a
+matrix, a list, or any other Python object.  Alternatively they can
+raise an exception if the comparison is impossible, inconsistent, or
+otherwise meaningless.
+
+The built-in \function{cmp(A,B)} function can use the rich comparison
+machinery, and now accepts an optional argument specifying which
+comparison operation to use; this is given as one of the strings
+\code{"<"}, \code{"<="}, \code{">"}, \code{">="}, \code{"=="}, or
+\code{"!="}.  If called without the optional third argument,
+\function{cmp()} will only return -1, 0, or +1 as in previous versions
+of Python; otherwise it will call the appropriate method and can
+return any Python object.
+
+There are also corresponding changes of interest to C programmers;
+there's a new slot \code{tp_richcmp} in type objects and an API for
+performing a given rich comparison.  I won't cover the C API here, but
+will refer you to PEP 207, or to 2.1's C API documentation, for the
+full list of related functions.
+
+\begin{seealso}
+
+\seepep{207}{Rich Comparisions}{Written by Guido van Rossum, heavily
+based on earlier work by David Ascher, and implemented by Guido van
+Rossum.}
+
+\end{seealso}
+
+%======================================================================
+\section{PEP 230: Warning Framework}
+
+Over its 10 years of existence, Python has accumulated a certain
+number of obsolete modules and features along the way.  It's difficult
+to know when a feature is safe to remove, since there's no way of
+knowing how much code uses it --- perhaps no programs depend on the
+feature, or perhaps many do.  To enable removing old features in a
+more structured way, a warning framework was added.  When the Python
+developers want to get rid of a feature, it will first trigger a
+warning in the next version of Python.  The following Python version
+can then drop the feature, and users will have had a full release
+cycle to remove uses of the old feature.
+
+Python 2.1 adds the warning framework to be used in this scheme.  It
+adds a \module{warnings} module that provide functions to issue
+warnings, and to filter out warnings that you don't want to be
+displayed. Third-party modules can also use this framework to
+deprecate old features that they no longer wish to support.
+
+For example, in Python 2.1 the \module{regex} module is deprecated, so
+importing it causes a warning to be printed:
+
+\begin{verbatim}
+>>> import regex
+__main__:1: DeprecationWarning: the regex module
+         is deprecated; please use the re module
+>>>
+\end{verbatim}
+
+Warnings can be issued by calling the \function{warnings.warn}
+function:
+
+\begin{verbatim}
+warnings.warn("feature X no longer supported")
+\end{verbatim}
+
+The first parameter is the warning message; an additional optional
+parameters can be used to specify a particular warning category.
+
+Filters can be added to disable certain warnings; a regular expression
+pattern can be applied to the message or to the module name in order
+to suppress a warning.  For example, you may have a program that uses
+the \module{regex} module and not want to spare the time to convert it
+to use the \module{re} module right now.  The warning can be
+suppressed by calling
+
+\begin{verbatim}
+import warnings
+warnings.filterwarnings(action = 'ignore',
+                        message='.*regex module is deprecated',
+                        category=DeprecationWarning,
+                        module = '__main__')
+\end{verbatim}
+
+This adds a filter that will apply only to warnings of the class
+\class{DeprecationWarning} triggered in the \module{__main__} module,
+and applies a regular expression to only match the message about the
+\module{regex} module being deprecated, and will cause such warnings
+to be ignored.  Warnings can also be printed only once, printed every
+time the offending code is executed, or turned into exceptions that
+will cause the program to stop (unless the exceptions are caught in
+the usual way, of course).
+
+Functions were also added to Python's C API for issuing warnings;
+refer to PEP 230 or to Python's API documentation for the details.
+
+\begin{seealso} 
+
+\seepep{5}{Guidelines for Language Evolution}{Written
+by Paul Prescod, to specify procedures to be followed when removing
+old features from Python.  The policy described in this PEP hasn't
+been officially adopted, but the eventual policy probably won't be too
+different from Prescod's proposal.}
+
+\seepep{230}{Warning Framework}{Written and implemented by Guido van
+Rossum.}
+
+\end{seealso}
+    
+%======================================================================
+\section{PEP 229: New Build System}
+
+When compiling Python, the user had to go in and edit the
+\file{Modules/Setup} file in order to enable various additional
+modules; the default set is relatively small and limited to modules
+that compile on most \UNIX{} platforms.  This means that on \Unix{}
+platforms with many more features, most notably Linux, Python
+installations often don't contain all useful modules they could.
+
+Python 2.0 added the Distutils, a set of modules for distributing and
+installing extensions.  In Python 2.1, the Distutils are used to
+compile much of the standard library of extension modules,
+autodetecting which ones are supported on the current machine.  It's
+hoped that this will make Python installations easier and more
+featureful.
+
+Instead of having to edit the \file{Modules/Setup} file in order to
+enable modules, a \file{setup.py} script in the top directory of the
+Python source distribution is run at build time, and attempts to
+discover which modules can be enabled by examining the modules and
+header files on the system.  If a module is configured in
+\file{Modules/Setup}, the \file{setup.py} script won't attempt to
+compile that module and will defer to the \file{Modules/Setup} file's
+contents.  This provides a way to specific any strange command-line
+flags or libraries that are required for a specific platform.
+
+In another far-reaching change to the build mechanism, Neil
+Schemenauer restructured things so Python now uses a single makefile
+that isn't recursive, instead of makefiles in the top directory and in
+each of the \file{Python/}, \file{Parser/}, \file{Objects/}, and
+\file{Modules/} subdirectories.  This makes building Python faster
+and also makes hacking the Makefiles clearer and simpler.
+
+\begin{seealso} 
+
+\seepep{229}{Using Distutils to Build Python}{Written
+and implemented by A.M. Kuchling.}
+
+\end{seealso}
+
+%======================================================================
+\section{PEP 205: Weak References}
+
+Weak references, available through the \module{weakref} module, are a
+minor but useful new data type in the Python programmer's toolbox.
+
+Storing a reference to an object (say, in a dictionary or a list) has
+the side effect of keeping that object alive forever.  There are a few
+specific cases where this behaviour is undesirable, object caches
+being the most common one, and another being circular references in
+data structures such as trees.
+
+For example, consider a memoizing function that caches the results of
+another function \function{f(\var{x})} by storing the function's
+argument and its result in a dictionary:
+
+\begin{verbatim}
+_cache = {}
+def memoize(x):
+    if _cache.has_key(x):
+        return _cache[x]
+
+    retval = f(x)
+
+    # Cache the returned object
+    _cache[x] = retval
+
+    return retval
+\end{verbatim}
+
+This version works for simple things such as integers, but it has a
+side effect; the \code{_cache} dictionary holds a reference to the
+return values, so they'll never be deallocated until the Python
+process exits and cleans up This isn't very noticeable for integers,
+but if \function{f()} returns an object, or a data structure that
+takes up a lot of memory, this can be a problem.
+
+Weak references provide a way to implement a cache that won't keep
+objects alive beyond their time.  If an object is only accessible
+through weak references, the object will be deallocated and the weak
+references will now indicate that the object it referred to no longer
+exists.  A weak reference to an object \var{obj} is created by calling
+\code{wr = weakref.ref(\var{obj})}.  The object being referred to is
+returned by calling the weak reference as if it were a function:
+\code{wr()}.  It will return the referenced object, or \code{None} if
+the object no longer exists. 
+
+This makes it possible to write a \function{memoize()} function whose
+cache doesn't keep objects alive, by storing weak references in the
+cache.
+
+\begin{verbatim}
+_cache = {}
+def memoize(x):
+    if _cache.has_key(x):
+        obj = _cache[x]()
+        # If weak reference object still exists,
+        # return it
+        if obj is not None: return obj
+ 
+    retval = f(x)
+
+    # Cache a weak reference
+    _cache[x] = weakref.ref(retval)
+
+    return retval
+\end{verbatim}
+
+The \module{weakref} module also allows creating proxy objects which
+behave like weak references --- an object referenced only by proxy
+objects is deallocated -- but instead of requiring an explicit call to
+retrieve the object, the proxy transparently forwards all operations
+to the object as long as the object still exists.  If the object is
+deallocated, attempting to use a proxy will cause a
+\exception{weakref.ReferenceError} exception to be raised.
+
+\begin{verbatim}
+proxy = weakref.proxy(obj)
+proxy.attr   # Equivalent to obj.attr
+proxy.meth() # Equivalent to obj.meth()
+del obj
+proxy.attr   # raises weakref.ReferenceError
+\end{verbatim}
+
+\begin{seealso}
+
+\seepep{205}{Weak References}{Written and implemented by
+Fred~L. Drake,~Jr.}
+
+\end{seealso}
+
+%======================================================================
+\section{PEP 232: Function Attributes}
+
+In Python 2.1, functions can now have arbitrary information attached
+to them.  People were often using docstrings to hold information about
+functions and methods, because the \code{__doc__} attribute was the
+only way of attaching any information to a function.  For example, in
+the Zope Web application server, functions are marked as safe for
+public access by having a docstring, and in John Aycock's SPARK
+parsing framework, docstrings hold parts of the BNF grammar to be
+parsed.  This overloading is unfortunate, since docstrings are really
+intended to hold a function's documentation; for example, it means you
+can't properly document functions intended for private use in Zope.
+
+Arbitrary attributes can now be set and retrieved on functions using the
+regular Python syntax:
+
+\begin{verbatim}
+def f(): pass
+
+f.publish = 1
+f.secure = 1
+f.grammar = "A ::= B (C D)*"
+\end{verbatim}
+
+The dictionary containing attributes can be accessed as the function's
+\member{__dict__}. Unlike the \member{__dict__} attribute of class
+instances, in functions you can actually assign a new dictionary to
+\member{__dict__}, though the new value is restricted to a regular
+Python dictionary; you \emph{can't} be tricky and set it to a
+\class{UserDict} instance, or any other random object that behaves
+like a mapping.
+
+\begin{seealso}
+
+\seepep{232}{Function Attributes}{Written and implemented by Barry
+Warsaw.}
+
+\end{seealso}
+
+
+%======================================================================
+
+\section{PEP 235: Importing Modules on Case-Insensitive Platforms}
+
+Some operating systems have filesystems that are case-insensitive,
+MacOS and Windows being the primary examples; on these systems, it's
+impossible to distinguish the filenames \samp{FILE.PY} and
+\samp{file.py}, even though they do store the file's name 
+in its original case (they're case-preserving, too).
+
+In Python 2.1, the \keyword{import} statement will work to simulate
+case-sensitivity on case-insensitive platforms.  Python will now
+search for the first case-sensitive match by default, raising an
+\exception{ImportError} if no such file is found, so \code{import file}
+will not import a module named \samp{FILE.PY}.  Case-insensitive
+matching can be requested by setting the \envvar{PYTHONCASEOK} environment
+variable before starting the Python interpreter.
+
+%======================================================================
+\section{PEP 217: Interactive Display Hook}
+
+When using the Python interpreter interactively, the output of
+commands is displayed using the built-in \function{repr()} function.
+In Python 2.1, the variable \function{sys.displayhook} can be set to a
+callable object which will be called instead of \function{repr()}.
+For example, you can set it to a special pretty-printing function:
+
+\begin{verbatim}
+>>> # Create a recursive data structure
+... L = [1,2,3]
+>>> L.append(L)
+>>> L # Show Python's default output
+[1, 2, 3, [...]]
+>>> # Use pprint.pprint() as the display function
+... import sys, pprint
+>>> sys.displayhook = pprint.pprint
+>>> L
+[1, 2, 3,  <Recursion on list with id=135143996>]
+>>>
+\end{verbatim}
+
+\begin{seealso}
+
+\seepep{217}{Display Hook for Interactive Use}{Written and implemented
+by Moshe Zadka.}
+
+\end{seealso}
+
+%======================================================================
+\section{PEP 208: New Coercion Model}
+
+How numeric coercion is done at the C level was significantly
+modified.  This will only affect the authors of C extensions to
+Python, allowing them more flexibility in writing extension types that
+support numeric operations.
+
+Extension types can now set the type flag \code{Py_TPFLAGS_CHECKTYPES}
+in their \code{PyTypeObject} structure to indicate that they support
+the new coercion model.  In such extension types, the numeric slot
+functions can no longer assume that they'll be passed two arguments of
+the same type; instead they may be passed two arguments of differing
+types, and can then perform their own internal coercion.  If the slot
+function is passed a type it can't handle, it can indicate the failure
+by returning a reference to the \code{Py_NotImplemented} singleton
+value.  The numeric functions of the other type will then be tried,
+and perhaps they can handle the operation; if the other type also
+returns \code{Py_NotImplemented}, then a \exception{TypeError} will be
+raised.  Numeric methods written in Python can also return
+\code{Py_NotImplemented}, causing the interpreter to act as if the
+method did not exist (perhaps raising a \exception{TypeError}, perhaps
+trying another object's numeric methods).
+
+\begin{seealso}
+
+\seepep{208}{Reworking the Coercion Model}{Written and implemented by
+Neil Schemenauer, heavily based upon earlier work by Marc-Andr\'e
+Lemburg.  Read this to understand the fine points of how numeric
+operations will now be processed at the C level.}
+
+\end{seealso}
+
+%======================================================================
+\section{PEP 241: Metadata in Python Packages}
+
+A common complaint from Python users is that there's no single catalog
+of all the Python modules in existence.  T.~Middleton's Vaults of
+Parnassus at \url{http://www.vex.net/parnassus/} are the largest
+catalog of Python modules, but registering software at the Vaults is
+optional, and many people don't bother.
+
+As a first small step toward fixing the problem, Python software
+packaged using the Distutils \command{sdist} command will include a
+file named \file{PKG-INFO} containing information about the package
+such as its name, version, and author (metadata, in cataloguing
+terminology).  PEP 241 contains the full list of fields that can be
+present in the \file{PKG-INFO} file.  As people began to package their
+software using Python 2.1, more and more packages will include
+metadata, making it possible to build automated cataloguing systems
+and experiment with them.  With the result experience, perhaps it'll
+be possible to design a really good catalog and then build support for
+it into Python 2.2.  For example, the Distutils \command{sdist}
+and \command{bdist_*} commands could support a \option{upload} option
+that would automatically upload your package to a catalog server. 
+
+You can start creating packages containing \file{PKG-INFO} even if
+you're not using Python 2.1, since a new release of the Distutils will
+be made for users of earlier Python versions.  Version 1.0.2 of the
+Distutils includes the changes described in PEP 241, as well as
+various bugfixes and enhancements.  It will be available from 
+the Distutils SIG at \url{http://www.python.org/sigs/distutils-sig/}.
+
+\begin{seealso}
+
+\seepep{241}{Metadata for Python Software Packages}{Written and
+implemented by A.M. Kuchling.}
+
+\seepep{243}{Module Repository Upload Mechanism}{Written by Sean
+Reifschneider, this draft PEP describes a proposed mechanism for uploading 
+Python packages to a central server.
+}
+
+\end{seealso}
+
+%======================================================================
+\section{New and Improved Modules}
+
+\begin{itemize}
+
+\item Ka-Ping Yee contributed two new modules: \module{inspect.py}, a
+module for getting information about live Python code, and
+\module{pydoc.py}, a module for interactively converting docstrings to
+HTML or text.  As a bonus, \file{Tools/scripts/pydoc}, which is now
+automatically installed, uses \module{pydoc.py} to display
+documentation given a Python module, package, or class name.  For
+example, \samp{pydoc xml.dom} displays the following:
+
+\begin{verbatim}
+Python Library Documentation: package xml.dom in xml
+ 
+NAME
+    xml.dom - W3C Document Object Model implementation for Python.
+ 
+FILE
+    /usr/local/lib/python2.1/xml/dom/__init__.pyc
+ 
+DESCRIPTION
+    The Python mapping of the Document Object Model is documented in the
+    Python Library Reference in the section on the xml.dom package.
+ 
+    This package contains the following modules:
+      ...
+\end{verbatim}
+
+\file{pydoc} also includes a Tk-based interactive help browser.  
+\file{pydoc} quickly becomes addictive; try it out!
+
+\item Two different modules for unit testing were added to the
+standard library.  The \module{doctest} module, contributed by Tim
+Peters, provides a testing framework based on running embedded
+examples in docstrings and comparing the results against the expected
+output.  PyUnit, contributed by Steve Purcell, is a unit testing
+framework inspired by JUnit, which was in turn an adaptation of Kent
+Beck's Smalltalk testing framework.  See
+\url{http://pyunit.sourceforge.net/} for more information about
+PyUnit.
+
+\item The \module{difflib} module contains a class,
+\class{SequenceMatcher}, which compares two sequences and computes the
+changes required to transform one sequence into the other.  For
+example, this module can be used to write a tool similar to the \UNIX{}
+\program{diff} program, and in fact the sample program
+\file{Tools/scripts/ndiff.py} demonstrates how to write such a script.  
+
+\item \module{curses.panel}, a wrapper for the panel library, part of
+ncurses and of SYSV curses, was contributed by Thomas Gellekum.  The
+panel library provides windows with the additional feature of depth.
+Windows can be moved higher or lower in the depth ordering, and the
+panel library figures out where panels overlap and which sections are
+visible.
+
+\item The PyXML package has gone through a few releases since Python
+2.0, and Python 2.1 includes an updated version of the \module{xml}
+package.  Some of the noteworthy changes include support for Expat 1.2
+and later versions, the ability for Expat parsers to handle files in
+any encoding supported by Python, and various bugfixes for SAX, DOM,
+and the \module{minidom} module.
+
+\item Ping also contributed another hook for handling uncaught
+exceptions.  \function{sys.excepthook} can be set to a callable
+object.  When an exception isn't caught by any
+\keyword{try}...\keyword{except} blocks, the exception will be passed
+to \function{sys.excepthook}, which can then do whatever it likes.  At
+the Ninth Python Conference, Ping demonstrated an application for this
+hook: printing an extended traceback that not only lists the stack
+frames, but also lists the function arguments and the local variables
+for each frame.  
+
+\item Various functions in the \module{time} module, such as
+\function{asctime()} and \function{localtime()}, require a floating
+point argument containing the time in seconds since the epoch.  The
+most common use of these functions is to work with the current time,
+so the floating point argument has been made optional; when a value
+isn't provided, the current time will be used.  For example, log file
+entries usually need a string containing the current time; in Python
+2.1, \code{time.asctime()} can be used, instead of the lengthier
+\code{time.asctime(time.localtime(time.time()))} that was previously
+required.
+ 
+This change was proposed and implemented by Thomas Wouters.
+
+\item The \module{ftplib} module now defaults to retrieving files in
+passive mode, because passive mode is more likely to work from behind
+a firewall.  This request came from the Debian bug tracking system,
+since other Debian packages use \module{ftplib} to retrieve files and
+then don't work from behind a firewall.  It's deemed unlikely that
+this will cause problems for anyone, because Netscape defaults to
+passive mode and few people complain, but if passive mode is
+unsuitable for your application or network setup, call
+\method{set_pasv(0)} on FTP objects to disable passive mode.
+
+\item Support for raw socket access has been added to the
+\module{socket} module, contributed by Grant Edwards.
+
+\item The \module{pstats} module now contains a simple interactive
+statistics browser for displaying timing profiles for Python programs,
+invoked when the module is run as a script.  Contributed by 
+Eric S.\ Raymond.
+
+\item A new implementation-dependent function, \function{sys._getframe(\optional{depth})},
+has been added to return a given frame object from the current call stack.
+\function{sys._getframe()} returns the frame at the top of the call stack; 
+if the optional integer argument \var{depth} is supplied, the function returns the frame
+that is \var{depth} calls below the top of the stack.  For example, \code{sys._getframe(1)}
+returns the caller's frame object.
+
+This function is only present in CPython, not in Jython or the .NET
+implementation.  Use it for debugging, and resist the temptation to
+put it into production code.
+
+
+
+\end{itemize}
+
+%======================================================================
+\section{Other Changes and Fixes}
+
+There were relatively few smaller changes made in Python 2.1 due to
+the shorter release cycle.  A search through the CVS change logs turns
+up 117 patches applied, and 136 bugs fixed; both figures are likely to
+be underestimates.  Some of the more notable changes are:
+
+\begin{itemize}
+
+
+\item A specialized object allocator is now optionally available, that
+should be faster than the system \function{malloc()} and have less
+memory overhead.  The allocator uses C's \function{malloc()} function
+to get large pools of memory, and then fulfills smaller memory
+requests from these pools.  It can be enabled by providing the
+\longprogramopt{with-pymalloc} option to the \program{configure} script; see
+\file{Objects/obmalloc.c} for the implementation details.  
+
+Authors of C extension modules should test their code with the object
+allocator enabled, because some incorrect code may break, causing core
+dumps at runtime.  There are a bunch of memory allocation functions in
+Python's C API that have previously been just aliases for the C
+library's \function{malloc()} and \function{free()}, meaning that if
+you accidentally called mismatched functions, the error wouldn't be
+noticeable.  When the object allocator is enabled, these functions
+aren't aliases of \function{malloc()} and \function{free()} any more,
+and calling the wrong function to free memory will get you a core
+dump.  For example, if memory was allocated using
+\function{PyMem_New()}, it has to be freed using
+\function{PyMem_Del()}, not \function{free()}.  A few modules included
+with Python fell afoul of this and had to be fixed; doubtless there
+are more third-party modules that will have the same problem.
+
+The object allocator was contributed by Vladimir Marangozov.
+
+\item The speed of line-oriented file I/O has been improved because
+people often complain about its lack of speed, and because it's often
+been used as a na\"ive benchmark.  The \method{readline()} method of
+file objects has therefore been rewritten to be much faster.  The
+exact amount of the speedup will vary from platform to platform
+depending on how slow the C library's \function{getc()} was, but is
+around 66\%, and potentially much faster on some particular operating
+systems.  Tim Peters did much of the benchmarking and coding for this
+change, motivated by a discussion in comp.lang.python.
+
+A new module and method for file objects was also added, contributed
+by Jeff Epler. The new method, \method{xreadlines()}, is similar to
+the existing \function{xrange()} built-in.  \function{xreadlines()}
+returns an opaque sequence object that only supports being iterated
+over, reading a line on every iteration but not reading the entire
+file into memory as the existing \method{readlines()} method does.
+You'd use it like this:
+
+\begin{verbatim}
+for line in sys.stdin.xreadlines():
+    # ... do something for each line ...
+    ...
+\end{verbatim}
+
+For a fuller discussion of the line I/O changes, see the python-dev
+summary for January 1-15, 2001 at
+\url{http://www.python.org/dev/summary/2001-01-1.html}.
+
+\item A new method, \method{popitem()}, was added to dictionaries to
+enable destructively iterating through the contents of a dictionary;
+this can be faster for large dictionaries because there's no need to
+construct a list containing all the keys or values.
+\code{D.popitem()} removes a random \code{(\var{key}, \var{value})}
+pair from the dictionary~\code{D} and returns it as a 2-tuple.  This
+was implemented mostly by Tim Peters and Guido van Rossum, after a
+suggestion and preliminary patch by Moshe Zadka.
+ 
+\item Modules can now control which names are imported when \code{from
+\var{module} import *} is used, by defining an \code{__all__}
+attribute containing a list of names that will be imported.  One
+common complaint is that if the module imports other modules such as
+\module{sys} or \module{string}, \code{from \var{module} import *}
+will add them to the importing module's namespace.  To fix this,
+simply list the public names in \code{__all__}:
+
+\begin{verbatim}
+# List public names
+__all__ = ['Database', 'open']
+\end{verbatim}
+
+A stricter version of this patch was first suggested and implemented
+by Ben Wolfson, but after some python-dev discussion, a weaker final
+version was checked in.
+
+\item Applying \function{repr()} to strings previously used octal
+escapes for non-printable characters; for example, a newline was
+\code{'\e 012'}.  This was a vestigial trace of Python's C ancestry, but
+today octal is of very little practical use.  Ka-Ping Yee suggested
+using hex escapes instead of octal ones, and using the \code{\e n},
+\code{\e t}, \code{\e r} escapes for the appropriate characters, and
+implemented this new formatting.
+
+\item Syntax errors detected at compile-time can now raise exceptions
+containing the filename and line number of the error, a pleasant side
+effect of the compiler reorganization done by Jeremy Hylton.
+
+\item C extensions which import other modules have been changed to use
+\function{PyImport_ImportModule()}, which means that they will use any
+import hooks that have been installed.  This is also encouraged for
+third-party extensions that need to import some other module from C
+code.  
+
+\item The size of the Unicode character database was shrunk by another
+340K thanks to Fredrik Lundh.
+
+\item Some new ports were contributed: MacOS X (by Steven Majewski),
+Cygwin (by Jason Tishler); RISCOS (by Dietmar Schwertberger); Unixware~7 
+(by Billy G. Allie).
+
+\end{itemize}
+
+And there's the usual list of minor bugfixes, minor memory leaks,
+docstring edits, and other tweaks, too lengthy to be worth itemizing;
+see the CVS logs for the full details if you want them.
+
+
+%======================================================================
+\section{Acknowledgements}
+
+The author would like to thank the following people for offering
+suggestions on various drafts of this article: Graeme Cross, David
+Goodger, Jay Graves, Michael Hudson, Marc-Andr\'e Lemburg, Fredrik
+Lundh, Neil Schemenauer, Thomas Wouters.
+
+\end{document}

Added: vendor/Python/current/Doc/whatsnew/whatsnew22.tex
===================================================================
--- vendor/Python/current/Doc/whatsnew/whatsnew22.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/whatsnew/whatsnew22.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1466 @@
+\documentclass{howto}
+
+% $Id: whatsnew22.tex 37315 2004-09-10 19:33:00Z akuchling $
+
+\title{What's New in Python 2.2}
+\release{1.02}
+\author{A.M. Kuchling}
+\authoraddress{
+	\strong{Python Software Foundation}\\
+	Email: \email{amk at amk.ca}
+}
+\begin{document}
+\maketitle\tableofcontents
+
+\section{Introduction}
+
+This article explains the new features in Python 2.2.2, released on
+October 14, 2002.  Python 2.2.2 is a bugfix release of Python 2.2,
+originally released on December 21, 2001.
+
+Python 2.2 can be thought of as the "cleanup release".  There are some
+features such as generators and iterators that are completely new, but
+most of the changes, significant and far-reaching though they may be,
+are aimed at cleaning up irregularities and dark corners of the
+language design.
+
+This article doesn't attempt to provide a complete specification of
+the new features, but instead provides a convenient overview.  For
+full details, you should refer to the documentation for Python 2.2,
+such as the
+\citetitle[http://www.python.org/doc/2.2/lib/lib.html]{Python
+Library Reference} and the
+\citetitle[http://www.python.org/doc/2.2/ref/ref.html]{Python
+Reference Manual}.  If you want to understand the complete
+implementation and design rationale for a change, refer to the PEP for
+a particular new feature.
+
+\begin{seealso}
+
+\seeurl{http://www.unixreview.com/documents/s=1356/urm0109h/0109h.htm}
+{``What's So Special About Python 2.2?'' is also about the new 2.2
+features, and was written by Cameron Laird and Kathryn Soraiz.}
+
+\end{seealso}
+
+
+%======================================================================
+\section{PEPs 252 and 253: Type and Class Changes}
+
+The largest and most far-reaching changes in Python 2.2 are to
+Python's model of objects and classes.  The changes should be backward
+compatible, so it's likely that your code will continue to run
+unchanged, but the changes provide some amazing new capabilities.
+Before beginning this, the longest and most complicated section of
+this article, I'll provide an overview of the changes and offer some
+comments.
+
+A long time ago I wrote a Web page
+(\url{http://www.amk.ca/python/writing/warts.html}) listing flaws in
+Python's design.  One of the most significant flaws was that it's
+impossible to subclass Python types implemented in C.  In particular,
+it's not possible to subclass built-in types, so you can't just
+subclass, say, lists in order to add a single useful method to them.
+The \module{UserList} module provides a class that supports all of the
+methods of lists and that can be subclassed further, but there's lots
+of C code that expects a regular Python list and won't accept a
+\class{UserList} instance.
+
+Python 2.2 fixes this, and in the process adds some exciting new
+capabilities.  A brief summary:
+
+\begin{itemize}
+
+\item You can subclass built-in types such as lists and even integers,
+and your subclasses should work in every place that requires the
+original type.
+
+\item It's now possible to define static and class methods, in addition
+to the instance methods available in previous versions of Python.
+
+\item It's also possible to automatically call methods on accessing or
+setting an instance attribute by using a new mechanism called
+\dfn{properties}.  Many uses of \method{__getattr__} can be rewritten
+to use properties instead, making the resulting code simpler and
+faster.  As a small side benefit, attributes can now have docstrings,
+too.
+
+\item The list of legal attributes for an instance can be limited to a
+particular set using \dfn{slots}, making it possible to safeguard
+against typos and perhaps make more optimizations possible in future
+versions of Python.
+
+\end{itemize}
+
+Some users have voiced concern about all these changes.  Sure, they
+say, the new features are neat and lend themselves to all sorts of
+tricks that weren't possible in previous versions of Python, but
+they also make the language more complicated.  Some people have said
+that they've always recommended Python for its simplicity, and feel
+that its simplicity is being lost.
+
+Personally, I think there's no need to worry.  Many of the new
+features are quite esoteric, and you can write a lot of Python code
+without ever needed to be aware of them.  Writing a simple class is no
+more difficult than it ever was, so you don't need to bother learning
+or teaching them unless they're actually needed.  Some very
+complicated tasks that were previously only possible from C will now
+be possible in pure Python, and to my mind that's all for the better.
+
+I'm not going to attempt to cover every single corner case and small
+change that were required to make the new features work.  Instead this
+section will paint only the broad strokes.  See section~\ref{sect-rellinks},
+``Related Links'', for further sources of information about Python 2.2's new
+object model.
+
+
+\subsection{Old and New Classes}
+
+First, you should know that Python 2.2 really has two kinds of
+classes: classic or old-style classes, and new-style classes.  The
+old-style class model is exactly the same as the class model in
+earlier versions of Python.  All the new features described in this
+section apply only to new-style classes. This divergence isn't
+intended to last forever; eventually old-style classes will be
+dropped, possibly in Python 3.0.
+
+So how do you define a new-style class?  You do it by subclassing an
+existing new-style class.  Most of Python's built-in types, such as
+integers, lists, dictionaries, and even files, are new-style classes
+now.  A new-style class named \class{object}, the base class for all
+built-in types, has also been added so if no built-in type is
+suitable, you can just subclass \class{object}:
+
+\begin{verbatim}
+class C(object):
+    def __init__ (self):
+        ...
+    ...
+\end{verbatim}
+
+This means that \keyword{class} statements that don't have any base
+classes are always classic classes in Python 2.2.  (Actually you can
+also change this by setting a module-level variable named
+\member{__metaclass__} --- see \pep{253} for the details --- but it's
+easier to just subclass \keyword{object}.)
+
+The type objects for the built-in types are available as built-ins,
+named using a clever trick.  Python has always had built-in functions
+named \function{int()}, \function{float()}, and \function{str()}.  In
+2.2, they aren't functions any more, but type objects that behave as
+factories when called.
+
+\begin{verbatim}
+>>> int
+<type 'int'>
+>>> int('123')
+123
+\end{verbatim}
+
+To make the set of types complete, new type objects such as
+\function{dict} and \function{file} have been added.  Here's a
+more interesting example, adding a \method{lock()} method to file
+objects:
+
+\begin{verbatim}
+class LockableFile(file):
+    def lock (self, operation, length=0, start=0, whence=0):
+        import fcntl
+        return fcntl.lockf(self.fileno(), operation,
+                           length, start, whence)
+\end{verbatim}
+
+The now-obsolete \module{posixfile} module contained a class that
+emulated all of a file object's methods and also added a
+\method{lock()} method, but this class couldn't be passed to internal
+functions that expected a built-in file, something which is possible
+with our new \class{LockableFile}.
+
+
+\subsection{Descriptors}
+
+In previous versions of Python, there was no consistent way to
+discover what attributes and methods were supported by an object.
+There were some informal conventions, such as defining
+\member{__members__} and \member{__methods__} attributes that were
+lists of names, but often the author of an extension type or a class
+wouldn't bother to define them.  You could fall back on inspecting the
+\member{__dict__} of an object, but when class inheritance or an
+arbitrary \method{__getattr__} hook were in use this could still be
+inaccurate.
+
+The one big idea underlying the new class model is that an API for
+describing the attributes of an object using \dfn{descriptors} has
+been formalized.  Descriptors specify the value of an attribute,
+stating whether it's a method or a field.  With the descriptor API,
+static methods and class methods become possible, as well as more
+exotic constructs.
+
+Attribute descriptors are objects that live inside class objects, and
+have a few attributes of their own:
+
+\begin{itemize}
+
+\item \member{__name__} is the attribute's name.
+
+\item \member{__doc__} is the attribute's docstring.
+
+\item \method{__get__(\var{object})} is a method that retrieves the
+attribute value from \var{object}. 
+
+\item \method{__set__(\var{object}, \var{value})} sets the attribute
+on \var{object} to \var{value}.
+
+\item \method{__delete__(\var{object}, \var{value})} deletes the \var{value} 
+attribute of \var{object}.
+\end{itemize}
+
+For example, when you write \code{obj.x}, the steps that Python
+actually performs are:
+
+\begin{verbatim}
+descriptor = obj.__class__.x
+descriptor.__get__(obj)
+\end{verbatim}
+
+For methods, \method{descriptor.__get__} returns a temporary object that's
+callable, and wraps up the instance and the method to be called on it.
+This is also why static methods and class methods are now possible;
+they have descriptors that wrap up just the method, or the method and
+the class.  As a brief explanation of these new kinds of methods,
+static methods aren't passed the instance, and therefore resemble
+regular functions.  Class methods are passed the class of the object,
+but not the object itself.  Static and class methods are defined like
+this:
+
+\begin{verbatim}
+class C(object):
+    def f(arg1, arg2):
+        ...
+    f = staticmethod(f)
+
+    def g(cls, arg1, arg2):
+        ...
+    g = classmethod(g)
+\end{verbatim}
+
+The \function{staticmethod()} function takes the function
+\function{f}, and returns it wrapped up in a descriptor so it can be
+stored in the class object.  You might expect there to be special
+syntax for creating such methods (\code{def static f()},
+\code{defstatic f()}, or something like that) but no such syntax has
+been defined yet; that's been left for future versions of Python.
+
+More new features, such as slots and properties, are also implemented
+as new kinds of descriptors, and it's not difficult to write a
+descriptor class that does something novel.  For example, it would be
+possible to write a descriptor class that made it possible to write
+Eiffel-style preconditions and postconditions for a method.  A class
+that used this feature might be defined like this:
+
+\begin{verbatim}
+from eiffel import eiffelmethod
+
+class C(object):
+    def f(self, arg1, arg2):
+        # The actual function
+        ...
+    def pre_f(self):
+        # Check preconditions
+        ...
+    def post_f(self):
+        # Check postconditions
+        ...
+
+    f = eiffelmethod(f, pre_f, post_f)
+\end{verbatim}
+
+Note that a person using the new \function{eiffelmethod()} doesn't
+have to understand anything about descriptors.  This is why I think
+the new features don't increase the basic complexity of the language.
+There will be a few wizards who need to know about it in order to
+write \function{eiffelmethod()} or the ZODB or whatever, but most
+users will just write code on top of the resulting libraries and
+ignore the implementation details.
+
+
+\subsection{Multiple Inheritance: The Diamond Rule}
+
+Multiple inheritance has also been made more useful through changing
+the rules under which names are resolved.  Consider this set of classes
+(diagram taken from \pep{253} by Guido van Rossum):
+
+\begin{verbatim}
+                class A:
+                  ^ ^  def save(self): ...
+                 /   \
+                /     \
+               /       \
+              /         \
+          class B     class C:
+              ^         ^  def save(self): ...
+               \       /
+                \     /
+                 \   /
+                  \ /
+                class D
+\end{verbatim}
+
+The lookup rule for classic classes is simple but not very smart; the
+base classes are searched depth-first, going from left to right.  A
+reference to \method{D.save} will search the classes \class{D},
+\class{B}, and then \class{A}, where \method{save()} would be found
+and returned.  \method{C.save()} would never be found at all.  This is
+bad, because if \class{C}'s \method{save()} method is saving some
+internal state specific to \class{C}, not calling it will result in
+that state never getting saved.
+
+New-style classes follow a different algorithm that's a bit more
+complicated to explain, but does the right thing in this situation.
+(Note that Python 2.3 changes this algorithm to one that produces the
+same results in most cases, but produces more useful results for
+really complicated inheritance graphs.)
+
+\begin{enumerate}
+
+\item List all the base classes, following the classic lookup rule and
+include a class multiple times if it's visited repeatedly.  In the
+above example, the list of visited classes is [\class{D}, \class{B},
+\class{A}, \class{C}, \class{A}].
+
+\item Scan the list for duplicated classes.  If any are found, remove
+all but one occurrence, leaving the \emph{last} one in the list.  In
+the above example, the list becomes [\class{D}, \class{B}, \class{C},
+\class{A}] after dropping duplicates.
+
+\end{enumerate}
+
+Following this rule, referring to \method{D.save()} will return
+\method{C.save()}, which is the behaviour we're after.  This lookup
+rule is the same as the one followed by Common Lisp.  A new built-in
+function, \function{super()}, provides a way to get at a class's
+superclasses without having to reimplement Python's algorithm.
+The most commonly used form will be 
+\function{super(\var{class}, \var{obj})}, which returns 
+a bound superclass object (not the actual class object).  This form
+will be used in methods to call a method in the superclass; for
+example, \class{D}'s \method{save()} method would look like this:
+
+\begin{verbatim}
+class D (B,C):
+    def save (self):
+	# Call superclass .save()
+        super(D, self).save()
+        # Save D's private information here
+        ...
+\end{verbatim}
+
+\function{super()} can also return unbound superclass objects
+when called as \function{super(\var{class})} or
+\function{super(\var{class1}, \var{class2})}, but this probably won't
+often be useful.
+
+
+\subsection{Attribute Access}
+
+A fair number of sophisticated Python classes define hooks for
+attribute access using \method{__getattr__}; most commonly this is
+done for convenience, to make code more readable by automatically
+mapping an attribute access such as \code{obj.parent} into a method
+call such as \code{obj.get_parent()}.  Python 2.2 adds some new ways
+of controlling attribute access.
+
+First, \method{__getattr__(\var{attr_name})} is still supported by
+new-style classes, and nothing about it has changed.  As before, it
+will be called when an attempt is made to access \code{obj.foo} and no
+attribute named \samp{foo} is found in the instance's dictionary.
+
+New-style classes also support a new method,
+\method{__getattribute__(\var{attr_name})}.  The difference between
+the two methods is that \method{__getattribute__} is \emph{always}
+called whenever any attribute is accessed, while the old
+\method{__getattr__} is only called if \samp{foo} isn't found in the
+instance's dictionary.
+
+However, Python 2.2's support for \dfn{properties} will often be a
+simpler way to trap attribute references.  Writing a
+\method{__getattr__} method is complicated because to avoid recursion
+you can't use regular attribute accesses inside them, and instead have
+to mess around with the contents of \member{__dict__}.
+\method{__getattr__} methods also end up being called by Python when
+it checks for other methods such as \method{__repr__} or
+\method{__coerce__}, and so have to be written with this in mind.
+Finally, calling a function on every attribute access results in a
+sizable performance loss.
+
+\class{property} is a new built-in type that packages up three
+functions that get, set, or delete an attribute, and a docstring.  For
+example, if you want to define a \member{size} attribute that's
+computed, but also settable, you could write:
+
+\begin{verbatim}
+class C(object):
+    def get_size (self):
+        result = ... computation ...
+        return result
+    def set_size (self, size):
+        ... compute something based on the size
+        and set internal state appropriately ...
+
+    # Define a property.  The 'delete this attribute'
+    # method is defined as None, so the attribute
+    # can't be deleted.
+    size = property(get_size, set_size,
+                    None,
+                    "Storage size of this instance")
+\end{verbatim}
+
+That is certainly clearer and easier to write than a pair of
+\method{__getattr__}/\method{__setattr__} methods that check for the
+\member{size} attribute and handle it specially while retrieving all
+other attributes from the instance's \member{__dict__}.  Accesses to
+\member{size} are also the only ones which have to perform the work of
+calling a function, so references to other attributes run at
+their usual speed.
+
+Finally, it's possible to constrain the list of attributes that can be
+referenced on an object using the new \member{__slots__} class attribute.
+Python objects are usually very dynamic; at any time it's possible to
+define a new attribute on an instance by just doing
+\code{obj.new_attr=1}.   A new-style class can define a class attribute named
+\member{__slots__} to limit the legal attributes 
+to a particular set of names.  An example will make this clear:
+
+\begin{verbatim}
+>>> class C(object):
+...     __slots__ = ('template', 'name')
+...
+>>> obj = C()
+>>> print obj.template
+None
+>>> obj.template = 'Test'
+>>> print obj.template
+Test
+>>> obj.newattr = None
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+AttributeError: 'C' object has no attribute 'newattr'
+\end{verbatim}
+
+Note how you get an \exception{AttributeError} on the attempt to
+assign to an attribute not listed in \member{__slots__}.
+
+
+
+\subsection{Related Links}
+\label{sect-rellinks}
+
+This section has just been a quick overview of the new features,
+giving enough of an explanation to start you programming, but many
+details have been simplified or ignored.  Where should you go to get a
+more complete picture?
+
+\url{http://www.python.org/2.2/descrintro.html} is a lengthy tutorial
+introduction to the descriptor features, written by Guido van Rossum.
+If my description has whetted your appetite, go read this tutorial
+next, because it goes into much more detail about the new features
+while still remaining quite easy to read.
+
+Next, there are two relevant PEPs, \pep{252} and \pep{253}.  \pep{252}
+is titled "Making Types Look More Like Classes", and covers the
+descriptor API.  \pep{253} is titled "Subtyping Built-in Types", and
+describes the changes to type objects that make it possible to subtype
+built-in objects.  \pep{253} is the more complicated PEP of the two,
+and at a few points the necessary explanations of types and meta-types
+may cause your head to explode.  Both PEPs were written and
+implemented by Guido van Rossum, with substantial assistance from the
+rest of the Zope Corp. team.
+
+Finally, there's the ultimate authority: the source code.  Most of the
+machinery for the type handling is in \file{Objects/typeobject.c}, but
+you should only resort to it after all other avenues have been
+exhausted, including posting a question to python-list or python-dev. 
+
+
+%======================================================================
+\section{PEP 234: Iterators}
+
+Another significant addition to 2.2 is an iteration interface at both
+the C and Python levels.  Objects can define how they can be looped
+over by callers.
+
+In Python versions up to 2.1, the usual way to make \code{for item in
+obj} work is to define a \method{__getitem__()} method that looks
+something like this:
+
+\begin{verbatim}
+    def __getitem__(self, index):
+        return <next item>
+\end{verbatim}
+
+\method{__getitem__()} is more properly used to define an indexing
+operation on an object so that you can write \code{obj[5]} to retrieve
+the sixth element.  It's a bit misleading when you're using this only
+to support \keyword{for} loops.  Consider some file-like object that
+wants to be looped over; the \var{index} parameter is essentially
+meaningless, as the class probably assumes that a series of
+\method{__getitem__()} calls will be made with \var{index}
+incrementing by one each time.  In other words, the presence of the
+\method{__getitem__()} method doesn't mean that using \code{file[5]} 
+to randomly access the sixth element will work, though it really should.
+
+In Python 2.2, iteration can be implemented separately, and
+\method{__getitem__()} methods can be limited to classes that really
+do support random access.  The basic idea of iterators is 
+simple.  A new built-in function, \function{iter(obj)} or
+\code{iter(\var{C}, \var{sentinel})}, is used to get an iterator.
+\function{iter(obj)} returns an iterator for the object \var{obj},
+while \code{iter(\var{C}, \var{sentinel})} returns an iterator that
+will invoke the callable object \var{C} until it returns
+\var{sentinel} to signal that the iterator is done.  
+
+Python classes can define an \method{__iter__()} method, which should
+create and return a new iterator for the object; if the object is its
+own iterator, this method can just return \code{self}.  In particular,
+iterators will usually be their own iterators.  Extension types
+implemented in C can implement a \member{tp_iter} function in order to
+return an iterator, and extension types that want to behave as
+iterators can define a \member{tp_iternext} function.
+
+So, after all this, what do iterators actually do?  They have one
+required method, \method{next()}, which takes no arguments and returns
+the next value.  When there are no more values to be returned, calling
+\method{next()} should raise the \exception{StopIteration} exception.
+
+\begin{verbatim}
+>>> L = [1,2,3]
+>>> i = iter(L)
+>>> print i
+<iterator object at 0x8116870>
+>>> i.next()
+1
+>>> i.next()
+2
+>>> i.next()
+3
+>>> i.next()
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+StopIteration
+>>>      
+\end{verbatim}
+
+In 2.2, Python's \keyword{for} statement no longer expects a sequence;
+it expects something for which \function{iter()} will return an iterator.
+For backward compatibility and convenience, an iterator is
+automatically constructed for sequences that don't implement
+\method{__iter__()} or a \member{tp_iter} slot, so \code{for i in
+[1,2,3]} will still work.  Wherever the Python interpreter loops over
+a sequence, it's been changed to use the iterator protocol.  This
+means you can do things like this:
+
+\begin{verbatim}
+>>> L = [1,2,3]
+>>> i = iter(L)
+>>> a,b,c = i
+>>> a,b,c
+(1, 2, 3)
+\end{verbatim}
+
+Iterator support has been added to some of Python's basic types.  
+Calling \function{iter()} on a dictionary will return an iterator
+which loops over its keys:
+
+\begin{verbatim}
+>>> m = {'Jan': 1, 'Feb': 2, 'Mar': 3, 'Apr': 4, 'May': 5, 'Jun': 6,
+...      'Jul': 7, 'Aug': 8, 'Sep': 9, 'Oct': 10, 'Nov': 11, 'Dec': 12}
+>>> for key in m: print key, m[key]
+...
+Mar 3
+Feb 2
+Aug 8
+Sep 9
+May 5
+Jun 6
+Jul 7
+Jan 1
+Apr 4
+Nov 11
+Dec 12
+Oct 10
+\end{verbatim}          
+
+That's just the default behaviour.  If you want to iterate over keys,
+values, or key/value pairs, you can explicitly call the
+\method{iterkeys()}, \method{itervalues()}, or \method{iteritems()}
+methods to get an appropriate iterator.  In a minor related change,
+the \keyword{in} operator now works on dictionaries, so
+\code{\var{key} in dict} is now equivalent to
+\code{dict.has_key(\var{key})}.
+
+Files also provide an iterator, which calls the \method{readline()}
+method until there are no more lines in the file.  This means you can
+now read each line of a file using code like this:
+
+\begin{verbatim}
+for line in file:
+    # do something for each line
+    ...
+\end{verbatim}
+
+Note that you can only go forward in an iterator; there's no way to
+get the previous element, reset the iterator, or make a copy of it.
+An iterator object could provide such additional capabilities, but the
+iterator protocol only requires a \method{next()} method.
+
+\begin{seealso}
+
+\seepep{234}{Iterators}{Written by Ka-Ping Yee and GvR; implemented 
+by the Python Labs crew, mostly by GvR and Tim Peters.}
+
+\end{seealso}
+
+
+%======================================================================
+\section{PEP 255: Simple Generators}
+
+Generators are another new feature, one that interacts with the
+introduction of iterators.
+
+You're doubtless familiar with how function calls work in Python or
+C.  When you call a function, it gets a private namespace where its local
+variables are created.  When the function reaches a \keyword{return}
+statement, the local variables are destroyed and the resulting value
+is returned to the caller.  A later call to the same function will get
+a fresh new set of local variables.  But, what if the local variables
+weren't thrown away on exiting a function?  What if you could later
+resume the function where it left off?  This is what generators
+provide; they can be thought of as resumable functions.
+
+Here's the simplest example of a generator function:
+
+\begin{verbatim}
+def generate_ints(N):
+    for i in range(N):
+        yield i
+\end{verbatim}
+
+A new keyword, \keyword{yield}, was introduced for generators.  Any
+function containing a \keyword{yield} statement is a generator
+function; this is detected by Python's bytecode compiler which
+compiles the function specially as a result.  Because a new keyword was
+introduced, generators must be explicitly enabled in a module by
+including a \code{from __future__ import generators} statement near
+the top of the module's source code.  In Python 2.3 this statement
+will become unnecessary.
+
+When you call a generator function, it doesn't return a single value;
+instead it returns a generator object that supports the iterator
+protocol.  On executing the \keyword{yield} statement, the generator
+outputs the value of \code{i}, similar to a \keyword{return}
+statement.  The big difference between \keyword{yield} and a
+\keyword{return} statement is that on reaching a \keyword{yield} the
+generator's state of execution is suspended and local variables are
+preserved.  On the next call to the generator's \code{next()} method,
+the function will resume executing immediately after the
+\keyword{yield} statement.  (For complicated reasons, the
+\keyword{yield} statement isn't allowed inside the \keyword{try} block
+of a \keyword{try}...\keyword{finally} statement; read \pep{255} for a full
+explanation of the interaction between \keyword{yield} and
+exceptions.)
+
+Here's a sample usage of the \function{generate_ints} generator:
+
+\begin{verbatim}
+>>> gen = generate_ints(3)
+>>> gen
+<generator object at 0x8117f90>
+>>> gen.next()
+0
+>>> gen.next()
+1
+>>> gen.next()
+2
+>>> gen.next()
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+  File "<stdin>", line 2, in generate_ints
+StopIteration
+\end{verbatim}
+
+You could equally write \code{for i in generate_ints(5)}, or
+\code{a,b,c = generate_ints(3)}.
+
+Inside a generator function, the \keyword{return} statement can only
+be used without a value, and signals the end of the procession of
+values; afterwards the generator cannot return any further values.
+\keyword{return} with a value, such as \code{return 5}, is a syntax
+error inside a generator function.  The end of the generator's results
+can also be indicated by raising \exception{StopIteration} manually,
+or by just letting the flow of execution fall off the bottom of the
+function.
+
+You could achieve the effect of generators manually by writing your
+own class and storing all the local variables of the generator as
+instance variables.  For example, returning a list of integers could
+be done by setting \code{self.count} to 0, and having the
+\method{next()} method increment \code{self.count} and return it.
+However, for a moderately complicated generator, writing a
+corresponding class would be much messier.
+\file{Lib/test/test_generators.py} contains a number of more
+interesting examples.  The simplest one implements an in-order
+traversal of a tree using generators recursively.
+
+\begin{verbatim}
+# A recursive generator that generates Tree leaves in in-order.
+def inorder(t):
+    if t:
+        for x in inorder(t.left):
+            yield x
+        yield t.label
+        for x in inorder(t.right):
+            yield x
+\end{verbatim}
+
+Two other examples in \file{Lib/test/test_generators.py} produce
+solutions for the N-Queens problem (placing $N$ queens on an $NxN$
+chess board so that no queen threatens another) and the Knight's Tour
+(a route that takes a knight to every square of an $NxN$ chessboard
+without visiting any square twice). 
+
+The idea of generators comes from other programming languages,
+especially Icon (\url{http://www.cs.arizona.edu/icon/}), where the
+idea of generators is central.  In Icon, every
+expression and function call behaves like a generator.  One example
+from ``An Overview of the Icon Programming Language'' at
+\url{http://www.cs.arizona.edu/icon/docs/ipd266.htm} gives an idea of
+what this looks like:
+
+\begin{verbatim}
+sentence := "Store it in the neighboring harbor"
+if (i := find("or", sentence)) > 5 then write(i)
+\end{verbatim}
+
+In Icon the \function{find()} function returns the indexes at which the
+substring ``or'' is found: 3, 23, 33.  In the \keyword{if} statement,
+\code{i} is first assigned a value of 3, but 3 is less than 5, so the
+comparison fails, and Icon retries it with the second value of 23.  23
+is greater than 5, so the comparison now succeeds, and the code prints
+the value 23 to the screen.
+
+Python doesn't go nearly as far as Icon in adopting generators as a
+central concept.  Generators are considered a new part of the core
+Python language, but learning or using them isn't compulsory; if they
+don't solve any problems that you have, feel free to ignore them.
+One novel feature of Python's interface as compared to
+Icon's is that a generator's state is represented as a concrete object
+(the iterator) that can be passed around to other functions or stored
+in a data structure.
+
+\begin{seealso}
+
+\seepep{255}{Simple Generators}{Written by Neil Schemenauer, Tim
+Peters, Magnus Lie Hetland.  Implemented mostly by Neil Schemenauer
+and Tim Peters, with other fixes from the Python Labs crew.}
+
+\end{seealso}
+
+
+%======================================================================
+\section{PEP 237: Unifying Long Integers and Integers}
+
+In recent versions, the distinction between regular integers, which
+are 32-bit values on most machines, and long integers, which can be of
+arbitrary size, was becoming an annoyance.  For example, on platforms
+that support files larger than \code{2**32} bytes, the
+\method{tell()} method of file objects has to return a long integer.
+However, there were various bits of Python that expected plain
+integers and would raise an error if a long integer was provided
+instead.  For example, in Python 1.5, only regular integers
+could be used as a slice index, and \code{'abc'[1L:]} would raise a
+\exception{TypeError} exception with the message 'slice index must be
+int'.
+
+Python 2.2 will shift values from short to long integers as required.
+The 'L' suffix is no longer needed to indicate a long integer literal,
+as now the compiler will choose the appropriate type.  (Using the 'L'
+suffix will be discouraged in future 2.x versions of Python,
+triggering a warning in Python 2.4, and probably dropped in Python
+3.0.)  Many operations that used to raise an \exception{OverflowError}
+will now return a long integer as their result.  For example:
+
+\begin{verbatim}
+>>> 1234567890123
+1234567890123L
+>>> 2 ** 64
+18446744073709551616L
+\end{verbatim}
+
+In most cases, integers and long integers will now be treated
+identically.  You can still distinguish them with the
+\function{type()} built-in function, but that's rarely needed.  
+
+\begin{seealso}
+
+\seepep{237}{Unifying Long Integers and Integers}{Written by
+Moshe Zadka and Guido van Rossum.  Implemented mostly by Guido van
+Rossum.}
+
+\end{seealso}
+
+
+%======================================================================
+\section{PEP 238: Changing the Division Operator}
+
+The most controversial change in Python 2.2 heralds the start of an effort
+to fix an old design flaw that's been in Python from the beginning.
+Currently Python's division operator, \code{/}, behaves like C's
+division operator when presented with two integer arguments: it
+returns an integer result that's truncated down when there would be
+a fractional part.  For example, \code{3/2} is 1, not 1.5, and
+\code{(-1)/2} is -1, not -0.5.  This means that the results of divison
+can vary unexpectedly depending on the type of the two operands and
+because Python is dynamically typed, it can be difficult to determine
+the possible types of the operands.
+
+(The controversy is over whether this is \emph{really} a design flaw,
+and whether it's worth breaking existing code to fix this.  It's
+caused endless discussions on python-dev, and in July 2001 erupted into an
+storm of acidly sarcastic postings on \newsgroup{comp.lang.python}. I
+won't argue for either side here and will stick to describing what's 
+implemented in 2.2.  Read \pep{238} for a summary of arguments and
+counter-arguments.)  
+
+Because this change might break code, it's being introduced very
+gradually.  Python 2.2 begins the transition, but the switch won't be
+complete until Python 3.0.
+
+First, I'll borrow some terminology from \pep{238}.  ``True division'' is the
+division that most non-programmers are familiar with: 3/2 is 1.5, 1/4
+is 0.25, and so forth.  ``Floor division'' is what Python's \code{/}
+operator currently does when given integer operands; the result is the
+floor of the value returned by true division.  ``Classic division'' is
+the current mixed behaviour of \code{/}; it returns the result of
+floor division when the operands are integers, and returns the result
+of true division when one of the operands is a floating-point number.
+
+Here are the changes 2.2 introduces:
+
+\begin{itemize}
+
+\item A new operator, \code{//}, is the floor division operator.
+(Yes, we know it looks like \Cpp's comment symbol.)  \code{//}
+\emph{always} performs floor division no matter what the types of
+its operands are, so \code{1 // 2} is 0 and \code{1.0 // 2.0} is also
+0.0.
+
+\code{//} is always available in Python 2.2; you don't need to enable
+it using a \code{__future__} statement.  
+
+\item By including a \code{from __future__ import division} in a
+module, the \code{/} operator will be changed to return the result of
+true division, so \code{1/2} is 0.5.  Without the \code{__future__}
+statement, \code{/} still means classic division.  The default meaning
+of \code{/} will not change until Python 3.0.  
+
+\item Classes can define methods called \method{__truediv__} and
+\method{__floordiv__} to overload the two division operators.  At the
+C level, there are also slots in the \ctype{PyNumberMethods} structure
+so extension types can define the two operators.
+
+\item Python 2.2 supports some command-line arguments for testing
+whether code will works with the changed division semantics.  Running
+python with \programopt{-Q warn} will cause a warning to be issued
+whenever division is applied to two integers.  You can use this to
+find code that's affected by the change and fix it.  By default,
+Python 2.2 will simply perform classic division without a warning; the
+warning will be turned on by default in Python 2.3.
+
+\end{itemize}
+
+\begin{seealso}
+
+\seepep{238}{Changing the Division Operator}{Written by Moshe Zadka and 
+Guido van Rossum.  Implemented by Guido van Rossum..}
+
+\end{seealso}
+
+
+%======================================================================
+\section{Unicode Changes}
+
+Python's Unicode support has been enhanced a bit in 2.2.  Unicode
+strings are usually stored as UCS-2, as 16-bit unsigned integers.
+Python 2.2 can also be compiled to use UCS-4, 32-bit unsigned
+integers, as its internal encoding by supplying
+\longprogramopt{enable-unicode=ucs4} to the configure script.  
+(It's also possible to specify
+\longprogramopt{disable-unicode} to completely disable Unicode
+support.)
+
+When built to use UCS-4 (a ``wide Python''), the interpreter can
+natively handle Unicode characters from U+000000 to U+110000, so the
+range of legal values for the \function{unichr()} function is expanded
+accordingly.  Using an interpreter compiled to use UCS-2 (a ``narrow
+Python''), values greater than 65535 will still cause
+\function{unichr()} to raise a \exception{ValueError} exception.
+This is all described in \pep{261}, ``Support for `wide' Unicode
+characters''; consult it for further details.
+
+Another change is simpler to explain. Since their introduction,
+Unicode strings have supported an \method{encode()} method to convert
+the string to a selected encoding such as UTF-8 or Latin-1.  A
+symmetric \method{decode(\optional{\var{encoding}})} method has been
+added to 8-bit strings (though not to Unicode strings) in 2.2.
+\method{decode()} assumes that the string is in the specified encoding
+and decodes it, returning whatever is returned by the codec. 
+
+Using this new feature, codecs have been added for tasks not directly
+related to Unicode.  For example, codecs have been added for
+uu-encoding, MIME's base64 encoding, and compression with the
+\module{zlib} module:
+
+\begin{verbatim}
+>>> s = """Here is a lengthy piece of redundant, overly verbose,
+... and repetitive text.
+... """
+>>> data = s.encode('zlib')
+>>> data
+'x\x9c\r\xc9\xc1\r\x80 \x10\x04\xc0?Ul...'
+>>> data.decode('zlib')
+'Here is a lengthy piece of redundant, overly verbose,\nand repetitive text.\n'
+>>> print s.encode('uu')
+begin 666 <data>
+M2&5R92!I<R!A(&QE;F=T:'D@<&EE8V4@;V8@<F5D=6YD86YT+"!O=F5R;'D@
+>=F5R8F]S92P*86YD(')E<&5T:71I=F4@=&5X="X*
+
+end
+>>> "sheesh".encode('rot-13')
+'furrfu'
+\end{verbatim}
+
+To convert a class instance to Unicode, a \method{__unicode__} method
+can be defined by a class, analogous to \method{__str__}.
+
+\method{encode()}, \method{decode()}, and \method{__unicode__} were
+implemented by Marc-Andr\'e Lemburg.  The changes to support using
+UCS-4 internally were implemented by Fredrik Lundh and Martin von
+L\"owis.
+
+\begin{seealso}
+
+\seepep{261}{Support for `wide' Unicode characters}{Written by
+Paul Prescod.}
+
+\end{seealso}
+
+
+%======================================================================
+\section{PEP 227: Nested Scopes}
+
+In Python 2.1, statically nested scopes were added as an optional
+feature, to be enabled by a \code{from __future__ import
+nested_scopes} directive.  In 2.2 nested scopes no longer need to be
+specially enabled, and are now always present.  The rest of this section
+is a copy of the description of nested scopes from my ``What's New in
+Python 2.1'' document; if you read it when 2.1 came out, you can skip
+the rest of this section.
+
+The largest change introduced in Python 2.1, and made complete in 2.2,
+is to Python's scoping rules.  In Python 2.0, at any given time there
+are at most three namespaces used to look up variable names: local,
+module-level, and the built-in namespace.  This often surprised people
+because it didn't match their intuitive expectations.  For example, a
+nested recursive function definition doesn't work:
+
+\begin{verbatim}
+def f():
+    ...
+    def g(value):
+        ...
+        return g(value-1) + 1
+    ...
+\end{verbatim}
+
+The function \function{g()} will always raise a \exception{NameError}
+exception, because the binding of the name \samp{g} isn't in either
+its local namespace or in the module-level namespace.  This isn't much
+of a problem in practice (how often do you recursively define interior
+functions like this?), but this also made using the \keyword{lambda}
+statement clumsier, and this was a problem in practice.  In code which
+uses \keyword{lambda} you can often find local variables being copied
+by passing them as the default values of arguments.
+
+\begin{verbatim}
+def find(self, name):
+    "Return list of any entries equal to 'name'"
+    L = filter(lambda x, name=name: x == name,
+               self.list_attribute)
+    return L
+\end{verbatim}
+
+The readability of Python code written in a strongly functional style
+suffers greatly as a result.
+
+The most significant change to Python 2.2 is that static scoping has
+been added to the language to fix this problem.  As a first effect,
+the \code{name=name} default argument is now unnecessary in the above
+example.  Put simply, when a given variable name is not assigned a
+value within a function (by an assignment, or the \keyword{def},
+\keyword{class}, or \keyword{import} statements), references to the
+variable will be looked up in the local namespace of the enclosing
+scope.  A more detailed explanation of the rules, and a dissection of
+the implementation, can be found in the PEP.
+
+This change may cause some compatibility problems for code where the
+same variable name is used both at the module level and as a local
+variable within a function that contains further function definitions.
+This seems rather unlikely though, since such code would have been
+pretty confusing to read in the first place.  
+
+One side effect of the change is that the \code{from \var{module}
+import *} and \keyword{exec} statements have been made illegal inside
+a function scope under certain conditions.  The Python reference
+manual has said all along that \code{from \var{module} import *} is
+only legal at the top level of a module, but the CPython interpreter
+has never enforced this before.  As part of the implementation of
+nested scopes, the compiler which turns Python source into bytecodes
+has to generate different code to access variables in a containing
+scope.  \code{from \var{module} import *} and \keyword{exec} make it
+impossible for the compiler to figure this out, because they add names
+to the local namespace that are unknowable at compile time.
+Therefore, if a function contains function definitions or
+\keyword{lambda} expressions with free variables, the compiler will
+flag this by raising a \exception{SyntaxError} exception.
+
+To make the preceding explanation a bit clearer, here's an example:
+
+\begin{verbatim}
+x = 1
+def f():
+    # The next line is a syntax error
+    exec 'x=2'  
+    def g():
+        return x
+\end{verbatim}
+
+Line 4 containing the \keyword{exec} statement is a syntax error,
+since \keyword{exec} would define a new local variable named \samp{x}
+whose value should be accessed by \function{g()}.  
+
+This shouldn't be much of a limitation, since \keyword{exec} is rarely
+used in most Python code (and when it is used, it's often a sign of a
+poor design anyway).
+
+\begin{seealso}
+
+\seepep{227}{Statically Nested Scopes}{Written and implemented by
+Jeremy Hylton.}
+
+\end{seealso}
+
+
+%======================================================================
+\section{New and Improved Modules}
+
+\begin{itemize}
+
+  \item The \module{xmlrpclib} module was contributed to the standard
+  library by Fredrik Lundh, providing support for writing XML-RPC
+  clients.  XML-RPC is a simple remote procedure call protocol built on
+  top of HTTP and XML. For example, the following snippet retrieves a
+  list of RSS channels from the O'Reilly Network, and then 
+  lists the recent headlines for one channel:
+
+\begin{verbatim}
+import xmlrpclib
+s = xmlrpclib.Server(
+      'http://www.oreillynet.com/meerkat/xml-rpc/server.php')
+channels = s.meerkat.getChannels()
+# channels is a list of dictionaries, like this:
+# [{'id': 4, 'title': 'Freshmeat Daily News'}
+#  {'id': 190, 'title': '32Bits Online'},
+#  {'id': 4549, 'title': '3DGamers'}, ... ]
+
+# Get the items for one channel
+items = s.meerkat.getItems( {'channel': 4} )
+
+# 'items' is another list of dictionaries, like this:
+# [{'link': 'http://freshmeat.net/releases/52719/', 
+#   'description': 'A utility which converts HTML to XSL FO.', 
+#   'title': 'html2fo 0.3 (Default)'}, ... ]
+\end{verbatim}
+
+The \module{SimpleXMLRPCServer} module makes it easy to create
+straightforward XML-RPC servers.  See \url{http://www.xmlrpc.com/} for
+more information about XML-RPC.
+
+  \item The new \module{hmac} module implements the HMAC
+  algorithm described by \rfc{2104}.
+  (Contributed by Gerhard H\"aring.)
+
+  \item Several functions that originally returned lengthy tuples now
+  return pseudo-sequences that still behave like tuples but also have
+  mnemonic attributes such as member{st_mtime} or \member{tm_year}.
+  The enhanced functions include \function{stat()},
+  \function{fstat()}, \function{statvfs()}, and \function{fstatvfs()}
+  in the \module{os} module, and \function{localtime()},
+  \function{gmtime()}, and \function{strptime()} in the \module{time}
+  module.  
+  
+  For example, to obtain a file's size using the old tuples, you'd end
+  up writing something like \code{file_size =
+  os.stat(filename)[stat.ST_SIZE]}, but now this can be written more
+  clearly as \code{file_size = os.stat(filename).st_size}.
+
+   The original patch for this feature was contributed by Nick Mathewson.
+
+  \item The Python profiler has been extensively reworked and various
+  errors in its output have been corrected.  (Contributed by
+  Fred~L. Drake, Jr. and Tim Peters.)
+ 
+  \item The \module{socket} module can be compiled to support IPv6;
+  specify the \longprogramopt{enable-ipv6} option to Python's configure
+  script.  (Contributed by Jun-ichiro ``itojun'' Hagino.)
+
+  \item Two new format characters were added to the \module{struct}
+  module for 64-bit integers on platforms that support the C
+  \ctype{long long} type.  \samp{q} is for a signed 64-bit integer,
+  and \samp{Q} is for an unsigned one.  The value is returned in
+  Python's long integer type.  (Contributed by Tim Peters.)
+
+  \item In the interpreter's interactive mode, there's a new built-in
+  function \function{help()} that uses the \module{pydoc} module
+  introduced in Python 2.1 to provide interactive help.
+  \code{help(\var{object})} displays any available help text about
+  \var{object}.  \function{help()} with no argument puts you in an online
+  help utility, where you can enter the names of functions, classes,
+  or modules to read their help text.
+  (Contributed by Guido van Rossum, using Ka-Ping Yee's \module{pydoc} module.)
+
+  \item Various bugfixes and performance improvements have been made
+  to the SRE engine underlying the \module{re} module.  For example,
+  the \function{re.sub()} and \function{re.split()} functions have
+  been rewritten in C.  Another contributed patch speeds up certain
+  Unicode character ranges by a factor of two, and a new \method{finditer()} 
+  method that returns an iterator over all the non-overlapping matches in 
+  a given string. 
+  (SRE is maintained by
+  Fredrik Lundh.  The BIGCHARSET patch was contributed by Martin von
+  L\"owis.)
+
+  \item The \module{smtplib} module now supports \rfc{2487}, ``Secure
+  SMTP over TLS'', so it's now possible to encrypt the SMTP traffic
+  between a Python program and the mail transport agent being handed a
+  message.  \module{smtplib} also supports SMTP authentication. 
+  (Contributed by Gerhard H\"aring.)
+
+  \item The \module{imaplib} module, maintained by Piers Lauder, has
+  support for several new extensions: the NAMESPACE extension defined
+  in \rfc{2342}, SORT, GETACL and SETACL.  (Contributed by Anthony
+  Baxter and Michel Pelletier.)
+
+  \item The \module{rfc822} module's parsing of email addresses is now
+  compliant with \rfc{2822}, an update to \rfc{822}.  (The module's
+  name is \emph{not} going to be changed to \samp{rfc2822}.)  A new
+  package, \module{email}, has also been added for parsing and
+  generating e-mail messages.  (Contributed by Barry Warsaw, and
+  arising out of his work on Mailman.)
+
+  \item The \module{difflib} module now contains a new \class{Differ}
+  class for producing human-readable lists of changes (a ``delta'')
+  between two sequences of lines of text.  There are also two
+  generator functions, \function{ndiff()} and \function{restore()},
+  which respectively return a delta from two sequences, or one of the
+  original sequences from a delta. (Grunt work contributed by David
+  Goodger, from ndiff.py code by Tim Peters who then did the
+  generatorization.)
+
+  \item New constants \constant{ascii_letters},
+  \constant{ascii_lowercase}, and \constant{ascii_uppercase} were
+  added to the \module{string} module.  There were several modules in
+  the standard library that used \constant{string.letters} to mean the
+  ranges A-Za-z, but that assumption is incorrect when locales are in
+  use, because \constant{string.letters} varies depending on the set
+  of legal characters defined by the current locale.  The buggy
+  modules have all been fixed to use \constant{ascii_letters} instead.
+  (Reported by an unknown person; fixed by Fred~L. Drake, Jr.)
+
+  \item The \module{mimetypes} module now makes it easier to use
+  alternative MIME-type databases by the addition of a
+  \class{MimeTypes} class, which takes a list of filenames to be
+  parsed.  (Contributed by Fred~L. Drake, Jr.)
+
+  \item A \class{Timer} class was added to the \module{threading}
+  module that allows scheduling an activity to happen at some future
+  time.  (Contributed by Itamar Shtull-Trauring.)
+
+\end{itemize}
+
+
+%======================================================================
+\section{Interpreter Changes and Fixes}
+
+Some of the changes only affect people who deal with the Python
+interpreter at the C level because they're writing Python extension modules,
+embedding the interpreter, or just hacking on the interpreter itself.
+If you only write Python code, none of the changes described here will
+affect you very much.
+
+\begin{itemize}
+
+  \item Profiling and tracing functions can now be implemented in C,
+  which can operate at much higher speeds than Python-based functions
+  and should reduce the overhead of profiling and tracing.  This 
+  will be of interest to authors of development environments for
+  Python.  Two new C functions were added to Python's API,
+  \cfunction{PyEval_SetProfile()} and \cfunction{PyEval_SetTrace()}.
+  The existing \function{sys.setprofile()} and
+  \function{sys.settrace()} functions still exist, and have simply
+  been changed to use the new C-level interface.  (Contributed by Fred
+  L. Drake, Jr.)
+
+  \item Another low-level API, primarily of interest to implementors
+  of Python debuggers and development tools, was added.
+  \cfunction{PyInterpreterState_Head()} and
+  \cfunction{PyInterpreterState_Next()} let a caller walk through all
+  the existing interpreter objects;
+  \cfunction{PyInterpreterState_ThreadHead()} and
+  \cfunction{PyThreadState_Next()} allow looping over all the thread
+  states for a given interpreter.  (Contributed by David Beazley.)
+
+\item The C-level interface to the garbage collector has been changed
+to make it easier to write extension types that support garbage
+collection and to debug misuses of the functions.
+Various functions have slightly different semantics, so a bunch of
+functions had to be renamed.  Extensions that use the old API will
+still compile but will \emph{not} participate in garbage collection,
+so updating them for 2.2 should be considered fairly high priority.
+
+To upgrade an extension module to the new API, perform the following
+steps:
+
+\begin{itemize}
+
+\item Rename \cfunction{Py_TPFLAGS_GC} to \cfunction{PyTPFLAGS_HAVE_GC}.
+
+\item Use \cfunction{PyObject_GC_New} or \cfunction{PyObject_GC_NewVar} to
+allocate objects, and \cfunction{PyObject_GC_Del} to deallocate them.
+
+\item Rename \cfunction{PyObject_GC_Init} to \cfunction{PyObject_GC_Track} and
+\cfunction{PyObject_GC_Fini} to \cfunction{PyObject_GC_UnTrack}.
+
+\item Remove \cfunction{PyGC_HEAD_SIZE} from object size calculations.
+
+\item Remove calls to \cfunction{PyObject_AS_GC} and \cfunction{PyObject_FROM_GC}.
+
+\end{itemize}
+
+  \item A new \samp{et} format sequence was added to
+  \cfunction{PyArg_ParseTuple}; \samp{et} takes both a parameter and
+  an encoding name, and converts the parameter to the given encoding
+  if the parameter turns out to be a Unicode string, or leaves it
+  alone if it's an 8-bit string, assuming it to already be in the
+  desired encoding.  This differs from the \samp{es} format character,
+  which assumes that 8-bit strings are in Python's default ASCII
+  encoding and converts them to the specified new encoding.
+  (Contributed by M.-A. Lemburg, and used for the MBCS support on
+  Windows described in the following section.)
+
+  \item A different argument parsing function,
+  \cfunction{PyArg_UnpackTuple()}, has been added that's simpler and
+  presumably faster.  Instead of specifying a format string, the
+  caller simply gives the minimum and maximum number of arguments
+  expected, and a set of pointers to \ctype{PyObject*} variables that
+  will be filled in with argument values.  
+
+  \item Two new flags \constant{METH_NOARGS} and \constant{METH_O} are
+   available in method definition tables to simplify implementation of
+   methods with no arguments or a single untyped argument. Calling
+   such methods is more efficient than calling a corresponding method
+   that uses \constant{METH_VARARGS}. 
+   Also, the old \constant{METH_OLDARGS} style of writing C methods is 
+   now officially deprecated.  
+
+\item
+   Two new wrapper functions, \cfunction{PyOS_snprintf()} and
+   \cfunction{PyOS_vsnprintf()} were added to provide 
+   cross-platform implementations for the relatively new
+   \cfunction{snprintf()} and \cfunction{vsnprintf()} C lib APIs. In
+   contrast to the standard \cfunction{sprintf()} and
+   \cfunction{vsprintf()} functions, the Python versions check the
+   bounds of the buffer used to protect against buffer overruns.
+   (Contributed by M.-A. Lemburg.)
+
+   \item The \cfunction{_PyTuple_Resize()} function has lost an unused
+   parameter, so now it takes 2 parameters instead of 3.  The third
+   argument was never used, and can simply be discarded when porting
+   code from earlier versions to Python 2.2.
+
+\end{itemize}
+
+
+%======================================================================
+\section{Other Changes and Fixes}
+
+As usual there were a bunch of other improvements and bugfixes
+scattered throughout the source tree.  A search through the CVS change
+logs finds there were 527 patches applied and 683 bugs fixed between
+Python 2.1 and 2.2; 2.2.1 applied 139 patches and fixed 143 bugs;
+2.2.2 applied 106 patches and fixed 82 bugs.  These figures are likely
+to be underestimates.
+
+Some of the more notable changes are:
+
+\begin{itemize}
+
+  \item The code for the MacOS port for Python, maintained by Jack
+  Jansen, is now kept in the main Python CVS tree, and many changes
+  have been made to support MacOS~X.
+
+The most significant change is the ability to build Python as a
+framework, enabled by supplying the \longprogramopt{enable-framework}
+option to the configure script when compiling Python.  According to
+Jack Jansen, ``This installs a self-contained Python installation plus
+the OS~X framework "glue" into
+\file{/Library/Frameworks/Python.framework} (or another location of
+choice).  For now there is little immediate added benefit to this
+(actually, there is the disadvantage that you have to change your PATH
+to be able to find Python), but it is the basis for creating a
+full-blown Python application, porting the MacPython IDE, possibly
+using Python as a standard OSA scripting language and much more.''
+
+Most of the MacPython toolbox modules, which interface to MacOS APIs
+such as windowing, QuickTime, scripting, etc. have been ported to OS~X,
+but they've been left commented out in \file{setup.py}.  People who want
+to experiment with these modules can uncomment them manually.
+
+% Jack's original comments:
+%The main change is the possibility to build Python as a
+%framework. This installs a self-contained Python installation plus the
+%OSX framework "glue" into /Library/Frameworks/Python.framework (or
+%another location of choice). For now there is little immedeate added
+%benefit to this (actually, there is the disadvantage that you have to
+%change your PATH to be able to find Python), but it is the basis for
+%creating a fullblown Python application, porting the MacPython IDE,
+%possibly using Python as a standard OSA scripting language and much
+%more. You enable this with "configure --enable-framework".
+ 
+%The other change is that most MacPython toolbox modules, which
+%interface to all the MacOS APIs such as windowing, quicktime,
+%scripting, etc. have been ported. Again, most of these are not of
+%immedeate use, as they need a full application to be really useful, so
+%they have been commented out in setup.py. People wanting to experiment
+%can uncomment them. Gestalt and Internet Config modules are enabled by
+%default.
+  
+  \item Keyword arguments passed to builtin functions that don't take them
+  now cause a \exception{TypeError} exception to be raised, with the
+  message "\var{function} takes no keyword arguments".
+  
+  \item Weak references, added in Python 2.1 as an extension module,
+  are now part of the core because they're used in the implementation
+  of new-style classes.  The \exception{ReferenceError} exception has
+  therefore moved from the \module{weakref} module to become a
+  built-in exception.
+
+  \item A new script, \file{Tools/scripts/cleanfuture.py} by Tim
+  Peters, automatically removes obsolete \code{__future__} statements
+  from Python source code.
+
+  \item An additional \var{flags} argument has been added to the
+  built-in function \function{compile()}, so the behaviour of
+  \code{__future__} statements can now be correctly observed in
+  simulated shells, such as those presented by IDLE and other
+  development environments.  This is described in \pep{264}.
+  (Contributed by Michael Hudson.)
+
+  \item The new license introduced with Python 1.6 wasn't
+  GPL-compatible.  This is fixed by some minor textual changes to the
+  2.2 license, so it's now legal to embed Python inside a GPLed
+  program again.  Note that Python itself is not GPLed, but instead is
+  under a license that's essentially equivalent to the BSD license,
+  same as it always was.  The license changes were also applied to the
+  Python 2.0.1 and 2.1.1 releases.
+
+  \item When presented with a Unicode filename on Windows, Python will
+  now convert it to an MBCS encoded string, as used by the Microsoft
+  file APIs.  As MBCS is explicitly used by the file APIs, Python's
+  choice of ASCII as the default encoding turns out to be an
+  annoyance.  On \UNIX, the locale's character set is used if
+  \function{locale.nl_langinfo(CODESET)} is available.  (Windows
+  support was contributed by Mark Hammond with assistance from
+  Marc-Andr\'e Lemburg. \UNIX{} support was added by Martin von L\"owis.)
+
+  \item Large file support is now enabled on Windows.  (Contributed by
+  Tim Peters.)
+
+  \item The \file{Tools/scripts/ftpmirror.py} script
+  now parses a \file{.netrc} file, if you have one.
+  (Contributed by Mike Romberg.) 
+
+  \item Some features of the object returned by the
+  \function{xrange()} function are now deprecated, and trigger
+  warnings when they're accessed; they'll disappear in Python 2.3.
+  \class{xrange} objects tried to pretend they were full sequence
+  types by supporting slicing, sequence multiplication, and the
+  \keyword{in} operator, but these features were rarely used and
+  therefore buggy.  The \method{tolist()} method and the
+  \member{start}, \member{stop}, and \member{step} attributes are also
+  being deprecated.  At the C level, the fourth argument to the
+  \cfunction{PyRange_New()} function, \samp{repeat}, has also been
+  deprecated.
+
+  \item There were a bunch of patches to the dictionary
+  implementation, mostly to fix potential core dumps if a dictionary
+  contains objects that sneakily changed their hash value, or mutated
+  the dictionary they were contained in. For a while python-dev fell
+  into a gentle rhythm of Michael Hudson finding a case that dumped
+  core, Tim Peters fixing the bug, Michael finding another case, and round
+  and round it went.   
+
+  \item On Windows, Python can now be compiled with Borland C thanks
+  to a number of patches contributed by Stephen Hansen, though the
+  result isn't fully functional yet.  (But this \emph{is} progress...)
+  
+  \item Another Windows enhancement: Wise Solutions generously offered
+  PythonLabs use of their InstallerMaster 8.1 system.  Earlier
+  PythonLabs Windows installers used Wise 5.0a, which was beginning to
+  show its age.  (Packaged up by Tim Peters.)
+
+  \item Files ending in \samp{.pyw} can now be imported on Windows.
+  \samp{.pyw} is a Windows-only thing, used to indicate that a script
+  needs to be run using PYTHONW.EXE instead of PYTHON.EXE in order to
+  prevent a DOS console from popping up to display the output.  This
+  patch makes it possible to import such scripts, in case they're also
+  usable as modules.  (Implemented by David Bolen.)
+
+  \item On platforms where Python uses the C \cfunction{dlopen()} function 
+  to load extension modules, it's now possible to set the flags used 
+  by \cfunction{dlopen()} using the \function{sys.getdlopenflags()} and
+  \function{sys.setdlopenflags()} functions.    (Contributed by Bram Stolk.)
+
+  \item The \function{pow()} built-in function no longer supports 3
+  arguments when floating-point numbers are supplied.
+  \code{pow(\var{x}, \var{y}, \var{z})} returns \code{(x**y) \% z}, but
+  this is never useful for floating point numbers, and the final
+  result varies unpredictably depending on the platform.  A call such
+  as \code{pow(2.0, 8.0, 7.0)} will now raise a \exception{TypeError}
+  exception.
+  
+\end{itemize}
+
+
+%======================================================================
+\section{Acknowledgements}
+
+The author would like to thank the following people for offering
+suggestions, corrections and assistance with various drafts of this
+article: Fred Bremmer, Keith Briggs, Andrew Dalke, Fred~L. Drake, Jr.,
+Carel Fellinger, David Goodger, Mark Hammond, Stephen Hansen, Michael
+Hudson, Jack Jansen, Marc-Andr\'e Lemburg, Martin von L\"owis, Fredrik
+Lundh, Michael McLay, Nick Mathewson, Paul Moore, Gustavo Niemeyer,
+Don O'Donnell, Joonas Paalasma, Tim Peters, Jens Quade, Tom Reinhardt, Neil
+Schemenauer, Guido van Rossum, Greg Ward, Edward Welbourne.
+
+\end{document}

Added: vendor/Python/current/Doc/whatsnew/whatsnew23.tex
===================================================================
--- vendor/Python/current/Doc/whatsnew/whatsnew23.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/whatsnew/whatsnew23.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2380 @@
+\documentclass{howto}
+\usepackage{distutils}
+% $Id: whatsnew23.tex 50964 2006-07-30 03:03:43Z fred.drake $
+
+\title{What's New in Python 2.3}
+\release{1.01}
+\author{A.M.\ Kuchling}
+\authoraddress{
+	\strong{Python Software Foundation}\\
+	Email: \email{amk at amk.ca}
+}
+
+\begin{document}
+\maketitle
+\tableofcontents
+
+This article explains the new features in Python 2.3.  Python 2.3 was
+released on July 29, 2003.
+
+The main themes for Python 2.3 are polishing some of the features
+added in 2.2, adding various small but useful enhancements to the core
+language, and expanding the standard library.  The new object model
+introduced in the previous version has benefited from 18 months of
+bugfixes and from optimization efforts that have improved the
+performance of new-style classes.  A few new built-in functions have
+been added such as \function{sum()} and \function{enumerate()}.  The
+\keyword{in} operator can now be used for substring searches (e.g.
+\code{"ab" in "abc"} returns \constant{True}).
+
+Some of the many new library features include Boolean, set, heap, and
+date/time data types, the ability to import modules from ZIP-format
+archives, metadata support for the long-awaited Python catalog, an
+updated version of IDLE, and modules for logging messages, wrapping
+text, parsing CSV files, processing command-line options, using BerkeleyDB
+databases...  the list of new and enhanced modules is lengthy.
+
+This article doesn't attempt to provide a complete specification of
+the new features, but instead provides a convenient overview.  For
+full details, you should refer to the documentation for Python 2.3,
+such as the \citetitle[../lib/lib.html]{Python Library Reference} and
+the \citetitle[../ref/ref.html]{Python Reference Manual}.  If you want
+to understand the complete implementation and design rationale, 
+refer to the PEP for a particular new feature.
+
+
+%======================================================================
+\section{PEP 218: A Standard Set Datatype}
+
+The new \module{sets} module contains an implementation of a set
+datatype.  The \class{Set} class is for mutable sets, sets that can
+have members added and removed.  The \class{ImmutableSet} class is for
+sets that can't be modified, and instances of \class{ImmutableSet} can
+therefore be used as dictionary keys.  Sets are built on top of
+dictionaries, so the elements within a set must be hashable.
+
+Here's a simple example:
+
+\begin{verbatim}
+>>> import sets
+>>> S = sets.Set([1,2,3])
+>>> S
+Set([1, 2, 3])
+>>> 1 in S
+True
+>>> 0 in S
+False
+>>> S.add(5)
+>>> S.remove(3)
+>>> S
+Set([1, 2, 5])
+>>>
+\end{verbatim}
+
+The union and intersection of sets can be computed with the
+\method{union()} and \method{intersection()} methods; an alternative
+notation uses the bitwise operators \code{\&} and \code{|}.
+Mutable sets also have in-place versions of these methods,
+\method{union_update()} and \method{intersection_update()}.
+
+\begin{verbatim}
+>>> S1 = sets.Set([1,2,3])
+>>> S2 = sets.Set([4,5,6])
+>>> S1.union(S2)
+Set([1, 2, 3, 4, 5, 6])
+>>> S1 | S2                  # Alternative notation
+Set([1, 2, 3, 4, 5, 6])
+>>> S1.intersection(S2)
+Set([])
+>>> S1 & S2                  # Alternative notation
+Set([])
+>>> S1.union_update(S2)
+>>> S1
+Set([1, 2, 3, 4, 5, 6])
+>>>
+\end{verbatim}
+
+It's also possible to take the symmetric difference of two sets.  This
+is the set of all elements in the union that aren't in the
+intersection.  Another way of putting it is that the symmetric
+difference contains all elements that are in exactly one
+set.  Again, there's an alternative notation (\code{\^}), and an
+in-place version with the ungainly name
+\method{symmetric_difference_update()}.
+
+\begin{verbatim}
+>>> S1 = sets.Set([1,2,3,4])
+>>> S2 = sets.Set([3,4,5,6])
+>>> S1.symmetric_difference(S2)
+Set([1, 2, 5, 6])
+>>> S1 ^ S2
+Set([1, 2, 5, 6])
+>>>
+\end{verbatim}
+
+There are also \method{issubset()} and \method{issuperset()} methods
+for checking whether one set is a subset or superset of another:
+
+\begin{verbatim}
+>>> S1 = sets.Set([1,2,3])
+>>> S2 = sets.Set([2,3])
+>>> S2.issubset(S1)
+True
+>>> S1.issubset(S2)
+False
+>>> S1.issuperset(S2)
+True
+>>>
+\end{verbatim}
+
+
+\begin{seealso}
+
+\seepep{218}{Adding a Built-In Set Object Type}{PEP written by Greg V. Wilson.
+Implemented by Greg V. Wilson, Alex Martelli, and GvR.}
+
+\end{seealso}
+
+
+
+%======================================================================
+\section{PEP 255: Simple Generators\label{section-generators}}
+
+In Python 2.2, generators were added as an optional feature, to be
+enabled by a \code{from __future__ import generators} directive.  In
+2.3 generators no longer need to be specially enabled, and are now
+always present; this means that \keyword{yield} is now always a
+keyword.  The rest of this section is a copy of the description of
+generators from the ``What's New in Python 2.2'' document; if you read
+it back when Python 2.2 came out, you can skip the rest of this section.
+
+You're doubtless familiar with how function calls work in Python or C.
+When you call a function, it gets a private namespace where its local
+variables are created.  When the function reaches a \keyword{return}
+statement, the local variables are destroyed and the resulting value
+is returned to the caller.  A later call to the same function will get
+a fresh new set of local variables. But, what if the local variables
+weren't thrown away on exiting a function?  What if you could later
+resume the function where it left off?  This is what generators
+provide; they can be thought of as resumable functions.
+
+Here's the simplest example of a generator function:
+
+\begin{verbatim}
+def generate_ints(N):
+    for i in range(N):
+        yield i
+\end{verbatim}
+
+A new keyword, \keyword{yield}, was introduced for generators.  Any
+function containing a \keyword{yield} statement is a generator
+function; this is detected by Python's bytecode compiler which
+compiles the function specially as a result.
+
+When you call a generator function, it doesn't return a single value;
+instead it returns a generator object that supports the iterator
+protocol.  On executing the \keyword{yield} statement, the generator
+outputs the value of \code{i}, similar to a \keyword{return}
+statement.  The big difference between \keyword{yield} and a
+\keyword{return} statement is that on reaching a \keyword{yield} the
+generator's state of execution is suspended and local variables are
+preserved.  On the next call to the generator's \code{.next()} method,
+the function will resume executing immediately after the
+\keyword{yield} statement.  (For complicated reasons, the
+\keyword{yield} statement isn't allowed inside the \keyword{try} block
+of a \keyword{try}...\keyword{finally} statement; read \pep{255} for a full
+explanation of the interaction between \keyword{yield} and
+exceptions.)
+
+Here's a sample usage of the \function{generate_ints()} generator:
+
+\begin{verbatim}
+>>> gen = generate_ints(3)
+>>> gen
+<generator object at 0x8117f90>
+>>> gen.next()
+0
+>>> gen.next()
+1
+>>> gen.next()
+2
+>>> gen.next()
+Traceback (most recent call last):
+  File "stdin", line 1, in ?
+  File "stdin", line 2, in generate_ints
+StopIteration
+\end{verbatim}
+
+You could equally write \code{for i in generate_ints(5)}, or
+\code{a,b,c = generate_ints(3)}.
+
+Inside a generator function, the \keyword{return} statement can only
+be used without a value, and signals the end of the procession of
+values; afterwards the generator cannot return any further values.
+\keyword{return} with a value, such as \code{return 5}, is a syntax
+error inside a generator function.  The end of the generator's results
+can also be indicated by raising \exception{StopIteration} manually,
+or by just letting the flow of execution fall off the bottom of the
+function.
+
+You could achieve the effect of generators manually by writing your
+own class and storing all the local variables of the generator as
+instance variables.  For example, returning a list of integers could
+be done by setting \code{self.count} to 0, and having the
+\method{next()} method increment \code{self.count} and return it.
+However, for a moderately complicated generator, writing a
+corresponding class would be much messier.
+\file{Lib/test/test_generators.py} contains a number of more
+interesting examples.  The simplest one implements an in-order
+traversal of a tree using generators recursively.
+
+\begin{verbatim}
+# A recursive generator that generates Tree leaves in in-order.
+def inorder(t):
+    if t:
+        for x in inorder(t.left):
+            yield x
+        yield t.label
+        for x in inorder(t.right):
+            yield x
+\end{verbatim}
+
+Two other examples in \file{Lib/test/test_generators.py} produce
+solutions for the N-Queens problem (placing $N$ queens on an $NxN$
+chess board so that no queen threatens another) and the Knight's Tour
+(a route that takes a knight to every square of an $NxN$ chessboard
+without visiting any square twice).
+
+The idea of generators comes from other programming languages,
+especially Icon (\url{http://www.cs.arizona.edu/icon/}), where the
+idea of generators is central.  In Icon, every
+expression and function call behaves like a generator.  One example
+from ``An Overview of the Icon Programming Language'' at
+\url{http://www.cs.arizona.edu/icon/docs/ipd266.htm} gives an idea of
+what this looks like:
+
+\begin{verbatim}
+sentence := "Store it in the neighboring harbor"
+if (i := find("or", sentence)) > 5 then write(i)
+\end{verbatim}
+
+In Icon the \function{find()} function returns the indexes at which the
+substring ``or'' is found: 3, 23, 33.  In the \keyword{if} statement,
+\code{i} is first assigned a value of 3, but 3 is less than 5, so the
+comparison fails, and Icon retries it with the second value of 23.  23
+is greater than 5, so the comparison now succeeds, and the code prints
+the value 23 to the screen.
+
+Python doesn't go nearly as far as Icon in adopting generators as a
+central concept.  Generators are considered part of the core
+Python language, but learning or using them isn't compulsory; if they
+don't solve any problems that you have, feel free to ignore them.
+One novel feature of Python's interface as compared to
+Icon's is that a generator's state is represented as a concrete object
+(the iterator) that can be passed around to other functions or stored
+in a data structure.
+
+\begin{seealso}
+
+\seepep{255}{Simple Generators}{Written by Neil Schemenauer, Tim
+Peters, Magnus Lie Hetland.  Implemented mostly by Neil Schemenauer
+and Tim Peters, with other fixes from the Python Labs crew.}
+
+\end{seealso}
+
+
+%======================================================================
+\section{PEP 263: Source Code Encodings \label{section-encodings}}
+
+Python source files can now be declared as being in different
+character set encodings.  Encodings are declared by including a
+specially formatted comment in the first or second line of the source
+file.  For example, a UTF-8 file can be declared with:
+
+\begin{verbatim}
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+\end{verbatim}
+
+Without such an encoding declaration, the default encoding used is
+7-bit ASCII.  Executing or importing modules that contain string
+literals with 8-bit characters and have no encoding declaration will result
+in a \exception{DeprecationWarning} being signalled by Python 2.3; in
+2.4 this will be a syntax error.
+
+The encoding declaration only affects Unicode string literals, which
+will be converted to Unicode using the specified encoding.  Note that
+Python identifiers are still restricted to ASCII characters, so you
+can't have variable names that use characters outside of the usual
+alphanumerics.
+
+\begin{seealso}
+
+\seepep{263}{Defining Python Source Code Encodings}{Written by
+Marc-Andr\'e Lemburg and Martin von~L\"owis; implemented by Suzuki
+Hisao and Martin von~L\"owis.}
+
+\end{seealso}
+
+
+%======================================================================
+\section{PEP 273: Importing Modules from ZIP Archives}
+
+The new \module{zipimport} module adds support for importing
+modules from a ZIP-format archive.  You don't need to import the
+module explicitly; it will be automatically imported if a ZIP
+archive's filename is added to \code{sys.path}.  For example:
+
+\begin{verbatim}
+amk at nyman:~/src/python$ unzip -l /tmp/example.zip
+Archive:  /tmp/example.zip
+  Length     Date   Time    Name
+ --------    ----   ----    ----
+     8467  11-26-02 22:30   jwzthreading.py
+ --------                   -------
+     8467                   1 file
+amk at nyman:~/src/python$ ./python
+Python 2.3 (#1, Aug 1 2003, 19:54:32) 
+>>> import sys
+>>> sys.path.insert(0, '/tmp/example.zip')  # Add .zip file to front of path
+>>> import jwzthreading
+>>> jwzthreading.__file__
+'/tmp/example.zip/jwzthreading.py'
+>>>
+\end{verbatim}
+
+An entry in \code{sys.path} can now be the filename of a ZIP archive.
+The ZIP archive can contain any kind of files, but only files named
+\file{*.py}, \file{*.pyc}, or \file{*.pyo} can be imported.  If an
+archive only contains \file{*.py} files, Python will not attempt to
+modify the archive by adding the corresponding \file{*.pyc} file, meaning
+that if a ZIP archive doesn't contain \file{*.pyc} files, importing may be
+rather slow.
+
+A path within the archive can also be specified to only import from a
+subdirectory; for example, the path \file{/tmp/example.zip/lib/}
+would only import from the \file{lib/} subdirectory within the
+archive.
+
+\begin{seealso}
+
+\seepep{273}{Import Modules from Zip Archives}{Written by James C. Ahlstrom, 
+who also provided an implementation.
+Python 2.3 follows the specification in \pep{273}, 
+but uses an implementation written by Just van~Rossum 
+that uses the import hooks described in \pep{302}.
+See section~\ref{section-pep302} for a description of the new import hooks.
+}
+
+\end{seealso}
+
+%======================================================================
+\section{PEP 277: Unicode file name support for Windows NT}
+
+On Windows NT, 2000, and XP, the system stores file names as Unicode
+strings. Traditionally, Python has represented file names as byte
+strings, which is inadequate because it renders some file names
+inaccessible.
+
+Python now allows using arbitrary Unicode strings (within the
+limitations of the file system) for all functions that expect file
+names, most notably the \function{open()} built-in function. If a Unicode
+string is passed to \function{os.listdir()}, Python now returns a list
+of Unicode strings.  A new function, \function{os.getcwdu()}, returns
+the current directory as a Unicode string.
+
+Byte strings still work as file names, and on Windows Python will
+transparently convert them to Unicode using the \code{mbcs} encoding.
+
+Other systems also allow Unicode strings as file names but convert
+them to byte strings before passing them to the system, which can
+cause a \exception{UnicodeError} to be raised. Applications can test
+whether arbitrary Unicode strings are supported as file names by
+checking \member{os.path.supports_unicode_filenames}, a Boolean value.
+
+Under MacOS, \function{os.listdir()} may now return Unicode filenames.
+
+\begin{seealso}
+
+\seepep{277}{Unicode file name support for Windows NT}{Written by Neil
+Hodgson; implemented by Neil Hodgson, Martin von~L\"owis, and Mark
+Hammond.}
+
+\end{seealso}
+
+
+%======================================================================
+\section{PEP 278: Universal Newline Support}
+
+The three major operating systems used today are Microsoft Windows,
+Apple's Macintosh OS, and the various \UNIX\ derivatives.  A minor
+irritation of cross-platform work 
+is that these three platforms all use different characters
+to mark the ends of lines in text files.  \UNIX\ uses the linefeed
+(ASCII character 10), MacOS uses the carriage return (ASCII
+character 13), and Windows uses a two-character sequence of a
+carriage return plus a newline.
+
+Python's file objects can now support end of line conventions other
+than the one followed by the platform on which Python is running.
+Opening a file with the mode \code{'U'} or \code{'rU'} will open a file
+for reading in universal newline mode.  All three line ending
+conventions will be translated to a \character{\e n} in the strings
+returned by the various file methods such as \method{read()} and
+\method{readline()}.
+
+Universal newline support is also used when importing modules and when
+executing a file with the \function{execfile()} function.  This means
+that Python modules can be shared between all three operating systems
+without needing to convert the line-endings.
+
+This feature can be disabled when compiling Python by specifying
+the \longprogramopt{without-universal-newlines} switch when running Python's
+\program{configure} script.
+
+\begin{seealso}
+
+\seepep{278}{Universal Newline Support}{Written
+and implemented by Jack Jansen.}
+
+\end{seealso}
+
+
+%======================================================================
+\section{PEP 279: enumerate()\label{section-enumerate}}
+
+A new built-in function, \function{enumerate()}, will make
+certain loops a bit clearer.  \code{enumerate(thing)}, where
+\var{thing} is either an iterator or a sequence, returns a iterator
+that will return \code{(0, \var{thing}[0])}, \code{(1,
+\var{thing}[1])}, \code{(2, \var{thing}[2])}, and so forth.  
+
+A common idiom to change every element of a list looks like this:
+
+\begin{verbatim}
+for i in range(len(L)):
+    item = L[i]
+    # ... compute some result based on item ...
+    L[i] = result
+\end{verbatim}
+
+This can be rewritten using \function{enumerate()} as:
+
+\begin{verbatim}
+for i, item in enumerate(L):
+    # ... compute some result based on item ...
+    L[i] = result
+\end{verbatim}
+
+
+\begin{seealso}
+
+\seepep{279}{The enumerate() built-in function}{Written
+and implemented by Raymond D. Hettinger.}
+
+\end{seealso}
+
+
+%======================================================================
+\section{PEP 282: The logging Package}
+
+A standard package for writing logs, \module{logging}, has been added
+to Python 2.3.  It provides a powerful and flexible mechanism for
+generating logging output which can then be filtered and processed in
+various ways.  A configuration file written in a standard format can
+be used to control the logging behavior of a program.  Python
+includes handlers that will write log records to
+standard error or to a file or socket, send them to the system log, or
+even e-mail them to a particular address; of course, it's also
+possible to write your own handler classes.
+
+The \class{Logger} class is the primary class.
+Most application code will deal with one or more \class{Logger}
+objects, each one used by a particular subsystem of the application.
+Each \class{Logger} is identified by a name, and names are organized
+into a hierarchy using \samp{.}  as the component separator.  For
+example, you might have \class{Logger} instances named \samp{server},
+\samp{server.auth} and \samp{server.network}.  The latter two
+instances are below \samp{server} in the hierarchy.  This means that
+if you turn up the verbosity for \samp{server} or direct \samp{server}
+messages to a different handler, the changes will also apply to
+records logged to \samp{server.auth} and \samp{server.network}.
+There's also a root \class{Logger} that's the parent of all other
+loggers.
+
+For simple uses, the \module{logging} package contains some
+convenience functions that always use the root log:
+
+\begin{verbatim}
+import logging
+
+logging.debug('Debugging information')
+logging.info('Informational message')
+logging.warning('Warning:config file %s not found', 'server.conf')
+logging.error('Error occurred')
+logging.critical('Critical error -- shutting down')
+\end{verbatim}
+
+This produces the following output:
+
+\begin{verbatim}
+WARNING:root:Warning:config file server.conf not found
+ERROR:root:Error occurred
+CRITICAL:root:Critical error -- shutting down
+\end{verbatim}
+
+In the default configuration, informational and debugging messages are
+suppressed and the output is sent to standard error.  You can enable
+the display of informational and debugging messages by calling the
+\method{setLevel()} method on the root logger.
+
+Notice the \function{warning()} call's use of string formatting
+operators; all of the functions for logging messages take the
+arguments \code{(\var{msg}, \var{arg1}, \var{arg2}, ...)} and log the
+string resulting from \code{\var{msg} \% (\var{arg1}, \var{arg2},
+...)}.
+
+There's also an \function{exception()} function that records the most
+recent traceback.  Any of the other functions will also record the
+traceback if you specify a true value for the keyword argument
+\var{exc_info}.
+
+\begin{verbatim}
+def f():
+    try:    1/0
+    except: logging.exception('Problem recorded')
+
+f()
+\end{verbatim}
+
+This produces the following output:
+
+\begin{verbatim}
+ERROR:root:Problem recorded
+Traceback (most recent call last):
+  File "t.py", line 6, in f
+    1/0
+ZeroDivisionError: integer division or modulo by zero
+\end{verbatim}
+
+Slightly more advanced programs will use a logger other than the root
+logger.  The \function{getLogger(\var{name})} function is used to get
+a particular log, creating it if it doesn't exist yet.
+\function{getLogger(None)} returns the root logger.
+
+
+\begin{verbatim}
+log = logging.getLogger('server')
+ ...
+log.info('Listening on port %i', port)
+ ...
+log.critical('Disk full')
+ ...
+\end{verbatim}
+
+Log records are usually propagated up the hierarchy, so a message
+logged to \samp{server.auth} is also seen by \samp{server} and
+\samp{root}, but a \class{Logger} can prevent this by setting its
+\member{propagate} attribute to \constant{False}.
+
+There are more classes provided by the \module{logging} package that
+can be customized.  When a \class{Logger} instance is told to log a
+message, it creates a \class{LogRecord} instance that is sent to any
+number of different \class{Handler} instances.  Loggers and handlers
+can also have an attached list of filters, and each filter can cause
+the \class{LogRecord} to be ignored or can modify the record before
+passing it along.  When they're finally output, \class{LogRecord}
+instances are converted to text by a \class{Formatter} class.  All of
+these classes can be replaced by your own specially-written classes.
+
+With all of these features the \module{logging} package should provide
+enough flexibility for even the most complicated applications.  This
+is only an incomplete overview of its features, so please see the
+\ulink{package's reference documentation}{../lib/module-logging.html}
+for all of the details.  Reading \pep{282} will also be helpful.
+
+
+\begin{seealso}
+
+\seepep{282}{A Logging System}{Written by Vinay Sajip and Trent Mick;
+implemented by Vinay Sajip.}
+
+\end{seealso}
+
+
+%======================================================================
+\section{PEP 285: A Boolean Type\label{section-bool}}
+
+A Boolean type was added to Python 2.3.  Two new constants were added
+to the \module{__builtin__} module, \constant{True} and
+\constant{False}.  (\constant{True} and
+\constant{False} constants were added to the built-ins
+in Python 2.2.1, but the 2.2.1 versions are simply set to integer values of
+1 and 0 and aren't a different type.)
+
+The type object for this new type is named
+\class{bool}; the constructor for it takes any Python value and
+converts it to \constant{True} or \constant{False}.
+
+\begin{verbatim}
+>>> bool(1)
+True
+>>> bool(0)
+False
+>>> bool([])
+False
+>>> bool( (1,) )
+True
+\end{verbatim}
+
+Most of the standard library modules and built-in functions have been
+changed to return Booleans.
+
+\begin{verbatim}
+>>> obj = []
+>>> hasattr(obj, 'append')
+True
+>>> isinstance(obj, list)
+True
+>>> isinstance(obj, tuple)
+False
+\end{verbatim}
+
+Python's Booleans were added with the primary goal of making code
+clearer.  For example, if you're reading a function and encounter the
+statement \code{return 1}, you might wonder whether the \code{1}
+represents a Boolean truth value, an index, or a
+coefficient that multiplies some other quantity.  If the statement is
+\code{return True}, however, the meaning of the return value is quite
+clear.
+
+Python's Booleans were \emph{not} added for the sake of strict
+type-checking.  A very strict language such as Pascal would also
+prevent you performing arithmetic with Booleans, and would require
+that the expression in an \keyword{if} statement always evaluate to a
+Boolean result.  Python is not this strict and never will be, as
+\pep{285} explicitly says.  This means you can still use any
+expression in an \keyword{if} statement, even ones that evaluate to a
+list or tuple or some random object.  The Boolean type is a
+subclass of the \class{int} class so that arithmetic using a Boolean
+still works.
+
+\begin{verbatim}
+>>> True + 1
+2
+>>> False + 1
+1
+>>> False * 75
+0
+>>> True * 75
+75
+\end{verbatim}
+
+To sum up \constant{True} and \constant{False} in a sentence: they're
+alternative ways to spell the integer values 1 and 0, with the single
+difference that \function{str()} and \function{repr()} return the
+strings \code{'True'} and \code{'False'} instead of \code{'1'} and
+\code{'0'}.
+
+\begin{seealso}
+
+\seepep{285}{Adding a bool type}{Written and implemented by GvR.}
+
+\end{seealso}
+
+
+%======================================================================
+\section{PEP 293: Codec Error Handling Callbacks}
+
+When encoding a Unicode string into a byte string, unencodable
+characters may be encountered.  So far, Python has allowed specifying
+the error processing as either ``strict'' (raising
+\exception{UnicodeError}), ``ignore'' (skipping the character), or
+``replace'' (using a question mark in the output string), with
+``strict'' being the default behavior. It may be desirable to specify
+alternative processing of such errors, such as inserting an XML
+character reference or HTML entity reference into the converted
+string.
+
+Python now has a flexible framework to add different processing
+strategies.  New error handlers can be added with
+\function{codecs.register_error}, and codecs then can access the error
+handler with \function{codecs.lookup_error}. An equivalent C API has
+been added for codecs written in C. The error handler gets the
+necessary state information such as the string being converted, the
+position in the string where the error was detected, and the target
+encoding.  The handler can then either raise an exception or return a
+replacement string.
+
+Two additional error handlers have been implemented using this
+framework: ``backslashreplace'' uses Python backslash quoting to
+represent unencodable characters and ``xmlcharrefreplace'' emits
+XML character references.
+
+\begin{seealso}
+
+\seepep{293}{Codec Error Handling Callbacks}{Written and implemented by
+Walter D\"orwald.}
+
+\end{seealso}
+
+
+%======================================================================
+\section{PEP 301: Package Index and Metadata for
+Distutils\label{section-pep301}}
+
+Support for the long-requested Python catalog makes its first
+appearance in 2.3.
+
+The heart of the catalog is the new Distutils \command{register} command.
+Running \code{python setup.py register} will collect the metadata
+describing a package, such as its name, version, maintainer,
+description, \&c., and send it to a central catalog server.  The
+resulting catalog is available from \url{http://www.python.org/pypi}.
+
+To make the catalog a bit more useful, a new optional
+\var{classifiers} keyword argument has been added to the Distutils
+\function{setup()} function.  A list of
+\ulink{Trove}{http://catb.org/\textasciitilde esr/trove/}-style
+strings can be supplied to help classify the software.
+
+Here's an example \file{setup.py} with classifiers, written to be compatible 
+with older versions of the Distutils:
+
+\begin{verbatim}
+from distutils import core
+kw = {'name': "Quixote",
+      'version': "0.5.1",
+      'description': "A highly Pythonic Web application framework",
+      # ...
+      }
+
+if (hasattr(core, 'setup_keywords') and 
+    'classifiers' in core.setup_keywords):
+    kw['classifiers'] = \
+        ['Topic :: Internet :: WWW/HTTP :: Dynamic Content',
+         'Environment :: No Input/Output (Daemon)',
+         'Intended Audience :: Developers'],
+
+core.setup(**kw)
+\end{verbatim}
+
+The full list of classifiers can be obtained by running 
+\verb|python setup.py register --list-classifiers|.
+
+\begin{seealso}
+
+\seepep{301}{Package Index and Metadata for Distutils}{Written and
+implemented by Richard Jones.}
+
+\end{seealso}
+
+
+%======================================================================
+\section{PEP 302: New Import Hooks \label{section-pep302}}
+
+While it's been possible to write custom import hooks ever since the
+\module{ihooks} module was introduced in Python 1.3, no one has ever
+been really happy with it because writing new import hooks is
+difficult and messy.  There have been various proposed alternatives
+such as the \module{imputil} and \module{iu} modules, but none of them
+has ever gained much acceptance, and none of them were easily usable
+from \C{} code.
+
+\pep{302} borrows ideas from its predecessors, especially from
+Gordon McMillan's \module{iu} module.  Three new items 
+are added to the \module{sys} module:
+
+\begin{itemize}
+  \item \code{sys.path_hooks} is a list of callable objects; most 
+  often they'll be classes.  Each callable takes a string containing a
+  path and either returns an importer object that will handle imports
+  from this path or raises an \exception{ImportError} exception if it
+  can't handle this path.
+
+  \item \code{sys.path_importer_cache} caches importer objects for
+  each path, so \code{sys.path_hooks} will only need to be traversed
+  once for each path.
+
+  \item \code{sys.meta_path} is a list of importer objects that will
+  be traversed before \code{sys.path} is checked.  This list is
+  initially empty, but user code can add objects to it.  Additional
+  built-in and frozen modules can be imported by an object added to
+  this list.
+
+\end{itemize}
+
+Importer objects must have a single method,
+\method{find_module(\var{fullname}, \var{path}=None)}.  \var{fullname}
+will be a module or package name, e.g. \samp{string} or
+\samp{distutils.core}.  \method{find_module()} must return a loader object
+that has a single method, \method{load_module(\var{fullname})}, that
+creates and returns the corresponding module object.
+
+Pseudo-code for Python's new import logic, therefore, looks something
+like this (simplified a bit; see \pep{302} for the full details):
+
+\begin{verbatim}
+for mp in sys.meta_path:
+    loader = mp(fullname)
+    if loader is not None:
+        <module> = loader.load_module(fullname)
+        
+for path in sys.path:
+    for hook in sys.path_hooks:
+        try:
+            importer = hook(path)
+        except ImportError:
+            # ImportError, so try the other path hooks
+            pass
+        else:
+            loader = importer.find_module(fullname)
+            <module> = loader.load_module(fullname)
+
+# Not found!
+raise ImportError
+\end{verbatim}
+
+\begin{seealso}
+
+\seepep{302}{New Import Hooks}{Written by Just van~Rossum and Paul Moore.
+Implemented by Just van~Rossum.
+}
+
+\end{seealso}
+
+
+%======================================================================
+\section{PEP 305: Comma-separated Files \label{section-pep305}}
+
+Comma-separated files are a format frequently used for exporting data
+from databases and spreadsheets.  Python 2.3 adds a parser for
+comma-separated files.
+
+Comma-separated format is deceptively simple at first glance:
+
+\begin{verbatim}
+Costs,150,200,3.95
+\end{verbatim}
+
+Read a line and call \code{line.split(',')}: what could be simpler?
+But toss in string data that can contain commas, and things get more
+complicated:
+
+\begin{verbatim}
+"Costs",150,200,3.95,"Includes taxes, shipping, and sundry items"
+\end{verbatim}
+
+A big ugly regular expression can parse this, but using the new 
+\module{csv} package is much simpler:
+
+\begin{verbatim}
+import csv
+
+input = open('datafile', 'rb')
+reader = csv.reader(input)
+for line in reader:
+    print line
+\end{verbatim}
+
+The \function{reader} function takes a number of different options.
+The field separator isn't limited to the comma and can be changed to
+any character, and so can the quoting and line-ending characters.
+
+Different dialects of comma-separated files can be defined and
+registered; currently there are two dialects, both used by Microsoft Excel.
+A separate \class{csv.writer} class will generate comma-separated files
+from a succession of tuples or lists, quoting strings that contain the
+delimiter.  
+
+\begin{seealso}
+
+\seepep{305}{CSV File API}{Written and implemented 
+by Kevin Altis, Dave Cole, Andrew McNamara, Skip Montanaro, Cliff Wells.
+}
+
+\end{seealso}
+
+%======================================================================
+\section{PEP 307: Pickle Enhancements \label{section-pep305}}
+
+The \module{pickle} and \module{cPickle} modules received some
+attention during the 2.3 development cycle.  In 2.2, new-style classes
+could be pickled without difficulty, but they weren't pickled very
+compactly; \pep{307} quotes a trivial example where a new-style class
+results in a pickled string three times longer than that for a classic
+class.
+
+The solution was to invent a new pickle protocol.  The
+\function{pickle.dumps()} function has supported a text-or-binary flag 
+for a long time.  In 2.3, this flag is redefined from a Boolean to an
+integer: 0 is the old text-mode pickle format, 1 is the old binary
+format, and now 2 is a new 2.3-specific format.  A new constant,
+\constant{pickle.HIGHEST_PROTOCOL}, can be used to select the fanciest
+protocol available.
+
+Unpickling is no longer considered a safe operation.  2.2's
+\module{pickle} provided hooks for trying to prevent unsafe classes
+from being unpickled (specifically, a
+\member{__safe_for_unpickling__} attribute), but none of this code
+was ever audited and therefore it's all been ripped out in 2.3.  You
+should not unpickle untrusted data in any version of Python.
+
+To reduce the pickling overhead for new-style classes, a new interface
+for customizing pickling was added using three special methods:
+\method{__getstate__}, \method{__setstate__}, and
+\method{__getnewargs__}.  Consult \pep{307} for the full semantics 
+of these methods.
+
+As a way to compress pickles yet further, it's now possible to use
+integer codes instead of long strings to identify pickled classes.
+The Python Software Foundation will maintain a list of standardized
+codes; there's also a range of codes for private use.  Currently no
+codes have been specified.
+
+\begin{seealso}
+
+\seepep{307}{Extensions to the pickle protocol}{Written and implemented 
+by Guido van Rossum and Tim Peters.}
+
+\end{seealso}
+
+%======================================================================
+\section{Extended Slices\label{section-slices}}
+
+Ever since Python 1.4, the slicing syntax has supported an optional
+third ``step'' or ``stride'' argument.  For example, these are all
+legal Python syntax: \code{L[1:10:2]}, \code{L[:-1:1]},
+\code{L[::-1]}.  This was added to Python at the request of
+the developers of Numerical Python, which uses the third argument
+extensively.  However, Python's built-in list, tuple, and string
+sequence types have never supported this feature, raising a
+\exception{TypeError} if you tried it.  Michael Hudson contributed a
+patch to fix this shortcoming.
+
+For example, you can now easily extract the elements of a list that
+have even indexes:
+
+\begin{verbatim}
+>>> L = range(10)
+>>> L[::2]
+[0, 2, 4, 6, 8]
+\end{verbatim}
+
+Negative values also work to make a copy of the same list in reverse
+order:
+
+\begin{verbatim}
+>>> L[::-1]
+[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
+\end{verbatim}
+
+This also works for tuples, arrays, and strings:
+
+\begin{verbatim}
+>>> s='abcd'
+>>> s[::2]
+'ac'
+>>> s[::-1]
+'dcba'
+\end{verbatim}
+
+If you have a mutable sequence such as a list or an array you can
+assign to or delete an extended slice, but there are some differences
+between assignment to extended and regular slices.  Assignment to a
+regular slice can be used to change the length of the sequence:
+
+\begin{verbatim}
+>>> a = range(3)
+>>> a
+[0, 1, 2]
+>>> a[1:3] = [4, 5, 6]
+>>> a
+[0, 4, 5, 6]
+\end{verbatim}
+
+Extended slices aren't this flexible.  When assigning to an extended
+slice, the list on the right hand side of the statement must contain
+the same number of items as the slice it is replacing:
+
+\begin{verbatim}
+>>> a = range(4)
+>>> a
+[0, 1, 2, 3]
+>>> a[::2]
+[0, 2]
+>>> a[::2] = [0, -1]
+>>> a
+[0, 1, -1, 3]
+>>> a[::2] = [0,1,2]
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+ValueError: attempt to assign sequence of size 3 to extended slice of size 2
+\end{verbatim}
+
+Deletion is more straightforward:
+
+\begin{verbatim}
+>>> a = range(4)
+>>> a
+[0, 1, 2, 3]
+>>> a[::2]
+[0, 2]
+>>> del a[::2]
+>>> a
+[1, 3]
+\end{verbatim}
+
+One can also now pass slice objects to the
+\method{__getitem__} methods of the built-in sequences:
+
+\begin{verbatim}
+>>> range(10).__getitem__(slice(0, 5, 2))
+[0, 2, 4]
+\end{verbatim}
+
+Or use slice objects directly in subscripts:
+
+\begin{verbatim}
+>>> range(10)[slice(0, 5, 2)]
+[0, 2, 4]
+\end{verbatim}
+
+To simplify implementing sequences that support extended slicing,
+slice objects now have a method \method{indices(\var{length})} which,
+given the length of a sequence, returns a \code{(\var{start},
+\var{stop}, \var{step})} tuple that can be passed directly to
+\function{range()}.
+\method{indices()} handles omitted and out-of-bounds indices in a
+manner consistent with regular slices (and this innocuous phrase hides
+a welter of confusing details!).  The method is intended to be used
+like this:
+
+\begin{verbatim}
+class FakeSeq:
+    ...
+    def calc_item(self, i):
+        ...
+    def __getitem__(self, item):
+        if isinstance(item, slice):
+            indices = item.indices(len(self))
+            return FakeSeq([self.calc_item(i) for i in range(*indices)])
+        else:
+            return self.calc_item(i)
+\end{verbatim}
+
+From this example you can also see that the built-in \class{slice}
+object is now the type object for the slice type, and is no longer a
+function.  This is consistent with Python 2.2, where \class{int},
+\class{str}, etc., underwent the same change.
+
+
+%======================================================================
+\section{Other Language Changes}
+
+Here are all of the changes that Python 2.3 makes to the core Python
+language.
+
+\begin{itemize}
+\item The \keyword{yield} statement is now always a keyword, as
+described in section~\ref{section-generators} of this document.
+
+\item A new built-in function \function{enumerate()}
+was added, as described in section~\ref{section-enumerate} of this
+document.
+
+\item Two new constants, \constant{True} and \constant{False} were
+added along with the built-in \class{bool} type, as described in
+section~\ref{section-bool} of this document.
+
+\item The \function{int()} type constructor will now return a long
+integer instead of raising an \exception{OverflowError} when a string
+or floating-point number is too large to fit into an integer.  This
+can lead to the paradoxical result that
+\code{isinstance(int(\var{expression}), int)} is false, but that seems
+unlikely to cause problems in practice.
+
+\item Built-in types now support the extended slicing syntax,
+as described in section~\ref{section-slices} of this document.
+
+\item A new built-in function, \function{sum(\var{iterable}, \var{start}=0)}, 
+adds up the numeric items in the iterable object and returns their sum. 
+\function{sum()} only accepts numbers, meaning that you can't use it
+to concatenate a bunch of strings.   (Contributed by Alex
+Martelli.)
+
+\item \code{list.insert(\var{pos}, \var{value})} used to 
+insert \var{value} at the front of the list when \var{pos} was
+negative.  The behaviour has now been changed to be consistent with
+slice indexing, so when \var{pos} is -1 the value will be inserted
+before the last element, and so forth.
+
+\item \code{list.index(\var{value})}, which searches for \var{value} 
+within the list and returns its index, now takes optional 
+\var{start} and \var{stop} arguments to limit the search to 
+only part of the list.
+
+\item Dictionaries have a new method, \method{pop(\var{key}\optional{,
+\var{default}})}, that returns the value corresponding to \var{key}
+and removes that key/value pair from the dictionary.  If the requested
+key isn't present in the dictionary, \var{default} is returned if it's
+specified and \exception{KeyError} raised if it isn't.
+
+\begin{verbatim}
+>>> d = {1:2}
+>>> d
+{1: 2}
+>>> d.pop(4)
+Traceback (most recent call last):
+  File "stdin", line 1, in ?
+KeyError: 4
+>>> d.pop(1)
+2
+>>> d.pop(1)
+Traceback (most recent call last):
+  File "stdin", line 1, in ?
+KeyError: 'pop(): dictionary is empty'
+>>> d
+{}
+>>>
+\end{verbatim}
+
+There's also a new class method, 
+\method{dict.fromkeys(\var{iterable}, \var{value})}, that 
+creates a dictionary with keys taken from the supplied iterator
+\var{iterable} and all values set to \var{value}, defaulting to
+\code{None}.  
+
+(Patches contributed by Raymond Hettinger.)
+
+Also, the \function{dict()} constructor now accepts keyword arguments to
+simplify creating small dictionaries:
+
+\begin{verbatim}
+>>> dict(red=1, blue=2, green=3, black=4)
+{'blue': 2, 'black': 4, 'green': 3, 'red': 1}    
+\end{verbatim}
+
+(Contributed by Just van~Rossum.)       
+
+\item The \keyword{assert} statement no longer checks the \code{__debug__}
+flag, so you can no longer disable assertions by assigning to \code{__debug__}.
+Running Python with the \programopt{-O} switch will still generate
+code that doesn't execute any assertions.
+
+\item Most type objects are now callable, so you can use them
+to create new objects such as functions, classes, and modules.  (This
+means that the \module{new} module can be deprecated in a future
+Python version, because you can now use the type objects available in
+the \module{types} module.)
+% XXX should new.py use PendingDeprecationWarning?
+For example, you can create a new module object with the following code:
+
+\begin{verbatim}
+>>> import types
+>>> m = types.ModuleType('abc','docstring')
+>>> m
+<module 'abc' (built-in)>
+>>> m.__doc__
+'docstring'
+\end{verbatim}
+
+\item
+A new warning, \exception{PendingDeprecationWarning} was added to
+indicate features which are in the process of being
+deprecated.  The warning will \emph{not} be printed by default.  To
+check for use of features that will be deprecated in the future,
+supply \programopt{-Walways::PendingDeprecationWarning::} on the
+command line or use \function{warnings.filterwarnings()}.
+
+\item The process of deprecating string-based exceptions, as
+in \code{raise "Error occurred"}, has begun.  Raising a string will
+now trigger \exception{PendingDeprecationWarning}.
+
+\item Using \code{None} as a variable name will now result in a
+\exception{SyntaxWarning} warning.  In a future version of Python,
+\code{None} may finally become a keyword.
+
+\item The \method{xreadlines()} method of file objects, introduced in
+Python 2.1, is no longer necessary because files now behave as their
+own iterator.  \method{xreadlines()} was originally introduced as a
+faster way to loop over all the lines in a file, but now you can
+simply write \code{for line in file_obj}.  File objects also have a
+new read-only \member{encoding} attribute that gives the encoding used
+by the file; Unicode strings written to the file will be automatically 
+converted to bytes using the given encoding.
+
+\item The method resolution order used by new-style classes has
+changed, though you'll only notice the difference if you have a really
+complicated inheritance hierarchy.  Classic classes are unaffected by
+this change.  Python 2.2 originally used a topological sort of a
+class's ancestors, but 2.3 now uses the C3 algorithm as described in
+the paper \ulink{``A Monotonic Superclass Linearization for
+Dylan''}{http://www.webcom.com/haahr/dylan/linearization-oopsla96.html}.
+To understand the motivation for this change, 
+read Michele Simionato's article 
+\ulink{``Python 2.3 Method Resolution Order''}
+      {http://www.python.org/2.3/mro.html}, or
+read the thread on python-dev starting with the message at
+\url{http://mail.python.org/pipermail/python-dev/2002-October/029035.html}.
+Samuele Pedroni first pointed out the problem and also implemented the
+fix by coding the C3 algorithm.
+
+\item Python runs multithreaded programs by switching between threads
+after executing N bytecodes.  The default value for N has been
+increased from 10 to 100 bytecodes, speeding up single-threaded
+applications by reducing the switching overhead.  Some multithreaded
+applications may suffer slower response time, but that's easily fixed
+by setting the limit back to a lower number using
+\function{sys.setcheckinterval(\var{N})}.
+The limit can be retrieved with the new 
+\function{sys.getcheckinterval()} function.
+
+\item One minor but far-reaching change is that the names of extension
+types defined by the modules included with Python now contain the
+module and a \character{.} in front of the type name.  For example, in
+Python 2.2, if you created a socket and printed its
+\member{__class__}, you'd get this output:
+
+\begin{verbatim}
+>>> s = socket.socket()
+>>> s.__class__
+<type 'socket'>
+\end{verbatim}
+
+In 2.3, you get this:
+\begin{verbatim}
+>>> s.__class__
+<type '_socket.socket'>
+\end{verbatim}
+
+\item One of the noted incompatibilities between old- and new-style
+  classes has been removed: you can now assign to the
+  \member{__name__} and \member{__bases__} attributes of new-style
+  classes.  There are some restrictions on what can be assigned to
+  \member{__bases__} along the lines of those relating to assigning to
+  an instance's \member{__class__} attribute.
+
+\end{itemize}
+
+
+%======================================================================
+\subsection{String Changes}
+
+\begin{itemize}
+
+\item The \keyword{in} operator now works differently for strings.
+Previously, when evaluating \code{\var{X} in \var{Y}} where \var{X}
+and \var{Y} are strings, \var{X} could only be a single character.
+That's now changed; \var{X} can be a string of any length, and
+\code{\var{X} in \var{Y}} will return \constant{True} if \var{X} is a
+substring of \var{Y}.  If \var{X} is the empty string, the result is
+always \constant{True}.
+
+\begin{verbatim}
+>>> 'ab' in 'abcd'
+True
+>>> 'ad' in 'abcd'
+False
+>>> '' in 'abcd'
+True
+\end{verbatim}
+
+Note that this doesn't tell you where the substring starts; if you
+need that information, use the \method{find()} string method.
+
+\item The \method{strip()}, \method{lstrip()}, and \method{rstrip()}
+string methods now have an optional argument for specifying the
+characters to strip.  The default is still to remove all whitespace
+characters:
+
+\begin{verbatim}
+>>> '   abc '.strip()
+'abc'
+>>> '><><abc<><><>'.strip('<>')
+'abc'
+>>> '><><abc<><><>\n'.strip('<>')
+'abc<><><>\n'
+>>> u'\u4000\u4001abc\u4000'.strip(u'\u4000')
+u'\u4001abc'
+>>>
+\end{verbatim}
+
+(Suggested by Simon Brunning and implemented by Walter D\"orwald.)
+
+\item The \method{startswith()} and \method{endswith()}
+string methods now accept negative numbers for the \var{start} and \var{end}
+parameters.
+
+\item Another new string method is \method{zfill()}, originally a
+function in the \module{string} module.  \method{zfill()} pads a
+numeric string with zeros on the left until it's the specified width.
+Note that the \code{\%} operator is still more flexible and powerful
+than \method{zfill()}.
+
+\begin{verbatim}
+>>> '45'.zfill(4)
+'0045'
+>>> '12345'.zfill(4)
+'12345'
+>>> 'goofy'.zfill(6)
+'0goofy'
+\end{verbatim}
+
+(Contributed by Walter D\"orwald.)
+
+\item A new type object, \class{basestring}, has been added.
+   Both 8-bit strings and Unicode strings inherit from this type, so
+   \code{isinstance(obj, basestring)} will return \constant{True} for
+   either kind of string.  It's a completely abstract type, so you
+   can't create \class{basestring} instances.
+
+\item Interned strings are no longer immortal and will now be
+garbage-collected in the usual way when the only reference to them is
+from the internal dictionary of interned strings.  (Implemented by
+Oren Tirosh.)
+
+\end{itemize}
+
+
+%======================================================================
+\subsection{Optimizations}
+
+\begin{itemize}
+
+\item The creation of new-style class instances has been made much
+faster; they're now faster than classic classes!
+
+\item The \method{sort()} method of list objects has been extensively
+rewritten by Tim Peters, and the implementation is significantly
+faster.
+
+\item Multiplication of large long integers is now much faster thanks
+to an implementation of Karatsuba multiplication, an algorithm that
+scales better than the O(n*n) required for the grade-school
+multiplication algorithm.  (Original patch by Christopher A. Craig,
+and significantly reworked by Tim Peters.)
+
+\item The \code{SET_LINENO} opcode is now gone.  This may provide a
+small speed increase, depending on your compiler's idiosyncrasies.
+See section~\ref{section-other} for a longer explanation.
+(Removed by Michael Hudson.)
+
+\item \function{xrange()} objects now have their own iterator, making
+\code{for i in xrange(n)} slightly faster than
+\code{for i in range(n)}.  (Patch by Raymond Hettinger.)
+
+\item A number of small rearrangements have been made in various
+hotspots to improve performance, such as inlining a function or removing
+some code.  (Implemented mostly by GvR, but lots of people have
+contributed single changes.)    
+
+\end{itemize}
+
+The net result of the 2.3 optimizations is that Python 2.3 runs the 
+pystone benchmark around 25\% faster than Python 2.2.
+
+
+%======================================================================
+\section{New, Improved, and Deprecated Modules}
+
+As usual, Python's standard library received a number of enhancements and
+bug fixes.  Here's a partial list of the most notable changes, sorted
+alphabetically by module name. Consult the
+\file{Misc/NEWS} file in the source tree for a more
+complete list of changes, or look through the CVS logs for all the
+details.
+
+\begin{itemize}
+
+\item The \module{array} module now supports arrays of Unicode
+characters using the \character{u} format character.  Arrays also now
+support using the \code{+=} assignment operator to add another array's
+contents, and the \code{*=} assignment operator to repeat an array.
+(Contributed by Jason Orendorff.)
+
+\item The \module{bsddb} module has been replaced by version 4.1.6
+of the \ulink{PyBSDDB}{http://pybsddb.sourceforge.net} package,
+providing a more complete interface to the transactional features of
+the BerkeleyDB library.
+
+The old version of the module has been renamed to 
+\module{bsddb185} and is no longer built automatically; you'll 
+have to edit \file{Modules/Setup} to enable it.  Note that the new
+\module{bsddb} package is intended to be compatible with the 
+old module, so be sure to file bugs if you discover any
+incompatibilities.  When upgrading to Python 2.3, if the new interpreter is compiled
+with a new version of 
+the underlying BerkeleyDB library, you will almost certainly have to
+convert your database files to the new version.  You can do this
+fairly easily with the new scripts \file{db2pickle.py} and
+\file{pickle2db.py} which you will find in the distribution's
+\file{Tools/scripts} directory.  If you've already been using the PyBSDDB
+package and importing it as \module{bsddb3}, you will have to change your
+\code{import} statements to import it as \module{bsddb}.
+
+\item The new \module{bz2} module is an interface to the bz2 data
+compression library.  bz2-compressed data is usually smaller than 
+corresponding \module{zlib}-compressed data. (Contributed by Gustavo Niemeyer.)
+ 
+\item A set of standard date/time types has been added in the new \module{datetime}
+module.  See the following section for more details.
+
+\item The Distutils \class{Extension} class now supports
+an extra constructor argument named \var{depends} for listing
+additional source files that an extension depends on.  This lets
+Distutils recompile the module if any of the dependency files are
+modified.  For example, if \file{sampmodule.c} includes the header
+file \file{sample.h}, you would create the \class{Extension} object like
+this:
+
+\begin{verbatim}
+ext = Extension("samp",
+                sources=["sampmodule.c"],
+                depends=["sample.h"])
+\end{verbatim}
+
+Modifying \file{sample.h} would then cause the module to be recompiled.
+(Contributed by Jeremy Hylton.)
+
+\item Other minor changes to Distutils:
+it now checks for the \envvar{CC}, \envvar{CFLAGS}, \envvar{CPP},
+\envvar{LDFLAGS}, and \envvar{CPPFLAGS} environment variables, using
+them to override the settings in Python's configuration (contributed
+by Robert Weber).
+
+\item Previously the \module{doctest} module would only search the
+docstrings of public methods and functions for test cases, but it now
+also examines private ones as well.  The \function{DocTestSuite(}
+function creates a \class{unittest.TestSuite} object from a set of
+\module{doctest} tests.
+
+\item The new \function{gc.get_referents(\var{object})} function returns a
+list of all the objects referenced by \var{object}.
+
+\item The \module{getopt} module gained a new function,
+\function{gnu_getopt()}, that supports the same arguments as the existing
+\function{getopt()} function but uses GNU-style scanning mode.
+The existing \function{getopt()} stops processing options as soon as a
+non-option argument is encountered, but in GNU-style mode processing
+continues, meaning that options and arguments can be mixed.  For
+example:
+
+\begin{verbatim}
+>>> getopt.getopt(['-f', 'filename', 'output', '-v'], 'f:v')
+([('-f', 'filename')], ['output', '-v'])
+>>> getopt.gnu_getopt(['-f', 'filename', 'output', '-v'], 'f:v')
+([('-f', 'filename'), ('-v', '')], ['output'])
+\end{verbatim}
+
+(Contributed by Peter \AA{strand}.)
+
+\item The \module{grp}, \module{pwd}, and \module{resource} modules
+now return enhanced tuples:
+
+\begin{verbatim}
+>>> import grp
+>>> g = grp.getgrnam('amk')
+>>> g.gr_name, g.gr_gid
+('amk', 500)
+\end{verbatim}
+
+\item The \module{gzip} module can now handle files exceeding 2~GiB.  
+
+\item The new \module{heapq} module contains an implementation of a
+heap queue algorithm.  A heap is an array-like data structure that
+keeps items in a partially sorted order such that, for every index
+\var{k}, \code{heap[\var{k}] <= heap[2*\var{k}+1]} and
+\code{heap[\var{k}] <= heap[2*\var{k}+2]}.  This makes it quick to
+remove the smallest item, and inserting a new item while maintaining
+the heap property is O(lg~n).  (See
+\url{http://www.nist.gov/dads/HTML/priorityque.html} for more
+information about the priority queue data structure.)
+
+The \module{heapq} module provides \function{heappush()} and
+\function{heappop()} functions for adding and removing items while
+maintaining the heap property on top of some other mutable Python
+sequence type.  Here's an example that uses a Python list:
+
+\begin{verbatim}
+>>> import heapq
+>>> heap = []
+>>> for item in [3, 7, 5, 11, 1]:
+...    heapq.heappush(heap, item)
+...
+>>> heap
+[1, 3, 5, 11, 7]
+>>> heapq.heappop(heap)
+1
+>>> heapq.heappop(heap)
+3
+>>> heap
+[5, 7, 11]
+\end{verbatim}
+
+(Contributed by Kevin O'Connor.)
+
+\item The IDLE integrated development environment has been updated
+using the code from the IDLEfork project
+(\url{http://idlefork.sf.net}).  The most notable feature is that the
+code being developed is now executed in a subprocess, meaning that
+there's no longer any need for manual \code{reload()} operations.
+IDLE's core code has been incorporated into the standard library as the
+\module{idlelib} package.
+
+\item The \module{imaplib} module now supports IMAP over SSL.
+(Contributed by Piers Lauder and Tino Lange.)
+
+\item The \module{itertools} contains a number of useful functions for
+use with iterators, inspired by various functions provided by the ML
+and Haskell languages.  For example,
+\code{itertools.ifilter(predicate, iterator)} returns all elements in
+the iterator for which the function \function{predicate()} returns
+\constant{True}, and \code{itertools.repeat(obj, \var{N})} returns
+\code{obj} \var{N} times.  There are a number of other functions in
+the module; see the \ulink{package's reference
+documentation}{../lib/module-itertools.html} for details.
+(Contributed by Raymond Hettinger.)
+
+\item Two new functions in the \module{math} module,
+\function{degrees(\var{rads})} and \function{radians(\var{degs})},
+convert between radians and degrees.  Other functions in the
+\module{math} module such as \function{math.sin()} and
+\function{math.cos()} have always required input values measured in
+radians.  Also, an optional \var{base} argument was added to
+\function{math.log()} to make it easier to compute logarithms for
+bases other than \code{e} and \code{10}.  (Contributed by Raymond
+Hettinger.)
+
+\item Several new POSIX functions (\function{getpgid()}, \function{killpg()},
+\function{lchown()}, \function{loadavg()}, \function{major()}, \function{makedev()},
+\function{minor()}, and \function{mknod()}) were added to the
+\module{posix} module that underlies the \module{os} module.
+(Contributed by Gustavo Niemeyer, Geert Jansen, and Denis S. Otkidach.)
+
+\item In the \module{os} module, the \function{*stat()} family of
+functions can now report fractions of a second in a timestamp.  Such
+time stamps are represented as floats, similar to
+the value returned by \function{time.time()}.
+
+During testing, it was found that some applications will break if time
+stamps are floats.  For compatibility, when using the tuple interface
+of the \class{stat_result} time stamps will be represented as integers.
+When using named fields (a feature first introduced in Python 2.2),
+time stamps are still represented as integers, unless
+\function{os.stat_float_times()} is invoked to enable float return
+values:
+
+\begin{verbatim}
+>>> os.stat("/tmp").st_mtime
+1034791200
+>>> os.stat_float_times(True)
+>>> os.stat("/tmp").st_mtime
+1034791200.6335014
+\end{verbatim}
+
+In Python 2.4, the default will change to always returning floats.
+
+Application developers should enable this feature only if all their
+libraries work properly when confronted with floating point time
+stamps, or if they use the tuple API. If used, the feature should be
+activated on an application level instead of trying to enable it on a
+per-use basis.
+
+\item The \module{optparse} module contains a new parser for command-line arguments 
+that can convert option values to a particular Python type 
+and will automatically generate a usage message.  See the following section for 
+more details.
+
+\item The old and never-documented \module{linuxaudiodev} module has
+been deprecated, and a new version named \module{ossaudiodev} has been
+added.  The module was renamed because the OSS sound drivers can be
+used on platforms other than Linux, and the interface has also been
+tidied and brought up to date in various ways. (Contributed by Greg
+Ward and Nicholas FitzRoy-Dale.)
+
+\item The new \module{platform} module contains a number of functions
+that try to determine various properties of the platform you're
+running on.  There are functions for getting the architecture, CPU
+type, the Windows OS version, and even the Linux distribution version.
+(Contributed by Marc-Andr\'e Lemburg.)
+
+\item The parser objects provided by the \module{pyexpat} module
+can now optionally buffer character data, resulting in fewer calls to
+your character data handler and therefore faster performance.  Setting
+the parser object's \member{buffer_text} attribute to \constant{True}
+will enable buffering.
+
+\item The \function{sample(\var{population}, \var{k})} function was
+added to the \module{random} module.  \var{population} is a sequence or
+\class{xrange} object containing the elements of a population, and
+\function{sample()} chooses \var{k} elements from the population without
+replacing chosen elements.  \var{k} can be any value up to
+\code{len(\var{population})}. For example:
+
+\begin{verbatim}
+>>> days = ['Mo', 'Tu', 'We', 'Th', 'Fr', 'St', 'Sn']
+>>> random.sample(days, 3)      # Choose 3 elements
+['St', 'Sn', 'Th']
+>>> random.sample(days, 7)      # Choose 7 elements
+['Tu', 'Th', 'Mo', 'We', 'St', 'Fr', 'Sn']
+>>> random.sample(days, 7)      # Choose 7 again
+['We', 'Mo', 'Sn', 'Fr', 'Tu', 'St', 'Th']
+>>> random.sample(days, 8)      # Can't choose eight
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+  File "random.py", line 414, in sample
+      raise ValueError, "sample larger than population"
+ValueError: sample larger than population
+>>> random.sample(xrange(1,10000,2), 10)   # Choose ten odd nos. under 10000
+[3407, 3805, 1505, 7023, 2401, 2267, 9733, 3151, 8083, 9195]
+\end{verbatim}
+
+The \module{random} module now uses a new algorithm, the Mersenne
+Twister, implemented in C.  It's faster and more extensively studied
+than the previous algorithm.
+
+(All changes contributed by Raymond Hettinger.)
+
+\item The \module{readline} module also gained a number of new
+functions: \function{get_history_item()},
+\function{get_current_history_length()}, and \function{redisplay()}.
+
+\item The \module{rexec} and \module{Bastion} modules have been
+declared dead, and attempts to import them will fail with a
+\exception{RuntimeError}.  New-style classes provide new ways to break
+out of the restricted execution environment provided by
+\module{rexec}, and no one has interest in fixing them or time to do
+so.  If you have applications using \module{rexec}, rewrite them to
+use something else.
+
+(Sticking with Python 2.2 or 2.1 will not make your applications any
+safer because there are known bugs in the \module{rexec} module in
+those versions.  To repeat: if you're using \module{rexec}, stop using
+it immediately.)
+
+\item The \module{rotor} module has been deprecated because the 
+  algorithm it uses for encryption is not believed to be secure.  If
+  you need encryption, use one of the several AES Python modules
+  that are available separately.
+
+\item The \module{shutil} module gained a \function{move(\var{src},
+\var{dest})} function that recursively moves a file or directory to a new
+location.
+
+\item Support for more advanced POSIX signal handling was added
+to the \module{signal} but then removed again as it proved impossible
+to make it work reliably across platforms.
+
+\item The \module{socket} module now supports timeouts.  You
+can call the \method{settimeout(\var{t})} method on a socket object to
+set a timeout of \var{t} seconds.  Subsequent socket operations that
+take longer than \var{t} seconds to complete will abort and raise a
+\exception{socket.timeout} exception.
+
+The original timeout implementation was by Tim O'Malley.  Michael
+Gilfix integrated it into the Python \module{socket} module and
+shepherded it through a lengthy review.  After the code was checked
+in, Guido van~Rossum rewrote parts of it.  (This is a good example of
+a collaborative development process in action.)
+
+\item On Windows, the \module{socket} module now ships with Secure 
+Sockets Layer (SSL) support.
+
+\item The value of the C \constant{PYTHON_API_VERSION} macro is now
+exposed at the Python level as \code{sys.api_version}.  The current
+exception can be cleared by calling the new \function{sys.exc_clear()}
+function.
+
+\item The new \module{tarfile} module 
+allows reading from and writing to \program{tar}-format archive files.
+(Contributed by Lars Gust\"abel.)
+
+\item The new \module{textwrap} module contains functions for wrapping
+strings containing paragraphs of text.  The \function{wrap(\var{text},
+\var{width})} function takes a string and returns a list containing
+the text split into lines of no more than the chosen width.  The
+\function{fill(\var{text}, \var{width})} function returns a single
+string, reformatted to fit into lines no longer than the chosen width.
+(As you can guess, \function{fill()} is built on top of
+\function{wrap()}.  For example:
+
+\begin{verbatim}
+>>> import textwrap
+>>> paragraph = "Not a whit, we defy augury: ... more text ..."
+>>> textwrap.wrap(paragraph, 60)
+["Not a whit, we defy augury: there's a special providence in",
+ "the fall of a sparrow. If it be now, 'tis not to come; if it",
+ ...]
+>>> print textwrap.fill(paragraph, 35)
+Not a whit, we defy augury: there's
+a special providence in the fall of
+a sparrow. If it be now, 'tis not
+to come; if it be not to come, it
+will be now; if it be not now, yet
+it will come: the readiness is all.
+>>>
+\end{verbatim}
+
+The module also contains a \class{TextWrapper} class that actually
+implements the text wrapping strategy.   Both the
+\class{TextWrapper} class and the \function{wrap()} and
+\function{fill()} functions support a number of additional keyword
+arguments for fine-tuning the formatting; consult the \ulink{module's
+documentation}{../lib/module-textwrap.html} for details.
+(Contributed by Greg Ward.)
+
+\item The \module{thread} and \module{threading} modules now have
+companion modules, \module{dummy_thread} and \module{dummy_threading},
+that provide a do-nothing implementation of the \module{thread}
+module's interface for platforms where threads are not supported.  The
+intention is to simplify thread-aware modules (ones that \emph{don't}
+rely on threads to run) by putting the following code at the top:
+
+\begin{verbatim}
+try:
+    import threading as _threading
+except ImportError:
+    import dummy_threading as _threading
+\end{verbatim}
+
+In this example, \module{_threading} is used as the module name to make
+it clear that the module being used is not necessarily the actual
+\module{threading} module. Code can call functions and use classes in
+\module{_threading} whether or not threads are supported, avoiding an
+\keyword{if} statement and making the code slightly clearer.  This
+module will not magically make multithreaded code run without threads;
+code that waits for another thread to return or to do something will
+simply hang forever. 
+
+\item The \module{time} module's \function{strptime()} function has
+long been an annoyance because it uses the platform C library's
+\function{strptime()} implementation, and different platforms
+sometimes have odd bugs.  Brett Cannon contributed a portable
+implementation that's written in pure Python and should behave
+identically on all platforms.
+
+\item The new \module{timeit} module helps measure how long snippets
+of Python code take to execute.  The \file{timeit.py} file can be run
+directly from the command line, or the module's \class{Timer} class
+can be imported and used directly.  Here's a short example that
+figures out whether it's faster to convert an 8-bit string to Unicode
+by appending an empty Unicode string to it or by using the
+\function{unicode()} function:
+
+\begin{verbatim}
+import timeit
+
+timer1 = timeit.Timer('unicode("abc")')
+timer2 = timeit.Timer('"abc" + u""')
+
+# Run three trials
+print timer1.repeat(repeat=3, number=100000)
+print timer2.repeat(repeat=3, number=100000)
+
+# On my laptop this outputs:
+# [0.36831796169281006, 0.37441694736480713, 0.35304892063140869]
+# [0.17574405670166016, 0.18193507194519043, 0.17565798759460449]
+\end{verbatim}
+
+\item The \module{Tix} module has received various bug fixes and
+updates for the current version of the Tix package.
+
+\item The \module{Tkinter} module now works with a thread-enabled 
+version of Tcl.  Tcl's threading model requires that widgets only be
+accessed from the thread in which they're created; accesses from
+another thread can cause Tcl to panic.  For certain Tcl interfaces,
+\module{Tkinter} will now automatically avoid this 
+when a widget is accessed from a different thread by marshalling a
+command, passing it to the correct thread, and waiting for the
+results.  Other interfaces can't be handled automatically but
+\module{Tkinter} will now raise an exception on such an access so that
+you can at least find out about the problem.  See
+\url{http://mail.python.org/pipermail/python-dev/2002-December/031107.html} %
+for a more detailed explanation of this change.  (Implemented by
+Martin von~L\"owis.)
+
+\item Calling Tcl methods through \module{_tkinter} no longer 
+returns only strings. Instead, if Tcl returns other objects those
+objects are converted to their Python equivalent, if one exists, or
+wrapped with a \class{_tkinter.Tcl_Obj} object if no Python equivalent
+exists. This behavior can be controlled through the
+\method{wantobjects()} method of \class{tkapp} objects.
+
+When using \module{_tkinter} through the \module{Tkinter} module (as
+most Tkinter applications will), this feature is always activated. It
+should not cause compatibility problems, since Tkinter would always
+convert string results to Python types where possible.
+
+If any incompatibilities are found, the old behavior can be restored
+by setting the \member{wantobjects} variable in the \module{Tkinter}
+module to false before creating the first \class{tkapp} object.
+
+\begin{verbatim}
+import Tkinter
+Tkinter.wantobjects = 0
+\end{verbatim}
+
+Any breakage caused by this change should be reported as a bug.
+
+\item The \module{UserDict} module has a new \class{DictMixin} class which
+defines all dictionary methods for classes that already have a minimum
+mapping interface.  This greatly simplifies writing classes that need
+to be substitutable for dictionaries, such as the classes in 
+the \module{shelve} module.
+ 
+Adding the mix-in as a superclass provides the full dictionary
+interface whenever the class defines \method{__getitem__},
+\method{__setitem__}, \method{__delitem__}, and \method{keys}.
+For example:
+ 
+\begin{verbatim}
+>>> import UserDict
+>>> class SeqDict(UserDict.DictMixin):
+...     """Dictionary lookalike implemented with lists."""
+...     def __init__(self):
+...         self.keylist = []
+...         self.valuelist = []
+...     def __getitem__(self, key):
+...         try:
+...             i = self.keylist.index(key)
+...         except ValueError:
+...             raise KeyError
+...         return self.valuelist[i]
+...     def __setitem__(self, key, value):
+...         try:
+...             i = self.keylist.index(key)
+...             self.valuelist[i] = value
+...         except ValueError:
+...             self.keylist.append(key)
+...             self.valuelist.append(value)
+...     def __delitem__(self, key):
+...         try:
+...             i = self.keylist.index(key)
+...         except ValueError:
+...             raise KeyError
+...         self.keylist.pop(i)
+...         self.valuelist.pop(i)
+...     def keys(self):
+...         return list(self.keylist)
+... 
+>>> s = SeqDict()
+>>> dir(s)      # See that other dictionary methods are implemented
+['__cmp__', '__contains__', '__delitem__', '__doc__', '__getitem__',
+ '__init__', '__iter__', '__len__', '__module__', '__repr__',
+ '__setitem__', 'clear', 'get', 'has_key', 'items', 'iteritems',
+ 'iterkeys', 'itervalues', 'keylist', 'keys', 'pop', 'popitem',
+ 'setdefault', 'update', 'valuelist', 'values']
+\end{verbatim}
+
+(Contributed by Raymond Hettinger.)
+
+\item The DOM implementation
+in \module{xml.dom.minidom} can now generate XML output in a
+particular encoding by providing an optional encoding argument to
+the \method{toxml()} and \method{toprettyxml()} methods of DOM nodes.
+
+\item The \module{xmlrpclib} module now supports an XML-RPC extension
+for handling nil data values such as Python's \code{None}.  Nil values
+are always supported on unmarshalling an XML-RPC response.  To
+generate requests containing \code{None}, you must supply a true value
+for the \var{allow_none} parameter when creating a \class{Marshaller}
+instance.
+
+\item The new \module{DocXMLRPCServer} module allows writing
+self-documenting XML-RPC servers. Run it in demo mode (as a program)
+to see it in action.   Pointing the Web browser to the RPC server
+produces pydoc-style documentation; pointing xmlrpclib to the
+server allows invoking the actual methods.
+(Contributed by Brian Quinlan.)
+
+\item Support for internationalized domain names (RFCs 3454, 3490,
+3491, and 3492) has been added. The ``idna'' encoding can be used
+to convert between a Unicode domain name and the ASCII-compatible
+encoding (ACE) of that name.
+
+\begin{alltt}
+>{}>{}> u"www.Alliancefran\c caise.nu".encode("idna")
+'www.xn--alliancefranaise-npb.nu'
+\end{alltt}
+
+The \module{socket} module has also been extended to transparently
+convert Unicode hostnames to the ACE version before passing them to
+the C library.  Modules that deal with hostnames such as
+\module{httplib} and \module{ftplib}) also support Unicode host names;
+\module{httplib} also sends HTTP \samp{Host} headers using the ACE
+version of the domain name.  \module{urllib} supports Unicode URLs
+with non-ASCII host names as long as the \code{path} part of the URL
+is ASCII only.
+
+To implement this change, the \module{stringprep} module, the 
+\code{mkstringprep} tool and the \code{punycode} encoding have been added.  
+
+\end{itemize}
+
+
+%======================================================================
+\subsection{Date/Time Type}
+
+Date and time types suitable for expressing timestamps were added as
+the \module{datetime} module.  The types don't support different
+calendars or many fancy features, and just stick to the basics of
+representing time.
+
+The three primary types are: \class{date}, representing a day, month,
+and year; \class{time}, consisting of hour, minute, and second; and
+\class{datetime}, which contains all the attributes of both
+\class{date} and \class{time}.  There's also a
+\class{timedelta} class representing differences between two points
+in time, and time zone logic is implemented by classes inheriting from
+the abstract \class{tzinfo} class.
+
+You can create instances of \class{date} and \class{time} by either
+supplying keyword arguments to the appropriate constructor,
+e.g. \code{datetime.date(year=1972, month=10, day=15)}, or by using
+one of a number of class methods.  For example, the \method{date.today()}
+class method returns the current local date.
+
+Once created, instances of the date/time classes are all immutable.
+There are a number of methods for producing formatted strings from
+objects:
+
+\begin{verbatim}
+>>> import datetime
+>>> now = datetime.datetime.now()
+>>> now.isoformat()
+'2002-12-30T21:27:03.994956'
+>>> now.ctime()  # Only available on date, datetime
+'Mon Dec 30 21:27:03 2002'
+>>> now.strftime('%Y %d %b')
+'2002 30 Dec'
+\end{verbatim}
+
+The \method{replace()} method allows modifying one or more fields 
+of a \class{date} or \class{datetime} instance, returning a new instance:
+
+\begin{verbatim}
+>>> d = datetime.datetime.now()
+>>> d
+datetime.datetime(2002, 12, 30, 22, 15, 38, 827738)
+>>> d.replace(year=2001, hour = 12)
+datetime.datetime(2001, 12, 30, 12, 15, 38, 827738)
+>>>
+\end{verbatim}
+
+Instances can be compared, hashed, and converted to strings (the
+result is the same as that of \method{isoformat()}).  \class{date} and
+\class{datetime} instances can be subtracted from each other, and
+added to \class{timedelta} instances.  The largest missing feature is
+that there's no standard library support for parsing strings and getting back a
+\class{date} or \class{datetime}.
+
+For more information, refer to the \ulink{module's reference
+documentation}{../lib/module-datetime.html}.
+(Contributed by Tim Peters.)
+
+
+%======================================================================
+\subsection{The optparse Module}
+
+The \module{getopt} module provides simple parsing of command-line
+arguments.  The new \module{optparse} module (originally named Optik)
+provides more elaborate command-line parsing that follows the \UNIX{}
+conventions, automatically creates the output for \longprogramopt{help},
+and can perform different actions for different options.
+
+You start by creating an instance of \class{OptionParser} and telling
+it what your program's options are.
+
+\begin{verbatim}
+import sys
+from optparse import OptionParser
+
+op = OptionParser()
+op.add_option('-i', '--input',
+              action='store', type='string', dest='input',
+              help='set input filename')
+op.add_option('-l', '--length',
+              action='store', type='int', dest='length',
+              help='set maximum length of output')
+\end{verbatim}
+
+Parsing a command line is then done by calling the \method{parse_args()}
+method.
+
+\begin{verbatim}
+options, args = op.parse_args(sys.argv[1:])
+print options
+print args
+\end{verbatim}
+
+This returns an object containing all of the option values,
+and a list of strings containing the remaining arguments. 
+
+Invoking the script with the various arguments now works as you'd
+expect it to.  Note that the length argument is automatically
+converted to an integer.
+
+\begin{verbatim}
+$ ./python opt.py -i data arg1
+<Values at 0x400cad4c: {'input': 'data', 'length': None}>
+['arg1']
+$ ./python opt.py --input=data --length=4
+<Values at 0x400cad2c: {'input': 'data', 'length': 4}>
+[]
+$
+\end{verbatim}
+
+The help message is automatically generated for you:
+
+\begin{verbatim}
+$ ./python opt.py --help
+usage: opt.py [options]
+
+options:
+  -h, --help            show this help message and exit
+  -iINPUT, --input=INPUT
+                        set input filename
+  -lLENGTH, --length=LENGTH
+                        set maximum length of output
+$ 
+\end{verbatim}
+% $ prevent Emacs tex-mode from getting confused
+
+See the \ulink{module's documentation}{../lib/module-optparse.html}
+for more details.
+
+Optik was written by Greg Ward, with suggestions from the readers of
+the Getopt SIG.
+
+
+%======================================================================
+\section{Pymalloc: A Specialized Object Allocator\label{section-pymalloc}}
+
+Pymalloc, a specialized object allocator written by Vladimir
+Marangozov, was a feature added to Python 2.1.  Pymalloc is intended
+to be faster than the system \cfunction{malloc()} and to have less
+memory overhead for allocation patterns typical of Python programs.
+The allocator uses C's \cfunction{malloc()} function to get large
+pools of memory and then fulfills smaller memory requests from these
+pools.
+
+In 2.1 and 2.2, pymalloc was an experimental feature and wasn't
+enabled by default; you had to explicitly enable it when compiling
+Python by providing the
+\longprogramopt{with-pymalloc} option to the \program{configure}
+script.  In 2.3, pymalloc has had further enhancements and is now
+enabled by default; you'll have to supply
+\longprogramopt{without-pymalloc} to disable it.
+
+This change is transparent to code written in Python; however,
+pymalloc may expose bugs in C extensions.  Authors of C extension
+modules should test their code with pymalloc enabled,
+because some incorrect code may cause core dumps at runtime.  
+
+There's one particularly common error that causes problems.  There are
+a number of memory allocation functions in Python's C API that have
+previously just been aliases for the C library's \cfunction{malloc()}
+and \cfunction{free()}, meaning that if you accidentally called
+mismatched functions the error wouldn't be noticeable.  When the
+object allocator is enabled, these functions aren't aliases of
+\cfunction{malloc()} and \cfunction{free()} any more, and calling the
+wrong function to free memory may get you a core dump.  For example,
+if memory was allocated using \cfunction{PyObject_Malloc()}, it has to
+be freed using \cfunction{PyObject_Free()}, not \cfunction{free()}.  A
+few modules included with Python fell afoul of this and had to be
+fixed; doubtless there are more third-party modules that will have the
+same problem.
+
+As part of this change, the confusing multiple interfaces for
+allocating memory have been consolidated down into two API families.
+Memory allocated with one family must not be manipulated with
+functions from the other family.  There is one family for allocating
+chunks of memory and another family of functions specifically for
+allocating Python objects.
+
+\begin{itemize}
+  \item To allocate and free an undistinguished chunk of memory use
+  the ``raw memory'' family: \cfunction{PyMem_Malloc()},
+  \cfunction{PyMem_Realloc()}, and \cfunction{PyMem_Free()}.
+
+  \item The ``object memory'' family is the interface to the pymalloc
+  facility described above and is biased towards a large number of
+  ``small'' allocations: \cfunction{PyObject_Malloc},
+  \cfunction{PyObject_Realloc}, and \cfunction{PyObject_Free}.
+
+  \item To allocate and free Python objects, use the ``object'' family
+  \cfunction{PyObject_New()}, \cfunction{PyObject_NewVar()}, and
+  \cfunction{PyObject_Del()}.
+\end{itemize}
+
+Thanks to lots of work by Tim Peters, pymalloc in 2.3 also provides
+debugging features to catch memory overwrites and doubled frees in
+both extension modules and in the interpreter itself.  To enable this
+support, compile a debugging version of the Python interpreter by
+running \program{configure} with \longprogramopt{with-pydebug}.
+
+To aid extension writers, a header file \file{Misc/pymemcompat.h} is
+distributed with the source to Python 2.3 that allows Python
+extensions to use the 2.3 interfaces to memory allocation while
+compiling against any version of Python since 1.5.2.  You would copy
+the file from Python's source distribution and bundle it with the
+source of your extension.
+
+\begin{seealso}
+
+\seeurl{http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/python/python/dist/src/Objects/obmalloc.c}
+{For the full details of the pymalloc implementation, see
+the comments at the top of the file \file{Objects/obmalloc.c} in the
+Python source code.  The above link points to the file within the
+SourceForge CVS browser.}
+
+\end{seealso}
+
+
+% ======================================================================
+\section{Build and C API Changes}
+
+Changes to Python's build process and to the C API include:
+
+\begin{itemize}
+
+\item The cycle detection implementation used by the garbage collection
+has proven to be stable, so it's now been made mandatory.  You can no
+longer compile Python without it, and the
+\longprogramopt{with-cycle-gc} switch to \program{configure} has been removed.
+
+\item Python can now optionally be built as a shared library
+(\file{libpython2.3.so}) by supplying \longprogramopt{enable-shared}
+when running Python's \program{configure} script.  (Contributed by Ondrej
+Palkovsky.)
+
+\item The \csimplemacro{DL_EXPORT} and \csimplemacro{DL_IMPORT} macros
+are now deprecated.  Initialization functions for Python extension
+modules should now be declared using the new macro
+\csimplemacro{PyMODINIT_FUNC}, while the Python core will generally
+use the \csimplemacro{PyAPI_FUNC} and \csimplemacro{PyAPI_DATA}
+macros.
+
+\item The interpreter can be compiled without any docstrings for
+the built-in functions and modules by supplying
+\longprogramopt{without-doc-strings} to the \program{configure} script.
+This makes the Python executable about 10\% smaller, but will also
+mean that you can't get help for Python's built-ins.  (Contributed by
+Gustavo Niemeyer.)
+
+\item The \cfunction{PyArg_NoArgs()} macro is now deprecated, and code
+that uses it should be changed.  For Python 2.2 and later, the method
+definition table can specify the
+\constant{METH_NOARGS} flag, signalling that there are no arguments, and
+the argument checking can then be removed.  If compatibility with
+pre-2.2 versions of Python is important, the code could use
+\code{PyArg_ParseTuple(\var{args}, "")} instead, but this will be slower
+than using \constant{METH_NOARGS}.
+
+\item \cfunction{PyArg_ParseTuple()} accepts new format characters for various sizes of unsigned integers: \samp{B} for \ctype{unsigned char},
+\samp{H} for \ctype{unsigned short int}, 
+\samp{I} for \ctype{unsigned int}, 
+and \samp{K} for \ctype{unsigned long long}.
+
+\item A new function, \cfunction{PyObject_DelItemString(\var{mapping},
+char *\var{key})} was added as shorthand for
+\code{PyObject_DelItem(\var{mapping}, PyString_New(\var{key}))}.
+
+\item File objects now manage their internal string buffer
+differently, increasing it exponentially when needed.  This results in
+the benchmark tests in \file{Lib/test/test_bufio.py} speeding up
+considerably (from 57 seconds to 1.7 seconds, according to one
+measurement).
+
+\item It's now possible to define class and static methods for a C
+extension type by setting either the \constant{METH_CLASS} or
+\constant{METH_STATIC} flags in a method's \ctype{PyMethodDef}
+structure.
+
+\item Python now includes a copy of the Expat XML parser's source code,
+removing any dependence on a system version or local installation of
+Expat.
+
+\item If you dynamically allocate type objects in your extension, you
+should be aware of a change in the rules relating to the
+\member{__module__} and \member{__name__} attributes.  In summary,
+you will want to ensure the type's dictionary contains a
+\code{'__module__'} key; making the module name the part of the type
+name leading up to the final period will no longer have the desired
+effect.  For more detail, read the API reference documentation or the 
+source.
+
+\end{itemize}
+
+
+%======================================================================
+\subsection{Port-Specific Changes}
+
+Support for a port to IBM's OS/2 using the EMX runtime environment was
+merged into the main Python source tree.  EMX is a POSIX emulation
+layer over the OS/2 system APIs.  The Python port for EMX tries to
+support all the POSIX-like capability exposed by the EMX runtime, and
+mostly succeeds; \function{fork()} and \function{fcntl()} are
+restricted by the limitations of the underlying emulation layer.  The
+standard OS/2 port, which uses IBM's Visual Age compiler, also gained
+support for case-sensitive import semantics as part of the integration
+of the EMX port into CVS.  (Contributed by Andrew MacIntyre.)
+
+On MacOS, most toolbox modules have been weaklinked to improve
+backward compatibility.  This means that modules will no longer fail
+to load if a single routine is missing on the current OS version.
+Instead calling the missing routine will raise an exception.
+(Contributed by Jack Jansen.)
+
+The RPM spec files, found in the \file{Misc/RPM/} directory in the
+Python source distribution, were updated for 2.3.  (Contributed by
+Sean Reifschneider.)
+
+Other new platforms now supported by Python include AtheOS
+(\url{http://www.atheos.cx/}), GNU/Hurd, and OpenVMS.
+
+
+%======================================================================
+\section{Other Changes and Fixes \label{section-other}}
+
+As usual, there were a bunch of other improvements and bugfixes
+scattered throughout the source tree.  A search through the CVS change
+logs finds there were 523 patches applied and 514 bugs fixed between
+Python 2.2 and 2.3.  Both figures are likely to be underestimates.
+
+Some of the more notable changes are:
+
+\begin{itemize}
+
+\item If the \envvar{PYTHONINSPECT} environment variable is set, the
+Python interpreter will enter the interactive prompt after running a
+Python program, as if Python had been invoked with the \programopt{-i}
+option. The environment variable can be set before running the Python
+interpreter, or it can be set by the Python program as part of its
+execution.
+
+\item The \file{regrtest.py} script now provides a way to allow ``all
+resources except \var{foo}.''  A resource name passed to the
+\programopt{-u} option can now be prefixed with a hyphen
+(\character{-}) to mean ``remove this resource.''  For example, the
+option `\code{\programopt{-u}all,-bsddb}' could be used to enable the
+use of all resources except \code{bsddb}.
+
+\item The tools used to build the documentation now work under Cygwin
+as well as \UNIX.
+
+\item The \code{SET_LINENO} opcode has been removed.  Back in the
+mists of time, this opcode was needed to produce line numbers in
+tracebacks and support trace functions (for, e.g., \module{pdb}).
+Since Python 1.5, the line numbers in tracebacks have been computed
+using a different mechanism that works with ``python -O''.  For Python
+2.3 Michael Hudson implemented a similar scheme to determine when to
+call the trace function, removing the need for \code{SET_LINENO}
+entirely.
+
+It would be difficult to detect any resulting difference from Python
+code, apart from a slight speed up when Python is run without
+\programopt{-O}.
+
+C extensions that access the \member{f_lineno} field of frame objects
+should instead call \code{PyCode_Addr2Line(f->f_code, f->f_lasti)}.
+This will have the added effect of making the code work as desired
+under ``python -O'' in earlier versions of Python.
+
+A nifty new feature is that trace functions can now assign to the
+\member{f_lineno} attribute of frame objects, changing the line that
+will be executed next.  A \samp{jump} command has been added to the
+\module{pdb} debugger taking advantage of this new feature.
+(Implemented by Richie Hindle.)
+
+\end{itemize}
+
+
+%======================================================================
+\section{Porting to Python 2.3}
+
+This section lists previously described changes that may require
+changes to your code:
+
+\begin{itemize}
+
+\item \keyword{yield} is now always a keyword; if it's used as a
+variable name in your code, a different name must be chosen.
+
+\item For strings \var{X} and \var{Y}, \code{\var{X} in \var{Y}} now works
+if \var{X} is more than one character long.
+
+\item The \function{int()} type constructor will now return a long
+integer instead of raising an \exception{OverflowError} when a string
+or floating-point number is too large to fit into an integer.
+
+\item If you have Unicode strings that contain 8-bit characters, you
+must declare the file's encoding (UTF-8, Latin-1, or whatever) by
+adding a comment to the top of the file.  See
+section~\ref{section-encodings} for more information.
+
+\item Calling Tcl methods through \module{_tkinter} no longer 
+returns only strings. Instead, if Tcl returns other objects those
+objects are converted to their Python equivalent, if one exists, or
+wrapped with a \class{_tkinter.Tcl_Obj} object if no Python equivalent
+exists.
+
+\item Large octal and hex literals such as
+\code{0xffffffff} now trigger a \exception{FutureWarning}. Currently
+they're stored as 32-bit numbers and result in a negative value, but
+in Python 2.4 they'll become positive long integers. 
+
+% The empty groups below prevent conversion to guillemets.
+There are a few ways to fix this warning.  If you really need a
+positive number, just add an \samp{L} to the end of the literal.  If
+you're trying to get a 32-bit integer with low bits set and have
+previously used an expression such as \code{\textasciitilde(1 <{}< 31)},
+it's probably
+clearest to start with all bits set and clear the desired upper bits.
+For example, to clear just the top bit (bit 31), you could write
+\code{0xffffffffL {\&}{\textasciitilde}(1L<{}<31)}.
+
+\item You can no longer disable assertions by assigning to \code{__debug__}.
+
+\item The Distutils \function{setup()} function has gained various new
+keyword arguments such as \var{depends}.  Old versions of the
+Distutils will abort if passed unknown keywords.  A solution is to check
+for the presence of the new \function{get_distutil_options()} function
+in your \file{setup.py} and only uses the new keywords
+with a version of the Distutils that supports them:
+
+\begin{verbatim}
+from distutils import core
+
+kw = {'sources': 'foo.c', ...}
+if hasattr(core, 'get_distutil_options'):
+    kw['depends'] = ['foo.h']
+ext = Extension(**kw)
+\end{verbatim}
+
+\item Using \code{None} as a variable name will now result in a
+\exception{SyntaxWarning} warning.
+
+\item Names of extension types defined by the modules included with
+Python now contain the module and a \character{.} in front of the type
+name.
+
+\end{itemize}
+
+
+%======================================================================
+\section{Acknowledgements \label{acks}}
+
+The author would like to thank the following people for offering
+suggestions, corrections and assistance with various drafts of this
+article: Jeff Bauer, Simon Brunning, Brett Cannon, Michael Chermside,
+Andrew Dalke, Scott David Daniels, Fred~L. Drake, Jr., David Fraser, 
+Kelly Gerber,
+Raymond Hettinger, Michael Hudson, Chris Lambert, Detlef Lannert,
+Martin von~L\"owis, Andrew MacIntyre, Lalo Martins, Chad Netzer,
+Gustavo Niemeyer, Neal Norwitz, Hans Nowak, Chris Reedy, Francesco
+Ricciardi, Vinay Sajip, Neil Schemenauer, Roman Suzi, Jason Tishler,
+Just van~Rossum.
+
+\end{document}

Added: vendor/Python/current/Doc/whatsnew/whatsnew24.tex
===================================================================
--- vendor/Python/current/Doc/whatsnew/whatsnew24.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/whatsnew/whatsnew24.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1757 @@
+\documentclass{howto}
+\usepackage{distutils}
+% $Id: whatsnew24.tex 50936 2006-07-29 15:42:46Z andrew.kuchling $
+
+% Don't write extensive text for new sections; I'll do that.  
+% Feel free to add commented-out reminders of things that need
+% to be covered.  --amk
+
+\title{What's New in Python 2.4}
+\release{1.02}
+\author{A.M.\ Kuchling}
+\authoraddress{
+	\strong{Python Software Foundation}\\
+	Email: \email{amk at amk.ca}
+}
+
+\begin{document}
+\maketitle
+\tableofcontents
+
+This article explains the new features in Python 2.4.1, released on
+March~30, 2005.
+
+Python 2.4 is a medium-sized release.  It doesn't introduce as many
+changes as the radical Python 2.2, but introduces more features than
+the conservative 2.3 release.  The most significant new language
+features are function decorators and generator expressions; most other
+changes are to the standard library.
+
+According to the CVS change logs, there were 481 patches applied and
+502 bugs fixed between Python 2.3 and 2.4.  Both figures are likely to
+be underestimates.
+
+This article doesn't attempt to provide a complete specification of
+every single new feature, but instead provides a brief introduction to
+each feature.  For full details, you should refer to the documentation
+for Python 2.4, such as the \citetitle[../lib/lib.html]{Python Library
+Reference} and the \citetitle[../ref/ref.html]{Python Reference
+Manual}.  Often you will be referred to the PEP for a particular new
+feature for explanations of the implementation and design rationale.
+
+
+%======================================================================
+\section{PEP 218: Built-In Set Objects}
+
+Python 2.3 introduced the \module{sets} module.  C implementations of
+set data types have now been added to the Python core as two new
+built-in types, \function{set(\var{iterable})} and
+\function{frozenset(\var{iterable})}.  They provide high speed
+operations for membership testing, for eliminating duplicates from
+sequences, and for mathematical operations like unions, intersections,
+differences, and symmetric differences.
+
+\begin{verbatim}
+>>> a = set('abracadabra')              # form a set from a string
+>>> 'z' in a                            # fast membership testing
+False
+>>> a                                   # unique letters in a
+set(['a', 'r', 'b', 'c', 'd'])
+>>> ''.join(a)                          # convert back into a string
+'arbcd'
+
+>>> b = set('alacazam')                 # form a second set
+>>> a - b                               # letters in a but not in b
+set(['r', 'd', 'b'])
+>>> a | b                               # letters in either a or b
+set(['a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'])
+>>> a & b                               # letters in both a and b
+set(['a', 'c'])
+>>> a ^ b                               # letters in a or b but not both
+set(['r', 'd', 'b', 'm', 'z', 'l'])
+
+>>> a.add('z')                          # add a new element
+>>> a.update('wxy')                     # add multiple new elements
+>>> a
+set(['a', 'c', 'b', 'd', 'r', 'w', 'y', 'x', 'z'])       
+>>> a.remove('x')                       # take one element out
+>>> a
+set(['a', 'c', 'b', 'd', 'r', 'w', 'y', 'z'])       
+\end{verbatim}
+
+The \function{frozenset} type is an immutable version of \function{set}.
+Since it is immutable and hashable, it may be used as a dictionary key or
+as a member of another set.  
+
+The \module{sets} module remains in the standard library, and may be
+useful if you wish to subclass the \class{Set} or \class{ImmutableSet}
+classes.  There are currently no plans to deprecate the module.
+
+\begin{seealso}
+\seepep{218}{Adding a Built-In Set Object Type}{Originally proposed by
+Greg Wilson and ultimately implemented by Raymond Hettinger.}
+\end{seealso}
+
+
+%======================================================================
+\section{PEP 237: Unifying Long Integers and Integers}
+
+The lengthy transition process for this PEP, begun in Python 2.2,
+takes another step forward in Python 2.4.  In 2.3, certain integer
+operations that would behave differently after int/long unification
+triggered \exception{FutureWarning} warnings and returned values
+limited to 32 or 64 bits (depending on your platform).  In 2.4, these
+expressions no longer produce a warning and instead produce a
+different result that's usually a long integer.
+
+The problematic expressions are primarily left shifts and lengthy
+hexadecimal and octal constants.  For example,
+\code{2 \textless{}\textless{} 32} results
+in a warning in 2.3, evaluating to 0 on 32-bit platforms.  In Python
+2.4, this expression now returns the correct answer, 8589934592.
+
+\begin{seealso}
+\seepep{237}{Unifying Long Integers and Integers}{Original PEP
+written by Moshe Zadka and GvR.  The changes for 2.4 were implemented by 
+Kalle Svensson.}
+\end{seealso}
+
+
+%======================================================================
+\section{PEP 289: Generator Expressions}
+
+The iterator feature introduced in Python 2.2 and the
+\module{itertools} module make it easier to write programs that loop
+through large data sets without having the entire data set in memory
+at one time.  List comprehensions don't fit into this picture very
+well because they produce a Python list object containing all of the
+items.  This unavoidably pulls all of the objects into memory, which
+can be a problem if your data set is very large.  When trying to write
+a functionally-styled program, it would be natural to write something
+like:
+
+\begin{verbatim}
+links = [link for link in get_all_links() if not link.followed]
+for link in links:
+    ...
+\end{verbatim}
+
+instead of 
+
+\begin{verbatim}
+for link in get_all_links():
+    if link.followed:
+        continue
+    ...
+\end{verbatim}
+
+The first form is more concise and perhaps more readable, but if
+you're dealing with a large number of link objects you'd have to write
+the second form to avoid having all link objects in memory at the same
+time.
+
+Generator expressions work similarly to list comprehensions but don't
+materialize the entire list; instead they create a generator that will
+return elements one by one.  The above example could be written as:
+
+\begin{verbatim}
+links = (link for link in get_all_links() if not link.followed)
+for link in links:
+    ...
+\end{verbatim}
+
+Generator expressions always have to be written inside parentheses, as
+in the above example.  The parentheses signalling a function call also
+count, so if you want to create an iterator that will be immediately
+passed to a function you could write:
+
+\begin{verbatim}
+print sum(obj.count for obj in list_all_objects())
+\end{verbatim}
+
+Generator expressions differ from list comprehensions in various small
+ways.  Most notably, the loop variable (\var{obj} in the above
+example) is not accessible outside of the generator expression.  List
+comprehensions leave the variable assigned to its last value; future
+versions of Python will change this, making list comprehensions match
+generator expressions in this respect.
+
+\begin{seealso}
+\seepep{289}{Generator Expressions}{Proposed by Raymond Hettinger and
+implemented by Jiwon Seo with early efforts steered by Hye-Shik Chang.}
+\end{seealso}
+
+
+%======================================================================
+\section{PEP 292: Simpler String Substitutions}
+
+Some new classes in the standard library provide an alternative
+mechanism for substituting variables into strings; this style of
+substitution may be better for applications where untrained
+users need to edit templates.
+
+The usual way of substituting variables by name is the \code{\%}
+operator:
+
+\begin{verbatim}
+>>> '%(page)i: %(title)s' % {'page':2, 'title': 'The Best of Times'}
+'2: The Best of Times'
+\end{verbatim}
+
+When writing the template string, it can be easy to forget the
+\samp{i} or \samp{s} after the closing parenthesis.  This isn't a big
+problem if the template is in a Python module, because you run the
+code, get an ``Unsupported format character'' \exception{ValueError},
+and fix the problem.  However, consider an application such as Mailman
+where template strings or translations are being edited by users who
+aren't aware of the Python language.  The format string's syntax is
+complicated to explain to such users, and if they make a mistake, it's
+difficult to provide helpful feedback to them.
+
+PEP 292 adds a \class{Template} class to the \module{string} module
+that uses \samp{\$} to indicate a substitution:
+
+\begin{verbatim}
+>>> import string
+>>> t = string.Template('$page: $title')
+>>> t.substitute({'page':2, 'title': 'The Best of Times'})
+'2: The Best of Times'
+\end{verbatim}
+
+% $ Terminate $-mode for Emacs
+
+If a key is missing from the dictionary, the \method{substitute} method
+will raise a \exception{KeyError}.  There's also a \method{safe_substitute}
+method that ignores missing keys:
+
+\begin{verbatim}
+>>> t = string.Template('$page: $title')
+>>> t.safe_substitute({'page':3})
+'3: $title'
+\end{verbatim}
+
+% $ Terminate math-mode for Emacs
+
+
+\begin{seealso}
+\seepep{292}{Simpler String Substitutions}{Written and implemented 
+by Barry Warsaw.}
+\end{seealso}
+
+
+%======================================================================
+\section{PEP 318: Decorators for Functions and Methods}
+
+Python 2.2 extended Python's object model by adding static methods and
+class methods, but it didn't extend Python's syntax to provide any new
+way of defining static or class methods.  Instead, you had to write a
+\keyword{def} statement in the usual way, and pass the resulting
+method to a \function{staticmethod()} or \function{classmethod()}
+function that would wrap up the function as a method of the new type.
+Your code would look like this:
+
+\begin{verbatim}
+class C:
+   def meth (cls):
+       ...
+   
+   meth = classmethod(meth)   # Rebind name to wrapped-up class method
+\end{verbatim}
+
+If the method was very long, it would be easy to miss or forget the
+\function{classmethod()} invocation after the function body.  
+
+The intention was always to add some syntax to make such definitions
+more readable, but at the time of 2.2's release a good syntax was not
+obvious.  Today a good syntax \emph{still} isn't obvious but users are
+asking for easier access to the feature; a new syntactic feature has
+been added to meet this need.
+
+The new feature is called ``function decorators''.  The name comes
+from the idea that \function{classmethod}, \function{staticmethod},
+and friends are storing additional information on a function object;
+they're \emph{decorating} functions with more details.
+
+The notation borrows from Java and uses the \character{@} character as an
+indicator.  Using the new syntax, the example above would be written:
+
+\begin{verbatim}
+class C:
+
+   @classmethod
+   def meth (cls):
+       ...
+   
+\end{verbatim}
+
+The \code{@classmethod} is shorthand for the
+\code{meth=classmethod(meth)} assignment.  More generally, if you have
+the following:
+
+\begin{verbatim}
+ at A
+ at B
+ at C
+def f ():
+    ...
+\end{verbatim}
+
+It's equivalent to the following pre-decorator code:
+
+\begin{verbatim}
+def f(): ...
+f = A(B(C(f)))
+\end{verbatim}
+
+Decorators must come on the line before a function definition, one decorator
+per line, and can't be on the same line as the def statement, meaning that
+\code{@A def f(): ...} is illegal.  You can only decorate function
+definitions, either at the module level or inside a class; you can't
+decorate class definitions.
+
+A decorator is just a function that takes the function to be decorated as an
+argument and returns either the same function or some new object.  The
+return value of the decorator need not be callable (though it typically is),
+unless further decorators will be applied to the result.  It's easy to write
+your own decorators.  The following simple example just sets an attribute on
+the function object:
+
+\begin{verbatim}
+>>> def deco(func):
+...    func.attr = 'decorated'
+...    return func
+...
+>>> @deco
+... def f(): pass
+...
+>>> f
+<function f at 0x402ef0d4>
+>>> f.attr
+'decorated'
+>>>
+\end{verbatim}
+
+As a slightly more realistic example, the following decorator checks
+that the supplied argument is an integer:
+
+\begin{verbatim}
+def require_int (func):
+    def wrapper (arg):
+        assert isinstance(arg, int)
+        return func(arg)
+
+    return wrapper
+
+ at require_int
+def p1 (arg):
+    print arg
+
+ at require_int
+def p2(arg):
+    print arg*2
+\end{verbatim}
+
+An example in \pep{318} contains a fancier version of this idea that
+lets you both specify the required type and check the returned type.
+
+Decorator functions can take arguments.  If arguments are supplied,
+your decorator function is called with only those arguments and must
+return a new decorator function; this function must take a single
+function and return a function, as previously described.  In other
+words, \code{@A @B @C(args)} becomes:
+
+\begin{verbatim}
+def f(): ...
+_deco = C(args)
+f = A(B(_deco(f)))
+\end{verbatim}
+
+Getting this right can be slightly brain-bending, but it's not too
+difficult.
+
+A small related change makes the \member{func_name} attribute of
+functions writable.  This attribute is used to display function names
+in tracebacks, so decorators should change the name of any new
+function that's constructed and returned.
+
+\begin{seealso}
+\seepep{318}{Decorators for Functions, Methods and Classes}{Written 
+by Kevin D. Smith, Jim Jewett, and Skip Montanaro.  Several people
+wrote patches implementing function decorators, but the one that was
+actually checked in was patch \#979728, written by Mark Russell.}
+
+\seeurl{http://www.python.org/moin/PythonDecoratorLibrary}
+{This Wiki page contains several examples of decorators.}
+
+\end{seealso}
+
+
+%======================================================================
+\section{PEP 322: Reverse Iteration}
+
+A new built-in function, \function{reversed(\var{seq})}, takes a sequence
+and returns an iterator that loops over the elements of the sequence 
+in reverse order.  
+
+\begin{verbatim}
+>>> for i in reversed(xrange(1,4)):
+...    print i
+... 
+3
+2
+1
+\end{verbatim}
+
+Compared to extended slicing, such as \code{range(1,4)[::-1]},
+\function{reversed()} is easier to read, runs faster, and uses
+substantially less memory.
+
+Note that \function{reversed()} only accepts sequences, not arbitrary
+iterators.  If you want to reverse an iterator, first convert it to 
+a list with \function{list()}.
+
+\begin{verbatim}
+>>> input = open('/etc/passwd', 'r')
+>>> for line in reversed(list(input)):
+...   print line
+... 
+root:*:0:0:System Administrator:/var/root:/bin/tcsh
+  ...
+\end{verbatim}
+
+\begin{seealso}
+\seepep{322}{Reverse Iteration}{Written and implemented by Raymond Hettinger.}
+
+\end{seealso}
+
+
+%======================================================================
+\section{PEP 324: New subprocess Module}
+
+The standard library provides a number of ways to execute a
+subprocess, offering different features and different levels of
+complexity.  \function{os.system(\var{command})} is easy to use, but
+slow (it runs a shell process which executes the command) and
+dangerous (you have to be careful about escaping the shell's
+metacharacters).  The \module{popen2} module offers classes that can
+capture standard output and standard error from the subprocess, but
+the naming is confusing.  The \module{subprocess} module cleans 
+this up, providing a unified interface that offers all the features
+you might need.
+
+Instead of \module{popen2}'s collection of classes,
+\module{subprocess} contains a single class called \class{Popen} 
+whose constructor supports a number of different keyword arguments.
+
+\begin{verbatim}
+class Popen(args, bufsize=0, executable=None,
+	    stdin=None, stdout=None, stderr=None,
+	    preexec_fn=None, close_fds=False, shell=False,
+	    cwd=None, env=None, universal_newlines=False,
+	    startupinfo=None, creationflags=0):
+\end{verbatim}
+
+\var{args} is commonly a sequence of strings that will be the
+arguments to the program executed as the subprocess.  (If the
+\var{shell} argument is true, \var{args} can be a string which will
+then be passed on to the shell for interpretation, just as
+\function{os.system()} does.)
+
+\var{stdin}, \var{stdout}, and \var{stderr} specify what the
+subprocess's input, output, and error streams will be.  You can
+provide a file object or a file descriptor, or you can use the
+constant \code{subprocess.PIPE} to create a pipe between the
+subprocess and the parent.
+
+The constructor has a number of handy options:
+
+\begin{itemize}
+  \item \var{close_fds} requests that all file descriptors be closed
+  before running the subprocess.
+
+  \item \var{cwd} specifies the working directory in which the
+  subprocess will be executed (defaulting to whatever the parent's
+  working directory is).
+
+  \item \var{env} is a dictionary specifying environment variables.
+
+  \item \var{preexec_fn} is a function that gets called before the
+  child is started.
+
+  \item \var{universal_newlines} opens the child's input and output
+  using Python's universal newline feature.
+
+\end{itemize}
+
+Once you've created the \class{Popen} instance, 
+you can call its \method{wait()} method to pause until the subprocess
+has exited, \method{poll()} to check if it's exited without pausing, 
+or \method{communicate(\var{data})} to send the string \var{data} to
+the subprocess's standard input.   \method{communicate(\var{data})} 
+then reads any data that the subprocess has sent to its standard output 
+or standard error, returning a tuple \code{(\var{stdout_data},
+\var{stderr_data})}.
+
+\function{call()} is a shortcut that passes its arguments along to the
+\class{Popen} constructor, waits for the command to complete, and
+returns the status code of the subprocess.  It can serve as a safer
+analog to \function{os.system()}:
+
+\begin{verbatim}
+sts = subprocess.call(['dpkg', '-i', '/tmp/new-package.deb'])
+if sts == 0:
+    # Success
+    ...
+else:
+    # dpkg returned an error
+    ...
+\end{verbatim}
+
+The command is invoked without use of the shell.  If you really do want to 
+use the shell, you can add \code{shell=True} as a keyword argument and provide
+a string instead of a sequence:
+
+\begin{verbatim}
+sts = subprocess.call('dpkg -i /tmp/new-package.deb', shell=True)
+\end{verbatim}
+
+The PEP takes various examples of shell and Python code and shows how
+they'd be translated into Python code that uses \module{subprocess}. 
+Reading this section of the PEP is highly recommended.
+
+\begin{seealso}
+\seepep{324}{subprocess - New process module}{Written and implemented by Peter {\AA}strand, with assistance from Fredrik Lundh and others.}
+\end{seealso}
+
+
+%======================================================================
+\section{PEP 327: Decimal Data Type}
+
+Python has always supported floating-point (FP) numbers, based on the
+underlying C \ctype{double} type, as a data type.  However, while most
+programming languages provide a floating-point type, many people (even
+programmers) are unaware that floating-point numbers don't represent
+certain decimal fractions accurately.  The new \class{Decimal} type
+can represent these fractions accurately, up to a user-specified
+precision limit.
+
+
+\subsection{Why is Decimal needed?}
+
+The limitations arise from the representation used for floating-point numbers.
+FP numbers are made up of three components:
+
+\begin{itemize}
+\item The sign, which is positive or negative.
+\item The mantissa, which is a single-digit binary number  
+followed by a fractional part.  For example, \code{1.01} in base-2 notation
+is \code{1 + 0/2 + 1/4}, or 1.25 in decimal notation.
+\item The exponent, which tells where the decimal point is located in the number represented.  
+\end{itemize}
+
+For example, the number 1.25 has positive sign, a mantissa value of
+1.01 (in binary), and an exponent of 0 (the decimal point doesn't need
+to be shifted).  The number 5 has the same sign and mantissa, but the
+exponent is 2 because the mantissa is multiplied by 4 (2 to the power
+of the exponent 2); 1.25 * 4 equals 5.
+
+Modern systems usually provide floating-point support that conforms to
+a standard called IEEE 754.  C's \ctype{double} type is usually
+implemented as a 64-bit IEEE 754 number, which uses 52 bits of space
+for the mantissa.  This means that numbers can only be specified to 52
+bits of precision.  If you're trying to represent numbers whose
+expansion repeats endlessly, the expansion is cut off after 52 bits.
+Unfortunately, most software needs to produce output in base 10, and
+common fractions in base 10 are often repeating decimals in binary.
+For example, 1.1 decimal is binary \code{1.0001100110011 ...}; .1 =
+1/16 + 1/32 + 1/256 plus an infinite number of additional terms.  IEEE
+754 has to chop off that infinitely repeated decimal after 52 digits,
+so the representation is slightly inaccurate.
+
+Sometimes you can see this inaccuracy when the number is printed:
+\begin{verbatim}
+>>> 1.1
+1.1000000000000001
+\end{verbatim}
+
+The inaccuracy isn't always visible when you print the number because
+the FP-to-decimal-string conversion is provided by the C library, and
+most C libraries try to produce sensible output.  Even if it's not
+displayed, however, the inaccuracy is still there and subsequent
+operations can magnify the error.
+
+For many applications this doesn't matter.  If I'm plotting points and
+displaying them on my monitor, the difference between 1.1 and
+1.1000000000000001 is too small to be visible.  Reports often limit
+output to a certain number of decimal places, and if you round the
+number to two or three or even eight decimal places, the error is
+never apparent.  However, for applications where it does matter, 
+it's a lot of work to implement your own custom arithmetic routines.
+
+Hence, the \class{Decimal} type was created.
+
+\subsection{The \class{Decimal} type}
+
+A new module, \module{decimal}, was added to Python's standard
+library.  It contains two classes, \class{Decimal} and
+\class{Context}.  \class{Decimal} instances represent numbers, and
+\class{Context} instances are used to wrap up various settings such as
+the precision and default rounding mode.
+
+\class{Decimal} instances are immutable, like regular Python integers
+and FP numbers; once it's been created, you can't change the value an
+instance represents.  \class{Decimal} instances can be created from
+integers or strings:
+
+\begin{verbatim}
+>>> import decimal
+>>> decimal.Decimal(1972)
+Decimal("1972")
+>>> decimal.Decimal("1.1")
+Decimal("1.1")
+\end{verbatim}
+
+You can also provide tuples containing the sign, the mantissa represented 
+as a tuple of decimal digits, and the exponent:
+
+\begin{verbatim}
+>>> decimal.Decimal((1, (1, 4, 7, 5), -2))
+Decimal("-14.75")
+\end{verbatim}
+
+Cautionary note: the sign bit is a Boolean value, so 0 is positive and
+1 is negative. 
+
+Converting from floating-point numbers poses a bit of a problem:
+should the FP number representing 1.1 turn into the decimal number for
+exactly 1.1, or for 1.1 plus whatever inaccuracies are introduced?
+The decision was to dodge the issue and leave such a conversion out of
+the API.  Instead, you should convert the floating-point number into a
+string using the desired precision and pass the string to the
+\class{Decimal} constructor:
+
+\begin{verbatim}
+>>> f = 1.1
+>>> decimal.Decimal(str(f))
+Decimal("1.1")
+>>> decimal.Decimal('%.12f' % f)
+Decimal("1.100000000000")
+\end{verbatim}
+
+Once you have \class{Decimal} instances, you can perform the usual
+mathematical operations on them.  One limitation: exponentiation
+requires an integer exponent:
+
+\begin{verbatim}
+>>> a = decimal.Decimal('35.72')
+>>> b = decimal.Decimal('1.73')
+>>> a+b
+Decimal("37.45")
+>>> a-b
+Decimal("33.99")
+>>> a*b
+Decimal("61.7956")
+>>> a/b
+Decimal("20.64739884393063583815028902")
+>>> a ** 2
+Decimal("1275.9184")
+>>> a**b
+Traceback (most recent call last):
+  ...
+decimal.InvalidOperation: x ** (non-integer)
+\end{verbatim}
+
+You can combine \class{Decimal} instances with integers, but not with
+floating-point numbers:
+
+\begin{verbatim}
+>>> a + 4
+Decimal("39.72")
+>>> a + 4.5
+Traceback (most recent call last):
+  ...
+TypeError: You can interact Decimal only with int, long or Decimal data types.
+>>>
+\end{verbatim}
+
+\class{Decimal} numbers can be used with the \module{math} and
+\module{cmath} modules, but note that they'll be immediately converted to 
+floating-point numbers before the operation is performed, resulting in
+a possible loss of precision and accuracy.  You'll also get back a
+regular floating-point number and not a \class{Decimal}.  
+
+\begin{verbatim}
+>>> import math, cmath
+>>> d = decimal.Decimal('123456789012.345')
+>>> math.sqrt(d)
+351364.18288201344
+>>> cmath.sqrt(-d)
+351364.18288201344j
+\end{verbatim}
+
+\class{Decimal} instances have a \method{sqrt()} method that
+returns a \class{Decimal}, but if you need other things such as
+trigonometric functions you'll have to implement them.
+
+\begin{verbatim}
+>>> d.sqrt()
+Decimal("351364.1828820134592177245001")
+\end{verbatim}
+
+
+\subsection{The \class{Context} type}
+
+Instances of the \class{Context} class encapsulate several settings for 
+decimal operations:
+
+\begin{itemize}
+ \item \member{prec} is the precision, the number of decimal places.
+ \item \member{rounding} specifies the rounding mode.  The \module{decimal}
+       module has constants for the various possibilities:
+       \constant{ROUND_DOWN}, \constant{ROUND_CEILING}, 
+       \constant{ROUND_HALF_EVEN}, and various others.
+ \item \member{traps} is a dictionary specifying what happens on
+encountering certain error conditions: either  an exception is raised or 
+a value is returned.  Some examples of error conditions are
+division by zero, loss of precision, and overflow.
+\end{itemize}
+
+There's a thread-local default context available by calling
+\function{getcontext()}; you can change the properties of this context
+to alter the default precision, rounding, or trap handling.  The
+following example shows the effect of changing the precision of the default
+context:
+
+\begin{verbatim}
+>>> decimal.getcontext().prec
+28
+>>> decimal.Decimal(1) / decimal.Decimal(7)
+Decimal("0.1428571428571428571428571429")
+>>> decimal.getcontext().prec = 9 
+>>> decimal.Decimal(1) / decimal.Decimal(7)
+Decimal("0.142857143")
+\end{verbatim}
+
+The default action for error conditions is selectable; the module can
+either return a special value such as infinity or not-a-number, or
+exceptions can be raised:
+
+\begin{verbatim}
+>>> decimal.Decimal(1) / decimal.Decimal(0)
+Traceback (most recent call last):
+  ...
+decimal.DivisionByZero: x / 0
+>>> decimal.getcontext().traps[decimal.DivisionByZero] = False
+>>> decimal.Decimal(1) / decimal.Decimal(0)
+Decimal("Infinity")
+>>> 
+\end{verbatim}
+
+The \class{Context} instance also has various methods for formatting 
+numbers such as \method{to_eng_string()} and \method{to_sci_string()}.
+
+For more information, see the documentation for the \module{decimal}
+module, which includes a quick-start tutorial and a reference.
+
+\begin{seealso}
+\seepep{327}{Decimal Data Type}{Written by Facundo Batista and implemented
+  by Facundo Batista, Eric Price, Raymond Hettinger, Aahz, and Tim Peters.}
+
+\seeurl{http://research.microsoft.com/\textasciitilde hollasch/cgindex/coding/ieeefloat.html}
+{A more detailed overview of the IEEE-754 representation.}
+
+\seeurl{http://www.lahey.com/float.htm}
+{The article uses Fortran code to illustrate many of the problems
+that floating-point inaccuracy can cause.}
+
+\seeurl{http://www2.hursley.ibm.com/decimal/}
+{A description of a decimal-based representation.  This representation
+is being proposed as a standard, and underlies the new Python decimal
+type.  Much of this material was written by Mike Cowlishaw, designer of the
+Rexx language.}
+
+\end{seealso}      
+
+
+%======================================================================
+\section{PEP 328: Multi-line Imports}
+
+One language change is a small syntactic tweak aimed at making it
+easier to import many names from a module.  In a
+\code{from \var{module} import \var{names}} statement, 
+\var{names} is a sequence of names separated by commas.  If the sequence is 
+very long, you can either write multiple imports from the same module,
+or you can use backslashes to escape the line endings like this:
+
+\begin{verbatim}
+from SimpleXMLRPCServer import SimpleXMLRPCServer,\
+            SimpleXMLRPCRequestHandler,\
+            CGIXMLRPCRequestHandler,\
+            resolve_dotted_attribute
+\end{verbatim}
+
+The syntactic change in Python 2.4 simply allows putting the names
+within parentheses.  Python ignores newlines within a parenthesized
+expression, so the backslashes are no longer needed:
+
+\begin{verbatim}
+from SimpleXMLRPCServer import (SimpleXMLRPCServer,
+                                SimpleXMLRPCRequestHandler,
+                                CGIXMLRPCRequestHandler,
+                                resolve_dotted_attribute)
+\end{verbatim}
+
+The PEP also proposes that all \keyword{import} statements be absolute
+imports, with a leading \samp{.} character to indicate a relative
+import.  This part of the PEP was not implemented for Python 2.4,
+but was completed for Python 2.5.
+
+\begin{seealso}
+\seepep{328}{Imports: Multi-Line and Absolute/Relative}
+            {Written by Aahz.  Multi-line imports were implemented by
+             Dima Dorfman.}
+\end{seealso}
+
+
+%======================================================================
+\section{PEP 331: Locale-Independent Float/String Conversions}
+
+The \module{locale} modules lets Python software select various
+conversions and display conventions that are localized to a particular
+country or language.  However, the module was careful to not change
+the numeric locale because various functions in Python's
+implementation required that the numeric locale remain set to the
+\code{'C'} locale.  Often this was because the code was using the C library's
+\cfunction{atof()} function.  
+
+Not setting the numeric locale caused trouble for extensions that used
+third-party C libraries, however, because they wouldn't have the
+correct locale set.  The motivating example was GTK+, whose user
+interface widgets weren't displaying numbers in the current locale.
+
+The solution described in the PEP is to add three new functions to the
+Python API that perform ASCII-only conversions, ignoring the locale
+setting:
+
+\begin{itemize}
+ \item \cfunction{PyOS_ascii_strtod(\var{str}, \var{ptr})} 
+and \cfunction{PyOS_ascii_atof(\var{str}, \var{ptr})} 
+both convert a string to a C \ctype{double}.
+ \item \cfunction{PyOS_ascii_formatd(\var{buffer}, \var{buf_len}, \var{format}, \var{d})} converts a \ctype{double} to an ASCII string.
+\end{itemize}
+
+The code for these functions came from the GLib library
+(\url{http://developer.gnome.org/arch/gtk/glib.html}), whose
+developers kindly relicensed the relevant functions and donated them
+to the Python Software Foundation.  The \module{locale} module 
+can now change the numeric locale, letting extensions such as GTK+ 
+produce the correct results.
+
+\begin{seealso}
+\seepep{331}{Locale-Independent Float/String Conversions}
+{Written by Christian R. Reis, and implemented by Gustavo Carneiro.}
+\end{seealso}      
+
+%======================================================================
+\section{Other Language Changes}
+
+Here are all of the changes that Python 2.4 makes to the core Python
+language.
+
+\begin{itemize}
+
+\item Decorators for functions and methods were added (\pep{318}).
+
+\item Built-in \function{set} and \function{frozenset} types were 
+added (\pep{218}).  Other new built-ins include the \function{reversed(\var{seq})} function (\pep{322}).
+
+\item Generator expressions were added (\pep{289}).
+
+\item Certain numeric expressions no longer return values restricted to 32 or 64 bits (\pep{237}).
+
+\item You can now put parentheses around the list of names in a
+\code{from \var{module} import \var{names}} statement (\pep{328}).
+
+\item The \method{dict.update()} method now accepts the same
+argument forms as the \class{dict} constructor.  This includes any
+mapping, any iterable of key/value pairs, and keyword arguments.
+(Contributed by Raymond Hettinger.)
+
+\item The string methods \method{ljust()}, \method{rjust()}, and
+\method{center()} now take an optional argument for specifying a
+fill character other than a space.
+(Contributed by Raymond Hettinger.)
+
+\item Strings also gained an \method{rsplit()} method that
+works like the \method{split()} method but splits from the end of
+the string.  
+(Contributed by Sean Reifschneider.)
+
+\begin{verbatim}
+>>> 'www.python.org'.split('.', 1)
+['www', 'python.org']
+'www.python.org'.rsplit('.', 1)
+['www.python', 'org']        
+\end{verbatim}      
+
+\item Three keyword parameters, \var{cmp}, \var{key}, and
+\var{reverse}, were added to the \method{sort()} method of lists.
+These parameters make some common usages of \method{sort()} simpler.
+All of these parameters are optional.
+
+For the \var{cmp} parameter, the value should be a comparison function
+that takes two parameters and returns -1, 0, or +1 depending on how
+the parameters compare.  This function will then be used to sort the
+list.  Previously this was the only parameter that could be provided
+to \method{sort()}.
+
+\var{key} should be a single-parameter function that takes a list
+element and returns a comparison key for the element.  The list is
+then sorted using the comparison keys.  The following example sorts a
+list case-insensitively:
+
+\begin{verbatim}
+>>> L = ['A', 'b', 'c', 'D']
+>>> L.sort()                 # Case-sensitive sort
+>>> L
+['A', 'D', 'b', 'c']
+>>> # Using 'key' parameter to sort list
+>>> L.sort(key=lambda x: x.lower())
+>>> L
+['A', 'b', 'c', 'D']
+>>> # Old-fashioned way
+>>> L.sort(cmp=lambda x,y: cmp(x.lower(), y.lower()))
+>>> L
+['A', 'b', 'c', 'D']
+\end{verbatim}
+
+The last example, which uses the \var{cmp} parameter, is the old way
+to perform a case-insensitive sort.  It works but is slower than using
+a \var{key} parameter.  Using \var{key} calls \method{lower()} method
+once for each element in the list while using \var{cmp} will call it
+twice for each comparison, so using \var{key} saves on invocations of
+the \method{lower()} method.
+
+For simple key functions and comparison functions, it is often
+possible to avoid a \keyword{lambda} expression by using an unbound
+method instead.  For example, the above case-insensitive sort is best
+written as:
+
+\begin{verbatim}
+>>> L.sort(key=str.lower)
+>>> L
+['A', 'b', 'c', 'D']
+\end{verbatim}       
+
+Finally, the \var{reverse} parameter takes a Boolean value.  If the
+value is true, the list will be sorted into reverse order.
+Instead of \code{L.sort() ; L.reverse()}, you can now write
+\code{L.sort(reverse=True)}.
+
+The results of sorting are now guaranteed to be stable.  This means
+that two entries with equal keys will be returned in the same order as
+they were input.  For example, you can sort a list of people by name,
+and then sort the list by age, resulting in a list sorted by age where
+people with the same age are in name-sorted order.
+
+(All changes to \method{sort()} contributed by Raymond Hettinger.)
+
+\item There is a new built-in function
+\function{sorted(\var{iterable})} that works like the in-place
+\method{list.sort()} method but can be used in
+expressions.  The differences are:
+  \begin{itemize}
+  \item the input may be any iterable;
+  \item a newly formed copy is sorted, leaving the original intact; and
+  \item the expression returns the new sorted copy
+  \end{itemize}
+
+\begin{verbatim}
+>>> L = [9,7,8,3,2,4,1,6,5]
+>>> [10+i for i in sorted(L)]       # usable in a list comprehension
+[11, 12, 13, 14, 15, 16, 17, 18, 19]
+>>> L                               # original is left unchanged
+[9,7,8,3,2,4,1,6,5]
+>>> sorted('Monty Python')          # any iterable may be an input
+[' ', 'M', 'P', 'h', 'n', 'n', 'o', 'o', 't', 't', 'y', 'y']
+
+>>> # List the contents of a dict sorted by key values
+>>> colormap = dict(red=1, blue=2, green=3, black=4, yellow=5)
+>>> for k, v in sorted(colormap.iteritems()):
+...     print k, v
+...
+black 4
+blue 2
+green 3
+red 1
+yellow 5
+\end{verbatim}
+
+(Contributed by Raymond Hettinger.)
+
+\item Integer operations will no longer trigger an \exception{OverflowWarning}.
+The \exception{OverflowWarning} warning will disappear in Python 2.5.
+
+\item The interpreter gained a new switch, \programopt{-m}, that
+takes a name, searches for the corresponding  module on \code{sys.path},
+and runs the module as a script.  For example, 
+you can now run the Python profiler with \code{python -m profile}.
+(Contributed by Nick Coghlan.)
+
+\item The \function{eval(\var{expr}, \var{globals}, \var{locals})}
+and \function{execfile(\var{filename}, \var{globals}, \var{locals})}
+functions and the \keyword{exec} statement now accept any mapping type
+for the \var{locals} parameter.  Previously this had to be a regular
+Python dictionary.  (Contributed by Raymond Hettinger.)
+
+\item The \function{zip()} built-in function and \function{itertools.izip()}
+  now return an empty list if called with no arguments.
+  Previously they raised a \exception{TypeError}
+  exception.  This makes them more
+  suitable for use with variable length argument lists:
+
+\begin{verbatim}
+>>> def transpose(array):
+...    return zip(*array)
+...
+>>> transpose([(1,2,3), (4,5,6)])
+[(1, 4), (2, 5), (3, 6)]
+>>> transpose([])
+[]
+\end{verbatim}
+(Contributed by Raymond Hettinger.)
+    
+\item Encountering a failure while importing a module no longer leaves
+a partially-initialized module object in \code{sys.modules}.  The
+incomplete module object left behind would fool further imports of the
+same module into succeeding, leading to confusing errors.  
+(Fixed by Tim Peters.)
+
+\item \constant{None} is now a constant; code that binds a new value to 
+the name \samp{None} is now a syntax error.
+(Contributed by Raymond Hettinger.)       
+
+\end{itemize}
+
+
+%======================================================================
+\subsection{Optimizations}
+
+\begin{itemize}
+
+\item The inner loops for list and tuple slicing
+ were optimized and now run about one-third faster.  The inner loops
+ for dictionaries were also optimized, resulting in performance boosts for
+ \method{keys()}, \method{values()}, \method{items()},
+ \method{iterkeys()}, \method{itervalues()}, and \method{iteritems()}.
+ (Contributed by Raymond Hettinger.)
+
+\item The machinery for growing and shrinking lists was optimized for
+ speed and for space efficiency.  Appending and popping from lists now
+ runs faster due to more efficient code paths and less frequent use of
+ the underlying system \cfunction{realloc()}.  List comprehensions
+ also benefit.   \method{list.extend()} was also optimized and no
+ longer converts its argument into a temporary list before extending
+ the base list.  (Contributed by Raymond Hettinger.)
+
+\item \function{list()}, \function{tuple()}, \function{map()},
+  \function{filter()}, and \function{zip()} now run several times
+  faster with non-sequence arguments that supply a \method{__len__()}
+  method.  (Contributed by Raymond Hettinger.)
+
+\item The methods \method{list.__getitem__()},
+  \method{dict.__getitem__()}, and \method{dict.__contains__()} are
+  are now implemented as \class{method_descriptor} objects rather
+  than \class{wrapper_descriptor} objects.  This form of 
+  access doubles their performance and makes them more suitable for
+  use as arguments to functionals:
+  \samp{map(mydict.__getitem__, keylist)}.
+  (Contributed by Raymond Hettinger.)
+
+\item Added a new opcode, \code{LIST_APPEND}, that simplifies
+  the generated bytecode for list comprehensions and speeds them up
+  by about a third.  (Contributed by Raymond Hettinger.)
+
+\item The peephole bytecode optimizer has been improved to 
+produce shorter, faster bytecode; remarkably, the resulting bytecode is 
+more readable.  (Enhanced by Raymond Hettinger.)
+
+\item String concatenations in statements of the form \code{s = s +
+"abc"} and \code{s += "abc"} are now performed more efficiently in
+certain circumstances.  This optimization won't be present in other
+Python implementations such as Jython, so you shouldn't rely on it;
+using the \method{join()} method of strings is still recommended when
+you want to efficiently glue a large number of strings together.
+(Contributed by Armin Rigo.)       
+
+\end{itemize}
+
+% pystone is almost useless for comparing different versions of Python;
+% instead, it excels at predicting relative Python performance on
+% different machines.
+% So, this section would be more informative if it used other tools
+% such as pybench and parrotbench.  For a more application oriented
+% benchmark, try comparing the timings of test_decimal.py under 2.3
+% and 2.4.
+       
+The net result of the 2.4 optimizations is that Python 2.4 runs the
+pystone benchmark around 5\% faster than Python 2.3 and 35\% faster
+than Python 2.2.  (pystone is not a particularly good benchmark, but
+it's the most commonly used measurement of Python's performance.  Your
+own applications may show greater or smaller benefits from Python~2.4.)
+
+
+%======================================================================
+\section{New, Improved, and Deprecated Modules}
+
+As usual, Python's standard library received a number of enhancements and
+bug fixes.  Here's a partial list of the most notable changes, sorted
+alphabetically by module name. Consult the
+\file{Misc/NEWS} file in the source tree for a more
+complete list of changes, or look through the CVS logs for all the
+details.
+
+\begin{itemize}
+
+\item The \module{asyncore} module's \function{loop()} function now
+   has a \var{count} parameter that lets you perform a limited number
+   of passes through the polling loop.  The default is still to loop
+   forever.
+
+\item The \module{base64} module now has more complete RFC 3548 support
+  for Base64, Base32, and Base16 encoding and decoding, including
+  optional case folding and optional alternative alphabets.
+  (Contributed by Barry Warsaw.)
+
+\item The \module{bisect} module now has an underlying C implementation
+   for improved performance.
+   (Contributed by Dmitry Vasiliev.)
+
+\item The CJKCodecs collections of East Asian codecs, maintained
+by Hye-Shik Chang, was integrated into 2.4.  
+The new encodings are:
+
+\begin{itemize}
+ \item Chinese (PRC): gb2312, gbk, gb18030, big5hkscs, hz
+ \item Chinese (ROC): big5, cp950
+ \item Japanese: cp932, euc-jis-2004, euc-jp,
+euc-jisx0213, iso-2022-jp, iso-2022-jp-1, iso-2022-jp-2,
+ iso-2022-jp-3, iso-2022-jp-ext, iso-2022-jp-2004,
+ shift-jis, shift-jisx0213, shift-jis-2004
+ \item Korean: cp949, euc-kr, johab, iso-2022-kr
+\end{itemize} 
+
+\item Some other new encodings were added: HP Roman8, 
+ISO_8859-11, ISO_8859-16, PCTP-154, and TIS-620.
+
+\item The UTF-8 and UTF-16 codecs now cope better with receiving partial input.
+Previously the \class{StreamReader} class would try to read more data,
+making it impossible to resume decoding from the stream.  The
+\method{read()} method will now return as much data as it can and future
+calls will resume decoding where previous ones left off. 
+(Implemented by Walter D\"orwald.)
+
+\item There is a new \module{collections} module for 
+   various specialized collection datatypes.  
+   Currently it contains just one type, \class{deque}, 
+   a double-ended queue that supports efficiently adding and removing
+   elements from either end:
+
+\begin{verbatim}
+>>> from collections import deque
+>>> d = deque('ghi')        # make a new deque with three items
+>>> d.append('j')           # add a new entry to the right side
+>>> d.appendleft('f')       # add a new entry to the left side
+>>> d                       # show the representation of the deque
+deque(['f', 'g', 'h', 'i', 'j'])
+>>> d.pop()                 # return and remove the rightmost item
+'j'
+>>> d.popleft()             # return and remove the leftmost item
+'f'
+>>> list(d)                 # list the contents of the deque
+['g', 'h', 'i']
+>>> 'h' in d                # search the deque
+True  
+\end{verbatim}
+
+Several modules, such as the \module{Queue} and \module{threading}
+modules, now take advantage of \class{collections.deque} for improved
+performance.  (Contributed by Raymond Hettinger.)
+
+\item The \module{ConfigParser} classes have been enhanced slightly.
+   The \method{read()} method now returns a list of the files that
+   were successfully parsed, and the \method{set()} method raises
+   \exception{TypeError} if passed a \var{value} argument that isn't a
+   string.   (Contributed by John Belmonte and David Goodger.)
+
+\item The \module{curses} module now supports the ncurses extension 
+   \function{use_default_colors()}.  On platforms where the terminal
+   supports transparency, this makes it possible to use a transparent
+   background.  (Contributed by J\"org Lehmann.)
+
+\item The \module{difflib} module now includes an \class{HtmlDiff} class
+that creates an HTML table showing a side by side comparison
+of two versions of a text.   (Contributed by Dan Gass.)
+
+\item The \module{email} package was updated to version 3.0, 
+which dropped various deprecated APIs and removes support for Python
+versions earlier than 2.3.  The 3.0 version of the package uses a new
+incremental parser for MIME messages, available in the
+\module{email.FeedParser} module.  The new parser doesn't require
+reading the entire message into memory, and doesn't throw exceptions
+if a message is malformed; instead it records any problems in the 
+\member{defect} attribute of the message.  (Developed by Anthony
+Baxter, Barry Warsaw, Thomas Wouters, and others.)
+
+\item The \module{heapq} module has been converted to C.  The resulting
+   tenfold improvement in speed makes the module suitable for handling
+   high volumes of data.  In addition, the module has two new functions
+   \function{nlargest()} and \function{nsmallest()} that use heaps to
+   find the N largest or smallest values in a dataset without the
+   expense of a full sort.  (Contributed by Raymond Hettinger.)
+
+\item The \module{httplib} module now contains constants for HTTP
+status codes defined in various HTTP-related RFC documents.  Constants
+have names such as \constant{OK}, \constant{CREATED},
+\constant{CONTINUE}, and \constant{MOVED_PERMANENTLY}; use pydoc to
+get a full list.  (Contributed by Andrew Eland.)
+
+\item The \module{imaplib} module now supports IMAP's THREAD command
+(contributed by Yves Dionne) and new \method{deleteacl()} and
+\method{myrights()} methods (contributed by Arnaud Mazin).
+
+\item The \module{itertools} module gained a
+  \function{groupby(\var{iterable}\optional{, \var{func}})} function.
+  \var{iterable} is something that can be iterated over to return a
+  stream of elements, and the optional \var{func} parameter is a
+  function that takes an element and returns a key value; if omitted,
+  the key is simply the element itself.  \function{groupby()} then
+  groups the elements into subsequences which have matching values of
+  the key, and returns a series of 2-tuples containing the key value
+  and an iterator over the subsequence.
+ 
+Here's an example to make this clearer.  The \var{key} function simply
+returns whether a number is even or odd, so the result of
+\function{groupby()} is to return consecutive runs of odd or even
+numbers.
+
+\begin{verbatim}
+>>> import itertools
+>>> L = [2, 4, 6, 7, 8, 9, 11, 12, 14]
+>>> for key_val, it in itertools.groupby(L, lambda x: x % 2):
+...    print key_val, list(it)
+... 
+0 [2, 4, 6]
+1 [7]
+0 [8]
+1 [9, 11]
+0 [12, 14]
+>>> 
+\end{verbatim}
+
+\function{groupby()} is typically used with sorted input.  The logic
+for \function{groupby()} is similar to the \UNIX{} \code{uniq} filter
+which makes it handy for eliminating, counting, or identifying
+duplicate elements:
+
+\begin{verbatim}
+>>> word = 'abracadabra'
+>>> letters = sorted(word)   # Turn string into a sorted list of letters
+>>> letters 
+['a', 'a', 'a', 'a', 'a', 'b', 'b', 'c', 'd', 'r', 'r']
+>>> for k, g in itertools.groupby(letters):
+...    print k, list(g)
+... 
+a ['a', 'a', 'a', 'a', 'a']
+b ['b', 'b']
+c ['c']
+d ['d']
+r ['r', 'r']
+>>> # List unique letters
+>>> [k for k, g in groupby(letters)]                     
+['a', 'b', 'c', 'd', 'r']
+>>> # Count letter occurrences
+>>> [(k, len(list(g))) for k, g in groupby(letters)]     
+[('a', 5), ('b', 2), ('c', 1), ('d', 1), ('r', 2)]
+\end{verbatim}
+
+(Contributed by Hye-Shik Chang.)
+
+\item \module{itertools} also gained a function named
+\function{tee(\var{iterator}, \var{N})} that returns \var{N} independent
+iterators that replicate \var{iterator}.  If \var{N} is omitted, the
+default is 2.
+
+\begin{verbatim}
+>>> L = [1,2,3]
+>>> i1, i2 = itertools.tee(L)
+>>> i1,i2
+(<itertools.tee object at 0x402c2080>, <itertools.tee object at 0x402c2090>)
+>>> list(i1)               # Run the first iterator to exhaustion
+[1, 2, 3]
+>>> list(i2)               # Run the second iterator to exhaustion
+[1, 2, 3]
+>\end{verbatim}
+
+Note that \function{tee()} has to keep copies of the values returned 
+by the iterator; in the worst case, it may need to keep all of them.  
+This should therefore be used carefully if the leading iterator
+can run far ahead of the trailing iterator in a long stream of inputs.
+If the separation is large, then you might as well use 
+\function{list()} instead.  When the iterators track closely with one
+another, \function{tee()} is ideal.  Possible applications include
+bookmarking, windowing, or lookahead iterators.
+(Contributed by Raymond Hettinger.)       
+
+\item  A number of functions were added to the \module{locale} 
+module, such as \function{bind_textdomain_codeset()} to specify a
+particular encoding and a family of \function{l*gettext()} functions
+that return messages in the chosen encoding.
+(Contributed by Gustavo Niemeyer.)
+
+\item Some keyword arguments were added to the \module{logging}
+package's \function{basicConfig} function to simplify log
+configuration.  The default behavior is to log messages to standard
+error, but various keyword arguments can be specified to log to a
+particular file, change the logging format, or set the logging level.
+For example:
+
+\begin{verbatim}
+import logging
+logging.basicConfig(filename='/var/log/application.log',
+    level=0,  # Log all messages
+    format='%(levelname):%(process):%(thread):%(message)')	            
+\end{verbatim}
+
+Other additions to the \module{logging} package include a
+\method{log(\var{level}, \var{msg})} convenience method, as well as a
+\class{TimedRotatingFileHandler} class that rotates its log files at a
+timed interval.  The module already had \class{RotatingFileHandler},
+which rotated logs once the file exceeded a certain size.  Both
+classes derive from a new \class{BaseRotatingHandler} class that can
+be used to implement other rotating handlers.
+
+(Changes implemented by Vinay Sajip.)
+
+\item The \module{marshal} module now shares interned strings on unpacking a 
+data structure.  This may shrink the size of certain pickle strings,
+but the primary effect is to make \file{.pyc} files significantly smaller.
+(Contributed by Martin von~L\"owis.)
+
+\item The \module{nntplib} module's \class{NNTP} class gained
+\method{description()} and \method{descriptions()} methods to retrieve 
+newsgroup descriptions for a single group or for a range of groups.
+(Contributed by J\"urgen A. Erhard.)
+
+\item Two new functions were added to the \module{operator} module, 
+\function{attrgetter(\var{attr})} and \function{itemgetter(\var{index})}.
+Both functions return callables that take a single argument and return
+the corresponding attribute or item; these callables make excellent
+data extractors when used with \function{map()} or
+\function{sorted()}.  For example:
+
+\begin{verbatim}
+>>> L = [('c', 2), ('d', 1), ('a', 4), ('b', 3)]
+>>> map(operator.itemgetter(0), L)
+['c', 'd', 'a', 'b']
+>>> map(operator.itemgetter(1), L)
+[2, 1, 4, 3]
+>>> sorted(L, key=operator.itemgetter(1)) # Sort list by second tuple item
+[('d', 1), ('c', 2), ('b', 3), ('a', 4)]
+\end{verbatim}
+
+(Contributed by Raymond Hettinger.)       
+
+\item The \module{optparse} module was updated in various ways.  The
+module now passes its messages through \function{gettext.gettext()},
+making it possible to internationalize Optik's help and error
+messages.  Help messages for options can now include the string
+\code{'\%default'}, which will be replaced by the option's default
+value.  (Contributed by Greg Ward.)
+
+\item The long-term plan is to deprecate the \module{rfc822} module
+in some future Python release in favor of the \module{email} package.
+To this end, the \function{email.Utils.formatdate()} function has been
+changed to make it usable as a replacement for
+\function{rfc822.formatdate()}.  You may want to write new e-mail
+processing code with this in mind.  (Change implemented by Anthony
+Baxter.)
+
+\item A new \function{urandom(\var{n})} function was added to the
+\module{os} module, returning a string containing \var{n} bytes of
+random data.  This function provides access to platform-specific
+sources of randomness such as \file{/dev/urandom} on Linux or the
+Windows CryptoAPI.  (Contributed by Trevor Perrin.)
+
+\item Another new function: \function{os.path.lexists(\var{path})} 
+returns true if the file specified by \var{path} exists, whether or
+not it's a symbolic link.  This differs from the existing
+\function{os.path.exists(\var{path})} function, which returns false if 
+\var{path} is a symlink that points to a destination that doesn't exist.
+(Contributed by Beni Cherniavsky.)
+
+\item A new \function{getsid()} function was added to the
+\module{posix} module that underlies the \module{os} module.
+(Contributed by J. Raynor.)
+
+\item The \module{poplib} module now supports POP over SSL.  (Contributed by
+Hector Urtubia.)
+
+\item The \module{profile} module can now profile C extension functions.
+(Contributed by Nick Bastin.)
+
+\item The \module{random} module has a new method called
+   \method{getrandbits(\var{N})} that returns a long integer \var{N}
+   bits in length.  The existing \method{randrange()} method now uses
+   \method{getrandbits()} where appropriate, making generation of
+   arbitrarily large random numbers more efficient.  (Contributed by
+   Raymond Hettinger.)
+
+\item The regular expression language accepted by the \module{re} module
+   was extended with simple conditional expressions, written as
+   \regexp{(?(\var{group})\var{A}|\var{B})}.  \var{group} is either a
+   numeric group ID or a group name defined with \regexp{(?P<group>...)} 
+   earlier in the expression.  If the specified group matched, the
+   regular expression pattern \var{A} will be tested against the string; if
+   the group didn't match, the pattern \var{B} will be used instead.
+   (Contributed by Gustavo Niemeyer.)
+
+\item The \module{re} module is also no longer recursive, thanks to a
+massive amount of work by Gustavo Niemeyer.  In a recursive regular
+expression engine, certain patterns result in a large amount of C
+stack space being consumed, and it was possible to overflow the stack.
+For example, if you matched a 30000-byte string of \samp{a} characters
+against the expression \regexp{(a|b)+}, one stack frame was consumed
+per character.  Python 2.3 tried to check for stack overflow and raise
+a \exception{RuntimeError} exception, but certain patterns could
+sidestep the checking and if you were unlucky Python could segfault.
+Python 2.4's regular expression engine can match this pattern without
+problems.
+
+\item The \module{signal} module now performs tighter error-checking
+on the parameters to the \function{signal.signal()} function.  For
+example, you can't set a handler on the \constant{SIGKILL} signal;
+previous versions of Python would quietly accept this, but 2.4 will
+raise a \exception{RuntimeError} exception.
+
+\item Two new functions were added to the \module{socket} module.
+\function{socketpair()} returns a pair of connected sockets and
+\function{getservbyport(\var{port})} looks up the service name for a
+given port number. (Contributed by Dave Cole and Barry Warsaw.)
+
+\item The \function{sys.exitfunc()} function has been deprecated.  Code
+should be using the existing \module{atexit} module, which correctly
+handles calling multiple exit functions.  Eventually
+\function{sys.exitfunc()} will become a purely internal interface,
+accessed only by \module{atexit}.
+
+\item The \module{tarfile} module now generates GNU-format tar files
+by default.  (Contributed by Lars Gustaebel.)
+
+\item The \module{threading} module now has an elegantly simple way to support 
+thread-local data.  The module contains a \class{local} class whose
+attribute values are local to different threads.
+
+\begin{verbatim}
+import threading
+
+data = threading.local()
+data.number = 42
+data.url = ('www.python.org', 80)
+\end{verbatim}
+
+Other threads can assign and retrieve their own values for the
+\member{number} and \member{url} attributes.  You can subclass
+\class{local} to initialize attributes or to add methods.
+(Contributed by Jim Fulton.)
+
+\item The \module{timeit} module now automatically disables periodic
+  garbage collection during the timing loop.  This change makes
+  consecutive timings more comparable.  (Contributed by Raymond Hettinger.)
+
+\item The \module{weakref} module now supports a wider variety of objects
+   including Python functions, class instances, sets, frozensets, deques,
+   arrays, files, sockets, and regular expression pattern objects.
+   (Contributed by Raymond Hettinger.)
+
+\item The \module{xmlrpclib} module now supports a multi-call extension for 
+transmitting multiple XML-RPC calls in a single HTTP operation.
+(Contributed by Brian Quinlan.)
+
+\item The \module{mpz}, \module{rotor}, and \module{xreadlines} modules have 
+been removed.
+   
+\end{itemize}
+
+
+%======================================================================
+% whole new modules get described in subsections here
+
+%=====================
+\subsection{cookielib}
+
+The \module{cookielib} library supports client-side handling for HTTP
+cookies, mirroring the \module{Cookie} module's server-side cookie
+support. Cookies are stored in cookie jars; the library transparently
+stores cookies offered by the web server in the cookie jar, and
+fetches the cookie from the jar when connecting to the server. As in
+web browsers, policy objects control whether cookies are accepted or
+not.
+
+In order to store cookies across sessions, two implementations of
+cookie jars are provided: one that stores cookies in the Netscape
+format so applications can use the Mozilla or Lynx cookie files, and
+one that stores cookies in the same format as the Perl libwww library.
+
+\module{urllib2} has been changed to interact with \module{cookielib}:
+\class{HTTPCookieProcessor} manages a cookie jar that is used when
+accessing URLs.
+
+This module was contributed by John J. Lee.
+
+
+% ==================
+\subsection{doctest}
+
+The \module{doctest} module underwent considerable refactoring thanks
+to Edward Loper and Tim Peters.  Testing can still be as simple as
+running \function{doctest.testmod()}, but the refactorings allow
+customizing the module's operation in various ways
+
+The new \class{DocTestFinder} class extracts the tests from a given 
+object's docstrings:
+
+\begin{verbatim}
+def f (x, y):
+    """>>> f(2,2)
+4
+>>> f(3,2)
+6
+    """
+    return x*y
+
+finder = doctest.DocTestFinder()
+
+# Get list of DocTest instances
+tests = finder.find(f)
+\end{verbatim}
+
+The new \class{DocTestRunner} class then runs individual tests and can
+produce a summary of the results:
+
+\begin{verbatim}
+runner = doctest.DocTestRunner()
+for t in tests:
+    tried, failed = runner.run(t)
+    
+runner.summarize(verbose=1)
+\end{verbatim}
+
+The above example produces the following output:
+
+\begin{verbatim}
+1 items passed all tests:
+   2 tests in f
+2 tests in 1 items.
+2 passed and 0 failed.
+Test passed.
+\end{verbatim}
+
+\class{DocTestRunner} uses an instance of the \class{OutputChecker}
+class to compare the expected output with the actual output.  This
+class takes a number of different flags that customize its behaviour;
+ambitious users can also write a completely new subclass of
+\class{OutputChecker}.
+
+The default output checker provides a number of handy features.
+For example, with the \constant{doctest.ELLIPSIS} option flag,
+an ellipsis (\samp{...}) in the expected output matches any substring, 
+making it easier to accommodate outputs that vary in minor ways:
+
+\begin{verbatim}
+def o (n):
+    """>>> o(1)
+<__main__.C instance at 0x...>
+>>>
+"""
+\end{verbatim}
+
+Another special string, \samp{<BLANKLINE>}, matches a blank line:
+
+\begin{verbatim}
+def p (n):
+    """>>> p(1)
+<BLANKLINE>
+>>>
+"""
+\end{verbatim}
+
+Another new capability is producing a diff-style display of the output
+by specifying the \constant{doctest.REPORT_UDIFF} (unified diffs),
+\constant{doctest.REPORT_CDIFF} (context diffs), or
+\constant{doctest.REPORT_NDIFF} (delta-style) option flags.  For example:
+
+\begin{verbatim}
+def g (n):
+    """>>> g(4)
+here
+is
+a
+lengthy
+>>>"""
+    L = 'here is a rather lengthy list of words'.split()
+    for word in L[:n]:
+        print word
+\end{verbatim}
+
+Running the above function's tests with
+\constant{doctest.REPORT_UDIFF} specified, you get the following output:
+
+\begin{verbatim}
+**********************************************************************
+File ``t.py'', line 15, in g
+Failed example:
+    g(4)
+Differences (unified diff with -expected +actual):
+    @@ -2,3 +2,3 @@
+     is
+     a
+    -lengthy
+    +rather
+**********************************************************************
+\end{verbatim}
+
+
+% ======================================================================
+\section{Build and C API Changes}
+
+Some of the changes to Python's build process and to the C API are:
+
+\begin{itemize}
+
+  \item Three new convenience macros were added for common return
+  values from extension functions: \csimplemacro{Py_RETURN_NONE},
+  \csimplemacro{Py_RETURN_TRUE}, and \csimplemacro{Py_RETURN_FALSE}.
+  (Contributed by Brett Cannon.)
+
+  \item Another new macro, \csimplemacro{Py_CLEAR(\var{obj})}, 
+  decreases the reference count of \var{obj} and sets \var{obj} to the
+  null pointer.  (Contributed by Jim Fulton.)
+
+  \item A new function, \cfunction{PyTuple_Pack(\var{N}, \var{obj1},
+  \var{obj2}, ..., \var{objN})}, constructs tuples from a variable
+  length argument list of Python objects.  (Contributed by Raymond Hettinger.)
+
+  \item A new function, \cfunction{PyDict_Contains(\var{d}, \var{k})},
+  implements fast dictionary lookups without masking exceptions raised
+  during the look-up process.  (Contributed by Raymond Hettinger.)
+
+  \item The \csimplemacro{Py_IS_NAN(\var{X})} macro returns 1 if 
+  its float or double argument \var{X} is a NaN.  
+  (Contributed by Tim Peters.)
+
+  \item C code can avoid unnecessary locking by using the new
+   \cfunction{PyEval_ThreadsInitialized()} function to tell 
+   if any thread operations have been performed.  If this function 
+   returns false, no lock operations are needed.
+   (Contributed by Nick Coghlan.)
+
+  \item A new function, \cfunction{PyArg_VaParseTupleAndKeywords()},
+  is the same as \cfunction{PyArg_ParseTupleAndKeywords()} but takes a 
+  \ctype{va_list} instead of a number of arguments.
+  (Contributed by Greg Chapman.)
+
+  \item A new method flag, \constant{METH_COEXISTS}, allows a function
+  defined in slots to co-exist with a \ctype{PyCFunction} having the
+  same name.  This can halve the access time for a method such as
+  \method{set.__contains__()}.  (Contributed by Raymond Hettinger.)
+
+  \item Python can now be built with additional profiling for the
+  interpreter itself, intended as an aid to people developing the
+  Python core.  Providing \longprogramopt{--enable-profiling} to the
+  \program{configure} script will let you profile the interpreter with
+  \program{gprof}, and providing the \longprogramopt{--with-tsc}
+  switch enables profiling using the Pentium's Time-Stamp-Counter
+  register.  Note that the \longprogramopt{--with-tsc} switch is slightly
+  misnamed, because the profiling feature also works on the PowerPC
+  platform, though that processor architecture doesn't call that
+  register ``the TSC register''.  (Contributed by Jeremy Hylton.)
+    
+  \item The \ctype{tracebackobject} type has been renamed to \ctype{PyTracebackObject}.
+
+\end{itemize}
+
+
+%======================================================================
+\subsection{Port-Specific Changes}
+
+\begin{itemize}
+
+\item The Windows port now builds under MSVC++ 7.1 as well as version 6.
+  (Contributed by Martin von~L\"owis.)
+
+\end{itemize}
+
+
+
+%======================================================================
+\section{Porting to Python 2.4}
+
+This section lists previously described changes that may require
+changes to your code:
+
+\begin{itemize}
+
+\item Left shifts and hexadecimal/octal constants that are too 
+  large no longer trigger a \exception{FutureWarning} and return 
+  a value limited to 32 or 64 bits; instead they return a long integer.
+
+\item Integer operations will no longer trigger an \exception{OverflowWarning}.
+The \exception{OverflowWarning} warning will disappear in Python 2.5.
+
+\item The \function{zip()} built-in function and \function{itertools.izip()}
+  now return  an empty list instead of raising a \exception{TypeError}
+  exception if called with no arguments.
+
+\item You can no longer compare the \class{date} and \class{datetime}
+  instances provided by the \module{datetime} module.  Two 
+  instances of different classes will now always be unequal, and 
+  relative comparisons (\code{<}, \code{>}) will raise a \exception{TypeError}.
+
+\item \function{dircache.listdir()} now passes exceptions to the caller
+      instead of returning empty lists.
+
+\item \function{LexicalHandler.startDTD()} used to receive the public and
+  system IDs in the wrong order.  This has been corrected; applications
+  relying on the wrong order need to be fixed.
+
+\item \function{fcntl.ioctl} now warns if the \var{mutate} 
+ argument is omitted and relevant.
+
+\item The \module{tarfile} module now generates GNU-format tar files
+by default.
+
+\item Encountering a failure while importing a module no longer leaves
+a partially-initialized module object in \code{sys.modules}.  
+
+\item \constant{None} is now a constant; code that binds a new value to 
+the name \samp{None} is now a syntax error.
+
+\item The \function{signals.signal()} function now raises a
+\exception{RuntimeError} exception for certain illegal values;
+previously these errors would pass silently.  For example, you can no
+longer set a handler on the \constant{SIGKILL} signal.
+
+\end{itemize}
+
+
+%======================================================================
+\section{Acknowledgements \label{acks}}
+
+The author would like to thank the following people for offering
+suggestions, corrections and assistance with various drafts of this
+article: Koray Can, Hye-Shik Chang, Michael Dyck, Raymond Hettinger,
+Brian Hurt, Hamish Lawson, Fredrik Lundh, Sean Reifschneider,
+Sadruddin Rejeb.
+
+\end{document}

Added: vendor/Python/current/Doc/whatsnew/whatsnew25.tex
===================================================================
--- vendor/Python/current/Doc/whatsnew/whatsnew25.tex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Doc/whatsnew/whatsnew25.tex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2530 @@
+\documentclass{howto}
+\usepackage{distutils}
+% $Id: whatsnew25.tex 54622 2007-03-30 17:58:16Z andrew.kuchling $
+
+% Fix XXX comments
+
+\title{What's New in Python 2.5}
+\release{1.01}
+\author{A.M. Kuchling}
+\authoraddress{\email{amk at amk.ca}}
+
+\begin{document}
+\maketitle
+\tableofcontents
+
+This article explains the new features in Python 2.5.  The final
+release of Python 2.5 is scheduled for August 2006;
+\pep{356} describes the planned release schedule.
+
+The changes in Python 2.5 are an interesting mix of language and
+library improvements. The library enhancements will be more important
+to Python's user community, I think, because several widely-useful
+packages were added.  New modules include ElementTree for XML
+processing (section~\ref{module-etree}), the SQLite database module
+(section~\ref{module-sqlite}), and the \module{ctypes} module for
+calling C functions (section~\ref{module-ctypes}).
+
+The language changes are of middling significance.  Some pleasant new
+features were added, but most of them aren't features that you'll use
+every day.  Conditional expressions were finally added to the language
+using a novel syntax; see section~\ref{pep-308}.  The new
+'\keyword{with}' statement will make writing cleanup code easier
+(section~\ref{pep-343}).  Values can now be passed into generators
+(section~\ref{pep-342}).  Imports are now visible as either absolute
+or relative (section~\ref{pep-328}).  Some corner cases of exception
+handling are handled better (section~\ref{pep-341}).  All these
+improvements are worthwhile, but they're improvements to one specific
+language feature or another; none of them are broad modifications to
+Python's semantics.
+
+As well as the language and library additions, other improvements and
+bugfixes were made throughout the source tree.  A search through the
+SVN change logs finds there were 353 patches applied and 458 bugs
+fixed between Python 2.4 and 2.5.  (Both figures are likely to be
+underestimates.)  
+
+This article doesn't try to be a complete specification of the new
+features; instead changes are briefly introduced using helpful
+examples.  For full details, you should always refer to the
+documentation for Python 2.5 at \url{http://docs.python.org}.
+If you want to understand the complete implementation and design
+rationale, refer to the PEP for a particular new feature.
+
+Comments, suggestions, and error reports for this document are
+welcome; please e-mail them to the author or open a bug in the Python
+bug tracker.
+
+%======================================================================
+\section{PEP 308: Conditional Expressions\label{pep-308}}
+
+For a long time, people have been requesting a way to write
+conditional expressions, which are expressions that return value A or
+value B depending on whether a Boolean value is true or false.  A
+conditional expression lets you write a single assignment statement
+that has the same effect as the following:
+
+\begin{verbatim}
+if condition:
+    x = true_value
+else:
+    x = false_value
+\end{verbatim}
+
+There have been endless tedious discussions of syntax on both
+python-dev and comp.lang.python.  A vote was even held that found the
+majority of voters wanted conditional expressions in some form,
+but there was no syntax that was preferred by a clear majority.
+Candidates included C's \code{cond ? true_v : false_v},
+\code{if cond then true_v else false_v}, and 16 other variations.
+
+Guido van~Rossum eventually chose a surprising syntax:
+
+\begin{verbatim}
+x = true_value if condition else false_value
+\end{verbatim}
+
+Evaluation is still lazy as in existing Boolean expressions, so the
+order of evaluation jumps around a bit.  The \var{condition}
+expression in the middle is evaluated first, and the \var{true_value}
+expression is evaluated only if the condition was true.  Similarly,
+the \var{false_value} expression is only evaluated when the condition
+is false.
+
+This syntax may seem strange and backwards; why does the condition go
+in the \emph{middle} of the expression, and not in the front as in C's
+\code{c ? x : y}?  The decision was checked by applying the new syntax
+to the modules in the standard library and seeing how the resulting
+code read.  In many cases where a conditional expression is used, one
+value seems to be the 'common case' and one value is an 'exceptional
+case', used only on rarer occasions when the condition isn't met.  The
+conditional syntax makes this pattern a bit more obvious:
+
+\begin{verbatim}
+contents = ((doc + '\n') if doc else '')
+\end{verbatim}
+
+I read the above statement as meaning ``here \var{contents} is 
+usually assigned a value of \code{doc+'\e n'}; sometimes 
+\var{doc} is empty, in which special case an empty string is returned.''  
+I doubt I will use conditional expressions very often where there 
+isn't a clear common and uncommon case.
+
+There was some discussion of whether the language should require
+surrounding conditional expressions with parentheses.  The decision
+was made to \emph{not} require parentheses in the Python language's
+grammar, but as a matter of style I think you should always use them.
+Consider these two statements:
+
+\begin{verbatim}
+# First version -- no parens
+level = 1 if logging else 0
+
+# Second version -- with parens
+level = (1 if logging else 0)
+\end{verbatim}
+
+In the first version, I think a reader's eye might group the statement
+into 'level = 1', 'if logging', 'else 0', and think that the condition
+decides whether the assignment to \var{level} is performed.  The
+second version reads better, in my opinion, because it makes it clear
+that the assignment is always performed and the choice is being made
+between two values.
+
+Another reason for including the brackets: a few odd combinations of
+list comprehensions and lambdas could look like incorrect conditional
+expressions. See \pep{308} for some examples.  If you put parentheses
+around your conditional expressions, you won't run into this case.
+
+
+\begin{seealso}
+
+\seepep{308}{Conditional Expressions}{PEP written by
+Guido van~Rossum and Raymond D. Hettinger; implemented by Thomas
+Wouters.}
+
+\end{seealso}
+
+
+%======================================================================
+\section{PEP 309: Partial Function Application\label{pep-309}}
+
+The \module{functools} module is intended to contain tools for
+functional-style programming.  
+
+One useful tool in this module is the \function{partial()} function.
+For programs written in a functional style, you'll sometimes want to
+construct variants of existing functions that have some of the
+parameters filled in.  Consider a Python function \code{f(a, b, c)};
+you could create a new function \code{g(b, c)} that was equivalent to
+\code{f(1, b, c)}.  This is called ``partial function application''.
+
+\function{partial} takes the arguments
+\code{(\var{function}, \var{arg1}, \var{arg2}, ...
+\var{kwarg1}=\var{value1}, \var{kwarg2}=\var{value2})}.  The resulting
+object is callable, so you can just call it to invoke \var{function}
+with the filled-in arguments.
+
+Here's a small but realistic example:
+
+\begin{verbatim}
+import functools
+
+def log (message, subsystem):
+    "Write the contents of 'message' to the specified subsystem."
+    print '%s: %s' % (subsystem, message)
+    ...
+
+server_log = functools.partial(log, subsystem='server')
+server_log('Unable to open socket')
+\end{verbatim}
+
+Here's another example, from a program that uses PyGTK.  Here a
+context-sensitive pop-up menu is being constructed dynamically.  The
+callback provided for the menu option is a partially applied version
+of the \method{open_item()} method, where the first argument has been
+provided.
+
+\begin{verbatim}
+...
+class Application:
+    def open_item(self, path):
+       ...
+    def init (self):
+        open_func = functools.partial(self.open_item, item_path)
+        popup_menu.append( ("Open", open_func, 1) )
+\end{verbatim}
+
+
+Another function in the \module{functools} module is the
+\function{update_wrapper(\var{wrapper}, \var{wrapped})} function that
+helps you write well-behaved decorators.  \function{update_wrapper()}
+copies the name, module, and docstring attribute to a wrapper function
+so that tracebacks inside the wrapped function are easier to
+understand.  For example, you might write:
+
+\begin{verbatim}
+def my_decorator(f):
+    def wrapper(*args, **kwds):
+        print 'Calling decorated function'
+        return f(*args, **kwds)
+    functools.update_wrapper(wrapper, f)
+    return wrapper
+\end{verbatim}
+
+\function{wraps()} is a decorator that can be used inside your own
+decorators to copy the wrapped function's information.  An alternate 
+version of the previous example would be:
+
+\begin{verbatim}
+def my_decorator(f):
+    @functools.wraps(f)
+    def wrapper(*args, **kwds):
+        print 'Calling decorated function'
+        return f(*args, **kwds)
+    return wrapper
+\end{verbatim}
+
+\begin{seealso}
+
+\seepep{309}{Partial Function Application}{PEP proposed and written by
+Peter Harris; implemented by Hye-Shik Chang and Nick Coghlan, with
+adaptations by Raymond Hettinger.}
+
+\end{seealso}
+
+
+%======================================================================
+\section{PEP 314: Metadata for Python Software Packages v1.1\label{pep-314}}
+
+Some simple dependency support was added to Distutils.  The
+\function{setup()} function now has \code{requires}, \code{provides},
+and \code{obsoletes} keyword parameters.  When you build a source
+distribution using the \code{sdist} command, the dependency
+information will be recorded in the \file{PKG-INFO} file.
+
+Another new keyword parameter is \code{download_url}, which should be
+set to a URL for the package's source code.  This means it's now
+possible to look up an entry in the package index, determine the
+dependencies for a package, and download the required packages.
+
+\begin{verbatim}
+VERSION = '1.0'
+setup(name='PyPackage', 
+      version=VERSION,
+      requires=['numarray', 'zlib (>=1.1.4)'],
+      obsoletes=['OldPackage']
+      download_url=('http://www.example.com/pypackage/dist/pkg-%s.tar.gz'
+                    % VERSION),
+     )
+\end{verbatim}
+
+Another new enhancement to the Python package index at
+\url{http://cheeseshop.python.org} is storing source and binary
+archives for a package.  The new \command{upload} Distutils command
+will upload a package to the repository.
+
+Before a package can be uploaded, you must be able to build a
+distribution using the \command{sdist} Distutils command.  Once that
+works, you can run \code{python setup.py upload} to add your package
+to the PyPI archive.  Optionally you can GPG-sign the package by
+supplying the \longprogramopt{sign} and
+\longprogramopt{identity} options.
+
+Package uploading was implemented by Martin von~L\"owis and Richard Jones. 
+ 
+\begin{seealso}
+
+\seepep{314}{Metadata for Python Software Packages v1.1}{PEP proposed
+and written by A.M. Kuchling, Richard Jones, and Fred Drake; 
+implemented by Richard Jones and Fred Drake.}
+
+\end{seealso}
+
+
+%======================================================================
+\section{PEP 328: Absolute and Relative Imports\label{pep-328}}
+
+The simpler part of PEP 328 was implemented in Python 2.4: parentheses
+could now be used to enclose the names imported from a module using
+the \code{from ... import ...} statement, making it easier to import
+many different names.
+
+The more complicated part has been implemented in Python 2.5:
+importing a module can be specified to use absolute or
+package-relative imports.  The plan is to move toward making absolute
+imports the default in future versions of Python.
+
+Let's say you have a package directory like this:
+\begin{verbatim}
+pkg/
+pkg/__init__.py
+pkg/main.py
+pkg/string.py
+\end{verbatim}
+
+This defines a package named \module{pkg} containing the
+\module{pkg.main} and \module{pkg.string} submodules.  
+
+Consider the code in the \file{main.py} module.  What happens if it
+executes the statement \code{import string}?  In Python 2.4 and
+earlier, it will first look in the package's directory to perform a
+relative import, finds \file{pkg/string.py}, imports the contents of
+that file as the \module{pkg.string} module, and that module is bound
+to the name \samp{string} in the \module{pkg.main} module's namespace.
+
+That's fine if \module{pkg.string} was what you wanted.  But what if
+you wanted Python's standard \module{string} module?  There's no clean
+way to ignore \module{pkg.string} and look for the standard module;
+generally you had to look at the contents of \code{sys.modules}, which
+is slightly unclean.   
+Holger Krekel's \module{py.std} package provides a tidier way to perform
+imports from the standard library, \code{import py ; py.std.string.join()},
+but that package isn't available on all Python installations.
+
+Reading code which relies on relative imports is also less clear,
+because a reader may be confused about which module, \module{string}
+or \module{pkg.string}, is intended to be used.  Python users soon
+learned not to duplicate the names of standard library modules in the
+names of their packages' submodules, but you can't protect against
+having your submodule's name being used for a new module added in a
+future version of Python.
+
+In Python 2.5, you can switch \keyword{import}'s behaviour to 
+absolute imports using a \code{from __future__ import absolute_import}
+directive.  This absolute-import behaviour will become the default in
+a future version (probably Python 2.7).  Once absolute imports 
+are the default, \code{import string} will
+always find the standard library's version.
+It's suggested that users should begin using absolute imports as much
+as possible, so it's preferable to begin writing \code{from pkg import
+string} in your code.  
+
+Relative imports are still possible by adding a leading period 
+to the module name when using the \code{from ... import} form:
+
+\begin{verbatim}
+# Import names from pkg.string
+from .string import name1, name2
+# Import pkg.string
+from . import string
+\end{verbatim}
+
+This imports the \module{string} module relative to the current
+package, so in \module{pkg.main} this will import \var{name1} and
+\var{name2} from \module{pkg.string}.  Additional leading periods
+perform the relative import starting from the parent of the current
+package.  For example, code in the \module{A.B.C} module can do:
+
+\begin{verbatim}
+from . import D                 # Imports A.B.D
+from .. import E                # Imports A.E
+from ..F import G               # Imports A.F.G
+\end{verbatim}
+
+Leading periods cannot be used with the \code{import \var{modname}} 
+form of the import statement, only the \code{from ... import} form.
+
+\begin{seealso}
+
+\seepep{328}{Imports: Multi-Line and Absolute/Relative}
+{PEP written by Aahz; implemented by Thomas Wouters.}
+
+\seeurl{http://codespeak.net/py/current/doc/index.html}
+{The py library by Holger Krekel, which contains the \module{py.std} package.}
+
+\end{seealso}
+
+
+%======================================================================
+\section{PEP 338: Executing Modules as Scripts\label{pep-338}}
+
+The \programopt{-m} switch added in Python 2.4 to execute a module as
+a script gained a few more abilities.  Instead of being implemented in
+C code inside the Python interpreter, the switch now uses an
+implementation in a new module, \module{runpy}.
+
+The \module{runpy} module implements a more sophisticated import
+mechanism so that it's now possible to run modules in a package such
+as \module{pychecker.checker}.  The module also supports alternative
+import mechanisms such as the \module{zipimport} module.  This means
+you can add a .zip archive's path to \code{sys.path} and then use the
+\programopt{-m} switch to execute code from the archive.
+
+
+\begin{seealso}
+
+\seepep{338}{Executing modules as scripts}{PEP written and 
+implemented by Nick Coghlan.}
+
+\end{seealso}
+
+
+%======================================================================
+\section{PEP 341: Unified try/except/finally\label{pep-341}}
+
+Until Python 2.5, the \keyword{try} statement came in two
+flavours. You could use a \keyword{finally} block to ensure that code
+is always executed, or one or more \keyword{except} blocks to catch 
+specific exceptions.  You couldn't combine both \keyword{except} blocks and a
+\keyword{finally} block, because generating the right bytecode for the
+combined version was complicated and it wasn't clear what the
+semantics of the combined statement should be.  
+
+Guido van~Rossum spent some time working with Java, which does support the
+equivalent of combining \keyword{except} blocks and a
+\keyword{finally} block, and this clarified what the statement should
+mean.  In Python 2.5, you can now write:
+
+\begin{verbatim}
+try:
+    block-1 ...
+except Exception1:
+    handler-1 ...
+except Exception2:
+    handler-2 ...
+else:
+    else-block
+finally:
+    final-block 
+\end{verbatim}
+
+The code in \var{block-1} is executed.  If the code raises an
+exception, the various \keyword{except} blocks are tested: if the
+exception is of class \class{Exception1}, \var{handler-1} is executed;
+otherwise if it's of class \class{Exception2}, \var{handler-2} is
+executed, and so forth.  If no exception is raised, the
+\var{else-block} is executed.  
+
+No matter what happened previously, the \var{final-block} is executed
+once the code block is complete and any raised exceptions handled.
+Even if there's an error in an exception handler or the
+\var{else-block} and a new exception is raised, the
+code in the \var{final-block} is still run.
+
+\begin{seealso}
+
+\seepep{341}{Unifying try-except and try-finally}{PEP written by Georg Brandl; 
+implementation by Thomas Lee.}
+
+\end{seealso}
+
+
+%======================================================================
+\section{PEP 342: New Generator Features\label{pep-342}}
+
+Python 2.5 adds a simple way to pass values \emph{into} a generator.
+As introduced in Python 2.3, generators only produce output; once a
+generator's code was invoked to create an iterator, there was no way to
+pass any new information into the function when its execution is
+resumed.  Sometimes the ability to pass in some information would be
+useful.  Hackish solutions to this include making the generator's code
+look at a global variable and then changing the global variable's
+value, or passing in some mutable object that callers then modify.
+
+To refresh your memory of basic generators, here's a simple example:
+
+\begin{verbatim}
+def counter (maximum):
+    i = 0
+    while i < maximum:
+        yield i
+        i += 1
+\end{verbatim}
+
+When you call \code{counter(10)}, the result is an iterator that
+returns the values from 0 up to 9.  On encountering the
+\keyword{yield} statement, the iterator returns the provided value and
+suspends the function's execution, preserving the local variables.
+Execution resumes on the following call to the iterator's 
+\method{next()} method, picking up after the \keyword{yield} statement.
+
+In Python 2.3, \keyword{yield} was a statement; it didn't return any
+value.  In 2.5, \keyword{yield} is now an expression, returning a
+value that can be assigned to a variable or otherwise operated on:
+
+\begin{verbatim}
+val = (yield i)
+\end{verbatim}
+
+I recommend that you always put parentheses around a \keyword{yield}
+expression when you're doing something with the returned value, as in
+the above example.  The parentheses aren't always necessary, but it's
+easier to always add them instead of having to remember when they're
+needed.
+
+(\pep{342} explains the exact rules, which are that a
+\keyword{yield}-expression must always be parenthesized except when it
+occurs at the top-level expression on the right-hand side of an
+assignment.  This means you can write \code{val = yield i} but have to
+use parentheses when there's an operation, as in \code{val = (yield i)
++ 12}.)
+
+Values are sent into a generator by calling its
+\method{send(\var{value})} method.  The generator's code is then
+resumed and the \keyword{yield} expression returns the specified
+\var{value}.  If the regular \method{next()} method is called, the
+\keyword{yield} returns \constant{None}.
+
+Here's the previous example, modified to allow changing the value of
+the internal counter.
+
+\begin{verbatim}
+def counter (maximum):
+    i = 0
+    while i < maximum:
+        val = (yield i)
+        # If value provided, change counter
+        if val is not None:
+            i = val
+        else:
+            i += 1
+\end{verbatim}
+
+And here's an example of changing the counter:
+
+\begin{verbatim}
+>>> it = counter(10)
+>>> print it.next()
+0
+>>> print it.next()
+1
+>>> print it.send(8)
+8
+>>> print it.next()
+9
+>>> print it.next()
+Traceback (most recent call last):
+  File ``t.py'', line 15, in ?
+    print it.next()
+StopIteration
+\end{verbatim}
+
+\keyword{yield} will usually return \constant{None}, so you
+should always check for this case.  Don't just use its value in
+expressions unless you're sure that the \method{send()} method
+will be the only method used to resume your generator function.
+
+In addition to \method{send()}, there are two other new methods on
+generators:
+
+\begin{itemize}
+
+  \item \method{throw(\var{type}, \var{value}=None,
+  \var{traceback}=None)} is used to raise an exception inside the
+  generator; the exception is raised by the \keyword{yield} expression
+  where the generator's execution is paused.
+
+  \item \method{close()} raises a new \exception{GeneratorExit}
+  exception inside the generator to terminate the iteration.  On
+  receiving this exception, the generator's code must either raise
+  \exception{GeneratorExit} or \exception{StopIteration}.  Catching
+  the \exception{GeneratorExit} exception and returning a value is
+  illegal and will trigger a \exception{RuntimeError}; if the function
+  raises some other exception, that exception is propagated to the
+  caller.  \method{close()} will also be called by Python's garbage
+  collector when the generator is garbage-collected.
+
+  If you need to run cleanup code when a \exception{GeneratorExit} occurs,
+  I suggest using a \code{try: ... finally:} suite instead of 
+  catching \exception{GeneratorExit}.
+
+\end{itemize}
+
+The cumulative effect of these changes is to turn generators from
+one-way producers of information into both producers and consumers.
+
+Generators also become \emph{coroutines}, a more generalized form of
+subroutines.  Subroutines are entered at one point and exited at
+another point (the top of the function, and a \keyword{return}
+statement), but coroutines can be entered, exited, and resumed at
+many different points (the \keyword{yield} statements).  We'll have to
+figure out patterns for using coroutines effectively in Python.
+
+The addition of the \method{close()} method has one side effect that
+isn't obvious.  \method{close()} is called when a generator is
+garbage-collected, so this means the generator's code gets one last
+chance to run before the generator is destroyed.  This last chance
+means that \code{try...finally} statements in generators can now be
+guaranteed to work; the \keyword{finally} clause will now always get a
+chance to run.  The syntactic restriction that you couldn't mix
+\keyword{yield} statements with a \code{try...finally} suite has
+therefore been removed.  This seems like a minor bit of language
+trivia, but using generators and \code{try...finally} is actually
+necessary in order to implement the  \keyword{with} statement
+described by PEP 343.  I'll look at this new statement in the following 
+section.
+
+Another even more esoteric effect of this change: previously, the
+\member{gi_frame} attribute of a generator was always a frame object.
+It's now possible for \member{gi_frame} to be \code{None}
+once the generator has been exhausted.
+
+\begin{seealso}
+
+\seepep{342}{Coroutines via Enhanced Generators}{PEP written by 
+Guido van~Rossum and Phillip J. Eby;
+implemented by Phillip J. Eby.  Includes examples of 
+some fancier uses of generators as coroutines.
+
+Earlier versions of these features were proposed in 
+\pep{288} by Raymond Hettinger and \pep{325} by Samuele Pedroni.
+}
+
+\seeurl{http://en.wikipedia.org/wiki/Coroutine}{The Wikipedia entry for 
+coroutines.}
+
+\seeurl{http://www.sidhe.org/\~{}dan/blog/archives/000178.html}{An
+explanation of coroutines from a Perl point of view, written by Dan
+Sugalski.}
+
+\end{seealso}
+
+
+%======================================================================
+\section{PEP 343: The 'with' statement\label{pep-343}}
+
+The '\keyword{with}' statement clarifies code that previously would
+use \code{try...finally} blocks to ensure that clean-up code is
+executed.  In this section, I'll discuss the statement as it will
+commonly be used.  In the next section, I'll examine the
+implementation details and show how to write objects for use with this
+statement.
+
+The '\keyword{with}' statement is a new control-flow structure whose
+basic structure is:
+
+\begin{verbatim}
+with expression [as variable]:
+    with-block
+\end{verbatim}
+
+The expression is evaluated, and it should result in an object that
+supports the context management protocol.  This object may return a
+value that can optionally be bound to the name \var{variable}.  (Note
+carefully that \var{variable} is \emph{not} assigned the result of
+\var{expression}.)  The object can then run set-up code
+before \var{with-block} is executed and some clean-up code
+is executed after the block is done, even if the block raised an exception.
+
+To enable the statement in Python 2.5, you need 
+to add the following directive to your module:
+
+\begin{verbatim}
+from __future__ import with_statement
+\end{verbatim}
+
+The statement will always be enabled in Python 2.6.
+
+Some standard Python objects now support the context management
+protocol and can be used with the '\keyword{with}' statement. File
+objects are one example:
+
+\begin{verbatim}
+with open('/etc/passwd', 'r') as f:
+    for line in f:
+        print line
+        ... more processing code ...
+\end{verbatim}
+
+After this statement has executed, the file object in \var{f} will
+have been automatically closed, even if the 'for' loop
+raised an exception part-way through the block.
+
+The \module{threading} module's locks and condition variables 
+also support the '\keyword{with}' statement:
+
+\begin{verbatim}
+lock = threading.Lock()
+with lock:
+    # Critical section of code
+    ...
+\end{verbatim}
+
+The lock is acquired before the block is executed and always released once 
+the block is complete.
+
+The new \function{localcontext()} function in the \module{decimal} module
+makes it easy to save and restore the current decimal context, which
+encapsulates the desired precision and rounding characteristics for
+computations:
+
+\begin{verbatim}
+from decimal import Decimal, Context, localcontext
+
+# Displays with default precision of 28 digits
+v = Decimal('578')
+print v.sqrt()
+
+with localcontext(Context(prec=16)):
+    # All code in this block uses a precision of 16 digits.
+    # The original context is restored on exiting the block.
+    print v.sqrt()
+\end{verbatim}
+
+\subsection{Writing Context Managers\label{context-managers}}
+
+Under the hood, the '\keyword{with}' statement is fairly complicated.
+Most people will only use '\keyword{with}' in company with existing
+objects and don't need to know these details, so you can skip the rest
+of this section if you like.  Authors of new objects will need to
+understand the details of the underlying implementation and should
+keep reading.
+
+A high-level explanation of the context management protocol is:
+
+\begin{itemize}
+
+\item The expression is evaluated and should result in an object
+called a ``context manager''.  The context manager must have
+\method{__enter__()} and \method{__exit__()} methods.
+
+\item The context manager's \method{__enter__()} method is called.  The value
+returned is assigned to \var{VAR}.  If no \code{'as \var{VAR}'} clause
+is present, the value is simply discarded.
+
+\item The code in \var{BLOCK} is executed.
+
+\item If \var{BLOCK} raises an exception, the
+\method{__exit__(\var{type}, \var{value}, \var{traceback})} is called
+with the exception details, the same values returned by
+\function{sys.exc_info()}.  The method's return value controls whether
+the exception is re-raised: any false value re-raises the exception,
+and \code{True} will result in suppressing it.  You'll only rarely
+want to suppress the exception, because if you do
+the author of the code containing the
+'\keyword{with}' statement will never realize anything went wrong.
+
+\item If \var{BLOCK} didn't raise an exception, 
+the \method{__exit__()} method is still called,
+but \var{type}, \var{value}, and \var{traceback} are all \code{None}.
+
+\end{itemize}
+
+Let's think through an example.  I won't present detailed code but
+will only sketch the methods necessary for a database that supports
+transactions.
+
+(For people unfamiliar with database terminology: a set of changes to
+the database are grouped into a transaction.  Transactions can be
+either committed, meaning that all the changes are written into the
+database, or rolled back, meaning that the changes are all discarded
+and the database is unchanged.  See any database textbook for more
+information.)
+
+Let's assume there's an object representing a database connection.
+Our goal will be to let the user write code like this:
+
+\begin{verbatim}
+db_connection = DatabaseConnection()
+with db_connection as cursor:
+    cursor.execute('insert into ...')
+    cursor.execute('delete from ...')
+    # ... more operations ...
+\end{verbatim}
+
+The transaction should be committed if the code in the block
+runs flawlessly or rolled back if there's an exception.
+Here's the basic interface
+for \class{DatabaseConnection} that I'll assume:
+
+\begin{verbatim}
+class DatabaseConnection:
+    # Database interface
+    def cursor (self):
+        "Returns a cursor object and starts a new transaction"
+    def commit (self):
+        "Commits current transaction"
+    def rollback (self):
+        "Rolls back current transaction"
+\end{verbatim}
+
+The \method {__enter__()} method is pretty easy, having only to start
+a new transaction.  For this application the resulting cursor object
+would be a useful result, so the method will return it.  The user can
+then add \code{as cursor} to their '\keyword{with}' statement to bind
+the cursor to a variable name.
+
+\begin{verbatim}
+class DatabaseConnection:
+    ...
+    def __enter__ (self):
+        # Code to start a new transaction
+        cursor = self.cursor()
+        return cursor
+\end{verbatim}
+
+The \method{__exit__()} method is the most complicated because it's
+where most of the work has to be done.  The method has to check if an
+exception occurred.  If there was no exception, the transaction is
+committed.  The transaction is rolled back if there was an exception.
+
+In the code below, execution will just fall off the end of the
+function, returning the default value of \code{None}.  \code{None} is
+false, so the exception will be re-raised automatically.  If you
+wished, you could be more explicit and add a \keyword{return}
+statement at the marked location.
+
+\begin{verbatim}
+class DatabaseConnection:
+    ...
+    def __exit__ (self, type, value, tb):
+        if tb is None:
+            # No exception, so commit
+            self.commit()
+        else:
+            # Exception occurred, so rollback.
+            self.rollback()
+            # return False
+\end{verbatim}
+
+
+\subsection{The contextlib module\label{module-contextlib}}
+
+The new \module{contextlib} module provides some functions and a
+decorator that are useful for writing objects for use with the
+'\keyword{with}' statement.
+
+The decorator is called \function{contextmanager}, and lets you write
+a single generator function instead of defining a new class.  The generator
+should yield exactly one value.  The code up to the \keyword{yield}
+will be executed as the \method{__enter__()} method, and the value
+yielded will be the method's return value that will get bound to the
+variable in the '\keyword{with}' statement's \keyword{as} clause, if
+any.  The code after the \keyword{yield} will be executed in the
+\method{__exit__()} method.  Any exception raised in the block will be
+raised by the \keyword{yield} statement.
+
+Our database example from the previous section could be written 
+using this decorator as:
+
+\begin{verbatim}
+from contextlib import contextmanager
+
+ at contextmanager
+def db_transaction (connection):
+    cursor = connection.cursor()
+    try:
+        yield cursor
+    except:
+        connection.rollback()
+        raise
+    else:
+        connection.commit()
+
+db = DatabaseConnection()
+with db_transaction(db) as cursor:
+    ...
+\end{verbatim}
+
+The \module{contextlib} module also has a \function{nested(\var{mgr1},
+\var{mgr2}, ...)} function that combines a number of context managers so you
+don't need to write nested '\keyword{with}' statements.  In this
+example, the single '\keyword{with}' statement both starts a database
+transaction and acquires a thread lock:
+
+\begin{verbatim}
+lock = threading.Lock()
+with nested (db_transaction(db), lock) as (cursor, locked):
+    ...
+\end{verbatim}
+
+Finally, the \function{closing(\var{object})} function
+returns \var{object} so that it can be bound to a variable,
+and calls \code{\var{object}.close()} at the end of the block.
+
+\begin{verbatim}
+import urllib, sys
+from contextlib import closing
+
+with closing(urllib.urlopen('http://www.yahoo.com')) as f:
+    for line in f:
+        sys.stdout.write(line)
+\end{verbatim}
+
+\begin{seealso}
+
+\seepep{343}{The ``with'' statement}{PEP written by Guido van~Rossum
+and Nick Coghlan; implemented by Mike Bland, Guido van~Rossum, and
+Neal Norwitz.  The PEP shows the code generated for a '\keyword{with}'
+statement, which can be helpful in learning how the statement works.}
+
+\seeurl{../lib/module-contextlib.html}{The documentation 
+for the \module{contextlib} module.}
+
+\end{seealso}
+
+
+%======================================================================
+\section{PEP 352: Exceptions as New-Style Classes\label{pep-352}}
+
+Exception classes can now be new-style classes, not just classic
+classes, and the built-in \exception{Exception} class and all the
+standard built-in exceptions (\exception{NameError},
+\exception{ValueError}, etc.) are now new-style classes.
+
+The inheritance hierarchy for exceptions has been rearranged a bit.
+In 2.5, the inheritance relationships are:
+
+\begin{verbatim}
+BaseException       # New in Python 2.5
+|- KeyboardInterrupt
+|- SystemExit
+|- Exception
+   |- (all other current built-in exceptions)
+\end{verbatim}
+
+This rearrangement was done because people often want to catch all
+exceptions that indicate program errors.  \exception{KeyboardInterrupt} and
+\exception{SystemExit} aren't errors, though, and usually represent an explicit
+action such as the user hitting Control-C or code calling
+\function{sys.exit()}.  A bare \code{except:} will catch all exceptions,
+so you commonly need to list \exception{KeyboardInterrupt} and
+\exception{SystemExit} in order to re-raise them.  The usual pattern is:
+
+\begin{verbatim}
+try:
+    ...
+except (KeyboardInterrupt, SystemExit):
+    raise
+except: 
+    # Log error...  
+    # Continue running program...
+\end{verbatim}
+
+In Python 2.5, you can now write \code{except Exception} to achieve
+the same result, catching all the exceptions that usually indicate errors 
+but leaving \exception{KeyboardInterrupt} and
+\exception{SystemExit} alone.  As in previous versions,
+a bare \code{except:} still catches all exceptions.
+
+The goal for Python 3.0 is to require any class raised as an exception
+to derive from \exception{BaseException} or some descendant of
+\exception{BaseException}, and future releases in the
+Python 2.x series may begin to enforce this constraint.  Therefore, I
+suggest you begin making all your exception classes derive from
+\exception{Exception} now.  It's been suggested that the bare
+\code{except:} form should be removed in Python 3.0, but Guido van~Rossum
+hasn't decided whether to do this or not.
+
+Raising of strings as exceptions, as in the statement \code{raise
+"Error occurred"}, is deprecated in Python 2.5 and will trigger a
+warning.  The aim is to be able to remove the string-exception feature
+in a few releases.
+
+
+\begin{seealso}
+
+\seepep{352}{Required Superclass for Exceptions}{PEP written by 
+Brett Cannon and Guido van~Rossum; implemented by Brett Cannon.}
+
+\end{seealso}
+
+
+%======================================================================
+\section{PEP 353: Using ssize_t as the index type\label{pep-353}}
+
+A wide-ranging change to Python's C API, using a new 
+\ctype{Py_ssize_t} type definition instead of \ctype{int}, 
+will permit the interpreter to handle more data on 64-bit platforms.
+This change doesn't affect Python's capacity on 32-bit platforms.
+
+Various pieces of the Python interpreter used C's \ctype{int} type to
+store sizes or counts; for example, the number of items in a list or
+tuple were stored in an \ctype{int}.  The C compilers for most 64-bit
+platforms still define \ctype{int} as a 32-bit type, so that meant
+that lists could only hold up to \code{2**31 - 1} = 2147483647 items.
+(There are actually a few different programming models that 64-bit C
+compilers can use -- see
+\url{http://www.unix.org/version2/whatsnew/lp64_wp.html} for a
+discussion -- but the most commonly available model leaves \ctype{int}
+as 32 bits.)
+
+A limit of 2147483647 items doesn't really matter on a 32-bit platform
+because you'll run out of memory before hitting the length limit.
+Each list item requires space for a pointer, which is 4 bytes, plus
+space for a \ctype{PyObject} representing the item.  2147483647*4 is
+already more bytes than a 32-bit address space can contain.
+
+It's possible to address that much memory on a 64-bit platform,
+however.  The pointers for a list that size would only require 16~GiB
+of space, so it's not unreasonable that Python programmers might
+construct lists that large.  Therefore, the Python interpreter had to
+be changed to use some type other than \ctype{int}, and this will be a
+64-bit type on 64-bit platforms.  The change will cause
+incompatibilities on 64-bit machines, so it was deemed worth making
+the transition now, while the number of 64-bit users is still
+relatively small.  (In 5 or 10 years, we may \emph{all} be on 64-bit
+machines, and the transition would be more painful then.)
+
+This change most strongly affects authors of C extension modules.  
+Python strings and container types such as lists and tuples 
+now use \ctype{Py_ssize_t} to store their size.  
+Functions such as \cfunction{PyList_Size()} 
+now return \ctype{Py_ssize_t}.  Code in extension modules
+may therefore need to have some variables changed to
+\ctype{Py_ssize_t}.  
+
+The \cfunction{PyArg_ParseTuple()} and \cfunction{Py_BuildValue()} functions
+have a new conversion code, \samp{n}, for \ctype{Py_ssize_t}.  
+\cfunction{PyArg_ParseTuple()}'s \samp{s\#} and \samp{t\#} still output
+\ctype{int} by default, but you can define the macro 
+\csimplemacro{PY_SSIZE_T_CLEAN} before including \file{Python.h} 
+to make them return \ctype{Py_ssize_t}.
+
+\pep{353} has a section on conversion guidelines that 
+extension authors should read to learn about supporting 64-bit
+platforms.
+
+\begin{seealso}
+
+\seepep{353}{Using ssize_t as the index type}{PEP written and implemented by Martin von~L\"owis.}
+
+\end{seealso}
+
+
+%======================================================================
+\section{PEP 357: The '__index__' method\label{pep-357}}
+
+The NumPy developers had a problem that could only be solved by adding
+a new special method, \method{__index__}.  When using slice notation,
+as in \code{[\var{start}:\var{stop}:\var{step}]}, the values of the
+\var{start}, \var{stop}, and \var{step} indexes must all be either
+integers or long integers.  NumPy defines a variety of specialized
+integer types corresponding to unsigned and signed integers of 8, 16,
+32, and 64 bits, but there was no way to signal that these types could
+be used as slice indexes.
+
+Slicing can't just use the existing \method{__int__} method because
+that method is also used to implement coercion to integers.  If
+slicing used \method{__int__}, floating-point numbers would also
+become legal slice indexes and that's clearly an undesirable
+behaviour.
+
+Instead, a new special method called \method{__index__} was added.  It
+takes no arguments and returns an integer giving the slice index to
+use.  For example:
+
+\begin{verbatim}
+class C:
+    def __index__ (self):
+        return self.value  
+\end{verbatim}
+
+The return value must be either a Python integer or long integer.
+The interpreter will check that the type returned is correct, and
+raises a \exception{TypeError} if this requirement isn't met.
+
+A corresponding \member{nb_index} slot was added to the C-level
+\ctype{PyNumberMethods} structure to let C extensions implement this
+protocol.  \cfunction{PyNumber_Index(\var{obj})} can be used in
+extension code to call the \method{__index__} function and retrieve
+its result.
+
+\begin{seealso}
+
+\seepep{357}{Allowing Any Object to be Used for Slicing}{PEP written 
+and implemented by Travis Oliphant.}
+
+\end{seealso}
+
+
+%======================================================================
+\section{Other Language Changes\label{other-lang}}
+
+Here are all of the changes that Python 2.5 makes to the core Python
+language.
+
+\begin{itemize}
+
+\item The \class{dict} type has a new hook for letting subclasses
+provide a default value when a key isn't contained in the dictionary.
+When a key isn't found, the dictionary's
+\method{__missing__(\var{key})}
+method will be called.  This hook is used to implement
+the new \class{defaultdict} class in the \module{collections}
+module.  The following example defines a dictionary 
+that returns zero for any missing key:
+
+\begin{verbatim}
+class zerodict (dict):
+    def __missing__ (self, key):
+        return 0
+
+d = zerodict({1:1, 2:2})
+print d[1], d[2]   # Prints 1, 2
+print d[3], d[4]   # Prints 0, 0
+\end{verbatim}
+
+\item Both 8-bit and Unicode strings have new \method{partition(sep)} 
+and \method{rpartition(sep)} methods that simplify a common use case.
+
+The \method{find(S)} method is often used to get an index which is
+then used to slice the string and obtain the pieces that are before
+and after the separator.  
+\method{partition(sep)} condenses this
+pattern into a single method call that returns a 3-tuple containing
+the substring before the separator, the separator itself, and the
+substring after the separator.  If the separator isn't found, the
+first element of the tuple is the entire string and the other two
+elements are empty.  \method{rpartition(sep)} also returns a 3-tuple
+but starts searching from the end of the string; the \samp{r} stands
+for 'reverse'.
+
+Some examples:
+
+\begin{verbatim}
+>>> ('http://www.python.org').partition('://')
+('http', '://', 'www.python.org')
+>>> ('file:/usr/share/doc/index.html').partition('://')
+('file:/usr/share/doc/index.html', '', '')
+>>> (u'Subject: a quick question').partition(':')
+(u'Subject', u':', u' a quick question')
+>>> 'www.python.org'.rpartition('.')
+('www.python', '.', 'org')
+>>> 'www.python.org'.rpartition(':')
+('', '', 'www.python.org')
+\end{verbatim}
+
+(Implemented by Fredrik Lundh following a suggestion by Raymond Hettinger.)
+
+\item The \method{startswith()} and \method{endswith()} methods
+of string types now accept tuples of strings to check for.
+
+\begin{verbatim}
+def is_image_file (filename):
+    return filename.endswith(('.gif', '.jpg', '.tiff'))
+\end{verbatim}
+
+(Implemented by Georg Brandl following a suggestion by Tom Lynn.)
+% RFE #1491485
+
+\item The \function{min()} and \function{max()} built-in functions
+gained a \code{key} keyword parameter analogous to the \code{key}
+argument for \method{sort()}.  This parameter supplies a function that
+takes a single argument and is called for every value in the list;
+\function{min()}/\function{max()} will return the element with the 
+smallest/largest return value from this function.
+For example, to find the longest string in a list, you can do:
+
+\begin{verbatim}
+L = ['medium', 'longest', 'short']
+# Prints 'longest'
+print max(L, key=len)              
+# Prints 'short', because lexicographically 'short' has the largest value
+print max(L)         
+\end{verbatim}
+
+(Contributed by Steven Bethard and Raymond Hettinger.)
+
+\item Two new built-in functions, \function{any()} and
+\function{all()}, evaluate whether an iterator contains any true or
+false values.  \function{any()} returns \constant{True} if any value
+returned by the iterator is true; otherwise it will return
+\constant{False}.  \function{all()} returns \constant{True} only if
+all of the values returned by the iterator evaluate as true.
+(Suggested by Guido van~Rossum, and implemented by Raymond Hettinger.)
+
+\item The result of a class's \method{__hash__()} method can now 
+be either a long integer or a regular integer.  If a long integer is
+returned, the hash of that value is taken.  In earlier versions the
+hash value was required to be a regular integer, but in 2.5 the
+\function{id()} built-in was changed to always return non-negative
+numbers, and users often seem to use \code{id(self)} in
+\method{__hash__()} methods (though this is discouraged).
+% Bug #1536021
+
+\item ASCII is now the default encoding for modules.  It's now 
+a syntax error if a module contains string literals with 8-bit
+characters but doesn't have an encoding declaration.  In Python 2.4
+this triggered a warning, not a syntax error.  See \pep{263} 
+for how to declare a module's encoding; for example, you might add 
+a line like this near the top of the source file:
+
+\begin{verbatim}
+# -*- coding: latin1 -*-
+\end{verbatim}
+
+\item A new warning, \class{UnicodeWarning}, is triggered when 
+you attempt to compare a Unicode string and an 8-bit string 
+that can't be converted to Unicode using the default ASCII encoding.  
+The result of the comparison is false:
+
+\begin{verbatim}
+>>> chr(128) == unichr(128)   # Can't convert chr(128) to Unicode
+__main__:1: UnicodeWarning: Unicode equal comparison failed 
+  to convert both arguments to Unicode - interpreting them 
+  as being unequal
+False
+>>> chr(127) == unichr(127)   # chr(127) can be converted
+True
+\end{verbatim}
+
+Previously this would raise a \class{UnicodeDecodeError} exception,
+but in 2.5 this could result in puzzling problems when accessing a
+dictionary.  If you looked up \code{unichr(128)} and \code{chr(128)}
+was being used as a key, you'd get a \class{UnicodeDecodeError}
+exception.  Other changes in 2.5 resulted in this exception being
+raised instead of suppressed by the code in \file{dictobject.c} that
+implements dictionaries.
+
+Raising an exception for such a comparison is strictly correct, but
+the change might have broken code, so instead 
+\class{UnicodeWarning} was introduced.
+
+(Implemented by Marc-Andr\'e Lemburg.)
+
+\item One error that Python programmers sometimes make is forgetting
+to include an \file{__init__.py} module in a package directory.
+Debugging this mistake can be confusing, and usually requires running
+Python with the \programopt{-v} switch to log all the paths searched.
+In Python 2.5, a new \exception{ImportWarning} warning is triggered when
+an import would have picked up a directory as a package but no
+\file{__init__.py} was found.  This warning is silently ignored by default;
+provide the \programopt{-Wd} option when running the Python executable
+to display the warning message.
+(Implemented by Thomas Wouters.)
+
+\item The list of base classes in a class definition can now be empty.  
+As an example, this is now legal:
+
+\begin{verbatim}
+class C():
+    pass
+\end{verbatim}
+(Implemented by Brett Cannon.)
+
+\end{itemize}
+
+
+%======================================================================
+\subsection{Interactive Interpreter Changes\label{interactive}}
+
+In the interactive interpreter, \code{quit} and \code{exit} 
+have long been strings so that new users get a somewhat helpful message
+when they try to quit:
+
+\begin{verbatim}
+>>> quit
+'Use Ctrl-D (i.e. EOF) to exit.'
+\end{verbatim}
+
+In Python 2.5, \code{quit} and \code{exit} are now objects that still
+produce string representations of themselves, but are also callable.
+Newbies who try \code{quit()} or \code{exit()} will now exit the
+interpreter as they expect.  (Implemented by Georg Brandl.)
+
+The Python executable now accepts the standard long options 
+\longprogramopt{help} and \longprogramopt{version}; on Windows, 
+it also accepts the \programopt{/?} option for displaying a help message.
+(Implemented by Georg Brandl.)
+
+
+%======================================================================
+\subsection{Optimizations\label{opts}}
+
+Several of the optimizations were developed at the NeedForSpeed
+sprint, an event held in Reykjavik, Iceland, from May 21--28 2006.
+The sprint focused on speed enhancements to the CPython implementation
+and was funded by EWT LLC with local support from CCP Games.  Those
+optimizations added at this sprint are specially marked in the
+following list.
+
+\begin{itemize}
+
+\item When they were introduced 
+in Python 2.4, the built-in \class{set} and \class{frozenset} types
+were built on top of Python's dictionary type.  
+In 2.5 the internal data structure has been customized for implementing sets,
+and as a result sets will use a third less memory and are somewhat faster.
+(Implemented by Raymond Hettinger.)
+
+\item The speed of some Unicode operations, such as finding
+substrings, string splitting, and character map encoding and decoding,
+has been improved.  (Substring search and splitting improvements were
+added by Fredrik Lundh and Andrew Dalke at the NeedForSpeed
+sprint. Character maps were improved by Walter D\"orwald and
+Martin von~L\"owis.)
+% Patch 1313939, 1359618 
+
+\item The \function{long(\var{str}, \var{base})} function is now
+faster on long digit strings because fewer intermediate results are
+calculated.  The peak is for strings of around 800--1000 digits where 
+the function is 6 times faster.
+(Contributed by Alan McIntyre and committed at the NeedForSpeed sprint.)
+% Patch 1442927
+
+\item It's now illegal to mix iterating over a file 
+with \code{for line in \var{file}} and calling 
+the file object's \method{read()}/\method{readline()}/\method{readlines()}
+methods.  Iteration uses an internal buffer and the 
+\method{read*()} methods don't use that buffer.  
+Instead they would return the data following the buffer, causing the
+data to appear out of order.  Mixing iteration and these methods will
+now trigger a \exception{ValueError} from the \method{read*()} method.
+(Implemented by Thomas Wouters.)
+% Patch 1397960
+
+\item The \module{struct} module now compiles structure format 
+strings into an internal representation and caches this
+representation, yielding a 20\% speedup.  (Contributed by Bob Ippolito
+at the NeedForSpeed sprint.)
+
+\item The \module{re} module got a 1 or 2\% speedup by switching to 
+Python's allocator functions instead of the system's 
+\cfunction{malloc()} and \cfunction{free()}.
+(Contributed by Jack Diederich at the NeedForSpeed sprint.)
+
+\item The code generator's peephole optimizer now performs
+simple constant folding in expressions.  If you write something like
+\code{a = 2+3}, the code generator will do the arithmetic and produce
+code corresponding to \code{a = 5}.  (Proposed and implemented 
+by Raymond Hettinger.)
+
+\item Function calls are now faster because code objects now keep 
+the most recently finished frame (a ``zombie frame'') in an internal
+field of the code object, reusing it the next time the code object is
+invoked.  (Original patch by Michael Hudson, modified by Armin Rigo
+and Richard Jones; committed at the NeedForSpeed sprint.)
+% Patch 876206
+
+Frame objects are also slightly smaller, which may improve cache locality
+and reduce memory usage a bit.  (Contributed by Neal Norwitz.)
+% Patch 1337051
+
+\item Python's built-in exceptions are now new-style classes, a change
+that speeds up instantiation considerably.  Exception handling in
+Python 2.5 is therefore about 30\% faster than in 2.4.
+(Contributed by Richard Jones, Georg Brandl and Sean Reifschneider at
+the NeedForSpeed sprint.)
+
+\item Importing now caches the paths tried, recording whether 
+they exist or not so that the interpreter makes fewer 
+\cfunction{open()} and \cfunction{stat()} calls on startup.
+(Contributed by Martin von~L\"owis and Georg Brandl.)
+% Patch 921466
+
+\end{itemize}
+
+
+%======================================================================
+\section{New, Improved, and Removed Modules\label{modules}}
+
+The standard library received many enhancements and bug fixes in
+Python 2.5.  Here's a partial list of the most notable changes, sorted
+alphabetically by module name. Consult the \file{Misc/NEWS} file in
+the source tree for a more complete list of changes, or look through
+the SVN logs for all the details.
+
+\begin{itemize}
+
+\item The \module{audioop} module now supports the a-LAW encoding,
+and the code for u-LAW encoding has been improved.  (Contributed by
+Lars Immisch.)
+
+\item The \module{codecs} module gained support for incremental
+codecs.  The \function{codec.lookup()} function now
+returns a \class{CodecInfo} instance instead of a tuple.
+\class{CodecInfo} instances behave like a 4-tuple to preserve backward
+compatibility but also have the attributes \member{encode},
+\member{decode}, \member{incrementalencoder}, \member{incrementaldecoder},
+\member{streamwriter}, and \member{streamreader}.  Incremental codecs 
+can receive input and produce output in multiple chunks; the output is
+the same as if the entire input was fed to the non-incremental codec.
+See the \module{codecs} module documentation for details.
+(Designed and implemented by Walter D\"orwald.)
+% Patch  1436130
+
+\item The \module{collections} module gained a new type,
+\class{defaultdict}, that subclasses the standard \class{dict}
+type.  The new type mostly behaves like a dictionary but constructs a
+default value when a key isn't present, automatically adding it to the
+dictionary for the requested key value.
+
+The first argument to \class{defaultdict}'s constructor is a factory
+function that gets called whenever a key is requested but not found.
+This factory function receives no arguments, so you can use built-in
+type constructors such as \function{list()} or \function{int()}.  For
+example, 
+you can make an index of words based on their initial letter like this:
+
+\begin{verbatim}
+words = """Nel mezzo del cammin di nostra vita
+mi ritrovai per una selva oscura
+che la diritta via era smarrita""".lower().split()
+
+index = defaultdict(list)
+
+for w in words:
+    init_letter = w[0]
+    index[init_letter].append(w)
+\end{verbatim}
+
+Printing \code{index} results in the following output:
+
+\begin{verbatim}
+defaultdict(<type 'list'>, {'c': ['cammin', 'che'], 'e': ['era'], 
+        'd': ['del', 'di', 'diritta'], 'm': ['mezzo', 'mi'], 
+        'l': ['la'], 'o': ['oscura'], 'n': ['nel', 'nostra'], 
+        'p': ['per'], 's': ['selva', 'smarrita'], 
+        'r': ['ritrovai'], 'u': ['una'], 'v': ['vita', 'via']}
+\end{verbatim}
+
+(Contributed by Guido van~Rossum.)
+
+\item The \class{deque} double-ended queue type supplied by the
+\module{collections} module now has a \method{remove(\var{value})}
+method that removes the first occurrence of \var{value} in the queue,
+raising \exception{ValueError} if the value isn't found.
+(Contributed by Raymond Hettinger.)
+
+\item New module: The \module{contextlib} module contains helper functions for use 
+with the new '\keyword{with}' statement.  See
+section~\ref{module-contextlib} for more about this module.
+
+\item New module: The \module{cProfile} module is a C implementation of 
+the existing \module{profile} module that has much lower overhead.
+The module's interface is the same as \module{profile}: you run
+\code{cProfile.run('main()')} to profile a function, can save profile
+data to a file, etc.  It's not yet known if the Hotshot profiler,
+which is also written in C but doesn't match the \module{profile}
+module's interface, will continue to be maintained in future versions
+of Python.  (Contributed by Armin Rigo.)
+
+Also, the \module{pstats} module for analyzing the data measured by
+the profiler now supports directing the output to any file object
+by supplying a \var{stream} argument to the \class{Stats} constructor.
+(Contributed by Skip Montanaro.)
+
+\item The \module{csv} module, which parses files in
+comma-separated value format, received several enhancements and a
+number of bugfixes.  You can now set the maximum size in bytes of a
+field by calling the \method{csv.field_size_limit(\var{new_limit})}
+function; omitting the \var{new_limit} argument will return the
+currently-set limit.  The \class{reader} class now has a
+\member{line_num} attribute that counts the number of physical lines
+read from the source; records can span multiple physical lines, so
+\member{line_num} is not the same as the number of records read.
+
+The CSV parser is now stricter about multi-line quoted
+fields. Previously, if a line ended within a quoted field without a
+terminating newline character, a newline would be inserted into the
+returned field. This behavior caused problems when reading files that
+contained carriage return characters within fields, so the code was
+changed to return the field without inserting newlines. As a
+consequence, if newlines embedded within fields are important, the
+input should be split into lines in a manner that preserves the
+newline characters.
+
+(Contributed by Skip Montanaro and Andrew McNamara.)
+
+\item The \class{datetime} class in the \module{datetime} 
+module now has a \method{strptime(\var{string}, \var{format})} 
+method for parsing date strings, contributed by Josh Spoerri.
+It uses the same format characters as \function{time.strptime()} and
+\function{time.strftime()}:
+
+\begin{verbatim}
+from datetime import datetime
+
+ts = datetime.strptime('10:13:15 2006-03-07',
+                       '%H:%M:%S %Y-%m-%d')
+\end{verbatim}
+
+\item The \method{SequenceMatcher.get_matching_blocks()} method
+in the \module{difflib} module now guarantees to return a minimal list
+of blocks describing matching subsequences.  Previously, the algorithm would
+occasionally break a block of matching elements into two list entries.
+(Enhancement by Tim Peters.)
+
+\item The \module{doctest} module gained a \code{SKIP} option that
+keeps an example from being executed at all.  This is intended for
+code snippets that are usage examples intended for the reader and
+aren't actually test cases.
+
+An \var{encoding} parameter was added to the \function{testfile()}
+function and the \class{DocFileSuite} class to specify the file's
+encoding.  This makes it easier to use non-ASCII characters in 
+tests contained within a docstring.  (Contributed by Bjorn Tillenius.)
+% Patch 1080727
+
+\item The \module{email} package has been updated to version 4.0.
+% XXX need to provide some more detail here
+(Contributed by Barry Warsaw.)
+
+\item The \module{fileinput} module was made more flexible.
+Unicode filenames are now supported, and a \var{mode} parameter that
+defaults to \code{"r"} was added to the
+\function{input()} function to allow opening files in binary or
+universal-newline mode.  Another new parameter, \var{openhook},
+lets you use a function other than \function{open()} 
+to open the input files.  Once you're iterating over 
+the set of files, the \class{FileInput} object's new
+\method{fileno()} returns the file descriptor for the currently opened file.
+(Contributed by Georg Brandl.)
+
+\item In the \module{gc} module, the new \function{get_count()} function
+returns a 3-tuple containing the current collection counts for the
+three GC generations.  This is accounting information for the garbage
+collector; when these counts reach a specified threshold, a garbage
+collection sweep will be made.  The existing \function{gc.collect()}
+function now takes an optional \var{generation} argument of 0, 1, or 2
+to specify which generation to collect.
+(Contributed by Barry Warsaw.)
+
+\item The \function{nsmallest()} and 
+\function{nlargest()} functions in the \module{heapq} module 
+now support a \code{key} keyword parameter similar to the one
+provided by the \function{min()}/\function{max()} functions
+and the \method{sort()} methods.  For example:
+
+\begin{verbatim}
+>>> import heapq
+>>> L = ["short", 'medium', 'longest', 'longer still']
+>>> heapq.nsmallest(2, L)  # Return two lowest elements, lexicographically
+['longer still', 'longest']
+>>> heapq.nsmallest(2, L, key=len)   # Return two shortest elements
+['short', 'medium']
+\end{verbatim}
+
+(Contributed by Raymond Hettinger.)
+
+\item The \function{itertools.islice()} function now accepts
+\code{None} for the start and step arguments.  This makes it more
+compatible with the attributes of slice objects, so that you can now write
+the following:
+
+\begin{verbatim}
+s = slice(5)     # Create slice object
+itertools.islice(iterable, s.start, s.stop, s.step)
+\end{verbatim}
+
+(Contributed by Raymond Hettinger.)
+
+\item The \function{format()} function in the \module{locale} module
+has been modified and two new functions were added,
+\function{format_string()} and \function{currency()}.
+
+The \function{format()} function's \var{val} parameter could
+previously be a string as long as no more than one \%char specifier
+appeared; now the parameter must be exactly one \%char specifier with
+no surrounding text.  An optional \var{monetary} parameter was also
+added which, if \code{True}, will use the locale's rules for
+formatting currency in placing a separator between groups of three
+digits.
+
+To format strings with multiple \%char specifiers, use the new
+\function{format_string()} function that works like \function{format()}
+but also supports mixing \%char specifiers with
+arbitrary text.
+
+A new \function{currency()} function was also added that formats a
+number according to the current locale's settings.
+
+(Contributed by Georg Brandl.)
+% Patch 1180296
+
+\item The \module{mailbox} module underwent a massive rewrite to add
+the capability to modify mailboxes in addition to reading them.  A new
+set of classes that include \class{mbox}, \class{MH}, and
+\class{Maildir} are used to read mailboxes, and have an
+\method{add(\var{message})} method to add messages,
+\method{remove(\var{key})} to remove messages, and
+\method{lock()}/\method{unlock()} to lock/unlock the mailbox.  The
+following example converts a maildir-format mailbox into an mbox-format one:
+
+\begin{verbatim}
+import mailbox
+
+# 'factory=None' uses email.Message.Message as the class representing
+# individual messages.
+src = mailbox.Maildir('maildir', factory=None)
+dest = mailbox.mbox('/tmp/mbox')
+
+for msg in src:
+    dest.add(msg)
+\end{verbatim}
+
+(Contributed by Gregory K. Johnson.  Funding was provided by Google's
+2005 Summer of Code.)
+
+\item New module: the \module{msilib} module allows creating
+Microsoft Installer \file{.msi} files and CAB files.  Some support
+for reading the \file{.msi} database is also included.
+(Contributed by Martin von~L\"owis.)
+
+\item The \module{nis} module now supports accessing domains other
+than the system default domain by supplying a \var{domain} argument to
+the \function{nis.match()} and \function{nis.maps()} functions.
+(Contributed by Ben Bell.)
+
+\item The \module{operator} module's \function{itemgetter()} 
+and \function{attrgetter()} functions now support multiple fields.  
+A call such as \code{operator.attrgetter('a', 'b')}
+will return a function 
+that retrieves the \member{a} and \member{b} attributes.  Combining 
+this new feature with the \method{sort()} method's \code{key} parameter 
+lets you easily sort lists using multiple fields.
+(Contributed by Raymond Hettinger.)
+
+\item The \module{optparse} module was updated to version 1.5.1 of the
+Optik library.  The \class{OptionParser} class gained an
+\member{epilog} attribute, a string that will be printed after the
+help message, and a \method{destroy()} method to break reference
+cycles created by the object. (Contributed by Greg Ward.)
+
+\item The \module{os} module underwent several changes.  The
+\member{stat_float_times} variable now defaults to true, meaning that
+\function{os.stat()} will now return time values as floats.  (This
+doesn't necessarily mean that \function{os.stat()} will return times
+that are precise to fractions of a second; not all systems support
+such precision.)
+
+Constants named \member{os.SEEK_SET}, \member{os.SEEK_CUR}, and
+\member{os.SEEK_END} have been added; these are the parameters to the
+\function{os.lseek()} function.  Two new constants for locking are
+\member{os.O_SHLOCK} and \member{os.O_EXLOCK}.
+
+Two new functions, \function{wait3()} and \function{wait4()}, were
+added.  They're similar the \function{waitpid()} function which waits
+for a child process to exit and returns a tuple of the process ID and
+its exit status, but \function{wait3()} and \function{wait4()} return
+additional information.  \function{wait3()} doesn't take a process ID
+as input, so it waits for any child process to exit and returns a
+3-tuple of \var{process-id}, \var{exit-status}, \var{resource-usage}
+as returned from the \function{resource.getrusage()} function.
+\function{wait4(\var{pid})} does take a process ID.
+(Contributed by Chad J. Schroeder.)
+
+On FreeBSD, the \function{os.stat()} function now returns 
+times with nanosecond resolution, and the returned object
+now has \member{st_gen} and \member{st_birthtime}.
+The \member{st_flags} member is also available, if the platform supports it.
+(Contributed by Antti Louko and  Diego Petten\`o.)
+% (Patch 1180695, 1212117)
+
+\item The Python debugger provided by the \module{pdb} module
+can now store lists of commands to execute when a breakpoint is
+reached and execution stops.  Once breakpoint \#1 has been created,
+enter \samp{commands 1} and enter a series of commands to be executed,
+finishing the list with \samp{end}.  The command list can include
+commands that resume execution, such as \samp{continue} or
+\samp{next}.  (Contributed by Gr\'egoire Dooms.)
+% Patch 790710
+
+\item The \module{pickle} and \module{cPickle} modules no
+longer accept a return value of \code{None} from the
+\method{__reduce__()} method; the method must return a tuple of
+arguments instead.  The ability to return \code{None} was deprecated
+in Python 2.4, so this completes the removal of the feature.
+
+\item The \module{pkgutil} module, containing various utility
+functions for finding packages, was enhanced to support PEP 302's
+import hooks and now also works for packages stored in ZIP-format archives.
+(Contributed by Phillip J. Eby.)
+
+\item The pybench benchmark suite by Marc-Andr\'e~Lemburg is now
+included in the \file{Tools/pybench} directory.  The pybench suite is
+an improvement on the commonly used \file{pystone.py} program because
+pybench provides a more detailed measurement of the interpreter's
+speed.  It times particular operations such as function calls,
+tuple slicing, method lookups, and numeric operations, instead of
+performing many different operations and reducing the result to a
+single number as \file{pystone.py} does.
+
+\item The \module{pyexpat} module now uses version 2.0 of the Expat parser.
+(Contributed by Trent Mick.)
+
+\item The \class{Queue} class provided by the \module{Queue} module
+gained two new methods.  \method{join()} blocks until all items in
+the queue have been retrieved and all processing work on the items 
+have been completed.  Worker threads call the other new method, 
+\method{task_done()}, to signal that processing for an item has been
+completed.  (Contributed by Raymond Hettinger.)
+
+\item The old \module{regex} and \module{regsub} modules, which have been 
+deprecated ever since Python 2.0, have finally been deleted.  
+Other deleted modules: \module{statcache}, \module{tzparse},
+\module{whrandom}.
+
+\item Also deleted: the \file{lib-old} directory,
+which includes ancient modules such as \module{dircmp} and
+\module{ni}, was removed.  \file{lib-old} wasn't on the default
+\code{sys.path}, so unless your programs explicitly added the directory to 
+\code{sys.path}, this removal shouldn't affect your code.
+
+\item The \module{rlcompleter} module is no longer 
+dependent on importing the \module{readline} module and
+therefore now works on non-{\UNIX} platforms.
+(Patch from Robert Kiendl.)
+% Patch #1472854
+
+\item The \module{SimpleXMLRPCServer} and \module{DocXMLRPCServer} 
+classes now have a \member{rpc_paths} attribute that constrains
+XML-RPC operations to a limited set of URL paths; the default is
+to allow only \code{'/'} and \code{'/RPC2'}.  Setting 
+\member{rpc_paths} to \code{None} or an empty tuple disables 
+this path checking.
+% Bug #1473048
+
+\item The \module{socket} module now supports \constant{AF_NETLINK}
+sockets on Linux, thanks to a patch from Philippe Biondi.  
+Netlink sockets are a Linux-specific mechanism for communications
+between a user-space process and kernel code; an introductory 
+article about them is at \url{http://www.linuxjournal.com/article/7356}.
+In Python code, netlink addresses are represented as a tuple of 2 integers, 
+\code{(\var{pid}, \var{group_mask})}.
+
+Two new methods on socket objects, \method{recv_into(\var{buffer})} and
+\method{recvfrom_into(\var{buffer})}, store the received data in an object 
+that supports the buffer protocol instead of returning the data as a
+string.  This means you can put the data directly into an array or a
+memory-mapped file.
+
+Socket objects also gained \method{getfamily()}, \method{gettype()},
+and \method{getproto()} accessor methods to retrieve the family, type,
+and protocol values for the socket.
+
+\item New module: the \module{spwd} module provides functions for
+accessing the shadow password database on systems that support 
+shadow passwords.
+
+\item The \module{struct} is now faster because it 
+compiles format strings into \class{Struct} objects
+with \method{pack()} and \method{unpack()} methods.  This is similar
+to how the \module{re} module lets you create compiled regular
+expression objects.  You can still use the module-level 
+\function{pack()} and \function{unpack()} functions; they'll create 
+\class{Struct} objects and cache them.  Or you can use 
+\class{Struct} instances directly:
+
+\begin{verbatim}
+s = struct.Struct('ih3s')
+
+data = s.pack(1972, 187, 'abc')
+year, number, name = s.unpack(data)
+\end{verbatim}
+
+You can also pack and unpack data to and from buffer objects directly
+using the \method{pack_into(\var{buffer}, \var{offset}, \var{v1},
+\var{v2}, ...)} and \method{unpack_from(\var{buffer}, \var{offset})}
+methods.  This lets you store data directly into an array or a
+memory-mapped file.
+
+(\class{Struct} objects were implemented by Bob Ippolito at the
+NeedForSpeed sprint.  Support for buffer objects was added by Martin
+Blais, also at the NeedForSpeed sprint.)
+
+\item The Python developers switched from CVS to Subversion during the 2.5
+development process.  Information about the exact build version is
+available as the \code{sys.subversion} variable, a 3-tuple of
+\code{(\var{interpreter-name}, \var{branch-name},
+\var{revision-range})}.  For example, at the time of writing my copy
+of 2.5 was reporting \code{('CPython', 'trunk', '45313:45315')}.
+
+This information is also available to C extensions via the 
+\cfunction{Py_GetBuildInfo()} function that returns a 
+string of build information like this:
+\code{"trunk:45355:45356M, Apr 13 2006, 07:42:19"}.  
+(Contributed by Barry Warsaw.)
+
+\item Another new function, \function{sys._current_frames()}, returns
+the current stack frames for all running threads as a dictionary
+mapping thread identifiers to the topmost stack frame currently active
+in that thread at the time the function is called.  (Contributed by
+Tim Peters.)
+
+\item The \class{TarFile} class in the \module{tarfile} module now has
+an \method{extractall()} method that extracts all members from the
+archive into the current working directory.  It's also possible to set
+a different directory as the extraction target, and to unpack only a
+subset of the archive's members.
+
+The compression used for a tarfile opened in stream mode can now be
+autodetected using the mode \code{'r|*'}.
+% patch 918101
+(Contributed by Lars Gust\"abel.)
+
+\item The \module{threading} module now lets you set the stack size
+used when new threads are created. The
+\function{stack_size(\optional{\var{size}})} function returns the
+currently configured stack size, and supplying the optional \var{size}
+parameter sets a new value.  Not all platforms support changing the
+stack size, but Windows, POSIX threading, and OS/2 all do.
+(Contributed by Andrew MacIntyre.)
+% Patch 1454481
+
+\item The \module{unicodedata} module has been updated to use version 4.1.0
+of the Unicode character database.  Version 3.2.0 is required 
+by some specifications, so it's still available as 
+\member{unicodedata.ucd_3_2_0}.
+
+\item New module: the  \module{uuid} module generates 
+universally unique identifiers (UUIDs) according to \rfc{4122}.  The
+RFC defines several different UUID versions that are generated from a
+starting string, from system properties, or purely randomly.  This
+module contains a \class{UUID} class and 
+functions named \function{uuid1()},
+\function{uuid3()}, \function{uuid4()},  and 
+\function{uuid5()} to generate different versions of UUID.  (Version 2 UUIDs 
+are not specified in \rfc{4122} and are not supported by this module.)
+
+\begin{verbatim}
+>>> import uuid
+>>> # make a UUID based on the host ID and current time
+>>> uuid.uuid1()
+UUID('a8098c1a-f86e-11da-bd1a-00112444be1e')
+
+>>> # make a UUID using an MD5 hash of a namespace UUID and a name
+>>> uuid.uuid3(uuid.NAMESPACE_DNS, 'python.org')
+UUID('6fa459ea-ee8a-3ca4-894e-db77e160355e')
+
+>>> # make a random UUID
+>>> uuid.uuid4()
+UUID('16fd2706-8baf-433b-82eb-8c7fada847da')
+
+>>> # make a UUID using a SHA-1 hash of a namespace UUID and a name
+>>> uuid.uuid5(uuid.NAMESPACE_DNS, 'python.org')
+UUID('886313e1-3b8a-5372-9b90-0c9aee199e5d')
+\end{verbatim}
+
+(Contributed by Ka-Ping Yee.)
+
+\item The \module{weakref} module's \class{WeakKeyDictionary} and
+\class{WeakValueDictionary} types gained new methods for iterating
+over the weak references contained in the dictionary. 
+\method{iterkeyrefs()} and \method{keyrefs()} methods were
+added to \class{WeakKeyDictionary}, and
+\method{itervaluerefs()} and \method{valuerefs()} were added to
+\class{WeakValueDictionary}.  (Contributed by Fred L.~Drake, Jr.)
+
+\item The \module{webbrowser} module received a number of
+enhancements.
+It's now usable as a script with \code{python -m webbrowser}, taking a
+URL as the argument; there are a number of switches 
+to control the behaviour (\programopt{-n} for a new browser window, 
+\programopt{-t} for a new tab).  New module-level functions,
+\function{open_new()} and \function{open_new_tab()}, were added 
+to support this.  The module's \function{open()} function supports an
+additional feature, an \var{autoraise} parameter that signals whether
+to raise the open window when possible. A number of additional
+browsers were added to the supported list such as Firefox, Opera,
+Konqueror, and elinks.  (Contributed by Oleg Broytmann and Georg
+Brandl.)
+% Patch #754022
+
+\item The \module{xmlrpclib} module now supports returning 
+      \class{datetime} objects for the XML-RPC date type.  Supply 
+      \code{use_datetime=True} to the \function{loads()} function
+      or the \class{Unmarshaller} class to enable this feature.
+      (Contributed by Skip Montanaro.)
+% Patch 1120353
+
+\item The \module{zipfile} module now supports the ZIP64 version of the 
+format, meaning that a .zip archive can now be larger than 4~GiB and
+can contain individual files larger than 4~GiB.  (Contributed by
+Ronald Oussoren.)
+% Patch 1446489
+
+\item The \module{zlib} module's \class{Compress} and \class{Decompress}
+objects now support a \method{copy()} method that makes a copy of the 
+object's internal state and returns a new 
+\class{Compress} or \class{Decompress} object. 
+(Contributed by Chris AtLee.)
+% Patch 1435422
+
+\end{itemize}
+
+
+
+%======================================================================
+\subsection{The ctypes package\label{module-ctypes}}
+
+The \module{ctypes} package, written by Thomas Heller, has been added 
+to the standard library.  \module{ctypes} lets you call arbitrary functions 
+in shared libraries or DLLs.  Long-time users may remember the \module{dl} module, which 
+provides functions for loading shared libraries and calling functions in them.  The \module{ctypes} package is much fancier.
+
+To load a shared library or DLL, you must create an instance of the 
+\class{CDLL} class and provide the name or path of the shared library
+or DLL.  Once that's done, you can call arbitrary functions
+by accessing them as attributes of the \class{CDLL} object.  
+
+\begin{verbatim}
+import ctypes
+
+libc = ctypes.CDLL('libc.so.6')
+result = libc.printf("Line of output\n")
+\end{verbatim}
+
+Type constructors for the various C types are provided: \function{c_int},
+\function{c_float}, \function{c_double}, \function{c_char_p} (equivalent to \ctype{char *}), and so forth.  Unlike Python's types, the C versions are all mutable; you can assign to their \member{value} attribute
+to change the wrapped value.  Python integers and strings will be automatically
+converted to the corresponding C types, but for other types you 
+must call the correct type constructor.  (And I mean \emph{must}; 
+getting it wrong will often result in the interpreter crashing 
+with a segmentation fault.)
+
+You shouldn't use \function{c_char_p} with a Python string when the C function will be modifying the memory area, because Python strings are 
+supposed to be immutable; breaking this rule will cause puzzling bugs.  When you need a modifiable memory area,
+use \function{create_string_buffer()}:
+
+\begin{verbatim}
+s = "this is a string"
+buf = ctypes.create_string_buffer(s)
+libc.strfry(buf)
+\end{verbatim}
+
+C functions are assumed to return integers, but you can set
+the \member{restype} attribute of the function object to 
+change this:
+
+\begin{verbatim}
+>>> libc.atof('2.71828')
+-1783957616
+>>> libc.atof.restype = ctypes.c_double
+>>> libc.atof('2.71828')
+2.71828
+\end{verbatim}
+
+\module{ctypes} also provides a wrapper for Python's C API 
+as the \code{ctypes.pythonapi} object.  This object does \emph{not} 
+release the global interpreter lock before calling a function, because the lock must be held when calling into the interpreter's code.  
+There's a \class{py_object()} type constructor that will create a 
+\ctype{PyObject *} pointer.  A simple usage:
+
+\begin{verbatim}
+import ctypes
+
+d = {}
+ctypes.pythonapi.PyObject_SetItem(ctypes.py_object(d),
+          ctypes.py_object("abc"),  ctypes.py_object(1))
+# d is now {'abc', 1}.
+\end{verbatim}
+
+Don't forget to use \class{py_object()}; if it's omitted you end 
+up with a segmentation fault.
+
+\module{ctypes} has been around for a while, but people still write 
+and distribution hand-coded extension modules because you can't rely on \module{ctypes} being present.
+Perhaps developers will begin to write 
+Python wrappers atop a library accessed through \module{ctypes} instead
+of extension modules, now that \module{ctypes} is included with core Python.
+
+\begin{seealso}
+
+\seeurl{http://starship.python.net/crew/theller/ctypes/}
+{The ctypes web page, with a tutorial, reference, and FAQ.}
+
+\seeurl{../lib/module-ctypes.html}{The documentation 
+for the \module{ctypes} module.}
+
+\end{seealso}
+
+
+%======================================================================
+\subsection{The ElementTree package\label{module-etree}}
+
+A subset of Fredrik Lundh's ElementTree library for processing XML has
+been added to the standard library as \module{xml.etree}.  The
+available modules are
+\module{ElementTree}, \module{ElementPath}, and
+\module{ElementInclude} from ElementTree 1.2.6.   
+The \module{cElementTree} accelerator module is also included. 
+
+The rest of this section will provide a brief overview of using
+ElementTree.  Full documentation for ElementTree is available at
+\url{http://effbot.org/zone/element-index.htm}.
+
+ElementTree represents an XML document as a tree of element nodes.
+The text content of the document is stored as the \member{.text}
+and \member{.tail} attributes of 
+(This is one of the major differences between ElementTree and 
+the Document Object Model; in the DOM there are many different
+types of node, including \class{TextNode}.)
+
+The most commonly used parsing function is \function{parse()}, that
+takes either a string (assumed to contain a filename) or a file-like
+object and returns an \class{ElementTree} instance:
+
+\begin{verbatim}
+from xml.etree import ElementTree as ET
+
+tree = ET.parse('ex-1.xml')
+
+feed = urllib.urlopen(
+          'http://planet.python.org/rss10.xml')
+tree = ET.parse(feed)
+\end{verbatim}
+
+Once you have an \class{ElementTree} instance, you
+can call its \method{getroot()} method to get the root \class{Element} node.
+
+There's also an \function{XML()} function that takes a string literal
+and returns an \class{Element} node (not an \class{ElementTree}).  
+This function provides a tidy way to incorporate XML fragments,
+approaching the convenience of an XML literal:
+
+\begin{verbatim}
+svg = ET.XML("""<svg width="10px" version="1.0">
+             </svg>""")
+svg.set('height', '320px')
+svg.append(elem1)
+\end{verbatim}
+
+Each XML element supports some dictionary-like and some list-like
+access methods.  Dictionary-like operations are used to access attribute
+values, and list-like operations are used to access child nodes.
+
+\begin{tableii}{c|l}{code}{Operation}{Result}
+  \lineii{elem[n]}{Returns n'th child element.}
+  \lineii{elem[m:n]}{Returns list of m'th through n'th child elements.}
+  \lineii{len(elem)}{Returns number of child elements.}
+  \lineii{list(elem)}{Returns list of child elements.}
+  \lineii{elem.append(elem2)}{Adds \var{elem2} as a child.}
+  \lineii{elem.insert(index, elem2)}{Inserts \var{elem2} at the specified location.}
+  \lineii{del elem[n]}{Deletes n'th child element.}
+  \lineii{elem.keys()}{Returns list of attribute names.}
+  \lineii{elem.get(name)}{Returns value of attribute \var{name}.}
+  \lineii{elem.set(name, value)}{Sets new value for attribute \var{name}.}
+  \lineii{elem.attrib}{Retrieves the dictionary containing attributes.}
+  \lineii{del elem.attrib[name]}{Deletes attribute \var{name}.}
+\end{tableii}
+
+Comments and processing instructions are also represented as
+\class{Element} nodes.  To check if a node is a comment or processing
+instructions:
+
+\begin{verbatim}
+if elem.tag is ET.Comment:
+    ...
+elif elem.tag is ET.ProcessingInstruction:
+    ...
+\end{verbatim}
+
+To generate XML output, you should call the
+\method{ElementTree.write()} method.  Like \function{parse()},
+it can take either a string or a file-like object:
+
+\begin{verbatim}
+# Encoding is US-ASCII
+tree.write('output.xml')
+
+# Encoding is UTF-8
+f = open('output.xml', 'w')
+tree.write(f, encoding='utf-8')
+\end{verbatim}
+
+(Caution: the default encoding used for output is ASCII.  For general
+XML work, where an element's name may contain arbitrary Unicode
+characters, ASCII isn't a very useful encoding because it will raise
+an exception if an element's name contains any characters with values
+greater than 127.  Therefore, it's best to specify a different
+encoding such as UTF-8 that can handle any Unicode character.)
+
+This section is only a partial description of the ElementTree interfaces.
+Please read the package's official documentation for more details.
+
+\begin{seealso}
+
+\seeurl{http://effbot.org/zone/element-index.htm}
+{Official documentation for ElementTree.}
+
+\end{seealso}
+
+
+%======================================================================
+\subsection{The hashlib package\label{module-hashlib}}
+
+A new \module{hashlib} module, written by Gregory P. Smith, 
+has been added to replace the
+\module{md5} and \module{sha} modules.  \module{hashlib} adds support
+for additional secure hashes (SHA-224, SHA-256, SHA-384, and SHA-512).
+When available, the module uses OpenSSL for fast platform optimized
+implementations of algorithms.  
+
+The old \module{md5} and \module{sha} modules still exist as wrappers
+around hashlib to preserve backwards compatibility.  The new module's
+interface is very close to that of the old modules, but not identical.
+The most significant difference is that the constructor functions
+for creating new hashing objects are named differently.
+
+\begin{verbatim}
+# Old versions
+h = md5.md5()   
+h = md5.new()   
+
+# New version 
+h = hashlib.md5()
+
+# Old versions
+h = sha.sha()   
+h = sha.new()   
+
+# New version 
+h = hashlib.sha1()
+
+# Hash that weren't previously available
+h = hashlib.sha224()
+h = hashlib.sha256()
+h = hashlib.sha384()
+h = hashlib.sha512()
+
+# Alternative form
+h = hashlib.new('md5')          # Provide algorithm as a string
+\end{verbatim}
+
+Once a hash object has been created, its methods are the same as before:
+\method{update(\var{string})} hashes the specified string into the 
+current digest state, \method{digest()} and \method{hexdigest()}
+return the digest value as a binary string or a string of hex digits,
+and \method{copy()} returns a new hashing object with the same digest state.
+
+\begin{seealso}
+
+\seeurl{../lib/module-hashlib.html}{The documentation 
+for the \module{hashlib} module.}
+
+\end{seealso}
+
+
+%======================================================================
+\subsection{The sqlite3 package\label{module-sqlite}}
+
+The pysqlite module (\url{http://www.pysqlite.org}), a wrapper for the
+SQLite embedded database, has been added to the standard library under
+the package name \module{sqlite3}.  
+
+SQLite is a C library that provides a lightweight disk-based database
+that doesn't require a separate server process and allows accessing
+the database using a nonstandard variant of the SQL query language.
+Some applications can use SQLite for internal data storage.  It's also
+possible to prototype an application using SQLite and then port the
+code to a larger database such as PostgreSQL or Oracle.
+ 
+pysqlite was written by Gerhard H\"aring and provides a SQL interface
+compliant with the DB-API 2.0 specification described by
+\pep{249}. 
+
+If you're compiling the Python source yourself, note that the source
+tree doesn't include the SQLite code, only the wrapper module.
+You'll need to have the SQLite libraries and headers installed before
+compiling Python, and the build process will compile the module when
+the necessary headers are available.
+
+To use the module, you must first create a \class{Connection} object
+that represents the database.  Here the data will be stored in the 
+\file{/tmp/example} file:
+
+\begin{verbatim}
+conn = sqlite3.connect('/tmp/example')
+\end{verbatim}
+
+You can also supply the special name \samp{:memory:} to create
+a database in RAM.
+
+Once you have a \class{Connection}, you can create a \class{Cursor} 
+object and call its \method{execute()} method to perform SQL commands:
+
+\begin{verbatim}
+c = conn.cursor()
+
+# Create table
+c.execute('''create table stocks
+(date text, trans text, symbol text,
+ qty real, price real)''')
+
+# Insert a row of data
+c.execute("""insert into stocks
+          values ('2006-01-05','BUY','RHAT',100,35.14)""")
+\end{verbatim}    
+
+Usually your SQL operations will need to use values from Python
+variables.  You shouldn't assemble your query using Python's string
+operations because doing so is insecure; it makes your program
+vulnerable to an SQL injection attack.  
+
+Instead, use the DB-API's parameter substitution.  Put \samp{?} as a
+placeholder wherever you want to use a value, and then provide a tuple
+of values as the second argument to the cursor's \method{execute()}
+method.  (Other database modules may use a different placeholder,
+such as \samp{\%s} or \samp{:1}.) For example:
+
+\begin{verbatim}    
+# Never do this -- insecure!
+symbol = 'IBM'
+c.execute("... where symbol = '%s'" % symbol)
+
+# Do this instead
+t = (symbol,)
+c.execute('select * from stocks where symbol=?', t)
+
+# Larger example
+for t in (('2006-03-28', 'BUY', 'IBM', 1000, 45.00),
+          ('2006-04-05', 'BUY', 'MSOFT', 1000, 72.00),
+          ('2006-04-06', 'SELL', 'IBM', 500, 53.00),
+         ):
+    c.execute('insert into stocks values (?,?,?,?,?)', t)
+\end{verbatim}
+
+To retrieve data after executing a SELECT statement, you can either 
+treat the cursor as an iterator, call the cursor's \method{fetchone()}
+method to retrieve a single matching row, 
+or call \method{fetchall()} to get a list of the matching rows.
+
+This example uses the iterator form:
+
+\begin{verbatim}
+>>> c = conn.cursor()
+>>> c.execute('select * from stocks order by price')
+>>> for row in c:
+...    print row
+...
+(u'2006-01-05', u'BUY', u'RHAT', 100, 35.140000000000001)
+(u'2006-03-28', u'BUY', u'IBM', 1000, 45.0)
+(u'2006-04-06', u'SELL', u'IBM', 500, 53.0)
+(u'2006-04-05', u'BUY', u'MSOFT', 1000, 72.0)
+>>>
+\end{verbatim}
+
+For more information about the SQL dialect supported by SQLite, see 
+\url{http://www.sqlite.org}.
+
+\begin{seealso}
+
+\seeurl{http://www.pysqlite.org}
+{The pysqlite web page.}
+
+\seeurl{http://www.sqlite.org}
+{The SQLite web page; the documentation describes the syntax and the
+available data types for the supported SQL dialect.}
+
+\seeurl{../lib/module-sqlite3.html}{The documentation 
+for the \module{sqlite3} module.}
+
+\seepep{249}{Database API Specification 2.0}{PEP written by
+Marc-Andr\'e Lemburg.}
+
+\end{seealso}
+
+
+%======================================================================
+\subsection{The wsgiref package\label{module-wsgiref}}
+
+% XXX should this be in a PEP 333 section instead?
+
+The Web Server Gateway Interface (WSGI) v1.0 defines a standard
+interface between web servers and Python web applications and is
+described in \pep{333}.  The \module{wsgiref} package is a reference
+implementation of the WSGI specification.
+
+The package includes a basic HTTP server that will run a WSGI
+application; this server is useful for debugging but isn't intended for 
+production use.  Setting up a server takes only a few lines of code:
+
+\begin{verbatim}
+from wsgiref import simple_server
+
+wsgi_app = ...
+
+host = ''
+port = 8000
+httpd = simple_server.make_server(host, port, wsgi_app)
+httpd.serve_forever()
+\end{verbatim}
+
+% XXX discuss structure of WSGI applications?  
+% XXX provide an example using Django or some other framework?
+
+\begin{seealso}
+
+\seeurl{http://www.wsgi.org}{A central web site for WSGI-related resources.}
+
+\seepep{333}{Python Web Server Gateway Interface v1.0}{PEP written by
+Phillip J. Eby.}
+
+\end{seealso}
+
+
+% ======================================================================
+\section{Build and C API Changes\label{build-api}}
+
+Changes to Python's build process and to the C API include:
+
+\begin{itemize}
+
+\item The Python source tree was converted from CVS to Subversion, 
+in a complex migration procedure that was supervised and flawlessly
+carried out by Martin von~L\"owis.  The procedure was developed as
+\pep{347}.
+
+\item Coverity, a company that markets a source code analysis tool
+called Prevent, provided the results of their examination of the Python
+source code.  The analysis found about 60 bugs that 
+were quickly fixed.  Many of the bugs were refcounting problems, often
+occurring in error-handling code.  See
+\url{http://scan.coverity.com} for the statistics.
+
+\item The largest change to the C API came from \pep{353},
+which modifies the interpreter to use a \ctype{Py_ssize_t} type
+definition instead of \ctype{int}.  See the earlier
+section~\ref{pep-353} for a discussion of this change.
+
+\item The design of the bytecode compiler has changed a great deal, 
+no longer generating bytecode by traversing the parse tree.  Instead
+the parse tree is converted to an abstract syntax tree (or AST), and it is 
+the abstract syntax tree that's traversed to produce the bytecode.
+
+It's possible for Python code to obtain AST objects by using the 
+\function{compile()} built-in and specifying \code{_ast.PyCF_ONLY_AST}
+as the value of the 
+\var{flags} parameter:
+
+\begin{verbatim}
+from _ast import PyCF_ONLY_AST
+ast = compile("""a=0
+for i in range(10):
+    a += i
+""", "<string>", 'exec', PyCF_ONLY_AST)
+
+assignment = ast.body[0]
+for_loop = ast.body[1]
+\end{verbatim}
+
+No official documentation has been written for the AST code yet, but
+\pep{339} discusses the design.  To start learning about the code, read the
+definition of the various AST nodes in \file{Parser/Python.asdl}.  A
+Python script reads this file and generates a set of C structure
+definitions in \file{Include/Python-ast.h}.  The
+\cfunction{PyParser_ASTFromString()} and
+\cfunction{PyParser_ASTFromFile()}, defined in
+\file{Include/pythonrun.h}, take Python source as input and return the
+root of an AST representing the contents.  This AST can then be turned
+into a code object by \cfunction{PyAST_Compile()}.  For more
+information, read the source code, and then ask questions on
+python-dev.
+
+% List of names taken from Jeremy's python-dev post at 
+% http://mail.python.org/pipermail/python-dev/2005-October/057500.html
+The AST code was developed under Jeremy Hylton's management, and
+implemented by (in alphabetical order) Brett Cannon, Nick Coghlan,
+Grant Edwards, John Ehresman, Kurt Kaiser, Neal Norwitz, Tim Peters,
+Armin Rigo, and Neil Schemenauer, plus the participants in a number of
+AST sprints at conferences such as PyCon.
+ 
+\item Evan Jones's patch to obmalloc, first described in a talk
+at PyCon DC 2005, was applied.  Python 2.4 allocated small objects in
+256K-sized arenas, but never freed arenas.  With this patch, Python
+will free arenas when they're empty.  The net effect is that on some
+platforms, when you allocate many objects, Python's memory usage may
+actually drop when you delete them and the memory may be returned to
+the operating system.  (Implemented by Evan Jones, and reworked by Tim
+Peters.)
+
+Note that this change means extension modules must be more careful
+when allocating memory.  Python's API has many different
+functions for allocating memory that are grouped into families.  For
+example, \cfunction{PyMem_Malloc()}, \cfunction{PyMem_Realloc()}, and
+\cfunction{PyMem_Free()} are one family that allocates raw memory,
+while \cfunction{PyObject_Malloc()}, \cfunction{PyObject_Realloc()},
+and \cfunction{PyObject_Free()} are another family that's supposed to
+be used for creating Python objects.  
+
+Previously these different families all reduced to the platform's
+\cfunction{malloc()} and \cfunction{free()} functions.  This meant 
+it didn't matter if you got things wrong and allocated memory with the
+\cfunction{PyMem} function but freed it with the \cfunction{PyObject}
+function.  With 2.5's changes to obmalloc, these families now do different
+things and mismatches will probably result in a segfault.  You should
+carefully test your C extension modules with Python 2.5.
+
+\item The built-in set types now have an official C API.  Call
+\cfunction{PySet_New()} and \cfunction{PyFrozenSet_New()} to create a
+new set, \cfunction{PySet_Add()} and \cfunction{PySet_Discard()} to
+add and remove elements, and \cfunction{PySet_Contains} and
+\cfunction{PySet_Size} to examine the set's state.
+(Contributed by Raymond Hettinger.)
+
+\item C code can now obtain information about the exact revision
+of the Python interpreter by calling the 
+\cfunction{Py_GetBuildInfo()} function that returns a 
+string of build information like this:
+\code{"trunk:45355:45356M, Apr 13 2006, 07:42:19"}.  
+(Contributed by Barry Warsaw.)
+
+\item Two new macros can be used to indicate C functions that are
+local to the current file so that a faster calling convention can be
+used.  \cfunction{Py_LOCAL(\var{type})} declares the function as
+returning a value of the specified \var{type} and uses a fast-calling
+qualifier. \cfunction{Py_LOCAL_INLINE(\var{type})} does the same thing
+and also requests the function be inlined.  If
+\cfunction{PY_LOCAL_AGGRESSIVE} is defined before \file{python.h} is
+included, a set of more aggressive optimizations are enabled for the
+module; you should benchmark the results to find out if these
+optimizations actually make the code faster.  (Contributed by Fredrik
+Lundh at the NeedForSpeed sprint.)
+
+\item \cfunction{PyErr_NewException(\var{name}, \var{base},
+\var{dict})} can now accept a tuple of base classes as its \var{base}
+argument.  (Contributed by Georg Brandl.)
+
+\item The \cfunction{PyErr_Warn()} function for issuing warnings
+is now deprecated in favour of \cfunction{PyErr_WarnEx(category,
+message, stacklevel)} which lets you specify the number of stack
+frames separating this function and the caller.  A \var{stacklevel} of
+1 is the function calling \cfunction{PyErr_WarnEx()}, 2 is the
+function above that, and so forth.  (Added by Neal Norwitz.)
+
+\item The CPython interpreter is still written in C, but 
+the code can now be compiled with a {\Cpp} compiler without errors.  
+(Implemented by Anthony Baxter, Martin von~L\"owis, Skip Montanaro.)
+
+\item The \cfunction{PyRange_New()} function was removed.  It was
+never documented, never used in the core code, and had dangerously lax
+error checking.  In the unlikely case that your extensions were using
+it, you can replace it by something like the following:
+\begin{verbatim}
+range = PyObject_CallFunction((PyObject*) &PyRange_Type, "lll", 
+                              start, stop, step);
+\end{verbatim}
+
+\end{itemize}
+
+
+%======================================================================
+\subsection{Port-Specific Changes\label{ports}}
+
+\begin{itemize}
+
+\item MacOS X (10.3 and higher): dynamic loading of modules
+now uses the \cfunction{dlopen()} function instead of MacOS-specific
+functions.
+
+\item MacOS X: a \longprogramopt{enable-universalsdk} switch was added
+to the \program{configure} script that compiles the interpreter as a
+universal binary able to run on both PowerPC and Intel processors.
+(Contributed by Ronald Oussoren.)
+
+\item Windows: \file{.dll} is no longer supported as a filename extension for 
+extension modules.  \file{.pyd} is now the only filename extension that will
+be searched for.
+
+\end{itemize}
+
+
+%======================================================================
+\section{Porting to Python 2.5\label{porting}}
+
+This section lists previously described changes that may require
+changes to your code:
+
+\begin{itemize}
+
+\item ASCII is now the default encoding for modules.  It's now 
+a syntax error if a module contains string literals with 8-bit
+characters but doesn't have an encoding declaration.  In Python 2.4
+this triggered a warning, not a syntax error.
+
+\item Previously, the \member{gi_frame} attribute of a generator
+was always a frame object.  Because of the \pep{342} changes
+described in section~\ref{pep-342}, it's now possible
+for \member{gi_frame} to be \code{None}.
+
+\item A new warning, \class{UnicodeWarning}, is triggered when 
+you attempt to compare a Unicode string and an 8-bit string that can't
+be converted to Unicode using the default ASCII encoding.  Previously
+such comparisons would raise a \class{UnicodeDecodeError} exception.
+
+\item Library: the \module{csv} module is now stricter about multi-line quoted
+fields.  If your files contain newlines embedded within fields, the
+input should be split into lines in a manner which preserves the
+newline characters.
+
+\item Library: the \module{locale} module's 
+\function{format()} function's would previously 
+accept any string as long as no more than one \%char specifier
+appeared.  In Python 2.5, the argument must be exactly one \%char
+specifier with no surrounding text. 
+
+\item Library: The \module{pickle} and \module{cPickle} modules no
+longer accept a return value of \code{None} from the
+\method{__reduce__()} method; the method must return a tuple of
+arguments instead.  The modules also no longer accept the deprecated
+\var{bin} keyword parameter.
+
+\item Library: The \module{SimpleXMLRPCServer} and \module{DocXMLRPCServer} 
+classes now have a \member{rpc_paths} attribute that constrains
+XML-RPC operations to a limited set of URL paths; the default is
+to allow only \code{'/'} and \code{'/RPC2'}.  Setting 
+\member{rpc_paths} to \code{None} or an empty tuple disables 
+this path checking.
+
+\item C API: Many functions now use \ctype{Py_ssize_t} 
+instead of \ctype{int} to allow processing more data on 64-bit
+machines.  Extension code may need to make the same change to avoid
+warnings and to support 64-bit machines.  See the earlier
+section~\ref{pep-353} for a discussion of this change.
+
+\item C API: 
+The obmalloc changes mean that 
+you must be careful to not mix usage 
+of the \cfunction{PyMem_*()} and \cfunction{PyObject_*()}
+families of functions. Memory allocated with 
+one family's \cfunction{*_Malloc()} must be 
+freed with the corresponding family's \cfunction{*_Free()} function.
+
+\end{itemize}
+
+
+%======================================================================
+\section{Acknowledgements \label{acks}}
+
+The author would like to thank the following people for offering
+suggestions, corrections and assistance with various drafts of this
+article: Georg Brandl, Nick Coghlan, Phillip J. Eby, Lars Gust\"abel,
+Raymond Hettinger, Ralf W. Grosse-Kunstleve, Kent Johnson, Iain Lowe,
+Martin von~L\"owis, Fredrik Lundh, Andrew McNamara, Skip Montanaro,
+Gustavo Niemeyer, Paul Prescod, James Pryor, Mike Rovner, Scott
+Weikart, Barry Warsaw, Thomas Wouters.
+
+\end{document}

Added: vendor/Python/current/Grammar/Grammar
===================================================================
--- vendor/Python/current/Grammar/Grammar	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Grammar/Grammar	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,148 @@
+# Grammar for Python
+
+# Note:  Changing the grammar specified in this file will most likely
+#        require corresponding changes in the parser module
+#        (../Modules/parsermodule.c).  If you can't make the changes to
+#        that module yourself, please co-ordinate the required changes
+#        with someone who can; ask around on python-dev for help.  Fred
+#        Drake <fdrake at acm.org> will probably be listening there.
+
+# NOTE WELL: You should also follow all the steps listed in PEP 306,
+# "How to Change Python's Grammar"
+
+# Commands for Kees Blom's railroad program
+#diagram:token NAME
+#diagram:token NUMBER
+#diagram:token STRING
+#diagram:token NEWLINE
+#diagram:token ENDMARKER
+#diagram:token INDENT
+#diagram:output\input python.bla
+#diagram:token DEDENT
+#diagram:output\textwidth 20.04cm\oddsidemargin  0.0cm\evensidemargin 0.0cm
+#diagram:rules
+
+# Start symbols for the grammar:
+#	single_input is a single interactive statement;
+#	file_input is a module or sequence of commands read from an input file;
+#	eval_input is the input for the eval() and input() functions.
+# NB: compound_stmt in single_input is followed by extra NEWLINE!
+single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE
+file_input: (NEWLINE | stmt)* ENDMARKER
+eval_input: testlist NEWLINE* ENDMARKER
+
+decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE
+decorators: decorator+
+funcdef: [decorators] 'def' NAME parameters ':' suite
+parameters: '(' [varargslist] ')'
+varargslist: ((fpdef ['=' test] ',')*
+              ('*' NAME [',' '**' NAME] | '**' NAME) |
+              fpdef ['=' test] (',' fpdef ['=' test])* [','])
+fpdef: NAME | '(' fplist ')'
+fplist: fpdef (',' fpdef)* [',']
+
+stmt: simple_stmt | compound_stmt
+simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
+small_stmt: (expr_stmt | print_stmt  | del_stmt | pass_stmt | flow_stmt |
+             import_stmt | global_stmt | exec_stmt | assert_stmt)
+expr_stmt: testlist (augassign (yield_expr|testlist) |
+                     ('=' (yield_expr|testlist))*)
+augassign: ('+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' |
+            '<<=' | '>>=' | '**=' | '//=')
+# For normal assignments, additional restrictions enforced by the interpreter
+print_stmt: 'print' ( [ test (',' test)* [','] ] |
+                      '>>' test [ (',' test)+ [','] ] )
+del_stmt: 'del' exprlist
+pass_stmt: 'pass'
+flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | yield_stmt
+break_stmt: 'break'
+continue_stmt: 'continue'
+return_stmt: 'return' [testlist]
+yield_stmt: yield_expr
+raise_stmt: 'raise' [test [',' test [',' test]]]
+import_stmt: import_name | import_from
+import_name: 'import' dotted_as_names
+import_from: ('from' ('.'* dotted_name | '.'+)
+              'import' ('*' | '(' import_as_names ')' | import_as_names))
+import_as_name: NAME [('as' | NAME) NAME]
+dotted_as_name: dotted_name [('as' | NAME) NAME]
+import_as_names: import_as_name (',' import_as_name)* [',']
+dotted_as_names: dotted_as_name (',' dotted_as_name)*
+dotted_name: NAME ('.' NAME)*
+global_stmt: 'global' NAME (',' NAME)*
+exec_stmt: 'exec' expr ['in' test [',' test]]
+assert_stmt: 'assert' test [',' test]
+
+compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | with_stmt | funcdef | classdef
+if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
+while_stmt: 'while' test ':' suite ['else' ':' suite]
+for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite]
+try_stmt: ('try' ':' suite
+           ((except_clause ':' suite)+
+	    ['else' ':' suite]
+	    ['finally' ':' suite] |
+	   'finally' ':' suite))
+with_stmt: 'with' test [ with_var ] ':' suite
+with_var: ('as' | NAME) expr
+# NB compile.c makes sure that the default except clause is last
+except_clause: 'except' [test [',' test]]
+suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT
+
+# Backward compatibility cruft to support:
+# [ x for x in lambda: True, lambda: False if x() ]
+# even while also allowing:
+# lambda x: 5 if x else 2
+# (But not a mix of the two)
+testlist_safe: old_test [(',' old_test)+ [',']]
+old_test: or_test | old_lambdef
+old_lambdef: 'lambda' [varargslist] ':' old_test
+
+test: or_test ['if' or_test 'else' test] | lambdef
+or_test: and_test ('or' and_test)*
+and_test: not_test ('and' not_test)*
+not_test: 'not' not_test | comparison
+comparison: expr (comp_op expr)*
+comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not'
+expr: xor_expr ('|' xor_expr)*
+xor_expr: and_expr ('^' and_expr)*
+and_expr: shift_expr ('&' shift_expr)*
+shift_expr: arith_expr (('<<'|'>>') arith_expr)*
+arith_expr: term (('+'|'-') term)*
+term: factor (('*'|'/'|'%'|'//') factor)*
+factor: ('+'|'-'|'~') factor | power
+power: atom trailer* ['**' factor]
+atom: ('(' [yield_expr|testlist_gexp] ')' |
+       '[' [listmaker] ']' |
+       '{' [dictmaker] '}' |
+       '`' testlist1 '`' |
+       NAME | NUMBER | STRING+)
+listmaker: test ( list_for | (',' test)* [','] )
+testlist_gexp: test ( gen_for | (',' test)* [','] )
+lambdef: 'lambda' [varargslist] ':' test
+trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
+subscriptlist: subscript (',' subscript)* [',']
+subscript: '.' '.' '.' | test | [test] ':' [test] [sliceop]
+sliceop: ':' [test]
+exprlist: expr (',' expr)* [',']
+testlist: test (',' test)* [',']
+dictmaker: test ':' test (',' test ':' test)* [',']
+
+classdef: 'class' NAME ['(' [testlist] ')'] ':' suite
+
+arglist: (argument ',')* (argument [',']| '*' test [',' '**' test] | '**' test)
+argument: test [gen_for] | test '=' test  # Really [keyword '='] test
+
+list_iter: list_for | list_if
+list_for: 'for' exprlist 'in' testlist_safe [list_iter]
+list_if: 'if' old_test [list_iter]
+
+gen_iter: gen_for | gen_if
+gen_for: 'for' exprlist 'in' or_test [gen_iter]
+gen_if: 'if' old_test [gen_iter]
+
+testlist1: test (',' test)*
+
+# not used in grammar, but may appear in "node" passed from Parser to Compiler
+encoding_decl: NAME
+
+yield_expr: 'yield' [testlist]

Added: vendor/Python/current/Include/Python-ast.h
===================================================================
--- vendor/Python/current/Include/Python-ast.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/Python-ast.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,501 @@
+/* File automatically generated by Parser/asdl_c.py */
+
+#include "asdl.h"
+
+typedef struct _mod *mod_ty;
+
+typedef struct _stmt *stmt_ty;
+
+typedef struct _expr *expr_ty;
+
+typedef enum _expr_context { Load=1, Store=2, Del=3, AugLoad=4, AugStore=5,
+                             Param=6 } expr_context_ty;
+
+typedef struct _slice *slice_ty;
+
+typedef enum _boolop { And=1, Or=2 } boolop_ty;
+
+typedef enum _operator { Add=1, Sub=2, Mult=3, Div=4, Mod=5, Pow=6, LShift=7,
+                         RShift=8, BitOr=9, BitXor=10, BitAnd=11, FloorDiv=12 }
+                         operator_ty;
+
+typedef enum _unaryop { Invert=1, Not=2, UAdd=3, USub=4 } unaryop_ty;
+
+typedef enum _cmpop { Eq=1, NotEq=2, Lt=3, LtE=4, Gt=5, GtE=6, Is=7, IsNot=8,
+                      In=9, NotIn=10 } cmpop_ty;
+
+typedef struct _comprehension *comprehension_ty;
+
+typedef struct _excepthandler *excepthandler_ty;
+
+typedef struct _arguments *arguments_ty;
+
+typedef struct _keyword *keyword_ty;
+
+typedef struct _alias *alias_ty;
+
+
+enum _mod_kind {Module_kind=1, Interactive_kind=2, Expression_kind=3,
+                 Suite_kind=4};
+struct _mod {
+        enum _mod_kind kind;
+        union {
+                struct {
+                        asdl_seq *body;
+                } Module;
+                
+                struct {
+                        asdl_seq *body;
+                } Interactive;
+                
+                struct {
+                        expr_ty body;
+                } Expression;
+                
+                struct {
+                        asdl_seq *body;
+                } Suite;
+                
+        } v;
+};
+
+enum _stmt_kind {FunctionDef_kind=1, ClassDef_kind=2, Return_kind=3,
+                  Delete_kind=4, Assign_kind=5, AugAssign_kind=6, Print_kind=7,
+                  For_kind=8, While_kind=9, If_kind=10, With_kind=11,
+                  Raise_kind=12, TryExcept_kind=13, TryFinally_kind=14,
+                  Assert_kind=15, Import_kind=16, ImportFrom_kind=17,
+                  Exec_kind=18, Global_kind=19, Expr_kind=20, Pass_kind=21,
+                  Break_kind=22, Continue_kind=23};
+struct _stmt {
+        enum _stmt_kind kind;
+        union {
+                struct {
+                        identifier name;
+                        arguments_ty args;
+                        asdl_seq *body;
+                        asdl_seq *decorators;
+                } FunctionDef;
+                
+                struct {
+                        identifier name;
+                        asdl_seq *bases;
+                        asdl_seq *body;
+                } ClassDef;
+                
+                struct {
+                        expr_ty value;
+                } Return;
+                
+                struct {
+                        asdl_seq *targets;
+                } Delete;
+                
+                struct {
+                        asdl_seq *targets;
+                        expr_ty value;
+                } Assign;
+                
+                struct {
+                        expr_ty target;
+                        operator_ty op;
+                        expr_ty value;
+                } AugAssign;
+                
+                struct {
+                        expr_ty dest;
+                        asdl_seq *values;
+                        bool nl;
+                } Print;
+                
+                struct {
+                        expr_ty target;
+                        expr_ty iter;
+                        asdl_seq *body;
+                        asdl_seq *orelse;
+                } For;
+                
+                struct {
+                        expr_ty test;
+                        asdl_seq *body;
+                        asdl_seq *orelse;
+                } While;
+                
+                struct {
+                        expr_ty test;
+                        asdl_seq *body;
+                        asdl_seq *orelse;
+                } If;
+                
+                struct {
+                        expr_ty context_expr;
+                        expr_ty optional_vars;
+                        asdl_seq *body;
+                } With;
+                
+                struct {
+                        expr_ty type;
+                        expr_ty inst;
+                        expr_ty tback;
+                } Raise;
+                
+                struct {
+                        asdl_seq *body;
+                        asdl_seq *handlers;
+                        asdl_seq *orelse;
+                } TryExcept;
+                
+                struct {
+                        asdl_seq *body;
+                        asdl_seq *finalbody;
+                } TryFinally;
+                
+                struct {
+                        expr_ty test;
+                        expr_ty msg;
+                } Assert;
+                
+                struct {
+                        asdl_seq *names;
+                } Import;
+                
+                struct {
+                        identifier module;
+                        asdl_seq *names;
+                        int level;
+                } ImportFrom;
+                
+                struct {
+                        expr_ty body;
+                        expr_ty globals;
+                        expr_ty locals;
+                } Exec;
+                
+                struct {
+                        asdl_seq *names;
+                } Global;
+                
+                struct {
+                        expr_ty value;
+                } Expr;
+                
+        } v;
+        int lineno;
+        int col_offset;
+};
+
+enum _expr_kind {BoolOp_kind=1, BinOp_kind=2, UnaryOp_kind=3, Lambda_kind=4,
+                  IfExp_kind=5, Dict_kind=6, ListComp_kind=7,
+                  GeneratorExp_kind=8, Yield_kind=9, Compare_kind=10,
+                  Call_kind=11, Repr_kind=12, Num_kind=13, Str_kind=14,
+                  Attribute_kind=15, Subscript_kind=16, Name_kind=17,
+                  List_kind=18, Tuple_kind=19};
+struct _expr {
+        enum _expr_kind kind;
+        union {
+                struct {
+                        boolop_ty op;
+                        asdl_seq *values;
+                } BoolOp;
+                
+                struct {
+                        expr_ty left;
+                        operator_ty op;
+                        expr_ty right;
+                } BinOp;
+                
+                struct {
+                        unaryop_ty op;
+                        expr_ty operand;
+                } UnaryOp;
+                
+                struct {
+                        arguments_ty args;
+                        expr_ty body;
+                } Lambda;
+                
+                struct {
+                        expr_ty test;
+                        expr_ty body;
+                        expr_ty orelse;
+                } IfExp;
+                
+                struct {
+                        asdl_seq *keys;
+                        asdl_seq *values;
+                } Dict;
+                
+                struct {
+                        expr_ty elt;
+                        asdl_seq *generators;
+                } ListComp;
+                
+                struct {
+                        expr_ty elt;
+                        asdl_seq *generators;
+                } GeneratorExp;
+                
+                struct {
+                        expr_ty value;
+                } Yield;
+                
+                struct {
+                        expr_ty left;
+                        asdl_int_seq *ops;
+                        asdl_seq *comparators;
+                } Compare;
+                
+                struct {
+                        expr_ty func;
+                        asdl_seq *args;
+                        asdl_seq *keywords;
+                        expr_ty starargs;
+                        expr_ty kwargs;
+                } Call;
+                
+                struct {
+                        expr_ty value;
+                } Repr;
+                
+                struct {
+                        object n;
+                } Num;
+                
+                struct {
+                        string s;
+                } Str;
+                
+                struct {
+                        expr_ty value;
+                        identifier attr;
+                        expr_context_ty ctx;
+                } Attribute;
+                
+                struct {
+                        expr_ty value;
+                        slice_ty slice;
+                        expr_context_ty ctx;
+                } Subscript;
+                
+                struct {
+                        identifier id;
+                        expr_context_ty ctx;
+                } Name;
+                
+                struct {
+                        asdl_seq *elts;
+                        expr_context_ty ctx;
+                } List;
+                
+                struct {
+                        asdl_seq *elts;
+                        expr_context_ty ctx;
+                } Tuple;
+                
+        } v;
+        int lineno;
+        int col_offset;
+};
+
+enum _slice_kind {Ellipsis_kind=1, Slice_kind=2, ExtSlice_kind=3, Index_kind=4};
+struct _slice {
+        enum _slice_kind kind;
+        union {
+                struct {
+                        expr_ty lower;
+                        expr_ty upper;
+                        expr_ty step;
+                } Slice;
+                
+                struct {
+                        asdl_seq *dims;
+                } ExtSlice;
+                
+                struct {
+                        expr_ty value;
+                } Index;
+                
+        } v;
+};
+
+struct _comprehension {
+        expr_ty target;
+        expr_ty iter;
+        asdl_seq *ifs;
+};
+
+struct _excepthandler {
+        expr_ty type;
+        expr_ty name;
+        asdl_seq *body;
+        int lineno;
+        int col_offset;
+};
+
+struct _arguments {
+        asdl_seq *args;
+        identifier vararg;
+        identifier kwarg;
+        asdl_seq *defaults;
+};
+
+struct _keyword {
+        identifier arg;
+        expr_ty value;
+};
+
+struct _alias {
+        identifier name;
+        identifier asname;
+};
+
+
+#define Module(a0, a1) _Py_Module(a0, a1)
+mod_ty _Py_Module(asdl_seq * body, PyArena *arena);
+#define Interactive(a0, a1) _Py_Interactive(a0, a1)
+mod_ty _Py_Interactive(asdl_seq * body, PyArena *arena);
+#define Expression(a0, a1) _Py_Expression(a0, a1)
+mod_ty _Py_Expression(expr_ty body, PyArena *arena);
+#define Suite(a0, a1) _Py_Suite(a0, a1)
+mod_ty _Py_Suite(asdl_seq * body, PyArena *arena);
+#define FunctionDef(a0, a1, a2, a3, a4, a5, a6) _Py_FunctionDef(a0, a1, a2, a3, a4, a5, a6)
+stmt_ty _Py_FunctionDef(identifier name, arguments_ty args, asdl_seq * body,
+                        asdl_seq * decorators, int lineno, int col_offset,
+                        PyArena *arena);
+#define ClassDef(a0, a1, a2, a3, a4, a5) _Py_ClassDef(a0, a1, a2, a3, a4, a5)
+stmt_ty _Py_ClassDef(identifier name, asdl_seq * bases, asdl_seq * body, int
+                     lineno, int col_offset, PyArena *arena);
+#define Return(a0, a1, a2, a3) _Py_Return(a0, a1, a2, a3)
+stmt_ty _Py_Return(expr_ty value, int lineno, int col_offset, PyArena *arena);
+#define Delete(a0, a1, a2, a3) _Py_Delete(a0, a1, a2, a3)
+stmt_ty _Py_Delete(asdl_seq * targets, int lineno, int col_offset, PyArena
+                   *arena);
+#define Assign(a0, a1, a2, a3, a4) _Py_Assign(a0, a1, a2, a3, a4)
+stmt_ty _Py_Assign(asdl_seq * targets, expr_ty value, int lineno, int
+                   col_offset, PyArena *arena);
+#define AugAssign(a0, a1, a2, a3, a4, a5) _Py_AugAssign(a0, a1, a2, a3, a4, a5)
+stmt_ty _Py_AugAssign(expr_ty target, operator_ty op, expr_ty value, int
+                      lineno, int col_offset, PyArena *arena);
+#define Print(a0, a1, a2, a3, a4, a5) _Py_Print(a0, a1, a2, a3, a4, a5)
+stmt_ty _Py_Print(expr_ty dest, asdl_seq * values, bool nl, int lineno, int
+                  col_offset, PyArena *arena);
+#define For(a0, a1, a2, a3, a4, a5, a6) _Py_For(a0, a1, a2, a3, a4, a5, a6)
+stmt_ty _Py_For(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq *
+                orelse, int lineno, int col_offset, PyArena *arena);
+#define While(a0, a1, a2, a3, a4, a5) _Py_While(a0, a1, a2, a3, a4, a5)
+stmt_ty _Py_While(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno,
+                  int col_offset, PyArena *arena);
+#define If(a0, a1, a2, a3, a4, a5) _Py_If(a0, a1, a2, a3, a4, a5)
+stmt_ty _Py_If(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno,
+               int col_offset, PyArena *arena);
+#define With(a0, a1, a2, a3, a4, a5) _Py_With(a0, a1, a2, a3, a4, a5)
+stmt_ty _Py_With(expr_ty context_expr, expr_ty optional_vars, asdl_seq * body,
+                 int lineno, int col_offset, PyArena *arena);
+#define Raise(a0, a1, a2, a3, a4, a5) _Py_Raise(a0, a1, a2, a3, a4, a5)
+stmt_ty _Py_Raise(expr_ty type, expr_ty inst, expr_ty tback, int lineno, int
+                  col_offset, PyArena *arena);
+#define TryExcept(a0, a1, a2, a3, a4, a5) _Py_TryExcept(a0, a1, a2, a3, a4, a5)
+stmt_ty _Py_TryExcept(asdl_seq * body, asdl_seq * handlers, asdl_seq * orelse,
+                      int lineno, int col_offset, PyArena *arena);
+#define TryFinally(a0, a1, a2, a3, a4) _Py_TryFinally(a0, a1, a2, a3, a4)
+stmt_ty _Py_TryFinally(asdl_seq * body, asdl_seq * finalbody, int lineno, int
+                       col_offset, PyArena *arena);
+#define Assert(a0, a1, a2, a3, a4) _Py_Assert(a0, a1, a2, a3, a4)
+stmt_ty _Py_Assert(expr_ty test, expr_ty msg, int lineno, int col_offset,
+                   PyArena *arena);
+#define Import(a0, a1, a2, a3) _Py_Import(a0, a1, a2, a3)
+stmt_ty _Py_Import(asdl_seq * names, int lineno, int col_offset, PyArena
+                   *arena);
+#define ImportFrom(a0, a1, a2, a3, a4, a5) _Py_ImportFrom(a0, a1, a2, a3, a4, a5)
+stmt_ty _Py_ImportFrom(identifier module, asdl_seq * names, int level, int
+                       lineno, int col_offset, PyArena *arena);
+#define Exec(a0, a1, a2, a3, a4, a5) _Py_Exec(a0, a1, a2, a3, a4, a5)
+stmt_ty _Py_Exec(expr_ty body, expr_ty globals, expr_ty locals, int lineno, int
+                 col_offset, PyArena *arena);
+#define Global(a0, a1, a2, a3) _Py_Global(a0, a1, a2, a3)
+stmt_ty _Py_Global(asdl_seq * names, int lineno, int col_offset, PyArena
+                   *arena);
+#define Expr(a0, a1, a2, a3) _Py_Expr(a0, a1, a2, a3)
+stmt_ty _Py_Expr(expr_ty value, int lineno, int col_offset, PyArena *arena);
+#define Pass(a0, a1, a2) _Py_Pass(a0, a1, a2)
+stmt_ty _Py_Pass(int lineno, int col_offset, PyArena *arena);
+#define Break(a0, a1, a2) _Py_Break(a0, a1, a2)
+stmt_ty _Py_Break(int lineno, int col_offset, PyArena *arena);
+#define Continue(a0, a1, a2) _Py_Continue(a0, a1, a2)
+stmt_ty _Py_Continue(int lineno, int col_offset, PyArena *arena);
+#define BoolOp(a0, a1, a2, a3, a4) _Py_BoolOp(a0, a1, a2, a3, a4)
+expr_ty _Py_BoolOp(boolop_ty op, asdl_seq * values, int lineno, int col_offset,
+                   PyArena *arena);
+#define BinOp(a0, a1, a2, a3, a4, a5) _Py_BinOp(a0, a1, a2, a3, a4, a5)
+expr_ty _Py_BinOp(expr_ty left, operator_ty op, expr_ty right, int lineno, int
+                  col_offset, PyArena *arena);
+#define UnaryOp(a0, a1, a2, a3, a4) _Py_UnaryOp(a0, a1, a2, a3, a4)
+expr_ty _Py_UnaryOp(unaryop_ty op, expr_ty operand, int lineno, int col_offset,
+                    PyArena *arena);
+#define Lambda(a0, a1, a2, a3, a4) _Py_Lambda(a0, a1, a2, a3, a4)
+expr_ty _Py_Lambda(arguments_ty args, expr_ty body, int lineno, int col_offset,
+                   PyArena *arena);
+#define IfExp(a0, a1, a2, a3, a4, a5) _Py_IfExp(a0, a1, a2, a3, a4, a5)
+expr_ty _Py_IfExp(expr_ty test, expr_ty body, expr_ty orelse, int lineno, int
+                  col_offset, PyArena *arena);
+#define Dict(a0, a1, a2, a3, a4) _Py_Dict(a0, a1, a2, a3, a4)
+expr_ty _Py_Dict(asdl_seq * keys, asdl_seq * values, int lineno, int
+                 col_offset, PyArena *arena);
+#define ListComp(a0, a1, a2, a3, a4) _Py_ListComp(a0, a1, a2, a3, a4)
+expr_ty _Py_ListComp(expr_ty elt, asdl_seq * generators, int lineno, int
+                     col_offset, PyArena *arena);
+#define GeneratorExp(a0, a1, a2, a3, a4) _Py_GeneratorExp(a0, a1, a2, a3, a4)
+expr_ty _Py_GeneratorExp(expr_ty elt, asdl_seq * generators, int lineno, int
+                         col_offset, PyArena *arena);
+#define Yield(a0, a1, a2, a3) _Py_Yield(a0, a1, a2, a3)
+expr_ty _Py_Yield(expr_ty value, int lineno, int col_offset, PyArena *arena);
+#define Compare(a0, a1, a2, a3, a4, a5) _Py_Compare(a0, a1, a2, a3, a4, a5)
+expr_ty _Py_Compare(expr_ty left, asdl_int_seq * ops, asdl_seq * comparators,
+                    int lineno, int col_offset, PyArena *arena);
+#define Call(a0, a1, a2, a3, a4, a5, a6, a7) _Py_Call(a0, a1, a2, a3, a4, a5, a6, a7)
+expr_ty _Py_Call(expr_ty func, asdl_seq * args, asdl_seq * keywords, expr_ty
+                 starargs, expr_ty kwargs, int lineno, int col_offset, PyArena
+                 *arena);
+#define Repr(a0, a1, a2, a3) _Py_Repr(a0, a1, a2, a3)
+expr_ty _Py_Repr(expr_ty value, int lineno, int col_offset, PyArena *arena);
+#define Num(a0, a1, a2, a3) _Py_Num(a0, a1, a2, a3)
+expr_ty _Py_Num(object n, int lineno, int col_offset, PyArena *arena);
+#define Str(a0, a1, a2, a3) _Py_Str(a0, a1, a2, a3)
+expr_ty _Py_Str(string s, int lineno, int col_offset, PyArena *arena);
+#define Attribute(a0, a1, a2, a3, a4, a5) _Py_Attribute(a0, a1, a2, a3, a4, a5)
+expr_ty _Py_Attribute(expr_ty value, identifier attr, expr_context_ty ctx, int
+                      lineno, int col_offset, PyArena *arena);
+#define Subscript(a0, a1, a2, a3, a4, a5) _Py_Subscript(a0, a1, a2, a3, a4, a5)
+expr_ty _Py_Subscript(expr_ty value, slice_ty slice, expr_context_ty ctx, int
+                      lineno, int col_offset, PyArena *arena);
+#define Name(a0, a1, a2, a3, a4) _Py_Name(a0, a1, a2, a3, a4)
+expr_ty _Py_Name(identifier id, expr_context_ty ctx, int lineno, int
+                 col_offset, PyArena *arena);
+#define List(a0, a1, a2, a3, a4) _Py_List(a0, a1, a2, a3, a4)
+expr_ty _Py_List(asdl_seq * elts, expr_context_ty ctx, int lineno, int
+                 col_offset, PyArena *arena);
+#define Tuple(a0, a1, a2, a3, a4) _Py_Tuple(a0, a1, a2, a3, a4)
+expr_ty _Py_Tuple(asdl_seq * elts, expr_context_ty ctx, int lineno, int
+                  col_offset, PyArena *arena);
+#define Ellipsis(a0) _Py_Ellipsis(a0)
+slice_ty _Py_Ellipsis(PyArena *arena);
+#define Slice(a0, a1, a2, a3) _Py_Slice(a0, a1, a2, a3)
+slice_ty _Py_Slice(expr_ty lower, expr_ty upper, expr_ty step, PyArena *arena);
+#define ExtSlice(a0, a1) _Py_ExtSlice(a0, a1)
+slice_ty _Py_ExtSlice(asdl_seq * dims, PyArena *arena);
+#define Index(a0, a1) _Py_Index(a0, a1)
+slice_ty _Py_Index(expr_ty value, PyArena *arena);
+#define comprehension(a0, a1, a2, a3) _Py_comprehension(a0, a1, a2, a3)
+comprehension_ty _Py_comprehension(expr_ty target, expr_ty iter, asdl_seq *
+                                   ifs, PyArena *arena);
+#define excepthandler(a0, a1, a2, a3, a4, a5) _Py_excepthandler(a0, a1, a2, a3, a4, a5)
+excepthandler_ty _Py_excepthandler(expr_ty type, expr_ty name, asdl_seq * body,
+                                   int lineno, int col_offset, PyArena *arena);
+#define arguments(a0, a1, a2, a3, a4) _Py_arguments(a0, a1, a2, a3, a4)
+arguments_ty _Py_arguments(asdl_seq * args, identifier vararg, identifier
+                           kwarg, asdl_seq * defaults, PyArena *arena);
+#define keyword(a0, a1, a2) _Py_keyword(a0, a1, a2)
+keyword_ty _Py_keyword(identifier arg, expr_ty value, PyArena *arena);
+#define alias(a0, a1, a2) _Py_alias(a0, a1, a2)
+alias_ty _Py_alias(identifier name, identifier asname, PyArena *arena);
+
+PyObject* PyAST_mod2obj(mod_ty t);

Added: vendor/Python/current/Include/Python.h
===================================================================
--- vendor/Python/current/Include/Python.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/Python.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,173 @@
+#ifndef Py_PYTHON_H
+#define Py_PYTHON_H
+/* Since this is a "meta-include" file, no #ifdef __cplusplus / extern "C" { */
+
+/* Include nearly all Python header files */
+
+#include "patchlevel.h"
+#include "pyconfig.h"
+
+/* Cyclic gc is always enabled, starting with release 2.3a1.  Supply the
+ * old symbol for the benefit of extension modules written before then
+ * that may be conditionalizing on it.  The core doesn't use it anymore.
+ */
+#ifndef WITH_CYCLE_GC
+#define WITH_CYCLE_GC 1
+#endif
+
+#include <limits.h>
+
+#ifndef UCHAR_MAX
+#error "Something's broken.  UCHAR_MAX should be defined in limits.h."
+#endif
+
+#if UCHAR_MAX != 255
+#error "Python's source code assumes C's unsigned char is an 8-bit type."
+#endif
+
+#if defined(__sgi) && defined(WITH_THREAD) && !defined(_SGI_MP_SOURCE)
+#define _SGI_MP_SOURCE
+#endif
+
+#include <stdio.h>
+#ifndef NULL
+#   error "Python.h requires that stdio.h define NULL."
+#endif
+
+#include <string.h>
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#include <stdlib.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+/* For uintptr_t, intptr_t */
+#ifdef HAVE_STDDEF_H
+#include <stddef.h>
+#endif
+
+/* CAUTION:  Build setups should ensure that NDEBUG is defined on the
+ * compiler command line when building Python in release mode; else
+ * assert() calls won't be removed.
+ */
+#include <assert.h>
+
+#include "pyport.h"
+
+/* pyconfig.h or pyport.h may or may not define DL_IMPORT */
+#ifndef DL_IMPORT	/* declarations for DLL import/export */
+#define DL_IMPORT(RTYPE) RTYPE
+#endif
+#ifndef DL_EXPORT	/* declarations for DLL import/export */
+#define DL_EXPORT(RTYPE) RTYPE
+#endif
+
+/* Debug-mode build with pymalloc implies PYMALLOC_DEBUG.
+ *  PYMALLOC_DEBUG is in error if pymalloc is not in use.
+ */
+#if defined(Py_DEBUG) && defined(WITH_PYMALLOC) && !defined(PYMALLOC_DEBUG)
+#define PYMALLOC_DEBUG
+#endif
+#if defined(PYMALLOC_DEBUG) && !defined(WITH_PYMALLOC)
+#error "PYMALLOC_DEBUG requires WITH_PYMALLOC"
+#endif
+#include "pymem.h"
+
+#include "object.h"
+#include "objimpl.h"
+
+#include "pydebug.h"
+
+#include "unicodeobject.h"
+#include "intobject.h"
+#include "boolobject.h"
+#include "longobject.h"
+#include "floatobject.h"
+#ifndef WITHOUT_COMPLEX
+#include "complexobject.h"
+#endif
+#include "rangeobject.h"
+#include "stringobject.h"
+#include "bufferobject.h"
+#include "tupleobject.h"
+#include "listobject.h"
+#include "dictobject.h"
+#include "enumobject.h"
+#include "setobject.h"
+#include "methodobject.h"
+#include "moduleobject.h"
+#include "funcobject.h"
+#include "classobject.h"
+#include "fileobject.h"
+#include "cobject.h"
+#include "traceback.h"
+#include "sliceobject.h"
+#include "cellobject.h"
+#include "iterobject.h"
+#include "genobject.h"
+#include "descrobject.h"
+#include "weakrefobject.h"
+
+#include "codecs.h"
+#include "pyerrors.h"
+
+#include "pystate.h"
+
+#include "pyarena.h"
+#include "modsupport.h"
+#include "pythonrun.h"
+#include "ceval.h"
+#include "sysmodule.h"
+#include "intrcheck.h"
+#include "import.h"
+
+#include "abstract.h"
+
+#include "compile.h"
+#include "eval.h"
+
+#include "pystrtod.h"
+
+/* _Py_Mangle is defined in compile.c */
+PyAPI_FUNC(PyObject*) _Py_Mangle(PyObject *p, PyObject *name);
+
+/* PyArg_GetInt is deprecated and should not be used, use PyArg_Parse(). */
+#define PyArg_GetInt(v, a)	PyArg_Parse((v), "i", (a))
+
+/* PyArg_NoArgs should not be necessary.
+   Set ml_flags in the PyMethodDef to METH_NOARGS. */
+#define PyArg_NoArgs(v)		PyArg_Parse(v, "")
+
+/* Convert a possibly signed character to a nonnegative int */
+/* XXX This assumes characters are 8 bits wide */
+#ifdef __CHAR_UNSIGNED__
+#define Py_CHARMASK(c)		(c)
+#else
+#define Py_CHARMASK(c)		((c) & 0xff)
+#endif
+
+#include "pyfpe.h"
+
+/* These definitions must match corresponding definitions in graminit.h.
+   There's code in compile.c that checks that they are the same. */
+#define Py_single_input 256
+#define Py_file_input 257
+#define Py_eval_input 258
+
+#ifdef HAVE_PTH
+/* GNU pth user-space thread support */
+#include <pth.h>
+#endif
+
+/* Define macros for inline documentation. */
+#define PyDoc_VAR(name) static char name[]
+#define PyDoc_STRVAR(name,str) PyDoc_VAR(name) = PyDoc_STR(str)
+#ifdef WITH_DOC_STRINGS
+#define PyDoc_STR(str) str
+#else
+#define PyDoc_STR(str) ""
+#endif
+
+#endif /* !Py_PYTHON_H */

Added: vendor/Python/current/Include/abstract.h
===================================================================
--- vendor/Python/current/Include/abstract.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/abstract.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1276 @@
+#ifndef Py_ABSTRACTOBJECT_H
+#define Py_ABSTRACTOBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef PY_SSIZE_T_CLEAN
+#define PyObject_CallFunction _PyObject_CallFunction_SizeT
+#define PyObject_CallMethod _PyObject_CallMethod_SizeT
+#endif
+
+/* Abstract Object Interface (many thanks to Jim Fulton) */
+
+/*
+   PROPOSAL: A Generic Python Object Interface for Python C Modules
+
+Problem
+
+  Python modules written in C that must access Python objects must do
+  so through routines whose interfaces are described by a set of
+  include files.  Unfortunately, these routines vary according to the
+  object accessed.  To use these routines, the C programmer must check
+  the type of the object being used and must call a routine based on
+  the object type.  For example, to access an element of a sequence,
+  the programmer must determine whether the sequence is a list or a
+  tuple:
+
+    if(is_tupleobject(o))
+      e=gettupleitem(o,i)
+    else if(is_listitem(o))
+      e=getlistitem(o,i)
+
+  If the programmer wants to get an item from another type of object
+  that provides sequence behavior, there is no clear way to do it
+  correctly.  
+
+  The persistent programmer may peruse object.h and find that the
+  _typeobject structure provides a means of invoking up to (currently
+  about) 41 special operators.  So, for example, a routine can get an
+  item from any object that provides sequence behavior. However, to
+  use this mechanism, the programmer must make their code dependent on
+  the current Python implementation.
+
+  Also, certain semantics, especially memory management semantics, may
+  differ by the type of object being used.  Unfortunately, these
+  semantics are not clearly described in the current include files.
+  An abstract interface providing more consistent semantics is needed. 
+
+Proposal
+
+  I propose the creation of a standard interface (with an associated
+  library of routines and/or macros) for generically obtaining the
+  services of Python objects.  This proposal can be viewed as one
+  components of a Python C interface consisting of several components.
+
+  From the viewpoint of C access to Python services, we have (as
+  suggested by Guido in off-line discussions):
+
+  - "Very high level layer": two or three functions that let you exec or
+    eval arbitrary Python code given as a string in a module whose name is
+    given, passing C values in and getting C values out using
+    mkvalue/getargs style format strings.  This does not require the user
+    to declare any variables of type "PyObject *".  This should be enough
+    to write a simple application that gets Python code from the user,
+    execs it, and returns the output or errors.  (Error handling must also
+    be part of this API.)
+
+  - "Abstract objects layer": which is the subject of this proposal.
+    It has many functions operating on objects, and lest you do many
+    things from C that you can also write in Python, without going
+    through the Python parser.
+
+  - "Concrete objects layer": This is the public type-dependent
+    interface provided by the standard built-in types, such as floats,
+    strings, and lists.  This interface exists and is currently
+    documented by the collection of include files provided with the
+    Python distributions.
+
+  From the point of view of Python accessing services provided by C
+  modules: 
+
+  - "Python module interface": this interface consist of the basic
+    routines used to define modules and their members.  Most of the
+    current extensions-writing guide deals with this interface.
+
+  - "Built-in object interface": this is the interface that a new
+    built-in type must provide and the mechanisms and rules that a
+    developer of a new built-in type must use and follow.
+
+  This proposal is a "first-cut" that is intended to spur
+  discussion. See especially the lists of notes.
+
+  The Python C object interface will provide four protocols: object,
+  numeric, sequence, and mapping.  Each protocol consists of a
+  collection of related operations.  If an operation that is not
+  provided by a particular type is invoked, then a standard exception,
+  NotImplementedError is raised with a operation name as an argument.
+  In addition, for convenience this interface defines a set of
+  constructors for building objects of built-in types.  This is needed
+  so new objects can be returned from C functions that otherwise treat
+  objects generically.
+
+Memory Management
+
+  For all of the functions described in this proposal, if a function
+  retains a reference to a Python object passed as an argument, then the
+  function will increase the reference count of the object.  It is
+  unnecessary for the caller to increase the reference count of an
+  argument in anticipation of the object's retention.
+
+  All Python objects returned from functions should be treated as new
+  objects.  Functions that return objects assume that the caller will
+  retain a reference and the reference count of the object has already
+  been incremented to account for this fact.  A caller that does not
+  retain a reference to an object that is returned from a function
+  must decrement the reference count of the object (using
+  DECREF(object)) to prevent memory leaks.
+
+  Note that the behavior mentioned here is different from the current
+  behavior for some objects (e.g. lists and tuples) when certain
+  type-specific routines are called directly (e.g. setlistitem).  The
+  proposed abstraction layer will provide a consistent memory
+  management interface, correcting for inconsistent behavior for some
+  built-in types.
+
+Protocols
+
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
+
+/*  Object Protocol: */
+
+     /* Implemented elsewhere:
+
+     int PyObject_Print(PyObject *o, FILE *fp, int flags);
+
+         Print an object, o, on file, fp.  Returns -1 on
+	 error.  The flags argument is used to enable certain printing
+	 options. The only option currently supported is Py_Print_RAW. 
+
+         (What should be said about Py_Print_RAW?)	
+
+       */
+
+     /* Implemented elsewhere:
+
+     int PyObject_HasAttrString(PyObject *o, char *attr_name);
+
+         Returns 1 if o has the attribute attr_name, and 0 otherwise.
+	 This is equivalent to the Python expression:
+	 hasattr(o,attr_name). 
+
+	 This function always succeeds.
+
+       */
+
+     /* Implemented elsewhere:
+
+     PyObject* PyObject_GetAttrString(PyObject *o, char *attr_name);
+
+	 Retrieve an attributed named attr_name form object o.
+	 Returns the attribute value on success, or NULL on failure.
+	 This is the equivalent of the Python expression: o.attr_name.
+
+       */
+
+     /* Implemented elsewhere:
+
+     int PyObject_HasAttr(PyObject *o, PyObject *attr_name);
+
+         Returns 1 if o has the attribute attr_name, and 0 otherwise.
+	 This is equivalent to the Python expression:
+	 hasattr(o,attr_name). 
+
+	 This function always succeeds.
+
+       */
+
+     /* Implemented elsewhere:
+
+     PyObject* PyObject_GetAttr(PyObject *o, PyObject *attr_name);
+
+	 Retrieve an attributed named attr_name form object o.
+	 Returns the attribute value on success, or NULL on failure.
+	 This is the equivalent of the Python expression: o.attr_name.
+
+       */
+
+
+     /* Implemented elsewhere:
+
+     int PyObject_SetAttrString(PyObject *o, char *attr_name, PyObject *v);
+
+	 Set the value of the attribute named attr_name, for object o,
+	 to the value, v. Returns -1 on failure.  This is
+	 the equivalent of the Python statement: o.attr_name=v.
+
+       */
+
+     /* Implemented elsewhere:
+
+     int PyObject_SetAttr(PyObject *o, PyObject *attr_name, PyObject *v);
+
+	 Set the value of the attribute named attr_name, for object o,
+	 to the value, v. Returns -1 on failure.  This is
+	 the equivalent of the Python statement: o.attr_name=v.
+
+       */
+
+     /* implemented as a macro:
+
+     int PyObject_DelAttrString(PyObject *o, char *attr_name);
+
+	 Delete attribute named attr_name, for object o. Returns
+	 -1 on failure.  This is the equivalent of the Python
+	 statement: del o.attr_name.
+
+       */
+#define  PyObject_DelAttrString(O,A) PyObject_SetAttrString((O),(A),NULL)
+
+     /* implemented as a macro:
+
+     int PyObject_DelAttr(PyObject *o, PyObject *attr_name);
+
+	 Delete attribute named attr_name, for object o. Returns -1
+	 on failure.  This is the equivalent of the Python
+	 statement: del o.attr_name.
+
+       */
+#define  PyObject_DelAttr(O,A) PyObject_SetAttr((O),(A),NULL)
+
+     PyAPI_FUNC(int) PyObject_Cmp(PyObject *o1, PyObject *o2, int *result);
+
+       /*
+	 Compare the values of o1 and o2 using a routine provided by
+	 o1, if one exists, otherwise with a routine provided by o2.
+	 The result of the comparison is returned in result.  Returns
+	 -1 on failure.  This is the equivalent of the Python
+	 statement: result=cmp(o1,o2).
+
+       */
+
+     /* Implemented elsewhere:
+
+     int PyObject_Compare(PyObject *o1, PyObject *o2);
+
+	 Compare the values of o1 and o2 using a routine provided by
+	 o1, if one exists, otherwise with a routine provided by o2.
+	 Returns the result of the comparison on success.  On error,
+	 the value returned is undefined. This is equivalent to the
+	 Python expression: cmp(o1,o2).
+
+       */
+
+     /* Implemented elsewhere:
+
+     PyObject *PyObject_Repr(PyObject *o);
+
+	 Compute the string representation of object, o.  Returns the
+	 string representation on success, NULL on failure.  This is
+	 the equivalent of the Python expression: repr(o).
+
+	 Called by the repr() built-in function and by reverse quotes.
+
+       */
+
+     /* Implemented elsewhere:
+
+     PyObject *PyObject_Str(PyObject *o);
+
+	 Compute the string representation of object, o.  Returns the
+	 string representation on success, NULL on failure.  This is
+	 the equivalent of the Python expression: str(o).)
+
+	 Called by the str() built-in function and by the print
+	 statement.
+
+       */
+
+     /* Implemented elsewhere:
+
+     PyObject *PyObject_Unicode(PyObject *o);
+
+	 Compute the unicode representation of object, o.  Returns the
+	 unicode representation on success, NULL on failure.  This is
+	 the equivalent of the Python expression: unistr(o).)
+
+	 Called by the unistr() built-in function.
+
+       */
+
+       /* Declared elsewhere
+
+     PyAPI_FUNC(int) PyCallable_Check(PyObject *o);
+
+	 Determine if the object, o, is callable.  Return 1 if the
+	 object is callable and 0 otherwise.
+
+	 This function always succeeds.
+
+       */
+
+
+
+     PyAPI_FUNC(PyObject *) PyObject_Call(PyObject *callable_object,
+					 PyObject *args, PyObject *kw);
+
+       /*
+	 Call a callable Python object, callable_object, with
+	 arguments and keywords arguments.  The 'args' argument can not be
+	 NULL, but the 'kw' argument can be NULL.
+
+       */
+     
+     PyAPI_FUNC(PyObject *) PyObject_CallObject(PyObject *callable_object,
+                                               PyObject *args);
+
+       /*
+	 Call a callable Python object, callable_object, with
+	 arguments given by the tuple, args.  If no arguments are
+	 needed, then args may be NULL.  Returns the result of the
+	 call on success, or NULL on failure.  This is the equivalent
+	 of the Python expression: apply(o,args).
+
+       */
+
+     PyAPI_FUNC(PyObject *) PyObject_CallFunction(PyObject *callable_object,
+                                                 char *format, ...);
+
+       /*
+	 Call a callable Python object, callable_object, with a
+	 variable number of C arguments. The C arguments are described
+	 using a mkvalue-style format string. The format may be NULL,
+	 indicating that no arguments are provided.  Returns the
+	 result of the call on success, or NULL on failure.  This is
+	 the equivalent of the Python expression: apply(o,args).
+
+       */
+
+
+     PyAPI_FUNC(PyObject *) PyObject_CallMethod(PyObject *o, char *m,
+                                               char *format, ...);
+
+       /*
+	 Call the method named m of object o with a variable number of
+	 C arguments.  The C arguments are described by a mkvalue
+	 format string.  The format may be NULL, indicating that no
+	 arguments are provided. Returns the result of the call on
+	 success, or NULL on failure.  This is the equivalent of the
+	 Python expression: o.method(args).
+       */
+
+     PyAPI_FUNC(PyObject *) _PyObject_CallFunction_SizeT(PyObject *callable,
+							 char *format, ...);
+     PyAPI_FUNC(PyObject *) _PyObject_CallMethod_SizeT(PyObject *o,
+						       char *name,
+						       char *format, ...);
+
+     PyAPI_FUNC(PyObject *) PyObject_CallFunctionObjArgs(PyObject *callable,
+                                                        ...);
+
+       /*
+	 Call a callable Python object, callable_object, with a
+	 variable number of C arguments.  The C arguments are provided
+	 as PyObject * values, terminated by a NULL.  Returns the
+	 result of the call on success, or NULL on failure.  This is
+	 the equivalent of the Python expression: apply(o,args).
+       */
+
+
+     PyAPI_FUNC(PyObject *) PyObject_CallMethodObjArgs(PyObject *o,
+                                                      PyObject *m, ...);
+
+       /*
+	 Call the method named m of object o with a variable number of
+	 C arguments.  The C arguments are provided as PyObject *
+	 values, terminated by NULL.  Returns the result of the call
+	 on success, or NULL on failure.  This is the equivalent of
+	 the Python expression: o.method(args).
+       */
+
+
+     /* Implemented elsewhere:
+
+     long PyObject_Hash(PyObject *o);
+
+         Compute and return the hash, hash_value, of an object, o.  On
+	 failure, return -1.  This is the equivalent of the Python
+	 expression: hash(o).
+
+       */
+
+
+     /* Implemented elsewhere:
+
+     int PyObject_IsTrue(PyObject *o);
+
+	 Returns 1 if the object, o, is considered to be true, 0 if o is
+	 considered to be false and -1 on failure. This is equivalent to the
+	 Python expression: not not o
+
+       */
+
+     /* Implemented elsewhere:
+
+     int PyObject_Not(PyObject *o);
+
+	 Returns 0 if the object, o, is considered to be true, 1 if o is
+	 considered to be false and -1 on failure. This is equivalent to the
+	 Python expression: not o
+
+       */
+
+     PyAPI_FUNC(PyObject *) PyObject_Type(PyObject *o);
+
+       /*
+	 On success, returns a type object corresponding to the object
+	 type of object o. On failure, returns NULL.  This is
+	 equivalent to the Python expression: type(o).
+       */
+
+     PyAPI_FUNC(Py_ssize_t) PyObject_Size(PyObject *o);
+
+       /*
+         Return the size of object o.  If the object, o, provides
+	 both sequence and mapping protocols, the sequence size is
+	 returned. On error, -1 is returned.  This is the equivalent
+	 to the Python expression: len(o).
+
+       */
+
+       /* For DLL compatibility */
+#undef PyObject_Length
+     PyAPI_FUNC(Py_ssize_t) PyObject_Length(PyObject *o);
+#define PyObject_Length PyObject_Size
+
+     PyAPI_FUNC(Py_ssize_t) _PyObject_LengthHint(PyObject *o);
+
+       /*
+         Return the size of object o.  If the object, o, provides
+	 both sequence and mapping protocols, the sequence size is
+	 returned. On error, -1 is returned.  If the object provides
+	 a __length_hint__() method, its value is returned.  This is an
+	 internal undocumented API provided for performance reasons;
+	 for compatibility, don't use it outside the core.  This is the
+	 equivalent to the Python expression: 
+		try:
+			return len(o)
+		except (AttributeError, TypeError):
+			exc_type, exc_value, exc_tb = sys.exc_info()
+			try:
+				return o.__length_hint__()
+			except:
+				pass
+			raise exc_type, exc_value, exc_tb
+       */
+
+     PyAPI_FUNC(PyObject *) PyObject_GetItem(PyObject *o, PyObject *key);
+
+       /*
+	 Return element of o corresponding to the object, key, or NULL
+	 on failure. This is the equivalent of the Python expression:
+	 o[key].
+
+       */
+
+     PyAPI_FUNC(int) PyObject_SetItem(PyObject *o, PyObject *key, PyObject *v);
+
+       /*
+	 Map the object, key, to the value, v.  Returns
+	 -1 on failure.  This is the equivalent of the Python
+	 statement: o[key]=v.
+       */
+
+     PyAPI_FUNC(int) PyObject_DelItemString(PyObject *o, char *key);
+
+       /*
+         Remove the mapping for object, key, from the object *o.
+         Returns -1 on failure.  This is equivalent to
+         the Python statement: del o[key].
+       */
+
+     PyAPI_FUNC(int) PyObject_DelItem(PyObject *o, PyObject *key);
+
+       /*
+	 Delete the mapping for key from *o.  Returns -1 on failure.
+	 This is the equivalent of the Python statement: del o[key].
+       */
+
+     PyAPI_FUNC(int) PyObject_AsCharBuffer(PyObject *obj,
+					  const char **buffer,
+					  Py_ssize_t *buffer_len);
+
+       /* 
+	  Takes an arbitrary object which must support the (character,
+	  single segment) buffer interface and returns a pointer to a
+	  read-only memory location useable as character based input
+	  for subsequent processing.
+
+	  0 is returned on success.  buffer and buffer_len are only
+	  set in case no error occurs. Otherwise, -1 is returned and
+	  an exception set.
+
+       */
+
+     PyAPI_FUNC(int) PyObject_CheckReadBuffer(PyObject *obj);
+
+      /*  
+	  Checks whether an arbitrary object supports the (character,
+	  single segment) buffer interface.  Returns 1 on success, 0
+	  on failure.
+
+      */
+
+     PyAPI_FUNC(int) PyObject_AsReadBuffer(PyObject *obj,
+					  const void **buffer,
+					  Py_ssize_t *buffer_len);
+
+       /* 
+	  Same as PyObject_AsCharBuffer() except that this API expects
+	  (readable, single segment) buffer interface and returns a
+	  pointer to a read-only memory location which can contain
+	  arbitrary data.
+
+	  0 is returned on success.  buffer and buffer_len are only
+	  set in case no error occurrs.  Otherwise, -1 is returned and
+	  an exception set.
+
+       */
+
+     PyAPI_FUNC(int) PyObject_AsWriteBuffer(PyObject *obj,
+					   void **buffer,
+					   Py_ssize_t *buffer_len);
+
+       /* 
+	  Takes an arbitrary object which must support the (writeable,
+	  single segment) buffer interface and returns a pointer to a
+	  writeable memory location in buffer of size buffer_len.
+
+	  0 is returned on success.  buffer and buffer_len are only
+	  set in case no error occurrs. Otherwise, -1 is returned and
+	  an exception set.
+
+       */
+
+/* Iterators */
+
+     PyAPI_FUNC(PyObject *) PyObject_GetIter(PyObject *);
+     /* Takes an object and returns an iterator for it.
+        This is typically a new iterator but if the argument
+	is an iterator, this returns itself. */
+
+#define PyIter_Check(obj) \
+    (PyType_HasFeature((obj)->ob_type, Py_TPFLAGS_HAVE_ITER) && \
+     (obj)->ob_type->tp_iternext != NULL)
+
+     PyAPI_FUNC(PyObject *) PyIter_Next(PyObject *);
+     /* Takes an iterator object and calls its tp_iternext slot,
+	returning the next value.  If the iterator is exhausted,
+	this returns NULL without setting an exception.
+	NULL with an exception means an error occurred. */
+
+/*  Number Protocol:*/
+
+     PyAPI_FUNC(int) PyNumber_Check(PyObject *o);
+
+       /*
+         Returns 1 if the object, o, provides numeric protocols, and
+	 false otherwise. 
+
+	 This function always succeeds.
+
+       */
+
+     PyAPI_FUNC(PyObject *) PyNumber_Add(PyObject *o1, PyObject *o2);
+
+       /*
+	 Returns the result of adding o1 and o2, or null on failure.
+	 This is the equivalent of the Python expression: o1+o2.
+
+
+       */
+
+     PyAPI_FUNC(PyObject *) PyNumber_Subtract(PyObject *o1, PyObject *o2);
+
+       /*
+	 Returns the result of subtracting o2 from o1, or null on
+	 failure.  This is the equivalent of the Python expression:
+	 o1-o2.
+
+       */
+
+     PyAPI_FUNC(PyObject *) PyNumber_Multiply(PyObject *o1, PyObject *o2);
+
+       /*
+	 Returns the result of multiplying o1 and o2, or null on
+	 failure.  This is the equivalent of the Python expression:
+	 o1*o2.
+
+
+       */
+
+     PyAPI_FUNC(PyObject *) PyNumber_Divide(PyObject *o1, PyObject *o2);
+
+       /*
+	 Returns the result of dividing o1 by o2, or null on failure.
+	 This is the equivalent of the Python expression: o1/o2.
+
+
+       */
+
+     PyAPI_FUNC(PyObject *) PyNumber_FloorDivide(PyObject *o1, PyObject *o2);
+
+       /*
+	 Returns the result of dividing o1 by o2 giving an integral result,
+	 or null on failure.
+	 This is the equivalent of the Python expression: o1//o2.
+
+
+       */
+
+     PyAPI_FUNC(PyObject *) PyNumber_TrueDivide(PyObject *o1, PyObject *o2);
+
+       /*
+	 Returns the result of dividing o1 by o2 giving a float result,
+	 or null on failure.
+	 This is the equivalent of the Python expression: o1/o2.
+
+
+       */
+
+     PyAPI_FUNC(PyObject *) PyNumber_Remainder(PyObject *o1, PyObject *o2);
+
+       /*
+	 Returns the remainder of dividing o1 by o2, or null on
+	 failure.  This is the equivalent of the Python expression:
+	 o1%o2.
+
+
+       */
+
+     PyAPI_FUNC(PyObject *) PyNumber_Divmod(PyObject *o1, PyObject *o2);
+
+       /*
+	 See the built-in function divmod.  Returns NULL on failure.
+	 This is the equivalent of the Python expression:
+	 divmod(o1,o2).
+
+
+       */
+
+     PyAPI_FUNC(PyObject *) PyNumber_Power(PyObject *o1, PyObject *o2,
+                                          PyObject *o3);
+
+       /*
+	 See the built-in function pow.  Returns NULL on failure.
+	 This is the equivalent of the Python expression:
+	 pow(o1,o2,o3), where o3 is optional.
+
+       */
+
+     PyAPI_FUNC(PyObject *) PyNumber_Negative(PyObject *o);
+
+       /*
+	 Returns the negation of o on success, or null on failure.
+	 This is the equivalent of the Python expression: -o.
+
+       */
+
+     PyAPI_FUNC(PyObject *) PyNumber_Positive(PyObject *o);
+
+       /*
+         Returns the (what?) of o on success, or NULL on failure.
+	 This is the equivalent of the Python expression: +o.
+
+       */
+
+     PyAPI_FUNC(PyObject *) PyNumber_Absolute(PyObject *o);
+
+       /*
+	 Returns the absolute value of o, or null on failure.  This is
+	 the equivalent of the Python expression: abs(o).
+
+       */
+
+     PyAPI_FUNC(PyObject *) PyNumber_Invert(PyObject *o);
+
+       /*
+	 Returns the bitwise negation of o on success, or NULL on
+	 failure.  This is the equivalent of the Python expression:
+	 ~o.
+
+
+       */
+
+     PyAPI_FUNC(PyObject *) PyNumber_Lshift(PyObject *o1, PyObject *o2);
+
+       /*
+	 Returns the result of left shifting o1 by o2 on success, or
+	 NULL on failure.  This is the equivalent of the Python
+	 expression: o1 << o2.
+
+
+       */
+
+     PyAPI_FUNC(PyObject *) PyNumber_Rshift(PyObject *o1, PyObject *o2);
+
+       /*
+	 Returns the result of right shifting o1 by o2 on success, or
+	 NULL on failure.  This is the equivalent of the Python
+	 expression: o1 >> o2.
+
+       */
+
+     PyAPI_FUNC(PyObject *) PyNumber_And(PyObject *o1, PyObject *o2);
+
+       /*
+	 Returns the result of bitwise and of o1 and o2 on success, or
+	 NULL on failure. This is the equivalent of the Python
+	 expression: o1&o2.
+
+
+       */
+
+     PyAPI_FUNC(PyObject *) PyNumber_Xor(PyObject *o1, PyObject *o2);
+
+       /*
+	 Returns the bitwise exclusive or of o1 by o2 on success, or
+	 NULL on failure.  This is the equivalent of the Python
+	 expression: o1^o2.
+
+
+       */
+
+     PyAPI_FUNC(PyObject *) PyNumber_Or(PyObject *o1, PyObject *o2);
+
+       /*
+	 Returns the result of bitwise or on o1 and o2 on success, or
+	 NULL on failure.  This is the equivalent of the Python
+	 expression: o1|o2.
+
+       */
+
+     /* Implemented elsewhere:
+
+     int PyNumber_Coerce(PyObject **p1, PyObject **p2);
+
+	 This function takes the addresses of two variables of type
+	 PyObject*.
+
+	 If the objects pointed to by *p1 and *p2 have the same type,
+	 increment their reference count and return 0 (success).
+	 If the objects can be converted to a common numeric type,
+	 replace *p1 and *p2 by their converted value (with 'new'
+	 reference counts), and return 0.
+	 If no conversion is possible, or if some other error occurs,
+	 return -1 (failure) and don't increment the reference counts.
+	 The call PyNumber_Coerce(&o1, &o2) is equivalent to the Python
+	 statement o1, o2 = coerce(o1, o2).
+
+       */
+
+#define PyIndex_Check(obj) \
+   ((obj)->ob_type->tp_as_number != NULL && \
+    PyType_HasFeature((obj)->ob_type, Py_TPFLAGS_HAVE_INDEX) && \
+    (obj)->ob_type->tp_as_number->nb_index != NULL)
+        
+     PyAPI_FUNC(PyObject *) PyNumber_Index(PyObject *o);
+
+       /*
+	 Returns the object converted to a Python long or int
+	 or NULL with an error raised on failure.
+       */
+
+     PyAPI_FUNC(Py_ssize_t) PyNumber_AsSsize_t(PyObject *o, PyObject *exc);
+
+       /*
+        Returns the object converted to Py_ssize_t by going through
+        PyNumber_Index first.  If an overflow error occurs while
+        converting the int-or-long to Py_ssize_t, then the second argument
+        is the error-type to return.  If it is NULL, then the overflow error
+        is cleared and the value is clipped. 
+       */
+
+     PyAPI_FUNC(PyObject *) PyNumber_Int(PyObject *o);
+
+       /*
+	 Returns the o converted to an integer object on success, or
+	 NULL on failure.  This is the equivalent of the Python
+	 expression: int(o).
+
+       */
+
+     PyAPI_FUNC(PyObject *) PyNumber_Long(PyObject *o);
+
+       /*
+	 Returns the o converted to a long integer object on success,
+	 or NULL on failure.  This is the equivalent of the Python
+	 expression: long(o).
+
+       */
+
+     PyAPI_FUNC(PyObject *) PyNumber_Float(PyObject *o);
+
+       /*
+	 Returns the o converted to a float object on success, or NULL
+	 on failure.  This is the equivalent of the Python expression:
+	 float(o).
+       */
+	 
+/*  In-place variants of (some of) the above number protocol functions */
+
+     PyAPI_FUNC(PyObject *) PyNumber_InPlaceAdd(PyObject *o1, PyObject *o2);
+
+       /*
+	 Returns the result of adding o2 to o1, possibly in-place, or null
+	 on failure.  This is the equivalent of the Python expression:
+	 o1 += o2.
+
+       */
+
+     PyAPI_FUNC(PyObject *) PyNumber_InPlaceSubtract(PyObject *o1, PyObject *o2);
+
+       /*
+	 Returns the result of subtracting o2 from o1, possibly in-place or
+	 null on failure.  This is the equivalent of the Python expression:
+	 o1 -= o2.
+
+       */
+
+     PyAPI_FUNC(PyObject *) PyNumber_InPlaceMultiply(PyObject *o1, PyObject *o2);
+
+       /*
+	 Returns the result of multiplying o1 by o2, possibly in-place, or
+	 null on failure.  This is the equivalent of the Python expression:
+	 o1 *= o2.
+
+       */
+
+     PyAPI_FUNC(PyObject *) PyNumber_InPlaceDivide(PyObject *o1, PyObject *o2);
+
+       /*
+	 Returns the result of dividing o1 by o2, possibly in-place, or null
+	 on failure.  This is the equivalent of the Python expression:
+	 o1 /= o2.
+
+       */
+
+     PyAPI_FUNC(PyObject *) PyNumber_InPlaceFloorDivide(PyObject *o1,
+						       PyObject *o2);
+
+       /*
+	 Returns the result of dividing o1 by o2 giving an integral result,
+	 possibly in-place, or null on failure.
+	 This is the equivalent of the Python expression:
+	 o1 /= o2.
+
+       */
+
+     PyAPI_FUNC(PyObject *) PyNumber_InPlaceTrueDivide(PyObject *o1,
+						      PyObject *o2);
+
+       /*
+	 Returns the result of dividing o1 by o2 giving a float result,
+	 possibly in-place, or null on failure.
+	 This is the equivalent of the Python expression:
+	 o1 /= o2.
+
+       */
+
+     PyAPI_FUNC(PyObject *) PyNumber_InPlaceRemainder(PyObject *o1, PyObject *o2);
+
+       /*
+	 Returns the remainder of dividing o1 by o2, possibly in-place, or
+	 null on failure.  This is the equivalent of the Python expression:
+	 o1 %= o2.
+
+       */
+
+     PyAPI_FUNC(PyObject *) PyNumber_InPlacePower(PyObject *o1, PyObject *o2,
+     						 PyObject *o3);
+
+       /*
+	 Returns the result of raising o1 to the power of o2, possibly
+	 in-place, or null on failure.  This is the equivalent of the Python
+	 expression: o1 **= o2, or pow(o1, o2, o3) if o3 is present.
+
+       */
+
+     PyAPI_FUNC(PyObject *) PyNumber_InPlaceLshift(PyObject *o1, PyObject *o2);
+
+       /*
+	 Returns the result of left shifting o1 by o2, possibly in-place, or
+	 null on failure.  This is the equivalent of the Python expression:
+	 o1 <<= o2.
+
+       */
+
+     PyAPI_FUNC(PyObject *) PyNumber_InPlaceRshift(PyObject *o1, PyObject *o2);
+
+       /*
+	 Returns the result of right shifting o1 by o2, possibly in-place or
+	 null on failure.  This is the equivalent of the Python expression:
+	 o1 >>= o2.
+
+       */
+
+     PyAPI_FUNC(PyObject *) PyNumber_InPlaceAnd(PyObject *o1, PyObject *o2);
+
+       /*
+	 Returns the result of bitwise and of o1 and o2, possibly in-place,
+	 or null on failure. This is the equivalent of the Python
+	 expression: o1 &= o2.
+
+       */
+
+     PyAPI_FUNC(PyObject *) PyNumber_InPlaceXor(PyObject *o1, PyObject *o2);
+
+       /*
+	 Returns the bitwise exclusive or of o1 by o2, possibly in-place, or
+	 null on failure.  This is the equivalent of the Python expression:
+	 o1 ^= o2.
+
+       */
+
+     PyAPI_FUNC(PyObject *) PyNumber_InPlaceOr(PyObject *o1, PyObject *o2);
+
+       /*
+	 Returns the result of bitwise or of o1 and o2, possibly in-place,
+	 or null on failure.  This is the equivalent of the Python
+	 expression: o1 |= o2.
+
+       */
+
+
+/*  Sequence protocol:*/
+
+     PyAPI_FUNC(int) PySequence_Check(PyObject *o);
+
+       /*
+         Return 1 if the object provides sequence protocol, and zero
+	 otherwise.  
+
+	 This function always succeeds.
+
+       */
+
+     PyAPI_FUNC(Py_ssize_t) PySequence_Size(PyObject *o);
+
+       /*
+         Return the size of sequence object o, or -1 on failure.
+
+       */
+
+       /* For DLL compatibility */
+#undef PySequence_Length
+     PyAPI_FUNC(Py_ssize_t) PySequence_Length(PyObject *o);
+#define PySequence_Length PySequence_Size
+
+
+     PyAPI_FUNC(PyObject *) PySequence_Concat(PyObject *o1, PyObject *o2);
+
+       /*
+	 Return the concatenation of o1 and o2 on success, and NULL on
+	 failure.   This is the equivalent of the Python
+	 expression: o1+o2.
+
+       */
+
+     PyAPI_FUNC(PyObject *) PySequence_Repeat(PyObject *o, Py_ssize_t count);
+
+       /*
+	 Return the result of repeating sequence object o count times,
+	 or NULL on failure.  This is the equivalent of the Python
+	 expression: o1*count.
+
+       */
+
+     PyAPI_FUNC(PyObject *) PySequence_GetItem(PyObject *o, Py_ssize_t i);
+
+       /*
+	 Return the ith element of o, or NULL on failure. This is the
+	 equivalent of the Python expression: o[i].
+       */
+
+     PyAPI_FUNC(PyObject *) PySequence_GetSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2);
+
+       /*
+	 Return the slice of sequence object o between i1 and i2, or
+	 NULL on failure. This is the equivalent of the Python
+	 expression: o[i1:i2].
+
+       */
+
+     PyAPI_FUNC(int) PySequence_SetItem(PyObject *o, Py_ssize_t i, PyObject *v);
+
+       /*
+	 Assign object v to the ith element of o.  Returns
+	 -1 on failure.  This is the equivalent of the Python
+	 statement: o[i]=v.
+
+       */
+
+     PyAPI_FUNC(int) PySequence_DelItem(PyObject *o, Py_ssize_t i);
+
+       /*
+	 Delete the ith element of object v.  Returns
+	 -1 on failure.  This is the equivalent of the Python
+	 statement: del o[i].
+       */
+
+     PyAPI_FUNC(int) PySequence_SetSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2,
+                                        PyObject *v);
+
+       /*
+         Assign the sequence object, v, to the slice in sequence
+	 object, o, from i1 to i2.  Returns -1 on failure. This is the
+	 equivalent of the Python statement: o[i1:i2]=v.
+       */
+
+     PyAPI_FUNC(int) PySequence_DelSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2);
+
+       /*
+	 Delete the slice in sequence object, o, from i1 to i2.
+	 Returns -1 on failure. This is the equivalent of the Python
+	 statement: del o[i1:i2].
+       */
+
+     PyAPI_FUNC(PyObject *) PySequence_Tuple(PyObject *o);
+
+       /*
+	 Returns the sequence, o, as a tuple on success, and NULL on failure.
+	 This is equivalent to the Python expression: tuple(o)
+       */
+
+
+     PyAPI_FUNC(PyObject *) PySequence_List(PyObject *o);
+       /*
+	 Returns the sequence, o, as a list on success, and NULL on failure.
+	 This is equivalent to the Python expression: list(o)
+       */
+
+     PyAPI_FUNC(PyObject *) PySequence_Fast(PyObject *o, const char* m);
+       /*
+         Returns the sequence, o, as a tuple, unless it's already a
+         tuple or list.  Use PySequence_Fast_GET_ITEM to access the
+         members of this list, and PySequence_Fast_GET_SIZE to get its length.
+
+         Returns NULL on failure.  If the object does not support iteration,
+         raises a TypeError exception with m as the message text.
+       */
+
+#define PySequence_Fast_GET_SIZE(o) \
+	(PyList_Check(o) ? PyList_GET_SIZE(o) : PyTuple_GET_SIZE(o))
+       /*
+	 Return the size of o, assuming that o was returned by
+         PySequence_Fast and is not NULL.
+       */
+
+#define PySequence_Fast_GET_ITEM(o, i)\
+     (PyList_Check(o) ? PyList_GET_ITEM(o, i) : PyTuple_GET_ITEM(o, i))
+       /*
+	 Return the ith element of o, assuming that o was returned by
+         PySequence_Fast, and that i is within bounds.
+       */
+
+#define PySequence_ITEM(o, i)\
+	( o->ob_type->tp_as_sequence->sq_item(o, i) )
+       /* Assume tp_as_sequence and sq_item exist and that i does not
+	  need to be corrected for a negative index
+       */     
+
+#define PySequence_Fast_ITEMS(sf) \
+	(PyList_Check(sf) ? ((PyListObject *)(sf))->ob_item \
+			  : ((PyTupleObject *)(sf))->ob_item)
+	/* Return a pointer to the underlying item array for
+           an object retured by PySequence_Fast */
+
+     PyAPI_FUNC(Py_ssize_t) PySequence_Count(PyObject *o, PyObject *value);
+
+       /*
+         Return the number of occurrences on value on o, that is,
+	 return the number of keys for which o[key]==value.  On
+	 failure, return -1.  This is equivalent to the Python
+	 expression: o.count(value).
+       */
+
+     PyAPI_FUNC(int) PySequence_Contains(PyObject *seq, PyObject *ob);
+       /*
+         Return -1 if error; 1 if ob in seq; 0 if ob not in seq.
+         Use __contains__ if possible, else _PySequence_IterSearch().
+       */
+
+#define PY_ITERSEARCH_COUNT    1
+#define PY_ITERSEARCH_INDEX    2
+#define PY_ITERSEARCH_CONTAINS 3
+     PyAPI_FUNC(Py_ssize_t) _PySequence_IterSearch(PyObject *seq,
+     					PyObject *obj, int operation);
+	/*
+	  Iterate over seq.  Result depends on the operation:
+	  PY_ITERSEARCH_COUNT:  return # of times obj appears in seq; -1 if
+	  	error.
+	  PY_ITERSEARCH_INDEX:  return 0-based index of first occurrence of
+	  	obj in seq; set ValueError and return -1 if none found;
+	  	also return -1 on error.
+	  PY_ITERSEARCH_CONTAINS:  return 1 if obj in seq, else 0; -1 on
+	  	error.
+	*/
+
+/* For DLL-level backwards compatibility */
+#undef PySequence_In
+     PyAPI_FUNC(int) PySequence_In(PyObject *o, PyObject *value);
+
+/* For source-level backwards compatibility */
+#define PySequence_In PySequence_Contains
+
+       /*
+	 Determine if o contains value.  If an item in o is equal to
+	 X, return 1, otherwise return 0.  On error, return -1.  This
+	 is equivalent to the Python expression: value in o.
+       */
+
+     PyAPI_FUNC(Py_ssize_t) PySequence_Index(PyObject *o, PyObject *value);
+
+       /*
+	 Return the first index for which o[i]=value.  On error,
+	 return -1.    This is equivalent to the Python
+	 expression: o.index(value).
+       */
+
+/* In-place versions of some of the above Sequence functions. */
+
+     PyAPI_FUNC(PyObject *) PySequence_InPlaceConcat(PyObject *o1, PyObject *o2);
+
+       /*
+	 Append o2 to o1, in-place when possible. Return the resulting
+	 object, which could be o1, or NULL on failure.  This is the
+	 equivalent of the Python expression: o1 += o2.
+
+       */
+
+     PyAPI_FUNC(PyObject *) PySequence_InPlaceRepeat(PyObject *o, Py_ssize_t count);
+
+       /*
+	 Repeat o1 by count, in-place when possible. Return the resulting
+	 object, which could be o1, or NULL on failure.  This is the
+	 equivalent of the Python expression: o1 *= count.
+
+       */
+
+/*  Mapping protocol:*/
+
+     PyAPI_FUNC(int) PyMapping_Check(PyObject *o);
+
+       /*
+         Return 1 if the object provides mapping protocol, and zero
+	 otherwise.  
+
+	 This function always succeeds.
+       */
+
+     PyAPI_FUNC(Py_ssize_t) PyMapping_Size(PyObject *o);
+
+       /*
+         Returns the number of keys in object o on success, and -1 on
+	 failure.  For objects that do not provide sequence protocol,
+	 this is equivalent to the Python expression: len(o).
+       */
+
+       /* For DLL compatibility */
+#undef PyMapping_Length
+     PyAPI_FUNC(Py_ssize_t) PyMapping_Length(PyObject *o);
+#define PyMapping_Length PyMapping_Size
+
+
+     /* implemented as a macro:
+
+     int PyMapping_DelItemString(PyObject *o, char *key);
+
+	 Remove the mapping for object, key, from the object *o.
+	 Returns -1 on failure.  This is equivalent to
+	 the Python statement: del o[key].
+       */
+#define PyMapping_DelItemString(O,K) PyObject_DelItemString((O),(K))
+
+     /* implemented as a macro:
+
+     int PyMapping_DelItem(PyObject *o, PyObject *key);
+
+	 Remove the mapping for object, key, from the object *o.
+	 Returns -1 on failure.  This is equivalent to
+	 the Python statement: del o[key].
+       */
+#define PyMapping_DelItem(O,K) PyObject_DelItem((O),(K))
+
+     PyAPI_FUNC(int) PyMapping_HasKeyString(PyObject *o, char *key);
+
+       /*
+	 On success, return 1 if the mapping object has the key, key,
+	 and 0 otherwise.  This is equivalent to the Python expression:
+	 o.has_key(key). 
+
+	 This function always succeeds.
+       */
+
+     PyAPI_FUNC(int) PyMapping_HasKey(PyObject *o, PyObject *key);
+
+       /*
+	 Return 1 if the mapping object has the key, key,
+	 and 0 otherwise.  This is equivalent to the Python expression:
+	 o.has_key(key). 
+
+	 This function always succeeds.
+
+       */
+
+     /* Implemented as macro:
+
+     PyObject *PyMapping_Keys(PyObject *o);
+
+         On success, return a list of the keys in object o.  On
+	 failure, return NULL. This is equivalent to the Python
+	 expression: o.keys().
+       */
+#define PyMapping_Keys(O) PyObject_CallMethod(O,"keys",NULL)
+
+     /* Implemented as macro:
+
+     PyObject *PyMapping_Values(PyObject *o);
+
+         On success, return a list of the values in object o.  On
+	 failure, return NULL. This is equivalent to the Python
+	 expression: o.values().
+       */
+#define PyMapping_Values(O) PyObject_CallMethod(O,"values",NULL)
+
+     /* Implemented as macro:
+
+     PyObject *PyMapping_Items(PyObject *o);
+
+         On success, return a list of the items in object o, where
+	 each item is a tuple containing a key-value pair.  On
+	 failure, return NULL. This is equivalent to the Python
+	 expression: o.items().
+
+       */
+#define PyMapping_Items(O) PyObject_CallMethod(O,"items",NULL)
+
+     PyAPI_FUNC(PyObject *) PyMapping_GetItemString(PyObject *o, char *key);
+
+       /*
+	 Return element of o corresponding to the object, key, or NULL
+	 on failure. This is the equivalent of the Python expression:
+	 o[key].
+       */
+
+     PyAPI_FUNC(int) PyMapping_SetItemString(PyObject *o, char *key,
+                                            PyObject *value);
+
+       /*
+	 Map the object, key, to the value, v.  Returns 
+	 -1 on failure.  This is the equivalent of the Python
+	 statement: o[key]=v.
+      */
+
+
+PyAPI_FUNC(int) PyObject_IsInstance(PyObject *object, PyObject *typeorclass);
+      /* isinstance(object, typeorclass) */
+
+PyAPI_FUNC(int) PyObject_IsSubclass(PyObject *object, PyObject *typeorclass);
+      /* issubclass(object, typeorclass) */
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* Py_ABSTRACTOBJECT_H */

Added: vendor/Python/current/Include/asdl.h
===================================================================
--- vendor/Python/current/Include/asdl.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/asdl.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,45 @@
+#ifndef Py_ASDL_H
+#define Py_ASDL_H
+
+typedef PyObject * identifier;
+typedef PyObject * string;
+typedef PyObject * object;
+
+#ifndef __cplusplus
+typedef enum {false, true} bool;
+#endif
+
+/* It would be nice if the code generated by asdl_c.py was completely
+   independent of Python, but it is a goal the requires too much work
+   at this stage.  So, for example, I'll represent identifiers as
+   interned Python strings.
+*/
+
+/* XXX A sequence should be typed so that its use can be typechecked. */
+
+typedef struct {
+    int size;
+    void *elements[1];
+} asdl_seq;
+
+typedef struct {
+    int size;
+    int elements[1];
+} asdl_int_seq;
+
+asdl_seq *asdl_seq_new(int size, PyArena *arena);
+asdl_int_seq *asdl_int_seq_new(int size, PyArena *arena);
+
+#define asdl_seq_GET(S, I) (S)->elements[(I)]
+#define asdl_seq_LEN(S) ((S) == NULL ? 0 : (S)->size)
+#ifdef Py_DEBUG
+#define asdl_seq_SET(S, I, V) { \
+        int _asdl_i = (I); \
+        assert((S) && _asdl_i < (S)->size); \
+        (S)->elements[_asdl_i] = (V); \
+}
+#else
+#define asdl_seq_SET(S, I, V) (S)->elements[I] = (V)
+#endif
+
+#endif /* !Py_ASDL_H */

Added: vendor/Python/current/Include/ast.h
===================================================================
--- vendor/Python/current/Include/ast.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/ast.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,13 @@
+#ifndef Py_AST_H
+#define Py_AST_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+PyAPI_FUNC(mod_ty) PyAST_FromNode(const node *, PyCompilerFlags *flags,
+				  const char *, PyArena *);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_AST_H */

Added: vendor/Python/current/Include/bitset.h
===================================================================
--- vendor/Python/current/Include/bitset.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/bitset.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,32 @@
+
+#ifndef Py_BITSET_H
+#define Py_BITSET_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Bitset interface */
+
+#define BYTE		char
+
+typedef BYTE *bitset;
+
+bitset newbitset(int nbits);
+void delbitset(bitset bs);
+#define testbit(ss, ibit) (((ss)[BIT2BYTE(ibit)] & BIT2MASK(ibit)) != 0)
+int addbit(bitset bs, int ibit); /* Returns 0 if already set */
+int samebitset(bitset bs1, bitset bs2, int nbits);
+void mergebitset(bitset bs1, bitset bs2, int nbits);
+
+#define BITSPERBYTE	(8*sizeof(BYTE))
+#define NBYTES(nbits)	(((nbits) + BITSPERBYTE - 1) / BITSPERBYTE)
+
+#define BIT2BYTE(ibit)	((ibit) / BITSPERBYTE)
+#define BIT2SHIFT(ibit)	((ibit) % BITSPERBYTE)
+#define BIT2MASK(ibit)	(1 << BIT2SHIFT(ibit))
+#define BYTE2BIT(ibyte)	((ibyte) * BITSPERBYTE)
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_BITSET_H */

Added: vendor/Python/current/Include/boolobject.h
===================================================================
--- vendor/Python/current/Include/boolobject.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/boolobject.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,36 @@
+/* Boolean object interface */
+
+#ifndef Py_BOOLOBJECT_H
+#define Py_BOOLOBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+typedef PyIntObject PyBoolObject;
+
+PyAPI_DATA(PyTypeObject) PyBool_Type;
+
+#define PyBool_Check(x) ((x)->ob_type == &PyBool_Type)
+
+/* Py_False and Py_True are the only two bools in existence.
+Don't forget to apply Py_INCREF() when returning either!!! */
+
+/* Don't use these directly */
+PyAPI_DATA(PyIntObject) _Py_ZeroStruct, _Py_TrueStruct;
+
+/* Use these macros */
+#define Py_False ((PyObject *) &_Py_ZeroStruct)
+#define Py_True ((PyObject *) &_Py_TrueStruct)
+
+/* Macros for returning Py_True or Py_False, respectively */
+#define Py_RETURN_TRUE return Py_INCREF(Py_True), Py_True
+#define Py_RETURN_FALSE return Py_INCREF(Py_False), Py_False
+
+/* Function to return a bool from a C long */
+PyAPI_FUNC(PyObject *) PyBool_FromLong(long);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_BOOLOBJECT_H */

Added: vendor/Python/current/Include/bufferobject.h
===================================================================
--- vendor/Python/current/Include/bufferobject.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/bufferobject.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,33 @@
+
+/* Buffer object interface */
+
+/* Note: the object's structure is private */
+
+#ifndef Py_BUFFEROBJECT_H
+#define Py_BUFFEROBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+PyAPI_DATA(PyTypeObject) PyBuffer_Type;
+
+#define PyBuffer_Check(op) ((op)->ob_type == &PyBuffer_Type)
+
+#define Py_END_OF_BUFFER	(-1)
+
+PyAPI_FUNC(PyObject *) PyBuffer_FromObject(PyObject *base,
+                                           Py_ssize_t offset, Py_ssize_t size);
+PyAPI_FUNC(PyObject *) PyBuffer_FromReadWriteObject(PyObject *base,
+                                                    Py_ssize_t offset,
+                                                    Py_ssize_t size);
+
+PyAPI_FUNC(PyObject *) PyBuffer_FromMemory(void *ptr, Py_ssize_t size);
+PyAPI_FUNC(PyObject *) PyBuffer_FromReadWriteMemory(void *ptr, Py_ssize_t size);
+
+PyAPI_FUNC(PyObject *) PyBuffer_New(Py_ssize_t size);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_BUFFEROBJECT_H */

Added: vendor/Python/current/Include/cStringIO.h
===================================================================
--- vendor/Python/current/Include/cStringIO.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/cStringIO.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,70 @@
+#ifndef Py_CSTRINGIO_H
+#define Py_CSTRINGIO_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+
+  This header provides access to cStringIO objects from C.
+  Functions are provided for calling cStringIO objects and
+  macros are provided for testing whether you have cStringIO 
+  objects.
+
+  Before calling any of the functions or macros, you must initialize
+  the routines with:
+
+    PycString_IMPORT
+
+  This would typically be done in your init function.
+
+*/
+#define PycString_IMPORT \
+  PycStringIO = (struct PycStringIO_CAPI*)PyCObject_Import("cStringIO", \
+                                                           "cStringIO_CAPI")
+
+/* Basic functions to manipulate cStringIO objects from C */
+
+static struct PycStringIO_CAPI {
+  
+ /* Read a string from an input object.  If the last argument
+    is -1, the remainder will be read.
+    */
+  int(*cread)(PyObject *, char **, Py_ssize_t);
+
+ /* Read a line from an input object.  Returns the length of the read
+    line as an int and a pointer inside the object buffer as char** (so
+    the caller doesn't have to provide its own buffer as destination).
+    */
+  int(*creadline)(PyObject *, char **);
+
+  /* Write a string to an output object*/
+  int(*cwrite)(PyObject *, const char *, Py_ssize_t);
+
+  /* Get the output object as a Python string (returns new reference). */
+  PyObject *(*cgetvalue)(PyObject *);
+
+  /* Create a new output object */
+  PyObject *(*NewOutput)(int);
+
+  /* Create an input object from a Python string
+     (copies the Python string reference).
+     */
+  PyObject *(*NewInput)(PyObject *);
+
+  /* The Python types for cStringIO input and output objects.
+     Note that you can do input on an output object.
+     */
+  PyTypeObject *InputType, *OutputType;
+
+} *PycStringIO;
+
+/* These can be used to test if you have one */
+#define PycStringIO_InputCheck(O) \
+  ((O)->ob_type==PycStringIO->InputType)
+#define PycStringIO_OutputCheck(O) \
+  ((O)->ob_type==PycStringIO->OutputType)
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_CSTRINGIO_H */

Added: vendor/Python/current/Include/cellobject.h
===================================================================
--- vendor/Python/current/Include/cellobject.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/cellobject.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,28 @@
+/* Cell object interface */
+
+#ifndef Py_CELLOBJECT_H
+#define Py_CELLOBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+	PyObject_HEAD
+	PyObject *ob_ref;	/* Content of the cell or NULL when empty */
+} PyCellObject;
+
+PyAPI_DATA(PyTypeObject) PyCell_Type;
+
+#define PyCell_Check(op) ((op)->ob_type == &PyCell_Type)
+
+PyAPI_FUNC(PyObject *) PyCell_New(PyObject *);
+PyAPI_FUNC(PyObject *) PyCell_Get(PyObject *);
+PyAPI_FUNC(int) PyCell_Set(PyObject *, PyObject *);
+
+#define PyCell_GET(op) (((PyCellObject *)(op))->ob_ref)
+#define PyCell_SET(op, v) (((PyCellObject *)(op))->ob_ref = v)
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_TUPLEOBJECT_H */

Added: vendor/Python/current/Include/ceval.h
===================================================================
--- vendor/Python/current/Include/ceval.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/ceval.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,157 @@
+#ifndef Py_CEVAL_H
+#define Py_CEVAL_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Interface to random parts in ceval.c */
+
+PyAPI_FUNC(PyObject *) PyEval_CallObjectWithKeywords(
+	PyObject *, PyObject *, PyObject *);
+
+/* DLL-level Backwards compatibility: */
+#undef PyEval_CallObject
+PyAPI_FUNC(PyObject *) PyEval_CallObject(PyObject *, PyObject *);
+
+/* Inline this */
+#define PyEval_CallObject(func,arg) \
+        PyEval_CallObjectWithKeywords(func, arg, (PyObject *)NULL)
+
+PyAPI_FUNC(PyObject *) PyEval_CallFunction(PyObject *obj,
+                                           const char *format, ...);
+PyAPI_FUNC(PyObject *) PyEval_CallMethod(PyObject *obj,
+                                         const char *methodname,
+                                         const char *format, ...);
+
+PyAPI_FUNC(void) PyEval_SetProfile(Py_tracefunc, PyObject *);
+PyAPI_FUNC(void) PyEval_SetTrace(Py_tracefunc, PyObject *);
+
+struct _frame; /* Avoid including frameobject.h */
+
+PyAPI_FUNC(PyObject *) PyEval_GetBuiltins(void);
+PyAPI_FUNC(PyObject *) PyEval_GetGlobals(void);
+PyAPI_FUNC(PyObject *) PyEval_GetLocals(void);
+PyAPI_FUNC(struct _frame *) PyEval_GetFrame(void);
+PyAPI_FUNC(int) PyEval_GetRestricted(void);
+
+/* Look at the current frame's (if any) code's co_flags, and turn on
+   the corresponding compiler flags in cf->cf_flags.  Return 1 if any
+   flag was set, else return 0. */
+PyAPI_FUNC(int) PyEval_MergeCompilerFlags(PyCompilerFlags *cf);
+
+PyAPI_FUNC(int) Py_FlushLine(void);
+
+PyAPI_FUNC(int) Py_AddPendingCall(int (*func)(void *), void *arg);
+PyAPI_FUNC(int) Py_MakePendingCalls(void);
+
+/* Protection against deeply nested recursive calls */
+PyAPI_FUNC(void) Py_SetRecursionLimit(int);
+PyAPI_FUNC(int) Py_GetRecursionLimit(void);
+
+#define Py_EnterRecursiveCall(where)                                    \
+	    (_Py_MakeRecCheck(PyThreadState_GET()->recursion_depth) &&  \
+	     _Py_CheckRecursiveCall(where))
+#define Py_LeaveRecursiveCall()				\
+	    (--PyThreadState_GET()->recursion_depth)
+PyAPI_FUNC(int) _Py_CheckRecursiveCall(char *where);
+PyAPI_DATA(int) _Py_CheckRecursionLimit;
+#ifdef USE_STACKCHECK
+#  define _Py_MakeRecCheck(x)  (++(x) > --_Py_CheckRecursionLimit)
+#else
+#  define _Py_MakeRecCheck(x)  (++(x) > _Py_CheckRecursionLimit)
+#endif
+
+PyAPI_FUNC(const char *) PyEval_GetFuncName(PyObject *);
+PyAPI_FUNC(const char *) PyEval_GetFuncDesc(PyObject *);
+
+PyAPI_FUNC(PyObject *) PyEval_GetCallStats(PyObject *);
+PyAPI_FUNC(PyObject *) PyEval_EvalFrame(struct _frame *);
+PyAPI_FUNC(PyObject *) PyEval_EvalFrameEx(struct _frame *f, int exc);
+
+/* this used to be handled on a per-thread basis - now just two globals */
+PyAPI_DATA(volatile int) _Py_Ticker;
+PyAPI_DATA(int) _Py_CheckInterval;
+
+/* Interface for threads.
+
+   A module that plans to do a blocking system call (or something else
+   that lasts a long time and doesn't touch Python data) can allow other
+   threads to run as follows:
+
+	...preparations here...
+	Py_BEGIN_ALLOW_THREADS
+	...blocking system call here...
+	Py_END_ALLOW_THREADS
+	...interpret result here...
+
+   The Py_BEGIN_ALLOW_THREADS/Py_END_ALLOW_THREADS pair expands to a
+   {}-surrounded block.
+   To leave the block in the middle (e.g., with return), you must insert
+   a line containing Py_BLOCK_THREADS before the return, e.g.
+
+	if (...premature_exit...) {
+		Py_BLOCK_THREADS
+		PyErr_SetFromErrno(PyExc_IOError);
+		return NULL;
+	}
+
+   An alternative is:
+
+	Py_BLOCK_THREADS
+	if (...premature_exit...) {
+		PyErr_SetFromErrno(PyExc_IOError);
+		return NULL;
+	}
+	Py_UNBLOCK_THREADS
+
+   For convenience, that the value of 'errno' is restored across
+   Py_END_ALLOW_THREADS and Py_BLOCK_THREADS.
+
+   WARNING: NEVER NEST CALLS TO Py_BEGIN_ALLOW_THREADS AND
+   Py_END_ALLOW_THREADS!!!
+
+   The function PyEval_InitThreads() should be called only from
+   initthread() in "threadmodule.c".
+
+   Note that not yet all candidates have been converted to use this
+   mechanism!
+*/
+
+PyAPI_FUNC(PyThreadState *) PyEval_SaveThread(void);
+PyAPI_FUNC(void) PyEval_RestoreThread(PyThreadState *);
+
+#ifdef WITH_THREAD
+
+PyAPI_FUNC(int)  PyEval_ThreadsInitialized(void);
+PyAPI_FUNC(void) PyEval_InitThreads(void);
+PyAPI_FUNC(void) PyEval_AcquireLock(void);
+PyAPI_FUNC(void) PyEval_ReleaseLock(void);
+PyAPI_FUNC(void) PyEval_AcquireThread(PyThreadState *tstate);
+PyAPI_FUNC(void) PyEval_ReleaseThread(PyThreadState *tstate);
+PyAPI_FUNC(void) PyEval_ReInitThreads(void);
+
+#define Py_BEGIN_ALLOW_THREADS { \
+			PyThreadState *_save; \
+			_save = PyEval_SaveThread();
+#define Py_BLOCK_THREADS	PyEval_RestoreThread(_save);
+#define Py_UNBLOCK_THREADS	_save = PyEval_SaveThread();
+#define Py_END_ALLOW_THREADS	PyEval_RestoreThread(_save); \
+		 }
+
+#else /* !WITH_THREAD */
+
+#define Py_BEGIN_ALLOW_THREADS {
+#define Py_BLOCK_THREADS
+#define Py_UNBLOCK_THREADS
+#define Py_END_ALLOW_THREADS }
+
+#endif /* !WITH_THREAD */
+
+PyAPI_FUNC(int) _PyEval_SliceIndex(PyObject *, Py_ssize_t *);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_CEVAL_H */

Added: vendor/Python/current/Include/classobject.h
===================================================================
--- vendor/Python/current/Include/classobject.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/classobject.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,81 @@
+
+/* Class object interface */
+
+/* Revealing some structures (not for general use) */
+
+#ifndef Py_CLASSOBJECT_H
+#define Py_CLASSOBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+    PyObject_HEAD
+    PyObject	*cl_bases;	/* A tuple of class objects */
+    PyObject	*cl_dict;	/* A dictionary */
+    PyObject	*cl_name;	/* A string */
+    /* The following three are functions or NULL */
+    PyObject	*cl_getattr;
+    PyObject	*cl_setattr;
+    PyObject	*cl_delattr;
+} PyClassObject;
+
+typedef struct {
+    PyObject_HEAD
+    PyClassObject *in_class;	/* The class object */
+    PyObject	  *in_dict;	/* A dictionary */
+    PyObject	  *in_weakreflist; /* List of weak references */
+} PyInstanceObject;
+
+typedef struct {
+    PyObject_HEAD
+    PyObject *im_func;   /* The callable object implementing the method */
+    PyObject *im_self;   /* The instance it is bound to, or NULL */
+    PyObject *im_class;  /* The class that asked for the method */
+    PyObject *im_weakreflist; /* List of weak references */
+} PyMethodObject;
+
+PyAPI_DATA(PyTypeObject) PyClass_Type, PyInstance_Type, PyMethod_Type;
+
+#define PyClass_Check(op) ((op)->ob_type == &PyClass_Type)
+#define PyInstance_Check(op) ((op)->ob_type == &PyInstance_Type)
+#define PyMethod_Check(op) ((op)->ob_type == &PyMethod_Type)
+
+PyAPI_FUNC(PyObject *) PyClass_New(PyObject *, PyObject *, PyObject *);
+PyAPI_FUNC(PyObject *) PyInstance_New(PyObject *, PyObject *,
+                                            PyObject *);
+PyAPI_FUNC(PyObject *) PyInstance_NewRaw(PyObject *, PyObject *);
+PyAPI_FUNC(PyObject *) PyMethod_New(PyObject *, PyObject *, PyObject *);
+
+PyAPI_FUNC(PyObject *) PyMethod_Function(PyObject *);
+PyAPI_FUNC(PyObject *) PyMethod_Self(PyObject *);
+PyAPI_FUNC(PyObject *) PyMethod_Class(PyObject *);
+
+/* Look up attribute with name (a string) on instance object pinst, using
+ * only the instance and base class dicts.  If a descriptor is found in
+ * a class dict, the descriptor is returned without calling it.
+ * Returns NULL if nothing found, else a borrowed reference to the
+ * value associated with name in the dict in which name was found.
+ * The point of this routine is that it never calls arbitrary Python
+ * code, so is always "safe":  all it does is dict lookups.  The function
+ * can't fail, never sets an exception, and NULL is not an error (it just
+ * means "not found").
+ */
+PyAPI_FUNC(PyObject *) _PyInstance_Lookup(PyObject *pinst, PyObject *name);
+
+/* Macros for direct access to these values. Type checks are *not*
+   done, so use with care. */
+#define PyMethod_GET_FUNCTION(meth) \
+        (((PyMethodObject *)meth) -> im_func)
+#define PyMethod_GET_SELF(meth) \
+	(((PyMethodObject *)meth) -> im_self)
+#define PyMethod_GET_CLASS(meth) \
+	(((PyMethodObject *)meth) -> im_class)
+
+PyAPI_FUNC(int) PyClass_IsSubclass(PyObject *, PyObject *);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_CLASSOBJECT_H */

Added: vendor/Python/current/Include/cobject.h
===================================================================
--- vendor/Python/current/Include/cobject.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/cobject.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,54 @@
+
+/* C objects to be exported from one extension module to another.
+ 
+   C objects are used for communication between extension modules.
+   They provide a way for an extension module to export a C interface
+   to other extension modules, so that extension modules can use the
+   Python import mechanism to link to one another.
+
+*/
+
+#ifndef Py_COBJECT_H
+#define Py_COBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+PyAPI_DATA(PyTypeObject) PyCObject_Type;
+
+#define PyCObject_Check(op) ((op)->ob_type == &PyCObject_Type)
+
+/* Create a PyCObject from a pointer to a C object and an optional
+   destructor function.  If the second argument is non-null, then it
+   will be called with the first argument if and when the PyCObject is
+   destroyed.
+
+*/
+PyAPI_FUNC(PyObject *) PyCObject_FromVoidPtr(
+	void *cobj, void (*destruct)(void*));
+
+
+/* Create a PyCObject from a pointer to a C object, a description object,
+   and an optional destructor function.  If the third argument is non-null,
+   then it will be called with the first and second arguments if and when 
+   the PyCObject is destroyed.
+*/
+PyAPI_FUNC(PyObject *) PyCObject_FromVoidPtrAndDesc(
+	void *cobj, void *desc, void (*destruct)(void*,void*));
+
+/* Retrieve a pointer to a C object from a PyCObject. */
+PyAPI_FUNC(void *) PyCObject_AsVoidPtr(PyObject *);
+
+/* Retrieve a pointer to a description object from a PyCObject. */
+PyAPI_FUNC(void *) PyCObject_GetDesc(PyObject *);
+
+/* Import a pointer to a C object from a module using a PyCObject. */
+PyAPI_FUNC(void *) PyCObject_Import(char *module_name, char *cobject_name);
+
+/* Modify a C object. Fails (==0) if object has a destructor. */
+PyAPI_FUNC(int) PyCObject_SetVoidPtr(PyObject *self, void *cobj);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_COBJECT_H */

Added: vendor/Python/current/Include/code.h
===================================================================
--- vendor/Python/current/Include/code.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/code.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,94 @@
+/* Definitions for bytecode */
+
+#ifndef Py_CODE_H
+#define Py_CODE_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Bytecode object */
+typedef struct {
+    PyObject_HEAD
+    int co_argcount;		/* #arguments, except *args */
+    int co_nlocals;		/* #local variables */
+    int co_stacksize;		/* #entries needed for evaluation stack */
+    int co_flags;		/* CO_..., see below */
+    PyObject *co_code;		/* instruction opcodes */
+    PyObject *co_consts;	/* list (constants used) */
+    PyObject *co_names;		/* list of strings (names used) */
+    PyObject *co_varnames;	/* tuple of strings (local variable names) */
+    PyObject *co_freevars;	/* tuple of strings (free variable names) */
+    PyObject *co_cellvars;      /* tuple of strings (cell variable names) */
+    /* The rest doesn't count for hash/cmp */
+    PyObject *co_filename;	/* string (where it was loaded from) */
+    PyObject *co_name;		/* string (name, for reference) */
+    int co_firstlineno;		/* first source line number */
+    PyObject *co_lnotab;	/* string (encoding addr<->lineno mapping) */
+    void *co_zombieframe;     /* for optimization only (see frameobject.c) */
+} PyCodeObject;
+
+/* Masks for co_flags above */
+#define CO_OPTIMIZED	0x0001
+#define CO_NEWLOCALS	0x0002
+#define CO_VARARGS	0x0004
+#define CO_VARKEYWORDS	0x0008
+#define CO_NESTED       0x0010
+#define CO_GENERATOR    0x0020
+/* The CO_NOFREE flag is set if there are no free or cell variables.
+   This information is redundant, but it allows a single flag test
+   to determine whether there is any extra work to be done when the
+   call frame it setup.
+*/
+#define CO_NOFREE       0x0040
+
+#if 0
+/* This is no longer used.  Stopped defining in 2.5, do not re-use. */
+#define CO_GENERATOR_ALLOWED    0x1000
+#endif
+#define CO_FUTURE_DIVISION    	0x2000
+#define CO_FUTURE_ABSOLUTE_IMPORT 0x4000 /* do absolute imports by default */
+#define CO_FUTURE_WITH_STATEMENT  0x8000
+
+/* This should be defined if a future statement modifies the syntax.
+   For example, when a keyword is added.
+*/
+#define PY_PARSER_REQUIRES_FUTURE_KEYWORD
+
+#define CO_MAXBLOCKS 20 /* Max static block nesting within a function */
+
+PyAPI_DATA(PyTypeObject) PyCode_Type;
+
+#define PyCode_Check(op) ((op)->ob_type == &PyCode_Type)
+#define PyCode_GetNumFree(op) (PyTuple_GET_SIZE((op)->co_freevars))
+
+/* Public interface */
+PyAPI_FUNC(PyCodeObject *) PyCode_New(
+	int, int, int, int, PyObject *, PyObject *, PyObject *, PyObject *,
+	PyObject *, PyObject *, PyObject *, PyObject *, int, PyObject *); 
+        /* same as struct above */
+PyAPI_FUNC(int) PyCode_Addr2Line(PyCodeObject *, int);
+
+/* for internal use only */
+#define _PyCode_GETCODEPTR(co, pp) \
+	((*(co)->co_code->ob_type->tp_as_buffer->bf_getreadbuffer) \
+	 ((co)->co_code, 0, (void **)(pp)))
+
+typedef struct _addr_pair {
+        int ap_lower;
+        int ap_upper;
+} PyAddrPair;
+
+/* Check whether lasti (an instruction offset) falls outside bounds
+   and whether it is a line number that should be traced.  Returns
+   a line number if it should be traced or -1 if the line should not.
+
+   If lasti is not within bounds, updates bounds.
+*/
+
+PyAPI_FUNC(int) PyCode_CheckLineNumber(PyCodeObject* co,
+                                       int lasti, PyAddrPair *bounds);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_CODE_H */

Added: vendor/Python/current/Include/codecs.h
===================================================================
--- vendor/Python/current/Include/codecs.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/codecs.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,167 @@
+#ifndef Py_CODECREGISTRY_H
+#define Py_CODECREGISTRY_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ------------------------------------------------------------------------
+
+   Python Codec Registry and support functions
+
+
+Written by Marc-Andre Lemburg (mal at lemburg.com).
+
+Copyright (c) Corporation for National Research Initiatives.
+
+   ------------------------------------------------------------------------ */
+
+/* Register a new codec search function.
+
+   As side effect, this tries to load the encodings package, if not
+   yet done, to make sure that it is always first in the list of
+   search functions.
+
+   The search_function's refcount is incremented by this function. */
+
+PyAPI_FUNC(int) PyCodec_Register(
+       PyObject *search_function
+       );
+
+/* Codec register lookup API.
+
+   Looks up the given encoding and returns a CodecInfo object with
+   function attributes which implement the different aspects of
+   processing the encoding.
+
+   The encoding string is looked up converted to all lower-case
+   characters. This makes encodings looked up through this mechanism
+   effectively case-insensitive.
+
+   If no codec is found, a KeyError is set and NULL returned.
+
+   As side effect, this tries to load the encodings package, if not
+   yet done. This is part of the lazy load strategy for the encodings
+   package.
+
+ */
+
+PyAPI_FUNC(PyObject *) _PyCodec_Lookup(
+       const char *encoding
+       );
+
+/* Generic codec based encoding API.
+
+   object is passed through the encoder function found for the given
+   encoding using the error handling method defined by errors. errors
+   may be NULL to use the default method defined for the codec.
+   
+   Raises a LookupError in case no encoder can be found.
+
+ */
+
+PyAPI_FUNC(PyObject *) PyCodec_Encode(
+       PyObject *object,
+       const char *encoding,
+       const char *errors
+       );
+
+/* Generic codec based decoding API.
+
+   object is passed through the decoder function found for the given
+   encoding using the error handling method defined by errors. errors
+   may be NULL to use the default method defined for the codec.
+   
+   Raises a LookupError in case no encoder can be found.
+
+ */
+
+PyAPI_FUNC(PyObject *) PyCodec_Decode(
+       PyObject *object,
+       const char *encoding,
+       const char *errors
+       );
+
+/* --- Codec Lookup APIs -------------------------------------------------- 
+
+   All APIs return a codec object with incremented refcount and are
+   based on _PyCodec_Lookup().  The same comments w/r to the encoding
+   name also apply to these APIs.
+
+*/
+
+/* Get an encoder function for the given encoding. */
+
+PyAPI_FUNC(PyObject *) PyCodec_Encoder(
+       const char *encoding
+       );
+
+/* Get a decoder function for the given encoding. */
+
+PyAPI_FUNC(PyObject *) PyCodec_Decoder(
+       const char *encoding
+       );
+
+/* Get a IncrementalEncoder object for the given encoding. */
+
+PyAPI_FUNC(PyObject *) PyCodec_IncrementalEncoder(
+       const char *encoding,
+       const char *errors
+       );
+
+/* Get a IncrementalDecoder object function for the given encoding. */
+
+PyAPI_FUNC(PyObject *) PyCodec_IncrementalDecoder(
+       const char *encoding,
+       const char *errors
+       );
+
+/* Get a StreamReader factory function for the given encoding. */
+
+PyAPI_FUNC(PyObject *) PyCodec_StreamReader(
+       const char *encoding,
+       PyObject *stream,
+       const char *errors
+       );
+
+/* Get a StreamWriter factory function for the given encoding. */
+
+PyAPI_FUNC(PyObject *) PyCodec_StreamWriter(
+       const char *encoding,
+       PyObject *stream,
+       const char *errors
+       );
+
+/* Unicode encoding error handling callback registry API */
+
+/* Register the error handling callback function error under the name
+   name. This function will be called by the codec when it encounters
+   unencodable characters/undecodable bytes and doesn't know the
+   callback name, when name is specified as the error parameter
+   in the call to the encode/decode function.
+   Return 0 on success, -1 on error */
+PyAPI_FUNC(int) PyCodec_RegisterError(const char *name, PyObject *error);
+
+/* Lookup the error handling callback function registered under the
+   name error. As a special case NULL can be passed, in which case
+   the error handling callback for "strict" will be returned. */
+PyAPI_FUNC(PyObject *) PyCodec_LookupError(const char *name);
+
+/* raise exc as an exception */
+PyAPI_FUNC(PyObject *) PyCodec_StrictErrors(PyObject *exc);
+
+/* ignore the unicode error, skipping the faulty input */
+PyAPI_FUNC(PyObject *) PyCodec_IgnoreErrors(PyObject *exc);
+
+/* replace the unicode error with ? or U+FFFD */
+PyAPI_FUNC(PyObject *) PyCodec_ReplaceErrors(PyObject *exc);
+
+/* replace the unicode encode error with XML character references */
+PyAPI_FUNC(PyObject *) PyCodec_XMLCharRefReplaceErrors(PyObject *exc);
+
+/* replace the unicode encode error with backslash escapes (\x, \u and \U) */
+PyAPI_FUNC(PyObject *) PyCodec_BackslashReplaceErrors(PyObject *exc);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_CODECREGISTRY_H */

Added: vendor/Python/current/Include/compile.h
===================================================================
--- vendor/Python/current/Include/compile.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/compile.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,39 @@
+
+#ifndef Py_COMPILE_H
+#define Py_COMPILE_H
+
+#include "code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Public interface */
+struct _node; /* Declare the existence of this type */
+PyAPI_FUNC(PyCodeObject *) PyNode_Compile(struct _node *, const char *);
+
+/* Future feature support */
+
+typedef struct {
+    int ff_features;      /* flags set by future statements */
+    int ff_lineno;        /* line number of last future statement */
+} PyFutureFeatures;
+
+#define FUTURE_NESTED_SCOPES "nested_scopes"
+#define FUTURE_GENERATORS "generators"
+#define FUTURE_DIVISION "division"
+#define FUTURE_ABSOLUTE_IMPORT "absolute_import"
+#define FUTURE_WITH_STATEMENT "with_statement"
+
+struct _mod; /* Declare the existence of this type */
+PyAPI_FUNC(PyCodeObject *) PyAST_Compile(struct _mod *, const char *,
+					PyCompilerFlags *, PyArena *);
+PyAPI_FUNC(PyFutureFeatures *) PyFuture_FromAST(struct _mod *, const char *);
+
+#define ERR_LATE_FUTURE \
+"from __future__ imports must occur at the beginning of the file"
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_COMPILE_H */

Added: vendor/Python/current/Include/complexobject.h
===================================================================
--- vendor/Python/current/Include/complexobject.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/complexobject.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,58 @@
+/* Complex number structure */
+
+#ifndef Py_COMPLEXOBJECT_H
+#define Py_COMPLEXOBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+    double real;
+    double imag;
+} Py_complex;
+
+/* Operations on complex numbers from complexmodule.c */
+
+#define c_sum _Py_c_sum
+#define c_diff _Py_c_diff
+#define c_neg _Py_c_neg
+#define c_prod _Py_c_prod
+#define c_quot _Py_c_quot
+#define c_pow _Py_c_pow
+
+PyAPI_FUNC(Py_complex) c_sum(Py_complex, Py_complex);
+PyAPI_FUNC(Py_complex) c_diff(Py_complex, Py_complex);
+PyAPI_FUNC(Py_complex) c_neg(Py_complex);
+PyAPI_FUNC(Py_complex) c_prod(Py_complex, Py_complex);
+PyAPI_FUNC(Py_complex) c_quot(Py_complex, Py_complex);
+PyAPI_FUNC(Py_complex) c_pow(Py_complex, Py_complex);
+
+
+/* Complex object interface */
+
+/*
+PyComplexObject represents a complex number with double-precision
+real and imaginary parts.
+*/
+
+typedef struct {
+    PyObject_HEAD
+    Py_complex cval;
+} PyComplexObject;     
+
+PyAPI_DATA(PyTypeObject) PyComplex_Type;
+
+#define PyComplex_Check(op) PyObject_TypeCheck(op, &PyComplex_Type)
+#define PyComplex_CheckExact(op) ((op)->ob_type == &PyComplex_Type)
+
+PyAPI_FUNC(PyObject *) PyComplex_FromCComplex(Py_complex);
+PyAPI_FUNC(PyObject *) PyComplex_FromDoubles(double real, double imag);
+
+PyAPI_FUNC(double) PyComplex_RealAsDouble(PyObject *op);
+PyAPI_FUNC(double) PyComplex_ImagAsDouble(PyObject *op);
+PyAPI_FUNC(Py_complex) PyComplex_AsCComplex(PyObject *op);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_COMPLEXOBJECT_H */

Added: vendor/Python/current/Include/datetime.h
===================================================================
--- vendor/Python/current/Include/datetime.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/datetime.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,245 @@
+/*  datetime.h
+ */
+
+#ifndef DATETIME_H
+#define DATETIME_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Fields are packed into successive bytes, each viewed as unsigned and
+ * big-endian, unless otherwise noted:
+ *
+ * byte offset
+ *  0 		year     2 bytes, 1-9999
+ *  2		month    1 byte, 1-12
+ *  3 		day      1 byte, 1-31
+ *  4		hour     1 byte, 0-23
+ *  5 		minute   1 byte, 0-59
+ *  6 		second   1 byte, 0-59
+ *  7 		usecond  3 bytes, 0-999999
+ * 10
+ */
+
+/* # of bytes for year, month, and day. */
+#define _PyDateTime_DATE_DATASIZE 4
+
+/* # of bytes for hour, minute, second, and usecond. */
+#define _PyDateTime_TIME_DATASIZE 6
+
+/* # of bytes for year, month, day, hour, minute, second, and usecond. */
+#define _PyDateTime_DATETIME_DATASIZE 10
+
+
+typedef struct
+{
+	PyObject_HEAD
+	long hashcode;		/* -1 when unknown */
+	int days;		/* -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS */
+	int seconds;		/* 0 <= seconds < 24*3600 is invariant */
+	int microseconds;	/* 0 <= microseconds < 1000000 is invariant */
+} PyDateTime_Delta;
+
+typedef struct
+{
+	PyObject_HEAD		/* a pure abstract base clase */
+} PyDateTime_TZInfo;
+
+
+/* The datetime and time types have hashcodes, and an optional tzinfo member,
+ * present if and only if hastzinfo is true.
+ */
+#define _PyTZINFO_HEAD		\
+	PyObject_HEAD		\
+	long hashcode;		\
+	char hastzinfo;		/* boolean flag */
+
+/* No _PyDateTime_BaseTZInfo is allocated; it's just to have something
+ * convenient to cast to, when getting at the hastzinfo member of objects
+ * starting with _PyTZINFO_HEAD.
+ */
+typedef struct
+{
+	_PyTZINFO_HEAD
+} _PyDateTime_BaseTZInfo;
+
+/* All time objects are of PyDateTime_TimeType, but that can be allocated
+ * in two ways, with or without a tzinfo member.  Without is the same as
+ * tzinfo == None, but consumes less memory.  _PyDateTime_BaseTime is an
+ * internal struct used to allocate the right amount of space for the
+ * "without" case.
+ */
+#define _PyDateTime_TIMEHEAD	\
+	_PyTZINFO_HEAD		\
+	unsigned char data[_PyDateTime_TIME_DATASIZE];
+
+typedef struct
+{
+	_PyDateTime_TIMEHEAD
+} _PyDateTime_BaseTime;		/* hastzinfo false */
+
+typedef struct
+{
+	_PyDateTime_TIMEHEAD
+	PyObject *tzinfo;
+} PyDateTime_Time;		/* hastzinfo true */
+
+
+/* All datetime objects are of PyDateTime_DateTimeType, but that can be
+ * allocated in two ways too, just like for time objects above.  In addition,
+ * the plain date type is a base class for datetime, so it must also have
+ * a hastzinfo member (although it's unused there).
+ */
+typedef struct
+{
+	_PyTZINFO_HEAD
+	unsigned char data[_PyDateTime_DATE_DATASIZE];
+} PyDateTime_Date;
+
+#define _PyDateTime_DATETIMEHEAD	\
+	_PyTZINFO_HEAD			\
+	unsigned char data[_PyDateTime_DATETIME_DATASIZE];
+
+typedef struct
+{
+	_PyDateTime_DATETIMEHEAD
+} _PyDateTime_BaseDateTime;	/* hastzinfo false */
+
+typedef struct
+{
+	_PyDateTime_DATETIMEHEAD
+	PyObject *tzinfo;
+} PyDateTime_DateTime;		/* hastzinfo true */
+
+
+/* Apply for date and datetime instances. */
+#define PyDateTime_GET_YEAR(o)     ((((PyDateTime_Date*)o)->data[0] << 8) | \
+                                     ((PyDateTime_Date*)o)->data[1])
+#define PyDateTime_GET_MONTH(o)    (((PyDateTime_Date*)o)->data[2])
+#define PyDateTime_GET_DAY(o)      (((PyDateTime_Date*)o)->data[3])
+
+#define PyDateTime_DATE_GET_HOUR(o)        (((PyDateTime_DateTime*)o)->data[4])
+#define PyDateTime_DATE_GET_MINUTE(o)      (((PyDateTime_DateTime*)o)->data[5])
+#define PyDateTime_DATE_GET_SECOND(o)      (((PyDateTime_DateTime*)o)->data[6])
+#define PyDateTime_DATE_GET_MICROSECOND(o) 		\
+	((((PyDateTime_DateTime*)o)->data[7] << 16) |	\
+         (((PyDateTime_DateTime*)o)->data[8] << 8)  |	\
+          ((PyDateTime_DateTime*)o)->data[9])
+
+/* Apply for time instances. */
+#define PyDateTime_TIME_GET_HOUR(o)        (((PyDateTime_Time*)o)->data[0])
+#define PyDateTime_TIME_GET_MINUTE(o)      (((PyDateTime_Time*)o)->data[1])
+#define PyDateTime_TIME_GET_SECOND(o)      (((PyDateTime_Time*)o)->data[2])
+#define PyDateTime_TIME_GET_MICROSECOND(o) 		\
+	((((PyDateTime_Time*)o)->data[3] << 16) |	\
+         (((PyDateTime_Time*)o)->data[4] << 8)  |	\
+          ((PyDateTime_Time*)o)->data[5])
+
+
+/* Define structure for C API. */
+typedef struct {
+    /* type objects */
+    PyTypeObject *DateType;
+    PyTypeObject *DateTimeType;
+    PyTypeObject *TimeType;
+    PyTypeObject *DeltaType;
+    PyTypeObject *TZInfoType;
+
+    /* constructors */
+    PyObject *(*Date_FromDate)(int, int, int, PyTypeObject*);
+    PyObject *(*DateTime_FromDateAndTime)(int, int, int, int, int, int, int,
+            PyObject*, PyTypeObject*);
+    PyObject *(*Time_FromTime)(int, int, int, int, PyObject*, PyTypeObject*);
+    PyObject *(*Delta_FromDelta)(int, int, int, int, PyTypeObject*);
+
+    /* constructors for the DB API */
+    PyObject *(*DateTime_FromTimestamp)(PyObject*, PyObject*, PyObject*);
+    PyObject *(*Date_FromTimestamp)(PyObject*, PyObject*);
+
+} PyDateTime_CAPI;
+
+
+/* "magic" constant used to partially protect against developer mistakes. */
+#define DATETIME_API_MAGIC 0x414548d5
+
+#ifdef Py_BUILD_CORE
+
+/* Macros for type checking when building the Python core. */
+#define PyDate_Check(op) PyObject_TypeCheck(op, &PyDateTime_DateType)
+#define PyDate_CheckExact(op) ((op)->ob_type == &PyDateTime_DateType)
+
+#define PyDateTime_Check(op) PyObject_TypeCheck(op, &PyDateTime_DateTimeType)
+#define PyDateTime_CheckExact(op) ((op)->ob_type == &PyDateTime_DateTimeType)
+
+#define PyTime_Check(op) PyObject_TypeCheck(op, &PyDateTime_TimeType)
+#define PyTime_CheckExact(op) ((op)->ob_type == &PyDateTime_TimeType)
+
+#define PyDelta_Check(op) PyObject_TypeCheck(op, &PyDateTime_DeltaType)
+#define PyDelta_CheckExact(op) ((op)->ob_type == &PyDateTime_DeltaType)
+
+#define PyTZInfo_Check(op) PyObject_TypeCheck(op, &PyDateTime_TZInfoType)
+#define PyTZInfo_CheckExact(op) ((op)->ob_type == &PyDateTime_TZInfoType)
+
+#else
+
+/* Define global variable for the C API and a macro for setting it. */
+static PyDateTime_CAPI *PyDateTimeAPI;
+
+#define PyDateTime_IMPORT \
+        PyDateTimeAPI = (PyDateTime_CAPI*) PyCObject_Import("datetime", \
+                                                            "datetime_CAPI")
+
+/* This macro would be used if PyCObject_ImportEx() was created.
+#define PyDateTime_IMPORT \
+        PyDateTimeAPI = (PyDateTime_CAPI*) PyCObject_ImportEx("datetime", \
+                                                            "datetime_CAPI", \
+                                                            DATETIME_API_MAGIC)
+*/
+
+/* Macros for type checking when not building the Python core. */
+#define PyDate_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DateType)
+#define PyDate_CheckExact(op) ((op)->ob_type == PyDateTimeAPI->DateType)
+
+#define PyDateTime_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DateTimeType)
+#define PyDateTime_CheckExact(op) ((op)->ob_type == PyDateTimeAPI->DateTimeType)
+
+#define PyTime_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->TimeType)
+#define PyTime_CheckExact(op) ((op)->ob_type == PyDateTimeAPI->TimeType)
+
+#define PyDelta_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DeltaType)
+#define PyDelta_CheckExact(op) ((op)->ob_type == PyDateTimeAPI->DeltaType)
+
+#define PyTZInfo_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->TZInfoType)
+#define PyTZInfo_CheckExact(op) ((op)->ob_type == PyDateTimeAPI->TZInfoType)
+
+/* Macros for accessing constructors in a simplified fashion. */
+#define PyDate_FromDate(year, month, day) \
+	PyDateTimeAPI->Date_FromDate(year, month, day, PyDateTimeAPI->DateType)
+
+#define PyDateTime_FromDateAndTime(year, month, day, hour, min, sec, usec) \
+	PyDateTimeAPI->DateTime_FromDateAndTime(year, month, day, hour, \
+		min, sec, usec, Py_None, PyDateTimeAPI->DateTimeType)
+
+#define PyTime_FromTime(hour, minute, second, usecond) \
+	PyDateTimeAPI->Time_FromTime(hour, minute, second, usecond, \
+		Py_None, PyDateTimeAPI->TimeType)
+
+#define PyDelta_FromDSU(days, seconds, useconds) \
+	PyDateTimeAPI->Delta_FromDelta(days, seconds, useconds, 1, \
+		PyDateTimeAPI->DeltaType)
+
+/* Macros supporting the DB API. */
+#define PyDateTime_FromTimestamp(args) \
+	PyDateTimeAPI->DateTime_FromTimestamp( \
+		(PyObject*) (PyDateTimeAPI->DateTimeType), args, NULL)
+
+#define PyDate_FromTimestamp(args) \
+	PyDateTimeAPI->Date_FromTimestamp( \
+		(PyObject*) (PyDateTimeAPI->DateType), args)
+
+#endif	/* Py_BUILD_CORE */
+
+#ifdef __cplusplus
+}
+#endif
+#endif

Added: vendor/Python/current/Include/descrobject.h
===================================================================
--- vendor/Python/current/Include/descrobject.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/descrobject.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,91 @@
+/* Descriptors */
+#ifndef Py_DESCROBJECT_H
+#define Py_DESCROBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef PyObject *(*getter)(PyObject *, void *);
+typedef int (*setter)(PyObject *, PyObject *, void *);
+
+typedef struct PyGetSetDef {
+	char *name;
+	getter get;
+	setter set;
+	char *doc;
+	void *closure;
+} PyGetSetDef;
+
+typedef PyObject *(*wrapperfunc)(PyObject *self, PyObject *args,
+				 void *wrapped);
+
+typedef PyObject *(*wrapperfunc_kwds)(PyObject *self, PyObject *args,
+				      void *wrapped, PyObject *kwds);
+
+struct wrapperbase {
+	char *name;
+	int offset;
+	void *function;
+	wrapperfunc wrapper;
+	char *doc;
+	int flags;
+	PyObject *name_strobj;
+};
+
+/* Flags for above struct */
+#define PyWrapperFlag_KEYWORDS 1 /* wrapper function takes keyword args */
+
+/* Various kinds of descriptor objects */
+
+#define PyDescr_COMMON \
+	PyObject_HEAD \
+	PyTypeObject *d_type; \
+	PyObject *d_name
+
+typedef struct {
+	PyDescr_COMMON;
+} PyDescrObject;
+
+typedef struct {
+	PyDescr_COMMON;
+	PyMethodDef *d_method;
+} PyMethodDescrObject;
+
+typedef struct {
+	PyDescr_COMMON;
+	struct PyMemberDef *d_member;
+} PyMemberDescrObject;
+
+typedef struct {
+	PyDescr_COMMON;
+	PyGetSetDef *d_getset;
+} PyGetSetDescrObject;
+
+typedef struct {
+	PyDescr_COMMON;
+	struct wrapperbase *d_base;
+	void *d_wrapped; /* This can be any function pointer */
+} PyWrapperDescrObject;
+
+PyAPI_DATA(PyTypeObject) PyWrapperDescr_Type;
+
+PyAPI_FUNC(PyObject *) PyDescr_NewMethod(PyTypeObject *, PyMethodDef *);
+PyAPI_FUNC(PyObject *) PyDescr_NewClassMethod(PyTypeObject *, PyMethodDef *);
+PyAPI_FUNC(PyObject *) PyDescr_NewMember(PyTypeObject *,
+					       struct PyMemberDef *);
+PyAPI_FUNC(PyObject *) PyDescr_NewGetSet(PyTypeObject *,
+					       struct PyGetSetDef *);
+PyAPI_FUNC(PyObject *) PyDescr_NewWrapper(PyTypeObject *,
+						struct wrapperbase *, void *);
+#define PyDescr_IsData(d) ((d)->ob_type->tp_descr_set != NULL)
+
+PyAPI_FUNC(PyObject *) PyDictProxy_New(PyObject *);
+PyAPI_FUNC(PyObject *) PyWrapper_New(PyObject *, PyObject *);
+
+
+PyAPI_DATA(PyTypeObject) PyProperty_Type;
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_DESCROBJECT_H */
+

Added: vendor/Python/current/Include/dictobject.h
===================================================================
--- vendor/Python/current/Include/dictobject.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/dictobject.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,141 @@
+#ifndef Py_DICTOBJECT_H
+#define Py_DICTOBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Dictionary object type -- mapping from hashable object to object */
+
+/* The distribution includes a separate file, Objects/dictnotes.txt,
+   describing explorations into dictionary design and optimization.
+   It covers typical dictionary use patterns, the parameters for
+   tuning dictionaries, and several ideas for possible optimizations.
+*/
+
+/*
+There are three kinds of slots in the table:
+
+1. Unused.  me_key == me_value == NULL
+   Does not hold an active (key, value) pair now and never did.  Unused can
+   transition to Active upon key insertion.  This is the only case in which
+   me_key is NULL, and is each slot's initial state.
+
+2. Active.  me_key != NULL and me_key != dummy and me_value != NULL
+   Holds an active (key, value) pair.  Active can transition to Dummy upon
+   key deletion.  This is the only case in which me_value != NULL.
+
+3. Dummy.  me_key == dummy and me_value == NULL
+   Previously held an active (key, value) pair, but that was deleted and an
+   active pair has not yet overwritten the slot.  Dummy can transition to
+   Active upon key insertion.  Dummy slots cannot be made Unused again
+   (cannot have me_key set to NULL), else the probe sequence in case of
+   collision would have no way to know they were once active.
+
+Note: .popitem() abuses the me_hash field of an Unused or Dummy slot to
+hold a search finger.  The me_hash field of Unused or Dummy slots has no
+meaning otherwise.
+*/
+
+/* PyDict_MINSIZE is the minimum size of a dictionary.  This many slots are
+ * allocated directly in the dict object (in the ma_smalltable member).
+ * It must be a power of 2, and at least 4.  8 allows dicts with no more
+ * than 5 active entries to live in ma_smalltable (and so avoid an
+ * additional malloc); instrumentation suggested this suffices for the
+ * majority of dicts (consisting mostly of usually-small instance dicts and
+ * usually-small dicts created to pass keyword arguments).
+ */
+#define PyDict_MINSIZE 8
+
+typedef struct {
+	/* Cached hash code of me_key.  Note that hash codes are C longs.
+	 * We have to use Py_ssize_t instead because dict_popitem() abuses
+	 * me_hash to hold a search finger.
+	 */
+	Py_ssize_t me_hash;
+	PyObject *me_key;
+	PyObject *me_value;
+} PyDictEntry;
+
+/*
+To ensure the lookup algorithm terminates, there must be at least one Unused
+slot (NULL key) in the table.
+The value ma_fill is the number of non-NULL keys (sum of Active and Dummy);
+ma_used is the number of non-NULL, non-dummy keys (== the number of non-NULL
+values == the number of Active items).
+To avoid slowing down lookups on a near-full table, we resize the table when
+it's two-thirds full.
+*/
+typedef struct _dictobject PyDictObject;
+struct _dictobject {
+	PyObject_HEAD
+	Py_ssize_t ma_fill;  /* # Active + # Dummy */
+	Py_ssize_t ma_used;  /* # Active */
+
+	/* The table contains ma_mask + 1 slots, and that's a power of 2.
+	 * We store the mask instead of the size because the mask is more
+	 * frequently needed.
+	 */
+	Py_ssize_t ma_mask;
+
+	/* ma_table points to ma_smalltable for small tables, else to
+	 * additional malloc'ed memory.  ma_table is never NULL!  This rule
+	 * saves repeated runtime null-tests in the workhorse getitem and
+	 * setitem calls.
+	 */
+	PyDictEntry *ma_table;
+	PyDictEntry *(*ma_lookup)(PyDictObject *mp, PyObject *key, long hash);
+	PyDictEntry ma_smalltable[PyDict_MINSIZE];
+};
+
+PyAPI_DATA(PyTypeObject) PyDict_Type;
+
+#define PyDict_Check(op) PyObject_TypeCheck(op, &PyDict_Type)
+#define PyDict_CheckExact(op) ((op)->ob_type == &PyDict_Type)
+
+PyAPI_FUNC(PyObject *) PyDict_New(void);
+PyAPI_FUNC(PyObject *) PyDict_GetItem(PyObject *mp, PyObject *key);
+PyAPI_FUNC(int) PyDict_SetItem(PyObject *mp, PyObject *key, PyObject *item);
+PyAPI_FUNC(int) PyDict_DelItem(PyObject *mp, PyObject *key);
+PyAPI_FUNC(void) PyDict_Clear(PyObject *mp);
+PyAPI_FUNC(int) PyDict_Next(
+	PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value);
+PyAPI_FUNC(int) _PyDict_Next(
+	PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value, long *hash);
+PyAPI_FUNC(PyObject *) PyDict_Keys(PyObject *mp);
+PyAPI_FUNC(PyObject *) PyDict_Values(PyObject *mp);
+PyAPI_FUNC(PyObject *) PyDict_Items(PyObject *mp);
+PyAPI_FUNC(Py_ssize_t) PyDict_Size(PyObject *mp);
+PyAPI_FUNC(PyObject *) PyDict_Copy(PyObject *mp);
+PyAPI_FUNC(int) PyDict_Contains(PyObject *mp, PyObject *key);
+PyAPI_FUNC(int) _PyDict_Contains(PyObject *mp, PyObject *key, long hash);
+
+/* PyDict_Update(mp, other) is equivalent to PyDict_Merge(mp, other, 1). */
+PyAPI_FUNC(int) PyDict_Update(PyObject *mp, PyObject *other);
+
+/* PyDict_Merge updates/merges from a mapping object (an object that
+   supports PyMapping_Keys() and PyObject_GetItem()).  If override is true,
+   the last occurrence of a key wins, else the first.  The Python
+   dict.update(other) is equivalent to PyDict_Merge(dict, other, 1).
+*/
+PyAPI_FUNC(int) PyDict_Merge(PyObject *mp,
+				   PyObject *other,
+				   int override);
+
+/* PyDict_MergeFromSeq2 updates/merges from an iterable object producing
+   iterable objects of length 2.  If override is true, the last occurrence
+   of a key wins, else the first.  The Python dict constructor dict(seq2)
+   is equivalent to dict={}; PyDict_MergeFromSeq(dict, seq2, 1).
+*/
+PyAPI_FUNC(int) PyDict_MergeFromSeq2(PyObject *d,
+					   PyObject *seq2,
+					   int override);
+
+PyAPI_FUNC(PyObject *) PyDict_GetItemString(PyObject *dp, const char *key);
+PyAPI_FUNC(int) PyDict_SetItemString(PyObject *dp, const char *key, PyObject *item);
+PyAPI_FUNC(int) PyDict_DelItemString(PyObject *dp, const char *key);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_DICTOBJECT_H */

Added: vendor/Python/current/Include/enumobject.h
===================================================================
--- vendor/Python/current/Include/enumobject.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/enumobject.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,17 @@
+#ifndef Py_ENUMOBJECT_H
+#define Py_ENUMOBJECT_H
+
+/* Enumerate Object */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+PyAPI_DATA(PyTypeObject) PyEnum_Type;
+PyAPI_DATA(PyTypeObject) PyReversed_Type;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !Py_ENUMOBJECT_H */

Added: vendor/Python/current/Include/errcode.h
===================================================================
--- vendor/Python/current/Include/errcode.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/errcode.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,36 @@
+#ifndef Py_ERRCODE_H
+#define Py_ERRCODE_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Error codes passed around between file input, tokenizer, parser and
+   interpreter.  This is necessary so we can turn them into Python
+   exceptions at a higher level.  Note that some errors have a
+   slightly different meaning when passed from the tokenizer to the
+   parser than when passed from the parser to the interpreter; e.g.
+   the parser only returns E_EOF when it hits EOF immediately, and it
+   never returns E_OK. */
+
+#define E_OK		10	/* No error */
+#define E_EOF		11	/* End Of File */
+#define E_INTR		12	/* Interrupted */
+#define E_TOKEN		13	/* Bad token */
+#define E_SYNTAX	14	/* Syntax error */
+#define E_NOMEM		15	/* Ran out of memory */
+#define E_DONE		16	/* Parsing complete */
+#define E_ERROR		17	/* Execution error */
+#define E_TABSPACE	18	/* Inconsistent mixing of tabs and spaces */
+#define E_OVERFLOW      19	/* Node had too many children */
+#define E_TOODEEP	20	/* Too many indentation levels */
+#define E_DEDENT	21	/* No matching outer block for dedent */
+#define E_DECODE	22	/* Error in decoding into Unicode */
+#define E_EOFS		23	/* EOF in triple-quoted string */
+#define E_EOLS		24	/* EOL in single-quoted string */
+#define E_LINECONT	25	/* Unexpected characters after a line continuation */
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_ERRCODE_H */

Added: vendor/Python/current/Include/eval.h
===================================================================
--- vendor/Python/current/Include/eval.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/eval.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,25 @@
+
+/* Interface to execute compiled code */
+
+#ifndef Py_EVAL_H
+#define Py_EVAL_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+PyAPI_FUNC(PyObject *) PyEval_EvalCode(PyCodeObject *, PyObject *, PyObject *);
+
+PyAPI_FUNC(PyObject *) PyEval_EvalCodeEx(PyCodeObject *co,
+					PyObject *globals,
+					PyObject *locals,
+					PyObject **args, int argc,
+					PyObject **kwds, int kwdc,
+					PyObject **defs, int defc,
+					PyObject *closure);
+
+PyAPI_FUNC(PyObject *) _PyEval_CallTracing(PyObject *func, PyObject *args);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_EVAL_H */

Added: vendor/Python/current/Include/fileobject.h
===================================================================
--- vendor/Python/current/Include/fileobject.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/fileobject.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,63 @@
+
+/* File object interface */
+
+#ifndef Py_FILEOBJECT_H
+#define Py_FILEOBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+	PyObject_HEAD
+	FILE *f_fp;
+	PyObject *f_name;
+	PyObject *f_mode;
+	int (*f_close)(FILE *);
+	int f_softspace;	/* Flag used by 'print' command */
+	int f_binary;		/* Flag which indicates whether the file is 
+				   open in binary (1) or text (0) mode */
+	char* f_buf;		/* Allocated readahead buffer */
+	char* f_bufend;		/* Points after last occupied position */
+	char* f_bufptr;		/* Current buffer position */
+	char *f_setbuf;		/* Buffer for setbuf(3) and setvbuf(3) */
+	int f_univ_newline;	/* Handle any newline convention */
+	int f_newlinetypes;	/* Types of newlines seen */
+	int f_skipnextlf;	/* Skip next \n */
+	PyObject *f_encoding;
+	PyObject *weakreflist; /* List of weak references */
+} PyFileObject;
+
+PyAPI_DATA(PyTypeObject) PyFile_Type;
+
+#define PyFile_Check(op) PyObject_TypeCheck(op, &PyFile_Type)
+#define PyFile_CheckExact(op) ((op)->ob_type == &PyFile_Type)
+
+PyAPI_FUNC(PyObject *) PyFile_FromString(char *, char *);
+PyAPI_FUNC(void) PyFile_SetBufSize(PyObject *, int);
+PyAPI_FUNC(int) PyFile_SetEncoding(PyObject *, const char *);
+PyAPI_FUNC(PyObject *) PyFile_FromFile(FILE *, char *, char *,
+                                             int (*)(FILE *));
+PyAPI_FUNC(FILE *) PyFile_AsFile(PyObject *);
+PyAPI_FUNC(PyObject *) PyFile_Name(PyObject *);
+PyAPI_FUNC(PyObject *) PyFile_GetLine(PyObject *, int);
+PyAPI_FUNC(int) PyFile_WriteObject(PyObject *, PyObject *, int);
+PyAPI_FUNC(int) PyFile_SoftSpace(PyObject *, int);
+PyAPI_FUNC(int) PyFile_WriteString(const char *, PyObject *);
+PyAPI_FUNC(int) PyObject_AsFileDescriptor(PyObject *);
+
+/* The default encoding used by the platform file system APIs
+   If non-NULL, this is different than the default encoding for strings
+*/
+PyAPI_DATA(const char *) Py_FileSystemDefaultEncoding;
+
+/* Routines to replace fread() and fgets() which accept any of \r, \n
+   or \r\n as line terminators.
+*/
+#define PY_STDIOTEXTMODE "b"
+char *Py_UniversalNewlineFgets(char *, int, FILE*, PyObject *);
+size_t Py_UniversalNewlineFread(char *, size_t, FILE *, PyObject *);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_FILEOBJECT_H */

Added: vendor/Python/current/Include/floatobject.h
===================================================================
--- vendor/Python/current/Include/floatobject.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/floatobject.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,100 @@
+
+/* Float object interface */
+
+/*
+PyFloatObject represents a (double precision) floating point number.
+*/
+
+#ifndef Py_FLOATOBJECT_H
+#define Py_FLOATOBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+    PyObject_HEAD
+    double ob_fval;
+} PyFloatObject;
+
+PyAPI_DATA(PyTypeObject) PyFloat_Type;
+
+#define PyFloat_Check(op) PyObject_TypeCheck(op, &PyFloat_Type)
+#define PyFloat_CheckExact(op) ((op)->ob_type == &PyFloat_Type)
+
+/* Return Python float from string PyObject.  Second argument ignored on
+   input, and, if non-NULL, NULL is stored into *junk (this tried to serve a
+   purpose once but can't be made to work as intended). */
+PyAPI_FUNC(PyObject *) PyFloat_FromString(PyObject*, char** junk);
+
+/* Return Python float from C double. */
+PyAPI_FUNC(PyObject *) PyFloat_FromDouble(double);
+
+/* Extract C double from Python float.  The macro version trades safety for
+   speed. */
+PyAPI_FUNC(double) PyFloat_AsDouble(PyObject *);
+#define PyFloat_AS_DOUBLE(op) (((PyFloatObject *)(op))->ob_fval)
+
+/* Write repr(v) into the char buffer argument, followed by null byte.  The
+   buffer must be "big enough"; >= 100 is very safe.
+   PyFloat_AsReprString(buf, x) strives to print enough digits so that
+   PyFloat_FromString(buf) then reproduces x exactly. */
+PyAPI_FUNC(void) PyFloat_AsReprString(char*, PyFloatObject *v);
+
+/* Write str(v) into the char buffer argument, followed by null byte.  The
+   buffer must be "big enough"; >= 100 is very safe.  Note that it's
+   unusual to be able to get back the float you started with from
+   PyFloat_AsString's result -- use PyFloat_AsReprString() if you want to
+   preserve precision across conversions. */
+PyAPI_FUNC(void) PyFloat_AsString(char*, PyFloatObject *v);
+
+/* _PyFloat_{Pack,Unpack}{4,8}
+ *
+ * The struct and pickle (at least) modules need an efficient platform-
+ * independent way to store floating-point values as byte strings.
+ * The Pack routines produce a string from a C double, and the Unpack
+ * routines produce a C double from such a string.  The suffix (4 or 8)
+ * specifies the number of bytes in the string.
+ *
+ * On platforms that appear to use (see _PyFloat_Init()) IEEE-754 formats
+ * these functions work by copying bits.  On other platforms, the formats the
+ * 4- byte format is identical to the IEEE-754 single precision format, and
+ * the 8-byte format to the IEEE-754 double precision format, although the
+ * packing of INFs and NaNs (if such things exist on the platform) isn't
+ * handled correctly, and attempting to unpack a string containing an IEEE
+ * INF or NaN will raise an exception.
+ *
+ * On non-IEEE platforms with more precision, or larger dynamic range, than
+ * 754 supports, not all values can be packed; on non-IEEE platforms with less
+ * precision, or smaller dynamic range, not all values can be unpacked.  What
+ * happens in such cases is partly accidental (alas).
+ */
+
+/* The pack routines write 4 or 8 bytes, starting at p.  le is a bool
+ * argument, true if you want the string in little-endian format (exponent
+ * last, at p+3 or p+7), false if you want big-endian format (exponent
+ * first, at p).
+ * Return value:  0 if all is OK, -1 if error (and an exception is
+ * set, most likely OverflowError).
+ * There are two problems on non-IEEE platforms:
+ * 1):  What this does is undefined if x is a NaN or infinity.
+ * 2):  -0.0 and +0.0 produce the same string.
+ */
+PyAPI_FUNC(int) _PyFloat_Pack4(double x, unsigned char *p, int le);
+PyAPI_FUNC(int) _PyFloat_Pack8(double x, unsigned char *p, int le);
+
+/* The unpack routines read 4 or 8 bytes, starting at p.  le is a bool
+ * argument, true if the string is in little-endian format (exponent
+ * last, at p+3 or p+7), false if big-endian (exponent first, at p).
+ * Return value:  The unpacked double.  On error, this is -1.0 and
+ * PyErr_Occurred() is true (and an exception is set, most likely
+ * OverflowError).  Note that on a non-IEEE platform this will refuse
+ * to unpack a string that represents a NaN or infinity.
+ */
+PyAPI_FUNC(double) _PyFloat_Unpack4(const unsigned char *p, int le);
+PyAPI_FUNC(double) _PyFloat_Unpack8(const unsigned char *p, int le);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_FLOATOBJECT_H */

Added: vendor/Python/current/Include/frameobject.h
===================================================================
--- vendor/Python/current/Include/frameobject.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/frameobject.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,81 @@
+
+/* Frame object interface */
+
+#ifndef Py_FRAMEOBJECT_H
+#define Py_FRAMEOBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+    int b_type;			/* what kind of block this is */
+    int b_handler;		/* where to jump to find handler */
+    int b_level;		/* value stack level to pop to */
+} PyTryBlock;
+
+typedef struct _frame {
+    PyObject_VAR_HEAD
+    struct _frame *f_back;	/* previous frame, or NULL */
+    PyCodeObject *f_code;	/* code segment */
+    PyObject *f_builtins;	/* builtin symbol table (PyDictObject) */
+    PyObject *f_globals;	/* global symbol table (PyDictObject) */
+    PyObject *f_locals;		/* local symbol table (any mapping) */
+    PyObject **f_valuestack;	/* points after the last local */
+    /* Next free slot in f_valuestack.  Frame creation sets to f_valuestack.
+       Frame evaluation usually NULLs it, but a frame that yields sets it
+       to the current stack top. */
+    PyObject **f_stacktop;
+    PyObject *f_trace;		/* Trace function */
+
+    /* If an exception is raised in this frame, the next three are used to
+     * record the exception info (if any) originally in the thread state.  See
+     * comments before set_exc_info() -- it's not obvious.
+     * Invariant:  if _type is NULL, then so are _value and _traceback.
+     * Desired invariant:  all three are NULL, or all three are non-NULL.  That
+     * one isn't currently true, but "should be".
+     */
+    PyObject *f_exc_type, *f_exc_value, *f_exc_traceback;
+
+    PyThreadState *f_tstate;
+    int f_lasti;		/* Last instruction if called */
+    /* As of 2.3 f_lineno is only valid when tracing is active (i.e. when
+       f_trace is set) -- at other times use PyCode_Addr2Line instead. */
+    int f_lineno;		/* Current line number */
+    int f_iblock;		/* index in f_blockstack */
+    PyTryBlock f_blockstack[CO_MAXBLOCKS]; /* for try and loop blocks */
+    PyObject *f_localsplus[1];	/* locals+stack, dynamically sized */
+} PyFrameObject;
+
+
+/* Standard object interface */
+
+PyAPI_DATA(PyTypeObject) PyFrame_Type;
+
+#define PyFrame_Check(op) ((op)->ob_type == &PyFrame_Type)
+#define PyFrame_IsRestricted(f) \
+	((f)->f_builtins != (f)->f_tstate->interp->builtins)
+
+PyAPI_FUNC(PyFrameObject *) PyFrame_New(PyThreadState *, PyCodeObject *,
+                                       PyObject *, PyObject *);
+
+
+/* The rest of the interface is specific for frame objects */
+
+/* Block management functions */
+
+PyAPI_FUNC(void) PyFrame_BlockSetup(PyFrameObject *, int, int, int);
+PyAPI_FUNC(PyTryBlock *) PyFrame_BlockPop(PyFrameObject *);
+
+/* Extend the value stack */
+
+PyAPI_FUNC(PyObject **) PyFrame_ExtendStack(PyFrameObject *, int, int);
+
+/* Conversions between "fast locals" and locals in dictionary */
+
+PyAPI_FUNC(void) PyFrame_LocalsToFast(PyFrameObject *, int);
+PyAPI_FUNC(void) PyFrame_FastToLocals(PyFrameObject *);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_FRAMEOBJECT_H */

Added: vendor/Python/current/Include/funcobject.h
===================================================================
--- vendor/Python/current/Include/funcobject.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/funcobject.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,76 @@
+
+/* Function object interface */
+
+#ifndef Py_FUNCOBJECT_H
+#define Py_FUNCOBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Function objects and code objects should not be confused with each other:
+ *
+ * Function objects are created by the execution of the 'def' statement.
+ * They reference a code object in their func_code attribute, which is a
+ * purely syntactic object, i.e. nothing more than a compiled version of some
+ * source code lines.  There is one code object per source code "fragment",
+ * but each code object can be referenced by zero or many function objects
+ * depending only on how many times the 'def' statement in the source was
+ * executed so far.
+ */
+
+typedef struct {
+    PyObject_HEAD
+    PyObject *func_code;	/* A code object */
+    PyObject *func_globals;	/* A dictionary (other mappings won't do) */
+    PyObject *func_defaults;	/* NULL or a tuple */
+    PyObject *func_closure;	/* NULL or a tuple of cell objects */
+    PyObject *func_doc;		/* The __doc__ attribute, can be anything */
+    PyObject *func_name;	/* The __name__ attribute, a string object */
+    PyObject *func_dict;	/* The __dict__ attribute, a dict or NULL */
+    PyObject *func_weakreflist;	/* List of weak references */
+    PyObject *func_module;	/* The __module__ attribute, can be anything */
+
+    /* Invariant:
+     *     func_closure contains the bindings for func_code->co_freevars, so
+     *     PyTuple_Size(func_closure) == PyCode_GetNumFree(func_code)
+     *     (func_closure may be NULL if PyCode_GetNumFree(func_code) == 0).
+     */
+} PyFunctionObject;
+
+PyAPI_DATA(PyTypeObject) PyFunction_Type;
+
+#define PyFunction_Check(op) ((op)->ob_type == &PyFunction_Type)
+
+PyAPI_FUNC(PyObject *) PyFunction_New(PyObject *, PyObject *);
+PyAPI_FUNC(PyObject *) PyFunction_GetCode(PyObject *);
+PyAPI_FUNC(PyObject *) PyFunction_GetGlobals(PyObject *);
+PyAPI_FUNC(PyObject *) PyFunction_GetModule(PyObject *);
+PyAPI_FUNC(PyObject *) PyFunction_GetDefaults(PyObject *);
+PyAPI_FUNC(int) PyFunction_SetDefaults(PyObject *, PyObject *);
+PyAPI_FUNC(PyObject *) PyFunction_GetClosure(PyObject *);
+PyAPI_FUNC(int) PyFunction_SetClosure(PyObject *, PyObject *);
+
+/* Macros for direct access to these values. Type checks are *not*
+   done, so use with care. */
+#define PyFunction_GET_CODE(func) \
+        (((PyFunctionObject *)func) -> func_code)
+#define PyFunction_GET_GLOBALS(func) \
+	(((PyFunctionObject *)func) -> func_globals)
+#define PyFunction_GET_MODULE(func) \
+	(((PyFunctionObject *)func) -> func_module)
+#define PyFunction_GET_DEFAULTS(func) \
+	(((PyFunctionObject *)func) -> func_defaults)
+#define PyFunction_GET_CLOSURE(func) \
+	(((PyFunctionObject *)func) -> func_closure)
+
+/* The classmethod and staticmethod types lives here, too */
+PyAPI_DATA(PyTypeObject) PyClassMethod_Type;
+PyAPI_DATA(PyTypeObject) PyStaticMethod_Type;
+
+PyAPI_FUNC(PyObject *) PyClassMethod_New(PyObject *);
+PyAPI_FUNC(PyObject *) PyStaticMethod_New(PyObject *);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_FUNCOBJECT_H */

Added: vendor/Python/current/Include/genobject.h
===================================================================
--- vendor/Python/current/Include/genobject.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/genobject.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,37 @@
+
+/* Generator object interface */
+
+#ifndef Py_GENOBJECT_H
+#define Py_GENOBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct _frame; /* Avoid including frameobject.h */
+
+typedef struct {
+	PyObject_HEAD
+	/* The gi_ prefix is intended to remind of generator-iterator. */
+
+	/* Note: gi_frame can be NULL if the generator is "finished" */
+	struct _frame *gi_frame;
+
+	/* True if generator is being executed. */
+	int gi_running;
+
+	/* List of weak reference. */
+	PyObject *gi_weakreflist;
+} PyGenObject;
+
+PyAPI_DATA(PyTypeObject) PyGen_Type;
+
+#define PyGen_Check(op) PyObject_TypeCheck(op, &PyGen_Type)
+#define PyGen_CheckExact(op) ((op)->ob_type == &PyGen_Type)
+
+PyAPI_FUNC(PyObject *) PyGen_New(struct _frame *);
+PyAPI_FUNC(int) PyGen_NeedsFinalizing(PyGenObject *);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_GENOBJECT_H */

Added: vendor/Python/current/Include/graminit.h
===================================================================
--- vendor/Python/current/Include/graminit.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/graminit.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,84 @@
+#define single_input 256
+#define file_input 257
+#define eval_input 258
+#define decorator 259
+#define decorators 260
+#define funcdef 261
+#define parameters 262
+#define varargslist 263
+#define fpdef 264
+#define fplist 265
+#define stmt 266
+#define simple_stmt 267
+#define small_stmt 268
+#define expr_stmt 269
+#define augassign 270
+#define print_stmt 271
+#define del_stmt 272
+#define pass_stmt 273
+#define flow_stmt 274
+#define break_stmt 275
+#define continue_stmt 276
+#define return_stmt 277
+#define yield_stmt 278
+#define raise_stmt 279
+#define import_stmt 280
+#define import_name 281
+#define import_from 282
+#define import_as_name 283
+#define dotted_as_name 284
+#define import_as_names 285
+#define dotted_as_names 286
+#define dotted_name 287
+#define global_stmt 288
+#define exec_stmt 289
+#define assert_stmt 290
+#define compound_stmt 291
+#define if_stmt 292
+#define while_stmt 293
+#define for_stmt 294
+#define try_stmt 295
+#define with_stmt 296
+#define with_var 297
+#define except_clause 298
+#define suite 299
+#define testlist_safe 300
+#define old_test 301
+#define old_lambdef 302
+#define test 303
+#define or_test 304
+#define and_test 305
+#define not_test 306
+#define comparison 307
+#define comp_op 308
+#define expr 309
+#define xor_expr 310
+#define and_expr 311
+#define shift_expr 312
+#define arith_expr 313
+#define term 314
+#define factor 315
+#define power 316
+#define atom 317
+#define listmaker 318
+#define testlist_gexp 319
+#define lambdef 320
+#define trailer 321
+#define subscriptlist 322
+#define subscript 323
+#define sliceop 324
+#define exprlist 325
+#define testlist 326
+#define dictmaker 327
+#define classdef 328
+#define arglist 329
+#define argument 330
+#define list_iter 331
+#define list_for 332
+#define list_if 333
+#define gen_iter 334
+#define gen_for 335
+#define gen_if 336
+#define testlist1 337
+#define encoding_decl 338
+#define yield_expr 339

Added: vendor/Python/current/Include/grammar.h
===================================================================
--- vendor/Python/current/Include/grammar.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/grammar.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,93 @@
+
+/* Grammar interface */
+
+#ifndef Py_GRAMMAR_H
+#define Py_GRAMMAR_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "bitset.h" /* Sigh... */
+
+/* A label of an arc */
+
+typedef struct {
+    int		 lb_type;
+    char	*lb_str;
+} label;
+
+#define EMPTY 0		/* Label number 0 is by definition the empty label */
+
+/* A list of labels */
+
+typedef struct {
+    int		 ll_nlabels;
+    label	*ll_label;
+} labellist;
+
+/* An arc from one state to another */
+
+typedef struct {
+    short	a_lbl;		/* Label of this arc */
+    short	a_arrow;	/* State where this arc goes to */
+} arc;
+
+/* A state in a DFA */
+
+typedef struct {
+    int		 s_narcs;
+    arc		*s_arc;		/* Array of arcs */
+	
+    /* Optional accelerators */
+    int		 s_lower;	/* Lowest label index */
+    int		 s_upper;	/* Highest label index */
+    int		*s_accel;	/* Accelerator */
+    int		 s_accept;	/* Nonzero for accepting state */
+} state;
+
+/* A DFA */
+
+typedef struct {
+    int		 d_type;	/* Non-terminal this represents */
+    char	*d_name;	/* For printing */
+    int		 d_initial;	/* Initial state */
+    int		 d_nstates;
+    state	*d_state;	/* Array of states */
+    bitset	 d_first;
+} dfa;
+
+/* A grammar */
+
+typedef struct {
+    int		 g_ndfas;
+    dfa		*g_dfa;		/* Array of DFAs */
+    labellist	 g_ll;
+    int		 g_start;	/* Start symbol of the grammar */
+    int		 g_accel;	/* Set if accelerators present */
+} grammar;
+
+/* FUNCTIONS */
+
+grammar *newgrammar(int start);
+dfa *adddfa(grammar *g, int type, char *name);
+int addstate(dfa *d);
+void addarc(dfa *d, int from, int to, int lbl);
+dfa *PyGrammar_FindDFA(grammar *g, int type);
+
+int addlabel(labellist *ll, int type, char *str);
+int findlabel(labellist *ll, int type, char *str);
+char *PyGrammar_LabelRepr(label *lb);
+void translatelabels(grammar *g);
+
+void addfirstsets(grammar *g);
+
+void PyGrammar_AddAccelerators(grammar *g);
+void PyGrammar_RemoveAccelerators(grammar *);
+
+void printgrammar(grammar *g, FILE *fp);
+void printnonterminals(grammar *g, FILE *fp);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_GRAMMAR_H */

Added: vendor/Python/current/Include/import.h
===================================================================
--- vendor/Python/current/Include/import.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/import.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,64 @@
+
+/* Module definition and import interface */
+
+#ifndef Py_IMPORT_H
+#define Py_IMPORT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+PyAPI_FUNC(long) PyImport_GetMagicNumber(void);
+PyAPI_FUNC(PyObject *) PyImport_ExecCodeModule(char *name, PyObject *co);
+PyAPI_FUNC(PyObject *) PyImport_ExecCodeModuleEx(
+	char *name, PyObject *co, char *pathname);
+PyAPI_FUNC(PyObject *) PyImport_GetModuleDict(void);
+PyAPI_FUNC(PyObject *) PyImport_AddModule(const char *name);
+PyAPI_FUNC(PyObject *) PyImport_ImportModule(const char *name);
+PyAPI_FUNC(PyObject *) PyImport_ImportModuleLevel(char *name,
+	PyObject *globals, PyObject *locals, PyObject *fromlist, int level);
+
+/* For DLL compatibility */
+#undef PyImport_ImportModuleEx
+PyAPI_FUNC(PyObject *) PyImport_ImportModuleEx(
+	char *name, PyObject *globals, PyObject *locals, PyObject *fromlist);
+#define PyImport_ImportModuleEx(n, g, l, f) \
+	PyImport_ImportModuleLevel(n, g, l, f, -1)
+
+PyAPI_FUNC(PyObject *) PyImport_Import(PyObject *name);
+PyAPI_FUNC(PyObject *) PyImport_ReloadModule(PyObject *m);
+PyAPI_FUNC(void) PyImport_Cleanup(void);
+PyAPI_FUNC(int) PyImport_ImportFrozenModule(char *);
+
+PyAPI_FUNC(struct filedescr *) _PyImport_FindModule(
+	const char *, PyObject *, char *, size_t, FILE **, PyObject **);
+PyAPI_FUNC(int) _PyImport_IsScript(struct filedescr *);
+PyAPI_FUNC(void) _PyImport_ReInitLock(void);
+
+PyAPI_FUNC(PyObject *)_PyImport_FindExtension(char *, char *);
+PyAPI_FUNC(PyObject *)_PyImport_FixupExtension(char *, char *);
+
+struct _inittab {
+    char *name;
+    void (*initfunc)(void);
+};
+
+PyAPI_DATA(struct _inittab *) PyImport_Inittab;
+
+PyAPI_FUNC(int) PyImport_AppendInittab(char *name, void (*initfunc)(void));
+PyAPI_FUNC(int) PyImport_ExtendInittab(struct _inittab *newtab);
+
+struct _frozen {
+    char *name;
+    unsigned char *code;
+    int size;
+};
+
+/* Embedding apps may change this pointer to point to their favorite
+   collection of frozen modules: */
+
+PyAPI_DATA(struct _frozen *) PyImport_FrozenModules;
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_IMPORT_H */

Added: vendor/Python/current/Include/intobject.h
===================================================================
--- vendor/Python/current/Include/intobject.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/intobject.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,64 @@
+
+/* Integer object interface */
+
+/*
+PyIntObject represents a (long) integer.  This is an immutable object;
+an integer cannot change its value after creation.
+
+There are functions to create new integer objects, to test an object
+for integer-ness, and to get the integer value.  The latter functions
+returns -1 and sets errno to EBADF if the object is not an PyIntObject.
+None of the functions should be applied to nil objects.
+
+The type PyIntObject is (unfortunately) exposed here so we can declare
+_Py_TrueStruct and _Py_ZeroStruct in boolobject.h; don't use this.
+*/
+
+#ifndef Py_INTOBJECT_H
+#define Py_INTOBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+    PyObject_HEAD
+    long ob_ival;
+} PyIntObject;
+
+PyAPI_DATA(PyTypeObject) PyInt_Type;
+
+#define PyInt_Check(op) PyObject_TypeCheck(op, &PyInt_Type)
+#define PyInt_CheckExact(op) ((op)->ob_type == &PyInt_Type)
+
+PyAPI_FUNC(PyObject *) PyInt_FromString(char*, char**, int);
+#ifdef Py_USING_UNICODE
+PyAPI_FUNC(PyObject *) PyInt_FromUnicode(Py_UNICODE*, Py_ssize_t, int);
+#endif
+PyAPI_FUNC(PyObject *) PyInt_FromLong(long);
+PyAPI_FUNC(PyObject *) PyInt_FromSize_t(size_t);
+PyAPI_FUNC(PyObject *) PyInt_FromSsize_t(Py_ssize_t);
+PyAPI_FUNC(long) PyInt_AsLong(PyObject *);
+PyAPI_FUNC(Py_ssize_t) PyInt_AsSsize_t(PyObject *);
+PyAPI_FUNC(unsigned long) PyInt_AsUnsignedLongMask(PyObject *);
+#ifdef HAVE_LONG_LONG
+PyAPI_FUNC(unsigned PY_LONG_LONG) PyInt_AsUnsignedLongLongMask(PyObject *);
+#endif
+
+PyAPI_FUNC(long) PyInt_GetMax(void);
+
+/* Macro, trading safety for speed */
+#define PyInt_AS_LONG(op) (((PyIntObject *)(op))->ob_ival)
+
+/* These aren't really part of the Int object, but they're handy; the protos
+ * are necessary for systems that need the magic of PyAPI_FUNC and that want
+ * to have stropmodule as a dynamically loaded module instead of building it
+ * into the main Python shared library/DLL.  Guido thinks I'm weird for
+ * building it this way.  :-)  [cjh]
+ */
+PyAPI_FUNC(unsigned long) PyOS_strtoul(char *, char **, int);
+PyAPI_FUNC(long) PyOS_strtol(char *, char **, int);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_INTOBJECT_H */

Added: vendor/Python/current/Include/intrcheck.h
===================================================================
--- vendor/Python/current/Include/intrcheck.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/intrcheck.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,15 @@
+
+#ifndef Py_INTRCHECK_H
+#define Py_INTRCHECK_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+PyAPI_FUNC(int) PyOS_InterruptOccurred(void);
+PyAPI_FUNC(void) PyOS_InitInterrupts(void);
+PyAPI_FUNC(void) PyOS_AfterFork(void);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_INTRCHECK_H */

Added: vendor/Python/current/Include/iterobject.h
===================================================================
--- vendor/Python/current/Include/iterobject.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/iterobject.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,23 @@
+#ifndef Py_ITEROBJECT_H
+#define Py_ITEROBJECT_H
+/* Iterators (the basic kind, over a sequence) */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+PyAPI_DATA(PyTypeObject) PySeqIter_Type;
+
+#define PySeqIter_Check(op) ((op)->ob_type == &PySeqIter_Type)
+
+PyAPI_FUNC(PyObject *) PySeqIter_New(PyObject *);
+
+PyAPI_DATA(PyTypeObject) PyCallIter_Type;
+
+#define PyCallIter_Check(op) ((op)->ob_type == &PyCallIter_Type)
+
+PyAPI_FUNC(PyObject *) PyCallIter_New(PyObject *, PyObject *);
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_ITEROBJECT_H */
+

Added: vendor/Python/current/Include/listobject.h
===================================================================
--- vendor/Python/current/Include/listobject.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/listobject.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,67 @@
+
+/* List object interface */
+
+/*
+Another generally useful object type is an list of object pointers.
+This is a mutable type: the list items can be changed, and items can be
+added or removed.  Out-of-range indices or non-list objects are ignored.
+
+*** WARNING *** PyList_SetItem does not increment the new item's reference
+count, but does decrement the reference count of the item it replaces,
+if not nil.  It does *decrement* the reference count if it is *not*
+inserted in the list.  Similarly, PyList_GetItem does not increment the
+returned item's reference count.
+*/
+
+#ifndef Py_LISTOBJECT_H
+#define Py_LISTOBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+    PyObject_VAR_HEAD
+    /* Vector of pointers to list elements.  list[0] is ob_item[0], etc. */
+    PyObject **ob_item;
+
+    /* ob_item contains space for 'allocated' elements.  The number
+     * currently in use is ob_size.
+     * Invariants:
+     *     0 <= ob_size <= allocated
+     *     len(list) == ob_size
+     *     ob_item == NULL implies ob_size == allocated == 0
+     * list.sort() temporarily sets allocated to -1 to detect mutations.
+     *
+     * Items must normally not be NULL, except during construction when
+     * the list is not yet visible outside the function that builds it.
+     */
+    Py_ssize_t allocated;
+} PyListObject;
+
+PyAPI_DATA(PyTypeObject) PyList_Type;
+
+#define PyList_Check(op) PyObject_TypeCheck(op, &PyList_Type)
+#define PyList_CheckExact(op) ((op)->ob_type == &PyList_Type)
+
+PyAPI_FUNC(PyObject *) PyList_New(Py_ssize_t size);
+PyAPI_FUNC(Py_ssize_t) PyList_Size(PyObject *);
+PyAPI_FUNC(PyObject *) PyList_GetItem(PyObject *, Py_ssize_t);
+PyAPI_FUNC(int) PyList_SetItem(PyObject *, Py_ssize_t, PyObject *);
+PyAPI_FUNC(int) PyList_Insert(PyObject *, Py_ssize_t, PyObject *);
+PyAPI_FUNC(int) PyList_Append(PyObject *, PyObject *);
+PyAPI_FUNC(PyObject *) PyList_GetSlice(PyObject *, Py_ssize_t, Py_ssize_t);
+PyAPI_FUNC(int) PyList_SetSlice(PyObject *, Py_ssize_t, Py_ssize_t, PyObject *);
+PyAPI_FUNC(int) PyList_Sort(PyObject *);
+PyAPI_FUNC(int) PyList_Reverse(PyObject *);
+PyAPI_FUNC(PyObject *) PyList_AsTuple(PyObject *);
+PyAPI_FUNC(PyObject *) _PyList_Extend(PyListObject *, PyObject *);
+
+/* Macro, trading safety for speed */
+#define PyList_GET_ITEM(op, i) (((PyListObject *)(op))->ob_item[i])
+#define PyList_SET_ITEM(op, i, v) (((PyListObject *)(op))->ob_item[i] = (v))
+#define PyList_GET_SIZE(op)    (((PyListObject *)(op))->ob_size)
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_LISTOBJECT_H */

Added: vendor/Python/current/Include/longintrepr.h
===================================================================
--- vendor/Python/current/Include/longintrepr.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/longintrepr.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,63 @@
+#ifndef Py_LONGINTREPR_H
+#define Py_LONGINTREPR_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* This is published for the benefit of "friend" marshal.c only. */
+
+/* Parameters of the long integer representation.
+   These shouldn't have to be changed as C should guarantee that a short
+   contains at least 16 bits, but it's made changeable anyway.
+   Note: 'digit' should be able to hold 2*MASK+1, and 'twodigits'
+   should be able to hold the intermediate results in 'mul'
+   (at most (BASE-1)*(2*BASE+1) == MASK*(2*MASK+3)).
+   Also, x_sub assumes that 'digit' is an unsigned type, and overflow
+   is handled by taking the result mod 2**N for some N > SHIFT.
+   And, at some places it is assumed that MASK fits in an int, as well.
+   long_pow() requires that SHIFT be divisible by 5. */
+
+typedef unsigned short digit;
+typedef unsigned int wdigit; /* digit widened to parameter size */
+#define BASE_TWODIGITS_TYPE long
+typedef unsigned BASE_TWODIGITS_TYPE twodigits;
+typedef BASE_TWODIGITS_TYPE stwodigits; /* signed variant of twodigits */
+
+#define SHIFT	15
+#define BASE	((digit)1 << SHIFT)
+#define MASK	((int)(BASE - 1))
+
+#if SHIFT % 5 != 0
+#error "longobject.c requires that SHIFT be divisible by 5"
+#endif
+
+/* Long integer representation.
+   The absolute value of a number is equal to
+   	SUM(for i=0 through abs(ob_size)-1) ob_digit[i] * 2**(SHIFT*i)
+   Negative numbers are represented with ob_size < 0;
+   zero is represented by ob_size == 0.
+   In a normalized number, ob_digit[abs(ob_size)-1] (the most significant
+   digit) is never zero.  Also, in all cases, for all valid i,
+   	0 <= ob_digit[i] <= MASK.
+   The allocation function takes care of allocating extra memory
+   so that ob_digit[0] ... ob_digit[abs(ob_size)-1] are actually available.
+
+   CAUTION:  Generic code manipulating subtypes of PyVarObject has to
+   aware that longs abuse  ob_size's sign bit.
+*/
+
+struct _longobject {
+	PyObject_VAR_HEAD
+	digit ob_digit[1];
+};
+
+PyAPI_FUNC(PyLongObject *) _PyLong_New(Py_ssize_t);
+
+/* Return a copy of src. */
+PyAPI_FUNC(PyObject *) _PyLong_Copy(PyLongObject *src);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_LONGINTREPR_H */

Added: vendor/Python/current/Include/longobject.h
===================================================================
--- vendor/Python/current/Include/longobject.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/longobject.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,114 @@
+#ifndef Py_LONGOBJECT_H
+#define Py_LONGOBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Long (arbitrary precision) integer object interface */
+
+typedef struct _longobject PyLongObject; /* Revealed in longintrepr.h */
+
+PyAPI_DATA(PyTypeObject) PyLong_Type;
+
+#define PyLong_Check(op) PyObject_TypeCheck(op, &PyLong_Type)
+#define PyLong_CheckExact(op) ((op)->ob_type == &PyLong_Type)
+
+PyAPI_FUNC(PyObject *) PyLong_FromLong(long);
+PyAPI_FUNC(PyObject *) PyLong_FromUnsignedLong(unsigned long);
+PyAPI_FUNC(PyObject *) PyLong_FromDouble(double);
+PyAPI_FUNC(long) PyLong_AsLong(PyObject *);
+PyAPI_FUNC(unsigned long) PyLong_AsUnsignedLong(PyObject *);
+PyAPI_FUNC(unsigned long) PyLong_AsUnsignedLongMask(PyObject *);
+
+/* For use by intobject.c only */
+PyAPI_FUNC(Py_ssize_t) _PyLong_AsSsize_t(PyObject *);
+PyAPI_FUNC(PyObject *) _PyLong_FromSize_t(size_t);
+PyAPI_FUNC(PyObject *) _PyLong_FromSsize_t(Py_ssize_t);
+PyAPI_DATA(int) _PyLong_DigitValue[256];
+
+/* _PyLong_AsScaledDouble returns a double x and an exponent e such that
+   the true value is approximately equal to x * 2**(SHIFT*e).  e is >= 0.
+   x is 0.0 if and only if the input is 0 (in which case, e and x are both
+   zeroes).  Overflow is impossible.  Note that the exponent returned must
+   be multiplied by SHIFT!  There may not be enough room in an int to store
+   e*SHIFT directly. */
+PyAPI_FUNC(double) _PyLong_AsScaledDouble(PyObject *vv, int *e);
+
+PyAPI_FUNC(double) PyLong_AsDouble(PyObject *);
+PyAPI_FUNC(PyObject *) PyLong_FromVoidPtr(void *);
+PyAPI_FUNC(void *) PyLong_AsVoidPtr(PyObject *);
+
+#ifdef HAVE_LONG_LONG
+PyAPI_FUNC(PyObject *) PyLong_FromLongLong(PY_LONG_LONG);
+PyAPI_FUNC(PyObject *) PyLong_FromUnsignedLongLong(unsigned PY_LONG_LONG);
+PyAPI_FUNC(PY_LONG_LONG) PyLong_AsLongLong(PyObject *);
+PyAPI_FUNC(unsigned PY_LONG_LONG) PyLong_AsUnsignedLongLong(PyObject *);
+PyAPI_FUNC(unsigned PY_LONG_LONG) PyLong_AsUnsignedLongLongMask(PyObject *);
+#endif /* HAVE_LONG_LONG */
+
+PyAPI_FUNC(PyObject *) PyLong_FromString(char *, char **, int);
+#ifdef Py_USING_UNICODE
+PyAPI_FUNC(PyObject *) PyLong_FromUnicode(Py_UNICODE*, Py_ssize_t, int);
+#endif
+
+/* _PyLong_Sign.  Return 0 if v is 0, -1 if v < 0, +1 if v > 0.
+   v must not be NULL, and must be a normalized long.
+   There are no error cases.
+*/
+PyAPI_FUNC(int) _PyLong_Sign(PyObject *v);
+
+
+/* _PyLong_NumBits.  Return the number of bits needed to represent the
+   absolute value of a long.  For example, this returns 1 for 1 and -1, 2
+   for 2 and -2, and 2 for 3 and -3.  It returns 0 for 0.
+   v must not be NULL, and must be a normalized long.
+   (size_t)-1 is returned and OverflowError set if the true result doesn't
+   fit in a size_t.
+*/
+PyAPI_FUNC(size_t) _PyLong_NumBits(PyObject *v);
+
+/* _PyLong_FromByteArray:  View the n unsigned bytes as a binary integer in
+   base 256, and return a Python long with the same numeric value.
+   If n is 0, the integer is 0.  Else:
+   If little_endian is 1/true, bytes[n-1] is the MSB and bytes[0] the LSB;
+   else (little_endian is 0/false) bytes[0] is the MSB and bytes[n-1] the
+   LSB.
+   If is_signed is 0/false, view the bytes as a non-negative integer.
+   If is_signed is 1/true, view the bytes as a 2's-complement integer,
+   non-negative if bit 0x80 of the MSB is clear, negative if set.
+   Error returns:
+   + Return NULL with the appropriate exception set if there's not
+     enough memory to create the Python long.
+*/
+PyAPI_FUNC(PyObject *) _PyLong_FromByteArray(
+	const unsigned char* bytes, size_t n,
+	int little_endian, int is_signed);
+
+/* _PyLong_AsByteArray: Convert the least-significant 8*n bits of long
+   v to a base-256 integer, stored in array bytes.  Normally return 0,
+   return -1 on error.
+   If little_endian is 1/true, store the MSB at bytes[n-1] and the LSB at
+   bytes[0]; else (little_endian is 0/false) store the MSB at bytes[0] and
+   the LSB at bytes[n-1].
+   If is_signed is 0/false, it's an error if v < 0; else (v >= 0) n bytes
+   are filled and there's nothing special about bit 0x80 of the MSB.
+   If is_signed is 1/true, bytes is filled with the 2's-complement
+   representation of v's value.  Bit 0x80 of the MSB is the sign bit.
+   Error returns (-1):
+   + is_signed is 0 and v < 0.  TypeError is set in this case, and bytes
+     isn't altered.
+   + n isn't big enough to hold the full mathematical value of v.  For
+     example, if is_signed is 0 and there are more digits in the v than
+     fit in n; or if is_signed is 1, v < 0, and n is just 1 bit shy of
+     being large enough to hold a sign bit.  OverflowError is set in this
+     case, but bytes holds the least-signficant n bytes of the true value.
+*/
+PyAPI_FUNC(int) _PyLong_AsByteArray(PyLongObject* v,
+	unsigned char* bytes, size_t n,
+	int little_endian, int is_signed);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_LONGOBJECT_H */

Added: vendor/Python/current/Include/marshal.h
===================================================================
--- vendor/Python/current/Include/marshal.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/marshal.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,25 @@
+
+/* Interface for marshal.c */
+
+#ifndef Py_MARSHAL_H
+#define Py_MARSHAL_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define Py_MARSHAL_VERSION 2
+
+PyAPI_FUNC(void) PyMarshal_WriteLongToFile(long, FILE *, int);
+PyAPI_FUNC(void) PyMarshal_WriteObjectToFile(PyObject *, FILE *, int);
+PyAPI_FUNC(PyObject *) PyMarshal_WriteObjectToString(PyObject *, int);
+
+PyAPI_FUNC(long) PyMarshal_ReadLongFromFile(FILE *);
+PyAPI_FUNC(int) PyMarshal_ReadShortFromFile(FILE *);
+PyAPI_FUNC(PyObject *) PyMarshal_ReadObjectFromFile(FILE *);
+PyAPI_FUNC(PyObject *) PyMarshal_ReadLastObjectFromFile(FILE *);
+PyAPI_FUNC(PyObject *) PyMarshal_ReadObjectFromString(char *, Py_ssize_t);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_MARSHAL_H */

Added: vendor/Python/current/Include/metagrammar.h
===================================================================
--- vendor/Python/current/Include/metagrammar.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/metagrammar.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,18 @@
+#ifndef Py_METAGRAMMAR_H
+#define Py_METAGRAMMAR_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define MSTART 256
+#define RULE 257
+#define RHS 258
+#define ALT 259
+#define ITEM 260
+#define ATOM 261
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_METAGRAMMAR_H */

Added: vendor/Python/current/Include/methodobject.h
===================================================================
--- vendor/Python/current/Include/methodobject.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/methodobject.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,91 @@
+
+/* Method object interface */
+
+#ifndef Py_METHODOBJECT_H
+#define Py_METHODOBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* This is about the type 'builtin_function_or_method',
+   not Python methods in user-defined classes.  See classobject.h
+   for the latter. */
+
+PyAPI_DATA(PyTypeObject) PyCFunction_Type;
+
+#define PyCFunction_Check(op) ((op)->ob_type == &PyCFunction_Type)
+
+typedef PyObject *(*PyCFunction)(PyObject *, PyObject *);
+typedef PyObject *(*PyCFunctionWithKeywords)(PyObject *, PyObject *,
+					     PyObject *);
+typedef PyObject *(*PyNoArgsFunction)(PyObject *);
+
+PyAPI_FUNC(PyCFunction) PyCFunction_GetFunction(PyObject *);
+PyAPI_FUNC(PyObject *) PyCFunction_GetSelf(PyObject *);
+PyAPI_FUNC(int) PyCFunction_GetFlags(PyObject *);
+
+/* Macros for direct access to these values. Type checks are *not*
+   done, so use with care. */
+#define PyCFunction_GET_FUNCTION(func) \
+        (((PyCFunctionObject *)func) -> m_ml -> ml_meth)
+#define PyCFunction_GET_SELF(func) \
+	(((PyCFunctionObject *)func) -> m_self)
+#define PyCFunction_GET_FLAGS(func) \
+	(((PyCFunctionObject *)func) -> m_ml -> ml_flags)
+PyAPI_FUNC(PyObject *) PyCFunction_Call(PyObject *, PyObject *, PyObject *);
+
+struct PyMethodDef {
+    const char	*ml_name;	/* The name of the built-in function/method */
+    PyCFunction  ml_meth;	/* The C function that implements it */
+    int		 ml_flags;	/* Combination of METH_xxx flags, which mostly
+				   describe the args expected by the C func */
+    const char	*ml_doc;	/* The __doc__ attribute, or NULL */
+};
+typedef struct PyMethodDef PyMethodDef;
+
+PyAPI_FUNC(PyObject *) Py_FindMethod(PyMethodDef[], PyObject *, const char *);
+
+#define PyCFunction_New(ML, SELF) PyCFunction_NewEx((ML), (SELF), NULL)
+PyAPI_FUNC(PyObject *) PyCFunction_NewEx(PyMethodDef *, PyObject *, 
+					 PyObject *);
+
+/* Flag passed to newmethodobject */
+#define METH_OLDARGS  0x0000
+#define METH_VARARGS  0x0001
+#define METH_KEYWORDS 0x0002
+/* METH_NOARGS and METH_O must not be combined with the flags above. */
+#define METH_NOARGS   0x0004
+#define METH_O        0x0008
+
+/* METH_CLASS and METH_STATIC are a little different; these control
+   the construction of methods for a class.  These cannot be used for
+   functions in modules. */
+#define METH_CLASS    0x0010
+#define METH_STATIC   0x0020
+
+/* METH_COEXIST allows a method to be entered eventhough a slot has
+   already filled the entry.  When defined, the flag allows a separate
+   method, "__contains__" for example, to coexist with a defined 
+   slot like sq_contains. */
+
+#define METH_COEXIST   0x0040
+
+typedef struct PyMethodChain {
+    PyMethodDef *methods;		/* Methods of this type */
+    struct PyMethodChain *link;	/* NULL or base type */
+} PyMethodChain;
+
+PyAPI_FUNC(PyObject *) Py_FindMethodInChain(PyMethodChain *, PyObject *,
+                                            const char *);
+
+typedef struct {
+    PyObject_HEAD
+    PyMethodDef *m_ml; /* Description of the C function to call */
+    PyObject    *m_self; /* Passed as 'self' arg to the C func, can be NULL */
+    PyObject    *m_module; /* The __module__ attribute, can be anything */
+} PyCFunctionObject;
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_METHODOBJECT_H */

Added: vendor/Python/current/Include/modsupport.h
===================================================================
--- vendor/Python/current/Include/modsupport.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/modsupport.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,133 @@
+
+#ifndef Py_MODSUPPORT_H
+#define Py_MODSUPPORT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Module support interface */
+
+#include <stdarg.h>
+
+/* If PY_SSIZE_T_CLEAN is defined, each functions treats #-specifier
+   to mean Py_ssize_t */
+#ifdef PY_SSIZE_T_CLEAN
+#define PyArg_Parse			_PyArg_Parse_SizeT
+#define PyArg_ParseTuple		_PyArg_ParseTuple_SizeT
+#define PyArg_ParseTupleAndKeywords	_PyArg_ParseTupleAndKeywords_SizeT
+#define PyArg_VaParse			_PyArg_VaParse_SizeT
+#define PyArg_VaParseTupleAndKeywords	_PyArg_VaParseTupleAndKeywords_SizeT
+#define Py_BuildValue			_Py_BuildValue_SizeT
+#define Py_VaBuildValue			_Py_VaBuildValue_SizeT
+#else
+PyAPI_FUNC(PyObject *) _Py_VaBuildValue_SizeT(const char *, va_list);
+#endif
+
+PyAPI_FUNC(int) PyArg_Parse(PyObject *, const char *, ...);
+PyAPI_FUNC(int) PyArg_ParseTuple(PyObject *, const char *, ...);
+PyAPI_FUNC(int) PyArg_ParseTupleAndKeywords(PyObject *, PyObject *,
+                                                  const char *, char **, ...);
+PyAPI_FUNC(int) PyArg_UnpackTuple(PyObject *, const char *, Py_ssize_t, Py_ssize_t, ...);
+PyAPI_FUNC(PyObject *) Py_BuildValue(const char *, ...);
+PyAPI_FUNC(PyObject *) _Py_BuildValue_SizeT(const char *, ...);
+PyAPI_FUNC(int) _PyArg_NoKeywords(const char *funcname, PyObject *kw);
+
+PyAPI_FUNC(int) PyArg_VaParse(PyObject *, const char *, va_list);
+PyAPI_FUNC(int) PyArg_VaParseTupleAndKeywords(PyObject *, PyObject *,
+                                                  const char *, char **, va_list);
+PyAPI_FUNC(PyObject *) Py_VaBuildValue(const char *, va_list);
+
+PyAPI_FUNC(int) PyModule_AddObject(PyObject *, const char *, PyObject *);
+PyAPI_FUNC(int) PyModule_AddIntConstant(PyObject *, const char *, long);
+PyAPI_FUNC(int) PyModule_AddStringConstant(PyObject *, const char *, const char *);
+
+
+#define PYTHON_API_VERSION 1013
+#define PYTHON_API_STRING "1013"
+/* The API version is maintained (independently from the Python version)
+   so we can detect mismatches between the interpreter and dynamically
+   loaded modules.  These are diagnosed by an error message but
+   the module is still loaded (because the mismatch can only be tested
+   after loading the module).  The error message is intended to
+   explain the core dump a few seconds later.
+
+   The symbol PYTHON_API_STRING defines the same value as a string
+   literal.  *** PLEASE MAKE SURE THE DEFINITIONS MATCH. ***
+
+   Please add a line or two to the top of this log for each API
+   version change:
+
+   22-Feb-2006  MvL	1013	PEP 353 - long indices for sequence lengths
+
+   19-Aug-2002  GvR	1012	Changes to string object struct for
+   				interning changes, saving 3 bytes.
+
+   17-Jul-2001	GvR	1011	Descr-branch, just to be on the safe side
+
+   25-Jan-2001  FLD     1010    Parameters added to PyCode_New() and
+                                PyFrame_New(); Python 2.1a2
+
+   14-Mar-2000  GvR     1009    Unicode API added
+
+   3-Jan-1999	GvR	1007	Decided to change back!  (Don't reuse 1008!)
+
+   3-Dec-1998	GvR	1008	Python 1.5.2b1
+
+   18-Jan-1997	GvR	1007	string interning and other speedups
+
+   11-Oct-1996	GvR	renamed Py_Ellipses to Py_Ellipsis :-(
+
+   30-Jul-1996	GvR	Slice and ellipses syntax added
+
+   23-Jul-1996	GvR	For 1.4 -- better safe than sorry this time :-)
+
+   7-Nov-1995	GvR	Keyword arguments (should've been done at 1.3 :-( )
+
+   10-Jan-1995	GvR	Renamed globals to new naming scheme
+
+   9-Jan-1995	GvR	Initial version (incompatible with older API)
+*/
+
+#ifdef MS_WINDOWS
+/* Special defines for Windows versions used to live here.  Things
+   have changed, and the "Version" is now in a global string variable.
+   Reason for this is that this for easier branding of a "custom DLL"
+   without actually needing a recompile.  */
+#endif /* MS_WINDOWS */
+
+#if SIZEOF_SIZE_T != SIZEOF_INT
+/* On a 64-bit system, rename the Py_InitModule4 so that 2.4
+   modules cannot get loaded into a 2.5 interpreter */
+#define Py_InitModule4 Py_InitModule4_64
+#endif
+
+#ifdef Py_TRACE_REFS
+ /* When we are tracing reference counts, rename Py_InitModule4 so
+    modules compiled with incompatible settings will generate a
+    link-time error. */
+ #if SIZEOF_SIZE_T != SIZEOF_INT
+ #undef Py_InitModule4
+ #define Py_InitModule4 Py_InitModule4TraceRefs_64
+ #else
+ #define Py_InitModule4 Py_InitModule4TraceRefs
+ #endif
+#endif
+
+PyAPI_FUNC(PyObject *) Py_InitModule4(const char *name, PyMethodDef *methods,
+                                      const char *doc, PyObject *self,
+                                      int apiver);
+
+#define Py_InitModule(name, methods) \
+	Py_InitModule4(name, methods, (char *)NULL, (PyObject *)NULL, \
+		       PYTHON_API_VERSION)
+
+#define Py_InitModule3(name, methods, doc) \
+	Py_InitModule4(name, methods, doc, (PyObject *)NULL, \
+		       PYTHON_API_VERSION)
+
+PyAPI_DATA(char *) _Py_PackageContext;
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_MODSUPPORT_H */

Added: vendor/Python/current/Include/moduleobject.h
===================================================================
--- vendor/Python/current/Include/moduleobject.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/moduleobject.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,24 @@
+
+/* Module object interface */
+
+#ifndef Py_MODULEOBJECT_H
+#define Py_MODULEOBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+PyAPI_DATA(PyTypeObject) PyModule_Type;
+
+#define PyModule_Check(op) PyObject_TypeCheck(op, &PyModule_Type)
+#define PyModule_CheckExact(op) ((op)->ob_type == &PyModule_Type)
+
+PyAPI_FUNC(PyObject *) PyModule_New(const char *);
+PyAPI_FUNC(PyObject *) PyModule_GetDict(PyObject *);
+PyAPI_FUNC(char *) PyModule_GetName(PyObject *);
+PyAPI_FUNC(char *) PyModule_GetFilename(PyObject *);
+PyAPI_FUNC(void) _PyModule_Clear(PyObject *);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_MODULEOBJECT_H */

Added: vendor/Python/current/Include/node.h
===================================================================
--- vendor/Python/current/Include/node.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/node.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,40 @@
+
+/* Parse tree node interface */
+
+#ifndef Py_NODE_H
+#define Py_NODE_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct _node {
+    short		n_type;
+    char		*n_str;
+    int			n_lineno;
+    int			n_col_offset;
+    int			n_nchildren;
+    struct _node	*n_child;
+} node;
+
+PyAPI_FUNC(node *) PyNode_New(int type);
+PyAPI_FUNC(int) PyNode_AddChild(node *n, int type,
+                                      char *str, int lineno, int col_offset);
+PyAPI_FUNC(void) PyNode_Free(node *n);
+
+/* Node access functions */
+#define NCH(n)		((n)->n_nchildren)
+	
+#define CHILD(n, i)	(&(n)->n_child[i])
+#define RCHILD(n, i)	(CHILD(n, NCH(n) + i))
+#define TYPE(n)		((n)->n_type)
+#define STR(n)		((n)->n_str)
+
+/* Assert that the type of a node is what we expect */
+#define REQ(n, type) assert(TYPE(n) == (type))
+
+PyAPI_FUNC(void) PyNode_ListTree(node *);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_NODE_H */

Added: vendor/Python/current/Include/object.h
===================================================================
--- vendor/Python/current/Include/object.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/object.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,868 @@
+#ifndef Py_OBJECT_H
+#define Py_OBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Object and type object interface */
+
+/*
+Objects are structures allocated on the heap.  Special rules apply to
+the use of objects to ensure they are properly garbage-collected.
+Objects are never allocated statically or on the stack; they must be
+accessed through special macros and functions only.  (Type objects are
+exceptions to the first rule; the standard types are represented by
+statically initialized type objects, although work on type/class unification
+for Python 2.2 made it possible to have heap-allocated type objects too).
+
+An object has a 'reference count' that is increased or decreased when a
+pointer to the object is copied or deleted; when the reference count
+reaches zero there are no references to the object left and it can be
+removed from the heap.
+
+An object has a 'type' that determines what it represents and what kind
+of data it contains.  An object's type is fixed when it is created.
+Types themselves are represented as objects; an object contains a
+pointer to the corresponding type object.  The type itself has a type
+pointer pointing to the object representing the type 'type', which
+contains a pointer to itself!).
+
+Objects do not float around in memory; once allocated an object keeps
+the same size and address.  Objects that must hold variable-size data
+can contain pointers to variable-size parts of the object.  Not all
+objects of the same type have the same size; but the size cannot change
+after allocation.  (These restrictions are made so a reference to an
+object can be simply a pointer -- moving an object would require
+updating all the pointers, and changing an object's size would require
+moving it if there was another object right next to it.)
+
+Objects are always accessed through pointers of the type 'PyObject *'.
+The type 'PyObject' is a structure that only contains the reference count
+and the type pointer.  The actual memory allocated for an object
+contains other data that can only be accessed after casting the pointer
+to a pointer to a longer structure type.  This longer type must start
+with the reference count and type fields; the macro PyObject_HEAD should be
+used for this (to accommodate for future changes).  The implementation
+of a particular object type can cast the object pointer to the proper
+type and back.
+
+A standard interface exists for objects that contain an array of items
+whose size is determined when the object is allocated.
+*/
+
+/* Py_DEBUG implies Py_TRACE_REFS. */
+#if defined(Py_DEBUG) && !defined(Py_TRACE_REFS)
+#define Py_TRACE_REFS
+#endif
+
+/* Py_TRACE_REFS implies Py_REF_DEBUG. */
+#if defined(Py_TRACE_REFS) && !defined(Py_REF_DEBUG)
+#define Py_REF_DEBUG
+#endif
+
+#ifdef Py_TRACE_REFS
+/* Define pointers to support a doubly-linked list of all live heap objects. */
+#define _PyObject_HEAD_EXTRA		\
+	struct _object *_ob_next;	\
+	struct _object *_ob_prev;
+
+#define _PyObject_EXTRA_INIT 0, 0,
+
+#else
+#define _PyObject_HEAD_EXTRA
+#define _PyObject_EXTRA_INIT
+#endif
+
+/* PyObject_HEAD defines the initial segment of every PyObject. */
+#define PyObject_HEAD			\
+	_PyObject_HEAD_EXTRA		\
+	Py_ssize_t ob_refcnt;		\
+	struct _typeobject *ob_type;
+
+#define PyObject_HEAD_INIT(type)	\
+	_PyObject_EXTRA_INIT		\
+	1, type,
+
+/* PyObject_VAR_HEAD defines the initial segment of all variable-size
+ * container objects.  These end with a declaration of an array with 1
+ * element, but enough space is malloc'ed so that the array actually
+ * has room for ob_size elements.  Note that ob_size is an element count,
+ * not necessarily a byte count.
+ */
+#define PyObject_VAR_HEAD		\
+	PyObject_HEAD			\
+	Py_ssize_t ob_size; /* Number of items in variable part */
+#define Py_INVALID_SIZE (Py_ssize_t)-1
+
+/* Nothing is actually declared to be a PyObject, but every pointer to
+ * a Python object can be cast to a PyObject*.  This is inheritance built
+ * by hand.  Similarly every pointer to a variable-size Python object can,
+ * in addition, be cast to PyVarObject*.
+ */
+typedef struct _object {
+	PyObject_HEAD
+} PyObject;
+
+typedef struct {
+	PyObject_VAR_HEAD
+} PyVarObject;
+
+
+/*
+Type objects contain a string containing the type name (to help somewhat
+in debugging), the allocation parameters (see PyObject_New() and
+PyObject_NewVar()),
+and methods for accessing objects of the type.  Methods are optional, a
+nil pointer meaning that particular kind of access is not available for
+this type.  The Py_DECREF() macro uses the tp_dealloc method without
+checking for a nil pointer; it should always be implemented except if
+the implementation can guarantee that the reference count will never
+reach zero (e.g., for statically allocated type objects).
+
+NB: the methods for certain type groups are now contained in separate
+method blocks.
+*/
+
+typedef PyObject * (*unaryfunc)(PyObject *);
+typedef PyObject * (*binaryfunc)(PyObject *, PyObject *);
+typedef PyObject * (*ternaryfunc)(PyObject *, PyObject *, PyObject *);
+typedef int (*inquiry)(PyObject *);
+typedef Py_ssize_t (*lenfunc)(PyObject *);
+typedef int (*coercion)(PyObject **, PyObject **);
+typedef PyObject *(*intargfunc)(PyObject *, int) Py_DEPRECATED(2.5);
+typedef PyObject *(*intintargfunc)(PyObject *, int, int) Py_DEPRECATED(2.5);
+typedef PyObject *(*ssizeargfunc)(PyObject *, Py_ssize_t);
+typedef PyObject *(*ssizessizeargfunc)(PyObject *, Py_ssize_t, Py_ssize_t);
+typedef int(*intobjargproc)(PyObject *, int, PyObject *);
+typedef int(*intintobjargproc)(PyObject *, int, int, PyObject *);
+typedef int(*ssizeobjargproc)(PyObject *, Py_ssize_t, PyObject *);
+typedef int(*ssizessizeobjargproc)(PyObject *, Py_ssize_t, Py_ssize_t, PyObject *);
+typedef int(*objobjargproc)(PyObject *, PyObject *, PyObject *);
+
+/* int-based buffer interface */
+typedef int (*getreadbufferproc)(PyObject *, int, void **);
+typedef int (*getwritebufferproc)(PyObject *, int, void **);
+typedef int (*getsegcountproc)(PyObject *, int *);
+typedef int (*getcharbufferproc)(PyObject *, int, char **);
+/* ssize_t-based buffer interface */
+typedef Py_ssize_t (*readbufferproc)(PyObject *, Py_ssize_t, void **);
+typedef Py_ssize_t (*writebufferproc)(PyObject *, Py_ssize_t, void **);
+typedef Py_ssize_t (*segcountproc)(PyObject *, Py_ssize_t *);
+typedef Py_ssize_t (*charbufferproc)(PyObject *, Py_ssize_t, char **);
+
+typedef int (*objobjproc)(PyObject *, PyObject *);
+typedef int (*visitproc)(PyObject *, void *);
+typedef int (*traverseproc)(PyObject *, visitproc, void *);
+
+typedef struct {
+	/* For numbers without flag bit Py_TPFLAGS_CHECKTYPES set, all
+	   arguments are guaranteed to be of the object's type (modulo
+	   coercion hacks -- i.e. if the type's coercion function
+	   returns other types, then these are allowed as well).  Numbers that
+	   have the Py_TPFLAGS_CHECKTYPES flag bit set should check *both*
+	   arguments for proper type and implement the necessary conversions
+	   in the slot functions themselves. */
+
+	binaryfunc nb_add;
+	binaryfunc nb_subtract;
+	binaryfunc nb_multiply;
+	binaryfunc nb_divide;
+	binaryfunc nb_remainder;
+	binaryfunc nb_divmod;
+	ternaryfunc nb_power;
+	unaryfunc nb_negative;
+	unaryfunc nb_positive;
+	unaryfunc nb_absolute;
+	inquiry nb_nonzero;
+	unaryfunc nb_invert;
+	binaryfunc nb_lshift;
+	binaryfunc nb_rshift;
+	binaryfunc nb_and;
+	binaryfunc nb_xor;
+	binaryfunc nb_or;
+	coercion nb_coerce;
+	unaryfunc nb_int;
+	unaryfunc nb_long;
+	unaryfunc nb_float;
+	unaryfunc nb_oct;
+	unaryfunc nb_hex;
+	/* Added in release 2.0 */
+	binaryfunc nb_inplace_add;
+	binaryfunc nb_inplace_subtract;
+	binaryfunc nb_inplace_multiply;
+	binaryfunc nb_inplace_divide;
+	binaryfunc nb_inplace_remainder;
+	ternaryfunc nb_inplace_power;
+	binaryfunc nb_inplace_lshift;
+	binaryfunc nb_inplace_rshift;
+	binaryfunc nb_inplace_and;
+	binaryfunc nb_inplace_xor;
+	binaryfunc nb_inplace_or;
+
+	/* Added in release 2.2 */
+	/* The following require the Py_TPFLAGS_HAVE_CLASS flag */
+	binaryfunc nb_floor_divide;
+	binaryfunc nb_true_divide;
+	binaryfunc nb_inplace_floor_divide;
+	binaryfunc nb_inplace_true_divide;
+
+	/* Added in release 2.5 */
+	unaryfunc nb_index;
+} PyNumberMethods;
+
+typedef struct {
+	lenfunc sq_length;
+	binaryfunc sq_concat;
+	ssizeargfunc sq_repeat;
+	ssizeargfunc sq_item;
+	ssizessizeargfunc sq_slice;
+	ssizeobjargproc sq_ass_item;
+	ssizessizeobjargproc sq_ass_slice;
+	objobjproc sq_contains;
+	/* Added in release 2.0 */
+	binaryfunc sq_inplace_concat;
+	ssizeargfunc sq_inplace_repeat;
+} PySequenceMethods;
+
+typedef struct {
+	lenfunc mp_length;
+	binaryfunc mp_subscript;
+	objobjargproc mp_ass_subscript;
+} PyMappingMethods;
+
+typedef struct {
+	readbufferproc bf_getreadbuffer;
+	writebufferproc bf_getwritebuffer;
+	segcountproc bf_getsegcount;
+	charbufferproc bf_getcharbuffer;
+} PyBufferProcs;
+
+
+typedef void (*freefunc)(void *);
+typedef void (*destructor)(PyObject *);
+typedef int (*printfunc)(PyObject *, FILE *, int);
+typedef PyObject *(*getattrfunc)(PyObject *, char *);
+typedef PyObject *(*getattrofunc)(PyObject *, PyObject *);
+typedef int (*setattrfunc)(PyObject *, char *, PyObject *);
+typedef int (*setattrofunc)(PyObject *, PyObject *, PyObject *);
+typedef int (*cmpfunc)(PyObject *, PyObject *);
+typedef PyObject *(*reprfunc)(PyObject *);
+typedef long (*hashfunc)(PyObject *);
+typedef PyObject *(*richcmpfunc) (PyObject *, PyObject *, int);
+typedef PyObject *(*getiterfunc) (PyObject *);
+typedef PyObject *(*iternextfunc) (PyObject *);
+typedef PyObject *(*descrgetfunc) (PyObject *, PyObject *, PyObject *);
+typedef int (*descrsetfunc) (PyObject *, PyObject *, PyObject *);
+typedef int (*initproc)(PyObject *, PyObject *, PyObject *);
+typedef PyObject *(*newfunc)(struct _typeobject *, PyObject *, PyObject *);
+typedef PyObject *(*allocfunc)(struct _typeobject *, Py_ssize_t);
+
+typedef struct _typeobject {
+	PyObject_VAR_HEAD
+	const char *tp_name; /* For printing, in format "<module>.<name>" */
+	Py_ssize_t tp_basicsize, tp_itemsize; /* For allocation */
+
+	/* Methods to implement standard operations */
+
+	destructor tp_dealloc;
+	printfunc tp_print;
+	getattrfunc tp_getattr;
+	setattrfunc tp_setattr;
+	cmpfunc tp_compare;
+	reprfunc tp_repr;
+
+	/* Method suites for standard classes */
+
+	PyNumberMethods *tp_as_number;
+	PySequenceMethods *tp_as_sequence;
+	PyMappingMethods *tp_as_mapping;
+
+	/* More standard operations (here for binary compatibility) */
+
+	hashfunc tp_hash;
+	ternaryfunc tp_call;
+	reprfunc tp_str;
+	getattrofunc tp_getattro;
+	setattrofunc tp_setattro;
+
+	/* Functions to access object as input/output buffer */
+	PyBufferProcs *tp_as_buffer;
+
+	/* Flags to define presence of optional/expanded features */
+	long tp_flags;
+
+	const char *tp_doc; /* Documentation string */
+
+	/* Assigned meaning in release 2.0 */
+	/* call function for all accessible objects */
+	traverseproc tp_traverse;
+
+	/* delete references to contained objects */
+	inquiry tp_clear;
+
+	/* Assigned meaning in release 2.1 */
+	/* rich comparisons */
+	richcmpfunc tp_richcompare;
+
+	/* weak reference enabler */
+	Py_ssize_t tp_weaklistoffset;
+
+	/* Added in release 2.2 */
+	/* Iterators */
+	getiterfunc tp_iter;
+	iternextfunc tp_iternext;
+
+	/* Attribute descriptor and subclassing stuff */
+	struct PyMethodDef *tp_methods;
+	struct PyMemberDef *tp_members;
+	struct PyGetSetDef *tp_getset;
+	struct _typeobject *tp_base;
+	PyObject *tp_dict;
+	descrgetfunc tp_descr_get;
+	descrsetfunc tp_descr_set;
+	Py_ssize_t tp_dictoffset;
+	initproc tp_init;
+	allocfunc tp_alloc;
+	newfunc tp_new;
+	freefunc tp_free; /* Low-level free-memory routine */
+	inquiry tp_is_gc; /* For PyObject_IS_GC */
+	PyObject *tp_bases;
+	PyObject *tp_mro; /* method resolution order */
+	PyObject *tp_cache;
+	PyObject *tp_subclasses;
+	PyObject *tp_weaklist;
+	destructor tp_del;
+
+#ifdef COUNT_ALLOCS
+	/* these must be last and never explicitly initialized */
+	Py_ssize_t tp_allocs;
+	Py_ssize_t tp_frees;
+	Py_ssize_t tp_maxalloc;
+	struct _typeobject *tp_prev;
+	struct _typeobject *tp_next;
+#endif
+} PyTypeObject;
+
+
+/* The *real* layout of a type object when allocated on the heap */
+typedef struct _heaptypeobject {
+	/* Note: there's a dependency on the order of these members
+	   in slotptr() in typeobject.c . */
+	PyTypeObject ht_type;
+	PyNumberMethods as_number;
+	PyMappingMethods as_mapping;
+	PySequenceMethods as_sequence; /* as_sequence comes after as_mapping,
+					  so that the mapping wins when both
+					  the mapping and the sequence define
+					  a given operator (e.g. __getitem__).
+					  see add_operators() in typeobject.c . */
+	PyBufferProcs as_buffer;
+	PyObject *ht_name, *ht_slots;
+	/* here are optional user slots, followed by the members. */
+} PyHeapTypeObject;
+
+/* access macro to the members which are floating "behind" the object */
+#define PyHeapType_GET_MEMBERS(etype) \
+    ((PyMemberDef *)(((char *)etype) + (etype)->ht_type.ob_type->tp_basicsize))
+
+
+/* Generic type check */
+PyAPI_FUNC(int) PyType_IsSubtype(PyTypeObject *, PyTypeObject *);
+#define PyObject_TypeCheck(ob, tp) \
+	((ob)->ob_type == (tp) || PyType_IsSubtype((ob)->ob_type, (tp)))
+
+PyAPI_DATA(PyTypeObject) PyType_Type; /* built-in 'type' */
+PyAPI_DATA(PyTypeObject) PyBaseObject_Type; /* built-in 'object' */
+PyAPI_DATA(PyTypeObject) PySuper_Type; /* built-in 'super' */
+
+#define PyType_Check(op) PyObject_TypeCheck(op, &PyType_Type)
+#define PyType_CheckExact(op) ((op)->ob_type == &PyType_Type)
+
+PyAPI_FUNC(int) PyType_Ready(PyTypeObject *);
+PyAPI_FUNC(PyObject *) PyType_GenericAlloc(PyTypeObject *, Py_ssize_t);
+PyAPI_FUNC(PyObject *) PyType_GenericNew(PyTypeObject *,
+					       PyObject *, PyObject *);
+PyAPI_FUNC(PyObject *) _PyType_Lookup(PyTypeObject *, PyObject *);
+
+/* Generic operations on objects */
+PyAPI_FUNC(int) PyObject_Print(PyObject *, FILE *, int);
+PyAPI_FUNC(void) _PyObject_Dump(PyObject *);
+PyAPI_FUNC(PyObject *) PyObject_Repr(PyObject *);
+PyAPI_FUNC(PyObject *) _PyObject_Str(PyObject *);
+PyAPI_FUNC(PyObject *) PyObject_Str(PyObject *);
+#ifdef Py_USING_UNICODE
+PyAPI_FUNC(PyObject *) PyObject_Unicode(PyObject *);
+#endif
+PyAPI_FUNC(int) PyObject_Compare(PyObject *, PyObject *);
+PyAPI_FUNC(PyObject *) PyObject_RichCompare(PyObject *, PyObject *, int);
+PyAPI_FUNC(int) PyObject_RichCompareBool(PyObject *, PyObject *, int);
+PyAPI_FUNC(PyObject *) PyObject_GetAttrString(PyObject *, const char *);
+PyAPI_FUNC(int) PyObject_SetAttrString(PyObject *, const char *, PyObject *);
+PyAPI_FUNC(int) PyObject_HasAttrString(PyObject *, const char *);
+PyAPI_FUNC(PyObject *) PyObject_GetAttr(PyObject *, PyObject *);
+PyAPI_FUNC(int) PyObject_SetAttr(PyObject *, PyObject *, PyObject *);
+PyAPI_FUNC(int) PyObject_HasAttr(PyObject *, PyObject *);
+PyAPI_FUNC(PyObject **) _PyObject_GetDictPtr(PyObject *);
+PyAPI_FUNC(PyObject *) PyObject_SelfIter(PyObject *);
+PyAPI_FUNC(PyObject *) PyObject_GenericGetAttr(PyObject *, PyObject *);
+PyAPI_FUNC(int) PyObject_GenericSetAttr(PyObject *,
+					      PyObject *, PyObject *);
+PyAPI_FUNC(long) PyObject_Hash(PyObject *);
+PyAPI_FUNC(int) PyObject_IsTrue(PyObject *);
+PyAPI_FUNC(int) PyObject_Not(PyObject *);
+PyAPI_FUNC(int) PyCallable_Check(PyObject *);
+PyAPI_FUNC(int) PyNumber_Coerce(PyObject **, PyObject **);
+PyAPI_FUNC(int) PyNumber_CoerceEx(PyObject **, PyObject **);
+
+PyAPI_FUNC(void) PyObject_ClearWeakRefs(PyObject *);
+
+/* A slot function whose address we need to compare */
+extern int _PyObject_SlotCompare(PyObject *, PyObject *);
+
+
+/* PyObject_Dir(obj) acts like Python __builtin__.dir(obj), returning a
+   list of strings.  PyObject_Dir(NULL) is like __builtin__.dir(),
+   returning the names of the current locals.  In this case, if there are
+   no current locals, NULL is returned, and PyErr_Occurred() is false.
+*/
+PyAPI_FUNC(PyObject *) PyObject_Dir(PyObject *);
+
+
+/* Helpers for printing recursive container types */
+PyAPI_FUNC(int) Py_ReprEnter(PyObject *);
+PyAPI_FUNC(void) Py_ReprLeave(PyObject *);
+
+/* Helpers for hash functions */
+PyAPI_FUNC(long) _Py_HashDouble(double);
+PyAPI_FUNC(long) _Py_HashPointer(void*);
+
+/* Helper for passing objects to printf and the like */
+#define PyObject_REPR(obj) PyString_AS_STRING(PyObject_Repr(obj))
+
+/* Flag bits for printing: */
+#define Py_PRINT_RAW	1	/* No string quotes etc. */
+
+/*
+`Type flags (tp_flags)
+
+These flags are used to extend the type structure in a backwards-compatible
+fashion. Extensions can use the flags to indicate (and test) when a given
+type structure contains a new feature. The Python core will use these when
+introducing new functionality between major revisions (to avoid mid-version
+changes in the PYTHON_API_VERSION).
+
+Arbitration of the flag bit positions will need to be coordinated among
+all extension writers who publically release their extensions (this will
+be fewer than you might expect!)..
+
+Python 1.5.2 introduced the bf_getcharbuffer slot into PyBufferProcs.
+
+Type definitions should use Py_TPFLAGS_DEFAULT for their tp_flags value.
+
+Code can use PyType_HasFeature(type_ob, flag_value) to test whether the
+given type object has a specified feature.
+*/
+
+/* PyBufferProcs contains bf_getcharbuffer */
+#define Py_TPFLAGS_HAVE_GETCHARBUFFER  (1L<<0)
+
+/* PySequenceMethods contains sq_contains */
+#define Py_TPFLAGS_HAVE_SEQUENCE_IN (1L<<1)
+
+/* This is here for backwards compatibility.  Extensions that use the old GC
+ * API will still compile but the objects will not be tracked by the GC. */
+#define Py_TPFLAGS_GC 0 /* used to be (1L<<2) */
+
+/* PySequenceMethods and PyNumberMethods contain in-place operators */
+#define Py_TPFLAGS_HAVE_INPLACEOPS (1L<<3)
+
+/* PyNumberMethods do their own coercion */
+#define Py_TPFLAGS_CHECKTYPES (1L<<4)
+
+/* tp_richcompare is defined */
+#define Py_TPFLAGS_HAVE_RICHCOMPARE (1L<<5)
+
+/* Objects which are weakly referencable if their tp_weaklistoffset is >0 */
+#define Py_TPFLAGS_HAVE_WEAKREFS (1L<<6)
+
+/* tp_iter is defined */
+#define Py_TPFLAGS_HAVE_ITER (1L<<7)
+
+/* New members introduced by Python 2.2 exist */
+#define Py_TPFLAGS_HAVE_CLASS (1L<<8)
+
+/* Set if the type object is dynamically allocated */
+#define Py_TPFLAGS_HEAPTYPE (1L<<9)
+
+/* Set if the type allows subclassing */
+#define Py_TPFLAGS_BASETYPE (1L<<10)
+
+/* Set if the type is 'ready' -- fully initialized */
+#define Py_TPFLAGS_READY (1L<<12)
+
+/* Set while the type is being 'readied', to prevent recursive ready calls */
+#define Py_TPFLAGS_READYING (1L<<13)
+
+/* Objects support garbage collection (see objimp.h) */
+#define Py_TPFLAGS_HAVE_GC (1L<<14)
+
+/* These two bits are preserved for Stackless Python, next after this is 17 */
+#ifdef STACKLESS
+#define Py_TPFLAGS_HAVE_STACKLESS_EXTENSION (3L<<15)
+#else
+#define Py_TPFLAGS_HAVE_STACKLESS_EXTENSION 0
+#endif
+
+/* Objects support nb_index in PyNumberMethods */
+#define Py_TPFLAGS_HAVE_INDEX (1L<<17)
+
+#define Py_TPFLAGS_DEFAULT  ( \
+                             Py_TPFLAGS_HAVE_GETCHARBUFFER | \
+                             Py_TPFLAGS_HAVE_SEQUENCE_IN | \
+                             Py_TPFLAGS_HAVE_INPLACEOPS | \
+                             Py_TPFLAGS_HAVE_RICHCOMPARE | \
+                             Py_TPFLAGS_HAVE_WEAKREFS | \
+                             Py_TPFLAGS_HAVE_ITER | \
+                             Py_TPFLAGS_HAVE_CLASS | \
+                             Py_TPFLAGS_HAVE_STACKLESS_EXTENSION | \
+                             Py_TPFLAGS_HAVE_INDEX | \
+                            0)
+
+#define PyType_HasFeature(t,f)  (((t)->tp_flags & (f)) != 0)
+
+
+/*
+The macros Py_INCREF(op) and Py_DECREF(op) are used to increment or decrement
+reference counts.  Py_DECREF calls the object's deallocator function when
+the refcount falls to 0; for
+objects that don't contain references to other objects or heap memory
+this can be the standard function free().  Both macros can be used
+wherever a void expression is allowed.  The argument must not be a
+NIL pointer.  If it may be NIL, use Py_XINCREF/Py_XDECREF instead.
+The macro _Py_NewReference(op) initialize reference counts to 1, and
+in special builds (Py_REF_DEBUG, Py_TRACE_REFS) performs additional
+bookkeeping appropriate to the special build.
+
+We assume that the reference count field can never overflow; this can
+be proven when the size of the field is the same as the pointer size, so
+we ignore the possibility.  Provided a C int is at least 32 bits (which
+is implicitly assumed in many parts of this code), that's enough for
+about 2**31 references to an object.
+
+XXX The following became out of date in Python 2.2, but I'm not sure
+XXX what the full truth is now.  Certainly, heap-allocated type objects
+XXX can and should be deallocated.
+Type objects should never be deallocated; the type pointer in an object
+is not considered to be a reference to the type object, to save
+complications in the deallocation function.  (This is actually a
+decision that's up to the implementer of each new type so if you want,
+you can count such references to the type object.)
+
+*** WARNING*** The Py_DECREF macro must have a side-effect-free argument
+since it may evaluate its argument multiple times.  (The alternative
+would be to mace it a proper function or assign it to a global temporary
+variable first, both of which are slower; and in a multi-threaded
+environment the global variable trick is not safe.)
+*/
+
+/* First define a pile of simple helper macros, one set per special
+ * build symbol.  These either expand to the obvious things, or to
+ * nothing at all when the special mode isn't in effect.  The main
+ * macros can later be defined just once then, yet expand to different
+ * things depending on which special build options are and aren't in effect.
+ * Trust me <wink>:  while painful, this is 20x easier to understand than,
+ * e.g, defining _Py_NewReference five different times in a maze of nested
+ * #ifdefs (we used to do that -- it was impenetrable).
+ */
+#ifdef Py_REF_DEBUG
+PyAPI_DATA(Py_ssize_t) _Py_RefTotal;
+PyAPI_FUNC(void) _Py_NegativeRefcount(const char *fname,
+					    int lineno, PyObject *op);
+PyAPI_FUNC(PyObject *) _PyDict_Dummy(void);
+PyAPI_FUNC(PyObject *) _PySet_Dummy(void);
+PyAPI_FUNC(Py_ssize_t) _Py_GetRefTotal(void);
+#define _Py_INC_REFTOTAL	_Py_RefTotal++
+#define _Py_DEC_REFTOTAL	_Py_RefTotal--
+#define _Py_REF_DEBUG_COMMA	,
+#define _Py_CHECK_REFCNT(OP)					\
+{	if ((OP)->ob_refcnt < 0)				\
+		_Py_NegativeRefcount(__FILE__, __LINE__,	\
+				     (PyObject *)(OP));		\
+}
+#else
+#define _Py_INC_REFTOTAL
+#define _Py_DEC_REFTOTAL
+#define _Py_REF_DEBUG_COMMA
+#define _Py_CHECK_REFCNT(OP)	/* a semicolon */;
+#endif /* Py_REF_DEBUG */
+
+#ifdef COUNT_ALLOCS
+PyAPI_FUNC(void) inc_count(PyTypeObject *);
+PyAPI_FUNC(void) dec_count(PyTypeObject *);
+#define _Py_INC_TPALLOCS(OP)	inc_count((OP)->ob_type)
+#define _Py_INC_TPFREES(OP)	dec_count((OP)->ob_type)
+#define _Py_DEC_TPFREES(OP)	(OP)->ob_type->tp_frees--
+#define _Py_COUNT_ALLOCS_COMMA	,
+#else
+#define _Py_INC_TPALLOCS(OP)
+#define _Py_INC_TPFREES(OP)
+#define _Py_DEC_TPFREES(OP)
+#define _Py_COUNT_ALLOCS_COMMA
+#endif /* COUNT_ALLOCS */
+
+#ifdef Py_TRACE_REFS
+/* Py_TRACE_REFS is such major surgery that we call external routines. */
+PyAPI_FUNC(void) _Py_NewReference(PyObject *);
+PyAPI_FUNC(void) _Py_ForgetReference(PyObject *);
+PyAPI_FUNC(void) _Py_Dealloc(PyObject *);
+PyAPI_FUNC(void) _Py_PrintReferences(FILE *);
+PyAPI_FUNC(void) _Py_PrintReferenceAddresses(FILE *);
+PyAPI_FUNC(void) _Py_AddToAllObjects(PyObject *, int force);
+
+#else
+/* Without Py_TRACE_REFS, there's little enough to do that we expand code
+ * inline.
+ */
+#define _Py_NewReference(op) (				\
+	_Py_INC_TPALLOCS(op) _Py_COUNT_ALLOCS_COMMA	\
+	_Py_INC_REFTOTAL  _Py_REF_DEBUG_COMMA		\
+	(op)->ob_refcnt = 1)
+
+#define _Py_ForgetReference(op) _Py_INC_TPFREES(op)
+
+#define _Py_Dealloc(op) (				\
+	_Py_INC_TPFREES(op) _Py_COUNT_ALLOCS_COMMA	\
+	(*(op)->ob_type->tp_dealloc)((PyObject *)(op)))
+#endif /* !Py_TRACE_REFS */
+
+#define Py_INCREF(op) (				\
+	_Py_INC_REFTOTAL  _Py_REF_DEBUG_COMMA	\
+	(op)->ob_refcnt++)
+
+#define Py_DECREF(op)					\
+	if (_Py_DEC_REFTOTAL  _Py_REF_DEBUG_COMMA	\
+	    --(op)->ob_refcnt != 0)			\
+		_Py_CHECK_REFCNT(op)			\
+	else						\
+		_Py_Dealloc((PyObject *)(op))
+
+/* Safely decref `op` and set `op` to NULL, especially useful in tp_clear
+ * and tp_dealloc implementatons.
+ *
+ * Note that "the obvious" code can be deadly:
+ *
+ *     Py_XDECREF(op);
+ *     op = NULL;
+ *
+ * Typically, `op` is something like self->containee, and `self` is done
+ * using its `containee` member.  In the code sequence above, suppose
+ * `containee` is non-NULL with a refcount of 1.  Its refcount falls to
+ * 0 on the first line, which can trigger an arbitrary amount of code,
+ * possibly including finalizers (like __del__ methods or weakref callbacks)
+ * coded in Python, which in turn can release the GIL and allow other threads
+ * to run, etc.  Such code may even invoke methods of `self` again, or cause
+ * cyclic gc to trigger, but-- oops! --self->containee still points to the
+ * object being torn down, and it may be in an insane state while being torn
+ * down.  This has in fact been a rich historic source of miserable (rare &
+ * hard-to-diagnose) segfaulting (and other) bugs.
+ *
+ * The safe way is:
+ *
+ *      Py_CLEAR(op);
+ *
+ * That arranges to set `op` to NULL _before_ decref'ing, so that any code
+ * triggered as a side-effect of `op` getting torn down no longer believes
+ * `op` points to a valid object.
+ *
+ * There are cases where it's safe to use the naive code, but they're brittle.
+ * For example, if `op` points to a Python integer, you know that destroying
+ * one of those can't cause problems -- but in part that relies on that
+ * Python integers aren't currently weakly referencable.  Best practice is
+ * to use Py_CLEAR() even if you can't think of a reason for why you need to.
+ */
+#define Py_CLEAR(op)				\
+        do {                            	\
+                if (op) {			\
+                        PyObject *tmp = (PyObject *)(op);	\
+                        (op) = NULL;		\
+                        Py_DECREF(tmp);		\
+                }				\
+        } while (0)
+
+/* Macros to use in case the object pointer may be NULL: */
+#define Py_XINCREF(op) if ((op) == NULL) ; else Py_INCREF(op)
+#define Py_XDECREF(op) if ((op) == NULL) ; else Py_DECREF(op)
+
+/*
+These are provided as conveniences to Python runtime embedders, so that
+they can have object code that is not dependent on Python compilation flags.
+*/
+PyAPI_FUNC(void) Py_IncRef(PyObject *);
+PyAPI_FUNC(void) Py_DecRef(PyObject *);
+
+/*
+_Py_NoneStruct is an object of undefined type which can be used in contexts
+where NULL (nil) is not suitable (since NULL often means 'error').
+
+Don't forget to apply Py_INCREF() when returning this value!!!
+*/
+PyAPI_DATA(PyObject) _Py_NoneStruct; /* Don't use this directly */
+#define Py_None (&_Py_NoneStruct)
+
+/* Macro for returning Py_None from a function */
+#define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
+
+/*
+Py_NotImplemented is a singleton used to signal that an operation is
+not implemented for a given type combination.
+*/
+PyAPI_DATA(PyObject) _Py_NotImplementedStruct; /* Don't use this directly */
+#define Py_NotImplemented (&_Py_NotImplementedStruct)
+
+/* Rich comparison opcodes */
+#define Py_LT 0
+#define Py_LE 1
+#define Py_EQ 2
+#define Py_NE 3
+#define Py_GT 4
+#define Py_GE 5
+
+/* Maps Py_LT to Py_GT, ..., Py_GE to Py_LE.
+ * Defined in object.c.
+ */
+PyAPI_DATA(int) _Py_SwappedOp[];
+
+/*
+Define staticforward and statichere for source compatibility with old
+C extensions.
+
+The staticforward define was needed to support certain broken C
+compilers (notably SCO ODT 3.0, perhaps early AIX as well) botched the
+static keyword when it was used with a forward declaration of a static
+initialized structure.  Standard C allows the forward declaration with
+static, and we've decided to stop catering to broken C compilers.
+(In fact, we expect that the compilers are all fixed eight years later.)
+*/
+
+#define staticforward static
+#define statichere static
+
+
+/*
+More conventions
+================
+
+Argument Checking
+-----------------
+
+Functions that take objects as arguments normally don't check for nil
+arguments, but they do check the type of the argument, and return an
+error if the function doesn't apply to the type.
+
+Failure Modes
+-------------
+
+Functions may fail for a variety of reasons, including running out of
+memory.  This is communicated to the caller in two ways: an error string
+is set (see errors.h), and the function result differs: functions that
+normally return a pointer return NULL for failure, functions returning
+an integer return -1 (which could be a legal return value too!), and
+other functions return 0 for success and -1 for failure.
+Callers should always check for errors before using the result.  If
+an error was set, the caller must either explicitly clear it, or pass
+the error on to its caller.
+
+Reference Counts
+----------------
+
+It takes a while to get used to the proper usage of reference counts.
+
+Functions that create an object set the reference count to 1; such new
+objects must be stored somewhere or destroyed again with Py_DECREF().
+Some functions that 'store' objects, such as PyTuple_SetItem() and
+PyList_SetItem(),
+don't increment the reference count of the object, since the most
+frequent use is to store a fresh object.  Functions that 'retrieve'
+objects, such as PyTuple_GetItem() and PyDict_GetItemString(), also
+don't increment
+the reference count, since most frequently the object is only looked at
+quickly.  Thus, to retrieve an object and store it again, the caller
+must call Py_INCREF() explicitly.
+
+NOTE: functions that 'consume' a reference count, like
+PyList_SetItem(), consume the reference even if the object wasn't
+successfully stored, to simplify error handling.
+
+It seems attractive to make other functions that take an object as
+argument consume a reference count; however, this may quickly get
+confusing (even the current practice is already confusing).  Consider
+it carefully, it may save lots of calls to Py_INCREF() and Py_DECREF() at
+times.
+*/
+
+
+/* Trashcan mechanism, thanks to Christian Tismer.
+
+When deallocating a container object, it's possible to trigger an unbounded
+chain of deallocations, as each Py_DECREF in turn drops the refcount on "the
+next" object in the chain to 0.  This can easily lead to stack faults, and
+especially in threads (which typically have less stack space to work with).
+
+A container object that participates in cyclic gc can avoid this by
+bracketing the body of its tp_dealloc function with a pair of macros:
+
+static void
+mytype_dealloc(mytype *p)
+{
+        ... declarations go here ...
+
+ 	PyObject_GC_UnTrack(p);	   // must untrack first
+	Py_TRASHCAN_SAFE_BEGIN(p)
+	... The body of the deallocator goes here, including all calls ...
+	... to Py_DECREF on contained objects.                         ...
+	Py_TRASHCAN_SAFE_END(p)
+}
+
+CAUTION:  Never return from the middle of the body!  If the body needs to
+"get out early", put a label immediately before the Py_TRASHCAN_SAFE_END
+call, and goto it.  Else the call-depth counter (see below) will stay
+above 0 forever, and the trashcan will never get emptied.
+
+How it works:  The BEGIN macro increments a call-depth counter.  So long
+as this counter is small, the body of the deallocator is run directly without
+further ado.  But if the counter gets large, it instead adds p to a list of
+objects to be deallocated later, skips the body of the deallocator, and
+resumes execution after the END macro.  The tp_dealloc routine then returns
+without deallocating anything (and so unbounded call-stack depth is avoided).
+
+When the call stack finishes unwinding again, code generated by the END macro
+notices this, and calls another routine to deallocate all the objects that
+may have been added to the list of deferred deallocations.  In effect, a
+chain of N deallocations is broken into N / PyTrash_UNWIND_LEVEL pieces,
+with the call stack never exceeding a depth of PyTrash_UNWIND_LEVEL.
+*/
+
+PyAPI_FUNC(void) _PyTrash_deposit_object(PyObject*);
+PyAPI_FUNC(void) _PyTrash_destroy_chain(void);
+PyAPI_DATA(int) _PyTrash_delete_nesting;
+PyAPI_DATA(PyObject *) _PyTrash_delete_later;
+
+#define PyTrash_UNWIND_LEVEL 50
+
+#define Py_TRASHCAN_SAFE_BEGIN(op) \
+	if (_PyTrash_delete_nesting < PyTrash_UNWIND_LEVEL) { \
+		++_PyTrash_delete_nesting;
+		/* The body of the deallocator is here. */
+#define Py_TRASHCAN_SAFE_END(op) \
+		--_PyTrash_delete_nesting; \
+		if (_PyTrash_delete_later && _PyTrash_delete_nesting <= 0) \
+			_PyTrash_destroy_chain(); \
+	} \
+	else \
+		_PyTrash_deposit_object((PyObject*)op);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_OBJECT_H */

Added: vendor/Python/current/Include/objimpl.h
===================================================================
--- vendor/Python/current/Include/objimpl.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/objimpl.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,336 @@
+/* The PyObject_ memory family:  high-level object memory interfaces.
+   See pymem.h for the low-level PyMem_ family.
+*/
+
+#ifndef Py_OBJIMPL_H
+#define Py_OBJIMPL_H
+
+#include "pymem.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* BEWARE:
+
+   Each interface exports both functions and macros.  Extension modules should
+   use the functions, to ensure binary compatibility across Python versions.
+   Because the Python implementation is free to change internal details, and
+   the macros may (or may not) expose details for speed, if you do use the
+   macros you must recompile your extensions with each Python release.
+
+   Never mix calls to PyObject_ memory functions with calls to the platform
+   malloc/realloc/ calloc/free, or with calls to PyMem_.
+*/
+
+/*
+Functions and macros for modules that implement new object types.
+
+ - PyObject_New(type, typeobj) allocates memory for a new object of the given
+   type, and initializes part of it.  'type' must be the C structure type used
+   to represent the object, and 'typeobj' the address of the corresponding
+   type object.  Reference count and type pointer are filled in; the rest of
+   the bytes of the object are *undefined*!  The resulting expression type is
+   'type *'.  The size of the object is determined by the tp_basicsize field
+   of the type object.
+
+ - PyObject_NewVar(type, typeobj, n) is similar but allocates a variable-size
+   object with room for n items.  In addition to the refcount and type pointer
+   fields, this also fills in the ob_size field.
+
+ - PyObject_Del(op) releases the memory allocated for an object.  It does not
+   run a destructor -- it only frees the memory.  PyObject_Free is identical.
+
+ - PyObject_Init(op, typeobj) and PyObject_InitVar(op, typeobj, n) don't
+   allocate memory.  Instead of a 'type' parameter, they take a pointer to a
+   new object (allocated by an arbitrary allocator), and initialize its object
+   header fields.
+
+Note that objects created with PyObject_{New, NewVar} are allocated using the
+specialized Python allocator (implemented in obmalloc.c), if WITH_PYMALLOC is
+enabled.  In addition, a special debugging allocator is used if PYMALLOC_DEBUG
+is also #defined.
+
+In case a specific form of memory management is needed (for example, if you
+must use the platform malloc heap(s), or shared memory, or C++ local storage or
+operator new), you must first allocate the object with your custom allocator,
+then pass its pointer to PyObject_{Init, InitVar} for filling in its Python-
+specific fields:  reference count, type pointer, possibly others.  You should
+be aware that Python no control over these objects because they don't
+cooperate with the Python memory manager.  Such objects may not be eligible
+for automatic garbage collection and you have to make sure that they are
+released accordingly whenever their destructor gets called (cf. the specific
+form of memory management you're using).
+
+Unless you have specific memory management requirements, use
+PyObject_{New, NewVar, Del}.
+*/
+
+/*
+ * Raw object memory interface
+ * ===========================
+ */
+
+/* Functions to call the same malloc/realloc/free as used by Python's
+   object allocator.  If WITH_PYMALLOC is enabled, these may differ from
+   the platform malloc/realloc/free.  The Python object allocator is
+   designed for fast, cache-conscious allocation of many "small" objects,
+   and with low hidden memory overhead.
+
+   PyObject_Malloc(0) returns a unique non-NULL pointer if possible.
+
+   PyObject_Realloc(NULL, n) acts like PyObject_Malloc(n).
+   PyObject_Realloc(p != NULL, 0) does not return  NULL, or free the memory
+   at p.
+
+   Returned pointers must be checked for NULL explicitly; no action is
+   performed on failure other than to return NULL (no warning it printed, no
+   exception is set, etc).
+
+   For allocating objects, use PyObject_{New, NewVar} instead whenever
+   possible.  The PyObject_{Malloc, Realloc, Free} family is exposed
+   so that you can exploit Python's small-block allocator for non-object
+   uses.  If you must use these routines to allocate object memory, make sure
+   the object gets initialized via PyObject_{Init, InitVar} after obtaining
+   the raw memory.
+*/
+PyAPI_FUNC(void *) PyObject_Malloc(size_t);
+PyAPI_FUNC(void *) PyObject_Realloc(void *, size_t);
+PyAPI_FUNC(void) PyObject_Free(void *);
+
+
+/* Macros */
+#ifdef WITH_PYMALLOC
+#ifdef PYMALLOC_DEBUG	/* WITH_PYMALLOC && PYMALLOC_DEBUG */
+PyAPI_FUNC(void *) _PyObject_DebugMalloc(size_t nbytes);
+PyAPI_FUNC(void *) _PyObject_DebugRealloc(void *p, size_t nbytes);
+PyAPI_FUNC(void) _PyObject_DebugFree(void *p);
+PyAPI_FUNC(void) _PyObject_DebugDumpAddress(const void *p);
+PyAPI_FUNC(void) _PyObject_DebugCheckAddress(const void *p);
+PyAPI_FUNC(void) _PyObject_DebugMallocStats(void);
+#define PyObject_MALLOC		_PyObject_DebugMalloc
+#define PyObject_Malloc		_PyObject_DebugMalloc
+#define PyObject_REALLOC	_PyObject_DebugRealloc
+#define PyObject_Realloc	_PyObject_DebugRealloc
+#define PyObject_FREE		_PyObject_DebugFree
+#define PyObject_Free		_PyObject_DebugFree
+
+#else	/* WITH_PYMALLOC && ! PYMALLOC_DEBUG */
+#define PyObject_MALLOC		PyObject_Malloc
+#define PyObject_REALLOC	PyObject_Realloc
+#define PyObject_FREE		PyObject_Free
+#endif
+
+#else	/* ! WITH_PYMALLOC */
+#define PyObject_MALLOC		PyMem_MALLOC
+#define PyObject_REALLOC	PyMem_REALLOC
+#define PyObject_FREE		PyMem_FREE
+
+#endif	/* WITH_PYMALLOC */
+
+#define PyObject_Del		PyObject_Free
+#define PyObject_DEL		PyObject_FREE
+
+/* for source compatibility with 2.2 */
+#define _PyObject_Del		PyObject_Free
+
+/*
+ * Generic object allocator interface
+ * ==================================
+ */
+
+/* Functions */
+PyAPI_FUNC(PyObject *) PyObject_Init(PyObject *, PyTypeObject *);
+PyAPI_FUNC(PyVarObject *) PyObject_InitVar(PyVarObject *,
+                                                 PyTypeObject *, Py_ssize_t);
+PyAPI_FUNC(PyObject *) _PyObject_New(PyTypeObject *);
+PyAPI_FUNC(PyVarObject *) _PyObject_NewVar(PyTypeObject *, Py_ssize_t);
+
+#define PyObject_New(type, typeobj) \
+		( (type *) _PyObject_New(typeobj) )
+#define PyObject_NewVar(type, typeobj, n) \
+		( (type *) _PyObject_NewVar((typeobj), (n)) )
+
+/* Macros trading binary compatibility for speed. See also pymem.h.
+   Note that these macros expect non-NULL object pointers.*/
+#define PyObject_INIT(op, typeobj) \
+	( (op)->ob_type = (typeobj), _Py_NewReference((PyObject *)(op)), (op) )
+#define PyObject_INIT_VAR(op, typeobj, size) \
+	( (op)->ob_size = (size), PyObject_INIT((op), (typeobj)) )
+
+#define _PyObject_SIZE(typeobj) ( (typeobj)->tp_basicsize )
+
+/* _PyObject_VAR_SIZE returns the number of bytes (as size_t) allocated for a
+   vrbl-size object with nitems items, exclusive of gc overhead (if any).  The
+   value is rounded up to the closest multiple of sizeof(void *), in order to
+   ensure that pointer fields at the end of the object are correctly aligned
+   for the platform (this is of special importance for subclasses of, e.g.,
+   str or long, so that pointers can be stored after the embedded data).
+
+   Note that there's no memory wastage in doing this, as malloc has to
+   return (at worst) pointer-aligned memory anyway.
+*/
+#if ((SIZEOF_VOID_P - 1) & SIZEOF_VOID_P) != 0
+#   error "_PyObject_VAR_SIZE requires SIZEOF_VOID_P be a power of 2"
+#endif
+
+#define _PyObject_VAR_SIZE(typeobj, nitems)	\
+	(size_t)				\
+	( ( (typeobj)->tp_basicsize +		\
+	    (nitems)*(typeobj)->tp_itemsize +	\
+	    (SIZEOF_VOID_P - 1)			\
+	  ) & ~(SIZEOF_VOID_P - 1)		\
+	)
+
+#define PyObject_NEW(type, typeobj) \
+( (type *) PyObject_Init( \
+	(PyObject *) PyObject_MALLOC( _PyObject_SIZE(typeobj) ), (typeobj)) )
+
+#define PyObject_NEW_VAR(type, typeobj, n) \
+( (type *) PyObject_InitVar( \
+      (PyVarObject *) PyObject_MALLOC(_PyObject_VAR_SIZE((typeobj),(n)) ),\
+      (typeobj), (n)) )
+
+/* This example code implements an object constructor with a custom
+   allocator, where PyObject_New is inlined, and shows the important
+   distinction between two steps (at least):
+       1) the actual allocation of the object storage;
+       2) the initialization of the Python specific fields
+          in this storage with PyObject_{Init, InitVar}.
+
+   PyObject *
+   YourObject_New(...)
+   {
+       PyObject *op;
+
+       op = (PyObject *) Your_Allocator(_PyObject_SIZE(YourTypeStruct));
+       if (op == NULL)
+           return PyErr_NoMemory();
+
+       PyObject_Init(op, &YourTypeStruct);
+
+       op->ob_field = value;
+       ...
+       return op;
+   }
+
+   Note that in C++, the use of the new operator usually implies that
+   the 1st step is performed automatically for you, so in a C++ class
+   constructor you would start directly with PyObject_Init/InitVar
+*/
+
+/*
+ * Garbage Collection Support
+ * ==========================
+ */
+
+/* C equivalent of gc.collect(). */
+PyAPI_FUNC(Py_ssize_t) PyGC_Collect(void);
+
+/* Test if a type has a GC head */
+#define PyType_IS_GC(t) PyType_HasFeature((t), Py_TPFLAGS_HAVE_GC)
+
+/* Test if an object has a GC head */
+#define PyObject_IS_GC(o) (PyType_IS_GC((o)->ob_type) && \
+	((o)->ob_type->tp_is_gc == NULL || (o)->ob_type->tp_is_gc(o)))
+
+PyAPI_FUNC(PyVarObject *) _PyObject_GC_Resize(PyVarObject *, Py_ssize_t);
+#define PyObject_GC_Resize(type, op, n) \
+		( (type *) _PyObject_GC_Resize((PyVarObject *)(op), (n)) )
+
+/* for source compatibility with 2.2 */
+#define _PyObject_GC_Del PyObject_GC_Del
+
+/* GC information is stored BEFORE the object structure. */
+typedef union _gc_head {
+	struct {
+		union _gc_head *gc_next;
+		union _gc_head *gc_prev;
+		Py_ssize_t gc_refs;
+	} gc;
+	long double dummy;  /* force worst-case alignment */
+} PyGC_Head;
+
+extern PyGC_Head *_PyGC_generation0;
+
+#define _Py_AS_GC(o) ((PyGC_Head *)(o)-1)
+
+#define _PyGC_REFS_UNTRACKED			(-2)
+#define _PyGC_REFS_REACHABLE			(-3)
+#define _PyGC_REFS_TENTATIVELY_UNREACHABLE	(-4)
+
+/* Tell the GC to track this object.  NB: While the object is tracked the
+ * collector it must be safe to call the ob_traverse method. */
+#define _PyObject_GC_TRACK(o) do { \
+	PyGC_Head *g = _Py_AS_GC(o); \
+	if (g->gc.gc_refs != _PyGC_REFS_UNTRACKED) \
+		Py_FatalError("GC object already tracked"); \
+	g->gc.gc_refs = _PyGC_REFS_REACHABLE; \
+	g->gc.gc_next = _PyGC_generation0; \
+	g->gc.gc_prev = _PyGC_generation0->gc.gc_prev; \
+	g->gc.gc_prev->gc.gc_next = g; \
+	_PyGC_generation0->gc.gc_prev = g; \
+    } while (0);
+
+/* Tell the GC to stop tracking this object.
+ * gc_next doesn't need to be set to NULL, but doing so is a good
+ * way to provoke memory errors if calling code is confused.
+ */
+#define _PyObject_GC_UNTRACK(o) do { \
+	PyGC_Head *g = _Py_AS_GC(o); \
+	assert(g->gc.gc_refs != _PyGC_REFS_UNTRACKED); \
+	g->gc.gc_refs = _PyGC_REFS_UNTRACKED; \
+	g->gc.gc_prev->gc.gc_next = g->gc.gc_next; \
+	g->gc.gc_next->gc.gc_prev = g->gc.gc_prev; \
+	g->gc.gc_next = NULL; \
+    } while (0);
+
+PyAPI_FUNC(PyObject *) _PyObject_GC_Malloc(size_t);
+PyAPI_FUNC(PyObject *) _PyObject_GC_New(PyTypeObject *);
+PyAPI_FUNC(PyVarObject *) _PyObject_GC_NewVar(PyTypeObject *, Py_ssize_t);
+PyAPI_FUNC(void) PyObject_GC_Track(void *);
+PyAPI_FUNC(void) PyObject_GC_UnTrack(void *);
+PyAPI_FUNC(void) PyObject_GC_Del(void *);
+
+#define PyObject_GC_New(type, typeobj) \
+		( (type *) _PyObject_GC_New(typeobj) )
+#define PyObject_GC_NewVar(type, typeobj, n) \
+		( (type *) _PyObject_GC_NewVar((typeobj), (n)) )
+
+
+/* Utility macro to help write tp_traverse functions.
+ * To use this macro, the tp_traverse function must name its arguments
+ * "visit" and "arg".  This is intended to keep tp_traverse functions
+ * looking as much alike as possible.
+ */
+#define Py_VISIT(op)							\
+        do { 								\
+                if (op) {						\
+                        int vret = visit((PyObject *)(op), arg);	\
+                        if (vret)					\
+                                return vret;				\
+                }							\
+        } while (0)
+
+/* This is here for the sake of backwards compatibility.  Extensions that
+ * use the old GC API will still compile but the objects will not be
+ * tracked by the GC. */
+#define PyGC_HEAD_SIZE 0
+#define PyObject_GC_Init(op)
+#define PyObject_GC_Fini(op)
+#define PyObject_AS_GC(op) (op)
+#define PyObject_FROM_GC(op) (op)
+
+
+/* Test if a type supports weak references */
+#define PyType_SUPPORTS_WEAKREFS(t) \
+        (PyType_HasFeature((t), Py_TPFLAGS_HAVE_WEAKREFS) \
+         && ((t)->tp_weaklistoffset > 0))
+
+#define PyObject_GET_WEAKREFS_LISTPTR(o) \
+	((PyObject **) (((char *) (o)) + (o)->ob_type->tp_weaklistoffset))
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_OBJIMPL_H */

Added: vendor/Python/current/Include/opcode.h
===================================================================
--- vendor/Python/current/Include/opcode.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/opcode.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,152 @@
+#ifndef Py_OPCODE_H
+#define Py_OPCODE_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Instruction opcodes for compiled code */
+
+#define STOP_CODE	0
+#define POP_TOP		1
+#define ROT_TWO		2
+#define ROT_THREE	3
+#define DUP_TOP		4
+#define ROT_FOUR	5
+#define NOP		9
+
+#define UNARY_POSITIVE	10
+#define UNARY_NEGATIVE	11
+#define UNARY_NOT	12
+#define UNARY_CONVERT	13
+
+#define UNARY_INVERT	15
+
+#define LIST_APPEND	18
+#define BINARY_POWER	19
+
+#define BINARY_MULTIPLY	20
+#define BINARY_DIVIDE	21
+#define BINARY_MODULO	22
+#define BINARY_ADD	23
+#define BINARY_SUBTRACT	24
+#define BINARY_SUBSCR	25
+#define BINARY_FLOOR_DIVIDE 26
+#define BINARY_TRUE_DIVIDE 27
+#define INPLACE_FLOOR_DIVIDE 28
+#define INPLACE_TRUE_DIVIDE 29
+
+#define SLICE		30
+/* Also uses 31-33 */
+
+#define STORE_SLICE	40
+/* Also uses 41-43 */
+
+#define DELETE_SLICE	50
+/* Also uses 51-53 */
+
+#define INPLACE_ADD	55
+#define INPLACE_SUBTRACT	56
+#define INPLACE_MULTIPLY	57
+#define INPLACE_DIVIDE	58
+#define INPLACE_MODULO	59
+#define STORE_SUBSCR	60
+#define DELETE_SUBSCR	61
+
+#define BINARY_LSHIFT	62
+#define BINARY_RSHIFT	63
+#define BINARY_AND	64
+#define BINARY_XOR	65
+#define BINARY_OR	66
+#define INPLACE_POWER	67
+#define GET_ITER	68
+
+#define PRINT_EXPR	70
+#define PRINT_ITEM	71
+#define PRINT_NEWLINE	72
+#define PRINT_ITEM_TO   73
+#define PRINT_NEWLINE_TO 74
+#define INPLACE_LSHIFT	75
+#define INPLACE_RSHIFT	76
+#define INPLACE_AND	77
+#define INPLACE_XOR	78
+#define INPLACE_OR	79
+#define BREAK_LOOP	80
+#define WITH_CLEANUP    81
+#define LOAD_LOCALS	82
+#define RETURN_VALUE	83
+#define IMPORT_STAR	84
+#define EXEC_STMT	85
+#define YIELD_VALUE	86
+#define POP_BLOCK	87
+#define END_FINALLY	88
+#define BUILD_CLASS	89
+
+#define HAVE_ARGUMENT	90	/* Opcodes from here have an argument: */
+
+#define STORE_NAME	90	/* Index in name list */
+#define DELETE_NAME	91	/* "" */
+#define UNPACK_SEQUENCE	92	/* Number of sequence items */
+#define FOR_ITER	93
+
+#define STORE_ATTR	95	/* Index in name list */
+#define DELETE_ATTR	96	/* "" */
+#define STORE_GLOBAL	97	/* "" */
+#define DELETE_GLOBAL	98	/* "" */
+#define DUP_TOPX	99	/* number of items to duplicate */
+#define LOAD_CONST	100	/* Index in const list */
+#define LOAD_NAME	101	/* Index in name list */
+#define BUILD_TUPLE	102	/* Number of tuple items */
+#define BUILD_LIST	103	/* Number of list items */
+#define BUILD_MAP	104	/* Always zero for now */
+#define LOAD_ATTR	105	/* Index in name list */
+#define COMPARE_OP	106	/* Comparison operator */
+#define IMPORT_NAME	107	/* Index in name list */
+#define IMPORT_FROM	108	/* Index in name list */
+
+#define JUMP_FORWARD	110	/* Number of bytes to skip */
+#define JUMP_IF_FALSE	111	/* "" */
+#define JUMP_IF_TRUE	112	/* "" */
+#define JUMP_ABSOLUTE	113	/* Target byte offset from beginning of code */
+
+#define LOAD_GLOBAL	116	/* Index in name list */
+
+#define CONTINUE_LOOP	119	/* Start of loop (absolute) */
+#define SETUP_LOOP	120	/* Target address (absolute) */
+#define SETUP_EXCEPT	121	/* "" */
+#define SETUP_FINALLY	122	/* "" */
+
+#define LOAD_FAST	124	/* Local variable number */
+#define STORE_FAST	125	/* Local variable number */
+#define DELETE_FAST	126	/* Local variable number */
+
+#define RAISE_VARARGS	130	/* Number of raise arguments (1, 2 or 3) */
+/* CALL_FUNCTION_XXX opcodes defined below depend on this definition */
+#define CALL_FUNCTION	131	/* #args + (#kwargs<<8) */
+#define MAKE_FUNCTION	132	/* #defaults */
+#define BUILD_SLICE 	133	/* Number of items */
+
+#define MAKE_CLOSURE    134     /* #free vars */
+#define LOAD_CLOSURE    135     /* Load free variable from closure */
+#define LOAD_DEREF      136     /* Load and dereference from closure cell */ 
+#define STORE_DEREF     137     /* Store into cell */ 
+
+/* The next 3 opcodes must be contiguous and satisfy
+   (CALL_FUNCTION_VAR - CALL_FUNCTION) & 3 == 1  */
+#define CALL_FUNCTION_VAR          140	/* #args + (#kwargs<<8) */
+#define CALL_FUNCTION_KW           141	/* #args + (#kwargs<<8) */
+#define CALL_FUNCTION_VAR_KW       142	/* #args + (#kwargs<<8) */
+
+/* Support for opargs more than 16 bits long */
+#define EXTENDED_ARG  143
+
+
+enum cmp_op {PyCmp_LT=Py_LT, PyCmp_LE=Py_LE, PyCmp_EQ=Py_EQ, PyCmp_NE=Py_NE, PyCmp_GT=Py_GT, PyCmp_GE=Py_GE,
+	     PyCmp_IN, PyCmp_NOT_IN, PyCmp_IS, PyCmp_IS_NOT, PyCmp_EXC_MATCH, PyCmp_BAD};
+
+#define HAS_ARG(op) ((op) >= HAVE_ARGUMENT)
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_OPCODE_H */

Added: vendor/Python/current/Include/osdefs.h
===================================================================
--- vendor/Python/current/Include/osdefs.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/osdefs.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,55 @@
+#ifndef Py_OSDEFS_H
+#define Py_OSDEFS_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Operating system dependencies */
+
+/* Mod by chrish: QNX has WATCOM, but isn't DOS */
+#if !defined(__QNX__)
+#if defined(MS_WINDOWS) || defined(__BORLANDC__) || defined(__WATCOMC__) || defined(__DJGPP__) || defined(PYOS_OS2)
+#if defined(PYOS_OS2) && defined(PYCC_GCC)
+#define MAXPATHLEN 260
+#define SEP '/'
+#define ALTSEP '\\'
+#else
+#define SEP '\\'
+#define ALTSEP '/'
+#define MAXPATHLEN 256
+#endif
+#define DELIM ';'
+#endif
+#endif
+
+#ifdef RISCOS
+#define SEP '.'
+#define MAXPATHLEN 256
+#define DELIM ','
+#endif
+
+
+/* Filename separator */
+#ifndef SEP
+#define SEP '/'
+#endif
+
+/* Max pathname length */
+#ifndef MAXPATHLEN
+#if defined(PATH_MAX) && PATH_MAX > 1024
+#define MAXPATHLEN PATH_MAX
+#else
+#define MAXPATHLEN 1024
+#endif
+#endif
+
+/* Search path entry delimiter */
+#ifndef DELIM
+#define DELIM ':'
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_OSDEFS_H */

Added: vendor/Python/current/Include/parsetok.h
===================================================================
--- vendor/Python/current/Include/parsetok.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/parsetok.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,50 @@
+
+/* Parser-tokenizer link interface */
+
+#ifndef Py_PARSETOK_H
+#define Py_PARSETOK_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+    int error;
+    const char *filename;
+    int lineno;
+    int offset;
+    char *text;
+    int token;
+    int expected;
+} perrdetail;
+
+#if 0
+#define PyPARSE_YIELD_IS_KEYWORD	0x0001
+#endif
+
+#define PyPARSE_DONT_IMPLY_DEDENT	0x0002
+
+#define PyPARSE_WITH_IS_KEYWORD		0x0003
+
+PyAPI_FUNC(node *) PyParser_ParseString(const char *, grammar *, int,
+                                              perrdetail *);
+PyAPI_FUNC(node *) PyParser_ParseFile (FILE *, const char *, grammar *, int,
+                                             char *, char *, perrdetail *);
+
+PyAPI_FUNC(node *) PyParser_ParseStringFlags(const char *, grammar *, int,
+                                              perrdetail *, int);
+PyAPI_FUNC(node *) PyParser_ParseFileFlags(FILE *, const char *, grammar *,
+						 int, char *, char *,
+						 perrdetail *, int);
+
+PyAPI_FUNC(node *) PyParser_ParseStringFlagsFilename(const char *,
+					      const char *,
+					      grammar *, int,
+                                              perrdetail *, int);
+
+/* Note that he following function is defined in pythonrun.c not parsetok.c. */
+PyAPI_FUNC(void) PyParser_SetError(perrdetail *);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_PARSETOK_H */

Added: vendor/Python/current/Include/patchlevel.h
===================================================================
--- vendor/Python/current/Include/patchlevel.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/patchlevel.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,40 @@
+
+/* Newfangled version identification scheme.
+
+   This scheme was added in Python 1.5.2b2; before that time, only PATCHLEVEL
+   was available.  To test for presence of the scheme, test for
+   defined(PY_MAJOR_VERSION).
+
+   When the major or minor version changes, the VERSION variable in
+   configure.in must also be changed.
+
+   There is also (independent) API version information in modsupport.h.
+*/
+
+/* Values for PY_RELEASE_LEVEL */
+#define PY_RELEASE_LEVEL_ALPHA	0xA
+#define PY_RELEASE_LEVEL_BETA	0xB
+#define PY_RELEASE_LEVEL_GAMMA	0xC     /* For release candidates */
+#define PY_RELEASE_LEVEL_FINAL	0xF	/* Serial should be 0 here */
+					/* Higher for patch releases */
+
+/* Version parsed out into numeric values */
+#define PY_MAJOR_VERSION	2
+#define PY_MINOR_VERSION	5
+#define PY_MICRO_VERSION	1
+#define PY_RELEASE_LEVEL	PY_RELEASE_LEVEL_FINAL
+#define PY_RELEASE_SERIAL	0
+
+/* Version as a string */
+#define PY_VERSION		"2.5.1"
+
+/* Subversion Revision number of this file (not of the repository) */
+#define PY_PATCHLEVEL_REVISION  "$Revision: 54863 $"
+
+/* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2.
+   Use this for numeric comparisons, e.g. #if PY_VERSION_HEX >= ... */
+#define PY_VERSION_HEX ((PY_MAJOR_VERSION << 24) | \
+			(PY_MINOR_VERSION << 16) | \
+			(PY_MICRO_VERSION <<  8) | \
+			(PY_RELEASE_LEVEL <<  4) | \
+			(PY_RELEASE_SERIAL << 0))

Added: vendor/Python/current/Include/pgen.h
===================================================================
--- vendor/Python/current/Include/pgen.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/pgen.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,18 @@
+#ifndef Py_PGEN_H
+#define Py_PGEN_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Parser generator interface */
+
+extern grammar *meta_grammar(void);
+
+struct _node;
+extern grammar *pgen(struct _node *);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_PGEN_H */

Added: vendor/Python/current/Include/pgenheaders.h
===================================================================
--- vendor/Python/current/Include/pgenheaders.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/pgenheaders.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,42 @@
+#ifndef Py_PGENHEADERS_H
+#define Py_PGENHEADERS_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Include files and extern declarations used by most of the parser. */
+
+#include "Python.h"
+
+PyAPI_FUNC(void) PySys_WriteStdout(const char *format, ...)
+			Py_GCC_ATTRIBUTE((format(printf, 1, 2)));
+PyAPI_FUNC(void) PySys_WriteStderr(const char *format, ...)
+			Py_GCC_ATTRIBUTE((format(printf, 1, 2)));
+
+#define addarc _Py_addarc
+#define addbit _Py_addbit
+#define adddfa _Py_adddfa
+#define addfirstsets _Py_addfirstsets
+#define addlabel _Py_addlabel
+#define addstate _Py_addstate
+#define delbitset _Py_delbitset
+#define dumptree _Py_dumptree
+#define findlabel _Py_findlabel
+#define mergebitset _Py_mergebitset
+#define meta_grammar _Py_meta_grammar
+#define newbitset _Py_newbitset
+#define newgrammar _Py_newgrammar
+#define pgen _Py_pgen
+#define printgrammar _Py_printgrammar
+#define printnonterminals _Py_printnonterminals
+#define printtree _Py_printtree
+#define samebitset _Py_samebitset
+#define showtree _Py_showtree
+#define tok_dump _Py_tok_dump
+#define translatelabels _Py_translatelabels
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_PGENHEADERS_H */

Added: vendor/Python/current/Include/py_curses.h
===================================================================
--- vendor/Python/current/Include/py_curses.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/py_curses.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,176 @@
+
+#ifndef Py_CURSES_H
+#define Py_CURSES_H
+
+#ifdef __APPLE__
+/*
+** On Mac OS X 10.2 [n]curses.h and stdlib.h use different guards
+** against multiple definition of wchar_t.
+*/
+#ifdef	_BSD_WCHAR_T_DEFINED_
+#define _WCHAR_T
+#endif
+#endif
+
+#ifdef __FreeBSD__
+/*
+** On FreeBSD, [n]curses.h and stdlib.h/wchar.h use different guards
+** against multiple definition of wchar_t and wint_t.
+*/
+#ifdef	_XOPEN_SOURCE_EXTENDED
+#ifndef __FreeBSD_version
+#include <osreldate.h>
+#endif
+#if __FreeBSD_version >= 500000
+#ifndef __wchar_t
+#define __wchar_t
+#endif
+#ifndef __wint_t
+#define __wint_t
+#endif
+#else
+#ifndef _WCHAR_T
+#define _WCHAR_T
+#endif
+#ifndef _WINT_T
+#define _WINT_T
+#endif
+#endif
+#endif
+#endif
+
+#ifdef HAVE_NCURSES_H
+#include <ncurses.h>
+#else
+#include <curses.h>
+#ifdef HAVE_TERM_H
+/* for tigetstr, which is not declared in SysV curses */
+#include <term.h>
+#endif
+#endif
+
+#ifdef HAVE_NCURSES_H
+/* configure was checking <curses.h>, but we will
+   use <ncurses.h>, which has all these features. */
+#ifndef WINDOW_HAS_FLAGS
+#define WINDOW_HAS_FLAGS 1
+#endif
+#ifndef MVWDELCH_IS_EXPRESSION
+#define MVWDELCH_IS_EXPRESSION 1
+#endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define PyCurses_API_pointers 4
+
+/* Type declarations */
+
+typedef struct {
+	PyObject_HEAD
+	WINDOW *win;
+} PyCursesWindowObject;
+
+#define PyCursesWindow_Check(v)	 ((v)->ob_type == &PyCursesWindow_Type)
+
+#ifdef CURSES_MODULE
+/* This section is used when compiling _cursesmodule.c */
+
+#else
+/* This section is used in modules that use the _cursesmodule API */
+
+static void **PyCurses_API;
+
+#define PyCursesWindow_Type (*(PyTypeObject *) PyCurses_API[0])
+#define PyCursesSetupTermCalled  {if (! ((int (*)(void))PyCurses_API[1]) () ) return NULL;}
+#define PyCursesInitialised      {if (! ((int (*)(void))PyCurses_API[2]) () ) return NULL;}
+#define PyCursesInitialisedColor {if (! ((int (*)(void))PyCurses_API[3]) () ) return NULL;}
+
+#define import_curses() \
+{ \
+  PyObject *module = PyImport_ImportModule("_curses"); \
+  if (module != NULL) { \
+    PyObject *module_dict = PyModule_GetDict(module); \
+    PyObject *c_api_object = PyDict_GetItemString(module_dict, "_C_API"); \
+    if (PyCObject_Check(c_api_object)) { \
+      PyCurses_API = (void **)PyCObject_AsVoidPtr(c_api_object); \
+    } \
+  } \
+}
+#endif
+
+/* general error messages */
+static char *catchall_ERR  = "curses function returned ERR";
+static char *catchall_NULL = "curses function returned NULL";
+
+/* Function Prototype Macros - They are ugly but very, very useful. ;-)
+
+   X - function name
+   TYPE - parameter Type
+   ERGSTR - format string for construction of the return value
+   PARSESTR - format string for argument parsing
+   */
+
+#define NoArgNoReturnFunction(X) \
+static PyObject *PyCurses_ ## X (PyObject *self) \
+{ \
+  PyCursesInitialised \
+  return PyCursesCheckERR(X(), # X); }
+
+#define NoArgOrFlagNoReturnFunction(X) \
+static PyObject *PyCurses_ ## X (PyObject *self, PyObject *args) \
+{ \
+  int flag = 0; \
+  PyCursesInitialised \
+  switch(PyTuple_Size(args)) { \
+  case 0: \
+    return PyCursesCheckERR(X(), # X); \
+  case 1: \
+    if (!PyArg_ParseTuple(args, "i;True(1) or False(0)", &flag)) return NULL; \
+    if (flag) return PyCursesCheckERR(X(), # X); \
+    else return PyCursesCheckERR(no ## X (), # X); \
+  default: \
+    PyErr_SetString(PyExc_TypeError, # X " requires 0 or 1 arguments"); \
+    return NULL; } }
+
+#define NoArgReturnIntFunction(X) \
+static PyObject *PyCurses_ ## X (PyObject *self) \
+{ \
+ PyCursesInitialised \
+ return PyInt_FromLong((long) X()); }
+
+
+#define NoArgReturnStringFunction(X) \
+static PyObject *PyCurses_ ## X (PyObject *self) \
+{ \
+  PyCursesInitialised \
+  return PyString_FromString(X()); }
+
+#define NoArgTrueFalseFunction(X) \
+static PyObject *PyCurses_ ## X (PyObject *self) \
+{ \
+  PyCursesInitialised \
+  if (X () == FALSE) { \
+    Py_INCREF(Py_False); \
+    return Py_False; \
+  } \
+  Py_INCREF(Py_True); \
+  return Py_True; }
+
+#define NoArgNoReturnVoidFunction(X) \
+static PyObject *PyCurses_ ## X (PyObject *self) \
+{ \
+  PyCursesInitialised \
+  X(); \
+  Py_INCREF(Py_None); \
+  return Py_None; }
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !defined(Py_CURSES_H) */
+
+

Added: vendor/Python/current/Include/pyarena.h
===================================================================
--- vendor/Python/current/Include/pyarena.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/pyarena.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,62 @@
+/* An arena-like memory interface for the compiler.
+ */
+
+#ifndef Py_PYARENA_H
+#define Py_PYARENA_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+  typedef struct _arena PyArena;
+
+  /* PyArena_New() and PyArena_Free() create a new arena and free it,
+     respectively.  Once an arena has been created, it can be used
+     to allocate memory via PyArena_Malloc().  Pointers to PyObject can
+     also be registered with the arena via PyArena_AddPyObject(), and the
+     arena will ensure that the PyObjects stay alive at least until
+     PyArena_Free() is called.  When an arena is freed, all the memory it
+     allocated is freed, the arena releases internal references to registered
+     PyObject*, and none of its pointers are valid.
+     XXX (tim) What does "none of its pointers are valid" mean?  Does it
+     XXX mean that pointers previously obtained via PyArena_Malloc() are
+     XXX no longer valid?  (That's clearly true, but not sure that's what
+     XXX the text is trying to say.)
+
+     PyArena_New() returns an arena pointer.  On error, it
+     returns a negative number and sets an exception.
+     XXX (tim):  Not true.  On error, PyArena_New() actually returns NULL,
+     XXX and looks like it may or may not set an exception (e.g., if the
+     XXX internal PyList_New(0) returns NULL, PyArena_New() passes that on
+     XXX and an exception is set; OTOH, if the internal
+     XXX block_new(DEFAULT_BLOCK_SIZE) returns NULL, that's passed on but
+     XXX an exception is not set in that case).
+  */
+  PyAPI_FUNC(PyArena *) PyArena_New(void);
+  PyAPI_FUNC(void) PyArena_Free(PyArena *);
+
+  /* Mostly like malloc(), return the address of a block of memory spanning
+   * `size` bytes, or return NULL (without setting an exception) if enough
+   * new memory can't be obtained.  Unlike malloc(0), PyArena_Malloc() with
+   * size=0 does not guarantee to return a unique pointer (the pointer
+   * returned may equal one or more other pointers obtained from
+   * PyArena_Malloc()).
+   * Note that pointers obtained via PyArena_Malloc() must never be passed to
+   * the system free() or realloc(), or to any of Python's similar memory-
+   * management functions.  PyArena_Malloc()-obtained pointers remain valid
+   * until PyArena_Free(ar) is called, at which point all pointers obtained
+   * from the arena `ar` become invalid simultaneously.
+   */
+  PyAPI_FUNC(void *) PyArena_Malloc(PyArena *, size_t size);
+
+  /* This routine isn't a proper arena allocation routine.  It takes
+   * a PyObject* and records it so that it can be DECREFed when the
+   * arena is freed.
+   */
+  PyAPI_FUNC(int) PyArena_AddPyObject(PyArena *, PyObject *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !Py_PYARENA_H */

Added: vendor/Python/current/Include/pydebug.h
===================================================================
--- vendor/Python/current/Include/pydebug.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/pydebug.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,34 @@
+
+#ifndef Py_PYDEBUG_H
+#define Py_PYDEBUG_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+PyAPI_DATA(int) Py_DebugFlag;
+PyAPI_DATA(int) Py_VerboseFlag;
+PyAPI_DATA(int) Py_InteractiveFlag;
+PyAPI_DATA(int) Py_OptimizeFlag;
+PyAPI_DATA(int) Py_NoSiteFlag;
+PyAPI_DATA(int) Py_UseClassExceptionsFlag;
+PyAPI_DATA(int) Py_FrozenFlag;
+PyAPI_DATA(int) Py_TabcheckFlag;
+PyAPI_DATA(int) Py_UnicodeFlag;
+PyAPI_DATA(int) Py_IgnoreEnvironmentFlag;
+PyAPI_DATA(int) Py_DivisionWarningFlag;
+/* _XXX Py_QnewFlag should go away in 3.0.  It's true iff -Qnew is passed,
+  on the command line, and is used in 2.2 by ceval.c to make all "/" divisions
+  true divisions (which they will be in 3.0). */
+PyAPI_DATA(int) _Py_QnewFlag;
+
+/* this is a wrapper around getenv() that pays attention to
+   Py_IgnoreEnvironmentFlag.  It should be used for getting variables like
+   PYTHONPATH and PYTHONHOME from the environment */
+#define Py_GETENV(s) (Py_IgnoreEnvironmentFlag ? NULL : getenv(s))
+
+PyAPI_FUNC(void) Py_FatalError(const char *message);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_PYDEBUG_H */

Added: vendor/Python/current/Include/pyerrors.h
===================================================================
--- vendor/Python/current/Include/pyerrors.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/pyerrors.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,334 @@
+#ifndef Py_ERRORS_H
+#define Py_ERRORS_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Error objects */
+
+typedef struct {
+    PyObject_HEAD
+    PyObject *dict;
+    PyObject *args;
+    PyObject *message;
+} PyBaseExceptionObject;
+
+typedef struct {
+    PyObject_HEAD
+    PyObject *dict;
+    PyObject *args;
+    PyObject *message;
+    PyObject *msg;
+    PyObject *filename;
+    PyObject *lineno;
+    PyObject *offset;
+    PyObject *text;
+    PyObject *print_file_and_line;
+} PySyntaxErrorObject;
+
+#ifdef Py_USING_UNICODE
+typedef struct {
+    PyObject_HEAD
+    PyObject *dict;
+    PyObject *args;
+    PyObject *message;
+    PyObject *encoding;
+    PyObject *object;
+    PyObject *start;
+    PyObject *end;
+    PyObject *reason;
+} PyUnicodeErrorObject;
+#endif
+
+typedef struct {
+    PyObject_HEAD
+    PyObject *dict;
+    PyObject *args;
+    PyObject *message;
+    PyObject *code;
+} PySystemExitObject;
+
+typedef struct {
+    PyObject_HEAD
+    PyObject *dict;
+    PyObject *args;
+    PyObject *message;
+    PyObject *myerrno;
+    PyObject *strerror;
+    PyObject *filename;
+} PyEnvironmentErrorObject;
+
+#ifdef MS_WINDOWS
+typedef struct {
+    PyObject_HEAD
+    PyObject *dict;
+    PyObject *args;
+    PyObject *message;
+    PyObject *myerrno;
+    PyObject *strerror;
+    PyObject *filename;
+    PyObject *winerror;
+} PyWindowsErrorObject;
+#endif
+
+/* Error handling definitions */
+
+PyAPI_FUNC(void) PyErr_SetNone(PyObject *);
+PyAPI_FUNC(void) PyErr_SetObject(PyObject *, PyObject *);
+PyAPI_FUNC(void) PyErr_SetString(PyObject *, const char *);
+PyAPI_FUNC(PyObject *) PyErr_Occurred(void);
+PyAPI_FUNC(void) PyErr_Clear(void);
+PyAPI_FUNC(void) PyErr_Fetch(PyObject **, PyObject **, PyObject **);
+PyAPI_FUNC(void) PyErr_Restore(PyObject *, PyObject *, PyObject *);
+
+#ifdef Py_DEBUG
+#define _PyErr_OCCURRED() PyErr_Occurred()
+#else
+#define _PyErr_OCCURRED() (_PyThreadState_Current->curexc_type)
+#endif
+
+/* Error testing and normalization */
+PyAPI_FUNC(int) PyErr_GivenExceptionMatches(PyObject *, PyObject *);
+PyAPI_FUNC(int) PyErr_ExceptionMatches(PyObject *);
+PyAPI_FUNC(void) PyErr_NormalizeException(PyObject**, PyObject**, PyObject**);
+
+/* */
+
+#define PyExceptionClass_Check(x)					\
+	(PyClass_Check((x))						\
+	 || (PyType_Check((x)) && PyType_IsSubtype(			\
+		     (PyTypeObject*)(x), (PyTypeObject*)PyExc_BaseException)))
+
+
+#define PyExceptionInstance_Check(x)			\
+	(PyInstance_Check((x)) ||			\
+	 (PyType_IsSubtype((x)->ob_type, (PyTypeObject*)PyExc_BaseException)))
+
+#define PyExceptionClass_Name(x)				   \
+	(PyClass_Check((x))					   \
+	 ? PyString_AS_STRING(((PyClassObject*)(x))->cl_name)	   \
+	 : (char *)(((PyTypeObject*)(x))->tp_name))
+
+#define PyExceptionInstance_Class(x)					\
+	((PyInstance_Check((x))						\
+	  ? (PyObject*)((PyInstanceObject*)(x))->in_class		\
+	  : (PyObject*)((x)->ob_type)))
+
+	
+/* Predefined exceptions */
+
+PyAPI_DATA(PyObject *) PyExc_BaseException;
+PyAPI_DATA(PyObject *) PyExc_Exception;
+PyAPI_DATA(PyObject *) PyExc_StopIteration;
+PyAPI_DATA(PyObject *) PyExc_GeneratorExit;
+PyAPI_DATA(PyObject *) PyExc_StandardError;
+PyAPI_DATA(PyObject *) PyExc_ArithmeticError;
+PyAPI_DATA(PyObject *) PyExc_LookupError;
+
+PyAPI_DATA(PyObject *) PyExc_AssertionError;
+PyAPI_DATA(PyObject *) PyExc_AttributeError;
+PyAPI_DATA(PyObject *) PyExc_EOFError;
+PyAPI_DATA(PyObject *) PyExc_FloatingPointError;
+PyAPI_DATA(PyObject *) PyExc_EnvironmentError;
+PyAPI_DATA(PyObject *) PyExc_IOError;
+PyAPI_DATA(PyObject *) PyExc_OSError;
+PyAPI_DATA(PyObject *) PyExc_ImportError;
+PyAPI_DATA(PyObject *) PyExc_IndexError;
+PyAPI_DATA(PyObject *) PyExc_KeyError;
+PyAPI_DATA(PyObject *) PyExc_KeyboardInterrupt;
+PyAPI_DATA(PyObject *) PyExc_MemoryError;
+PyAPI_DATA(PyObject *) PyExc_NameError;
+PyAPI_DATA(PyObject *) PyExc_OverflowError;
+PyAPI_DATA(PyObject *) PyExc_RuntimeError;
+PyAPI_DATA(PyObject *) PyExc_NotImplementedError;
+PyAPI_DATA(PyObject *) PyExc_SyntaxError;
+PyAPI_DATA(PyObject *) PyExc_IndentationError;
+PyAPI_DATA(PyObject *) PyExc_TabError;
+PyAPI_DATA(PyObject *) PyExc_ReferenceError;
+PyAPI_DATA(PyObject *) PyExc_SystemError;
+PyAPI_DATA(PyObject *) PyExc_SystemExit;
+PyAPI_DATA(PyObject *) PyExc_TypeError;
+PyAPI_DATA(PyObject *) PyExc_UnboundLocalError;
+PyAPI_DATA(PyObject *) PyExc_UnicodeError;
+PyAPI_DATA(PyObject *) PyExc_UnicodeEncodeError;
+PyAPI_DATA(PyObject *) PyExc_UnicodeDecodeError;
+PyAPI_DATA(PyObject *) PyExc_UnicodeTranslateError;
+PyAPI_DATA(PyObject *) PyExc_ValueError;
+PyAPI_DATA(PyObject *) PyExc_ZeroDivisionError;
+#ifdef MS_WINDOWS
+PyAPI_DATA(PyObject *) PyExc_WindowsError;
+#endif
+#ifdef __VMS
+PyAPI_DATA(PyObject *) PyExc_VMSError;
+#endif
+
+PyAPI_DATA(PyObject *) PyExc_MemoryErrorInst;
+
+/* Predefined warning categories */
+PyAPI_DATA(PyObject *) PyExc_Warning;
+PyAPI_DATA(PyObject *) PyExc_UserWarning;
+PyAPI_DATA(PyObject *) PyExc_DeprecationWarning;
+PyAPI_DATA(PyObject *) PyExc_PendingDeprecationWarning;
+PyAPI_DATA(PyObject *) PyExc_SyntaxWarning;
+PyAPI_DATA(PyObject *) PyExc_RuntimeWarning;
+PyAPI_DATA(PyObject *) PyExc_FutureWarning;
+PyAPI_DATA(PyObject *) PyExc_ImportWarning;
+PyAPI_DATA(PyObject *) PyExc_UnicodeWarning;
+
+
+/* Convenience functions */
+
+PyAPI_FUNC(int) PyErr_BadArgument(void);
+PyAPI_FUNC(PyObject *) PyErr_NoMemory(void);
+PyAPI_FUNC(PyObject *) PyErr_SetFromErrno(PyObject *);
+PyAPI_FUNC(PyObject *) PyErr_SetFromErrnoWithFilenameObject(
+	PyObject *, PyObject *);
+PyAPI_FUNC(PyObject *) PyErr_SetFromErrnoWithFilename(PyObject *, char *);
+#ifdef Py_WIN_WIDE_FILENAMES
+PyAPI_FUNC(PyObject *) PyErr_SetFromErrnoWithUnicodeFilename(
+	PyObject *, Py_UNICODE *);
+#endif /* Py_WIN_WIDE_FILENAMES */
+
+PyAPI_FUNC(PyObject *) PyErr_Format(PyObject *, const char *, ...)
+			Py_GCC_ATTRIBUTE((format(printf, 2, 3)));
+
+#ifdef MS_WINDOWS
+PyAPI_FUNC(PyObject *) PyErr_SetFromWindowsErrWithFilenameObject(
+	int, const char *);
+PyAPI_FUNC(PyObject *) PyErr_SetFromWindowsErrWithFilename(
+	int, const char *);
+#ifdef Py_WIN_WIDE_FILENAMES
+PyAPI_FUNC(PyObject *) PyErr_SetFromWindowsErrWithUnicodeFilename(
+	int, const Py_UNICODE *);
+#endif /* Py_WIN_WIDE_FILENAMES */
+PyAPI_FUNC(PyObject *) PyErr_SetFromWindowsErr(int);
+PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErrWithFilenameObject(
+	PyObject *,int, PyObject *);
+PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErrWithFilename(
+	PyObject *,int, const char *);
+#ifdef Py_WIN_WIDE_FILENAMES
+PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErrWithUnicodeFilename(
+	PyObject *,int, const Py_UNICODE *);
+#endif /* Py_WIN_WIDE_FILENAMES */
+PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErr(PyObject *, int);
+#endif /* MS_WINDOWS */
+
+/* Export the old function so that the existing API remains available: */
+PyAPI_FUNC(void) PyErr_BadInternalCall(void);
+PyAPI_FUNC(void) _PyErr_BadInternalCall(char *filename, int lineno);
+/* Mask the old API with a call to the new API for code compiled under
+   Python 2.0: */
+#define PyErr_BadInternalCall() _PyErr_BadInternalCall(__FILE__, __LINE__)
+
+/* Function to create a new exception */
+PyAPI_FUNC(PyObject *) PyErr_NewException(char *name, PyObject *base,
+                                         PyObject *dict);
+PyAPI_FUNC(void) PyErr_WriteUnraisable(PyObject *);
+
+/* Issue a warning or exception */
+PyAPI_FUNC(int) PyErr_WarnEx(PyObject *category, const char *msg,
+			     Py_ssize_t stack_level);
+PyAPI_FUNC(int) PyErr_WarnExplicit(PyObject *, const char *,
+				   const char *, int, 
+				   const char *, PyObject *);
+/* PyErr_Warn is only for backwards compatability and will be removed.
+   Use PyErr_WarnEx instead. */
+#define PyErr_Warn(category, msg) PyErr_WarnEx(category, msg, 1)
+
+/* In sigcheck.c or signalmodule.c */
+PyAPI_FUNC(int) PyErr_CheckSignals(void);
+PyAPI_FUNC(void) PyErr_SetInterrupt(void);
+
+/* Support for adding program text to SyntaxErrors */
+PyAPI_FUNC(void) PyErr_SyntaxLocation(const char *, int);
+PyAPI_FUNC(PyObject *) PyErr_ProgramText(const char *, int);
+
+#ifdef Py_USING_UNICODE
+/* The following functions are used to create and modify unicode
+   exceptions from C */
+
+/* create a UnicodeDecodeError object */
+PyAPI_FUNC(PyObject *) PyUnicodeDecodeError_Create(
+	const char *, const char *, Py_ssize_t, Py_ssize_t, Py_ssize_t, const char *);
+
+/* create a UnicodeEncodeError object */
+PyAPI_FUNC(PyObject *) PyUnicodeEncodeError_Create(
+	const char *, const Py_UNICODE *, Py_ssize_t, Py_ssize_t, Py_ssize_t, const char *);
+
+/* create a UnicodeTranslateError object */
+PyAPI_FUNC(PyObject *) PyUnicodeTranslateError_Create(
+	const Py_UNICODE *, Py_ssize_t, Py_ssize_t, Py_ssize_t, const char *);
+
+/* get the encoding attribute */
+PyAPI_FUNC(PyObject *) PyUnicodeEncodeError_GetEncoding(PyObject *);
+PyAPI_FUNC(PyObject *) PyUnicodeDecodeError_GetEncoding(PyObject *);
+
+/* get the object attribute */
+PyAPI_FUNC(PyObject *) PyUnicodeEncodeError_GetObject(PyObject *);
+PyAPI_FUNC(PyObject *) PyUnicodeDecodeError_GetObject(PyObject *);
+PyAPI_FUNC(PyObject *) PyUnicodeTranslateError_GetObject(PyObject *);
+
+/* get the value of the start attribute (the int * may not be NULL)
+   return 0 on success, -1 on failure */
+PyAPI_FUNC(int) PyUnicodeEncodeError_GetStart(PyObject *, Py_ssize_t *);
+PyAPI_FUNC(int) PyUnicodeDecodeError_GetStart(PyObject *, Py_ssize_t *);
+PyAPI_FUNC(int) PyUnicodeTranslateError_GetStart(PyObject *, Py_ssize_t *);
+
+/* assign a new value to the start attribute
+   return 0 on success, -1 on failure */
+PyAPI_FUNC(int) PyUnicodeEncodeError_SetStart(PyObject *, Py_ssize_t);
+PyAPI_FUNC(int) PyUnicodeDecodeError_SetStart(PyObject *, Py_ssize_t);
+PyAPI_FUNC(int) PyUnicodeTranslateError_SetStart(PyObject *, Py_ssize_t);
+
+/* get the value of the end attribute (the int *may not be NULL)
+ return 0 on success, -1 on failure */
+PyAPI_FUNC(int) PyUnicodeEncodeError_GetEnd(PyObject *, Py_ssize_t *);
+PyAPI_FUNC(int) PyUnicodeDecodeError_GetEnd(PyObject *, Py_ssize_t *);
+PyAPI_FUNC(int) PyUnicodeTranslateError_GetEnd(PyObject *, Py_ssize_t *);
+
+/* assign a new value to the end attribute
+   return 0 on success, -1 on failure */
+PyAPI_FUNC(int) PyUnicodeEncodeError_SetEnd(PyObject *, Py_ssize_t);
+PyAPI_FUNC(int) PyUnicodeDecodeError_SetEnd(PyObject *, Py_ssize_t);
+PyAPI_FUNC(int) PyUnicodeTranslateError_SetEnd(PyObject *, Py_ssize_t);
+
+/* get the value of the reason attribute */
+PyAPI_FUNC(PyObject *) PyUnicodeEncodeError_GetReason(PyObject *);
+PyAPI_FUNC(PyObject *) PyUnicodeDecodeError_GetReason(PyObject *);
+PyAPI_FUNC(PyObject *) PyUnicodeTranslateError_GetReason(PyObject *);
+
+/* assign a new value to the reason attribute
+   return 0 on success, -1 on failure */
+PyAPI_FUNC(int) PyUnicodeEncodeError_SetReason(
+	PyObject *, const char *);
+PyAPI_FUNC(int) PyUnicodeDecodeError_SetReason(
+	PyObject *, const char *);
+PyAPI_FUNC(int) PyUnicodeTranslateError_SetReason(
+	PyObject *, const char *);
+#endif
+
+
+/* These APIs aren't really part of the error implementation, but
+   often needed to format error messages; the native C lib APIs are
+   not available on all platforms, which is why we provide emulations
+   for those platforms in Python/mysnprintf.c,
+   WARNING:  The return value of snprintf varies across platforms; do
+   not rely on any particular behavior; eventually the C99 defn may
+   be reliable.
+*/
+#if defined(MS_WIN32) && !defined(HAVE_SNPRINTF)
+# define HAVE_SNPRINTF
+# define snprintf _snprintf
+# define vsnprintf _vsnprintf
+#endif
+
+#include <stdarg.h>
+PyAPI_FUNC(int) PyOS_snprintf(char *str, size_t size, const char  *format, ...)
+			Py_GCC_ATTRIBUTE((format(printf, 3, 4)));
+PyAPI_FUNC(int) PyOS_vsnprintf(char *str, size_t size, const char  *format, va_list va)
+			Py_GCC_ATTRIBUTE((format(printf, 3, 0)));
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_ERRORS_H */

Added: vendor/Python/current/Include/pyexpat.h
===================================================================
--- vendor/Python/current/Include/pyexpat.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/pyexpat.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,47 @@
+/* Stuff to export relevant 'expat' entry points from pyexpat to other
+ * parser modules, such as cElementTree. */
+
+/* note: you must import expat.h before importing this module! */
+
+#define PyExpat_CAPI_MAGIC  "pyexpat.expat_CAPI 1.0"
+
+struct PyExpat_CAPI 
+{
+    char* magic; /* set to PyExpat_CAPI_MAGIC */
+    int size; /* set to sizeof(struct PyExpat_CAPI) */
+    int MAJOR_VERSION;
+    int MINOR_VERSION;
+    int MICRO_VERSION;
+    /* pointers to selected expat functions.  add new functions at
+       the end, if needed */
+    const XML_LChar * (*ErrorString)(enum XML_Error code);
+    enum XML_Error (*GetErrorCode)(XML_Parser parser);
+    XML_Size (*GetErrorColumnNumber)(XML_Parser parser);
+    XML_Size (*GetErrorLineNumber)(XML_Parser parser);
+    enum XML_Status (*Parse)(
+        XML_Parser parser, const char *s, int len, int isFinal);
+    XML_Parser (*ParserCreate_MM)(
+        const XML_Char *encoding, const XML_Memory_Handling_Suite *memsuite,
+        const XML_Char *namespaceSeparator);
+    void (*ParserFree)(XML_Parser parser);
+    void (*SetCharacterDataHandler)(
+        XML_Parser parser, XML_CharacterDataHandler handler);
+    void (*SetCommentHandler)(
+        XML_Parser parser, XML_CommentHandler handler);
+    void (*SetDefaultHandlerExpand)(
+        XML_Parser parser, XML_DefaultHandler handler);
+    void (*SetElementHandler)(
+        XML_Parser parser, XML_StartElementHandler start,
+        XML_EndElementHandler end);
+    void (*SetNamespaceDeclHandler)(
+        XML_Parser parser, XML_StartNamespaceDeclHandler start,
+        XML_EndNamespaceDeclHandler end);
+    void (*SetProcessingInstructionHandler)(
+        XML_Parser parser, XML_ProcessingInstructionHandler handler);
+    void (*SetUnknownEncodingHandler)(
+        XML_Parser parser, XML_UnknownEncodingHandler handler,
+        void *encodingHandlerData);
+    void (*SetUserData)(XML_Parser parser, void *userData);
+    /* always add new stuff to the end! */
+};
+

Added: vendor/Python/current/Include/pyfpe.h
===================================================================
--- vendor/Python/current/Include/pyfpe.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/pyfpe.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,176 @@
+#ifndef Py_PYFPE_H
+#define Py_PYFPE_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+     ---------------------------------------------------------------------  
+    /                       Copyright (c) 1996.                           \ 
+   |          The Regents of the University of California.                 |
+   |                        All rights reserved.                           |
+   |                                                                       |
+   |   Permission to use, copy, modify, and distribute this software for   |
+   |   any purpose without fee is hereby granted, provided that this en-   |
+   |   tire notice is included in all copies of any software which is or   |
+   |   includes  a  copy  or  modification  of  this software and in all   |
+   |   copies of the supporting documentation for such software.           |
+   |                                                                       |
+   |   This  work was produced at the University of California, Lawrence   |
+   |   Livermore National Laboratory under  contract  no.  W-7405-ENG-48   |
+   |   between  the  U.S.  Department  of  Energy and The Regents of the   |
+   |   University of California for the operation of UC LLNL.              |
+   |                                                                       |
+   |                              DISCLAIMER                               |
+   |                                                                       |
+   |   This  software was prepared as an account of work sponsored by an   |
+   |   agency of the United States Government. Neither the United States   |
+   |   Government  nor the University of California nor any of their em-   |
+   |   ployees, makes any warranty, express or implied, or  assumes  any   |
+   |   liability  or  responsibility  for the accuracy, completeness, or   |
+   |   usefulness of any information,  apparatus,  product,  or  process   |
+   |   disclosed,   or  represents  that  its  use  would  not  infringe   |
+   |   privately-owned rights. Reference herein to any specific  commer-   |
+   |   cial  products,  process,  or  service  by trade name, trademark,   |
+   |   manufacturer, or otherwise, does not  necessarily  constitute  or   |
+   |   imply  its endorsement, recommendation, or favoring by the United   |
+   |   States Government or the University of California. The views  and   |
+   |   opinions  of authors expressed herein do not necessarily state or   |
+   |   reflect those of the United States Government or  the  University   |
+   |   of  California,  and shall not be used for advertising or product   |
+    \  endorsement purposes.                                              / 
+     ---------------------------------------------------------------------  
+*/
+
+/*
+ *       Define macros for handling SIGFPE.
+ *       Lee Busby, LLNL, November, 1996
+ *       busby1 at llnl.gov
+ * 
+ *********************************************
+ * Overview of the system for handling SIGFPE:
+ * 
+ * This file (Include/pyfpe.h) defines a couple of "wrapper" macros for
+ * insertion into your Python C code of choice. Their proper use is
+ * discussed below. The file Python/pyfpe.c defines a pair of global
+ * variables PyFPE_jbuf and PyFPE_counter which are used by the signal
+ * handler for SIGFPE to decide if a particular exception was protected
+ * by the macros. The signal handler itself, and code for enabling the
+ * generation of SIGFPE in the first place, is in a (new) Python module
+ * named fpectl. This module is standard in every respect. It can be loaded
+ * either statically or dynamically as you choose, and like any other
+ * Python module, has no effect until you import it.
+ * 
+ * In the general case, there are three steps toward handling SIGFPE in any
+ * Python code:
+ * 
+ * 1) Add the *_PROTECT macros to your C code as required to protect
+ *    dangerous floating point sections.
+ * 
+ * 2) Turn on the inclusion of the code by adding the ``--with-fpectl''
+ *    flag at the time you run configure.  If the fpectl or other modules
+ *    which use the *_PROTECT macros are to be dynamically loaded, be
+ *    sure they are compiled with WANT_SIGFPE_HANDLER defined.
+ * 
+ * 3) When python is built and running, import fpectl, and execute
+ *    fpectl.turnon_sigfpe(). This sets up the signal handler and enables
+ *    generation of SIGFPE whenever an exception occurs. From this point
+ *    on, any properly trapped SIGFPE should result in the Python
+ *    FloatingPointError exception.
+ * 
+ * Step 1 has been done already for the Python kernel code, and should be
+ * done soon for the NumPy array package.  Step 2 is usually done once at
+ * python install time. Python's behavior with respect to SIGFPE is not
+ * changed unless you also do step 3. Thus you can control this new
+ * facility at compile time, or run time, or both.
+ * 
+ ******************************** 
+ * Using the macros in your code:
+ * 
+ * static PyObject *foobar(PyObject *self,PyObject *args)
+ * {
+ *     ....
+ *     PyFPE_START_PROTECT("Error in foobar", return 0)
+ *     result = dangerous_op(somearg1, somearg2, ...);
+ *     PyFPE_END_PROTECT(result)
+ *     ....
+ * }
+ * 
+ * If a floating point error occurs in dangerous_op, foobar returns 0 (NULL),
+ * after setting the associated value of the FloatingPointError exception to
+ * "Error in foobar". ``Dangerous_op'' can be a single operation, or a block
+ * of code, function calls, or any combination, so long as no alternate
+ * return is possible before the PyFPE_END_PROTECT macro is reached.
+ * 
+ * The macros can only be used in a function context where an error return
+ * can be recognized as signaling a Python exception. (Generally, most
+ * functions that return a PyObject * will qualify.)
+ * 
+ * Guido's original design suggestion for PyFPE_START_PROTECT and
+ * PyFPE_END_PROTECT had them open and close a local block, with a locally
+ * defined jmp_buf and jmp_buf pointer. This would allow recursive nesting
+ * of the macros. The Ansi C standard makes it clear that such local
+ * variables need to be declared with the "volatile" type qualifier to keep
+ * setjmp from corrupting their values. Some current implementations seem
+ * to be more restrictive. For example, the HPUX man page for setjmp says
+ * 
+ *   Upon the return from a setjmp() call caused by a longjmp(), the
+ *   values of any non-static local variables belonging to the routine
+ *   from which setjmp() was called are undefined. Code which depends on
+ *   such values is not guaranteed to be portable.
+ * 
+ * I therefore decided on a more limited form of nesting, using a counter
+ * variable (PyFPE_counter) to keep track of any recursion.  If an exception
+ * occurs in an ``inner'' pair of macros, the return will apparently
+ * come from the outermost level.
+ * 
+ */
+
+#ifdef WANT_SIGFPE_HANDLER
+#include <signal.h>
+#include <setjmp.h>
+#include <math.h>
+extern jmp_buf PyFPE_jbuf;
+extern int PyFPE_counter;
+extern double PyFPE_dummy(void *);
+
+#define PyFPE_START_PROTECT(err_string, leave_stmt) \
+if (!PyFPE_counter++ && setjmp(PyFPE_jbuf)) { \
+	PyErr_SetString(PyExc_FloatingPointError, err_string); \
+	PyFPE_counter = 0; \
+	leave_stmt; \
+}
+
+/*
+ * This (following) is a heck of a way to decrement a counter. However,
+ * unless the macro argument is provided, code optimizers will sometimes move
+ * this statement so that it gets executed *before* the unsafe expression
+ * which we're trying to protect.  That pretty well messes things up,
+ * of course.
+ * 
+ * If the expression(s) you're trying to protect don't happen to return a
+ * value, you will need to manufacture a dummy result just to preserve the
+ * correct ordering of statements.  Note that the macro passes the address
+ * of its argument (so you need to give it something which is addressable).
+ * If your expression returns multiple results, pass the last such result
+ * to PyFPE_END_PROTECT.
+ * 
+ * Note that PyFPE_dummy returns a double, which is cast to int.
+ * This seeming insanity is to tickle the Floating Point Unit (FPU).
+ * If an exception has occurred in a preceding floating point operation,
+ * some architectures (notably Intel 80x86) will not deliver the interrupt
+ * until the *next* floating point operation.  This is painful if you've
+ * already decremented PyFPE_counter.
+ */
+#define PyFPE_END_PROTECT(v) PyFPE_counter -= (int)PyFPE_dummy(&(v));
+
+#else
+
+#define PyFPE_START_PROTECT(err_string, leave_stmt)
+#define PyFPE_END_PROTECT(v)
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_PYFPE_H */

Added: vendor/Python/current/Include/pygetopt.h
===================================================================
--- vendor/Python/current/Include/pygetopt.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/pygetopt.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,17 @@
+
+#ifndef Py_PYGETOPT_H
+#define Py_PYGETOPT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+PyAPI_DATA(int) _PyOS_opterr;
+PyAPI_DATA(int) _PyOS_optind;
+PyAPI_DATA(char *) _PyOS_optarg;
+
+PyAPI_FUNC(int) _PyOS_GetOpt(int argc, char **argv, char *optstring);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_PYGETOPT_H */

Added: vendor/Python/current/Include/pymactoolbox.h
===================================================================
--- vendor/Python/current/Include/pymactoolbox.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/pymactoolbox.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,189 @@
+/*
+** pymactoolbox.h - globals defined in mactoolboxglue.c
+*/
+#ifndef Py_PYMACTOOLBOX_H
+#define Py_PYMACTOOLBOX_H
+#ifdef __cplusplus
+	extern "C" {
+#endif
+
+#include <Carbon/Carbon.h>
+#include <QuickTime/QuickTime.h>
+
+/*
+** Helper routines for error codes and such.
+*/
+char *PyMac_StrError(int);			/* strerror with mac errors */
+extern PyObject *PyMac_OSErrException;		/* Exception for OSErr */
+PyObject *PyMac_GetOSErrException(void);	/* Initialize & return it */
+PyObject *PyErr_Mac(PyObject *, int);		/* Exception with a mac error */
+PyObject *PyMac_Error(OSErr);			/* Uses PyMac_GetOSErrException */
+extern OSErr PyMac_GetFullPathname(FSSpec *, char *, int); /* convert
+							      fsspec->path */
+/*
+** These conversion routines are defined in mactoolboxglue.c itself.
+*/
+int PyMac_GetOSType(PyObject *, OSType *);	/* argument parser for OSType */
+PyObject *PyMac_BuildOSType(OSType);		/* Convert OSType to PyObject */
+
+PyObject *PyMac_BuildNumVersion(NumVersion);/* Convert NumVersion to PyObject */
+
+int PyMac_GetStr255(PyObject *, Str255);	/* argument parser for Str255 */
+PyObject *PyMac_BuildStr255(Str255);		/* Convert Str255 to PyObject */
+PyObject *PyMac_BuildOptStr255(Str255);		/* Convert Str255 to PyObject,
+						   NULL to None */
+
+int PyMac_GetRect(PyObject *, Rect *);		/* argument parser for Rect */
+PyObject *PyMac_BuildRect(Rect *);		/* Convert Rect to PyObject */
+
+int PyMac_GetPoint(PyObject *, Point *);	/* argument parser for Point */
+PyObject *PyMac_BuildPoint(Point);		/* Convert Point to PyObject */
+
+int PyMac_GetEventRecord(PyObject *, EventRecord *); /* argument parser for
+							EventRecord */
+PyObject *PyMac_BuildEventRecord(EventRecord *); /* Convert EventRecord to
+						    PyObject */
+
+int PyMac_GetFixed(PyObject *, Fixed *);	/* argument parser for Fixed */
+PyObject *PyMac_BuildFixed(Fixed);		/* Convert Fixed to PyObject */
+int PyMac_Getwide(PyObject *, wide *);		/* argument parser for wide */
+PyObject *PyMac_Buildwide(wide *);		/* Convert wide to PyObject */
+
+/*
+** The rest of the routines are implemented by extension modules. If they are
+** dynamically loaded mactoolboxglue will contain a stub implementation of the
+** routine, which imports the module, whereupon the module's init routine will
+** communicate the routine pointer back to the stub.
+** If USE_TOOLBOX_OBJECT_GLUE is not defined there is no glue code, and the
+** extension modules simply declare the routine. This is the case for static
+** builds (and could be the case for MacPython CFM builds, because CFM extension
+** modules can reference each other without problems).
+*/
+
+#ifdef USE_TOOLBOX_OBJECT_GLUE
+/*
+** These macros are used in the module init code. If we use toolbox object glue
+** it sets the function pointer to point to the real function.
+*/
+#define PyMac_INIT_TOOLBOX_OBJECT_NEW(object, rtn) { \
+	extern PyObject *(*PyMacGluePtr_##rtn)(object); \
+	PyMacGluePtr_##rtn = _##rtn; \
+}
+#define PyMac_INIT_TOOLBOX_OBJECT_CONVERT(object, rtn) { \
+	extern int (*PyMacGluePtr_##rtn)(PyObject *, object *); \
+	PyMacGluePtr_##rtn = _##rtn; \
+}
+#else
+/*
+** If we don't use toolbox object glue the init macros are empty. Moreover, we define
+** _xxx_New to be the same as xxx_New, and the code in mactoolboxglue isn't included.
+*/
+#define PyMac_INIT_TOOLBOX_OBJECT_NEW(object, rtn)
+#define PyMac_INIT_TOOLBOX_OBJECT_CONVERT(object, rtn)
+#endif /* USE_TOOLBOX_OBJECT_GLUE */
+
+/* macfs exports */
+int PyMac_GetFSSpec(PyObject *, FSSpec *);	/* argument parser for FSSpec */
+PyObject *PyMac_BuildFSSpec(FSSpec *);		/* Convert FSSpec to PyObject */
+
+int PyMac_GetFSRef(PyObject *, FSRef *);	/* argument parser for FSRef */
+PyObject *PyMac_BuildFSRef(FSRef *);		/* Convert FSRef to PyObject */
+
+/* AE exports */
+extern PyObject *AEDesc_New(AppleEvent *); /* XXXX Why passed by address?? */
+extern PyObject *AEDesc_NewBorrowed(AppleEvent *);
+extern int AEDesc_Convert(PyObject *, AppleEvent *);
+
+/* Cm exports */
+extern PyObject *CmpObj_New(Component);
+extern int CmpObj_Convert(PyObject *, Component *);
+extern PyObject *CmpInstObj_New(ComponentInstance);
+extern int CmpInstObj_Convert(PyObject *, ComponentInstance *);
+
+/* Ctl exports */
+extern PyObject *CtlObj_New(ControlHandle);
+extern int CtlObj_Convert(PyObject *, ControlHandle *);
+
+/* Dlg exports */
+extern PyObject *DlgObj_New(DialogPtr);
+extern int DlgObj_Convert(PyObject *, DialogPtr *);
+extern PyObject *DlgObj_WhichDialog(DialogPtr);
+
+/* Drag exports */
+extern PyObject *DragObj_New(DragReference);
+extern int DragObj_Convert(PyObject *, DragReference *);
+
+/* List exports */
+extern PyObject *ListObj_New(ListHandle);
+extern int ListObj_Convert(PyObject *, ListHandle *);
+
+/* Menu exports */
+extern PyObject *MenuObj_New(MenuHandle);
+extern int MenuObj_Convert(PyObject *, MenuHandle *);
+
+/* Qd exports */
+extern PyObject *GrafObj_New(GrafPtr);
+extern int GrafObj_Convert(PyObject *, GrafPtr *);
+extern PyObject *BMObj_New(BitMapPtr);
+extern int BMObj_Convert(PyObject *, BitMapPtr *);
+extern PyObject *QdRGB_New(RGBColor *);
+extern int QdRGB_Convert(PyObject *, RGBColor *);
+
+/* Qdoffs exports */
+extern PyObject *GWorldObj_New(GWorldPtr);
+extern int GWorldObj_Convert(PyObject *, GWorldPtr *);
+
+/* Qt exports */
+extern PyObject *TrackObj_New(Track);
+extern int TrackObj_Convert(PyObject *, Track *);
+extern PyObject *MovieObj_New(Movie);
+extern int MovieObj_Convert(PyObject *, Movie *);
+extern PyObject *MovieCtlObj_New(MovieController);
+extern int MovieCtlObj_Convert(PyObject *, MovieController *);
+extern PyObject *TimeBaseObj_New(TimeBase);
+extern int TimeBaseObj_Convert(PyObject *, TimeBase *);
+extern PyObject *UserDataObj_New(UserData);
+extern int UserDataObj_Convert(PyObject *, UserData *);
+extern PyObject *MediaObj_New(Media);
+extern int MediaObj_Convert(PyObject *, Media *);
+
+/* Res exports */
+extern PyObject *ResObj_New(Handle);
+extern int ResObj_Convert(PyObject *, Handle *);
+extern PyObject *OptResObj_New(Handle);
+extern int OptResObj_Convert(PyObject *, Handle *);
+
+/* TE exports */
+extern PyObject *TEObj_New(TEHandle);
+extern int TEObj_Convert(PyObject *, TEHandle *);
+
+/* Win exports */
+extern PyObject *WinObj_New(WindowPtr);
+extern int WinObj_Convert(PyObject *, WindowPtr *);
+extern PyObject *WinObj_WhichWindow(WindowPtr);
+
+/* CF exports */
+extern PyObject *CFObj_New(CFTypeRef);
+extern int CFObj_Convert(PyObject *, CFTypeRef *);
+extern PyObject *CFTypeRefObj_New(CFTypeRef);
+extern int CFTypeRefObj_Convert(PyObject *, CFTypeRef *);
+extern PyObject *CFStringRefObj_New(CFStringRef);
+extern int CFStringRefObj_Convert(PyObject *, CFStringRef *);
+extern PyObject *CFMutableStringRefObj_New(CFMutableStringRef);
+extern int CFMutableStringRefObj_Convert(PyObject *, CFMutableStringRef *);
+extern PyObject *CFArrayRefObj_New(CFArrayRef);
+extern int CFArrayRefObj_Convert(PyObject *, CFArrayRef *);
+extern PyObject *CFMutableArrayRefObj_New(CFMutableArrayRef);
+extern int CFMutableArrayRefObj_Convert(PyObject *, CFMutableArrayRef *);
+extern PyObject *CFDictionaryRefObj_New(CFDictionaryRef);
+extern int CFDictionaryRefObj_Convert(PyObject *, CFDictionaryRef *);
+extern PyObject *CFMutableDictionaryRefObj_New(CFMutableDictionaryRef);
+extern int CFMutableDictionaryRefObj_Convert(PyObject *, CFMutableDictionaryRef *);
+extern PyObject *CFURLRefObj_New(CFURLRef);
+extern int CFURLRefObj_Convert(PyObject *, CFURLRef *);
+extern int OptionalCFURLRefObj_Convert(PyObject *, CFURLRef *);
+
+#ifdef __cplusplus
+	}
+#endif
+#endif

Added: vendor/Python/current/Include/pymem.h
===================================================================
--- vendor/Python/current/Include/pymem.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/pymem.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,105 @@
+/* The PyMem_ family:  low-level memory allocation interfaces.
+   See objimpl.h for the PyObject_ memory family.
+*/
+
+#ifndef Py_PYMEM_H
+#define Py_PYMEM_H
+
+#include "pyport.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* BEWARE:
+
+   Each interface exports both functions and macros.  Extension modules should
+   use the functions, to ensure binary compatibility across Python versions.
+   Because the Python implementation is free to change internal details, and
+   the macros may (or may not) expose details for speed, if you do use the
+   macros you must recompile your extensions with each Python release.
+
+   Never mix calls to PyMem_ with calls to the platform malloc/realloc/
+   calloc/free.  For example, on Windows different DLLs may end up using
+   different heaps, and if you use PyMem_Malloc you'll get the memory from the
+   heap used by the Python DLL; it could be a disaster if you free()'ed that
+   directly in your own extension.  Using PyMem_Free instead ensures Python
+   can return the memory to the proper heap.  As another example, in
+   PYMALLOC_DEBUG mode, Python wraps all calls to all PyMem_ and PyObject_
+   memory functions in special debugging wrappers that add additional
+   debugging info to dynamic memory blocks.  The system routines have no idea
+   what to do with that stuff, and the Python wrappers have no idea what to do
+   with raw blocks obtained directly by the system routines then.
+*/
+
+/*
+ * Raw memory interface
+ * ====================
+ */
+
+/* Functions
+
+   Functions supplying platform-independent semantics for malloc/realloc/
+   free.  These functions make sure that allocating 0 bytes returns a distinct
+   non-NULL pointer (whenever possible -- if we're flat out of memory, NULL
+   may be returned), even if the platform malloc and realloc don't.
+   Returned pointers must be checked for NULL explicitly.  No action is
+   performed on failure (no exception is set, no warning is printed, etc).
+*/
+
+PyAPI_FUNC(void *) PyMem_Malloc(size_t);
+PyAPI_FUNC(void *) PyMem_Realloc(void *, size_t);
+PyAPI_FUNC(void) PyMem_Free(void *);
+
+/* Starting from Python 1.6, the wrappers Py_{Malloc,Realloc,Free} are
+   no longer supported. They used to call PyErr_NoMemory() on failure. */
+
+/* Macros. */
+#ifdef PYMALLOC_DEBUG
+/* Redirect all memory operations to Python's debugging allocator. */
+#define PyMem_MALLOC		PyObject_MALLOC
+#define PyMem_REALLOC		PyObject_REALLOC
+#define PyMem_FREE		PyObject_FREE
+
+#else	/* ! PYMALLOC_DEBUG */
+
+/* PyMem_MALLOC(0) means malloc(1). Some systems would return NULL
+   for malloc(0), which would be treated as an error. Some platforms
+   would return a pointer with no memory behind it, which would break
+   pymalloc. To solve these problems, allocate an extra byte. */
+#define PyMem_MALLOC(n)         malloc((n) ? (n) : 1)
+#define PyMem_REALLOC(p, n)     realloc((p), (n) ? (n) : 1)
+#define PyMem_FREE		free
+
+#endif	/* PYMALLOC_DEBUG */
+
+/*
+ * Type-oriented memory interface
+ * ==============================
+ *
+ * These are carried along for historical reasons.  There's rarely a good
+ * reason to use them anymore (you can just as easily do the multiply and
+ * cast yourself).
+ */
+
+#define PyMem_New(type, n) \
+	( (type *) PyMem_Malloc((n) * sizeof(type)) )
+#define PyMem_NEW(type, n) \
+	( (type *) PyMem_MALLOC((n) * sizeof(type)) )
+
+#define PyMem_Resize(p, type, n) \
+	( (p) = (type *) PyMem_Realloc((p), (n) * sizeof(type)) )
+#define PyMem_RESIZE(p, type, n) \
+	( (p) = (type *) PyMem_REALLOC((p), (n) * sizeof(type)) )
+
+/* PyMem{Del,DEL} are left over from ancient days, and shouldn't be used
+ * anymore.  They're just confusing aliases for PyMem_{Free,FREE} now.
+ */
+#define PyMem_Del		PyMem_Free
+#define PyMem_DEL		PyMem_FREE
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !Py_PYMEM_H */

Added: vendor/Python/current/Include/pyport.h
===================================================================
--- vendor/Python/current/Include/pyport.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/pyport.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,771 @@
+#ifndef Py_PYPORT_H
+#define Py_PYPORT_H
+
+#include "pyconfig.h" /* include for defines */
+
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+/**************************************************************************
+Symbols and macros to supply platform-independent interfaces to basic
+C language & library operations whose spellings vary across platforms.
+
+Please try to make documentation here as clear as possible:  by definition,
+the stuff here is trying to illuminate C's darkest corners.
+
+Config #defines referenced here:
+
+SIGNED_RIGHT_SHIFT_ZERO_FILLS
+Meaning:  To be defined iff i>>j does not extend the sign bit when i is a
+          signed integral type and i < 0.
+Used in:  Py_ARITHMETIC_RIGHT_SHIFT
+
+Py_DEBUG
+Meaning:  Extra checks compiled in for debug mode.
+Used in:  Py_SAFE_DOWNCAST
+
+HAVE_UINTPTR_T
+Meaning:  The C9X type uintptr_t is supported by the compiler
+Used in:  Py_uintptr_t
+
+HAVE_LONG_LONG
+Meaning:  The compiler supports the C type "long long"
+Used in:  PY_LONG_LONG
+
+**************************************************************************/
+
+
+/* For backward compatibility only. Obsolete, do not use. */
+#ifdef HAVE_PROTOTYPES
+#define Py_PROTO(x) x
+#else
+#define Py_PROTO(x) ()
+#endif
+#ifndef Py_FPROTO
+#define Py_FPROTO(x) Py_PROTO(x)
+#endif
+
+/* typedefs for some C9X-defined synonyms for integral types.
+ *
+ * The names in Python are exactly the same as the C9X names, except with a
+ * Py_ prefix.  Until C9X is universally implemented, this is the only way
+ * to ensure that Python gets reliable names that don't conflict with names
+ * in non-Python code that are playing their own tricks to define the C9X
+ * names.
+ *
+ * NOTE: don't go nuts here!  Python has no use for *most* of the C9X
+ * integral synonyms.  Only define the ones we actually need.
+ */
+
+#ifdef HAVE_LONG_LONG
+#ifndef PY_LONG_LONG
+#define PY_LONG_LONG long long
+#endif
+#endif /* HAVE_LONG_LONG */
+
+/* uintptr_t is the C9X name for an unsigned integral type such that a
+ * legitimate void* can be cast to uintptr_t and then back to void* again
+ * without loss of information.  Similarly for intptr_t, wrt a signed
+ * integral type.
+ */
+#ifdef HAVE_UINTPTR_T
+typedef uintptr_t	Py_uintptr_t;
+typedef intptr_t	Py_intptr_t;
+
+#elif SIZEOF_VOID_P <= SIZEOF_INT
+typedef unsigned int	Py_uintptr_t;
+typedef int		Py_intptr_t;
+
+#elif SIZEOF_VOID_P <= SIZEOF_LONG
+typedef unsigned long	Py_uintptr_t;
+typedef long		Py_intptr_t;
+
+#elif defined(HAVE_LONG_LONG) && (SIZEOF_VOID_P <= SIZEOF_LONG_LONG)
+typedef unsigned PY_LONG_LONG	Py_uintptr_t;
+typedef PY_LONG_LONG		Py_intptr_t;
+
+#else
+#   error "Python needs a typedef for Py_uintptr_t in pyport.h."
+#endif /* HAVE_UINTPTR_T */
+
+/* Py_ssize_t is a signed integral type such that sizeof(Py_ssize_t) ==
+ * sizeof(size_t).  C99 doesn't define such a thing directly (size_t is an
+ * unsigned integral type).  See PEP 353 for details.
+ */
+#ifdef HAVE_SSIZE_T
+typedef ssize_t		Py_ssize_t;
+#elif SIZEOF_VOID_P == SIZEOF_SIZE_T
+typedef Py_intptr_t	Py_ssize_t;
+#else
+#   error "Python needs a typedef for Py_ssize_t in pyport.h."
+#endif
+
+/* Largest positive value of type Py_ssize_t. */
+#define PY_SSIZE_T_MAX ((Py_ssize_t)(((size_t)-1)>>1))
+/* Smallest negative value of type Py_ssize_t. */
+#define PY_SSIZE_T_MIN (-PY_SSIZE_T_MAX-1)
+
+/* PY_FORMAT_SIZE_T is a platform-specific modifier for use in a printf
+ * format to convert an argument with the width of a size_t or Py_ssize_t.
+ * C99 introduced "z" for this purpose, but not all platforms support that;
+ * e.g., MS compilers use "I" instead.
+ *
+ * These "high level" Python format functions interpret "z" correctly on
+ * all platforms (Python interprets the format string itself, and does whatever
+ * the platform C requires to convert a size_t/Py_ssize_t argument):
+ *
+ *     PyString_FromFormat
+ *     PyErr_Format
+ *     PyString_FromFormatV
+ *
+ * Lower-level uses require that you interpolate the correct format modifier
+ * yourself (e.g., calling printf, fprintf, sprintf, PyOS_snprintf); for
+ * example,
+ *
+ *     Py_ssize_t index;
+ *     fprintf(stderr, "index %" PY_FORMAT_SIZE_T "d sucks\n", index);
+ *
+ * That will expand to %ld, or %Id, or to something else correct for a
+ * Py_ssize_t on the platform.
+ */
+#ifndef PY_FORMAT_SIZE_T
+#   if SIZEOF_SIZE_T == SIZEOF_INT && !defined(__APPLE__)
+#       define PY_FORMAT_SIZE_T ""
+#   elif SIZEOF_SIZE_T == SIZEOF_LONG
+#       define PY_FORMAT_SIZE_T "l"
+#   elif defined(MS_WINDOWS)
+#       define PY_FORMAT_SIZE_T "I"
+#   else
+#       error "This platform's pyconfig.h needs to define PY_FORMAT_SIZE_T"
+#   endif
+#endif
+
+/* Py_LOCAL can be used instead of static to get the fastest possible calling
+ * convention for functions that are local to a given module.
+ *
+ * Py_LOCAL_INLINE does the same thing, and also explicitly requests inlining,
+ * for platforms that support that.
+ *
+ * If PY_LOCAL_AGGRESSIVE is defined before python.h is included, more
+ * "aggressive" inlining/optimizaion is enabled for the entire module.  This
+ * may lead to code bloat, and may slow things down for those reasons.  It may
+ * also lead to errors, if the code relies on pointer aliasing.  Use with
+ * care.
+ *
+ * NOTE: You can only use this for functions that are entirely local to a
+ * module; functions that are exported via method tables, callbacks, etc,
+ * should keep using static.
+ */
+
+#undef USE_INLINE /* XXX - set via configure? */
+
+#if defined(_MSC_VER)
+#if defined(PY_LOCAL_AGGRESSIVE)
+/* enable more aggressive optimization for visual studio */
+#pragma optimize("agtw", on)
+#endif
+/* ignore warnings if the compiler decides not to inline a function */ 
+#pragma warning(disable: 4710)
+/* fastest possible local call under MSVC */
+#define Py_LOCAL(type) static type __fastcall
+#define Py_LOCAL_INLINE(type) static __inline type __fastcall
+#elif defined(USE_INLINE)
+#define Py_LOCAL(type) static type
+#define Py_LOCAL_INLINE(type) static inline type
+#else
+#define Py_LOCAL(type) static type
+#define Py_LOCAL_INLINE(type) static type
+#endif
+
+/* Py_MEMCPY can be used instead of memcpy in cases where the copied blocks
+ * are often very short.  While most platforms have highly optimized code for
+ * large transfers, the setup costs for memcpy are often quite high.  MEMCPY
+ * solves this by doing short copies "in line".
+ */
+
+#if defined(_MSC_VER)
+#define Py_MEMCPY(target, source, length) do {				\
+		size_t i_, n_ = (length);				\
+		char *t_ = (void*) (target);				\
+		const char *s_ = (void*) (source);			\
+		if (n_ >= 16)						\
+			memcpy(t_, s_, n_);				\
+		else							\
+			for (i_ = 0; i_ < n_; i_++)			\
+				t_[i_] = s_[i_];			\
+	} while (0)
+#else
+#define Py_MEMCPY memcpy
+#endif
+
+#include <stdlib.h>
+
+#include <math.h> /* Moved here from the math section, before extern "C" */
+
+/********************************************
+ * WRAPPER FOR <time.h> and/or <sys/time.h> *
+ ********************************************/
+
+#ifdef TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#else /* !TIME_WITH_SYS_TIME */
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#else /* !HAVE_SYS_TIME_H */
+#include <time.h>
+#endif /* !HAVE_SYS_TIME_H */
+#endif /* !TIME_WITH_SYS_TIME */
+
+
+/******************************
+ * WRAPPER FOR <sys/select.h> *
+ ******************************/
+
+/* NB caller must include <sys/types.h> */
+
+#ifdef HAVE_SYS_SELECT_H
+
+#include <sys/select.h>
+
+#endif /* !HAVE_SYS_SELECT_H */
+
+/*******************************
+ * stat() and fstat() fiddling *
+ *******************************/
+
+/* We expect that stat and fstat exist on most systems.
+ *  It's confirmed on Unix, Mac and Windows.
+ *  If you don't have them, add
+ *      #define DONT_HAVE_STAT
+ * and/or
+ *      #define DONT_HAVE_FSTAT
+ * to your pyconfig.h. Python code beyond this should check HAVE_STAT and
+ * HAVE_FSTAT instead.
+ * Also
+ *      #define HAVE_SYS_STAT_H
+ * if <sys/stat.h> exists on your platform, and
+ *      #define HAVE_STAT_H
+ * if <stat.h> does.
+ */
+#ifndef DONT_HAVE_STAT
+#define HAVE_STAT
+#endif
+
+#ifndef DONT_HAVE_FSTAT
+#define HAVE_FSTAT
+#endif
+
+#ifdef RISCOS
+#include <sys/types.h>
+#include "unixstuff.h"
+#endif
+
+#ifdef HAVE_SYS_STAT_H
+#if defined(PYOS_OS2) && defined(PYCC_GCC)
+#include <sys/types.h>
+#endif
+#include <sys/stat.h>
+#elif defined(HAVE_STAT_H)
+#include <stat.h>
+#endif
+
+#if defined(PYCC_VACPP)
+/* VisualAge C/C++ Failed to Define MountType Field in sys/stat.h */
+#define S_IFMT (S_IFDIR|S_IFCHR|S_IFREG)
+#endif
+
+#ifndef S_ISREG
+#define S_ISREG(x) (((x) & S_IFMT) == S_IFREG)
+#endif
+
+#ifndef S_ISDIR
+#define S_ISDIR(x) (((x) & S_IFMT) == S_IFDIR)
+#endif
+
+
+#ifdef __cplusplus
+/* Move this down here since some C++ #include's don't like to be included
+   inside an extern "C" */
+extern "C" {
+#endif
+
+
+/* Py_ARITHMETIC_RIGHT_SHIFT
+ * C doesn't define whether a right-shift of a signed integer sign-extends
+ * or zero-fills.  Here a macro to force sign extension:
+ * Py_ARITHMETIC_RIGHT_SHIFT(TYPE, I, J)
+ *    Return I >> J, forcing sign extension.
+ * Requirements:
+ *    I is of basic signed type TYPE (char, short, int, long, or long long).
+ *    TYPE is one of char, short, int, long, or long long, although long long
+ *    must not be used except on platforms that support it.
+ *    J is an integer >= 0 and strictly less than the number of bits in TYPE
+ *    (because C doesn't define what happens for J outside that range either).
+ * Caution:
+ *    I may be evaluated more than once.
+ */
+#ifdef SIGNED_RIGHT_SHIFT_ZERO_FILLS
+#define Py_ARITHMETIC_RIGHT_SHIFT(TYPE, I, J) \
+	((I) < 0 ? ~((~(unsigned TYPE)(I)) >> (J)) : (I) >> (J))
+#else
+#define Py_ARITHMETIC_RIGHT_SHIFT(TYPE, I, J) ((I) >> (J))
+#endif
+
+/* Py_FORCE_EXPANSION(X)
+ * "Simply" returns its argument.  However, macro expansions within the
+ * argument are evaluated.  This unfortunate trickery is needed to get
+ * token-pasting to work as desired in some cases.
+ */
+#define Py_FORCE_EXPANSION(X) X
+
+/* Py_SAFE_DOWNCAST(VALUE, WIDE, NARROW)
+ * Cast VALUE to type NARROW from type WIDE.  In Py_DEBUG mode, this
+ * assert-fails if any information is lost.
+ * Caution:
+ *    VALUE may be evaluated more than once.
+ */
+#ifdef Py_DEBUG
+#define Py_SAFE_DOWNCAST(VALUE, WIDE, NARROW) \
+	(assert((WIDE)(NARROW)(VALUE) == (VALUE)), (NARROW)(VALUE))
+#else
+#define Py_SAFE_DOWNCAST(VALUE, WIDE, NARROW) (NARROW)(VALUE)
+#endif
+
+/* Py_IS_NAN(X)
+ * Return 1 if float or double arg is a NaN, else 0.
+ * Caution:
+ *     X is evaluated more than once.
+ *     This may not work on all platforms.  Each platform has *some*
+ *     way to spell this, though -- override in pyconfig.h if you have
+ *     a platform where it doesn't work.
+ */
+#ifndef Py_IS_NAN
+#define Py_IS_NAN(X) ((X) != (X))
+#endif
+
+/* Py_IS_INFINITY(X)
+ * Return 1 if float or double arg is an infinity, else 0.
+ * Caution:
+ *    X is evaluated more than once.
+ *    This implementation may set the underflow flag if |X| is very small;
+ *    it really can't be implemented correctly (& easily) before C99.
+ *    Override in pyconfig.h if you have a better spelling on your platform.
+ */
+#ifndef Py_IS_INFINITY
+#define Py_IS_INFINITY(X) ((X) && (X)*0.5 == (X))
+#endif
+
+/* Py_IS_FINITE(X)
+ * Return 1 if float or double arg is neither infinite nor NAN, else 0.
+ * Some compilers (e.g. VisualStudio) have intrisics for this, so a special
+ * macro for this particular test is useful
+ */
+#ifndef Py_IS_FINITE
+#define Py_IS_FINITE(X) (!Py_IS_INFINITY(X) && !Py_IS_NAN(X))
+#endif
+
+/* HUGE_VAL is supposed to expand to a positive double infinity.  Python
+ * uses Py_HUGE_VAL instead because some platforms are broken in this
+ * respect.  We used to embed code in pyport.h to try to worm around that,
+ * but different platforms are broken in conflicting ways.  If you're on
+ * a platform where HUGE_VAL is defined incorrectly, fiddle your Python
+ * config to #define Py_HUGE_VAL to something that works on your platform.
+ */
+#ifndef Py_HUGE_VAL
+#define Py_HUGE_VAL HUGE_VAL
+#endif
+
+/* Py_OVERFLOWED(X)
+ * Return 1 iff a libm function overflowed.  Set errno to 0 before calling
+ * a libm function, and invoke this macro after, passing the function
+ * result.
+ * Caution:
+ *    This isn't reliable.  C99 no longer requires libm to set errno under
+ *	  any exceptional condition, but does require +- HUGE_VAL return
+ *	  values on overflow.  A 754 box *probably* maps HUGE_VAL to a
+ *	  double infinity, and we're cool if that's so, unless the input
+ *	  was an infinity and an infinity is the expected result.  A C89
+ *	  system sets errno to ERANGE, so we check for that too.  We're
+ *	  out of luck if a C99 754 box doesn't map HUGE_VAL to +Inf, or
+ *	  if the returned result is a NaN, or if a C89 box returns HUGE_VAL
+ *	  in non-overflow cases.
+ *    X is evaluated more than once.
+ * Some platforms have better way to spell this, so expect some #ifdef'ery.
+ *
+ * OpenBSD uses 'isinf()' because a compiler bug on that platform causes
+ * the longer macro version to be mis-compiled. This isn't optimal, and
+ * should be removed once a newer compiler is available on that platform.
+ * The system that had the failure was running OpenBSD 3.2 on Intel, with
+ * gcc 2.95.3.
+ *
+ * According to Tim's checkin, the FreeBSD systems use isinf() to work
+ * around a FPE bug on that platform.
+ */
+#if defined(__FreeBSD__) || defined(__OpenBSD__)
+#define Py_OVERFLOWED(X) isinf(X)
+#else
+#define Py_OVERFLOWED(X) ((X) != 0.0 && (errno == ERANGE ||    \
+					 (X) == Py_HUGE_VAL || \
+					 (X) == -Py_HUGE_VAL))
+#endif
+
+/* Py_SET_ERRNO_ON_MATH_ERROR(x)
+ * If a libm function did not set errno, but it looks like the result
+ * overflowed or not-a-number, set errno to ERANGE or EDOM.  Set errno
+ * to 0 before calling a libm function, and invoke this macro after,
+ * passing the function result.
+ * Caution:
+ *    This isn't reliable.  See Py_OVERFLOWED comments.
+ *    X is evaluated more than once.
+ */
+#if defined(__FreeBSD__) || defined(__OpenBSD__) || (defined(__hpux) && defined(__ia64))
+#define _Py_SET_EDOM_FOR_NAN(X) if (isnan(X)) errno = EDOM;
+#else
+#define _Py_SET_EDOM_FOR_NAN(X) ;
+#endif
+#define Py_SET_ERRNO_ON_MATH_ERROR(X) \
+	do { \
+		if (errno == 0) { \
+			if ((X) == Py_HUGE_VAL || (X) == -Py_HUGE_VAL) \
+				errno = ERANGE; \
+			else _Py_SET_EDOM_FOR_NAN(X) \
+		} \
+	} while(0)
+
+/* Py_SET_ERANGE_ON_OVERFLOW(x)
+ * An alias of Py_SET_ERRNO_ON_MATH_ERROR for backward-compatibility.
+ */
+#define Py_SET_ERANGE_IF_OVERFLOW(X) Py_SET_ERRNO_ON_MATH_ERROR(X)
+
+/* Py_ADJUST_ERANGE1(x)
+ * Py_ADJUST_ERANGE2(x, y)
+ * Set errno to 0 before calling a libm function, and invoke one of these
+ * macros after, passing the function result(s) (Py_ADJUST_ERANGE2 is useful
+ * for functions returning complex results).  This makes two kinds of
+ * adjustments to errno:  (A) If it looks like the platform libm set
+ * errno=ERANGE due to underflow, clear errno. (B) If it looks like the
+ * platform libm overflowed but didn't set errno, force errno to ERANGE.  In
+ * effect, we're trying to force a useful implementation of C89 errno
+ * behavior.
+ * Caution:
+ *    This isn't reliable.  See Py_OVERFLOWED comments.
+ *    X and Y may be evaluated more than once.
+ */
+#define Py_ADJUST_ERANGE1(X)						\
+	do {								\
+		if (errno == 0) {					\
+			if ((X) == Py_HUGE_VAL || (X) == -Py_HUGE_VAL)	\
+				errno = ERANGE;				\
+		}							\
+		else if (errno == ERANGE && (X) == 0.0)			\
+			errno = 0;					\
+	} while(0)
+
+#define Py_ADJUST_ERANGE2(X, Y)						\
+	do {								\
+		if ((X) == Py_HUGE_VAL || (X) == -Py_HUGE_VAL ||	\
+		    (Y) == Py_HUGE_VAL || (Y) == -Py_HUGE_VAL) {	\
+				if (errno == 0)				\
+					errno = ERANGE;			\
+		}							\
+		else if (errno == ERANGE)				\
+			errno = 0;					\
+	} while(0)
+
+/* Py_DEPRECATED(version)
+ * Declare a variable, type, or function deprecated.
+ * Usage:
+ *    extern int old_var Py_DEPRECATED(2.3);
+ *    typedef int T1 Py_DEPRECATED(2.4);
+ *    extern int x() Py_DEPRECATED(2.5);
+ */
+#if defined(__GNUC__) && ((__GNUC__ >= 4) || \
+			  (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1))
+#define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__))
+#else
+#define Py_DEPRECATED(VERSION_UNUSED)
+#endif
+
+/**************************************************************************
+Prototypes that are missing from the standard include files on some systems
+(and possibly only some versions of such systems.)
+
+Please be conservative with adding new ones, document them and enclose them
+in platform-specific #ifdefs.
+**************************************************************************/
+
+#ifdef SOLARIS
+/* Unchecked */
+extern int gethostname(char *, int);
+#endif
+
+#ifdef __BEOS__
+/* Unchecked */
+/* It's in the libs, but not the headers... - [cjh] */
+int shutdown( int, int );
+#endif
+
+#ifdef HAVE__GETPTY
+#include <sys/types.h>		/* we need to import mode_t */
+extern char * _getpty(int *, int, mode_t, int);
+#endif
+
+#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
+#if !defined(HAVE_PTY_H) && !defined(HAVE_LIBUTIL_H)
+/* BSDI does not supply a prototype for the 'openpty' and 'forkpty'
+   functions, even though they are included in libutil. */
+#include <termios.h>
+extern int openpty(int *, int *, char *, struct termios *, struct winsize *);
+extern int forkpty(int *, char *, struct termios *, struct winsize *);
+#endif /* !defined(HAVE_PTY_H) && !defined(HAVE_LIBUTIL_H) */
+#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
+
+
+/* These are pulled from various places. It isn't obvious on what platforms
+   they are necessary, nor what the exact prototype should look like (which
+   is likely to vary between platforms!) If you find you need one of these
+   declarations, please move them to a platform-specific block and include
+   proper prototypes. */
+#if 0
+
+/* From Modules/resource.c */
+extern int getrusage();
+extern int getpagesize();
+
+/* From Python/sysmodule.c and Modules/posixmodule.c */
+extern int fclose(FILE *);
+
+/* From Modules/posixmodule.c */
+extern int fdatasync(int);
+#endif /* 0 */
+
+
+/************************
+ * WRAPPER FOR <math.h> *
+ ************************/
+
+#ifndef HAVE_HYPOT
+extern double hypot(double, double);
+#endif
+
+
+/* On 4.4BSD-descendants, ctype functions serves the whole range of
+ * wchar_t character set rather than single byte code points only.
+ * This characteristic can break some operations of string object
+ * including str.upper() and str.split() on UTF-8 locales.  This
+ * workaround was provided by Tim Robbins of FreeBSD project.
+ */
+
+#ifdef __FreeBSD__
+#include <osreldate.h>
+#if __FreeBSD_version > 500039
+#include <ctype.h>
+#include <wctype.h>
+#undef isalnum
+#define isalnum(c) iswalnum(btowc(c))
+#undef isalpha
+#define isalpha(c) iswalpha(btowc(c))
+#undef islower
+#define islower(c) iswlower(btowc(c))
+#undef isspace
+#define isspace(c) iswspace(btowc(c))
+#undef isupper
+#define isupper(c) iswupper(btowc(c))
+#undef tolower
+#define tolower(c) towlower(btowc(c))
+#undef toupper
+#define toupper(c) towupper(btowc(c))
+#endif
+#endif
+
+
+/* Declarations for symbol visibility.
+
+  PyAPI_FUNC(type): Declares a public Python API function and return type
+  PyAPI_DATA(type): Declares public Python data and its type
+  PyMODINIT_FUNC:   A Python module init function.  If these functions are
+                    inside the Python core, they are private to the core.
+                    If in an extension module, it may be declared with
+                    external linkage depending on the platform.
+
+  As a number of platforms support/require "__declspec(dllimport/dllexport)",
+  we support a HAVE_DECLSPEC_DLL macro to save duplication.
+*/
+
+/*
+  All windows ports, except cygwin, are handled in PC/pyconfig.h.
+
+  BeOS and cygwin are the only other autoconf platform requiring special
+  linkage handling and both of these use __declspec().
+*/
+#if defined(__CYGWIN__) || defined(__BEOS__)
+#	define HAVE_DECLSPEC_DLL
+#endif
+
+/* only get special linkage if built as shared or platform is Cygwin */
+#if defined(Py_ENABLE_SHARED) || defined(__CYGWIN__)
+#	if defined(HAVE_DECLSPEC_DLL)
+#		ifdef Py_BUILD_CORE
+#			define PyAPI_FUNC(RTYPE) __declspec(dllexport) RTYPE
+#			define PyAPI_DATA(RTYPE) extern __declspec(dllexport) RTYPE
+			/* module init functions inside the core need no external linkage */
+			/* except for Cygwin to handle embedding (FIXME: BeOS too?) */
+#			if defined(__CYGWIN__)
+#				define PyMODINIT_FUNC __declspec(dllexport) void
+#			else /* __CYGWIN__ */
+#				define PyMODINIT_FUNC void
+#			endif /* __CYGWIN__ */
+#		else /* Py_BUILD_CORE */
+			/* Building an extension module, or an embedded situation */
+			/* public Python functions and data are imported */
+			/* Under Cygwin, auto-import functions to prevent compilation */
+			/* failures similar to http://python.org/doc/FAQ.html#3.24 */
+#			if !defined(__CYGWIN__)
+#				define PyAPI_FUNC(RTYPE) __declspec(dllimport) RTYPE
+#			endif /* !__CYGWIN__ */
+#			define PyAPI_DATA(RTYPE) extern __declspec(dllimport) RTYPE
+			/* module init functions outside the core must be exported */
+#			if defined(__cplusplus)
+#				define PyMODINIT_FUNC extern "C" __declspec(dllexport) void
+#			else /* __cplusplus */
+#				define PyMODINIT_FUNC __declspec(dllexport) void
+#			endif /* __cplusplus */
+#		endif /* Py_BUILD_CORE */
+#	endif /* HAVE_DECLSPEC */
+#endif /* Py_ENABLE_SHARED */
+
+/* If no external linkage macros defined by now, create defaults */
+#ifndef PyAPI_FUNC
+#	define PyAPI_FUNC(RTYPE) RTYPE
+#endif
+#ifndef PyAPI_DATA
+#	define PyAPI_DATA(RTYPE) extern RTYPE
+#endif
+#ifndef PyMODINIT_FUNC
+#	if defined(__cplusplus)
+#		define PyMODINIT_FUNC extern "C" void
+#	else /* __cplusplus */
+#		define PyMODINIT_FUNC void
+#	endif /* __cplusplus */
+#endif
+
+/* Deprecated DL_IMPORT and DL_EXPORT macros */
+#if defined(Py_ENABLE_SHARED) && defined (HAVE_DECLSPEC_DLL)
+#	if defined(Py_BUILD_CORE)
+#		define DL_IMPORT(RTYPE) __declspec(dllexport) RTYPE
+#		define DL_EXPORT(RTYPE) __declspec(dllexport) RTYPE
+#	else
+#		define DL_IMPORT(RTYPE) __declspec(dllimport) RTYPE
+#		define DL_EXPORT(RTYPE) __declspec(dllexport) RTYPE
+#	endif
+#endif
+#ifndef DL_EXPORT
+#	define DL_EXPORT(RTYPE) RTYPE
+#endif
+#ifndef DL_IMPORT
+#	define DL_IMPORT(RTYPE) RTYPE
+#endif
+/* End of deprecated DL_* macros */
+
+/* If the fd manipulation macros aren't defined,
+   here is a set that should do the job */
+
+#if 0 /* disabled and probably obsolete */
+
+#ifndef	FD_SETSIZE
+#define	FD_SETSIZE	256
+#endif
+
+#ifndef FD_SET
+
+typedef long fd_mask;
+
+#define NFDBITS	(sizeof(fd_mask) * NBBY)	/* bits per mask */
+#ifndef howmany
+#define	howmany(x, y)	(((x)+((y)-1))/(y))
+#endif /* howmany */
+
+typedef	struct fd_set {
+	fd_mask	fds_bits[howmany(FD_SETSIZE, NFDBITS)];
+} fd_set;
+
+#define	FD_SET(n, p)	((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
+#define	FD_CLR(n, p)	((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
+#define	FD_ISSET(n, p)	((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
+#define FD_ZERO(p)	memset((char *)(p), '\0', sizeof(*(p)))
+
+#endif /* FD_SET */
+
+#endif /* fd manipulation macros */
+
+
+/* limits.h constants that may be missing */
+
+#ifndef INT_MAX
+#define INT_MAX 2147483647
+#endif
+
+#ifndef LONG_MAX
+#if SIZEOF_LONG == 4
+#define LONG_MAX 0X7FFFFFFFL
+#elif SIZEOF_LONG == 8
+#define LONG_MAX 0X7FFFFFFFFFFFFFFFL
+#else
+#error "could not set LONG_MAX in pyport.h"
+#endif
+#endif
+
+#ifndef LONG_MIN
+#define LONG_MIN (-LONG_MAX-1)
+#endif
+
+#ifndef LONG_BIT
+#define LONG_BIT (8 * SIZEOF_LONG)
+#endif
+
+#if LONG_BIT != 8 * SIZEOF_LONG
+/* 04-Oct-2000 LONG_BIT is apparently (mis)defined as 64 on some recent
+ * 32-bit platforms using gcc.  We try to catch that here at compile-time
+ * rather than waiting for integer multiplication to trigger bogus
+ * overflows.
+ */
+#error "LONG_BIT definition appears wrong for platform (bad gcc/glibc config?)."
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/*
+ * Hide GCC attributes from compilers that don't support them.
+ */
+#if (!defined(__GNUC__) || __GNUC__ < 2 || \
+     (__GNUC__ == 2 && __GNUC_MINOR__ < 7) ) && \
+    !defined(RISCOS)
+#define Py_GCC_ATTRIBUTE(x)
+#else
+#define Py_GCC_ATTRIBUTE(x) __attribute__(x)
+#endif
+
+/* Eliminate end-of-loop code not reached warnings from SunPro C
+ * when using do{...}while(0) macros
+ */
+#ifdef __SUNPRO_C
+#pragma error_messages (off,E_END_OF_LOOP_CODE_NOT_REACHED)
+#endif
+
+/*
+ * Older Microsoft compilers don't support the C99 long long literal suffixes,
+ * so these will be defined in PC/pyconfig.h for those compilers.
+ */
+#ifndef Py_LL
+#define Py_LL(x) x##LL
+#endif
+
+#ifndef Py_ULL
+#define Py_ULL(x) Py_LL(x##U)
+#endif
+
+#endif /* Py_PYPORT_H */

Added: vendor/Python/current/Include/pystate.h
===================================================================
--- vendor/Python/current/Include/pystate.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/pystate.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,195 @@
+
+/* Thread and interpreter state structures and their interfaces */
+
+
+#ifndef Py_PYSTATE_H
+#define Py_PYSTATE_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* State shared between threads */
+
+struct _ts; /* Forward */
+struct _is; /* Forward */
+
+typedef struct _is {
+
+    struct _is *next;
+    struct _ts *tstate_head;
+
+    PyObject *modules;
+    PyObject *sysdict;
+    PyObject *builtins;
+    PyObject *modules_reloading;
+
+    PyObject *codec_search_path;
+    PyObject *codec_search_cache;
+    PyObject *codec_error_registry;
+
+#ifdef HAVE_DLOPEN
+    int dlopenflags;
+#endif
+#ifdef WITH_TSC
+    int tscdump;
+#endif
+
+} PyInterpreterState;
+
+
+/* State unique per thread */
+
+struct _frame; /* Avoid including frameobject.h */
+
+/* Py_tracefunc return -1 when raising an exception, or 0 for success. */
+typedef int (*Py_tracefunc)(PyObject *, struct _frame *, int, PyObject *);
+
+/* The following values are used for 'what' for tracefunc functions: */
+#define PyTrace_CALL 0
+#define PyTrace_EXCEPTION 1
+#define PyTrace_LINE 2
+#define PyTrace_RETURN 3
+#define PyTrace_C_CALL 4
+#define PyTrace_C_EXCEPTION 5
+#define PyTrace_C_RETURN 6
+
+typedef struct _ts {
+    /* See Python/ceval.c for comments explaining most fields */
+
+    struct _ts *next;
+    PyInterpreterState *interp;
+
+    struct _frame *frame;
+    int recursion_depth;
+    /* 'tracing' keeps track of the execution depth when tracing/profiling.
+       This is to prevent the actual trace/profile code from being recorded in
+       the trace/profile. */
+    int tracing;
+    int use_tracing;
+
+    Py_tracefunc c_profilefunc;
+    Py_tracefunc c_tracefunc;
+    PyObject *c_profileobj;
+    PyObject *c_traceobj;
+
+    PyObject *curexc_type;
+    PyObject *curexc_value;
+    PyObject *curexc_traceback;
+
+    PyObject *exc_type;
+    PyObject *exc_value;
+    PyObject *exc_traceback;
+
+    PyObject *dict;  /* Stores per-thread state */
+
+    /* tick_counter is incremented whenever the check_interval ticker
+     * reaches zero. The purpose is to give a useful measure of the number
+     * of interpreted bytecode instructions in a given thread.  This
+     * extremely lightweight statistic collector may be of interest to
+     * profilers (like psyco.jit()), although nothing in the core uses it.
+     */
+    int tick_counter;
+
+    int gilstate_counter;
+
+    PyObject *async_exc; /* Asynchronous exception to raise */
+    long thread_id; /* Thread id where this tstate was created */
+
+    /* XXX signal handlers should also be here */
+
+} PyThreadState;
+
+
+PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_New(void);
+PyAPI_FUNC(void) PyInterpreterState_Clear(PyInterpreterState *);
+PyAPI_FUNC(void) PyInterpreterState_Delete(PyInterpreterState *);
+
+PyAPI_FUNC(PyThreadState *) PyThreadState_New(PyInterpreterState *);
+PyAPI_FUNC(void) PyThreadState_Clear(PyThreadState *);
+PyAPI_FUNC(void) PyThreadState_Delete(PyThreadState *);
+#ifdef WITH_THREAD
+PyAPI_FUNC(void) PyThreadState_DeleteCurrent(void);
+#endif
+
+PyAPI_FUNC(PyThreadState *) PyThreadState_Get(void);
+PyAPI_FUNC(PyThreadState *) PyThreadState_Swap(PyThreadState *);
+PyAPI_FUNC(PyObject *) PyThreadState_GetDict(void);
+PyAPI_FUNC(int) PyThreadState_SetAsyncExc(long, PyObject *);
+
+
+/* Variable and macro for in-line access to current thread state */
+
+PyAPI_DATA(PyThreadState *) _PyThreadState_Current;
+
+#ifdef Py_DEBUG
+#define PyThreadState_GET() PyThreadState_Get()
+#else
+#define PyThreadState_GET() (_PyThreadState_Current)
+#endif
+
+typedef
+    enum {PyGILState_LOCKED, PyGILState_UNLOCKED}
+        PyGILState_STATE;
+
+/* Ensure that the current thread is ready to call the Python
+   C API, regardless of the current state of Python, or of its
+   thread lock.  This may be called as many times as desired
+   by a thread so long as each call is matched with a call to
+   PyGILState_Release().  In general, other thread-state APIs may
+   be used between _Ensure() and _Release() calls, so long as the
+   thread-state is restored to its previous state before the Release().
+   For example, normal use of the Py_BEGIN_ALLOW_THREADS/
+   Py_END_ALLOW_THREADS macros are acceptable.
+
+   The return value is an opaque "handle" to the thread state when
+   PyGILState_Ensure() was called, and must be passed to
+   PyGILState_Release() to ensure Python is left in the same state. Even
+   though recursive calls are allowed, these handles can *not* be shared -
+   each unique call to PyGILState_Ensure must save the handle for its
+   call to PyGILState_Release.
+
+   When the function returns, the current thread will hold the GIL.
+
+   Failure is a fatal error.
+*/
+PyAPI_FUNC(PyGILState_STATE) PyGILState_Ensure(void);
+
+/* Release any resources previously acquired.  After this call, Python's
+   state will be the same as it was prior to the corresponding
+   PyGILState_Ensure() call (but generally this state will be unknown to
+   the caller, hence the use of the GILState API.)
+
+   Every call to PyGILState_Ensure must be matched by a call to
+   PyGILState_Release on the same thread.
+*/
+PyAPI_FUNC(void) PyGILState_Release(PyGILState_STATE);
+
+/* Helper/diagnostic function - get the current thread state for
+   this thread.  May return NULL if no GILState API has been used
+   on the current thread.  Note the main thread always has such a
+   thread-state, even if no auto-thread-state call has been made
+   on the main thread.
+*/
+PyAPI_FUNC(PyThreadState *) PyGILState_GetThisThreadState(void);
+
+/* The implementation of sys._current_frames()  Returns a dict mapping
+   thread id to that thread's current frame.
+*/
+PyAPI_FUNC(PyObject *) _PyThread_CurrentFrames(void);
+
+/* Routines for advanced debuggers, requested by David Beazley.
+   Don't use unless you know what you are doing! */
+PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Head(void);
+PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Next(PyInterpreterState *);
+PyAPI_FUNC(PyThreadState *) PyInterpreterState_ThreadHead(PyInterpreterState *);
+PyAPI_FUNC(PyThreadState *) PyThreadState_Next(PyThreadState *);
+
+typedef struct _frame *(*PyThreadFrameGetter)(PyThreadState *self_);
+
+/* hook for PyEval_GetFrame(), requested for Psyco */
+PyAPI_DATA(PyThreadFrameGetter) _PyThreadState_GetFrame;
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_PYSTATE_H */

Added: vendor/Python/current/Include/pystrtod.h
===================================================================
--- vendor/Python/current/Include/pystrtod.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/pystrtod.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,18 @@
+#ifndef Py_STRTOD_H
+#define Py_STRTOD_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+PyAPI_FUNC(double) PyOS_ascii_strtod(const char *str, char **ptr);
+PyAPI_FUNC(double) PyOS_ascii_atof(const char *str);
+PyAPI_FUNC(char *) PyOS_ascii_formatd(char *buffer, size_t buf_len,  const char *format, double d);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !Py_STRTOD_H */

Added: vendor/Python/current/Include/pythonrun.h
===================================================================
--- vendor/Python/current/Include/pythonrun.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/pythonrun.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,171 @@
+
+/* Interfaces to parse and execute pieces of python code */
+
+#ifndef Py_PYTHONRUN_H
+#define Py_PYTHONRUN_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define PyCF_MASK (CO_FUTURE_DIVISION | CO_FUTURE_ABSOLUTE_IMPORT | \
+                   CO_FUTURE_WITH_STATEMENT)
+#define PyCF_MASK_OBSOLETE (CO_NESTED)
+#define PyCF_SOURCE_IS_UTF8  0x0100
+#define PyCF_DONT_IMPLY_DEDENT 0x0200
+#define PyCF_ONLY_AST 0x0400
+
+typedef struct {
+	int cf_flags;  /* bitmask of CO_xxx flags relevant to future */
+} PyCompilerFlags;
+
+PyAPI_FUNC(void) Py_SetProgramName(char *);
+PyAPI_FUNC(char *) Py_GetProgramName(void);
+
+PyAPI_FUNC(void) Py_SetPythonHome(char *);
+PyAPI_FUNC(char *) Py_GetPythonHome(void);
+
+PyAPI_FUNC(void) Py_Initialize(void);
+PyAPI_FUNC(void) Py_InitializeEx(int);
+PyAPI_FUNC(void) Py_Finalize(void);
+PyAPI_FUNC(int) Py_IsInitialized(void);
+PyAPI_FUNC(PyThreadState *) Py_NewInterpreter(void);
+PyAPI_FUNC(void) Py_EndInterpreter(PyThreadState *);
+
+PyAPI_FUNC(int) PyRun_AnyFileFlags(FILE *, const char *, PyCompilerFlags *);
+PyAPI_FUNC(int) PyRun_AnyFileExFlags(FILE *, const char *, int, PyCompilerFlags *);
+PyAPI_FUNC(int) PyRun_SimpleStringFlags(const char *, PyCompilerFlags *);
+PyAPI_FUNC(int) PyRun_SimpleFileExFlags(FILE *, const char *, int, PyCompilerFlags *);
+PyAPI_FUNC(int) PyRun_InteractiveOneFlags(FILE *, const char *, PyCompilerFlags *);
+PyAPI_FUNC(int) PyRun_InteractiveLoopFlags(FILE *, const char *, PyCompilerFlags *);
+
+PyAPI_FUNC(struct _mod *) PyParser_ASTFromString(const char *, const char *, 
+						 int, PyCompilerFlags *flags,
+                                                 PyArena *);
+PyAPI_FUNC(struct _mod *) PyParser_ASTFromFile(FILE *, const char *, int, 
+					       char *, char *,
+                                               PyCompilerFlags *, int *,
+                                               PyArena *);
+#define PyParser_SimpleParseString(S, B) \
+        PyParser_SimpleParseStringFlags(S, B, 0)
+#define PyParser_SimpleParseFile(FP, S, B) \
+        PyParser_SimpleParseFileFlags(FP, S, B, 0)
+PyAPI_FUNC(struct _node *) PyParser_SimpleParseStringFlags(const char *, int, 
+							  int);
+PyAPI_FUNC(struct _node *) PyParser_SimpleParseFileFlags(FILE *, const char *,
+							int, int);
+
+PyAPI_FUNC(PyObject *) PyRun_StringFlags(const char *, int, PyObject *, 
+					 PyObject *, PyCompilerFlags *);
+
+PyAPI_FUNC(PyObject *) PyRun_FileExFlags(FILE *, const char *, int, 
+					 PyObject *, PyObject *, int, 
+					 PyCompilerFlags *);
+
+#define Py_CompileString(str, p, s) Py_CompileStringFlags(str, p, s, NULL)
+PyAPI_FUNC(PyObject *) Py_CompileStringFlags(const char *, const char *, int,
+					     PyCompilerFlags *);
+PyAPI_FUNC(struct symtable *) Py_SymtableString(const char *, const char *, int);
+
+PyAPI_FUNC(void) PyErr_Print(void);
+PyAPI_FUNC(void) PyErr_PrintEx(int);
+PyAPI_FUNC(void) PyErr_Display(PyObject *, PyObject *, PyObject *);
+
+PyAPI_FUNC(int) Py_AtExit(void (*func)(void));
+
+PyAPI_FUNC(void) Py_Exit(int);
+
+PyAPI_FUNC(int) Py_FdIsInteractive(FILE *, const char *);
+
+/* Bootstrap */
+PyAPI_FUNC(int) Py_Main(int argc, char **argv);
+
+/* Use macros for a bunch of old variants */
+#define PyRun_String(str, s, g, l) PyRun_StringFlags(str, s, g, l, NULL)
+#define PyRun_AnyFile(fp, name) PyRun_AnyFileExFlags(fp, name, 0, NULL)
+#define PyRun_AnyFileEx(fp, name, closeit) \
+	PyRun_AnyFileExFlags(fp, name, closeit, NULL)
+#define PyRun_AnyFileFlags(fp, name, flags) \
+	PyRun_AnyFileExFlags(fp, name, 0, flags)
+#define PyRun_SimpleString(s) PyRun_SimpleStringFlags(s, NULL)
+#define PyRun_SimpleFile(f, p) PyRun_SimpleFileExFlags(f, p, 0, NULL)
+#define PyRun_SimpleFileEx(f, p, c) PyRun_SimpleFileExFlags(f, p, c, NULL)
+#define PyRun_InteractiveOne(f, p) PyRun_InteractiveOneFlags(f, p, NULL)
+#define PyRun_InteractiveLoop(f, p) PyRun_InteractiveLoopFlags(f, p, NULL)
+#define PyRun_File(fp, p, s, g, l) \
+        PyRun_FileExFlags(fp, p, s, g, l, 0, NULL)
+#define PyRun_FileEx(fp, p, s, g, l, c) \
+        PyRun_FileExFlags(fp, p, s, g, l, c, NULL)
+#define PyRun_FileFlags(fp, p, s, g, l, flags) \
+        PyRun_FileExFlags(fp, p, s, g, l, 0, flags)
+
+/* In getpath.c */
+PyAPI_FUNC(char *) Py_GetProgramFullPath(void);
+PyAPI_FUNC(char *) Py_GetPrefix(void);
+PyAPI_FUNC(char *) Py_GetExecPrefix(void);
+PyAPI_FUNC(char *) Py_GetPath(void);
+
+/* In their own files */
+PyAPI_FUNC(const char *) Py_GetVersion(void);
+PyAPI_FUNC(const char *) Py_GetPlatform(void);
+PyAPI_FUNC(const char *) Py_GetCopyright(void);
+PyAPI_FUNC(const char *) Py_GetCompiler(void);
+PyAPI_FUNC(const char *) Py_GetBuildInfo(void);
+PyAPI_FUNC(const char *) _Py_svnversion(void);
+PyAPI_FUNC(const char *) Py_SubversionRevision(void);
+PyAPI_FUNC(const char *) Py_SubversionShortBranch(void);
+
+/* Internal -- various one-time initializations */
+PyAPI_FUNC(PyObject *) _PyBuiltin_Init(void);
+PyAPI_FUNC(PyObject *) _PySys_Init(void);
+PyAPI_FUNC(void) _PyImport_Init(void);
+PyAPI_FUNC(void) _PyExc_Init(void);
+PyAPI_FUNC(void) _PyImportHooks_Init(void);
+PyAPI_FUNC(int) _PyFrame_Init(void);
+PyAPI_FUNC(int) _PyInt_Init(void);
+PyAPI_FUNC(void) _PyFloat_Init(void);
+
+/* Various internal finalizers */
+PyAPI_FUNC(void) _PyExc_Fini(void);
+PyAPI_FUNC(void) _PyImport_Fini(void);
+PyAPI_FUNC(void) PyMethod_Fini(void);
+PyAPI_FUNC(void) PyFrame_Fini(void);
+PyAPI_FUNC(void) PyCFunction_Fini(void);
+PyAPI_FUNC(void) PyTuple_Fini(void);
+PyAPI_FUNC(void) PyList_Fini(void);
+PyAPI_FUNC(void) PySet_Fini(void);
+PyAPI_FUNC(void) PyString_Fini(void);
+PyAPI_FUNC(void) PyInt_Fini(void);
+PyAPI_FUNC(void) PyFloat_Fini(void);
+PyAPI_FUNC(void) PyOS_FiniInterrupts(void);
+
+/* Stuff with no proper home (yet) */
+PyAPI_FUNC(char *) PyOS_Readline(FILE *, FILE *, char *);
+PyAPI_DATA(int) (*PyOS_InputHook)(void);
+PyAPI_DATA(char) *(*PyOS_ReadlineFunctionPointer)(FILE *, FILE *, char *);
+PyAPI_DATA(PyThreadState*) _PyOS_ReadlineTState;
+
+/* Stack size, in "pointers" (so we get extra safety margins
+   on 64-bit platforms).  On a 32-bit platform, this translates
+   to a 8k margin. */
+#define PYOS_STACK_MARGIN 2048
+
+#if defined(WIN32) && !defined(MS_WIN64) && defined(_MSC_VER)
+/* Enable stack checking under Microsoft C */
+#define USE_STACKCHECK
+#endif
+
+#ifdef USE_STACKCHECK
+/* Check that we aren't overflowing our stack */
+PyAPI_FUNC(int) PyOS_CheckStack(void);
+#endif
+
+/* Signals */
+typedef void (*PyOS_sighandler_t)(int);
+PyAPI_FUNC(PyOS_sighandler_t) PyOS_getsig(int);
+PyAPI_FUNC(PyOS_sighandler_t) PyOS_setsig(int, PyOS_sighandler_t);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_PYTHONRUN_H */

Added: vendor/Python/current/Include/pythread.h
===================================================================
--- vendor/Python/current/Include/pythread.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/pythread.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,47 @@
+
+#ifndef Py_PYTHREAD_H
+#define Py_PYTHREAD_H
+
+#define NO_EXIT_PROG		/* don't define PyThread_exit_prog() */
+				/* (the result is no use of signals on SGI) */
+
+typedef void *PyThread_type_lock;
+typedef void *PyThread_type_sema;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+PyAPI_FUNC(void) PyThread_init_thread(void);
+PyAPI_FUNC(long) PyThread_start_new_thread(void (*)(void *), void *);
+PyAPI_FUNC(void) PyThread_exit_thread(void);
+PyAPI_FUNC(void) PyThread__PyThread_exit_thread(void);
+PyAPI_FUNC(long) PyThread_get_thread_ident(void);
+
+PyAPI_FUNC(PyThread_type_lock) PyThread_allocate_lock(void);
+PyAPI_FUNC(void) PyThread_free_lock(PyThread_type_lock);
+PyAPI_FUNC(int) PyThread_acquire_lock(PyThread_type_lock, int);
+#define WAIT_LOCK	1
+#define NOWAIT_LOCK	0
+PyAPI_FUNC(void) PyThread_release_lock(PyThread_type_lock);
+
+PyAPI_FUNC(size_t) PyThread_get_stacksize(void);
+PyAPI_FUNC(int) PyThread_set_stacksize(size_t);
+
+#ifndef NO_EXIT_PROG
+PyAPI_FUNC(void) PyThread_exit_prog(int);
+PyAPI_FUNC(void) PyThread__PyThread_exit_prog(int);
+#endif
+
+/* Thread Local Storage (TLS) API */
+PyAPI_FUNC(int) PyThread_create_key(void);
+PyAPI_FUNC(void) PyThread_delete_key(int);
+PyAPI_FUNC(int) PyThread_set_key_value(int, void *);
+PyAPI_FUNC(void *) PyThread_get_key_value(int);
+PyAPI_FUNC(void) PyThread_delete_key_value(int key);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !Py_PYTHREAD_H */

Added: vendor/Python/current/Include/rangeobject.h
===================================================================
--- vendor/Python/current/Include/rangeobject.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/rangeobject.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,28 @@
+
+/* Range object interface */
+
+#ifndef Py_RANGEOBJECT_H
+#define Py_RANGEOBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* This is about the type 'xrange', not the built-in function range(), which
+   returns regular lists. */
+
+/*
+A range object represents an integer range.  This is an immutable object;
+a range cannot change its value after creation.
+
+Range objects behave like the corresponding tuple objects except that
+they are represented by a start, stop, and step datamembers.
+*/
+
+PyAPI_DATA(PyTypeObject) PyRange_Type;
+
+#define PyRange_Check(op) ((op)->ob_type == &PyRange_Type)
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_RANGEOBJECT_H */

Added: vendor/Python/current/Include/setobject.h
===================================================================
--- vendor/Python/current/Include/setobject.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/setobject.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,93 @@
+/* Set object interface */
+
+#ifndef Py_SETOBJECT_H
+#define Py_SETOBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*
+There are three kinds of slots in the table:
+
+1. Unused:  key == NULL
+2. Active:  key != NULL and key != dummy
+3. Dummy:   key == dummy
+
+Note: .pop() abuses the hash field of an Unused or Dummy slot to
+hold a search finger.  The hash field of Unused or Dummy slots has
+no meaning otherwise.
+*/
+
+#define PySet_MINSIZE 8
+
+typedef struct {
+	long hash;      /* cached hash code for the entry key */
+	PyObject *key;
+} setentry;
+
+
+/*
+This data structure is shared by set and frozenset objects.
+*/
+
+typedef struct _setobject PySetObject;
+struct _setobject {
+	PyObject_HEAD
+
+	Py_ssize_t fill;  /* # Active + # Dummy */
+	Py_ssize_t used;  /* # Active */
+
+	/* The table contains mask + 1 slots, and that's a power of 2.
+	 * We store the mask instead of the size because the mask is more
+	 * frequently needed.
+	 */
+	Py_ssize_t mask;
+
+	/* table points to smalltable for small tables, else to
+	 * additional malloc'ed memory.  table is never NULL!  This rule
+	 * saves repeated runtime null-tests.
+	 */
+	setentry *table;
+	setentry *(*lookup)(PySetObject *so, PyObject *key, long hash);
+	setentry smalltable[PySet_MINSIZE];
+
+	long hash;		/* only used by frozenset objects */
+	PyObject *weakreflist;	/* List of weak references */
+};
+
+PyAPI_DATA(PyTypeObject) PySet_Type;
+PyAPI_DATA(PyTypeObject) PyFrozenSet_Type;
+
+/* Invariants for frozensets:
+ *     data is immutable.
+ *     hash is the hash of the frozenset or -1 if not computed yet.
+ * Invariants for sets:
+ *     hash is -1
+ */
+
+#define PyFrozenSet_CheckExact(ob) ((ob)->ob_type == &PyFrozenSet_Type)
+#define PyAnySet_CheckExact(ob) \
+	((ob)->ob_type == &PySet_Type || (ob)->ob_type == &PyFrozenSet_Type)
+#define PyAnySet_Check(ob) \
+	((ob)->ob_type == &PySet_Type || (ob)->ob_type == &PyFrozenSet_Type || \
+	  PyType_IsSubtype((ob)->ob_type, &PySet_Type) || \
+	  PyType_IsSubtype((ob)->ob_type, &PyFrozenSet_Type))
+
+PyAPI_FUNC(PyObject *) PySet_New(PyObject *);
+PyAPI_FUNC(PyObject *) PyFrozenSet_New(PyObject *);
+PyAPI_FUNC(Py_ssize_t) PySet_Size(PyObject *anyset);
+#define PySet_GET_SIZE(so) (((PySetObject *)(so))->used)
+PyAPI_FUNC(int) PySet_Clear(PyObject *set);
+PyAPI_FUNC(int) PySet_Contains(PyObject *anyset, PyObject *key);
+PyAPI_FUNC(int) PySet_Discard(PyObject *set, PyObject *key);
+PyAPI_FUNC(int) PySet_Add(PyObject *set, PyObject *key);
+PyAPI_FUNC(int) _PySet_Next(PyObject *set, Py_ssize_t *pos, PyObject **key);
+PyAPI_FUNC(int) _PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, long *hash);
+PyAPI_FUNC(PyObject *) PySet_Pop(PyObject *set);
+PyAPI_FUNC(int) _PySet_Update(PyObject *set, PyObject *iterable);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_SETOBJECT_H */

Added: vendor/Python/current/Include/sliceobject.h
===================================================================
--- vendor/Python/current/Include/sliceobject.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/sliceobject.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,43 @@
+#ifndef Py_SLICEOBJECT_H
+#define Py_SLICEOBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* The unique ellipsis object "..." */
+
+PyAPI_DATA(PyObject) _Py_EllipsisObject; /* Don't use this directly */
+
+#define Py_Ellipsis (&_Py_EllipsisObject)
+
+/* Slice object interface */
+
+/*
+
+A slice object containing start, stop, and step data members (the
+names are from range).  After much talk with Guido, it was decided to
+let these be any arbitrary python type.  Py_None stands for omitted values.
+*/
+
+typedef struct {
+    PyObject_HEAD
+    PyObject *start, *stop, *step;	/* not NULL */
+} PySliceObject;
+
+PyAPI_DATA(PyTypeObject) PySlice_Type;
+
+#define PySlice_Check(op) ((op)->ob_type == &PySlice_Type)
+
+PyAPI_FUNC(PyObject *) PySlice_New(PyObject* start, PyObject* stop,
+                                  PyObject* step);
+PyAPI_FUNC(PyObject *) _PySlice_FromIndices(Py_ssize_t start, Py_ssize_t stop);
+PyAPI_FUNC(int) PySlice_GetIndices(PySliceObject *r, Py_ssize_t length,
+                                  Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step);
+PyAPI_FUNC(int) PySlice_GetIndicesEx(PySliceObject *r, Py_ssize_t length,
+				    Py_ssize_t *start, Py_ssize_t *stop, 
+				    Py_ssize_t *step, Py_ssize_t *slicelength);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_SLICEOBJECT_H */

Added: vendor/Python/current/Include/stringobject.h
===================================================================
--- vendor/Python/current/Include/stringobject.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/stringobject.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,183 @@
+
+/* String object interface */
+
+#ifndef Py_STRINGOBJECT_H
+#define Py_STRINGOBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdarg.h>
+
+/*
+Type PyStringObject represents a character string.  An extra zero byte is
+reserved at the end to ensure it is zero-terminated, but a size is
+present so strings with null bytes in them can be represented.  This
+is an immutable object type.
+
+There are functions to create new string objects, to test
+an object for string-ness, and to get the
+string value.  The latter function returns a null pointer
+if the object is not of the proper type.
+There is a variant that takes an explicit size as well as a
+variant that assumes a zero-terminated string.  Note that none of the
+functions should be applied to nil objects.
+*/
+
+/* Caching the hash (ob_shash) saves recalculation of a string's hash value.
+   Interning strings (ob_sstate) tries to ensure that only one string
+   object with a given value exists, so equality tests can be one pointer
+   comparison.  This is generally restricted to strings that "look like"
+   Python identifiers, although the intern() builtin can be used to force
+   interning of any string.
+   Together, these sped the interpreter by up to 20%. */
+
+typedef struct {
+    PyObject_VAR_HEAD
+    long ob_shash;
+    int ob_sstate;
+    char ob_sval[1];
+
+    /* Invariants:
+     *     ob_sval contains space for 'ob_size+1' elements.
+     *     ob_sval[ob_size] == 0.
+     *     ob_shash is the hash of the string or -1 if not computed yet.
+     *     ob_sstate != 0 iff the string object is in stringobject.c's
+     *       'interned' dictionary; in this case the two references
+     *       from 'interned' to this object are *not counted* in ob_refcnt.
+     */
+} PyStringObject;
+
+#define SSTATE_NOT_INTERNED 0
+#define SSTATE_INTERNED_MORTAL 1
+#define SSTATE_INTERNED_IMMORTAL 2
+
+PyAPI_DATA(PyTypeObject) PyBaseString_Type;
+PyAPI_DATA(PyTypeObject) PyString_Type;
+
+#define PyString_Check(op) PyObject_TypeCheck(op, &PyString_Type)
+#define PyString_CheckExact(op) ((op)->ob_type == &PyString_Type)
+
+PyAPI_FUNC(PyObject *) PyString_FromStringAndSize(const char *, Py_ssize_t);
+PyAPI_FUNC(PyObject *) PyString_FromString(const char *);
+PyAPI_FUNC(PyObject *) PyString_FromFormatV(const char*, va_list)
+				Py_GCC_ATTRIBUTE((format(printf, 1, 0)));
+PyAPI_FUNC(PyObject *) PyString_FromFormat(const char*, ...)
+				Py_GCC_ATTRIBUTE((format(printf, 1, 2)));
+PyAPI_FUNC(Py_ssize_t) PyString_Size(PyObject *);
+PyAPI_FUNC(char *) PyString_AsString(PyObject *);
+PyAPI_FUNC(PyObject *) PyString_Repr(PyObject *, int);
+PyAPI_FUNC(void) PyString_Concat(PyObject **, PyObject *);
+PyAPI_FUNC(void) PyString_ConcatAndDel(PyObject **, PyObject *);
+PyAPI_FUNC(int) _PyString_Resize(PyObject **, Py_ssize_t);
+PyAPI_FUNC(int) _PyString_Eq(PyObject *, PyObject*);
+PyAPI_FUNC(PyObject *) PyString_Format(PyObject *, PyObject *);
+PyAPI_FUNC(PyObject *) _PyString_FormatLong(PyObject*, int, int,
+						  int, char**, int*);
+PyAPI_FUNC(PyObject *) PyString_DecodeEscape(const char *, Py_ssize_t, 
+						   const char *, Py_ssize_t,
+						   const char *);
+
+PyAPI_FUNC(void) PyString_InternInPlace(PyObject **);
+PyAPI_FUNC(void) PyString_InternImmortal(PyObject **);
+PyAPI_FUNC(PyObject *) PyString_InternFromString(const char *);
+PyAPI_FUNC(void) _Py_ReleaseInternedStrings(void);
+
+/* Use only if you know it's a string */
+#define PyString_CHECK_INTERNED(op) (((PyStringObject *)(op))->ob_sstate)
+
+/* Macro, trading safety for speed */
+#define PyString_AS_STRING(op) (((PyStringObject *)(op))->ob_sval)
+#define PyString_GET_SIZE(op)  (((PyStringObject *)(op))->ob_size)
+
+/* _PyString_Join(sep, x) is like sep.join(x).  sep must be PyStringObject*,
+   x must be an iterable object. */
+PyAPI_FUNC(PyObject *) _PyString_Join(PyObject *sep, PyObject *x);
+
+/* --- Generic Codecs ----------------------------------------------------- */
+
+/* Create an object by decoding the encoded string s of the
+   given size. */
+
+PyAPI_FUNC(PyObject*) PyString_Decode(
+    const char *s,              /* encoded string */
+    Py_ssize_t size,            /* size of buffer */
+    const char *encoding,       /* encoding */
+    const char *errors          /* error handling */
+    );
+
+/* Encodes a char buffer of the given size and returns a 
+   Python object. */
+
+PyAPI_FUNC(PyObject*) PyString_Encode(
+    const char *s,              /* string char buffer */
+    Py_ssize_t size,            /* number of chars to encode */
+    const char *encoding,       /* encoding */
+    const char *errors          /* error handling */
+    );
+
+/* Encodes a string object and returns the result as Python 
+   object. */
+
+PyAPI_FUNC(PyObject*) PyString_AsEncodedObject(
+    PyObject *str,	 	/* string object */
+    const char *encoding,	/* encoding */
+    const char *errors		/* error handling */
+    );
+
+/* Encodes a string object and returns the result as Python string
+   object.   
+   
+   If the codec returns an Unicode object, the object is converted
+   back to a string using the default encoding.
+
+   DEPRECATED - use PyString_AsEncodedObject() instead. */
+
+PyAPI_FUNC(PyObject*) PyString_AsEncodedString(
+    PyObject *str,	 	/* string object */
+    const char *encoding,	/* encoding */
+    const char *errors		/* error handling */
+    );
+
+/* Decodes a string object and returns the result as Python 
+   object. */
+
+PyAPI_FUNC(PyObject*) PyString_AsDecodedObject(
+    PyObject *str,	 	/* string object */
+    const char *encoding,	/* encoding */
+    const char *errors		/* error handling */
+    );
+
+/* Decodes a string object and returns the result as Python string
+   object.  
+   
+   If the codec returns an Unicode object, the object is converted
+   back to a string using the default encoding.
+
+   DEPRECATED - use PyString_AsDecodedObject() instead. */
+
+PyAPI_FUNC(PyObject*) PyString_AsDecodedString(
+    PyObject *str,	 	/* string object */
+    const char *encoding,	/* encoding */
+    const char *errors		/* error handling */
+    );
+
+/* Provides access to the internal data buffer and size of a string
+   object or the default encoded version of an Unicode object. Passing
+   NULL as *len parameter will force the string buffer to be
+   0-terminated (passing a string with embedded NULL characters will
+   cause an exception).  */
+
+PyAPI_FUNC(int) PyString_AsStringAndSize(
+    register PyObject *obj,	/* string or Unicode object */
+    register char **s,		/* pointer to buffer variable */
+    register Py_ssize_t *len	/* pointer to length variable or NULL
+				   (only possible for 0-terminated
+				   strings) */
+    );
+    
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_STRINGOBJECT_H */

Added: vendor/Python/current/Include/structmember.h
===================================================================
--- vendor/Python/current/Include/structmember.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/structmember.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,93 @@
+#ifndef Py_STRUCTMEMBER_H
+#define Py_STRUCTMEMBER_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Interface to map C struct members to Python object attributes */
+
+#include <stddef.h> /* For offsetof */
+
+/* The offsetof() macro calculates the offset of a structure member
+   in its structure.  Unfortunately this cannot be written down
+   portably, hence it is provided by a Standard C header file.
+   For pre-Standard C compilers, here is a version that usually works
+   (but watch out!): */
+
+#ifndef offsetof
+#define offsetof(type, member) ( (int) & ((type*)0) -> member )
+#endif
+
+/* An array of memberlist structures defines the name, type and offset
+   of selected members of a C structure.  These can be read by
+   PyMember_Get() and set by PyMember_Set() (except if their READONLY flag
+   is set).  The array must be terminated with an entry whose name
+   pointer is NULL. */
+
+struct memberlist {
+	/* Obsolete version, for binary backwards compatibility */
+	char *name;
+	int type;
+	int offset;
+	int flags;
+};
+
+typedef struct PyMemberDef {
+	/* Current version, use this */
+	char *name;
+	int type;
+	Py_ssize_t offset;
+	int flags;
+	char *doc;
+} PyMemberDef;
+
+/* Types */
+#define T_SHORT		0
+#define T_INT		1
+#define T_LONG		2
+#define T_FLOAT		3
+#define T_DOUBLE	4
+#define T_STRING	5
+#define T_OBJECT	6
+/* XXX the ordering here is weird for binary compatibility */
+#define T_CHAR		7	/* 1-character string */
+#define T_BYTE		8	/* 8-bit signed int */
+/* unsigned variants: */
+#define T_UBYTE		9
+#define T_USHORT	10
+#define T_UINT		11
+#define T_ULONG		12
+
+/* Added by Jack: strings contained in the structure */
+#define T_STRING_INPLACE	13
+
+#define T_OBJECT_EX	16	/* Like T_OBJECT, but raises AttributeError
+				   when the value is NULL, instead of
+				   converting to None. */
+#ifdef HAVE_LONG_LONG
+#define T_LONGLONG      17  
+#define T_ULONGLONG      18
+#endif /* HAVE_LONG_LONG */
+
+/* Flags */
+#define READONLY	1
+#define RO		READONLY		/* Shorthand */
+#define READ_RESTRICTED	2
+#define WRITE_RESTRICTED 4
+#define RESTRICTED	(READ_RESTRICTED | WRITE_RESTRICTED)
+
+
+/* Obsolete API, for binary backwards compatibility */
+PyAPI_FUNC(PyObject *) PyMember_Get(const char *, struct memberlist *, const char *);
+PyAPI_FUNC(int) PyMember_Set(char *, struct memberlist *, const char *, PyObject *);
+
+/* Current API, use this */
+PyAPI_FUNC(PyObject *) PyMember_GetOne(const char *, struct PyMemberDef *);
+PyAPI_FUNC(int) PyMember_SetOne(char *, struct PyMemberDef *, PyObject *);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_STRUCTMEMBER_H */

Added: vendor/Python/current/Include/structseq.h
===================================================================
--- vendor/Python/current/Include/structseq.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/structseq.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,41 @@
+
+/* Tuple object interface */
+
+#ifndef Py_STRUCTSEQ_H
+#define Py_STRUCTSEQ_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct PyStructSequence_Field {
+	char *name;
+	char *doc;
+} PyStructSequence_Field;
+
+typedef struct PyStructSequence_Desc {
+	char *name;
+	char *doc;
+	struct PyStructSequence_Field *fields;
+	int n_in_sequence;
+} PyStructSequence_Desc;
+
+extern char* PyStructSequence_UnnamedField;
+
+PyAPI_FUNC(void) PyStructSequence_InitType(PyTypeObject *type,
+					   PyStructSequence_Desc *desc);
+
+PyAPI_FUNC(PyObject *) PyStructSequence_New(PyTypeObject* type);
+
+typedef struct {
+	PyObject_VAR_HEAD
+	PyObject *ob_item[1];
+} PyStructSequence;
+
+/* Macro, *only* to be used to fill in brand new objects */
+#define PyStructSequence_SET_ITEM(op, i, v) \
+	(((PyStructSequence *)(op))->ob_item[i] = v)
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_STRUCTSEQ_H */

Added: vendor/Python/current/Include/symtable.h
===================================================================
--- vendor/Python/current/Include/symtable.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/symtable.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,103 @@
+#ifndef Py_SYMTABLE_H
+#define Py_SYMTABLE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum _block_type { FunctionBlock, ClassBlock, ModuleBlock }
+    _Py_block_ty;
+
+struct _symtable_entry;
+
+struct symtable {
+	const char *st_filename; /* name of file being compiled */
+	struct _symtable_entry *st_cur; /* current symbol table entry */
+	struct _symtable_entry *st_top; /* module entry */
+	PyObject *st_symbols;    /* dictionary of symbol table entries */
+        PyObject *st_stack;      /* stack of namespace info */
+	PyObject *st_global;     /* borrowed ref to MODULE in st_symbols */
+	int st_nblocks;          /* number of blocks */
+	PyObject *st_private;        /* name of current class or NULL */
+        int st_tmpname;          /* temporary name counter */
+	PyFutureFeatures *st_future; /* module's future features */
+};
+
+typedef struct _symtable_entry {
+	PyObject_HEAD
+	PyObject *ste_id;        /* int: key in st_symbols */
+	PyObject *ste_symbols;   /* dict: name to flags */
+	PyObject *ste_name;      /* string: name of block */
+	PyObject *ste_varnames;  /* list of variable names */
+	PyObject *ste_children;  /* list of child ids */
+	_Py_block_ty ste_type;   /* module, class, or function */
+	int ste_unoptimized;     /* false if namespace is optimized */
+	unsigned ste_nested : 1;      /* true if block is nested */
+	unsigned ste_free : 1;        /* true if block has free variables */
+	unsigned ste_child_free : 1;  /* true if a child block has free vars,
+				         including free refs to globals */
+	unsigned ste_generator : 1;   /* true if namespace is a generator */
+	unsigned ste_varargs : 1;     /* true if block has varargs */
+	unsigned ste_varkeywords : 1; /* true if block has varkeywords */
+	unsigned ste_returns_value : 1;  /* true if namespace uses return with
+	                                    an argument */
+	int ste_lineno;          /* first line of block */
+	int ste_opt_lineno;      /* lineno of last exec or import * */
+	int ste_tmpname;         /* counter for listcomp temp vars */
+	struct symtable *ste_table;
+} PySTEntryObject;
+
+PyAPI_DATA(PyTypeObject) PySTEntry_Type;
+
+#define PySTEntry_Check(op) ((op)->ob_type == &PySTEntry_Type)
+
+PyAPI_FUNC(int) PyST_GetScope(PySTEntryObject *, PyObject *);
+
+PyAPI_FUNC(struct symtable *) PySymtable_Build(mod_ty, const char *, 
+					      PyFutureFeatures *);
+PyAPI_FUNC(PySTEntryObject *) PySymtable_Lookup(struct symtable *, void *);
+
+PyAPI_FUNC(void) PySymtable_Free(struct symtable *);
+
+/* Flags for def-use information */
+
+#define DEF_GLOBAL 1           /* global stmt */
+#define DEF_LOCAL 2            /* assignment in code block */
+#define DEF_PARAM 2<<1         /* formal parameter */
+#define USE 2<<2               /* name is used */
+#define DEF_STAR 2<<3          /* parameter is star arg */
+#define DEF_DOUBLESTAR 2<<4    /* parameter is star-star arg */
+#define DEF_INTUPLE 2<<5       /* name defined in tuple in parameters */
+#define DEF_FREE 2<<6          /* name used but not defined in nested block */
+#define DEF_FREE_GLOBAL 2<<7   /* free variable is actually implicit global */
+#define DEF_FREE_CLASS 2<<8    /* free variable from class's method */
+#define DEF_IMPORT 2<<9        /* assignment occurred via import */
+
+#define DEF_BOUND (DEF_LOCAL | DEF_PARAM | DEF_IMPORT)
+
+/* GLOBAL_EXPLICIT and GLOBAL_IMPLICIT are used internally by the symbol
+   table.  GLOBAL is returned from PyST_GetScope() for either of them. 
+   It is stored in ste_symbols at bits 12-14.
+*/
+#define SCOPE_OFF 11
+#define SCOPE_MASK 7
+
+#define LOCAL 1
+#define GLOBAL_EXPLICIT 2
+#define GLOBAL_IMPLICIT 3
+#define FREE 4
+#define CELL 5
+
+/* The following three names are used for the ste_unoptimized bit field */
+#define OPT_IMPORT_STAR 1
+#define OPT_EXEC 2
+#define OPT_BARE_EXEC 4
+#define OPT_TOPLEVEL 8  /* top-level names, including eval and exec */
+
+#define GENERATOR 1
+#define GENERATOR_EXPRESSION 2
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_SYMTABLE_H */

Added: vendor/Python/current/Include/sysmodule.h
===================================================================
--- vendor/Python/current/Include/sysmodule.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/sysmodule.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,30 @@
+
+/* System module interface */
+
+#ifndef Py_SYSMODULE_H
+#define Py_SYSMODULE_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+PyAPI_FUNC(PyObject *) PySys_GetObject(char *);
+PyAPI_FUNC(int) PySys_SetObject(char *, PyObject *);
+PyAPI_FUNC(FILE *) PySys_GetFile(char *, FILE *);
+PyAPI_FUNC(void) PySys_SetArgv(int, char **);
+PyAPI_FUNC(void) PySys_SetPath(char *);
+
+PyAPI_FUNC(void) PySys_WriteStdout(const char *format, ...)
+			Py_GCC_ATTRIBUTE((format(printf, 1, 2)));
+PyAPI_FUNC(void) PySys_WriteStderr(const char *format, ...)
+			Py_GCC_ATTRIBUTE((format(printf, 1, 2)));
+
+PyAPI_DATA(PyObject *) _PySys_TraceFunc, *_PySys_ProfileFunc;
+PyAPI_DATA(int) _PySys_CheckInterval;
+
+PyAPI_FUNC(void) PySys_ResetWarnOptions(void);
+PyAPI_FUNC(void) PySys_AddWarnOption(char *);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_SYSMODULE_H */

Added: vendor/Python/current/Include/timefuncs.h
===================================================================
--- vendor/Python/current/Include/timefuncs.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/timefuncs.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,23 @@
+/*  timefuncs.h
+ */
+
+/* Utility function related to timemodule.c. */
+
+#ifndef TIMEFUNCS_H
+#define TIMEFUNCS_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Cast double x to time_t, but raise ValueError if x is too large
+ * to fit in a time_t.  ValueError is set on return iff the return
+ * value is (time_t)-1 and PyErr_Occurred().
+ */
+PyAPI_FUNC(time_t) _PyTime_DoubleToTimet(double x);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif  /* TIMEFUNCS_H */

Added: vendor/Python/current/Include/token.h
===================================================================
--- vendor/Python/current/Include/token.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/token.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,83 @@
+
+/* Token types */
+
+#ifndef Py_TOKEN_H
+#define Py_TOKEN_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ENDMARKER	0
+#define NAME		1
+#define NUMBER		2
+#define STRING		3
+#define NEWLINE		4
+#define INDENT		5
+#define DEDENT		6
+#define LPAR		7
+#define RPAR		8
+#define LSQB		9
+#define RSQB		10
+#define COLON		11
+#define COMMA		12
+#define SEMI		13
+#define PLUS		14
+#define MINUS		15
+#define STAR		16
+#define SLASH		17
+#define VBAR		18
+#define AMPER		19
+#define LESS		20
+#define GREATER		21
+#define EQUAL		22
+#define DOT		23
+#define PERCENT		24
+#define BACKQUOTE	25
+#define LBRACE		26
+#define RBRACE		27
+#define EQEQUAL		28
+#define NOTEQUAL	29
+#define LESSEQUAL	30
+#define GREATEREQUAL	31
+#define TILDE		32
+#define CIRCUMFLEX	33
+#define LEFTSHIFT	34
+#define RIGHTSHIFT	35
+#define DOUBLESTAR	36
+#define PLUSEQUAL	37
+#define MINEQUAL	38
+#define STAREQUAL	39
+#define SLASHEQUAL	40
+#define PERCENTEQUAL	41
+#define AMPEREQUAL	42
+#define VBAREQUAL	43
+#define CIRCUMFLEXEQUAL	44
+#define LEFTSHIFTEQUAL	45
+#define RIGHTSHIFTEQUAL	46
+#define DOUBLESTAREQUAL	47
+#define DOUBLESLASH	48
+#define DOUBLESLASHEQUAL 49
+#define AT              50	
+/* Don't forget to update the table _PyParser_TokenNames in tokenizer.c! */
+#define OP		51
+#define ERRORTOKEN	52
+#define N_TOKENS	53
+
+/* Special definitions for cooperation with parser */
+
+#define NT_OFFSET		256
+
+#define ISTERMINAL(x)		((x) < NT_OFFSET)
+#define ISNONTERMINAL(x)	((x) >= NT_OFFSET)
+#define ISEOF(x)		((x) == ENDMARKER)
+
+
+PyAPI_DATA(char *) _PyParser_TokenNames[]; /* Token names */
+PyAPI_FUNC(int) PyToken_OneChar(int);
+PyAPI_FUNC(int) PyToken_TwoChars(int, int);
+PyAPI_FUNC(int) PyToken_ThreeChars(int, int, int);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_TOKEN_H */

Added: vendor/Python/current/Include/traceback.h
===================================================================
--- vendor/Python/current/Include/traceback.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/traceback.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,30 @@
+
+#ifndef Py_TRACEBACK_H
+#define Py_TRACEBACK_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct _frame;
+
+/* Traceback interface */
+
+typedef struct _traceback {
+	PyObject_HEAD
+	struct _traceback *tb_next;
+	struct _frame *tb_frame;
+	int tb_lasti;
+	int tb_lineno;
+} PyTracebackObject;
+
+PyAPI_FUNC(int) PyTraceBack_Here(struct _frame *);
+PyAPI_FUNC(int) PyTraceBack_Print(PyObject *, PyObject *);
+
+/* Reveal traceback type so we can typecheck traceback objects */
+PyAPI_DATA(PyTypeObject) PyTraceBack_Type;
+#define PyTraceBack_Check(v) ((v)->ob_type == &PyTraceBack_Type)
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_TRACEBACK_H */

Added: vendor/Python/current/Include/tupleobject.h
===================================================================
--- vendor/Python/current/Include/tupleobject.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/tupleobject.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,57 @@
+
+/* Tuple object interface */
+
+#ifndef Py_TUPLEOBJECT_H
+#define Py_TUPLEOBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+Another generally useful object type is a tuple of object pointers.
+For Python, this is an immutable type.  C code can change the tuple items
+(but not their number), and even use tuples are general-purpose arrays of
+object references, but in general only brand new tuples should be mutated,
+not ones that might already have been exposed to Python code.
+
+*** WARNING *** PyTuple_SetItem does not increment the new item's reference
+count, but does decrement the reference count of the item it replaces,
+if not nil.  It does *decrement* the reference count if it is *not*
+inserted in the tuple.  Similarly, PyTuple_GetItem does not increment the
+returned item's reference count.
+*/
+
+typedef struct {
+    PyObject_VAR_HEAD
+    PyObject *ob_item[1];
+
+    /* ob_item contains space for 'ob_size' elements.
+     * Items must normally not be NULL, except during construction when
+     * the tuple is not yet visible outside the function that builds it.
+     */
+} PyTupleObject;
+
+PyAPI_DATA(PyTypeObject) PyTuple_Type;
+
+#define PyTuple_Check(op) PyObject_TypeCheck(op, &PyTuple_Type)
+#define PyTuple_CheckExact(op) ((op)->ob_type == &PyTuple_Type)
+
+PyAPI_FUNC(PyObject *) PyTuple_New(Py_ssize_t size);
+PyAPI_FUNC(Py_ssize_t) PyTuple_Size(PyObject *);
+PyAPI_FUNC(PyObject *) PyTuple_GetItem(PyObject *, Py_ssize_t);
+PyAPI_FUNC(int) PyTuple_SetItem(PyObject *, Py_ssize_t, PyObject *);
+PyAPI_FUNC(PyObject *) PyTuple_GetSlice(PyObject *, Py_ssize_t, Py_ssize_t);
+PyAPI_FUNC(int) _PyTuple_Resize(PyObject **, Py_ssize_t);
+PyAPI_FUNC(PyObject *) PyTuple_Pack(Py_ssize_t, ...);
+
+/* Macro, trading safety for speed */
+#define PyTuple_GET_ITEM(op, i) (((PyTupleObject *)(op))->ob_item[i])
+#define PyTuple_GET_SIZE(op)    (((PyTupleObject *)(op))->ob_size)
+
+/* Macro, *only* to be used to fill in brand new tuples */
+#define PyTuple_SET_ITEM(op, i, v) (((PyTupleObject *)(op))->ob_item[i] = v)
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_TUPLEOBJECT_H */

Added: vendor/Python/current/Include/ucnhash.h
===================================================================
--- vendor/Python/current/Include/ucnhash.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/ucnhash.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,31 @@
+/* Unicode name database interface */
+
+#ifndef Py_UCNHASH_H
+#define Py_UCNHASH_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* revised ucnhash CAPI interface (exported through a PyCObject) */
+
+typedef struct {
+
+    /* Size of this struct */
+    int size;
+
+    /* Get name for a given character code.  Returns non-zero if
+       success, zero if not.  Does not set Python exceptions. 
+       If self is NULL, data come from the default version of the database.
+       If it is not NULL, it should be a unicodedata.ucd_X_Y_Z object */
+    int (*getname)(PyObject *self, Py_UCS4 code, char* buffer, int buflen);
+
+    /* Get character code for a given name.  Same error handling
+       as for getname. */
+    int (*getcode)(PyObject *self, const char* name, int namelen, Py_UCS4* code);
+
+} _PyUnicode_Name_CAPI;
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_UCNHASH_H */

Added: vendor/Python/current/Include/unicodeobject.h
===================================================================
--- vendor/Python/current/Include/unicodeobject.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/unicodeobject.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1265 @@
+#ifndef Py_UNICODEOBJECT_H
+#define Py_UNICODEOBJECT_H
+
+/*
+
+Unicode implementation based on original code by Fredrik Lundh,
+modified by Marc-Andre Lemburg (mal at lemburg.com) according to the
+Unicode Integration Proposal (see file Misc/unicode.txt).
+
+Copyright (c) Corporation for National Research Initiatives.
+
+
+ Original header:
+ --------------------------------------------------------------------
+
+ * Yet another Unicode string type for Python.  This type supports the
+ * 16-bit Basic Multilingual Plane (BMP) only.
+ *
+ * Written by Fredrik Lundh, January 1999.
+ *
+ * Copyright (c) 1999 by Secret Labs AB.
+ * Copyright (c) 1999 by Fredrik Lundh.
+ *
+ * fredrik at pythonware.com
+ * http://www.pythonware.com
+ *
+ * --------------------------------------------------------------------
+ * This Unicode String Type is
+ * 
+ * Copyright (c) 1999 by Secret Labs AB
+ * Copyright (c) 1999 by Fredrik Lundh
+ * 
+ * By obtaining, using, and/or copying this software and/or its
+ * associated documentation, you agree that you have read, understood,
+ * and will comply with the following terms and conditions:
+ * 
+ * Permission to use, copy, modify, and distribute this software and its
+ * associated documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice appears in all
+ * copies, and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of Secret Labs
+ * AB or the author not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission.
+ * 
+ * SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS.  IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ * -------------------------------------------------------------------- */
+
+#include <ctype.h>
+
+/* === Internal API ======================================================= */
+
+/* --- Internal Unicode Format -------------------------------------------- */
+
+#ifndef Py_USING_UNICODE
+
+#define PyUnicode_Check(op)                 0
+#define PyUnicode_CheckExact(op)            0
+
+#else
+
+/* FIXME: MvL's new implementation assumes that Py_UNICODE_SIZE is
+   properly set, but the default rules below doesn't set it.  I'll
+   sort this out some other day -- fredrik at pythonware.com */
+
+#ifndef Py_UNICODE_SIZE
+#error Must define Py_UNICODE_SIZE
+#endif
+
+/* Setting Py_UNICODE_WIDE enables UCS-4 storage.  Otherwise, Unicode
+   strings are stored as UCS-2 (with limited support for UTF-16) */
+
+#if Py_UNICODE_SIZE >= 4
+#define Py_UNICODE_WIDE
+#endif
+
+/* Set these flags if the platform has "wchar.h", "wctype.h" and the
+   wchar_t type is a 16-bit unsigned type */
+/* #define HAVE_WCHAR_H */
+/* #define HAVE_USABLE_WCHAR_T */
+
+/* Defaults for various platforms */
+#ifndef PY_UNICODE_TYPE
+
+/* Windows has a usable wchar_t type (unless we're using UCS-4) */
+# if defined(MS_WIN32) && Py_UNICODE_SIZE == 2
+#  define HAVE_USABLE_WCHAR_T
+#  define PY_UNICODE_TYPE wchar_t
+# endif
+
+# if defined(Py_UNICODE_WIDE)
+#  define PY_UNICODE_TYPE Py_UCS4
+# endif
+
+#endif
+
+/* If the compiler provides a wchar_t type we try to support it
+   through the interface functions PyUnicode_FromWideChar() and
+   PyUnicode_AsWideChar(). */
+
+#ifdef HAVE_USABLE_WCHAR_T
+# ifndef HAVE_WCHAR_H
+#  define HAVE_WCHAR_H
+# endif
+#endif
+
+#ifdef HAVE_WCHAR_H
+/* Work around a cosmetic bug in BSDI 4.x wchar.h; thanks to Thomas Wouters */
+# ifdef _HAVE_BSDI
+#  include <time.h>
+# endif
+#  include <wchar.h>
+#endif
+
+/*
+ * Use this typedef when you need to represent a UTF-16 surrogate pair
+ * as single unsigned integer.
+ */
+#if SIZEOF_INT >= 4 
+typedef unsigned int Py_UCS4; 
+#elif SIZEOF_LONG >= 4
+typedef unsigned long Py_UCS4; 
+#endif
+
+typedef PY_UNICODE_TYPE Py_UNICODE;
+
+/* --- UCS-2/UCS-4 Name Mangling ------------------------------------------ */
+
+/* Unicode API names are mangled to assure that UCS-2 and UCS-4 builds
+   produce different external names and thus cause import errors in
+   case Python interpreters and extensions with mixed compiled in
+   Unicode width assumptions are combined. */
+
+#ifndef Py_UNICODE_WIDE
+
+# define PyUnicode_AsASCIIString PyUnicodeUCS2_AsASCIIString
+# define PyUnicode_AsCharmapString PyUnicodeUCS2_AsCharmapString
+# define PyUnicode_AsEncodedObject PyUnicodeUCS2_AsEncodedObject
+# define PyUnicode_AsEncodedString PyUnicodeUCS2_AsEncodedString
+# define PyUnicode_AsLatin1String PyUnicodeUCS2_AsLatin1String
+# define PyUnicode_AsRawUnicodeEscapeString PyUnicodeUCS2_AsRawUnicodeEscapeString
+# define PyUnicode_AsUTF16String PyUnicodeUCS2_AsUTF16String
+# define PyUnicode_AsUTF8String PyUnicodeUCS2_AsUTF8String
+# define PyUnicode_AsUnicode PyUnicodeUCS2_AsUnicode
+# define PyUnicode_AsUnicodeEscapeString PyUnicodeUCS2_AsUnicodeEscapeString
+# define PyUnicode_AsWideChar PyUnicodeUCS2_AsWideChar
+# define PyUnicode_Compare PyUnicodeUCS2_Compare
+# define PyUnicode_Concat PyUnicodeUCS2_Concat
+# define PyUnicode_Contains PyUnicodeUCS2_Contains
+# define PyUnicode_Count PyUnicodeUCS2_Count
+# define PyUnicode_Decode PyUnicodeUCS2_Decode
+# define PyUnicode_DecodeASCII PyUnicodeUCS2_DecodeASCII
+# define PyUnicode_DecodeCharmap PyUnicodeUCS2_DecodeCharmap
+# define PyUnicode_DecodeLatin1 PyUnicodeUCS2_DecodeLatin1
+# define PyUnicode_DecodeRawUnicodeEscape PyUnicodeUCS2_DecodeRawUnicodeEscape
+# define PyUnicode_DecodeUTF16 PyUnicodeUCS2_DecodeUTF16
+# define PyUnicode_DecodeUTF16Stateful PyUnicodeUCS2_DecodeUTF16Stateful
+# define PyUnicode_DecodeUTF8 PyUnicodeUCS2_DecodeUTF8
+# define PyUnicode_DecodeUTF8Stateful PyUnicodeUCS2_DecodeUTF8Stateful
+# define PyUnicode_DecodeUnicodeEscape PyUnicodeUCS2_DecodeUnicodeEscape
+# define PyUnicode_Encode PyUnicodeUCS2_Encode
+# define PyUnicode_EncodeASCII PyUnicodeUCS2_EncodeASCII
+# define PyUnicode_EncodeCharmap PyUnicodeUCS2_EncodeCharmap
+# define PyUnicode_EncodeDecimal PyUnicodeUCS2_EncodeDecimal
+# define PyUnicode_EncodeLatin1 PyUnicodeUCS2_EncodeLatin1
+# define PyUnicode_EncodeRawUnicodeEscape PyUnicodeUCS2_EncodeRawUnicodeEscape
+# define PyUnicode_EncodeUTF16 PyUnicodeUCS2_EncodeUTF16
+# define PyUnicode_EncodeUTF8 PyUnicodeUCS2_EncodeUTF8
+# define PyUnicode_EncodeUnicodeEscape PyUnicodeUCS2_EncodeUnicodeEscape
+# define PyUnicode_Find PyUnicodeUCS2_Find
+# define PyUnicode_Format PyUnicodeUCS2_Format
+# define PyUnicode_FromEncodedObject PyUnicodeUCS2_FromEncodedObject
+# define PyUnicode_FromObject PyUnicodeUCS2_FromObject
+# define PyUnicode_FromOrdinal PyUnicodeUCS2_FromOrdinal
+# define PyUnicode_FromUnicode PyUnicodeUCS2_FromUnicode
+# define PyUnicode_FromWideChar PyUnicodeUCS2_FromWideChar
+# define PyUnicode_GetDefaultEncoding PyUnicodeUCS2_GetDefaultEncoding
+# define PyUnicode_GetMax PyUnicodeUCS2_GetMax
+# define PyUnicode_GetSize PyUnicodeUCS2_GetSize
+# define PyUnicode_Join PyUnicodeUCS2_Join
+# define PyUnicode_Partition PyUnicodeUCS2_Partition
+# define PyUnicode_RPartition PyUnicodeUCS2_RPartition
+# define PyUnicode_RSplit PyUnicodeUCS2_RSplit
+# define PyUnicode_Replace PyUnicodeUCS2_Replace
+# define PyUnicode_Resize PyUnicodeUCS2_Resize
+# define PyUnicode_RichCompare PyUnicodeUCS2_RichCompare
+# define PyUnicode_SetDefaultEncoding PyUnicodeUCS2_SetDefaultEncoding
+# define PyUnicode_Split PyUnicodeUCS2_Split
+# define PyUnicode_Splitlines PyUnicodeUCS2_Splitlines
+# define PyUnicode_Tailmatch PyUnicodeUCS2_Tailmatch
+# define PyUnicode_Translate PyUnicodeUCS2_Translate
+# define PyUnicode_TranslateCharmap PyUnicodeUCS2_TranslateCharmap
+# define _PyUnicode_AsDefaultEncodedString _PyUnicodeUCS2_AsDefaultEncodedString
+# define _PyUnicode_Fini _PyUnicodeUCS2_Fini
+# define _PyUnicode_Init _PyUnicodeUCS2_Init
+# define _PyUnicode_IsAlpha _PyUnicodeUCS2_IsAlpha
+# define _PyUnicode_IsDecimalDigit _PyUnicodeUCS2_IsDecimalDigit
+# define _PyUnicode_IsDigit _PyUnicodeUCS2_IsDigit
+# define _PyUnicode_IsLinebreak _PyUnicodeUCS2_IsLinebreak
+# define _PyUnicode_IsLowercase _PyUnicodeUCS2_IsLowercase
+# define _PyUnicode_IsNumeric _PyUnicodeUCS2_IsNumeric
+# define _PyUnicode_IsTitlecase _PyUnicodeUCS2_IsTitlecase
+# define _PyUnicode_IsUppercase _PyUnicodeUCS2_IsUppercase
+# define _PyUnicode_IsWhitespace _PyUnicodeUCS2_IsWhitespace
+# define _PyUnicode_ToDecimalDigit _PyUnicodeUCS2_ToDecimalDigit
+# define _PyUnicode_ToDigit _PyUnicodeUCS2_ToDigit
+# define _PyUnicode_ToLowercase _PyUnicodeUCS2_ToLowercase
+# define _PyUnicode_ToNumeric _PyUnicodeUCS2_ToNumeric
+# define _PyUnicode_ToTitlecase _PyUnicodeUCS2_ToTitlecase
+# define _PyUnicode_ToUppercase _PyUnicodeUCS2_ToUppercase
+
+#else
+
+# define PyUnicode_AsASCIIString PyUnicodeUCS4_AsASCIIString
+# define PyUnicode_AsCharmapString PyUnicodeUCS4_AsCharmapString
+# define PyUnicode_AsEncodedObject PyUnicodeUCS4_AsEncodedObject
+# define PyUnicode_AsEncodedString PyUnicodeUCS4_AsEncodedString
+# define PyUnicode_AsLatin1String PyUnicodeUCS4_AsLatin1String
+# define PyUnicode_AsRawUnicodeEscapeString PyUnicodeUCS4_AsRawUnicodeEscapeString
+# define PyUnicode_AsUTF16String PyUnicodeUCS4_AsUTF16String
+# define PyUnicode_AsUTF8String PyUnicodeUCS4_AsUTF8String
+# define PyUnicode_AsUnicode PyUnicodeUCS4_AsUnicode
+# define PyUnicode_AsUnicodeEscapeString PyUnicodeUCS4_AsUnicodeEscapeString
+# define PyUnicode_AsWideChar PyUnicodeUCS4_AsWideChar
+# define PyUnicode_Compare PyUnicodeUCS4_Compare
+# define PyUnicode_Concat PyUnicodeUCS4_Concat
+# define PyUnicode_Contains PyUnicodeUCS4_Contains
+# define PyUnicode_Count PyUnicodeUCS4_Count
+# define PyUnicode_Decode PyUnicodeUCS4_Decode
+# define PyUnicode_DecodeASCII PyUnicodeUCS4_DecodeASCII
+# define PyUnicode_DecodeCharmap PyUnicodeUCS4_DecodeCharmap
+# define PyUnicode_DecodeLatin1 PyUnicodeUCS4_DecodeLatin1
+# define PyUnicode_DecodeRawUnicodeEscape PyUnicodeUCS4_DecodeRawUnicodeEscape
+# define PyUnicode_DecodeUTF16 PyUnicodeUCS4_DecodeUTF16
+# define PyUnicode_DecodeUTF16Stateful PyUnicodeUCS4_DecodeUTF16Stateful
+# define PyUnicode_DecodeUTF8 PyUnicodeUCS4_DecodeUTF8
+# define PyUnicode_DecodeUTF8Stateful PyUnicodeUCS4_DecodeUTF8Stateful
+# define PyUnicode_DecodeUnicodeEscape PyUnicodeUCS4_DecodeUnicodeEscape
+# define PyUnicode_Encode PyUnicodeUCS4_Encode
+# define PyUnicode_EncodeASCII PyUnicodeUCS4_EncodeASCII
+# define PyUnicode_EncodeCharmap PyUnicodeUCS4_EncodeCharmap
+# define PyUnicode_EncodeDecimal PyUnicodeUCS4_EncodeDecimal
+# define PyUnicode_EncodeLatin1 PyUnicodeUCS4_EncodeLatin1
+# define PyUnicode_EncodeRawUnicodeEscape PyUnicodeUCS4_EncodeRawUnicodeEscape
+# define PyUnicode_EncodeUTF16 PyUnicodeUCS4_EncodeUTF16
+# define PyUnicode_EncodeUTF8 PyUnicodeUCS4_EncodeUTF8
+# define PyUnicode_EncodeUnicodeEscape PyUnicodeUCS4_EncodeUnicodeEscape
+# define PyUnicode_Find PyUnicodeUCS4_Find
+# define PyUnicode_Format PyUnicodeUCS4_Format
+# define PyUnicode_FromEncodedObject PyUnicodeUCS4_FromEncodedObject
+# define PyUnicode_FromObject PyUnicodeUCS4_FromObject
+# define PyUnicode_FromOrdinal PyUnicodeUCS4_FromOrdinal
+# define PyUnicode_FromUnicode PyUnicodeUCS4_FromUnicode
+# define PyUnicode_FromWideChar PyUnicodeUCS4_FromWideChar
+# define PyUnicode_GetDefaultEncoding PyUnicodeUCS4_GetDefaultEncoding
+# define PyUnicode_GetMax PyUnicodeUCS4_GetMax
+# define PyUnicode_GetSize PyUnicodeUCS4_GetSize
+# define PyUnicode_Join PyUnicodeUCS4_Join
+# define PyUnicode_Partition PyUnicodeUCS4_Partition
+# define PyUnicode_RPartition PyUnicodeUCS4_RPartition
+# define PyUnicode_RSplit PyUnicodeUCS4_RSplit
+# define PyUnicode_Replace PyUnicodeUCS4_Replace
+# define PyUnicode_Resize PyUnicodeUCS4_Resize
+# define PyUnicode_RichCompare PyUnicodeUCS4_RichCompare
+# define PyUnicode_SetDefaultEncoding PyUnicodeUCS4_SetDefaultEncoding
+# define PyUnicode_Split PyUnicodeUCS4_Split
+# define PyUnicode_Splitlines PyUnicodeUCS4_Splitlines
+# define PyUnicode_Tailmatch PyUnicodeUCS4_Tailmatch
+# define PyUnicode_Translate PyUnicodeUCS4_Translate
+# define PyUnicode_TranslateCharmap PyUnicodeUCS4_TranslateCharmap
+# define _PyUnicode_AsDefaultEncodedString _PyUnicodeUCS4_AsDefaultEncodedString
+# define _PyUnicode_Fini _PyUnicodeUCS4_Fini
+# define _PyUnicode_Init _PyUnicodeUCS4_Init
+# define _PyUnicode_IsAlpha _PyUnicodeUCS4_IsAlpha
+# define _PyUnicode_IsDecimalDigit _PyUnicodeUCS4_IsDecimalDigit
+# define _PyUnicode_IsDigit _PyUnicodeUCS4_IsDigit
+# define _PyUnicode_IsLinebreak _PyUnicodeUCS4_IsLinebreak
+# define _PyUnicode_IsLowercase _PyUnicodeUCS4_IsLowercase
+# define _PyUnicode_IsNumeric _PyUnicodeUCS4_IsNumeric
+# define _PyUnicode_IsTitlecase _PyUnicodeUCS4_IsTitlecase
+# define _PyUnicode_IsUppercase _PyUnicodeUCS4_IsUppercase
+# define _PyUnicode_IsWhitespace _PyUnicodeUCS4_IsWhitespace
+# define _PyUnicode_ToDecimalDigit _PyUnicodeUCS4_ToDecimalDigit
+# define _PyUnicode_ToDigit _PyUnicodeUCS4_ToDigit
+# define _PyUnicode_ToLowercase _PyUnicodeUCS4_ToLowercase
+# define _PyUnicode_ToNumeric _PyUnicodeUCS4_ToNumeric
+# define _PyUnicode_ToTitlecase _PyUnicodeUCS4_ToTitlecase
+# define _PyUnicode_ToUppercase _PyUnicodeUCS4_ToUppercase
+
+
+#endif
+
+/* --- Internal Unicode Operations ---------------------------------------- */
+
+/* If you want Python to use the compiler's wctype.h functions instead
+   of the ones supplied with Python, define WANT_WCTYPE_FUNCTIONS or
+   configure Python using --with-wctype-functions.  This reduces the
+   interpreter's code size. */
+
+#if defined(HAVE_USABLE_WCHAR_T) && defined(WANT_WCTYPE_FUNCTIONS)
+
+#include <wctype.h>
+
+#define Py_UNICODE_ISSPACE(ch) iswspace(ch)
+
+#define Py_UNICODE_ISLOWER(ch) iswlower(ch)
+#define Py_UNICODE_ISUPPER(ch) iswupper(ch)
+#define Py_UNICODE_ISTITLE(ch) _PyUnicode_IsTitlecase(ch)
+#define Py_UNICODE_ISLINEBREAK(ch) _PyUnicode_IsLinebreak(ch)
+
+#define Py_UNICODE_TOLOWER(ch) towlower(ch)
+#define Py_UNICODE_TOUPPER(ch) towupper(ch)
+#define Py_UNICODE_TOTITLE(ch) _PyUnicode_ToTitlecase(ch)
+
+#define Py_UNICODE_ISDECIMAL(ch) _PyUnicode_IsDecimalDigit(ch)
+#define Py_UNICODE_ISDIGIT(ch) _PyUnicode_IsDigit(ch)
+#define Py_UNICODE_ISNUMERIC(ch) _PyUnicode_IsNumeric(ch)
+
+#define Py_UNICODE_TODECIMAL(ch) _PyUnicode_ToDecimalDigit(ch)
+#define Py_UNICODE_TODIGIT(ch) _PyUnicode_ToDigit(ch)
+#define Py_UNICODE_TONUMERIC(ch) _PyUnicode_ToNumeric(ch)
+
+#define Py_UNICODE_ISALPHA(ch) iswalpha(ch)
+
+#else
+
+#define Py_UNICODE_ISSPACE(ch) _PyUnicode_IsWhitespace(ch)
+
+#define Py_UNICODE_ISLOWER(ch) _PyUnicode_IsLowercase(ch)
+#define Py_UNICODE_ISUPPER(ch) _PyUnicode_IsUppercase(ch)
+#define Py_UNICODE_ISTITLE(ch) _PyUnicode_IsTitlecase(ch)
+#define Py_UNICODE_ISLINEBREAK(ch) _PyUnicode_IsLinebreak(ch)
+
+#define Py_UNICODE_TOLOWER(ch) _PyUnicode_ToLowercase(ch)
+#define Py_UNICODE_TOUPPER(ch) _PyUnicode_ToUppercase(ch)
+#define Py_UNICODE_TOTITLE(ch) _PyUnicode_ToTitlecase(ch)
+
+#define Py_UNICODE_ISDECIMAL(ch) _PyUnicode_IsDecimalDigit(ch)
+#define Py_UNICODE_ISDIGIT(ch) _PyUnicode_IsDigit(ch)
+#define Py_UNICODE_ISNUMERIC(ch) _PyUnicode_IsNumeric(ch)
+
+#define Py_UNICODE_TODECIMAL(ch) _PyUnicode_ToDecimalDigit(ch)
+#define Py_UNICODE_TODIGIT(ch) _PyUnicode_ToDigit(ch)
+#define Py_UNICODE_TONUMERIC(ch) _PyUnicode_ToNumeric(ch)
+
+#define Py_UNICODE_ISALPHA(ch) _PyUnicode_IsAlpha(ch)
+
+#endif
+
+#define Py_UNICODE_ISALNUM(ch) \
+       (Py_UNICODE_ISALPHA(ch) || \
+        Py_UNICODE_ISDECIMAL(ch) || \
+        Py_UNICODE_ISDIGIT(ch) || \
+        Py_UNICODE_ISNUMERIC(ch))
+
+#define Py_UNICODE_COPY(target, source, length)				\
+	Py_MEMCPY((target), (source), (length)*sizeof(Py_UNICODE))
+
+#define Py_UNICODE_FILL(target, value, length) do\
+    {Py_ssize_t i_; Py_UNICODE *t_ = (target); Py_UNICODE v_ = (value);\
+        for (i_ = 0; i_ < (length); i_++) t_[i_] = v_;\
+    } while (0)
+
+/* check if substring matches at given offset.  the offset must be
+   valid, and the substring must not be empty */
+#define Py_UNICODE_MATCH(string, offset, substring) \
+    ((*((string)->str + (offset)) == *((substring)->str)) && \
+    ((*((string)->str + (offset) + (substring)->length-1) == *((substring)->str + (substring)->length-1))) && \
+     !memcmp((string)->str + (offset), (substring)->str, (substring)->length*sizeof(Py_UNICODE)))
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* --- Unicode Type ------------------------------------------------------- */
+
+typedef struct {
+    PyObject_HEAD
+    Py_ssize_t length;		/* Length of raw Unicode data in buffer */
+    Py_UNICODE *str;		/* Raw Unicode buffer */
+    long hash;			/* Hash value; -1 if not set */
+    PyObject *defenc;		/* (Default) Encoded version as Python
+				   string, or NULL; this is used for
+				   implementing the buffer protocol */
+} PyUnicodeObject;
+
+PyAPI_DATA(PyTypeObject) PyUnicode_Type;
+
+#define PyUnicode_Check(op) PyObject_TypeCheck(op, &PyUnicode_Type)
+#define PyUnicode_CheckExact(op) ((op)->ob_type == &PyUnicode_Type)
+
+/* Fast access macros */
+#define PyUnicode_GET_SIZE(op) \
+        (((PyUnicodeObject *)(op))->length)
+#define PyUnicode_GET_DATA_SIZE(op) \
+        (((PyUnicodeObject *)(op))->length * sizeof(Py_UNICODE))
+#define PyUnicode_AS_UNICODE(op) \
+        (((PyUnicodeObject *)(op))->str)
+#define PyUnicode_AS_DATA(op) \
+        ((const char *)((PyUnicodeObject *)(op))->str)
+
+/* --- Constants ---------------------------------------------------------- */
+
+/* This Unicode character will be used as replacement character during
+   decoding if the errors argument is set to "replace". Note: the
+   Unicode character U+FFFD is the official REPLACEMENT CHARACTER in
+   Unicode 3.0. */
+
+#define Py_UNICODE_REPLACEMENT_CHARACTER ((Py_UNICODE) 0xFFFD)
+
+/* === Public API ========================================================= */
+
+/* --- Plain Py_UNICODE --------------------------------------------------- */
+
+/* Create a Unicode Object from the Py_UNICODE buffer u of the given
+   size. 
+
+   u may be NULL which causes the contents to be undefined. It is the
+   user's responsibility to fill in the needed data afterwards. Note
+   that modifying the Unicode object contents after construction is
+   only allowed if u was set to NULL.
+
+   The buffer is copied into the new object. */
+
+PyAPI_FUNC(PyObject*) PyUnicode_FromUnicode(
+    const Py_UNICODE *u,        /* Unicode buffer */
+    Py_ssize_t size             /* size of buffer */
+    );
+
+/* Return a read-only pointer to the Unicode object's internal
+   Py_UNICODE buffer. */
+
+PyAPI_FUNC(Py_UNICODE *) PyUnicode_AsUnicode(
+    PyObject *unicode	 	/* Unicode object */
+    );
+
+/* Get the length of the Unicode object. */
+
+PyAPI_FUNC(Py_ssize_t) PyUnicode_GetSize(
+    PyObject *unicode	 	/* Unicode object */
+    );
+
+/* Get the maximum ordinal for a Unicode character. */
+PyAPI_FUNC(Py_UNICODE) PyUnicode_GetMax(void);
+
+/* Resize an already allocated Unicode object to the new size length.
+
+   *unicode is modified to point to the new (resized) object and 0
+   returned on success.
+
+   This API may only be called by the function which also called the
+   Unicode constructor. The refcount on the object must be 1. Otherwise,
+   an error is returned.
+
+   Error handling is implemented as follows: an exception is set, -1
+   is returned and *unicode left untouched.
+
+*/
+
+PyAPI_FUNC(int) PyUnicode_Resize(
+    PyObject **unicode,		/* Pointer to the Unicode object */
+    Py_ssize_t length		/* New length */
+    );
+
+/* Coerce obj to an Unicode object and return a reference with
+   *incremented* refcount.
+
+   Coercion is done in the following way:
+
+   1. String and other char buffer compatible objects are decoded
+      under the assumptions that they contain data using the current
+      default encoding. Decoding is done in "strict" mode.
+
+   2. All other objects (including Unicode objects) raise an
+      exception.
+
+   The API returns NULL in case of an error. The caller is responsible
+   for decref'ing the returned objects.
+
+*/
+
+PyAPI_FUNC(PyObject*) PyUnicode_FromEncodedObject(
+    register PyObject *obj, 	/* Object */
+    const char *encoding,       /* encoding */
+    const char *errors          /* error handling */
+    );
+
+/* Coerce obj to an Unicode object and return a reference with
+   *incremented* refcount.
+   
+   Unicode objects are passed back as-is (subclasses are converted to
+   true Unicode objects), all other objects are delegated to
+   PyUnicode_FromEncodedObject(obj, NULL, "strict") which results in
+   using the default encoding as basis for decoding the object.
+
+   The API returns NULL in case of an error. The caller is responsible
+   for decref'ing the returned objects.
+
+*/
+
+PyAPI_FUNC(PyObject*) PyUnicode_FromObject(
+    register PyObject *obj 	/* Object */
+    );
+
+/* --- wchar_t support for platforms which support it --------------------- */
+
+#ifdef HAVE_WCHAR_H
+
+/* Create a Unicode Object from the whcar_t buffer w of the given
+   size.
+
+   The buffer is copied into the new object. */
+
+PyAPI_FUNC(PyObject*) PyUnicode_FromWideChar(
+    register const wchar_t *w,  /* wchar_t buffer */
+    Py_ssize_t size             /* size of buffer */
+    );
+
+/* Copies the Unicode Object contents into the wchar_t buffer w.  At
+   most size wchar_t characters are copied.
+
+   Note that the resulting wchar_t string may or may not be
+   0-terminated.  It is the responsibility of the caller to make sure
+   that the wchar_t string is 0-terminated in case this is required by
+   the application.
+
+   Returns the number of wchar_t characters copied (excluding a
+   possibly trailing 0-termination character) or -1 in case of an
+   error. */
+
+PyAPI_FUNC(Py_ssize_t) PyUnicode_AsWideChar(
+    PyUnicodeObject *unicode,   /* Unicode object */
+    register wchar_t *w,        /* wchar_t buffer */
+    Py_ssize_t size             /* size of buffer */
+    );
+
+#endif
+
+/* --- Unicode ordinals --------------------------------------------------- */
+
+/* Create a Unicode Object from the given Unicode code point ordinal. 
+ 
+   The ordinal must be in range(0x10000) on narrow Python builds
+   (UCS2), and range(0x110000) on wide builds (UCS4). A ValueError is
+   raised in case it is not.
+
+*/
+
+PyAPI_FUNC(PyObject*) PyUnicode_FromOrdinal(int ordinal);
+
+/* === Builtin Codecs ===================================================== 
+
+   Many of these APIs take two arguments encoding and errors. These
+   parameters encoding and errors have the same semantics as the ones
+   of the builtin unicode() API. 
+
+   Setting encoding to NULL causes the default encoding to be used.
+
+   Error handling is set by errors which may also be set to NULL
+   meaning to use the default handling defined for the codec. Default
+   error handling for all builtin codecs is "strict" (ValueErrors are
+   raised).
+
+   The codecs all use a similar interface. Only deviation from the
+   generic ones are documented.
+
+*/
+
+/* --- Manage the default encoding ---------------------------------------- */
+
+/* Return a Python string holding the default encoded value of the
+   Unicode object. 
+
+   The resulting string is cached in the Unicode object for subsequent
+   usage by this function. The cached version is needed to implement
+   the character buffer interface and will live (at least) as long as
+   the Unicode object itself.
+
+   The refcount of the string is *not* incremented.
+
+   *** Exported for internal use by the interpreter only !!! ***
+
+*/
+
+PyAPI_FUNC(PyObject *) _PyUnicode_AsDefaultEncodedString(
+    PyObject *, const char *);
+
+/* Returns the currently active default encoding.
+
+   The default encoding is currently implemented as run-time settable
+   process global.  This may change in future versions of the
+   interpreter to become a parameter which is managed on a per-thread
+   basis.
+   
+ */
+
+PyAPI_FUNC(const char*) PyUnicode_GetDefaultEncoding(void);
+
+/* Sets the currently active default encoding.
+
+   Returns 0 on success, -1 in case of an error.
+   
+ */
+
+PyAPI_FUNC(int) PyUnicode_SetDefaultEncoding(
+    const char *encoding	/* Encoding name in standard form */
+    );
+
+/* --- Generic Codecs ----------------------------------------------------- */
+
+/* Create a Unicode object by decoding the encoded string s of the
+   given size. */
+
+PyAPI_FUNC(PyObject*) PyUnicode_Decode(
+    const char *s,              /* encoded string */
+    Py_ssize_t size,            /* size of buffer */
+    const char *encoding,       /* encoding */
+    const char *errors          /* error handling */
+    );
+
+/* Encodes a Py_UNICODE buffer of the given size and returns a 
+   Python string object. */
+
+PyAPI_FUNC(PyObject*) PyUnicode_Encode(
+    const Py_UNICODE *s,        /* Unicode char buffer */
+    Py_ssize_t size,            /* number of Py_UNICODE chars to encode */
+    const char *encoding,       /* encoding */
+    const char *errors          /* error handling */
+    );
+
+/* Encodes a Unicode object and returns the result as Python
+   object. */
+
+PyAPI_FUNC(PyObject*) PyUnicode_AsEncodedObject(
+    PyObject *unicode,	 	/* Unicode object */
+    const char *encoding,	/* encoding */
+    const char *errors		/* error handling */
+    );
+
+/* Encodes a Unicode object and returns the result as Python string
+   object. */
+
+PyAPI_FUNC(PyObject*) PyUnicode_AsEncodedString(
+    PyObject *unicode,	 	/* Unicode object */
+    const char *encoding,	/* encoding */
+    const char *errors		/* error handling */
+    );
+
+PyAPI_FUNC(PyObject*) PyUnicode_BuildEncodingMap(
+    PyObject* string            /* 256 character map */
+   );
+
+
+/* --- UTF-7 Codecs ------------------------------------------------------- */
+
+PyAPI_FUNC(PyObject*) PyUnicode_DecodeUTF7(
+    const char *string, 	/* UTF-7 encoded string */
+    Py_ssize_t length,	 	/* size of string */
+    const char *errors		/* error handling */
+    );
+
+PyAPI_FUNC(PyObject*) PyUnicode_EncodeUTF7(
+    const Py_UNICODE *data, 	/* Unicode char buffer */
+    Py_ssize_t length,	 		/* number of Py_UNICODE chars to encode */
+    int encodeSetO,             /* force the encoder to encode characters in
+                                   Set O, as described in RFC2152 */
+    int encodeWhiteSpace,       /* force the encoder to encode space, tab,
+                                   carriage return and linefeed characters */
+    const char *errors		/* error handling */
+    );
+
+/* --- UTF-8 Codecs ------------------------------------------------------- */
+
+PyAPI_FUNC(PyObject*) PyUnicode_DecodeUTF8(
+    const char *string, 	/* UTF-8 encoded string */
+    Py_ssize_t length,	 	/* size of string */
+    const char *errors		/* error handling */
+    );
+
+PyAPI_FUNC(PyObject*) PyUnicode_DecodeUTF8Stateful(
+    const char *string, 	/* UTF-8 encoded string */
+    Py_ssize_t length,	 	/* size of string */
+    const char *errors,		/* error handling */
+    Py_ssize_t *consumed		/* bytes consumed */
+    );
+
+PyAPI_FUNC(PyObject*) PyUnicode_AsUTF8String(
+    PyObject *unicode	 	/* Unicode object */
+    );
+
+PyAPI_FUNC(PyObject*) PyUnicode_EncodeUTF8(
+    const Py_UNICODE *data, 	/* Unicode char buffer */
+    Py_ssize_t length,	 		/* number of Py_UNICODE chars to encode */
+    const char *errors		/* error handling */
+    );
+
+/* --- UTF-16 Codecs ------------------------------------------------------ */
+
+/* Decodes length bytes from a UTF-16 encoded buffer string and returns
+   the corresponding Unicode object.
+
+   errors (if non-NULL) defines the error handling. It defaults
+   to "strict". 
+
+   If byteorder is non-NULL, the decoder starts decoding using the
+   given byte order:
+
+	*byteorder == -1: little endian
+	*byteorder == 0:  native order
+	*byteorder == 1:  big endian
+
+   In native mode, the first two bytes of the stream are checked for a
+   BOM mark. If found, the BOM mark is analysed, the byte order
+   adjusted and the BOM skipped.  In the other modes, no BOM mark
+   interpretation is done. After completion, *byteorder is set to the
+   current byte order at the end of input data.
+
+   If byteorder is NULL, the codec starts in native order mode.
+
+*/
+
+PyAPI_FUNC(PyObject*) PyUnicode_DecodeUTF16(
+    const char *string, 	/* UTF-16 encoded string */
+    Py_ssize_t length,	 	/* size of string */
+    const char *errors,		/* error handling */
+    int *byteorder		/* pointer to byteorder to use
+				   0=native;-1=LE,1=BE; updated on
+				   exit */
+    );
+
+PyAPI_FUNC(PyObject*) PyUnicode_DecodeUTF16Stateful(
+    const char *string, 	/* UTF-16 encoded string */
+    Py_ssize_t length,	 	/* size of string */
+    const char *errors,		/* error handling */
+    int *byteorder,		/* pointer to byteorder to use
+				   0=native;-1=LE,1=BE; updated on
+				   exit */
+    Py_ssize_t *consumed		/* bytes consumed */
+    );
+
+/* Returns a Python string using the UTF-16 encoding in native byte
+   order. The string always starts with a BOM mark.  */
+
+PyAPI_FUNC(PyObject*) PyUnicode_AsUTF16String(
+    PyObject *unicode	 	/* Unicode object */
+    );
+
+/* Returns a Python string object holding the UTF-16 encoded value of
+   the Unicode data.
+
+   If byteorder is not 0, output is written according to the following
+   byte order:
+
+   byteorder == -1: little endian
+   byteorder == 0:  native byte order (writes a BOM mark)
+   byteorder == 1:  big endian
+
+   If byteorder is 0, the output string will always start with the
+   Unicode BOM mark (U+FEFF). In the other two modes, no BOM mark is
+   prepended.
+
+   Note that Py_UNICODE data is being interpreted as UTF-16 reduced to
+   UCS-2. This trick makes it possible to add full UTF-16 capabilities
+   at a later point without compromising the APIs.
+
+*/
+
+PyAPI_FUNC(PyObject*) PyUnicode_EncodeUTF16(
+    const Py_UNICODE *data, 	/* Unicode char buffer */
+    Py_ssize_t length,	 		/* number of Py_UNICODE chars to encode */
+    const char *errors,		/* error handling */
+    int byteorder		/* byteorder to use 0=BOM+native;-1=LE,1=BE */
+    );
+
+/* --- Unicode-Escape Codecs ---------------------------------------------- */
+
+PyAPI_FUNC(PyObject*) PyUnicode_DecodeUnicodeEscape(
+    const char *string, 	/* Unicode-Escape encoded string */
+    Py_ssize_t length,	 	/* size of string */
+    const char *errors		/* error handling */
+    );
+
+PyAPI_FUNC(PyObject*) PyUnicode_AsUnicodeEscapeString(
+    PyObject *unicode	 	/* Unicode object */
+    );
+
+PyAPI_FUNC(PyObject*) PyUnicode_EncodeUnicodeEscape(
+    const Py_UNICODE *data, 	/* Unicode char buffer */
+    Py_ssize_t length	 		/* Number of Py_UNICODE chars to encode */
+    );
+
+/* --- Raw-Unicode-Escape Codecs ------------------------------------------ */
+
+PyAPI_FUNC(PyObject*) PyUnicode_DecodeRawUnicodeEscape(
+    const char *string, 	/* Raw-Unicode-Escape encoded string */
+    Py_ssize_t length,	 	/* size of string */
+    const char *errors		/* error handling */
+    );
+
+PyAPI_FUNC(PyObject*) PyUnicode_AsRawUnicodeEscapeString(
+    PyObject *unicode	 	/* Unicode object */
+    );
+
+PyAPI_FUNC(PyObject*) PyUnicode_EncodeRawUnicodeEscape(
+    const Py_UNICODE *data, 	/* Unicode char buffer */
+    Py_ssize_t length	 		/* Number of Py_UNICODE chars to encode */
+    );
+
+/* --- Unicode Internal Codec ---------------------------------------------
+
+    Only for internal use in _codecsmodule.c */
+
+PyObject *_PyUnicode_DecodeUnicodeInternal(
+    const char *string,
+    Py_ssize_t length,
+    const char *errors
+    );
+
+/* --- Latin-1 Codecs ----------------------------------------------------- 
+
+   Note: Latin-1 corresponds to the first 256 Unicode ordinals.
+
+*/
+
+PyAPI_FUNC(PyObject*) PyUnicode_DecodeLatin1(
+    const char *string, 	/* Latin-1 encoded string */
+    Py_ssize_t length,	 	/* size of string */
+    const char *errors		/* error handling */
+    );
+
+PyAPI_FUNC(PyObject*) PyUnicode_AsLatin1String(
+    PyObject *unicode	 	/* Unicode object */
+    );
+
+PyAPI_FUNC(PyObject*) PyUnicode_EncodeLatin1(
+    const Py_UNICODE *data, 	/* Unicode char buffer */
+    Py_ssize_t length,	 		/* Number of Py_UNICODE chars to encode */
+    const char *errors		/* error handling */
+    );
+
+/* --- ASCII Codecs ------------------------------------------------------- 
+
+   Only 7-bit ASCII data is excepted. All other codes generate errors.
+
+*/
+
+PyAPI_FUNC(PyObject*) PyUnicode_DecodeASCII(
+    const char *string, 	/* ASCII encoded string */
+    Py_ssize_t length,	 	/* size of string */
+    const char *errors		/* error handling */
+    );
+
+PyAPI_FUNC(PyObject*) PyUnicode_AsASCIIString(
+    PyObject *unicode	 	/* Unicode object */
+    );
+
+PyAPI_FUNC(PyObject*) PyUnicode_EncodeASCII(
+    const Py_UNICODE *data, 	/* Unicode char buffer */
+    Py_ssize_t length,	 		/* Number of Py_UNICODE chars to encode */
+    const char *errors		/* error handling */
+    );
+
+/* --- Character Map Codecs ----------------------------------------------- 
+
+   This codec uses mappings to encode and decode characters. 
+
+   Decoding mappings must map single string characters to single
+   Unicode characters, integers (which are then interpreted as Unicode
+   ordinals) or None (meaning "undefined mapping" and causing an
+   error).
+
+   Encoding mappings must map single Unicode characters to single
+   string characters, integers (which are then interpreted as Latin-1
+   ordinals) or None (meaning "undefined mapping" and causing an
+   error).
+
+   If a character lookup fails with a LookupError, the character is
+   copied as-is meaning that its ordinal value will be interpreted as
+   Unicode or Latin-1 ordinal resp. Because of this mappings only need
+   to contain those mappings which map characters to different code
+   points.
+
+*/
+
+PyAPI_FUNC(PyObject*) PyUnicode_DecodeCharmap(
+    const char *string, 	/* Encoded string */
+    Py_ssize_t length,	 	/* size of string */
+    PyObject *mapping,		/* character mapping 
+				   (char ordinal -> unicode ordinal) */
+    const char *errors		/* error handling */
+    );
+
+PyAPI_FUNC(PyObject*) PyUnicode_AsCharmapString(
+    PyObject *unicode,	 	/* Unicode object */
+    PyObject *mapping		/* character mapping 
+				   (unicode ordinal -> char ordinal) */
+    );
+
+PyAPI_FUNC(PyObject*) PyUnicode_EncodeCharmap(
+    const Py_UNICODE *data, 	/* Unicode char buffer */
+    Py_ssize_t length,	 	/* Number of Py_UNICODE chars to encode */
+    PyObject *mapping,		/* character mapping 
+				   (unicode ordinal -> char ordinal) */
+    const char *errors		/* error handling */
+    );
+
+/* Translate a Py_UNICODE buffer of the given length by applying a
+   character mapping table to it and return the resulting Unicode
+   object.
+
+   The mapping table must map Unicode ordinal integers to Unicode
+   ordinal integers or None (causing deletion of the character). 
+
+   Mapping tables may be dictionaries or sequences. Unmapped character
+   ordinals (ones which cause a LookupError) are left untouched and
+   are copied as-is.
+
+*/
+
+PyAPI_FUNC(PyObject *) PyUnicode_TranslateCharmap(
+    const Py_UNICODE *data, 	/* Unicode char buffer */
+    Py_ssize_t length,	 		/* Number of Py_UNICODE chars to encode */
+    PyObject *table,		/* Translate table */
+    const char *errors		/* error handling */
+    );
+
+#ifdef MS_WIN32
+
+/* --- MBCS codecs for Windows -------------------------------------------- */
+
+PyAPI_FUNC(PyObject*) PyUnicode_DecodeMBCS(
+    const char *string,         /* MBCS encoded string */
+    Py_ssize_t length,              /* size of string */
+    const char *errors          /* error handling */
+    );
+
+PyAPI_FUNC(PyObject*) PyUnicode_DecodeMBCSStateful(
+    const char *string,         /* MBCS encoded string */
+    Py_ssize_t length,          /* size of string */
+    const char *errors,         /* error handling */
+    Py_ssize_t *consumed        /* bytes consumed */
+    );
+
+PyAPI_FUNC(PyObject*) PyUnicode_AsMBCSString(
+    PyObject *unicode           /* Unicode object */
+    );
+
+PyAPI_FUNC(PyObject*) PyUnicode_EncodeMBCS(
+    const Py_UNICODE *data,     /* Unicode char buffer */
+    Py_ssize_t length,              /* Number of Py_UNICODE chars to encode */
+    const char *errors          /* error handling */
+    );
+
+#endif /* MS_WIN32 */
+
+/* --- Decimal Encoder ---------------------------------------------------- */
+
+/* Takes a Unicode string holding a decimal value and writes it into
+   an output buffer using standard ASCII digit codes.
+
+   The output buffer has to provide at least length+1 bytes of storage
+   area. The output string is 0-terminated.
+
+   The encoder converts whitespace to ' ', decimal characters to their
+   corresponding ASCII digit and all other Latin-1 characters except
+   \0 as-is. Characters outside this range (Unicode ordinals 1-256)
+   are treated as errors. This includes embedded NULL bytes.
+
+   Error handling is defined by the errors argument:
+
+      NULL or "strict": raise a ValueError
+      "ignore": ignore the wrong characters (these are not copied to the
+		output buffer)
+      "replace": replaces illegal characters with '?'
+
+   Returns 0 on success, -1 on failure.
+
+*/
+
+PyAPI_FUNC(int) PyUnicode_EncodeDecimal(
+    Py_UNICODE *s,		/* Unicode buffer */
+    Py_ssize_t length,			/* Number of Py_UNICODE chars to encode */
+    char *output,		/* Output buffer; must have size >= length */
+    const char *errors		/* error handling */
+    );
+
+/* --- Methods & Slots ----------------------------------------------------
+
+   These are capable of handling Unicode objects and strings on input
+   (we refer to them as strings in the descriptions) and return
+   Unicode objects or integers as apporpriate. */
+
+/* Concat two strings giving a new Unicode string. */
+
+PyAPI_FUNC(PyObject*) PyUnicode_Concat(
+    PyObject *left,	 	/* Left string */
+    PyObject *right	 	/* Right string */
+    );
+
+/* Split a string giving a list of Unicode strings.
+
+   If sep is NULL, splitting will be done at all whitespace
+   substrings. Otherwise, splits occur at the given separator.
+
+   At most maxsplit splits will be done. If negative, no limit is set.
+
+   Separators are not included in the resulting list.
+
+*/
+
+PyAPI_FUNC(PyObject*) PyUnicode_Split(
+    PyObject *s,		/* String to split */
+    PyObject *sep,		/* String separator */
+    Py_ssize_t maxsplit		/* Maxsplit count */
+    );		
+
+/* Dito, but split at line breaks.
+
+   CRLF is considered to be one line break. Line breaks are not
+   included in the resulting list. */
+    
+PyAPI_FUNC(PyObject*) PyUnicode_Splitlines(
+    PyObject *s,		/* String to split */
+    int keepends		/* If true, line end markers are included */
+    );		
+
+/* Partition a string using a given separator. */
+
+PyAPI_FUNC(PyObject*) PyUnicode_Partition(
+    PyObject *s,		/* String to partition */
+    PyObject *sep		/* String separator */
+    );		
+
+/* Partition a string using a given separator, searching from the end of the
+   string. */
+
+PyAPI_FUNC(PyObject*) PyUnicode_RPartition(
+    PyObject *s,		/* String to partition */
+    PyObject *sep		/* String separator */
+    );		
+
+/* Split a string giving a list of Unicode strings.
+
+   If sep is NULL, splitting will be done at all whitespace
+   substrings. Otherwise, splits occur at the given separator.
+
+   At most maxsplit splits will be done. But unlike PyUnicode_Split
+   PyUnicode_RSplit splits from the end of the string. If negative,
+   no limit is set.
+
+   Separators are not included in the resulting list.
+
+*/
+
+PyAPI_FUNC(PyObject*) PyUnicode_RSplit(
+    PyObject *s,		/* String to split */
+    PyObject *sep,		/* String separator */
+    Py_ssize_t maxsplit		/* Maxsplit count */
+    );		
+
+/* Translate a string by applying a character mapping table to it and
+   return the resulting Unicode object.
+
+   The mapping table must map Unicode ordinal integers to Unicode
+   ordinal integers or None (causing deletion of the character). 
+
+   Mapping tables may be dictionaries or sequences. Unmapped character
+   ordinals (ones which cause a LookupError) are left untouched and
+   are copied as-is.
+
+*/
+
+PyAPI_FUNC(PyObject *) PyUnicode_Translate(
+    PyObject *str,		/* String */ 
+    PyObject *table,		/* Translate table */
+    const char *errors		/* error handling */
+    );
+
+/* Join a sequence of strings using the given separator and return
+   the resulting Unicode string. */
+    
+PyAPI_FUNC(PyObject*) PyUnicode_Join(
+    PyObject *separator, 	/* Separator string */
+    PyObject *seq	 	/* Sequence object */
+    );
+
+/* Return 1 if substr matches str[start:end] at the given tail end, 0
+   otherwise. */
+
+PyAPI_FUNC(Py_ssize_t) PyUnicode_Tailmatch(
+    PyObject *str,		/* String */ 
+    PyObject *substr,		/* Prefix or Suffix string */
+    Py_ssize_t start,		/* Start index */
+    Py_ssize_t end,		/* Stop index */
+    int direction		/* Tail end: -1 prefix, +1 suffix */
+    );
+
+/* Return the first position of substr in str[start:end] using the
+   given search direction or -1 if not found. -2 is returned in case
+   an error occurred and an exception is set. */
+
+PyAPI_FUNC(Py_ssize_t) PyUnicode_Find(
+    PyObject *str,		/* String */ 
+    PyObject *substr,		/* Substring to find */
+    Py_ssize_t start,		/* Start index */
+    Py_ssize_t end,		/* Stop index */
+    int direction		/* Find direction: +1 forward, -1 backward */
+    );
+
+/* Count the number of occurrences of substr in str[start:end]. */
+
+PyAPI_FUNC(Py_ssize_t) PyUnicode_Count(
+    PyObject *str,		/* String */ 
+    PyObject *substr,		/* Substring to count */
+    Py_ssize_t start,		/* Start index */
+    Py_ssize_t end		/* Stop index */
+    );
+
+/* Replace at most maxcount occurrences of substr in str with replstr
+   and return the resulting Unicode object. */
+
+PyAPI_FUNC(PyObject *) PyUnicode_Replace(
+    PyObject *str,		/* String */ 
+    PyObject *substr,		/* Substring to find */
+    PyObject *replstr,		/* Substring to replace */
+    Py_ssize_t maxcount		/* Max. number of replacements to apply;
+				   -1 = all */
+    );
+
+/* Compare two strings and return -1, 0, 1 for less than, equal,
+   greater than resp. */
+
+PyAPI_FUNC(int) PyUnicode_Compare(
+    PyObject *left,		/* Left string */ 
+    PyObject *right		/* Right string */
+    );
+
+/* Rich compare two strings and return one of the following:
+
+   - NULL in case an exception was raised
+   - Py_True or Py_False for successfuly comparisons
+   - Py_NotImplemented in case the type combination is unknown
+
+   Note that Py_EQ and Py_NE comparisons can cause a UnicodeWarning in
+   case the conversion of the arguments to Unicode fails with a
+   UnicodeDecodeError.
+
+   Possible values for op:
+
+     Py_GT, Py_GE, Py_EQ, Py_NE, Py_LT, Py_LE
+
+*/
+
+PyAPI_FUNC(PyObject *) PyUnicode_RichCompare(
+    PyObject *left,		/* Left string */ 
+    PyObject *right,		/* Right string */
+    int op			/* Operation: Py_EQ, Py_NE, Py_GT, etc. */
+    );
+
+/* Apply a argument tuple or dictionary to a format string and return
+   the resulting Unicode string. */
+
+PyAPI_FUNC(PyObject *) PyUnicode_Format(
+    PyObject *format,		/* Format string */ 
+    PyObject *args		/* Argument tuple or dictionary */
+    );
+
+/* Checks whether element is contained in container and return 1/0
+   accordingly.
+
+   element has to coerce to an one element Unicode string. -1 is
+   returned in case of an error. */
+
+PyAPI_FUNC(int) PyUnicode_Contains(
+    PyObject *container,	/* Container string */ 
+    PyObject *element		/* Element string */
+    );
+
+/* Externally visible for str.strip(unicode) */
+PyAPI_FUNC(PyObject *) _PyUnicode_XStrip(
+    PyUnicodeObject *self,
+    int striptype,
+    PyObject *sepobj
+    );
+
+/* === Characters Type APIs =============================================== */
+
+/* These should not be used directly. Use the Py_UNICODE_IS* and
+   Py_UNICODE_TO* macros instead. 
+
+   These APIs are implemented in Objects/unicodectype.c.
+
+*/
+
+PyAPI_FUNC(int) _PyUnicode_IsLowercase(
+    Py_UNICODE ch 	/* Unicode character */
+    );
+
+PyAPI_FUNC(int) _PyUnicode_IsUppercase(
+    Py_UNICODE ch 	/* Unicode character */
+    );
+
+PyAPI_FUNC(int) _PyUnicode_IsTitlecase(
+    Py_UNICODE ch 	/* Unicode character */
+    );
+
+PyAPI_FUNC(int) _PyUnicode_IsWhitespace(
+    const Py_UNICODE ch 	/* Unicode character */
+    );
+
+PyAPI_FUNC(int) _PyUnicode_IsLinebreak(
+    const Py_UNICODE ch 	/* Unicode character */
+    );
+
+PyAPI_FUNC(Py_UNICODE) _PyUnicode_ToLowercase(
+    Py_UNICODE ch 	/* Unicode character */
+    );
+
+PyAPI_FUNC(Py_UNICODE) _PyUnicode_ToUppercase(
+    Py_UNICODE ch 	/* Unicode character */
+    );
+
+PyAPI_FUNC(Py_UNICODE) _PyUnicode_ToTitlecase(
+    Py_UNICODE ch 	/* Unicode character */
+    );
+
+PyAPI_FUNC(int) _PyUnicode_ToDecimalDigit(
+    Py_UNICODE ch 	/* Unicode character */
+    );
+
+PyAPI_FUNC(int) _PyUnicode_ToDigit(
+    Py_UNICODE ch 	/* Unicode character */
+    );
+
+PyAPI_FUNC(double) _PyUnicode_ToNumeric(
+    Py_UNICODE ch 	/* Unicode character */
+    );
+
+PyAPI_FUNC(int) _PyUnicode_IsDecimalDigit(
+    Py_UNICODE ch 	/* Unicode character */
+    );
+
+PyAPI_FUNC(int) _PyUnicode_IsDigit(
+    Py_UNICODE ch 	/* Unicode character */
+    );
+
+PyAPI_FUNC(int) _PyUnicode_IsNumeric(
+    Py_UNICODE ch 	/* Unicode character */
+    );
+
+PyAPI_FUNC(int) _PyUnicode_IsAlpha(
+    Py_UNICODE ch 	/* Unicode character */
+    );
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* Py_USING_UNICODE */
+#endif /* !Py_UNICODEOBJECT_H */

Added: vendor/Python/current/Include/weakrefobject.h
===================================================================
--- vendor/Python/current/Include/weakrefobject.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Include/weakrefobject.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,75 @@
+/* Weak references objects for Python. */
+
+#ifndef Py_WEAKREFOBJECT_H
+#define Py_WEAKREFOBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+typedef struct _PyWeakReference PyWeakReference;
+
+/* PyWeakReference is the base struct for the Python ReferenceType, ProxyType,
+ * and CallableProxyType.
+ */
+struct _PyWeakReference {
+    PyObject_HEAD
+
+    /* The object to which this is a weak reference, or Py_None if none.
+     * Note that this is a stealth reference:  wr_object's refcount is
+     * not incremented to reflect this pointer.
+     */
+    PyObject *wr_object;
+
+    /* A callable to invoke when wr_object dies, or NULL if none. */
+    PyObject *wr_callback;
+
+    /* A cache for wr_object's hash code.  As usual for hashes, this is -1
+     * if the hash code isn't known yet.
+     */
+    long hash;
+
+    /* If wr_object is weakly referenced, wr_object has a doubly-linked NULL-
+     * terminated list of weak references to it.  These are the list pointers.
+     * If wr_object goes away, wr_object is set to Py_None, and these pointers
+     * have no meaning then.
+     */
+    PyWeakReference *wr_prev;
+    PyWeakReference *wr_next;
+};
+
+PyAPI_DATA(PyTypeObject) _PyWeakref_RefType;
+PyAPI_DATA(PyTypeObject) _PyWeakref_ProxyType;
+PyAPI_DATA(PyTypeObject) _PyWeakref_CallableProxyType;
+
+#define PyWeakref_CheckRef(op) PyObject_TypeCheck(op, &_PyWeakref_RefType)
+#define PyWeakref_CheckRefExact(op) \
+        ((op)->ob_type == &_PyWeakref_RefType)
+#define PyWeakref_CheckProxy(op) \
+        (((op)->ob_type == &_PyWeakref_ProxyType) || \
+         ((op)->ob_type == &_PyWeakref_CallableProxyType))
+
+/* This macro calls PyWeakref_CheckRef() last since that can involve a
+   function call; this makes it more likely that the function call
+   will be avoided. */
+#define PyWeakref_Check(op) \
+        (PyWeakref_CheckRef(op) || PyWeakref_CheckProxy(op))
+
+
+PyAPI_FUNC(PyObject *) PyWeakref_NewRef(PyObject *ob,
+                                              PyObject *callback);
+PyAPI_FUNC(PyObject *) PyWeakref_NewProxy(PyObject *ob,
+                                                PyObject *callback);
+PyAPI_FUNC(PyObject *) PyWeakref_GetObject(PyObject *ref);
+
+PyAPI_FUNC(Py_ssize_t) _PyWeakref_GetWeakrefCount(PyWeakReference *head);
+
+PyAPI_FUNC(void) _PyWeakref_ClearRef(PyWeakReference *self);
+
+#define PyWeakref_GET_OBJECT(ref) (((PyWeakReference *)(ref))->wr_object)
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_WEAKREFOBJECT_H */

Added: vendor/Python/current/LICENSE
===================================================================
--- vendor/Python/current/LICENSE	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/LICENSE	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,270 @@
+A. HISTORY OF THE SOFTWARE
+==========================
+
+Python was created in the early 1990s by Guido van Rossum at Stichting
+Mathematisch Centrum (CWI, see http://www.cwi.nl) in the Netherlands
+as a successor of a language called ABC.  Guido remains Python's
+principal author, although it includes many contributions from others.
+
+In 1995, Guido continued his work on Python at the Corporation for
+National Research Initiatives (CNRI, see http://www.cnri.reston.va.us)
+in Reston, Virginia where he released several versions of the
+software.
+
+In May 2000, Guido and the Python core development team moved to
+BeOpen.com to form the BeOpen PythonLabs team.  In October of the same
+year, the PythonLabs team moved to Digital Creations (now Zope
+Corporation, see http://www.zope.com).  In 2001, the Python Software
+Foundation (PSF, see http://www.python.org/psf/) was formed, a
+non-profit organization created specifically to own Python-related
+Intellectual Property.  Zope Corporation is a sponsoring member of
+the PSF.
+
+All Python releases are Open Source (see http://www.opensource.org for
+the Open Source Definition).  Historically, most, but not all, Python
+releases have also been GPL-compatible; the table below summarizes
+the various releases.
+
+    Release         Derived     Year        Owner       GPL-
+                    from                                compatible? (1)
+
+    0.9.0 thru 1.2              1991-1995   CWI         yes
+    1.3 thru 1.5.2  1.2         1995-1999   CNRI        yes
+    1.6             1.5.2       2000        CNRI        no
+    2.0             1.6         2000        BeOpen.com  no
+    1.6.1           1.6         2001        CNRI        yes (2)
+    2.1             2.0+1.6.1   2001        PSF         no
+    2.0.1           2.0+1.6.1   2001        PSF         yes
+    2.1.1           2.1+2.0.1   2001        PSF         yes
+    2.2             2.1.1       2001        PSF         yes
+    2.1.2           2.1.1       2002        PSF         yes
+    2.1.3           2.1.2       2002        PSF         yes
+    2.2.1           2.2         2002        PSF         yes
+    2.2.2           2.2.1       2002        PSF         yes
+    2.2.3           2.2.2       2003        PSF         yes
+    2.3             2.2.2       2002-2003   PSF         yes
+    2.3.1           2.3         2002-2003   PSF         yes
+    2.3.2           2.3.1       2002-2003   PSF         yes
+    2.3.3           2.3.2       2002-2003   PSF         yes
+    2.3.4           2.3.3       2004        PSF         yes
+    2.3.5           2.3.4       2005        PSF         yes
+    2.4             2.3         2004        PSF         yes
+    2.4.1           2.4         2005        PSF         yes
+    2.4.2           2.4.1       2005        PSF         yes
+    2.4.3           2.4.2       2006        PSF         yes
+    2.5             2.4         2006        PSF         yes
+    2.5.1           2.5         2007        PSF         yes
+
+Footnotes:
+
+(1) GPL-compatible doesn't mean that we're distributing Python under
+    the GPL.  All Python licenses, unlike the GPL, let you distribute
+    a modified version without making your changes open source.  The
+    GPL-compatible licenses make it possible to combine Python with
+    other software that is released under the GPL; the others don't.
+
+(2) According to Richard Stallman, 1.6.1 is not GPL-compatible,
+    because its license has a choice of law clause.  According to
+    CNRI, however, Stallman's lawyer has told CNRI's lawyer that 1.6.1
+    is "not incompatible" with the GPL.
+
+Thanks to the many outside volunteers who have worked under Guido's
+direction to make these releases possible.
+
+
+B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON
+===============================================================
+
+PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
+--------------------------------------------
+
+1. This LICENSE AGREEMENT is between the Python Software Foundation
+("PSF"), and the Individual or Organization ("Licensee") accessing and
+otherwise using this software ("Python") in source or binary form and
+its associated documentation.
+
+2. Subject to the terms and conditions of this License Agreement, PSF
+hereby grants Licensee a nonexclusive, royalty-free, world-wide
+license to reproduce, analyze, test, perform and/or display publicly,
+prepare derivative works, distribute, and otherwise use Python
+alone or in any derivative version, provided, however, that PSF's
+License Agreement and PSF's notice of copyright, i.e., "Copyright (c)
+2001, 2002, 2003, 2004, 2005, 2006, 2007 Python Software Foundation; 
+All Rights Reserved" are retained in Python alone or in any derivative 
+version prepared by Licensee.
+
+3. In the event Licensee prepares a derivative work that is based on
+or incorporates Python or any part thereof, and wants to make
+the derivative work available to others as provided herein, then
+Licensee hereby agrees to include in any such work a brief summary of
+the changes made to Python.
+
+4. PSF is making Python available to Licensee on an "AS IS"
+basis.  PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
+DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT
+INFRINGE ANY THIRD PARTY RIGHTS.
+
+5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
+FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
+A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,
+OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+6. This License Agreement will automatically terminate upon a material
+breach of its terms and conditions.
+
+7. Nothing in this License Agreement shall be deemed to create any
+relationship of agency, partnership, or joint venture between PSF and
+Licensee.  This License Agreement does not grant permission to use PSF
+trademarks or trade name in a trademark sense to endorse or promote
+products or services of Licensee, or any third party.
+
+8. By copying, installing or otherwise using Python, Licensee
+agrees to be bound by the terms and conditions of this License
+Agreement.
+
+
+BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0
+-------------------------------------------
+
+BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1
+
+1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an
+office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the
+Individual or Organization ("Licensee") accessing and otherwise using
+this software in source or binary form and its associated
+documentation ("the Software").
+
+2. Subject to the terms and conditions of this BeOpen Python License
+Agreement, BeOpen hereby grants Licensee a non-exclusive,
+royalty-free, world-wide license to reproduce, analyze, test, perform
+and/or display publicly, prepare derivative works, distribute, and
+otherwise use the Software alone or in any derivative version,
+provided, however, that the BeOpen Python License is retained in the
+Software, alone or in any derivative version prepared by Licensee.
+
+3. BeOpen is making the Software available to Licensee on an "AS IS"
+basis.  BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND
+DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT
+INFRINGE ANY THIRD PARTY RIGHTS.
+
+4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE
+SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS
+AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY
+DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+5. This License Agreement will automatically terminate upon a material
+breach of its terms and conditions.
+
+6. This License Agreement shall be governed by and interpreted in all
+respects by the law of the State of California, excluding conflict of
+law provisions.  Nothing in this License Agreement shall be deemed to
+create any relationship of agency, partnership, or joint venture
+between BeOpen and Licensee.  This License Agreement does not grant
+permission to use BeOpen trademarks or trade names in a trademark
+sense to endorse or promote products or services of Licensee, or any
+third party.  As an exception, the "BeOpen Python" logos available at
+http://www.pythonlabs.com/logos.html may be used according to the
+permissions granted on that web page.
+
+7. By copying, installing or otherwise using the software, Licensee
+agrees to be bound by the terms and conditions of this License
+Agreement.
+
+
+CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1
+---------------------------------------
+
+1. This LICENSE AGREEMENT is between the Corporation for National
+Research Initiatives, having an office at 1895 Preston White Drive,
+Reston, VA 20191 ("CNRI"), and the Individual or Organization
+("Licensee") accessing and otherwise using Python 1.6.1 software in
+source or binary form and its associated documentation.
+
+2. Subject to the terms and conditions of this License Agreement, CNRI
+hereby grants Licensee a nonexclusive, royalty-free, world-wide
+license to reproduce, analyze, test, perform and/or display publicly,
+prepare derivative works, distribute, and otherwise use Python 1.6.1
+alone or in any derivative version, provided, however, that CNRI's
+License Agreement and CNRI's notice of copyright, i.e., "Copyright (c)
+1995-2001 Corporation for National Research Initiatives; All Rights
+Reserved" are retained in Python 1.6.1 alone or in any derivative
+version prepared by Licensee.  Alternately, in lieu of CNRI's License
+Agreement, Licensee may substitute the following text (omitting the
+quotes): "Python 1.6.1 is made available subject to the terms and
+conditions in CNRI's License Agreement.  This Agreement together with
+Python 1.6.1 may be located on the Internet using the following
+unique, persistent identifier (known as a handle): 1895.22/1013.  This
+Agreement may also be obtained from a proxy server on the Internet
+using the following URL: http://hdl.handle.net/1895.22/1013".
+
+3. In the event Licensee prepares a derivative work that is based on
+or incorporates Python 1.6.1 or any part thereof, and wants to make
+the derivative work available to others as provided herein, then
+Licensee hereby agrees to include in any such work a brief summary of
+the changes made to Python 1.6.1.
+
+4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS"
+basis.  CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND
+DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT
+INFRINGE ANY THIRD PARTY RIGHTS.
+
+5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
+1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
+A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1,
+OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+6. This License Agreement will automatically terminate upon a material
+breach of its terms and conditions.
+
+7. This License Agreement shall be governed by the federal
+intellectual property law of the United States, including without
+limitation the federal copyright law, and, to the extent such
+U.S. federal law does not apply, by the law of the Commonwealth of
+Virginia, excluding Virginia's conflict of law provisions.
+Notwithstanding the foregoing, with regard to derivative works based
+on Python 1.6.1 that incorporate non-separable material that was
+previously distributed under the GNU General Public License (GPL), the
+law of the Commonwealth of Virginia shall govern this License
+Agreement only as to issues arising under or with respect to
+Paragraphs 4, 5, and 7 of this License Agreement.  Nothing in this
+License Agreement shall be deemed to create any relationship of
+agency, partnership, or joint venture between CNRI and Licensee.  This
+License Agreement does not grant permission to use CNRI trademarks or
+trade name in a trademark sense to endorse or promote products or
+services of Licensee, or any third party.
+
+8. By clicking on the "ACCEPT" button where indicated, or by copying,
+installing or otherwise using Python 1.6.1, Licensee agrees to be
+bound by the terms and conditions of this License Agreement.
+
+        ACCEPT
+
+
+CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2
+--------------------------------------------------
+
+Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam,
+The Netherlands.  All rights reserved.
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Stichting Mathematisch
+Centrum or CWI not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
+THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
+FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

Added: vendor/Python/current/Lib/BaseHTTPServer.py
===================================================================
--- vendor/Python/current/Lib/BaseHTTPServer.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/BaseHTTPServer.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,578 @@
+"""HTTP server base class.
+
+Note: the class in this module doesn't implement any HTTP request; see
+SimpleHTTPServer for simple implementations of GET, HEAD and POST
+(including CGI scripts).  It does, however, optionally implement HTTP/1.1
+persistent connections, as of version 0.3.
+
+Contents:
+
+- BaseHTTPRequestHandler: HTTP request handler base class
+- test: test function
+
+XXX To do:
+
+- log requests even later (to capture byte count)
+- log user-agent header and other interesting goodies
+- send error log to separate file
+"""
+
+
+# See also:
+#
+# HTTP Working Group                                        T. Berners-Lee
+# INTERNET-DRAFT                                            R. T. Fielding
+# <draft-ietf-http-v10-spec-00.txt>                     H. Frystyk Nielsen
+# Expires September 8, 1995                                  March 8, 1995
+#
+# URL: http://www.ics.uci.edu/pub/ietf/http/draft-ietf-http-v10-spec-00.txt
+#
+# and
+#
+# Network Working Group                                      R. Fielding
+# Request for Comments: 2616                                       et al
+# Obsoletes: 2068                                              June 1999
+# Category: Standards Track
+#
+# URL: http://www.faqs.org/rfcs/rfc2616.html
+
+# Log files
+# ---------
+#
+# Here's a quote from the NCSA httpd docs about log file format.
+#
+# | The logfile format is as follows. Each line consists of:
+# |
+# | host rfc931 authuser [DD/Mon/YYYY:hh:mm:ss] "request" ddd bbbb
+# |
+# |        host: Either the DNS name or the IP number of the remote client
+# |        rfc931: Any information returned by identd for this person,
+# |                - otherwise.
+# |        authuser: If user sent a userid for authentication, the user name,
+# |                  - otherwise.
+# |        DD: Day
+# |        Mon: Month (calendar name)
+# |        YYYY: Year
+# |        hh: hour (24-hour format, the machine's timezone)
+# |        mm: minutes
+# |        ss: seconds
+# |        request: The first line of the HTTP request as sent by the client.
+# |        ddd: the status code returned by the server, - if not available.
+# |        bbbb: the total number of bytes sent,
+# |              *not including the HTTP/1.0 header*, - if not available
+# |
+# | You can determine the name of the file accessed through request.
+#
+# (Actually, the latter is only true if you know the server configuration
+# at the time the request was made!)
+
+__version__ = "0.3"
+
+__all__ = ["HTTPServer", "BaseHTTPRequestHandler"]
+
+import sys
+import time
+import socket # For gethostbyaddr()
+import mimetools
+import SocketServer
+
+# Default error message
+DEFAULT_ERROR_MESSAGE = """\
+<head>
+<title>Error response</title>
+</head>
+<body>
+<h1>Error response</h1>
+<p>Error code %(code)d.
+<p>Message: %(message)s.
+<p>Error code explanation: %(code)s = %(explain)s.
+</body>
+"""
+
+def _quote_html(html):
+    return html.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;")
+
+class HTTPServer(SocketServer.TCPServer):
+
+    allow_reuse_address = 1    # Seems to make sense in testing environment
+
+    def server_bind(self):
+        """Override server_bind to store the server name."""
+        SocketServer.TCPServer.server_bind(self)
+        host, port = self.socket.getsockname()[:2]
+        self.server_name = socket.getfqdn(host)
+        self.server_port = port
+
+
+class BaseHTTPRequestHandler(SocketServer.StreamRequestHandler):
+
+    """HTTP request handler base class.
+
+    The following explanation of HTTP serves to guide you through the
+    code as well as to expose any misunderstandings I may have about
+    HTTP (so you don't need to read the code to figure out I'm wrong
+    :-).
+
+    HTTP (HyperText Transfer Protocol) is an extensible protocol on
+    top of a reliable stream transport (e.g. TCP/IP).  The protocol
+    recognizes three parts to a request:
+
+    1. One line identifying the request type and path
+    2. An optional set of RFC-822-style headers
+    3. An optional data part
+
+    The headers and data are separated by a blank line.
+
+    The first line of the request has the form
+
+    <command> <path> <version>
+
+    where <command> is a (case-sensitive) keyword such as GET or POST,
+    <path> is a string containing path information for the request,
+    and <version> should be the string "HTTP/1.0" or "HTTP/1.1".
+    <path> is encoded using the URL encoding scheme (using %xx to signify
+    the ASCII character with hex code xx).
+
+    The specification specifies that lines are separated by CRLF but
+    for compatibility with the widest range of clients recommends
+    servers also handle LF.  Similarly, whitespace in the request line
+    is treated sensibly (allowing multiple spaces between components
+    and allowing trailing whitespace).
+
+    Similarly, for output, lines ought to be separated by CRLF pairs
+    but most clients grok LF characters just fine.
+
+    If the first line of the request has the form
+
+    <command> <path>
+
+    (i.e. <version> is left out) then this is assumed to be an HTTP
+    0.9 request; this form has no optional headers and data part and
+    the reply consists of just the data.
+
+    The reply form of the HTTP 1.x protocol again has three parts:
+
+    1. One line giving the response code
+    2. An optional set of RFC-822-style headers
+    3. The data
+
+    Again, the headers and data are separated by a blank line.
+
+    The response code line has the form
+
+    <version> <responsecode> <responsestring>
+
+    where <version> is the protocol version ("HTTP/1.0" or "HTTP/1.1"),
+    <responsecode> is a 3-digit response code indicating success or
+    failure of the request, and <responsestring> is an optional
+    human-readable string explaining what the response code means.
+
+    This server parses the request and the headers, and then calls a
+    function specific to the request type (<command>).  Specifically,
+    a request SPAM will be handled by a method do_SPAM().  If no
+    such method exists the server sends an error response to the
+    client.  If it exists, it is called with no arguments:
+
+    do_SPAM()
+
+    Note that the request name is case sensitive (i.e. SPAM and spam
+    are different requests).
+
+    The various request details are stored in instance variables:
+
+    - client_address is the client IP address in the form (host,
+    port);
+
+    - command, path and version are the broken-down request line;
+
+    - headers is an instance of mimetools.Message (or a derived
+    class) containing the header information;
+
+    - rfile is a file object open for reading positioned at the
+    start of the optional input data part;
+
+    - wfile is a file object open for writing.
+
+    IT IS IMPORTANT TO ADHERE TO THE PROTOCOL FOR WRITING!
+
+    The first thing to be written must be the response line.  Then
+    follow 0 or more header lines, then a blank line, and then the
+    actual data (if any).  The meaning of the header lines depends on
+    the command executed by the server; in most cases, when data is
+    returned, there should be at least one header line of the form
+
+    Content-type: <type>/<subtype>
+
+    where <type> and <subtype> should be registered MIME types,
+    e.g. "text/html" or "text/plain".
+
+    """
+
+    # The Python system version, truncated to its first component.
+    sys_version = "Python/" + sys.version.split()[0]
+
+    # The server software version.  You may want to override this.
+    # The format is multiple whitespace-separated strings,
+    # where each string is of the form name[/version].
+    server_version = "BaseHTTP/" + __version__
+
+    def parse_request(self):
+        """Parse a request (internal).
+
+        The request should be stored in self.raw_requestline; the results
+        are in self.command, self.path, self.request_version and
+        self.headers.
+
+        Return True for success, False for failure; on failure, an
+        error is sent back.
+
+        """
+        self.command = None  # set in case of error on the first line
+        self.request_version = version = "HTTP/0.9" # Default
+        self.close_connection = 1
+        requestline = self.raw_requestline
+        if requestline[-2:] == '\r\n':
+            requestline = requestline[:-2]
+        elif requestline[-1:] == '\n':
+            requestline = requestline[:-1]
+        self.requestline = requestline
+        words = requestline.split()
+        if len(words) == 3:
+            [command, path, version] = words
+            if version[:5] != 'HTTP/':
+                self.send_error(400, "Bad request version (%r)" % version)
+                return False
+            try:
+                base_version_number = version.split('/', 1)[1]
+                version_number = base_version_number.split(".")
+                # RFC 2145 section 3.1 says there can be only one "." and
+                #   - major and minor numbers MUST be treated as
+                #      separate integers;
+                #   - HTTP/2.4 is a lower version than HTTP/2.13, which in
+                #      turn is lower than HTTP/12.3;
+                #   - Leading zeros MUST be ignored by recipients.
+                if len(version_number) != 2:
+                    raise ValueError
+                version_number = int(version_number[0]), int(version_number[1])
+            except (ValueError, IndexError):
+                self.send_error(400, "Bad request version (%r)" % version)
+                return False
+            if version_number >= (1, 1) and self.protocol_version >= "HTTP/1.1":
+                self.close_connection = 0
+            if version_number >= (2, 0):
+                self.send_error(505,
+                          "Invalid HTTP Version (%s)" % base_version_number)
+                return False
+        elif len(words) == 2:
+            [command, path] = words
+            self.close_connection = 1
+            if command != 'GET':
+                self.send_error(400,
+                                "Bad HTTP/0.9 request type (%r)" % command)
+                return False
+        elif not words:
+            return False
+        else:
+            self.send_error(400, "Bad request syntax (%r)" % requestline)
+            return False
+        self.command, self.path, self.request_version = command, path, version
+
+        # Examine the headers and look for a Connection directive
+        self.headers = self.MessageClass(self.rfile, 0)
+
+        conntype = self.headers.get('Connection', "")
+        if conntype.lower() == 'close':
+            self.close_connection = 1
+        elif (conntype.lower() == 'keep-alive' and
+              self.protocol_version >= "HTTP/1.1"):
+            self.close_connection = 0
+        return True
+
+    def handle_one_request(self):
+        """Handle a single HTTP request.
+
+        You normally don't need to override this method; see the class
+        __doc__ string for information on how to handle specific HTTP
+        commands such as GET and POST.
+
+        """
+        self.raw_requestline = self.rfile.readline()
+        if not self.raw_requestline:
+            self.close_connection = 1
+            return
+        if not self.parse_request(): # An error code has been sent, just exit
+            return
+        mname = 'do_' + self.command
+        if not hasattr(self, mname):
+            self.send_error(501, "Unsupported method (%r)" % self.command)
+            return
+        method = getattr(self, mname)
+        method()
+
+    def handle(self):
+        """Handle multiple requests if necessary."""
+        self.close_connection = 1
+
+        self.handle_one_request()
+        while not self.close_connection:
+            self.handle_one_request()
+
+    def send_error(self, code, message=None):
+        """Send and log an error reply.
+
+        Arguments are the error code, and a detailed message.
+        The detailed message defaults to the short entry matching the
+        response code.
+
+        This sends an error response (so it must be called before any
+        output has been generated), logs the error, and finally sends
+        a piece of HTML explaining the error to the user.
+
+        """
+
+        try:
+            short, long = self.responses[code]
+        except KeyError:
+            short, long = '???', '???'
+        if message is None:
+            message = short
+        explain = long
+        self.log_error("code %d, message %s", code, message)
+        # using _quote_html to prevent Cross Site Scripting attacks (see bug #1100201)
+        content = (self.error_message_format %
+                   {'code': code, 'message': _quote_html(message), 'explain': explain})
+        self.send_response(code, message)
+        self.send_header("Content-Type", "text/html")
+        self.send_header('Connection', 'close')
+        self.end_headers()
+        if self.command != 'HEAD' and code >= 200 and code not in (204, 304):
+            self.wfile.write(content)
+
+    error_message_format = DEFAULT_ERROR_MESSAGE
+
+    def send_response(self, code, message=None):
+        """Send the response header and log the response code.
+
+        Also send two standard headers with the server software
+        version and the current date.
+
+        """
+        self.log_request(code)
+        if message is None:
+            if code in self.responses:
+                message = self.responses[code][0]
+            else:
+                message = ''
+        if self.request_version != 'HTTP/0.9':
+            self.wfile.write("%s %d %s\r\n" %
+                             (self.protocol_version, code, message))
+            # print (self.protocol_version, code, message)
+        self.send_header('Server', self.version_string())
+        self.send_header('Date', self.date_time_string())
+
+    def send_header(self, keyword, value):
+        """Send a MIME header."""
+        if self.request_version != 'HTTP/0.9':
+            self.wfile.write("%s: %s\r\n" % (keyword, value))
+
+        if keyword.lower() == 'connection':
+            if value.lower() == 'close':
+                self.close_connection = 1
+            elif value.lower() == 'keep-alive':
+                self.close_connection = 0
+
+    def end_headers(self):
+        """Send the blank line ending the MIME headers."""
+        if self.request_version != 'HTTP/0.9':
+            self.wfile.write("\r\n")
+
+    def log_request(self, code='-', size='-'):
+        """Log an accepted request.
+
+        This is called by send_response().
+
+        """
+
+        self.log_message('"%s" %s %s',
+                         self.requestline, str(code), str(size))
+
+    def log_error(self, *args):
+        """Log an error.
+
+        This is called when a request cannot be fulfilled.  By
+        default it passes the message on to log_message().
+
+        Arguments are the same as for log_message().
+
+        XXX This should go to the separate error log.
+
+        """
+
+        self.log_message(*args)
+
+    def log_message(self, format, *args):
+        """Log an arbitrary message.
+
+        This is used by all other logging functions.  Override
+        it if you have specific logging wishes.
+
+        The first argument, FORMAT, is a format string for the
+        message to be logged.  If the format string contains
+        any % escapes requiring parameters, they should be
+        specified as subsequent arguments (it's just like
+        printf!).
+
+        The client host and current date/time are prefixed to
+        every message.
+
+        """
+
+        sys.stderr.write("%s - - [%s] %s\n" %
+                         (self.address_string(),
+                          self.log_date_time_string(),
+                          format%args))
+
+    def version_string(self):
+        """Return the server software version string."""
+        return self.server_version + ' ' + self.sys_version
+
+    def date_time_string(self, timestamp=None):
+        """Return the current date and time formatted for a message header."""
+        if timestamp is None:
+            timestamp = time.time()
+        year, month, day, hh, mm, ss, wd, y, z = time.gmtime(timestamp)
+        s = "%s, %02d %3s %4d %02d:%02d:%02d GMT" % (
+                self.weekdayname[wd],
+                day, self.monthname[month], year,
+                hh, mm, ss)
+        return s
+
+    def log_date_time_string(self):
+        """Return the current time formatted for logging."""
+        now = time.time()
+        year, month, day, hh, mm, ss, x, y, z = time.localtime(now)
+        s = "%02d/%3s/%04d %02d:%02d:%02d" % (
+                day, self.monthname[month], year, hh, mm, ss)
+        return s
+
+    weekdayname = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
+
+    monthname = [None,
+                 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
+                 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
+
+    def address_string(self):
+        """Return the client address formatted for logging.
+
+        This version looks up the full hostname using gethostbyaddr(),
+        and tries to find a name that contains at least one dot.
+
+        """
+
+        host, port = self.client_address[:2]
+        return socket.getfqdn(host)
+
+    # Essentially static class variables
+
+    # The version of the HTTP protocol we support.
+    # Set this to HTTP/1.1 to enable automatic keepalive
+    protocol_version = "HTTP/1.0"
+
+    # The Message-like class used to parse headers
+    MessageClass = mimetools.Message
+
+    # Table mapping response codes to messages; entries have the
+    # form {code: (shortmessage, longmessage)}.
+    # See RFC 2616.
+    responses = {
+        100: ('Continue', 'Request received, please continue'),
+        101: ('Switching Protocols',
+              'Switching to new protocol; obey Upgrade header'),
+
+        200: ('OK', 'Request fulfilled, document follows'),
+        201: ('Created', 'Document created, URL follows'),
+        202: ('Accepted',
+              'Request accepted, processing continues off-line'),
+        203: ('Non-Authoritative Information', 'Request fulfilled from cache'),
+        204: ('No Content', 'Request fulfilled, nothing follows'),
+        205: ('Reset Content', 'Clear input form for further input.'),
+        206: ('Partial Content', 'Partial content follows.'),
+
+        300: ('Multiple Choices',
+              'Object has several resources -- see URI list'),
+        301: ('Moved Permanently', 'Object moved permanently -- see URI list'),
+        302: ('Found', 'Object moved temporarily -- see URI list'),
+        303: ('See Other', 'Object moved -- see Method and URL list'),
+        304: ('Not Modified',
+              'Document has not changed since given time'),
+        305: ('Use Proxy',
+              'You must use proxy specified in Location to access this '
+              'resource.'),
+        307: ('Temporary Redirect',
+              'Object moved temporarily -- see URI list'),
+
+        400: ('Bad Request',
+              'Bad request syntax or unsupported method'),
+        401: ('Unauthorized',
+              'No permission -- see authorization schemes'),
+        402: ('Payment Required',
+              'No payment -- see charging schemes'),
+        403: ('Forbidden',
+              'Request forbidden -- authorization will not help'),
+        404: ('Not Found', 'Nothing matches the given URI'),
+        405: ('Method Not Allowed',
+              'Specified method is invalid for this server.'),
+        406: ('Not Acceptable', 'URI not available in preferred format.'),
+        407: ('Proxy Authentication Required', 'You must authenticate with '
+              'this proxy before proceeding.'),
+        408: ('Request Timeout', 'Request timed out; try again later.'),
+        409: ('Conflict', 'Request conflict.'),
+        410: ('Gone',
+              'URI no longer exists and has been permanently removed.'),
+        411: ('Length Required', 'Client must specify Content-Length.'),
+        412: ('Precondition Failed', 'Precondition in headers is false.'),
+        413: ('Request Entity Too Large', 'Entity is too large.'),
+        414: ('Request-URI Too Long', 'URI is too long.'),
+        415: ('Unsupported Media Type', 'Entity body in unsupported format.'),
+        416: ('Requested Range Not Satisfiable',
+              'Cannot satisfy request range.'),
+        417: ('Expectation Failed',
+              'Expect condition could not be satisfied.'),
+
+        500: ('Internal Server Error', 'Server got itself in trouble'),
+        501: ('Not Implemented',
+              'Server does not support this operation'),
+        502: ('Bad Gateway', 'Invalid responses from another server/proxy.'),
+        503: ('Service Unavailable',
+              'The server cannot process the request due to a high load'),
+        504: ('Gateway Timeout',
+              'The gateway server did not receive a timely response'),
+        505: ('HTTP Version Not Supported', 'Cannot fulfill request.'),
+        }
+
+
+def test(HandlerClass = BaseHTTPRequestHandler,
+         ServerClass = HTTPServer, protocol="HTTP/1.0"):
+    """Test the HTTP request handler class.
+
+    This runs an HTTP server on port 8000 (or the first command line
+    argument).
+
+    """
+
+    if sys.argv[1:]:
+        port = int(sys.argv[1])
+    else:
+        port = 8000
+    server_address = ('', port)
+
+    HandlerClass.protocol_version = protocol
+    httpd = ServerClass(server_address, HandlerClass)
+
+    sa = httpd.socket.getsockname()
+    print "Serving HTTP on", sa[0], "port", sa[1], "..."
+    httpd.serve_forever()
+
+
+if __name__ == '__main__':
+    test()

Added: vendor/Python/current/Lib/Bastion.py
===================================================================
--- vendor/Python/current/Lib/Bastion.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/Bastion.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,177 @@
+"""Bastionification utility.
+
+A bastion (for another object -- the 'original') is an object that has
+the same methods as the original but does not give access to its
+instance variables.  Bastions have a number of uses, but the most
+obvious one is to provide code executing in restricted mode with a
+safe interface to an object implemented in unrestricted mode.
+
+The bastionification routine has an optional second argument which is
+a filter function.  Only those methods for which the filter method
+(called with the method name as argument) returns true are accessible.
+The default filter method returns true unless the method name begins
+with an underscore.
+
+There are a number of possible implementations of bastions.  We use a
+'lazy' approach where the bastion's __getattr__() discipline does all
+the work for a particular method the first time it is used.  This is
+usually fastest, especially if the user doesn't call all available
+methods.  The retrieved methods are stored as instance variables of
+the bastion, so the overhead is only occurred on the first use of each
+method.
+
+Detail: the bastion class has a __repr__() discipline which includes
+the repr() of the original object.  This is precomputed when the
+bastion is created.
+
+"""
+
+__all__ = ["BastionClass", "Bastion"]
+
+from types import MethodType
+
+
+class BastionClass:
+
+    """Helper class used by the Bastion() function.
+
+    You could subclass this and pass the subclass as the bastionclass
+    argument to the Bastion() function, as long as the constructor has
+    the same signature (a get() function and a name for the object).
+
+    """
+
+    def __init__(self, get, name):
+        """Constructor.
+
+        Arguments:
+
+        get - a function that gets the attribute value (by name)
+        name - a human-readable name for the original object
+               (suggestion: use repr(object))
+
+        """
+        self._get_ = get
+        self._name_ = name
+
+    def __repr__(self):
+        """Return a representation string.
+
+        This includes the name passed in to the constructor, so that
+        if you print the bastion during debugging, at least you have
+        some idea of what it is.
+
+        """
+        return "<Bastion for %s>" % self._name_
+
+    def __getattr__(self, name):
+        """Get an as-yet undefined attribute value.
+
+        This calls the get() function that was passed to the
+        constructor.  The result is stored as an instance variable so
+        that the next time the same attribute is requested,
+        __getattr__() won't be invoked.
+
+        If the get() function raises an exception, this is simply
+        passed on -- exceptions are not cached.
+
+        """
+        attribute = self._get_(name)
+        self.__dict__[name] = attribute
+        return attribute
+
+
+def Bastion(object, filter = lambda name: name[:1] != '_',
+            name=None, bastionclass=BastionClass):
+    """Create a bastion for an object, using an optional filter.
+
+    See the Bastion module's documentation for background.
+
+    Arguments:
+
+    object - the original object
+    filter - a predicate that decides whether a function name is OK;
+             by default all names are OK that don't start with '_'
+    name - the name of the object; default repr(object)
+    bastionclass - class used to create the bastion; default BastionClass
+
+    """
+
+    raise RuntimeError, "This code is not secure in Python 2.2 and 2.3"
+
+    # Note: we define *two* ad-hoc functions here, get1 and get2.
+    # Both are intended to be called in the same way: get(name).
+    # It is clear that the real work (getting the attribute
+    # from the object and calling the filter) is done in get1.
+    # Why can't we pass get1 to the bastion?  Because the user
+    # would be able to override the filter argument!  With get2,
+    # overriding the default argument is no security loophole:
+    # all it does is call it.
+    # Also notice that we can't place the object and filter as
+    # instance variables on the bastion object itself, since
+    # the user has full access to all instance variables!
+
+    def get1(name, object=object, filter=filter):
+        """Internal function for Bastion().  See source comments."""
+        if filter(name):
+            attribute = getattr(object, name)
+            if type(attribute) == MethodType:
+                return attribute
+        raise AttributeError, name
+
+    def get2(name, get1=get1):
+        """Internal function for Bastion().  See source comments."""
+        return get1(name)
+
+    if name is None:
+        name = repr(object)
+    return bastionclass(get2, name)
+
+
+def _test():
+    """Test the Bastion() function."""
+    class Original:
+        def __init__(self):
+            self.sum = 0
+        def add(self, n):
+            self._add(n)
+        def _add(self, n):
+            self.sum = self.sum + n
+        def total(self):
+            return self.sum
+    o = Original()
+    b = Bastion(o)
+    testcode = """if 1:
+    b.add(81)
+    b.add(18)
+    print "b.total() =", b.total()
+    try:
+        print "b.sum =", b.sum,
+    except:
+        print "inaccessible"
+    else:
+        print "accessible"
+    try:
+        print "b._add =", b._add,
+    except:
+        print "inaccessible"
+    else:
+        print "accessible"
+    try:
+        print "b._get_.func_defaults =", map(type, b._get_.func_defaults),
+    except:
+        print "inaccessible"
+    else:
+        print "accessible"
+    \n"""
+    exec testcode
+    print '='*20, "Using rexec:", '='*20
+    import rexec
+    r = rexec.RExec()
+    m = r.add_module('__main__')
+    m.b = b
+    r.r_exec(testcode)
+
+
+if __name__ == '__main__':
+    _test()

Added: vendor/Python/current/Lib/CGIHTTPServer.py
===================================================================
--- vendor/Python/current/Lib/CGIHTTPServer.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/CGIHTTPServer.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,362 @@
+"""CGI-savvy HTTP Server.
+
+This module builds on SimpleHTTPServer by implementing GET and POST
+requests to cgi-bin scripts.
+
+If the os.fork() function is not present (e.g. on Windows),
+os.popen2() is used as a fallback, with slightly altered semantics; if
+that function is not present either (e.g. on Macintosh), only Python
+scripts are supported, and they are executed by the current process.
+
+In all cases, the implementation is intentionally naive -- all
+requests are executed sychronously.
+
+SECURITY WARNING: DON'T USE THIS CODE UNLESS YOU ARE INSIDE A FIREWALL
+-- it may execute arbitrary Python code or external programs.
+
+Note that status code 200 is sent prior to execution of a CGI script, so
+scripts cannot send other status codes such as 302 (redirect).
+"""
+
+
+__version__ = "0.4"
+
+__all__ = ["CGIHTTPRequestHandler"]
+
+import os
+import sys
+import urllib
+import BaseHTTPServer
+import SimpleHTTPServer
+import select
+
+
+class CGIHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
+
+    """Complete HTTP server with GET, HEAD and POST commands.
+
+    GET and HEAD also support running CGI scripts.
+
+    The POST command is *only* implemented for CGI scripts.
+
+    """
+
+    # Determine platform specifics
+    have_fork = hasattr(os, 'fork')
+    have_popen2 = hasattr(os, 'popen2')
+    have_popen3 = hasattr(os, 'popen3')
+
+    # Make rfile unbuffered -- we need to read one line and then pass
+    # the rest to a subprocess, so we can't use buffered input.
+    rbufsize = 0
+
+    def do_POST(self):
+        """Serve a POST request.
+
+        This is only implemented for CGI scripts.
+
+        """
+
+        if self.is_cgi():
+            self.run_cgi()
+        else:
+            self.send_error(501, "Can only POST to CGI scripts")
+
+    def send_head(self):
+        """Version of send_head that support CGI scripts"""
+        if self.is_cgi():
+            return self.run_cgi()
+        else:
+            return SimpleHTTPServer.SimpleHTTPRequestHandler.send_head(self)
+
+    def is_cgi(self):
+        """Test whether self.path corresponds to a CGI script.
+
+        Return a tuple (dir, rest) if self.path requires running a
+        CGI script, None if not.  Note that rest begins with a
+        slash if it is not empty.
+
+        The default implementation tests whether the path
+        begins with one of the strings in the list
+        self.cgi_directories (and the next character is a '/'
+        or the end of the string).
+
+        """
+
+        path = self.path
+
+        for x in self.cgi_directories:
+            i = len(x)
+            if path[:i] == x and (not path[i:] or path[i] == '/'):
+                self.cgi_info = path[:i], path[i+1:]
+                return True
+        return False
+
+    cgi_directories = ['/cgi-bin', '/htbin']
+
+    def is_executable(self, path):
+        """Test whether argument path is an executable file."""
+        return executable(path)
+
+    def is_python(self, path):
+        """Test whether argument path is a Python script."""
+        head, tail = os.path.splitext(path)
+        return tail.lower() in (".py", ".pyw")
+
+    def run_cgi(self):
+        """Execute a CGI script."""
+        path = self.path
+        dir, rest = self.cgi_info
+        
+        i = path.find('/', len(dir) + 1)
+        while i >= 0:
+            nextdir = path[:i]
+            nextrest = path[i+1:]
+
+            scriptdir = self.translate_path(nextdir)
+            if os.path.isdir(scriptdir):
+                dir, rest = nextdir, nextrest
+                i = path.find('/', len(dir) + 1)
+            else:
+                break
+
+        # find an explicit query string, if present.
+        i = rest.rfind('?')
+        if i >= 0:
+            rest, query = rest[:i], rest[i+1:]
+        else:
+            query = ''
+
+        # dissect the part after the directory name into a script name &
+        # a possible additional path, to be stored in PATH_INFO.
+        i = rest.find('/')
+        if i >= 0:
+            script, rest = rest[:i], rest[i:]
+        else:
+            script, rest = rest, ''
+
+        scriptname = dir + '/' + script
+        scriptfile = self.translate_path(scriptname)
+        if not os.path.exists(scriptfile):
+            self.send_error(404, "No such CGI script (%r)" % scriptname)
+            return
+        if not os.path.isfile(scriptfile):
+            self.send_error(403, "CGI script is not a plain file (%r)" %
+                            scriptname)
+            return
+        ispy = self.is_python(scriptname)
+        if not ispy:
+            if not (self.have_fork or self.have_popen2 or self.have_popen3):
+                self.send_error(403, "CGI script is not a Python script (%r)" %
+                                scriptname)
+                return
+            if not self.is_executable(scriptfile):
+                self.send_error(403, "CGI script is not executable (%r)" %
+                                scriptname)
+                return
+
+        # Reference: http://hoohoo.ncsa.uiuc.edu/cgi/env.html
+        # XXX Much of the following could be prepared ahead of time!
+        env = {}
+        env['SERVER_SOFTWARE'] = self.version_string()
+        env['SERVER_NAME'] = self.server.server_name
+        env['GATEWAY_INTERFACE'] = 'CGI/1.1'
+        env['SERVER_PROTOCOL'] = self.protocol_version
+        env['SERVER_PORT'] = str(self.server.server_port)
+        env['REQUEST_METHOD'] = self.command
+        uqrest = urllib.unquote(rest)
+        env['PATH_INFO'] = uqrest
+        env['PATH_TRANSLATED'] = self.translate_path(uqrest)
+        env['SCRIPT_NAME'] = scriptname
+        if query:
+            env['QUERY_STRING'] = query
+        host = self.address_string()
+        if host != self.client_address[0]:
+            env['REMOTE_HOST'] = host
+        env['REMOTE_ADDR'] = self.client_address[0]
+        authorization = self.headers.getheader("authorization")
+        if authorization:
+            authorization = authorization.split()
+            if len(authorization) == 2:
+                import base64, binascii
+                env['AUTH_TYPE'] = authorization[0]
+                if authorization[0].lower() == "basic":
+                    try:
+                        authorization = base64.decodestring(authorization[1])
+                    except binascii.Error:
+                        pass
+                    else:
+                        authorization = authorization.split(':')
+                        if len(authorization) == 2:
+                            env['REMOTE_USER'] = authorization[0]
+        # XXX REMOTE_IDENT
+        if self.headers.typeheader is None:
+            env['CONTENT_TYPE'] = self.headers.type
+        else:
+            env['CONTENT_TYPE'] = self.headers.typeheader
+        length = self.headers.getheader('content-length')
+        if length:
+            env['CONTENT_LENGTH'] = length
+        accept = []
+        for line in self.headers.getallmatchingheaders('accept'):
+            if line[:1] in "\t\n\r ":
+                accept.append(line.strip())
+            else:
+                accept = accept + line[7:].split(',')
+        env['HTTP_ACCEPT'] = ','.join(accept)
+        ua = self.headers.getheader('user-agent')
+        if ua:
+            env['HTTP_USER_AGENT'] = ua
+        co = filter(None, self.headers.getheaders('cookie'))
+        if co:
+            env['HTTP_COOKIE'] = ', '.join(co)
+        # XXX Other HTTP_* headers
+        # Since we're setting the env in the parent, provide empty
+        # values to override previously set values
+        for k in ('QUERY_STRING', 'REMOTE_HOST', 'CONTENT_LENGTH',
+                  'HTTP_USER_AGENT', 'HTTP_COOKIE'):
+            env.setdefault(k, "")
+        os.environ.update(env)
+
+        self.send_response(200, "Script output follows")
+
+        decoded_query = query.replace('+', ' ')
+
+        if self.have_fork:
+            # Unix -- fork as we should
+            args = [script]
+            if '=' not in decoded_query:
+                args.append(decoded_query)
+            nobody = nobody_uid()
+            self.wfile.flush() # Always flush before forking
+            pid = os.fork()
+            if pid != 0:
+                # Parent
+                pid, sts = os.waitpid(pid, 0)
+                # throw away additional data [see bug #427345]
+                while select.select([self.rfile], [], [], 0)[0]:
+                    if not self.rfile.read(1):
+                        break
+                if sts:
+                    self.log_error("CGI script exit status %#x", sts)
+                return
+            # Child
+            try:
+                try:
+                    os.setuid(nobody)
+                except os.error:
+                    pass
+                os.dup2(self.rfile.fileno(), 0)
+                os.dup2(self.wfile.fileno(), 1)
+                os.execve(scriptfile, args, os.environ)
+            except:
+                self.server.handle_error(self.request, self.client_address)
+                os._exit(127)
+
+        elif self.have_popen2 or self.have_popen3:
+            # Windows -- use popen2 or popen3 to create a subprocess
+            import shutil
+            if self.have_popen3:
+                popenx = os.popen3
+            else:
+                popenx = os.popen2
+            cmdline = scriptfile
+            if self.is_python(scriptfile):
+                interp = sys.executable
+                if interp.lower().endswith("w.exe"):
+                    # On Windows, use python.exe, not pythonw.exe
+                    interp = interp[:-5] + interp[-4:]
+                cmdline = "%s -u %s" % (interp, cmdline)
+            if '=' not in query and '"' not in query:
+                cmdline = '%s "%s"' % (cmdline, query)
+            self.log_message("command: %s", cmdline)
+            try:
+                nbytes = int(length)
+            except (TypeError, ValueError):
+                nbytes = 0
+            files = popenx(cmdline, 'b')
+            fi = files[0]
+            fo = files[1]
+            if self.have_popen3:
+                fe = files[2]
+            if self.command.lower() == "post" and nbytes > 0:
+                data = self.rfile.read(nbytes)
+                fi.write(data)
+            # throw away additional data [see bug #427345]
+            while select.select([self.rfile._sock], [], [], 0)[0]:
+                if not self.rfile._sock.recv(1):
+                    break
+            fi.close()
+            shutil.copyfileobj(fo, self.wfile)
+            if self.have_popen3:
+                errors = fe.read()
+                fe.close()
+                if errors:
+                    self.log_error('%s', errors)
+            sts = fo.close()
+            if sts:
+                self.log_error("CGI script exit status %#x", sts)
+            else:
+                self.log_message("CGI script exited OK")
+
+        else:
+            # Other O.S. -- execute script in this process
+            save_argv = sys.argv
+            save_stdin = sys.stdin
+            save_stdout = sys.stdout
+            save_stderr = sys.stderr
+            try:
+                save_cwd = os.getcwd()
+                try:
+                    sys.argv = [scriptfile]
+                    if '=' not in decoded_query:
+                        sys.argv.append(decoded_query)
+                    sys.stdout = self.wfile
+                    sys.stdin = self.rfile
+                    execfile(scriptfile, {"__name__": "__main__"})
+                finally:
+                    sys.argv = save_argv
+                    sys.stdin = save_stdin
+                    sys.stdout = save_stdout
+                    sys.stderr = save_stderr
+                    os.chdir(save_cwd)
+            except SystemExit, sts:
+                self.log_error("CGI script exit status %s", str(sts))
+            else:
+                self.log_message("CGI script exited OK")
+
+
+nobody = None
+
+def nobody_uid():
+    """Internal routine to get nobody's uid"""
+    global nobody
+    if nobody:
+        return nobody
+    try:
+        import pwd
+    except ImportError:
+        return -1
+    try:
+        nobody = pwd.getpwnam('nobody')[2]
+    except KeyError:
+        nobody = 1 + max(map(lambda x: x[2], pwd.getpwall()))
+    return nobody
+
+
+def executable(path):
+    """Test for executable file."""
+    try:
+        st = os.stat(path)
+    except os.error:
+        return False
+    return st.st_mode & 0111 != 0
+
+
+def test(HandlerClass = CGIHTTPRequestHandler,
+         ServerClass = BaseHTTPServer.HTTPServer):
+    SimpleHTTPServer.test(HandlerClass, ServerClass)
+
+
+if __name__ == '__main__':
+    test()

Added: vendor/Python/current/Lib/ConfigParser.py
===================================================================
--- vendor/Python/current/Lib/ConfigParser.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ConfigParser.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,640 @@
+"""Configuration file parser.
+
+A setup file consists of sections, lead by a "[section]" header,
+and followed by "name: value" entries, with continuations and such in
+the style of RFC 822.
+
+The option values can contain format strings which refer to other values in
+the same section, or values in a special [DEFAULT] section.
+
+For example:
+
+    something: %(dir)s/whatever
+
+would resolve the "%(dir)s" to the value of dir.  All reference
+expansions are done late, on demand.
+
+Intrinsic defaults can be specified by passing them into the
+ConfigParser constructor as a dictionary.
+
+class:
+
+ConfigParser -- responsible for parsing a list of
+                configuration files, and managing the parsed database.
+
+    methods:
+
+    __init__(defaults=None)
+        create the parser and specify a dictionary of intrinsic defaults.  The
+        keys must be strings, the values must be appropriate for %()s string
+        interpolation.  Note that `__name__' is always an intrinsic default;
+        its value is the section's name.
+
+    sections()
+        return all the configuration section names, sans DEFAULT
+
+    has_section(section)
+        return whether the given section exists
+
+    has_option(section, option)
+        return whether the given option exists in the given section
+
+    options(section)
+        return list of configuration options for the named section
+
+    read(filenames)
+        read and parse the list of named configuration files, given by
+        name.  A single filename is also allowed.  Non-existing files
+        are ignored.  Return list of successfully read files.
+
+    readfp(fp, filename=None)
+        read and parse one configuration file, given as a file object.
+        The filename defaults to fp.name; it is only used in error
+        messages (if fp has no `name' attribute, the string `<???>' is used).
+
+    get(section, option, raw=False, vars=None)
+        return a string value for the named option.  All % interpolations are
+        expanded in the return values, based on the defaults passed into the
+        constructor and the DEFAULT section.  Additional substitutions may be
+        provided using the `vars' argument, which must be a dictionary whose
+        contents override any pre-existing defaults.
+
+    getint(section, options)
+        like get(), but convert value to an integer
+
+    getfloat(section, options)
+        like get(), but convert value to a float
+
+    getboolean(section, options)
+        like get(), but convert value to a boolean (currently case
+        insensitively defined as 0, false, no, off for False, and 1, true,
+        yes, on for True).  Returns False or True.
+
+    items(section, raw=False, vars=None)
+        return a list of tuples with (name, value) for each option
+        in the section.
+
+    remove_section(section)
+        remove the given file section and all its options
+
+    remove_option(section, option)
+        remove the given option from the given section
+
+    set(section, option, value)
+        set the given option
+
+    write(fp)
+        write the configuration state in .ini format
+"""
+
+import re
+
+__all__ = ["NoSectionError", "DuplicateSectionError", "NoOptionError",
+           "InterpolationError", "InterpolationDepthError",
+           "InterpolationSyntaxError", "ParsingError",
+           "MissingSectionHeaderError",
+           "ConfigParser", "SafeConfigParser", "RawConfigParser",
+           "DEFAULTSECT", "MAX_INTERPOLATION_DEPTH"]
+
+DEFAULTSECT = "DEFAULT"
+
+MAX_INTERPOLATION_DEPTH = 10
+
+
+
+# exception classes
+class Error(Exception):
+    """Base class for ConfigParser exceptions."""
+
+    def __init__(self, msg=''):
+        self.message = msg
+        Exception.__init__(self, msg)
+
+    def __repr__(self):
+        return self.message
+
+    __str__ = __repr__
+
+class NoSectionError(Error):
+    """Raised when no section matches a requested option."""
+
+    def __init__(self, section):
+        Error.__init__(self, 'No section: %r' % (section,))
+        self.section = section
+
+class DuplicateSectionError(Error):
+    """Raised when a section is multiply-created."""
+
+    def __init__(self, section):
+        Error.__init__(self, "Section %r already exists" % section)
+        self.section = section
+
+class NoOptionError(Error):
+    """A requested option was not found."""
+
+    def __init__(self, option, section):
+        Error.__init__(self, "No option %r in section: %r" %
+                       (option, section))
+        self.option = option
+        self.section = section
+
+class InterpolationError(Error):
+    """Base class for interpolation-related exceptions."""
+
+    def __init__(self, option, section, msg):
+        Error.__init__(self, msg)
+        self.option = option
+        self.section = section
+
+class InterpolationMissingOptionError(InterpolationError):
+    """A string substitution required a setting which was not available."""
+
+    def __init__(self, option, section, rawval, reference):
+        msg = ("Bad value substitution:\n"
+               "\tsection: [%s]\n"
+               "\toption : %s\n"
+               "\tkey    : %s\n"
+               "\trawval : %s\n"
+               % (section, option, reference, rawval))
+        InterpolationError.__init__(self, option, section, msg)
+        self.reference = reference
+
+class InterpolationSyntaxError(InterpolationError):
+    """Raised when the source text into which substitutions are made
+    does not conform to the required syntax."""
+
+class InterpolationDepthError(InterpolationError):
+    """Raised when substitutions are nested too deeply."""
+
+    def __init__(self, option, section, rawval):
+        msg = ("Value interpolation too deeply recursive:\n"
+               "\tsection: [%s]\n"
+               "\toption : %s\n"
+               "\trawval : %s\n"
+               % (section, option, rawval))
+        InterpolationError.__init__(self, option, section, msg)
+
+class ParsingError(Error):
+    """Raised when a configuration file does not follow legal syntax."""
+
+    def __init__(self, filename):
+        Error.__init__(self, 'File contains parsing errors: %s' % filename)
+        self.filename = filename
+        self.errors = []
+
+    def append(self, lineno, line):
+        self.errors.append((lineno, line))
+        self.message += '\n\t[line %2d]: %s' % (lineno, line)
+
+class MissingSectionHeaderError(ParsingError):
+    """Raised when a key-value pair is found before any section header."""
+
+    def __init__(self, filename, lineno, line):
+        Error.__init__(
+            self,
+            'File contains no section headers.\nfile: %s, line: %d\n%r' %
+            (filename, lineno, line))
+        self.filename = filename
+        self.lineno = lineno
+        self.line = line
+
+
+
+class RawConfigParser:
+    def __init__(self, defaults=None):
+        self._sections = {}
+        self._defaults = {}
+        if defaults:
+            for key, value in defaults.items():
+                self._defaults[self.optionxform(key)] = value
+
+    def defaults(self):
+        return self._defaults
+
+    def sections(self):
+        """Return a list of section names, excluding [DEFAULT]"""
+        # self._sections will never have [DEFAULT] in it
+        return self._sections.keys()
+
+    def add_section(self, section):
+        """Create a new section in the configuration.
+
+        Raise DuplicateSectionError if a section by the specified name
+        already exists.
+        """
+        if section in self._sections:
+            raise DuplicateSectionError(section)
+        self._sections[section] = {}
+
+    def has_section(self, section):
+        """Indicate whether the named section is present in the configuration.
+
+        The DEFAULT section is not acknowledged.
+        """
+        return section in self._sections
+
+    def options(self, section):
+        """Return a list of option names for the given section name."""
+        try:
+            opts = self._sections[section].copy()
+        except KeyError:
+            raise NoSectionError(section)
+        opts.update(self._defaults)
+        if '__name__' in opts:
+            del opts['__name__']
+        return opts.keys()
+
+    def read(self, filenames):
+        """Read and parse a filename or a list of filenames.
+
+        Files that cannot be opened are silently ignored; this is
+        designed so that you can specify a list of potential
+        configuration file locations (e.g. current directory, user's
+        home directory, systemwide directory), and all existing
+        configuration files in the list will be read.  A single
+        filename may also be given.
+
+        Return list of successfully read files.
+        """
+        if isinstance(filenames, basestring):
+            filenames = [filenames]
+        read_ok = []
+        for filename in filenames:
+            try:
+                fp = open(filename)
+            except IOError:
+                continue
+            self._read(fp, filename)
+            fp.close()
+            read_ok.append(filename)
+        return read_ok
+
+    def readfp(self, fp, filename=None):
+        """Like read() but the argument must be a file-like object.
+
+        The `fp' argument must have a `readline' method.  Optional
+        second argument is the `filename', which if not given, is
+        taken from fp.name.  If fp has no `name' attribute, `<???>' is
+        used.
+
+        """
+        if filename is None:
+            try:
+                filename = fp.name
+            except AttributeError:
+                filename = '<???>'
+        self._read(fp, filename)
+
+    def get(self, section, option):
+        opt = self.optionxform(option)
+        if section not in self._sections:
+            if section != DEFAULTSECT:
+                raise NoSectionError(section)
+            if opt in self._defaults:
+                return self._defaults[opt]
+            else:
+                raise NoOptionError(option, section)
+        elif opt in self._sections[section]:
+            return self._sections[section][opt]
+        elif opt in self._defaults:
+            return self._defaults[opt]
+        else:
+            raise NoOptionError(option, section)
+
+    def items(self, section):
+        try:
+            d2 = self._sections[section]
+        except KeyError:
+            if section != DEFAULTSECT:
+                raise NoSectionError(section)
+            d2 = {}
+        d = self._defaults.copy()
+        d.update(d2)
+        if "__name__" in d:
+            del d["__name__"]
+        return d.items()
+
+    def _get(self, section, conv, option):
+        return conv(self.get(section, option))
+
+    def getint(self, section, option):
+        return self._get(section, int, option)
+
+    def getfloat(self, section, option):
+        return self._get(section, float, option)
+
+    _boolean_states = {'1': True, 'yes': True, 'true': True, 'on': True,
+                       '0': False, 'no': False, 'false': False, 'off': False}
+
+    def getboolean(self, section, option):
+        v = self.get(section, option)
+        if v.lower() not in self._boolean_states:
+            raise ValueError, 'Not a boolean: %s' % v
+        return self._boolean_states[v.lower()]
+
+    def optionxform(self, optionstr):
+        return optionstr.lower()
+
+    def has_option(self, section, option):
+        """Check for the existence of a given option in a given section."""
+        if not section or section == DEFAULTSECT:
+            option = self.optionxform(option)
+            return option in self._defaults
+        elif section not in self._sections:
+            return False
+        else:
+            option = self.optionxform(option)
+            return (option in self._sections[section]
+                    or option in self._defaults)
+
+    def set(self, section, option, value):
+        """Set an option."""
+        if not section or section == DEFAULTSECT:
+            sectdict = self._defaults
+        else:
+            try:
+                sectdict = self._sections[section]
+            except KeyError:
+                raise NoSectionError(section)
+        sectdict[self.optionxform(option)] = value
+
+    def write(self, fp):
+        """Write an .ini-format representation of the configuration state."""
+        if self._defaults:
+            fp.write("[%s]\n" % DEFAULTSECT)
+            for (key, value) in self._defaults.items():
+                fp.write("%s = %s\n" % (key, str(value).replace('\n', '\n\t')))
+            fp.write("\n")
+        for section in self._sections:
+            fp.write("[%s]\n" % section)
+            for (key, value) in self._sections[section].items():
+                if key != "__name__":
+                    fp.write("%s = %s\n" %
+                             (key, str(value).replace('\n', '\n\t')))
+            fp.write("\n")
+
+    def remove_option(self, section, option):
+        """Remove an option."""
+        if not section or section == DEFAULTSECT:
+            sectdict = self._defaults
+        else:
+            try:
+                sectdict = self._sections[section]
+            except KeyError:
+                raise NoSectionError(section)
+        option = self.optionxform(option)
+        existed = option in sectdict
+        if existed:
+            del sectdict[option]
+        return existed
+
+    def remove_section(self, section):
+        """Remove a file section."""
+        existed = section in self._sections
+        if existed:
+            del self._sections[section]
+        return existed
+
+    #
+    # Regular expressions for parsing section headers and options.
+    #
+    SECTCRE = re.compile(
+        r'\['                                 # [
+        r'(?P<header>[^]]+)'                  # very permissive!
+        r'\]'                                 # ]
+        )
+    OPTCRE = re.compile(
+        r'(?P<option>[^:=\s][^:=]*)'          # very permissive!
+        r'\s*(?P<vi>[:=])\s*'                 # any number of space/tab,
+                                              # followed by separator
+                                              # (either : or =), followed
+                                              # by any # space/tab
+        r'(?P<value>.*)$'                     # everything up to eol
+        )
+
+    def _read(self, fp, fpname):
+        """Parse a sectioned setup file.
+
+        The sections in setup file contains a title line at the top,
+        indicated by a name in square brackets (`[]'), plus key/value
+        options lines, indicated by `name: value' format lines.
+        Continuations are represented by an embedded newline then
+        leading whitespace.  Blank lines, lines beginning with a '#',
+        and just about everything else are ignored.
+        """
+        cursect = None                            # None, or a dictionary
+        optname = None
+        lineno = 0
+        e = None                                  # None, or an exception
+        while True:
+            line = fp.readline()
+            if not line:
+                break
+            lineno = lineno + 1
+            # comment or blank line?
+            if line.strip() == '' or line[0] in '#;':
+                continue
+            if line.split(None, 1)[0].lower() == 'rem' and line[0] in "rR":
+                # no leading whitespace
+                continue
+            # continuation line?
+            if line[0].isspace() and cursect is not None and optname:
+                value = line.strip()
+                if value:
+                    cursect[optname] = "%s\n%s" % (cursect[optname], value)
+            # a section header or option header?
+            else:
+                # is it a section header?
+                mo = self.SECTCRE.match(line)
+                if mo:
+                    sectname = mo.group('header')
+                    if sectname in self._sections:
+                        cursect = self._sections[sectname]
+                    elif sectname == DEFAULTSECT:
+                        cursect = self._defaults
+                    else:
+                        cursect = {'__name__': sectname}
+                        self._sections[sectname] = cursect
+                    # So sections can't start with a continuation line
+                    optname = None
+                # no section header in the file?
+                elif cursect is None:
+                    raise MissingSectionHeaderError(fpname, lineno, line)
+                # an option line?
+                else:
+                    mo = self.OPTCRE.match(line)
+                    if mo:
+                        optname, vi, optval = mo.group('option', 'vi', 'value')
+                        if vi in ('=', ':') and ';' in optval:
+                            # ';' is a comment delimiter only if it follows
+                            # a spacing character
+                            pos = optval.find(';')
+                            if pos != -1 and optval[pos-1].isspace():
+                                optval = optval[:pos]
+                        optval = optval.strip()
+                        # allow empty values
+                        if optval == '""':
+                            optval = ''
+                        optname = self.optionxform(optname.rstrip())
+                        cursect[optname] = optval
+                    else:
+                        # a non-fatal parsing error occurred.  set up the
+                        # exception but keep going. the exception will be
+                        # raised at the end of the file and will contain a
+                        # list of all bogus lines
+                        if not e:
+                            e = ParsingError(fpname)
+                        e.append(lineno, repr(line))
+        # if any parsing errors occurred, raise an exception
+        if e:
+            raise e
+
+
+class ConfigParser(RawConfigParser):
+
+    def get(self, section, option, raw=False, vars=None):
+        """Get an option value for a given section.
+
+        All % interpolations are expanded in the return values, based on the
+        defaults passed into the constructor, unless the optional argument
+        `raw' is true.  Additional substitutions may be provided using the
+        `vars' argument, which must be a dictionary whose contents overrides
+        any pre-existing defaults.
+
+        The section DEFAULT is special.
+        """
+        d = self._defaults.copy()
+        try:
+            d.update(self._sections[section])
+        except KeyError:
+            if section != DEFAULTSECT:
+                raise NoSectionError(section)
+        # Update with the entry specific variables
+        if vars:
+            for key, value in vars.items():
+                d[self.optionxform(key)] = value
+        option = self.optionxform(option)
+        try:
+            value = d[option]
+        except KeyError:
+            raise NoOptionError(option, section)
+
+        if raw:
+            return value
+        else:
+            return self._interpolate(section, option, value, d)
+
+    def items(self, section, raw=False, vars=None):
+        """Return a list of tuples with (name, value) for each option
+        in the section.
+
+        All % interpolations are expanded in the return values, based on the
+        defaults passed into the constructor, unless the optional argument
+        `raw' is true.  Additional substitutions may be provided using the
+        `vars' argument, which must be a dictionary whose contents overrides
+        any pre-existing defaults.
+
+        The section DEFAULT is special.
+        """
+        d = self._defaults.copy()
+        try:
+            d.update(self._sections[section])
+        except KeyError:
+            if section != DEFAULTSECT:
+                raise NoSectionError(section)
+        # Update with the entry specific variables
+        if vars:
+            for key, value in vars.items():
+                d[self.optionxform(key)] = value
+        options = d.keys()
+        if "__name__" in options:
+            options.remove("__name__")
+        if raw:
+            return [(option, d[option])
+                    for option in options]
+        else:
+            return [(option, self._interpolate(section, option, d[option], d))
+                    for option in options]
+
+    def _interpolate(self, section, option, rawval, vars):
+        # do the string interpolation
+        value = rawval
+        depth = MAX_INTERPOLATION_DEPTH
+        while depth:                    # Loop through this until it's done
+            depth -= 1
+            if "%(" in value:
+                value = self._KEYCRE.sub(self._interpolation_replace, value)
+                try:
+                    value = value % vars
+                except KeyError, e:
+                    raise InterpolationMissingOptionError(
+                        option, section, rawval, e[0])
+            else:
+                break
+        if "%(" in value:
+            raise InterpolationDepthError(option, section, rawval)
+        return value
+
+    _KEYCRE = re.compile(r"%\(([^)]*)\)s|.")
+
+    def _interpolation_replace(self, match):
+        s = match.group(1)
+        if s is None:
+            return match.group()
+        else:
+            return "%%(%s)s" % self.optionxform(s)
+
+
+class SafeConfigParser(ConfigParser):
+
+    def _interpolate(self, section, option, rawval, vars):
+        # do the string interpolation
+        L = []
+        self._interpolate_some(option, L, rawval, section, vars, 1)
+        return ''.join(L)
+
+    _interpvar_match = re.compile(r"%\(([^)]+)\)s").match
+
+    def _interpolate_some(self, option, accum, rest, section, map, depth):
+        if depth > MAX_INTERPOLATION_DEPTH:
+            raise InterpolationDepthError(option, section, rest)
+        while rest:
+            p = rest.find("%")
+            if p < 0:
+                accum.append(rest)
+                return
+            if p > 0:
+                accum.append(rest[:p])
+                rest = rest[p:]
+            # p is no longer used
+            c = rest[1:2]
+            if c == "%":
+                accum.append("%")
+                rest = rest[2:]
+            elif c == "(":
+                m = self._interpvar_match(rest)
+                if m is None:
+                    raise InterpolationSyntaxError(option, section,
+                        "bad interpolation variable reference %r" % rest)
+                var = self.optionxform(m.group(1))
+                rest = rest[m.end():]
+                try:
+                    v = map[var]
+                except KeyError:
+                    raise InterpolationMissingOptionError(
+                        option, section, rest, var)
+                if "%" in v:
+                    self._interpolate_some(option, accum, v,
+                                           section, map, depth + 1)
+                else:
+                    accum.append(v)
+            else:
+                raise InterpolationSyntaxError(
+                    option, section,
+                    "'%%' must be followed by '%%' or '(', found: %r" % (rest,))
+
+    def set(self, section, option, value):
+        """Set an option.  Extend ConfigParser.set: check for string values."""
+        if not isinstance(value, basestring):
+            raise TypeError("option values must be strings")
+        ConfigParser.set(self, section, option, value)

Added: vendor/Python/current/Lib/Cookie.py
===================================================================
--- vendor/Python/current/Lib/Cookie.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/Cookie.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,746 @@
+#!/usr/bin/env python
+#
+
+####
+# Copyright 2000 by Timothy O'Malley <timo at alum.mit.edu>
+#
+#                All Rights Reserved
+#
+# Permission to use, copy, modify, and distribute this software
+# and its documentation for any purpose and without fee is hereby
+# granted, provided that the above copyright notice appear in all
+# copies and that both that copyright notice and this permission
+# notice appear in supporting documentation, and that the name of
+# Timothy O'Malley  not be used in advertising or publicity
+# pertaining to distribution of the software without specific, written
+# prior permission.
+#
+# Timothy O'Malley DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+# SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS, IN NO EVENT SHALL Timothy O'Malley BE LIABLE FOR
+# ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+#
+####
+#
+# Id: Cookie.py,v 2.29 2000/08/23 05:28:49 timo Exp
+#   by Timothy O'Malley <timo at alum.mit.edu>
+#
+#  Cookie.py is a Python module for the handling of HTTP
+#  cookies as a Python dictionary.  See RFC 2109 for more
+#  information on cookies.
+#
+#  The original idea to treat Cookies as a dictionary came from
+#  Dave Mitchell (davem at magnet.com) in 1995, when he released the
+#  first version of nscookie.py.
+#
+####
+
+r"""
+Here's a sample session to show how to use this module.
+At the moment, this is the only documentation.
+
+The Basics
+----------
+
+Importing is easy..
+
+   >>> import Cookie
+
+Most of the time you start by creating a cookie.  Cookies come in
+three flavors, each with slightly different encoding semantics, but
+more on that later.
+
+   >>> C = Cookie.SimpleCookie()
+   >>> C = Cookie.SerialCookie()
+   >>> C = Cookie.SmartCookie()
+
+[Note: Long-time users of Cookie.py will remember using
+Cookie.Cookie() to create an Cookie object.  Although deprecated, it
+is still supported by the code.  See the Backward Compatibility notes
+for more information.]
+
+Once you've created your Cookie, you can add values just as if it were
+a dictionary.
+
+   >>> C = Cookie.SmartCookie()
+   >>> C["fig"] = "newton"
+   >>> C["sugar"] = "wafer"
+   >>> C.output()
+   'Set-Cookie: fig=newton\r\nSet-Cookie: sugar=wafer'
+
+Notice that the printable representation of a Cookie is the
+appropriate format for a Set-Cookie: header.  This is the
+default behavior.  You can change the header and printed
+attributes by using the .output() function
+
+   >>> C = Cookie.SmartCookie()
+   >>> C["rocky"] = "road"
+   >>> C["rocky"]["path"] = "/cookie"
+   >>> print C.output(header="Cookie:")
+   Cookie: rocky=road; Path=/cookie
+   >>> print C.output(attrs=[], header="Cookie:")
+   Cookie: rocky=road
+
+The load() method of a Cookie extracts cookies from a string.  In a
+CGI script, you would use this method to extract the cookies from the
+HTTP_COOKIE environment variable.
+
+   >>> C = Cookie.SmartCookie()
+   >>> C.load("chips=ahoy; vienna=finger")
+   >>> C.output()
+   'Set-Cookie: chips=ahoy\r\nSet-Cookie: vienna=finger'
+
+The load() method is darn-tootin smart about identifying cookies
+within a string.  Escaped quotation marks, nested semicolons, and other
+such trickeries do not confuse it.
+
+   >>> C = Cookie.SmartCookie()
+   >>> C.load('keebler="E=everybody; L=\\"Loves\\"; fudge=\\012;";')
+   >>> print C
+   Set-Cookie: keebler="E=everybody; L=\"Loves\"; fudge=\012;"
+
+Each element of the Cookie also supports all of the RFC 2109
+Cookie attributes.  Here's an example which sets the Path
+attribute.
+
+   >>> C = Cookie.SmartCookie()
+   >>> C["oreo"] = "doublestuff"
+   >>> C["oreo"]["path"] = "/"
+   >>> print C
+   Set-Cookie: oreo=doublestuff; Path=/
+
+Each dictionary element has a 'value' attribute, which gives you
+back the value associated with the key.
+
+   >>> C = Cookie.SmartCookie()
+   >>> C["twix"] = "none for you"
+   >>> C["twix"].value
+   'none for you'
+
+
+A Bit More Advanced
+-------------------
+
+As mentioned before, there are three different flavors of Cookie
+objects, each with different encoding/decoding semantics.  This
+section briefly discusses the differences.
+
+SimpleCookie
+
+The SimpleCookie expects that all values should be standard strings.
+Just to be sure, SimpleCookie invokes the str() builtin to convert
+the value to a string, when the values are set dictionary-style.
+
+   >>> C = Cookie.SimpleCookie()
+   >>> C["number"] = 7
+   >>> C["string"] = "seven"
+   >>> C["number"].value
+   '7'
+   >>> C["string"].value
+   'seven'
+   >>> C.output()
+   'Set-Cookie: number=7\r\nSet-Cookie: string=seven'
+
+
+SerialCookie
+
+The SerialCookie expects that all values should be serialized using
+cPickle (or pickle, if cPickle isn't available).  As a result of
+serializing, SerialCookie can save almost any Python object to a
+value, and recover the exact same object when the cookie has been
+returned.  (SerialCookie can yield some strange-looking cookie
+values, however.)
+
+   >>> C = Cookie.SerialCookie()
+   >>> C["number"] = 7
+   >>> C["string"] = "seven"
+   >>> C["number"].value
+   7
+   >>> C["string"].value
+   'seven'
+   >>> C.output()
+   'Set-Cookie: number="I7\\012."\r\nSet-Cookie: string="S\'seven\'\\012p1\\012."'
+
+Be warned, however, if SerialCookie cannot de-serialize a value (because
+it isn't a valid pickle'd object), IT WILL RAISE AN EXCEPTION.
+
+
+SmartCookie
+
+The SmartCookie combines aspects of each of the other two flavors.
+When setting a value in a dictionary-fashion, the SmartCookie will
+serialize (ala cPickle) the value *if and only if* it isn't a
+Python string.  String objects are *not* serialized.  Similarly,
+when the load() method parses out values, it attempts to de-serialize
+the value.  If it fails, then it fallsback to treating the value
+as a string.
+
+   >>> C = Cookie.SmartCookie()
+   >>> C["number"] = 7
+   >>> C["string"] = "seven"
+   >>> C["number"].value
+   7
+   >>> C["string"].value
+   'seven'
+   >>> C.output()
+   'Set-Cookie: number="I7\\012."\r\nSet-Cookie: string=seven'
+
+
+Backwards Compatibility
+-----------------------
+
+In order to keep compatibilty with earlier versions of Cookie.py,
+it is still possible to use Cookie.Cookie() to create a Cookie.  In
+fact, this simply returns a SmartCookie.
+
+   >>> C = Cookie.Cookie()
+   >>> print C.__class__.__name__
+   SmartCookie
+
+
+Finis.
+"""  #"
+#     ^
+#     |----helps out font-lock
+
+#
+# Import our required modules
+#
+import string
+
+try:
+    from cPickle import dumps, loads
+except ImportError:
+    from pickle import dumps, loads
+
+import re, warnings
+
+__all__ = ["CookieError","BaseCookie","SimpleCookie","SerialCookie",
+           "SmartCookie","Cookie"]
+
+_nulljoin = ''.join
+_semispacejoin = '; '.join
+_spacejoin = ' '.join
+
+#
+# Define an exception visible to External modules
+#
+class CookieError(Exception):
+    pass
+
+
+# These quoting routines conform to the RFC2109 specification, which in
+# turn references the character definitions from RFC2068.  They provide
+# a two-way quoting algorithm.  Any non-text character is translated
+# into a 4 character sequence: a forward-slash followed by the
+# three-digit octal equivalent of the character.  Any '\' or '"' is
+# quoted with a preceeding '\' slash.
+#
+# These are taken from RFC2068 and RFC2109.
+#       _LegalChars       is the list of chars which don't require "'s
+#       _Translator       hash-table for fast quoting
+#
+_LegalChars       = string.ascii_letters + string.digits + "!#$%&'*+-.^_`|~"
+_Translator       = {
+    '\000' : '\\000',  '\001' : '\\001',  '\002' : '\\002',
+    '\003' : '\\003',  '\004' : '\\004',  '\005' : '\\005',
+    '\006' : '\\006',  '\007' : '\\007',  '\010' : '\\010',
+    '\011' : '\\011',  '\012' : '\\012',  '\013' : '\\013',
+    '\014' : '\\014',  '\015' : '\\015',  '\016' : '\\016',
+    '\017' : '\\017',  '\020' : '\\020',  '\021' : '\\021',
+    '\022' : '\\022',  '\023' : '\\023',  '\024' : '\\024',
+    '\025' : '\\025',  '\026' : '\\026',  '\027' : '\\027',
+    '\030' : '\\030',  '\031' : '\\031',  '\032' : '\\032',
+    '\033' : '\\033',  '\034' : '\\034',  '\035' : '\\035',
+    '\036' : '\\036',  '\037' : '\\037',
+
+    '"' : '\\"',       '\\' : '\\\\',
+
+    '\177' : '\\177',  '\200' : '\\200',  '\201' : '\\201',
+    '\202' : '\\202',  '\203' : '\\203',  '\204' : '\\204',
+    '\205' : '\\205',  '\206' : '\\206',  '\207' : '\\207',
+    '\210' : '\\210',  '\211' : '\\211',  '\212' : '\\212',
+    '\213' : '\\213',  '\214' : '\\214',  '\215' : '\\215',
+    '\216' : '\\216',  '\217' : '\\217',  '\220' : '\\220',
+    '\221' : '\\221',  '\222' : '\\222',  '\223' : '\\223',
+    '\224' : '\\224',  '\225' : '\\225',  '\226' : '\\226',
+    '\227' : '\\227',  '\230' : '\\230',  '\231' : '\\231',
+    '\232' : '\\232',  '\233' : '\\233',  '\234' : '\\234',
+    '\235' : '\\235',  '\236' : '\\236',  '\237' : '\\237',
+    '\240' : '\\240',  '\241' : '\\241',  '\242' : '\\242',
+    '\243' : '\\243',  '\244' : '\\244',  '\245' : '\\245',
+    '\246' : '\\246',  '\247' : '\\247',  '\250' : '\\250',
+    '\251' : '\\251',  '\252' : '\\252',  '\253' : '\\253',
+    '\254' : '\\254',  '\255' : '\\255',  '\256' : '\\256',
+    '\257' : '\\257',  '\260' : '\\260',  '\261' : '\\261',
+    '\262' : '\\262',  '\263' : '\\263',  '\264' : '\\264',
+    '\265' : '\\265',  '\266' : '\\266',  '\267' : '\\267',
+    '\270' : '\\270',  '\271' : '\\271',  '\272' : '\\272',
+    '\273' : '\\273',  '\274' : '\\274',  '\275' : '\\275',
+    '\276' : '\\276',  '\277' : '\\277',  '\300' : '\\300',
+    '\301' : '\\301',  '\302' : '\\302',  '\303' : '\\303',
+    '\304' : '\\304',  '\305' : '\\305',  '\306' : '\\306',
+    '\307' : '\\307',  '\310' : '\\310',  '\311' : '\\311',
+    '\312' : '\\312',  '\313' : '\\313',  '\314' : '\\314',
+    '\315' : '\\315',  '\316' : '\\316',  '\317' : '\\317',
+    '\320' : '\\320',  '\321' : '\\321',  '\322' : '\\322',
+    '\323' : '\\323',  '\324' : '\\324',  '\325' : '\\325',
+    '\326' : '\\326',  '\327' : '\\327',  '\330' : '\\330',
+    '\331' : '\\331',  '\332' : '\\332',  '\333' : '\\333',
+    '\334' : '\\334',  '\335' : '\\335',  '\336' : '\\336',
+    '\337' : '\\337',  '\340' : '\\340',  '\341' : '\\341',
+    '\342' : '\\342',  '\343' : '\\343',  '\344' : '\\344',
+    '\345' : '\\345',  '\346' : '\\346',  '\347' : '\\347',
+    '\350' : '\\350',  '\351' : '\\351',  '\352' : '\\352',
+    '\353' : '\\353',  '\354' : '\\354',  '\355' : '\\355',
+    '\356' : '\\356',  '\357' : '\\357',  '\360' : '\\360',
+    '\361' : '\\361',  '\362' : '\\362',  '\363' : '\\363',
+    '\364' : '\\364',  '\365' : '\\365',  '\366' : '\\366',
+    '\367' : '\\367',  '\370' : '\\370',  '\371' : '\\371',
+    '\372' : '\\372',  '\373' : '\\373',  '\374' : '\\374',
+    '\375' : '\\375',  '\376' : '\\376',  '\377' : '\\377'
+    }
+
+_idmap = ''.join(chr(x) for x in xrange(256))
+
+def _quote(str, LegalChars=_LegalChars,
+           idmap=_idmap, translate=string.translate):
+    #
+    # If the string does not need to be double-quoted,
+    # then just return the string.  Otherwise, surround
+    # the string in doublequotes and precede quote (with a \)
+    # special characters.
+    #
+    if "" == translate(str, idmap, LegalChars):
+        return str
+    else:
+        return '"' + _nulljoin( map(_Translator.get, str, str) ) + '"'
+# end _quote
+
+
+_OctalPatt = re.compile(r"\\[0-3][0-7][0-7]")
+_QuotePatt = re.compile(r"[\\].")
+
+def _unquote(str):
+    # If there aren't any doublequotes,
+    # then there can't be any special characters.  See RFC 2109.
+    if  len(str) < 2:
+        return str
+    if str[0] != '"' or str[-1] != '"':
+        return str
+
+    # We have to assume that we must decode this string.
+    # Down to work.
+
+    # Remove the "s
+    str = str[1:-1]
+
+    # Check for special sequences.  Examples:
+    #    \012 --> \n
+    #    \"   --> "
+    #
+    i = 0
+    n = len(str)
+    res = []
+    while 0 <= i < n:
+        Omatch = _OctalPatt.search(str, i)
+        Qmatch = _QuotePatt.search(str, i)
+        if not Omatch and not Qmatch:              # Neither matched
+            res.append(str[i:])
+            break
+        # else:
+        j = k = -1
+        if Omatch: j = Omatch.start(0)
+        if Qmatch: k = Qmatch.start(0)
+        if Qmatch and ( not Omatch or k < j ):     # QuotePatt matched
+            res.append(str[i:k])
+            res.append(str[k+1])
+            i = k+2
+        else:                                      # OctalPatt matched
+            res.append(str[i:j])
+            res.append( chr( int(str[j+1:j+4], 8) ) )
+            i = j+4
+    return _nulljoin(res)
+# end _unquote
+
+# The _getdate() routine is used to set the expiration time in
+# the cookie's HTTP header.      By default, _getdate() returns the
+# current time in the appropriate "expires" format for a
+# Set-Cookie header.     The one optional argument is an offset from
+# now, in seconds.      For example, an offset of -3600 means "one hour ago".
+# The offset may be a floating point number.
+#
+
+_weekdayname = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
+
+_monthname = [None,
+              'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
+              'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
+
+def _getdate(future=0, weekdayname=_weekdayname, monthname=_monthname):
+    from time import gmtime, time
+    now = time()
+    year, month, day, hh, mm, ss, wd, y, z = gmtime(now + future)
+    return "%s, %02d-%3s-%4d %02d:%02d:%02d GMT" % \
+           (weekdayname[wd], day, monthname[month], year, hh, mm, ss)
+
+
+#
+# A class to hold ONE key,value pair.
+# In a cookie, each such pair may have several attributes.
+#       so this class is used to keep the attributes associated
+#       with the appropriate key,value pair.
+# This class also includes a coded_value attribute, which
+#       is used to hold the network representation of the
+#       value.  This is most useful when Python objects are
+#       pickled for network transit.
+#
+
+class Morsel(dict):
+    # RFC 2109 lists these attributes as reserved:
+    #   path       comment         domain
+    #   max-age    secure      version
+    #
+    # For historical reasons, these attributes are also reserved:
+    #   expires
+    #
+    # This dictionary provides a mapping from the lowercase
+    # variant on the left to the appropriate traditional
+    # formatting on the right.
+    _reserved = { "expires" : "expires",
+                   "path"        : "Path",
+                   "comment" : "Comment",
+                   "domain"      : "Domain",
+                   "max-age" : "Max-Age",
+                   "secure"      : "secure",
+                   "version" : "Version",
+                   }
+
+    def __init__(self):
+        # Set defaults
+        self.key = self.value = self.coded_value = None
+
+        # Set default attributes
+        for K in self._reserved:
+            dict.__setitem__(self, K, "")
+    # end __init__
+
+    def __setitem__(self, K, V):
+        K = K.lower()
+        if not K in self._reserved:
+            raise CookieError("Invalid Attribute %s" % K)
+        dict.__setitem__(self, K, V)
+    # end __setitem__
+
+    def isReservedKey(self, K):
+        return K.lower() in self._reserved
+    # end isReservedKey
+
+    def set(self, key, val, coded_val,
+            LegalChars=_LegalChars,
+            idmap=_idmap, translate=string.translate):
+        # First we verify that the key isn't a reserved word
+        # Second we make sure it only contains legal characters
+        if key.lower() in self._reserved:
+            raise CookieError("Attempt to set a reserved key: %s" % key)
+        if "" != translate(key, idmap, LegalChars):
+            raise CookieError("Illegal key value: %s" % key)
+
+        # It's a good key, so save it.
+        self.key                 = key
+        self.value               = val
+        self.coded_value         = coded_val
+    # end set
+
+    def output(self, attrs=None, header = "Set-Cookie:"):
+        return "%s %s" % ( header, self.OutputString(attrs) )
+
+    __str__ = output
+
+    def __repr__(self):
+        return '<%s: %s=%s>' % (self.__class__.__name__,
+                                self.key, repr(self.value) )
+
+    def js_output(self, attrs=None):
+        # Print javascript
+        return """
+        <script type="text/javascript">
+        <!-- begin hiding
+        document.cookie = \"%s\";
+        // end hiding -->
+        </script>
+        """ % ( self.OutputString(attrs), )
+    # end js_output()
+
+    def OutputString(self, attrs=None):
+        # Build up our result
+        #
+        result = []
+        RA = result.append
+
+        # First, the key=value pair
+        RA("%s=%s" % (self.key, self.coded_value))
+
+        # Now add any defined attributes
+        if attrs is None:
+            attrs = self._reserved
+        items = self.items()
+        items.sort()
+        for K,V in items:
+            if V == "": continue
+            if K not in attrs: continue
+            if K == "expires" and type(V) == type(1):
+                RA("%s=%s" % (self._reserved[K], _getdate(V)))
+            elif K == "max-age" and type(V) == type(1):
+                RA("%s=%d" % (self._reserved[K], V))
+            elif K == "secure":
+                RA(str(self._reserved[K]))
+            else:
+                RA("%s=%s" % (self._reserved[K], V))
+
+        # Return the result
+        return _semispacejoin(result)
+    # end OutputString
+# end Morsel class
+
+
+
+#
+# Pattern for finding cookie
+#
+# This used to be strict parsing based on the RFC2109 and RFC2068
+# specifications.  I have since discovered that MSIE 3.0x doesn't
+# follow the character rules outlined in those specs.  As a
+# result, the parsing rules here are less strict.
+#
+
+_LegalCharsPatt  = r"[\w\d!#%&'~_`><@,:/\$\*\+\-\.\^\|\)\(\?\}\{\=]"
+_CookiePattern = re.compile(
+    r"(?x)"                       # This is a Verbose pattern
+    r"(?P<key>"                   # Start of group 'key'
+    ""+ _LegalCharsPatt +"+?"     # Any word of at least one letter, nongreedy
+    r")"                          # End of group 'key'
+    r"\s*=\s*"                    # Equal Sign
+    r"(?P<val>"                   # Start of group 'val'
+    r'"(?:[^\\"]|\\.)*"'            # Any doublequoted string
+    r"|"                            # or
+    ""+ _LegalCharsPatt +"*"        # Any word or empty string
+    r")"                          # End of group 'val'
+    r"\s*;?"                      # Probably ending in a semi-colon
+    )
+
+
+# At long last, here is the cookie class.
+#   Using this class is almost just like using a dictionary.
+# See this module's docstring for example usage.
+#
+class BaseCookie(dict):
+    # A container class for a set of Morsels
+    #
+
+    def value_decode(self, val):
+        """real_value, coded_value = value_decode(STRING)
+        Called prior to setting a cookie's value from the network
+        representation.  The VALUE is the value read from HTTP
+        header.
+        Override this function to modify the behavior of cookies.
+        """
+        return val, val
+    # end value_encode
+
+    def value_encode(self, val):
+        """real_value, coded_value = value_encode(VALUE)
+        Called prior to setting a cookie's value from the dictionary
+        representation.  The VALUE is the value being assigned.
+        Override this function to modify the behavior of cookies.
+        """
+        strval = str(val)
+        return strval, strval
+    # end value_encode
+
+    def __init__(self, input=None):
+        if input: self.load(input)
+    # end __init__
+
+    def __set(self, key, real_value, coded_value):
+        """Private method for setting a cookie's value"""
+        M = self.get(key, Morsel())
+        M.set(key, real_value, coded_value)
+        dict.__setitem__(self, key, M)
+    # end __set
+
+    def __setitem__(self, key, value):
+        """Dictionary style assignment."""
+        rval, cval = self.value_encode(value)
+        self.__set(key, rval, cval)
+    # end __setitem__
+
+    def output(self, attrs=None, header="Set-Cookie:", sep="\015\012"):
+        """Return a string suitable for HTTP."""
+        result = []
+        items = self.items()
+        items.sort()
+        for K,V in items:
+            result.append( V.output(attrs, header) )
+        return sep.join(result)
+    # end output
+
+    __str__ = output
+
+    def __repr__(self):
+        L = []
+        items = self.items()
+        items.sort()
+        for K,V in items:
+            L.append( '%s=%s' % (K,repr(V.value) ) )
+        return '<%s: %s>' % (self.__class__.__name__, _spacejoin(L))
+
+    def js_output(self, attrs=None):
+        """Return a string suitable for JavaScript."""
+        result = []
+        items = self.items()
+        items.sort()
+        for K,V in items:
+            result.append( V.js_output(attrs) )
+        return _nulljoin(result)
+    # end js_output
+
+    def load(self, rawdata):
+        """Load cookies from a string (presumably HTTP_COOKIE) or
+        from a dictionary.  Loading cookies from a dictionary 'd'
+        is equivalent to calling:
+            map(Cookie.__setitem__, d.keys(), d.values())
+        """
+        if type(rawdata) == type(""):
+            self.__ParseString(rawdata)
+        else:
+            self.update(rawdata)
+        return
+    # end load()
+
+    def __ParseString(self, str, patt=_CookiePattern):
+        i = 0            # Our starting point
+        n = len(str)     # Length of string
+        M = None         # current morsel
+
+        while 0 <= i < n:
+            # Start looking for a cookie
+            match = patt.search(str, i)
+            if not match: break          # No more cookies
+
+            K,V = match.group("key"), match.group("val")
+            i = match.end(0)
+
+            # Parse the key, value in case it's metainfo
+            if K[0] == "$":
+                # We ignore attributes which pertain to the cookie
+                # mechanism as a whole.  See RFC 2109.
+                # (Does anyone care?)
+                if M:
+                    M[ K[1:] ] = V
+            elif K.lower() in Morsel._reserved:
+                if M:
+                    M[ K ] = _unquote(V)
+            else:
+                rval, cval = self.value_decode(V)
+                self.__set(K, rval, cval)
+                M = self[K]
+    # end __ParseString
+# end BaseCookie class
+
+class SimpleCookie(BaseCookie):
+    """SimpleCookie
+    SimpleCookie supports strings as cookie values.  When setting
+    the value using the dictionary assignment notation, SimpleCookie
+    calls the builtin str() to convert the value to a string.  Values
+    received from HTTP are kept as strings.
+    """
+    def value_decode(self, val):
+        return _unquote( val ), val
+    def value_encode(self, val):
+        strval = str(val)
+        return strval, _quote( strval )
+# end SimpleCookie
+
+class SerialCookie(BaseCookie):
+    """SerialCookie
+    SerialCookie supports arbitrary objects as cookie values. All
+    values are serialized (using cPickle) before being sent to the
+    client.  All incoming values are assumed to be valid Pickle
+    representations.  IF AN INCOMING VALUE IS NOT IN A VALID PICKLE
+    FORMAT, THEN AN EXCEPTION WILL BE RAISED.
+
+    Note: Large cookie values add overhead because they must be
+    retransmitted on every HTTP transaction.
+
+    Note: HTTP has a 2k limit on the size of a cookie.  This class
+    does not check for this limit, so be careful!!!
+    """
+    def __init__(self, input=None):
+        warnings.warn("SerialCookie class is insecure; do not use it",
+                      DeprecationWarning)
+        BaseCookie.__init__(self, input)
+    # end __init__
+    def value_decode(self, val):
+        # This could raise an exception!
+        return loads( _unquote(val) ), val
+    def value_encode(self, val):
+        return val, _quote( dumps(val) )
+# end SerialCookie
+
+class SmartCookie(BaseCookie):
+    """SmartCookie
+    SmartCookie supports arbitrary objects as cookie values.  If the
+    object is a string, then it is quoted.  If the object is not a
+    string, however, then SmartCookie will use cPickle to serialize
+    the object into a string representation.
+
+    Note: Large cookie values add overhead because they must be
+    retransmitted on every HTTP transaction.
+
+    Note: HTTP has a 2k limit on the size of a cookie.  This class
+    does not check for this limit, so be careful!!!
+    """
+    def __init__(self, input=None):
+        warnings.warn("Cookie/SmartCookie class is insecure; do not use it",
+                      DeprecationWarning)
+        BaseCookie.__init__(self, input)
+    # end __init__
+    def value_decode(self, val):
+        strval = _unquote(val)
+        try:
+            return loads(strval), val
+        except:
+            return strval, val
+    def value_encode(self, val):
+        if type(val) == type(""):
+            return val, _quote(val)
+        else:
+            return val, _quote( dumps(val) )
+# end SmartCookie
+
+
+###########################################################
+# Backwards Compatibility:  Don't break any existing code!
+
+# We provide Cookie() as an alias for SmartCookie()
+Cookie = SmartCookie
+
+#
+###########################################################
+
+def _test():
+    import doctest, Cookie
+    return doctest.testmod(Cookie)
+
+if __name__ == "__main__":
+    _test()
+
+
+#Local Variables:
+#tab-width: 4
+#end:

Added: vendor/Python/current/Lib/DocXMLRPCServer.py
===================================================================
--- vendor/Python/current/Lib/DocXMLRPCServer.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/DocXMLRPCServer.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,306 @@
+"""Self documenting XML-RPC Server.
+
+This module can be used to create XML-RPC servers that
+serve pydoc-style documentation in response to HTTP
+GET requests. This documentation is dynamically generated
+based on the functions and methods registered with the
+server.
+
+This module is built upon the pydoc and SimpleXMLRPCServer
+modules.
+"""
+
+import pydoc
+import inspect
+import re
+import sys
+
+from SimpleXMLRPCServer import (SimpleXMLRPCServer,
+            SimpleXMLRPCRequestHandler,
+            CGIXMLRPCRequestHandler,
+            resolve_dotted_attribute)
+
+class ServerHTMLDoc(pydoc.HTMLDoc):
+    """Class used to generate pydoc HTML document for a server"""
+
+    def markup(self, text, escape=None, funcs={}, classes={}, methods={}):
+        """Mark up some plain text, given a context of symbols to look for.
+        Each context dictionary maps object names to anchor names."""
+        escape = escape or self.escape
+        results = []
+        here = 0
+
+        # XXX Note that this regular expressions does not allow for the
+        # hyperlinking of arbitrary strings being used as method
+        # names. Only methods with names consisting of word characters
+        # and '.'s are hyperlinked.
+        pattern = re.compile(r'\b((http|ftp)://\S+[\w/]|'
+                                r'RFC[- ]?(\d+)|'
+                                r'PEP[- ]?(\d+)|'
+                                r'(self\.)?((?:\w|\.)+))\b')
+        while 1:
+            match = pattern.search(text, here)
+            if not match: break
+            start, end = match.span()
+            results.append(escape(text[here:start]))
+
+            all, scheme, rfc, pep, selfdot, name = match.groups()
+            if scheme:
+                url = escape(all).replace('"', '&quot;')
+                results.append('<a href="%s">%s</a>' % (url, url))
+            elif rfc:
+                url = 'http://www.rfc-editor.org/rfc/rfc%d.txt' % int(rfc)
+                results.append('<a href="%s">%s</a>' % (url, escape(all)))
+            elif pep:
+                url = 'http://www.python.org/peps/pep-%04d.html' % int(pep)
+                results.append('<a href="%s">%s</a>' % (url, escape(all)))
+            elif text[end:end+1] == '(':
+                results.append(self.namelink(name, methods, funcs, classes))
+            elif selfdot:
+                results.append('self.<strong>%s</strong>' % name)
+            else:
+                results.append(self.namelink(name, classes))
+            here = end
+        results.append(escape(text[here:]))
+        return ''.join(results)
+
+    def docroutine(self, object, name=None, mod=None,
+                   funcs={}, classes={}, methods={}, cl=None):
+        """Produce HTML documentation for a function or method object."""
+
+        anchor = (cl and cl.__name__ or '') + '-' + name
+        note = ''
+
+        title = '<a name="%s"><strong>%s</strong></a>' % (anchor, name)
+
+        if inspect.ismethod(object):
+            args, varargs, varkw, defaults = inspect.getargspec(object.im_func)
+            # exclude the argument bound to the instance, it will be
+            # confusing to the non-Python user
+            argspec = inspect.formatargspec (
+                    args[1:],
+                    varargs,
+                    varkw,
+                    defaults,
+                    formatvalue=self.formatvalue
+                )
+        elif inspect.isfunction(object):
+            args, varargs, varkw, defaults = inspect.getargspec(object)
+            argspec = inspect.formatargspec(
+                args, varargs, varkw, defaults, formatvalue=self.formatvalue)
+        else:
+            argspec = '(...)'
+
+        if isinstance(object, tuple):
+            argspec = object[0] or argspec
+            docstring = object[1] or ""
+        else:
+            docstring = pydoc.getdoc(object)
+
+        decl = title + argspec + (note and self.grey(
+               '<font face="helvetica, arial">%s</font>' % note))
+
+        doc = self.markup(
+            docstring, self.preformat, funcs, classes, methods)
+        doc = doc and '<dd><tt>%s</tt></dd>' % doc
+        return '<dl><dt>%s</dt>%s</dl>\n' % (decl, doc)
+
+    def docserver(self, server_name, package_documentation, methods):
+        """Produce HTML documentation for an XML-RPC server."""
+
+        fdict = {}
+        for key, value in methods.items():
+            fdict[key] = '#-' + key
+            fdict[value] = fdict[key]
+
+        head = '<big><big><strong>%s</strong></big></big>' % server_name
+        result = self.heading(head, '#ffffff', '#7799ee')
+
+        doc = self.markup(package_documentation, self.preformat, fdict)
+        doc = doc and '<tt>%s</tt>' % doc
+        result = result + '<p>%s</p>\n' % doc
+
+        contents = []
+        method_items = methods.items()
+        method_items.sort()
+        for key, value in method_items:
+            contents.append(self.docroutine(value, key, funcs=fdict))
+        result = result + self.bigsection(
+            'Methods', '#ffffff', '#eeaa77', pydoc.join(contents))
+
+        return result
+
+class XMLRPCDocGenerator:
+    """Generates documentation for an XML-RPC server.
+
+    This class is designed as mix-in and should not
+    be constructed directly.
+    """
+
+    def __init__(self):
+        # setup variables used for HTML documentation
+        self.server_name = 'XML-RPC Server Documentation'
+        self.server_documentation = \
+            "This server exports the following methods through the XML-RPC "\
+            "protocol."
+        self.server_title = 'XML-RPC Server Documentation'
+
+    def set_server_title(self, server_title):
+        """Set the HTML title of the generated server documentation"""
+
+        self.server_title = server_title
+
+    def set_server_name(self, server_name):
+        """Set the name of the generated HTML server documentation"""
+
+        self.server_name = server_name
+
+    def set_server_documentation(self, server_documentation):
+        """Set the documentation string for the entire server."""
+
+        self.server_documentation = server_documentation
+
+    def generate_html_documentation(self):
+        """generate_html_documentation() => html documentation for the server
+
+        Generates HTML documentation for the server using introspection for
+        installed functions and instances that do not implement the
+        _dispatch method. Alternatively, instances can choose to implement
+        the _get_method_argstring(method_name) method to provide the
+        argument string used in the documentation and the
+        _methodHelp(method_name) method to provide the help text used
+        in the documentation."""
+
+        methods = {}
+
+        for method_name in self.system_listMethods():
+            if self.funcs.has_key(method_name):
+                method = self.funcs[method_name]
+            elif self.instance is not None:
+                method_info = [None, None] # argspec, documentation
+                if hasattr(self.instance, '_get_method_argstring'):
+                    method_info[0] = self.instance._get_method_argstring(method_name)
+                if hasattr(self.instance, '_methodHelp'):
+                    method_info[1] = self.instance._methodHelp(method_name)
+
+                method_info = tuple(method_info)
+                if method_info != (None, None):
+                    method = method_info
+                elif not hasattr(self.instance, '_dispatch'):
+                    try:
+                        method = resolve_dotted_attribute(
+                                    self.instance,
+                                    method_name
+                                    )
+                    except AttributeError:
+                        method = method_info
+                else:
+                    method = method_info
+            else:
+                assert 0, "Could not find method in self.functions and no "\
+                          "instance installed"
+
+            methods[method_name] = method
+
+        documenter = ServerHTMLDoc()
+        documentation = documenter.docserver(
+                                self.server_name,
+                                self.server_documentation,
+                                methods
+                            )
+
+        return documenter.page(self.server_title, documentation)
+
+class DocXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
+    """XML-RPC and documentation request handler class.
+
+    Handles all HTTP POST requests and attempts to decode them as
+    XML-RPC requests.
+
+    Handles all HTTP GET requests and interprets them as requests
+    for documentation.
+    """
+
+    def do_GET(self):
+        """Handles the HTTP GET request.
+
+        Interpret all HTTP GET requests as requests for server
+        documentation.
+        """
+        # Check that the path is legal
+        if not self.is_rpc_path_valid():
+            self.report_404()
+            return
+
+        response = self.server.generate_html_documentation()
+        self.send_response(200)
+        self.send_header("Content-type", "text/html")
+        self.send_header("Content-length", str(len(response)))
+        self.end_headers()
+        self.wfile.write(response)
+
+        # shut down the connection
+        self.wfile.flush()
+        self.connection.shutdown(1)
+
+class DocXMLRPCServer(  SimpleXMLRPCServer,
+                        XMLRPCDocGenerator):
+    """XML-RPC and HTML documentation server.
+
+    Adds the ability to serve server documentation to the capabilities
+    of SimpleXMLRPCServer.
+    """
+
+    def __init__(self, addr, requestHandler=DocXMLRPCRequestHandler,
+                 logRequests=1):
+        SimpleXMLRPCServer.__init__(self, addr, requestHandler, logRequests)
+        XMLRPCDocGenerator.__init__(self)
+
+class DocCGIXMLRPCRequestHandler(   CGIXMLRPCRequestHandler,
+                                    XMLRPCDocGenerator):
+    """Handler for XML-RPC data and documentation requests passed through
+    CGI"""
+
+    def handle_get(self):
+        """Handles the HTTP GET request.
+
+        Interpret all HTTP GET requests as requests for server
+        documentation.
+        """
+
+        response = self.generate_html_documentation()
+
+        print 'Content-Type: text/html'
+        print 'Content-Length: %d' % len(response)
+        print
+        sys.stdout.write(response)
+
+    def __init__(self):
+        CGIXMLRPCRequestHandler.__init__(self)
+        XMLRPCDocGenerator.__init__(self)
+
+if __name__ == '__main__':
+    def deg_to_rad(deg):
+        """deg_to_rad(90) => 1.5707963267948966
+
+        Converts an angle in degrees to an angle in radians"""
+        import math
+        return deg * math.pi / 180
+
+    server = DocXMLRPCServer(("localhost", 8000))
+
+    server.set_server_title("Math Server")
+    server.set_server_name("Math XML-RPC Server")
+    server.set_server_documentation("""This server supports various mathematical functions.
+
+You can use it from Python as follows:
+
+>>> from xmlrpclib import ServerProxy
+>>> s = ServerProxy("http://localhost:8000")
+>>> s.deg_to_rad(90.0)
+1.5707963267948966""")
+
+    server.register_function(deg_to_rad)
+    server.register_introspection_functions()
+
+    server.serve_forever()

Added: vendor/Python/current/Lib/HTMLParser.py
===================================================================
--- vendor/Python/current/Lib/HTMLParser.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/HTMLParser.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,369 @@
+"""A parser for HTML and XHTML."""
+
+# This file is based on sgmllib.py, but the API is slightly different.
+
+# XXX There should be a way to distinguish between PCDATA (parsed
+# character data -- the normal case), RCDATA (replaceable character
+# data -- only char and entity references and end tags are special)
+# and CDATA (character data -- only end tags are special).
+
+
+import markupbase
+import re
+
+# Regular expressions used for parsing
+
+interesting_normal = re.compile('[&<]')
+interesting_cdata = re.compile(r'<(/|\Z)')
+incomplete = re.compile('&[a-zA-Z#]')
+
+entityref = re.compile('&([a-zA-Z][-.a-zA-Z0-9]*)[^a-zA-Z0-9]')
+charref = re.compile('&#(?:[0-9]+|[xX][0-9a-fA-F]+)[^0-9a-fA-F]')
+
+starttagopen = re.compile('<[a-zA-Z]')
+piclose = re.compile('>')
+commentclose = re.compile(r'--\s*>')
+tagfind = re.compile('[a-zA-Z][-.a-zA-Z0-9:_]*')
+attrfind = re.compile(
+    r'\s*([a-zA-Z_][-.:a-zA-Z_0-9]*)(\s*=\s*'
+    r'(\'[^\']*\'|"[^"]*"|[-a-zA-Z0-9./,:;+*%?!&$\(\)_#=~@]*))?')
+
+locatestarttagend = re.compile(r"""
+  <[a-zA-Z][-.a-zA-Z0-9:_]*          # tag name
+  (?:\s+                             # whitespace before attribute name
+    (?:[a-zA-Z_][-.:a-zA-Z0-9_]*     # attribute name
+      (?:\s*=\s*                     # value indicator
+        (?:'[^']*'                   # LITA-enclosed value
+          |\"[^\"]*\"                # LIT-enclosed value
+          |[^'\">\s]+                # bare value
+         )
+       )?
+     )
+   )*
+  \s*                                # trailing whitespace
+""", re.VERBOSE)
+endendtag = re.compile('>')
+endtagfind = re.compile('</\s*([a-zA-Z][-.a-zA-Z0-9:_]*)\s*>')
+
+
+class HTMLParseError(Exception):
+    """Exception raised for all parse errors."""
+
+    def __init__(self, msg, position=(None, None)):
+        assert msg
+        self.msg = msg
+        self.lineno = position[0]
+        self.offset = position[1]
+
+    def __str__(self):
+        result = self.msg
+        if self.lineno is not None:
+            result = result + ", at line %d" % self.lineno
+        if self.offset is not None:
+            result = result + ", column %d" % (self.offset + 1)
+        return result
+
+
+class HTMLParser(markupbase.ParserBase):
+    """Find tags and other markup and call handler functions.
+
+    Usage:
+        p = HTMLParser()
+        p.feed(data)
+        ...
+        p.close()
+
+    Start tags are handled by calling self.handle_starttag() or
+    self.handle_startendtag(); end tags by self.handle_endtag().  The
+    data between tags is passed from the parser to the derived class
+    by calling self.handle_data() with the data as argument (the data
+    may be split up in arbitrary chunks).  Entity references are
+    passed by calling self.handle_entityref() with the entity
+    reference as the argument.  Numeric character references are
+    passed to self.handle_charref() with the string containing the
+    reference as the argument.
+    """
+
+    CDATA_CONTENT_ELEMENTS = ("script", "style")
+
+
+    def __init__(self):
+        """Initialize and reset this instance."""
+        self.reset()
+
+    def reset(self):
+        """Reset this instance.  Loses all unprocessed data."""
+        self.rawdata = ''
+        self.lasttag = '???'
+        self.interesting = interesting_normal
+        markupbase.ParserBase.reset(self)
+
+    def feed(self, data):
+        """Feed data to the parser.
+
+        Call this as often as you want, with as little or as much text
+        as you want (may include '\n').
+        """
+        self.rawdata = self.rawdata + data
+        self.goahead(0)
+
+    def close(self):
+        """Handle any buffered data."""
+        self.goahead(1)
+
+    def error(self, message):
+        raise HTMLParseError(message, self.getpos())
+
+    __starttag_text = None
+
+    def get_starttag_text(self):
+        """Return full source of start tag: '<...>'."""
+        return self.__starttag_text
+
+    def set_cdata_mode(self):
+        self.interesting = interesting_cdata
+
+    def clear_cdata_mode(self):
+        self.interesting = interesting_normal
+
+    # Internal -- handle data as far as reasonable.  May leave state
+    # and data to be processed by a subsequent call.  If 'end' is
+    # true, force handling all data as if followed by EOF marker.
+    def goahead(self, end):
+        rawdata = self.rawdata
+        i = 0
+        n = len(rawdata)
+        while i < n:
+            match = self.interesting.search(rawdata, i) # < or &
+            if match:
+                j = match.start()
+            else:
+                j = n
+            if i < j: self.handle_data(rawdata[i:j])
+            i = self.updatepos(i, j)
+            if i == n: break
+            startswith = rawdata.startswith
+            if startswith('<', i):
+                if starttagopen.match(rawdata, i): # < + letter
+                    k = self.parse_starttag(i)
+                elif startswith("</", i):
+                    k = self.parse_endtag(i)
+                elif startswith("<!--", i):
+                    k = self.parse_comment(i)
+                elif startswith("<?", i):
+                    k = self.parse_pi(i)
+                elif startswith("<!", i):
+                    k = self.parse_declaration(i)
+                elif (i + 1) < n:
+                    self.handle_data("<")
+                    k = i + 1
+                else:
+                    break
+                if k < 0:
+                    if end:
+                        self.error("EOF in middle of construct")
+                    break
+                i = self.updatepos(i, k)
+            elif startswith("&#", i):
+                match = charref.match(rawdata, i)
+                if match:
+                    name = match.group()[2:-1]
+                    self.handle_charref(name)
+                    k = match.end()
+                    if not startswith(';', k-1):
+                        k = k - 1
+                    i = self.updatepos(i, k)
+                    continue
+                else:
+                    break
+            elif startswith('&', i):
+                match = entityref.match(rawdata, i)
+                if match:
+                    name = match.group(1)
+                    self.handle_entityref(name)
+                    k = match.end()
+                    if not startswith(';', k-1):
+                        k = k - 1
+                    i = self.updatepos(i, k)
+                    continue
+                match = incomplete.match(rawdata, i)
+                if match:
+                    # match.group() will contain at least 2 chars
+                    if end and match.group() == rawdata[i:]:
+                        self.error("EOF in middle of entity or char ref")
+                    # incomplete
+                    break
+                elif (i + 1) < n:
+                    # not the end of the buffer, and can't be confused
+                    # with some other construct
+                    self.handle_data("&")
+                    i = self.updatepos(i, i + 1)
+                else:
+                    break
+            else:
+                assert 0, "interesting.search() lied"
+        # end while
+        if end and i < n:
+            self.handle_data(rawdata[i:n])
+            i = self.updatepos(i, n)
+        self.rawdata = rawdata[i:]
+
+    # Internal -- parse processing instr, return end or -1 if not terminated
+    def parse_pi(self, i):
+        rawdata = self.rawdata
+        assert rawdata[i:i+2] == '<?', 'unexpected call to parse_pi()'
+        match = piclose.search(rawdata, i+2) # >
+        if not match:
+            return -1
+        j = match.start()
+        self.handle_pi(rawdata[i+2: j])
+        j = match.end()
+        return j
+
+    # Internal -- handle starttag, return end or -1 if not terminated
+    def parse_starttag(self, i):
+        self.__starttag_text = None
+        endpos = self.check_for_whole_start_tag(i)
+        if endpos < 0:
+            return endpos
+        rawdata = self.rawdata
+        self.__starttag_text = rawdata[i:endpos]
+
+        # Now parse the data between i+1 and j into a tag and attrs
+        attrs = []
+        match = tagfind.match(rawdata, i+1)
+        assert match, 'unexpected call to parse_starttag()'
+        k = match.end()
+        self.lasttag = tag = rawdata[i+1:k].lower()
+
+        while k < endpos:
+            m = attrfind.match(rawdata, k)
+            if not m:
+                break
+            attrname, rest, attrvalue = m.group(1, 2, 3)
+            if not rest:
+                attrvalue = None
+            elif attrvalue[:1] == '\'' == attrvalue[-1:] or \
+                 attrvalue[:1] == '"' == attrvalue[-1:]:
+                attrvalue = attrvalue[1:-1]
+                attrvalue = self.unescape(attrvalue)
+            attrs.append((attrname.lower(), attrvalue))
+            k = m.end()
+
+        end = rawdata[k:endpos].strip()
+        if end not in (">", "/>"):
+            lineno, offset = self.getpos()
+            if "\n" in self.__starttag_text:
+                lineno = lineno + self.__starttag_text.count("\n")
+                offset = len(self.__starttag_text) \
+                         - self.__starttag_text.rfind("\n")
+            else:
+                offset = offset + len(self.__starttag_text)
+            self.error("junk characters in start tag: %r"
+                       % (rawdata[k:endpos][:20],))
+        if end.endswith('/>'):
+            # XHTML-style empty tag: <span attr="value" />
+            self.handle_startendtag(tag, attrs)
+        else:
+            self.handle_starttag(tag, attrs)
+            if tag in self.CDATA_CONTENT_ELEMENTS:
+                self.set_cdata_mode()
+        return endpos
+
+    # Internal -- check to see if we have a complete starttag; return end
+    # or -1 if incomplete.
+    def check_for_whole_start_tag(self, i):
+        rawdata = self.rawdata
+        m = locatestarttagend.match(rawdata, i)
+        if m:
+            j = m.end()
+            next = rawdata[j:j+1]
+            if next == ">":
+                return j + 1
+            if next == "/":
+                if rawdata.startswith("/>", j):
+                    return j + 2
+                if rawdata.startswith("/", j):
+                    # buffer boundary
+                    return -1
+                # else bogus input
+                self.updatepos(i, j + 1)
+                self.error("malformed empty start tag")
+            if next == "":
+                # end of input
+                return -1
+            if next in ("abcdefghijklmnopqrstuvwxyz=/"
+                        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"):
+                # end of input in or before attribute value, or we have the
+                # '/' from a '/>' ending
+                return -1
+            self.updatepos(i, j)
+            self.error("malformed start tag")
+        raise AssertionError("we should not get here!")
+
+    # Internal -- parse endtag, return end or -1 if incomplete
+    def parse_endtag(self, i):
+        rawdata = self.rawdata
+        assert rawdata[i:i+2] == "</", "unexpected call to parse_endtag"
+        match = endendtag.search(rawdata, i+1) # >
+        if not match:
+            return -1
+        j = match.end()
+        match = endtagfind.match(rawdata, i) # </ + tag + >
+        if not match:
+            self.error("bad end tag: %r" % (rawdata[i:j],))
+        tag = match.group(1)
+        self.handle_endtag(tag.lower())
+        self.clear_cdata_mode()
+        return j
+
+    # Overridable -- finish processing of start+end tag: <tag.../>
+    def handle_startendtag(self, tag, attrs):
+        self.handle_starttag(tag, attrs)
+        self.handle_endtag(tag)
+
+    # Overridable -- handle start tag
+    def handle_starttag(self, tag, attrs):
+        pass
+
+    # Overridable -- handle end tag
+    def handle_endtag(self, tag):
+        pass
+
+    # Overridable -- handle character reference
+    def handle_charref(self, name):
+        pass
+
+    # Overridable -- handle entity reference
+    def handle_entityref(self, name):
+        pass
+
+    # Overridable -- handle data
+    def handle_data(self, data):
+        pass
+
+    # Overridable -- handle comment
+    def handle_comment(self, data):
+        pass
+
+    # Overridable -- handle declaration
+    def handle_decl(self, decl):
+        pass
+
+    # Overridable -- handle processing instruction
+    def handle_pi(self, data):
+        pass
+
+    def unknown_decl(self, data):
+        self.error("unknown declaration: %r" % (data,))
+
+    # Internal -- helper to remove special character quoting
+    def unescape(self, s):
+        if '&' not in s:
+            return s
+        s = s.replace("&lt;", "<")
+        s = s.replace("&gt;", ">")
+        s = s.replace("&apos;", "'")
+        s = s.replace("&quot;", '"')
+        s = s.replace("&amp;", "&") # Must be last
+        return s

Added: vendor/Python/current/Lib/MimeWriter.py
===================================================================
--- vendor/Python/current/Lib/MimeWriter.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/MimeWriter.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,181 @@
+"""Generic MIME writer.
+
+This module defines the class MimeWriter.  The MimeWriter class implements
+a basic formatter for creating MIME multi-part files.  It doesn't seek around
+the output file nor does it use large amounts of buffer space. You must write
+the parts out in the order that they should occur in the final file.
+MimeWriter does buffer the headers you add, allowing you to rearrange their
+order.
+
+"""
+
+
+import mimetools
+
+__all__ = ["MimeWriter"]
+
+class MimeWriter:
+
+    """Generic MIME writer.
+
+    Methods:
+
+    __init__()
+    addheader()
+    flushheaders()
+    startbody()
+    startmultipartbody()
+    nextpart()
+    lastpart()
+
+    A MIME writer is much more primitive than a MIME parser.  It
+    doesn't seek around on the output file, and it doesn't use large
+    amounts of buffer space, so you have to write the parts in the
+    order they should occur on the output file.  It does buffer the
+    headers you add, allowing you to rearrange their order.
+
+    General usage is:
+
+    f = <open the output file>
+    w = MimeWriter(f)
+    ...call w.addheader(key, value) 0 or more times...
+
+    followed by either:
+
+    f = w.startbody(content_type)
+    ...call f.write(data) for body data...
+
+    or:
+
+    w.startmultipartbody(subtype)
+    for each part:
+        subwriter = w.nextpart()
+        ...use the subwriter's methods to create the subpart...
+    w.lastpart()
+
+    The subwriter is another MimeWriter instance, and should be
+    treated in the same way as the toplevel MimeWriter.  This way,
+    writing recursive body parts is easy.
+
+    Warning: don't forget to call lastpart()!
+
+    XXX There should be more state so calls made in the wrong order
+    are detected.
+
+    Some special cases:
+
+    - startbody() just returns the file passed to the constructor;
+      but don't use this knowledge, as it may be changed.
+
+    - startmultipartbody() actually returns a file as well;
+      this can be used to write the initial 'if you can read this your
+      mailer is not MIME-aware' message.
+
+    - If you call flushheaders(), the headers accumulated so far are
+      written out (and forgotten); this is useful if you don't need a
+      body part at all, e.g. for a subpart of type message/rfc822
+      that's (mis)used to store some header-like information.
+
+    - Passing a keyword argument 'prefix=<flag>' to addheader(),
+      start*body() affects where the header is inserted; 0 means
+      append at the end, 1 means insert at the start; default is
+      append for addheader(), but insert for start*body(), which use
+      it to determine where the Content-Type header goes.
+
+    """
+
+    def __init__(self, fp):
+        self._fp = fp
+        self._headers = []
+
+    def addheader(self, key, value, prefix=0):
+        """Add a header line to the MIME message.
+
+        The key is the name of the header, where the value obviously provides
+        the value of the header. The optional argument prefix determines
+        where the header is inserted; 0 means append at the end, 1 means
+        insert at the start. The default is to append.
+
+        """
+        lines = value.split("\n")
+        while lines and not lines[-1]: del lines[-1]
+        while lines and not lines[0]: del lines[0]
+        for i in range(1, len(lines)):
+            lines[i] = "    " + lines[i].strip()
+        value = "\n".join(lines) + "\n"
+        line = key + ": " + value
+        if prefix:
+            self._headers.insert(0, line)
+        else:
+            self._headers.append(line)
+
+    def flushheaders(self):
+        """Writes out and forgets all headers accumulated so far.
+
+        This is useful if you don't need a body part at all; for example,
+        for a subpart of type message/rfc822 that's (mis)used to store some
+        header-like information.
+
+        """
+        self._fp.writelines(self._headers)
+        self._headers = []
+
+    def startbody(self, ctype, plist=[], prefix=1):
+        """Returns a file-like object for writing the body of the message.
+
+        The content-type is set to the provided ctype, and the optional
+        parameter, plist, provides additional parameters for the
+        content-type declaration.  The optional argument prefix determines
+        where the header is inserted; 0 means append at the end, 1 means
+        insert at the start. The default is to insert at the start.
+
+        """
+        for name, value in plist:
+            ctype = ctype + ';\n %s=\"%s\"' % (name, value)
+        self.addheader("Content-Type", ctype, prefix=prefix)
+        self.flushheaders()
+        self._fp.write("\n")
+        return self._fp
+
+    def startmultipartbody(self, subtype, boundary=None, plist=[], prefix=1):
+        """Returns a file-like object for writing the body of the message.
+
+        Additionally, this method initializes the multi-part code, where the
+        subtype parameter provides the multipart subtype, the boundary
+        parameter may provide a user-defined boundary specification, and the
+        plist parameter provides optional parameters for the subtype.  The
+        optional argument, prefix, determines where the header is inserted;
+        0 means append at the end, 1 means insert at the start. The default
+        is to insert at the start.  Subparts should be created using the
+        nextpart() method.
+
+        """
+        self._boundary = boundary or mimetools.choose_boundary()
+        return self.startbody("multipart/" + subtype,
+                              [("boundary", self._boundary)] + plist,
+                              prefix=prefix)
+
+    def nextpart(self):
+        """Returns a new instance of MimeWriter which represents an
+        individual part in a multipart message.
+
+        This may be used to write the part as well as used for creating
+        recursively complex multipart messages. The message must first be
+        initialized with the startmultipartbody() method before using the
+        nextpart() method.
+
+        """
+        self._fp.write("\n--" + self._boundary + "\n")
+        return self.__class__(self._fp)
+
+    def lastpart(self):
+        """This is used to designate the last part of a multipart message.
+
+        It should always be used when writing multipart messages.
+
+        """
+        self._fp.write("\n--" + self._boundary + "--\n")
+
+
+if __name__ == '__main__':
+    import test.test_MimeWriter

Added: vendor/Python/current/Lib/Queue.py
===================================================================
--- vendor/Python/current/Lib/Queue.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/Queue.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,215 @@
+"""A multi-producer, multi-consumer queue."""
+
+from time import time as _time
+from collections import deque
+
+__all__ = ['Empty', 'Full', 'Queue']
+
+class Empty(Exception):
+    "Exception raised by Queue.get(block=0)/get_nowait()."
+    pass
+
+class Full(Exception):
+    "Exception raised by Queue.put(block=0)/put_nowait()."
+    pass
+
+class Queue:
+    """Create a queue object with a given maximum size.
+
+    If maxsize is <= 0, the queue size is infinite.
+    """
+    def __init__(self, maxsize=0):
+        try:
+            import threading
+        except ImportError:
+            import dummy_threading as threading
+        self._init(maxsize)
+        # mutex must be held whenever the queue is mutating.  All methods
+        # that acquire mutex must release it before returning.  mutex
+        # is shared between the three conditions, so acquiring and
+        # releasing the conditions also acquires and releases mutex.
+        self.mutex = threading.Lock()
+        # Notify not_empty whenever an item is added to the queue; a
+        # thread waiting to get is notified then.
+        self.not_empty = threading.Condition(self.mutex)
+        # Notify not_full whenever an item is removed from the queue;
+        # a thread waiting to put is notified then.
+        self.not_full = threading.Condition(self.mutex)
+        # Notify all_tasks_done whenever the number of unfinished tasks
+        # drops to zero; thread waiting to join() is notified to resume
+        self.all_tasks_done = threading.Condition(self.mutex)
+        self.unfinished_tasks = 0
+
+    def task_done(self):
+        """Indicate that a formerly enqueued task is complete.
+
+        Used by Queue consumer threads.  For each get() used to fetch a task,
+        a subsequent call to task_done() tells the queue that the processing
+        on the task is complete.
+
+        If a join() is currently blocking, it will resume when all items
+        have been processed (meaning that a task_done() call was received
+        for every item that had been put() into the queue).
+
+        Raises a ValueError if called more times than there were items
+        placed in the queue.
+        """
+        self.all_tasks_done.acquire()
+        try:
+            unfinished = self.unfinished_tasks - 1
+            if unfinished <= 0:
+                if unfinished < 0:
+                    raise ValueError('task_done() called too many times')
+                self.all_tasks_done.notifyAll()
+            self.unfinished_tasks = unfinished
+        finally:
+            self.all_tasks_done.release()
+
+    def join(self):
+        """Blocks until all items in the Queue have been gotten and processed.
+
+        The count of unfinished tasks goes up whenever an item is added to the
+        queue. The count goes down whenever a consumer thread calls task_done()
+        to indicate the item was retrieved and all work on it is complete.
+
+        When the count of unfinished tasks drops to zero, join() unblocks.
+        """
+        self.all_tasks_done.acquire()
+        try:
+            while self.unfinished_tasks:
+                self.all_tasks_done.wait()
+        finally:
+            self.all_tasks_done.release()
+
+    def qsize(self):
+        """Return the approximate size of the queue (not reliable!)."""
+        self.mutex.acquire()
+        n = self._qsize()
+        self.mutex.release()
+        return n
+
+    def empty(self):
+        """Return True if the queue is empty, False otherwise (not reliable!)."""
+        self.mutex.acquire()
+        n = self._empty()
+        self.mutex.release()
+        return n
+
+    def full(self):
+        """Return True if the queue is full, False otherwise (not reliable!)."""
+        self.mutex.acquire()
+        n = self._full()
+        self.mutex.release()
+        return n
+
+    def put(self, item, block=True, timeout=None):
+        """Put an item into the queue.
+
+        If optional args 'block' is true and 'timeout' is None (the default),
+        block if necessary until a free slot is available. If 'timeout' is
+        a positive number, it blocks at most 'timeout' seconds and raises
+        the Full exception if no free slot was available within that time.
+        Otherwise ('block' is false), put an item on the queue if a free slot
+        is immediately available, else raise the Full exception ('timeout'
+        is ignored in that case).
+        """
+        self.not_full.acquire()
+        try:
+            if not block:
+                if self._full():
+                    raise Full
+            elif timeout is None:
+                while self._full():
+                    self.not_full.wait()
+            else:
+                if timeout < 0:
+                    raise ValueError("'timeout' must be a positive number")
+                endtime = _time() + timeout
+                while self._full():
+                    remaining = endtime - _time()
+                    if remaining <= 0.0:
+                        raise Full
+                    self.not_full.wait(remaining)
+            self._put(item)
+            self.unfinished_tasks += 1
+            self.not_empty.notify()
+        finally:
+            self.not_full.release()
+
+    def put_nowait(self, item):
+        """Put an item into the queue without blocking.
+
+        Only enqueue the item if a free slot is immediately available.
+        Otherwise raise the Full exception.
+        """
+        return self.put(item, False)
+
+    def get(self, block=True, timeout=None):
+        """Remove and return an item from the queue.
+
+        If optional args 'block' is true and 'timeout' is None (the default),
+        block if necessary until an item is available. If 'timeout' is
+        a positive number, it blocks at most 'timeout' seconds and raises
+        the Empty exception if no item was available within that time.
+        Otherwise ('block' is false), return an item if one is immediately
+        available, else raise the Empty exception ('timeout' is ignored
+        in that case).
+        """
+        self.not_empty.acquire()
+        try:
+            if not block:
+                if self._empty():
+                    raise Empty
+            elif timeout is None:
+                while self._empty():
+                    self.not_empty.wait()
+            else:
+                if timeout < 0:
+                    raise ValueError("'timeout' must be a positive number")
+                endtime = _time() + timeout
+                while self._empty():
+                    remaining = endtime - _time()
+                    if remaining <= 0.0:
+                        raise Empty
+                    self.not_empty.wait(remaining)
+            item = self._get()
+            self.not_full.notify()
+            return item
+        finally:
+            self.not_empty.release()
+
+    def get_nowait(self):
+        """Remove and return an item from the queue without blocking.
+
+        Only get an item if one is immediately available. Otherwise
+        raise the Empty exception.
+        """
+        return self.get(False)
+
+    # Override these methods to implement other queue organizations
+    # (e.g. stack or priority queue).
+    # These will only be called with appropriate locks held
+
+    # Initialize the queue representation
+    def _init(self, maxsize):
+        self.maxsize = maxsize
+        self.queue = deque()
+
+    def _qsize(self):
+        return len(self.queue)
+
+    # Check whether the queue is empty
+    def _empty(self):
+        return not self.queue
+
+    # Check whether the queue is full
+    def _full(self):
+        return self.maxsize > 0 and len(self.queue) == self.maxsize
+
+    # Put a new item in the queue
+    def _put(self, item):
+        self.queue.append(item)
+
+    # Get an item from the queue
+    def _get(self):
+        return self.queue.popleft()

Added: vendor/Python/current/Lib/SimpleHTTPServer.py
===================================================================
--- vendor/Python/current/Lib/SimpleHTTPServer.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/SimpleHTTPServer.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,218 @@
+"""Simple HTTP Server.
+
+This module builds on BaseHTTPServer by implementing the standard GET
+and HEAD requests in a fairly straightforward manner.
+
+"""
+
+
+__version__ = "0.6"
+
+__all__ = ["SimpleHTTPRequestHandler"]
+
+import os
+import posixpath
+import BaseHTTPServer
+import urllib
+import urlparse
+import cgi
+import shutil
+import mimetypes
+try:
+    from cStringIO import StringIO
+except ImportError:
+    from StringIO import StringIO
+
+
+class SimpleHTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
+
+    """Simple HTTP request handler with GET and HEAD commands.
+
+    This serves files from the current directory and any of its
+    subdirectories.  The MIME type for files is determined by
+    calling the .guess_type() method.
+
+    The GET and HEAD requests are identical except that the HEAD
+    request omits the actual contents of the file.
+
+    """
+
+    server_version = "SimpleHTTP/" + __version__
+
+    def do_GET(self):
+        """Serve a GET request."""
+        f = self.send_head()
+        if f:
+            self.copyfile(f, self.wfile)
+            f.close()
+
+    def do_HEAD(self):
+        """Serve a HEAD request."""
+        f = self.send_head()
+        if f:
+            f.close()
+
+    def send_head(self):
+        """Common code for GET and HEAD commands.
+
+        This sends the response code and MIME headers.
+
+        Return value is either a file object (which has to be copied
+        to the outputfile by the caller unless the command was HEAD,
+        and must be closed by the caller under all circumstances), or
+        None, in which case the caller has nothing further to do.
+
+        """
+        path = self.translate_path(self.path)
+        f = None
+        if os.path.isdir(path):
+            if not self.path.endswith('/'):
+                # redirect browser - doing basically what apache does
+                self.send_response(301)
+                self.send_header("Location", self.path + "/")
+                self.end_headers()
+                return None
+            for index in "index.html", "index.htm":
+                index = os.path.join(path, index)
+                if os.path.exists(index):
+                    path = index
+                    break
+            else:
+                return self.list_directory(path)
+        ctype = self.guess_type(path)
+        if ctype.startswith('text/'):
+            mode = 'r'
+        else:
+            mode = 'rb'
+        try:
+            f = open(path, mode)
+        except IOError:
+            self.send_error(404, "File not found")
+            return None
+        self.send_response(200)
+        self.send_header("Content-type", ctype)
+        fs = os.fstat(f.fileno())
+        self.send_header("Content-Length", str(fs[6]))
+        self.send_header("Last-Modified", self.date_time_string(fs.st_mtime))
+        self.end_headers()
+        return f
+
+    def list_directory(self, path):
+        """Helper to produce a directory listing (absent index.html).
+
+        Return value is either a file object, or None (indicating an
+        error).  In either case, the headers are sent, making the
+        interface the same as for send_head().
+
+        """
+        try:
+            list = os.listdir(path)
+        except os.error:
+            self.send_error(404, "No permission to list directory")
+            return None
+        list.sort(key=lambda a: a.lower())
+        f = StringIO()
+        displaypath = cgi.escape(urllib.unquote(self.path))
+        f.write("<title>Directory listing for %s</title>\n" % displaypath)
+        f.write("<h2>Directory listing for %s</h2>\n" % displaypath)
+        f.write("<hr>\n<ul>\n")
+        for name in list:
+            fullname = os.path.join(path, name)
+            displayname = linkname = name
+            # Append / for directories or @ for symbolic links
+            if os.path.isdir(fullname):
+                displayname = name + "/"
+                linkname = name + "/"
+            if os.path.islink(fullname):
+                displayname = name + "@"
+                # Note: a link to a directory displays with @ and links with /
+            f.write('<li><a href="%s">%s</a>\n'
+                    % (urllib.quote(linkname), cgi.escape(displayname)))
+        f.write("</ul>\n<hr>\n")
+        length = f.tell()
+        f.seek(0)
+        self.send_response(200)
+        self.send_header("Content-type", "text/html")
+        self.send_header("Content-Length", str(length))
+        self.end_headers()
+        return f
+
+    def translate_path(self, path):
+        """Translate a /-separated PATH to the local filename syntax.
+
+        Components that mean special things to the local file system
+        (e.g. drive or directory names) are ignored.  (XXX They should
+        probably be diagnosed.)
+
+        """
+        # abandon query parameters
+        path = urlparse.urlparse(path)[2]
+        path = posixpath.normpath(urllib.unquote(path))
+        words = path.split('/')
+        words = filter(None, words)
+        path = os.getcwd()
+        for word in words:
+            drive, word = os.path.splitdrive(word)
+            head, word = os.path.split(word)
+            if word in (os.curdir, os.pardir): continue
+            path = os.path.join(path, word)
+        return path
+
+    def copyfile(self, source, outputfile):
+        """Copy all data between two file objects.
+
+        The SOURCE argument is a file object open for reading
+        (or anything with a read() method) and the DESTINATION
+        argument is a file object open for writing (or
+        anything with a write() method).
+
+        The only reason for overriding this would be to change
+        the block size or perhaps to replace newlines by CRLF
+        -- note however that this the default server uses this
+        to copy binary data as well.
+
+        """
+        shutil.copyfileobj(source, outputfile)
+
+    def guess_type(self, path):
+        """Guess the type of a file.
+
+        Argument is a PATH (a filename).
+
+        Return value is a string of the form type/subtype,
+        usable for a MIME Content-type header.
+
+        The default implementation looks the file's extension
+        up in the table self.extensions_map, using application/octet-stream
+        as a default; however it would be permissible (if
+        slow) to look inside the data to make a better guess.
+
+        """
+
+        base, ext = posixpath.splitext(path)
+        if ext in self.extensions_map:
+            return self.extensions_map[ext]
+        ext = ext.lower()
+        if ext in self.extensions_map:
+            return self.extensions_map[ext]
+        else:
+            return self.extensions_map['']
+
+    if not mimetypes.inited:
+        mimetypes.init() # try to read system mime.types
+    extensions_map = mimetypes.types_map.copy()
+    extensions_map.update({
+        '': 'application/octet-stream', # Default
+        '.py': 'text/plain',
+        '.c': 'text/plain',
+        '.h': 'text/plain',
+        })
+
+
+def test(HandlerClass = SimpleHTTPRequestHandler,
+         ServerClass = BaseHTTPServer.HTTPServer):
+    BaseHTTPServer.test(HandlerClass, ServerClass)
+
+
+if __name__ == '__main__':
+    test()

Added: vendor/Python/current/Lib/SimpleXMLRPCServer.py
===================================================================
--- vendor/Python/current/Lib/SimpleXMLRPCServer.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/SimpleXMLRPCServer.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,595 @@
+"""Simple XML-RPC Server.
+
+This module can be used to create simple XML-RPC servers
+by creating a server and either installing functions, a
+class instance, or by extending the SimpleXMLRPCServer
+class.
+
+It can also be used to handle XML-RPC requests in a CGI
+environment using CGIXMLRPCRequestHandler.
+
+A list of possible usage patterns follows:
+
+1. Install functions:
+
+server = SimpleXMLRPCServer(("localhost", 8000))
+server.register_function(pow)
+server.register_function(lambda x,y: x+y, 'add')
+server.serve_forever()
+
+2. Install an instance:
+
+class MyFuncs:
+    def __init__(self):
+        # make all of the string functions available through
+        # string.func_name
+        import string
+        self.string = string
+    def _listMethods(self):
+        # implement this method so that system.listMethods
+        # knows to advertise the strings methods
+        return list_public_methods(self) + \
+                ['string.' + method for method in list_public_methods(self.string)]
+    def pow(self, x, y): return pow(x, y)
+    def add(self, x, y) : return x + y
+
+server = SimpleXMLRPCServer(("localhost", 8000))
+server.register_introspection_functions()
+server.register_instance(MyFuncs())
+server.serve_forever()
+
+3. Install an instance with custom dispatch method:
+
+class Math:
+    def _listMethods(self):
+        # this method must be present for system.listMethods
+        # to work
+        return ['add', 'pow']
+    def _methodHelp(self, method):
+        # this method must be present for system.methodHelp
+        # to work
+        if method == 'add':
+            return "add(2,3) => 5"
+        elif method == 'pow':
+            return "pow(x, y[, z]) => number"
+        else:
+            # By convention, return empty
+            # string if no help is available
+            return ""
+    def _dispatch(self, method, params):
+        if method == 'pow':
+            return pow(*params)
+        elif method == 'add':
+            return params[0] + params[1]
+        else:
+            raise 'bad method'
+
+server = SimpleXMLRPCServer(("localhost", 8000))
+server.register_introspection_functions()
+server.register_instance(Math())
+server.serve_forever()
+
+4. Subclass SimpleXMLRPCServer:
+
+class MathServer(SimpleXMLRPCServer):
+    def _dispatch(self, method, params):
+        try:
+            # We are forcing the 'export_' prefix on methods that are
+            # callable through XML-RPC to prevent potential security
+            # problems
+            func = getattr(self, 'export_' + method)
+        except AttributeError:
+            raise Exception('method "%s" is not supported' % method)
+        else:
+            return func(*params)
+
+    def export_add(self, x, y):
+        return x + y
+
+server = MathServer(("localhost", 8000))
+server.serve_forever()
+
+5. CGI script:
+
+server = CGIXMLRPCRequestHandler()
+server.register_function(pow)
+server.handle_request()
+"""
+
+# Written by Brian Quinlan (brian at sweetapp.com).
+# Based on code written by Fredrik Lundh.
+
+import xmlrpclib
+from xmlrpclib import Fault
+import SocketServer
+import BaseHTTPServer
+import sys
+import os
+try:
+    import fcntl
+except ImportError:
+    fcntl = None
+
+def resolve_dotted_attribute(obj, attr, allow_dotted_names=True):
+    """resolve_dotted_attribute(a, 'b.c.d') => a.b.c.d
+
+    Resolves a dotted attribute name to an object.  Raises
+    an AttributeError if any attribute in the chain starts with a '_'.
+
+    If the optional allow_dotted_names argument is false, dots are not
+    supported and this function operates similar to getattr(obj, attr).
+    """
+
+    if allow_dotted_names:
+        attrs = attr.split('.')
+    else:
+        attrs = [attr]
+
+    for i in attrs:
+        if i.startswith('_'):
+            raise AttributeError(
+                'attempt to access private attribute "%s"' % i
+                )
+        else:
+            obj = getattr(obj,i)
+    return obj
+
+def list_public_methods(obj):
+    """Returns a list of attribute strings, found in the specified
+    object, which represent callable attributes"""
+
+    return [member for member in dir(obj)
+                if not member.startswith('_') and
+                    callable(getattr(obj, member))]
+
+def remove_duplicates(lst):
+    """remove_duplicates([2,2,2,1,3,3]) => [3,1,2]
+
+    Returns a copy of a list without duplicates. Every list
+    item must be hashable and the order of the items in the
+    resulting list is not defined.
+    """
+    u = {}
+    for x in lst:
+        u[x] = 1
+
+    return u.keys()
+
+class SimpleXMLRPCDispatcher:
+    """Mix-in class that dispatches XML-RPC requests.
+
+    This class is used to register XML-RPC method handlers
+    and then to dispatch them. There should never be any
+    reason to instantiate this class directly.
+    """
+
+    def __init__(self, allow_none, encoding):
+        self.funcs = {}
+        self.instance = None
+        self.allow_none = allow_none
+        self.encoding = encoding
+
+    def register_instance(self, instance, allow_dotted_names=False):
+        """Registers an instance to respond to XML-RPC requests.
+
+        Only one instance can be installed at a time.
+
+        If the registered instance has a _dispatch method then that
+        method will be called with the name of the XML-RPC method and
+        its parameters as a tuple
+        e.g. instance._dispatch('add',(2,3))
+
+        If the registered instance does not have a _dispatch method
+        then the instance will be searched to find a matching method
+        and, if found, will be called. Methods beginning with an '_'
+        are considered private and will not be called by
+        SimpleXMLRPCServer.
+
+        If a registered function matches a XML-RPC request, then it
+        will be called instead of the registered instance.
+
+        If the optional allow_dotted_names argument is true and the
+        instance does not have a _dispatch method, method names
+        containing dots are supported and resolved, as long as none of
+        the name segments start with an '_'.
+
+            *** SECURITY WARNING: ***
+
+            Enabling the allow_dotted_names options allows intruders
+            to access your module's global variables and may allow
+            intruders to execute arbitrary code on your machine.  Only
+            use this option on a secure, closed network.
+
+        """
+
+        self.instance = instance
+        self.allow_dotted_names = allow_dotted_names
+
+    def register_function(self, function, name = None):
+        """Registers a function to respond to XML-RPC requests.
+
+        The optional name argument can be used to set a Unicode name
+        for the function.
+        """
+
+        if name is None:
+            name = function.__name__
+        self.funcs[name] = function
+
+    def register_introspection_functions(self):
+        """Registers the XML-RPC introspection methods in the system
+        namespace.
+
+        see http://xmlrpc.usefulinc.com/doc/reserved.html
+        """
+
+        self.funcs.update({'system.listMethods' : self.system_listMethods,
+                      'system.methodSignature' : self.system_methodSignature,
+                      'system.methodHelp' : self.system_methodHelp})
+
+    def register_multicall_functions(self):
+        """Registers the XML-RPC multicall method in the system
+        namespace.
+
+        see http://www.xmlrpc.com/discuss/msgReader$1208"""
+
+        self.funcs.update({'system.multicall' : self.system_multicall})
+
+    def _marshaled_dispatch(self, data, dispatch_method = None):
+        """Dispatches an XML-RPC method from marshalled (XML) data.
+
+        XML-RPC methods are dispatched from the marshalled (XML) data
+        using the _dispatch method and the result is returned as
+        marshalled data. For backwards compatibility, a dispatch
+        function can be provided as an argument (see comment in
+        SimpleXMLRPCRequestHandler.do_POST) but overriding the
+        existing method through subclassing is the prefered means
+        of changing method dispatch behavior.
+        """
+
+        try:
+            params, method = xmlrpclib.loads(data)
+
+            # generate response
+            if dispatch_method is not None:
+                response = dispatch_method(method, params)
+            else:
+                response = self._dispatch(method, params)
+            # wrap response in a singleton tuple
+            response = (response,)
+            response = xmlrpclib.dumps(response, methodresponse=1,
+                                       allow_none=self.allow_none, encoding=self.encoding)
+        except Fault, fault:
+            response = xmlrpclib.dumps(fault, allow_none=self.allow_none,
+                                       encoding=self.encoding)
+        except:
+            # report exception back to server
+            response = xmlrpclib.dumps(
+                xmlrpclib.Fault(1, "%s:%s" % (sys.exc_type, sys.exc_value)),
+                encoding=self.encoding, allow_none=self.allow_none,
+                )
+
+        return response
+
+    def system_listMethods(self):
+        """system.listMethods() => ['add', 'subtract', 'multiple']
+
+        Returns a list of the methods supported by the server."""
+
+        methods = self.funcs.keys()
+        if self.instance is not None:
+            # Instance can implement _listMethod to return a list of
+            # methods
+            if hasattr(self.instance, '_listMethods'):
+                methods = remove_duplicates(
+                        methods + self.instance._listMethods()
+                    )
+            # if the instance has a _dispatch method then we
+            # don't have enough information to provide a list
+            # of methods
+            elif not hasattr(self.instance, '_dispatch'):
+                methods = remove_duplicates(
+                        methods + list_public_methods(self.instance)
+                    )
+        methods.sort()
+        return methods
+
+    def system_methodSignature(self, method_name):
+        """system.methodSignature('add') => [double, int, int]
+
+        Returns a list describing the signature of the method. In the
+        above example, the add method takes two integers as arguments
+        and returns a double result.
+
+        This server does NOT support system.methodSignature."""
+
+        # See http://xmlrpc.usefulinc.com/doc/sysmethodsig.html
+
+        return 'signatures not supported'
+
+    def system_methodHelp(self, method_name):
+        """system.methodHelp('add') => "Adds two integers together"
+
+        Returns a string containing documentation for the specified method."""
+
+        method = None
+        if self.funcs.has_key(method_name):
+            method = self.funcs[method_name]
+        elif self.instance is not None:
+            # Instance can implement _methodHelp to return help for a method
+            if hasattr(self.instance, '_methodHelp'):
+                return self.instance._methodHelp(method_name)
+            # if the instance has a _dispatch method then we
+            # don't have enough information to provide help
+            elif not hasattr(self.instance, '_dispatch'):
+                try:
+                    method = resolve_dotted_attribute(
+                                self.instance,
+                                method_name,
+                                self.allow_dotted_names
+                                )
+                except AttributeError:
+                    pass
+
+        # Note that we aren't checking that the method actually
+        # be a callable object of some kind
+        if method is None:
+            return ""
+        else:
+            import pydoc
+            return pydoc.getdoc(method)
+
+    def system_multicall(self, call_list):
+        """system.multicall([{'methodName': 'add', 'params': [2, 2]}, ...]) => \
+[[4], ...]
+
+        Allows the caller to package multiple XML-RPC calls into a single
+        request.
+
+        See http://www.xmlrpc.com/discuss/msgReader$1208
+        """
+
+        results = []
+        for call in call_list:
+            method_name = call['methodName']
+            params = call['params']
+
+            try:
+                # XXX A marshalling error in any response will fail the entire
+                # multicall. If someone cares they should fix this.
+                results.append([self._dispatch(method_name, params)])
+            except Fault, fault:
+                results.append(
+                    {'faultCode' : fault.faultCode,
+                     'faultString' : fault.faultString}
+                    )
+            except:
+                results.append(
+                    {'faultCode' : 1,
+                     'faultString' : "%s:%s" % (sys.exc_type, sys.exc_value)}
+                    )
+        return results
+
+    def _dispatch(self, method, params):
+        """Dispatches the XML-RPC method.
+
+        XML-RPC calls are forwarded to a registered function that
+        matches the called XML-RPC method name. If no such function
+        exists then the call is forwarded to the registered instance,
+        if available.
+
+        If the registered instance has a _dispatch method then that
+        method will be called with the name of the XML-RPC method and
+        its parameters as a tuple
+        e.g. instance._dispatch('add',(2,3))
+
+        If the registered instance does not have a _dispatch method
+        then the instance will be searched to find a matching method
+        and, if found, will be called.
+
+        Methods beginning with an '_' are considered private and will
+        not be called.
+        """
+
+        func = None
+        try:
+            # check to see if a matching function has been registered
+            func = self.funcs[method]
+        except KeyError:
+            if self.instance is not None:
+                # check for a _dispatch method
+                if hasattr(self.instance, '_dispatch'):
+                    return self.instance._dispatch(method, params)
+                else:
+                    # call instance method directly
+                    try:
+                        func = resolve_dotted_attribute(
+                            self.instance,
+                            method,
+                            self.allow_dotted_names
+                            )
+                    except AttributeError:
+                        pass
+
+        if func is not None:
+            return func(*params)
+        else:
+            raise Exception('method "%s" is not supported' % method)
+
+class SimpleXMLRPCRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
+    """Simple XML-RPC request handler class.
+
+    Handles all HTTP POST requests and attempts to decode them as
+    XML-RPC requests.
+    """
+
+    # Class attribute listing the accessible path components;
+    # paths not on this list will result in a 404 error.
+    rpc_paths = ('/', '/RPC2')
+
+    def is_rpc_path_valid(self):
+        if self.rpc_paths:
+            return self.path in self.rpc_paths
+        else:
+            # If .rpc_paths is empty, just assume all paths are legal
+            return True
+
+    def do_POST(self):
+        """Handles the HTTP POST request.
+
+        Attempts to interpret all HTTP POST requests as XML-RPC calls,
+        which are forwarded to the server's _dispatch method for handling.
+        """
+
+        # Check that the path is legal
+        if not self.is_rpc_path_valid():
+            self.report_404()
+            return
+
+        try:
+            # Get arguments by reading body of request.
+            # We read this in chunks to avoid straining
+            # socket.read(); around the 10 or 15Mb mark, some platforms
+            # begin to have problems (bug #792570).
+            max_chunk_size = 10*1024*1024
+            size_remaining = int(self.headers["content-length"])
+            L = []
+            while size_remaining:
+                chunk_size = min(size_remaining, max_chunk_size)
+                L.append(self.rfile.read(chunk_size))
+                size_remaining -= len(L[-1])
+            data = ''.join(L)
+
+            # In previous versions of SimpleXMLRPCServer, _dispatch
+            # could be overridden in this class, instead of in
+            # SimpleXMLRPCDispatcher. To maintain backwards compatibility,
+            # check to see if a subclass implements _dispatch and dispatch
+            # using that method if present.
+            response = self.server._marshaled_dispatch(
+                    data, getattr(self, '_dispatch', None)
+                )
+        except: # This should only happen if the module is buggy
+            # internal error, report as HTTP server error
+            self.send_response(500)
+            self.end_headers()
+        else:
+            # got a valid XML RPC response
+            self.send_response(200)
+            self.send_header("Content-type", "text/xml")
+            self.send_header("Content-length", str(len(response)))
+            self.end_headers()
+            self.wfile.write(response)
+
+            # shut down the connection
+            self.wfile.flush()
+            self.connection.shutdown(1)
+
+    def report_404 (self):
+            # Report a 404 error
+        self.send_response(404)
+        response = 'No such page'
+        self.send_header("Content-type", "text/plain")
+        self.send_header("Content-length", str(len(response)))
+        self.end_headers()
+        self.wfile.write(response)
+        # shut down the connection
+        self.wfile.flush()
+        self.connection.shutdown(1)
+
+    def log_request(self, code='-', size='-'):
+        """Selectively log an accepted request."""
+
+        if self.server.logRequests:
+            BaseHTTPServer.BaseHTTPRequestHandler.log_request(self, code, size)
+
+class SimpleXMLRPCServer(SocketServer.TCPServer,
+                         SimpleXMLRPCDispatcher):
+    """Simple XML-RPC server.
+
+    Simple XML-RPC server that allows functions and a single instance
+    to be installed to handle requests. The default implementation
+    attempts to dispatch XML-RPC calls to the functions or instance
+    installed in the server. Override the _dispatch method inhereted
+    from SimpleXMLRPCDispatcher to change this behavior.
+    """
+
+    allow_reuse_address = True
+
+    def __init__(self, addr, requestHandler=SimpleXMLRPCRequestHandler,
+                 logRequests=True, allow_none=False, encoding=None):
+        self.logRequests = logRequests
+
+        SimpleXMLRPCDispatcher.__init__(self, allow_none, encoding)
+        SocketServer.TCPServer.__init__(self, addr, requestHandler)
+
+        # [Bug #1222790] If possible, set close-on-exec flag; if a
+        # method spawns a subprocess, the subprocess shouldn't have
+        # the listening socket open.
+        if fcntl is not None and hasattr(fcntl, 'FD_CLOEXEC'):
+            flags = fcntl.fcntl(self.fileno(), fcntl.F_GETFD)
+            flags |= fcntl.FD_CLOEXEC
+            fcntl.fcntl(self.fileno(), fcntl.F_SETFD, flags)
+
+class CGIXMLRPCRequestHandler(SimpleXMLRPCDispatcher):
+    """Simple handler for XML-RPC data passed through CGI."""
+
+    def __init__(self, allow_none=False, encoding=None):
+        SimpleXMLRPCDispatcher.__init__(self, allow_none, encoding)
+
+    def handle_xmlrpc(self, request_text):
+        """Handle a single XML-RPC request"""
+
+        response = self._marshaled_dispatch(request_text)
+
+        print 'Content-Type: text/xml'
+        print 'Content-Length: %d' % len(response)
+        print
+        sys.stdout.write(response)
+
+    def handle_get(self):
+        """Handle a single HTTP GET request.
+
+        Default implementation indicates an error because
+        XML-RPC uses the POST method.
+        """
+
+        code = 400
+        message, explain = \
+                 BaseHTTPServer.BaseHTTPRequestHandler.responses[code]
+
+        response = BaseHTTPServer.DEFAULT_ERROR_MESSAGE % \
+            {
+             'code' : code,
+             'message' : message,
+             'explain' : explain
+            }
+        print 'Status: %d %s' % (code, message)
+        print 'Content-Type: text/html'
+        print 'Content-Length: %d' % len(response)
+        print
+        sys.stdout.write(response)
+
+    def handle_request(self, request_text = None):
+        """Handle a single XML-RPC request passed through a CGI post method.
+
+        If no XML data is given then it is read from stdin. The resulting
+        XML-RPC response is printed to stdout along with the correct HTTP
+        headers.
+        """
+
+        if request_text is None and \
+            os.environ.get('REQUEST_METHOD', None) == 'GET':
+            self.handle_get()
+        else:
+            # POST data is normally available through stdin
+            if request_text is None:
+                request_text = sys.stdin.read()
+
+            self.handle_xmlrpc(request_text)
+
+if __name__ == '__main__':
+    print 'Running XML-RPC server on port 8000'
+    server = SimpleXMLRPCServer(("localhost", 8000))
+    server.register_function(pow)
+    server.register_function(lambda x,y: x+y, 'add')
+    server.serve_forever()

Added: vendor/Python/current/Lib/SocketServer.py
===================================================================
--- vendor/Python/current/Lib/SocketServer.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/SocketServer.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,588 @@
+"""Generic socket server classes.
+
+This module tries to capture the various aspects of defining a server:
+
+For socket-based servers:
+
+- address family:
+        - AF_INET{,6}: IP (Internet Protocol) sockets (default)
+        - AF_UNIX: Unix domain sockets
+        - others, e.g. AF_DECNET are conceivable (see <socket.h>
+- socket type:
+        - SOCK_STREAM (reliable stream, e.g. TCP)
+        - SOCK_DGRAM (datagrams, e.g. UDP)
+
+For request-based servers (including socket-based):
+
+- client address verification before further looking at the request
+        (This is actually a hook for any processing that needs to look
+         at the request before anything else, e.g. logging)
+- how to handle multiple requests:
+        - synchronous (one request is handled at a time)
+        - forking (each request is handled by a new process)
+        - threading (each request is handled by a new thread)
+
+The classes in this module favor the server type that is simplest to
+write: a synchronous TCP/IP server.  This is bad class design, but
+save some typing.  (There's also the issue that a deep class hierarchy
+slows down method lookups.)
+
+There are five classes in an inheritance diagram, four of which represent
+synchronous servers of four types:
+
+        +------------+
+        | BaseServer |
+        +------------+
+              |
+              v
+        +-----------+        +------------------+
+        | TCPServer |------->| UnixStreamServer |
+        +-----------+        +------------------+
+              |
+              v
+        +-----------+        +--------------------+
+        | UDPServer |------->| UnixDatagramServer |
+        +-----------+        +--------------------+
+
+Note that UnixDatagramServer derives from UDPServer, not from
+UnixStreamServer -- the only difference between an IP and a Unix
+stream server is the address family, which is simply repeated in both
+unix server classes.
+
+Forking and threading versions of each type of server can be created
+using the ForkingMixIn and ThreadingMixIn mix-in classes.  For
+instance, a threading UDP server class is created as follows:
+
+        class ThreadingUDPServer(ThreadingMixIn, UDPServer): pass
+
+The Mix-in class must come first, since it overrides a method defined
+in UDPServer! Setting the various member variables also changes
+the behavior of the underlying server mechanism.
+
+To implement a service, you must derive a class from
+BaseRequestHandler and redefine its handle() method.  You can then run
+various versions of the service by combining one of the server classes
+with your request handler class.
+
+The request handler class must be different for datagram or stream
+services.  This can be hidden by using the request handler
+subclasses StreamRequestHandler or DatagramRequestHandler.
+
+Of course, you still have to use your head!
+
+For instance, it makes no sense to use a forking server if the service
+contains state in memory that can be modified by requests (since the
+modifications in the child process would never reach the initial state
+kept in the parent process and passed to each child).  In this case,
+you can use a threading server, but you will probably have to use
+locks to avoid two requests that come in nearly simultaneous to apply
+conflicting changes to the server state.
+
+On the other hand, if you are building e.g. an HTTP server, where all
+data is stored externally (e.g. in the file system), a synchronous
+class will essentially render the service "deaf" while one request is
+being handled -- which may be for a very long time if a client is slow
+to reqd all the data it has requested.  Here a threading or forking
+server is appropriate.
+
+In some cases, it may be appropriate to process part of a request
+synchronously, but to finish processing in a forked child depending on
+the request data.  This can be implemented by using a synchronous
+server and doing an explicit fork in the request handler class
+handle() method.
+
+Another approach to handling multiple simultaneous requests in an
+environment that supports neither threads nor fork (or where these are
+too expensive or inappropriate for the service) is to maintain an
+explicit table of partially finished requests and to use select() to
+decide which request to work on next (or whether to handle a new
+incoming request).  This is particularly important for stream services
+where each client can potentially be connected for a long time (if
+threads or subprocesses cannot be used).
+
+Future work:
+- Standard classes for Sun RPC (which uses either UDP or TCP)
+- Standard mix-in classes to implement various authentication
+  and encryption schemes
+- Standard framework for select-based multiplexing
+
+XXX Open problems:
+- What to do with out-of-band data?
+
+BaseServer:
+- split generic "request" functionality out into BaseServer class.
+  Copyright (C) 2000  Luke Kenneth Casson Leighton <lkcl at samba.org>
+
+  example: read entries from a SQL database (requires overriding
+  get_request() to return a table entry from the database).
+  entry is processed by a RequestHandlerClass.
+
+"""
+
+# Author of the BaseServer patch: Luke Kenneth Casson Leighton
+
+# XXX Warning!
+# There is a test suite for this module, but it cannot be run by the
+# standard regression test.
+# To run it manually, run Lib/test/test_socketserver.py.
+
+__version__ = "0.4"
+
+
+import socket
+import sys
+import os
+
+__all__ = ["TCPServer","UDPServer","ForkingUDPServer","ForkingTCPServer",
+           "ThreadingUDPServer","ThreadingTCPServer","BaseRequestHandler",
+           "StreamRequestHandler","DatagramRequestHandler",
+           "ThreadingMixIn", "ForkingMixIn"]
+if hasattr(socket, "AF_UNIX"):
+    __all__.extend(["UnixStreamServer","UnixDatagramServer",
+                    "ThreadingUnixStreamServer",
+                    "ThreadingUnixDatagramServer"])
+
+class BaseServer:
+
+    """Base class for server classes.
+
+    Methods for the caller:
+
+    - __init__(server_address, RequestHandlerClass)
+    - serve_forever()
+    - handle_request()  # if you do not use serve_forever()
+    - fileno() -> int   # for select()
+
+    Methods that may be overridden:
+
+    - server_bind()
+    - server_activate()
+    - get_request() -> request, client_address
+    - verify_request(request, client_address)
+    - server_close()
+    - process_request(request, client_address)
+    - close_request(request)
+    - handle_error()
+
+    Methods for derived classes:
+
+    - finish_request(request, client_address)
+
+    Class variables that may be overridden by derived classes or
+    instances:
+
+    - address_family
+    - socket_type
+    - allow_reuse_address
+
+    Instance variables:
+
+    - RequestHandlerClass
+    - socket
+
+    """
+
+    def __init__(self, server_address, RequestHandlerClass):
+        """Constructor.  May be extended, do not override."""
+        self.server_address = server_address
+        self.RequestHandlerClass = RequestHandlerClass
+
+    def server_activate(self):
+        """Called by constructor to activate the server.
+
+        May be overridden.
+
+        """
+        pass
+
+    def serve_forever(self):
+        """Handle one request at a time until doomsday."""
+        while 1:
+            self.handle_request()
+
+    # The distinction between handling, getting, processing and
+    # finishing a request is fairly arbitrary.  Remember:
+    #
+    # - handle_request() is the top-level call.  It calls
+    #   get_request(), verify_request() and process_request()
+    # - get_request() is different for stream or datagram sockets
+    # - process_request() is the place that may fork a new process
+    #   or create a new thread to finish the request
+    # - finish_request() instantiates the request handler class;
+    #   this constructor will handle the request all by itself
+
+    def handle_request(self):
+        """Handle one request, possibly blocking."""
+        try:
+            request, client_address = self.get_request()
+        except socket.error:
+            return
+        if self.verify_request(request, client_address):
+            try:
+                self.process_request(request, client_address)
+            except:
+                self.handle_error(request, client_address)
+                self.close_request(request)
+
+    def verify_request(self, request, client_address):
+        """Verify the request.  May be overridden.
+
+        Return True if we should proceed with this request.
+
+        """
+        return True
+
+    def process_request(self, request, client_address):
+        """Call finish_request.
+
+        Overridden by ForkingMixIn and ThreadingMixIn.
+
+        """
+        self.finish_request(request, client_address)
+        self.close_request(request)
+
+    def server_close(self):
+        """Called to clean-up the server.
+
+        May be overridden.
+
+        """
+        pass
+
+    def finish_request(self, request, client_address):
+        """Finish one request by instantiating RequestHandlerClass."""
+        self.RequestHandlerClass(request, client_address, self)
+
+    def close_request(self, request):
+        """Called to clean up an individual request."""
+        pass
+
+    def handle_error(self, request, client_address):
+        """Handle an error gracefully.  May be overridden.
+
+        The default is to print a traceback and continue.
+
+        """
+        print '-'*40
+        print 'Exception happened during processing of request from',
+        print client_address
+        import traceback
+        traceback.print_exc() # XXX But this goes to stderr!
+        print '-'*40
+
+
+class TCPServer(BaseServer):
+
+    """Base class for various socket-based server classes.
+
+    Defaults to synchronous IP stream (i.e., TCP).
+
+    Methods for the caller:
+
+    - __init__(server_address, RequestHandlerClass)
+    - serve_forever()
+    - handle_request()  # if you don't use serve_forever()
+    - fileno() -> int   # for select()
+
+    Methods that may be overridden:
+
+    - server_bind()
+    - server_activate()
+    - get_request() -> request, client_address
+    - verify_request(request, client_address)
+    - process_request(request, client_address)
+    - close_request(request)
+    - handle_error()
+
+    Methods for derived classes:
+
+    - finish_request(request, client_address)
+
+    Class variables that may be overridden by derived classes or
+    instances:
+
+    - address_family
+    - socket_type
+    - request_queue_size (only for stream sockets)
+    - allow_reuse_address
+
+    Instance variables:
+
+    - server_address
+    - RequestHandlerClass
+    - socket
+
+    """
+
+    address_family = socket.AF_INET
+
+    socket_type = socket.SOCK_STREAM
+
+    request_queue_size = 5
+
+    allow_reuse_address = False
+
+    def __init__(self, server_address, RequestHandlerClass):
+        """Constructor.  May be extended, do not override."""
+        BaseServer.__init__(self, server_address, RequestHandlerClass)
+        self.socket = socket.socket(self.address_family,
+                                    self.socket_type)
+        self.server_bind()
+        self.server_activate()
+
+    def server_bind(self):
+        """Called by constructor to bind the socket.
+
+        May be overridden.
+
+        """
+        if self.allow_reuse_address:
+            self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+        self.socket.bind(self.server_address)
+        self.server_address = self.socket.getsockname()
+
+    def server_activate(self):
+        """Called by constructor to activate the server.
+
+        May be overridden.
+
+        """
+        self.socket.listen(self.request_queue_size)
+
+    def server_close(self):
+        """Called to clean-up the server.
+
+        May be overridden.
+
+        """
+        self.socket.close()
+
+    def fileno(self):
+        """Return socket file number.
+
+        Interface required by select().
+
+        """
+        return self.socket.fileno()
+
+    def get_request(self):
+        """Get the request and client address from the socket.
+
+        May be overridden.
+
+        """
+        return self.socket.accept()
+
+    def close_request(self, request):
+        """Called to clean up an individual request."""
+        request.close()
+
+
+class UDPServer(TCPServer):
+
+    """UDP server class."""
+
+    allow_reuse_address = False
+
+    socket_type = socket.SOCK_DGRAM
+
+    max_packet_size = 8192
+
+    def get_request(self):
+        data, client_addr = self.socket.recvfrom(self.max_packet_size)
+        return (data, self.socket), client_addr
+
+    def server_activate(self):
+        # No need to call listen() for UDP.
+        pass
+
+    def close_request(self, request):
+        # No need to close anything.
+        pass
+
+class ForkingMixIn:
+
+    """Mix-in class to handle each request in a new process."""
+
+    active_children = None
+    max_children = 40
+
+    def collect_children(self):
+        """Internal routine to wait for died children."""
+        while self.active_children:
+            if len(self.active_children) < self.max_children:
+                options = os.WNOHANG
+            else:
+                # If the maximum number of children are already
+                # running, block while waiting for a child to exit
+                options = 0
+            try:
+                pid, status = os.waitpid(0, options)
+            except os.error:
+                pid = None
+            if not pid: break
+            self.active_children.remove(pid)
+
+    def process_request(self, request, client_address):
+        """Fork a new subprocess to process the request."""
+        self.collect_children()
+        pid = os.fork()
+        if pid:
+            # Parent process
+            if self.active_children is None:
+                self.active_children = []
+            self.active_children.append(pid)
+            self.close_request(request)
+            return
+        else:
+            # Child process.
+            # This must never return, hence os._exit()!
+            try:
+                self.finish_request(request, client_address)
+                os._exit(0)
+            except:
+                try:
+                    self.handle_error(request, client_address)
+                finally:
+                    os._exit(1)
+
+
+class ThreadingMixIn:
+    """Mix-in class to handle each request in a new thread."""
+
+    # Decides how threads will act upon termination of the
+    # main process
+    daemon_threads = False
+
+    def process_request_thread(self, request, client_address):
+        """Same as in BaseServer but as a thread.
+
+        In addition, exception handling is done here.
+
+        """
+        try:
+            self.finish_request(request, client_address)
+            self.close_request(request)
+        except:
+            self.handle_error(request, client_address)
+            self.close_request(request)
+
+    def process_request(self, request, client_address):
+        """Start a new thread to process the request."""
+        import threading
+        t = threading.Thread(target = self.process_request_thread,
+                             args = (request, client_address))
+        if self.daemon_threads:
+            t.setDaemon (1)
+        t.start()
+
+
+class ForkingUDPServer(ForkingMixIn, UDPServer): pass
+class ForkingTCPServer(ForkingMixIn, TCPServer): pass
+
+class ThreadingUDPServer(ThreadingMixIn, UDPServer): pass
+class ThreadingTCPServer(ThreadingMixIn, TCPServer): pass
+
+if hasattr(socket, 'AF_UNIX'):
+
+    class UnixStreamServer(TCPServer):
+        address_family = socket.AF_UNIX
+
+    class UnixDatagramServer(UDPServer):
+        address_family = socket.AF_UNIX
+
+    class ThreadingUnixStreamServer(ThreadingMixIn, UnixStreamServer): pass
+
+    class ThreadingUnixDatagramServer(ThreadingMixIn, UnixDatagramServer): pass
+
+class BaseRequestHandler:
+
+    """Base class for request handler classes.
+
+    This class is instantiated for each request to be handled.  The
+    constructor sets the instance variables request, client_address
+    and server, and then calls the handle() method.  To implement a
+    specific service, all you need to do is to derive a class which
+    defines a handle() method.
+
+    The handle() method can find the request as self.request, the
+    client address as self.client_address, and the server (in case it
+    needs access to per-server information) as self.server.  Since a
+    separate instance is created for each request, the handle() method
+    can define arbitrary other instance variariables.
+
+    """
+
+    def __init__(self, request, client_address, server):
+        self.request = request
+        self.client_address = client_address
+        self.server = server
+        try:
+            self.setup()
+            self.handle()
+            self.finish()
+        finally:
+            sys.exc_traceback = None    # Help garbage collection
+
+    def setup(self):
+        pass
+
+    def handle(self):
+        pass
+
+    def finish(self):
+        pass
+
+
+# The following two classes make it possible to use the same service
+# class for stream or datagram servers.
+# Each class sets up these instance variables:
+# - rfile: a file object from which receives the request is read
+# - wfile: a file object to which the reply is written
+# When the handle() method returns, wfile is flushed properly
+
+
+class StreamRequestHandler(BaseRequestHandler):
+
+    """Define self.rfile and self.wfile for stream sockets."""
+
+    # Default buffer sizes for rfile, wfile.
+    # We default rfile to buffered because otherwise it could be
+    # really slow for large data (a getc() call per byte); we make
+    # wfile unbuffered because (a) often after a write() we want to
+    # read and we need to flush the line; (b) big writes to unbuffered
+    # files are typically optimized by stdio even when big reads
+    # aren't.
+    rbufsize = -1
+    wbufsize = 0
+
+    def setup(self):
+        self.connection = self.request
+        self.rfile = self.connection.makefile('rb', self.rbufsize)
+        self.wfile = self.connection.makefile('wb', self.wbufsize)
+
+    def finish(self):
+        if not self.wfile.closed:
+            self.wfile.flush()
+        self.wfile.close()
+        self.rfile.close()
+
+
+class DatagramRequestHandler(BaseRequestHandler):
+
+    # XXX Regrettably, I cannot get this working on Linux;
+    # s.recvfrom() doesn't return a meaningful client address.
+
+    """Define self.rfile and self.wfile for datagram sockets."""
+
+    def setup(self):
+        try:
+            from cStringIO import StringIO
+        except ImportError:
+            from StringIO import StringIO
+        self.packet, self.socket = self.request
+        self.rfile = StringIO(self.packet)
+        self.wfile = StringIO()
+
+    def finish(self):
+        self.socket.sendto(self.wfile.getvalue(), self.client_address)

Added: vendor/Python/current/Lib/StringIO.py
===================================================================
--- vendor/Python/current/Lib/StringIO.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/StringIO.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,323 @@
+r"""File-like objects that read from or write to a string buffer.
+
+This implements (nearly) all stdio methods.
+
+f = StringIO()      # ready for writing
+f = StringIO(buf)   # ready for reading
+f.close()           # explicitly release resources held
+flag = f.isatty()   # always false
+pos = f.tell()      # get current position
+f.seek(pos)         # set current position
+f.seek(pos, mode)   # mode 0: absolute; 1: relative; 2: relative to EOF
+buf = f.read()      # read until EOF
+buf = f.read(n)     # read up to n bytes
+buf = f.readline()  # read until end of line ('\n') or EOF
+list = f.readlines()# list of f.readline() results until EOF
+f.truncate([size])  # truncate file at to at most size (default: current pos)
+f.write(buf)        # write at current position
+f.writelines(list)  # for line in list: f.write(line)
+f.getvalue()        # return whole file's contents as a string
+
+Notes:
+- Using a real file is often faster (but less convenient).
+- There's also a much faster implementation in C, called cStringIO, but
+  it's not subclassable.
+- fileno() is left unimplemented so that code which uses it triggers
+  an exception early.
+- Seeking far beyond EOF and then writing will insert real null
+  bytes that occupy space in the buffer.
+- There's a simple test set (see end of this file).
+"""
+try:
+    from errno import EINVAL
+except ImportError:
+    EINVAL = 22
+
+__all__ = ["StringIO"]
+
+def _complain_ifclosed(closed):
+    if closed:
+        raise ValueError, "I/O operation on closed file"
+
+class StringIO:
+    """class StringIO([buffer])
+
+    When a StringIO object is created, it can be initialized to an existing
+    string by passing the string to the constructor. If no string is given,
+    the StringIO will start empty.
+
+    The StringIO object can accept either Unicode or 8-bit strings, but
+    mixing the two may take some care. If both are used, 8-bit strings that
+    cannot be interpreted as 7-bit ASCII (that use the 8th bit) will cause
+    a UnicodeError to be raised when getvalue() is called.
+    """
+    def __init__(self, buf = ''):
+        # Force self.buf to be a string or unicode
+        if not isinstance(buf, basestring):
+            buf = str(buf)
+        self.buf = buf
+        self.len = len(buf)
+        self.buflist = []
+        self.pos = 0
+        self.closed = False
+        self.softspace = 0
+
+    def __iter__(self):
+        return self
+
+    def next(self):
+        """A file object is its own iterator, for example iter(f) returns f
+        (unless f is closed). When a file is used as an iterator, typically
+        in a for loop (for example, for line in f: print line), the next()
+        method is called repeatedly. This method returns the next input line,
+        or raises StopIteration when EOF is hit.
+        """
+        _complain_ifclosed(self.closed)
+        r = self.readline()
+        if not r:
+            raise StopIteration
+        return r
+
+    def close(self):
+        """Free the memory buffer.
+        """
+        if not self.closed:
+            self.closed = True
+            del self.buf, self.pos
+
+    def isatty(self):
+        """Returns False because StringIO objects are not connected to a
+        tty-like device.
+        """
+        _complain_ifclosed(self.closed)
+        return False
+
+    def seek(self, pos, mode = 0):
+        """Set the file's current position.
+
+        The mode argument is optional and defaults to 0 (absolute file
+        positioning); other values are 1 (seek relative to the current
+        position) and 2 (seek relative to the file's end).
+
+        There is no return value.
+        """
+        _complain_ifclosed(self.closed)
+        if self.buflist:
+            self.buf += ''.join(self.buflist)
+            self.buflist = []
+        if mode == 1:
+            pos += self.pos
+        elif mode == 2:
+            pos += self.len
+        self.pos = max(0, pos)
+
+    def tell(self):
+        """Return the file's current position."""
+        _complain_ifclosed(self.closed)
+        return self.pos
+
+    def read(self, n = -1):
+        """Read at most size bytes from the file
+        (less if the read hits EOF before obtaining size bytes).
+
+        If the size argument is negative or omitted, read all data until EOF
+        is reached. The bytes are returned as a string object. An empty
+        string is returned when EOF is encountered immediately.
+        """
+        _complain_ifclosed(self.closed)
+        if self.buflist:
+            self.buf += ''.join(self.buflist)
+            self.buflist = []
+        if n < 0:
+            newpos = self.len
+        else:
+            newpos = min(self.pos+n, self.len)
+        r = self.buf[self.pos:newpos]
+        self.pos = newpos
+        return r
+
+    def readline(self, length=None):
+        r"""Read one entire line from the file.
+
+        A trailing newline character is kept in the string (but may be absent
+        when a file ends with an incomplete line). If the size argument is
+        present and non-negative, it is a maximum byte count (including the
+        trailing newline) and an incomplete line may be returned.
+
+        An empty string is returned only when EOF is encountered immediately.
+
+        Note: Unlike stdio's fgets(), the returned string contains null
+        characters ('\0') if they occurred in the input.
+        """
+        _complain_ifclosed(self.closed)
+        if self.buflist:
+            self.buf += ''.join(self.buflist)
+            self.buflist = []
+        i = self.buf.find('\n', self.pos)
+        if i < 0:
+            newpos = self.len
+        else:
+            newpos = i+1
+        if length is not None:
+            if self.pos + length < newpos:
+                newpos = self.pos + length
+        r = self.buf[self.pos:newpos]
+        self.pos = newpos
+        return r
+
+    def readlines(self, sizehint = 0):
+        """Read until EOF using readline() and return a list containing the
+        lines thus read.
+
+        If the optional sizehint argument is present, instead of reading up
+        to EOF, whole lines totalling approximately sizehint bytes (or more
+        to accommodate a final whole line).
+        """
+        total = 0
+        lines = []
+        line = self.readline()
+        while line:
+            lines.append(line)
+            total += len(line)
+            if 0 < sizehint <= total:
+                break
+            line = self.readline()
+        return lines
+
+    def truncate(self, size=None):
+        """Truncate the file's size.
+
+        If the optional size argument is present, the file is truncated to
+        (at most) that size. The size defaults to the current position.
+        The current file position is not changed unless the position
+        is beyond the new file size.
+
+        If the specified size exceeds the file's current size, the
+        file remains unchanged.
+        """
+        _complain_ifclosed(self.closed)
+        if size is None:
+            size = self.pos
+        elif size < 0:
+            raise IOError(EINVAL, "Negative size not allowed")
+        elif size < self.pos:
+            self.pos = size
+        self.buf = self.getvalue()[:size]
+        self.len = size
+
+    def write(self, s):
+        """Write a string to the file.
+
+        There is no return value.
+        """
+        _complain_ifclosed(self.closed)
+        if not s: return
+        # Force s to be a string or unicode
+        if not isinstance(s, basestring):
+            s = str(s)
+        spos = self.pos
+        slen = self.len
+        if spos == slen:
+            self.buflist.append(s)
+            self.len = self.pos = spos + len(s)
+            return
+        if spos > slen:
+            self.buflist.append('\0'*(spos - slen))
+            slen = spos
+        newpos = spos + len(s)
+        if spos < slen:
+            if self.buflist:
+                self.buf += ''.join(self.buflist)
+            self.buflist = [self.buf[:spos], s, self.buf[newpos:]]
+            self.buf = ''
+            if newpos > slen:
+                slen = newpos
+        else:
+            self.buflist.append(s)
+            slen = newpos
+        self.len = slen
+        self.pos = newpos
+
+    def writelines(self, iterable):
+        """Write a sequence of strings to the file. The sequence can be any
+        iterable object producing strings, typically a list of strings. There
+        is no return value.
+
+        (The name is intended to match readlines(); writelines() does not add
+        line separators.)
+        """
+        write = self.write
+        for line in iterable:
+            write(line)
+
+    def flush(self):
+        """Flush the internal buffer
+        """
+        _complain_ifclosed(self.closed)
+
+    def getvalue(self):
+        """
+        Retrieve the entire contents of the "file" at any time before
+        the StringIO object's close() method is called.
+
+        The StringIO object can accept either Unicode or 8-bit strings,
+        but mixing the two may take some care. If both are used, 8-bit
+        strings that cannot be interpreted as 7-bit ASCII (that use the
+        8th bit) will cause a UnicodeError to be raised when getvalue()
+        is called.
+        """
+        if self.buflist:
+            self.buf += ''.join(self.buflist)
+            self.buflist = []
+        return self.buf
+
+
+# A little test suite
+
+def test():
+    import sys
+    if sys.argv[1:]:
+        file = sys.argv[1]
+    else:
+        file = '/etc/passwd'
+    lines = open(file, 'r').readlines()
+    text = open(file, 'r').read()
+    f = StringIO()
+    for line in lines[:-2]:
+        f.write(line)
+    f.writelines(lines[-2:])
+    if f.getvalue() != text:
+        raise RuntimeError, 'write failed'
+    length = f.tell()
+    print 'File length =', length
+    f.seek(len(lines[0]))
+    f.write(lines[1])
+    f.seek(0)
+    print 'First line =', repr(f.readline())
+    print 'Position =', f.tell()
+    line = f.readline()
+    print 'Second line =', repr(line)
+    f.seek(-len(line), 1)
+    line2 = f.read(len(line))
+    if line != line2:
+        raise RuntimeError, 'bad result after seek back'
+    f.seek(len(line2), 1)
+    list = f.readlines()
+    line = list[-1]
+    f.seek(f.tell() - len(line))
+    line2 = f.read()
+    if line != line2:
+        raise RuntimeError, 'bad result after seek back from EOF'
+    print 'Read', len(list), 'more lines'
+    print 'File length =', f.tell()
+    if f.tell() != length:
+        raise RuntimeError, 'bad length'
+    f.truncate(length/2)
+    f.seek(0, 2)
+    print 'Truncated length =', f.tell()
+    if f.tell() != length/2:
+        raise RuntimeError, 'truncate did not adjust length'
+    f.close()
+
+if __name__ == '__main__':
+    test()

Added: vendor/Python/current/Lib/UserDict.py
===================================================================
--- vendor/Python/current/Lib/UserDict.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/UserDict.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,175 @@
+"""A more or less complete user-defined wrapper around dictionary objects."""
+
+class UserDict:
+    def __init__(self, dict=None, **kwargs):
+        self.data = {}
+        if dict is not None:
+            self.update(dict)
+        if len(kwargs):
+            self.update(kwargs)
+    def __repr__(self): return repr(self.data)
+    def __cmp__(self, dict):
+        if isinstance(dict, UserDict):
+            return cmp(self.data, dict.data)
+        else:
+            return cmp(self.data, dict)
+    def __len__(self): return len(self.data)
+    def __getitem__(self, key):
+        if key in self.data:
+            return self.data[key]
+        if hasattr(self.__class__, "__missing__"):
+            return self.__class__.__missing__(self, key)
+        raise KeyError(key)
+    def __setitem__(self, key, item): self.data[key] = item
+    def __delitem__(self, key): del self.data[key]
+    def clear(self): self.data.clear()
+    def copy(self):
+        if self.__class__ is UserDict:
+            return UserDict(self.data.copy())
+        import copy
+        data = self.data
+        try:
+            self.data = {}
+            c = copy.copy(self)
+        finally:
+            self.data = data
+        c.update(self)
+        return c
+    def keys(self): return self.data.keys()
+    def items(self): return self.data.items()
+    def iteritems(self): return self.data.iteritems()
+    def iterkeys(self): return self.data.iterkeys()
+    def itervalues(self): return self.data.itervalues()
+    def values(self): return self.data.values()
+    def has_key(self, key): return self.data.has_key(key)
+    def update(self, dict=None, **kwargs):
+        if dict is None:
+            pass
+        elif isinstance(dict, UserDict):
+            self.data.update(dict.data)
+        elif isinstance(dict, type({})) or not hasattr(dict, 'items'):
+            self.data.update(dict)
+        else:
+            for k, v in dict.items():
+                self[k] = v
+        if len(kwargs):
+            self.data.update(kwargs)
+    def get(self, key, failobj=None):
+        if not self.has_key(key):
+            return failobj
+        return self[key]
+    def setdefault(self, key, failobj=None):
+        if not self.has_key(key):
+            self[key] = failobj
+        return self[key]
+    def pop(self, key, *args):
+        return self.data.pop(key, *args)
+    def popitem(self):
+        return self.data.popitem()
+    def __contains__(self, key):
+        return key in self.data
+    @classmethod
+    def fromkeys(cls, iterable, value=None):
+        d = cls()
+        for key in iterable:
+            d[key] = value
+        return d
+
+class IterableUserDict(UserDict):
+    def __iter__(self):
+        return iter(self.data)
+
+class DictMixin:
+    # Mixin defining all dictionary methods for classes that already have
+    # a minimum dictionary interface including getitem, setitem, delitem,
+    # and keys. Without knowledge of the subclass constructor, the mixin
+    # does not define __init__() or copy().  In addition to the four base
+    # methods, progressively more efficiency comes with defining
+    # __contains__(), __iter__(), and iteritems().
+
+    # second level definitions support higher levels
+    def __iter__(self):
+        for k in self.keys():
+            yield k
+    def has_key(self, key):
+        try:
+            value = self[key]
+        except KeyError:
+            return False
+        return True
+    def __contains__(self, key):
+        return self.has_key(key)
+
+    # third level takes advantage of second level definitions
+    def iteritems(self):
+        for k in self:
+            yield (k, self[k])
+    def iterkeys(self):
+        return self.__iter__()
+
+    # fourth level uses definitions from lower levels
+    def itervalues(self):
+        for _, v in self.iteritems():
+            yield v
+    def values(self):
+        return [v for _, v in self.iteritems()]
+    def items(self):
+        return list(self.iteritems())
+    def clear(self):
+        for key in self.keys():
+            del self[key]
+    def setdefault(self, key, default=None):
+        try:
+            return self[key]
+        except KeyError:
+            self[key] = default
+        return default
+    def pop(self, key, *args):
+        if len(args) > 1:
+            raise TypeError, "pop expected at most 2 arguments, got "\
+                              + repr(1 + len(args))
+        try:
+            value = self[key]
+        except KeyError:
+            if args:
+                return args[0]
+            raise
+        del self[key]
+        return value
+    def popitem(self):
+        try:
+            k, v = self.iteritems().next()
+        except StopIteration:
+            raise KeyError, 'container is empty'
+        del self[k]
+        return (k, v)
+    def update(self, other=None, **kwargs):
+        # Make progressively weaker assumptions about "other"
+        if other is None:
+            pass
+        elif hasattr(other, 'iteritems'):  # iteritems saves memory and lookups
+            for k, v in other.iteritems():
+                self[k] = v
+        elif hasattr(other, 'keys'):
+            for k in other.keys():
+                self[k] = other[k]
+        else:
+            for k, v in other:
+                self[k] = v
+        if kwargs:
+            self.update(kwargs)
+    def get(self, key, default=None):
+        try:
+            return self[key]
+        except KeyError:
+            return default
+    def __repr__(self):
+        return repr(dict(self.iteritems()))
+    def __cmp__(self, other):
+        if other is None:
+            return 1
+        if isinstance(other, DictMixin):
+            other = dict(other.iteritems())
+        return cmp(dict(self.iteritems()), other)
+    def __len__(self):
+        return len(self.keys())

Added: vendor/Python/current/Lib/UserList.py
===================================================================
--- vendor/Python/current/Lib/UserList.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/UserList.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,85 @@
+"""A more or less complete user-defined wrapper around list objects."""
+
+class UserList:
+    def __init__(self, initlist=None):
+        self.data = []
+        if initlist is not None:
+            # XXX should this accept an arbitrary sequence?
+            if type(initlist) == type(self.data):
+                self.data[:] = initlist
+            elif isinstance(initlist, UserList):
+                self.data[:] = initlist.data[:]
+            else:
+                self.data = list(initlist)
+    def __repr__(self): return repr(self.data)
+    def __lt__(self, other): return self.data <  self.__cast(other)
+    def __le__(self, other): return self.data <= self.__cast(other)
+    def __eq__(self, other): return self.data == self.__cast(other)
+    def __ne__(self, other): return self.data != self.__cast(other)
+    def __gt__(self, other): return self.data >  self.__cast(other)
+    def __ge__(self, other): return self.data >= self.__cast(other)
+    def __cast(self, other):
+        if isinstance(other, UserList): return other.data
+        else: return other
+    def __cmp__(self, other):
+        return cmp(self.data, self.__cast(other))
+    def __contains__(self, item): return item in self.data
+    def __len__(self): return len(self.data)
+    def __getitem__(self, i): return self.data[i]
+    def __setitem__(self, i, item): self.data[i] = item
+    def __delitem__(self, i): del self.data[i]
+    def __getslice__(self, i, j):
+        i = max(i, 0); j = max(j, 0)
+        return self.__class__(self.data[i:j])
+    def __setslice__(self, i, j, other):
+        i = max(i, 0); j = max(j, 0)
+        if isinstance(other, UserList):
+            self.data[i:j] = other.data
+        elif isinstance(other, type(self.data)):
+            self.data[i:j] = other
+        else:
+            self.data[i:j] = list(other)
+    def __delslice__(self, i, j):
+        i = max(i, 0); j = max(j, 0)
+        del self.data[i:j]
+    def __add__(self, other):
+        if isinstance(other, UserList):
+            return self.__class__(self.data + other.data)
+        elif isinstance(other, type(self.data)):
+            return self.__class__(self.data + other)
+        else:
+            return self.__class__(self.data + list(other))
+    def __radd__(self, other):
+        if isinstance(other, UserList):
+            return self.__class__(other.data + self.data)
+        elif isinstance(other, type(self.data)):
+            return self.__class__(other + self.data)
+        else:
+            return self.__class__(list(other) + self.data)
+    def __iadd__(self, other):
+        if isinstance(other, UserList):
+            self.data += other.data
+        elif isinstance(other, type(self.data)):
+            self.data += other
+        else:
+            self.data += list(other)
+        return self
+    def __mul__(self, n):
+        return self.__class__(self.data*n)
+    __rmul__ = __mul__
+    def __imul__(self, n):
+        self.data *= n
+        return self
+    def append(self, item): self.data.append(item)
+    def insert(self, i, item): self.data.insert(i, item)
+    def pop(self, i=-1): return self.data.pop(i)
+    def remove(self, item): self.data.remove(item)
+    def count(self, item): return self.data.count(item)
+    def index(self, item, *args): return self.data.index(item, *args)
+    def reverse(self): self.data.reverse()
+    def sort(self, *args, **kwds): self.data.sort(*args, **kwds)
+    def extend(self, other):
+        if isinstance(other, UserList):
+            self.data.extend(other.data)
+        else:
+            self.data.extend(other)

Added: vendor/Python/current/Lib/UserString.py
===================================================================
--- vendor/Python/current/Lib/UserString.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/UserString.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,194 @@
+#!/usr/bin/env python
+## vim:ts=4:et:nowrap
+"""A user-defined wrapper around string objects
+
+Note: string objects have grown methods in Python 1.6
+This module requires Python 1.6 or later.
+"""
+import sys
+
+__all__ = ["UserString","MutableString"]
+
+class UserString:
+    def __init__(self, seq):
+        if isinstance(seq, basestring):
+            self.data = seq
+        elif isinstance(seq, UserString):
+            self.data = seq.data[:]
+        else:
+            self.data = str(seq)
+    def __str__(self): return str(self.data)
+    def __repr__(self): return repr(self.data)
+    def __int__(self): return int(self.data)
+    def __long__(self): return long(self.data)
+    def __float__(self): return float(self.data)
+    def __complex__(self): return complex(self.data)
+    def __hash__(self): return hash(self.data)
+
+    def __cmp__(self, string):
+        if isinstance(string, UserString):
+            return cmp(self.data, string.data)
+        else:
+            return cmp(self.data, string)
+    def __contains__(self, char):
+        return char in self.data
+
+    def __len__(self): return len(self.data)
+    def __getitem__(self, index): return self.__class__(self.data[index])
+    def __getslice__(self, start, end):
+        start = max(start, 0); end = max(end, 0)
+        return self.__class__(self.data[start:end])
+
+    def __add__(self, other):
+        if isinstance(other, UserString):
+            return self.__class__(self.data + other.data)
+        elif isinstance(other, basestring):
+            return self.__class__(self.data + other)
+        else:
+            return self.__class__(self.data + str(other))
+    def __radd__(self, other):
+        if isinstance(other, basestring):
+            return self.__class__(other + self.data)
+        else:
+            return self.__class__(str(other) + self.data)
+    def __mul__(self, n):
+        return self.__class__(self.data*n)
+    __rmul__ = __mul__
+    def __mod__(self, args):
+        return self.__class__(self.data % args)
+
+    # the following methods are defined in alphabetical order:
+    def capitalize(self): return self.__class__(self.data.capitalize())
+    def center(self, width, *args):
+        return self.__class__(self.data.center(width, *args))
+    def count(self, sub, start=0, end=sys.maxint):
+        return self.data.count(sub, start, end)
+    def decode(self, encoding=None, errors=None): # XXX improve this?
+        if encoding:
+            if errors:
+                return self.__class__(self.data.decode(encoding, errors))
+            else:
+                return self.__class__(self.data.decode(encoding))
+        else:
+            return self.__class__(self.data.decode())
+    def encode(self, encoding=None, errors=None): # XXX improve this?
+        if encoding:
+            if errors:
+                return self.__class__(self.data.encode(encoding, errors))
+            else:
+                return self.__class__(self.data.encode(encoding))
+        else:
+            return self.__class__(self.data.encode())
+    def endswith(self, suffix, start=0, end=sys.maxint):
+        return self.data.endswith(suffix, start, end)
+    def expandtabs(self, tabsize=8):
+        return self.__class__(self.data.expandtabs(tabsize))
+    def find(self, sub, start=0, end=sys.maxint):
+        return self.data.find(sub, start, end)
+    def index(self, sub, start=0, end=sys.maxint):
+        return self.data.index(sub, start, end)
+    def isalpha(self): return self.data.isalpha()
+    def isalnum(self): return self.data.isalnum()
+    def isdecimal(self): return self.data.isdecimal()
+    def isdigit(self): return self.data.isdigit()
+    def islower(self): return self.data.islower()
+    def isnumeric(self): return self.data.isnumeric()
+    def isspace(self): return self.data.isspace()
+    def istitle(self): return self.data.istitle()
+    def isupper(self): return self.data.isupper()
+    def join(self, seq): return self.data.join(seq)
+    def ljust(self, width, *args):
+        return self.__class__(self.data.ljust(width, *args))
+    def lower(self): return self.__class__(self.data.lower())
+    def lstrip(self, chars=None): return self.__class__(self.data.lstrip(chars))
+    def partition(self, sep):
+        return self.data.partition(sep)
+    def replace(self, old, new, maxsplit=-1):
+        return self.__class__(self.data.replace(old, new, maxsplit))
+    def rfind(self, sub, start=0, end=sys.maxint):
+        return self.data.rfind(sub, start, end)
+    def rindex(self, sub, start=0, end=sys.maxint):
+        return self.data.rindex(sub, start, end)
+    def rjust(self, width, *args):
+        return self.__class__(self.data.rjust(width, *args))
+    def rpartition(self, sep):
+        return self.data.rpartition(sep)
+    def rstrip(self, chars=None): return self.__class__(self.data.rstrip(chars))
+    def split(self, sep=None, maxsplit=-1):
+        return self.data.split(sep, maxsplit)
+    def rsplit(self, sep=None, maxsplit=-1):
+        return self.data.rsplit(sep, maxsplit)
+    def splitlines(self, keepends=0): return self.data.splitlines(keepends)
+    def startswith(self, prefix, start=0, end=sys.maxint):
+        return self.data.startswith(prefix, start, end)
+    def strip(self, chars=None): return self.__class__(self.data.strip(chars))
+    def swapcase(self): return self.__class__(self.data.swapcase())
+    def title(self): return self.__class__(self.data.title())
+    def translate(self, *args):
+        return self.__class__(self.data.translate(*args))
+    def upper(self): return self.__class__(self.data.upper())
+    def zfill(self, width): return self.__class__(self.data.zfill(width))
+
+class MutableString(UserString):
+    """mutable string objects
+
+    Python strings are immutable objects.  This has the advantage, that
+    strings may be used as dictionary keys.  If this property isn't needed
+    and you insist on changing string values in place instead, you may cheat
+    and use MutableString.
+
+    But the purpose of this class is an educational one: to prevent
+    people from inventing their own mutable string class derived
+    from UserString and than forget thereby to remove (override) the
+    __hash__ method inherited from UserString.  This would lead to
+    errors that would be very hard to track down.
+
+    A faster and better solution is to rewrite your program using lists."""
+    def __init__(self, string=""):
+        self.data = string
+    def __hash__(self):
+        raise TypeError, "unhashable type (it is mutable)"
+    def __setitem__(self, index, sub):
+        if index < 0:
+            index += len(self.data)
+        if index < 0 or index >= len(self.data): raise IndexError
+        self.data = self.data[:index] + sub + self.data[index+1:]
+    def __delitem__(self, index):
+        if index < 0:
+            index += len(self.data)
+        if index < 0 or index >= len(self.data): raise IndexError
+        self.data = self.data[:index] + self.data[index+1:]
+    def __setslice__(self, start, end, sub):
+        start = max(start, 0); end = max(end, 0)
+        if isinstance(sub, UserString):
+            self.data = self.data[:start]+sub.data+self.data[end:]
+        elif isinstance(sub, basestring):
+            self.data = self.data[:start]+sub+self.data[end:]
+        else:
+            self.data =  self.data[:start]+str(sub)+self.data[end:]
+    def __delslice__(self, start, end):
+        start = max(start, 0); end = max(end, 0)
+        self.data = self.data[:start] + self.data[end:]
+    def immutable(self):
+        return UserString(self.data)
+    def __iadd__(self, other):
+        if isinstance(other, UserString):
+            self.data += other.data
+        elif isinstance(other, basestring):
+            self.data += other
+        else:
+            self.data += str(other)
+        return self
+    def __imul__(self, n):
+        self.data *= n
+        return self
+
+if __name__ == "__main__":
+    # execute the regression test to stdout, if called as a script:
+    import os
+    called_in_dir, called_as = os.path.split(sys.argv[0])
+    called_as, py = os.path.splitext(called_as)
+    if '-q' in sys.argv:
+        from test import test_support
+        test_support.verbose = 0
+    __import__('test.test_' + called_as.lower())


Property changes on: vendor/Python/current/Lib/UserString.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/_LWPCookieJar.py
===================================================================
--- vendor/Python/current/Lib/_LWPCookieJar.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/_LWPCookieJar.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,170 @@
+"""Load / save to libwww-perl (LWP) format files.
+
+Actually, the format is slightly extended from that used by LWP's
+(libwww-perl's) HTTP::Cookies, to avoid losing some RFC 2965 information
+not recorded by LWP.
+
+It uses the version string "2.0", though really there isn't an LWP Cookies
+2.0 format.  This indicates that there is extra information in here
+(domain_dot and # port_spec) while still being compatible with
+libwww-perl, I hope.
+
+"""
+
+import time, re
+from cookielib import (_warn_unhandled_exception, FileCookieJar, LoadError,
+                       Cookie, MISSING_FILENAME_TEXT,
+                       join_header_words, split_header_words,
+                       iso2time, time2isoz)
+
+def lwp_cookie_str(cookie):
+    """Return string representation of Cookie in an the LWP cookie file format.
+
+    Actually, the format is extended a bit -- see module docstring.
+
+    """
+    h = [(cookie.name, cookie.value),
+         ("path", cookie.path),
+         ("domain", cookie.domain)]
+    if cookie.port is not None: h.append(("port", cookie.port))
+    if cookie.path_specified: h.append(("path_spec", None))
+    if cookie.port_specified: h.append(("port_spec", None))
+    if cookie.domain_initial_dot: h.append(("domain_dot", None))
+    if cookie.secure: h.append(("secure", None))
+    if cookie.expires: h.append(("expires",
+                               time2isoz(float(cookie.expires))))
+    if cookie.discard: h.append(("discard", None))
+    if cookie.comment: h.append(("comment", cookie.comment))
+    if cookie.comment_url: h.append(("commenturl", cookie.comment_url))
+
+    keys = cookie._rest.keys()
+    keys.sort()
+    for k in keys:
+        h.append((k, str(cookie._rest[k])))
+
+    h.append(("version", str(cookie.version)))
+
+    return join_header_words([h])
+
+class LWPCookieJar(FileCookieJar):
+    """
+    The LWPCookieJar saves a sequence of"Set-Cookie3" lines.
+    "Set-Cookie3" is the format used by the libwww-perl libary, not known
+    to be compatible with any browser, but which is easy to read and
+    doesn't lose information about RFC 2965 cookies.
+
+    Additional methods
+
+    as_lwp_str(ignore_discard=True, ignore_expired=True)
+
+    """
+
+    def as_lwp_str(self, ignore_discard=True, ignore_expires=True):
+        """Return cookies as a string of "\n"-separated "Set-Cookie3" headers.
+
+        ignore_discard and ignore_expires: see docstring for FileCookieJar.save
+
+        """
+        now = time.time()
+        r = []
+        for cookie in self:
+            if not ignore_discard and cookie.discard:
+                continue
+            if not ignore_expires and cookie.is_expired(now):
+                continue
+            r.append("Set-Cookie3: %s" % lwp_cookie_str(cookie))
+        return "\n".join(r+[""])
+
+    def save(self, filename=None, ignore_discard=False, ignore_expires=False):
+        if filename is None:
+            if self.filename is not None: filename = self.filename
+            else: raise ValueError(MISSING_FILENAME_TEXT)
+
+        f = open(filename, "w")
+        try:
+            # There really isn't an LWP Cookies 2.0 format, but this indicates
+            # that there is extra information in here (domain_dot and
+            # port_spec) while still being compatible with libwww-perl, I hope.
+            f.write("#LWP-Cookies-2.0\n")
+            f.write(self.as_lwp_str(ignore_discard, ignore_expires))
+        finally:
+            f.close()
+
+    def _really_load(self, f, filename, ignore_discard, ignore_expires):
+        magic = f.readline()
+        if not re.search(self.magic_re, magic):
+            msg = ("%r does not look like a Set-Cookie3 (LWP) format "
+                   "file" % filename)
+            raise LoadError(msg)
+
+        now = time.time()
+
+        header = "Set-Cookie3:"
+        boolean_attrs = ("port_spec", "path_spec", "domain_dot",
+                         "secure", "discard")
+        value_attrs = ("version",
+                       "port", "path", "domain",
+                       "expires",
+                       "comment", "commenturl")
+
+        try:
+            while 1:
+                line = f.readline()
+                if line == "": break
+                if not line.startswith(header):
+                    continue
+                line = line[len(header):].strip()
+
+                for data in split_header_words([line]):
+                    name, value = data[0]
+                    standard = {}
+                    rest = {}
+                    for k in boolean_attrs:
+                        standard[k] = False
+                    for k, v in data[1:]:
+                        if k is not None:
+                            lc = k.lower()
+                        else:
+                            lc = None
+                        # don't lose case distinction for unknown fields
+                        if (lc in value_attrs) or (lc in boolean_attrs):
+                            k = lc
+                        if k in boolean_attrs:
+                            if v is None: v = True
+                            standard[k] = v
+                        elif k in value_attrs:
+                            standard[k] = v
+                        else:
+                            rest[k] = v
+
+                    h = standard.get
+                    expires = h("expires")
+                    discard = h("discard")
+                    if expires is not None:
+                        expires = iso2time(expires)
+                    if expires is None:
+                        discard = True
+                    domain = h("domain")
+                    domain_specified = domain.startswith(".")
+                    c = Cookie(h("version"), name, value,
+                               h("port"), h("port_spec"),
+                               domain, domain_specified, h("domain_dot"),
+                               h("path"), h("path_spec"),
+                               h("secure"),
+                               expires,
+                               discard,
+                               h("comment"),
+                               h("commenturl"),
+                               rest)
+                    if not ignore_discard and c.discard:
+                        continue
+                    if not ignore_expires and c.is_expired(now):
+                        continue
+                    self.set_cookie(c)
+
+        except IOError:
+            raise
+        except Exception:
+            _warn_unhandled_exception()
+            raise LoadError("invalid Set-Cookie3 format file %r: %r" %
+                            (filename, line))

Added: vendor/Python/current/Lib/_MozillaCookieJar.py
===================================================================
--- vendor/Python/current/Lib/_MozillaCookieJar.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/_MozillaCookieJar.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,149 @@
+"""Mozilla / Netscape cookie loading / saving."""
+
+import re, time
+
+from cookielib import (_warn_unhandled_exception, FileCookieJar, LoadError,
+                       Cookie, MISSING_FILENAME_TEXT)
+
+class MozillaCookieJar(FileCookieJar):
+    """
+
+    WARNING: you may want to backup your browser's cookies file if you use
+    this class to save cookies.  I *think* it works, but there have been
+    bugs in the past!
+
+    This class differs from CookieJar only in the format it uses to save and
+    load cookies to and from a file.  This class uses the Mozilla/Netscape
+    `cookies.txt' format.  lynx uses this file format, too.
+
+    Don't expect cookies saved while the browser is running to be noticed by
+    the browser (in fact, Mozilla on unix will overwrite your saved cookies if
+    you change them on disk while it's running; on Windows, you probably can't
+    save at all while the browser is running).
+
+    Note that the Mozilla/Netscape format will downgrade RFC2965 cookies to
+    Netscape cookies on saving.
+
+    In particular, the cookie version and port number information is lost,
+    together with information about whether or not Path, Port and Discard were
+    specified by the Set-Cookie2 (or Set-Cookie) header, and whether or not the
+    domain as set in the HTTP header started with a dot (yes, I'm aware some
+    domains in Netscape files start with a dot and some don't -- trust me, you
+    really don't want to know any more about this).
+
+    Note that though Mozilla and Netscape use the same format, they use
+    slightly different headers.  The class saves cookies using the Netscape
+    header by default (Mozilla can cope with that).
+
+    """
+    magic_re = "#( Netscape)? HTTP Cookie File"
+    header = """\
+    # Netscape HTTP Cookie File
+    # http://www.netscape.com/newsref/std/cookie_spec.html
+    # This is a generated file!  Do not edit.
+
+"""
+
+    def _really_load(self, f, filename, ignore_discard, ignore_expires):
+        now = time.time()
+
+        magic = f.readline()
+        if not re.search(self.magic_re, magic):
+            f.close()
+            raise LoadError(
+                "%r does not look like a Netscape format cookies file" %
+                filename)
+
+        try:
+            while 1:
+                line = f.readline()
+                if line == "": break
+
+                # last field may be absent, so keep any trailing tab
+                if line.endswith("\n"): line = line[:-1]
+
+                # skip comments and blank lines XXX what is $ for?
+                if (line.strip().startswith(("#", "$")) or
+                    line.strip() == ""):
+                    continue
+
+                domain, domain_specified, path, secure, expires, name, value = \
+                        line.split("\t")
+                secure = (secure == "TRUE")
+                domain_specified = (domain_specified == "TRUE")
+                if name == "":
+                    # cookies.txt regards 'Set-Cookie: foo' as a cookie
+                    # with no name, whereas cookielib regards it as a
+                    # cookie with no value.
+                    name = value
+                    value = None
+
+                initial_dot = domain.startswith(".")
+                assert domain_specified == initial_dot
+
+                discard = False
+                if expires == "":
+                    expires = None
+                    discard = True
+
+                # assume path_specified is false
+                c = Cookie(0, name, value,
+                           None, False,
+                           domain, domain_specified, initial_dot,
+                           path, False,
+                           secure,
+                           expires,
+                           discard,
+                           None,
+                           None,
+                           {})
+                if not ignore_discard and c.discard:
+                    continue
+                if not ignore_expires and c.is_expired(now):
+                    continue
+                self.set_cookie(c)
+
+        except IOError:
+            raise
+        except Exception:
+            _warn_unhandled_exception()
+            raise LoadError("invalid Netscape format cookies file %r: %r" %
+                            (filename, line))
+
+    def save(self, filename=None, ignore_discard=False, ignore_expires=False):
+        if filename is None:
+            if self.filename is not None: filename = self.filename
+            else: raise ValueError(MISSING_FILENAME_TEXT)
+
+        f = open(filename, "w")
+        try:
+            f.write(self.header)
+            now = time.time()
+            for cookie in self:
+                if not ignore_discard and cookie.discard:
+                    continue
+                if not ignore_expires and cookie.is_expired(now):
+                    continue
+                if cookie.secure: secure = "TRUE"
+                else: secure = "FALSE"
+                if cookie.domain.startswith("."): initial_dot = "TRUE"
+                else: initial_dot = "FALSE"
+                if cookie.expires is not None:
+                    expires = str(cookie.expires)
+                else:
+                    expires = ""
+                if cookie.value is None:
+                    # cookies.txt regards 'Set-Cookie: foo' as a cookie
+                    # with no name, whereas cookielib regards it as a
+                    # cookie with no value.
+                    name = ""
+                    value = cookie.name
+                else:
+                    name = cookie.name
+                    value = cookie.value
+                f.write(
+                    "\t".join([cookie.domain, initial_dot, cookie.path,
+                               secure, expires, name, value])+
+                    "\n")
+        finally:
+            f.close()

Added: vendor/Python/current/Lib/__future__.py
===================================================================
--- vendor/Python/current/Lib/__future__.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/__future__.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,116 @@
+"""Record of phased-in incompatible language changes.
+
+Each line is of the form:
+
+    FeatureName = "_Feature(" OptionalRelease "," MandatoryRelease ","
+                              CompilerFlag ")"
+
+where, normally, OptionalRelease < MandatoryRelease, and both are 5-tuples
+of the same form as sys.version_info:
+
+    (PY_MAJOR_VERSION, # the 2 in 2.1.0a3; an int
+     PY_MINOR_VERSION, # the 1; an int
+     PY_MICRO_VERSION, # the 0; an int
+     PY_RELEASE_LEVEL, # "alpha", "beta", "candidate" or "final"; string
+     PY_RELEASE_SERIAL # the 3; an int
+    )
+
+OptionalRelease records the first release in which
+
+    from __future__ import FeatureName
+
+was accepted.
+
+In the case of MandatoryReleases that have not yet occurred,
+MandatoryRelease predicts the release in which the feature will become part
+of the language.
+
+Else MandatoryRelease records when the feature became part of the language;
+in releases at or after that, modules no longer need
+
+    from __future__ import FeatureName
+
+to use the feature in question, but may continue to use such imports.
+
+MandatoryRelease may also be None, meaning that a planned feature got
+dropped.
+
+Instances of class _Feature have two corresponding methods,
+.getOptionalRelease() and .getMandatoryRelease().
+
+CompilerFlag is the (bitfield) flag that should be passed in the fourth
+argument to the builtin function compile() to enable the feature in
+dynamically compiled code.  This flag is stored in the .compiler_flag
+attribute on _Future instances.  These values must match the appropriate
+#defines of CO_xxx flags in Include/compile.h.
+
+No feature line is ever to be deleted from this file.
+"""
+
+all_feature_names = [
+    "nested_scopes",
+    "generators",
+    "division",
+    "absolute_import",
+    "with_statement",
+]
+
+__all__ = ["all_feature_names"] + all_feature_names
+
+# The CO_xxx symbols are defined here under the same names used by
+# compile.h, so that an editor search will find them here.  However,
+# they're not exported in __all__, because they don't really belong to
+# this module.
+CO_NESTED            = 0x0010   # nested_scopes
+CO_GENERATOR_ALLOWED = 0        # generators (obsolete, was 0x1000)
+CO_FUTURE_DIVISION   = 0x2000   # division
+CO_FUTURE_ABSOLUTE_IMPORT = 0x4000 # perform absolute imports by default
+CO_FUTURE_WITH_STATEMENT  = 0x8000   # with statement
+
+class _Feature:
+    def __init__(self, optionalRelease, mandatoryRelease, compiler_flag):
+        self.optional = optionalRelease
+        self.mandatory = mandatoryRelease
+        self.compiler_flag = compiler_flag
+
+    def getOptionalRelease(self):
+        """Return first release in which this feature was recognized.
+
+        This is a 5-tuple, of the same form as sys.version_info.
+        """
+
+        return self.optional
+
+    def getMandatoryRelease(self):
+        """Return release in which this feature will become mandatory.
+
+        This is a 5-tuple, of the same form as sys.version_info, or, if
+        the feature was dropped, is None.
+        """
+
+        return self.mandatory
+
+    def __repr__(self):
+        return "_Feature" + repr((self.optional,
+                                  self.mandatory,
+                                  self.compiler_flag))
+
+nested_scopes = _Feature((2, 1, 0, "beta",  1),
+                         (2, 2, 0, "alpha", 0),
+                         CO_NESTED)
+
+generators = _Feature((2, 2, 0, "alpha", 1),
+                      (2, 3, 0, "final", 0),
+                      CO_GENERATOR_ALLOWED)
+
+division = _Feature((2, 2, 0, "alpha", 2),
+                    (3, 0, 0, "alpha", 0),
+                    CO_FUTURE_DIVISION)
+
+absolute_import = _Feature((2, 5, 0, "alpha", 1),
+                           (2, 7, 0, "alpha", 0),
+                           CO_FUTURE_ABSOLUTE_IMPORT)
+
+with_statement = _Feature((2, 5, 0, "alpha", 1),
+                          (2, 6, 0, "alpha", 0),
+                          CO_FUTURE_WITH_STATEMENT)

Added: vendor/Python/current/Lib/__phello__.foo.py
===================================================================
--- vendor/Python/current/Lib/__phello__.foo.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/__phello__.foo.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1 @@
+# This file exists as a helper for the test.test_frozen module.

Added: vendor/Python/current/Lib/_strptime.py
===================================================================
--- vendor/Python/current/Lib/_strptime.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/_strptime.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,452 @@
+"""Strptime-related classes and functions.
+
+CLASSES:
+    LocaleTime -- Discovers and stores locale-specific time information
+    TimeRE -- Creates regexes for pattern matching a string of text containing
+                time information
+
+FUNCTIONS:
+    _getlang -- Figure out what language is being used for the locale
+    strptime -- Calculates the time struct represented by the passed-in string
+
+"""
+import time
+import locale
+import calendar
+from re import compile as re_compile
+from re import IGNORECASE
+from re import escape as re_escape
+from datetime import date as datetime_date
+try:
+    from thread import allocate_lock as _thread_allocate_lock
+except:
+    from dummy_thread import allocate_lock as _thread_allocate_lock
+
+__author__ = "Brett Cannon"
+__email__ = "brett at python.org"
+
+__all__ = ['strptime']
+
+def _getlang():
+    # Figure out what the current language is set to.
+    return locale.getlocale(locale.LC_TIME)
+
+class LocaleTime(object):
+    """Stores and handles locale-specific information related to time.
+
+    ATTRIBUTES:
+        f_weekday -- full weekday names (7-item list)
+        a_weekday -- abbreviated weekday names (7-item list)
+        f_month -- full month names (13-item list; dummy value in [0], which
+                    is added by code)
+        a_month -- abbreviated month names (13-item list, dummy value in
+                    [0], which is added by code)
+        am_pm -- AM/PM representation (2-item list)
+        LC_date_time -- format string for date/time representation (string)
+        LC_date -- format string for date representation (string)
+        LC_time -- format string for time representation (string)
+        timezone -- daylight- and non-daylight-savings timezone representation
+                    (2-item list of sets)
+        lang -- Language used by instance (2-item tuple)
+    """
+
+    def __init__(self):
+        """Set all attributes.
+
+        Order of methods called matters for dependency reasons.
+
+        The locale language is set at the offset and then checked again before
+        exiting.  This is to make sure that the attributes were not set with a
+        mix of information from more than one locale.  This would most likely
+        happen when using threads where one thread calls a locale-dependent
+        function while another thread changes the locale while the function in
+        the other thread is still running.  Proper coding would call for
+        locks to prevent changing the locale while locale-dependent code is
+        running.  The check here is done in case someone does not think about
+        doing this.
+
+        Only other possible issue is if someone changed the timezone and did
+        not call tz.tzset .  That is an issue for the programmer, though,
+        since changing the timezone is worthless without that call.
+
+        """
+        self.lang = _getlang()
+        self.__calc_weekday()
+        self.__calc_month()
+        self.__calc_am_pm()
+        self.__calc_timezone()
+        self.__calc_date_time()
+        if _getlang() != self.lang:
+            raise ValueError("locale changed during initialization")
+
+    def __pad(self, seq, front):
+        # Add '' to seq to either the front (is True), else the back.
+        seq = list(seq)
+        if front:
+            seq.insert(0, '')
+        else:
+            seq.append('')
+        return seq
+
+    def __calc_weekday(self):
+        # Set self.a_weekday and self.f_weekday using the calendar
+        # module.
+        a_weekday = [calendar.day_abbr[i].lower() for i in range(7)]
+        f_weekday = [calendar.day_name[i].lower() for i in range(7)]
+        self.a_weekday = a_weekday
+        self.f_weekday = f_weekday
+
+    def __calc_month(self):
+        # Set self.f_month and self.a_month using the calendar module.
+        a_month = [calendar.month_abbr[i].lower() for i in range(13)]
+        f_month = [calendar.month_name[i].lower() for i in range(13)]
+        self.a_month = a_month
+        self.f_month = f_month
+
+    def __calc_am_pm(self):
+        # Set self.am_pm by using time.strftime().
+
+        # The magic date (1999,3,17,hour,44,55,2,76,0) is not really that
+        # magical; just happened to have used it everywhere else where a
+        # static date was needed.
+        am_pm = []
+        for hour in (01,22):
+            time_tuple = time.struct_time((1999,3,17,hour,44,55,2,76,0))
+            am_pm.append(time.strftime("%p", time_tuple).lower())
+        self.am_pm = am_pm
+
+    def __calc_date_time(self):
+        # Set self.date_time, self.date, & self.time by using
+        # time.strftime().
+
+        # Use (1999,3,17,22,44,55,2,76,0) for magic date because the amount of
+        # overloaded numbers is minimized.  The order in which searches for
+        # values within the format string is very important; it eliminates
+        # possible ambiguity for what something represents.
+        time_tuple = time.struct_time((1999,3,17,22,44,55,2,76,0))
+        date_time = [None, None, None]
+        date_time[0] = time.strftime("%c", time_tuple).lower()
+        date_time[1] = time.strftime("%x", time_tuple).lower()
+        date_time[2] = time.strftime("%X", time_tuple).lower()
+        replacement_pairs = [('%', '%%'), (self.f_weekday[2], '%A'),
+                    (self.f_month[3], '%B'), (self.a_weekday[2], '%a'),
+                    (self.a_month[3], '%b'), (self.am_pm[1], '%p'),
+                    ('1999', '%Y'), ('99', '%y'), ('22', '%H'),
+                    ('44', '%M'), ('55', '%S'), ('76', '%j'),
+                    ('17', '%d'), ('03', '%m'), ('3', '%m'),
+                    # '3' needed for when no leading zero.
+                    ('2', '%w'), ('10', '%I')]
+        replacement_pairs.extend([(tz, "%Z") for tz_values in self.timezone
+                                                for tz in tz_values])
+        for offset,directive in ((0,'%c'), (1,'%x'), (2,'%X')):
+            current_format = date_time[offset]
+            for old, new in replacement_pairs:
+                # Must deal with possible lack of locale info
+                # manifesting itself as the empty string (e.g., Swedish's
+                # lack of AM/PM info) or a platform returning a tuple of empty
+                # strings (e.g., MacOS 9 having timezone as ('','')).
+                if old:
+                    current_format = current_format.replace(old, new)
+            # If %W is used, then Sunday, 2005-01-03 will fall on week 0 since
+            # 2005-01-03 occurs before the first Monday of the year.  Otherwise
+            # %U is used.
+            time_tuple = time.struct_time((1999,1,3,1,1,1,6,3,0))
+            if '00' in time.strftime(directive, time_tuple):
+                U_W = '%W'
+            else:
+                U_W = '%U'
+            date_time[offset] = current_format.replace('11', U_W)
+        self.LC_date_time = date_time[0]
+        self.LC_date = date_time[1]
+        self.LC_time = date_time[2]
+
+    def __calc_timezone(self):
+        # Set self.timezone by using time.tzname.
+        # Do not worry about possibility of time.tzname[0] == timetzname[1]
+        # and time.daylight; handle that in strptime .
+        try:
+            time.tzset()
+        except AttributeError:
+            pass
+        no_saving = frozenset(["utc", "gmt", time.tzname[0].lower()])
+        if time.daylight:
+            has_saving = frozenset([time.tzname[1].lower()])
+        else:
+            has_saving = frozenset()
+        self.timezone = (no_saving, has_saving)
+
+
+class TimeRE(dict):
+    """Handle conversion from format directives to regexes."""
+
+    def __init__(self, locale_time=None):
+        """Create keys/values.
+
+        Order of execution is important for dependency reasons.
+
+        """
+        if locale_time:
+            self.locale_time = locale_time
+        else:
+            self.locale_time = LocaleTime()
+        base = super(TimeRE, self)
+        base.__init__({
+            # The " \d" part of the regex is to make %c from ANSI C work
+            'd': r"(?P<d>3[0-1]|[1-2]\d|0[1-9]|[1-9]| [1-9])",
+            'H': r"(?P<H>2[0-3]|[0-1]\d|\d)",
+            'I': r"(?P<I>1[0-2]|0[1-9]|[1-9])",
+            'j': r"(?P<j>36[0-6]|3[0-5]\d|[1-2]\d\d|0[1-9]\d|00[1-9]|[1-9]\d|0[1-9]|[1-9])",
+            'm': r"(?P<m>1[0-2]|0[1-9]|[1-9])",
+            'M': r"(?P<M>[0-5]\d|\d)",
+            'S': r"(?P<S>6[0-1]|[0-5]\d|\d)",
+            'U': r"(?P<U>5[0-3]|[0-4]\d|\d)",
+            'w': r"(?P<w>[0-6])",
+            # W is set below by using 'U'
+            'y': r"(?P<y>\d\d)",
+            #XXX: Does 'Y' need to worry about having less or more than
+            #     4 digits?
+            'Y': r"(?P<Y>\d\d\d\d)",
+            'A': self.__seqToRE(self.locale_time.f_weekday, 'A'),
+            'a': self.__seqToRE(self.locale_time.a_weekday, 'a'),
+            'B': self.__seqToRE(self.locale_time.f_month[1:], 'B'),
+            'b': self.__seqToRE(self.locale_time.a_month[1:], 'b'),
+            'p': self.__seqToRE(self.locale_time.am_pm, 'p'),
+            'Z': self.__seqToRE((tz for tz_names in self.locale_time.timezone
+                                        for tz in tz_names),
+                                'Z'),
+            '%': '%'})
+        base.__setitem__('W', base.__getitem__('U').replace('U', 'W'))
+        base.__setitem__('c', self.pattern(self.locale_time.LC_date_time))
+        base.__setitem__('x', self.pattern(self.locale_time.LC_date))
+        base.__setitem__('X', self.pattern(self.locale_time.LC_time))
+
+    def __seqToRE(self, to_convert, directive):
+        """Convert a list to a regex string for matching a directive.
+
+        Want possible matching values to be from longest to shortest.  This
+        prevents the possibility of a match occuring for a value that also
+        a substring of a larger value that should have matched (e.g., 'abc'
+        matching when 'abcdef' should have been the match).
+
+        """
+        to_convert = sorted(to_convert, key=len, reverse=True)
+        for value in to_convert:
+            if value != '':
+                break
+        else:
+            return ''
+        regex = '|'.join(re_escape(stuff) for stuff in to_convert)
+        regex = '(?P<%s>%s' % (directive, regex)
+        return '%s)' % regex
+
+    def pattern(self, format):
+        """Return regex pattern for the format string.
+
+        Need to make sure that any characters that might be interpreted as
+        regex syntax are escaped.
+
+        """
+        processed_format = ''
+        # The sub() call escapes all characters that might be misconstrued
+        # as regex syntax.  Cannot use re.escape since we have to deal with
+        # format directives (%m, etc.).
+        regex_chars = re_compile(r"([\\.^$*+?\(\){}\[\]|])")
+        format = regex_chars.sub(r"\\\1", format)
+        whitespace_replacement = re_compile('\s+')
+        format = whitespace_replacement.sub('\s*', format)
+        while '%' in format:
+            directive_index = format.index('%')+1
+            processed_format = "%s%s%s" % (processed_format,
+                                           format[:directive_index-1],
+                                           self[format[directive_index]])
+            format = format[directive_index+1:]
+        return "%s%s" % (processed_format, format)
+
+    def compile(self, format):
+        """Return a compiled re object for the format string."""
+        return re_compile(self.pattern(format), IGNORECASE)
+
+_cache_lock = _thread_allocate_lock()
+# DO NOT modify _TimeRE_cache or _regex_cache without acquiring the cache lock
+# first!
+_TimeRE_cache = TimeRE()
+_CACHE_MAX_SIZE = 5 # Max number of regexes stored in _regex_cache
+_regex_cache = {}
+
+def _calc_julian_from_U_or_W(year, week_of_year, day_of_week, week_starts_Mon):
+    """Calculate the Julian day based on the year, week of the year, and day of
+    the week, with week_start_day representing whether the week of the year
+    assumes the week starts on Sunday or Monday (6 or 0)."""
+    first_weekday = datetime_date(year, 1, 1).weekday()
+    # If we are dealing with the %U directive (week starts on Sunday), it's
+    # easier to just shift the view to Sunday being the first day of the
+    # week.
+    if not week_starts_Mon:
+        first_weekday = (first_weekday + 1) % 7
+        day_of_week = (day_of_week + 1) % 7
+    # Need to watch out for a week 0 (when the first day of the year is not
+    # the same as that specified by %U or %W).
+    week_0_length = (7 - first_weekday) % 7
+    if week_of_year == 0:
+        return 1 + day_of_week - first_weekday
+    else:
+        days_to_week = week_0_length + (7 * (week_of_year - 1))
+        return 1 + days_to_week + day_of_week
+
+
+def strptime(data_string, format="%a %b %d %H:%M:%S %Y"):
+    """Return a time struct based on the input string and the format string."""
+    global _TimeRE_cache, _regex_cache
+    _cache_lock.acquire()
+    try:
+        time_re = _TimeRE_cache
+        locale_time = time_re.locale_time
+        if _getlang() != locale_time.lang:
+            _TimeRE_cache = TimeRE()
+            _regex_cache = {}
+        if len(_regex_cache) > _CACHE_MAX_SIZE:
+            _regex_cache.clear()
+        format_regex = _regex_cache.get(format)
+        if not format_regex:
+            try:
+                format_regex = time_re.compile(format)
+            # KeyError raised when a bad format is found; can be specified as
+            # \\, in which case it was a stray % but with a space after it
+            except KeyError, err:
+                bad_directive = err.args[0]
+                if bad_directive == "\\":
+                    bad_directive = "%"
+                del err
+                raise ValueError("'%s' is a bad directive in format '%s'" %
+                                    (bad_directive, format))
+            # IndexError only occurs when the format string is "%"
+            except IndexError:
+                raise ValueError("stray %% in format '%s'" % format)
+            _regex_cache[format] = format_regex
+    finally:
+        _cache_lock.release()
+    found = format_regex.match(data_string)
+    if not found:
+        raise ValueError("time data did not match format:  data=%s  fmt=%s" %
+                         (data_string, format))
+    if len(data_string) != found.end():
+        raise ValueError("unconverted data remains: %s" %
+                          data_string[found.end():])
+    year = 1900
+    month = day = 1
+    hour = minute = second = 0
+    tz = -1
+    # Default to -1 to signify that values not known; not critical to have,
+    # though
+    week_of_year = -1
+    week_of_year_start = -1
+    # weekday and julian defaulted to -1 so as to signal need to calculate
+    # values
+    weekday = julian = -1
+    found_dict = found.groupdict()
+    for group_key in found_dict.iterkeys():
+        # Directives not explicitly handled below:
+        #   c, x, X
+        #      handled by making out of other directives
+        #   U, W
+        #      worthless without day of the week
+        if group_key == 'y':
+            year = int(found_dict['y'])
+            # Open Group specification for strptime() states that a %y
+            #value in the range of [00, 68] is in the century 2000, while
+            #[69,99] is in the century 1900
+            if year <= 68:
+                year += 2000
+            else:
+                year += 1900
+        elif group_key == 'Y':
+            year = int(found_dict['Y'])
+        elif group_key == 'm':
+            month = int(found_dict['m'])
+        elif group_key == 'B':
+            month = locale_time.f_month.index(found_dict['B'].lower())
+        elif group_key == 'b':
+            month = locale_time.a_month.index(found_dict['b'].lower())
+        elif group_key == 'd':
+            day = int(found_dict['d'])
+        elif group_key == 'H':
+            hour = int(found_dict['H'])
+        elif group_key == 'I':
+            hour = int(found_dict['I'])
+            ampm = found_dict.get('p', '').lower()
+            # If there was no AM/PM indicator, we'll treat this like AM
+            if ampm in ('', locale_time.am_pm[0]):
+                # We're in AM so the hour is correct unless we're
+                # looking at 12 midnight.
+                # 12 midnight == 12 AM == hour 0
+                if hour == 12:
+                    hour = 0
+            elif ampm == locale_time.am_pm[1]:
+                # We're in PM so we need to add 12 to the hour unless
+                # we're looking at 12 noon.
+                # 12 noon == 12 PM == hour 12
+                if hour != 12:
+                    hour += 12
+        elif group_key == 'M':
+            minute = int(found_dict['M'])
+        elif group_key == 'S':
+            second = int(found_dict['S'])
+        elif group_key == 'A':
+            weekday = locale_time.f_weekday.index(found_dict['A'].lower())
+        elif group_key == 'a':
+            weekday = locale_time.a_weekday.index(found_dict['a'].lower())
+        elif group_key == 'w':
+            weekday = int(found_dict['w'])
+            if weekday == 0:
+                weekday = 6
+            else:
+                weekday -= 1
+        elif group_key == 'j':
+            julian = int(found_dict['j'])
+        elif group_key in ('U', 'W'):
+            week_of_year = int(found_dict[group_key])
+            if group_key == 'U':
+                # U starts week on Sunday.
+                week_of_year_start = 6
+            else:
+                # W starts week on Monday.
+                week_of_year_start = 0
+        elif group_key == 'Z':
+            # Since -1 is default value only need to worry about setting tz if
+            # it can be something other than -1.
+            found_zone = found_dict['Z'].lower()
+            for value, tz_values in enumerate(locale_time.timezone):
+                if found_zone in tz_values:
+                    # Deal with bad locale setup where timezone names are the
+                    # same and yet time.daylight is true; too ambiguous to
+                    # be able to tell what timezone has daylight savings
+                    if (time.tzname[0] == time.tzname[1] and
+                       time.daylight and found_zone not in ("utc", "gmt")):
+                        break
+                    else:
+                        tz = value
+                        break
+    # If we know the week of the year and what day of that week, we can figure
+    # out the Julian day of the year.
+    if julian == -1 and week_of_year != -1 and weekday != -1:
+        week_starts_Mon = True if week_of_year_start == 0 else False
+        julian = _calc_julian_from_U_or_W(year, week_of_year, weekday,
+                                            week_starts_Mon)
+    # Cannot pre-calculate datetime_date() since can change in Julian
+    # calculation and thus could have different value for the day of the week
+    # calculation.
+    if julian == -1:
+        # Need to add 1 to result since first day of the year is 1, not 0.
+        julian = datetime_date(year, month, day).toordinal() - \
+                  datetime_date(year, 1, 1).toordinal() + 1
+    else:  # Assume that if they bothered to include Julian day it will
+           # be accurate.
+        datetime_result = datetime_date.fromordinal((julian - 1) + datetime_date(year, 1, 1).toordinal())
+        year = datetime_result.year
+        month = datetime_result.month
+        day = datetime_result.day
+    if weekday == -1:
+        weekday = datetime_date(year, month, day).weekday()
+    return time.struct_time((year, month, day,
+                             hour, minute, second,
+                             weekday, julian, tz))

Added: vendor/Python/current/Lib/_threading_local.py
===================================================================
--- vendor/Python/current/Lib/_threading_local.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/_threading_local.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,241 @@
+"""Thread-local objects.
+
+(Note that this module provides a Python version of the threading.local
+ class.  Depending on the version of Python you're using, there may be a
+ faster one available.  You should always import the `local` class from
+ `threading`.)
+
+Thread-local objects support the management of thread-local data.
+If you have data that you want to be local to a thread, simply create
+a thread-local object and use its attributes:
+
+  >>> mydata = local()
+  >>> mydata.number = 42
+  >>> mydata.number
+  42
+
+You can also access the local-object's dictionary:
+
+  >>> mydata.__dict__
+  {'number': 42}
+  >>> mydata.__dict__.setdefault('widgets', [])
+  []
+  >>> mydata.widgets
+  []
+
+What's important about thread-local objects is that their data are
+local to a thread. If we access the data in a different thread:
+
+  >>> log = []
+  >>> def f():
+  ...     items = mydata.__dict__.items()
+  ...     items.sort()
+  ...     log.append(items)
+  ...     mydata.number = 11
+  ...     log.append(mydata.number)
+
+  >>> import threading
+  >>> thread = threading.Thread(target=f)
+  >>> thread.start()
+  >>> thread.join()
+  >>> log
+  [[], 11]
+
+we get different data.  Furthermore, changes made in the other thread
+don't affect data seen in this thread:
+
+  >>> mydata.number
+  42
+
+Of course, values you get from a local object, including a __dict__
+attribute, are for whatever thread was current at the time the
+attribute was read.  For that reason, you generally don't want to save
+these values across threads, as they apply only to the thread they
+came from.
+
+You can create custom local objects by subclassing the local class:
+
+  >>> class MyLocal(local):
+  ...     number = 2
+  ...     initialized = False
+  ...     def __init__(self, **kw):
+  ...         if self.initialized:
+  ...             raise SystemError('__init__ called too many times')
+  ...         self.initialized = True
+  ...         self.__dict__.update(kw)
+  ...     def squared(self):
+  ...         return self.number ** 2
+
+This can be useful to support default values, methods and
+initialization.  Note that if you define an __init__ method, it will be
+called each time the local object is used in a separate thread.  This
+is necessary to initialize each thread's dictionary.
+
+Now if we create a local object:
+
+  >>> mydata = MyLocal(color='red')
+
+Now we have a default number:
+
+  >>> mydata.number
+  2
+
+an initial color:
+
+  >>> mydata.color
+  'red'
+  >>> del mydata.color
+
+And a method that operates on the data:
+
+  >>> mydata.squared()
+  4
+
+As before, we can access the data in a separate thread:
+
+  >>> log = []
+  >>> thread = threading.Thread(target=f)
+  >>> thread.start()
+  >>> thread.join()
+  >>> log
+  [[('color', 'red'), ('initialized', True)], 11]
+
+without affecting this thread's data:
+
+  >>> mydata.number
+  2
+  >>> mydata.color
+  Traceback (most recent call last):
+  ...
+  AttributeError: 'MyLocal' object has no attribute 'color'
+
+Note that subclasses can define slots, but they are not thread
+local. They are shared across threads:
+
+  >>> class MyLocal(local):
+  ...     __slots__ = 'number'
+
+  >>> mydata = MyLocal()
+  >>> mydata.number = 42
+  >>> mydata.color = 'red'
+
+So, the separate thread:
+
+  >>> thread = threading.Thread(target=f)
+  >>> thread.start()
+  >>> thread.join()
+
+affects what we see:
+
+  >>> mydata.number
+  11
+
+>>> del mydata
+"""
+
+__all__ = ["local"]
+
+# We need to use objects from the threading module, but the threading
+# module may also want to use our `local` class, if support for locals
+# isn't compiled in to the `thread` module.  This creates potential problems
+# with circular imports.  For that reason, we don't import `threading`
+# until the bottom of this file (a hack sufficient to worm around the
+# potential problems).  Note that almost all platforms do have support for
+# locals in the `thread` module, and there is no circular import problem
+# then, so problems introduced by fiddling the order of imports here won't
+# manifest on most boxes.
+
+class _localbase(object):
+    __slots__ = '_local__key', '_local__args', '_local__lock'
+
+    def __new__(cls, *args, **kw):
+        self = object.__new__(cls)
+        key = '_local__key', 'thread.local.' + str(id(self))
+        object.__setattr__(self, '_local__key', key)
+        object.__setattr__(self, '_local__args', (args, kw))
+        object.__setattr__(self, '_local__lock', RLock())
+
+        if args or kw and (cls.__init__ is object.__init__):
+            raise TypeError("Initialization arguments are not supported")
+
+        # We need to create the thread dict in anticipation of
+        # __init__ being called, to make sure we don't call it
+        # again ourselves.
+        dict = object.__getattribute__(self, '__dict__')
+        currentThread().__dict__[key] = dict
+
+        return self
+
+def _patch(self):
+    key = object.__getattribute__(self, '_local__key')
+    d = currentThread().__dict__.get(key)
+    if d is None:
+        d = {}
+        currentThread().__dict__[key] = d
+        object.__setattr__(self, '__dict__', d)
+
+        # we have a new instance dict, so call out __init__ if we have
+        # one
+        cls = type(self)
+        if cls.__init__ is not object.__init__:
+            args, kw = object.__getattribute__(self, '_local__args')
+            cls.__init__(self, *args, **kw)
+    else:
+        object.__setattr__(self, '__dict__', d)
+
+class local(_localbase):
+
+    def __getattribute__(self, name):
+        lock = object.__getattribute__(self, '_local__lock')
+        lock.acquire()
+        try:
+            _patch(self)
+            return object.__getattribute__(self, name)
+        finally:
+            lock.release()
+
+    def __setattr__(self, name, value):
+        lock = object.__getattribute__(self, '_local__lock')
+        lock.acquire()
+        try:
+            _patch(self)
+            return object.__setattr__(self, name, value)
+        finally:
+            lock.release()
+
+    def __delattr__(self, name):
+        lock = object.__getattribute__(self, '_local__lock')
+        lock.acquire()
+        try:
+            _patch(self)
+            return object.__delattr__(self, name)
+        finally:
+            lock.release()
+
+    def __del__(self):
+        import threading
+
+        key = object.__getattribute__(self, '_local__key')
+
+        try:
+            threads = list(threading.enumerate())
+        except:
+            # If enumerate fails, as it seems to do during
+            # shutdown, we'll skip cleanup under the assumption
+            # that there is nothing to clean up.
+            return
+
+        for thread in threads:
+            try:
+                __dict__ = thread.__dict__
+            except AttributeError:
+                # Thread is dying, rest in peace.
+                continue
+
+            if key in __dict__:
+                try:
+                    del __dict__[key]
+                except KeyError:
+                    pass # didn't have anything in this thread
+
+from threading import currentThread, RLock

Added: vendor/Python/current/Lib/aifc.py
===================================================================
--- vendor/Python/current/Lib/aifc.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/aifc.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,961 @@
+"""Stuff to parse AIFF-C and AIFF files.
+
+Unless explicitly stated otherwise, the description below is true
+both for AIFF-C files and AIFF files.
+
+An AIFF-C file has the following structure.
+
+  +-----------------+
+  | FORM            |
+  +-----------------+
+  | <size>          |
+  +----+------------+
+  |    | AIFC       |
+  |    +------------+
+  |    | <chunks>   |
+  |    |    .       |
+  |    |    .       |
+  |    |    .       |
+  +----+------------+
+
+An AIFF file has the string "AIFF" instead of "AIFC".
+
+A chunk consists of an identifier (4 bytes) followed by a size (4 bytes,
+big endian order), followed by the data.  The size field does not include
+the size of the 8 byte header.
+
+The following chunk types are recognized.
+
+  FVER
+      <version number of AIFF-C defining document> (AIFF-C only).
+  MARK
+      <# of markers> (2 bytes)
+      list of markers:
+          <marker ID> (2 bytes, must be > 0)
+          <position> (4 bytes)
+          <marker name> ("pstring")
+  COMM
+      <# of channels> (2 bytes)
+      <# of sound frames> (4 bytes)
+      <size of the samples> (2 bytes)
+      <sampling frequency> (10 bytes, IEEE 80-bit extended
+          floating point)
+      in AIFF-C files only:
+      <compression type> (4 bytes)
+      <human-readable version of compression type> ("pstring")
+  SSND
+      <offset> (4 bytes, not used by this program)
+      <blocksize> (4 bytes, not used by this program)
+      <sound data>
+
+A pstring consists of 1 byte length, a string of characters, and 0 or 1
+byte pad to make the total length even.
+
+Usage.
+
+Reading AIFF files:
+  f = aifc.open(file, 'r')
+where file is either the name of a file or an open file pointer.
+The open file pointer must have methods read(), seek(), and close().
+In some types of audio files, if the setpos() method is not used,
+the seek() method is not necessary.
+
+This returns an instance of a class with the following public methods:
+  getnchannels()  -- returns number of audio channels (1 for
+             mono, 2 for stereo)
+  getsampwidth()  -- returns sample width in bytes
+  getframerate()  -- returns sampling frequency
+  getnframes()    -- returns number of audio frames
+  getcomptype()   -- returns compression type ('NONE' for AIFF files)
+  getcompname()   -- returns human-readable version of
+             compression type ('not compressed' for AIFF files)
+  getparams() -- returns a tuple consisting of all of the
+             above in the above order
+  getmarkers()    -- get the list of marks in the audio file or None
+             if there are no marks
+  getmark(id) -- get mark with the specified id (raises an error
+             if the mark does not exist)
+  readframes(n)   -- returns at most n frames of audio
+  rewind()    -- rewind to the beginning of the audio stream
+  setpos(pos) -- seek to the specified position
+  tell()      -- return the current position
+  close()     -- close the instance (make it unusable)
+The position returned by tell(), the position given to setpos() and
+the position of marks are all compatible and have nothing to do with
+the actual position in the file.
+The close() method is called automatically when the class instance
+is destroyed.
+
+Writing AIFF files:
+  f = aifc.open(file, 'w')
+where file is either the name of a file or an open file pointer.
+The open file pointer must have methods write(), tell(), seek(), and
+close().
+
+This returns an instance of a class with the following public methods:
+  aiff()      -- create an AIFF file (AIFF-C default)
+  aifc()      -- create an AIFF-C file
+  setnchannels(n) -- set the number of channels
+  setsampwidth(n) -- set the sample width
+  setframerate(n) -- set the frame rate
+  setnframes(n)   -- set the number of frames
+  setcomptype(type, name)
+          -- set the compression type and the
+             human-readable compression type
+  setparams(tuple)
+          -- set all parameters at once
+  setmark(id, pos, name)
+          -- add specified mark to the list of marks
+  tell()      -- return current position in output file (useful
+             in combination with setmark())
+  writeframesraw(data)
+          -- write audio frames without pathing up the
+             file header
+  writeframes(data)
+          -- write audio frames and patch up the file header
+  close()     -- patch up the file header and close the
+             output file
+You should set the parameters before the first writeframesraw or
+writeframes.  The total number of frames does not need to be set,
+but when it is set to the correct value, the header does not have to
+be patched up.
+It is best to first set all parameters, perhaps possibly the
+compression type, and then write audio frames using writeframesraw.
+When all frames have been written, either call writeframes('') or
+close() to patch up the sizes in the header.
+Marks can be added anytime.  If there are any marks, ypu must call
+close() after all frames have been written.
+The close() method is called automatically when the class instance
+is destroyed.
+
+When a file is opened with the extension '.aiff', an AIFF file is
+written, otherwise an AIFF-C file is written.  This default can be
+changed by calling aiff() or aifc() before the first writeframes or
+writeframesraw.
+"""
+
+import struct
+import __builtin__
+
+__all__ = ["Error","open","openfp"]
+
+class Error(Exception):
+    pass
+
+_AIFC_version = 0xA2805140L     # Version 1 of AIFF-C
+
+_skiplist = 'COMT', 'INST', 'MIDI', 'AESD', \
+      'APPL', 'NAME', 'AUTH', '(c) ', 'ANNO'
+
+def _read_long(file):
+    try:
+        return struct.unpack('>l', file.read(4))[0]
+    except struct.error:
+        raise EOFError
+
+def _read_ulong(file):
+    try:
+        return struct.unpack('>L', file.read(4))[0]
+    except struct.error:
+        raise EOFError
+
+def _read_short(file):
+    try:
+        return struct.unpack('>h', file.read(2))[0]
+    except struct.error:
+        raise EOFError
+
+def _read_string(file):
+    length = ord(file.read(1))
+    if length == 0:
+        data = ''
+    else:
+        data = file.read(length)
+    if length & 1 == 0:
+        dummy = file.read(1)
+    return data
+
+_HUGE_VAL = 1.79769313486231e+308 # See <limits.h>
+
+def _read_float(f): # 10 bytes
+    expon = _read_short(f) # 2 bytes
+    sign = 1
+    if expon < 0:
+        sign = -1
+        expon = expon + 0x8000
+    himant = _read_ulong(f) # 4 bytes
+    lomant = _read_ulong(f) # 4 bytes
+    if expon == himant == lomant == 0:
+        f = 0.0
+    elif expon == 0x7FFF:
+        f = _HUGE_VAL
+    else:
+        expon = expon - 16383
+        f = (himant * 0x100000000L + lomant) * pow(2.0, expon - 63)
+    return sign * f
+
+def _write_short(f, x):
+    f.write(struct.pack('>h', x))
+
+def _write_long(f, x):
+    f.write(struct.pack('>L', x))
+
+def _write_string(f, s):
+    if len(s) > 255:
+        raise ValueError("string exceeds maximum pstring length")
+    f.write(chr(len(s)))
+    f.write(s)
+    if len(s) & 1 == 0:
+        f.write(chr(0))
+
+def _write_float(f, x):
+    import math
+    if x < 0:
+        sign = 0x8000
+        x = x * -1
+    else:
+        sign = 0
+    if x == 0:
+        expon = 0
+        himant = 0
+        lomant = 0
+    else:
+        fmant, expon = math.frexp(x)
+        if expon > 16384 or fmant >= 1:     # Infinity or NaN
+            expon = sign|0x7FFF
+            himant = 0
+            lomant = 0
+        else:                   # Finite
+            expon = expon + 16382
+            if expon < 0:           # denormalized
+                fmant = math.ldexp(fmant, expon)
+                expon = 0
+            expon = expon | sign
+            fmant = math.ldexp(fmant, 32)
+            fsmant = math.floor(fmant)
+            himant = long(fsmant)
+            fmant = math.ldexp(fmant - fsmant, 32)
+            fsmant = math.floor(fmant)
+            lomant = long(fsmant)
+    _write_short(f, expon)
+    _write_long(f, himant)
+    _write_long(f, lomant)
+
+from chunk import Chunk
+
+class Aifc_read:
+    # Variables used in this class:
+    #
+    # These variables are available to the user though appropriate
+    # methods of this class:
+    # _file -- the open file with methods read(), close(), and seek()
+    #       set through the __init__() method
+    # _nchannels -- the number of audio channels
+    #       available through the getnchannels() method
+    # _nframes -- the number of audio frames
+    #       available through the getnframes() method
+    # _sampwidth -- the number of bytes per audio sample
+    #       available through the getsampwidth() method
+    # _framerate -- the sampling frequency
+    #       available through the getframerate() method
+    # _comptype -- the AIFF-C compression type ('NONE' if AIFF)
+    #       available through the getcomptype() method
+    # _compname -- the human-readable AIFF-C compression type
+    #       available through the getcomptype() method
+    # _markers -- the marks in the audio file
+    #       available through the getmarkers() and getmark()
+    #       methods
+    # _soundpos -- the position in the audio stream
+    #       available through the tell() method, set through the
+    #       setpos() method
+    #
+    # These variables are used internally only:
+    # _version -- the AIFF-C version number
+    # _decomp -- the decompressor from builtin module cl
+    # _comm_chunk_read -- 1 iff the COMM chunk has been read
+    # _aifc -- 1 iff reading an AIFF-C file
+    # _ssnd_seek_needed -- 1 iff positioned correctly in audio
+    #       file for readframes()
+    # _ssnd_chunk -- instantiation of a chunk class for the SSND chunk
+    # _framesize -- size of one frame in the file
+
+    def initfp(self, file):
+        self._version = 0
+        self._decomp = None
+        self._convert = None
+        self._markers = []
+        self._soundpos = 0
+        self._file = Chunk(file)
+        if self._file.getname() != 'FORM':
+            raise Error, 'file does not start with FORM id'
+        formdata = self._file.read(4)
+        if formdata == 'AIFF':
+            self._aifc = 0
+        elif formdata == 'AIFC':
+            self._aifc = 1
+        else:
+            raise Error, 'not an AIFF or AIFF-C file'
+        self._comm_chunk_read = 0
+        while 1:
+            self._ssnd_seek_needed = 1
+            try:
+                chunk = Chunk(self._file)
+            except EOFError:
+                break
+            chunkname = chunk.getname()
+            if chunkname == 'COMM':
+                self._read_comm_chunk(chunk)
+                self._comm_chunk_read = 1
+            elif chunkname == 'SSND':
+                self._ssnd_chunk = chunk
+                dummy = chunk.read(8)
+                self._ssnd_seek_needed = 0
+            elif chunkname == 'FVER':
+                self._version = _read_ulong(chunk)
+            elif chunkname == 'MARK':
+                self._readmark(chunk)
+            elif chunkname in _skiplist:
+                pass
+            else:
+                raise Error, 'unrecognized chunk type '+chunk.chunkname
+            chunk.skip()
+        if not self._comm_chunk_read or not self._ssnd_chunk:
+            raise Error, 'COMM chunk and/or SSND chunk missing'
+        if self._aifc and self._decomp:
+            import cl
+            params = [cl.ORIGINAL_FORMAT, 0,
+                  cl.BITS_PER_COMPONENT, self._sampwidth * 8,
+                  cl.FRAME_RATE, self._framerate]
+            if self._nchannels == 1:
+                params[1] = cl.MONO
+            elif self._nchannels == 2:
+                params[1] = cl.STEREO_INTERLEAVED
+            else:
+                raise Error, 'cannot compress more than 2 channels'
+            self._decomp.SetParams(params)
+
+    def __init__(self, f):
+        if type(f) == type(''):
+            f = __builtin__.open(f, 'rb')
+        # else, assume it is an open file object already
+        self.initfp(f)
+
+    #
+    # User visible methods.
+    #
+    def getfp(self):
+        return self._file
+
+    def rewind(self):
+        self._ssnd_seek_needed = 1
+        self._soundpos = 0
+
+    def close(self):
+        if self._decomp:
+            self._decomp.CloseDecompressor()
+            self._decomp = None
+        self._file = None
+
+    def tell(self):
+        return self._soundpos
+
+    def getnchannels(self):
+        return self._nchannels
+
+    def getnframes(self):
+        return self._nframes
+
+    def getsampwidth(self):
+        return self._sampwidth
+
+    def getframerate(self):
+        return self._framerate
+
+    def getcomptype(self):
+        return self._comptype
+
+    def getcompname(self):
+        return self._compname
+
+##  def getversion(self):
+##      return self._version
+
+    def getparams(self):
+        return self.getnchannels(), self.getsampwidth(), \
+              self.getframerate(), self.getnframes(), \
+              self.getcomptype(), self.getcompname()
+
+    def getmarkers(self):
+        if len(self._markers) == 0:
+            return None
+        return self._markers
+
+    def getmark(self, id):
+        for marker in self._markers:
+            if id == marker[0]:
+                return marker
+        raise Error, 'marker %r does not exist' % (id,)
+
+    def setpos(self, pos):
+        if pos < 0 or pos > self._nframes:
+            raise Error, 'position not in range'
+        self._soundpos = pos
+        self._ssnd_seek_needed = 1
+
+    def readframes(self, nframes):
+        if self._ssnd_seek_needed:
+            self._ssnd_chunk.seek(0)
+            dummy = self._ssnd_chunk.read(8)
+            pos = self._soundpos * self._framesize
+            if pos:
+                self._ssnd_chunk.seek(pos + 8)
+            self._ssnd_seek_needed = 0
+        if nframes == 0:
+            return ''
+        data = self._ssnd_chunk.read(nframes * self._framesize)
+        if self._convert and data:
+            data = self._convert(data)
+        self._soundpos = self._soundpos + len(data) / (self._nchannels * self._sampwidth)
+        return data
+
+    #
+    # Internal methods.
+    #
+
+    def _decomp_data(self, data):
+        import cl
+        dummy = self._decomp.SetParam(cl.FRAME_BUFFER_SIZE,
+                          len(data) * 2)
+        return self._decomp.Decompress(len(data) / self._nchannels,
+                           data)
+
+    def _ulaw2lin(self, data):
+        import audioop
+        return audioop.ulaw2lin(data, 2)
+
+    def _adpcm2lin(self, data):
+        import audioop
+        if not hasattr(self, '_adpcmstate'):
+            # first time
+            self._adpcmstate = None
+        data, self._adpcmstate = audioop.adpcm2lin(data, 2,
+                               self._adpcmstate)
+        return data
+
+    def _read_comm_chunk(self, chunk):
+        self._nchannels = _read_short(chunk)
+        self._nframes = _read_long(chunk)
+        self._sampwidth = (_read_short(chunk) + 7) / 8
+        self._framerate = int(_read_float(chunk))
+        self._framesize = self._nchannels * self._sampwidth
+        if self._aifc:
+            #DEBUG: SGI's soundeditor produces a bad size :-(
+            kludge = 0
+            if chunk.chunksize == 18:
+                kludge = 1
+                print 'Warning: bad COMM chunk size'
+                chunk.chunksize = 23
+            #DEBUG end
+            self._comptype = chunk.read(4)
+            #DEBUG start
+            if kludge:
+                length = ord(chunk.file.read(1))
+                if length & 1 == 0:
+                    length = length + 1
+                chunk.chunksize = chunk.chunksize + length
+                chunk.file.seek(-1, 1)
+            #DEBUG end
+            self._compname = _read_string(chunk)
+            if self._comptype != 'NONE':
+                if self._comptype == 'G722':
+                    try:
+                        import audioop
+                    except ImportError:
+                        pass
+                    else:
+                        self._convert = self._adpcm2lin
+                        self._framesize = self._framesize / 4
+                        return
+                # for ULAW and ALAW try Compression Library
+                try:
+                    import cl
+                except ImportError:
+                    if self._comptype == 'ULAW':
+                        try:
+                            import audioop
+                            self._convert = self._ulaw2lin
+                            self._framesize = self._framesize / 2
+                            return
+                        except ImportError:
+                            pass
+                    raise Error, 'cannot read compressed AIFF-C files'
+                if self._comptype == 'ULAW':
+                    scheme = cl.G711_ULAW
+                    self._framesize = self._framesize / 2
+                elif self._comptype == 'ALAW':
+                    scheme = cl.G711_ALAW
+                    self._framesize = self._framesize / 2
+                else:
+                    raise Error, 'unsupported compression type'
+                self._decomp = cl.OpenDecompressor(scheme)
+                self._convert = self._decomp_data
+        else:
+            self._comptype = 'NONE'
+            self._compname = 'not compressed'
+
+    def _readmark(self, chunk):
+        nmarkers = _read_short(chunk)
+        # Some files appear to contain invalid counts.
+        # Cope with this by testing for EOF.
+        try:
+            for i in range(nmarkers):
+                id = _read_short(chunk)
+                pos = _read_long(chunk)
+                name = _read_string(chunk)
+                if pos or name:
+                    # some files appear to have
+                    # dummy markers consisting of
+                    # a position 0 and name ''
+                    self._markers.append((id, pos, name))
+        except EOFError:
+            print 'Warning: MARK chunk contains only',
+            print len(self._markers),
+            if len(self._markers) == 1: print 'marker',
+            else: print 'markers',
+            print 'instead of', nmarkers
+
+class Aifc_write:
+    # Variables used in this class:
+    #
+    # These variables are user settable through appropriate methods
+    # of this class:
+    # _file -- the open file with methods write(), close(), tell(), seek()
+    #       set through the __init__() method
+    # _comptype -- the AIFF-C compression type ('NONE' in AIFF)
+    #       set through the setcomptype() or setparams() method
+    # _compname -- the human-readable AIFF-C compression type
+    #       set through the setcomptype() or setparams() method
+    # _nchannels -- the number of audio channels
+    #       set through the setnchannels() or setparams() method
+    # _sampwidth -- the number of bytes per audio sample
+    #       set through the setsampwidth() or setparams() method
+    # _framerate -- the sampling frequency
+    #       set through the setframerate() or setparams() method
+    # _nframes -- the number of audio frames written to the header
+    #       set through the setnframes() or setparams() method
+    # _aifc -- whether we're writing an AIFF-C file or an AIFF file
+    #       set through the aifc() method, reset through the
+    #       aiff() method
+    #
+    # These variables are used internally only:
+    # _version -- the AIFF-C version number
+    # _comp -- the compressor from builtin module cl
+    # _nframeswritten -- the number of audio frames actually written
+    # _datalength -- the size of the audio samples written to the header
+    # _datawritten -- the size of the audio samples actually written
+
+    def __init__(self, f):
+        if type(f) == type(''):
+            filename = f
+            f = __builtin__.open(f, 'wb')
+        else:
+            # else, assume it is an open file object already
+            filename = '???'
+        self.initfp(f)
+        if filename[-5:] == '.aiff':
+            self._aifc = 0
+        else:
+            self._aifc = 1
+
+    def initfp(self, file):
+        self._file = file
+        self._version = _AIFC_version
+        self._comptype = 'NONE'
+        self._compname = 'not compressed'
+        self._comp = None
+        self._convert = None
+        self._nchannels = 0
+        self._sampwidth = 0
+        self._framerate = 0
+        self._nframes = 0
+        self._nframeswritten = 0
+        self._datawritten = 0
+        self._datalength = 0
+        self._markers = []
+        self._marklength = 0
+        self._aifc = 1      # AIFF-C is default
+
+    def __del__(self):
+        if self._file:
+            self.close()
+
+    #
+    # User visible methods.
+    #
+    def aiff(self):
+        if self._nframeswritten:
+            raise Error, 'cannot change parameters after starting to write'
+        self._aifc = 0
+
+    def aifc(self):
+        if self._nframeswritten:
+            raise Error, 'cannot change parameters after starting to write'
+        self._aifc = 1
+
+    def setnchannels(self, nchannels):
+        if self._nframeswritten:
+            raise Error, 'cannot change parameters after starting to write'
+        if nchannels < 1:
+            raise Error, 'bad # of channels'
+        self._nchannels = nchannels
+
+    def getnchannels(self):
+        if not self._nchannels:
+            raise Error, 'number of channels not set'
+        return self._nchannels
+
+    def setsampwidth(self, sampwidth):
+        if self._nframeswritten:
+            raise Error, 'cannot change parameters after starting to write'
+        if sampwidth < 1 or sampwidth > 4:
+            raise Error, 'bad sample width'
+        self._sampwidth = sampwidth
+
+    def getsampwidth(self):
+        if not self._sampwidth:
+            raise Error, 'sample width not set'
+        return self._sampwidth
+
+    def setframerate(self, framerate):
+        if self._nframeswritten:
+            raise Error, 'cannot change parameters after starting to write'
+        if framerate <= 0:
+            raise Error, 'bad frame rate'
+        self._framerate = framerate
+
+    def getframerate(self):
+        if not self._framerate:
+            raise Error, 'frame rate not set'
+        return self._framerate
+
+    def setnframes(self, nframes):
+        if self._nframeswritten:
+            raise Error, 'cannot change parameters after starting to write'
+        self._nframes = nframes
+
+    def getnframes(self):
+        return self._nframeswritten
+
+    def setcomptype(self, comptype, compname):
+        if self._nframeswritten:
+            raise Error, 'cannot change parameters after starting to write'
+        if comptype not in ('NONE', 'ULAW', 'ALAW', 'G722'):
+            raise Error, 'unsupported compression type'
+        self._comptype = comptype
+        self._compname = compname
+
+    def getcomptype(self):
+        return self._comptype
+
+    def getcompname(self):
+        return self._compname
+
+##  def setversion(self, version):
+##      if self._nframeswritten:
+##          raise Error, 'cannot change parameters after starting to write'
+##      self._version = version
+
+    def setparams(self, (nchannels, sampwidth, framerate, nframes, comptype, compname)):
+        if self._nframeswritten:
+            raise Error, 'cannot change parameters after starting to write'
+        if comptype not in ('NONE', 'ULAW', 'ALAW', 'G722'):
+            raise Error, 'unsupported compression type'
+        self.setnchannels(nchannels)
+        self.setsampwidth(sampwidth)
+        self.setframerate(framerate)
+        self.setnframes(nframes)
+        self.setcomptype(comptype, compname)
+
+    def getparams(self):
+        if not self._nchannels or not self._sampwidth or not self._framerate:
+            raise Error, 'not all parameters set'
+        return self._nchannels, self._sampwidth, self._framerate, \
+              self._nframes, self._comptype, self._compname
+
+    def setmark(self, id, pos, name):
+        if id <= 0:
+            raise Error, 'marker ID must be > 0'
+        if pos < 0:
+            raise Error, 'marker position must be >= 0'
+        if type(name) != type(''):
+            raise Error, 'marker name must be a string'
+        for i in range(len(self._markers)):
+            if id == self._markers[i][0]:
+                self._markers[i] = id, pos, name
+                return
+        self._markers.append((id, pos, name))
+
+    def getmark(self, id):
+        for marker in self._markers:
+            if id == marker[0]:
+                return marker
+        raise Error, 'marker %r does not exist' % (id,)
+
+    def getmarkers(self):
+        if len(self._markers) == 0:
+            return None
+        return self._markers
+
+    def tell(self):
+        return self._nframeswritten
+
+    def writeframesraw(self, data):
+        self._ensure_header_written(len(data))
+        nframes = len(data) / (self._sampwidth * self._nchannels)
+        if self._convert:
+            data = self._convert(data)
+        self._file.write(data)
+        self._nframeswritten = self._nframeswritten + nframes
+        self._datawritten = self._datawritten + len(data)
+
+    def writeframes(self, data):
+        self.writeframesraw(data)
+        if self._nframeswritten != self._nframes or \
+              self._datalength != self._datawritten:
+            self._patchheader()
+
+    def close(self):
+        self._ensure_header_written(0)
+        if self._datawritten & 1:
+            # quick pad to even size
+            self._file.write(chr(0))
+            self._datawritten = self._datawritten + 1
+        self._writemarkers()
+        if self._nframeswritten != self._nframes or \
+              self._datalength != self._datawritten or \
+              self._marklength:
+            self._patchheader()
+        if self._comp:
+            self._comp.CloseCompressor()
+            self._comp = None
+        self._file.flush()
+        self._file = None
+
+    #
+    # Internal methods.
+    #
+
+    def _comp_data(self, data):
+        import cl
+        dummy = self._comp.SetParam(cl.FRAME_BUFFER_SIZE, len(data))
+        dummy = self._comp.SetParam(cl.COMPRESSED_BUFFER_SIZE, len(data))
+        return self._comp.Compress(self._nframes, data)
+
+    def _lin2ulaw(self, data):
+        import audioop
+        return audioop.lin2ulaw(data, 2)
+
+    def _lin2adpcm(self, data):
+        import audioop
+        if not hasattr(self, '_adpcmstate'):
+            self._adpcmstate = None
+        data, self._adpcmstate = audioop.lin2adpcm(data, 2,
+                               self._adpcmstate)
+        return data
+
+    def _ensure_header_written(self, datasize):
+        if not self._nframeswritten:
+            if self._comptype in ('ULAW', 'ALAW'):
+                if not self._sampwidth:
+                    self._sampwidth = 2
+                if self._sampwidth != 2:
+                    raise Error, 'sample width must be 2 when compressing with ULAW or ALAW'
+            if self._comptype == 'G722':
+                if not self._sampwidth:
+                    self._sampwidth = 2
+                if self._sampwidth != 2:
+                    raise Error, 'sample width must be 2 when compressing with G7.22 (ADPCM)'
+            if not self._nchannels:
+                raise Error, '# channels not specified'
+            if not self._sampwidth:
+                raise Error, 'sample width not specified'
+            if not self._framerate:
+                raise Error, 'sampling rate not specified'
+            self._write_header(datasize)
+
+    def _init_compression(self):
+        if self._comptype == 'G722':
+            self._convert = self._lin2adpcm
+            return
+        try:
+            import cl
+        except ImportError:
+            if self._comptype == 'ULAW':
+                try:
+                    import audioop
+                    self._convert = self._lin2ulaw
+                    return
+                except ImportError:
+                    pass
+            raise Error, 'cannot write compressed AIFF-C files'
+        if self._comptype == 'ULAW':
+            scheme = cl.G711_ULAW
+        elif self._comptype == 'ALAW':
+            scheme = cl.G711_ALAW
+        else:
+            raise Error, 'unsupported compression type'
+        self._comp = cl.OpenCompressor(scheme)
+        params = [cl.ORIGINAL_FORMAT, 0,
+              cl.BITS_PER_COMPONENT, self._sampwidth * 8,
+              cl.FRAME_RATE, self._framerate,
+              cl.FRAME_BUFFER_SIZE, 100,
+              cl.COMPRESSED_BUFFER_SIZE, 100]
+        if self._nchannels == 1:
+            params[1] = cl.MONO
+        elif self._nchannels == 2:
+            params[1] = cl.STEREO_INTERLEAVED
+        else:
+            raise Error, 'cannot compress more than 2 channels'
+        self._comp.SetParams(params)
+        # the compressor produces a header which we ignore
+        dummy = self._comp.Compress(0, '')
+        self._convert = self._comp_data
+
+    def _write_header(self, initlength):
+        if self._aifc and self._comptype != 'NONE':
+            self._init_compression()
+        self._file.write('FORM')
+        if not self._nframes:
+            self._nframes = initlength / (self._nchannels * self._sampwidth)
+        self._datalength = self._nframes * self._nchannels * self._sampwidth
+        if self._datalength & 1:
+            self._datalength = self._datalength + 1
+        if self._aifc:
+            if self._comptype in ('ULAW', 'ALAW'):
+                self._datalength = self._datalength / 2
+                if self._datalength & 1:
+                    self._datalength = self._datalength + 1
+            elif self._comptype == 'G722':
+                self._datalength = (self._datalength + 3) / 4
+                if self._datalength & 1:
+                    self._datalength = self._datalength + 1
+        self._form_length_pos = self._file.tell()
+        commlength = self._write_form_length(self._datalength)
+        if self._aifc:
+            self._file.write('AIFC')
+            self._file.write('FVER')
+            _write_long(self._file, 4)
+            _write_long(self._file, self._version)
+        else:
+            self._file.write('AIFF')
+        self._file.write('COMM')
+        _write_long(self._file, commlength)
+        _write_short(self._file, self._nchannels)
+        self._nframes_pos = self._file.tell()
+        _write_long(self._file, self._nframes)
+        _write_short(self._file, self._sampwidth * 8)
+        _write_float(self._file, self._framerate)
+        if self._aifc:
+            self._file.write(self._comptype)
+            _write_string(self._file, self._compname)
+        self._file.write('SSND')
+        self._ssnd_length_pos = self._file.tell()
+        _write_long(self._file, self._datalength + 8)
+        _write_long(self._file, 0)
+        _write_long(self._file, 0)
+
+    def _write_form_length(self, datalength):
+        if self._aifc:
+            commlength = 18 + 5 + len(self._compname)
+            if commlength & 1:
+                commlength = commlength + 1
+            verslength = 12
+        else:
+            commlength = 18
+            verslength = 0
+        _write_long(self._file, 4 + verslength + self._marklength + \
+                    8 + commlength + 16 + datalength)
+        return commlength
+
+    def _patchheader(self):
+        curpos = self._file.tell()
+        if self._datawritten & 1:
+            datalength = self._datawritten + 1
+            self._file.write(chr(0))
+        else:
+            datalength = self._datawritten
+        if datalength == self._datalength and \
+              self._nframes == self._nframeswritten and \
+              self._marklength == 0:
+            self._file.seek(curpos, 0)
+            return
+        self._file.seek(self._form_length_pos, 0)
+        dummy = self._write_form_length(datalength)
+        self._file.seek(self._nframes_pos, 0)
+        _write_long(self._file, self._nframeswritten)
+        self._file.seek(self._ssnd_length_pos, 0)
+        _write_long(self._file, datalength + 8)
+        self._file.seek(curpos, 0)
+        self._nframes = self._nframeswritten
+        self._datalength = datalength
+
+    def _writemarkers(self):
+        if len(self._markers) == 0:
+            return
+        self._file.write('MARK')
+        length = 2
+        for marker in self._markers:
+            id, pos, name = marker
+            length = length + len(name) + 1 + 6
+            if len(name) & 1 == 0:
+                length = length + 1
+        _write_long(self._file, length)
+        self._marklength = length + 8
+        _write_short(self._file, len(self._markers))
+        for marker in self._markers:
+            id, pos, name = marker
+            _write_short(self._file, id)
+            _write_long(self._file, pos)
+            _write_string(self._file, name)
+
+def open(f, mode=None):
+    if mode is None:
+        if hasattr(f, 'mode'):
+            mode = f.mode
+        else:
+            mode = 'rb'
+    if mode in ('r', 'rb'):
+        return Aifc_read(f)
+    elif mode in ('w', 'wb'):
+        return Aifc_write(f)
+    else:
+        raise Error, "mode must be 'r', 'rb', 'w', or 'wb'"
+
+openfp = open # B/W compatibility
+
+if __name__ == '__main__':
+    import sys
+    if not sys.argv[1:]:
+        sys.argv.append('/usr/demos/data/audio/bach.aiff')
+    fn = sys.argv[1]
+    f = open(fn, 'r')
+    print "Reading", fn
+    print "nchannels =", f.getnchannels()
+    print "nframes   =", f.getnframes()
+    print "sampwidth =", f.getsampwidth()
+    print "framerate =", f.getframerate()
+    print "comptype  =", f.getcomptype()
+    print "compname  =", f.getcompname()
+    if sys.argv[2:]:
+        gn = sys.argv[2]
+        print "Writing", gn
+        g = open(gn, 'w')
+        g.setparams(f.getparams())
+        while 1:
+            data = f.readframes(1024)
+            if not data:
+                break
+            g.writeframes(data)
+        g.close()
+        f.close()
+        print "Done."

Added: vendor/Python/current/Lib/anydbm.py
===================================================================
--- vendor/Python/current/Lib/anydbm.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/anydbm.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,83 @@
+"""Generic interface to all dbm clones.
+
+Instead of
+
+        import dbm
+        d = dbm.open(file, 'w', 0666)
+
+use
+
+        import anydbm
+        d = anydbm.open(file, 'w')
+
+The returned object is a dbhash, gdbm, dbm or dumbdbm object,
+dependent on the type of database being opened (determined by whichdb
+module) in the case of an existing dbm. If the dbm does not exist and
+the create or new flag ('c' or 'n') was specified, the dbm type will
+be determined by the availability of the modules (tested in the above
+order).
+
+It has the following interface (key and data are strings):
+
+        d[key] = data   # store data at key (may override data at
+                        # existing key)
+        data = d[key]   # retrieve data at key (raise KeyError if no
+                        # such key)
+        del d[key]      # delete data stored at key (raises KeyError
+                        # if no such key)
+        flag = key in d   # true if the key exists
+        list = d.keys() # return a list of all existing keys (slow!)
+
+Future versions may change the order in which implementations are
+tested for existence, add interfaces to other dbm-like
+implementations.
+
+The open function has an optional second argument.  This can be 'r',
+for read-only access, 'w', for read-write access of an existing
+database, 'c' for read-write access to a new or existing database, and
+'n' for read-write access to a new database.  The default is 'r'.
+
+Note: 'r' and 'w' fail if the database doesn't exist; 'c' creates it
+only if it doesn't exist; and 'n' always creates a new database.
+
+"""
+
+class error(Exception):
+    pass
+
+_names = ['dbhash', 'gdbm', 'dbm', 'dumbdbm']
+_errors = [error]
+_defaultmod = None
+
+for _name in _names:
+    try:
+        _mod = __import__(_name)
+    except ImportError:
+        continue
+    if not _defaultmod:
+        _defaultmod = _mod
+    _errors.append(_mod.error)
+
+if not _defaultmod:
+    raise ImportError, "no dbm clone found; tried %s" % _names
+
+error = tuple(_errors)
+
+def open(file, flag = 'r', mode = 0666):
+    # guess the type of an existing database
+    from whichdb import whichdb
+    result=whichdb(file)
+    if result is None:
+        # db doesn't exist
+        if 'c' in flag or 'n' in flag:
+            # file doesn't exist and the new
+            # flag was used so use default type
+            mod = _defaultmod
+        else:
+            raise error, "need 'c' or 'n' flag to open new db"
+    elif result == "":
+        # db type cannot be determined
+        raise error, "db type could not be determined"
+    else:
+        mod = __import__(result)
+    return mod.open(file, flag, mode)

Added: vendor/Python/current/Lib/asynchat.py
===================================================================
--- vendor/Python/current/Lib/asynchat.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/asynchat.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,295 @@
+# -*- Mode: Python; tab-width: 4 -*-
+#       Id: asynchat.py,v 2.26 2000/09/07 22:29:26 rushing Exp
+#       Author: Sam Rushing <rushing at nightmare.com>
+
+# ======================================================================
+# Copyright 1996 by Sam Rushing
+#
+#                         All Rights Reserved
+#
+# Permission to use, copy, modify, and distribute this software and
+# its documentation for any purpose and without fee is hereby
+# granted, provided that the above copyright notice appear in all
+# copies and that both that copyright notice and this permission
+# notice appear in supporting documentation, and that the name of Sam
+# Rushing not be used in advertising or publicity pertaining to
+# distribution of the software without specific, written prior
+# permission.
+#
+# SAM RUSHING DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+# NO EVENT SHALL SAM RUSHING BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+# OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+# ======================================================================
+
+r"""A class supporting chat-style (command/response) protocols.
+
+This class adds support for 'chat' style protocols - where one side
+sends a 'command', and the other sends a response (examples would be
+the common internet protocols - smtp, nntp, ftp, etc..).
+
+The handle_read() method looks at the input stream for the current
+'terminator' (usually '\r\n' for single-line responses, '\r\n.\r\n'
+for multi-line output), calling self.found_terminator() on its
+receipt.
+
+for example:
+Say you build an async nntp client using this class.  At the start
+of the connection, you'll have self.terminator set to '\r\n', in
+order to process the single-line greeting.  Just before issuing a
+'LIST' command you'll set it to '\r\n.\r\n'.  The output of the LIST
+command will be accumulated (using your own 'collect_incoming_data'
+method) up to the terminator, and then control will be returned to
+you - by calling your self.found_terminator() method.
+"""
+
+import socket
+import asyncore
+from collections import deque
+
+class async_chat (asyncore.dispatcher):
+    """This is an abstract class.  You must derive from this class, and add
+    the two methods collect_incoming_data() and found_terminator()"""
+
+    # these are overridable defaults
+
+    ac_in_buffer_size       = 4096
+    ac_out_buffer_size      = 4096
+
+    def __init__ (self, conn=None):
+        self.ac_in_buffer = ''
+        self.ac_out_buffer = ''
+        self.producer_fifo = fifo()
+        asyncore.dispatcher.__init__ (self, conn)
+
+    def collect_incoming_data(self, data):
+        raise NotImplementedError, "must be implemented in subclass"
+
+    def found_terminator(self):
+        raise NotImplementedError, "must be implemented in subclass"
+
+    def set_terminator (self, term):
+        "Set the input delimiter.  Can be a fixed string of any length, an integer, or None"
+        self.terminator = term
+
+    def get_terminator (self):
+        return self.terminator
+
+    # grab some more data from the socket,
+    # throw it to the collector method,
+    # check for the terminator,
+    # if found, transition to the next state.
+
+    def handle_read (self):
+
+        try:
+            data = self.recv (self.ac_in_buffer_size)
+        except socket.error, why:
+            self.handle_error()
+            return
+
+        self.ac_in_buffer = self.ac_in_buffer + data
+
+        # Continue to search for self.terminator in self.ac_in_buffer,
+        # while calling self.collect_incoming_data.  The while loop
+        # is necessary because we might read several data+terminator
+        # combos with a single recv(1024).
+
+        while self.ac_in_buffer:
+            lb = len(self.ac_in_buffer)
+            terminator = self.get_terminator()
+            if not terminator:
+                # no terminator, collect it all
+                self.collect_incoming_data (self.ac_in_buffer)
+                self.ac_in_buffer = ''
+            elif isinstance(terminator, int) or isinstance(terminator, long):
+                # numeric terminator
+                n = terminator
+                if lb < n:
+                    self.collect_incoming_data (self.ac_in_buffer)
+                    self.ac_in_buffer = ''
+                    self.terminator = self.terminator - lb
+                else:
+                    self.collect_incoming_data (self.ac_in_buffer[:n])
+                    self.ac_in_buffer = self.ac_in_buffer[n:]
+                    self.terminator = 0
+                    self.found_terminator()
+            else:
+                # 3 cases:
+                # 1) end of buffer matches terminator exactly:
+                #    collect data, transition
+                # 2) end of buffer matches some prefix:
+                #    collect data to the prefix
+                # 3) end of buffer does not match any prefix:
+                #    collect data
+                terminator_len = len(terminator)
+                index = self.ac_in_buffer.find(terminator)
+                if index != -1:
+                    # we found the terminator
+                    if index > 0:
+                        # don't bother reporting the empty string (source of subtle bugs)
+                        self.collect_incoming_data (self.ac_in_buffer[:index])
+                    self.ac_in_buffer = self.ac_in_buffer[index+terminator_len:]
+                    # This does the Right Thing if the terminator is changed here.
+                    self.found_terminator()
+                else:
+                    # check for a prefix of the terminator
+                    index = find_prefix_at_end (self.ac_in_buffer, terminator)
+                    if index:
+                        if index != lb:
+                            # we found a prefix, collect up to the prefix
+                            self.collect_incoming_data (self.ac_in_buffer[:-index])
+                            self.ac_in_buffer = self.ac_in_buffer[-index:]
+                        break
+                    else:
+                        # no prefix, collect it all
+                        self.collect_incoming_data (self.ac_in_buffer)
+                        self.ac_in_buffer = ''
+
+    def handle_write (self):
+        self.initiate_send ()
+
+    def handle_close (self):
+        self.close()
+
+    def push (self, data):
+        self.producer_fifo.push (simple_producer (data))
+        self.initiate_send()
+
+    def push_with_producer (self, producer):
+        self.producer_fifo.push (producer)
+        self.initiate_send()
+
+    def readable (self):
+        "predicate for inclusion in the readable for select()"
+        return (len(self.ac_in_buffer) <= self.ac_in_buffer_size)
+
+    def writable (self):
+        "predicate for inclusion in the writable for select()"
+        # return len(self.ac_out_buffer) or len(self.producer_fifo) or (not self.connected)
+        # this is about twice as fast, though not as clear.
+        return not (
+                (self.ac_out_buffer == '') and
+                self.producer_fifo.is_empty() and
+                self.connected
+                )
+
+    def close_when_done (self):
+        "automatically close this channel once the outgoing queue is empty"
+        self.producer_fifo.push (None)
+
+    # refill the outgoing buffer by calling the more() method
+    # of the first producer in the queue
+    def refill_buffer (self):
+        while 1:
+            if len(self.producer_fifo):
+                p = self.producer_fifo.first()
+                # a 'None' in the producer fifo is a sentinel,
+                # telling us to close the channel.
+                if p is None:
+                    if not self.ac_out_buffer:
+                        self.producer_fifo.pop()
+                        self.close()
+                    return
+                elif isinstance(p, str):
+                    self.producer_fifo.pop()
+                    self.ac_out_buffer = self.ac_out_buffer + p
+                    return
+                data = p.more()
+                if data:
+                    self.ac_out_buffer = self.ac_out_buffer + data
+                    return
+                else:
+                    self.producer_fifo.pop()
+            else:
+                return
+
+    def initiate_send (self):
+        obs = self.ac_out_buffer_size
+        # try to refill the buffer
+        if (len (self.ac_out_buffer) < obs):
+            self.refill_buffer()
+
+        if self.ac_out_buffer and self.connected:
+            # try to send the buffer
+            try:
+                num_sent = self.send (self.ac_out_buffer[:obs])
+                if num_sent:
+                    self.ac_out_buffer = self.ac_out_buffer[num_sent:]
+
+            except socket.error, why:
+                self.handle_error()
+                return
+
+    def discard_buffers (self):
+        # Emergencies only!
+        self.ac_in_buffer = ''
+        self.ac_out_buffer = ''
+        while self.producer_fifo:
+            self.producer_fifo.pop()
+
+
+class simple_producer:
+
+    def __init__ (self, data, buffer_size=512):
+        self.data = data
+        self.buffer_size = buffer_size
+
+    def more (self):
+        if len (self.data) > self.buffer_size:
+            result = self.data[:self.buffer_size]
+            self.data = self.data[self.buffer_size:]
+            return result
+        else:
+            result = self.data
+            self.data = ''
+            return result
+
+class fifo:
+    def __init__ (self, list=None):
+        if not list:
+            self.list = deque()
+        else:
+            self.list = deque(list)
+
+    def __len__ (self):
+        return len(self.list)
+
+    def is_empty (self):
+        return not self.list
+
+    def first (self):
+        return self.list[0]
+
+    def push (self, data):
+        self.list.append(data)
+
+    def pop (self):
+        if self.list:
+            return (1, self.list.popleft())
+        else:
+            return (0, None)
+
+# Given 'haystack', see if any prefix of 'needle' is at its end.  This
+# assumes an exact match has already been checked.  Return the number of
+# characters matched.
+# for example:
+# f_p_a_e ("qwerty\r", "\r\n") => 1
+# f_p_a_e ("qwertydkjf", "\r\n") => 0
+# f_p_a_e ("qwerty\r\n", "\r\n") => <undefined>
+
+# this could maybe be made faster with a computed regex?
+# [answer: no; circa Python-2.0, Jan 2001]
+# new python:   28961/s
+# old python:   18307/s
+# re:        12820/s
+# regex:     14035/s
+
+def find_prefix_at_end (haystack, needle):
+    l = len(needle) - 1
+    while l and not haystack.endswith(needle[:l]):
+        l -= 1
+    return l

Added: vendor/Python/current/Lib/asyncore.py
===================================================================
--- vendor/Python/current/Lib/asyncore.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/asyncore.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,551 @@
+# -*- Mode: Python -*-
+#   Id: asyncore.py,v 2.51 2000/09/07 22:29:26 rushing Exp
+#   Author: Sam Rushing <rushing at nightmare.com>
+
+# ======================================================================
+# Copyright 1996 by Sam Rushing
+#
+#                         All Rights Reserved
+#
+# Permission to use, copy, modify, and distribute this software and
+# its documentation for any purpose and without fee is hereby
+# granted, provided that the above copyright notice appear in all
+# copies and that both that copyright notice and this permission
+# notice appear in supporting documentation, and that the name of Sam
+# Rushing not be used in advertising or publicity pertaining to
+# distribution of the software without specific, written prior
+# permission.
+#
+# SAM RUSHING DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+# NO EVENT SHALL SAM RUSHING BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+# OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+# ======================================================================
+
+"""Basic infrastructure for asynchronous socket service clients and servers.
+
+There are only two ways to have a program on a single processor do "more
+than one thing at a time".  Multi-threaded programming is the simplest and
+most popular way to do it, but there is another very different technique,
+that lets you have nearly all the advantages of multi-threading, without
+actually using multiple threads. it's really only practical if your program
+is largely I/O bound. If your program is CPU bound, then pre-emptive
+scheduled threads are probably what you really need. Network servers are
+rarely CPU-bound, however.
+
+If your operating system supports the select() system call in its I/O
+library (and nearly all do), then you can use it to juggle multiple
+communication channels at once; doing other work while your I/O is taking
+place in the "background."  Although this strategy can seem strange and
+complex, especially at first, it is in many ways easier to understand and
+control than multi-threaded programming. The module documented here solves
+many of the difficult problems for you, making the task of building
+sophisticated high-performance network servers and clients a snap.
+"""
+
+import select
+import socket
+import sys
+import time
+
+import os
+from errno import EALREADY, EINPROGRESS, EWOULDBLOCK, ECONNRESET, \
+     ENOTCONN, ESHUTDOWN, EINTR, EISCONN, errorcode
+
+try:
+    socket_map
+except NameError:
+    socket_map = {}
+
+class ExitNow(Exception):
+    pass
+
+def read(obj):
+    try:
+        obj.handle_read_event()
+    except ExitNow:
+        raise
+    except:
+        obj.handle_error()
+
+def write(obj):
+    try:
+        obj.handle_write_event()
+    except ExitNow:
+        raise
+    except:
+        obj.handle_error()
+
+def _exception (obj):
+    try:
+        obj.handle_expt_event()
+    except ExitNow:
+        raise
+    except:
+        obj.handle_error()
+
+def readwrite(obj, flags):
+    try:
+        if flags & (select.POLLIN | select.POLLPRI):
+            obj.handle_read_event()
+        if flags & select.POLLOUT:
+            obj.handle_write_event()
+        if flags & (select.POLLERR | select.POLLHUP | select.POLLNVAL):
+            obj.handle_expt_event()
+    except ExitNow:
+        raise
+    except:
+        obj.handle_error()
+
+def poll(timeout=0.0, map=None):
+    if map is None:
+        map = socket_map
+    if map:
+        r = []; w = []; e = []
+        for fd, obj in map.items():
+            is_r = obj.readable()
+            is_w = obj.writable()
+            if is_r:
+                r.append(fd)
+            if is_w:
+                w.append(fd)
+            if is_r or is_w:
+                e.append(fd)
+        if [] == r == w == e:
+            time.sleep(timeout)
+        else:
+            try:
+                r, w, e = select.select(r, w, e, timeout)
+            except select.error, err:
+                if err[0] != EINTR:
+                    raise
+                else:
+                    return
+
+        for fd in r:
+            obj = map.get(fd)
+            if obj is None:
+                continue
+            read(obj)
+
+        for fd in w:
+            obj = map.get(fd)
+            if obj is None:
+                continue
+            write(obj)
+
+        for fd in e:
+            obj = map.get(fd)
+            if obj is None:
+                continue
+            _exception(obj)
+
+def poll2(timeout=0.0, map=None):
+    # Use the poll() support added to the select module in Python 2.0
+    if map is None:
+        map = socket_map
+    if timeout is not None:
+        # timeout is in milliseconds
+        timeout = int(timeout*1000)
+    pollster = select.poll()
+    if map:
+        for fd, obj in map.items():
+            flags = 0
+            if obj.readable():
+                flags |= select.POLLIN | select.POLLPRI
+            if obj.writable():
+                flags |= select.POLLOUT
+            if flags:
+                # Only check for exceptions if object was either readable
+                # or writable.
+                flags |= select.POLLERR | select.POLLHUP | select.POLLNVAL
+                pollster.register(fd, flags)
+        try:
+            r = pollster.poll(timeout)
+        except select.error, err:
+            if err[0] != EINTR:
+                raise
+            r = []
+        for fd, flags in r:
+            obj = map.get(fd)
+            if obj is None:
+                continue
+            readwrite(obj, flags)
+
+poll3 = poll2                           # Alias for backward compatibility
+
+def loop(timeout=30.0, use_poll=False, map=None, count=None):
+    if map is None:
+        map = socket_map
+
+    if use_poll and hasattr(select, 'poll'):
+        poll_fun = poll2
+    else:
+        poll_fun = poll
+
+    if count is None:
+        while map:
+            poll_fun(timeout, map)
+
+    else:
+        while map and count > 0:
+            poll_fun(timeout, map)
+            count = count - 1
+
+class dispatcher:
+
+    debug = False
+    connected = False
+    accepting = False
+    closing = False
+    addr = None
+
+    def __init__(self, sock=None, map=None):
+        if map is None:
+            self._map = socket_map
+        else:
+            self._map = map
+
+        if sock:
+            self.set_socket(sock, map)
+            # I think it should inherit this anyway
+            self.socket.setblocking(0)
+            self.connected = True
+            # XXX Does the constructor require that the socket passed
+            # be connected?
+            try:
+                self.addr = sock.getpeername()
+            except socket.error:
+                # The addr isn't crucial
+                pass
+        else:
+            self.socket = None
+
+    def __repr__(self):
+        status = [self.__class__.__module__+"."+self.__class__.__name__]
+        if self.accepting and self.addr:
+            status.append('listening')
+        elif self.connected:
+            status.append('connected')
+        if self.addr is not None:
+            try:
+                status.append('%s:%d' % self.addr)
+            except TypeError:
+                status.append(repr(self.addr))
+        return '<%s at %#x>' % (' '.join(status), id(self))
+
+    def add_channel(self, map=None):
+        #self.log_info('adding channel %s' % self)
+        if map is None:
+            map = self._map
+        map[self._fileno] = self
+
+    def del_channel(self, map=None):
+        fd = self._fileno
+        if map is None:
+            map = self._map
+        if map.has_key(fd):
+            #self.log_info('closing channel %d:%s' % (fd, self))
+            del map[fd]
+        self._fileno = None
+
+    def create_socket(self, family, type):
+        self.family_and_type = family, type
+        self.socket = socket.socket(family, type)
+        self.socket.setblocking(0)
+        self._fileno = self.socket.fileno()
+        self.add_channel()
+
+    def set_socket(self, sock, map=None):
+        self.socket = sock
+##        self.__dict__['socket'] = sock
+        self._fileno = sock.fileno()
+        self.add_channel(map)
+
+    def set_reuse_addr(self):
+        # try to re-use a server port if possible
+        try:
+            self.socket.setsockopt(
+                socket.SOL_SOCKET, socket.SO_REUSEADDR,
+                self.socket.getsockopt(socket.SOL_SOCKET,
+                                       socket.SO_REUSEADDR) | 1
+                )
+        except socket.error:
+            pass
+
+    # ==================================================
+    # predicates for select()
+    # these are used as filters for the lists of sockets
+    # to pass to select().
+    # ==================================================
+
+    def readable(self):
+        return True
+
+    def writable(self):
+        return True
+
+    # ==================================================
+    # socket object methods.
+    # ==================================================
+
+    def listen(self, num):
+        self.accepting = True
+        if os.name == 'nt' and num > 5:
+            num = 1
+        return self.socket.listen(num)
+
+    def bind(self, addr):
+        self.addr = addr
+        return self.socket.bind(addr)
+
+    def connect(self, address):
+        self.connected = False
+        err = self.socket.connect_ex(address)
+        # XXX Should interpret Winsock return values
+        if err in (EINPROGRESS, EALREADY, EWOULDBLOCK):
+            return
+        if err in (0, EISCONN):
+            self.addr = address
+            self.connected = True
+            self.handle_connect()
+        else:
+            raise socket.error, (err, errorcode[err])
+
+    def accept(self):
+        # XXX can return either an address pair or None
+        try:
+            conn, addr = self.socket.accept()
+            return conn, addr
+        except socket.error, why:
+            if why[0] == EWOULDBLOCK:
+                pass
+            else:
+                raise
+
+    def send(self, data):
+        try:
+            result = self.socket.send(data)
+            return result
+        except socket.error, why:
+            if why[0] == EWOULDBLOCK:
+                return 0
+            else:
+                raise
+            return 0
+
+    def recv(self, buffer_size):
+        try:
+            data = self.socket.recv(buffer_size)
+            if not data:
+                # a closed connection is indicated by signaling
+                # a read condition, and having recv() return 0.
+                self.handle_close()
+                return ''
+            else:
+                return data
+        except socket.error, why:
+            # winsock sometimes throws ENOTCONN
+            if why[0] in [ECONNRESET, ENOTCONN, ESHUTDOWN]:
+                self.handle_close()
+                return ''
+            else:
+                raise
+
+    def close(self):
+        self.del_channel()
+        self.socket.close()
+
+    # cheap inheritance, used to pass all other attribute
+    # references to the underlying socket object.
+    def __getattr__(self, attr):
+        return getattr(self.socket, attr)
+
+    # log and log_info may be overridden to provide more sophisticated
+    # logging and warning methods. In general, log is for 'hit' logging
+    # and 'log_info' is for informational, warning and error logging.
+
+    def log(self, message):
+        sys.stderr.write('log: %s\n' % str(message))
+
+    def log_info(self, message, type='info'):
+        if __debug__ or type != 'info':
+            print '%s: %s' % (type, message)
+
+    def handle_read_event(self):
+        if self.accepting:
+            # for an accepting socket, getting a read implies
+            # that we are connected
+            if not self.connected:
+                self.connected = True
+            self.handle_accept()
+        elif not self.connected:
+            self.handle_connect()
+            self.connected = True
+            self.handle_read()
+        else:
+            self.handle_read()
+
+    def handle_write_event(self):
+        # getting a write implies that we are connected
+        if not self.connected:
+            self.handle_connect()
+            self.connected = True
+        self.handle_write()
+
+    def handle_expt_event(self):
+        self.handle_expt()
+
+    def handle_error(self):
+        nil, t, v, tbinfo = compact_traceback()
+
+        # sometimes a user repr method will crash.
+        try:
+            self_repr = repr(self)
+        except:
+            self_repr = '<__repr__(self) failed for object at %0x>' % id(self)
+
+        self.log_info(
+            'uncaptured python exception, closing channel %s (%s:%s %s)' % (
+                self_repr,
+                t,
+                v,
+                tbinfo
+                ),
+            'error'
+            )
+        self.close()
+
+    def handle_expt(self):
+        self.log_info('unhandled exception', 'warning')
+
+    def handle_read(self):
+        self.log_info('unhandled read event', 'warning')
+
+    def handle_write(self):
+        self.log_info('unhandled write event', 'warning')
+
+    def handle_connect(self):
+        self.log_info('unhandled connect event', 'warning')
+
+    def handle_accept(self):
+        self.log_info('unhandled accept event', 'warning')
+
+    def handle_close(self):
+        self.log_info('unhandled close event', 'warning')
+        self.close()
+
+# ---------------------------------------------------------------------------
+# adds simple buffered output capability, useful for simple clients.
+# [for more sophisticated usage use asynchat.async_chat]
+# ---------------------------------------------------------------------------
+
+class dispatcher_with_send(dispatcher):
+
+    def __init__(self, sock=None, map=None):
+        dispatcher.__init__(self, sock, map)
+        self.out_buffer = ''
+
+    def initiate_send(self):
+        num_sent = 0
+        num_sent = dispatcher.send(self, self.out_buffer[:512])
+        self.out_buffer = self.out_buffer[num_sent:]
+
+    def handle_write(self):
+        self.initiate_send()
+
+    def writable(self):
+        return (not self.connected) or len(self.out_buffer)
+
+    def send(self, data):
+        if self.debug:
+            self.log_info('sending %s' % repr(data))
+        self.out_buffer = self.out_buffer + data
+        self.initiate_send()
+
+# ---------------------------------------------------------------------------
+# used for debugging.
+# ---------------------------------------------------------------------------
+
+def compact_traceback():
+    t, v, tb = sys.exc_info()
+    tbinfo = []
+    assert tb # Must have a traceback
+    while tb:
+        tbinfo.append((
+            tb.tb_frame.f_code.co_filename,
+            tb.tb_frame.f_code.co_name,
+            str(tb.tb_lineno)
+            ))
+        tb = tb.tb_next
+
+    # just to be safe
+    del tb
+
+    file, function, line = tbinfo[-1]
+    info = ' '.join(['[%s|%s|%s]' % x for x in tbinfo])
+    return (file, function, line), t, v, info
+
+def close_all(map=None):
+    if map is None:
+        map = socket_map
+    for x in map.values():
+        x.socket.close()
+    map.clear()
+
+# Asynchronous File I/O:
+#
+# After a little research (reading man pages on various unixen, and
+# digging through the linux kernel), I've determined that select()
+# isn't meant for doing asynchronous file i/o.
+# Heartening, though - reading linux/mm/filemap.c shows that linux
+# supports asynchronous read-ahead.  So _MOST_ of the time, the data
+# will be sitting in memory for us already when we go to read it.
+#
+# What other OS's (besides NT) support async file i/o?  [VMS?]
+#
+# Regardless, this is useful for pipes, and stdin/stdout...
+
+if os.name == 'posix':
+    import fcntl
+
+    class file_wrapper:
+        # here we override just enough to make a file
+        # look like a socket for the purposes of asyncore.
+
+        def __init__(self, fd):
+            self.fd = fd
+
+        def recv(self, *args):
+            return os.read(self.fd, *args)
+
+        def send(self, *args):
+            return os.write(self.fd, *args)
+
+        read = recv
+        write = send
+
+        def close(self):
+            os.close(self.fd)
+
+        def fileno(self):
+            return self.fd
+
+    class file_dispatcher(dispatcher):
+
+        def __init__(self, fd, map=None):
+            dispatcher.__init__(self, None, map)
+            self.connected = True
+            self.set_file(fd)
+            # set it to non-blocking mode
+            flags = fcntl.fcntl(fd, fcntl.F_GETFL, 0)
+            flags = flags | os.O_NONBLOCK
+            fcntl.fcntl(fd, fcntl.F_SETFL, flags)
+
+        def set_file(self, fd):
+            self._fileno = fd
+            self.socket = file_wrapper(fd)
+            self.add_channel()

Added: vendor/Python/current/Lib/atexit.py
===================================================================
--- vendor/Python/current/Lib/atexit.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/atexit.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,62 @@
+"""
+atexit.py - allow programmer to define multiple exit functions to be executed
+upon normal program termination.
+
+One public function, register, is defined.
+"""
+
+__all__ = ["register"]
+
+import sys
+
+_exithandlers = []
+def _run_exitfuncs():
+    """run any registered exit functions
+
+    _exithandlers is traversed in reverse order so functions are executed
+    last in, first out.
+    """
+
+    exc_info = None
+    while _exithandlers:
+        func, targs, kargs = _exithandlers.pop()
+        try:
+            func(*targs, **kargs)
+        except SystemExit:
+            exc_info = sys.exc_info()
+        except:
+            import traceback
+            print >> sys.stderr, "Error in atexit._run_exitfuncs:"
+            traceback.print_exc()
+            exc_info = sys.exc_info()
+
+    if exc_info is not None:
+        raise exc_info[0], exc_info[1], exc_info[2]
+
+
+def register(func, *targs, **kargs):
+    """register a function to be executed upon normal program termination
+
+    func - function to be called at exit
+    targs - optional arguments to pass to func
+    kargs - optional keyword arguments to pass to func
+    """
+    _exithandlers.append((func, targs, kargs))
+
+if hasattr(sys, "exitfunc"):
+    # Assume it's another registered exit function - append it to our list
+    register(sys.exitfunc)
+sys.exitfunc = _run_exitfuncs
+
+if __name__ == "__main__":
+    def x1():
+        print "running x1"
+    def x2(n):
+        print "running x2(%r)" % (n,)
+    def x3(n, kwd=None):
+        print "running x3(%r, kwd=%r)" % (n, kwd)
+
+    register(x1)
+    register(x2, 12)
+    register(x3, 5, "bar")
+    register(x3, "no kwd args")

Added: vendor/Python/current/Lib/audiodev.py
===================================================================
--- vendor/Python/current/Lib/audiodev.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/audiodev.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,257 @@
+"""Classes for manipulating audio devices (currently only for Sun and SGI)"""
+
+__all__ = ["error","AudioDev"]
+
+class error(Exception):
+    pass
+
+class Play_Audio_sgi:
+    # Private instance variables
+##      if 0: access frameratelist, nchannelslist, sampwidthlist, oldparams, \
+##                params, config, inited_outrate, inited_width, \
+##                inited_nchannels, port, converter, classinited: private
+
+    classinited = 0
+    frameratelist = nchannelslist = sampwidthlist = None
+
+    def initclass(self):
+        import AL
+        self.frameratelist = [
+                  (48000, AL.RATE_48000),
+                  (44100, AL.RATE_44100),
+                  (32000, AL.RATE_32000),
+                  (22050, AL.RATE_22050),
+                  (16000, AL.RATE_16000),
+                  (11025, AL.RATE_11025),
+                  ( 8000,  AL.RATE_8000),
+                  ]
+        self.nchannelslist = [
+                  (1, AL.MONO),
+                  (2, AL.STEREO),
+                  (4, AL.QUADRO),
+                  ]
+        self.sampwidthlist = [
+                  (1, AL.SAMPLE_8),
+                  (2, AL.SAMPLE_16),
+                  (3, AL.SAMPLE_24),
+                  ]
+        self.classinited = 1
+
+    def __init__(self):
+        import al, AL
+        if not self.classinited:
+            self.initclass()
+        self.oldparams = []
+        self.params = [AL.OUTPUT_RATE, 0]
+        self.config = al.newconfig()
+        self.inited_outrate = 0
+        self.inited_width = 0
+        self.inited_nchannels = 0
+        self.converter = None
+        self.port = None
+        return
+
+    def __del__(self):
+        if self.port:
+            self.stop()
+        if self.oldparams:
+            import al, AL
+            al.setparams(AL.DEFAULT_DEVICE, self.oldparams)
+            self.oldparams = []
+
+    def wait(self):
+        if not self.port:
+            return
+        import time
+        while self.port.getfilled() > 0:
+            time.sleep(0.1)
+        self.stop()
+
+    def stop(self):
+        if self.port:
+            self.port.closeport()
+            self.port = None
+        if self.oldparams:
+            import al, AL
+            al.setparams(AL.DEFAULT_DEVICE, self.oldparams)
+            self.oldparams = []
+
+    def setoutrate(self, rate):
+        for (raw, cooked) in self.frameratelist:
+            if rate == raw:
+                self.params[1] = cooked
+                self.inited_outrate = 1
+                break
+        else:
+            raise error, 'bad output rate'
+
+    def setsampwidth(self, width):
+        for (raw, cooked) in self.sampwidthlist:
+            if width == raw:
+                self.config.setwidth(cooked)
+                self.inited_width = 1
+                break
+        else:
+            if width == 0:
+                import AL
+                self.inited_width = 0
+                self.config.setwidth(AL.SAMPLE_16)
+                self.converter = self.ulaw2lin
+            else:
+                raise error, 'bad sample width'
+
+    def setnchannels(self, nchannels):
+        for (raw, cooked) in self.nchannelslist:
+            if nchannels == raw:
+                self.config.setchannels(cooked)
+                self.inited_nchannels = 1
+                break
+        else:
+            raise error, 'bad # of channels'
+
+    def writeframes(self, data):
+        if not (self.inited_outrate and self.inited_nchannels):
+            raise error, 'params not specified'
+        if not self.port:
+            import al, AL
+            self.port = al.openport('Python', 'w', self.config)
+            self.oldparams = self.params[:]
+            al.getparams(AL.DEFAULT_DEVICE, self.oldparams)
+            al.setparams(AL.DEFAULT_DEVICE, self.params)
+        if self.converter:
+            data = self.converter(data)
+        self.port.writesamps(data)
+
+    def getfilled(self):
+        if self.port:
+            return self.port.getfilled()
+        else:
+            return 0
+
+    def getfillable(self):
+        if self.port:
+            return self.port.getfillable()
+        else:
+            return self.config.getqueuesize()
+
+    # private methods
+##      if 0: access *: private
+
+    def ulaw2lin(self, data):
+        import audioop
+        return audioop.ulaw2lin(data, 2)
+
+class Play_Audio_sun:
+##      if 0: access outrate, sampwidth, nchannels, inited_outrate, inited_width, \
+##                inited_nchannels, converter: private
+
+    def __init__(self):
+        self.outrate = 0
+        self.sampwidth = 0
+        self.nchannels = 0
+        self.inited_outrate = 0
+        self.inited_width = 0
+        self.inited_nchannels = 0
+        self.converter = None
+        self.port = None
+        return
+
+    def __del__(self):
+        self.stop()
+
+    def setoutrate(self, rate):
+        self.outrate = rate
+        self.inited_outrate = 1
+
+    def setsampwidth(self, width):
+        self.sampwidth = width
+        self.inited_width = 1
+
+    def setnchannels(self, nchannels):
+        self.nchannels = nchannels
+        self.inited_nchannels = 1
+
+    def writeframes(self, data):
+        if not (self.inited_outrate and self.inited_width and self.inited_nchannels):
+            raise error, 'params not specified'
+        if not self.port:
+            import sunaudiodev, SUNAUDIODEV
+            self.port = sunaudiodev.open('w')
+            info = self.port.getinfo()
+            info.o_sample_rate = self.outrate
+            info.o_channels = self.nchannels
+            if self.sampwidth == 0:
+                info.o_precision = 8
+                self.o_encoding = SUNAUDIODEV.ENCODING_ULAW
+                # XXX Hack, hack -- leave defaults
+            else:
+                info.o_precision = 8 * self.sampwidth
+                info.o_encoding = SUNAUDIODEV.ENCODING_LINEAR
+                self.port.setinfo(info)
+        if self.converter:
+            data = self.converter(data)
+        self.port.write(data)
+
+    def wait(self):
+        if not self.port:
+            return
+        self.port.drain()
+        self.stop()
+
+    def stop(self):
+        if self.port:
+            self.port.flush()
+            self.port.close()
+            self.port = None
+
+    def getfilled(self):
+        if self.port:
+            return self.port.obufcount()
+        else:
+            return 0
+
+##    # Nobody remembers what this method does, and it's broken. :-(
+##    def getfillable(self):
+##        return BUFFERSIZE - self.getfilled()
+
+def AudioDev():
+    # Dynamically try to import and use a platform specific module.
+    try:
+        import al
+    except ImportError:
+        try:
+            import sunaudiodev
+            return Play_Audio_sun()
+        except ImportError:
+            try:
+                import Audio_mac
+            except ImportError:
+                raise error, 'no audio device'
+            else:
+                return Audio_mac.Play_Audio_mac()
+    else:
+        return Play_Audio_sgi()
+
+def test(fn = None):
+    import sys
+    if sys.argv[1:]:
+        fn = sys.argv[1]
+    else:
+        fn = 'f:just samples:just.aif'
+    import aifc
+    af = aifc.open(fn, 'r')
+    print fn, af.getparams()
+    p = AudioDev()
+    p.setoutrate(af.getframerate())
+    p.setsampwidth(af.getsampwidth())
+    p.setnchannels(af.getnchannels())
+    BUFSIZ = af.getframerate()/af.getsampwidth()/af.getnchannels()
+    while 1:
+        data = af.readframes(BUFSIZ)
+        if not data: break
+        print len(data)
+        p.writeframes(data)
+    p.wait()
+
+if __name__ == '__main__':
+    test()

Added: vendor/Python/current/Lib/base64.py
===================================================================
--- vendor/Python/current/Lib/base64.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/base64.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,359 @@
+#! /usr/bin/env python
+
+"""RFC 3548: Base16, Base32, Base64 Data Encodings"""
+
+# Modified 04-Oct-1995 by Jack Jansen to use binascii module
+# Modified 30-Dec-2003 by Barry Warsaw to add full RFC 3548 support
+
+import re
+import struct
+import binascii
+
+
+__all__ = [
+    # Legacy interface exports traditional RFC 1521 Base64 encodings
+    'encode', 'decode', 'encodestring', 'decodestring',
+    # Generalized interface for other encodings
+    'b64encode', 'b64decode', 'b32encode', 'b32decode',
+    'b16encode', 'b16decode',
+    # Standard Base64 encoding
+    'standard_b64encode', 'standard_b64decode',
+    # Some common Base64 alternatives.  As referenced by RFC 3458, see thread
+    # starting at:
+    #
+    # http://zgp.org/pipermail/p2p-hackers/2001-September/000316.html
+    'urlsafe_b64encode', 'urlsafe_b64decode',
+    ]
+
+_translation = [chr(_x) for _x in range(256)]
+EMPTYSTRING = ''
+
+
+def _translate(s, altchars):
+    translation = _translation[:]
+    for k, v in altchars.items():
+        translation[ord(k)] = v
+    return s.translate(''.join(translation))
+
+
+
+# Base64 encoding/decoding uses binascii
+
+def b64encode(s, altchars=None):
+    """Encode a string using Base64.
+
+    s is the string to encode.  Optional altchars must be a string of at least
+    length 2 (additional characters are ignored) which specifies an
+    alternative alphabet for the '+' and '/' characters.  This allows an
+    application to e.g. generate url or filesystem safe Base64 strings.
+
+    The encoded string is returned.
+    """
+    # Strip off the trailing newline
+    encoded = binascii.b2a_base64(s)[:-1]
+    if altchars is not None:
+        return _translate(encoded, {'+': altchars[0], '/': altchars[1]})
+    return encoded
+
+
+def b64decode(s, altchars=None):
+    """Decode a Base64 encoded string.
+
+    s is the string to decode.  Optional altchars must be a string of at least
+    length 2 (additional characters are ignored) which specifies the
+    alternative alphabet used instead of the '+' and '/' characters.
+
+    The decoded string is returned.  A TypeError is raised if s were
+    incorrectly padded or if there are non-alphabet characters present in the
+    string.
+    """
+    if altchars is not None:
+        s = _translate(s, {altchars[0]: '+', altchars[1]: '/'})
+    try:
+        return binascii.a2b_base64(s)
+    except binascii.Error, msg:
+        # Transform this exception for consistency
+        raise TypeError(msg)
+
+
+def standard_b64encode(s):
+    """Encode a string using the standard Base64 alphabet.
+
+    s is the string to encode.  The encoded string is returned.
+    """
+    return b64encode(s)
+
+def standard_b64decode(s):
+    """Decode a string encoded with the standard Base64 alphabet.
+
+    s is the string to decode.  The decoded string is returned.  A TypeError
+    is raised if the string is incorrectly padded or if there are non-alphabet
+    characters present in the string.
+    """
+    return b64decode(s)
+
+def urlsafe_b64encode(s):
+    """Encode a string using a url-safe Base64 alphabet.
+
+    s is the string to encode.  The encoded string is returned.  The alphabet
+    uses '-' instead of '+' and '_' instead of '/'.
+    """
+    return b64encode(s, '-_')
+
+def urlsafe_b64decode(s):
+    """Decode a string encoded with the standard Base64 alphabet.
+
+    s is the string to decode.  The decoded string is returned.  A TypeError
+    is raised if the string is incorrectly padded or if there are non-alphabet
+    characters present in the string.
+
+    The alphabet uses '-' instead of '+' and '_' instead of '/'.
+    """
+    return b64decode(s, '-_')
+
+
+
+# Base32 encoding/decoding must be done in Python
+_b32alphabet = {
+    0: 'A',  9: 'J', 18: 'S', 27: '3',
+    1: 'B', 10: 'K', 19: 'T', 28: '4',
+    2: 'C', 11: 'L', 20: 'U', 29: '5',
+    3: 'D', 12: 'M', 21: 'V', 30: '6',
+    4: 'E', 13: 'N', 22: 'W', 31: '7',
+    5: 'F', 14: 'O', 23: 'X',
+    6: 'G', 15: 'P', 24: 'Y',
+    7: 'H', 16: 'Q', 25: 'Z',
+    8: 'I', 17: 'R', 26: '2',
+    }
+
+_b32tab = _b32alphabet.items()
+_b32tab.sort()
+_b32tab = [v for k, v in _b32tab]
+_b32rev = dict([(v, long(k)) for k, v in _b32alphabet.items()])
+
+
+def b32encode(s):
+    """Encode a string using Base32.
+
+    s is the string to encode.  The encoded string is returned.
+    """
+    parts = []
+    quanta, leftover = divmod(len(s), 5)
+    # Pad the last quantum with zero bits if necessary
+    if leftover:
+        s += ('\0' * (5 - leftover))
+        quanta += 1
+    for i in range(quanta):
+        # c1 and c2 are 16 bits wide, c3 is 8 bits wide.  The intent of this
+        # code is to process the 40 bits in units of 5 bits.  So we take the 1
+        # leftover bit of c1 and tack it onto c2.  Then we take the 2 leftover
+        # bits of c2 and tack them onto c3.  The shifts and masks are intended
+        # to give us values of exactly 5 bits in width.
+        c1, c2, c3 = struct.unpack('!HHB', s[i*5:(i+1)*5])
+        c2 += (c1 & 1) << 16 # 17 bits wide
+        c3 += (c2 & 3) << 8  # 10 bits wide
+        parts.extend([_b32tab[c1 >> 11],         # bits 1 - 5
+                      _b32tab[(c1 >> 6) & 0x1f], # bits 6 - 10
+                      _b32tab[(c1 >> 1) & 0x1f], # bits 11 - 15
+                      _b32tab[c2 >> 12],         # bits 16 - 20 (1 - 5)
+                      _b32tab[(c2 >> 7) & 0x1f], # bits 21 - 25 (6 - 10)
+                      _b32tab[(c2 >> 2) & 0x1f], # bits 26 - 30 (11 - 15)
+                      _b32tab[c3 >> 5],          # bits 31 - 35 (1 - 5)
+                      _b32tab[c3 & 0x1f],        # bits 36 - 40 (1 - 5)
+                      ])
+    encoded = EMPTYSTRING.join(parts)
+    # Adjust for any leftover partial quanta
+    if leftover == 1:
+        return encoded[:-6] + '======'
+    elif leftover == 2:
+        return encoded[:-4] + '===='
+    elif leftover == 3:
+        return encoded[:-3] + '==='
+    elif leftover == 4:
+        return encoded[:-1] + '='
+    return encoded
+
+
+def b32decode(s, casefold=False, map01=None):
+    """Decode a Base32 encoded string.
+
+    s is the string to decode.  Optional casefold is a flag specifying whether
+    a lowercase alphabet is acceptable as input.  For security purposes, the
+    default is False.
+
+    RFC 3548 allows for optional mapping of the digit 0 (zero) to the letter O
+    (oh), and for optional mapping of the digit 1 (one) to either the letter I
+    (eye) or letter L (el).  The optional argument map01 when not None,
+    specifies which letter the digit 1 should be mapped to (when map01 is not
+    None, the digit 0 is always mapped to the letter O).  For security
+    purposes the default is None, so that 0 and 1 are not allowed in the
+    input.
+
+    The decoded string is returned.  A TypeError is raised if s were
+    incorrectly padded or if there are non-alphabet characters present in the
+    string.
+    """
+    quanta, leftover = divmod(len(s), 8)
+    if leftover:
+        raise TypeError('Incorrect padding')
+    # Handle section 2.4 zero and one mapping.  The flag map01 will be either
+    # False, or the character to map the digit 1 (one) to.  It should be
+    # either L (el) or I (eye).
+    if map01:
+        s = _translate(s, {'0': 'O', '1': map01})
+    if casefold:
+        s = s.upper()
+    # Strip off pad characters from the right.  We need to count the pad
+    # characters because this will tell us how many null bytes to remove from
+    # the end of the decoded string.
+    padchars = 0
+    mo = re.search('(?P<pad>[=]*)$', s)
+    if mo:
+        padchars = len(mo.group('pad'))
+        if padchars > 0:
+            s = s[:-padchars]
+    # Now decode the full quanta
+    parts = []
+    acc = 0
+    shift = 35
+    for c in s:
+        val = _b32rev.get(c)
+        if val is None:
+            raise TypeError('Non-base32 digit found')
+        acc += _b32rev[c] << shift
+        shift -= 5
+        if shift < 0:
+            parts.append(binascii.unhexlify('%010x' % acc))
+            acc = 0
+            shift = 35
+    # Process the last, partial quanta
+    last = binascii.unhexlify('%010x' % acc)
+    if padchars == 0:
+        last = ''                       # No characters
+    elif padchars == 1:
+        last = last[:-1]
+    elif padchars == 3:
+        last = last[:-2]
+    elif padchars == 4:
+        last = last[:-3]
+    elif padchars == 6:
+        last = last[:-4]
+    else:
+        raise TypeError('Incorrect padding')
+    parts.append(last)
+    return EMPTYSTRING.join(parts)
+
+
+
+# RFC 3548, Base 16 Alphabet specifies uppercase, but hexlify() returns
+# lowercase.  The RFC also recommends against accepting input case
+# insensitively.
+def b16encode(s):
+    """Encode a string using Base16.
+
+    s is the string to encode.  The encoded string is returned.
+    """
+    return binascii.hexlify(s).upper()
+
+
+def b16decode(s, casefold=False):
+    """Decode a Base16 encoded string.
+
+    s is the string to decode.  Optional casefold is a flag specifying whether
+    a lowercase alphabet is acceptable as input.  For security purposes, the
+    default is False.
+
+    The decoded string is returned.  A TypeError is raised if s were
+    incorrectly padded or if there are non-alphabet characters present in the
+    string.
+    """
+    if casefold:
+        s = s.upper()
+    if re.search('[^0-9A-F]', s):
+        raise TypeError('Non-base16 digit found')
+    return binascii.unhexlify(s)
+
+
+
+# Legacy interface.  This code could be cleaned up since I don't believe
+# binascii has any line length limitations.  It just doesn't seem worth it
+# though.
+
+MAXLINESIZE = 76 # Excluding the CRLF
+MAXBINSIZE = (MAXLINESIZE//4)*3
+
+def encode(input, output):
+    """Encode a file."""
+    while True:
+        s = input.read(MAXBINSIZE)
+        if not s:
+            break
+        while len(s) < MAXBINSIZE:
+            ns = input.read(MAXBINSIZE-len(s))
+            if not ns:
+                break
+            s += ns
+        line = binascii.b2a_base64(s)
+        output.write(line)
+
+
+def decode(input, output):
+    """Decode a file."""
+    while True:
+        line = input.readline()
+        if not line:
+            break
+        s = binascii.a2b_base64(line)
+        output.write(s)
+
+
+def encodestring(s):
+    """Encode a string."""
+    pieces = []
+    for i in range(0, len(s), MAXBINSIZE):
+        chunk = s[i : i + MAXBINSIZE]
+        pieces.append(binascii.b2a_base64(chunk))
+    return "".join(pieces)
+
+
+def decodestring(s):
+    """Decode a string."""
+    return binascii.a2b_base64(s)
+
+
+
+# Useable as a script...
+def test():
+    """Small test program"""
+    import sys, getopt
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], 'deut')
+    except getopt.error, msg:
+        sys.stdout = sys.stderr
+        print msg
+        print """usage: %s [-d|-e|-u|-t] [file|-]
+        -d, -u: decode
+        -e: encode (default)
+        -t: encode and decode string 'Aladdin:open sesame'"""%sys.argv[0]
+        sys.exit(2)
+    func = encode
+    for o, a in opts:
+        if o == '-e': func = encode
+        if o == '-d': func = decode
+        if o == '-u': func = decode
+        if o == '-t': test1(); return
+    if args and args[0] != '-':
+        func(open(args[0], 'rb'), sys.stdout)
+    else:
+        func(sys.stdin, sys.stdout)
+
+
+def test1():
+    s0 = "Aladdin:open sesame"
+    s1 = encodestring(s0)
+    s2 = decodestring(s1)
+    print s0, repr(s1), s2
+
+
+if __name__ == '__main__':
+    test()


Property changes on: vendor/Python/current/Lib/base64.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/bdb.py
===================================================================
--- vendor/Python/current/Lib/bdb.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/bdb.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,613 @@
+"""Debugger basics"""
+
+import sys
+import os
+import types
+
+__all__ = ["BdbQuit","Bdb","Breakpoint"]
+
+class BdbQuit(Exception):
+    """Exception to give up completely"""
+
+
+class Bdb:
+
+    """Generic Python debugger base class.
+
+    This class takes care of details of the trace facility;
+    a derived class should implement user interaction.
+    The standard debugger class (pdb.Pdb) is an example.
+    """
+
+    def __init__(self):
+        self.breaks = {}
+        self.fncache = {}
+
+    def canonic(self, filename):
+        if filename == "<" + filename[1:-1] + ">":
+            return filename
+        canonic = self.fncache.get(filename)
+        if not canonic:
+            canonic = os.path.abspath(filename)
+            canonic = os.path.normcase(canonic)
+            self.fncache[filename] = canonic
+        return canonic
+
+    def reset(self):
+        import linecache
+        linecache.checkcache()
+        self.botframe = None
+        self.stopframe = None
+        self.returnframe = None
+        self.quitting = 0
+
+    def trace_dispatch(self, frame, event, arg):
+        if self.quitting:
+            return # None
+        if event == 'line':
+            return self.dispatch_line(frame)
+        if event == 'call':
+            return self.dispatch_call(frame, arg)
+        if event == 'return':
+            return self.dispatch_return(frame, arg)
+        if event == 'exception':
+            return self.dispatch_exception(frame, arg)
+        if event == 'c_call':
+            return self.trace_dispatch
+        if event == 'c_exception':
+            return self.trace_dispatch
+        if event == 'c_return':
+            return self.trace_dispatch
+        print 'bdb.Bdb.dispatch: unknown debugging event:', repr(event)
+        return self.trace_dispatch
+
+    def dispatch_line(self, frame):
+        if self.stop_here(frame) or self.break_here(frame):
+            self.user_line(frame)
+            if self.quitting: raise BdbQuit
+        return self.trace_dispatch
+
+    def dispatch_call(self, frame, arg):
+        # XXX 'arg' is no longer used
+        if self.botframe is None:
+            # First call of dispatch since reset()
+            self.botframe = frame.f_back # (CT) Note that this may also be None!
+            return self.trace_dispatch
+        if not (self.stop_here(frame) or self.break_anywhere(frame)):
+            # No need to trace this function
+            return # None
+        self.user_call(frame, arg)
+        if self.quitting: raise BdbQuit
+        return self.trace_dispatch
+
+    def dispatch_return(self, frame, arg):
+        if self.stop_here(frame) or frame == self.returnframe:
+            self.user_return(frame, arg)
+            if self.quitting: raise BdbQuit
+        return self.trace_dispatch
+
+    def dispatch_exception(self, frame, arg):
+        if self.stop_here(frame):
+            self.user_exception(frame, arg)
+            if self.quitting: raise BdbQuit
+        return self.trace_dispatch
+
+    # Normally derived classes don't override the following
+    # methods, but they may if they want to redefine the
+    # definition of stopping and breakpoints.
+
+    def stop_here(self, frame):
+        # (CT) stopframe may now also be None, see dispatch_call.
+        # (CT) the former test for None is therefore removed from here.
+        if frame is self.stopframe:
+            return True
+        while frame is not None and frame is not self.stopframe:
+            if frame is self.botframe:
+                return True
+            frame = frame.f_back
+        return False
+
+    def break_here(self, frame):
+        filename = self.canonic(frame.f_code.co_filename)
+        if not filename in self.breaks:
+            return False
+        lineno = frame.f_lineno
+        if not lineno in self.breaks[filename]:
+            # The line itself has no breakpoint, but maybe the line is the
+            # first line of a function with breakpoint set by function name.
+            lineno = frame.f_code.co_firstlineno
+            if not lineno in self.breaks[filename]:
+                return False
+
+        # flag says ok to delete temp. bp
+        (bp, flag) = effective(filename, lineno, frame)
+        if bp:
+            self.currentbp = bp.number
+            if (flag and bp.temporary):
+                self.do_clear(str(bp.number))
+            return True
+        else:
+            return False
+
+    def do_clear(self, arg):
+        raise NotImplementedError, "subclass of bdb must implement do_clear()"
+
+    def break_anywhere(self, frame):
+        return self.breaks.has_key(
+            self.canonic(frame.f_code.co_filename))
+
+    # Derived classes should override the user_* methods
+    # to gain control.
+
+    def user_call(self, frame, argument_list):
+        """This method is called when there is the remote possibility
+        that we ever need to stop in this function."""
+        pass
+
+    def user_line(self, frame):
+        """This method is called when we stop or break at this line."""
+        pass
+
+    def user_return(self, frame, return_value):
+        """This method is called when a return trap is set here."""
+        pass
+
+    def user_exception(self, frame, (exc_type, exc_value, exc_traceback)):
+        """This method is called if an exception occurs,
+        but only if we are to stop at or just below this level."""
+        pass
+
+    # Derived classes and clients can call the following methods
+    # to affect the stepping state.
+
+    def set_step(self):
+        """Stop after one line of code."""
+        self.stopframe = None
+        self.returnframe = None
+        self.quitting = 0
+
+    def set_next(self, frame):
+        """Stop on the next line in or below the given frame."""
+        self.stopframe = frame
+        self.returnframe = None
+        self.quitting = 0
+
+    def set_return(self, frame):
+        """Stop when returning from the given frame."""
+        self.stopframe = frame.f_back
+        self.returnframe = frame
+        self.quitting = 0
+
+    def set_trace(self, frame=None):
+        """Start debugging from `frame`.
+
+        If frame is not specified, debugging starts from caller's frame.
+        """
+        if frame is None:
+            frame = sys._getframe().f_back
+        self.reset()
+        while frame:
+            frame.f_trace = self.trace_dispatch
+            self.botframe = frame
+            frame = frame.f_back
+        self.set_step()
+        sys.settrace(self.trace_dispatch)
+
+    def set_continue(self):
+        # Don't stop except at breakpoints or when finished
+        self.stopframe = self.botframe
+        self.returnframe = None
+        self.quitting = 0
+        if not self.breaks:
+            # no breakpoints; run without debugger overhead
+            sys.settrace(None)
+            frame = sys._getframe().f_back
+            while frame and frame is not self.botframe:
+                del frame.f_trace
+                frame = frame.f_back
+
+    def set_quit(self):
+        self.stopframe = self.botframe
+        self.returnframe = None
+        self.quitting = 1
+        sys.settrace(None)
+
+    # Derived classes and clients can call the following methods
+    # to manipulate breakpoints.  These methods return an
+    # error message is something went wrong, None if all is well.
+    # Set_break prints out the breakpoint line and file:lineno.
+    # Call self.get_*break*() to see the breakpoints or better
+    # for bp in Breakpoint.bpbynumber: if bp: bp.bpprint().
+
+    def set_break(self, filename, lineno, temporary=0, cond = None,
+                  funcname=None):
+        filename = self.canonic(filename)
+        import linecache # Import as late as possible
+        line = linecache.getline(filename, lineno)
+        if not line:
+            return 'Line %s:%d does not exist' % (filename,
+                                   lineno)
+        if not filename in self.breaks:
+            self.breaks[filename] = []
+        list = self.breaks[filename]
+        if not lineno in list:
+            list.append(lineno)
+        bp = Breakpoint(filename, lineno, temporary, cond, funcname)
+
+    def clear_break(self, filename, lineno):
+        filename = self.canonic(filename)
+        if not filename in self.breaks:
+            return 'There are no breakpoints in %s' % filename
+        if lineno not in self.breaks[filename]:
+            return 'There is no breakpoint at %s:%d' % (filename,
+                                    lineno)
+        # If there's only one bp in the list for that file,line
+        # pair, then remove the breaks entry
+        for bp in Breakpoint.bplist[filename, lineno][:]:
+            bp.deleteMe()
+        if not Breakpoint.bplist.has_key((filename, lineno)):
+            self.breaks[filename].remove(lineno)
+        if not self.breaks[filename]:
+            del self.breaks[filename]
+
+    def clear_bpbynumber(self, arg):
+        try:
+            number = int(arg)
+        except:
+            return 'Non-numeric breakpoint number (%s)' % arg
+        try:
+            bp = Breakpoint.bpbynumber[number]
+        except IndexError:
+            return 'Breakpoint number (%d) out of range' % number
+        if not bp:
+            return 'Breakpoint (%d) already deleted' % number
+        self.clear_break(bp.file, bp.line)
+
+    def clear_all_file_breaks(self, filename):
+        filename = self.canonic(filename)
+        if not filename in self.breaks:
+            return 'There are no breakpoints in %s' % filename
+        for line in self.breaks[filename]:
+            blist = Breakpoint.bplist[filename, line]
+            for bp in blist:
+                bp.deleteMe()
+        del self.breaks[filename]
+
+    def clear_all_breaks(self):
+        if not self.breaks:
+            return 'There are no breakpoints'
+        for bp in Breakpoint.bpbynumber:
+            if bp:
+                bp.deleteMe()
+        self.breaks = {}
+
+    def get_break(self, filename, lineno):
+        filename = self.canonic(filename)
+        return filename in self.breaks and \
+            lineno in self.breaks[filename]
+
+    def get_breaks(self, filename, lineno):
+        filename = self.canonic(filename)
+        return filename in self.breaks and \
+            lineno in self.breaks[filename] and \
+            Breakpoint.bplist[filename, lineno] or []
+
+    def get_file_breaks(self, filename):
+        filename = self.canonic(filename)
+        if filename in self.breaks:
+            return self.breaks[filename]
+        else:
+            return []
+
+    def get_all_breaks(self):
+        return self.breaks
+
+    # Derived classes and clients can call the following method
+    # to get a data structure representing a stack trace.
+
+    def get_stack(self, f, t):
+        stack = []
+        if t and t.tb_frame is f:
+            t = t.tb_next
+        while f is not None:
+            stack.append((f, f.f_lineno))
+            if f is self.botframe:
+                break
+            f = f.f_back
+        stack.reverse()
+        i = max(0, len(stack) - 1)
+        while t is not None:
+            stack.append((t.tb_frame, t.tb_lineno))
+            t = t.tb_next
+        return stack, i
+
+    #
+
+    def format_stack_entry(self, frame_lineno, lprefix=': '):
+        import linecache, repr
+        frame, lineno = frame_lineno
+        filename = self.canonic(frame.f_code.co_filename)
+        s = '%s(%r)' % (filename, lineno)
+        if frame.f_code.co_name:
+            s = s + frame.f_code.co_name
+        else:
+            s = s + "<lambda>"
+        if '__args__' in frame.f_locals:
+            args = frame.f_locals['__args__']
+        else:
+            args = None
+        if args:
+            s = s + repr.repr(args)
+        else:
+            s = s + '()'
+        if '__return__' in frame.f_locals:
+            rv = frame.f_locals['__return__']
+            s = s + '->'
+            s = s + repr.repr(rv)
+        line = linecache.getline(filename, lineno)
+        if line: s = s + lprefix + line.strip()
+        return s
+
+    # The following two methods can be called by clients to use
+    # a debugger to debug a statement, given as a string.
+
+    def run(self, cmd, globals=None, locals=None):
+        if globals is None:
+            import __main__
+            globals = __main__.__dict__
+        if locals is None:
+            locals = globals
+        self.reset()
+        sys.settrace(self.trace_dispatch)
+        if not isinstance(cmd, types.CodeType):
+            cmd = cmd+'\n'
+        try:
+            try:
+                exec cmd in globals, locals
+            except BdbQuit:
+                pass
+        finally:
+            self.quitting = 1
+            sys.settrace(None)
+
+    def runeval(self, expr, globals=None, locals=None):
+        if globals is None:
+            import __main__
+            globals = __main__.__dict__
+        if locals is None:
+            locals = globals
+        self.reset()
+        sys.settrace(self.trace_dispatch)
+        if not isinstance(expr, types.CodeType):
+            expr = expr+'\n'
+        try:
+            try:
+                return eval(expr, globals, locals)
+            except BdbQuit:
+                pass
+        finally:
+            self.quitting = 1
+            sys.settrace(None)
+
+    def runctx(self, cmd, globals, locals):
+        # B/W compatibility
+        self.run(cmd, globals, locals)
+
+    # This method is more useful to debug a single function call.
+
+    def runcall(self, func, *args, **kwds):
+        self.reset()
+        sys.settrace(self.trace_dispatch)
+        res = None
+        try:
+            try:
+                res = func(*args, **kwds)
+            except BdbQuit:
+                pass
+        finally:
+            self.quitting = 1
+            sys.settrace(None)
+        return res
+
+
+def set_trace():
+    Bdb().set_trace()
+
+
+class Breakpoint:
+
+    """Breakpoint class
+
+    Implements temporary breakpoints, ignore counts, disabling and
+    (re)-enabling, and conditionals.
+
+    Breakpoints are indexed by number through bpbynumber and by
+    the file,line tuple using bplist.  The former points to a
+    single instance of class Breakpoint.  The latter points to a
+    list of such instances since there may be more than one
+    breakpoint per line.
+
+    """
+
+    # XXX Keeping state in the class is a mistake -- this means
+    # you cannot have more than one active Bdb instance.
+
+    next = 1        # Next bp to be assigned
+    bplist = {}     # indexed by (file, lineno) tuple
+    bpbynumber = [None] # Each entry is None or an instance of Bpt
+                # index 0 is unused, except for marking an
+                # effective break .... see effective()
+
+    def __init__(self, file, line, temporary=0, cond=None, funcname=None):
+        self.funcname = funcname
+        # Needed if funcname is not None.
+        self.func_first_executable_line = None
+        self.file = file    # This better be in canonical form!
+        self.line = line
+        self.temporary = temporary
+        self.cond = cond
+        self.enabled = 1
+        self.ignore = 0
+        self.hits = 0
+        self.number = Breakpoint.next
+        Breakpoint.next = Breakpoint.next + 1
+        # Build the two lists
+        self.bpbynumber.append(self)
+        if self.bplist.has_key((file, line)):
+            self.bplist[file, line].append(self)
+        else:
+            self.bplist[file, line] = [self]
+
+
+    def deleteMe(self):
+        index = (self.file, self.line)
+        self.bpbynumber[self.number] = None   # No longer in list
+        self.bplist[index].remove(self)
+        if not self.bplist[index]:
+            # No more bp for this f:l combo
+            del self.bplist[index]
+
+    def enable(self):
+        self.enabled = 1
+
+    def disable(self):
+        self.enabled = 0
+
+    def bpprint(self, out=None):
+        if out is None:
+            out = sys.stdout
+        if self.temporary:
+            disp = 'del  '
+        else:
+            disp = 'keep '
+        if self.enabled:
+            disp = disp + 'yes  '
+        else:
+            disp = disp + 'no   '
+        print >>out, '%-4dbreakpoint   %s at %s:%d' % (self.number, disp,
+                                                       self.file, self.line)
+        if self.cond:
+            print >>out, '\tstop only if %s' % (self.cond,)
+        if self.ignore:
+            print >>out, '\tignore next %d hits' % (self.ignore)
+        if (self.hits):
+            if (self.hits > 1): ss = 's'
+            else: ss = ''
+            print >>out, ('\tbreakpoint already hit %d time%s' %
+                          (self.hits, ss))
+
+# -----------end of Breakpoint class----------
+
+def checkfuncname(b, frame):
+    """Check whether we should break here because of `b.funcname`."""
+    if not b.funcname:
+        # Breakpoint was set via line number.
+        if b.line != frame.f_lineno:
+            # Breakpoint was set at a line with a def statement and the function
+            # defined is called: don't break.
+            return False
+        return True
+
+    # Breakpoint set via function name.
+
+    if frame.f_code.co_name != b.funcname:
+        # It's not a function call, but rather execution of def statement.
+        return False
+
+    # We are in the right frame.
+    if not b.func_first_executable_line:
+        # The function is entered for the 1st time.
+        b.func_first_executable_line = frame.f_lineno
+
+    if  b.func_first_executable_line != frame.f_lineno:
+        # But we are not at the first line number: don't break.
+        return False
+    return True
+
+# Determines if there is an effective (active) breakpoint at this
+# line of code.  Returns breakpoint number or 0 if none
+def effective(file, line, frame):
+    """Determine which breakpoint for this file:line is to be acted upon.
+
+    Called only if we know there is a bpt at this
+    location.  Returns breakpoint that was triggered and a flag
+    that indicates if it is ok to delete a temporary bp.
+
+    """
+    possibles = Breakpoint.bplist[file,line]
+    for i in range(0, len(possibles)):
+        b = possibles[i]
+        if b.enabled == 0:
+            continue
+        if not checkfuncname(b, frame):
+            continue
+        # Count every hit when bp is enabled
+        b.hits = b.hits + 1
+        if not b.cond:
+            # If unconditional, and ignoring,
+            # go on to next, else break
+            if b.ignore > 0:
+                b.ignore = b.ignore -1
+                continue
+            else:
+                # breakpoint and marker that's ok
+                # to delete if temporary
+                return (b,1)
+        else:
+            # Conditional bp.
+            # Ignore count applies only to those bpt hits where the
+            # condition evaluates to true.
+            try:
+                val = eval(b.cond, frame.f_globals,
+                       frame.f_locals)
+                if val:
+                    if b.ignore > 0:
+                        b.ignore = b.ignore -1
+                        # continue
+                    else:
+                        return (b,1)
+                # else:
+                #   continue
+            except:
+                # if eval fails, most conservative
+                # thing is to stop on breakpoint
+                # regardless of ignore count.
+                # Don't delete temporary,
+                # as another hint to user.
+                return (b,0)
+    return (None, None)
+
+# -------------------- testing --------------------
+
+class Tdb(Bdb):
+    def user_call(self, frame, args):
+        name = frame.f_code.co_name
+        if not name: name = '???'
+        print '+++ call', name, args
+    def user_line(self, frame):
+        import linecache
+        name = frame.f_code.co_name
+        if not name: name = '???'
+        fn = self.canonic(frame.f_code.co_filename)
+        line = linecache.getline(fn, frame.f_lineno)
+        print '+++', fn, frame.f_lineno, name, ':', line.strip()
+    def user_return(self, frame, retval):
+        print '+++ return', retval
+    def user_exception(self, frame, exc_stuff):
+        print '+++ exception', exc_stuff
+        self.set_continue()
+
+def foo(n):
+    print 'foo(', n, ')'
+    x = bar(n*10)
+    print 'bar returned', x
+
+def bar(a):
+    print 'bar(', a, ')'
+    return a/2
+
+def test():
+    t = Tdb()
+    t.run('import bdb; bdb.foo(10)')
+
+# end

Added: vendor/Python/current/Lib/binhex.py
===================================================================
--- vendor/Python/current/Lib/binhex.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/binhex.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,527 @@
+"""Macintosh binhex compression/decompression.
+
+easy interface:
+binhex(inputfilename, outputfilename)
+hexbin(inputfilename, outputfilename)
+"""
+
+#
+# Jack Jansen, CWI, August 1995.
+#
+# The module is supposed to be as compatible as possible. Especially the
+# easy interface should work "as expected" on any platform.
+# XXXX Note: currently, textfiles appear in mac-form on all platforms.
+# We seem to lack a simple character-translate in python.
+# (we should probably use ISO-Latin-1 on all but the mac platform).
+# XXXX The simple routines are too simple: they expect to hold the complete
+# files in-core. Should be fixed.
+# XXXX It would be nice to handle AppleDouble format on unix
+# (for servers serving macs).
+# XXXX I don't understand what happens when you get 0x90 times the same byte on
+# input. The resulting code (xx 90 90) would appear to be interpreted as an
+# escaped *value* of 0x90. All coders I've seen appear to ignore this nicety...
+#
+import sys
+import os
+import struct
+import binascii
+
+__all__ = ["binhex","hexbin","Error"]
+
+class Error(Exception):
+    pass
+
+# States (what have we written)
+[_DID_HEADER, _DID_DATA, _DID_RSRC] = range(3)
+
+# Various constants
+REASONABLY_LARGE=32768  # Minimal amount we pass the rle-coder
+LINELEN=64
+RUNCHAR=chr(0x90)   # run-length introducer
+
+#
+# This code is no longer byte-order dependent
+
+#
+# Workarounds for non-mac machines.
+try:
+    from Carbon.File import FSSpec, FInfo
+    from MacOS import openrf
+
+    def getfileinfo(name):
+        finfo = FSSpec(name).FSpGetFInfo()
+        dir, file = os.path.split(name)
+        # XXX Get resource/data sizes
+        fp = open(name, 'rb')
+        fp.seek(0, 2)
+        dlen = fp.tell()
+        fp = openrf(name, '*rb')
+        fp.seek(0, 2)
+        rlen = fp.tell()
+        return file, finfo, dlen, rlen
+
+    def openrsrc(name, *mode):
+        if not mode:
+            mode = '*rb'
+        else:
+            mode = '*' + mode[0]
+        return openrf(name, mode)
+
+except ImportError:
+    #
+    # Glue code for non-macintosh usage
+    #
+
+    class FInfo:
+        def __init__(self):
+            self.Type = '????'
+            self.Creator = '????'
+            self.Flags = 0
+
+    def getfileinfo(name):
+        finfo = FInfo()
+        # Quick check for textfile
+        fp = open(name)
+        data = open(name).read(256)
+        for c in data:
+            if not c.isspace() and (c<' ' or ord(c) > 0x7f):
+                break
+        else:
+            finfo.Type = 'TEXT'
+        fp.seek(0, 2)
+        dsize = fp.tell()
+        fp.close()
+        dir, file = os.path.split(name)
+        file = file.replace(':', '-', 1)
+        return file, finfo, dsize, 0
+
+    class openrsrc:
+        def __init__(self, *args):
+            pass
+
+        def read(self, *args):
+            return ''
+
+        def write(self, *args):
+            pass
+
+        def close(self):
+            pass
+
+class _Hqxcoderengine:
+    """Write data to the coder in 3-byte chunks"""
+
+    def __init__(self, ofp):
+        self.ofp = ofp
+        self.data = ''
+        self.hqxdata = ''
+        self.linelen = LINELEN-1
+
+    def write(self, data):
+        self.data = self.data + data
+        datalen = len(self.data)
+        todo = (datalen//3)*3
+        data = self.data[:todo]
+        self.data = self.data[todo:]
+        if not data:
+            return
+        self.hqxdata = self.hqxdata + binascii.b2a_hqx(data)
+        self._flush(0)
+
+    def _flush(self, force):
+        first = 0
+        while first <= len(self.hqxdata)-self.linelen:
+            last = first + self.linelen
+            self.ofp.write(self.hqxdata[first:last]+'\n')
+            self.linelen = LINELEN
+            first = last
+        self.hqxdata = self.hqxdata[first:]
+        if force:
+            self.ofp.write(self.hqxdata + ':\n')
+
+    def close(self):
+        if self.data:
+            self.hqxdata = \
+                 self.hqxdata + binascii.b2a_hqx(self.data)
+        self._flush(1)
+        self.ofp.close()
+        del self.ofp
+
+class _Rlecoderengine:
+    """Write data to the RLE-coder in suitably large chunks"""
+
+    def __init__(self, ofp):
+        self.ofp = ofp
+        self.data = ''
+
+    def write(self, data):
+        self.data = self.data + data
+        if len(self.data) < REASONABLY_LARGE:
+            return
+        rledata = binascii.rlecode_hqx(self.data)
+        self.ofp.write(rledata)
+        self.data = ''
+
+    def close(self):
+        if self.data:
+            rledata = binascii.rlecode_hqx(self.data)
+            self.ofp.write(rledata)
+        self.ofp.close()
+        del self.ofp
+
+class BinHex:
+    def __init__(self, (name, finfo, dlen, rlen), ofp):
+        if type(ofp) == type(''):
+            ofname = ofp
+            ofp = open(ofname, 'w')
+            if os.name == 'mac':
+                fss = FSSpec(ofname)
+                fss.SetCreatorType('BnHq', 'TEXT')
+        ofp.write('(This file must be converted with BinHex 4.0)\n\n:')
+        hqxer = _Hqxcoderengine(ofp)
+        self.ofp = _Rlecoderengine(hqxer)
+        self.crc = 0
+        if finfo is None:
+            finfo = FInfo()
+        self.dlen = dlen
+        self.rlen = rlen
+        self._writeinfo(name, finfo)
+        self.state = _DID_HEADER
+
+    def _writeinfo(self, name, finfo):
+        nl = len(name)
+        if nl > 63:
+            raise Error, 'Filename too long'
+        d = chr(nl) + name + '\0'
+        d2 = finfo.Type + finfo.Creator
+
+        # Force all structs to be packed with big-endian
+        d3 = struct.pack('>h', finfo.Flags)
+        d4 = struct.pack('>ii', self.dlen, self.rlen)
+        info = d + d2 + d3 + d4
+        self._write(info)
+        self._writecrc()
+
+    def _write(self, data):
+        self.crc = binascii.crc_hqx(data, self.crc)
+        self.ofp.write(data)
+
+    def _writecrc(self):
+        # XXXX Should this be here??
+        # self.crc = binascii.crc_hqx('\0\0', self.crc)
+        if self.crc < 0:
+            fmt = '>h'
+        else:
+            fmt = '>H'
+        self.ofp.write(struct.pack(fmt, self.crc))
+        self.crc = 0
+
+    def write(self, data):
+        if self.state != _DID_HEADER:
+            raise Error, 'Writing data at the wrong time'
+        self.dlen = self.dlen - len(data)
+        self._write(data)
+
+    def close_data(self):
+        if self.dlen != 0:
+            raise Error, 'Incorrect data size, diff=%r' % (self.rlen,)
+        self._writecrc()
+        self.state = _DID_DATA
+
+    def write_rsrc(self, data):
+        if self.state < _DID_DATA:
+            self.close_data()
+        if self.state != _DID_DATA:
+            raise Error, 'Writing resource data at the wrong time'
+        self.rlen = self.rlen - len(data)
+        self._write(data)
+
+    def close(self):
+        if self.state < _DID_DATA:
+            self.close_data()
+        if self.state != _DID_DATA:
+            raise Error, 'Close at the wrong time'
+        if self.rlen != 0:
+            raise Error, \
+                  "Incorrect resource-datasize, diff=%r" % (self.rlen,)
+        self._writecrc()
+        self.ofp.close()
+        self.state = None
+        del self.ofp
+
+def binhex(inp, out):
+    """(infilename, outfilename) - Create binhex-encoded copy of a file"""
+    finfo = getfileinfo(inp)
+    ofp = BinHex(finfo, out)
+
+    ifp = open(inp, 'rb')
+    # XXXX Do textfile translation on non-mac systems
+    while 1:
+        d = ifp.read(128000)
+        if not d: break
+        ofp.write(d)
+    ofp.close_data()
+    ifp.close()
+
+    ifp = openrsrc(inp, 'rb')
+    while 1:
+        d = ifp.read(128000)
+        if not d: break
+        ofp.write_rsrc(d)
+    ofp.close()
+    ifp.close()
+
+class _Hqxdecoderengine:
+    """Read data via the decoder in 4-byte chunks"""
+
+    def __init__(self, ifp):
+        self.ifp = ifp
+        self.eof = 0
+
+    def read(self, totalwtd):
+        """Read at least wtd bytes (or until EOF)"""
+        decdata = ''
+        wtd = totalwtd
+        #
+        # The loop here is convoluted, since we don't really now how
+        # much to decode: there may be newlines in the incoming data.
+        while wtd > 0:
+            if self.eof: return decdata
+            wtd = ((wtd+2)//3)*4
+            data = self.ifp.read(wtd)
+            #
+            # Next problem: there may not be a complete number of
+            # bytes in what we pass to a2b. Solve by yet another
+            # loop.
+            #
+            while 1:
+                try:
+                    decdatacur, self.eof = \
+                            binascii.a2b_hqx(data)
+                    break
+                except binascii.Incomplete:
+                    pass
+                newdata = self.ifp.read(1)
+                if not newdata:
+                    raise Error, \
+                          'Premature EOF on binhex file'
+                data = data + newdata
+            decdata = decdata + decdatacur
+            wtd = totalwtd - len(decdata)
+            if not decdata and not self.eof:
+                raise Error, 'Premature EOF on binhex file'
+        return decdata
+
+    def close(self):
+        self.ifp.close()
+
+class _Rledecoderengine:
+    """Read data via the RLE-coder"""
+
+    def __init__(self, ifp):
+        self.ifp = ifp
+        self.pre_buffer = ''
+        self.post_buffer = ''
+        self.eof = 0
+
+    def read(self, wtd):
+        if wtd > len(self.post_buffer):
+            self._fill(wtd-len(self.post_buffer))
+        rv = self.post_buffer[:wtd]
+        self.post_buffer = self.post_buffer[wtd:]
+        return rv
+
+    def _fill(self, wtd):
+        self.pre_buffer = self.pre_buffer + self.ifp.read(wtd+4)
+        if self.ifp.eof:
+            self.post_buffer = self.post_buffer + \
+                binascii.rledecode_hqx(self.pre_buffer)
+            self.pre_buffer = ''
+            return
+
+        #
+        # Obfuscated code ahead. We have to take care that we don't
+        # end up with an orphaned RUNCHAR later on. So, we keep a couple
+        # of bytes in the buffer, depending on what the end of
+        # the buffer looks like:
+        # '\220\0\220' - Keep 3 bytes: repeated \220 (escaped as \220\0)
+        # '?\220' - Keep 2 bytes: repeated something-else
+        # '\220\0' - Escaped \220: Keep 2 bytes.
+        # '?\220?' - Complete repeat sequence: decode all
+        # otherwise: keep 1 byte.
+        #
+        mark = len(self.pre_buffer)
+        if self.pre_buffer[-3:] == RUNCHAR + '\0' + RUNCHAR:
+            mark = mark - 3
+        elif self.pre_buffer[-1] == RUNCHAR:
+            mark = mark - 2
+        elif self.pre_buffer[-2:] == RUNCHAR + '\0':
+            mark = mark - 2
+        elif self.pre_buffer[-2] == RUNCHAR:
+            pass # Decode all
+        else:
+            mark = mark - 1
+
+        self.post_buffer = self.post_buffer + \
+            binascii.rledecode_hqx(self.pre_buffer[:mark])
+        self.pre_buffer = self.pre_buffer[mark:]
+
+    def close(self):
+        self.ifp.close()
+
+class HexBin:
+    def __init__(self, ifp):
+        if type(ifp) == type(''):
+            ifp = open(ifp)
+        #
+        # Find initial colon.
+        #
+        while 1:
+            ch = ifp.read(1)
+            if not ch:
+                raise Error, "No binhex data found"
+            # Cater for \r\n terminated lines (which show up as \n\r, hence
+            # all lines start with \r)
+            if ch == '\r':
+                continue
+            if ch == ':':
+                break
+            if ch != '\n':
+                dummy = ifp.readline()
+
+        hqxifp = _Hqxdecoderengine(ifp)
+        self.ifp = _Rledecoderengine(hqxifp)
+        self.crc = 0
+        self._readheader()
+
+    def _read(self, len):
+        data = self.ifp.read(len)
+        self.crc = binascii.crc_hqx(data, self.crc)
+        return data
+
+    def _checkcrc(self):
+        filecrc = struct.unpack('>h', self.ifp.read(2))[0] & 0xffff
+        #self.crc = binascii.crc_hqx('\0\0', self.crc)
+        # XXXX Is this needed??
+        self.crc = self.crc & 0xffff
+        if filecrc != self.crc:
+            raise Error, 'CRC error, computed %x, read %x' \
+                  %(self.crc, filecrc)
+        self.crc = 0
+
+    def _readheader(self):
+        len = self._read(1)
+        fname = self._read(ord(len))
+        rest = self._read(1+4+4+2+4+4)
+        self._checkcrc()
+
+        type = rest[1:5]
+        creator = rest[5:9]
+        flags = struct.unpack('>h', rest[9:11])[0]
+        self.dlen = struct.unpack('>l', rest[11:15])[0]
+        self.rlen = struct.unpack('>l', rest[15:19])[0]
+
+        self.FName = fname
+        self.FInfo = FInfo()
+        self.FInfo.Creator = creator
+        self.FInfo.Type = type
+        self.FInfo.Flags = flags
+
+        self.state = _DID_HEADER
+
+    def read(self, *n):
+        if self.state != _DID_HEADER:
+            raise Error, 'Read data at wrong time'
+        if n:
+            n = n[0]
+            n = min(n, self.dlen)
+        else:
+            n = self.dlen
+        rv = ''
+        while len(rv) < n:
+            rv = rv + self._read(n-len(rv))
+        self.dlen = self.dlen - n
+        return rv
+
+    def close_data(self):
+        if self.state != _DID_HEADER:
+            raise Error, 'close_data at wrong time'
+        if self.dlen:
+            dummy = self._read(self.dlen)
+        self._checkcrc()
+        self.state = _DID_DATA
+
+    def read_rsrc(self, *n):
+        if self.state == _DID_HEADER:
+            self.close_data()
+        if self.state != _DID_DATA:
+            raise Error, 'Read resource data at wrong time'
+        if n:
+            n = n[0]
+            n = min(n, self.rlen)
+        else:
+            n = self.rlen
+        self.rlen = self.rlen - n
+        return self._read(n)
+
+    def close(self):
+        if self.rlen:
+            dummy = self.read_rsrc(self.rlen)
+        self._checkcrc()
+        self.state = _DID_RSRC
+        self.ifp.close()
+
+def hexbin(inp, out):
+    """(infilename, outfilename) - Decode binhexed file"""
+    ifp = HexBin(inp)
+    finfo = ifp.FInfo
+    if not out:
+        out = ifp.FName
+    if os.name == 'mac':
+        ofss = FSSpec(out)
+        out = ofss.as_pathname()
+
+    ofp = open(out, 'wb')
+    # XXXX Do translation on non-mac systems
+    while 1:
+        d = ifp.read(128000)
+        if not d: break
+        ofp.write(d)
+    ofp.close()
+    ifp.close_data()
+
+    d = ifp.read_rsrc(128000)
+    if d:
+        ofp = openrsrc(out, 'wb')
+        ofp.write(d)
+        while 1:
+            d = ifp.read_rsrc(128000)
+            if not d: break
+            ofp.write(d)
+        ofp.close()
+
+    if os.name == 'mac':
+        nfinfo = ofss.GetFInfo()
+        nfinfo.Creator = finfo.Creator
+        nfinfo.Type = finfo.Type
+        nfinfo.Flags = finfo.Flags
+        ofss.SetFInfo(nfinfo)
+
+    ifp.close()
+
+def _test():
+    if os.name == 'mac':
+        import macfs
+        fss, ok = macfs.PromptGetFile('File to convert:')
+        if not ok:
+            sys.exit(0)
+        fname = fss.as_pathname()
+    else:
+        fname = sys.argv[1]
+    binhex(fname, fname+'.hqx')
+    hexbin(fname+'.hqx', fname+'.viahqx')
+    #hexbin(fname, fname+'.unpacked')
+    sys.exit(1)
+
+if __name__ == '__main__':
+    _test()

Added: vendor/Python/current/Lib/bisect.py
===================================================================
--- vendor/Python/current/Lib/bisect.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/bisect.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,84 @@
+"""Bisection algorithms."""
+
+def insort_right(a, x, lo=0, hi=None):
+    """Insert item x in list a, and keep it sorted assuming a is sorted.
+
+    If x is already in a, insert it to the right of the rightmost x.
+
+    Optional args lo (default 0) and hi (default len(a)) bound the
+    slice of a to be searched.
+    """
+
+    if hi is None:
+        hi = len(a)
+    while lo < hi:
+        mid = (lo+hi)//2
+        if x < a[mid]: hi = mid
+        else: lo = mid+1
+    a.insert(lo, x)
+
+insort = insort_right   # backward compatibility
+
+def bisect_right(a, x, lo=0, hi=None):
+    """Return the index where to insert item x in list a, assuming a is sorted.
+
+    The return value i is such that all e in a[:i] have e <= x, and all e in
+    a[i:] have e > x.  So if x already appears in the list, a.insert(x) will
+    insert just after the rightmost x already there.
+
+    Optional args lo (default 0) and hi (default len(a)) bound the
+    slice of a to be searched.
+    """
+
+    if hi is None:
+        hi = len(a)
+    while lo < hi:
+        mid = (lo+hi)//2
+        if x < a[mid]: hi = mid
+        else: lo = mid+1
+    return lo
+
+bisect = bisect_right   # backward compatibility
+
+def insort_left(a, x, lo=0, hi=None):
+    """Insert item x in list a, and keep it sorted assuming a is sorted.
+
+    If x is already in a, insert it to the left of the leftmost x.
+
+    Optional args lo (default 0) and hi (default len(a)) bound the
+    slice of a to be searched.
+    """
+
+    if hi is None:
+        hi = len(a)
+    while lo < hi:
+        mid = (lo+hi)//2
+        if a[mid] < x: lo = mid+1
+        else: hi = mid
+    a.insert(lo, x)
+
+
+def bisect_left(a, x, lo=0, hi=None):
+    """Return the index where to insert item x in list a, assuming a is sorted.
+
+    The return value i is such that all e in a[:i] have e < x, and all e in
+    a[i:] have e >= x.  So if x already appears in the list, a.insert(x) will
+    insert just before the leftmost x already there.
+
+    Optional args lo (default 0) and hi (default len(a)) bound the
+    slice of a to be searched.
+    """
+
+    if hi is None:
+        hi = len(a)
+    while lo < hi:
+        mid = (lo+hi)//2
+        if a[mid] < x: lo = mid+1
+        else: hi = mid
+    return lo
+
+# Overwrite above definitions with a fast C implementation
+try:
+    from _bisect import bisect_right, bisect_left, insort_left, insort_right, insort, bisect
+except ImportError:
+    pass

Added: vendor/Python/current/Lib/bsddb/__init__.py
===================================================================
--- vendor/Python/current/Lib/bsddb/__init__.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/bsddb/__init__.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,397 @@
+#----------------------------------------------------------------------
+#  Copyright (c) 1999-2001, Digital Creations, Fredericksburg, VA, USA
+#  and Andrew Kuchling. All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are
+#  met:
+#
+#    o Redistributions of source code must retain the above copyright
+#      notice, this list of conditions, and the disclaimer that follows.
+#
+#    o Redistributions in binary form must reproduce the above copyright
+#      notice, this list of conditions, and the following disclaimer in
+#      the documentation and/or other materials provided with the
+#      distribution.
+#
+#    o Neither the name of Digital Creations nor the names of its
+#      contributors may be used to endorse or promote products derived
+#      from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS AND CONTRIBUTORS *AS
+#  IS* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+#  TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+#  PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL DIGITAL
+#  CREATIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+#  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+#  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+#  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+#  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+#  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+#  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+#  DAMAGE.
+#----------------------------------------------------------------------
+
+
+"""Support for BerkeleyDB 3.3 through 4.4 with a simple interface.
+
+For the full featured object oriented interface use the bsddb.db module
+instead.  It mirrors the Sleepycat BerkeleyDB C API.
+"""
+
+try:
+    if __name__ == 'bsddb3':
+        # import _pybsddb binary as it should be the more recent version from
+        # a standalone pybsddb addon package than the version included with
+        # python as bsddb._bsddb.
+        import _pybsddb
+        _bsddb = _pybsddb
+        from bsddb3.dbutils import DeadlockWrap as _DeadlockWrap
+    else:
+        import _bsddb
+        from bsddb.dbutils import DeadlockWrap as _DeadlockWrap
+except ImportError:
+    # Remove ourselves from sys.modules
+    import sys
+    del sys.modules[__name__]
+    raise
+
+# bsddb3 calls it db, but provide _db for backwards compatibility
+db = _db = _bsddb
+__version__ = db.__version__
+
+error = db.DBError  # So bsddb.error will mean something...
+
+#----------------------------------------------------------------------
+
+import sys, os
+
+# for backwards compatibility with python versions older than 2.3, the
+# iterator interface is dynamically defined and added using a mixin
+# class.  old python can't tokenize it due to the yield keyword.
+if sys.version >= '2.3':
+    import UserDict
+    from weakref import ref
+    exec """
+class _iter_mixin(UserDict.DictMixin):
+    def _make_iter_cursor(self):
+        cur = _DeadlockWrap(self.db.cursor)
+        key = id(cur)
+        self._cursor_refs[key] = ref(cur, self._gen_cref_cleaner(key))
+        return cur
+
+    def _gen_cref_cleaner(self, key):
+        # use generate the function for the weakref callback here
+        # to ensure that we do not hold a strict reference to cur
+        # in the callback.
+        return lambda ref: self._cursor_refs.pop(key, None)
+
+    def __iter__(self):
+        try:
+            cur = self._make_iter_cursor()
+
+            # FIXME-20031102-greg: race condition.  cursor could
+            # be closed by another thread before this call.
+
+            # since we're only returning keys, we call the cursor
+            # methods with flags=0, dlen=0, dofs=0
+            key = _DeadlockWrap(cur.first, 0,0,0)[0]
+            yield key
+
+            next = cur.next
+            while 1:
+                try:
+                    key = _DeadlockWrap(next, 0,0,0)[0]
+                    yield key
+                except _bsddb.DBCursorClosedError:
+                    cur = self._make_iter_cursor()
+                    # FIXME-20031101-greg: race condition.  cursor could
+                    # be closed by another thread before this call.
+                    _DeadlockWrap(cur.set, key,0,0,0)
+                    next = cur.next
+        except _bsddb.DBNotFoundError:
+            return
+        except _bsddb.DBCursorClosedError:
+            # the database was modified during iteration.  abort.
+            return
+
+    def iteritems(self):
+        if not self.db:
+            return
+        try:
+            cur = self._make_iter_cursor()
+
+            # FIXME-20031102-greg: race condition.  cursor could
+            # be closed by another thread before this call.
+
+            kv = _DeadlockWrap(cur.first)
+            key = kv[0]
+            yield kv
+
+            next = cur.next
+            while 1:
+                try:
+                    kv = _DeadlockWrap(next)
+                    key = kv[0]
+                    yield kv
+                except _bsddb.DBCursorClosedError:
+                    cur = self._make_iter_cursor()
+                    # FIXME-20031101-greg: race condition.  cursor could
+                    # be closed by another thread before this call.
+                    _DeadlockWrap(cur.set, key,0,0,0)
+                    next = cur.next
+        except _bsddb.DBNotFoundError:
+            return
+        except _bsddb.DBCursorClosedError:
+            # the database was modified during iteration.  abort.
+            return
+"""
+else:
+    class _iter_mixin: pass
+
+
+class _DBWithCursor(_iter_mixin):
+    """
+    A simple wrapper around DB that makes it look like the bsddbobject in
+    the old module.  It uses a cursor as needed to provide DB traversal.
+    """
+    def __init__(self, db):
+        self.db = db
+        self.db.set_get_returns_none(0)
+
+        # FIXME-20031101-greg: I believe there is still the potential
+        # for deadlocks in a multithreaded environment if someone
+        # attempts to use the any of the cursor interfaces in one
+        # thread while doing a put or delete in another thread.  The
+        # reason is that _checkCursor and _closeCursors are not atomic
+        # operations.  Doing our own locking around self.dbc,
+        # self.saved_dbc_key and self._cursor_refs could prevent this.
+        # TODO: A test case demonstrating the problem needs to be written.
+
+        # self.dbc is a DBCursor object used to implement the
+        # first/next/previous/last/set_location methods.
+        self.dbc = None
+        self.saved_dbc_key = None
+
+        # a collection of all DBCursor objects currently allocated
+        # by the _iter_mixin interface.
+        self._cursor_refs = {}
+
+    def __del__(self):
+        self.close()
+
+    def _checkCursor(self):
+        if self.dbc is None:
+            self.dbc = _DeadlockWrap(self.db.cursor)
+            if self.saved_dbc_key is not None:
+                _DeadlockWrap(self.dbc.set, self.saved_dbc_key)
+                self.saved_dbc_key = None
+
+    # This method is needed for all non-cursor DB calls to avoid
+    # BerkeleyDB deadlocks (due to being opened with DB_INIT_LOCK
+    # and DB_THREAD to be thread safe) when intermixing database
+    # operations that use the cursor internally with those that don't.
+    def _closeCursors(self, save=1):
+        if self.dbc:
+            c = self.dbc
+            self.dbc = None
+            if save:
+                try:
+                    self.saved_dbc_key = _DeadlockWrap(c.current, 0,0,0)[0]
+                except db.DBError:
+                    pass
+            _DeadlockWrap(c.close)
+            del c
+        for cref in self._cursor_refs.values():
+            c = cref()
+            if c is not None:
+                _DeadlockWrap(c.close)
+
+    def _checkOpen(self):
+        if self.db is None:
+            raise error, "BSDDB object has already been closed"
+
+    def isOpen(self):
+        return self.db is not None
+
+    def __len__(self):
+        self._checkOpen()
+        return _DeadlockWrap(lambda: len(self.db))  # len(self.db)
+
+    def __getitem__(self, key):
+        self._checkOpen()
+        return _DeadlockWrap(lambda: self.db[key])  # self.db[key]
+
+    def __setitem__(self, key, value):
+        self._checkOpen()
+        self._closeCursors()
+        def wrapF():
+            self.db[key] = value
+        _DeadlockWrap(wrapF)  # self.db[key] = value
+
+    def __delitem__(self, key):
+        self._checkOpen()
+        self._closeCursors()
+        def wrapF():
+            del self.db[key]
+        _DeadlockWrap(wrapF)  # del self.db[key]
+
+    def close(self):
+        self._closeCursors(save=0)
+        if self.dbc is not None:
+            _DeadlockWrap(self.dbc.close)
+        v = 0
+        if self.db is not None:
+            v = _DeadlockWrap(self.db.close)
+        self.dbc = None
+        self.db = None
+        return v
+
+    def keys(self):
+        self._checkOpen()
+        return _DeadlockWrap(self.db.keys)
+
+    def has_key(self, key):
+        self._checkOpen()
+        return _DeadlockWrap(self.db.has_key, key)
+
+    def set_location(self, key):
+        self._checkOpen()
+        self._checkCursor()
+        return _DeadlockWrap(self.dbc.set_range, key)
+
+    def next(self):
+        self._checkOpen()
+        self._checkCursor()
+        rv = _DeadlockWrap(self.dbc.next)
+        return rv
+
+    def previous(self):
+        self._checkOpen()
+        self._checkCursor()
+        rv = _DeadlockWrap(self.dbc.prev)
+        return rv
+
+    def first(self):
+        self._checkOpen()
+        self._checkCursor()
+        rv = _DeadlockWrap(self.dbc.first)
+        return rv
+
+    def last(self):
+        self._checkOpen()
+        self._checkCursor()
+        rv = _DeadlockWrap(self.dbc.last)
+        return rv
+
+    def sync(self):
+        self._checkOpen()
+        return _DeadlockWrap(self.db.sync)
+
+
+#----------------------------------------------------------------------
+# Compatibility object factory functions
+
+def hashopen(file, flag='c', mode=0666, pgsize=None, ffactor=None, nelem=None,
+            cachesize=None, lorder=None, hflags=0):
+
+    flags = _checkflag(flag, file)
+    e = _openDBEnv(cachesize)
+    d = db.DB(e)
+    d.set_flags(hflags)
+    if pgsize is not None:    d.set_pagesize(pgsize)
+    if lorder is not None:    d.set_lorder(lorder)
+    if ffactor is not None:   d.set_h_ffactor(ffactor)
+    if nelem is not None:     d.set_h_nelem(nelem)
+    d.open(file, db.DB_HASH, flags, mode)
+    return _DBWithCursor(d)
+
+#----------------------------------------------------------------------
+
+def btopen(file, flag='c', mode=0666,
+            btflags=0, cachesize=None, maxkeypage=None, minkeypage=None,
+            pgsize=None, lorder=None):
+
+    flags = _checkflag(flag, file)
+    e = _openDBEnv(cachesize)
+    d = db.DB(e)
+    if pgsize is not None: d.set_pagesize(pgsize)
+    if lorder is not None: d.set_lorder(lorder)
+    d.set_flags(btflags)
+    if minkeypage is not None: d.set_bt_minkey(minkeypage)
+    if maxkeypage is not None: d.set_bt_maxkey(maxkeypage)
+    d.open(file, db.DB_BTREE, flags, mode)
+    return _DBWithCursor(d)
+
+#----------------------------------------------------------------------
+
+
+def rnopen(file, flag='c', mode=0666,
+            rnflags=0, cachesize=None, pgsize=None, lorder=None,
+            rlen=None, delim=None, source=None, pad=None):
+
+    flags = _checkflag(flag, file)
+    e = _openDBEnv(cachesize)
+    d = db.DB(e)
+    if pgsize is not None: d.set_pagesize(pgsize)
+    if lorder is not None: d.set_lorder(lorder)
+    d.set_flags(rnflags)
+    if delim is not None: d.set_re_delim(delim)
+    if rlen is not None: d.set_re_len(rlen)
+    if source is not None: d.set_re_source(source)
+    if pad is not None: d.set_re_pad(pad)
+    d.open(file, db.DB_RECNO, flags, mode)
+    return _DBWithCursor(d)
+
+#----------------------------------------------------------------------
+
+def _openDBEnv(cachesize):
+    e = db.DBEnv()
+    if cachesize is not None:
+        if cachesize >= 20480:
+            e.set_cachesize(0, cachesize)
+        else:
+            raise error, "cachesize must be >= 20480"
+    e.set_lk_detect(db.DB_LOCK_DEFAULT)
+    e.open('.', db.DB_PRIVATE | db.DB_CREATE | db.DB_THREAD | db.DB_INIT_LOCK | db.DB_INIT_MPOOL)
+    return e
+
+def _checkflag(flag, file):
+    if flag == 'r':
+        flags = db.DB_RDONLY
+    elif flag == 'rw':
+        flags = 0
+    elif flag == 'w':
+        flags =  db.DB_CREATE
+    elif flag == 'c':
+        flags =  db.DB_CREATE
+    elif flag == 'n':
+        flags = db.DB_CREATE
+        #flags = db.DB_CREATE | db.DB_TRUNCATE
+        # we used db.DB_TRUNCATE flag for this before but BerkeleyDB
+        # 4.2.52 changed to disallowed truncate with txn environments.
+        if file is not None and os.path.isfile(file):
+            os.unlink(file)
+    else:
+        raise error, "flags should be one of 'r', 'w', 'c' or 'n'"
+    return flags | db.DB_THREAD
+
+#----------------------------------------------------------------------
+
+
+# This is a silly little hack that allows apps to continue to use the
+# DB_THREAD flag even on systems without threads without freaking out
+# BerkeleyDB.
+#
+# This assumes that if Python was built with thread support then
+# BerkeleyDB was too.
+
+try:
+    import thread
+    del thread
+    if db.version() < (3, 3, 0):
+        db.DB_THREAD = 0
+except ImportError:
+    db.DB_THREAD = 0
+
+#----------------------------------------------------------------------

Added: vendor/Python/current/Lib/bsddb/db.py
===================================================================
--- vendor/Python/current/Lib/bsddb/db.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/bsddb/db.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,51 @@
+#----------------------------------------------------------------------
+#  Copyright (c) 1999-2001, Digital Creations, Fredericksburg, VA, USA
+#  and Andrew Kuchling. All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are
+#  met:
+#
+#    o Redistributions of source code must retain the above copyright
+#      notice, this list of conditions, and the disclaimer that follows.
+#
+#    o Redistributions in binary form must reproduce the above copyright
+#      notice, this list of conditions, and the following disclaimer in
+#      the documentation and/or other materials provided with the
+#      distribution.
+#
+#    o Neither the name of Digital Creations nor the names of its
+#      contributors may be used to endorse or promote products derived
+#      from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS AND CONTRIBUTORS *AS
+#  IS* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+#  TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+#  PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL DIGITAL
+#  CREATIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+#  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+#  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+#  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+#  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+#  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+#  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+#  DAMAGE.
+#----------------------------------------------------------------------
+
+
+# This module is just a placeholder for possible future expansion, in
+# case we ever want to augment the stuff in _db in any way.  For now
+# it just simply imports everything from _db.
+
+if __name__.startswith('bsddb3.'):
+    # import _pybsddb binary as it should be the more recent version from
+    # a standalone pybsddb addon package than the version included with
+    # python as bsddb._bsddb.
+    from _pybsddb import *
+    from _pybsddb import __version__
+else:
+    from _bsddb import *
+    from _bsddb import __version__
+
+if version() < (3, 2, 0):
+    raise ImportError, "correct BerkeleyDB symbols not found.  Perhaps python was statically linked with an older version?"

Added: vendor/Python/current/Lib/bsddb/dbobj.py
===================================================================
--- vendor/Python/current/Lib/bsddb/dbobj.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/bsddb/dbobj.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,254 @@
+#-------------------------------------------------------------------------
+#  This file contains real Python object wrappers for DB and DBEnv
+#  C "objects" that can be usefully subclassed.  The previous SWIG
+#  based interface allowed this thanks to SWIG's shadow classes.
+#   --  Gregory P. Smith
+#-------------------------------------------------------------------------
+#
+# (C) Copyright 2001  Autonomous Zone Industries
+#
+# License:  This is free software.  You may use this software for any
+#           purpose including modification/redistribution, so long as
+#           this header remains intact and that you do not claim any
+#           rights of ownership or authorship of this software.  This
+#           software has been tested, but no warranty is expressed or
+#           implied.
+#
+
+#
+# TODO it would be *really nice* to have an automatic shadow class populator
+# so that new methods don't need to be added  here manually after being
+# added to _bsddb.c.
+#
+
+import db
+
+try:
+    from UserDict import DictMixin
+except ImportError:
+    # DictMixin is new in Python 2.3
+    class DictMixin: pass
+
+class DBEnv:
+    def __init__(self, *args, **kwargs):
+        self._cobj = apply(db.DBEnv, args, kwargs)
+
+    def close(self, *args, **kwargs):
+        return apply(self._cobj.close, args, kwargs)
+    def open(self, *args, **kwargs):
+        return apply(self._cobj.open, args, kwargs)
+    def remove(self, *args, **kwargs):
+        return apply(self._cobj.remove, args, kwargs)
+    def set_shm_key(self, *args, **kwargs):
+        return apply(self._cobj.set_shm_key, args, kwargs)
+    def set_cachesize(self, *args, **kwargs):
+        return apply(self._cobj.set_cachesize, args, kwargs)
+    def set_data_dir(self, *args, **kwargs):
+        return apply(self._cobj.set_data_dir, args, kwargs)
+    def set_flags(self, *args, **kwargs):
+        return apply(self._cobj.set_flags, args, kwargs)
+    def set_lg_bsize(self, *args, **kwargs):
+        return apply(self._cobj.set_lg_bsize, args, kwargs)
+    def set_lg_dir(self, *args, **kwargs):
+        return apply(self._cobj.set_lg_dir, args, kwargs)
+    def set_lg_max(self, *args, **kwargs):
+        return apply(self._cobj.set_lg_max, args, kwargs)
+    def set_lk_detect(self, *args, **kwargs):
+        return apply(self._cobj.set_lk_detect, args, kwargs)
+    if db.version() < (4,5):
+        def set_lk_max(self, *args, **kwargs):
+            return apply(self._cobj.set_lk_max, args, kwargs)
+    def set_lk_max_locks(self, *args, **kwargs):
+        return apply(self._cobj.set_lk_max_locks, args, kwargs)
+    def set_lk_max_lockers(self, *args, **kwargs):
+        return apply(self._cobj.set_lk_max_lockers, args, kwargs)
+    def set_lk_max_objects(self, *args, **kwargs):
+        return apply(self._cobj.set_lk_max_objects, args, kwargs)
+    def set_mp_mmapsize(self, *args, **kwargs):
+        return apply(self._cobj.set_mp_mmapsize, args, kwargs)
+    def set_timeout(self, *args, **kwargs):
+        return apply(self._cobj.set_timeout, args, kwargs)
+    def set_tmp_dir(self, *args, **kwargs):
+        return apply(self._cobj.set_tmp_dir, args, kwargs)
+    def txn_begin(self, *args, **kwargs):
+        return apply(self._cobj.txn_begin, args, kwargs)
+    def txn_checkpoint(self, *args, **kwargs):
+        return apply(self._cobj.txn_checkpoint, args, kwargs)
+    def txn_stat(self, *args, **kwargs):
+        return apply(self._cobj.txn_stat, args, kwargs)
+    def set_tx_max(self, *args, **kwargs):
+        return apply(self._cobj.set_tx_max, args, kwargs)
+    def set_tx_timestamp(self, *args, **kwargs):
+        return apply(self._cobj.set_tx_timestamp, args, kwargs)
+    def lock_detect(self, *args, **kwargs):
+        return apply(self._cobj.lock_detect, args, kwargs)
+    def lock_get(self, *args, **kwargs):
+        return apply(self._cobj.lock_get, args, kwargs)
+    def lock_id(self, *args, **kwargs):
+        return apply(self._cobj.lock_id, args, kwargs)
+    def lock_put(self, *args, **kwargs):
+        return apply(self._cobj.lock_put, args, kwargs)
+    def lock_stat(self, *args, **kwargs):
+        return apply(self._cobj.lock_stat, args, kwargs)
+    def log_archive(self, *args, **kwargs):
+        return apply(self._cobj.log_archive, args, kwargs)
+
+    def set_get_returns_none(self, *args, **kwargs):
+        return apply(self._cobj.set_get_returns_none, args, kwargs)
+
+    if db.version() >= (4,0):
+        def log_stat(self, *args, **kwargs):
+            return apply(self._cobj.log_stat, args, kwargs)
+
+    if db.version() >= (4,1):
+        def dbremove(self, *args, **kwargs):
+            return apply(self._cobj.dbremove, args, kwargs)
+        def dbrename(self, *args, **kwargs):
+            return apply(self._cobj.dbrename, args, kwargs)
+        def set_encrypt(self, *args, **kwargs):
+            return apply(self._cobj.set_encrypt, args, kwargs)
+
+    if db.version() >= (4,4):
+        def lsn_reset(self, *args, **kwargs):
+            return apply(self._cobj.lsn_reset, args, kwargs)
+
+
+class DB(DictMixin):
+    def __init__(self, dbenv, *args, **kwargs):
+        # give it the proper DBEnv C object that its expecting
+        self._cobj = apply(db.DB, (dbenv._cobj,) + args, kwargs)
+
+    # TODO are there other dict methods that need to be overridden?
+    def __len__(self):
+        return len(self._cobj)
+    def __getitem__(self, arg):
+        return self._cobj[arg]
+    def __setitem__(self, key, value):
+        self._cobj[key] = value
+    def __delitem__(self, arg):
+        del self._cobj[arg]
+
+    def append(self, *args, **kwargs):
+        return apply(self._cobj.append, args, kwargs)
+    def associate(self, *args, **kwargs):
+        return apply(self._cobj.associate, args, kwargs)
+    def close(self, *args, **kwargs):
+        return apply(self._cobj.close, args, kwargs)
+    def consume(self, *args, **kwargs):
+        return apply(self._cobj.consume, args, kwargs)
+    def consume_wait(self, *args, **kwargs):
+        return apply(self._cobj.consume_wait, args, kwargs)
+    def cursor(self, *args, **kwargs):
+        return apply(self._cobj.cursor, args, kwargs)
+    def delete(self, *args, **kwargs):
+        return apply(self._cobj.delete, args, kwargs)
+    def fd(self, *args, **kwargs):
+        return apply(self._cobj.fd, args, kwargs)
+    def get(self, *args, **kwargs):
+        return apply(self._cobj.get, args, kwargs)
+    def pget(self, *args, **kwargs):
+        return apply(self._cobj.pget, args, kwargs)
+    def get_both(self, *args, **kwargs):
+        return apply(self._cobj.get_both, args, kwargs)
+    def get_byteswapped(self, *args, **kwargs):
+        return apply(self._cobj.get_byteswapped, args, kwargs)
+    def get_size(self, *args, **kwargs):
+        return apply(self._cobj.get_size, args, kwargs)
+    def get_type(self, *args, **kwargs):
+        return apply(self._cobj.get_type, args, kwargs)
+    def join(self, *args, **kwargs):
+        return apply(self._cobj.join, args, kwargs)
+    def key_range(self, *args, **kwargs):
+        return apply(self._cobj.key_range, args, kwargs)
+    def has_key(self, *args, **kwargs):
+        return apply(self._cobj.has_key, args, kwargs)
+    def items(self, *args, **kwargs):
+        return apply(self._cobj.items, args, kwargs)
+    def keys(self, *args, **kwargs):
+        return apply(self._cobj.keys, args, kwargs)
+    def open(self, *args, **kwargs):
+        return apply(self._cobj.open, args, kwargs)
+    def put(self, *args, **kwargs):
+        return apply(self._cobj.put, args, kwargs)
+    def remove(self, *args, **kwargs):
+        return apply(self._cobj.remove, args, kwargs)
+    def rename(self, *args, **kwargs):
+        return apply(self._cobj.rename, args, kwargs)
+    def set_bt_minkey(self, *args, **kwargs):
+        return apply(self._cobj.set_bt_minkey, args, kwargs)
+    def set_bt_compare(self, *args, **kwargs):
+        return apply(self._cobj.set_bt_compare, args, kwargs)
+    def set_cachesize(self, *args, **kwargs):
+        return apply(self._cobj.set_cachesize, args, kwargs)
+    def set_flags(self, *args, **kwargs):
+        return apply(self._cobj.set_flags, args, kwargs)
+    def set_h_ffactor(self, *args, **kwargs):
+        return apply(self._cobj.set_h_ffactor, args, kwargs)
+    def set_h_nelem(self, *args, **kwargs):
+        return apply(self._cobj.set_h_nelem, args, kwargs)
+    def set_lorder(self, *args, **kwargs):
+        return apply(self._cobj.set_lorder, args, kwargs)
+    def set_pagesize(self, *args, **kwargs):
+        return apply(self._cobj.set_pagesize, args, kwargs)
+    def set_re_delim(self, *args, **kwargs):
+        return apply(self._cobj.set_re_delim, args, kwargs)
+    def set_re_len(self, *args, **kwargs):
+        return apply(self._cobj.set_re_len, args, kwargs)
+    def set_re_pad(self, *args, **kwargs):
+        return apply(self._cobj.set_re_pad, args, kwargs)
+    def set_re_source(self, *args, **kwargs):
+        return apply(self._cobj.set_re_source, args, kwargs)
+    def set_q_extentsize(self, *args, **kwargs):
+        return apply(self._cobj.set_q_extentsize, args, kwargs)
+    def stat(self, *args, **kwargs):
+        return apply(self._cobj.stat, args, kwargs)
+    def sync(self, *args, **kwargs):
+        return apply(self._cobj.sync, args, kwargs)
+    def type(self, *args, **kwargs):
+        return apply(self._cobj.type, args, kwargs)
+    def upgrade(self, *args, **kwargs):
+        return apply(self._cobj.upgrade, args, kwargs)
+    def values(self, *args, **kwargs):
+        return apply(self._cobj.values, args, kwargs)
+    def verify(self, *args, **kwargs):
+        return apply(self._cobj.verify, args, kwargs)
+    def set_get_returns_none(self, *args, **kwargs):
+        return apply(self._cobj.set_get_returns_none, args, kwargs)
+
+    if db.version() >= (4,1):
+        def set_encrypt(self, *args, **kwargs):
+            return apply(self._cobj.set_encrypt, args, kwargs)
+
+
+class DBSequence:
+    def __init__(self, *args, **kwargs):
+        self._cobj = apply(db.DBSequence, args, kwargs)
+
+    def close(self, *args, **kwargs):
+        return apply(self._cobj.close, args, kwargs)
+    def get(self, *args, **kwargs):
+        return apply(self._cobj.get, args, kwargs)
+    def get_dbp(self, *args, **kwargs):
+        return apply(self._cobj.get_dbp, args, kwargs)
+    def get_key(self, *args, **kwargs):
+        return apply(self._cobj.get_key, args, kwargs)
+    def init_value(self, *args, **kwargs):
+        return apply(self._cobj.init_value, args, kwargs)
+    def open(self, *args, **kwargs):
+        return apply(self._cobj.open, args, kwargs)
+    def remove(self, *args, **kwargs):
+        return apply(self._cobj.remove, args, kwargs)
+    def stat(self, *args, **kwargs):
+        return apply(self._cobj.stat, args, kwargs)
+    def set_cachesize(self, *args, **kwargs):
+        return apply(self._cobj.set_cachesize, args, kwargs)
+    def set_flags(self, *args, **kwargs):
+        return apply(self._cobj.set_flags, args, kwargs)
+    def set_range(self, *args, **kwargs):
+        return apply(self._cobj.set_range, args, kwargs)
+    def get_cachesize(self, *args, **kwargs):
+        return apply(self._cobj.get_cachesize, args, kwargs)
+    def get_flags(self, *args, **kwargs):
+        return apply(self._cobj.get_flags, args, kwargs)
+    def get_range(self, *args, **kwargs):
+        return apply(self._cobj.get_range, args, kwargs)

Added: vendor/Python/current/Lib/bsddb/dbrecio.py
===================================================================
--- vendor/Python/current/Lib/bsddb/dbrecio.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/bsddb/dbrecio.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,190 @@
+
+"""
+File-like objects that read from or write to a bsddb record.
+
+This implements (nearly) all stdio methods.
+
+f = DBRecIO(db, key, txn=None)
+f.close()           # explicitly release resources held
+flag = f.isatty()   # always false
+pos = f.tell()      # get current position
+f.seek(pos)         # set current position
+f.seek(pos, mode)   # mode 0: absolute; 1: relative; 2: relative to EOF
+buf = f.read()      # read until EOF
+buf = f.read(n)     # read up to n bytes
+f.truncate([size])  # truncate file at to at most size (default: current pos)
+f.write(buf)        # write at current position
+f.writelines(list)  # for line in list: f.write(line)
+
+Notes:
+- fileno() is left unimplemented so that code which uses it triggers
+  an exception early.
+- There's a simple test set (see end of this file) - not yet updated
+  for DBRecIO.
+- readline() is not implemented yet.
+
+
+From:
+    Itamar Shtull-Trauring <itamar at maxnm.com>
+"""
+
+import errno
+import string
+
+class DBRecIO:
+    def __init__(self, db, key, txn=None):
+        self.db = db
+        self.key = key
+        self.txn = txn
+        self.len = None
+        self.pos = 0
+        self.closed = 0
+        self.softspace = 0
+
+    def close(self):
+        if not self.closed:
+            self.closed = 1
+            del self.db, self.txn
+
+    def isatty(self):
+        if self.closed:
+            raise ValueError, "I/O operation on closed file"
+        return 0
+
+    def seek(self, pos, mode = 0):
+        if self.closed:
+            raise ValueError, "I/O operation on closed file"
+        if mode == 1:
+            pos = pos + self.pos
+        elif mode == 2:
+            pos = pos + self.len
+        self.pos = max(0, pos)
+
+    def tell(self):
+        if self.closed:
+            raise ValueError, "I/O operation on closed file"
+        return self.pos
+
+    def read(self, n = -1):
+        if self.closed:
+            raise ValueError, "I/O operation on closed file"
+        if n < 0:
+            newpos = self.len
+        else:
+            newpos = min(self.pos+n, self.len)
+
+        dlen = newpos - self.pos
+
+        r = self.db.get(self.key, txn=self.txn, dlen=dlen, doff=self.pos)
+        self.pos = newpos
+        return r
+
+    __fixme = """
+    def readline(self, length=None):
+        if self.closed:
+            raise ValueError, "I/O operation on closed file"
+        if self.buflist:
+            self.buf = self.buf + string.joinfields(self.buflist, '')
+            self.buflist = []
+        i = string.find(self.buf, '\n', self.pos)
+        if i < 0:
+            newpos = self.len
+        else:
+            newpos = i+1
+        if length is not None:
+            if self.pos + length < newpos:
+                newpos = self.pos + length
+        r = self.buf[self.pos:newpos]
+        self.pos = newpos
+        return r
+
+    def readlines(self, sizehint = 0):
+        total = 0
+        lines = []
+        line = self.readline()
+        while line:
+            lines.append(line)
+            total += len(line)
+            if 0 < sizehint <= total:
+                break
+            line = self.readline()
+        return lines
+    """
+
+    def truncate(self, size=None):
+        if self.closed:
+            raise ValueError, "I/O operation on closed file"
+        if size is None:
+            size = self.pos
+        elif size < 0:
+            raise IOError(errno.EINVAL,
+                                      "Negative size not allowed")
+        elif size < self.pos:
+            self.pos = size
+        self.db.put(self.key, "", txn=self.txn, dlen=self.len-size, doff=size)
+
+    def write(self, s):
+        if self.closed:
+            raise ValueError, "I/O operation on closed file"
+        if not s: return
+        if self.pos > self.len:
+            self.buflist.append('\0'*(self.pos - self.len))
+            self.len = self.pos
+        newpos = self.pos + len(s)
+        self.db.put(self.key, s, txn=self.txn, dlen=len(s), doff=self.pos)
+        self.pos = newpos
+
+    def writelines(self, list):
+        self.write(string.joinfields(list, ''))
+
+    def flush(self):
+        if self.closed:
+            raise ValueError, "I/O operation on closed file"
+
+
+"""
+# A little test suite
+
+def _test():
+    import sys
+    if sys.argv[1:]:
+        file = sys.argv[1]
+    else:
+        file = '/etc/passwd'
+    lines = open(file, 'r').readlines()
+    text = open(file, 'r').read()
+    f = StringIO()
+    for line in lines[:-2]:
+        f.write(line)
+    f.writelines(lines[-2:])
+    if f.getvalue() != text:
+        raise RuntimeError, 'write failed'
+    length = f.tell()
+    print 'File length =', length
+    f.seek(len(lines[0]))
+    f.write(lines[1])
+    f.seek(0)
+    print 'First line =', repr(f.readline())
+    here = f.tell()
+    line = f.readline()
+    print 'Second line =', repr(line)
+    f.seek(-len(line), 1)
+    line2 = f.read(len(line))
+    if line != line2:
+        raise RuntimeError, 'bad result after seek back'
+    f.seek(len(line2), 1)
+    list = f.readlines()
+    line = list[-1]
+    f.seek(f.tell() - len(line))
+    line2 = f.read()
+    if line != line2:
+        raise RuntimeError, 'bad result after seek back from EOF'
+    print 'Read', len(list), 'more lines'
+    print 'File length =', f.tell()
+    if f.tell() != length:
+        raise RuntimeError, 'bad length'
+    f.close()
+
+if __name__ == '__main__':
+    _test()
+"""

Added: vendor/Python/current/Lib/bsddb/dbshelve.py
===================================================================
--- vendor/Python/current/Lib/bsddb/dbshelve.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/bsddb/dbshelve.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,299 @@
+#!/bin/env python
+#------------------------------------------------------------------------
+#           Copyright (c) 1997-2001 by Total Control Software
+#                         All Rights Reserved
+#------------------------------------------------------------------------
+#
+# Module Name:  dbShelve.py
+#
+# Description:  A reimplementation of the standard shelve.py that
+#               forces the use of cPickle, and DB.
+#
+# Creation Date:    11/3/97 3:39:04PM
+#
+# License:      This is free software.  You may use this software for any
+#               purpose including modification/redistribution, so long as
+#               this header remains intact and that you do not claim any
+#               rights of ownership or authorship of this software.  This
+#               software has been tested, but no warranty is expressed or
+#               implied.
+#
+# 13-Dec-2000:  Updated to be used with the new bsddb3 package.
+#               Added DBShelfCursor class.
+#
+#------------------------------------------------------------------------
+
+"""Manage shelves of pickled objects using bsddb database files for the
+storage.
+"""
+
+#------------------------------------------------------------------------
+
+import cPickle
+try:
+    from UserDict import DictMixin
+except ImportError:
+    # DictMixin is new in Python 2.3
+    class DictMixin: pass
+import db
+
+#------------------------------------------------------------------------
+
+
+def open(filename, flags=db.DB_CREATE, mode=0660, filetype=db.DB_HASH,
+         dbenv=None, dbname=None):
+    """
+    A simple factory function for compatibility with the standard
+    shleve.py module.  It can be used like this, where key is a string
+    and data is a pickleable object:
+
+        from bsddb import dbshelve
+        db = dbshelve.open(filename)
+
+        db[key] = data
+
+        db.close()
+    """
+    if type(flags) == type(''):
+        sflag = flags
+        if sflag == 'r':
+            flags = db.DB_RDONLY
+        elif sflag == 'rw':
+            flags = 0
+        elif sflag == 'w':
+            flags =  db.DB_CREATE
+        elif sflag == 'c':
+            flags =  db.DB_CREATE
+        elif sflag == 'n':
+            flags = db.DB_TRUNCATE | db.DB_CREATE
+        else:
+            raise db.DBError, "flags should be one of 'r', 'w', 'c' or 'n' or use the bsddb.db.DB_* flags"
+
+    d = DBShelf(dbenv)
+    d.open(filename, dbname, filetype, flags, mode)
+    return d
+
+#---------------------------------------------------------------------------
+
+class DBShelf(DictMixin):
+    """A shelf to hold pickled objects, built upon a bsddb DB object.  It
+    automatically pickles/unpickles data objects going to/from the DB.
+    """
+    def __init__(self, dbenv=None):
+        self.db = db.DB(dbenv)
+        self.binary = 1
+
+
+    def __del__(self):
+        self.close()
+
+
+    def __getattr__(self, name):
+        """Many methods we can just pass through to the DB object.
+        (See below)
+        """
+        return getattr(self.db, name)
+
+
+    #-----------------------------------
+    # Dictionary access methods
+
+    def __len__(self):
+        return len(self.db)
+
+
+    def __getitem__(self, key):
+        data = self.db[key]
+        return cPickle.loads(data)
+
+
+    def __setitem__(self, key, value):
+        data = cPickle.dumps(value, self.binary)
+        self.db[key] = data
+
+
+    def __delitem__(self, key):
+        del self.db[key]
+
+
+    def keys(self, txn=None):
+        if txn != None:
+            return self.db.keys(txn)
+        else:
+            return self.db.keys()
+
+
+    def items(self, txn=None):
+        if txn != None:
+            items = self.db.items(txn)
+        else:
+            items = self.db.items()
+        newitems = []
+
+        for k, v in items:
+            newitems.append( (k, cPickle.loads(v)) )
+        return newitems
+
+    def values(self, txn=None):
+        if txn != None:
+            values = self.db.values(txn)
+        else:
+            values = self.db.values()
+
+        return map(cPickle.loads, values)
+
+    #-----------------------------------
+    # Other methods
+
+    def __append(self, value, txn=None):
+        data = cPickle.dumps(value, self.binary)
+        return self.db.append(data, txn)
+
+    def append(self, value, txn=None):
+        if self.get_type() != db.DB_RECNO:
+            self.append = self.__append
+            return self.append(value, txn=txn)
+        raise db.DBError, "append() only supported when dbshelve opened with filetype=dbshelve.db.DB_RECNO"
+
+
+    def associate(self, secondaryDB, callback, flags=0):
+        def _shelf_callback(priKey, priData, realCallback=callback):
+            data = cPickle.loads(priData)
+            return realCallback(priKey, data)
+        return self.db.associate(secondaryDB, _shelf_callback, flags)
+
+
+    #def get(self, key, default=None, txn=None, flags=0):
+    def get(self, *args, **kw):
+        # We do it with *args and **kw so if the default value wasn't
+        # given nothing is passed to the extension module.  That way
+        # an exception can be raised if set_get_returns_none is turned
+        # off.
+        data = apply(self.db.get, args, kw)
+        try:
+            return cPickle.loads(data)
+        except (TypeError, cPickle.UnpicklingError):
+            return data  # we may be getting the default value, or None,
+                         # so it doesn't need unpickled.
+
+    def get_both(self, key, value, txn=None, flags=0):
+        data = cPickle.dumps(value, self.binary)
+        data = self.db.get(key, data, txn, flags)
+        return cPickle.loads(data)
+
+
+    def cursor(self, txn=None, flags=0):
+        c = DBShelfCursor(self.db.cursor(txn, flags))
+        c.binary = self.binary
+        return c
+
+
+    def put(self, key, value, txn=None, flags=0):
+        data = cPickle.dumps(value, self.binary)
+        return self.db.put(key, data, txn, flags)
+
+
+    def join(self, cursorList, flags=0):
+        raise NotImplementedError
+
+
+    #----------------------------------------------
+    # Methods allowed to pass-through to self.db
+    #
+    #    close,  delete, fd, get_byteswapped, get_type, has_key,
+    #    key_range, open, remove, rename, stat, sync,
+    #    upgrade, verify, and all set_* methods.
+
+
+#---------------------------------------------------------------------------
+
+class DBShelfCursor:
+    """
+    """
+    def __init__(self, cursor):
+        self.dbc = cursor
+
+    def __del__(self):
+        self.close()
+
+
+    def __getattr__(self, name):
+        """Some methods we can just pass through to the cursor object.  (See below)"""
+        return getattr(self.dbc, name)
+
+
+    #----------------------------------------------
+
+    def dup(self, flags=0):
+        return DBShelfCursor(self.dbc.dup(flags))
+
+
+    def put(self, key, value, flags=0):
+        data = cPickle.dumps(value, self.binary)
+        return self.dbc.put(key, data, flags)
+
+
+    def get(self, *args):
+        count = len(args)  # a method overloading hack
+        method = getattr(self, 'get_%d' % count)
+        apply(method, args)
+
+    def get_1(self, flags):
+        rec = self.dbc.get(flags)
+        return self._extract(rec)
+
+    def get_2(self, key, flags):
+        rec = self.dbc.get(key, flags)
+        return self._extract(rec)
+
+    def get_3(self, key, value, flags):
+        data = cPickle.dumps(value, self.binary)
+        rec = self.dbc.get(key, flags)
+        return self._extract(rec)
+
+
+    def current(self, flags=0): return self.get_1(flags|db.DB_CURRENT)
+    def first(self, flags=0): return self.get_1(flags|db.DB_FIRST)
+    def last(self, flags=0): return self.get_1(flags|db.DB_LAST)
+    def next(self, flags=0): return self.get_1(flags|db.DB_NEXT)
+    def prev(self, flags=0): return self.get_1(flags|db.DB_PREV)
+    def consume(self, flags=0): return self.get_1(flags|db.DB_CONSUME)
+    def next_dup(self, flags=0): return self.get_1(flags|db.DB_NEXT_DUP)
+    def next_nodup(self, flags=0): return self.get_1(flags|db.DB_NEXT_NODUP)
+    def prev_nodup(self, flags=0): return self.get_1(flags|db.DB_PREV_NODUP)
+
+
+    def get_both(self, key, value, flags=0):
+        data = cPickle.dumps(value, self.binary)
+        rec = self.dbc.get_both(key, flags)
+        return self._extract(rec)
+
+
+    def set(self, key, flags=0):
+        rec = self.dbc.set(key, flags)
+        return self._extract(rec)
+
+    def set_range(self, key, flags=0):
+        rec = self.dbc.set_range(key, flags)
+        return self._extract(rec)
+
+    def set_recno(self, recno, flags=0):
+        rec = self.dbc.set_recno(recno, flags)
+        return self._extract(rec)
+
+    set_both = get_both
+
+    def _extract(self, rec):
+        if rec is None:
+            return None
+        else:
+            key, data = rec
+            return key, cPickle.loads(data)
+
+    #----------------------------------------------
+    # Methods allowed to pass-through to self.dbc
+    #
+    # close, count, delete, get_recno, join_item
+
+
+#---------------------------------------------------------------------------

Added: vendor/Python/current/Lib/bsddb/dbtables.py
===================================================================
--- vendor/Python/current/Lib/bsddb/dbtables.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/bsddb/dbtables.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,706 @@
+#-----------------------------------------------------------------------
+#
+# Copyright (C) 2000, 2001 by Autonomous Zone Industries
+# Copyright (C) 2002 Gregory P. Smith
+#
+# License:      This is free software.  You may use this software for any
+#               purpose including modification/redistribution, so long as
+#               this header remains intact and that you do not claim any
+#               rights of ownership or authorship of this software.  This
+#               software has been tested, but no warranty is expressed or
+#               implied.
+#
+#   --  Gregory P. Smith <greg at electricrain.com>
+
+# This provides a simple database table interface built on top of
+# the Python BerkeleyDB 3 interface.
+#
+_cvsid = '$Id: dbtables.py 46858 2006-06-11 08:35:14Z neal.norwitz $'
+
+import re
+import sys
+import copy
+import xdrlib
+import random
+from types import ListType, StringType
+import cPickle as pickle
+
+try:
+    # For Pythons w/distutils pybsddb
+    from bsddb3.db import *
+except ImportError:
+    # For Python 2.3
+    from bsddb.db import *
+
+# XXX(nnorwitz): is this correct? DBIncompleteError is conditional in _bsddb.c
+try:
+    DBIncompleteError
+except NameError:
+    class DBIncompleteError(Exception):
+        pass
+
+class TableDBError(StandardError):
+    pass
+class TableAlreadyExists(TableDBError):
+    pass
+
+
+class Cond:
+    """This condition matches everything"""
+    def __call__(self, s):
+        return 1
+
+class ExactCond(Cond):
+    """Acts as an exact match condition function"""
+    def __init__(self, strtomatch):
+        self.strtomatch = strtomatch
+    def __call__(self, s):
+        return s == self.strtomatch
+
+class PrefixCond(Cond):
+    """Acts as a condition function for matching a string prefix"""
+    def __init__(self, prefix):
+        self.prefix = prefix
+    def __call__(self, s):
+        return s[:len(self.prefix)] == self.prefix
+
+class PostfixCond(Cond):
+    """Acts as a condition function for matching a string postfix"""
+    def __init__(self, postfix):
+        self.postfix = postfix
+    def __call__(self, s):
+        return s[-len(self.postfix):] == self.postfix
+
+class LikeCond(Cond):
+    """
+    Acts as a function that will match using an SQL 'LIKE' style
+    string.  Case insensitive and % signs are wild cards.
+    This isn't perfect but it should work for the simple common cases.
+    """
+    def __init__(self, likestr, re_flags=re.IGNORECASE):
+        # escape python re characters
+        chars_to_escape = '.*+()[]?'
+        for char in chars_to_escape :
+            likestr = likestr.replace(char, '\\'+char)
+        # convert %s to wildcards
+        self.likestr = likestr.replace('%', '.*')
+        self.re = re.compile('^'+self.likestr+'$', re_flags)
+    def __call__(self, s):
+        return self.re.match(s)
+
+#
+# keys used to store database metadata
+#
+_table_names_key = '__TABLE_NAMES__'  # list of the tables in this db
+_columns = '._COLUMNS__'  # table_name+this key contains a list of columns
+
+def _columns_key(table):
+    return table + _columns
+
+#
+# these keys are found within table sub databases
+#
+_data =  '._DATA_.'  # this+column+this+rowid key contains table data
+_rowid = '._ROWID_.' # this+rowid+this key contains a unique entry for each
+                     # row in the table.  (no data is stored)
+_rowid_str_len = 8   # length in bytes of the unique rowid strings
+
+def _data_key(table, col, rowid):
+    return table + _data + col + _data + rowid
+
+def _search_col_data_key(table, col):
+    return table + _data + col + _data
+
+def _search_all_data_key(table):
+    return table + _data
+
+def _rowid_key(table, rowid):
+    return table + _rowid + rowid + _rowid
+
+def _search_rowid_key(table):
+    return table + _rowid
+
+def contains_metastrings(s) :
+    """Verify that the given string does not contain any
+    metadata strings that might interfere with dbtables database operation.
+    """
+    if (s.find(_table_names_key) >= 0 or
+        s.find(_columns) >= 0 or
+        s.find(_data) >= 0 or
+        s.find(_rowid) >= 0):
+        # Then
+        return 1
+    else:
+        return 0
+
+
+class bsdTableDB :
+    def __init__(self, filename, dbhome, create=0, truncate=0, mode=0600,
+                 recover=0, dbflags=0):
+        """bsdTableDB(filename, dbhome, create=0, truncate=0, mode=0600)
+
+        Open database name in the dbhome BerkeleyDB directory.
+        Use keyword arguments when calling this constructor.
+        """
+        self.db = None
+        myflags = DB_THREAD
+        if create:
+            myflags |= DB_CREATE
+        flagsforenv = (DB_INIT_MPOOL | DB_INIT_LOCK | DB_INIT_LOG |
+                       DB_INIT_TXN | dbflags)
+        # DB_AUTO_COMMIT isn't a valid flag for env.open()
+        try:
+            dbflags |= DB_AUTO_COMMIT
+        except AttributeError:
+            pass
+        if recover:
+            flagsforenv = flagsforenv | DB_RECOVER
+        self.env = DBEnv()
+        # enable auto deadlock avoidance
+        self.env.set_lk_detect(DB_LOCK_DEFAULT)
+        self.env.open(dbhome, myflags | flagsforenv)
+        if truncate:
+            myflags |= DB_TRUNCATE
+        self.db = DB(self.env)
+        # this code relies on DBCursor.set* methods to raise exceptions
+        # rather than returning None
+        self.db.set_get_returns_none(1)
+        # allow duplicate entries [warning: be careful w/ metadata]
+        self.db.set_flags(DB_DUP)
+        self.db.open(filename, DB_BTREE, dbflags | myflags, mode)
+        self.dbfilename = filename
+        # Initialize the table names list if this is a new database
+        txn = self.env.txn_begin()
+        try:
+            if not self.db.has_key(_table_names_key, txn):
+                self.db.put(_table_names_key, pickle.dumps([], 1), txn=txn)
+        # Yes, bare except
+        except:
+            txn.abort()
+            raise
+        else:
+            txn.commit()
+        # TODO verify more of the database's metadata?
+        self.__tablecolumns = {}
+
+    def __del__(self):
+        self.close()
+
+    def close(self):
+        if self.db is not None:
+            self.db.close()
+            self.db = None
+        if self.env is not None:
+            self.env.close()
+            self.env = None
+
+    def checkpoint(self, mins=0):
+        try:
+            self.env.txn_checkpoint(mins)
+        except DBIncompleteError:
+            pass
+
+    def sync(self):
+        try:
+            self.db.sync()
+        except DBIncompleteError:
+            pass
+
+    def _db_print(self) :
+        """Print the database to stdout for debugging"""
+        print "******** Printing raw database for debugging ********"
+        cur = self.db.cursor()
+        try:
+            key, data = cur.first()
+            while 1:
+                print repr({key: data})
+                next = cur.next()
+                if next:
+                    key, data = next
+                else:
+                    cur.close()
+                    return
+        except DBNotFoundError:
+            cur.close()
+
+
+    def CreateTable(self, table, columns):
+        """CreateTable(table, columns) - Create a new table in the database.
+
+        raises TableDBError if it already exists or for other DB errors.
+        """
+        assert isinstance(columns, ListType)
+        txn = None
+        try:
+            # checking sanity of the table and column names here on
+            # table creation will prevent problems elsewhere.
+            if contains_metastrings(table):
+                raise ValueError(
+                    "bad table name: contains reserved metastrings")
+            for column in columns :
+                if contains_metastrings(column):
+                    raise ValueError(
+                        "bad column name: contains reserved metastrings")
+
+            columnlist_key = _columns_key(table)
+            if self.db.has_key(columnlist_key):
+                raise TableAlreadyExists, "table already exists"
+
+            txn = self.env.txn_begin()
+            # store the table's column info
+            self.db.put(columnlist_key, pickle.dumps(columns, 1), txn=txn)
+
+            # add the table name to the tablelist
+            tablelist = pickle.loads(self.db.get(_table_names_key, txn=txn,
+                                                 flags=DB_RMW))
+            tablelist.append(table)
+            # delete 1st, in case we opened with DB_DUP
+            self.db.delete(_table_names_key, txn)
+            self.db.put(_table_names_key, pickle.dumps(tablelist, 1), txn=txn)
+
+            txn.commit()
+            txn = None
+        except DBError, dberror:
+            if txn:
+                txn.abort()
+            raise TableDBError, dberror[1]
+
+
+    def ListTableColumns(self, table):
+        """Return a list of columns in the given table.
+        [] if the table doesn't exist.
+        """
+        assert isinstance(table, StringType)
+        if contains_metastrings(table):
+            raise ValueError, "bad table name: contains reserved metastrings"
+
+        columnlist_key = _columns_key(table)
+        if not self.db.has_key(columnlist_key):
+            return []
+        pickledcolumnlist = self.db.get(columnlist_key)
+        if pickledcolumnlist:
+            return pickle.loads(pickledcolumnlist)
+        else:
+            return []
+
+    def ListTables(self):
+        """Return a list of tables in this database."""
+        pickledtablelist = self.db.get(_table_names_key)
+        if pickledtablelist:
+            return pickle.loads(pickledtablelist)
+        else:
+            return []
+
+    def CreateOrExtendTable(self, table, columns):
+        """CreateOrExtendTable(table, columns)
+
+        Create a new table in the database.
+
+        If a table of this name already exists, extend it to have any
+        additional columns present in the given list as well as
+        all of its current columns.
+        """
+        assert isinstance(columns, ListType)
+        try:
+            self.CreateTable(table, columns)
+        except TableAlreadyExists:
+            # the table already existed, add any new columns
+            txn = None
+            try:
+                columnlist_key = _columns_key(table)
+                txn = self.env.txn_begin()
+
+                # load the current column list
+                oldcolumnlist = pickle.loads(
+                    self.db.get(columnlist_key, txn=txn, flags=DB_RMW))
+                # create a hash table for fast lookups of column names in the
+                # loop below
+                oldcolumnhash = {}
+                for c in oldcolumnlist:
+                    oldcolumnhash[c] = c
+
+                # create a new column list containing both the old and new
+                # column names
+                newcolumnlist = copy.copy(oldcolumnlist)
+                for c in columns:
+                    if not oldcolumnhash.has_key(c):
+                        newcolumnlist.append(c)
+
+                # store the table's new extended column list
+                if newcolumnlist != oldcolumnlist :
+                    # delete the old one first since we opened with DB_DUP
+                    self.db.delete(columnlist_key, txn)
+                    self.db.put(columnlist_key,
+                                pickle.dumps(newcolumnlist, 1),
+                                txn=txn)
+
+                txn.commit()
+                txn = None
+
+                self.__load_column_info(table)
+            except DBError, dberror:
+                if txn:
+                    txn.abort()
+                raise TableDBError, dberror[1]
+
+
+    def __load_column_info(self, table) :
+        """initialize the self.__tablecolumns dict"""
+        # check the column names
+        try:
+            tcolpickles = self.db.get(_columns_key(table))
+        except DBNotFoundError:
+            raise TableDBError, "unknown table: %r" % (table,)
+        if not tcolpickles:
+            raise TableDBError, "unknown table: %r" % (table,)
+        self.__tablecolumns[table] = pickle.loads(tcolpickles)
+
+    def __new_rowid(self, table, txn) :
+        """Create a new unique row identifier"""
+        unique = 0
+        while not unique:
+            # Generate a random 64-bit row ID string
+            # (note: this code has <64 bits of randomness
+            # but it's plenty for our database id needs!)
+            p = xdrlib.Packer()
+            p.pack_int(int(random.random()*2147483647))
+            p.pack_int(int(random.random()*2147483647))
+            newid = p.get_buffer()
+
+            # Guarantee uniqueness by adding this key to the database
+            try:
+                self.db.put(_rowid_key(table, newid), None, txn=txn,
+                            flags=DB_NOOVERWRITE)
+            except DBKeyExistError:
+                pass
+            else:
+                unique = 1
+
+        return newid
+
+
+    def Insert(self, table, rowdict) :
+        """Insert(table, datadict) - Insert a new row into the table
+        using the keys+values from rowdict as the column values.
+        """
+        txn = None
+        try:
+            if not self.db.has_key(_columns_key(table)):
+                raise TableDBError, "unknown table"
+
+            # check the validity of each column name
+            if not self.__tablecolumns.has_key(table):
+                self.__load_column_info(table)
+            for column in rowdict.keys() :
+                if not self.__tablecolumns[table].count(column):
+                    raise TableDBError, "unknown column: %r" % (column,)
+
+            # get a unique row identifier for this row
+            txn = self.env.txn_begin()
+            rowid = self.__new_rowid(table, txn=txn)
+
+            # insert the row values into the table database
+            for column, dataitem in rowdict.items():
+                # store the value
+                self.db.put(_data_key(table, column, rowid), dataitem, txn=txn)
+
+            txn.commit()
+            txn = None
+
+        except DBError, dberror:
+            # WIBNI we could just abort the txn and re-raise the exception?
+            # But no, because TableDBError is not related to DBError via
+            # inheritance, so it would be backwards incompatible.  Do the next
+            # best thing.
+            info = sys.exc_info()
+            if txn:
+                txn.abort()
+                self.db.delete(_rowid_key(table, rowid))
+            raise TableDBError, dberror[1], info[2]
+
+
+    def Modify(self, table, conditions={}, mappings={}):
+        """Modify(table, conditions={}, mappings={}) - Modify items in rows matching 'conditions' using mapping functions in 'mappings'
+
+        * table - the table name
+        * conditions - a dictionary keyed on column names containing
+          a condition callable expecting the data string as an
+          argument and returning a boolean.
+        * mappings - a dictionary keyed on column names containing a
+          condition callable expecting the data string as an argument and
+          returning the new string for that column.
+        """
+        try:
+            matching_rowids = self.__Select(table, [], conditions)
+
+            # modify only requested columns
+            columns = mappings.keys()
+            for rowid in matching_rowids.keys():
+                txn = None
+                try:
+                    for column in columns:
+                        txn = self.env.txn_begin()
+                        # modify the requested column
+                        try:
+                            dataitem = self.db.get(
+                                _data_key(table, column, rowid),
+                                txn)
+                            self.db.delete(
+                                _data_key(table, column, rowid),
+                                txn)
+                        except DBNotFoundError:
+                             # XXXXXXX row key somehow didn't exist, assume no
+                             # error
+                            dataitem = None
+                        dataitem = mappings[column](dataitem)
+                        if dataitem <> None:
+                            self.db.put(
+                                _data_key(table, column, rowid),
+                                dataitem, txn=txn)
+                        txn.commit()
+                        txn = None
+
+                # catch all exceptions here since we call unknown callables
+                except:
+                    if txn:
+                        txn.abort()
+                    raise
+
+        except DBError, dberror:
+            raise TableDBError, dberror[1]
+
+    def Delete(self, table, conditions={}):
+        """Delete(table, conditions) - Delete items matching the given
+        conditions from the table.
+
+        * conditions - a dictionary keyed on column names containing
+          condition functions expecting the data string as an
+          argument and returning a boolean.
+        """
+        try:
+            matching_rowids = self.__Select(table, [], conditions)
+
+            # delete row data from all columns
+            columns = self.__tablecolumns[table]
+            for rowid in matching_rowids.keys():
+                txn = None
+                try:
+                    txn = self.env.txn_begin()
+                    for column in columns:
+                        # delete the data key
+                        try:
+                            self.db.delete(_data_key(table, column, rowid),
+                                           txn)
+                        except DBNotFoundError:
+                            # XXXXXXX column may not exist, assume no error
+                            pass
+
+                    try:
+                        self.db.delete(_rowid_key(table, rowid), txn)
+                    except DBNotFoundError:
+                        # XXXXXXX row key somehow didn't exist, assume no error
+                        pass
+                    txn.commit()
+                    txn = None
+                except DBError, dberror:
+                    if txn:
+                        txn.abort()
+                    raise
+        except DBError, dberror:
+            raise TableDBError, dberror[1]
+
+
+    def Select(self, table, columns, conditions={}):
+        """Select(table, columns, conditions) - retrieve specific row data
+        Returns a list of row column->value mapping dictionaries.
+
+        * columns - a list of which column data to return.  If
+          columns is None, all columns will be returned.
+        * conditions - a dictionary keyed on column names
+          containing callable conditions expecting the data string as an
+          argument and returning a boolean.
+        """
+        try:
+            if not self.__tablecolumns.has_key(table):
+                self.__load_column_info(table)
+            if columns is None:
+                columns = self.__tablecolumns[table]
+            matching_rowids = self.__Select(table, columns, conditions)
+        except DBError, dberror:
+            raise TableDBError, dberror[1]
+        # return the matches as a list of dictionaries
+        return matching_rowids.values()
+
+
+    def __Select(self, table, columns, conditions):
+        """__Select() - Used to implement Select and Delete (above)
+        Returns a dictionary keyed on rowids containing dicts
+        holding the row data for columns listed in the columns param
+        that match the given conditions.
+        * conditions is a dictionary keyed on column names
+        containing callable conditions expecting the data string as an
+        argument and returning a boolean.
+        """
+        # check the validity of each column name
+        if not self.__tablecolumns.has_key(table):
+            self.__load_column_info(table)
+        if columns is None:
+            columns = self.tablecolumns[table]
+        for column in (columns + conditions.keys()):
+            if not self.__tablecolumns[table].count(column):
+                raise TableDBError, "unknown column: %r" % (column,)
+
+        # keyed on rows that match so far, containings dicts keyed on
+        # column names containing the data for that row and column.
+        matching_rowids = {}
+        # keys are rowids that do not match
+        rejected_rowids = {}
+
+        # attempt to sort the conditions in such a way as to minimize full
+        # column lookups
+        def cmp_conditions(atuple, btuple):
+            a = atuple[1]
+            b = btuple[1]
+            if type(a) is type(b):
+                if isinstance(a, PrefixCond) and isinstance(b, PrefixCond):
+                    # longest prefix first
+                    return cmp(len(b.prefix), len(a.prefix))
+                if isinstance(a, LikeCond) and isinstance(b, LikeCond):
+                    # longest likestr first
+                    return cmp(len(b.likestr), len(a.likestr))
+                return 0
+            if isinstance(a, ExactCond):
+                return -1
+            if isinstance(b, ExactCond):
+                return 1
+            if isinstance(a, PrefixCond):
+                return -1
+            if isinstance(b, PrefixCond):
+                return 1
+            # leave all unknown condition callables alone as equals
+            return 0
+
+        conditionlist = conditions.items()
+        conditionlist.sort(cmp_conditions)
+
+        # Apply conditions to column data to find what we want
+        cur = self.db.cursor()
+        column_num = -1
+        for column, condition in conditionlist:
+            column_num = column_num + 1
+            searchkey = _search_col_data_key(table, column)
+            # speedup: don't linear search columns within loop
+            if column in columns:
+                savethiscolumndata = 1  # save the data for return
+            else:
+                savethiscolumndata = 0  # data only used for selection
+
+            try:
+                key, data = cur.set_range(searchkey)
+                while key[:len(searchkey)] == searchkey:
+                    # extract the rowid from the key
+                    rowid = key[-_rowid_str_len:]
+
+                    if not rejected_rowids.has_key(rowid):
+                        # if no condition was specified or the condition
+                        # succeeds, add row to our match list.
+                        if not condition or condition(data):
+                            if not matching_rowids.has_key(rowid):
+                                matching_rowids[rowid] = {}
+                            if savethiscolumndata:
+                                matching_rowids[rowid][column] = data
+                        else:
+                            if matching_rowids.has_key(rowid):
+                                del matching_rowids[rowid]
+                            rejected_rowids[rowid] = rowid
+
+                    key, data = cur.next()
+
+            except DBError, dberror:
+                if dberror[0] != DB_NOTFOUND:
+                    raise
+                continue
+
+        cur.close()
+
+        # we're done selecting rows, garbage collect the reject list
+        del rejected_rowids
+
+        # extract any remaining desired column data from the
+        # database for the matching rows.
+        if len(columns) > 0:
+            for rowid, rowdata in matching_rowids.items():
+                for column in columns:
+                    if rowdata.has_key(column):
+                        continue
+                    try:
+                        rowdata[column] = self.db.get(
+                            _data_key(table, column, rowid))
+                    except DBError, dberror:
+                        if dberror[0] != DB_NOTFOUND:
+                            raise
+                        rowdata[column] = None
+
+        # return the matches
+        return matching_rowids
+
+
+    def Drop(self, table):
+        """Remove an entire table from the database"""
+        txn = None
+        try:
+            txn = self.env.txn_begin()
+
+            # delete the column list
+            self.db.delete(_columns_key(table), txn)
+
+            cur = self.db.cursor(txn)
+
+            # delete all keys containing this tables column and row info
+            table_key = _search_all_data_key(table)
+            while 1:
+                try:
+                    key, data = cur.set_range(table_key)
+                except DBNotFoundError:
+                    break
+                # only delete items in this table
+                if key[:len(table_key)] != table_key:
+                    break
+                cur.delete()
+
+            # delete all rowids used by this table
+            table_key = _search_rowid_key(table)
+            while 1:
+                try:
+                    key, data = cur.set_range(table_key)
+                except DBNotFoundError:
+                    break
+                # only delete items in this table
+                if key[:len(table_key)] != table_key:
+                    break
+                cur.delete()
+
+            cur.close()
+
+            # delete the tablename from the table name list
+            tablelist = pickle.loads(
+                self.db.get(_table_names_key, txn=txn, flags=DB_RMW))
+            try:
+                tablelist.remove(table)
+            except ValueError:
+                # hmm, it wasn't there, oh well, that's what we want.
+                pass
+            # delete 1st, incase we opened with DB_DUP
+            self.db.delete(_table_names_key, txn)
+            self.db.put(_table_names_key, pickle.dumps(tablelist, 1), txn=txn)
+
+            txn.commit()
+            txn = None
+
+            if self.__tablecolumns.has_key(table):
+                del self.__tablecolumns[table]
+
+        except DBError, dberror:
+            if txn:
+                txn.abort()
+            raise TableDBError, dberror[1]

Added: vendor/Python/current/Lib/bsddb/dbutils.py
===================================================================
--- vendor/Python/current/Lib/bsddb/dbutils.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/bsddb/dbutils.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,77 @@
+#------------------------------------------------------------------------
+#
+# Copyright (C) 2000 Autonomous Zone Industries
+#
+# License:      This is free software.  You may use this software for any
+#               purpose including modification/redistribution, so long as
+#               this header remains intact and that you do not claim any
+#               rights of ownership or authorship of this software.  This
+#               software has been tested, but no warranty is expressed or
+#               implied.
+#
+# Author: Gregory P. Smith <greg at electricrain.com>
+#
+# Note: I don't know how useful this is in reality since when a
+#       DBLockDeadlockError happens the current transaction is supposed to be
+#       aborted.  If it doesn't then when the operation is attempted again
+#       the deadlock is still happening...
+#       --Robin
+#
+#------------------------------------------------------------------------
+
+
+#
+# import the time.sleep function in a namespace safe way to allow
+# "from bsddb.dbutils import *"
+#
+from time import sleep as _sleep
+
+import db
+
+# always sleep at least N seconds between retrys
+_deadlock_MinSleepTime = 1.0/128
+# never sleep more than N seconds between retrys
+_deadlock_MaxSleepTime = 3.14159
+
+# Assign a file object to this for a "sleeping" message to be written to it
+# each retry
+_deadlock_VerboseFile = None
+
+
+def DeadlockWrap(function, *_args, **_kwargs):
+    """DeadlockWrap(function, *_args, **_kwargs) - automatically retries
+    function in case of a database deadlock.
+
+    This is a function intended to be used to wrap database calls such
+    that they perform retrys with exponentially backing off sleeps in
+    between when a DBLockDeadlockError exception is raised.
+
+    A 'max_retries' parameter may optionally be passed to prevent it
+    from retrying forever (in which case the exception will be reraised).
+
+        d = DB(...)
+        d.open(...)
+        DeadlockWrap(d.put, "foo", data="bar")  # set key "foo" to "bar"
+    """
+    sleeptime = _deadlock_MinSleepTime
+    max_retries = _kwargs.get('max_retries', -1)
+    if _kwargs.has_key('max_retries'):
+        del _kwargs['max_retries']
+    while True:
+        try:
+            return function(*_args, **_kwargs)
+        except db.DBLockDeadlockError:
+            if _deadlock_VerboseFile:
+                _deadlock_VerboseFile.write(
+                    'dbutils.DeadlockWrap: sleeping %1.3f\n' % sleeptime)
+            _sleep(sleeptime)
+            # exponential backoff in the sleep time
+            sleeptime *= 2
+            if sleeptime > _deadlock_MaxSleepTime:
+                sleeptime = _deadlock_MaxSleepTime
+            max_retries -= 1
+            if max_retries == -1:
+                raise
+
+
+#------------------------------------------------------------------------

Added: vendor/Python/current/Lib/bsddb/test/__init__.py
===================================================================

Added: vendor/Python/current/Lib/bsddb/test/test_1413192.py
===================================================================
--- vendor/Python/current/Lib/bsddb/test/test_1413192.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/bsddb/test/test_1413192.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,21 @@
+
+# http://python.org/sf/1413192
+#
+# This test relies on the variable names, see the bug report for details.
+# The problem was that the env was deallocated prior to the txn.
+
+try:
+    # For Pythons w/distutils and add-on pybsddb
+    from bsddb3 import db
+except ImportError:
+    # For Python >= 2.3 builtin bsddb distribution
+    from bsddb import db
+
+env_name = '.'
+
+env = db.DBEnv()
+env.open(env_name, db.DB_CREATE | db.DB_INIT_TXN | db.DB_INIT_MPOOL)
+the_txn = env.txn_begin()
+
+map = db.DB(env)
+map.open('xxx.db', "p", db.DB_HASH, db.DB_CREATE, 0666, txn=the_txn)

Added: vendor/Python/current/Lib/bsddb/test/test_all.py
===================================================================
--- vendor/Python/current/Lib/bsddb/test/test_all.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/bsddb/test/test_all.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,91 @@
+"""Run all test cases.
+"""
+
+import sys
+import os
+import unittest
+try:
+    # For Pythons w/distutils pybsddb
+    from bsddb3 import db
+except ImportError:
+    # For Python 2.3
+    from bsddb import db
+
+verbose = 0
+if 'verbose' in sys.argv:
+    verbose = 1
+    sys.argv.remove('verbose')
+
+if 'silent' in sys.argv:  # take care of old flag, just in case
+    verbose = 0
+    sys.argv.remove('silent')
+
+
+def print_versions():
+    print
+    print '-=' * 38
+    print db.DB_VERSION_STRING
+    print 'bsddb.db.version():   %s' % (db.version(), )
+    print 'bsddb.db.__version__: %s' % db.__version__
+    print 'bsddb.db.cvsid:       %s' % db.cvsid
+    print 'python version:       %s' % sys.version
+    print 'My pid:               %s' % os.getpid()
+    print '-=' * 38
+
+
+class PrintInfoFakeTest(unittest.TestCase):
+    def testPrintVersions(self):
+        print_versions()
+
+
+# This little hack is for when this module is run as main and all the
+# other modules import it so they will still be able to get the right
+# verbose setting.  It's confusing but it works.
+import test_all
+test_all.verbose = verbose
+
+
+def suite():
+    try:
+        # this is special, it used to segfault the interpreter
+        import test_1413192
+    except:
+        pass
+
+    test_modules = [
+        'test_associate',
+        'test_basics',
+        'test_compat',
+        'test_compare',
+        'test_dbobj',
+        'test_dbshelve',
+        'test_dbtables',
+        'test_env_close',
+        'test_get_none',
+        'test_join',
+        'test_lock',
+        'test_misc',
+        'test_pickle',
+        'test_queue',
+        'test_recno',
+        'test_thread',
+        'test_sequence',
+        'test_cursor_pget_bug',
+        ]
+
+    alltests = unittest.TestSuite()
+    for name in test_modules:
+        module = __import__(name)
+        alltests.addTest(module.test_suite())
+    return alltests
+
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(PrintInfoFakeTest))
+    return suite
+
+
+if __name__ == '__main__':
+    print_versions()
+    unittest.main(defaultTest='suite')

Added: vendor/Python/current/Lib/bsddb/test/test_associate.py
===================================================================
--- vendor/Python/current/Lib/bsddb/test/test_associate.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/bsddb/test/test_associate.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,478 @@
+"""
+TestCases for DB.associate.
+"""
+
+import sys, os, string
+import tempfile
+import time
+from pprint import pprint
+
+try:
+    from threading import Thread, currentThread
+    have_threads = 1
+except ImportError:
+    have_threads = 0
+
+import unittest
+from test_all import verbose
+
+try:
+    # For Pythons w/distutils pybsddb
+    from bsddb3 import db, dbshelve
+except ImportError:
+    # For Python 2.3
+    from bsddb import db, dbshelve
+
+
+#----------------------------------------------------------------------
+
+
+musicdata = {
+1 : ("Bad English", "The Price Of Love", "Rock"),
+2 : ("DNA featuring Suzanne Vega", "Tom's Diner", "Rock"),
+3 : ("George Michael", "Praying For Time", "Rock"),
+4 : ("Gloria Estefan", "Here We Are", "Rock"),
+5 : ("Linda Ronstadt", "Don't Know Much", "Rock"),
+6 : ("Michael Bolton", "How Am I Supposed To Live Without You", "Blues"),
+7 : ("Paul Young", "Oh Girl", "Rock"),
+8 : ("Paula Abdul", "Opposites Attract", "Rock"),
+9 : ("Richard Marx", "Should've Known Better", "Rock"),
+10: ("Rod Stewart", "Forever Young", "Rock"),
+11: ("Roxette", "Dangerous", "Rock"),
+12: ("Sheena Easton", "The Lover In Me", "Rock"),
+13: ("Sinead O'Connor", "Nothing Compares 2 U", "Rock"),
+14: ("Stevie B.", "Because I Love You", "Rock"),
+15: ("Taylor Dayne", "Love Will Lead You Back", "Rock"),
+16: ("The Bangles", "Eternal Flame", "Rock"),
+17: ("Wilson Phillips", "Release Me", "Rock"),
+18: ("Billy Joel", "Blonde Over Blue", "Rock"),
+19: ("Billy Joel", "Famous Last Words", "Rock"),
+20: ("Billy Joel", "Lullabye (Goodnight, My Angel)", "Rock"),
+21: ("Billy Joel", "The River Of Dreams", "Rock"),
+22: ("Billy Joel", "Two Thousand Years", "Rock"),
+23: ("Janet Jackson", "Alright", "Rock"),
+24: ("Janet Jackson", "Black Cat", "Rock"),
+25: ("Janet Jackson", "Come Back To Me", "Rock"),
+26: ("Janet Jackson", "Escapade", "Rock"),
+27: ("Janet Jackson", "Love Will Never Do (Without You)", "Rock"),
+28: ("Janet Jackson", "Miss You Much", "Rock"),
+29: ("Janet Jackson", "Rhythm Nation", "Rock"),
+30: ("Janet Jackson", "State Of The World", "Rock"),
+31: ("Janet Jackson", "The Knowledge", "Rock"),
+32: ("Spyro Gyra", "End of Romanticism", "Jazz"),
+33: ("Spyro Gyra", "Heliopolis", "Jazz"),
+34: ("Spyro Gyra", "Jubilee", "Jazz"),
+35: ("Spyro Gyra", "Little Linda", "Jazz"),
+36: ("Spyro Gyra", "Morning Dance", "Jazz"),
+37: ("Spyro Gyra", "Song for Lorraine", "Jazz"),
+38: ("Yes", "Owner Of A Lonely Heart", "Rock"),
+39: ("Yes", "Rhythm Of Love", "Rock"),
+40: ("Cusco", "Dream Catcher", "New Age"),
+41: ("Cusco", "Geronimos Laughter", "New Age"),
+42: ("Cusco", "Ghost Dance", "New Age"),
+43: ("Blue Man Group", "Drumbone", "New Age"),
+44: ("Blue Man Group", "Endless Column", "New Age"),
+45: ("Blue Man Group", "Klein Mandelbrot", "New Age"),
+46: ("Kenny G", "Silhouette", "Jazz"),
+47: ("Sade", "Smooth Operator", "Jazz"),
+48: ("David Arkenstone", "Papillon (On The Wings Of The Butterfly)",
+     "New Age"),
+49: ("David Arkenstone", "Stepping Stars", "New Age"),
+50: ("David Arkenstone", "Carnation Lily Lily Rose", "New Age"),
+51: ("David Lanz", "Behind The Waterfall", "New Age"),
+52: ("David Lanz", "Cristofori's Dream", "New Age"),
+53: ("David Lanz", "Heartsounds", "New Age"),
+54: ("David Lanz", "Leaves on the Seine", "New Age"),
+99: ("unknown artist", "Unnamed song", "Unknown"),
+}
+
+#----------------------------------------------------------------------
+
+class AssociateErrorTestCase(unittest.TestCase):
+    def setUp(self):
+        self.filename = self.__class__.__name__ + '.db'
+        homeDir = os.path.join(os.path.dirname(sys.argv[0]), 'db_home')
+        self.homeDir = homeDir
+        try:
+            os.mkdir(homeDir)
+        except os.error:
+            import glob
+            files = glob.glob(os.path.join(self.homeDir, '*'))
+            for file in files:
+                os.remove(file)
+        self.env = db.DBEnv()
+        self.env.open(homeDir, db.DB_CREATE | db.DB_INIT_MPOOL)
+
+    def tearDown(self):
+        self.env.close()
+        self.env = None
+        import glob
+        files = glob.glob(os.path.join(self.homeDir, '*'))
+        for file in files:
+            os.remove(file)
+
+
+    def test00_associateDBError(self):
+        if verbose:
+            print '\n', '-=' * 30
+            print "Running %s.test00_associateDBError..." % \
+                  self.__class__.__name__
+
+        dupDB = db.DB(self.env)
+        dupDB.set_flags(db.DB_DUP)
+        dupDB.open(self.filename, "primary", db.DB_BTREE, db.DB_CREATE)
+
+        secDB = db.DB(self.env)
+        secDB.open(self.filename, "secondary", db.DB_BTREE, db.DB_CREATE)
+
+        # dupDB has been configured to allow duplicates, it can't
+        # associate with a secondary.  BerkeleyDB will return an error.
+        try:
+            def f(a,b): return a+b
+            dupDB.associate(secDB, f)
+        except db.DBError:
+            # good
+            secDB.close()
+            dupDB.close()
+        else:
+            secDB.close()
+            dupDB.close()
+            self.fail("DBError exception was expected")
+
+
+
+#----------------------------------------------------------------------
+
+
+class AssociateTestCase(unittest.TestCase):
+    keytype = ''
+    envFlags = 0
+    dbFlags = 0
+
+    def setUp(self):
+        self.filename = self.__class__.__name__ + '.db'
+        homeDir = os.path.join(os.path.dirname(sys.argv[0]), 'db_home')
+        self.homeDir = homeDir
+        try:
+            os.mkdir(homeDir)
+        except os.error:
+            import glob
+            files = glob.glob(os.path.join(self.homeDir, '*'))
+            for file in files:
+                os.remove(file)
+        self.env = db.DBEnv()
+        self.env.open(homeDir, db.DB_CREATE | db.DB_INIT_MPOOL |
+                               db.DB_INIT_LOCK | db.DB_THREAD | self.envFlags)
+
+    def tearDown(self):
+        self.closeDB()
+        self.env.close()
+        self.env = None
+        import glob
+        files = glob.glob(os.path.join(self.homeDir, '*'))
+        for file in files:
+            os.remove(file)
+
+    def addDataToDB(self, d, txn=None):
+        for key, value in musicdata.items():
+            if type(self.keytype) == type(''):
+                key = "%02d" % key
+            d.put(key, string.join(value, '|'), txn=txn)
+
+    def createDB(self, txn=None):
+        self.cur = None
+        self.secDB = None
+        self.primary = db.DB(self.env)
+        self.primary.set_get_returns_none(2)
+        if db.version() >= (4, 1):
+            self.primary.open(self.filename, "primary", self.dbtype,
+                          db.DB_CREATE | db.DB_THREAD | self.dbFlags, txn=txn)
+        else:
+            self.primary.open(self.filename, "primary", self.dbtype,
+                          db.DB_CREATE | db.DB_THREAD | self.dbFlags)
+
+    def closeDB(self):
+        if self.cur:
+            self.cur.close()
+            self.cur = None
+        if self.secDB:
+            self.secDB.close()
+            self.secDB = None
+        self.primary.close()
+        self.primary = None
+
+    def getDB(self):
+        return self.primary
+
+
+    def test01_associateWithDB(self):
+        if verbose:
+            print '\n', '-=' * 30
+            print "Running %s.test01_associateWithDB..." % \
+                  self.__class__.__name__
+
+        self.createDB()
+
+        self.secDB = db.DB(self.env)
+        self.secDB.set_flags(db.DB_DUP)
+        self.secDB.set_get_returns_none(2)
+        self.secDB.open(self.filename, "secondary", db.DB_BTREE,
+                   db.DB_CREATE | db.DB_THREAD | self.dbFlags)
+        self.getDB().associate(self.secDB, self.getGenre)
+
+        self.addDataToDB(self.getDB())
+
+        self.finish_test(self.secDB)
+
+
+    def test02_associateAfterDB(self):
+        if verbose:
+            print '\n', '-=' * 30
+            print "Running %s.test02_associateAfterDB..." % \
+                  self.__class__.__name__
+
+        self.createDB()
+        self.addDataToDB(self.getDB())
+
+        self.secDB = db.DB(self.env)
+        self.secDB.set_flags(db.DB_DUP)
+        self.secDB.open(self.filename, "secondary", db.DB_BTREE,
+                   db.DB_CREATE | db.DB_THREAD | self.dbFlags)
+
+        # adding the DB_CREATE flag will cause it to index existing records
+        self.getDB().associate(self.secDB, self.getGenre, db.DB_CREATE)
+
+        self.finish_test(self.secDB)
+
+
+    def finish_test(self, secDB, txn=None):
+        # 'Blues' should not be in the secondary database
+        vals = secDB.pget('Blues', txn=txn)
+        assert vals == None, vals
+
+        vals = secDB.pget('Unknown', txn=txn)
+        assert vals[0] == 99 or vals[0] == '99', vals
+        vals[1].index('Unknown')
+        vals[1].index('Unnamed')
+        vals[1].index('unknown')
+
+        if verbose:
+            print "Primary key traversal:"
+        self.cur = self.getDB().cursor(txn)
+        count = 0
+        rec = self.cur.first()
+        while rec is not None:
+            if type(self.keytype) == type(''):
+                assert string.atoi(rec[0])  # for primary db, key is a number
+            else:
+                assert rec[0] and type(rec[0]) == type(0)
+            count = count + 1
+            if verbose:
+                print rec
+            rec = self.cur.next()
+        assert count == len(musicdata) # all items accounted for
+
+
+        if verbose:
+            print "Secondary key traversal:"
+        self.cur = secDB.cursor(txn)
+        count = 0
+
+        # test cursor pget
+        vals = self.cur.pget('Unknown', flags=db.DB_LAST)
+        assert vals[1] == 99 or vals[1] == '99', vals
+        assert vals[0] == 'Unknown'
+        vals[2].index('Unknown')
+        vals[2].index('Unnamed')
+        vals[2].index('unknown')
+
+        vals = self.cur.pget('Unknown', data='wrong value', flags=db.DB_GET_BOTH)
+        assert vals == None, vals
+
+        rec = self.cur.first()
+        assert rec[0] == "Jazz"
+        while rec is not None:
+            count = count + 1
+            if verbose:
+                print rec
+            rec = self.cur.next()
+        # all items accounted for EXCEPT for 1 with "Blues" genre
+        assert count == len(musicdata)-1
+
+        self.cur = None
+
+    def getGenre(self, priKey, priData):
+        assert type(priData) == type("")
+        if verbose:
+            print 'getGenre key: %r data: %r' % (priKey, priData)
+        genre = string.split(priData, '|')[2]
+        if genre == 'Blues':
+            return db.DB_DONOTINDEX
+        else:
+            return genre
+
+
+#----------------------------------------------------------------------
+
+
+class AssociateHashTestCase(AssociateTestCase):
+    dbtype = db.DB_HASH
+
+class AssociateBTreeTestCase(AssociateTestCase):
+    dbtype = db.DB_BTREE
+
+class AssociateRecnoTestCase(AssociateTestCase):
+    dbtype = db.DB_RECNO
+    keytype = 0
+
+#----------------------------------------------------------------------
+
+class AssociateBTreeTxnTestCase(AssociateBTreeTestCase):
+    envFlags = db.DB_INIT_TXN
+    dbFlags = 0
+
+    def txn_finish_test(self, sDB, txn):
+        try:
+            self.finish_test(sDB, txn=txn)
+        finally:
+            if self.cur:
+                self.cur.close()
+                self.cur = None
+            if txn:
+                txn.commit()
+
+    def test13_associate_in_transaction(self):
+        if verbose:
+            print '\n', '-=' * 30
+            print "Running %s.test13_associateAutoCommit..." % \
+                  self.__class__.__name__
+
+        txn = self.env.txn_begin()
+        try:
+            self.createDB(txn=txn)
+
+            self.secDB = db.DB(self.env)
+            self.secDB.set_flags(db.DB_DUP)
+            self.secDB.set_get_returns_none(2)
+            self.secDB.open(self.filename, "secondary", db.DB_BTREE,
+                       db.DB_CREATE | db.DB_THREAD, txn=txn)
+            if db.version() >= (4,1):
+                self.getDB().associate(self.secDB, self.getGenre, txn=txn)
+            else:
+                self.getDB().associate(self.secDB, self.getGenre)
+
+            self.addDataToDB(self.getDB(), txn=txn)
+        except:
+            txn.abort()
+            raise
+
+        self.txn_finish_test(self.secDB, txn=txn)
+
+
+#----------------------------------------------------------------------
+
+class ShelveAssociateTestCase(AssociateTestCase):
+
+    def createDB(self):
+        self.primary = dbshelve.open(self.filename,
+                                     dbname="primary",
+                                     dbenv=self.env,
+                                     filetype=self.dbtype)
+
+    def addDataToDB(self, d):
+        for key, value in musicdata.items():
+            if type(self.keytype) == type(''):
+                key = "%02d" % key
+            d.put(key, value)    # save the value as is this time
+
+
+    def getGenre(self, priKey, priData):
+        assert type(priData) == type(())
+        if verbose:
+            print 'getGenre key: %r data: %r' % (priKey, priData)
+        genre = priData[2]
+        if genre == 'Blues':
+            return db.DB_DONOTINDEX
+        else:
+            return genre
+
+
+class ShelveAssociateHashTestCase(ShelveAssociateTestCase):
+    dbtype = db.DB_HASH
+
+class ShelveAssociateBTreeTestCase(ShelveAssociateTestCase):
+    dbtype = db.DB_BTREE
+
+class ShelveAssociateRecnoTestCase(ShelveAssociateTestCase):
+    dbtype = db.DB_RECNO
+    keytype = 0
+
+
+#----------------------------------------------------------------------
+
+class ThreadedAssociateTestCase(AssociateTestCase):
+
+    def addDataToDB(self, d):
+        t1 = Thread(target = self.writer1,
+                    args = (d, ))
+        t2 = Thread(target = self.writer2,
+                    args = (d, ))
+
+        t1.start()
+        t2.start()
+        t1.join()
+        t2.join()
+
+    def writer1(self, d):
+        for key, value in musicdata.items():
+            if type(self.keytype) == type(''):
+                key = "%02d" % key
+            d.put(key, string.join(value, '|'))
+
+    def writer2(self, d):
+        for x in range(100, 600):
+            key = 'z%2d' % x
+            value = [key] * 4
+            d.put(key, string.join(value, '|'))
+
+
+class ThreadedAssociateHashTestCase(ShelveAssociateTestCase):
+    dbtype = db.DB_HASH
+
+class ThreadedAssociateBTreeTestCase(ShelveAssociateTestCase):
+    dbtype = db.DB_BTREE
+
+class ThreadedAssociateRecnoTestCase(ShelveAssociateTestCase):
+    dbtype = db.DB_RECNO
+    keytype = 0
+
+
+#----------------------------------------------------------------------
+
+def test_suite():
+    suite = unittest.TestSuite()
+
+    if db.version() >= (3, 3, 11):
+        suite.addTest(unittest.makeSuite(AssociateErrorTestCase))
+
+        suite.addTest(unittest.makeSuite(AssociateHashTestCase))
+        suite.addTest(unittest.makeSuite(AssociateBTreeTestCase))
+        suite.addTest(unittest.makeSuite(AssociateRecnoTestCase))
+
+        if db.version() >= (4, 1):
+            suite.addTest(unittest.makeSuite(AssociateBTreeTxnTestCase))
+
+        suite.addTest(unittest.makeSuite(ShelveAssociateHashTestCase))
+        suite.addTest(unittest.makeSuite(ShelveAssociateBTreeTestCase))
+        suite.addTest(unittest.makeSuite(ShelveAssociateRecnoTestCase))
+
+        if have_threads:
+            suite.addTest(unittest.makeSuite(ThreadedAssociateHashTestCase))
+            suite.addTest(unittest.makeSuite(ThreadedAssociateBTreeTestCase))
+            suite.addTest(unittest.makeSuite(ThreadedAssociateRecnoTestCase))
+
+    return suite
+
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')

Added: vendor/Python/current/Lib/bsddb/test/test_basics.py
===================================================================
--- vendor/Python/current/Lib/bsddb/test/test_basics.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/bsddb/test/test_basics.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,989 @@
+"""
+Basic TestCases for BTree and hash DBs, with and without a DBEnv, with
+various DB flags, etc.
+"""
+
+import os
+import sys
+import errno
+import shutil
+import string
+import tempfile
+from pprint import pprint
+import unittest
+import time
+
+try:
+    # For Pythons w/distutils pybsddb
+    from bsddb3 import db
+except ImportError:
+    # For Python 2.3
+    from bsddb import db
+
+from test_all import verbose
+
+DASH = '-'
+
+
+#----------------------------------------------------------------------
+
+class VersionTestCase(unittest.TestCase):
+    def test00_version(self):
+        info = db.version()
+        if verbose:
+            print '\n', '-=' * 20
+            print 'bsddb.db.version(): %s' % (info, )
+            print db.DB_VERSION_STRING
+            print '-=' * 20
+        assert info == (db.DB_VERSION_MAJOR, db.DB_VERSION_MINOR,
+                        db.DB_VERSION_PATCH)
+
+#----------------------------------------------------------------------
+
+class BasicTestCase(unittest.TestCase):
+    dbtype       = db.DB_UNKNOWN  # must be set in derived class
+    dbopenflags  = 0
+    dbsetflags   = 0
+    dbmode       = 0660
+    dbname       = None
+    useEnv       = 0
+    envflags     = 0
+    envsetflags  = 0
+
+    _numKeys      = 1002    # PRIVATE.  NOTE: must be an even value
+
+    def setUp(self):
+        if self.useEnv:
+            homeDir = os.path.join(os.path.dirname(sys.argv[0]), 'db_home')
+            self.homeDir = homeDir
+            try:
+                shutil.rmtree(homeDir)
+            except OSError, e:
+                # unix returns ENOENT, windows returns ESRCH
+                if e.errno not in (errno.ENOENT, errno.ESRCH): raise
+            os.mkdir(homeDir)
+            try:
+                self.env = db.DBEnv()
+                self.env.set_lg_max(1024*1024)
+                self.env.set_tx_max(30)
+                self.env.set_tx_timestamp(int(time.time()))
+                self.env.set_flags(self.envsetflags, 1)
+                self.env.open(homeDir, self.envflags | db.DB_CREATE)
+                tempfile.tempdir = homeDir
+                self.filename = os.path.split(tempfile.mktemp())[1]
+                tempfile.tempdir = None
+            # Yes, a bare except is intended, since we're re-raising the exc.
+            except:
+                shutil.rmtree(homeDir)
+                raise
+        else:
+            self.env = None
+            self.filename = tempfile.mktemp()
+
+        # create and open the DB
+        self.d = db.DB(self.env)
+        self.d.set_flags(self.dbsetflags)
+        if self.dbname:
+            self.d.open(self.filename, self.dbname, self.dbtype,
+                        self.dbopenflags|db.DB_CREATE, self.dbmode)
+        else:
+            self.d.open(self.filename,   # try out keyword args
+                        mode = self.dbmode,
+                        dbtype = self.dbtype,
+                        flags = self.dbopenflags|db.DB_CREATE)
+
+        self.populateDB()
+
+
+    def tearDown(self):
+        self.d.close()
+        if self.env is not None:
+            self.env.close()
+            shutil.rmtree(self.homeDir)
+            ## Make a new DBEnv to remove the env files from the home dir.
+            ## (It can't be done while the env is open, nor after it has been
+            ## closed, so we make a new one to do it.)
+            #e = db.DBEnv()
+            #e.remove(self.homeDir)
+            #os.remove(os.path.join(self.homeDir, self.filename))
+        else:
+            os.remove(self.filename)
+
+
+
+    def populateDB(self, _txn=None):
+        d = self.d
+
+        for x in range(self._numKeys/2):
+            key = '%04d' % (self._numKeys - x)  # insert keys in reverse order
+            data = self.makeData(key)
+            d.put(key, data, _txn)
+
+        d.put('empty value', '', _txn)
+
+        for x in range(self._numKeys/2-1):
+            key = '%04d' % x  # and now some in forward order
+            data = self.makeData(key)
+            d.put(key, data, _txn)
+
+        if _txn:
+            _txn.commit()
+
+        num = len(d)
+        if verbose:
+            print "created %d records" % num
+
+
+    def makeData(self, key):
+        return DASH.join([key] * 5)
+
+
+
+    #----------------------------------------
+
+    def test01_GetsAndPuts(self):
+        d = self.d
+
+        if verbose:
+            print '\n', '-=' * 30
+            print "Running %s.test01_GetsAndPuts..." % self.__class__.__name__
+
+        for key in ['0001', '0100', '0400', '0700', '0999']:
+            data = d.get(key)
+            if verbose:
+                print data
+
+        assert d.get('0321') == '0321-0321-0321-0321-0321'
+
+        # By default non-existant keys return None...
+        assert d.get('abcd') == None
+
+        # ...but they raise exceptions in other situations.  Call
+        # set_get_returns_none() to change it.
+        try:
+            d.delete('abcd')
+        except db.DBNotFoundError, val:
+            assert val[0] == db.DB_NOTFOUND
+            if verbose: print val
+        else:
+            self.fail("expected exception")
+
+
+        d.put('abcd', 'a new record')
+        assert d.get('abcd') == 'a new record'
+
+        d.put('abcd', 'same key')
+        if self.dbsetflags & db.DB_DUP:
+            assert d.get('abcd') == 'a new record'
+        else:
+            assert d.get('abcd') == 'same key'
+
+
+        try:
+            d.put('abcd', 'this should fail', flags=db.DB_NOOVERWRITE)
+        except db.DBKeyExistError, val:
+            assert val[0] == db.DB_KEYEXIST
+            if verbose: print val
+        else:
+            self.fail("expected exception")
+
+        if self.dbsetflags & db.DB_DUP:
+            assert d.get('abcd') == 'a new record'
+        else:
+            assert d.get('abcd') == 'same key'
+
+
+        d.sync()
+        d.close()
+        del d
+
+        self.d = db.DB(self.env)
+        if self.dbname:
+            self.d.open(self.filename, self.dbname)
+        else:
+            self.d.open(self.filename)
+        d = self.d
+
+        assert d.get('0321') == '0321-0321-0321-0321-0321'
+        if self.dbsetflags & db.DB_DUP:
+            assert d.get('abcd') == 'a new record'
+        else:
+            assert d.get('abcd') == 'same key'
+
+        rec = d.get_both('0555', '0555-0555-0555-0555-0555')
+        if verbose:
+            print rec
+
+        assert d.get_both('0555', 'bad data') == None
+
+        # test default value
+        data = d.get('bad key', 'bad data')
+        assert data == 'bad data'
+
+        # any object can pass through
+        data = d.get('bad key', self)
+        assert data == self
+
+        s = d.stat()
+        assert type(s) == type({})
+        if verbose:
+            print 'd.stat() returned this dictionary:'
+            pprint(s)
+
+
+    #----------------------------------------
+
+    def test02_DictionaryMethods(self):
+        d = self.d
+
+        if verbose:
+            print '\n', '-=' * 30
+            print "Running %s.test02_DictionaryMethods..." % \
+                  self.__class__.__name__
+
+        for key in ['0002', '0101', '0401', '0701', '0998']:
+            data = d[key]
+            assert data == self.makeData(key)
+            if verbose:
+                print data
+
+        assert len(d) == self._numKeys
+        keys = d.keys()
+        assert len(keys) == self._numKeys
+        assert type(keys) == type([])
+
+        d['new record'] = 'a new record'
+        assert len(d) == self._numKeys+1
+        keys = d.keys()
+        assert len(keys) == self._numKeys+1
+
+        d['new record'] = 'a replacement record'
+        assert len(d) == self._numKeys+1
+        keys = d.keys()
+        assert len(keys) == self._numKeys+1
+
+        if verbose:
+            print "the first 10 keys are:"
+            pprint(keys[:10])
+
+        assert d['new record'] == 'a replacement record'
+
+        assert d.has_key('0001') == 1
+        assert d.has_key('spam') == 0
+
+        items = d.items()
+        assert len(items) == self._numKeys+1
+        assert type(items) == type([])
+        assert type(items[0]) == type(())
+        assert len(items[0]) == 2
+
+        if verbose:
+            print "the first 10 items are:"
+            pprint(items[:10])
+
+        values = d.values()
+        assert len(values) == self._numKeys+1
+        assert type(values) == type([])
+
+        if verbose:
+            print "the first 10 values are:"
+            pprint(values[:10])
+
+
+
+    #----------------------------------------
+
+    def test03_SimpleCursorStuff(self, get_raises_error=0, set_raises_error=0):
+        if verbose:
+            print '\n', '-=' * 30
+            print "Running %s.test03_SimpleCursorStuff (get_error %s, set_error %s)..." % \
+                  (self.__class__.__name__, get_raises_error, set_raises_error)
+
+        if self.env and self.dbopenflags & db.DB_AUTO_COMMIT:
+            txn = self.env.txn_begin()
+        else:
+            txn = None
+        c = self.d.cursor(txn=txn)
+
+        rec = c.first()
+        count = 0
+        while rec is not None:
+            count = count + 1
+            if verbose and count % 100 == 0:
+                print rec
+            try:
+                rec = c.next()
+            except db.DBNotFoundError, val:
+                if get_raises_error:
+                    assert val[0] == db.DB_NOTFOUND
+                    if verbose: print val
+                    rec = None
+                else:
+                    self.fail("unexpected DBNotFoundError")
+            assert c.get_current_size() == len(c.current()[1]), "%s != len(%r)" % (c.get_current_size(), c.current()[1])
+
+        assert count == self._numKeys
+
+
+        rec = c.last()
+        count = 0
+        while rec is not None:
+            count = count + 1
+            if verbose and count % 100 == 0:
+                print rec
+            try:
+                rec = c.prev()
+            except db.DBNotFoundError, val:
+                if get_raises_error:
+                    assert val[0] == db.DB_NOTFOUND
+                    if verbose: print val
+                    rec = None
+                else:
+                    self.fail("unexpected DBNotFoundError")
+
+        assert count == self._numKeys
+
+        rec = c.set('0505')
+        rec2 = c.current()
+        assert rec == rec2
+        assert rec[0] == '0505'
+        assert rec[1] == self.makeData('0505')
+        assert c.get_current_size() == len(rec[1])
+
+        # make sure we get empty values properly
+        rec = c.set('empty value')
+        assert rec[1] == ''
+        assert c.get_current_size() == 0
+
+        try:
+            n = c.set('bad key')
+        except db.DBNotFoundError, val:
+            assert val[0] == db.DB_NOTFOUND
+            if verbose: print val
+        else:
+            if set_raises_error:
+                self.fail("expected exception")
+            if n != None:
+                self.fail("expected None: %r" % (n,))
+
+        rec = c.get_both('0404', self.makeData('0404'))
+        assert rec == ('0404', self.makeData('0404'))
+
+        try:
+            n = c.get_both('0404', 'bad data')
+        except db.DBNotFoundError, val:
+            assert val[0] == db.DB_NOTFOUND
+            if verbose: print val
+        else:
+            if get_raises_error:
+                self.fail("expected exception")
+            if n != None:
+                self.fail("expected None: %r" % (n,))
+
+        if self.d.get_type() == db.DB_BTREE:
+            rec = c.set_range('011')
+            if verbose:
+                print "searched for '011', found: ", rec
+
+            rec = c.set_range('011',dlen=0,doff=0)
+            if verbose:
+                print "searched (partial) for '011', found: ", rec
+            if rec[1] != '': self.fail('expected empty data portion')
+
+            ev = c.set_range('empty value')
+            if verbose:
+                print "search for 'empty value' returned", ev
+            if ev[1] != '': self.fail('empty value lookup failed')
+
+        c.set('0499')
+        c.delete()
+        try:
+            rec = c.current()
+        except db.DBKeyEmptyError, val:
+            if get_raises_error:
+                assert val[0] == db.DB_KEYEMPTY
+                if verbose: print val
+            else:
+                self.fail("unexpected DBKeyEmptyError")
+        else:
+            if get_raises_error:
+                self.fail('DBKeyEmptyError exception expected')
+
+        c.next()
+        c2 = c.dup(db.DB_POSITION)
+        assert c.current() == c2.current()
+
+        c2.put('', 'a new value', db.DB_CURRENT)
+        assert c.current() == c2.current()
+        assert c.current()[1] == 'a new value'
+
+        c2.put('', 'er', db.DB_CURRENT, dlen=0, doff=5)
+        assert c2.current()[1] == 'a newer value'
+
+        c.close()
+        c2.close()
+        if txn:
+            txn.commit()
+
+        # time to abuse the closed cursors and hope we don't crash
+        methods_to_test = {
+            'current': (),
+            'delete': (),
+            'dup': (db.DB_POSITION,),
+            'first': (),
+            'get': (0,),
+            'next': (),
+            'prev': (),
+            'last': (),
+            'put':('', 'spam', db.DB_CURRENT),
+            'set': ("0505",),
+        }
+        for method, args in methods_to_test.items():
+            try:
+                if verbose:
+                    print "attempting to use a closed cursor's %s method" % \
+                          method
+                # a bug may cause a NULL pointer dereference...
+                apply(getattr(c, method), args)
+            except db.DBError, val:
+                assert val[0] == 0
+                if verbose: print val
+            else:
+                self.fail("no exception raised when using a buggy cursor's"
+                          "%s method" % method)
+
+        #
+        # free cursor referencing a closed database, it should not barf:
+        #
+        oldcursor = self.d.cursor(txn=txn)
+        self.d.close()
+
+        # this would originally cause a segfault when the cursor for a
+        # closed database was cleaned up.  it should not anymore.
+        # SF pybsddb bug id 667343
+        del oldcursor
+
+    def test03b_SimpleCursorWithoutGetReturnsNone0(self):
+        # same test but raise exceptions instead of returning None
+        if verbose:
+            print '\n', '-=' * 30
+            print "Running %s.test03b_SimpleCursorStuffWithoutGetReturnsNone..." % \
+                  self.__class__.__name__
+
+        old = self.d.set_get_returns_none(0)
+        assert old == 2
+        self.test03_SimpleCursorStuff(get_raises_error=1, set_raises_error=1)
+
+    def test03b_SimpleCursorWithGetReturnsNone1(self):
+        # same test but raise exceptions instead of returning None
+        if verbose:
+            print '\n', '-=' * 30
+            print "Running %s.test03b_SimpleCursorStuffWithoutGetReturnsNone..." % \
+                  self.__class__.__name__
+
+        old = self.d.set_get_returns_none(1)
+        self.test03_SimpleCursorStuff(get_raises_error=0, set_raises_error=1)
+
+
+    def test03c_SimpleCursorGetReturnsNone2(self):
+        # same test but raise exceptions instead of returning None
+        if verbose:
+            print '\n', '-=' * 30
+            print "Running %s.test03c_SimpleCursorStuffWithoutSetReturnsNone..." % \
+                  self.__class__.__name__
+
+        old = self.d.set_get_returns_none(1)
+        assert old == 2
+        old = self.d.set_get_returns_none(2)
+        assert old == 1
+        self.test03_SimpleCursorStuff(get_raises_error=0, set_raises_error=0)
+
+    #----------------------------------------
+
+    def test04_PartialGetAndPut(self):
+        d = self.d
+        if verbose:
+            print '\n', '-=' * 30
+            print "Running %s.test04_PartialGetAndPut..." % \
+                  self.__class__.__name__
+
+        key = "partialTest"
+        data = "1" * 1000 + "2" * 1000
+        d.put(key, data)
+        assert d.get(key) == data
+        assert d.get(key, dlen=20, doff=990) == ("1" * 10) + ("2" * 10)
+
+        d.put("partialtest2", ("1" * 30000) + "robin" )
+        assert d.get("partialtest2", dlen=5, doff=30000) == "robin"
+
+        # There seems to be a bug in DB here...  Commented out the test for
+        # now.
+        ##assert d.get("partialtest2", dlen=5, doff=30010) == ""
+
+        if self.dbsetflags != db.DB_DUP:
+            # Partial put with duplicate records requires a cursor
+            d.put(key, "0000", dlen=2000, doff=0)
+            assert d.get(key) == "0000"
+
+            d.put(key, "1111", dlen=1, doff=2)
+            assert d.get(key) == "0011110"
+
+    #----------------------------------------
+
+    def test05_GetSize(self):
+        d = self.d
+        if verbose:
+            print '\n', '-=' * 30
+            print "Running %s.test05_GetSize..." % self.__class__.__name__
+
+        for i in range(1, 50000, 500):
+            key = "size%s" % i
+            #print "before ", i,
+            d.put(key, "1" * i)
+            #print "after",
+            assert d.get_size(key) == i
+            #print "done"
+
+    #----------------------------------------
+
+    def test06_Truncate(self):
+        if db.version() < (3,3):
+            # truncate is a feature of BerkeleyDB 3.3 and above
+            return
+
+        d = self.d
+        if verbose:
+            print '\n', '-=' * 30
+            print "Running %s.test99_Truncate..." % self.__class__.__name__
+
+        d.put("abcde", "ABCDE");
+        num = d.truncate()
+        assert num >= 1, "truncate returned <= 0 on non-empty database"
+        num = d.truncate()
+        assert num == 0, "truncate on empty DB returned nonzero (%r)" % (num,)
+
+    #----------------------------------------
+
+
+#----------------------------------------------------------------------
+
+
+class BasicBTreeTestCase(BasicTestCase):
+    dbtype = db.DB_BTREE
+
+
+class BasicHashTestCase(BasicTestCase):
+    dbtype = db.DB_HASH
+
+
+class BasicBTreeWithThreadFlagTestCase(BasicTestCase):
+    dbtype = db.DB_BTREE
+    dbopenflags = db.DB_THREAD
+
+
+class BasicHashWithThreadFlagTestCase(BasicTestCase):
+    dbtype = db.DB_HASH
+    dbopenflags = db.DB_THREAD
+
+
+class BasicWithEnvTestCase(BasicTestCase):
+    dbopenflags = db.DB_THREAD
+    useEnv = 1
+    envflags = db.DB_THREAD | db.DB_INIT_MPOOL | db.DB_INIT_LOCK
+
+    #----------------------------------------
+
+    def test07_EnvRemoveAndRename(self):
+        if not self.env:
+            return
+
+        if verbose:
+            print '\n', '-=' * 30
+            print "Running %s.test07_EnvRemoveAndRename..." % self.__class__.__name__
+
+        # can't rename or remove an open DB
+        self.d.close()
+
+        newname = self.filename + '.renamed'
+        self.env.dbrename(self.filename, None, newname)
+        self.env.dbremove(newname)
+
+    # dbremove and dbrename are in 4.1 and later
+    if db.version() < (4,1):
+        del test07_EnvRemoveAndRename
+
+    #----------------------------------------
+
+class BasicBTreeWithEnvTestCase(BasicWithEnvTestCase):
+    dbtype = db.DB_BTREE
+
+
+class BasicHashWithEnvTestCase(BasicWithEnvTestCase):
+    dbtype = db.DB_HASH
+
+
+#----------------------------------------------------------------------
+
+class BasicTransactionTestCase(BasicTestCase):
+    dbopenflags = db.DB_THREAD | db.DB_AUTO_COMMIT
+    useEnv = 1
+    envflags = (db.DB_THREAD | db.DB_INIT_MPOOL | db.DB_INIT_LOCK |
+                db.DB_INIT_TXN)
+    envsetflags = db.DB_AUTO_COMMIT
+
+
+    def tearDown(self):
+        self.txn.commit()
+        BasicTestCase.tearDown(self)
+
+
+    def populateDB(self):
+        txn = self.env.txn_begin()
+        BasicTestCase.populateDB(self, _txn=txn)
+
+        self.txn = self.env.txn_begin()
+
+
+    def test06_Transactions(self):
+        d = self.d
+        if verbose:
+            print '\n', '-=' * 30
+            print "Running %s.test06_Transactions..." % self.__class__.__name__
+
+        assert d.get('new rec', txn=self.txn) == None
+        d.put('new rec', 'this is a new record', self.txn)
+        assert d.get('new rec', txn=self.txn) == 'this is a new record'
+        self.txn.abort()
+        assert d.get('new rec') == None
+
+        self.txn = self.env.txn_begin()
+
+        assert d.get('new rec', txn=self.txn) == None
+        d.put('new rec', 'this is a new record', self.txn)
+        assert d.get('new rec', txn=self.txn) == 'this is a new record'
+        self.txn.commit()
+        assert d.get('new rec') == 'this is a new record'
+
+        self.txn = self.env.txn_begin()
+        c = d.cursor(self.txn)
+        rec = c.first()
+        count = 0
+        while rec is not None:
+            count = count + 1
+            if verbose and count % 100 == 0:
+                print rec
+            rec = c.next()
+        assert count == self._numKeys+1
+
+        c.close()                # Cursors *MUST* be closed before commit!
+        self.txn.commit()
+
+        # flush pending updates
+        try:
+            self.env.txn_checkpoint (0, 0, 0)
+        except db.DBIncompleteError:
+            pass
+
+        if db.version() >= (4,0):
+            statDict = self.env.log_stat(0);
+            assert statDict.has_key('magic')
+            assert statDict.has_key('version')
+            assert statDict.has_key('cur_file')
+            assert statDict.has_key('region_nowait')
+
+        # must have at least one log file present:
+        logs = self.env.log_archive(db.DB_ARCH_ABS | db.DB_ARCH_LOG)
+        assert logs != None
+        for log in logs:
+            if verbose:
+                print 'log file: ' + log
+        if db.version() >= (4,2):
+            logs = self.env.log_archive(db.DB_ARCH_REMOVE)
+            assert not logs
+
+        self.txn = self.env.txn_begin()
+
+    #----------------------------------------
+
+    def test07_TxnTruncate(self):
+        if db.version() < (3,3):
+            # truncate is a feature of BerkeleyDB 3.3 and above
+            return
+
+        d = self.d
+        if verbose:
+            print '\n', '-=' * 30
+            print "Running %s.test07_TxnTruncate..." % self.__class__.__name__
+
+        d.put("abcde", "ABCDE");
+        txn = self.env.txn_begin()
+        num = d.truncate(txn)
+        assert num >= 1, "truncate returned <= 0 on non-empty database"
+        num = d.truncate(txn)
+        assert num == 0, "truncate on empty DB returned nonzero (%r)" % (num,)
+        txn.commit()
+
+    #----------------------------------------
+
+    def test08_TxnLateUse(self):
+        txn = self.env.txn_begin()
+        txn.abort()
+        try:
+            txn.abort()
+        except db.DBError, e:
+            pass
+        else:
+            raise RuntimeError, "DBTxn.abort() called after DB_TXN no longer valid w/o an exception"
+
+        txn = self.env.txn_begin()
+        txn.commit()
+        try:
+            txn.commit()
+        except db.DBError, e:
+            pass
+        else:
+            raise RuntimeError, "DBTxn.commit() called after DB_TXN no longer valid w/o an exception"
+
+
+class BTreeTransactionTestCase(BasicTransactionTestCase):
+    dbtype = db.DB_BTREE
+
+class HashTransactionTestCase(BasicTransactionTestCase):
+    dbtype = db.DB_HASH
+
+
+
+#----------------------------------------------------------------------
+
+class BTreeRecnoTestCase(BasicTestCase):
+    dbtype     = db.DB_BTREE
+    dbsetflags = db.DB_RECNUM
+
+    def test07_RecnoInBTree(self):
+        d = self.d
+        if verbose:
+            print '\n', '-=' * 30
+            print "Running %s.test07_RecnoInBTree..." % self.__class__.__name__
+
+        rec = d.get(200)
+        assert type(rec) == type(())
+        assert len(rec) == 2
+        if verbose:
+            print "Record #200 is ", rec
+
+        c = d.cursor()
+        c.set('0200')
+        num = c.get_recno()
+        assert type(num) == type(1)
+        if verbose:
+            print "recno of d['0200'] is ", num
+
+        rec = c.current()
+        assert c.set_recno(num) == rec
+
+        c.close()
+
+
+
+class BTreeRecnoWithThreadFlagTestCase(BTreeRecnoTestCase):
+    dbopenflags = db.DB_THREAD
+
+#----------------------------------------------------------------------
+
+class BasicDUPTestCase(BasicTestCase):
+    dbsetflags = db.DB_DUP
+
+    def test08_DuplicateKeys(self):
+        d = self.d
+        if verbose:
+            print '\n', '-=' * 30
+            print "Running %s.test08_DuplicateKeys..." % \
+                  self.__class__.__name__
+
+        d.put("dup0", "before")
+        for x in "The quick brown fox jumped over the lazy dog.".split():
+            d.put("dup1", x)
+        d.put("dup2", "after")
+
+        data = d.get("dup1")
+        assert data == "The"
+        if verbose:
+            print data
+
+        c = d.cursor()
+        rec = c.set("dup1")
+        assert rec == ('dup1', 'The')
+
+        next = c.next()
+        assert next == ('dup1', 'quick')
+
+        rec = c.set("dup1")
+        count = c.count()
+        assert count == 9
+
+        next_dup = c.next_dup()
+        assert next_dup == ('dup1', 'quick')
+
+        rec = c.set('dup1')
+        while rec is not None:
+            if verbose:
+                print rec
+            rec = c.next_dup()
+
+        c.set('dup1')
+        rec = c.next_nodup()
+        assert rec[0] != 'dup1'
+        if verbose:
+            print rec
+
+        c.close()
+
+
+
+class BTreeDUPTestCase(BasicDUPTestCase):
+    dbtype = db.DB_BTREE
+
+class HashDUPTestCase(BasicDUPTestCase):
+    dbtype = db.DB_HASH
+
+class BTreeDUPWithThreadTestCase(BasicDUPTestCase):
+    dbtype = db.DB_BTREE
+    dbopenflags = db.DB_THREAD
+
+class HashDUPWithThreadTestCase(BasicDUPTestCase):
+    dbtype = db.DB_HASH
+    dbopenflags = db.DB_THREAD
+
+
+#----------------------------------------------------------------------
+
+class BasicMultiDBTestCase(BasicTestCase):
+    dbname = 'first'
+
+    def otherType(self):
+        if self.dbtype == db.DB_BTREE:
+            return db.DB_HASH
+        else:
+            return db.DB_BTREE
+
+    def test09_MultiDB(self):
+        d1 = self.d
+        if verbose:
+            print '\n', '-=' * 30
+            print "Running %s.test09_MultiDB..." % self.__class__.__name__
+
+        d2 = db.DB(self.env)
+        d2.open(self.filename, "second", self.dbtype,
+                self.dbopenflags|db.DB_CREATE)
+        d3 = db.DB(self.env)
+        d3.open(self.filename, "third", self.otherType(),
+                self.dbopenflags|db.DB_CREATE)
+
+        for x in "The quick brown fox jumped over the lazy dog".split():
+            d2.put(x, self.makeData(x))
+
+        for x in string.letters:
+            d3.put(x, x*70)
+
+        d1.sync()
+        d2.sync()
+        d3.sync()
+        d1.close()
+        d2.close()
+        d3.close()
+
+        self.d = d1 = d2 = d3 = None
+
+        self.d = d1 = db.DB(self.env)
+        d1.open(self.filename, self.dbname, flags = self.dbopenflags)
+        d2 = db.DB(self.env)
+        d2.open(self.filename, "second",  flags = self.dbopenflags)
+        d3 = db.DB(self.env)
+        d3.open(self.filename, "third", flags = self.dbopenflags)
+
+        c1 = d1.cursor()
+        c2 = d2.cursor()
+        c3 = d3.cursor()
+
+        count = 0
+        rec = c1.first()
+        while rec is not None:
+            count = count + 1
+            if verbose and (count % 50) == 0:
+                print rec
+            rec = c1.next()
+        assert count == self._numKeys
+
+        count = 0
+        rec = c2.first()
+        while rec is not None:
+            count = count + 1
+            if verbose:
+                print rec
+            rec = c2.next()
+        assert count == 9
+
+        count = 0
+        rec = c3.first()
+        while rec is not None:
+            count = count + 1
+            if verbose:
+                print rec
+            rec = c3.next()
+        assert count == 52
+
+
+        c1.close()
+        c2.close()
+        c3.close()
+
+        d2.close()
+        d3.close()
+
+
+
+# Strange things happen if you try to use Multiple DBs per file without a
+# DBEnv with MPOOL and LOCKing...
+
+class BTreeMultiDBTestCase(BasicMultiDBTestCase):
+    dbtype = db.DB_BTREE
+    dbopenflags = db.DB_THREAD
+    useEnv = 1
+    envflags = db.DB_THREAD | db.DB_INIT_MPOOL | db.DB_INIT_LOCK
+
+class HashMultiDBTestCase(BasicMultiDBTestCase):
+    dbtype = db.DB_HASH
+    dbopenflags = db.DB_THREAD
+    useEnv = 1
+    envflags = db.DB_THREAD | db.DB_INIT_MPOOL | db.DB_INIT_LOCK
+
+
+#----------------------------------------------------------------------
+#----------------------------------------------------------------------
+
+def test_suite():
+    suite = unittest.TestSuite()
+
+    suite.addTest(unittest.makeSuite(VersionTestCase))
+    suite.addTest(unittest.makeSuite(BasicBTreeTestCase))
+    suite.addTest(unittest.makeSuite(BasicHashTestCase))
+    suite.addTest(unittest.makeSuite(BasicBTreeWithThreadFlagTestCase))
+    suite.addTest(unittest.makeSuite(BasicHashWithThreadFlagTestCase))
+    suite.addTest(unittest.makeSuite(BasicBTreeWithEnvTestCase))
+    suite.addTest(unittest.makeSuite(BasicHashWithEnvTestCase))
+    suite.addTest(unittest.makeSuite(BTreeTransactionTestCase))
+    suite.addTest(unittest.makeSuite(HashTransactionTestCase))
+    suite.addTest(unittest.makeSuite(BTreeRecnoTestCase))
+    suite.addTest(unittest.makeSuite(BTreeRecnoWithThreadFlagTestCase))
+    suite.addTest(unittest.makeSuite(BTreeDUPTestCase))
+    suite.addTest(unittest.makeSuite(HashDUPTestCase))
+    suite.addTest(unittest.makeSuite(BTreeDUPWithThreadTestCase))
+    suite.addTest(unittest.makeSuite(HashDUPWithThreadTestCase))
+    suite.addTest(unittest.makeSuite(BTreeMultiDBTestCase))
+    suite.addTest(unittest.makeSuite(HashMultiDBTestCase))
+
+    return suite
+
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')

Added: vendor/Python/current/Lib/bsddb/test/test_compare.py
===================================================================
--- vendor/Python/current/Lib/bsddb/test/test_compare.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/bsddb/test/test_compare.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,249 @@
+"""
+TestCases for python DB Btree key comparison function.
+"""
+
+import sys, os, re
+import test_all
+from cStringIO import StringIO
+
+import unittest
+try:
+    # For Pythons w/distutils pybsddb
+    from bsddb3 import db, dbshelve
+except ImportError:
+    # For Python 2.3
+    from bsddb import db, dbshelve
+
+lexical_cmp = cmp
+
+def lowercase_cmp(left, right):
+    return cmp (left.lower(), right.lower())
+
+def make_reverse_comparator (cmp):
+    def reverse (left, right, delegate=cmp):
+        return - delegate (left, right)
+    return reverse
+
+_expected_lexical_test_data = ['', 'CCCP', 'a', 'aaa', 'b', 'c', 'cccce', 'ccccf']
+_expected_lowercase_test_data = ['', 'a', 'aaa', 'b', 'c', 'CC', 'cccce', 'ccccf', 'CCCP']
+
+class ComparatorTests (unittest.TestCase):
+    def comparator_test_helper (self, comparator, expected_data):
+        data = expected_data[:]
+        data.sort (comparator)
+        self.failUnless (data == expected_data,
+                         "comparator `%s' is not right: %s vs. %s"
+                         % (comparator, expected_data, data))
+    def test_lexical_comparator (self):
+        self.comparator_test_helper (lexical_cmp, _expected_lexical_test_data)
+    def test_reverse_lexical_comparator (self):
+        rev = _expected_lexical_test_data[:]
+        rev.reverse ()
+        self.comparator_test_helper (make_reverse_comparator (lexical_cmp),
+                                     rev)
+    def test_lowercase_comparator (self):
+        self.comparator_test_helper (lowercase_cmp,
+                                     _expected_lowercase_test_data)
+
+class AbstractBtreeKeyCompareTestCase (unittest.TestCase):
+    env = None
+    db = None
+
+    def setUp (self):
+        self.filename = self.__class__.__name__ + '.db'
+        homeDir = os.path.join (os.path.dirname (sys.argv[0]), 'db_home')
+        self.homeDir = homeDir
+        try:
+            os.mkdir (homeDir)
+        except os.error:
+            pass
+
+        env = db.DBEnv ()
+        env.open (homeDir,
+                  db.DB_CREATE | db.DB_INIT_MPOOL
+                  | db.DB_INIT_LOCK | db.DB_THREAD)
+        self.env = env
+
+    def tearDown (self):
+        self.closeDB ()
+        if self.env is not None:
+            self.env.close ()
+            self.env = None
+        import glob
+        map (os.remove, glob.glob (os.path.join (self.homeDir, '*')))
+
+    def addDataToDB (self, data):
+        i = 0
+        for item in data:
+            self.db.put (item, str (i))
+            i = i + 1
+
+    def createDB (self, key_comparator):
+        self.db = db.DB (self.env)
+        self.setupDB (key_comparator)
+        self.db.open (self.filename, "test", db.DB_BTREE, db.DB_CREATE)
+
+    def setupDB (self, key_comparator):
+        self.db.set_bt_compare (key_comparator)
+
+    def closeDB (self):
+        if self.db is not None:
+            self.db.close ()
+            self.db = None
+
+    def startTest (self):
+        pass
+
+    def finishTest (self, expected = None):
+        if expected is not None:
+            self.check_results (expected)
+        self.closeDB ()
+
+    def check_results (self, expected):
+        curs = self.db.cursor ()
+        try:
+            index = 0
+            rec = curs.first ()
+            while rec:
+                key, ignore = rec
+                self.failUnless (index < len (expected),
+                                 "to many values returned from cursor")
+                self.failUnless (expected[index] == key,
+                                 "expected value `%s' at %d but got `%s'"
+                                 % (expected[index], index, key))
+                index = index + 1
+                rec = curs.next ()
+            self.failUnless (index == len (expected),
+                             "not enough values returned from cursor")
+        finally:
+            curs.close ()
+
+class BtreeKeyCompareTestCase (AbstractBtreeKeyCompareTestCase):
+    def runCompareTest (self, comparator, data):
+        self.startTest ()
+        self.createDB (comparator)
+        self.addDataToDB (data)
+        self.finishTest (data)
+
+    def test_lexical_ordering (self):
+        self.runCompareTest (lexical_cmp, _expected_lexical_test_data)
+
+    def test_reverse_lexical_ordering (self):
+        expected_rev_data = _expected_lexical_test_data[:]
+        expected_rev_data.reverse ()
+        self.runCompareTest (make_reverse_comparator (lexical_cmp),
+                             expected_rev_data)
+
+    def test_compare_function_useless (self):
+        self.startTest ()
+        def socialist_comparator (l, r):
+            return 0
+        self.createDB (socialist_comparator)
+        self.addDataToDB (['b', 'a', 'd'])
+        # all things being equal the first key will be the only key
+        # in the database...  (with the last key's value fwiw)
+        self.finishTest (['b'])
+
+
+class BtreeExceptionsTestCase (AbstractBtreeKeyCompareTestCase):
+    def test_raises_non_callable (self):
+        self.startTest ()
+        self.assertRaises (TypeError, self.createDB, 'abc')
+        self.assertRaises (TypeError, self.createDB, None)
+        self.finishTest ()
+
+    def test_set_bt_compare_with_function (self):
+        self.startTest ()
+        self.createDB (lexical_cmp)
+        self.finishTest ()
+
+    def check_results (self, results):
+        pass
+
+    def test_compare_function_incorrect (self):
+        self.startTest ()
+        def bad_comparator (l, r):
+            return 1
+        # verify that set_bt_compare checks that comparator('', '') == 0
+        self.assertRaises (TypeError, self.createDB, bad_comparator)
+        self.finishTest ()
+
+    def verifyStderr(self, method, successRe):
+        """
+        Call method() while capturing sys.stderr output internally and
+        call self.fail() if successRe.search() does not match the stderr
+        output.  This is used to test for uncatchable exceptions.
+        """
+        stdErr = sys.stderr
+        sys.stderr = StringIO()
+        try:
+            method()
+        finally:
+            temp = sys.stderr
+            sys.stderr = stdErr
+            errorOut = temp.getvalue()
+            if not successRe.search(errorOut):
+                self.fail("unexpected stderr output:\n"+errorOut)
+
+    def _test_compare_function_exception (self):
+        self.startTest ()
+        def bad_comparator (l, r):
+            if l == r:
+                # pass the set_bt_compare test
+                return 0
+            raise RuntimeError, "i'm a naughty comparison function"
+        self.createDB (bad_comparator)
+        #print "\n*** test should print 2 uncatchable tracebacks ***"
+        self.addDataToDB (['a', 'b', 'c'])  # this should raise, but...
+        self.finishTest ()
+
+    def test_compare_function_exception(self):
+        self.verifyStderr(
+                self._test_compare_function_exception,
+                re.compile('(^RuntimeError:.* naughty.*){2}', re.M|re.S)
+        )
+
+    def _test_compare_function_bad_return (self):
+        self.startTest ()
+        def bad_comparator (l, r):
+            if l == r:
+                # pass the set_bt_compare test
+                return 0
+            return l
+        self.createDB (bad_comparator)
+        #print "\n*** test should print 2 errors about returning an int ***"
+        self.addDataToDB (['a', 'b', 'c'])  # this should raise, but...
+        self.finishTest ()
+
+    def test_compare_function_bad_return(self):
+        self.verifyStderr(
+                self._test_compare_function_bad_return,
+                re.compile('(^TypeError:.* return an int.*){2}', re.M|re.S)
+        )
+
+
+    def test_cannot_assign_twice (self):
+
+        def my_compare (a, b):
+            return 0
+
+        self.startTest ()
+        self.createDB (my_compare)
+        try:
+            self.db.set_bt_compare (my_compare)
+            assert False, "this set should fail"
+
+        except RuntimeError, msg:
+            pass
+
+def test_suite ():
+    res = unittest.TestSuite ()
+
+    res.addTest (unittest.makeSuite (ComparatorTests))
+    if db.version () >= (3, 3, 11):
+        res.addTest (unittest.makeSuite (BtreeExceptionsTestCase))
+        res.addTest (unittest.makeSuite (BtreeKeyCompareTestCase))
+    return res
+
+if __name__ == '__main__':
+    unittest.main (defaultTest = 'suite')

Added: vendor/Python/current/Lib/bsddb/test/test_compat.py
===================================================================
--- vendor/Python/current/Lib/bsddb/test/test_compat.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/bsddb/test/test_compat.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,191 @@
+"""
+Test cases adapted from the test_bsddb.py module in Python's
+regression test suite.
+"""
+
+import sys, os, string
+import unittest
+import tempfile
+
+from test_all import verbose
+
+try:
+    # For Pythons w/distutils pybsddb
+    from bsddb3 import db, hashopen, btopen, rnopen
+except ImportError:
+    # For Python 2.3
+    from bsddb import db, hashopen, btopen, rnopen
+
+
+class CompatibilityTestCase(unittest.TestCase):
+    def setUp(self):
+        self.filename = tempfile.mktemp()
+
+    def tearDown(self):
+        try:
+            os.remove(self.filename)
+        except os.error:
+            pass
+
+
+    def test01_btopen(self):
+        self.do_bthash_test(btopen, 'btopen')
+
+    def test02_hashopen(self):
+        self.do_bthash_test(hashopen, 'hashopen')
+
+    def test03_rnopen(self):
+        data = string.split("The quick brown fox jumped over the lazy dog.")
+        if verbose:
+            print "\nTesting: rnopen"
+
+        f = rnopen(self.filename, 'c')
+        for x in range(len(data)):
+            f[x+1] = data[x]
+
+        getTest = (f[1], f[2], f[3])
+        if verbose:
+            print '%s %s %s' % getTest
+
+        assert getTest[1] == 'quick', 'data mismatch!'
+
+        rv = f.set_location(3)
+        if rv != (3, 'brown'):
+            self.fail('recno database set_location failed: '+repr(rv))
+
+        f[25] = 'twenty-five'
+        f.close()
+        del f
+
+        f = rnopen(self.filename, 'w')
+        f[20] = 'twenty'
+
+        def noRec(f):
+            rec = f[15]
+        self.assertRaises(KeyError, noRec, f)
+
+        def badKey(f):
+            rec = f['a string']
+        self.assertRaises(TypeError, badKey, f)
+
+        del f[3]
+
+        rec = f.first()
+        while rec:
+            if verbose:
+                print rec
+            try:
+                rec = f.next()
+            except KeyError:
+                break
+
+        f.close()
+
+
+    def test04_n_flag(self):
+        f = hashopen(self.filename, 'n')
+        f.close()
+
+
+    def do_bthash_test(self, factory, what):
+        if verbose:
+            print '\nTesting: ', what
+
+        f = factory(self.filename, 'c')
+        if verbose:
+            print 'creation...'
+
+        # truth test
+        if f:
+            if verbose: print "truth test: true"
+        else:
+            if verbose: print "truth test: false"
+
+        f['0'] = ''
+        f['a'] = 'Guido'
+        f['b'] = 'van'
+        f['c'] = 'Rossum'
+        f['d'] = 'invented'
+        # 'e' intentionally left out
+        f['f'] = 'Python'
+        if verbose:
+            print '%s %s %s' % (f['a'], f['b'], f['c'])
+
+        if verbose:
+            print 'key ordering...'
+        start = f.set_location(f.first()[0])
+        if start != ('0', ''):
+            self.fail("incorrect first() result: "+repr(start))
+        while 1:
+            try:
+                rec = f.next()
+            except KeyError:
+                assert rec == f.last(), 'Error, last <> last!'
+                f.previous()
+                break
+            if verbose:
+                print rec
+
+        assert f.has_key('f'), 'Error, missing key!'
+
+        # test that set_location() returns the next nearest key, value
+        # on btree databases and raises KeyError on others.
+        if factory == btopen:
+            e = f.set_location('e')
+            if e != ('f', 'Python'):
+                self.fail('wrong key,value returned: '+repr(e))
+        else:
+            try:
+                e = f.set_location('e')
+            except KeyError:
+                pass
+            else:
+                self.fail("set_location on non-existant key did not raise KeyError")
+
+        f.sync()
+        f.close()
+        # truth test
+        try:
+            if f:
+                if verbose: print "truth test: true"
+            else:
+                if verbose: print "truth test: false"
+        except db.DBError:
+            pass
+        else:
+            self.fail("Exception expected")
+
+        del f
+
+        if verbose:
+            print 'modification...'
+        f = factory(self.filename, 'w')
+        f['d'] = 'discovered'
+
+        if verbose:
+            print 'access...'
+        for key in f.keys():
+            word = f[key]
+            if verbose:
+                print word
+
+        def noRec(f):
+            rec = f['no such key']
+        self.assertRaises(KeyError, noRec, f)
+
+        def badKey(f):
+            rec = f[15]
+        self.assertRaises(TypeError, badKey, f)
+
+        f.close()
+
+
+#----------------------------------------------------------------------
+
+
+def test_suite():
+    return unittest.makeSuite(CompatibilityTestCase)
+
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')

Added: vendor/Python/current/Lib/bsddb/test/test_cursor_pget_bug.py
===================================================================
--- vendor/Python/current/Lib/bsddb/test/test_cursor_pget_bug.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/bsddb/test/test_cursor_pget_bug.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,65 @@
+import unittest
+import sys, os, glob
+
+try:
+    # For Pythons w/distutils pybsddb
+    from bsddb3 import db
+except ImportError:
+    # For Python 2.3
+    from bsddb import db
+
+
+#----------------------------------------------------------------------
+
+class pget_bugTestCase(unittest.TestCase):
+    """Verify that cursor.pget works properly"""
+    db_name = 'test-cursor_pget.db'
+
+    def setUp(self):
+        self.homeDir = os.path.join(os.path.dirname(sys.argv[0]), 'db_home')
+        try:
+            os.mkdir(self.homeDir)
+        except os.error:
+            pass
+        self.env = db.DBEnv()
+        self.env.open(self.homeDir, db.DB_CREATE | db.DB_INIT_MPOOL)
+        self.primary_db = db.DB(self.env)
+        self.primary_db.open(self.db_name, 'primary', db.DB_BTREE, db.DB_CREATE)
+        self.secondary_db = db.DB(self.env)
+        self.secondary_db.set_flags(db.DB_DUP)
+        self.secondary_db.open(self.db_name, 'secondary', db.DB_BTREE, db.DB_CREATE)
+        self.primary_db.associate(self.secondary_db, lambda key, data: data)
+        self.primary_db.put('salad', 'eggs')
+        self.primary_db.put('spam', 'ham')
+        self.primary_db.put('omelet', 'eggs')
+
+
+    def tearDown(self):
+        self.secondary_db.close()
+        self.primary_db.close()
+        self.env.close()
+        del self.secondary_db
+        del self.primary_db
+        del self.env
+        for file in glob.glob(os.path.join(self.homeDir, '*')):
+            os.remove(file)
+        os.removedirs(self.homeDir)
+
+    def test_pget(self):
+        cursor = self.secondary_db.cursor()
+
+        self.assertEquals(('eggs', 'salad', 'eggs'), cursor.pget(key='eggs', flags=db.DB_SET))
+        self.assertEquals(('eggs', 'omelet', 'eggs'), cursor.pget(db.DB_NEXT_DUP))
+        self.assertEquals(None, cursor.pget(db.DB_NEXT_DUP))
+
+        self.assertEquals(('ham', 'spam', 'ham'), cursor.pget('ham', 'spam', flags=db.DB_SET))
+        self.assertEquals(None, cursor.pget(db.DB_NEXT_DUP))
+
+        cursor.close()
+
+
+def test_suite():
+    return unittest.makeSuite(pget_bugTestCase)
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')

Added: vendor/Python/current/Lib/bsddb/test/test_dbobj.py
===================================================================
--- vendor/Python/current/Lib/bsddb/test/test_dbobj.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/bsddb/test/test_dbobj.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,82 @@
+
+import sys, os, string
+import unittest
+import glob
+
+try:
+    # For Pythons w/distutils pybsddb
+    from bsddb3 import db, dbobj
+except ImportError:
+    # For Python 2.3
+    from bsddb import db, dbobj
+
+
+#----------------------------------------------------------------------
+
+class dbobjTestCase(unittest.TestCase):
+    """Verify that dbobj.DB and dbobj.DBEnv work properly"""
+    db_home = 'db_home'
+    db_name = 'test-dbobj.db'
+
+    def setUp(self):
+        homeDir = os.path.join(os.path.dirname(sys.argv[0]), 'db_home')
+        self.homeDir = homeDir
+        try: os.mkdir(homeDir)
+        except os.error: pass
+
+    def tearDown(self):
+        if hasattr(self, 'db'):
+            del self.db
+        if hasattr(self, 'env'):
+            del self.env
+        files = glob.glob(os.path.join(self.homeDir, '*'))
+        for file in files:
+            os.remove(file)
+
+    def test01_both(self):
+        class TestDBEnv(dbobj.DBEnv): pass
+        class TestDB(dbobj.DB):
+            def put(self, key, *args, **kwargs):
+                key = string.upper(key)
+                # call our parent classes put method with an upper case key
+                return apply(dbobj.DB.put, (self, key) + args, kwargs)
+        self.env = TestDBEnv()
+        self.env.open(self.homeDir, db.DB_CREATE | db.DB_INIT_MPOOL)
+        self.db = TestDB(self.env)
+        self.db.open(self.db_name, db.DB_HASH, db.DB_CREATE)
+        self.db.put('spam', 'eggs')
+        assert self.db.get('spam') == None, \
+               "overridden dbobj.DB.put() method failed [1]"
+        assert self.db.get('SPAM') == 'eggs', \
+               "overridden dbobj.DB.put() method failed [2]"
+        self.db.close()
+        self.env.close()
+
+    def test02_dbobj_dict_interface(self):
+        self.env = dbobj.DBEnv()
+        self.env.open(self.homeDir, db.DB_CREATE | db.DB_INIT_MPOOL)
+        self.db = dbobj.DB(self.env)
+        self.db.open(self.db_name+'02', db.DB_HASH, db.DB_CREATE)
+        # __setitem__
+        self.db['spam'] = 'eggs'
+        # __len__
+        assert len(self.db) == 1
+        # __getitem__
+        assert self.db['spam'] == 'eggs'
+        # __del__
+        del self.db['spam']
+        assert self.db.get('spam') == None, "dbobj __del__ failed"
+        self.db.close()
+        self.env.close()
+
+    def test03_dbobj_type_before_open(self):
+        # Ensure this doesn't cause a segfault.
+        self.assertRaises(db.DBInvalidArgError, db.DB().type)
+
+#----------------------------------------------------------------------
+
+def test_suite():
+    return unittest.makeSuite(dbobjTestCase)
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')

Added: vendor/Python/current/Lib/bsddb/test/test_dbshelve.py
===================================================================
--- vendor/Python/current/Lib/bsddb/test/test_dbshelve.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/bsddb/test/test_dbshelve.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,306 @@
+"""
+TestCases for checking dbShelve objects.
+"""
+
+import sys, os, string
+import tempfile, random
+from pprint import pprint
+from types import *
+import unittest
+
+try:
+    # For Pythons w/distutils pybsddb
+    from bsddb3 import db, dbshelve
+except ImportError:
+    # For Python 2.3
+    from bsddb import db, dbshelve
+
+from test_all import verbose
+
+
+#----------------------------------------------------------------------
+
+# We want the objects to be comparable so we can test dbshelve.values
+# later on.
+class DataClass:
+    def __init__(self):
+        self.value = random.random()
+
+    def __cmp__(self, other):
+        return cmp(self.value, other)
+
+class DBShelveTestCase(unittest.TestCase):
+    def setUp(self):
+        self.filename = tempfile.mktemp()
+        self.do_open()
+
+    def tearDown(self):
+        self.do_close()
+        try:
+            os.remove(self.filename)
+        except os.error:
+            pass
+
+    def populateDB(self, d):
+        for x in string.letters:
+            d['S' + x] = 10 * x           # add a string
+            d['I' + x] = ord(x)           # add an integer
+            d['L' + x] = [x] * 10         # add a list
+
+            inst = DataClass()            # add an instance
+            inst.S = 10 * x
+            inst.I = ord(x)
+            inst.L = [x] * 10
+            d['O' + x] = inst
+
+
+    # overridable in derived classes to affect how the shelf is created/opened
+    def do_open(self):
+        self.d = dbshelve.open(self.filename)
+
+    # and closed...
+    def do_close(self):
+        self.d.close()
+
+
+
+    def test01_basics(self):
+        if verbose:
+            print '\n', '-=' * 30
+            print "Running %s.test01_basics..." % self.__class__.__name__
+
+        self.populateDB(self.d)
+        self.d.sync()
+        self.do_close()
+        self.do_open()
+        d = self.d
+
+        l = len(d)
+        k = d.keys()
+        s = d.stat()
+        f = d.fd()
+
+        if verbose:
+            print "length:", l
+            print "keys:", k
+            print "stats:", s
+
+        assert 0 == d.has_key('bad key')
+        assert 1 == d.has_key('IA')
+        assert 1 == d.has_key('OA')
+
+        d.delete('IA')
+        del d['OA']
+        assert 0 == d.has_key('IA')
+        assert 0 == d.has_key('OA')
+        assert len(d) == l-2
+
+        values = []
+        for key in d.keys():
+            value = d[key]
+            values.append(value)
+            if verbose:
+                print "%s: %s" % (key, value)
+            self.checkrec(key, value)
+
+        dbvalues = d.values()
+        assert len(dbvalues) == len(d.keys())
+        values.sort()
+        dbvalues.sort()
+        assert values == dbvalues
+
+        items = d.items()
+        assert len(items) == len(values)
+
+        for key, value in items:
+            self.checkrec(key, value)
+
+        assert d.get('bad key') == None
+        assert d.get('bad key', None) == None
+        assert d.get('bad key', 'a string') == 'a string'
+        assert d.get('bad key', [1, 2, 3]) == [1, 2, 3]
+
+        d.set_get_returns_none(0)
+        self.assertRaises(db.DBNotFoundError, d.get, 'bad key')
+        d.set_get_returns_none(1)
+
+        d.put('new key', 'new data')
+        assert d.get('new key') == 'new data'
+        assert d['new key'] == 'new data'
+
+
+
+    def test02_cursors(self):
+        if verbose:
+            print '\n', '-=' * 30
+            print "Running %s.test02_cursors..." % self.__class__.__name__
+
+        self.populateDB(self.d)
+        d = self.d
+
+        count = 0
+        c = d.cursor()
+        rec = c.first()
+        while rec is not None:
+            count = count + 1
+            if verbose:
+                print rec
+            key, value = rec
+            self.checkrec(key, value)
+            rec = c.next()
+        del c
+
+        assert count == len(d)
+
+        count = 0
+        c = d.cursor()
+        rec = c.last()
+        while rec is not None:
+            count = count + 1
+            if verbose:
+                print rec
+            key, value = rec
+            self.checkrec(key, value)
+            rec = c.prev()
+
+        assert count == len(d)
+
+        c.set('SS')
+        key, value = c.current()
+        self.checkrec(key, value)
+        del c
+
+
+
+    def checkrec(self, key, value):
+        x = key[1]
+        if key[0] == 'S':
+            assert type(value) == StringType
+            assert value == 10 * x
+
+        elif key[0] == 'I':
+            assert type(value) == IntType
+            assert value == ord(x)
+
+        elif key[0] == 'L':
+            assert type(value) == ListType
+            assert value == [x] * 10
+
+        elif key[0] == 'O':
+            assert type(value) == InstanceType
+            assert value.S == 10 * x
+            assert value.I == ord(x)
+            assert value.L == [x] * 10
+
+        else:
+            raise AssertionError, 'Unknown key type, fix the test'
+
+#----------------------------------------------------------------------
+
+class BasicShelveTestCase(DBShelveTestCase):
+    def do_open(self):
+        self.d = dbshelve.DBShelf()
+        self.d.open(self.filename, self.dbtype, self.dbflags)
+
+    def do_close(self):
+        self.d.close()
+
+
+class BTreeShelveTestCase(BasicShelveTestCase):
+    dbtype = db.DB_BTREE
+    dbflags = db.DB_CREATE
+
+
+class HashShelveTestCase(BasicShelveTestCase):
+    dbtype = db.DB_HASH
+    dbflags = db.DB_CREATE
+
+
+class ThreadBTreeShelveTestCase(BasicShelveTestCase):
+    dbtype = db.DB_BTREE
+    dbflags = db.DB_CREATE | db.DB_THREAD
+
+
+class ThreadHashShelveTestCase(BasicShelveTestCase):
+    dbtype = db.DB_HASH
+    dbflags = db.DB_CREATE | db.DB_THREAD
+
+
+#----------------------------------------------------------------------
+
+class BasicEnvShelveTestCase(DBShelveTestCase):
+    def do_open(self):
+        self.homeDir = homeDir = os.path.join(
+            os.path.dirname(sys.argv[0]), 'db_home')
+        try: os.mkdir(homeDir)
+        except os.error: pass
+        self.env = db.DBEnv()
+        self.env.open(homeDir, self.envflags | db.DB_INIT_MPOOL | db.DB_CREATE)
+
+        self.filename = os.path.split(self.filename)[1]
+        self.d = dbshelve.DBShelf(self.env)
+        self.d.open(self.filename, self.dbtype, self.dbflags)
+
+
+    def do_close(self):
+        self.d.close()
+        self.env.close()
+
+
+    def tearDown(self):
+        self.do_close()
+        import glob
+        files = glob.glob(os.path.join(self.homeDir, '*'))
+        for file in files:
+            os.remove(file)
+
+
+
+class EnvBTreeShelveTestCase(BasicEnvShelveTestCase):
+    envflags = 0
+    dbtype = db.DB_BTREE
+    dbflags = db.DB_CREATE
+
+
+class EnvHashShelveTestCase(BasicEnvShelveTestCase):
+    envflags = 0
+    dbtype = db.DB_HASH
+    dbflags = db.DB_CREATE
+
+
+class EnvThreadBTreeShelveTestCase(BasicEnvShelveTestCase):
+    envflags = db.DB_THREAD
+    dbtype = db.DB_BTREE
+    dbflags = db.DB_CREATE | db.DB_THREAD
+
+
+class EnvThreadHashShelveTestCase(BasicEnvShelveTestCase):
+    envflags = db.DB_THREAD
+    dbtype = db.DB_HASH
+    dbflags = db.DB_CREATE | db.DB_THREAD
+
+
+#----------------------------------------------------------------------
+# TODO:  Add test cases for a DBShelf in a RECNO DB.
+
+
+#----------------------------------------------------------------------
+
+def test_suite():
+    suite = unittest.TestSuite()
+
+    suite.addTest(unittest.makeSuite(DBShelveTestCase))
+    suite.addTest(unittest.makeSuite(BTreeShelveTestCase))
+    suite.addTest(unittest.makeSuite(HashShelveTestCase))
+    suite.addTest(unittest.makeSuite(ThreadBTreeShelveTestCase))
+    suite.addTest(unittest.makeSuite(ThreadHashShelveTestCase))
+    suite.addTest(unittest.makeSuite(EnvBTreeShelveTestCase))
+    suite.addTest(unittest.makeSuite(EnvHashShelveTestCase))
+    suite.addTest(unittest.makeSuite(EnvThreadBTreeShelveTestCase))
+    suite.addTest(unittest.makeSuite(EnvThreadHashShelveTestCase))
+
+    return suite
+
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')

Added: vendor/Python/current/Lib/bsddb/test/test_dbtables.py
===================================================================
--- vendor/Python/current/Lib/bsddb/test/test_dbtables.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/bsddb/test/test_dbtables.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,383 @@
+#!/usr/bin/env python
+#
+#-----------------------------------------------------------------------
+# A test suite for the table interface built on bsddb.db
+#-----------------------------------------------------------------------
+#
+# Copyright (C) 2000, 2001 by Autonomous Zone Industries
+# Copyright (C) 2002 Gregory P. Smith
+#
+# March 20, 2000
+#
+# License:      This is free software.  You may use this software for any
+#               purpose including modification/redistribution, so long as
+#               this header remains intact and that you do not claim any
+#               rights of ownership or authorship of this software.  This
+#               software has been tested, but no warranty is expressed or
+#               implied.
+#
+#   --  Gregory P. Smith <greg at electricrain.com>
+#
+# $Id: test_dbtables.py 46737 2006-06-08 05:38:11Z gregory.p.smith $
+
+import sys, os, re
+try:
+    import cPickle
+    pickle = cPickle
+except ImportError:
+    import pickle
+
+import unittest
+from test_all import verbose
+
+try:
+    # For Pythons w/distutils pybsddb
+    from bsddb3 import db, dbtables
+except ImportError:
+    # For Python 2.3
+    from bsddb import db, dbtables
+
+
+
+#----------------------------------------------------------------------
+
+class TableDBTestCase(unittest.TestCase):
+    db_home = 'db_home'
+    db_name = 'test-table.db'
+
+    def setUp(self):
+        homeDir = os.path.join(os.path.dirname(sys.argv[0]), 'db_home')
+        self.homeDir = homeDir
+        try: os.mkdir(homeDir)
+        except os.error: pass
+        self.tdb = dbtables.bsdTableDB(
+            filename='tabletest.db', dbhome=homeDir, create=1)
+
+    def tearDown(self):
+        self.tdb.close()
+        import glob
+        files = glob.glob(os.path.join(self.homeDir, '*'))
+        for file in files:
+            os.remove(file)
+
+    def test01(self):
+        tabname = "test01"
+        colname = 'cool numbers'
+        try:
+            self.tdb.Drop(tabname)
+        except dbtables.TableDBError:
+            pass
+        self.tdb.CreateTable(tabname, [colname])
+        self.tdb.Insert(tabname, {colname: pickle.dumps(3.14159, 1)})
+
+        if verbose:
+            self.tdb._db_print()
+
+        values = self.tdb.Select(
+            tabname, [colname], conditions={colname: None})
+
+        colval = pickle.loads(values[0][colname])
+        assert(colval > 3.141 and colval < 3.142)
+
+
+    def test02(self):
+        tabname = "test02"
+        col0 = 'coolness factor'
+        col1 = 'but can it fly?'
+        col2 = 'Species'
+        testinfo = [
+            {col0: pickle.dumps(8, 1), col1: 'no', col2: 'Penguin'},
+            {col0: pickle.dumps(-1, 1), col1: 'no', col2: 'Turkey'},
+            {col0: pickle.dumps(9, 1), col1: 'yes', col2: 'SR-71A Blackbird'}
+        ]
+
+        try:
+            self.tdb.Drop(tabname)
+        except dbtables.TableDBError:
+            pass
+        self.tdb.CreateTable(tabname, [col0, col1, col2])
+        for row in testinfo :
+            self.tdb.Insert(tabname, row)
+
+        values = self.tdb.Select(tabname, [col2],
+            conditions={col0: lambda x: pickle.loads(x) >= 8})
+
+        assert len(values) == 2
+        if values[0]['Species'] == 'Penguin' :
+            assert values[1]['Species'] == 'SR-71A Blackbird'
+        elif values[0]['Species'] == 'SR-71A Blackbird' :
+            assert values[1]['Species'] == 'Penguin'
+        else :
+            if verbose:
+                print "values= %r" % (values,)
+            raise "Wrong values returned!"
+
+    def test03(self):
+        tabname = "test03"
+        try:
+            self.tdb.Drop(tabname)
+        except dbtables.TableDBError:
+            pass
+        if verbose:
+            print '...before CreateTable...'
+            self.tdb._db_print()
+        self.tdb.CreateTable(tabname, ['a', 'b', 'c', 'd', 'e'])
+        if verbose:
+            print '...after CreateTable...'
+            self.tdb._db_print()
+        self.tdb.Drop(tabname)
+        if verbose:
+            print '...after Drop...'
+            self.tdb._db_print()
+        self.tdb.CreateTable(tabname, ['a', 'b', 'c', 'd', 'e'])
+
+        try:
+            self.tdb.Insert(tabname,
+                            {'a': "",
+                             'e': pickle.dumps([{4:5, 6:7}, 'foo'], 1),
+                             'f': "Zero"})
+            assert 0
+        except dbtables.TableDBError:
+            pass
+
+        try:
+            self.tdb.Select(tabname, [], conditions={'foo': '123'})
+            assert 0
+        except dbtables.TableDBError:
+            pass
+
+        self.tdb.Insert(tabname,
+                        {'a': '42',
+                         'b': "bad",
+                         'c': "meep",
+                         'e': 'Fuzzy wuzzy was a bear'})
+        self.tdb.Insert(tabname,
+                        {'a': '581750',
+                         'b': "good",
+                         'd': "bla",
+                         'c': "black",
+                         'e': 'fuzzy was here'})
+        self.tdb.Insert(tabname,
+                        {'a': '800000',
+                         'b': "good",
+                         'd': "bla",
+                         'c': "black",
+                         'e': 'Fuzzy wuzzy is a bear'})
+
+        if verbose:
+            self.tdb._db_print()
+
+        # this should return two rows
+        values = self.tdb.Select(tabname, ['b', 'a', 'd'],
+            conditions={'e': re.compile('wuzzy').search,
+                        'a': re.compile('^[0-9]+$').match})
+        assert len(values) == 2
+
+        # now lets delete one of them and try again
+        self.tdb.Delete(tabname, conditions={'b': dbtables.ExactCond('good')})
+        values = self.tdb.Select(
+            tabname, ['a', 'd', 'b'],
+            conditions={'e': dbtables.PrefixCond('Fuzzy')})
+        assert len(values) == 1
+        assert values[0]['d'] == None
+
+        values = self.tdb.Select(tabname, ['b'],
+            conditions={'c': lambda c: c == 'meep'})
+        assert len(values) == 1
+        assert values[0]['b'] == "bad"
+
+
+    def test04_MultiCondSelect(self):
+        tabname = "test04_MultiCondSelect"
+        try:
+            self.tdb.Drop(tabname)
+        except dbtables.TableDBError:
+            pass
+        self.tdb.CreateTable(tabname, ['a', 'b', 'c', 'd', 'e'])
+
+        try:
+            self.tdb.Insert(tabname,
+                            {'a': "",
+                             'e': pickle.dumps([{4:5, 6:7}, 'foo'], 1),
+                             'f': "Zero"})
+            assert 0
+        except dbtables.TableDBError:
+            pass
+
+        self.tdb.Insert(tabname, {'a': "A", 'b': "B", 'c': "C", 'd': "D",
+                                  'e': "E"})
+        self.tdb.Insert(tabname, {'a': "-A", 'b': "-B", 'c': "-C", 'd': "-D",
+                                  'e': "-E"})
+        self.tdb.Insert(tabname, {'a': "A-", 'b': "B-", 'c': "C-", 'd': "D-",
+                                  'e': "E-"})
+
+        if verbose:
+            self.tdb._db_print()
+
+        # This select should return 0 rows.  it is designed to test
+        # the bug identified and fixed in sourceforge bug # 590449
+        # (Big Thanks to "Rob Tillotson (n9mtb)" for tracking this down
+        # and supplying a fix!!  This one caused many headaches to say
+        # the least...)
+        values = self.tdb.Select(tabname, ['b', 'a', 'd'],
+            conditions={'e': dbtables.ExactCond('E'),
+                        'a': dbtables.ExactCond('A'),
+                        'd': dbtables.PrefixCond('-')
+                       } )
+        assert len(values) == 0, values
+
+
+    def test_CreateOrExtend(self):
+        tabname = "test_CreateOrExtend"
+
+        self.tdb.CreateOrExtendTable(
+            tabname, ['name', 'taste', 'filling', 'alcohol content', 'price'])
+        try:
+            self.tdb.Insert(tabname,
+                            {'taste': 'crap',
+                             'filling': 'no',
+                             'is it Guinness?': 'no'})
+            assert 0, "Insert should've failed due to bad column name"
+        except:
+            pass
+        self.tdb.CreateOrExtendTable(tabname,
+                                     ['name', 'taste', 'is it Guinness?'])
+
+        # these should both succeed as the table should contain the union of both sets of columns.
+        self.tdb.Insert(tabname, {'taste': 'crap', 'filling': 'no',
+                                  'is it Guinness?': 'no'})
+        self.tdb.Insert(tabname, {'taste': 'great', 'filling': 'yes',
+                                  'is it Guinness?': 'yes',
+                                  'name': 'Guinness'})
+
+
+    def test_CondObjs(self):
+        tabname = "test_CondObjs"
+
+        self.tdb.CreateTable(tabname, ['a', 'b', 'c', 'd', 'e', 'p'])
+
+        self.tdb.Insert(tabname, {'a': "the letter A",
+                                  'b': "the letter B",
+                                  'c': "is for cookie"})
+        self.tdb.Insert(tabname, {'a': "is for aardvark",
+                                  'e': "the letter E",
+                                  'c': "is for cookie",
+                                  'd': "is for dog"})
+        self.tdb.Insert(tabname, {'a': "the letter A",
+                                  'e': "the letter E",
+                                  'c': "is for cookie",
+                                  'p': "is for Python"})
+
+        values = self.tdb.Select(
+            tabname, ['p', 'e'],
+            conditions={'e': dbtables.PrefixCond('the l')})
+        assert len(values) == 2, values
+        assert values[0]['e'] == values[1]['e'], values
+        assert values[0]['p'] != values[1]['p'], values
+
+        values = self.tdb.Select(
+            tabname, ['d', 'a'],
+            conditions={'a': dbtables.LikeCond('%aardvark%')})
+        assert len(values) == 1, values
+        assert values[0]['d'] == "is for dog", values
+        assert values[0]['a'] == "is for aardvark", values
+
+        values = self.tdb.Select(tabname, None,
+                                 {'b': dbtables.Cond(),
+                                  'e':dbtables.LikeCond('%letter%'),
+                                  'a':dbtables.PrefixCond('is'),
+                                  'd':dbtables.ExactCond('is for dog'),
+                                  'c':dbtables.PrefixCond('is for'),
+                                  'p':lambda s: not s})
+        assert len(values) == 1, values
+        assert values[0]['d'] == "is for dog", values
+        assert values[0]['a'] == "is for aardvark", values
+
+    def test_Delete(self):
+        tabname = "test_Delete"
+        self.tdb.CreateTable(tabname, ['x', 'y', 'z'])
+
+        # prior to 2001-05-09 there was a bug where Delete() would
+        # fail if it encountered any rows that did not have values in
+        # every column.
+        # Hunted and Squashed by <Donwulff> (Jukka Santala - donwulff at nic.fi)
+        self.tdb.Insert(tabname, {'x': 'X1', 'y':'Y1'})
+        self.tdb.Insert(tabname, {'x': 'X2', 'y':'Y2', 'z': 'Z2'})
+
+        self.tdb.Delete(tabname, conditions={'x': dbtables.PrefixCond('X')})
+        values = self.tdb.Select(tabname, ['y'],
+                                 conditions={'x': dbtables.PrefixCond('X')})
+        assert len(values) == 0
+
+    def test_Modify(self):
+        tabname = "test_Modify"
+        self.tdb.CreateTable(tabname, ['Name', 'Type', 'Access'])
+
+        self.tdb.Insert(tabname, {'Name': 'Index to MP3 files.doc',
+                                  'Type': 'Word', 'Access': '8'})
+        self.tdb.Insert(tabname, {'Name': 'Nifty.MP3', 'Access': '1'})
+        self.tdb.Insert(tabname, {'Type': 'Unknown', 'Access': '0'})
+
+        def set_type(type):
+            if type == None:
+                return 'MP3'
+            return type
+
+        def increment_access(count):
+            return str(int(count)+1)
+
+        def remove_value(value):
+            return None
+
+        self.tdb.Modify(tabname,
+                        conditions={'Access': dbtables.ExactCond('0')},
+                        mappings={'Access': remove_value})
+        self.tdb.Modify(tabname,
+                        conditions={'Name': dbtables.LikeCond('%MP3%')},
+                        mappings={'Type': set_type})
+        self.tdb.Modify(tabname,
+                        conditions={'Name': dbtables.LikeCond('%')},
+                        mappings={'Access': increment_access})
+
+        try:
+            self.tdb.Modify(tabname,
+                            conditions={'Name': dbtables.LikeCond('%')},
+                            mappings={'Access': 'What is your quest?'})
+        except TypeError:
+            # success, the string value in mappings isn't callable
+            pass
+        else:
+            raise RuntimeError, "why was TypeError not raised for bad callable?"
+
+        # Delete key in select conditions
+        values = self.tdb.Select(
+            tabname, None,
+            conditions={'Type': dbtables.ExactCond('Unknown')})
+        assert len(values) == 1, values
+        assert values[0]['Name'] == None, values
+        assert values[0]['Access'] == None, values
+
+        # Modify value by select conditions
+        values = self.tdb.Select(
+            tabname, None,
+            conditions={'Name': dbtables.ExactCond('Nifty.MP3')})
+        assert len(values) == 1, values
+        assert values[0]['Type'] == "MP3", values
+        assert values[0]['Access'] == "2", values
+
+        # Make sure change applied only to select conditions
+        values = self.tdb.Select(
+            tabname, None, conditions={'Name': dbtables.LikeCond('%doc%')})
+        assert len(values) == 1, values
+        assert values[0]['Type'] == "Word", values
+        assert values[0]['Access'] == "9", values
+
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(TableDBTestCase))
+    return suite
+
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')

Added: vendor/Python/current/Lib/bsddb/test/test_env_close.py
===================================================================
--- vendor/Python/current/Lib/bsddb/test/test_env_close.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/bsddb/test/test_env_close.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,107 @@
+"""TestCases for checking that it does not segfault when a DBEnv object
+is closed before its DB objects.
+"""
+
+import os
+import sys
+import tempfile
+import glob
+import unittest
+
+try:
+    # For Pythons w/distutils pybsddb
+    from bsddb3 import db
+except ImportError:
+    # For Python 2.3
+    from bsddb import db
+
+from test_all import verbose
+
+# We're going to get warnings in this module about trying to close the db when
+# its env is already closed.  Let's just ignore those.
+try:
+    import warnings
+except ImportError:
+    pass
+else:
+    warnings.filterwarnings('ignore',
+                            message='DB could not be closed in',
+                            category=RuntimeWarning)
+
+
+#----------------------------------------------------------------------
+
+class DBEnvClosedEarlyCrash(unittest.TestCase):
+    def setUp(self):
+        self.homeDir = os.path.join(os.path.dirname(sys.argv[0]), 'db_home')
+        try: os.mkdir(self.homeDir)
+        except os.error: pass
+        tempfile.tempdir = self.homeDir
+        self.filename = os.path.split(tempfile.mktemp())[1]
+        tempfile.tempdir = None
+
+    def tearDown(self):
+        files = glob.glob(os.path.join(self.homeDir, '*'))
+        for file in files:
+            os.remove(file)
+
+
+    def test01_close_dbenv_before_db(self):
+        dbenv = db.DBEnv()
+        dbenv.open(self.homeDir,
+                   db.DB_INIT_CDB| db.DB_CREATE |db.DB_THREAD|db.DB_INIT_MPOOL,
+                   0666)
+
+        d = db.DB(dbenv)
+        d.open(self.filename, db.DB_BTREE, db.DB_CREATE | db.DB_THREAD, 0666)
+
+        try:
+            dbenv.close()
+        except db.DBError:
+            try:
+                d.close()
+            except db.DBError:
+                return
+            assert 0, \
+                   "DB close did not raise an exception about its "\
+                   "DBEnv being trashed"
+
+        # XXX This may fail when using older versions of BerkeleyDB.
+        # E.g. 3.2.9 never raised the exception.
+        assert 0, "dbenv did not raise an exception about its DB being open"
+
+
+    def test02_close_dbenv_delete_db_success(self):
+        dbenv = db.DBEnv()
+        dbenv.open(self.homeDir,
+                   db.DB_INIT_CDB| db.DB_CREATE |db.DB_THREAD|db.DB_INIT_MPOOL,
+                   0666)
+
+        d = db.DB(dbenv)
+        d.open(self.filename, db.DB_BTREE, db.DB_CREATE | db.DB_THREAD, 0666)
+
+        try:
+            dbenv.close()
+        except db.DBError:
+            pass  # good, it should raise an exception
+
+        del d
+        try:
+            import gc
+        except ImportError:
+            gc = None
+        if gc:
+            # force d.__del__ [DB_dealloc] to be called
+            gc.collect()
+
+
+#----------------------------------------------------------------------
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(DBEnvClosedEarlyCrash))
+    return suite
+
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')

Added: vendor/Python/current/Lib/bsddb/test/test_get_none.py
===================================================================
--- vendor/Python/current/Lib/bsddb/test/test_get_none.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/bsddb/test/test_get_none.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,101 @@
+"""
+TestCases for checking set_get_returns_none.
+"""
+
+import sys, os, string
+import tempfile
+from pprint import pprint
+import unittest
+
+try:
+    # For Pythons w/distutils pybsddb
+    from bsddb3 import db
+except ImportError:
+    # For Python 2.3
+    from bsddb import db
+
+from test_all import verbose
+
+
+#----------------------------------------------------------------------
+
+class GetReturnsNoneTestCase(unittest.TestCase):
+    def setUp(self):
+        self.filename = tempfile.mktemp()
+
+    def tearDown(self):
+        try:
+            os.remove(self.filename)
+        except os.error:
+            pass
+
+
+    def test01_get_returns_none(self):
+        d = db.DB()
+        d.open(self.filename, db.DB_BTREE, db.DB_CREATE)
+        d.set_get_returns_none(1)
+
+        for x in string.letters:
+            d.put(x, x * 40)
+
+        data = d.get('bad key')
+        assert data == None
+
+        data = d.get('a')
+        assert data == 'a'*40
+
+        count = 0
+        c = d.cursor()
+        rec = c.first()
+        while rec:
+            count = count + 1
+            rec = c.next()
+
+        assert rec == None
+        assert count == 52
+
+        c.close()
+        d.close()
+
+
+    def test02_get_raises_exception(self):
+        d = db.DB()
+        d.open(self.filename, db.DB_BTREE, db.DB_CREATE)
+        d.set_get_returns_none(0)
+
+        for x in string.letters:
+            d.put(x, x * 40)
+
+        self.assertRaises(db.DBNotFoundError, d.get, 'bad key')
+        self.assertRaises(KeyError, d.get, 'bad key')
+
+        data = d.get('a')
+        assert data == 'a'*40
+
+        count = 0
+        exceptionHappened = 0
+        c = d.cursor()
+        rec = c.first()
+        while rec:
+            count = count + 1
+            try:
+                rec = c.next()
+            except db.DBNotFoundError:  # end of the records
+                exceptionHappened = 1
+                break
+
+        assert rec != None
+        assert exceptionHappened
+        assert count == 52
+
+        c.close()
+        d.close()
+
+#----------------------------------------------------------------------
+
+def test_suite():
+    return unittest.makeSuite(GetReturnsNoneTestCase)
+
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')

Added: vendor/Python/current/Lib/bsddb/test/test_join.py
===================================================================
--- vendor/Python/current/Lib/bsddb/test/test_join.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/bsddb/test/test_join.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,120 @@
+"""TestCases for using the DB.join and DBCursor.join_item methods.
+"""
+
+import sys, os, string
+import tempfile
+import time
+from pprint import pprint
+
+try:
+    from threading import Thread, currentThread
+    have_threads = 1
+except ImportError:
+    have_threads = 0
+
+import unittest
+from test_all import verbose
+
+try:
+    # For Pythons w/distutils pybsddb
+    from bsddb3 import db, dbshelve
+except ImportError:
+    # For Python 2.3
+    from bsddb import db, dbshelve
+
+
+#----------------------------------------------------------------------
+
+ProductIndex = [
+    ('apple', "Convenience Store"),
+    ('blueberry', "Farmer's Market"),
+    ('shotgun', "S-Mart"),              # Aisle 12
+    ('pear', "Farmer's Market"),
+    ('chainsaw', "S-Mart"),             # "Shop smart.  Shop S-Mart!"
+    ('strawberry', "Farmer's Market"),
+]
+
+ColorIndex = [
+    ('blue', "blueberry"),
+    ('red', "apple"),
+    ('red', "chainsaw"),
+    ('red', "strawberry"),
+    ('yellow', "peach"),
+    ('yellow', "pear"),
+    ('black', "shotgun"),
+]
+
+class JoinTestCase(unittest.TestCase):
+    keytype = ''
+
+    def setUp(self):
+        self.filename = self.__class__.__name__ + '.db'
+        homeDir = os.path.join(os.path.dirname(sys.argv[0]), 'db_home')
+        self.homeDir = homeDir
+        try: os.mkdir(homeDir)
+        except os.error: pass
+        self.env = db.DBEnv()
+        self.env.open(homeDir, db.DB_CREATE | db.DB_INIT_MPOOL | db.DB_INIT_LOCK )
+
+    def tearDown(self):
+        self.env.close()
+        import glob
+        files = glob.glob(os.path.join(self.homeDir, '*'))
+        for file in files:
+            os.remove(file)
+
+    def test01_join(self):
+        if verbose:
+            print '\n', '-=' * 30
+            print "Running %s.test01_join..." % \
+                  self.__class__.__name__
+
+        # create and populate primary index
+        priDB = db.DB(self.env)
+        priDB.open(self.filename, "primary", db.DB_BTREE, db.DB_CREATE)
+        map(lambda t, priDB=priDB: apply(priDB.put, t), ProductIndex)
+
+        # create and populate secondary index
+        secDB = db.DB(self.env)
+        secDB.set_flags(db.DB_DUP | db.DB_DUPSORT)
+        secDB.open(self.filename, "secondary", db.DB_BTREE, db.DB_CREATE)
+        map(lambda t, secDB=secDB: apply(secDB.put, t), ColorIndex)
+
+        sCursor = None
+        jCursor = None
+        try:
+            # lets look up all of the red Products
+            sCursor = secDB.cursor()
+            # Don't do the .set() in an assert, or you can get a bogus failure
+            # when running python -O
+            tmp = sCursor.set('red')
+            assert tmp
+
+            # FIXME: jCursor doesn't properly hold a reference to its
+            # cursors, if they are closed before jcursor is used it
+            # can cause a crash.
+            jCursor = priDB.join([sCursor])
+
+            if jCursor.get(0) != ('apple', "Convenience Store"):
+                self.fail("join cursor positioned wrong")
+            if jCursor.join_item() != 'chainsaw':
+                self.fail("DBCursor.join_item returned wrong item")
+            if jCursor.get(0)[0] != 'strawberry':
+                self.fail("join cursor returned wrong thing")
+            if jCursor.get(0):  # there were only three red items to return
+                self.fail("join cursor returned too many items")
+        finally:
+            if jCursor:
+                jCursor.close()
+            if sCursor:
+                sCursor.close()
+            priDB.close()
+            secDB.close()
+
+
+def test_suite():
+    suite = unittest.TestSuite()
+
+    suite.addTest(unittest.makeSuite(JoinTestCase))
+
+    return suite

Added: vendor/Python/current/Lib/bsddb/test/test_lock.py
===================================================================
--- vendor/Python/current/Lib/bsddb/test/test_lock.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/bsddb/test/test_lock.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,143 @@
+"""
+TestCases for testing the locking sub-system.
+"""
+
+import sys, os, string
+import tempfile
+import time
+from pprint import pprint
+
+try:
+    from threading import Thread, currentThread
+    have_threads = 1
+except ImportError:
+    have_threads = 0
+
+
+import unittest
+from test_all import verbose
+
+try:
+    # For Pythons w/distutils pybsddb
+    from bsddb3 import db
+except ImportError:
+    # For Python 2.3
+    from bsddb import db
+
+
+#----------------------------------------------------------------------
+
+class LockingTestCase(unittest.TestCase):
+
+    def setUp(self):
+        homeDir = os.path.join(os.path.dirname(sys.argv[0]), 'db_home')
+        self.homeDir = homeDir
+        try: os.mkdir(homeDir)
+        except os.error: pass
+        self.env = db.DBEnv()
+        self.env.open(homeDir, db.DB_THREAD | db.DB_INIT_MPOOL |
+                      db.DB_INIT_LOCK | db.DB_CREATE)
+
+
+    def tearDown(self):
+        self.env.close()
+        import glob
+        files = glob.glob(os.path.join(self.homeDir, '*'))
+        for file in files:
+            os.remove(file)
+
+
+    def test01_simple(self):
+        if verbose:
+            print '\n', '-=' * 30
+            print "Running %s.test01_simple..." % self.__class__.__name__
+
+        anID = self.env.lock_id()
+        if verbose:
+            print "locker ID: %s" % anID
+        lock = self.env.lock_get(anID, "some locked thing", db.DB_LOCK_WRITE)
+        if verbose:
+            print "Aquired lock: %s" % lock
+        time.sleep(1)
+        self.env.lock_put(lock)
+        if verbose:
+            print "Released lock: %s" % lock
+
+
+
+
+    def test02_threaded(self):
+        if verbose:
+            print '\n', '-=' * 30
+            print "Running %s.test02_threaded..." % self.__class__.__name__
+
+        threads = []
+        threads.append(Thread(target = self.theThread,
+                              args=(5, db.DB_LOCK_WRITE)))
+        threads.append(Thread(target = self.theThread,
+                              args=(1, db.DB_LOCK_READ)))
+        threads.append(Thread(target = self.theThread,
+                              args=(1, db.DB_LOCK_READ)))
+        threads.append(Thread(target = self.theThread,
+                              args=(1, db.DB_LOCK_WRITE)))
+        threads.append(Thread(target = self.theThread,
+                              args=(1, db.DB_LOCK_READ)))
+        threads.append(Thread(target = self.theThread,
+                              args=(1, db.DB_LOCK_READ)))
+        threads.append(Thread(target = self.theThread,
+                              args=(1, db.DB_LOCK_WRITE)))
+        threads.append(Thread(target = self.theThread,
+                              args=(1, db.DB_LOCK_WRITE)))
+        threads.append(Thread(target = self.theThread,
+                              args=(1, db.DB_LOCK_WRITE)))
+
+        for t in threads:
+            t.start()
+        for t in threads:
+            t.join()
+
+    def test03_set_timeout(self):
+        # test that the set_timeout call works
+        if hasattr(self.env, 'set_timeout'):
+            self.env.set_timeout(0, db.DB_SET_LOCK_TIMEOUT)
+            self.env.set_timeout(0, db.DB_SET_TXN_TIMEOUT)
+            self.env.set_timeout(123456, db.DB_SET_LOCK_TIMEOUT)
+            self.env.set_timeout(7890123, db.DB_SET_TXN_TIMEOUT)
+
+    def theThread(self, sleepTime, lockType):
+        name = currentThread().getName()
+        if lockType ==  db.DB_LOCK_WRITE:
+            lt = "write"
+        else:
+            lt = "read"
+
+        anID = self.env.lock_id()
+        if verbose:
+            print "%s: locker ID: %s" % (name, anID)
+
+        lock = self.env.lock_get(anID, "some locked thing", lockType)
+        if verbose:
+            print "%s: Aquired %s lock: %s" % (name, lt, lock)
+
+        time.sleep(sleepTime)
+
+        self.env.lock_put(lock)
+        if verbose:
+            print "%s: Released %s lock: %s" % (name, lt, lock)
+
+
+#----------------------------------------------------------------------
+
+def test_suite():
+    suite = unittest.TestSuite()
+
+    if have_threads:
+        suite.addTest(unittest.makeSuite(LockingTestCase))
+    else:
+        suite.addTest(unittest.makeSuite(LockingTestCase, 'test01'))
+
+    return suite
+
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')

Added: vendor/Python/current/Lib/bsddb/test/test_misc.py
===================================================================
--- vendor/Python/current/Lib/bsddb/test/test_misc.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/bsddb/test/test_misc.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,64 @@
+"""Miscellaneous bsddb module test cases
+"""
+
+import os
+import sys
+import unittest
+
+try:
+    # For Pythons w/distutils pybsddb
+    from bsddb3 import db, dbshelve, hashopen
+except ImportError:
+    # For Python 2.3
+    from bsddb import db, dbshelve, hashopen
+
+#----------------------------------------------------------------------
+
+class MiscTestCase(unittest.TestCase):
+    def setUp(self):
+        self.filename = self.__class__.__name__ + '.db'
+        homeDir = os.path.join(os.path.dirname(sys.argv[0]), 'db_home')
+        self.homeDir = homeDir
+        try:
+            os.mkdir(homeDir)
+        except OSError:
+            pass
+
+    def tearDown(self):
+        try:
+            os.remove(self.filename)
+        except OSError:
+            pass
+        import glob
+        files = glob.glob(os.path.join(self.homeDir, '*'))
+        for file in files:
+            os.remove(file)
+
+    def test01_badpointer(self):
+        dbs = dbshelve.open(self.filename)
+        dbs.close()
+        self.assertRaises(db.DBError, dbs.get, "foo")
+
+    def test02_db_home(self):
+        env = db.DBEnv()
+        # check for crash fixed when db_home is used before open()
+        assert env.db_home is None
+        env.open(self.homeDir, db.DB_CREATE)
+        assert self.homeDir == env.db_home
+
+    def test03_repr_closed_db(self):
+        db = hashopen(self.filename)
+        db.close()
+        rp = repr(db)
+        self.assertEquals(rp, "{}")
+
+
+#----------------------------------------------------------------------
+
+
+def test_suite():
+    return unittest.makeSuite(MiscTestCase)
+
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')

Added: vendor/Python/current/Lib/bsddb/test/test_pickle.py
===================================================================
--- vendor/Python/current/Lib/bsddb/test/test_pickle.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/bsddb/test/test_pickle.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,75 @@
+
+import sys, os, string
+import pickle
+try:
+    import cPickle
+except ImportError:
+    cPickle = None
+import unittest
+import glob
+
+try:
+    # For Pythons w/distutils pybsddb
+    from bsddb3 import db
+except ImportError, e:
+    # For Python 2.3
+    from bsddb import db
+
+
+#----------------------------------------------------------------------
+
+class pickleTestCase(unittest.TestCase):
+    """Verify that DBError can be pickled and unpickled"""
+    db_home = 'db_home'
+    db_name = 'test-dbobj.db'
+
+    def setUp(self):
+        homeDir = os.path.join(os.path.dirname(sys.argv[0]), 'db_home')
+        self.homeDir = homeDir
+        try: os.mkdir(homeDir)
+        except os.error: pass
+
+    def tearDown(self):
+        if hasattr(self, 'db'):
+            del self.db
+        if hasattr(self, 'env'):
+            del self.env
+        files = glob.glob(os.path.join(self.homeDir, '*'))
+        for file in files:
+            os.remove(file)
+
+    def _base_test_pickle_DBError(self, pickle):
+        self.env = db.DBEnv()
+        self.env.open(self.homeDir, db.DB_CREATE | db.DB_INIT_MPOOL)
+        self.db = db.DB(self.env)
+        self.db.open(self.db_name, db.DB_HASH, db.DB_CREATE)
+        self.db.put('spam', 'eggs')
+        assert self.db['spam'] == 'eggs'
+        try:
+            self.db.put('spam', 'ham', flags=db.DB_NOOVERWRITE)
+        except db.DBError, egg:
+            pickledEgg = pickle.dumps(egg)
+            #print repr(pickledEgg)
+            rottenEgg = pickle.loads(pickledEgg)
+            if rottenEgg.args != egg.args or type(rottenEgg) != type(egg):
+                raise Exception, (rottenEgg, '!=', egg)
+        else:
+            raise Exception, "where's my DBError exception?!?"
+
+        self.db.close()
+        self.env.close()
+
+    def test01_pickle_DBError(self):
+        self._base_test_pickle_DBError(pickle=pickle)
+
+    if cPickle:
+        def test02_cPickle_DBError(self):
+            self._base_test_pickle_DBError(pickle=cPickle)
+
+#----------------------------------------------------------------------
+
+def test_suite():
+    return unittest.makeSuite(pickleTestCase)
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')

Added: vendor/Python/current/Lib/bsddb/test/test_queue.py
===================================================================
--- vendor/Python/current/Lib/bsddb/test/test_queue.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/bsddb/test/test_queue.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,173 @@
+"""
+TestCases for exercising a Queue DB.
+"""
+
+import sys, os, string
+import tempfile
+from pprint import pprint
+import unittest
+
+try:
+    # For Pythons w/distutils pybsddb
+    from bsddb3 import db
+except ImportError:
+    # For Python 2.3
+    from bsddb import db
+
+from test_all import verbose
+
+
+#----------------------------------------------------------------------
+
+class SimpleQueueTestCase(unittest.TestCase):
+    def setUp(self):
+        self.filename = tempfile.mktemp()
+
+    def tearDown(self):
+        try:
+            os.remove(self.filename)
+        except os.error:
+            pass
+
+
+    def test01_basic(self):
+        # Basic Queue tests using the deprecated DBCursor.consume method.
+
+        if verbose:
+            print '\n', '-=' * 30
+            print "Running %s.test01_basic..." % self.__class__.__name__
+
+        d = db.DB()
+        d.set_re_len(40)  # Queues must be fixed length
+        d.open(self.filename, db.DB_QUEUE, db.DB_CREATE)
+
+        if verbose:
+            print "before appends" + '-' * 30
+            pprint(d.stat())
+
+        for x in string.letters:
+            d.append(x * 40)
+
+        assert len(d) == 52
+
+        d.put(100, "some more data")
+        d.put(101, "and some more ")
+        d.put(75,  "out of order")
+        d.put(1,   "replacement data")
+
+        assert len(d) == 55
+
+        if verbose:
+            print "before close" + '-' * 30
+            pprint(d.stat())
+
+        d.close()
+        del d
+        d = db.DB()
+        d.open(self.filename)
+
+        if verbose:
+            print "after open" + '-' * 30
+            pprint(d.stat())
+
+        d.append("one more")
+        c = d.cursor()
+
+        if verbose:
+            print "after append" + '-' * 30
+            pprint(d.stat())
+
+        rec = c.consume()
+        while rec:
+            if verbose:
+                print rec
+            rec = c.consume()
+        c.close()
+
+        if verbose:
+            print "after consume loop" + '-' * 30
+            pprint(d.stat())
+
+        assert len(d) == 0, \
+               "if you see this message then you need to rebuild " \
+               "BerkeleyDB 3.1.17 with the patch in patches/qam_stat.diff"
+
+        d.close()
+
+
+
+    def test02_basicPost32(self):
+        # Basic Queue tests using the new DB.consume method in DB 3.2+
+        # (No cursor needed)
+
+        if verbose:
+            print '\n', '-=' * 30
+            print "Running %s.test02_basicPost32..." % self.__class__.__name__
+
+        if db.version() < (3, 2, 0):
+            if verbose:
+                print "Test not run, DB not new enough..."
+            return
+
+        d = db.DB()
+        d.set_re_len(40)  # Queues must be fixed length
+        d.open(self.filename, db.DB_QUEUE, db.DB_CREATE)
+
+        if verbose:
+            print "before appends" + '-' * 30
+            pprint(d.stat())
+
+        for x in string.letters:
+            d.append(x * 40)
+
+        assert len(d) == 52
+
+        d.put(100, "some more data")
+        d.put(101, "and some more ")
+        d.put(75,  "out of order")
+        d.put(1,   "replacement data")
+
+        assert len(d) == 55
+
+        if verbose:
+            print "before close" + '-' * 30
+            pprint(d.stat())
+
+        d.close()
+        del d
+        d = db.DB()
+        d.open(self.filename)
+        #d.set_get_returns_none(true)
+
+        if verbose:
+            print "after open" + '-' * 30
+            pprint(d.stat())
+
+        d.append("one more")
+
+        if verbose:
+            print "after append" + '-' * 30
+            pprint(d.stat())
+
+        rec = d.consume()
+        while rec:
+            if verbose:
+                print rec
+            rec = d.consume()
+
+        if verbose:
+            print "after consume loop" + '-' * 30
+            pprint(d.stat())
+
+        d.close()
+
+
+
+#----------------------------------------------------------------------
+
+def test_suite():
+    return unittest.makeSuite(SimpleQueueTestCase)
+
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')

Added: vendor/Python/current/Lib/bsddb/test/test_recno.py
===================================================================
--- vendor/Python/current/Lib/bsddb/test/test_recno.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/bsddb/test/test_recno.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,295 @@
+"""TestCases for exercising a Recno DB.
+"""
+
+import os
+import sys
+import errno
+import tempfile
+from pprint import pprint
+import unittest
+
+from test_all import verbose
+
+try:
+    # For Pythons w/distutils pybsddb
+    from bsddb3 import db
+except ImportError:
+    # For Python 2.3
+    from bsddb import db
+
+letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
+
+
+#----------------------------------------------------------------------
+
+class SimpleRecnoTestCase(unittest.TestCase):
+    def setUp(self):
+        self.filename = tempfile.mktemp()
+
+    def tearDown(self):
+        try:
+            os.remove(self.filename)
+        except OSError, e:
+            if e.errno <> errno.EEXIST: raise
+
+    def test01_basic(self):
+        d = db.DB()
+
+        get_returns_none = d.set_get_returns_none(2)
+        d.set_get_returns_none(get_returns_none)
+
+        d.open(self.filename, db.DB_RECNO, db.DB_CREATE)
+
+        for x in letters:
+            recno = d.append(x * 60)
+            assert type(recno) == type(0)
+            assert recno >= 1
+            if verbose:
+                print recno,
+
+        if verbose: print
+
+        stat = d.stat()
+        if verbose:
+            pprint(stat)
+
+        for recno in range(1, len(d)+1):
+            data = d[recno]
+            if verbose:
+                print data
+
+            assert type(data) == type("")
+            assert data == d.get(recno)
+
+        try:
+            data = d[0]  # This should raise a KeyError!?!?!
+        except db.DBInvalidArgError, val:
+            assert val[0] == db.EINVAL
+            if verbose: print val
+        else:
+            self.fail("expected exception")
+
+        # test that has_key raises DB exceptions (fixed in pybsddb 4.3.2)
+        try:
+            d.has_key(0)
+        except db.DBError, val:
+            pass
+        else:
+            self.fail("has_key did not raise a proper exception")
+
+        try:
+            data = d[100]
+        except KeyError:
+            pass
+        else:
+            self.fail("expected exception")
+
+        try:
+            data = d.get(100)
+        except db.DBNotFoundError, val:
+            if get_returns_none:
+                self.fail("unexpected exception")
+        else:
+            assert data == None
+
+        keys = d.keys()
+        if verbose:
+            print keys
+        assert type(keys) == type([])
+        assert type(keys[0]) == type(123)
+        assert len(keys) == len(d)
+
+        items = d.items()
+        if verbose:
+            pprint(items)
+        assert type(items) == type([])
+        assert type(items[0]) == type(())
+        assert len(items[0]) == 2
+        assert type(items[0][0]) == type(123)
+        assert type(items[0][1]) == type("")
+        assert len(items) == len(d)
+
+        assert d.has_key(25)
+
+        del d[25]
+        assert not d.has_key(25)
+
+        d.delete(13)
+        assert not d.has_key(13)
+
+        data = d.get_both(26, "z" * 60)
+        assert data == "z" * 60
+        if verbose:
+            print data
+
+        fd = d.fd()
+        if verbose:
+            print fd
+
+        c = d.cursor()
+        rec = c.first()
+        while rec:
+            if verbose:
+                print rec
+            rec = c.next()
+
+        c.set(50)
+        rec = c.current()
+        if verbose:
+            print rec
+
+        c.put(-1, "a replacement record", db.DB_CURRENT)
+
+        c.set(50)
+        rec = c.current()
+        assert rec == (50, "a replacement record")
+        if verbose:
+            print rec
+
+        rec = c.set_range(30)
+        if verbose:
+            print rec
+
+        # test that non-existant key lookups work (and that
+        # DBC_set_range doesn't have a memleak under valgrind)
+        rec = c.set_range(999999)
+        assert rec == None
+        if verbose:
+            print rec
+
+        c.close()
+        d.close()
+
+        d = db.DB()
+        d.open(self.filename)
+        c = d.cursor()
+
+        # put a record beyond the consecutive end of the recno's
+        d[100] = "way out there"
+        assert d[100] == "way out there"
+
+        try:
+            data = d[99]
+        except KeyError:
+            pass
+        else:
+            self.fail("expected exception")
+
+        try:
+            d.get(99)
+        except db.DBKeyEmptyError, val:
+            if get_returns_none:
+                self.fail("unexpected DBKeyEmptyError exception")
+            else:
+                assert val[0] == db.DB_KEYEMPTY
+                if verbose: print val
+        else:
+            if not get_returns_none:
+                self.fail("expected exception")
+
+        rec = c.set(40)
+        while rec:
+            if verbose:
+                print rec
+            rec = c.next()
+
+        c.close()
+        d.close()
+
+    def test02_WithSource(self):
+        """
+        A Recno file that is given a "backing source file" is essentially a
+        simple ASCII file.  Normally each record is delimited by \n and so is
+        just a line in the file, but you can set a different record delimiter
+        if needed.
+        """
+        source = os.path.join(os.path.dirname(sys.argv[0]),
+                              'db_home/test_recno.txt')
+        if not os.path.isdir('db_home'):
+            os.mkdir('db_home')
+        f = open(source, 'w') # create the file
+        f.close()
+
+        d = db.DB()
+        # This is the default value, just checking if both int
+        d.set_re_delim(0x0A)
+        d.set_re_delim('\n')  # and char can be used...
+        d.set_re_source(source)
+        d.open(self.filename, db.DB_RECNO, db.DB_CREATE)
+
+        data = "The quick brown fox jumped over the lazy dog".split()
+        for datum in data:
+            d.append(datum)
+        d.sync()
+        d.close()
+
+        # get the text from the backing source
+        text = open(source, 'r').read()
+        text = text.strip()
+        if verbose:
+            print text
+            print data
+            print text.split('\n')
+
+        assert text.split('\n') == data
+
+        # open as a DB again
+        d = db.DB()
+        d.set_re_source(source)
+        d.open(self.filename, db.DB_RECNO)
+
+        d[3] = 'reddish-brown'
+        d[8] = 'comatose'
+
+        d.sync()
+        d.close()
+
+        text = open(source, 'r').read()
+        text = text.strip()
+        if verbose:
+            print text
+            print text.split('\n')
+
+        assert text.split('\n') == \
+             "The quick reddish-brown fox jumped over the comatose dog".split()
+
+    def test03_FixedLength(self):
+        d = db.DB()
+        d.set_re_len(40)  # fixed length records, 40 bytes long
+        d.set_re_pad('-') # sets the pad character...
+        d.set_re_pad(45)  # ...test both int and char
+        d.open(self.filename, db.DB_RECNO, db.DB_CREATE)
+
+        for x in letters:
+            d.append(x * 35)    # These will be padded
+
+        d.append('.' * 40)      # this one will be exact
+
+        try:                    # this one will fail
+            d.append('bad' * 20)
+        except db.DBInvalidArgError, val:
+            assert val[0] == db.EINVAL
+            if verbose: print val
+        else:
+            self.fail("expected exception")
+
+        c = d.cursor()
+        rec = c.first()
+        while rec:
+            if verbose:
+                print rec
+            rec = c.next()
+
+        c.close()
+        d.close()
+
+
+#----------------------------------------------------------------------
+
+
+def test_suite():
+    return unittest.makeSuite(SimpleRecnoTestCase)
+
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')

Added: vendor/Python/current/Lib/bsddb/test/test_sequence.py
===================================================================
--- vendor/Python/current/Lib/bsddb/test/test_sequence.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/bsddb/test/test_sequence.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,112 @@
+import unittest
+import os
+import sys
+import tempfile
+import glob
+
+try:
+    # For Pythons w/distutils pybsddb
+    from bsddb3 import db
+except ImportError:
+    from bsddb import db
+
+from test_all import verbose
+
+
+class DBSequenceTest(unittest.TestCase):
+    def setUp(self):
+        self.int_32_max = 0x100000000
+        self.homeDir = os.path.join(os.path.dirname(sys.argv[0]), 'db_home')
+        try:
+            os.mkdir(self.homeDir)
+        except os.error:
+            pass
+        tempfile.tempdir = self.homeDir
+        self.filename = os.path.split(tempfile.mktemp())[1]
+        tempfile.tempdir = None
+
+        self.dbenv = db.DBEnv()
+        self.dbenv.open(self.homeDir, db.DB_CREATE | db.DB_INIT_MPOOL, 0666)
+        self.d = db.DB(self.dbenv)
+        self.d.open(self.filename, db.DB_BTREE, db.DB_CREATE, 0666)
+
+    def tearDown(self):
+        if hasattr(self, 'seq'):
+            self.seq.close()
+            del self.seq
+        if hasattr(self, 'd'):
+            self.d.close()
+            del self.d
+        if hasattr(self, 'dbenv'):
+            self.dbenv.close()
+            del self.dbenv
+
+        files = glob.glob(os.path.join(self.homeDir, '*'))
+        for file in files:
+            os.remove(file)
+
+    def test_get(self):
+        self.seq = db.DBSequence(self.d, flags=0)
+        start_value = 10 * self.int_32_max
+        self.assertEqual(0xA00000000, start_value)
+        self.assertEquals(None, self.seq.init_value(start_value))
+        self.assertEquals(None, self.seq.open(key='id', txn=None, flags=db.DB_CREATE))
+        self.assertEquals(start_value, self.seq.get(5))
+        self.assertEquals(start_value + 5, self.seq.get())
+
+    def test_remove(self):
+        self.seq = db.DBSequence(self.d, flags=0)
+        self.assertEquals(None, self.seq.open(key='foo', txn=None, flags=db.DB_CREATE))
+        self.assertEquals(None, self.seq.remove(txn=None, flags=0))
+        del self.seq
+
+    def test_get_key(self):
+        self.seq = db.DBSequence(self.d, flags=0)
+        key = 'foo'
+        self.assertEquals(None, self.seq.open(key=key, txn=None, flags=db.DB_CREATE))
+        self.assertEquals(key, self.seq.get_key())
+
+    def test_get_dbp(self):
+        self.seq = db.DBSequence(self.d, flags=0)
+        self.assertEquals(None, self.seq.open(key='foo', txn=None, flags=db.DB_CREATE))
+        self.assertEquals(self.d, self.seq.get_dbp())
+
+    def test_cachesize(self):
+        self.seq = db.DBSequence(self.d, flags=0)
+        cashe_size = 10
+        self.assertEquals(None, self.seq.set_cachesize(cashe_size))
+        self.assertEquals(None, self.seq.open(key='foo', txn=None, flags=db.DB_CREATE))
+        self.assertEquals(cashe_size, self.seq.get_cachesize())
+
+    def test_flags(self):
+        self.seq = db.DBSequence(self.d, flags=0)
+        flag = db.DB_SEQ_WRAP;
+        self.assertEquals(None, self.seq.set_flags(flag))
+        self.assertEquals(None, self.seq.open(key='foo', txn=None, flags=db.DB_CREATE))
+        self.assertEquals(flag, self.seq.get_flags() & flag)
+
+    def test_range(self):
+        self.seq = db.DBSequence(self.d, flags=0)
+        seq_range = (10 * self.int_32_max, 11 * self.int_32_max - 1)
+        self.assertEquals(None, self.seq.set_range(seq_range))
+        self.seq.init_value(seq_range[0])
+        self.assertEquals(None, self.seq.open(key='foo', txn=None, flags=db.DB_CREATE))
+        self.assertEquals(seq_range, self.seq.get_range())
+
+    def test_stat(self):
+        self.seq = db.DBSequence(self.d, flags=0)
+        self.assertEquals(None, self.seq.open(key='foo', txn=None, flags=db.DB_CREATE))
+        stat = self.seq.stat()
+        for param in ('nowait', 'min', 'max', 'value', 'current',
+                      'flags', 'cache_size', 'last_value', 'wait'):
+            self.assertTrue(param in stat, "parameter %s isn't in stat info" % param)
+
+def test_suite():
+    suite = unittest.TestSuite()
+    if db.version() >= (4,3):
+        suite.addTest(unittest.makeSuite(DBSequenceTest))
+    return suite
+
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')

Added: vendor/Python/current/Lib/bsddb/test/test_thread.py
===================================================================
--- vendor/Python/current/Lib/bsddb/test/test_thread.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/bsddb/test/test_thread.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,506 @@
+"""TestCases for multi-threaded access to a DB.
+"""
+
+import os
+import sys
+import time
+import errno
+import shutil
+import tempfile
+from pprint import pprint
+from random import random
+
+try:
+    True, False
+except NameError:
+    True = 1
+    False = 0
+
+DASH = '-'
+
+try:
+    from threading import Thread, currentThread
+    have_threads = True
+except ImportError:
+    have_threads = False
+
+try:
+    WindowsError
+except NameError:
+    class WindowsError(Exception):
+        pass
+
+import unittest
+from test_all import verbose
+
+try:
+    # For Pythons w/distutils pybsddb
+    from bsddb3 import db, dbutils
+except ImportError:
+    # For Python 2.3
+    from bsddb import db, dbutils
+
+
+#----------------------------------------------------------------------
+
+class BaseThreadedTestCase(unittest.TestCase):
+    dbtype       = db.DB_UNKNOWN  # must be set in derived class
+    dbopenflags  = 0
+    dbsetflags   = 0
+    envflags     = 0
+
+    def setUp(self):
+        if verbose:
+            dbutils._deadlock_VerboseFile = sys.stdout
+
+        homeDir = os.path.join(os.path.dirname(sys.argv[0]), 'db_home')
+        self.homeDir = homeDir
+        try:
+            os.mkdir(homeDir)
+        except OSError, e:
+            if e.errno <> errno.EEXIST: raise
+        self.env = db.DBEnv()
+        self.setEnvOpts()
+        self.env.open(homeDir, self.envflags | db.DB_CREATE)
+
+        self.filename = self.__class__.__name__ + '.db'
+        self.d = db.DB(self.env)
+        if self.dbsetflags:
+            self.d.set_flags(self.dbsetflags)
+        self.d.open(self.filename, self.dbtype, self.dbopenflags|db.DB_CREATE)
+
+    def tearDown(self):
+        self.d.close()
+        self.env.close()
+        shutil.rmtree(self.homeDir)
+
+    def setEnvOpts(self):
+        pass
+
+    def makeData(self, key):
+        return DASH.join([key] * 5)
+
+
+#----------------------------------------------------------------------
+
+
+class ConcurrentDataStoreBase(BaseThreadedTestCase):
+    dbopenflags = db.DB_THREAD
+    envflags    = db.DB_THREAD | db.DB_INIT_CDB | db.DB_INIT_MPOOL
+    readers     = 0 # derived class should set
+    writers     = 0
+    records     = 1000
+
+    def test01_1WriterMultiReaders(self):
+        if verbose:
+            print '\n', '-=' * 30
+            print "Running %s.test01_1WriterMultiReaders..." % \
+                  self.__class__.__name__
+
+        threads = []
+        for x in range(self.writers):
+            wt = Thread(target = self.writerThread,
+                        args = (self.d, self.records, x),
+                        name = 'writer %d' % x,
+                        )#verbose = verbose)
+            threads.append(wt)
+
+        for x in range(self.readers):
+            rt = Thread(target = self.readerThread,
+                        args = (self.d, x),
+                        name = 'reader %d' % x,
+                        )#verbose = verbose)
+            threads.append(rt)
+
+        for t in threads:
+            t.start()
+        for t in threads:
+            t.join()
+
+    def writerThread(self, d, howMany, writerNum):
+        #time.sleep(0.01 * writerNum + 0.01)
+        name = currentThread().getName()
+        start = howMany * writerNum
+        stop = howMany * (writerNum + 1) - 1
+        if verbose:
+            print "%s: creating records %d - %d" % (name, start, stop)
+
+        for x in range(start, stop):
+            key = '%04d' % x
+            dbutils.DeadlockWrap(d.put, key, self.makeData(key),
+                                 max_retries=12)
+            if verbose and x % 100 == 0:
+                print "%s: records %d - %d finished" % (name, start, x)
+
+        if verbose:
+            print "%s: finished creating records" % name
+
+##         # Each write-cursor will be exclusive, the only one that can update the DB...
+##         if verbose: print "%s: deleting a few records" % name
+##         c = d.cursor(flags = db.DB_WRITECURSOR)
+##         for x in range(10):
+##             key = int(random() * howMany) + start
+##             key = '%04d' % key
+##             if d.has_key(key):
+##                 c.set(key)
+##                 c.delete()
+
+##         c.close()
+        if verbose:
+            print "%s: thread finished" % name
+
+    def readerThread(self, d, readerNum):
+        time.sleep(0.01 * readerNum)
+        name = currentThread().getName()
+
+        for loop in range(5):
+            c = d.cursor()
+            count = 0
+            rec = c.first()
+            while rec:
+                count += 1
+                key, data = rec
+                self.assertEqual(self.makeData(key), data)
+                rec = c.next()
+            if verbose:
+                print "%s: found %d records" % (name, count)
+            c.close()
+            time.sleep(0.05)
+
+        if verbose:
+            print "%s: thread finished" % name
+
+
+class BTreeConcurrentDataStore(ConcurrentDataStoreBase):
+    dbtype  = db.DB_BTREE
+    writers = 2
+    readers = 10
+    records = 1000
+
+
+class HashConcurrentDataStore(ConcurrentDataStoreBase):
+    dbtype  = db.DB_HASH
+    writers = 2
+    readers = 10
+    records = 1000
+
+
+#----------------------------------------------------------------------
+
+class SimpleThreadedBase(BaseThreadedTestCase):
+    dbopenflags = db.DB_THREAD
+    envflags    = db.DB_THREAD | db.DB_INIT_MPOOL | db.DB_INIT_LOCK
+    readers = 5
+    writers = 3
+    records = 1000
+
+    def setEnvOpts(self):
+        self.env.set_lk_detect(db.DB_LOCK_DEFAULT)
+
+    def test02_SimpleLocks(self):
+        if verbose:
+            print '\n', '-=' * 30
+            print "Running %s.test02_SimpleLocks..." % self.__class__.__name__
+
+        threads = []
+        for x in range(self.writers):
+            wt = Thread(target = self.writerThread,
+                        args = (self.d, self.records, x),
+                        name = 'writer %d' % x,
+                        )#verbose = verbose)
+            threads.append(wt)
+        for x in range(self.readers):
+            rt = Thread(target = self.readerThread,
+                        args = (self.d, x),
+                        name = 'reader %d' % x,
+                        )#verbose = verbose)
+            threads.append(rt)
+
+        for t in threads:
+            t.start()
+        for t in threads:
+            t.join()
+
+    def writerThread(self, d, howMany, writerNum):
+        name = currentThread().getName()
+        start = howMany * writerNum
+        stop = howMany * (writerNum + 1) - 1
+        if verbose:
+            print "%s: creating records %d - %d" % (name, start, stop)
+
+        # create a bunch of records
+        for x in xrange(start, stop):
+            key = '%04d' % x
+            dbutils.DeadlockWrap(d.put, key, self.makeData(key),
+                                 max_retries=12)
+
+            if verbose and x % 100 == 0:
+                print "%s: records %d - %d finished" % (name, start, x)
+
+            # do a bit or reading too
+            if random() <= 0.05:
+                for y in xrange(start, x):
+                    key = '%04d' % x
+                    data = dbutils.DeadlockWrap(d.get, key, max_retries=12)
+                    self.assertEqual(data, self.makeData(key))
+
+        # flush them
+        try:
+            dbutils.DeadlockWrap(d.sync, max_retries=12)
+        except db.DBIncompleteError, val:
+            if verbose:
+                print "could not complete sync()..."
+
+        # read them back, deleting a few
+        for x in xrange(start, stop):
+            key = '%04d' % x
+            data = dbutils.DeadlockWrap(d.get, key, max_retries=12)
+            if verbose and x % 100 == 0:
+                print "%s: fetched record (%s, %s)" % (name, key, data)
+            self.assertEqual(data, self.makeData(key))
+            if random() <= 0.10:
+                dbutils.DeadlockWrap(d.delete, key, max_retries=12)
+                if verbose:
+                    print "%s: deleted record %s" % (name, key)
+
+        if verbose:
+            print "%s: thread finished" % name
+
+    def readerThread(self, d, readerNum):
+        time.sleep(0.01 * readerNum)
+        name = currentThread().getName()
+
+        for loop in range(5):
+            c = d.cursor()
+            count = 0
+            rec = dbutils.DeadlockWrap(c.first, max_retries=10)
+            while rec:
+                count += 1
+                key, data = rec
+                self.assertEqual(self.makeData(key), data)
+                rec = dbutils.DeadlockWrap(c.next, max_retries=10)
+            if verbose:
+                print "%s: found %d records" % (name, count)
+            c.close()
+            time.sleep(0.05)
+
+        if verbose:
+            print "%s: thread finished" % name
+
+
+class BTreeSimpleThreaded(SimpleThreadedBase):
+    dbtype = db.DB_BTREE
+
+
+class HashSimpleThreaded(SimpleThreadedBase):
+    dbtype = db.DB_HASH
+
+
+#----------------------------------------------------------------------
+
+
+class ThreadedTransactionsBase(BaseThreadedTestCase):
+    dbopenflags = db.DB_THREAD | db.DB_AUTO_COMMIT
+    envflags    = (db.DB_THREAD |
+                   db.DB_INIT_MPOOL |
+                   db.DB_INIT_LOCK |
+                   db.DB_INIT_LOG |
+                   db.DB_INIT_TXN
+                   )
+    readers = 0
+    writers = 0
+    records = 2000
+    txnFlag = 0
+
+    def setEnvOpts(self):
+        #self.env.set_lk_detect(db.DB_LOCK_DEFAULT)
+        pass
+
+    def test03_ThreadedTransactions(self):
+        if verbose:
+            print '\n', '-=' * 30
+            print "Running %s.test03_ThreadedTransactions..." % \
+                  self.__class__.__name__
+
+        threads = []
+        for x in range(self.writers):
+            wt = Thread(target = self.writerThread,
+                        args = (self.d, self.records, x),
+                        name = 'writer %d' % x,
+                        )#verbose = verbose)
+            threads.append(wt)
+
+        for x in range(self.readers):
+            rt = Thread(target = self.readerThread,
+                        args = (self.d, x),
+                        name = 'reader %d' % x,
+                        )#verbose = verbose)
+            threads.append(rt)
+
+        dt = Thread(target = self.deadlockThread)
+        dt.start()
+
+        for t in threads:
+            t.start()
+        for t in threads:
+            t.join()
+
+        self.doLockDetect = False
+        dt.join()
+
+    def doWrite(self, d, name, start, stop):
+        finished = False
+        while not finished:
+            try:
+                txn = self.env.txn_begin(None, self.txnFlag)
+                for x in range(start, stop):
+                    key = '%04d' % x
+                    d.put(key, self.makeData(key), txn)
+                    if verbose and x % 100 == 0:
+                        print "%s: records %d - %d finished" % (name, start, x)
+                txn.commit()
+                finished = True
+            except (db.DBLockDeadlockError, db.DBLockNotGrantedError), val:
+                if verbose:
+                    print "%s: Aborting transaction (%s)" % (name, val[1])
+                txn.abort()
+                time.sleep(0.05)
+
+    def writerThread(self, d, howMany, writerNum):
+        name = currentThread().getName()
+        start = howMany * writerNum
+        stop = howMany * (writerNum + 1) - 1
+        if verbose:
+            print "%s: creating records %d - %d" % (name, start, stop)
+
+        step = 100
+        for x in range(start, stop, step):
+            self.doWrite(d, name, x, min(stop, x+step))
+
+        if verbose:
+            print "%s: finished creating records" % name
+        if verbose:
+            print "%s: deleting a few records" % name
+
+        finished = False
+        while not finished:
+            try:
+                recs = []
+                txn = self.env.txn_begin(None, self.txnFlag)
+                for x in range(10):
+                    key = int(random() * howMany) + start
+                    key = '%04d' % key
+                    data = d.get(key, None, txn, db.DB_RMW)
+                    if data is not None:
+                        d.delete(key, txn)
+                        recs.append(key)
+                txn.commit()
+                finished = True
+                if verbose:
+                    print "%s: deleted records %s" % (name, recs)
+            except (db.DBLockDeadlockError, db.DBLockNotGrantedError), val:
+                if verbose:
+                    print "%s: Aborting transaction (%s)" % (name, val[1])
+                txn.abort()
+                time.sleep(0.05)
+
+        if verbose:
+            print "%s: thread finished" % name
+
+    def readerThread(self, d, readerNum):
+        time.sleep(0.01 * readerNum + 0.05)
+        name = currentThread().getName()
+
+        for loop in range(5):
+            finished = False
+            while not finished:
+                try:
+                    txn = self.env.txn_begin(None, self.txnFlag)
+                    c = d.cursor(txn)
+                    count = 0
+                    rec = c.first()
+                    while rec:
+                        count += 1
+                        key, data = rec
+                        self.assertEqual(self.makeData(key), data)
+                        rec = c.next()
+                    if verbose: print "%s: found %d records" % (name, count)
+                    c.close()
+                    txn.commit()
+                    finished = True
+                except (db.DBLockDeadlockError, db.DBLockNotGrantedError), val:
+                    if verbose:
+                        print "%s: Aborting transaction (%s)" % (name, val[1])
+                    c.close()
+                    txn.abort()
+                    time.sleep(0.05)
+
+            time.sleep(0.05)
+
+        if verbose:
+            print "%s: thread finished" % name
+
+    def deadlockThread(self):
+        self.doLockDetect = True
+        while self.doLockDetect:
+            time.sleep(0.5)
+            try:
+                aborted = self.env.lock_detect(
+                    db.DB_LOCK_RANDOM, db.DB_LOCK_CONFLICT)
+                if verbose and aborted:
+                    print "deadlock: Aborted %d deadlocked transaction(s)" \
+                          % aborted
+            except db.DBError:
+                pass
+
+
+class BTreeThreadedTransactions(ThreadedTransactionsBase):
+    dbtype = db.DB_BTREE
+    writers = 3
+    readers = 5
+    records = 2000
+
+class HashThreadedTransactions(ThreadedTransactionsBase):
+    dbtype = db.DB_HASH
+    writers = 1
+    readers = 5
+    records = 2000
+
+class BTreeThreadedNoWaitTransactions(ThreadedTransactionsBase):
+    dbtype = db.DB_BTREE
+    writers = 3
+    readers = 5
+    records = 2000
+    txnFlag = db.DB_TXN_NOWAIT
+
+class HashThreadedNoWaitTransactions(ThreadedTransactionsBase):
+    dbtype = db.DB_HASH
+    writers = 1
+    readers = 5
+    records = 2000
+    txnFlag = db.DB_TXN_NOWAIT
+
+
+#----------------------------------------------------------------------
+
+def test_suite():
+    suite = unittest.TestSuite()
+
+    if have_threads:
+        suite.addTest(unittest.makeSuite(BTreeConcurrentDataStore))
+        suite.addTest(unittest.makeSuite(HashConcurrentDataStore))
+        suite.addTest(unittest.makeSuite(BTreeSimpleThreaded))
+        suite.addTest(unittest.makeSuite(HashSimpleThreaded))
+        suite.addTest(unittest.makeSuite(BTreeThreadedTransactions))
+        suite.addTest(unittest.makeSuite(HashThreadedTransactions))
+        suite.addTest(unittest.makeSuite(BTreeThreadedNoWaitTransactions))
+        suite.addTest(unittest.makeSuite(HashThreadedNoWaitTransactions))
+
+    else:
+        print "Threads not available, skipping thread tests."
+
+    return suite
+
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')

Added: vendor/Python/current/Lib/cProfile.py
===================================================================
--- vendor/Python/current/Lib/cProfile.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/cProfile.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,190 @@
+#! /usr/bin/env python
+
+"""Python interface for the 'lsprof' profiler.
+   Compatible with the 'profile' module.
+"""
+
+__all__ = ["run", "runctx", "help", "Profile"]
+
+import _lsprof
+
+# ____________________________________________________________
+# Simple interface
+
+def run(statement, filename=None, sort=-1):
+    """Run statement under profiler optionally saving results in filename
+
+    This function takes a single argument that can be passed to the
+    "exec" statement, and an optional file name.  In all cases this
+    routine attempts to "exec" its first argument and gather profiling
+    statistics from the execution. If no file name is present, then this
+    function automatically prints a simple profiling report, sorted by the
+    standard name string (file/line/function-name) that is presented in
+    each line.
+    """
+    prof = Profile()
+    result = None
+    try:
+        try:
+            prof = prof.run(statement)
+        except SystemExit:
+            pass
+    finally:
+        if filename is not None:
+            prof.dump_stats(filename)
+        else:
+            result = prof.print_stats(sort)
+    return result
+
+def runctx(statement, globals, locals, filename=None):
+    """Run statement under profiler, supplying your own globals and locals,
+    optionally saving results in filename.
+
+    statement and filename have the same semantics as profile.run
+    """
+    prof = Profile()
+    result = None
+    try:
+        try:
+            prof = prof.runctx(statement, globals, locals)
+        except SystemExit:
+            pass
+    finally:
+        if filename is not None:
+            prof.dump_stats(filename)
+        else:
+            result = prof.print_stats()
+    return result
+
+# Backwards compatibility.
+def help():
+    print "Documentation for the profile/cProfile modules can be found "
+    print "in the Python Library Reference, section 'The Python Profiler'."
+
+# ____________________________________________________________
+
+class Profile(_lsprof.Profiler):
+    """Profile(custom_timer=None, time_unit=None, subcalls=True, builtins=True)
+
+    Builds a profiler object using the specified timer function.
+    The default timer is a fast built-in one based on real time.
+    For custom timer functions returning integers, time_unit can
+    be a float specifying a scale (i.e. how long each integer unit
+    is, in seconds).
+    """
+
+    # Most of the functionality is in the base class.
+    # This subclass only adds convenient and backward-compatible methods.
+
+    def print_stats(self, sort=-1):
+        import pstats
+        pstats.Stats(self).strip_dirs().sort_stats(sort).print_stats()
+
+    def dump_stats(self, file):
+        import marshal
+        f = open(file, 'wb')
+        self.create_stats()
+        marshal.dump(self.stats, f)
+        f.close()
+
+    def create_stats(self):
+        self.disable()
+        self.snapshot_stats()
+
+    def snapshot_stats(self):
+        entries = self.getstats()
+        self.stats = {}
+        callersdicts = {}
+        # call information
+        for entry in entries:
+            func = label(entry.code)
+            nc = entry.callcount         # ncalls column of pstats (before '/')
+            cc = nc - entry.reccallcount # ncalls column of pstats (after '/')
+            tt = entry.inlinetime        # tottime column of pstats
+            ct = entry.totaltime         # cumtime column of pstats
+            callers = {}
+            callersdicts[id(entry.code)] = callers
+            self.stats[func] = cc, nc, tt, ct, callers
+        # subcall information
+        for entry in entries:
+            if entry.calls:
+                func = label(entry.code)
+                for subentry in entry.calls:
+                    try:
+                        callers = callersdicts[id(subentry.code)]
+                    except KeyError:
+                        continue
+                    nc = subentry.callcount
+                    cc = nc - subentry.reccallcount
+                    tt = subentry.inlinetime
+                    ct = subentry.totaltime
+                    if func in callers:
+                        prev = callers[func]
+                        nc += prev[0]
+                        cc += prev[1]
+                        tt += prev[2]
+                        ct += prev[3]
+                    callers[func] = nc, cc, tt, ct
+
+    # The following two methods can be called by clients to use
+    # a profiler to profile a statement, given as a string.
+
+    def run(self, cmd):
+        import __main__
+        dict = __main__.__dict__
+        return self.runctx(cmd, dict, dict)
+
+    def runctx(self, cmd, globals, locals):
+        self.enable()
+        try:
+            exec cmd in globals, locals
+        finally:
+            self.disable()
+        return self
+
+    # This method is more useful to profile a single function call.
+    def runcall(self, func, *args, **kw):
+        self.enable()
+        try:
+            return func(*args, **kw)
+        finally:
+            self.disable()
+
+# ____________________________________________________________
+
+def label(code):
+    if isinstance(code, str):
+        return ('~', 0, code)    # built-in functions ('~' sorts at the end)
+    else:
+        return (code.co_filename, code.co_firstlineno, code.co_name)
+
+# ____________________________________________________________
+
+def main():
+    import os, sys
+    from optparse import OptionParser
+    usage = "cProfile.py [-o output_file_path] [-s sort] scriptfile [arg] ..."
+    parser = OptionParser(usage=usage)
+    parser.allow_interspersed_args = False
+    parser.add_option('-o', '--outfile', dest="outfile",
+        help="Save stats to <outfile>", default=None)
+    parser.add_option('-s', '--sort', dest="sort",
+        help="Sort order when printing to stdout, based on pstats.Stats class", default=-1)
+
+    if not sys.argv[1:]:
+        parser.print_usage()
+        sys.exit(2)
+
+    (options, args) = parser.parse_args()
+    sys.argv[:] = args
+
+    if (len(sys.argv) > 0):
+        sys.path.insert(0, os.path.dirname(sys.argv[0]))
+        run('execfile(%r)' % (sys.argv[0],), options.outfile, options.sort)
+    else:
+        parser.print_usage()
+    return parser
+
+# When invoked as main program, invoke the profiler on a script
+if __name__ == '__main__':
+    main()


Property changes on: vendor/Python/current/Lib/cProfile.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/calendar.py
===================================================================
--- vendor/Python/current/Lib/calendar.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/calendar.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,701 @@
+"""Calendar printing functions
+
+Note when comparing these calendars to the ones printed by cal(1): By
+default, these calendars have Monday as the first day of the week, and
+Sunday as the last (the European convention). Use setfirstweekday() to
+set the first day of the week (0=Monday, 6=Sunday)."""
+
+from __future__ import with_statement
+import sys, datetime, locale
+
+__all__ = ["IllegalMonthError", "IllegalWeekdayError", "setfirstweekday",
+           "firstweekday", "isleap", "leapdays", "weekday", "monthrange",
+           "monthcalendar", "prmonth", "month", "prcal", "calendar",
+           "timegm", "month_name", "month_abbr", "day_name", "day_abbr"]
+
+# Exception raised for bad input (with string parameter for details)
+error = ValueError
+
+# Exceptions raised for bad input
+class IllegalMonthError(ValueError):
+    def __init__(self, month):
+        self.month = month
+    def __str__(self):
+        return "bad month number %r; must be 1-12" % self.month
+
+
+class IllegalWeekdayError(ValueError):
+    def __init__(self, weekday):
+        self.weekday = weekday
+    def __str__(self):
+        return "bad weekday number %r; must be 0 (Monday) to 6 (Sunday)" % self.weekday
+
+
+# Constants for months referenced later
+January = 1
+February = 2
+
+# Number of days per month (except for February in leap years)
+mdays = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
+
+# This module used to have hard-coded lists of day and month names, as
+# English strings.  The classes following emulate a read-only version of
+# that, but supply localized names.  Note that the values are computed
+# fresh on each call, in case the user changes locale between calls.
+
+class _localized_month:
+
+    _months = [datetime.date(2001, i+1, 1).strftime for i in xrange(12)]
+    _months.insert(0, lambda x: "")
+
+    def __init__(self, format):
+        self.format = format
+
+    def __getitem__(self, i):
+        funcs = self._months[i]
+        if isinstance(i, slice):
+            return [f(self.format) for f in funcs]
+        else:
+            return funcs(self.format)
+
+    def __len__(self):
+        return 13
+
+
+class _localized_day:
+
+    # January 1, 2001, was a Monday.
+    _days = [datetime.date(2001, 1, i+1).strftime for i in xrange(7)]
+
+    def __init__(self, format):
+        self.format = format
+
+    def __getitem__(self, i):
+        funcs = self._days[i]
+        if isinstance(i, slice):
+            return [f(self.format) for f in funcs]
+        else:
+            return funcs(self.format)
+
+    def __len__(self):
+        return 7
+
+
+# Full and abbreviated names of weekdays
+day_name = _localized_day('%A')
+day_abbr = _localized_day('%a')
+
+# Full and abbreviated names of months (1-based arrays!!!)
+month_name = _localized_month('%B')
+month_abbr = _localized_month('%b')
+
+# Constants for weekdays
+(MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY) = range(7)
+
+
+def isleap(year):
+    """Return 1 for leap years, 0 for non-leap years."""
+    return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)
+
+
+def leapdays(y1, y2):
+    """Return number of leap years in range [y1, y2).
+       Assume y1 <= y2."""
+    y1 -= 1
+    y2 -= 1
+    return (y2//4 - y1//4) - (y2//100 - y1//100) + (y2//400 - y1//400)
+
+
+def weekday(year, month, day):
+    """Return weekday (0-6 ~ Mon-Sun) for year (1970-...), month (1-12),
+       day (1-31)."""
+    return datetime.date(year, month, day).weekday()
+
+
+def monthrange(year, month):
+    """Return weekday (0-6 ~ Mon-Sun) and number of days (28-31) for
+       year, month."""
+    if not 1 <= month <= 12:
+        raise IllegalMonthError(month)
+    day1 = weekday(year, month, 1)
+    ndays = mdays[month] + (month == February and isleap(year))
+    return day1, ndays
+
+
+class Calendar(object):
+    """
+    Base calendar class. This class doesn't do any formatting. It simply
+    provides data to subclasses.
+    """
+
+    def __init__(self, firstweekday=0):
+        self.firstweekday = firstweekday # 0 = Monday, 6 = Sunday
+
+    def getfirstweekday(self):
+        return self._firstweekday % 7
+
+    def setfirstweekday(self, firstweekday):
+        self._firstweekday = firstweekday
+
+    firstweekday = property(getfirstweekday, setfirstweekday)
+
+    def iterweekdays(self):
+        """
+        Return a iterator for one week of weekday numbers starting with the
+        configured first one.
+        """
+        for i in xrange(self.firstweekday, self.firstweekday + 7):
+            yield i%7
+
+    def itermonthdates(self, year, month):
+        """
+        Return an iterator for one month. The iterator will yield datetime.date
+        values and will always iterate through complete weeks, so it will yield
+        dates outside the specified month.
+        """
+        date = datetime.date(year, month, 1)
+        # Go back to the beginning of the week
+        days = (date.weekday() - self.firstweekday) % 7
+        date -= datetime.timedelta(days=days)
+        oneday = datetime.timedelta(days=1)
+        while True:
+            yield date
+            date += oneday
+            if date.month != month and date.weekday() == self.firstweekday:
+                break
+
+    def itermonthdays2(self, year, month):
+        """
+        Like itermonthdates(), but will yield (day number, weekday number)
+        tuples. For days outside the specified month the day number is 0.
+        """
+        for date in self.itermonthdates(year, month):
+            if date.month != month:
+                yield (0, date.weekday())
+            else:
+                yield (date.day, date.weekday())
+
+    def itermonthdays(self, year, month):
+        """
+        Like itermonthdates(), but will yield day numbers tuples. For days
+        outside the specified month the day number is 0.
+        """
+        for date in self.itermonthdates(year, month):
+            if date.month != month:
+                yield 0
+            else:
+                yield date.day
+
+    def monthdatescalendar(self, year, month):
+        """
+        Return a matrix (list of lists) representing a month's calendar.
+        Each row represents a week; week entries are datetime.date values.
+        """
+        dates = list(self.itermonthdates(year, month))
+        return [ dates[i:i+7] for i in xrange(0, len(dates), 7) ]
+
+    def monthdays2calendar(self, year, month):
+        """
+        Return a matrix representing a month's calendar.
+        Each row represents a week; week entries are
+        (day number, weekday number) tuples. Day numbers outside this month
+        are zero.
+        """
+        days = list(self.itermonthdays2(year, month))
+        return [ days[i:i+7] for i in xrange(0, len(days), 7) ]
+
+    def monthdayscalendar(self, year, month):
+        """
+        Return a matrix representing a month's calendar.
+        Each row represents a week; days outside this month are zero.
+        """
+        days = list(self.itermonthdays(year, month))
+        return [ days[i:i+7] for i in xrange(0, len(days), 7) ]
+
+    def yeardatescalendar(self, year, width=3):
+        """
+        Return the data for the specified year ready for formatting. The return
+        value is a list of month rows. Each month row contains upto width months.
+        Each month contains between 4 and 6 weeks and each week contains 1-7
+        days. Days are datetime.date objects.
+        """
+        months = [
+            self.monthdatescalendar(year, i)
+            for i in xrange(January, January+12)
+        ]
+        return [months[i:i+width] for i in xrange(0, len(months), width) ]
+
+    def yeardays2calendar(self, year, width=3):
+        """
+        Return the data for the specified year ready for formatting (similar to
+        yeardatescalendar()). Entries in the week lists are
+        (day number, weekday number) tuples. Day numbers outside this month are
+        zero.
+        """
+        months = [
+            self.monthdays2calendar(year, i)
+            for i in xrange(January, January+12)
+        ]
+        return [months[i:i+width] for i in xrange(0, len(months), width) ]
+
+    def yeardayscalendar(self, year, width=3):
+        """
+        Return the data for the specified year ready for formatting (similar to
+        yeardatescalendar()). Entries in the week lists are day numbers.
+        Day numbers outside this month are zero.
+        """
+        months = [
+            self.monthdayscalendar(year, i)
+            for i in xrange(January, January+12)
+        ]
+        return [months[i:i+width] for i in xrange(0, len(months), width) ]
+
+
+class TextCalendar(Calendar):
+    """
+    Subclass of Calendar that outputs a calendar as a simple plain text
+    similar to the UNIX program cal.
+    """
+
+    def prweek(self, theweek, width):
+        """
+        Print a single week (no newline).
+        """
+        print self.week(theweek, width),
+
+    def formatday(self, day, weekday, width):
+        """
+        Returns a formatted day.
+        """
+        if day == 0:
+            s = ''
+        else:
+            s = '%2i' % day             # right-align single-digit days
+        return s.center(width)
+
+    def formatweek(self, theweek, width):
+        """
+        Returns a single week in a string (no newline).
+        """
+        return ' '.join(self.formatday(d, wd, width) for (d, wd) in theweek)
+
+    def formatweekday(self, day, width):
+        """
+        Returns a formatted week day name.
+        """
+        if width >= 9:
+            names = day_name
+        else:
+            names = day_abbr
+        return names[day][:width].center(width)
+
+    def formatweekheader(self, width):
+        """
+        Return a header for a week.
+        """
+        return ' '.join(self.formatweekday(i, width) for i in self.iterweekdays())
+
+    def formatmonthname(self, theyear, themonth, width, withyear=True):
+        """
+        Return a formatted month name.
+        """
+        s = month_name[themonth]
+        if withyear:
+            s = "%s %r" % (s, theyear)
+        return s.center(width)
+
+    def prmonth(self, theyear, themonth, w=0, l=0):
+        """
+        Print a month's calendar.
+        """
+        print self.formatmonth(theyear, themonth, w, l),
+
+    def formatmonth(self, theyear, themonth, w=0, l=0):
+        """
+        Return a month's calendar string (multi-line).
+        """
+        w = max(2, w)
+        l = max(1, l)
+        s = self.formatmonthname(theyear, themonth, 7 * (w + 1) - 1)
+        s = s.rstrip()
+        s += '\n' * l
+        s += self.formatweekheader(w).rstrip()
+        s += '\n' * l
+        for week in self.monthdays2calendar(theyear, themonth):
+            s += self.formatweek(week, w).rstrip()
+            s += '\n' * l
+        return s
+
+    def formatyear(self, theyear, w=2, l=1, c=6, m=3):
+        """
+        Returns a year's calendar as a multi-line string.
+        """
+        w = max(2, w)
+        l = max(1, l)
+        c = max(2, c)
+        colwidth = (w + 1) * 7 - 1
+        v = []
+        a = v.append
+        a(repr(theyear).center(colwidth*m+c*(m-1)).rstrip())
+        a('\n'*l)
+        header = self.formatweekheader(w)
+        for (i, row) in enumerate(self.yeardays2calendar(theyear, m)):
+            # months in this row
+            months = xrange(m*i+1, min(m*(i+1)+1, 13))
+            a('\n'*l)
+            names = (self.formatmonthname(theyear, k, colwidth, False)
+                     for k in months)
+            a(formatstring(names, colwidth, c).rstrip())
+            a('\n'*l)
+            headers = (header for k in months)
+            a(formatstring(headers, colwidth, c).rstrip())
+            a('\n'*l)
+            # max number of weeks for this row
+            height = max(len(cal) for cal in row)
+            for j in xrange(height):
+                weeks = []
+                for cal in row:
+                    if j >= len(cal):
+                        weeks.append('')
+                    else:
+                        weeks.append(self.formatweek(cal[j], w))
+                a(formatstring(weeks, colwidth, c).rstrip())
+                a('\n' * l)
+        return ''.join(v)
+
+    def pryear(self, theyear, w=0, l=0, c=6, m=3):
+        """Print a year's calendar."""
+        print self.formatyear(theyear, w, l, c, m)
+
+
+class HTMLCalendar(Calendar):
+    """
+    This calendar returns complete HTML pages.
+    """
+
+    # CSS classes for the day <td>s
+    cssclasses = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"]
+
+    def formatday(self, day, weekday):
+        """
+        Return a day as a table cell.
+        """
+        if day == 0:
+            return '<td class="noday">&nbsp;</td>' # day outside month
+        else:
+            return '<td class="%s">%d</td>' % (self.cssclasses[weekday], day)
+
+    def formatweek(self, theweek):
+        """
+        Return a complete week as a table row.
+        """
+        s = ''.join(self.formatday(d, wd) for (d, wd) in theweek)
+        return '<tr>%s</tr>' % s
+
+    def formatweekday(self, day):
+        """
+        Return a weekday name as a table header.
+        """
+        return '<th class="%s">%s</th>' % (self.cssclasses[day], day_abbr[day])
+
+    def formatweekheader(self):
+        """
+        Return a header for a week as a table row.
+        """
+        s = ''.join(self.formatweekday(i) for i in self.iterweekdays())
+        return '<tr>%s</tr>' % s
+
+    def formatmonthname(self, theyear, themonth, withyear=True):
+        """
+        Return a month name as a table row.
+        """
+        if withyear:
+            s = '%s %s' % (month_name[themonth], theyear)
+        else:
+            s = '%s' % month_name[themonth]
+        return '<tr><th colspan="7" class="month">%s</th></tr>' % s
+
+    def formatmonth(self, theyear, themonth, withyear=True):
+        """
+        Return a formatted month as a table.
+        """
+        v = []
+        a = v.append
+        a('<table border="0" cellpadding="0" cellspacing="0" class="month">')
+        a('\n')
+        a(self.formatmonthname(theyear, themonth, withyear=withyear))
+        a('\n')
+        a(self.formatweekheader())
+        a('\n')
+        for week in self.monthdays2calendar(theyear, themonth):
+            a(self.formatweek(week))
+            a('\n')
+        a('</table>')
+        a('\n')
+        return ''.join(v)
+
+    def formatyear(self, theyear, width=3):
+        """
+        Return a formatted year as a table of tables.
+        """
+        v = []
+        a = v.append
+        width = max(width, 1)
+        a('<table border="0" cellpadding="0" cellspacing="0" class="year">')
+        a('\n')
+        a('<tr><th colspan="%d" class="year">%s</th></tr>' % (width, theyear))
+        for i in xrange(January, January+12, width):
+            # months in this row
+            months = xrange(i, min(i+width, 13))
+            a('<tr>')
+            for m in months:
+                a('<td>')
+                a(self.formatmonth(theyear, m, withyear=False))
+                a('</td>')
+            a('</tr>')
+        a('</table>')
+        return ''.join(v)
+
+    def formatyearpage(self, theyear, width=3, css='calendar.css', encoding=None):
+        """
+        Return a formatted year as a complete HTML page.
+        """
+        if encoding is None:
+            encoding = sys.getdefaultencoding()
+        v = []
+        a = v.append
+        a('<?xml version="1.0" encoding="%s"?>\n' % encoding)
+        a('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n')
+        a('<html>\n')
+        a('<head>\n')
+        a('<meta http-equiv="Content-Type" content="text/html; charset=%s" />\n' % encoding)
+        if css is not None:
+            a('<link rel="stylesheet" type="text/css" href="%s" />\n' % css)
+        a('<title>Calendar for %d</title\n' % theyear)
+        a('</head>\n')
+        a('<body>\n')
+        a(self.formatyear(theyear, width))
+        a('</body>\n')
+        a('</html>\n')
+        return ''.join(v).encode(encoding, "xmlcharrefreplace")
+
+
+class TimeEncoding:
+    def __init__(self, locale):
+        self.locale = locale
+
+    def __enter__(self):
+        self.oldlocale = locale.setlocale(locale.LC_TIME, self.locale)
+        return locale.getlocale(locale.LC_TIME)[1]
+
+    def __exit__(self, *args):
+        locale.setlocale(locale.LC_TIME, self.oldlocale)
+
+
+class LocaleTextCalendar(TextCalendar):
+    """
+    This class can be passed a locale name in the constructor and will return
+    month and weekday names in the specified locale. If this locale includes
+    an encoding all strings containing month and weekday names will be returned
+    as unicode.
+    """
+
+    def __init__(self, firstweekday=0, locale=None):
+        TextCalendar.__init__(self, firstweekday)
+        if locale is None:
+            locale = locale.getdefaultlocale()
+        self.locale = locale
+
+    def formatweekday(self, day, width):
+        with TimeEncoding(self.locale) as encoding:
+            if width >= 9:
+                names = day_name
+            else:
+                names = day_abbr
+            name = names[day]
+            if encoding is not None:
+                name = name.decode(encoding)
+            return name[:width].center(width)
+
+    def formatmonthname(self, theyear, themonth, width, withyear=True):
+        with TimeEncoding(self.locale) as encoding:
+            s = month_name[themonth]
+            if encoding is not None:
+                s = s.decode(encoding)
+            if withyear:
+                s = "%s %r" % (s, theyear)
+            return s.center(width)
+
+
+class LocaleHTMLCalendar(HTMLCalendar):
+    """
+    This class can be passed a locale name in the constructor and will return
+    month and weekday names in the specified locale. If this locale includes
+    an encoding all strings containing month and weekday names will be returned
+    as unicode.
+    """
+    def __init__(self, firstweekday=0, locale=None):
+        HTMLCalendar.__init__(self, firstweekday)
+        if locale is None:
+            locale = locale.getdefaultlocale()
+        self.locale = locale
+
+    def formatweekday(self, day):
+        with TimeEncoding(self.locale) as encoding:
+            s = day_abbr[day]
+            if encoding is not None:
+                s = s.decode(encoding)
+            return '<th class="%s">%s</th>' % (self.cssclasses[day], s)
+
+    def formatmonthname(self, theyear, themonth, withyear=True):
+        with TimeEncoding(self.locale) as encoding:
+            s = month_name[themonth]
+            if encoding is not None:
+                s = s.decode(encoding)
+            if withyear:
+                s = '%s %s' % (s, theyear)
+            return '<tr><th colspan="7" class="month">%s</th></tr>' % s
+
+
+# Support for old module level interface
+c = TextCalendar()
+
+firstweekday = c.getfirstweekday
+
+def setfirstweekday(firstweekday):
+    if not MONDAY <= firstweekday <= SUNDAY:
+        raise IllegalWeekdayError(firstweekday)
+    c.firstweekday = firstweekday
+
+monthcalendar = c.monthdayscalendar
+prweek = c.prweek
+week = c.formatweek
+weekheader = c.formatweekheader
+prmonth = c.prmonth
+month = c.formatmonth
+calendar = c.formatyear
+prcal = c.pryear
+
+
+# Spacing of month columns for multi-column year calendar
+_colwidth = 7*3 - 1         # Amount printed by prweek()
+_spacing = 6                # Number of spaces between columns
+
+
+def format(cols, colwidth=_colwidth, spacing=_spacing):
+    """Prints multi-column formatting for year calendars"""
+    print formatstring(cols, colwidth, spacing)
+
+
+def formatstring(cols, colwidth=_colwidth, spacing=_spacing):
+    """Returns a string formatted from n strings, centered within n columns."""
+    spacing *= ' '
+    return spacing.join(c.center(colwidth) for c in cols)
+
+
+EPOCH = 1970
+_EPOCH_ORD = datetime.date(EPOCH, 1, 1).toordinal()
+
+
+def timegm(tuple):
+    """Unrelated but handy function to calculate Unix timestamp from GMT."""
+    year, month, day, hour, minute, second = tuple[:6]
+    days = datetime.date(year, month, 1).toordinal() - _EPOCH_ORD + day - 1
+    hours = days*24 + hour
+    minutes = hours*60 + minute
+    seconds = minutes*60 + second
+    return seconds
+
+
+def main(args):
+    import optparse
+    parser = optparse.OptionParser(usage="usage: %prog [options] [year [month]]")
+    parser.add_option(
+        "-w", "--width",
+        dest="width", type="int", default=2,
+        help="width of date column (default 2, text only)"
+    )
+    parser.add_option(
+        "-l", "--lines",
+        dest="lines", type="int", default=1,
+        help="number of lines for each week (default 1, text only)"
+    )
+    parser.add_option(
+        "-s", "--spacing",
+        dest="spacing", type="int", default=6,
+        help="spacing between months (default 6, text only)"
+    )
+    parser.add_option(
+        "-m", "--months",
+        dest="months", type="int", default=3,
+        help="months per row (default 3, text only)"
+    )
+    parser.add_option(
+        "-c", "--css",
+        dest="css", default="calendar.css",
+        help="CSS to use for page (html only)"
+    )
+    parser.add_option(
+        "-L", "--locale",
+        dest="locale", default=None,
+        help="locale to be used from month and weekday names"
+    )
+    parser.add_option(
+        "-e", "--encoding",
+        dest="encoding", default=None,
+        help="Encoding to use for output"
+    )
+    parser.add_option(
+        "-t", "--type",
+        dest="type", default="text",
+        choices=("text", "html"),
+        help="output type (text or html)"
+    )
+
+    (options, args) = parser.parse_args(args)
+
+    if options.locale and not options.encoding:
+        parser.error("if --locale is specified --encoding is required")
+        sys.exit(1)
+
+    if options.type == "html":
+        if options.locale:
+            cal = LocaleHTMLCalendar(locale=options.locale)
+        else:
+            cal = HTMLCalendar()
+        encoding = options.encoding
+        if encoding is None:
+            encoding = sys.getdefaultencoding()
+        optdict = dict(encoding=encoding, css=options.css)
+        if len(args) == 1:
+            print cal.formatyearpage(datetime.date.today().year, **optdict)
+        elif len(args) == 2:
+            print cal.formatyearpage(int(args[1]), **optdict)
+        else:
+            parser.error("incorrect number of arguments")
+            sys.exit(1)
+    else:
+        if options.locale:
+            cal = LocaleTextCalendar(locale=options.locale)
+        else:
+            cal = TextCalendar()
+        optdict = dict(w=options.width, l=options.lines)
+        if len(args) != 3:
+            optdict["c"] = options.spacing
+            optdict["m"] = options.months
+        if len(args) == 1:
+            result = cal.formatyear(datetime.date.today().year, **optdict)
+        elif len(args) == 2:
+            result = cal.formatyear(int(args[1]), **optdict)
+        elif len(args) == 3:
+            result = cal.formatmonth(int(args[1]), int(args[2]), **optdict)
+        else:
+            parser.error("incorrect number of arguments")
+            sys.exit(1)
+        if options.encoding:
+            result = result.encode(options.encoding)
+        print result
+
+
+if __name__ == "__main__":
+    main(sys.argv)

Added: vendor/Python/current/Lib/cgi.py
===================================================================
--- vendor/Python/current/Lib/cgi.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/cgi.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1071 @@
+#! /usr/local/bin/python
+
+# NOTE: the above "/usr/local/bin/python" is NOT a mistake.  It is
+# intentionally NOT "/usr/bin/env python".  On many systems
+# (e.g. Solaris), /usr/local/bin is not in $PATH as passed to CGI
+# scripts, and /usr/local/bin is the default directory where Python is
+# installed, so /usr/bin/env would be unable to find python.  Granted,
+# binary installations by Linux vendors often install Python in
+# /usr/bin.  So let those vendors patch cgi.py to match their choice
+# of installation.
+
+"""Support module for CGI (Common Gateway Interface) scripts.
+
+This module defines a number of utilities for use by CGI scripts
+written in Python.
+"""
+
+# XXX Perhaps there should be a slimmed version that doesn't contain
+# all those backwards compatible and debugging classes and functions?
+
+# History
+# -------
+#
+# Michael McLay started this module.  Steve Majewski changed the
+# interface to SvFormContentDict and FormContentDict.  The multipart
+# parsing was inspired by code submitted by Andreas Paepcke.  Guido van
+# Rossum rewrote, reformatted and documented the module and is currently
+# responsible for its maintenance.
+#
+
+__version__ = "2.6"
+
+
+# Imports
+# =======
+
+from operator import attrgetter
+import sys
+import os
+import urllib
+import mimetools
+import rfc822
+import UserDict
+try:
+    from cStringIO import StringIO
+except ImportError:
+    from StringIO import StringIO
+
+__all__ = ["MiniFieldStorage", "FieldStorage", "FormContentDict",
+           "SvFormContentDict", "InterpFormContentDict", "FormContent",
+           "parse", "parse_qs", "parse_qsl", "parse_multipart",
+           "parse_header", "print_exception", "print_environ",
+           "print_form", "print_directory", "print_arguments",
+           "print_environ_usage", "escape"]
+
+# Logging support
+# ===============
+
+logfile = ""            # Filename to log to, if not empty
+logfp = None            # File object to log to, if not None
+
+def initlog(*allargs):
+    """Write a log message, if there is a log file.
+
+    Even though this function is called initlog(), you should always
+    use log(); log is a variable that is set either to initlog
+    (initially), to dolog (once the log file has been opened), or to
+    nolog (when logging is disabled).
+
+    The first argument is a format string; the remaining arguments (if
+    any) are arguments to the % operator, so e.g.
+        log("%s: %s", "a", "b")
+    will write "a: b" to the log file, followed by a newline.
+
+    If the global logfp is not None, it should be a file object to
+    which log data is written.
+
+    If the global logfp is None, the global logfile may be a string
+    giving a filename to open, in append mode.  This file should be
+    world writable!!!  If the file can't be opened, logging is
+    silently disabled (since there is no safe place where we could
+    send an error message).
+
+    """
+    global logfp, log
+    if logfile and not logfp:
+        try:
+            logfp = open(logfile, "a")
+        except IOError:
+            pass
+    if not logfp:
+        log = nolog
+    else:
+        log = dolog
+    log(*allargs)
+
+def dolog(fmt, *args):
+    """Write a log message to the log file.  See initlog() for docs."""
+    logfp.write(fmt%args + "\n")
+
+def nolog(*allargs):
+    """Dummy function, assigned to log when logging is disabled."""
+    pass
+
+log = initlog           # The current logging function
+
+
+# Parsing functions
+# =================
+
+# Maximum input we will accept when REQUEST_METHOD is POST
+# 0 ==> unlimited input
+maxlen = 0
+
+def parse(fp=None, environ=os.environ, keep_blank_values=0, strict_parsing=0):
+    """Parse a query in the environment or from a file (default stdin)
+
+        Arguments, all optional:
+
+        fp              : file pointer; default: sys.stdin
+
+        environ         : environment dictionary; default: os.environ
+
+        keep_blank_values: flag indicating whether blank values in
+            URL encoded forms should be treated as blank strings.
+            A true value indicates that blanks should be retained as
+            blank strings.  The default false value indicates that
+            blank values are to be ignored and treated as if they were
+            not included.
+
+        strict_parsing: flag indicating what to do with parsing errors.
+            If false (the default), errors are silently ignored.
+            If true, errors raise a ValueError exception.
+    """
+    if fp is None:
+        fp = sys.stdin
+    if not 'REQUEST_METHOD' in environ:
+        environ['REQUEST_METHOD'] = 'GET'       # For testing stand-alone
+    if environ['REQUEST_METHOD'] == 'POST':
+        ctype, pdict = parse_header(environ['CONTENT_TYPE'])
+        if ctype == 'multipart/form-data':
+            return parse_multipart(fp, pdict)
+        elif ctype == 'application/x-www-form-urlencoded':
+            clength = int(environ['CONTENT_LENGTH'])
+            if maxlen and clength > maxlen:
+                raise ValueError, 'Maximum content length exceeded'
+            qs = fp.read(clength)
+        else:
+            qs = ''                     # Unknown content-type
+        if 'QUERY_STRING' in environ:
+            if qs: qs = qs + '&'
+            qs = qs + environ['QUERY_STRING']
+        elif sys.argv[1:]:
+            if qs: qs = qs + '&'
+            qs = qs + sys.argv[1]
+        environ['QUERY_STRING'] = qs    # XXX Shouldn't, really
+    elif 'QUERY_STRING' in environ:
+        qs = environ['QUERY_STRING']
+    else:
+        if sys.argv[1:]:
+            qs = sys.argv[1]
+        else:
+            qs = ""
+        environ['QUERY_STRING'] = qs    # XXX Shouldn't, really
+    return parse_qs(qs, keep_blank_values, strict_parsing)
+
+
+def parse_qs(qs, keep_blank_values=0, strict_parsing=0):
+    """Parse a query given as a string argument.
+
+        Arguments:
+
+        qs: URL-encoded query string to be parsed
+
+        keep_blank_values: flag indicating whether blank values in
+            URL encoded queries should be treated as blank strings.
+            A true value indicates that blanks should be retained as
+            blank strings.  The default false value indicates that
+            blank values are to be ignored and treated as if they were
+            not included.
+
+        strict_parsing: flag indicating what to do with parsing errors.
+            If false (the default), errors are silently ignored.
+            If true, errors raise a ValueError exception.
+    """
+    dict = {}
+    for name, value in parse_qsl(qs, keep_blank_values, strict_parsing):
+        if name in dict:
+            dict[name].append(value)
+        else:
+            dict[name] = [value]
+    return dict
+
+def parse_qsl(qs, keep_blank_values=0, strict_parsing=0):
+    """Parse a query given as a string argument.
+
+    Arguments:
+
+    qs: URL-encoded query string to be parsed
+
+    keep_blank_values: flag indicating whether blank values in
+        URL encoded queries should be treated as blank strings.  A
+        true value indicates that blanks should be retained as blank
+        strings.  The default false value indicates that blank values
+        are to be ignored and treated as if they were  not included.
+
+    strict_parsing: flag indicating what to do with parsing errors. If
+        false (the default), errors are silently ignored. If true,
+        errors raise a ValueError exception.
+
+    Returns a list, as G-d intended.
+    """
+    pairs = [s2 for s1 in qs.split('&') for s2 in s1.split(';')]
+    r = []
+    for name_value in pairs:
+        if not name_value and not strict_parsing:
+            continue
+        nv = name_value.split('=', 1)
+        if len(nv) != 2:
+            if strict_parsing:
+                raise ValueError, "bad query field: %r" % (name_value,)
+            # Handle case of a control-name with no equal sign
+            if keep_blank_values:
+                nv.append('')
+            else:
+                continue
+        if len(nv[1]) or keep_blank_values:
+            name = urllib.unquote(nv[0].replace('+', ' '))
+            value = urllib.unquote(nv[1].replace('+', ' '))
+            r.append((name, value))
+
+    return r
+
+
+def parse_multipart(fp, pdict):
+    """Parse multipart input.
+
+    Arguments:
+    fp   : input file
+    pdict: dictionary containing other parameters of content-type header
+
+    Returns a dictionary just like parse_qs(): keys are the field names, each
+    value is a list of values for that field.  This is easy to use but not
+    much good if you are expecting megabytes to be uploaded -- in that case,
+    use the FieldStorage class instead which is much more flexible.  Note
+    that content-type is the raw, unparsed contents of the content-type
+    header.
+
+    XXX This does not parse nested multipart parts -- use FieldStorage for
+    that.
+
+    XXX This should really be subsumed by FieldStorage altogether -- no
+    point in having two implementations of the same parsing algorithm.
+    Also, FieldStorage protects itself better against certain DoS attacks
+    by limiting the size of the data read in one chunk.  The API here
+    does not support that kind of protection.  This also affects parse()
+    since it can call parse_multipart().
+
+    """
+    boundary = ""
+    if 'boundary' in pdict:
+        boundary = pdict['boundary']
+    if not valid_boundary(boundary):
+        raise ValueError,  ('Invalid boundary in multipart form: %r'
+                            % (boundary,))
+
+    nextpart = "--" + boundary
+    lastpart = "--" + boundary + "--"
+    partdict = {}
+    terminator = ""
+
+    while terminator != lastpart:
+        bytes = -1
+        data = None
+        if terminator:
+            # At start of next part.  Read headers first.
+            headers = mimetools.Message(fp)
+            clength = headers.getheader('content-length')
+            if clength:
+                try:
+                    bytes = int(clength)
+                except ValueError:
+                    pass
+            if bytes > 0:
+                if maxlen and bytes > maxlen:
+                    raise ValueError, 'Maximum content length exceeded'
+                data = fp.read(bytes)
+            else:
+                data = ""
+        # Read lines until end of part.
+        lines = []
+        while 1:
+            line = fp.readline()
+            if not line:
+                terminator = lastpart # End outer loop
+                break
+            if line[:2] == "--":
+                terminator = line.strip()
+                if terminator in (nextpart, lastpart):
+                    break
+            lines.append(line)
+        # Done with part.
+        if data is None:
+            continue
+        if bytes < 0:
+            if lines:
+                # Strip final line terminator
+                line = lines[-1]
+                if line[-2:] == "\r\n":
+                    line = line[:-2]
+                elif line[-1:] == "\n":
+                    line = line[:-1]
+                lines[-1] = line
+                data = "".join(lines)
+        line = headers['content-disposition']
+        if not line:
+            continue
+        key, params = parse_header(line)
+        if key != 'form-data':
+            continue
+        if 'name' in params:
+            name = params['name']
+        else:
+            continue
+        if name in partdict:
+            partdict[name].append(data)
+        else:
+            partdict[name] = [data]
+
+    return partdict
+
+
+def parse_header(line):
+    """Parse a Content-type like header.
+
+    Return the main content-type and a dictionary of options.
+
+    """
+    plist = [x.strip() for x in line.split(';')]
+    key = plist.pop(0).lower()
+    pdict = {}
+    for p in plist:
+        i = p.find('=')
+        if i >= 0:
+            name = p[:i].strip().lower()
+            value = p[i+1:].strip()
+            if len(value) >= 2 and value[0] == value[-1] == '"':
+                value = value[1:-1]
+                value = value.replace('\\\\', '\\').replace('\\"', '"')
+            pdict[name] = value
+    return key, pdict
+
+
+# Classes for field storage
+# =========================
+
+class MiniFieldStorage:
+
+    """Like FieldStorage, for use when no file uploads are possible."""
+
+    # Dummy attributes
+    filename = None
+    list = None
+    type = None
+    file = None
+    type_options = {}
+    disposition = None
+    disposition_options = {}
+    headers = {}
+
+    def __init__(self, name, value):
+        """Constructor from field name and value."""
+        self.name = name
+        self.value = value
+        # self.file = StringIO(value)
+
+    def __repr__(self):
+        """Return printable representation."""
+        return "MiniFieldStorage(%r, %r)" % (self.name, self.value)
+
+
+class FieldStorage:
+
+    """Store a sequence of fields, reading multipart/form-data.
+
+    This class provides naming, typing, files stored on disk, and
+    more.  At the top level, it is accessible like a dictionary, whose
+    keys are the field names.  (Note: None can occur as a field name.)
+    The items are either a Python list (if there's multiple values) or
+    another FieldStorage or MiniFieldStorage object.  If it's a single
+    object, it has the following attributes:
+
+    name: the field name, if specified; otherwise None
+
+    filename: the filename, if specified; otherwise None; this is the
+        client side filename, *not* the file name on which it is
+        stored (that's a temporary file you don't deal with)
+
+    value: the value as a *string*; for file uploads, this
+        transparently reads the file every time you request the value
+
+    file: the file(-like) object from which you can read the data;
+        None if the data is stored a simple string
+
+    type: the content-type, or None if not specified
+
+    type_options: dictionary of options specified on the content-type
+        line
+
+    disposition: content-disposition, or None if not specified
+
+    disposition_options: dictionary of corresponding options
+
+    headers: a dictionary(-like) object (sometimes rfc822.Message or a
+        subclass thereof) containing *all* headers
+
+    The class is subclassable, mostly for the purpose of overriding
+    the make_file() method, which is called internally to come up with
+    a file open for reading and writing.  This makes it possible to
+    override the default choice of storing all files in a temporary
+    directory and unlinking them as soon as they have been opened.
+
+    """
+
+    def __init__(self, fp=None, headers=None, outerboundary="",
+                 environ=os.environ, keep_blank_values=0, strict_parsing=0):
+        """Constructor.  Read multipart/* until last part.
+
+        Arguments, all optional:
+
+        fp              : file pointer; default: sys.stdin
+            (not used when the request method is GET)
+
+        headers         : header dictionary-like object; default:
+            taken from environ as per CGI spec
+
+        outerboundary   : terminating multipart boundary
+            (for internal use only)
+
+        environ         : environment dictionary; default: os.environ
+
+        keep_blank_values: flag indicating whether blank values in
+            URL encoded forms should be treated as blank strings.
+            A true value indicates that blanks should be retained as
+            blank strings.  The default false value indicates that
+            blank values are to be ignored and treated as if they were
+            not included.
+
+        strict_parsing: flag indicating what to do with parsing errors.
+            If false (the default), errors are silently ignored.
+            If true, errors raise a ValueError exception.
+
+        """
+        method = 'GET'
+        self.keep_blank_values = keep_blank_values
+        self.strict_parsing = strict_parsing
+        if 'REQUEST_METHOD' in environ:
+            method = environ['REQUEST_METHOD'].upper()
+        if method == 'GET' or method == 'HEAD':
+            if 'QUERY_STRING' in environ:
+                qs = environ['QUERY_STRING']
+            elif sys.argv[1:]:
+                qs = sys.argv[1]
+            else:
+                qs = ""
+            fp = StringIO(qs)
+            if headers is None:
+                headers = {'content-type':
+                           "application/x-www-form-urlencoded"}
+        if headers is None:
+            headers = {}
+            if method == 'POST':
+                # Set default content-type for POST to what's traditional
+                headers['content-type'] = "application/x-www-form-urlencoded"
+            if 'CONTENT_TYPE' in environ:
+                headers['content-type'] = environ['CONTENT_TYPE']
+            if 'CONTENT_LENGTH' in environ:
+                headers['content-length'] = environ['CONTENT_LENGTH']
+        self.fp = fp or sys.stdin
+        self.headers = headers
+        self.outerboundary = outerboundary
+
+        # Process content-disposition header
+        cdisp, pdict = "", {}
+        if 'content-disposition' in self.headers:
+            cdisp, pdict = parse_header(self.headers['content-disposition'])
+        self.disposition = cdisp
+        self.disposition_options = pdict
+        self.name = None
+        if 'name' in pdict:
+            self.name = pdict['name']
+        self.filename = None
+        if 'filename' in pdict:
+            self.filename = pdict['filename']
+
+        # Process content-type header
+        #
+        # Honor any existing content-type header.  But if there is no
+        # content-type header, use some sensible defaults.  Assume
+        # outerboundary is "" at the outer level, but something non-false
+        # inside a multi-part.  The default for an inner part is text/plain,
+        # but for an outer part it should be urlencoded.  This should catch
+        # bogus clients which erroneously forget to include a content-type
+        # header.
+        #
+        # See below for what we do if there does exist a content-type header,
+        # but it happens to be something we don't understand.
+        if 'content-type' in self.headers:
+            ctype, pdict = parse_header(self.headers['content-type'])
+        elif self.outerboundary or method != 'POST':
+            ctype, pdict = "text/plain", {}
+        else:
+            ctype, pdict = 'application/x-www-form-urlencoded', {}
+        self.type = ctype
+        self.type_options = pdict
+        self.innerboundary = ""
+        if 'boundary' in pdict:
+            self.innerboundary = pdict['boundary']
+        clen = -1
+        if 'content-length' in self.headers:
+            try:
+                clen = int(self.headers['content-length'])
+            except ValueError:
+                pass
+            if maxlen and clen > maxlen:
+                raise ValueError, 'Maximum content length exceeded'
+        self.length = clen
+
+        self.list = self.file = None
+        self.done = 0
+        if ctype == 'application/x-www-form-urlencoded':
+            self.read_urlencoded()
+        elif ctype[:10] == 'multipart/':
+            self.read_multi(environ, keep_blank_values, strict_parsing)
+        else:
+            self.read_single()
+
+    def __repr__(self):
+        """Return a printable representation."""
+        return "FieldStorage(%r, %r, %r)" % (
+                self.name, self.filename, self.value)
+
+    def __iter__(self):
+        return iter(self.keys())
+
+    def __getattr__(self, name):
+        if name != 'value':
+            raise AttributeError, name
+        if self.file:
+            self.file.seek(0)
+            value = self.file.read()
+            self.file.seek(0)
+        elif self.list is not None:
+            value = self.list
+        else:
+            value = None
+        return value
+
+    def __getitem__(self, key):
+        """Dictionary style indexing."""
+        if self.list is None:
+            raise TypeError, "not indexable"
+        found = []
+        for item in self.list:
+            if item.name == key: found.append(item)
+        if not found:
+            raise KeyError, key
+        if len(found) == 1:
+            return found[0]
+        else:
+            return found
+
+    def getvalue(self, key, default=None):
+        """Dictionary style get() method, including 'value' lookup."""
+        if key in self:
+            value = self[key]
+            if type(value) is type([]):
+                return map(attrgetter('value'), value)
+            else:
+                return value.value
+        else:
+            return default
+
+    def getfirst(self, key, default=None):
+        """ Return the first value received."""
+        if key in self:
+            value = self[key]
+            if type(value) is type([]):
+                return value[0].value
+            else:
+                return value.value
+        else:
+            return default
+
+    def getlist(self, key):
+        """ Return list of received values."""
+        if key in self:
+            value = self[key]
+            if type(value) is type([]):
+                return map(attrgetter('value'), value)
+            else:
+                return [value.value]
+        else:
+            return []
+
+    def keys(self):
+        """Dictionary style keys() method."""
+        if self.list is None:
+            raise TypeError, "not indexable"
+        keys = []
+        for item in self.list:
+            if item.name not in keys: keys.append(item.name)
+        return keys
+
+    def has_key(self, key):
+        """Dictionary style has_key() method."""
+        if self.list is None:
+            raise TypeError, "not indexable"
+        for item in self.list:
+            if item.name == key: return True
+        return False
+
+    def __contains__(self, key):
+        """Dictionary style __contains__ method."""
+        if self.list is None:
+            raise TypeError, "not indexable"
+        for item in self.list:
+            if item.name == key: return True
+        return False
+
+    def __len__(self):
+        """Dictionary style len(x) support."""
+        return len(self.keys())
+
+    def read_urlencoded(self):
+        """Internal: read data in query string format."""
+        qs = self.fp.read(self.length)
+        self.list = list = []
+        for key, value in parse_qsl(qs, self.keep_blank_values,
+                                    self.strict_parsing):
+            list.append(MiniFieldStorage(key, value))
+        self.skip_lines()
+
+    FieldStorageClass = None
+
+    def read_multi(self, environ, keep_blank_values, strict_parsing):
+        """Internal: read a part that is itself multipart."""
+        ib = self.innerboundary
+        if not valid_boundary(ib):
+            raise ValueError, 'Invalid boundary in multipart form: %r' % (ib,)
+        self.list = []
+        klass = self.FieldStorageClass or self.__class__
+        part = klass(self.fp, {}, ib,
+                     environ, keep_blank_values, strict_parsing)
+        # Throw first part away
+        while not part.done:
+            headers = rfc822.Message(self.fp)
+            part = klass(self.fp, headers, ib,
+                         environ, keep_blank_values, strict_parsing)
+            self.list.append(part)
+        self.skip_lines()
+
+    def read_single(self):
+        """Internal: read an atomic part."""
+        if self.length >= 0:
+            self.read_binary()
+            self.skip_lines()
+        else:
+            self.read_lines()
+        self.file.seek(0)
+
+    bufsize = 8*1024            # I/O buffering size for copy to file
+
+    def read_binary(self):
+        """Internal: read binary data."""
+        self.file = self.make_file('b')
+        todo = self.length
+        if todo >= 0:
+            while todo > 0:
+                data = self.fp.read(min(todo, self.bufsize))
+                if not data:
+                    self.done = -1
+                    break
+                self.file.write(data)
+                todo = todo - len(data)
+
+    def read_lines(self):
+        """Internal: read lines until EOF or outerboundary."""
+        self.file = self.__file = StringIO()
+        if self.outerboundary:
+            self.read_lines_to_outerboundary()
+        else:
+            self.read_lines_to_eof()
+
+    def __write(self, line):
+        if self.__file is not None:
+            if self.__file.tell() + len(line) > 1000:
+                self.file = self.make_file('')
+                self.file.write(self.__file.getvalue())
+                self.__file = None
+        self.file.write(line)
+
+    def read_lines_to_eof(self):
+        """Internal: read lines until EOF."""
+        while 1:
+            line = self.fp.readline(1<<16)
+            if not line:
+                self.done = -1
+                break
+            self.__write(line)
+
+    def read_lines_to_outerboundary(self):
+        """Internal: read lines until outerboundary."""
+        next = "--" + self.outerboundary
+        last = next + "--"
+        delim = ""
+        last_line_lfend = True
+        while 1:
+            line = self.fp.readline(1<<16)
+            if not line:
+                self.done = -1
+                break
+            if line[:2] == "--" and last_line_lfend:
+                strippedline = line.strip()
+                if strippedline == next:
+                    break
+                if strippedline == last:
+                    self.done = 1
+                    break
+            odelim = delim
+            if line[-2:] == "\r\n":
+                delim = "\r\n"
+                line = line[:-2]
+                last_line_lfend = True
+            elif line[-1] == "\n":
+                delim = "\n"
+                line = line[:-1]
+                last_line_lfend = True
+            else:
+                delim = ""
+                last_line_lfend = False
+            self.__write(odelim + line)
+
+    def skip_lines(self):
+        """Internal: skip lines until outer boundary if defined."""
+        if not self.outerboundary or self.done:
+            return
+        next = "--" + self.outerboundary
+        last = next + "--"
+        last_line_lfend = True
+        while 1:
+            line = self.fp.readline(1<<16)
+            if not line:
+                self.done = -1
+                break
+            if line[:2] == "--" and last_line_lfend:
+                strippedline = line.strip()
+                if strippedline == next:
+                    break
+                if strippedline == last:
+                    self.done = 1
+                    break
+            last_line_lfend = line.endswith('\n')
+
+    def make_file(self, binary=None):
+        """Overridable: return a readable & writable file.
+
+        The file will be used as follows:
+        - data is written to it
+        - seek(0)
+        - data is read from it
+
+        The 'binary' argument is unused -- the file is always opened
+        in binary mode.
+
+        This version opens a temporary file for reading and writing,
+        and immediately deletes (unlinks) it.  The trick (on Unix!) is
+        that the file can still be used, but it can't be opened by
+        another process, and it will automatically be deleted when it
+        is closed or when the current process terminates.
+
+        If you want a more permanent file, you derive a class which
+        overrides this method.  If you want a visible temporary file
+        that is nevertheless automatically deleted when the script
+        terminates, try defining a __del__ method in a derived class
+        which unlinks the temporary files you have created.
+
+        """
+        import tempfile
+        return tempfile.TemporaryFile("w+b")
+
+
+
+# Backwards Compatibility Classes
+# ===============================
+
+class FormContentDict(UserDict.UserDict):
+    """Form content as dictionary with a list of values per field.
+
+    form = FormContentDict()
+
+    form[key] -> [value, value, ...]
+    key in form -> Boolean
+    form.keys() -> [key, key, ...]
+    form.values() -> [[val, val, ...], [val, val, ...], ...]
+    form.items() ->  [(key, [val, val, ...]), (key, [val, val, ...]), ...]
+    form.dict == {key: [val, val, ...], ...}
+
+    """
+    def __init__(self, environ=os.environ):
+        self.dict = self.data = parse(environ=environ)
+        self.query_string = environ['QUERY_STRING']
+
+
+class SvFormContentDict(FormContentDict):
+    """Form content as dictionary expecting a single value per field.
+
+    If you only expect a single value for each field, then form[key]
+    will return that single value.  It will raise an IndexError if
+    that expectation is not true.  If you expect a field to have
+    possible multiple values, than you can use form.getlist(key) to
+    get all of the values.  values() and items() are a compromise:
+    they return single strings where there is a single value, and
+    lists of strings otherwise.
+
+    """
+    def __getitem__(self, key):
+        if len(self.dict[key]) > 1:
+            raise IndexError, 'expecting a single value'
+        return self.dict[key][0]
+    def getlist(self, key):
+        return self.dict[key]
+    def values(self):
+        result = []
+        for value in self.dict.values():
+            if len(value) == 1:
+                result.append(value[0])
+            else: result.append(value)
+        return result
+    def items(self):
+        result = []
+        for key, value in self.dict.items():
+            if len(value) == 1:
+                result.append((key, value[0]))
+            else: result.append((key, value))
+        return result
+
+
+class InterpFormContentDict(SvFormContentDict):
+    """This class is present for backwards compatibility only."""
+    def __getitem__(self, key):
+        v = SvFormContentDict.__getitem__(self, key)
+        if v[0] in '0123456789+-.':
+            try: return int(v)
+            except ValueError:
+                try: return float(v)
+                except ValueError: pass
+        return v.strip()
+    def values(self):
+        result = []
+        for key in self.keys():
+            try:
+                result.append(self[key])
+            except IndexError:
+                result.append(self.dict[key])
+        return result
+    def items(self):
+        result = []
+        for key in self.keys():
+            try:
+                result.append((key, self[key]))
+            except IndexError:
+                result.append((key, self.dict[key]))
+        return result
+
+
+class FormContent(FormContentDict):
+    """This class is present for backwards compatibility only."""
+    def values(self, key):
+        if key in self.dict :return self.dict[key]
+        else: return None
+    def indexed_value(self, key, location):
+        if key in self.dict:
+            if len(self.dict[key]) > location:
+                return self.dict[key][location]
+            else: return None
+        else: return None
+    def value(self, key):
+        if key in self.dict: return self.dict[key][0]
+        else: return None
+    def length(self, key):
+        return len(self.dict[key])
+    def stripped(self, key):
+        if key in self.dict: return self.dict[key][0].strip()
+        else: return None
+    def pars(self):
+        return self.dict
+
+
+# Test/debug code
+# ===============
+
+def test(environ=os.environ):
+    """Robust test CGI script, usable as main program.
+
+    Write minimal HTTP headers and dump all information provided to
+    the script in HTML form.
+
+    """
+    print "Content-type: text/html"
+    print
+    sys.stderr = sys.stdout
+    try:
+        form = FieldStorage()   # Replace with other classes to test those
+        print_directory()
+        print_arguments()
+        print_form(form)
+        print_environ(environ)
+        print_environ_usage()
+        def f():
+            exec "testing print_exception() -- <I>italics?</I>"
+        def g(f=f):
+            f()
+        print "<H3>What follows is a test, not an actual exception:</H3>"
+        g()
+    except:
+        print_exception()
+
+    print "<H1>Second try with a small maxlen...</H1>"
+
+    global maxlen
+    maxlen = 50
+    try:
+        form = FieldStorage()   # Replace with other classes to test those
+        print_directory()
+        print_arguments()
+        print_form(form)
+        print_environ(environ)
+    except:
+        print_exception()
+
+def print_exception(type=None, value=None, tb=None, limit=None):
+    if type is None:
+        type, value, tb = sys.exc_info()
+    import traceback
+    print
+    print "<H3>Traceback (most recent call last):</H3>"
+    list = traceback.format_tb(tb, limit) + \
+           traceback.format_exception_only(type, value)
+    print "<PRE>%s<B>%s</B></PRE>" % (
+        escape("".join(list[:-1])),
+        escape(list[-1]),
+        )
+    del tb
+
+def print_environ(environ=os.environ):
+    """Dump the shell environment as HTML."""
+    keys = environ.keys()
+    keys.sort()
+    print
+    print "<H3>Shell Environment:</H3>"
+    print "<DL>"
+    for key in keys:
+        print "<DT>", escape(key), "<DD>", escape(environ[key])
+    print "</DL>"
+    print
+
+def print_form(form):
+    """Dump the contents of a form as HTML."""
+    keys = form.keys()
+    keys.sort()
+    print
+    print "<H3>Form Contents:</H3>"
+    if not keys:
+        print "<P>No form fields."
+    print "<DL>"
+    for key in keys:
+        print "<DT>" + escape(key) + ":",
+        value = form[key]
+        print "<i>" + escape(repr(type(value))) + "</i>"
+        print "<DD>" + escape(repr(value))
+    print "</DL>"
+    print
+
+def print_directory():
+    """Dump the current directory as HTML."""
+    print
+    print "<H3>Current Working Directory:</H3>"
+    try:
+        pwd = os.getcwd()
+    except os.error, msg:
+        print "os.error:", escape(str(msg))
+    else:
+        print escape(pwd)
+    print
+
+def print_arguments():
+    print
+    print "<H3>Command Line Arguments:</H3>"
+    print
+    print sys.argv
+    print
+
+def print_environ_usage():
+    """Dump a list of environment variables used by CGI as HTML."""
+    print """
+<H3>These environment variables could have been set:</H3>
+<UL>
+<LI>AUTH_TYPE
+<LI>CONTENT_LENGTH
+<LI>CONTENT_TYPE
+<LI>DATE_GMT
+<LI>DATE_LOCAL
+<LI>DOCUMENT_NAME
+<LI>DOCUMENT_ROOT
+<LI>DOCUMENT_URI
+<LI>GATEWAY_INTERFACE
+<LI>LAST_MODIFIED
+<LI>PATH
+<LI>PATH_INFO
+<LI>PATH_TRANSLATED
+<LI>QUERY_STRING
+<LI>REMOTE_ADDR
+<LI>REMOTE_HOST
+<LI>REMOTE_IDENT
+<LI>REMOTE_USER
+<LI>REQUEST_METHOD
+<LI>SCRIPT_NAME
+<LI>SERVER_NAME
+<LI>SERVER_PORT
+<LI>SERVER_PROTOCOL
+<LI>SERVER_ROOT
+<LI>SERVER_SOFTWARE
+</UL>
+In addition, HTTP headers sent by the server may be passed in the
+environment as well.  Here are some common variable names:
+<UL>
+<LI>HTTP_ACCEPT
+<LI>HTTP_CONNECTION
+<LI>HTTP_HOST
+<LI>HTTP_PRAGMA
+<LI>HTTP_REFERER
+<LI>HTTP_USER_AGENT
+</UL>
+"""
+
+
+# Utilities
+# =========
+
+def escape(s, quote=None):
+    '''Replace special characters "&", "<" and ">" to HTML-safe sequences.
+    If the optional flag quote is true, the quotation mark character (")
+    is also translated.'''
+    s = s.replace("&", "&amp;") # Must be done first!
+    s = s.replace("<", "&lt;")
+    s = s.replace(">", "&gt;")
+    if quote:
+        s = s.replace('"', "&quot;")
+    return s
+
+def valid_boundary(s, _vb_pattern="^[ -~]{0,200}[!-~]$"):
+    import re
+    return re.match(_vb_pattern, s)
+
+# Invoke mainline
+# ===============
+
+# Call test() when this file is run as a script (not imported as a module)
+if __name__ == '__main__':
+    test()


Property changes on: vendor/Python/current/Lib/cgi.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/cgitb.py
===================================================================
--- vendor/Python/current/Lib/cgitb.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/cgitb.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,317 @@
+"""More comprehensive traceback formatting for Python scripts.
+
+To enable this module, do:
+
+    import cgitb; cgitb.enable()
+
+at the top of your script.  The optional arguments to enable() are:
+
+    display     - if true, tracebacks are displayed in the web browser
+    logdir      - if set, tracebacks are written to files in this directory
+    context     - number of lines of source code to show for each stack frame
+    format      - 'text' or 'html' controls the output format
+
+By default, tracebacks are displayed but not saved, the context is 5 lines
+and the output format is 'html' (for backwards compatibility with the
+original use of this module)
+
+Alternatively, if you have caught an exception and want cgitb to display it
+for you, call cgitb.handler().  The optional argument to handler() is a
+3-item tuple (etype, evalue, etb) just like the value of sys.exc_info().
+The default handler displays output as HTML.
+"""
+
+__author__ = 'Ka-Ping Yee'
+
+__version__ = '$Revision: 39758 $'
+
+import sys
+
+def reset():
+    """Return a string that resets the CGI and browser to a known state."""
+    return '''<!--: spam
+Content-Type: text/html
+
+<body bgcolor="#f0f0f8"><font color="#f0f0f8" size="-5"> -->
+<body bgcolor="#f0f0f8"><font color="#f0f0f8" size="-5"> --> -->
+</font> </font> </font> </script> </object> </blockquote> </pre>
+</table> </table> </table> </table> </table> </font> </font> </font>'''
+
+__UNDEF__ = []                          # a special sentinel object
+def small(text):
+    if text:
+        return '<small>' + text + '</small>'
+    else:
+        return ''
+
+def strong(text):
+    if text:
+        return '<strong>' + text + '</strong>'
+    else:
+        return ''
+
+def grey(text):
+    if text:
+        return '<font color="#909090">' + text + '</font>'
+    else:
+        return ''
+
+def lookup(name, frame, locals):
+    """Find the value for a given name in the given environment."""
+    if name in locals:
+        return 'local', locals[name]
+    if name in frame.f_globals:
+        return 'global', frame.f_globals[name]
+    if '__builtins__' in frame.f_globals:
+        builtins = frame.f_globals['__builtins__']
+        if type(builtins) is type({}):
+            if name in builtins:
+                return 'builtin', builtins[name]
+        else:
+            if hasattr(builtins, name):
+                return 'builtin', getattr(builtins, name)
+    return None, __UNDEF__
+
+def scanvars(reader, frame, locals):
+    """Scan one logical line of Python and look up values of variables used."""
+    import tokenize, keyword
+    vars, lasttoken, parent, prefix, value = [], None, None, '', __UNDEF__
+    for ttype, token, start, end, line in tokenize.generate_tokens(reader):
+        if ttype == tokenize.NEWLINE: break
+        if ttype == tokenize.NAME and token not in keyword.kwlist:
+            if lasttoken == '.':
+                if parent is not __UNDEF__:
+                    value = getattr(parent, token, __UNDEF__)
+                    vars.append((prefix + token, prefix, value))
+            else:
+                where, value = lookup(token, frame, locals)
+                vars.append((token, where, value))
+        elif token == '.':
+            prefix += lasttoken + '.'
+            parent = value
+        else:
+            parent, prefix = None, ''
+        lasttoken = token
+    return vars
+
+def html((etype, evalue, etb), context=5):
+    """Return a nice HTML document describing a given traceback."""
+    import os, types, time, traceback, linecache, inspect, pydoc
+
+    if type(etype) is types.ClassType:
+        etype = etype.__name__
+    pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable
+    date = time.ctime(time.time())
+    head = '<body bgcolor="#f0f0f8">' + pydoc.html.heading(
+        '<big><big>%s</big></big>' %
+        strong(pydoc.html.escape(str(etype))),
+        '#ffffff', '#6622aa', pyver + '<br>' + date) + '''
+<p>A problem occurred in a Python script.  Here is the sequence of
+function calls leading up to the error, in the order they occurred.</p>'''
+
+    indent = '<tt>' + small('&nbsp;' * 5) + '&nbsp;</tt>'
+    frames = []
+    records = inspect.getinnerframes(etb, context)
+    for frame, file, lnum, func, lines, index in records:
+        if file:
+            file = os.path.abspath(file)
+            link = '<a href="file://%s">%s</a>' % (file, pydoc.html.escape(file))
+        else:
+            file = link = '?'
+        args, varargs, varkw, locals = inspect.getargvalues(frame)
+        call = ''
+        if func != '?':
+            call = 'in ' + strong(func) + \
+                inspect.formatargvalues(args, varargs, varkw, locals,
+                    formatvalue=lambda value: '=' + pydoc.html.repr(value))
+
+        highlight = {}
+        def reader(lnum=[lnum]):
+            highlight[lnum[0]] = 1
+            try: return linecache.getline(file, lnum[0])
+            finally: lnum[0] += 1
+        vars = scanvars(reader, frame, locals)
+
+        rows = ['<tr><td bgcolor="#d8bbff">%s%s %s</td></tr>' %
+                ('<big>&nbsp;</big>', link, call)]
+        if index is not None:
+            i = lnum - index
+            for line in lines:
+                num = small('&nbsp;' * (5-len(str(i))) + str(i)) + '&nbsp;'
+                line = '<tt>%s%s</tt>' % (num, pydoc.html.preformat(line))
+                if i in highlight:
+                    rows.append('<tr><td bgcolor="#ffccee">%s</td></tr>' % line)
+                else:
+                    rows.append('<tr><td>%s</td></tr>' % grey(line))
+                i += 1
+
+        done, dump = {}, []
+        for name, where, value in vars:
+            if name in done: continue
+            done[name] = 1
+            if value is not __UNDEF__:
+                if where in ('global', 'builtin'):
+                    name = ('<em>%s</em> ' % where) + strong(name)
+                elif where == 'local':
+                    name = strong(name)
+                else:
+                    name = where + strong(name.split('.')[-1])
+                dump.append('%s&nbsp;= %s' % (name, pydoc.html.repr(value)))
+            else:
+                dump.append(name + ' <em>undefined</em>')
+
+        rows.append('<tr><td>%s</td></tr>' % small(grey(', '.join(dump))))
+        frames.append('''
+<table width="100%%" cellspacing=0 cellpadding=0 border=0>
+%s</table>''' % '\n'.join(rows))
+
+    exception = ['<p>%s: %s' % (strong(pydoc.html.escape(str(etype))),
+                                pydoc.html.escape(str(evalue)))]
+    if type(evalue) is types.InstanceType:
+        for name in dir(evalue):
+            if name[:1] == '_': continue
+            value = pydoc.html.repr(getattr(evalue, name))
+            exception.append('\n<br>%s%s&nbsp;=\n%s' % (indent, name, value))
+
+    import traceback
+    return head + ''.join(frames) + ''.join(exception) + '''
+
+
+<!-- The above is a description of an error in a Python program, formatted
+     for a Web browser because the 'cgitb' module was enabled.  In case you
+     are not reading this in a Web browser, here is the original traceback:
+
+%s
+-->
+''' % ''.join(traceback.format_exception(etype, evalue, etb))
+
+def text((etype, evalue, etb), context=5):
+    """Return a plain text document describing a given traceback."""
+    import os, types, time, traceback, linecache, inspect, pydoc
+
+    if type(etype) is types.ClassType:
+        etype = etype.__name__
+    pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable
+    date = time.ctime(time.time())
+    head = "%s\n%s\n%s\n" % (str(etype), pyver, date) + '''
+A problem occurred in a Python script.  Here is the sequence of
+function calls leading up to the error, in the order they occurred.
+'''
+
+    frames = []
+    records = inspect.getinnerframes(etb, context)
+    for frame, file, lnum, func, lines, index in records:
+        file = file and os.path.abspath(file) or '?'
+        args, varargs, varkw, locals = inspect.getargvalues(frame)
+        call = ''
+        if func != '?':
+            call = 'in ' + func + \
+                inspect.formatargvalues(args, varargs, varkw, locals,
+                    formatvalue=lambda value: '=' + pydoc.text.repr(value))
+
+        highlight = {}
+        def reader(lnum=[lnum]):
+            highlight[lnum[0]] = 1
+            try: return linecache.getline(file, lnum[0])
+            finally: lnum[0] += 1
+        vars = scanvars(reader, frame, locals)
+
+        rows = [' %s %s' % (file, call)]
+        if index is not None:
+            i = lnum - index
+            for line in lines:
+                num = '%5d ' % i
+                rows.append(num+line.rstrip())
+                i += 1
+
+        done, dump = {}, []
+        for name, where, value in vars:
+            if name in done: continue
+            done[name] = 1
+            if value is not __UNDEF__:
+                if where == 'global': name = 'global ' + name
+                elif where != 'local': name = where + name.split('.')[-1]
+                dump.append('%s = %s' % (name, pydoc.text.repr(value)))
+            else:
+                dump.append(name + ' undefined')
+
+        rows.append('\n'.join(dump))
+        frames.append('\n%s\n' % '\n'.join(rows))
+
+    exception = ['%s: %s' % (str(etype), str(evalue))]
+    if type(evalue) is types.InstanceType:
+        for name in dir(evalue):
+            value = pydoc.text.repr(getattr(evalue, name))
+            exception.append('\n%s%s = %s' % (" "*4, name, value))
+
+    import traceback
+    return head + ''.join(frames) + ''.join(exception) + '''
+
+The above is a description of an error in a Python program.  Here is
+the original traceback:
+
+%s
+''' % ''.join(traceback.format_exception(etype, evalue, etb))
+
+class Hook:
+    """A hook to replace sys.excepthook that shows tracebacks in HTML."""
+
+    def __init__(self, display=1, logdir=None, context=5, file=None,
+                 format="html"):
+        self.display = display          # send tracebacks to browser if true
+        self.logdir = logdir            # log tracebacks to files if not None
+        self.context = context          # number of source code lines per frame
+        self.file = file or sys.stdout  # place to send the output
+        self.format = format
+
+    def __call__(self, etype, evalue, etb):
+        self.handle((etype, evalue, etb))
+
+    def handle(self, info=None):
+        info = info or sys.exc_info()
+        if self.format == "html":
+            self.file.write(reset())
+
+        formatter = (self.format=="html") and html or text
+        plain = False
+        try:
+            doc = formatter(info, self.context)
+        except:                         # just in case something goes wrong
+            import traceback
+            doc = ''.join(traceback.format_exception(*info))
+            plain = True
+
+        if self.display:
+            if plain:
+                doc = doc.replace('&', '&amp;').replace('<', '&lt;')
+                self.file.write('<pre>' + doc + '</pre>\n')
+            else:
+                self.file.write(doc + '\n')
+        else:
+            self.file.write('<p>A problem occurred in a Python script.\n')
+
+        if self.logdir is not None:
+            import os, tempfile
+            suffix = ['.txt', '.html'][self.format=="html"]
+            (fd, path) = tempfile.mkstemp(suffix=suffix, dir=self.logdir)
+            try:
+                file = os.fdopen(fd, 'w')
+                file.write(doc)
+                file.close()
+                msg = '<p> %s contains the description of this error.' % path
+            except:
+                msg = '<p> Tried to save traceback to %s, but failed.' % path
+            self.file.write(msg + '\n')
+        try:
+            self.file.flush()
+        except: pass
+
+handler = Hook().handle
+def enable(display=1, logdir=None, context=5, format="html"):
+    """Install an exception handler that formats tracebacks as HTML.
+
+    The optional argument 'display' can be set to 0 to suppress sending the
+    traceback to the browser, and 'logdir' can be set to a directory to cause
+    tracebacks to be written to files there."""
+    sys.excepthook = Hook(display=display, logdir=logdir,
+                          context=context, format=format)

Added: vendor/Python/current/Lib/chunk.py
===================================================================
--- vendor/Python/current/Lib/chunk.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/chunk.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,167 @@
+"""Simple class to read IFF chunks.
+
+An IFF chunk (used in formats such as AIFF, TIFF, RMFF (RealMedia File
+Format)) has the following structure:
+
++----------------+
+| ID (4 bytes)   |
++----------------+
+| size (4 bytes) |
++----------------+
+| data           |
+| ...            |
++----------------+
+
+The ID is a 4-byte string which identifies the type of chunk.
+
+The size field (a 32-bit value, encoded using big-endian byte order)
+gives the size of the whole chunk, including the 8-byte header.
+
+Usually an IFF-type file consists of one or more chunks.  The proposed
+usage of the Chunk class defined here is to instantiate an instance at
+the start of each chunk and read from the instance until it reaches
+the end, after which a new instance can be instantiated.  At the end
+of the file, creating a new instance will fail with a EOFError
+exception.
+
+Usage:
+while True:
+    try:
+        chunk = Chunk(file)
+    except EOFError:
+        break
+    chunktype = chunk.getname()
+    while True:
+        data = chunk.read(nbytes)
+        if not data:
+            pass
+        # do something with data
+
+The interface is file-like.  The implemented methods are:
+read, close, seek, tell, isatty.
+Extra methods are: skip() (called by close, skips to the end of the chunk),
+getname() (returns the name (ID) of the chunk)
+
+The __init__ method has one required argument, a file-like object
+(including a chunk instance), and one optional argument, a flag which
+specifies whether or not chunks are aligned on 2-byte boundaries.  The
+default is 1, i.e. aligned.
+"""
+
+class Chunk:
+    def __init__(self, file, align=True, bigendian=True, inclheader=False):
+        import struct
+        self.closed = False
+        self.align = align      # whether to align to word (2-byte) boundaries
+        if bigendian:
+            strflag = '>'
+        else:
+            strflag = '<'
+        self.file = file
+        self.chunkname = file.read(4)
+        if len(self.chunkname) < 4:
+            raise EOFError
+        try:
+            self.chunksize = struct.unpack(strflag+'L', file.read(4))[0]
+        except struct.error:
+            raise EOFError
+        if inclheader:
+            self.chunksize = self.chunksize - 8 # subtract header
+        self.size_read = 0
+        try:
+            self.offset = self.file.tell()
+        except (AttributeError, IOError):
+            self.seekable = False
+        else:
+            self.seekable = True
+
+    def getname(self):
+        """Return the name (ID) of the current chunk."""
+        return self.chunkname
+
+    def getsize(self):
+        """Return the size of the current chunk."""
+        return self.chunksize
+
+    def close(self):
+        if not self.closed:
+            self.skip()
+            self.closed = True
+
+    def isatty(self):
+        if self.closed:
+            raise ValueError, "I/O operation on closed file"
+        return False
+
+    def seek(self, pos, whence=0):
+        """Seek to specified position into the chunk.
+        Default position is 0 (start of chunk).
+        If the file is not seekable, this will result in an error.
+        """
+
+        if self.closed:
+            raise ValueError, "I/O operation on closed file"
+        if not self.seekable:
+            raise IOError, "cannot seek"
+        if whence == 1:
+            pos = pos + self.size_read
+        elif whence == 2:
+            pos = pos + self.chunksize
+        if pos < 0 or pos > self.chunksize:
+            raise RuntimeError
+        self.file.seek(self.offset + pos, 0)
+        self.size_read = pos
+
+    def tell(self):
+        if self.closed:
+            raise ValueError, "I/O operation on closed file"
+        return self.size_read
+
+    def read(self, size=-1):
+        """Read at most size bytes from the chunk.
+        If size is omitted or negative, read until the end
+        of the chunk.
+        """
+
+        if self.closed:
+            raise ValueError, "I/O operation on closed file"
+        if self.size_read >= self.chunksize:
+            return ''
+        if size < 0:
+            size = self.chunksize - self.size_read
+        if size > self.chunksize - self.size_read:
+            size = self.chunksize - self.size_read
+        data = self.file.read(size)
+        self.size_read = self.size_read + len(data)
+        if self.size_read == self.chunksize and \
+           self.align and \
+           (self.chunksize & 1):
+            dummy = self.file.read(1)
+            self.size_read = self.size_read + len(dummy)
+        return data
+
+    def skip(self):
+        """Skip the rest of the chunk.
+        If you are not interested in the contents of the chunk,
+        this method should be called so that the file points to
+        the start of the next chunk.
+        """
+
+        if self.closed:
+            raise ValueError, "I/O operation on closed file"
+        if self.seekable:
+            try:
+                n = self.chunksize - self.size_read
+                # maybe fix alignment
+                if self.align and (self.chunksize & 1):
+                    n = n + 1
+                self.file.seek(n, 1)
+                self.size_read = self.size_read + n
+                return
+            except IOError:
+                pass
+        while self.size_read < self.chunksize:
+            n = min(8192, self.chunksize - self.size_read)
+            dummy = self.read(n)
+            if not dummy:
+                raise EOFError

Added: vendor/Python/current/Lib/cmd.py
===================================================================
--- vendor/Python/current/Lib/cmd.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/cmd.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,405 @@
+"""A generic class to build line-oriented command interpreters.
+
+Interpreters constructed with this class obey the following conventions:
+
+1. End of file on input is processed as the command 'EOF'.
+2. A command is parsed out of each line by collecting the prefix composed
+   of characters in the identchars member.
+3. A command `foo' is dispatched to a method 'do_foo()'; the do_ method
+   is passed a single argument consisting of the remainder of the line.
+4. Typing an empty line repeats the last command.  (Actually, it calls the
+   method `emptyline', which may be overridden in a subclass.)
+5. There is a predefined `help' method.  Given an argument `topic', it
+   calls the command `help_topic'.  With no arguments, it lists all topics
+   with defined help_ functions, broken into up to three topics; documented
+   commands, miscellaneous help topics, and undocumented commands.
+6. The command '?' is a synonym for `help'.  The command '!' is a synonym
+   for `shell', if a do_shell method exists.
+7. If completion is enabled, completing commands will be done automatically,
+   and completing of commands args is done by calling complete_foo() with
+   arguments text, line, begidx, endidx.  text is string we are matching
+   against, all returned matches must begin with it.  line is the current
+   input line (lstripped), begidx and endidx are the beginning and end
+   indexes of the text being matched, which could be used to provide
+   different completion depending upon which position the argument is in.
+
+The `default' method may be overridden to intercept commands for which there
+is no do_ method.
+
+The `completedefault' method may be overridden to intercept completions for
+commands that have no complete_ method.
+
+The data member `self.ruler' sets the character used to draw separator lines
+in the help messages.  If empty, no ruler line is drawn.  It defaults to "=".
+
+If the value of `self.intro' is nonempty when the cmdloop method is called,
+it is printed out on interpreter startup.  This value may be overridden
+via an optional argument to the cmdloop() method.
+
+The data members `self.doc_header', `self.misc_header', and
+`self.undoc_header' set the headers used for the help function's
+listings of documented functions, miscellaneous topics, and undocumented
+functions respectively.
+
+These interpreters use raw_input; thus, if the readline module is loaded,
+they automatically support Emacs-like command history and editing features.
+"""
+
+import string
+
+__all__ = ["Cmd"]
+
+PROMPT = '(Cmd) '
+IDENTCHARS = string.ascii_letters + string.digits + '_'
+
+class Cmd:
+    """A simple framework for writing line-oriented command interpreters.
+
+    These are often useful for test harnesses, administrative tools, and
+    prototypes that will later be wrapped in a more sophisticated interface.
+
+    A Cmd instance or subclass instance is a line-oriented interpreter
+    framework.  There is no good reason to instantiate Cmd itself; rather,
+    it's useful as a superclass of an interpreter class you define yourself
+    in order to inherit Cmd's methods and encapsulate action methods.
+
+    """
+    prompt = PROMPT
+    identchars = IDENTCHARS
+    ruler = '='
+    lastcmd = ''
+    intro = None
+    doc_leader = ""
+    doc_header = "Documented commands (type help <topic>):"
+    misc_header = "Miscellaneous help topics:"
+    undoc_header = "Undocumented commands:"
+    nohelp = "*** No help on %s"
+    use_rawinput = 1
+
+    def __init__(self, completekey='tab', stdin=None, stdout=None):
+        """Instantiate a line-oriented interpreter framework.
+
+        The optional argument 'completekey' is the readline name of a
+        completion key; it defaults to the Tab key. If completekey is
+        not None and the readline module is available, command completion
+        is done automatically. The optional arguments stdin and stdout
+        specify alternate input and output file objects; if not specified,
+        sys.stdin and sys.stdout are used.
+
+        """
+        import sys
+        if stdin is not None:
+            self.stdin = stdin
+        else:
+            self.stdin = sys.stdin
+        if stdout is not None:
+            self.stdout = stdout
+        else:
+            self.stdout = sys.stdout
+        self.cmdqueue = []
+        self.completekey = completekey
+
+    def cmdloop(self, intro=None):
+        """Repeatedly issue a prompt, accept input, parse an initial prefix
+        off the received input, and dispatch to action methods, passing them
+        the remainder of the line as argument.
+
+        """
+
+        self.preloop()
+        if self.use_rawinput and self.completekey:
+            try:
+                import readline
+                self.old_completer = readline.get_completer()
+                readline.set_completer(self.complete)
+                readline.parse_and_bind(self.completekey+": complete")
+            except ImportError:
+                pass
+        try:
+            if intro is not None:
+                self.intro = intro
+            if self.intro:
+                self.stdout.write(str(self.intro)+"\n")
+            stop = None
+            while not stop:
+                if self.cmdqueue:
+                    line = self.cmdqueue.pop(0)
+                else:
+                    if self.use_rawinput:
+                        try:
+                            line = raw_input(self.prompt)
+                        except EOFError:
+                            line = 'EOF'
+                    else:
+                        self.stdout.write(self.prompt)
+                        self.stdout.flush()
+                        line = self.stdin.readline()
+                        if not len(line):
+                            line = 'EOF'
+                        else:
+                            line = line[:-1] # chop \n
+                line = self.precmd(line)
+                stop = self.onecmd(line)
+                stop = self.postcmd(stop, line)
+            self.postloop()
+        finally:
+            if self.use_rawinput and self.completekey:
+                try:
+                    import readline
+                    readline.set_completer(self.old_completer)
+                except ImportError:
+                    pass
+
+
+    def precmd(self, line):
+        """Hook method executed just before the command line is
+        interpreted, but after the input prompt is generated and issued.
+
+        """
+        return line
+
+    def postcmd(self, stop, line):
+        """Hook method executed just after a command dispatch is finished."""
+        return stop
+
+    def preloop(self):
+        """Hook method executed once when the cmdloop() method is called."""
+        pass
+
+    def postloop(self):
+        """Hook method executed once when the cmdloop() method is about to
+        return.
+
+        """
+        pass
+
+    def parseline(self, line):
+        """Parse the line into a command name and a string containing
+        the arguments.  Returns a tuple containing (command, args, line).
+        'command' and 'args' may be None if the line couldn't be parsed.
+        """
+        line = line.strip()
+        if not line:
+            return None, None, line
+        elif line[0] == '?':
+            line = 'help ' + line[1:]
+        elif line[0] == '!':
+            if hasattr(self, 'do_shell'):
+                line = 'shell ' + line[1:]
+            else:
+                return None, None, line
+        i, n = 0, len(line)
+        while i < n and line[i] in self.identchars: i = i+1
+        cmd, arg = line[:i], line[i:].strip()
+        return cmd, arg, line
+
+    def onecmd(self, line):
+        """Interpret the argument as though it had been typed in response
+        to the prompt.
+
+        This may be overridden, but should not normally need to be;
+        see the precmd() and postcmd() methods for useful execution hooks.
+        The return value is a flag indicating whether interpretation of
+        commands by the interpreter should stop.
+
+        """
+        cmd, arg, line = self.parseline(line)
+        if not line:
+            return self.emptyline()
+        if cmd is None:
+            return self.default(line)
+        self.lastcmd = line
+        if cmd == '':
+            return self.default(line)
+        else:
+            try:
+                func = getattr(self, 'do_' + cmd)
+            except AttributeError:
+                return self.default(line)
+            return func(arg)
+
+    def emptyline(self):
+        """Called when an empty line is entered in response to the prompt.
+
+        If this method is not overridden, it repeats the last nonempty
+        command entered.
+
+        """
+        if self.lastcmd:
+            return self.onecmd(self.lastcmd)
+
+    def default(self, line):
+        """Called on an input line when the command prefix is not recognized.
+
+        If this method is not overridden, it prints an error message and
+        returns.
+
+        """
+        self.stdout.write('*** Unknown syntax: %s\n'%line)
+
+    def completedefault(self, *ignored):
+        """Method called to complete an input line when no command-specific
+        complete_*() method is available.
+
+        By default, it returns an empty list.
+
+        """
+        return []
+
+    def completenames(self, text, *ignored):
+        dotext = 'do_'+text
+        return [a[3:] for a in self.get_names() if a.startswith(dotext)]
+
+    def complete(self, text, state):
+        """Return the next possible completion for 'text'.
+
+        If a command has not been entered, then complete against command list.
+        Otherwise try to call complete_<command> to get list of completions.
+        """
+        if state == 0:
+            import readline
+            origline = readline.get_line_buffer()
+            line = origline.lstrip()
+            stripped = len(origline) - len(line)
+            begidx = readline.get_begidx() - stripped
+            endidx = readline.get_endidx() - stripped
+            if begidx>0:
+                cmd, args, foo = self.parseline(line)
+                if cmd == '':
+                    compfunc = self.completedefault
+                else:
+                    try:
+                        compfunc = getattr(self, 'complete_' + cmd)
+                    except AttributeError:
+                        compfunc = self.completedefault
+            else:
+                compfunc = self.completenames
+            self.completion_matches = compfunc(text, line, begidx, endidx)
+        try:
+            return self.completion_matches[state]
+        except IndexError:
+            return None
+
+    def get_names(self):
+        # Inheritance says we have to look in class and
+        # base classes; order is not important.
+        names = []
+        classes = [self.__class__]
+        while classes:
+            aclass = classes.pop(0)
+            if aclass.__bases__:
+                classes = classes + list(aclass.__bases__)
+            names = names + dir(aclass)
+        return names
+
+    def complete_help(self, *args):
+        return self.completenames(*args)
+
+    def do_help(self, arg):
+        if arg:
+            # XXX check arg syntax
+            try:
+                func = getattr(self, 'help_' + arg)
+            except AttributeError:
+                try:
+                    doc=getattr(self, 'do_' + arg).__doc__
+                    if doc:
+                        self.stdout.write("%s\n"%str(doc))
+                        return
+                except AttributeError:
+                    pass
+                self.stdout.write("%s\n"%str(self.nohelp % (arg,)))
+                return
+            func()
+        else:
+            names = self.get_names()
+            cmds_doc = []
+            cmds_undoc = []
+            help = {}
+            for name in names:
+                if name[:5] == 'help_':
+                    help[name[5:]]=1
+            names.sort()
+            # There can be duplicates if routines overridden
+            prevname = ''
+            for name in names:
+                if name[:3] == 'do_':
+                    if name == prevname:
+                        continue
+                    prevname = name
+                    cmd=name[3:]
+                    if cmd in help:
+                        cmds_doc.append(cmd)
+                        del help[cmd]
+                    elif getattr(self, name).__doc__:
+                        cmds_doc.append(cmd)
+                    else:
+                        cmds_undoc.append(cmd)
+            self.stdout.write("%s\n"%str(self.doc_leader))
+            self.print_topics(self.doc_header,   cmds_doc,   15,80)
+            self.print_topics(self.misc_header,  help.keys(),15,80)
+            self.print_topics(self.undoc_header, cmds_undoc, 15,80)
+
+    def print_topics(self, header, cmds, cmdlen, maxcol):
+        if cmds:
+            self.stdout.write("%s\n"%str(header))
+            if self.ruler:
+                self.stdout.write("%s\n"%str(self.ruler * len(header)))
+            self.columnize(cmds, maxcol-1)
+            self.stdout.write("\n")
+
+    def columnize(self, list, displaywidth=80):
+        """Display a list of strings as a compact set of columns.
+
+        Each column is only as wide as necessary.
+        Columns are separated by two spaces (one was not legible enough).
+        """
+        if not list:
+            self.stdout.write("<empty>\n")
+            return
+        nonstrings = [i for i in range(len(list))
+                        if not isinstance(list[i], str)]
+        if nonstrings:
+            raise TypeError, ("list[i] not a string for i in %s" %
+                              ", ".join(map(str, nonstrings)))
+        size = len(list)
+        if size == 1:
+            self.stdout.write('%s\n'%str(list[0]))
+            return
+        # Try every row count from 1 upwards
+        for nrows in range(1, len(list)):
+            ncols = (size+nrows-1) // nrows
+            colwidths = []
+            totwidth = -2
+            for col in range(ncols):
+                colwidth = 0
+                for row in range(nrows):
+                    i = row + nrows*col
+                    if i >= size:
+                        break
+                    x = list[i]
+                    colwidth = max(colwidth, len(x))
+                colwidths.append(colwidth)
+                totwidth += colwidth + 2
+                if totwidth > displaywidth:
+                    break
+            if totwidth <= displaywidth:
+                break
+        else:
+            nrows = len(list)
+            ncols = 1
+            colwidths = [0]
+        for row in range(nrows):
+            texts = []
+            for col in range(ncols):
+                i = row + nrows*col
+                if i >= size:
+                    x = ""
+                else:
+                    x = list[i]
+                texts.append(x)
+            while texts and not texts[-1]:
+                del texts[-1]
+            for col in range(len(texts)):
+                texts[col] = texts[col].ljust(colwidths[col])
+            self.stdout.write("%s\n"%str("  ".join(texts)))

Added: vendor/Python/current/Lib/code.py
===================================================================
--- vendor/Python/current/Lib/code.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/code.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,307 @@
+"""Utilities needed to emulate Python's interactive interpreter.
+
+"""
+
+# Inspired by similar code by Jeff Epler and Fredrik Lundh.
+
+
+import sys
+import traceback
+from codeop import CommandCompiler, compile_command
+
+__all__ = ["InteractiveInterpreter", "InteractiveConsole", "interact",
+           "compile_command"]
+
+def softspace(file, newvalue):
+    oldvalue = 0
+    try:
+        oldvalue = file.softspace
+    except AttributeError:
+        pass
+    try:
+        file.softspace = newvalue
+    except (AttributeError, TypeError):
+        # "attribute-less object" or "read-only attributes"
+        pass
+    return oldvalue
+
+class InteractiveInterpreter:
+    """Base class for InteractiveConsole.
+
+    This class deals with parsing and interpreter state (the user's
+    namespace); it doesn't deal with input buffering or prompting or
+    input file naming (the filename is always passed in explicitly).
+
+    """
+
+    def __init__(self, locals=None):
+        """Constructor.
+
+        The optional 'locals' argument specifies the dictionary in
+        which code will be executed; it defaults to a newly created
+        dictionary with key "__name__" set to "__console__" and key
+        "__doc__" set to None.
+
+        """
+        if locals is None:
+            locals = {"__name__": "__console__", "__doc__": None}
+        self.locals = locals
+        self.compile = CommandCompiler()
+
+    def runsource(self, source, filename="<input>", symbol="single"):
+        """Compile and run some source in the interpreter.
+
+        Arguments are as for compile_command().
+
+        One several things can happen:
+
+        1) The input is incorrect; compile_command() raised an
+        exception (SyntaxError or OverflowError).  A syntax traceback
+        will be printed by calling the showsyntaxerror() method.
+
+        2) The input is incomplete, and more input is required;
+        compile_command() returned None.  Nothing happens.
+
+        3) The input is complete; compile_command() returned a code
+        object.  The code is executed by calling self.runcode() (which
+        also handles run-time exceptions, except for SystemExit).
+
+        The return value is True in case 2, False in the other cases (unless
+        an exception is raised).  The return value can be used to
+        decide whether to use sys.ps1 or sys.ps2 to prompt the next
+        line.
+
+        """
+        try:
+            code = self.compile(source, filename, symbol)
+        except (OverflowError, SyntaxError, ValueError):
+            # Case 1
+            self.showsyntaxerror(filename)
+            return False
+
+        if code is None:
+            # Case 2
+            return True
+
+        # Case 3
+        self.runcode(code)
+        return False
+
+    def runcode(self, code):
+        """Execute a code object.
+
+        When an exception occurs, self.showtraceback() is called to
+        display a traceback.  All exceptions are caught except
+        SystemExit, which is reraised.
+
+        A note about KeyboardInterrupt: this exception may occur
+        elsewhere in this code, and may not always be caught.  The
+        caller should be prepared to deal with it.
+
+        """
+        try:
+            exec code in self.locals
+        except SystemExit:
+            raise
+        except:
+            self.showtraceback()
+        else:
+            if softspace(sys.stdout, 0):
+                print
+
+    def showsyntaxerror(self, filename=None):
+        """Display the syntax error that just occurred.
+
+        This doesn't display a stack trace because there isn't one.
+
+        If a filename is given, it is stuffed in the exception instead
+        of what was there before (because Python's parser always uses
+        "<string>" when reading from a string).
+
+        The output is written by self.write(), below.
+
+        """
+        type, value, sys.last_traceback = sys.exc_info()
+        sys.last_type = type
+        sys.last_value = value
+        if filename and type is SyntaxError:
+            # Work hard to stuff the correct filename in the exception
+            try:
+                msg, (dummy_filename, lineno, offset, line) = value
+            except:
+                # Not the format we expect; leave it alone
+                pass
+            else:
+                # Stuff in the right filename
+                value = SyntaxError(msg, (filename, lineno, offset, line))
+                sys.last_value = value
+        list = traceback.format_exception_only(type, value)
+        map(self.write, list)
+
+    def showtraceback(self):
+        """Display the exception that just occurred.
+
+        We remove the first stack item because it is our own code.
+
+        The output is written by self.write(), below.
+
+        """
+        try:
+            type, value, tb = sys.exc_info()
+            sys.last_type = type
+            sys.last_value = value
+            sys.last_traceback = tb
+            tblist = traceback.extract_tb(tb)
+            del tblist[:1]
+            list = traceback.format_list(tblist)
+            if list:
+                list.insert(0, "Traceback (most recent call last):\n")
+            list[len(list):] = traceback.format_exception_only(type, value)
+        finally:
+            tblist = tb = None
+        map(self.write, list)
+
+    def write(self, data):
+        """Write a string.
+
+        The base implementation writes to sys.stderr; a subclass may
+        replace this with a different implementation.
+
+        """
+        sys.stderr.write(data)
+
+
+class InteractiveConsole(InteractiveInterpreter):
+    """Closely emulate the behavior of the interactive Python interpreter.
+
+    This class builds on InteractiveInterpreter and adds prompting
+    using the familiar sys.ps1 and sys.ps2, and input buffering.
+
+    """
+
+    def __init__(self, locals=None, filename="<console>"):
+        """Constructor.
+
+        The optional locals argument will be passed to the
+        InteractiveInterpreter base class.
+
+        The optional filename argument should specify the (file)name
+        of the input stream; it will show up in tracebacks.
+
+        """
+        InteractiveInterpreter.__init__(self, locals)
+        self.filename = filename
+        self.resetbuffer()
+
+    def resetbuffer(self):
+        """Reset the input buffer."""
+        self.buffer = []
+
+    def interact(self, banner=None):
+        """Closely emulate the interactive Python console.
+
+        The optional banner argument specify the banner to print
+        before the first interaction; by default it prints a banner
+        similar to the one printed by the real Python interpreter,
+        followed by the current class name in parentheses (so as not
+        to confuse this with the real interpreter -- since it's so
+        close!).
+
+        """
+        try:
+            sys.ps1
+        except AttributeError:
+            sys.ps1 = ">>> "
+        try:
+            sys.ps2
+        except AttributeError:
+            sys.ps2 = "... "
+        cprt = 'Type "help", "copyright", "credits" or "license" for more information.'
+        if banner is None:
+            self.write("Python %s on %s\n%s\n(%s)\n" %
+                       (sys.version, sys.platform, cprt,
+                        self.__class__.__name__))
+        else:
+            self.write("%s\n" % str(banner))
+        more = 0
+        while 1:
+            try:
+                if more:
+                    prompt = sys.ps2
+                else:
+                    prompt = sys.ps1
+                try:
+                    line = self.raw_input(prompt)
+                except EOFError:
+                    self.write("\n")
+                    break
+                else:
+                    more = self.push(line)
+            except KeyboardInterrupt:
+                self.write("\nKeyboardInterrupt\n")
+                self.resetbuffer()
+                more = 0
+
+    def push(self, line):
+        """Push a line to the interpreter.
+
+        The line should not have a trailing newline; it may have
+        internal newlines.  The line is appended to a buffer and the
+        interpreter's runsource() method is called with the
+        concatenated contents of the buffer as source.  If this
+        indicates that the command was executed or invalid, the buffer
+        is reset; otherwise, the command is incomplete, and the buffer
+        is left as it was after the line was appended.  The return
+        value is 1 if more input is required, 0 if the line was dealt
+        with in some way (this is the same as runsource()).
+
+        """
+        self.buffer.append(line)
+        source = "\n".join(self.buffer)
+        more = self.runsource(source, self.filename)
+        if not more:
+            self.resetbuffer()
+        return more
+
+    def raw_input(self, prompt=""):
+        """Write a prompt and read a line.
+
+        The returned line does not include the trailing newline.
+        When the user enters the EOF key sequence, EOFError is raised.
+
+        The base implementation uses the built-in function
+        raw_input(); a subclass may replace this with a different
+        implementation.
+
+        """
+        return raw_input(prompt)
+
+
+def interact(banner=None, readfunc=None, local=None):
+    """Closely emulate the interactive Python interpreter.
+
+    This is a backwards compatible interface to the InteractiveConsole
+    class.  When readfunc is not specified, it attempts to import the
+    readline module to enable GNU readline if it is available.
+
+    Arguments (all optional, all default to None):
+
+    banner -- passed to InteractiveConsole.interact()
+    readfunc -- if not None, replaces InteractiveConsole.raw_input()
+    local -- passed to InteractiveInterpreter.__init__()
+
+    """
+    console = InteractiveConsole(local)
+    if readfunc is not None:
+        console.raw_input = readfunc
+    else:
+        try:
+            import readline
+        except ImportError:
+            pass
+    console.interact(banner)
+
+
+if __name__ == '__main__':
+    import pdb
+    pdb.run("interact()\n")

Added: vendor/Python/current/Lib/codecs.py
===================================================================
--- vendor/Python/current/Lib/codecs.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/codecs.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1034 @@
+""" codecs -- Python Codec Registry, API and helpers.
+
+
+Written by Marc-Andre Lemburg (mal at lemburg.com).
+
+(c) Copyright CNRI, All Rights Reserved. NO WARRANTY.
+
+"""#"
+
+import __builtin__, sys
+
+### Registry and builtin stateless codec functions
+
+try:
+    from _codecs import *
+except ImportError, why:
+    raise SystemError('Failed to load the builtin codecs: %s' % why)
+
+__all__ = ["register", "lookup", "open", "EncodedFile", "BOM", "BOM_BE",
+           "BOM_LE", "BOM32_BE", "BOM32_LE", "BOM64_BE", "BOM64_LE",
+           "BOM_UTF8", "BOM_UTF16", "BOM_UTF16_LE", "BOM_UTF16_BE",
+           "BOM_UTF32", "BOM_UTF32_LE", "BOM_UTF32_BE",
+           "strict_errors", "ignore_errors", "replace_errors",
+           "xmlcharrefreplace_errors",
+           "register_error", "lookup_error"]
+
+### Constants
+
+#
+# Byte Order Mark (BOM = ZERO WIDTH NO-BREAK SPACE = U+FEFF)
+# and its possible byte string values
+# for UTF8/UTF16/UTF32 output and little/big endian machines
+#
+
+# UTF-8
+BOM_UTF8 = '\xef\xbb\xbf'
+
+# UTF-16, little endian
+BOM_LE = BOM_UTF16_LE = '\xff\xfe'
+
+# UTF-16, big endian
+BOM_BE = BOM_UTF16_BE = '\xfe\xff'
+
+# UTF-32, little endian
+BOM_UTF32_LE = '\xff\xfe\x00\x00'
+
+# UTF-32, big endian
+BOM_UTF32_BE = '\x00\x00\xfe\xff'
+
+if sys.byteorder == 'little':
+
+    # UTF-16, native endianness
+    BOM = BOM_UTF16 = BOM_UTF16_LE
+
+    # UTF-32, native endianness
+    BOM_UTF32 = BOM_UTF32_LE
+
+else:
+
+    # UTF-16, native endianness
+    BOM = BOM_UTF16 = BOM_UTF16_BE
+
+    # UTF-32, native endianness
+    BOM_UTF32 = BOM_UTF32_BE
+
+# Old broken names (don't use in new code)
+BOM32_LE = BOM_UTF16_LE
+BOM32_BE = BOM_UTF16_BE
+BOM64_LE = BOM_UTF32_LE
+BOM64_BE = BOM_UTF32_BE
+
+
+### Codec base classes (defining the API)
+
+class CodecInfo(tuple):
+
+    def __new__(cls, encode, decode, streamreader=None, streamwriter=None,
+        incrementalencoder=None, incrementaldecoder=None, name=None):
+        self = tuple.__new__(cls, (encode, decode, streamreader, streamwriter))
+        self.name = name
+        self.encode = encode
+        self.decode = decode
+        self.incrementalencoder = incrementalencoder
+        self.incrementaldecoder = incrementaldecoder
+        self.streamwriter = streamwriter
+        self.streamreader = streamreader
+        return self
+
+    def __repr__(self):
+        return "<%s.%s object for encoding %s at 0x%x>" % (self.__class__.__module__, self.__class__.__name__, self.name, id(self))
+
+class Codec:
+
+    """ Defines the interface for stateless encoders/decoders.
+
+        The .encode()/.decode() methods may use different error
+        handling schemes by providing the errors argument. These
+        string values are predefined:
+
+         'strict' - raise a ValueError error (or a subclass)
+         'ignore' - ignore the character and continue with the next
+         'replace' - replace with a suitable replacement character;
+                    Python will use the official U+FFFD REPLACEMENT
+                    CHARACTER for the builtin Unicode codecs on
+                    decoding and '?' on encoding.
+         'xmlcharrefreplace' - Replace with the appropriate XML
+                               character reference (only for encoding).
+         'backslashreplace'  - Replace with backslashed escape sequences
+                               (only for encoding).
+
+        The set of allowed values can be extended via register_error.
+
+    """
+    def encode(self, input, errors='strict'):
+
+        """ Encodes the object input and returns a tuple (output
+            object, length consumed).
+
+            errors defines the error handling to apply. It defaults to
+            'strict' handling.
+
+            The method may not store state in the Codec instance. Use
+            StreamCodec for codecs which have to keep state in order to
+            make encoding/decoding efficient.
+
+            The encoder must be able to handle zero length input and
+            return an empty object of the output object type in this
+            situation.
+
+        """
+        raise NotImplementedError
+
+    def decode(self, input, errors='strict'):
+
+        """ Decodes the object input and returns a tuple (output
+            object, length consumed).
+
+            input must be an object which provides the bf_getreadbuf
+            buffer slot. Python strings, buffer objects and memory
+            mapped files are examples of objects providing this slot.
+
+            errors defines the error handling to apply. It defaults to
+            'strict' handling.
+
+            The method may not store state in the Codec instance. Use
+            StreamCodec for codecs which have to keep state in order to
+            make encoding/decoding efficient.
+
+            The decoder must be able to handle zero length input and
+            return an empty object of the output object type in this
+            situation.
+
+        """
+        raise NotImplementedError
+
+class IncrementalEncoder(object):
+    """
+    An IncrementalEncoder encodes an input in multiple steps. The input can be
+    passed piece by piece to the encode() method. The IncrementalEncoder remembers
+    the state of the Encoding process between calls to encode().
+    """
+    def __init__(self, errors='strict'):
+        """
+        Creates an IncrementalEncoder instance.
+
+        The IncrementalEncoder may use different error handling schemes by
+        providing the errors keyword argument. See the module docstring
+        for a list of possible values.
+        """
+        self.errors = errors
+        self.buffer = ""
+
+    def encode(self, input, final=False):
+        """
+        Encodes input and returns the resulting object.
+        """
+        raise NotImplementedError
+
+    def reset(self):
+        """
+        Resets the encoder to the initial state.
+        """
+
+class BufferedIncrementalEncoder(IncrementalEncoder):
+    """
+    This subclass of IncrementalEncoder can be used as the baseclass for an
+    incremental encoder if the encoder must keep some of the output in a
+    buffer between calls to encode().
+    """
+    def __init__(self, errors='strict'):
+        IncrementalEncoder.__init__(self, errors)
+        self.buffer = "" # unencoded input that is kept between calls to encode()
+
+    def _buffer_encode(self, input, errors, final):
+        # Overwrite this method in subclasses: It must encode input
+        # and return an (output, length consumed) tuple
+        raise NotImplementedError
+
+    def encode(self, input, final=False):
+        # encode input (taking the buffer into account)
+        data = self.buffer + input
+        (result, consumed) = self._buffer_encode(data, self.errors, final)
+        # keep unencoded input until the next call
+        self.buffer = data[consumed:]
+        return result
+
+    def reset(self):
+        IncrementalEncoder.reset(self)
+        self.buffer = ""
+
+class IncrementalDecoder(object):
+    """
+    An IncrementalDecoder decodes an input in multiple steps. The input can be
+    passed piece by piece to the decode() method. The IncrementalDecoder
+    remembers the state of the decoding process between calls to decode().
+    """
+    def __init__(self, errors='strict'):
+        """
+        Creates a IncrementalDecoder instance.
+
+        The IncrementalDecoder may use different error handling schemes by
+        providing the errors keyword argument. See the module docstring
+        for a list of possible values.
+        """
+        self.errors = errors
+
+    def decode(self, input, final=False):
+        """
+        Decodes input and returns the resulting object.
+        """
+        raise NotImplementedError
+
+    def reset(self):
+        """
+        Resets the decoder to the initial state.
+        """
+
+class BufferedIncrementalDecoder(IncrementalDecoder):
+    """
+    This subclass of IncrementalDecoder can be used as the baseclass for an
+    incremental decoder if the decoder must be able to handle incomplete byte
+    sequences.
+    """
+    def __init__(self, errors='strict'):
+        IncrementalDecoder.__init__(self, errors)
+        self.buffer = "" # undecoded input that is kept between calls to decode()
+
+    def _buffer_decode(self, input, errors, final):
+        # Overwrite this method in subclasses: It must decode input
+        # and return an (output, length consumed) tuple
+        raise NotImplementedError
+
+    def decode(self, input, final=False):
+        # decode input (taking the buffer into account)
+        data = self.buffer + input
+        (result, consumed) = self._buffer_decode(data, self.errors, final)
+        # keep undecoded input until the next call
+        self.buffer = data[consumed:]
+        return result
+
+    def reset(self):
+        IncrementalDecoder.reset(self)
+        self.buffer = ""
+
+#
+# The StreamWriter and StreamReader class provide generic working
+# interfaces which can be used to implement new encoding submodules
+# very easily. See encodings/utf_8.py for an example on how this is
+# done.
+#
+
+class StreamWriter(Codec):
+
+    def __init__(self, stream, errors='strict'):
+
+        """ Creates a StreamWriter instance.
+
+            stream must be a file-like object open for writing
+            (binary) data.
+
+            The StreamWriter may use different error handling
+            schemes by providing the errors keyword argument. These
+            parameters are predefined:
+
+             'strict' - raise a ValueError (or a subclass)
+             'ignore' - ignore the character and continue with the next
+             'replace'- replace with a suitable replacement character
+             'xmlcharrefreplace' - Replace with the appropriate XML
+                                   character reference.
+             'backslashreplace'  - Replace with backslashed escape
+                                   sequences (only for encoding).
+
+            The set of allowed parameter values can be extended via
+            register_error.
+        """
+        self.stream = stream
+        self.errors = errors
+
+    def write(self, object):
+
+        """ Writes the object's contents encoded to self.stream.
+        """
+        data, consumed = self.encode(object, self.errors)
+        self.stream.write(data)
+
+    def writelines(self, list):
+
+        """ Writes the concatenated list of strings to the stream
+            using .write().
+        """
+        self.write(''.join(list))
+
+    def reset(self):
+
+        """ Flushes and resets the codec buffers used for keeping state.
+
+            Calling this method should ensure that the data on the
+            output is put into a clean state, that allows appending
+            of new fresh data without having to rescan the whole
+            stream to recover state.
+
+        """
+        pass
+
+    def __getattr__(self, name,
+                    getattr=getattr):
+
+        """ Inherit all other methods from the underlying stream.
+        """
+        return getattr(self.stream, name)
+
+    def __enter__(self):
+        return self
+
+    def __exit__(self, type, value, tb):
+        self.stream.close()
+
+###
+
+class StreamReader(Codec):
+
+    def __init__(self, stream, errors='strict'):
+
+        """ Creates a StreamReader instance.
+
+            stream must be a file-like object open for reading
+            (binary) data.
+
+            The StreamReader may use different error handling
+            schemes by providing the errors keyword argument. These
+            parameters are predefined:
+
+             'strict' - raise a ValueError (or a subclass)
+             'ignore' - ignore the character and continue with the next
+             'replace'- replace with a suitable replacement character;
+
+            The set of allowed parameter values can be extended via
+            register_error.
+        """
+        self.stream = stream
+        self.errors = errors
+        self.bytebuffer = ""
+        # For str->str decoding this will stay a str
+        # For str->unicode decoding the first read will promote it to unicode
+        self.charbuffer = ""
+        self.linebuffer = None
+
+    def decode(self, input, errors='strict'):
+        raise NotImplementedError
+
+    def read(self, size=-1, chars=-1, firstline=False):
+
+        """ Decodes data from the stream self.stream and returns the
+            resulting object.
+
+            chars indicates the number of characters to read from the
+            stream. read() will never return more than chars
+            characters, but it might return less, if there are not enough
+            characters available.
+
+            size indicates the approximate maximum number of bytes to
+            read from the stream for decoding purposes. The decoder
+            can modify this setting as appropriate. The default value
+            -1 indicates to read and decode as much as possible.  size
+            is intended to prevent having to decode huge files in one
+            step.
+
+            If firstline is true, and a UnicodeDecodeError happens
+            after the first line terminator in the input only the first line
+            will be returned, the rest of the input will be kept until the
+            next call to read().
+
+            The method should use a greedy read strategy meaning that
+            it should read as much data as is allowed within the
+            definition of the encoding and the given size, e.g.  if
+            optional encoding endings or state markers are available
+            on the stream, these should be read too.
+        """
+        # If we have lines cached, first merge them back into characters
+        if self.linebuffer:
+            self.charbuffer = "".join(self.linebuffer)
+            self.linebuffer = None
+
+        # read until we get the required number of characters (if available)
+        while True:
+            # can the request can be satisfied from the character buffer?
+            if chars < 0:
+                if size < 0:
+                    if self.charbuffer:
+                        break
+                elif len(self.charbuffer) >= size:
+                    break
+            else:
+                if len(self.charbuffer) >= chars:
+                    break
+            # we need more data
+            if size < 0:
+                newdata = self.stream.read()
+            else:
+                newdata = self.stream.read(size)
+            # decode bytes (those remaining from the last call included)
+            data = self.bytebuffer + newdata
+            try:
+                newchars, decodedbytes = self.decode(data, self.errors)
+            except UnicodeDecodeError, exc:
+                if firstline:
+                    newchars, decodedbytes = self.decode(data[:exc.start], self.errors)
+                    lines = newchars.splitlines(True)
+                    if len(lines)<=1:
+                        raise
+                else:
+                    raise
+            # keep undecoded bytes until the next call
+            self.bytebuffer = data[decodedbytes:]
+            # put new characters in the character buffer
+            self.charbuffer += newchars
+            # there was no data available
+            if not newdata:
+                break
+        if chars < 0:
+            # Return everything we've got
+            result = self.charbuffer
+            self.charbuffer = ""
+        else:
+            # Return the first chars characters
+            result = self.charbuffer[:chars]
+            self.charbuffer = self.charbuffer[chars:]
+        return result
+
+    def readline(self, size=None, keepends=True):
+
+        """ Read one line from the input stream and return the
+            decoded data.
+
+            size, if given, is passed as size argument to the
+            read() method.
+
+        """
+        # If we have lines cached from an earlier read, return
+        # them unconditionally
+        if self.linebuffer:
+            line = self.linebuffer[0]
+            del self.linebuffer[0]
+            if len(self.linebuffer) == 1:
+                # revert to charbuffer mode; we might need more data
+                # next time
+                self.charbuffer = self.linebuffer[0]
+                self.linebuffer = None
+            if not keepends:
+                line = line.splitlines(False)[0]
+            return line
+
+        readsize = size or 72
+        line = ""
+        # If size is given, we call read() only once
+        while True:
+            data = self.read(readsize, firstline=True)
+            if data:
+                # If we're at a "\r" read one extra character (which might
+                # be a "\n") to get a proper line ending. If the stream is
+                # temporarily exhausted we return the wrong line ending.
+                if data.endswith("\r"):
+                    data += self.read(size=1, chars=1)
+
+            line += data
+            lines = line.splitlines(True)
+            if lines:
+                if len(lines) > 1:
+                    # More than one line result; the first line is a full line
+                    # to return
+                    line = lines[0]
+                    del lines[0]
+                    if len(lines) > 1:
+                        # cache the remaining lines
+                        lines[-1] += self.charbuffer
+                        self.linebuffer = lines
+                        self.charbuffer = None
+                    else:
+                        # only one remaining line, put it back into charbuffer
+                        self.charbuffer = lines[0] + self.charbuffer
+                    if not keepends:
+                        line = line.splitlines(False)[0]
+                    break
+                line0withend = lines[0]
+                line0withoutend = lines[0].splitlines(False)[0]
+                if line0withend != line0withoutend: # We really have a line end
+                    # Put the rest back together and keep it until the next call
+                    self.charbuffer = "".join(lines[1:]) + self.charbuffer
+                    if keepends:
+                        line = line0withend
+                    else:
+                        line = line0withoutend
+                    break
+            # we didn't get anything or this was our only try
+            if not data or size is not None:
+                if line and not keepends:
+                    line = line.splitlines(False)[0]
+                break
+            if readsize<8000:
+                readsize *= 2
+        return line
+
+    def readlines(self, sizehint=None, keepends=True):
+
+        """ Read all lines available on the input stream
+            and return them as list of lines.
+
+            Line breaks are implemented using the codec's decoder
+            method and are included in the list entries.
+
+            sizehint, if given, is ignored since there is no efficient
+            way to finding the true end-of-line.
+
+        """
+        data = self.read()
+        return data.splitlines(keepends)
+
+    def reset(self):
+
+        """ Resets the codec buffers used for keeping state.
+
+            Note that no stream repositioning should take place.
+            This method is primarily intended to be able to recover
+            from decoding errors.
+
+        """
+        self.bytebuffer = ""
+        self.charbuffer = u""
+        self.linebuffer = None
+
+    def seek(self, offset, whence=0):
+        """ Set the input stream's current position.
+
+            Resets the codec buffers used for keeping state.
+        """
+        self.reset()
+        self.stream.seek(offset, whence)
+
+    def next(self):
+
+        """ Return the next decoded line from the input stream."""
+        line = self.readline()
+        if line:
+            return line
+        raise StopIteration
+
+    def __iter__(self):
+        return self
+
+    def __getattr__(self, name,
+                    getattr=getattr):
+
+        """ Inherit all other methods from the underlying stream.
+        """
+        return getattr(self.stream, name)
+
+    def __enter__(self):
+        return self
+
+    def __exit__(self, type, value, tb):
+        self.stream.close()
+
+###
+
+class StreamReaderWriter:
+
+    """ StreamReaderWriter instances allow wrapping streams which
+        work in both read and write modes.
+
+        The design is such that one can use the factory functions
+        returned by the codec.lookup() function to construct the
+        instance.
+
+    """
+    # Optional attributes set by the file wrappers below
+    encoding = 'unknown'
+
+    def __init__(self, stream, Reader, Writer, errors='strict'):
+
+        """ Creates a StreamReaderWriter instance.
+
+            stream must be a Stream-like object.
+
+            Reader, Writer must be factory functions or classes
+            providing the StreamReader, StreamWriter interface resp.
+
+            Error handling is done in the same way as defined for the
+            StreamWriter/Readers.
+
+        """
+        self.stream = stream
+        self.reader = Reader(stream, errors)
+        self.writer = Writer(stream, errors)
+        self.errors = errors
+
+    def read(self, size=-1):
+
+        return self.reader.read(size)
+
+    def readline(self, size=None):
+
+        return self.reader.readline(size)
+
+    def readlines(self, sizehint=None):
+
+        return self.reader.readlines(sizehint)
+
+    def next(self):
+
+        """ Return the next decoded line from the input stream."""
+        return self.reader.next()
+
+    def __iter__(self):
+        return self
+
+    def write(self, data):
+
+        return self.writer.write(data)
+
+    def writelines(self, list):
+
+        return self.writer.writelines(list)
+
+    def reset(self):
+
+        self.reader.reset()
+        self.writer.reset()
+
+    def __getattr__(self, name,
+                    getattr=getattr):
+
+        """ Inherit all other methods from the underlying stream.
+        """
+        return getattr(self.stream, name)
+
+    # these are needed to make "with codecs.open(...)" work properly
+
+    def __enter__(self):
+        return self
+
+    def __exit__(self, type, value, tb):
+        self.stream.close()
+
+###
+
+class StreamRecoder:
+
+    """ StreamRecoder instances provide a frontend - backend
+        view of encoding data.
+
+        They use the complete set of APIs returned by the
+        codecs.lookup() function to implement their task.
+
+        Data written to the stream is first decoded into an
+        intermediate format (which is dependent on the given codec
+        combination) and then written to the stream using an instance
+        of the provided Writer class.
+
+        In the other direction, data is read from the stream using a
+        Reader instance and then return encoded data to the caller.
+
+    """
+    # Optional attributes set by the file wrappers below
+    data_encoding = 'unknown'
+    file_encoding = 'unknown'
+
+    def __init__(self, stream, encode, decode, Reader, Writer,
+                 errors='strict'):
+
+        """ Creates a StreamRecoder instance which implements a two-way
+            conversion: encode and decode work on the frontend (the
+            input to .read() and output of .write()) while
+            Reader and Writer work on the backend (reading and
+            writing to the stream).
+
+            You can use these objects to do transparent direct
+            recodings from e.g. latin-1 to utf-8 and back.
+
+            stream must be a file-like object.
+
+            encode, decode must adhere to the Codec interface, Reader,
+            Writer must be factory functions or classes providing the
+            StreamReader, StreamWriter interface resp.
+
+            encode and decode are needed for the frontend translation,
+            Reader and Writer for the backend translation. Unicode is
+            used as intermediate encoding.
+
+            Error handling is done in the same way as defined for the
+            StreamWriter/Readers.
+
+        """
+        self.stream = stream
+        self.encode = encode
+        self.decode = decode
+        self.reader = Reader(stream, errors)
+        self.writer = Writer(stream, errors)
+        self.errors = errors
+
+    def read(self, size=-1):
+
+        data = self.reader.read(size)
+        data, bytesencoded = self.encode(data, self.errors)
+        return data
+
+    def readline(self, size=None):
+
+        if size is None:
+            data = self.reader.readline()
+        else:
+            data = self.reader.readline(size)
+        data, bytesencoded = self.encode(data, self.errors)
+        return data
+
+    def readlines(self, sizehint=None):
+
+        data = self.reader.read()
+        data, bytesencoded = self.encode(data, self.errors)
+        return data.splitlines(1)
+
+    def next(self):
+
+        """ Return the next decoded line from the input stream."""
+        data = self.reader.next()
+        data, bytesencoded = self.encode(data, self.errors)
+        return data
+
+    def __iter__(self):
+        return self
+
+    def write(self, data):
+
+        data, bytesdecoded = self.decode(data, self.errors)
+        return self.writer.write(data)
+
+    def writelines(self, list):
+
+        data = ''.join(list)
+        data, bytesdecoded = self.decode(data, self.errors)
+        return self.writer.write(data)
+
+    def reset(self):
+
+        self.reader.reset()
+        self.writer.reset()
+
+    def __getattr__(self, name,
+                    getattr=getattr):
+
+        """ Inherit all other methods from the underlying stream.
+        """
+        return getattr(self.stream, name)
+
+    def __enter__(self):
+        return self
+
+    def __exit__(self, type, value, tb):
+        self.stream.close()
+
+### Shortcuts
+
+def open(filename, mode='rb', encoding=None, errors='strict', buffering=1):
+
+    """ Open an encoded file using the given mode and return
+        a wrapped version providing transparent encoding/decoding.
+
+        Note: The wrapped version will only accept the object format
+        defined by the codecs, i.e. Unicode objects for most builtin
+        codecs. Output is also codec dependent and will usually be
+        Unicode as well.
+
+        Files are always opened in binary mode, even if no binary mode
+        was specified. This is done to avoid data loss due to encodings
+        using 8-bit values. The default file mode is 'rb' meaning to
+        open the file in binary read mode.
+
+        encoding specifies the encoding which is to be used for the
+        file.
+
+        errors may be given to define the error handling. It defaults
+        to 'strict' which causes ValueErrors to be raised in case an
+        encoding error occurs.
+
+        buffering has the same meaning as for the builtin open() API.
+        It defaults to line buffered.
+
+        The returned wrapped file object provides an extra attribute
+        .encoding which allows querying the used encoding. This
+        attribute is only available if an encoding was specified as
+        parameter.
+
+    """
+    if encoding is not None and \
+       'b' not in mode:
+        # Force opening of the file in binary mode
+        mode = mode + 'b'
+    file = __builtin__.open(filename, mode, buffering)
+    if encoding is None:
+        return file
+    info = lookup(encoding)
+    srw = StreamReaderWriter(file, info.streamreader, info.streamwriter, errors)
+    # Add attributes to simplify introspection
+    srw.encoding = encoding
+    return srw
+
+def EncodedFile(file, data_encoding, file_encoding=None, errors='strict'):
+
+    """ Return a wrapped version of file which provides transparent
+        encoding translation.
+
+        Strings written to the wrapped file are interpreted according
+        to the given data_encoding and then written to the original
+        file as string using file_encoding. The intermediate encoding
+        will usually be Unicode but depends on the specified codecs.
+
+        Strings are read from the file using file_encoding and then
+        passed back to the caller as string using data_encoding.
+
+        If file_encoding is not given, it defaults to data_encoding.
+
+        errors may be given to define the error handling. It defaults
+        to 'strict' which causes ValueErrors to be raised in case an
+        encoding error occurs.
+
+        The returned wrapped file object provides two extra attributes
+        .data_encoding and .file_encoding which reflect the given
+        parameters of the same name. The attributes can be used for
+        introspection by Python programs.
+
+    """
+    if file_encoding is None:
+        file_encoding = data_encoding
+    data_info = lookup(data_encoding)
+    file_info = lookup(file_encoding)
+    sr = StreamRecoder(file, data_info.encode, data_info.decode,
+                       file_info.streamreader, file_info.streamwriter, errors)
+    # Add attributes to simplify introspection
+    sr.data_encoding = data_encoding
+    sr.file_encoding = file_encoding
+    return sr
+
+### Helpers for codec lookup
+
+def getencoder(encoding):
+
+    """ Lookup up the codec for the given encoding and return
+        its encoder function.
+
+        Raises a LookupError in case the encoding cannot be found.
+
+    """
+    return lookup(encoding).encode
+
+def getdecoder(encoding):
+
+    """ Lookup up the codec for the given encoding and return
+        its decoder function.
+
+        Raises a LookupError in case the encoding cannot be found.
+
+    """
+    return lookup(encoding).decode
+
+def getincrementalencoder(encoding):
+
+    """ Lookup up the codec for the given encoding and return
+        its IncrementalEncoder class or factory function.
+
+        Raises a LookupError in case the encoding cannot be found
+        or the codecs doesn't provide an incremental encoder.
+
+    """
+    encoder = lookup(encoding).incrementalencoder
+    if encoder is None:
+        raise LookupError(encoding)
+    return encoder
+
+def getincrementaldecoder(encoding):
+
+    """ Lookup up the codec for the given encoding and return
+        its IncrementalDecoder class or factory function.
+
+        Raises a LookupError in case the encoding cannot be found
+        or the codecs doesn't provide an incremental decoder.
+
+    """
+    decoder = lookup(encoding).incrementaldecoder
+    if decoder is None:
+        raise LookupError(encoding)
+    return decoder
+
+def getreader(encoding):
+
+    """ Lookup up the codec for the given encoding and return
+        its StreamReader class or factory function.
+
+        Raises a LookupError in case the encoding cannot be found.
+
+    """
+    return lookup(encoding).streamreader
+
+def getwriter(encoding):
+
+    """ Lookup up the codec for the given encoding and return
+        its StreamWriter class or factory function.
+
+        Raises a LookupError in case the encoding cannot be found.
+
+    """
+    return lookup(encoding).streamwriter
+
+def iterencode(iterator, encoding, errors='strict', **kwargs):
+    """
+    Encoding iterator.
+
+    Encodes the input strings from the iterator using a IncrementalEncoder.
+
+    errors and kwargs are passed through to the IncrementalEncoder
+    constructor.
+    """
+    encoder = getincrementalencoder(encoding)(errors, **kwargs)
+    for input in iterator:
+        output = encoder.encode(input)
+        if output:
+            yield output
+    output = encoder.encode("", True)
+    if output:
+        yield output
+
+def iterdecode(iterator, encoding, errors='strict', **kwargs):
+    """
+    Decoding iterator.
+
+    Decodes the input strings from the iterator using a IncrementalDecoder.
+
+    errors and kwargs are passed through to the IncrementalDecoder
+    constructor.
+    """
+    decoder = getincrementaldecoder(encoding)(errors, **kwargs)
+    for input in iterator:
+        output = decoder.decode(input)
+        if output:
+            yield output
+    output = decoder.decode("", True)
+    if output:
+        yield output
+
+### Helpers for charmap-based codecs
+
+def make_identity_dict(rng):
+
+    """ make_identity_dict(rng) -> dict
+
+        Return a dictionary where elements of the rng sequence are
+        mapped to themselves.
+
+    """
+    res = {}
+    for i in rng:
+        res[i]=i
+    return res
+
+def make_encoding_map(decoding_map):
+
+    """ Creates an encoding map from a decoding map.
+
+        If a target mapping in the decoding map occurs multiple
+        times, then that target is mapped to None (undefined mapping),
+        causing an exception when encountered by the charmap codec
+        during translation.
+
+        One example where this happens is cp875.py which decodes
+        multiple character to \u001a.
+
+    """
+    m = {}
+    for k,v in decoding_map.items():
+        if not v in m:
+            m[v] = k
+        else:
+            m[v] = None
+    return m
+
+### error handlers
+
+try:
+    strict_errors = lookup_error("strict")
+    ignore_errors = lookup_error("ignore")
+    replace_errors = lookup_error("replace")
+    xmlcharrefreplace_errors = lookup_error("xmlcharrefreplace")
+    backslashreplace_errors = lookup_error("backslashreplace")
+except LookupError:
+    # In --disable-unicode builds, these error handler are missing
+    strict_errors = None
+    ignore_errors = None
+    replace_errors = None
+    xmlcharrefreplace_errors = None
+    backslashreplace_errors = None
+
+# Tell modulefinder that using codecs probably needs the encodings
+# package
+_false = 0
+if _false:
+    import encodings
+
+### Tests
+
+if __name__ == '__main__':
+
+    # Make stdout translate Latin-1 output into UTF-8 output
+    sys.stdout = EncodedFile(sys.stdout, 'latin-1', 'utf-8')
+
+    # Have stdin translate Latin-1 input into UTF-8 input
+    sys.stdin = EncodedFile(sys.stdin, 'utf-8', 'latin-1')

Added: vendor/Python/current/Lib/codeop.py
===================================================================
--- vendor/Python/current/Lib/codeop.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/codeop.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,168 @@
+r"""Utilities to compile possibly incomplete Python source code.
+
+This module provides two interfaces, broadly similar to the builtin
+function compile(), which take program text, a filename and a 'mode'
+and:
+
+- Return code object if the command is complete and valid
+- Return None if the command is incomplete
+- Raise SyntaxError, ValueError or OverflowError if the command is a
+  syntax error (OverflowError and ValueError can be produced by
+  malformed literals).
+
+Approach:
+
+First, check if the source consists entirely of blank lines and
+comments; if so, replace it with 'pass', because the built-in
+parser doesn't always do the right thing for these.
+
+Compile three times: as is, with \n, and with \n\n appended.  If it
+compiles as is, it's complete.  If it compiles with one \n appended,
+we expect more.  If it doesn't compile either way, we compare the
+error we get when compiling with \n or \n\n appended.  If the errors
+are the same, the code is broken.  But if the errors are different, we
+expect more.  Not intuitive; not even guaranteed to hold in future
+releases; but this matches the compiler's behavior from Python 1.4
+through 2.2, at least.
+
+Caveat:
+
+It is possible (but not likely) that the parser stops parsing with a
+successful outcome before reaching the end of the source; in this
+case, trailing symbols may be ignored instead of causing an error.
+For example, a backslash followed by two newlines may be followed by
+arbitrary garbage.  This will be fixed once the API for the parser is
+better.
+
+The two interfaces are:
+
+compile_command(source, filename, symbol):
+
+    Compiles a single command in the manner described above.
+
+CommandCompiler():
+
+    Instances of this class have __call__ methods identical in
+    signature to compile_command; the difference is that if the
+    instance compiles program text containing a __future__ statement,
+    the instance 'remembers' and compiles all subsequent program texts
+    with the statement in force.
+
+The module also provides another class:
+
+Compile():
+
+    Instances of this class act like the built-in function compile,
+    but with 'memory' in the sense described above.
+"""
+
+import __future__
+
+_features = [getattr(__future__, fname)
+             for fname in __future__.all_feature_names]
+
+__all__ = ["compile_command", "Compile", "CommandCompiler"]
+
+PyCF_DONT_IMPLY_DEDENT = 0x200          # Matches pythonrun.h
+
+def _maybe_compile(compiler, source, filename, symbol):
+    # Check for source consisting of only blank lines and comments
+    for line in source.split("\n"):
+        line = line.strip()
+        if line and line[0] != '#':
+            break               # Leave it alone
+    else:
+        if symbol != "eval":
+            source = "pass"     # Replace it with a 'pass' statement
+
+    err = err1 = err2 = None
+    code = code1 = code2 = None
+
+    try:
+        code = compiler(source, filename, symbol)
+    except SyntaxError, err:
+        pass
+
+    try:
+        code1 = compiler(source + "\n", filename, symbol)
+    except SyntaxError, err1:
+        pass
+
+    try:
+        code2 = compiler(source + "\n\n", filename, symbol)
+    except SyntaxError, err2:
+        pass
+
+    if code:
+        return code
+    if not code1 and repr(err1) == repr(err2):
+        raise SyntaxError, err1
+
+def _compile(source, filename, symbol):
+    return compile(source, filename, symbol, PyCF_DONT_IMPLY_DEDENT)
+
+def compile_command(source, filename="<input>", symbol="single"):
+    r"""Compile a command and determine whether it is incomplete.
+
+    Arguments:
+
+    source -- the source string; may contain \n characters
+    filename -- optional filename from which source was read; default
+                "<input>"
+    symbol -- optional grammar start symbol; "single" (default) or "eval"
+
+    Return value / exceptions raised:
+
+    - Return a code object if the command is complete and valid
+    - Return None if the command is incomplete
+    - Raise SyntaxError, ValueError or OverflowError if the command is a
+      syntax error (OverflowError and ValueError can be produced by
+      malformed literals).
+    """
+    return _maybe_compile(_compile, source, filename, symbol)
+
+class Compile:
+    """Instances of this class behave much like the built-in compile
+    function, but if one is used to compile text containing a future
+    statement, it "remembers" and compiles all subsequent program texts
+    with the statement in force."""
+    def __init__(self):
+        self.flags = PyCF_DONT_IMPLY_DEDENT
+
+    def __call__(self, source, filename, symbol):
+        codeob = compile(source, filename, symbol, self.flags, 1)
+        for feature in _features:
+            if codeob.co_flags & feature.compiler_flag:
+                self.flags |= feature.compiler_flag
+        return codeob
+
+class CommandCompiler:
+    """Instances of this class have __call__ methods identical in
+    signature to compile_command; the difference is that if the
+    instance compiles program text containing a __future__ statement,
+    the instance 'remembers' and compiles all subsequent program texts
+    with the statement in force."""
+
+    def __init__(self,):
+        self.compiler = Compile()
+
+    def __call__(self, source, filename="<input>", symbol="single"):
+        r"""Compile a command and determine whether it is incomplete.
+
+        Arguments:
+
+        source -- the source string; may contain \n characters
+        filename -- optional filename from which source was read;
+                    default "<input>"
+        symbol -- optional grammar start symbol; "single" (default) or
+                  "eval"
+
+        Return value / exceptions raised:
+
+        - Return a code object if the command is complete and valid
+        - Return None if the command is incomplete
+        - Raise SyntaxError, ValueError or OverflowError if the command is a
+          syntax error (OverflowError and ValueError can be produced by
+          malformed literals).
+        """
+        return _maybe_compile(self.compiler, source, filename, symbol)

Added: vendor/Python/current/Lib/colorsys.py
===================================================================
--- vendor/Python/current/Lib/colorsys.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/colorsys.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,126 @@
+"""Conversion functions between RGB and other color systems.
+
+This modules provides two functions for each color system ABC:
+
+  rgb_to_abc(r, g, b) --> a, b, c
+  abc_to_rgb(a, b, c) --> r, g, b
+
+All inputs and outputs are triples of floats in the range [0.0...1.0]
+(with the exception of I and Q, which covers a slightly larger range).
+Inputs outside the valid range may cause exceptions or invalid outputs.
+
+Supported color systems:
+RGB: Red, Green, Blue components
+YIQ: Luminance, Chrominance (used by composite video signals)
+HLS: Hue, Luminance, Saturation
+HSV: Hue, Saturation, Value
+"""
+
+# References:
+# http://en.wikipedia.org/wiki/YIQ
+# http://en.wikipedia.org/wiki/HLS_color_space
+# http://en.wikipedia.org/wiki/HSV_color_space
+
+__all__ = ["rgb_to_yiq","yiq_to_rgb","rgb_to_hls","hls_to_rgb",
+           "rgb_to_hsv","hsv_to_rgb"]
+
+# Some floating point constants
+
+ONE_THIRD = 1.0/3.0
+ONE_SIXTH = 1.0/6.0
+TWO_THIRD = 2.0/3.0
+
+# YIQ: used by composite video signals (linear combinations of RGB)
+# Y: perceived grey level (0.0 == black, 1.0 == white)
+# I, Q: color components
+
+def rgb_to_yiq(r, g, b):
+    y = 0.30*r + 0.59*g + 0.11*b
+    i = 0.60*r - 0.28*g - 0.32*b
+    q = 0.21*r - 0.52*g + 0.31*b
+    return (y, i, q)
+
+def yiq_to_rgb(y, i, q):
+    r = y + 0.948262*i + 0.624013*q
+    g = y - 0.276066*i - 0.639810*q
+    b = y - 1.105450*i + 1.729860*q
+    if r < 0.0: r = 0.0
+    if g < 0.0: g = 0.0
+    if b < 0.0: b = 0.0
+    if r > 1.0: r = 1.0
+    if g > 1.0: g = 1.0
+    if b > 1.0: b = 1.0
+    return (r, g, b)
+
+
+# HLS: Hue, Luminance, Saturation
+# H: position in the spectrum
+# L: color lightness
+# S: color saturation
+
+def rgb_to_hls(r, g, b):
+    maxc = max(r, g, b)
+    minc = min(r, g, b)
+    # XXX Can optimize (maxc+minc) and (maxc-minc)
+    l = (minc+maxc)/2.0
+    if minc == maxc: return 0.0, l, 0.0
+    if l <= 0.5: s = (maxc-minc) / (maxc+minc)
+    else: s = (maxc-minc) / (2.0-maxc-minc)
+    rc = (maxc-r) / (maxc-minc)
+    gc = (maxc-g) / (maxc-minc)
+    bc = (maxc-b) / (maxc-minc)
+    if r == maxc: h = bc-gc
+    elif g == maxc: h = 2.0+rc-bc
+    else: h = 4.0+gc-rc
+    h = (h/6.0) % 1.0
+    return h, l, s
+
+def hls_to_rgb(h, l, s):
+    if s == 0.0: return l, l, l
+    if l <= 0.5: m2 = l * (1.0+s)
+    else: m2 = l+s-(l*s)
+    m1 = 2.0*l - m2
+    return (_v(m1, m2, h+ONE_THIRD), _v(m1, m2, h), _v(m1, m2, h-ONE_THIRD))
+
+def _v(m1, m2, hue):
+    hue = hue % 1.0
+    if hue < ONE_SIXTH: return m1 + (m2-m1)*hue*6.0
+    if hue < 0.5: return m2
+    if hue < TWO_THIRD: return m1 + (m2-m1)*(TWO_THIRD-hue)*6.0
+    return m1
+
+
+# HSV: Hue, Saturation, Value
+# H: position in the spectrum
+# S: color saturation ("purity")
+# V: color brightness
+
+def rgb_to_hsv(r, g, b):
+    maxc = max(r, g, b)
+    minc = min(r, g, b)
+    v = maxc
+    if minc == maxc: return 0.0, 0.0, v
+    s = (maxc-minc) / maxc
+    rc = (maxc-r) / (maxc-minc)
+    gc = (maxc-g) / (maxc-minc)
+    bc = (maxc-b) / (maxc-minc)
+    if r == maxc: h = bc-gc
+    elif g == maxc: h = 2.0+rc-bc
+    else: h = 4.0+gc-rc
+    h = (h/6.0) % 1.0
+    return h, s, v
+
+def hsv_to_rgb(h, s, v):
+    if s == 0.0: return v, v, v
+    i = int(h*6.0) # XXX assume int() truncates!
+    f = (h*6.0) - i
+    p = v*(1.0 - s)
+    q = v*(1.0 - s*f)
+    t = v*(1.0 - s*(1.0-f))
+    if i%6 == 0: return v, t, p
+    if i == 1: return q, v, p
+    if i == 2: return p, v, t
+    if i == 3: return p, q, v
+    if i == 4: return t, p, v
+    if i == 5: return v, p, q
+    # Cannot get here

Added: vendor/Python/current/Lib/commands.py
===================================================================
--- vendor/Python/current/Lib/commands.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/commands.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,84 @@
+"""Execute shell commands via os.popen() and return status, output.
+
+Interface summary:
+
+       import commands
+
+       outtext = commands.getoutput(cmd)
+       (exitstatus, outtext) = commands.getstatusoutput(cmd)
+       outtext = commands.getstatus(file)  # returns output of "ls -ld file"
+
+A trailing newline is removed from the output string.
+
+Encapsulates the basic operation:
+
+      pipe = os.popen('{ ' + cmd + '; } 2>&1', 'r')
+      text = pipe.read()
+      sts = pipe.close()
+
+ [Note:  it would be nice to add functions to interpret the exit status.]
+"""
+
+__all__ = ["getstatusoutput","getoutput","getstatus"]
+
+# Module 'commands'
+#
+# Various tools for executing commands and looking at their output and status.
+#
+# NB This only works (and is only relevant) for UNIX.
+
+
+# Get 'ls -l' status for an object into a string
+#
+def getstatus(file):
+    """Return output of "ls -ld <file>" in a string."""
+    return getoutput('ls -ld' + mkarg(file))
+
+
+# Get the output from a shell command into a string.
+# The exit status is ignored; a trailing newline is stripped.
+# Assume the command will work with '{ ... ; } 2>&1' around it..
+#
+def getoutput(cmd):
+    """Return output (stdout or stderr) of executing cmd in a shell."""
+    return getstatusoutput(cmd)[1]
+
+
+# Ditto but preserving the exit status.
+# Returns a pair (sts, output)
+#
+def getstatusoutput(cmd):
+    """Return (status, output) of executing cmd in a shell."""
+    import os
+    pipe = os.popen('{ ' + cmd + '; } 2>&1', 'r')
+    text = pipe.read()
+    sts = pipe.close()
+    if sts is None: sts = 0
+    if text[-1:] == '\n': text = text[:-1]
+    return sts, text
+
+
+# Make command argument from directory and pathname (prefix space, add quotes).
+#
+def mk2arg(head, x):
+    import os
+    return mkarg(os.path.join(head, x))
+
+
+# Make a shell command argument from a string.
+# Return a string beginning with a space followed by a shell-quoted
+# version of the argument.
+# Two strategies: enclose in single quotes if it contains none;
+# otherwise, enclose in double quotes and prefix quotable characters
+# with backslash.
+#
+def mkarg(x):
+    if '\'' not in x:
+        return ' \'' + x + '\''
+    s = ' "'
+    for c in x:
+        if c in '\\$"`':
+            s = s + '\\'
+        s = s + c
+    s = s + '"'
+    return s

Added: vendor/Python/current/Lib/compileall.py
===================================================================
--- vendor/Python/current/Lib/compileall.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/compileall.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,157 @@
+"""Module/script to "compile" all .py files to .pyc (or .pyo) file.
+
+When called as a script with arguments, this compiles the directories
+given as arguments recursively; the -l option prevents it from
+recursing into directories.
+
+Without arguments, if compiles all modules on sys.path, without
+recursing into subdirectories.  (Even though it should do so for
+packages -- for now, you'll have to deal with packages separately.)
+
+See module py_compile for details of the actual byte-compilation.
+
+"""
+
+import os
+import sys
+import py_compile
+
+__all__ = ["compile_dir","compile_path"]
+
+def compile_dir(dir, maxlevels=10, ddir=None,
+                force=0, rx=None, quiet=0):
+    """Byte-compile all modules in the given directory tree.
+
+    Arguments (only dir is required):
+
+    dir:       the directory to byte-compile
+    maxlevels: maximum recursion level (default 10)
+    ddir:      if given, purported directory name (this is the
+               directory name that will show up in error messages)
+    force:     if 1, force compilation, even if timestamps are up-to-date
+    quiet:     if 1, be quiet during compilation
+
+    """
+    if not quiet:
+        print 'Listing', dir, '...'
+    try:
+        names = os.listdir(dir)
+    except os.error:
+        print "Can't list", dir
+        names = []
+    names.sort()
+    success = 1
+    for name in names:
+        fullname = os.path.join(dir, name)
+        if ddir is not None:
+            dfile = os.path.join(ddir, name)
+        else:
+            dfile = None
+        if rx is not None:
+            mo = rx.search(fullname)
+            if mo:
+                continue
+        if os.path.isfile(fullname):
+            head, tail = name[:-3], name[-3:]
+            if tail == '.py':
+                cfile = fullname + (__debug__ and 'c' or 'o')
+                ftime = os.stat(fullname).st_mtime
+                try: ctime = os.stat(cfile).st_mtime
+                except os.error: ctime = 0
+                if (ctime > ftime) and not force: continue
+                if not quiet:
+                    print 'Compiling', fullname, '...'
+                try:
+                    ok = py_compile.compile(fullname, None, dfile, True)
+                except KeyboardInterrupt:
+                    raise KeyboardInterrupt
+                except py_compile.PyCompileError,err:
+                    if quiet:
+                        print 'Compiling', fullname, '...'
+                    print err.msg
+                    success = 0
+                except IOError, e:
+                    print "Sorry", e
+                    success = 0
+                else:
+                    if ok == 0:
+                        success = 0
+        elif maxlevels > 0 and \
+             name != os.curdir and name != os.pardir and \
+             os.path.isdir(fullname) and \
+             not os.path.islink(fullname):
+            if not compile_dir(fullname, maxlevels - 1, dfile, force, rx, quiet):
+                success = 0
+    return success
+
+def compile_path(skip_curdir=1, maxlevels=0, force=0, quiet=0):
+    """Byte-compile all module on sys.path.
+
+    Arguments (all optional):
+
+    skip_curdir: if true, skip current directory (default true)
+    maxlevels:   max recursion level (default 0)
+    force: as for compile_dir() (default 0)
+    quiet: as for compile_dir() (default 0)
+
+    """
+    success = 1
+    for dir in sys.path:
+        if (not dir or dir == os.curdir) and skip_curdir:
+            print 'Skipping current directory'
+        else:
+            success = success and compile_dir(dir, maxlevels, None,
+                                              force, quiet=quiet)
+    return success
+
+def main():
+    """Script main program."""
+    import getopt
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], 'lfqd:x:')
+    except getopt.error, msg:
+        print msg
+        print "usage: python compileall.py [-l] [-f] [-q] [-d destdir] " \
+              "[-x regexp] [directory ...]"
+        print "-l: don't recurse down"
+        print "-f: force rebuild even if timestamps are up-to-date"
+        print "-q: quiet operation"
+        print "-d destdir: purported directory name for error messages"
+        print "   if no directory arguments, -l sys.path is assumed"
+        print "-x regexp: skip files matching the regular expression regexp"
+        print "   the regexp is search for in the full path of the file"
+        sys.exit(2)
+    maxlevels = 10
+    ddir = None
+    force = 0
+    quiet = 0
+    rx = None
+    for o, a in opts:
+        if o == '-l': maxlevels = 0
+        if o == '-d': ddir = a
+        if o == '-f': force = 1
+        if o == '-q': quiet = 1
+        if o == '-x':
+            import re
+            rx = re.compile(a)
+    if ddir:
+        if len(args) != 1:
+            print "-d destdir require exactly one directory argument"
+            sys.exit(2)
+    success = 1
+    try:
+        if args:
+            for dir in args:
+                if not compile_dir(dir, maxlevels, ddir,
+                                   force, rx, quiet):
+                    success = 0
+        else:
+            success = compile_path()
+    except KeyboardInterrupt:
+        print "\n[interrupt]"
+        success = 0
+    return success
+
+if __name__ == '__main__':
+    exit_status = int(not main())
+    sys.exit(exit_status)

Added: vendor/Python/current/Lib/compiler/__init__.py
===================================================================
--- vendor/Python/current/Lib/compiler/__init__.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/compiler/__init__.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,26 @@
+"""Package for parsing and compiling Python source code
+
+There are several functions defined at the top level that are imported
+from modules contained in the package.
+
+parse(buf, mode="exec") -> AST
+    Converts a string containing Python source code to an abstract
+    syntax tree (AST).  The AST is defined in compiler.ast.
+
+parseFile(path) -> AST
+    The same as parse(open(path))
+
+walk(ast, visitor, verbose=None)
+    Does a pre-order walk over the ast using the visitor instance.
+    See compiler.visitor for details.
+
+compile(source, filename, mode, flags=None, dont_inherit=None)
+    Returns a code object.  A replacement for the builtin compile() function.
+
+compileFile(filename)
+    Generates a .pyc file by compiling filename.
+"""
+
+from compiler.transformer import parse, parseFile
+from compiler.visitor import walk
+from compiler.pycodegen import compile, compileFile

Added: vendor/Python/current/Lib/compiler/ast.py
===================================================================
--- vendor/Python/current/Lib/compiler/ast.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/compiler/ast.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1356 @@
+"""Python abstract syntax node definitions
+
+This file is automatically generated by Tools/compiler/astgen.py
+"""
+from compiler.consts import CO_VARARGS, CO_VARKEYWORDS
+
+def flatten(seq):
+    l = []
+    for elt in seq:
+        t = type(elt)
+        if t is tuple or t is list:
+            for elt2 in flatten(elt):
+                l.append(elt2)
+        else:
+            l.append(elt)
+    return l
+
+def flatten_nodes(seq):
+    return [n for n in flatten(seq) if isinstance(n, Node)]
+
+nodes = {}
+
+class Node:
+    """Abstract base class for ast nodes."""
+    def getChildren(self):
+        pass # implemented by subclasses
+    def __iter__(self):
+        for n in self.getChildren():
+            yield n
+    def asList(self): # for backwards compatibility
+        return self.getChildren()
+    def getChildNodes(self):
+        pass # implemented by subclasses
+
+class EmptyNode(Node):
+    pass
+
+class Expression(Node):
+    # Expression is an artificial node class to support "eval"
+    nodes["expression"] = "Expression"
+    def __init__(self, node):
+        self.node = node
+
+    def getChildren(self):
+        return self.node,
+
+    def getChildNodes(self):
+        return self.node,
+
+    def __repr__(self):
+        return "Expression(%s)" % (repr(self.node))
+
+class Add(Node):
+    def __init__(self, (left, right), lineno=None):
+        self.left = left
+        self.right = right
+        self.lineno = lineno
+
+    def getChildren(self):
+        return self.left, self.right
+
+    def getChildNodes(self):
+        return self.left, self.right
+
+    def __repr__(self):
+        return "Add((%s, %s))" % (repr(self.left), repr(self.right))
+
+class And(Node):
+    def __init__(self, nodes, lineno=None):
+        self.nodes = nodes
+        self.lineno = lineno
+
+    def getChildren(self):
+        return tuple(flatten(self.nodes))
+
+    def getChildNodes(self):
+        nodelist = []
+        nodelist.extend(flatten_nodes(self.nodes))
+        return tuple(nodelist)
+
+    def __repr__(self):
+        return "And(%s)" % (repr(self.nodes),)
+
+class AssAttr(Node):
+    def __init__(self, expr, attrname, flags, lineno=None):
+        self.expr = expr
+        self.attrname = attrname
+        self.flags = flags
+        self.lineno = lineno
+
+    def getChildren(self):
+        return self.expr, self.attrname, self.flags
+
+    def getChildNodes(self):
+        return self.expr,
+
+    def __repr__(self):
+        return "AssAttr(%s, %s, %s)" % (repr(self.expr), repr(self.attrname), repr(self.flags))
+
+class AssList(Node):
+    def __init__(self, nodes, lineno=None):
+        self.nodes = nodes
+        self.lineno = lineno
+
+    def getChildren(self):
+        return tuple(flatten(self.nodes))
+
+    def getChildNodes(self):
+        nodelist = []
+        nodelist.extend(flatten_nodes(self.nodes))
+        return tuple(nodelist)
+
+    def __repr__(self):
+        return "AssList(%s)" % (repr(self.nodes),)
+
+class AssName(Node):
+    def __init__(self, name, flags, lineno=None):
+        self.name = name
+        self.flags = flags
+        self.lineno = lineno
+
+    def getChildren(self):
+        return self.name, self.flags
+
+    def getChildNodes(self):
+        return ()
+
+    def __repr__(self):
+        return "AssName(%s, %s)" % (repr(self.name), repr(self.flags))
+
+class AssTuple(Node):
+    def __init__(self, nodes, lineno=None):
+        self.nodes = nodes
+        self.lineno = lineno
+
+    def getChildren(self):
+        return tuple(flatten(self.nodes))
+
+    def getChildNodes(self):
+        nodelist = []
+        nodelist.extend(flatten_nodes(self.nodes))
+        return tuple(nodelist)
+
+    def __repr__(self):
+        return "AssTuple(%s)" % (repr(self.nodes),)
+
+class Assert(Node):
+    def __init__(self, test, fail, lineno=None):
+        self.test = test
+        self.fail = fail
+        self.lineno = lineno
+
+    def getChildren(self):
+        children = []
+        children.append(self.test)
+        children.append(self.fail)
+        return tuple(children)
+
+    def getChildNodes(self):
+        nodelist = []
+        nodelist.append(self.test)
+        if self.fail is not None:
+            nodelist.append(self.fail)
+        return tuple(nodelist)
+
+    def __repr__(self):
+        return "Assert(%s, %s)" % (repr(self.test), repr(self.fail))
+
+class Assign(Node):
+    def __init__(self, nodes, expr, lineno=None):
+        self.nodes = nodes
+        self.expr = expr
+        self.lineno = lineno
+
+    def getChildren(self):
+        children = []
+        children.extend(flatten(self.nodes))
+        children.append(self.expr)
+        return tuple(children)
+
+    def getChildNodes(self):
+        nodelist = []
+        nodelist.extend(flatten_nodes(self.nodes))
+        nodelist.append(self.expr)
+        return tuple(nodelist)
+
+    def __repr__(self):
+        return "Assign(%s, %s)" % (repr(self.nodes), repr(self.expr))
+
+class AugAssign(Node):
+    def __init__(self, node, op, expr, lineno=None):
+        self.node = node
+        self.op = op
+        self.expr = expr
+        self.lineno = lineno
+
+    def getChildren(self):
+        return self.node, self.op, self.expr
+
+    def getChildNodes(self):
+        return self.node, self.expr
+
+    def __repr__(self):
+        return "AugAssign(%s, %s, %s)" % (repr(self.node), repr(self.op), repr(self.expr))
+
+class Backquote(Node):
+    def __init__(self, expr, lineno=None):
+        self.expr = expr
+        self.lineno = lineno
+
+    def getChildren(self):
+        return self.expr,
+
+    def getChildNodes(self):
+        return self.expr,
+
+    def __repr__(self):
+        return "Backquote(%s)" % (repr(self.expr),)
+
+class Bitand(Node):
+    def __init__(self, nodes, lineno=None):
+        self.nodes = nodes
+        self.lineno = lineno
+
+    def getChildren(self):
+        return tuple(flatten(self.nodes))
+
+    def getChildNodes(self):
+        nodelist = []
+        nodelist.extend(flatten_nodes(self.nodes))
+        return tuple(nodelist)
+
+    def __repr__(self):
+        return "Bitand(%s)" % (repr(self.nodes),)
+
+class Bitor(Node):
+    def __init__(self, nodes, lineno=None):
+        self.nodes = nodes
+        self.lineno = lineno
+
+    def getChildren(self):
+        return tuple(flatten(self.nodes))
+
+    def getChildNodes(self):
+        nodelist = []
+        nodelist.extend(flatten_nodes(self.nodes))
+        return tuple(nodelist)
+
+    def __repr__(self):
+        return "Bitor(%s)" % (repr(self.nodes),)
+
+class Bitxor(Node):
+    def __init__(self, nodes, lineno=None):
+        self.nodes = nodes
+        self.lineno = lineno
+
+    def getChildren(self):
+        return tuple(flatten(self.nodes))
+
+    def getChildNodes(self):
+        nodelist = []
+        nodelist.extend(flatten_nodes(self.nodes))
+        return tuple(nodelist)
+
+    def __repr__(self):
+        return "Bitxor(%s)" % (repr(self.nodes),)
+
+class Break(Node):
+    def __init__(self, lineno=None):
+        self.lineno = lineno
+
+    def getChildren(self):
+        return ()
+
+    def getChildNodes(self):
+        return ()
+
+    def __repr__(self):
+        return "Break()"
+
+class CallFunc(Node):
+    def __init__(self, node, args, star_args = None, dstar_args = None, lineno=None):
+        self.node = node
+        self.args = args
+        self.star_args = star_args
+        self.dstar_args = dstar_args
+        self.lineno = lineno
+
+    def getChildren(self):
+        children = []
+        children.append(self.node)
+        children.extend(flatten(self.args))
+        children.append(self.star_args)
+        children.append(self.dstar_args)
+        return tuple(children)
+
+    def getChildNodes(self):
+        nodelist = []
+        nodelist.append(self.node)
+        nodelist.extend(flatten_nodes(self.args))
+        if self.star_args is not None:
+            nodelist.append(self.star_args)
+        if self.dstar_args is not None:
+            nodelist.append(self.dstar_args)
+        return tuple(nodelist)
+
+    def __repr__(self):
+        return "CallFunc(%s, %s, %s, %s)" % (repr(self.node), repr(self.args), repr(self.star_args), repr(self.dstar_args))
+
+class Class(Node):
+    def __init__(self, name, bases, doc, code, lineno=None):
+        self.name = name
+        self.bases = bases
+        self.doc = doc
+        self.code = code
+        self.lineno = lineno
+
+    def getChildren(self):
+        children = []
+        children.append(self.name)
+        children.extend(flatten(self.bases))
+        children.append(self.doc)
+        children.append(self.code)
+        return tuple(children)
+
+    def getChildNodes(self):
+        nodelist = []
+        nodelist.extend(flatten_nodes(self.bases))
+        nodelist.append(self.code)
+        return tuple(nodelist)
+
+    def __repr__(self):
+        return "Class(%s, %s, %s, %s)" % (repr(self.name), repr(self.bases), repr(self.doc), repr(self.code))
+
+class Compare(Node):
+    def __init__(self, expr, ops, lineno=None):
+        self.expr = expr
+        self.ops = ops
+        self.lineno = lineno
+
+    def getChildren(self):
+        children = []
+        children.append(self.expr)
+        children.extend(flatten(self.ops))
+        return tuple(children)
+
+    def getChildNodes(self):
+        nodelist = []
+        nodelist.append(self.expr)
+        nodelist.extend(flatten_nodes(self.ops))
+        return tuple(nodelist)
+
+    def __repr__(self):
+        return "Compare(%s, %s)" % (repr(self.expr), repr(self.ops))
+
+class Const(Node):
+    def __init__(self, value, lineno=None):
+        self.value = value
+        self.lineno = lineno
+
+    def getChildren(self):
+        return self.value,
+
+    def getChildNodes(self):
+        return ()
+
+    def __repr__(self):
+        return "Const(%s)" % (repr(self.value),)
+
+class Continue(Node):
+    def __init__(self, lineno=None):
+        self.lineno = lineno
+
+    def getChildren(self):
+        return ()
+
+    def getChildNodes(self):
+        return ()
+
+    def __repr__(self):
+        return "Continue()"
+
+class Decorators(Node):
+    def __init__(self, nodes, lineno=None):
+        self.nodes = nodes
+        self.lineno = lineno
+
+    def getChildren(self):
+        return tuple(flatten(self.nodes))
+
+    def getChildNodes(self):
+        nodelist = []
+        nodelist.extend(flatten_nodes(self.nodes))
+        return tuple(nodelist)
+
+    def __repr__(self):
+        return "Decorators(%s)" % (repr(self.nodes),)
+
+class Dict(Node):
+    def __init__(self, items, lineno=None):
+        self.items = items
+        self.lineno = lineno
+
+    def getChildren(self):
+        return tuple(flatten(self.items))
+
+    def getChildNodes(self):
+        nodelist = []
+        nodelist.extend(flatten_nodes(self.items))
+        return tuple(nodelist)
+
+    def __repr__(self):
+        return "Dict(%s)" % (repr(self.items),)
+
+class Discard(Node):
+    def __init__(self, expr, lineno=None):
+        self.expr = expr
+        self.lineno = lineno
+
+    def getChildren(self):
+        return self.expr,
+
+    def getChildNodes(self):
+        return self.expr,
+
+    def __repr__(self):
+        return "Discard(%s)" % (repr(self.expr),)
+
+class Div(Node):
+    def __init__(self, (left, right), lineno=None):
+        self.left = left
+        self.right = right
+        self.lineno = lineno
+
+    def getChildren(self):
+        return self.left, self.right
+
+    def getChildNodes(self):
+        return self.left, self.right
+
+    def __repr__(self):
+        return "Div((%s, %s))" % (repr(self.left), repr(self.right))
+
+class Ellipsis(Node):
+    def __init__(self, lineno=None):
+        self.lineno = lineno
+
+    def getChildren(self):
+        return ()
+
+    def getChildNodes(self):
+        return ()
+
+    def __repr__(self):
+        return "Ellipsis()"
+
+class Exec(Node):
+    def __init__(self, expr, locals, globals, lineno=None):
+        self.expr = expr
+        self.locals = locals
+        self.globals = globals
+        self.lineno = lineno
+
+    def getChildren(self):
+        children = []
+        children.append(self.expr)
+        children.append(self.locals)
+        children.append(self.globals)
+        return tuple(children)
+
+    def getChildNodes(self):
+        nodelist = []
+        nodelist.append(self.expr)
+        if self.locals is not None:
+            nodelist.append(self.locals)
+        if self.globals is not None:
+            nodelist.append(self.globals)
+        return tuple(nodelist)
+
+    def __repr__(self):
+        return "Exec(%s, %s, %s)" % (repr(self.expr), repr(self.locals), repr(self.globals))
+
+class FloorDiv(Node):
+    def __init__(self, (left, right), lineno=None):
+        self.left = left
+        self.right = right
+        self.lineno = lineno
+
+    def getChildren(self):
+        return self.left, self.right
+
+    def getChildNodes(self):
+        return self.left, self.right
+
+    def __repr__(self):
+        return "FloorDiv((%s, %s))" % (repr(self.left), repr(self.right))
+
+class For(Node):
+    def __init__(self, assign, list, body, else_, lineno=None):
+        self.assign = assign
+        self.list = list
+        self.body = body
+        self.else_ = else_
+        self.lineno = lineno
+
+    def getChildren(self):
+        children = []
+        children.append(self.assign)
+        children.append(self.list)
+        children.append(self.body)
+        children.append(self.else_)
+        return tuple(children)
+
+    def getChildNodes(self):
+        nodelist = []
+        nodelist.append(self.assign)
+        nodelist.append(self.list)
+        nodelist.append(self.body)
+        if self.else_ is not None:
+            nodelist.append(self.else_)
+        return tuple(nodelist)
+
+    def __repr__(self):
+        return "For(%s, %s, %s, %s)" % (repr(self.assign), repr(self.list), repr(self.body), repr(self.else_))
+
+class From(Node):
+    def __init__(self, modname, names, level, lineno=None):
+        self.modname = modname
+        self.names = names
+        self.level = level
+        self.lineno = lineno
+
+    def getChildren(self):
+        return self.modname, self.names, self.level
+
+    def getChildNodes(self):
+        return ()
+
+    def __repr__(self):
+        return "From(%s, %s, %s)" % (repr(self.modname), repr(self.names), repr(self.level))
+
+class Function(Node):
+    def __init__(self, decorators, name, argnames, defaults, flags, doc, code, lineno=None):
+        self.decorators = decorators
+        self.name = name
+        self.argnames = argnames
+        self.defaults = defaults
+        self.flags = flags
+        self.doc = doc
+        self.code = code
+        self.lineno = lineno
+        self.varargs = self.kwargs = None
+        if flags & CO_VARARGS:
+            self.varargs = 1
+        if flags & CO_VARKEYWORDS:
+            self.kwargs = 1
+
+
+
+    def getChildren(self):
+        children = []
+        children.append(self.decorators)
+        children.append(self.name)
+        children.append(self.argnames)
+        children.extend(flatten(self.defaults))
+        children.append(self.flags)
+        children.append(self.doc)
+        children.append(self.code)
+        return tuple(children)
+
+    def getChildNodes(self):
+        nodelist = []
+        if self.decorators is not None:
+            nodelist.append(self.decorators)
+        nodelist.extend(flatten_nodes(self.defaults))
+        nodelist.append(self.code)
+        return tuple(nodelist)
+
+    def __repr__(self):
+        return "Function(%s, %s, %s, %s, %s, %s, %s)" % (repr(self.decorators), repr(self.name), repr(self.argnames), repr(self.defaults), repr(self.flags), repr(self.doc), repr(self.code))
+
+class GenExpr(Node):
+    def __init__(self, code, lineno=None):
+        self.code = code
+        self.lineno = lineno
+        self.argnames = ['.0']
+        self.varargs = self.kwargs = None
+
+    def getChildren(self):
+        return self.code,
+
+    def getChildNodes(self):
+        return self.code,
+
+    def __repr__(self):
+        return "GenExpr(%s)" % (repr(self.code),)
+
+class GenExprFor(Node):
+    def __init__(self, assign, iter, ifs, lineno=None):
+        self.assign = assign
+        self.iter = iter
+        self.ifs = ifs
+        self.lineno = lineno
+        self.is_outmost = False
+
+
+    def getChildren(self):
+        children = []
+        children.append(self.assign)
+        children.append(self.iter)
+        children.extend(flatten(self.ifs))
+        return tuple(children)
+
+    def getChildNodes(self):
+        nodelist = []
+        nodelist.append(self.assign)
+        nodelist.append(self.iter)
+        nodelist.extend(flatten_nodes(self.ifs))
+        return tuple(nodelist)
+
+    def __repr__(self):
+        return "GenExprFor(%s, %s, %s)" % (repr(self.assign), repr(self.iter), repr(self.ifs))
+
+class GenExprIf(Node):
+    def __init__(self, test, lineno=None):
+        self.test = test
+        self.lineno = lineno
+
+    def getChildren(self):
+        return self.test,
+
+    def getChildNodes(self):
+        return self.test,
+
+    def __repr__(self):
+        return "GenExprIf(%s)" % (repr(self.test),)
+
+class GenExprInner(Node):
+    def __init__(self, expr, quals, lineno=None):
+        self.expr = expr
+        self.quals = quals
+        self.lineno = lineno
+
+    def getChildren(self):
+        children = []
+        children.append(self.expr)
+        children.extend(flatten(self.quals))
+        return tuple(children)
+
+    def getChildNodes(self):
+        nodelist = []
+        nodelist.append(self.expr)
+        nodelist.extend(flatten_nodes(self.quals))
+        return tuple(nodelist)
+
+    def __repr__(self):
+        return "GenExprInner(%s, %s)" % (repr(self.expr), repr(self.quals))
+
+class Getattr(Node):
+    def __init__(self, expr, attrname, lineno=None):
+        self.expr = expr
+        self.attrname = attrname
+        self.lineno = lineno
+
+    def getChildren(self):
+        return self.expr, self.attrname
+
+    def getChildNodes(self):
+        return self.expr,
+
+    def __repr__(self):
+        return "Getattr(%s, %s)" % (repr(self.expr), repr(self.attrname))
+
+class Global(Node):
+    def __init__(self, names, lineno=None):
+        self.names = names
+        self.lineno = lineno
+
+    def getChildren(self):
+        return self.names,
+
+    def getChildNodes(self):
+        return ()
+
+    def __repr__(self):
+        return "Global(%s)" % (repr(self.names),)
+
+class If(Node):
+    def __init__(self, tests, else_, lineno=None):
+        self.tests = tests
+        self.else_ = else_
+        self.lineno = lineno
+
+    def getChildren(self):
+        children = []
+        children.extend(flatten(self.tests))
+        children.append(self.else_)
+        return tuple(children)
+
+    def getChildNodes(self):
+        nodelist = []
+        nodelist.extend(flatten_nodes(self.tests))
+        if self.else_ is not None:
+            nodelist.append(self.else_)
+        return tuple(nodelist)
+
+    def __repr__(self):
+        return "If(%s, %s)" % (repr(self.tests), repr(self.else_))
+
+class IfExp(Node):
+    def __init__(self, test, then, else_, lineno=None):
+        self.test = test
+        self.then = then
+        self.else_ = else_
+        self.lineno = lineno
+
+    def getChildren(self):
+        return self.test, self.then, self.else_
+
+    def getChildNodes(self):
+        return self.test, self.then, self.else_
+
+    def __repr__(self):
+        return "IfExp(%s, %s, %s)" % (repr(self.test), repr(self.then), repr(self.else_))
+
+class Import(Node):
+    def __init__(self, names, lineno=None):
+        self.names = names
+        self.lineno = lineno
+
+    def getChildren(self):
+        return self.names,
+
+    def getChildNodes(self):
+        return ()
+
+    def __repr__(self):
+        return "Import(%s)" % (repr(self.names),)
+
+class Invert(Node):
+    def __init__(self, expr, lineno=None):
+        self.expr = expr
+        self.lineno = lineno
+
+    def getChildren(self):
+        return self.expr,
+
+    def getChildNodes(self):
+        return self.expr,
+
+    def __repr__(self):
+        return "Invert(%s)" % (repr(self.expr),)
+
+class Keyword(Node):
+    def __init__(self, name, expr, lineno=None):
+        self.name = name
+        self.expr = expr
+        self.lineno = lineno
+
+    def getChildren(self):
+        return self.name, self.expr
+
+    def getChildNodes(self):
+        return self.expr,
+
+    def __repr__(self):
+        return "Keyword(%s, %s)" % (repr(self.name), repr(self.expr))
+
+class Lambda(Node):
+    def __init__(self, argnames, defaults, flags, code, lineno=None):
+        self.argnames = argnames
+        self.defaults = defaults
+        self.flags = flags
+        self.code = code
+        self.lineno = lineno
+        self.varargs = self.kwargs = None
+        if flags & CO_VARARGS:
+            self.varargs = 1
+        if flags & CO_VARKEYWORDS:
+            self.kwargs = 1
+
+
+
+    def getChildren(self):
+        children = []
+        children.append(self.argnames)
+        children.extend(flatten(self.defaults))
+        children.append(self.flags)
+        children.append(self.code)
+        return tuple(children)
+
+    def getChildNodes(self):
+        nodelist = []
+        nodelist.extend(flatten_nodes(self.defaults))
+        nodelist.append(self.code)
+        return tuple(nodelist)
+
+    def __repr__(self):
+        return "Lambda(%s, %s, %s, %s)" % (repr(self.argnames), repr(self.defaults), repr(self.flags), repr(self.code))
+
+class LeftShift(Node):
+    def __init__(self, (left, right), lineno=None):
+        self.left = left
+        self.right = right
+        self.lineno = lineno
+
+    def getChildren(self):
+        return self.left, self.right
+
+    def getChildNodes(self):
+        return self.left, self.right
+
+    def __repr__(self):
+        return "LeftShift((%s, %s))" % (repr(self.left), repr(self.right))
+
+class List(Node):
+    def __init__(self, nodes, lineno=None):
+        self.nodes = nodes
+        self.lineno = lineno
+
+    def getChildren(self):
+        return tuple(flatten(self.nodes))
+
+    def getChildNodes(self):
+        nodelist = []
+        nodelist.extend(flatten_nodes(self.nodes))
+        return tuple(nodelist)
+
+    def __repr__(self):
+        return "List(%s)" % (repr(self.nodes),)
+
+class ListComp(Node):
+    def __init__(self, expr, quals, lineno=None):
+        self.expr = expr
+        self.quals = quals
+        self.lineno = lineno
+
+    def getChildren(self):
+        children = []
+        children.append(self.expr)
+        children.extend(flatten(self.quals))
+        return tuple(children)
+
+    def getChildNodes(self):
+        nodelist = []
+        nodelist.append(self.expr)
+        nodelist.extend(flatten_nodes(self.quals))
+        return tuple(nodelist)
+
+    def __repr__(self):
+        return "ListComp(%s, %s)" % (repr(self.expr), repr(self.quals))
+
+class ListCompFor(Node):
+    def __init__(self, assign, list, ifs, lineno=None):
+        self.assign = assign
+        self.list = list
+        self.ifs = ifs
+        self.lineno = lineno
+
+    def getChildren(self):
+        children = []
+        children.append(self.assign)
+        children.append(self.list)
+        children.extend(flatten(self.ifs))
+        return tuple(children)
+
+    def getChildNodes(self):
+        nodelist = []
+        nodelist.append(self.assign)
+        nodelist.append(self.list)
+        nodelist.extend(flatten_nodes(self.ifs))
+        return tuple(nodelist)
+
+    def __repr__(self):
+        return "ListCompFor(%s, %s, %s)" % (repr(self.assign), repr(self.list), repr(self.ifs))
+
+class ListCompIf(Node):
+    def __init__(self, test, lineno=None):
+        self.test = test
+        self.lineno = lineno
+
+    def getChildren(self):
+        return self.test,
+
+    def getChildNodes(self):
+        return self.test,
+
+    def __repr__(self):
+        return "ListCompIf(%s)" % (repr(self.test),)
+
+class Mod(Node):
+    def __init__(self, (left, right), lineno=None):
+        self.left = left
+        self.right = right
+        self.lineno = lineno
+
+    def getChildren(self):
+        return self.left, self.right
+
+    def getChildNodes(self):
+        return self.left, self.right
+
+    def __repr__(self):
+        return "Mod((%s, %s))" % (repr(self.left), repr(self.right))
+
+class Module(Node):
+    def __init__(self, doc, node, lineno=None):
+        self.doc = doc
+        self.node = node
+        self.lineno = lineno
+
+    def getChildren(self):
+        return self.doc, self.node
+
+    def getChildNodes(self):
+        return self.node,
+
+    def __repr__(self):
+        return "Module(%s, %s)" % (repr(self.doc), repr(self.node))
+
+class Mul(Node):
+    def __init__(self, (left, right), lineno=None):
+        self.left = left
+        self.right = right
+        self.lineno = lineno
+
+    def getChildren(self):
+        return self.left, self.right
+
+    def getChildNodes(self):
+        return self.left, self.right
+
+    def __repr__(self):
+        return "Mul((%s, %s))" % (repr(self.left), repr(self.right))
+
+class Name(Node):
+    def __init__(self, name, lineno=None):
+        self.name = name
+        self.lineno = lineno
+
+    def getChildren(self):
+        return self.name,
+
+    def getChildNodes(self):
+        return ()
+
+    def __repr__(self):
+        return "Name(%s)" % (repr(self.name),)
+
+class Not(Node):
+    def __init__(self, expr, lineno=None):
+        self.expr = expr
+        self.lineno = lineno
+
+    def getChildren(self):
+        return self.expr,
+
+    def getChildNodes(self):
+        return self.expr,
+
+    def __repr__(self):
+        return "Not(%s)" % (repr(self.expr),)
+
+class Or(Node):
+    def __init__(self, nodes, lineno=None):
+        self.nodes = nodes
+        self.lineno = lineno
+
+    def getChildren(self):
+        return tuple(flatten(self.nodes))
+
+    def getChildNodes(self):
+        nodelist = []
+        nodelist.extend(flatten_nodes(self.nodes))
+        return tuple(nodelist)
+
+    def __repr__(self):
+        return "Or(%s)" % (repr(self.nodes),)
+
+class Pass(Node):
+    def __init__(self, lineno=None):
+        self.lineno = lineno
+
+    def getChildren(self):
+        return ()
+
+    def getChildNodes(self):
+        return ()
+
+    def __repr__(self):
+        return "Pass()"
+
+class Power(Node):
+    def __init__(self, (left, right), lineno=None):
+        self.left = left
+        self.right = right
+        self.lineno = lineno
+
+    def getChildren(self):
+        return self.left, self.right
+
+    def getChildNodes(self):
+        return self.left, self.right
+
+    def __repr__(self):
+        return "Power((%s, %s))" % (repr(self.left), repr(self.right))
+
+class Print(Node):
+    def __init__(self, nodes, dest, lineno=None):
+        self.nodes = nodes
+        self.dest = dest
+        self.lineno = lineno
+
+    def getChildren(self):
+        children = []
+        children.extend(flatten(self.nodes))
+        children.append(self.dest)
+        return tuple(children)
+
+    def getChildNodes(self):
+        nodelist = []
+        nodelist.extend(flatten_nodes(self.nodes))
+        if self.dest is not None:
+            nodelist.append(self.dest)
+        return tuple(nodelist)
+
+    def __repr__(self):
+        return "Print(%s, %s)" % (repr(self.nodes), repr(self.dest))
+
+class Printnl(Node):
+    def __init__(self, nodes, dest, lineno=None):
+        self.nodes = nodes
+        self.dest = dest
+        self.lineno = lineno
+
+    def getChildren(self):
+        children = []
+        children.extend(flatten(self.nodes))
+        children.append(self.dest)
+        return tuple(children)
+
+    def getChildNodes(self):
+        nodelist = []
+        nodelist.extend(flatten_nodes(self.nodes))
+        if self.dest is not None:
+            nodelist.append(self.dest)
+        return tuple(nodelist)
+
+    def __repr__(self):
+        return "Printnl(%s, %s)" % (repr(self.nodes), repr(self.dest))
+
+class Raise(Node):
+    def __init__(self, expr1, expr2, expr3, lineno=None):
+        self.expr1 = expr1
+        self.expr2 = expr2
+        self.expr3 = expr3
+        self.lineno = lineno
+
+    def getChildren(self):
+        children = []
+        children.append(self.expr1)
+        children.append(self.expr2)
+        children.append(self.expr3)
+        return tuple(children)
+
+    def getChildNodes(self):
+        nodelist = []
+        if self.expr1 is not None:
+            nodelist.append(self.expr1)
+        if self.expr2 is not None:
+            nodelist.append(self.expr2)
+        if self.expr3 is not None:
+            nodelist.append(self.expr3)
+        return tuple(nodelist)
+
+    def __repr__(self):
+        return "Raise(%s, %s, %s)" % (repr(self.expr1), repr(self.expr2), repr(self.expr3))
+
+class Return(Node):
+    def __init__(self, value, lineno=None):
+        self.value = value
+        self.lineno = lineno
+
+    def getChildren(self):
+        return self.value,
+
+    def getChildNodes(self):
+        return self.value,
+
+    def __repr__(self):
+        return "Return(%s)" % (repr(self.value),)
+
+class RightShift(Node):
+    def __init__(self, (left, right), lineno=None):
+        self.left = left
+        self.right = right
+        self.lineno = lineno
+
+    def getChildren(self):
+        return self.left, self.right
+
+    def getChildNodes(self):
+        return self.left, self.right
+
+    def __repr__(self):
+        return "RightShift((%s, %s))" % (repr(self.left), repr(self.right))
+
+class Slice(Node):
+    def __init__(self, expr, flags, lower, upper, lineno=None):
+        self.expr = expr
+        self.flags = flags
+        self.lower = lower
+        self.upper = upper
+        self.lineno = lineno
+
+    def getChildren(self):
+        children = []
+        children.append(self.expr)
+        children.append(self.flags)
+        children.append(self.lower)
+        children.append(self.upper)
+        return tuple(children)
+
+    def getChildNodes(self):
+        nodelist = []
+        nodelist.append(self.expr)
+        if self.lower is not None:
+            nodelist.append(self.lower)
+        if self.upper is not None:
+            nodelist.append(self.upper)
+        return tuple(nodelist)
+
+    def __repr__(self):
+        return "Slice(%s, %s, %s, %s)" % (repr(self.expr), repr(self.flags), repr(self.lower), repr(self.upper))
+
+class Sliceobj(Node):
+    def __init__(self, nodes, lineno=None):
+        self.nodes = nodes
+        self.lineno = lineno
+
+    def getChildren(self):
+        return tuple(flatten(self.nodes))
+
+    def getChildNodes(self):
+        nodelist = []
+        nodelist.extend(flatten_nodes(self.nodes))
+        return tuple(nodelist)
+
+    def __repr__(self):
+        return "Sliceobj(%s)" % (repr(self.nodes),)
+
+class Stmt(Node):
+    def __init__(self, nodes, lineno=None):
+        self.nodes = nodes
+        self.lineno = lineno
+
+    def getChildren(self):
+        return tuple(flatten(self.nodes))
+
+    def getChildNodes(self):
+        nodelist = []
+        nodelist.extend(flatten_nodes(self.nodes))
+        return tuple(nodelist)
+
+    def __repr__(self):
+        return "Stmt(%s)" % (repr(self.nodes),)
+
+class Sub(Node):
+    def __init__(self, (left, right), lineno=None):
+        self.left = left
+        self.right = right
+        self.lineno = lineno
+
+    def getChildren(self):
+        return self.left, self.right
+
+    def getChildNodes(self):
+        return self.left, self.right
+
+    def __repr__(self):
+        return "Sub((%s, %s))" % (repr(self.left), repr(self.right))
+
+class Subscript(Node):
+    def __init__(self, expr, flags, subs, lineno=None):
+        self.expr = expr
+        self.flags = flags
+        self.subs = subs
+        self.lineno = lineno
+
+    def getChildren(self):
+        children = []
+        children.append(self.expr)
+        children.append(self.flags)
+        children.extend(flatten(self.subs))
+        return tuple(children)
+
+    def getChildNodes(self):
+        nodelist = []
+        nodelist.append(self.expr)
+        nodelist.extend(flatten_nodes(self.subs))
+        return tuple(nodelist)
+
+    def __repr__(self):
+        return "Subscript(%s, %s, %s)" % (repr(self.expr), repr(self.flags), repr(self.subs))
+
+class TryExcept(Node):
+    def __init__(self, body, handlers, else_, lineno=None):
+        self.body = body
+        self.handlers = handlers
+        self.else_ = else_
+        self.lineno = lineno
+
+    def getChildren(self):
+        children = []
+        children.append(self.body)
+        children.extend(flatten(self.handlers))
+        children.append(self.else_)
+        return tuple(children)
+
+    def getChildNodes(self):
+        nodelist = []
+        nodelist.append(self.body)
+        nodelist.extend(flatten_nodes(self.handlers))
+        if self.else_ is not None:
+            nodelist.append(self.else_)
+        return tuple(nodelist)
+
+    def __repr__(self):
+        return "TryExcept(%s, %s, %s)" % (repr(self.body), repr(self.handlers), repr(self.else_))
+
+class TryFinally(Node):
+    def __init__(self, body, final, lineno=None):
+        self.body = body
+        self.final = final
+        self.lineno = lineno
+
+    def getChildren(self):
+        return self.body, self.final
+
+    def getChildNodes(self):
+        return self.body, self.final
+
+    def __repr__(self):
+        return "TryFinally(%s, %s)" % (repr(self.body), repr(self.final))
+
+class Tuple(Node):
+    def __init__(self, nodes, lineno=None):
+        self.nodes = nodes
+        self.lineno = lineno
+
+    def getChildren(self):
+        return tuple(flatten(self.nodes))
+
+    def getChildNodes(self):
+        nodelist = []
+        nodelist.extend(flatten_nodes(self.nodes))
+        return tuple(nodelist)
+
+    def __repr__(self):
+        return "Tuple(%s)" % (repr(self.nodes),)
+
+class UnaryAdd(Node):
+    def __init__(self, expr, lineno=None):
+        self.expr = expr
+        self.lineno = lineno
+
+    def getChildren(self):
+        return self.expr,
+
+    def getChildNodes(self):
+        return self.expr,
+
+    def __repr__(self):
+        return "UnaryAdd(%s)" % (repr(self.expr),)
+
+class UnarySub(Node):
+    def __init__(self, expr, lineno=None):
+        self.expr = expr
+        self.lineno = lineno
+
+    def getChildren(self):
+        return self.expr,
+
+    def getChildNodes(self):
+        return self.expr,
+
+    def __repr__(self):
+        return "UnarySub(%s)" % (repr(self.expr),)
+
+class While(Node):
+    def __init__(self, test, body, else_, lineno=None):
+        self.test = test
+        self.body = body
+        self.else_ = else_
+        self.lineno = lineno
+
+    def getChildren(self):
+        children = []
+        children.append(self.test)
+        children.append(self.body)
+        children.append(self.else_)
+        return tuple(children)
+
+    def getChildNodes(self):
+        nodelist = []
+        nodelist.append(self.test)
+        nodelist.append(self.body)
+        if self.else_ is not None:
+            nodelist.append(self.else_)
+        return tuple(nodelist)
+
+    def __repr__(self):
+        return "While(%s, %s, %s)" % (repr(self.test), repr(self.body), repr(self.else_))
+
+class With(Node):
+    def __init__(self, expr, vars, body, lineno=None):
+        self.expr = expr
+        self.vars = vars
+        self.body = body
+        self.lineno = lineno
+
+    def getChildren(self):
+        children = []
+        children.append(self.expr)
+        children.append(self.vars)
+        children.append(self.body)
+        return tuple(children)
+
+    def getChildNodes(self):
+        nodelist = []
+        nodelist.append(self.expr)
+        if self.vars is not None:
+            nodelist.append(self.vars)
+        nodelist.append(self.body)
+        return tuple(nodelist)
+
+    def __repr__(self):
+        return "With(%s, %s, %s)" % (repr(self.expr), repr(self.vars), repr(self.body))
+
+class Yield(Node):
+    def __init__(self, value, lineno=None):
+        self.value = value
+        self.lineno = lineno
+
+    def getChildren(self):
+        return self.value,
+
+    def getChildNodes(self):
+        return self.value,
+
+    def __repr__(self):
+        return "Yield(%s)" % (repr(self.value),)
+
+for name, obj in globals().items():
+    if isinstance(obj, type) and issubclass(obj, Node):
+        nodes[name.lower()] = obj

Added: vendor/Python/current/Lib/compiler/consts.py
===================================================================
--- vendor/Python/current/Lib/compiler/consts.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/compiler/consts.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,21 @@
+# operation flags
+OP_ASSIGN = 'OP_ASSIGN'
+OP_DELETE = 'OP_DELETE'
+OP_APPLY = 'OP_APPLY'
+
+SC_LOCAL = 1
+SC_GLOBAL = 2
+SC_FREE = 3
+SC_CELL = 4
+SC_UNKNOWN = 5
+
+CO_OPTIMIZED = 0x0001
+CO_NEWLOCALS = 0x0002
+CO_VARARGS = 0x0004
+CO_VARKEYWORDS = 0x0008
+CO_NESTED = 0x0010
+CO_GENERATOR = 0x0020
+CO_GENERATOR_ALLOWED = 0
+CO_FUTURE_DIVISION = 0x2000
+CO_FUTURE_ABSIMPORT = 0x4000
+CO_FUTURE_WITH_STATEMENT = 0x8000

Added: vendor/Python/current/Lib/compiler/future.py
===================================================================
--- vendor/Python/current/Lib/compiler/future.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/compiler/future.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,73 @@
+"""Parser for future statements
+
+"""
+
+from compiler import ast, walk
+
+def is_future(stmt):
+    """Return true if statement is a well-formed future statement"""
+    if not isinstance(stmt, ast.From):
+        return 0
+    if stmt.modname == "__future__":
+        return 1
+    else:
+        return 0
+
+class FutureParser:
+
+    features = ("nested_scopes", "generators", "division",
+                "absolute_import", "with_statement")
+
+    def __init__(self):
+        self.found = {} # set
+
+    def visitModule(self, node):
+        stmt = node.node
+        for s in stmt.nodes:
+            if not self.check_stmt(s):
+                break
+
+    def check_stmt(self, stmt):
+        if is_future(stmt):
+            for name, asname in stmt.names:
+                if name in self.features:
+                    self.found[name] = 1
+                else:
+                    raise SyntaxError, \
+                          "future feature %s is not defined" % name
+            stmt.valid_future = 1
+            return 1
+        return 0
+
+    def get_features(self):
+        """Return list of features enabled by future statements"""
+        return self.found.keys()
+
+class BadFutureParser:
+    """Check for invalid future statements"""
+
+    def visitFrom(self, node):
+        if hasattr(node, 'valid_future'):
+            return
+        if node.modname != "__future__":
+            return
+        raise SyntaxError, "invalid future statement " + repr(node)
+
+def find_futures(node):
+    p1 = FutureParser()
+    p2 = BadFutureParser()
+    walk(node, p1)
+    walk(node, p2)
+    return p1.get_features()
+
+if __name__ == "__main__":
+    import sys
+    from compiler import parseFile, walk
+
+    for file in sys.argv[1:]:
+        print file
+        tree = parseFile(file)
+        v = FutureParser()
+        walk(tree, v)
+        print v.found
+        print

Added: vendor/Python/current/Lib/compiler/misc.py
===================================================================
--- vendor/Python/current/Lib/compiler/misc.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/compiler/misc.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,73 @@
+
+def flatten(tup):
+    elts = []
+    for elt in tup:
+        if isinstance(elt, tuple):
+            elts = elts + flatten(elt)
+        else:
+            elts.append(elt)
+    return elts
+
+class Set:
+    def __init__(self):
+        self.elts = {}
+    def __len__(self):
+        return len(self.elts)
+    def __contains__(self, elt):
+        return self.elts.has_key(elt)
+    def add(self, elt):
+        self.elts[elt] = elt
+    def elements(self):
+        return self.elts.keys()
+    def has_elt(self, elt):
+        return self.elts.has_key(elt)
+    def remove(self, elt):
+        del self.elts[elt]
+    def copy(self):
+        c = Set()
+        c.elts.update(self.elts)
+        return c
+
+class Stack:
+    def __init__(self):
+        self.stack = []
+        self.pop = self.stack.pop
+    def __len__(self):
+        return len(self.stack)
+    def push(self, elt):
+        self.stack.append(elt)
+    def top(self):
+        return self.stack[-1]
+    def __getitem__(self, index): # needed by visitContinue()
+        return self.stack[index]
+
+MANGLE_LEN = 256 # magic constant from compile.c
+
+def mangle(name, klass):
+    if not name.startswith('__'):
+        return name
+    if len(name) + 2 >= MANGLE_LEN:
+        return name
+    if name.endswith('__'):
+        return name
+    try:
+        i = 0
+        while klass[i] == '_':
+            i = i + 1
+    except IndexError:
+        return name
+    klass = klass[i:]
+
+    tlen = len(klass) + len(name)
+    if tlen > MANGLE_LEN:
+        klass = klass[:MANGLE_LEN-tlen]
+
+    return "_%s%s" % (klass, name)
+
+def set_filename(filename, tree):
+    """Set the filename attribute to filename on every node in tree"""
+    worklist = [tree]
+    while worklist:
+        node = worklist.pop(0)
+        node.filename = filename
+        worklist.extend(node.getChildNodes())

Added: vendor/Python/current/Lib/compiler/pyassem.py
===================================================================
--- vendor/Python/current/Lib/compiler/pyassem.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/compiler/pyassem.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,818 @@
+"""A flow graph representation for Python bytecode"""
+
+import dis
+import new
+import sys
+
+from compiler import misc
+from compiler.consts \
+     import CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS
+
+class FlowGraph:
+    def __init__(self):
+        self.current = self.entry = Block()
+        self.exit = Block("exit")
+        self.blocks = misc.Set()
+        self.blocks.add(self.entry)
+        self.blocks.add(self.exit)
+
+    def startBlock(self, block):
+        if self._debug:
+            if self.current:
+                print "end", repr(self.current)
+                print "    next", self.current.next
+                print "   ", self.current.get_children()
+            print repr(block)
+        self.current = block
+
+    def nextBlock(self, block=None):
+        # XXX think we need to specify when there is implicit transfer
+        # from one block to the next.  might be better to represent this
+        # with explicit JUMP_ABSOLUTE instructions that are optimized
+        # out when they are unnecessary.
+        #
+        # I think this strategy works: each block has a child
+        # designated as "next" which is returned as the last of the
+        # children.  because the nodes in a graph are emitted in
+        # reverse post order, the "next" block will always be emitted
+        # immediately after its parent.
+        # Worry: maintaining this invariant could be tricky
+        if block is None:
+            block = self.newBlock()
+
+        # Note: If the current block ends with an unconditional
+        # control transfer, then it is incorrect to add an implicit
+        # transfer to the block graph.  The current code requires
+        # these edges to get the blocks emitted in the right order,
+        # however. :-(  If a client needs to remove these edges, call
+        # pruneEdges().
+
+        self.current.addNext(block)
+        self.startBlock(block)
+
+    def newBlock(self):
+        b = Block()
+        self.blocks.add(b)
+        return b
+
+    def startExitBlock(self):
+        self.startBlock(self.exit)
+
+    _debug = 0
+
+    def _enable_debug(self):
+        self._debug = 1
+
+    def _disable_debug(self):
+        self._debug = 0
+
+    def emit(self, *inst):
+        if self._debug:
+            print "\t", inst
+        if inst[0] in ['RETURN_VALUE', 'YIELD_VALUE']:
+            self.current.addOutEdge(self.exit)
+        if len(inst) == 2 and isinstance(inst[1], Block):
+            self.current.addOutEdge(inst[1])
+        self.current.emit(inst)
+
+    def getBlocksInOrder(self):
+        """Return the blocks in reverse postorder
+
+        i.e. each node appears before all of its successors
+        """
+        # XXX make sure every node that doesn't have an explicit next
+        # is set so that next points to exit
+        for b in self.blocks.elements():
+            if b is self.exit:
+                continue
+            if not b.next:
+                b.addNext(self.exit)
+        order = dfs_postorder(self.entry, {})
+        order.reverse()
+        self.fixupOrder(order, self.exit)
+        # hack alert
+        if not self.exit in order:
+            order.append(self.exit)
+
+        return order
+
+    def fixupOrder(self, blocks, default_next):
+        """Fixup bad order introduced by DFS."""
+
+        # XXX This is a total mess.  There must be a better way to get
+        # the code blocks in the right order.
+
+        self.fixupOrderHonorNext(blocks, default_next)
+        self.fixupOrderForward(blocks, default_next)
+
+    def fixupOrderHonorNext(self, blocks, default_next):
+        """Fix one problem with DFS.
+
+        The DFS uses child block, but doesn't know about the special
+        "next" block.  As a result, the DFS can order blocks so that a
+        block isn't next to the right block for implicit control
+        transfers.
+        """
+        index = {}
+        for i in range(len(blocks)):
+            index[blocks[i]] = i
+
+        for i in range(0, len(blocks) - 1):
+            b = blocks[i]
+            n = blocks[i + 1]
+            if not b.next or b.next[0] == default_next or b.next[0] == n:
+                continue
+            # The blocks are in the wrong order.  Find the chain of
+            # blocks to insert where they belong.
+            cur = b
+            chain = []
+            elt = cur
+            while elt.next and elt.next[0] != default_next:
+                chain.append(elt.next[0])
+                elt = elt.next[0]
+            # Now remove the blocks in the chain from the current
+            # block list, so that they can be re-inserted.
+            l = []
+            for b in chain:
+                assert index[b] > i
+                l.append((index[b], b))
+            l.sort()
+            l.reverse()
+            for j, b in l:
+                del blocks[index[b]]
+            # Insert the chain in the proper location
+            blocks[i:i + 1] = [cur] + chain
+            # Finally, re-compute the block indexes
+            for i in range(len(blocks)):
+                index[blocks[i]] = i
+
+    def fixupOrderForward(self, blocks, default_next):
+        """Make sure all JUMP_FORWARDs jump forward"""
+        index = {}
+        chains = []
+        cur = []
+        for b in blocks:
+            index[b] = len(chains)
+            cur.append(b)
+            if b.next and b.next[0] == default_next:
+                chains.append(cur)
+                cur = []
+        chains.append(cur)
+
+        while 1:
+            constraints = []
+
+            for i in range(len(chains)):
+                l = chains[i]
+                for b in l:
+                    for c in b.get_children():
+                        if index[c] < i:
+                            forward_p = 0
+                            for inst in b.insts:
+                                if inst[0] == 'JUMP_FORWARD':
+                                    if inst[1] == c:
+                                        forward_p = 1
+                            if not forward_p:
+                                continue
+                            constraints.append((index[c], i))
+
+            if not constraints:
+                break
+
+            # XXX just do one for now
+            # do swaps to get things in the right order
+            goes_before, a_chain = constraints[0]
+            assert a_chain > goes_before
+            c = chains[a_chain]
+            chains.remove(c)
+            chains.insert(goes_before, c)
+
+        del blocks[:]
+        for c in chains:
+            for b in c:
+                blocks.append(b)
+
+    def getBlocks(self):
+        return self.blocks.elements()
+
+    def getRoot(self):
+        """Return nodes appropriate for use with dominator"""
+        return self.entry
+
+    def getContainedGraphs(self):
+        l = []
+        for b in self.getBlocks():
+            l.extend(b.getContainedGraphs())
+        return l
+
+def dfs_postorder(b, seen):
+    """Depth-first search of tree rooted at b, return in postorder"""
+    order = []
+    seen[b] = b
+    for c in b.get_children():
+        if seen.has_key(c):
+            continue
+        order = order + dfs_postorder(c, seen)
+    order.append(b)
+    return order
+
+class Block:
+    _count = 0
+
+    def __init__(self, label=''):
+        self.insts = []
+        self.inEdges = misc.Set()
+        self.outEdges = misc.Set()
+        self.label = label
+        self.bid = Block._count
+        self.next = []
+        Block._count = Block._count + 1
+
+    def __repr__(self):
+        if self.label:
+            return "<block %s id=%d>" % (self.label, self.bid)
+        else:
+            return "<block id=%d>" % (self.bid)
+
+    def __str__(self):
+        insts = map(str, self.insts)
+        return "<block %s %d:\n%s>" % (self.label, self.bid,
+                                       '\n'.join(insts))
+
+    def emit(self, inst):
+        op = inst[0]
+        if op[:4] == 'JUMP':
+            self.outEdges.add(inst[1])
+        self.insts.append(inst)
+
+    def getInstructions(self):
+        return self.insts
+
+    def addInEdge(self, block):
+        self.inEdges.add(block)
+
+    def addOutEdge(self, block):
+        self.outEdges.add(block)
+
+    def addNext(self, block):
+        self.next.append(block)
+        assert len(self.next) == 1, map(str, self.next)
+
+    _uncond_transfer = ('RETURN_VALUE', 'RAISE_VARARGS', 'YIELD_VALUE',
+                        'JUMP_ABSOLUTE', 'JUMP_FORWARD', 'CONTINUE_LOOP')
+
+    def pruneNext(self):
+        """Remove bogus edge for unconditional transfers
+
+        Each block has a next edge that accounts for implicit control
+        transfers, e.g. from a JUMP_IF_FALSE to the block that will be
+        executed if the test is true.
+
+        These edges must remain for the current assembler code to
+        work. If they are removed, the dfs_postorder gets things in
+        weird orders.  However, they shouldn't be there for other
+        purposes, e.g. conversion to SSA form.  This method will
+        remove the next edge when it follows an unconditional control
+        transfer.
+        """
+        try:
+            op, arg = self.insts[-1]
+        except (IndexError, ValueError):
+            return
+        if op in self._uncond_transfer:
+            self.next = []
+
+    def get_children(self):
+        if self.next and self.next[0] in self.outEdges:
+            self.outEdges.remove(self.next[0])
+        return self.outEdges.elements() + self.next
+
+    def getContainedGraphs(self):
+        """Return all graphs contained within this block.
+
+        For example, a MAKE_FUNCTION block will contain a reference to
+        the graph for the function body.
+        """
+        contained = []
+        for inst in self.insts:
+            if len(inst) == 1:
+                continue
+            op = inst[1]
+            if hasattr(op, 'graph'):
+                contained.append(op.graph)
+        return contained
+
+# flags for code objects
+
+# the FlowGraph is transformed in place; it exists in one of these states
+RAW = "RAW"
+FLAT = "FLAT"
+CONV = "CONV"
+DONE = "DONE"
+
+class PyFlowGraph(FlowGraph):
+    super_init = FlowGraph.__init__
+
+    def __init__(self, name, filename, args=(), optimized=0, klass=None):
+        self.super_init()
+        self.name = name
+        self.filename = filename
+        self.docstring = None
+        self.args = args # XXX
+        self.argcount = getArgCount(args)
+        self.klass = klass
+        if optimized:
+            self.flags = CO_OPTIMIZED | CO_NEWLOCALS
+        else:
+            self.flags = 0
+        self.consts = []
+        self.names = []
+        # Free variables found by the symbol table scan, including
+        # variables used only in nested scopes, are included here.
+        self.freevars = []
+        self.cellvars = []
+        # The closure list is used to track the order of cell
+        # variables and free variables in the resulting code object.
+        # The offsets used by LOAD_CLOSURE/LOAD_DEREF refer to both
+        # kinds of variables.
+        self.closure = []
+        self.varnames = list(args) or []
+        for i in range(len(self.varnames)):
+            var = self.varnames[i]
+            if isinstance(var, TupleArg):
+                self.varnames[i] = var.getName()
+        self.stage = RAW
+
+    def setDocstring(self, doc):
+        self.docstring = doc
+
+    def setFlag(self, flag):
+        self.flags = self.flags | flag
+        if flag == CO_VARARGS:
+            self.argcount = self.argcount - 1
+
+    def checkFlag(self, flag):
+        if self.flags & flag:
+            return 1
+
+    def setFreeVars(self, names):
+        self.freevars = list(names)
+
+    def setCellVars(self, names):
+        self.cellvars = names
+
+    def getCode(self):
+        """Get a Python code object"""
+        assert self.stage == RAW
+        self.computeStackDepth()
+        self.flattenGraph()
+        assert self.stage == FLAT
+        self.convertArgs()
+        assert self.stage == CONV
+        self.makeByteCode()
+        assert self.stage == DONE
+        return self.newCodeObject()
+
+    def dump(self, io=None):
+        if io:
+            save = sys.stdout
+            sys.stdout = io
+        pc = 0
+        for t in self.insts:
+            opname = t[0]
+            if opname == "SET_LINENO":
+                print
+            if len(t) == 1:
+                print "\t", "%3d" % pc, opname
+                pc = pc + 1
+            else:
+                print "\t", "%3d" % pc, opname, t[1]
+                pc = pc + 3
+        if io:
+            sys.stdout = save
+
+    def computeStackDepth(self):
+        """Compute the max stack depth.
+
+        Approach is to compute the stack effect of each basic block.
+        Then find the path through the code with the largest total
+        effect.
+        """
+        depth = {}
+        exit = None
+        for b in self.getBlocks():
+            depth[b] = findDepth(b.getInstructions())
+
+        seen = {}
+
+        def max_depth(b, d):
+            if seen.has_key(b):
+                return d
+            seen[b] = 1
+            d = d + depth[b]
+            children = b.get_children()
+            if children:
+                return max([max_depth(c, d) for c in children])
+            else:
+                if not b.label == "exit":
+                    return max_depth(self.exit, d)
+                else:
+                    return d
+
+        self.stacksize = max_depth(self.entry, 0)
+
+    def flattenGraph(self):
+        """Arrange the blocks in order and resolve jumps"""
+        assert self.stage == RAW
+        self.insts = insts = []
+        pc = 0
+        begin = {}
+        end = {}
+        for b in self.getBlocksInOrder():
+            begin[b] = pc
+            for inst in b.getInstructions():
+                insts.append(inst)
+                if len(inst) == 1:
+                    pc = pc + 1
+                elif inst[0] != "SET_LINENO":
+                    # arg takes 2 bytes
+                    pc = pc + 3
+            end[b] = pc
+        pc = 0
+        for i in range(len(insts)):
+            inst = insts[i]
+            if len(inst) == 1:
+                pc = pc + 1
+            elif inst[0] != "SET_LINENO":
+                pc = pc + 3
+            opname = inst[0]
+            if self.hasjrel.has_elt(opname):
+                oparg = inst[1]
+                offset = begin[oparg] - pc
+                insts[i] = opname, offset
+            elif self.hasjabs.has_elt(opname):
+                insts[i] = opname, begin[inst[1]]
+        self.stage = FLAT
+
+    hasjrel = misc.Set()
+    for i in dis.hasjrel:
+        hasjrel.add(dis.opname[i])
+    hasjabs = misc.Set()
+    for i in dis.hasjabs:
+        hasjabs.add(dis.opname[i])
+
+    def convertArgs(self):
+        """Convert arguments from symbolic to concrete form"""
+        assert self.stage == FLAT
+        self.consts.insert(0, self.docstring)
+        self.sort_cellvars()
+        for i in range(len(self.insts)):
+            t = self.insts[i]
+            if len(t) == 2:
+                opname, oparg = t
+                conv = self._converters.get(opname, None)
+                if conv:
+                    self.insts[i] = opname, conv(self, oparg)
+        self.stage = CONV
+
+    def sort_cellvars(self):
+        """Sort cellvars in the order of varnames and prune from freevars.
+        """
+        cells = {}
+        for name in self.cellvars:
+            cells[name] = 1
+        self.cellvars = [name for name in self.varnames
+                         if cells.has_key(name)]
+        for name in self.cellvars:
+            del cells[name]
+        self.cellvars = self.cellvars + cells.keys()
+        self.closure = self.cellvars + self.freevars
+
+    def _lookupName(self, name, list):
+        """Return index of name in list, appending if necessary
+
+        This routine uses a list instead of a dictionary, because a
+        dictionary can't store two different keys if the keys have the
+        same value but different types, e.g. 2 and 2L.  The compiler
+        must treat these two separately, so it does an explicit type
+        comparison before comparing the values.
+        """
+        t = type(name)
+        for i in range(len(list)):
+            if t == type(list[i]) and list[i] == name:
+                return i
+        end = len(list)
+        list.append(name)
+        return end
+
+    _converters = {}
+    def _convert_LOAD_CONST(self, arg):
+        if hasattr(arg, 'getCode'):
+            arg = arg.getCode()
+        return self._lookupName(arg, self.consts)
+
+    def _convert_LOAD_FAST(self, arg):
+        self._lookupName(arg, self.names)
+        return self._lookupName(arg, self.varnames)
+    _convert_STORE_FAST = _convert_LOAD_FAST
+    _convert_DELETE_FAST = _convert_LOAD_FAST
+
+    def _convert_LOAD_NAME(self, arg):
+        if self.klass is None:
+            self._lookupName(arg, self.varnames)
+        return self._lookupName(arg, self.names)
+
+    def _convert_NAME(self, arg):
+        if self.klass is None:
+            self._lookupName(arg, self.varnames)
+        return self._lookupName(arg, self.names)
+    _convert_STORE_NAME = _convert_NAME
+    _convert_DELETE_NAME = _convert_NAME
+    _convert_IMPORT_NAME = _convert_NAME
+    _convert_IMPORT_FROM = _convert_NAME
+    _convert_STORE_ATTR = _convert_NAME
+    _convert_LOAD_ATTR = _convert_NAME
+    _convert_DELETE_ATTR = _convert_NAME
+    _convert_LOAD_GLOBAL = _convert_NAME
+    _convert_STORE_GLOBAL = _convert_NAME
+    _convert_DELETE_GLOBAL = _convert_NAME
+
+    def _convert_DEREF(self, arg):
+        self._lookupName(arg, self.names)
+        self._lookupName(arg, self.varnames)
+        return self._lookupName(arg, self.closure)
+    _convert_LOAD_DEREF = _convert_DEREF
+    _convert_STORE_DEREF = _convert_DEREF
+
+    def _convert_LOAD_CLOSURE(self, arg):
+        self._lookupName(arg, self.varnames)
+        return self._lookupName(arg, self.closure)
+
+    _cmp = list(dis.cmp_op)
+    def _convert_COMPARE_OP(self, arg):
+        return self._cmp.index(arg)
+
+    # similarly for other opcodes...
+
+    for name, obj in locals().items():
+        if name[:9] == "_convert_":
+            opname = name[9:]
+            _converters[opname] = obj
+    del name, obj, opname
+
+    def makeByteCode(self):
+        assert self.stage == CONV
+        self.lnotab = lnotab = LineAddrTable()
+        for t in self.insts:
+            opname = t[0]
+            if len(t) == 1:
+                lnotab.addCode(self.opnum[opname])
+            else:
+                oparg = t[1]
+                if opname == "SET_LINENO":
+                    lnotab.nextLine(oparg)
+                    continue
+                hi, lo = twobyte(oparg)
+                try:
+                    lnotab.addCode(self.opnum[opname], lo, hi)
+                except ValueError:
+                    print opname, oparg
+                    print self.opnum[opname], lo, hi
+                    raise
+        self.stage = DONE
+
+    opnum = {}
+    for num in range(len(dis.opname)):
+        opnum[dis.opname[num]] = num
+    del num
+
+    def newCodeObject(self):
+        assert self.stage == DONE
+        if (self.flags & CO_NEWLOCALS) == 0:
+            nlocals = 0
+        else:
+            nlocals = len(self.varnames)
+        argcount = self.argcount
+        if self.flags & CO_VARKEYWORDS:
+            argcount = argcount - 1
+        return new.code(argcount, nlocals, self.stacksize, self.flags,
+                        self.lnotab.getCode(), self.getConsts(),
+                        tuple(self.names), tuple(self.varnames),
+                        self.filename, self.name, self.lnotab.firstline,
+                        self.lnotab.getTable(), tuple(self.freevars),
+                        tuple(self.cellvars))
+
+    def getConsts(self):
+        """Return a tuple for the const slot of the code object
+
+        Must convert references to code (MAKE_FUNCTION) to code
+        objects recursively.
+        """
+        l = []
+        for elt in self.consts:
+            if isinstance(elt, PyFlowGraph):
+                elt = elt.getCode()
+            l.append(elt)
+        return tuple(l)
+
+def isJump(opname):
+    if opname[:4] == 'JUMP':
+        return 1
+
+class TupleArg:
+    """Helper for marking func defs with nested tuples in arglist"""
+    def __init__(self, count, names):
+        self.count = count
+        self.names = names
+    def __repr__(self):
+        return "TupleArg(%s, %s)" % (self.count, self.names)
+    def getName(self):
+        return ".%d" % self.count
+
+def getArgCount(args):
+    argcount = len(args)
+    if args:
+        for arg in args:
+            if isinstance(arg, TupleArg):
+                numNames = len(misc.flatten(arg.names))
+                argcount = argcount - numNames
+    return argcount
+
+def twobyte(val):
+    """Convert an int argument into high and low bytes"""
+    assert isinstance(val, int)
+    return divmod(val, 256)
+
+class LineAddrTable:
+    """lnotab
+
+    This class builds the lnotab, which is documented in compile.c.
+    Here's a brief recap:
+
+    For each SET_LINENO instruction after the first one, two bytes are
+    added to lnotab.  (In some cases, multiple two-byte entries are
+    added.)  The first byte is the distance in bytes between the
+    instruction for the last SET_LINENO and the current SET_LINENO.
+    The second byte is offset in line numbers.  If either offset is
+    greater than 255, multiple two-byte entries are added -- see
+    compile.c for the delicate details.
+    """
+
+    def __init__(self):
+        self.code = []
+        self.codeOffset = 0
+        self.firstline = 0
+        self.lastline = 0
+        self.lastoff = 0
+        self.lnotab = []
+
+    def addCode(self, *args):
+        for arg in args:
+            self.code.append(chr(arg))
+        self.codeOffset = self.codeOffset + len(args)
+
+    def nextLine(self, lineno):
+        if self.firstline == 0:
+            self.firstline = lineno
+            self.lastline = lineno
+        else:
+            # compute deltas
+            addr = self.codeOffset - self.lastoff
+            line = lineno - self.lastline
+            # Python assumes that lineno always increases with
+            # increasing bytecode address (lnotab is unsigned char).
+            # Depending on when SET_LINENO instructions are emitted
+            # this is not always true.  Consider the code:
+            #     a = (1,
+            #          b)
+            # In the bytecode stream, the assignment to "a" occurs
+            # after the loading of "b".  This works with the C Python
+            # compiler because it only generates a SET_LINENO instruction
+            # for the assignment.
+            if line >= 0:
+                push = self.lnotab.append
+                while addr > 255:
+                    push(255); push(0)
+                    addr -= 255
+                while line > 255:
+                    push(addr); push(255)
+                    line -= 255
+                    addr = 0
+                if addr > 0 or line > 0:
+                    push(addr); push(line)
+                self.lastline = lineno
+                self.lastoff = self.codeOffset
+
+    def getCode(self):
+        return ''.join(self.code)
+
+    def getTable(self):
+        return ''.join(map(chr, self.lnotab))
+
+class StackDepthTracker:
+    # XXX 1. need to keep track of stack depth on jumps
+    # XXX 2. at least partly as a result, this code is broken
+
+    def findDepth(self, insts, debug=0):
+        depth = 0
+        maxDepth = 0
+        for i in insts:
+            opname = i[0]
+            if debug:
+                print i,
+            delta = self.effect.get(opname, None)
+            if delta is not None:
+                depth = depth + delta
+            else:
+                # now check patterns
+                for pat, pat_delta in self.patterns:
+                    if opname[:len(pat)] == pat:
+                        delta = pat_delta
+                        depth = depth + delta
+                        break
+                # if we still haven't found a match
+                if delta is None:
+                    meth = getattr(self, opname, None)
+                    if meth is not None:
+                        depth = depth + meth(i[1])
+            if depth > maxDepth:
+                maxDepth = depth
+            if debug:
+                print depth, maxDepth
+        return maxDepth
+
+    effect = {
+        'POP_TOP': -1,
+        'DUP_TOP': 1,
+        'LIST_APPEND': -2,
+        'SLICE+1': -1,
+        'SLICE+2': -1,
+        'SLICE+3': -2,
+        'STORE_SLICE+0': -1,
+        'STORE_SLICE+1': -2,
+        'STORE_SLICE+2': -2,
+        'STORE_SLICE+3': -3,
+        'DELETE_SLICE+0': -1,
+        'DELETE_SLICE+1': -2,
+        'DELETE_SLICE+2': -2,
+        'DELETE_SLICE+3': -3,
+        'STORE_SUBSCR': -3,
+        'DELETE_SUBSCR': -2,
+        # PRINT_EXPR?
+        'PRINT_ITEM': -1,
+        'RETURN_VALUE': -1,
+        'YIELD_VALUE': -1,
+        'EXEC_STMT': -3,
+        'BUILD_CLASS': -2,
+        'STORE_NAME': -1,
+        'STORE_ATTR': -2,
+        'DELETE_ATTR': -1,
+        'STORE_GLOBAL': -1,
+        'BUILD_MAP': 1,
+        'COMPARE_OP': -1,
+        'STORE_FAST': -1,
+        'IMPORT_STAR': -1,
+        'IMPORT_NAME': -1,
+        'IMPORT_FROM': 1,
+        'LOAD_ATTR': 0, # unlike other loads
+        # close enough...
+        'SETUP_EXCEPT': 3,
+        'SETUP_FINALLY': 3,
+        'FOR_ITER': 1,
+        'WITH_CLEANUP': -1,
+        }
+    # use pattern match
+    patterns = [
+        ('BINARY_', -1),
+        ('LOAD_', 1),
+        ]
+
+    def UNPACK_SEQUENCE(self, count):
+        return count-1
+    def BUILD_TUPLE(self, count):
+        return -count+1
+    def BUILD_LIST(self, count):
+        return -count+1
+    def CALL_FUNCTION(self, argc):
+        hi, lo = divmod(argc, 256)
+        return -(lo + hi * 2)
+    def CALL_FUNCTION_VAR(self, argc):
+        return self.CALL_FUNCTION(argc)-1
+    def CALL_FUNCTION_KW(self, argc):
+        return self.CALL_FUNCTION(argc)-1
+    def CALL_FUNCTION_VAR_KW(self, argc):
+        return self.CALL_FUNCTION(argc)-2
+    def MAKE_FUNCTION(self, argc):
+        return -argc
+    def MAKE_CLOSURE(self, argc):
+        # XXX need to account for free variables too!
+        return -argc
+    def BUILD_SLICE(self, argc):
+        if argc == 2:
+            return -1
+        elif argc == 3:
+            return -2
+    def DUP_TOPX(self, argc):
+        return argc
+
+findDepth = StackDepthTracker().findDepth

Added: vendor/Python/current/Lib/compiler/pycodegen.py
===================================================================
--- vendor/Python/current/Lib/compiler/pycodegen.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/compiler/pycodegen.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1533 @@
+import imp
+import os
+import marshal
+import struct
+import sys
+from cStringIO import StringIO
+
+from compiler import ast, parse, walk, syntax
+from compiler import pyassem, misc, future, symbols
+from compiler.consts import SC_LOCAL, SC_GLOBAL, SC_FREE, SC_CELL
+from compiler.consts import (CO_VARARGS, CO_VARKEYWORDS, CO_NEWLOCALS,
+     CO_NESTED, CO_GENERATOR, CO_FUTURE_DIVISION,
+     CO_FUTURE_ABSIMPORT, CO_FUTURE_WITH_STATEMENT)
+from compiler.pyassem import TupleArg
+
+# XXX The version-specific code can go, since this code only works with 2.x.
+# Do we have Python 1.x or Python 2.x?
+try:
+    VERSION = sys.version_info[0]
+except AttributeError:
+    VERSION = 1
+
+callfunc_opcode_info = {
+    # (Have *args, Have **args) : opcode
+    (0,0) : "CALL_FUNCTION",
+    (1,0) : "CALL_FUNCTION_VAR",
+    (0,1) : "CALL_FUNCTION_KW",
+    (1,1) : "CALL_FUNCTION_VAR_KW",
+}
+
+LOOP = 1
+EXCEPT = 2
+TRY_FINALLY = 3
+END_FINALLY = 4
+
+def compileFile(filename, display=0):
+    f = open(filename, 'U')
+    buf = f.read()
+    f.close()
+    mod = Module(buf, filename)
+    try:
+        mod.compile(display)
+    except SyntaxError:
+        raise
+    else:
+        f = open(filename + "c", "wb")
+        mod.dump(f)
+        f.close()
+
+def compile(source, filename, mode, flags=None, dont_inherit=None):
+    """Replacement for builtin compile() function"""
+    if flags is not None or dont_inherit is not None:
+        raise RuntimeError, "not implemented yet"
+
+    if mode == "single":
+        gen = Interactive(source, filename)
+    elif mode == "exec":
+        gen = Module(source, filename)
+    elif mode == "eval":
+        gen = Expression(source, filename)
+    else:
+        raise ValueError("compile() 3rd arg must be 'exec' or "
+                         "'eval' or 'single'")
+    gen.compile()
+    return gen.code
+
+class AbstractCompileMode:
+
+    mode = None # defined by subclass
+
+    def __init__(self, source, filename):
+        self.source = source
+        self.filename = filename
+        self.code = None
+
+    def _get_tree(self):
+        tree = parse(self.source, self.mode)
+        misc.set_filename(self.filename, tree)
+        syntax.check(tree)
+        return tree
+
+    def compile(self):
+        pass # implemented by subclass
+
+    def getCode(self):
+        return self.code
+
+class Expression(AbstractCompileMode):
+
+    mode = "eval"
+
+    def compile(self):
+        tree = self._get_tree()
+        gen = ExpressionCodeGenerator(tree)
+        self.code = gen.getCode()
+
+class Interactive(AbstractCompileMode):
+
+    mode = "single"
+
+    def compile(self):
+        tree = self._get_tree()
+        gen = InteractiveCodeGenerator(tree)
+        self.code = gen.getCode()
+
+class Module(AbstractCompileMode):
+
+    mode = "exec"
+
+    def compile(self, display=0):
+        tree = self._get_tree()
+        gen = ModuleCodeGenerator(tree)
+        if display:
+            import pprint
+            print pprint.pprint(tree)
+        self.code = gen.getCode()
+
+    def dump(self, f):
+        f.write(self.getPycHeader())
+        marshal.dump(self.code, f)
+
+    MAGIC = imp.get_magic()
+
+    def getPycHeader(self):
+        # compile.c uses marshal to write a long directly, with
+        # calling the interface that would also generate a 1-byte code
+        # to indicate the type of the value.  simplest way to get the
+        # same effect is to call marshal and then skip the code.
+        mtime = os.path.getmtime(self.filename)
+        mtime = struct.pack('<i', mtime)
+        return self.MAGIC + mtime
+
+class LocalNameFinder:
+    """Find local names in scope"""
+    def __init__(self, names=()):
+        self.names = misc.Set()
+        self.globals = misc.Set()
+        for name in names:
+            self.names.add(name)
+
+    # XXX list comprehensions and for loops
+
+    def getLocals(self):
+        for elt in self.globals.elements():
+            if self.names.has_elt(elt):
+                self.names.remove(elt)
+        return self.names
+
+    def visitDict(self, node):
+        pass
+
+    def visitGlobal(self, node):
+        for name in node.names:
+            self.globals.add(name)
+
+    def visitFunction(self, node):
+        self.names.add(node.name)
+
+    def visitLambda(self, node):
+        pass
+
+    def visitImport(self, node):
+        for name, alias in node.names:
+            self.names.add(alias or name)
+
+    def visitFrom(self, node):
+        for name, alias in node.names:
+            self.names.add(alias or name)
+
+    def visitClass(self, node):
+        self.names.add(node.name)
+
+    def visitAssName(self, node):
+        self.names.add(node.name)
+
+def is_constant_false(node):
+    if isinstance(node, ast.Const):
+        if not node.value:
+            return 1
+    return 0
+
+class CodeGenerator:
+    """Defines basic code generator for Python bytecode
+
+    This class is an abstract base class.  Concrete subclasses must
+    define an __init__() that defines self.graph and then calls the
+    __init__() defined in this class.
+
+    The concrete class must also define the class attributes
+    NameFinder, FunctionGen, and ClassGen.  These attributes can be
+    defined in the initClass() method, which is a hook for
+    initializing these methods after all the classes have been
+    defined.
+    """
+
+    optimized = 0 # is namespace access optimized?
+    __initialized = None
+    class_name = None # provide default for instance variable
+
+    def __init__(self):
+        if self.__initialized is None:
+            self.initClass()
+            self.__class__.__initialized = 1
+        self.checkClass()
+        self.locals = misc.Stack()
+        self.setups = misc.Stack()
+        self.last_lineno = None
+        self._setupGraphDelegation()
+        self._div_op = "BINARY_DIVIDE"
+
+        # XXX set flags based on future features
+        futures = self.get_module().futures
+        for feature in futures:
+            if feature == "division":
+                self.graph.setFlag(CO_FUTURE_DIVISION)
+                self._div_op = "BINARY_TRUE_DIVIDE"
+            elif feature == "absolute_import":
+                self.graph.setFlag(CO_FUTURE_ABSIMPORT)
+            elif feature == "with_statement":
+                self.graph.setFlag(CO_FUTURE_WITH_STATEMENT)
+
+    def initClass(self):
+        """This method is called once for each class"""
+
+    def checkClass(self):
+        """Verify that class is constructed correctly"""
+        try:
+            assert hasattr(self, 'graph')
+            assert getattr(self, 'NameFinder')
+            assert getattr(self, 'FunctionGen')
+            assert getattr(self, 'ClassGen')
+        except AssertionError, msg:
+            intro = "Bad class construction for %s" % self.__class__.__name__
+            raise AssertionError, intro
+
+    def _setupGraphDelegation(self):
+        self.emit = self.graph.emit
+        self.newBlock = self.graph.newBlock
+        self.startBlock = self.graph.startBlock
+        self.nextBlock = self.graph.nextBlock
+        self.setDocstring = self.graph.setDocstring
+
+    def getCode(self):
+        """Return a code object"""
+        return self.graph.getCode()
+
+    def mangle(self, name):
+        if self.class_name is not None:
+            return misc.mangle(name, self.class_name)
+        else:
+            return name
+
+    def parseSymbols(self, tree):
+        s = symbols.SymbolVisitor()
+        walk(tree, s)
+        return s.scopes
+
+    def get_module(self):
+        raise RuntimeError, "should be implemented by subclasses"
+
+    # Next five methods handle name access
+
+    def isLocalName(self, name):
+        return self.locals.top().has_elt(name)
+
+    def storeName(self, name):
+        self._nameOp('STORE', name)
+
+    def loadName(self, name):
+        self._nameOp('LOAD', name)
+
+    def delName(self, name):
+        self._nameOp('DELETE', name)
+
+    def _nameOp(self, prefix, name):
+        name = self.mangle(name)
+        scope = self.scope.check_name(name)
+        if scope == SC_LOCAL:
+            if not self.optimized:
+                self.emit(prefix + '_NAME', name)
+            else:
+                self.emit(prefix + '_FAST', name)
+        elif scope == SC_GLOBAL:
+            if not self.optimized:
+                self.emit(prefix + '_NAME', name)
+            else:
+                self.emit(prefix + '_GLOBAL', name)
+        elif scope == SC_FREE or scope == SC_CELL:
+            self.emit(prefix + '_DEREF', name)
+        else:
+            raise RuntimeError, "unsupported scope for var %s: %d" % \
+                  (name, scope)
+
+    def _implicitNameOp(self, prefix, name):
+        """Emit name ops for names generated implicitly by for loops
+
+        The interpreter generates names that start with a period or
+        dollar sign.  The symbol table ignores these names because
+        they aren't present in the program text.
+        """
+        if self.optimized:
+            self.emit(prefix + '_FAST', name)
+        else:
+            self.emit(prefix + '_NAME', name)
+
+    # The set_lineno() function and the explicit emit() calls for
+    # SET_LINENO below are only used to generate the line number table.
+    # As of Python 2.3, the interpreter does not have a SET_LINENO
+    # instruction.  pyassem treats SET_LINENO opcodes as a special case.
+
+    def set_lineno(self, node, force=False):
+        """Emit SET_LINENO if necessary.
+
+        The instruction is considered necessary if the node has a
+        lineno attribute and it is different than the last lineno
+        emitted.
+
+        Returns true if SET_LINENO was emitted.
+
+        There are no rules for when an AST node should have a lineno
+        attribute.  The transformer and AST code need to be reviewed
+        and a consistent policy implemented and documented.  Until
+        then, this method works around missing line numbers.
+        """
+        lineno = getattr(node, 'lineno', None)
+        if lineno is not None and (lineno != self.last_lineno
+                                   or force):
+            self.emit('SET_LINENO', lineno)
+            self.last_lineno = lineno
+            return True
+        return False
+
+    # The first few visitor methods handle nodes that generator new
+    # code objects.  They use class attributes to determine what
+    # specialized code generators to use.
+
+    NameFinder = LocalNameFinder
+    FunctionGen = None
+    ClassGen = None
+
+    def visitModule(self, node):
+        self.scopes = self.parseSymbols(node)
+        self.scope = self.scopes[node]
+        self.emit('SET_LINENO', 0)
+        if node.doc:
+            self.emit('LOAD_CONST', node.doc)
+            self.storeName('__doc__')
+        lnf = walk(node.node, self.NameFinder(), verbose=0)
+        self.locals.push(lnf.getLocals())
+        self.visit(node.node)
+        self.emit('LOAD_CONST', None)
+        self.emit('RETURN_VALUE')
+
+    def visitExpression(self, node):
+        self.set_lineno(node)
+        self.scopes = self.parseSymbols(node)
+        self.scope = self.scopes[node]
+        self.visit(node.node)
+        self.emit('RETURN_VALUE')
+
+    def visitFunction(self, node):
+        self._visitFuncOrLambda(node, isLambda=0)
+        if node.doc:
+            self.setDocstring(node.doc)
+        self.storeName(node.name)
+
+    def visitLambda(self, node):
+        self._visitFuncOrLambda(node, isLambda=1)
+
+    def _visitFuncOrLambda(self, node, isLambda=0):
+        if not isLambda and node.decorators:
+            for decorator in node.decorators.nodes:
+                self.visit(decorator)
+            ndecorators = len(node.decorators.nodes)
+        else:
+            ndecorators = 0
+
+        gen = self.FunctionGen(node, self.scopes, isLambda,
+                               self.class_name, self.get_module())
+        walk(node.code, gen)
+        gen.finish()
+        self.set_lineno(node)
+        for default in node.defaults:
+            self.visit(default)
+        self._makeClosure(gen, len(node.defaults))
+        for i in range(ndecorators):
+            self.emit('CALL_FUNCTION', 1)
+
+    def visitClass(self, node):
+        gen = self.ClassGen(node, self.scopes,
+                            self.get_module())
+        walk(node.code, gen)
+        gen.finish()
+        self.set_lineno(node)
+        self.emit('LOAD_CONST', node.name)
+        for base in node.bases:
+            self.visit(base)
+        self.emit('BUILD_TUPLE', len(node.bases))
+        self._makeClosure(gen, 0)
+        self.emit('CALL_FUNCTION', 0)
+        self.emit('BUILD_CLASS')
+        self.storeName(node.name)
+
+    # The rest are standard visitor methods
+
+    # The next few implement control-flow statements
+
+    def visitIf(self, node):
+        end = self.newBlock()
+        numtests = len(node.tests)
+        for i in range(numtests):
+            test, suite = node.tests[i]
+            if is_constant_false(test):
+                # XXX will need to check generator stuff here
+                continue
+            self.set_lineno(test)
+            self.visit(test)
+            nextTest = self.newBlock()
+            self.emit('JUMP_IF_FALSE', nextTest)
+            self.nextBlock()
+            self.emit('POP_TOP')
+            self.visit(suite)
+            self.emit('JUMP_FORWARD', end)
+            self.startBlock(nextTest)
+            self.emit('POP_TOP')
+        if node.else_:
+            self.visit(node.else_)
+        self.nextBlock(end)
+
+    def visitWhile(self, node):
+        self.set_lineno(node)
+
+        loop = self.newBlock()
+        else_ = self.newBlock()
+
+        after = self.newBlock()
+        self.emit('SETUP_LOOP', after)
+
+        self.nextBlock(loop)
+        self.setups.push((LOOP, loop))
+
+        self.set_lineno(node, force=True)
+        self.visit(node.test)
+        self.emit('JUMP_IF_FALSE', else_ or after)
+
+        self.nextBlock()
+        self.emit('POP_TOP')
+        self.visit(node.body)
+        self.emit('JUMP_ABSOLUTE', loop)
+
+        self.startBlock(else_) # or just the POPs if not else clause
+        self.emit('POP_TOP')
+        self.emit('POP_BLOCK')
+        self.setups.pop()
+        if node.else_:
+            self.visit(node.else_)
+        self.nextBlock(after)
+
+    def visitFor(self, node):
+        start = self.newBlock()
+        anchor = self.newBlock()
+        after = self.newBlock()
+        self.setups.push((LOOP, start))
+
+        self.set_lineno(node)
+        self.emit('SETUP_LOOP', after)
+        self.visit(node.list)
+        self.emit('GET_ITER')
+
+        self.nextBlock(start)
+        self.set_lineno(node, force=1)
+        self.emit('FOR_ITER', anchor)
+        self.visit(node.assign)
+        self.visit(node.body)
+        self.emit('JUMP_ABSOLUTE', start)
+        self.nextBlock(anchor)
+        self.emit('POP_BLOCK')
+        self.setups.pop()
+        if node.else_:
+            self.visit(node.else_)
+        self.nextBlock(after)
+
+    def visitBreak(self, node):
+        if not self.setups:
+            raise SyntaxError, "'break' outside loop (%s, %d)" % \
+                  (node.filename, node.lineno)
+        self.set_lineno(node)
+        self.emit('BREAK_LOOP')
+
+    def visitContinue(self, node):
+        if not self.setups:
+            raise SyntaxError, "'continue' outside loop (%s, %d)" % \
+                  (node.filename, node.lineno)
+        kind, block = self.setups.top()
+        if kind == LOOP:
+            self.set_lineno(node)
+            self.emit('JUMP_ABSOLUTE', block)
+            self.nextBlock()
+        elif kind == EXCEPT or kind == TRY_FINALLY:
+            self.set_lineno(node)
+            # find the block that starts the loop
+            top = len(self.setups)
+            while top > 0:
+                top = top - 1
+                kind, loop_block = self.setups[top]
+                if kind == LOOP:
+                    break
+            if kind != LOOP:
+                raise SyntaxError, "'continue' outside loop (%s, %d)" % \
+                      (node.filename, node.lineno)
+            self.emit('CONTINUE_LOOP', loop_block)
+            self.nextBlock()
+        elif kind == END_FINALLY:
+            msg = "'continue' not allowed inside 'finally' clause (%s, %d)"
+            raise SyntaxError, msg % (node.filename, node.lineno)
+
+    def visitTest(self, node, jump):
+        end = self.newBlock()
+        for child in node.nodes[:-1]:
+            self.visit(child)
+            self.emit(jump, end)
+            self.nextBlock()
+            self.emit('POP_TOP')
+        self.visit(node.nodes[-1])
+        self.nextBlock(end)
+
+    def visitAnd(self, node):
+        self.visitTest(node, 'JUMP_IF_FALSE')
+
+    def visitOr(self, node):
+        self.visitTest(node, 'JUMP_IF_TRUE')
+
+    def visitIfExp(self, node):
+        endblock = self.newBlock()
+        elseblock = self.newBlock()
+        self.visit(node.test)
+        self.emit('JUMP_IF_FALSE', elseblock)
+        self.emit('POP_TOP')
+        self.visit(node.then)
+        self.emit('JUMP_FORWARD', endblock)
+        self.nextBlock(elseblock)
+        self.emit('POP_TOP')
+        self.visit(node.else_)
+        self.nextBlock(endblock)
+
+    def visitCompare(self, node):
+        self.visit(node.expr)
+        cleanup = self.newBlock()
+        for op, code in node.ops[:-1]:
+            self.visit(code)
+            self.emit('DUP_TOP')
+            self.emit('ROT_THREE')
+            self.emit('COMPARE_OP', op)
+            self.emit('JUMP_IF_FALSE', cleanup)
+            self.nextBlock()
+            self.emit('POP_TOP')
+        # now do the last comparison
+        if node.ops:
+            op, code = node.ops[-1]
+            self.visit(code)
+            self.emit('COMPARE_OP', op)
+        if len(node.ops) > 1:
+            end = self.newBlock()
+            self.emit('JUMP_FORWARD', end)
+            self.startBlock(cleanup)
+            self.emit('ROT_TWO')
+            self.emit('POP_TOP')
+            self.nextBlock(end)
+
+    # list comprehensions
+    __list_count = 0
+
+    def visitListComp(self, node):
+        self.set_lineno(node)
+        # setup list
+        append = "$append%d" % self.__list_count
+        self.__list_count = self.__list_count + 1
+        self.emit('BUILD_LIST', 0)
+        self.emit('DUP_TOP')
+        self.emit('LOAD_ATTR', 'append')
+        self._implicitNameOp('STORE', append)
+
+        stack = []
+        for i, for_ in zip(range(len(node.quals)), node.quals):
+            start, anchor = self.visit(for_)
+            cont = None
+            for if_ in for_.ifs:
+                if cont is None:
+                    cont = self.newBlock()
+                self.visit(if_, cont)
+            stack.insert(0, (start, cont, anchor))
+
+        self._implicitNameOp('LOAD', append)
+        self.visit(node.expr)
+        self.emit('CALL_FUNCTION', 1)
+        self.emit('POP_TOP')
+
+        for start, cont, anchor in stack:
+            if cont:
+                skip_one = self.newBlock()
+                self.emit('JUMP_FORWARD', skip_one)
+                self.startBlock(cont)
+                self.emit('POP_TOP')
+                self.nextBlock(skip_one)
+            self.emit('JUMP_ABSOLUTE', start)
+            self.startBlock(anchor)
+        self._implicitNameOp('DELETE', append)
+
+        self.__list_count = self.__list_count - 1
+
+    def visitListCompFor(self, node):
+        start = self.newBlock()
+        anchor = self.newBlock()
+
+        self.visit(node.list)
+        self.emit('GET_ITER')
+        self.nextBlock(start)
+        self.set_lineno(node, force=True)
+        self.emit('FOR_ITER', anchor)
+        self.nextBlock()
+        self.visit(node.assign)
+        return start, anchor
+
+    def visitListCompIf(self, node, branch):
+        self.set_lineno(node, force=True)
+        self.visit(node.test)
+        self.emit('JUMP_IF_FALSE', branch)
+        self.newBlock()
+        self.emit('POP_TOP')
+
+    def _makeClosure(self, gen, args):
+        frees = gen.scope.get_free_vars()
+        if frees:
+            for name in frees:
+                self.emit('LOAD_CLOSURE', name)
+            self.emit('BUILD_TUPLE', len(frees))
+            self.emit('LOAD_CONST', gen)
+            self.emit('MAKE_CLOSURE', args)
+        else:
+            self.emit('LOAD_CONST', gen)
+            self.emit('MAKE_FUNCTION', args)
+
+    def visitGenExpr(self, node):
+        gen = GenExprCodeGenerator(node, self.scopes, self.class_name,
+                                   self.get_module())
+        walk(node.code, gen)
+        gen.finish()
+        self.set_lineno(node)
+        self._makeClosure(gen, 0)
+        # precomputation of outmost iterable
+        self.visit(node.code.quals[0].iter)
+        self.emit('GET_ITER')
+        self.emit('CALL_FUNCTION', 1)
+
+    def visitGenExprInner(self, node):
+        self.set_lineno(node)
+        # setup list
+
+        stack = []
+        for i, for_ in zip(range(len(node.quals)), node.quals):
+            start, anchor, end = self.visit(for_)
+            cont = None
+            for if_ in for_.ifs:
+                if cont is None:
+                    cont = self.newBlock()
+                self.visit(if_, cont)
+            stack.insert(0, (start, cont, anchor, end))
+
+        self.visit(node.expr)
+        self.emit('YIELD_VALUE')
+        self.emit('POP_TOP')
+
+        for start, cont, anchor, end in stack:
+            if cont:
+                skip_one = self.newBlock()
+                self.emit('JUMP_FORWARD', skip_one)
+                self.startBlock(cont)
+                self.emit('POP_TOP')
+                self.nextBlock(skip_one)
+            self.emit('JUMP_ABSOLUTE', start)
+            self.startBlock(anchor)
+            self.emit('POP_BLOCK')
+            self.setups.pop()
+            self.startBlock(end)
+
+        self.emit('LOAD_CONST', None)
+
+    def visitGenExprFor(self, node):
+        start = self.newBlock()
+        anchor = self.newBlock()
+        end = self.newBlock()
+
+        self.setups.push((LOOP, start))
+        self.emit('SETUP_LOOP', end)
+
+        if node.is_outmost:
+            self.loadName('.0')
+        else:
+            self.visit(node.iter)
+            self.emit('GET_ITER')
+
+        self.nextBlock(start)
+        self.set_lineno(node, force=True)
+        self.emit('FOR_ITER', anchor)
+        self.nextBlock()
+        self.visit(node.assign)
+        return start, anchor, end
+
+    def visitGenExprIf(self, node, branch):
+        self.set_lineno(node, force=True)
+        self.visit(node.test)
+        self.emit('JUMP_IF_FALSE', branch)
+        self.newBlock()
+        self.emit('POP_TOP')
+
+    # exception related
+
+    def visitAssert(self, node):
+        # XXX would be interesting to implement this via a
+        # transformation of the AST before this stage
+        if __debug__:
+            end = self.newBlock()
+            self.set_lineno(node)
+            # XXX AssertionError appears to be special case -- it is always
+            # loaded as a global even if there is a local name.  I guess this
+            # is a sort of renaming op.
+            self.nextBlock()
+            self.visit(node.test)
+            self.emit('JUMP_IF_TRUE', end)
+            self.nextBlock()
+            self.emit('POP_TOP')
+            self.emit('LOAD_GLOBAL', 'AssertionError')
+            if node.fail:
+                self.visit(node.fail)
+                self.emit('RAISE_VARARGS', 2)
+            else:
+                self.emit('RAISE_VARARGS', 1)
+            self.nextBlock(end)
+            self.emit('POP_TOP')
+
+    def visitRaise(self, node):
+        self.set_lineno(node)
+        n = 0
+        if node.expr1:
+            self.visit(node.expr1)
+            n = n + 1
+        if node.expr2:
+            self.visit(node.expr2)
+            n = n + 1
+        if node.expr3:
+            self.visit(node.expr3)
+            n = n + 1
+        self.emit('RAISE_VARARGS', n)
+
+    def visitTryExcept(self, node):
+        body = self.newBlock()
+        handlers = self.newBlock()
+        end = self.newBlock()
+        if node.else_:
+            lElse = self.newBlock()
+        else:
+            lElse = end
+        self.set_lineno(node)
+        self.emit('SETUP_EXCEPT', handlers)
+        self.nextBlock(body)
+        self.setups.push((EXCEPT, body))
+        self.visit(node.body)
+        self.emit('POP_BLOCK')
+        self.setups.pop()
+        self.emit('JUMP_FORWARD', lElse)
+        self.startBlock(handlers)
+
+        last = len(node.handlers) - 1
+        for i in range(len(node.handlers)):
+            expr, target, body = node.handlers[i]
+            self.set_lineno(expr)
+            if expr:
+                self.emit('DUP_TOP')
+                self.visit(expr)
+                self.emit('COMPARE_OP', 'exception match')
+                next = self.newBlock()
+                self.emit('JUMP_IF_FALSE', next)
+                self.nextBlock()
+                self.emit('POP_TOP')
+            self.emit('POP_TOP')
+            if target:
+                self.visit(target)
+            else:
+                self.emit('POP_TOP')
+            self.emit('POP_TOP')
+            self.visit(body)
+            self.emit('JUMP_FORWARD', end)
+            if expr:
+                self.nextBlock(next)
+            else:
+                self.nextBlock()
+            if expr: # XXX
+                self.emit('POP_TOP')
+        self.emit('END_FINALLY')
+        if node.else_:
+            self.nextBlock(lElse)
+            self.visit(node.else_)
+        self.nextBlock(end)
+
+    def visitTryFinally(self, node):
+        body = self.newBlock()
+        final = self.newBlock()
+        self.set_lineno(node)
+        self.emit('SETUP_FINALLY', final)
+        self.nextBlock(body)
+        self.setups.push((TRY_FINALLY, body))
+        self.visit(node.body)
+        self.emit('POP_BLOCK')
+        self.setups.pop()
+        self.emit('LOAD_CONST', None)
+        self.nextBlock(final)
+        self.setups.push((END_FINALLY, final))
+        self.visit(node.final)
+        self.emit('END_FINALLY')
+        self.setups.pop()
+
+    __with_count = 0
+
+    def visitWith(self, node):
+        body = self.newBlock()
+        final = self.newBlock()
+        exitvar = "$exit%d" % self.__with_count
+        valuevar = "$value%d" % self.__with_count
+        self.__with_count += 1
+        self.set_lineno(node)
+        self.visit(node.expr)
+        self.emit('DUP_TOP')
+        self.emit('LOAD_ATTR', '__exit__')
+        self._implicitNameOp('STORE', exitvar)
+        self.emit('LOAD_ATTR', '__enter__')
+        self.emit('CALL_FUNCTION', 0)
+        if node.vars is None:
+            self.emit('POP_TOP')
+        else:
+            self._implicitNameOp('STORE', valuevar)
+        self.emit('SETUP_FINALLY', final)
+        self.nextBlock(body)
+        self.setups.push((TRY_FINALLY, body))
+        if node.vars is not None:
+            self._implicitNameOp('LOAD', valuevar)
+            self._implicitNameOp('DELETE', valuevar)
+            self.visit(node.vars)
+        self.visit(node.body)
+        self.emit('POP_BLOCK')
+        self.setups.pop()
+        self.emit('LOAD_CONST', None)
+        self.nextBlock(final)
+        self.setups.push((END_FINALLY, final))
+        self._implicitNameOp('LOAD', exitvar)
+        self._implicitNameOp('DELETE', exitvar)
+        self.emit('WITH_CLEANUP')
+        self.emit('END_FINALLY')
+        self.setups.pop()
+        self.__with_count -= 1
+
+    # misc
+
+    def visitDiscard(self, node):
+        self.set_lineno(node)
+        self.visit(node.expr)
+        self.emit('POP_TOP')
+
+    def visitConst(self, node):
+        self.emit('LOAD_CONST', node.value)
+
+    def visitKeyword(self, node):
+        self.emit('LOAD_CONST', node.name)
+        self.visit(node.expr)
+
+    def visitGlobal(self, node):
+        # no code to generate
+        pass
+
+    def visitName(self, node):
+        self.set_lineno(node)
+        self.loadName(node.name)
+
+    def visitPass(self, node):
+        self.set_lineno(node)
+
+    def visitImport(self, node):
+        self.set_lineno(node)
+        level = 0 if self.graph.checkFlag(CO_FUTURE_ABSIMPORT) else -1
+        for name, alias in node.names:
+            if VERSION > 1:
+                self.emit('LOAD_CONST', level)
+                self.emit('LOAD_CONST', None)
+            self.emit('IMPORT_NAME', name)
+            mod = name.split(".")[0]
+            if alias:
+                self._resolveDots(name)
+                self.storeName(alias)
+            else:
+                self.storeName(mod)
+
+    def visitFrom(self, node):
+        self.set_lineno(node)
+        level = node.level
+        if level == 0 and not self.graph.checkFlag(CO_FUTURE_ABSIMPORT):
+            level = -1
+        fromlist = map(lambda (name, alias): name, node.names)
+        if VERSION > 1:
+            self.emit('LOAD_CONST', level)
+            self.emit('LOAD_CONST', tuple(fromlist))
+        self.emit('IMPORT_NAME', node.modname)
+        for name, alias in node.names:
+            if VERSION > 1:
+                if name == '*':
+                    self.namespace = 0
+                    self.emit('IMPORT_STAR')
+                    # There can only be one name w/ from ... import *
+                    assert len(node.names) == 1
+                    return
+                else:
+                    self.emit('IMPORT_FROM', name)
+                    self._resolveDots(name)
+                    self.storeName(alias or name)
+            else:
+                self.emit('IMPORT_FROM', name)
+        self.emit('POP_TOP')
+
+    def _resolveDots(self, name):
+        elts = name.split(".")
+        if len(elts) == 1:
+            return
+        for elt in elts[1:]:
+            self.emit('LOAD_ATTR', elt)
+
+    def visitGetattr(self, node):
+        self.visit(node.expr)
+        self.emit('LOAD_ATTR', self.mangle(node.attrname))
+
+    # next five implement assignments
+
+    def visitAssign(self, node):
+        self.set_lineno(node)
+        self.visit(node.expr)
+        dups = len(node.nodes) - 1
+        for i in range(len(node.nodes)):
+            elt = node.nodes[i]
+            if i < dups:
+                self.emit('DUP_TOP')
+            if isinstance(elt, ast.Node):
+                self.visit(elt)
+
+    def visitAssName(self, node):
+        if node.flags == 'OP_ASSIGN':
+            self.storeName(node.name)
+        elif node.flags == 'OP_DELETE':
+            self.set_lineno(node)
+            self.delName(node.name)
+        else:
+            print "oops", node.flags
+
+    def visitAssAttr(self, node):
+        self.visit(node.expr)
+        if node.flags == 'OP_ASSIGN':
+            self.emit('STORE_ATTR', self.mangle(node.attrname))
+        elif node.flags == 'OP_DELETE':
+            self.emit('DELETE_ATTR', self.mangle(node.attrname))
+        else:
+            print "warning: unexpected flags:", node.flags
+            print node
+
+    def _visitAssSequence(self, node, op='UNPACK_SEQUENCE'):
+        if findOp(node) != 'OP_DELETE':
+            self.emit(op, len(node.nodes))
+        for child in node.nodes:
+            self.visit(child)
+
+    if VERSION > 1:
+        visitAssTuple = _visitAssSequence
+        visitAssList = _visitAssSequence
+    else:
+        def visitAssTuple(self, node):
+            self._visitAssSequence(node, 'UNPACK_TUPLE')
+
+        def visitAssList(self, node):
+            self._visitAssSequence(node, 'UNPACK_LIST')
+
+    # augmented assignment
+
+    def visitAugAssign(self, node):
+        self.set_lineno(node)
+        aug_node = wrap_aug(node.node)
+        self.visit(aug_node, "load")
+        self.visit(node.expr)
+        self.emit(self._augmented_opcode[node.op])
+        self.visit(aug_node, "store")
+
+    _augmented_opcode = {
+        '+=' : 'INPLACE_ADD',
+        '-=' : 'INPLACE_SUBTRACT',
+        '*=' : 'INPLACE_MULTIPLY',
+        '/=' : 'INPLACE_DIVIDE',
+        '//=': 'INPLACE_FLOOR_DIVIDE',
+        '%=' : 'INPLACE_MODULO',
+        '**=': 'INPLACE_POWER',
+        '>>=': 'INPLACE_RSHIFT',
+        '<<=': 'INPLACE_LSHIFT',
+        '&=' : 'INPLACE_AND',
+        '^=' : 'INPLACE_XOR',
+        '|=' : 'INPLACE_OR',
+        }
+
+    def visitAugName(self, node, mode):
+        if mode == "load":
+            self.loadName(node.name)
+        elif mode == "store":
+            self.storeName(node.name)
+
+    def visitAugGetattr(self, node, mode):
+        if mode == "load":
+            self.visit(node.expr)
+            self.emit('DUP_TOP')
+            self.emit('LOAD_ATTR', self.mangle(node.attrname))
+        elif mode == "store":
+            self.emit('ROT_TWO')
+            self.emit('STORE_ATTR', self.mangle(node.attrname))
+
+    def visitAugSlice(self, node, mode):
+        if mode == "load":
+            self.visitSlice(node, 1)
+        elif mode == "store":
+            slice = 0
+            if node.lower:
+                slice = slice | 1
+            if node.upper:
+                slice = slice | 2
+            if slice == 0:
+                self.emit('ROT_TWO')
+            elif slice == 3:
+                self.emit('ROT_FOUR')
+            else:
+                self.emit('ROT_THREE')
+            self.emit('STORE_SLICE+%d' % slice)
+
+    def visitAugSubscript(self, node, mode):
+        if mode == "load":
+            self.visitSubscript(node, 1)
+        elif mode == "store":
+            self.emit('ROT_THREE')
+            self.emit('STORE_SUBSCR')
+
+    def visitExec(self, node):
+        self.visit(node.expr)
+        if node.locals is None:
+            self.emit('LOAD_CONST', None)
+        else:
+            self.visit(node.locals)
+        if node.globals is None:
+            self.emit('DUP_TOP')
+        else:
+            self.visit(node.globals)
+        self.emit('EXEC_STMT')
+
+    def visitCallFunc(self, node):
+        pos = 0
+        kw = 0
+        self.set_lineno(node)
+        self.visit(node.node)
+        for arg in node.args:
+            self.visit(arg)
+            if isinstance(arg, ast.Keyword):
+                kw = kw + 1
+            else:
+                pos = pos + 1
+        if node.star_args is not None:
+            self.visit(node.star_args)
+        if node.dstar_args is not None:
+            self.visit(node.dstar_args)
+        have_star = node.star_args is not None
+        have_dstar = node.dstar_args is not None
+        opcode = callfunc_opcode_info[have_star, have_dstar]
+        self.emit(opcode, kw << 8 | pos)
+
+    def visitPrint(self, node, newline=0):
+        self.set_lineno(node)
+        if node.dest:
+            self.visit(node.dest)
+        for child in node.nodes:
+            if node.dest:
+                self.emit('DUP_TOP')
+            self.visit(child)
+            if node.dest:
+                self.emit('ROT_TWO')
+                self.emit('PRINT_ITEM_TO')
+            else:
+                self.emit('PRINT_ITEM')
+        if node.dest and not newline:
+            self.emit('POP_TOP')
+
+    def visitPrintnl(self, node):
+        self.visitPrint(node, newline=1)
+        if node.dest:
+            self.emit('PRINT_NEWLINE_TO')
+        else:
+            self.emit('PRINT_NEWLINE')
+
+    def visitReturn(self, node):
+        self.set_lineno(node)
+        self.visit(node.value)
+        self.emit('RETURN_VALUE')
+
+    def visitYield(self, node):
+        self.set_lineno(node)
+        self.visit(node.value)
+        self.emit('YIELD_VALUE')
+
+    # slice and subscript stuff
+
+    def visitSlice(self, node, aug_flag=None):
+        # aug_flag is used by visitAugSlice
+        self.visit(node.expr)
+        slice = 0
+        if node.lower:
+            self.visit(node.lower)
+            slice = slice | 1
+        if node.upper:
+            self.visit(node.upper)
+            slice = slice | 2
+        if aug_flag:
+            if slice == 0:
+                self.emit('DUP_TOP')
+            elif slice == 3:
+                self.emit('DUP_TOPX', 3)
+            else:
+                self.emit('DUP_TOPX', 2)
+        if node.flags == 'OP_APPLY':
+            self.emit('SLICE+%d' % slice)
+        elif node.flags == 'OP_ASSIGN':
+            self.emit('STORE_SLICE+%d' % slice)
+        elif node.flags == 'OP_DELETE':
+            self.emit('DELETE_SLICE+%d' % slice)
+        else:
+            print "weird slice", node.flags
+            raise
+
+    def visitSubscript(self, node, aug_flag=None):
+        self.visit(node.expr)
+        for sub in node.subs:
+            self.visit(sub)
+        if len(node.subs) > 1:
+            self.emit('BUILD_TUPLE', len(node.subs))
+        if aug_flag:
+            self.emit('DUP_TOPX', 2)
+        if node.flags == 'OP_APPLY':
+            self.emit('BINARY_SUBSCR')
+        elif node.flags == 'OP_ASSIGN':
+            self.emit('STORE_SUBSCR')
+        elif node.flags == 'OP_DELETE':
+            self.emit('DELETE_SUBSCR')
+
+    # binary ops
+
+    def binaryOp(self, node, op):
+        self.visit(node.left)
+        self.visit(node.right)
+        self.emit(op)
+
+    def visitAdd(self, node):
+        return self.binaryOp(node, 'BINARY_ADD')
+
+    def visitSub(self, node):
+        return self.binaryOp(node, 'BINARY_SUBTRACT')
+
+    def visitMul(self, node):
+        return self.binaryOp(node, 'BINARY_MULTIPLY')
+
+    def visitDiv(self, node):
+        return self.binaryOp(node, self._div_op)
+
+    def visitFloorDiv(self, node):
+        return self.binaryOp(node, 'BINARY_FLOOR_DIVIDE')
+
+    def visitMod(self, node):
+        return self.binaryOp(node, 'BINARY_MODULO')
+
+    def visitPower(self, node):
+        return self.binaryOp(node, 'BINARY_POWER')
+
+    def visitLeftShift(self, node):
+        return self.binaryOp(node, 'BINARY_LSHIFT')
+
+    def visitRightShift(self, node):
+        return self.binaryOp(node, 'BINARY_RSHIFT')
+
+    # unary ops
+
+    def unaryOp(self, node, op):
+        self.visit(node.expr)
+        self.emit(op)
+
+    def visitInvert(self, node):
+        return self.unaryOp(node, 'UNARY_INVERT')
+
+    def visitUnarySub(self, node):
+        return self.unaryOp(node, 'UNARY_NEGATIVE')
+
+    def visitUnaryAdd(self, node):
+        return self.unaryOp(node, 'UNARY_POSITIVE')
+
+    def visitUnaryInvert(self, node):
+        return self.unaryOp(node, 'UNARY_INVERT')
+
+    def visitNot(self, node):
+        return self.unaryOp(node, 'UNARY_NOT')
+
+    def visitBackquote(self, node):
+        return self.unaryOp(node, 'UNARY_CONVERT')
+
+    # bit ops
+
+    def bitOp(self, nodes, op):
+        self.visit(nodes[0])
+        for node in nodes[1:]:
+            self.visit(node)
+            self.emit(op)
+
+    def visitBitand(self, node):
+        return self.bitOp(node.nodes, 'BINARY_AND')
+
+    def visitBitor(self, node):
+        return self.bitOp(node.nodes, 'BINARY_OR')
+
+    def visitBitxor(self, node):
+        return self.bitOp(node.nodes, 'BINARY_XOR')
+
+    # object constructors
+
+    def visitEllipsis(self, node):
+        self.emit('LOAD_CONST', Ellipsis)
+
+    def visitTuple(self, node):
+        self.set_lineno(node)
+        for elt in node.nodes:
+            self.visit(elt)
+        self.emit('BUILD_TUPLE', len(node.nodes))
+
+    def visitList(self, node):
+        self.set_lineno(node)
+        for elt in node.nodes:
+            self.visit(elt)
+        self.emit('BUILD_LIST', len(node.nodes))
+
+    def visitSliceobj(self, node):
+        for child in node.nodes:
+            self.visit(child)
+        self.emit('BUILD_SLICE', len(node.nodes))
+
+    def visitDict(self, node):
+        self.set_lineno(node)
+        self.emit('BUILD_MAP', 0)
+        for k, v in node.items:
+            self.emit('DUP_TOP')
+            self.visit(k)
+            self.visit(v)
+            self.emit('ROT_THREE')
+            self.emit('STORE_SUBSCR')
+
+class NestedScopeMixin:
+    """Defines initClass() for nested scoping (Python 2.2-compatible)"""
+    def initClass(self):
+        self.__class__.NameFinder = LocalNameFinder
+        self.__class__.FunctionGen = FunctionCodeGenerator
+        self.__class__.ClassGen = ClassCodeGenerator
+
+class ModuleCodeGenerator(NestedScopeMixin, CodeGenerator):
+    __super_init = CodeGenerator.__init__
+
+    scopes = None
+
+    def __init__(self, tree):
+        self.graph = pyassem.PyFlowGraph("<module>", tree.filename)
+        self.futures = future.find_futures(tree)
+        self.__super_init()
+        walk(tree, self)
+
+    def get_module(self):
+        return self
+
+class ExpressionCodeGenerator(NestedScopeMixin, CodeGenerator):
+    __super_init = CodeGenerator.__init__
+
+    scopes = None
+    futures = ()
+
+    def __init__(self, tree):
+        self.graph = pyassem.PyFlowGraph("<expression>", tree.filename)
+        self.__super_init()
+        walk(tree, self)
+
+    def get_module(self):
+        return self
+
+class InteractiveCodeGenerator(NestedScopeMixin, CodeGenerator):
+
+    __super_init = CodeGenerator.__init__
+
+    scopes = None
+    futures = ()
+
+    def __init__(self, tree):
+        self.graph = pyassem.PyFlowGraph("<interactive>", tree.filename)
+        self.__super_init()
+        self.set_lineno(tree)
+        walk(tree, self)
+        self.emit('RETURN_VALUE')
+
+    def get_module(self):
+        return self
+
+    def visitDiscard(self, node):
+        # XXX Discard means it's an expression.  Perhaps this is a bad
+        # name.
+        self.visit(node.expr)
+        self.emit('PRINT_EXPR')
+
+class AbstractFunctionCode:
+    optimized = 1
+    lambdaCount = 0
+
+    def __init__(self, func, scopes, isLambda, class_name, mod):
+        self.class_name = class_name
+        self.module = mod
+        if isLambda:
+            klass = FunctionCodeGenerator
+            name = "<lambda.%d>" % klass.lambdaCount
+            klass.lambdaCount = klass.lambdaCount + 1
+        else:
+            name = func.name
+
+        args, hasTupleArg = generateArgList(func.argnames)
+        self.graph = pyassem.PyFlowGraph(name, func.filename, args,
+                                         optimized=1)
+        self.isLambda = isLambda
+        self.super_init()
+
+        if not isLambda and func.doc:
+            self.setDocstring(func.doc)
+
+        lnf = walk(func.code, self.NameFinder(args), verbose=0)
+        self.locals.push(lnf.getLocals())
+        if func.varargs:
+            self.graph.setFlag(CO_VARARGS)
+        if func.kwargs:
+            self.graph.setFlag(CO_VARKEYWORDS)
+        self.set_lineno(func)
+        if hasTupleArg:
+            self.generateArgUnpack(func.argnames)
+
+    def get_module(self):
+        return self.module
+
+    def finish(self):
+        self.graph.startExitBlock()
+        if not self.isLambda:
+            self.emit('LOAD_CONST', None)
+        self.emit('RETURN_VALUE')
+
+    def generateArgUnpack(self, args):
+        for i in range(len(args)):
+            arg = args[i]
+            if isinstance(arg, tuple):
+                self.emit('LOAD_FAST', '.%d' % (i * 2))
+                self.unpackSequence(arg)
+
+    def unpackSequence(self, tup):
+        if VERSION > 1:
+            self.emit('UNPACK_SEQUENCE', len(tup))
+        else:
+            self.emit('UNPACK_TUPLE', len(tup))
+        for elt in tup:
+            if isinstance(elt, tuple):
+                self.unpackSequence(elt)
+            else:
+                self._nameOp('STORE', elt)
+
+    unpackTuple = unpackSequence
+
+class FunctionCodeGenerator(NestedScopeMixin, AbstractFunctionCode,
+                            CodeGenerator):
+    super_init = CodeGenerator.__init__ # call be other init
+    scopes = None
+
+    __super_init = AbstractFunctionCode.__init__
+
+    def __init__(self, func, scopes, isLambda, class_name, mod):
+        self.scopes = scopes
+        self.scope = scopes[func]
+        self.__super_init(func, scopes, isLambda, class_name, mod)
+        self.graph.setFreeVars(self.scope.get_free_vars())
+        self.graph.setCellVars(self.scope.get_cell_vars())
+        if self.scope.generator is not None:
+            self.graph.setFlag(CO_GENERATOR)
+
+class GenExprCodeGenerator(NestedScopeMixin, AbstractFunctionCode,
+                           CodeGenerator):
+    super_init = CodeGenerator.__init__ # call be other init
+    scopes = None
+
+    __super_init = AbstractFunctionCode.__init__
+
+    def __init__(self, gexp, scopes, class_name, mod):
+        self.scopes = scopes
+        self.scope = scopes[gexp]
+        self.__super_init(gexp, scopes, 1, class_name, mod)
+        self.graph.setFreeVars(self.scope.get_free_vars())
+        self.graph.setCellVars(self.scope.get_cell_vars())
+        self.graph.setFlag(CO_GENERATOR)
+
+class AbstractClassCode:
+
+    def __init__(self, klass, scopes, module):
+        self.class_name = klass.name
+        self.module = module
+        self.graph = pyassem.PyFlowGraph(klass.name, klass.filename,
+                                           optimized=0, klass=1)
+        self.super_init()
+        lnf = walk(klass.code, self.NameFinder(), verbose=0)
+        self.locals.push(lnf.getLocals())
+        self.graph.setFlag(CO_NEWLOCALS)
+        if klass.doc:
+            self.setDocstring(klass.doc)
+
+    def get_module(self):
+        return self.module
+
+    def finish(self):
+        self.graph.startExitBlock()
+        self.emit('LOAD_LOCALS')
+        self.emit('RETURN_VALUE')
+
+class ClassCodeGenerator(NestedScopeMixin, AbstractClassCode, CodeGenerator):
+    super_init = CodeGenerator.__init__
+    scopes = None
+
+    __super_init = AbstractClassCode.__init__
+
+    def __init__(self, klass, scopes, module):
+        self.scopes = scopes
+        self.scope = scopes[klass]
+        self.__super_init(klass, scopes, module)
+        self.graph.setFreeVars(self.scope.get_free_vars())
+        self.graph.setCellVars(self.scope.get_cell_vars())
+        self.set_lineno(klass)
+        self.emit("LOAD_GLOBAL", "__name__")
+        self.storeName("__module__")
+        if klass.doc:
+            self.emit("LOAD_CONST", klass.doc)
+            self.storeName('__doc__')
+
+def generateArgList(arglist):
+    """Generate an arg list marking TupleArgs"""
+    args = []
+    extra = []
+    count = 0
+    for i in range(len(arglist)):
+        elt = arglist[i]
+        if isinstance(elt, str):
+            args.append(elt)
+        elif isinstance(elt, tuple):
+            args.append(TupleArg(i * 2, elt))
+            extra.extend(misc.flatten(elt))
+            count = count + 1
+        else:
+            raise ValueError, "unexpect argument type:", elt
+    return args + extra, count
+
+def findOp(node):
+    """Find the op (DELETE, LOAD, STORE) in an AssTuple tree"""
+    v = OpFinder()
+    walk(node, v, verbose=0)
+    return v.op
+
+class OpFinder:
+    def __init__(self):
+        self.op = None
+    def visitAssName(self, node):
+        if self.op is None:
+            self.op = node.flags
+        elif self.op != node.flags:
+            raise ValueError, "mixed ops in stmt"
+    visitAssAttr = visitAssName
+    visitSubscript = visitAssName
+
+class Delegator:
+    """Base class to support delegation for augmented assignment nodes
+
+    To generator code for augmented assignments, we use the following
+    wrapper classes.  In visitAugAssign, the left-hand expression node
+    is visited twice.  The first time the visit uses the normal method
+    for that node .  The second time the visit uses a different method
+    that generates the appropriate code to perform the assignment.
+    These delegator classes wrap the original AST nodes in order to
+    support the variant visit methods.
+    """
+    def __init__(self, obj):
+        self.obj = obj
+
+    def __getattr__(self, attr):
+        return getattr(self.obj, attr)
+
+class AugGetattr(Delegator):
+    pass
+
+class AugName(Delegator):
+    pass
+
+class AugSlice(Delegator):
+    pass
+
+class AugSubscript(Delegator):
+    pass
+
+wrapper = {
+    ast.Getattr: AugGetattr,
+    ast.Name: AugName,
+    ast.Slice: AugSlice,
+    ast.Subscript: AugSubscript,
+    }
+
+def wrap_aug(node):
+    return wrapper[node.__class__](node)
+
+if __name__ == "__main__":
+    for file in sys.argv[1:]:
+        compileFile(file)

Added: vendor/Python/current/Lib/compiler/symbols.py
===================================================================
--- vendor/Python/current/Lib/compiler/symbols.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/compiler/symbols.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,463 @@
+"""Module symbol-table generator"""
+
+from compiler import ast
+from compiler.consts import SC_LOCAL, SC_GLOBAL, SC_FREE, SC_CELL, SC_UNKNOWN
+from compiler.misc import mangle
+import types
+
+
+import sys
+
+MANGLE_LEN = 256
+
+class Scope:
+    # XXX how much information do I need about each name?
+    def __init__(self, name, module, klass=None):
+        self.name = name
+        self.module = module
+        self.defs = {}
+        self.uses = {}
+        self.globals = {}
+        self.params = {}
+        self.frees = {}
+        self.cells = {}
+        self.children = []
+        # nested is true if the class could contain free variables,
+        # i.e. if it is nested within another function.
+        self.nested = None
+        self.generator = None
+        self.klass = None
+        if klass is not None:
+            for i in range(len(klass)):
+                if klass[i] != '_':
+                    self.klass = klass[i:]
+                    break
+
+    def __repr__(self):
+        return "<%s: %s>" % (self.__class__.__name__, self.name)
+
+    def mangle(self, name):
+        if self.klass is None:
+            return name
+        return mangle(name, self.klass)
+
+    def add_def(self, name):
+        self.defs[self.mangle(name)] = 1
+
+    def add_use(self, name):
+        self.uses[self.mangle(name)] = 1
+
+    def add_global(self, name):
+        name = self.mangle(name)
+        if self.uses.has_key(name) or self.defs.has_key(name):
+            pass # XXX warn about global following def/use
+        if self.params.has_key(name):
+            raise SyntaxError, "%s in %s is global and parameter" % \
+                  (name, self.name)
+        self.globals[name] = 1
+        self.module.add_def(name)
+
+    def add_param(self, name):
+        name = self.mangle(name)
+        self.defs[name] = 1
+        self.params[name] = 1
+
+    def get_names(self):
+        d = {}
+        d.update(self.defs)
+        d.update(self.uses)
+        d.update(self.globals)
+        return d.keys()
+
+    def add_child(self, child):
+        self.children.append(child)
+
+    def get_children(self):
+        return self.children
+
+    def DEBUG(self):
+        print >> sys.stderr, self.name, self.nested and "nested" or ""
+        print >> sys.stderr, "\tglobals: ", self.globals
+        print >> sys.stderr, "\tcells: ", self.cells
+        print >> sys.stderr, "\tdefs: ", self.defs
+        print >> sys.stderr, "\tuses: ", self.uses
+        print >> sys.stderr, "\tfrees:", self.frees
+
+    def check_name(self, name):
+        """Return scope of name.
+
+        The scope of a name could be LOCAL, GLOBAL, FREE, or CELL.
+        """
+        if self.globals.has_key(name):
+            return SC_GLOBAL
+        if self.cells.has_key(name):
+            return SC_CELL
+        if self.defs.has_key(name):
+            return SC_LOCAL
+        if self.nested and (self.frees.has_key(name) or
+                            self.uses.has_key(name)):
+            return SC_FREE
+        if self.nested:
+            return SC_UNKNOWN
+        else:
+            return SC_GLOBAL
+
+    def get_free_vars(self):
+        if not self.nested:
+            return ()
+        free = {}
+        free.update(self.frees)
+        for name in self.uses.keys():
+            if not (self.defs.has_key(name) or
+                    self.globals.has_key(name)):
+                free[name] = 1
+        return free.keys()
+
+    def handle_children(self):
+        for child in self.children:
+            frees = child.get_free_vars()
+            globals = self.add_frees(frees)
+            for name in globals:
+                child.force_global(name)
+
+    def force_global(self, name):
+        """Force name to be global in scope.
+
+        Some child of the current node had a free reference to name.
+        When the child was processed, it was labelled a free
+        variable.  Now that all its enclosing scope have been
+        processed, the name is known to be a global or builtin.  So
+        walk back down the child chain and set the name to be global
+        rather than free.
+
+        Be careful to stop if a child does not think the name is
+        free.
+        """
+        self.globals[name] = 1
+        if self.frees.has_key(name):
+            del self.frees[name]
+        for child in self.children:
+            if child.check_name(name) == SC_FREE:
+                child.force_global(name)
+
+    def add_frees(self, names):
+        """Process list of free vars from nested scope.
+
+        Returns a list of names that are either 1) declared global in the
+        parent or 2) undefined in a top-level parent.  In either case,
+        the nested scope should treat them as globals.
+        """
+        child_globals = []
+        for name in names:
+            sc = self.check_name(name)
+            if self.nested:
+                if sc == SC_UNKNOWN or sc == SC_FREE \
+                   or isinstance(self, ClassScope):
+                    self.frees[name] = 1
+                elif sc == SC_GLOBAL:
+                    child_globals.append(name)
+                elif isinstance(self, FunctionScope) and sc == SC_LOCAL:
+                    self.cells[name] = 1
+                elif sc != SC_CELL:
+                    child_globals.append(name)
+            else:
+                if sc == SC_LOCAL:
+                    self.cells[name] = 1
+                elif sc != SC_CELL:
+                    child_globals.append(name)
+        return child_globals
+
+    def get_cell_vars(self):
+        return self.cells.keys()
+
+class ModuleScope(Scope):
+    __super_init = Scope.__init__
+
+    def __init__(self):
+        self.__super_init("global", self)
+
+class FunctionScope(Scope):
+    pass
+
+class GenExprScope(Scope):
+    __super_init = Scope.__init__
+
+    __counter = 1
+
+    def __init__(self, module, klass=None):
+        i = self.__counter
+        self.__counter += 1
+        self.__super_init("generator expression<%d>"%i, module, klass)
+        self.add_param('.0')
+
+    def get_names(self):
+        keys = Scope.get_names(self)
+        return keys
+
+class LambdaScope(FunctionScope):
+    __super_init = Scope.__init__
+
+    __counter = 1
+
+    def __init__(self, module, klass=None):
+        i = self.__counter
+        self.__counter += 1
+        self.__super_init("lambda.%d" % i, module, klass)
+
+class ClassScope(Scope):
+    __super_init = Scope.__init__
+
+    def __init__(self, name, module):
+        self.__super_init(name, module, name)
+
+class SymbolVisitor:
+    def __init__(self):
+        self.scopes = {}
+        self.klass = None
+
+    # node that define new scopes
+
+    def visitModule(self, node):
+        scope = self.module = self.scopes[node] = ModuleScope()
+        self.visit(node.node, scope)
+
+    visitExpression = visitModule
+
+    def visitFunction(self, node, parent):
+        if node.decorators:
+            self.visit(node.decorators, parent)
+        parent.add_def(node.name)
+        for n in node.defaults:
+            self.visit(n, parent)
+        scope = FunctionScope(node.name, self.module, self.klass)
+        if parent.nested or isinstance(parent, FunctionScope):
+            scope.nested = 1
+        self.scopes[node] = scope
+        self._do_args(scope, node.argnames)
+        self.visit(node.code, scope)
+        self.handle_free_vars(scope, parent)
+
+    def visitGenExpr(self, node, parent):
+        scope = GenExprScope(self.module, self.klass);
+        if parent.nested or isinstance(parent, FunctionScope) \
+                or isinstance(parent, GenExprScope):
+            scope.nested = 1
+
+        self.scopes[node] = scope
+        self.visit(node.code, scope)
+
+        self.handle_free_vars(scope, parent)
+
+    def visitGenExprInner(self, node, scope):
+        for genfor in node.quals:
+            self.visit(genfor, scope)
+
+        self.visit(node.expr, scope)
+
+    def visitGenExprFor(self, node, scope):
+        self.visit(node.assign, scope, 1)
+        self.visit(node.iter, scope)
+        for if_ in node.ifs:
+            self.visit(if_, scope)
+
+    def visitGenExprIf(self, node, scope):
+        self.visit(node.test, scope)
+
+    def visitLambda(self, node, parent, assign=0):
+        # Lambda is an expression, so it could appear in an expression
+        # context where assign is passed.  The transformer should catch
+        # any code that has a lambda on the left-hand side.
+        assert not assign
+
+        for n in node.defaults:
+            self.visit(n, parent)
+        scope = LambdaScope(self.module, self.klass)
+        if parent.nested or isinstance(parent, FunctionScope):
+            scope.nested = 1
+        self.scopes[node] = scope
+        self._do_args(scope, node.argnames)
+        self.visit(node.code, scope)
+        self.handle_free_vars(scope, parent)
+
+    def _do_args(self, scope, args):
+        for name in args:
+            if type(name) == types.TupleType:
+                self._do_args(scope, name)
+            else:
+                scope.add_param(name)
+
+    def handle_free_vars(self, scope, parent):
+        parent.add_child(scope)
+        scope.handle_children()
+
+    def visitClass(self, node, parent):
+        parent.add_def(node.name)
+        for n in node.bases:
+            self.visit(n, parent)
+        scope = ClassScope(node.name, self.module)
+        if parent.nested or isinstance(parent, FunctionScope):
+            scope.nested = 1
+        if node.doc is not None:
+            scope.add_def('__doc__')
+        scope.add_def('__module__')
+        self.scopes[node] = scope
+        prev = self.klass
+        self.klass = node.name
+        self.visit(node.code, scope)
+        self.klass = prev
+        self.handle_free_vars(scope, parent)
+
+    # name can be a def or a use
+
+    # XXX a few calls and nodes expect a third "assign" arg that is
+    # true if the name is being used as an assignment.  only
+    # expressions contained within statements may have the assign arg.
+
+    def visitName(self, node, scope, assign=0):
+        if assign:
+            scope.add_def(node.name)
+        else:
+            scope.add_use(node.name)
+
+    # operations that bind new names
+
+    def visitFor(self, node, scope):
+        self.visit(node.assign, scope, 1)
+        self.visit(node.list, scope)
+        self.visit(node.body, scope)
+        if node.else_:
+            self.visit(node.else_, scope)
+
+    def visitFrom(self, node, scope):
+        for name, asname in node.names:
+            if name == "*":
+                continue
+            scope.add_def(asname or name)
+
+    def visitImport(self, node, scope):
+        for name, asname in node.names:
+            i = name.find(".")
+            if i > -1:
+                name = name[:i]
+            scope.add_def(asname or name)
+
+    def visitGlobal(self, node, scope):
+        for name in node.names:
+            scope.add_global(name)
+
+    def visitAssign(self, node, scope):
+        """Propagate assignment flag down to child nodes.
+
+        The Assign node doesn't itself contains the variables being
+        assigned to.  Instead, the children in node.nodes are visited
+        with the assign flag set to true.  When the names occur in
+        those nodes, they are marked as defs.
+
+        Some names that occur in an assignment target are not bound by
+        the assignment, e.g. a name occurring inside a slice.  The
+        visitor handles these nodes specially; they do not propagate
+        the assign flag to their children.
+        """
+        for n in node.nodes:
+            self.visit(n, scope, 1)
+        self.visit(node.expr, scope)
+
+    def visitAssName(self, node, scope, assign=1):
+        scope.add_def(node.name)
+
+    def visitAssAttr(self, node, scope, assign=0):
+        self.visit(node.expr, scope, 0)
+
+    def visitSubscript(self, node, scope, assign=0):
+        self.visit(node.expr, scope, 0)
+        for n in node.subs:
+            self.visit(n, scope, 0)
+
+    def visitSlice(self, node, scope, assign=0):
+        self.visit(node.expr, scope, 0)
+        if node.lower:
+            self.visit(node.lower, scope, 0)
+        if node.upper:
+            self.visit(node.upper, scope, 0)
+
+    def visitAugAssign(self, node, scope):
+        # If the LHS is a name, then this counts as assignment.
+        # Otherwise, it's just use.
+        self.visit(node.node, scope)
+        if isinstance(node.node, ast.Name):
+            self.visit(node.node, scope, 1) # XXX worry about this
+        self.visit(node.expr, scope)
+
+    # prune if statements if tests are false
+
+    _const_types = types.StringType, types.IntType, types.FloatType
+
+    def visitIf(self, node, scope):
+        for test, body in node.tests:
+            if isinstance(test, ast.Const):
+                if type(test.value) in self._const_types:
+                    if not test.value:
+                        continue
+            self.visit(test, scope)
+            self.visit(body, scope)
+        if node.else_:
+            self.visit(node.else_, scope)
+
+    # a yield statement signals a generator
+
+    def visitYield(self, node, scope):
+        scope.generator = 1
+        self.visit(node.value, scope)
+
+def list_eq(l1, l2):
+    return sorted(l1) == sorted(l2)
+
+if __name__ == "__main__":
+    import sys
+    from compiler import parseFile, walk
+    import symtable
+
+    def get_names(syms):
+        return [s for s in [s.get_name() for s in syms.get_symbols()]
+                if not (s.startswith('_[') or s.startswith('.'))]
+
+    for file in sys.argv[1:]:
+        print file
+        f = open(file)
+        buf = f.read()
+        f.close()
+        syms = symtable.symtable(buf, file, "exec")
+        mod_names = get_names(syms)
+        tree = parseFile(file)
+        s = SymbolVisitor()
+        walk(tree, s)
+
+        # compare module-level symbols
+        names2 = s.scopes[tree].get_names()
+
+        if not list_eq(mod_names, names2):
+            print
+            print "oops", file
+            print sorted(mod_names)
+            print sorted(names2)
+            sys.exit(-1)
+
+        d = {}
+        d.update(s.scopes)
+        del d[tree]
+        scopes = d.values()
+        del d
+
+        for s in syms.get_symbols():
+            if s.is_namespace():
+                l = [sc for sc in scopes
+                     if sc.name == s.get_name()]
+                if len(l) > 1:
+                    print "skipping", s.get_name()
+                else:
+                    if not list_eq(get_names(s.get_namespace()),
+                                   l[0].get_names()):
+                        print s.get_name()
+                        print sorted(get_names(s.get_namespace()))
+                        print sorted(l[0].get_names())
+                        sys.exit(-1)

Added: vendor/Python/current/Lib/compiler/syntax.py
===================================================================
--- vendor/Python/current/Lib/compiler/syntax.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/compiler/syntax.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,46 @@
+"""Check for errs in the AST.
+
+The Python parser does not catch all syntax errors.  Others, like
+assignments with invalid targets, are caught in the code generation
+phase.
+
+The compiler package catches some errors in the transformer module.
+But it seems clearer to write checkers that use the AST to detect
+errors.
+"""
+
+from compiler import ast, walk
+
+def check(tree, multi=None):
+    v = SyntaxErrorChecker(multi)
+    walk(tree, v)
+    return v.errors
+
+class SyntaxErrorChecker:
+    """A visitor to find syntax errors in the AST."""
+
+    def __init__(self, multi=None):
+        """Create new visitor object.
+
+        If optional argument multi is not None, then print messages
+        for each error rather than raising a SyntaxError for the
+        first.
+        """
+        self.multi = multi
+        self.errors = 0
+
+    def error(self, node, msg):
+        self.errors = self.errors + 1
+        if self.multi is not None:
+            print "%s:%s: %s" % (node.filename, node.lineno, msg)
+        else:
+            raise SyntaxError, "%s (%s:%s)" % (msg, node.filename, node.lineno)
+
+    def visitAssign(self, node):
+        # the transformer module handles many of these
+        pass
+##        for target in node.nodes:
+##            if isinstance(target, ast.AssList):
+##                if target.lineno is None:
+##                    target.lineno = node.lineno
+##                self.error(target, "can't assign to list comprehension")

Added: vendor/Python/current/Lib/compiler/transformer.py
===================================================================
--- vendor/Python/current/Lib/compiler/transformer.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/compiler/transformer.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1490 @@
+"""Parse tree transformation module.
+
+Transforms Python source code into an abstract syntax tree (AST)
+defined in the ast module.
+
+The simplest ways to invoke this module are via parse and parseFile.
+parse(buf) -> AST
+parseFile(path) -> AST
+"""
+
+# Original version written by Greg Stein (gstein at lyra.org)
+#                         and Bill Tutt (rassilon at lima.mudlib.org)
+# February 1997.
+#
+# Modifications and improvements for Python 2.0 by Jeremy Hylton and
+# Mark Hammond
+#
+# Some fixes to try to have correct line number on almost all nodes
+# (except Module, Discard and Stmt) added by Sylvain Thenault
+#
+# Portions of this file are:
+# Copyright (C) 1997-1998 Greg Stein. All Rights Reserved.
+#
+# This module is provided under a BSD-ish license. See
+#   http://www.opensource.org/licenses/bsd-license.html
+# and replace OWNER, ORGANIZATION, and YEAR as appropriate.
+
+from compiler.ast import *
+import parser
+import symbol
+import token
+import sys
+
+class WalkerError(StandardError):
+    pass
+
+from compiler.consts import CO_VARARGS, CO_VARKEYWORDS
+from compiler.consts import OP_ASSIGN, OP_DELETE, OP_APPLY
+
+def parseFile(path):
+    f = open(path, "U")
+    # XXX The parser API tolerates files without a trailing newline,
+    # but not strings without a trailing newline.  Always add an extra
+    # newline to the file contents, since we're going through the string
+    # version of the API.
+    src = f.read() + "\n"
+    f.close()
+    return parse(src)
+
+def parse(buf, mode="exec"):
+    if mode == "exec" or mode == "single":
+        return Transformer().parsesuite(buf)
+    elif mode == "eval":
+        return Transformer().parseexpr(buf)
+    else:
+        raise ValueError("compile() arg 3 must be"
+                         " 'exec' or 'eval' or 'single'")
+
+def asList(nodes):
+    l = []
+    for item in nodes:
+        if hasattr(item, "asList"):
+            l.append(item.asList())
+        else:
+            if type(item) is type( (None, None) ):
+                l.append(tuple(asList(item)))
+            elif type(item) is type( [] ):
+                l.append(asList(item))
+            else:
+                l.append(item)
+    return l
+
+def extractLineNo(ast):
+    if not isinstance(ast[1], tuple):
+        # get a terminal node
+        return ast[2]
+    for child in ast[1:]:
+        if isinstance(child, tuple):
+            lineno = extractLineNo(child)
+            if lineno is not None:
+                return lineno
+
+def Node(*args):
+    kind = args[0]
+    if nodes.has_key(kind):
+        try:
+            return nodes[kind](*args[1:])
+        except TypeError:
+            print nodes[kind], len(args), args
+            raise
+    else:
+        raise WalkerError, "Can't find appropriate Node type: %s" % str(args)
+        #return apply(ast.Node, args)
+
+class Transformer:
+    """Utility object for transforming Python parse trees.
+
+    Exposes the following methods:
+        tree = transform(ast_tree)
+        tree = parsesuite(text)
+        tree = parseexpr(text)
+        tree = parsefile(fileob | filename)
+    """
+
+    def __init__(self):
+        self._dispatch = {}
+        for value, name in symbol.sym_name.items():
+            if hasattr(self, name):
+                self._dispatch[value] = getattr(self, name)
+        self._dispatch[token.NEWLINE] = self.com_NEWLINE
+        self._atom_dispatch = {token.LPAR: self.atom_lpar,
+                               token.LSQB: self.atom_lsqb,
+                               token.LBRACE: self.atom_lbrace,
+                               token.BACKQUOTE: self.atom_backquote,
+                               token.NUMBER: self.atom_number,
+                               token.STRING: self.atom_string,
+                               token.NAME: self.atom_name,
+                               }
+        self.encoding = None
+
+    def transform(self, tree):
+        """Transform an AST into a modified parse tree."""
+        if not (isinstance(tree, tuple) or isinstance(tree, list)):
+            tree = parser.ast2tuple(tree, line_info=1)
+        return self.compile_node(tree)
+
+    def parsesuite(self, text):
+        """Return a modified parse tree for the given suite text."""
+        return self.transform(parser.suite(text))
+
+    def parseexpr(self, text):
+        """Return a modified parse tree for the given expression text."""
+        return self.transform(parser.expr(text))
+
+    def parsefile(self, file):
+        """Return a modified parse tree for the contents of the given file."""
+        if type(file) == type(''):
+            file = open(file)
+        return self.parsesuite(file.read())
+
+    # --------------------------------------------------------------
+    #
+    # PRIVATE METHODS
+    #
+
+    def compile_node(self, node):
+        ### emit a line-number node?
+        n = node[0]
+
+        if n == symbol.encoding_decl:
+            self.encoding = node[2]
+            node = node[1]
+            n = node[0]
+
+        if n == symbol.single_input:
+            return self.single_input(node[1:])
+        if n == symbol.file_input:
+            return self.file_input(node[1:])
+        if n == symbol.eval_input:
+            return self.eval_input(node[1:])
+        if n == symbol.lambdef:
+            return self.lambdef(node[1:])
+        if n == symbol.funcdef:
+            return self.funcdef(node[1:])
+        if n == symbol.classdef:
+            return self.classdef(node[1:])
+
+        raise WalkerError, ('unexpected node type', n)
+
+    def single_input(self, node):
+        ### do we want to do anything about being "interactive" ?
+
+        # NEWLINE | simple_stmt | compound_stmt NEWLINE
+        n = node[0][0]
+        if n != token.NEWLINE:
+            return self.com_stmt(node[0])
+
+        return Pass()
+
+    def file_input(self, nodelist):
+        doc = self.get_docstring(nodelist, symbol.file_input)
+        if doc is not None:
+            i = 1
+        else:
+            i = 0
+        stmts = []
+        for node in nodelist[i:]:
+            if node[0] != token.ENDMARKER and node[0] != token.NEWLINE:
+                self.com_append_stmt(stmts, node)
+        return Module(doc, Stmt(stmts))
+
+    def eval_input(self, nodelist):
+        # from the built-in function input()
+        ### is this sufficient?
+        return Expression(self.com_node(nodelist[0]))
+
+    def decorator_name(self, nodelist):
+        listlen = len(nodelist)
+        assert listlen >= 1 and listlen % 2 == 1
+
+        item = self.atom_name(nodelist)
+        i = 1
+        while i < listlen:
+            assert nodelist[i][0] == token.DOT
+            assert nodelist[i + 1][0] == token.NAME
+            item = Getattr(item, nodelist[i + 1][1])
+            i += 2
+
+        return item
+
+    def decorator(self, nodelist):
+        # '@' dotted_name [ '(' [arglist] ')' ]
+        assert len(nodelist) in (3, 5, 6)
+        assert nodelist[0][0] == token.AT
+        assert nodelist[-1][0] == token.NEWLINE
+
+        assert nodelist[1][0] == symbol.dotted_name
+        funcname = self.decorator_name(nodelist[1][1:])
+
+        if len(nodelist) > 3:
+            assert nodelist[2][0] == token.LPAR
+            expr = self.com_call_function(funcname, nodelist[3])
+        else:
+            expr = funcname
+
+        return expr
+
+    def decorators(self, nodelist):
+        # decorators: decorator ([NEWLINE] decorator)* NEWLINE
+        items = []
+        for dec_nodelist in nodelist:
+            assert dec_nodelist[0] == symbol.decorator
+            items.append(self.decorator(dec_nodelist[1:]))
+        return Decorators(items)
+
+    def funcdef(self, nodelist):
+        #                    -6   -5    -4         -3  -2    -1
+        # funcdef: [decorators] 'def' NAME parameters ':' suite
+        # parameters: '(' [varargslist] ')'
+
+        if len(nodelist) == 6:
+            assert nodelist[0][0] == symbol.decorators
+            decorators = self.decorators(nodelist[0][1:])
+        else:
+            assert len(nodelist) == 5
+            decorators = None
+
+        lineno = nodelist[-4][2]
+        name = nodelist[-4][1]
+        args = nodelist[-3][2]
+
+        if args[0] == symbol.varargslist:
+            names, defaults, flags = self.com_arglist(args[1:])
+        else:
+            names = defaults = ()
+            flags = 0
+        doc = self.get_docstring(nodelist[-1])
+
+        # code for function
+        code = self.com_node(nodelist[-1])
+
+        if doc is not None:
+            assert isinstance(code, Stmt)
+            assert isinstance(code.nodes[0], Discard)
+            del code.nodes[0]
+        return Function(decorators, name, names, defaults, flags, doc, code,
+                     lineno=lineno)
+
+    def lambdef(self, nodelist):
+        # lambdef: 'lambda' [varargslist] ':' test
+        if nodelist[2][0] == symbol.varargslist:
+            names, defaults, flags = self.com_arglist(nodelist[2][1:])
+        else:
+            names = defaults = ()
+            flags = 0
+
+        # code for lambda
+        code = self.com_node(nodelist[-1])
+
+        return Lambda(names, defaults, flags, code, lineno=nodelist[1][2])
+    old_lambdef = lambdef
+
+    def classdef(self, nodelist):
+        # classdef: 'class' NAME ['(' [testlist] ')'] ':' suite
+
+        name = nodelist[1][1]
+        doc = self.get_docstring(nodelist[-1])
+        if nodelist[2][0] == token.COLON:
+            bases = []
+        elif nodelist[3][0] == token.RPAR:
+            bases = []
+        else:
+            bases = self.com_bases(nodelist[3])
+
+        # code for class
+        code = self.com_node(nodelist[-1])
+
+        if doc is not None:
+            assert isinstance(code, Stmt)
+            assert isinstance(code.nodes[0], Discard)
+            del code.nodes[0]
+
+        return Class(name, bases, doc, code, lineno=nodelist[1][2])
+
+    def stmt(self, nodelist):
+        return self.com_stmt(nodelist[0])
+
+    small_stmt = stmt
+    flow_stmt = stmt
+    compound_stmt = stmt
+
+    def simple_stmt(self, nodelist):
+        # small_stmt (';' small_stmt)* [';'] NEWLINE
+        stmts = []
+        for i in range(0, len(nodelist), 2):
+            self.com_append_stmt(stmts, nodelist[i])
+        return Stmt(stmts)
+
+    def parameters(self, nodelist):
+        raise WalkerError
+
+    def varargslist(self, nodelist):
+        raise WalkerError
+
+    def fpdef(self, nodelist):
+        raise WalkerError
+
+    def fplist(self, nodelist):
+        raise WalkerError
+
+    def dotted_name(self, nodelist):
+        raise WalkerError
+
+    def comp_op(self, nodelist):
+        raise WalkerError
+
+    def trailer(self, nodelist):
+        raise WalkerError
+
+    def sliceop(self, nodelist):
+        raise WalkerError
+
+    def argument(self, nodelist):
+        raise WalkerError
+
+    # --------------------------------------------------------------
+    #
+    # STATEMENT NODES  (invoked by com_node())
+    #
+
+    def expr_stmt(self, nodelist):
+        # augassign testlist | testlist ('=' testlist)*
+        en = nodelist[-1]
+        exprNode = self.lookup_node(en)(en[1:])
+        if len(nodelist) == 1:
+            return Discard(exprNode, lineno=exprNode.lineno)
+        if nodelist[1][0] == token.EQUAL:
+            nodesl = []
+            for i in range(0, len(nodelist) - 2, 2):
+                nodesl.append(self.com_assign(nodelist[i], OP_ASSIGN))
+            return Assign(nodesl, exprNode, lineno=nodelist[1][2])
+        else:
+            lval = self.com_augassign(nodelist[0])
+            op = self.com_augassign_op(nodelist[1])
+            return AugAssign(lval, op[1], exprNode, lineno=op[2])
+        raise WalkerError, "can't get here"
+
+    def print_stmt(self, nodelist):
+        # print ([ test (',' test)* [','] ] | '>>' test [ (',' test)+ [','] ])
+        items = []
+        if len(nodelist) == 1:
+            start = 1
+            dest = None
+        elif nodelist[1][0] == token.RIGHTSHIFT:
+            assert len(nodelist) == 3 \
+                   or nodelist[3][0] == token.COMMA
+            dest = self.com_node(nodelist[2])
+            start = 4
+        else:
+            dest = None
+            start = 1
+        for i in range(start, len(nodelist), 2):
+            items.append(self.com_node(nodelist[i]))
+        if nodelist[-1][0] == token.COMMA:
+            return Print(items, dest, lineno=nodelist[0][2])
+        return Printnl(items, dest, lineno=nodelist[0][2])
+
+    def del_stmt(self, nodelist):
+        return self.com_assign(nodelist[1], OP_DELETE)
+
+    def pass_stmt(self, nodelist):
+        return Pass(lineno=nodelist[0][2])
+
+    def break_stmt(self, nodelist):
+        return Break(lineno=nodelist[0][2])
+
+    def continue_stmt(self, nodelist):
+        return Continue(lineno=nodelist[0][2])
+
+    def return_stmt(self, nodelist):
+        # return: [testlist]
+        if len(nodelist) < 2:
+            return Return(Const(None), lineno=nodelist[0][2])
+        return Return(self.com_node(nodelist[1]), lineno=nodelist[0][2])
+
+    def yield_stmt(self, nodelist):
+        expr = self.com_node(nodelist[0])
+        return Discard(expr, lineno=expr.lineno)
+
+    def yield_expr(self, nodelist):
+        if len(nodelist) > 1:
+            value = self.com_node(nodelist[1])
+        else:
+            value = Const(None)
+        return Yield(value, lineno=nodelist[0][2])
+
+    def raise_stmt(self, nodelist):
+        # raise: [test [',' test [',' test]]]
+        if len(nodelist) > 5:
+            expr3 = self.com_node(nodelist[5])
+        else:
+            expr3 = None
+        if len(nodelist) > 3:
+            expr2 = self.com_node(nodelist[3])
+        else:
+            expr2 = None
+        if len(nodelist) > 1:
+            expr1 = self.com_node(nodelist[1])
+        else:
+            expr1 = None
+        return Raise(expr1, expr2, expr3, lineno=nodelist[0][2])
+
+    def import_stmt(self, nodelist):
+        # import_stmt: import_name | import_from
+        assert len(nodelist) == 1
+        return self.com_node(nodelist[0])
+
+    def import_name(self, nodelist):
+        # import_name: 'import' dotted_as_names
+        return Import(self.com_dotted_as_names(nodelist[1]),
+                      lineno=nodelist[0][2])
+
+    def import_from(self, nodelist):
+        # import_from: 'from' ('.'* dotted_name | '.') 'import' ('*' |
+        #    '(' import_as_names ')' | import_as_names)
+        assert nodelist[0][1] == 'from'
+        idx = 1
+        while nodelist[idx][1] == '.':
+            idx += 1
+        level = idx - 1
+        if nodelist[idx][0] == symbol.dotted_name:
+            fromname = self.com_dotted_name(nodelist[idx])
+            idx += 1
+        else:
+            fromname = ""
+        assert nodelist[idx][1] == 'import'
+        if nodelist[idx + 1][0] == token.STAR:
+            return From(fromname, [('*', None)], level,
+                        lineno=nodelist[0][2])
+        else:
+            node = nodelist[idx + 1 + (nodelist[idx + 1][0] == token.LPAR)]
+            return From(fromname, self.com_import_as_names(node), level,
+                        lineno=nodelist[0][2])
+
+    def global_stmt(self, nodelist):
+        # global: NAME (',' NAME)*
+        names = []
+        for i in range(1, len(nodelist), 2):
+            names.append(nodelist[i][1])
+        return Global(names, lineno=nodelist[0][2])
+
+    def exec_stmt(self, nodelist):
+        # exec_stmt: 'exec' expr ['in' expr [',' expr]]
+        expr1 = self.com_node(nodelist[1])
+        if len(nodelist) >= 4:
+            expr2 = self.com_node(nodelist[3])
+            if len(nodelist) >= 6:
+                expr3 = self.com_node(nodelist[5])
+            else:
+                expr3 = None
+        else:
+            expr2 = expr3 = None
+
+        return Exec(expr1, expr2, expr3, lineno=nodelist[0][2])
+
+    def assert_stmt(self, nodelist):
+        # 'assert': test, [',' test]
+        expr1 = self.com_node(nodelist[1])
+        if (len(nodelist) == 4):
+            expr2 = self.com_node(nodelist[3])
+        else:
+            expr2 = None
+        return Assert(expr1, expr2, lineno=nodelist[0][2])
+
+    def if_stmt(self, nodelist):
+        # if: test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
+        tests = []
+        for i in range(0, len(nodelist) - 3, 4):
+            testNode = self.com_node(nodelist[i + 1])
+            suiteNode = self.com_node(nodelist[i + 3])
+            tests.append((testNode, suiteNode))
+
+        if len(nodelist) % 4 == 3:
+            elseNode = self.com_node(nodelist[-1])
+##      elseNode.lineno = nodelist[-1][1][2]
+        else:
+            elseNode = None
+        return If(tests, elseNode, lineno=nodelist[0][2])
+
+    def while_stmt(self, nodelist):
+        # 'while' test ':' suite ['else' ':' suite]
+
+        testNode = self.com_node(nodelist[1])
+        bodyNode = self.com_node(nodelist[3])
+
+        if len(nodelist) > 4:
+            elseNode = self.com_node(nodelist[6])
+        else:
+            elseNode = None
+
+        return While(testNode, bodyNode, elseNode, lineno=nodelist[0][2])
+
+    def for_stmt(self, nodelist):
+        # 'for' exprlist 'in' exprlist ':' suite ['else' ':' suite]
+
+        assignNode = self.com_assign(nodelist[1], OP_ASSIGN)
+        listNode = self.com_node(nodelist[3])
+        bodyNode = self.com_node(nodelist[5])
+
+        if len(nodelist) > 8:
+            elseNode = self.com_node(nodelist[8])
+        else:
+            elseNode = None
+
+        return For(assignNode, listNode, bodyNode, elseNode,
+                   lineno=nodelist[0][2])
+
+    def try_stmt(self, nodelist):
+        return self.com_try_except_finally(nodelist)
+
+    def with_stmt(self, nodelist):
+        return self.com_with(nodelist)
+
+    def with_var(self, nodelist):
+        return self.com_with_var(nodelist)
+
+    def suite(self, nodelist):
+        # simple_stmt | NEWLINE INDENT NEWLINE* (stmt NEWLINE*)+ DEDENT
+        if len(nodelist) == 1:
+            return self.com_stmt(nodelist[0])
+
+        stmts = []
+        for node in nodelist:
+            if node[0] == symbol.stmt:
+                self.com_append_stmt(stmts, node)
+        return Stmt(stmts)
+
+    # --------------------------------------------------------------
+    #
+    # EXPRESSION NODES  (invoked by com_node())
+    #
+
+    def testlist(self, nodelist):
+        # testlist: expr (',' expr)* [',']
+        # testlist_safe: test [(',' test)+ [',']]
+        # exprlist: expr (',' expr)* [',']
+        return self.com_binary(Tuple, nodelist)
+
+    testlist_safe = testlist # XXX
+    testlist1 = testlist
+    exprlist = testlist
+
+    def testlist_gexp(self, nodelist):
+        if len(nodelist) == 2 and nodelist[1][0] == symbol.gen_for:
+            test = self.com_node(nodelist[0])
+            return self.com_generator_expression(test, nodelist[1])
+        return self.testlist(nodelist)
+
+    def test(self, nodelist):
+        # or_test ['if' or_test 'else' test] | lambdef
+        if len(nodelist) == 1 and nodelist[0][0] == symbol.lambdef:
+            return self.lambdef(nodelist[0])
+        then = self.com_node(nodelist[0])
+        if len(nodelist) > 1:
+            assert len(nodelist) == 5
+            assert nodelist[1][1] == 'if'
+            assert nodelist[3][1] == 'else'
+            test = self.com_node(nodelist[2])
+            else_ = self.com_node(nodelist[4])
+            return IfExp(test, then, else_, lineno=nodelist[1][2])
+        return then
+
+    def or_test(self, nodelist):
+        # and_test ('or' and_test)* | lambdef
+        if len(nodelist) == 1 and nodelist[0][0] == symbol.lambdef:
+            return self.lambdef(nodelist[0])
+        return self.com_binary(Or, nodelist)
+    old_test = or_test
+
+    def and_test(self, nodelist):
+        # not_test ('and' not_test)*
+        return self.com_binary(And, nodelist)
+
+    def not_test(self, nodelist):
+        # 'not' not_test | comparison
+        result = self.com_node(nodelist[-1])
+        if len(nodelist) == 2:
+            return Not(result, lineno=nodelist[0][2])
+        return result
+
+    def comparison(self, nodelist):
+        # comparison: expr (comp_op expr)*
+        node = self.com_node(nodelist[0])
+        if len(nodelist) == 1:
+            return node
+
+        results = []
+        for i in range(2, len(nodelist), 2):
+            nl = nodelist[i-1]
+
+            # comp_op: '<' | '>' | '=' | '>=' | '<=' | '<>' | '!=' | '=='
+            #          | 'in' | 'not' 'in' | 'is' | 'is' 'not'
+            n = nl[1]
+            if n[0] == token.NAME:
+                type = n[1]
+                if len(nl) == 3:
+                    if type == 'not':
+                        type = 'not in'
+                    else:
+                        type = 'is not'
+            else:
+                type = _cmp_types[n[0]]
+
+            lineno = nl[1][2]
+            results.append((type, self.com_node(nodelist[i])))
+
+        # we need a special "compare" node so that we can distinguish
+        #   3 < x < 5   from    (3 < x) < 5
+        # the two have very different semantics and results (note that the
+        # latter form is always true)
+
+        return Compare(node, results, lineno=lineno)
+
+    def expr(self, nodelist):
+        # xor_expr ('|' xor_expr)*
+        return self.com_binary(Bitor, nodelist)
+
+    def xor_expr(self, nodelist):
+        # xor_expr ('^' xor_expr)*
+        return self.com_binary(Bitxor, nodelist)
+
+    def and_expr(self, nodelist):
+        # xor_expr ('&' xor_expr)*
+        return self.com_binary(Bitand, nodelist)
+
+    def shift_expr(self, nodelist):
+        # shift_expr ('<<'|'>>' shift_expr)*
+        node = self.com_node(nodelist[0])
+        for i in range(2, len(nodelist), 2):
+            right = self.com_node(nodelist[i])
+            if nodelist[i-1][0] == token.LEFTSHIFT:
+                node = LeftShift([node, right], lineno=nodelist[1][2])
+            elif nodelist[i-1][0] == token.RIGHTSHIFT:
+                node = RightShift([node, right], lineno=nodelist[1][2])
+            else:
+                raise ValueError, "unexpected token: %s" % nodelist[i-1][0]
+        return node
+
+    def arith_expr(self, nodelist):
+        node = self.com_node(nodelist[0])
+        for i in range(2, len(nodelist), 2):
+            right = self.com_node(nodelist[i])
+            if nodelist[i-1][0] == token.PLUS:
+                node = Add([node, right], lineno=nodelist[1][2])
+            elif nodelist[i-1][0] == token.MINUS:
+                node = Sub([node, right], lineno=nodelist[1][2])
+            else:
+                raise ValueError, "unexpected token: %s" % nodelist[i-1][0]
+        return node
+
+    def term(self, nodelist):
+        node = self.com_node(nodelist[0])
+        for i in range(2, len(nodelist), 2):
+            right = self.com_node(nodelist[i])
+            t = nodelist[i-1][0]
+            if t == token.STAR:
+                node = Mul([node, right])
+            elif t == token.SLASH:
+                node = Div([node, right])
+            elif t == token.PERCENT:
+                node = Mod([node, right])
+            elif t == token.DOUBLESLASH:
+                node = FloorDiv([node, right])
+            else:
+                raise ValueError, "unexpected token: %s" % t
+            node.lineno = nodelist[1][2]
+        return node
+
+    def factor(self, nodelist):
+        elt = nodelist[0]
+        t = elt[0]
+        node = self.lookup_node(nodelist[-1])(nodelist[-1][1:])
+        # need to handle (unary op)constant here...
+        if t == token.PLUS:
+            return UnaryAdd(node, lineno=elt[2])
+        elif t == token.MINUS:
+            return UnarySub(node, lineno=elt[2])
+        elif t == token.TILDE:
+            node = Invert(node, lineno=elt[2])
+        return node
+
+    def power(self, nodelist):
+        # power: atom trailer* ('**' factor)*
+        node = self.com_node(nodelist[0])
+        for i in range(1, len(nodelist)):
+            elt = nodelist[i]
+            if elt[0] == token.DOUBLESTAR:
+                return Power([node, self.com_node(nodelist[i+1])],
+                             lineno=elt[2])
+
+            node = self.com_apply_trailer(node, elt)
+
+        return node
+
+    def atom(self, nodelist):
+        return self._atom_dispatch[nodelist[0][0]](nodelist)
+
+    def atom_lpar(self, nodelist):
+        if nodelist[1][0] == token.RPAR:
+            return Tuple((), lineno=nodelist[0][2])
+        return self.com_node(nodelist[1])
+
+    def atom_lsqb(self, nodelist):
+        if nodelist[1][0] == token.RSQB:
+            return List((), lineno=nodelist[0][2])
+        return self.com_list_constructor(nodelist[1])
+
+    def atom_lbrace(self, nodelist):
+        if nodelist[1][0] == token.RBRACE:
+            return Dict((), lineno=nodelist[0][2])
+        return self.com_dictmaker(nodelist[1])
+
+    def atom_backquote(self, nodelist):
+        return Backquote(self.com_node(nodelist[1]))
+
+    def atom_number(self, nodelist):
+        ### need to verify this matches compile.c
+        k = eval(nodelist[0][1])
+        return Const(k, lineno=nodelist[0][2])
+
+    def decode_literal(self, lit):
+        if self.encoding:
+            # this is particularly fragile & a bit of a
+            # hack... changes in compile.c:parsestr and
+            # tokenizer.c must be reflected here.
+            if self.encoding not in ['utf-8', 'iso-8859-1']:
+                lit = unicode(lit, 'utf-8').encode(self.encoding)
+            return eval("# coding: %s\n%s" % (self.encoding, lit))
+        else:
+            return eval(lit)
+
+    def atom_string(self, nodelist):
+        k = ''
+        for node in nodelist:
+            k += self.decode_literal(node[1])
+        return Const(k, lineno=nodelist[0][2])
+
+    def atom_name(self, nodelist):
+        return Name(nodelist[0][1], lineno=nodelist[0][2])
+
+    # --------------------------------------------------------------
+    #
+    # INTERNAL PARSING UTILITIES
+    #
+
+    # The use of com_node() introduces a lot of extra stack frames,
+    # enough to cause a stack overflow compiling test.test_parser with
+    # the standard interpreter recursionlimit.  The com_node() is a
+    # convenience function that hides the dispatch details, but comes
+    # at a very high cost.  It is more efficient to dispatch directly
+    # in the callers.  In these cases, use lookup_node() and call the
+    # dispatched node directly.
+
+    def lookup_node(self, node):
+        return self._dispatch[node[0]]
+
+    def com_node(self, node):
+        # Note: compile.c has handling in com_node for del_stmt, pass_stmt,
+        #       break_stmt, stmt, small_stmt, flow_stmt, simple_stmt,
+        #       and compound_stmt.
+        #       We'll just dispatch them.
+        return self._dispatch[node[0]](node[1:])
+
+    def com_NEWLINE(self, *args):
+        # A ';' at the end of a line can make a NEWLINE token appear
+        # here, Render it harmless. (genc discards ('discard',
+        # ('const', xxxx)) Nodes)
+        return Discard(Const(None))
+
+    def com_arglist(self, nodelist):
+        # varargslist:
+        #     (fpdef ['=' test] ',')* ('*' NAME [',' '**' NAME] | '**' NAME)
+        #   | fpdef ['=' test] (',' fpdef ['=' test])* [',']
+        # fpdef: NAME | '(' fplist ')'
+        # fplist: fpdef (',' fpdef)* [',']
+        names = []
+        defaults = []
+        flags = 0
+
+        i = 0
+        while i < len(nodelist):
+            node = nodelist[i]
+            if node[0] == token.STAR or node[0] == token.DOUBLESTAR:
+                if node[0] == token.STAR:
+                    node = nodelist[i+1]
+                    if node[0] == token.NAME:
+                        names.append(node[1])
+                        flags = flags | CO_VARARGS
+                        i = i + 3
+
+                if i < len(nodelist):
+                    # should be DOUBLESTAR
+                    t = nodelist[i][0]
+                    if t == token.DOUBLESTAR:
+                        node = nodelist[i+1]
+                    else:
+                        raise ValueError, "unexpected token: %s" % t
+                    names.append(node[1])
+                    flags = flags | CO_VARKEYWORDS
+
+                break
+
+            # fpdef: NAME | '(' fplist ')'
+            names.append(self.com_fpdef(node))
+
+            i = i + 1
+            if i < len(nodelist) and nodelist[i][0] == token.EQUAL:
+                defaults.append(self.com_node(nodelist[i + 1]))
+                i = i + 2
+            elif len(defaults):
+                # we have already seen an argument with default, but here
+                # came one without
+                raise SyntaxError, "non-default argument follows default argument"
+
+            # skip the comma
+            i = i + 1
+
+        return names, defaults, flags
+
+    def com_fpdef(self, node):
+        # fpdef: NAME | '(' fplist ')'
+        if node[1][0] == token.LPAR:
+            return self.com_fplist(node[2])
+        return node[1][1]
+
+    def com_fplist(self, node):
+        # fplist: fpdef (',' fpdef)* [',']
+        if len(node) == 2:
+            return self.com_fpdef(node[1])
+        list = []
+        for i in range(1, len(node), 2):
+            list.append(self.com_fpdef(node[i]))
+        return tuple(list)
+
+    def com_dotted_name(self, node):
+        # String together the dotted names and return the string
+        name = ""
+        for n in node:
+            if type(n) == type(()) and n[0] == 1:
+                name = name + n[1] + '.'
+        return name[:-1]
+
+    def com_dotted_as_name(self, node):
+        assert node[0] == symbol.dotted_as_name
+        node = node[1:]
+        dot = self.com_dotted_name(node[0][1:])
+        if len(node) == 1:
+            return dot, None
+        assert node[1][1] == 'as'
+        assert node[2][0] == token.NAME
+        return dot, node[2][1]
+
+    def com_dotted_as_names(self, node):
+        assert node[0] == symbol.dotted_as_names
+        node = node[1:]
+        names = [self.com_dotted_as_name(node[0])]
+        for i in range(2, len(node), 2):
+            names.append(self.com_dotted_as_name(node[i]))
+        return names
+
+    def com_import_as_name(self, node):
+        assert node[0] == symbol.import_as_name
+        node = node[1:]
+        assert node[0][0] == token.NAME
+        if len(node) == 1:
+            return node[0][1], None
+        assert node[1][1] == 'as', node
+        assert node[2][0] == token.NAME
+        return node[0][1], node[2][1]
+
+    def com_import_as_names(self, node):
+        assert node[0] == symbol.import_as_names
+        node = node[1:]
+        names = [self.com_import_as_name(node[0])]
+        for i in range(2, len(node), 2):
+            names.append(self.com_import_as_name(node[i]))
+        return names
+
+    def com_bases(self, node):
+        bases = []
+        for i in range(1, len(node), 2):
+            bases.append(self.com_node(node[i]))
+        return bases
+
+    def com_try_except_finally(self, nodelist):
+        # ('try' ':' suite
+        #  ((except_clause ':' suite)+ ['else' ':' suite] ['finally' ':' suite]
+        #   | 'finally' ':' suite))
+
+        if nodelist[3][0] == token.NAME:
+            # first clause is a finally clause: only try-finally
+            return TryFinally(self.com_node(nodelist[2]),
+                              self.com_node(nodelist[5]),
+                              lineno=nodelist[0][2])
+
+        #tryexcept:  [TryNode, [except_clauses], elseNode)]
+        clauses = []
+        elseNode = None
+        finallyNode = None
+        for i in range(3, len(nodelist), 3):
+            node = nodelist[i]
+            if node[0] == symbol.except_clause:
+                # except_clause: 'except' [expr [',' expr]] */
+                if len(node) > 2:
+                    expr1 = self.com_node(node[2])
+                    if len(node) > 4:
+                        expr2 = self.com_assign(node[4], OP_ASSIGN)
+                    else:
+                        expr2 = None
+                else:
+                    expr1 = expr2 = None
+                clauses.append((expr1, expr2, self.com_node(nodelist[i+2])))
+
+            if node[0] == token.NAME:
+                if node[1] == 'else':
+                    elseNode = self.com_node(nodelist[i+2])
+                elif node[1] == 'finally':
+                    finallyNode = self.com_node(nodelist[i+2])
+        try_except = TryExcept(self.com_node(nodelist[2]), clauses, elseNode,
+                               lineno=nodelist[0][2])
+        if finallyNode:
+            return TryFinally(try_except, finallyNode, lineno=nodelist[0][2])
+        else:
+            return try_except
+
+    def com_with(self, nodelist):
+        # with_stmt: 'with' expr [with_var] ':' suite
+        expr = self.com_node(nodelist[1])
+        body = self.com_node(nodelist[-1])
+        if nodelist[2][0] == token.COLON:
+            var = None
+        else:
+            var = self.com_assign(nodelist[2][2], OP_ASSIGN)
+        return With(expr, var, body, lineno=nodelist[0][2])
+
+    def com_with_var(self, nodelist):
+        # with_var: 'as' expr
+        return self.com_node(nodelist[1])
+
+    def com_augassign_op(self, node):
+        assert node[0] == symbol.augassign
+        return node[1]
+
+    def com_augassign(self, node):
+        """Return node suitable for lvalue of augmented assignment
+
+        Names, slices, and attributes are the only allowable nodes.
+        """
+        l = self.com_node(node)
+        if l.__class__ in (Name, Slice, Subscript, Getattr):
+            return l
+        raise SyntaxError, "can't assign to %s" % l.__class__.__name__
+
+    def com_assign(self, node, assigning):
+        # return a node suitable for use as an "lvalue"
+        # loop to avoid trivial recursion
+        while 1:
+            t = node[0]
+            if t in (symbol.exprlist, symbol.testlist, symbol.testlist_safe, symbol.testlist_gexp):
+                if len(node) > 2:
+                    return self.com_assign_tuple(node, assigning)
+                node = node[1]
+            elif t in _assign_types:
+                if len(node) > 2:
+                    raise SyntaxError, "can't assign to operator"
+                node = node[1]
+            elif t == symbol.power:
+                if node[1][0] != symbol.atom:
+                    raise SyntaxError, "can't assign to operator"
+                if len(node) > 2:
+                    primary = self.com_node(node[1])
+                    for i in range(2, len(node)-1):
+                        ch = node[i]
+                        if ch[0] == token.DOUBLESTAR:
+                            raise SyntaxError, "can't assign to operator"
+                        primary = self.com_apply_trailer(primary, ch)
+                    return self.com_assign_trailer(primary, node[-1],
+                                                   assigning)
+                node = node[1]
+            elif t == symbol.atom:
+                t = node[1][0]
+                if t == token.LPAR:
+                    node = node[2]
+                    if node[0] == token.RPAR:
+                        raise SyntaxError, "can't assign to ()"
+                elif t == token.LSQB:
+                    node = node[2]
+                    if node[0] == token.RSQB:
+                        raise SyntaxError, "can't assign to []"
+                    return self.com_assign_list(node, assigning)
+                elif t == token.NAME:
+                    return self.com_assign_name(node[1], assigning)
+                else:
+                    raise SyntaxError, "can't assign to literal"
+            else:
+                raise SyntaxError, "bad assignment (%s)" % t
+
+    def com_assign_tuple(self, node, assigning):
+        assigns = []
+        for i in range(1, len(node), 2):
+            assigns.append(self.com_assign(node[i], assigning))
+        return AssTuple(assigns, lineno=extractLineNo(node))
+
+    def com_assign_list(self, node, assigning):
+        assigns = []
+        for i in range(1, len(node), 2):
+            if i + 1 < len(node):
+                if node[i + 1][0] == symbol.list_for:
+                    raise SyntaxError, "can't assign to list comprehension"
+                assert node[i + 1][0] == token.COMMA, node[i + 1]
+            assigns.append(self.com_assign(node[i], assigning))
+        return AssList(assigns, lineno=extractLineNo(node))
+
+    def com_assign_name(self, node, assigning):
+        return AssName(node[1], assigning, lineno=node[2])
+
+    def com_assign_trailer(self, primary, node, assigning):
+        t = node[1][0]
+        if t == token.DOT:
+            return self.com_assign_attr(primary, node[2], assigning)
+        if t == token.LSQB:
+            return self.com_subscriptlist(primary, node[2], assigning)
+        if t == token.LPAR:
+            raise SyntaxError, "can't assign to function call"
+        raise SyntaxError, "unknown trailer type: %s" % t
+
+    def com_assign_attr(self, primary, node, assigning):
+        return AssAttr(primary, node[1], assigning, lineno=node[-1])
+
+    def com_binary(self, constructor, nodelist):
+        "Compile 'NODE (OP NODE)*' into (type, [ node1, ..., nodeN ])."
+        l = len(nodelist)
+        if l == 1:
+            n = nodelist[0]
+            return self.lookup_node(n)(n[1:])
+        items = []
+        for i in range(0, l, 2):
+            n = nodelist[i]
+            items.append(self.lookup_node(n)(n[1:]))
+        return constructor(items, lineno=extractLineNo(nodelist))
+
+    def com_stmt(self, node):
+        result = self.lookup_node(node)(node[1:])
+        assert result is not None
+        if isinstance(result, Stmt):
+            return result
+        return Stmt([result])
+
+    def com_append_stmt(self, stmts, node):
+        result = self.lookup_node(node)(node[1:])
+        assert result is not None
+        if isinstance(result, Stmt):
+            stmts.extend(result.nodes)
+        else:
+            stmts.append(result)
+
+    if hasattr(symbol, 'list_for'):
+        def com_list_constructor(self, nodelist):
+            # listmaker: test ( list_for | (',' test)* [','] )
+            values = []
+            for i in range(1, len(nodelist)):
+                if nodelist[i][0] == symbol.list_for:
+                    assert len(nodelist[i:]) == 1
+                    return self.com_list_comprehension(values[0],
+                                                       nodelist[i])
+                elif nodelist[i][0] == token.COMMA:
+                    continue
+                values.append(self.com_node(nodelist[i]))
+            return List(values, lineno=values[0].lineno)
+
+        def com_list_comprehension(self, expr, node):
+            # list_iter: list_for | list_if
+            # list_for: 'for' exprlist 'in' testlist [list_iter]
+            # list_if: 'if' test [list_iter]
+
+            # XXX should raise SyntaxError for assignment
+
+            lineno = node[1][2]
+            fors = []
+            while node:
+                t = node[1][1]
+                if t == 'for':
+                    assignNode = self.com_assign(node[2], OP_ASSIGN)
+                    listNode = self.com_node(node[4])
+                    newfor = ListCompFor(assignNode, listNode, [])
+                    newfor.lineno = node[1][2]
+                    fors.append(newfor)
+                    if len(node) == 5:
+                        node = None
+                    else:
+                        node = self.com_list_iter(node[5])
+                elif t == 'if':
+                    test = self.com_node(node[2])
+                    newif = ListCompIf(test, lineno=node[1][2])
+                    newfor.ifs.append(newif)
+                    if len(node) == 3:
+                        node = None
+                    else:
+                        node = self.com_list_iter(node[3])
+                else:
+                    raise SyntaxError, \
+                          ("unexpected list comprehension element: %s %d"
+                           % (node, lineno))
+            return ListComp(expr, fors, lineno=lineno)
+
+        def com_list_iter(self, node):
+            assert node[0] == symbol.list_iter
+            return node[1]
+    else:
+        def com_list_constructor(self, nodelist):
+            values = []
+            for i in range(1, len(nodelist), 2):
+                values.append(self.com_node(nodelist[i]))
+            return List(values, lineno=values[0].lineno)
+
+    if hasattr(symbol, 'gen_for'):
+        def com_generator_expression(self, expr, node):
+            # gen_iter: gen_for | gen_if
+            # gen_for: 'for' exprlist 'in' test [gen_iter]
+            # gen_if: 'if' test [gen_iter]
+
+            lineno = node[1][2]
+            fors = []
+            while node:
+                t = node[1][1]
+                if t == 'for':
+                    assignNode = self.com_assign(node[2], OP_ASSIGN)
+                    genNode = self.com_node(node[4])
+                    newfor = GenExprFor(assignNode, genNode, [],
+                                        lineno=node[1][2])
+                    fors.append(newfor)
+                    if (len(node)) == 5:
+                        node = None
+                    else:
+                        node = self.com_gen_iter(node[5])
+                elif t == 'if':
+                    test = self.com_node(node[2])
+                    newif = GenExprIf(test, lineno=node[1][2])
+                    newfor.ifs.append(newif)
+                    if len(node) == 3:
+                        node = None
+                    else:
+                        node = self.com_gen_iter(node[3])
+                else:
+                    raise SyntaxError, \
+                            ("unexpected generator expression element: %s %d"
+                             % (node, lineno))
+            fors[0].is_outmost = True
+            return GenExpr(GenExprInner(expr, fors), lineno=lineno)
+
+        def com_gen_iter(self, node):
+            assert node[0] == symbol.gen_iter
+            return node[1]
+
+    def com_dictmaker(self, nodelist):
+        # dictmaker: test ':' test (',' test ':' value)* [',']
+        items = []
+        for i in range(1, len(nodelist), 4):
+            items.append((self.com_node(nodelist[i]),
+                          self.com_node(nodelist[i+2])))
+        return Dict(items, lineno=items[0][0].lineno)
+
+    def com_apply_trailer(self, primaryNode, nodelist):
+        t = nodelist[1][0]
+        if t == token.LPAR:
+            return self.com_call_function(primaryNode, nodelist[2])
+        if t == token.DOT:
+            return self.com_select_member(primaryNode, nodelist[2])
+        if t == token.LSQB:
+            return self.com_subscriptlist(primaryNode, nodelist[2], OP_APPLY)
+
+        raise SyntaxError, 'unknown node type: %s' % t
+
+    def com_select_member(self, primaryNode, nodelist):
+        if nodelist[0] != token.NAME:
+            raise SyntaxError, "member must be a name"
+        return Getattr(primaryNode, nodelist[1], lineno=nodelist[2])
+
+    def com_call_function(self, primaryNode, nodelist):
+        if nodelist[0] == token.RPAR:
+            return CallFunc(primaryNode, [], lineno=extractLineNo(nodelist))
+        args = []
+        kw = 0
+        len_nodelist = len(nodelist)
+        for i in range(1, len_nodelist, 2):
+            node = nodelist[i]
+            if node[0] == token.STAR or node[0] == token.DOUBLESTAR:
+                break
+            kw, result = self.com_argument(node, kw)
+
+            if len_nodelist != 2 and isinstance(result, GenExpr) \
+               and len(node) == 3 and node[2][0] == symbol.gen_for:
+                # allow f(x for x in y), but reject f(x for x in y, 1)
+                # should use f((x for x in y), 1) instead of f(x for x in y, 1)
+                raise SyntaxError, 'generator expression needs parenthesis'
+
+            args.append(result)
+        else:
+            # No broken by star arg, so skip the last one we processed.
+            i = i + 1
+        if i < len_nodelist and nodelist[i][0] == token.COMMA:
+            # need to accept an application that looks like "f(a, b,)"
+            i = i + 1
+        star_node = dstar_node = None
+        while i < len_nodelist:
+            tok = nodelist[i]
+            ch = nodelist[i+1]
+            i = i + 3
+            if tok[0]==token.STAR:
+                if star_node is not None:
+                    raise SyntaxError, 'already have the varargs indentifier'
+                star_node = self.com_node(ch)
+            elif tok[0]==token.DOUBLESTAR:
+                if dstar_node is not None:
+                    raise SyntaxError, 'already have the kwargs indentifier'
+                dstar_node = self.com_node(ch)
+            else:
+                raise SyntaxError, 'unknown node type: %s' % tok
+        return CallFunc(primaryNode, args, star_node, dstar_node,
+                        lineno=extractLineNo(nodelist))
+
+    def com_argument(self, nodelist, kw):
+        if len(nodelist) == 3 and nodelist[2][0] == symbol.gen_for:
+            test = self.com_node(nodelist[1])
+            return 0, self.com_generator_expression(test, nodelist[2])
+        if len(nodelist) == 2:
+            if kw:
+                raise SyntaxError, "non-keyword arg after keyword arg"
+            return 0, self.com_node(nodelist[1])
+        result = self.com_node(nodelist[3])
+        n = nodelist[1]
+        while len(n) == 2 and n[0] != token.NAME:
+            n = n[1]
+        if n[0] != token.NAME:
+            raise SyntaxError, "keyword can't be an expression (%s)"%n[0]
+        node = Keyword(n[1], result, lineno=n[2])
+        return 1, node
+
+    def com_subscriptlist(self, primary, nodelist, assigning):
+        # slicing:      simple_slicing | extended_slicing
+        # simple_slicing:   primary "[" short_slice "]"
+        # extended_slicing: primary "[" slice_list "]"
+        # slice_list:   slice_item ("," slice_item)* [","]
+
+        # backwards compat slice for '[i:j]'
+        if len(nodelist) == 2:
+            sub = nodelist[1]
+            if (sub[1][0] == token.COLON or \
+                            (len(sub) > 2 and sub[2][0] == token.COLON)) and \
+                            sub[-1][0] != symbol.sliceop:
+                return self.com_slice(primary, sub, assigning)
+
+        subscripts = []
+        for i in range(1, len(nodelist), 2):
+            subscripts.append(self.com_subscript(nodelist[i]))
+        return Subscript(primary, assigning, subscripts,
+                         lineno=extractLineNo(nodelist))
+
+    def com_subscript(self, node):
+        # slice_item: expression | proper_slice | ellipsis
+        ch = node[1]
+        t = ch[0]
+        if t == token.DOT and node[2][0] == token.DOT:
+            return Ellipsis()
+        if t == token.COLON or len(node) > 2:
+            return self.com_sliceobj(node)
+        return self.com_node(ch)
+
+    def com_sliceobj(self, node):
+        # proper_slice: short_slice | long_slice
+        # short_slice:  [lower_bound] ":" [upper_bound]
+        # long_slice:   short_slice ":" [stride]
+        # lower_bound:  expression
+        # upper_bound:  expression
+        # stride:       expression
+        #
+        # Note: a stride may be further slicing...
+
+        items = []
+
+        if node[1][0] == token.COLON:
+            items.append(Const(None))
+            i = 2
+        else:
+            items.append(self.com_node(node[1]))
+            # i == 2 is a COLON
+            i = 3
+
+        if i < len(node) and node[i][0] == symbol.test:
+            items.append(self.com_node(node[i]))
+            i = i + 1
+        else:
+            items.append(Const(None))
+
+        # a short_slice has been built. look for long_slice now by looking
+        # for strides...
+        for j in range(i, len(node)):
+            ch = node[j]
+            if len(ch) == 2:
+                items.append(Const(None))
+            else:
+                items.append(self.com_node(ch[2]))
+        return Sliceobj(items, lineno=extractLineNo(node))
+
+    def com_slice(self, primary, node, assigning):
+        # short_slice:  [lower_bound] ":" [upper_bound]
+        lower = upper = None
+        if len(node) == 3:
+            if node[1][0] == token.COLON:
+                upper = self.com_node(node[2])
+            else:
+                lower = self.com_node(node[1])
+        elif len(node) == 4:
+            lower = self.com_node(node[1])
+            upper = self.com_node(node[3])
+        return Slice(primary, assigning, lower, upper,
+                     lineno=extractLineNo(node))
+
+    def get_docstring(self, node, n=None):
+        if n is None:
+            n = node[0]
+            node = node[1:]
+        if n == symbol.suite:
+            if len(node) == 1:
+                return self.get_docstring(node[0])
+            for sub in node:
+                if sub[0] == symbol.stmt:
+                    return self.get_docstring(sub)
+            return None
+        if n == symbol.file_input:
+            for sub in node:
+                if sub[0] == symbol.stmt:
+                    return self.get_docstring(sub)
+            return None
+        if n == symbol.atom:
+            if node[0][0] == token.STRING:
+                s = ''
+                for t in node:
+                    s = s + eval(t[1])
+                return s
+            return None
+        if n == symbol.stmt or n == symbol.simple_stmt \
+           or n == symbol.small_stmt:
+            return self.get_docstring(node[0])
+        if n in _doc_nodes and len(node) == 1:
+            return self.get_docstring(node[0])
+        return None
+
+
+_doc_nodes = [
+    symbol.expr_stmt,
+    symbol.testlist,
+    symbol.testlist_safe,
+    symbol.test,
+    symbol.or_test,
+    symbol.and_test,
+    symbol.not_test,
+    symbol.comparison,
+    symbol.expr,
+    symbol.xor_expr,
+    symbol.and_expr,
+    symbol.shift_expr,
+    symbol.arith_expr,
+    symbol.term,
+    symbol.factor,
+    symbol.power,
+    ]
+
+# comp_op: '<' | '>' | '=' | '>=' | '<=' | '<>' | '!=' | '=='
+#             | 'in' | 'not' 'in' | 'is' | 'is' 'not'
+_cmp_types = {
+    token.LESS : '<',
+    token.GREATER : '>',
+    token.EQEQUAL : '==',
+    token.EQUAL : '==',
+    token.LESSEQUAL : '<=',
+    token.GREATEREQUAL : '>=',
+    token.NOTEQUAL : '!=',
+    }
+
+_legal_node_types = [
+    symbol.funcdef,
+    symbol.classdef,
+    symbol.stmt,
+    symbol.small_stmt,
+    symbol.flow_stmt,
+    symbol.simple_stmt,
+    symbol.compound_stmt,
+    symbol.expr_stmt,
+    symbol.print_stmt,
+    symbol.del_stmt,
+    symbol.pass_stmt,
+    symbol.break_stmt,
+    symbol.continue_stmt,
+    symbol.return_stmt,
+    symbol.raise_stmt,
+    symbol.import_stmt,
+    symbol.global_stmt,
+    symbol.exec_stmt,
+    symbol.assert_stmt,
+    symbol.if_stmt,
+    symbol.while_stmt,
+    symbol.for_stmt,
+    symbol.try_stmt,
+    symbol.with_stmt,
+    symbol.suite,
+    symbol.testlist,
+    symbol.testlist_safe,
+    symbol.test,
+    symbol.and_test,
+    symbol.not_test,
+    symbol.comparison,
+    symbol.exprlist,
+    symbol.expr,
+    symbol.xor_expr,
+    symbol.and_expr,
+    symbol.shift_expr,
+    symbol.arith_expr,
+    symbol.term,
+    symbol.factor,
+    symbol.power,
+    symbol.atom,
+    ]
+
+if hasattr(symbol, 'yield_stmt'):
+    _legal_node_types.append(symbol.yield_stmt)
+if hasattr(symbol, 'yield_expr'):
+    _legal_node_types.append(symbol.yield_expr)
+
+_assign_types = [
+    symbol.test,
+    symbol.or_test,
+    symbol.and_test,
+    symbol.not_test,
+    symbol.comparison,
+    symbol.expr,
+    symbol.xor_expr,
+    symbol.and_expr,
+    symbol.shift_expr,
+    symbol.arith_expr,
+    symbol.term,
+    symbol.factor,
+    ]
+
+_names = {}
+for k, v in symbol.sym_name.items():
+    _names[k] = v
+for k, v in token.tok_name.items():
+    _names[k] = v
+
+def debug_tree(tree):
+    l = []
+    for elt in tree:
+        if isinstance(elt, int):
+            l.append(_names.get(elt, elt))
+        elif isinstance(elt, str):
+            l.append(elt)
+        else:
+            l.append(debug_tree(elt))
+    return l

Added: vendor/Python/current/Lib/compiler/visitor.py
===================================================================
--- vendor/Python/current/Lib/compiler/visitor.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/compiler/visitor.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,113 @@
+from compiler import ast
+
+# XXX should probably rename ASTVisitor to ASTWalker
+# XXX can it be made even more generic?
+
+class ASTVisitor:
+    """Performs a depth-first walk of the AST
+
+    The ASTVisitor will walk the AST, performing either a preorder or
+    postorder traversal depending on which method is called.
+
+    methods:
+    preorder(tree, visitor)
+    postorder(tree, visitor)
+        tree: an instance of ast.Node
+        visitor: an instance with visitXXX methods
+
+    The ASTVisitor is responsible for walking over the tree in the
+    correct order.  For each node, it checks the visitor argument for
+    a method named 'visitNodeType' where NodeType is the name of the
+    node's class, e.g. Class.  If the method exists, it is called
+    with the node as its sole argument.
+
+    The visitor method for a particular node type can control how
+    child nodes are visited during a preorder walk.  (It can't control
+    the order during a postorder walk, because it is called _after_
+    the walk has occurred.)  The ASTVisitor modifies the visitor
+    argument by adding a visit method to the visitor; this method can
+    be used to visit a child node of arbitrary type.
+    """
+
+    VERBOSE = 0
+
+    def __init__(self):
+        self.node = None
+        self._cache = {}
+
+    def default(self, node, *args):
+        for child in node.getChildNodes():
+            self.dispatch(child, *args)
+
+    def dispatch(self, node, *args):
+        self.node = node
+        klass = node.__class__
+        meth = self._cache.get(klass, None)
+        if meth is None:
+            className = klass.__name__
+            meth = getattr(self.visitor, 'visit' + className, self.default)
+            self._cache[klass] = meth
+##        if self.VERBOSE > 0:
+##            className = klass.__name__
+##            if self.VERBOSE == 1:
+##                if meth == 0:
+##                    print "dispatch", className
+##            else:
+##                print "dispatch", className, (meth and meth.__name__ or '')
+        return meth(node, *args)
+
+    def preorder(self, tree, visitor, *args):
+        """Do preorder walk of tree using visitor"""
+        self.visitor = visitor
+        visitor.visit = self.dispatch
+        self.dispatch(tree, *args) # XXX *args make sense?
+
+class ExampleASTVisitor(ASTVisitor):
+    """Prints examples of the nodes that aren't visited
+
+    This visitor-driver is only useful for development, when it's
+    helpful to develop a visitor incrementally, and get feedback on what
+    you still have to do.
+    """
+    examples = {}
+
+    def dispatch(self, node, *args):
+        self.node = node
+        meth = self._cache.get(node.__class__, None)
+        className = node.__class__.__name__
+        if meth is None:
+            meth = getattr(self.visitor, 'visit' + className, 0)
+            self._cache[node.__class__] = meth
+        if self.VERBOSE > 1:
+            print "dispatch", className, (meth and meth.__name__ or '')
+        if meth:
+            meth(node, *args)
+        elif self.VERBOSE > 0:
+            klass = node.__class__
+            if not self.examples.has_key(klass):
+                self.examples[klass] = klass
+                print
+                print self.visitor
+                print klass
+                for attr in dir(node):
+                    if attr[0] != '_':
+                        print "\t", "%-12.12s" % attr, getattr(node, attr)
+                print
+            return self.default(node, *args)
+
+# XXX this is an API change
+
+_walker = ASTVisitor
+def walk(tree, visitor, walker=None, verbose=None):
+    if walker is None:
+        walker = _walker()
+    if verbose is not None:
+        walker.VERBOSE = verbose
+    walker.preorder(tree, visitor)
+    return walker.visitor
+
+def dumpNode(node):
+    print node.__class__
+    for attr in dir(node):
+        if attr[0] != '_':
+            print "\t", "%-10.10s" % attr, getattr(node, attr)

Added: vendor/Python/current/Lib/contextlib.py
===================================================================
--- vendor/Python/current/Lib/contextlib.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/contextlib.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,154 @@
+"""Utilities for with-statement contexts.  See PEP 343."""
+
+import sys
+
+__all__ = ["contextmanager", "nested", "closing"]
+
+class GeneratorContextManager(object):
+    """Helper for @contextmanager decorator."""
+
+    def __init__(self, gen):
+        self.gen = gen
+
+    def __enter__(self):
+        try:
+            return self.gen.next()
+        except StopIteration:
+            raise RuntimeError("generator didn't yield")
+
+    def __exit__(self, type, value, traceback):
+        if type is None:
+            try:
+                self.gen.next()
+            except StopIteration:
+                return
+            else:
+                raise RuntimeError("generator didn't stop")
+        else:
+            try:
+                self.gen.throw(type, value, traceback)
+                raise RuntimeError("generator didn't stop after throw()")
+            except StopIteration, exc:
+                # Suppress the exception *unless* it's the same exception that
+                # was passed to throw().  This prevents a StopIteration
+                # raised inside the "with" statement from being suppressed
+                return exc is not value
+            except:
+                # only re-raise if it's *not* the exception that was
+                # passed to throw(), because __exit__() must not raise
+                # an exception unless __exit__() itself failed.  But throw()
+                # has to raise the exception to signal propagation, so this
+                # fixes the impedance mismatch between the throw() protocol
+                # and the __exit__() protocol.
+                #
+                if sys.exc_info()[1] is not value:
+                    raise
+
+
+def contextmanager(func):
+    """@contextmanager decorator.
+
+    Typical usage:
+
+        @contextmanager
+        def some_generator(<arguments>):
+            <setup>
+            try:
+                yield <value>
+            finally:
+                <cleanup>
+
+    This makes this:
+
+        with some_generator(<arguments>) as <variable>:
+            <body>
+
+    equivalent to this:
+
+        <setup>
+        try:
+            <variable> = <value>
+            <body>
+        finally:
+            <cleanup>
+
+    """
+    def helper(*args, **kwds):
+        return GeneratorContextManager(func(*args, **kwds))
+    try:
+        helper.__name__ = func.__name__
+        helper.__doc__ = func.__doc__
+        helper.__dict__ = func.__dict__
+    except:
+        pass
+    return helper
+
+
+ at contextmanager
+def nested(*managers):
+    """Support multiple context managers in a single with-statement.
+
+    Code like this:
+
+        with nested(A, B, C) as (X, Y, Z):
+            <body>
+
+    is equivalent to this:
+
+        with A as X:
+            with B as Y:
+                with C as Z:
+                    <body>
+
+    """
+    exits = []
+    vars = []
+    exc = (None, None, None)
+    try:
+        try:
+            for mgr in managers:
+                exit = mgr.__exit__
+                enter = mgr.__enter__
+                vars.append(enter())
+                exits.append(exit)
+            yield vars
+        except:
+            exc = sys.exc_info()
+    finally:
+        while exits:
+            exit = exits.pop()
+            try:
+                if exit(*exc):
+                    exc = (None, None, None)
+            except:
+                exc = sys.exc_info()
+        if exc != (None, None, None):
+            # Don't rely on sys.exc_info() still containing
+            # the right information. Another exception may
+            # have been raised and caught by an exit method
+            raise exc[0], exc[1], exc[2]
+
+
+class closing(object):
+    """Context to automatically close something at the end of a block.
+
+    Code like this:
+
+        with closing(<module>.open(<arguments>)) as f:
+            <block>
+
+    is equivalent to this:
+
+        f = <module>.open(<arguments>)
+        try:
+            <block>
+        finally:
+            f.close()
+
+    """
+    def __init__(self, thing):
+        self.thing = thing
+    def __enter__(self):
+        return self.thing
+    def __exit__(self, *exc_info):
+        self.thing.close()

Added: vendor/Python/current/Lib/cookielib.py
===================================================================
--- vendor/Python/current/Lib/cookielib.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/cookielib.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1776 @@
+"""HTTP cookie handling for web clients.
+
+This module has (now fairly distant) origins in Gisle Aas' Perl module
+HTTP::Cookies, from the libwww-perl library.
+
+Docstrings, comments and debug strings in this code refer to the
+attributes of the HTTP cookie system as cookie-attributes, to distinguish
+them clearly from Python attributes.
+
+Class diagram (note that BSDDBCookieJar and the MSIE* classes are not
+distributed with the Python standard library, but are available from
+http://wwwsearch.sf.net/):
+
+                        CookieJar____
+                        /     \      \
+            FileCookieJar      \      \
+             /    |   \         \      \
+ MozillaCookieJar | LWPCookieJar \      \
+                  |               |      \
+                  |   ---MSIEBase |       \
+                  |  /      |     |        \
+                  | /   MSIEDBCookieJar BSDDBCookieJar
+                  |/
+               MSIECookieJar
+
+"""
+
+__all__ = ['Cookie', 'CookieJar', 'CookiePolicy', 'DefaultCookiePolicy',
+           'FileCookieJar', 'LWPCookieJar', 'LoadError', 'MozillaCookieJar']
+
+import re, urlparse, copy, time, urllib
+try:
+    import threading as _threading
+except ImportError:
+    import dummy_threading as _threading
+import httplib  # only for the default HTTP port
+from calendar import timegm
+
+debug = False   # set to True to enable debugging via the logging module
+logger = None
+
+def _debug(*args):
+    if not debug:
+        return
+    global logger
+    if not logger:
+        import logging
+        logger = logging.getLogger("cookielib")
+    return logger.debug(*args)
+
+
+DEFAULT_HTTP_PORT = str(httplib.HTTP_PORT)
+MISSING_FILENAME_TEXT = ("a filename was not supplied (nor was the CookieJar "
+                         "instance initialised with one)")
+
+def _warn_unhandled_exception():
+    # There are a few catch-all except: statements in this module, for
+    # catching input that's bad in unexpected ways.  Warn if any
+    # exceptions are caught there.
+    import warnings, traceback, StringIO
+    f = StringIO.StringIO()
+    traceback.print_exc(None, f)
+    msg = f.getvalue()
+    warnings.warn("cookielib bug!\n%s" % msg, stacklevel=2)
+
+
+# Date/time conversion
+# -----------------------------------------------------------------------------
+
+EPOCH_YEAR = 1970
+def _timegm(tt):
+    year, month, mday, hour, min, sec = tt[:6]
+    if ((year >= EPOCH_YEAR) and (1 <= month <= 12) and (1 <= mday <= 31) and
+        (0 <= hour <= 24) and (0 <= min <= 59) and (0 <= sec <= 61)):
+        return timegm(tt)
+    else:
+        return None
+
+DAYS = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
+MONTHS = ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
+          "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
+MONTHS_LOWER = []
+for month in MONTHS: MONTHS_LOWER.append(month.lower())
+
+def time2isoz(t=None):
+    """Return a string representing time in seconds since epoch, t.
+
+    If the function is called without an argument, it will use the current
+    time.
+
+    The format of the returned string is like "YYYY-MM-DD hh:mm:ssZ",
+    representing Universal Time (UTC, aka GMT).  An example of this format is:
+
+    1994-11-24 08:49:37Z
+
+    """
+    if t is None: t = time.time()
+    year, mon, mday, hour, min, sec = time.gmtime(t)[:6]
+    return "%04d-%02d-%02d %02d:%02d:%02dZ" % (
+        year, mon, mday, hour, min, sec)
+
+def time2netscape(t=None):
+    """Return a string representing time in seconds since epoch, t.
+
+    If the function is called without an argument, it will use the current
+    time.
+
+    The format of the returned string is like this:
+
+    Wed, DD-Mon-YYYY HH:MM:SS GMT
+
+    """
+    if t is None: t = time.time()
+    year, mon, mday, hour, min, sec, wday = time.gmtime(t)[:7]
+    return "%s %02d-%s-%04d %02d:%02d:%02d GMT" % (
+        DAYS[wday], mday, MONTHS[mon-1], year, hour, min, sec)
+
+
+UTC_ZONES = {"GMT": None, "UTC": None, "UT": None, "Z": None}
+
+TIMEZONE_RE = re.compile(r"^([-+])?(\d\d?):?(\d\d)?$")
+def offset_from_tz_string(tz):
+    offset = None
+    if tz in UTC_ZONES:
+        offset = 0
+    else:
+        m = TIMEZONE_RE.search(tz)
+        if m:
+            offset = 3600 * int(m.group(2))
+            if m.group(3):
+                offset = offset + 60 * int(m.group(3))
+            if m.group(1) == '-':
+                offset = -offset
+    return offset
+
+def _str2time(day, mon, yr, hr, min, sec, tz):
+    # translate month name to number
+    # month numbers start with 1 (January)
+    try:
+        mon = MONTHS_LOWER.index(mon.lower())+1
+    except ValueError:
+        # maybe it's already a number
+        try:
+            imon = int(mon)
+        except ValueError:
+            return None
+        if 1 <= imon <= 12:
+            mon = imon
+        else:
+            return None
+
+    # make sure clock elements are defined
+    if hr is None: hr = 0
+    if min is None: min = 0
+    if sec is None: sec = 0
+
+    yr = int(yr)
+    day = int(day)
+    hr = int(hr)
+    min = int(min)
+    sec = int(sec)
+
+    if yr < 1000:
+        # find "obvious" year
+        cur_yr = time.localtime(time.time())[0]
+        m = cur_yr % 100
+        tmp = yr
+        yr = yr + cur_yr - m
+        m = m - tmp
+        if abs(m) > 50:
+            if m > 0: yr = yr + 100
+            else: yr = yr - 100
+
+    # convert UTC time tuple to seconds since epoch (not timezone-adjusted)
+    t = _timegm((yr, mon, day, hr, min, sec, tz))
+
+    if t is not None:
+        # adjust time using timezone string, to get absolute time since epoch
+        if tz is None:
+            tz = "UTC"
+        tz = tz.upper()
+        offset = offset_from_tz_string(tz)
+        if offset is None:
+            return None
+        t = t - offset
+
+    return t
+
+STRICT_DATE_RE = re.compile(
+    r"^[SMTWF][a-z][a-z], (\d\d) ([JFMASOND][a-z][a-z]) "
+    "(\d\d\d\d) (\d\d):(\d\d):(\d\d) GMT$")
+WEEKDAY_RE = re.compile(
+    r"^(?:Sun|Mon|Tue|Wed|Thu|Fri|Sat)[a-z]*,?\s*", re.I)
+LOOSE_HTTP_DATE_RE = re.compile(
+    r"""^
+    (\d\d?)            # day
+       (?:\s+|[-\/])
+    (\w+)              # month
+        (?:\s+|[-\/])
+    (\d+)              # year
+    (?:
+          (?:\s+|:)    # separator before clock
+       (\d\d?):(\d\d)  # hour:min
+       (?::(\d\d))?    # optional seconds
+    )?                 # optional clock
+       \s*
+    ([-+]?\d{2,4}|(?![APap][Mm]\b)[A-Za-z]+)? # timezone
+       \s*
+    (?:\(\w+\))?       # ASCII representation of timezone in parens.
+       \s*$""", re.X)
+def http2time(text):
+    """Returns time in seconds since epoch of time represented by a string.
+
+    Return value is an integer.
+
+    None is returned if the format of str is unrecognized, the time is outside
+    the representable range, or the timezone string is not recognized.  If the
+    string contains no timezone, UTC is assumed.
+
+    The timezone in the string may be numerical (like "-0800" or "+0100") or a
+    string timezone (like "UTC", "GMT", "BST" or "EST").  Currently, only the
+    timezone strings equivalent to UTC (zero offset) are known to the function.
+
+    The function loosely parses the following formats:
+
+    Wed, 09 Feb 1994 22:23:32 GMT       -- HTTP format
+    Tuesday, 08-Feb-94 14:15:29 GMT     -- old rfc850 HTTP format
+    Tuesday, 08-Feb-1994 14:15:29 GMT   -- broken rfc850 HTTP format
+    09 Feb 1994 22:23:32 GMT            -- HTTP format (no weekday)
+    08-Feb-94 14:15:29 GMT              -- rfc850 format (no weekday)
+    08-Feb-1994 14:15:29 GMT            -- broken rfc850 format (no weekday)
+
+    The parser ignores leading and trailing whitespace.  The time may be
+    absent.
+
+    If the year is given with only 2 digits, the function will select the
+    century that makes the year closest to the current date.
+
+    """
+    # fast exit for strictly conforming string
+    m = STRICT_DATE_RE.search(text)
+    if m:
+        g = m.groups()
+        mon = MONTHS_LOWER.index(g[1].lower()) + 1
+        tt = (int(g[2]), mon, int(g[0]),
+              int(g[3]), int(g[4]), float(g[5]))
+        return _timegm(tt)
+
+    # No, we need some messy parsing...
+
+    # clean up
+    text = text.lstrip()
+    text = WEEKDAY_RE.sub("", text, 1)  # Useless weekday
+
+    # tz is time zone specifier string
+    day, mon, yr, hr, min, sec, tz = [None]*7
+
+    # loose regexp parse
+    m = LOOSE_HTTP_DATE_RE.search(text)
+    if m is not None:
+        day, mon, yr, hr, min, sec, tz = m.groups()
+    else:
+        return None  # bad format
+
+    return _str2time(day, mon, yr, hr, min, sec, tz)
+
+ISO_DATE_RE = re.compile(
+    """^
+    (\d{4})              # year
+       [-\/]?
+    (\d\d?)              # numerical month
+       [-\/]?
+    (\d\d?)              # day
+   (?:
+         (?:\s+|[-:Tt])  # separator before clock
+      (\d\d?):?(\d\d)    # hour:min
+      (?::?(\d\d(?:\.\d*)?))?  # optional seconds (and fractional)
+   )?                    # optional clock
+      \s*
+   ([-+]?\d\d?:?(:?\d\d)?
+    |Z|z)?               # timezone  (Z is "zero meridian", i.e. GMT)
+      \s*$""", re.X)
+def iso2time(text):
+    """
+    As for http2time, but parses the ISO 8601 formats:
+
+    1994-02-03 14:15:29 -0100    -- ISO 8601 format
+    1994-02-03 14:15:29          -- zone is optional
+    1994-02-03                   -- only date
+    1994-02-03T14:15:29          -- Use T as separator
+    19940203T141529Z             -- ISO 8601 compact format
+    19940203                     -- only date
+
+    """
+    # clean up
+    text = text.lstrip()
+
+    # tz is time zone specifier string
+    day, mon, yr, hr, min, sec, tz = [None]*7
+
+    # loose regexp parse
+    m = ISO_DATE_RE.search(text)
+    if m is not None:
+        # XXX there's an extra bit of the timezone I'm ignoring here: is
+        #   this the right thing to do?
+        yr, mon, day, hr, min, sec, tz, _ = m.groups()
+    else:
+        return None  # bad format
+
+    return _str2time(day, mon, yr, hr, min, sec, tz)
+
+
+# Header parsing
+# -----------------------------------------------------------------------------
+
+def unmatched(match):
+    """Return unmatched part of re.Match object."""
+    start, end = match.span(0)
+    return match.string[:start]+match.string[end:]
+
+HEADER_TOKEN_RE =        re.compile(r"^\s*([^=\s;,]+)")
+HEADER_QUOTED_VALUE_RE = re.compile(r"^\s*=\s*\"([^\"\\]*(?:\\.[^\"\\]*)*)\"")
+HEADER_VALUE_RE =        re.compile(r"^\s*=\s*([^\s;,]*)")
+HEADER_ESCAPE_RE = re.compile(r"\\(.)")
+def split_header_words(header_values):
+    r"""Parse header values into a list of lists containing key,value pairs.
+
+    The function knows how to deal with ",", ";" and "=" as well as quoted
+    values after "=".  A list of space separated tokens are parsed as if they
+    were separated by ";".
+
+    If the header_values passed as argument contains multiple values, then they
+    are treated as if they were a single value separated by comma ",".
+
+    This means that this function is useful for parsing header fields that
+    follow this syntax (BNF as from the HTTP/1.1 specification, but we relax
+    the requirement for tokens).
+
+      headers           = #header
+      header            = (token | parameter) *( [";"] (token | parameter))
+
+      token             = 1*<any CHAR except CTLs or separators>
+      separators        = "(" | ")" | "<" | ">" | "@"
+                        | "," | ";" | ":" | "\" | <">
+                        | "/" | "[" | "]" | "?" | "="
+                        | "{" | "}" | SP | HT
+
+      quoted-string     = ( <"> *(qdtext | quoted-pair ) <"> )
+      qdtext            = <any TEXT except <">>
+      quoted-pair       = "\" CHAR
+
+      parameter         = attribute "=" value
+      attribute         = token
+      value             = token | quoted-string
+
+    Each header is represented by a list of key/value pairs.  The value for a
+    simple token (not part of a parameter) is None.  Syntactically incorrect
+    headers will not necessarily be parsed as you would want.
+
+    This is easier to describe with some examples:
+
+    >>> split_header_words(['foo="bar"; port="80,81"; discard, bar=baz'])
+    [[('foo', 'bar'), ('port', '80,81'), ('discard', None)], [('bar', 'baz')]]
+    >>> split_header_words(['text/html; charset="iso-8859-1"'])
+    [[('text/html', None), ('charset', 'iso-8859-1')]]
+    >>> split_header_words([r'Basic realm="\"foo\bar\""'])
+    [[('Basic', None), ('realm', '"foobar"')]]
+
+    """
+    assert not isinstance(header_values, basestring)
+    result = []
+    for text in header_values:
+        orig_text = text
+        pairs = []
+        while text:
+            m = HEADER_TOKEN_RE.search(text)
+            if m:
+                text = unmatched(m)
+                name = m.group(1)
+                m = HEADER_QUOTED_VALUE_RE.search(text)
+                if m:  # quoted value
+                    text = unmatched(m)
+                    value = m.group(1)
+                    value = HEADER_ESCAPE_RE.sub(r"\1", value)
+                else:
+                    m = HEADER_VALUE_RE.search(text)
+                    if m:  # unquoted value
+                        text = unmatched(m)
+                        value = m.group(1)
+                        value = value.rstrip()
+                    else:
+                        # no value, a lone token
+                        value = None
+                pairs.append((name, value))
+            elif text.lstrip().startswith(","):
+                # concatenated headers, as per RFC 2616 section 4.2
+                text = text.lstrip()[1:]
+                if pairs: result.append(pairs)
+                pairs = []
+            else:
+                # skip junk
+                non_junk, nr_junk_chars = re.subn("^[=\s;]*", "", text)
+                assert nr_junk_chars > 0, (
+                    "split_header_words bug: '%s', '%s', %s" %
+                    (orig_text, text, pairs))
+                text = non_junk
+        if pairs: result.append(pairs)
+    return result
+
+HEADER_JOIN_ESCAPE_RE = re.compile(r"([\"\\])")
+def join_header_words(lists):
+    """Do the inverse (almost) of the conversion done by split_header_words.
+
+    Takes a list of lists of (key, value) pairs and produces a single header
+    value.  Attribute values are quoted if needed.
+
+    >>> join_header_words([[("text/plain", None), ("charset", "iso-8859/1")]])
+    'text/plain; charset="iso-8859/1"'
+    >>> join_header_words([[("text/plain", None)], [("charset", "iso-8859/1")]])
+    'text/plain, charset="iso-8859/1"'
+
+    """
+    headers = []
+    for pairs in lists:
+        attr = []
+        for k, v in pairs:
+            if v is not None:
+                if not re.search(r"^\w+$", v):
+                    v = HEADER_JOIN_ESCAPE_RE.sub(r"\\\1", v)  # escape " and \
+                    v = '"%s"' % v
+                k = "%s=%s" % (k, v)
+            attr.append(k)
+        if attr: headers.append("; ".join(attr))
+    return ", ".join(headers)
+
+def parse_ns_headers(ns_headers):
+    """Ad-hoc parser for Netscape protocol cookie-attributes.
+
+    The old Netscape cookie format for Set-Cookie can for instance contain
+    an unquoted "," in the expires field, so we have to use this ad-hoc
+    parser instead of split_header_words.
+
+    XXX This may not make the best possible effort to parse all the crap
+    that Netscape Cookie headers contain.  Ronald Tschalar's HTTPClient
+    parser is probably better, so could do worse than following that if
+    this ever gives any trouble.
+
+    Currently, this is also used for parsing RFC 2109 cookies.
+
+    """
+    known_attrs = ("expires", "domain", "path", "secure",
+                   # RFC 2109 attrs (may turn up in Netscape cookies, too)
+                   "port", "max-age")
+
+    result = []
+    for ns_header in ns_headers:
+        pairs = []
+        version_set = False
+        for ii, param in enumerate(re.split(r";\s*", ns_header)):
+            param = param.rstrip()
+            if param == "": continue
+            if "=" not in param:
+                k, v = param, None
+            else:
+                k, v = re.split(r"\s*=\s*", param, 1)
+                k = k.lstrip()
+            if ii != 0:
+                lc = k.lower()
+                if lc in known_attrs:
+                    k = lc
+                if k == "version":
+                    # This is an RFC 2109 cookie.
+                    version_set = True
+                if k == "expires":
+                    # convert expires date to seconds since epoch
+                    if v.startswith('"'): v = v[1:]
+                    if v.endswith('"'): v = v[:-1]
+                    v = http2time(v)  # None if invalid
+            pairs.append((k, v))
+
+        if pairs:
+            if not version_set:
+                pairs.append(("version", "0"))
+            result.append(pairs)
+
+    return result
+
+
+IPV4_RE = re.compile(r"\.\d+$")
+def is_HDN(text):
+    """Return True if text is a host domain name."""
+    # XXX
+    # This may well be wrong.  Which RFC is HDN defined in, if any (for
+    #  the purposes of RFC 2965)?
+    # For the current implementation, what about IPv6?  Remember to look
+    #  at other uses of IPV4_RE also, if change this.
+    if IPV4_RE.search(text):
+        return False
+    if text == "":
+        return False
+    if text[0] == "." or text[-1] == ".":
+        return False
+    return True
+
+def domain_match(A, B):
+    """Return True if domain A domain-matches domain B, according to RFC 2965.
+
+    A and B may be host domain names or IP addresses.
+
+    RFC 2965, section 1:
+
+    Host names can be specified either as an IP address or a HDN string.
+    Sometimes we compare one host name with another.  (Such comparisons SHALL
+    be case-insensitive.)  Host A's name domain-matches host B's if
+
+         *  their host name strings string-compare equal; or
+
+         * A is a HDN string and has the form NB, where N is a non-empty
+            name string, B has the form .B', and B' is a HDN string.  (So,
+            x.y.com domain-matches .Y.com but not Y.com.)
+
+    Note that domain-match is not a commutative operation: a.b.c.com
+    domain-matches .c.com, but not the reverse.
+
+    """
+    # Note that, if A or B are IP addresses, the only relevant part of the
+    # definition of the domain-match algorithm is the direct string-compare.
+    A = A.lower()
+    B = B.lower()
+    if A == B:
+        return True
+    if not is_HDN(A):
+        return False
+    i = A.rfind(B)
+    if i == -1 or i == 0:
+        # A does not have form NB, or N is the empty string
+        return False
+    if not B.startswith("."):
+        return False
+    if not is_HDN(B[1:]):
+        return False
+    return True
+
+def liberal_is_HDN(text):
+    """Return True if text is a sort-of-like a host domain name.
+
+    For accepting/blocking domains.
+
+    """
+    if IPV4_RE.search(text):
+        return False
+    return True
+
+def user_domain_match(A, B):
+    """For blocking/accepting domains.
+
+    A and B may be host domain names or IP addresses.
+
+    """
+    A = A.lower()
+    B = B.lower()
+    if not (liberal_is_HDN(A) and liberal_is_HDN(B)):
+        if A == B:
+            # equal IP addresses
+            return True
+        return False
+    initial_dot = B.startswith(".")
+    if initial_dot and A.endswith(B):
+        return True
+    if not initial_dot and A == B:
+        return True
+    return False
+
+cut_port_re = re.compile(r":\d+$")
+def request_host(request):
+    """Return request-host, as defined by RFC 2965.
+
+    Variation from RFC: returned value is lowercased, for convenient
+    comparison.
+
+    """
+    url = request.get_full_url()
+    host = urlparse.urlparse(url)[1]
+    if host == "":
+        host = request.get_header("Host", "")
+
+    # remove port, if present
+    host = cut_port_re.sub("", host, 1)
+    return host.lower()
+
+def eff_request_host(request):
+    """Return a tuple (request-host, effective request-host name).
+
+    As defined by RFC 2965, except both are lowercased.
+
+    """
+    erhn = req_host = request_host(request)
+    if req_host.find(".") == -1 and not IPV4_RE.search(req_host):
+        erhn = req_host + ".local"
+    return req_host, erhn
+
+def request_path(request):
+    """request-URI, as defined by RFC 2965."""
+    url = request.get_full_url()
+    #scheme, netloc, path, parameters, query, frag = urlparse.urlparse(url)
+    #req_path = escape_path("".join(urlparse.urlparse(url)[2:]))
+    path, parameters, query, frag = urlparse.urlparse(url)[2:]
+    if parameters:
+        path = "%s;%s" % (path, parameters)
+    path = escape_path(path)
+    req_path = urlparse.urlunparse(("", "", path, "", query, frag))
+    if not req_path.startswith("/"):
+        # fix bad RFC 2396 absoluteURI
+        req_path = "/"+req_path
+    return req_path
+
+def request_port(request):
+    host = request.get_host()
+    i = host.find(':')
+    if i >= 0:
+        port = host[i+1:]
+        try:
+            int(port)
+        except ValueError:
+            _debug("nonnumeric port: '%s'", port)
+            return None
+    else:
+        port = DEFAULT_HTTP_PORT
+    return port
+
+# Characters in addition to A-Z, a-z, 0-9, '_', '.', and '-' that don't
+# need to be escaped to form a valid HTTP URL (RFCs 2396 and 1738).
+HTTP_PATH_SAFE = "%/;:@&=+$,!~*'()"
+ESCAPED_CHAR_RE = re.compile(r"%([0-9a-fA-F][0-9a-fA-F])")
+def uppercase_escaped_char(match):
+    return "%%%s" % match.group(1).upper()
+def escape_path(path):
+    """Escape any invalid characters in HTTP URL, and uppercase all escapes."""
+    # There's no knowing what character encoding was used to create URLs
+    # containing %-escapes, but since we have to pick one to escape invalid
+    # path characters, we pick UTF-8, as recommended in the HTML 4.0
+    # specification:
+    # http://www.w3.org/TR/REC-html40/appendix/notes.html#h-B.2.1
+    # And here, kind of: draft-fielding-uri-rfc2396bis-03
+    # (And in draft IRI specification: draft-duerst-iri-05)
+    # (And here, for new URI schemes: RFC 2718)
+    if isinstance(path, unicode):
+        path = path.encode("utf-8")
+    path = urllib.quote(path, HTTP_PATH_SAFE)
+    path = ESCAPED_CHAR_RE.sub(uppercase_escaped_char, path)
+    return path
+
+def reach(h):
+    """Return reach of host h, as defined by RFC 2965, section 1.
+
+    The reach R of a host name H is defined as follows:
+
+       *  If
+
+          -  H is the host domain name of a host; and,
+
+          -  H has the form A.B; and
+
+          -  A has no embedded (that is, interior) dots; and
+
+          -  B has at least one embedded dot, or B is the string "local".
+             then the reach of H is .B.
+
+       *  Otherwise, the reach of H is H.
+
+    >>> reach("www.acme.com")
+    '.acme.com'
+    >>> reach("acme.com")
+    'acme.com'
+    >>> reach("acme.local")
+    '.local'
+
+    """
+    i = h.find(".")
+    if i >= 0:
+        #a = h[:i]  # this line is only here to show what a is
+        b = h[i+1:]
+        i = b.find(".")
+        if is_HDN(h) and (i >= 0 or b == "local"):
+            return "."+b
+    return h
+
+def is_third_party(request):
+    """
+
+    RFC 2965, section 3.3.6:
+
+        An unverifiable transaction is to a third-party host if its request-
+        host U does not domain-match the reach R of the request-host O in the
+        origin transaction.
+
+    """
+    req_host = request_host(request)
+    if not domain_match(req_host, reach(request.get_origin_req_host())):
+        return True
+    else:
+        return False
+
+
+class Cookie:
+    """HTTP Cookie.
+
+    This class represents both Netscape and RFC 2965 cookies.
+
+    This is deliberately a very simple class.  It just holds attributes.  It's
+    possible to construct Cookie instances that don't comply with the cookie
+    standards.  CookieJar.make_cookies is the factory function for Cookie
+    objects -- it deals with cookie parsing, supplying defaults, and
+    normalising to the representation used in this class.  CookiePolicy is
+    responsible for checking them to see whether they should be accepted from
+    and returned to the server.
+
+    Note that the port may be present in the headers, but unspecified ("Port"
+    rather than"Port=80", for example); if this is the case, port is None.
+
+    """
+
+    def __init__(self, version, name, value,
+                 port, port_specified,
+                 domain, domain_specified, domain_initial_dot,
+                 path, path_specified,
+                 secure,
+                 expires,
+                 discard,
+                 comment,
+                 comment_url,
+                 rest,
+                 rfc2109=False,
+                 ):
+
+        if version is not None: version = int(version)
+        if expires is not None: expires = int(expires)
+        if port is None and port_specified is True:
+            raise ValueError("if port is None, port_specified must be false")
+
+        self.version = version
+        self.name = name
+        self.value = value
+        self.port = port
+        self.port_specified = port_specified
+        # normalise case, as per RFC 2965 section 3.3.3
+        self.domain = domain.lower()
+        self.domain_specified = domain_specified
+        # Sigh.  We need to know whether the domain given in the
+        # cookie-attribute had an initial dot, in order to follow RFC 2965
+        # (as clarified in draft errata).  Needed for the returned $Domain
+        # value.
+        self.domain_initial_dot = domain_initial_dot
+        self.path = path
+        self.path_specified = path_specified
+        self.secure = secure
+        self.expires = expires
+        self.discard = discard
+        self.comment = comment
+        self.comment_url = comment_url
+        self.rfc2109 = rfc2109
+
+        self._rest = copy.copy(rest)
+
+    def has_nonstandard_attr(self, name):
+        return name in self._rest
+    def get_nonstandard_attr(self, name, default=None):
+        return self._rest.get(name, default)
+    def set_nonstandard_attr(self, name, value):
+        self._rest[name] = value
+
+    def is_expired(self, now=None):
+        if now is None: now = time.time()
+        if (self.expires is not None) and (self.expires <= now):
+            return True
+        return False
+
+    def __str__(self):
+        if self.port is None: p = ""
+        else: p = ":"+self.port
+        limit = self.domain + p + self.path
+        if self.value is not None:
+            namevalue = "%s=%s" % (self.name, self.value)
+        else:
+            namevalue = self.name
+        return "<Cookie %s for %s>" % (namevalue, limit)
+
+    def __repr__(self):
+        args = []
+        for name in ("version", "name", "value",
+                     "port", "port_specified",
+                     "domain", "domain_specified", "domain_initial_dot",
+                     "path", "path_specified",
+                     "secure", "expires", "discard", "comment", "comment_url",
+                     ):
+            attr = getattr(self, name)
+            args.append("%s=%s" % (name, repr(attr)))
+        args.append("rest=%s" % repr(self._rest))
+        args.append("rfc2109=%s" % repr(self.rfc2109))
+        return "Cookie(%s)" % ", ".join(args)
+
+
+class CookiePolicy:
+    """Defines which cookies get accepted from and returned to server.
+
+    May also modify cookies, though this is probably a bad idea.
+
+    The subclass DefaultCookiePolicy defines the standard rules for Netscape
+    and RFC 2965 cookies -- override that if you want a customised policy.
+
+    """
+    def set_ok(self, cookie, request):
+        """Return true if (and only if) cookie should be accepted from server.
+
+        Currently, pre-expired cookies never get this far -- the CookieJar
+        class deletes such cookies itself.
+
+        """
+        raise NotImplementedError()
+
+    def return_ok(self, cookie, request):
+        """Return true if (and only if) cookie should be returned to server."""
+        raise NotImplementedError()
+
+    def domain_return_ok(self, domain, request):
+        """Return false if cookies should not be returned, given cookie domain.
+        """
+        return True
+
+    def path_return_ok(self, path, request):
+        """Return false if cookies should not be returned, given cookie path.
+        """
+        return True
+
+
+class DefaultCookiePolicy(CookiePolicy):
+    """Implements the standard rules for accepting and returning cookies."""
+
+    DomainStrictNoDots = 1
+    DomainStrictNonDomain = 2
+    DomainRFC2965Match = 4
+
+    DomainLiberal = 0
+    DomainStrict = DomainStrictNoDots|DomainStrictNonDomain
+
+    def __init__(self,
+                 blocked_domains=None, allowed_domains=None,
+                 netscape=True, rfc2965=False,
+                 rfc2109_as_netscape=None,
+                 hide_cookie2=False,
+                 strict_domain=False,
+                 strict_rfc2965_unverifiable=True,
+                 strict_ns_unverifiable=False,
+                 strict_ns_domain=DomainLiberal,
+                 strict_ns_set_initial_dollar=False,
+                 strict_ns_set_path=False,
+                 ):
+        """Constructor arguments should be passed as keyword arguments only."""
+        self.netscape = netscape
+        self.rfc2965 = rfc2965
+        self.rfc2109_as_netscape = rfc2109_as_netscape
+        self.hide_cookie2 = hide_cookie2
+        self.strict_domain = strict_domain
+        self.strict_rfc2965_unverifiable = strict_rfc2965_unverifiable
+        self.strict_ns_unverifiable = strict_ns_unverifiable
+        self.strict_ns_domain = strict_ns_domain
+        self.strict_ns_set_initial_dollar = strict_ns_set_initial_dollar
+        self.strict_ns_set_path = strict_ns_set_path
+
+        if blocked_domains is not None:
+            self._blocked_domains = tuple(blocked_domains)
+        else:
+            self._blocked_domains = ()
+
+        if allowed_domains is not None:
+            allowed_domains = tuple(allowed_domains)
+        self._allowed_domains = allowed_domains
+
+    def blocked_domains(self):
+        """Return the sequence of blocked domains (as a tuple)."""
+        return self._blocked_domains
+    def set_blocked_domains(self, blocked_domains):
+        """Set the sequence of blocked domains."""
+        self._blocked_domains = tuple(blocked_domains)
+
+    def is_blocked(self, domain):
+        for blocked_domain in self._blocked_domains:
+            if user_domain_match(domain, blocked_domain):
+                return True
+        return False
+
+    def allowed_domains(self):
+        """Return None, or the sequence of allowed domains (as a tuple)."""
+        return self._allowed_domains
+    def set_allowed_domains(self, allowed_domains):
+        """Set the sequence of allowed domains, or None."""
+        if allowed_domains is not None:
+            allowed_domains = tuple(allowed_domains)
+        self._allowed_domains = allowed_domains
+
+    def is_not_allowed(self, domain):
+        if self._allowed_domains is None:
+            return False
+        for allowed_domain in self._allowed_domains:
+            if user_domain_match(domain, allowed_domain):
+                return False
+        return True
+
+    def set_ok(self, cookie, request):
+        """
+        If you override .set_ok(), be sure to call this method.  If it returns
+        false, so should your subclass (assuming your subclass wants to be more
+        strict about which cookies to accept).
+
+        """
+        _debug(" - checking cookie %s=%s", cookie.name, cookie.value)
+
+        assert cookie.name is not None
+
+        for n in "version", "verifiability", "name", "path", "domain", "port":
+            fn_name = "set_ok_"+n
+            fn = getattr(self, fn_name)
+            if not fn(cookie, request):
+                return False
+
+        return True
+
+    def set_ok_version(self, cookie, request):
+        if cookie.version is None:
+            # Version is always set to 0 by parse_ns_headers if it's a Netscape
+            # cookie, so this must be an invalid RFC 2965 cookie.
+            _debug("   Set-Cookie2 without version attribute (%s=%s)",
+                   cookie.name, cookie.value)
+            return False
+        if cookie.version > 0 and not self.rfc2965:
+            _debug("   RFC 2965 cookies are switched off")
+            return False
+        elif cookie.version == 0 and not self.netscape:
+            _debug("   Netscape cookies are switched off")
+            return False
+        return True
+
+    def set_ok_verifiability(self, cookie, request):
+        if request.is_unverifiable() and is_third_party(request):
+            if cookie.version > 0 and self.strict_rfc2965_unverifiable:
+                _debug("   third-party RFC 2965 cookie during "
+                             "unverifiable transaction")
+                return False
+            elif cookie.version == 0 and self.strict_ns_unverifiable:
+                _debug("   third-party Netscape cookie during "
+                             "unverifiable transaction")
+                return False
+        return True
+
+    def set_ok_name(self, cookie, request):
+        # Try and stop servers setting V0 cookies designed to hack other
+        # servers that know both V0 and V1 protocols.
+        if (cookie.version == 0 and self.strict_ns_set_initial_dollar and
+            cookie.name.startswith("$")):
+            _debug("   illegal name (starts with '$'): '%s'", cookie.name)
+            return False
+        return True
+
+    def set_ok_path(self, cookie, request):
+        if cookie.path_specified:
+            req_path = request_path(request)
+            if ((cookie.version > 0 or
+                 (cookie.version == 0 and self.strict_ns_set_path)) and
+                not req_path.startswith(cookie.path)):
+                _debug("   path attribute %s is not a prefix of request "
+                       "path %s", cookie.path, req_path)
+                return False
+        return True
+
+    def set_ok_domain(self, cookie, request):
+        if self.is_blocked(cookie.domain):
+            _debug("   domain %s is in user block-list", cookie.domain)
+            return False
+        if self.is_not_allowed(cookie.domain):
+            _debug("   domain %s is not in user allow-list", cookie.domain)
+            return False
+        if cookie.domain_specified:
+            req_host, erhn = eff_request_host(request)
+            domain = cookie.domain
+            if self.strict_domain and (domain.count(".") >= 2):
+                # XXX This should probably be compared with the Konqueror
+                # (kcookiejar.cpp) and Mozilla implementations, but it's a
+                # losing battle.
+                i = domain.rfind(".")
+                j = domain.rfind(".", 0, i)
+                if j == 0:  # domain like .foo.bar
+                    tld = domain[i+1:]
+                    sld = domain[j+1:i]
+                    if sld.lower() in ("co", "ac", "com", "edu", "org", "net",
+                       "gov", "mil", "int", "aero", "biz", "cat", "coop",
+                       "info", "jobs", "mobi", "museum", "name", "pro",
+                       "travel", "eu") and len(tld) == 2:
+                        # domain like .co.uk
+                        _debug("   country-code second level domain %s", domain)
+                        return False
+            if domain.startswith("."):
+                undotted_domain = domain[1:]
+            else:
+                undotted_domain = domain
+            embedded_dots = (undotted_domain.find(".") >= 0)
+            if not embedded_dots and domain != ".local":
+                _debug("   non-local domain %s contains no embedded dot",
+                       domain)
+                return False
+            if cookie.version == 0:
+                if (not erhn.endswith(domain) and
+                    (not erhn.startswith(".") and
+                     not ("."+erhn).endswith(domain))):
+                    _debug("   effective request-host %s (even with added "
+                           "initial dot) does not end end with %s",
+                           erhn, domain)
+                    return False
+            if (cookie.version > 0 or
+                (self.strict_ns_domain & self.DomainRFC2965Match)):
+                if not domain_match(erhn, domain):
+                    _debug("   effective request-host %s does not domain-match "
+                           "%s", erhn, domain)
+                    return False
+            if (cookie.version > 0 or
+                (self.strict_ns_domain & self.DomainStrictNoDots)):
+                host_prefix = req_host[:-len(domain)]
+                if (host_prefix.find(".") >= 0 and
+                    not IPV4_RE.search(req_host)):
+                    _debug("   host prefix %s for domain %s contains a dot",
+                           host_prefix, domain)
+                    return False
+        return True
+
+    def set_ok_port(self, cookie, request):
+        if cookie.port_specified:
+            req_port = request_port(request)
+            if req_port is None:
+                req_port = "80"
+            else:
+                req_port = str(req_port)
+            for p in cookie.port.split(","):
+                try:
+                    int(p)
+                except ValueError:
+                    _debug("   bad port %s (not numeric)", p)
+                    return False
+                if p == req_port:
+                    break
+            else:
+                _debug("   request port (%s) not found in %s",
+                       req_port, cookie.port)
+                return False
+        return True
+
+    def return_ok(self, cookie, request):
+        """
+        If you override .return_ok(), be sure to call this method.  If it
+        returns false, so should your subclass (assuming your subclass wants to
+        be more strict about which cookies to return).
+
+        """
+        # Path has already been checked by .path_return_ok(), and domain
+        # blocking done by .domain_return_ok().
+        _debug(" - checking cookie %s=%s", cookie.name, cookie.value)
+
+        for n in "version", "verifiability", "secure", "expires", "port", "domain":
+            fn_name = "return_ok_"+n
+            fn = getattr(self, fn_name)
+            if not fn(cookie, request):
+                return False
+        return True
+
+    def return_ok_version(self, cookie, request):
+        if cookie.version > 0 and not self.rfc2965:
+            _debug("   RFC 2965 cookies are switched off")
+            return False
+        elif cookie.version == 0 and not self.netscape:
+            _debug("   Netscape cookies are switched off")
+            return False
+        return True
+
+    def return_ok_verifiability(self, cookie, request):
+        if request.is_unverifiable() and is_third_party(request):
+            if cookie.version > 0 and self.strict_rfc2965_unverifiable:
+                _debug("   third-party RFC 2965 cookie during unverifiable "
+                       "transaction")
+                return False
+            elif cookie.version == 0 and self.strict_ns_unverifiable:
+                _debug("   third-party Netscape cookie during unverifiable "
+                       "transaction")
+                return False
+        return True
+
+    def return_ok_secure(self, cookie, request):
+        if cookie.secure and request.get_type() != "https":
+            _debug("   secure cookie with non-secure request")
+            return False
+        return True
+
+    def return_ok_expires(self, cookie, request):
+        if cookie.is_expired(self._now):
+            _debug("   cookie expired")
+            return False
+        return True
+
+    def return_ok_port(self, cookie, request):
+        if cookie.port:
+            req_port = request_port(request)
+            if req_port is None:
+                req_port = "80"
+            for p in cookie.port.split(","):
+                if p == req_port:
+                    break
+            else:
+                _debug("   request port %s does not match cookie port %s",
+                       req_port, cookie.port)
+                return False
+        return True
+
+    def return_ok_domain(self, cookie, request):
+        req_host, erhn = eff_request_host(request)
+        domain = cookie.domain
+
+        # strict check of non-domain cookies: Mozilla does this, MSIE5 doesn't
+        if (cookie.version == 0 and
+            (self.strict_ns_domain & self.DomainStrictNonDomain) and
+            not cookie.domain_specified and domain != erhn):
+            _debug("   cookie with unspecified domain does not string-compare "
+                   "equal to request domain")
+            return False
+
+        if cookie.version > 0 and not domain_match(erhn, domain):
+            _debug("   effective request-host name %s does not domain-match "
+                   "RFC 2965 cookie domain %s", erhn, domain)
+            return False
+        if cookie.version == 0 and not ("."+erhn).endswith(domain):
+            _debug("   request-host %s does not match Netscape cookie domain "
+                   "%s", req_host, domain)
+            return False
+        return True
+
+    def domain_return_ok(self, domain, request):
+        # Liberal check of.  This is here as an optimization to avoid
+        # having to load lots of MSIE cookie files unless necessary.
+        req_host, erhn = eff_request_host(request)
+        if not req_host.startswith("."):
+            req_host = "."+req_host
+        if not erhn.startswith("."):
+            erhn = "."+erhn
+        if not (req_host.endswith(domain) or erhn.endswith(domain)):
+            #_debug("   request domain %s does not match cookie domain %s",
+            #       req_host, domain)
+            return False
+
+        if self.is_blocked(domain):
+            _debug("   domain %s is in user block-list", domain)
+            return False
+        if self.is_not_allowed(domain):
+            _debug("   domain %s is not in user allow-list", domain)
+            return False
+
+        return True
+
+    def path_return_ok(self, path, request):
+        _debug("- checking cookie path=%s", path)
+        req_path = request_path(request)
+        if not req_path.startswith(path):
+            _debug("  %s does not path-match %s", req_path, path)
+            return False
+        return True
+
+
+def vals_sorted_by_key(adict):
+    keys = adict.keys()
+    keys.sort()
+    return map(adict.get, keys)
+
+def deepvalues(mapping):
+    """Iterates over nested mapping, depth-first, in sorted order by key."""
+    values = vals_sorted_by_key(mapping)
+    for obj in values:
+        mapping = False
+        try:
+            obj.items
+        except AttributeError:
+            pass
+        else:
+            mapping = True
+            for subobj in deepvalues(obj):
+                yield subobj
+        if not mapping:
+            yield obj
+
+
+# Used as second parameter to dict.get() method, to distinguish absent
+# dict key from one with a None value.
+class Absent: pass
+
+class CookieJar:
+    """Collection of HTTP cookies.
+
+    You may not need to know about this class: try
+    urllib2.build_opener(HTTPCookieProcessor).open(url).
+
+    """
+
+    non_word_re = re.compile(r"\W")
+    quote_re = re.compile(r"([\"\\])")
+    strict_domain_re = re.compile(r"\.?[^.]*")
+    domain_re = re.compile(r"[^.]*")
+    dots_re = re.compile(r"^\.+")
+
+    magic_re = r"^\#LWP-Cookies-(\d+\.\d+)"
+
+    def __init__(self, policy=None):
+        if policy is None:
+            policy = DefaultCookiePolicy()
+        self._policy = policy
+
+        self._cookies_lock = _threading.RLock()
+        self._cookies = {}
+
+    def set_policy(self, policy):
+        self._policy = policy
+
+    def _cookies_for_domain(self, domain, request):
+        cookies = []
+        if not self._policy.domain_return_ok(domain, request):
+            return []
+        _debug("Checking %s for cookies to return", domain)
+        cookies_by_path = self._cookies[domain]
+        for path in cookies_by_path.keys():
+            if not self._policy.path_return_ok(path, request):
+                continue
+            cookies_by_name = cookies_by_path[path]
+            for cookie in cookies_by_name.values():
+                if not self._policy.return_ok(cookie, request):
+                    _debug("   not returning cookie")
+                    continue
+                _debug("   it's a match")
+                cookies.append(cookie)
+        return cookies
+
+    def _cookies_for_request(self, request):
+        """Return a list of cookies to be returned to server."""
+        cookies = []
+        for domain in self._cookies.keys():
+            cookies.extend(self._cookies_for_domain(domain, request))
+        return cookies
+
+    def _cookie_attrs(self, cookies):
+        """Return a list of cookie-attributes to be returned to server.
+
+        like ['foo="bar"; $Path="/"', ...]
+
+        The $Version attribute is also added when appropriate (currently only
+        once per request).
+
+        """
+        # add cookies in order of most specific (ie. longest) path first
+        def decreasing_size(a, b): return cmp(len(b.path), len(a.path))
+        cookies.sort(decreasing_size)
+
+        version_set = False
+
+        attrs = []
+        for cookie in cookies:
+            # set version of Cookie header
+            # XXX
+            # What should it be if multiple matching Set-Cookie headers have
+            #  different versions themselves?
+            # Answer: there is no answer; was supposed to be settled by
+            #  RFC 2965 errata, but that may never appear...
+            version = cookie.version
+            if not version_set:
+                version_set = True
+                if version > 0:
+                    attrs.append("$Version=%s" % version)
+
+            # quote cookie value if necessary
+            # (not for Netscape protocol, which already has any quotes
+            #  intact, due to the poorly-specified Netscape Cookie: syntax)
+            if ((cookie.value is not None) and
+                self.non_word_re.search(cookie.value) and version > 0):
+                value = self.quote_re.sub(r"\\\1", cookie.value)
+            else:
+                value = cookie.value
+
+            # add cookie-attributes to be returned in Cookie header
+            if cookie.value is None:
+                attrs.append(cookie.name)
+            else:
+                attrs.append("%s=%s" % (cookie.name, value))
+            if version > 0:
+                if cookie.path_specified:
+                    attrs.append('$Path="%s"' % cookie.path)
+                if cookie.domain.startswith("."):
+                    domain = cookie.domain
+                    if (not cookie.domain_initial_dot and
+                        domain.startswith(".")):
+                        domain = domain[1:]
+                    attrs.append('$Domain="%s"' % domain)
+                if cookie.port is not None:
+                    p = "$Port"
+                    if cookie.port_specified:
+                        p = p + ('="%s"' % cookie.port)
+                    attrs.append(p)
+
+        return attrs
+
+    def add_cookie_header(self, request):
+        """Add correct Cookie: header to request (urllib2.Request object).
+
+        The Cookie2 header is also added unless policy.hide_cookie2 is true.
+
+        """
+        _debug("add_cookie_header")
+        self._cookies_lock.acquire()
+
+        self._policy._now = self._now = int(time.time())
+
+        cookies = self._cookies_for_request(request)
+
+        attrs = self._cookie_attrs(cookies)
+        if attrs:
+            if not request.has_header("Cookie"):
+                request.add_unredirected_header(
+                    "Cookie", "; ".join(attrs))
+
+        # if necessary, advertise that we know RFC 2965
+        if (self._policy.rfc2965 and not self._policy.hide_cookie2 and
+            not request.has_header("Cookie2")):
+            for cookie in cookies:
+                if cookie.version != 1:
+                    request.add_unredirected_header("Cookie2", '$Version="1"')
+                    break
+
+        self._cookies_lock.release()
+
+        self.clear_expired_cookies()
+
+    def _normalized_cookie_tuples(self, attrs_set):
+        """Return list of tuples containing normalised cookie information.
+
+        attrs_set is the list of lists of key,value pairs extracted from
+        the Set-Cookie or Set-Cookie2 headers.
+
+        Tuples are name, value, standard, rest, where name and value are the
+        cookie name and value, standard is a dictionary containing the standard
+        cookie-attributes (discard, secure, version, expires or max-age,
+        domain, path and port) and rest is a dictionary containing the rest of
+        the cookie-attributes.
+
+        """
+        cookie_tuples = []
+
+        boolean_attrs = "discard", "secure"
+        value_attrs = ("version",
+                       "expires", "max-age",
+                       "domain", "path", "port",
+                       "comment", "commenturl")
+
+        for cookie_attrs in attrs_set:
+            name, value = cookie_attrs[0]
+
+            # Build dictionary of standard cookie-attributes (standard) and
+            # dictionary of other cookie-attributes (rest).
+
+            # Note: expiry time is normalised to seconds since epoch.  V0
+            # cookies should have the Expires cookie-attribute, and V1 cookies
+            # should have Max-Age, but since V1 includes RFC 2109 cookies (and
+            # since V0 cookies may be a mish-mash of Netscape and RFC 2109), we
+            # accept either (but prefer Max-Age).
+            max_age_set = False
+
+            bad_cookie = False
+
+            standard = {}
+            rest = {}
+            for k, v in cookie_attrs[1:]:
+                lc = k.lower()
+                # don't lose case distinction for unknown fields
+                if lc in value_attrs or lc in boolean_attrs:
+                    k = lc
+                if k in boolean_attrs and v is None:
+                    # boolean cookie-attribute is present, but has no value
+                    # (like "discard", rather than "port=80")
+                    v = True
+                if k in standard:
+                    # only first value is significant
+                    continue
+                if k == "domain":
+                    if v is None:
+                        _debug("   missing value for domain attribute")
+                        bad_cookie = True
+                        break
+                    # RFC 2965 section 3.3.3
+                    v = v.lower()
+                if k == "expires":
+                    if max_age_set:
+                        # Prefer max-age to expires (like Mozilla)
+                        continue
+                    if v is None:
+                        _debug("   missing or invalid value for expires "
+                              "attribute: treating as session cookie")
+                        continue
+                if k == "max-age":
+                    max_age_set = True
+                    try:
+                        v = int(v)
+                    except ValueError:
+                        _debug("   missing or invalid (non-numeric) value for "
+                              "max-age attribute")
+                        bad_cookie = True
+                        break
+                    # convert RFC 2965 Max-Age to seconds since epoch
+                    # XXX Strictly you're supposed to follow RFC 2616
+                    #   age-calculation rules.  Remember that zero Max-Age is a
+                    #   is a request to discard (old and new) cookie, though.
+                    k = "expires"
+                    v = self._now + v
+                if (k in value_attrs) or (k in boolean_attrs):
+                    if (v is None and
+                        k not in ("port", "comment", "commenturl")):
+                        _debug("   missing value for %s attribute" % k)
+                        bad_cookie = True
+                        break
+                    standard[k] = v
+                else:
+                    rest[k] = v
+
+            if bad_cookie:
+                continue
+
+            cookie_tuples.append((name, value, standard, rest))
+
+        return cookie_tuples
+
+    def _cookie_from_cookie_tuple(self, tup, request):
+        # standard is dict of standard cookie-attributes, rest is dict of the
+        # rest of them
+        name, value, standard, rest = tup
+
+        domain = standard.get("domain", Absent)
+        path = standard.get("path", Absent)
+        port = standard.get("port", Absent)
+        expires = standard.get("expires", Absent)
+
+        # set the easy defaults
+        version = standard.get("version", None)
+        if version is not None: version = int(version)
+        secure = standard.get("secure", False)
+        # (discard is also set if expires is Absent)
+        discard = standard.get("discard", False)
+        comment = standard.get("comment", None)
+        comment_url = standard.get("commenturl", None)
+
+        # set default path
+        if path is not Absent and path != "":
+            path_specified = True
+            path = escape_path(path)
+        else:
+            path_specified = False
+            path = request_path(request)
+            i = path.rfind("/")
+            if i != -1:
+                if version == 0:
+                    # Netscape spec parts company from reality here
+                    path = path[:i]
+                else:
+                    path = path[:i+1]
+            if len(path) == 0: path = "/"
+
+        # set default domain
+        domain_specified = domain is not Absent
+        # but first we have to remember whether it starts with a dot
+        domain_initial_dot = False
+        if domain_specified:
+            domain_initial_dot = bool(domain.startswith("."))
+        if domain is Absent:
+            req_host, erhn = eff_request_host(request)
+            domain = erhn
+        elif not domain.startswith("."):
+            domain = "."+domain
+
+        # set default port
+        port_specified = False
+        if port is not Absent:
+            if port is None:
+                # Port attr present, but has no value: default to request port.
+                # Cookie should then only be sent back on that port.
+                port = request_port(request)
+            else:
+                port_specified = True
+                port = re.sub(r"\s+", "", port)
+        else:
+            # No port attr present.  Cookie can be sent back on any port.
+            port = None
+
+        # set default expires and discard
+        if expires is Absent:
+            expires = None
+            discard = True
+        elif expires <= self._now:
+            # Expiry date in past is request to delete cookie.  This can't be
+            # in DefaultCookiePolicy, because can't delete cookies there.
+            try:
+                self.clear(domain, path, name)
+            except KeyError:
+                pass
+            _debug("Expiring cookie, domain='%s', path='%s', name='%s'",
+                   domain, path, name)
+            return None
+
+        return Cookie(version,
+                      name, value,
+                      port, port_specified,
+                      domain, domain_specified, domain_initial_dot,
+                      path, path_specified,
+                      secure,
+                      expires,
+                      discard,
+                      comment,
+                      comment_url,
+                      rest)
+
+    def _cookies_from_attrs_set(self, attrs_set, request):
+        cookie_tuples = self._normalized_cookie_tuples(attrs_set)
+
+        cookies = []
+        for tup in cookie_tuples:
+            cookie = self._cookie_from_cookie_tuple(tup, request)
+            if cookie: cookies.append(cookie)
+        return cookies
+
+    def _process_rfc2109_cookies(self, cookies):
+        rfc2109_as_ns = getattr(self._policy, 'rfc2109_as_netscape', None)
+        if rfc2109_as_ns is None:
+            rfc2109_as_ns = not self._policy.rfc2965
+        for cookie in cookies:
+            if cookie.version == 1:
+                cookie.rfc2109 = True
+                if rfc2109_as_ns:
+                    # treat 2109 cookies as Netscape cookies rather than
+                    # as RFC2965 cookies
+                    cookie.version = 0
+
+    def make_cookies(self, response, request):
+        """Return sequence of Cookie objects extracted from response object."""
+        # get cookie-attributes for RFC 2965 and Netscape protocols
+        headers = response.info()
+        rfc2965_hdrs = headers.getheaders("Set-Cookie2")
+        ns_hdrs = headers.getheaders("Set-Cookie")
+
+        rfc2965 = self._policy.rfc2965
+        netscape = self._policy.netscape
+
+        if ((not rfc2965_hdrs and not ns_hdrs) or
+            (not ns_hdrs and not rfc2965) or
+            (not rfc2965_hdrs and not netscape) or
+            (not netscape and not rfc2965)):
+            return []  # no relevant cookie headers: quick exit
+
+        try:
+            cookies = self._cookies_from_attrs_set(
+                split_header_words(rfc2965_hdrs), request)
+        except Exception:
+            _warn_unhandled_exception()
+            cookies = []
+
+        if ns_hdrs and netscape:
+            try:
+                # RFC 2109 and Netscape cookies
+                ns_cookies = self._cookies_from_attrs_set(
+                    parse_ns_headers(ns_hdrs), request)
+            except Exception:
+                _warn_unhandled_exception()
+                ns_cookies = []
+            self._process_rfc2109_cookies(ns_cookies)
+
+            # Look for Netscape cookies (from Set-Cookie headers) that match
+            # corresponding RFC 2965 cookies (from Set-Cookie2 headers).
+            # For each match, keep the RFC 2965 cookie and ignore the Netscape
+            # cookie (RFC 2965 section 9.1).  Actually, RFC 2109 cookies are
+            # bundled in with the Netscape cookies for this purpose, which is
+            # reasonable behaviour.
+            if rfc2965:
+                lookup = {}
+                for cookie in cookies:
+                    lookup[(cookie.domain, cookie.path, cookie.name)] = None
+
+                def no_matching_rfc2965(ns_cookie, lookup=lookup):
+                    key = ns_cookie.domain, ns_cookie.path, ns_cookie.name
+                    return key not in lookup
+                ns_cookies = filter(no_matching_rfc2965, ns_cookies)
+
+            if ns_cookies:
+                cookies.extend(ns_cookies)
+
+        return cookies
+
+    def set_cookie_if_ok(self, cookie, request):
+        """Set a cookie if policy says it's OK to do so."""
+        self._cookies_lock.acquire()
+        self._policy._now = self._now = int(time.time())
+
+        if self._policy.set_ok(cookie, request):
+            self.set_cookie(cookie)
+
+        self._cookies_lock.release()
+
+    def set_cookie(self, cookie):
+        """Set a cookie, without checking whether or not it should be set."""
+        c = self._cookies
+        self._cookies_lock.acquire()
+        try:
+            if cookie.domain not in c: c[cookie.domain] = {}
+            c2 = c[cookie.domain]
+            if cookie.path not in c2: c2[cookie.path] = {}
+            c3 = c2[cookie.path]
+            c3[cookie.name] = cookie
+        finally:
+            self._cookies_lock.release()
+
+    def extract_cookies(self, response, request):
+        """Extract cookies from response, where allowable given the request."""
+        _debug("extract_cookies: %s", response.info())
+        self._cookies_lock.acquire()
+        self._policy._now = self._now = int(time.time())
+
+        for cookie in self.make_cookies(response, request):
+            if self._policy.set_ok(cookie, request):
+                _debug(" setting cookie: %s", cookie)
+                self.set_cookie(cookie)
+        self._cookies_lock.release()
+
+    def clear(self, domain=None, path=None, name=None):
+        """Clear some cookies.
+
+        Invoking this method without arguments will clear all cookies.  If
+        given a single argument, only cookies belonging to that domain will be
+        removed.  If given two arguments, cookies belonging to the specified
+        path within that domain are removed.  If given three arguments, then
+        the cookie with the specified name, path and domain is removed.
+
+        Raises KeyError if no matching cookie exists.
+
+        """
+        if name is not None:
+            if (domain is None) or (path is None):
+                raise ValueError(
+                    "domain and path must be given to remove a cookie by name")
+            del self._cookies[domain][path][name]
+        elif path is not None:
+            if domain is None:
+                raise ValueError(
+                    "domain must be given to remove cookies by path")
+            del self._cookies[domain][path]
+        elif domain is not None:
+            del self._cookies[domain]
+        else:
+            self._cookies = {}
+
+    def clear_session_cookies(self):
+        """Discard all session cookies.
+
+        Note that the .save() method won't save session cookies anyway, unless
+        you ask otherwise by passing a true ignore_discard argument.
+
+        """
+        self._cookies_lock.acquire()
+        for cookie in self:
+            if cookie.discard:
+                self.clear(cookie.domain, cookie.path, cookie.name)
+        self._cookies_lock.release()
+
+    def clear_expired_cookies(self):
+        """Discard all expired cookies.
+
+        You probably don't need to call this method: expired cookies are never
+        sent back to the server (provided you're using DefaultCookiePolicy),
+        this method is called by CookieJar itself every so often, and the
+        .save() method won't save expired cookies anyway (unless you ask
+        otherwise by passing a true ignore_expires argument).
+
+        """
+        self._cookies_lock.acquire()
+        now = time.time()
+        for cookie in self:
+            if cookie.is_expired(now):
+                self.clear(cookie.domain, cookie.path, cookie.name)
+        self._cookies_lock.release()
+
+    def __iter__(self):
+        return deepvalues(self._cookies)
+
+    def __len__(self):
+        """Return number of contained cookies."""
+        i = 0
+        for cookie in self: i = i + 1
+        return i
+
+    def __repr__(self):
+        r = []
+        for cookie in self: r.append(repr(cookie))
+        return "<%s[%s]>" % (self.__class__, ", ".join(r))
+
+    def __str__(self):
+        r = []
+        for cookie in self: r.append(str(cookie))
+        return "<%s[%s]>" % (self.__class__, ", ".join(r))
+
+
+# derives from IOError for backwards-compatibility with Python 2.4.0
+class LoadError(IOError): pass
+
+class FileCookieJar(CookieJar):
+    """CookieJar that can be loaded from and saved to a file."""
+
+    def __init__(self, filename=None, delayload=False, policy=None):
+        """
+        Cookies are NOT loaded from the named file until either the .load() or
+        .revert() method is called.
+
+        """
+        CookieJar.__init__(self, policy)
+        if filename is not None:
+            try:
+                filename+""
+            except:
+                raise ValueError("filename must be string-like")
+        self.filename = filename
+        self.delayload = bool(delayload)
+
+    def save(self, filename=None, ignore_discard=False, ignore_expires=False):
+        """Save cookies to a file."""
+        raise NotImplementedError()
+
+    def load(self, filename=None, ignore_discard=False, ignore_expires=False):
+        """Load cookies from a file."""
+        if filename is None:
+            if self.filename is not None: filename = self.filename
+            else: raise ValueError(MISSING_FILENAME_TEXT)
+
+        f = open(filename)
+        try:
+            self._really_load(f, filename, ignore_discard, ignore_expires)
+        finally:
+            f.close()
+
+    def revert(self, filename=None,
+               ignore_discard=False, ignore_expires=False):
+        """Clear all cookies and reload cookies from a saved file.
+
+        Raises LoadError (or IOError) if reversion is not successful; the
+        object's state will not be altered if this happens.
+
+        """
+        if filename is None:
+            if self.filename is not None: filename = self.filename
+            else: raise ValueError(MISSING_FILENAME_TEXT)
+
+        self._cookies_lock.acquire()
+
+        old_state = copy.deepcopy(self._cookies)
+        self._cookies = {}
+        try:
+            self.load(filename, ignore_discard, ignore_expires)
+        except (LoadError, IOError):
+            self._cookies = old_state
+            raise
+
+        self._cookies_lock.release()
+
+from _LWPCookieJar import LWPCookieJar, lwp_cookie_str
+from _MozillaCookieJar import MozillaCookieJar

Added: vendor/Python/current/Lib/copy.py
===================================================================
--- vendor/Python/current/Lib/copy.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/copy.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,414 @@
+"""Generic (shallow and deep) copying operations.
+
+Interface summary:
+
+        import copy
+
+        x = copy.copy(y)        # make a shallow copy of y
+        x = copy.deepcopy(y)    # make a deep copy of y
+
+For module specific errors, copy.Error is raised.
+
+The difference between shallow and deep copying is only relevant for
+compound objects (objects that contain other objects, like lists or
+class instances).
+
+- A shallow copy constructs a new compound object and then (to the
+  extent possible) inserts *the same objects* into it that the
+  original contains.
+
+- A deep copy constructs a new compound object and then, recursively,
+  inserts *copies* into it of the objects found in the original.
+
+Two problems often exist with deep copy operations that don't exist
+with shallow copy operations:
+
+ a) recursive objects (compound objects that, directly or indirectly,
+    contain a reference to themselves) may cause a recursive loop
+
+ b) because deep copy copies *everything* it may copy too much, e.g.
+    administrative data structures that should be shared even between
+    copies
+
+Python's deep copy operation avoids these problems by:
+
+ a) keeping a table of objects already copied during the current
+    copying pass
+
+ b) letting user-defined classes override the copying operation or the
+    set of components copied
+
+This version does not copy types like module, class, function, method,
+nor stack trace, stack frame, nor file, socket, window, nor array, nor
+any similar types.
+
+Classes can use the same interfaces to control copying that they use
+to control pickling: they can define methods called __getinitargs__(),
+__getstate__() and __setstate__().  See the documentation for module
+"pickle" for information on these methods.
+"""
+
+import types
+from copy_reg import dispatch_table
+
+class Error(Exception):
+    pass
+error = Error   # backward compatibility
+
+try:
+    from org.python.core import PyStringMap
+except ImportError:
+    PyStringMap = None
+
+__all__ = ["Error", "copy", "deepcopy"]
+
+def copy(x):
+    """Shallow copy operation on arbitrary Python objects.
+
+    See the module's __doc__ string for more info.
+    """
+
+    cls = type(x)
+
+    copier = _copy_dispatch.get(cls)
+    if copier:
+        return copier(x)
+
+    copier = getattr(cls, "__copy__", None)
+    if copier:
+        return copier(x)
+
+    reductor = dispatch_table.get(cls)
+    if reductor:
+        rv = reductor(x)
+    else:
+        reductor = getattr(x, "__reduce_ex__", None)
+        if reductor:
+            rv = reductor(2)
+        else:
+            reductor = getattr(x, "__reduce__", None)
+            if reductor:
+                rv = reductor()
+            else:
+                raise Error("un(shallow)copyable object of type %s" % cls)
+
+    return _reconstruct(x, rv, 0)
+
+
+_copy_dispatch = d = {}
+
+def _copy_immutable(x):
+    return x
+for t in (type(None), int, long, float, bool, str, tuple,
+          frozenset, type, xrange, types.ClassType,
+          types.BuiltinFunctionType,
+          types.FunctionType):
+    d[t] = _copy_immutable
+for name in ("ComplexType", "UnicodeType", "CodeType"):
+    t = getattr(types, name, None)
+    if t is not None:
+        d[t] = _copy_immutable
+
+def _copy_with_constructor(x):
+    return type(x)(x)
+for t in (list, dict, set):
+    d[t] = _copy_with_constructor
+
+def _copy_with_copy_method(x):
+    return x.copy()
+if PyStringMap is not None:
+    d[PyStringMap] = _copy_with_copy_method
+
+def _copy_inst(x):
+    if hasattr(x, '__copy__'):
+        return x.__copy__()
+    if hasattr(x, '__getinitargs__'):
+        args = x.__getinitargs__()
+        y = x.__class__(*args)
+    else:
+        y = _EmptyClass()
+        y.__class__ = x.__class__
+    if hasattr(x, '__getstate__'):
+        state = x.__getstate__()
+    else:
+        state = x.__dict__
+    if hasattr(y, '__setstate__'):
+        y.__setstate__(state)
+    else:
+        y.__dict__.update(state)
+    return y
+d[types.InstanceType] = _copy_inst
+
+del d
+
+def deepcopy(x, memo=None, _nil=[]):
+    """Deep copy operation on arbitrary Python objects.
+
+    See the module's __doc__ string for more info.
+    """
+
+    if memo is None:
+        memo = {}
+
+    d = id(x)
+    y = memo.get(d, _nil)
+    if y is not _nil:
+        return y
+
+    cls = type(x)
+
+    copier = _deepcopy_dispatch.get(cls)
+    if copier:
+        y = copier(x, memo)
+    else:
+        try:
+            issc = issubclass(cls, type)
+        except TypeError: # cls is not a class (old Boost; see SF #502085)
+            issc = 0
+        if issc:
+            y = _deepcopy_atomic(x, memo)
+        else:
+            copier = getattr(x, "__deepcopy__", None)
+            if copier:
+                y = copier(memo)
+            else:
+                reductor = dispatch_table.get(cls)
+                if reductor:
+                    rv = reductor(x)
+                else:
+                    reductor = getattr(x, "__reduce_ex__", None)
+                    if reductor:
+                        rv = reductor(2)
+                    else:
+                        reductor = getattr(x, "__reduce__", None)
+                        if reductor:
+                            rv = reductor()
+                        else:
+                            raise Error(
+                                "un(deep)copyable object of type %s" % cls)
+                y = _reconstruct(x, rv, 1, memo)
+
+    memo[d] = y
+    _keep_alive(x, memo) # Make sure x lives at least as long as d
+    return y
+
+_deepcopy_dispatch = d = {}
+
+def _deepcopy_atomic(x, memo):
+    return x
+d[type(None)] = _deepcopy_atomic
+d[int] = _deepcopy_atomic
+d[long] = _deepcopy_atomic
+d[float] = _deepcopy_atomic
+d[bool] = _deepcopy_atomic
+try:
+    d[complex] = _deepcopy_atomic
+except NameError:
+    pass
+d[str] = _deepcopy_atomic
+try:
+    d[unicode] = _deepcopy_atomic
+except NameError:
+    pass
+try:
+    d[types.CodeType] = _deepcopy_atomic
+except AttributeError:
+    pass
+d[type] = _deepcopy_atomic
+d[xrange] = _deepcopy_atomic
+d[types.ClassType] = _deepcopy_atomic
+d[types.BuiltinFunctionType] = _deepcopy_atomic
+d[types.FunctionType] = _deepcopy_atomic
+
+def _deepcopy_list(x, memo):
+    y = []
+    memo[id(x)] = y
+    for a in x:
+        y.append(deepcopy(a, memo))
+    return y
+d[list] = _deepcopy_list
+
+def _deepcopy_tuple(x, memo):
+    y = []
+    for a in x:
+        y.append(deepcopy(a, memo))
+    d = id(x)
+    try:
+        return memo[d]
+    except KeyError:
+        pass
+    for i in range(len(x)):
+        if x[i] is not y[i]:
+            y = tuple(y)
+            break
+    else:
+        y = x
+    memo[d] = y
+    return y
+d[tuple] = _deepcopy_tuple
+
+def _deepcopy_dict(x, memo):
+    y = {}
+    memo[id(x)] = y
+    for key, value in x.iteritems():
+        y[deepcopy(key, memo)] = deepcopy(value, memo)
+    return y
+d[dict] = _deepcopy_dict
+if PyStringMap is not None:
+    d[PyStringMap] = _deepcopy_dict
+
+def _keep_alive(x, memo):
+    """Keeps a reference to the object x in the memo.
+
+    Because we remember objects by their id, we have
+    to assure that possibly temporary objects are kept
+    alive by referencing them.
+    We store a reference at the id of the memo, which should
+    normally not be used unless someone tries to deepcopy
+    the memo itself...
+    """
+    try:
+        memo[id(memo)].append(x)
+    except KeyError:
+        # aha, this is the first one :-)
+        memo[id(memo)]=[x]
+
+def _deepcopy_inst(x, memo):
+    if hasattr(x, '__deepcopy__'):
+        return x.__deepcopy__(memo)
+    if hasattr(x, '__getinitargs__'):
+        args = x.__getinitargs__()
+        args = deepcopy(args, memo)
+        y = x.__class__(*args)
+    else:
+        y = _EmptyClass()
+        y.__class__ = x.__class__
+    memo[id(x)] = y
+    if hasattr(x, '__getstate__'):
+        state = x.__getstate__()
+    else:
+        state = x.__dict__
+    state = deepcopy(state, memo)
+    if hasattr(y, '__setstate__'):
+        y.__setstate__(state)
+    else:
+        y.__dict__.update(state)
+    return y
+d[types.InstanceType] = _deepcopy_inst
+
+def _reconstruct(x, info, deep, memo=None):
+    if isinstance(info, str):
+        return x
+    assert isinstance(info, tuple)
+    if memo is None:
+        memo = {}
+    n = len(info)
+    assert n in (2, 3, 4, 5)
+    callable, args = info[:2]
+    if n > 2:
+        state = info[2]
+    else:
+        state = {}
+    if n > 3:
+        listiter = info[3]
+    else:
+        listiter = None
+    if n > 4:
+        dictiter = info[4]
+    else:
+        dictiter = None
+    if deep:
+        args = deepcopy(args, memo)
+    y = callable(*args)
+    memo[id(x)] = y
+    if listiter is not None:
+        for item in listiter:
+            if deep:
+                item = deepcopy(item, memo)
+            y.append(item)
+    if dictiter is not None:
+        for key, value in dictiter:
+            if deep:
+                key = deepcopy(key, memo)
+                value = deepcopy(value, memo)
+            y[key] = value
+    if state:
+        if deep:
+            state = deepcopy(state, memo)
+        if hasattr(y, '__setstate__'):
+            y.__setstate__(state)
+        else:
+            if isinstance(state, tuple) and len(state) == 2:
+                state, slotstate = state
+            else:
+                slotstate = None
+            if state is not None:
+                y.__dict__.update(state)
+            if slotstate is not None:
+                for key, value in slotstate.iteritems():
+                    setattr(y, key, value)
+    return y
+
+del d
+
+del types
+
+# Helper for instance creation without calling __init__
+class _EmptyClass:
+    pass
+
+def _test():
+    l = [None, 1, 2L, 3.14, 'xyzzy', (1, 2L), [3.14, 'abc'],
+         {'abc': 'ABC'}, (), [], {}]
+    l1 = copy(l)
+    print l1==l
+    l1 = map(copy, l)
+    print l1==l
+    l1 = deepcopy(l)
+    print l1==l
+    class C:
+        def __init__(self, arg=None):
+            self.a = 1
+            self.arg = arg
+            if __name__ == '__main__':
+                import sys
+                file = sys.argv[0]
+            else:
+                file = __file__
+            self.fp = open(file)
+            self.fp.close()
+        def __getstate__(self):
+            return {'a': self.a, 'arg': self.arg}
+        def __setstate__(self, state):
+            for key, value in state.iteritems():
+                setattr(self, key, value)
+        def __deepcopy__(self, memo=None):
+            new = self.__class__(deepcopy(self.arg, memo))
+            new.a = self.a
+            return new
+    c = C('argument sketch')
+    l.append(c)
+    l2 = copy(l)
+    print l == l2
+    print l
+    print l2
+    l2 = deepcopy(l)
+    print l == l2
+    print l
+    print l2
+    l.append({l[1]: l, 'xyz': l[2]})
+    l3 = copy(l)
+    import repr
+    print map(repr.repr, l)
+    print map(repr.repr, l1)
+    print map(repr.repr, l2)
+    print map(repr.repr, l3)
+    l3 = deepcopy(l)
+    import repr
+    print map(repr.repr, l)
+    print map(repr.repr, l1)
+    print map(repr.repr, l2)
+    print map(repr.repr, l3)
+
+if __name__ == '__main__':
+    _test()

Added: vendor/Python/current/Lib/copy_reg.py
===================================================================
--- vendor/Python/current/Lib/copy_reg.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/copy_reg.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,200 @@
+"""Helper to provide extensibility for pickle/cPickle.
+
+This is only useful to add pickle support for extension types defined in
+C, not for instances of user-defined classes.
+"""
+
+from types import ClassType as _ClassType
+
+__all__ = ["pickle", "constructor",
+           "add_extension", "remove_extension", "clear_extension_cache"]
+
+dispatch_table = {}
+
+def pickle(ob_type, pickle_function, constructor_ob=None):
+    if type(ob_type) is _ClassType:
+        raise TypeError("copy_reg is not intended for use with classes")
+
+    if not callable(pickle_function):
+        raise TypeError("reduction functions must be callable")
+    dispatch_table[ob_type] = pickle_function
+
+    # The constructor_ob function is a vestige of safe for unpickling.
+    # There is no reason for the caller to pass it anymore.
+    if constructor_ob is not None:
+        constructor(constructor_ob)
+
+def constructor(object):
+    if not callable(object):
+        raise TypeError("constructors must be callable")
+
+# Example: provide pickling support for complex numbers.
+
+try:
+    complex
+except NameError:
+    pass
+else:
+
+    def pickle_complex(c):
+        return complex, (c.real, c.imag)
+
+    pickle(complex, pickle_complex, complex)
+
+# Support for pickling new-style objects
+
+def _reconstructor(cls, base, state):
+    if base is object:
+        obj = object.__new__(cls)
+    else:
+        obj = base.__new__(cls, state)
+        base.__init__(obj, state)
+    return obj
+
+_HEAPTYPE = 1<<9
+
+# Python code for object.__reduce_ex__ for protocols 0 and 1
+
+def _reduce_ex(self, proto):
+    assert proto < 2
+    for base in self.__class__.__mro__:
+        if hasattr(base, '__flags__') and not base.__flags__ & _HEAPTYPE:
+            break
+    else:
+        base = object # not really reachable
+    if base is object:
+        state = None
+    else:
+        if base is self.__class__:
+            raise TypeError, "can't pickle %s objects" % base.__name__
+        state = base(self)
+    args = (self.__class__, base, state)
+    try:
+        getstate = self.__getstate__
+    except AttributeError:
+        if getattr(self, "__slots__", None):
+            raise TypeError("a class that defines __slots__ without "
+                            "defining __getstate__ cannot be pickled")
+        try:
+            dict = self.__dict__
+        except AttributeError:
+            dict = None
+    else:
+        dict = getstate()
+    if dict:
+        return _reconstructor, args, dict
+    else:
+        return _reconstructor, args
+
+# Helper for __reduce_ex__ protocol 2
+
+def __newobj__(cls, *args):
+    return cls.__new__(cls, *args)
+
+def _slotnames(cls):
+    """Return a list of slot names for a given class.
+
+    This needs to find slots defined by the class and its bases, so we
+    can't simply return the __slots__ attribute.  We must walk down
+    the Method Resolution Order and concatenate the __slots__ of each
+    class found there.  (This assumes classes don't modify their
+    __slots__ attribute to misrepresent their slots after the class is
+    defined.)
+    """
+
+    # Get the value from a cache in the class if possible
+    names = cls.__dict__.get("__slotnames__")
+    if names is not None:
+        return names
+
+    # Not cached -- calculate the value
+    names = []
+    if not hasattr(cls, "__slots__"):
+        # This class has no slots
+        pass
+    else:
+        # Slots found -- gather slot names from all base classes
+        for c in cls.__mro__:
+            if "__slots__" in c.__dict__:
+                slots = c.__dict__['__slots__']
+                # if class has a single slot, it can be given as a string
+                if isinstance(slots, basestring):
+                    slots = (slots,)
+                for name in slots:
+                    # special descriptors
+                    if name in ("__dict__", "__weakref__"):
+                        continue
+                    # mangled names
+                    elif name.startswith('__') and not name.endswith('__'):
+                        names.append('_%s%s' % (c.__name__, name))
+                    else:
+                        names.append(name)
+
+    # Cache the outcome in the class if at all possible
+    try:
+        cls.__slotnames__ = names
+    except:
+        pass # But don't die if we can't
+
+    return names
+
+# A registry of extension codes.  This is an ad-hoc compression
+# mechanism.  Whenever a global reference to <module>, <name> is about
+# to be pickled, the (<module>, <name>) tuple is looked up here to see
+# if it is a registered extension code for it.  Extension codes are
+# universal, so that the meaning of a pickle does not depend on
+# context.  (There are also some codes reserved for local use that
+# don't have this restriction.)  Codes are positive ints; 0 is
+# reserved.
+
+_extension_registry = {}                # key -> code
+_inverted_registry = {}                 # code -> key
+_extension_cache = {}                   # code -> object
+# Don't ever rebind those names:  cPickle grabs a reference to them when
+# it's initialized, and won't see a rebinding.
+
+def add_extension(module, name, code):
+    """Register an extension code."""
+    code = int(code)
+    if not 1 <= code <= 0x7fffffff:
+        raise ValueError, "code out of range"
+    key = (module, name)
+    if (_extension_registry.get(key) == code and
+        _inverted_registry.get(code) == key):
+        return # Redundant registrations are benign
+    if key in _extension_registry:
+        raise ValueError("key %s is already registered with code %s" %
+                         (key, _extension_registry[key]))
+    if code in _inverted_registry:
+        raise ValueError("code %s is already in use for key %s" %
+                         (code, _inverted_registry[code]))
+    _extension_registry[key] = code
+    _inverted_registry[code] = key
+
+def remove_extension(module, name, code):
+    """Unregister an extension code.  For testing only."""
+    key = (module, name)
+    if (_extension_registry.get(key) != code or
+        _inverted_registry.get(code) != key):
+        raise ValueError("key %s is not registered with code %s" %
+                         (key, code))
+    del _extension_registry[key]
+    del _inverted_registry[code]
+    if code in _extension_cache:
+        del _extension_cache[code]
+
+def clear_extension_cache():
+    _extension_cache.clear()
+
+# Standard extension code assignments
+
+# Reserved ranges
+
+# First  Last Count  Purpose
+#     1   127   127  Reserved for Python standard library
+#   128   191    64  Reserved for Zope
+#   192   239    48  Reserved for 3rd parties
+#   240   255    16  Reserved for private use (will never be assigned)
+#   256   Inf   Inf  Reserved for future assignment
+
+# Extension codes are assigned by the Python Software Foundation.

Added: vendor/Python/current/Lib/csv.py
===================================================================
--- vendor/Python/current/Lib/csv.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/csv.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,415 @@
+
+"""
+csv.py - read/write/investigate CSV files
+"""
+
+import re
+from _csv import Error, __version__, writer, reader, register_dialect, \
+                 unregister_dialect, get_dialect, list_dialects, \
+                 field_size_limit, \
+                 QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC, QUOTE_NONE, \
+                 __doc__
+from _csv import Dialect as _Dialect
+
+try:
+    from cStringIO import StringIO
+except ImportError:
+    from StringIO import StringIO
+
+__all__ = [ "QUOTE_MINIMAL", "QUOTE_ALL", "QUOTE_NONNUMERIC", "QUOTE_NONE",
+            "Error", "Dialect", "excel", "excel_tab", "reader", "writer",
+            "register_dialect", "get_dialect", "list_dialects", "Sniffer",
+            "unregister_dialect", "__version__", "DictReader", "DictWriter" ]
+
+class Dialect:
+    """Describe an Excel dialect.
+
+    This must be subclassed (see csv.excel).  Valid attributes are:
+    delimiter, quotechar, escapechar, doublequote, skipinitialspace,
+    lineterminator, quoting.
+
+    """
+    _name = ""
+    _valid = False
+    # placeholders
+    delimiter = None
+    quotechar = None
+    escapechar = None
+    doublequote = None
+    skipinitialspace = None
+    lineterminator = None
+    quoting = None
+
+    def __init__(self):
+        if self.__class__ != Dialect:
+            self._valid = True
+        self._validate()
+
+    def _validate(self):
+        try:
+            _Dialect(self)
+        except TypeError, e:
+            # We do this for compatibility with py2.3
+            raise Error(str(e))
+
+class excel(Dialect):
+    """Describe the usual properties of Excel-generated CSV files."""
+    delimiter = ','
+    quotechar = '"'
+    doublequote = True
+    skipinitialspace = False
+    lineterminator = '\r\n'
+    quoting = QUOTE_MINIMAL
+register_dialect("excel", excel)
+
+class excel_tab(excel):
+    """Describe the usual properties of Excel-generated TAB-delimited files."""
+    delimiter = '\t'
+register_dialect("excel-tab", excel_tab)
+
+
+class DictReader:
+    def __init__(self, f, fieldnames=None, restkey=None, restval=None,
+                 dialect="excel", *args, **kwds):
+        self.fieldnames = fieldnames    # list of keys for the dict
+        self.restkey = restkey          # key to catch long rows
+        self.restval = restval          # default value for short rows
+        self.reader = reader(f, dialect, *args, **kwds)
+
+    def __iter__(self):
+        return self
+
+    def next(self):
+        row = self.reader.next()
+        if self.fieldnames is None:
+            self.fieldnames = row
+            row = self.reader.next()
+
+        # unlike the basic reader, we prefer not to return blanks,
+        # because we will typically wind up with a dict full of None
+        # values
+        while row == []:
+            row = self.reader.next()
+        d = dict(zip(self.fieldnames, row))
+        lf = len(self.fieldnames)
+        lr = len(row)
+        if lf < lr:
+            d[self.restkey] = row[lf:]
+        elif lf > lr:
+            for key in self.fieldnames[lr:]:
+                d[key] = self.restval
+        return d
+
+
+class DictWriter:
+    def __init__(self, f, fieldnames, restval="", extrasaction="raise",
+                 dialect="excel", *args, **kwds):
+        self.fieldnames = fieldnames    # list of keys for the dict
+        self.restval = restval          # for writing short dicts
+        if extrasaction.lower() not in ("raise", "ignore"):
+            raise ValueError, \
+                  ("extrasaction (%s) must be 'raise' or 'ignore'" %
+                   extrasaction)
+        self.extrasaction = extrasaction
+        self.writer = writer(f, dialect, *args, **kwds)
+
+    def _dict_to_list(self, rowdict):
+        if self.extrasaction == "raise":
+            for k in rowdict.keys():
+                if k not in self.fieldnames:
+                    raise ValueError, "dict contains fields not in fieldnames"
+        return [rowdict.get(key, self.restval) for key in self.fieldnames]
+
+    def writerow(self, rowdict):
+        return self.writer.writerow(self._dict_to_list(rowdict))
+
+    def writerows(self, rowdicts):
+        rows = []
+        for rowdict in rowdicts:
+            rows.append(self._dict_to_list(rowdict))
+        return self.writer.writerows(rows)
+
+# Guard Sniffer's type checking against builds that exclude complex()
+try:
+    complex
+except NameError:
+    complex = float
+
+class Sniffer:
+    '''
+    "Sniffs" the format of a CSV file (i.e. delimiter, quotechar)
+    Returns a Dialect object.
+    '''
+    def __init__(self):
+        # in case there is more than one possible delimiter
+        self.preferred = [',', '\t', ';', ' ', ':']
+
+
+    def sniff(self, sample, delimiters=None):
+        """
+        Returns a dialect (or None) corresponding to the sample
+        """
+
+        quotechar, delimiter, skipinitialspace = \
+                   self._guess_quote_and_delimiter(sample, delimiters)
+        if not delimiter:
+            delimiter, skipinitialspace = self._guess_delimiter(sample,
+                                                                delimiters)
+
+        if not delimiter:
+            raise Error, "Could not determine delimiter"
+
+        class dialect(Dialect):
+            _name = "sniffed"
+            lineterminator = '\r\n'
+            quoting = QUOTE_MINIMAL
+            # escapechar = ''
+            doublequote = False
+
+        dialect.delimiter = delimiter
+        # _csv.reader won't accept a quotechar of ''
+        dialect.quotechar = quotechar or '"'
+        dialect.skipinitialspace = skipinitialspace
+
+        return dialect
+
+
+    def _guess_quote_and_delimiter(self, data, delimiters):
+        """
+        Looks for text enclosed between two identical quotes
+        (the probable quotechar) which are preceded and followed
+        by the same character (the probable delimiter).
+        For example:
+                         ,'some text',
+        The quote with the most wins, same with the delimiter.
+        If there is no quotechar the delimiter can't be determined
+        this way.
+        """
+
+        matches = []
+        for restr in ('(?P<delim>[^\w\n"\'])(?P<space> ?)(?P<quote>["\']).*?(?P=quote)(?P=delim)', # ,".*?",
+                      '(?:^|\n)(?P<quote>["\']).*?(?P=quote)(?P<delim>[^\w\n"\'])(?P<space> ?)',   #  ".*?",
+                      '(?P<delim>>[^\w\n"\'])(?P<space> ?)(?P<quote>["\']).*?(?P=quote)(?:$|\n)',  # ,".*?"
+                      '(?:^|\n)(?P<quote>["\']).*?(?P=quote)(?:$|\n)'):                            #  ".*?" (no delim, no space)
+            regexp = re.compile(restr, re.DOTALL | re.MULTILINE)
+            matches = regexp.findall(data)
+            if matches:
+                break
+
+        if not matches:
+            return ('', None, 0) # (quotechar, delimiter, skipinitialspace)
+
+        quotes = {}
+        delims = {}
+        spaces = 0
+        for m in matches:
+            n = regexp.groupindex['quote'] - 1
+            key = m[n]
+            if key:
+                quotes[key] = quotes.get(key, 0) + 1
+            try:
+                n = regexp.groupindex['delim'] - 1
+                key = m[n]
+            except KeyError:
+                continue
+            if key and (delimiters is None or key in delimiters):
+                delims[key] = delims.get(key, 0) + 1
+            try:
+                n = regexp.groupindex['space'] - 1
+            except KeyError:
+                continue
+            if m[n]:
+                spaces += 1
+
+        quotechar = reduce(lambda a, b, quotes = quotes:
+                           (quotes[a] > quotes[b]) and a or b, quotes.keys())
+
+        if delims:
+            delim = reduce(lambda a, b, delims = delims:
+                           (delims[a] > delims[b]) and a or b, delims.keys())
+            skipinitialspace = delims[delim] == spaces
+            if delim == '\n': # most likely a file with a single column
+                delim = ''
+        else:
+            # there is *no* delimiter, it's a single column of quoted data
+            delim = ''
+            skipinitialspace = 0
+
+        return (quotechar, delim, skipinitialspace)
+
+
+    def _guess_delimiter(self, data, delimiters):
+        """
+        The delimiter /should/ occur the same number of times on
+        each row. However, due to malformed data, it may not. We don't want
+        an all or nothing approach, so we allow for small variations in this
+        number.
+          1) build a table of the frequency of each character on every line.
+          2) build a table of freqencies of this frequency (meta-frequency?),
+             e.g.  'x occurred 5 times in 10 rows, 6 times in 1000 rows,
+             7 times in 2 rows'
+          3) use the mode of the meta-frequency to determine the /expected/
+             frequency for that character
+          4) find out how often the character actually meets that goal
+          5) the character that best meets its goal is the delimiter
+        For performance reasons, the data is evaluated in chunks, so it can
+        try and evaluate the smallest portion of the data possible, evaluating
+        additional chunks as necessary.
+        """
+
+        data = filter(None, data.split('\n'))
+
+        ascii = [chr(c) for c in range(127)] # 7-bit ASCII
+
+        # build frequency tables
+        chunkLength = min(10, len(data))
+        iteration = 0
+        charFrequency = {}
+        modes = {}
+        delims = {}
+        start, end = 0, min(chunkLength, len(data))
+        while start < len(data):
+            iteration += 1
+            for line in data[start:end]:
+                for char in ascii:
+                    metaFrequency = charFrequency.get(char, {})
+                    # must count even if frequency is 0
+                    freq = line.count(char)
+                    # value is the mode
+                    metaFrequency[freq] = metaFrequency.get(freq, 0) + 1
+                    charFrequency[char] = metaFrequency
+
+            for char in charFrequency.keys():
+                items = charFrequency[char].items()
+                if len(items) == 1 and items[0][0] == 0:
+                    continue
+                # get the mode of the frequencies
+                if len(items) > 1:
+                    modes[char] = reduce(lambda a, b: a[1] > b[1] and a or b,
+                                         items)
+                    # adjust the mode - subtract the sum of all
+                    # other frequencies
+                    items.remove(modes[char])
+                    modes[char] = (modes[char][0], modes[char][1]
+                                   - reduce(lambda a, b: (0, a[1] + b[1]),
+                                            items)[1])
+                else:
+                    modes[char] = items[0]
+
+            # build a list of possible delimiters
+            modeList = modes.items()
+            total = float(chunkLength * iteration)
+            # (rows of consistent data) / (number of rows) = 100%
+            consistency = 1.0
+            # minimum consistency threshold
+            threshold = 0.9
+            while len(delims) == 0 and consistency >= threshold:
+                for k, v in modeList:
+                    if v[0] > 0 and v[1] > 0:
+                        if ((v[1]/total) >= consistency and
+                            (delimiters is None or k in delimiters)):
+                            delims[k] = v
+                consistency -= 0.01
+
+            if len(delims) == 1:
+                delim = delims.keys()[0]
+                skipinitialspace = (data[0].count(delim) ==
+                                    data[0].count("%c " % delim))
+                return (delim, skipinitialspace)
+
+            # analyze another chunkLength lines
+            start = end
+            end += chunkLength
+
+        if not delims:
+            return ('', 0)
+
+        # if there's more than one, fall back to a 'preferred' list
+        if len(delims) > 1:
+            for d in self.preferred:
+                if d in delims.keys():
+                    skipinitialspace = (data[0].count(d) ==
+                                        data[0].count("%c " % d))
+                    return (d, skipinitialspace)
+
+        # nothing else indicates a preference, pick the character that
+        # dominates(?)
+        items = [(v,k) for (k,v) in delims.items()]
+        items.sort()
+        delim = items[-1][1]
+
+        skipinitialspace = (data[0].count(delim) ==
+                            data[0].count("%c " % delim))
+        return (delim, skipinitialspace)
+
+
+    def has_header(self, sample):
+        # Creates a dictionary of types of data in each column. If any
+        # column is of a single type (say, integers), *except* for the first
+        # row, then the first row is presumed to be labels. If the type
+        # can't be determined, it is assumed to be a string in which case
+        # the length of the string is the determining factor: if all of the
+        # rows except for the first are the same length, it's a header.
+        # Finally, a 'vote' is taken at the end for each column, adding or
+        # subtracting from the likelihood of the first row being a header.
+
+        rdr = reader(StringIO(sample), self.sniff(sample))
+
+        header = rdr.next() # assume first row is header
+
+        columns = len(header)
+        columnTypes = {}
+        for i in range(columns): columnTypes[i] = None
+
+        checked = 0
+        for row in rdr:
+            # arbitrary number of rows to check, to keep it sane
+            if checked > 20:
+                break
+            checked += 1
+
+            if len(row) != columns:
+                continue # skip rows that have irregular number of columns
+
+            for col in columnTypes.keys():
+
+                for thisType in [int, long, float, complex]:
+                    try:
+                        thisType(row[col])
+                        break
+                    except (ValueError, OverflowError):
+                        pass
+                else:
+                    # fallback to length of string
+                    thisType = len(row[col])
+
+                # treat longs as ints
+                if thisType == long:
+                    thisType = int
+
+                if thisType != columnTypes[col]:
+                    if columnTypes[col] is None: # add new column type
+                        columnTypes[col] = thisType
+                    else:
+                        # type is inconsistent, remove column from
+                        # consideration
+                        del columnTypes[col]
+
+        # finally, compare results against first row and "vote"
+        # on whether it's a header
+        hasHeader = 0
+        for col, colType in columnTypes.items():
+            if type(colType) == type(0): # it's a length
+                if len(header[col]) != colType:
+                    hasHeader += 1
+                else:
+                    hasHeader -= 1
+            else: # attempt typecast
+                try:
+                    colType(header[col])
+                except (ValueError, TypeError):
+                    hasHeader += 1
+                else:
+                    hasHeader -= 1
+
+        return hasHeader > 0

Added: vendor/Python/current/Lib/ctypes/__init__.py
===================================================================
--- vendor/Python/current/Lib/ctypes/__init__.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/__init__.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,529 @@
+######################################################################
+#  This file should be kept compatible with Python 2.3, see PEP 291. #
+######################################################################
+"""create and manipulate C data types in Python"""
+
+import os as _os, sys as _sys
+
+__version__ = "1.0.2"
+
+from _ctypes import Union, Structure, Array
+from _ctypes import _Pointer
+from _ctypes import CFuncPtr as _CFuncPtr
+from _ctypes import __version__ as _ctypes_version
+from _ctypes import RTLD_LOCAL, RTLD_GLOBAL
+from _ctypes import ArgumentError
+
+from struct import calcsize as _calcsize
+
+if __version__ != _ctypes_version:
+    raise Exception, ("Version number mismatch", __version__, _ctypes_version)
+
+if _os.name in ("nt", "ce"):
+    from _ctypes import FormatError
+
+DEFAULT_MODE = RTLD_LOCAL
+if _os.name == "posix" and _sys.platform == "darwin":
+    import gestalt
+
+    # gestalt.gestalt("sysv") returns the version number of the
+    # currently active system file as BCD.
+    # On OS X 10.4.6 -> 0x1046
+    # On OS X 10.2.8 -> 0x1028
+    # See also http://www.rgaros.nl/gestalt/
+    #
+    # On OS X 10.3, we use RTLD_GLOBAL as default mode
+    # because RTLD_LOCAL does not work at least on some
+    # libraries.
+
+    if gestalt.gestalt("sysv") < 0x1040:
+        DEFAULT_MODE = RTLD_GLOBAL
+
+from _ctypes import FUNCFLAG_CDECL as _FUNCFLAG_CDECL, \
+     FUNCFLAG_PYTHONAPI as _FUNCFLAG_PYTHONAPI
+
+"""
+WINOLEAPI -> HRESULT
+WINOLEAPI_(type)
+
+STDMETHODCALLTYPE
+
+STDMETHOD(name)
+STDMETHOD_(type, name)
+
+STDAPICALLTYPE
+"""
+
+def create_string_buffer(init, size=None):
+    """create_string_buffer(aString) -> character array
+    create_string_buffer(anInteger) -> character array
+    create_string_buffer(aString, anInteger) -> character array
+    """
+    if isinstance(init, (str, unicode)):
+        if size is None:
+            size = len(init)+1
+        buftype = c_char * size
+        buf = buftype()
+        buf.value = init
+        return buf
+    elif isinstance(init, (int, long)):
+        buftype = c_char * init
+        buf = buftype()
+        return buf
+    raise TypeError, init
+
+def c_buffer(init, size=None):
+##    "deprecated, use create_string_buffer instead"
+##    import warnings
+##    warnings.warn("c_buffer is deprecated, use create_string_buffer instead",
+##                  DeprecationWarning, stacklevel=2)
+    return create_string_buffer(init, size)
+
+_c_functype_cache = {}
+def CFUNCTYPE(restype, *argtypes):
+    """CFUNCTYPE(restype, *argtypes) -> function prototype.
+
+    restype: the result type
+    argtypes: a sequence specifying the argument types
+
+    The function prototype can be called in different ways to create a
+    callable object:
+
+    prototype(integer address) -> foreign function
+    prototype(callable) -> create and return a C callable function from callable
+    prototype(integer index, method name[, paramflags]) -> foreign function calling a COM method
+    prototype((ordinal number, dll object)[, paramflags]) -> foreign function exported by ordinal
+    prototype((function name, dll object)[, paramflags]) -> foreign function exported by name
+    """
+    try:
+        return _c_functype_cache[(restype, argtypes)]
+    except KeyError:
+        class CFunctionType(_CFuncPtr):
+            _argtypes_ = argtypes
+            _restype_ = restype
+            _flags_ = _FUNCFLAG_CDECL
+        _c_functype_cache[(restype, argtypes)] = CFunctionType
+        return CFunctionType
+
+if _os.name in ("nt", "ce"):
+    from _ctypes import LoadLibrary as _dlopen
+    from _ctypes import FUNCFLAG_STDCALL as _FUNCFLAG_STDCALL
+    if _os.name == "ce":
+        # 'ce' doesn't have the stdcall calling convention
+        _FUNCFLAG_STDCALL = _FUNCFLAG_CDECL
+
+    _win_functype_cache = {}
+    def WINFUNCTYPE(restype, *argtypes):
+        # docstring set later (very similar to CFUNCTYPE.__doc__)
+        try:
+            return _win_functype_cache[(restype, argtypes)]
+        except KeyError:
+            class WinFunctionType(_CFuncPtr):
+                _argtypes_ = argtypes
+                _restype_ = restype
+                _flags_ = _FUNCFLAG_STDCALL
+            _win_functype_cache[(restype, argtypes)] = WinFunctionType
+            return WinFunctionType
+    if WINFUNCTYPE.__doc__:
+        WINFUNCTYPE.__doc__ = CFUNCTYPE.__doc__.replace("CFUNCTYPE", "WINFUNCTYPE")
+
+elif _os.name == "posix":
+    from _ctypes import dlopen as _dlopen
+
+from _ctypes import sizeof, byref, addressof, alignment, resize
+from _ctypes import _SimpleCData
+
+def _check_size(typ, typecode=None):
+    # Check if sizeof(ctypes_type) against struct.calcsize.  This
+    # should protect somewhat against a misconfigured libffi.
+    from struct import calcsize
+    if typecode is None:
+        # Most _type_ codes are the same as used in struct
+        typecode = typ._type_
+    actual, required = sizeof(typ), calcsize(typecode)
+    if actual != required:
+        raise SystemError("sizeof(%s) wrong: %d instead of %d" % \
+                          (typ, actual, required))
+
+class py_object(_SimpleCData):
+    _type_ = "O"
+    def __repr__(self):
+        try:
+            return super(py_object, self).__repr__()
+        except ValueError:
+            return "%s(<NULL>)" % type(self).__name__
+_check_size(py_object, "P")
+
+class c_short(_SimpleCData):
+    _type_ = "h"
+_check_size(c_short)
+
+class c_ushort(_SimpleCData):
+    _type_ = "H"
+_check_size(c_ushort)
+
+class c_long(_SimpleCData):
+    _type_ = "l"
+_check_size(c_long)
+
+class c_ulong(_SimpleCData):
+    _type_ = "L"
+_check_size(c_ulong)
+
+if _calcsize("i") == _calcsize("l"):
+    # if int and long have the same size, make c_int an alias for c_long
+    c_int = c_long
+    c_uint = c_ulong
+else:
+    class c_int(_SimpleCData):
+        _type_ = "i"
+    _check_size(c_int)
+
+    class c_uint(_SimpleCData):
+        _type_ = "I"
+    _check_size(c_uint)
+
+class c_float(_SimpleCData):
+    _type_ = "f"
+_check_size(c_float)
+
+class c_double(_SimpleCData):
+    _type_ = "d"
+_check_size(c_double)
+
+if _calcsize("l") == _calcsize("q"):
+    # if long and long long have the same size, make c_longlong an alias for c_long
+    c_longlong = c_long
+    c_ulonglong = c_ulong
+else:
+    class c_longlong(_SimpleCData):
+        _type_ = "q"
+    _check_size(c_longlong)
+
+    class c_ulonglong(_SimpleCData):
+        _type_ = "Q"
+    ##    def from_param(cls, val):
+    ##        return ('d', float(val), val)
+    ##    from_param = classmethod(from_param)
+    _check_size(c_ulonglong)
+
+class c_ubyte(_SimpleCData):
+    _type_ = "B"
+c_ubyte.__ctype_le__ = c_ubyte.__ctype_be__ = c_ubyte
+# backward compatibility:
+##c_uchar = c_ubyte
+_check_size(c_ubyte)
+
+class c_byte(_SimpleCData):
+    _type_ = "b"
+c_byte.__ctype_le__ = c_byte.__ctype_be__ = c_byte
+_check_size(c_byte)
+
+class c_char(_SimpleCData):
+    _type_ = "c"
+c_char.__ctype_le__ = c_char.__ctype_be__ = c_char
+_check_size(c_char)
+
+class c_char_p(_SimpleCData):
+    _type_ = "z"
+_check_size(c_char_p, "P")
+
+class c_void_p(_SimpleCData):
+    _type_ = "P"
+c_voidp = c_void_p # backwards compatibility (to a bug)
+_check_size(c_void_p)
+
+# This cache maps types to pointers to them.
+_pointer_type_cache = {}
+
+def POINTER(cls):
+    try:
+        return _pointer_type_cache[cls]
+    except KeyError:
+        pass
+    if type(cls) is str:
+        klass = type(_Pointer)("LP_%s" % cls,
+                               (_Pointer,),
+                               {})
+        _pointer_type_cache[id(klass)] = klass
+        return klass
+    else:
+        name = "LP_%s" % cls.__name__
+        klass = type(_Pointer)(name,
+                               (_Pointer,),
+                               {'_type_': cls})
+        _pointer_type_cache[cls] = klass
+    return klass
+
+try:
+    from _ctypes import set_conversion_mode
+except ImportError:
+    pass
+else:
+    if _os.name in ("nt", "ce"):
+        set_conversion_mode("mbcs", "ignore")
+    else:
+        set_conversion_mode("ascii", "strict")
+
+    class c_wchar_p(_SimpleCData):
+        _type_ = "Z"
+
+    class c_wchar(_SimpleCData):
+        _type_ = "u"
+
+    POINTER(c_wchar).from_param = c_wchar_p.from_param #_SimpleCData.c_wchar_p_from_param
+
+    def create_unicode_buffer(init, size=None):
+        """create_unicode_buffer(aString) -> character array
+        create_unicode_buffer(anInteger) -> character array
+        create_unicode_buffer(aString, anInteger) -> character array
+        """
+        if isinstance(init, (str, unicode)):
+            if size is None:
+                size = len(init)+1
+            buftype = c_wchar * size
+            buf = buftype()
+            buf.value = init
+            return buf
+        elif isinstance(init, (int, long)):
+            buftype = c_wchar * init
+            buf = buftype()
+            return buf
+        raise TypeError, init
+
+POINTER(c_char).from_param = c_char_p.from_param #_SimpleCData.c_char_p_from_param
+
+# XXX Deprecated
+def SetPointerType(pointer, cls):
+    if _pointer_type_cache.get(cls, None) is not None:
+        raise RuntimeError, \
+              "This type already exists in the cache"
+    if not _pointer_type_cache.has_key(id(pointer)):
+        raise RuntimeError, \
+              "What's this???"
+    pointer.set_type(cls)
+    _pointer_type_cache[cls] = pointer
+    del _pointer_type_cache[id(pointer)]
+
+
+def pointer(inst):
+    return POINTER(type(inst))(inst)
+
+# XXX Deprecated
+def ARRAY(typ, len):
+    return typ * len
+
+################################################################
+
+
+class CDLL(object):
+    """An instance of this class represents a loaded dll/shared
+    library, exporting functions using the standard C calling
+    convention (named 'cdecl' on Windows).
+
+    The exported functions can be accessed as attributes, or by
+    indexing with the function name.  Examples:
+
+    <obj>.qsort -> callable object
+    <obj>['qsort'] -> callable object
+
+    Calling the functions releases the Python GIL during the call and
+    reaquires it afterwards.
+    """
+    class _FuncPtr(_CFuncPtr):
+        _flags_ = _FUNCFLAG_CDECL
+        _restype_ = c_int # default, can be overridden in instances
+
+    def __init__(self, name, mode=DEFAULT_MODE, handle=None):
+        self._name = name
+        if handle is None:
+            self._handle = _dlopen(self._name, mode)
+        else:
+            self._handle = handle
+
+    def __repr__(self):
+        return "<%s '%s', handle %x at %x>" % \
+               (self.__class__.__name__, self._name,
+                (self._handle & (_sys.maxint*2 + 1)),
+                id(self) & (_sys.maxint*2 + 1))
+
+    def __getattr__(self, name):
+        if name.startswith('__') and name.endswith('__'):
+            raise AttributeError, name
+        func = self.__getitem__(name)
+        setattr(self, name, func)
+        return func
+
+    def __getitem__(self, name_or_ordinal):
+        func = self._FuncPtr((name_or_ordinal, self))
+        if not isinstance(name_or_ordinal, (int, long)):
+            func.__name__ = name_or_ordinal
+        return func
+
+class PyDLL(CDLL):
+    """This class represents the Python library itself.  It allows to
+    access Python API functions.  The GIL is not released, and
+    Python exceptions are handled correctly.
+    """
+    class _FuncPtr(_CFuncPtr):
+        _flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI
+        _restype_ = c_int # default, can be overridden in instances
+
+if _os.name in ("nt", "ce"):
+
+    class WinDLL(CDLL):
+        """This class represents a dll exporting functions using the
+        Windows stdcall calling convention.
+        """
+        class _FuncPtr(_CFuncPtr):
+            _flags_ = _FUNCFLAG_STDCALL
+            _restype_ = c_int # default, can be overridden in instances
+
+    # XXX Hm, what about HRESULT as normal parameter?
+    # Mustn't it derive from c_long then?
+    from _ctypes import _check_HRESULT, _SimpleCData
+    class HRESULT(_SimpleCData):
+        _type_ = "l"
+        # _check_retval_ is called with the function's result when it
+        # is used as restype.  It checks for the FAILED bit, and
+        # raises a WindowsError if it is set.
+        #
+        # The _check_retval_ method is implemented in C, so that the
+        # method definition itself is not included in the traceback
+        # when it raises an error - that is what we want (and Python
+        # doesn't have a way to raise an exception in the caller's
+        # frame).
+        _check_retval_ = _check_HRESULT
+
+    class OleDLL(CDLL):
+        """This class represents a dll exporting functions using the
+        Windows stdcall calling convention, and returning HRESULT.
+        HRESULT error values are automatically raised as WindowsError
+        exceptions.
+        """
+        class _FuncPtr(_CFuncPtr):
+            _flags_ = _FUNCFLAG_STDCALL
+            _restype_ = HRESULT
+
+class LibraryLoader(object):
+    def __init__(self, dlltype):
+        self._dlltype = dlltype
+
+    def __getattr__(self, name):
+        if name[0] == '_':
+            raise AttributeError(name)
+        dll = self._dlltype(name)
+        setattr(self, name, dll)
+        return dll
+
+    def __getitem__(self, name):
+        return getattr(self, name)
+
+    def LoadLibrary(self, name):
+        return self._dlltype(name)
+
+cdll = LibraryLoader(CDLL)
+pydll = LibraryLoader(PyDLL)
+
+if _os.name in ("nt", "ce"):
+    pythonapi = PyDLL("python dll", None, _sys.dllhandle)
+elif _sys.platform == "cygwin":
+    pythonapi = PyDLL("libpython%d.%d.dll" % _sys.version_info[:2])
+else:
+    pythonapi = PyDLL(None)
+
+
+if _os.name in ("nt", "ce"):
+    windll = LibraryLoader(WinDLL)
+    oledll = LibraryLoader(OleDLL)
+
+    if _os.name == "nt":
+        GetLastError = windll.kernel32.GetLastError
+    else:
+        GetLastError = windll.coredll.GetLastError
+
+    def WinError(code=None, descr=None):
+        if code is None:
+            code = GetLastError()
+        if descr is None:
+            descr = FormatError(code).strip()
+        return WindowsError(code, descr)
+
+_pointer_type_cache[None] = c_void_p
+
+if sizeof(c_uint) == sizeof(c_void_p):
+    c_size_t = c_uint
+elif sizeof(c_ulong) == sizeof(c_void_p):
+    c_size_t = c_ulong
+
+# functions
+
+from _ctypes import _memmove_addr, _memset_addr, _string_at_addr, _cast_addr
+
+## void *memmove(void *, const void *, size_t);
+memmove = CFUNCTYPE(c_void_p, c_void_p, c_void_p, c_size_t)(_memmove_addr)
+
+## void *memset(void *, int, size_t)
+memset = CFUNCTYPE(c_void_p, c_void_p, c_int, c_size_t)(_memset_addr)
+
+def PYFUNCTYPE(restype, *argtypes):
+    class CFunctionType(_CFuncPtr):
+        _argtypes_ = argtypes
+        _restype_ = restype
+        _flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI
+    return CFunctionType
+
+_cast = PYFUNCTYPE(py_object, c_void_p, py_object, py_object)(_cast_addr)
+def cast(obj, typ):
+    return _cast(obj, obj, typ)
+
+_string_at = CFUNCTYPE(py_object, c_void_p, c_int)(_string_at_addr)
+def string_at(ptr, size=-1):
+    """string_at(addr[, size]) -> string
+
+    Return the string at addr."""
+    return _string_at(ptr, size)
+
+try:
+    from _ctypes import _wstring_at_addr
+except ImportError:
+    pass
+else:
+    _wstring_at = CFUNCTYPE(py_object, c_void_p, c_int)(_wstring_at_addr)
+    def wstring_at(ptr, size=-1):
+        """wstring_at(addr[, size]) -> string
+
+        Return the string at addr."""
+        return _wstring_at(ptr, size)
+
+
+if _os.name in ("nt", "ce"): # COM stuff
+    def DllGetClassObject(rclsid, riid, ppv):
+        try:
+            ccom = __import__("comtypes.server.inprocserver", globals(), locals(), ['*'])
+        except ImportError:
+            return -2147221231 # CLASS_E_CLASSNOTAVAILABLE
+        else:
+            return ccom.DllGetClassObject(rclsid, riid, ppv)
+
+    def DllCanUnloadNow():
+        try:
+            ccom = __import__("comtypes.server.inprocserver", globals(), locals(), ['*'])
+        except ImportError:
+            return 0 # S_OK
+        return ccom.DllCanUnloadNow()
+
+from ctypes._endian import BigEndianStructure, LittleEndianStructure
+
+# Fill in specifically-sized types
+c_int8 = c_byte
+c_uint8 = c_ubyte
+for kind in [c_short, c_int, c_long, c_longlong]:
+    if sizeof(kind) == 2: c_int16 = kind
+    elif sizeof(kind) == 4: c_int32 = kind
+    elif sizeof(kind) == 8: c_int64 = kind
+for kind in [c_ushort, c_uint, c_ulong, c_ulonglong]:
+    if sizeof(kind) == 2: c_uint16 = kind
+    elif sizeof(kind) == 4: c_uint32 = kind
+    elif sizeof(kind) == 8: c_uint64 = kind
+del(kind)

Added: vendor/Python/current/Lib/ctypes/_endian.py
===================================================================
--- vendor/Python/current/Lib/ctypes/_endian.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/_endian.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,60 @@
+######################################################################
+#  This file should be kept compatible with Python 2.3, see PEP 291. #
+######################################################################
+import sys
+from ctypes import *
+
+_array_type = type(c_int * 3)
+
+def _other_endian(typ):
+    """Return the type with the 'other' byte order.  Simple types like
+    c_int and so on already have __ctype_be__ and __ctype_le__
+    attributes which contain the types, for more complicated types
+    only arrays are supported.
+    """
+    try:
+        return getattr(typ, _OTHER_ENDIAN)
+    except AttributeError:
+        if type(typ) == _array_type:
+            return _other_endian(typ._type_) * typ._length_
+        raise TypeError("This type does not support other endian: %s" % typ)
+
+class _swapped_meta(type(Structure)):
+    def __setattr__(self, attrname, value):
+        if attrname == "_fields_":
+            fields = []
+            for desc in value:
+                name = desc[0]
+                typ = desc[1]
+                rest = desc[2:]
+                fields.append((name, _other_endian(typ)) + rest)
+            value = fields
+        super(_swapped_meta, self).__setattr__(attrname, value)
+
+################################################################
+
+# Note: The Structure metaclass checks for the *presence* (not the
+# value!) of a _swapped_bytes_ attribute to determine the bit order in
+# structures containing bit fields.
+
+if sys.byteorder == "little":
+    _OTHER_ENDIAN = "__ctype_be__"
+
+    LittleEndianStructure = Structure
+
+    class BigEndianStructure(Structure):
+        """Structure with big endian byte order"""
+        __metaclass__ = _swapped_meta
+        _swappedbytes_ = None
+
+elif sys.byteorder == "big":
+    _OTHER_ENDIAN = "__ctype_le__"
+
+    BigEndianStructure = Structure
+    class LittleEndianStructure(Structure):
+        """Structure with little endian byte order"""
+        __metaclass__ = _swapped_meta
+        _swappedbytes_ = None
+
+else:
+    raise RuntimeError("Invalid byteorder")

Added: vendor/Python/current/Lib/ctypes/macholib/README.ctypes
===================================================================
--- vendor/Python/current/Lib/ctypes/macholib/README.ctypes	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/macholib/README.ctypes	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,7 @@
+Files in this directory from from Bob Ippolito's py2app.
+
+License: Any components of the py2app suite may be distributed under
+the MIT or PSF open source licenses.
+
+This is version 1.0, SVN revision 789, from 2006/01/25.
+The main repository is http://svn.red-bean.com/bob/macholib/trunk/macholib/
\ No newline at end of file

Added: vendor/Python/current/Lib/ctypes/macholib/__init__.py
===================================================================
--- vendor/Python/current/Lib/ctypes/macholib/__init__.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/macholib/__init__.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,12 @@
+######################################################################
+#  This file should be kept compatible with Python 2.3, see PEP 291. #
+######################################################################
+"""
+Enough Mach-O to make your head spin.
+
+See the relevant header files in /usr/include/mach-o
+
+And also Apple's documentation.
+"""
+
+__version__ = '1.0'

Added: vendor/Python/current/Lib/ctypes/macholib/dyld.py
===================================================================
--- vendor/Python/current/Lib/ctypes/macholib/dyld.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/macholib/dyld.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,169 @@
+######################################################################
+#  This file should be kept compatible with Python 2.3, see PEP 291. #
+######################################################################
+"""
+dyld emulation
+"""
+
+import os
+from framework import framework_info
+from dylib import dylib_info
+from itertools import *
+
+__all__ = [
+    'dyld_find', 'framework_find',
+    'framework_info', 'dylib_info',
+]
+
+# These are the defaults as per man dyld(1)
+#
+DEFAULT_FRAMEWORK_FALLBACK = [
+    os.path.expanduser("~/Library/Frameworks"),
+    "/Library/Frameworks",
+    "/Network/Library/Frameworks",
+    "/System/Library/Frameworks",
+]
+
+DEFAULT_LIBRARY_FALLBACK = [
+    os.path.expanduser("~/lib"),
+    "/usr/local/lib",
+    "/lib",
+    "/usr/lib",
+]
+
+def ensure_utf8(s):
+    """Not all of PyObjC and Python understand unicode paths very well yet"""
+    if isinstance(s, unicode):
+        return s.encode('utf8')
+    return s
+
+def dyld_env(env, var):
+    if env is None:
+        env = os.environ
+    rval = env.get(var)
+    if rval is None:
+        return []
+    return rval.split(':')
+
+def dyld_image_suffix(env=None):
+    if env is None:
+        env = os.environ
+    return env.get('DYLD_IMAGE_SUFFIX')
+
+def dyld_framework_path(env=None):
+    return dyld_env(env, 'DYLD_FRAMEWORK_PATH')
+
+def dyld_library_path(env=None):
+    return dyld_env(env, 'DYLD_LIBRARY_PATH')
+
+def dyld_fallback_framework_path(env=None):
+    return dyld_env(env, 'DYLD_FALLBACK_FRAMEWORK_PATH')
+
+def dyld_fallback_library_path(env=None):
+    return dyld_env(env, 'DYLD_FALLBACK_LIBRARY_PATH')
+
+def dyld_image_suffix_search(iterator, env=None):
+    """For a potential path iterator, add DYLD_IMAGE_SUFFIX semantics"""
+    suffix = dyld_image_suffix(env)
+    if suffix is None:
+        return iterator
+    def _inject(iterator=iterator, suffix=suffix):
+        for path in iterator:
+            if path.endswith('.dylib'):
+                yield path[:-len('.dylib')] + suffix + '.dylib'
+            else:
+                yield path + suffix
+            yield path
+    return _inject()
+
+def dyld_override_search(name, env=None):
+    # If DYLD_FRAMEWORK_PATH is set and this dylib_name is a
+    # framework name, use the first file that exists in the framework
+    # path if any.  If there is none go on to search the DYLD_LIBRARY_PATH
+    # if any.
+
+    framework = framework_info(name)
+
+    if framework is not None:
+        for path in dyld_framework_path(env):
+            yield os.path.join(path, framework['name'])
+
+    # If DYLD_LIBRARY_PATH is set then use the first file that exists
+    # in the path.  If none use the original name.
+    for path in dyld_library_path(env):
+        yield os.path.join(path, os.path.basename(name))
+
+def dyld_executable_path_search(name, executable_path=None):
+    # If we haven't done any searching and found a library and the
+    # dylib_name starts with "@executable_path/" then construct the
+    # library name.
+    if name.startswith('@executable_path/') and executable_path is not None:
+        yield os.path.join(executable_path, name[len('@executable_path/'):])
+
+def dyld_default_search(name, env=None):
+    yield name
+
+    framework = framework_info(name)
+
+    if framework is not None:
+        fallback_framework_path = dyld_fallback_framework_path(env)
+        for path in fallback_framework_path:
+            yield os.path.join(path, framework['name'])
+
+    fallback_library_path = dyld_fallback_library_path(env)
+    for path in fallback_library_path:
+        yield os.path.join(path, os.path.basename(name))
+
+    if framework is not None and not fallback_framework_path:
+        for path in DEFAULT_FRAMEWORK_FALLBACK:
+            yield os.path.join(path, framework['name'])
+
+    if not fallback_library_path:
+        for path in DEFAULT_LIBRARY_FALLBACK:
+            yield os.path.join(path, os.path.basename(name))
+
+def dyld_find(name, executable_path=None, env=None):
+    """
+    Find a library or framework using dyld semantics
+    """
+    name = ensure_utf8(name)
+    executable_path = ensure_utf8(executable_path)
+    for path in dyld_image_suffix_search(chain(
+                dyld_override_search(name, env),
+                dyld_executable_path_search(name, executable_path),
+                dyld_default_search(name, env),
+            ), env):
+        if os.path.isfile(path):
+            return path
+    raise ValueError, "dylib %s could not be found" % (name,)
+
+def framework_find(fn, executable_path=None, env=None):
+    """
+    Find a framework using dyld semantics in a very loose manner.
+
+    Will take input such as:
+        Python
+        Python.framework
+        Python.framework/Versions/Current
+    """
+    try:
+        return dyld_find(fn, executable_path=executable_path, env=env)
+    except ValueError, e:
+        pass
+    fmwk_index = fn.rfind('.framework')
+    if fmwk_index == -1:
+        fmwk_index = len(fn)
+        fn += '.framework'
+    fn = os.path.join(fn, os.path.basename(fn[:fmwk_index]))
+    try:
+        return dyld_find(fn, executable_path=executable_path, env=env)
+    except ValueError:
+        raise e
+
+def test_dyld_find():
+    env = {}
+    assert dyld_find('libSystem.dylib') == '/usr/lib/libSystem.dylib'
+    assert dyld_find('System.framework/System') == '/System/Library/Frameworks/System.framework/System'
+
+if __name__ == '__main__':
+    test_dyld_find()

Added: vendor/Python/current/Lib/ctypes/macholib/dylib.py
===================================================================
--- vendor/Python/current/Lib/ctypes/macholib/dylib.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/macholib/dylib.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,66 @@
+######################################################################
+#  This file should be kept compatible with Python 2.3, see PEP 291. #
+######################################################################
+"""
+Generic dylib path manipulation
+"""
+
+import re
+
+__all__ = ['dylib_info']
+
+DYLIB_RE = re.compile(r"""(?x)
+(?P<location>^.*)(?:^|/)
+(?P<name>
+    (?P<shortname>\w+?)
+    (?:\.(?P<version>[^._]+))?
+    (?:_(?P<suffix>[^._]+))?
+    \.dylib$
+)
+""")
+
+def dylib_info(filename):
+    """
+    A dylib name can take one of the following four forms:
+        Location/Name.SomeVersion_Suffix.dylib
+        Location/Name.SomeVersion.dylib
+        Location/Name_Suffix.dylib
+        Location/Name.dylib
+
+    returns None if not found or a mapping equivalent to:
+        dict(
+            location='Location',
+            name='Name.SomeVersion_Suffix.dylib',
+            shortname='Name',
+            version='SomeVersion',
+            suffix='Suffix',
+        )
+
+    Note that SomeVersion and Suffix are optional and may be None
+    if not present.
+    """
+    is_dylib = DYLIB_RE.match(filename)
+    if not is_dylib:
+        return None
+    return is_dylib.groupdict()
+
+
+def test_dylib_info():
+    def d(location=None, name=None, shortname=None, version=None, suffix=None):
+        return dict(
+            location=location,
+            name=name,
+            shortname=shortname,
+            version=version,
+            suffix=suffix
+        )
+    assert dylib_info('completely/invalid') is None
+    assert dylib_info('completely/invalide_debug') is None
+    assert dylib_info('P/Foo.dylib') == d('P', 'Foo.dylib', 'Foo')
+    assert dylib_info('P/Foo_debug.dylib') == d('P', 'Foo_debug.dylib', 'Foo', suffix='debug')
+    assert dylib_info('P/Foo.A.dylib') == d('P', 'Foo.A.dylib', 'Foo', 'A')
+    assert dylib_info('P/Foo_debug.A.dylib') == d('P', 'Foo_debug.A.dylib', 'Foo_debug', 'A')
+    assert dylib_info('P/Foo.A_debug.dylib') == d('P', 'Foo.A_debug.dylib', 'Foo', 'A', 'debug')
+
+if __name__ == '__main__':
+    test_dylib_info()

Added: vendor/Python/current/Lib/ctypes/macholib/fetch_macholib
===================================================================
--- vendor/Python/current/Lib/ctypes/macholib/fetch_macholib	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/macholib/fetch_macholib	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2 @@
+#!/bin/sh
+svn export --force http://svn.red-bean.com/bob/macholib/trunk/macholib/ .


Property changes on: vendor/Python/current/Lib/ctypes/macholib/fetch_macholib
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/ctypes/macholib/fetch_macholib.bat
===================================================================
--- vendor/Python/current/Lib/ctypes/macholib/fetch_macholib.bat	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/macholib/fetch_macholib.bat	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1 @@
+svn export --force http://svn.red-bean.com/bob/macholib/trunk/macholib/ .

Added: vendor/Python/current/Lib/ctypes/macholib/framework.py
===================================================================
--- vendor/Python/current/Lib/ctypes/macholib/framework.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/macholib/framework.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,68 @@
+######################################################################
+#  This file should be kept compatible with Python 2.3, see PEP 291. #
+######################################################################
+"""
+Generic framework path manipulation
+"""
+
+import re
+
+__all__ = ['framework_info']
+
+STRICT_FRAMEWORK_RE = re.compile(r"""(?x)
+(?P<location>^.*)(?:^|/)
+(?P<name>
+    (?P<shortname>\w+).framework/
+    (?:Versions/(?P<version>[^/]+)/)?
+    (?P=shortname)
+    (?:_(?P<suffix>[^_]+))?
+)$
+""")
+
+def framework_info(filename):
+    """
+    A framework name can take one of the following four forms:
+        Location/Name.framework/Versions/SomeVersion/Name_Suffix
+        Location/Name.framework/Versions/SomeVersion/Name
+        Location/Name.framework/Name_Suffix
+        Location/Name.framework/Name
+
+    returns None if not found, or a mapping equivalent to:
+        dict(
+            location='Location',
+            name='Name.framework/Versions/SomeVersion/Name_Suffix',
+            shortname='Name',
+            version='SomeVersion',
+            suffix='Suffix',
+        )
+
+    Note that SomeVersion and Suffix are optional and may be None
+    if not present
+    """
+    is_framework = STRICT_FRAMEWORK_RE.match(filename)
+    if not is_framework:
+        return None
+    return is_framework.groupdict()
+
+def test_framework_info():
+    def d(location=None, name=None, shortname=None, version=None, suffix=None):
+        return dict(
+            location=location,
+            name=name,
+            shortname=shortname,
+            version=version,
+            suffix=suffix
+        )
+    assert framework_info('completely/invalid') is None
+    assert framework_info('completely/invalid/_debug') is None
+    assert framework_info('P/F.framework') is None
+    assert framework_info('P/F.framework/_debug') is None
+    assert framework_info('P/F.framework/F') == d('P', 'F.framework/F', 'F')
+    assert framework_info('P/F.framework/F_debug') == d('P', 'F.framework/F_debug', 'F', suffix='debug')
+    assert framework_info('P/F.framework/Versions') is None
+    assert framework_info('P/F.framework/Versions/A') is None
+    assert framework_info('P/F.framework/Versions/A/F') == d('P', 'F.framework/Versions/A/F', 'F', 'A')
+    assert framework_info('P/F.framework/Versions/A/F_debug') == d('P', 'F.framework/Versions/A/F_debug', 'F', 'A', 'debug')
+
+if __name__ == '__main__':
+    test_framework_info()

Added: vendor/Python/current/Lib/ctypes/test/__init__.py
===================================================================
--- vendor/Python/current/Lib/ctypes/test/__init__.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/test/__init__.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,202 @@
+import glob, os, sys, unittest, getopt, time
+
+use_resources = []
+
+class ResourceDenied(Exception):
+    """Test skipped because it requested a disallowed resource.
+
+    This is raised when a test calls requires() for a resource that
+    has not be enabled.  Resources are defined by test modules.
+    """
+
+def is_resource_enabled(resource):
+    """Test whether a resource is enabled.
+
+    If the caller's module is __main__ then automatically return True."""
+    if sys._getframe().f_back.f_globals.get("__name__") == "__main__":
+        return True
+    result = use_resources is not None and \
+           (resource in use_resources or "*" in use_resources)
+    if not result:
+        _unavail[resource] = None
+    return result
+
+_unavail = {}
+def requires(resource, msg=None):
+    """Raise ResourceDenied if the specified resource is not available.
+
+    If the caller's module is __main__ then automatically return True."""
+    # see if the caller's module is __main__ - if so, treat as if
+    # the resource was set
+    if sys._getframe().f_back.f_globals.get("__name__") == "__main__":
+        return
+    if not is_resource_enabled(resource):
+        if msg is None:
+            msg = "Use of the `%s' resource not enabled" % resource
+        raise ResourceDenied(msg)
+
+def find_package_modules(package, mask):
+    import fnmatch
+    if hasattr(package, "__loader__"):
+        path = package.__name__.replace(".", os.path.sep)
+        mask = os.path.join(path, mask)
+        for fnm in package.__loader__._files.iterkeys():
+            if fnmatch.fnmatchcase(fnm, mask):
+                yield os.path.splitext(fnm)[0].replace(os.path.sep, ".")
+    else:
+        path = package.__path__[0]
+        for fnm in os.listdir(path):
+            if fnmatch.fnmatchcase(fnm, mask):
+                yield "%s.%s" % (package.__name__, os.path.splitext(fnm)[0])
+
+def get_tests(package, mask, verbosity):
+    """Return a list of skipped test modules, and a list of test cases."""
+    tests = []
+    skipped = []
+    for modname in find_package_modules(package, mask):
+        try:
+            mod = __import__(modname, globals(), locals(), ['*'])
+        except ResourceDenied, detail:
+            skipped.append(modname)
+            if verbosity > 1:
+                print >> sys.stderr, "Skipped %s: %s" % (modname, detail)
+            continue
+        except Exception, detail:
+            print >> sys.stderr, "Warning: could not import %s: %s" % (modname, detail)
+            continue
+        for name in dir(mod):
+            if name.startswith("_"):
+                continue
+            o = getattr(mod, name)
+            if type(o) is type(unittest.TestCase) and issubclass(o, unittest.TestCase):
+                tests.append(o)
+    return skipped, tests
+
+def usage():
+    print __doc__
+    return 1
+
+def test_with_refcounts(runner, verbosity, testcase):
+    """Run testcase several times, tracking reference counts."""
+    import gc
+    import ctypes
+    ptc = ctypes._pointer_type_cache.copy()
+    cfc = ctypes._c_functype_cache.copy()
+    wfc = ctypes._win_functype_cache.copy()
+
+    # when searching for refcount leaks, we have to manually reset any
+    # caches that ctypes has.
+    def cleanup():
+        ctypes._pointer_type_cache = ptc.copy()
+        ctypes._c_functype_cache = cfc.copy()
+        ctypes._win_functype_cache = wfc.copy()
+        gc.collect()
+
+    test = unittest.makeSuite(testcase)
+    for i in range(5):
+        rc = sys.gettotalrefcount()
+        runner.run(test)
+        cleanup()
+    COUNT = 5
+    refcounts = [None] * COUNT
+    for i in range(COUNT):
+        rc = sys.gettotalrefcount()
+        runner.run(test)
+        cleanup()
+        refcounts[i] = sys.gettotalrefcount() - rc
+    if filter(None, refcounts):
+        print "%s leaks:\n\t" % testcase, refcounts
+    elif verbosity:
+        print "%s: ok." % testcase
+
+class TestRunner(unittest.TextTestRunner):
+    def run(self, test, skipped):
+        "Run the given test case or test suite."
+        # Same as unittest.TextTestRunner.run, except that it reports
+        # skipped tests.
+        result = self._makeResult()
+        startTime = time.time()
+        test(result)
+        stopTime = time.time()
+        timeTaken = stopTime - startTime
+        result.printErrors()
+        self.stream.writeln(result.separator2)
+        run = result.testsRun
+        if _unavail: #skipped:
+            requested = _unavail.keys()
+            requested.sort()
+            self.stream.writeln("Ran %d test%s in %.3fs (%s module%s skipped)" %
+                                (run, run != 1 and "s" or "", timeTaken,
+                                 len(skipped),
+                                 len(skipped) != 1 and "s" or ""))
+            self.stream.writeln("Unavailable resources: %s" % ", ".join(requested))
+        else:
+            self.stream.writeln("Ran %d test%s in %.3fs" %
+                                (run, run != 1 and "s" or "", timeTaken))
+        self.stream.writeln()
+        if not result.wasSuccessful():
+            self.stream.write("FAILED (")
+            failed, errored = map(len, (result.failures, result.errors))
+            if failed:
+                self.stream.write("failures=%d" % failed)
+            if errored:
+                if failed: self.stream.write(", ")
+                self.stream.write("errors=%d" % errored)
+            self.stream.writeln(")")
+        else:
+            self.stream.writeln("OK")
+        return result
+
+
+def main(*packages):
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], "rqvu:")
+    except getopt.error:
+        return usage()
+
+    verbosity = 1
+    search_leaks = False
+    for flag, value in opts:
+        if flag == "-q":
+            verbosity -= 1
+        elif flag == "-v":
+            verbosity += 1
+        elif flag == "-r":
+            try:
+                sys.gettotalrefcount
+            except AttributeError:
+                print >> sys.stderr, "-r flag requires Python debug build"
+                return -1
+            search_leaks = True
+        elif flag == "-u":
+            use_resources.extend(value.split(","))
+
+    mask = "test_*.py"
+    if args:
+        mask = args[0]
+
+    for package in packages:
+        run_tests(package, mask, verbosity, search_leaks)
+
+
+def run_tests(package, mask, verbosity, search_leaks):
+    skipped, testcases = get_tests(package, mask, verbosity)
+    runner = TestRunner(verbosity=verbosity)
+
+    suites = [unittest.makeSuite(o) for o in testcases]
+    suite = unittest.TestSuite(suites)
+    result = runner.run(suite, skipped)
+
+    if search_leaks:
+        # hunt for refcount leaks
+        runner = BasicTestRunner()
+        for t in testcases:
+            test_with_refcounts(runner, verbosity, t)
+
+    return bool(result.errors)
+
+class BasicTestRunner:
+    def run(self, test):
+        result = unittest.TestResult()
+        test(result)
+        return result

Added: vendor/Python/current/Lib/ctypes/test/runtests.py
===================================================================
--- vendor/Python/current/Lib/ctypes/test/runtests.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/test/runtests.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,17 @@
+"""Usage: runtests.py [-q] [-r] [-v] [-u resources] [mask]
+
+Run all tests found in this directory, and print a summary of the results.
+Command line flags:
+  -q     quiet mode: don't prnt anything while the tests are running
+  -r     run tests repeatedly, look for refcount leaks
+  -u<resources>
+         Add resources to the lits of allowed resources. '*' allows all
+         resources.
+  -v     verbose mode: print the test currently executed
+  mask   mask to select filenames containing testcases, wildcards allowed
+"""
+import sys
+import ctypes.test
+
+if __name__ == "__main__":
+    sys.exit(ctypes.test.main(ctypes.test))

Added: vendor/Python/current/Lib/ctypes/test/test_anon.py
===================================================================
--- vendor/Python/current/Lib/ctypes/test/test_anon.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/test/test_anon.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,60 @@
+import unittest
+from ctypes import *
+
+class AnonTest(unittest.TestCase):
+
+    def test_anon(self):
+        class ANON(Union):
+            _fields_ = [("a", c_int),
+                        ("b", c_int)]
+
+        class Y(Structure):
+            _fields_ = [("x", c_int),
+                        ("_", ANON),
+                        ("y", c_int)]
+            _anonymous_ = ["_"]
+
+        self.failUnlessEqual(Y.a.offset, sizeof(c_int))
+        self.failUnlessEqual(Y.b.offset, sizeof(c_int))
+
+        self.failUnlessEqual(ANON.a.offset, 0)
+        self.failUnlessEqual(ANON.b.offset, 0)
+
+    def test_anon_nonseq(self):
+        # TypeError: _anonymous_ must be a sequence
+        self.failUnlessRaises(TypeError,
+                              lambda: type(Structure)("Name",
+                                                      (Structure,),
+                                                      {"_fields_": [], "_anonymous_": 42}))
+
+    def test_anon_nonmember(self):
+        # AttributeError: type object 'Name' has no attribute 'x'
+        self.failUnlessRaises(AttributeError,
+                              lambda: type(Structure)("Name",
+                                                      (Structure,),
+                                                      {"_fields_": [],
+                                                       "_anonymous_": ["x"]}))
+
+    def test_nested(self):
+        class ANON_S(Structure):
+            _fields_ = [("a", c_int)]
+
+        class ANON_U(Union):
+            _fields_ = [("_", ANON_S),
+                        ("b", c_int)]
+            _anonymous_ = ["_"]
+
+        class Y(Structure):
+            _fields_ = [("x", c_int),
+                        ("_", ANON_U),
+                        ("y", c_int)]
+            _anonymous_ = ["_"]
+
+        self.failUnlessEqual(Y.x.offset, 0)
+        self.failUnlessEqual(Y.a.offset, sizeof(c_int))
+        self.failUnlessEqual(Y.b.offset, sizeof(c_int))
+        self.failUnlessEqual(Y._.offset, sizeof(c_int))
+        self.failUnlessEqual(Y.y.offset, sizeof(c_int) * 2)
+
+if __name__ == "__main__":
+    unittest.main()

Added: vendor/Python/current/Lib/ctypes/test/test_array_in_pointer.py
===================================================================
--- vendor/Python/current/Lib/ctypes/test/test_array_in_pointer.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/test/test_array_in_pointer.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,64 @@
+import unittest
+from ctypes import *
+from binascii import hexlify
+import re
+
+def dump(obj):
+    # helper function to dump memory contents in hex, with a hyphen
+    # between the bytes.
+    h = hexlify(buffer(obj))
+    return re.sub(r"(..)", r"\1-", h)[:-1]
+
+
+class Value(Structure):
+    _fields_ = [("val", c_byte)]
+
+class Container(Structure):
+    _fields_ = [("pvalues", POINTER(Value))]
+
+class Test(unittest.TestCase):
+    def test(self):
+        # create an array of 4 values
+        val_array = (Value * 4)()
+
+        # create a container, which holds a pointer to the pvalues array.
+        c = Container()
+        c.pvalues = val_array
+
+        # memory contains 4 NUL bytes now, that's correct
+        self.failUnlessEqual("00-00-00-00", dump(val_array))
+
+        # set the values of the array through the pointer:
+        for i in range(4):
+            c.pvalues[i].val = i + 1
+
+        values = [c.pvalues[i].val for i in range(4)]
+
+        # These are the expected results: here s the bug!
+        self.failUnlessEqual(
+            (values, dump(val_array)),
+            ([1, 2, 3, 4], "01-02-03-04")
+        )
+
+    def test_2(self):
+
+        val_array = (Value * 4)()
+
+        # memory contains 4 NUL bytes now, that's correct
+        self.failUnlessEqual("00-00-00-00", dump(val_array))
+
+        ptr = cast(val_array, POINTER(Value))
+        # set the values of the array through the pointer:
+        for i in range(4):
+            ptr[i].val = i + 1
+
+        values = [ptr[i].val for i in range(4)]
+
+        # These are the expected results: here s the bug!
+        self.failUnlessEqual(
+            (values, dump(val_array)),
+            ([1, 2, 3, 4], "01-02-03-04")
+        )
+
+if __name__ == "__main__":
+    unittest.main()

Added: vendor/Python/current/Lib/ctypes/test/test_arrays.py
===================================================================
--- vendor/Python/current/Lib/ctypes/test/test_arrays.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/test/test_arrays.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,112 @@
+import unittest
+from ctypes import *
+
+formats = "bBhHiIlLqQfd"
+
+formats = c_byte, c_ubyte, c_short, c_ushort, c_int, c_uint, \
+          c_long, c_ulonglong, c_float, c_double
+
+class ArrayTestCase(unittest.TestCase):
+    def test_simple(self):
+        # create classes holding simple numeric types, and check
+        # various properties.
+
+        init = range(15, 25)
+
+        for fmt in formats:
+            alen = len(init)
+            int_array = ARRAY(fmt, alen)
+
+            ia = int_array(*init)
+            # length of instance ok?
+            self.failUnlessEqual(len(ia), alen)
+
+            # slot values ok?
+            values = [ia[i] for i in range(len(init))]
+            self.failUnlessEqual(values, init)
+
+            # change the items
+            from operator import setitem
+            new_values = range(42, 42+alen)
+            [setitem(ia, n, new_values[n]) for n in range(alen)]
+            values = [ia[i] for i in range(len(init))]
+            self.failUnlessEqual(values, new_values)
+
+            # are the items initialized to 0?
+            ia = int_array()
+            values = [ia[i] for i in range(len(init))]
+            self.failUnlessEqual(values, [0] * len(init))
+
+            # Too many in itializers should be caught
+            self.assertRaises(IndexError, int_array, *range(alen*2))
+
+        CharArray = ARRAY(c_char, 3)
+
+        ca = CharArray("a", "b", "c")
+
+        # Should this work? It doesn't:
+        # CharArray("abc")
+        self.assertRaises(TypeError, CharArray, "abc")
+
+        self.failUnlessEqual(ca[0], "a")
+        self.failUnlessEqual(ca[1], "b")
+        self.failUnlessEqual(ca[2], "c")
+        self.failUnlessEqual(ca[-3], "a")
+        self.failUnlessEqual(ca[-2], "b")
+        self.failUnlessEqual(ca[-1], "c")
+
+        self.failUnlessEqual(len(ca), 3)
+
+        # slicing is now supported, but not extended slicing (3-argument)!
+        from operator import getslice, delitem
+        self.assertRaises(TypeError, getslice, ca, 0, 1, -1)
+
+        # cannot delete items
+        self.assertRaises(TypeError, delitem, ca, 0)
+
+    def test_numeric_arrays(self):
+
+        alen = 5
+
+        numarray = ARRAY(c_int, alen)
+
+        na = numarray()
+        values = [na[i] for i in range(alen)]
+        self.failUnlessEqual(values, [0] * alen)
+
+        na = numarray(*[c_int()] * alen)
+        values = [na[i] for i in range(alen)]
+        self.failUnlessEqual(values, [0]*alen)
+
+        na = numarray(1, 2, 3, 4, 5)
+        values = [i for i in na]
+        self.failUnlessEqual(values, [1, 2, 3, 4, 5])
+
+        na = numarray(*map(c_int, (1, 2, 3, 4, 5)))
+        values = [i for i in na]
+        self.failUnlessEqual(values, [1, 2, 3, 4, 5])
+
+    def test_classcache(self):
+        self.failUnless(not ARRAY(c_int, 3) is ARRAY(c_int, 4))
+        self.failUnless(ARRAY(c_int, 3) is ARRAY(c_int, 3))
+
+    def test_from_address(self):
+        # Failed with 0.9.8, reported by JUrner
+        p = create_string_buffer("foo")
+        sz = (c_char * 3).from_address(addressof(p))
+        self.failUnlessEqual(sz[:], "foo")
+        self.failUnlessEqual(sz.value, "foo")
+
+    try:
+        create_unicode_buffer
+    except NameError:
+        pass
+    else:
+        def test_from_addressW(self):
+            p = create_unicode_buffer("foo")
+            sz = (c_wchar * 3).from_address(addressof(p))
+            self.failUnlessEqual(sz[:], "foo")
+            self.failUnlessEqual(sz.value, "foo")
+
+if __name__ == '__main__':
+    unittest.main()

Added: vendor/Python/current/Lib/ctypes/test/test_as_parameter.py
===================================================================
--- vendor/Python/current/Lib/ctypes/test/test_as_parameter.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/test/test_as_parameter.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,215 @@
+import unittest
+from ctypes import *
+import _ctypes_test
+
+dll = CDLL(_ctypes_test.__file__)
+
+try:
+    CALLBACK_FUNCTYPE = WINFUNCTYPE
+except NameError:
+    # fake to enable this test on Linux
+    CALLBACK_FUNCTYPE = CFUNCTYPE
+
+class POINT(Structure):
+    _fields_ = [("x", c_int), ("y", c_int)]
+
+class BasicWrapTestCase(unittest.TestCase):
+    def wrap(self, param):
+        return param
+
+    def test_wchar_parm(self):
+        try:
+            c_wchar
+        except NameError:
+            return
+        f = dll._testfunc_i_bhilfd
+        f.argtypes = [c_byte, c_wchar, c_int, c_long, c_float, c_double]
+        result = f(self.wrap(1), self.wrap(u"x"), self.wrap(3), self.wrap(4), self.wrap(5.0), self.wrap(6.0))
+        self.failUnlessEqual(result, 139)
+        self.failUnless(type(result), int)
+
+    def test_pointers(self):
+        f = dll._testfunc_p_p
+        f.restype = POINTER(c_int)
+        f.argtypes = [POINTER(c_int)]
+
+        # This only works if the value c_int(42) passed to the
+        # function is still alive while the pointer (the result) is
+        # used.
+
+        v = c_int(42)
+
+        self.failUnlessEqual(pointer(v).contents.value, 42)
+        result = f(self.wrap(pointer(v)))
+        self.failUnlessEqual(type(result), POINTER(c_int))
+        self.failUnlessEqual(result.contents.value, 42)
+
+        # This on works...
+        result = f(self.wrap(pointer(v)))
+        self.failUnlessEqual(result.contents.value, v.value)
+
+        p = pointer(c_int(99))
+        result = f(self.wrap(p))
+        self.failUnlessEqual(result.contents.value, 99)
+
+    def test_shorts(self):
+        f = dll._testfunc_callback_i_if
+
+        args = []
+        expected = [262144, 131072, 65536, 32768, 16384, 8192, 4096, 2048,
+                    1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1]
+
+        def callback(v):
+            args.append(v)
+            return v
+
+        CallBack = CFUNCTYPE(c_int, c_int)
+
+        cb = CallBack(callback)
+        f(self.wrap(2**18), self.wrap(cb))
+        self.failUnlessEqual(args, expected)
+
+    ################################################################
+
+    def test_callbacks(self):
+        f = dll._testfunc_callback_i_if
+        f.restype = c_int
+
+        MyCallback = CFUNCTYPE(c_int, c_int)
+
+        def callback(value):
+            #print "called back with", value
+            return value
+
+        cb = MyCallback(callback)
+
+        result = f(self.wrap(-10), self.wrap(cb))
+        self.failUnlessEqual(result, -18)
+
+        # test with prototype
+        f.argtypes = [c_int, MyCallback]
+        cb = MyCallback(callback)
+
+        result = f(self.wrap(-10), self.wrap(cb))
+        self.failUnlessEqual(result, -18)
+
+        result = f(self.wrap(-10), self.wrap(cb))
+        self.failUnlessEqual(result, -18)
+
+        AnotherCallback = CALLBACK_FUNCTYPE(c_int, c_int, c_int, c_int, c_int)
+
+        # check that the prototype works: we call f with wrong
+        # argument types
+        cb = AnotherCallback(callback)
+        self.assertRaises(ArgumentError, f, self.wrap(-10), self.wrap(cb))
+
+    def test_callbacks_2(self):
+        # Can also use simple datatypes as argument type specifiers
+        # for the callback function.
+        # In this case the call receives an instance of that type
+        f = dll._testfunc_callback_i_if
+        f.restype = c_int
+
+        MyCallback = CFUNCTYPE(c_int, c_int)
+
+        f.argtypes = [c_int, MyCallback]
+
+        def callback(value):
+            #print "called back with", value
+            self.failUnlessEqual(type(value), int)
+            return value
+
+        cb = MyCallback(callback)
+        result = f(self.wrap(-10), self.wrap(cb))
+        self.failUnlessEqual(result, -18)
+
+    def test_longlong_callbacks(self):
+
+        f = dll._testfunc_callback_q_qf
+        f.restype = c_longlong
+
+        MyCallback = CFUNCTYPE(c_longlong, c_longlong)
+
+        f.argtypes = [c_longlong, MyCallback]
+
+        def callback(value):
+            self.failUnless(isinstance(value, (int, long)))
+            return value & 0x7FFFFFFF
+
+        cb = MyCallback(callback)
+
+        self.failUnlessEqual(13577625587, int(f(self.wrap(1000000000000), self.wrap(cb))))
+
+    def test_byval(self):
+        # without prototype
+        ptin = POINT(1, 2)
+        ptout = POINT()
+        # EXPORT int _testfunc_byval(point in, point *pout)
+        result = dll._testfunc_byval(ptin, byref(ptout))
+        got = result, ptout.x, ptout.y
+        expected = 3, 1, 2
+        self.failUnlessEqual(got, expected)
+
+        # with prototype
+        ptin = POINT(101, 102)
+        ptout = POINT()
+        dll._testfunc_byval.argtypes = (POINT, POINTER(POINT))
+        dll._testfunc_byval.restype = c_int
+        result = dll._testfunc_byval(self.wrap(ptin), byref(ptout))
+        got = result, ptout.x, ptout.y
+        expected = 203, 101, 102
+        self.failUnlessEqual(got, expected)
+
+    def test_struct_return_2H(self):
+        class S2H(Structure):
+            _fields_ = [("x", c_short),
+                        ("y", c_short)]
+        dll.ret_2h_func.restype = S2H
+        dll.ret_2h_func.argtypes = [S2H]
+        inp = S2H(99, 88)
+        s2h = dll.ret_2h_func(self.wrap(inp))
+        self.failUnlessEqual((s2h.x, s2h.y), (99*2, 88*3))
+
+    def test_struct_return_8H(self):
+        class S8I(Structure):
+            _fields_ = [("a", c_int),
+                        ("b", c_int),
+                        ("c", c_int),
+                        ("d", c_int),
+                        ("e", c_int),
+                        ("f", c_int),
+                        ("g", c_int),
+                        ("h", c_int)]
+        dll.ret_8i_func.restype = S8I
+        dll.ret_8i_func.argtypes = [S8I]
+        inp = S8I(9, 8, 7, 6, 5, 4, 3, 2)
+        s8i = dll.ret_8i_func(self.wrap(inp))
+        self.failUnlessEqual((s8i.a, s8i.b, s8i.c, s8i.d, s8i.e, s8i.f, s8i.g, s8i.h),
+                             (9*2, 8*3, 7*4, 6*5, 5*6, 4*7, 3*8, 2*9))
+
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class AsParamWrapper(object):
+    def __init__(self, param):
+        self._as_parameter_ = param
+
+class AsParamWrapperTestCase(BasicWrapTestCase):
+    wrap = AsParamWrapper
+
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class AsParamPropertyWrapper(object):
+    def __init__(self, param):
+        self._param = param
+
+    def getParameter(self):
+        return self._param
+    _as_parameter_ = property(getParameter)
+
+class AsParamPropertyWrapperTestCase(BasicWrapTestCase):
+    wrap = AsParamPropertyWrapper
+
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+if __name__ == '__main__':
+    unittest.main()

Added: vendor/Python/current/Lib/ctypes/test/test_bitfields.py
===================================================================
--- vendor/Python/current/Lib/ctypes/test/test_bitfields.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/test/test_bitfields.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,228 @@
+from ctypes import *
+import unittest
+import os
+
+import ctypes
+import _ctypes_test
+
+class BITS(Structure):
+    _fields_ = [("A", c_int, 1),
+                ("B", c_int, 2),
+                ("C", c_int, 3),
+                ("D", c_int, 4),
+                ("E", c_int, 5),
+                ("F", c_int, 6),
+                ("G", c_int, 7),
+                ("H", c_int, 8),
+                ("I", c_int, 9),
+
+                ("M", c_short, 1),
+                ("N", c_short, 2),
+                ("O", c_short, 3),
+                ("P", c_short, 4),
+                ("Q", c_short, 5),
+                ("R", c_short, 6),
+                ("S", c_short, 7)]
+
+func = CDLL(_ctypes_test.__file__).unpack_bitfields
+func.argtypes = POINTER(BITS), c_char
+
+##for n in "ABCDEFGHIMNOPQRS":
+##    print n, hex(getattr(BITS, n).size), getattr(BITS, n).offset
+
+class C_Test(unittest.TestCase):
+
+    def test_ints(self):
+        for i in range(512):
+            for name in "ABCDEFGHI":
+                b = BITS()
+                setattr(b, name, i)
+                self.failUnlessEqual((name, i, getattr(b, name)), (name, i, func(byref(b), name)))
+
+    def test_shorts(self):
+        for i in range(256):
+            for name in "MNOPQRS":
+                b = BITS()
+                setattr(b, name, i)
+                self.failUnlessEqual((name, i, getattr(b, name)), (name, i, func(byref(b), name)))
+
+signed_int_types = (c_byte, c_short, c_int, c_long, c_longlong)
+unsigned_int_types = (c_ubyte, c_ushort, c_uint, c_ulong, c_ulonglong)
+int_types = unsigned_int_types + signed_int_types
+
+class BitFieldTest(unittest.TestCase):
+
+    def test_longlong(self):
+        class X(Structure):
+            _fields_ = [("a", c_longlong, 1),
+                        ("b", c_longlong, 62),
+                        ("c", c_longlong, 1)]
+
+        self.failUnlessEqual(sizeof(X), sizeof(c_longlong))
+        x = X()
+        x.a, x.b, x.c = -1, 7, -1
+        self.failUnlessEqual((x.a, x.b, x.c), (-1, 7, -1))
+
+    def test_ulonglong(self):
+        class X(Structure):
+            _fields_ = [("a", c_ulonglong, 1),
+                        ("b", c_ulonglong, 62),
+                        ("c", c_ulonglong, 1)]
+
+        self.failUnlessEqual(sizeof(X), sizeof(c_longlong))
+        x = X()
+        self.failUnlessEqual((x.a, x.b, x.c), (0, 0, 0))
+        x.a, x.b, x.c = 7, 7, 7
+        self.failUnlessEqual((x.a, x.b, x.c), (1, 7, 1))
+
+    def test_signed(self):
+        for c_typ in signed_int_types:
+            class X(Structure):
+                _fields_ = [("dummy", c_typ),
+                            ("a", c_typ, 3),
+                            ("b", c_typ, 3),
+                            ("c", c_typ, 1)]
+            self.failUnlessEqual(sizeof(X), sizeof(c_typ)*2)
+
+            x = X()
+            self.failUnlessEqual((c_typ, x.a, x.b, x.c), (c_typ, 0, 0, 0))
+            x.a = -1
+            self.failUnlessEqual((c_typ, x.a, x.b, x.c), (c_typ, -1, 0, 0))
+            x.a, x.b = 0, -1
+            self.failUnlessEqual((c_typ, x.a, x.b, x.c), (c_typ, 0, -1, 0))
+
+
+    def test_unsigned(self):
+        for c_typ in unsigned_int_types:
+            class X(Structure):
+                _fields_ = [("a", c_typ, 3),
+                            ("b", c_typ, 3),
+                            ("c", c_typ, 1)]
+            self.failUnlessEqual(sizeof(X), sizeof(c_typ))
+
+            x = X()
+            self.failUnlessEqual((c_typ, x.a, x.b, x.c), (c_typ, 0, 0, 0))
+            x.a = -1
+            self.failUnlessEqual((c_typ, x.a, x.b, x.c), (c_typ, 7, 0, 0))
+            x.a, x.b = 0, -1
+            self.failUnlessEqual((c_typ, x.a, x.b, x.c), (c_typ, 0, 7, 0))
+
+
+    def fail_fields(self, *fields):
+        return self.get_except(type(Structure), "X", (),
+                               {"_fields_": fields})
+
+    def test_nonint_types(self):
+        # bit fields are not allowed on non-integer types.
+        result = self.fail_fields(("a", c_char_p, 1))
+        self.failUnlessEqual(result, (TypeError, 'bit fields not allowed for type c_char_p'))
+
+        result = self.fail_fields(("a", c_void_p, 1))
+        self.failUnlessEqual(result, (TypeError, 'bit fields not allowed for type c_void_p'))
+
+        if c_int != c_long:
+            result = self.fail_fields(("a", POINTER(c_int), 1))
+            self.failUnlessEqual(result, (TypeError, 'bit fields not allowed for type LP_c_int'))
+
+        result = self.fail_fields(("a", c_char, 1))
+        self.failUnlessEqual(result, (TypeError, 'bit fields not allowed for type c_char'))
+
+        try:
+            c_wchar
+        except NameError:
+            pass
+        else:
+            result = self.fail_fields(("a", c_wchar, 1))
+            self.failUnlessEqual(result, (TypeError, 'bit fields not allowed for type c_wchar'))
+
+        class Dummy(Structure):
+            _fields_ = []
+
+        result = self.fail_fields(("a", Dummy, 1))
+        self.failUnlessEqual(result, (TypeError, 'bit fields not allowed for type Dummy'))
+
+    def test_single_bitfield_size(self):
+        for c_typ in int_types:
+            result = self.fail_fields(("a", c_typ, -1))
+            self.failUnlessEqual(result, (ValueError, 'number of bits invalid for bit field'))
+
+            result = self.fail_fields(("a", c_typ, 0))
+            self.failUnlessEqual(result, (ValueError, 'number of bits invalid for bit field'))
+
+            class X(Structure):
+                _fields_ = [("a", c_typ, 1)]
+            self.failUnlessEqual(sizeof(X), sizeof(c_typ))
+
+            class X(Structure):
+                _fields_ = [("a", c_typ, sizeof(c_typ)*8)]
+            self.failUnlessEqual(sizeof(X), sizeof(c_typ))
+
+            result = self.fail_fields(("a", c_typ, sizeof(c_typ)*8 + 1))
+            self.failUnlessEqual(result, (ValueError, 'number of bits invalid for bit field'))
+
+    def test_multi_bitfields_size(self):
+        class X(Structure):
+            _fields_ = [("a", c_short, 1),
+                        ("b", c_short, 14),
+                        ("c", c_short, 1)]
+        self.failUnlessEqual(sizeof(X), sizeof(c_short))
+
+        class X(Structure):
+            _fields_ = [("a", c_short, 1),
+                        ("a1", c_short),
+                        ("b", c_short, 14),
+                        ("c", c_short, 1)]
+        self.failUnlessEqual(sizeof(X), sizeof(c_short)*3)
+        self.failUnlessEqual(X.a.offset, 0)
+        self.failUnlessEqual(X.a1.offset, sizeof(c_short))
+        self.failUnlessEqual(X.b.offset, sizeof(c_short)*2)
+        self.failUnlessEqual(X.c.offset, sizeof(c_short)*2)
+
+        class X(Structure):
+            _fields_ = [("a", c_short, 3),
+                        ("b", c_short, 14),
+                        ("c", c_short, 14)]
+        self.failUnlessEqual(sizeof(X), sizeof(c_short)*3)
+        self.failUnlessEqual(X.a.offset, sizeof(c_short)*0)
+        self.failUnlessEqual(X.b.offset, sizeof(c_short)*1)
+        self.failUnlessEqual(X.c.offset, sizeof(c_short)*2)
+
+
+    def get_except(self, func, *args, **kw):
+        try:
+            func(*args, **kw)
+        except Exception, detail:
+            return detail.__class__, str(detail)
+
+    def test_mixed_1(self):
+        class X(Structure):
+            _fields_ = [("a", c_byte, 4),
+                        ("b", c_int, 4)]
+        if os.name in ("nt", "ce"):
+            self.failUnlessEqual(sizeof(X), sizeof(c_int)*2)
+        else:
+            self.failUnlessEqual(sizeof(X), sizeof(c_int))
+
+    def test_mixed_2(self):
+        class X(Structure):
+            _fields_ = [("a", c_byte, 4),
+                        ("b", c_int, 32)]
+        self.failUnlessEqual(sizeof(X), sizeof(c_int)*2)
+
+    def test_mixed_3(self):
+        class X(Structure):
+            _fields_ = [("a", c_byte, 4),
+                        ("b", c_ubyte, 4)]
+        self.failUnlessEqual(sizeof(X), sizeof(c_byte))
+
+    def test_anon_bitfields(self):
+        # anonymous bit-fields gave a strange error message
+        class X(Structure):
+            _fields_ = [("a", c_byte, 4),
+                        ("b", c_ubyte, 4)]
+        class Y(Structure):
+            _anonymous_ = ["_"]
+            _fields_ = [("_", X)]
+
+if __name__ == "__main__":
+    unittest.main()

Added: vendor/Python/current/Lib/ctypes/test/test_buffers.py
===================================================================
--- vendor/Python/current/Lib/ctypes/test/test_buffers.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/test/test_buffers.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,54 @@
+from ctypes import *
+import unittest
+
+class StringBufferTestCase(unittest.TestCase):
+
+    def test_buffer(self):
+        b = create_string_buffer(32)
+        self.failUnlessEqual(len(b), 32)
+        self.failUnlessEqual(sizeof(b), 32 * sizeof(c_char))
+        self.failUnless(type(b[0]) is str)
+
+        b = create_string_buffer("abc")
+        self.failUnlessEqual(len(b), 4) # trailing nul char
+        self.failUnlessEqual(sizeof(b), 4 * sizeof(c_char))
+        self.failUnless(type(b[0]) is str)
+        self.failUnlessEqual(b[0], "a")
+        self.failUnlessEqual(b[:], "abc\0")
+
+    def test_string_conversion(self):
+        b = create_string_buffer(u"abc")
+        self.failUnlessEqual(len(b), 4) # trailing nul char
+        self.failUnlessEqual(sizeof(b), 4 * sizeof(c_char))
+        self.failUnless(type(b[0]) is str)
+        self.failUnlessEqual(b[0], "a")
+        self.failUnlessEqual(b[:], "abc\0")
+
+    try:
+        c_wchar
+    except NameError:
+        pass
+    else:
+        def test_unicode_buffer(self):
+            b = create_unicode_buffer(32)
+            self.failUnlessEqual(len(b), 32)
+            self.failUnlessEqual(sizeof(b), 32 * sizeof(c_wchar))
+            self.failUnless(type(b[0]) is unicode)
+
+            b = create_unicode_buffer(u"abc")
+            self.failUnlessEqual(len(b), 4) # trailing nul char
+            self.failUnlessEqual(sizeof(b), 4 * sizeof(c_wchar))
+            self.failUnless(type(b[0]) is unicode)
+            self.failUnlessEqual(b[0], u"a")
+            self.failUnlessEqual(b[:], "abc\0")
+
+        def test_unicode_conversion(self):
+            b = create_unicode_buffer("abc")
+            self.failUnlessEqual(len(b), 4) # trailing nul char
+            self.failUnlessEqual(sizeof(b), 4 * sizeof(c_wchar))
+            self.failUnless(type(b[0]) is unicode)
+            self.failUnlessEqual(b[0], u"a")
+            self.failUnlessEqual(b[:], "abc\0")
+
+if __name__ == "__main__":
+    unittest.main()

Added: vendor/Python/current/Lib/ctypes/test/test_byteswap.py
===================================================================
--- vendor/Python/current/Lib/ctypes/test/test_byteswap.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/test/test_byteswap.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,280 @@
+import sys, unittest, struct, math
+from binascii import hexlify
+
+from ctypes import *
+
+def bin(s):
+    return hexlify(buffer(s)).upper()
+
+# Each *simple* type that supports different byte orders has an
+# __ctype_be__ attribute that specifies the same type in BIG ENDIAN
+# byte order, and a __ctype_le__ attribute that is the same type in
+# LITTLE ENDIAN byte order.
+#
+# For Structures and Unions, these types are created on demand.
+
+class Test(unittest.TestCase):
+    def X_test(self):
+        print >> sys.stderr,  sys.byteorder
+        for i in range(32):
+            bits = BITS()
+            setattr(bits, "i%s" % i, 1)
+            dump(bits)
+
+    def test_endian_short(self):
+        if sys.byteorder == "little":
+            self.failUnless(c_short.__ctype_le__ is c_short)
+            self.failUnless(c_short.__ctype_be__.__ctype_le__ is c_short)
+        else:
+            self.failUnless(c_short.__ctype_be__ is c_short)
+            self.failUnless(c_short.__ctype_le__.__ctype_be__ is c_short)
+        s = c_short.__ctype_be__(0x1234)
+        self.failUnlessEqual(bin(struct.pack(">h", 0x1234)), "1234")
+        self.failUnlessEqual(bin(s), "1234")
+        self.failUnlessEqual(s.value, 0x1234)
+
+        s = c_short.__ctype_le__(0x1234)
+        self.failUnlessEqual(bin(struct.pack("<h", 0x1234)), "3412")
+        self.failUnlessEqual(bin(s), "3412")
+        self.failUnlessEqual(s.value, 0x1234)
+
+        s = c_ushort.__ctype_be__(0x1234)
+        self.failUnlessEqual(bin(struct.pack(">h", 0x1234)), "1234")
+        self.failUnlessEqual(bin(s), "1234")
+        self.failUnlessEqual(s.value, 0x1234)
+
+        s = c_ushort.__ctype_le__(0x1234)
+        self.failUnlessEqual(bin(struct.pack("<h", 0x1234)), "3412")
+        self.failUnlessEqual(bin(s), "3412")
+        self.failUnlessEqual(s.value, 0x1234)
+
+    def test_endian_int(self):
+        if sys.byteorder == "little":
+            self.failUnless(c_int.__ctype_le__ is c_int)
+            self.failUnless(c_int.__ctype_be__.__ctype_le__ is c_int)
+        else:
+            self.failUnless(c_int.__ctype_be__ is c_int)
+            self.failUnless(c_int.__ctype_le__.__ctype_be__ is c_int)
+
+        s = c_int.__ctype_be__(0x12345678)
+        self.failUnlessEqual(bin(struct.pack(">i", 0x12345678)), "12345678")
+        self.failUnlessEqual(bin(s), "12345678")
+        self.failUnlessEqual(s.value, 0x12345678)
+
+        s = c_int.__ctype_le__(0x12345678)
+        self.failUnlessEqual(bin(struct.pack("<i", 0x12345678)), "78563412")
+        self.failUnlessEqual(bin(s), "78563412")
+        self.failUnlessEqual(s.value, 0x12345678)
+
+        s = c_uint.__ctype_be__(0x12345678)
+        self.failUnlessEqual(bin(struct.pack(">I", 0x12345678)), "12345678")
+        self.failUnlessEqual(bin(s), "12345678")
+        self.failUnlessEqual(s.value, 0x12345678)
+
+        s = c_uint.__ctype_le__(0x12345678)
+        self.failUnlessEqual(bin(struct.pack("<I", 0x12345678)), "78563412")
+        self.failUnlessEqual(bin(s), "78563412")
+        self.failUnlessEqual(s.value, 0x12345678)
+
+    def test_endian_longlong(self):
+        if sys.byteorder == "little":
+            self.failUnless(c_longlong.__ctype_le__ is c_longlong)
+            self.failUnless(c_longlong.__ctype_be__.__ctype_le__ is c_longlong)
+        else:
+            self.failUnless(c_longlong.__ctype_be__ is c_longlong)
+            self.failUnless(c_longlong.__ctype_le__.__ctype_be__ is c_longlong)
+
+        s = c_longlong.__ctype_be__(0x1234567890ABCDEF)
+        self.failUnlessEqual(bin(struct.pack(">q", 0x1234567890ABCDEF)), "1234567890ABCDEF")
+        self.failUnlessEqual(bin(s), "1234567890ABCDEF")
+        self.failUnlessEqual(s.value, 0x1234567890ABCDEF)
+
+        s = c_longlong.__ctype_le__(0x1234567890ABCDEF)
+        self.failUnlessEqual(bin(struct.pack("<q", 0x1234567890ABCDEF)), "EFCDAB9078563412")
+        self.failUnlessEqual(bin(s), "EFCDAB9078563412")
+        self.failUnlessEqual(s.value, 0x1234567890ABCDEF)
+
+        s = c_ulonglong.__ctype_be__(0x1234567890ABCDEF)
+        self.failUnlessEqual(bin(struct.pack(">Q", 0x1234567890ABCDEF)), "1234567890ABCDEF")
+        self.failUnlessEqual(bin(s), "1234567890ABCDEF")
+        self.failUnlessEqual(s.value, 0x1234567890ABCDEF)
+
+        s = c_ulonglong.__ctype_le__(0x1234567890ABCDEF)
+        self.failUnlessEqual(bin(struct.pack("<Q", 0x1234567890ABCDEF)), "EFCDAB9078563412")
+        self.failUnlessEqual(bin(s), "EFCDAB9078563412")
+        self.failUnlessEqual(s.value, 0x1234567890ABCDEF)
+
+    def test_endian_float(self):
+        if sys.byteorder == "little":
+            self.failUnless(c_float.__ctype_le__ is c_float)
+            self.failUnless(c_float.__ctype_be__.__ctype_le__ is c_float)
+        else:
+            self.failUnless(c_float.__ctype_be__ is c_float)
+            self.failUnless(c_float.__ctype_le__.__ctype_be__ is c_float)
+        s = c_float(math.pi)
+        self.failUnlessEqual(bin(struct.pack("f", math.pi)), bin(s))
+        # Hm, what's the precision of a float compared to a double?
+        self.failUnlessAlmostEqual(s.value, math.pi, 6)
+        s = c_float.__ctype_le__(math.pi)
+        self.failUnlessAlmostEqual(s.value, math.pi, 6)
+        self.failUnlessEqual(bin(struct.pack("<f", math.pi)), bin(s))
+        s = c_float.__ctype_be__(math.pi)
+        self.failUnlessAlmostEqual(s.value, math.pi, 6)
+        self.failUnlessEqual(bin(struct.pack(">f", math.pi)), bin(s))
+
+    def test_endian_double(self):
+        if sys.byteorder == "little":
+            self.failUnless(c_double.__ctype_le__ is c_double)
+            self.failUnless(c_double.__ctype_be__.__ctype_le__ is c_double)
+        else:
+            self.failUnless(c_double.__ctype_be__ is c_double)
+            self.failUnless(c_double.__ctype_le__.__ctype_be__ is c_double)
+        s = c_double(math.pi)
+        self.failUnlessEqual(s.value, math.pi)
+        self.failUnlessEqual(bin(struct.pack("d", math.pi)), bin(s))
+        s = c_double.__ctype_le__(math.pi)
+        self.failUnlessEqual(s.value, math.pi)
+        self.failUnlessEqual(bin(struct.pack("<d", math.pi)), bin(s))
+        s = c_double.__ctype_be__(math.pi)
+        self.failUnlessEqual(s.value, math.pi)
+        self.failUnlessEqual(bin(struct.pack(">d", math.pi)), bin(s))
+
+    def test_endian_other(self):
+        self.failUnless(c_byte.__ctype_le__ is c_byte)
+        self.failUnless(c_byte.__ctype_be__ is c_byte)
+
+        self.failUnless(c_ubyte.__ctype_le__ is c_ubyte)
+        self.failUnless(c_ubyte.__ctype_be__ is c_ubyte)
+
+        self.failUnless(c_char.__ctype_le__ is c_char)
+        self.failUnless(c_char.__ctype_be__ is c_char)
+
+    def test_struct_fields_1(self):
+        if sys.byteorder == "little":
+            base = BigEndianStructure
+        else:
+            base = LittleEndianStructure
+
+        class T(base):
+            pass
+        _fields_ = [("a", c_ubyte),
+                    ("b", c_byte),
+                    ("c", c_short),
+                    ("d", c_ushort),
+                    ("e", c_int),
+                    ("f", c_uint),
+                    ("g", c_long),
+                    ("h", c_ulong),
+                    ("i", c_longlong),
+                    ("k", c_ulonglong),
+                    ("l", c_float),
+                    ("m", c_double),
+                    ("n", c_char),
+
+                    ("b1", c_byte, 3),
+                    ("b2", c_byte, 3),
+                    ("b3", c_byte, 2),
+                    ("a", c_int * 3 * 3 * 3)]
+        T._fields_ = _fields_
+
+        # these fields do not support different byte order:
+        for typ in c_wchar, c_void_p, POINTER(c_int):
+            _fields_.append(("x", typ))
+            class T(base):
+                pass
+            self.assertRaises(TypeError, setattr, T, "_fields_", [("x", typ)])
+
+    def test_struct_struct(self):
+        # Nested structures with different byte order not (yet) supported
+        if sys.byteorder == "little":
+            base = BigEndianStructure
+        else:
+            base = LittleEndianStructure
+
+        class T(Structure):
+            _fields_ = [("a", c_int),
+                        ("b", c_int)]
+        class S(base):
+            pass
+        self.assertRaises(TypeError, setattr, S, "_fields_", [("s", T)])
+
+    def test_struct_fields_2(self):
+        # standard packing in struct uses no alignment.
+        # So, we have to align using pad bytes.
+        #
+        # Unaligned accesses will crash Python (on those platforms that
+        # don't allow it, like sparc solaris).
+        if sys.byteorder == "little":
+            base = BigEndianStructure
+            fmt = ">bxhid"
+        else:
+            base = LittleEndianStructure
+            fmt = "<bxhid"
+
+        class S(base):
+            _fields_ = [("b", c_byte),
+                        ("h", c_short),
+                        ("i", c_int),
+                        ("d", c_double)]
+
+        s1 = S(0x12, 0x1234, 0x12345678, 3.14)
+        s2 = struct.pack(fmt, 0x12, 0x1234, 0x12345678, 3.14)
+        self.failUnlessEqual(bin(s1), bin(s2))
+
+    def test_unaligned_nonnative_struct_fields(self):
+        if sys.byteorder == "little":
+            base = BigEndianStructure
+            fmt = ">b h xi xd"
+        else:
+            base = LittleEndianStructure
+            fmt = "<b h xi xd"
+
+        class S(base):
+            _pack_ = 1
+            _fields_ = [("b", c_byte),
+
+                        ("h", c_short),
+
+                        ("_1", c_byte),
+                        ("i", c_int),
+
+                        ("_2", c_byte),
+                        ("d", c_double)]
+
+        s1 = S()
+        s1.b = 0x12
+        s1.h = 0x1234
+        s1.i = 0x12345678
+        s1.d = 3.14
+        s2 = struct.pack(fmt, 0x12, 0x1234, 0x12345678, 3.14)
+        self.failUnlessEqual(bin(s1), bin(s2))
+
+    def test_unaligned_native_struct_fields(self):
+        if sys.byteorder == "little":
+            fmt = "<b h xi xd"
+        else:
+            base = LittleEndianStructure
+            fmt = ">b h xi xd"
+
+        class S(Structure):
+            _pack_ = 1
+            _fields_ = [("b", c_byte),
+
+                        ("h", c_short),
+
+                        ("_1", c_byte),
+                        ("i", c_int),
+
+                        ("_2", c_byte),
+                        ("d", c_double)]
+
+        s1 = S()
+        s1.b = 0x12
+        s1.h = 0x1234
+        s1.i = 0x12345678
+        s1.d = 3.14
+        s2 = struct.pack(fmt, 0x12, 0x1234, 0x12345678, 3.14)
+        self.failUnlessEqual(bin(s1), bin(s2))
+
+if __name__ == "__main__":
+    unittest.main()

Added: vendor/Python/current/Lib/ctypes/test/test_callbacks.py
===================================================================
--- vendor/Python/current/Lib/ctypes/test/test_callbacks.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/test/test_callbacks.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,152 @@
+import unittest
+from ctypes import *
+import _ctypes_test
+
+class Callbacks(unittest.TestCase):
+    functype = CFUNCTYPE
+
+##    def tearDown(self):
+##        import gc
+##        gc.collect()
+
+    def callback(self, *args):
+        self.got_args = args
+        return args[-1]
+
+    def check_type(self, typ, arg):
+        PROTO = self.functype.im_func(typ, typ)
+        result = PROTO(self.callback)(arg)
+        if typ == c_float:
+            self.failUnlessAlmostEqual(result, arg, places=5)
+        else:
+            self.failUnlessEqual(self.got_args, (arg,))
+            self.failUnlessEqual(result, arg)
+
+        PROTO = self.functype.im_func(typ, c_byte, typ)
+        result = PROTO(self.callback)(-3, arg)
+        if typ == c_float:
+            self.failUnlessAlmostEqual(result, arg, places=5)
+        else:
+            self.failUnlessEqual(self.got_args, (-3, arg))
+            self.failUnlessEqual(result, arg)
+
+    ################
+
+    def test_byte(self):
+        self.check_type(c_byte, 42)
+        self.check_type(c_byte, -42)
+
+    def test_ubyte(self):
+        self.check_type(c_ubyte, 42)
+
+    def test_short(self):
+        self.check_type(c_short, 42)
+        self.check_type(c_short, -42)
+
+    def test_ushort(self):
+        self.check_type(c_ushort, 42)
+
+    def test_int(self):
+        self.check_type(c_int, 42)
+        self.check_type(c_int, -42)
+
+    def test_uint(self):
+        self.check_type(c_uint, 42)
+
+    def test_long(self):
+        self.check_type(c_long, 42)
+        self.check_type(c_long, -42)
+
+    def test_ulong(self):
+        self.check_type(c_ulong, 42)
+
+    def test_longlong(self):
+        self.check_type(c_longlong, 42)
+        self.check_type(c_longlong, -42)
+
+    def test_ulonglong(self):
+        self.check_type(c_ulonglong, 42)
+
+    def test_float(self):
+        # only almost equal: double -> float -> double
+        import math
+        self.check_type(c_float, math.e)
+        self.check_type(c_float, -math.e)
+
+    def test_double(self):
+        self.check_type(c_double, 3.14)
+        self.check_type(c_double, -3.14)
+
+    def test_char(self):
+        self.check_type(c_char, "x")
+        self.check_type(c_char, "a")
+
+    # disabled: would now (correctly) raise a RuntimeWarning about
+    # a memory leak.  A callback function cannot return a non-integral
+    # C type without causing a memory leak.
+##    def test_char_p(self):
+##        self.check_type(c_char_p, "abc")
+##        self.check_type(c_char_p, "def")
+
+    def test_pyobject(self):
+        o = ()
+        from sys import getrefcount as grc
+        for o in (), [], object():
+            initial = grc(o)
+            # This call leaks a reference to 'o'...
+            self.check_type(py_object, o)
+            before = grc(o)
+            # ...but this call doesn't leak any more.  Where is the refcount?
+            self.check_type(py_object, o)
+            after = grc(o)
+            self.failUnlessEqual((after, o), (before, o))
+
+    def test_unsupported_restype_1(self):
+        # Only "fundamental" result types are supported for callback
+        # functions, the type must have a non-NULL stgdict->setfunc.
+        # POINTER(c_double), for example, is not supported.
+
+        prototype = self.functype.im_func(POINTER(c_double))
+        # The type is checked when the prototype is called
+        self.assertRaises(TypeError, prototype, lambda: None)
+
+    def test_unsupported_restype_2(self):
+        prototype = self.functype.im_func(object)
+        self.assertRaises(TypeError, prototype, lambda: None)
+
+try:
+    WINFUNCTYPE
+except NameError:
+    pass
+else:
+    class StdcallCallbacks(Callbacks):
+        functype = WINFUNCTYPE
+
+################################################################
+
+class SampleCallbacksTestCase(unittest.TestCase):
+
+    def test_integrate(self):
+        # Derived from some then non-working code, posted by David Foster
+        dll = CDLL(_ctypes_test.__file__)
+
+        # The function prototype called by 'integrate': double func(double);
+        CALLBACK = CFUNCTYPE(c_double, c_double)
+
+        # The integrate function itself, exposed from the _ctypes_test dll
+        integrate = dll.integrate
+        integrate.argtypes = (c_double, c_double, CALLBACK, c_long)
+        integrate.restype = c_double
+
+        def func(x):
+            return x**2
+
+        result = integrate(0.0, 1.0, CALLBACK(func), 10)
+        diff = abs(result - 1./3.)
+
+        self.failUnless(diff < 0.01, "%s not less than 0.01" % diff)
+
+################################################################
+
+if __name__ == '__main__':
+    unittest.main()

Added: vendor/Python/current/Lib/ctypes/test/test_cast.py
===================================================================
--- vendor/Python/current/Lib/ctypes/test/test_cast.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/test/test_cast.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,77 @@
+from ctypes import *
+import unittest
+import sys
+
+class Test(unittest.TestCase):
+
+    def test_array2pointer(self):
+        array = (c_int * 3)(42, 17, 2)
+
+        # casting an array to a pointer works.
+        ptr = cast(array, POINTER(c_int))
+        self.failUnlessEqual([ptr[i] for i in range(3)], [42, 17, 2])
+
+        if 2*sizeof(c_short) == sizeof(c_int):
+            ptr = cast(array, POINTER(c_short))
+            if sys.byteorder == "little":
+                self.failUnlessEqual([ptr[i] for i in range(6)],
+                                     [42, 0, 17, 0, 2, 0])
+            else:
+                self.failUnlessEqual([ptr[i] for i in range(6)],
+                                     [0, 42, 0, 17, 0, 2])
+
+    def test_address2pointer(self):
+        array = (c_int * 3)(42, 17, 2)
+
+        address = addressof(array)
+        ptr = cast(c_void_p(address), POINTER(c_int))
+        self.failUnlessEqual([ptr[i] for i in range(3)], [42, 17, 2])
+
+        ptr = cast(address, POINTER(c_int))
+        self.failUnlessEqual([ptr[i] for i in range(3)], [42, 17, 2])
+
+    def test_p2a_objects(self):
+        array = (c_char_p * 5)()
+        self.failUnlessEqual(array._objects, None)
+        array[0] = "foo bar"
+        self.failUnlessEqual(array._objects, {'0': "foo bar"})
+
+        p = cast(array, POINTER(c_char_p))
+        # array and p share a common _objects attribute
+        self.failUnless(p._objects is array._objects)
+        self.failUnlessEqual(array._objects, {'0': "foo bar", id(array): array})
+        p[0] = "spam spam"
+        self.failUnlessEqual(p._objects, {'0': "spam spam", id(array): array})
+        self.failUnless(array._objects is p._objects)
+        p[1] = "foo bar"
+        self.failUnlessEqual(p._objects, {'1': 'foo bar', '0': "spam spam", id(array): array})
+        self.failUnless(array._objects is p._objects)
+
+    def test_other(self):
+        p = cast((c_int * 4)(1, 2, 3, 4), POINTER(c_int))
+        self.failUnlessEqual(p[:4], [1,2, 3, 4])
+        c_int()
+        self.failUnlessEqual(p[:4], [1, 2, 3, 4])
+        p[2] = 96
+        self.failUnlessEqual(p[:4], [1, 2, 96, 4])
+        c_int()
+        self.failUnlessEqual(p[:4], [1, 2, 96, 4])
+
+    def test_char_p(self):
+        # This didn't work: bad argument to internal function
+        s = c_char_p("hiho")
+        self.failUnlessEqual(cast(cast(s, c_void_p), c_char_p).value,
+                             "hiho")
+
+    try:
+        c_wchar_p
+    except NameError:
+        pass
+    else:
+        def test_wchar_p(self):
+            s = c_wchar_p("hiho")
+            self.failUnlessEqual(cast(cast(s, c_void_p), c_wchar_p).value,
+                                 "hiho")
+
+if __name__ == "__main__":
+    unittest.main()

Added: vendor/Python/current/Lib/ctypes/test/test_cfuncs.py
===================================================================
--- vendor/Python/current/Lib/ctypes/test/test_cfuncs.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/test/test_cfuncs.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,199 @@
+# A lot of failures in these tests on Mac OS X.
+# Byte order related?
+
+import unittest
+from ctypes import *
+
+import _ctypes_test
+
+class CFunctions(unittest.TestCase):
+    _dll = CDLL(_ctypes_test.__file__)
+
+    def S(self):
+        return c_longlong.in_dll(self._dll, "last_tf_arg_s").value
+    def U(self):
+        return c_ulonglong.in_dll(self._dll, "last_tf_arg_u").value
+
+    def test_byte(self):
+        self._dll.tf_b.restype = c_byte
+        self._dll.tf_b.argtypes = (c_byte,)
+        self.failUnlessEqual(self._dll.tf_b(-126), -42)
+        self.failUnlessEqual(self.S(), -126)
+
+    def test_byte_plus(self):
+        self._dll.tf_bb.restype = c_byte
+        self._dll.tf_bb.argtypes = (c_byte, c_byte)
+        self.failUnlessEqual(self._dll.tf_bb(0, -126), -42)
+        self.failUnlessEqual(self.S(), -126)
+
+    def test_ubyte(self):
+        self._dll.tf_B.restype = c_ubyte
+        self._dll.tf_B.argtypes = (c_ubyte,)
+        self.failUnlessEqual(self._dll.tf_B(255), 85)
+        self.failUnlessEqual(self.U(), 255)
+
+    def test_ubyte_plus(self):
+        self._dll.tf_bB.restype = c_ubyte
+        self._dll.tf_bB.argtypes = (c_byte, c_ubyte)
+        self.failUnlessEqual(self._dll.tf_bB(0, 255), 85)
+        self.failUnlessEqual(self.U(), 255)
+
+    def test_short(self):
+        self._dll.tf_h.restype = c_short
+        self._dll.tf_h.argtypes = (c_short,)
+        self.failUnlessEqual(self._dll.tf_h(-32766), -10922)
+        self.failUnlessEqual(self.S(), -32766)
+
+    def test_short_plus(self):
+        self._dll.tf_bh.restype = c_short
+        self._dll.tf_bh.argtypes = (c_byte, c_short)
+        self.failUnlessEqual(self._dll.tf_bh(0, -32766), -10922)
+        self.failUnlessEqual(self.S(), -32766)
+
+    def test_ushort(self):
+        self._dll.tf_H.restype = c_ushort
+        self._dll.tf_H.argtypes = (c_ushort,)
+        self.failUnlessEqual(self._dll.tf_H(65535), 21845)
+        self.failUnlessEqual(self.U(), 65535)
+
+    def test_ushort_plus(self):
+        self._dll.tf_bH.restype = c_ushort
+        self._dll.tf_bH.argtypes = (c_byte, c_ushort)
+        self.failUnlessEqual(self._dll.tf_bH(0, 65535), 21845)
+        self.failUnlessEqual(self.U(), 65535)
+
+    def test_int(self):
+        self._dll.tf_i.restype = c_int
+        self._dll.tf_i.argtypes = (c_int,)
+        self.failUnlessEqual(self._dll.tf_i(-2147483646), -715827882)
+        self.failUnlessEqual(self.S(), -2147483646)
+
+    def test_int_plus(self):
+        self._dll.tf_bi.restype = c_int
+        self._dll.tf_bi.argtypes = (c_byte, c_int)
+        self.failUnlessEqual(self._dll.tf_bi(0, -2147483646), -715827882)
+        self.failUnlessEqual(self.S(), -2147483646)
+
+    def test_uint(self):
+        self._dll.tf_I.restype = c_uint
+        self._dll.tf_I.argtypes = (c_uint,)
+        self.failUnlessEqual(self._dll.tf_I(4294967295), 1431655765)
+        self.failUnlessEqual(self.U(), 4294967295)
+
+    def test_uint_plus(self):
+        self._dll.tf_bI.restype = c_uint
+        self._dll.tf_bI.argtypes = (c_byte, c_uint)
+        self.failUnlessEqual(self._dll.tf_bI(0, 4294967295), 1431655765)
+        self.failUnlessEqual(self.U(), 4294967295)
+
+    def test_long(self):
+        self._dll.tf_l.restype = c_long
+        self._dll.tf_l.argtypes = (c_long,)
+        self.failUnlessEqual(self._dll.tf_l(-2147483646), -715827882)
+        self.failUnlessEqual(self.S(), -2147483646)
+
+    def test_long_plus(self):
+        self._dll.tf_bl.restype = c_long
+        self._dll.tf_bl.argtypes = (c_byte, c_long)
+        self.failUnlessEqual(self._dll.tf_bl(0, -2147483646), -715827882)
+        self.failUnlessEqual(self.S(), -2147483646)
+
+    def test_ulong(self):
+        self._dll.tf_L.restype = c_ulong
+        self._dll.tf_L.argtypes = (c_ulong,)
+        self.failUnlessEqual(self._dll.tf_L(4294967295), 1431655765)
+        self.failUnlessEqual(self.U(), 4294967295)
+
+    def test_ulong_plus(self):
+        self._dll.tf_bL.restype = c_ulong
+        self._dll.tf_bL.argtypes = (c_char, c_ulong)
+        self.failUnlessEqual(self._dll.tf_bL(' ', 4294967295), 1431655765)
+        self.failUnlessEqual(self.U(), 4294967295)
+
+    def test_longlong(self):
+        self._dll.tf_q.restype = c_longlong
+        self._dll.tf_q.argtypes = (c_longlong, )
+        self.failUnlessEqual(self._dll.tf_q(-9223372036854775806), -3074457345618258602)
+        self.failUnlessEqual(self.S(), -9223372036854775806)
+
+    def test_longlong_plus(self):
+        self._dll.tf_bq.restype = c_longlong
+        self._dll.tf_bq.argtypes = (c_byte, c_longlong)
+        self.failUnlessEqual(self._dll.tf_bq(0, -9223372036854775806), -3074457345618258602)
+        self.failUnlessEqual(self.S(), -9223372036854775806)
+
+    def test_ulonglong(self):
+        self._dll.tf_Q.restype = c_ulonglong
+        self._dll.tf_Q.argtypes = (c_ulonglong, )
+        self.failUnlessEqual(self._dll.tf_Q(18446744073709551615), 6148914691236517205)
+        self.failUnlessEqual(self.U(), 18446744073709551615)
+
+    def test_ulonglong_plus(self):
+        self._dll.tf_bQ.restype = c_ulonglong
+        self._dll.tf_bQ.argtypes = (c_byte, c_ulonglong)
+        self.failUnlessEqual(self._dll.tf_bQ(0, 18446744073709551615), 6148914691236517205)
+        self.failUnlessEqual(self.U(), 18446744073709551615)
+
+    def test_float(self):
+        self._dll.tf_f.restype = c_float
+        self._dll.tf_f.argtypes = (c_float,)
+        self.failUnlessEqual(self._dll.tf_f(-42.), -14.)
+        self.failUnlessEqual(self.S(), -42)
+
+    def test_float_plus(self):
+        self._dll.tf_bf.restype = c_float
+        self._dll.tf_bf.argtypes = (c_byte, c_float)
+        self.failUnlessEqual(self._dll.tf_bf(0, -42.), -14.)
+        self.failUnlessEqual(self.S(), -42)
+
+    def test_double(self):
+        self._dll.tf_d.restype = c_double
+        self._dll.tf_d.argtypes = (c_double,)
+        self.failUnlessEqual(self._dll.tf_d(42.), 14.)
+        self.failUnlessEqual(self.S(), 42)
+
+    def test_double_plus(self):
+        self._dll.tf_bd.restype = c_double
+        self._dll.tf_bd.argtypes = (c_byte, c_double)
+        self.failUnlessEqual(self._dll.tf_bd(0, 42.), 14.)
+        self.failUnlessEqual(self.S(), 42)
+
+    def test_callwithresult(self):
+        def process_result(result):
+            return result * 2
+        self._dll.tf_i.restype = process_result
+        self._dll.tf_i.argtypes = (c_int,)
+        self.failUnlessEqual(self._dll.tf_i(42), 28)
+        self.failUnlessEqual(self.S(), 42)
+        self.failUnlessEqual(self._dll.tf_i(-42), -28)
+        self.failUnlessEqual(self.S(), -42)
+
+    def test_void(self):
+        self._dll.tv_i.restype = None
+        self._dll.tv_i.argtypes = (c_int,)
+        self.failUnlessEqual(self._dll.tv_i(42), None)
+        self.failUnlessEqual(self.S(), 42)
+        self.failUnlessEqual(self._dll.tv_i(-42), None)
+        self.failUnlessEqual(self.S(), -42)
+
+# The following repeates the above tests with stdcall functions (where
+# they are available)
+try:
+    WinDLL
+except NameError:
+    pass
+else:
+    class stdcall_dll(WinDLL):
+        def __getattr__(self, name):
+            if name[:2] == '__' and name[-2:] == '__':
+                raise AttributeError, name
+            func = self._FuncPtr(("s_" + name, self))
+            setattr(self, name, func)
+            return func
+
+    class stdcallCFunctions(CFunctions):
+        _dll = stdcall_dll(_ctypes_test.__file__)
+        pass
+
+if __name__ == '__main__':
+    unittest.main()

Added: vendor/Python/current/Lib/ctypes/test/test_checkretval.py
===================================================================
--- vendor/Python/current/Lib/ctypes/test/test_checkretval.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/test/test_checkretval.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,40 @@
+import unittest
+import sys
+
+from ctypes import *
+
+class CHECKED(c_int):
+    def _check_retval_(value):
+        # Receives a CHECKED instance.
+        return str(value.value)
+    _check_retval_ = staticmethod(_check_retval_)
+
+class Test(unittest.TestCase):
+
+    def test_checkretval(self):
+
+        import _ctypes_test
+        dll = CDLL(_ctypes_test.__file__)
+        self.failUnlessEqual(42, dll._testfunc_p_p(42))
+
+        dll._testfunc_p_p.restype = CHECKED
+        self.failUnlessEqual("42", dll._testfunc_p_p(42))
+
+        dll._testfunc_p_p.restype = None
+        self.failUnlessEqual(None, dll._testfunc_p_p(42))
+
+        del dll._testfunc_p_p.restype
+        self.failUnlessEqual(42, dll._testfunc_p_p(42))
+
+    try:
+        oledll
+    except NameError:
+        pass
+    else:
+        def test_oledll(self):
+            self.failUnlessRaises(WindowsError,
+                                  oledll.oleaut32.CreateTypeLib2,
+                                  0, 0, 0)
+
+if __name__ == "__main__":
+    unittest.main()

Added: vendor/Python/current/Lib/ctypes/test/test_errcheck.py
===================================================================
--- vendor/Python/current/Lib/ctypes/test/test_errcheck.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/test/test_errcheck.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,19 @@
+import sys
+from ctypes import *
+
+##class HMODULE(Structure):
+##    _fields_ = [("value", c_void_p)]
+
+##    def __repr__(self):
+##        return "<HMODULE %s>" % self.value
+
+##windll.kernel32.GetModuleHandleA.restype = HMODULE
+
+##print windll.kernel32.GetModuleHandleA("python23.dll")
+##print hex(sys.dllhandle)
+
+##def nonzero(handle):
+##    return (GetLastError(), handle)
+
+##windll.kernel32.GetModuleHandleA.errcheck = nonzero
+##print windll.kernel32.GetModuleHandleA("spam")

Added: vendor/Python/current/Lib/ctypes/test/test_find.py
===================================================================
--- vendor/Python/current/Lib/ctypes/test/test_find.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/test/test_find.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,104 @@
+import unittest
+import os, sys
+from ctypes import *
+from ctypes.util import find_library
+from ctypes.test import is_resource_enabled
+
+if sys.platform == "win32":
+    lib_gl = find_library("OpenGL32")
+    lib_glu = find_library("Glu32")
+    lib_glut = find_library("glut32")
+    lib_gle = None
+elif sys.platform == "darwin":
+    lib_gl = lib_glu = find_library("OpenGL")
+    lib_glut = find_library("GLUT")
+    lib_gle = None
+else:
+    lib_gl = find_library("GL")
+    lib_glu = find_library("GLU")
+    lib_glut = find_library("glut")
+    lib_gle = find_library("gle")
+
+## print, for debugging
+if is_resource_enabled("printing"):
+    if lib_gl or lib_glu or lib_glut or lib_gle:
+        print "OpenGL libraries:"
+        for item in (("GL", lib_gl),
+                     ("GLU", lib_glu),
+                     ("glut", lib_glut),
+                     ("gle", lib_gle)):
+            print "\t", item
+
+
+# On some systems, loading the OpenGL libraries needs the RTLD_GLOBAL mode.
+class Test_OpenGL_libs(unittest.TestCase):
+    def setUp(self):
+        self.gl = self.glu = self.gle = self.glut = None
+        if lib_gl:
+            self.gl = CDLL(lib_gl, mode=RTLD_GLOBAL)
+        if lib_glu:
+            self.glu = CDLL(lib_glu, RTLD_GLOBAL)
+        if lib_glut:
+            # On some systems, additional libraries seem to be
+            # required, loading glut fails with
+            # "OSError: /usr/lib/libglut.so.3: undefined symbol: XGetExtensionVersion"
+            # I cannot figure out how to repair the test on these
+            # systems (red hat), so we ignore it when the glut or gle
+            # libraries cannot be loaded.  See also:
+            # https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1478253&group_id=5470
+            # http://mail.python.org/pipermail/python-dev/2006-May/064789.html
+            try:
+                self.glut = CDLL(lib_glut)
+            except OSError:
+                pass
+        if lib_gle:
+            try:
+                self.gle = CDLL(lib_gle)
+            except OSError:
+                pass
+
+    if lib_gl:
+        def test_gl(self):
+            if self.gl:
+                self.gl.glClearIndex
+
+    if lib_glu:
+        def test_glu(self):
+            if self.glu:
+                self.glu.gluBeginCurve
+
+    if lib_glut:
+        def test_glut(self):
+            if self.glut:
+                self.glut.glutWireTetrahedron
+
+    if lib_gle:
+        def test_gle(self):
+            if self.gle:
+                self.gle.gleGetJoinStyle
+
+##if os.name == "posix" and sys.platform != "darwin":
+
+##    # On platforms where the default shared library suffix is '.so',
+##    # at least some libraries can be loaded as attributes of the cdll
+##    # object, since ctypes now tries loading the lib again
+##    # with '.so' appended of the first try fails.
+##    #
+##    # Won't work for libc, unfortunately.  OTOH, it isn't
+##    # needed for libc since this is already mapped into the current
+##    # process (?)
+##    #
+##    # On MAC OSX, it won't work either, because dlopen() needs a full path,
+##    # and the default suffix is either none or '.dylib'.
+
+##    class LoadLibs(unittest.TestCase):
+##        def test_libm(self):
+##            import math
+##            libm = cdll.libm
+##            sqrt = libm.sqrt
+##            sqrt.argtypes = (c_double,)
+##            sqrt.restype = c_double
+##            self.failUnlessEqual(sqrt(2), math.sqrt(2))
+
+if __name__ == "__main__":
+    unittest.main()

Added: vendor/Python/current/Lib/ctypes/test/test_funcptr.py
===================================================================
--- vendor/Python/current/Lib/ctypes/test/test_funcptr.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/test/test_funcptr.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,127 @@
+import os, unittest
+from ctypes import *
+
+try:
+    WINFUNCTYPE
+except NameError:
+    # fake to enable this test on Linux
+    WINFUNCTYPE = CFUNCTYPE
+
+import _ctypes_test
+lib = CDLL(_ctypes_test.__file__)
+
+class CFuncPtrTestCase(unittest.TestCase):
+    def test_basic(self):
+        X = WINFUNCTYPE(c_int, c_int, c_int)
+
+        def func(*args):
+            return len(args)
+
+        x = X(func)
+        self.failUnlessEqual(x.restype, c_int)
+        self.failUnlessEqual(x.argtypes, (c_int, c_int))
+        self.failUnlessEqual(sizeof(x), sizeof(c_voidp))
+        self.failUnlessEqual(sizeof(X), sizeof(c_voidp))
+
+    def test_first(self):
+        StdCallback = WINFUNCTYPE(c_int, c_int, c_int)
+        CdeclCallback = CFUNCTYPE(c_int, c_int, c_int)
+
+        def func(a, b):
+            return a + b
+
+        s = StdCallback(func)
+        c = CdeclCallback(func)
+
+        self.failUnlessEqual(s(1, 2), 3)
+        self.failUnlessEqual(c(1, 2), 3)
+        # The following no longer raises a TypeError - it is now
+        # possible, as in C, to call cdecl functions with more parameters.
+        #self.assertRaises(TypeError, c, 1, 2, 3)
+        self.failUnlessEqual(c(1, 2, 3, 4, 5, 6), 3)
+        if not WINFUNCTYPE is CFUNCTYPE and os.name != "ce":
+            self.assertRaises(TypeError, s, 1, 2, 3)
+
+    def test_structures(self):
+        WNDPROC = WINFUNCTYPE(c_long, c_int, c_int, c_int, c_int)
+
+        def wndproc(hwnd, msg, wParam, lParam):
+            return hwnd + msg + wParam + lParam
+
+        HINSTANCE = c_int
+        HICON = c_int
+        HCURSOR = c_int
+        LPCTSTR = c_char_p
+
+        class WNDCLASS(Structure):
+            _fields_ = [("style", c_uint),
+                        ("lpfnWndProc", WNDPROC),
+                        ("cbClsExtra", c_int),
+                        ("cbWndExtra", c_int),
+                        ("hInstance", HINSTANCE),
+                        ("hIcon", HICON),
+                        ("hCursor", HCURSOR),
+                        ("lpszMenuName", LPCTSTR),
+                        ("lpszClassName", LPCTSTR)]
+
+        wndclass = WNDCLASS()
+        wndclass.lpfnWndProc = WNDPROC(wndproc)
+
+        WNDPROC_2 = WINFUNCTYPE(c_long, c_int, c_int, c_int, c_int)
+
+        # This is no longer true, now that WINFUNCTYPE caches created types internally.
+        ## # CFuncPtr subclasses are compared by identity, so this raises a TypeError:
+        ## self.assertRaises(TypeError, setattr, wndclass,
+        ##                  "lpfnWndProc", WNDPROC_2(wndproc))
+        # instead:
+
+        self.failUnless(WNDPROC is WNDPROC_2)
+        # 'wndclass.lpfnWndProc' leaks 94 references.  Why?
+        self.failUnlessEqual(wndclass.lpfnWndProc(1, 2, 3, 4), 10)
+
+
+        f = wndclass.lpfnWndProc
+
+        del wndclass
+        del wndproc
+
+        self.failUnlessEqual(f(10, 11, 12, 13), 46)
+
+    def test_dllfunctions(self):
+
+        def NoNullHandle(value):
+            if not value:
+                raise WinError()
+            return value
+
+        strchr = lib.my_strchr
+        strchr.restype = c_char_p
+        strchr.argtypes = (c_char_p, c_char)
+        self.failUnlessEqual(strchr("abcdefghi", "b"), "bcdefghi")
+        self.failUnlessEqual(strchr("abcdefghi", "x"), None)
+
+
+        strtok = lib.my_strtok
+        strtok.restype = c_char_p
+        # Neither of this does work: strtok changes the buffer it is passed
+##        strtok.argtypes = (c_char_p, c_char_p)
+##        strtok.argtypes = (c_string, c_char_p)
+
+        def c_string(init):
+            size = len(init) + 1
+            return (c_char*size)(*init)
+
+        s = "a\nb\nc"
+        b = c_string(s)
+
+##        b = (c_char * (len(s)+1))()
+##        b.value = s
+
+##        b = c_string(s)
+        self.failUnlessEqual(strtok(b, "\n"), "a")
+        self.failUnlessEqual(strtok(None, "\n"), "b")
+        self.failUnlessEqual(strtok(None, "\n"), "c")
+        self.failUnlessEqual(strtok(None, "\n"), None)
+
+if __name__ == '__main__':
+    unittest.main()

Added: vendor/Python/current/Lib/ctypes/test/test_functions.py
===================================================================
--- vendor/Python/current/Lib/ctypes/test/test_functions.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/test/test_functions.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,395 @@
+"""
+Here is probably the place to write the docs, since the test-cases
+show how the type behave.
+
+Later...
+"""
+
+from ctypes import *
+import sys, unittest
+
+try:
+    WINFUNCTYPE
+except NameError:
+    # fake to enable this test on Linux
+    WINFUNCTYPE = CFUNCTYPE
+
+import _ctypes_test
+dll = CDLL(_ctypes_test.__file__)
+if sys.platform == "win32":
+    windll = WinDLL(_ctypes_test.__file__)
+
+class POINT(Structure):
+    _fields_ = [("x", c_int), ("y", c_int)]
+class RECT(Structure):
+    _fields_ = [("left", c_int), ("top", c_int),
+                ("right", c_int), ("bottom", c_int)]
+class FunctionTestCase(unittest.TestCase):
+
+    def test_mro(self):
+        # in Python 2.3, this raises TypeError: MRO conflict among bases classes,
+        # in Python 2.2 it works.
+        #
+        # But in early versions of _ctypes.c, the result of tp_new
+        # wasn't checked, and it even crashed Python.
+        # Found by Greg Chapman.
+
+        try:
+            class X(object, Array):
+                _length_ = 5
+                _type_ = "i"
+        except TypeError:
+            pass
+
+
+        from _ctypes import _Pointer
+        try:
+            class X(object, _Pointer):
+                pass
+        except TypeError:
+            pass
+
+        from _ctypes import _SimpleCData
+        try:
+            class X(object, _SimpleCData):
+                _type_ = "i"
+        except TypeError:
+            pass
+
+        try:
+            class X(object, Structure):
+                _fields_ = []
+        except TypeError:
+            pass
+
+
+    def test_wchar_parm(self):
+        try:
+            c_wchar
+        except NameError:
+            return
+        f = dll._testfunc_i_bhilfd
+        f.argtypes = [c_byte, c_wchar, c_int, c_long, c_float, c_double]
+        result = f(1, u"x", 3, 4, 5.0, 6.0)
+        self.failUnlessEqual(result, 139)
+        self.failUnlessEqual(type(result), int)
+
+    def test_wchar_result(self):
+        try:
+            c_wchar
+        except NameError:
+            return
+        f = dll._testfunc_i_bhilfd
+        f.argtypes = [c_byte, c_short, c_int, c_long, c_float, c_double]
+        f.restype = c_wchar
+        result = f(0, 0, 0, 0, 0, 0)
+        self.failUnlessEqual(result, u'\x00')
+
+    def test_voidresult(self):
+        f = dll._testfunc_v
+        f.restype = None
+        f.argtypes = [c_int, c_int, POINTER(c_int)]
+        result = c_int()
+        self.failUnlessEqual(None, f(1, 2, byref(result)))
+        self.failUnlessEqual(result.value, 3)
+
+    def test_intresult(self):
+        f = dll._testfunc_i_bhilfd
+        f.argtypes = [c_byte, c_short, c_int, c_long, c_float, c_double]
+        f.restype = c_int
+        result = f(1, 2, 3, 4, 5.0, 6.0)
+        self.failUnlessEqual(result, 21)
+        self.failUnlessEqual(type(result), int)
+
+        result = f(-1, -2, -3, -4, -5.0, -6.0)
+        self.failUnlessEqual(result, -21)
+        self.failUnlessEqual(type(result), int)
+
+        # If we declare the function to return a short,
+        # is the high part split off?
+        f.restype = c_short
+        result = f(1, 2, 3, 4, 5.0, 6.0)
+        self.failUnlessEqual(result, 21)
+        self.failUnlessEqual(type(result), int)
+
+        result = f(1, 2, 3, 0x10004, 5.0, 6.0)
+        self.failUnlessEqual(result, 21)
+        self.failUnlessEqual(type(result), int)
+
+        # You cannot assing character format codes as restype any longer
+        self.assertRaises(TypeError, setattr, f, "restype", "i")
+
+    def test_floatresult(self):
+        f = dll._testfunc_f_bhilfd
+        f.argtypes = [c_byte, c_short, c_int, c_long, c_float, c_double]
+        f.restype = c_float
+        result = f(1, 2, 3, 4, 5.0, 6.0)
+        self.failUnlessEqual(result, 21)
+        self.failUnlessEqual(type(result), float)
+
+        result = f(-1, -2, -3, -4, -5.0, -6.0)
+        self.failUnlessEqual(result, -21)
+        self.failUnlessEqual(type(result), float)
+
+    def test_doubleresult(self):
+        f = dll._testfunc_d_bhilfd
+        f.argtypes = [c_byte, c_short, c_int, c_long, c_float, c_double]
+        f.restype = c_double
+        result = f(1, 2, 3, 4, 5.0, 6.0)
+        self.failUnlessEqual(result, 21)
+        self.failUnlessEqual(type(result), float)
+
+        result = f(-1, -2, -3, -4, -5.0, -6.0)
+        self.failUnlessEqual(result, -21)
+        self.failUnlessEqual(type(result), float)
+
+    def test_longlongresult(self):
+        try:
+            c_longlong
+        except NameError:
+            return
+        f = dll._testfunc_q_bhilfd
+        f.restype = c_longlong
+        f.argtypes = [c_byte, c_short, c_int, c_long, c_float, c_double]
+        result = f(1, 2, 3, 4, 5.0, 6.0)
+        self.failUnlessEqual(result, 21)
+
+        f = dll._testfunc_q_bhilfdq
+        f.restype = c_longlong
+        f.argtypes = [c_byte, c_short, c_int, c_long, c_float, c_double, c_longlong]
+        result = f(1, 2, 3, 4, 5.0, 6.0, 21)
+        self.failUnlessEqual(result, 42)
+
+    def test_stringresult(self):
+        f = dll._testfunc_p_p
+        f.argtypes = None
+        f.restype = c_char_p
+        result = f("123")
+        self.failUnlessEqual(result, "123")
+
+        result = f(None)
+        self.failUnlessEqual(result, None)
+
+    def test_pointers(self):
+        f = dll._testfunc_p_p
+        f.restype = POINTER(c_int)
+        f.argtypes = [POINTER(c_int)]
+
+        # This only works if the value c_int(42) passed to the
+        # function is still alive while the pointer (the result) is
+        # used.
+
+        v = c_int(42)
+
+        self.failUnlessEqual(pointer(v).contents.value, 42)
+        result = f(pointer(v))
+        self.failUnlessEqual(type(result), POINTER(c_int))
+        self.failUnlessEqual(result.contents.value, 42)
+
+        # This on works...
+        result = f(pointer(v))
+        self.failUnlessEqual(result.contents.value, v.value)
+
+        p = pointer(c_int(99))
+        result = f(p)
+        self.failUnlessEqual(result.contents.value, 99)
+
+        arg = byref(v)
+        result = f(arg)
+        self.failIfEqual(result.contents, v.value)
+
+        self.assertRaises(ArgumentError, f, byref(c_short(22)))
+
+        # It is dangerous, however, because you don't control the lifetime
+        # of the pointer:
+        result = f(byref(c_int(99)))
+        self.failIfEqual(result.contents, 99)
+
+    def test_errors(self):
+        f = dll._testfunc_p_p
+        f.restype = c_int
+
+        class X(Structure):
+            _fields_ = [("y", c_int)]
+
+        self.assertRaises(TypeError, f, X()) #cannot convert parameter
+
+    ################################################################
+    def test_shorts(self):
+        f = dll._testfunc_callback_i_if
+
+        args = []
+        expected = [262144, 131072, 65536, 32768, 16384, 8192, 4096, 2048,
+                    1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1]
+
+        def callback(v):
+            args.append(v)
+            return v
+
+        CallBack = CFUNCTYPE(c_int, c_int)
+
+        cb = CallBack(callback)
+        f(2**18, cb)
+        self.failUnlessEqual(args, expected)
+
+    ################################################################
+
+
+    def test_callbacks(self):
+        f = dll._testfunc_callback_i_if
+        f.restype = c_int
+
+        MyCallback = CFUNCTYPE(c_int, c_int)
+
+        def callback(value):
+            #print "called back with", value
+            return value
+
+        cb = MyCallback(callback)
+        result = f(-10, cb)
+        self.failUnlessEqual(result, -18)
+
+        # test with prototype
+        f.argtypes = [c_int, MyCallback]
+        cb = MyCallback(callback)
+        result = f(-10, cb)
+        self.failUnlessEqual(result, -18)
+
+        AnotherCallback = WINFUNCTYPE(c_int, c_int, c_int, c_int, c_int)
+
+        # check that the prototype works: we call f with wrong
+        # argument types
+        cb = AnotherCallback(callback)
+        self.assertRaises(ArgumentError, f, -10, cb)
+
+
+    def test_callbacks_2(self):
+        # Can also use simple datatypes as argument type specifiers
+        # for the callback function.
+        # In this case the call receives an instance of that type
+        f = dll._testfunc_callback_i_if
+        f.restype = c_int
+
+        MyCallback = CFUNCTYPE(c_int, c_int)
+
+        f.argtypes = [c_int, MyCallback]
+
+        def callback(value):
+            #print "called back with", value
+            self.failUnlessEqual(type(value), int)
+            return value
+
+        cb = MyCallback(callback)
+        result = f(-10, cb)
+        self.failUnlessEqual(result, -18)
+
+    def test_longlong_callbacks(self):
+
+        f = dll._testfunc_callback_q_qf
+        f.restype = c_longlong
+
+        MyCallback = CFUNCTYPE(c_longlong, c_longlong)
+
+        f.argtypes = [c_longlong, MyCallback]
+
+        def callback(value):
+            self.failUnless(isinstance(value, (int, long)))
+            return value & 0x7FFFFFFF
+
+        cb = MyCallback(callback)
+
+        self.failUnlessEqual(13577625587, f(1000000000000, cb))
+
+    def test_errors(self):
+        self.assertRaises(AttributeError, getattr, dll, "_xxx_yyy")
+        self.assertRaises(ValueError, c_int.in_dll, dll, "_xxx_yyy")
+
+    def test_byval(self):
+
+        # without prototype
+        ptin = POINT(1, 2)
+        ptout = POINT()
+        # EXPORT int _testfunc_byval(point in, point *pout)
+        result = dll._testfunc_byval(ptin, byref(ptout))
+        got = result, ptout.x, ptout.y
+        expected = 3, 1, 2
+        self.failUnlessEqual(got, expected)
+
+        # with prototype
+        ptin = POINT(101, 102)
+        ptout = POINT()
+        dll._testfunc_byval.argtypes = (POINT, POINTER(POINT))
+        dll._testfunc_byval.restype = c_int
+        result = dll._testfunc_byval(ptin, byref(ptout))
+        got = result, ptout.x, ptout.y
+        expected = 203, 101, 102
+        self.failUnlessEqual(got, expected)
+
+    def test_struct_return_2H(self):
+        class S2H(Structure):
+            _fields_ = [("x", c_short),
+                        ("y", c_short)]
+        dll.ret_2h_func.restype = S2H
+        dll.ret_2h_func.argtypes = [S2H]
+        inp = S2H(99, 88)
+        s2h = dll.ret_2h_func(inp)
+        self.failUnlessEqual((s2h.x, s2h.y), (99*2, 88*3))
+
+    if sys.platform == "win32":
+        def test_struct_return_2H_stdcall(self):
+            class S2H(Structure):
+                _fields_ = [("x", c_short),
+                            ("y", c_short)]
+
+            windll.s_ret_2h_func.restype = S2H
+            windll.s_ret_2h_func.argtypes = [S2H]
+            s2h = windll.s_ret_2h_func(S2H(99, 88))
+            self.failUnlessEqual((s2h.x, s2h.y), (99*2, 88*3))
+
+    def test_struct_return_8H(self):
+        class S8I(Structure):
+            _fields_ = [("a", c_int),
+                        ("b", c_int),
+                        ("c", c_int),
+                        ("d", c_int),
+                        ("e", c_int),
+                        ("f", c_int),
+                        ("g", c_int),
+                        ("h", c_int)]
+        dll.ret_8i_func.restype = S8I
+        dll.ret_8i_func.argtypes = [S8I]
+        inp = S8I(9, 8, 7, 6, 5, 4, 3, 2)
+        s8i = dll.ret_8i_func(inp)
+        self.failUnlessEqual((s8i.a, s8i.b, s8i.c, s8i.d, s8i.e, s8i.f, s8i.g, s8i.h),
+                             (9*2, 8*3, 7*4, 6*5, 5*6, 4*7, 3*8, 2*9))
+
+    if sys.platform == "win32":
+        def test_struct_return_8H_stdcall(self):
+            class S8I(Structure):
+                _fields_ = [("a", c_int),
+                            ("b", c_int),
+                            ("c", c_int),
+                            ("d", c_int),
+                            ("e", c_int),
+                            ("f", c_int),
+                            ("g", c_int),
+                            ("h", c_int)]
+            windll.s_ret_8i_func.restype = S8I
+            windll.s_ret_8i_func.argtypes = [S8I]
+            inp = S8I(9, 8, 7, 6, 5, 4, 3, 2)
+            s8i = windll.s_ret_8i_func(inp)
+            self.failUnlessEqual((s8i.a, s8i.b, s8i.c, s8i.d, s8i.e, s8i.f, s8i.g, s8i.h),
+                                 (9*2, 8*3, 7*4, 6*5, 5*6, 4*7, 3*8, 2*9))
+
+    def test_sf1651235(self):
+        # see http://www.python.org/sf/1651235
+
+        proto = CFUNCTYPE(c_int, RECT, POINT)
+        def callback(*args):
+            return 0
+
+        callback = proto(callback)
+        self.failUnlessRaises(ArgumentError, lambda: callback((1, 2, 3, 4), POINT()))
+
+if __name__ == '__main__':
+    unittest.main()

Added: vendor/Python/current/Lib/ctypes/test/test_incomplete.py
===================================================================
--- vendor/Python/current/Lib/ctypes/test/test_incomplete.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/test/test_incomplete.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,42 @@
+import unittest
+from ctypes import *
+
+################################################################
+#
+# The incomplete pointer example from the tutorial
+#
+
+class MyTestCase(unittest.TestCase):
+
+    def test_incomplete_example(self):
+        lpcell = POINTER("cell")
+        class cell(Structure):
+            _fields_ = [("name", c_char_p),
+                        ("next", lpcell)]
+
+        SetPointerType(lpcell, cell)
+
+        c1 = cell()
+        c1.name = "foo"
+        c2 = cell()
+        c2.name = "bar"
+
+        c1.next = pointer(c2)
+        c2.next = pointer(c1)
+
+        p = c1
+
+        result = []
+        for i in range(8):
+            result.append(p.name)
+            p = p.next[0]
+        self.failUnlessEqual(result, ["foo", "bar"] * 4)
+
+        # to not leak references, we must clean _pointer_type_cache
+        from ctypes import _pointer_type_cache
+        del _pointer_type_cache[cell]
+
+################################################################
+
+if __name__ == '__main__':
+    unittest.main()

Added: vendor/Python/current/Lib/ctypes/test/test_init.py
===================================================================
--- vendor/Python/current/Lib/ctypes/test/test_init.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/test/test_init.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,40 @@
+from ctypes import *
+import unittest
+
+class X(Structure):
+    _fields_ = [("a", c_int),
+                ("b", c_int)]
+    new_was_called = False
+
+    def __new__(cls):
+        result = super(X, cls).__new__(cls)
+        result.new_was_called = True
+        return result
+
+    def __init__(self):
+        self.a = 9
+        self.b = 12
+
+class Y(Structure):
+    _fields_ = [("x", X)]
+
+
+class InitTest(unittest.TestCase):
+    def test_get(self):
+        # make sure the only accessing a nested structure
+        # doesn't call the structure's __new__ and __init__
+        y = Y()
+        self.failUnlessEqual((y.x.a, y.x.b), (0, 0))
+        self.failUnlessEqual(y.x.new_was_called, False)
+
+        # But explicitely creating an X structure calls __new__ and __init__, of course.
+        x = X()
+        self.failUnlessEqual((x.a, x.b), (9, 12))
+        self.failUnlessEqual(x.new_was_called, True)
+
+        y.x = x
+        self.failUnlessEqual((y.x.a, y.x.b), (9, 12))
+        self.failUnlessEqual(y.x.new_was_called, False)
+
+if __name__ == "__main__":
+    unittest.main()

Added: vendor/Python/current/Lib/ctypes/test/test_integers.py
===================================================================
--- vendor/Python/current/Lib/ctypes/test/test_integers.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/test/test_integers.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,5 @@
+# superseeded by test_numbers.py
+import unittest
+
+if __name__ == '__main__':
+    unittest.main()

Added: vendor/Python/current/Lib/ctypes/test/test_internals.py
===================================================================
--- vendor/Python/current/Lib/ctypes/test/test_internals.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/test/test_internals.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,103 @@
+# This tests the internal _objects attribute
+import unittest
+from ctypes import *
+from sys import getrefcount as grc
+
+# XXX This test must be reviewed for correctness!!!
+
+"""
+ctypes' types are container types.
+
+They have an internal memory block, which only consists of some bytes,
+but it has to keep references to other objects as well. This is not
+really needed for trivial C types like int or char, but it is important
+for aggregate types like strings or pointers in particular.
+
+What about pointers?
+
+"""
+
+class ObjectsTestCase(unittest.TestCase):
+    def failUnlessSame(self, a, b):
+        self.failUnlessEqual(id(a), id(b))
+
+    def test_ints(self):
+        i = 42000123
+        self.failUnlessEqual(3, grc(i))
+        ci = c_int(i)
+        self.failUnlessEqual(3, grc(i))
+        self.failUnlessEqual(ci._objects, None)
+
+    def test_c_char_p(self):
+        s = "Hello, World"
+        self.failUnlessEqual(3, grc(s))
+        cs = c_char_p(s)
+        self.failUnlessEqual(4, grc(s))
+        self.failUnlessSame(cs._objects, s)
+
+    def test_simple_struct(self):
+        class X(Structure):
+            _fields_ = [("a", c_int), ("b", c_int)]
+
+        a = 421234
+        b = 421235
+        x = X()
+        self.failUnlessEqual(x._objects, None)
+        x.a = a
+        x.b = b
+        self.failUnlessEqual(x._objects, None)
+
+    def test_embedded_structs(self):
+        class X(Structure):
+            _fields_ = [("a", c_int), ("b", c_int)]
+
+        class Y(Structure):
+            _fields_ = [("x", X), ("y", X)]
+
+        y = Y()
+        self.failUnlessEqual(y._objects, None)
+
+        x1, x2 = X(), X()
+        y.x, y.y = x1, x2
+        self.failUnlessEqual(y._objects, {"0": {}, "1": {}})
+        x1.a, x2.b = 42, 93
+        self.failUnlessEqual(y._objects, {"0": {}, "1": {}})
+
+    def test_xxx(self):
+        class X(Structure):
+            _fields_ = [("a", c_char_p), ("b", c_char_p)]
+
+        class Y(Structure):
+            _fields_ = [("x", X), ("y", X)]
+
+        s1 = "Hello, World"
+        s2 = "Hallo, Welt"
+
+        x = X()
+        x.a = s1
+        x.b = s2
+        self.failUnlessEqual(x._objects, {"0": s1, "1": s2})
+
+        y = Y()
+        y.x = x
+        self.failUnlessEqual(y._objects, {"0": {"0": s1, "1": s2}})
+##        x = y.x
+##        del y
+##        print x._b_base_._objects
+
+    def test_ptr_struct(self):
+        class X(Structure):
+            _fields_ = [("data", POINTER(c_int))]
+
+        A = c_int*4
+        a = A(11, 22, 33, 44)
+        self.failUnlessEqual(a._objects, None)
+
+        x = X()
+        x.data = a
+##XXX        print x._objects
+##XXX        print x.data[0]
+##XXX        print x.data._objects
+
+if __name__ == '__main__':
+    unittest.main()

Added: vendor/Python/current/Lib/ctypes/test/test_keeprefs.py
===================================================================
--- vendor/Python/current/Lib/ctypes/test/test_keeprefs.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/test/test_keeprefs.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,152 @@
+from ctypes import *
+import unittest
+
+class SimpleTestCase(unittest.TestCase):
+    def test_cint(self):
+        x = c_int()
+        self.assertEquals(x._objects, None)
+        x.value = 42
+        self.assertEquals(x._objects, None)
+        x = c_int(99)
+        self.assertEquals(x._objects, None)
+
+    def test_ccharp(self):
+        x = c_char_p()
+        self.assertEquals(x._objects, None)
+        x.value = "abc"
+        self.assertEquals(x._objects, "abc")
+        x = c_char_p("spam")
+        self.assertEquals(x._objects, "spam")
+
+class StructureTestCase(unittest.TestCase):
+    def test_cint_struct(self):
+        class X(Structure):
+            _fields_ = [("a", c_int),
+                        ("b", c_int)]
+
+        x = X()
+        self.assertEquals(x._objects, None)
+        x.a = 42
+        x.b = 99
+        self.assertEquals(x._objects, None)
+
+    def test_ccharp_struct(self):
+        class X(Structure):
+            _fields_ = [("a", c_char_p),
+                        ("b", c_char_p)]
+        x = X()
+        self.assertEquals(x._objects, None)
+
+        x.a = "spam"
+        x.b = "foo"
+        self.assertEquals(x._objects, {"0": "spam", "1": "foo"})
+
+    def test_struct_struct(self):
+        class POINT(Structure):
+            _fields_ = [("x", c_int), ("y", c_int)]
+        class RECT(Structure):
+            _fields_ = [("ul", POINT), ("lr", POINT)]
+
+        r = RECT()
+        r.ul.x = 0
+        r.ul.y = 1
+        r.lr.x = 2
+        r.lr.y = 3
+        self.assertEquals(r._objects, None)
+
+        r = RECT()
+        pt = POINT(1, 2)
+        r.ul = pt
+        self.assertEquals(r._objects, {'0': {}})
+        r.ul.x = 22
+        r.ul.y = 44
+        self.assertEquals(r._objects, {'0': {}})
+        r.lr = POINT()
+        self.assertEquals(r._objects, {'0': {}, '1': {}})
+
+class ArrayTestCase(unittest.TestCase):
+    def test_cint_array(self):
+        INTARR = c_int * 3
+
+        ia = INTARR()
+        self.assertEquals(ia._objects, None)
+        ia[0] = 1
+        ia[1] = 2
+        ia[2] = 3
+        self.assertEquals(ia._objects, None)
+
+        class X(Structure):
+            _fields_ = [("x", c_int),
+                        ("a", INTARR)]
+
+        x = X()
+        x.x = 1000
+        x.a[0] = 42
+        x.a[1] = 96
+        self.assertEquals(x._objects, None)
+        x.a = ia
+        self.assertEquals(x._objects, {'1': {}})
+
+class PointerTestCase(unittest.TestCase):
+    def test_p_cint(self):
+        i = c_int(42)
+        x = pointer(i)
+        self.failUnlessEqual(x._objects, {'1': i})
+
+class DeletePointerTestCase(unittest.TestCase):
+    def X_test(self):
+        class X(Structure):
+            _fields_ = [("p", POINTER(c_char_p))]
+        x = X()
+        i = c_char_p("abc def")
+        from sys import getrefcount as grc
+        print "2?", grc(i)
+        x.p = pointer(i)
+        print "3?", grc(i)
+        for i in range(320):
+            c_int(99)
+            x.p[0]
+        print x.p[0]
+##        del x
+##        print "2?", grc(i)
+##        del i
+        import gc
+        gc.collect()
+        for i in range(320):
+            c_int(99)
+            x.p[0]
+        print x.p[0]
+        print x.p.contents
+##        print x._objects
+
+        x.p[0] = "spam spam"
+##        print x.p[0]
+        print "+" * 42
+        print x._objects
+
+class PointerToStructure(unittest.TestCase):
+    def test(self):
+        class POINT(Structure):
+            _fields_ = [("x", c_int), ("y", c_int)]
+        class RECT(Structure):
+            _fields_ = [("a", POINTER(POINT)),
+                        ("b", POINTER(POINT))]
+        r = RECT()
+        p1 = POINT(1, 2)
+
+        r.a = pointer(p1)
+        r.b = pointer(p1)
+##        from pprint import pprint as pp
+##        pp(p1._objects)
+##        pp(r._objects)
+
+        r.a[0].x = 42
+        r.a[0].y = 99
+
+        # to avoid leaking when tests are run several times
+        # clean up the types left in the cache.
+        from ctypes import _pointer_type_cache
+        del _pointer_type_cache[POINT]
+
+if __name__ == "__main__":
+    unittest.main()

Added: vendor/Python/current/Lib/ctypes/test/test_libc.py
===================================================================
--- vendor/Python/current/Lib/ctypes/test/test_libc.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/test/test_libc.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,30 @@
+import sys, os
+import unittest
+
+from ctypes import *
+import _ctypes_test
+
+lib = CDLL(_ctypes_test.__file__)
+
+class LibTest(unittest.TestCase):
+    def test_sqrt(self):
+        lib.my_sqrt.argtypes = c_double,
+        lib.my_sqrt.restype = c_double
+        self.failUnlessEqual(lib.my_sqrt(4.0), 2.0)
+        import math
+        self.failUnlessEqual(lib.my_sqrt(2.0), math.sqrt(2.0))
+
+    def test_qsort(self):
+        comparefunc = CFUNCTYPE(c_int, POINTER(c_char), POINTER(c_char))
+        lib.my_qsort.argtypes = c_void_p, c_size_t, c_size_t, comparefunc
+        lib.my_qsort.restype = None
+
+        def sort(a, b):
+            return cmp(a[0], b[0])
+
+        chars = create_string_buffer("spam, spam, and spam")
+        lib.my_qsort(chars, len(chars)-1, sizeof(c_char), comparefunc(sort))
+        self.failUnlessEqual(chars.raw, "   ,,aaaadmmmnpppsss\x00")
+
+if __name__ == "__main__":
+    unittest.main()

Added: vendor/Python/current/Lib/ctypes/test/test_loading.py
===================================================================
--- vendor/Python/current/Lib/ctypes/test/test_loading.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/test/test_loading.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,78 @@
+from ctypes import *
+import sys, unittest
+import os, StringIO
+from ctypes.util import find_library
+from ctypes.test import is_resource_enabled
+
+libc_name = None
+if os.name == "nt":
+    libc_name = "msvcrt"
+elif os.name == "ce":
+    libc_name = "coredll"
+elif sys.platform == "cygwin":
+    libc_name = "cygwin1.dll"
+else:
+    libc_name = find_library("c")
+
+if True or is_resource_enabled("printing"):
+    print >> sys.stderr, "\tfind_library('c') -> ", find_library('c')
+    print >> sys.stderr, "\tfind_library('m') -> ", find_library('m')
+
+class LoaderTest(unittest.TestCase):
+
+    unknowndll = "xxrandomnamexx"
+
+    if libc_name is not None:
+        def test_load(self):
+            CDLL(libc_name)
+            CDLL(os.path.basename(libc_name))
+            self.assertRaises(OSError, CDLL, self.unknowndll)
+
+    if libc_name is not None and os.path.basename(libc_name) == "libc.so.6":
+        def test_load_version(self):
+            cdll.LoadLibrary("libc.so.6")
+            # linux uses version, libc 9 should not exist
+            self.assertRaises(OSError, cdll.LoadLibrary, "libc.so.9")
+            self.assertRaises(OSError, cdll.LoadLibrary, self.unknowndll)
+
+    def test_find(self):
+        for name in ("c", "m"):
+            lib = find_library(name)
+            if lib:
+                cdll.LoadLibrary(lib)
+                CDLL(lib)
+
+    if os.name in ("nt", "ce"):
+        def test_load_library(self):
+            if is_resource_enabled("printing"):
+                print find_library("kernel32")
+                print find_library("user32")
+
+            if os.name == "nt":
+                windll.kernel32.GetModuleHandleW
+                windll["kernel32"].GetModuleHandleW
+                windll.LoadLibrary("kernel32").GetModuleHandleW
+                WinDLL("kernel32").GetModuleHandleW
+            elif os.name == "ce":
+                windll.coredll.GetModuleHandleW
+                windll["coredll"].GetModuleHandleW
+                windll.LoadLibrary("coredll").GetModuleHandleW
+                WinDLL("coredll").GetModuleHandleW
+
+        def test_load_ordinal_functions(self):
+            import _ctypes_test
+            dll = WinDLL(_ctypes_test.__file__)
+            # We load the same function both via ordinal and name
+            func_ord = dll[2]
+            func_name = dll.GetString
+            # addressof gets the address where the function pointer is stored
+            a_ord = addressof(func_ord)
+            a_name = addressof(func_name)
+            f_ord_addr = c_void_p.from_address(a_ord).value
+            f_name_addr = c_void_p.from_address(a_name).value
+            self.failUnlessEqual(hex(f_ord_addr), hex(f_name_addr))
+
+            self.failUnlessRaises(AttributeError, dll.__getitem__, 1234)
+
+if __name__ == "__main__":
+    unittest.main()

Added: vendor/Python/current/Lib/ctypes/test/test_macholib.py
===================================================================
--- vendor/Python/current/Lib/ctypes/test/test_macholib.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/test/test_macholib.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,62 @@
+import os
+import sys
+import unittest
+
+# Bob Ippolito:
+"""
+Ok.. the code to find the filename for __getattr__ should look
+something like:
+
+import os
+from macholib.dyld import dyld_find
+
+def find_lib(name):
+     possible = ['lib'+name+'.dylib', name+'.dylib',
+     name+'.framework/'+name]
+     for dylib in possible:
+         try:
+             return os.path.realpath(dyld_find(dylib))
+         except ValueError:
+             pass
+     raise ValueError, "%s not found" % (name,)
+
+It'll have output like this:
+
+ >>> find_lib('pthread')
+'/usr/lib/libSystem.B.dylib'
+ >>> find_lib('z')
+'/usr/lib/libz.1.dylib'
+ >>> find_lib('IOKit')
+'/System/Library/Frameworks/IOKit.framework/Versions/A/IOKit'
+
+-bob
+
+"""
+
+from ctypes.macholib.dyld import dyld_find
+
+def find_lib(name):
+    possible = ['lib'+name+'.dylib', name+'.dylib', name+'.framework/'+name]
+    for dylib in possible:
+        try:
+            return os.path.realpath(dyld_find(dylib))
+        except ValueError:
+            pass
+    raise ValueError, "%s not found" % (name,)
+
+class MachOTest(unittest.TestCase):
+    if sys.platform == "darwin":
+        def test_find(self):
+
+            self.failUnlessEqual(find_lib('pthread'),
+                                 '/usr/lib/libSystem.B.dylib')
+
+            result = find_lib('z')
+            self.failUnless(result.startswith('/usr/lib/libz.1'))
+            self.failUnless(result.endswith('.dylib'))
+
+            self.failUnlessEqual(find_lib('IOKit'),
+                                 '/System/Library/Frameworks/IOKit.framework/Versions/A/IOKit')
+
+if __name__ == "__main__":
+    unittest.main()

Added: vendor/Python/current/Lib/ctypes/test/test_memfunctions.py
===================================================================
--- vendor/Python/current/Lib/ctypes/test/test_memfunctions.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/test/test_memfunctions.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,61 @@
+import sys
+import unittest
+from ctypes import *
+
+class MemFunctionsTest(unittest.TestCase):
+    def test_memmove(self):
+        # large buffers apparently increase the chance that the memory
+        # is allocated in high address space.
+        a = create_string_buffer(1000000)
+        p = "Hello, World"
+        result = memmove(a, p, len(p))
+        self.failUnlessEqual(a.value, "Hello, World")
+
+        self.failUnlessEqual(string_at(result), "Hello, World")
+        self.failUnlessEqual(string_at(result, 5), "Hello")
+        self.failUnlessEqual(string_at(result, 16), "Hello, World\0\0\0\0")
+        self.failUnlessEqual(string_at(result, 0), "")
+
+    def test_memset(self):
+        a = create_string_buffer(1000000)
+        result = memset(a, ord('x'), 16)
+        self.failUnlessEqual(a.value, "xxxxxxxxxxxxxxxx")
+
+        self.failUnlessEqual(string_at(result), "xxxxxxxxxxxxxxxx")
+        self.failUnlessEqual(string_at(a), "xxxxxxxxxxxxxxxx")
+        self.failUnlessEqual(string_at(a, 20), "xxxxxxxxxxxxxxxx\0\0\0\0")
+
+    def test_cast(self):
+        a = (c_ubyte * 32)(*map(ord, "abcdef"))
+        self.failUnlessEqual(cast(a, c_char_p).value, "abcdef")
+        self.failUnlessEqual(cast(a, POINTER(c_byte))[:7],
+                             [97, 98, 99, 100, 101, 102, 0])
+
+    def test_string_at(self):
+        s = string_at("foo bar")
+        # XXX The following may be wrong, depending on how Python
+        # manages string instances
+        self.failUnlessEqual(2, sys.getrefcount(s))
+        self.failUnless(s, "foo bar")
+
+        self.failUnlessEqual(string_at("foo bar", 8), "foo bar\0")
+        self.failUnlessEqual(string_at("foo bar", 3), "foo")
+
+    try:
+        create_unicode_buffer
+    except NameError:
+        pass
+    else:
+        def test_wstring_at(self):
+            p = create_unicode_buffer("Hello, World")
+            a = create_unicode_buffer(1000000)
+            result = memmove(a, p, len(p) * sizeof(c_wchar))
+            self.failUnlessEqual(a.value, "Hello, World")
+
+            self.failUnlessEqual(wstring_at(a), "Hello, World")
+            self.failUnlessEqual(wstring_at(a, 5), "Hello")
+            self.failUnlessEqual(wstring_at(a, 16), "Hello, World\0\0\0\0")
+            self.failUnlessEqual(wstring_at(a, 0), "")
+
+if __name__ == "__main__":
+    unittest.main()

Added: vendor/Python/current/Lib/ctypes/test/test_numbers.py
===================================================================
--- vendor/Python/current/Lib/ctypes/test/test_numbers.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/test/test_numbers.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,230 @@
+from ctypes import *
+import unittest
+import sys, struct
+
+def valid_ranges(*types):
+    # given a sequence of numeric types, collect their _type_
+    # attribute, which is a single format character compatible with
+    # the struct module, use the struct module to calculate the
+    # minimum and maximum value allowed for this format.
+    # Returns a list of (min, max) values.
+    result = []
+    for t in types:
+        fmt = t._type_
+        size = struct.calcsize(fmt)
+        a = struct.unpack(fmt, ("\x00"*32)[:size])[0]
+        b = struct.unpack(fmt, ("\xFF"*32)[:size])[0]
+        c = struct.unpack(fmt, ("\x7F"+"\x00"*32)[:size])[0]
+        d = struct.unpack(fmt, ("\x80"+"\xFF"*32)[:size])[0]
+        result.append((min(a, b, c, d), max(a, b, c, d)))
+    return result
+
+ArgType = type(byref(c_int(0)))
+
+unsigned_types = [c_ubyte, c_ushort, c_uint, c_ulong]
+signed_types = [c_byte, c_short, c_int, c_long, c_longlong]
+
+float_types = [c_double, c_float]
+
+try:
+    c_ulonglong
+    c_longlong
+except NameError:
+    pass
+else:
+    unsigned_types.append(c_ulonglong)
+    signed_types.append(c_longlong)
+
+unsigned_ranges = valid_ranges(*unsigned_types)
+signed_ranges = valid_ranges(*signed_types)
+
+################################################################
+
+class NumberTestCase(unittest.TestCase):
+
+    def test_default_init(self):
+        # default values are set to zero
+        for t in signed_types + unsigned_types + float_types:
+            self.failUnlessEqual(t().value, 0)
+
+    def test_unsigned_values(self):
+        # the value given to the constructor is available
+        # as the 'value' attribute
+        for t, (l, h) in zip(unsigned_types, unsigned_ranges):
+            self.failUnlessEqual(t(l).value, l)
+            self.failUnlessEqual(t(h).value, h)
+
+    def test_signed_values(self):
+        # see above
+        for t, (l, h) in zip(signed_types, signed_ranges):
+            self.failUnlessEqual(t(l).value, l)
+            self.failUnlessEqual(t(h).value, h)
+
+    def test_typeerror(self):
+        # Only numbers are allowed in the contructor,
+        # otherwise TypeError is raised
+        for t in signed_types + unsigned_types + float_types:
+            self.assertRaises(TypeError, t, "")
+            self.assertRaises(TypeError, t, None)
+
+##    def test_valid_ranges(self):
+##        # invalid values of the correct type
+##        # raise ValueError (not OverflowError)
+##        for t, (l, h) in zip(unsigned_types, unsigned_ranges):
+##            self.assertRaises(ValueError, t, l-1)
+##            self.assertRaises(ValueError, t, h+1)
+
+    def test_from_param(self):
+        # the from_param class method attribute always
+        # returns PyCArgObject instances
+        for t in signed_types + unsigned_types + float_types:
+            self.failUnlessEqual(ArgType, type(t.from_param(0)))
+
+    def test_byref(self):
+        # calling byref returns also a PyCArgObject instance
+        for t in signed_types + unsigned_types + float_types:
+            parm = byref(t())
+            self.failUnlessEqual(ArgType, type(parm))
+
+
+    def test_floats(self):
+        # c_float and c_double can be created from
+        # Python int, long and float
+        for t in float_types:
+            self.failUnlessEqual(t(2.0).value, 2.0)
+            self.failUnlessEqual(t(2).value, 2.0)
+            self.failUnlessEqual(t(2L).value, 2.0)
+
+    def test_integers(self):
+        # integers cannot be constructed from floats
+        for t in signed_types + unsigned_types:
+            self.assertRaises(TypeError, t, 3.14)
+
+    def test_sizes(self):
+        for t in signed_types + unsigned_types + float_types:
+            size = struct.calcsize(t._type_)
+            # sizeof of the type...
+            self.failUnlessEqual(sizeof(t), size)
+            # and sizeof of an instance
+            self.failUnlessEqual(sizeof(t()), size)
+
+    def test_alignments(self):
+        for t in signed_types + unsigned_types + float_types:
+            code = t._type_ # the typecode
+            align = struct.calcsize("c%c" % code) - struct.calcsize(code)
+
+            # alignment of the type...
+            self.failUnlessEqual((code, alignment(t)),
+                                 (code, align))
+            # and alignment of an instance
+            self.failUnlessEqual((code, alignment(t())),
+                                 (code, align))
+
+    def test_int_from_address(self):
+        from array import array
+        for t in signed_types + unsigned_types:
+            # the array module doesn't suppport all format codes
+            # (no 'q' or 'Q')
+            try:
+                array(t._type_)
+            except ValueError:
+                continue
+            a = array(t._type_, [100])
+
+            # v now is an integer at an 'external' memory location
+            v = t.from_address(a.buffer_info()[0])
+            self.failUnlessEqual(v.value, a[0])
+            self.failUnlessEqual(type(v), t)
+
+            # changing the value at the memory location changes v's value also
+            a[0] = 42
+            self.failUnlessEqual(v.value, a[0])
+
+
+    def test_float_from_address(self):
+        from array import array
+        for t in float_types:
+            a = array(t._type_, [3.14])
+            v = t.from_address(a.buffer_info()[0])
+            self.failUnlessEqual(v.value, a[0])
+            self.failUnless(type(v) is t)
+            a[0] = 2.3456e17
+            self.failUnlessEqual(v.value, a[0])
+            self.failUnless(type(v) is t)
+
+    def test_char_from_address(self):
+        from ctypes import c_char
+        from array import array
+
+        a = array('c', 'x')
+        v = c_char.from_address(a.buffer_info()[0])
+        self.failUnlessEqual(v.value, a[0])
+        self.failUnless(type(v) is c_char)
+
+        a[0] = '?'
+        self.failUnlessEqual(v.value, a[0])
+
+    def test_init(self):
+        # c_int() can be initialized from Python's int, and c_int.
+        # Not from c_long or so, which seems strange, abd should
+        # probably be changed:
+        self.assertRaises(TypeError, c_int, c_long(42))
+
+##    def test_perf(self):
+##        check_perf()
+
+from ctypes import _SimpleCData
+class c_int_S(_SimpleCData):
+    _type_ = "i"
+    __slots__ = []
+
+def run_test(rep, msg, func, arg=None):
+##    items = [None] * rep
+    items = range(rep)
+    from time import clock
+    if arg is not None:
+        start = clock()
+        for i in items:
+            func(arg); func(arg); func(arg); func(arg); func(arg)
+        stop = clock()
+    else:
+        start = clock()
+        for i in items:
+            func(); func(); func(); func(); func()
+        stop = clock()
+    print "%15s: %.2f us" % (msg, ((stop-start)*1e6/5/rep))
+
+def check_perf():
+    # Construct 5 objects
+    from ctypes import c_int
+
+    REP = 200000
+
+    run_test(REP, "int()", int)
+    run_test(REP, "int(999)", int)
+    run_test(REP, "c_int()", c_int)
+    run_test(REP, "c_int(999)", c_int)
+    run_test(REP, "c_int_S()", c_int_S)
+    run_test(REP, "c_int_S(999)", c_int_S)
+
+# Python 2.3 -OO, win2k, P4 700 MHz:
+#
+#          int(): 0.87 us
+#       int(999): 0.87 us
+#        c_int(): 3.35 us
+#     c_int(999): 3.34 us
+#      c_int_S(): 3.23 us
+#   c_int_S(999): 3.24 us
+
+# Python 2.2 -OO, win2k, P4 700 MHz:
+#
+#          int(): 0.89 us
+#       int(999): 0.89 us
+#        c_int(): 9.99 us
+#     c_int(999): 10.02 us
+#      c_int_S(): 9.87 us
+#   c_int_S(999): 9.85 us
+
+if __name__ == '__main__':
+##    check_perf()
+    unittest.main()

Added: vendor/Python/current/Lib/ctypes/test/test_objects.py
===================================================================
--- vendor/Python/current/Lib/ctypes/test/test_objects.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/test/test_objects.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,70 @@
+r'''
+This tests the '_objects' attribute of ctypes instances.  '_objects'
+holds references to objects that must be kept alive as long as the
+ctypes instance, to make sure that the memory buffer is valid.
+
+WARNING: The '_objects' attribute is exposed ONLY for debugging ctypes itself,
+it MUST NEVER BE MODIFIED!
+
+'_objects' is initialized to a dictionary on first use, before that it
+is None.
+
+Here is an array of string pointers:
+
+>>> from ctypes import *
+>>> array = (c_char_p * 5)()
+>>> print array._objects
+None
+>>>
+
+The memory block stores pointers to strings, and the strings itself
+assigned from Python must be kept.
+
+>>> array[4] = 'foo bar'
+>>> array._objects
+{'4': 'foo bar'}
+>>> array[4]
+'foo bar'
+>>>
+
+It gets more complicated when the ctypes instance itself is contained
+in a 'base' object.
+
+>>> class X(Structure):
+...     _fields_ = [("x", c_int), ("y", c_int), ("array", c_char_p * 5)]
+...
+>>> x = X()
+>>> print x._objects
+None
+>>>
+
+The'array' attribute of the 'x' object shares part of the memory buffer
+of 'x' ('_b_base_' is either None, or the root object owning the memory block):
+
+>>> print x.array._b_base_ # doctest: +ELLIPSIS
+<ctypes.test.test_objects.X object at 0x...>
+>>>
+
+>>> x.array[0] = 'spam spam spam'
+>>> x._objects
+{'0:2': 'spam spam spam'}
+>>> x.array._b_base_._objects
+{'0:2': 'spam spam spam'}
+>>>
+
+'''
+
+import unittest, doctest, sys
+
+import ctypes.test.test_objects
+
+class TestCase(unittest.TestCase):
+    if sys.hexversion > 0x02040000:
+        # Python 2.3 has no ELLIPSIS flag, so we don't test with this
+        # version:
+        def test(self):
+            doctest.testmod(ctypes.test.test_objects)
+
+if __name__ == '__main__':
+    if sys.hexversion > 0x02040000:
+        doctest.testmod(ctypes.test.test_objects)

Added: vendor/Python/current/Lib/ctypes/test/test_parameters.py
===================================================================
--- vendor/Python/current/Lib/ctypes/test/test_parameters.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/test/test_parameters.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,188 @@
+import unittest, sys
+
+class SimpleTypesTestCase(unittest.TestCase):
+
+    def setUp(self):
+        import ctypes
+        try:
+            from _ctypes import set_conversion_mode
+        except ImportError:
+            pass
+        else:
+            self.prev_conv_mode = set_conversion_mode("ascii", "strict")
+
+    def tearDown(self):
+        try:
+            from _ctypes import set_conversion_mode
+        except ImportError:
+            pass
+        else:
+            set_conversion_mode(*self.prev_conv_mode)
+
+
+    def test_subclasses(self):
+        from ctypes import c_void_p, c_char_p
+        # ctypes 0.9.5 and before did overwrite from_param in SimpleType_new
+        class CVOIDP(c_void_p):
+            def from_param(cls, value):
+                return value * 2
+            from_param = classmethod(from_param)
+
+        class CCHARP(c_char_p):
+            def from_param(cls, value):
+                return value * 4
+            from_param = classmethod(from_param)
+
+        self.failUnlessEqual(CVOIDP.from_param("abc"), "abcabc")
+        self.failUnlessEqual(CCHARP.from_param("abc"), "abcabcabcabc")
+
+        try:
+            from ctypes import c_wchar_p
+        except ImportError:
+            return
+
+        class CWCHARP(c_wchar_p):
+            def from_param(cls, value):
+                return value * 3
+            from_param = classmethod(from_param)
+
+        self.failUnlessEqual(CWCHARP.from_param("abc"), "abcabcabc")
+
+    # XXX Replace by c_char_p tests
+    def test_cstrings(self):
+        from ctypes import c_char_p, byref
+
+        # c_char_p.from_param on a Python String packs the string
+        # into a cparam object
+        s = "123"
+        self.failUnless(c_char_p.from_param(s)._obj is s)
+
+        # new in 0.9.1: convert (encode) unicode to ascii
+        self.failUnlessEqual(c_char_p.from_param(u"123")._obj, "123")
+        self.assertRaises(UnicodeEncodeError, c_char_p.from_param, u"123\377")
+
+        self.assertRaises(TypeError, c_char_p.from_param, 42)
+
+        # calling c_char_p.from_param with a c_char_p instance
+        # returns the argument itself:
+        a = c_char_p("123")
+        self.failUnless(c_char_p.from_param(a) is a)
+
+    def test_cw_strings(self):
+        from ctypes import byref
+        try:
+            from ctypes import c_wchar_p
+        except ImportError:
+##            print "(No c_wchar_p)"
+            return
+        s = u"123"
+        if sys.platform == "win32":
+            self.failUnless(c_wchar_p.from_param(s)._obj is s)
+            self.assertRaises(TypeError, c_wchar_p.from_param, 42)
+
+            # new in 0.9.1: convert (decode) ascii to unicode
+            self.failUnlessEqual(c_wchar_p.from_param("123")._obj, u"123")
+        self.assertRaises(UnicodeDecodeError, c_wchar_p.from_param, "123\377")
+
+        pa = c_wchar_p.from_param(c_wchar_p(u"123"))
+        self.failUnlessEqual(type(pa), c_wchar_p)
+
+    def test_int_pointers(self):
+        from ctypes import c_short, c_uint, c_int, c_long, POINTER, pointer
+        LPINT = POINTER(c_int)
+
+##        p = pointer(c_int(42))
+##        x = LPINT.from_param(p)
+        x = LPINT.from_param(pointer(c_int(42)))
+        self.failUnlessEqual(x.contents.value, 42)
+        self.failUnlessEqual(LPINT(c_int(42)).contents.value, 42)
+
+        self.failUnlessEqual(LPINT.from_param(None), 0)
+
+        if c_int != c_long:
+            self.assertRaises(TypeError, LPINT.from_param, pointer(c_long(42)))
+        self.assertRaises(TypeError, LPINT.from_param, pointer(c_uint(42)))
+        self.assertRaises(TypeError, LPINT.from_param, pointer(c_short(42)))
+
+    def test_byref_pointer(self):
+        # The from_param class method of POINTER(typ) classes accepts what is
+        # returned by byref(obj), it type(obj) == typ
+        from ctypes import c_short, c_uint, c_int, c_long, pointer, POINTER, byref
+        LPINT = POINTER(c_int)
+
+        LPINT.from_param(byref(c_int(42)))
+
+        self.assertRaises(TypeError, LPINT.from_param, byref(c_short(22)))
+        if c_int != c_long:
+            self.assertRaises(TypeError, LPINT.from_param, byref(c_long(22)))
+        self.assertRaises(TypeError, LPINT.from_param, byref(c_uint(22)))
+
+    def test_byref_pointerpointer(self):
+        # See above
+        from ctypes import c_short, c_uint, c_int, c_long, pointer, POINTER, byref
+
+        LPLPINT = POINTER(POINTER(c_int))
+        LPLPINT.from_param(byref(pointer(c_int(42))))
+
+        self.assertRaises(TypeError, LPLPINT.from_param, byref(pointer(c_short(22))))
+        if c_int != c_long:
+            self.assertRaises(TypeError, LPLPINT.from_param, byref(pointer(c_long(22))))
+        self.assertRaises(TypeError, LPLPINT.from_param, byref(pointer(c_uint(22))))
+
+    def test_array_pointers(self):
+        from ctypes import c_short, c_uint, c_int, c_long, POINTER
+        INTARRAY = c_int * 3
+        ia = INTARRAY()
+        self.failUnlessEqual(len(ia), 3)
+        self.failUnlessEqual([ia[i] for i in range(3)], [0, 0, 0])
+
+        # Pointers are only compatible with arrays containing items of
+        # the same type!
+        LPINT = POINTER(c_int)
+        LPINT.from_param((c_int*3)())
+        self.assertRaises(TypeError, LPINT.from_param, c_short*3)
+        self.assertRaises(TypeError, LPINT.from_param, c_long*3)
+        self.assertRaises(TypeError, LPINT.from_param, c_uint*3)
+
+##    def test_performance(self):
+##        check_perf()
+
+    def test_noctypes_argtype(self):
+        import _ctypes_test
+        from ctypes import CDLL, c_void_p, ArgumentError
+
+        func = CDLL(_ctypes_test.__file__)._testfunc_p_p
+        func.restype = c_void_p
+        # TypeError: has no from_param method
+        self.assertRaises(TypeError, setattr, func, "argtypes", (object,))
+
+        class Adapter(object):
+            def from_param(cls, obj):
+                return None
+
+        func.argtypes = (Adapter(),)
+        self.failUnlessEqual(func(None), None)
+        self.failUnlessEqual(func(object()), None)
+
+        class Adapter(object):
+            def from_param(cls, obj):
+                return obj
+
+        func.argtypes = (Adapter(),)
+        # don't know how to convert parameter 1
+        self.assertRaises(ArgumentError, func, object())
+        self.failUnlessEqual(func(c_void_p(42)), 42)
+
+        class Adapter(object):
+            def from_param(cls, obj):
+                raise ValueError(obj)
+
+        func.argtypes = (Adapter(),)
+        # ArgumentError: argument 1: ValueError: 99
+        self.assertRaises(ArgumentError, func, 99)
+
+
+################################################################
+
+if __name__ == '__main__':
+    unittest.main()

Added: vendor/Python/current/Lib/ctypes/test/test_pointers.py
===================================================================
--- vendor/Python/current/Lib/ctypes/test/test_pointers.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/test/test_pointers.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,179 @@
+import unittest
+
+from ctypes import *
+import _ctypes_test
+
+ctype_types = [c_byte, c_ubyte, c_short, c_ushort, c_int, c_uint,
+                 c_long, c_ulong, c_longlong, c_ulonglong, c_double, c_float]
+python_types = [int, int, int, int, int, long,
+                int, long, long, long, float, float]
+
+class PointersTestCase(unittest.TestCase):
+
+    def test_pointer_crash(self):
+
+        class A(POINTER(c_ulong)):
+            pass
+
+        POINTER(c_ulong)(c_ulong(22))
+        # Pointer can't set contents: has no _type_
+        self.failUnlessRaises(TypeError, A, c_ulong(33))
+
+    def test_pass_pointers(self):
+        dll = CDLL(_ctypes_test.__file__)
+        func = dll._testfunc_p_p
+        func.restype = c_long
+
+        i = c_int(12345678)
+##        func.argtypes = (POINTER(c_int),)
+        address = func(byref(i))
+        self.failUnlessEqual(c_int.from_address(address).value, 12345678)
+
+        func.restype = POINTER(c_int)
+        res = func(pointer(i))
+        self.failUnlessEqual(res.contents.value, 12345678)
+        self.failUnlessEqual(res[0], 12345678)
+
+    def test_change_pointers(self):
+        dll = CDLL(_ctypes_test.__file__)
+        func = dll._testfunc_p_p
+
+        i = c_int(87654)
+        func.restype = POINTER(c_int)
+        func.argtypes = (POINTER(c_int),)
+
+        res = func(pointer(i))
+        self.failUnlessEqual(res[0], 87654)
+        self.failUnlessEqual(res.contents.value, 87654)
+
+        # C code: *res = 54345
+        res[0] = 54345
+        self.failUnlessEqual(i.value, 54345)
+
+        # C code:
+        #   int x = 12321;
+        #   res = &x
+        res.contents = c_int(12321)
+        self.failUnlessEqual(i.value, 54345)
+
+    def test_callbacks_with_pointers(self):
+        # a function type receiving a pointer
+        PROTOTYPE = CFUNCTYPE(c_int, POINTER(c_int))
+
+        self.result = []
+
+        def func(arg):
+            for i in range(10):
+##                print arg[i],
+                self.result.append(arg[i])
+##            print
+            return 0
+        callback = PROTOTYPE(func)
+
+        dll = CDLL(_ctypes_test.__file__)
+        # This function expects a function pointer,
+        # and calls this with an integer pointer as parameter.
+        # The int pointer points to a table containing the numbers 1..10
+        doit = dll._testfunc_callback_with_pointer
+
+##        i = c_int(42)
+##        callback(byref(i))
+##        self.failUnless(i.value == 84)
+
+        doit(callback)
+##        print self.result
+        doit(callback)
+##        print self.result
+
+    def test_basics(self):
+        from operator import delitem
+        for ct, pt in zip(ctype_types, python_types):
+            i = ct(42)
+            p = pointer(i)
+##            print type(p.contents), ct
+            self.failUnless(type(p.contents) is ct)
+            # p.contents is the same as p[0]
+##            print p.contents
+##            self.failUnless(p.contents == 42)
+##            self.failUnless(p[0] == 42)
+
+            self.assertRaises(TypeError, delitem, p, 0)
+
+    def test_from_address(self):
+        from array import array
+        a = array('i', [100, 200, 300, 400, 500])
+        addr = a.buffer_info()[0]
+
+        p = POINTER(POINTER(c_int))
+##        print dir(p)
+##        print p.from_address
+##        print p.from_address(addr)[0][0]
+
+    def test_other(self):
+        class Table(Structure):
+            _fields_ = [("a", c_int),
+                        ("b", c_int),
+                        ("c", c_int)]
+
+        pt = pointer(Table(1, 2, 3))
+
+        self.failUnlessEqual(pt.contents.a, 1)
+        self.failUnlessEqual(pt.contents.b, 2)
+        self.failUnlessEqual(pt.contents.c, 3)
+
+        pt.contents.c = 33
+
+        from ctypes import _pointer_type_cache
+        del _pointer_type_cache[Table]
+
+    def test_basic(self):
+        p = pointer(c_int(42))
+        # Although a pointer can be indexed, it ha no length
+        self.assertRaises(TypeError, len, p)
+        self.failUnlessEqual(p[0], 42)
+        self.failUnlessEqual(p.contents.value, 42)
+
+    def test_charpp(self):
+        """Test that a character pointer-to-pointer is correctly passed"""
+        dll = CDLL(_ctypes_test.__file__)
+        func = dll._testfunc_c_p_p
+        func.restype = c_char_p
+        argv = (c_char_p * 2)()
+        argc = c_int( 2 )
+        argv[0] = 'hello'
+        argv[1] = 'world'
+        result = func( byref(argc), argv )
+        assert result == 'world', result
+
+    def test_bug_1467852(self):
+        # http://sourceforge.net/tracker/?func=detail&atid=532154&aid=1467852&group_id=71702
+        x = c_int(5)
+        dummy = []
+        for i in range(32000):
+            dummy.append(c_int(i))
+        y = c_int(6)
+        p = pointer(x)
+        pp = pointer(p)
+        q = pointer(y)
+        pp[0] = q         # <==
+        self.failUnlessEqual(p[0], 6)
+    def test_c_void_p(self):
+        # http://sourceforge.net/tracker/?func=detail&aid=1518190&group_id=5470&atid=105470
+        if sizeof(c_void_p) == 4:
+            self.failUnlessEqual(c_void_p(0xFFFFFFFFL).value,
+                                 c_void_p(-1).value)
+            self.failUnlessEqual(c_void_p(0xFFFFFFFFFFFFFFFFL).value,
+                                 c_void_p(-1).value)
+        elif sizeof(c_void_p) == 8:
+            self.failUnlessEqual(c_void_p(0xFFFFFFFFL).value,
+                                 0xFFFFFFFFL)
+            self.failUnlessEqual(c_void_p(0xFFFFFFFFFFFFFFFFL).value,
+                                 c_void_p(-1).value)
+            self.failUnlessEqual(c_void_p(0xFFFFFFFFFFFFFFFFFFFFFFFFL).value,
+                                 c_void_p(-1).value)
+
+        self.assertRaises(TypeError, c_void_p, 3.14) # make sure floats are NOT accepted
+        self.assertRaises(TypeError, c_void_p, object()) # nor other objects
+
+if __name__ == '__main__':
+    unittest.main()

Added: vendor/Python/current/Lib/ctypes/test/test_prototypes.py
===================================================================
--- vendor/Python/current/Lib/ctypes/test/test_prototypes.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/test/test_prototypes.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,203 @@
+from ctypes import *
+import unittest
+
+# IMPORTANT INFO:
+#
+# Consider this call:
+#    func.restype = c_char_p
+#    func(c_char_p("123"))
+# It returns
+#    "123"
+#
+# WHY IS THIS SO?
+#
+# argument tuple (c_char_p("123"), ) is destroyed after the function
+# func is called, but NOT before the result is actually built.
+#
+# If the arglist would be destroyed BEFORE the result has been built,
+# the c_char_p("123") object would already have a zero refcount,
+# and the pointer passed to (and returned by) the function would
+# probably point to deallocated space.
+#
+# In this case, there would have to be an additional reference to the argument...
+
+import _ctypes_test
+testdll = CDLL(_ctypes_test.__file__)
+
+# Return machine address `a` as a (possibly long) non-negative integer.
+# Starting with Python 2.5, id(anything) is always non-negative, and
+# the ctypes addressof() inherits that via PyLong_FromVoidPtr().
+def positive_address(a):
+    if a >= 0:
+        return a
+    # View the bits in `a` as unsigned instead.
+    import struct
+    num_bits = struct.calcsize("P") * 8 # num bits in native machine address
+    a += 1L << num_bits
+    assert a >= 0
+    return a
+
+def c_wbuffer(init):
+    n = len(init) + 1
+    return (c_wchar * n)(*init)
+
+class CharPointersTestCase(unittest.TestCase):
+
+    def setUp(self):
+        func = testdll._testfunc_p_p
+        func.restype = c_long
+        func.argtypes = None
+
+    def test_int_pointer_arg(self):
+        func = testdll._testfunc_p_p
+        func.restype = c_long
+        self.failUnlessEqual(0, func(0))
+
+        ci = c_int(0)
+
+        func.argtypes = POINTER(c_int),
+        self.failUnlessEqual(positive_address(addressof(ci)),
+                             positive_address(func(byref(ci))))
+
+        func.argtypes = c_char_p,
+        self.assertRaises(ArgumentError, func, byref(ci))
+
+        func.argtypes = POINTER(c_short),
+        self.assertRaises(ArgumentError, func, byref(ci))
+
+        func.argtypes = POINTER(c_double),
+        self.assertRaises(ArgumentError, func, byref(ci))
+
+    def test_POINTER_c_char_arg(self):
+        func = testdll._testfunc_p_p
+        func.restype = c_char_p
+        func.argtypes = POINTER(c_char),
+
+        self.failUnlessEqual(None, func(None))
+        self.failUnlessEqual("123", func("123"))
+        self.failUnlessEqual(None, func(c_char_p(None)))
+        self.failUnlessEqual("123", func(c_char_p("123")))
+
+        self.failUnlessEqual("123", func(c_buffer("123")))
+        ca = c_char("a")
+        self.failUnlessEqual("a", func(pointer(ca))[0])
+        self.failUnlessEqual("a", func(byref(ca))[0])
+
+    def test_c_char_p_arg(self):
+        func = testdll._testfunc_p_p
+        func.restype = c_char_p
+        func.argtypes = c_char_p,
+
+        self.failUnlessEqual(None, func(None))
+        self.failUnlessEqual("123", func("123"))
+        self.failUnlessEqual(None, func(c_char_p(None)))
+        self.failUnlessEqual("123", func(c_char_p("123")))
+
+        self.failUnlessEqual("123", func(c_buffer("123")))
+        ca = c_char("a")
+        self.failUnlessEqual("a", func(pointer(ca))[0])
+        self.failUnlessEqual("a", func(byref(ca))[0])
+
+    def test_c_void_p_arg(self):
+        func = testdll._testfunc_p_p
+        func.restype = c_char_p
+        func.argtypes = c_void_p,
+
+        self.failUnlessEqual(None, func(None))
+        self.failUnlessEqual("123", func("123"))
+        self.failUnlessEqual("123", func(c_char_p("123")))
+        self.failUnlessEqual(None, func(c_char_p(None)))
+
+        self.failUnlessEqual("123", func(c_buffer("123")))
+        ca = c_char("a")
+        self.failUnlessEqual("a", func(pointer(ca))[0])
+        self.failUnlessEqual("a", func(byref(ca))[0])
+
+        func(byref(c_int()))
+        func(pointer(c_int()))
+        func((c_int * 3)())
+
+        try:
+            func.restype = c_wchar_p
+        except NameError:
+            pass
+        else:
+            self.failUnlessEqual(None, func(c_wchar_p(None)))
+            self.failUnlessEqual(u"123", func(c_wchar_p(u"123")))
+
+    def test_instance(self):
+        func = testdll._testfunc_p_p
+        func.restype = c_void_p
+
+        class X:
+            _as_parameter_ = None
+
+        func.argtypes = c_void_p,
+        self.failUnlessEqual(None, func(X()))
+
+        func.argtypes = None
+        self.failUnlessEqual(None, func(X()))
+
+try:
+    c_wchar
+except NameError:
+    pass
+else:
+    class WCharPointersTestCase(unittest.TestCase):
+
+        def setUp(self):
+            func = testdll._testfunc_p_p
+            func.restype = c_int
+            func.argtypes = None
+
+
+        def test_POINTER_c_wchar_arg(self):
+            func = testdll._testfunc_p_p
+            func.restype = c_wchar_p
+            func.argtypes = POINTER(c_wchar),
+
+            self.failUnlessEqual(None, func(None))
+            self.failUnlessEqual(u"123", func(u"123"))
+            self.failUnlessEqual(None, func(c_wchar_p(None)))
+            self.failUnlessEqual(u"123", func(c_wchar_p(u"123")))
+
+            self.failUnlessEqual(u"123", func(c_wbuffer(u"123")))
+            ca = c_wchar("a")
+            self.failUnlessEqual(u"a", func(pointer(ca))[0])
+            self.failUnlessEqual(u"a", func(byref(ca))[0])
+
+        def test_c_wchar_p_arg(self):
+            func = testdll._testfunc_p_p
+            func.restype = c_wchar_p
+            func.argtypes = c_wchar_p,
+
+            c_wchar_p.from_param(u"123")
+
+            self.failUnlessEqual(None, func(None))
+            self.failUnlessEqual("123", func(u"123"))
+            self.failUnlessEqual(None, func(c_wchar_p(None)))
+            self.failUnlessEqual("123", func(c_wchar_p("123")))
+
+            # XXX Currently, these raise TypeErrors, although they shouldn't:
+            self.failUnlessEqual("123", func(c_wbuffer("123")))
+            ca = c_wchar("a")
+            self.failUnlessEqual("a", func(pointer(ca))[0])
+            self.failUnlessEqual("a", func(byref(ca))[0])
+
+class ArrayTest(unittest.TestCase):
+    def test(self):
+        func = testdll._testfunc_ai8
+        func.restype = POINTER(c_int)
+        func.argtypes = c_int * 8,
+
+        func((c_int * 8)(1, 2, 3, 4, 5, 6, 7, 8))
+
+        # This did crash before:
+
+        def func(): pass
+        CFUNCTYPE(None, c_int * 3)(func)
+
+################################################################
+
+if __name__ == '__main__':
+    unittest.main()

Added: vendor/Python/current/Lib/ctypes/test/test_python_api.py
===================================================================
--- vendor/Python/current/Lib/ctypes/test/test_python_api.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/test/test_python_api.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,87 @@
+from ctypes import *
+import unittest, sys
+from ctypes.test import is_resource_enabled
+
+################################################################
+# This section should be moved into ctypes\__init__.py, when it's ready.
+
+from _ctypes import PyObj_FromPtr
+
+################################################################
+
+from sys import getrefcount as grc
+
+
+class PythonAPITestCase(unittest.TestCase):
+
+    def test_PyString_FromStringAndSize(self):
+        PyString_FromStringAndSize = pythonapi.PyString_FromStringAndSize
+
+        PyString_FromStringAndSize.restype = py_object
+        PyString_FromStringAndSize.argtypes = c_char_p, c_int
+
+        self.failUnlessEqual(PyString_FromStringAndSize("abcdefghi", 3), "abc")
+
+    def test_PyString_FromString(self):
+        pythonapi.PyString_FromString.restype = py_object
+        pythonapi.PyString_FromString.argtypes = (c_char_p,)
+
+        s = "abc"
+        refcnt = grc(s)
+        pyob = pythonapi.PyString_FromString(s)
+        self.failUnlessEqual(grc(s), refcnt)
+        self.failUnlessEqual(s, pyob)
+        del pyob
+        self.failUnlessEqual(grc(s), refcnt)
+
+    if is_resource_enabled("refcount"):
+        # This test is unreliable, because it is possible that code in
+        # unittest changes the refcount of the '42' integer.  So, it
+        # is disabled by default.
+        def test_PyInt_Long(self):
+            ref42 = grc(42)
+            pythonapi.PyInt_FromLong.restype = py_object
+            self.failUnlessEqual(pythonapi.PyInt_FromLong(42), 42)
+
+            self.failUnlessEqual(grc(42), ref42)
+
+            pythonapi.PyInt_AsLong.argtypes = (py_object,)
+            pythonapi.PyInt_AsLong.restype = c_long
+
+            res = pythonapi.PyInt_AsLong(42)
+            self.failUnlessEqual(grc(res), ref42 + 1)
+            del res
+            self.failUnlessEqual(grc(42), ref42)
+
+    def test_PyObj_FromPtr(self):
+        s = "abc def ghi jkl"
+        ref = grc(s)
+        # id(python-object) is the address
+        pyobj = PyObj_FromPtr(id(s))
+        self.failUnless(s is pyobj)
+
+        self.failUnlessEqual(grc(s), ref + 1)
+        del pyobj
+        self.failUnlessEqual(grc(s), ref)
+
+    def test_PyOS_snprintf(self):
+        PyOS_snprintf = pythonapi.PyOS_snprintf
+        PyOS_snprintf.argtypes = POINTER(c_char), c_int, c_char_p
+
+        buf = c_buffer(256)
+        PyOS_snprintf(buf, sizeof(buf), "Hello from %s", "ctypes")
+        self.failUnlessEqual(buf.value, "Hello from ctypes")
+
+        PyOS_snprintf(buf, sizeof(buf), "Hello from %s", "ctypes", 1, 2, 3)
+        self.failUnlessEqual(buf.value, "Hello from ctypes")
+
+        # not enough arguments
+        self.failUnlessRaises(TypeError, PyOS_snprintf, buf)
+
+    def test_pyobject_repr(self):
+        self.failUnlessEqual(repr(py_object()), "py_object(<NULL>)")
+        self.failUnlessEqual(repr(py_object(42)), "py_object(42)")
+        self.failUnlessEqual(repr(py_object(object)), "py_object(%r)" % object)
+
+if __name__ == "__main__":
+    unittest.main()

Added: vendor/Python/current/Lib/ctypes/test/test_random_things.py
===================================================================
--- vendor/Python/current/Lib/ctypes/test/test_random_things.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/test/test_random_things.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,71 @@
+from ctypes import *
+import unittest, sys
+
+def callback_func(arg):
+    42 / arg
+    raise ValueError, arg
+
+if sys.platform == "win32":
+
+    class call_function_TestCase(unittest.TestCase):
+        # _ctypes.call_function is deprecated and private, but used by
+        # Gary Bishp's readline module.  If we have it, we must test it as well.
+
+        def test(self):
+            from _ctypes import call_function
+            hdll = windll.kernel32.LoadLibraryA("kernel32")
+            funcaddr = windll.kernel32.GetProcAddress(hdll, "GetModuleHandleA")
+
+            self.failUnlessEqual(call_function(funcaddr, (None,)),
+                                 windll.kernel32.GetModuleHandleA(None))
+
+class CallbackTracbackTestCase(unittest.TestCase):
+    # When an exception is raised in a ctypes callback function, the C
+    # code prints a traceback.
+    #
+    # This test makes sure the exception types *and* the exception
+    # value is printed correctly.
+    #
+    # Changed in 0.9.3: No longer is '(in callback)' prepended to the
+    # error message - instead a additional frame for the C code is
+    # created, then a full traceback printed.  When SystemExit is
+    # raised in a callback function, the interpreter exits.
+
+    def capture_stderr(self, func, *args, **kw):
+        # helper - call function 'func', and return the captured stderr
+        import StringIO
+        old_stderr = sys.stderr
+        logger = sys.stderr = StringIO.StringIO()
+        try:
+            func(*args, **kw)
+        finally:
+            sys.stderr = old_stderr
+        return logger.getvalue()
+
+    def test_ValueError(self):
+        cb = CFUNCTYPE(c_int, c_int)(callback_func)
+        out = self.capture_stderr(cb, 42)
+        self.failUnlessEqual(out.splitlines()[-1],
+                             "ValueError: 42")
+
+    def test_IntegerDivisionError(self):
+        cb = CFUNCTYPE(c_int, c_int)(callback_func)
+        out = self.capture_stderr(cb, 0)
+        self.failUnlessEqual(out.splitlines()[-1][:19],
+                             "ZeroDivisionError: ")
+
+    def test_FloatDivisionError(self):
+        cb = CFUNCTYPE(c_int, c_double)(callback_func)
+        out = self.capture_stderr(cb, 0.0)
+        self.failUnlessEqual(out.splitlines()[-1][:19],
+                             "ZeroDivisionError: ")
+
+    def test_TypeErrorDivisionError(self):
+        cb = CFUNCTYPE(c_int, c_char_p)(callback_func)
+        out = self.capture_stderr(cb, "spam")
+        self.failUnlessEqual(out.splitlines()[-1],
+                             "TypeError: "
+                             "unsupported operand type(s) for /: 'int' and 'str'")
+
+if __name__ == '__main__':
+    unittest.main()

Added: vendor/Python/current/Lib/ctypes/test/test_refcounts.py
===================================================================
--- vendor/Python/current/Lib/ctypes/test/test_refcounts.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/test/test_refcounts.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,98 @@
+import unittest
+import ctypes
+import gc
+
+MyCallback = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int)
+OtherCallback = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int, ctypes.c_ulonglong)
+
+import _ctypes_test
+dll = ctypes.CDLL(_ctypes_test.__file__)
+
+class RefcountTestCase(unittest.TestCase):
+
+    def test_1(self):
+        from sys import getrefcount as grc
+
+        f = dll._testfunc_callback_i_if
+        f.restype = ctypes.c_int
+        f.argtypes = [ctypes.c_int, MyCallback]
+
+        def callback(value):
+            #print "called back with", value
+            return value
+
+        self.failUnlessEqual(grc(callback), 2)
+        cb = MyCallback(callback)
+
+        self.failUnless(grc(callback) > 2)
+        result = f(-10, cb)
+        self.failUnlessEqual(result, -18)
+        cb = None
+
+        gc.collect()
+
+        self.failUnlessEqual(grc(callback), 2)
+
+
+    def test_refcount(self):
+        from sys import getrefcount as grc
+        def func(*args):
+            pass
+        # this is the standard refcount for func
+        self.failUnlessEqual(grc(func), 2)
+
+        # the CFuncPtr instance holds atr least one refcount on func:
+        f = OtherCallback(func)
+        self.failUnless(grc(func) > 2)
+
+        # and may release it again
+        del f
+        self.failUnless(grc(func) >= 2)
+
+        # but now it must be gone
+        gc.collect()
+        self.failUnless(grc(func) == 2)
+
+        class X(ctypes.Structure):
+            _fields_ = [("a", OtherCallback)]
+        x = X()
+        x.a = OtherCallback(func)
+
+        # the CFuncPtr instance holds atr least one refcount on func:
+        self.failUnless(grc(func) > 2)
+
+        # and may release it again
+        del x
+        self.failUnless(grc(func) >= 2)
+
+        # and now it must be gone again
+        gc.collect()
+        self.failUnlessEqual(grc(func), 2)
+
+        f = OtherCallback(func)
+
+        # the CFuncPtr instance holds atr least one refcount on func:
+        self.failUnless(grc(func) > 2)
+
+        # create a cycle
+        f.cycle = f
+
+        del f
+        gc.collect()
+        self.failUnlessEqual(grc(func), 2)
+
+class AnotherLeak(unittest.TestCase):
+    def test_callback(self):
+        import sys
+
+        proto = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int, ctypes.c_int)
+        def func(a, b):
+            return a * b * 2
+        f = proto(func)
+
+        a = sys.getrefcount(ctypes.c_int)
+        f(1, 2)
+        self.failUnlessEqual(sys.getrefcount(ctypes.c_int), a)
+
+if __name__ == '__main__':
+    unittest.main()

Added: vendor/Python/current/Lib/ctypes/test/test_repr.py
===================================================================
--- vendor/Python/current/Lib/ctypes/test/test_repr.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/test/test_repr.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,29 @@
+from ctypes import *
+import unittest
+
+subclasses = []
+for base in [c_byte, c_short, c_int, c_long, c_longlong,
+        c_ubyte, c_ushort, c_uint, c_ulong, c_ulonglong,
+        c_float, c_double]:
+    class X(base):
+        pass
+    subclasses.append(X)
+
+class X(c_char):
+    pass
+
+# This test checks if the __repr__ is correct for subclasses of simple types
+
+class ReprTest(unittest.TestCase):
+    def test_numbers(self):
+        for typ in subclasses:
+            base = typ.__bases__[0]
+            self.failUnless(repr(base(42)).startswith(base.__name__))
+            self.failUnlessEqual("<X object at", repr(typ(42))[:12])
+
+    def test_char(self):
+        self.failUnlessEqual("c_char('x')", repr(c_char('x')))
+        self.failUnlessEqual("<X object at", repr(X('x'))[:12])
+
+if __name__ == "__main__":
+    unittest.main()

Added: vendor/Python/current/Lib/ctypes/test/test_returnfuncptrs.py
===================================================================
--- vendor/Python/current/Lib/ctypes/test/test_returnfuncptrs.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/test/test_returnfuncptrs.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,35 @@
+import unittest
+from ctypes import *
+
+import _ctypes_test
+
+class ReturnFuncPtrTestCase(unittest.TestCase):
+
+    def test_with_prototype(self):
+        # The _ctypes_test shared lib/dll exports quite some functions for testing.
+        # The get_strchr function returns a *pointer* to the C strchr function.
+        dll = CDLL(_ctypes_test.__file__)
+        get_strchr = dll.get_strchr
+        get_strchr.restype = CFUNCTYPE(c_char_p, c_char_p, c_char)
+        strchr = get_strchr()
+        self.failUnlessEqual(strchr("abcdef", "b"), "bcdef")
+        self.failUnlessEqual(strchr("abcdef", "x"), None)
+        self.assertRaises(ArgumentError, strchr, "abcdef", 3)
+        self.assertRaises(TypeError, strchr, "abcdef")
+
+    def test_without_prototype(self):
+        dll = CDLL(_ctypes_test.__file__)
+        get_strchr = dll.get_strchr
+        # the default 'c_int' would not work on systems where sizeof(int) != sizeof(void *)
+        get_strchr.restype = c_void_p
+        addr = get_strchr()
+        # _CFuncPtr instances are now callable with an integer argument
+        # which denotes a function address:
+        strchr = CFUNCTYPE(c_char_p, c_char_p, c_char)(addr)
+        self.failUnless(strchr("abcdef", "b"), "bcdef")
+        self.failUnlessEqual(strchr("abcdef", "x"), None)
+        self.assertRaises(ArgumentError, strchr, "abcdef", 3)
+        self.assertRaises(TypeError, strchr, "abcdef")
+
+if __name__ == "__main__":
+    unittest.main()

Added: vendor/Python/current/Lib/ctypes/test/test_simplesubclasses.py
===================================================================
--- vendor/Python/current/Lib/ctypes/test/test_simplesubclasses.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/test/test_simplesubclasses.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,55 @@
+import unittest
+from ctypes import *
+
+class MyInt(c_int):
+    def __cmp__(self, other):
+        if type(other) != MyInt:
+            return -1
+        return cmp(self.value, other.value)
+
+class Test(unittest.TestCase):
+
+    def test_compare(self):
+        self.failUnlessEqual(MyInt(3), MyInt(3))
+        self.failIfEqual(MyInt(42), MyInt(43))
+
+    def test_ignore_retval(self):
+        # Test if the return value of a callback is ignored
+        # if restype is None
+        proto = CFUNCTYPE(None)
+        def func():
+            return (1, "abc", None)
+
+        cb = proto(func)
+        self.failUnlessEqual(None, cb())
+
+
+    def test_int_callback(self):
+        args = []
+        def func(arg):
+            args.append(arg)
+            return arg
+
+        cb = CFUNCTYPE(None, MyInt)(func)
+
+        self.failUnlessEqual(None, cb(42))
+        self.failUnlessEqual(type(args[-1]), MyInt)
+
+        cb = CFUNCTYPE(c_int, c_int)(func)
+
+        self.failUnlessEqual(42, cb(42))
+        self.failUnlessEqual(type(args[-1]), int)
+
+    def test_int_struct(self):
+        class X(Structure):
+            _fields_ = [("x", MyInt)]
+
+        self.failUnlessEqual(X().x, MyInt())
+
+        s = X()
+        s.x = MyInt(42)
+
+        self.failUnlessEqual(s.x, MyInt(42))
+
+if __name__ == "__main__":
+    unittest.main()

Added: vendor/Python/current/Lib/ctypes/test/test_sizes.py
===================================================================
--- vendor/Python/current/Lib/ctypes/test/test_sizes.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/test/test_sizes.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,27 @@
+# Test specifically-sized containers.
+
+import unittest
+from ctypes import *
+
+class SizesTestCase(unittest.TestCase):
+    def test_8(self):
+        self.failUnlessEqual(1, sizeof(c_int8))
+        self.failUnlessEqual(1, sizeof(c_uint8))
+
+    def test_16(self):
+        self.failUnlessEqual(2, sizeof(c_int16))
+        self.failUnlessEqual(2, sizeof(c_uint16))
+
+    def test_32(self):
+        self.failUnlessEqual(4, sizeof(c_int32))
+        self.failUnlessEqual(4, sizeof(c_uint32))
+
+    def test_64(self):
+        self.failUnlessEqual(8, sizeof(c_int64))
+        self.failUnlessEqual(8, sizeof(c_uint64))
+
+    def test_size_t(self):
+        self.failUnlessEqual(sizeof(c_void_p), sizeof(c_size_t))
+
+if __name__ == "__main__":
+    unittest.main()

Added: vendor/Python/current/Lib/ctypes/test/test_slicing.py
===================================================================
--- vendor/Python/current/Lib/ctypes/test/test_slicing.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/test/test_slicing.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,120 @@
+import unittest
+from ctypes import *
+
+import _ctypes_test
+
+class SlicesTestCase(unittest.TestCase):
+    def test_getslice_cint(self):
+        a = (c_int * 100)(*xrange(1100, 1200))
+        b = range(1100, 1200)
+        self.failUnlessEqual(a[0:2], b[0:2])
+        self.failUnlessEqual(len(a), len(b))
+        self.failUnlessEqual(a[5:7], b[5:7])
+        self.failUnlessEqual(a[-1], b[-1])
+        self.failUnlessEqual(a[:], b[:])
+
+        a[0:5] = range(5, 10)
+        self.failUnlessEqual(a[0:5], range(5, 10))
+
+    def test_setslice_cint(self):
+        a = (c_int * 100)(*xrange(1100, 1200))
+        b = range(1100, 1200)
+
+        a[32:47] = range(32, 47)
+        self.failUnlessEqual(a[32:47], range(32, 47))
+
+        from operator import setslice
+
+        # TypeError: int expected instead of str instance
+        self.assertRaises(TypeError, setslice, a, 0, 5, "abcde")
+        # TypeError: int expected instead of str instance
+        self.assertRaises(TypeError, setslice, a, 0, 5, ["a", "b", "c", "d", "e"])
+        # TypeError: int expected instead of float instance
+        self.assertRaises(TypeError, setslice, a, 0, 5, [1, 2, 3, 4, 3.14])
+        # ValueError: Can only assign sequence of same size
+        self.assertRaises(ValueError, setslice, a, 0, 5, range(32))
+
+    def test_char_ptr(self):
+        s = "abcdefghijklmnopqrstuvwxyz"
+
+        dll = CDLL(_ctypes_test.__file__)
+        dll.my_strdup.restype = POINTER(c_char)
+        dll.my_free.restype = None
+        res = dll.my_strdup(s)
+        self.failUnlessEqual(res[:len(s)], s)
+
+        import operator
+        self.assertRaises(TypeError, operator.setslice,
+                          res, 0, 5, u"abcde")
+        dll.my_free(res)
+
+        dll.my_strdup.restype = POINTER(c_byte)
+        res = dll.my_strdup(s)
+        self.failUnlessEqual(res[:len(s)], range(ord("a"), ord("z")+1))
+        dll.my_free(res)
+
+    def test_char_ptr_with_free(self):
+        dll = CDLL(_ctypes_test.__file__)
+        s = "abcdefghijklmnopqrstuvwxyz"
+
+        class allocated_c_char_p(c_char_p):
+            pass
+
+        dll.my_free.restype = None
+        def errcheck(result, func, args):
+            retval = result.value
+            dll.my_free(result)
+            return retval
+
+        dll.my_strdup.restype = allocated_c_char_p
+        dll.my_strdup.errcheck = errcheck
+        try:
+            res = dll.my_strdup(s)
+            self.failUnlessEqual(res, s)
+        finally:
+            del dll.my_strdup.errcheck
+
+
+    def test_char_array(self):
+        s = "abcdefghijklmnopqrstuvwxyz\0"
+
+        p = (c_char * 27)(*s)
+        self.failUnlessEqual(p[:], s)
+
+
+    try:
+        c_wchar
+    except NameError:
+        pass
+    else:
+        def test_wchar_ptr(self):
+            s = u"abcdefghijklmnopqrstuvwxyz\0"
+
+            dll = CDLL(_ctypes_test.__file__)
+            dll.my_wcsdup.restype = POINTER(c_wchar)
+            dll.my_wcsdup.argtypes = POINTER(c_wchar),
+            dll.my_free.restype = None
+            res = dll.my_wcsdup(s)
+            self.failUnlessEqual(res[:len(s)], s)
+
+            import operator
+            self.assertRaises(TypeError, operator.setslice,
+                              res, 0, 5, u"abcde")
+            dll.my_free(res)
+
+            if sizeof(c_wchar) == sizeof(c_short):
+                dll.my_wcsdup.restype = POINTER(c_short)
+            elif sizeof(c_wchar) == sizeof(c_int):
+                dll.my_wcsdup.restype = POINTER(c_int)
+            elif sizeof(c_wchar) == sizeof(c_long):
+                dll.my_wcsdup.restype = POINTER(c_long)
+            else:
+                return
+            res = dll.my_wcsdup(s)
+            self.failUnlessEqual(res[:len(s)-1], range(ord("a"), ord("z")+1))
+            dll.my_free(res)
+
+################################################################
+
+if __name__ == "__main__":
+    unittest.main()

Added: vendor/Python/current/Lib/ctypes/test/test_stringptr.py
===================================================================
--- vendor/Python/current/Lib/ctypes/test/test_stringptr.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/test/test_stringptr.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,75 @@
+import unittest
+from ctypes import *
+
+import _ctypes_test
+
+lib = CDLL(_ctypes_test.__file__)
+
+class StringPtrTestCase(unittest.TestCase):
+
+    def test__POINTER_c_char(self):
+        class X(Structure):
+            _fields_ = [("str", POINTER(c_char))]
+        x = X()
+
+        # NULL pointer access
+        self.assertRaises(ValueError, getattr, x.str, "contents")
+        b = c_buffer("Hello, World")
+        from sys import getrefcount as grc
+        self.failUnlessEqual(grc(b), 2)
+        x.str = b
+        self.failUnlessEqual(grc(b), 3)
+
+        # POINTER(c_char) and Python string is NOT compatible
+        # POINTER(c_char) and c_buffer() is compatible
+        for i in range(len(b)):
+            self.failUnlessEqual(b[i], x.str[i])
+
+        self.assertRaises(TypeError, setattr, x, "str", "Hello, World")
+
+    def test__c_char_p(self):
+        class X(Structure):
+            _fields_ = [("str", c_char_p)]
+        x = X()
+
+        # c_char_p and Python string is compatible
+        # c_char_p and c_buffer is NOT compatible
+        self.failUnlessEqual(x.str, None)
+        x.str = "Hello, World"
+        self.failUnlessEqual(x.str, "Hello, World")
+        b = c_buffer("Hello, World")
+        self.failUnlessRaises(TypeError, setattr, x, "str", b)
+
+
+    def test_functions(self):
+        strchr = lib.my_strchr
+        strchr.restype = c_char_p
+
+        # c_char_p and Python string is compatible
+        # c_char_p and c_buffer are now compatible
+        strchr.argtypes = c_char_p, c_char
+        self.failUnlessEqual(strchr("abcdef", "c"), "cdef")
+        self.failUnlessEqual(strchr(c_buffer("abcdef"), "c"), "cdef")
+
+        # POINTER(c_char) and Python string is NOT compatible
+        # POINTER(c_char) and c_buffer() is compatible
+        strchr.argtypes = POINTER(c_char), c_char
+        buf = c_buffer("abcdef")
+        self.failUnlessEqual(strchr(buf, "c"), "cdef")
+        self.failUnlessEqual(strchr("abcdef", "c"), "cdef")
+
+        # XXX These calls are dangerous, because the first argument
+        # to strchr is no longer valid after the function returns!
+        # So we must keep a reference to buf separately
+
+        strchr.restype = POINTER(c_char)
+        buf = c_buffer("abcdef")
+        r = strchr(buf, "c")
+        x = r[0], r[1], r[2], r[3], r[4]
+        self.failUnlessEqual(x, ("c", "d", "e", "f", "\000"))
+        del buf
+        # x1 will NOT be the same as x, usually:
+        x1 = r[0], r[1], r[2], r[3], r[4]
+
+if __name__ == '__main__':
+    unittest.main()

Added: vendor/Python/current/Lib/ctypes/test/test_strings.py
===================================================================
--- vendor/Python/current/Lib/ctypes/test/test_strings.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/test/test_strings.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,215 @@
+import unittest
+from ctypes import *
+
+class StringArrayTestCase(unittest.TestCase):
+    def test(self):
+        BUF = c_char * 4
+
+        buf = BUF("a", "b", "c")
+        self.failUnlessEqual(buf.value, "abc")
+        self.failUnlessEqual(buf.raw, "abc\000")
+
+        buf.value = "ABCD"
+        self.failUnlessEqual(buf.value, "ABCD")
+        self.failUnlessEqual(buf.raw, "ABCD")
+
+        buf.value = "x"
+        self.failUnlessEqual(buf.value, "x")
+        self.failUnlessEqual(buf.raw, "x\000CD")
+
+        buf[1] = "Z"
+        self.failUnlessEqual(buf.value, "xZCD")
+        self.failUnlessEqual(buf.raw, "xZCD")
+
+        self.assertRaises(ValueError, setattr, buf, "value", "aaaaaaaa")
+        self.assertRaises(TypeError, setattr, buf, "value", 42)
+
+    def test_c_buffer_value(self):
+        buf = c_buffer(32)
+
+        buf.value = "Hello, World"
+        self.failUnlessEqual(buf.value, "Hello, World")
+
+        self.failUnlessRaises(TypeError, setattr, buf, "value", buffer("Hello, World"))
+        self.assertRaises(TypeError, setattr, buf, "value", buffer("abc"))
+        self.assertRaises(ValueError, setattr, buf, "raw", buffer("x" * 100))
+
+    def test_c_buffer_raw(self):
+        buf = c_buffer(32)
+
+        buf.raw = buffer("Hello, World")
+        self.failUnlessEqual(buf.value, "Hello, World")
+        self.assertRaises(TypeError, setattr, buf, "value", buffer("abc"))
+        self.assertRaises(ValueError, setattr, buf, "raw", buffer("x" * 100))
+
+    def test_param_1(self):
+        BUF = c_char * 4
+        buf = BUF()
+##        print c_char_p.from_param(buf)
+
+    def test_param_2(self):
+        BUF = c_char * 4
+        buf = BUF()
+##        print BUF.from_param(c_char_p("python"))
+##        print BUF.from_param(BUF(*"pyth"))
+
+try:
+    c_wchar
+except NameError:
+    pass
+else:
+    class WStringArrayTestCase(unittest.TestCase):
+        def test(self):
+            BUF = c_wchar * 4
+
+            buf = BUF(u"a", u"b", u"c")
+            self.failUnlessEqual(buf.value, u"abc")
+
+            buf.value = u"ABCD"
+            self.failUnlessEqual(buf.value, u"ABCD")
+
+            buf.value = u"x"
+            self.failUnlessEqual(buf.value, u"x")
+
+            buf[1] = u"Z"
+            self.failUnlessEqual(buf.value, u"xZCD")
+
+class StringTestCase(unittest.TestCase):
+    def XX_test_basic_strings(self):
+        cs = c_string("abcdef")
+
+        # Cannot call len on a c_string any longer
+        self.assertRaises(TypeError, len, cs)
+        self.failUnlessEqual(sizeof(cs), 7)
+
+        # The value property is the string up to the first terminating NUL.
+        self.failUnlessEqual(cs.value, "abcdef")
+        self.failUnlessEqual(c_string("abc\000def").value, "abc")
+
+        # The raw property is the total buffer contents:
+        self.failUnlessEqual(cs.raw, "abcdef\000")
+        self.failUnlessEqual(c_string("abc\000def").raw, "abc\000def\000")
+
+        # We can change the value:
+        cs.value = "ab"
+        self.failUnlessEqual(cs.value, "ab")
+        self.failUnlessEqual(cs.raw, "ab\000\000\000\000\000")
+
+        cs.raw = "XY"
+        self.failUnlessEqual(cs.value, "XY")
+        self.failUnlessEqual(cs.raw, "XY\000\000\000\000\000")
+
+        self.assertRaises(TypeError, c_string, u"123")
+
+    def XX_test_sized_strings(self):
+
+        # New in releases later than 0.4.0:
+        self.assertRaises(TypeError, c_string, None)
+
+        # New in releases later than 0.4.0:
+        # c_string(number) returns an empty string of size number
+        self.failUnless(len(c_string(32).raw) == 32)
+        self.assertRaises(ValueError, c_string, -1)
+        self.assertRaises(ValueError, c_string, 0)
+
+        # These tests fail, because it is no longer initialized
+##        self.failUnless(c_string(2).value == "")
+##        self.failUnless(c_string(2).raw == "\000\000")
+        self.failUnless(c_string(2).raw[-1] == "\000")
+        self.failUnless(len(c_string(2).raw) == 2)
+
+    def XX_test_initialized_strings(self):
+
+        self.failUnless(c_string("ab", 4).raw[:2] == "ab")
+        self.failUnless(c_string("ab", 4).raw[-1] == "\000")
+        self.failUnless(c_string("ab", 2).raw == "a\000")
+
+    def XX_test_toolong(self):
+        cs = c_string("abcdef")
+        # Much too long string:
+        self.assertRaises(ValueError, setattr, cs, "value", "123456789012345")
+
+        # One char too long values:
+        self.assertRaises(ValueError, setattr, cs, "value", "1234567")
+
+##    def test_perf(self):
+##        check_perf()
+
+try:
+    c_wchar
+except NameError:
+    pass
+else:
+    class WStringTestCase(unittest.TestCase):
+        def test_wchar(self):
+            c_wchar(u"x")
+            repr(byref(c_wchar(u"x")))
+            c_wchar("x")
+
+
+        def X_test_basic_wstrings(self):
+            cs = c_wstring(u"abcdef")
+
+            # XXX This behaviour is about to change:
+            # len returns the size of the internal buffer in bytes.
+            # This includes the terminating NUL character.
+            self.failUnless(sizeof(cs) == 14)
+
+            # The value property is the string up to the first terminating NUL.
+            self.failUnless(cs.value == u"abcdef")
+            self.failUnless(c_wstring(u"abc\000def").value == u"abc")
+
+            self.failUnless(c_wstring(u"abc\000def").value == u"abc")
+
+            # The raw property is the total buffer contents:
+            self.failUnless(cs.raw == u"abcdef\000")
+            self.failUnless(c_wstring(u"abc\000def").raw == u"abc\000def\000")
+
+            # We can change the value:
+            cs.value = u"ab"
+            self.failUnless(cs.value == u"ab")
+            self.failUnless(cs.raw == u"ab\000\000\000\000\000")
+
+            self.assertRaises(TypeError, c_wstring, "123")
+            self.assertRaises(ValueError, c_wstring, 0)
+
+        def X_test_toolong(self):
+            cs = c_wstring(u"abcdef")
+            # Much too long string:
+            self.assertRaises(ValueError, setattr, cs, "value", u"123456789012345")
+
+            # One char too long values:
+            self.assertRaises(ValueError, setattr, cs, "value", u"1234567")
+
+
+def run_test(rep, msg, func, arg):
+    items = range(rep)
+    from time import clock
+    start = clock()
+    for i in items:
+        func(arg); func(arg); func(arg); func(arg); func(arg)
+    stop = clock()
+    print "%20s: %.2f us" % (msg, ((stop-start)*1e6/5/rep))
+
+def check_perf():
+    # Construct 5 objects
+
+    REP = 200000
+
+    run_test(REP, "c_string(None)", c_string, None)
+    run_test(REP, "c_string('abc')", c_string, 'abc')
+
+# Python 2.3 -OO, win2k, P4 700 MHz:
+#
+#      c_string(None): 1.75 us
+#     c_string('abc'): 2.74 us
+
+# Python 2.2 -OO, win2k, P4 700 MHz:
+#
+#      c_string(None): 2.95 us
+#     c_string('abc'): 3.67 us
+
+
+if __name__ == '__main__':
+##    check_perf()
+    unittest.main()

Added: vendor/Python/current/Lib/ctypes/test/test_struct_fields.py
===================================================================
--- vendor/Python/current/Lib/ctypes/test/test_struct_fields.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/test/test_struct_fields.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,50 @@
+import unittest
+from ctypes import *
+
+class StructFieldsTestCase(unittest.TestCase):
+    # Structure/Union classes must get 'finalized' sooner or
+    # later, when one of these things happen:
+    #
+    # 1. _fields_ is set.
+    # 2. An instance is created.
+    # 3. The type is used as field of another Structure/Union.
+    # 4. The type is subclassed
+    #
+    # When they are finalized, assigning _fields_ is no longer allowed.
+
+    def test_1_A(self):
+        class X(Structure):
+            pass
+        self.failUnlessEqual(sizeof(X), 0) # not finalized
+        X._fields_ = [] # finalized
+        self.assertRaises(AttributeError, setattr, X, "_fields_", [])
+
+    def test_1_B(self):
+        class X(Structure):
+            _fields_ = [] # finalized
+        self.assertRaises(AttributeError, setattr, X, "_fields_", [])
+
+    def test_2(self):
+        class X(Structure):
+            pass
+        X()
+        self.assertRaises(AttributeError, setattr, X, "_fields_", [])
+
+    def test_3(self):
+        class X(Structure):
+            pass
+        class Y(Structure):
+            _fields_ = [("x", X)] # finalizes X
+        self.assertRaises(AttributeError, setattr, X, "_fields_", [])
+
+    def test_4(self):
+        class X(Structure):
+            pass
+        class Y(X):
+            pass
+        self.assertRaises(AttributeError, setattr, X, "_fields_", [])
+        Y._fields_ = []
+        self.assertRaises(AttributeError, setattr, X, "_fields_", [])
+
+if __name__ == "__main__":
+    unittest.main()

Added: vendor/Python/current/Lib/ctypes/test/test_structures.py
===================================================================
--- vendor/Python/current/Lib/ctypes/test/test_structures.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/test/test_structures.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,415 @@
+import unittest
+from ctypes import *
+from struct import calcsize
+
+class SubclassesTest(unittest.TestCase):
+    def test_subclass(self):
+        class X(Structure):
+            _fields_ = [("a", c_int)]
+
+        class Y(X):
+            _fields_ = [("b", c_int)]
+
+        class Z(X):
+            pass
+
+        self.failUnlessEqual(sizeof(X), sizeof(c_int))
+        self.failUnlessEqual(sizeof(Y), sizeof(c_int)*2)
+        self.failUnlessEqual(sizeof(Z), sizeof(c_int))
+        self.failUnlessEqual(X._fields_, [("a", c_int)])
+        self.failUnlessEqual(Y._fields_, [("b", c_int)])
+        self.failUnlessEqual(Z._fields_, [("a", c_int)])
+
+    def test_subclass_delayed(self):
+        class X(Structure):
+            pass
+        self.failUnlessEqual(sizeof(X), 0)
+        X._fields_ = [("a", c_int)]
+
+        class Y(X):
+            pass
+        self.failUnlessEqual(sizeof(Y), sizeof(X))
+        Y._fields_ = [("b", c_int)]
+
+        class Z(X):
+            pass
+
+        self.failUnlessEqual(sizeof(X), sizeof(c_int))
+        self.failUnlessEqual(sizeof(Y), sizeof(c_int)*2)
+        self.failUnlessEqual(sizeof(Z), sizeof(c_int))
+        self.failUnlessEqual(X._fields_, [("a", c_int)])
+        self.failUnlessEqual(Y._fields_, [("b", c_int)])
+        self.failUnlessEqual(Z._fields_, [("a", c_int)])
+
+class StructureTestCase(unittest.TestCase):
+    formats = {"c": c_char,
+               "b": c_byte,
+               "B": c_ubyte,
+               "h": c_short,
+               "H": c_ushort,
+               "i": c_int,
+               "I": c_uint,
+               "l": c_long,
+               "L": c_ulong,
+               "q": c_longlong,
+               "Q": c_ulonglong,
+               "f": c_float,
+               "d": c_double,
+               }
+
+    def test_simple_structs(self):
+        for code, tp in self.formats.items():
+            class X(Structure):
+                _fields_ = [("x", c_char),
+                            ("y", tp)]
+            self.failUnlessEqual((sizeof(X), code),
+                                 (calcsize("c%c0%c" % (code, code)), code))
+
+    def test_unions(self):
+        for code, tp in self.formats.items():
+            class X(Union):
+                _fields_ = [("x", c_char),
+                            ("y", tp)]
+            self.failUnlessEqual((sizeof(X), code),
+                                 (calcsize("%c" % (code)), code))
+
+    def test_struct_alignment(self):
+        class X(Structure):
+            _fields_ = [("x", c_char * 3)]
+        self.failUnlessEqual(alignment(X), calcsize("s"))
+        self.failUnlessEqual(sizeof(X), calcsize("3s"))
+
+        class Y(Structure):
+            _fields_ = [("x", c_char * 3),
+                        ("y", c_int)]
+        self.failUnlessEqual(alignment(Y), calcsize("i"))
+        self.failUnlessEqual(sizeof(Y), calcsize("3si"))
+
+        class SI(Structure):
+            _fields_ = [("a", X),
+                        ("b", Y)]
+        self.failUnlessEqual(alignment(SI), max(alignment(Y), alignment(X)))
+        self.failUnlessEqual(sizeof(SI), calcsize("3s0i 3si 0i"))
+
+        class IS(Structure):
+            _fields_ = [("b", Y),
+                        ("a", X)]
+
+        self.failUnlessEqual(alignment(SI), max(alignment(X), alignment(Y)))
+        self.failUnlessEqual(sizeof(IS), calcsize("3si 3s 0i"))
+
+        class XX(Structure):
+            _fields_ = [("a", X),
+                        ("b", X)]
+        self.failUnlessEqual(alignment(XX), alignment(X))
+        self.failUnlessEqual(sizeof(XX), calcsize("3s 3s 0s"))
+
+    def test_emtpy(self):
+        # I had problems with these
+        #
+        # Although these are patological cases: Empty Structures!
+        class X(Structure):
+            _fields_ = []
+
+        class Y(Union):
+            _fields_ = []
+
+        # Is this really the correct alignment, or should it be 0?
+        self.failUnless(alignment(X) == alignment(Y) == 1)
+        self.failUnless(sizeof(X) == sizeof(Y) == 0)
+
+        class XX(Structure):
+            _fields_ = [("a", X),
+                        ("b", X)]
+
+        self.failUnlessEqual(alignment(XX), 1)
+        self.failUnlessEqual(sizeof(XX), 0)
+
+    def test_fields(self):
+        # test the offset and size attributes of Structure/Unoin fields.
+        class X(Structure):
+            _fields_ = [("x", c_int),
+                        ("y", c_char)]
+
+        self.failUnlessEqual(X.x.offset, 0)
+        self.failUnlessEqual(X.x.size, sizeof(c_int))
+
+        self.failUnlessEqual(X.y.offset, sizeof(c_int))
+        self.failUnlessEqual(X.y.size, sizeof(c_char))
+
+        # readonly
+        self.assertRaises((TypeError, AttributeError), setattr, X.x, "offset", 92)
+        self.assertRaises((TypeError, AttributeError), setattr, X.x, "size", 92)
+
+        class X(Union):
+            _fields_ = [("x", c_int),
+                        ("y", c_char)]
+
+        self.failUnlessEqual(X.x.offset, 0)
+        self.failUnlessEqual(X.x.size, sizeof(c_int))
+
+        self.failUnlessEqual(X.y.offset, 0)
+        self.failUnlessEqual(X.y.size, sizeof(c_char))
+
+        # readonly
+        self.assertRaises((TypeError, AttributeError), setattr, X.x, "offset", 92)
+        self.assertRaises((TypeError, AttributeError), setattr, X.x, "size", 92)
+
+        # XXX Should we check nested data types also?
+        # offset is always relative to the class...
+
+    def test_packed(self):
+        class X(Structure):
+            _fields_ = [("a", c_byte),
+                        ("b", c_longlong)]
+            _pack_ = 1
+
+        self.failUnlessEqual(sizeof(X), 9)
+        self.failUnlessEqual(X.b.offset, 1)
+
+        class X(Structure):
+            _fields_ = [("a", c_byte),
+                        ("b", c_longlong)]
+            _pack_ = 2
+        self.failUnlessEqual(sizeof(X), 10)
+        self.failUnlessEqual(X.b.offset, 2)
+
+        class X(Structure):
+            _fields_ = [("a", c_byte),
+                        ("b", c_longlong)]
+            _pack_ = 4
+        self.failUnlessEqual(sizeof(X), 12)
+        self.failUnlessEqual(X.b.offset, 4)
+
+        import struct
+        longlong_size = struct.calcsize("q")
+        longlong_align = struct.calcsize("bq") - longlong_size
+
+        class X(Structure):
+            _fields_ = [("a", c_byte),
+                        ("b", c_longlong)]
+            _pack_ = 8
+
+        self.failUnlessEqual(sizeof(X), longlong_align + longlong_size)
+        self.failUnlessEqual(X.b.offset, min(8, longlong_align))
+
+
+        d = {"_fields_": [("a", "b"),
+                          ("b", "q")],
+             "_pack_": -1}
+        self.assertRaises(ValueError, type(Structure), "X", (Structure,), d)
+
+    def test_initializers(self):
+        class Person(Structure):
+            _fields_ = [("name", c_char*6),
+                        ("age", c_int)]
+
+        self.assertRaises(TypeError, Person, 42)
+        self.assertRaises(ValueError, Person, "asldkjaslkdjaslkdj")
+        self.assertRaises(TypeError, Person, "Name", "HI")
+
+        # short enough
+        self.failUnlessEqual(Person("12345", 5).name, "12345")
+        # exact fit
+        self.failUnlessEqual(Person("123456", 5).name, "123456")
+        # too long
+        self.assertRaises(ValueError, Person, "1234567", 5)
+
+
+    def test_keyword_initializers(self):
+        class POINT(Structure):
+            _fields_ = [("x", c_int), ("y", c_int)]
+        pt = POINT(1, 2)
+        self.failUnlessEqual((pt.x, pt.y), (1, 2))
+
+        pt = POINT(y=2, x=1)
+        self.failUnlessEqual((pt.x, pt.y), (1, 2))
+
+    def test_invalid_field_types(self):
+        class POINT(Structure):
+            pass
+        self.assertRaises(TypeError, setattr, POINT, "_fields_", [("x", 1), ("y", 2)])
+
+    def test_intarray_fields(self):
+        class SomeInts(Structure):
+            _fields_ = [("a", c_int * 4)]
+
+        # can use tuple to initialize array (but not list!)
+        self.failUnlessEqual(SomeInts((1, 2)).a[:], [1, 2, 0, 0])
+        self.failUnlessEqual(SomeInts((1, 2, 3, 4)).a[:], [1, 2, 3, 4])
+        # too long
+        # XXX Should raise ValueError?, not RuntimeError
+        self.assertRaises(RuntimeError, SomeInts, (1, 2, 3, 4, 5))
+
+    def test_nested_initializers(self):
+        # test initializing nested structures
+        class Phone(Structure):
+            _fields_ = [("areacode", c_char*6),
+                        ("number", c_char*12)]
+
+        class Person(Structure):
+            _fields_ = [("name", c_char * 12),
+                        ("phone", Phone),
+                        ("age", c_int)]
+
+        p = Person("Someone", ("1234", "5678"), 5)
+
+        self.failUnlessEqual(p.name, "Someone")
+        self.failUnlessEqual(p.phone.areacode, "1234")
+        self.failUnlessEqual(p.phone.number, "5678")
+        self.failUnlessEqual(p.age, 5)
+
+    def test_structures_with_wchar(self):
+        try:
+            c_wchar
+        except NameError:
+            return # no unicode
+
+        class PersonW(Structure):
+            _fields_ = [("name", c_wchar * 12),
+                        ("age", c_int)]
+
+        p = PersonW(u"Someone")
+        self.failUnlessEqual(p.name, "Someone")
+
+        self.failUnlessEqual(PersonW(u"1234567890").name, u"1234567890")
+        self.failUnlessEqual(PersonW(u"12345678901").name, u"12345678901")
+        # exact fit
+        self.failUnlessEqual(PersonW(u"123456789012").name, u"123456789012")
+        #too long
+        self.assertRaises(ValueError, PersonW, u"1234567890123")
+
+    def test_init_errors(self):
+        class Phone(Structure):
+            _fields_ = [("areacode", c_char*6),
+                        ("number", c_char*12)]
+
+        class Person(Structure):
+            _fields_ = [("name", c_char * 12),
+                        ("phone", Phone),
+                        ("age", c_int)]
+
+        cls, msg = self.get_except(Person, "Someone", (1, 2))
+        self.failUnlessEqual(cls, RuntimeError)
+        # In Python 2.5, Exception is a new-style class, and the repr changed
+        if issubclass(Exception, object):
+            self.failUnlessEqual(msg,
+                                 "(Phone) <type 'exceptions.TypeError'>: "
+                                 "expected string or Unicode object, int found")
+        else:
+            self.failUnlessEqual(msg,
+                                 "(Phone) exceptions.TypeError: "
+                                 "expected string or Unicode object, int found")
+
+        cls, msg = self.get_except(Person, "Someone", ("a", "b", "c"))
+        self.failUnlessEqual(cls, RuntimeError)
+        if issubclass(Exception, object):
+            self.failUnlessEqual(msg,
+                                 "(Phone) <type 'exceptions.ValueError'>: too many initializers")
+        else:
+            self.failUnlessEqual(msg, "(Phone) exceptions.ValueError: too many initializers")
+
+
+    def get_except(self, func, *args):
+        try:
+            func(*args)
+        except Exception, detail:
+            return detail.__class__, str(detail)
+
+
+##    def test_subclass_creation(self):
+##        meta = type(Structure)
+##        # same as 'class X(Structure): pass'
+##        # fails, since we need either a _fields_ or a _abstract_ attribute
+##        cls, msg = self.get_except(meta, "X", (Structure,), {})
+##        self.failUnlessEqual((cls, msg),
+##                             (AttributeError, "class must define a '_fields_' attribute"))
+
+    def test_abstract_class(self):
+        class X(Structure):
+            _abstract_ = "something"
+        # try 'X()'
+        cls, msg = self.get_except(eval, "X()", locals())
+        self.failUnlessEqual((cls, msg), (TypeError, "abstract class"))
+
+    def test_methods(self):
+##        class X(Structure):
+##            _fields_ = []
+
+        self.failUnless("in_dll" in dir(type(Structure)))
+        self.failUnless("from_address" in dir(type(Structure)))
+        self.failUnless("in_dll" in dir(type(Structure)))
+
+class PointerMemberTestCase(unittest.TestCase):
+
+    def test(self):
+        # a Structure with a POINTER field
+        class S(Structure):
+            _fields_ = [("array", POINTER(c_int))]
+
+        s = S()
+        # We can assign arrays of the correct type
+        s.array = (c_int * 3)(1, 2, 3)
+        items = [s.array[i] for i in range(3)]
+        self.failUnlessEqual(items, [1, 2, 3])
+
+        # The following are bugs, but are included here because the unittests
+        # also describe the current behaviour.
+        #
+        # This fails with SystemError: bad arg to internal function
+        # or with IndexError (with a patch I have)
+
+        s.array[0] = 42
+
+        items = [s.array[i] for i in range(3)]
+        self.failUnlessEqual(items, [42, 2, 3])
+
+        s.array[0] = 1
+
+##        s.array[1] = 42
+
+        items = [s.array[i] for i in range(3)]
+        self.failUnlessEqual(items, [1, 2, 3])
+
+    def test_none_to_pointer_fields(self):
+        class S(Structure):
+            _fields_ = [("x", c_int),
+                        ("p", POINTER(c_int))]
+
+        s = S()
+        s.x = 12345678
+        s.p = None
+        self.failUnlessEqual(s.x, 12345678)
+
+class TestRecursiveStructure(unittest.TestCase):
+    def test_contains_itself(self):
+        class Recursive(Structure):
+            pass
+
+        try:
+            Recursive._fields_ = [("next", Recursive)]
+        except AttributeError, details:
+            self.failUnless("Structure or union cannot contain itself" in
+                            str(details))
+        else:
+            self.fail("Structure or union cannot contain itself")
+
+
+    def test_vice_versa(self):
+        class First(Structure):
+            pass
+        class Second(Structure):
+            pass
+
+        First._fields_ = [("second", Second)]
+
+        try:
+            Second._fields_ = [("first", First)]
+        except AttributeError, details:
+            self.failUnless("_fields_ is final" in
+                            str(details))
+        else:
+            self.fail("AttributeError not raised")
+
+if __name__ == '__main__':
+    unittest.main()

Added: vendor/Python/current/Lib/ctypes/test/test_unaligned_structures.py
===================================================================
--- vendor/Python/current/Lib/ctypes/test/test_unaligned_structures.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/test/test_unaligned_structures.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,45 @@
+import sys, unittest
+from ctypes import *
+
+structures = []
+byteswapped_structures = []
+
+
+if sys.byteorder == "little":
+    SwappedStructure = BigEndianStructure
+else:
+    SwappedStructure = LittleEndianStructure
+
+for typ in [c_short, c_int, c_long, c_longlong,
+            c_float, c_double,
+            c_ushort, c_uint, c_ulong, c_ulonglong]:
+    class X(Structure):
+        _pack_ = 1
+        _fields_ = [("pad", c_byte),
+                    ("value", typ)]
+    class Y(SwappedStructure):
+        _pack_ = 1
+        _fields_ = [("pad", c_byte),
+                    ("value", typ)]
+    structures.append(X)
+    byteswapped_structures.append(Y)
+
+class TestStructures(unittest.TestCase):
+    def test_native(self):
+        for typ in structures:
+##            print typ.value
+            self.failUnlessEqual(typ.value.offset, 1)
+            o = typ()
+            o.value = 4
+            self.failUnlessEqual(o.value, 4)
+
+    def test_swapped(self):
+        for typ in byteswapped_structures:
+##            print >> sys.stderr, typ.value
+            self.failUnlessEqual(typ.value.offset, 1)
+            o = typ()
+            o.value = 4
+            self.failUnlessEqual(o.value, 4)
+
+if __name__ == '__main__':
+    unittest.main()

Added: vendor/Python/current/Lib/ctypes/test/test_unicode.py
===================================================================
--- vendor/Python/current/Lib/ctypes/test/test_unicode.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/test/test_unicode.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,115 @@
+# coding: latin-1
+import unittest
+import ctypes
+
+try:
+    ctypes.c_wchar
+except AttributeError:
+    pass
+else:
+    import _ctypes_test
+    dll = ctypes.CDLL(_ctypes_test.__file__)
+    wcslen = dll.my_wcslen
+    wcslen.argtypes = [ctypes.c_wchar_p]
+
+
+    class UnicodeTestCase(unittest.TestCase):
+        def setUp(self):
+            self.prev_conv_mode = ctypes.set_conversion_mode("ascii", "strict")
+
+        def tearDown(self):
+            ctypes.set_conversion_mode(*self.prev_conv_mode)
+
+        def test_ascii_strict(self):
+            ctypes.set_conversion_mode("ascii", "strict")
+            # no conversions take place with unicode arguments
+            self.failUnlessEqual(wcslen(u"abc"), 3)
+            self.failUnlessEqual(wcslen(u"ab\u2070"), 3)
+            # string args are converted
+            self.failUnlessEqual(wcslen("abc"), 3)
+            self.failUnlessRaises(ctypes.ArgumentError, wcslen, "abä")
+
+        def test_ascii_replace(self):
+            ctypes.set_conversion_mode("ascii", "replace")
+            self.failUnlessEqual(wcslen(u"abc"), 3)
+            self.failUnlessEqual(wcslen(u"ab\u2070"), 3)
+            self.failUnlessEqual(wcslen("abc"), 3)
+            self.failUnlessEqual(wcslen("abä"), 3)
+
+        def test_ascii_ignore(self):
+            ctypes.set_conversion_mode("ascii", "ignore")
+            self.failUnlessEqual(wcslen(u"abc"), 3)
+            self.failUnlessEqual(wcslen(u"ab\u2070"), 3)
+            # ignore error mode skips non-ascii characters
+            self.failUnlessEqual(wcslen("abc"), 3)
+            self.failUnlessEqual(wcslen("äöüß"), 0)
+
+        def test_latin1_strict(self):
+            ctypes.set_conversion_mode("latin-1", "strict")
+            self.failUnlessEqual(wcslen(u"abc"), 3)
+            self.failUnlessEqual(wcslen(u"ab\u2070"), 3)
+            self.failUnlessEqual(wcslen("abc"), 3)
+            self.failUnlessEqual(wcslen("äöüß"), 4)
+
+        def test_buffers(self):
+            ctypes.set_conversion_mode("ascii", "strict")
+            buf = ctypes.create_unicode_buffer("abc")
+            self.failUnlessEqual(len(buf), 3+1)
+
+            ctypes.set_conversion_mode("ascii", "replace")
+            buf = ctypes.create_unicode_buffer("abäöü")
+            self.failUnlessEqual(buf[:], u"ab\uFFFD\uFFFD\uFFFD\0")
+
+            ctypes.set_conversion_mode("ascii", "ignore")
+            buf = ctypes.create_unicode_buffer("abäöü")
+            # is that correct? not sure.  But with 'ignore', you get what you pay for..
+            self.failUnlessEqual(buf[:], u"ab\0\0\0\0")
+
+    import _ctypes_test
+    func = ctypes.CDLL(_ctypes_test.__file__)._testfunc_p_p
+
+    class StringTestCase(UnicodeTestCase):
+        def setUp(self):
+            self.prev_conv_mode = ctypes.set_conversion_mode("ascii", "strict")
+            func.argtypes = [ctypes.c_char_p]
+            func.restype = ctypes.c_char_p
+
+        def tearDown(self):
+            ctypes.set_conversion_mode(*self.prev_conv_mode)
+            func.argtypes = None
+            func.restype = ctypes.c_int
+
+        def test_ascii_replace(self):
+            ctypes.set_conversion_mode("ascii", "strict")
+            self.failUnlessEqual(func("abc"), "abc")
+            self.failUnlessEqual(func(u"abc"), "abc")
+            self.assertRaises(ctypes.ArgumentError, func, u"abä")
+
+        def test_ascii_ignore(self):
+            ctypes.set_conversion_mode("ascii", "ignore")
+            self.failUnlessEqual(func("abc"), "abc")
+            self.failUnlessEqual(func(u"abc"), "abc")
+            self.failUnlessEqual(func(u"äöüß"), "")
+
+        def test_ascii_replace(self):
+            ctypes.set_conversion_mode("ascii", "replace")
+            self.failUnlessEqual(func("abc"), "abc")
+            self.failUnlessEqual(func(u"abc"), "abc")
+            self.failUnlessEqual(func(u"äöüß"), "????")
+
+        def test_buffers(self):
+            ctypes.set_conversion_mode("ascii", "strict")
+            buf = ctypes.create_string_buffer(u"abc")
+            self.failUnlessEqual(len(buf), 3+1)
+
+            ctypes.set_conversion_mode("ascii", "replace")
+            buf = ctypes.create_string_buffer(u"abäöü")
+            self.failUnlessEqual(buf[:], "ab???\0")
+
+            ctypes.set_conversion_mode("ascii", "ignore")
+            buf = ctypes.create_string_buffer(u"abäöü")
+            # is that correct? not sure.  But with 'ignore', you get what you pay for..
+            self.failUnlessEqual(buf[:], "ab\0\0\0\0")
+
+if __name__ == '__main__':
+    unittest.main()

Added: vendor/Python/current/Lib/ctypes/test/test_values.py
===================================================================
--- vendor/Python/current/Lib/ctypes/test/test_values.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/test/test_values.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,82 @@
+"""
+A testcase which accesses *values* in a dll.
+"""
+
+import unittest
+from ctypes import *
+
+import _ctypes_test
+
+class ValuesTestCase(unittest.TestCase):
+
+    def test_an_integer(self):
+        ctdll = CDLL(_ctypes_test.__file__)
+        an_integer = c_int.in_dll(ctdll, "an_integer")
+        x = an_integer.value
+        self.failUnlessEqual(x, ctdll.get_an_integer())
+        an_integer.value *= 2
+        self.failUnlessEqual(x*2, ctdll.get_an_integer())
+
+    def test_undefined(self):
+        ctdll = CDLL(_ctypes_test.__file__)
+        self.assertRaises(ValueError, c_int.in_dll, ctdll, "Undefined_Symbol")
+
+    class Win_ValuesTestCase(unittest.TestCase):
+        """This test only works when python itself is a dll/shared library"""
+
+        def test_optimizeflag(self):
+            # This test accesses the Py_OptimizeFlag intger, which is
+            # exported by the Python dll.
+
+            # It's value is set depending on the -O and -OO flags:
+            # if not given, it is 0 and __debug__ is 1.
+            # If -O is given, the flag is 1, for -OO it is 2.
+            # docstrings are also removed in the latter case.
+            opt = c_int.in_dll(pydll, "Py_OptimizeFlag").value
+            if __debug__:
+                self.failUnlessEqual(opt, 0)
+            elif ValuesTestCase.__doc__ is not None:
+                self.failUnlessEqual(opt, 1)
+            else:
+                self.failUnlessEqual(opt, 2)
+
+        def test_frozentable(self):
+            # Python exports a PyImport_FrozenModules symbol. This is a
+            # pointer to an array of struct _frozen entries.  The end of the
+            # array is marked by an entry containing a NULL name and zero
+            # size.
+
+            # In standard Python, this table contains a __hello__
+            # module, and a __phello__ package containing a spam
+            # module.
+            class struct_frozen(Structure):
+                _fields_ = [("name", c_char_p),
+                            ("code", POINTER(c_ubyte)),
+                            ("size", c_int)]
+            FrozenTable = POINTER(struct_frozen)
+
+            ft = FrozenTable.in_dll(pydll, "PyImport_FrozenModules")
+            # ft is a pointer to the struct_frozen entries:
+            items = []
+            for entry in ft:
+                # This is dangerous. We *can* iterate over a pointer, but
+                # the loop will not terminate (maybe with an access
+                # violation;-) because the pointer instance has no size.
+                if entry.name is None:
+                    break
+                items.append((entry.name, entry.size))
+            import sys
+            if sys.version_info[:2] >= (2, 3):
+                expected = [("__hello__", 104), ("__phello__", -104), ("__phello__.spam", 104)]
+            else:
+                expected = [("__hello__", 100), ("__phello__", -100), ("__phello__.spam", 100)]
+            self.failUnlessEqual(items, expected)
+
+            from ctypes import _pointer_type_cache
+            del _pointer_type_cache[struct_frozen]
+
+        def test_undefined(self):
+            self.assertRaises(ValueError, c_int.in_dll, pydll, "Undefined_Symbol")
+
+if __name__ == '__main__':
+    unittest.main()

Added: vendor/Python/current/Lib/ctypes/test/test_varsize_struct.py
===================================================================
--- vendor/Python/current/Lib/ctypes/test/test_varsize_struct.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/test/test_varsize_struct.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,50 @@
+from ctypes import *
+import unittest
+
+class VarSizeTest(unittest.TestCase):
+    def test_resize(self):
+        class X(Structure):
+            _fields_ = [("item", c_int),
+                        ("array", c_int * 1)]
+
+        self.failUnlessEqual(sizeof(X), sizeof(c_int) * 2)
+        x = X()
+        x.item = 42
+        x.array[0] = 100
+        self.failUnlessEqual(sizeof(x), sizeof(c_int) * 2)
+
+        # make room for one additional item
+        new_size = sizeof(X) + sizeof(c_int) * 1
+        resize(x, new_size)
+        self.failUnlessEqual(sizeof(x), new_size)
+        self.failUnlessEqual((x.item, x.array[0]), (42, 100))
+
+        # make room for 10 additional items
+        new_size = sizeof(X) + sizeof(c_int) * 9
+        resize(x, new_size)
+        self.failUnlessEqual(sizeof(x), new_size)
+        self.failUnlessEqual((x.item, x.array[0]), (42, 100))
+
+        # make room for one additional item
+        new_size = sizeof(X) + sizeof(c_int) * 1
+        resize(x, new_size)
+        self.failUnlessEqual(sizeof(x), new_size)
+        self.failUnlessEqual((x.item, x.array[0]), (42, 100))
+
+    def test_array_invalid_length(self):
+        # cannot create arrays with non-positive size
+        self.failUnlessRaises(ValueError, lambda: c_int * -1)
+        self.failUnlessRaises(ValueError, lambda: c_int * -3)
+
+    def test_zerosized_array(self):
+        array = (c_int * 0)()
+        # accessing elements of zero-sized arrays raise IndexError
+        self.failUnlessRaises(IndexError, array.__setitem__, 0, None)
+        self.failUnlessRaises(IndexError, array.__getitem__, 0)
+        self.failUnlessRaises(IndexError, array.__setitem__, 1, None)
+        self.failUnlessRaises(IndexError, array.__getitem__, 1)
+        self.failUnlessRaises(IndexError, array.__setitem__, -1, None)
+        self.failUnlessRaises(IndexError, array.__getitem__, -1)
+
+if __name__ == "__main__":
+    unittest.main()

Added: vendor/Python/current/Lib/ctypes/test/test_win32.py
===================================================================
--- vendor/Python/current/Lib/ctypes/test/test_win32.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/test/test_win32.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,60 @@
+# Windows specific tests
+
+from ctypes import *
+from ctypes.test import is_resource_enabled
+import unittest, sys
+
+import _ctypes_test
+
+if sys.platform == "win32":
+
+    class WindowsTestCase(unittest.TestCase):
+        def test_callconv_1(self):
+            # Testing stdcall function
+
+            IsWindow = windll.user32.IsWindow
+            # ValueError: Procedure probably called with not enough arguments (4 bytes missing)
+            self.assertRaises(ValueError, IsWindow)
+
+            # This one should succeeed...
+            self.failUnlessEqual(0, IsWindow(0))
+
+            # ValueError: Procedure probably called with too many arguments (8 bytes in excess)
+            self.assertRaises(ValueError, IsWindow, 0, 0, 0)
+
+        def test_callconv_2(self):
+            # Calling stdcall function as cdecl
+
+            IsWindow = cdll.user32.IsWindow
+
+            # ValueError: Procedure called with not enough arguments (4 bytes missing)
+            # or wrong calling convention
+            self.assertRaises(ValueError, IsWindow, None)
+
+        if is_resource_enabled("SEH"):
+            def test_SEH(self):
+                # Call functions with invalid arguments, and make sure that access violations
+                # are trapped and raise an exception.
+                self.assertRaises(WindowsError, windll.kernel32.GetModuleHandleA, 32)
+
+class Structures(unittest.TestCase):
+
+    def test_struct_by_value(self):
+        class POINT(Structure):
+            _fields_ = [("x", c_long),
+                        ("y", c_long)]
+
+        class RECT(Structure):
+            _fields_ = [("left", c_long),
+                        ("top", c_long),
+                        ("right", c_long),
+                        ("bottom", c_long)]
+
+        dll = CDLL(_ctypes_test.__file__)
+
+        pt = POINT(10, 10)
+        rect = RECT(0, 0, 20, 20)
+        self.failUnlessEqual(1, dll.PointInRect(byref(rect), pt))
+
+if __name__ == '__main__':
+    unittest.main()

Added: vendor/Python/current/Lib/ctypes/util.py
===================================================================
--- vendor/Python/current/Lib/ctypes/util.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/util.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,154 @@
+######################################################################
+#  This file should be kept compatible with Python 2.3, see PEP 291. #
+######################################################################
+import sys, os
+
+# find_library(name) returns the pathname of a library, or None.
+if os.name == "nt":
+    def find_library(name):
+        # See MSDN for the REAL search order.
+        for directory in os.environ['PATH'].split(os.pathsep):
+            fname = os.path.join(directory, name)
+            if os.path.exists(fname):
+                return fname
+            if fname.lower().endswith(".dll"):
+                continue
+            fname = fname + ".dll"
+            if os.path.exists(fname):
+                return fname
+        return None
+
+if os.name == "ce":
+    # search path according to MSDN:
+    # - absolute path specified by filename
+    # - The .exe launch directory
+    # - the Windows directory
+    # - ROM dll files (where are they?)
+    # - OEM specified search path: HKLM\Loader\SystemPath
+    def find_library(name):
+        return name
+
+if os.name == "posix" and sys.platform == "darwin":
+    from ctypes.macholib.dyld import dyld_find as _dyld_find
+    def find_library(name):
+        possible = ['lib%s.dylib' % name,
+                    '%s.dylib' % name,
+                    '%s.framework/%s' % (name, name)]
+        for name in possible:
+            try:
+                return _dyld_find(name)
+            except ValueError:
+                continue
+        return None
+
+elif os.name == "posix":
+    # Andreas Degert's find functions, using gcc, /sbin/ldconfig, objdump
+    import re, tempfile, errno
+
+    def _findLib_gcc(name):
+        expr = r'[^\(\)\s]*lib%s\.[^\(\)\s]*' % re.escape(name)
+        fdout, ccout = tempfile.mkstemp()
+        os.close(fdout)
+        cmd = 'if type gcc >/dev/null 2>&1; then CC=gcc; else CC=cc; fi;' \
+              '$CC -Wl,-t -o ' + ccout + ' 2>&1 -l' + name
+        try:
+            f = os.popen(cmd)
+            trace = f.read()
+            f.close()
+        finally:
+            try:
+                os.unlink(ccout)
+            except OSError, e:
+                if e.errno != errno.ENOENT:
+                    raise
+        res = re.search(expr, trace)
+        if not res:
+            return None
+        return res.group(0)
+
+    def _get_soname(f):
+        # assuming GNU binutils / ELF
+        if not f:
+            return None
+        cmd = "objdump -p -j .dynamic 2>/dev/null " + f
+        res = re.search(r'\sSONAME\s+([^\s]+)', os.popen(cmd).read())
+        if not res:
+            return None
+        return res.group(1)
+
+    if (sys.platform.startswith("freebsd")
+        or sys.platform.startswith("openbsd")
+        or sys.platform.startswith("dragonfly")):
+
+        def _num_version(libname):
+            # "libxyz.so.MAJOR.MINOR" => [ MAJOR, MINOR ]
+            parts = libname.split(".")
+            nums = []
+            try:
+                while parts:
+                    nums.insert(0, int(parts.pop()))
+            except ValueError:
+                pass
+            return nums or [ sys.maxint ]
+
+        def find_library(name):
+            ename = re.escape(name)
+            expr = r':-l%s\.\S+ => \S*/(lib%s\.\S+)' % (ename, ename)
+            res = re.findall(expr,
+                             os.popen('/sbin/ldconfig -r 2>/dev/null').read())
+            if not res:
+                return _get_soname(_findLib_gcc(name))
+            res.sort(cmp= lambda x,y: cmp(_num_version(x), _num_version(y)))
+            return res[-1]
+
+    else:
+
+        def _findLib_ldconfig(name):
+            # XXX assuming GLIBC's ldconfig (with option -p)
+            expr = r'/[^\(\)\s]*lib%s\.[^\(\)\s]*' % re.escape(name)
+            res = re.search(expr,
+                            os.popen('/sbin/ldconfig -p 2>/dev/null').read())
+            if not res:
+                # Hm, this works only for libs needed by the python executable.
+                cmd = 'ldd %s 2>/dev/null' % sys.executable
+                res = re.search(expr, os.popen(cmd).read())
+                if not res:
+                    return None
+            return res.group(0)
+
+        def find_library(name):
+            return _get_soname(_findLib_ldconfig(name) or _findLib_gcc(name))
+
+################################################################
+# test code
+
+def test():
+    from ctypes import cdll
+    if os.name == "nt":
+        print cdll.msvcrt
+        print cdll.load("msvcrt")
+        print find_library("msvcrt")
+
+    if os.name == "posix":
+        # find and load_version
+        print find_library("m")
+        print find_library("c")
+        print find_library("bz2")
+
+        # getattr
+##        print cdll.m
+##        print cdll.bz2
+
+        # load
+        if sys.platform == "darwin":
+            print cdll.LoadLibrary("libm.dylib")
+            print cdll.LoadLibrary("libcrypto.dylib")
+            print cdll.LoadLibrary("libSystem.dylib")
+            print cdll.LoadLibrary("System.framework/System")
+        else:
+            print cdll.LoadLibrary("libm.so")
+            print cdll.LoadLibrary("libcrypt.so")
+            print find_library("crypt")
+
+if __name__ == "__main__":
+    test()

Added: vendor/Python/current/Lib/ctypes/wintypes.py
===================================================================
--- vendor/Python/current/Lib/ctypes/wintypes.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ctypes/wintypes.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,172 @@
+######################################################################
+#  This file should be kept compatible with Python 2.3, see PEP 291. #
+######################################################################
+
+# The most useful windows datatypes
+from ctypes import *
+
+BYTE = c_byte
+WORD = c_ushort
+DWORD = c_ulong
+
+WCHAR = c_wchar
+UINT = c_uint
+
+DOUBLE = c_double
+
+BOOLEAN = BYTE
+BOOL = c_long
+
+from ctypes import _SimpleCData
+class VARIANT_BOOL(_SimpleCData):
+    _type_ = "v"
+    def __repr__(self):
+        return "%s(%r)" % (self.__class__.__name__, self.value)
+
+ULONG = c_ulong
+LONG = c_long
+
+# in the windows header files, these are structures.
+_LARGE_INTEGER = LARGE_INTEGER = c_longlong
+_ULARGE_INTEGER = ULARGE_INTEGER = c_ulonglong
+
+LPCOLESTR = LPOLESTR = OLESTR = c_wchar_p
+LPCWSTR = LPWSTR = c_wchar_p
+LPCSTR = LPSTR = c_char_p
+
+WPARAM = c_uint
+LPARAM = c_long
+
+ATOM = WORD
+LANGID = WORD
+
+COLORREF = DWORD
+LGRPID = DWORD
+LCTYPE = DWORD
+
+LCID = DWORD
+
+################################################################
+# HANDLE types
+HANDLE = c_ulong # in the header files: void *
+
+HACCEL = HANDLE
+HBITMAP = HANDLE
+HBRUSH = HANDLE
+HCOLORSPACE = HANDLE
+HDC = HANDLE
+HDESK = HANDLE
+HDWP = HANDLE
+HENHMETAFILE = HANDLE
+HFONT = HANDLE
+HGDIOBJ = HANDLE
+HGLOBAL = HANDLE
+HHOOK = HANDLE
+HICON = HANDLE
+HINSTANCE = HANDLE
+HKEY = HANDLE
+HKL = HANDLE
+HLOCAL = HANDLE
+HMENU = HANDLE
+HMETAFILE = HANDLE
+HMODULE = HANDLE
+HMONITOR = HANDLE
+HPALETTE = HANDLE
+HPEN = HANDLE
+HRGN = HANDLE
+HRSRC = HANDLE
+HSTR = HANDLE
+HTASK = HANDLE
+HWINSTA = HANDLE
+HWND = HANDLE
+SC_HANDLE = HANDLE
+SERVICE_STATUS_HANDLE = HANDLE
+
+################################################################
+# Some important structure definitions
+
+class RECT(Structure):
+    _fields_ = [("left", c_long),
+                ("top", c_long),
+                ("right", c_long),
+                ("bottom", c_long)]
+tagRECT = _RECTL = RECTL = RECT
+
+class _SMALL_RECT(Structure):
+    _fields_ = [('Left', c_short),
+                ('Top', c_short),
+                ('Right', c_short),
+                ('Bottom', c_short)]
+SMALL_RECT = _SMALL_RECT
+
+class _COORD(Structure):
+    _fields_ = [('X', c_short),
+                ('Y', c_short)]
+
+class POINT(Structure):
+    _fields_ = [("x", c_long),
+                ("y", c_long)]
+tagPOINT = _POINTL = POINTL = POINT
+
+class SIZE(Structure):
+    _fields_ = [("cx", c_long),
+                ("cy", c_long)]
+tagSIZE = SIZEL = SIZE
+
+def RGB(red, green, blue):
+    return red + (green << 8) + (blue << 16)
+
+class FILETIME(Structure):
+    _fields_ = [("dwLowDateTime", DWORD),
+                ("dwHighDateTime", DWORD)]
+_FILETIME = FILETIME
+
+class MSG(Structure):
+    _fields_ = [("hWnd", HWND),
+                ("message", c_uint),
+                ("wParam", WPARAM),
+                ("lParam", LPARAM),
+                ("time", DWORD),
+                ("pt", POINT)]
+tagMSG = MSG
+MAX_PATH = 260
+
+class WIN32_FIND_DATAA(Structure):
+    _fields_ = [("dwFileAttributes", DWORD),
+                ("ftCreationTime", FILETIME),
+                ("ftLastAccessTime", FILETIME),
+                ("ftLastWriteTime", FILETIME),
+                ("nFileSizeHigh", DWORD),
+                ("nFileSizeLow", DWORD),
+                ("dwReserved0", DWORD),
+                ("dwReserved1", DWORD),
+                ("cFileName", c_char * MAX_PATH),
+                ("cAlternameFileName", c_char * 14)]
+
+class WIN32_FIND_DATAW(Structure):
+    _fields_ = [("dwFileAttributes", DWORD),
+                ("ftCreationTime", FILETIME),
+                ("ftLastAccessTime", FILETIME),
+                ("ftLastWriteTime", FILETIME),
+                ("nFileSizeHigh", DWORD),
+                ("nFileSizeLow", DWORD),
+                ("dwReserved0", DWORD),
+                ("dwReserved1", DWORD),
+                ("cFileName", c_wchar * MAX_PATH),
+                ("cAlternameFileName", c_wchar * 14)]
+
+__all__ = ['ATOM', 'BOOL', 'BOOLEAN', 'BYTE', 'COLORREF', 'DOUBLE',
+           'DWORD', 'FILETIME', 'HACCEL', 'HANDLE', 'HBITMAP', 'HBRUSH',
+           'HCOLORSPACE', 'HDC', 'HDESK', 'HDWP', 'HENHMETAFILE', 'HFONT',
+           'HGDIOBJ', 'HGLOBAL', 'HHOOK', 'HICON', 'HINSTANCE', 'HKEY',
+           'HKL', 'HLOCAL', 'HMENU', 'HMETAFILE', 'HMODULE', 'HMONITOR',
+           'HPALETTE', 'HPEN', 'HRGN', 'HRSRC', 'HSTR', 'HTASK', 'HWINSTA',
+           'HWND', 'LANGID', 'LARGE_INTEGER', 'LCID', 'LCTYPE', 'LGRPID',
+           'LONG', 'LPARAM', 'LPCOLESTR', 'LPCSTR', 'LPCWSTR', 'LPOLESTR',
+           'LPSTR', 'LPWSTR', 'MAX_PATH', 'MSG', 'OLESTR', 'POINT',
+           'POINTL', 'RECT', 'RECTL', 'RGB', 'SC_HANDLE',
+           'SERVICE_STATUS_HANDLE', 'SIZE', 'SIZEL', 'SMALL_RECT', 'UINT',
+           'ULARGE_INTEGER', 'ULONG', 'VARIANT_BOOL', 'WCHAR',
+           'WIN32_FIND_DATAA', 'WIN32_FIND_DATAW', 'WORD', 'WPARAM', '_COORD',
+           '_FILETIME', '_LARGE_INTEGER', '_POINTL', '_RECTL', '_SMALL_RECT',
+           '_ULARGE_INTEGER', 'tagMSG', 'tagPOINT', 'tagRECT', 'tagSIZE']

Added: vendor/Python/current/Lib/curses/__init__.py
===================================================================
--- vendor/Python/current/Lib/curses/__init__.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/curses/__init__.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,53 @@
+"""curses
+
+The main package for curses support for Python.  Normally used by importing
+the package, and perhaps a particular module inside it.
+
+   import curses
+   from curses import textpad
+   curses.initwin()
+   ...
+
+"""
+
+__revision__ = "$Id: __init__.py 36560 2004-07-18 06:16:08Z tim_one $"
+
+from _curses import *
+from curses.wrapper import wrapper
+
+# Some constants, most notably the ACS_* ones, are only added to the C
+# _curses module's dictionary after initscr() is called.  (Some
+# versions of SGI's curses don't define values for those constants
+# until initscr() has been called.)  This wrapper function calls the
+# underlying C initscr(), and then copies the constants from the
+# _curses module to the curses package's dictionary.  Don't do 'from
+# curses import *' if you'll be needing the ACS_* constants.
+
+def initscr():
+    import _curses, curses
+    stdscr = _curses.initscr()
+    for key, value in _curses.__dict__.items():
+        if key[0:4] == 'ACS_' or key in ('LINES', 'COLS'):
+            setattr(curses, key, value)
+
+    return stdscr
+
+# This is a similar wrapper for start_color(), which adds the COLORS and
+# COLOR_PAIRS variables which are only available after start_color() is
+# called.
+
+def start_color():
+    import _curses, curses
+    retval = _curses.start_color()
+    if hasattr(_curses, 'COLORS'):
+        curses.COLORS = _curses.COLORS
+    if hasattr(_curses, 'COLOR_PAIRS'):
+        curses.COLOR_PAIRS = _curses.COLOR_PAIRS
+    return retval
+
+# Import Python has_key() implementation if _curses doesn't contain has_key()
+
+try:
+    has_key
+except NameError:
+    from has_key import has_key

Added: vendor/Python/current/Lib/curses/ascii.py
===================================================================
--- vendor/Python/current/Lib/curses/ascii.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/curses/ascii.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,99 @@
+"""Constants and membership tests for ASCII characters"""
+
+NUL     = 0x00  # ^@
+SOH     = 0x01  # ^A
+STX     = 0x02  # ^B
+ETX     = 0x03  # ^C
+EOT     = 0x04  # ^D
+ENQ     = 0x05  # ^E
+ACK     = 0x06  # ^F
+BEL     = 0x07  # ^G
+BS      = 0x08  # ^H
+TAB     = 0x09  # ^I
+HT      = 0x09  # ^I
+LF      = 0x0a  # ^J
+NL      = 0x0a  # ^J
+VT      = 0x0b  # ^K
+FF      = 0x0c  # ^L
+CR      = 0x0d  # ^M
+SO      = 0x0e  # ^N
+SI      = 0x0f  # ^O
+DLE     = 0x10  # ^P
+DC1     = 0x11  # ^Q
+DC2     = 0x12  # ^R
+DC3     = 0x13  # ^S
+DC4     = 0x14  # ^T
+NAK     = 0x15  # ^U
+SYN     = 0x16  # ^V
+ETB     = 0x17  # ^W
+CAN     = 0x18  # ^X
+EM      = 0x19  # ^Y
+SUB     = 0x1a  # ^Z
+ESC     = 0x1b  # ^[
+FS      = 0x1c  # ^\
+GS      = 0x1d  # ^]
+RS      = 0x1e  # ^^
+US      = 0x1f  # ^_
+SP      = 0x20  # space
+DEL     = 0x7f  # delete
+
+controlnames = [
+"NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL",
+"BS",  "HT",  "LF",  "VT",  "FF",  "CR",  "SO",  "SI",
+"DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB",
+"CAN", "EM",  "SUB", "ESC", "FS",  "GS",  "RS",  "US",
+"SP"
+]
+
+def _ctoi(c):
+    if type(c) == type(""):
+        return ord(c)
+    else:
+        return c
+
+def isalnum(c): return isalpha(c) or isdigit(c)
+def isalpha(c): return isupper(c) or islower(c)
+def isascii(c): return _ctoi(c) <= 127          # ?
+def isblank(c): return _ctoi(c) in (8,32)
+def iscntrl(c): return _ctoi(c) <= 31
+def isdigit(c): return _ctoi(c) >= 48 and _ctoi(c) <= 57
+def isgraph(c): return _ctoi(c) >= 33 and _ctoi(c) <= 126
+def islower(c): return _ctoi(c) >= 97 and _ctoi(c) <= 122
+def isprint(c): return _ctoi(c) >= 32 and _ctoi(c) <= 126
+def ispunct(c): return _ctoi(c) != 32 and not isalnum(c)
+def isspace(c): return _ctoi(c) in (9, 10, 11, 12, 13, 32)
+def isupper(c): return _ctoi(c) >= 65 and _ctoi(c) <= 90
+def isxdigit(c): return isdigit(c) or \
+    (_ctoi(c) >= 65 and _ctoi(c) <= 70) or (_ctoi(c) >= 97 and _ctoi(c) <= 102)
+def isctrl(c): return _ctoi(c) < 32
+def ismeta(c): return _ctoi(c) > 127
+
+def ascii(c):
+    if type(c) == type(""):
+        return chr(_ctoi(c) & 0x7f)
+    else:
+        return _ctoi(c) & 0x7f
+
+def ctrl(c):
+    if type(c) == type(""):
+        return chr(_ctoi(c) & 0x1f)
+    else:
+        return _ctoi(c) & 0x1f
+
+def alt(c):
+    if type(c) == type(""):
+        return chr(_ctoi(c) | 0x80)
+    else:
+        return _ctoi(c) | 0x80
+
+def unctrl(c):
+    bits = _ctoi(c)
+    if bits == 0x7f:
+        rep = "^?"
+    elif isprint(bits & 0x7f):
+        rep = chr(bits & 0x7f)
+    else:
+        rep = "^" + chr(((bits & 0x7f) | 0x20) + 0x20)
+    if bits & 0x80:
+        return "!" + rep
+    return rep

Added: vendor/Python/current/Lib/curses/has_key.py
===================================================================
--- vendor/Python/current/Lib/curses/has_key.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/curses/has_key.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,192 @@
+
+#
+# Emulation of has_key() function for platforms that don't use ncurses
+#
+
+import _curses
+
+# Table mapping curses keys to the terminfo capability name
+
+_capability_names = {
+    _curses.KEY_A1: 'ka1',
+    _curses.KEY_A3: 'ka3',
+    _curses.KEY_B2: 'kb2',
+    _curses.KEY_BACKSPACE: 'kbs',
+    _curses.KEY_BEG: 'kbeg',
+    _curses.KEY_BTAB: 'kcbt',
+    _curses.KEY_C1: 'kc1',
+    _curses.KEY_C3: 'kc3',
+    _curses.KEY_CANCEL: 'kcan',
+    _curses.KEY_CATAB: 'ktbc',
+    _curses.KEY_CLEAR: 'kclr',
+    _curses.KEY_CLOSE: 'kclo',
+    _curses.KEY_COMMAND: 'kcmd',
+    _curses.KEY_COPY: 'kcpy',
+    _curses.KEY_CREATE: 'kcrt',
+    _curses.KEY_CTAB: 'kctab',
+    _curses.KEY_DC: 'kdch1',
+    _curses.KEY_DL: 'kdl1',
+    _curses.KEY_DOWN: 'kcud1',
+    _curses.KEY_EIC: 'krmir',
+    _curses.KEY_END: 'kend',
+    _curses.KEY_ENTER: 'kent',
+    _curses.KEY_EOL: 'kel',
+    _curses.KEY_EOS: 'ked',
+    _curses.KEY_EXIT: 'kext',
+    _curses.KEY_F0: 'kf0',
+    _curses.KEY_F1: 'kf1',
+    _curses.KEY_F10: 'kf10',
+    _curses.KEY_F11: 'kf11',
+    _curses.KEY_F12: 'kf12',
+    _curses.KEY_F13: 'kf13',
+    _curses.KEY_F14: 'kf14',
+    _curses.KEY_F15: 'kf15',
+    _curses.KEY_F16: 'kf16',
+    _curses.KEY_F17: 'kf17',
+    _curses.KEY_F18: 'kf18',
+    _curses.KEY_F19: 'kf19',
+    _curses.KEY_F2: 'kf2',
+    _curses.KEY_F20: 'kf20',
+    _curses.KEY_F21: 'kf21',
+    _curses.KEY_F22: 'kf22',
+    _curses.KEY_F23: 'kf23',
+    _curses.KEY_F24: 'kf24',
+    _curses.KEY_F25: 'kf25',
+    _curses.KEY_F26: 'kf26',
+    _curses.KEY_F27: 'kf27',
+    _curses.KEY_F28: 'kf28',
+    _curses.KEY_F29: 'kf29',
+    _curses.KEY_F3: 'kf3',
+    _curses.KEY_F30: 'kf30',
+    _curses.KEY_F31: 'kf31',
+    _curses.KEY_F32: 'kf32',
+    _curses.KEY_F33: 'kf33',
+    _curses.KEY_F34: 'kf34',
+    _curses.KEY_F35: 'kf35',
+    _curses.KEY_F36: 'kf36',
+    _curses.KEY_F37: 'kf37',
+    _curses.KEY_F38: 'kf38',
+    _curses.KEY_F39: 'kf39',
+    _curses.KEY_F4: 'kf4',
+    _curses.KEY_F40: 'kf40',
+    _curses.KEY_F41: 'kf41',
+    _curses.KEY_F42: 'kf42',
+    _curses.KEY_F43: 'kf43',
+    _curses.KEY_F44: 'kf44',
+    _curses.KEY_F45: 'kf45',
+    _curses.KEY_F46: 'kf46',
+    _curses.KEY_F47: 'kf47',
+    _curses.KEY_F48: 'kf48',
+    _curses.KEY_F49: 'kf49',
+    _curses.KEY_F5: 'kf5',
+    _curses.KEY_F50: 'kf50',
+    _curses.KEY_F51: 'kf51',
+    _curses.KEY_F52: 'kf52',
+    _curses.KEY_F53: 'kf53',
+    _curses.KEY_F54: 'kf54',
+    _curses.KEY_F55: 'kf55',
+    _curses.KEY_F56: 'kf56',
+    _curses.KEY_F57: 'kf57',
+    _curses.KEY_F58: 'kf58',
+    _curses.KEY_F59: 'kf59',
+    _curses.KEY_F6: 'kf6',
+    _curses.KEY_F60: 'kf60',
+    _curses.KEY_F61: 'kf61',
+    _curses.KEY_F62: 'kf62',
+    _curses.KEY_F63: 'kf63',
+    _curses.KEY_F7: 'kf7',
+    _curses.KEY_F8: 'kf8',
+    _curses.KEY_F9: 'kf9',
+    _curses.KEY_FIND: 'kfnd',
+    _curses.KEY_HELP: 'khlp',
+    _curses.KEY_HOME: 'khome',
+    _curses.KEY_IC: 'kich1',
+    _curses.KEY_IL: 'kil1',
+    _curses.KEY_LEFT: 'kcub1',
+    _curses.KEY_LL: 'kll',
+    _curses.KEY_MARK: 'kmrk',
+    _curses.KEY_MESSAGE: 'kmsg',
+    _curses.KEY_MOVE: 'kmov',
+    _curses.KEY_NEXT: 'knxt',
+    _curses.KEY_NPAGE: 'knp',
+    _curses.KEY_OPEN: 'kopn',
+    _curses.KEY_OPTIONS: 'kopt',
+    _curses.KEY_PPAGE: 'kpp',
+    _curses.KEY_PREVIOUS: 'kprv',
+    _curses.KEY_PRINT: 'kprt',
+    _curses.KEY_REDO: 'krdo',
+    _curses.KEY_REFERENCE: 'kref',
+    _curses.KEY_REFRESH: 'krfr',
+    _curses.KEY_REPLACE: 'krpl',
+    _curses.KEY_RESTART: 'krst',
+    _curses.KEY_RESUME: 'kres',
+    _curses.KEY_RIGHT: 'kcuf1',
+    _curses.KEY_SAVE: 'ksav',
+    _curses.KEY_SBEG: 'kBEG',
+    _curses.KEY_SCANCEL: 'kCAN',
+    _curses.KEY_SCOMMAND: 'kCMD',
+    _curses.KEY_SCOPY: 'kCPY',
+    _curses.KEY_SCREATE: 'kCRT',
+    _curses.KEY_SDC: 'kDC',
+    _curses.KEY_SDL: 'kDL',
+    _curses.KEY_SELECT: 'kslt',
+    _curses.KEY_SEND: 'kEND',
+    _curses.KEY_SEOL: 'kEOL',
+    _curses.KEY_SEXIT: 'kEXT',
+    _curses.KEY_SF: 'kind',
+    _curses.KEY_SFIND: 'kFND',
+    _curses.KEY_SHELP: 'kHLP',
+    _curses.KEY_SHOME: 'kHOM',
+    _curses.KEY_SIC: 'kIC',
+    _curses.KEY_SLEFT: 'kLFT',
+    _curses.KEY_SMESSAGE: 'kMSG',
+    _curses.KEY_SMOVE: 'kMOV',
+    _curses.KEY_SNEXT: 'kNXT',
+    _curses.KEY_SOPTIONS: 'kOPT',
+    _curses.KEY_SPREVIOUS: 'kPRV',
+    _curses.KEY_SPRINT: 'kPRT',
+    _curses.KEY_SR: 'kri',
+    _curses.KEY_SREDO: 'kRDO',
+    _curses.KEY_SREPLACE: 'kRPL',
+    _curses.KEY_SRIGHT: 'kRIT',
+    _curses.KEY_SRSUME: 'kRES',
+    _curses.KEY_SSAVE: 'kSAV',
+    _curses.KEY_SSUSPEND: 'kSPD',
+    _curses.KEY_STAB: 'khts',
+    _curses.KEY_SUNDO: 'kUND',
+    _curses.KEY_SUSPEND: 'kspd',
+    _curses.KEY_UNDO: 'kund',
+    _curses.KEY_UP: 'kcuu1'
+    }
+
+def has_key(ch):
+    if isinstance(ch, str):
+        ch = ord(ch)
+
+    # Figure out the correct capability name for the keycode.
+    capability_name = _capability_names.get(ch)
+    if capability_name is None:
+        return False
+
+    #Check the current terminal description for that capability;
+    #if present, return true, else return false.
+    if _curses.tigetstr( capability_name ):
+        return True
+    else:
+        return False
+
+if __name__ == '__main__':
+    # Compare the output of this implementation and the ncurses has_key,
+    # on platforms where has_key is already available
+    try:
+        L = []
+        _curses.initscr()
+        for key in _capability_names.keys():
+            system = _curses.has_key(key)
+            python = has_key(key)
+            if system != python:
+                L.append( 'Mismatch for key %s, system=%i, Python=%i'
+                          % (_curses.keyname( key ), system, python) )
+    finally:
+        _curses.endwin()
+        for i in L: print i

Added: vendor/Python/current/Lib/curses/panel.py
===================================================================
--- vendor/Python/current/Lib/curses/panel.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/curses/panel.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,8 @@
+"""curses.panel
+
+Module for using panels with curses.
+"""
+
+__revision__ = "$Id: panel.py 36560 2004-07-18 06:16:08Z tim_one $"
+
+from _curses_panel import *

Added: vendor/Python/current/Lib/curses/textpad.py
===================================================================
--- vendor/Python/current/Lib/curses/textpad.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/curses/textpad.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,173 @@
+"""Simple textbox editing widget with Emacs-like keybindings."""
+
+import curses, ascii
+
+def rectangle(win, uly, ulx, lry, lrx):
+    """Draw a rectangle with corners at the provided upper-left
+    and lower-right coordinates.
+    """
+    win.vline(uly+1, ulx, curses.ACS_VLINE, lry - uly - 1)
+    win.hline(uly, ulx+1, curses.ACS_HLINE, lrx - ulx - 1)
+    win.hline(lry, ulx+1, curses.ACS_HLINE, lrx - ulx - 1)
+    win.vline(uly+1, lrx, curses.ACS_VLINE, lry - uly - 1)
+    win.addch(uly, ulx, curses.ACS_ULCORNER)
+    win.addch(uly, lrx, curses.ACS_URCORNER)
+    win.addch(lry, lrx, curses.ACS_LRCORNER)
+    win.addch(lry, ulx, curses.ACS_LLCORNER)
+
+class Textbox:
+    """Editing widget using the interior of a window object.
+     Supports the following Emacs-like key bindings:
+
+    Ctrl-A      Go to left edge of window.
+    Ctrl-B      Cursor left, wrapping to previous line if appropriate.
+    Ctrl-D      Delete character under cursor.
+    Ctrl-E      Go to right edge (stripspaces off) or end of line (stripspaces on).
+    Ctrl-F      Cursor right, wrapping to next line when appropriate.
+    Ctrl-G      Terminate, returning the window contents.
+    Ctrl-H      Delete character backward.
+    Ctrl-J      Terminate if the window is 1 line, otherwise insert newline.
+    Ctrl-K      If line is blank, delete it, otherwise clear to end of line.
+    Ctrl-L      Refresh screen.
+    Ctrl-N      Cursor down; move down one line.
+    Ctrl-O      Insert a blank line at cursor location.
+    Ctrl-P      Cursor up; move up one line.
+
+    Move operations do nothing if the cursor is at an edge where the movement
+    is not possible.  The following synonyms are supported where possible:
+
+    KEY_LEFT = Ctrl-B, KEY_RIGHT = Ctrl-F, KEY_UP = Ctrl-P, KEY_DOWN = Ctrl-N
+    KEY_BACKSPACE = Ctrl-h
+    """
+    def __init__(self, win):
+        self.win = win
+        (self.maxy, self.maxx) = win.getmaxyx()
+        self.maxy = self.maxy - 1
+        self.maxx = self.maxx - 1
+        self.stripspaces = 1
+        self.lastcmd = None
+        win.keypad(1)
+
+    def _end_of_line(self, y):
+        "Go to the location of the first blank on the given line."
+        last = self.maxx
+        while 1:
+            if ascii.ascii(self.win.inch(y, last)) != ascii.SP:
+                last = min(self.maxx, last+1)
+                break
+            elif last == 0:
+                break
+            last = last - 1
+        return last
+
+    def do_command(self, ch):
+        "Process a single editing command."
+        (y, x) = self.win.getyx()
+        self.lastcmd = ch
+        if ascii.isprint(ch):
+            if y < self.maxy or x < self.maxx:
+                # The try-catch ignores the error we trigger from some curses
+                # versions by trying to write into the lowest-rightmost spot
+                # in the window.
+                try:
+                    self.win.addch(ch)
+                except curses.error:
+                    pass
+        elif ch == ascii.SOH:                           # ^a
+            self.win.move(y, 0)
+        elif ch in (ascii.STX,curses.KEY_LEFT, ascii.BS,curses.KEY_BACKSPACE):
+            if x > 0:
+                self.win.move(y, x-1)
+            elif y == 0:
+                pass
+            elif self.stripspaces:
+                self.win.move(y-1, self._end_of_line(y-1))
+            else:
+                self.win.move(y-1, self.maxx)
+            if ch in (ascii.BS, curses.KEY_BACKSPACE):
+                self.win.delch()
+        elif ch == ascii.EOT:                           # ^d
+            self.win.delch()
+        elif ch == ascii.ENQ:                           # ^e
+            if self.stripspaces:
+                self.win.move(y, self._end_of_line(y))
+            else:
+                self.win.move(y, self.maxx)
+        elif ch in (ascii.ACK, curses.KEY_RIGHT):       # ^f
+            if x < self.maxx:
+                self.win.move(y, x+1)
+            elif y == self.maxy:
+                pass
+            else:
+                self.win.move(y+1, 0)
+        elif ch == ascii.BEL:                           # ^g
+            return 0
+        elif ch == ascii.NL:                            # ^j
+            if self.maxy == 0:
+                return 0
+            elif y < self.maxy:
+                self.win.move(y+1, 0)
+        elif ch == ascii.VT:                            # ^k
+            if x == 0 and self._end_of_line(y) == 0:
+                self.win.deleteln()
+            else:
+                # first undo the effect of self._end_of_line
+                self.win.move(y, x)
+                self.win.clrtoeol()
+        elif ch == ascii.FF:                            # ^l
+            self.win.refresh()
+        elif ch in (ascii.SO, curses.KEY_DOWN):         # ^n
+            if y < self.maxy:
+                self.win.move(y+1, x)
+                if x > self._end_of_line(y+1):
+                    self.win.move(y+1, self._end_of_line(y+1))
+        elif ch == ascii.SI:                            # ^o
+            self.win.insertln()
+        elif ch in (ascii.DLE, curses.KEY_UP):          # ^p
+            if y > 0:
+                self.win.move(y-1, x)
+                if x > self._end_of_line(y-1):
+                    self.win.move(y-1, self._end_of_line(y-1))
+        return 1
+
+    def gather(self):
+        "Collect and return the contents of the window."
+        result = ""
+        for y in range(self.maxy+1):
+            self.win.move(y, 0)
+            stop = self._end_of_line(y)
+            if stop == 0 and self.stripspaces:
+                continue
+            for x in range(self.maxx+1):
+                if self.stripspaces and x == stop:
+                    break
+                result = result + chr(ascii.ascii(self.win.inch(y, x)))
+            if self.maxy > 0:
+                result = result + "\n"
+        return result
+
+    def edit(self, validate=None):
+        "Edit in the widget window and collect the results."
+        while 1:
+            ch = self.win.getch()
+            if validate:
+                ch = validate(ch)
+            if not ch:
+                continue
+            if not self.do_command(ch):
+                break
+            self.win.refresh()
+        return self.gather()
+
+if __name__ == '__main__':
+    def test_editbox(stdscr):
+        ncols, nlines = 9, 4
+        uly, ulx = 15, 20
+        stdscr.addstr(uly-2, ulx, "Use Ctrl-G to end editing.")
+        win = curses.newwin(nlines, ncols, uly, ulx)
+        rectangle(stdscr, uly-1, ulx-1, uly + nlines, ulx + ncols)
+        stdscr.refresh()
+        return Textbox(win).edit()
+
+    str = curses.wrapper(test_editbox)
+    print 'Contents of text box:', repr(str)

Added: vendor/Python/current/Lib/curses/wrapper.py
===================================================================
--- vendor/Python/current/Lib/curses/wrapper.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/curses/wrapper.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,50 @@
+"""curses.wrapper
+
+Contains one function, wrapper(), which runs another function which
+should be the rest of your curses-based application.  If the
+application raises an exception, wrapper() will restore the terminal
+to a sane state so you can read the resulting traceback.
+
+"""
+
+import sys, curses
+
+def wrapper(func, *args, **kwds):
+    """Wrapper function that initializes curses and calls another function,
+    restoring normal keyboard/screen behavior on error.
+    The callable object 'func' is then passed the main window 'stdscr'
+    as its first argument, followed by any other arguments passed to
+    wrapper().
+    """
+
+    res = None
+    try:
+        # Initialize curses
+        stdscr=curses.initscr()
+
+        # Turn off echoing of keys, and enter cbreak mode,
+        # where no buffering is performed on keyboard input
+        curses.noecho()
+        curses.cbreak()
+
+        # In keypad mode, escape sequences for special keys
+        # (like the cursor keys) will be interpreted and
+        # a special value like curses.KEY_LEFT will be returned
+        stdscr.keypad(1)
+
+        # Start color, too.  Harmless if the terminal doesn't have
+        # color; user can test with has_color() later on.  The try/catch
+        # works around a minor bit of over-conscientiousness in the curses
+        # module -- the error return from C start_color() is ignorable.
+        try:
+            curses.start_color()
+        except:
+            pass
+
+        return func(stdscr, *args, **kwds)
+    finally:
+        # Set everything back to normal
+        stdscr.keypad(0)
+        curses.echo()
+        curses.nocbreak()
+        curses.endwin()

Added: vendor/Python/current/Lib/dbhash.py
===================================================================
--- vendor/Python/current/Lib/dbhash.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/dbhash.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,16 @@
+"""Provide a (g)dbm-compatible interface to bsddb.hashopen."""
+
+import sys
+try:
+    import bsddb
+except ImportError:
+    # prevent a second import of this module from spuriously succeeding
+    del sys.modules[__name__]
+    raise
+
+__all__ = ["error","open"]
+
+error = bsddb.error                     # Exported for anydbm
+
+def open(file, flag = 'r', mode=0666):
+    return bsddb.hashopen(file, flag, mode)

Added: vendor/Python/current/Lib/decimal.py
===================================================================
--- vendor/Python/current/Lib/decimal.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/decimal.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,3137 @@
+# Copyright (c) 2004 Python Software Foundation.
+# All rights reserved.
+
+# Written by Eric Price <eprice at tjhsst.edu>
+#    and Facundo Batista <facundo at taniquetil.com.ar>
+#    and Raymond Hettinger <python at rcn.com>
+#    and Aahz <aahz at pobox.com>
+#    and Tim Peters
+
+# This module is currently Py2.3 compatible and should be kept that way
+# unless a major compelling advantage arises.  IOW, 2.3 compatibility is
+# strongly preferred, but not guaranteed.
+
+# Also, this module should be kept in sync with the latest updates of
+# the IBM specification as it evolves.  Those updates will be treated
+# as bug fixes (deviation from the spec is a compatibility, usability
+# bug) and will be backported.  At this point the spec is stabilizing
+# and the updates are becoming fewer, smaller, and less significant.
+
+"""
+This is a Py2.3 implementation of decimal floating point arithmetic based on
+the General Decimal Arithmetic Specification:
+
+    www2.hursley.ibm.com/decimal/decarith.html
+
+and IEEE standard 854-1987:
+
+    www.cs.berkeley.edu/~ejr/projects/754/private/drafts/854-1987/dir.html
+
+Decimal floating point has finite precision with arbitrarily large bounds.
+
+The purpose of the module is to support arithmetic using familiar
+"schoolhouse" rules and to avoid the some of tricky representation
+issues associated with binary floating point.  The package is especially
+useful for financial applications or for contexts where users have
+expectations that are at odds with binary floating point (for instance,
+in binary floating point, 1.00 % 0.1 gives 0.09999999999999995 instead
+of the expected Decimal("0.00") returned by decimal floating point).
+
+Here are some examples of using the decimal module:
+
+>>> from decimal import *
+>>> setcontext(ExtendedContext)
+>>> Decimal(0)
+Decimal("0")
+>>> Decimal("1")
+Decimal("1")
+>>> Decimal("-.0123")
+Decimal("-0.0123")
+>>> Decimal(123456)
+Decimal("123456")
+>>> Decimal("123.45e12345678901234567890")
+Decimal("1.2345E+12345678901234567892")
+>>> Decimal("1.33") + Decimal("1.27")
+Decimal("2.60")
+>>> Decimal("12.34") + Decimal("3.87") - Decimal("18.41")
+Decimal("-2.20")
+>>> dig = Decimal(1)
+>>> print dig / Decimal(3)
+0.333333333
+>>> getcontext().prec = 18
+>>> print dig / Decimal(3)
+0.333333333333333333
+>>> print dig.sqrt()
+1
+>>> print Decimal(3).sqrt()
+1.73205080756887729
+>>> print Decimal(3) ** 123
+4.85192780976896427E+58
+>>> inf = Decimal(1) / Decimal(0)
+>>> print inf
+Infinity
+>>> neginf = Decimal(-1) / Decimal(0)
+>>> print neginf
+-Infinity
+>>> print neginf + inf
+NaN
+>>> print neginf * inf
+-Infinity
+>>> print dig / 0
+Infinity
+>>> getcontext().traps[DivisionByZero] = 1
+>>> print dig / 0
+Traceback (most recent call last):
+  ...
+  ...
+  ...
+DivisionByZero: x / 0
+>>> c = Context()
+>>> c.traps[InvalidOperation] = 0
+>>> print c.flags[InvalidOperation]
+0
+>>> c.divide(Decimal(0), Decimal(0))
+Decimal("NaN")
+>>> c.traps[InvalidOperation] = 1
+>>> print c.flags[InvalidOperation]
+1
+>>> c.flags[InvalidOperation] = 0
+>>> print c.flags[InvalidOperation]
+0
+>>> print c.divide(Decimal(0), Decimal(0))
+Traceback (most recent call last):
+  ...
+  ...
+  ...
+InvalidOperation: 0 / 0
+>>> print c.flags[InvalidOperation]
+1
+>>> c.flags[InvalidOperation] = 0
+>>> c.traps[InvalidOperation] = 0
+>>> print c.divide(Decimal(0), Decimal(0))
+NaN
+>>> print c.flags[InvalidOperation]
+1
+>>>
+"""
+
+__all__ = [
+    # Two major classes
+    'Decimal', 'Context',
+
+    # Contexts
+    'DefaultContext', 'BasicContext', 'ExtendedContext',
+
+    # Exceptions
+    'DecimalException', 'Clamped', 'InvalidOperation', 'DivisionByZero',
+    'Inexact', 'Rounded', 'Subnormal', 'Overflow', 'Underflow',
+
+    # Constants for use in setting up contexts
+    'ROUND_DOWN', 'ROUND_HALF_UP', 'ROUND_HALF_EVEN', 'ROUND_CEILING',
+    'ROUND_FLOOR', 'ROUND_UP', 'ROUND_HALF_DOWN',
+
+    # Functions for manipulating contexts
+    'setcontext', 'getcontext', 'localcontext'
+]
+
+import copy as _copy
+
+#Rounding
+ROUND_DOWN = 'ROUND_DOWN'
+ROUND_HALF_UP = 'ROUND_HALF_UP'
+ROUND_HALF_EVEN = 'ROUND_HALF_EVEN'
+ROUND_CEILING = 'ROUND_CEILING'
+ROUND_FLOOR = 'ROUND_FLOOR'
+ROUND_UP = 'ROUND_UP'
+ROUND_HALF_DOWN = 'ROUND_HALF_DOWN'
+
+#Rounding decision (not part of the public API)
+NEVER_ROUND = 'NEVER_ROUND'    # Round in division (non-divmod), sqrt ONLY
+ALWAYS_ROUND = 'ALWAYS_ROUND'  # Every operation rounds at end.
+
+#Errors
+
+class DecimalException(ArithmeticError):
+    """Base exception class.
+
+    Used exceptions derive from this.
+    If an exception derives from another exception besides this (such as
+    Underflow (Inexact, Rounded, Subnormal) that indicates that it is only
+    called if the others are present.  This isn't actually used for
+    anything, though.
+
+    handle  -- Called when context._raise_error is called and the
+               trap_enabler is set.  First argument is self, second is the
+               context.  More arguments can be given, those being after
+               the explanation in _raise_error (For example,
+               context._raise_error(NewError, '(-x)!', self._sign) would
+               call NewError().handle(context, self._sign).)
+
+    To define a new exception, it should be sufficient to have it derive
+    from DecimalException.
+    """
+    def handle(self, context, *args):
+        pass
+
+
+class Clamped(DecimalException):
+    """Exponent of a 0 changed to fit bounds.
+
+    This occurs and signals clamped if the exponent of a result has been
+    altered in order to fit the constraints of a specific concrete
+    representation. This may occur when the exponent of a zero result would
+    be outside the bounds of a representation, or  when a large normal
+    number would have an encoded exponent that cannot be represented. In
+    this latter case, the exponent is reduced to fit and the corresponding
+    number of zero digits are appended to the coefficient ("fold-down").
+    """
+
+
+class InvalidOperation(DecimalException):
+    """An invalid operation was performed.
+
+    Various bad things cause this:
+
+    Something creates a signaling NaN
+    -INF + INF
+     0 * (+-)INF
+     (+-)INF / (+-)INF
+    x % 0
+    (+-)INF % x
+    x._rescale( non-integer )
+    sqrt(-x) , x > 0
+    0 ** 0
+    x ** (non-integer)
+    x ** (+-)INF
+    An operand is invalid
+    """
+    def handle(self, context, *args):
+        if args:
+            if args[0] == 1: #sNaN, must drop 's' but keep diagnostics
+                return Decimal( (args[1]._sign, args[1]._int, 'n') )
+        return NaN
+
+class ConversionSyntax(InvalidOperation):
+    """Trying to convert badly formed string.
+
+    This occurs and signals invalid-operation if an string is being
+    converted to a number and it does not conform to the numeric string
+    syntax. The result is [0,qNaN].
+    """
+
+    def handle(self, context, *args):
+        return (0, (0,), 'n') #Passed to something which uses a tuple.
+
+class DivisionByZero(DecimalException, ZeroDivisionError):
+    """Division by 0.
+
+    This occurs and signals division-by-zero if division of a finite number
+    by zero was attempted (during a divide-integer or divide operation, or a
+    power operation with negative right-hand operand), and the dividend was
+    not zero.
+
+    The result of the operation is [sign,inf], where sign is the exclusive
+    or of the signs of the operands for divide, or is 1 for an odd power of
+    -0, for power.
+    """
+
+    def handle(self, context, sign, double = None, *args):
+        if double is not None:
+            return (Infsign[sign],)*2
+        return Infsign[sign]
+
+class DivisionImpossible(InvalidOperation):
+    """Cannot perform the division adequately.
+
+    This occurs and signals invalid-operation if the integer result of a
+    divide-integer or remainder operation had too many digits (would be
+    longer than precision). The result is [0,qNaN].
+    """
+
+    def handle(self, context, *args):
+        return (NaN, NaN)
+
+class DivisionUndefined(InvalidOperation, ZeroDivisionError):
+    """Undefined result of division.
+
+    This occurs and signals invalid-operation if division by zero was
+    attempted (during a divide-integer, divide, or remainder operation), and
+    the dividend is also zero. The result is [0,qNaN].
+    """
+
+    def handle(self, context, tup=None, *args):
+        if tup is not None:
+            return (NaN, NaN) #for 0 %0, 0 // 0
+        return NaN
+
+class Inexact(DecimalException):
+    """Had to round, losing information.
+
+    This occurs and signals inexact whenever the result of an operation is
+    not exact (that is, it needed to be rounded and any discarded digits
+    were non-zero), or if an overflow or underflow condition occurs. The
+    result in all cases is unchanged.
+
+    The inexact signal may be tested (or trapped) to determine if a given
+    operation (or sequence of operations) was inexact.
+    """
+    pass
+
+class InvalidContext(InvalidOperation):
+    """Invalid context.  Unknown rounding, for example.
+
+    This occurs and signals invalid-operation if an invalid context was
+    detected during an operation. This can occur if contexts are not checked
+    on creation and either the precision exceeds the capability of the
+    underlying concrete representation or an unknown or unsupported rounding
+    was specified. These aspects of the context need only be checked when
+    the values are required to be used. The result is [0,qNaN].
+    """
+
+    def handle(self, context, *args):
+        return NaN
+
+class Rounded(DecimalException):
+    """Number got rounded (not  necessarily changed during rounding).
+
+    This occurs and signals rounded whenever the result of an operation is
+    rounded (that is, some zero or non-zero digits were discarded from the
+    coefficient), or if an overflow or underflow condition occurs. The
+    result in all cases is unchanged.
+
+    The rounded signal may be tested (or trapped) to determine if a given
+    operation (or sequence of operations) caused a loss of precision.
+    """
+    pass
+
+class Subnormal(DecimalException):
+    """Exponent < Emin before rounding.
+
+    This occurs and signals subnormal whenever the result of a conversion or
+    operation is subnormal (that is, its adjusted exponent is less than
+    Emin, before any rounding). The result in all cases is unchanged.
+
+    The subnormal signal may be tested (or trapped) to determine if a given
+    or operation (or sequence of operations) yielded a subnormal result.
+    """
+    pass
+
+class Overflow(Inexact, Rounded):
+    """Numerical overflow.
+
+    This occurs and signals overflow if the adjusted exponent of a result
+    (from a conversion or from an operation that is not an attempt to divide
+    by zero), after rounding, would be greater than the largest value that
+    can be handled by the implementation (the value Emax).
+
+    The result depends on the rounding mode:
+
+    For round-half-up and round-half-even (and for round-half-down and
+    round-up, if implemented), the result of the operation is [sign,inf],
+    where sign is the sign of the intermediate result. For round-down, the
+    result is the largest finite number that can be represented in the
+    current precision, with the sign of the intermediate result. For
+    round-ceiling, the result is the same as for round-down if the sign of
+    the intermediate result is 1, or is [0,inf] otherwise. For round-floor,
+    the result is the same as for round-down if the sign of the intermediate
+    result is 0, or is [1,inf] otherwise. In all cases, Inexact and Rounded
+    will also be raised.
+   """
+
+    def handle(self, context, sign, *args):
+        if context.rounding in (ROUND_HALF_UP, ROUND_HALF_EVEN,
+                                     ROUND_HALF_DOWN, ROUND_UP):
+            return Infsign[sign]
+        if sign == 0:
+            if context.rounding == ROUND_CEILING:
+                return Infsign[sign]
+            return Decimal((sign, (9,)*context.prec,
+                            context.Emax-context.prec+1))
+        if sign == 1:
+            if context.rounding == ROUND_FLOOR:
+                return Infsign[sign]
+            return Decimal( (sign, (9,)*context.prec,
+                             context.Emax-context.prec+1))
+
+
+class Underflow(Inexact, Rounded, Subnormal):
+    """Numerical underflow with result rounded to 0.
+
+    This occurs and signals underflow if a result is inexact and the
+    adjusted exponent of the result would be smaller (more negative) than
+    the smallest value that can be handled by the implementation (the value
+    Emin). That is, the result is both inexact and subnormal.
+
+    The result after an underflow will be a subnormal number rounded, if
+    necessary, so that its exponent is not less than Etiny. This may result
+    in 0 with the sign of the intermediate result and an exponent of Etiny.
+
+    In all cases, Inexact, Rounded, and Subnormal will also be raised.
+    """
+
+# List of public traps and flags
+_signals = [Clamped, DivisionByZero, Inexact, Overflow, Rounded,
+           Underflow, InvalidOperation, Subnormal]
+
+# Map conditions (per the spec) to signals
+_condition_map = {ConversionSyntax:InvalidOperation,
+                  DivisionImpossible:InvalidOperation,
+                  DivisionUndefined:InvalidOperation,
+                  InvalidContext:InvalidOperation}
+
+##### Context Functions #######################################
+
+# The getcontext() and setcontext() function manage access to a thread-local
+# current context.  Py2.4 offers direct support for thread locals.  If that
+# is not available, use threading.currentThread() which is slower but will
+# work for older Pythons.  If threads are not part of the build, create a
+# mock threading object with threading.local() returning the module namespace.
+
+try:
+    import threading
+except ImportError:
+    # Python was compiled without threads; create a mock object instead
+    import sys
+    class MockThreading:
+        def local(self, sys=sys):
+            return sys.modules[__name__]
+    threading = MockThreading()
+    del sys, MockThreading
+
+try:
+    threading.local
+
+except AttributeError:
+
+    #To fix reloading, force it to create a new context
+    #Old contexts have different exceptions in their dicts, making problems.
+    if hasattr(threading.currentThread(), '__decimal_context__'):
+        del threading.currentThread().__decimal_context__
+
+    def setcontext(context):
+        """Set this thread's context to context."""
+        if context in (DefaultContext, BasicContext, ExtendedContext):
+            context = context.copy()
+            context.clear_flags()
+        threading.currentThread().__decimal_context__ = context
+
+    def getcontext():
+        """Returns this thread's context.
+
+        If this thread does not yet have a context, returns
+        a new context and sets this thread's context.
+        New contexts are copies of DefaultContext.
+        """
+        try:
+            return threading.currentThread().__decimal_context__
+        except AttributeError:
+            context = Context()
+            threading.currentThread().__decimal_context__ = context
+            return context
+
+else:
+
+    local = threading.local()
+    if hasattr(local, '__decimal_context__'):
+        del local.__decimal_context__
+
+    def getcontext(_local=local):
+        """Returns this thread's context.
+
+        If this thread does not yet have a context, returns
+        a new context and sets this thread's context.
+        New contexts are copies of DefaultContext.
+        """
+        try:
+            return _local.__decimal_context__
+        except AttributeError:
+            context = Context()
+            _local.__decimal_context__ = context
+            return context
+
+    def setcontext(context, _local=local):
+        """Set this thread's context to context."""
+        if context in (DefaultContext, BasicContext, ExtendedContext):
+            context = context.copy()
+            context.clear_flags()
+        _local.__decimal_context__ = context
+
+    del threading, local        # Don't contaminate the namespace
+
+def localcontext(ctx=None):
+    """Return a context manager for a copy of the supplied context
+
+    Uses a copy of the current context if no context is specified
+    The returned context manager creates a local decimal context
+    in a with statement:
+        def sin(x):
+             with localcontext() as ctx:
+                 ctx.prec += 2
+                 # Rest of sin calculation algorithm
+                 # uses a precision 2 greater than normal
+             return +s # Convert result to normal precision
+
+         def sin(x):
+             with localcontext(ExtendedContext):
+                 # Rest of sin calculation algorithm
+                 # uses the Extended Context from the
+                 # General Decimal Arithmetic Specification
+             return +s # Convert result to normal context
+
+    """
+    # The string below can't be included in the docstring until Python 2.6
+    # as the doctest module doesn't understand __future__ statements
+    """
+    >>> from __future__ import with_statement
+    >>> print getcontext().prec
+    28
+    >>> with localcontext():
+    ...     ctx = getcontext()
+    ...     ctx.prec += 2
+    ...     print ctx.prec
+    ...
+    30
+    >>> with localcontext(ExtendedContext):
+    ...     print getcontext().prec
+    ...
+    9
+    >>> print getcontext().prec
+    28
+    """
+    if ctx is None: ctx = getcontext()
+    return _ContextManager(ctx)
+
+
+##### Decimal class ###########################################
+
+class Decimal(object):
+    """Floating point class for decimal arithmetic."""
+
+    __slots__ = ('_exp','_int','_sign', '_is_special')
+    # Generally, the value of the Decimal instance is given by
+    #  (-1)**_sign * _int * 10**_exp
+    # Special values are signified by _is_special == True
+
+    # We're immutable, so use __new__ not __init__
+    def __new__(cls, value="0", context=None):
+        """Create a decimal point instance.
+
+        >>> Decimal('3.14')              # string input
+        Decimal("3.14")
+        >>> Decimal((0, (3, 1, 4), -2))  # tuple input (sign, digit_tuple, exponent)
+        Decimal("3.14")
+        >>> Decimal(314)                 # int or long
+        Decimal("314")
+        >>> Decimal(Decimal(314))        # another decimal instance
+        Decimal("314")
+        """
+
+        self = object.__new__(cls)
+        self._is_special = False
+
+        # From an internal working value
+        if isinstance(value, _WorkRep):
+            self._sign = value.sign
+            self._int = tuple(map(int, str(value.int)))
+            self._exp = int(value.exp)
+            return self
+
+        # From another decimal
+        if isinstance(value, Decimal):
+            self._exp  = value._exp
+            self._sign = value._sign
+            self._int  = value._int
+            self._is_special  = value._is_special
+            return self
+
+        # From an integer
+        if isinstance(value, (int,long)):
+            if value >= 0:
+                self._sign = 0
+            else:
+                self._sign = 1
+            self._exp = 0
+            self._int = tuple(map(int, str(abs(value))))
+            return self
+
+        # tuple/list conversion (possibly from as_tuple())
+        if isinstance(value, (list,tuple)):
+            if len(value) != 3:
+                raise ValueError, 'Invalid arguments'
+            if value[0] not in (0,1):
+                raise ValueError, 'Invalid sign'
+            for digit in value[1]:
+                if not isinstance(digit, (int,long)) or digit < 0:
+                    raise ValueError, "The second value in the tuple must be composed of non negative integer elements."
+
+            self._sign = value[0]
+            self._int  = tuple(value[1])
+            if value[2] in ('F','n','N'):
+                self._exp = value[2]
+                self._is_special = True
+            else:
+                self._exp  = int(value[2])
+            return self
+
+        if isinstance(value, float):
+            raise TypeError("Cannot convert float to Decimal.  " +
+                            "First convert the float to a string")
+
+        # Other argument types may require the context during interpretation
+        if context is None:
+            context = getcontext()
+
+        # From a string
+        # REs insist on real strings, so we can too.
+        if isinstance(value, basestring):
+            if _isinfinity(value):
+                self._exp = 'F'
+                self._int = (0,)
+                self._is_special = True
+                if _isinfinity(value) == 1:
+                    self._sign = 0
+                else:
+                    self._sign = 1
+                return self
+            if _isnan(value):
+                sig, sign, diag = _isnan(value)
+                self._is_special = True
+                if len(diag) > context.prec: #Diagnostic info too long
+                    self._sign, self._int, self._exp = \
+                                context._raise_error(ConversionSyntax)
+                    return self
+                if sig == 1:
+                    self._exp = 'n' #qNaN
+                else: #sig == 2
+                    self._exp = 'N' #sNaN
+                self._sign = sign
+                self._int = tuple(map(int, diag)) #Diagnostic info
+                return self
+            try:
+                self._sign, self._int, self._exp = _string2exact(value)
+            except ValueError:
+                self._is_special = True
+                self._sign, self._int, self._exp = context._raise_error(ConversionSyntax)
+            return self
+
+        raise TypeError("Cannot convert %r to Decimal" % value)
+
+    def _isnan(self):
+        """Returns whether the number is not actually one.
+
+        0 if a number
+        1 if NaN
+        2 if sNaN
+        """
+        if self._is_special:
+            exp = self._exp
+            if exp == 'n':
+                return 1
+            elif exp == 'N':
+                return 2
+        return 0
+
+    def _isinfinity(self):
+        """Returns whether the number is infinite
+
+        0 if finite or not a number
+        1 if +INF
+        -1 if -INF
+        """
+        if self._exp == 'F':
+            if self._sign:
+                return -1
+            return 1
+        return 0
+
+    def _check_nans(self, other = None, context=None):
+        """Returns whether the number is not actually one.
+
+        if self, other are sNaN, signal
+        if self, other are NaN return nan
+        return 0
+
+        Done before operations.
+        """
+
+        self_is_nan = self._isnan()
+        if other is None:
+            other_is_nan = False
+        else:
+            other_is_nan = other._isnan()
+
+        if self_is_nan or other_is_nan:
+            if context is None:
+                context = getcontext()
+
+            if self_is_nan == 2:
+                return context._raise_error(InvalidOperation, 'sNaN',
+                                        1, self)
+            if other_is_nan == 2:
+                return context._raise_error(InvalidOperation, 'sNaN',
+                                        1, other)
+            if self_is_nan:
+                return self
+
+            return other
+        return 0
+
+    def __nonzero__(self):
+        """Is the number non-zero?
+
+        0 if self == 0
+        1 if self != 0
+        """
+        if self._is_special:
+            return 1
+        return sum(self._int) != 0
+
+    def __cmp__(self, other, context=None):
+        other = _convert_other(other)
+        if other is NotImplemented:
+            return other
+
+        if self._is_special or other._is_special:
+            ans = self._check_nans(other, context)
+            if ans:
+                return 1 # Comparison involving NaN's always reports self > other
+
+            # INF = INF
+            return cmp(self._isinfinity(), other._isinfinity())
+
+        if not self and not other:
+            return 0 #If both 0, sign comparison isn't certain.
+
+        #If different signs, neg one is less
+        if other._sign < self._sign:
+            return -1
+        if self._sign < other._sign:
+            return 1
+
+        self_adjusted = self.adjusted()
+        other_adjusted = other.adjusted()
+        if self_adjusted == other_adjusted and \
+           self._int + (0,)*(self._exp - other._exp) == \
+           other._int + (0,)*(other._exp - self._exp):
+            return 0 #equal, except in precision. ([0]*(-x) = [])
+        elif self_adjusted > other_adjusted and self._int[0] != 0:
+            return (-1)**self._sign
+        elif self_adjusted < other_adjusted and other._int[0] != 0:
+            return -((-1)**self._sign)
+
+        # Need to round, so make sure we have a valid context
+        if context is None:
+            context = getcontext()
+
+        context = context._shallow_copy()
+        rounding = context._set_rounding(ROUND_UP) #round away from 0
+
+        flags = context._ignore_all_flags()
+        res = self.__sub__(other, context=context)
+
+        context._regard_flags(*flags)
+
+        context.rounding = rounding
+
+        if not res:
+            return 0
+        elif res._sign:
+            return -1
+        return 1
+
+    def __eq__(self, other):
+        if not isinstance(other, (Decimal, int, long)):
+            return NotImplemented
+        return self.__cmp__(other) == 0
+
+    def __ne__(self, other):
+        if not isinstance(other, (Decimal, int, long)):
+            return NotImplemented
+        return self.__cmp__(other) != 0
+
+    def compare(self, other, context=None):
+        """Compares one to another.
+
+        -1 => a < b
+        0  => a = b
+        1  => a > b
+        NaN => one is NaN
+        Like __cmp__, but returns Decimal instances.
+        """
+        other = _convert_other(other)
+        if other is NotImplemented:
+            return other
+
+        #compare(NaN, NaN) = NaN
+        if (self._is_special or other and other._is_special):
+            ans = self._check_nans(other, context)
+            if ans:
+                return ans
+
+        return Decimal(self.__cmp__(other, context))
+
+    def __hash__(self):
+        """x.__hash__() <==> hash(x)"""
+        # Decimal integers must hash the same as the ints
+        # Non-integer decimals are normalized and hashed as strings
+        # Normalization assures that hash(100E-1) == hash(10)
+        if self._is_special:
+            if self._isnan():
+                raise TypeError('Cannot hash a NaN value.')
+            return hash(str(self))
+        i = int(self)
+        if self == Decimal(i):
+            return hash(i)
+        assert self.__nonzero__()   # '-0' handled by integer case
+        return hash(str(self.normalize()))
+
+    def as_tuple(self):
+        """Represents the number as a triple tuple.
+
+        To show the internals exactly as they are.
+        """
+        return (self._sign, self._int, self._exp)
+
+    def __repr__(self):
+        """Represents the number as an instance of Decimal."""
+        # Invariant:  eval(repr(d)) == d
+        return 'Decimal("%s")' % str(self)
+
+    def __str__(self, eng = 0, context=None):
+        """Return string representation of the number in scientific notation.
+
+        Captures all of the information in the underlying representation.
+        """
+
+        if self._is_special:
+            if self._isnan():
+                minus = '-'*self._sign
+                if self._int == (0,):
+                    info = ''
+                else:
+                    info = ''.join(map(str, self._int))
+                if self._isnan() == 2:
+                    return minus + 'sNaN' + info
+                return minus + 'NaN' + info
+            if self._isinfinity():
+                minus = '-'*self._sign
+                return minus + 'Infinity'
+
+        if context is None:
+            context = getcontext()
+
+        tmp = map(str, self._int)
+        numdigits = len(self._int)
+        leftdigits = self._exp + numdigits
+        if eng and not self: #self = 0eX wants 0[.0[0]]eY, not [[0]0]0eY
+            if self._exp < 0 and self._exp >= -6: #short, no need for e/E
+                s = '-'*self._sign + '0.' + '0'*(abs(self._exp))
+                return s
+            #exp is closest mult. of 3 >= self._exp
+            exp = ((self._exp - 1)// 3 + 1) * 3
+            if exp != self._exp:
+                s = '0.'+'0'*(exp - self._exp)
+            else:
+                s = '0'
+            if exp != 0:
+                if context.capitals:
+                    s += 'E'
+                else:
+                    s += 'e'
+                if exp > 0:
+                    s += '+' #0.0e+3, not 0.0e3
+                s += str(exp)
+            s = '-'*self._sign + s
+            return s
+        if eng:
+            dotplace = (leftdigits-1)%3+1
+            adjexp = leftdigits -1 - (leftdigits-1)%3
+        else:
+            adjexp = leftdigits-1
+            dotplace = 1
+        if self._exp == 0:
+            pass
+        elif self._exp < 0 and adjexp >= 0:
+            tmp.insert(leftdigits, '.')
+        elif self._exp < 0 and adjexp >= -6:
+            tmp[0:0] = ['0'] * int(-leftdigits)
+            tmp.insert(0, '0.')
+        else:
+            if numdigits > dotplace:
+                tmp.insert(dotplace, '.')
+            elif numdigits < dotplace:
+                tmp.extend(['0']*(dotplace-numdigits))
+            if adjexp:
+                if not context.capitals:
+                    tmp.append('e')
+                else:
+                    tmp.append('E')
+                    if adjexp > 0:
+                        tmp.append('+')
+                tmp.append(str(adjexp))
+        if eng:
+            while tmp[0:1] == ['0']:
+                tmp[0:1] = []
+            if len(tmp) == 0 or tmp[0] == '.' or tmp[0].lower() == 'e':
+                tmp[0:0] = ['0']
+        if self._sign:
+            tmp.insert(0, '-')
+
+        return ''.join(tmp)
+
+    def to_eng_string(self, context=None):
+        """Convert to engineering-type string.
+
+        Engineering notation has an exponent which is a multiple of 3, so there
+        are up to 3 digits left of the decimal place.
+
+        Same rules for when in exponential and when as a value as in __str__.
+        """
+        return self.__str__(eng=1, context=context)
+
+    def __neg__(self, context=None):
+        """Returns a copy with the sign switched.
+
+        Rounds, if it has reason.
+        """
+        if self._is_special:
+            ans = self._check_nans(context=context)
+            if ans:
+                return ans
+
+        if not self:
+            # -Decimal('0') is Decimal('0'), not Decimal('-0')
+            sign = 0
+        elif self._sign:
+            sign = 0
+        else:
+            sign = 1
+
+        if context is None:
+            context = getcontext()
+        if context._rounding_decision == ALWAYS_ROUND:
+            return Decimal((sign, self._int, self._exp))._fix(context)
+        return Decimal( (sign, self._int, self._exp))
+
+    def __pos__(self, context=None):
+        """Returns a copy, unless it is a sNaN.
+
+        Rounds the number (if more then precision digits)
+        """
+        if self._is_special:
+            ans = self._check_nans(context=context)
+            if ans:
+                return ans
+
+        sign = self._sign
+        if not self:
+            # + (-0) = 0
+            sign = 0
+
+        if context is None:
+            context = getcontext()
+
+        if context._rounding_decision == ALWAYS_ROUND:
+            ans = self._fix(context)
+        else:
+            ans = Decimal(self)
+        ans._sign = sign
+        return ans
+
+    def __abs__(self, round=1, context=None):
+        """Returns the absolute value of self.
+
+        If the second argument is 0, do not round.
+        """
+        if self._is_special:
+            ans = self._check_nans(context=context)
+            if ans:
+                return ans
+
+        if not round:
+            if context is None:
+                context = getcontext()
+            context = context._shallow_copy()
+            context._set_rounding_decision(NEVER_ROUND)
+
+        if self._sign:
+            ans = self.__neg__(context=context)
+        else:
+            ans = self.__pos__(context=context)
+
+        return ans
+
+    def __add__(self, other, context=None):
+        """Returns self + other.
+
+        -INF + INF (or the reverse) cause InvalidOperation errors.
+        """
+        other = _convert_other(other)
+        if other is NotImplemented:
+            return other
+
+        if context is None:
+            context = getcontext()
+
+        if self._is_special or other._is_special:
+            ans = self._check_nans(other, context)
+            if ans:
+                return ans
+
+            if self._isinfinity():
+                #If both INF, same sign => same as both, opposite => error.
+                if self._sign != other._sign and other._isinfinity():
+                    return context._raise_error(InvalidOperation, '-INF + INF')
+                return Decimal(self)
+            if other._isinfinity():
+                return Decimal(other)  #Can't both be infinity here
+
+        shouldround = context._rounding_decision == ALWAYS_ROUND
+
+        exp = min(self._exp, other._exp)
+        negativezero = 0
+        if context.rounding == ROUND_FLOOR and self._sign != other._sign:
+            #If the answer is 0, the sign should be negative, in this case.
+            negativezero = 1
+
+        if not self and not other:
+            sign = min(self._sign, other._sign)
+            if negativezero:
+                sign = 1
+            return Decimal( (sign, (0,), exp))
+        if not self:
+            exp = max(exp, other._exp - context.prec-1)
+            ans = other._rescale(exp, watchexp=0, context=context)
+            if shouldround:
+                ans = ans._fix(context)
+            return ans
+        if not other:
+            exp = max(exp, self._exp - context.prec-1)
+            ans = self._rescale(exp, watchexp=0, context=context)
+            if shouldround:
+                ans = ans._fix(context)
+            return ans
+
+        op1 = _WorkRep(self)
+        op2 = _WorkRep(other)
+        op1, op2 = _normalize(op1, op2, shouldround, context.prec)
+
+        result = _WorkRep()
+        if op1.sign != op2.sign:
+            # Equal and opposite
+            if op1.int == op2.int:
+                if exp < context.Etiny():
+                    exp = context.Etiny()
+                    context._raise_error(Clamped)
+                return Decimal((negativezero, (0,), exp))
+            if op1.int < op2.int:
+                op1, op2 = op2, op1
+                #OK, now abs(op1) > abs(op2)
+            if op1.sign == 1:
+                result.sign = 1
+                op1.sign, op2.sign = op2.sign, op1.sign
+            else:
+                result.sign = 0
+                #So we know the sign, and op1 > 0.
+        elif op1.sign == 1:
+            result.sign = 1
+            op1.sign, op2.sign = (0, 0)
+        else:
+            result.sign = 0
+        #Now, op1 > abs(op2) > 0
+
+        if op2.sign == 0:
+            result.int = op1.int + op2.int
+        else:
+            result.int = op1.int - op2.int
+
+        result.exp = op1.exp
+        ans = Decimal(result)
+        if shouldround:
+            ans = ans._fix(context)
+        return ans
+
+    __radd__ = __add__
+
+    def __sub__(self, other, context=None):
+        """Return self + (-other)"""
+        other = _convert_other(other)
+        if other is NotImplemented:
+            return other
+
+        if self._is_special or other._is_special:
+            ans = self._check_nans(other, context=context)
+            if ans:
+                return ans
+
+        # -Decimal(0) = Decimal(0), which we don't want since
+        # (-0 - 0 = -0 + (-0) = -0, but -0 + 0 = 0.)
+        # so we change the sign directly to a copy
+        tmp = Decimal(other)
+        tmp._sign = 1-tmp._sign
+
+        return self.__add__(tmp, context=context)
+
+    def __rsub__(self, other, context=None):
+        """Return other + (-self)"""
+        other = _convert_other(other)
+        if other is NotImplemented:
+            return other
+
+        tmp = Decimal(self)
+        tmp._sign = 1 - tmp._sign
+        return other.__add__(tmp, context=context)
+
+    def _increment(self, round=1, context=None):
+        """Special case of add, adding 1eExponent
+
+        Since it is common, (rounding, for example) this adds
+        (sign)*one E self._exp to the number more efficiently than add.
+
+        For example:
+        Decimal('5.624e10')._increment() == Decimal('5.625e10')
+        """
+        if self._is_special:
+            ans = self._check_nans(context=context)
+            if ans:
+                return ans
+
+            return Decimal(self) # Must be infinite, and incrementing makes no difference
+
+        L = list(self._int)
+        L[-1] += 1
+        spot = len(L)-1
+        while L[spot] == 10:
+            L[spot] = 0
+            if spot == 0:
+                L[0:0] = [1]
+                break
+            L[spot-1] += 1
+            spot -= 1
+        ans = Decimal((self._sign, L, self._exp))
+
+        if context is None:
+            context = getcontext()
+        if round and context._rounding_decision == ALWAYS_ROUND:
+            ans = ans._fix(context)
+        return ans
+
+    def __mul__(self, other, context=None):
+        """Return self * other.
+
+        (+-) INF * 0 (or its reverse) raise InvalidOperation.
+        """
+        other = _convert_other(other)
+        if other is NotImplemented:
+            return other
+
+        if context is None:
+            context = getcontext()
+
+        resultsign = self._sign ^ other._sign
+
+        if self._is_special or other._is_special:
+            ans = self._check_nans(other, context)
+            if ans:
+                return ans
+
+            if self._isinfinity():
+                if not other:
+                    return context._raise_error(InvalidOperation, '(+-)INF * 0')
+                return Infsign[resultsign]
+
+            if other._isinfinity():
+                if not self:
+                    return context._raise_error(InvalidOperation, '0 * (+-)INF')
+                return Infsign[resultsign]
+
+        resultexp = self._exp + other._exp
+        shouldround = context._rounding_decision == ALWAYS_ROUND
+
+        # Special case for multiplying by zero
+        if not self or not other:
+            ans = Decimal((resultsign, (0,), resultexp))
+            if shouldround:
+                #Fixing in case the exponent is out of bounds
+                ans = ans._fix(context)
+            return ans
+
+        # Special case for multiplying by power of 10
+        if self._int == (1,):
+            ans = Decimal((resultsign, other._int, resultexp))
+            if shouldround:
+                ans = ans._fix(context)
+            return ans
+        if other._int == (1,):
+            ans = Decimal((resultsign, self._int, resultexp))
+            if shouldround:
+                ans = ans._fix(context)
+            return ans
+
+        op1 = _WorkRep(self)
+        op2 = _WorkRep(other)
+
+        ans = Decimal( (resultsign, map(int, str(op1.int * op2.int)), resultexp))
+        if shouldround:
+            ans = ans._fix(context)
+
+        return ans
+    __rmul__ = __mul__
+
+    def __div__(self, other, context=None):
+        """Return self / other."""
+        return self._divide(other, context=context)
+    __truediv__ = __div__
+
+    def _divide(self, other, divmod = 0, context=None):
+        """Return a / b, to context.prec precision.
+
+        divmod:
+        0 => true division
+        1 => (a //b, a%b)
+        2 => a //b
+        3 => a%b
+
+        Actually, if divmod is 2 or 3 a tuple is returned, but errors for
+        computing the other value are not raised.
+        """
+        other = _convert_other(other)
+        if other is NotImplemented:
+            if divmod in (0, 1):
+                return NotImplemented
+            return (NotImplemented, NotImplemented)
+
+        if context is None:
+            context = getcontext()
+
+        sign = self._sign ^ other._sign
+
+        if self._is_special or other._is_special:
+            ans = self._check_nans(other, context)
+            if ans:
+                if divmod:
+                    return (ans, ans)
+                return ans
+
+            if self._isinfinity() and other._isinfinity():
+                if divmod:
+                    return (context._raise_error(InvalidOperation,
+                                            '(+-)INF // (+-)INF'),
+                            context._raise_error(InvalidOperation,
+                                            '(+-)INF % (+-)INF'))
+                return context._raise_error(InvalidOperation, '(+-)INF/(+-)INF')
+
+            if self._isinfinity():
+                if divmod == 1:
+                    return (Infsign[sign],
+                            context._raise_error(InvalidOperation, 'INF % x'))
+                elif divmod == 2:
+                    return (Infsign[sign], NaN)
+                elif divmod == 3:
+                    return (Infsign[sign],
+                            context._raise_error(InvalidOperation, 'INF % x'))
+                return Infsign[sign]
+
+            if other._isinfinity():
+                if divmod:
+                    return (Decimal((sign, (0,), 0)), Decimal(self))
+                context._raise_error(Clamped, 'Division by infinity')
+                return Decimal((sign, (0,), context.Etiny()))
+
+        # Special cases for zeroes
+        if not self and not other:
+            if divmod:
+                return context._raise_error(DivisionUndefined, '0 / 0', 1)
+            return context._raise_error(DivisionUndefined, '0 / 0')
+
+        if not self:
+            if divmod:
+                otherside = Decimal(self)
+                otherside._exp = min(self._exp, other._exp)
+                return (Decimal((sign, (0,), 0)),  otherside)
+            exp = self._exp - other._exp
+            if exp < context.Etiny():
+                exp = context.Etiny()
+                context._raise_error(Clamped, '0e-x / y')
+            if exp > context.Emax:
+                exp = context.Emax
+                context._raise_error(Clamped, '0e+x / y')
+            return Decimal( (sign, (0,), exp) )
+
+        if not other:
+            if divmod:
+                return context._raise_error(DivisionByZero, 'divmod(x,0)',
+                                           sign, 1)
+            return context._raise_error(DivisionByZero, 'x / 0', sign)
+
+        #OK, so neither = 0, INF or NaN
+
+        shouldround = context._rounding_decision == ALWAYS_ROUND
+
+        #If we're dividing into ints, and self < other, stop.
+        #self.__abs__(0) does not round.
+        if divmod and (self.__abs__(0, context) < other.__abs__(0, context)):
+
+            if divmod == 1 or divmod == 3:
+                exp = min(self._exp, other._exp)
+                ans2 = self._rescale(exp, context=context, watchexp=0)
+                if shouldround:
+                    ans2 = ans2._fix(context)
+                return (Decimal( (sign, (0,), 0) ),
+                        ans2)
+
+            elif divmod == 2:
+                #Don't round the mod part, if we don't need it.
+                return (Decimal( (sign, (0,), 0) ), Decimal(self))
+
+        op1 = _WorkRep(self)
+        op2 = _WorkRep(other)
+        op1, op2, adjust = _adjust_coefficients(op1, op2)
+        res = _WorkRep( (sign, 0, (op1.exp - op2.exp)) )
+        if divmod and res.exp > context.prec + 1:
+            return context._raise_error(DivisionImpossible)
+
+        prec_limit = 10 ** context.prec
+        while 1:
+            while op2.int <= op1.int:
+                res.int += 1
+                op1.int -= op2.int
+            if res.exp == 0 and divmod:
+                if res.int >= prec_limit and shouldround:
+                    return context._raise_error(DivisionImpossible)
+                otherside = Decimal(op1)
+                frozen = context._ignore_all_flags()
+
+                exp = min(self._exp, other._exp)
+                otherside = otherside._rescale(exp, context=context, watchexp=0)
+                context._regard_flags(*frozen)
+                if shouldround:
+                    otherside = otherside._fix(context)
+                return (Decimal(res), otherside)
+
+            if op1.int == 0 and adjust >= 0 and not divmod:
+                break
+            if res.int >= prec_limit and shouldround:
+                if divmod:
+                    return context._raise_error(DivisionImpossible)
+                shouldround=1
+                # Really, the answer is a bit higher, so adding a one to
+                # the end will make sure the rounding is right.
+                if op1.int != 0:
+                    res.int *= 10
+                    res.int += 1
+                    res.exp -= 1
+
+                break
+            res.int *= 10
+            res.exp -= 1
+            adjust += 1
+            op1.int *= 10
+            op1.exp -= 1
+
+            if res.exp == 0 and divmod and op2.int > op1.int:
+                #Solves an error in precision.  Same as a previous block.
+
+                if res.int >= prec_limit and shouldround:
+                    return context._raise_error(DivisionImpossible)
+                otherside = Decimal(op1)
+                frozen = context._ignore_all_flags()
+
+                exp = min(self._exp, other._exp)
+                otherside = otherside._rescale(exp, context=context)
+
+                context._regard_flags(*frozen)
+
+                return (Decimal(res), otherside)
+
+        ans = Decimal(res)
+        if shouldround:
+            ans = ans._fix(context)
+        return ans
+
+    def __rdiv__(self, other, context=None):
+        """Swaps self/other and returns __div__."""
+        other = _convert_other(other)
+        if other is NotImplemented:
+            return other
+        return other.__div__(self, context=context)
+    __rtruediv__ = __rdiv__
+
+    def __divmod__(self, other, context=None):
+        """
+        (self // other, self % other)
+        """
+        return self._divide(other, 1, context)
+
+    def __rdivmod__(self, other, context=None):
+        """Swaps self/other and returns __divmod__."""
+        other = _convert_other(other)
+        if other is NotImplemented:
+            return other
+        return other.__divmod__(self, context=context)
+
+    def __mod__(self, other, context=None):
+        """
+        self % other
+        """
+        other = _convert_other(other)
+        if other is NotImplemented:
+            return other
+
+        if self._is_special or other._is_special:
+            ans = self._check_nans(other, context)
+            if ans:
+                return ans
+
+        if self and not other:
+            return context._raise_error(InvalidOperation, 'x % 0')
+
+        return self._divide(other, 3, context)[1]
+
+    def __rmod__(self, other, context=None):
+        """Swaps self/other and returns __mod__."""
+        other = _convert_other(other)
+        if other is NotImplemented:
+            return other
+        return other.__mod__(self, context=context)
+
+    def remainder_near(self, other, context=None):
+        """
+        Remainder nearest to 0-  abs(remainder-near) <= other/2
+        """
+        other = _convert_other(other)
+        if other is NotImplemented:
+            return other
+
+        if self._is_special or other._is_special:
+            ans = self._check_nans(other, context)
+            if ans:
+                return ans
+        if self and not other:
+            return context._raise_error(InvalidOperation, 'x % 0')
+
+        if context is None:
+            context = getcontext()
+        # If DivisionImpossible causes an error, do not leave Rounded/Inexact
+        # ignored in the calling function.
+        context = context._shallow_copy()
+        flags = context._ignore_flags(Rounded, Inexact)
+        #keep DivisionImpossible flags
+        (side, r) = self.__divmod__(other, context=context)
+
+        if r._isnan():
+            context._regard_flags(*flags)
+            return r
+
+        context = context._shallow_copy()
+        rounding = context._set_rounding_decision(NEVER_ROUND)
+
+        if other._sign:
+            comparison = other.__div__(Decimal(-2), context=context)
+        else:
+            comparison = other.__div__(Decimal(2), context=context)
+
+        context._set_rounding_decision(rounding)
+        context._regard_flags(*flags)
+
+        s1, s2 = r._sign, comparison._sign
+        r._sign, comparison._sign = 0, 0
+
+        if r < comparison:
+            r._sign, comparison._sign = s1, s2
+            #Get flags now
+            self.__divmod__(other, context=context)
+            return r._fix(context)
+        r._sign, comparison._sign = s1, s2
+
+        rounding = context._set_rounding_decision(NEVER_ROUND)
+
+        (side, r) = self.__divmod__(other, context=context)
+        context._set_rounding_decision(rounding)
+        if r._isnan():
+            return r
+
+        decrease = not side._iseven()
+        rounding = context._set_rounding_decision(NEVER_ROUND)
+        side = side.__abs__(context=context)
+        context._set_rounding_decision(rounding)
+
+        s1, s2 = r._sign, comparison._sign
+        r._sign, comparison._sign = 0, 0
+        if r > comparison or decrease and r == comparison:
+            r._sign, comparison._sign = s1, s2
+            context.prec += 1
+            if len(side.__add__(Decimal(1), context=context)._int) >= context.prec:
+                context.prec -= 1
+                return context._raise_error(DivisionImpossible)[1]
+            context.prec -= 1
+            if self._sign == other._sign:
+                r = r.__sub__(other, context=context)
+            else:
+                r = r.__add__(other, context=context)
+        else:
+            r._sign, comparison._sign = s1, s2
+
+        return r._fix(context)
+
+    def __floordiv__(self, other, context=None):
+        """self // other"""
+        return self._divide(other, 2, context)[0]
+
+    def __rfloordiv__(self, other, context=None):
+        """Swaps self/other and returns __floordiv__."""
+        other = _convert_other(other)
+        if other is NotImplemented:
+            return other
+        return other.__floordiv__(self, context=context)
+
+    def __float__(self):
+        """Float representation."""
+        return float(str(self))
+
+    def __int__(self):
+        """Converts self to an int, truncating if necessary."""
+        if self._is_special:
+            if self._isnan():
+                context = getcontext()
+                return context._raise_error(InvalidContext)
+            elif self._isinfinity():
+                raise OverflowError, "Cannot convert infinity to long"
+        if self._exp >= 0:
+            s = ''.join(map(str, self._int)) + '0'*self._exp
+        else:
+            s = ''.join(map(str, self._int))[:self._exp]
+        if s == '':
+            s = '0'
+        sign = '-'*self._sign
+        return int(sign + s)
+
+    def __long__(self):
+        """Converts to a long.
+
+        Equivalent to long(int(self))
+        """
+        return long(self.__int__())
+
+    def _fix(self, context):
+        """Round if it is necessary to keep self within prec precision.
+
+        Rounds and fixes the exponent.  Does not raise on a sNaN.
+
+        Arguments:
+        self - Decimal instance
+        context - context used.
+        """
+        if self._is_special:
+            return self
+        if context is None:
+            context = getcontext()
+        prec = context.prec
+        ans = self._fixexponents(context)
+        if len(ans._int) > prec:
+            ans = ans._round(prec, context=context)
+            ans = ans._fixexponents(context)
+        return ans
+
+    def _fixexponents(self, context):
+        """Fix the exponents and return a copy with the exponent in bounds.
+        Only call if known to not be a special value.
+        """
+        folddown = context._clamp
+        Emin = context.Emin
+        ans = self
+        ans_adjusted = ans.adjusted()
+        if ans_adjusted < Emin:
+            Etiny = context.Etiny()
+            if ans._exp < Etiny:
+                if not ans:
+                    ans = Decimal(self)
+                    ans._exp = Etiny
+                    context._raise_error(Clamped)
+                    return ans
+                ans = ans._rescale(Etiny, context=context)
+                #It isn't zero, and exp < Emin => subnormal
+                context._raise_error(Subnormal)
+                if context.flags[Inexact]:
+                    context._raise_error(Underflow)
+            else:
+                if ans:
+                    #Only raise subnormal if non-zero.
+                    context._raise_error(Subnormal)
+        else:
+            Etop = context.Etop()
+            if folddown and ans._exp > Etop:
+                context._raise_error(Clamped)
+                ans = ans._rescale(Etop, context=context)
+            else:
+                Emax = context.Emax
+                if ans_adjusted > Emax:
+                    if not ans:
+                        ans = Decimal(self)
+                        ans._exp = Emax
+                        context._raise_error(Clamped)
+                        return ans
+                    context._raise_error(Inexact)
+                    context._raise_error(Rounded)
+                    return context._raise_error(Overflow, 'above Emax', ans._sign)
+        return ans
+
+    def _round(self, prec=None, rounding=None, context=None):
+        """Returns a rounded version of self.
+
+        You can specify the precision or rounding method.  Otherwise, the
+        context determines it.
+        """
+
+        if self._is_special:
+            ans = self._check_nans(context=context)
+            if ans:
+                return ans
+
+            if self._isinfinity():
+                return Decimal(self)
+
+        if context is None:
+            context = getcontext()
+
+        if rounding is None:
+            rounding = context.rounding
+        if prec is None:
+            prec = context.prec
+
+        if not self:
+            if prec <= 0:
+                dig = (0,)
+                exp = len(self._int) - prec + self._exp
+            else:
+                dig = (0,) * prec
+                exp = len(self._int) + self._exp - prec
+            ans = Decimal((self._sign, dig, exp))
+            context._raise_error(Rounded)
+            return ans
+
+        if prec == 0:
+            temp = Decimal(self)
+            temp._int = (0,)+temp._int
+            prec = 1
+        elif prec < 0:
+            exp = self._exp + len(self._int) - prec - 1
+            temp = Decimal( (self._sign, (0, 1), exp))
+            prec = 1
+        else:
+            temp = Decimal(self)
+
+        numdigits = len(temp._int)
+        if prec == numdigits:
+            return temp
+
+        # See if we need to extend precision
+        expdiff = prec - numdigits
+        if expdiff > 0:
+            tmp = list(temp._int)
+            tmp.extend([0] * expdiff)
+            ans =  Decimal( (temp._sign, tmp, temp._exp - expdiff))
+            return ans
+
+        #OK, but maybe all the lost digits are 0.
+        lostdigits = self._int[expdiff:]
+        if lostdigits == (0,) * len(lostdigits):
+            ans = Decimal( (temp._sign, temp._int[:prec], temp._exp - expdiff))
+            #Rounded, but not Inexact
+            context._raise_error(Rounded)
+            return ans
+
+        # Okay, let's round and lose data
+
+        this_function = getattr(temp, self._pick_rounding_function[rounding])
+        #Now we've got the rounding function
+
+        if prec != context.prec:
+            context = context._shallow_copy()
+            context.prec = prec
+        ans = this_function(prec, expdiff, context)
+        context._raise_error(Rounded)
+        context._raise_error(Inexact, 'Changed in rounding')
+
+        return ans
+
+    _pick_rounding_function = {}
+
+    def _round_down(self, prec, expdiff, context):
+        """Also known as round-towards-0, truncate."""
+        return Decimal( (self._sign, self._int[:prec], self._exp - expdiff) )
+
+    def _round_half_up(self, prec, expdiff, context, tmp = None):
+        """Rounds 5 up (away from 0)"""
+
+        if tmp is None:
+            tmp = Decimal( (self._sign,self._int[:prec], self._exp - expdiff))
+        if self._int[prec] >= 5:
+            tmp = tmp._increment(round=0, context=context)
+            if len(tmp._int) > prec:
+                return Decimal( (tmp._sign, tmp._int[:-1], tmp._exp + 1))
+        return tmp
+
+    def _round_half_even(self, prec, expdiff, context):
+        """Round 5 to even, rest to nearest."""
+
+        tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff))
+        half = (self._int[prec] == 5)
+        if half:
+            for digit in self._int[prec+1:]:
+                if digit != 0:
+                    half = 0
+                    break
+        if half:
+            if self._int[prec-1] & 1 == 0:
+                return tmp
+        return self._round_half_up(prec, expdiff, context, tmp)
+
+    def _round_half_down(self, prec, expdiff, context):
+        """Round 5 down"""
+
+        tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff))
+        half = (self._int[prec] == 5)
+        if half:
+            for digit in self._int[prec+1:]:
+                if digit != 0:
+                    half = 0
+                    break
+        if half:
+            return tmp
+        return self._round_half_up(prec, expdiff, context, tmp)
+
+    def _round_up(self, prec, expdiff, context):
+        """Rounds away from 0."""
+        tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff) )
+        for digit in self._int[prec:]:
+            if digit != 0:
+                tmp = tmp._increment(round=1, context=context)
+                if len(tmp._int) > prec:
+                    return Decimal( (tmp._sign, tmp._int[:-1], tmp._exp + 1))
+                else:
+                    return tmp
+        return tmp
+
+    def _round_ceiling(self, prec, expdiff, context):
+        """Rounds up (not away from 0 if negative.)"""
+        if self._sign:
+            return self._round_down(prec, expdiff, context)
+        else:
+            return self._round_up(prec, expdiff, context)
+
+    def _round_floor(self, prec, expdiff, context):
+        """Rounds down (not towards 0 if negative)"""
+        if not self._sign:
+            return self._round_down(prec, expdiff, context)
+        else:
+            return self._round_up(prec, expdiff, context)
+
+    def __pow__(self, n, modulo = None, context=None):
+        """Return self ** n (mod modulo)
+
+        If modulo is None (default), don't take it mod modulo.
+        """
+        n = _convert_other(n)
+        if n is NotImplemented:
+            return n
+
+        if context is None:
+            context = getcontext()
+
+        if self._is_special or n._is_special or n.adjusted() > 8:
+            #Because the spot << doesn't work with really big exponents
+            if n._isinfinity() or n.adjusted() > 8:
+                return context._raise_error(InvalidOperation, 'x ** INF')
+
+            ans = self._check_nans(n, context)
+            if ans:
+                return ans
+
+        if not n._isinteger():
+            return context._raise_error(InvalidOperation, 'x ** (non-integer)')
+
+        if not self and not n:
+            return context._raise_error(InvalidOperation, '0 ** 0')
+
+        if not n:
+            return Decimal(1)
+
+        if self == Decimal(1):
+            return Decimal(1)
+
+        sign = self._sign and not n._iseven()
+        n = int(n)
+
+        if self._isinfinity():
+            if modulo:
+                return context._raise_error(InvalidOperation, 'INF % x')
+            if n > 0:
+                return Infsign[sign]
+            return Decimal( (sign, (0,), 0) )
+
+        #with ludicrously large exponent, just raise an overflow and return inf.
+        if not modulo and n > 0 and (self._exp + len(self._int) - 1) * n > context.Emax \
+           and self:
+
+            tmp = Decimal('inf')
+            tmp._sign = sign
+            context._raise_error(Rounded)
+            context._raise_error(Inexact)
+            context._raise_error(Overflow, 'Big power', sign)
+            return tmp
+
+        elength = len(str(abs(n)))
+        firstprec = context.prec
+
+        if not modulo and firstprec + elength + 1 > DefaultContext.Emax:
+            return context._raise_error(Overflow, 'Too much precision.', sign)
+
+        mul = Decimal(self)
+        val = Decimal(1)
+        context = context._shallow_copy()
+        context.prec = firstprec + elength + 1
+        if n < 0:
+            #n is a long now, not Decimal instance
+            n = -n
+            mul = Decimal(1).__div__(mul, context=context)
+
+        spot = 1
+        while spot <= n:
+            spot <<= 1
+
+        spot >>= 1
+        #Spot is the highest power of 2 less than n
+        while spot:
+            val = val.__mul__(val, context=context)
+            if val._isinfinity():
+                val = Infsign[sign]
+                break
+            if spot & n:
+                val = val.__mul__(mul, context=context)
+            if modulo is not None:
+                val = val.__mod__(modulo, context=context)
+            spot >>= 1
+        context.prec = firstprec
+
+        if context._rounding_decision == ALWAYS_ROUND:
+            return val._fix(context)
+        return val
+
+    def __rpow__(self, other, context=None):
+        """Swaps self/other and returns __pow__."""
+        other = _convert_other(other)
+        if other is NotImplemented:
+            return other
+        return other.__pow__(self, context=context)
+
+    def normalize(self, context=None):
+        """Normalize- strip trailing 0s, change anything equal to 0 to 0e0"""
+
+        if self._is_special:
+            ans = self._check_nans(context=context)
+            if ans:
+                return ans
+
+        dup = self._fix(context)
+        if dup._isinfinity():
+            return dup
+
+        if not dup:
+            return Decimal( (dup._sign, (0,), 0) )
+        end = len(dup._int)
+        exp = dup._exp
+        while dup._int[end-1] == 0:
+            exp += 1
+            end -= 1
+        return Decimal( (dup._sign, dup._int[:end], exp) )
+
+
+    def quantize(self, exp, rounding=None, context=None, watchexp=1):
+        """Quantize self so its exponent is the same as that of exp.
+
+        Similar to self._rescale(exp._exp) but with error checking.
+        """
+        if self._is_special or exp._is_special:
+            ans = self._check_nans(exp, context)
+            if ans:
+                return ans
+
+            if exp._isinfinity() or self._isinfinity():
+                if exp._isinfinity() and self._isinfinity():
+                    return self  #if both are inf, it is OK
+                if context is None:
+                    context = getcontext()
+                return context._raise_error(InvalidOperation,
+                                        'quantize with one INF')
+        return self._rescale(exp._exp, rounding, context, watchexp)
+
+    def same_quantum(self, other):
+        """Test whether self and other have the same exponent.
+
+        same as self._exp == other._exp, except NaN == sNaN
+        """
+        if self._is_special or other._is_special:
+            if self._isnan() or other._isnan():
+                return self._isnan() and other._isnan() and True
+            if self._isinfinity() or other._isinfinity():
+                return self._isinfinity() and other._isinfinity() and True
+        return self._exp == other._exp
+
+    def _rescale(self, exp, rounding=None, context=None, watchexp=1):
+        """Rescales so that the exponent is exp.
+
+        exp = exp to scale to (an integer)
+        rounding = rounding version
+        watchexp: if set (default) an error is returned if exp is greater
+        than Emax or less than Etiny.
+        """
+        if context is None:
+            context = getcontext()
+
+        if self._is_special:
+            if self._isinfinity():
+                return context._raise_error(InvalidOperation, 'rescale with an INF')
+
+            ans = self._check_nans(context=context)
+            if ans:
+                return ans
+
+        if watchexp and (context.Emax  < exp or context.Etiny() > exp):
+            return context._raise_error(InvalidOperation, 'rescale(a, INF)')
+
+        if not self:
+            ans = Decimal(self)
+            ans._int = (0,)
+            ans._exp = exp
+            return ans
+
+        diff = self._exp - exp
+        digits = len(self._int) + diff
+
+        if watchexp and digits > context.prec:
+            return context._raise_error(InvalidOperation, 'Rescale > prec')
+
+        tmp = Decimal(self)
+        tmp._int = (0,) + tmp._int
+        digits += 1
+
+        if digits < 0:
+            tmp._exp = -digits + tmp._exp
+            tmp._int = (0,1)
+            digits = 1
+        tmp = tmp._round(digits, rounding, context=context)
+
+        if tmp._int[0] == 0 and len(tmp._int) > 1:
+            tmp._int = tmp._int[1:]
+        tmp._exp = exp
+
+        tmp_adjusted = tmp.adjusted()
+        if tmp and tmp_adjusted < context.Emin:
+            context._raise_error(Subnormal)
+        elif tmp and tmp_adjusted > context.Emax:
+            return context._raise_error(InvalidOperation, 'rescale(a, INF)')
+        return tmp
+
+    def to_integral(self, rounding=None, context=None):
+        """Rounds to the nearest integer, without raising inexact, rounded."""
+        if self._is_special:
+            ans = self._check_nans(context=context)
+            if ans:
+                return ans
+        if self._exp >= 0:
+            return self
+        if context is None:
+            context = getcontext()
+        flags = context._ignore_flags(Rounded, Inexact)
+        ans = self._rescale(0, rounding, context=context)
+        context._regard_flags(flags)
+        return ans
+
+    def sqrt(self, context=None):
+        """Return the square root of self.
+
+        Uses a converging algorithm (Xn+1 = 0.5*(Xn + self / Xn))
+        Should quadratically approach the right answer.
+        """
+        if self._is_special:
+            ans = self._check_nans(context=context)
+            if ans:
+                return ans
+
+            if self._isinfinity() and self._sign == 0:
+                return Decimal(self)
+
+        if not self:
+            #exponent = self._exp / 2, using round_down.
+            #if self._exp < 0:
+            #    exp = (self._exp+1) // 2
+            #else:
+            exp = (self._exp) // 2
+            if self._sign == 1:
+                #sqrt(-0) = -0
+                return Decimal( (1, (0,), exp))
+            else:
+                return Decimal( (0, (0,), exp))
+
+        if context is None:
+            context = getcontext()
+
+        if self._sign == 1:
+            return context._raise_error(InvalidOperation, 'sqrt(-x), x > 0')
+
+        tmp = Decimal(self)
+
+        expadd = tmp._exp // 2
+        if tmp._exp & 1:
+            tmp._int += (0,)
+            tmp._exp = 0
+        else:
+            tmp._exp = 0
+
+        context = context._shallow_copy()
+        flags = context._ignore_all_flags()
+        firstprec = context.prec
+        context.prec = 3
+        if tmp.adjusted() & 1 == 0:
+            ans = Decimal( (0, (8,1,9), tmp.adjusted()  - 2) )
+            ans = ans.__add__(tmp.__mul__(Decimal((0, (2,5,9), -2)),
+                                          context=context), context=context)
+            ans._exp -= 1 + tmp.adjusted() // 2
+        else:
+            ans = Decimal( (0, (2,5,9), tmp._exp + len(tmp._int)- 3) )
+            ans = ans.__add__(tmp.__mul__(Decimal((0, (8,1,9), -3)),
+                                          context=context), context=context)
+            ans._exp -= 1 + tmp.adjusted()  // 2
+
+        #ans is now a linear approximation.
+
+        Emax, Emin = context.Emax, context.Emin
+        context.Emax, context.Emin = DefaultContext.Emax, DefaultContext.Emin
+
+        half = Decimal('0.5')
+
+        maxp = firstprec + 2
+        rounding = context._set_rounding(ROUND_HALF_EVEN)
+        while 1:
+            context.prec = min(2*context.prec - 2, maxp)
+            ans = half.__mul__(ans.__add__(tmp.__div__(ans, context=context),
+                                           context=context), context=context)
+            if context.prec == maxp:
+                break
+
+        #round to the answer's precision-- the only error can be 1 ulp.
+        context.prec = firstprec
+        prevexp = ans.adjusted()
+        ans = ans._round(context=context)
+
+        #Now, check if the other last digits are better.
+        context.prec = firstprec + 1
+        # In case we rounded up another digit and we should actually go lower.
+        if prevexp != ans.adjusted():
+            ans._int += (0,)
+            ans._exp -= 1
+
+
+        lower = ans.__sub__(Decimal((0, (5,), ans._exp-1)), context=context)
+        context._set_rounding(ROUND_UP)
+        if lower.__mul__(lower, context=context) > (tmp):
+            ans = ans.__sub__(Decimal((0, (1,), ans._exp)), context=context)
+
+        else:
+            upper = ans.__add__(Decimal((0, (5,), ans._exp-1)),context=context)
+            context._set_rounding(ROUND_DOWN)
+            if upper.__mul__(upper, context=context) < tmp:
+                ans = ans.__add__(Decimal((0, (1,), ans._exp)),context=context)
+
+        ans._exp += expadd
+
+        context.prec = firstprec
+        context.rounding = rounding
+        ans = ans._fix(context)
+
+        rounding = context._set_rounding_decision(NEVER_ROUND)
+        if not ans.__mul__(ans, context=context) == self:
+            # Only rounded/inexact if here.
+            context._regard_flags(flags)
+            context._raise_error(Rounded)
+            context._raise_error(Inexact)
+        else:
+            #Exact answer, so let's set the exponent right.
+            #if self._exp < 0:
+            #    exp = (self._exp +1)// 2
+            #else:
+            exp = self._exp // 2
+            context.prec += ans._exp - exp
+            ans = ans._rescale(exp, context=context)
+            context.prec = firstprec
+            context._regard_flags(flags)
+        context.Emax, context.Emin = Emax, Emin
+
+        return ans._fix(context)
+
+    def max(self, other, context=None):
+        """Returns the larger value.
+
+        like max(self, other) except if one is not a number, returns
+        NaN (and signals if one is sNaN).  Also rounds.
+        """
+        other = _convert_other(other)
+        if other is NotImplemented:
+            return other
+
+        if self._is_special or other._is_special:
+            # if one operand is a quiet NaN and the other is number, then the
+            # number is always returned
+            sn = self._isnan()
+            on = other._isnan()
+            if sn or on:
+                if on == 1 and sn != 2:
+                    return self
+                if sn == 1 and on != 2:
+                    return other
+                return self._check_nans(other, context)
+
+        ans = self
+        c = self.__cmp__(other)
+        if c == 0:
+            # if both operands are finite and equal in numerical value
+            # then an ordering is applied:
+            #
+            # if the signs differ then max returns the operand with the
+            # positive sign and min returns the operand with the negative sign
+            #
+            # if the signs are the same then the exponent is used to select
+            # the result.
+            if self._sign != other._sign:
+                if self._sign:
+                    ans = other
+            elif self._exp < other._exp and not self._sign:
+                ans = other
+            elif self._exp > other._exp and self._sign:
+                ans = other
+        elif c == -1:
+            ans = other
+
+        if context is None:
+            context = getcontext()
+        if context._rounding_decision == ALWAYS_ROUND:
+            return ans._fix(context)
+        return ans
+
+    def min(self, other, context=None):
+        """Returns the smaller value.
+
+        like min(self, other) except if one is not a number, returns
+        NaN (and signals if one is sNaN).  Also rounds.
+        """
+        other = _convert_other(other)
+        if other is NotImplemented:
+            return other
+
+        if self._is_special or other._is_special:
+            # if one operand is a quiet NaN and the other is number, then the
+            # number is always returned
+            sn = self._isnan()
+            on = other._isnan()
+            if sn or on:
+                if on == 1 and sn != 2:
+                    return self
+                if sn == 1 and on != 2:
+                    return other
+                return self._check_nans(other, context)
+
+        ans = self
+        c = self.__cmp__(other)
+        if c == 0:
+            # if both operands are finite and equal in numerical value
+            # then an ordering is applied:
+            #
+            # if the signs differ then max returns the operand with the
+            # positive sign and min returns the operand with the negative sign
+            #
+            # if the signs are the same then the exponent is used to select
+            # the result.
+            if self._sign != other._sign:
+                if other._sign:
+                    ans = other
+            elif self._exp > other._exp and not self._sign:
+                ans = other
+            elif self._exp < other._exp and self._sign:
+                ans = other
+        elif c == 1:
+            ans = other
+
+        if context is None:
+            context = getcontext()
+        if context._rounding_decision == ALWAYS_ROUND:
+            return ans._fix(context)
+        return ans
+
+    def _isinteger(self):
+        """Returns whether self is an integer"""
+        if self._exp >= 0:
+            return True
+        rest = self._int[self._exp:]
+        return rest == (0,)*len(rest)
+
+    def _iseven(self):
+        """Returns 1 if self is even.  Assumes self is an integer."""
+        if self._exp > 0:
+            return 1
+        return self._int[-1+self._exp] & 1 == 0
+
+    def adjusted(self):
+        """Return the adjusted exponent of self"""
+        try:
+            return self._exp + len(self._int) - 1
+        #If NaN or Infinity, self._exp is string
+        except TypeError:
+            return 0
+
+    # support for pickling, copy, and deepcopy
+    def __reduce__(self):
+        return (self.__class__, (str(self),))
+
+    def __copy__(self):
+        if type(self) == Decimal:
+            return self     # I'm immutable; therefore I am my own clone
+        return self.__class__(str(self))
+
+    def __deepcopy__(self, memo):
+        if type(self) == Decimal:
+            return self     # My components are also immutable
+        return self.__class__(str(self))
+
+##### Context class ###########################################
+
+
+# get rounding method function:
+rounding_functions = [name for name in Decimal.__dict__.keys() if name.startswith('_round_')]
+for name in rounding_functions:
+    #name is like _round_half_even, goes to the global ROUND_HALF_EVEN value.
+    globalname = name[1:].upper()
+    val = globals()[globalname]
+    Decimal._pick_rounding_function[val] = name
+
+del name, val, globalname, rounding_functions
+
+class _ContextManager(object):
+    """Context manager class to support localcontext().
+
+      Sets a copy of the supplied context in __enter__() and restores
+      the previous decimal context in __exit__()
+    """
+    def __init__(self, new_context):
+        self.new_context = new_context.copy()
+    def __enter__(self):
+        self.saved_context = getcontext()
+        setcontext(self.new_context)
+        return self.new_context
+    def __exit__(self, t, v, tb):
+        setcontext(self.saved_context)
+
+class Context(object):
+    """Contains the context for a Decimal instance.
+
+    Contains:
+    prec - precision (for use in rounding, division, square roots..)
+    rounding - rounding type. (how you round)
+    _rounding_decision - ALWAYS_ROUND, NEVER_ROUND -- do you round?
+    traps - If traps[exception] = 1, then the exception is
+                    raised when it is caused.  Otherwise, a value is
+                    substituted in.
+    flags  - When an exception is caused, flags[exception] is incremented.
+             (Whether or not the trap_enabler is set)
+             Should be reset by user of Decimal instance.
+    Emin -   Minimum exponent
+    Emax -   Maximum exponent
+    capitals -      If 1, 1*10^1 is printed as 1E+1.
+                    If 0, printed as 1e1
+    _clamp - If 1, change exponents if too high (Default 0)
+    """
+
+    def __init__(self, prec=None, rounding=None,
+                 traps=None, flags=None,
+                 _rounding_decision=None,
+                 Emin=None, Emax=None,
+                 capitals=None, _clamp=0,
+                 _ignored_flags=None):
+        if flags is None:
+            flags = []
+        if _ignored_flags is None:
+            _ignored_flags = []
+        if not isinstance(flags, dict):
+            flags = dict([(s,s in flags) for s in _signals])
+            del s
+        if traps is not None and not isinstance(traps, dict):
+            traps = dict([(s,s in traps) for s in _signals])
+            del s
+        for name, val in locals().items():
+            if val is None:
+                setattr(self, name, _copy.copy(getattr(DefaultContext, name)))
+            else:
+                setattr(self, name, val)
+        del self.self
+
+    def __repr__(self):
+        """Show the current context."""
+        s = []
+        s.append('Context(prec=%(prec)d, rounding=%(rounding)s, Emin=%(Emin)d, Emax=%(Emax)d, capitals=%(capitals)d' % vars(self))
+        s.append('flags=[' + ', '.join([f.__name__ for f, v in self.flags.items() if v]) + ']')
+        s.append('traps=[' + ', '.join([t.__name__ for t, v in self.traps.items() if v]) + ']')
+        return ', '.join(s) + ')'
+
+    def clear_flags(self):
+        """Reset all flags to zero"""
+        for flag in self.flags:
+            self.flags[flag] = 0
+
+    def _shallow_copy(self):
+        """Returns a shallow copy from self."""
+        nc = Context(self.prec, self.rounding, self.traps, self.flags,
+                         self._rounding_decision, self.Emin, self.Emax,
+                         self.capitals, self._clamp, self._ignored_flags)
+        return nc
+
+    def copy(self):
+        """Returns a deep copy from self."""
+        nc = Context(self.prec, self.rounding, self.traps.copy(), self.flags.copy(),
+                         self._rounding_decision, self.Emin, self.Emax,
+                         self.capitals, self._clamp, self._ignored_flags)
+        return nc
+    __copy__ = copy
+
+    def _raise_error(self, condition, explanation = None, *args):
+        """Handles an error
+
+        If the flag is in _ignored_flags, returns the default response.
+        Otherwise, it increments the flag, then, if the corresponding
+        trap_enabler is set, it reaises the exception.  Otherwise, it returns
+        the default value after incrementing the flag.
+        """
+        error = _condition_map.get(condition, condition)
+        if error in self._ignored_flags:
+            #Don't touch the flag
+            return error().handle(self, *args)
+
+        self.flags[error] += 1
+        if not self.traps[error]:
+            #The errors define how to handle themselves.
+            return condition().handle(self, *args)
+
+        # Errors should only be risked on copies of the context
+        #self._ignored_flags = []
+        raise error, explanation
+
+    def _ignore_all_flags(self):
+        """Ignore all flags, if they are raised"""
+        return self._ignore_flags(*_signals)
+
+    def _ignore_flags(self, *flags):
+        """Ignore the flags, if they are raised"""
+        # Do not mutate-- This way, copies of a context leave the original
+        # alone.
+        self._ignored_flags = (self._ignored_flags + list(flags))
+        return list(flags)
+
+    def _regard_flags(self, *flags):
+        """Stop ignoring the flags, if they are raised"""
+        if flags and isinstance(flags[0], (tuple,list)):
+            flags = flags[0]
+        for flag in flags:
+            self._ignored_flags.remove(flag)
+
+    def __hash__(self):
+        """A Context cannot be hashed."""
+        # We inherit object.__hash__, so we must deny this explicitly
+        raise TypeError, "Cannot hash a Context."
+
+    def Etiny(self):
+        """Returns Etiny (= Emin - prec + 1)"""
+        return int(self.Emin - self.prec + 1)
+
+    def Etop(self):
+        """Returns maximum exponent (= Emax - prec + 1)"""
+        return int(self.Emax - self.prec + 1)
+
+    def _set_rounding_decision(self, type):
+        """Sets the rounding decision.
+
+        Sets the rounding decision, and returns the current (previous)
+        rounding decision.  Often used like:
+
+        context = context._shallow_copy()
+        # That so you don't change the calling context
+        # if an error occurs in the middle (say DivisionImpossible is raised).
+
+        rounding = context._set_rounding_decision(NEVER_ROUND)
+        instance = instance / Decimal(2)
+        context._set_rounding_decision(rounding)
+
+        This will make it not round for that operation.
+        """
+
+        rounding = self._rounding_decision
+        self._rounding_decision = type
+        return rounding
+
+    def _set_rounding(self, type):
+        """Sets the rounding type.
+
+        Sets the rounding type, and returns the current (previous)
+        rounding type.  Often used like:
+
+        context = context.copy()
+        # so you don't change the calling context
+        # if an error occurs in the middle.
+        rounding = context._set_rounding(ROUND_UP)
+        val = self.__sub__(other, context=context)
+        context._set_rounding(rounding)
+
+        This will make it round up for that operation.
+        """
+        rounding = self.rounding
+        self.rounding= type
+        return rounding
+
+    def create_decimal(self, num='0'):
+        """Creates a new Decimal instance but using self as context."""
+        d = Decimal(num, context=self)
+        return d._fix(self)
+
+    #Methods
+    def abs(self, a):
+        """Returns the absolute value of the operand.
+
+        If the operand is negative, the result is the same as using the minus
+        operation on the operand. Otherwise, the result is the same as using
+        the plus operation on the operand.
+
+        >>> ExtendedContext.abs(Decimal('2.1'))
+        Decimal("2.1")
+        >>> ExtendedContext.abs(Decimal('-100'))
+        Decimal("100")
+        >>> ExtendedContext.abs(Decimal('101.5'))
+        Decimal("101.5")
+        >>> ExtendedContext.abs(Decimal('-101.5'))
+        Decimal("101.5")
+        """
+        return a.__abs__(context=self)
+
+    def add(self, a, b):
+        """Return the sum of the two operands.
+
+        >>> ExtendedContext.add(Decimal('12'), Decimal('7.00'))
+        Decimal("19.00")
+        >>> ExtendedContext.add(Decimal('1E+2'), Decimal('1.01E+4'))
+        Decimal("1.02E+4")
+        """
+        return a.__add__(b, context=self)
+
+    def _apply(self, a):
+        return str(a._fix(self))
+
+    def compare(self, a, b):
+        """Compares values numerically.
+
+        If the signs of the operands differ, a value representing each operand
+        ('-1' if the operand is less than zero, '0' if the operand is zero or
+        negative zero, or '1' if the operand is greater than zero) is used in
+        place of that operand for the comparison instead of the actual
+        operand.
+
+        The comparison is then effected by subtracting the second operand from
+        the first and then returning a value according to the result of the
+        subtraction: '-1' if the result is less than zero, '0' if the result is
+        zero or negative zero, or '1' if the result is greater than zero.
+
+        >>> ExtendedContext.compare(Decimal('2.1'), Decimal('3'))
+        Decimal("-1")
+        >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.1'))
+        Decimal("0")
+        >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.10'))
+        Decimal("0")
+        >>> ExtendedContext.compare(Decimal('3'), Decimal('2.1'))
+        Decimal("1")
+        >>> ExtendedContext.compare(Decimal('2.1'), Decimal('-3'))
+        Decimal("1")
+        >>> ExtendedContext.compare(Decimal('-3'), Decimal('2.1'))
+        Decimal("-1")
+        """
+        return a.compare(b, context=self)
+
+    def divide(self, a, b):
+        """Decimal division in a specified context.
+
+        >>> ExtendedContext.divide(Decimal('1'), Decimal('3'))
+        Decimal("0.333333333")
+        >>> ExtendedContext.divide(Decimal('2'), Decimal('3'))
+        Decimal("0.666666667")
+        >>> ExtendedContext.divide(Decimal('5'), Decimal('2'))
+        Decimal("2.5")
+        >>> ExtendedContext.divide(Decimal('1'), Decimal('10'))
+        Decimal("0.1")
+        >>> ExtendedContext.divide(Decimal('12'), Decimal('12'))
+        Decimal("1")
+        >>> ExtendedContext.divide(Decimal('8.00'), Decimal('2'))
+        Decimal("4.00")
+        >>> ExtendedContext.divide(Decimal('2.400'), Decimal('2.0'))
+        Decimal("1.20")
+        >>> ExtendedContext.divide(Decimal('1000'), Decimal('100'))
+        Decimal("10")
+        >>> ExtendedContext.divide(Decimal('1000'), Decimal('1'))
+        Decimal("1000")
+        >>> ExtendedContext.divide(Decimal('2.40E+6'), Decimal('2'))
+        Decimal("1.20E+6")
+        """
+        return a.__div__(b, context=self)
+
+    def divide_int(self, a, b):
+        """Divides two numbers and returns the integer part of the result.
+
+        >>> ExtendedContext.divide_int(Decimal('2'), Decimal('3'))
+        Decimal("0")
+        >>> ExtendedContext.divide_int(Decimal('10'), Decimal('3'))
+        Decimal("3")
+        >>> ExtendedContext.divide_int(Decimal('1'), Decimal('0.3'))
+        Decimal("3")
+        """
+        return a.__floordiv__(b, context=self)
+
+    def divmod(self, a, b):
+        return a.__divmod__(b, context=self)
+
+    def max(self, a,b):
+        """max compares two values numerically and returns the maximum.
+
+        If either operand is a NaN then the general rules apply.
+        Otherwise, the operands are compared as as though by the compare
+        operation. If they are numerically equal then the left-hand operand
+        is chosen as the result. Otherwise the maximum (closer to positive
+        infinity) of the two operands is chosen as the result.
+
+        >>> ExtendedContext.max(Decimal('3'), Decimal('2'))
+        Decimal("3")
+        >>> ExtendedContext.max(Decimal('-10'), Decimal('3'))
+        Decimal("3")
+        >>> ExtendedContext.max(Decimal('1.0'), Decimal('1'))
+        Decimal("1")
+        >>> ExtendedContext.max(Decimal('7'), Decimal('NaN'))
+        Decimal("7")
+        """
+        return a.max(b, context=self)
+
+    def min(self, a,b):
+        """min compares two values numerically and returns the minimum.
+
+        If either operand is a NaN then the general rules apply.
+        Otherwise, the operands are compared as as though by the compare
+        operation. If they are numerically equal then the left-hand operand
+        is chosen as the result. Otherwise the minimum (closer to negative
+        infinity) of the two operands is chosen as the result.
+
+        >>> ExtendedContext.min(Decimal('3'), Decimal('2'))
+        Decimal("2")
+        >>> ExtendedContext.min(Decimal('-10'), Decimal('3'))
+        Decimal("-10")
+        >>> ExtendedContext.min(Decimal('1.0'), Decimal('1'))
+        Decimal("1.0")
+        >>> ExtendedContext.min(Decimal('7'), Decimal('NaN'))
+        Decimal("7")
+        """
+        return a.min(b, context=self)
+
+    def minus(self, a):
+        """Minus corresponds to unary prefix minus in Python.
+
+        The operation is evaluated using the same rules as subtract; the
+        operation minus(a) is calculated as subtract('0', a) where the '0'
+        has the same exponent as the operand.
+
+        >>> ExtendedContext.minus(Decimal('1.3'))
+        Decimal("-1.3")
+        >>> ExtendedContext.minus(Decimal('-1.3'))
+        Decimal("1.3")
+        """
+        return a.__neg__(context=self)
+
+    def multiply(self, a, b):
+        """multiply multiplies two operands.
+
+        If either operand is a special value then the general rules apply.
+        Otherwise, the operands are multiplied together ('long multiplication'),
+        resulting in a number which may be as long as the sum of the lengths
+        of the two operands.
+
+        >>> ExtendedContext.multiply(Decimal('1.20'), Decimal('3'))
+        Decimal("3.60")
+        >>> ExtendedContext.multiply(Decimal('7'), Decimal('3'))
+        Decimal("21")
+        >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('0.8'))
+        Decimal("0.72")
+        >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('-0'))
+        Decimal("-0.0")
+        >>> ExtendedContext.multiply(Decimal('654321'), Decimal('654321'))
+        Decimal("4.28135971E+11")
+        """
+        return a.__mul__(b, context=self)
+
+    def normalize(self, a):
+        """normalize reduces an operand to its simplest form.
+
+        Essentially a plus operation with all trailing zeros removed from the
+        result.
+
+        >>> ExtendedContext.normalize(Decimal('2.1'))
+        Decimal("2.1")
+        >>> ExtendedContext.normalize(Decimal('-2.0'))
+        Decimal("-2")
+        >>> ExtendedContext.normalize(Decimal('1.200'))
+        Decimal("1.2")
+        >>> ExtendedContext.normalize(Decimal('-120'))
+        Decimal("-1.2E+2")
+        >>> ExtendedContext.normalize(Decimal('120.00'))
+        Decimal("1.2E+2")
+        >>> ExtendedContext.normalize(Decimal('0.00'))
+        Decimal("0")
+        """
+        return a.normalize(context=self)
+
+    def plus(self, a):
+        """Plus corresponds to unary prefix plus in Python.
+
+        The operation is evaluated using the same rules as add; the
+        operation plus(a) is calculated as add('0', a) where the '0'
+        has the same exponent as the operand.
+
+        >>> ExtendedContext.plus(Decimal('1.3'))
+        Decimal("1.3")
+        >>> ExtendedContext.plus(Decimal('-1.3'))
+        Decimal("-1.3")
+        """
+        return a.__pos__(context=self)
+
+    def power(self, a, b, modulo=None):
+        """Raises a to the power of b, to modulo if given.
+
+        The right-hand operand must be a whole number whose integer part (after
+        any exponent has been applied) has no more than 9 digits and whose
+        fractional part (if any) is all zeros before any rounding. The operand
+        may be positive, negative, or zero; if negative, the absolute value of
+        the power is used, and the left-hand operand is inverted (divided into
+        1) before use.
+
+        If the increased precision needed for the intermediate calculations
+        exceeds the capabilities of the implementation then an Invalid operation
+        condition is raised.
+
+        If, when raising to a negative power, an underflow occurs during the
+        division into 1, the operation is not halted at that point but
+        continues.
+
+        >>> ExtendedContext.power(Decimal('2'), Decimal('3'))
+        Decimal("8")
+        >>> ExtendedContext.power(Decimal('2'), Decimal('-3'))
+        Decimal("0.125")
+        >>> ExtendedContext.power(Decimal('1.7'), Decimal('8'))
+        Decimal("69.7575744")
+        >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-2'))
+        Decimal("0")
+        >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-1'))
+        Decimal("0")
+        >>> ExtendedContext.power(Decimal('Infinity'), Decimal('0'))
+        Decimal("1")
+        >>> ExtendedContext.power(Decimal('Infinity'), Decimal('1'))
+        Decimal("Infinity")
+        >>> ExtendedContext.power(Decimal('Infinity'), Decimal('2'))
+        Decimal("Infinity")
+        >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-2'))
+        Decimal("0")
+        >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-1'))
+        Decimal("-0")
+        >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('0'))
+        Decimal("1")
+        >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('1'))
+        Decimal("-Infinity")
+        >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('2'))
+        Decimal("Infinity")
+        >>> ExtendedContext.power(Decimal('0'), Decimal('0'))
+        Decimal("NaN")
+        """
+        return a.__pow__(b, modulo, context=self)
+
+    def quantize(self, a, b):
+        """Returns a value equal to 'a' (rounded) and having the exponent of 'b'.
+
+        The coefficient of the result is derived from that of the left-hand
+        operand. It may be rounded using the current rounding setting (if the
+        exponent is being increased), multiplied by a positive power of ten (if
+        the exponent is being decreased), or is unchanged (if the exponent is
+        already equal to that of the right-hand operand).
+
+        Unlike other operations, if the length of the coefficient after the
+        quantize operation would be greater than precision then an Invalid
+        operation condition is raised. This guarantees that, unless there is an
+        error condition, the exponent of the result of a quantize is always
+        equal to that of the right-hand operand.
+
+        Also unlike other operations, quantize will never raise Underflow, even
+        if the result is subnormal and inexact.
+
+        >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.001'))
+        Decimal("2.170")
+        >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.01'))
+        Decimal("2.17")
+        >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.1'))
+        Decimal("2.2")
+        >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+0'))
+        Decimal("2")
+        >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+1'))
+        Decimal("0E+1")
+        >>> ExtendedContext.quantize(Decimal('-Inf'), Decimal('Infinity'))
+        Decimal("-Infinity")
+        >>> ExtendedContext.quantize(Decimal('2'), Decimal('Infinity'))
+        Decimal("NaN")
+        >>> ExtendedContext.quantize(Decimal('-0.1'), Decimal('1'))
+        Decimal("-0")
+        >>> ExtendedContext.quantize(Decimal('-0'), Decimal('1e+5'))
+        Decimal("-0E+5")
+        >>> ExtendedContext.quantize(Decimal('+35236450.6'), Decimal('1e-2'))
+        Decimal("NaN")
+        >>> ExtendedContext.quantize(Decimal('-35236450.6'), Decimal('1e-2'))
+        Decimal("NaN")
+        >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-1'))
+        Decimal("217.0")
+        >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-0'))
+        Decimal("217")
+        >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+1'))
+        Decimal("2.2E+2")
+        >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+2'))
+        Decimal("2E+2")
+        """
+        return a.quantize(b, context=self)
+
+    def remainder(self, a, b):
+        """Returns the remainder from integer division.
+
+        The result is the residue of the dividend after the operation of
+        calculating integer division as described for divide-integer, rounded to
+        precision digits if necessary. The sign of the result, if non-zero, is
+        the same as that of the original dividend.
+
+        This operation will fail under the same conditions as integer division
+        (that is, if integer division on the same two operands would fail, the
+        remainder cannot be calculated).
+
+        >>> ExtendedContext.remainder(Decimal('2.1'), Decimal('3'))
+        Decimal("2.1")
+        >>> ExtendedContext.remainder(Decimal('10'), Decimal('3'))
+        Decimal("1")
+        >>> ExtendedContext.remainder(Decimal('-10'), Decimal('3'))
+        Decimal("-1")
+        >>> ExtendedContext.remainder(Decimal('10.2'), Decimal('1'))
+        Decimal("0.2")
+        >>> ExtendedContext.remainder(Decimal('10'), Decimal('0.3'))
+        Decimal("0.1")
+        >>> ExtendedContext.remainder(Decimal('3.6'), Decimal('1.3'))
+        Decimal("1.0")
+        """
+        return a.__mod__(b, context=self)
+
+    def remainder_near(self, a, b):
+        """Returns to be "a - b * n", where n is the integer nearest the exact
+        value of "x / b" (if two integers are equally near then the even one
+        is chosen). If the result is equal to 0 then its sign will be the
+        sign of a.
+
+        This operation will fail under the same conditions as integer division
+        (that is, if integer division on the same two operands would fail, the
+        remainder cannot be calculated).
+
+        >>> ExtendedContext.remainder_near(Decimal('2.1'), Decimal('3'))
+        Decimal("-0.9")
+        >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('6'))
+        Decimal("-2")
+        >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('3'))
+        Decimal("1")
+        >>> ExtendedContext.remainder_near(Decimal('-10'), Decimal('3'))
+        Decimal("-1")
+        >>> ExtendedContext.remainder_near(Decimal('10.2'), Decimal('1'))
+        Decimal("0.2")
+        >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('0.3'))
+        Decimal("0.1")
+        >>> ExtendedContext.remainder_near(Decimal('3.6'), Decimal('1.3'))
+        Decimal("-0.3")
+        """
+        return a.remainder_near(b, context=self)
+
+    def same_quantum(self, a, b):
+        """Returns True if the two operands have the same exponent.
+
+        The result is never affected by either the sign or the coefficient of
+        either operand.
+
+        >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.001'))
+        False
+        >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.01'))
+        True
+        >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('1'))
+        False
+        >>> ExtendedContext.same_quantum(Decimal('Inf'), Decimal('-Inf'))
+        True
+        """
+        return a.same_quantum(b)
+
+    def sqrt(self, a):
+        """Returns the square root of a non-negative number to context precision.
+
+        If the result must be inexact, it is rounded using the round-half-even
+        algorithm.
+
+        >>> ExtendedContext.sqrt(Decimal('0'))
+        Decimal("0")
+        >>> ExtendedContext.sqrt(Decimal('-0'))
+        Decimal("-0")
+        >>> ExtendedContext.sqrt(Decimal('0.39'))
+        Decimal("0.624499800")
+        >>> ExtendedContext.sqrt(Decimal('100'))
+        Decimal("10")
+        >>> ExtendedContext.sqrt(Decimal('1'))
+        Decimal("1")
+        >>> ExtendedContext.sqrt(Decimal('1.0'))
+        Decimal("1.0")
+        >>> ExtendedContext.sqrt(Decimal('1.00'))
+        Decimal("1.0")
+        >>> ExtendedContext.sqrt(Decimal('7'))
+        Decimal("2.64575131")
+        >>> ExtendedContext.sqrt(Decimal('10'))
+        Decimal("3.16227766")
+        >>> ExtendedContext.prec
+        9
+        """
+        return a.sqrt(context=self)
+
+    def subtract(self, a, b):
+        """Return the difference between the two operands.
+
+        >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.07'))
+        Decimal("0.23")
+        >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.30'))
+        Decimal("0.00")
+        >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('2.07'))
+        Decimal("-0.77")
+        """
+        return a.__sub__(b, context=self)
+
+    def to_eng_string(self, a):
+        """Converts a number to a string, using scientific notation.
+
+        The operation is not affected by the context.
+        """
+        return a.to_eng_string(context=self)
+
+    def to_sci_string(self, a):
+        """Converts a number to a string, using scientific notation.
+
+        The operation is not affected by the context.
+        """
+        return a.__str__(context=self)
+
+    def to_integral(self, a):
+        """Rounds to an integer.
+
+        When the operand has a negative exponent, the result is the same
+        as using the quantize() operation using the given operand as the
+        left-hand-operand, 1E+0 as the right-hand-operand, and the precision
+        of the operand as the precision setting, except that no flags will
+        be set. The rounding mode is taken from the context.
+
+        >>> ExtendedContext.to_integral(Decimal('2.1'))
+        Decimal("2")
+        >>> ExtendedContext.to_integral(Decimal('100'))
+        Decimal("100")
+        >>> ExtendedContext.to_integral(Decimal('100.0'))
+        Decimal("100")
+        >>> ExtendedContext.to_integral(Decimal('101.5'))
+        Decimal("102")
+        >>> ExtendedContext.to_integral(Decimal('-101.5'))
+        Decimal("-102")
+        >>> ExtendedContext.to_integral(Decimal('10E+5'))
+        Decimal("1.0E+6")
+        >>> ExtendedContext.to_integral(Decimal('7.89E+77'))
+        Decimal("7.89E+77")
+        >>> ExtendedContext.to_integral(Decimal('-Inf'))
+        Decimal("-Infinity")
+        """
+        return a.to_integral(context=self)
+
+class _WorkRep(object):
+    __slots__ = ('sign','int','exp')
+    # sign: 0 or 1
+    # int:  int or long
+    # exp:  None, int, or string
+
+    def __init__(self, value=None):
+        if value is None:
+            self.sign = None
+            self.int = 0
+            self.exp = None
+        elif isinstance(value, Decimal):
+            self.sign = value._sign
+            cum = 0
+            for digit  in value._int:
+                cum = cum * 10 + digit
+            self.int = cum
+            self.exp = value._exp
+        else:
+            # assert isinstance(value, tuple)
+            self.sign = value[0]
+            self.int = value[1]
+            self.exp = value[2]
+
+    def __repr__(self):
+        return "(%r, %r, %r)" % (self.sign, self.int, self.exp)
+
+    __str__ = __repr__
+
+
+
+def _normalize(op1, op2, shouldround = 0, prec = 0):
+    """Normalizes op1, op2 to have the same exp and length of coefficient.
+
+    Done during addition.
+    """
+    # Yes, the exponent is a long, but the difference between exponents
+    # must be an int-- otherwise you'd get a big memory problem.
+    numdigits = int(op1.exp - op2.exp)
+    if numdigits < 0:
+        numdigits = -numdigits
+        tmp = op2
+        other = op1
+    else:
+        tmp = op1
+        other = op2
+
+
+    if shouldround and numdigits > prec + 1:
+        # Big difference in exponents - check the adjusted exponents
+        tmp_len = len(str(tmp.int))
+        other_len = len(str(other.int))
+        if numdigits > (other_len + prec + 1 - tmp_len):
+            # If the difference in adjusted exps is > prec+1, we know
+            # other is insignificant, so might as well put a 1 after the precision.
+            # (since this is only for addition.)  Also stops use of massive longs.
+
+            extend = prec + 2 - tmp_len
+            if extend <= 0:
+                extend = 1
+            tmp.int *= 10 ** extend
+            tmp.exp -= extend
+            other.int = 1
+            other.exp = tmp.exp
+            return op1, op2
+
+    tmp.int *= 10 ** numdigits
+    tmp.exp -= numdigits
+    return op1, op2
+
+def _adjust_coefficients(op1, op2):
+    """Adjust op1, op2 so that op2.int * 10 > op1.int >= op2.int.
+
+    Returns the adjusted op1, op2 as well as the change in op1.exp-op2.exp.
+
+    Used on _WorkRep instances during division.
+    """
+    adjust = 0
+    #If op1 is smaller, make it larger
+    while op2.int > op1.int:
+        op1.int *= 10
+        op1.exp -= 1
+        adjust += 1
+
+    #If op2 is too small, make it larger
+    while op1.int >= (10 * op2.int):
+        op2.int *= 10
+        op2.exp -= 1
+        adjust -= 1
+
+    return op1, op2, adjust
+
+##### Helper Functions ########################################
+
+def _convert_other(other):
+    """Convert other to Decimal.
+
+    Verifies that it's ok to use in an implicit construction.
+    """
+    if isinstance(other, Decimal):
+        return other
+    if isinstance(other, (int, long)):
+        return Decimal(other)
+    return NotImplemented
+
+_infinity_map = {
+    'inf' : 1,
+    'infinity' : 1,
+    '+inf' : 1,
+    '+infinity' : 1,
+    '-inf' : -1,
+    '-infinity' : -1
+}
+
+def _isinfinity(num):
+    """Determines whether a string or float is infinity.
+
+    +1 for negative infinity; 0 for finite ; +1 for positive infinity
+    """
+    num = str(num).lower()
+    return _infinity_map.get(num, 0)
+
+def _isnan(num):
+    """Determines whether a string or float is NaN
+
+    (1, sign, diagnostic info as string) => NaN
+    (2, sign, diagnostic info as string) => sNaN
+    0 => not a NaN
+    """
+    num = str(num).lower()
+    if not num:
+        return 0
+
+    #get the sign, get rid of trailing [+-]
+    sign = 0
+    if num[0] == '+':
+        num = num[1:]
+    elif num[0] == '-':  #elif avoids '+-nan'
+        num = num[1:]
+        sign = 1
+
+    if num.startswith('nan'):
+        if len(num) > 3 and not num[3:].isdigit(): #diagnostic info
+            return 0
+        return (1, sign, num[3:].lstrip('0'))
+    if num.startswith('snan'):
+        if len(num) > 4 and not num[4:].isdigit():
+            return 0
+        return (2, sign, num[4:].lstrip('0'))
+    return 0
+
+
+##### Setup Specific Contexts ################################
+
+# The default context prototype used by Context()
+# Is mutable, so that new contexts can have different default values
+
+DefaultContext = Context(
+        prec=28, rounding=ROUND_HALF_EVEN,
+        traps=[DivisionByZero, Overflow, InvalidOperation],
+        flags=[],
+        _rounding_decision=ALWAYS_ROUND,
+        Emax=999999999,
+        Emin=-999999999,
+        capitals=1
+)
+
+# Pre-made alternate contexts offered by the specification
+# Don't change these; the user should be able to select these
+# contexts and be able to reproduce results from other implementations
+# of the spec.
+
+BasicContext = Context(
+        prec=9, rounding=ROUND_HALF_UP,
+        traps=[DivisionByZero, Overflow, InvalidOperation, Clamped, Underflow],
+        flags=[],
+)
+
+ExtendedContext = Context(
+        prec=9, rounding=ROUND_HALF_EVEN,
+        traps=[],
+        flags=[],
+)
+
+
+##### Useful Constants (internal use only) ####################
+
+#Reusable defaults
+Inf = Decimal('Inf')
+negInf = Decimal('-Inf')
+
+#Infsign[sign] is infinity w/ that sign
+Infsign = (Inf, negInf)
+
+NaN = Decimal('NaN')
+
+
+##### crud for parsing strings #################################
+import re
+
+# There's an optional sign at the start, and an optional exponent
+# at the end.  The exponent has an optional sign and at least one
+# digit.  In between, must have either at least one digit followed
+# by an optional fraction, or a decimal point followed by at least
+# one digit.  Yuck.
+
+_parser = re.compile(r"""
+#    \s*
+    (?P<sign>[-+])?
+    (
+        (?P<int>\d+) (\. (?P<frac>\d*))?
+    |
+        \. (?P<onlyfrac>\d+)
+    )
+    ([eE](?P<exp>[-+]? \d+))?
+#    \s*
+    $
+""", re.VERBOSE).match #Uncomment the \s* to allow leading or trailing spaces.
+
+del re
+
+# return sign, n, p s.t. float string value == -1**sign * n * 10**p exactly
+
+def _string2exact(s):
+    m = _parser(s)
+    if m is None:
+        raise ValueError("invalid literal for Decimal: %r" % s)
+
+    if m.group('sign') == "-":
+        sign = 1
+    else:
+        sign = 0
+
+    exp = m.group('exp')
+    if exp is None:
+        exp = 0
+    else:
+        exp = int(exp)
+
+    intpart = m.group('int')
+    if intpart is None:
+        intpart = ""
+        fracpart = m.group('onlyfrac')
+    else:
+        fracpart = m.group('frac')
+        if fracpart is None:
+            fracpart = ""
+
+    exp -= len(fracpart)
+
+    mantissa = intpart + fracpart
+    tmp = map(int, mantissa)
+    backup = tmp
+    while tmp and tmp[0] == 0:
+        del tmp[0]
+
+    # It's a zero
+    if not tmp:
+        if backup:
+            return (sign, tuple(backup), exp)
+        return (sign, (0,), exp)
+    mantissa = tuple(tmp)
+
+    return (sign, mantissa, exp)
+
+
+if __name__ == '__main__':
+    import doctest, sys
+    doctest.testmod(sys.modules[__name__])

Added: vendor/Python/current/Lib/difflib.py
===================================================================
--- vendor/Python/current/Lib/difflib.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/difflib.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2019 @@
+#! /usr/bin/env python
+
+"""
+Module difflib -- helpers for computing deltas between objects.
+
+Function get_close_matches(word, possibilities, n=3, cutoff=0.6):
+    Use SequenceMatcher to return list of the best "good enough" matches.
+
+Function context_diff(a, b):
+    For two lists of strings, return a delta in context diff format.
+
+Function ndiff(a, b):
+    Return a delta: the difference between `a` and `b` (lists of strings).
+
+Function restore(delta, which):
+    Return one of the two sequences that generated an ndiff delta.
+
+Function unified_diff(a, b):
+    For two lists of strings, return a delta in unified diff format.
+
+Class SequenceMatcher:
+    A flexible class for comparing pairs of sequences of any type.
+
+Class Differ:
+    For producing human-readable deltas from sequences of lines of text.
+
+Class HtmlDiff:
+    For producing HTML side by side comparison with change highlights.
+"""
+
+__all__ = ['get_close_matches', 'ndiff', 'restore', 'SequenceMatcher',
+           'Differ','IS_CHARACTER_JUNK', 'IS_LINE_JUNK', 'context_diff',
+           'unified_diff', 'HtmlDiff']
+
+import heapq
+
+def _calculate_ratio(matches, length):
+    if length:
+        return 2.0 * matches / length
+    return 1.0
+
+class SequenceMatcher:
+
+    """
+    SequenceMatcher is a flexible class for comparing pairs of sequences of
+    any type, so long as the sequence elements are hashable.  The basic
+    algorithm predates, and is a little fancier than, an algorithm
+    published in the late 1980's by Ratcliff and Obershelp under the
+    hyperbolic name "gestalt pattern matching".  The basic idea is to find
+    the longest contiguous matching subsequence that contains no "junk"
+    elements (R-O doesn't address junk).  The same idea is then applied
+    recursively to the pieces of the sequences to the left and to the right
+    of the matching subsequence.  This does not yield minimal edit
+    sequences, but does tend to yield matches that "look right" to people.
+
+    SequenceMatcher tries to compute a "human-friendly diff" between two
+    sequences.  Unlike e.g. UNIX(tm) diff, the fundamental notion is the
+    longest *contiguous* & junk-free matching subsequence.  That's what
+    catches peoples' eyes.  The Windows(tm) windiff has another interesting
+    notion, pairing up elements that appear uniquely in each sequence.
+    That, and the method here, appear to yield more intuitive difference
+    reports than does diff.  This method appears to be the least vulnerable
+    to synching up on blocks of "junk lines", though (like blank lines in
+    ordinary text files, or maybe "<P>" lines in HTML files).  That may be
+    because this is the only method of the 3 that has a *concept* of
+    "junk" <wink>.
+
+    Example, comparing two strings, and considering blanks to be "junk":
+
+    >>> s = SequenceMatcher(lambda x: x == " ",
+    ...                     "private Thread currentThread;",
+    ...                     "private volatile Thread currentThread;")
+    >>>
+
+    .ratio() returns a float in [0, 1], measuring the "similarity" of the
+    sequences.  As a rule of thumb, a .ratio() value over 0.6 means the
+    sequences are close matches:
+
+    >>> print round(s.ratio(), 3)
+    0.866
+    >>>
+
+    If you're only interested in where the sequences match,
+    .get_matching_blocks() is handy:
+
+    >>> for block in s.get_matching_blocks():
+    ...     print "a[%d] and b[%d] match for %d elements" % block
+    a[0] and b[0] match for 8 elements
+    a[8] and b[17] match for 21 elements
+    a[29] and b[38] match for 0 elements
+
+    Note that the last tuple returned by .get_matching_blocks() is always a
+    dummy, (len(a), len(b), 0), and this is the only case in which the last
+    tuple element (number of elements matched) is 0.
+
+    If you want to know how to change the first sequence into the second,
+    use .get_opcodes():
+
+    >>> for opcode in s.get_opcodes():
+    ...     print "%6s a[%d:%d] b[%d:%d]" % opcode
+     equal a[0:8] b[0:8]
+    insert a[8:8] b[8:17]
+     equal a[8:29] b[17:38]
+
+    See the Differ class for a fancy human-friendly file differencer, which
+    uses SequenceMatcher both to compare sequences of lines, and to compare
+    sequences of characters within similar (near-matching) lines.
+
+    See also function get_close_matches() in this module, which shows how
+    simple code building on SequenceMatcher can be used to do useful work.
+
+    Timing:  Basic R-O is cubic time worst case and quadratic time expected
+    case.  SequenceMatcher is quadratic time for the worst case and has
+    expected-case behavior dependent in a complicated way on how many
+    elements the sequences have in common; best case time is linear.
+
+    Methods:
+
+    __init__(isjunk=None, a='', b='')
+        Construct a SequenceMatcher.
+
+    set_seqs(a, b)
+        Set the two sequences to be compared.
+
+    set_seq1(a)
+        Set the first sequence to be compared.
+
+    set_seq2(b)
+        Set the second sequence to be compared.
+
+    find_longest_match(alo, ahi, blo, bhi)
+        Find longest matching block in a[alo:ahi] and b[blo:bhi].
+
+    get_matching_blocks()
+        Return list of triples describing matching subsequences.
+
+    get_opcodes()
+        Return list of 5-tuples describing how to turn a into b.
+
+    ratio()
+        Return a measure of the sequences' similarity (float in [0,1]).
+
+    quick_ratio()
+        Return an upper bound on .ratio() relatively quickly.
+
+    real_quick_ratio()
+        Return an upper bound on ratio() very quickly.
+    """
+
+    def __init__(self, isjunk=None, a='', b=''):
+        """Construct a SequenceMatcher.
+
+        Optional arg isjunk is None (the default), or a one-argument
+        function that takes a sequence element and returns true iff the
+        element is junk.  None is equivalent to passing "lambda x: 0", i.e.
+        no elements are considered to be junk.  For example, pass
+            lambda x: x in " \\t"
+        if you're comparing lines as sequences of characters, and don't
+        want to synch up on blanks or hard tabs.
+
+        Optional arg a is the first of two sequences to be compared.  By
+        default, an empty string.  The elements of a must be hashable.  See
+        also .set_seqs() and .set_seq1().
+
+        Optional arg b is the second of two sequences to be compared.  By
+        default, an empty string.  The elements of b must be hashable. See
+        also .set_seqs() and .set_seq2().
+        """
+
+        # Members:
+        # a
+        #      first sequence
+        # b
+        #      second sequence; differences are computed as "what do
+        #      we need to do to 'a' to change it into 'b'?"
+        # b2j
+        #      for x in b, b2j[x] is a list of the indices (into b)
+        #      at which x appears; junk elements do not appear
+        # fullbcount
+        #      for x in b, fullbcount[x] == the number of times x
+        #      appears in b; only materialized if really needed (used
+        #      only for computing quick_ratio())
+        # matching_blocks
+        #      a list of (i, j, k) triples, where a[i:i+k] == b[j:j+k];
+        #      ascending & non-overlapping in i and in j; terminated by
+        #      a dummy (len(a), len(b), 0) sentinel
+        # opcodes
+        #      a list of (tag, i1, i2, j1, j2) tuples, where tag is
+        #      one of
+        #          'replace'   a[i1:i2] should be replaced by b[j1:j2]
+        #          'delete'    a[i1:i2] should be deleted
+        #          'insert'    b[j1:j2] should be inserted
+        #          'equal'     a[i1:i2] == b[j1:j2]
+        # isjunk
+        #      a user-supplied function taking a sequence element and
+        #      returning true iff the element is "junk" -- this has
+        #      subtle but helpful effects on the algorithm, which I'll
+        #      get around to writing up someday <0.9 wink>.
+        #      DON'T USE!  Only __chain_b uses this.  Use isbjunk.
+        # isbjunk
+        #      for x in b, isbjunk(x) == isjunk(x) but much faster;
+        #      it's really the has_key method of a hidden dict.
+        #      DOES NOT WORK for x in a!
+        # isbpopular
+        #      for x in b, isbpopular(x) is true iff b is reasonably long
+        #      (at least 200 elements) and x accounts for more than 1% of
+        #      its elements.  DOES NOT WORK for x in a!
+
+        self.isjunk = isjunk
+        self.a = self.b = None
+        self.set_seqs(a, b)
+
+    def set_seqs(self, a, b):
+        """Set the two sequences to be compared.
+
+        >>> s = SequenceMatcher()
+        >>> s.set_seqs("abcd", "bcde")
+        >>> s.ratio()
+        0.75
+        """
+
+        self.set_seq1(a)
+        self.set_seq2(b)
+
+    def set_seq1(self, a):
+        """Set the first sequence to be compared.
+
+        The second sequence to be compared is not changed.
+
+        >>> s = SequenceMatcher(None, "abcd", "bcde")
+        >>> s.ratio()
+        0.75
+        >>> s.set_seq1("bcde")
+        >>> s.ratio()
+        1.0
+        >>>
+
+        SequenceMatcher computes and caches detailed information about the
+        second sequence, so if you want to compare one sequence S against
+        many sequences, use .set_seq2(S) once and call .set_seq1(x)
+        repeatedly for each of the other sequences.
+
+        See also set_seqs() and set_seq2().
+        """
+
+        if a is self.a:
+            return
+        self.a = a
+        self.matching_blocks = self.opcodes = None
+
+    def set_seq2(self, b):
+        """Set the second sequence to be compared.
+
+        The first sequence to be compared is not changed.
+
+        >>> s = SequenceMatcher(None, "abcd", "bcde")
+        >>> s.ratio()
+        0.75
+        >>> s.set_seq2("abcd")
+        >>> s.ratio()
+        1.0
+        >>>
+
+        SequenceMatcher computes and caches detailed information about the
+        second sequence, so if you want to compare one sequence S against
+        many sequences, use .set_seq2(S) once and call .set_seq1(x)
+        repeatedly for each of the other sequences.
+
+        See also set_seqs() and set_seq1().
+        """
+
+        if b is self.b:
+            return
+        self.b = b
+        self.matching_blocks = self.opcodes = None
+        self.fullbcount = None
+        self.__chain_b()
+
+    # For each element x in b, set b2j[x] to a list of the indices in
+    # b where x appears; the indices are in increasing order; note that
+    # the number of times x appears in b is len(b2j[x]) ...
+    # when self.isjunk is defined, junk elements don't show up in this
+    # map at all, which stops the central find_longest_match method
+    # from starting any matching block at a junk element ...
+    # also creates the fast isbjunk function ...
+    # b2j also does not contain entries for "popular" elements, meaning
+    # elements that account for more than 1% of the total elements, and
+    # when the sequence is reasonably large (>= 200 elements); this can
+    # be viewed as an adaptive notion of semi-junk, and yields an enormous
+    # speedup when, e.g., comparing program files with hundreds of
+    # instances of "return NULL;" ...
+    # note that this is only called when b changes; so for cross-product
+    # kinds of matches, it's best to call set_seq2 once, then set_seq1
+    # repeatedly
+
+    def __chain_b(self):
+        # Because isjunk is a user-defined (not C) function, and we test
+        # for junk a LOT, it's important to minimize the number of calls.
+        # Before the tricks described here, __chain_b was by far the most
+        # time-consuming routine in the whole module!  If anyone sees
+        # Jim Roskind, thank him again for profile.py -- I never would
+        # have guessed that.
+        # The first trick is to build b2j ignoring the possibility
+        # of junk.  I.e., we don't call isjunk at all yet.  Throwing
+        # out the junk later is much cheaper than building b2j "right"
+        # from the start.
+        b = self.b
+        n = len(b)
+        self.b2j = b2j = {}
+        populardict = {}
+        for i, elt in enumerate(b):
+            if elt in b2j:
+                indices = b2j[elt]
+                if n >= 200 and len(indices) * 100 > n:
+                    populardict[elt] = 1
+                    del indices[:]
+                else:
+                    indices.append(i)
+            else:
+                b2j[elt] = [i]
+
+        # Purge leftover indices for popular elements.
+        for elt in populardict:
+            del b2j[elt]
+
+        # Now b2j.keys() contains elements uniquely, and especially when
+        # the sequence is a string, that's usually a good deal smaller
+        # than len(string).  The difference is the number of isjunk calls
+        # saved.
+        isjunk = self.isjunk
+        junkdict = {}
+        if isjunk:
+            for d in populardict, b2j:
+                for elt in d.keys():
+                    if isjunk(elt):
+                        junkdict[elt] = 1
+                        del d[elt]
+
+        # Now for x in b, isjunk(x) == x in junkdict, but the
+        # latter is much faster.  Note too that while there may be a
+        # lot of junk in the sequence, the number of *unique* junk
+        # elements is probably small.  So the memory burden of keeping
+        # this dict alive is likely trivial compared to the size of b2j.
+        self.isbjunk = junkdict.has_key
+        self.isbpopular = populardict.has_key
+
+    def find_longest_match(self, alo, ahi, blo, bhi):
+        """Find longest matching block in a[alo:ahi] and b[blo:bhi].
+
+        If isjunk is not defined:
+
+        Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
+            alo <= i <= i+k <= ahi
+            blo <= j <= j+k <= bhi
+        and for all (i',j',k') meeting those conditions,
+            k >= k'
+            i <= i'
+            and if i == i', j <= j'
+
+        In other words, of all maximal matching blocks, return one that
+        starts earliest in a, and of all those maximal matching blocks that
+        start earliest in a, return the one that starts earliest in b.
+
+        >>> s = SequenceMatcher(None, " abcd", "abcd abcd")
+        >>> s.find_longest_match(0, 5, 0, 9)
+        (0, 4, 5)
+
+        If isjunk is defined, first the longest matching block is
+        determined as above, but with the additional restriction that no
+        junk element appears in the block.  Then that block is extended as
+        far as possible by matching (only) junk elements on both sides.  So
+        the resulting block never matches on junk except as identical junk
+        happens to be adjacent to an "interesting" match.
+
+        Here's the same example as before, but considering blanks to be
+        junk.  That prevents " abcd" from matching the " abcd" at the tail
+        end of the second sequence directly.  Instead only the "abcd" can
+        match, and matches the leftmost "abcd" in the second sequence:
+
+        >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
+        >>> s.find_longest_match(0, 5, 0, 9)
+        (1, 0, 4)
+
+        If no blocks match, return (alo, blo, 0).
+
+        >>> s = SequenceMatcher(None, "ab", "c")
+        >>> s.find_longest_match(0, 2, 0, 1)
+        (0, 0, 0)
+        """
+
+        # CAUTION:  stripping common prefix or suffix would be incorrect.
+        # E.g.,
+        #    ab
+        #    acab
+        # Longest matching block is "ab", but if common prefix is
+        # stripped, it's "a" (tied with "b").  UNIX(tm) diff does so
+        # strip, so ends up claiming that ab is changed to acab by
+        # inserting "ca" in the middle.  That's minimal but unintuitive:
+        # "it's obvious" that someone inserted "ac" at the front.
+        # Windiff ends up at the same place as diff, but by pairing up
+        # the unique 'b's and then matching the first two 'a's.
+
+        a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.isbjunk
+        besti, bestj, bestsize = alo, blo, 0
+        # find longest junk-free match
+        # during an iteration of the loop, j2len[j] = length of longest
+        # junk-free match ending with a[i-1] and b[j]
+        j2len = {}
+        nothing = []
+        for i in xrange(alo, ahi):
+            # look at all instances of a[i] in b; note that because
+            # b2j has no junk keys, the loop is skipped if a[i] is junk
+            j2lenget = j2len.get
+            newj2len = {}
+            for j in b2j.get(a[i], nothing):
+                # a[i] matches b[j]
+                if j < blo:
+                    continue
+                if j >= bhi:
+                    break
+                k = newj2len[j] = j2lenget(j-1, 0) + 1
+                if k > bestsize:
+                    besti, bestj, bestsize = i-k+1, j-k+1, k
+            j2len = newj2len
+
+        # Extend the best by non-junk elements on each end.  In particular,
+        # "popular" non-junk elements aren't in b2j, which greatly speeds
+        # the inner loop above, but also means "the best" match so far
+        # doesn't contain any junk *or* popular non-junk elements.
+        while besti > alo and bestj > blo and \
+              not isbjunk(b[bestj-1]) and \
+              a[besti-1] == b[bestj-1]:
+            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
+        while besti+bestsize < ahi and bestj+bestsize < bhi and \
+              not isbjunk(b[bestj+bestsize]) and \
+              a[besti+bestsize] == b[bestj+bestsize]:
+            bestsize += 1
+
+        # Now that we have a wholly interesting match (albeit possibly
+        # empty!), we may as well suck up the matching junk on each
+        # side of it too.  Can't think of a good reason not to, and it
+        # saves post-processing the (possibly considerable) expense of
+        # figuring out what to do with it.  In the case of an empty
+        # interesting match, this is clearly the right thing to do,
+        # because no other kind of match is possible in the regions.
+        while besti > alo and bestj > blo and \
+              isbjunk(b[bestj-1]) and \
+              a[besti-1] == b[bestj-1]:
+            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
+        while besti+bestsize < ahi and bestj+bestsize < bhi and \
+              isbjunk(b[bestj+bestsize]) and \
+              a[besti+bestsize] == b[bestj+bestsize]:
+            bestsize = bestsize + 1
+
+        return besti, bestj, bestsize
+
+    def get_matching_blocks(self):
+        """Return list of triples describing matching subsequences.
+
+        Each triple is of the form (i, j, n), and means that
+        a[i:i+n] == b[j:j+n].  The triples are monotonically increasing in
+        i and in j.  New in Python 2.5, it's also guaranteed that if
+        (i, j, n) and (i', j', n') are adjacent triples in the list, and
+        the second is not the last triple in the list, then i+n != i' or
+        j+n != j'.  IOW, adjacent triples never describe adjacent equal
+        blocks.
+
+        The last triple is a dummy, (len(a), len(b), 0), and is the only
+        triple with n==0.
+
+        >>> s = SequenceMatcher(None, "abxcd", "abcd")
+        >>> s.get_matching_blocks()
+        [(0, 0, 2), (3, 2, 2), (5, 4, 0)]
+        """
+
+        if self.matching_blocks is not None:
+            return self.matching_blocks
+        la, lb = len(self.a), len(self.b)
+
+        # This is most naturally expressed as a recursive algorithm, but
+        # at least one user bumped into extreme use cases that exceeded
+        # the recursion limit on their box.  So, now we maintain a list
+        # ('queue`) of blocks we still need to look at, and append partial
+        # results to `matching_blocks` in a loop; the matches are sorted
+        # at the end.
+        queue = [(0, la, 0, lb)]
+        matching_blocks = []
+        while queue:
+            alo, ahi, blo, bhi = queue.pop()
+            i, j, k = x = self.find_longest_match(alo, ahi, blo, bhi)
+            # a[alo:i] vs b[blo:j] unknown
+            # a[i:i+k] same as b[j:j+k]
+            # a[i+k:ahi] vs b[j+k:bhi] unknown
+            if k:   # if k is 0, there was no matching block
+                matching_blocks.append(x)
+                if alo < i and blo < j:
+                    queue.append((alo, i, blo, j))
+                if i+k < ahi and j+k < bhi:
+                    queue.append((i+k, ahi, j+k, bhi))
+        matching_blocks.sort()
+
+        # It's possible that we have adjacent equal blocks in the
+        # matching_blocks list now.  Starting with 2.5, this code was added
+        # to collapse them.
+        i1 = j1 = k1 = 0
+        non_adjacent = []
+        for i2, j2, k2 in matching_blocks:
+            # Is this block adjacent to i1, j1, k1?
+            if i1 + k1 == i2 and j1 + k1 == j2:
+                # Yes, so collapse them -- this just increases the length of
+                # the first block by the length of the second, and the first
+                # block so lengthened remains the block to compare against.
+                k1 += k2
+            else:
+                # Not adjacent.  Remember the first block (k1==0 means it's
+                # the dummy we started with), and make the second block the
+                # new block to compare against.
+                if k1:
+                    non_adjacent.append((i1, j1, k1))
+                i1, j1, k1 = i2, j2, k2
+        if k1:
+            non_adjacent.append((i1, j1, k1))
+
+        non_adjacent.append( (la, lb, 0) )
+        self.matching_blocks = non_adjacent
+        return self.matching_blocks
+
+    def get_opcodes(self):
+        """Return list of 5-tuples describing how to turn a into b.
+
+        Each tuple is of the form (tag, i1, i2, j1, j2).  The first tuple
+        has i1 == j1 == 0, and remaining tuples have i1 == the i2 from the
+        tuple preceding it, and likewise for j1 == the previous j2.
+
+        The tags are strings, with these meanings:
+
+        'replace':  a[i1:i2] should be replaced by b[j1:j2]
+        'delete':   a[i1:i2] should be deleted.
+                    Note that j1==j2 in this case.
+        'insert':   b[j1:j2] should be inserted at a[i1:i1].
+                    Note that i1==i2 in this case.
+        'equal':    a[i1:i2] == b[j1:j2]
+
+        >>> a = "qabxcd"
+        >>> b = "abycdf"
+        >>> s = SequenceMatcher(None, a, b)
+        >>> for tag, i1, i2, j1, j2 in s.get_opcodes():
+        ...    print ("%7s a[%d:%d] (%s) b[%d:%d] (%s)" %
+        ...           (tag, i1, i2, a[i1:i2], j1, j2, b[j1:j2]))
+         delete a[0:1] (q) b[0:0] ()
+          equal a[1:3] (ab) b[0:2] (ab)
+        replace a[3:4] (x) b[2:3] (y)
+          equal a[4:6] (cd) b[3:5] (cd)
+         insert a[6:6] () b[5:6] (f)
+        """
+
+        if self.opcodes is not None:
+            return self.opcodes
+        i = j = 0
+        self.opcodes = answer = []
+        for ai, bj, size in self.get_matching_blocks():
+            # invariant:  we've pumped out correct diffs to change
+            # a[:i] into b[:j], and the next matching block is
+            # a[ai:ai+size] == b[bj:bj+size].  So we need to pump
+            # out a diff to change a[i:ai] into b[j:bj], pump out
+            # the matching block, and move (i,j) beyond the match
+            tag = ''
+            if i < ai and j < bj:
+                tag = 'replace'
+            elif i < ai:
+                tag = 'delete'
+            elif j < bj:
+                tag = 'insert'
+            if tag:
+                answer.append( (tag, i, ai, j, bj) )
+            i, j = ai+size, bj+size
+            # the list of matching blocks is terminated by a
+            # sentinel with size 0
+            if size:
+                answer.append( ('equal', ai, i, bj, j) )
+        return answer
+
+    def get_grouped_opcodes(self, n=3):
+        """ Isolate change clusters by eliminating ranges with no changes.
+
+        Return a generator of groups with upto n lines of context.
+        Each group is in the same format as returned by get_opcodes().
+
+        >>> from pprint import pprint
+        >>> a = map(str, range(1,40))
+        >>> b = a[:]
+        >>> b[8:8] = ['i']     # Make an insertion
+        >>> b[20] += 'x'       # Make a replacement
+        >>> b[23:28] = []      # Make a deletion
+        >>> b[30] += 'y'       # Make another replacement
+        >>> pprint(list(SequenceMatcher(None,a,b).get_grouped_opcodes()))
+        [[('equal', 5, 8, 5, 8), ('insert', 8, 8, 8, 9), ('equal', 8, 11, 9, 12)],
+         [('equal', 16, 19, 17, 20),
+          ('replace', 19, 20, 20, 21),
+          ('equal', 20, 22, 21, 23),
+          ('delete', 22, 27, 23, 23),
+          ('equal', 27, 30, 23, 26)],
+         [('equal', 31, 34, 27, 30),
+          ('replace', 34, 35, 30, 31),
+          ('equal', 35, 38, 31, 34)]]
+        """
+
+        codes = self.get_opcodes()
+        if not codes:
+            codes = [("equal", 0, 1, 0, 1)]
+        # Fixup leading and trailing groups if they show no changes.
+        if codes[0][0] == 'equal':
+            tag, i1, i2, j1, j2 = codes[0]
+            codes[0] = tag, max(i1, i2-n), i2, max(j1, j2-n), j2
+        if codes[-1][0] == 'equal':
+            tag, i1, i2, j1, j2 = codes[-1]
+            codes[-1] = tag, i1, min(i2, i1+n), j1, min(j2, j1+n)
+
+        nn = n + n
+        group = []
+        for tag, i1, i2, j1, j2 in codes:
+            # End the current group and start a new one whenever
+            # there is a large range with no changes.
+            if tag == 'equal' and i2-i1 > nn:
+                group.append((tag, i1, min(i2, i1+n), j1, min(j2, j1+n)))
+                yield group
+                group = []
+                i1, j1 = max(i1, i2-n), max(j1, j2-n)
+            group.append((tag, i1, i2, j1 ,j2))
+        if group and not (len(group)==1 and group[0][0] == 'equal'):
+            yield group
+
+    def ratio(self):
+        """Return a measure of the sequences' similarity (float in [0,1]).
+
+        Where T is the total number of elements in both sequences, and
+        M is the number of matches, this is 2.0*M / T.
+        Note that this is 1 if the sequences are identical, and 0 if
+        they have nothing in common.
+
+        .ratio() is expensive to compute if you haven't already computed
+        .get_matching_blocks() or .get_opcodes(), in which case you may
+        want to try .quick_ratio() or .real_quick_ratio() first to get an
+        upper bound.
+
+        >>> s = SequenceMatcher(None, "abcd", "bcde")
+        >>> s.ratio()
+        0.75
+        >>> s.quick_ratio()
+        0.75
+        >>> s.real_quick_ratio()
+        1.0
+        """
+
+        matches = reduce(lambda sum, triple: sum + triple[-1],
+                         self.get_matching_blocks(), 0)
+        return _calculate_ratio(matches, len(self.a) + len(self.b))
+
+    def quick_ratio(self):
+        """Return an upper bound on ratio() relatively quickly.
+
+        This isn't defined beyond that it is an upper bound on .ratio(), and
+        is faster to compute.
+        """
+
+        # viewing a and b as multisets, set matches to the cardinality
+        # of their intersection; this counts the number of matches
+        # without regard to order, so is clearly an upper bound
+        if self.fullbcount is None:
+            self.fullbcount = fullbcount = {}
+            for elt in self.b:
+                fullbcount[elt] = fullbcount.get(elt, 0) + 1
+        fullbcount = self.fullbcount
+        # avail[x] is the number of times x appears in 'b' less the
+        # number of times we've seen it in 'a' so far ... kinda
+        avail = {}
+        availhas, matches = avail.has_key, 0
+        for elt in self.a:
+            if availhas(elt):
+                numb = avail[elt]
+            else:
+                numb = fullbcount.get(elt, 0)
+            avail[elt] = numb - 1
+            if numb > 0:
+                matches = matches + 1
+        return _calculate_ratio(matches, len(self.a) + len(self.b))
+
+    def real_quick_ratio(self):
+        """Return an upper bound on ratio() very quickly.
+
+        This isn't defined beyond that it is an upper bound on .ratio(), and
+        is faster to compute than either .ratio() or .quick_ratio().
+        """
+
+        la, lb = len(self.a), len(self.b)
+        # can't have more matches than the number of elements in the
+        # shorter sequence
+        return _calculate_ratio(min(la, lb), la + lb)
+
+def get_close_matches(word, possibilities, n=3, cutoff=0.6):
+    """Use SequenceMatcher to return list of the best "good enough" matches.
+
+    word is a sequence for which close matches are desired (typically a
+    string).
+
+    possibilities is a list of sequences against which to match word
+    (typically a list of strings).
+
+    Optional arg n (default 3) is the maximum number of close matches to
+    return.  n must be > 0.
+
+    Optional arg cutoff (default 0.6) is a float in [0, 1].  Possibilities
+    that don't score at least that similar to word are ignored.
+
+    The best (no more than n) matches among the possibilities are returned
+    in a list, sorted by similarity score, most similar first.
+
+    >>> get_close_matches("appel", ["ape", "apple", "peach", "puppy"])
+    ['apple', 'ape']
+    >>> import keyword as _keyword
+    >>> get_close_matches("wheel", _keyword.kwlist)
+    ['while']
+    >>> get_close_matches("apple", _keyword.kwlist)
+    []
+    >>> get_close_matches("accept", _keyword.kwlist)
+    ['except']
+    """
+
+    if not n >  0:
+        raise ValueError("n must be > 0: %r" % (n,))
+    if not 0.0 <= cutoff <= 1.0:
+        raise ValueError("cutoff must be in [0.0, 1.0]: %r" % (cutoff,))
+    result = []
+    s = SequenceMatcher()
+    s.set_seq2(word)
+    for x in possibilities:
+        s.set_seq1(x)
+        if s.real_quick_ratio() >= cutoff and \
+           s.quick_ratio() >= cutoff and \
+           s.ratio() >= cutoff:
+            result.append((s.ratio(), x))
+
+    # Move the best scorers to head of list
+    result = heapq.nlargest(n, result)
+    # Strip scores for the best n matches
+    return [x for score, x in result]
+
+def _count_leading(line, ch):
+    """
+    Return number of `ch` characters at the start of `line`.
+
+    Example:
+
+    >>> _count_leading('   abc', ' ')
+    3
+    """
+
+    i, n = 0, len(line)
+    while i < n and line[i] == ch:
+        i += 1
+    return i
+
+class Differ:
+    r"""
+    Differ is a class for comparing sequences of lines of text, and
+    producing human-readable differences or deltas.  Differ uses
+    SequenceMatcher both to compare sequences of lines, and to compare
+    sequences of characters within similar (near-matching) lines.
+
+    Each line of a Differ delta begins with a two-letter code:
+
+        '- '    line unique to sequence 1
+        '+ '    line unique to sequence 2
+        '  '    line common to both sequences
+        '? '    line not present in either input sequence
+
+    Lines beginning with '? ' attempt to guide the eye to intraline
+    differences, and were not present in either input sequence.  These lines
+    can be confusing if the sequences contain tab characters.
+
+    Note that Differ makes no claim to produce a *minimal* diff.  To the
+    contrary, minimal diffs are often counter-intuitive, because they synch
+    up anywhere possible, sometimes accidental matches 100 pages apart.
+    Restricting synch points to contiguous matches preserves some notion of
+    locality, at the occasional cost of producing a longer diff.
+
+    Example: Comparing two texts.
+
+    First we set up the texts, sequences of individual single-line strings
+    ending with newlines (such sequences can also be obtained from the
+    `readlines()` method of file-like objects):
+
+    >>> text1 = '''  1. Beautiful is better than ugly.
+    ...   2. Explicit is better than implicit.
+    ...   3. Simple is better than complex.
+    ...   4. Complex is better than complicated.
+    ... '''.splitlines(1)
+    >>> len(text1)
+    4
+    >>> text1[0][-1]
+    '\n'
+    >>> text2 = '''  1. Beautiful is better than ugly.
+    ...   3.   Simple is better than complex.
+    ...   4. Complicated is better than complex.
+    ...   5. Flat is better than nested.
+    ... '''.splitlines(1)
+
+    Next we instantiate a Differ object:
+
+    >>> d = Differ()
+
+    Note that when instantiating a Differ object we may pass functions to
+    filter out line and character 'junk'.  See Differ.__init__ for details.
+
+    Finally, we compare the two:
+
+    >>> result = list(d.compare(text1, text2))
+
+    'result' is a list of strings, so let's pretty-print it:
+
+    >>> from pprint import pprint as _pprint
+    >>> _pprint(result)
+    ['    1. Beautiful is better than ugly.\n',
+     '-   2. Explicit is better than implicit.\n',
+     '-   3. Simple is better than complex.\n',
+     '+   3.   Simple is better than complex.\n',
+     '?     ++\n',
+     '-   4. Complex is better than complicated.\n',
+     '?            ^                     ---- ^\n',
+     '+   4. Complicated is better than complex.\n',
+     '?           ++++ ^                      ^\n',
+     '+   5. Flat is better than nested.\n']
+
+    As a single multi-line string it looks like this:
+
+    >>> print ''.join(result),
+        1. Beautiful is better than ugly.
+    -   2. Explicit is better than implicit.
+    -   3. Simple is better than complex.
+    +   3.   Simple is better than complex.
+    ?     ++
+    -   4. Complex is better than complicated.
+    ?            ^                     ---- ^
+    +   4. Complicated is better than complex.
+    ?           ++++ ^                      ^
+    +   5. Flat is better than nested.
+
+    Methods:
+
+    __init__(linejunk=None, charjunk=None)
+        Construct a text differencer, with optional filters.
+
+    compare(a, b)
+        Compare two sequences of lines; generate the resulting delta.
+    """
+
+    def __init__(self, linejunk=None, charjunk=None):
+        """
+        Construct a text differencer, with optional filters.
+
+        The two optional keyword parameters are for filter functions:
+
+        - `linejunk`: A function that should accept a single string argument,
+          and return true iff the string is junk. The module-level function
+          `IS_LINE_JUNK` may be used to filter out lines without visible
+          characters, except for at most one splat ('#').  It is recommended
+          to leave linejunk None; as of Python 2.3, the underlying
+          SequenceMatcher class has grown an adaptive notion of "noise" lines
+          that's better than any static definition the author has ever been
+          able to craft.
+
+        - `charjunk`: A function that should accept a string of length 1. The
+          module-level function `IS_CHARACTER_JUNK` may be used to filter out
+          whitespace characters (a blank or tab; **note**: bad idea to include
+          newline in this!).  Use of IS_CHARACTER_JUNK is recommended.
+        """
+
+        self.linejunk = linejunk
+        self.charjunk = charjunk
+
+    def compare(self, a, b):
+        r"""
+        Compare two sequences of lines; generate the resulting delta.
+
+        Each sequence must contain individual single-line strings ending with
+        newlines. Such sequences can be obtained from the `readlines()` method
+        of file-like objects.  The delta generated also consists of newline-
+        terminated strings, ready to be printed as-is via the writeline()
+        method of a file-like object.
+
+        Example:
+
+        >>> print ''.join(Differ().compare('one\ntwo\nthree\n'.splitlines(1),
+        ...                                'ore\ntree\nemu\n'.splitlines(1))),
+        - one
+        ?  ^
+        + ore
+        ?  ^
+        - two
+        - three
+        ?  -
+        + tree
+        + emu
+        """
+
+        cruncher = SequenceMatcher(self.linejunk, a, b)
+        for tag, alo, ahi, blo, bhi in cruncher.get_opcodes():
+            if tag == 'replace':
+                g = self._fancy_replace(a, alo, ahi, b, blo, bhi)
+            elif tag == 'delete':
+                g = self._dump('-', a, alo, ahi)
+            elif tag == 'insert':
+                g = self._dump('+', b, blo, bhi)
+            elif tag == 'equal':
+                g = self._dump(' ', a, alo, ahi)
+            else:
+                raise ValueError, 'unknown tag %r' % (tag,)
+
+            for line in g:
+                yield line
+
+    def _dump(self, tag, x, lo, hi):
+        """Generate comparison results for a same-tagged range."""
+        for i in xrange(lo, hi):
+            yield '%s %s' % (tag, x[i])
+
+    def _plain_replace(self, a, alo, ahi, b, blo, bhi):
+        assert alo < ahi and blo < bhi
+        # dump the shorter block first -- reduces the burden on short-term
+        # memory if the blocks are of very different sizes
+        if bhi - blo < ahi - alo:
+            first  = self._dump('+', b, blo, bhi)
+            second = self._dump('-', a, alo, ahi)
+        else:
+            first  = self._dump('-', a, alo, ahi)
+            second = self._dump('+', b, blo, bhi)
+
+        for g in first, second:
+            for line in g:
+                yield line
+
+    def _fancy_replace(self, a, alo, ahi, b, blo, bhi):
+        r"""
+        When replacing one block of lines with another, search the blocks
+        for *similar* lines; the best-matching pair (if any) is used as a
+        synch point, and intraline difference marking is done on the
+        similar pair. Lots of work, but often worth it.
+
+        Example:
+
+        >>> d = Differ()
+        >>> results = d._fancy_replace(['abcDefghiJkl\n'], 0, 1,
+        ...                            ['abcdefGhijkl\n'], 0, 1)
+        >>> print ''.join(results),
+        - abcDefghiJkl
+        ?    ^  ^  ^
+        + abcdefGhijkl
+        ?    ^  ^  ^
+        """
+
+        # don't synch up unless the lines have a similarity score of at
+        # least cutoff; best_ratio tracks the best score seen so far
+        best_ratio, cutoff = 0.74, 0.75
+        cruncher = SequenceMatcher(self.charjunk)
+        eqi, eqj = None, None   # 1st indices of equal lines (if any)
+
+        # search for the pair that matches best without being identical
+        # (identical lines must be junk lines, & we don't want to synch up
+        # on junk -- unless we have to)
+        for j in xrange(blo, bhi):
+            bj = b[j]
+            cruncher.set_seq2(bj)
+            for i in xrange(alo, ahi):
+                ai = a[i]
+                if ai == bj:
+                    if eqi is None:
+                        eqi, eqj = i, j
+                    continue
+                cruncher.set_seq1(ai)
+                # computing similarity is expensive, so use the quick
+                # upper bounds first -- have seen this speed up messy
+                # compares by a factor of 3.
+                # note that ratio() is only expensive to compute the first
+                # time it's called on a sequence pair; the expensive part
+                # of the computation is cached by cruncher
+                if cruncher.real_quick_ratio() > best_ratio and \
+                      cruncher.quick_ratio() > best_ratio and \
+                      cruncher.ratio() > best_ratio:
+                    best_ratio, best_i, best_j = cruncher.ratio(), i, j
+        if best_ratio < cutoff:
+            # no non-identical "pretty close" pair
+            if eqi is None:
+                # no identical pair either -- treat it as a straight replace
+                for line in self._plain_replace(a, alo, ahi, b, blo, bhi):
+                    yield line
+                return
+            # no close pair, but an identical pair -- synch up on that
+            best_i, best_j, best_ratio = eqi, eqj, 1.0
+        else:
+            # there's a close pair, so forget the identical pair (if any)
+            eqi = None
+
+        # a[best_i] very similar to b[best_j]; eqi is None iff they're not
+        # identical
+
+        # pump out diffs from before the synch point
+        for line in self._fancy_helper(a, alo, best_i, b, blo, best_j):
+            yield line
+
+        # do intraline marking on the synch pair
+        aelt, belt = a[best_i], b[best_j]
+        if eqi is None:
+            # pump out a '-', '?', '+', '?' quad for the synched lines
+            atags = btags = ""
+            cruncher.set_seqs(aelt, belt)
+            for tag, ai1, ai2, bj1, bj2 in cruncher.get_opcodes():
+                la, lb = ai2 - ai1, bj2 - bj1
+                if tag == 'replace':
+                    atags += '^' * la
+                    btags += '^' * lb
+                elif tag == 'delete':
+                    atags += '-' * la
+                elif tag == 'insert':
+                    btags += '+' * lb
+                elif tag == 'equal':
+                    atags += ' ' * la
+                    btags += ' ' * lb
+                else:
+                    raise ValueError, 'unknown tag %r' % (tag,)
+            for line in self._qformat(aelt, belt, atags, btags):
+                yield line
+        else:
+            # the synch pair is identical
+            yield '  ' + aelt
+
+        # pump out diffs from after the synch point
+        for line in self._fancy_helper(a, best_i+1, ahi, b, best_j+1, bhi):
+            yield line
+
+    def _fancy_helper(self, a, alo, ahi, b, blo, bhi):
+        g = []
+        if alo < ahi:
+            if blo < bhi:
+                g = self._fancy_replace(a, alo, ahi, b, blo, bhi)
+            else:
+                g = self._dump('-', a, alo, ahi)
+        elif blo < bhi:
+            g = self._dump('+', b, blo, bhi)
+
+        for line in g:
+            yield line
+
+    def _qformat(self, aline, bline, atags, btags):
+        r"""
+        Format "?" output and deal with leading tabs.
+
+        Example:
+
+        >>> d = Differ()
+        >>> results = d._qformat('\tabcDefghiJkl\n', '\t\tabcdefGhijkl\n',
+        ...                      '  ^ ^  ^      ', '+  ^ ^  ^      ')
+        >>> for line in results: print repr(line)
+        ...
+        '- \tabcDefghiJkl\n'
+        '? \t ^ ^  ^\n'
+        '+ \t\tabcdefGhijkl\n'
+        '? \t  ^ ^  ^\n'
+        """
+
+        # Can hurt, but will probably help most of the time.
+        common = min(_count_leading(aline, "\t"),
+                     _count_leading(bline, "\t"))
+        common = min(common, _count_leading(atags[:common], " "))
+        atags = atags[common:].rstrip()
+        btags = btags[common:].rstrip()
+
+        yield "- " + aline
+        if atags:
+            yield "? %s%s\n" % ("\t" * common, atags)
+
+        yield "+ " + bline
+        if btags:
+            yield "? %s%s\n" % ("\t" * common, btags)
+
+# With respect to junk, an earlier version of ndiff simply refused to
+# *start* a match with a junk element.  The result was cases like this:
+#     before: private Thread currentThread;
+#     after:  private volatile Thread currentThread;
+# If you consider whitespace to be junk, the longest contiguous match
+# not starting with junk is "e Thread currentThread".  So ndiff reported
+# that "e volatil" was inserted between the 't' and the 'e' in "private".
+# While an accurate view, to people that's absurd.  The current version
+# looks for matching blocks that are entirely junk-free, then extends the
+# longest one of those as far as possible but only with matching junk.
+# So now "currentThread" is matched, then extended to suck up the
+# preceding blank; then "private" is matched, and extended to suck up the
+# following blank; then "Thread" is matched; and finally ndiff reports
+# that "volatile " was inserted before "Thread".  The only quibble
+# remaining is that perhaps it was really the case that " volatile"
+# was inserted after "private".  I can live with that <wink>.
+
+import re
+
+def IS_LINE_JUNK(line, pat=re.compile(r"\s*#?\s*$").match):
+    r"""
+    Return 1 for ignorable line: iff `line` is blank or contains a single '#'.
+
+    Examples:
+
+    >>> IS_LINE_JUNK('\n')
+    True
+    >>> IS_LINE_JUNK('  #   \n')
+    True
+    >>> IS_LINE_JUNK('hello\n')
+    False
+    """
+
+    return pat(line) is not None
+
+def IS_CHARACTER_JUNK(ch, ws=" \t"):
+    r"""
+    Return 1 for ignorable character: iff `ch` is a space or tab.
+
+    Examples:
+
+    >>> IS_CHARACTER_JUNK(' ')
+    True
+    >>> IS_CHARACTER_JUNK('\t')
+    True
+    >>> IS_CHARACTER_JUNK('\n')
+    False
+    >>> IS_CHARACTER_JUNK('x')
+    False
+    """
+
+    return ch in ws
+
+
+def unified_diff(a, b, fromfile='', tofile='', fromfiledate='',
+                 tofiledate='', n=3, lineterm='\n'):
+    r"""
+    Compare two sequences of lines; generate the delta as a unified diff.
+
+    Unified diffs are a compact way of showing line changes and a few
+    lines of context.  The number of context lines is set by 'n' which
+    defaults to three.
+
+    By default, the diff control lines (those with ---, +++, or @@) are
+    created with a trailing newline.  This is helpful so that inputs
+    created from file.readlines() result in diffs that are suitable for
+    file.writelines() since both the inputs and outputs have trailing
+    newlines.
+
+    For inputs that do not have trailing newlines, set the lineterm
+    argument to "" so that the output will be uniformly newline free.
+
+    The unidiff format normally has a header for filenames and modification
+    times.  Any or all of these may be specified using strings for
+    'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'.  The modification
+    times are normally expressed in the format returned by time.ctime().
+
+    Example:
+
+    >>> for line in unified_diff('one two three four'.split(),
+    ...             'zero one tree four'.split(), 'Original', 'Current',
+    ...             'Sat Jan 26 23:30:50 1991', 'Fri Jun 06 10:20:52 2003',
+    ...             lineterm=''):
+    ...     print line
+    --- Original Sat Jan 26 23:30:50 1991
+    +++ Current Fri Jun 06 10:20:52 2003
+    @@ -1,4 +1,4 @@
+    +zero
+     one
+    -two
+    -three
+    +tree
+     four
+    """
+
+    started = False
+    for group in SequenceMatcher(None,a,b).get_grouped_opcodes(n):
+        if not started:
+            yield '--- %s %s%s' % (fromfile, fromfiledate, lineterm)
+            yield '+++ %s %s%s' % (tofile, tofiledate, lineterm)
+            started = True
+        i1, i2, j1, j2 = group[0][1], group[-1][2], group[0][3], group[-1][4]
+        yield "@@ -%d,%d +%d,%d @@%s" % (i1+1, i2-i1, j1+1, j2-j1, lineterm)
+        for tag, i1, i2, j1, j2 in group:
+            if tag == 'equal':
+                for line in a[i1:i2]:
+                    yield ' ' + line
+                continue
+            if tag == 'replace' or tag == 'delete':
+                for line in a[i1:i2]:
+                    yield '-' + line
+            if tag == 'replace' or tag == 'insert':
+                for line in b[j1:j2]:
+                    yield '+' + line
+
+# See http://www.unix.org/single_unix_specification/
+def context_diff(a, b, fromfile='', tofile='',
+                 fromfiledate='', tofiledate='', n=3, lineterm='\n'):
+    r"""
+    Compare two sequences of lines; generate the delta as a context diff.
+
+    Context diffs are a compact way of showing line changes and a few
+    lines of context.  The number of context lines is set by 'n' which
+    defaults to three.
+
+    By default, the diff control lines (those with *** or ---) are
+    created with a trailing newline.  This is helpful so that inputs
+    created from file.readlines() result in diffs that are suitable for
+    file.writelines() since both the inputs and outputs have trailing
+    newlines.
+
+    For inputs that do not have trailing newlines, set the lineterm
+    argument to "" so that the output will be uniformly newline free.
+
+    The context diff format normally has a header for filenames and
+    modification times.  Any or all of these may be specified using
+    strings for 'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'.
+    The modification times are normally expressed in the format returned
+    by time.ctime().  If not specified, the strings default to blanks.
+
+    Example:
+
+    >>> print ''.join(context_diff('one\ntwo\nthree\nfour\n'.splitlines(1),
+    ...       'zero\none\ntree\nfour\n'.splitlines(1), 'Original', 'Current',
+    ...       'Sat Jan 26 23:30:50 1991', 'Fri Jun 06 10:22:46 2003')),
+    *** Original Sat Jan 26 23:30:50 1991
+    --- Current Fri Jun 06 10:22:46 2003
+    ***************
+    *** 1,4 ****
+      one
+    ! two
+    ! three
+      four
+    --- 1,4 ----
+    + zero
+      one
+    ! tree
+      four
+    """
+
+    started = False
+    prefixmap = {'insert':'+ ', 'delete':'- ', 'replace':'! ', 'equal':'  '}
+    for group in SequenceMatcher(None,a,b).get_grouped_opcodes(n):
+        if not started:
+            yield '*** %s %s%s' % (fromfile, fromfiledate, lineterm)
+            yield '--- %s %s%s' % (tofile, tofiledate, lineterm)
+            started = True
+
+        yield '***************%s' % (lineterm,)
+        if group[-1][2] - group[0][1] >= 2:
+            yield '*** %d,%d ****%s' % (group[0][1]+1, group[-1][2], lineterm)
+        else:
+            yield '*** %d ****%s' % (group[-1][2], lineterm)
+        visiblechanges = [e for e in group if e[0] in ('replace', 'delete')]
+        if visiblechanges:
+            for tag, i1, i2, _, _ in group:
+                if tag != 'insert':
+                    for line in a[i1:i2]:
+                        yield prefixmap[tag] + line
+
+        if group[-1][4] - group[0][3] >= 2:
+            yield '--- %d,%d ----%s' % (group[0][3]+1, group[-1][4], lineterm)
+        else:
+            yield '--- %d ----%s' % (group[-1][4], lineterm)
+        visiblechanges = [e for e in group if e[0] in ('replace', 'insert')]
+        if visiblechanges:
+            for tag, _, _, j1, j2 in group:
+                if tag != 'delete':
+                    for line in b[j1:j2]:
+                        yield prefixmap[tag] + line
+
+def ndiff(a, b, linejunk=None, charjunk=IS_CHARACTER_JUNK):
+    r"""
+    Compare `a` and `b` (lists of strings); return a `Differ`-style delta.
+
+    Optional keyword parameters `linejunk` and `charjunk` are for filter
+    functions (or None):
+
+    - linejunk: A function that should accept a single string argument, and
+      return true iff the string is junk.  The default is None, and is
+      recommended; as of Python 2.3, an adaptive notion of "noise" lines is
+      used that does a good job on its own.
+
+    - charjunk: A function that should accept a string of length 1. The
+      default is module-level function IS_CHARACTER_JUNK, which filters out
+      whitespace characters (a blank or tab; note: bad idea to include newline
+      in this!).
+
+    Tools/scripts/ndiff.py is a command-line front-end to this function.
+
+    Example:
+
+    >>> diff = ndiff('one\ntwo\nthree\n'.splitlines(1),
+    ...              'ore\ntree\nemu\n'.splitlines(1))
+    >>> print ''.join(diff),
+    - one
+    ?  ^
+    + ore
+    ?  ^
+    - two
+    - three
+    ?  -
+    + tree
+    + emu
+    """
+    return Differ(linejunk, charjunk).compare(a, b)
+
+def _mdiff(fromlines, tolines, context=None, linejunk=None,
+           charjunk=IS_CHARACTER_JUNK):
+    r"""Returns generator yielding marked up from/to side by side differences.
+
+    Arguments:
+    fromlines -- list of text lines to compared to tolines
+    tolines -- list of text lines to be compared to fromlines
+    context -- number of context lines to display on each side of difference,
+               if None, all from/to text lines will be generated.
+    linejunk -- passed on to ndiff (see ndiff documentation)
+    charjunk -- passed on to ndiff (see ndiff documentation)
+
+    This function returns an interator which returns a tuple:
+    (from line tuple, to line tuple, boolean flag)
+
+    from/to line tuple -- (line num, line text)
+        line num -- integer or None (to indicate a context seperation)
+        line text -- original line text with following markers inserted:
+            '\0+' -- marks start of added text
+            '\0-' -- marks start of deleted text
+            '\0^' -- marks start of changed text
+            '\1' -- marks end of added/deleted/changed text
+
+    boolean flag -- None indicates context separation, True indicates
+        either "from" or "to" line contains a change, otherwise False.
+
+    This function/iterator was originally developed to generate side by side
+    file difference for making HTML pages (see HtmlDiff class for example
+    usage).
+
+    Note, this function utilizes the ndiff function to generate the side by
+    side difference markup.  Optional ndiff arguments may be passed to this
+    function and they in turn will be passed to ndiff.
+    """
+    import re
+
+    # regular expression for finding intraline change indices
+    change_re = re.compile('(\++|\-+|\^+)')
+
+    # create the difference iterator to generate the differences
+    diff_lines_iterator = ndiff(fromlines,tolines,linejunk,charjunk)
+
+    def _make_line(lines, format_key, side, num_lines=[0,0]):
+        """Returns line of text with user's change markup and line formatting.
+
+        lines -- list of lines from the ndiff generator to produce a line of
+                 text from.  When producing the line of text to return, the
+                 lines used are removed from this list.
+        format_key -- '+' return first line in list with "add" markup around
+                          the entire line.
+                      '-' return first line in list with "delete" markup around
+                          the entire line.
+                      '?' return first line in list with add/delete/change
+                          intraline markup (indices obtained from second line)
+                      None return first line in list with no markup
+        side -- indice into the num_lines list (0=from,1=to)
+        num_lines -- from/to current line number.  This is NOT intended to be a
+                     passed parameter.  It is present as a keyword argument to
+                     maintain memory of the current line numbers between calls
+                     of this function.
+
+        Note, this function is purposefully not defined at the module scope so
+        that data it needs from its parent function (within whose context it
+        is defined) does not need to be of module scope.
+        """
+        num_lines[side] += 1
+        # Handle case where no user markup is to be added, just return line of
+        # text with user's line format to allow for usage of the line number.
+        if format_key is None:
+            return (num_lines[side],lines.pop(0)[2:])
+        # Handle case of intraline changes
+        if format_key == '?':
+            text, markers = lines.pop(0), lines.pop(0)
+            # find intraline changes (store change type and indices in tuples)
+            sub_info = []
+            def record_sub_info(match_object,sub_info=sub_info):
+                sub_info.append([match_object.group(1)[0],match_object.span()])
+                return match_object.group(1)
+            change_re.sub(record_sub_info,markers)
+            # process each tuple inserting our special marks that won't be
+            # noticed by an xml/html escaper.
+            for key,(begin,end) in sub_info[::-1]:
+                text = text[0:begin]+'\0'+key+text[begin:end]+'\1'+text[end:]
+            text = text[2:]
+        # Handle case of add/delete entire line
+        else:
+            text = lines.pop(0)[2:]
+            # if line of text is just a newline, insert a space so there is
+            # something for the user to highlight and see.
+            if not text:
+                text = ' '
+            # insert marks that won't be noticed by an xml/html escaper.
+            text = '\0' + format_key + text + '\1'
+        # Return line of text, first allow user's line formatter to do its
+        # thing (such as adding the line number) then replace the special
+        # marks with what the user's change markup.
+        return (num_lines[side],text)
+
+    def _line_iterator():
+        """Yields from/to lines of text with a change indication.
+
+        This function is an iterator.  It itself pulls lines from a
+        differencing iterator, processes them and yields them.  When it can
+        it yields both a "from" and a "to" line, otherwise it will yield one
+        or the other.  In addition to yielding the lines of from/to text, a
+        boolean flag is yielded to indicate if the text line(s) have
+        differences in them.
+
+        Note, this function is purposefully not defined at the module scope so
+        that data it needs from its parent function (within whose context it
+        is defined) does not need to be of module scope.
+        """
+        lines = []
+        num_blanks_pending, num_blanks_to_yield = 0, 0
+        while True:
+            # Load up next 4 lines so we can look ahead, create strings which
+            # are a concatenation of the first character of each of the 4 lines
+            # so we can do some very readable comparisons.
+            while len(lines) < 4:
+                try:
+                    lines.append(diff_lines_iterator.next())
+                except StopIteration:
+                    lines.append('X')
+            s = ''.join([line[0] for line in lines])
+            if s.startswith('X'):
+                # When no more lines, pump out any remaining blank lines so the
+                # corresponding add/delete lines get a matching blank line so
+                # all line pairs get yielded at the next level.
+                num_blanks_to_yield = num_blanks_pending
+            elif s.startswith('-?+?'):
+                # simple intraline change
+                yield _make_line(lines,'?',0), _make_line(lines,'?',1), True
+                continue
+            elif s.startswith('--++'):
+                # in delete block, add block coming: we do NOT want to get
+                # caught up on blank lines yet, just process the delete line
+                num_blanks_pending -= 1
+                yield _make_line(lines,'-',0), None, True
+                continue
+            elif s.startswith(('--?+', '--+', '- ')):
+                # in delete block and see a intraline change or unchanged line
+                # coming: yield the delete line and then blanks
+                from_line,to_line = _make_line(lines,'-',0), None
+                num_blanks_to_yield,num_blanks_pending = num_blanks_pending-1,0
+            elif s.startswith('-+?'):
+                # intraline change
+                yield _make_line(lines,None,0), _make_line(lines,'?',1), True
+                continue
+            elif s.startswith('-?+'):
+                # intraline change
+                yield _make_line(lines,'?',0), _make_line(lines,None,1), True
+                continue
+            elif s.startswith('-'):
+                # delete FROM line
+                num_blanks_pending -= 1
+                yield _make_line(lines,'-',0), None, True
+                continue
+            elif s.startswith('+--'):
+                # in add block, delete block coming: we do NOT want to get
+                # caught up on blank lines yet, just process the add line
+                num_blanks_pending += 1
+                yield None, _make_line(lines,'+',1), True
+                continue
+            elif s.startswith(('+ ', '+-')):
+                # will be leaving an add block: yield blanks then add line
+                from_line, to_line = None, _make_line(lines,'+',1)
+                num_blanks_to_yield,num_blanks_pending = num_blanks_pending+1,0
+            elif s.startswith('+'):
+                # inside an add block, yield the add line
+                num_blanks_pending += 1
+                yield None, _make_line(lines,'+',1), True
+                continue
+            elif s.startswith(' '):
+                # unchanged text, yield it to both sides
+                yield _make_line(lines[:],None,0),_make_line(lines,None,1),False
+                continue
+            # Catch up on the blank lines so when we yield the next from/to
+            # pair, they are lined up.
+            while(num_blanks_to_yield < 0):
+                num_blanks_to_yield += 1
+                yield None,('','\n'),True
+            while(num_blanks_to_yield > 0):
+                num_blanks_to_yield -= 1
+                yield ('','\n'),None,True
+            if s.startswith('X'):
+                raise StopIteration
+            else:
+                yield from_line,to_line,True
+
+    def _line_pair_iterator():
+        """Yields from/to lines of text with a change indication.
+
+        This function is an iterator.  It itself pulls lines from the line
+        iterator.  Its difference from that iterator is that this function
+        always yields a pair of from/to text lines (with the change
+        indication).  If necessary it will collect single from/to lines
+        until it has a matching pair from/to pair to yield.
+
+        Note, this function is purposefully not defined at the module scope so
+        that data it needs from its parent function (within whose context it
+        is defined) does not need to be of module scope.
+        """
+        line_iterator = _line_iterator()
+        fromlines,tolines=[],[]
+        while True:
+            # Collecting lines of text until we have a from/to pair
+            while (len(fromlines)==0 or len(tolines)==0):
+                from_line, to_line, found_diff =line_iterator.next()
+                if from_line is not None:
+                    fromlines.append((from_line,found_diff))
+                if to_line is not None:
+                    tolines.append((to_line,found_diff))
+            # Once we have a pair, remove them from the collection and yield it
+            from_line, fromDiff = fromlines.pop(0)
+            to_line, to_diff = tolines.pop(0)
+            yield (from_line,to_line,fromDiff or to_diff)
+
+    # Handle case where user does not want context differencing, just yield
+    # them up without doing anything else with them.
+    line_pair_iterator = _line_pair_iterator()
+    if context is None:
+        while True:
+            yield line_pair_iterator.next()
+    # Handle case where user wants context differencing.  We must do some
+    # storage of lines until we know for sure that they are to be yielded.
+    else:
+        context += 1
+        lines_to_write = 0
+        while True:
+            # Store lines up until we find a difference, note use of a
+            # circular queue because we only need to keep around what
+            # we need for context.
+            index, contextLines = 0, [None]*(context)
+            found_diff = False
+            while(found_diff is False):
+                from_line, to_line, found_diff = line_pair_iterator.next()
+                i = index % context
+                contextLines[i] = (from_line, to_line, found_diff)
+                index += 1
+            # Yield lines that we have collected so far, but first yield
+            # the user's separator.
+            if index > context:
+                yield None, None, None
+                lines_to_write = context
+            else:
+                lines_to_write = index
+                index = 0
+            while(lines_to_write):
+                i = index % context
+                index += 1
+                yield contextLines[i]
+                lines_to_write -= 1
+            # Now yield the context lines after the change
+            lines_to_write = context-1
+            while(lines_to_write):
+                from_line, to_line, found_diff = line_pair_iterator.next()
+                # If another change within the context, extend the context
+                if found_diff:
+                    lines_to_write = context-1
+                else:
+                    lines_to_write -= 1
+                yield from_line, to_line, found_diff
+
+
+_file_template = """
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html>
+
+<head>
+    <meta http-equiv="Content-Type"
+          content="text/html; charset=ISO-8859-1" />
+    <title></title>
+    <style type="text/css">%(styles)s
+    </style>
+</head>
+
+<body>
+    %(table)s%(legend)s
+</body>
+
+</html>"""
+
+_styles = """
+        table.diff {font-family:Courier; border:medium;}
+        .diff_header {background-color:#e0e0e0}
+        td.diff_header {text-align:right}
+        .diff_next {background-color:#c0c0c0}
+        .diff_add {background-color:#aaffaa}
+        .diff_chg {background-color:#ffff77}
+        .diff_sub {background-color:#ffaaaa}"""
+
+_table_template = """
+    <table class="diff" id="difflib_chg_%(prefix)s_top"
+           cellspacing="0" cellpadding="0" rules="groups" >
+        <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup>
+        <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup>
+        %(header_row)s
+        <tbody>
+%(data_rows)s        </tbody>
+    </table>"""
+
+_legend = """
+    <table class="diff" summary="Legends">
+        <tr> <th colspan="2"> Legends </th> </tr>
+        <tr> <td> <table border="" summary="Colors">
+                      <tr><th> Colors </th> </tr>
+                      <tr><td class="diff_add">&nbsp;Added&nbsp;</td></tr>
+                      <tr><td class="diff_chg">Changed</td> </tr>
+                      <tr><td class="diff_sub">Deleted</td> </tr>
+                  </table></td>
+             <td> <table border="" summary="Links">
+                      <tr><th colspan="2"> Links </th> </tr>
+                      <tr><td>(f)irst change</td> </tr>
+                      <tr><td>(n)ext change</td> </tr>
+                      <tr><td>(t)op</td> </tr>
+                  </table></td> </tr>
+    </table>"""
+
+class HtmlDiff(object):
+    """For producing HTML side by side comparison with change highlights.
+
+    This class can be used to create an HTML table (or a complete HTML file
+    containing the table) showing a side by side, line by line comparison
+    of text with inter-line and intra-line change highlights.  The table can
+    be generated in either full or contextual difference mode.
+
+    The following methods are provided for HTML generation:
+
+    make_table -- generates HTML for a single side by side table
+    make_file -- generates complete HTML file with a single side by side table
+
+    See tools/scripts/diff.py for an example usage of this class.
+    """
+
+    _file_template = _file_template
+    _styles = _styles
+    _table_template = _table_template
+    _legend = _legend
+    _default_prefix = 0
+
+    def __init__(self,tabsize=8,wrapcolumn=None,linejunk=None,
+                 charjunk=IS_CHARACTER_JUNK):
+        """HtmlDiff instance initializer
+
+        Arguments:
+        tabsize -- tab stop spacing, defaults to 8.
+        wrapcolumn -- column number where lines are broken and wrapped,
+            defaults to None where lines are not wrapped.
+        linejunk,charjunk -- keyword arguments passed into ndiff() (used to by
+            HtmlDiff() to generate the side by side HTML differences).  See
+            ndiff() documentation for argument default values and descriptions.
+        """
+        self._tabsize = tabsize
+        self._wrapcolumn = wrapcolumn
+        self._linejunk = linejunk
+        self._charjunk = charjunk
+
+    def make_file(self,fromlines,tolines,fromdesc='',todesc='',context=False,
+                  numlines=5):
+        """Returns HTML file of side by side comparison with change highlights
+
+        Arguments:
+        fromlines -- list of "from" lines
+        tolines -- list of "to" lines
+        fromdesc -- "from" file column header string
+        todesc -- "to" file column header string
+        context -- set to True for contextual differences (defaults to False
+            which shows full differences).
+        numlines -- number of context lines.  When context is set True,
+            controls number of lines displayed before and after the change.
+            When context is False, controls the number of lines to place
+            the "next" link anchors before the next change (so click of
+            "next" link jumps to just before the change).
+        """
+
+        return self._file_template % dict(
+            styles = self._styles,
+            legend = self._legend,
+            table = self.make_table(fromlines,tolines,fromdesc,todesc,
+                                    context=context,numlines=numlines))
+
+    def _tab_newline_replace(self,fromlines,tolines):
+        """Returns from/to line lists with tabs expanded and newlines removed.
+
+        Instead of tab characters being replaced by the number of spaces
+        needed to fill in to the next tab stop, this function will fill
+        the space with tab characters.  This is done so that the difference
+        algorithms can identify changes in a file when tabs are replaced by
+        spaces and vice versa.  At the end of the HTML generation, the tab
+        characters will be replaced with a nonbreakable space.
+        """
+        def expand_tabs(line):
+            # hide real spaces
+            line = line.replace(' ','\0')
+            # expand tabs into spaces
+            line = line.expandtabs(self._tabsize)
+            # relace spaces from expanded tabs back into tab characters
+            # (we'll replace them with markup after we do differencing)
+            line = line.replace(' ','\t')
+            return line.replace('\0',' ').rstrip('\n')
+        fromlines = [expand_tabs(line) for line in fromlines]
+        tolines = [expand_tabs(line) for line in tolines]
+        return fromlines,tolines
+
+    def _split_line(self,data_list,line_num,text):
+        """Builds list of text lines by splitting text lines at wrap point
+
+        This function will determine if the input text line needs to be
+        wrapped (split) into separate lines.  If so, the first wrap point
+        will be determined and the first line appended to the output
+        text line list.  This function is used recursively to handle
+        the second part of the split line to further split it.
+        """
+        # if blank line or context separator, just add it to the output list
+        if not line_num:
+            data_list.append((line_num,text))
+            return
+
+        # if line text doesn't need wrapping, just add it to the output list
+        size = len(text)
+        max = self._wrapcolumn
+        if (size <= max) or ((size -(text.count('\0')*3)) <= max):
+            data_list.append((line_num,text))
+            return
+
+        # scan text looking for the wrap point, keeping track if the wrap
+        # point is inside markers
+        i = 0
+        n = 0
+        mark = ''
+        while n < max and i < size:
+            if text[i] == '\0':
+                i += 1
+                mark = text[i]
+                i += 1
+            elif text[i] == '\1':
+                i += 1
+                mark = ''
+            else:
+                i += 1
+                n += 1
+
+        # wrap point is inside text, break it up into separate lines
+        line1 = text[:i]
+        line2 = text[i:]
+
+        # if wrap point is inside markers, place end marker at end of first
+        # line and start marker at beginning of second line because each
+        # line will have its own table tag markup around it.
+        if mark:
+            line1 = line1 + '\1'
+            line2 = '\0' + mark + line2
+
+        # tack on first line onto the output list
+        data_list.append((line_num,line1))
+
+        # use this routine again to wrap the remaining text
+        self._split_line(data_list,'>',line2)
+
+    def _line_wrapper(self,diffs):
+        """Returns iterator that splits (wraps) mdiff text lines"""
+
+        # pull from/to data and flags from mdiff iterator
+        for fromdata,todata,flag in diffs:
+            # check for context separators and pass them through
+            if flag is None:
+                yield fromdata,todata,flag
+                continue
+            (fromline,fromtext),(toline,totext) = fromdata,todata
+            # for each from/to line split it at the wrap column to form
+            # list of text lines.
+            fromlist,tolist = [],[]
+            self._split_line(fromlist,fromline,fromtext)
+            self._split_line(tolist,toline,totext)
+            # yield from/to line in pairs inserting blank lines as
+            # necessary when one side has more wrapped lines
+            while fromlist or tolist:
+                if fromlist:
+                    fromdata = fromlist.pop(0)
+                else:
+                    fromdata = ('',' ')
+                if tolist:
+                    todata = tolist.pop(0)
+                else:
+                    todata = ('',' ')
+                yield fromdata,todata,flag
+
+    def _collect_lines(self,diffs):
+        """Collects mdiff output into separate lists
+
+        Before storing the mdiff from/to data into a list, it is converted
+        into a single line of text with HTML markup.
+        """
+
+        fromlist,tolist,flaglist = [],[],[]
+        # pull from/to data and flags from mdiff style iterator
+        for fromdata,todata,flag in diffs:
+            try:
+                # store HTML markup of the lines into the lists
+                fromlist.append(self._format_line(0,flag,*fromdata))
+                tolist.append(self._format_line(1,flag,*todata))
+            except TypeError:
+                # exceptions occur for lines where context separators go
+                fromlist.append(None)
+                tolist.append(None)
+            flaglist.append(flag)
+        return fromlist,tolist,flaglist
+
+    def _format_line(self,side,flag,linenum,text):
+        """Returns HTML markup of "from" / "to" text lines
+
+        side -- 0 or 1 indicating "from" or "to" text
+        flag -- indicates if difference on line
+        linenum -- line number (used for line number column)
+        text -- line text to be marked up
+        """
+        try:
+            linenum = '%d' % linenum
+            id = ' id="%s%s"' % (self._prefix[side],linenum)
+        except TypeError:
+            # handle blank lines where linenum is '>' or ''
+            id = ''
+        # replace those things that would get confused with HTML symbols
+        text=text.replace("&","&amp;").replace(">","&gt;").replace("<","&lt;")
+
+        # make space non-breakable so they don't get compressed or line wrapped
+        text = text.replace(' ','&nbsp;').rstrip()
+
+        return '<td class="diff_header"%s>%s</td><td nowrap="nowrap">%s</td>' \
+               % (id,linenum,text)
+
+    def _make_prefix(self):
+        """Create unique anchor prefixes"""
+
+        # Generate a unique anchor prefix so multiple tables
+        # can exist on the same HTML page without conflicts.
+        fromprefix = "from%d_" % HtmlDiff._default_prefix
+        toprefix = "to%d_" % HtmlDiff._default_prefix
+        HtmlDiff._default_prefix += 1
+        # store prefixes so line format method has access
+        self._prefix = [fromprefix,toprefix]
+
+    def _convert_flags(self,fromlist,tolist,flaglist,context,numlines):
+        """Makes list of "next" links"""
+
+        # all anchor names will be generated using the unique "to" prefix
+        toprefix = self._prefix[1]
+
+        # process change flags, generating middle column of next anchors/links
+        next_id = ['']*len(flaglist)
+        next_href = ['']*len(flaglist)
+        num_chg, in_change = 0, False
+        last = 0
+        for i,flag in enumerate(flaglist):
+            if flag:
+                if not in_change:
+                    in_change = True
+                    last = i
+                    # at the beginning of a change, drop an anchor a few lines
+                    # (the context lines) before the change for the previous
+                    # link
+                    i = max([0,i-numlines])
+                    next_id[i] = ' id="difflib_chg_%s_%d"' % (toprefix,num_chg)
+                    # at the beginning of a change, drop a link to the next
+                    # change
+                    num_chg += 1
+                    next_href[last] = '<a href="#difflib_chg_%s_%d">n</a>' % (
+                         toprefix,num_chg)
+            else:
+                in_change = False
+        # check for cases where there is no content to avoid exceptions
+        if not flaglist:
+            flaglist = [False]
+            next_id = ['']
+            next_href = ['']
+            last = 0
+            if context:
+                fromlist = ['<td></td><td>&nbsp;No Differences Found&nbsp;</td>']
+                tolist = fromlist
+            else:
+                fromlist = tolist = ['<td></td><td>&nbsp;Empty File&nbsp;</td>']
+        # if not a change on first line, drop a link
+        if not flaglist[0]:
+            next_href[0] = '<a href="#difflib_chg_%s_0">f</a>' % toprefix
+        # redo the last link to link to the top
+        next_href[last] = '<a href="#difflib_chg_%s_top">t</a>' % (toprefix)
+
+        return fromlist,tolist,flaglist,next_href,next_id
+
+    def make_table(self,fromlines,tolines,fromdesc='',todesc='',context=False,
+                   numlines=5):
+        """Returns HTML table of side by side comparison with change highlights
+
+        Arguments:
+        fromlines -- list of "from" lines
+        tolines -- list of "to" lines
+        fromdesc -- "from" file column header string
+        todesc -- "to" file column header string
+        context -- set to True for contextual differences (defaults to False
+            which shows full differences).
+        numlines -- number of context lines.  When context is set True,
+            controls number of lines displayed before and after the change.
+            When context is False, controls the number of lines to place
+            the "next" link anchors before the next change (so click of
+            "next" link jumps to just before the change).
+        """
+
+        # make unique anchor prefixes so that multiple tables may exist
+        # on the same page without conflict.
+        self._make_prefix()
+
+        # change tabs to spaces before it gets more difficult after we insert
+        # markkup
+        fromlines,tolines = self._tab_newline_replace(fromlines,tolines)
+
+        # create diffs iterator which generates side by side from/to data
+        if context:
+            context_lines = numlines
+        else:
+            context_lines = None
+        diffs = _mdiff(fromlines,tolines,context_lines,linejunk=self._linejunk,
+                      charjunk=self._charjunk)
+
+        # set up iterator to wrap lines that exceed desired width
+        if self._wrapcolumn:
+            diffs = self._line_wrapper(diffs)
+
+        # collect up from/to lines and flags into lists (also format the lines)
+        fromlist,tolist,flaglist = self._collect_lines(diffs)
+
+        # process change flags, generating middle column of next anchors/links
+        fromlist,tolist,flaglist,next_href,next_id = self._convert_flags(
+            fromlist,tolist,flaglist,context,numlines)
+
+        s = []
+        fmt = '            <tr><td class="diff_next"%s>%s</td>%s' + \
+              '<td class="diff_next">%s</td>%s</tr>\n'
+        for i in range(len(flaglist)):
+            if flaglist[i] is None:
+                # mdiff yields None on separator lines skip the bogus ones
+                # generated for the first line
+                if i > 0:
+                    s.append('        </tbody>        \n        <tbody>\n')
+            else:
+                s.append( fmt % (next_id[i],next_href[i],fromlist[i],
+                                           next_href[i],tolist[i]))
+        if fromdesc or todesc:
+            header_row = '<thead><tr>%s%s%s%s</tr></thead>' % (
+                '<th class="diff_next"><br /></th>',
+                '<th colspan="2" class="diff_header">%s</th>' % fromdesc,
+                '<th class="diff_next"><br /></th>',
+                '<th colspan="2" class="diff_header">%s</th>' % todesc)
+        else:
+            header_row = ''
+
+        table = self._table_template % dict(
+            data_rows=''.join(s),
+            header_row=header_row,
+            prefix=self._prefix[1])
+
+        return table.replace('\0+','<span class="diff_add">'). \
+                     replace('\0-','<span class="diff_sub">'). \
+                     replace('\0^','<span class="diff_chg">'). \
+                     replace('\1','</span>'). \
+                     replace('\t','&nbsp;')
+
+del re
+
+def restore(delta, which):
+    r"""
+    Generate one of the two sequences that generated a delta.
+
+    Given a `delta` produced by `Differ.compare()` or `ndiff()`, extract
+    lines originating from file 1 or 2 (parameter `which`), stripping off line
+    prefixes.
+
+    Examples:
+
+    >>> diff = ndiff('one\ntwo\nthree\n'.splitlines(1),
+    ...              'ore\ntree\nemu\n'.splitlines(1))
+    >>> diff = list(diff)
+    >>> print ''.join(restore(diff, 1)),
+    one
+    two
+    three
+    >>> print ''.join(restore(diff, 2)),
+    ore
+    tree
+    emu
+    """
+    try:
+        tag = {1: "- ", 2: "+ "}[int(which)]
+    except KeyError:
+        raise ValueError, ('unknown delta choice (must be 1 or 2): %r'
+                           % which)
+    prefixes = ("  ", tag)
+    for line in delta:
+        if line[:2] in prefixes:
+            yield line[2:]
+
+def _test():
+    import doctest, difflib
+    return doctest.testmod(difflib)
+
+if __name__ == "__main__":
+    _test()

Added: vendor/Python/current/Lib/dircache.py
===================================================================
--- vendor/Python/current/Lib/dircache.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/dircache.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,38 @@
+"""Read and cache directory listings.
+
+The listdir() routine returns a sorted list of the files in a directory,
+using a cache to avoid reading the directory more often than necessary.
+The annotate() routine appends slashes to directories."""
+
+import os
+
+__all__ = ["listdir", "opendir", "annotate", "reset"]
+
+cache = {}
+
+def reset():
+    """Reset the cache completely."""
+    global cache
+    cache = {}
+
+def listdir(path):
+    """List directory contents, using cache."""
+    try:
+        cached_mtime, list = cache[path]
+        del cache[path]
+    except KeyError:
+        cached_mtime, list = -1, []
+    mtime = os.stat(path).st_mtime
+    if mtime != cached_mtime:
+        list = os.listdir(path)
+        list.sort()
+    cache[path] = mtime, list
+    return list
+
+opendir = listdir # XXX backward compatibility
+
+def annotate(head, list):
+    """Add '/' suffixes to directories."""
+    for i in range(len(list)):
+        if os.path.isdir(os.path.join(head, list[i])):
+            list[i] = list[i] + '/'

Added: vendor/Python/current/Lib/dis.py
===================================================================
--- vendor/Python/current/Lib/dis.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/dis.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,223 @@
+"""Disassembler of Python byte code into mnemonics."""
+
+import sys
+import types
+
+from opcode import *
+from opcode import __all__ as _opcodes_all
+
+__all__ = ["dis","disassemble","distb","disco"] + _opcodes_all
+del _opcodes_all
+
+def dis(x=None):
+    """Disassemble classes, methods, functions, or code.
+
+    With no argument, disassemble the last traceback.
+
+    """
+    if x is None:
+        distb()
+        return
+    if type(x) is types.InstanceType:
+        x = x.__class__
+    if hasattr(x, 'im_func'):
+        x = x.im_func
+    if hasattr(x, 'func_code'):
+        x = x.func_code
+    if hasattr(x, '__dict__'):
+        items = x.__dict__.items()
+        items.sort()
+        for name, x1 in items:
+            if type(x1) in (types.MethodType,
+                            types.FunctionType,
+                            types.CodeType,
+                            types.ClassType):
+                print "Disassembly of %s:" % name
+                try:
+                    dis(x1)
+                except TypeError, msg:
+                    print "Sorry:", msg
+                print
+    elif hasattr(x, 'co_code'):
+        disassemble(x)
+    elif isinstance(x, str):
+        disassemble_string(x)
+    else:
+        raise TypeError, \
+              "don't know how to disassemble %s objects" % \
+              type(x).__name__
+
+def distb(tb=None):
+    """Disassemble a traceback (default: last traceback)."""
+    if tb is None:
+        try:
+            tb = sys.last_traceback
+        except AttributeError:
+            raise RuntimeError, "no last traceback to disassemble"
+        while tb.tb_next: tb = tb.tb_next
+    disassemble(tb.tb_frame.f_code, tb.tb_lasti)
+
+def disassemble(co, lasti=-1):
+    """Disassemble a code object."""
+    code = co.co_code
+    labels = findlabels(code)
+    linestarts = dict(findlinestarts(co))
+    n = len(code)
+    i = 0
+    extended_arg = 0
+    free = None
+    while i < n:
+        c = code[i]
+        op = ord(c)
+        if i in linestarts:
+            if i > 0:
+                print
+            print "%3d" % linestarts[i],
+        else:
+            print '   ',
+
+        if i == lasti: print '-->',
+        else: print '   ',
+        if i in labels: print '>>',
+        else: print '  ',
+        print repr(i).rjust(4),
+        print opname[op].ljust(20),
+        i = i+1
+        if op >= HAVE_ARGUMENT:
+            oparg = ord(code[i]) + ord(code[i+1])*256 + extended_arg
+            extended_arg = 0
+            i = i+2
+            if op == EXTENDED_ARG:
+                extended_arg = oparg*65536L
+            print repr(oparg).rjust(5),
+            if op in hasconst:
+                print '(' + repr(co.co_consts[oparg]) + ')',
+            elif op in hasname:
+                print '(' + co.co_names[oparg] + ')',
+            elif op in hasjrel:
+                print '(to ' + repr(i + oparg) + ')',
+            elif op in haslocal:
+                print '(' + co.co_varnames[oparg] + ')',
+            elif op in hascompare:
+                print '(' + cmp_op[oparg] + ')',
+            elif op in hasfree:
+                if free is None:
+                    free = co.co_cellvars + co.co_freevars
+                print '(' + free[oparg] + ')',
+        print
+
+def disassemble_string(code, lasti=-1, varnames=None, names=None,
+                       constants=None):
+    labels = findlabels(code)
+    n = len(code)
+    i = 0
+    while i < n:
+        c = code[i]
+        op = ord(c)
+        if i == lasti: print '-->',
+        else: print '   ',
+        if i in labels: print '>>',
+        else: print '  ',
+        print repr(i).rjust(4),
+        print opname[op].ljust(15),
+        i = i+1
+        if op >= HAVE_ARGUMENT:
+            oparg = ord(code[i]) + ord(code[i+1])*256
+            i = i+2
+            print repr(oparg).rjust(5),
+            if op in hasconst:
+                if constants:
+                    print '(' + repr(constants[oparg]) + ')',
+                else:
+                    print '(%d)'%oparg,
+            elif op in hasname:
+                if names is not None:
+                    print '(' + names[oparg] + ')',
+                else:
+                    print '(%d)'%oparg,
+            elif op in hasjrel:
+                print '(to ' + repr(i + oparg) + ')',
+            elif op in haslocal:
+                if varnames:
+                    print '(' + varnames[oparg] + ')',
+                else:
+                    print '(%d)' % oparg,
+            elif op in hascompare:
+                print '(' + cmp_op[oparg] + ')',
+        print
+
+disco = disassemble                     # XXX For backwards compatibility
+
+def findlabels(code):
+    """Detect all offsets in a byte code which are jump targets.
+
+    Return the list of offsets.
+
+    """
+    labels = []
+    n = len(code)
+    i = 0
+    while i < n:
+        c = code[i]
+        op = ord(c)
+        i = i+1
+        if op >= HAVE_ARGUMENT:
+            oparg = ord(code[i]) + ord(code[i+1])*256
+            i = i+2
+            label = -1
+            if op in hasjrel:
+                label = i+oparg
+            elif op in hasjabs:
+                label = oparg
+            if label >= 0:
+                if label not in labels:
+                    labels.append(label)
+    return labels
+
+def findlinestarts(code):
+    """Find the offsets in a byte code which are start of lines in the source.
+
+    Generate pairs (offset, lineno) as described in Python/compile.c.
+
+    """
+    byte_increments = [ord(c) for c in code.co_lnotab[0::2]]
+    line_increments = [ord(c) for c in code.co_lnotab[1::2]]
+
+    lastlineno = None
+    lineno = code.co_firstlineno
+    addr = 0
+    for byte_incr, line_incr in zip(byte_increments, line_increments):
+        if byte_incr:
+            if lineno != lastlineno:
+                yield (addr, lineno)
+                lastlineno = lineno
+            addr += byte_incr
+        lineno += line_incr
+    if lineno != lastlineno:
+        yield (addr, lineno)
+
+def _test():
+    """Simple test program to disassemble a file."""
+    if sys.argv[1:]:
+        if sys.argv[2:]:
+            sys.stderr.write("usage: python dis.py [-|file]\n")
+            sys.exit(2)
+        fn = sys.argv[1]
+        if not fn or fn == "-":
+            fn = None
+    else:
+        fn = None
+    if fn is None:
+        f = sys.stdin
+    else:
+        f = open(fn)
+    source = f.read()
+    if fn is not None:
+        f.close()
+    else:
+        fn = "<stdin>"
+    code = compile(source, fn, "exec")
+    dis(code)
+
+if __name__ == "__main__":
+    _test()

Added: vendor/Python/current/Lib/distutils/README
===================================================================
--- vendor/Python/current/Lib/distutils/README	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/README	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,22 @@
+This directory contains only a subset of the Distutils, specifically
+the Python modules in the 'distutils' and 'distutils.command'
+packages.  This is all you need to distribute and install Python
+modules using the Distutils.  There is also a separately packaged
+standalone version of the Distutils available for people who want to
+upgrade the Distutils without upgrading Python, available from the
+Distutils web page:
+
+    http://www.python.org/sigs/distutils-sig/
+
+The standalone version includes all of the code in this directory,
+plus documentation, test scripts, examples, etc.
+
+The Distutils documentation is divided into two documents, "Installing
+Python Modules", which explains how to install Python packages, and
+"Distributing Python Modules", which explains how to write setup.py
+files.  Both documents are part of the standard Python documentation
+set, and are available from http://www.python.org/doc/current/ .
+
+        Greg Ward (gward at python.net)
+
+$Id: README 29650 2002-11-13 13:26:59Z akuchling $

Added: vendor/Python/current/Lib/distutils/__init__.py
===================================================================
--- vendor/Python/current/Lib/distutils/__init__.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/__init__.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,23 @@
+"""distutils
+
+The main package for the Python Module Distribution Utilities.  Normally
+used from a setup script as
+
+   from distutils.core import setup
+
+   setup (...)
+"""
+
+# This module should be kept compatible with Python 2.1.
+
+__revision__ = "$Id: __init__.py 54641 2007-03-31 21:02:43Z marc-andre.lemburg $"
+
+# Distutils version
+#
+# Please coordinate with Marc-Andre Lemburg <mal at egenix.com> when adding
+# new features to distutils that would warrant bumping the version number.
+#
+# In general, major and minor version should loosely follow the Python
+# version number the distutils code was shipped with.
+#
+__version__ = "2.5.1"

Added: vendor/Python/current/Lib/distutils/archive_util.py
===================================================================
--- vendor/Python/current/Lib/distutils/archive_util.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/archive_util.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,173 @@
+"""distutils.archive_util
+
+Utility functions for creating archive files (tarballs, zip files,
+that sort of thing)."""
+
+# This module should be kept compatible with Python 2.1.
+
+__revision__ = "$Id: archive_util.py 37828 2004-11-10 22:23:15Z loewis $"
+
+import os
+from distutils.errors import DistutilsExecError
+from distutils.spawn import spawn
+from distutils.dir_util import mkpath
+from distutils import log
+
+def make_tarball (base_name, base_dir, compress="gzip",
+                  verbose=0, dry_run=0):
+    """Create a (possibly compressed) tar file from all the files under
+    'base_dir'.  'compress' must be "gzip" (the default), "compress",
+    "bzip2", or None.  Both "tar" and the compression utility named by
+    'compress' must be on the default program search path, so this is
+    probably Unix-specific.  The output tar file will be named 'base_dir' +
+    ".tar", possibly plus the appropriate compression extension (".gz",
+    ".bz2" or ".Z").  Return the output filename.
+    """
+    # XXX GNU tar 1.13 has a nifty option to add a prefix directory.
+    # It's pretty new, though, so we certainly can't require it --
+    # but it would be nice to take advantage of it to skip the
+    # "create a tree of hardlinks" step!  (Would also be nice to
+    # detect GNU tar to use its 'z' option and save a step.)
+
+    compress_ext = { 'gzip': ".gz",
+                     'bzip2': '.bz2',
+                     'compress': ".Z" }
+
+    # flags for compression program, each element of list will be an argument
+    compress_flags = {'gzip': ["-f9"],
+                      'compress': ["-f"],
+                      'bzip2': ['-f9']}
+
+    if compress is not None and compress not in compress_ext.keys():
+        raise ValueError, \
+              "bad value for 'compress': must be None, 'gzip', or 'compress'"
+
+    archive_name = base_name + ".tar"
+    mkpath(os.path.dirname(archive_name), dry_run=dry_run)
+    cmd = ["tar", "-cf", archive_name, base_dir]
+    spawn(cmd, dry_run=dry_run)
+
+    if compress:
+        spawn([compress] + compress_flags[compress] + [archive_name],
+              dry_run=dry_run)
+        return archive_name + compress_ext[compress]
+    else:
+        return archive_name
+
+# make_tarball ()
+
+
+def make_zipfile (base_name, base_dir, verbose=0, dry_run=0):
+    """Create a zip file from all the files under 'base_dir'.  The output
+    zip file will be named 'base_dir' + ".zip".  Uses either the "zipfile"
+    Python module (if available) or the InfoZIP "zip" utility (if installed
+    and found on the default search path).  If neither tool is available,
+    raises DistutilsExecError.  Returns the name of the output zip file.
+    """
+    try:
+        import zipfile
+    except ImportError:
+        zipfile = None
+
+    zip_filename = base_name + ".zip"
+    mkpath(os.path.dirname(zip_filename), dry_run=dry_run)
+
+    # If zipfile module is not available, try spawning an external
+    # 'zip' command.
+    if zipfile is None:
+        if verbose:
+            zipoptions = "-r"
+        else:
+            zipoptions = "-rq"
+
+        try:
+            spawn(["zip", zipoptions, zip_filename, base_dir],
+                  dry_run=dry_run)
+        except DistutilsExecError:
+            # XXX really should distinguish between "couldn't find
+            # external 'zip' command" and "zip failed".
+            raise DistutilsExecError, \
+                  ("unable to create zip file '%s': "
+                   "could neither import the 'zipfile' module nor "
+                   "find a standalone zip utility") % zip_filename
+
+    else:
+        log.info("creating '%s' and adding '%s' to it",
+                 zip_filename, base_dir)
+
+        def visit (z, dirname, names):
+            for name in names:
+                path = os.path.normpath(os.path.join(dirname, name))
+                if os.path.isfile(path):
+                    z.write(path, path)
+                    log.info("adding '%s'" % path)
+
+        if not dry_run:
+            z = zipfile.ZipFile(zip_filename, "w",
+                                compression=zipfile.ZIP_DEFLATED)
+
+            os.path.walk(base_dir, visit, z)
+            z.close()
+
+    return zip_filename
+
+# make_zipfile ()
+
+
+ARCHIVE_FORMATS = {
+    'gztar': (make_tarball, [('compress', 'gzip')], "gzip'ed tar-file"),
+    'bztar': (make_tarball, [('compress', 'bzip2')], "bzip2'ed tar-file"),
+    'ztar':  (make_tarball, [('compress', 'compress')], "compressed tar file"),
+    'tar':   (make_tarball, [('compress', None)], "uncompressed tar file"),
+    'zip':   (make_zipfile, [],"ZIP file")
+    }
+
+def check_archive_formats (formats):
+    for format in formats:
+        if not ARCHIVE_FORMATS.has_key(format):
+            return format
+    else:
+        return None
+
+def make_archive (base_name, format,
+                  root_dir=None, base_dir=None,
+                  verbose=0, dry_run=0):
+    """Create an archive file (eg. zip or tar).  'base_name' is the name
+    of the file to create, minus any format-specific extension; 'format'
+    is the archive format: one of "zip", "tar", "ztar", or "gztar".
+    'root_dir' is a directory that will be the root directory of the
+    archive; ie. we typically chdir into 'root_dir' before creating the
+    archive.  'base_dir' is the directory where we start archiving from;
+    ie. 'base_dir' will be the common prefix of all files and
+    directories in the archive.  'root_dir' and 'base_dir' both default
+    to the current directory.  Returns the name of the archive file.
+    """
+    save_cwd = os.getcwd()
+    if root_dir is not None:
+        log.debug("changing into '%s'", root_dir)
+        base_name = os.path.abspath(base_name)
+        if not dry_run:
+            os.chdir(root_dir)
+
+    if base_dir is None:
+        base_dir = os.curdir
+
+    kwargs = { 'dry_run': dry_run }
+
+    try:
+        format_info = ARCHIVE_FORMATS[format]
+    except KeyError:
+        raise ValueError, "unknown archive format '%s'" % format
+
+    func = format_info[0]
+    for (arg,val) in format_info[1]:
+        kwargs[arg] = val
+    filename = apply(func, (base_name, base_dir), kwargs)
+
+    if root_dir is not None:
+        log.debug("changing back to '%s'", save_cwd)
+        os.chdir(save_cwd)
+
+    return filename
+
+# make_archive ()

Added: vendor/Python/current/Lib/distutils/bcppcompiler.py
===================================================================
--- vendor/Python/current/Lib/distutils/bcppcompiler.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/bcppcompiler.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,398 @@
+"""distutils.bcppcompiler
+
+Contains BorlandCCompiler, an implementation of the abstract CCompiler class
+for the Borland C++ compiler.
+"""
+
+# This implementation by Lyle Johnson, based on the original msvccompiler.py
+# module and using the directions originally published by Gordon Williams.
+
+# XXX looks like there's a LOT of overlap between these two classes:
+# someone should sit down and factor out the common code as
+# WindowsCCompiler!  --GPW
+
+# This module should be kept compatible with Python 2.1.
+
+__revision__ = "$Id: bcppcompiler.py 37828 2004-11-10 22:23:15Z loewis $"
+
+
+import sys, os
+from distutils.errors import \
+     DistutilsExecError, DistutilsPlatformError, \
+     CompileError, LibError, LinkError, UnknownFileError
+from distutils.ccompiler import \
+     CCompiler, gen_preprocess_options, gen_lib_options
+from distutils.file_util import write_file
+from distutils.dep_util import newer
+from distutils import log
+
+class BCPPCompiler(CCompiler) :
+    """Concrete class that implements an interface to the Borland C/C++
+    compiler, as defined by the CCompiler abstract class.
+    """
+
+    compiler_type = 'bcpp'
+
+    # Just set this so CCompiler's constructor doesn't barf.  We currently
+    # don't use the 'set_executables()' bureaucracy provided by CCompiler,
+    # as it really isn't necessary for this sort of single-compiler class.
+    # Would be nice to have a consistent interface with UnixCCompiler,
+    # though, so it's worth thinking about.
+    executables = {}
+
+    # Private class data (need to distinguish C from C++ source for compiler)
+    _c_extensions = ['.c']
+    _cpp_extensions = ['.cc', '.cpp', '.cxx']
+
+    # Needed for the filename generation methods provided by the
+    # base class, CCompiler.
+    src_extensions = _c_extensions + _cpp_extensions
+    obj_extension = '.obj'
+    static_lib_extension = '.lib'
+    shared_lib_extension = '.dll'
+    static_lib_format = shared_lib_format = '%s%s'
+    exe_extension = '.exe'
+
+
+    def __init__ (self,
+                  verbose=0,
+                  dry_run=0,
+                  force=0):
+
+        CCompiler.__init__ (self, verbose, dry_run, force)
+
+        # These executables are assumed to all be in the path.
+        # Borland doesn't seem to use any special registry settings to
+        # indicate their installation locations.
+
+        self.cc = "bcc32.exe"
+        self.linker = "ilink32.exe"
+        self.lib = "tlib.exe"
+
+        self.preprocess_options = None
+        self.compile_options = ['/tWM', '/O2', '/q', '/g0']
+        self.compile_options_debug = ['/tWM', '/Od', '/q', '/g0']
+
+        self.ldflags_shared = ['/Tpd', '/Gn', '/q', '/x']
+        self.ldflags_shared_debug = ['/Tpd', '/Gn', '/q', '/x']
+        self.ldflags_static = []
+        self.ldflags_exe = ['/Gn', '/q', '/x']
+        self.ldflags_exe_debug = ['/Gn', '/q', '/x','/r']
+
+
+    # -- Worker methods ------------------------------------------------
+
+    def compile(self, sources,
+                output_dir=None, macros=None, include_dirs=None, debug=0,
+                extra_preargs=None, extra_postargs=None, depends=None):
+
+        macros, objects, extra_postargs, pp_opts, build = \
+                self._setup_compile(output_dir, macros, include_dirs, sources,
+                                    depends, extra_postargs)
+        compile_opts = extra_preargs or []
+        compile_opts.append ('-c')
+        if debug:
+            compile_opts.extend (self.compile_options_debug)
+        else:
+            compile_opts.extend (self.compile_options)
+
+        for obj in objects:
+            try:
+                src, ext = build[obj]
+            except KeyError:
+                continue
+            # XXX why do the normpath here?
+            src = os.path.normpath(src)
+            obj = os.path.normpath(obj)
+            # XXX _setup_compile() did a mkpath() too but before the normpath.
+            # Is it possible to skip the normpath?
+            self.mkpath(os.path.dirname(obj))
+
+            if ext == '.res':
+                # This is already a binary file -- skip it.
+                continue # the 'for' loop
+            if ext == '.rc':
+                # This needs to be compiled to a .res file -- do it now.
+                try:
+                    self.spawn (["brcc32", "-fo", obj, src])
+                except DistutilsExecError, msg:
+                    raise CompileError, msg
+                continue # the 'for' loop
+
+            # The next two are both for the real compiler.
+            if ext in self._c_extensions:
+                input_opt = ""
+            elif ext in self._cpp_extensions:
+                input_opt = "-P"
+            else:
+                # Unknown file type -- no extra options.  The compiler
+                # will probably fail, but let it just in case this is a
+                # file the compiler recognizes even if we don't.
+                input_opt = ""
+
+            output_opt = "-o" + obj
+
+            # Compiler command line syntax is: "bcc32 [options] file(s)".
+            # Note that the source file names must appear at the end of
+            # the command line.
+            try:
+                self.spawn ([self.cc] + compile_opts + pp_opts +
+                            [input_opt, output_opt] +
+                            extra_postargs + [src])
+            except DistutilsExecError, msg:
+                raise CompileError, msg
+
+        return objects
+
+    # compile ()
+
+
+    def create_static_lib (self,
+                           objects,
+                           output_libname,
+                           output_dir=None,
+                           debug=0,
+                           target_lang=None):
+
+        (objects, output_dir) = self._fix_object_args (objects, output_dir)
+        output_filename = \
+            self.library_filename (output_libname, output_dir=output_dir)
+
+        if self._need_link (objects, output_filename):
+            lib_args = [output_filename, '/u'] + objects
+            if debug:
+                pass                    # XXX what goes here?
+            try:
+                self.spawn ([self.lib] + lib_args)
+            except DistutilsExecError, msg:
+                raise LibError, msg
+        else:
+            log.debug("skipping %s (up-to-date)", output_filename)
+
+    # create_static_lib ()
+
+
+    def link (self,
+              target_desc,
+              objects,
+              output_filename,
+              output_dir=None,
+              libraries=None,
+              library_dirs=None,
+              runtime_library_dirs=None,
+              export_symbols=None,
+              debug=0,
+              extra_preargs=None,
+              extra_postargs=None,
+              build_temp=None,
+              target_lang=None):
+
+        # XXX this ignores 'build_temp'!  should follow the lead of
+        # msvccompiler.py
+
+        (objects, output_dir) = self._fix_object_args (objects, output_dir)
+        (libraries, library_dirs, runtime_library_dirs) = \
+            self._fix_lib_args (libraries, library_dirs, runtime_library_dirs)
+
+        if runtime_library_dirs:
+            log.warn("I don't know what to do with 'runtime_library_dirs': %s",
+                     str(runtime_library_dirs))
+
+        if output_dir is not None:
+            output_filename = os.path.join (output_dir, output_filename)
+
+        if self._need_link (objects, output_filename):
+
+            # Figure out linker args based on type of target.
+            if target_desc == CCompiler.EXECUTABLE:
+                startup_obj = 'c0w32'
+                if debug:
+                    ld_args = self.ldflags_exe_debug[:]
+                else:
+                    ld_args = self.ldflags_exe[:]
+            else:
+                startup_obj = 'c0d32'
+                if debug:
+                    ld_args = self.ldflags_shared_debug[:]
+                else:
+                    ld_args = self.ldflags_shared[:]
+
+
+            # Create a temporary exports file for use by the linker
+            if export_symbols is None:
+                def_file = ''
+            else:
+                head, tail = os.path.split (output_filename)
+                modname, ext = os.path.splitext (tail)
+                temp_dir = os.path.dirname(objects[0]) # preserve tree structure
+                def_file = os.path.join (temp_dir, '%s.def' % modname)
+                contents = ['EXPORTS']
+                for sym in (export_symbols or []):
+                    contents.append('  %s=_%s' % (sym, sym))
+                self.execute(write_file, (def_file, contents),
+                             "writing %s" % def_file)
+
+            # Borland C++ has problems with '/' in paths
+            objects2 = map(os.path.normpath, objects)
+            # split objects in .obj and .res files
+            # Borland C++ needs them at different positions in the command line
+            objects = [startup_obj]
+            resources = []
+            for file in objects2:
+                (base, ext) = os.path.splitext(os.path.normcase(file))
+                if ext == '.res':
+                    resources.append(file)
+                else:
+                    objects.append(file)
+
+
+            for l in library_dirs:
+                ld_args.append("/L%s" % os.path.normpath(l))
+            ld_args.append("/L.") # we sometimes use relative paths
+
+            # list of object files
+            ld_args.extend(objects)
+
+            # XXX the command-line syntax for Borland C++ is a bit wonky;
+            # certain filenames are jammed together in one big string, but
+            # comma-delimited.  This doesn't mesh too well with the
+            # Unix-centric attitude (with a DOS/Windows quoting hack) of
+            # 'spawn()', so constructing the argument list is a bit
+            # awkward.  Note that doing the obvious thing and jamming all
+            # the filenames and commas into one argument would be wrong,
+            # because 'spawn()' would quote any filenames with spaces in
+            # them.  Arghghh!.  Apparently it works fine as coded...
+
+            # name of dll/exe file
+            ld_args.extend([',',output_filename])
+            # no map file and start libraries
+            ld_args.append(',,')
+
+            for lib in libraries:
+                # see if we find it and if there is a bcpp specific lib
+                # (xxx_bcpp.lib)
+                libfile = self.find_library_file(library_dirs, lib, debug)
+                if libfile is None:
+                    ld_args.append(lib)
+                    # probably a BCPP internal library -- don't warn
+                else:
+                    # full name which prefers bcpp_xxx.lib over xxx.lib
+                    ld_args.append(libfile)
+
+            # some default libraries
+            ld_args.append ('import32')
+            ld_args.append ('cw32mt')
+
+            # def file for export symbols
+            ld_args.extend([',',def_file])
+            # add resource files
+            ld_args.append(',')
+            ld_args.extend(resources)
+
+
+            if extra_preargs:
+                ld_args[:0] = extra_preargs
+            if extra_postargs:
+                ld_args.extend(extra_postargs)
+
+            self.mkpath (os.path.dirname (output_filename))
+            try:
+                self.spawn ([self.linker] + ld_args)
+            except DistutilsExecError, msg:
+                raise LinkError, msg
+
+        else:
+            log.debug("skipping %s (up-to-date)", output_filename)
+
+    # link ()
+
+    # -- Miscellaneous methods -----------------------------------------
+
+
+    def find_library_file (self, dirs, lib, debug=0):
+        # List of effective library names to try, in order of preference:
+        # xxx_bcpp.lib is better than xxx.lib
+        # and xxx_d.lib is better than xxx.lib if debug is set
+        #
+        # The "_bcpp" suffix is to handle a Python installation for people
+        # with multiple compilers (primarily Distutils hackers, I suspect
+        # ;-).  The idea is they'd have one static library for each
+        # compiler they care about, since (almost?) every Windows compiler
+        # seems to have a different format for static libraries.
+        if debug:
+            dlib = (lib + "_d")
+            try_names = (dlib + "_bcpp", lib + "_bcpp", dlib, lib)
+        else:
+            try_names = (lib + "_bcpp", lib)
+
+        for dir in dirs:
+            for name in try_names:
+                libfile = os.path.join(dir, self.library_filename(name))
+                if os.path.exists(libfile):
+                    return libfile
+        else:
+            # Oops, didn't find it in *any* of 'dirs'
+            return None
+
+    # overwrite the one from CCompiler to support rc and res-files
+    def object_filenames (self,
+                          source_filenames,
+                          strip_dir=0,
+                          output_dir=''):
+        if output_dir is None: output_dir = ''
+        obj_names = []
+        for src_name in source_filenames:
+            # use normcase to make sure '.rc' is really '.rc' and not '.RC'
+            (base, ext) = os.path.splitext (os.path.normcase(src_name))
+            if ext not in (self.src_extensions + ['.rc','.res']):
+                raise UnknownFileError, \
+                      "unknown file type '%s' (from '%s')" % \
+                      (ext, src_name)
+            if strip_dir:
+                base = os.path.basename (base)
+            if ext == '.res':
+                # these can go unchanged
+                obj_names.append (os.path.join (output_dir, base + ext))
+            elif ext == '.rc':
+                # these need to be compiled to .res-files
+                obj_names.append (os.path.join (output_dir, base + '.res'))
+            else:
+                obj_names.append (os.path.join (output_dir,
+                                            base + self.obj_extension))
+        return obj_names
+
+    # object_filenames ()
+
+    def preprocess (self,
+                    source,
+                    output_file=None,
+                    macros=None,
+                    include_dirs=None,
+                    extra_preargs=None,
+                    extra_postargs=None):
+
+        (_, macros, include_dirs) = \
+            self._fix_compile_args(None, macros, include_dirs)
+        pp_opts = gen_preprocess_options(macros, include_dirs)
+        pp_args = ['cpp32.exe'] + pp_opts
+        if output_file is not None:
+            pp_args.append('-o' + output_file)
+        if extra_preargs:
+            pp_args[:0] = extra_preargs
+        if extra_postargs:
+            pp_args.extend(extra_postargs)
+        pp_args.append(source)
+
+        # We need to preprocess: either we're being forced to, or the
+        # source file is newer than the target (or the target doesn't
+        # exist).
+        if self.force or output_file is None or newer(source, output_file):
+            if output_file:
+                self.mkpath(os.path.dirname(output_file))
+            try:
+                self.spawn(pp_args)
+            except DistutilsExecError, msg:
+                print msg
+                raise CompileError, msg
+
+    # preprocess()

Added: vendor/Python/current/Lib/distutils/ccompiler.py
===================================================================
--- vendor/Python/current/Lib/distutils/ccompiler.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/ccompiler.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1268 @@
+"""distutils.ccompiler
+
+Contains CCompiler, an abstract base class that defines the interface
+for the Distutils compiler abstraction model."""
+
+# This module should be kept compatible with Python 2.1.
+
+__revision__ = "$Id: ccompiler.py 46331 2006-05-26 14:07:23Z bob.ippolito $"
+
+import sys, os, re
+from types import *
+from copy import copy
+from distutils.errors import *
+from distutils.spawn import spawn
+from distutils.file_util import move_file
+from distutils.dir_util import mkpath
+from distutils.dep_util import newer_pairwise, newer_group
+from distutils.util import split_quoted, execute
+from distutils import log
+
+class CCompiler:
+    """Abstract base class to define the interface that must be implemented
+    by real compiler classes.  Also has some utility methods used by
+    several compiler classes.
+
+    The basic idea behind a compiler abstraction class is that each
+    instance can be used for all the compile/link steps in building a
+    single project.  Thus, attributes common to all of those compile and
+    link steps -- include directories, macros to define, libraries to link
+    against, etc. -- are attributes of the compiler instance.  To allow for
+    variability in how individual files are treated, most of those
+    attributes may be varied on a per-compilation or per-link basis.
+    """
+
+    # 'compiler_type' is a class attribute that identifies this class.  It
+    # keeps code that wants to know what kind of compiler it's dealing with
+    # from having to import all possible compiler classes just to do an
+    # 'isinstance'.  In concrete CCompiler subclasses, 'compiler_type'
+    # should really, really be one of the keys of the 'compiler_class'
+    # dictionary (see below -- used by the 'new_compiler()' factory
+    # function) -- authors of new compiler interface classes are
+    # responsible for updating 'compiler_class'!
+    compiler_type = None
+
+    # XXX things not handled by this compiler abstraction model:
+    #   * client can't provide additional options for a compiler,
+    #     e.g. warning, optimization, debugging flags.  Perhaps this
+    #     should be the domain of concrete compiler abstraction classes
+    #     (UnixCCompiler, MSVCCompiler, etc.) -- or perhaps the base
+    #     class should have methods for the common ones.
+    #   * can't completely override the include or library searchg
+    #     path, ie. no "cc -I -Idir1 -Idir2" or "cc -L -Ldir1 -Ldir2".
+    #     I'm not sure how widely supported this is even by Unix
+    #     compilers, much less on other platforms.  And I'm even less
+    #     sure how useful it is; maybe for cross-compiling, but
+    #     support for that is a ways off.  (And anyways, cross
+    #     compilers probably have a dedicated binary with the
+    #     right paths compiled in.  I hope.)
+    #   * can't do really freaky things with the library list/library
+    #     dirs, e.g. "-Ldir1 -lfoo -Ldir2 -lfoo" to link against
+    #     different versions of libfoo.a in different locations.  I
+    #     think this is useless without the ability to null out the
+    #     library search path anyways.
+
+
+    # Subclasses that rely on the standard filename generation methods
+    # implemented below should override these; see the comment near
+    # those methods ('object_filenames()' et. al.) for details:
+    src_extensions = None               # list of strings
+    obj_extension = None                # string
+    static_lib_extension = None
+    shared_lib_extension = None         # string
+    static_lib_format = None            # format string
+    shared_lib_format = None            # prob. same as static_lib_format
+    exe_extension = None                # string
+
+    # Default language settings. language_map is used to detect a source
+    # file or Extension target language, checking source filenames.
+    # language_order is used to detect the language precedence, when deciding
+    # what language to use when mixing source types. For example, if some
+    # extension has two files with ".c" extension, and one with ".cpp", it
+    # is still linked as c++.
+    language_map = {".c"   : "c",
+                    ".cc"  : "c++",
+                    ".cpp" : "c++",
+                    ".cxx" : "c++",
+                    ".m"   : "objc",
+                   }
+    language_order = ["c++", "objc", "c"]
+
+    def __init__ (self,
+                  verbose=0,
+                  dry_run=0,
+                  force=0):
+
+        self.dry_run = dry_run
+        self.force = force
+        self.verbose = verbose
+
+        # 'output_dir': a common output directory for object, library,
+        # shared object, and shared library files
+        self.output_dir = None
+
+        # 'macros': a list of macro definitions (or undefinitions).  A
+        # macro definition is a 2-tuple (name, value), where the value is
+        # either a string or None (no explicit value).  A macro
+        # undefinition is a 1-tuple (name,).
+        self.macros = []
+
+        # 'include_dirs': a list of directories to search for include files
+        self.include_dirs = []
+
+        # 'libraries': a list of libraries to include in any link
+        # (library names, not filenames: eg. "foo" not "libfoo.a")
+        self.libraries = []
+
+        # 'library_dirs': a list of directories to search for libraries
+        self.library_dirs = []
+
+        # 'runtime_library_dirs': a list of directories to search for
+        # shared libraries/objects at runtime
+        self.runtime_library_dirs = []
+
+        # 'objects': a list of object files (or similar, such as explicitly
+        # named library files) to include on any link
+        self.objects = []
+
+        for key in self.executables.keys():
+            self.set_executable(key, self.executables[key])
+
+    # __init__ ()
+
+
+    def set_executables (self, **args):
+
+        """Define the executables (and options for them) that will be run
+        to perform the various stages of compilation.  The exact set of
+        executables that may be specified here depends on the compiler
+        class (via the 'executables' class attribute), but most will have:
+          compiler      the C/C++ compiler
+          linker_so     linker used to create shared objects and libraries
+          linker_exe    linker used to create binary executables
+          archiver      static library creator
+
+        On platforms with a command-line (Unix, DOS/Windows), each of these
+        is a string that will be split into executable name and (optional)
+        list of arguments.  (Splitting the string is done similarly to how
+        Unix shells operate: words are delimited by spaces, but quotes and
+        backslashes can override this.  See
+        'distutils.util.split_quoted()'.)
+        """
+
+        # Note that some CCompiler implementation classes will define class
+        # attributes 'cpp', 'cc', etc. with hard-coded executable names;
+        # this is appropriate when a compiler class is for exactly one
+        # compiler/OS combination (eg. MSVCCompiler).  Other compiler
+        # classes (UnixCCompiler, in particular) are driven by information
+        # discovered at run-time, since there are many different ways to do
+        # basically the same things with Unix C compilers.
+
+        for key in args.keys():
+            if not self.executables.has_key(key):
+                raise ValueError, \
+                      "unknown executable '%s' for class %s" % \
+                      (key, self.__class__.__name__)
+            self.set_executable(key, args[key])
+
+    # set_executables ()
+
+    def set_executable(self, key, value):
+        if type(value) is StringType:
+            setattr(self, key, split_quoted(value))
+        else:
+            setattr(self, key, value)
+
+
+    def _find_macro (self, name):
+        i = 0
+        for defn in self.macros:
+            if defn[0] == name:
+                return i
+            i = i + 1
+
+        return None
+
+
+    def _check_macro_definitions (self, definitions):
+        """Ensures that every element of 'definitions' is a valid macro
+        definition, ie. either (name,value) 2-tuple or a (name,) tuple.  Do
+        nothing if all definitions are OK, raise TypeError otherwise.
+        """
+        for defn in definitions:
+            if not (type (defn) is TupleType and
+                    (len (defn) == 1 or
+                     (len (defn) == 2 and
+                      (type (defn[1]) is StringType or defn[1] is None))) and
+                    type (defn[0]) is StringType):
+                raise TypeError, \
+                      ("invalid macro definition '%s': " % defn) + \
+                      "must be tuple (string,), (string, string), or " + \
+                      "(string, None)"
+
+
+    # -- Bookkeeping methods -------------------------------------------
+
+    def define_macro (self, name, value=None):
+        """Define a preprocessor macro for all compilations driven by this
+        compiler object.  The optional parameter 'value' should be a
+        string; if it is not supplied, then the macro will be defined
+        without an explicit value and the exact outcome depends on the
+        compiler used (XXX true? does ANSI say anything about this?)
+        """
+        # Delete from the list of macro definitions/undefinitions if
+        # already there (so that this one will take precedence).
+        i = self._find_macro (name)
+        if i is not None:
+            del self.macros[i]
+
+        defn = (name, value)
+        self.macros.append (defn)
+
+
+    def undefine_macro (self, name):
+        """Undefine a preprocessor macro for all compilations driven by
+        this compiler object.  If the same macro is defined by
+        'define_macro()' and undefined by 'undefine_macro()' the last call
+        takes precedence (including multiple redefinitions or
+        undefinitions).  If the macro is redefined/undefined on a
+        per-compilation basis (ie. in the call to 'compile()'), then that
+        takes precedence.
+        """
+        # Delete from the list of macro definitions/undefinitions if
+        # already there (so that this one will take precedence).
+        i = self._find_macro (name)
+        if i is not None:
+            del self.macros[i]
+
+        undefn = (name,)
+        self.macros.append (undefn)
+
+
+    def add_include_dir (self, dir):
+        """Add 'dir' to the list of directories that will be searched for
+        header files.  The compiler is instructed to search directories in
+        the order in which they are supplied by successive calls to
+        'add_include_dir()'.
+        """
+        self.include_dirs.append (dir)
+
+    def set_include_dirs (self, dirs):
+        """Set the list of directories that will be searched to 'dirs' (a
+        list of strings).  Overrides any preceding calls to
+        'add_include_dir()'; subsequence calls to 'add_include_dir()' add
+        to the list passed to 'set_include_dirs()'.  This does not affect
+        any list of standard include directories that the compiler may
+        search by default.
+        """
+        self.include_dirs = copy (dirs)
+
+
+    def add_library (self, libname):
+        """Add 'libname' to the list of libraries that will be included in
+        all links driven by this compiler object.  Note that 'libname'
+        should *not* be the name of a file containing a library, but the
+        name of the library itself: the actual filename will be inferred by
+        the linker, the compiler, or the compiler class (depending on the
+        platform).
+
+        The linker will be instructed to link against libraries in the
+        order they were supplied to 'add_library()' and/or
+        'set_libraries()'.  It is perfectly valid to duplicate library
+        names; the linker will be instructed to link against libraries as
+        many times as they are mentioned.
+        """
+        self.libraries.append (libname)
+
+    def set_libraries (self, libnames):
+        """Set the list of libraries to be included in all links driven by
+        this compiler object to 'libnames' (a list of strings).  This does
+        not affect any standard system libraries that the linker may
+        include by default.
+        """
+        self.libraries = copy (libnames)
+
+
+    def add_library_dir (self, dir):
+        """Add 'dir' to the list of directories that will be searched for
+        libraries specified to 'add_library()' and 'set_libraries()'.  The
+        linker will be instructed to search for libraries in the order they
+        are supplied to 'add_library_dir()' and/or 'set_library_dirs()'.
+        """
+        self.library_dirs.append (dir)
+
+    def set_library_dirs (self, dirs):
+        """Set the list of library search directories to 'dirs' (a list of
+        strings).  This does not affect any standard library search path
+        that the linker may search by default.
+        """
+        self.library_dirs = copy (dirs)
+
+
+    def add_runtime_library_dir (self, dir):
+        """Add 'dir' to the list of directories that will be searched for
+        shared libraries at runtime.
+        """
+        self.runtime_library_dirs.append (dir)
+
+    def set_runtime_library_dirs (self, dirs):
+        """Set the list of directories to search for shared libraries at
+        runtime to 'dirs' (a list of strings).  This does not affect any
+        standard search path that the runtime linker may search by
+        default.
+        """
+        self.runtime_library_dirs = copy (dirs)
+
+
+    def add_link_object (self, object):
+        """Add 'object' to the list of object files (or analogues, such as
+        explicitly named library files or the output of "resource
+        compilers") to be included in every link driven by this compiler
+        object.
+        """
+        self.objects.append (object)
+
+    def set_link_objects (self, objects):
+        """Set the list of object files (or analogues) to be included in
+        every link to 'objects'.  This does not affect any standard object
+        files that the linker may include by default (such as system
+        libraries).
+        """
+        self.objects = copy (objects)
+
+
+    # -- Private utility methods --------------------------------------
+    # (here for the convenience of subclasses)
+
+    # Helper method to prep compiler in subclass compile() methods
+
+    def _setup_compile(self, outdir, macros, incdirs, sources, depends,
+                       extra):
+        """Process arguments and decide which source files to compile.
+
+        Merges _fix_compile_args() and _prep_compile().
+        """
+        if outdir is None:
+            outdir = self.output_dir
+        elif type(outdir) is not StringType:
+            raise TypeError, "'output_dir' must be a string or None"
+
+        if macros is None:
+            macros = self.macros
+        elif type(macros) is ListType:
+            macros = macros + (self.macros or [])
+        else:
+            raise TypeError, "'macros' (if supplied) must be a list of tuples"
+
+        if incdirs is None:
+            incdirs = self.include_dirs
+        elif type(incdirs) in (ListType, TupleType):
+            incdirs = list(incdirs) + (self.include_dirs or [])
+        else:
+            raise TypeError, \
+                  "'include_dirs' (if supplied) must be a list of strings"
+
+        if extra is None:
+            extra = []
+
+        # Get the list of expected output (object) files
+        objects = self.object_filenames(sources,
+                                        strip_dir=0,
+                                        output_dir=outdir)
+        assert len(objects) == len(sources)
+
+        # XXX should redo this code to eliminate skip_source entirely.
+        # XXX instead create build and issue skip messages inline
+
+        if self.force:
+            skip_source = {}            # rebuild everything
+            for source in sources:
+                skip_source[source] = 0
+        elif depends is None:
+            # If depends is None, figure out which source files we
+            # have to recompile according to a simplistic check. We
+            # just compare the source and object file, no deep
+            # dependency checking involving header files.
+            skip_source = {}            # rebuild everything
+            for source in sources:      # no wait, rebuild nothing
+                skip_source[source] = 1
+
+            n_sources, n_objects = newer_pairwise(sources, objects)
+            for source in n_sources:    # no really, only rebuild what's
+                skip_source[source] = 0 # out-of-date
+        else:
+            # If depends is a list of files, then do a different
+            # simplistic check.  Assume that each object depends on
+            # its source and all files in the depends list.
+            skip_source = {}
+            # L contains all the depends plus a spot at the end for a
+            # particular source file
+            L = depends[:] + [None]
+            for i in range(len(objects)):
+                source = sources[i]
+                L[-1] = source
+                if newer_group(L, objects[i]):
+                    skip_source[source] = 0
+                else:
+                    skip_source[source] = 1
+
+        pp_opts = gen_preprocess_options(macros, incdirs)
+
+        build = {}
+        for i in range(len(sources)):
+            src = sources[i]
+            obj = objects[i]
+            ext = os.path.splitext(src)[1]
+            self.mkpath(os.path.dirname(obj))
+            if skip_source[src]:
+                log.debug("skipping %s (%s up-to-date)", src, obj)
+            else:
+                build[obj] = src, ext
+
+        return macros, objects, extra, pp_opts, build
+
+    def _get_cc_args(self, pp_opts, debug, before):
+        # works for unixccompiler, emxccompiler, cygwinccompiler
+        cc_args = pp_opts + ['-c']
+        if debug:
+            cc_args[:0] = ['-g']
+        if before:
+            cc_args[:0] = before
+        return cc_args
+
+    def _fix_compile_args (self, output_dir, macros, include_dirs):
+        """Typecheck and fix-up some of the arguments to the 'compile()'
+        method, and return fixed-up values.  Specifically: if 'output_dir'
+        is None, replaces it with 'self.output_dir'; ensures that 'macros'
+        is a list, and augments it with 'self.macros'; ensures that
+        'include_dirs' is a list, and augments it with 'self.include_dirs'.
+        Guarantees that the returned values are of the correct type,
+        i.e. for 'output_dir' either string or None, and for 'macros' and
+        'include_dirs' either list or None.
+        """
+        if output_dir is None:
+            output_dir = self.output_dir
+        elif type (output_dir) is not StringType:
+            raise TypeError, "'output_dir' must be a string or None"
+
+        if macros is None:
+            macros = self.macros
+        elif type (macros) is ListType:
+            macros = macros + (self.macros or [])
+        else:
+            raise TypeError, "'macros' (if supplied) must be a list of tuples"
+
+        if include_dirs is None:
+            include_dirs = self.include_dirs
+        elif type (include_dirs) in (ListType, TupleType):
+            include_dirs = list (include_dirs) + (self.include_dirs or [])
+        else:
+            raise TypeError, \
+                  "'include_dirs' (if supplied) must be a list of strings"
+
+        return output_dir, macros, include_dirs
+
+    # _fix_compile_args ()
+
+
+    def _prep_compile(self, sources, output_dir, depends=None):
+        """Decide which souce files must be recompiled.
+
+        Determine the list of object files corresponding to 'sources',
+        and figure out which ones really need to be recompiled.
+        Return a list of all object files and a dictionary telling
+        which source files can be skipped.
+        """
+        # Get the list of expected output (object) files
+        objects = self.object_filenames(sources, output_dir=output_dir)
+        assert len(objects) == len(sources)
+
+        if self.force:
+            skip_source = {}            # rebuild everything
+            for source in sources:
+                skip_source[source] = 0
+        elif depends is None:
+            # If depends is None, figure out which source files we
+            # have to recompile according to a simplistic check. We
+            # just compare the source and object file, no deep
+            # dependency checking involving header files.
+            skip_source = {}            # rebuild everything
+            for source in sources:      # no wait, rebuild nothing
+                skip_source[source] = 1
+
+            n_sources, n_objects = newer_pairwise(sources, objects)
+            for source in n_sources:    # no really, only rebuild what's
+                skip_source[source] = 0 # out-of-date
+        else:
+            # If depends is a list of files, then do a different
+            # simplistic check.  Assume that each object depends on
+            # its source and all files in the depends list.
+            skip_source = {}
+            # L contains all the depends plus a spot at the end for a
+            # particular source file
+            L = depends[:] + [None]
+            for i in range(len(objects)):
+                source = sources[i]
+                L[-1] = source
+                if newer_group(L, objects[i]):
+                    skip_source[source] = 0
+                else:
+                    skip_source[source] = 1
+
+        return objects, skip_source
+
+    # _prep_compile ()
+
+
+    def _fix_object_args (self, objects, output_dir):
+        """Typecheck and fix up some arguments supplied to various methods.
+        Specifically: ensure that 'objects' is a list; if output_dir is
+        None, replace with self.output_dir.  Return fixed versions of
+        'objects' and 'output_dir'.
+        """
+        if type (objects) not in (ListType, TupleType):
+            raise TypeError, \
+                  "'objects' must be a list or tuple of strings"
+        objects = list (objects)
+
+        if output_dir is None:
+            output_dir = self.output_dir
+        elif type (output_dir) is not StringType:
+            raise TypeError, "'output_dir' must be a string or None"
+
+        return (objects, output_dir)
+
+
+    def _fix_lib_args (self, libraries, library_dirs, runtime_library_dirs):
+        """Typecheck and fix up some of the arguments supplied to the
+        'link_*' methods.  Specifically: ensure that all arguments are
+        lists, and augment them with their permanent versions
+        (eg. 'self.libraries' augments 'libraries').  Return a tuple with
+        fixed versions of all arguments.
+        """
+        if libraries is None:
+            libraries = self.libraries
+        elif type (libraries) in (ListType, TupleType):
+            libraries = list (libraries) + (self.libraries or [])
+        else:
+            raise TypeError, \
+                  "'libraries' (if supplied) must be a list of strings"
+
+        if library_dirs is None:
+            library_dirs = self.library_dirs
+        elif type (library_dirs) in (ListType, TupleType):
+            library_dirs = list (library_dirs) + (self.library_dirs or [])
+        else:
+            raise TypeError, \
+                  "'library_dirs' (if supplied) must be a list of strings"
+
+        if runtime_library_dirs is None:
+            runtime_library_dirs = self.runtime_library_dirs
+        elif type (runtime_library_dirs) in (ListType, TupleType):
+            runtime_library_dirs = (list (runtime_library_dirs) +
+                                    (self.runtime_library_dirs or []))
+        else:
+            raise TypeError, \
+                  "'runtime_library_dirs' (if supplied) " + \
+                  "must be a list of strings"
+
+        return (libraries, library_dirs, runtime_library_dirs)
+
+    # _fix_lib_args ()
+
+
+    def _need_link (self, objects, output_file):
+        """Return true if we need to relink the files listed in 'objects'
+        to recreate 'output_file'.
+        """
+        if self.force:
+            return 1
+        else:
+            if self.dry_run:
+                newer = newer_group (objects, output_file, missing='newer')
+            else:
+                newer = newer_group (objects, output_file)
+            return newer
+
+    # _need_link ()
+
+    def detect_language (self, sources):
+        """Detect the language of a given file, or list of files. Uses
+        language_map, and language_order to do the job.
+        """
+        if type(sources) is not ListType:
+            sources = [sources]
+        lang = None
+        index = len(self.language_order)
+        for source in sources:
+            base, ext = os.path.splitext(source)
+            extlang = self.language_map.get(ext)
+            try:
+                extindex = self.language_order.index(extlang)
+                if extindex < index:
+                    lang = extlang
+                    index = extindex
+            except ValueError:
+                pass
+        return lang
+
+    # detect_language ()
+
+    # -- Worker methods ------------------------------------------------
+    # (must be implemented by subclasses)
+
+    def preprocess (self,
+                    source,
+                    output_file=None,
+                    macros=None,
+                    include_dirs=None,
+                    extra_preargs=None,
+                    extra_postargs=None):
+        """Preprocess a single C/C++ source file, named in 'source'.
+        Output will be written to file named 'output_file', or stdout if
+        'output_file' not supplied.  'macros' is a list of macro
+        definitions as for 'compile()', which will augment the macros set
+        with 'define_macro()' and 'undefine_macro()'.  'include_dirs' is a
+        list of directory names that will be added to the default list.
+
+        Raises PreprocessError on failure.
+        """
+        pass
+
+    def compile(self, sources, output_dir=None, macros=None,
+                include_dirs=None, debug=0, extra_preargs=None,
+                extra_postargs=None, depends=None):
+        """Compile one or more source files.
+
+        'sources' must be a list of filenames, most likely C/C++
+        files, but in reality anything that can be handled by a
+        particular compiler and compiler class (eg. MSVCCompiler can
+        handle resource files in 'sources').  Return a list of object
+        filenames, one per source filename in 'sources'.  Depending on
+        the implementation, not all source files will necessarily be
+        compiled, but all corresponding object filenames will be
+        returned.
+
+        If 'output_dir' is given, object files will be put under it, while
+        retaining their original path component.  That is, "foo/bar.c"
+        normally compiles to "foo/bar.o" (for a Unix implementation); if
+        'output_dir' is "build", then it would compile to
+        "build/foo/bar.o".
+
+        'macros', if given, must be a list of macro definitions.  A macro
+        definition is either a (name, value) 2-tuple or a (name,) 1-tuple.
+        The former defines a macro; if the value is None, the macro is
+        defined without an explicit value.  The 1-tuple case undefines a
+        macro.  Later definitions/redefinitions/ undefinitions take
+        precedence.
+
+        'include_dirs', if given, must be a list of strings, the
+        directories to add to the default include file search path for this
+        compilation only.
+
+        'debug' is a boolean; if true, the compiler will be instructed to
+        output debug symbols in (or alongside) the object file(s).
+
+        'extra_preargs' and 'extra_postargs' are implementation- dependent.
+        On platforms that have the notion of a command-line (e.g. Unix,
+        DOS/Windows), they are most likely lists of strings: extra
+        command-line arguments to prepand/append to the compiler command
+        line.  On other platforms, consult the implementation class
+        documentation.  In any event, they are intended as an escape hatch
+        for those occasions when the abstract compiler framework doesn't
+        cut the mustard.
+
+        'depends', if given, is a list of filenames that all targets
+        depend on.  If a source file is older than any file in
+        depends, then the source file will be recompiled.  This
+        supports dependency tracking, but only at a coarse
+        granularity.
+
+        Raises CompileError on failure.
+        """
+
+        # A concrete compiler class can either override this method
+        # entirely or implement _compile().
+
+        macros, objects, extra_postargs, pp_opts, build = \
+                self._setup_compile(output_dir, macros, include_dirs, sources,
+                                    depends, extra_postargs)
+        cc_args = self._get_cc_args(pp_opts, debug, extra_preargs)
+
+        for obj in objects:
+            try:
+                src, ext = build[obj]
+            except KeyError:
+                continue
+            self._compile(obj, src, ext, cc_args, extra_postargs, pp_opts)
+
+        # Return *all* object filenames, not just the ones we just built.
+        return objects
+
+    def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts):
+        """Compile 'src' to product 'obj'."""
+
+        # A concrete compiler class that does not override compile()
+        # should implement _compile().
+        pass
+
+    def create_static_lib (self,
+                           objects,
+                           output_libname,
+                           output_dir=None,
+                           debug=0,
+                           target_lang=None):
+        """Link a bunch of stuff together to create a static library file.
+        The "bunch of stuff" consists of the list of object files supplied
+        as 'objects', the extra object files supplied to
+        'add_link_object()' and/or 'set_link_objects()', the libraries
+        supplied to 'add_library()' and/or 'set_libraries()', and the
+        libraries supplied as 'libraries' (if any).
+
+        'output_libname' should be a library name, not a filename; the
+        filename will be inferred from the library name.  'output_dir' is
+        the directory where the library file will be put.
+
+        'debug' is a boolean; if true, debugging information will be
+        included in the library (note that on most platforms, it is the
+        compile step where this matters: the 'debug' flag is included here
+        just for consistency).
+
+        'target_lang' is the target language for which the given objects
+        are being compiled. This allows specific linkage time treatment of
+        certain languages.
+
+        Raises LibError on failure.
+        """
+        pass
+
+
+    # values for target_desc parameter in link()
+    SHARED_OBJECT = "shared_object"
+    SHARED_LIBRARY = "shared_library"
+    EXECUTABLE = "executable"
+
+    def link (self,
+              target_desc,
+              objects,
+              output_filename,
+              output_dir=None,
+              libraries=None,
+              library_dirs=None,
+              runtime_library_dirs=None,
+              export_symbols=None,
+              debug=0,
+              extra_preargs=None,
+              extra_postargs=None,
+              build_temp=None,
+              target_lang=None):
+        """Link a bunch of stuff together to create an executable or
+        shared library file.
+
+        The "bunch of stuff" consists of the list of object files supplied
+        as 'objects'.  'output_filename' should be a filename.  If
+        'output_dir' is supplied, 'output_filename' is relative to it
+        (i.e. 'output_filename' can provide directory components if
+        needed).
+
+        'libraries' is a list of libraries to link against.  These are
+        library names, not filenames, since they're translated into
+        filenames in a platform-specific way (eg. "foo" becomes "libfoo.a"
+        on Unix and "foo.lib" on DOS/Windows).  However, they can include a
+        directory component, which means the linker will look in that
+        specific directory rather than searching all the normal locations.
+
+        'library_dirs', if supplied, should be a list of directories to
+        search for libraries that were specified as bare library names
+        (ie. no directory component).  These are on top of the system
+        default and those supplied to 'add_library_dir()' and/or
+        'set_library_dirs()'.  'runtime_library_dirs' is a list of
+        directories that will be embedded into the shared library and used
+        to search for other shared libraries that *it* depends on at
+        run-time.  (This may only be relevant on Unix.)
+
+        'export_symbols' is a list of symbols that the shared library will
+        export.  (This appears to be relevant only on Windows.)
+
+        'debug' is as for 'compile()' and 'create_static_lib()', with the
+        slight distinction that it actually matters on most platforms (as
+        opposed to 'create_static_lib()', which includes a 'debug' flag
+        mostly for form's sake).
+
+        'extra_preargs' and 'extra_postargs' are as for 'compile()' (except
+        of course that they supply command-line arguments for the
+        particular linker being used).
+
+        'target_lang' is the target language for which the given objects
+        are being compiled. This allows specific linkage time treatment of
+        certain languages.
+
+        Raises LinkError on failure.
+        """
+        raise NotImplementedError
+
+
+    # Old 'link_*()' methods, rewritten to use the new 'link()' method.
+
+    def link_shared_lib (self,
+                         objects,
+                         output_libname,
+                         output_dir=None,
+                         libraries=None,
+                         library_dirs=None,
+                         runtime_library_dirs=None,
+                         export_symbols=None,
+                         debug=0,
+                         extra_preargs=None,
+                         extra_postargs=None,
+                         build_temp=None,
+                         target_lang=None):
+        self.link(CCompiler.SHARED_LIBRARY, objects,
+                  self.library_filename(output_libname, lib_type='shared'),
+                  output_dir,
+                  libraries, library_dirs, runtime_library_dirs,
+                  export_symbols, debug,
+                  extra_preargs, extra_postargs, build_temp, target_lang)
+
+
+    def link_shared_object (self,
+                            objects,
+                            output_filename,
+                            output_dir=None,
+                            libraries=None,
+                            library_dirs=None,
+                            runtime_library_dirs=None,
+                            export_symbols=None,
+                            debug=0,
+                            extra_preargs=None,
+                            extra_postargs=None,
+                            build_temp=None,
+                            target_lang=None):
+        self.link(CCompiler.SHARED_OBJECT, objects,
+                  output_filename, output_dir,
+                  libraries, library_dirs, runtime_library_dirs,
+                  export_symbols, debug,
+                  extra_preargs, extra_postargs, build_temp, target_lang)
+
+
+    def link_executable (self,
+                         objects,
+                         output_progname,
+                         output_dir=None,
+                         libraries=None,
+                         library_dirs=None,
+                         runtime_library_dirs=None,
+                         debug=0,
+                         extra_preargs=None,
+                         extra_postargs=None,
+                         target_lang=None):
+        self.link(CCompiler.EXECUTABLE, objects,
+                  self.executable_filename(output_progname), output_dir,
+                  libraries, library_dirs, runtime_library_dirs, None,
+                  debug, extra_preargs, extra_postargs, None, target_lang)
+
+
+    # -- Miscellaneous methods -----------------------------------------
+    # These are all used by the 'gen_lib_options() function; there is
+    # no appropriate default implementation so subclasses should
+    # implement all of these.
+
+    def library_dir_option (self, dir):
+        """Return the compiler option to add 'dir' to the list of
+        directories searched for libraries.
+        """
+        raise NotImplementedError
+
+    def runtime_library_dir_option (self, dir):
+        """Return the compiler option to add 'dir' to the list of
+        directories searched for runtime libraries.
+        """
+        raise NotImplementedError
+
+    def library_option (self, lib):
+        """Return the compiler option to add 'dir' to the list of libraries
+        linked into the shared library or executable.
+        """
+        raise NotImplementedError
+
+    def has_function(self, funcname,
+                     includes=None,
+                     include_dirs=None,
+                     libraries=None,
+                     library_dirs=None):
+        """Return a boolean indicating whether funcname is supported on
+        the current platform.  The optional arguments can be used to
+        augment the compilation environment.
+        """
+
+        # this can't be included at module scope because it tries to
+        # import math which might not be available at that point - maybe
+        # the necessary logic should just be inlined?
+        import tempfile
+        if includes is None:
+            includes = []
+        if include_dirs is None:
+            include_dirs = []
+        if libraries is None:
+            libraries = []
+        if library_dirs is None:
+            library_dirs = []
+        fd, fname = tempfile.mkstemp(".c", funcname, text=True)
+        f = os.fdopen(fd, "w")
+        for incl in includes:
+            f.write("""#include "%s"\n""" % incl)
+        f.write("""\
+main (int argc, char **argv) {
+    %s();
+}
+""" % funcname)
+        f.close()
+        try:
+            objects = self.compile([fname], include_dirs=include_dirs)
+        except CompileError:
+            return False
+
+        try:
+            self.link_executable(objects, "a.out",
+                                 libraries=libraries,
+                                 library_dirs=library_dirs)
+        except (LinkError, TypeError):
+            return False
+        return True
+
+    def find_library_file (self, dirs, lib, debug=0):
+        """Search the specified list of directories for a static or shared
+        library file 'lib' and return the full path to that file.  If
+        'debug' true, look for a debugging version (if that makes sense on
+        the current platform).  Return None if 'lib' wasn't found in any of
+        the specified directories.
+        """
+        raise NotImplementedError
+
+    # -- Filename generation methods -----------------------------------
+
+    # The default implementation of the filename generating methods are
+    # prejudiced towards the Unix/DOS/Windows view of the world:
+    #   * object files are named by replacing the source file extension
+    #     (eg. .c/.cpp -> .o/.obj)
+    #   * library files (shared or static) are named by plugging the
+    #     library name and extension into a format string, eg.
+    #     "lib%s.%s" % (lib_name, ".a") for Unix static libraries
+    #   * executables are named by appending an extension (possibly
+    #     empty) to the program name: eg. progname + ".exe" for
+    #     Windows
+    #
+    # To reduce redundant code, these methods expect to find
+    # several attributes in the current object (presumably defined
+    # as class attributes):
+    #   * src_extensions -
+    #     list of C/C++ source file extensions, eg. ['.c', '.cpp']
+    #   * obj_extension -
+    #     object file extension, eg. '.o' or '.obj'
+    #   * static_lib_extension -
+    #     extension for static library files, eg. '.a' or '.lib'
+    #   * shared_lib_extension -
+    #     extension for shared library/object files, eg. '.so', '.dll'
+    #   * static_lib_format -
+    #     format string for generating static library filenames,
+    #     eg. 'lib%s.%s' or '%s.%s'
+    #   * shared_lib_format
+    #     format string for generating shared library filenames
+    #     (probably same as static_lib_format, since the extension
+    #     is one of the intended parameters to the format string)
+    #   * exe_extension -
+    #     extension for executable files, eg. '' or '.exe'
+
+    def object_filenames(self, source_filenames, strip_dir=0, output_dir=''):
+        if output_dir is None:
+            output_dir = ''
+        obj_names = []
+        for src_name in source_filenames:
+            base, ext = os.path.splitext(src_name)
+            base = os.path.splitdrive(base)[1] # Chop off the drive
+            base = base[os.path.isabs(base):]  # If abs, chop off leading /
+            if ext not in self.src_extensions:
+                raise UnknownFileError, \
+                      "unknown file type '%s' (from '%s')" % (ext, src_name)
+            if strip_dir:
+                base = os.path.basename(base)
+            obj_names.append(os.path.join(output_dir,
+                                          base + self.obj_extension))
+        return obj_names
+
+    def shared_object_filename(self, basename, strip_dir=0, output_dir=''):
+        assert output_dir is not None
+        if strip_dir:
+            basename = os.path.basename (basename)
+        return os.path.join(output_dir, basename + self.shared_lib_extension)
+
+    def executable_filename(self, basename, strip_dir=0, output_dir=''):
+        assert output_dir is not None
+        if strip_dir:
+            basename = os.path.basename (basename)
+        return os.path.join(output_dir, basename + (self.exe_extension or ''))
+
+    def library_filename(self, libname, lib_type='static',     # or 'shared'
+                         strip_dir=0, output_dir=''):
+        assert output_dir is not None
+        if lib_type not in ("static", "shared", "dylib"):
+            raise ValueError, "'lib_type' must be \"static\", \"shared\" or \"dylib\""
+        fmt = getattr(self, lib_type + "_lib_format")
+        ext = getattr(self, lib_type + "_lib_extension")
+
+        dir, base = os.path.split (libname)
+        filename = fmt % (base, ext)
+        if strip_dir:
+            dir = ''
+
+        return os.path.join(output_dir, dir, filename)
+
+
+    # -- Utility methods -----------------------------------------------
+
+    def announce (self, msg, level=1):
+        log.debug(msg)
+
+    def debug_print (self, msg):
+        from distutils.debug import DEBUG
+        if DEBUG:
+            print msg
+
+    def warn (self, msg):
+        sys.stderr.write ("warning: %s\n" % msg)
+
+    def execute (self, func, args, msg=None, level=1):
+        execute(func, args, msg, self.dry_run)
+
+    def spawn (self, cmd):
+        spawn (cmd, dry_run=self.dry_run)
+
+    def move_file (self, src, dst):
+        return move_file (src, dst, dry_run=self.dry_run)
+
+    def mkpath (self, name, mode=0777):
+        mkpath (name, mode, self.dry_run)
+
+
+# class CCompiler
+
+
+# Map a sys.platform/os.name ('posix', 'nt') to the default compiler
+# type for that platform. Keys are interpreted as re match
+# patterns. Order is important; platform mappings are preferred over
+# OS names.
+_default_compilers = (
+
+    # Platform string mappings
+
+    # on a cygwin built python we can use gcc like an ordinary UNIXish
+    # compiler
+    ('cygwin.*', 'unix'),
+    ('os2emx', 'emx'),
+
+    # OS name mappings
+    ('posix', 'unix'),
+    ('nt', 'msvc'),
+    ('mac', 'mwerks'),
+
+    )
+
+def get_default_compiler(osname=None, platform=None):
+
+    """ Determine the default compiler to use for the given platform.
+
+        osname should be one of the standard Python OS names (i.e. the
+        ones returned by os.name) and platform the common value
+        returned by sys.platform for the platform in question.
+
+        The default values are os.name and sys.platform in case the
+        parameters are not given.
+
+    """
+    if osname is None:
+        osname = os.name
+    if platform is None:
+        platform = sys.platform
+    for pattern, compiler in _default_compilers:
+        if re.match(pattern, platform) is not None or \
+           re.match(pattern, osname) is not None:
+            return compiler
+    # Default to Unix compiler
+    return 'unix'
+
+# Map compiler types to (module_name, class_name) pairs -- ie. where to
+# find the code that implements an interface to this compiler.  (The module
+# is assumed to be in the 'distutils' package.)
+compiler_class = { 'unix':    ('unixccompiler', 'UnixCCompiler',
+                               "standard UNIX-style compiler"),
+                   'msvc':    ('msvccompiler', 'MSVCCompiler',
+                               "Microsoft Visual C++"),
+                   'cygwin':  ('cygwinccompiler', 'CygwinCCompiler',
+                               "Cygwin port of GNU C Compiler for Win32"),
+                   'mingw32': ('cygwinccompiler', 'Mingw32CCompiler',
+                               "Mingw32 port of GNU C Compiler for Win32"),
+                   'bcpp':    ('bcppcompiler', 'BCPPCompiler',
+                               "Borland C++ Compiler"),
+                   'mwerks':  ('mwerkscompiler', 'MWerksCompiler',
+                               "MetroWerks CodeWarrior"),
+                   'emx':     ('emxccompiler', 'EMXCCompiler',
+                               "EMX port of GNU C Compiler for OS/2"),
+                 }
+
+def show_compilers():
+    """Print list of available compilers (used by the "--help-compiler"
+    options to "build", "build_ext", "build_clib").
+    """
+    # XXX this "knows" that the compiler option it's describing is
+    # "--compiler", which just happens to be the case for the three
+    # commands that use it.
+    from distutils.fancy_getopt import FancyGetopt
+    compilers = []
+    for compiler in compiler_class.keys():
+        compilers.append(("compiler="+compiler, None,
+                          compiler_class[compiler][2]))
+    compilers.sort()
+    pretty_printer = FancyGetopt(compilers)
+    pretty_printer.print_help("List of available compilers:")
+
+
+def new_compiler (plat=None,
+                  compiler=None,
+                  verbose=0,
+                  dry_run=0,
+                  force=0):
+    """Generate an instance of some CCompiler subclass for the supplied
+    platform/compiler combination.  'plat' defaults to 'os.name'
+    (eg. 'posix', 'nt'), and 'compiler' defaults to the default compiler
+    for that platform.  Currently only 'posix' and 'nt' are supported, and
+    the default compilers are "traditional Unix interface" (UnixCCompiler
+    class) and Visual C++ (MSVCCompiler class).  Note that it's perfectly
+    possible to ask for a Unix compiler object under Windows, and a
+    Microsoft compiler object under Unix -- if you supply a value for
+    'compiler', 'plat' is ignored.
+    """
+    if plat is None:
+        plat = os.name
+
+    try:
+        if compiler is None:
+            compiler = get_default_compiler(plat)
+
+        (module_name, class_name, long_description) = compiler_class[compiler]
+    except KeyError:
+        msg = "don't know how to compile C/C++ code on platform '%s'" % plat
+        if compiler is not None:
+            msg = msg + " with '%s' compiler" % compiler
+        raise DistutilsPlatformError, msg
+
+    try:
+        module_name = "distutils." + module_name
+        __import__ (module_name)
+        module = sys.modules[module_name]
+        klass = vars(module)[class_name]
+    except ImportError:
+        raise DistutilsModuleError, \
+              "can't compile C/C++ code: unable to load module '%s'" % \
+              module_name
+    except KeyError:
+        raise DistutilsModuleError, \
+              ("can't compile C/C++ code: unable to find class '%s' " +
+               "in module '%s'") % (class_name, module_name)
+
+    # XXX The None is necessary to preserve backwards compatibility
+    # with classes that expect verbose to be the first positional
+    # argument.
+    return klass (None, dry_run, force)
+
+
+def gen_preprocess_options (macros, include_dirs):
+    """Generate C pre-processor options (-D, -U, -I) as used by at least
+    two types of compilers: the typical Unix compiler and Visual C++.
+    'macros' is the usual thing, a list of 1- or 2-tuples, where (name,)
+    means undefine (-U) macro 'name', and (name,value) means define (-D)
+    macro 'name' to 'value'.  'include_dirs' is just a list of directory
+    names to be added to the header file search path (-I).  Returns a list
+    of command-line options suitable for either Unix compilers or Visual
+    C++.
+    """
+    # XXX it would be nice (mainly aesthetic, and so we don't generate
+    # stupid-looking command lines) to go over 'macros' and eliminate
+    # redundant definitions/undefinitions (ie. ensure that only the
+    # latest mention of a particular macro winds up on the command
+    # line).  I don't think it's essential, though, since most (all?)
+    # Unix C compilers only pay attention to the latest -D or -U
+    # mention of a macro on their command line.  Similar situation for
+    # 'include_dirs'.  I'm punting on both for now.  Anyways, weeding out
+    # redundancies like this should probably be the province of
+    # CCompiler, since the data structures used are inherited from it
+    # and therefore common to all CCompiler classes.
+
+    pp_opts = []
+    for macro in macros:
+
+        if not (type (macro) is TupleType and
+                1 <= len (macro) <= 2):
+            raise TypeError, \
+                  ("bad macro definition '%s': " +
+                   "each element of 'macros' list must be a 1- or 2-tuple") % \
+                  macro
+
+        if len (macro) == 1:        # undefine this macro
+            pp_opts.append ("-U%s" % macro[0])
+        elif len (macro) == 2:
+            if macro[1] is None:    # define with no explicit value
+                pp_opts.append ("-D%s" % macro[0])
+            else:
+                # XXX *don't* need to be clever about quoting the
+                # macro value here, because we're going to avoid the
+                # shell at all costs when we spawn the command!
+                pp_opts.append ("-D%s=%s" % macro)
+
+    for dir in include_dirs:
+        pp_opts.append ("-I%s" % dir)
+
+    return pp_opts
+
+# gen_preprocess_options ()
+
+
+def gen_lib_options (compiler, library_dirs, runtime_library_dirs, libraries):
+    """Generate linker options for searching library directories and
+    linking with specific libraries.  'libraries' and 'library_dirs' are,
+    respectively, lists of library names (not filenames!) and search
+    directories.  Returns a list of command-line options suitable for use
+    with some compiler (depending on the two format strings passed in).
+    """
+    lib_opts = []
+
+    for dir in library_dirs:
+        lib_opts.append (compiler.library_dir_option (dir))
+
+    for dir in runtime_library_dirs:
+        opt = compiler.runtime_library_dir_option (dir)
+        if type(opt) is ListType:
+            lib_opts = lib_opts + opt
+        else:
+            lib_opts.append (opt)
+
+    # XXX it's important that we *not* remove redundant library mentions!
+    # sometimes you really do have to say "-lfoo -lbar -lfoo" in order to
+    # resolve all symbols.  I just hope we never have to say "-lfoo obj.o
+    # -lbar" to get things to work -- that's certainly a possibility, but a
+    # pretty nasty way to arrange your C code.
+
+    for lib in libraries:
+        (lib_dir, lib_name) = os.path.split (lib)
+        if lib_dir:
+            lib_file = compiler.find_library_file ([lib_dir], lib_name)
+            if lib_file:
+                lib_opts.append (lib_file)
+            else:
+                compiler.warn ("no library file corresponding to "
+                               "'%s' found (skipping)" % lib)
+        else:
+            lib_opts.append (compiler.library_option (lib))
+
+    return lib_opts
+
+# gen_lib_options ()

Added: vendor/Python/current/Lib/distutils/cmd.py
===================================================================
--- vendor/Python/current/Lib/distutils/cmd.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/cmd.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,478 @@
+"""distutils.cmd
+
+Provides the Command class, the base class for the command classes
+in the distutils.command package.
+"""
+
+# This module should be kept compatible with Python 2.1.
+
+__revision__ = "$Id: cmd.py 37828 2004-11-10 22:23:15Z loewis $"
+
+import sys, os, string, re
+from types import *
+from distutils.errors import *
+from distutils import util, dir_util, file_util, archive_util, dep_util
+from distutils import log
+
+class Command:
+    """Abstract base class for defining command classes, the "worker bees"
+    of the Distutils.  A useful analogy for command classes is to think of
+    them as subroutines with local variables called "options".  The options
+    are "declared" in 'initialize_options()' and "defined" (given their
+    final values, aka "finalized") in 'finalize_options()', both of which
+    must be defined by every command class.  The distinction between the
+    two is necessary because option values might come from the outside
+    world (command line, config file, ...), and any options dependent on
+    other options must be computed *after* these outside influences have
+    been processed -- hence 'finalize_options()'.  The "body" of the
+    subroutine, where it does all its work based on the values of its
+    options, is the 'run()' method, which must also be implemented by every
+    command class.
+    """
+
+    # 'sub_commands' formalizes the notion of a "family" of commands,
+    # eg. "install" as the parent with sub-commands "install_lib",
+    # "install_headers", etc.  The parent of a family of commands
+    # defines 'sub_commands' as a class attribute; it's a list of
+    #    (command_name : string, predicate : unbound_method | string | None)
+    # tuples, where 'predicate' is a method of the parent command that
+    # determines whether the corresponding command is applicable in the
+    # current situation.  (Eg. we "install_headers" is only applicable if
+    # we have any C header files to install.)  If 'predicate' is None,
+    # that command is always applicable.
+    #
+    # 'sub_commands' is usually defined at the *end* of a class, because
+    # predicates can be unbound methods, so they must already have been
+    # defined.  The canonical example is the "install" command.
+    sub_commands = []
+
+
+    # -- Creation/initialization methods -------------------------------
+
+    def __init__ (self, dist):
+        """Create and initialize a new Command object.  Most importantly,
+        invokes the 'initialize_options()' method, which is the real
+        initializer and depends on the actual command being
+        instantiated.
+        """
+        # late import because of mutual dependence between these classes
+        from distutils.dist import Distribution
+
+        if not isinstance(dist, Distribution):
+            raise TypeError, "dist must be a Distribution instance"
+        if self.__class__ is Command:
+            raise RuntimeError, "Command is an abstract class"
+
+        self.distribution = dist
+        self.initialize_options()
+
+        # Per-command versions of the global flags, so that the user can
+        # customize Distutils' behaviour command-by-command and let some
+        # commands fall back on the Distribution's behaviour.  None means
+        # "not defined, check self.distribution's copy", while 0 or 1 mean
+        # false and true (duh).  Note that this means figuring out the real
+        # value of each flag is a touch complicated -- hence "self._dry_run"
+        # will be handled by __getattr__, below.
+        # XXX This needs to be fixed.
+        self._dry_run = None
+
+        # verbose is largely ignored, but needs to be set for
+        # backwards compatibility (I think)?
+        self.verbose = dist.verbose
+
+        # Some commands define a 'self.force' option to ignore file
+        # timestamps, but methods defined *here* assume that
+        # 'self.force' exists for all commands.  So define it here
+        # just to be safe.
+        self.force = None
+
+        # The 'help' flag is just used for command-line parsing, so
+        # none of that complicated bureaucracy is needed.
+        self.help = 0
+
+        # 'finalized' records whether or not 'finalize_options()' has been
+        # called.  'finalize_options()' itself should not pay attention to
+        # this flag: it is the business of 'ensure_finalized()', which
+        # always calls 'finalize_options()', to respect/update it.
+        self.finalized = 0
+
+    # __init__ ()
+
+
+    # XXX A more explicit way to customize dry_run would be better.
+
+    def __getattr__ (self, attr):
+        if attr == 'dry_run':
+            myval = getattr(self, "_" + attr)
+            if myval is None:
+                return getattr(self.distribution, attr)
+            else:
+                return myval
+        else:
+            raise AttributeError, attr
+
+
+    def ensure_finalized (self):
+        if not self.finalized:
+            self.finalize_options()
+        self.finalized = 1
+
+
+    # Subclasses must define:
+    #   initialize_options()
+    #     provide default values for all options; may be customized by
+    #     setup script, by options from config file(s), or by command-line
+    #     options
+    #   finalize_options()
+    #     decide on the final values for all options; this is called
+    #     after all possible intervention from the outside world
+    #     (command-line, option file, etc.) has been processed
+    #   run()
+    #     run the command: do whatever it is we're here to do,
+    #     controlled by the command's various option values
+
+    def initialize_options (self):
+        """Set default values for all the options that this command
+        supports.  Note that these defaults may be overridden by other
+        commands, by the setup script, by config files, or by the
+        command-line.  Thus, this is not the place to code dependencies
+        between options; generally, 'initialize_options()' implementations
+        are just a bunch of "self.foo = None" assignments.
+
+        This method must be implemented by all command classes.
+        """
+        raise RuntimeError, \
+              "abstract method -- subclass %s must override" % self.__class__
+
+    def finalize_options (self):
+        """Set final values for all the options that this command supports.
+        This is always called as late as possible, ie.  after any option
+        assignments from the command-line or from other commands have been
+        done.  Thus, this is the place to code option dependencies: if
+        'foo' depends on 'bar', then it is safe to set 'foo' from 'bar' as
+        long as 'foo' still has the same value it was assigned in
+        'initialize_options()'.
+
+        This method must be implemented by all command classes.
+        """
+        raise RuntimeError, \
+              "abstract method -- subclass %s must override" % self.__class__
+
+
+    def dump_options (self, header=None, indent=""):
+        from distutils.fancy_getopt import longopt_xlate
+        if header is None:
+            header = "command options for '%s':" % self.get_command_name()
+        print indent + header
+        indent = indent + "  "
+        for (option, _, _) in self.user_options:
+            option = string.translate(option, longopt_xlate)
+            if option[-1] == "=":
+                option = option[:-1]
+            value = getattr(self, option)
+            print indent + "%s = %s" % (option, value)
+
+
+    def run (self):
+        """A command's raison d'etre: carry out the action it exists to
+        perform, controlled by the options initialized in
+        'initialize_options()', customized by other commands, the setup
+        script, the command-line, and config files, and finalized in
+        'finalize_options()'.  All terminal output and filesystem
+        interaction should be done by 'run()'.
+
+        This method must be implemented by all command classes.
+        """
+
+        raise RuntimeError, \
+              "abstract method -- subclass %s must override" % self.__class__
+
+    def announce (self, msg, level=1):
+        """If the current verbosity level is of greater than or equal to
+        'level' print 'msg' to stdout.
+        """
+        log.log(level, msg)
+
+    def debug_print (self, msg):
+        """Print 'msg' to stdout if the global DEBUG (taken from the
+        DISTUTILS_DEBUG environment variable) flag is true.
+        """
+        from distutils.debug import DEBUG
+        if DEBUG:
+            print msg
+            sys.stdout.flush()
+
+
+
+    # -- Option validation methods -------------------------------------
+    # (these are very handy in writing the 'finalize_options()' method)
+    #
+    # NB. the general philosophy here is to ensure that a particular option
+    # value meets certain type and value constraints.  If not, we try to
+    # force it into conformance (eg. if we expect a list but have a string,
+    # split the string on comma and/or whitespace).  If we can't force the
+    # option into conformance, raise DistutilsOptionError.  Thus, command
+    # classes need do nothing more than (eg.)
+    #   self.ensure_string_list('foo')
+    # and they can be guaranteed that thereafter, self.foo will be
+    # a list of strings.
+
+    def _ensure_stringlike (self, option, what, default=None):
+        val = getattr(self, option)
+        if val is None:
+            setattr(self, option, default)
+            return default
+        elif type(val) is not StringType:
+            raise DistutilsOptionError, \
+                  "'%s' must be a %s (got `%s`)" % (option, what, val)
+        return val
+
+    def ensure_string (self, option, default=None):
+        """Ensure that 'option' is a string; if not defined, set it to
+        'default'.
+        """
+        self._ensure_stringlike(option, "string", default)
+
+    def ensure_string_list (self, option):
+        """Ensure that 'option' is a list of strings.  If 'option' is
+        currently a string, we split it either on /,\s*/ or /\s+/, so
+        "foo bar baz", "foo,bar,baz", and "foo,   bar baz" all become
+        ["foo", "bar", "baz"].
+        """
+        val = getattr(self, option)
+        if val is None:
+            return
+        elif type(val) is StringType:
+            setattr(self, option, re.split(r',\s*|\s+', val))
+        else:
+            if type(val) is ListType:
+                types = map(type, val)
+                ok = (types == [StringType] * len(val))
+            else:
+                ok = 0
+
+            if not ok:
+                raise DistutilsOptionError, \
+                      "'%s' must be a list of strings (got %r)" % \
+                      (option, val)
+
+    def _ensure_tested_string (self, option, tester,
+                               what, error_fmt, default=None):
+        val = self._ensure_stringlike(option, what, default)
+        if val is not None and not tester(val):
+            raise DistutilsOptionError, \
+                  ("error in '%s' option: " + error_fmt) % (option, val)
+
+    def ensure_filename (self, option):
+        """Ensure that 'option' is the name of an existing file."""
+        self._ensure_tested_string(option, os.path.isfile,
+                                   "filename",
+                                   "'%s' does not exist or is not a file")
+
+    def ensure_dirname (self, option):
+        self._ensure_tested_string(option, os.path.isdir,
+                                   "directory name",
+                                   "'%s' does not exist or is not a directory")
+
+
+    # -- Convenience methods for commands ------------------------------
+
+    def get_command_name (self):
+        if hasattr(self, 'command_name'):
+            return self.command_name
+        else:
+            return self.__class__.__name__
+
+
+    def set_undefined_options (self, src_cmd, *option_pairs):
+        """Set the values of any "undefined" options from corresponding
+        option values in some other command object.  "Undefined" here means
+        "is None", which is the convention used to indicate that an option
+        has not been changed between 'initialize_options()' and
+        'finalize_options()'.  Usually called from 'finalize_options()' for
+        options that depend on some other command rather than another
+        option of the same command.  'src_cmd' is the other command from
+        which option values will be taken (a command object will be created
+        for it if necessary); the remaining arguments are
+        '(src_option,dst_option)' tuples which mean "take the value of
+        'src_option' in the 'src_cmd' command object, and copy it to
+        'dst_option' in the current command object".
+        """
+
+        # Option_pairs: list of (src_option, dst_option) tuples
+
+        src_cmd_obj = self.distribution.get_command_obj(src_cmd)
+        src_cmd_obj.ensure_finalized()
+        for (src_option, dst_option) in option_pairs:
+            if getattr(self, dst_option) is None:
+                setattr(self, dst_option,
+                        getattr(src_cmd_obj, src_option))
+
+
+    def get_finalized_command (self, command, create=1):
+        """Wrapper around Distribution's 'get_command_obj()' method: find
+        (create if necessary and 'create' is true) the command object for
+        'command', call its 'ensure_finalized()' method, and return the
+        finalized command object.
+        """
+        cmd_obj = self.distribution.get_command_obj(command, create)
+        cmd_obj.ensure_finalized()
+        return cmd_obj
+
+    # XXX rename to 'get_reinitialized_command()'? (should do the
+    # same in dist.py, if so)
+    def reinitialize_command (self, command, reinit_subcommands=0):
+        return self.distribution.reinitialize_command(
+            command, reinit_subcommands)
+
+    def run_command (self, command):
+        """Run some other command: uses the 'run_command()' method of
+        Distribution, which creates and finalizes the command object if
+        necessary and then invokes its 'run()' method.
+        """
+        self.distribution.run_command(command)
+
+
+    def get_sub_commands (self):
+        """Determine the sub-commands that are relevant in the current
+        distribution (ie., that need to be run).  This is based on the
+        'sub_commands' class attribute: each tuple in that list may include
+        a method that we call to determine if the subcommand needs to be
+        run for the current distribution.  Return a list of command names.
+        """
+        commands = []
+        for (cmd_name, method) in self.sub_commands:
+            if method is None or method(self):
+                commands.append(cmd_name)
+        return commands
+
+
+    # -- External world manipulation -----------------------------------
+
+    def warn (self, msg):
+        sys.stderr.write("warning: %s: %s\n" %
+                         (self.get_command_name(), msg))
+
+
+    def execute (self, func, args, msg=None, level=1):
+        util.execute(func, args, msg, dry_run=self.dry_run)
+
+
+    def mkpath (self, name, mode=0777):
+        dir_util.mkpath(name, mode, dry_run=self.dry_run)
+
+
+    def copy_file (self, infile, outfile,
+                   preserve_mode=1, preserve_times=1, link=None, level=1):
+        """Copy a file respecting verbose, dry-run and force flags.  (The
+        former two default to whatever is in the Distribution object, and
+        the latter defaults to false for commands that don't define it.)"""
+
+        return file_util.copy_file(
+            infile, outfile,
+            preserve_mode, preserve_times,
+            not self.force,
+            link,
+            dry_run=self.dry_run)
+
+
+    def copy_tree (self, infile, outfile,
+                   preserve_mode=1, preserve_times=1, preserve_symlinks=0,
+                   level=1):
+        """Copy an entire directory tree respecting verbose, dry-run,
+        and force flags.
+        """
+        return dir_util.copy_tree(
+            infile, outfile,
+            preserve_mode,preserve_times,preserve_symlinks,
+            not self.force,
+            dry_run=self.dry_run)
+
+    def move_file (self, src, dst, level=1):
+        """Move a file respectin dry-run flag."""
+        return file_util.move_file(src, dst, dry_run = self.dry_run)
+
+    def spawn (self, cmd, search_path=1, level=1):
+        """Spawn an external command respecting dry-run flag."""
+        from distutils.spawn import spawn
+        spawn(cmd, search_path, dry_run= self.dry_run)
+
+    def make_archive (self, base_name, format,
+                      root_dir=None, base_dir=None):
+        return archive_util.make_archive(
+            base_name, format, root_dir, base_dir, dry_run=self.dry_run)
+
+
+    def make_file (self, infiles, outfile, func, args,
+                   exec_msg=None, skip_msg=None, level=1):
+        """Special case of 'execute()' for operations that process one or
+        more input files and generate one output file.  Works just like
+        'execute()', except the operation is skipped and a different
+        message printed if 'outfile' already exists and is newer than all
+        files listed in 'infiles'.  If the command defined 'self.force',
+        and it is true, then the command is unconditionally run -- does no
+        timestamp checks.
+        """
+        if exec_msg is None:
+            exec_msg = "generating %s from %s" % \
+                       (outfile, string.join(infiles, ', '))
+        if skip_msg is None:
+            skip_msg = "skipping %s (inputs unchanged)" % outfile
+
+
+        # Allow 'infiles' to be a single string
+        if type(infiles) is StringType:
+            infiles = (infiles,)
+        elif type(infiles) not in (ListType, TupleType):
+            raise TypeError, \
+                  "'infiles' must be a string, or a list or tuple of strings"
+
+        # If 'outfile' must be regenerated (either because it doesn't
+        # exist, is out-of-date, or the 'force' flag is true) then
+        # perform the action that presumably regenerates it
+        if self.force or dep_util.newer_group (infiles, outfile):
+            self.execute(func, args, exec_msg, level)
+
+        # Otherwise, print the "skip" message
+        else:
+            log.debug(skip_msg)
+
+    # make_file ()
+
+# class Command
+
+
+# XXX 'install_misc' class not currently used -- it was the base class for
+# both 'install_scripts' and 'install_data', but they outgrew it.  It might
+# still be useful for 'install_headers', though, so I'm keeping it around
+# for the time being.
+
+class install_misc (Command):
+    """Common base class for installing some files in a subdirectory.
+    Currently used by install_data and install_scripts.
+    """
+
+    user_options = [('install-dir=', 'd', "directory to install the files to")]
+
+    def initialize_options (self):
+        self.install_dir = None
+        self.outfiles = []
+
+    def _install_dir_from (self, dirname):
+        self.set_undefined_options('install', (dirname, 'install_dir'))
+
+    def _copy_files (self, filelist):
+        self.outfiles = []
+        if not filelist:
+            return
+        self.mkpath(self.install_dir)
+        for f in filelist:
+            self.copy_file(f, self.install_dir)
+            self.outfiles.append(os.path.join(self.install_dir, f))
+
+    def get_outputs (self):
+        return self.outfiles
+
+
+if __name__ == "__main__":
+    print "ok"

Added: vendor/Python/current/Lib/distutils/command/__init__.py
===================================================================
--- vendor/Python/current/Lib/distutils/command/__init__.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/command/__init__.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,33 @@
+"""distutils.command
+
+Package containing implementation of all the standard Distutils
+commands."""
+
+# This module should be kept compatible with Python 2.1.
+
+__revision__ = "$Id: __init__.py 37828 2004-11-10 22:23:15Z loewis $"
+
+__all__ = ['build',
+           'build_py',
+           'build_ext',
+           'build_clib',
+           'build_scripts',
+           'clean',
+           'install',
+           'install_lib',
+           'install_headers',
+           'install_scripts',
+           'install_data',
+           'sdist',
+           'register',
+           'bdist',
+           'bdist_dumb',
+           'bdist_rpm',
+           'bdist_wininst',
+           # These two are reserved for future use:
+           #'bdist_sdux',
+           #'bdist_pkgtool',
+           # Note:
+           # bdist_packager is not included because it only provides
+           # an abstract base class
+          ]

Added: vendor/Python/current/Lib/distutils/command/bdist.py
===================================================================
--- vendor/Python/current/Lib/distutils/command/bdist.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/command/bdist.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,150 @@
+"""distutils.command.bdist
+
+Implements the Distutils 'bdist' command (create a built [binary]
+distribution)."""
+
+# This module should be kept compatible with Python 2.1.
+
+__revision__ = "$Id: bdist.py 37828 2004-11-10 22:23:15Z loewis $"
+
+import os, string
+from types import *
+from distutils.core import Command
+from distutils.errors import *
+from distutils.util import get_platform
+
+
+def show_formats ():
+    """Print list of available formats (arguments to "--format" option).
+    """
+    from distutils.fancy_getopt import FancyGetopt
+    formats=[]
+    for format in bdist.format_commands:
+        formats.append(("formats=" + format, None,
+                        bdist.format_command[format][1]))
+    pretty_printer = FancyGetopt(formats)
+    pretty_printer.print_help("List of available distribution formats:")
+
+
+class bdist (Command):
+
+    description = "create a built (binary) distribution"
+
+    user_options = [('bdist-base=', 'b',
+                     "temporary directory for creating built distributions"),
+                    ('plat-name=', 'p',
+                     "platform name to embed in generated filenames "
+                     "(default: %s)" % get_platform()),
+                    ('formats=', None,
+                     "formats for distribution (comma-separated list)"),
+                    ('dist-dir=', 'd',
+                     "directory to put final built distributions in "
+                     "[default: dist]"),
+                    ('skip-build', None,
+                     "skip rebuilding everything (for testing/debugging)"),
+                   ]
+
+    boolean_options = ['skip-build']
+
+    help_options = [
+        ('help-formats', None,
+         "lists available distribution formats", show_formats),
+        ]
+
+    # The following commands do not take a format option from bdist
+    no_format_option = ('bdist_rpm',
+                        #'bdist_sdux', 'bdist_pkgtool'
+                        )
+
+    # This won't do in reality: will need to distinguish RPM-ish Linux,
+    # Debian-ish Linux, Solaris, FreeBSD, ..., Windows, Mac OS.
+    default_format = { 'posix': 'gztar',
+                       'nt': 'zip',
+                       'os2': 'zip', }
+
+    # Establish the preferred order (for the --help-formats option).
+    format_commands = ['rpm', 'gztar', 'bztar', 'ztar', 'tar',
+                       'wininst', 'zip',
+                       #'pkgtool', 'sdux'
+                       ]
+
+    # And the real information.
+    format_command = { 'rpm':   ('bdist_rpm',  "RPM distribution"),
+                       'zip':   ('bdist_dumb', "ZIP file"),
+                       'gztar': ('bdist_dumb', "gzip'ed tar file"),
+                       'bztar': ('bdist_dumb', "bzip2'ed tar file"),
+                       'ztar':  ('bdist_dumb', "compressed tar file"),
+                       'tar':   ('bdist_dumb', "tar file"),
+                       'wininst': ('bdist_wininst',
+                                   "Windows executable installer"),
+                       'zip':   ('bdist_dumb', "ZIP file"),
+                       #'pkgtool': ('bdist_pkgtool',
+                       #            "Solaris pkgtool distribution"),
+                       #'sdux':  ('bdist_sdux', "HP-UX swinstall depot"),
+                      }
+
+
+    def initialize_options (self):
+        self.bdist_base = None
+        self.plat_name = None
+        self.formats = None
+        self.dist_dir = None
+        self.skip_build = 0
+
+    # initialize_options()
+
+
+    def finalize_options (self):
+        # have to finalize 'plat_name' before 'bdist_base'
+        if self.plat_name is None:
+            self.plat_name = get_platform()
+
+        # 'bdist_base' -- parent of per-built-distribution-format
+        # temporary directories (eg. we'll probably have
+        # "build/bdist.<plat>/dumb", "build/bdist.<plat>/rpm", etc.)
+        if self.bdist_base is None:
+            build_base = self.get_finalized_command('build').build_base
+            self.bdist_base = os.path.join(build_base,
+                                           'bdist.' + self.plat_name)
+
+        self.ensure_string_list('formats')
+        if self.formats is None:
+            try:
+                self.formats = [self.default_format[os.name]]
+            except KeyError:
+                raise DistutilsPlatformError, \
+                      "don't know how to create built distributions " + \
+                      "on platform %s" % os.name
+
+        if self.dist_dir is None:
+            self.dist_dir = "dist"
+
+    # finalize_options()
+
+
+    def run (self):
+
+        # Figure out which sub-commands we need to run.
+        commands = []
+        for format in self.formats:
+            try:
+                commands.append(self.format_command[format][0])
+            except KeyError:
+                raise DistutilsOptionError, "invalid format '%s'" % format
+
+        # Reinitialize and run each command.
+        for i in range(len(self.formats)):
+            cmd_name = commands[i]
+            sub_cmd = self.reinitialize_command(cmd_name)
+            if cmd_name not in self.no_format_option:
+                sub_cmd.format = self.formats[i]
+
+            # If we're going to need to run this command again, tell it to
+            # keep its temporary files around so subsequent runs go faster.
+            if cmd_name in commands[i+1:]:
+                sub_cmd.keep_temp = 1
+            self.run_command(cmd_name)
+
+    # run()
+
+# class bdist

Added: vendor/Python/current/Lib/distutils/command/bdist_dumb.py
===================================================================
--- vendor/Python/current/Lib/distutils/command/bdist_dumb.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/command/bdist_dumb.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,135 @@
+"""distutils.command.bdist_dumb
+
+Implements the Distutils 'bdist_dumb' command (create a "dumb" built
+distribution -- i.e., just an archive to be unpacked under $prefix or
+$exec_prefix)."""
+
+# This module should be kept compatible with Python 2.1.
+
+__revision__ = "$Id: bdist_dumb.py 38697 2005-03-23 18:54:36Z loewis $"
+
+import os
+from distutils.core import Command
+from distutils.util import get_platform
+from distutils.dir_util import create_tree, remove_tree, ensure_relative
+from distutils.errors import *
+from distutils.sysconfig import get_python_version
+from distutils import log
+
+class bdist_dumb (Command):
+
+    description = "create a \"dumb\" built distribution"
+
+    user_options = [('bdist-dir=', 'd',
+                     "temporary directory for creating the distribution"),
+                    ('plat-name=', 'p',
+                     "platform name to embed in generated filenames "
+                     "(default: %s)" % get_platform()),
+                    ('format=', 'f',
+                     "archive format to create (tar, ztar, gztar, zip)"),
+                    ('keep-temp', 'k',
+                     "keep the pseudo-installation tree around after " +
+                     "creating the distribution archive"),
+                    ('dist-dir=', 'd',
+                     "directory to put final built distributions in"),
+                    ('skip-build', None,
+                     "skip rebuilding everything (for testing/debugging)"),
+                    ('relative', None,
+                     "build the archive using relative paths"
+                     "(default: false)"),
+                   ]
+
+    boolean_options = ['keep-temp', 'skip-build', 'relative']
+
+    default_format = { 'posix': 'gztar',
+                       'nt': 'zip',
+                       'os2': 'zip' }
+
+
+    def initialize_options (self):
+        self.bdist_dir = None
+        self.plat_name = None
+        self.format = None
+        self.keep_temp = 0
+        self.dist_dir = None
+        self.skip_build = 0
+        self.relative = 0
+
+    # initialize_options()
+
+
+    def finalize_options (self):
+
+        if self.bdist_dir is None:
+            bdist_base = self.get_finalized_command('bdist').bdist_base
+            self.bdist_dir = os.path.join(bdist_base, 'dumb')
+
+        if self.format is None:
+            try:
+                self.format = self.default_format[os.name]
+            except KeyError:
+                raise DistutilsPlatformError, \
+                      ("don't know how to create dumb built distributions " +
+                       "on platform %s") % os.name
+
+        self.set_undefined_options('bdist',
+                                   ('dist_dir', 'dist_dir'),
+                                   ('plat_name', 'plat_name'))
+
+    # finalize_options()
+
+
+    def run (self):
+
+        if not self.skip_build:
+            self.run_command('build')
+
+        install = self.reinitialize_command('install', reinit_subcommands=1)
+        install.root = self.bdist_dir
+        install.skip_build = self.skip_build
+        install.warn_dir = 0
+
+        log.info("installing to %s" % self.bdist_dir)
+        self.run_command('install')
+
+        # And make an archive relative to the root of the
+        # pseudo-installation tree.
+        archive_basename = "%s.%s" % (self.distribution.get_fullname(),
+                                      self.plat_name)
+
+        # OS/2 objects to any ":" characters in a filename (such as when
+        # a timestamp is used in a version) so change them to hyphens.
+        if os.name == "os2":
+            archive_basename = archive_basename.replace(":", "-")
+
+        pseudoinstall_root = os.path.join(self.dist_dir, archive_basename)
+        if not self.relative:
+            archive_root = self.bdist_dir
+        else:
+            if (self.distribution.has_ext_modules() and
+                (install.install_base != install.install_platbase)):
+                raise DistutilsPlatformError, \
+                      ("can't make a dumb built distribution where "
+                       "base and platbase are different (%s, %s)"
+                       % (repr(install.install_base),
+                          repr(install.install_platbase)))
+            else:
+                archive_root = os.path.join(self.bdist_dir,
+                                   ensure_relative(install.install_base))
+
+        # Make the archive
+        filename = self.make_archive(pseudoinstall_root,
+                                     self.format, root_dir=archive_root)
+        if self.distribution.has_ext_modules():
+            pyversion = get_python_version()
+        else:
+            pyversion = 'any'
+        self.distribution.dist_files.append(('bdist_dumb', pyversion,
+                                             filename))
+
+        if not self.keep_temp:
+            remove_tree(self.bdist_dir, dry_run=self.dry_run)
+
+    # run()
+
+# class bdist_dumb

Added: vendor/Python/current/Lib/distutils/command/bdist_msi.py
===================================================================
--- vendor/Python/current/Lib/distutils/command/bdist_msi.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/command/bdist_msi.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,639 @@
+# -*- coding: iso-8859-1 -*-
+# Copyright (C) 2005, 2006 Martin v. Löwis
+# Licensed to PSF under a Contributor Agreement.
+# The bdist_wininst command proper
+# based on bdist_wininst
+"""
+Implements the bdist_msi command.
+"""
+
+import sys, os, string
+from distutils.core import Command
+from distutils.util import get_platform
+from distutils.dir_util import remove_tree
+from distutils.sysconfig import get_python_version
+from distutils.version import StrictVersion
+from distutils.errors import DistutilsOptionError
+from distutils import log
+import msilib
+from msilib import schema, sequence, text
+from msilib import Directory, Feature, Dialog, add_data
+
+class PyDialog(Dialog):
+    """Dialog class with a fixed layout: controls at the top, then a ruler,
+    then a list of buttons: back, next, cancel. Optionally a bitmap at the
+    left."""
+    def __init__(self, *args, **kw):
+        """Dialog(database, name, x, y, w, h, attributes, title, first,
+        default, cancel, bitmap=true)"""
+        Dialog.__init__(self, *args)
+        ruler = self.h - 36
+        bmwidth = 152*ruler/328
+        #if kw.get("bitmap", True):
+        #    self.bitmap("Bitmap", 0, 0, bmwidth, ruler, "PythonWin")
+        self.line("BottomLine", 0, ruler, self.w, 0)
+
+    def title(self, title):
+        "Set the title text of the dialog at the top."
+        # name, x, y, w, h, flags=Visible|Enabled|Transparent|NoPrefix,
+        # text, in VerdanaBold10
+        self.text("Title", 15, 10, 320, 60, 0x30003,
+                  r"{\VerdanaBold10}%s" % title)
+
+    def back(self, title, next, name = "Back", active = 1):
+        """Add a back button with a given title, the tab-next button,
+        its name in the Control table, possibly initially disabled.
+
+        Return the button, so that events can be associated"""
+        if active:
+            flags = 3 # Visible|Enabled
+        else:
+            flags = 1 # Visible
+        return self.pushbutton(name, 180, self.h-27 , 56, 17, flags, title, next)
+
+    def cancel(self, title, next, name = "Cancel", active = 1):
+        """Add a cancel button with a given title, the tab-next button,
+        its name in the Control table, possibly initially disabled.
+
+        Return the button, so that events can be associated"""
+        if active:
+            flags = 3 # Visible|Enabled
+        else:
+            flags = 1 # Visible
+        return self.pushbutton(name, 304, self.h-27, 56, 17, flags, title, next)
+
+    def next(self, title, next, name = "Next", active = 1):
+        """Add a Next button with a given title, the tab-next button,
+        its name in the Control table, possibly initially disabled.
+
+        Return the button, so that events can be associated"""
+        if active:
+            flags = 3 # Visible|Enabled
+        else:
+            flags = 1 # Visible
+        return self.pushbutton(name, 236, self.h-27, 56, 17, flags, title, next)
+
+    def xbutton(self, name, title, next, xpos):
+        """Add a button with a given title, the tab-next button,
+        its name in the Control table, giving its x position; the
+        y-position is aligned with the other buttons.
+
+        Return the button, so that events can be associated"""
+        return self.pushbutton(name, int(self.w*xpos - 28), self.h-27, 56, 17, 3, title, next)
+
+class bdist_msi (Command):
+
+    description = "create a Microsoft Installer (.msi) binary distribution"
+
+    user_options = [('bdist-dir=', None,
+                     "temporary directory for creating the distribution"),
+                    ('keep-temp', 'k',
+                     "keep the pseudo-installation tree around after " +
+                     "creating the distribution archive"),
+                    ('target-version=', None,
+                     "require a specific python version" +
+                     " on the target system"),
+                    ('no-target-compile', 'c',
+                     "do not compile .py to .pyc on the target system"),
+                    ('no-target-optimize', 'o',
+                     "do not compile .py to .pyo (optimized)"
+                     "on the target system"),
+                    ('dist-dir=', 'd',
+                     "directory to put final built distributions in"),
+                    ('skip-build', None,
+                     "skip rebuilding everything (for testing/debugging)"),
+                    ('install-script=', None,
+                     "basename of installation script to be run after"
+                     "installation or before deinstallation"),
+                    ('pre-install-script=', None,
+                     "Fully qualified filename of a script to be run before "
+                     "any files are installed.  This script need not be in the "
+                     "distribution"),
+                   ]
+
+    boolean_options = ['keep-temp', 'no-target-compile', 'no-target-optimize',
+                       'skip-build']
+
+    def initialize_options (self):
+        self.bdist_dir = None
+        self.keep_temp = 0
+        self.no_target_compile = 0
+        self.no_target_optimize = 0
+        self.target_version = None
+        self.dist_dir = None
+        self.skip_build = 0
+        self.install_script = None
+        self.pre_install_script = None
+
+    def finalize_options (self):
+        if self.bdist_dir is None:
+            bdist_base = self.get_finalized_command('bdist').bdist_base
+            self.bdist_dir = os.path.join(bdist_base, 'msi')
+        short_version = get_python_version()
+        if self.target_version:
+            if not self.skip_build and self.distribution.has_ext_modules()\
+               and self.target_version != short_version:
+                raise DistutilsOptionError, \
+                      "target version can only be %s, or the '--skip_build'" \
+                      " option must be specified" % (short_version,)
+        else:
+            self.target_version = short_version
+
+        self.set_undefined_options('bdist', ('dist_dir', 'dist_dir'))
+
+        if self.pre_install_script:
+            raise DistutilsOptionError, "the pre-install-script feature is not yet implemented"
+
+        if self.install_script:
+            for script in self.distribution.scripts:
+                if self.install_script == os.path.basename(script):
+                    break
+            else:
+                raise DistutilsOptionError, \
+                      "install_script '%s' not found in scripts" % \
+                      self.install_script
+        self.install_script_key = None
+    # finalize_options()
+
+
+    def run (self):
+        if not self.skip_build:
+            self.run_command('build')
+
+        install = self.reinitialize_command('install', reinit_subcommands=1)
+        install.prefix = self.bdist_dir
+        install.skip_build = self.skip_build
+        install.warn_dir = 0
+
+        install_lib = self.reinitialize_command('install_lib')
+        # we do not want to include pyc or pyo files
+        install_lib.compile = 0
+        install_lib.optimize = 0
+
+        if self.distribution.has_ext_modules():
+            # If we are building an installer for a Python version other
+            # than the one we are currently running, then we need to ensure
+            # our build_lib reflects the other Python version rather than ours.
+            # Note that for target_version!=sys.version, we must have skipped the
+            # build step, so there is no issue with enforcing the build of this
+            # version.
+            target_version = self.target_version
+            if not target_version:
+                assert self.skip_build, "Should have already checked this"
+                target_version = sys.version[0:3]
+            plat_specifier = ".%s-%s" % (get_platform(), target_version)
+            build = self.get_finalized_command('build')
+            build.build_lib = os.path.join(build.build_base,
+                                           'lib' + plat_specifier)
+
+        log.info("installing to %s", self.bdist_dir)
+        install.ensure_finalized()
+
+        # avoid warning of 'install_lib' about installing
+        # into a directory not in sys.path
+        sys.path.insert(0, os.path.join(self.bdist_dir, 'PURELIB'))
+
+        install.run()
+
+        del sys.path[0]
+
+        self.mkpath(self.dist_dir)
+        fullname = self.distribution.get_fullname()
+        installer_name = self.get_installer_filename(fullname)
+        installer_name = os.path.abspath(installer_name)
+        if os.path.exists(installer_name): os.unlink(installer_name)
+
+        metadata = self.distribution.metadata
+        author = metadata.author
+        if not author:
+            author = metadata.maintainer
+        if not author:
+            author = "UNKNOWN"
+        version = metadata.get_version()
+        # ProductVersion must be strictly numeric
+        # XXX need to deal with prerelease versions
+        sversion = "%d.%d.%d" % StrictVersion(version).version
+        # Prefix ProductName with Python x.y, so that
+        # it sorts together with the other Python packages
+        # in Add-Remove-Programs (APR)
+        product_name = "Python %s %s" % (self.target_version,
+                       self.distribution.get_fullname())
+        self.db = msilib.init_database(installer_name, schema,
+                product_name, msilib.gen_uuid(),
+                sversion, author)
+        msilib.add_tables(self.db, sequence)
+        props = [('DistVersion', version)]
+        email = metadata.author_email or metadata.maintainer_email
+        if email:
+            props.append(("ARPCONTACT", email))
+        if metadata.url:
+            props.append(("ARPURLINFOABOUT", metadata.url))
+        if props:
+            add_data(self.db, 'Property', props)
+
+        self.add_find_python()
+        self.add_files()
+        self.add_scripts()
+        self.add_ui()
+        self.db.Commit()
+
+        if hasattr(self.distribution, 'dist_files'):
+            self.distribution.dist_files.append(('bdist_msi', self.target_version, fullname))
+
+        if not self.keep_temp:
+            remove_tree(self.bdist_dir, dry_run=self.dry_run)
+
+    def add_files(self):
+        db = self.db
+        cab = msilib.CAB("distfiles")
+        f = Feature(db, "default", "Default Feature", "Everything", 1, directory="TARGETDIR")
+        f.set_current()
+        rootdir = os.path.abspath(self.bdist_dir)
+        root = Directory(db, cab, None, rootdir, "TARGETDIR", "SourceDir")
+        db.Commit()
+        todo = [root]
+        while todo:
+            dir = todo.pop()
+            for file in os.listdir(dir.absolute):
+                afile = os.path.join(dir.absolute, file)
+                if os.path.isdir(afile):
+                    newdir = Directory(db, cab, dir, file, file, "%s|%s" % (dir.make_short(file), file))
+                    todo.append(newdir)
+                else:
+                    key = dir.add_file(file)
+                    if file==self.install_script:
+                        if self.install_script_key:
+                            raise DistutilsOptionError, "Multiple files with name %s" % file
+                        self.install_script_key = '[#%s]' % key
+
+        cab.commit(db)
+
+    def add_find_python(self):
+        """Adds code to the installer to compute the location of Python.
+        Properties PYTHON.MACHINE, PYTHON.USER, PYTHONDIR and PYTHON will be set
+        in both the execute and UI sequences; PYTHONDIR will be set from
+        PYTHON.USER if defined, else from PYTHON.MACHINE.
+        PYTHON is PYTHONDIR\python.exe"""
+        install_path = r"SOFTWARE\Python\PythonCore\%s\InstallPath" % self.target_version
+        add_data(self.db, "RegLocator",
+                [("python.machine", 2, install_path, None, 2),
+                 ("python.user", 1, install_path, None, 2)])
+        add_data(self.db, "AppSearch",
+                [("PYTHON.MACHINE", "python.machine"),
+                 ("PYTHON.USER", "python.user")])
+        add_data(self.db, "CustomAction",
+                [("PythonFromMachine", 51+256, "PYTHONDIR", "[PYTHON.MACHINE]"),
+                 ("PythonFromUser", 51+256, "PYTHONDIR", "[PYTHON.USER]"),
+                 ("PythonExe", 51+256, "PYTHON", "[PYTHONDIR]\\python.exe"),
+                 ("InitialTargetDir", 51+256, "TARGETDIR", "[PYTHONDIR]")])
+        add_data(self.db, "InstallExecuteSequence",
+                [("PythonFromMachine", "PYTHON.MACHINE", 401),
+                 ("PythonFromUser", "PYTHON.USER", 402),
+                 ("PythonExe", None, 403),
+                 ("InitialTargetDir", 'TARGETDIR=""', 404),
+                ])
+        add_data(self.db, "InstallUISequence",
+                [("PythonFromMachine", "PYTHON.MACHINE", 401),
+                 ("PythonFromUser", "PYTHON.USER", 402),
+                 ("PythonExe", None, 403),
+                 ("InitialTargetDir", 'TARGETDIR=""', 404),
+                ])
+
+    def add_scripts(self):
+        if self.install_script:
+            add_data(self.db, "CustomAction",
+                    [("install_script", 50, "PYTHON", self.install_script_key)])
+            add_data(self.db, "InstallExecuteSequence",
+                    [("install_script", "NOT Installed", 6800)])
+        if self.pre_install_script:
+            scriptfn = os.path.join(self.bdist_dir, "preinstall.bat")
+            f = open(scriptfn, "w")
+            # The batch file will be executed with [PYTHON], so that %1
+            # is the path to the Python interpreter; %0 will be the path
+            # of the batch file.
+            # rem ="""
+            # %1 %0
+            # exit
+            # """
+            # <actual script>
+            f.write('rem ="""\n%1 %0\nexit\n"""\n')
+            f.write(open(self.pre_install_script).read())
+            f.close()
+            add_data(self.db, "Binary",
+                [("PreInstall", msilib.Binary(scriptfn))
+                ])
+            add_data(self.db, "CustomAction",
+                [("PreInstall", 2, "PreInstall", None)
+                ])
+            add_data(self.db, "InstallExecuteSequence",
+                    [("PreInstall", "NOT Installed", 450)])
+
+
+    def add_ui(self):
+        db = self.db
+        x = y = 50
+        w = 370
+        h = 300
+        title = "[ProductName] Setup"
+
+        # see "Dialog Style Bits"
+        modal = 3      # visible | modal
+        modeless = 1   # visible
+        track_disk_space = 32
+
+        # UI customization properties
+        add_data(db, "Property",
+                 # See "DefaultUIFont Property"
+                 [("DefaultUIFont", "DlgFont8"),
+                  # See "ErrorDialog Style Bit"
+                  ("ErrorDialog", "ErrorDlg"),
+                  ("Progress1", "Install"),   # modified in maintenance type dlg
+                  ("Progress2", "installs"),
+                  ("MaintenanceForm_Action", "Repair"),
+                  # possible values: ALL, JUSTME
+                  ("WhichUsers", "ALL")
+                 ])
+
+        # Fonts, see "TextStyle Table"
+        add_data(db, "TextStyle",
+                 [("DlgFont8", "Tahoma", 9, None, 0),
+                  ("DlgFontBold8", "Tahoma", 8, None, 1), #bold
+                  ("VerdanaBold10", "Verdana", 10, None, 1),
+                  ("VerdanaRed9", "Verdana", 9, 255, 0),
+                 ])
+
+        # UI Sequences, see "InstallUISequence Table", "Using a Sequence Table"
+        # Numbers indicate sequence; see sequence.py for how these action integrate
+        add_data(db, "InstallUISequence",
+                 [("PrepareDlg", "Not Privileged or Windows9x or Installed", 140),
+                  ("WhichUsersDlg", "Privileged and not Windows9x and not Installed", 141),
+                  # In the user interface, assume all-users installation if privileged.
+                  ("SelectDirectoryDlg", "Not Installed", 1230),
+                  # XXX no support for resume installations yet
+                  #("ResumeDlg", "Installed AND (RESUME OR Preselected)", 1240),
+                  ("MaintenanceTypeDlg", "Installed AND NOT RESUME AND NOT Preselected", 1250),
+                  ("ProgressDlg", None, 1280)])
+
+        add_data(db, 'ActionText', text.ActionText)
+        add_data(db, 'UIText', text.UIText)
+        #####################################################################
+        # Standard dialogs: FatalError, UserExit, ExitDialog
+        fatal=PyDialog(db, "FatalError", x, y, w, h, modal, title,
+                     "Finish", "Finish", "Finish")
+        fatal.title("[ProductName] Installer ended prematurely")
+        fatal.back("< Back", "Finish", active = 0)
+        fatal.cancel("Cancel", "Back", active = 0)
+        fatal.text("Description1", 15, 70, 320, 80, 0x30003,
+                   "[ProductName] setup ended prematurely because of an error.  Your system has not been modified.  To install this program at a later time, please run the installation again.")
+        fatal.text("Description2", 15, 155, 320, 20, 0x30003,
+                   "Click the Finish button to exit the Installer.")
+        c=fatal.next("Finish", "Cancel", name="Finish")
+        c.event("EndDialog", "Exit")
+
+        user_exit=PyDialog(db, "UserExit", x, y, w, h, modal, title,
+                     "Finish", "Finish", "Finish")
+        user_exit.title("[ProductName] Installer was interrupted")
+        user_exit.back("< Back", "Finish", active = 0)
+        user_exit.cancel("Cancel", "Back", active = 0)
+        user_exit.text("Description1", 15, 70, 320, 80, 0x30003,
+                   "[ProductName] setup was interrupted.  Your system has not been modified.  "
+                   "To install this program at a later time, please run the installation again.")
+        user_exit.text("Description2", 15, 155, 320, 20, 0x30003,
+                   "Click the Finish button to exit the Installer.")
+        c = user_exit.next("Finish", "Cancel", name="Finish")
+        c.event("EndDialog", "Exit")
+
+        exit_dialog = PyDialog(db, "ExitDialog", x, y, w, h, modal, title,
+                             "Finish", "Finish", "Finish")
+        exit_dialog.title("Completing the [ProductName] Installer")
+        exit_dialog.back("< Back", "Finish", active = 0)
+        exit_dialog.cancel("Cancel", "Back", active = 0)
+        exit_dialog.text("Description", 15, 235, 320, 20, 0x30003,
+                   "Click the Finish button to exit the Installer.")
+        c = exit_dialog.next("Finish", "Cancel", name="Finish")
+        c.event("EndDialog", "Return")
+
+        #####################################################################
+        # Required dialog: FilesInUse, ErrorDlg
+        inuse = PyDialog(db, "FilesInUse",
+                         x, y, w, h,
+                         19,                # KeepModeless|Modal|Visible
+                         title,
+                         "Retry", "Retry", "Retry", bitmap=False)
+        inuse.text("Title", 15, 6, 200, 15, 0x30003,
+                   r"{\DlgFontBold8}Files in Use")
+        inuse.text("Description", 20, 23, 280, 20, 0x30003,
+               "Some files that need to be updated are currently in use.")
+        inuse.text("Text", 20, 55, 330, 50, 3,
+                   "The following applications are using files that need to be updated by this setup. Close these applications and then click Retry to continue the installation or Cancel to exit it.")
+        inuse.control("List", "ListBox", 20, 107, 330, 130, 7, "FileInUseProcess",
+                      None, None, None)
+        c=inuse.back("Exit", "Ignore", name="Exit")
+        c.event("EndDialog", "Exit")
+        c=inuse.next("Ignore", "Retry", name="Ignore")
+        c.event("EndDialog", "Ignore")
+        c=inuse.cancel("Retry", "Exit", name="Retry")
+        c.event("EndDialog","Retry")
+
+        # See "Error Dialog". See "ICE20" for the required names of the controls.
+        error = Dialog(db, "ErrorDlg",
+                       50, 10, 330, 101,
+                       65543,       # Error|Minimize|Modal|Visible
+                       title,
+                       "ErrorText", None, None)
+        error.text("ErrorText", 50,9,280,48,3, "")
+        #error.control("ErrorIcon", "Icon", 15, 9, 24, 24, 5242881, None, "py.ico", None, None)
+        error.pushbutton("N",120,72,81,21,3,"No",None).event("EndDialog","ErrorNo")
+        error.pushbutton("Y",240,72,81,21,3,"Yes",None).event("EndDialog","ErrorYes")
+        error.pushbutton("A",0,72,81,21,3,"Abort",None).event("EndDialog","ErrorAbort")
+        error.pushbutton("C",42,72,81,21,3,"Cancel",None).event("EndDialog","ErrorCancel")
+        error.pushbutton("I",81,72,81,21,3,"Ignore",None).event("EndDialog","ErrorIgnore")
+        error.pushbutton("O",159,72,81,21,3,"Ok",None).event("EndDialog","ErrorOk")
+        error.pushbutton("R",198,72,81,21,3,"Retry",None).event("EndDialog","ErrorRetry")
+
+        #####################################################################
+        # Global "Query Cancel" dialog
+        cancel = Dialog(db, "CancelDlg", 50, 10, 260, 85, 3, title,
+                        "No", "No", "No")
+        cancel.text("Text", 48, 15, 194, 30, 3,
+                    "Are you sure you want to cancel [ProductName] installation?")
+        #cancel.control("Icon", "Icon", 15, 15, 24, 24, 5242881, None,
+        #               "py.ico", None, None)
+        c=cancel.pushbutton("Yes", 72, 57, 56, 17, 3, "Yes", "No")
+        c.event("EndDialog", "Exit")
+
+        c=cancel.pushbutton("No", 132, 57, 56, 17, 3, "No", "Yes")
+        c.event("EndDialog", "Return")
+
+        #####################################################################
+        # Global "Wait for costing" dialog
+        costing = Dialog(db, "WaitForCostingDlg", 50, 10, 260, 85, modal, title,
+                         "Return", "Return", "Return")
+        costing.text("Text", 48, 15, 194, 30, 3,
+                     "Please wait while the installer finishes determining your disk space requirements.")
+        c = costing.pushbutton("Return", 102, 57, 56, 17, 3, "Return", None)
+        c.event("EndDialog", "Exit")
+
+        #####################################################################
+        # Preparation dialog: no user input except cancellation
+        prep = PyDialog(db, "PrepareDlg", x, y, w, h, modeless, title,
+                        "Cancel", "Cancel", "Cancel")
+        prep.text("Description", 15, 70, 320, 40, 0x30003,
+                  "Please wait while the Installer prepares to guide you through the installation.")
+        prep.title("Welcome to the [ProductName] Installer")
+        c=prep.text("ActionText", 15, 110, 320, 20, 0x30003, "Pondering...")
+        c.mapping("ActionText", "Text")
+        c=prep.text("ActionData", 15, 135, 320, 30, 0x30003, None)
+        c.mapping("ActionData", "Text")
+        prep.back("Back", None, active=0)
+        prep.next("Next", None, active=0)
+        c=prep.cancel("Cancel", None)
+        c.event("SpawnDialog", "CancelDlg")
+
+        #####################################################################
+        # Target directory selection
+        seldlg = PyDialog(db, "SelectDirectoryDlg", x, y, w, h, modal, title,
+                        "Next", "Next", "Cancel")
+        seldlg.title("Select Destination Directory")
+
+        version = sys.version[:3]+" "
+        seldlg.text("Hint", 15, 30, 300, 40, 3,
+                "The destination directory should contain a Python %sinstallation" % version)
+
+        seldlg.back("< Back", None, active=0)
+        c = seldlg.next("Next >", "Cancel")
+        c.event("SetTargetPath", "TARGETDIR", ordering=1)
+        c.event("SpawnWaitDialog", "WaitForCostingDlg", ordering=2)
+        c.event("EndDialog", "Return", ordering=3)
+
+        c = seldlg.cancel("Cancel", "DirectoryCombo")
+        c.event("SpawnDialog", "CancelDlg")
+
+        seldlg.control("DirectoryCombo", "DirectoryCombo", 15, 70, 272, 80, 393219,
+                       "TARGETDIR", None, "DirectoryList", None)
+        seldlg.control("DirectoryList", "DirectoryList", 15, 90, 308, 136, 3, "TARGETDIR",
+                       None, "PathEdit", None)
+        seldlg.control("PathEdit", "PathEdit", 15, 230, 306, 16, 3, "TARGETDIR", None, "Next", None)
+        c = seldlg.pushbutton("Up", 306, 70, 18, 18, 3, "Up", None)
+        c.event("DirectoryListUp", "0")
+        c = seldlg.pushbutton("NewDir", 324, 70, 30, 18, 3, "New", None)
+        c.event("DirectoryListNew", "0")
+
+        #####################################################################
+        # Disk cost
+        cost = PyDialog(db, "DiskCostDlg", x, y, w, h, modal, title,
+                        "OK", "OK", "OK", bitmap=False)
+        cost.text("Title", 15, 6, 200, 15, 0x30003,
+                  "{\DlgFontBold8}Disk Space Requirements")
+        cost.text("Description", 20, 20, 280, 20, 0x30003,
+                  "The disk space required for the installation of the selected features.")
+        cost.text("Text", 20, 53, 330, 60, 3,
+                  "The highlighted volumes (if any) do not have enough disk space "
+              "available for the currently selected features.  You can either "
+              "remove some files from the highlighted volumes, or choose to "
+              "install less features onto local drive(s), or select different "
+              "destination drive(s).")
+        cost.control("VolumeList", "VolumeCostList", 20, 100, 330, 150, 393223,
+                     None, "{120}{70}{70}{70}{70}", None, None)
+        cost.xbutton("OK", "Ok", None, 0.5).event("EndDialog", "Return")
+
+        #####################################################################
+        # WhichUsers Dialog. Only available on NT, and for privileged users.
+        # This must be run before FindRelatedProducts, because that will
+        # take into account whether the previous installation was per-user
+        # or per-machine. We currently don't support going back to this
+        # dialog after "Next" was selected; to support this, we would need to
+        # find how to reset the ALLUSERS property, and how to re-run
+        # FindRelatedProducts.
+        # On Windows9x, the ALLUSERS property is ignored on the command line
+        # and in the Property table, but installer fails according to the documentation
+        # if a dialog attempts to set ALLUSERS.
+        whichusers = PyDialog(db, "WhichUsersDlg", x, y, w, h, modal, title,
+                            "AdminInstall", "Next", "Cancel")
+        whichusers.title("Select whether to install [ProductName] for all users of this computer.")
+        # A radio group with two options: allusers, justme
+        g = whichusers.radiogroup("AdminInstall", 15, 60, 260, 50, 3,
+                                  "WhichUsers", "", "Next")
+        g.add("ALL", 0, 5, 150, 20, "Install for all users")
+        g.add("JUSTME", 0, 25, 150, 20, "Install just for me")
+
+        whichusers.back("Back", None, active=0)
+
+        c = whichusers.next("Next >", "Cancel")
+        c.event("[ALLUSERS]", "1", 'WhichUsers="ALL"', 1)
+        c.event("EndDialog", "Return", ordering = 2)
+
+        c = whichusers.cancel("Cancel", "AdminInstall")
+        c.event("SpawnDialog", "CancelDlg")
+
+        #####################################################################
+        # Installation Progress dialog (modeless)
+        progress = PyDialog(db, "ProgressDlg", x, y, w, h, modeless, title,
+                            "Cancel", "Cancel", "Cancel", bitmap=False)
+        progress.text("Title", 20, 15, 200, 15, 0x30003,
+                      "{\DlgFontBold8}[Progress1] [ProductName]")
+        progress.text("Text", 35, 65, 300, 30, 3,
+                      "Please wait while the Installer [Progress2] [ProductName]. "
+                      "This may take several minutes.")
+        progress.text("StatusLabel", 35, 100, 35, 20, 3, "Status:")
+
+        c=progress.text("ActionText", 70, 100, w-70, 20, 3, "Pondering...")
+        c.mapping("ActionText", "Text")
+
+        #c=progress.text("ActionData", 35, 140, 300, 20, 3, None)
+        #c.mapping("ActionData", "Text")
+
+        c=progress.control("ProgressBar", "ProgressBar", 35, 120, 300, 10, 65537,
+                           None, "Progress done", None, None)
+        c.mapping("SetProgress", "Progress")
+
+        progress.back("< Back", "Next", active=False)
+        progress.next("Next >", "Cancel", active=False)
+        progress.cancel("Cancel", "Back").event("SpawnDialog", "CancelDlg")
+
+        ###################################################################
+        # Maintenance type: repair/uninstall
+        maint = PyDialog(db, "MaintenanceTypeDlg", x, y, w, h, modal, title,
+                         "Next", "Next", "Cancel")
+        maint.title("Welcome to the [ProductName] Setup Wizard")
+        maint.text("BodyText", 15, 63, 330, 42, 3,
+                   "Select whether you want to repair or remove [ProductName].")
+        g=maint.radiogroup("RepairRadioGroup", 15, 108, 330, 60, 3,
+                            "MaintenanceForm_Action", "", "Next")
+        #g.add("Change", 0, 0, 200, 17, "&Change [ProductName]")
+        g.add("Repair", 0, 18, 200, 17, "&Repair [ProductName]")
+        g.add("Remove", 0, 36, 200, 17, "Re&move [ProductName]")
+
+        maint.back("< Back", None, active=False)
+        c=maint.next("Finish", "Cancel")
+        # Change installation: Change progress dialog to "Change", then ask
+        # for feature selection
+        #c.event("[Progress1]", "Change", 'MaintenanceForm_Action="Change"', 1)
+        #c.event("[Progress2]", "changes", 'MaintenanceForm_Action="Change"', 2)
+
+        # Reinstall: Change progress dialog to "Repair", then invoke reinstall
+        # Also set list of reinstalled features to "ALL"
+        c.event("[REINSTALL]", "ALL", 'MaintenanceForm_Action="Repair"', 5)
+        c.event("[Progress1]", "Repairing", 'MaintenanceForm_Action="Repair"', 6)
+        c.event("[Progress2]", "repairs", 'MaintenanceForm_Action="Repair"', 7)
+        c.event("Reinstall", "ALL", 'MaintenanceForm_Action="Repair"', 8)
+
+        # Uninstall: Change progress to "Remove", then invoke uninstall
+        # Also set list of removed features to "ALL"
+        c.event("[REMOVE]", "ALL", 'MaintenanceForm_Action="Remove"', 11)
+        c.event("[Progress1]", "Removing", 'MaintenanceForm_Action="Remove"', 12)
+        c.event("[Progress2]", "removes", 'MaintenanceForm_Action="Remove"', 13)
+        c.event("Remove", "ALL", 'MaintenanceForm_Action="Remove"', 14)
+
+        # Close dialog when maintenance action scheduled
+        c.event("EndDialog", "Return", 'MaintenanceForm_Action<>"Change"', 20)
+        #c.event("NewDialog", "SelectFeaturesDlg", 'MaintenanceForm_Action="Change"', 21)
+
+        maint.cancel("Cancel", "RepairRadioGroup").event("SpawnDialog", "CancelDlg")
+
+    def get_installer_filename(self, fullname):
+        # Factored out to allow overriding in subclasses
+        installer_name = os.path.join(self.dist_dir,
+                                      "%s.win32-py%s.msi" %
+                                       (fullname, self.target_version))
+        return installer_name

Added: vendor/Python/current/Lib/distutils/command/bdist_rpm.py
===================================================================
--- vendor/Python/current/Lib/distutils/command/bdist_rpm.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/command/bdist_rpm.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,564 @@
+"""distutils.command.bdist_rpm
+
+Implements the Distutils 'bdist_rpm' command (create RPM source and binary
+distributions)."""
+
+# This module should be kept compatible with Python 2.1.
+
+__revision__ = "$Id: bdist_rpm.py 52742 2006-11-12 18:56:18Z martin.v.loewis $"
+
+import sys, os, string
+import glob
+from types import *
+from distutils.core import Command
+from distutils.debug import DEBUG
+from distutils.util import get_platform
+from distutils.file_util import write_file
+from distutils.errors import *
+from distutils.sysconfig import get_python_version
+from distutils import log
+
+class bdist_rpm (Command):
+
+    description = "create an RPM distribution"
+
+    user_options = [
+        ('bdist-base=', None,
+         "base directory for creating built distributions"),
+        ('rpm-base=', None,
+         "base directory for creating RPMs (defaults to \"rpm\" under "
+         "--bdist-base; must be specified for RPM 2)"),
+        ('dist-dir=', 'd',
+         "directory to put final RPM files in "
+         "(and .spec files if --spec-only)"),
+        ('python=', None,
+         "path to Python interpreter to hard-code in the .spec file "
+         "(default: \"python\")"),
+        ('fix-python', None,
+         "hard-code the exact path to the current Python interpreter in "
+         "the .spec file"),
+        ('spec-only', None,
+         "only regenerate spec file"),
+        ('source-only', None,
+         "only generate source RPM"),
+        ('binary-only', None,
+         "only generate binary RPM"),
+        ('use-bzip2', None,
+         "use bzip2 instead of gzip to create source distribution"),
+
+        # More meta-data: too RPM-specific to put in the setup script,
+        # but needs to go in the .spec file -- so we make these options
+        # to "bdist_rpm".  The idea is that packagers would put this
+        # info in setup.cfg, although they are of course free to
+        # supply it on the command line.
+        ('distribution-name=', None,
+         "name of the (Linux) distribution to which this "
+         "RPM applies (*not* the name of the module distribution!)"),
+        ('group=', None,
+         "package classification [default: \"Development/Libraries\"]"),
+        ('release=', None,
+         "RPM release number"),
+        ('serial=', None,
+         "RPM serial number"),
+        ('vendor=', None,
+         "RPM \"vendor\" (eg. \"Joe Blow <joe at example.com>\") "
+         "[default: maintainer or author from setup script]"),
+        ('packager=', None,
+         "RPM packager (eg. \"Jane Doe <jane at example.net>\")"
+         "[default: vendor]"),
+        ('doc-files=', None,
+         "list of documentation files (space or comma-separated)"),
+        ('changelog=', None,
+         "RPM changelog"),
+        ('icon=', None,
+         "name of icon file"),
+        ('provides=', None,
+         "capabilities provided by this package"),
+        ('requires=', None,
+         "capabilities required by this package"),
+        ('conflicts=', None,
+         "capabilities which conflict with this package"),
+        ('build-requires=', None,
+         "capabilities required to build this package"),
+        ('obsoletes=', None,
+         "capabilities made obsolete by this package"),
+        ('no-autoreq', None,
+         "do not automatically calculate dependencies"),
+
+        # Actions to take when building RPM
+        ('keep-temp', 'k',
+         "don't clean up RPM build directory"),
+        ('no-keep-temp', None,
+         "clean up RPM build directory [default]"),
+        ('use-rpm-opt-flags', None,
+         "compile with RPM_OPT_FLAGS when building from source RPM"),
+        ('no-rpm-opt-flags', None,
+         "do not pass any RPM CFLAGS to compiler"),
+        ('rpm3-mode', None,
+         "RPM 3 compatibility mode (default)"),
+        ('rpm2-mode', None,
+         "RPM 2 compatibility mode"),
+
+        # Add the hooks necessary for specifying custom scripts
+        ('prep-script=', None,
+         "Specify a script for the PREP phase of RPM building"),
+        ('build-script=', None,
+         "Specify a script for the BUILD phase of RPM building"),
+
+        ('pre-install=', None,
+         "Specify a script for the pre-INSTALL phase of RPM building"),
+        ('install-script=', None,
+         "Specify a script for the INSTALL phase of RPM building"),
+        ('post-install=', None,
+         "Specify a script for the post-INSTALL phase of RPM building"),
+
+        ('pre-uninstall=', None,
+         "Specify a script for the pre-UNINSTALL phase of RPM building"),
+        ('post-uninstall=', None,
+         "Specify a script for the post-UNINSTALL phase of RPM building"),
+
+        ('clean-script=', None,
+         "Specify a script for the CLEAN phase of RPM building"),
+
+        ('verify-script=', None,
+         "Specify a script for the VERIFY phase of the RPM build"),
+
+        # Allow a packager to explicitly force an architecture
+        ('force-arch=', None,
+         "Force an architecture onto the RPM build process"),
+       ]
+
+    boolean_options = ['keep-temp', 'use-rpm-opt-flags', 'rpm3-mode',
+                       'no-autoreq']
+
+    negative_opt = {'no-keep-temp': 'keep-temp',
+                    'no-rpm-opt-flags': 'use-rpm-opt-flags',
+                    'rpm2-mode': 'rpm3-mode'}
+
+
+    def initialize_options (self):
+        self.bdist_base = None
+        self.rpm_base = None
+        self.dist_dir = None
+        self.python = None
+        self.fix_python = None
+        self.spec_only = None
+        self.binary_only = None
+        self.source_only = None
+        self.use_bzip2 = None
+
+        self.distribution_name = None
+        self.group = None
+        self.release = None
+        self.serial = None
+        self.vendor = None
+        self.packager = None
+        self.doc_files = None
+        self.changelog = None
+        self.icon = None
+
+        self.prep_script = None
+        self.build_script = None
+        self.install_script = None
+        self.clean_script = None
+        self.verify_script = None
+        self.pre_install = None
+        self.post_install = None
+        self.pre_uninstall = None
+        self.post_uninstall = None
+        self.prep = None
+        self.provides = None
+        self.requires = None
+        self.conflicts = None
+        self.build_requires = None
+        self.obsoletes = None
+
+        self.keep_temp = 0
+        self.use_rpm_opt_flags = 1
+        self.rpm3_mode = 1
+        self.no_autoreq = 0
+
+        self.force_arch = None
+
+    # initialize_options()
+
+
+    def finalize_options (self):
+        self.set_undefined_options('bdist', ('bdist_base', 'bdist_base'))
+        if self.rpm_base is None:
+            if not self.rpm3_mode:
+                raise DistutilsOptionError, \
+                      "you must specify --rpm-base in RPM 2 mode"
+            self.rpm_base = os.path.join(self.bdist_base, "rpm")
+
+        if self.python is None:
+            if self.fix_python:
+                self.python = sys.executable
+            else:
+                self.python = "python"
+        elif self.fix_python:
+            raise DistutilsOptionError, \
+                  "--python and --fix-python are mutually exclusive options"
+
+        if os.name != 'posix':
+            raise DistutilsPlatformError, \
+                  ("don't know how to create RPM "
+                   "distributions on platform %s" % os.name)
+        if self.binary_only and self.source_only:
+            raise DistutilsOptionError, \
+                  "cannot supply both '--source-only' and '--binary-only'"
+
+        # don't pass CFLAGS to pure python distributions
+        if not self.distribution.has_ext_modules():
+            self.use_rpm_opt_flags = 0
+
+        self.set_undefined_options('bdist', ('dist_dir', 'dist_dir'))
+        self.finalize_package_data()
+
+    # finalize_options()
+
+    def finalize_package_data (self):
+        self.ensure_string('group', "Development/Libraries")
+        self.ensure_string('vendor',
+                           "%s <%s>" % (self.distribution.get_contact(),
+                                        self.distribution.get_contact_email()))
+        self.ensure_string('packager')
+        self.ensure_string_list('doc_files')
+        if type(self.doc_files) is ListType:
+            for readme in ('README', 'README.txt'):
+                if os.path.exists(readme) and readme not in self.doc_files:
+                    self.doc_files.append(readme)
+
+        self.ensure_string('release', "1")
+        self.ensure_string('serial')   # should it be an int?
+
+        self.ensure_string('distribution_name')
+
+        self.ensure_string('changelog')
+          # Format changelog correctly
+        self.changelog = self._format_changelog(self.changelog)
+
+        self.ensure_filename('icon')
+
+        self.ensure_filename('prep_script')
+        self.ensure_filename('build_script')
+        self.ensure_filename('install_script')
+        self.ensure_filename('clean_script')
+        self.ensure_filename('verify_script')
+        self.ensure_filename('pre_install')
+        self.ensure_filename('post_install')
+        self.ensure_filename('pre_uninstall')
+        self.ensure_filename('post_uninstall')
+
+        # XXX don't forget we punted on summaries and descriptions -- they
+        # should be handled here eventually!
+
+        # Now *this* is some meta-data that belongs in the setup script...
+        self.ensure_string_list('provides')
+        self.ensure_string_list('requires')
+        self.ensure_string_list('conflicts')
+        self.ensure_string_list('build_requires')
+        self.ensure_string_list('obsoletes')
+
+        self.ensure_string('force_arch')
+    # finalize_package_data ()
+
+
+    def run (self):
+
+        if DEBUG:
+            print "before _get_package_data():"
+            print "vendor =", self.vendor
+            print "packager =", self.packager
+            print "doc_files =", self.doc_files
+            print "changelog =", self.changelog
+
+        # make directories
+        if self.spec_only:
+            spec_dir = self.dist_dir
+            self.mkpath(spec_dir)
+        else:
+            rpm_dir = {}
+            for d in ('SOURCES', 'SPECS', 'BUILD', 'RPMS', 'SRPMS'):
+                rpm_dir[d] = os.path.join(self.rpm_base, d)
+                self.mkpath(rpm_dir[d])
+            spec_dir = rpm_dir['SPECS']
+
+        # Spec file goes into 'dist_dir' if '--spec-only specified',
+        # build/rpm.<plat> otherwise.
+        spec_path = os.path.join(spec_dir,
+                                 "%s.spec" % self.distribution.get_name())
+        self.execute(write_file,
+                     (spec_path,
+                      self._make_spec_file()),
+                     "writing '%s'" % spec_path)
+
+        if self.spec_only: # stop if requested
+            return
+
+        # Make a source distribution and copy to SOURCES directory with
+        # optional icon.
+        saved_dist_files = self.distribution.dist_files[:]
+        sdist = self.reinitialize_command('sdist')
+        if self.use_bzip2:
+            sdist.formats = ['bztar']
+        else:
+            sdist.formats = ['gztar']
+        self.run_command('sdist')
+        self.distribution.dist_files = saved_dist_files
+
+        source = sdist.get_archive_files()[0]
+        source_dir = rpm_dir['SOURCES']
+        self.copy_file(source, source_dir)
+
+        if self.icon:
+            if os.path.exists(self.icon):
+                self.copy_file(self.icon, source_dir)
+            else:
+                raise DistutilsFileError, \
+                      "icon file '%s' does not exist" % self.icon
+
+
+        # build package
+        log.info("building RPMs")
+        rpm_cmd = ['rpm']
+        if os.path.exists('/usr/bin/rpmbuild') or \
+           os.path.exists('/bin/rpmbuild'):
+            rpm_cmd = ['rpmbuild']
+        if self.source_only: # what kind of RPMs?
+            rpm_cmd.append('-bs')
+        elif self.binary_only:
+            rpm_cmd.append('-bb')
+        else:
+            rpm_cmd.append('-ba')
+        if self.rpm3_mode:
+            rpm_cmd.extend(['--define',
+                             '_topdir %s' % os.path.abspath(self.rpm_base)])
+        if not self.keep_temp:
+            rpm_cmd.append('--clean')
+        rpm_cmd.append(spec_path)
+        # Determine the binary rpm names that should be built out of this spec
+        # file
+        # Note that some of these may not be really built (if the file
+        # list is empty)
+        nvr_string = "%{name}-%{version}-%{release}"
+        src_rpm = nvr_string + ".src.rpm"
+        non_src_rpm = "%{arch}/" + nvr_string + ".%{arch}.rpm"
+        q_cmd = r"rpm -q --qf '%s %s\n' --specfile '%s'" % (
+            src_rpm, non_src_rpm, spec_path)
+
+        out = os.popen(q_cmd)
+        binary_rpms = []
+        source_rpm = None
+        while 1:
+            line = out.readline()
+            if not line:
+                break
+            l = string.split(string.strip(line))
+            assert(len(l) == 2)
+            binary_rpms.append(l[1])
+            # The source rpm is named after the first entry in the spec file
+            if source_rpm is None:
+                source_rpm = l[0]
+
+        status = out.close()
+        if status:
+            raise DistutilsExecError("Failed to execute: %s" % repr(q_cmd))
+
+        self.spawn(rpm_cmd)
+
+        if not self.dry_run:
+            if not self.binary_only:
+                srpm = os.path.join(rpm_dir['SRPMS'], source_rpm)
+                assert(os.path.exists(srpm))
+                self.move_file(srpm, self.dist_dir)
+
+            if not self.source_only:
+                for rpm in binary_rpms:
+                    rpm = os.path.join(rpm_dir['RPMS'], rpm)
+                    if os.path.exists(rpm):
+                        self.move_file(rpm, self.dist_dir)
+    # run()
+
+    def _dist_path(self, path):
+        return os.path.join(self.dist_dir, os.path.basename(path))
+
+    def _make_spec_file(self):
+        """Generate the text of an RPM spec file and return it as a
+        list of strings (one per line).
+        """
+        # definitions and headers
+        spec_file = [
+            '%define name ' + self.distribution.get_name(),
+            '%define version ' + self.distribution.get_version().replace('-','_'),
+            '%define unmangled_version ' + self.distribution.get_version(),
+            '%define release ' + self.release.replace('-','_'),
+            '',
+            'Summary: ' + self.distribution.get_description(),
+            ]
+
+        # put locale summaries into spec file
+        # XXX not supported for now (hard to put a dictionary
+        # in a config file -- arg!)
+        #for locale in self.summaries.keys():
+        #    spec_file.append('Summary(%s): %s' % (locale,
+        #                                          self.summaries[locale]))
+
+        spec_file.extend([
+            'Name: %{name}',
+            'Version: %{version}',
+            'Release: %{release}',])
+
+        # XXX yuck! this filename is available from the "sdist" command,
+        # but only after it has run: and we create the spec file before
+        # running "sdist", in case of --spec-only.
+        if self.use_bzip2:
+            spec_file.append('Source0: %{name}-%{unmangled_version}.tar.bz2')
+        else:
+            spec_file.append('Source0: %{name}-%{unmangled_version}.tar.gz')
+
+        spec_file.extend([
+            'License: ' + self.distribution.get_license(),
+            'Group: ' + self.group,
+            'BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot',
+            'Prefix: %{_prefix}', ])
+
+        if not self.force_arch:
+            # noarch if no extension modules
+            if not self.distribution.has_ext_modules():
+                spec_file.append('BuildArch: noarch')
+        else:
+            spec_file.append( 'BuildArch: %s' % self.force_arch )
+
+        for field in ('Vendor',
+                      'Packager',
+                      'Provides',
+                      'Requires',
+                      'Conflicts',
+                      'Obsoletes',
+                      ):
+            val = getattr(self, string.lower(field))
+            if type(val) is ListType:
+                spec_file.append('%s: %s' % (field, string.join(val)))
+            elif val is not None:
+                spec_file.append('%s: %s' % (field, val))
+
+
+        if self.distribution.get_url() != 'UNKNOWN':
+            spec_file.append('Url: ' + self.distribution.get_url())
+
+        if self.distribution_name:
+            spec_file.append('Distribution: ' + self.distribution_name)
+
+        if self.build_requires:
+            spec_file.append('BuildRequires: ' +
+                             string.join(self.build_requires))
+
+        if self.icon:
+            spec_file.append('Icon: ' + os.path.basename(self.icon))
+
+        if self.no_autoreq:
+            spec_file.append('AutoReq: 0')
+
+        spec_file.extend([
+            '',
+            '%description',
+            self.distribution.get_long_description()
+            ])
+
+        # put locale descriptions into spec file
+        # XXX again, suppressed because config file syntax doesn't
+        # easily support this ;-(
+        #for locale in self.descriptions.keys():
+        #    spec_file.extend([
+        #        '',
+        #        '%description -l ' + locale,
+        #        self.descriptions[locale],
+        #        ])
+
+        # rpm scripts
+        # figure out default build script
+        def_setup_call = "%s %s" % (self.python,os.path.basename(sys.argv[0]))
+        def_build = "%s build" % def_setup_call
+        if self.use_rpm_opt_flags:
+            def_build = 'env CFLAGS="$RPM_OPT_FLAGS" ' + def_build
+
+        # insert contents of files
+
+        # XXX this is kind of misleading: user-supplied options are files
+        # that we open and interpolate into the spec file, but the defaults
+        # are just text that we drop in as-is.  Hmmm.
+
+        script_options = [
+            ('prep', 'prep_script', "%setup -n %{name}-%{unmangled_version}"),
+            ('build', 'build_script', def_build),
+            ('install', 'install_script',
+             ("%s install "
+              "--root=$RPM_BUILD_ROOT "
+              "--record=INSTALLED_FILES") % def_setup_call),
+            ('clean', 'clean_script', "rm -rf $RPM_BUILD_ROOT"),
+            ('verifyscript', 'verify_script', None),
+            ('pre', 'pre_install', None),
+            ('post', 'post_install', None),
+            ('preun', 'pre_uninstall', None),
+            ('postun', 'post_uninstall', None),
+        ]
+
+        for (rpm_opt, attr, default) in script_options:
+            # Insert contents of file referred to, if no file is referred to
+            # use 'default' as contents of script
+            val = getattr(self, attr)
+            if val or default:
+                spec_file.extend([
+                    '',
+                    '%' + rpm_opt,])
+                if val:
+                    spec_file.extend(string.split(open(val, 'r').read(), '\n'))
+                else:
+                    spec_file.append(default)
+
+
+        # files section
+        spec_file.extend([
+            '',
+            '%files -f INSTALLED_FILES',
+            '%defattr(-,root,root)',
+            ])
+
+        if self.doc_files:
+            spec_file.append('%doc ' + string.join(self.doc_files))
+
+        if self.changelog:
+            spec_file.extend([
+                '',
+                '%changelog',])
+            spec_file.extend(self.changelog)
+
+        return spec_file
+
+    # _make_spec_file ()
+
+    def _format_changelog(self, changelog):
+        """Format the changelog correctly and convert it to a list of strings
+        """
+        if not changelog:
+            return changelog
+        new_changelog = []
+        for line in string.split(string.strip(changelog), '\n'):
+            line = string.strip(line)
+            if line[0] == '*':
+                new_changelog.extend(['', line])
+            elif line[0] == '-':
+                new_changelog.append(line)
+            else:
+                new_changelog.append('  ' + line)
+
+        # strip trailing newline inserted by first changelog entry
+        if not new_changelog[0]:
+            del new_changelog[0]
+
+        return new_changelog
+
+    # _format_changelog()
+
+# class bdist_rpm

Added: vendor/Python/current/Lib/distutils/command/bdist_wininst.py
===================================================================
--- vendor/Python/current/Lib/distutils/command/bdist_wininst.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/command/bdist_wininst.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,328 @@
+"""distutils.command.bdist_wininst
+
+Implements the Distutils 'bdist_wininst' command: create a windows installer
+exe-program."""
+
+# This module should be kept compatible with Python 2.1.
+
+__revision__ = "$Id: bdist_wininst.py 38697 2005-03-23 18:54:36Z loewis $"
+
+import sys, os, string
+from distutils.core import Command
+from distutils.util import get_platform
+from distutils.dir_util import create_tree, remove_tree
+from distutils.errors import *
+from distutils.sysconfig import get_python_version
+from distutils import log
+
+class bdist_wininst (Command):
+
+    description = "create an executable installer for MS Windows"
+
+    user_options = [('bdist-dir=', None,
+                     "temporary directory for creating the distribution"),
+                    ('keep-temp', 'k',
+                     "keep the pseudo-installation tree around after " +
+                     "creating the distribution archive"),
+                    ('target-version=', None,
+                     "require a specific python version" +
+                     " on the target system"),
+                    ('no-target-compile', 'c',
+                     "do not compile .py to .pyc on the target system"),
+                    ('no-target-optimize', 'o',
+                     "do not compile .py to .pyo (optimized)"
+                     "on the target system"),
+                    ('dist-dir=', 'd',
+                     "directory to put final built distributions in"),
+                    ('bitmap=', 'b',
+                     "bitmap to use for the installer instead of python-powered logo"),
+                    ('title=', 't',
+                     "title to display on the installer background instead of default"),
+                    ('skip-build', None,
+                     "skip rebuilding everything (for testing/debugging)"),
+                    ('install-script=', None,
+                     "basename of installation script to be run after"
+                     "installation or before deinstallation"),
+                    ('pre-install-script=', None,
+                     "Fully qualified filename of a script to be run before "
+                     "any files are installed.  This script need not be in the "
+                     "distribution"),
+                   ]
+
+    boolean_options = ['keep-temp', 'no-target-compile', 'no-target-optimize',
+                       'skip-build']
+
+    def initialize_options (self):
+        self.bdist_dir = None
+        self.keep_temp = 0
+        self.no_target_compile = 0
+        self.no_target_optimize = 0
+        self.target_version = None
+        self.dist_dir = None
+        self.bitmap = None
+        self.title = None
+        self.skip_build = 0
+        self.install_script = None
+        self.pre_install_script = None
+
+    # initialize_options()
+
+
+    def finalize_options (self):
+        if self.bdist_dir is None:
+            bdist_base = self.get_finalized_command('bdist').bdist_base
+            self.bdist_dir = os.path.join(bdist_base, 'wininst')
+        if not self.target_version:
+            self.target_version = ""
+        if not self.skip_build and self.distribution.has_ext_modules():
+            short_version = get_python_version()
+            if self.target_version and self.target_version != short_version:
+                raise DistutilsOptionError, \
+                      "target version can only be %s, or the '--skip_build'" \
+                      " option must be specified" % (short_version,)
+            self.target_version = short_version
+
+        self.set_undefined_options('bdist', ('dist_dir', 'dist_dir'))
+
+        if self.install_script:
+            for script in self.distribution.scripts:
+                if self.install_script == os.path.basename(script):
+                    break
+            else:
+                raise DistutilsOptionError, \
+                      "install_script '%s' not found in scripts" % \
+                      self.install_script
+    # finalize_options()
+
+
+    def run (self):
+        if (sys.platform != "win32" and
+            (self.distribution.has_ext_modules() or
+             self.distribution.has_c_libraries())):
+            raise DistutilsPlatformError \
+                  ("distribution contains extensions and/or C libraries; "
+                   "must be compiled on a Windows 32 platform")
+
+        if not self.skip_build:
+            self.run_command('build')
+
+        install = self.reinitialize_command('install', reinit_subcommands=1)
+        install.root = self.bdist_dir
+        install.skip_build = self.skip_build
+        install.warn_dir = 0
+
+        install_lib = self.reinitialize_command('install_lib')
+        # we do not want to include pyc or pyo files
+        install_lib.compile = 0
+        install_lib.optimize = 0
+
+        if self.distribution.has_ext_modules():
+            # If we are building an installer for a Python version other
+            # than the one we are currently running, then we need to ensure
+            # our build_lib reflects the other Python version rather than ours.
+            # Note that for target_version!=sys.version, we must have skipped the
+            # build step, so there is no issue with enforcing the build of this
+            # version.
+            target_version = self.target_version
+            if not target_version:
+                assert self.skip_build, "Should have already checked this"
+                target_version = sys.version[0:3]
+            plat_specifier = ".%s-%s" % (get_platform(), target_version)
+            build = self.get_finalized_command('build')
+            build.build_lib = os.path.join(build.build_base,
+                                           'lib' + plat_specifier)
+
+        # Use a custom scheme for the zip-file, because we have to decide
+        # at installation time which scheme to use.
+        for key in ('purelib', 'platlib', 'headers', 'scripts', 'data'):
+            value = string.upper(key)
+            if key == 'headers':
+                value = value + '/Include/$dist_name'
+            setattr(install,
+                    'install_' + key,
+                    value)
+
+        log.info("installing to %s", self.bdist_dir)
+        install.ensure_finalized()
+
+        # avoid warning of 'install_lib' about installing
+        # into a directory not in sys.path
+        sys.path.insert(0, os.path.join(self.bdist_dir, 'PURELIB'))
+
+        install.run()
+
+        del sys.path[0]
+
+        # And make an archive relative to the root of the
+        # pseudo-installation tree.
+        from tempfile import mktemp
+        archive_basename = mktemp()
+        fullname = self.distribution.get_fullname()
+        arcname = self.make_archive(archive_basename, "zip",
+                                    root_dir=self.bdist_dir)
+        # create an exe containing the zip-file
+        self.create_exe(arcname, fullname, self.bitmap)
+        if self.distribution.has_ext_modules():
+            pyversion = get_python_version()
+        else:
+            pyversion = 'any'
+        self.distribution.dist_files.append(('bdist_wininst', pyversion,
+                                             self.get_installer_filename(fullname)))
+        # remove the zip-file again
+        log.debug("removing temporary file '%s'", arcname)
+        os.remove(arcname)
+
+        if not self.keep_temp:
+            remove_tree(self.bdist_dir, dry_run=self.dry_run)
+
+    # run()
+
+    def get_inidata (self):
+        # Return data describing the installation.
+
+        lines = []
+        metadata = self.distribution.metadata
+
+        # Write the [metadata] section.
+        lines.append("[metadata]")
+
+        # 'info' will be displayed in the installer's dialog box,
+        # describing the items to be installed.
+        info = (metadata.long_description or '') + '\n'
+
+        # Escape newline characters
+        def escape(s):
+            return string.replace(s, "\n", "\\n")
+
+        for name in ["author", "author_email", "description", "maintainer",
+                     "maintainer_email", "name", "url", "version"]:
+            data = getattr(metadata, name, "")
+            if data:
+                info = info + ("\n    %s: %s" % \
+                               (string.capitalize(name), escape(data)))
+                lines.append("%s=%s" % (name, escape(data)))
+
+        # The [setup] section contains entries controlling
+        # the installer runtime.
+        lines.append("\n[Setup]")
+        if self.install_script:
+            lines.append("install_script=%s" % self.install_script)
+        lines.append("info=%s" % escape(info))
+        lines.append("target_compile=%d" % (not self.no_target_compile))
+        lines.append("target_optimize=%d" % (not self.no_target_optimize))
+        if self.target_version:
+            lines.append("target_version=%s" % self.target_version)
+
+        title = self.title or self.distribution.get_fullname()
+        lines.append("title=%s" % escape(title))
+        import time
+        import distutils
+        build_info = "Built %s with distutils-%s" % \
+                     (time.ctime(time.time()), distutils.__version__)
+        lines.append("build_info=%s" % build_info)
+        return string.join(lines, "\n")
+
+    # get_inidata()
+
+    def create_exe (self, arcname, fullname, bitmap=None):
+        import struct
+
+        self.mkpath(self.dist_dir)
+
+        cfgdata = self.get_inidata()
+
+        installer_name = self.get_installer_filename(fullname)
+        self.announce("creating %s" % installer_name)
+
+        if bitmap:
+            bitmapdata = open(bitmap, "rb").read()
+            bitmaplen = len(bitmapdata)
+        else:
+            bitmaplen = 0
+
+        file = open(installer_name, "wb")
+        file.write(self.get_exe_bytes())
+        if bitmap:
+            file.write(bitmapdata)
+
+        # Convert cfgdata from unicode to ascii, mbcs encoded
+        try:
+            unicode
+        except NameError:
+            pass
+        else:
+            if isinstance(cfgdata, unicode):
+                cfgdata = cfgdata.encode("mbcs")
+
+        # Append the pre-install script
+        cfgdata = cfgdata + "\0"
+        if self.pre_install_script:
+            script_data = open(self.pre_install_script, "r").read()
+            cfgdata = cfgdata + script_data + "\n\0"
+        else:
+            # empty pre-install script
+            cfgdata = cfgdata + "\0"
+        file.write(cfgdata)
+
+        # The 'magic number' 0x1234567B is used to make sure that the
+        # binary layout of 'cfgdata' is what the wininst.exe binary
+        # expects.  If the layout changes, increment that number, make
+        # the corresponding changes to the wininst.exe sources, and
+        # recompile them.
+        header = struct.pack("<iii",
+                             0x1234567B,       # tag
+                             len(cfgdata),     # length
+                             bitmaplen,        # number of bytes in bitmap
+                             )
+        file.write(header)
+        file.write(open(arcname, "rb").read())
+
+    # create_exe()
+
+    def get_installer_filename(self, fullname):
+        # Factored out to allow overriding in subclasses
+        if self.target_version:
+            # if we create an installer for a specific python version,
+            # it's better to include this in the name
+            installer_name = os.path.join(self.dist_dir,
+                                          "%s.win32-py%s.exe" %
+                                           (fullname, self.target_version))
+        else:
+            installer_name = os.path.join(self.dist_dir,
+                                          "%s.win32.exe" % fullname)
+        return installer_name
+    # get_installer_filename()
+
+    def get_exe_bytes (self):
+        from distutils.msvccompiler import get_build_version
+        # If a target-version other than the current version has been
+        # specified, then using the MSVC version from *this* build is no good.
+        # Without actually finding and executing the target version and parsing
+        # its sys.version, we just hard-code our knowledge of old versions.
+        # NOTE: Possible alternative is to allow "--target-version" to
+        # specify a Python executable rather than a simple version string.
+        # We can then execute this program to obtain any info we need, such
+        # as the real sys.version string for the build.
+        cur_version = get_python_version()
+        if self.target_version and self.target_version != cur_version:
+            # If the target version is *later* than us, then we assume they
+            # use what we use
+            # string compares seem wrong, but are what sysconfig.py itself uses
+            if self.target_version > cur_version:
+                bv = get_build_version()
+            else:
+                if self.target_version < "2.4":
+                    bv = "6"
+                else:
+                    bv = "7.1"
+        else:
+            # for current version - use authoritative check.
+            bv = get_build_version()
+
+        # wininst-x.y.exe is in the same directory as this file
+        directory = os.path.dirname(__file__)
+        # we must use a wininst-x.y.exe built with the same C compiler
+        # used for python.  XXX What about mingw, borland, and so on?
+        filename = os.path.join(directory, "wininst-%s.exe" % bv)
+        return open(filename, "rb").read()
+# class bdist_wininst

Added: vendor/Python/current/Lib/distutils/command/build.py
===================================================================
--- vendor/Python/current/Lib/distutils/command/build.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/command/build.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,136 @@
+"""distutils.command.build
+
+Implements the Distutils 'build' command."""
+
+# This module should be kept compatible with Python 2.1.
+
+__revision__ = "$Id: build.py 37828 2004-11-10 22:23:15Z loewis $"
+
+import sys, os
+from distutils.core import Command
+from distutils.util import get_platform
+
+
+def show_compilers ():
+    from distutils.ccompiler import show_compilers
+    show_compilers()
+
+
+class build (Command):
+
+    description = "build everything needed to install"
+
+    user_options = [
+        ('build-base=', 'b',
+         "base directory for build library"),
+        ('build-purelib=', None,
+         "build directory for platform-neutral distributions"),
+        ('build-platlib=', None,
+         "build directory for platform-specific distributions"),
+        ('build-lib=', None,
+         "build directory for all distribution (defaults to either " +
+         "build-purelib or build-platlib"),
+        ('build-scripts=', None,
+         "build directory for scripts"),
+        ('build-temp=', 't',
+         "temporary build directory"),
+        ('compiler=', 'c',
+         "specify the compiler type"),
+        ('debug', 'g',
+         "compile extensions and libraries with debugging information"),
+        ('force', 'f',
+         "forcibly build everything (ignore file timestamps)"),
+        ('executable=', 'e',
+         "specify final destination interpreter path (build.py)"),
+        ]
+
+    boolean_options = ['debug', 'force']
+
+    help_options = [
+        ('help-compiler', None,
+         "list available compilers", show_compilers),
+        ]
+
+    def initialize_options (self):
+        self.build_base = 'build'
+        # these are decided only after 'build_base' has its final value
+        # (unless overridden by the user or client)
+        self.build_purelib = None
+        self.build_platlib = None
+        self.build_lib = None
+        self.build_temp = None
+        self.build_scripts = None
+        self.compiler = None
+        self.debug = None
+        self.force = 0
+        self.executable = None
+
+    def finalize_options (self):
+
+        plat_specifier = ".%s-%s" % (get_platform(), sys.version[0:3])
+
+        # 'build_purelib' and 'build_platlib' just default to 'lib' and
+        # 'lib.<plat>' under the base build directory.  We only use one of
+        # them for a given distribution, though --
+        if self.build_purelib is None:
+            self.build_purelib = os.path.join(self.build_base, 'lib')
+        if self.build_platlib is None:
+            self.build_platlib = os.path.join(self.build_base,
+                                              'lib' + plat_specifier)
+
+        # 'build_lib' is the actual directory that we will use for this
+        # particular module distribution -- if user didn't supply it, pick
+        # one of 'build_purelib' or 'build_platlib'.
+        if self.build_lib is None:
+            if self.distribution.ext_modules:
+                self.build_lib = self.build_platlib
+            else:
+                self.build_lib = self.build_purelib
+
+        # 'build_temp' -- temporary directory for compiler turds,
+        # "build/temp.<plat>"
+        if self.build_temp is None:
+            self.build_temp = os.path.join(self.build_base,
+                                           'temp' + plat_specifier)
+        if self.build_scripts is None:
+            self.build_scripts = os.path.join(self.build_base,
+                                              'scripts-' + sys.version[0:3])
+
+        if self.executable is None:
+            self.executable = os.path.normpath(sys.executable)
+    # finalize_options ()
+
+
+    def run (self):
+
+        # Run all relevant sub-commands.  This will be some subset of:
+        #  - build_py      - pure Python modules
+        #  - build_clib    - standalone C libraries
+        #  - build_ext     - Python extensions
+        #  - build_scripts - (Python) scripts
+        for cmd_name in self.get_sub_commands():
+            self.run_command(cmd_name)
+
+
+    # -- Predicates for the sub-command list ---------------------------
+
+    def has_pure_modules (self):
+        return self.distribution.has_pure_modules()
+
+    def has_c_libraries (self):
+        return self.distribution.has_c_libraries()
+
+    def has_ext_modules (self):
+        return self.distribution.has_ext_modules()
+
+    def has_scripts (self):
+        return self.distribution.has_scripts()
+
+
+    sub_commands = [('build_py',      has_pure_modules),
+                    ('build_clib',    has_c_libraries),
+                    ('build_ext',     has_ext_modules),
+                    ('build_scripts', has_scripts),
+                   ]
+
+# class build

Added: vendor/Python/current/Lib/distutils/command/build_clib.py
===================================================================
--- vendor/Python/current/Lib/distutils/command/build_clib.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/command/build_clib.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,238 @@
+"""distutils.command.build_clib
+
+Implements the Distutils 'build_clib' command, to build a C/C++ library
+that is included in the module distribution and needed by an extension
+module."""
+
+# This module should be kept compatible with Python 2.1.
+
+__revision__ = "$Id: build_clib.py 37828 2004-11-10 22:23:15Z loewis $"
+
+
+# XXX this module has *lots* of code ripped-off quite transparently from
+# build_ext.py -- not surprisingly really, as the work required to build
+# a static library from a collection of C source files is not really all
+# that different from what's required to build a shared object file from
+# a collection of C source files.  Nevertheless, I haven't done the
+# necessary refactoring to account for the overlap in code between the
+# two modules, mainly because a number of subtle details changed in the
+# cut 'n paste.  Sigh.
+
+import os, string
+from types import *
+from distutils.core import Command
+from distutils.errors import *
+from distutils.sysconfig import customize_compiler
+from distutils import log
+
+def show_compilers ():
+    from distutils.ccompiler import show_compilers
+    show_compilers()
+
+
+class build_clib (Command):
+
+    description = "build C/C++ libraries used by Python extensions"
+
+    user_options = [
+        ('build-clib', 'b',
+         "directory to build C/C++ libraries to"),
+        ('build-temp', 't',
+         "directory to put temporary build by-products"),
+        ('debug', 'g',
+         "compile with debugging information"),
+        ('force', 'f',
+         "forcibly build everything (ignore file timestamps)"),
+        ('compiler=', 'c',
+         "specify the compiler type"),
+        ]
+
+    boolean_options = ['debug', 'force']
+
+    help_options = [
+        ('help-compiler', None,
+         "list available compilers", show_compilers),
+        ]
+
+    def initialize_options (self):
+        self.build_clib = None
+        self.build_temp = None
+
+        # List of libraries to build
+        self.libraries = None
+
+        # Compilation options for all libraries
+        self.include_dirs = None
+        self.define = None
+        self.undef = None
+        self.debug = None
+        self.force = 0
+        self.compiler = None
+
+    # initialize_options()
+
+
+    def finalize_options (self):
+
+        # This might be confusing: both build-clib and build-temp default
+        # to build-temp as defined by the "build" command.  This is because
+        # I think that C libraries are really just temporary build
+        # by-products, at least from the point of view of building Python
+        # extensions -- but I want to keep my options open.
+        self.set_undefined_options('build',
+                                   ('build_temp', 'build_clib'),
+                                   ('build_temp', 'build_temp'),
+                                   ('compiler', 'compiler'),
+                                   ('debug', 'debug'),
+                                   ('force', 'force'))
+
+        self.libraries = self.distribution.libraries
+        if self.libraries:
+            self.check_library_list(self.libraries)
+
+        if self.include_dirs is None:
+            self.include_dirs = self.distribution.include_dirs or []
+        if type(self.include_dirs) is StringType:
+            self.include_dirs = string.split(self.include_dirs,
+                                             os.pathsep)
+
+        # XXX same as for build_ext -- what about 'self.define' and
+        # 'self.undef' ?
+
+    # finalize_options()
+
+
+    def run (self):
+
+        if not self.libraries:
+            return
+
+        # Yech -- this is cut 'n pasted from build_ext.py!
+        from distutils.ccompiler import new_compiler
+        self.compiler = new_compiler(compiler=self.compiler,
+                                     dry_run=self.dry_run,
+                                     force=self.force)
+        customize_compiler(self.compiler)
+
+        if self.include_dirs is not None:
+            self.compiler.set_include_dirs(self.include_dirs)
+        if self.define is not None:
+            # 'define' option is a list of (name,value) tuples
+            for (name,value) in self.define:
+                self.compiler.define_macro(name, value)
+        if self.undef is not None:
+            for macro in self.undef:
+                self.compiler.undefine_macro(macro)
+
+        self.build_libraries(self.libraries)
+
+    # run()
+
+
+    def check_library_list (self, libraries):
+        """Ensure that the list of libraries (presumably provided as a
+           command option 'libraries') is valid, i.e. it is a list of
+           2-tuples, where the tuples are (library_name, build_info_dict).
+           Raise DistutilsSetupError if the structure is invalid anywhere;
+           just returns otherwise."""
+
+        # Yechh, blecch, ackk: this is ripped straight out of build_ext.py,
+        # with only names changed to protect the innocent!
+
+        if type(libraries) is not ListType:
+            raise DistutilsSetupError, \
+                  "'libraries' option must be a list of tuples"
+
+        for lib in libraries:
+            if type(lib) is not TupleType and len(lib) != 2:
+                raise DistutilsSetupError, \
+                      "each element of 'libraries' must a 2-tuple"
+
+            if type(lib[0]) is not StringType:
+                raise DistutilsSetupError, \
+                      "first element of each tuple in 'libraries' " + \
+                      "must be a string (the library name)"
+            if '/' in lib[0] or (os.sep != '/' and os.sep in lib[0]):
+                raise DistutilsSetupError, \
+                      ("bad library name '%s': " +
+                       "may not contain directory separators") % \
+                      lib[0]
+
+            if type(lib[1]) is not DictionaryType:
+                raise DistutilsSetupError, \
+                      "second element of each tuple in 'libraries' " + \
+                      "must be a dictionary (build info)"
+        # for lib
+
+    # check_library_list ()
+
+
+    def get_library_names (self):
+        # Assume the library list is valid -- 'check_library_list()' is
+        # called from 'finalize_options()', so it should be!
+
+        if not self.libraries:
+            return None
+
+        lib_names = []
+        for (lib_name, build_info) in self.libraries:
+            lib_names.append(lib_name)
+        return lib_names
+
+    # get_library_names ()
+
+
+    def get_source_files (self):
+        self.check_library_list(self.libraries)
+        filenames = []
+        for (lib_name, build_info) in self.libraries:
+            sources = build_info.get('sources')
+            if (sources is None or
+                type(sources) not in (ListType, TupleType) ):
+                raise DistutilsSetupError, \
+                      ("in 'libraries' option (library '%s'), "
+                       "'sources' must be present and must be "
+                       "a list of source filenames") % lib_name
+
+            filenames.extend(sources)
+
+        return filenames
+    # get_source_files ()
+
+
+    def build_libraries (self, libraries):
+
+        for (lib_name, build_info) in libraries:
+            sources = build_info.get('sources')
+            if sources is None or type(sources) not in (ListType, TupleType):
+                raise DistutilsSetupError, \
+                      ("in 'libraries' option (library '%s'), " +
+                       "'sources' must be present and must be " +
+                       "a list of source filenames") % lib_name
+            sources = list(sources)
+
+            log.info("building '%s' library", lib_name)
+
+            # First, compile the source code to object files in the library
+            # directory.  (This should probably change to putting object
+            # files in a temporary build directory.)
+            macros = build_info.get('macros')
+            include_dirs = build_info.get('include_dirs')
+            objects = self.compiler.compile(sources,
+                                            output_dir=self.build_temp,
+                                            macros=macros,
+                                            include_dirs=include_dirs,
+                                            debug=self.debug)
+
+            # Now "link" the object files together into a static library.
+            # (On Unix at least, this isn't really linking -- it just
+            # builds an archive.  Whatever.)
+            self.compiler.create_static_lib(objects, lib_name,
+                                            output_dir=self.build_clib,
+                                            debug=self.debug)
+
+        # for libraries
+
+    # build_libraries ()
+
+# class build_lib

Added: vendor/Python/current/Lib/distutils/command/build_ext.py
===================================================================
--- vendor/Python/current/Lib/distutils/command/build_ext.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/command/build_ext.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,716 @@
+"""distutils.command.build_ext
+
+Implements the Distutils 'build_ext' command, for building extension
+modules (currently limited to C extensions, should accommodate C++
+extensions ASAP)."""
+
+# This module should be kept compatible with Python 2.1.
+
+__revision__ = "$Id: build_ext.py 54332 2007-03-13 10:19:35Z georg.brandl $"
+
+import sys, os, string, re
+from types import *
+from distutils.core import Command
+from distutils.errors import *
+from distutils.sysconfig import customize_compiler, get_python_version
+from distutils.dep_util import newer_group
+from distutils.extension import Extension
+from distutils import log
+
+# An extension name is just a dot-separated list of Python NAMEs (ie.
+# the same as a fully-qualified module name).
+extension_name_re = re.compile \
+    (r'^[a-zA-Z_][a-zA-Z_0-9]*(\.[a-zA-Z_][a-zA-Z_0-9]*)*$')
+
+
+def show_compilers ():
+    from distutils.ccompiler import show_compilers
+    show_compilers()
+
+
+class build_ext (Command):
+
+    description = "build C/C++ extensions (compile/link to build directory)"
+
+    # XXX thoughts on how to deal with complex command-line options like
+    # these, i.e. how to make it so fancy_getopt can suck them off the
+    # command line and make it look like setup.py defined the appropriate
+    # lists of tuples of what-have-you.
+    #   - each command needs a callback to process its command-line options
+    #   - Command.__init__() needs access to its share of the whole
+    #     command line (must ultimately come from
+    #     Distribution.parse_command_line())
+    #   - it then calls the current command class' option-parsing
+    #     callback to deal with weird options like -D, which have to
+    #     parse the option text and churn out some custom data
+    #     structure
+    #   - that data structure (in this case, a list of 2-tuples)
+    #     will then be present in the command object by the time
+    #     we get to finalize_options() (i.e. the constructor
+    #     takes care of both command-line and client options
+    #     in between initialize_options() and finalize_options())
+
+    sep_by = " (separated by '%s')" % os.pathsep
+    user_options = [
+        ('build-lib=', 'b',
+         "directory for compiled extension modules"),
+        ('build-temp=', 't',
+         "directory for temporary files (build by-products)"),
+        ('inplace', 'i',
+         "ignore build-lib and put compiled extensions into the source " +
+         "directory alongside your pure Python modules"),
+        ('include-dirs=', 'I',
+         "list of directories to search for header files" + sep_by),
+        ('define=', 'D',
+         "C preprocessor macros to define"),
+        ('undef=', 'U',
+         "C preprocessor macros to undefine"),
+        ('libraries=', 'l',
+         "external C libraries to link with"),
+        ('library-dirs=', 'L',
+         "directories to search for external C libraries" + sep_by),
+        ('rpath=', 'R',
+         "directories to search for shared C libraries at runtime"),
+        ('link-objects=', 'O',
+         "extra explicit link objects to include in the link"),
+        ('debug', 'g',
+         "compile/link with debugging information"),
+        ('force', 'f',
+         "forcibly build everything (ignore file timestamps)"),
+        ('compiler=', 'c',
+         "specify the compiler type"),
+        ('swig-cpp', None,
+         "make SWIG create C++ files (default is C)"),
+        ('swig-opts=', None,
+         "list of SWIG command line options"),
+        ('swig=', None,
+         "path to the SWIG executable"),
+        ]
+
+    boolean_options = ['inplace', 'debug', 'force', 'swig-cpp']
+
+    help_options = [
+        ('help-compiler', None,
+         "list available compilers", show_compilers),
+        ]
+
+    def initialize_options (self):
+        self.extensions = None
+        self.build_lib = None
+        self.build_temp = None
+        self.inplace = 0
+        self.package = None
+
+        self.include_dirs = None
+        self.define = None
+        self.undef = None
+        self.libraries = None
+        self.library_dirs = None
+        self.rpath = None
+        self.link_objects = None
+        self.debug = None
+        self.force = None
+        self.compiler = None
+        self.swig = None
+        self.swig_cpp = None
+        self.swig_opts = None
+
+    def finalize_options (self):
+        from distutils import sysconfig
+
+        self.set_undefined_options('build',
+                                   ('build_lib', 'build_lib'),
+                                   ('build_temp', 'build_temp'),
+                                   ('compiler', 'compiler'),
+                                   ('debug', 'debug'),
+                                   ('force', 'force'))
+
+        if self.package is None:
+            self.package = self.distribution.ext_package
+
+        self.extensions = self.distribution.ext_modules
+
+
+        # Make sure Python's include directories (for Python.h, pyconfig.h,
+        # etc.) are in the include search path.
+        py_include = sysconfig.get_python_inc()
+        plat_py_include = sysconfig.get_python_inc(plat_specific=1)
+        if self.include_dirs is None:
+            self.include_dirs = self.distribution.include_dirs or []
+        if type(self.include_dirs) is StringType:
+            self.include_dirs = string.split(self.include_dirs, os.pathsep)
+
+        # Put the Python "system" include dir at the end, so that
+        # any local include dirs take precedence.
+        self.include_dirs.append(py_include)
+        if plat_py_include != py_include:
+            self.include_dirs.append(plat_py_include)
+
+        if type(self.libraries) is StringType:
+            self.libraries = [self.libraries]
+
+        # Life is easier if we're not forever checking for None, so
+        # simplify these options to empty lists if unset
+        if self.libraries is None:
+            self.libraries = []
+        if self.library_dirs is None:
+            self.library_dirs = []
+        elif type(self.library_dirs) is StringType:
+            self.library_dirs = string.split(self.library_dirs, os.pathsep)
+
+        if self.rpath is None:
+            self.rpath = []
+        elif type(self.rpath) is StringType:
+            self.rpath = string.split(self.rpath, os.pathsep)
+
+        # for extensions under windows use different directories
+        # for Release and Debug builds.
+        # also Python's library directory must be appended to library_dirs
+        if os.name == 'nt':
+            self.library_dirs.append(os.path.join(sys.exec_prefix, 'libs'))
+            if self.debug:
+                self.build_temp = os.path.join(self.build_temp, "Debug")
+            else:
+                self.build_temp = os.path.join(self.build_temp, "Release")
+
+            # Append the source distribution include and library directories,
+            # this allows distutils on windows to work in the source tree
+            self.include_dirs.append(os.path.join(sys.exec_prefix, 'PC'))
+            self.library_dirs.append(os.path.join(sys.exec_prefix, 'PCBuild'))
+
+        # OS/2 (EMX) doesn't support Debug vs Release builds, but has the
+        # import libraries in its "Config" subdirectory
+        if os.name == 'os2':
+            self.library_dirs.append(os.path.join(sys.exec_prefix, 'Config'))
+
+        # for extensions under Cygwin and AtheOS Python's library directory must be
+        # appended to library_dirs
+        if sys.platform[:6] == 'cygwin' or sys.platform[:6] == 'atheos':
+            if sys.executable.startswith(os.path.join(sys.exec_prefix, "bin")):
+                # building third party extensions
+                self.library_dirs.append(os.path.join(sys.prefix, "lib",
+                                                      "python" + get_python_version(),
+                                                      "config"))
+            else:
+                # building python standard extensions
+                self.library_dirs.append('.')
+
+        # for extensions under Linux with a shared Python library,
+        # Python's library directory must be appended to library_dirs
+        if (sys.platform.startswith('linux') or sys.platform.startswith('gnu')) \
+                and sysconfig.get_config_var('Py_ENABLE_SHARED'):
+            if sys.executable.startswith(os.path.join(sys.exec_prefix, "bin")):
+                # building third party extensions
+                self.library_dirs.append(sysconfig.get_config_var('LIBDIR'))
+            else:
+                # building python standard extensions
+                self.library_dirs.append('.')
+
+        # The argument parsing will result in self.define being a string, but
+        # it has to be a list of 2-tuples.  All the preprocessor symbols
+        # specified by the 'define' option will be set to '1'.  Multiple
+        # symbols can be separated with commas.
+
+        if self.define:
+            defines = string.split(self.define, ',')
+            self.define = map(lambda symbol: (symbol, '1'), defines)
+
+        # The option for macros to undefine is also a string from the
+        # option parsing, but has to be a list.  Multiple symbols can also
+        # be separated with commas here.
+        if self.undef:
+            self.undef = string.split(self.undef, ',')
+
+        if self.swig_opts is None:
+            self.swig_opts = []
+        else:
+            self.swig_opts = self.swig_opts.split(' ')
+
+    # finalize_options ()
+
+
+    def run (self):
+
+        from distutils.ccompiler import new_compiler
+
+        # 'self.extensions', as supplied by setup.py, is a list of
+        # Extension instances.  See the documentation for Extension (in
+        # distutils.extension) for details.
+        #
+        # For backwards compatibility with Distutils 0.8.2 and earlier, we
+        # also allow the 'extensions' list to be a list of tuples:
+        #    (ext_name, build_info)
+        # where build_info is a dictionary containing everything that
+        # Extension instances do except the name, with a few things being
+        # differently named.  We convert these 2-tuples to Extension
+        # instances as needed.
+
+        if not self.extensions:
+            return
+
+        # If we were asked to build any C/C++ libraries, make sure that the
+        # directory where we put them is in the library search path for
+        # linking extensions.
+        if self.distribution.has_c_libraries():
+            build_clib = self.get_finalized_command('build_clib')
+            self.libraries.extend(build_clib.get_library_names() or [])
+            self.library_dirs.append(build_clib.build_clib)
+
+        # Setup the CCompiler object that we'll use to do all the
+        # compiling and linking
+        self.compiler = new_compiler(compiler=self.compiler,
+                                     verbose=self.verbose,
+                                     dry_run=self.dry_run,
+                                     force=self.force)
+        customize_compiler(self.compiler)
+
+        # And make sure that any compile/link-related options (which might
+        # come from the command-line or from the setup script) are set in
+        # that CCompiler object -- that way, they automatically apply to
+        # all compiling and linking done here.
+        if self.include_dirs is not None:
+            self.compiler.set_include_dirs(self.include_dirs)
+        if self.define is not None:
+            # 'define' option is a list of (name,value) tuples
+            for (name,value) in self.define:
+                self.compiler.define_macro(name, value)
+        if self.undef is not None:
+            for macro in self.undef:
+                self.compiler.undefine_macro(macro)
+        if self.libraries is not None:
+            self.compiler.set_libraries(self.libraries)
+        if self.library_dirs is not None:
+            self.compiler.set_library_dirs(self.library_dirs)
+        if self.rpath is not None:
+            self.compiler.set_runtime_library_dirs(self.rpath)
+        if self.link_objects is not None:
+            self.compiler.set_link_objects(self.link_objects)
+
+        # Now actually compile and link everything.
+        self.build_extensions()
+
+    # run ()
+
+
+    def check_extensions_list (self, extensions):
+        """Ensure that the list of extensions (presumably provided as a
+        command option 'extensions') is valid, i.e. it is a list of
+        Extension objects.  We also support the old-style list of 2-tuples,
+        where the tuples are (ext_name, build_info), which are converted to
+        Extension instances here.
+
+        Raise DistutilsSetupError if the structure is invalid anywhere;
+        just returns otherwise.
+        """
+        if type(extensions) is not ListType:
+            raise DistutilsSetupError, \
+                  "'ext_modules' option must be a list of Extension instances"
+
+        for i in range(len(extensions)):
+            ext = extensions[i]
+            if isinstance(ext, Extension):
+                continue                # OK! (assume type-checking done
+                                        # by Extension constructor)
+
+            (ext_name, build_info) = ext
+            log.warn(("old-style (ext_name, build_info) tuple found in "
+                      "ext_modules for extension '%s'"
+                      "-- please convert to Extension instance" % ext_name))
+            if type(ext) is not TupleType and len(ext) != 2:
+                raise DistutilsSetupError, \
+                      ("each element of 'ext_modules' option must be an "
+                       "Extension instance or 2-tuple")
+
+            if not (type(ext_name) is StringType and
+                    extension_name_re.match(ext_name)):
+                raise DistutilsSetupError, \
+                      ("first element of each tuple in 'ext_modules' "
+                       "must be the extension name (a string)")
+
+            if type(build_info) is not DictionaryType:
+                raise DistutilsSetupError, \
+                      ("second element of each tuple in 'ext_modules' "
+                       "must be a dictionary (build info)")
+
+            # OK, the (ext_name, build_info) dict is type-safe: convert it
+            # to an Extension instance.
+            ext = Extension(ext_name, build_info['sources'])
+
+            # Easy stuff: one-to-one mapping from dict elements to
+            # instance attributes.
+            for key in ('include_dirs',
+                        'library_dirs',
+                        'libraries',
+                        'extra_objects',
+                        'extra_compile_args',
+                        'extra_link_args'):
+                val = build_info.get(key)
+                if val is not None:
+                    setattr(ext, key, val)
+
+            # Medium-easy stuff: same syntax/semantics, different names.
+            ext.runtime_library_dirs = build_info.get('rpath')
+            if build_info.has_key('def_file'):
+                log.warn("'def_file' element of build info dict "
+                         "no longer supported")
+
+            # Non-trivial stuff: 'macros' split into 'define_macros'
+            # and 'undef_macros'.
+            macros = build_info.get('macros')
+            if macros:
+                ext.define_macros = []
+                ext.undef_macros = []
+                for macro in macros:
+                    if not (type(macro) is TupleType and
+                            1 <= len(macro) <= 2):
+                        raise DistutilsSetupError, \
+                              ("'macros' element of build info dict "
+                               "must be 1- or 2-tuple")
+                    if len(macro) == 1:
+                        ext.undef_macros.append(macro[0])
+                    elif len(macro) == 2:
+                        ext.define_macros.append(macro)
+
+            extensions[i] = ext
+
+        # for extensions
+
+    # check_extensions_list ()
+
+
+    def get_source_files (self):
+        self.check_extensions_list(self.extensions)
+        filenames = []
+
+        # Wouldn't it be neat if we knew the names of header files too...
+        for ext in self.extensions:
+            filenames.extend(ext.sources)
+
+        return filenames
+
+
+    def get_outputs (self):
+
+        # Sanity check the 'extensions' list -- can't assume this is being
+        # done in the same run as a 'build_extensions()' call (in fact, we
+        # can probably assume that it *isn't*!).
+        self.check_extensions_list(self.extensions)
+
+        # And build the list of output (built) filenames.  Note that this
+        # ignores the 'inplace' flag, and assumes everything goes in the
+        # "build" tree.
+        outputs = []
+        for ext in self.extensions:
+            fullname = self.get_ext_fullname(ext.name)
+            outputs.append(os.path.join(self.build_lib,
+                                        self.get_ext_filename(fullname)))
+        return outputs
+
+    # get_outputs ()
+
+    def build_extensions(self):
+        # First, sanity-check the 'extensions' list
+        self.check_extensions_list(self.extensions)
+
+        for ext in self.extensions:
+            self.build_extension(ext)
+
+    def build_extension(self, ext):
+        sources = ext.sources
+        if sources is None or type(sources) not in (ListType, TupleType):
+            raise DistutilsSetupError, \
+                  ("in 'ext_modules' option (extension '%s'), " +
+                   "'sources' must be present and must be " +
+                   "a list of source filenames") % ext.name
+        sources = list(sources)
+
+        fullname = self.get_ext_fullname(ext.name)
+        if self.inplace:
+            # ignore build-lib -- put the compiled extension into
+            # the source tree along with pure Python modules
+
+            modpath = string.split(fullname, '.')
+            package = string.join(modpath[0:-1], '.')
+            base = modpath[-1]
+
+            build_py = self.get_finalized_command('build_py')
+            package_dir = build_py.get_package_dir(package)
+            ext_filename = os.path.join(package_dir,
+                                        self.get_ext_filename(base))
+        else:
+            ext_filename = os.path.join(self.build_lib,
+                                        self.get_ext_filename(fullname))
+        depends = sources + ext.depends
+        if not (self.force or newer_group(depends, ext_filename, 'newer')):
+            log.debug("skipping '%s' extension (up-to-date)", ext.name)
+            return
+        else:
+            log.info("building '%s' extension", ext.name)
+
+        # First, scan the sources for SWIG definition files (.i), run
+        # SWIG on 'em to create .c files, and modify the sources list
+        # accordingly.
+        sources = self.swig_sources(sources, ext)
+
+        # Next, compile the source code to object files.
+
+        # XXX not honouring 'define_macros' or 'undef_macros' -- the
+        # CCompiler API needs to change to accommodate this, and I
+        # want to do one thing at a time!
+
+        # Two possible sources for extra compiler arguments:
+        #   - 'extra_compile_args' in Extension object
+        #   - CFLAGS environment variable (not particularly
+        #     elegant, but people seem to expect it and I
+        #     guess it's useful)
+        # The environment variable should take precedence, and
+        # any sensible compiler will give precedence to later
+        # command line args.  Hence we combine them in order:
+        extra_args = ext.extra_compile_args or []
+
+        macros = ext.define_macros[:]
+        for undef in ext.undef_macros:
+            macros.append((undef,))
+
+        objects = self.compiler.compile(sources,
+                                        output_dir=self.build_temp,
+                                        macros=macros,
+                                        include_dirs=ext.include_dirs,
+                                        debug=self.debug,
+                                        extra_postargs=extra_args,
+                                        depends=ext.depends)
+
+        # XXX -- this is a Vile HACK!
+        #
+        # The setup.py script for Python on Unix needs to be able to
+        # get this list so it can perform all the clean up needed to
+        # avoid keeping object files around when cleaning out a failed
+        # build of an extension module.  Since Distutils does not
+        # track dependencies, we have to get rid of intermediates to
+        # ensure all the intermediates will be properly re-built.
+        #
+        self._built_objects = objects[:]
+
+        # Now link the object files together into a "shared object" --
+        # of course, first we have to figure out all the other things
+        # that go into the mix.
+        if ext.extra_objects:
+            objects.extend(ext.extra_objects)
+        extra_args = ext.extra_link_args or []
+
+        # Detect target language, if not provided
+        language = ext.language or self.compiler.detect_language(sources)
+
+        self.compiler.link_shared_object(
+            objects, ext_filename,
+            libraries=self.get_libraries(ext),
+            library_dirs=ext.library_dirs,
+            runtime_library_dirs=ext.runtime_library_dirs,
+            extra_postargs=extra_args,
+            export_symbols=self.get_export_symbols(ext),
+            debug=self.debug,
+            build_temp=self.build_temp,
+            target_lang=language)
+
+
+    def swig_sources (self, sources, extension):
+
+        """Walk the list of source files in 'sources', looking for SWIG
+        interface (.i) files.  Run SWIG on all that are found, and
+        return a modified 'sources' list with SWIG source files replaced
+        by the generated C (or C++) files.
+        """
+
+        new_sources = []
+        swig_sources = []
+        swig_targets = {}
+
+        # XXX this drops generated C/C++ files into the source tree, which
+        # is fine for developers who want to distribute the generated
+        # source -- but there should be an option to put SWIG output in
+        # the temp dir.
+
+        if self.swig_cpp:
+            log.warn("--swig-cpp is deprecated - use --swig-opts=-c++")
+
+        if self.swig_cpp or ('-c++' in self.swig_opts):
+            target_ext = '.cpp'
+        else:
+            target_ext = '.c'
+
+        for source in sources:
+            (base, ext) = os.path.splitext(source)
+            if ext == ".i":             # SWIG interface file
+                new_sources.append(base + '_wrap' + target_ext)
+                swig_sources.append(source)
+                swig_targets[source] = new_sources[-1]
+            else:
+                new_sources.append(source)
+
+        if not swig_sources:
+            return new_sources
+
+        swig = self.swig or self.find_swig()
+        swig_cmd = [swig, "-python"]
+        swig_cmd.extend(self.swig_opts)
+        if self.swig_cpp:
+            swig_cmd.append("-c++")
+
+        # Do not override commandline arguments
+        if not self.swig_opts:
+            for o in extension.swig_opts:
+                swig_cmd.append(o)
+
+        for source in swig_sources:
+            target = swig_targets[source]
+            log.info("swigging %s to %s", source, target)
+            self.spawn(swig_cmd + ["-o", target, source])
+
+        return new_sources
+
+    # swig_sources ()
+
+    def find_swig (self):
+        """Return the name of the SWIG executable.  On Unix, this is
+        just "swig" -- it should be in the PATH.  Tries a bit harder on
+        Windows.
+        """
+
+        if os.name == "posix":
+            return "swig"
+        elif os.name == "nt":
+
+            # Look for SWIG in its standard installation directory on
+            # Windows (or so I presume!).  If we find it there, great;
+            # if not, act like Unix and assume it's in the PATH.
+            for vers in ("1.3", "1.2", "1.1"):
+                fn = os.path.join("c:\\swig%s" % vers, "swig.exe")
+                if os.path.isfile(fn):
+                    return fn
+            else:
+                return "swig.exe"
+
+        elif os.name == "os2":
+            # assume swig available in the PATH.
+            return "swig.exe"
+
+        else:
+            raise DistutilsPlatformError, \
+                  ("I don't know how to find (much less run) SWIG "
+                   "on platform '%s'") % os.name
+
+    # find_swig ()
+
+    # -- Name generators -----------------------------------------------
+    # (extension names, filenames, whatever)
+
+    def get_ext_fullname (self, ext_name):
+        if self.package is None:
+            return ext_name
+        else:
+            return self.package + '.' + ext_name
+
+    def get_ext_filename (self, ext_name):
+        r"""Convert the name of an extension (eg. "foo.bar") into the name
+        of the file from which it will be loaded (eg. "foo/bar.so", or
+        "foo\bar.pyd").
+        """
+
+        from distutils.sysconfig import get_config_var
+        ext_path = string.split(ext_name, '.')
+        # OS/2 has an 8 character module (extension) limit :-(
+        if os.name == "os2":
+            ext_path[len(ext_path) - 1] = ext_path[len(ext_path) - 1][:8]
+        # extensions in debug_mode are named 'module_d.pyd' under windows
+        so_ext = get_config_var('SO')
+        if os.name == 'nt' and self.debug:
+            return apply(os.path.join, ext_path) + '_d' + so_ext
+        return apply(os.path.join, ext_path) + so_ext
+
+    def get_export_symbols (self, ext):
+        """Return the list of symbols that a shared extension has to
+        export.  This either uses 'ext.export_symbols' or, if it's not
+        provided, "init" + module_name.  Only relevant on Windows, where
+        the .pyd file (DLL) must export the module "init" function.
+        """
+
+        initfunc_name = "init" + string.split(ext.name,'.')[-1]
+        if initfunc_name not in ext.export_symbols:
+            ext.export_symbols.append(initfunc_name)
+        return ext.export_symbols
+
+    def get_libraries (self, ext):
+        """Return the list of libraries to link against when building a
+        shared extension.  On most platforms, this is just 'ext.libraries';
+        on Windows and OS/2, we add the Python library (eg. python20.dll).
+        """
+        # The python library is always needed on Windows.  For MSVC, this
+        # is redundant, since the library is mentioned in a pragma in
+        # pyconfig.h that MSVC groks.  The other Windows compilers all seem
+        # to need it mentioned explicitly, though, so that's what we do.
+        # Append '_d' to the python import library on debug builds.
+        if sys.platform == "win32":
+            from distutils.msvccompiler import MSVCCompiler
+            if not isinstance(self.compiler, MSVCCompiler):
+                template = "python%d%d"
+                if self.debug:
+                    template = template + '_d'
+                pythonlib = (template %
+                       (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff))
+                # don't extend ext.libraries, it may be shared with other
+                # extensions, it is a reference to the original list
+                return ext.libraries + [pythonlib]
+            else:
+                return ext.libraries
+        elif sys.platform == "os2emx":
+            # EMX/GCC requires the python library explicitly, and I
+            # believe VACPP does as well (though not confirmed) - AIM Apr01
+            template = "python%d%d"
+            # debug versions of the main DLL aren't supported, at least
+            # not at this time - AIM Apr01
+            #if self.debug:
+            #    template = template + '_d'
+            pythonlib = (template %
+                   (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff))
+            # don't extend ext.libraries, it may be shared with other
+            # extensions, it is a reference to the original list
+            return ext.libraries + [pythonlib]
+        elif sys.platform[:6] == "cygwin":
+            template = "python%d.%d"
+            pythonlib = (template %
+                   (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff))
+            # don't extend ext.libraries, it may be shared with other
+            # extensions, it is a reference to the original list
+            return ext.libraries + [pythonlib]
+        elif sys.platform[:6] == "atheos":
+            from distutils import sysconfig
+
+            template = "python%d.%d"
+            pythonlib = (template %
+                   (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff))
+            # Get SHLIBS from Makefile
+            extra = []
+            for lib in sysconfig.get_config_var('SHLIBS').split():
+                if lib.startswith('-l'):
+                    extra.append(lib[2:])
+                else:
+                    extra.append(lib)
+            # don't extend ext.libraries, it may be shared with other
+            # extensions, it is a reference to the original list
+            return ext.libraries + [pythonlib, "m"] + extra
+
+        elif sys.platform == 'darwin':
+            # Don't use the default code below
+            return ext.libraries
+
+        else:
+            from distutils import sysconfig
+            if sysconfig.get_config_var('Py_ENABLE_SHARED'):
+                template = "python%d.%d"
+                pythonlib = (template %
+                             (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff))
+                return ext.libraries + [pythonlib]
+            else:
+                return ext.libraries
+
+# class build_ext

Added: vendor/Python/current/Lib/distutils/command/build_py.py
===================================================================
--- vendor/Python/current/Lib/distutils/command/build_py.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/command/build_py.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,435 @@
+"""distutils.command.build_py
+
+Implements the Distutils 'build_py' command."""
+
+# This module should be kept compatible with Python 2.1.
+
+__revision__ = "$Id: build_py.py 37828 2004-11-10 22:23:15Z loewis $"
+
+import sys, string, os
+from types import *
+from glob import glob
+
+from distutils.core import Command
+from distutils.errors import *
+from distutils.util import convert_path
+from distutils import log
+
+class build_py (Command):
+
+    description = "\"build\" pure Python modules (copy to build directory)"
+
+    user_options = [
+        ('build-lib=', 'd', "directory to \"build\" (copy) to"),
+        ('compile', 'c', "compile .py to .pyc"),
+        ('no-compile', None, "don't compile .py files [default]"),
+        ('optimize=', 'O',
+         "also compile with optimization: -O1 for \"python -O\", "
+         "-O2 for \"python -OO\", and -O0 to disable [default: -O0]"),
+        ('force', 'f', "forcibly build everything (ignore file timestamps)"),
+        ]
+
+    boolean_options = ['compile', 'force']
+    negative_opt = {'no-compile' : 'compile'}
+
+
+    def initialize_options (self):
+        self.build_lib = None
+        self.py_modules = None
+        self.package = None
+        self.package_data = None
+        self.package_dir = None
+        self.compile = 0
+        self.optimize = 0
+        self.force = None
+
+    def finalize_options (self):
+        self.set_undefined_options('build',
+                                   ('build_lib', 'build_lib'),
+                                   ('force', 'force'))
+
+        # Get the distribution options that are aliases for build_py
+        # options -- list of packages and list of modules.
+        self.packages = self.distribution.packages
+        self.py_modules = self.distribution.py_modules
+        self.package_data = self.distribution.package_data
+        self.package_dir = {}
+        if self.distribution.package_dir:
+            for name, path in self.distribution.package_dir.items():
+                self.package_dir[name] = convert_path(path)
+        self.data_files = self.get_data_files()
+
+        # Ick, copied straight from install_lib.py (fancy_getopt needs a
+        # type system!  Hell, *everything* needs a type system!!!)
+        if type(self.optimize) is not IntType:
+            try:
+                self.optimize = int(self.optimize)
+                assert 0 <= self.optimize <= 2
+            except (ValueError, AssertionError):
+                raise DistutilsOptionError, "optimize must be 0, 1, or 2"
+
+    def run (self):
+
+        # XXX copy_file by default preserves atime and mtime.  IMHO this is
+        # the right thing to do, but perhaps it should be an option -- in
+        # particular, a site administrator might want installed files to
+        # reflect the time of installation rather than the last
+        # modification time before the installed release.
+
+        # XXX copy_file by default preserves mode, which appears to be the
+        # wrong thing to do: if a file is read-only in the working
+        # directory, we want it to be installed read/write so that the next
+        # installation of the same module distribution can overwrite it
+        # without problems.  (This might be a Unix-specific issue.)  Thus
+        # we turn off 'preserve_mode' when copying to the build directory,
+        # since the build directory is supposed to be exactly what the
+        # installation will look like (ie. we preserve mode when
+        # installing).
+
+        # Two options control which modules will be installed: 'packages'
+        # and 'py_modules'.  The former lets us work with whole packages, not
+        # specifying individual modules at all; the latter is for
+        # specifying modules one-at-a-time.
+
+        if self.py_modules:
+            self.build_modules()
+        if self.packages:
+            self.build_packages()
+            self.build_package_data()
+
+        self.byte_compile(self.get_outputs(include_bytecode=0))
+
+    # run ()
+
+    def get_data_files (self):
+        """Generate list of '(package,src_dir,build_dir,filenames)' tuples"""
+        data = []
+        if not self.packages:
+            return data
+        for package in self.packages:
+            # Locate package source directory
+            src_dir = self.get_package_dir(package)
+
+            # Compute package build directory
+            build_dir = os.path.join(*([self.build_lib] + package.split('.')))
+
+            # Length of path to strip from found files
+            plen = len(src_dir)+1
+
+            # Strip directory from globbed filenames
+            filenames = [
+                file[plen:] for file in self.find_data_files(package, src_dir)
+                ]
+            data.append((package, src_dir, build_dir, filenames))
+        return data
+
+    def find_data_files (self, package, src_dir):
+        """Return filenames for package's data files in 'src_dir'"""
+        globs = (self.package_data.get('', [])
+                 + self.package_data.get(package, []))
+        files = []
+        for pattern in globs:
+            # Each pattern has to be converted to a platform-specific path
+            filelist = glob(os.path.join(src_dir, convert_path(pattern)))
+            # Files that match more than one pattern are only added once
+            files.extend([fn for fn in filelist if fn not in files])
+        return files
+
+    def build_package_data (self):
+        """Copy data files into build directory"""
+        lastdir = None
+        for package, src_dir, build_dir, filenames in self.data_files:
+            for filename in filenames:
+                target = os.path.join(build_dir, filename)
+                self.mkpath(os.path.dirname(target))
+                self.copy_file(os.path.join(src_dir, filename), target,
+                               preserve_mode=False)
+
+    def get_package_dir (self, package):
+        """Return the directory, relative to the top of the source
+           distribution, where package 'package' should be found
+           (at least according to the 'package_dir' option, if any)."""
+
+        path = string.split(package, '.')
+
+        if not self.package_dir:
+            if path:
+                return apply(os.path.join, path)
+            else:
+                return ''
+        else:
+            tail = []
+            while path:
+                try:
+                    pdir = self.package_dir[string.join(path, '.')]
+                except KeyError:
+                    tail.insert(0, path[-1])
+                    del path[-1]
+                else:
+                    tail.insert(0, pdir)
+                    return apply(os.path.join, tail)
+            else:
+                # Oops, got all the way through 'path' without finding a
+                # match in package_dir.  If package_dir defines a directory
+                # for the root (nameless) package, then fallback on it;
+                # otherwise, we might as well have not consulted
+                # package_dir at all, as we just use the directory implied
+                # by 'tail' (which should be the same as the original value
+                # of 'path' at this point).
+                pdir = self.package_dir.get('')
+                if pdir is not None:
+                    tail.insert(0, pdir)
+
+                if tail:
+                    return apply(os.path.join, tail)
+                else:
+                    return ''
+
+    # get_package_dir ()
+
+
+    def check_package (self, package, package_dir):
+
+        # Empty dir name means current directory, which we can probably
+        # assume exists.  Also, os.path.exists and isdir don't know about
+        # my "empty string means current dir" convention, so we have to
+        # circumvent them.
+        if package_dir != "":
+            if not os.path.exists(package_dir):
+                raise DistutilsFileError, \
+                      "package directory '%s' does not exist" % package_dir
+            if not os.path.isdir(package_dir):
+                raise DistutilsFileError, \
+                      ("supposed package directory '%s' exists, " +
+                       "but is not a directory") % package_dir
+
+        # Require __init__.py for all but the "root package"
+        if package:
+            init_py = os.path.join(package_dir, "__init__.py")
+            if os.path.isfile(init_py):
+                return init_py
+            else:
+                log.warn(("package init file '%s' not found " +
+                          "(or not a regular file)"), init_py)
+
+        # Either not in a package at all (__init__.py not expected), or
+        # __init__.py doesn't exist -- so don't return the filename.
+        return None
+
+    # check_package ()
+
+
+    def check_module (self, module, module_file):
+        if not os.path.isfile(module_file):
+            log.warn("file %s (for module %s) not found", module_file, module)
+            return 0
+        else:
+            return 1
+
+    # check_module ()
+
+
+    def find_package_modules (self, package, package_dir):
+        self.check_package(package, package_dir)
+        module_files = glob(os.path.join(package_dir, "*.py"))
+        modules = []
+        setup_script = os.path.abspath(self.distribution.script_name)
+
+        for f in module_files:
+            abs_f = os.path.abspath(f)
+            if abs_f != setup_script:
+                module = os.path.splitext(os.path.basename(f))[0]
+                modules.append((package, module, f))
+            else:
+                self.debug_print("excluding %s" % setup_script)
+        return modules
+
+
+    def find_modules (self):
+        """Finds individually-specified Python modules, ie. those listed by
+        module name in 'self.py_modules'.  Returns a list of tuples (package,
+        module_base, filename): 'package' is a tuple of the path through
+        package-space to the module; 'module_base' is the bare (no
+        packages, no dots) module name, and 'filename' is the path to the
+        ".py" file (relative to the distribution root) that implements the
+        module.
+        """
+
+        # Map package names to tuples of useful info about the package:
+        #    (package_dir, checked)
+        # package_dir - the directory where we'll find source files for
+        #   this package
+        # checked - true if we have checked that the package directory
+        #   is valid (exists, contains __init__.py, ... ?)
+        packages = {}
+
+        # List of (package, module, filename) tuples to return
+        modules = []
+
+        # We treat modules-in-packages almost the same as toplevel modules,
+        # just the "package" for a toplevel is empty (either an empty
+        # string or empty list, depending on context).  Differences:
+        #   - don't check for __init__.py in directory for empty package
+
+        for module in self.py_modules:
+            path = string.split(module, '.')
+            package = string.join(path[0:-1], '.')
+            module_base = path[-1]
+
+            try:
+                (package_dir, checked) = packages[package]
+            except KeyError:
+                package_dir = self.get_package_dir(package)
+                checked = 0
+
+            if not checked:
+                init_py = self.check_package(package, package_dir)
+                packages[package] = (package_dir, 1)
+                if init_py:
+                    modules.append((package, "__init__", init_py))
+
+            # XXX perhaps we should also check for just .pyc files
+            # (so greedy closed-source bastards can distribute Python
+            # modules too)
+            module_file = os.path.join(package_dir, module_base + ".py")
+            if not self.check_module(module, module_file):
+                continue
+
+            modules.append((package, module_base, module_file))
+
+        return modules
+
+    # find_modules ()
+
+
+    def find_all_modules (self):
+        """Compute the list of all modules that will be built, whether
+        they are specified one-module-at-a-time ('self.py_modules') or
+        by whole packages ('self.packages').  Return a list of tuples
+        (package, module, module_file), just like 'find_modules()' and
+        'find_package_modules()' do."""
+
+        modules = []
+        if self.py_modules:
+            modules.extend(self.find_modules())
+        if self.packages:
+            for package in self.packages:
+                package_dir = self.get_package_dir(package)
+                m = self.find_package_modules(package, package_dir)
+                modules.extend(m)
+
+        return modules
+
+    # find_all_modules ()
+
+
+    def get_source_files (self):
+
+        modules = self.find_all_modules()
+        filenames = []
+        for module in modules:
+            filenames.append(module[-1])
+
+        return filenames
+
+
+    def get_module_outfile (self, build_dir, package, module):
+        outfile_path = [build_dir] + list(package) + [module + ".py"]
+        return apply(os.path.join, outfile_path)
+
+
+    def get_outputs (self, include_bytecode=1):
+        modules = self.find_all_modules()
+        outputs = []
+        for (package, module, module_file) in modules:
+            package = string.split(package, '.')
+            filename = self.get_module_outfile(self.build_lib, package, module)
+            outputs.append(filename)
+            if include_bytecode:
+                if self.compile:
+                    outputs.append(filename + "c")
+                if self.optimize > 0:
+                    outputs.append(filename + "o")
+
+        outputs += [
+            os.path.join(build_dir, filename)
+            for package, src_dir, build_dir, filenames in self.data_files
+            for filename in filenames
+            ]
+
+        return outputs
+
+
+    def build_module (self, module, module_file, package):
+        if type(package) is StringType:
+            package = string.split(package, '.')
+        elif type(package) not in (ListType, TupleType):
+            raise TypeError, \
+                  "'package' must be a string (dot-separated), list, or tuple"
+
+        # Now put the module source file into the "build" area -- this is
+        # easy, we just copy it somewhere under self.build_lib (the build
+        # directory for Python source).
+        outfile = self.get_module_outfile(self.build_lib, package, module)
+        dir = os.path.dirname(outfile)
+        self.mkpath(dir)
+        return self.copy_file(module_file, outfile, preserve_mode=0)
+
+
+    def build_modules (self):
+
+        modules = self.find_modules()
+        for (package, module, module_file) in modules:
+
+            # Now "build" the module -- ie. copy the source file to
+            # self.build_lib (the build directory for Python source).
+            # (Actually, it gets copied to the directory for this package
+            # under self.build_lib.)
+            self.build_module(module, module_file, package)
+
+    # build_modules ()
+
+
+    def build_packages (self):
+
+        for package in self.packages:
+
+            # Get list of (package, module, module_file) tuples based on
+            # scanning the package directory.  'package' is only included
+            # in the tuple so that 'find_modules()' and
+            # 'find_package_tuples()' have a consistent interface; it's
+            # ignored here (apart from a sanity check).  Also, 'module' is
+            # the *unqualified* module name (ie. no dots, no package -- we
+            # already know its package!), and 'module_file' is the path to
+            # the .py file, relative to the current directory
+            # (ie. including 'package_dir').
+            package_dir = self.get_package_dir(package)
+            modules = self.find_package_modules(package, package_dir)
+
+            # Now loop over the modules we found, "building" each one (just
+            # copy it to self.build_lib).
+            for (package_, module, module_file) in modules:
+                assert package == package_
+                self.build_module(module, module_file, package)
+
+    # build_packages ()
+
+
+    def byte_compile (self, files):
+        from distutils.util import byte_compile
+        prefix = self.build_lib
+        if prefix[-1] != os.sep:
+            prefix = prefix + os.sep
+
+        # XXX this code is essentially the same as the 'byte_compile()
+        # method of the "install_lib" command, except for the determination
+        # of the 'prefix' string.  Hmmm.
+
+        if self.compile:
+            byte_compile(files, optimize=0,
+                         force=self.force, prefix=prefix, dry_run=self.dry_run)
+        if self.optimize > 0:
+            byte_compile(files, optimize=self.optimize,
+                         force=self.force, prefix=prefix, dry_run=self.dry_run)
+
+# class build_py

Added: vendor/Python/current/Lib/distutils/command/build_scripts.py
===================================================================
--- vendor/Python/current/Lib/distutils/command/build_scripts.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/command/build_scripts.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,131 @@
+"""distutils.command.build_scripts
+
+Implements the Distutils 'build_scripts' command."""
+
+# This module should be kept compatible with Python 2.1.
+
+__revision__ = "$Id: build_scripts.py 37828 2004-11-10 22:23:15Z loewis $"
+
+import sys, os, re
+from stat import ST_MODE
+from distutils import sysconfig
+from distutils.core import Command
+from distutils.dep_util import newer
+from distutils.util import convert_path
+from distutils import log
+
+# check if Python is called on the first line with this expression
+first_line_re = re.compile('^#!.*python[0-9.]*([ \t].*)?$')
+
+class build_scripts (Command):
+
+    description = "\"build\" scripts (copy and fixup #! line)"
+
+    user_options = [
+        ('build-dir=', 'd', "directory to \"build\" (copy) to"),
+        ('force', 'f', "forcibly build everything (ignore file timestamps"),
+        ('executable=', 'e', "specify final destination interpreter path"),
+        ]
+
+    boolean_options = ['force']
+
+
+    def initialize_options (self):
+        self.build_dir = None
+        self.scripts = None
+        self.force = None
+        self.executable = None
+        self.outfiles = None
+
+    def finalize_options (self):
+        self.set_undefined_options('build',
+                                   ('build_scripts', 'build_dir'),
+                                   ('force', 'force'),
+                                   ('executable', 'executable'))
+        self.scripts = self.distribution.scripts
+
+    def get_source_files(self):
+        return self.scripts
+
+    def run (self):
+        if not self.scripts:
+            return
+        self.copy_scripts()
+
+
+    def copy_scripts (self):
+        """Copy each script listed in 'self.scripts'; if it's marked as a
+        Python script in the Unix way (first line matches 'first_line_re',
+        ie. starts with "\#!" and contains "python"), then adjust the first
+        line to refer to the current Python interpreter as we copy.
+        """
+        self.mkpath(self.build_dir)
+        outfiles = []
+        for script in self.scripts:
+            adjust = 0
+            script = convert_path(script)
+            outfile = os.path.join(self.build_dir, os.path.basename(script))
+            outfiles.append(outfile)
+
+            if not self.force and not newer(script, outfile):
+                log.debug("not copying %s (up-to-date)", script)
+                continue
+
+            # Always open the file, but ignore failures in dry-run mode --
+            # that way, we'll get accurate feedback if we can read the
+            # script.
+            try:
+                f = open(script, "r")
+            except IOError:
+                if not self.dry_run:
+                    raise
+                f = None
+            else:
+                first_line = f.readline()
+                if not first_line:
+                    self.warn("%s is an empty file (skipping)" % script)
+                    continue
+
+                match = first_line_re.match(first_line)
+                if match:
+                    adjust = 1
+                    post_interp = match.group(1) or ''
+
+            if adjust:
+                log.info("copying and adjusting %s -> %s", script,
+                         self.build_dir)
+                if not self.dry_run:
+                    outf = open(outfile, "w")
+                    if not sysconfig.python_build:
+                        outf.write("#!%s%s\n" %
+                                   (self.executable,
+                                    post_interp))
+                    else:
+                        outf.write("#!%s%s\n" %
+                                   (os.path.join(
+                            sysconfig.get_config_var("BINDIR"),
+                            "python" + sysconfig.get_config_var("EXE")),
+                                    post_interp))
+                    outf.writelines(f.readlines())
+                    outf.close()
+                if f:
+                    f.close()
+            else:
+                f.close()
+                self.copy_file(script, outfile)
+
+        if os.name == 'posix':
+            for file in outfiles:
+                if self.dry_run:
+                    log.info("changing mode of %s", file)
+                else:
+                    oldmode = os.stat(file)[ST_MODE] & 07777
+                    newmode = (oldmode | 0555) & 07777
+                    if newmode != oldmode:
+                        log.info("changing mode of %s from %o to %o",
+                                 file, oldmode, newmode)
+                        os.chmod(file, newmode)
+
+    # copy_scripts ()
+
+# class build_scripts

Added: vendor/Python/current/Lib/distutils/command/clean.py
===================================================================
--- vendor/Python/current/Lib/distutils/command/clean.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/command/clean.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,82 @@
+"""distutils.command.clean
+
+Implements the Distutils 'clean' command."""
+
+# contributed by Bastian Kleineidam <calvin at cs.uni-sb.de>, added 2000-03-18
+
+# This module should be kept compatible with Python 2.1.
+
+__revision__ = "$Id: clean.py 38532 2005-03-03 08:12:27Z loewis $"
+
+import os
+from distutils.core import Command
+from distutils.dir_util import remove_tree
+from distutils import log
+
+class clean (Command):
+
+    description = "clean up temporary files from 'build' command"
+    user_options = [
+        ('build-base=', 'b',
+         "base build directory (default: 'build.build-base')"),
+        ('build-lib=', None,
+         "build directory for all modules (default: 'build.build-lib')"),
+        ('build-temp=', 't',
+         "temporary build directory (default: 'build.build-temp')"),
+        ('build-scripts=', None,
+         "build directory for scripts (default: 'build.build-scripts')"),
+        ('bdist-base=', None,
+         "temporary directory for built distributions"),
+        ('all', 'a',
+         "remove all build output, not just temporary by-products")
+    ]
+
+    boolean_options = ['all']
+
+    def initialize_options(self):
+        self.build_base = None
+        self.build_lib = None
+        self.build_temp = None
+        self.build_scripts = None
+        self.bdist_base = None
+        self.all = None
+
+    def finalize_options(self):
+        self.set_undefined_options('build',
+                                   ('build_base', 'build_base'),
+                                   ('build_lib', 'build_lib'),
+                                   ('build_scripts', 'build_scripts'),
+                                   ('build_temp', 'build_temp'))
+        self.set_undefined_options('bdist',
+                                   ('bdist_base', 'bdist_base'))
+
+    def run(self):
+        # remove the build/temp.<plat> directory (unless it's already
+        # gone)
+        if os.path.exists(self.build_temp):
+            remove_tree(self.build_temp, dry_run=self.dry_run)
+        else:
+            log.debug("'%s' does not exist -- can't clean it",
+                      self.build_temp)
+
+        if self.all:
+            # remove build directories
+            for directory in (self.build_lib,
+                              self.bdist_base,
+                              self.build_scripts):
+                if os.path.exists(directory):
+                    remove_tree(directory, dry_run=self.dry_run)
+                else:
+                    log.warn("'%s' does not exist -- can't clean it",
+                             directory)
+
+        # just for the heck of it, try to remove the base build directory:
+        # we might have emptied it right now, but if not we don't care
+        if not self.dry_run:
+            try:
+                os.rmdir(self.build_base)
+                log.info("removing '%s'", self.build_base)
+            except OSError:
+                pass
+
+# class clean

Added: vendor/Python/current/Lib/distutils/command/command_template
===================================================================
--- vendor/Python/current/Lib/distutils/command/command_template	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/command/command_template	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,45 @@
+"""distutils.command.x
+
+Implements the Distutils 'x' command.
+"""
+
+# created 2000/mm/dd, John Doe
+
+__revision__ = "$Id$"
+
+from distutils.core import Command
+
+
+class x (Command):
+
+    # Brief (40-50 characters) description of the command
+    description = ""
+
+    # List of option tuples: long name, short name (None if no short
+    # name), and help string.
+    user_options = [('', '',
+                     ""),
+                   ]
+
+
+    def initialize_options (self):
+        self. = None
+        self. = None
+        self. = None
+
+    # initialize_options()
+
+
+    def finalize_options (self):
+        if self.x is None:
+            self.x = 
+
+    # finalize_options()
+
+
+    def run (self):
+
+
+    # run()
+
+# class x

Added: vendor/Python/current/Lib/distutils/command/config.py
===================================================================
--- vendor/Python/current/Lib/distutils/command/config.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/command/config.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,368 @@
+"""distutils.command.config
+
+Implements the Distutils 'config' command, a (mostly) empty command class
+that exists mainly to be sub-classed by specific module distributions and
+applications.  The idea is that while every "config" command is different,
+at least they're all named the same, and users always see "config" in the
+list of standard commands.  Also, this is a good place to put common
+configure-like tasks: "try to compile this C code", or "figure out where
+this header file lives".
+"""
+
+# This module should be kept compatible with Python 2.1.
+
+__revision__ = "$Id: config.py 37828 2004-11-10 22:23:15Z loewis $"
+
+import sys, os, string, re
+from types import *
+from distutils.core import Command
+from distutils.errors import DistutilsExecError
+from distutils.sysconfig import customize_compiler
+from distutils import log
+
+LANG_EXT = {'c': '.c',
+            'c++': '.cxx'}
+
+class config (Command):
+
+    description = "prepare to build"
+
+    user_options = [
+        ('compiler=', None,
+         "specify the compiler type"),
+        ('cc=', None,
+         "specify the compiler executable"),
+        ('include-dirs=', 'I',
+         "list of directories to search for header files"),
+        ('define=', 'D',
+         "C preprocessor macros to define"),
+        ('undef=', 'U',
+         "C preprocessor macros to undefine"),
+        ('libraries=', 'l',
+         "external C libraries to link with"),
+        ('library-dirs=', 'L',
+         "directories to search for external C libraries"),
+
+        ('noisy', None,
+         "show every action (compile, link, run, ...) taken"),
+        ('dump-source', None,
+         "dump generated source files before attempting to compile them"),
+        ]
+
+
+    # The three standard command methods: since the "config" command
+    # does nothing by default, these are empty.
+
+    def initialize_options (self):
+        self.compiler = None
+        self.cc = None
+        self.include_dirs = None
+        #self.define = None
+        #self.undef = None
+        self.libraries = None
+        self.library_dirs = None
+
+        # maximal output for now
+        self.noisy = 1
+        self.dump_source = 1
+
+        # list of temporary files generated along-the-way that we have
+        # to clean at some point
+        self.temp_files = []
+
+    def finalize_options (self):
+        if self.include_dirs is None:
+            self.include_dirs = self.distribution.include_dirs or []
+        elif type(self.include_dirs) is StringType:
+            self.include_dirs = string.split(self.include_dirs, os.pathsep)
+
+        if self.libraries is None:
+            self.libraries = []
+        elif type(self.libraries) is StringType:
+            self.libraries = [self.libraries]
+
+        if self.library_dirs is None:
+            self.library_dirs = []
+        elif type(self.library_dirs) is StringType:
+            self.library_dirs = string.split(self.library_dirs, os.pathsep)
+
+
+    def run (self):
+        pass
+
+
+    # Utility methods for actual "config" commands.  The interfaces are
+    # loosely based on Autoconf macros of similar names.  Sub-classes
+    # may use these freely.
+
+    def _check_compiler (self):
+        """Check that 'self.compiler' really is a CCompiler object;
+        if not, make it one.
+        """
+        # We do this late, and only on-demand, because this is an expensive
+        # import.
+        from distutils.ccompiler import CCompiler, new_compiler
+        if not isinstance(self.compiler, CCompiler):
+            self.compiler = new_compiler(compiler=self.compiler,
+                                         dry_run=self.dry_run, force=1)
+            customize_compiler(self.compiler)
+            if self.include_dirs:
+                self.compiler.set_include_dirs(self.include_dirs)
+            if self.libraries:
+                self.compiler.set_libraries(self.libraries)
+            if self.library_dirs:
+                self.compiler.set_library_dirs(self.library_dirs)
+
+
+    def _gen_temp_sourcefile (self, body, headers, lang):
+        filename = "_configtest" + LANG_EXT[lang]
+        file = open(filename, "w")
+        if headers:
+            for header in headers:
+                file.write("#include <%s>\n" % header)
+            file.write("\n")
+        file.write(body)
+        if body[-1] != "\n":
+            file.write("\n")
+        file.close()
+        return filename
+
+    def _preprocess (self, body, headers, include_dirs, lang):
+        src = self._gen_temp_sourcefile(body, headers, lang)
+        out = "_configtest.i"
+        self.temp_files.extend([src, out])
+        self.compiler.preprocess(src, out, include_dirs=include_dirs)
+        return (src, out)
+
+    def _compile (self, body, headers, include_dirs, lang):
+        src = self._gen_temp_sourcefile(body, headers, lang)
+        if self.dump_source:
+            dump_file(src, "compiling '%s':" % src)
+        (obj,) = self.compiler.object_filenames([src])
+        self.temp_files.extend([src, obj])
+        self.compiler.compile([src], include_dirs=include_dirs)
+        return (src, obj)
+
+    def _link (self, body,
+               headers, include_dirs,
+               libraries, library_dirs, lang):
+        (src, obj) = self._compile(body, headers, include_dirs, lang)
+        prog = os.path.splitext(os.path.basename(src))[0]
+        self.compiler.link_executable([obj], prog,
+                                      libraries=libraries,
+                                      library_dirs=library_dirs,
+                                      target_lang=lang)
+
+        if self.compiler.exe_extension is not None:
+            prog = prog + self.compiler.exe_extension
+        self.temp_files.append(prog)
+
+        return (src, obj, prog)
+
+    def _clean (self, *filenames):
+        if not filenames:
+            filenames = self.temp_files
+            self.temp_files = []
+        log.info("removing: %s", string.join(filenames))
+        for filename in filenames:
+            try:
+                os.remove(filename)
+            except OSError:
+                pass
+
+
+    # XXX these ignore the dry-run flag: what to do, what to do? even if
+    # you want a dry-run build, you still need some sort of configuration
+    # info.  My inclination is to make it up to the real config command to
+    # consult 'dry_run', and assume a default (minimal) configuration if
+    # true.  The problem with trying to do it here is that you'd have to
+    # return either true or false from all the 'try' methods, neither of
+    # which is correct.
+
+    # XXX need access to the header search path and maybe default macros.
+
+    def try_cpp (self, body=None, headers=None, include_dirs=None, lang="c"):
+        """Construct a source file from 'body' (a string containing lines
+        of C/C++ code) and 'headers' (a list of header files to include)
+        and run it through the preprocessor.  Return true if the
+        preprocessor succeeded, false if there were any errors.
+        ('body' probably isn't of much use, but what the heck.)
+        """
+        from distutils.ccompiler import CompileError
+        self._check_compiler()
+        ok = 1
+        try:
+            self._preprocess(body, headers, include_dirs, lang)
+        except CompileError:
+            ok = 0
+
+        self._clean()
+        return ok
+
+    def search_cpp (self, pattern, body=None,
+                    headers=None, include_dirs=None, lang="c"):
+        """Construct a source file (just like 'try_cpp()'), run it through
+        the preprocessor, and return true if any line of the output matches
+        'pattern'.  'pattern' should either be a compiled regex object or a
+        string containing a regex.  If both 'body' and 'headers' are None,
+        preprocesses an empty file -- which can be useful to determine the
+        symbols the preprocessor and compiler set by default.
+        """
+
+        self._check_compiler()
+        (src, out) = self._preprocess(body, headers, include_dirs, lang)
+
+        if type(pattern) is StringType:
+            pattern = re.compile(pattern)
+
+        file = open(out)
+        match = 0
+        while 1:
+            line = file.readline()
+            if line == '':
+                break
+            if pattern.search(line):
+                match = 1
+                break
+
+        file.close()
+        self._clean()
+        return match
+
+    def try_compile (self, body, headers=None, include_dirs=None, lang="c"):
+        """Try to compile a source file built from 'body' and 'headers'.
+        Return true on success, false otherwise.
+        """
+        from distutils.ccompiler import CompileError
+        self._check_compiler()
+        try:
+            self._compile(body, headers, include_dirs, lang)
+            ok = 1
+        except CompileError:
+            ok = 0
+
+        log.info(ok and "success!" or "failure.")
+        self._clean()
+        return ok
+
+    def try_link (self, body,
+                  headers=None, include_dirs=None,
+                  libraries=None, library_dirs=None,
+                  lang="c"):
+        """Try to compile and link a source file, built from 'body' and
+        'headers', to executable form.  Return true on success, false
+        otherwise.
+        """
+        from distutils.ccompiler import CompileError, LinkError
+        self._check_compiler()
+        try:
+            self._link(body, headers, include_dirs,
+                       libraries, library_dirs, lang)
+            ok = 1
+        except (CompileError, LinkError):
+            ok = 0
+
+        log.info(ok and "success!" or "failure.")
+        self._clean()
+        return ok
+
+    def try_run (self, body,
+                 headers=None, include_dirs=None,
+                 libraries=None, library_dirs=None,
+                 lang="c"):
+        """Try to compile, link to an executable, and run a program
+        built from 'body' and 'headers'.  Return true on success, false
+        otherwise.
+        """
+        from distutils.ccompiler import CompileError, LinkError
+        self._check_compiler()
+        try:
+            src, obj, exe = self._link(body, headers, include_dirs,
+                                       libraries, library_dirs, lang)
+            self.spawn([exe])
+            ok = 1
+        except (CompileError, LinkError, DistutilsExecError):
+            ok = 0
+
+        log.info(ok and "success!" or "failure.")
+        self._clean()
+        return ok
+
+
+    # -- High-level methods --------------------------------------------
+    # (these are the ones that are actually likely to be useful
+    # when implementing a real-world config command!)
+
+    def check_func (self, func,
+                    headers=None, include_dirs=None,
+                    libraries=None, library_dirs=None,
+                    decl=0, call=0):
+
+        """Determine if function 'func' is available by constructing a
+        source file that refers to 'func', and compiles and links it.
+        If everything succeeds, returns true; otherwise returns false.
+
+        The constructed source file starts out by including the header
+        files listed in 'headers'.  If 'decl' is true, it then declares
+        'func' (as "int func()"); you probably shouldn't supply 'headers'
+        and set 'decl' true in the same call, or you might get errors about
+        a conflicting declarations for 'func'.  Finally, the constructed
+        'main()' function either references 'func' or (if 'call' is true)
+        calls it.  'libraries' and 'library_dirs' are used when
+        linking.
+        """
+
+        self._check_compiler()
+        body = []
+        if decl:
+            body.append("int %s ();" % func)
+        body.append("int main () {")
+        if call:
+            body.append("  %s();" % func)
+        else:
+            body.append("  %s;" % func)
+        body.append("}")
+        body = string.join(body, "\n") + "\n"
+
+        return self.try_link(body, headers, include_dirs,
+                             libraries, library_dirs)
+
+    # check_func ()
+
+    def check_lib (self, library, library_dirs=None,
+                   headers=None, include_dirs=None, other_libraries=[]):
+        """Determine if 'library' is available to be linked against,
+        without actually checking that any particular symbols are provided
+        by it.  'headers' will be used in constructing the source file to
+        be compiled, but the only effect of this is to check if all the
+        header files listed are available.  Any libraries listed in
+        'other_libraries' will be included in the link, in case 'library'
+        has symbols that depend on other libraries.
+        """
+        self._check_compiler()
+        return self.try_link("int main (void) { }",
+                             headers, include_dirs,
+                             [library]+other_libraries, library_dirs)
+
+    def check_header (self, header, include_dirs=None,
+                      library_dirs=None, lang="c"):
+        """Determine if the system header file named by 'header_file'
+        exists and can be found by the preprocessor; return true if so,
+        false otherwise.
+        """
+        return self.try_cpp(body="/* No body */", headers=[header],
+                            include_dirs=include_dirs)
+
+
+# class config
+
+
+def dump_file (filename, head=None):
+    if head is None:
+        print filename + ":"
+    else:
+        print head
+
+    file = open(filename)
+    sys.stdout.write(file.read())
+    file.close()

Added: vendor/Python/current/Lib/distutils/command/install.py
===================================================================
--- vendor/Python/current/Lib/distutils/command/install.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/command/install.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,607 @@
+"""distutils.command.install
+
+Implements the Distutils 'install' command."""
+
+from distutils import log
+
+# This module should be kept compatible with Python 2.1.
+
+__revision__ = "$Id: install.py 43363 2006-03-27 21:55:21Z phillip.eby $"
+
+import sys, os, string
+from types import *
+from distutils.core import Command
+from distutils.debug import DEBUG
+from distutils.sysconfig import get_config_vars
+from distutils.errors import DistutilsPlatformError
+from distutils.file_util import write_file
+from distutils.util import convert_path, subst_vars, change_root
+from distutils.errors import DistutilsOptionError
+from glob import glob
+
+if sys.version < "2.2":
+    WINDOWS_SCHEME = {
+        'purelib': '$base',
+        'platlib': '$base',
+        'headers': '$base/Include/$dist_name',
+        'scripts': '$base/Scripts',
+        'data'   : '$base',
+    }
+else:
+    WINDOWS_SCHEME = {
+        'purelib': '$base/Lib/site-packages',
+        'platlib': '$base/Lib/site-packages',
+        'headers': '$base/Include/$dist_name',
+        'scripts': '$base/Scripts',
+        'data'   : '$base',
+    }
+
+INSTALL_SCHEMES = {
+    'unix_prefix': {
+        'purelib': '$base/lib/python$py_version_short/site-packages',
+        'platlib': '$platbase/lib/python$py_version_short/site-packages',
+        'headers': '$base/include/python$py_version_short/$dist_name',
+        'scripts': '$base/bin',
+        'data'   : '$base',
+        },
+    'unix_home': {
+        'purelib': '$base/lib/python',
+        'platlib': '$base/lib/python',
+        'headers': '$base/include/python/$dist_name',
+        'scripts': '$base/bin',
+        'data'   : '$base',
+        },
+    'nt': WINDOWS_SCHEME,
+    'mac': {
+        'purelib': '$base/Lib/site-packages',
+        'platlib': '$base/Lib/site-packages',
+        'headers': '$base/Include/$dist_name',
+        'scripts': '$base/Scripts',
+        'data'   : '$base',
+        },
+    'os2': {
+        'purelib': '$base/Lib/site-packages',
+        'platlib': '$base/Lib/site-packages',
+        'headers': '$base/Include/$dist_name',
+        'scripts': '$base/Scripts',
+        'data'   : '$base',
+        }
+    }
+
+# The keys to an installation scheme; if any new types of files are to be
+# installed, be sure to add an entry to every installation scheme above,
+# and to SCHEME_KEYS here.
+SCHEME_KEYS = ('purelib', 'platlib', 'headers', 'scripts', 'data')
+
+
+class install (Command):
+
+    description = "install everything from build directory"
+
+    user_options = [
+        # Select installation scheme and set base director(y|ies)
+        ('prefix=', None,
+         "installation prefix"),
+        ('exec-prefix=', None,
+         "(Unix only) prefix for platform-specific files"),
+        ('home=', None,
+         "(Unix only) home directory to install under"),
+
+        # Or, just set the base director(y|ies)
+        ('install-base=', None,
+         "base installation directory (instead of --prefix or --home)"),
+        ('install-platbase=', None,
+         "base installation directory for platform-specific files " +
+         "(instead of --exec-prefix or --home)"),
+        ('root=', None,
+         "install everything relative to this alternate root directory"),
+
+        # Or, explicitly set the installation scheme
+        ('install-purelib=', None,
+         "installation directory for pure Python module distributions"),
+        ('install-platlib=', None,
+         "installation directory for non-pure module distributions"),
+        ('install-lib=', None,
+         "installation directory for all module distributions " +
+         "(overrides --install-purelib and --install-platlib)"),
+
+        ('install-headers=', None,
+         "installation directory for C/C++ headers"),
+        ('install-scripts=', None,
+         "installation directory for Python scripts"),
+        ('install-data=', None,
+         "installation directory for data files"),
+
+        # Byte-compilation options -- see install_lib.py for details, as
+        # these are duplicated from there (but only install_lib does
+        # anything with them).
+        ('compile', 'c', "compile .py to .pyc [default]"),
+        ('no-compile', None, "don't compile .py files"),
+        ('optimize=', 'O',
+         "also compile with optimization: -O1 for \"python -O\", "
+         "-O2 for \"python -OO\", and -O0 to disable [default: -O0]"),
+
+        # Miscellaneous control options
+        ('force', 'f',
+         "force installation (overwrite any existing files)"),
+        ('skip-build', None,
+         "skip rebuilding everything (for testing/debugging)"),
+
+        # Where to install documentation (eventually!)
+        #('doc-format=', None, "format of documentation to generate"),
+        #('install-man=', None, "directory for Unix man pages"),
+        #('install-html=', None, "directory for HTML documentation"),
+        #('install-info=', None, "directory for GNU info files"),
+
+        ('record=', None,
+         "filename in which to record list of installed files"),
+        ]
+
+    boolean_options = ['compile', 'force', 'skip-build']
+    negative_opt = {'no-compile' : 'compile'}
+
+
+    def initialize_options (self):
+
+        # High-level options: these select both an installation base
+        # and scheme.
+        self.prefix = None
+        self.exec_prefix = None
+        self.home = None
+
+        # These select only the installation base; it's up to the user to
+        # specify the installation scheme (currently, that means supplying
+        # the --install-{platlib,purelib,scripts,data} options).
+        self.install_base = None
+        self.install_platbase = None
+        self.root = None
+
+        # These options are the actual installation directories; if not
+        # supplied by the user, they are filled in using the installation
+        # scheme implied by prefix/exec-prefix/home and the contents of
+        # that installation scheme.
+        self.install_purelib = None     # for pure module distributions
+        self.install_platlib = None     # non-pure (dists w/ extensions)
+        self.install_headers = None     # for C/C++ headers
+        self.install_lib = None         # set to either purelib or platlib
+        self.install_scripts = None
+        self.install_data = None
+
+        self.compile = None
+        self.optimize = None
+
+        # These two are for putting non-packagized distributions into their
+        # own directory and creating a .pth file if it makes sense.
+        # 'extra_path' comes from the setup file; 'install_path_file' can
+        # be turned off if it makes no sense to install a .pth file.  (But
+        # better to install it uselessly than to guess wrong and not
+        # install it when it's necessary and would be used!)  Currently,
+        # 'install_path_file' is always true unless some outsider meddles
+        # with it.
+        self.extra_path = None
+        self.install_path_file = 1
+
+        # 'force' forces installation, even if target files are not
+        # out-of-date.  'skip_build' skips running the "build" command,
+        # handy if you know it's not necessary.  'warn_dir' (which is *not*
+        # a user option, it's just there so the bdist_* commands can turn
+        # it off) determines whether we warn about installing to a
+        # directory not in sys.path.
+        self.force = 0
+        self.skip_build = 0
+        self.warn_dir = 1
+
+        # These are only here as a conduit from the 'build' command to the
+        # 'install_*' commands that do the real work.  ('build_base' isn't
+        # actually used anywhere, but it might be useful in future.)  They
+        # are not user options, because if the user told the install
+        # command where the build directory is, that wouldn't affect the
+        # build command.
+        self.build_base = None
+        self.build_lib = None
+
+        # Not defined yet because we don't know anything about
+        # documentation yet.
+        #self.install_man = None
+        #self.install_html = None
+        #self.install_info = None
+
+        self.record = None
+
+
+    # -- Option finalizing methods -------------------------------------
+    # (This is rather more involved than for most commands,
+    # because this is where the policy for installing third-
+    # party Python modules on various platforms given a wide
+    # array of user input is decided.  Yes, it's quite complex!)
+
+    def finalize_options (self):
+
+        # This method (and its pliant slaves, like 'finalize_unix()',
+        # 'finalize_other()', and 'select_scheme()') is where the default
+        # installation directories for modules, extension modules, and
+        # anything else we care to install from a Python module
+        # distribution.  Thus, this code makes a pretty important policy
+        # statement about how third-party stuff is added to a Python
+        # installation!  Note that the actual work of installation is done
+        # by the relatively simple 'install_*' commands; they just take
+        # their orders from the installation directory options determined
+        # here.
+
+        # Check for errors/inconsistencies in the options; first, stuff
+        # that's wrong on any platform.
+
+        if ((self.prefix or self.exec_prefix or self.home) and
+            (self.install_base or self.install_platbase)):
+            raise DistutilsOptionError, \
+                  ("must supply either prefix/exec-prefix/home or " +
+                   "install-base/install-platbase -- not both")
+
+        if self.home and (self.prefix or self.exec_prefix):
+            raise DistutilsOptionError, \
+                  "must supply either home or prefix/exec-prefix -- not both"
+
+        # Next, stuff that's wrong (or dubious) only on certain platforms.
+        if os.name != "posix":
+            if self.exec_prefix:
+                self.warn("exec-prefix option ignored on this platform")
+                self.exec_prefix = None
+
+        # Now the interesting logic -- so interesting that we farm it out
+        # to other methods.  The goal of these methods is to set the final
+        # values for the install_{lib,scripts,data,...}  options, using as
+        # input a heady brew of prefix, exec_prefix, home, install_base,
+        # install_platbase, user-supplied versions of
+        # install_{purelib,platlib,lib,scripts,data,...}, and the
+        # INSTALL_SCHEME dictionary above.  Phew!
+
+        self.dump_dirs("pre-finalize_{unix,other}")
+
+        if os.name == 'posix':
+            self.finalize_unix()
+        else:
+            self.finalize_other()
+
+        self.dump_dirs("post-finalize_{unix,other}()")
+
+        # Expand configuration variables, tilde, etc. in self.install_base
+        # and self.install_platbase -- that way, we can use $base or
+        # $platbase in the other installation directories and not worry
+        # about needing recursive variable expansion (shudder).
+
+        py_version = (string.split(sys.version))[0]
+        (prefix, exec_prefix) = get_config_vars('prefix', 'exec_prefix')
+        self.config_vars = {'dist_name': self.distribution.get_name(),
+                            'dist_version': self.distribution.get_version(),
+                            'dist_fullname': self.distribution.get_fullname(),
+                            'py_version': py_version,
+                            'py_version_short': py_version[0:3],
+                            'sys_prefix': prefix,
+                            'prefix': prefix,
+                            'sys_exec_prefix': exec_prefix,
+                            'exec_prefix': exec_prefix,
+                           }
+        self.expand_basedirs()
+
+        self.dump_dirs("post-expand_basedirs()")
+
+        # Now define config vars for the base directories so we can expand
+        # everything else.
+        self.config_vars['base'] = self.install_base
+        self.config_vars['platbase'] = self.install_platbase
+
+        if DEBUG:
+            from pprint import pprint
+            print "config vars:"
+            pprint(self.config_vars)
+
+        # Expand "~" and configuration variables in the installation
+        # directories.
+        self.expand_dirs()
+
+        self.dump_dirs("post-expand_dirs()")
+
+        # Pick the actual directory to install all modules to: either
+        # install_purelib or install_platlib, depending on whether this
+        # module distribution is pure or not.  Of course, if the user
+        # already specified install_lib, use their selection.
+        if self.install_lib is None:
+            if self.distribution.ext_modules: # has extensions: non-pure
+                self.install_lib = self.install_platlib
+            else:
+                self.install_lib = self.install_purelib
+
+
+        # Convert directories from Unix /-separated syntax to the local
+        # convention.
+        self.convert_paths('lib', 'purelib', 'platlib',
+                           'scripts', 'data', 'headers')
+
+        # Well, we're not actually fully completely finalized yet: we still
+        # have to deal with 'extra_path', which is the hack for allowing
+        # non-packagized module distributions (hello, Numerical Python!) to
+        # get their own directories.
+        self.handle_extra_path()
+        self.install_libbase = self.install_lib # needed for .pth file
+        self.install_lib = os.path.join(self.install_lib, self.extra_dirs)
+
+        # If a new root directory was supplied, make all the installation
+        # dirs relative to it.
+        if self.root is not None:
+            self.change_roots('libbase', 'lib', 'purelib', 'platlib',
+                              'scripts', 'data', 'headers')
+
+        self.dump_dirs("after prepending root")
+
+        # Find out the build directories, ie. where to install from.
+        self.set_undefined_options('build',
+                                   ('build_base', 'build_base'),
+                                   ('build_lib', 'build_lib'))
+
+        # Punt on doc directories for now -- after all, we're punting on
+        # documentation completely!
+
+    # finalize_options ()
+
+
+    def dump_dirs (self, msg):
+        if DEBUG:
+            from distutils.fancy_getopt import longopt_xlate
+            print msg + ":"
+            for opt in self.user_options:
+                opt_name = opt[0]
+                if opt_name[-1] == "=":
+                    opt_name = opt_name[0:-1]
+                if self.negative_opt.has_key(opt_name):
+                    opt_name = string.translate(self.negative_opt[opt_name],
+                                                longopt_xlate)
+                    val = not getattr(self, opt_name)
+                else:
+                    opt_name = string.translate(opt_name, longopt_xlate)
+                    val = getattr(self, opt_name)
+                print "  %s: %s" % (opt_name, val)
+
+
+    def finalize_unix (self):
+
+        if self.install_base is not None or self.install_platbase is not None:
+            if ((self.install_lib is None and
+                 self.install_purelib is None and
+                 self.install_platlib is None) or
+                self.install_headers is None or
+                self.install_scripts is None or
+                self.install_data is None):
+                raise DistutilsOptionError, \
+                      ("install-base or install-platbase supplied, but "
+                      "installation scheme is incomplete")
+            return
+
+        if self.home is not None:
+            self.install_base = self.install_platbase = self.home
+            self.select_scheme("unix_home")
+        else:
+            if self.prefix is None:
+                if self.exec_prefix is not None:
+                    raise DistutilsOptionError, \
+                          "must not supply exec-prefix without prefix"
+
+                self.prefix = os.path.normpath(sys.prefix)
+                self.exec_prefix = os.path.normpath(sys.exec_prefix)
+
+            else:
+                if self.exec_prefix is None:
+                    self.exec_prefix = self.prefix
+
+            self.install_base = self.prefix
+            self.install_platbase = self.exec_prefix
+            self.select_scheme("unix_prefix")
+
+    # finalize_unix ()
+
+
+    def finalize_other (self):          # Windows and Mac OS for now
+
+        if self.home is not None:
+            self.install_base = self.install_platbase = self.home
+            self.select_scheme("unix_home")
+        else:
+            if self.prefix is None:
+                self.prefix = os.path.normpath(sys.prefix)
+
+            self.install_base = self.install_platbase = self.prefix
+            try:
+                self.select_scheme(os.name)
+            except KeyError:
+                raise DistutilsPlatformError, \
+                      "I don't know how to install stuff on '%s'" % os.name
+
+    # finalize_other ()
+
+
+    def select_scheme (self, name):
+        # it's the caller's problem if they supply a bad name!
+        scheme = INSTALL_SCHEMES[name]
+        for key in SCHEME_KEYS:
+            attrname = 'install_' + key
+            if getattr(self, attrname) is None:
+                setattr(self, attrname, scheme[key])
+
+
+    def _expand_attrs (self, attrs):
+        for attr in attrs:
+            val = getattr(self, attr)
+            if val is not None:
+                if os.name == 'posix':
+                    val = os.path.expanduser(val)
+                val = subst_vars(val, self.config_vars)
+                setattr(self, attr, val)
+
+
+    def expand_basedirs (self):
+        self._expand_attrs(['install_base',
+                            'install_platbase',
+                            'root'])
+
+    def expand_dirs (self):
+        self._expand_attrs(['install_purelib',
+                            'install_platlib',
+                            'install_lib',
+                            'install_headers',
+                            'install_scripts',
+                            'install_data',])
+
+
+    def convert_paths (self, *names):
+        for name in names:
+            attr = "install_" + name
+            setattr(self, attr, convert_path(getattr(self, attr)))
+
+
+    def handle_extra_path (self):
+
+        if self.extra_path is None:
+            self.extra_path = self.distribution.extra_path
+
+        if self.extra_path is not None:
+            if type(self.extra_path) is StringType:
+                self.extra_path = string.split(self.extra_path, ',')
+
+            if len(self.extra_path) == 1:
+                path_file = extra_dirs = self.extra_path[0]
+            elif len(self.extra_path) == 2:
+                (path_file, extra_dirs) = self.extra_path
+            else:
+                raise DistutilsOptionError, \
+                      ("'extra_path' option must be a list, tuple, or "
+                      "comma-separated string with 1 or 2 elements")
+
+            # convert to local form in case Unix notation used (as it
+            # should be in setup scripts)
+            extra_dirs = convert_path(extra_dirs)
+
+        else:
+            path_file = None
+            extra_dirs = ''
+
+        # XXX should we warn if path_file and not extra_dirs? (in which
+        # case the path file would be harmless but pointless)
+        self.path_file = path_file
+        self.extra_dirs = extra_dirs
+
+    # handle_extra_path ()
+
+
+    def change_roots (self, *names):
+        for name in names:
+            attr = "install_" + name
+            setattr(self, attr, change_root(self.root, getattr(self, attr)))
+
+
+    # -- Command execution methods -------------------------------------
+
+    def run (self):
+
+        # Obviously have to build before we can install
+        if not self.skip_build:
+            self.run_command('build')
+
+        # Run all sub-commands (at least those that need to be run)
+        for cmd_name in self.get_sub_commands():
+            self.run_command(cmd_name)
+
+        if self.path_file:
+            self.create_path_file()
+
+        # write list of installed files, if requested.
+        if self.record:
+            outputs = self.get_outputs()
+            if self.root:               # strip any package prefix
+                root_len = len(self.root)
+                for counter in xrange(len(outputs)):
+                    outputs[counter] = outputs[counter][root_len:]
+            self.execute(write_file,
+                         (self.record, outputs),
+                         "writing list of installed files to '%s'" %
+                         self.record)
+
+        sys_path = map(os.path.normpath, sys.path)
+        sys_path = map(os.path.normcase, sys_path)
+        install_lib = os.path.normcase(os.path.normpath(self.install_lib))
+        if (self.warn_dir and
+            not (self.path_file and self.install_path_file) and
+            install_lib not in sys_path):
+            log.debug(("modules installed to '%s', which is not in "
+                       "Python's module search path (sys.path) -- "
+                       "you'll have to change the search path yourself"),
+                       self.install_lib)
+
+    # run ()
+
+    def create_path_file (self):
+        filename = os.path.join(self.install_libbase,
+                                self.path_file + ".pth")
+        if self.install_path_file:
+            self.execute(write_file,
+                         (filename, [self.extra_dirs]),
+                         "creating %s" % filename)
+        else:
+            self.warn("path file '%s' not created" % filename)
+
+
+    # -- Reporting methods ---------------------------------------------
+
+    def get_outputs (self):
+        # Assemble the outputs of all the sub-commands.
+        outputs = []
+        for cmd_name in self.get_sub_commands():
+            cmd = self.get_finalized_command(cmd_name)
+            # Add the contents of cmd.get_outputs(), ensuring
+            # that outputs doesn't contain duplicate entries
+            for filename in cmd.get_outputs():
+                if filename not in outputs:
+                    outputs.append(filename)
+
+        if self.path_file and self.install_path_file:
+            outputs.append(os.path.join(self.install_libbase,
+                                        self.path_file + ".pth"))
+
+        return outputs
+
+    def get_inputs (self):
+        # XXX gee, this looks familiar ;-(
+        inputs = []
+        for cmd_name in self.get_sub_commands():
+            cmd = self.get_finalized_command(cmd_name)
+            inputs.extend(cmd.get_inputs())
+
+        return inputs
+
+
+    # -- Predicates for sub-command list -------------------------------
+
+    def has_lib (self):
+        """Return true if the current distribution has any Python
+        modules to install."""
+        return (self.distribution.has_pure_modules() or
+                self.distribution.has_ext_modules())
+
+    def has_headers (self):
+        return self.distribution.has_headers()
+
+    def has_scripts (self):
+        return self.distribution.has_scripts()
+
+    def has_data (self):
+        return self.distribution.has_data_files()
+
+
+    # 'sub_commands': a list of commands this command might have to run to
+    # get its work done.  See cmd.py for more info.
+    sub_commands = [('install_lib',     has_lib),
+                    ('install_headers', has_headers),
+                    ('install_scripts', has_scripts),
+                    ('install_data',    has_data),
+                    ('install_egg_info', lambda self:True),
+                   ]
+
+# class install

Added: vendor/Python/current/Lib/distutils/command/install_data.py
===================================================================
--- vendor/Python/current/Lib/distutils/command/install_data.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/command/install_data.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,85 @@
+"""distutils.command.install_data
+
+Implements the Distutils 'install_data' command, for installing
+platform-independent data files."""
+
+# contributed by Bastian Kleineidam
+
+# This module should be kept compatible with Python 2.1.
+
+__revision__ = "$Id: install_data.py 37828 2004-11-10 22:23:15Z loewis $"
+
+import os
+from types import StringType
+from distutils.core import Command
+from distutils.util import change_root, convert_path
+
+class install_data (Command):
+
+    description = "install data files"
+
+    user_options = [
+        ('install-dir=', 'd',
+         "base directory for installing data files "
+         "(default: installation base dir)"),
+        ('root=', None,
+         "install everything relative to this alternate root directory"),
+        ('force', 'f', "force installation (overwrite existing files)"),
+        ]
+
+    boolean_options = ['force']
+
+    def initialize_options (self):
+        self.install_dir = None
+        self.outfiles = []
+        self.root = None
+        self.force = 0
+
+        self.data_files = self.distribution.data_files
+        self.warn_dir = 1
+
+    def finalize_options (self):
+        self.set_undefined_options('install',
+                                   ('install_data', 'install_dir'),
+                                   ('root', 'root'),
+                                   ('force', 'force'),
+                                  )
+
+    def run (self):
+        self.mkpath(self.install_dir)
+        for f in self.data_files:
+            if type(f) is StringType:
+                # it's a simple file, so copy it
+                f = convert_path(f)
+                if self.warn_dir:
+                    self.warn("setup script did not provide a directory for "
+                              "'%s' -- installing right in '%s'" %
+                              (f, self.install_dir))
+                (out, _) = self.copy_file(f, self.install_dir)
+                self.outfiles.append(out)
+            else:
+                # it's a tuple with path to install to and a list of files
+                dir = convert_path(f[0])
+                if not os.path.isabs(dir):
+                    dir = os.path.join(self.install_dir, dir)
+                elif self.root:
+                    dir = change_root(self.root, dir)
+                self.mkpath(dir)
+
+                if f[1] == []:
+                    # If there are no files listed, the user must be
+                    # trying to create an empty directory, so add the
+                    # directory to the list of output files.
+                    self.outfiles.append(dir)
+                else:
+                    # Copy files, adding them to the list of output files.
+                    for data in f[1]:
+                        data = convert_path(data)
+                        (out, _) = self.copy_file(data, dir)
+                        self.outfiles.append(out)
+
+    def get_inputs (self):
+        return self.data_files or []
+
+    def get_outputs (self):
+        return self.outfiles

Added: vendor/Python/current/Lib/distutils/command/install_egg_info.py
===================================================================
--- vendor/Python/current/Lib/distutils/command/install_egg_info.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/command/install_egg_info.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,78 @@
+"""distutils.command.install_egg_info
+
+Implements the Distutils 'install_egg_info' command, for installing
+a package's PKG-INFO metadata."""
+
+
+from distutils.cmd import Command
+from distutils import log, dir_util
+import os, sys, re
+
+class install_egg_info(Command):
+    """Install an .egg-info file for the package"""
+
+    description = "Install package's PKG-INFO metadata as an .egg-info file"
+    user_options = [
+        ('install-dir=', 'd', "directory to install to"),
+    ]
+
+    def initialize_options(self):
+        self.install_dir = None
+
+    def finalize_options(self):
+        self.set_undefined_options('install_lib',('install_dir','install_dir'))
+        basename = "%s-%s-py%s.egg-info" % (
+            to_filename(safe_name(self.distribution.get_name())),
+            to_filename(safe_version(self.distribution.get_version())),
+            sys.version[:3]
+        )
+        self.target = os.path.join(self.install_dir, basename)
+        self.outputs = [self.target]
+
+    def run(self):
+        target = self.target
+        if os.path.isdir(target) and not os.path.islink(target):
+            dir_util.remove_tree(target, dry_run=self.dry_run)
+        elif os.path.exists(target):
+            self.execute(os.unlink,(self.target,),"Removing "+target)
+        elif not os.path.isdir(self.install_dir):
+            self.execute(os.makedirs, (self.install_dir,),
+                         "Creating "+self.install_dir)
+        log.info("Writing %s", target)
+        if not self.dry_run:
+            f = open(target, 'w')
+            self.distribution.metadata.write_pkg_file(f)
+            f.close()
+
+    def get_outputs(self):
+        return self.outputs
+
+
+# The following routines are taken from setuptools' pkg_resources module and
+# can be replaced by importing them from pkg_resources once it is included
+# in the stdlib.
+
+def safe_name(name):
+    """Convert an arbitrary string to a standard distribution name
+
+    Any runs of non-alphanumeric/. characters are replaced with a single '-'.
+    """
+    return re.sub('[^A-Za-z0-9.]+', '-', name)
+
+
+def safe_version(version):
+    """Convert an arbitrary string to a standard version string
+
+    Spaces become dots, and all other non-alphanumeric characters become
+    dashes, with runs of multiple dashes condensed to a single dash.
+    """
+    version = version.replace(' ','.')
+    return re.sub('[^A-Za-z0-9.]+', '-', version)
+
+
+def to_filename(name):
+    """Convert a project or version name to its filename-escaped form
+
+    Any '-' characters are currently replaced with '_'.
+    """
+    return name.replace('-','_')

Added: vendor/Python/current/Lib/distutils/command/install_headers.py
===================================================================
--- vendor/Python/current/Lib/distutils/command/install_headers.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/command/install_headers.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,53 @@
+"""distutils.command.install_headers
+
+Implements the Distutils 'install_headers' command, to install C/C++ header
+files to the Python include directory."""
+
+# This module should be kept compatible with Python 2.1.
+
+__revision__ = "$Id: install_headers.py 37828 2004-11-10 22:23:15Z loewis $"
+
+import os
+from distutils.core import Command
+
+
+class install_headers (Command):
+
+    description = "install C/C++ header files"
+
+    user_options = [('install-dir=', 'd',
+                     "directory to install header files to"),
+                    ('force', 'f',
+                     "force installation (overwrite existing files)"),
+                   ]
+
+    boolean_options = ['force']
+
+    def initialize_options (self):
+        self.install_dir = None
+        self.force = 0
+        self.outfiles = []
+
+    def finalize_options (self):
+        self.set_undefined_options('install',
+                                   ('install_headers', 'install_dir'),
+                                   ('force', 'force'))
+
+
+    def run (self):
+        headers = self.distribution.headers
+        if not headers:
+            return
+
+        self.mkpath(self.install_dir)
+        for header in headers:
+            (out, _) = self.copy_file(header, self.install_dir)
+            self.outfiles.append(out)
+
+    def get_inputs (self):
+        return self.distribution.headers or []
+
+    def get_outputs (self):
+        return self.outfiles
+
+# class install_headers

Added: vendor/Python/current/Lib/distutils/command/install_lib.py
===================================================================
--- vendor/Python/current/Lib/distutils/command/install_lib.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/command/install_lib.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,223 @@
+# This module should be kept compatible with Python 2.1.
+
+__revision__ = "$Id: install_lib.py 37946 2004-12-02 20:14:16Z lemburg $"
+
+import sys, os, string
+from types import IntType
+from distutils.core import Command
+from distutils.errors import DistutilsOptionError
+
+
+# Extension for Python source files.
+if hasattr(os, 'extsep'):
+    PYTHON_SOURCE_EXTENSION = os.extsep + "py"
+else:
+    PYTHON_SOURCE_EXTENSION = ".py"
+
+class install_lib (Command):
+
+    description = "install all Python modules (extensions and pure Python)"
+
+    # The byte-compilation options are a tad confusing.  Here are the
+    # possible scenarios:
+    #   1) no compilation at all (--no-compile --no-optimize)
+    #   2) compile .pyc only (--compile --no-optimize; default)
+    #   3) compile .pyc and "level 1" .pyo (--compile --optimize)
+    #   4) compile "level 1" .pyo only (--no-compile --optimize)
+    #   5) compile .pyc and "level 2" .pyo (--compile --optimize-more)
+    #   6) compile "level 2" .pyo only (--no-compile --optimize-more)
+    #
+    # The UI for this is two option, 'compile' and 'optimize'.
+    # 'compile' is strictly boolean, and only decides whether to
+    # generate .pyc files.  'optimize' is three-way (0, 1, or 2), and
+    # decides both whether to generate .pyo files and what level of
+    # optimization to use.
+
+    user_options = [
+        ('install-dir=', 'd', "directory to install to"),
+        ('build-dir=','b', "build directory (where to install from)"),
+        ('force', 'f', "force installation (overwrite existing files)"),
+        ('compile', 'c', "compile .py to .pyc [default]"),
+        ('no-compile', None, "don't compile .py files"),
+        ('optimize=', 'O',
+         "also compile with optimization: -O1 for \"python -O\", "
+         "-O2 for \"python -OO\", and -O0 to disable [default: -O0]"),
+        ('skip-build', None, "skip the build steps"),
+        ]
+
+    boolean_options = ['force', 'compile', 'skip-build']
+    negative_opt = {'no-compile' : 'compile'}
+
+
+    def initialize_options (self):
+        # let the 'install' command dictate our installation directory
+        self.install_dir = None
+        self.build_dir = None
+        self.force = 0
+        self.compile = None
+        self.optimize = None
+        self.skip_build = None
+
+    def finalize_options (self):
+
+        # Get all the information we need to install pure Python modules
+        # from the umbrella 'install' command -- build (source) directory,
+        # install (target) directory, and whether to compile .py files.
+        self.set_undefined_options('install',
+                                   ('build_lib', 'build_dir'),
+                                   ('install_lib', 'install_dir'),
+                                   ('force', 'force'),
+                                   ('compile', 'compile'),
+                                   ('optimize', 'optimize'),
+                                   ('skip_build', 'skip_build'),
+                                  )
+
+        if self.compile is None:
+            self.compile = 1
+        if self.optimize is None:
+            self.optimize = 0
+
+        if type(self.optimize) is not IntType:
+            try:
+                self.optimize = int(self.optimize)
+                assert 0 <= self.optimize <= 2
+            except (ValueError, AssertionError):
+                raise DistutilsOptionError, "optimize must be 0, 1, or 2"
+
+    def run (self):
+
+        # Make sure we have built everything we need first
+        self.build()
+
+        # Install everything: simply dump the entire contents of the build
+        # directory to the installation directory (that's the beauty of
+        # having a build directory!)
+        outfiles = self.install()
+
+        # (Optionally) compile .py to .pyc
+        if outfiles is not None and self.distribution.has_pure_modules():
+            self.byte_compile(outfiles)
+
+    # run ()
+
+
+    # -- Top-level worker functions ------------------------------------
+    # (called from 'run()')
+
+    def build (self):
+        if not self.skip_build:
+            if self.distribution.has_pure_modules():
+                self.run_command('build_py')
+            if self.distribution.has_ext_modules():
+                self.run_command('build_ext')
+
+    def install (self):
+        if os.path.isdir(self.build_dir):
+            outfiles = self.copy_tree(self.build_dir, self.install_dir)
+        else:
+            self.warn("'%s' does not exist -- no Python modules to install" %
+                      self.build_dir)
+            return
+        return outfiles
+
+    def byte_compile (self, files):
+        from distutils.util import byte_compile
+
+        # Get the "--root" directory supplied to the "install" command,
+        # and use it as a prefix to strip off the purported filename
+        # encoded in bytecode files.  This is far from complete, but it
+        # should at least generate usable bytecode in RPM distributions.
+        install_root = self.get_finalized_command('install').root
+
+        if self.compile:
+            byte_compile(files, optimize=0,
+                         force=self.force, prefix=install_root,
+                         dry_run=self.dry_run)
+        if self.optimize > 0:
+            byte_compile(files, optimize=self.optimize,
+                         force=self.force, prefix=install_root,
+                         verbose=self.verbose, dry_run=self.dry_run)
+
+
+    # -- Utility methods -----------------------------------------------
+
+    def _mutate_outputs (self, has_any, build_cmd, cmd_option, output_dir):
+
+        if not has_any:
+            return []
+
+        build_cmd = self.get_finalized_command(build_cmd)
+        build_files = build_cmd.get_outputs()
+        build_dir = getattr(build_cmd, cmd_option)
+
+        prefix_len = len(build_dir) + len(os.sep)
+        outputs = []
+        for file in build_files:
+            outputs.append(os.path.join(output_dir, file[prefix_len:]))
+
+        return outputs
+
+    # _mutate_outputs ()
+
+    def _bytecode_filenames (self, py_filenames):
+        bytecode_files = []
+        for py_file in py_filenames:
+            # Since build_py handles package data installation, the
+            # list of outputs can contain more than just .py files.
+            # Make sure we only report bytecode for the .py files.
+            ext = os.path.splitext(os.path.normcase(py_file))[1]
+            if ext != PYTHON_SOURCE_EXTENSION:
+                continue
+            if self.compile:
+                bytecode_files.append(py_file + "c")
+            if self.optimize > 0:
+                bytecode_files.append(py_file + "o")
+
+        return bytecode_files
+
+
+    # -- External interface --------------------------------------------
+    # (called by outsiders)
+
+    def get_outputs (self):
+        """Return the list of files that would be installed if this command
+        were actually run.  Not affected by the "dry-run" flag or whether
+        modules have actually been built yet.
+        """
+        pure_outputs = \
+            self._mutate_outputs(self.distribution.has_pure_modules(),
+                                 'build_py', 'build_lib',
+                                 self.install_dir)
+        if self.compile:
+            bytecode_outputs = self._bytecode_filenames(pure_outputs)
+        else:
+            bytecode_outputs = []
+
+        ext_outputs = \
+            self._mutate_outputs(self.distribution.has_ext_modules(),
+                                 'build_ext', 'build_lib',
+                                 self.install_dir)
+
+        return pure_outputs + bytecode_outputs + ext_outputs
+
+    # get_outputs ()
+
+    def get_inputs (self):
+        """Get the list of files that are input to this command, ie. the
+        files that get installed as they are named in the build tree.
+        The files in this list correspond one-to-one to the output
+        filenames returned by 'get_outputs()'.
+        """
+        inputs = []
+
+        if self.distribution.has_pure_modules():
+            build_py = self.get_finalized_command('build_py')
+            inputs.extend(build_py.get_outputs())
+
+        if self.distribution.has_ext_modules():
+            build_ext = self.get_finalized_command('build_ext')
+            inputs.extend(build_ext.get_outputs())
+
+        return inputs
+
+# class install_lib

Added: vendor/Python/current/Lib/distutils/command/install_scripts.py
===================================================================
--- vendor/Python/current/Lib/distutils/command/install_scripts.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/command/install_scripts.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,66 @@
+"""distutils.command.install_scripts
+
+Implements the Distutils 'install_scripts' command, for installing
+Python scripts."""
+
+# contributed by Bastian Kleineidam
+
+# This module should be kept compatible with Python 2.1.
+
+__revision__ = "$Id: install_scripts.py 37828 2004-11-10 22:23:15Z loewis $"
+
+import os
+from distutils.core import Command
+from distutils import log
+from stat import ST_MODE
+
+class install_scripts (Command):
+
+    description = "install scripts (Python or otherwise)"
+
+    user_options = [
+        ('install-dir=', 'd', "directory to install scripts to"),
+        ('build-dir=','b', "build directory (where to install from)"),
+        ('force', 'f', "force installation (overwrite existing files)"),
+        ('skip-build', None, "skip the build steps"),
+    ]
+
+    boolean_options = ['force', 'skip-build']
+
+
+    def initialize_options (self):
+        self.install_dir = None
+        self.force = 0
+        self.build_dir = None
+        self.skip_build = None
+
+    def finalize_options (self):
+        self.set_undefined_options('build', ('build_scripts', 'build_dir'))
+        self.set_undefined_options('install',
+                                   ('install_scripts', 'install_dir'),
+                                   ('force', 'force'),
+                                   ('skip_build', 'skip_build'),
+                                  )
+
+    def run (self):
+        if not self.skip_build:
+            self.run_command('build_scripts')
+        self.outfiles = self.copy_tree(self.build_dir, self.install_dir)
+        if os.name == 'posix':
+            # Set the executable bits (owner, group, and world) on
+            # all the scripts we just installed.
+            for file in self.get_outputs():
+                if self.dry_run:
+                    log.info("changing mode of %s", file)
+                else:
+                    mode = ((os.stat(file)[ST_MODE]) | 0555) & 07777
+                    log.info("changing mode of %s to %o", file, mode)
+                    os.chmod(file, mode)
+
+    def get_inputs (self):
+        return self.distribution.scripts or []
+
+    def get_outputs(self):
+        return self.outfiles or []
+
+# class install_scripts

Added: vendor/Python/current/Lib/distutils/command/register.py
===================================================================
--- vendor/Python/current/Lib/distutils/command/register.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/command/register.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,294 @@
+"""distutils.command.register
+
+Implements the Distutils 'register' command (register with the repository).
+"""
+
+# created 2002/10/21, Richard Jones
+
+__revision__ = "$Id: register.py 52243 2006-10-09 17:13:26Z andrew.kuchling $"
+
+import sys, os, string, urllib2, getpass, urlparse
+import StringIO, ConfigParser
+
+from distutils.core import Command
+from distutils.errors import *
+
+class register(Command):
+
+    description = ("register the distribution with the Python package index")
+
+    DEFAULT_REPOSITORY = 'http://www.python.org/pypi'
+
+    user_options = [
+        ('repository=', 'r',
+         "url of repository [default: %s]"%DEFAULT_REPOSITORY),
+        ('list-classifiers', None,
+         'list the valid Trove classifiers'),
+        ('show-response', None,
+         'display full response text from server'),
+        ]
+    boolean_options = ['verify', 'show-response', 'list-classifiers']
+
+    def initialize_options(self):
+        self.repository = None
+        self.show_response = 0
+        self.list_classifiers = 0
+
+    def finalize_options(self):
+        if self.repository is None:
+            self.repository = self.DEFAULT_REPOSITORY
+
+    def run(self):
+        self.check_metadata()
+        if self.dry_run:
+            self.verify_metadata()
+        elif self.list_classifiers:
+            self.classifiers()
+        else:
+            self.send_metadata()
+
+    def check_metadata(self):
+        """Ensure that all required elements of meta-data (name, version,
+           URL, (author and author_email) or (maintainer and
+           maintainer_email)) are supplied by the Distribution object; warn if
+           any are missing.
+        """
+        metadata = self.distribution.metadata
+
+        missing = []
+        for attr in ('name', 'version', 'url'):
+            if not (hasattr(metadata, attr) and getattr(metadata, attr)):
+                missing.append(attr)
+
+        if missing:
+            self.warn("missing required meta-data: " +
+                      string.join(missing, ", "))
+
+        if metadata.author:
+            if not metadata.author_email:
+                self.warn("missing meta-data: if 'author' supplied, " +
+                          "'author_email' must be supplied too")
+        elif metadata.maintainer:
+            if not metadata.maintainer_email:
+                self.warn("missing meta-data: if 'maintainer' supplied, " +
+                          "'maintainer_email' must be supplied too")
+        else:
+            self.warn("missing meta-data: either (author and author_email) " +
+                      "or (maintainer and maintainer_email) " +
+                      "must be supplied")
+
+    def classifiers(self):
+        ''' Fetch the list of classifiers from the server.
+        '''
+        response = urllib2.urlopen(self.repository+'?:action=list_classifiers')
+        print response.read()
+
+    def verify_metadata(self):
+        ''' Send the metadata to the package index server to be checked.
+        '''
+        # send the info to the server and report the result
+        (code, result) = self.post_to_server(self.build_post_data('verify'))
+        print 'Server response (%s): %s'%(code, result)
+
+    def send_metadata(self):
+        ''' Send the metadata to the package index server.
+
+            Well, do the following:
+            1. figure who the user is, and then
+            2. send the data as a Basic auth'ed POST.
+
+            First we try to read the username/password from $HOME/.pypirc,
+            which is a ConfigParser-formatted file with a section
+            [server-login] containing username and password entries (both
+            in clear text). Eg:
+
+                [server-login]
+                username: fred
+                password: sekrit
+
+            Otherwise, to figure who the user is, we offer the user three
+            choices:
+
+             1. use existing login,
+             2. register as a new user, or
+             3. set the password to a random string and email the user.
+
+        '''
+        choice = 'x'
+        username = password = ''
+
+        # see if we can short-cut and get the username/password from the
+        # config
+        config = None
+        if os.environ.has_key('HOME'):
+            rc = os.path.join(os.environ['HOME'], '.pypirc')
+            if os.path.exists(rc):
+                print 'Using PyPI login from %s'%rc
+                config = ConfigParser.ConfigParser()
+                config.read(rc)
+                username = config.get('server-login', 'username')
+                password = config.get('server-login', 'password')
+                choice = '1'
+
+        # get the user's login info
+        choices = '1 2 3 4'.split()
+        while choice not in choices:
+            print '''We need to know who you are, so please choose either:
+ 1. use your existing login,
+ 2. register as a new user,
+ 3. have the server generate a new password for you (and email it to you), or
+ 4. quit
+Your selection [default 1]: ''',
+            choice = raw_input()
+            if not choice:
+                choice = '1'
+            elif choice not in choices:
+                print 'Please choose one of the four options!'
+
+        if choice == '1':
+            # get the username and password
+            while not username:
+                username = raw_input('Username: ')
+            while not password:
+                password = getpass.getpass('Password: ')
+
+            # set up the authentication
+            auth = urllib2.HTTPPasswordMgr()
+            host = urlparse.urlparse(self.repository)[1]
+            auth.add_password('pypi', host, username, password)
+
+            # send the info to the server and report the result
+            code, result = self.post_to_server(self.build_post_data('submit'),
+                auth)
+            print 'Server response (%s): %s'%(code, result)
+
+            # possibly save the login
+            if os.environ.has_key('HOME') and config is None and code == 200:
+                rc = os.path.join(os.environ['HOME'], '.pypirc')
+                print 'I can store your PyPI login so future submissions will be faster.'
+                print '(the login will be stored in %s)'%rc
+                choice = 'X'
+                while choice.lower() not in 'yn':
+                    choice = raw_input('Save your login (y/N)?')
+                    if not choice:
+                        choice = 'n'
+                if choice.lower() == 'y':
+                    f = open(rc, 'w')
+                    f.write('[server-login]\nusername:%s\npassword:%s\n'%(
+                        username, password))
+                    f.close()
+                    try:
+                        os.chmod(rc, 0600)
+                    except:
+                        pass
+        elif choice == '2':
+            data = {':action': 'user'}
+            data['name'] = data['password'] = data['email'] = ''
+            data['confirm'] = None
+            while not data['name']:
+                data['name'] = raw_input('Username: ')
+            while data['password'] != data['confirm']:
+                while not data['password']:
+                    data['password'] = getpass.getpass('Password: ')
+                while not data['confirm']:
+                    data['confirm'] = getpass.getpass(' Confirm: ')
+                if data['password'] != data['confirm']:
+                    data['password'] = ''
+                    data['confirm'] = None
+                    print "Password and confirm don't match!"
+            while not data['email']:
+                data['email'] = raw_input('   EMail: ')
+            code, result = self.post_to_server(data)
+            if code != 200:
+                print 'Server response (%s): %s'%(code, result)
+            else:
+                print 'You will receive an email shortly.'
+                print 'Follow the instructions in it to complete registration.'
+        elif choice == '3':
+            data = {':action': 'password_reset'}
+            data['email'] = ''
+            while not data['email']:
+                data['email'] = raw_input('Your email address: ')
+            code, result = self.post_to_server(data)
+            print 'Server response (%s): %s'%(code, result)
+
+    def build_post_data(self, action):
+        # figure the data to send - the metadata plus some additional
+        # information used by the package server
+        meta = self.distribution.metadata
+        data = {
+            ':action': action,
+            'metadata_version' : '1.0',
+            'name': meta.get_name(),
+            'version': meta.get_version(),
+            'summary': meta.get_description(),
+            'home_page': meta.get_url(),
+            'author': meta.get_contact(),
+            'author_email': meta.get_contact_email(),
+            'license': meta.get_licence(),
+            'description': meta.get_long_description(),
+            'keywords': meta.get_keywords(),
+            'platform': meta.get_platforms(),
+            'classifiers': meta.get_classifiers(),
+            'download_url': meta.get_download_url(),
+            # PEP 314
+            'provides': meta.get_provides(),
+            'requires': meta.get_requires(),
+            'obsoletes': meta.get_obsoletes(),
+        }
+        if data['provides'] or data['requires'] or data['obsoletes']:
+            data['metadata_version'] = '1.1'
+        return data
+
+    def post_to_server(self, data, auth=None):
+        ''' Post a query to the server, and return a string response.
+        '''
+
+        # Build up the MIME payload for the urllib2 POST data
+        boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254'
+        sep_boundary = '\n--' + boundary
+        end_boundary = sep_boundary + '--'
+        body = StringIO.StringIO()
+        for key, value in data.items():
+            # handle multiple entries for the same name
+            if type(value) not in (type([]), type( () )):
+                value = [value]
+            for value in value:
+                value = unicode(value).encode("utf-8")
+                body.write(sep_boundary)
+                body.write('\nContent-Disposition: form-data; name="%s"'%key)
+                body.write("\n\n")
+                body.write(value)
+                if value and value[-1] == '\r':
+                    body.write('\n')  # write an extra newline (lurve Macs)
+        body.write(end_boundary)
+        body.write("\n")
+        body = body.getvalue()
+
+        # build the Request
+        headers = {
+            'Content-type': 'multipart/form-data; boundary=%s; charset=utf-8'%boundary,
+            'Content-length': str(len(body))
+        }
+        req = urllib2.Request(self.repository, body, headers)
+
+        # handle HTTP and include the Basic Auth handler
+        opener = urllib2.build_opener(
+            urllib2.HTTPBasicAuthHandler(password_mgr=auth)
+        )
+        data = ''
+        try:
+            result = opener.open(req)
+        except urllib2.HTTPError, e:
+            if self.show_response:
+                data = e.fp.read()
+            result = e.code, e.msg
+        except urllib2.URLError, e:
+            result = 500, str(e)
+        else:
+            if self.show_response:
+                data = result.read()
+            result = 200, 'OK'
+        if self.show_response:
+            print '-'*75, data, '-'*75
+        return result

Added: vendor/Python/current/Lib/distutils/command/sdist.py
===================================================================
--- vendor/Python/current/Lib/distutils/command/sdist.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/command/sdist.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,465 @@
+"""distutils.command.sdist
+
+Implements the Distutils 'sdist' command (create a source distribution)."""
+
+# This module should be kept compatible with Python 2.1.
+
+__revision__ = "$Id: sdist.py 38697 2005-03-23 18:54:36Z loewis $"
+
+import sys, os, string
+from types import *
+from glob import glob
+from distutils.core import Command
+from distutils import dir_util, dep_util, file_util, archive_util
+from distutils.text_file import TextFile
+from distutils.errors import *
+from distutils.filelist import FileList
+from distutils import log
+
+
+def show_formats ():
+    """Print all possible values for the 'formats' option (used by
+    the "--help-formats" command-line option).
+    """
+    from distutils.fancy_getopt import FancyGetopt
+    from distutils.archive_util import ARCHIVE_FORMATS
+    formats=[]
+    for format in ARCHIVE_FORMATS.keys():
+        formats.append(("formats=" + format, None,
+                        ARCHIVE_FORMATS[format][2]))
+    formats.sort()
+    pretty_printer = FancyGetopt(formats)
+    pretty_printer.print_help(
+        "List of available source distribution formats:")
+
+class sdist (Command):
+
+    description = "create a source distribution (tarball, zip file, etc.)"
+
+    user_options = [
+        ('template=', 't',
+         "name of manifest template file [default: MANIFEST.in]"),
+        ('manifest=', 'm',
+         "name of manifest file [default: MANIFEST]"),
+        ('use-defaults', None,
+         "include the default file set in the manifest "
+         "[default; disable with --no-defaults]"),
+        ('no-defaults', None,
+         "don't include the default file set"),
+        ('prune', None,
+         "specifically exclude files/directories that should not be "
+         "distributed (build tree, RCS/CVS dirs, etc.) "
+         "[default; disable with --no-prune]"),
+        ('no-prune', None,
+         "don't automatically exclude anything"),
+        ('manifest-only', 'o',
+         "just regenerate the manifest and then stop "
+         "(implies --force-manifest)"),
+        ('force-manifest', 'f',
+         "forcibly regenerate the manifest and carry on as usual"),
+        ('formats=', None,
+         "formats for source distribution (comma-separated list)"),
+        ('keep-temp', 'k',
+         "keep the distribution tree around after creating " +
+         "archive file(s)"),
+        ('dist-dir=', 'd',
+         "directory to put the source distribution archive(s) in "
+         "[default: dist]"),
+        ]
+
+    boolean_options = ['use-defaults', 'prune',
+                       'manifest-only', 'force-manifest',
+                       'keep-temp']
+
+    help_options = [
+        ('help-formats', None,
+         "list available distribution formats", show_formats),
+        ]
+
+    negative_opt = {'no-defaults': 'use-defaults',
+                    'no-prune': 'prune' }
+
+    default_format = { 'posix': 'gztar',
+                       'nt': 'zip' }
+
+    def initialize_options (self):
+        # 'template' and 'manifest' are, respectively, the names of
+        # the manifest template and manifest file.
+        self.template = None
+        self.manifest = None
+
+        # 'use_defaults': if true, we will include the default file set
+        # in the manifest
+        self.use_defaults = 1
+        self.prune = 1
+
+        self.manifest_only = 0
+        self.force_manifest = 0
+
+        self.formats = None
+        self.keep_temp = 0
+        self.dist_dir = None
+
+        self.archive_files = None
+
+
+    def finalize_options (self):
+        if self.manifest is None:
+            self.manifest = "MANIFEST"
+        if self.template is None:
+            self.template = "MANIFEST.in"
+
+        self.ensure_string_list('formats')
+        if self.formats is None:
+            try:
+                self.formats = [self.default_format[os.name]]
+            except KeyError:
+                raise DistutilsPlatformError, \
+                      "don't know how to create source distributions " + \
+                      "on platform %s" % os.name
+
+        bad_format = archive_util.check_archive_formats(self.formats)
+        if bad_format:
+            raise DistutilsOptionError, \
+                  "unknown archive format '%s'" % bad_format
+
+        if self.dist_dir is None:
+            self.dist_dir = "dist"
+
+
+    def run (self):
+
+        # 'filelist' contains the list of files that will make up the
+        # manifest
+        self.filelist = FileList()
+
+        # Ensure that all required meta-data is given; warn if not (but
+        # don't die, it's not *that* serious!)
+        self.check_metadata()
+
+        # Do whatever it takes to get the list of files to process
+        # (process the manifest template, read an existing manifest,
+        # whatever).  File list is accumulated in 'self.filelist'.
+        self.get_file_list()
+
+        # If user just wanted us to regenerate the manifest, stop now.
+        if self.manifest_only:
+            return
+
+        # Otherwise, go ahead and create the source distribution tarball,
+        # or zipfile, or whatever.
+        self.make_distribution()
+
+
+    def check_metadata (self):
+        """Ensure that all required elements of meta-data (name, version,
+        URL, (author and author_email) or (maintainer and
+        maintainer_email)) are supplied by the Distribution object; warn if
+        any are missing.
+        """
+        metadata = self.distribution.metadata
+
+        missing = []
+        for attr in ('name', 'version', 'url'):
+            if not (hasattr(metadata, attr) and getattr(metadata, attr)):
+                missing.append(attr)
+
+        if missing:
+            self.warn("missing required meta-data: " +
+                      string.join(missing, ", "))
+
+        if metadata.author:
+            if not metadata.author_email:
+                self.warn("missing meta-data: if 'author' supplied, " +
+                          "'author_email' must be supplied too")
+        elif metadata.maintainer:
+            if not metadata.maintainer_email:
+                self.warn("missing meta-data: if 'maintainer' supplied, " +
+                          "'maintainer_email' must be supplied too")
+        else:
+            self.warn("missing meta-data: either (author and author_email) " +
+                      "or (maintainer and maintainer_email) " +
+                      "must be supplied")
+
+    # check_metadata ()
+
+
+    def get_file_list (self):
+        """Figure out the list of files to include in the source
+        distribution, and put it in 'self.filelist'.  This might involve
+        reading the manifest template (and writing the manifest), or just
+        reading the manifest, or just using the default file set -- it all
+        depends on the user's options and the state of the filesystem.
+        """
+
+        # If we have a manifest template, see if it's newer than the
+        # manifest; if so, we'll regenerate the manifest.
+        template_exists = os.path.isfile(self.template)
+        if template_exists:
+            template_newer = dep_util.newer(self.template, self.manifest)
+
+        # The contents of the manifest file almost certainly depend on the
+        # setup script as well as the manifest template -- so if the setup
+        # script is newer than the manifest, we'll regenerate the manifest
+        # from the template.  (Well, not quite: if we already have a
+        # manifest, but there's no template -- which will happen if the
+        # developer elects to generate a manifest some other way -- then we
+        # can't regenerate the manifest, so we don't.)
+        self.debug_print("checking if %s newer than %s" %
+                         (self.distribution.script_name, self.manifest))
+        setup_newer = dep_util.newer(self.distribution.script_name,
+                                     self.manifest)
+
+        # cases:
+        #   1) no manifest, template exists: generate manifest
+        #      (covered by 2a: no manifest == template newer)
+        #   2) manifest & template exist:
+        #      2a) template or setup script newer than manifest:
+        #          regenerate manifest
+        #      2b) manifest newer than both:
+        #          do nothing (unless --force or --manifest-only)
+        #   3) manifest exists, no template:
+        #      do nothing (unless --force or --manifest-only)
+        #   4) no manifest, no template: generate w/ warning ("defaults only")
+
+        manifest_outofdate = (template_exists and
+                              (template_newer or setup_newer))
+        force_regen = self.force_manifest or self.manifest_only
+        manifest_exists = os.path.isfile(self.manifest)
+        neither_exists = (not template_exists and not manifest_exists)
+
+        # Regenerate the manifest if necessary (or if explicitly told to)
+        if manifest_outofdate or neither_exists or force_regen:
+            if not template_exists:
+                self.warn(("manifest template '%s' does not exist " +
+                           "(using default file list)") %
+                          self.template)
+            self.filelist.findall()
+
+            if self.use_defaults:
+                self.add_defaults()
+            if template_exists:
+                self.read_template()
+            if self.prune:
+                self.prune_file_list()
+
+            self.filelist.sort()
+            self.filelist.remove_duplicates()
+            self.write_manifest()
+
+        # Don't regenerate the manifest, just read it in.
+        else:
+            self.read_manifest()
+
+    # get_file_list ()
+
+
+    def add_defaults (self):
+        """Add all the default files to self.filelist:
+          - README or README.txt
+          - setup.py
+          - test/test*.py
+          - all pure Python modules mentioned in setup script
+          - all C sources listed as part of extensions or C libraries
+            in the setup script (doesn't catch C headers!)
+        Warns if (README or README.txt) or setup.py are missing; everything
+        else is optional.
+        """
+
+        standards = [('README', 'README.txt'), self.distribution.script_name]
+        for fn in standards:
+            if type(fn) is TupleType:
+                alts = fn
+                got_it = 0
+                for fn in alts:
+                    if os.path.exists(fn):
+                        got_it = 1
+                        self.filelist.append(fn)
+                        break
+
+                if not got_it:
+                    self.warn("standard file not found: should have one of " +
+                              string.join(alts, ', '))
+            else:
+                if os.path.exists(fn):
+                    self.filelist.append(fn)
+                else:
+                    self.warn("standard file '%s' not found" % fn)
+
+        optional = ['test/test*.py', 'setup.cfg']
+        for pattern in optional:
+            files = filter(os.path.isfile, glob(pattern))
+            if files:
+                self.filelist.extend(files)
+
+        if self.distribution.has_pure_modules():
+            build_py = self.get_finalized_command('build_py')
+            self.filelist.extend(build_py.get_source_files())
+
+        if self.distribution.has_ext_modules():
+            build_ext = self.get_finalized_command('build_ext')
+            self.filelist.extend(build_ext.get_source_files())
+
+        if self.distribution.has_c_libraries():
+            build_clib = self.get_finalized_command('build_clib')
+            self.filelist.extend(build_clib.get_source_files())
+
+        if self.distribution.has_scripts():
+            build_scripts = self.get_finalized_command('build_scripts')
+            self.filelist.extend(build_scripts.get_source_files())
+
+    # add_defaults ()
+
+
+    def read_template (self):
+        """Read and parse manifest template file named by self.template.
+
+        (usually "MANIFEST.in") The parsing and processing is done by
+        'self.filelist', which updates itself accordingly.
+        """
+        log.info("reading manifest template '%s'", self.template)
+        template = TextFile(self.template,
+                            strip_comments=1,
+                            skip_blanks=1,
+                            join_lines=1,
+                            lstrip_ws=1,
+                            rstrip_ws=1,
+                            collapse_join=1)
+
+        while 1:
+            line = template.readline()
+            if line is None:            # end of file
+                break
+
+            try:
+                self.filelist.process_template_line(line)
+            except DistutilsTemplateError, msg:
+                self.warn("%s, line %d: %s" % (template.filename,
+                                               template.current_line,
+                                               msg))
+
+    # read_template ()
+
+
+    def prune_file_list (self):
+        """Prune off branches that might slip into the file list as created
+        by 'read_template()', but really don't belong there:
+          * the build tree (typically "build")
+          * the release tree itself (only an issue if we ran "sdist"
+            previously with --keep-temp, or it aborted)
+          * any RCS, CVS and .svn directories
+        """
+        build = self.get_finalized_command('build')
+        base_dir = self.distribution.get_fullname()
+
+        self.filelist.exclude_pattern(None, prefix=build.build_base)
+        self.filelist.exclude_pattern(None, prefix=base_dir)
+        self.filelist.exclude_pattern(r'/(RCS|CVS|\.svn)/.*', is_regex=1)
+
+
+    def write_manifest (self):
+        """Write the file list in 'self.filelist' (presumably as filled in
+        by 'add_defaults()' and 'read_template()') to the manifest file
+        named by 'self.manifest'.
+        """
+        self.execute(file_util.write_file,
+                     (self.manifest, self.filelist.files),
+                     "writing manifest file '%s'" % self.manifest)
+
+    # write_manifest ()
+
+
+    def read_manifest (self):
+        """Read the manifest file (named by 'self.manifest') and use it to
+        fill in 'self.filelist', the list of files to include in the source
+        distribution.
+        """
+        log.info("reading manifest file '%s'", self.manifest)
+        manifest = open(self.manifest)
+        while 1:
+            line = manifest.readline()
+            if line == '':              # end of file
+                break
+            if line[-1] == '\n':
+                line = line[0:-1]
+            self.filelist.append(line)
+
+    # read_manifest ()
+
+
+    def make_release_tree (self, base_dir, files):
+        """Create the directory tree that will become the source
+        distribution archive.  All directories implied by the filenames in
+        'files' are created under 'base_dir', and then we hard link or copy
+        (if hard linking is unavailable) those files into place.
+        Essentially, this duplicates the developer's source tree, but in a
+        directory named after the distribution, containing only the files
+        to be distributed.
+        """
+        # Create all the directories under 'base_dir' necessary to
+        # put 'files' there; the 'mkpath()' is just so we don't die
+        # if the manifest happens to be empty.
+        self.mkpath(base_dir)
+        dir_util.create_tree(base_dir, files, dry_run=self.dry_run)
+
+        # And walk over the list of files, either making a hard link (if
+        # os.link exists) to each one that doesn't already exist in its
+        # corresponding location under 'base_dir', or copying each file
+        # that's out-of-date in 'base_dir'.  (Usually, all files will be
+        # out-of-date, because by default we blow away 'base_dir' when
+        # we're done making the distribution archives.)
+
+        if hasattr(os, 'link'):        # can make hard links on this system
+            link = 'hard'
+            msg = "making hard links in %s..." % base_dir
+        else:                           # nope, have to copy
+            link = None
+            msg = "copying files to %s..." % base_dir
+
+        if not files:
+            log.warn("no files to distribute -- empty manifest?")
+        else:
+            log.info(msg)
+        for file in files:
+            if not os.path.isfile(file):
+                log.warn("'%s' not a regular file -- skipping" % file)
+            else:
+                dest = os.path.join(base_dir, file)
+                self.copy_file(file, dest, link=link)
+
+        self.distribution.metadata.write_pkg_info(base_dir)
+
+    # make_release_tree ()
+
+    def make_distribution (self):
+        """Create the source distribution(s).  First, we create the release
+        tree with 'make_release_tree()'; then, we create all required
+        archive files (according to 'self.formats') from the release tree.
+        Finally, we clean up by blowing away the release tree (unless
+        'self.keep_temp' is true).  The list of archive files created is
+        stored so it can be retrieved later by 'get_archive_files()'.
+        """
+        # Don't warn about missing meta-data here -- should be (and is!)
+        # done elsewhere.
+        base_dir = self.distribution.get_fullname()
+        base_name = os.path.join(self.dist_dir, base_dir)
+
+        self.make_release_tree(base_dir, self.filelist.files)
+        archive_files = []              # remember names of files we create
+        for fmt in self.formats:
+            file = self.make_archive(base_name, fmt, base_dir=base_dir)
+            archive_files.append(file)
+            self.distribution.dist_files.append(('sdist', '', file))
+
+        self.archive_files = archive_files
+
+        if not self.keep_temp:
+            dir_util.remove_tree(base_dir, dry_run=self.dry_run)
+
+    def get_archive_files (self):
+        """Return the list of archive files created when the command
+        was run, or None if the command hasn't run yet.
+        """
+        return self.archive_files
+
+# class sdist

Added: vendor/Python/current/Lib/distutils/command/upload.py
===================================================================
--- vendor/Python/current/Lib/distutils/command/upload.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/command/upload.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,199 @@
+"""distutils.command.upload
+
+Implements the Distutils 'upload' subcommand (upload package to PyPI)."""
+
+from distutils.errors import *
+from distutils.core import Command
+from distutils.spawn import spawn
+from distutils import log
+from hashlib import md5
+import os
+import socket
+import platform
+import ConfigParser
+import httplib
+import base64
+import urlparse
+import cStringIO as StringIO
+
+class upload(Command):
+
+    description = "upload binary package to PyPI"
+
+    DEFAULT_REPOSITORY = 'http://www.python.org/pypi'
+
+    user_options = [
+        ('repository=', 'r',
+         "url of repository [default: %s]" % DEFAULT_REPOSITORY),
+        ('show-response', None,
+         'display full response text from server'),
+        ('sign', 's',
+         'sign files to upload using gpg'),
+        ('identity=', 'i', 'GPG identity used to sign files'),
+        ]
+    boolean_options = ['show-response', 'sign']
+
+    def initialize_options(self):
+        self.username = ''
+        self.password = ''
+        self.repository = ''
+        self.show_response = 0
+        self.sign = False
+        self.identity = None
+
+    def finalize_options(self):
+        if self.identity and not self.sign:
+            raise DistutilsOptionError(
+                "Must use --sign for --identity to have meaning"
+            )
+        if os.environ.has_key('HOME'):
+            rc = os.path.join(os.environ['HOME'], '.pypirc')
+            if os.path.exists(rc):
+                self.announce('Using PyPI login from %s' % rc)
+                config = ConfigParser.ConfigParser({
+                        'username':'',
+                        'password':'',
+                        'repository':''})
+                config.read(rc)
+                if not self.repository:
+                    self.repository = config.get('server-login', 'repository')
+                if not self.username:
+                    self.username = config.get('server-login', 'username')
+                if not self.password:
+                    self.password = config.get('server-login', 'password')
+        if not self.repository:
+            self.repository = self.DEFAULT_REPOSITORY
+
+    def run(self):
+        if not self.distribution.dist_files:
+            raise DistutilsOptionError("No dist file created in earlier command")
+        for command, pyversion, filename in self.distribution.dist_files:
+            self.upload_file(command, pyversion, filename)
+
+    def upload_file(self, command, pyversion, filename):
+        # Sign if requested
+        if self.sign:
+            gpg_args = ["gpg", "--detach-sign", "-a", filename]
+            if self.identity:
+                gpg_args[2:2] = ["--local-user", self.identity]
+            spawn(gpg_args,
+                  dry_run=self.dry_run)
+
+        # Fill in the data - send all the meta-data in case we need to
+        # register a new release
+        content = open(filename,'rb').read()
+        meta = self.distribution.metadata
+        data = {
+            # action
+            ':action': 'file_upload',
+            'protcol_version': '1',
+
+            # identify release
+            'name': meta.get_name(),
+            'version': meta.get_version(),
+
+            # file content
+            'content': (os.path.basename(filename),content),
+            'filetype': command,
+            'pyversion': pyversion,
+            'md5_digest': md5(content).hexdigest(),
+
+            # additional meta-data
+            'metadata_version' : '1.0',
+            'summary': meta.get_description(),
+            'home_page': meta.get_url(),
+            'author': meta.get_contact(),
+            'author_email': meta.get_contact_email(),
+            'license': meta.get_licence(),
+            'description': meta.get_long_description(),
+            'keywords': meta.get_keywords(),
+            'platform': meta.get_platforms(),
+            'classifiers': meta.get_classifiers(),
+            'download_url': meta.get_download_url(),
+            # PEP 314
+            'provides': meta.get_provides(),
+            'requires': meta.get_requires(),
+            'obsoletes': meta.get_obsoletes(),
+            }
+        comment = ''
+        if command == 'bdist_rpm':
+            dist, version, id = platform.dist()
+            if dist:
+                comment = 'built for %s %s' % (dist, version)
+        elif command == 'bdist_dumb':
+            comment = 'built for %s' % platform.platform(terse=1)
+        data['comment'] = comment
+
+        if self.sign:
+            data['gpg_signature'] = (os.path.basename(filename) + ".asc",
+                                     open(filename+".asc").read())
+
+        # set up the authentication
+        auth = "Basic " + base64.encodestring(self.username + ":" + self.password).strip()
+
+        # Build up the MIME payload for the POST data
+        boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254'
+        sep_boundary = '\n--' + boundary
+        end_boundary = sep_boundary + '--'
+        body = StringIO.StringIO()
+        for key, value in data.items():
+            # handle multiple entries for the same name
+            if type(value) != type([]):
+                value = [value]
+            for value in value:
+                if type(value) is tuple:
+                    fn = ';filename="%s"' % value[0]
+                    value = value[1]
+                else:
+                    fn = ""
+                value = str(value)
+                body.write(sep_boundary)
+                body.write('\nContent-Disposition: form-data; name="%s"'%key)
+                body.write(fn)
+                body.write("\n\n")
+                body.write(value)
+                if value and value[-1] == '\r':
+                    body.write('\n')  # write an extra newline (lurve Macs)
+        body.write(end_boundary)
+        body.write("\n")
+        body = body.getvalue()
+
+        self.announce("Submitting %s to %s" % (filename, self.repository), log.INFO)
+
+        # build the Request
+        # We can't use urllib2 since we need to send the Basic
+        # auth right with the first request
+        schema, netloc, url, params, query, fragments = \
+            urlparse.urlparse(self.repository)
+        assert not params and not query and not fragments
+        if schema == 'http':
+            http = httplib.HTTPConnection(netloc)
+        elif schema == 'https':
+            http = httplib.HTTPSConnection(netloc)
+        else:
+            raise AssertionError, "unsupported schema "+schema
+
+        data = ''
+        loglevel = log.INFO
+        try:
+            http.connect()
+            http.putrequest("POST", url)
+            http.putheader('Content-type',
+                           'multipart/form-data; boundary=%s'%boundary)
+            http.putheader('Content-length', str(len(body)))
+            http.putheader('Authorization', auth)
+            http.endheaders()
+            http.send(body)
+        except socket.error, e:
+            self.announce(str(e), log.ERROR)
+            return
+
+        r = http.getresponse()
+        if r.status == 200:
+            self.announce('Server response (%s): %s' % (r.status, r.reason),
+                          log.INFO)
+        else:
+            self.announce('Upload failed (%s): %s' % (r.status, r.reason),
+                          log.ERROR)
+        if self.show_response:
+            print '-'*75, r.read(), '-'*75

Added: vendor/Python/current/Lib/distutils/command/wininst-6.exe
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Lib/distutils/command/wininst-6.exe
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Lib/distutils/command/wininst-7.1.exe
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Lib/distutils/command/wininst-7.1.exe
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Lib/distutils/core.py
===================================================================
--- vendor/Python/current/Lib/distutils/core.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/core.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,242 @@
+"""distutils.core
+
+The only module that needs to be imported to use the Distutils; provides
+the 'setup' function (which is to be called from the setup script).  Also
+indirectly provides the Distribution and Command classes, although they are
+really defined in distutils.dist and distutils.cmd.
+"""
+
+# This module should be kept compatible with Python 2.1.
+
+__revision__ = "$Id: core.py 38672 2005-03-20 22:19:47Z fdrake $"
+
+import sys, os
+from types import *
+
+from distutils.debug import DEBUG
+from distutils.errors import *
+from distutils.util import grok_environment_error
+
+# Mainly import these so setup scripts can "from distutils.core import" them.
+from distutils.dist import Distribution
+from distutils.cmd import Command
+from distutils.extension import Extension
+
+# This is a barebones help message generated displayed when the user
+# runs the setup script with no arguments at all.  More useful help
+# is generated with various --help options: global help, list commands,
+# and per-command help.
+USAGE = """\
+usage: %(script)s [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...]
+   or: %(script)s --help [cmd1 cmd2 ...]
+   or: %(script)s --help-commands
+   or: %(script)s cmd --help
+"""
+
+def gen_usage (script_name):
+    script = os.path.basename(script_name)
+    return USAGE % vars()
+
+
+# Some mild magic to control the behaviour of 'setup()' from 'run_setup()'.
+_setup_stop_after = None
+_setup_distribution = None
+
+# Legal keyword arguments for the setup() function
+setup_keywords = ('distclass', 'script_name', 'script_args', 'options',
+                  'name', 'version', 'author', 'author_email',
+                  'maintainer', 'maintainer_email', 'url', 'license',
+                  'description', 'long_description', 'keywords',
+                  'platforms', 'classifiers', 'download_url',
+                  'requires', 'provides', 'obsoletes',
+                  )
+
+# Legal keyword arguments for the Extension constructor
+extension_keywords = ('name', 'sources', 'include_dirs',
+                      'define_macros', 'undef_macros',
+                      'library_dirs', 'libraries', 'runtime_library_dirs',
+                      'extra_objects', 'extra_compile_args', 'extra_link_args',
+                      'swig_opts', 'export_symbols', 'depends', 'language')
+
+def setup (**attrs):
+    """The gateway to the Distutils: do everything your setup script needs
+    to do, in a highly flexible and user-driven way.  Briefly: create a
+    Distribution instance; find and parse config files; parse the command
+    line; run each Distutils command found there, customized by the options
+    supplied to 'setup()' (as keyword arguments), in config files, and on
+    the command line.
+
+    The Distribution instance might be an instance of a class supplied via
+    the 'distclass' keyword argument to 'setup'; if no such class is
+    supplied, then the Distribution class (in dist.py) is instantiated.
+    All other arguments to 'setup' (except for 'cmdclass') are used to set
+    attributes of the Distribution instance.
+
+    The 'cmdclass' argument, if supplied, is a dictionary mapping command
+    names to command classes.  Each command encountered on the command line
+    will be turned into a command class, which is in turn instantiated; any
+    class found in 'cmdclass' is used in place of the default, which is
+    (for command 'foo_bar') class 'foo_bar' in module
+    'distutils.command.foo_bar'.  The command class must provide a
+    'user_options' attribute which is a list of option specifiers for
+    'distutils.fancy_getopt'.  Any command-line options between the current
+    and the next command are used to set attributes of the current command
+    object.
+
+    When the entire command-line has been successfully parsed, calls the
+    'run()' method on each command object in turn.  This method will be
+    driven entirely by the Distribution object (which each command object
+    has a reference to, thanks to its constructor), and the
+    command-specific options that became attributes of each command
+    object.
+    """
+
+    global _setup_stop_after, _setup_distribution
+
+    # Determine the distribution class -- either caller-supplied or
+    # our Distribution (see below).
+    klass = attrs.get('distclass')
+    if klass:
+        del attrs['distclass']
+    else:
+        klass = Distribution
+
+    if not attrs.has_key('script_name'):
+        attrs['script_name'] = os.path.basename(sys.argv[0])
+    if not attrs.has_key('script_args'):
+        attrs['script_args'] = sys.argv[1:]
+
+    # Create the Distribution instance, using the remaining arguments
+    # (ie. everything except distclass) to initialize it
+    try:
+        _setup_distribution = dist = klass(attrs)
+    except DistutilsSetupError, msg:
+        if attrs.has_key('name'):
+            raise SystemExit, "error in %s setup command: %s" % \
+                  (attrs['name'], msg)
+        else:
+            raise SystemExit, "error in setup command: %s" % msg
+
+    if _setup_stop_after == "init":
+        return dist
+
+    # Find and parse the config file(s): they will override options from
+    # the setup script, but be overridden by the command line.
+    dist.parse_config_files()
+
+    if DEBUG:
+        print "options (after parsing config files):"
+        dist.dump_option_dicts()
+
+    if _setup_stop_after == "config":
+        return dist
+
+    # Parse the command line; any command-line errors are the end user's
+    # fault, so turn them into SystemExit to suppress tracebacks.
+    try:
+        ok = dist.parse_command_line()
+    except DistutilsArgError, msg:
+        raise SystemExit, gen_usage(dist.script_name) + "\nerror: %s" % msg
+
+    if DEBUG:
+        print "options (after parsing command line):"
+        dist.dump_option_dicts()
+
+    if _setup_stop_after == "commandline":
+        return dist
+
+    # And finally, run all the commands found on the command line.
+    if ok:
+        try:
+            dist.run_commands()
+        except KeyboardInterrupt:
+            raise SystemExit, "interrupted"
+        except (IOError, os.error), exc:
+            error = grok_environment_error(exc)
+
+            if DEBUG:
+                sys.stderr.write(error + "\n")
+                raise
+            else:
+                raise SystemExit, error
+
+        except (DistutilsError,
+                CCompilerError), msg:
+            if DEBUG:
+                raise
+            else:
+                raise SystemExit, "error: " + str(msg)
+
+    return dist
+
+# setup ()
+
+
+def run_setup (script_name, script_args=None, stop_after="run"):
+    """Run a setup script in a somewhat controlled environment, and
+    return the Distribution instance that drives things.  This is useful
+    if you need to find out the distribution meta-data (passed as
+    keyword args from 'script' to 'setup()', or the contents of the
+    config files or command-line.
+
+    'script_name' is a file that will be run with 'execfile()';
+    'sys.argv[0]' will be replaced with 'script' for the duration of the
+    call.  'script_args' is a list of strings; if supplied,
+    'sys.argv[1:]' will be replaced by 'script_args' for the duration of
+    the call.
+
+    'stop_after' tells 'setup()' when to stop processing; possible
+    values:
+      init
+        stop after the Distribution instance has been created and
+        populated with the keyword arguments to 'setup()'
+      config
+        stop after config files have been parsed (and their data
+        stored in the Distribution instance)
+      commandline
+        stop after the command-line ('sys.argv[1:]' or 'script_args')
+        have been parsed (and the data stored in the Distribution)
+      run [default]
+        stop after all commands have been run (the same as if 'setup()'
+        had been called in the usual way
+
+    Returns the Distribution instance, which provides all information
+    used to drive the Distutils.
+    """
+    if stop_after not in ('init', 'config', 'commandline', 'run'):
+        raise ValueError, "invalid value for 'stop_after': %r" % (stop_after,)
+
+    global _setup_stop_after, _setup_distribution
+    _setup_stop_after = stop_after
+
+    save_argv = sys.argv
+    g = {}
+    l = {}
+    try:
+        try:
+            sys.argv[0] = script_name
+            if script_args is not None:
+                sys.argv[1:] = script_args
+            execfile(script_name, g, l)
+        finally:
+            sys.argv = save_argv
+            _setup_stop_after = None
+    except SystemExit:
+        # Hmm, should we do something if exiting with a non-zero code
+        # (ie. error)?
+        pass
+    except:
+        raise
+
+    if _setup_distribution is None:
+        raise RuntimeError, \
+              ("'distutils.core.setup()' was never called -- "
+               "perhaps '%s' is not a Distutils setup script?") % \
+              script_name
+
+    # I wonder if the setup script's namespace -- g and l -- would be of
+    # any interest to callers?
+    #print "_setup_distribution:", _setup_distribution
+    return _setup_distribution
+
+# run_setup ()

Added: vendor/Python/current/Lib/distutils/cygwinccompiler.py
===================================================================
--- vendor/Python/current/Lib/distutils/cygwinccompiler.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/cygwinccompiler.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,441 @@
+"""distutils.cygwinccompiler
+
+Provides the CygwinCCompiler class, a subclass of UnixCCompiler that
+handles the Cygwin port of the GNU C compiler to Windows.  It also contains
+the Mingw32CCompiler class which handles the mingw32 port of GCC (same as
+cygwin in no-cygwin mode).
+"""
+
+# problems:
+#
+# * if you use a msvc compiled python version (1.5.2)
+#   1. you have to insert a __GNUC__ section in its config.h
+#   2. you have to generate a import library for its dll
+#      - create a def-file for python??.dll
+#      - create a import library using
+#             dlltool --dllname python15.dll --def python15.def \
+#                       --output-lib libpython15.a
+#
+#   see also http://starship.python.net/crew/kernr/mingw32/Notes.html
+#
+# * We put export_symbols in a def-file, and don't use
+#   --export-all-symbols because it doesn't worked reliable in some
+#   tested configurations. And because other windows compilers also
+#   need their symbols specified this no serious problem.
+#
+# tested configurations:
+#
+# * cygwin gcc 2.91.57/ld 2.9.4/dllwrap 0.2.4 works
+#   (after patching python's config.h and for C++ some other include files)
+#   see also http://starship.python.net/crew/kernr/mingw32/Notes.html
+# * mingw32 gcc 2.95.2/ld 2.9.4/dllwrap 0.2.4 works
+#   (ld doesn't support -shared, so we use dllwrap)
+# * cygwin gcc 2.95.2/ld 2.10.90/dllwrap 2.10.90 works now
+#   - its dllwrap doesn't work, there is a bug in binutils 2.10.90
+#     see also http://sources.redhat.com/ml/cygwin/2000-06/msg01274.html
+#   - using gcc -mdll instead dllwrap doesn't work without -static because
+#     it tries to link against dlls instead their import libraries. (If
+#     it finds the dll first.)
+#     By specifying -static we force ld to link against the import libraries,
+#     this is windows standard and there are normally not the necessary symbols
+#     in the dlls.
+#   *** only the version of June 2000 shows these problems
+# * cygwin gcc 3.2/ld 2.13.90 works
+#   (ld supports -shared)
+# * mingw gcc 3.2/ld 2.13 works
+#   (ld supports -shared)
+
+# This module should be kept compatible with Python 2.1.
+
+__revision__ = "$Id: cygwinccompiler.py 37828 2004-11-10 22:23:15Z loewis $"
+
+import os,sys,copy
+from distutils.ccompiler import gen_preprocess_options, gen_lib_options
+from distutils.unixccompiler import UnixCCompiler
+from distutils.file_util import write_file
+from distutils.errors import DistutilsExecError, CompileError, UnknownFileError
+from distutils import log
+
+class CygwinCCompiler (UnixCCompiler):
+
+    compiler_type = 'cygwin'
+    obj_extension = ".o"
+    static_lib_extension = ".a"
+    shared_lib_extension = ".dll"
+    static_lib_format = "lib%s%s"
+    shared_lib_format = "%s%s"
+    exe_extension = ".exe"
+
+    def __init__ (self, verbose=0, dry_run=0, force=0):
+
+        UnixCCompiler.__init__ (self, verbose, dry_run, force)
+
+        (status, details) = check_config_h()
+        self.debug_print("Python's GCC status: %s (details: %s)" %
+                         (status, details))
+        if status is not CONFIG_H_OK:
+            self.warn(
+                "Python's pyconfig.h doesn't seem to support your compiler. "
+                "Reason: %s. "
+                "Compiling may fail because of undefined preprocessor macros."
+                % details)
+
+        self.gcc_version, self.ld_version, self.dllwrap_version = \
+            get_versions()
+        self.debug_print(self.compiler_type + ": gcc %s, ld %s, dllwrap %s\n" %
+                         (self.gcc_version,
+                          self.ld_version,
+                          self.dllwrap_version) )
+
+        # ld_version >= "2.10.90" and < "2.13" should also be able to use
+        # gcc -mdll instead of dllwrap
+        # Older dllwraps had own version numbers, newer ones use the
+        # same as the rest of binutils ( also ld )
+        # dllwrap 2.10.90 is buggy
+        if self.ld_version >= "2.10.90":
+            self.linker_dll = "gcc"
+        else:
+            self.linker_dll = "dllwrap"
+
+        # ld_version >= "2.13" support -shared so use it instead of
+        # -mdll -static
+        if self.ld_version >= "2.13":
+            shared_option = "-shared"
+        else:
+            shared_option = "-mdll -static"
+
+        # Hard-code GCC because that's what this is all about.
+        # XXX optimization, warnings etc. should be customizable.
+        self.set_executables(compiler='gcc -mcygwin -O -Wall',
+                             compiler_so='gcc -mcygwin -mdll -O -Wall',
+                             compiler_cxx='g++ -mcygwin -O -Wall',
+                             linker_exe='gcc -mcygwin',
+                             linker_so=('%s -mcygwin %s' %
+                                        (self.linker_dll, shared_option)))
+
+        # cygwin and mingw32 need different sets of libraries
+        if self.gcc_version == "2.91.57":
+            # cygwin shouldn't need msvcrt, but without the dlls will crash
+            # (gcc version 2.91.57) -- perhaps something about initialization
+            self.dll_libraries=["msvcrt"]
+            self.warn(
+                "Consider upgrading to a newer version of gcc")
+        else:
+            self.dll_libraries=[]
+            # Include the appropriate MSVC runtime library if Python was built
+            # with MSVC 7.0 or 7.1.
+            msc_pos = sys.version.find('MSC v.')
+            if msc_pos != -1:
+                msc_ver = sys.version[msc_pos+6:msc_pos+10]
+                if msc_ver == '1300':
+                    # MSVC 7.0
+                    self.dll_libraries = ['msvcr70']
+                elif msc_ver == '1310':
+                    # MSVC 7.1
+                    self.dll_libraries = ['msvcr71']
+
+    # __init__ ()
+
+
+    def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts):
+        if ext == '.rc' or ext == '.res':
+            # gcc needs '.res' and '.rc' compiled to object files !!!
+            try:
+                self.spawn(["windres", "-i", src, "-o", obj])
+            except DistutilsExecError, msg:
+                raise CompileError, msg
+        else: # for other files use the C-compiler
+            try:
+                self.spawn(self.compiler_so + cc_args + [src, '-o', obj] +
+                           extra_postargs)
+            except DistutilsExecError, msg:
+                raise CompileError, msg
+
+    def link (self,
+              target_desc,
+              objects,
+              output_filename,
+              output_dir=None,
+              libraries=None,
+              library_dirs=None,
+              runtime_library_dirs=None,
+              export_symbols=None,
+              debug=0,
+              extra_preargs=None,
+              extra_postargs=None,
+              build_temp=None,
+              target_lang=None):
+
+        # use separate copies, so we can modify the lists
+        extra_preargs = copy.copy(extra_preargs or [])
+        libraries = copy.copy(libraries or [])
+        objects = copy.copy(objects or [])
+
+        # Additional libraries
+        libraries.extend(self.dll_libraries)
+
+        # handle export symbols by creating a def-file
+        # with executables this only works with gcc/ld as linker
+        if ((export_symbols is not None) and
+            (target_desc != self.EXECUTABLE or self.linker_dll == "gcc")):
+            # (The linker doesn't do anything if output is up-to-date.
+            # So it would probably better to check if we really need this,
+            # but for this we had to insert some unchanged parts of
+            # UnixCCompiler, and this is not what we want.)
+
+            # we want to put some files in the same directory as the
+            # object files are, build_temp doesn't help much
+            # where are the object files
+            temp_dir = os.path.dirname(objects[0])
+            # name of dll to give the helper files the same base name
+            (dll_name, dll_extension) = os.path.splitext(
+                os.path.basename(output_filename))
+
+            # generate the filenames for these files
+            def_file = os.path.join(temp_dir, dll_name + ".def")
+            lib_file = os.path.join(temp_dir, 'lib' + dll_name + ".a")
+
+            # Generate .def file
+            contents = [
+                "LIBRARY %s" % os.path.basename(output_filename),
+                "EXPORTS"]
+            for sym in export_symbols:
+                contents.append(sym)
+            self.execute(write_file, (def_file, contents),
+                         "writing %s" % def_file)
+
+            # next add options for def-file and to creating import libraries
+
+            # dllwrap uses different options than gcc/ld
+            if self.linker_dll == "dllwrap":
+                extra_preargs.extend(["--output-lib", lib_file])
+                # for dllwrap we have to use a special option
+                extra_preargs.extend(["--def", def_file])
+            # we use gcc/ld here and can be sure ld is >= 2.9.10
+            else:
+                # doesn't work: bfd_close build\...\libfoo.a: Invalid operation
+                #extra_preargs.extend(["-Wl,--out-implib,%s" % lib_file])
+                # for gcc/ld the def-file is specified as any object files
+                objects.append(def_file)
+
+        #end: if ((export_symbols is not None) and
+        #        (target_desc != self.EXECUTABLE or self.linker_dll == "gcc")):
+
+        # who wants symbols and a many times larger output file
+        # should explicitly switch the debug mode on
+        # otherwise we let dllwrap/ld strip the output file
+        # (On my machine: 10KB < stripped_file < ??100KB
+        #   unstripped_file = stripped_file + XXX KB
+        #  ( XXX=254 for a typical python extension))
+        if not debug:
+            extra_preargs.append("-s")
+
+        UnixCCompiler.link(self,
+                           target_desc,
+                           objects,
+                           output_filename,
+                           output_dir,
+                           libraries,
+                           library_dirs,
+                           runtime_library_dirs,
+                           None, # export_symbols, we do this in our def-file
+                           debug,
+                           extra_preargs,
+                           extra_postargs,
+                           build_temp,
+                           target_lang)
+
+    # link ()
+
+    # -- Miscellaneous methods -----------------------------------------
+
+    # overwrite the one from CCompiler to support rc and res-files
+    def object_filenames (self,
+                          source_filenames,
+                          strip_dir=0,
+                          output_dir=''):
+        if output_dir is None: output_dir = ''
+        obj_names = []
+        for src_name in source_filenames:
+            # use normcase to make sure '.rc' is really '.rc' and not '.RC'
+            (base, ext) = os.path.splitext (os.path.normcase(src_name))
+            if ext not in (self.src_extensions + ['.rc','.res']):
+                raise UnknownFileError, \
+                      "unknown file type '%s' (from '%s')" % \
+                      (ext, src_name)
+            if strip_dir:
+                base = os.path.basename (base)
+            if ext == '.res' or ext == '.rc':
+                # these need to be compiled to object files
+                obj_names.append (os.path.join (output_dir,
+                                            base + ext + self.obj_extension))
+            else:
+                obj_names.append (os.path.join (output_dir,
+                                            base + self.obj_extension))
+        return obj_names
+
+    # object_filenames ()
+
+# class CygwinCCompiler
+
+
+# the same as cygwin plus some additional parameters
+class Mingw32CCompiler (CygwinCCompiler):
+
+    compiler_type = 'mingw32'
+
+    def __init__ (self,
+                  verbose=0,
+                  dry_run=0,
+                  force=0):
+
+        CygwinCCompiler.__init__ (self, verbose, dry_run, force)
+
+        # ld_version >= "2.13" support -shared so use it instead of
+        # -mdll -static
+        if self.ld_version >= "2.13":
+            shared_option = "-shared"
+        else:
+            shared_option = "-mdll -static"
+
+        # A real mingw32 doesn't need to specify a different entry point,
+        # but cygwin 2.91.57 in no-cygwin-mode needs it.
+        if self.gcc_version <= "2.91.57":
+            entry_point = '--entry _DllMain at 12'
+        else:
+            entry_point = ''
+
+        self.set_executables(compiler='gcc -mno-cygwin -O -Wall',
+                             compiler_so='gcc -mno-cygwin -mdll -O -Wall',
+                             compiler_cxx='g++ -mno-cygwin -O -Wall',
+                             linker_exe='gcc -mno-cygwin',
+                             linker_so='%s -mno-cygwin %s %s'
+                                        % (self.linker_dll, shared_option,
+                                           entry_point))
+        # Maybe we should also append -mthreads, but then the finished
+        # dlls need another dll (mingwm10.dll see Mingw32 docs)
+        # (-mthreads: Support thread-safe exception handling on `Mingw32')
+
+        # no additional libraries needed
+        self.dll_libraries=[]
+
+        # Include the appropriate MSVC runtime library if Python was built
+        # with MSVC 7.0 or 7.1.
+        msc_pos = sys.version.find('MSC v.')
+        if msc_pos != -1:
+            msc_ver = sys.version[msc_pos+6:msc_pos+10]
+            if msc_ver == '1300':
+                # MSVC 7.0
+                self.dll_libraries = ['msvcr70']
+            elif msc_ver == '1310':
+                # MSVC 7.1
+                self.dll_libraries = ['msvcr71']
+
+    # __init__ ()
+
+# class Mingw32CCompiler
+
+# Because these compilers aren't configured in Python's pyconfig.h file by
+# default, we should at least warn the user if he is using a unmodified
+# version.
+
+CONFIG_H_OK = "ok"
+CONFIG_H_NOTOK = "not ok"
+CONFIG_H_UNCERTAIN = "uncertain"
+
+def check_config_h():
+
+    """Check if the current Python installation (specifically, pyconfig.h)
+    appears amenable to building extensions with GCC.  Returns a tuple
+    (status, details), where 'status' is one of the following constants:
+      CONFIG_H_OK
+        all is well, go ahead and compile
+      CONFIG_H_NOTOK
+        doesn't look good
+      CONFIG_H_UNCERTAIN
+        not sure -- unable to read pyconfig.h
+    'details' is a human-readable string explaining the situation.
+
+    Note there are two ways to conclude "OK": either 'sys.version' contains
+    the string "GCC" (implying that this Python was built with GCC), or the
+    installed "pyconfig.h" contains the string "__GNUC__".
+    """
+
+    # XXX since this function also checks sys.version, it's not strictly a
+    # "pyconfig.h" check -- should probably be renamed...
+
+    from distutils import sysconfig
+    import string
+    # if sys.version contains GCC then python was compiled with
+    # GCC, and the pyconfig.h file should be OK
+    if string.find(sys.version,"GCC") >= 0:
+        return (CONFIG_H_OK, "sys.version mentions 'GCC'")
+
+    fn = sysconfig.get_config_h_filename()
+    try:
+        # It would probably better to read single lines to search.
+        # But we do this only once, and it is fast enough
+        f = open(fn)
+        s = f.read()
+        f.close()
+
+    except IOError, exc:
+        # if we can't read this file, we cannot say it is wrong
+        # the compiler will complain later about this file as missing
+        return (CONFIG_H_UNCERTAIN,
+                "couldn't read '%s': %s" % (fn, exc.strerror))
+
+    else:
+        # "pyconfig.h" contains an "#ifdef __GNUC__" or something similar
+        if string.find(s,"__GNUC__") >= 0:
+            return (CONFIG_H_OK, "'%s' mentions '__GNUC__'" % fn)
+        else:
+            return (CONFIG_H_NOTOK, "'%s' does not mention '__GNUC__'" % fn)
+
+
+
+def get_versions():
+    """ Try to find out the versions of gcc, ld and dllwrap.
+        If not possible it returns None for it.
+    """
+    from distutils.version import StrictVersion
+    from distutils.spawn import find_executable
+    import re
+
+    gcc_exe = find_executable('gcc')
+    if gcc_exe:
+        out = os.popen(gcc_exe + ' -dumpversion','r')
+        out_string = out.read()
+        out.close()
+        result = re.search('(\d+\.\d+(\.\d+)*)',out_string)
+        if result:
+            gcc_version = StrictVersion(result.group(1))
+        else:
+            gcc_version = None
+    else:
+        gcc_version = None
+    ld_exe = find_executable('ld')
+    if ld_exe:
+        out = os.popen(ld_exe + ' -v','r')
+        out_string = out.read()
+        out.close()
+        result = re.search('(\d+\.\d+(\.\d+)*)',out_string)
+        if result:
+            ld_version = StrictVersion(result.group(1))
+        else:
+            ld_version = None
+    else:
+        ld_version = None
+    dllwrap_exe = find_executable('dllwrap')
+    if dllwrap_exe:
+        out = os.popen(dllwrap_exe + ' --version','r')
+        out_string = out.read()
+        out.close()
+        result = re.search(' (\d+\.\d+(\.\d+)*)',out_string)
+        if result:
+            dllwrap_version = StrictVersion(result.group(1))
+        else:
+            dllwrap_version = None
+    else:
+        dllwrap_version = None
+    return (gcc_version, ld_version, dllwrap_version)

Added: vendor/Python/current/Lib/distutils/debug.py
===================================================================
--- vendor/Python/current/Lib/distutils/debug.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/debug.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,9 @@
+import os
+
+# This module should be kept compatible with Python 2.1.
+
+__revision__ = "$Id: debug.py 37828 2004-11-10 22:23:15Z loewis $"
+
+# If DISTUTILS_DEBUG is anything other than the empty string, we run in
+# debug mode.
+DEBUG = os.environ.get('DISTUTILS_DEBUG')

Added: vendor/Python/current/Lib/distutils/dep_util.py
===================================================================
--- vendor/Python/current/Lib/distutils/dep_util.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/dep_util.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,95 @@
+"""distutils.dep_util
+
+Utility functions for simple, timestamp-based dependency of files
+and groups of files; also, function based entirely on such
+timestamp dependency analysis."""
+
+# This module should be kept compatible with Python 2.1.
+
+__revision__ = "$Id: dep_util.py 37828 2004-11-10 22:23:15Z loewis $"
+
+import os
+from distutils.errors import DistutilsFileError
+
+
+def newer (source, target):
+    """Return true if 'source' exists and is more recently modified than
+    'target', or if 'source' exists and 'target' doesn't.  Return false if
+    both exist and 'target' is the same age or younger than 'source'.
+    Raise DistutilsFileError if 'source' does not exist.
+    """
+    if not os.path.exists(source):
+        raise DistutilsFileError, "file '%s' does not exist" % source
+    if not os.path.exists(target):
+        return 1
+
+    from stat import ST_MTIME
+    mtime1 = os.stat(source)[ST_MTIME]
+    mtime2 = os.stat(target)[ST_MTIME]
+
+    return mtime1 > mtime2
+
+# newer ()
+
+
+def newer_pairwise (sources, targets):
+    """Walk two filename lists in parallel, testing if each source is newer
+    than its corresponding target.  Return a pair of lists (sources,
+    targets) where source is newer than target, according to the semantics
+    of 'newer()'.
+    """
+    if len(sources) != len(targets):
+        raise ValueError, "'sources' and 'targets' must be same length"
+
+    # build a pair of lists (sources, targets) where  source is newer
+    n_sources = []
+    n_targets = []
+    for i in range(len(sources)):
+        if newer(sources[i], targets[i]):
+            n_sources.append(sources[i])
+            n_targets.append(targets[i])
+
+    return (n_sources, n_targets)
+
+# newer_pairwise ()
+
+
+def newer_group (sources, target, missing='error'):
+    """Return true if 'target' is out-of-date with respect to any file
+    listed in 'sources'.  In other words, if 'target' exists and is newer
+    than every file in 'sources', return false; otherwise return true.
+    'missing' controls what we do when a source file is missing; the
+    default ("error") is to blow up with an OSError from inside 'stat()';
+    if it is "ignore", we silently drop any missing source files; if it is
+    "newer", any missing source files make us assume that 'target' is
+    out-of-date (this is handy in "dry-run" mode: it'll make you pretend to
+    carry out commands that wouldn't work because inputs are missing, but
+    that doesn't matter because you're not actually going to run the
+    commands).
+    """
+    # If the target doesn't even exist, then it's definitely out-of-date.
+    if not os.path.exists(target):
+        return 1
+
+    # Otherwise we have to find out the hard way: if *any* source file
+    # is more recent than 'target', then 'target' is out-of-date and
+    # we can immediately return true.  If we fall through to the end
+    # of the loop, then 'target' is up-to-date and we return false.
+    from stat import ST_MTIME
+    target_mtime = os.stat(target)[ST_MTIME]
+    for source in sources:
+        if not os.path.exists(source):
+            if missing == 'error':      # blow up when we stat() the file
+                pass
+            elif missing == 'ignore':   # missing source dropped from
+                continue                #  target's dependency list
+            elif missing == 'newer':    # missing source means target is
+                return 1                #  out-of-date
+
+        source_mtime = os.stat(source)[ST_MTIME]
+        if source_mtime > target_mtime:
+            return 1
+    else:
+        return 0
+
+# newer_group ()

Added: vendor/Python/current/Lib/distutils/dir_util.py
===================================================================
--- vendor/Python/current/Lib/distutils/dir_util.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/dir_util.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,227 @@
+"""distutils.dir_util
+
+Utility functions for manipulating directories and directory trees."""
+
+# This module should be kept compatible with Python 2.1.
+
+__revision__ = "$Id: dir_util.py 39416 2005-08-26 15:20:46Z tim_one $"
+
+import os, sys
+from types import *
+from distutils.errors import DistutilsFileError, DistutilsInternalError
+from distutils import log
+
+# cache for by mkpath() -- in addition to cheapening redundant calls,
+# eliminates redundant "creating /foo/bar/baz" messages in dry-run mode
+_path_created = {}
+
+# I don't use os.makedirs because a) it's new to Python 1.5.2, and
+# b) it blows up if the directory already exists (I want to silently
+# succeed in that case).
+def mkpath (name, mode=0777, verbose=0, dry_run=0):
+    """Create a directory and any missing ancestor directories.  If the
+       directory already exists (or if 'name' is the empty string, which
+       means the current directory, which of course exists), then do
+       nothing.  Raise DistutilsFileError if unable to create some
+       directory along the way (eg. some sub-path exists, but is a file
+       rather than a directory).  If 'verbose' is true, print a one-line
+       summary of each mkdir to stdout.  Return the list of directories
+       actually created."""
+
+    global _path_created
+
+    # Detect a common bug -- name is None
+    if not isinstance(name, StringTypes):
+        raise DistutilsInternalError, \
+              "mkpath: 'name' must be a string (got %r)" % (name,)
+
+    # XXX what's the better way to handle verbosity? print as we create
+    # each directory in the path (the current behaviour), or only announce
+    # the creation of the whole path? (quite easy to do the latter since
+    # we're not using a recursive algorithm)
+
+    name = os.path.normpath(name)
+    created_dirs = []
+    if os.path.isdir(name) or name == '':
+        return created_dirs
+    if _path_created.get(os.path.abspath(name)):
+        return created_dirs
+
+    (head, tail) = os.path.split(name)
+    tails = [tail]                      # stack of lone dirs to create
+
+    while head and tail and not os.path.isdir(head):
+        #print "splitting '%s': " % head,
+        (head, tail) = os.path.split(head)
+        #print "to ('%s','%s')" % (head, tail)
+        tails.insert(0, tail)          # push next higher dir onto stack
+
+    #print "stack of tails:", tails
+
+    # now 'head' contains the deepest directory that already exists
+    # (that is, the child of 'head' in 'name' is the highest directory
+    # that does *not* exist)
+    for d in tails:
+        #print "head = %s, d = %s: " % (head, d),
+        head = os.path.join(head, d)
+        abs_head = os.path.abspath(head)
+
+        if _path_created.get(abs_head):
+            continue
+
+        log.info("creating %s", head)
+
+        if not dry_run:
+            try:
+                os.mkdir(head)
+                created_dirs.append(head)
+            except OSError, exc:
+                raise DistutilsFileError, \
+                      "could not create '%s': %s" % (head, exc[-1])
+
+        _path_created[abs_head] = 1
+    return created_dirs
+
+# mkpath ()
+
+
+def create_tree (base_dir, files, mode=0777, verbose=0, dry_run=0):
+
+    """Create all the empty directories under 'base_dir' needed to
+       put 'files' there.  'base_dir' is just the a name of a directory
+       which doesn't necessarily exist yet; 'files' is a list of filenames
+       to be interpreted relative to 'base_dir'.  'base_dir' + the
+       directory portion of every file in 'files' will be created if it
+       doesn't already exist.  'mode', 'verbose' and 'dry_run' flags are as
+       for 'mkpath()'."""
+
+    # First get the list of directories to create
+    need_dir = {}
+    for file in files:
+        need_dir[os.path.join(base_dir, os.path.dirname(file))] = 1
+    need_dirs = need_dir.keys()
+    need_dirs.sort()
+
+    # Now create them
+    for dir in need_dirs:
+        mkpath(dir, mode, dry_run=dry_run)
+
+# create_tree ()
+
+
+def copy_tree (src, dst,
+               preserve_mode=1,
+               preserve_times=1,
+               preserve_symlinks=0,
+               update=0,
+               verbose=0,
+               dry_run=0):
+
+    """Copy an entire directory tree 'src' to a new location 'dst'.  Both
+       'src' and 'dst' must be directory names.  If 'src' is not a
+       directory, raise DistutilsFileError.  If 'dst' does not exist, it is
+       created with 'mkpath()'.  The end result of the copy is that every
+       file in 'src' is copied to 'dst', and directories under 'src' are
+       recursively copied to 'dst'.  Return the list of files that were
+       copied or might have been copied, using their output name.  The
+       return value is unaffected by 'update' or 'dry_run': it is simply
+       the list of all files under 'src', with the names changed to be
+       under 'dst'.
+
+       'preserve_mode' and 'preserve_times' are the same as for
+       'copy_file'; note that they only apply to regular files, not to
+       directories.  If 'preserve_symlinks' is true, symlinks will be
+       copied as symlinks (on platforms that support them!); otherwise
+       (the default), the destination of the symlink will be copied.
+       'update' and 'verbose' are the same as for 'copy_file'."""
+
+    from distutils.file_util import copy_file
+
+    if not dry_run and not os.path.isdir(src):
+        raise DistutilsFileError, \
+              "cannot copy tree '%s': not a directory" % src
+    try:
+        names = os.listdir(src)
+    except os.error, (errno, errstr):
+        if dry_run:
+            names = []
+        else:
+            raise DistutilsFileError, \
+                  "error listing files in '%s': %s" % (src, errstr)
+
+    if not dry_run:
+        mkpath(dst)
+
+    outputs = []
+
+    for n in names:
+        src_name = os.path.join(src, n)
+        dst_name = os.path.join(dst, n)
+
+        if preserve_symlinks and os.path.islink(src_name):
+            link_dest = os.readlink(src_name)
+            log.info("linking %s -> %s", dst_name, link_dest)
+            if not dry_run:
+                os.symlink(link_dest, dst_name)
+            outputs.append(dst_name)
+
+        elif os.path.isdir(src_name):
+            outputs.extend(
+                copy_tree(src_name, dst_name, preserve_mode,
+                          preserve_times, preserve_symlinks, update,
+                          dry_run=dry_run))
+        else:
+            copy_file(src_name, dst_name, preserve_mode,
+                      preserve_times, update, dry_run=dry_run)
+            outputs.append(dst_name)
+
+    return outputs
+
+# copy_tree ()
+
+# Helper for remove_tree()
+def _build_cmdtuple(path, cmdtuples):
+    for f in os.listdir(path):
+        real_f = os.path.join(path,f)
+        if os.path.isdir(real_f) and not os.path.islink(real_f):
+            _build_cmdtuple(real_f, cmdtuples)
+        else:
+            cmdtuples.append((os.remove, real_f))
+    cmdtuples.append((os.rmdir, path))
+
+
+def remove_tree (directory, verbose=0, dry_run=0):
+    """Recursively remove an entire directory tree.  Any errors are ignored
+    (apart from being reported to stdout if 'verbose' is true).
+    """
+    from distutils.util import grok_environment_error
+    global _path_created
+
+    log.info("removing '%s' (and everything under it)", directory)
+    if dry_run:
+        return
+    cmdtuples = []
+    _build_cmdtuple(directory, cmdtuples)
+    for cmd in cmdtuples:
+        try:
+            apply(cmd[0], (cmd[1],))
+            # remove dir from cache if it's already there
+            abspath = os.path.abspath(cmd[1])
+            if _path_created.has_key(abspath):
+                del _path_created[abspath]
+        except (IOError, OSError), exc:
+            log.warn(grok_environment_error(
+                    exc, "error removing %s: " % directory))
+
+
+def ensure_relative (path):
+    """Take the full path 'path', and make it a relative path so
+    it can be the second argument to os.path.join().
+    """
+    drive, path = os.path.splitdrive(path)
+    if sys.platform == 'mac':
+        return os.sep + path
+    else:
+        if path[0:1] == os.sep:
+            path = drive + path[1:]
+        return path

Added: vendor/Python/current/Lib/distutils/dist.py
===================================================================
--- vendor/Python/current/Lib/distutils/dist.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/dist.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1222 @@
+"""distutils.dist
+
+Provides the Distribution class, which represents the module distribution
+being built/installed/distributed.
+"""
+
+# This module should be kept compatible with Python 2.1.
+
+__revision__ = "$Id: dist.py 38697 2005-03-23 18:54:36Z loewis $"
+
+import sys, os, string, re
+from types import *
+from copy import copy
+
+try:
+    import warnings
+except ImportError:
+    warnings = None
+
+from distutils.errors import *
+from distutils.fancy_getopt import FancyGetopt, translate_longopt
+from distutils.util import check_environ, strtobool, rfc822_escape
+from distutils import log
+from distutils.debug import DEBUG
+
+# Regex to define acceptable Distutils command names.  This is not *quite*
+# the same as a Python NAME -- I don't allow leading underscores.  The fact
+# that they're very similar is no coincidence; the default naming scheme is
+# to look for a Python module named after the command.
+command_re = re.compile (r'^[a-zA-Z]([a-zA-Z0-9_]*)$')
+
+
+class Distribution:
+    """The core of the Distutils.  Most of the work hiding behind 'setup'
+    is really done within a Distribution instance, which farms the work out
+    to the Distutils commands specified on the command line.
+
+    Setup scripts will almost never instantiate Distribution directly,
+    unless the 'setup()' function is totally inadequate to their needs.
+    However, it is conceivable that a setup script might wish to subclass
+    Distribution for some specialized purpose, and then pass the subclass
+    to 'setup()' as the 'distclass' keyword argument.  If so, it is
+    necessary to respect the expectations that 'setup' has of Distribution.
+    See the code for 'setup()', in core.py, for details.
+    """
+
+
+    # 'global_options' describes the command-line options that may be
+    # supplied to the setup script prior to any actual commands.
+    # Eg. "./setup.py -n" or "./setup.py --quiet" both take advantage of
+    # these global options.  This list should be kept to a bare minimum,
+    # since every global option is also valid as a command option -- and we
+    # don't want to pollute the commands with too many options that they
+    # have minimal control over.
+    # The fourth entry for verbose means that it can be repeated.
+    global_options = [('verbose', 'v', "run verbosely (default)", 1),
+                      ('quiet', 'q', "run quietly (turns verbosity off)"),
+                      ('dry-run', 'n', "don't actually do anything"),
+                      ('help', 'h', "show detailed help message"),
+                     ]
+
+    # 'common_usage' is a short (2-3 line) string describing the common
+    # usage of the setup script.
+    common_usage = """\
+Common commands: (see '--help-commands' for more)
+
+  setup.py build      will build the package underneath 'build/'
+  setup.py install    will install the package
+"""
+
+    # options that are not propagated to the commands
+    display_options = [
+        ('help-commands', None,
+         "list all available commands"),
+        ('name', None,
+         "print package name"),
+        ('version', 'V',
+         "print package version"),
+        ('fullname', None,
+         "print <package name>-<version>"),
+        ('author', None,
+         "print the author's name"),
+        ('author-email', None,
+         "print the author's email address"),
+        ('maintainer', None,
+         "print the maintainer's name"),
+        ('maintainer-email', None,
+         "print the maintainer's email address"),
+        ('contact', None,
+         "print the maintainer's name if known, else the author's"),
+        ('contact-email', None,
+         "print the maintainer's email address if known, else the author's"),
+        ('url', None,
+         "print the URL for this package"),
+        ('license', None,
+         "print the license of the package"),
+        ('licence', None,
+         "alias for --license"),
+        ('description', None,
+         "print the package description"),
+        ('long-description', None,
+         "print the long package description"),
+        ('platforms', None,
+         "print the list of platforms"),
+        ('classifiers', None,
+         "print the list of classifiers"),
+        ('keywords', None,
+         "print the list of keywords"),
+        ('provides', None,
+         "print the list of packages/modules provided"),
+        ('requires', None,
+         "print the list of packages/modules required"),
+        ('obsoletes', None,
+         "print the list of packages/modules made obsolete")
+        ]
+    display_option_names = map(lambda x: translate_longopt(x[0]),
+                               display_options)
+
+    # negative options are options that exclude other options
+    negative_opt = {'quiet': 'verbose'}
+
+
+    # -- Creation/initialization methods -------------------------------
+
+    def __init__ (self, attrs=None):
+        """Construct a new Distribution instance: initialize all the
+        attributes of a Distribution, and then use 'attrs' (a dictionary
+        mapping attribute names to values) to assign some of those
+        attributes their "real" values.  (Any attributes not mentioned in
+        'attrs' will be assigned to some null value: 0, None, an empty list
+        or dictionary, etc.)  Most importantly, initialize the
+        'command_obj' attribute to the empty dictionary; this will be
+        filled in with real command objects by 'parse_command_line()'.
+        """
+
+        # Default values for our command-line options
+        self.verbose = 1
+        self.dry_run = 0
+        self.help = 0
+        for attr in self.display_option_names:
+            setattr(self, attr, 0)
+
+        # Store the distribution meta-data (name, version, author, and so
+        # forth) in a separate object -- we're getting to have enough
+        # information here (and enough command-line options) that it's
+        # worth it.  Also delegate 'get_XXX()' methods to the 'metadata'
+        # object in a sneaky and underhanded (but efficient!) way.
+        self.metadata = DistributionMetadata()
+        for basename in self.metadata._METHOD_BASENAMES:
+            method_name = "get_" + basename
+            setattr(self, method_name, getattr(self.metadata, method_name))
+
+        # 'cmdclass' maps command names to class objects, so we
+        # can 1) quickly figure out which class to instantiate when
+        # we need to create a new command object, and 2) have a way
+        # for the setup script to override command classes
+        self.cmdclass = {}
+
+        # 'command_packages' is a list of packages in which commands
+        # are searched for.  The factory for command 'foo' is expected
+        # to be named 'foo' in the module 'foo' in one of the packages
+        # named here.  This list is searched from the left; an error
+        # is raised if no named package provides the command being
+        # searched for.  (Always access using get_command_packages().)
+        self.command_packages = None
+
+        # 'script_name' and 'script_args' are usually set to sys.argv[0]
+        # and sys.argv[1:], but they can be overridden when the caller is
+        # not necessarily a setup script run from the command-line.
+        self.script_name = None
+        self.script_args = None
+
+        # 'command_options' is where we store command options between
+        # parsing them (from config files, the command-line, etc.) and when
+        # they are actually needed -- ie. when the command in question is
+        # instantiated.  It is a dictionary of dictionaries of 2-tuples:
+        #   command_options = { command_name : { option : (source, value) } }
+        self.command_options = {}
+
+        # 'dist_files' is the list of (command, pyversion, file) that
+        # have been created by any dist commands run so far. This is
+        # filled regardless of whether the run is dry or not. pyversion
+        # gives sysconfig.get_python_version() if the dist file is
+        # specific to a Python version, 'any' if it is good for all
+        # Python versions on the target platform, and '' for a source
+        # file. pyversion should not be used to specify minimum or
+        # maximum required Python versions; use the metainfo for that
+        # instead.
+        self.dist_files = []
+
+        # These options are really the business of various commands, rather
+        # than of the Distribution itself.  We provide aliases for them in
+        # Distribution as a convenience to the developer.
+        self.packages = None
+        self.package_data = {}
+        self.package_dir = None
+        self.py_modules = None
+        self.libraries = None
+        self.headers = None
+        self.ext_modules = None
+        self.ext_package = None
+        self.include_dirs = None
+        self.extra_path = None
+        self.scripts = None
+        self.data_files = None
+
+        # And now initialize bookkeeping stuff that can't be supplied by
+        # the caller at all.  'command_obj' maps command names to
+        # Command instances -- that's how we enforce that every command
+        # class is a singleton.
+        self.command_obj = {}
+
+        # 'have_run' maps command names to boolean values; it keeps track
+        # of whether we have actually run a particular command, to make it
+        # cheap to "run" a command whenever we think we might need to -- if
+        # it's already been done, no need for expensive filesystem
+        # operations, we just check the 'have_run' dictionary and carry on.
+        # It's only safe to query 'have_run' for a command class that has
+        # been instantiated -- a false value will be inserted when the
+        # command object is created, and replaced with a true value when
+        # the command is successfully run.  Thus it's probably best to use
+        # '.get()' rather than a straight lookup.
+        self.have_run = {}
+
+        # Now we'll use the attrs dictionary (ultimately, keyword args from
+        # the setup script) to possibly override any or all of these
+        # distribution options.
+
+        if attrs:
+            # Pull out the set of command options and work on them
+            # specifically.  Note that this order guarantees that aliased
+            # command options will override any supplied redundantly
+            # through the general options dictionary.
+            options = attrs.get('options')
+            if options:
+                del attrs['options']
+                for (command, cmd_options) in options.items():
+                    opt_dict = self.get_option_dict(command)
+                    for (opt, val) in cmd_options.items():
+                        opt_dict[opt] = ("setup script", val)
+
+            if attrs.has_key('licence'):
+                attrs['license'] = attrs['licence']
+                del attrs['licence']
+                msg = "'licence' distribution option is deprecated; use 'license'"
+                if warnings is not None:
+                    warnings.warn(msg)
+                else:
+                    sys.stderr.write(msg + "\n")
+
+            # Now work on the rest of the attributes.  Any attribute that's
+            # not already defined is invalid!
+            for (key,val) in attrs.items():
+                if hasattr(self.metadata, "set_" + key):
+                    getattr(self.metadata, "set_" + key)(val)
+                elif hasattr(self.metadata, key):
+                    setattr(self.metadata, key, val)
+                elif hasattr(self, key):
+                    setattr(self, key, val)
+                else:
+                    msg = "Unknown distribution option: %s" % repr(key)
+                    if warnings is not None:
+                        warnings.warn(msg)
+                    else:
+                        sys.stderr.write(msg + "\n")
+
+        self.finalize_options()
+
+    # __init__ ()
+
+
+    def get_option_dict (self, command):
+        """Get the option dictionary for a given command.  If that
+        command's option dictionary hasn't been created yet, then create it
+        and return the new dictionary; otherwise, return the existing
+        option dictionary.
+        """
+
+        dict = self.command_options.get(command)
+        if dict is None:
+            dict = self.command_options[command] = {}
+        return dict
+
+
+    def dump_option_dicts (self, header=None, commands=None, indent=""):
+        from pprint import pformat
+
+        if commands is None:             # dump all command option dicts
+            commands = self.command_options.keys()
+            commands.sort()
+
+        if header is not None:
+            print indent + header
+            indent = indent + "  "
+
+        if not commands:
+            print indent + "no commands known yet"
+            return
+
+        for cmd_name in commands:
+            opt_dict = self.command_options.get(cmd_name)
+            if opt_dict is None:
+                print indent + "no option dict for '%s' command" % cmd_name
+            else:
+                print indent + "option dict for '%s' command:" % cmd_name
+                out = pformat(opt_dict)
+                for line in string.split(out, "\n"):
+                    print indent + "  " + line
+
+    # dump_option_dicts ()
+
+
+
+    # -- Config file finding/parsing methods ---------------------------
+
+    def find_config_files (self):
+        """Find as many configuration files as should be processed for this
+        platform, and return a list of filenames in the order in which they
+        should be parsed.  The filenames returned are guaranteed to exist
+        (modulo nasty race conditions).
+
+        There are three possible config files: distutils.cfg in the
+        Distutils installation directory (ie. where the top-level
+        Distutils __inst__.py file lives), a file in the user's home
+        directory named .pydistutils.cfg on Unix and pydistutils.cfg
+        on Windows/Mac, and setup.cfg in the current directory.
+        """
+        files = []
+        check_environ()
+
+        # Where to look for the system-wide Distutils config file
+        sys_dir = os.path.dirname(sys.modules['distutils'].__file__)
+
+        # Look for the system config file
+        sys_file = os.path.join(sys_dir, "distutils.cfg")
+        if os.path.isfile(sys_file):
+            files.append(sys_file)
+
+        # What to call the per-user config file
+        if os.name == 'posix':
+            user_filename = ".pydistutils.cfg"
+        else:
+            user_filename = "pydistutils.cfg"
+
+        # And look for the user config file
+        if os.environ.has_key('HOME'):
+            user_file = os.path.join(os.environ.get('HOME'), user_filename)
+            if os.path.isfile(user_file):
+                files.append(user_file)
+
+        # All platforms support local setup.cfg
+        local_file = "setup.cfg"
+        if os.path.isfile(local_file):
+            files.append(local_file)
+
+        return files
+
+    # find_config_files ()
+
+
+    def parse_config_files (self, filenames=None):
+
+        from ConfigParser import ConfigParser
+
+        if filenames is None:
+            filenames = self.find_config_files()
+
+        if DEBUG: print "Distribution.parse_config_files():"
+
+        parser = ConfigParser()
+        for filename in filenames:
+            if DEBUG: print "  reading", filename
+            parser.read(filename)
+            for section in parser.sections():
+                options = parser.options(section)
+                opt_dict = self.get_option_dict(section)
+
+                for opt in options:
+                    if opt != '__name__':
+                        val = parser.get(section,opt)
+                        opt = string.replace(opt, '-', '_')
+                        opt_dict[opt] = (filename, val)
+
+            # Make the ConfigParser forget everything (so we retain
+            # the original filenames that options come from)
+            parser.__init__()
+
+        # If there was a "global" section in the config file, use it
+        # to set Distribution options.
+
+        if self.command_options.has_key('global'):
+            for (opt, (src, val)) in self.command_options['global'].items():
+                alias = self.negative_opt.get(opt)
+                try:
+                    if alias:
+                        setattr(self, alias, not strtobool(val))
+                    elif opt in ('verbose', 'dry_run'): # ugh!
+                        setattr(self, opt, strtobool(val))
+                    else:
+                        setattr(self, opt, val)
+                except ValueError, msg:
+                    raise DistutilsOptionError, msg
+
+    # parse_config_files ()
+
+
+    # -- Command-line parsing methods ----------------------------------
+
+    def parse_command_line (self):
+        """Parse the setup script's command line, taken from the
+        'script_args' instance attribute (which defaults to 'sys.argv[1:]'
+        -- see 'setup()' in core.py).  This list is first processed for
+        "global options" -- options that set attributes of the Distribution
+        instance.  Then, it is alternately scanned for Distutils commands
+        and options for that command.  Each new command terminates the
+        options for the previous command.  The allowed options for a
+        command are determined by the 'user_options' attribute of the
+        command class -- thus, we have to be able to load command classes
+        in order to parse the command line.  Any error in that 'options'
+        attribute raises DistutilsGetoptError; any error on the
+        command-line raises DistutilsArgError.  If no Distutils commands
+        were found on the command line, raises DistutilsArgError.  Return
+        true if command-line was successfully parsed and we should carry
+        on with executing commands; false if no errors but we shouldn't
+        execute commands (currently, this only happens if user asks for
+        help).
+        """
+        #
+        # We now have enough information to show the Macintosh dialog
+        # that allows the user to interactively specify the "command line".
+        #
+        toplevel_options = self._get_toplevel_options()
+        if sys.platform == 'mac':
+            import EasyDialogs
+            cmdlist = self.get_command_list()
+            self.script_args = EasyDialogs.GetArgv(
+                toplevel_options + self.display_options, cmdlist)
+
+        # We have to parse the command line a bit at a time -- global
+        # options, then the first command, then its options, and so on --
+        # because each command will be handled by a different class, and
+        # the options that are valid for a particular class aren't known
+        # until we have loaded the command class, which doesn't happen
+        # until we know what the command is.
+
+        self.commands = []
+        parser = FancyGetopt(toplevel_options + self.display_options)
+        parser.set_negative_aliases(self.negative_opt)
+        parser.set_aliases({'licence': 'license'})
+        args = parser.getopt(args=self.script_args, object=self)
+        option_order = parser.get_option_order()
+        log.set_verbosity(self.verbose)
+
+        # for display options we return immediately
+        if self.handle_display_options(option_order):
+            return
+
+        while args:
+            args = self._parse_command_opts(parser, args)
+            if args is None:            # user asked for help (and got it)
+                return
+
+        # Handle the cases of --help as a "global" option, ie.
+        # "setup.py --help" and "setup.py --help command ...".  For the
+        # former, we show global options (--verbose, --dry-run, etc.)
+        # and display-only options (--name, --version, etc.); for the
+        # latter, we omit the display-only options and show help for
+        # each command listed on the command line.
+        if self.help:
+            self._show_help(parser,
+                            display_options=len(self.commands) == 0,
+                            commands=self.commands)
+            return
+
+        # Oops, no commands found -- an end-user error
+        if not self.commands:
+            raise DistutilsArgError, "no commands supplied"
+
+        # All is well: return true
+        return 1
+
+    # parse_command_line()
+
+    def _get_toplevel_options (self):
+        """Return the non-display options recognized at the top level.
+
+        This includes options that are recognized *only* at the top
+        level as well as options recognized for commands.
+        """
+        return self.global_options + [
+            ("command-packages=", None,
+             "list of packages that provide distutils commands"),
+            ]
+
+    def _parse_command_opts (self, parser, args):
+        """Parse the command-line options for a single command.
+        'parser' must be a FancyGetopt instance; 'args' must be the list
+        of arguments, starting with the current command (whose options
+        we are about to parse).  Returns a new version of 'args' with
+        the next command at the front of the list; will be the empty
+        list if there are no more commands on the command line.  Returns
+        None if the user asked for help on this command.
+        """
+        # late import because of mutual dependence between these modules
+        from distutils.cmd import Command
+
+        # Pull the current command from the head of the command line
+        command = args[0]
+        if not command_re.match(command):
+            raise SystemExit, "invalid command name '%s'" % command
+        self.commands.append(command)
+
+        # Dig up the command class that implements this command, so we
+        # 1) know that it's a valid command, and 2) know which options
+        # it takes.
+        try:
+            cmd_class = self.get_command_class(command)
+        except DistutilsModuleError, msg:
+            raise DistutilsArgError, msg
+
+        # Require that the command class be derived from Command -- want
+        # to be sure that the basic "command" interface is implemented.
+        if not issubclass(cmd_class, Command):
+            raise DistutilsClassError, \
+                  "command class %s must subclass Command" % cmd_class
+
+        # Also make sure that the command object provides a list of its
+        # known options.
+        if not (hasattr(cmd_class, 'user_options') and
+                type(cmd_class.user_options) is ListType):
+            raise DistutilsClassError, \
+                  ("command class %s must provide " +
+                   "'user_options' attribute (a list of tuples)") % \
+                  cmd_class
+
+        # If the command class has a list of negative alias options,
+        # merge it in with the global negative aliases.
+        negative_opt = self.negative_opt
+        if hasattr(cmd_class, 'negative_opt'):
+            negative_opt = copy(negative_opt)
+            negative_opt.update(cmd_class.negative_opt)
+
+        # Check for help_options in command class.  They have a different
+        # format (tuple of four) so we need to preprocess them here.
+        if (hasattr(cmd_class, 'help_options') and
+            type(cmd_class.help_options) is ListType):
+            help_options = fix_help_options(cmd_class.help_options)
+        else:
+            help_options = []
+
+
+        # All commands support the global options too, just by adding
+        # in 'global_options'.
+        parser.set_option_table(self.global_options +
+                                cmd_class.user_options +
+                                help_options)
+        parser.set_negative_aliases(negative_opt)
+        (args, opts) = parser.getopt(args[1:])
+        if hasattr(opts, 'help') and opts.help:
+            self._show_help(parser, display_options=0, commands=[cmd_class])
+            return
+
+        if (hasattr(cmd_class, 'help_options') and
+            type(cmd_class.help_options) is ListType):
+            help_option_found=0
+            for (help_option, short, desc, func) in cmd_class.help_options:
+                if hasattr(opts, parser.get_attr_name(help_option)):
+                    help_option_found=1
+                    #print "showing help for option %s of command %s" % \
+                    #      (help_option[0],cmd_class)
+
+                    if callable(func):
+                        func()
+                    else:
+                        raise DistutilsClassError(
+                            "invalid help function %r for help option '%s': "
+                            "must be a callable object (function, etc.)"
+                            % (func, help_option))
+
+            if help_option_found:
+                return
+
+        # Put the options from the command-line into their official
+        # holding pen, the 'command_options' dictionary.
+        opt_dict = self.get_option_dict(command)
+        for (name, value) in vars(opts).items():
+            opt_dict[name] = ("command line", value)
+
+        return args
+
+    # _parse_command_opts ()
+
+    def finalize_options (self):
+        """Set final values for all the options on the Distribution
+        instance, analogous to the .finalize_options() method of Command
+        objects.
+        """
+
+        keywords = self.metadata.keywords
+        if keywords is not None:
+            if type(keywords) is StringType:
+                keywordlist = string.split(keywords, ',')
+                self.metadata.keywords = map(string.strip, keywordlist)
+
+        platforms = self.metadata.platforms
+        if platforms is not None:
+            if type(platforms) is StringType:
+                platformlist = string.split(platforms, ',')
+                self.metadata.platforms = map(string.strip, platformlist)
+
+    def _show_help (self,
+                    parser,
+                    global_options=1,
+                    display_options=1,
+                    commands=[]):
+        """Show help for the setup script command-line in the form of
+        several lists of command-line options.  'parser' should be a
+        FancyGetopt instance; do not expect it to be returned in the
+        same state, as its option table will be reset to make it
+        generate the correct help text.
+
+        If 'global_options' is true, lists the global options:
+        --verbose, --dry-run, etc.  If 'display_options' is true, lists
+        the "display-only" options: --name, --version, etc.  Finally,
+        lists per-command help for every command name or command class
+        in 'commands'.
+        """
+        # late import because of mutual dependence between these modules
+        from distutils.core import gen_usage
+        from distutils.cmd import Command
+
+        if global_options:
+            if display_options:
+                options = self._get_toplevel_options()
+            else:
+                options = self.global_options
+            parser.set_option_table(options)
+            parser.print_help(self.common_usage + "\nGlobal options:")
+            print
+
+        if display_options:
+            parser.set_option_table(self.display_options)
+            parser.print_help(
+                "Information display options (just display " +
+                "information, ignore any commands)")
+            print
+
+        for command in self.commands:
+            if type(command) is ClassType and issubclass(command, Command):
+                klass = command
+            else:
+                klass = self.get_command_class(command)
+            if (hasattr(klass, 'help_options') and
+                type(klass.help_options) is ListType):
+                parser.set_option_table(klass.user_options +
+                                        fix_help_options(klass.help_options))
+            else:
+                parser.set_option_table(klass.user_options)
+            parser.print_help("Options for '%s' command:" % klass.__name__)
+            print
+
+        print gen_usage(self.script_name)
+        return
+
+    # _show_help ()
+
+
+    def handle_display_options (self, option_order):
+        """If there were any non-global "display-only" options
+        (--help-commands or the metadata display options) on the command
+        line, display the requested info and return true; else return
+        false.
+        """
+        from distutils.core import gen_usage
+
+        # User just wants a list of commands -- we'll print it out and stop
+        # processing now (ie. if they ran "setup --help-commands foo bar",
+        # we ignore "foo bar").
+        if self.help_commands:
+            self.print_commands()
+            print
+            print gen_usage(self.script_name)
+            return 1
+
+        # If user supplied any of the "display metadata" options, then
+        # display that metadata in the order in which the user supplied the
+        # metadata options.
+        any_display_options = 0
+        is_display_option = {}
+        for option in self.display_options:
+            is_display_option[option[0]] = 1
+
+        for (opt, val) in option_order:
+            if val and is_display_option.get(opt):
+                opt = translate_longopt(opt)
+                value = getattr(self.metadata, "get_"+opt)()
+                if opt in ['keywords', 'platforms']:
+                    print string.join(value, ',')
+                elif opt in ('classifiers', 'provides', 'requires',
+                             'obsoletes'):
+                    print string.join(value, '\n')
+                else:
+                    print value
+                any_display_options = 1
+
+        return any_display_options
+
+    # handle_display_options()
+
+    def print_command_list (self, commands, header, max_length):
+        """Print a subset of the list of all commands -- used by
+        'print_commands()'.
+        """
+
+        print header + ":"
+
+        for cmd in commands:
+            klass = self.cmdclass.get(cmd)
+            if not klass:
+                klass = self.get_command_class(cmd)
+            try:
+                description = klass.description
+            except AttributeError:
+                description = "(no description available)"
+
+            print "  %-*s  %s" % (max_length, cmd, description)
+
+    # print_command_list ()
+
+
+    def print_commands (self):
+        """Print out a help message listing all available commands with a
+        description of each.  The list is divided into "standard commands"
+        (listed in distutils.command.__all__) and "extra commands"
+        (mentioned in self.cmdclass, but not a standard command).  The
+        descriptions come from the command class attribute
+        'description'.
+        """
+
+        import distutils.command
+        std_commands = distutils.command.__all__
+        is_std = {}
+        for cmd in std_commands:
+            is_std[cmd] = 1
+
+        extra_commands = []
+        for cmd in self.cmdclass.keys():
+            if not is_std.get(cmd):
+                extra_commands.append(cmd)
+
+        max_length = 0
+        for cmd in (std_commands + extra_commands):
+            if len(cmd) > max_length:
+                max_length = len(cmd)
+
+        self.print_command_list(std_commands,
+                                "Standard commands",
+                                max_length)
+        if extra_commands:
+            print
+            self.print_command_list(extra_commands,
+                                    "Extra commands",
+                                    max_length)
+
+    # print_commands ()
+
+    def get_command_list (self):
+        """Get a list of (command, description) tuples.
+        The list is divided into "standard commands" (listed in
+        distutils.command.__all__) and "extra commands" (mentioned in
+        self.cmdclass, but not a standard command).  The descriptions come
+        from the command class attribute 'description'.
+        """
+        # Currently this is only used on Mac OS, for the Mac-only GUI
+        # Distutils interface (by Jack Jansen)
+
+        import distutils.command
+        std_commands = distutils.command.__all__
+        is_std = {}
+        for cmd in std_commands:
+            is_std[cmd] = 1
+
+        extra_commands = []
+        for cmd in self.cmdclass.keys():
+            if not is_std.get(cmd):
+                extra_commands.append(cmd)
+
+        rv = []
+        for cmd in (std_commands + extra_commands):
+            klass = self.cmdclass.get(cmd)
+            if not klass:
+                klass = self.get_command_class(cmd)
+            try:
+                description = klass.description
+            except AttributeError:
+                description = "(no description available)"
+            rv.append((cmd, description))
+        return rv
+
+    # -- Command class/object methods ----------------------------------
+
+    def get_command_packages (self):
+        """Return a list of packages from which commands are loaded."""
+        pkgs = self.command_packages
+        if not isinstance(pkgs, type([])):
+            pkgs = string.split(pkgs or "", ",")
+            for i in range(len(pkgs)):
+                pkgs[i] = string.strip(pkgs[i])
+            pkgs = filter(None, pkgs)
+            if "distutils.command" not in pkgs:
+                pkgs.insert(0, "distutils.command")
+            self.command_packages = pkgs
+        return pkgs
+
+    def get_command_class (self, command):
+        """Return the class that implements the Distutils command named by
+        'command'.  First we check the 'cmdclass' dictionary; if the
+        command is mentioned there, we fetch the class object from the
+        dictionary and return it.  Otherwise we load the command module
+        ("distutils.command." + command) and fetch the command class from
+        the module.  The loaded class is also stored in 'cmdclass'
+        to speed future calls to 'get_command_class()'.
+
+        Raises DistutilsModuleError if the expected module could not be
+        found, or if that module does not define the expected class.
+        """
+        klass = self.cmdclass.get(command)
+        if klass:
+            return klass
+
+        for pkgname in self.get_command_packages():
+            module_name = "%s.%s" % (pkgname, command)
+            klass_name = command
+
+            try:
+                __import__ (module_name)
+                module = sys.modules[module_name]
+            except ImportError:
+                continue
+
+            try:
+                klass = getattr(module, klass_name)
+            except AttributeError:
+                raise DistutilsModuleError, \
+                      "invalid command '%s' (no class '%s' in module '%s')" \
+                      % (command, klass_name, module_name)
+
+            self.cmdclass[command] = klass
+            return klass
+
+        raise DistutilsModuleError("invalid command '%s'" % command)
+
+
+    # get_command_class ()
+
+    def get_command_obj (self, command, create=1):
+        """Return the command object for 'command'.  Normally this object
+        is cached on a previous call to 'get_command_obj()'; if no command
+        object for 'command' is in the cache, then we either create and
+        return it (if 'create' is true) or return None.
+        """
+        cmd_obj = self.command_obj.get(command)
+        if not cmd_obj and create:
+            if DEBUG:
+                print "Distribution.get_command_obj(): " \
+                      "creating '%s' command object" % command
+
+            klass = self.get_command_class(command)
+            cmd_obj = self.command_obj[command] = klass(self)
+            self.have_run[command] = 0
+
+            # Set any options that were supplied in config files
+            # or on the command line.  (NB. support for error
+            # reporting is lame here: any errors aren't reported
+            # until 'finalize_options()' is called, which means
+            # we won't report the source of the error.)
+            options = self.command_options.get(command)
+            if options:
+                self._set_command_options(cmd_obj, options)
+
+        return cmd_obj
+
+    def _set_command_options (self, command_obj, option_dict=None):
+        """Set the options for 'command_obj' from 'option_dict'.  Basically
+        this means copying elements of a dictionary ('option_dict') to
+        attributes of an instance ('command').
+
+        'command_obj' must be a Command instance.  If 'option_dict' is not
+        supplied, uses the standard option dictionary for this command
+        (from 'self.command_options').
+        """
+        command_name = command_obj.get_command_name()
+        if option_dict is None:
+            option_dict = self.get_option_dict(command_name)
+
+        if DEBUG: print "  setting options for '%s' command:" % command_name
+        for (option, (source, value)) in option_dict.items():
+            if DEBUG: print "    %s = %s (from %s)" % (option, value, source)
+            try:
+                bool_opts = map(translate_longopt, command_obj.boolean_options)
+            except AttributeError:
+                bool_opts = []
+            try:
+                neg_opt = command_obj.negative_opt
+            except AttributeError:
+                neg_opt = {}
+
+            try:
+                is_string = type(value) is StringType
+                if neg_opt.has_key(option) and is_string:
+                    setattr(command_obj, neg_opt[option], not strtobool(value))
+                elif option in bool_opts and is_string:
+                    setattr(command_obj, option, strtobool(value))
+                elif hasattr(command_obj, option):
+                    setattr(command_obj, option, value)
+                else:
+                    raise DistutilsOptionError, \
+                          ("error in %s: command '%s' has no such option '%s'"
+                           % (source, command_name, option))
+            except ValueError, msg:
+                raise DistutilsOptionError, msg
+
+    def reinitialize_command (self, command, reinit_subcommands=0):
+        """Reinitializes a command to the state it was in when first
+        returned by 'get_command_obj()': ie., initialized but not yet
+        finalized.  This provides the opportunity to sneak option
+        values in programmatically, overriding or supplementing
+        user-supplied values from the config files and command line.
+        You'll have to re-finalize the command object (by calling
+        'finalize_options()' or 'ensure_finalized()') before using it for
+        real.
+
+        'command' should be a command name (string) or command object.  If
+        'reinit_subcommands' is true, also reinitializes the command's
+        sub-commands, as declared by the 'sub_commands' class attribute (if
+        it has one).  See the "install" command for an example.  Only
+        reinitializes the sub-commands that actually matter, ie. those
+        whose test predicates return true.
+
+        Returns the reinitialized command object.
+        """
+        from distutils.cmd import Command
+        if not isinstance(command, Command):
+            command_name = command
+            command = self.get_command_obj(command_name)
+        else:
+            command_name = command.get_command_name()
+
+        if not command.finalized:
+            return command
+        command.initialize_options()
+        command.finalized = 0
+        self.have_run[command_name] = 0
+        self._set_command_options(command)
+
+        if reinit_subcommands:
+            for sub in command.get_sub_commands():
+                self.reinitialize_command(sub, reinit_subcommands)
+
+        return command
+
+
+    # -- Methods that operate on the Distribution ----------------------
+
+    def announce (self, msg, level=1):
+        log.debug(msg)
+
+    def run_commands (self):
+        """Run each command that was seen on the setup script command line.
+        Uses the list of commands found and cache of command objects
+        created by 'get_command_obj()'.
+        """
+        for cmd in self.commands:
+            self.run_command(cmd)
+
+
+    # -- Methods that operate on its Commands --------------------------
+
+    def run_command (self, command):
+        """Do whatever it takes to run a command (including nothing at all,
+        if the command has already been run).  Specifically: if we have
+        already created and run the command named by 'command', return
+        silently without doing anything.  If the command named by 'command'
+        doesn't even have a command object yet, create one.  Then invoke
+        'run()' on that command object (or an existing one).
+        """
+        # Already been here, done that? then return silently.
+        if self.have_run.get(command):
+            return
+
+        log.info("running %s", command)
+        cmd_obj = self.get_command_obj(command)
+        cmd_obj.ensure_finalized()
+        cmd_obj.run()
+        self.have_run[command] = 1
+
+
+    # -- Distribution query methods ------------------------------------
+
+    def has_pure_modules (self):
+        return len(self.packages or self.py_modules or []) > 0
+
+    def has_ext_modules (self):
+        return self.ext_modules and len(self.ext_modules) > 0
+
+    def has_c_libraries (self):
+        return self.libraries and len(self.libraries) > 0
+
+    def has_modules (self):
+        return self.has_pure_modules() or self.has_ext_modules()
+
+    def has_headers (self):
+        return self.headers and len(self.headers) > 0
+
+    def has_scripts (self):
+        return self.scripts and len(self.scripts) > 0
+
+    def has_data_files (self):
+        return self.data_files and len(self.data_files) > 0
+
+    def is_pure (self):
+        return (self.has_pure_modules() and
+                not self.has_ext_modules() and
+                not self.has_c_libraries())
+
+    # -- Metadata query methods ----------------------------------------
+
+    # If you're looking for 'get_name()', 'get_version()', and so forth,
+    # they are defined in a sneaky way: the constructor binds self.get_XXX
+    # to self.metadata.get_XXX.  The actual code is in the
+    # DistributionMetadata class, below.
+
+# class Distribution
+
+
+class DistributionMetadata:
+    """Dummy class to hold the distribution meta-data: name, version,
+    author, and so forth.
+    """
+
+    _METHOD_BASENAMES = ("name", "version", "author", "author_email",
+                         "maintainer", "maintainer_email", "url",
+                         "license", "description", "long_description",
+                         "keywords", "platforms", "fullname", "contact",
+                         "contact_email", "license", "classifiers",
+                         "download_url",
+                         # PEP 314
+                         "provides", "requires", "obsoletes",
+                         )
+
+    def __init__ (self):
+        self.name = None
+        self.version = None
+        self.author = None
+        self.author_email = None
+        self.maintainer = None
+        self.maintainer_email = None
+        self.url = None
+        self.license = None
+        self.description = None
+        self.long_description = None
+        self.keywords = None
+        self.platforms = None
+        self.classifiers = None
+        self.download_url = None
+        # PEP 314
+        self.provides = None
+        self.requires = None
+        self.obsoletes = None
+
+    def write_pkg_info (self, base_dir):
+        """Write the PKG-INFO file into the release tree.
+        """
+        pkg_info = open( os.path.join(base_dir, 'PKG-INFO'), 'w')
+
+        self.write_pkg_file(pkg_info)
+
+        pkg_info.close()
+
+    # write_pkg_info ()
+
+    def write_pkg_file (self, file):
+        """Write the PKG-INFO format data to a file object.
+        """
+        version = '1.0'
+        if self.provides or self.requires or self.obsoletes:
+            version = '1.1'
+
+        file.write('Metadata-Version: %s\n' % version)
+        file.write('Name: %s\n' % self.get_name() )
+        file.write('Version: %s\n' % self.get_version() )
+        file.write('Summary: %s\n' % self.get_description() )
+        file.write('Home-page: %s\n' % self.get_url() )
+        file.write('Author: %s\n' % self.get_contact() )
+        file.write('Author-email: %s\n' % self.get_contact_email() )
+        file.write('License: %s\n' % self.get_license() )
+        if self.download_url:
+            file.write('Download-URL: %s\n' % self.download_url)
+
+        long_desc = rfc822_escape( self.get_long_description() )
+        file.write('Description: %s\n' % long_desc)
+
+        keywords = string.join( self.get_keywords(), ',')
+        if keywords:
+            file.write('Keywords: %s\n' % keywords )
+
+        self._write_list(file, 'Platform', self.get_platforms())
+        self._write_list(file, 'Classifier', self.get_classifiers())
+
+        # PEP 314
+        self._write_list(file, 'Requires', self.get_requires())
+        self._write_list(file, 'Provides', self.get_provides())
+        self._write_list(file, 'Obsoletes', self.get_obsoletes())
+
+    def _write_list (self, file, name, values):
+        for value in values:
+            file.write('%s: %s\n' % (name, value))
+
+    # -- Metadata query methods ----------------------------------------
+
+    def get_name (self):
+        return self.name or "UNKNOWN"
+
+    def get_version(self):
+        return self.version or "0.0.0"
+
+    def get_fullname (self):
+        return "%s-%s" % (self.get_name(), self.get_version())
+
+    def get_author(self):
+        return self.author or "UNKNOWN"
+
+    def get_author_email(self):
+        return self.author_email or "UNKNOWN"
+
+    def get_maintainer(self):
+        return self.maintainer or "UNKNOWN"
+
+    def get_maintainer_email(self):
+        return self.maintainer_email or "UNKNOWN"
+
+    def get_contact(self):
+        return (self.maintainer or
+                self.author or
+                "UNKNOWN")
+
+    def get_contact_email(self):
+        return (self.maintainer_email or
+                self.author_email or
+                "UNKNOWN")
+
+    def get_url(self):
+        return self.url or "UNKNOWN"
+
+    def get_license(self):
+        return self.license or "UNKNOWN"
+    get_licence = get_license
+
+    def get_description(self):
+        return self.description or "UNKNOWN"
+
+    def get_long_description(self):
+        return self.long_description or "UNKNOWN"
+
+    def get_keywords(self):
+        return self.keywords or []
+
+    def get_platforms(self):
+        return self.platforms or ["UNKNOWN"]
+
+    def get_classifiers(self):
+        return self.classifiers or []
+
+    def get_download_url(self):
+        return self.download_url or "UNKNOWN"
+
+    # PEP 314
+
+    def get_requires(self):
+        return self.requires or []
+
+    def set_requires(self, value):
+        import distutils.versionpredicate
+        for v in value:
+            distutils.versionpredicate.VersionPredicate(v)
+        self.requires = value
+
+    def get_provides(self):
+        return self.provides or []
+
+    def set_provides(self, value):
+        value = [v.strip() for v in value]
+        for v in value:
+            import distutils.versionpredicate
+            distutils.versionpredicate.split_provision(v)
+        self.provides = value
+
+    def get_obsoletes(self):
+        return self.obsoletes or []
+
+    def set_obsoletes(self, value):
+        import distutils.versionpredicate
+        for v in value:
+            distutils.versionpredicate.VersionPredicate(v)
+        self.obsoletes = value
+
+# class DistributionMetadata
+
+
+def fix_help_options (options):
+    """Convert a 4-tuple 'help_options' list as found in various command
+    classes to the 3-tuple form required by FancyGetopt.
+    """
+    new_options = []
+    for help_tuple in options:
+        new_options.append(help_tuple[0:3])
+    return new_options
+
+
+if __name__ == "__main__":
+    dist = Distribution()
+    print "ok"

Added: vendor/Python/current/Lib/distutils/emxccompiler.py
===================================================================
--- vendor/Python/current/Lib/distutils/emxccompiler.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/emxccompiler.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,315 @@
+"""distutils.emxccompiler
+
+Provides the EMXCCompiler class, a subclass of UnixCCompiler that
+handles the EMX port of the GNU C compiler to OS/2.
+"""
+
+# issues:
+#
+# * OS/2 insists that DLLs can have names no longer than 8 characters
+#   We put export_symbols in a def-file, as though the DLL can have
+#   an arbitrary length name, but truncate the output filename.
+#
+# * only use OMF objects and use LINK386 as the linker (-Zomf)
+#
+# * always build for multithreading (-Zmt) as the accompanying OS/2 port
+#   of Python is only distributed with threads enabled.
+#
+# tested configurations:
+#
+# * EMX gcc 2.81/EMX 0.9d fix03
+
+__revision__ = "$Id: emxccompiler.py 34786 2003-12-02 12:17:59Z aimacintyre $"
+
+import os,sys,copy
+from distutils.ccompiler import gen_preprocess_options, gen_lib_options
+from distutils.unixccompiler import UnixCCompiler
+from distutils.file_util import write_file
+from distutils.errors import DistutilsExecError, CompileError, UnknownFileError
+from distutils import log
+
+class EMXCCompiler (UnixCCompiler):
+
+    compiler_type = 'emx'
+    obj_extension = ".obj"
+    static_lib_extension = ".lib"
+    shared_lib_extension = ".dll"
+    static_lib_format = "%s%s"
+    shared_lib_format = "%s%s"
+    res_extension = ".res"      # compiled resource file
+    exe_extension = ".exe"
+
+    def __init__ (self,
+                  verbose=0,
+                  dry_run=0,
+                  force=0):
+
+        UnixCCompiler.__init__ (self, verbose, dry_run, force)
+
+        (status, details) = check_config_h()
+        self.debug_print("Python's GCC status: %s (details: %s)" %
+                         (status, details))
+        if status is not CONFIG_H_OK:
+            self.warn(
+                "Python's pyconfig.h doesn't seem to support your compiler.  " +
+                ("Reason: %s." % details) +
+                "Compiling may fail because of undefined preprocessor macros.")
+
+        (self.gcc_version, self.ld_version) = \
+            get_versions()
+        self.debug_print(self.compiler_type + ": gcc %s, ld %s\n" %
+                         (self.gcc_version,
+                          self.ld_version) )
+
+        # Hard-code GCC because that's what this is all about.
+        # XXX optimization, warnings etc. should be customizable.
+        self.set_executables(compiler='gcc -Zomf -Zmt -O3 -fomit-frame-pointer -mprobe -Wall',
+                             compiler_so='gcc -Zomf -Zmt -O3 -fomit-frame-pointer -mprobe -Wall',
+                             linker_exe='gcc -Zomf -Zmt -Zcrtdll',
+                             linker_so='gcc -Zomf -Zmt -Zcrtdll -Zdll')
+
+        # want the gcc library statically linked (so that we don't have
+        # to distribute a version dependent on the compiler we have)
+        self.dll_libraries=["gcc"]
+
+    # __init__ ()
+
+    def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts):
+        if ext == '.rc':
+            # gcc requires '.rc' compiled to binary ('.res') files !!!
+            try:
+                self.spawn(["rc", "-r", src])
+            except DistutilsExecError, msg:
+                raise CompileError, msg
+        else: # for other files use the C-compiler
+            try:
+                self.spawn(self.compiler_so + cc_args + [src, '-o', obj] +
+                           extra_postargs)
+            except DistutilsExecError, msg:
+                raise CompileError, msg
+
+    def link (self,
+              target_desc,
+              objects,
+              output_filename,
+              output_dir=None,
+              libraries=None,
+              library_dirs=None,
+              runtime_library_dirs=None,
+              export_symbols=None,
+              debug=0,
+              extra_preargs=None,
+              extra_postargs=None,
+              build_temp=None,
+              target_lang=None):
+
+        # use separate copies, so we can modify the lists
+        extra_preargs = copy.copy(extra_preargs or [])
+        libraries = copy.copy(libraries or [])
+        objects = copy.copy(objects or [])
+
+        # Additional libraries
+        libraries.extend(self.dll_libraries)
+
+        # handle export symbols by creating a def-file
+        # with executables this only works with gcc/ld as linker
+        if ((export_symbols is not None) and
+            (target_desc != self.EXECUTABLE)):
+            # (The linker doesn't do anything if output is up-to-date.
+            # So it would probably better to check if we really need this,
+            # but for this we had to insert some unchanged parts of
+            # UnixCCompiler, and this is not what we want.)
+
+            # we want to put some files in the same directory as the
+            # object files are, build_temp doesn't help much
+            # where are the object files
+            temp_dir = os.path.dirname(objects[0])
+            # name of dll to give the helper files the same base name
+            (dll_name, dll_extension) = os.path.splitext(
+                os.path.basename(output_filename))
+
+            # generate the filenames for these files
+            def_file = os.path.join(temp_dir, dll_name + ".def")
+
+            # Generate .def file
+            contents = [
+                "LIBRARY %s INITINSTANCE TERMINSTANCE" % \
+                os.path.splitext(os.path.basename(output_filename))[0],
+                "DATA MULTIPLE NONSHARED",
+                "EXPORTS"]
+            for sym in export_symbols:
+                contents.append('  "%s"' % sym)
+            self.execute(write_file, (def_file, contents),
+                         "writing %s" % def_file)
+
+            # next add options for def-file and to creating import libraries
+            # for gcc/ld the def-file is specified as any other object files
+            objects.append(def_file)
+
+        #end: if ((export_symbols is not None) and
+        #        (target_desc != self.EXECUTABLE or self.linker_dll == "gcc")):
+
+        # who wants symbols and a many times larger output file
+        # should explicitly switch the debug mode on
+        # otherwise we let dllwrap/ld strip the output file
+        # (On my machine: 10KB < stripped_file < ??100KB
+        #   unstripped_file = stripped_file + XXX KB
+        #  ( XXX=254 for a typical python extension))
+        if not debug:
+            extra_preargs.append("-s")
+
+        UnixCCompiler.link(self,
+                           target_desc,
+                           objects,
+                           output_filename,
+                           output_dir,
+                           libraries,
+                           library_dirs,
+                           runtime_library_dirs,
+                           None, # export_symbols, we do this in our def-file
+                           debug,
+                           extra_preargs,
+                           extra_postargs,
+                           build_temp,
+                           target_lang)
+
+    # link ()
+
+    # -- Miscellaneous methods -----------------------------------------
+
+    # override the object_filenames method from CCompiler to
+    # support rc and res-files
+    def object_filenames (self,
+                          source_filenames,
+                          strip_dir=0,
+                          output_dir=''):
+        if output_dir is None: output_dir = ''
+        obj_names = []
+        for src_name in source_filenames:
+            # use normcase to make sure '.rc' is really '.rc' and not '.RC'
+            (base, ext) = os.path.splitext (os.path.normcase(src_name))
+            if ext not in (self.src_extensions + ['.rc']):
+                raise UnknownFileError, \
+                      "unknown file type '%s' (from '%s')" % \
+                      (ext, src_name)
+            if strip_dir:
+                base = os.path.basename (base)
+            if ext == '.rc':
+                # these need to be compiled to object files
+                obj_names.append (os.path.join (output_dir,
+                                            base + self.res_extension))
+            else:
+                obj_names.append (os.path.join (output_dir,
+                                            base + self.obj_extension))
+        return obj_names
+
+    # object_filenames ()
+
+    # override the find_library_file method from UnixCCompiler
+    # to deal with file naming/searching differences
+    def find_library_file(self, dirs, lib, debug=0):
+        shortlib = '%s.lib' % lib
+        longlib = 'lib%s.lib' % lib    # this form very rare
+
+        # get EMX's default library directory search path
+        try:
+            emx_dirs = os.environ['LIBRARY_PATH'].split(';')
+        except KeyError:
+            emx_dirs = []
+
+        for dir in dirs + emx_dirs:
+            shortlibp = os.path.join(dir, shortlib)
+            longlibp = os.path.join(dir, longlib)
+            if os.path.exists(shortlibp):
+                return shortlibp
+            elif os.path.exists(longlibp):
+                return longlibp
+
+        # Oops, didn't find it in *any* of 'dirs'
+        return None
+
+# class EMXCCompiler
+
+
+# Because these compilers aren't configured in Python's pyconfig.h file by
+# default, we should at least warn the user if he is using a unmodified
+# version.
+
+CONFIG_H_OK = "ok"
+CONFIG_H_NOTOK = "not ok"
+CONFIG_H_UNCERTAIN = "uncertain"
+
+def check_config_h():
+
+    """Check if the current Python installation (specifically, pyconfig.h)
+    appears amenable to building extensions with GCC.  Returns a tuple
+    (status, details), where 'status' is one of the following constants:
+      CONFIG_H_OK
+        all is well, go ahead and compile
+      CONFIG_H_NOTOK
+        doesn't look good
+      CONFIG_H_UNCERTAIN
+        not sure -- unable to read pyconfig.h
+    'details' is a human-readable string explaining the situation.
+
+    Note there are two ways to conclude "OK": either 'sys.version' contains
+    the string "GCC" (implying that this Python was built with GCC), or the
+    installed "pyconfig.h" contains the string "__GNUC__".
+    """
+
+    # XXX since this function also checks sys.version, it's not strictly a
+    # "pyconfig.h" check -- should probably be renamed...
+
+    from distutils import sysconfig
+    import string
+    # if sys.version contains GCC then python was compiled with
+    # GCC, and the pyconfig.h file should be OK
+    if string.find(sys.version,"GCC") >= 0:
+        return (CONFIG_H_OK, "sys.version mentions 'GCC'")
+
+    fn = sysconfig.get_config_h_filename()
+    try:
+        # It would probably better to read single lines to search.
+        # But we do this only once, and it is fast enough
+        f = open(fn)
+        s = f.read()
+        f.close()
+
+    except IOError, exc:
+        # if we can't read this file, we cannot say it is wrong
+        # the compiler will complain later about this file as missing
+        return (CONFIG_H_UNCERTAIN,
+                "couldn't read '%s': %s" % (fn, exc.strerror))
+
+    else:
+        # "pyconfig.h" contains an "#ifdef __GNUC__" or something similar
+        if string.find(s,"__GNUC__") >= 0:
+            return (CONFIG_H_OK, "'%s' mentions '__GNUC__'" % fn)
+        else:
+            return (CONFIG_H_NOTOK, "'%s' does not mention '__GNUC__'" % fn)
+
+
+def get_versions():
+    """ Try to find out the versions of gcc and ld.
+        If not possible it returns None for it.
+    """
+    from distutils.version import StrictVersion
+    from distutils.spawn import find_executable
+    import re
+
+    gcc_exe = find_executable('gcc')
+    if gcc_exe:
+        out = os.popen(gcc_exe + ' -dumpversion','r')
+        out_string = out.read()
+        out.close()
+        result = re.search('(\d+\.\d+\.\d+)',out_string)
+        if result:
+            gcc_version = StrictVersion(result.group(1))
+        else:
+            gcc_version = None
+    else:
+        gcc_version = None
+    # EMX ld has no way of reporting version number, and we use GCC
+    # anyway - so we can link OMF DLLs
+    ld_version = None
+    return (gcc_version, ld_version)

Added: vendor/Python/current/Lib/distutils/errors.py
===================================================================
--- vendor/Python/current/Lib/distutils/errors.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/errors.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,99 @@
+"""distutils.errors
+
+Provides exceptions used by the Distutils modules.  Note that Distutils
+modules may raise standard exceptions; in particular, SystemExit is
+usually raised for errors that are obviously the end-user's fault
+(eg. bad command-line arguments).
+
+This module is safe to use in "from ... import *" mode; it only exports
+symbols whose names start with "Distutils" and end with "Error"."""
+
+# This module should be kept compatible with Python 2.1.
+
+__revision__ = "$Id: errors.py 37828 2004-11-10 22:23:15Z loewis $"
+
+class DistutilsError (Exception):
+    """The root of all Distutils evil."""
+    pass
+
+class DistutilsModuleError (DistutilsError):
+    """Unable to load an expected module, or to find an expected class
+    within some module (in particular, command modules and classes)."""
+    pass
+
+class DistutilsClassError (DistutilsError):
+    """Some command class (or possibly distribution class, if anyone
+    feels a need to subclass Distribution) is found not to be holding
+    up its end of the bargain, ie. implementing some part of the
+    "command "interface."""
+    pass
+
+class DistutilsGetoptError (DistutilsError):
+    """The option table provided to 'fancy_getopt()' is bogus."""
+    pass
+
+class DistutilsArgError (DistutilsError):
+    """Raised by fancy_getopt in response to getopt.error -- ie. an
+    error in the command line usage."""
+    pass
+
+class DistutilsFileError (DistutilsError):
+    """Any problems in the filesystem: expected file not found, etc.
+    Typically this is for problems that we detect before IOError or
+    OSError could be raised."""
+    pass
+
+class DistutilsOptionError (DistutilsError):
+    """Syntactic/semantic errors in command options, such as use of
+    mutually conflicting options, or inconsistent options,
+    badly-spelled values, etc.  No distinction is made between option
+    values originating in the setup script, the command line, config
+    files, or what-have-you -- but if we *know* something originated in
+    the setup script, we'll raise DistutilsSetupError instead."""
+    pass
+
+class DistutilsSetupError (DistutilsError):
+    """For errors that can be definitely blamed on the setup script,
+    such as invalid keyword arguments to 'setup()'."""
+    pass
+
+class DistutilsPlatformError (DistutilsError):
+    """We don't know how to do something on the current platform (but
+    we do know how to do it on some platform) -- eg. trying to compile
+    C files on a platform not supported by a CCompiler subclass."""
+    pass
+
+class DistutilsExecError (DistutilsError):
+    """Any problems executing an external program (such as the C
+    compiler, when compiling C files)."""
+    pass
+
+class DistutilsInternalError (DistutilsError):
+    """Internal inconsistencies or impossibilities (obviously, this
+    should never be seen if the code is working!)."""
+    pass
+
+class DistutilsTemplateError (DistutilsError):
+    """Syntax error in a file list template."""
+
+
+# Exception classes used by the CCompiler implementation classes
+class CCompilerError (Exception):
+    """Some compile/link operation failed."""
+
+class PreprocessError (CCompilerError):
+    """Failure to preprocess one or more C/C++ files."""
+
+class CompileError (CCompilerError):
+    """Failure to compile one or more C/C++ source files."""
+
+class LibError (CCompilerError):
+    """Failure to create a static library from one or more C/C++ object
+    files."""
+
+class LinkError (CCompilerError):
+    """Failure to link one or more C/C++ object files into an executable
+    or shared library file."""
+
+class UnknownFileError (CCompilerError):
+    """Attempt to process an unknown file type."""

Added: vendor/Python/current/Lib/distutils/extension.py
===================================================================
--- vendor/Python/current/Lib/distutils/extension.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/extension.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,246 @@
+"""distutils.extension
+
+Provides the Extension class, used to describe C/C++ extension
+modules in setup scripts."""
+
+__revision__ = "$Id: extension.py 37623 2004-10-14 10:02:08Z anthonybaxter $"
+
+import os, string, sys
+from types import *
+
+try:
+    import warnings
+except ImportError:
+    warnings = None
+
+# This class is really only used by the "build_ext" command, so it might
+# make sense to put it in distutils.command.build_ext.  However, that
+# module is already big enough, and I want to make this class a bit more
+# complex to simplify some common cases ("foo" module in "foo.c") and do
+# better error-checking ("foo.c" actually exists).
+#
+# Also, putting this in build_ext.py means every setup script would have to
+# import that large-ish module (indirectly, through distutils.core) in
+# order to do anything.
+
+class Extension:
+    """Just a collection of attributes that describes an extension
+    module and everything needed to build it (hopefully in a portable
+    way, but there are hooks that let you be as unportable as you need).
+
+    Instance attributes:
+      name : string
+        the full name of the extension, including any packages -- ie.
+        *not* a filename or pathname, but Python dotted name
+      sources : [string]
+        list of source filenames, relative to the distribution root
+        (where the setup script lives), in Unix form (slash-separated)
+        for portability.  Source files may be C, C++, SWIG (.i),
+        platform-specific resource files, or whatever else is recognized
+        by the "build_ext" command as source for a Python extension.
+      include_dirs : [string]
+        list of directories to search for C/C++ header files (in Unix
+        form for portability)
+      define_macros : [(name : string, value : string|None)]
+        list of macros to define; each macro is defined using a 2-tuple,
+        where 'value' is either the string to define it to or None to
+        define it without a particular value (equivalent of "#define
+        FOO" in source or -DFOO on Unix C compiler command line)
+      undef_macros : [string]
+        list of macros to undefine explicitly
+      library_dirs : [string]
+        list of directories to search for C/C++ libraries at link time
+      libraries : [string]
+        list of library names (not filenames or paths) to link against
+      runtime_library_dirs : [string]
+        list of directories to search for C/C++ libraries at run time
+        (for shared extensions, this is when the extension is loaded)
+      extra_objects : [string]
+        list of extra files to link with (eg. object files not implied
+        by 'sources', static library that must be explicitly specified,
+        binary resource files, etc.)
+      extra_compile_args : [string]
+        any extra platform- and compiler-specific information to use
+        when compiling the source files in 'sources'.  For platforms and
+        compilers where "command line" makes sense, this is typically a
+        list of command-line arguments, but for other platforms it could
+        be anything.
+      extra_link_args : [string]
+        any extra platform- and compiler-specific information to use
+        when linking object files together to create the extension (or
+        to create a new static Python interpreter).  Similar
+        interpretation as for 'extra_compile_args'.
+      export_symbols : [string]
+        list of symbols to be exported from a shared extension.  Not
+        used on all platforms, and not generally necessary for Python
+        extensions, which typically export exactly one symbol: "init" +
+        extension_name.
+      swig_opts : [string]
+        any extra options to pass to SWIG if a source file has the .i
+        extension.
+      depends : [string]
+        list of files that the extension depends on
+      language : string
+        extension language (i.e. "c", "c++", "objc"). Will be detected
+        from the source extensions if not provided.
+    """
+
+    # When adding arguments to this constructor, be sure to update
+    # setup_keywords in core.py.
+    def __init__ (self, name, sources,
+                  include_dirs=None,
+                  define_macros=None,
+                  undef_macros=None,
+                  library_dirs=None,
+                  libraries=None,
+                  runtime_library_dirs=None,
+                  extra_objects=None,
+                  extra_compile_args=None,
+                  extra_link_args=None,
+                  export_symbols=None,
+                  swig_opts = None,
+                  depends=None,
+                  language=None,
+                  **kw                      # To catch unknown keywords
+                 ):
+        assert type(name) is StringType, "'name' must be a string"
+        assert (type(sources) is ListType and
+                map(type, sources) == [StringType]*len(sources)), \
+                "'sources' must be a list of strings"
+
+        self.name = name
+        self.sources = sources
+        self.include_dirs = include_dirs or []
+        self.define_macros = define_macros or []
+        self.undef_macros = undef_macros or []
+        self.library_dirs = library_dirs or []
+        self.libraries = libraries or []
+        self.runtime_library_dirs = runtime_library_dirs or []
+        self.extra_objects = extra_objects or []
+        self.extra_compile_args = extra_compile_args or []
+        self.extra_link_args = extra_link_args or []
+        self.export_symbols = export_symbols or []
+        self.swig_opts = swig_opts or []
+        self.depends = depends or []
+        self.language = language
+
+        # If there are unknown keyword options, warn about them
+        if len(kw):
+            L = kw.keys() ; L.sort()
+            L = map(repr, L)
+            msg = "Unknown Extension options: " + string.join(L, ', ')
+            if warnings is not None:
+                warnings.warn(msg)
+            else:
+                sys.stderr.write(msg + '\n')
+# class Extension
+
+
+def read_setup_file (filename):
+    from distutils.sysconfig import \
+         parse_makefile, expand_makefile_vars, _variable_rx
+    from distutils.text_file import TextFile
+    from distutils.util import split_quoted
+
+    # First pass over the file to gather "VAR = VALUE" assignments.
+    vars = parse_makefile(filename)
+
+    # Second pass to gobble up the real content: lines of the form
+    #   <module> ... [<sourcefile> ...] [<cpparg> ...] [<library> ...]
+    file = TextFile(filename,
+                    strip_comments=1, skip_blanks=1, join_lines=1,
+                    lstrip_ws=1, rstrip_ws=1)
+    extensions = []
+
+    while 1:
+        line = file.readline()
+        if line is None:                # eof
+            break
+        if _variable_rx.match(line):    # VAR=VALUE, handled in first pass
+            continue
+
+        if line[0] == line[-1] == "*":
+            file.warn("'%s' lines not handled yet" % line)
+            continue
+
+        #print "original line: " + line
+        line = expand_makefile_vars(line, vars)
+        words = split_quoted(line)
+        #print "expanded line: " + line
+
+        # NB. this parses a slightly different syntax than the old
+        # makesetup script: here, there must be exactly one extension per
+        # line, and it must be the first word of the line.  I have no idea
+        # why the old syntax supported multiple extensions per line, as
+        # they all wind up being the same.
+
+        module = words[0]
+        ext = Extension(module, [])
+        append_next_word = None
+
+        for word in words[1:]:
+            if append_next_word is not None:
+                append_next_word.append(word)
+                append_next_word = None
+                continue
+
+            suffix = os.path.splitext(word)[1]
+            switch = word[0:2] ; value = word[2:]
+
+            if suffix in (".c", ".cc", ".cpp", ".cxx", ".c++", ".m", ".mm"):
+                # hmm, should we do something about C vs. C++ sources?
+                # or leave it up to the CCompiler implementation to
+                # worry about?
+                ext.sources.append(word)
+            elif switch == "-I":
+                ext.include_dirs.append(value)
+            elif switch == "-D":
+                equals = string.find(value, "=")
+                if equals == -1:        # bare "-DFOO" -- no value
+                    ext.define_macros.append((value, None))
+                else:                   # "-DFOO=blah"
+                    ext.define_macros.append((value[0:equals],
+                                              value[equals+2:]))
+            elif switch == "-U":
+                ext.undef_macros.append(value)
+            elif switch == "-C":        # only here 'cause makesetup has it!
+                ext.extra_compile_args.append(word)
+            elif switch == "-l":
+                ext.libraries.append(value)
+            elif switch == "-L":
+                ext.library_dirs.append(value)
+            elif switch == "-R":
+                ext.runtime_library_dirs.append(value)
+            elif word == "-rpath":
+                append_next_word = ext.runtime_library_dirs
+            elif word == "-Xlinker":
+                append_next_word = ext.extra_link_args
+            elif word == "-Xcompiler":
+                append_next_word = ext.extra_compile_args
+            elif switch == "-u":
+                ext.extra_link_args.append(word)
+                if not value:
+                    append_next_word = ext.extra_link_args
+            elif suffix in (".a", ".so", ".sl", ".o", ".dylib"):
+                # NB. a really faithful emulation of makesetup would
+                # append a .o file to extra_objects only if it
+                # had a slash in it; otherwise, it would s/.o/.c/
+                # and append it to sources.  Hmmmm.
+                ext.extra_objects.append(word)
+            else:
+                file.warn("unrecognized argument '%s'" % word)
+
+        extensions.append(ext)
+
+        #print "module:", module
+        #print "source files:", source_files
+        #print "cpp args:", cpp_args
+        #print "lib args:", library_args
+
+        #extensions[module] = { 'sources': source_files,
+        #                       'cpp_args': cpp_args,
+        #                       'lib_args': library_args }
+
+    return extensions
+
+# read_setup_file ()

Added: vendor/Python/current/Lib/distutils/fancy_getopt.py
===================================================================
--- vendor/Python/current/Lib/distutils/fancy_getopt.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/fancy_getopt.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,502 @@
+"""distutils.fancy_getopt
+
+Wrapper around the standard getopt module that provides the following
+additional features:
+  * short and long options are tied together
+  * options have help strings, so fancy_getopt could potentially
+    create a complete usage summary
+  * options set attributes of a passed-in object
+"""
+
+# This module should be kept compatible with Python 2.1.
+
+__revision__ = "$Id: fancy_getopt.py 37828 2004-11-10 22:23:15Z loewis $"
+
+import sys, string, re
+from types import *
+import getopt
+from distutils.errors import *
+
+# Much like command_re in distutils.core, this is close to but not quite
+# the same as a Python NAME -- except, in the spirit of most GNU
+# utilities, we use '-' in place of '_'.  (The spirit of LISP lives on!)
+# The similarities to NAME are again not a coincidence...
+longopt_pat = r'[a-zA-Z](?:[a-zA-Z0-9-]*)'
+longopt_re = re.compile(r'^%s$' % longopt_pat)
+
+# For recognizing "negative alias" options, eg. "quiet=!verbose"
+neg_alias_re = re.compile("^(%s)=!(%s)$" % (longopt_pat, longopt_pat))
+
+# This is used to translate long options to legitimate Python identifiers
+# (for use as attributes of some object).
+longopt_xlate = string.maketrans('-', '_')
+
+class FancyGetopt:
+    """Wrapper around the standard 'getopt()' module that provides some
+    handy extra functionality:
+      * short and long options are tied together
+      * options have help strings, and help text can be assembled
+        from them
+      * options set attributes of a passed-in object
+      * boolean options can have "negative aliases" -- eg. if
+        --quiet is the "negative alias" of --verbose, then "--quiet"
+        on the command line sets 'verbose' to false
+    """
+
+    def __init__ (self, option_table=None):
+
+        # The option table is (currently) a list of tuples.  The
+        # tuples may have 3 or four values:
+        #   (long_option, short_option, help_string [, repeatable])
+        # if an option takes an argument, its long_option should have '='
+        # appended; short_option should just be a single character, no ':'
+        # in any case.  If a long_option doesn't have a corresponding
+        # short_option, short_option should be None.  All option tuples
+        # must have long options.
+        self.option_table = option_table
+
+        # 'option_index' maps long option names to entries in the option
+        # table (ie. those 3-tuples).
+        self.option_index = {}
+        if self.option_table:
+            self._build_index()
+
+        # 'alias' records (duh) alias options; {'foo': 'bar'} means
+        # --foo is an alias for --bar
+        self.alias = {}
+
+        # 'negative_alias' keeps track of options that are the boolean
+        # opposite of some other option
+        self.negative_alias = {}
+
+        # These keep track of the information in the option table.  We
+        # don't actually populate these structures until we're ready to
+        # parse the command-line, since the 'option_table' passed in here
+        # isn't necessarily the final word.
+        self.short_opts = []
+        self.long_opts = []
+        self.short2long = {}
+        self.attr_name = {}
+        self.takes_arg = {}
+
+        # And 'option_order' is filled up in 'getopt()'; it records the
+        # original order of options (and their values) on the command-line,
+        # but expands short options, converts aliases, etc.
+        self.option_order = []
+
+    # __init__ ()
+
+
+    def _build_index (self):
+        self.option_index.clear()
+        for option in self.option_table:
+            self.option_index[option[0]] = option
+
+    def set_option_table (self, option_table):
+        self.option_table = option_table
+        self._build_index()
+
+    def add_option (self, long_option, short_option=None, help_string=None):
+        if self.option_index.has_key(long_option):
+            raise DistutilsGetoptError, \
+                  "option conflict: already an option '%s'" % long_option
+        else:
+            option = (long_option, short_option, help_string)
+            self.option_table.append(option)
+            self.option_index[long_option] = option
+
+
+    def has_option (self, long_option):
+        """Return true if the option table for this parser has an
+        option with long name 'long_option'."""
+        return self.option_index.has_key(long_option)
+
+    def get_attr_name (self, long_option):
+        """Translate long option name 'long_option' to the form it
+        has as an attribute of some object: ie., translate hyphens
+        to underscores."""
+        return string.translate(long_option, longopt_xlate)
+
+
+    def _check_alias_dict (self, aliases, what):
+        assert type(aliases) is DictionaryType
+        for (alias, opt) in aliases.items():
+            if not self.option_index.has_key(alias):
+                raise DistutilsGetoptError, \
+                      ("invalid %s '%s': "
+                       "option '%s' not defined") % (what, alias, alias)
+            if not self.option_index.has_key(opt):
+                raise DistutilsGetoptError, \
+                      ("invalid %s '%s': "
+                       "aliased option '%s' not defined") % (what, alias, opt)
+
+    def set_aliases (self, alias):
+        """Set the aliases for this option parser."""
+        self._check_alias_dict(alias, "alias")
+        self.alias = alias
+
+    def set_negative_aliases (self, negative_alias):
+        """Set the negative aliases for this option parser.
+        'negative_alias' should be a dictionary mapping option names to
+        option names, both the key and value must already be defined
+        in the option table."""
+        self._check_alias_dict(negative_alias, "negative alias")
+        self.negative_alias = negative_alias
+
+
+    def _grok_option_table (self):
+        """Populate the various data structures that keep tabs on the
+        option table.  Called by 'getopt()' before it can do anything
+        worthwhile.
+        """
+        self.long_opts = []
+        self.short_opts = []
+        self.short2long.clear()
+        self.repeat = {}
+
+        for option in self.option_table:
+            if len(option) == 3:
+                long, short, help = option
+                repeat = 0
+            elif len(option) == 4:
+                long, short, help, repeat = option
+            else:
+                # the option table is part of the code, so simply
+                # assert that it is correct
+                raise ValueError, "invalid option tuple: %r" % (option,)
+
+            # Type- and value-check the option names
+            if type(long) is not StringType or len(long) < 2:
+                raise DistutilsGetoptError, \
+                      ("invalid long option '%s': "
+                       "must be a string of length >= 2") % long
+
+            if (not ((short is None) or
+                     (type(short) is StringType and len(short) == 1))):
+                raise DistutilsGetoptError, \
+                      ("invalid short option '%s': "
+                       "must a single character or None") % short
+
+            self.repeat[long] = repeat
+            self.long_opts.append(long)
+
+            if long[-1] == '=':             # option takes an argument?
+                if short: short = short + ':'
+                long = long[0:-1]
+                self.takes_arg[long] = 1
+            else:
+
+                # Is option is a "negative alias" for some other option (eg.
+                # "quiet" == "!verbose")?
+                alias_to = self.negative_alias.get(long)
+                if alias_to is not None:
+                    if self.takes_arg[alias_to]:
+                        raise DistutilsGetoptError, \
+                              ("invalid negative alias '%s': "
+                               "aliased option '%s' takes a value") % \
+                               (long, alias_to)
+
+                    self.long_opts[-1] = long # XXX redundant?!
+                    self.takes_arg[long] = 0
+
+                else:
+                    self.takes_arg[long] = 0
+
+            # If this is an alias option, make sure its "takes arg" flag is
+            # the same as the option it's aliased to.
+            alias_to = self.alias.get(long)
+            if alias_to is not None:
+                if self.takes_arg[long] != self.takes_arg[alias_to]:
+                    raise DistutilsGetoptError, \
+                          ("invalid alias '%s': inconsistent with "
+                           "aliased option '%s' (one of them takes a value, "
+                           "the other doesn't") % (long, alias_to)
+
+
+            # Now enforce some bondage on the long option name, so we can
+            # later translate it to an attribute name on some object.  Have
+            # to do this a bit late to make sure we've removed any trailing
+            # '='.
+            if not longopt_re.match(long):
+                raise DistutilsGetoptError, \
+                      ("invalid long option name '%s' " +
+                       "(must be letters, numbers, hyphens only") % long
+
+            self.attr_name[long] = self.get_attr_name(long)
+            if short:
+                self.short_opts.append(short)
+                self.short2long[short[0]] = long
+
+        # for option_table
+
+    # _grok_option_table()
+
+
+    def getopt (self, args=None, object=None):
+        """Parse command-line options in args. Store as attributes on object.
+
+        If 'args' is None or not supplied, uses 'sys.argv[1:]'.  If
+        'object' is None or not supplied, creates a new OptionDummy
+        object, stores option values there, and returns a tuple (args,
+        object).  If 'object' is supplied, it is modified in place and
+        'getopt()' just returns 'args'; in both cases, the returned
+        'args' is a modified copy of the passed-in 'args' list, which
+        is left untouched.
+        """
+        if args is None:
+            args = sys.argv[1:]
+        if object is None:
+            object = OptionDummy()
+            created_object = 1
+        else:
+            created_object = 0
+
+        self._grok_option_table()
+
+        short_opts = string.join(self.short_opts)
+        try:
+            opts, args = getopt.getopt(args, short_opts, self.long_opts)
+        except getopt.error, msg:
+            raise DistutilsArgError, msg
+
+        for opt, val in opts:
+            if len(opt) == 2 and opt[0] == '-': # it's a short option
+                opt = self.short2long[opt[1]]
+            else:
+                assert len(opt) > 2 and opt[:2] == '--'
+                opt = opt[2:]
+
+            alias = self.alias.get(opt)
+            if alias:
+                opt = alias
+
+            if not self.takes_arg[opt]:     # boolean option?
+                assert val == '', "boolean option can't have value"
+                alias = self.negative_alias.get(opt)
+                if alias:
+                    opt = alias
+                    val = 0
+                else:
+                    val = 1
+
+            attr = self.attr_name[opt]
+            # The only repeating option at the moment is 'verbose'.
+            # It has a negative option -q quiet, which should set verbose = 0.
+            if val and self.repeat.get(attr) is not None:
+                val = getattr(object, attr, 0) + 1
+            setattr(object, attr, val)
+            self.option_order.append((opt, val))
+
+        # for opts
+        if created_object:
+            return args, object
+        else:
+            return args
+
+    # getopt()
+
+
+    def get_option_order (self):
+        """Returns the list of (option, value) tuples processed by the
+        previous run of 'getopt()'.  Raises RuntimeError if
+        'getopt()' hasn't been called yet.
+        """
+        if self.option_order is None:
+            raise RuntimeError, "'getopt()' hasn't been called yet"
+        else:
+            return self.option_order
+
+
+    def generate_help (self, header=None):
+        """Generate help text (a list of strings, one per suggested line of
+        output) from the option table for this FancyGetopt object.
+        """
+        # Blithely assume the option table is good: probably wouldn't call
+        # 'generate_help()' unless you've already called 'getopt()'.
+
+        # First pass: determine maximum length of long option names
+        max_opt = 0
+        for option in self.option_table:
+            long = option[0]
+            short = option[1]
+            l = len(long)
+            if long[-1] == '=':
+                l = l - 1
+            if short is not None:
+                l = l + 5                   # " (-x)" where short == 'x'
+            if l > max_opt:
+                max_opt = l
+
+        opt_width = max_opt + 2 + 2 + 2     # room for indent + dashes + gutter
+
+        # Typical help block looks like this:
+        #   --foo       controls foonabulation
+        # Help block for longest option looks like this:
+        #   --flimflam  set the flim-flam level
+        # and with wrapped text:
+        #   --flimflam  set the flim-flam level (must be between
+        #               0 and 100, except on Tuesdays)
+        # Options with short names will have the short name shown (but
+        # it doesn't contribute to max_opt):
+        #   --foo (-f)  controls foonabulation
+        # If adding the short option would make the left column too wide,
+        # we push the explanation off to the next line
+        #   --flimflam (-l)
+        #               set the flim-flam level
+        # Important parameters:
+        #   - 2 spaces before option block start lines
+        #   - 2 dashes for each long option name
+        #   - min. 2 spaces between option and explanation (gutter)
+        #   - 5 characters (incl. space) for short option name
+
+        # Now generate lines of help text.  (If 80 columns were good enough
+        # for Jesus, then 78 columns are good enough for me!)
+        line_width = 78
+        text_width = line_width - opt_width
+        big_indent = ' ' * opt_width
+        if header:
+            lines = [header]
+        else:
+            lines = ['Option summary:']
+
+        for option in self.option_table:
+            long, short, help = option[:3]
+            text = wrap_text(help, text_width)
+            if long[-1] == '=':
+                long = long[0:-1]
+
+            # Case 1: no short option at all (makes life easy)
+            if short is None:
+                if text:
+                    lines.append("  --%-*s  %s" % (max_opt, long, text[0]))
+                else:
+                    lines.append("  --%-*s  " % (max_opt, long))
+
+            # Case 2: we have a short option, so we have to include it
+            # just after the long option
+            else:
+                opt_names = "%s (-%s)" % (long, short)
+                if text:
+                    lines.append("  --%-*s  %s" %
+                                 (max_opt, opt_names, text[0]))
+                else:
+                    lines.append("  --%-*s" % opt_names)
+
+            for l in text[1:]:
+                lines.append(big_indent + l)
+
+        # for self.option_table
+
+        return lines
+
+    # generate_help ()
+
+    def print_help (self, header=None, file=None):
+        if file is None:
+            file = sys.stdout
+        for line in self.generate_help(header):
+            file.write(line + "\n")
+
+# class FancyGetopt
+
+
+def fancy_getopt (options, negative_opt, object, args):
+    parser = FancyGetopt(options)
+    parser.set_negative_aliases(negative_opt)
+    return parser.getopt(args, object)
+
+
+WS_TRANS = string.maketrans(string.whitespace, ' ' * len(string.whitespace))
+
+def wrap_text (text, width):
+    """wrap_text(text : string, width : int) -> [string]
+
+    Split 'text' into multiple lines of no more than 'width' characters
+    each, and return the list of strings that results.
+    """
+
+    if text is None:
+        return []
+    if len(text) <= width:
+        return [text]
+
+    text = string.expandtabs(text)
+    text = string.translate(text, WS_TRANS)
+    chunks = re.split(r'( +|-+)', text)
+    chunks = filter(None, chunks)      # ' - ' results in empty strings
+    lines = []
+
+    while chunks:
+
+        cur_line = []                   # list of chunks (to-be-joined)
+        cur_len = 0                     # length of current line
+
+        while chunks:
+            l = len(chunks[0])
+            if cur_len + l <= width:    # can squeeze (at least) this chunk in
+                cur_line.append(chunks[0])
+                del chunks[0]
+                cur_len = cur_len + l
+            else:                       # this line is full
+                # drop last chunk if all space
+                if cur_line and cur_line[-1][0] == ' ':
+                    del cur_line[-1]
+                break
+
+        if chunks:                      # any chunks left to process?
+
+            # if the current line is still empty, then we had a single
+            # chunk that's too big too fit on a line -- so we break
+            # down and break it up at the line width
+            if cur_len == 0:
+                cur_line.append(chunks[0][0:width])
+                chunks[0] = chunks[0][width:]
+
+            # all-whitespace chunks at the end of a line can be discarded
+            # (and we know from the re.split above that if a chunk has
+            # *any* whitespace, it is *all* whitespace)
+            if chunks[0][0] == ' ':
+                del chunks[0]
+
+        # and store this line in the list-of-all-lines -- as a single
+        # string, of course!
+        lines.append(string.join(cur_line, ''))
+
+    # while chunks
+
+    return lines
+
+# wrap_text ()
+
+
+def translate_longopt (opt):
+    """Convert a long option name to a valid Python identifier by
+    changing "-" to "_".
+    """
+    return string.translate(opt, longopt_xlate)
+
+
+class OptionDummy:
+    """Dummy class just used as a place to hold command-line option
+    values as instance attributes."""
+
+    def __init__ (self, options=[]):
+        """Create a new OptionDummy instance.  The attributes listed in
+        'options' will be initialized to None."""
+        for opt in options:
+            setattr(self, opt, None)
+
+# class OptionDummy
+
+
+if __name__ == "__main__":
+    text = """\
+Tra-la-la, supercalifragilisticexpialidocious.
+How *do* you spell that odd word, anyways?
+(Someone ask Mary -- she'll know [or she'll
+say, "How should I know?"].)"""
+
+    for w in (10, 20, 30, 40):
+        print "width: %d" % w
+        print string.join(wrap_text(text, w), "\n")
+        print

Added: vendor/Python/current/Lib/distutils/file_util.py
===================================================================
--- vendor/Python/current/Lib/distutils/file_util.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/file_util.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,253 @@
+"""distutils.file_util
+
+Utility functions for operating on single files.
+"""
+
+# This module should be kept compatible with Python 2.1.
+
+__revision__ = "$Id: file_util.py 37828 2004-11-10 22:23:15Z loewis $"
+
+import os
+from distutils.errors import DistutilsFileError
+from distutils import log
+
+# for generating verbose output in 'copy_file()'
+_copy_action = { None:   'copying',
+                 'hard': 'hard linking',
+                 'sym':  'symbolically linking' }
+
+
+def _copy_file_contents (src, dst, buffer_size=16*1024):
+    """Copy the file 'src' to 'dst'; both must be filenames.  Any error
+    opening either file, reading from 'src', or writing to 'dst', raises
+    DistutilsFileError.  Data is read/written in chunks of 'buffer_size'
+    bytes (default 16k).  No attempt is made to handle anything apart from
+    regular files.
+    """
+    # Stolen from shutil module in the standard library, but with
+    # custom error-handling added.
+
+    fsrc = None
+    fdst = None
+    try:
+        try:
+            fsrc = open(src, 'rb')
+        except os.error, (errno, errstr):
+            raise DistutilsFileError, \
+                  "could not open '%s': %s" % (src, errstr)
+
+        if os.path.exists(dst):
+            try:
+                os.unlink(dst)
+            except os.error, (errno, errstr):
+                raise DistutilsFileError, \
+                      "could not delete '%s': %s" % (dst, errstr)
+
+        try:
+            fdst = open(dst, 'wb')
+        except os.error, (errno, errstr):
+            raise DistutilsFileError, \
+                  "could not create '%s': %s" % (dst, errstr)
+
+        while 1:
+            try:
+                buf = fsrc.read(buffer_size)
+            except os.error, (errno, errstr):
+                raise DistutilsFileError, \
+                      "could not read from '%s': %s" % (src, errstr)
+
+            if not buf:
+                break
+
+            try:
+                fdst.write(buf)
+            except os.error, (errno, errstr):
+                raise DistutilsFileError, \
+                      "could not write to '%s': %s" % (dst, errstr)
+
+    finally:
+        if fdst:
+            fdst.close()
+        if fsrc:
+            fsrc.close()
+
+# _copy_file_contents()
+
+def copy_file (src, dst,
+               preserve_mode=1,
+               preserve_times=1,
+               update=0,
+               link=None,
+               verbose=0,
+               dry_run=0):
+
+    """Copy a file 'src' to 'dst'.  If 'dst' is a directory, then 'src' is
+    copied there with the same name; otherwise, it must be a filename.  (If
+    the file exists, it will be ruthlessly clobbered.)  If 'preserve_mode'
+    is true (the default), the file's mode (type and permission bits, or
+    whatever is analogous on the current platform) is copied.  If
+    'preserve_times' is true (the default), the last-modified and
+    last-access times are copied as well.  If 'update' is true, 'src' will
+    only be copied if 'dst' does not exist, or if 'dst' does exist but is
+    older than 'src'.
+
+    'link' allows you to make hard links (os.link) or symbolic links
+    (os.symlink) instead of copying: set it to "hard" or "sym"; if it is
+    None (the default), files are copied.  Don't set 'link' on systems that
+    don't support it: 'copy_file()' doesn't check if hard or symbolic
+    linking is available.
+
+    Under Mac OS, uses the native file copy function in macostools; on
+    other systems, uses '_copy_file_contents()' to copy file contents.
+
+    Return a tuple (dest_name, copied): 'dest_name' is the actual name of
+    the output file, and 'copied' is true if the file was copied (or would
+    have been copied, if 'dry_run' true).
+    """
+    # XXX if the destination file already exists, we clobber it if
+    # copying, but blow up if linking.  Hmmm.  And I don't know what
+    # macostools.copyfile() does.  Should definitely be consistent, and
+    # should probably blow up if destination exists and we would be
+    # changing it (ie. it's not already a hard/soft link to src OR
+    # (not update) and (src newer than dst).
+
+    from distutils.dep_util import newer
+    from stat import ST_ATIME, ST_MTIME, ST_MODE, S_IMODE
+
+    if not os.path.isfile(src):
+        raise DistutilsFileError, \
+              "can't copy '%s': doesn't exist or not a regular file" % src
+
+    if os.path.isdir(dst):
+        dir = dst
+        dst = os.path.join(dst, os.path.basename(src))
+    else:
+        dir = os.path.dirname(dst)
+
+    if update and not newer(src, dst):
+        log.debug("not copying %s (output up-to-date)", src)
+        return dst, 0
+
+    try:
+        action = _copy_action[link]
+    except KeyError:
+        raise ValueError, \
+              "invalid value '%s' for 'link' argument" % link
+    if os.path.basename(dst) == os.path.basename(src):
+        log.info("%s %s -> %s", action, src, dir)
+    else:
+        log.info("%s %s -> %s", action, src, dst)
+
+    if dry_run:
+        return (dst, 1)
+
+    # On Mac OS, use the native file copy routine
+    if os.name == 'mac':
+        import macostools
+        try:
+            macostools.copy(src, dst, 0, preserve_times)
+        except os.error, exc:
+            raise DistutilsFileError, \
+                  "could not copy '%s' to '%s': %s" % (src, dst, exc[-1])
+
+    # If linking (hard or symbolic), use the appropriate system call
+    # (Unix only, of course, but that's the caller's responsibility)
+    elif link == 'hard':
+        if not (os.path.exists(dst) and os.path.samefile(src, dst)):
+            os.link(src, dst)
+    elif link == 'sym':
+        if not (os.path.exists(dst) and os.path.samefile(src, dst)):
+            os.symlink(src, dst)
+
+    # Otherwise (non-Mac, not linking), copy the file contents and
+    # (optionally) copy the times and mode.
+    else:
+        _copy_file_contents(src, dst)
+        if preserve_mode or preserve_times:
+            st = os.stat(src)
+
+            # According to David Ascher <da at ski.org>, utime() should be done
+            # before chmod() (at least under NT).
+            if preserve_times:
+                os.utime(dst, (st[ST_ATIME], st[ST_MTIME]))
+            if preserve_mode:
+                os.chmod(dst, S_IMODE(st[ST_MODE]))
+
+    return (dst, 1)
+
+# copy_file ()
+
+
+# XXX I suspect this is Unix-specific -- need porting help!
+def move_file (src, dst,
+               verbose=0,
+               dry_run=0):
+
+    """Move a file 'src' to 'dst'.  If 'dst' is a directory, the file will
+    be moved into it with the same name; otherwise, 'src' is just renamed
+    to 'dst'.  Return the new full name of the file.
+
+    Handles cross-device moves on Unix using 'copy_file()'.  What about
+    other systems???
+    """
+    from os.path import exists, isfile, isdir, basename, dirname
+    import errno
+
+    log.info("moving %s -> %s", src, dst)
+
+    if dry_run:
+        return dst
+
+    if not isfile(src):
+        raise DistutilsFileError, \
+              "can't move '%s': not a regular file" % src
+
+    if isdir(dst):
+        dst = os.path.join(dst, basename(src))
+    elif exists(dst):
+        raise DistutilsFileError, \
+              "can't move '%s': destination '%s' already exists" % \
+              (src, dst)
+
+    if not isdir(dirname(dst)):
+        raise DistutilsFileError, \
+              "can't move '%s': destination '%s' not a valid path" % \
+              (src, dst)
+
+    copy_it = 0
+    try:
+        os.rename(src, dst)
+    except os.error, (num, msg):
+        if num == errno.EXDEV:
+            copy_it = 1
+        else:
+            raise DistutilsFileError, \
+                  "couldn't move '%s' to '%s': %s" % (src, dst, msg)
+
+    if copy_it:
+        copy_file(src, dst)
+        try:
+            os.unlink(src)
+        except os.error, (num, msg):
+            try:
+                os.unlink(dst)
+            except os.error:
+                pass
+            raise DistutilsFileError, \
+                  ("couldn't move '%s' to '%s' by copy/delete: " +
+                   "delete '%s' failed: %s") % \
+                  (src, dst, src, msg)
+
+    return dst
+
+# move_file ()
+
+
+def write_file (filename, contents):
+    """Create a file with the specified name and write 'contents' (a
+    sequence of strings without line terminators) to it.
+    """
+    f = open(filename, "w")
+    for line in contents:
+        f.write(line + "\n")
+    f.close()

Added: vendor/Python/current/Lib/distutils/filelist.py
===================================================================
--- vendor/Python/current/Lib/distutils/filelist.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/filelist.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,355 @@
+"""distutils.filelist
+
+Provides the FileList class, used for poking about the filesystem
+and building lists of files.
+"""
+
+# This module should be kept compatible with Python 2.1.
+
+__revision__ = "$Id: filelist.py 37828 2004-11-10 22:23:15Z loewis $"
+
+import os, string, re
+import fnmatch
+from types import *
+from glob import glob
+from distutils.util import convert_path
+from distutils.errors import DistutilsTemplateError, DistutilsInternalError
+from distutils import log
+
+class FileList:
+
+    """A list of files built by on exploring the filesystem and filtered by
+    applying various patterns to what we find there.
+
+    Instance attributes:
+      dir
+        directory from which files will be taken -- only used if
+        'allfiles' not supplied to constructor
+      files
+        list of filenames currently being built/filtered/manipulated
+      allfiles
+        complete list of files under consideration (ie. without any
+        filtering applied)
+    """
+
+    def __init__(self,
+                 warn=None,
+                 debug_print=None):
+        # ignore argument to FileList, but keep them for backwards
+        # compatibility
+
+        self.allfiles = None
+        self.files = []
+
+    def set_allfiles (self, allfiles):
+        self.allfiles = allfiles
+
+    def findall (self, dir=os.curdir):
+        self.allfiles = findall(dir)
+
+    def debug_print (self, msg):
+        """Print 'msg' to stdout if the global DEBUG (taken from the
+        DISTUTILS_DEBUG environment variable) flag is true.
+        """
+        from distutils.debug import DEBUG
+        if DEBUG:
+            print msg
+
+    # -- List-like methods ---------------------------------------------
+
+    def append (self, item):
+        self.files.append(item)
+
+    def extend (self, items):
+        self.files.extend(items)
+
+    def sort (self):
+        # Not a strict lexical sort!
+        sortable_files = map(os.path.split, self.files)
+        sortable_files.sort()
+        self.files = []
+        for sort_tuple in sortable_files:
+            self.files.append(apply(os.path.join, sort_tuple))
+
+
+    # -- Other miscellaneous utility methods ---------------------------
+
+    def remove_duplicates (self):
+        # Assumes list has been sorted!
+        for i in range(len(self.files) - 1, 0, -1):
+            if self.files[i] == self.files[i - 1]:
+                del self.files[i]
+
+
+    # -- "File template" methods ---------------------------------------
+
+    def _parse_template_line (self, line):
+        words = string.split(line)
+        action = words[0]
+
+        patterns = dir = dir_pattern = None
+
+        if action in ('include', 'exclude',
+                      'global-include', 'global-exclude'):
+            if len(words) < 2:
+                raise DistutilsTemplateError, \
+                      "'%s' expects <pattern1> <pattern2> ..." % action
+
+            patterns = map(convert_path, words[1:])
+
+        elif action in ('recursive-include', 'recursive-exclude'):
+            if len(words) < 3:
+                raise DistutilsTemplateError, \
+                      "'%s' expects <dir> <pattern1> <pattern2> ..." % action
+
+            dir = convert_path(words[1])
+            patterns = map(convert_path, words[2:])
+
+        elif action in ('graft', 'prune'):
+            if len(words) != 2:
+                raise DistutilsTemplateError, \
+                     "'%s' expects a single <dir_pattern>" % action
+
+            dir_pattern = convert_path(words[1])
+
+        else:
+            raise DistutilsTemplateError, "unknown action '%s'" % action
+
+        return (action, patterns, dir, dir_pattern)
+
+    # _parse_template_line ()
+
+
+    def process_template_line (self, line):
+
+        # Parse the line: split it up, make sure the right number of words
+        # is there, and return the relevant words.  'action' is always
+        # defined: it's the first word of the line.  Which of the other
+        # three are defined depends on the action; it'll be either
+        # patterns, (dir and patterns), or (dir_pattern).
+        (action, patterns, dir, dir_pattern) = self._parse_template_line(line)
+
+        # OK, now we know that the action is valid and we have the
+        # right number of words on the line for that action -- so we
+        # can proceed with minimal error-checking.
+        if action == 'include':
+            self.debug_print("include " + string.join(patterns))
+            for pattern in patterns:
+                if not self.include_pattern(pattern, anchor=1):
+                    log.warn("warning: no files found matching '%s'",
+                             pattern)
+
+        elif action == 'exclude':
+            self.debug_print("exclude " + string.join(patterns))
+            for pattern in patterns:
+                if not self.exclude_pattern(pattern, anchor=1):
+                    log.warn(("warning: no previously-included files "
+                              "found matching '%s'"), pattern)
+
+        elif action == 'global-include':
+            self.debug_print("global-include " + string.join(patterns))
+            for pattern in patterns:
+                if not self.include_pattern(pattern, anchor=0):
+                    log.warn(("warning: no files found matching '%s' " +
+                              "anywhere in distribution"), pattern)
+
+        elif action == 'global-exclude':
+            self.debug_print("global-exclude " + string.join(patterns))
+            for pattern in patterns:
+                if not self.exclude_pattern(pattern, anchor=0):
+                    log.warn(("warning: no previously-included files matching "
+                              "'%s' found anywhere in distribution"),
+                             pattern)
+
+        elif action == 'recursive-include':
+            self.debug_print("recursive-include %s %s" %
+                             (dir, string.join(patterns)))
+            for pattern in patterns:
+                if not self.include_pattern(pattern, prefix=dir):
+                    log.warn(("warning: no files found matching '%s' " +
+                                "under directory '%s'"),
+                             pattern, dir)
+
+        elif action == 'recursive-exclude':
+            self.debug_print("recursive-exclude %s %s" %
+                             (dir, string.join(patterns)))
+            for pattern in patterns:
+                if not self.exclude_pattern(pattern, prefix=dir):
+                    log.warn(("warning: no previously-included files matching "
+                              "'%s' found under directory '%s'"),
+                             pattern, dir)
+
+        elif action == 'graft':
+            self.debug_print("graft " + dir_pattern)
+            if not self.include_pattern(None, prefix=dir_pattern):
+                log.warn("warning: no directories found matching '%s'",
+                         dir_pattern)
+
+        elif action == 'prune':
+            self.debug_print("prune " + dir_pattern)
+            if not self.exclude_pattern(None, prefix=dir_pattern):
+                log.warn(("no previously-included directories found " +
+                          "matching '%s'"), dir_pattern)
+        else:
+            raise DistutilsInternalError, \
+                  "this cannot happen: invalid action '%s'" % action
+
+    # process_template_line ()
+
+
+    # -- Filtering/selection methods -----------------------------------
+
+    def include_pattern (self, pattern,
+                         anchor=1, prefix=None, is_regex=0):
+        """Select strings (presumably filenames) from 'self.files' that
+        match 'pattern', a Unix-style wildcard (glob) pattern.  Patterns
+        are not quite the same as implemented by the 'fnmatch' module: '*'
+        and '?'  match non-special characters, where "special" is platform-
+        dependent: slash on Unix; colon, slash, and backslash on
+        DOS/Windows; and colon on Mac OS.
+
+        If 'anchor' is true (the default), then the pattern match is more
+        stringent: "*.py" will match "foo.py" but not "foo/bar.py".  If
+        'anchor' is false, both of these will match.
+
+        If 'prefix' is supplied, then only filenames starting with 'prefix'
+        (itself a pattern) and ending with 'pattern', with anything in between
+        them, will match.  'anchor' is ignored in this case.
+
+        If 'is_regex' is true, 'anchor' and 'prefix' are ignored, and
+        'pattern' is assumed to be either a string containing a regex or a
+        regex object -- no translation is done, the regex is just compiled
+        and used as-is.
+
+        Selected strings will be added to self.files.
+
+        Return 1 if files are found.
+        """
+        files_found = 0
+        pattern_re = translate_pattern(pattern, anchor, prefix, is_regex)
+        self.debug_print("include_pattern: applying regex r'%s'" %
+                         pattern_re.pattern)
+
+        # delayed loading of allfiles list
+        if self.allfiles is None:
+            self.findall()
+
+        for name in self.allfiles:
+            if pattern_re.search(name):
+                self.debug_print(" adding " + name)
+                self.files.append(name)
+                files_found = 1
+
+        return files_found
+
+    # include_pattern ()
+
+
+    def exclude_pattern (self, pattern,
+                         anchor=1, prefix=None, is_regex=0):
+        """Remove strings (presumably filenames) from 'files' that match
+        'pattern'.  Other parameters are the same as for
+        'include_pattern()', above.
+        The list 'self.files' is modified in place.
+        Return 1 if files are found.
+        """
+        files_found = 0
+        pattern_re = translate_pattern(pattern, anchor, prefix, is_regex)
+        self.debug_print("exclude_pattern: applying regex r'%s'" %
+                         pattern_re.pattern)
+        for i in range(len(self.files)-1, -1, -1):
+            if pattern_re.search(self.files[i]):
+                self.debug_print(" removing " + self.files[i])
+                del self.files[i]
+                files_found = 1
+
+        return files_found
+
+    # exclude_pattern ()
+
+# class FileList
+
+
+# ----------------------------------------------------------------------
+# Utility functions
+
+def findall (dir = os.curdir):
+    """Find all files under 'dir' and return the list of full filenames
+    (relative to 'dir').
+    """
+    from stat import ST_MODE, S_ISREG, S_ISDIR, S_ISLNK
+
+    list = []
+    stack = [dir]
+    pop = stack.pop
+    push = stack.append
+
+    while stack:
+        dir = pop()
+        names = os.listdir(dir)
+
+        for name in names:
+            if dir != os.curdir:        # avoid the dreaded "./" syndrome
+                fullname = os.path.join(dir, name)
+            else:
+                fullname = name
+
+            # Avoid excess stat calls -- just one will do, thank you!
+            stat = os.stat(fullname)
+            mode = stat[ST_MODE]
+            if S_ISREG(mode):
+                list.append(fullname)
+            elif S_ISDIR(mode) and not S_ISLNK(mode):
+                push(fullname)
+
+    return list
+
+
+def glob_to_re (pattern):
+    """Translate a shell-like glob pattern to a regular expression; return
+    a string containing the regex.  Differs from 'fnmatch.translate()' in
+    that '*' does not match "special characters" (which are
+    platform-specific).
+    """
+    pattern_re = fnmatch.translate(pattern)
+
+    # '?' and '*' in the glob pattern become '.' and '.*' in the RE, which
+    # IMHO is wrong -- '?' and '*' aren't supposed to match slash in Unix,
+    # and by extension they shouldn't match such "special characters" under
+    # any OS.  So change all non-escaped dots in the RE to match any
+    # character except the special characters.
+    # XXX currently the "special characters" are just slash -- i.e. this is
+    # Unix-only.
+    pattern_re = re.sub(r'(^|[^\\])\.', r'\1[^/]', pattern_re)
+    return pattern_re
+
+# glob_to_re ()
+
+
+def translate_pattern (pattern, anchor=1, prefix=None, is_regex=0):
+    """Translate a shell-like wildcard pattern to a compiled regular
+    expression.  Return the compiled regex.  If 'is_regex' true,
+    then 'pattern' is directly compiled to a regex (if it's a string)
+    or just returned as-is (assumes it's a regex object).
+    """
+    if is_regex:
+        if type(pattern) is StringType:
+            return re.compile(pattern)
+        else:
+            return pattern
+
+    if pattern:
+        pattern_re = glob_to_re(pattern)
+    else:
+        pattern_re = ''
+
+    if prefix is not None:
+        prefix_re = (glob_to_re(prefix))[0:-1] # ditch trailing $
+        pattern_re = "^" + os.path.join(prefix_re, ".*" + pattern_re)
+    else:                               # no prefix -- respect anchor flag
+        if anchor:
+            pattern_re = "^" + pattern_re
+
+    return re.compile(pattern_re)
+
+# translate_pattern ()

Added: vendor/Python/current/Lib/distutils/log.py
===================================================================
--- vendor/Python/current/Lib/distutils/log.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/log.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,69 @@
+"""A simple log mechanism styled after PEP 282."""
+
+# This module should be kept compatible with Python 2.1.
+
+# The class here is styled after PEP 282 so that it could later be
+# replaced with a standard Python logging implementation.
+
+DEBUG = 1
+INFO = 2
+WARN = 3
+ERROR = 4
+FATAL = 5
+
+import sys
+
+class Log:
+
+    def __init__(self, threshold=WARN):
+        self.threshold = threshold
+
+    def _log(self, level, msg, args):
+        if level >= self.threshold:
+            if not args:
+                # msg may contain a '%'. If args is empty,
+                # don't even try to string-format
+                print msg
+            else:
+                print msg % args
+            sys.stdout.flush()
+
+    def log(self, level, msg, *args):
+        self._log(level, msg, args)
+
+    def debug(self, msg, *args):
+        self._log(DEBUG, msg, args)
+
+    def info(self, msg, *args):
+        self._log(INFO, msg, args)
+
+    def warn(self, msg, *args):
+        self._log(WARN, msg, args)
+
+    def error(self, msg, *args):
+        self._log(ERROR, msg, args)
+
+    def fatal(self, msg, *args):
+        self._log(FATAL, msg, args)
+
+_global_log = Log()
+log = _global_log.log
+debug = _global_log.debug
+info = _global_log.info
+warn = _global_log.warn
+error = _global_log.error
+fatal = _global_log.fatal
+
+def set_threshold(level):
+    # return the old threshold for use from tests
+    old = _global_log.threshold
+    _global_log.threshold = level
+    return old
+
+def set_verbosity(v):
+    if v <= 0:
+        set_threshold(WARN)
+    elif v == 1:
+        set_threshold(INFO)
+    elif v >= 2:
+        set_threshold(DEBUG)

Added: vendor/Python/current/Lib/distutils/msvccompiler.py
===================================================================
--- vendor/Python/current/Lib/distutils/msvccompiler.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/msvccompiler.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,652 @@
+"""distutils.msvccompiler
+
+Contains MSVCCompiler, an implementation of the abstract CCompiler class
+for the Microsoft Visual Studio.
+"""
+
+# Written by Perry Stoll
+# hacked by Robin Becker and Thomas Heller to do a better job of
+#   finding DevStudio (through the registry)
+
+# This module should be kept compatible with Python 2.1.
+
+__revision__ = "$Id: msvccompiler.py 54645 2007-04-01 18:29:47Z neal.norwitz $"
+
+import sys, os, string
+from distutils.errors import \
+     DistutilsExecError, DistutilsPlatformError, \
+     CompileError, LibError, LinkError
+from distutils.ccompiler import \
+     CCompiler, gen_preprocess_options, gen_lib_options
+from distutils import log
+
+_can_read_reg = 0
+try:
+    import _winreg
+
+    _can_read_reg = 1
+    hkey_mod = _winreg
+
+    RegOpenKeyEx = _winreg.OpenKeyEx
+    RegEnumKey = _winreg.EnumKey
+    RegEnumValue = _winreg.EnumValue
+    RegError = _winreg.error
+
+except ImportError:
+    try:
+        import win32api
+        import win32con
+        _can_read_reg = 1
+        hkey_mod = win32con
+
+        RegOpenKeyEx = win32api.RegOpenKeyEx
+        RegEnumKey = win32api.RegEnumKey
+        RegEnumValue = win32api.RegEnumValue
+        RegError = win32api.error
+
+    except ImportError:
+        log.info("Warning: Can't read registry to find the "
+                 "necessary compiler setting\n"
+                 "Make sure that Python modules _winreg, "
+                 "win32api or win32con are installed.")
+        pass
+
+if _can_read_reg:
+    HKEYS = (hkey_mod.HKEY_USERS,
+             hkey_mod.HKEY_CURRENT_USER,
+             hkey_mod.HKEY_LOCAL_MACHINE,
+             hkey_mod.HKEY_CLASSES_ROOT)
+
+def read_keys(base, key):
+    """Return list of registry keys."""
+
+    try:
+        handle = RegOpenKeyEx(base, key)
+    except RegError:
+        return None
+    L = []
+    i = 0
+    while 1:
+        try:
+            k = RegEnumKey(handle, i)
+        except RegError:
+            break
+        L.append(k)
+        i = i + 1
+    return L
+
+def read_values(base, key):
+    """Return dict of registry keys and values.
+
+    All names are converted to lowercase.
+    """
+    try:
+        handle = RegOpenKeyEx(base, key)
+    except RegError:
+        return None
+    d = {}
+    i = 0
+    while 1:
+        try:
+            name, value, type = RegEnumValue(handle, i)
+        except RegError:
+            break
+        name = name.lower()
+        d[convert_mbcs(name)] = convert_mbcs(value)
+        i = i + 1
+    return d
+
+def convert_mbcs(s):
+    enc = getattr(s, "encode", None)
+    if enc is not None:
+        try:
+            s = enc("mbcs")
+        except UnicodeError:
+            pass
+    return s
+
+class MacroExpander:
+
+    def __init__(self, version):
+        self.macros = {}
+        self.load_macros(version)
+
+    def set_macro(self, macro, path, key):
+        for base in HKEYS:
+            d = read_values(base, path)
+            if d:
+                self.macros["$(%s)" % macro] = d[key]
+                break
+
+    def load_macros(self, version):
+        vsbase = r"Software\Microsoft\VisualStudio\%0.1f" % version
+        self.set_macro("VCInstallDir", vsbase + r"\Setup\VC", "productdir")
+        self.set_macro("VSInstallDir", vsbase + r"\Setup\VS", "productdir")
+        net = r"Software\Microsoft\.NETFramework"
+        self.set_macro("FrameworkDir", net, "installroot")
+        try:
+            if version > 7.0:
+                self.set_macro("FrameworkSDKDir", net, "sdkinstallrootv1.1")
+            else:
+                self.set_macro("FrameworkSDKDir", net, "sdkinstallroot")
+        except KeyError, exc: #
+            raise DistutilsPlatformError, \
+                  ("""Python was built with Visual Studio 2003;
+extensions must be built with a compiler than can generate compatible binaries.
+Visual Studio 2003 was not found on this system. If you have Cygwin installed,
+you can try compiling with MingW32, by passing "-c mingw32" to setup.py.""")
+
+        p = r"Software\Microsoft\NET Framework Setup\Product"
+        for base in HKEYS:
+            try:
+                h = RegOpenKeyEx(base, p)
+            except RegError:
+                continue
+            key = RegEnumKey(h, 0)
+            d = read_values(base, r"%s\%s" % (p, key))
+            self.macros["$(FrameworkVersion)"] = d["version"]
+
+    def sub(self, s):
+        for k, v in self.macros.items():
+            s = string.replace(s, k, v)
+        return s
+
+def get_build_version():
+    """Return the version of MSVC that was used to build Python.
+
+    For Python 2.3 and up, the version number is included in
+    sys.version.  For earlier versions, assume the compiler is MSVC 6.
+    """
+
+    prefix = "MSC v."
+    i = string.find(sys.version, prefix)
+    if i == -1:
+        return 6
+    i = i + len(prefix)
+    s, rest = sys.version[i:].split(" ", 1)
+    majorVersion = int(s[:-2]) - 6
+    minorVersion = int(s[2:3]) / 10.0
+    # I don't think paths are affected by minor version in version 6
+    if majorVersion == 6:
+        minorVersion = 0
+    if majorVersion >= 6:
+        return majorVersion + minorVersion
+    # else we don't know what version of the compiler this is
+    return None
+
+def get_build_architecture():
+    """Return the processor architecture.
+
+    Possible results are "Intel", "Itanium", or "AMD64".
+    """
+
+    prefix = " bit ("
+    i = string.find(sys.version, prefix)
+    if i == -1:
+        return "Intel"
+    j = string.find(sys.version, ")", i)
+    return sys.version[i+len(prefix):j]
+
+def normalize_and_reduce_paths(paths):
+    """Return a list of normalized paths with duplicates removed.
+
+    The current order of paths is maintained.
+    """
+    # Paths are normalized so things like:  /a and /a/ aren't both preserved.
+    reduced_paths = []
+    for p in paths:
+        np = os.path.normpath(p)
+        # XXX(nnorwitz): O(n**2), if reduced_paths gets long perhaps use a set.
+        if np not in reduced_paths:
+            reduced_paths.append(np)
+    return reduced_paths
+
+
+class MSVCCompiler (CCompiler) :
+    """Concrete class that implements an interface to Microsoft Visual C++,
+       as defined by the CCompiler abstract class."""
+
+    compiler_type = 'msvc'
+
+    # Just set this so CCompiler's constructor doesn't barf.  We currently
+    # don't use the 'set_executables()' bureaucracy provided by CCompiler,
+    # as it really isn't necessary for this sort of single-compiler class.
+    # Would be nice to have a consistent interface with UnixCCompiler,
+    # though, so it's worth thinking about.
+    executables = {}
+
+    # Private class data (need to distinguish C from C++ source for compiler)
+    _c_extensions = ['.c']
+    _cpp_extensions = ['.cc', '.cpp', '.cxx']
+    _rc_extensions = ['.rc']
+    _mc_extensions = ['.mc']
+
+    # Needed for the filename generation methods provided by the
+    # base class, CCompiler.
+    src_extensions = (_c_extensions + _cpp_extensions +
+                      _rc_extensions + _mc_extensions)
+    res_extension = '.res'
+    obj_extension = '.obj'
+    static_lib_extension = '.lib'
+    shared_lib_extension = '.dll'
+    static_lib_format = shared_lib_format = '%s%s'
+    exe_extension = '.exe'
+
+    def __init__ (self, verbose=0, dry_run=0, force=0):
+        CCompiler.__init__ (self, verbose, dry_run, force)
+        self.__version = get_build_version()
+        self.__arch = get_build_architecture()
+        if self.__arch == "Intel":
+            # x86
+            if self.__version >= 7:
+                self.__root = r"Software\Microsoft\VisualStudio"
+                self.__macros = MacroExpander(self.__version)
+            else:
+                self.__root = r"Software\Microsoft\Devstudio"
+            self.__product = "Visual Studio version %s" % self.__version
+        else:
+            # Win64. Assume this was built with the platform SDK
+            self.__product = "Microsoft SDK compiler %s" % (self.__version + 6)
+
+        self.initialized = False
+
+    def initialize(self):
+        self.__paths = []
+        if os.environ.has_key("DISTUTILS_USE_SDK") and os.environ.has_key("MSSdk") and self.find_exe("cl.exe"):
+            # Assume that the SDK set up everything alright; don't try to be
+            # smarter
+            self.cc = "cl.exe"
+            self.linker = "link.exe"
+            self.lib = "lib.exe"
+            self.rc = "rc.exe"
+            self.mc = "mc.exe"
+        else:
+            self.__paths = self.get_msvc_paths("path")
+
+            if len (self.__paths) == 0:
+                raise DistutilsPlatformError, \
+                      ("Python was built with %s, "
+                       "and extensions need to be built with the same "
+                       "version of the compiler, but it isn't installed." % self.__product)
+
+            self.cc = self.find_exe("cl.exe")
+            self.linker = self.find_exe("link.exe")
+            self.lib = self.find_exe("lib.exe")
+            self.rc = self.find_exe("rc.exe")   # resource compiler
+            self.mc = self.find_exe("mc.exe")   # message compiler
+            self.set_path_env_var('lib')
+            self.set_path_env_var('include')
+
+        # extend the MSVC path with the current path
+        try:
+            for p in string.split(os.environ['path'], ';'):
+                self.__paths.append(p)
+        except KeyError:
+            pass
+        self.__paths = normalize_and_reduce_paths(self.__paths)
+        os.environ['path'] = string.join(self.__paths, ';')
+
+        self.preprocess_options = None
+        if self.__arch == "Intel":
+            self.compile_options = [ '/nologo', '/Ox', '/MD', '/W3', '/GX' ,
+                                     '/DNDEBUG']
+            self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/GX',
+                                          '/Z7', '/D_DEBUG']
+        else:
+            # Win64
+            self.compile_options = [ '/nologo', '/Ox', '/MD', '/W3', '/GS-' ,
+                                     '/DNDEBUG']
+            self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/GS-',
+                                          '/Z7', '/D_DEBUG']
+
+        self.ldflags_shared = ['/DLL', '/nologo', '/INCREMENTAL:NO']
+        if self.__version >= 7:
+            self.ldflags_shared_debug = [
+                '/DLL', '/nologo', '/INCREMENTAL:no', '/DEBUG'
+                ]
+        else:
+            self.ldflags_shared_debug = [
+                '/DLL', '/nologo', '/INCREMENTAL:no', '/pdb:None', '/DEBUG'
+                ]
+        self.ldflags_static = [ '/nologo']
+
+        self.initialized = True
+
+    # -- Worker methods ------------------------------------------------
+
+    def object_filenames (self,
+                          source_filenames,
+                          strip_dir=0,
+                          output_dir=''):
+        # Copied from ccompiler.py, extended to return .res as 'object'-file
+        # for .rc input file
+        if output_dir is None: output_dir = ''
+        obj_names = []
+        for src_name in source_filenames:
+            (base, ext) = os.path.splitext (src_name)
+            base = os.path.splitdrive(base)[1] # Chop off the drive
+            base = base[os.path.isabs(base):]  # If abs, chop off leading /
+            if ext not in self.src_extensions:
+                # Better to raise an exception instead of silently continuing
+                # and later complain about sources and targets having
+                # different lengths
+                raise CompileError ("Don't know how to compile %s" % src_name)
+            if strip_dir:
+                base = os.path.basename (base)
+            if ext in self._rc_extensions:
+                obj_names.append (os.path.join (output_dir,
+                                                base + self.res_extension))
+            elif ext in self._mc_extensions:
+                obj_names.append (os.path.join (output_dir,
+                                                base + self.res_extension))
+            else:
+                obj_names.append (os.path.join (output_dir,
+                                                base + self.obj_extension))
+        return obj_names
+
+    # object_filenames ()
+
+
+    def compile(self, sources,
+                output_dir=None, macros=None, include_dirs=None, debug=0,
+                extra_preargs=None, extra_postargs=None, depends=None):
+
+        if not self.initialized: self.initialize()
+        macros, objects, extra_postargs, pp_opts, build = \
+                self._setup_compile(output_dir, macros, include_dirs, sources,
+                                    depends, extra_postargs)
+
+        compile_opts = extra_preargs or []
+        compile_opts.append ('/c')
+        if debug:
+            compile_opts.extend(self.compile_options_debug)
+        else:
+            compile_opts.extend(self.compile_options)
+
+        for obj in objects:
+            try:
+                src, ext = build[obj]
+            except KeyError:
+                continue
+            if debug:
+                # pass the full pathname to MSVC in debug mode,
+                # this allows the debugger to find the source file
+                # without asking the user to browse for it
+                src = os.path.abspath(src)
+
+            if ext in self._c_extensions:
+                input_opt = "/Tc" + src
+            elif ext in self._cpp_extensions:
+                input_opt = "/Tp" + src
+            elif ext in self._rc_extensions:
+                # compile .RC to .RES file
+                input_opt = src
+                output_opt = "/fo" + obj
+                try:
+                    self.spawn ([self.rc] + pp_opts +
+                                [output_opt] + [input_opt])
+                except DistutilsExecError, msg:
+                    raise CompileError, msg
+                continue
+            elif ext in self._mc_extensions:
+
+                # Compile .MC to .RC file to .RES file.
+                #   * '-h dir' specifies the directory for the
+                #     generated include file
+                #   * '-r dir' specifies the target directory of the
+                #     generated RC file and the binary message resource
+                #     it includes
+                #
+                # For now (since there are no options to change this),
+                # we use the source-directory for the include file and
+                # the build directory for the RC file and message
+                # resources. This works at least for win32all.
+
+                h_dir = os.path.dirname (src)
+                rc_dir = os.path.dirname (obj)
+                try:
+                    # first compile .MC to .RC and .H file
+                    self.spawn ([self.mc] +
+                                ['-h', h_dir, '-r', rc_dir] + [src])
+                    base, _ = os.path.splitext (os.path.basename (src))
+                    rc_file = os.path.join (rc_dir, base + '.rc')
+                    # then compile .RC to .RES file
+                    self.spawn ([self.rc] +
+                                ["/fo" + obj] + [rc_file])
+
+                except DistutilsExecError, msg:
+                    raise CompileError, msg
+                continue
+            else:
+                # how to handle this file?
+                raise CompileError (
+                    "Don't know how to compile %s to %s" % \
+                    (src, obj))
+
+            output_opt = "/Fo" + obj
+            try:
+                self.spawn ([self.cc] + compile_opts + pp_opts +
+                            [input_opt, output_opt] +
+                            extra_postargs)
+            except DistutilsExecError, msg:
+                raise CompileError, msg
+
+        return objects
+
+    # compile ()
+
+
+    def create_static_lib (self,
+                           objects,
+                           output_libname,
+                           output_dir=None,
+                           debug=0,
+                           target_lang=None):
+
+        if not self.initialized: self.initialize()
+        (objects, output_dir) = self._fix_object_args (objects, output_dir)
+        output_filename = \
+            self.library_filename (output_libname, output_dir=output_dir)
+
+        if self._need_link (objects, output_filename):
+            lib_args = objects + ['/OUT:' + output_filename]
+            if debug:
+                pass                    # XXX what goes here?
+            try:
+                self.spawn ([self.lib] + lib_args)
+            except DistutilsExecError, msg:
+                raise LibError, msg
+
+        else:
+            log.debug("skipping %s (up-to-date)", output_filename)
+
+    # create_static_lib ()
+
+    def link (self,
+              target_desc,
+              objects,
+              output_filename,
+              output_dir=None,
+              libraries=None,
+              library_dirs=None,
+              runtime_library_dirs=None,
+              export_symbols=None,
+              debug=0,
+              extra_preargs=None,
+              extra_postargs=None,
+              build_temp=None,
+              target_lang=None):
+
+        if not self.initialized: self.initialize()
+        (objects, output_dir) = self._fix_object_args (objects, output_dir)
+        (libraries, library_dirs, runtime_library_dirs) = \
+            self._fix_lib_args (libraries, library_dirs, runtime_library_dirs)
+
+        if runtime_library_dirs:
+            self.warn ("I don't know what to do with 'runtime_library_dirs': "
+                       + str (runtime_library_dirs))
+
+        lib_opts = gen_lib_options (self,
+                                    library_dirs, runtime_library_dirs,
+                                    libraries)
+        if output_dir is not None:
+            output_filename = os.path.join (output_dir, output_filename)
+
+        if self._need_link (objects, output_filename):
+
+            if target_desc == CCompiler.EXECUTABLE:
+                if debug:
+                    ldflags = self.ldflags_shared_debug[1:]
+                else:
+                    ldflags = self.ldflags_shared[1:]
+            else:
+                if debug:
+                    ldflags = self.ldflags_shared_debug
+                else:
+                    ldflags = self.ldflags_shared
+
+            export_opts = []
+            for sym in (export_symbols or []):
+                export_opts.append("/EXPORT:" + sym)
+
+            ld_args = (ldflags + lib_opts + export_opts +
+                       objects + ['/OUT:' + output_filename])
+
+            # The MSVC linker generates .lib and .exp files, which cannot be
+            # suppressed by any linker switches. The .lib files may even be
+            # needed! Make sure they are generated in the temporary build
+            # directory. Since they have different names for debug and release
+            # builds, they can go into the same directory.
+            if export_symbols is not None:
+                (dll_name, dll_ext) = os.path.splitext(
+                    os.path.basename(output_filename))
+                implib_file = os.path.join(
+                    os.path.dirname(objects[0]),
+                    self.library_filename(dll_name))
+                ld_args.append ('/IMPLIB:' + implib_file)
+
+            if extra_preargs:
+                ld_args[:0] = extra_preargs
+            if extra_postargs:
+                ld_args.extend(extra_postargs)
+
+            self.mkpath (os.path.dirname (output_filename))
+            try:
+                self.spawn ([self.linker] + ld_args)
+            except DistutilsExecError, msg:
+                raise LinkError, msg
+
+        else:
+            log.debug("skipping %s (up-to-date)", output_filename)
+
+    # link ()
+
+
+    # -- Miscellaneous methods -----------------------------------------
+    # These are all used by the 'gen_lib_options() function, in
+    # ccompiler.py.
+
+    def library_dir_option (self, dir):
+        return "/LIBPATH:" + dir
+
+    def runtime_library_dir_option (self, dir):
+        raise DistutilsPlatformError, \
+              "don't know how to set runtime library search path for MSVC++"
+
+    def library_option (self, lib):
+        return self.library_filename (lib)
+
+
+    def find_library_file (self, dirs, lib, debug=0):
+        # Prefer a debugging library if found (and requested), but deal
+        # with it if we don't have one.
+        if debug:
+            try_names = [lib + "_d", lib]
+        else:
+            try_names = [lib]
+        for dir in dirs:
+            for name in try_names:
+                libfile = os.path.join(dir, self.library_filename (name))
+                if os.path.exists(libfile):
+                    return libfile
+        else:
+            # Oops, didn't find it in *any* of 'dirs'
+            return None
+
+    # find_library_file ()
+
+    # Helper methods for using the MSVC registry settings
+
+    def find_exe(self, exe):
+        """Return path to an MSVC executable program.
+
+        Tries to find the program in several places: first, one of the
+        MSVC program search paths from the registry; next, the directories
+        in the PATH environment variable.  If any of those work, return an
+        absolute path that is known to exist.  If none of them work, just
+        return the original program name, 'exe'.
+        """
+
+        for p in self.__paths:
+            fn = os.path.join(os.path.abspath(p), exe)
+            if os.path.isfile(fn):
+                return fn
+
+        # didn't find it; try existing path
+        for p in string.split(os.environ['Path'],';'):
+            fn = os.path.join(os.path.abspath(p),exe)
+            if os.path.isfile(fn):
+                return fn
+
+        return exe
+
+    def get_msvc_paths(self, path, platform='x86'):
+        """Get a list of devstudio directories (include, lib or path).
+
+        Return a list of strings.  The list will be empty if unable to
+        access the registry or appropriate registry keys not found.
+        """
+
+        if not _can_read_reg:
+            return []
+
+        path = path + " dirs"
+        if self.__version >= 7:
+            key = (r"%s\%0.1f\VC\VC_OBJECTS_PLATFORM_INFO\Win32\Directories"
+                   % (self.__root, self.__version))
+        else:
+            key = (r"%s\6.0\Build System\Components\Platforms"
+                   r"\Win32 (%s)\Directories" % (self.__root, platform))
+
+        for base in HKEYS:
+            d = read_values(base, key)
+            if d:
+                if self.__version >= 7:
+                    return string.split(self.__macros.sub(d[path]), ";")
+                else:
+                    return string.split(d[path], ";")
+        # MSVC 6 seems to create the registry entries we need only when
+        # the GUI is run.
+        if self.__version == 6:
+            for base in HKEYS:
+                if read_values(base, r"%s\6.0" % self.__root) is not None:
+                    self.warn("It seems you have Visual Studio 6 installed, "
+                        "but the expected registry settings are not present.\n"
+                        "You must at least run the Visual Studio GUI once "
+                        "so that these entries are created.")
+                    break
+        return []
+
+    def set_path_env_var(self, name):
+        """Set environment variable 'name' to an MSVC path type value.
+
+        This is equivalent to a SET command prior to execution of spawned
+        commands.
+        """
+
+        if name == "lib":
+            p = self.get_msvc_paths("library")
+        else:
+            p = self.get_msvc_paths(name)
+        if p:
+            os.environ[name] = string.join(p, ';')

Added: vendor/Python/current/Lib/distutils/mwerkscompiler.py
===================================================================
--- vendor/Python/current/Lib/distutils/mwerkscompiler.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/mwerkscompiler.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,248 @@
+"""distutils.mwerkscompiler
+
+Contains MWerksCompiler, an implementation of the abstract CCompiler class
+for MetroWerks CodeWarrior on the Macintosh. Needs work to support CW on
+Windows."""
+
+# This module should be kept compatible with Python 2.1.
+
+__revision__ = "$Id: mwerkscompiler.py 37828 2004-11-10 22:23:15Z loewis $"
+
+import sys, os, string
+from types import *
+from distutils.errors import \
+     DistutilsExecError, DistutilsPlatformError, \
+     CompileError, LibError, LinkError
+from distutils.ccompiler import \
+     CCompiler, gen_preprocess_options, gen_lib_options
+import distutils.util
+import distutils.dir_util
+from distutils import log
+import mkcwproject
+
+class MWerksCompiler (CCompiler) :
+    """Concrete class that implements an interface to MetroWerks CodeWarrior,
+       as defined by the CCompiler abstract class."""
+
+    compiler_type = 'mwerks'
+
+    # Just set this so CCompiler's constructor doesn't barf.  We currently
+    # don't use the 'set_executables()' bureaucracy provided by CCompiler,
+    # as it really isn't necessary for this sort of single-compiler class.
+    # Would be nice to have a consistent interface with UnixCCompiler,
+    # though, so it's worth thinking about.
+    executables = {}
+
+    # Private class data (need to distinguish C from C++ source for compiler)
+    _c_extensions = ['.c']
+    _cpp_extensions = ['.cc', '.cpp', '.cxx']
+    _rc_extensions = ['.r']
+    _exp_extension = '.exp'
+
+    # Needed for the filename generation methods provided by the
+    # base class, CCompiler.
+    src_extensions = (_c_extensions + _cpp_extensions +
+                      _rc_extensions)
+    res_extension = '.rsrc'
+    obj_extension = '.obj' # Not used, really
+    static_lib_extension = '.lib'
+    shared_lib_extension = '.slb'
+    static_lib_format = shared_lib_format = '%s%s'
+    exe_extension = ''
+
+
+    def __init__ (self,
+                  verbose=0,
+                  dry_run=0,
+                  force=0):
+
+        CCompiler.__init__ (self, verbose, dry_run, force)
+
+
+    def compile (self,
+                 sources,
+                 output_dir=None,
+                 macros=None,
+                 include_dirs=None,
+                 debug=0,
+                 extra_preargs=None,
+                 extra_postargs=None,
+                 depends=None):
+        (output_dir, macros, include_dirs) = \
+           self._fix_compile_args (output_dir, macros, include_dirs)
+        self.__sources = sources
+        self.__macros = macros
+        self.__include_dirs = include_dirs
+        # Don't need extra_preargs and extra_postargs for CW
+        return []
+
+    def link (self,
+              target_desc,
+              objects,
+              output_filename,
+              output_dir=None,
+              libraries=None,
+              library_dirs=None,
+              runtime_library_dirs=None,
+              export_symbols=None,
+              debug=0,
+              extra_preargs=None,
+              extra_postargs=None,
+              build_temp=None,
+              target_lang=None):
+        # First fixup.
+        (objects, output_dir) = self._fix_object_args (objects, output_dir)
+        (libraries, library_dirs, runtime_library_dirs) = \
+            self._fix_lib_args (libraries, library_dirs, runtime_library_dirs)
+
+        # First examine a couple of options for things that aren't implemented yet
+        if not target_desc in (self.SHARED_LIBRARY, self.SHARED_OBJECT):
+            raise DistutilsPlatformError, 'Can only make SHARED_LIBRARY or SHARED_OBJECT targets on the Mac'
+        if runtime_library_dirs:
+            raise DistutilsPlatformError, 'Runtime library dirs not implemented yet'
+        if extra_preargs or extra_postargs:
+            raise DistutilsPlatformError, 'Runtime library dirs not implemented yet'
+        if len(export_symbols) != 1:
+            raise DistutilsPlatformError, 'Need exactly one export symbol'
+        # Next there are various things for which we need absolute pathnames.
+        # This is because we (usually) create the project in a subdirectory of
+        # where we are now, and keeping the paths relative is too much work right
+        # now.
+        sources = map(self._filename_to_abs, self.__sources)
+        include_dirs = map(self._filename_to_abs, self.__include_dirs)
+        if objects:
+            objects = map(self._filename_to_abs, objects)
+        else:
+            objects = []
+        if build_temp:
+            build_temp = self._filename_to_abs(build_temp)
+        else:
+            build_temp = os.curdir()
+        if output_dir:
+            output_filename = os.path.join(output_dir, output_filename)
+        # The output filename needs special handling: splitting it into dir and
+        # filename part. Actually I'm not sure this is really needed, but it
+        # can't hurt.
+        output_filename = self._filename_to_abs(output_filename)
+        output_dir, output_filename = os.path.split(output_filename)
+        # Now we need the short names of a couple of things for putting them
+        # into the project.
+        if output_filename[-8:] == '.ppc.slb':
+            basename = output_filename[:-8]
+        elif output_filename[-11:] == '.carbon.slb':
+            basename = output_filename[:-11]
+        else:
+            basename = os.path.strip(output_filename)[0]
+        projectname = basename + '.mcp'
+        targetname = basename
+        xmlname = basename + '.xml'
+        exportname = basename + '.mcp.exp'
+        prefixname = 'mwerks_%s_config.h'%basename
+        # Create the directories we need
+        distutils.dir_util.mkpath(build_temp, dry_run=self.dry_run)
+        distutils.dir_util.mkpath(output_dir, dry_run=self.dry_run)
+        # And on to filling in the parameters for the project builder
+        settings = {}
+        settings['mac_exportname'] = exportname
+        settings['mac_outputdir'] = output_dir
+        settings['mac_dllname'] = output_filename
+        settings['mac_targetname'] = targetname
+        settings['sysprefix'] = sys.prefix
+        settings['mac_sysprefixtype'] = 'Absolute'
+        sourcefilenames = []
+        sourcefiledirs = []
+        for filename in sources + objects:
+            dirname, filename = os.path.split(filename)
+            sourcefilenames.append(filename)
+            if not dirname in sourcefiledirs:
+                sourcefiledirs.append(dirname)
+        settings['sources'] = sourcefilenames
+        settings['libraries'] = libraries
+        settings['extrasearchdirs'] = sourcefiledirs + include_dirs + library_dirs
+        if self.dry_run:
+            print 'CALLING LINKER IN', os.getcwd()
+            for key, value in settings.items():
+                print '%20.20s %s'%(key, value)
+            return
+        # Build the export file
+        exportfilename = os.path.join(build_temp, exportname)
+        log.debug("\tCreate export file %s", exportfilename)
+        fp = open(exportfilename, 'w')
+        fp.write('%s\n'%export_symbols[0])
+        fp.close()
+        # Generate the prefix file, if needed, and put it in the settings
+        if self.__macros:
+            prefixfilename = os.path.join(os.getcwd(), os.path.join(build_temp, prefixname))
+            fp = open(prefixfilename, 'w')
+            fp.write('#include "mwerks_shcarbon_config.h"\n')
+            for name, value in self.__macros:
+                if value is None:
+                    fp.write('#define %s\n'%name)
+                else:
+                    fp.write('#define %s %s\n'%(name, value))
+            fp.close()
+            settings['prefixname'] = prefixname
+
+        # Build the XML file. We need the full pathname (only lateron, really)
+        # because we pass this pathname to CodeWarrior in an AppleEvent, and CW
+        # doesn't have a clue about our working directory.
+        xmlfilename = os.path.join(os.getcwd(), os.path.join(build_temp, xmlname))
+        log.debug("\tCreate XML file %s", xmlfilename)
+        xmlbuilder = mkcwproject.cwxmlgen.ProjectBuilder(settings)
+        xmlbuilder.generate()
+        xmldata = settings['tmp_projectxmldata']
+        fp = open(xmlfilename, 'w')
+        fp.write(xmldata)
+        fp.close()
+        # Generate the project. Again a full pathname.
+        projectfilename = os.path.join(os.getcwd(), os.path.join(build_temp, projectname))
+        log.debug('\tCreate project file %s', projectfilename)
+        mkcwproject.makeproject(xmlfilename, projectfilename)
+        # And build it
+        log.debug('\tBuild project')
+        mkcwproject.buildproject(projectfilename)
+
+    def _filename_to_abs(self, filename):
+        # Some filenames seem to be unix-like. Convert to Mac names.
+##        if '/' in filename and ':' in filename:
+##           raise DistutilsPlatformError, 'Filename may be Unix or Mac style: %s'%filename
+##        if '/' in filename:
+##           filename = macurl2path(filename)
+        filename = distutils.util.convert_path(filename)
+        if not os.path.isabs(filename):
+            curdir = os.getcwd()
+            filename = os.path.join(curdir, filename)
+        # Finally remove .. components
+        components = string.split(filename, ':')
+        for i in range(1, len(components)):
+            if components[i] == '..':
+                components[i] = ''
+        return string.join(components, ':')
+
+    def library_dir_option (self, dir):
+        """Return the compiler option to add 'dir' to the list of
+        directories searched for libraries.
+        """
+        return # XXXX Not correct...
+
+    def runtime_library_dir_option (self, dir):
+        """Return the compiler option to add 'dir' to the list of
+        directories searched for runtime libraries.
+        """
+        # Nothing needed or Mwerks/Mac.
+        return
+
+    def library_option (self, lib):
+        """Return the compiler option to add 'dir' to the list of libraries
+        linked into the shared library or executable.
+        """
+        return
+
+    def find_library_file (self, dirs, lib, debug=0):
+        """Search the specified list of directories for a static or shared
+        library file 'lib' and return the full path to that file.  If
+        'debug' true, look for a debugging version (if that makes sense on
+        the current platform).  Return None if 'lib' wasn't found in any of
+        the specified directories.
+        """
+        return 0

Added: vendor/Python/current/Lib/distutils/spawn.py
===================================================================
--- vendor/Python/current/Lib/distutils/spawn.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/spawn.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,201 @@
+"""distutils.spawn
+
+Provides the 'spawn()' function, a front-end to various platform-
+specific functions for launching another program in a sub-process.
+Also provides the 'find_executable()' to search the path for a given
+executable name.
+"""
+
+# This module should be kept compatible with Python 2.1.
+
+__revision__ = "$Id: spawn.py 37828 2004-11-10 22:23:15Z loewis $"
+
+import sys, os, string
+from distutils.errors import *
+from distutils import log
+
+def spawn (cmd,
+           search_path=1,
+           verbose=0,
+           dry_run=0):
+
+    """Run another program, specified as a command list 'cmd', in a new
+    process.  'cmd' is just the argument list for the new process, ie.
+    cmd[0] is the program to run and cmd[1:] are the rest of its arguments.
+    There is no way to run a program with a name different from that of its
+    executable.
+
+    If 'search_path' is true (the default), the system's executable
+    search path will be used to find the program; otherwise, cmd[0]
+    must be the exact path to the executable.  If 'dry_run' is true,
+    the command will not actually be run.
+
+    Raise DistutilsExecError if running the program fails in any way; just
+    return on success.
+    """
+    if os.name == 'posix':
+        _spawn_posix(cmd, search_path, dry_run=dry_run)
+    elif os.name == 'nt':
+        _spawn_nt(cmd, search_path, dry_run=dry_run)
+    elif os.name == 'os2':
+        _spawn_os2(cmd, search_path, dry_run=dry_run)
+    else:
+        raise DistutilsPlatformError, \
+              "don't know how to spawn programs on platform '%s'" % os.name
+
+# spawn ()
+
+
+def _nt_quote_args (args):
+    """Quote command-line arguments for DOS/Windows conventions: just
+    wraps every argument which contains blanks in double quotes, and
+    returns a new argument list.
+    """
+
+    # XXX this doesn't seem very robust to me -- but if the Windows guys
+    # say it'll work, I guess I'll have to accept it.  (What if an arg
+    # contains quotes?  What other magic characters, other than spaces,
+    # have to be escaped?  Is there an escaping mechanism other than
+    # quoting?)
+
+    for i in range(len(args)):
+        if string.find(args[i], ' ') != -1:
+            args[i] = '"%s"' % args[i]
+    return args
+
+def _spawn_nt (cmd,
+               search_path=1,
+               verbose=0,
+               dry_run=0):
+
+    executable = cmd[0]
+    cmd = _nt_quote_args(cmd)
+    if search_path:
+        # either we find one or it stays the same
+        executable = find_executable(executable) or executable
+    log.info(string.join([executable] + cmd[1:], ' '))
+    if not dry_run:
+        # spawn for NT requires a full path to the .exe
+        try:
+            rc = os.spawnv(os.P_WAIT, executable, cmd)
+        except OSError, exc:
+            # this seems to happen when the command isn't found
+            raise DistutilsExecError, \
+                  "command '%s' failed: %s" % (cmd[0], exc[-1])
+        if rc != 0:
+            # and this reflects the command running but failing
+            raise DistutilsExecError, \
+                  "command '%s' failed with exit status %d" % (cmd[0], rc)
+
+
+def _spawn_os2 (cmd,
+                search_path=1,
+                verbose=0,
+                dry_run=0):
+
+    executable = cmd[0]
+    #cmd = _nt_quote_args(cmd)
+    if search_path:
+        # either we find one or it stays the same
+        executable = find_executable(executable) or executable
+    log.info(string.join([executable] + cmd[1:], ' '))
+    if not dry_run:
+        # spawnv for OS/2 EMX requires a full path to the .exe
+        try:
+            rc = os.spawnv(os.P_WAIT, executable, cmd)
+        except OSError, exc:
+            # this seems to happen when the command isn't found
+            raise DistutilsExecError, \
+                  "command '%s' failed: %s" % (cmd[0], exc[-1])
+        if rc != 0:
+            # and this reflects the command running but failing
+            print "command '%s' failed with exit status %d" % (cmd[0], rc)
+            raise DistutilsExecError, \
+                  "command '%s' failed with exit status %d" % (cmd[0], rc)
+
+
+def _spawn_posix (cmd,
+                  search_path=1,
+                  verbose=0,
+                  dry_run=0):
+
+    log.info(string.join(cmd, ' '))
+    if dry_run:
+        return
+    exec_fn = search_path and os.execvp or os.execv
+
+    pid = os.fork()
+
+    if pid == 0:                        # in the child
+        try:
+            #print "cmd[0] =", cmd[0]
+            #print "cmd =", cmd
+            exec_fn(cmd[0], cmd)
+        except OSError, e:
+            sys.stderr.write("unable to execute %s: %s\n" %
+                             (cmd[0], e.strerror))
+            os._exit(1)
+
+        sys.stderr.write("unable to execute %s for unknown reasons" % cmd[0])
+        os._exit(1)
+
+
+    else:                               # in the parent
+        # Loop until the child either exits or is terminated by a signal
+        # (ie. keep waiting if it's merely stopped)
+        while 1:
+            try:
+                (pid, status) = os.waitpid(pid, 0)
+            except OSError, exc:
+                import errno
+                if exc.errno == errno.EINTR:
+                    continue
+                raise DistutilsExecError, \
+                      "command '%s' failed: %s" % (cmd[0], exc[-1])
+            if os.WIFSIGNALED(status):
+                raise DistutilsExecError, \
+                      "command '%s' terminated by signal %d" % \
+                      (cmd[0], os.WTERMSIG(status))
+
+            elif os.WIFEXITED(status):
+                exit_status = os.WEXITSTATUS(status)
+                if exit_status == 0:
+                    return              # hey, it succeeded!
+                else:
+                    raise DistutilsExecError, \
+                          "command '%s' failed with exit status %d" % \
+                          (cmd[0], exit_status)
+
+            elif os.WIFSTOPPED(status):
+                continue
+
+            else:
+                raise DistutilsExecError, \
+                      "unknown error executing '%s': termination status %d" % \
+                      (cmd[0], status)
+# _spawn_posix ()
+
+
+def find_executable(executable, path=None):
+    """Try to find 'executable' in the directories listed in 'path' (a
+    string listing directories separated by 'os.pathsep'; defaults to
+    os.environ['PATH']).  Returns the complete filename or None if not
+    found.
+    """
+    if path is None:
+        path = os.environ['PATH']
+    paths = string.split(path, os.pathsep)
+    (base, ext) = os.path.splitext(executable)
+    if (sys.platform == 'win32' or os.name == 'os2') and (ext != '.exe'):
+        executable = executable + '.exe'
+    if not os.path.isfile(executable):
+        for p in paths:
+            f = os.path.join(p, executable)
+            if os.path.isfile(f):
+                # the file exists, we have a shot at spawn working
+                return f
+        return None
+    else:
+        return executable
+
+# find_executable()

Added: vendor/Python/current/Lib/distutils/sysconfig.py
===================================================================
--- vendor/Python/current/Lib/distutils/sysconfig.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/sysconfig.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,535 @@
+"""Provide access to Python's configuration information.  The specific
+configuration variables available depend heavily on the platform and
+configuration.  The values may be retrieved using
+get_config_var(name), and the list of variables is available via
+get_config_vars().keys().  Additional convenience functions are also
+available.
+
+Written by:   Fred L. Drake, Jr.
+Email:        <fdrake at acm.org>
+"""
+
+__revision__ = "$Id: sysconfig.py 52234 2006-10-08 17:50:26Z ronald.oussoren $"
+
+import os
+import re
+import string
+import sys
+
+from distutils.errors import DistutilsPlatformError
+
+# These are needed in a couple of spots, so just compute them once.
+PREFIX = os.path.normpath(sys.prefix)
+EXEC_PREFIX = os.path.normpath(sys.exec_prefix)
+
+# python_build: (Boolean) if true, we're either building Python or
+# building an extension with an un-installed Python, so we use
+# different (hard-wired) directories.
+
+argv0_path = os.path.dirname(os.path.abspath(sys.executable))
+landmark = os.path.join(argv0_path, "Modules", "Setup")
+
+python_build = os.path.isfile(landmark)
+
+del landmark
+
+
+def get_python_version():
+    """Return a string containing the major and minor Python version,
+    leaving off the patchlevel.  Sample return values could be '1.5'
+    or '2.2'.
+    """
+    return sys.version[:3]
+
+
+def get_python_inc(plat_specific=0, prefix=None):
+    """Return the directory containing installed Python header files.
+
+    If 'plat_specific' is false (the default), this is the path to the
+    non-platform-specific header files, i.e. Python.h and so on;
+    otherwise, this is the path to platform-specific header files
+    (namely pyconfig.h).
+
+    If 'prefix' is supplied, use it instead of sys.prefix or
+    sys.exec_prefix -- i.e., ignore 'plat_specific'.
+    """
+    if prefix is None:
+        prefix = plat_specific and EXEC_PREFIX or PREFIX
+    if os.name == "posix":
+        if python_build:
+            base = os.path.dirname(os.path.abspath(sys.executable))
+            if plat_specific:
+                inc_dir = base
+            else:
+                inc_dir = os.path.join(base, "Include")
+                if not os.path.exists(inc_dir):
+                    inc_dir = os.path.join(os.path.dirname(base), "Include")
+            return inc_dir
+        return os.path.join(prefix, "include", "python" + get_python_version())
+    elif os.name == "nt":
+        return os.path.join(prefix, "include")
+    elif os.name == "mac":
+        if plat_specific:
+            return os.path.join(prefix, "Mac", "Include")
+        else:
+            return os.path.join(prefix, "Include")
+    elif os.name == "os2":
+        return os.path.join(prefix, "Include")
+    else:
+        raise DistutilsPlatformError(
+            "I don't know where Python installs its C header files "
+            "on platform '%s'" % os.name)
+
+
+def get_python_lib(plat_specific=0, standard_lib=0, prefix=None):
+    """Return the directory containing the Python library (standard or
+    site additions).
+
+    If 'plat_specific' is true, return the directory containing
+    platform-specific modules, i.e. any module from a non-pure-Python
+    module distribution; otherwise, return the platform-shared library
+    directory.  If 'standard_lib' is true, return the directory
+    containing standard Python library modules; otherwise, return the
+    directory for site-specific modules.
+
+    If 'prefix' is supplied, use it instead of sys.prefix or
+    sys.exec_prefix -- i.e., ignore 'plat_specific'.
+    """
+    if prefix is None:
+        prefix = plat_specific and EXEC_PREFIX or PREFIX
+
+    if os.name == "posix":
+        libpython = os.path.join(prefix,
+                                 "lib", "python" + get_python_version())
+        if standard_lib:
+            return libpython
+        else:
+            return os.path.join(libpython, "site-packages")
+
+    elif os.name == "nt":
+        if standard_lib:
+            return os.path.join(prefix, "Lib")
+        else:
+            if get_python_version() < "2.2":
+                return prefix
+            else:
+                return os.path.join(PREFIX, "Lib", "site-packages")
+
+    elif os.name == "mac":
+        if plat_specific:
+            if standard_lib:
+                return os.path.join(prefix, "Lib", "lib-dynload")
+            else:
+                return os.path.join(prefix, "Lib", "site-packages")
+        else:
+            if standard_lib:
+                return os.path.join(prefix, "Lib")
+            else:
+                return os.path.join(prefix, "Lib", "site-packages")
+
+    elif os.name == "os2":
+        if standard_lib:
+            return os.path.join(PREFIX, "Lib")
+        else:
+            return os.path.join(PREFIX, "Lib", "site-packages")
+
+    else:
+        raise DistutilsPlatformError(
+            "I don't know where Python installs its library "
+            "on platform '%s'" % os.name)
+
+
+def customize_compiler(compiler):
+    """Do any platform-specific customization of a CCompiler instance.
+
+    Mainly needed on Unix, so we can plug in the information that
+    varies across Unices and is stored in Python's Makefile.
+    """
+    if compiler.compiler_type == "unix":
+        (cc, cxx, opt, cflags, ccshared, ldshared, so_ext) = \
+            get_config_vars('CC', 'CXX', 'OPT', 'CFLAGS',
+                            'CCSHARED', 'LDSHARED', 'SO')
+
+        if os.environ.has_key('CC'):
+            cc = os.environ['CC']
+        if os.environ.has_key('CXX'):
+            cxx = os.environ['CXX']
+        if os.environ.has_key('LDSHARED'):
+            ldshared = os.environ['LDSHARED']
+        if os.environ.has_key('CPP'):
+            cpp = os.environ['CPP']
+        else:
+            cpp = cc + " -E"           # not always
+        if os.environ.has_key('LDFLAGS'):
+            ldshared = ldshared + ' ' + os.environ['LDFLAGS']
+        if os.environ.has_key('CFLAGS'):
+            cflags = opt + ' ' + os.environ['CFLAGS']
+            ldshared = ldshared + ' ' + os.environ['CFLAGS']
+        if os.environ.has_key('CPPFLAGS'):
+            cpp = cpp + ' ' + os.environ['CPPFLAGS']
+            cflags = cflags + ' ' + os.environ['CPPFLAGS']
+            ldshared = ldshared + ' ' + os.environ['CPPFLAGS']
+
+        cc_cmd = cc + ' ' + cflags
+        compiler.set_executables(
+            preprocessor=cpp,
+            compiler=cc_cmd,
+            compiler_so=cc_cmd + ' ' + ccshared,
+            compiler_cxx=cxx,
+            linker_so=ldshared,
+            linker_exe=cc)
+
+        compiler.shared_lib_extension = so_ext
+
+
+def get_config_h_filename():
+    """Return full pathname of installed pyconfig.h file."""
+    if python_build:
+        inc_dir = argv0_path
+    else:
+        inc_dir = get_python_inc(plat_specific=1)
+    if get_python_version() < '2.2':
+        config_h = 'config.h'
+    else:
+        # The name of the config.h file changed in 2.2
+        config_h = 'pyconfig.h'
+    return os.path.join(inc_dir, config_h)
+
+
+def get_makefile_filename():
+    """Return full pathname of installed Makefile from the Python build."""
+    if python_build:
+        return os.path.join(os.path.dirname(sys.executable), "Makefile")
+    lib_dir = get_python_lib(plat_specific=1, standard_lib=1)
+    return os.path.join(lib_dir, "config", "Makefile")
+
+
+def parse_config_h(fp, g=None):
+    """Parse a config.h-style file.
+
+    A dictionary containing name/value pairs is returned.  If an
+    optional dictionary is passed in as the second argument, it is
+    used instead of a new dictionary.
+    """
+    if g is None:
+        g = {}
+    define_rx = re.compile("#define ([A-Z][A-Za-z0-9_]+) (.*)\n")
+    undef_rx = re.compile("/[*] #undef ([A-Z][A-Za-z0-9_]+) [*]/\n")
+    #
+    while 1:
+        line = fp.readline()
+        if not line:
+            break
+        m = define_rx.match(line)
+        if m:
+            n, v = m.group(1, 2)
+            try: v = int(v)
+            except ValueError: pass
+            g[n] = v
+        else:
+            m = undef_rx.match(line)
+            if m:
+                g[m.group(1)] = 0
+    return g
+
+
+# Regexes needed for parsing Makefile (and similar syntaxes,
+# like old-style Setup files).
+_variable_rx = re.compile("([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)")
+_findvar1_rx = re.compile(r"\$\(([A-Za-z][A-Za-z0-9_]*)\)")
+_findvar2_rx = re.compile(r"\${([A-Za-z][A-Za-z0-9_]*)}")
+
+def parse_makefile(fn, g=None):
+    """Parse a Makefile-style file.
+
+    A dictionary containing name/value pairs is returned.  If an
+    optional dictionary is passed in as the second argument, it is
+    used instead of a new dictionary.
+    """
+    from distutils.text_file import TextFile
+    fp = TextFile(fn, strip_comments=1, skip_blanks=1, join_lines=1)
+
+    if g is None:
+        g = {}
+    done = {}
+    notdone = {}
+
+    while 1:
+        line = fp.readline()
+        if line is None:                # eof
+            break
+        m = _variable_rx.match(line)
+        if m:
+            n, v = m.group(1, 2)
+            v = string.strip(v)
+            if "$" in v:
+                notdone[n] = v
+            else:
+                try: v = int(v)
+                except ValueError: pass
+                done[n] = v
+
+    # do variable interpolation here
+    while notdone:
+        for name in notdone.keys():
+            value = notdone[name]
+            m = _findvar1_rx.search(value) or _findvar2_rx.search(value)
+            if m:
+                n = m.group(1)
+                found = True
+                if done.has_key(n):
+                    item = str(done[n])
+                elif notdone.has_key(n):
+                    # get it on a subsequent round
+                    found = False
+                elif os.environ.has_key(n):
+                    # do it like make: fall back to environment
+                    item = os.environ[n]
+                else:
+                    done[n] = item = ""
+                if found:
+                    after = value[m.end():]
+                    value = value[:m.start()] + item + after
+                    if "$" in after:
+                        notdone[name] = value
+                    else:
+                        try: value = int(value)
+                        except ValueError:
+                            done[name] = string.strip(value)
+                        else:
+                            done[name] = value
+                        del notdone[name]
+            else:
+                # bogus variable reference; just drop it since we can't deal
+                del notdone[name]
+
+    fp.close()
+
+    # save the results in the global dictionary
+    g.update(done)
+    return g
+
+
+def expand_makefile_vars(s, vars):
+    """Expand Makefile-style variables -- "${foo}" or "$(foo)" -- in
+    'string' according to 'vars' (a dictionary mapping variable names to
+    values).  Variables not present in 'vars' are silently expanded to the
+    empty string.  The variable values in 'vars' should not contain further
+    variable expansions; if 'vars' is the output of 'parse_makefile()',
+    you're fine.  Returns a variable-expanded version of 's'.
+    """
+
+    # This algorithm does multiple expansion, so if vars['foo'] contains
+    # "${bar}", it will expand ${foo} to ${bar}, and then expand
+    # ${bar}... and so forth.  This is fine as long as 'vars' comes from
+    # 'parse_makefile()', which takes care of such expansions eagerly,
+    # according to make's variable expansion semantics.
+
+    while 1:
+        m = _findvar1_rx.search(s) or _findvar2_rx.search(s)
+        if m:
+            (beg, end) = m.span()
+            s = s[0:beg] + vars.get(m.group(1)) + s[end:]
+        else:
+            break
+    return s
+
+
+_config_vars = None
+
+def _init_posix():
+    """Initialize the module as appropriate for POSIX systems."""
+    g = {}
+    # load the installed Makefile:
+    try:
+        filename = get_makefile_filename()
+        parse_makefile(filename, g)
+    except IOError, msg:
+        my_msg = "invalid Python installation: unable to open %s" % filename
+        if hasattr(msg, "strerror"):
+            my_msg = my_msg + " (%s)" % msg.strerror
+
+        raise DistutilsPlatformError(my_msg)
+
+    # load the installed pyconfig.h:
+    try:
+        filename = get_config_h_filename()
+        parse_config_h(file(filename), g)
+    except IOError, msg:
+        my_msg = "invalid Python installation: unable to open %s" % filename
+        if hasattr(msg, "strerror"):
+            my_msg = my_msg + " (%s)" % msg.strerror
+
+        raise DistutilsPlatformError(my_msg)
+
+    # On MacOSX we need to check the setting of the environment variable
+    # MACOSX_DEPLOYMENT_TARGET: configure bases some choices on it so
+    # it needs to be compatible.
+    # If it isn't set we set it to the configure-time value
+    if sys.platform == 'darwin' and g.has_key('MACOSX_DEPLOYMENT_TARGET'):
+        cfg_target = g['MACOSX_DEPLOYMENT_TARGET']
+        cur_target = os.getenv('MACOSX_DEPLOYMENT_TARGET', '')
+        if cur_target == '':
+            cur_target = cfg_target
+            os.putenv('MACOSX_DEPLOYMENT_TARGET', cfg_target)
+        elif map(int, cfg_target.split('.')) > map(int, cur_target.split('.')):
+            my_msg = ('$MACOSX_DEPLOYMENT_TARGET mismatch: now "%s" but "%s" during configure'
+                % (cur_target, cfg_target))
+            raise DistutilsPlatformError(my_msg)
+
+    # On AIX, there are wrong paths to the linker scripts in the Makefile
+    # -- these paths are relative to the Python source, but when installed
+    # the scripts are in another directory.
+    if python_build:
+        g['LDSHARED'] = g['BLDSHARED']
+
+    elif get_python_version() < '2.1':
+        # The following two branches are for 1.5.2 compatibility.
+        if sys.platform == 'aix4':          # what about AIX 3.x ?
+            # Linker script is in the config directory, not in Modules as the
+            # Makefile says.
+            python_lib = get_python_lib(standard_lib=1)
+            ld_so_aix = os.path.join(python_lib, 'config', 'ld_so_aix')
+            python_exp = os.path.join(python_lib, 'config', 'python.exp')
+
+            g['LDSHARED'] = "%s %s -bI:%s" % (ld_so_aix, g['CC'], python_exp)
+
+        elif sys.platform == 'beos':
+            # Linker script is in the config directory.  In the Makefile it is
+            # relative to the srcdir, which after installation no longer makes
+            # sense.
+            python_lib = get_python_lib(standard_lib=1)
+            linkerscript_path = string.split(g['LDSHARED'])[0]
+            linkerscript_name = os.path.basename(linkerscript_path)
+            linkerscript = os.path.join(python_lib, 'config',
+                                        linkerscript_name)
+
+            # XXX this isn't the right place to do this: adding the Python
+            # library to the link, if needed, should be in the "build_ext"
+            # command.  (It's also needed for non-MS compilers on Windows, and
+            # it's taken care of for them by the 'build_ext.get_libraries()'
+            # method.)
+            g['LDSHARED'] = ("%s -L%s/lib -lpython%s" %
+                             (linkerscript, PREFIX, get_python_version()))
+
+    global _config_vars
+    _config_vars = g
+
+
+def _init_nt():
+    """Initialize the module as appropriate for NT"""
+    g = {}
+    # set basic install directories
+    g['LIBDEST'] = get_python_lib(plat_specific=0, standard_lib=1)
+    g['BINLIBDEST'] = get_python_lib(plat_specific=1, standard_lib=1)
+
+    # XXX hmmm.. a normal install puts include files here
+    g['INCLUDEPY'] = get_python_inc(plat_specific=0)
+
+    g['SO'] = '.pyd'
+    g['EXE'] = ".exe"
+
+    global _config_vars
+    _config_vars = g
+
+
+def _init_mac():
+    """Initialize the module as appropriate for Macintosh systems"""
+    g = {}
+    # set basic install directories
+    g['LIBDEST'] = get_python_lib(plat_specific=0, standard_lib=1)
+    g['BINLIBDEST'] = get_python_lib(plat_specific=1, standard_lib=1)
+
+    # XXX hmmm.. a normal install puts include files here
+    g['INCLUDEPY'] = get_python_inc(plat_specific=0)
+
+    import MacOS
+    if not hasattr(MacOS, 'runtimemodel'):
+        g['SO'] = '.ppc.slb'
+    else:
+        g['SO'] = '.%s.slb' % MacOS.runtimemodel
+
+    # XXX are these used anywhere?
+    g['install_lib'] = os.path.join(EXEC_PREFIX, "Lib")
+    g['install_platlib'] = os.path.join(EXEC_PREFIX, "Mac", "Lib")
+
+    # These are used by the extension module build
+    g['srcdir'] = ':'
+    global _config_vars
+    _config_vars = g
+
+
+def _init_os2():
+    """Initialize the module as appropriate for OS/2"""
+    g = {}
+    # set basic install directories
+    g['LIBDEST'] = get_python_lib(plat_specific=0, standard_lib=1)
+    g['BINLIBDEST'] = get_python_lib(plat_specific=1, standard_lib=1)
+
+    # XXX hmmm.. a normal install puts include files here
+    g['INCLUDEPY'] = get_python_inc(plat_specific=0)
+
+    g['SO'] = '.pyd'
+    g['EXE'] = ".exe"
+
+    global _config_vars
+    _config_vars = g
+
+
+def get_config_vars(*args):
+    """With no arguments, return a dictionary of all configuration
+    variables relevant for the current platform.  Generally this includes
+    everything needed to build extensions and install both pure modules and
+    extensions.  On Unix, this means every variable defined in Python's
+    installed Makefile; on Windows and Mac OS it's a much smaller set.
+
+    With arguments, return a list of values that result from looking up
+    each argument in the configuration variable dictionary.
+    """
+    global _config_vars
+    if _config_vars is None:
+        func = globals().get("_init_" + os.name)
+        if func:
+            func()
+        else:
+            _config_vars = {}
+
+        # Normalized versions of prefix and exec_prefix are handy to have;
+        # in fact, these are the standard versions used most places in the
+        # Distutils.
+        _config_vars['prefix'] = PREFIX
+        _config_vars['exec_prefix'] = EXEC_PREFIX
+
+        if sys.platform == 'darwin':
+            kernel_version = os.uname()[2] # Kernel version (8.4.3)
+            major_version = int(kernel_version.split('.')[0])
+
+            if major_version < 8:
+                # On Mac OS X before 10.4, check if -arch and -isysroot
+                # are in CFLAGS or LDFLAGS and remove them if they are.
+                # This is needed when building extensions on a 10.3 system
+                # using a universal build of python.
+                for key in ('LDFLAGS', 'BASECFLAGS',
+                        # a number of derived variables. These need to be
+                        # patched up as well.
+                        'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'):
+
+                    flags = _config_vars[key]
+                    flags = re.sub('-arch\s+\w+\s', ' ', flags)
+                    flags = re.sub('-isysroot [^ \t]*', ' ', flags)
+                    _config_vars[key] = flags
+
+    if args:
+        vals = []
+        for name in args:
+            vals.append(_config_vars.get(name))
+        return vals
+    else:
+        return _config_vars
+
+def get_config_var(name):
+    """Return the value of a single variable using the dictionary
+    returned by 'get_config_vars()'.  Equivalent to
+    get_config_vars().get(name)
+    """
+    return get_config_vars().get(name)

Added: vendor/Python/current/Lib/distutils/tests/__init__.py
===================================================================
--- vendor/Python/current/Lib/distutils/tests/__init__.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/tests/__init__.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,35 @@
+"""Test suite for distutils.
+
+This test suite consists of a collection of test modules in the
+distutils.tests package.  Each test module has a name starting with
+'test' and contains a function test_suite().  The function is expected
+to return an initialized unittest.TestSuite instance.
+
+Tests for the command classes in the distutils.command package are
+included in distutils.tests as well, instead of using a separate
+distutils.command.tests package, since command identification is done
+by import rather than matching pre-defined names.
+
+"""
+
+import os
+import sys
+import unittest
+
+
+here = os.path.dirname(__file__)
+
+
+def test_suite():
+    suite = unittest.TestSuite()
+    for fn in os.listdir(here):
+        if fn.startswith("test") and fn.endswith(".py"):
+            modname = "distutils.tests." + fn[:-3]
+            __import__(modname)
+            module = sys.modules[modname]
+            suite.addTest(module.test_suite())
+    return suite
+
+
+if __name__ == "__main__":
+    unittest.main(defaultTest="test_suite")

Added: vendor/Python/current/Lib/distutils/tests/support.py
===================================================================
--- vendor/Python/current/Lib/distutils/tests/support.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/tests/support.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,54 @@
+"""Support code for distutils test cases."""
+
+import shutil
+import tempfile
+
+from distutils import log
+
+
+class LoggingSilencer(object):
+
+    def setUp(self):
+        super(LoggingSilencer, self).setUp()
+        self.threshold = log.set_threshold(log.FATAL)
+
+    def tearDown(self):
+        log.set_threshold(self.threshold)
+        super(LoggingSilencer, self).tearDown()
+
+
+class TempdirManager(object):
+    """Mix-in class that handles temporary directories for test cases.
+
+    This is intended to be used with unittest.TestCase.
+    """
+
+    def setUp(self):
+        super(TempdirManager, self).setUp()
+        self.tempdirs = []
+
+    def tearDown(self):
+        super(TempdirManager, self).tearDown()
+        while self.tempdirs:
+            d = self.tempdirs.pop()
+            shutil.rmtree(d)
+
+    def mkdtemp(self):
+        """Create a temporary directory that will be cleaned up.
+
+        Returns the path of the directory.
+        """
+        d = tempfile.mkdtemp()
+        self.tempdirs.append(d)
+        return d
+
+
+class DummyCommand:
+    """Class to store options for retrieval via set_undefined_options()."""
+
+    def __init__(self, **kwargs):
+        for kw, val in kwargs.items():
+            setattr(self, kw, val)
+
+    def ensure_finalized(self):
+        pass

Added: vendor/Python/current/Lib/distutils/tests/test_build_py.py
===================================================================
--- vendor/Python/current/Lib/distutils/tests/test_build_py.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/tests/test_build_py.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,61 @@
+"""Tests for distutils.command.build_py."""
+
+import os
+import unittest
+
+from distutils.command.build_py import build_py
+from distutils.core import Distribution
+
+from distutils.tests import support
+
+
+class BuildPyTestCase(support.TempdirManager,
+                      support.LoggingSilencer,
+                      unittest.TestCase):
+
+    def test_package_data(self):
+        sources = self.mkdtemp()
+        f = open(os.path.join(sources, "__init__.py"), "w")
+        f.write("# Pretend this is a package.")
+        f.close()
+        f = open(os.path.join(sources, "README.txt"), "w")
+        f.write("Info about this package")
+        f.close()
+
+        destination = self.mkdtemp()
+
+        dist = Distribution({"packages": ["pkg"],
+                             "package_dir": {"pkg": sources}})
+        # script_name need not exist, it just need to be initialized
+        dist.script_name = os.path.join(sources, "setup.py")
+        dist.command_obj["build"] = support.DummyCommand(
+            force=0,
+            build_lib=destination)
+        dist.packages = ["pkg"]
+        dist.package_data = {"pkg": ["README.txt"]}
+        dist.package_dir = {"pkg": sources}
+
+        cmd = build_py(dist)
+        cmd.compile = 1
+        cmd.ensure_finalized()
+        self.assertEqual(cmd.package_data, dist.package_data)
+
+        cmd.run()
+
+        # This makes sure the list of outputs includes byte-compiled
+        # files for Python modules but not for package data files
+        # (there shouldn't *be* byte-code files for those!).
+        #
+        self.assertEqual(len(cmd.get_outputs()), 3)
+        pkgdest = os.path.join(destination, "pkg")
+        files = os.listdir(pkgdest)
+        self.assert_("__init__.py" in files)
+        self.assert_("__init__.pyc" in files)
+        self.assert_("README.txt" in files)
+
+
+def test_suite():
+    return unittest.makeSuite(BuildPyTestCase)
+
+if __name__ == "__main__":
+    unittest.main(defaultTest="test_suite")

Added: vendor/Python/current/Lib/distutils/tests/test_build_scripts.py
===================================================================
--- vendor/Python/current/Lib/distutils/tests/test_build_scripts.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/tests/test_build_scripts.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,81 @@
+"""Tests for distutils.command.build_scripts."""
+
+import os
+import unittest
+
+from distutils.command.build_scripts import build_scripts
+from distutils.core import Distribution
+
+from distutils.tests import support
+
+
+class BuildScriptsTestCase(support.TempdirManager,
+                           support.LoggingSilencer,
+                           unittest.TestCase):
+
+    def test_default_settings(self):
+        cmd = self.get_build_scripts_cmd("/foo/bar", [])
+        self.assert_(not cmd.force)
+        self.assert_(cmd.build_dir is None)
+
+        cmd.finalize_options()
+
+        self.assert_(cmd.force)
+        self.assertEqual(cmd.build_dir, "/foo/bar")
+
+    def test_build(self):
+        source = self.mkdtemp()
+        target = self.mkdtemp()
+        expected = self.write_sample_scripts(source)
+
+        cmd = self.get_build_scripts_cmd(target,
+                                         [os.path.join(source, fn)
+                                          for fn in expected])
+        cmd.finalize_options()
+        cmd.run()
+
+        built = os.listdir(target)
+        for name in expected:
+            self.assert_(name in built)
+
+    def get_build_scripts_cmd(self, target, scripts):
+        import sys
+        dist = Distribution()
+        dist.scripts = scripts
+        dist.command_obj["build"] = support.DummyCommand(
+            build_scripts=target,
+            force=1,
+            executable=sys.executable
+            )
+        return build_scripts(dist)
+
+    def write_sample_scripts(self, dir):
+        expected = []
+        expected.append("script1.py")
+        self.write_script(dir, "script1.py",
+                          ("#! /usr/bin/env python2.3\n"
+                           "# bogus script w/ Python sh-bang\n"
+                           "pass\n"))
+        expected.append("script2.py")
+        self.write_script(dir, "script2.py",
+                          ("#!/usr/bin/python\n"
+                           "# bogus script w/ Python sh-bang\n"
+                           "pass\n"))
+        expected.append("shell.sh")
+        self.write_script(dir, "shell.sh",
+                          ("#!/bin/sh\n"
+                           "# bogus shell script w/ sh-bang\n"
+                           "exit 0\n"))
+        return expected
+
+    def write_script(self, dir, name, text):
+        f = open(os.path.join(dir, name), "w")
+        f.write(text)
+        f.close()
+
+
+def test_suite():
+    return unittest.makeSuite(BuildScriptsTestCase)
+
+if __name__ == "__main__":
+    unittest.main(defaultTest="test_suite")

Added: vendor/Python/current/Lib/distutils/tests/test_dist.py
===================================================================
--- vendor/Python/current/Lib/distutils/tests/test_dist.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/tests/test_dist.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,189 @@
+"""Tests for distutils.dist."""
+
+import distutils.cmd
+import distutils.dist
+import os
+import shutil
+import StringIO
+import sys
+import tempfile
+import unittest
+
+from test.test_support import TESTFN
+
+
+class test_dist(distutils.cmd.Command):
+    """Sample distutils extension command."""
+
+    user_options = [
+        ("sample-option=", "S", "help text"),
+        ]
+
+    def initialize_options(self):
+        self.sample_option = None
+
+
+class TestDistribution(distutils.dist.Distribution):
+    """Distribution subclasses that avoids the default search for
+    configuration files.
+
+    The ._config_files attribute must be set before
+    .parse_config_files() is called.
+    """
+
+    def find_config_files(self):
+        return self._config_files
+
+
+class DistributionTestCase(unittest.TestCase):
+
+    def setUp(self):
+        self.argv = sys.argv[:]
+        del sys.argv[1:]
+
+    def tearDown(self):
+        sys.argv[:] = self.argv
+
+    def create_distribution(self, configfiles=()):
+        d = TestDistribution()
+        d._config_files = configfiles
+        d.parse_config_files()
+        d.parse_command_line()
+        return d
+
+    def test_command_packages_unspecified(self):
+        sys.argv.append("build")
+        d = self.create_distribution()
+        self.assertEqual(d.get_command_packages(), ["distutils.command"])
+
+    def test_command_packages_cmdline(self):
+        sys.argv.extend(["--command-packages",
+                         "foo.bar,distutils.tests",
+                         "test_dist",
+                         "-Ssometext",
+                         ])
+        d = self.create_distribution()
+        # let's actually try to load our test command:
+        self.assertEqual(d.get_command_packages(),
+                         ["distutils.command", "foo.bar", "distutils.tests"])
+        cmd = d.get_command_obj("test_dist")
+        self.assert_(isinstance(cmd, test_dist))
+        self.assertEqual(cmd.sample_option, "sometext")
+
+    def test_command_packages_configfile(self):
+        sys.argv.append("build")
+        f = open(TESTFN, "w")
+        try:
+            print >>f, "[global]"
+            print >>f, "command_packages = foo.bar, splat"
+            f.close()
+            d = self.create_distribution([TESTFN])
+            self.assertEqual(d.get_command_packages(),
+                             ["distutils.command", "foo.bar", "splat"])
+
+            # ensure command line overrides config:
+            sys.argv[1:] = ["--command-packages", "spork", "build"]
+            d = self.create_distribution([TESTFN])
+            self.assertEqual(d.get_command_packages(),
+                             ["distutils.command", "spork"])
+
+            # Setting --command-packages to '' should cause the default to
+            # be used even if a config file specified something else:
+            sys.argv[1:] = ["--command-packages", "", "build"]
+            d = self.create_distribution([TESTFN])
+            self.assertEqual(d.get_command_packages(), ["distutils.command"])
+
+        finally:
+            os.unlink(TESTFN)
+
+
+class MetadataTestCase(unittest.TestCase):
+
+    def test_simple_metadata(self):
+        attrs = {"name": "package",
+                 "version": "1.0"}
+        dist = distutils.dist.Distribution(attrs)
+        meta = self.format_metadata(dist)
+        self.assert_("Metadata-Version: 1.0" in meta)
+        self.assert_("provides:" not in meta.lower())
+        self.assert_("requires:" not in meta.lower())
+        self.assert_("obsoletes:" not in meta.lower())
+
+    def test_provides(self):
+        attrs = {"name": "package",
+                 "version": "1.0",
+                 "provides": ["package", "package.sub"]}
+        dist = distutils.dist.Distribution(attrs)
+        self.assertEqual(dist.metadata.get_provides(),
+                         ["package", "package.sub"])
+        self.assertEqual(dist.get_provides(),
+                         ["package", "package.sub"])
+        meta = self.format_metadata(dist)
+        self.assert_("Metadata-Version: 1.1" in meta)
+        self.assert_("requires:" not in meta.lower())
+        self.assert_("obsoletes:" not in meta.lower())
+
+    def test_provides_illegal(self):
+        self.assertRaises(ValueError,
+                          distutils.dist.Distribution,
+                          {"name": "package",
+                           "version": "1.0",
+                           "provides": ["my.pkg (splat)"]})
+
+    def test_requires(self):
+        attrs = {"name": "package",
+                 "version": "1.0",
+                 "requires": ["other", "another (==1.0)"]}
+        dist = distutils.dist.Distribution(attrs)
+        self.assertEqual(dist.metadata.get_requires(),
+                         ["other", "another (==1.0)"])
+        self.assertEqual(dist.get_requires(),
+                         ["other", "another (==1.0)"])
+        meta = self.format_metadata(dist)
+        self.assert_("Metadata-Version: 1.1" in meta)
+        self.assert_("provides:" not in meta.lower())
+        self.assert_("Requires: other" in meta)
+        self.assert_("Requires: another (==1.0)" in meta)
+        self.assert_("obsoletes:" not in meta.lower())
+
+    def test_requires_illegal(self):
+        self.assertRaises(ValueError,
+                          distutils.dist.Distribution,
+                          {"name": "package",
+                           "version": "1.0",
+                           "requires": ["my.pkg (splat)"]})
+
+    def test_obsoletes(self):
+        attrs = {"name": "package",
+                 "version": "1.0",
+                 "obsoletes": ["other", "another (<1.0)"]}
+        dist = distutils.dist.Distribution(attrs)
+        self.assertEqual(dist.metadata.get_obsoletes(),
+                         ["other", "another (<1.0)"])
+        self.assertEqual(dist.get_obsoletes(),
+                         ["other", "another (<1.0)"])
+        meta = self.format_metadata(dist)
+        self.assert_("Metadata-Version: 1.1" in meta)
+        self.assert_("provides:" not in meta.lower())
+        self.assert_("requires:" not in meta.lower())
+        self.assert_("Obsoletes: other" in meta)
+        self.assert_("Obsoletes: another (<1.0)" in meta)
+
+    def test_obsoletes_illegal(self):
+        self.assertRaises(ValueError,
+                          distutils.dist.Distribution,
+                          {"name": "package",
+                           "version": "1.0",
+                           "obsoletes": ["my.pkg (splat)"]})
+
+    def format_metadata(self, dist):
+        sio = StringIO.StringIO()
+        dist.metadata.write_pkg_file(sio)
+        return sio.getvalue()
+
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(DistributionTestCase))
+    suite.addTest(unittest.makeSuite(MetadataTestCase))
+    return suite

Added: vendor/Python/current/Lib/distutils/tests/test_install.py
===================================================================
--- vendor/Python/current/Lib/distutils/tests/test_install.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/tests/test_install.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,55 @@
+"""Tests for distutils.command.install."""
+
+import os
+import unittest
+
+from distutils.command.install import install
+from distutils.core import Distribution
+
+from distutils.tests import support
+
+
+class InstallTestCase(support.TempdirManager, unittest.TestCase):
+
+    def test_home_installation_scheme(self):
+        # This ensure two things:
+        # - that --home generates the desired set of directory names
+        # - test --home is supported on all platforms
+        builddir = self.mkdtemp()
+        destination = os.path.join(builddir, "installation")
+
+        dist = Distribution({"name": "foopkg"})
+        # script_name need not exist, it just need to be initialized
+        dist.script_name = os.path.join(builddir, "setup.py")
+        dist.command_obj["build"] = support.DummyCommand(
+            build_base=builddir,
+            build_lib=os.path.join(builddir, "lib"),
+            )
+
+        cmd = install(dist)
+        cmd.home = destination
+        cmd.ensure_finalized()
+
+        self.assertEqual(cmd.install_base, destination)
+        self.assertEqual(cmd.install_platbase, destination)
+
+        def check_path(got, expected):
+            got = os.path.normpath(got)
+            expected = os.path.normpath(expected)
+            self.assertEqual(got, expected)
+
+        libdir = os.path.join(destination, "lib", "python")
+        check_path(cmd.install_lib, libdir)
+        check_path(cmd.install_platlib, libdir)
+        check_path(cmd.install_purelib, libdir)
+        check_path(cmd.install_headers,
+                   os.path.join(destination, "include", "python", "foopkg"))
+        check_path(cmd.install_scripts, os.path.join(destination, "bin"))
+        check_path(cmd.install_data, destination)
+
+
+def test_suite():
+    return unittest.makeSuite(InstallTestCase)
+
+if __name__ == "__main__":
+    unittest.main(defaultTest="test_suite")

Added: vendor/Python/current/Lib/distutils/tests/test_install_scripts.py
===================================================================
--- vendor/Python/current/Lib/distutils/tests/test_install_scripts.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/tests/test_install_scripts.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,79 @@
+"""Tests for distutils.command.install_scripts."""
+
+import os
+import unittest
+
+from distutils.command.install_scripts import install_scripts
+from distutils.core import Distribution
+
+from distutils.tests import support
+
+
+class InstallScriptsTestCase(support.TempdirManager,
+                             support.LoggingSilencer,
+                             unittest.TestCase):
+
+    def test_default_settings(self):
+        dist = Distribution()
+        dist.command_obj["build"] = support.DummyCommand(
+            build_scripts="/foo/bar")
+        dist.command_obj["install"] = support.DummyCommand(
+            install_scripts="/splat/funk",
+            force=1,
+            skip_build=1,
+            )
+        cmd = install_scripts(dist)
+        self.assert_(not cmd.force)
+        self.assert_(not cmd.skip_build)
+        self.assert_(cmd.build_dir is None)
+        self.assert_(cmd.install_dir is None)
+
+        cmd.finalize_options()
+
+        self.assert_(cmd.force)
+        self.assert_(cmd.skip_build)
+        self.assertEqual(cmd.build_dir, "/foo/bar")
+        self.assertEqual(cmd.install_dir, "/splat/funk")
+
+    def test_installation(self):
+        source = self.mkdtemp()
+        expected = []
+
+        def write_script(name, text):
+            expected.append(name)
+            f = open(os.path.join(source, name), "w")
+            f.write(text)
+            f.close()
+
+        write_script("script1.py", ("#! /usr/bin/env python2.3\n"
+                                    "# bogus script w/ Python sh-bang\n"
+                                    "pass\n"))
+        write_script("script2.py", ("#!/usr/bin/python\n"
+                                    "# bogus script w/ Python sh-bang\n"
+                                    "pass\n"))
+        write_script("shell.sh", ("#!/bin/sh\n"
+                                  "# bogus shell script w/ sh-bang\n"
+                                  "exit 0\n"))
+
+        target = self.mkdtemp()
+        dist = Distribution()
+        dist.command_obj["build"] = support.DummyCommand(build_scripts=source)
+        dist.command_obj["install"] = support.DummyCommand(
+            install_scripts=target,
+            force=1,
+            skip_build=1,
+            )
+        cmd = install_scripts(dist)
+        cmd.finalize_options()
+        cmd.run()
+
+        installed = os.listdir(target)
+        for name in expected:
+            self.assert_(name in installed)
+
+
+def test_suite():
+    return unittest.makeSuite(InstallScriptsTestCase)
+
+if __name__ == "__main__":
+    unittest.main(defaultTest="test_suite")

Added: vendor/Python/current/Lib/distutils/tests/test_versionpredicate.py
===================================================================
--- vendor/Python/current/Lib/distutils/tests/test_versionpredicate.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/tests/test_versionpredicate.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,9 @@
+"""Tests harness for distutils.versionpredicate.
+
+"""
+
+import distutils.versionpredicate
+import doctest
+
+def test_suite():
+    return doctest.DocTestSuite(distutils.versionpredicate)

Added: vendor/Python/current/Lib/distutils/text_file.py
===================================================================
--- vendor/Python/current/Lib/distutils/text_file.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/text_file.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,382 @@
+"""text_file
+
+provides the TextFile class, which gives an interface to text files
+that (optionally) takes care of stripping comments, ignoring blank
+lines, and joining lines with backslashes."""
+
+__revision__ = "$Id: text_file.py 29687 2002-11-14 02:25:42Z akuchling $"
+
+from types import *
+import sys, os, string
+
+
+class TextFile:
+
+    """Provides a file-like object that takes care of all the things you
+       commonly want to do when processing a text file that has some
+       line-by-line syntax: strip comments (as long as "#" is your
+       comment character), skip blank lines, join adjacent lines by
+       escaping the newline (ie. backslash at end of line), strip
+       leading and/or trailing whitespace.  All of these are optional
+       and independently controllable.
+
+       Provides a 'warn()' method so you can generate warning messages that
+       report physical line number, even if the logical line in question
+       spans multiple physical lines.  Also provides 'unreadline()' for
+       implementing line-at-a-time lookahead.
+
+       Constructor is called as:
+
+           TextFile (filename=None, file=None, **options)
+
+       It bombs (RuntimeError) if both 'filename' and 'file' are None;
+       'filename' should be a string, and 'file' a file object (or
+       something that provides 'readline()' and 'close()' methods).  It is
+       recommended that you supply at least 'filename', so that TextFile
+       can include it in warning messages.  If 'file' is not supplied,
+       TextFile creates its own using the 'open()' builtin.
+
+       The options are all boolean, and affect the value returned by
+       'readline()':
+         strip_comments [default: true]
+           strip from "#" to end-of-line, as well as any whitespace
+           leading up to the "#" -- unless it is escaped by a backslash
+         lstrip_ws [default: false]
+           strip leading whitespace from each line before returning it
+         rstrip_ws [default: true]
+           strip trailing whitespace (including line terminator!) from
+           each line before returning it
+         skip_blanks [default: true}
+           skip lines that are empty *after* stripping comments and
+           whitespace.  (If both lstrip_ws and rstrip_ws are false,
+           then some lines may consist of solely whitespace: these will
+           *not* be skipped, even if 'skip_blanks' is true.)
+         join_lines [default: false]
+           if a backslash is the last non-newline character on a line
+           after stripping comments and whitespace, join the following line
+           to it to form one "logical line"; if N consecutive lines end
+           with a backslash, then N+1 physical lines will be joined to
+           form one logical line.
+         collapse_join [default: false]
+           strip leading whitespace from lines that are joined to their
+           predecessor; only matters if (join_lines and not lstrip_ws)
+
+       Note that since 'rstrip_ws' can strip the trailing newline, the
+       semantics of 'readline()' must differ from those of the builtin file
+       object's 'readline()' method!  In particular, 'readline()' returns
+       None for end-of-file: an empty string might just be a blank line (or
+       an all-whitespace line), if 'rstrip_ws' is true but 'skip_blanks' is
+       not."""
+
+    default_options = { 'strip_comments': 1,
+                        'skip_blanks':    1,
+                        'lstrip_ws':      0,
+                        'rstrip_ws':      1,
+                        'join_lines':     0,
+                        'collapse_join':  0,
+                      }
+
+    def __init__ (self, filename=None, file=None, **options):
+        """Construct a new TextFile object.  At least one of 'filename'
+           (a string) and 'file' (a file-like object) must be supplied.
+           They keyword argument options are described above and affect
+           the values returned by 'readline()'."""
+
+        if filename is None and file is None:
+            raise RuntimeError, \
+                  "you must supply either or both of 'filename' and 'file'"
+
+        # set values for all options -- either from client option hash
+        # or fallback to default_options
+        for opt in self.default_options.keys():
+            if options.has_key (opt):
+                setattr (self, opt, options[opt])
+
+            else:
+                setattr (self, opt, self.default_options[opt])
+
+        # sanity check client option hash
+        for opt in options.keys():
+            if not self.default_options.has_key (opt):
+                raise KeyError, "invalid TextFile option '%s'" % opt
+
+        if file is None:
+            self.open (filename)
+        else:
+            self.filename = filename
+            self.file = file
+            self.current_line = 0       # assuming that file is at BOF!
+
+        # 'linebuf' is a stack of lines that will be emptied before we
+        # actually read from the file; it's only populated by an
+        # 'unreadline()' operation
+        self.linebuf = []
+
+
+    def open (self, filename):
+        """Open a new file named 'filename'.  This overrides both the
+           'filename' and 'file' arguments to the constructor."""
+
+        self.filename = filename
+        self.file = open (self.filename, 'r')
+        self.current_line = 0
+
+
+    def close (self):
+        """Close the current file and forget everything we know about it
+           (filename, current line number)."""
+
+        self.file.close ()
+        self.file = None
+        self.filename = None
+        self.current_line = None
+
+
+    def gen_error (self, msg, line=None):
+        outmsg = []
+        if line is None:
+            line = self.current_line
+        outmsg.append(self.filename + ", ")
+        if type (line) in (ListType, TupleType):
+            outmsg.append("lines %d-%d: " % tuple (line))
+        else:
+            outmsg.append("line %d: " % line)
+        outmsg.append(str(msg))
+        return string.join(outmsg, "")
+
+
+    def error (self, msg, line=None):
+        raise ValueError, "error: " + self.gen_error(msg, line)
+
+    def warn (self, msg, line=None):
+        """Print (to stderr) a warning message tied to the current logical
+           line in the current file.  If the current logical line in the
+           file spans multiple physical lines, the warning refers to the
+           whole range, eg. "lines 3-5".  If 'line' supplied, it overrides
+           the current line number; it may be a list or tuple to indicate a
+           range of physical lines, or an integer for a single physical
+           line."""
+        sys.stderr.write("warning: " + self.gen_error(msg, line) + "\n")
+
+
+    def readline (self):
+        """Read and return a single logical line from the current file (or
+           from an internal buffer if lines have previously been "unread"
+           with 'unreadline()').  If the 'join_lines' option is true, this
+           may involve reading multiple physical lines concatenated into a
+           single string.  Updates the current line number, so calling
+           'warn()' after 'readline()' emits a warning about the physical
+           line(s) just read.  Returns None on end-of-file, since the empty
+           string can occur if 'rstrip_ws' is true but 'strip_blanks' is
+           not."""
+
+        # If any "unread" lines waiting in 'linebuf', return the top
+        # one.  (We don't actually buffer read-ahead data -- lines only
+        # get put in 'linebuf' if the client explicitly does an
+        # 'unreadline()'.
+        if self.linebuf:
+            line = self.linebuf[-1]
+            del self.linebuf[-1]
+            return line
+
+        buildup_line = ''
+
+        while 1:
+            # read the line, make it None if EOF
+            line = self.file.readline()
+            if line == '': line = None
+
+            if self.strip_comments and line:
+
+                # Look for the first "#" in the line.  If none, never
+                # mind.  If we find one and it's the first character, or
+                # is not preceded by "\", then it starts a comment --
+                # strip the comment, strip whitespace before it, and
+                # carry on.  Otherwise, it's just an escaped "#", so
+                # unescape it (and any other escaped "#"'s that might be
+                # lurking in there) and otherwise leave the line alone.
+
+                pos = string.find (line, "#")
+                if pos == -1:           # no "#" -- no comments
+                    pass
+
+                # It's definitely a comment -- either "#" is the first
+                # character, or it's elsewhere and unescaped.
+                elif pos == 0 or line[pos-1] != "\\":
+                    # Have to preserve the trailing newline, because it's
+                    # the job of a later step (rstrip_ws) to remove it --
+                    # and if rstrip_ws is false, we'd better preserve it!
+                    # (NB. this means that if the final line is all comment
+                    # and has no trailing newline, we will think that it's
+                    # EOF; I think that's OK.)
+                    eol = (line[-1] == '\n') and '\n' or ''
+                    line = line[0:pos] + eol
+
+                    # If all that's left is whitespace, then skip line
+                    # *now*, before we try to join it to 'buildup_line' --
+                    # that way constructs like
+                    #   hello \\
+                    #   # comment that should be ignored
+                    #   there
+                    # result in "hello there".
+                    if string.strip(line) == "":
+                        continue
+
+                else:                   # it's an escaped "#"
+                    line = string.replace (line, "\\#", "#")
+
+
+            # did previous line end with a backslash? then accumulate
+            if self.join_lines and buildup_line:
+                # oops: end of file
+                if line is None:
+                    self.warn ("continuation line immediately precedes "
+                               "end-of-file")
+                    return buildup_line
+
+                if self.collapse_join:
+                    line = string.lstrip (line)
+                line = buildup_line + line
+
+                # careful: pay attention to line number when incrementing it
+                if type (self.current_line) is ListType:
+                    self.current_line[1] = self.current_line[1] + 1
+                else:
+                    self.current_line = [self.current_line,
+                                         self.current_line+1]
+            # just an ordinary line, read it as usual
+            else:
+                if line is None:        # eof
+                    return None
+
+                # still have to be careful about incrementing the line number!
+                if type (self.current_line) is ListType:
+                    self.current_line = self.current_line[1] + 1
+                else:
+                    self.current_line = self.current_line + 1
+
+
+            # strip whitespace however the client wants (leading and
+            # trailing, or one or the other, or neither)
+            if self.lstrip_ws and self.rstrip_ws:
+                line = string.strip (line)
+            elif self.lstrip_ws:
+                line = string.lstrip (line)
+            elif self.rstrip_ws:
+                line = string.rstrip (line)
+
+            # blank line (whether we rstrip'ed or not)? skip to next line
+            # if appropriate
+            if (line == '' or line == '\n') and self.skip_blanks:
+                continue
+
+            if self.join_lines:
+                if line[-1] == '\\':
+                    buildup_line = line[:-1]
+                    continue
+
+                if line[-2:] == '\\\n':
+                    buildup_line = line[0:-2] + '\n'
+                    continue
+
+            # well, I guess there's some actual content there: return it
+            return line
+
+    # readline ()
+
+
+    def readlines (self):
+        """Read and return the list of all logical lines remaining in the
+           current file."""
+
+        lines = []
+        while 1:
+            line = self.readline()
+            if line is None:
+                return lines
+            lines.append (line)
+
+
+    def unreadline (self, line):
+        """Push 'line' (a string) onto an internal buffer that will be
+           checked by future 'readline()' calls.  Handy for implementing
+           a parser with line-at-a-time lookahead."""
+
+        self.linebuf.append (line)
+
+
+if __name__ == "__main__":
+    test_data = """# test file
+
+line 3 \\
+# intervening comment
+  continues on next line
+"""
+    # result 1: no fancy options
+    result1 = map (lambda x: x + "\n", string.split (test_data, "\n")[0:-1])
+
+    # result 2: just strip comments
+    result2 = ["\n",
+               "line 3 \\\n",
+               "  continues on next line\n"]
+
+    # result 3: just strip blank lines
+    result3 = ["# test file\n",
+               "line 3 \\\n",
+               "# intervening comment\n",
+               "  continues on next line\n"]
+
+    # result 4: default, strip comments, blank lines, and trailing whitespace
+    result4 = ["line 3 \\",
+               "  continues on next line"]
+
+    # result 5: strip comments and blanks, plus join lines (but don't
+    # "collapse" joined lines
+    result5 = ["line 3   continues on next line"]
+
+    # result 6: strip comments and blanks, plus join lines (and
+    # "collapse" joined lines
+    result6 = ["line 3 continues on next line"]
+
+    def test_input (count, description, file, expected_result):
+        result = file.readlines ()
+        # result = string.join (result, '')
+        if result == expected_result:
+            print "ok %d (%s)" % (count, description)
+        else:
+            print "not ok %d (%s):" % (count, description)
+            print "** expected:"
+            print expected_result
+            print "** received:"
+            print result
+
+
+    filename = "test.txt"
+    out_file = open (filename, "w")
+    out_file.write (test_data)
+    out_file.close ()
+
+    in_file = TextFile (filename, strip_comments=0, skip_blanks=0,
+                        lstrip_ws=0, rstrip_ws=0)
+    test_input (1, "no processing", in_file, result1)
+
+    in_file = TextFile (filename, strip_comments=1, skip_blanks=0,
+                        lstrip_ws=0, rstrip_ws=0)
+    test_input (2, "strip comments", in_file, result2)
+
+    in_file = TextFile (filename, strip_comments=0, skip_blanks=1,
+                        lstrip_ws=0, rstrip_ws=0)
+    test_input (3, "strip blanks", in_file, result3)
+
+    in_file = TextFile (filename)
+    test_input (4, "default processing", in_file, result4)
+
+    in_file = TextFile (filename, strip_comments=1, skip_blanks=1,
+                        join_lines=1, rstrip_ws=1)
+    test_input (5, "join lines without collapsing", in_file, result5)
+
+    in_file = TextFile (filename, strip_comments=1, skip_blanks=1,
+                        join_lines=1, rstrip_ws=1, collapse_join=1)
+    test_input (6, "join lines with collapsing", in_file, result6)
+
+    os.remove (filename)

Added: vendor/Python/current/Lib/distutils/unixccompiler.py
===================================================================
--- vendor/Python/current/Lib/distutils/unixccompiler.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/unixccompiler.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,315 @@
+"""distutils.unixccompiler
+
+Contains the UnixCCompiler class, a subclass of CCompiler that handles
+the "typical" Unix-style command-line C compiler:
+  * macros defined with -Dname[=value]
+  * macros undefined with -Uname
+  * include search directories specified with -Idir
+  * libraries specified with -lllib
+  * library search directories specified with -Ldir
+  * compile handled by 'cc' (or similar) executable with -c option:
+    compiles .c to .o
+  * link static library handled by 'ar' command (possibly with 'ranlib')
+  * link shared library handled by 'cc -shared'
+"""
+
+__revision__ = "$Id: unixccompiler.py 52237 2006-10-08 17:52:37Z ronald.oussoren $"
+
+import os, sys
+from types import StringType, NoneType
+from copy import copy
+
+from distutils import sysconfig
+from distutils.dep_util import newer
+from distutils.ccompiler import \
+     CCompiler, gen_preprocess_options, gen_lib_options
+from distutils.errors import \
+     DistutilsExecError, CompileError, LibError, LinkError
+from distutils import log
+
+# XXX Things not currently handled:
+#   * optimization/debug/warning flags; we just use whatever's in Python's
+#     Makefile and live with it.  Is this adequate?  If not, we might
+#     have to have a bunch of subclasses GNUCCompiler, SGICCompiler,
+#     SunCCompiler, and I suspect down that road lies madness.
+#   * even if we don't know a warning flag from an optimization flag,
+#     we need some way for outsiders to feed preprocessor/compiler/linker
+#     flags in to us -- eg. a sysadmin might want to mandate certain flags
+#     via a site config file, or a user might want to set something for
+#     compiling this module distribution only via the setup.py command
+#     line, whatever.  As long as these options come from something on the
+#     current system, they can be as system-dependent as they like, and we
+#     should just happily stuff them into the preprocessor/compiler/linker
+#     options and carry on.
+
+def _darwin_compiler_fixup(compiler_so, cc_args):
+    """
+    This function will strip '-isysroot PATH' and '-arch ARCH' from the
+    compile flags if the user has specified one them in extra_compile_flags.
+
+    This is needed because '-arch ARCH' adds another architecture to the
+    build, without a way to remove an architecture. Furthermore GCC will
+    barf if multiple '-isysroot' arguments are present.
+    """
+    stripArch = stripSysroot = 0
+
+    compiler_so = list(compiler_so)
+    kernel_version = os.uname()[2] # 8.4.3
+    major_version = int(kernel_version.split('.')[0])
+
+    if major_version < 8:
+        # OSX before 10.4.0, these don't support -arch and -isysroot at
+        # all.
+        stripArch = stripSysroot = True
+    else:
+        stripArch = '-arch' in cc_args
+        stripSysroot = '-isysroot' in cc_args
+
+    if stripArch:
+        while 1:
+            try:
+                index = compiler_so.index('-arch')
+                # Strip this argument and the next one:
+                del compiler_so[index:index+2]
+            except ValueError:
+                break
+
+    if stripSysroot:
+        try:
+            index = compiler_so.index('-isysroot')
+            # Strip this argument and the next one:
+            del compiler_so[index:index+2]
+        except ValueError:
+            pass
+
+    # Check if the SDK that is used during compilation actually exists, 
+    # the universal build requires the usage of a universal SDK and not all
+    # users have that installed by default.
+    sysroot = None
+    if '-isysroot' in cc_args:
+        idx = cc_args.index('-isysroot')
+        sysroot = cc_args[idx+1]
+    elif '-isysroot' in compiler_so:
+        idx = compiler_so.index('-isysroot')
+        sysroot = compiler_so[idx+1]
+
+    if sysroot and not os.path.isdir(sysroot):
+        log.warn("Compiling with an SDK that doesn't seem to exist: %s",
+                sysroot)
+        log.warn("Please check your Xcode installation")
+
+    return compiler_so
+
+class UnixCCompiler(CCompiler):
+
+    compiler_type = 'unix'
+
+    # These are used by CCompiler in two places: the constructor sets
+    # instance attributes 'preprocessor', 'compiler', etc. from them, and
+    # 'set_executable()' allows any of these to be set.  The defaults here
+    # are pretty generic; they will probably have to be set by an outsider
+    # (eg. using information discovered by the sysconfig about building
+    # Python extensions).
+    executables = {'preprocessor' : None,
+                   'compiler'     : ["cc"],
+                   'compiler_so'  : ["cc"],
+                   'compiler_cxx' : ["cc"],
+                   'linker_so'    : ["cc", "-shared"],
+                   'linker_exe'   : ["cc"],
+                   'archiver'     : ["ar", "-cr"],
+                   'ranlib'       : None,
+                  }
+
+    if sys.platform[:6] == "darwin":
+        executables['ranlib'] = ["ranlib"]
+
+    # Needed for the filename generation methods provided by the base
+    # class, CCompiler.  NB. whoever instantiates/uses a particular
+    # UnixCCompiler instance should set 'shared_lib_ext' -- we set a
+    # reasonable common default here, but it's not necessarily used on all
+    # Unices!
+
+    src_extensions = [".c",".C",".cc",".cxx",".cpp",".m"]
+    obj_extension = ".o"
+    static_lib_extension = ".a"
+    shared_lib_extension = ".so"
+    dylib_lib_extension = ".dylib"
+    static_lib_format = shared_lib_format = dylib_lib_format = "lib%s%s"
+    if sys.platform == "cygwin":
+        exe_extension = ".exe"
+
+    def preprocess(self, source,
+                   output_file=None, macros=None, include_dirs=None,
+                   extra_preargs=None, extra_postargs=None):
+        ignore, macros, include_dirs = \
+            self._fix_compile_args(None, macros, include_dirs)
+        pp_opts = gen_preprocess_options(macros, include_dirs)
+        pp_args = self.preprocessor + pp_opts
+        if output_file:
+            pp_args.extend(['-o', output_file])
+        if extra_preargs:
+            pp_args[:0] = extra_preargs
+        if extra_postargs:
+            pp_args.extend(extra_postargs)
+        pp_args.append(source)
+
+        # We need to preprocess: either we're being forced to, or we're
+        # generating output to stdout, or there's a target output file and
+        # the source file is newer than the target (or the target doesn't
+        # exist).
+        if self.force or output_file is None or newer(source, output_file):
+            if output_file:
+                self.mkpath(os.path.dirname(output_file))
+            try:
+                self.spawn(pp_args)
+            except DistutilsExecError, msg:
+                raise CompileError, msg
+
+    def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts):
+        compiler_so = self.compiler_so
+        if sys.platform == 'darwin':
+            compiler_so = _darwin_compiler_fixup(compiler_so, cc_args + extra_postargs)
+        try:
+            self.spawn(compiler_so + cc_args + [src, '-o', obj] +
+                       extra_postargs)
+        except DistutilsExecError, msg:
+            raise CompileError, msg
+
+    def create_static_lib(self, objects, output_libname,
+                          output_dir=None, debug=0, target_lang=None):
+        objects, output_dir = self._fix_object_args(objects, output_dir)
+
+        output_filename = \
+            self.library_filename(output_libname, output_dir=output_dir)
+
+        if self._need_link(objects, output_filename):
+            self.mkpath(os.path.dirname(output_filename))
+            self.spawn(self.archiver +
+                       [output_filename] +
+                       objects + self.objects)
+
+            # Not many Unices required ranlib anymore -- SunOS 4.x is, I
+            # think the only major Unix that does.  Maybe we need some
+            # platform intelligence here to skip ranlib if it's not
+            # needed -- or maybe Python's configure script took care of
+            # it for us, hence the check for leading colon.
+            if self.ranlib:
+                try:
+                    self.spawn(self.ranlib + [output_filename])
+                except DistutilsExecError, msg:
+                    raise LibError, msg
+        else:
+            log.debug("skipping %s (up-to-date)", output_filename)
+
+    def link(self, target_desc, objects,
+             output_filename, output_dir=None, libraries=None,
+             library_dirs=None, runtime_library_dirs=None,
+             export_symbols=None, debug=0, extra_preargs=None,
+             extra_postargs=None, build_temp=None, target_lang=None):
+        objects, output_dir = self._fix_object_args(objects, output_dir)
+        libraries, library_dirs, runtime_library_dirs = \
+            self._fix_lib_args(libraries, library_dirs, runtime_library_dirs)
+
+        lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs,
+                                   libraries)
+        if type(output_dir) not in (StringType, NoneType):
+            raise TypeError, "'output_dir' must be a string or None"
+        if output_dir is not None:
+            output_filename = os.path.join(output_dir, output_filename)
+
+        if self._need_link(objects, output_filename):
+            ld_args = (objects + self.objects +
+                       lib_opts + ['-o', output_filename])
+            if debug:
+                ld_args[:0] = ['-g']
+            if extra_preargs:
+                ld_args[:0] = extra_preargs
+            if extra_postargs:
+                ld_args.extend(extra_postargs)
+            self.mkpath(os.path.dirname(output_filename))
+            try:
+                if target_desc == CCompiler.EXECUTABLE:
+                    linker = self.linker_exe[:]
+                else:
+                    linker = self.linker_so[:]
+                if target_lang == "c++" and self.compiler_cxx:
+                    # skip over environment variable settings if /usr/bin/env
+                    # is used to set up the linker's environment.
+                    # This is needed on OSX. Note: this assumes that the
+                    # normal and C++ compiler have the same environment
+                    # settings.
+                    i = 0
+                    if os.path.basename(linker[0]) == "env":
+                        i = 1
+                        while '=' in linker[i]:
+                            i = i + 1
+
+                    linker[i] = self.compiler_cxx[i]
+
+                if sys.platform == 'darwin':
+                    linker = _darwin_compiler_fixup(linker, ld_args)
+
+                self.spawn(linker + ld_args)
+            except DistutilsExecError, msg:
+                raise LinkError, msg
+        else:
+            log.debug("skipping %s (up-to-date)", output_filename)
+
+    # -- Miscellaneous methods -----------------------------------------
+    # These are all used by the 'gen_lib_options() function, in
+    # ccompiler.py.
+
+    def library_dir_option(self, dir):
+        return "-L" + dir
+
+    def runtime_library_dir_option(self, dir):
+        # XXX Hackish, at the very least.  See Python bug #445902:
+        # http://sourceforge.net/tracker/index.php
+        #   ?func=detail&aid=445902&group_id=5470&atid=105470
+        # Linkers on different platforms need different options to
+        # specify that directories need to be added to the list of
+        # directories searched for dependencies when a dynamic library
+        # is sought.  GCC has to be told to pass the -R option through
+        # to the linker, whereas other compilers just know this.
+        # Other compilers may need something slightly different.  At
+        # this time, there's no way to determine this information from
+        # the configuration data stored in the Python installation, so
+        # we use this hack.
+        compiler = os.path.basename(sysconfig.get_config_var("CC"))
+        if sys.platform[:6] == "darwin":
+            # MacOSX's linker doesn't understand the -R flag at all
+            return "-L" + dir
+        elif sys.platform[:5] == "hp-ux":
+            return "+s -L" + dir
+        elif sys.platform[:7] == "irix646" or sys.platform[:6] == "osf1V5":
+            return ["-rpath", dir]
+        elif compiler[:3] == "gcc" or compiler[:3] == "g++":
+            return "-Wl,-R" + dir
+        else:
+            return "-R" + dir
+
+    def library_option(self, lib):
+        return "-l" + lib
+
+    def find_library_file(self, dirs, lib, debug=0):
+        shared_f = self.library_filename(lib, lib_type='shared')
+        dylib_f = self.library_filename(lib, lib_type='dylib')
+        static_f = self.library_filename(lib, lib_type='static')
+
+        for dir in dirs:
+            shared = os.path.join(dir, shared_f)
+            dylib = os.path.join(dir, dylib_f)
+            static = os.path.join(dir, static_f)
+            # We're second-guessing the linker here, with not much hard
+            # data to go on: GCC seems to prefer the shared library, so I'm
+            # assuming that *all* Unix C compilers do.  And of course I'm
+            # ignoring even GCC's "-static" option.  So sue me.
+            if os.path.exists(dylib):
+                return dylib
+            elif os.path.exists(shared):
+                return shared
+            elif os.path.exists(static):
+                return static
+
+        # Oops, didn't find it in *any* of 'dirs'
+        return None

Added: vendor/Python/current/Lib/distutils/util.py
===================================================================
--- vendor/Python/current/Lib/distutils/util.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/util.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,513 @@
+"""distutils.util
+
+Miscellaneous utility functions -- anything that doesn't fit into
+one of the other *util.py modules.
+"""
+
+__revision__ = "$Id: util.py 46157 2006-05-23 21:54:23Z tim.peters $"
+
+import sys, os, string, re
+from distutils.errors import DistutilsPlatformError
+from distutils.dep_util import newer
+from distutils.spawn import spawn
+from distutils import log
+
+def get_platform ():
+    """Return a string that identifies the current platform.  This is used
+    mainly to distinguish platform-specific build directories and
+    platform-specific built distributions.  Typically includes the OS name
+    and version and the architecture (as supplied by 'os.uname()'),
+    although the exact information included depends on the OS; eg. for IRIX
+    the architecture isn't particularly important (IRIX only runs on SGI
+    hardware), but for Linux the kernel version isn't particularly
+    important.
+
+    Examples of returned values:
+       linux-i586
+       linux-alpha (?)
+       solaris-2.6-sun4u
+       irix-5.3
+       irix64-6.2
+
+    For non-POSIX platforms, currently just returns 'sys.platform'.
+    """
+    if os.name != "posix" or not hasattr(os, 'uname'):
+        # XXX what about the architecture? NT is Intel or Alpha,
+        # Mac OS is M68k or PPC, etc.
+        return sys.platform
+
+    # Try to distinguish various flavours of Unix
+
+    (osname, host, release, version, machine) = os.uname()
+
+    # Convert the OS name to lowercase, remove '/' characters
+    # (to accommodate BSD/OS), and translate spaces (for "Power Macintosh")
+    osname = string.lower(osname)
+    osname = string.replace(osname, '/', '')
+    machine = string.replace(machine, ' ', '_')
+    machine = string.replace(machine, '/', '-')
+
+    if osname[:5] == "linux":
+        # At least on Linux/Intel, 'machine' is the processor --
+        # i386, etc.
+        # XXX what about Alpha, SPARC, etc?
+        return  "%s-%s" % (osname, machine)
+    elif osname[:5] == "sunos":
+        if release[0] >= "5":           # SunOS 5 == Solaris 2
+            osname = "solaris"
+            release = "%d.%s" % (int(release[0]) - 3, release[2:])
+        # fall through to standard osname-release-machine representation
+    elif osname[:4] == "irix":              # could be "irix64"!
+        return "%s-%s" % (osname, release)
+    elif osname[:3] == "aix":
+        return "%s-%s.%s" % (osname, version, release)
+    elif osname[:6] == "cygwin":
+        osname = "cygwin"
+        rel_re = re.compile (r'[\d.]+')
+        m = rel_re.match(release)
+        if m:
+            release = m.group()
+    elif osname[:6] == "darwin":
+        #
+        # For our purposes, we'll assume that the system version from
+        # distutils' perspective is what MACOSX_DEPLOYMENT_TARGET is set
+        # to. This makes the compatibility story a bit more sane because the
+        # machine is going to compile and link as if it were
+        # MACOSX_DEPLOYMENT_TARGET.
+        from distutils.sysconfig import get_config_vars
+        cfgvars = get_config_vars()
+
+        macver = os.environ.get('MACOSX_DEPLOYMENT_TARGET')
+        if not macver:
+            macver = cfgvars.get('MACOSX_DEPLOYMENT_TARGET')
+
+        if not macver:
+            # Get the system version. Reading this plist is a documented
+            # way to get the system version (see the documentation for
+            # the Gestalt Manager)
+            try:
+                f = open('/System/Library/CoreServices/SystemVersion.plist')
+            except IOError:
+                # We're on a plain darwin box, fall back to the default
+                # behaviour.
+                pass
+            else:
+                m = re.search(
+                        r'<key>ProductUserVisibleVersion</key>\s*' +
+                        r'<string>(.*?)</string>', f.read())
+                f.close()
+                if m is not None:
+                    macver = '.'.join(m.group(1).split('.')[:2])
+                # else: fall back to the default behaviour
+
+        if macver:
+            from distutils.sysconfig import get_config_vars
+            release = macver
+            osname = "macosx"
+
+
+            if (release + '.') < '10.4.' and \
+                    get_config_vars().get('UNIVERSALSDK', '').strip():
+                # The universal build will build fat binaries, but not on
+                # systems before 10.4
+                machine = 'fat'
+
+            elif machine in ('PowerPC', 'Power_Macintosh'):
+                # Pick a sane name for the PPC architecture.
+                machine = 'ppc'
+
+    return "%s-%s-%s" % (osname, release, machine)
+
+# get_platform ()
+
+
+def convert_path (pathname):
+    """Return 'pathname' as a name that will work on the native filesystem,
+    i.e. split it on '/' and put it back together again using the current
+    directory separator.  Needed because filenames in the setup script are
+    always supplied in Unix style, and have to be converted to the local
+    convention before we can actually use them in the filesystem.  Raises
+    ValueError on non-Unix-ish systems if 'pathname' either starts or
+    ends with a slash.
+    """
+    if os.sep == '/':
+        return pathname
+    if not pathname:
+        return pathname
+    if pathname[0] == '/':
+        raise ValueError, "path '%s' cannot be absolute" % pathname
+    if pathname[-1] == '/':
+        raise ValueError, "path '%s' cannot end with '/'" % pathname
+
+    paths = string.split(pathname, '/')
+    while '.' in paths:
+        paths.remove('.')
+    if not paths:
+        return os.curdir
+    return apply(os.path.join, paths)
+
+# convert_path ()
+
+
+def change_root (new_root, pathname):
+    """Return 'pathname' with 'new_root' prepended.  If 'pathname' is
+    relative, this is equivalent to "os.path.join(new_root,pathname)".
+    Otherwise, it requires making 'pathname' relative and then joining the
+    two, which is tricky on DOS/Windows and Mac OS.
+    """
+    if os.name == 'posix':
+        if not os.path.isabs(pathname):
+            return os.path.join(new_root, pathname)
+        else:
+            return os.path.join(new_root, pathname[1:])
+
+    elif os.name == 'nt':
+        (drive, path) = os.path.splitdrive(pathname)
+        if path[0] == '\\':
+            path = path[1:]
+        return os.path.join(new_root, path)
+
+    elif os.name == 'os2':
+        (drive, path) = os.path.splitdrive(pathname)
+        if path[0] == os.sep:
+            path = path[1:]
+        return os.path.join(new_root, path)
+
+    elif os.name == 'mac':
+        if not os.path.isabs(pathname):
+            return os.path.join(new_root, pathname)
+        else:
+            # Chop off volume name from start of path
+            elements = string.split(pathname, ":", 1)
+            pathname = ":" + elements[1]
+            return os.path.join(new_root, pathname)
+
+    else:
+        raise DistutilsPlatformError, \
+              "nothing known about platform '%s'" % os.name
+
+
+_environ_checked = 0
+def check_environ ():
+    """Ensure that 'os.environ' has all the environment variables we
+    guarantee that users can use in config files, command-line options,
+    etc.  Currently this includes:
+      HOME - user's home directory (Unix only)
+      PLAT - description of the current platform, including hardware
+             and OS (see 'get_platform()')
+    """
+    global _environ_checked
+    if _environ_checked:
+        return
+
+    if os.name == 'posix' and not os.environ.has_key('HOME'):
+        import pwd
+        os.environ['HOME'] = pwd.getpwuid(os.getuid())[5]
+
+    if not os.environ.has_key('PLAT'):
+        os.environ['PLAT'] = get_platform()
+
+    _environ_checked = 1
+
+
+def subst_vars (s, local_vars):
+    """Perform shell/Perl-style variable substitution on 'string'.  Every
+    occurrence of '$' followed by a name is considered a variable, and
+    variable is substituted by the value found in the 'local_vars'
+    dictionary, or in 'os.environ' if it's not in 'local_vars'.
+    'os.environ' is first checked/augmented to guarantee that it contains
+    certain values: see 'check_environ()'.  Raise ValueError for any
+    variables not found in either 'local_vars' or 'os.environ'.
+    """
+    check_environ()
+    def _subst (match, local_vars=local_vars):
+        var_name = match.group(1)
+        if local_vars.has_key(var_name):
+            return str(local_vars[var_name])
+        else:
+            return os.environ[var_name]
+
+    try:
+        return re.sub(r'\$([a-zA-Z_][a-zA-Z_0-9]*)', _subst, s)
+    except KeyError, var:
+        raise ValueError, "invalid variable '$%s'" % var
+
+# subst_vars ()
+
+
+def grok_environment_error (exc, prefix="error: "):
+    """Generate a useful error message from an EnvironmentError (IOError or
+    OSError) exception object.  Handles Python 1.5.1 and 1.5.2 styles, and
+    does what it can to deal with exception objects that don't have a
+    filename (which happens when the error is due to a two-file operation,
+    such as 'rename()' or 'link()'.  Returns the error message as a string
+    prefixed with 'prefix'.
+    """
+    # check for Python 1.5.2-style {IO,OS}Error exception objects
+    if hasattr(exc, 'filename') and hasattr(exc, 'strerror'):
+        if exc.filename:
+            error = prefix + "%s: %s" % (exc.filename, exc.strerror)
+        else:
+            # two-argument functions in posix module don't
+            # include the filename in the exception object!
+            error = prefix + "%s" % exc.strerror
+    else:
+        error = prefix + str(exc[-1])
+
+    return error
+
+
+# Needed by 'split_quoted()'
+_wordchars_re = _squote_re = _dquote_re = None
+def _init_regex():
+    global _wordchars_re, _squote_re, _dquote_re
+    _wordchars_re = re.compile(r'[^\\\'\"%s ]*' % string.whitespace)
+    _squote_re = re.compile(r"'(?:[^'\\]|\\.)*'")
+    _dquote_re = re.compile(r'"(?:[^"\\]|\\.)*"')
+
+def split_quoted (s):
+    """Split a string up according to Unix shell-like rules for quotes and
+    backslashes.  In short: words are delimited by spaces, as long as those
+    spaces are not escaped by a backslash, or inside a quoted string.
+    Single and double quotes are equivalent, and the quote characters can
+    be backslash-escaped.  The backslash is stripped from any two-character
+    escape sequence, leaving only the escaped character.  The quote
+    characters are stripped from any quoted string.  Returns a list of
+    words.
+    """
+
+    # This is a nice algorithm for splitting up a single string, since it
+    # doesn't require character-by-character examination.  It was a little
+    # bit of a brain-bender to get it working right, though...
+    if _wordchars_re is None: _init_regex()
+
+    s = string.strip(s)
+    words = []
+    pos = 0
+
+    while s:
+        m = _wordchars_re.match(s, pos)
+        end = m.end()
+        if end == len(s):
+            words.append(s[:end])
+            break
+
+        if s[end] in string.whitespace: # unescaped, unquoted whitespace: now
+            words.append(s[:end])       # we definitely have a word delimiter
+            s = string.lstrip(s[end:])
+            pos = 0
+
+        elif s[end] == '\\':            # preserve whatever is being escaped;
+                                        # will become part of the current word
+            s = s[:end] + s[end+1:]
+            pos = end+1
+
+        else:
+            if s[end] == "'":           # slurp singly-quoted string
+                m = _squote_re.match(s, end)
+            elif s[end] == '"':         # slurp doubly-quoted string
+                m = _dquote_re.match(s, end)
+            else:
+                raise RuntimeError, \
+                      "this can't happen (bad char '%c')" % s[end]
+
+            if m is None:
+                raise ValueError, \
+                      "bad string (mismatched %s quotes?)" % s[end]
+
+            (beg, end) = m.span()
+            s = s[:beg] + s[beg+1:end-1] + s[end:]
+            pos = m.end() - 2
+
+        if pos >= len(s):
+            words.append(s)
+            break
+
+    return words
+
+# split_quoted ()
+
+
+def execute (func, args, msg=None, verbose=0, dry_run=0):
+    """Perform some action that affects the outside world (eg.  by
+    writing to the filesystem).  Such actions are special because they
+    are disabled by the 'dry_run' flag.  This method takes care of all
+    that bureaucracy for you; all you have to do is supply the
+    function to call and an argument tuple for it (to embody the
+    "external action" being performed), and an optional message to
+    print.
+    """
+    if msg is None:
+        msg = "%s%r" % (func.__name__, args)
+        if msg[-2:] == ',)':        # correct for singleton tuple
+            msg = msg[0:-2] + ')'
+
+    log.info(msg)
+    if not dry_run:
+        apply(func, args)
+
+
+def strtobool (val):
+    """Convert a string representation of truth to true (1) or false (0).
+
+    True values are 'y', 'yes', 't', 'true', 'on', and '1'; false values
+    are 'n', 'no', 'f', 'false', 'off', and '0'.  Raises ValueError if
+    'val' is anything else.
+    """
+    val = string.lower(val)
+    if val in ('y', 'yes', 't', 'true', 'on', '1'):
+        return 1
+    elif val in ('n', 'no', 'f', 'false', 'off', '0'):
+        return 0
+    else:
+        raise ValueError, "invalid truth value %r" % (val,)
+
+
+def byte_compile (py_files,
+                  optimize=0, force=0,
+                  prefix=None, base_dir=None,
+                  verbose=1, dry_run=0,
+                  direct=None):
+    """Byte-compile a collection of Python source files to either .pyc
+    or .pyo files in the same directory.  'py_files' is a list of files
+    to compile; any files that don't end in ".py" are silently skipped.
+    'optimize' must be one of the following:
+      0 - don't optimize (generate .pyc)
+      1 - normal optimization (like "python -O")
+      2 - extra optimization (like "python -OO")
+    If 'force' is true, all files are recompiled regardless of
+    timestamps.
+
+    The source filename encoded in each bytecode file defaults to the
+    filenames listed in 'py_files'; you can modify these with 'prefix' and
+    'basedir'.  'prefix' is a string that will be stripped off of each
+    source filename, and 'base_dir' is a directory name that will be
+    prepended (after 'prefix' is stripped).  You can supply either or both
+    (or neither) of 'prefix' and 'base_dir', as you wish.
+
+    If 'dry_run' is true, doesn't actually do anything that would
+    affect the filesystem.
+
+    Byte-compilation is either done directly in this interpreter process
+    with the standard py_compile module, or indirectly by writing a
+    temporary script and executing it.  Normally, you should let
+    'byte_compile()' figure out to use direct compilation or not (see
+    the source for details).  The 'direct' flag is used by the script
+    generated in indirect mode; unless you know what you're doing, leave
+    it set to None.
+    """
+
+    # First, if the caller didn't force us into direct or indirect mode,
+    # figure out which mode we should be in.  We take a conservative
+    # approach: choose direct mode *only* if the current interpreter is
+    # in debug mode and optimize is 0.  If we're not in debug mode (-O
+    # or -OO), we don't know which level of optimization this
+    # interpreter is running with, so we can't do direct
+    # byte-compilation and be certain that it's the right thing.  Thus,
+    # always compile indirectly if the current interpreter is in either
+    # optimize mode, or if either optimization level was requested by
+    # the caller.
+    if direct is None:
+        direct = (__debug__ and optimize == 0)
+
+    # "Indirect" byte-compilation: write a temporary script and then
+    # run it with the appropriate flags.
+    if not direct:
+        try:
+            from tempfile import mkstemp
+            (script_fd, script_name) = mkstemp(".py")
+        except ImportError:
+            from tempfile import mktemp
+            (script_fd, script_name) = None, mktemp(".py")
+        log.info("writing byte-compilation script '%s'", script_name)
+        if not dry_run:
+            if script_fd is not None:
+                script = os.fdopen(script_fd, "w")
+            else:
+                script = open(script_name, "w")
+
+            script.write("""\
+from distutils.util import byte_compile
+files = [
+""")
+
+            # XXX would be nice to write absolute filenames, just for
+            # safety's sake (script should be more robust in the face of
+            # chdir'ing before running it).  But this requires abspath'ing
+            # 'prefix' as well, and that breaks the hack in build_lib's
+            # 'byte_compile()' method that carefully tacks on a trailing
+            # slash (os.sep really) to make sure the prefix here is "just
+            # right".  This whole prefix business is rather delicate -- the
+            # problem is that it's really a directory, but I'm treating it
+            # as a dumb string, so trailing slashes and so forth matter.
+
+            #py_files = map(os.path.abspath, py_files)
+            #if prefix:
+            #    prefix = os.path.abspath(prefix)
+
+            script.write(string.join(map(repr, py_files), ",\n") + "]\n")
+            script.write("""
+byte_compile(files, optimize=%r, force=%r,
+             prefix=%r, base_dir=%r,
+             verbose=%r, dry_run=0,
+             direct=1)
+""" % (optimize, force, prefix, base_dir, verbose))
+
+            script.close()
+
+        cmd = [sys.executable, script_name]
+        if optimize == 1:
+            cmd.insert(1, "-O")
+        elif optimize == 2:
+            cmd.insert(1, "-OO")
+        spawn(cmd, dry_run=dry_run)
+        execute(os.remove, (script_name,), "removing %s" % script_name,
+                dry_run=dry_run)
+
+    # "Direct" byte-compilation: use the py_compile module to compile
+    # right here, right now.  Note that the script generated in indirect
+    # mode simply calls 'byte_compile()' in direct mode, a weird sort of
+    # cross-process recursion.  Hey, it works!
+    else:
+        from py_compile import compile
+
+        for file in py_files:
+            if file[-3:] != ".py":
+                # This lets us be lazy and not filter filenames in
+                # the "install_lib" command.
+                continue
+
+            # Terminology from the py_compile module:
+            #   cfile - byte-compiled file
+            #   dfile - purported source filename (same as 'file' by default)
+            cfile = file + (__debug__ and "c" or "o")
+            dfile = file
+            if prefix:
+                if file[:len(prefix)] != prefix:
+                    raise ValueError, \
+                          ("invalid prefix: filename %r doesn't start with %r"
+                           % (file, prefix))
+                dfile = dfile[len(prefix):]
+            if base_dir:
+                dfile = os.path.join(base_dir, dfile)
+
+            cfile_base = os.path.basename(cfile)
+            if direct:
+                if force or newer(file, cfile):
+                    log.info("byte-compiling %s to %s", file, cfile_base)
+                    if not dry_run:
+                        compile(file, cfile, dfile)
+                else:
+                    log.debug("skipping byte-compilation of %s to %s",
+                              file, cfile_base)
+
+# byte_compile ()
+
+def rfc822_escape (header):
+    """Return a version of the string escaped for inclusion in an
+    RFC-822 header, by ensuring there are 8 spaces space after each newline.
+    """
+    lines = string.split(header, '\n')
+    lines = map(string.strip, lines)
+    header = string.join(lines, '\n' + 8*' ')
+    return header

Added: vendor/Python/current/Lib/distutils/version.py
===================================================================
--- vendor/Python/current/Lib/distutils/version.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/version.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,299 @@
+#
+# distutils/version.py
+#
+# Implements multiple version numbering conventions for the
+# Python Module Distribution Utilities.
+#
+# $Id: version.py 29687 2002-11-14 02:25:42Z akuchling $
+#
+
+"""Provides classes to represent module version numbers (one class for
+each style of version numbering).  There are currently two such classes
+implemented: StrictVersion and LooseVersion.
+
+Every version number class implements the following interface:
+  * the 'parse' method takes a string and parses it to some internal
+    representation; if the string is an invalid version number,
+    'parse' raises a ValueError exception
+  * the class constructor takes an optional string argument which,
+    if supplied, is passed to 'parse'
+  * __str__ reconstructs the string that was passed to 'parse' (or
+    an equivalent string -- ie. one that will generate an equivalent
+    version number instance)
+  * __repr__ generates Python code to recreate the version number instance
+  * __cmp__ compares the current instance with either another instance
+    of the same class or a string (which will be parsed to an instance
+    of the same class, thus must follow the same rules)
+"""
+
+import string, re
+from types import StringType
+
+class Version:
+    """Abstract base class for version numbering classes.  Just provides
+    constructor (__init__) and reproducer (__repr__), because those
+    seem to be the same for all version numbering classes.
+    """
+
+    def __init__ (self, vstring=None):
+        if vstring:
+            self.parse(vstring)
+
+    def __repr__ (self):
+        return "%s ('%s')" % (self.__class__.__name__, str(self))
+
+
+# Interface for version-number classes -- must be implemented
+# by the following classes (the concrete ones -- Version should
+# be treated as an abstract class).
+#    __init__ (string) - create and take same action as 'parse'
+#                        (string parameter is optional)
+#    parse (string)    - convert a string representation to whatever
+#                        internal representation is appropriate for
+#                        this style of version numbering
+#    __str__ (self)    - convert back to a string; should be very similar
+#                        (if not identical to) the string supplied to parse
+#    __repr__ (self)   - generate Python code to recreate
+#                        the instance
+#    __cmp__ (self, other) - compare two version numbers ('other' may
+#                        be an unparsed version string, or another
+#                        instance of your version class)
+
+
+class StrictVersion (Version):
+
+    """Version numbering for anal retentives and software idealists.
+    Implements the standard interface for version number classes as
+    described above.  A version number consists of two or three
+    dot-separated numeric components, with an optional "pre-release" tag
+    on the end.  The pre-release tag consists of the letter 'a' or 'b'
+    followed by a number.  If the numeric components of two version
+    numbers are equal, then one with a pre-release tag will always
+    be deemed earlier (lesser) than one without.
+
+    The following are valid version numbers (shown in the order that
+    would be obtained by sorting according to the supplied cmp function):
+
+        0.4       0.4.0  (these two are equivalent)
+        0.4.1
+        0.5a1
+        0.5b3
+        0.5
+        0.9.6
+        1.0
+        1.0.4a3
+        1.0.4b1
+        1.0.4
+
+    The following are examples of invalid version numbers:
+
+        1
+        2.7.2.2
+        1.3.a4
+        1.3pl1
+        1.3c4
+
+    The rationale for this version numbering system will be explained
+    in the distutils documentation.
+    """
+
+    version_re = re.compile(r'^(\d+) \. (\d+) (\. (\d+))? ([ab](\d+))?$',
+                            re.VERBOSE)
+
+
+    def parse (self, vstring):
+        match = self.version_re.match(vstring)
+        if not match:
+            raise ValueError, "invalid version number '%s'" % vstring
+
+        (major, minor, patch, prerelease, prerelease_num) = \
+            match.group(1, 2, 4, 5, 6)
+
+        if patch:
+            self.version = tuple(map(string.atoi, [major, minor, patch]))
+        else:
+            self.version = tuple(map(string.atoi, [major, minor]) + [0])
+
+        if prerelease:
+            self.prerelease = (prerelease[0], string.atoi(prerelease_num))
+        else:
+            self.prerelease = None
+
+
+    def __str__ (self):
+
+        if self.version[2] == 0:
+            vstring = string.join(map(str, self.version[0:2]), '.')
+        else:
+            vstring = string.join(map(str, self.version), '.')
+
+        if self.prerelease:
+            vstring = vstring + self.prerelease[0] + str(self.prerelease[1])
+
+        return vstring
+
+
+    def __cmp__ (self, other):
+        if isinstance(other, StringType):
+            other = StrictVersion(other)
+
+        compare = cmp(self.version, other.version)
+        if (compare == 0):              # have to compare prerelease
+
+            # case 1: neither has prerelease; they're equal
+            # case 2: self has prerelease, other doesn't; other is greater
+            # case 3: self doesn't have prerelease, other does: self is greater
+            # case 4: both have prerelease: must compare them!
+
+            if (not self.prerelease and not other.prerelease):
+                return 0
+            elif (self.prerelease and not other.prerelease):
+                return -1
+            elif (not self.prerelease and other.prerelease):
+                return 1
+            elif (self.prerelease and other.prerelease):
+                return cmp(self.prerelease, other.prerelease)
+
+        else:                           # numeric versions don't match --
+            return compare              # prerelease stuff doesn't matter
+
+
+# end class StrictVersion
+
+
+# The rules according to Greg Stein:
+# 1) a version number has 1 or more numbers separate by a period or by
+#    sequences of letters. If only periods, then these are compared
+#    left-to-right to determine an ordering.
+# 2) sequences of letters are part of the tuple for comparison and are
+#    compared lexicographically
+# 3) recognize the numeric components may have leading zeroes
+#
+# The LooseVersion class below implements these rules: a version number
+# string is split up into a tuple of integer and string components, and
+# comparison is a simple tuple comparison.  This means that version
+# numbers behave in a predictable and obvious way, but a way that might
+# not necessarily be how people *want* version numbers to behave.  There
+# wouldn't be a problem if people could stick to purely numeric version
+# numbers: just split on period and compare the numbers as tuples.
+# However, people insist on putting letters into their version numbers;
+# the most common purpose seems to be:
+#   - indicating a "pre-release" version
+#     ('alpha', 'beta', 'a', 'b', 'pre', 'p')
+#   - indicating a post-release patch ('p', 'pl', 'patch')
+# but of course this can't cover all version number schemes, and there's
+# no way to know what a programmer means without asking him.
+#
+# The problem is what to do with letters (and other non-numeric
+# characters) in a version number.  The current implementation does the
+# obvious and predictable thing: keep them as strings and compare
+# lexically within a tuple comparison.  This has the desired effect if
+# an appended letter sequence implies something "post-release":
+# eg. "0.99" < "0.99pl14" < "1.0", and "5.001" < "5.001m" < "5.002".
+#
+# However, if letters in a version number imply a pre-release version,
+# the "obvious" thing isn't correct.  Eg. you would expect that
+# "1.5.1" < "1.5.2a2" < "1.5.2", but under the tuple/lexical comparison
+# implemented here, this just isn't so.
+#
+# Two possible solutions come to mind.  The first is to tie the
+# comparison algorithm to a particular set of semantic rules, as has
+# been done in the StrictVersion class above.  This works great as long
+# as everyone can go along with bondage and discipline.  Hopefully a
+# (large) subset of Python module programmers will agree that the
+# particular flavour of bondage and discipline provided by StrictVersion
+# provides enough benefit to be worth using, and will submit their
+# version numbering scheme to its domination.  The free-thinking
+# anarchists in the lot will never give in, though, and something needs
+# to be done to accommodate them.
+#
+# Perhaps a "moderately strict" version class could be implemented that
+# lets almost anything slide (syntactically), and makes some heuristic
+# assumptions about non-digits in version number strings.  This could
+# sink into special-case-hell, though; if I was as talented and
+# idiosyncratic as Larry Wall, I'd go ahead and implement a class that
+# somehow knows that "1.2.1" < "1.2.2a2" < "1.2.2" < "1.2.2pl3", and is
+# just as happy dealing with things like "2g6" and "1.13++".  I don't
+# think I'm smart enough to do it right though.
+#
+# In any case, I've coded the test suite for this module (see
+# ../test/test_version.py) specifically to fail on things like comparing
+# "1.2a2" and "1.2".  That's not because the *code* is doing anything
+# wrong, it's because the simple, obvious design doesn't match my
+# complicated, hairy expectations for real-world version numbers.  It
+# would be a snap to fix the test suite to say, "Yep, LooseVersion does
+# the Right Thing" (ie. the code matches the conception).  But I'd rather
+# have a conception that matches common notions about version numbers.
+
+class LooseVersion (Version):
+
+    """Version numbering for anarchists and software realists.
+    Implements the standard interface for version number classes as
+    described above.  A version number consists of a series of numbers,
+    separated by either periods or strings of letters.  When comparing
+    version numbers, the numeric components will be compared
+    numerically, and the alphabetic components lexically.  The following
+    are all valid version numbers, in no particular order:
+
+        1.5.1
+        1.5.2b2
+        161
+        3.10a
+        8.02
+        3.4j
+        1996.07.12
+        3.2.pl0
+        3.1.1.6
+        2g6
+        11g
+        0.960923
+        2.2beta29
+        1.13++
+        5.5.kw
+        2.0b1pl0
+
+    In fact, there is no such thing as an invalid version number under
+    this scheme; the rules for comparison are simple and predictable,
+    but may not always give the results you want (for some definition
+    of "want").
+    """
+
+    component_re = re.compile(r'(\d+ | [a-z]+ | \.)', re.VERBOSE)
+
+    def __init__ (self, vstring=None):
+        if vstring:
+            self.parse(vstring)
+
+
+    def parse (self, vstring):
+        # I've given up on thinking I can reconstruct the version string
+        # from the parsed tuple -- so I just store the string here for
+        # use by __str__
+        self.vstring = vstring
+        components = filter(lambda x: x and x != '.',
+                            self.component_re.split(vstring))
+        for i in range(len(components)):
+            try:
+                components[i] = int(components[i])
+            except ValueError:
+                pass
+
+        self.version = components
+
+
+    def __str__ (self):
+        return self.vstring
+
+
+    def __repr__ (self):
+        return "LooseVersion ('%s')" % str(self)
+
+
+    def __cmp__ (self, other):
+        if isinstance(other, StringType):
+            other = LooseVersion(other)
+
+        return cmp(self.version, other.version)
+
+
+# end class LooseVersion

Added: vendor/Python/current/Lib/distutils/versionpredicate.py
===================================================================
--- vendor/Python/current/Lib/distutils/versionpredicate.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/distutils/versionpredicate.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,164 @@
+"""Module for parsing and testing package version predicate strings.
+"""
+import re
+import distutils.version
+import operator
+
+
+re_validPackage = re.compile(r"(?i)^\s*([a-z_]\w*(?:\.[a-z_]\w*)*)(.*)")
+# (package) (rest)
+
+re_paren = re.compile(r"^\s*\((.*)\)\s*$") # (list) inside of parentheses
+re_splitComparison = re.compile(r"^\s*(<=|>=|<|>|!=|==)\s*([^\s,]+)\s*$")
+# (comp) (version)
+
+
+def splitUp(pred):
+    """Parse a single version comparison.
+
+    Return (comparison string, StrictVersion)
+    """
+    res = re_splitComparison.match(pred)
+    if not res:
+        raise ValueError("bad package restriction syntax: %r" % pred)
+    comp, verStr = res.groups()
+    return (comp, distutils.version.StrictVersion(verStr))
+
+compmap = {"<": operator.lt, "<=": operator.le, "==": operator.eq,
+           ">": operator.gt, ">=": operator.ge, "!=": operator.ne}
+
+class VersionPredicate:
+    """Parse and test package version predicates.
+
+    >>> v = VersionPredicate('pyepat.abc (>1.0, <3333.3a1, !=1555.1b3)')
+
+    The `name` attribute provides the full dotted name that is given::
+
+    >>> v.name
+    'pyepat.abc'
+
+    The str() of a `VersionPredicate` provides a normalized
+    human-readable version of the expression::
+
+    >>> print v
+    pyepat.abc (> 1.0, < 3333.3a1, != 1555.1b3)
+
+    The `satisfied_by()` method can be used to determine with a given
+    version number is included in the set described by the version
+    restrictions::
+
+    >>> v.satisfied_by('1.1')
+    True
+    >>> v.satisfied_by('1.4')
+    True
+    >>> v.satisfied_by('1.0')
+    False
+    >>> v.satisfied_by('4444.4')
+    False
+    >>> v.satisfied_by('1555.1b3')
+    False
+
+    `VersionPredicate` is flexible in accepting extra whitespace::
+
+    >>> v = VersionPredicate(' pat( ==  0.1  )  ')
+    >>> v.name
+    'pat'
+    >>> v.satisfied_by('0.1')
+    True
+    >>> v.satisfied_by('0.2')
+    False
+
+    If any version numbers passed in do not conform to the
+    restrictions of `StrictVersion`, a `ValueError` is raised::
+
+    >>> v = VersionPredicate('p1.p2.p3.p4(>=1.0, <=1.3a1, !=1.2zb3)')
+    Traceback (most recent call last):
+      ...
+    ValueError: invalid version number '1.2zb3'
+
+    It the module or package name given does not conform to what's
+    allowed as a legal module or package name, `ValueError` is
+    raised::
+
+    >>> v = VersionPredicate('foo-bar')
+    Traceback (most recent call last):
+      ...
+    ValueError: expected parenthesized list: '-bar'
+
+    >>> v = VersionPredicate('foo bar (12.21)')
+    Traceback (most recent call last):
+      ...
+    ValueError: expected parenthesized list: 'bar (12.21)'
+
+    """
+
+    def __init__(self, versionPredicateStr):
+        """Parse a version predicate string.
+        """
+        # Fields:
+        #    name:  package name
+        #    pred:  list of (comparison string, StrictVersion)
+
+        versionPredicateStr = versionPredicateStr.strip()
+        if not versionPredicateStr:
+            raise ValueError("empty package restriction")
+        match = re_validPackage.match(versionPredicateStr)
+        if not match:
+            raise ValueError("bad package name in %r" % versionPredicateStr)
+        self.name, paren = match.groups()
+        paren = paren.strip()
+        if paren:
+            match = re_paren.match(paren)
+            if not match:
+                raise ValueError("expected parenthesized list: %r" % paren)
+            str = match.groups()[0]
+            self.pred = [splitUp(aPred) for aPred in str.split(",")]
+            if not self.pred:
+                raise ValueError("empty parenthesized list in %r"
+                                 % versionPredicateStr)
+        else:
+            self.pred = []
+
+    def __str__(self):
+        if self.pred:
+            seq = [cond + " " + str(ver) for cond, ver in self.pred]
+            return self.name + " (" + ", ".join(seq) + ")"
+        else:
+            return self.name
+
+    def satisfied_by(self, version):
+        """True if version is compatible with all the predicates in self.
+        The parameter version must be acceptable to the StrictVersion
+        constructor.  It may be either a string or StrictVersion.
+        """
+        for cond, ver in self.pred:
+            if not compmap[cond](version, ver):
+                return False
+        return True
+
+
+_provision_rx = None
+
+def split_provision(value):
+    """Return the name and optional version number of a provision.
+
+    The version number, if given, will be returned as a `StrictVersion`
+    instance, otherwise it will be `None`.
+
+    >>> split_provision('mypkg')
+    ('mypkg', None)
+    >>> split_provision(' mypkg( 1.2 ) ')
+    ('mypkg', StrictVersion ('1.2'))
+    """
+    global _provision_rx
+    if _provision_rx is None:
+        _provision_rx = re.compile(
+            "([a-zA-Z_]\w*(?:\.[a-zA-Z_]\w*)*)(?:\s*\(\s*([^)\s]+)\s*\))?$")
+    value = value.strip()
+    m = _provision_rx.match(value)
+    if not m:
+        raise ValueError("illegal provides specification: %r" % value)
+    ver = m.group(2) or None
+    if ver:
+        ver = distutils.version.StrictVersion(ver)
+    return m.group(1), ver

Added: vendor/Python/current/Lib/doctest.py
===================================================================
--- vendor/Python/current/Lib/doctest.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/doctest.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2637 @@
+# Module doctest.
+# Released to the public domain 16-Jan-2001, by Tim Peters (tim at python.org).
+# Major enhancements and refactoring by:
+#     Jim Fulton
+#     Edward Loper
+
+# Provided as-is; use at your own risk; no warranty; no promises; enjoy!
+
+r"""Module doctest -- a framework for running examples in docstrings.
+
+In simplest use, end each module M to be tested with:
+
+def _test():
+    import doctest
+    doctest.testmod()
+
+if __name__ == "__main__":
+    _test()
+
+Then running the module as a script will cause the examples in the
+docstrings to get executed and verified:
+
+python M.py
+
+This won't display anything unless an example fails, in which case the
+failing example(s) and the cause(s) of the failure(s) are printed to stdout
+(why not stderr? because stderr is a lame hack <0.2 wink>), and the final
+line of output is "Test failed.".
+
+Run it with the -v switch instead:
+
+python M.py -v
+
+and a detailed report of all examples tried is printed to stdout, along
+with assorted summaries at the end.
+
+You can force verbose mode by passing "verbose=True" to testmod, or prohibit
+it by passing "verbose=False".  In either of those cases, sys.argv is not
+examined by testmod.
+
+There are a variety of other ways to run doctests, including integration
+with the unittest framework, and support for running non-Python text
+files containing doctests.  There are also many ways to override parts
+of doctest's default behaviors.  See the Library Reference Manual for
+details.
+"""
+
+__docformat__ = 'reStructuredText en'
+
+__all__ = [
+    # 0, Option Flags
+    'register_optionflag',
+    'DONT_ACCEPT_TRUE_FOR_1',
+    'DONT_ACCEPT_BLANKLINE',
+    'NORMALIZE_WHITESPACE',
+    'ELLIPSIS',
+    'SKIP',
+    'IGNORE_EXCEPTION_DETAIL',
+    'COMPARISON_FLAGS',
+    'REPORT_UDIFF',
+    'REPORT_CDIFF',
+    'REPORT_NDIFF',
+    'REPORT_ONLY_FIRST_FAILURE',
+    'REPORTING_FLAGS',
+    # 1. Utility Functions
+    # 2. Example & DocTest
+    'Example',
+    'DocTest',
+    # 3. Doctest Parser
+    'DocTestParser',
+    # 4. Doctest Finder
+    'DocTestFinder',
+    # 5. Doctest Runner
+    'DocTestRunner',
+    'OutputChecker',
+    'DocTestFailure',
+    'UnexpectedException',
+    'DebugRunner',
+    # 6. Test Functions
+    'testmod',
+    'testfile',
+    'run_docstring_examples',
+    # 7. Tester
+    'Tester',
+    # 8. Unittest Support
+    'DocTestSuite',
+    'DocFileSuite',
+    'set_unittest_reportflags',
+    # 9. Debugging Support
+    'script_from_examples',
+    'testsource',
+    'debug_src',
+    'debug',
+]
+
+import __future__
+
+import sys, traceback, inspect, linecache, os, re
+import unittest, difflib, pdb, tempfile
+import warnings
+from StringIO import StringIO
+
+# There are 4 basic classes:
+#  - Example: a <source, want> pair, plus an intra-docstring line number.
+#  - DocTest: a collection of examples, parsed from a docstring, plus
+#    info about where the docstring came from (name, filename, lineno).
+#  - DocTestFinder: extracts DocTests from a given object's docstring and
+#    its contained objects' docstrings.
+#  - DocTestRunner: runs DocTest cases, and accumulates statistics.
+#
+# So the basic picture is:
+#
+#                             list of:
+# +------+                   +---------+                   +-------+
+# |object| --DocTestFinder-> | DocTest | --DocTestRunner-> |results|
+# +------+                   +---------+                   +-------+
+#                            | Example |
+#                            |   ...   |
+#                            | Example |
+#                            +---------+
+
+# Option constants.
+
+OPTIONFLAGS_BY_NAME = {}
+def register_optionflag(name):
+    # Create a new flag unless `name` is already known.
+    return OPTIONFLAGS_BY_NAME.setdefault(name, 1 << len(OPTIONFLAGS_BY_NAME))
+
+DONT_ACCEPT_TRUE_FOR_1 = register_optionflag('DONT_ACCEPT_TRUE_FOR_1')
+DONT_ACCEPT_BLANKLINE = register_optionflag('DONT_ACCEPT_BLANKLINE')
+NORMALIZE_WHITESPACE = register_optionflag('NORMALIZE_WHITESPACE')
+ELLIPSIS = register_optionflag('ELLIPSIS')
+SKIP = register_optionflag('SKIP')
+IGNORE_EXCEPTION_DETAIL = register_optionflag('IGNORE_EXCEPTION_DETAIL')
+
+COMPARISON_FLAGS = (DONT_ACCEPT_TRUE_FOR_1 |
+                    DONT_ACCEPT_BLANKLINE |
+                    NORMALIZE_WHITESPACE |
+                    ELLIPSIS |
+                    SKIP |
+                    IGNORE_EXCEPTION_DETAIL)
+
+REPORT_UDIFF = register_optionflag('REPORT_UDIFF')
+REPORT_CDIFF = register_optionflag('REPORT_CDIFF')
+REPORT_NDIFF = register_optionflag('REPORT_NDIFF')
+REPORT_ONLY_FIRST_FAILURE = register_optionflag('REPORT_ONLY_FIRST_FAILURE')
+
+REPORTING_FLAGS = (REPORT_UDIFF |
+                   REPORT_CDIFF |
+                   REPORT_NDIFF |
+                   REPORT_ONLY_FIRST_FAILURE)
+
+# Special string markers for use in `want` strings:
+BLANKLINE_MARKER = '<BLANKLINE>'
+ELLIPSIS_MARKER = '...'
+
+######################################################################
+## Table of Contents
+######################################################################
+#  1. Utility Functions
+#  2. Example & DocTest -- store test cases
+#  3. DocTest Parser -- extracts examples from strings
+#  4. DocTest Finder -- extracts test cases from objects
+#  5. DocTest Runner -- runs test cases
+#  6. Test Functions -- convenient wrappers for testing
+#  7. Tester Class -- for backwards compatibility
+#  8. Unittest Support
+#  9. Debugging Support
+# 10. Example Usage
+
+######################################################################
+## 1. Utility Functions
+######################################################################
+
+def _extract_future_flags(globs):
+    """
+    Return the compiler-flags associated with the future features that
+    have been imported into the given namespace (globs).
+    """
+    flags = 0
+    for fname in __future__.all_feature_names:
+        feature = globs.get(fname, None)
+        if feature is getattr(__future__, fname):
+            flags |= feature.compiler_flag
+    return flags
+
+def _normalize_module(module, depth=2):
+    """
+    Return the module specified by `module`.  In particular:
+      - If `module` is a module, then return module.
+      - If `module` is a string, then import and return the
+        module with that name.
+      - If `module` is None, then return the calling module.
+        The calling module is assumed to be the module of
+        the stack frame at the given depth in the call stack.
+    """
+    if inspect.ismodule(module):
+        return module
+    elif isinstance(module, (str, unicode)):
+        return __import__(module, globals(), locals(), ["*"])
+    elif module is None:
+        return sys.modules[sys._getframe(depth).f_globals['__name__']]
+    else:
+        raise TypeError("Expected a module, string, or None")
+
+def _load_testfile(filename, package, module_relative):
+    if module_relative:
+        package = _normalize_module(package, 3)
+        filename = _module_relative_path(package, filename)
+        if hasattr(package, '__loader__'):
+            if hasattr(package.__loader__, 'get_data'):
+                return package.__loader__.get_data(filename), filename
+    return open(filename).read(), filename
+
+def _indent(s, indent=4):
+    """
+    Add the given number of space characters to the beginning every
+    non-blank line in `s`, and return the result.
+    """
+    # This regexp matches the start of non-blank lines:
+    return re.sub('(?m)^(?!$)', indent*' ', s)
+
+def _exception_traceback(exc_info):
+    """
+    Return a string containing a traceback message for the given
+    exc_info tuple (as returned by sys.exc_info()).
+    """
+    # Get a traceback message.
+    excout = StringIO()
+    exc_type, exc_val, exc_tb = exc_info
+    traceback.print_exception(exc_type, exc_val, exc_tb, file=excout)
+    return excout.getvalue()
+
+# Override some StringIO methods.
+class _SpoofOut(StringIO):
+    def getvalue(self):
+        result = StringIO.getvalue(self)
+        # If anything at all was written, make sure there's a trailing
+        # newline.  There's no way for the expected output to indicate
+        # that a trailing newline is missing.
+        if result and not result.endswith("\n"):
+            result += "\n"
+        # Prevent softspace from screwing up the next test case, in
+        # case they used print with a trailing comma in an example.
+        if hasattr(self, "softspace"):
+            del self.softspace
+        return result
+
+    def truncate(self,   size=None):
+        StringIO.truncate(self, size)
+        if hasattr(self, "softspace"):
+            del self.softspace
+
+# Worst-case linear-time ellipsis matching.
+def _ellipsis_match(want, got):
+    """
+    Essentially the only subtle case:
+    >>> _ellipsis_match('aa...aa', 'aaa')
+    False
+    """
+    if ELLIPSIS_MARKER not in want:
+        return want == got
+
+    # Find "the real" strings.
+    ws = want.split(ELLIPSIS_MARKER)
+    assert len(ws) >= 2
+
+    # Deal with exact matches possibly needed at one or both ends.
+    startpos, endpos = 0, len(got)
+    w = ws[0]
+    if w:   # starts with exact match
+        if got.startswith(w):
+            startpos = len(w)
+            del ws[0]
+        else:
+            return False
+    w = ws[-1]
+    if w:   # ends with exact match
+        if got.endswith(w):
+            endpos -= len(w)
+            del ws[-1]
+        else:
+            return False
+
+    if startpos > endpos:
+        # Exact end matches required more characters than we have, as in
+        # _ellipsis_match('aa...aa', 'aaa')
+        return False
+
+    # For the rest, we only need to find the leftmost non-overlapping
+    # match for each piece.  If there's no overall match that way alone,
+    # there's no overall match period.
+    for w in ws:
+        # w may be '' at times, if there are consecutive ellipses, or
+        # due to an ellipsis at the start or end of `want`.  That's OK.
+        # Search for an empty string succeeds, and doesn't change startpos.
+        startpos = got.find(w, startpos, endpos)
+        if startpos < 0:
+            return False
+        startpos += len(w)
+
+    return True
+
+def _comment_line(line):
+    "Return a commented form of the given line"
+    line = line.rstrip()
+    if line:
+        return '# '+line
+    else:
+        return '#'
+
+class _OutputRedirectingPdb(pdb.Pdb):
+    """
+    A specialized version of the python debugger that redirects stdout
+    to a given stream when interacting with the user.  Stdout is *not*
+    redirected when traced code is executed.
+    """
+    def __init__(self, out):
+        self.__out = out
+        pdb.Pdb.__init__(self, stdout=out)
+
+    def trace_dispatch(self, *args):
+        # Redirect stdout to the given stream.
+        save_stdout = sys.stdout
+        sys.stdout = self.__out
+        # Call Pdb's trace dispatch method.
+        try:
+            return pdb.Pdb.trace_dispatch(self, *args)
+        finally:
+            sys.stdout = save_stdout
+
+# [XX] Normalize with respect to os.path.pardir?
+def _module_relative_path(module, path):
+    if not inspect.ismodule(module):
+        raise TypeError, 'Expected a module: %r' % module
+    if path.startswith('/'):
+        raise ValueError, 'Module-relative files may not have absolute paths'
+
+    # Find the base directory for the path.
+    if hasattr(module, '__file__'):
+        # A normal module/package
+        basedir = os.path.split(module.__file__)[0]
+    elif module.__name__ == '__main__':
+        # An interactive session.
+        if len(sys.argv)>0 and sys.argv[0] != '':
+            basedir = os.path.split(sys.argv[0])[0]
+        else:
+            basedir = os.curdir
+    else:
+        # A module w/o __file__ (this includes builtins)
+        raise ValueError("Can't resolve paths relative to the module " +
+                         module + " (it has no __file__)")
+
+    # Combine the base directory and the path.
+    return os.path.join(basedir, *(path.split('/')))
+
+######################################################################
+## 2. Example & DocTest
+######################################################################
+## - An "example" is a <source, want> pair, where "source" is a
+##   fragment of source code, and "want" is the expected output for
+##   "source."  The Example class also includes information about
+##   where the example was extracted from.
+##
+## - A "doctest" is a collection of examples, typically extracted from
+##   a string (such as an object's docstring).  The DocTest class also
+##   includes information about where the string was extracted from.
+
+class Example:
+    """
+    A single doctest example, consisting of source code and expected
+    output.  `Example` defines the following attributes:
+
+      - source: A single Python statement, always ending with a newline.
+        The constructor adds a newline if needed.
+
+      - want: The expected output from running the source code (either
+        from stdout, or a traceback in case of exception).  `want` ends
+        with a newline unless it's empty, in which case it's an empty
+        string.  The constructor adds a newline if needed.
+
+      - exc_msg: The exception message generated by the example, if
+        the example is expected to generate an exception; or `None` if
+        it is not expected to generate an exception.  This exception
+        message is compared against the return value of
+        `traceback.format_exception_only()`.  `exc_msg` ends with a
+        newline unless it's `None`.  The constructor adds a newline
+        if needed.
+
+      - lineno: The line number within the DocTest string containing
+        this Example where the Example begins.  This line number is
+        zero-based, with respect to the beginning of the DocTest.
+
+      - indent: The example's indentation in the DocTest string.
+        I.e., the number of space characters that preceed the
+        example's first prompt.
+
+      - options: A dictionary mapping from option flags to True or
+        False, which is used to override default options for this
+        example.  Any option flags not contained in this dictionary
+        are left at their default value (as specified by the
+        DocTestRunner's optionflags).  By default, no options are set.
+    """
+    def __init__(self, source, want, exc_msg=None, lineno=0, indent=0,
+                 options=None):
+        # Normalize inputs.
+        if not source.endswith('\n'):
+            source += '\n'
+        if want and not want.endswith('\n'):
+            want += '\n'
+        if exc_msg is not None and not exc_msg.endswith('\n'):
+            exc_msg += '\n'
+        # Store properties.
+        self.source = source
+        self.want = want
+        self.lineno = lineno
+        self.indent = indent
+        if options is None: options = {}
+        self.options = options
+        self.exc_msg = exc_msg
+
+class DocTest:
+    """
+    A collection of doctest examples that should be run in a single
+    namespace.  Each `DocTest` defines the following attributes:
+
+      - examples: the list of examples.
+
+      - globs: The namespace (aka globals) that the examples should
+        be run in.
+
+      - name: A name identifying the DocTest (typically, the name of
+        the object whose docstring this DocTest was extracted from).
+
+      - filename: The name of the file that this DocTest was extracted
+        from, or `None` if the filename is unknown.
+
+      - lineno: The line number within filename where this DocTest
+        begins, or `None` if the line number is unavailable.  This
+        line number is zero-based, with respect to the beginning of
+        the file.
+
+      - docstring: The string that the examples were extracted from,
+        or `None` if the string is unavailable.
+    """
+    def __init__(self, examples, globs, name, filename, lineno, docstring):
+        """
+        Create a new DocTest containing the given examples.  The
+        DocTest's globals are initialized with a copy of `globs`.
+        """
+        assert not isinstance(examples, basestring), \
+               "DocTest no longer accepts str; use DocTestParser instead"
+        self.examples = examples
+        self.docstring = docstring
+        self.globs = globs.copy()
+        self.name = name
+        self.filename = filename
+        self.lineno = lineno
+
+    def __repr__(self):
+        if len(self.examples) == 0:
+            examples = 'no examples'
+        elif len(self.examples) == 1:
+            examples = '1 example'
+        else:
+            examples = '%d examples' % len(self.examples)
+        return ('<DocTest %s from %s:%s (%s)>' %
+                (self.name, self.filename, self.lineno, examples))
+
+
+    # This lets us sort tests by name:
+    def __cmp__(self, other):
+        if not isinstance(other, DocTest):
+            return -1
+        return cmp((self.name, self.filename, self.lineno, id(self)),
+                   (other.name, other.filename, other.lineno, id(other)))
+
+######################################################################
+## 3. DocTestParser
+######################################################################
+
+class DocTestParser:
+    """
+    A class used to parse strings containing doctest examples.
+    """
+    # This regular expression is used to find doctest examples in a
+    # string.  It defines three groups: `source` is the source code
+    # (including leading indentation and prompts); `indent` is the
+    # indentation of the first (PS1) line of the source code; and
+    # `want` is the expected output (including leading indentation).
+    _EXAMPLE_RE = re.compile(r'''
+        # Source consists of a PS1 line followed by zero or more PS2 lines.
+        (?P<source>
+            (?:^(?P<indent> [ ]*) >>>    .*)    # PS1 line
+            (?:\n           [ ]*  \.\.\. .*)*)  # PS2 lines
+        \n?
+        # Want consists of any non-blank lines that do not start with PS1.
+        (?P<want> (?:(?![ ]*$)    # Not a blank line
+                     (?![ ]*>>>)  # Not a line starting with PS1
+                     .*$\n?       # But any other line
+                  )*)
+        ''', re.MULTILINE | re.VERBOSE)
+
+    # A regular expression for handling `want` strings that contain
+    # expected exceptions.  It divides `want` into three pieces:
+    #    - the traceback header line (`hdr`)
+    #    - the traceback stack (`stack`)
+    #    - the exception message (`msg`), as generated by
+    #      traceback.format_exception_only()
+    # `msg` may have multiple lines.  We assume/require that the
+    # exception message is the first non-indented line starting with a word
+    # character following the traceback header line.
+    _EXCEPTION_RE = re.compile(r"""
+        # Grab the traceback header.  Different versions of Python have
+        # said different things on the first traceback line.
+        ^(?P<hdr> Traceback\ \(
+            (?: most\ recent\ call\ last
+            |   innermost\ last
+            ) \) :
+        )
+        \s* $                # toss trailing whitespace on the header.
+        (?P<stack> .*?)      # don't blink: absorb stuff until...
+        ^ (?P<msg> \w+ .*)   #     a line *starts* with alphanum.
+        """, re.VERBOSE | re.MULTILINE | re.DOTALL)
+
+    # A callable returning a true value iff its argument is a blank line
+    # or contains a single comment.
+    _IS_BLANK_OR_COMMENT = re.compile(r'^[ ]*(#.*)?$').match
+
+    def parse(self, string, name='<string>'):
+        """
+        Divide the given string into examples and intervening text,
+        and return them as a list of alternating Examples and strings.
+        Line numbers for the Examples are 0-based.  The optional
+        argument `name` is a name identifying this string, and is only
+        used for error messages.
+        """
+        string = string.expandtabs()
+        # If all lines begin with the same indentation, then strip it.
+        min_indent = self._min_indent(string)
+        if min_indent > 0:
+            string = '\n'.join([l[min_indent:] for l in string.split('\n')])
+
+        output = []
+        charno, lineno = 0, 0
+        # Find all doctest examples in the string:
+        for m in self._EXAMPLE_RE.finditer(string):
+            # Add the pre-example text to `output`.
+            output.append(string[charno:m.start()])
+            # Update lineno (lines before this example)
+            lineno += string.count('\n', charno, m.start())
+            # Extract info from the regexp match.
+            (source, options, want, exc_msg) = \
+                     self._parse_example(m, name, lineno)
+            # Create an Example, and add it to the list.
+            if not self._IS_BLANK_OR_COMMENT(source):
+                output.append( Example(source, want, exc_msg,
+                                    lineno=lineno,
+                                    indent=min_indent+len(m.group('indent')),
+                                    options=options) )
+            # Update lineno (lines inside this example)
+            lineno += string.count('\n', m.start(), m.end())
+            # Update charno.
+            charno = m.end()
+        # Add any remaining post-example text to `output`.
+        output.append(string[charno:])
+        return output
+
+    def get_doctest(self, string, globs, name, filename, lineno):
+        """
+        Extract all doctest examples from the given string, and
+        collect them into a `DocTest` object.
+
+        `globs`, `name`, `filename`, and `lineno` are attributes for
+        the new `DocTest` object.  See the documentation for `DocTest`
+        for more information.
+        """
+        return DocTest(self.get_examples(string, name), globs,
+                       name, filename, lineno, string)
+
+    def get_examples(self, string, name='<string>'):
+        """
+        Extract all doctest examples from the given string, and return
+        them as a list of `Example` objects.  Line numbers are
+        0-based, because it's most common in doctests that nothing
+        interesting appears on the same line as opening triple-quote,
+        and so the first interesting line is called \"line 1\" then.
+
+        The optional argument `name` is a name identifying this
+        string, and is only used for error messages.
+        """
+        return [x for x in self.parse(string, name)
+                if isinstance(x, Example)]
+
+    def _parse_example(self, m, name, lineno):
+        """
+        Given a regular expression match from `_EXAMPLE_RE` (`m`),
+        return a pair `(source, want)`, where `source` is the matched
+        example's source code (with prompts and indentation stripped);
+        and `want` is the example's expected output (with indentation
+        stripped).
+
+        `name` is the string's name, and `lineno` is the line number
+        where the example starts; both are used for error messages.
+        """
+        # Get the example's indentation level.
+        indent = len(m.group('indent'))
+
+        # Divide source into lines; check that they're properly
+        # indented; and then strip their indentation & prompts.
+        source_lines = m.group('source').split('\n')
+        self._check_prompt_blank(source_lines, indent, name, lineno)
+        self._check_prefix(source_lines[1:], ' '*indent + '.', name, lineno)
+        source = '\n'.join([sl[indent+4:] for sl in source_lines])
+
+        # Divide want into lines; check that it's properly indented; and
+        # then strip the indentation.  Spaces before the last newline should
+        # be preserved, so plain rstrip() isn't good enough.
+        want = m.group('want')
+        want_lines = want.split('\n')
+        if len(want_lines) > 1 and re.match(r' *$', want_lines[-1]):
+            del want_lines[-1]  # forget final newline & spaces after it
+        self._check_prefix(want_lines, ' '*indent, name,
+                           lineno + len(source_lines))
+        want = '\n'.join([wl[indent:] for wl in want_lines])
+
+        # If `want` contains a traceback message, then extract it.
+        m = self._EXCEPTION_RE.match(want)
+        if m:
+            exc_msg = m.group('msg')
+        else:
+            exc_msg = None
+
+        # Extract options from the source.
+        options = self._find_options(source, name, lineno)
+
+        return source, options, want, exc_msg
+
+    # This regular expression looks for option directives in the
+    # source code of an example.  Option directives are comments
+    # starting with "doctest:".  Warning: this may give false
+    # positives for string-literals that contain the string
+    # "#doctest:".  Eliminating these false positives would require
+    # actually parsing the string; but we limit them by ignoring any
+    # line containing "#doctest:" that is *followed* by a quote mark.
+    _OPTION_DIRECTIVE_RE = re.compile(r'#\s*doctest:\s*([^\n\'"]*)$',
+                                      re.MULTILINE)
+
+    def _find_options(self, source, name, lineno):
+        """
+        Return a dictionary containing option overrides extracted from
+        option directives in the given source string.
+
+        `name` is the string's name, and `lineno` is the line number
+        where the example starts; both are used for error messages.
+        """
+        options = {}
+        # (note: with the current regexp, this will match at most once:)
+        for m in self._OPTION_DIRECTIVE_RE.finditer(source):
+            option_strings = m.group(1).replace(',', ' ').split()
+            for option in option_strings:
+                if (option[0] not in '+-' or
+                    option[1:] not in OPTIONFLAGS_BY_NAME):
+                    raise ValueError('line %r of the doctest for %s '
+                                     'has an invalid option: %r' %
+                                     (lineno+1, name, option))
+                flag = OPTIONFLAGS_BY_NAME[option[1:]]
+                options[flag] = (option[0] == '+')
+        if options and self._IS_BLANK_OR_COMMENT(source):
+            raise ValueError('line %r of the doctest for %s has an option '
+                             'directive on a line with no example: %r' %
+                             (lineno, name, source))
+        return options
+
+    # This regular expression finds the indentation of every non-blank
+    # line in a string.
+    _INDENT_RE = re.compile('^([ ]*)(?=\S)', re.MULTILINE)
+
+    def _min_indent(self, s):
+        "Return the minimum indentation of any non-blank line in `s`"
+        indents = [len(indent) for indent in self._INDENT_RE.findall(s)]
+        if len(indents) > 0:
+            return min(indents)
+        else:
+            return 0
+
+    def _check_prompt_blank(self, lines, indent, name, lineno):
+        """
+        Given the lines of a source string (including prompts and
+        leading indentation), check to make sure that every prompt is
+        followed by a space character.  If any line is not followed by
+        a space character, then raise ValueError.
+        """
+        for i, line in enumerate(lines):
+            if len(line) >= indent+4 and line[indent+3] != ' ':
+                raise ValueError('line %r of the docstring for %s '
+                                 'lacks blank after %s: %r' %
+                                 (lineno+i+1, name,
+                                  line[indent:indent+3], line))
+
+    def _check_prefix(self, lines, prefix, name, lineno):
+        """
+        Check that every line in the given list starts with the given
+        prefix; if any line does not, then raise a ValueError.
+        """
+        for i, line in enumerate(lines):
+            if line and not line.startswith(prefix):
+                raise ValueError('line %r of the docstring for %s has '
+                                 'inconsistent leading whitespace: %r' %
+                                 (lineno+i+1, name, line))
+
+
+######################################################################
+## 4. DocTest Finder
+######################################################################
+
+class DocTestFinder:
+    """
+    A class used to extract the DocTests that are relevant to a given
+    object, from its docstring and the docstrings of its contained
+    objects.  Doctests can currently be extracted from the following
+    object types: modules, functions, classes, methods, staticmethods,
+    classmethods, and properties.
+    """
+
+    def __init__(self, verbose=False, parser=DocTestParser(),
+                 recurse=True, exclude_empty=True):
+        """
+        Create a new doctest finder.
+
+        The optional argument `parser` specifies a class or
+        function that should be used to create new DocTest objects (or
+        objects that implement the same interface as DocTest).  The
+        signature for this factory function should match the signature
+        of the DocTest constructor.
+
+        If the optional argument `recurse` is false, then `find` will
+        only examine the given object, and not any contained objects.
+
+        If the optional argument `exclude_empty` is false, then `find`
+        will include tests for objects with empty docstrings.
+        """
+        self._parser = parser
+        self._verbose = verbose
+        self._recurse = recurse
+        self._exclude_empty = exclude_empty
+
+    def find(self, obj, name=None, module=None, globs=None, extraglobs=None):
+        """
+        Return a list of the DocTests that are defined by the given
+        object's docstring, or by any of its contained objects'
+        docstrings.
+
+        The optional parameter `module` is the module that contains
+        the given object.  If the module is not specified or is None, then
+        the test finder will attempt to automatically determine the
+        correct module.  The object's module is used:
+
+            - As a default namespace, if `globs` is not specified.
+            - To prevent the DocTestFinder from extracting DocTests
+              from objects that are imported from other modules.
+            - To find the name of the file containing the object.
+            - To help find the line number of the object within its
+              file.
+
+        Contained objects whose module does not match `module` are ignored.
+
+        If `module` is False, no attempt to find the module will be made.
+        This is obscure, of use mostly in tests:  if `module` is False, or
+        is None but cannot be found automatically, then all objects are
+        considered to belong to the (non-existent) module, so all contained
+        objects will (recursively) be searched for doctests.
+
+        The globals for each DocTest is formed by combining `globs`
+        and `extraglobs` (bindings in `extraglobs` override bindings
+        in `globs`).  A new copy of the globals dictionary is created
+        for each DocTest.  If `globs` is not specified, then it
+        defaults to the module's `__dict__`, if specified, or {}
+        otherwise.  If `extraglobs` is not specified, then it defaults
+        to {}.
+
+        """
+        # If name was not specified, then extract it from the object.
+        if name is None:
+            name = getattr(obj, '__name__', None)
+            if name is None:
+                raise ValueError("DocTestFinder.find: name must be given "
+                        "when obj.__name__ doesn't exist: %r" %
+                                 (type(obj),))
+
+        # Find the module that contains the given object (if obj is
+        # a module, then module=obj.).  Note: this may fail, in which
+        # case module will be None.
+        if module is False:
+            module = None
+        elif module is None:
+            module = inspect.getmodule(obj)
+
+        # Read the module's source code.  This is used by
+        # DocTestFinder._find_lineno to find the line number for a
+        # given object's docstring.
+        try:
+            file = inspect.getsourcefile(obj) or inspect.getfile(obj)
+            source_lines = linecache.getlines(file)
+            if not source_lines:
+                source_lines = None
+        except TypeError:
+            source_lines = None
+
+        # Initialize globals, and merge in extraglobs.
+        if globs is None:
+            if module is None:
+                globs = {}
+            else:
+                globs = module.__dict__.copy()
+        else:
+            globs = globs.copy()
+        if extraglobs is not None:
+            globs.update(extraglobs)
+
+        # Recursively expore `obj`, extracting DocTests.
+        tests = []
+        self._find(tests, obj, name, module, source_lines, globs, {})
+        # Sort the tests by alpha order of names, for consistency in
+        # verbose-mode output.  This was a feature of doctest in Pythons
+        # <= 2.3 that got lost by accident in 2.4.  It was repaired in
+        # 2.4.4 and 2.5.
+        tests.sort()
+        return tests
+
+    def _from_module(self, module, object):
+        """
+        Return true if the given object is defined in the given
+        module.
+        """
+        if module is None:
+            return True
+        elif inspect.isfunction(object):
+            return module.__dict__ is object.func_globals
+        elif inspect.isclass(object):
+            return module.__name__ == object.__module__
+        elif inspect.getmodule(object) is not None:
+            return module is inspect.getmodule(object)
+        elif hasattr(object, '__module__'):
+            return module.__name__ == object.__module__
+        elif isinstance(object, property):
+            return True # [XX] no way not be sure.
+        else:
+            raise ValueError("object must be a class or function")
+
+    def _find(self, tests, obj, name, module, source_lines, globs, seen):
+        """
+        Find tests for the given object and any contained objects, and
+        add them to `tests`.
+        """
+        if self._verbose:
+            print 'Finding tests in %s' % name
+
+        # If we've already processed this object, then ignore it.
+        if id(obj) in seen:
+            return
+        seen[id(obj)] = 1
+
+        # Find a test for this object, and add it to the list of tests.
+        test = self._get_test(obj, name, module, globs, source_lines)
+        if test is not None:
+            tests.append(test)
+
+        # Look for tests in a module's contained objects.
+        if inspect.ismodule(obj) and self._recurse:
+            for valname, val in obj.__dict__.items():
+                valname = '%s.%s' % (name, valname)
+                # Recurse to functions & classes.
+                if ((inspect.isfunction(val) or inspect.isclass(val)) and
+                    self._from_module(module, val)):
+                    self._find(tests, val, valname, module, source_lines,
+                               globs, seen)
+
+        # Look for tests in a module's __test__ dictionary.
+        if inspect.ismodule(obj) and self._recurse:
+            for valname, val in getattr(obj, '__test__', {}).items():
+                if not isinstance(valname, basestring):
+                    raise ValueError("DocTestFinder.find: __test__ keys "
+                                     "must be strings: %r" %
+                                     (type(valname),))
+                if not (inspect.isfunction(val) or inspect.isclass(val) or
+                        inspect.ismethod(val) or inspect.ismodule(val) or
+                        isinstance(val, basestring)):
+                    raise ValueError("DocTestFinder.find: __test__ values "
+                                     "must be strings, functions, methods, "
+                                     "classes, or modules: %r" %
+                                     (type(val),))
+                valname = '%s.__test__.%s' % (name, valname)
+                self._find(tests, val, valname, module, source_lines,
+                           globs, seen)
+
+        # Look for tests in a class's contained objects.
+        if inspect.isclass(obj) and self._recurse:
+            for valname, val in obj.__dict__.items():
+                # Special handling for staticmethod/classmethod.
+                if isinstance(val, staticmethod):
+                    val = getattr(obj, valname)
+                if isinstance(val, classmethod):
+                    val = getattr(obj, valname).im_func
+
+                # Recurse to methods, properties, and nested classes.
+                if ((inspect.isfunction(val) or inspect.isclass(val) or
+                      isinstance(val, property)) and
+                      self._from_module(module, val)):
+                    valname = '%s.%s' % (name, valname)
+                    self._find(tests, val, valname, module, source_lines,
+                               globs, seen)
+
+    def _get_test(self, obj, name, module, globs, source_lines):
+        """
+        Return a DocTest for the given object, if it defines a docstring;
+        otherwise, return None.
+        """
+        # Extract the object's docstring.  If it doesn't have one,
+        # then return None (no test for this object).
+        if isinstance(obj, basestring):
+            docstring = obj
+        else:
+            try:
+                if obj.__doc__ is None:
+                    docstring = ''
+                else:
+                    docstring = obj.__doc__
+                    if not isinstance(docstring, basestring):
+                        docstring = str(docstring)
+            except (TypeError, AttributeError):
+                docstring = ''
+
+        # Find the docstring's location in the file.
+        lineno = self._find_lineno(obj, source_lines)
+
+        # Don't bother if the docstring is empty.
+        if self._exclude_empty and not docstring:
+            return None
+
+        # Return a DocTest for this object.
+        if module is None:
+            filename = None
+        else:
+            filename = getattr(module, '__file__', module.__name__)
+            if filename[-4:] in (".pyc", ".pyo"):
+                filename = filename[:-1]
+        return self._parser.get_doctest(docstring, globs, name,
+                                        filename, lineno)
+
+    def _find_lineno(self, obj, source_lines):
+        """
+        Return a line number of the given object's docstring.  Note:
+        this method assumes that the object has a docstring.
+        """
+        lineno = None
+
+        # Find the line number for modules.
+        if inspect.ismodule(obj):
+            lineno = 0
+
+        # Find the line number for classes.
+        # Note: this could be fooled if a class is defined multiple
+        # times in a single file.
+        if inspect.isclass(obj):
+            if source_lines is None:
+                return None
+            pat = re.compile(r'^\s*class\s*%s\b' %
+                             getattr(obj, '__name__', '-'))
+            for i, line in enumerate(source_lines):
+                if pat.match(line):
+                    lineno = i
+                    break
+
+        # Find the line number for functions & methods.
+        if inspect.ismethod(obj): obj = obj.im_func
+        if inspect.isfunction(obj): obj = obj.func_code
+        if inspect.istraceback(obj): obj = obj.tb_frame
+        if inspect.isframe(obj): obj = obj.f_code
+        if inspect.iscode(obj):
+            lineno = getattr(obj, 'co_firstlineno', None)-1
+
+        # Find the line number where the docstring starts.  Assume
+        # that it's the first line that begins with a quote mark.
+        # Note: this could be fooled by a multiline function
+        # signature, where a continuation line begins with a quote
+        # mark.
+        if lineno is not None:
+            if source_lines is None:
+                return lineno+1
+            pat = re.compile('(^|.*:)\s*\w*("|\')')
+            for lineno in range(lineno, len(source_lines)):
+                if pat.match(source_lines[lineno]):
+                    return lineno
+
+        # We couldn't find the line number.
+        return None
+
+######################################################################
+## 5. DocTest Runner
+######################################################################
+
+class DocTestRunner:
+    """
+    A class used to run DocTest test cases, and accumulate statistics.
+    The `run` method is used to process a single DocTest case.  It
+    returns a tuple `(f, t)`, where `t` is the number of test cases
+    tried, and `f` is the number of test cases that failed.
+
+        >>> tests = DocTestFinder().find(_TestClass)
+        >>> runner = DocTestRunner(verbose=False)
+        >>> tests.sort(key = lambda test: test.name)
+        >>> for test in tests:
+        ...     print test.name, '->', runner.run(test)
+        _TestClass -> (0, 2)
+        _TestClass.__init__ -> (0, 2)
+        _TestClass.get -> (0, 2)
+        _TestClass.square -> (0, 1)
+
+    The `summarize` method prints a summary of all the test cases that
+    have been run by the runner, and returns an aggregated `(f, t)`
+    tuple:
+
+        >>> runner.summarize(verbose=1)
+        4 items passed all tests:
+           2 tests in _TestClass
+           2 tests in _TestClass.__init__
+           2 tests in _TestClass.get
+           1 tests in _TestClass.square
+        7 tests in 4 items.
+        7 passed and 0 failed.
+        Test passed.
+        (0, 7)
+
+    The aggregated number of tried examples and failed examples is
+    also available via the `tries` and `failures` attributes:
+
+        >>> runner.tries
+        7
+        >>> runner.failures
+        0
+
+    The comparison between expected outputs and actual outputs is done
+    by an `OutputChecker`.  This comparison may be customized with a
+    number of option flags; see the documentation for `testmod` for
+    more information.  If the option flags are insufficient, then the
+    comparison may also be customized by passing a subclass of
+    `OutputChecker` to the constructor.
+
+    The test runner's display output can be controlled in two ways.
+    First, an output function (`out) can be passed to
+    `TestRunner.run`; this function will be called with strings that
+    should be displayed.  It defaults to `sys.stdout.write`.  If
+    capturing the output is not sufficient, then the display output
+    can be also customized by subclassing DocTestRunner, and
+    overriding the methods `report_start`, `report_success`,
+    `report_unexpected_exception`, and `report_failure`.
+    """
+    # This divider string is used to separate failure messages, and to
+    # separate sections of the summary.
+    DIVIDER = "*" * 70
+
+    def __init__(self, checker=None, verbose=None, optionflags=0):
+        """
+        Create a new test runner.
+
+        Optional keyword arg `checker` is the `OutputChecker` that
+        should be used to compare the expected outputs and actual
+        outputs of doctest examples.
+
+        Optional keyword arg 'verbose' prints lots of stuff if true,
+        only failures if false; by default, it's true iff '-v' is in
+        sys.argv.
+
+        Optional argument `optionflags` can be used to control how the
+        test runner compares expected output to actual output, and how
+        it displays failures.  See the documentation for `testmod` for
+        more information.
+        """
+        self._checker = checker or OutputChecker()
+        if verbose is None:
+            verbose = '-v' in sys.argv
+        self._verbose = verbose
+        self.optionflags = optionflags
+        self.original_optionflags = optionflags
+
+        # Keep track of the examples we've run.
+        self.tries = 0
+        self.failures = 0
+        self._name2ft = {}
+
+        # Create a fake output target for capturing doctest output.
+        self._fakeout = _SpoofOut()
+
+    #/////////////////////////////////////////////////////////////////
+    # Reporting methods
+    #/////////////////////////////////////////////////////////////////
+
+    def report_start(self, out, test, example):
+        """
+        Report that the test runner is about to process the given
+        example.  (Only displays a message if verbose=True)
+        """
+        if self._verbose:
+            if example.want:
+                out('Trying:\n' + _indent(example.source) +
+                    'Expecting:\n' + _indent(example.want))
+            else:
+                out('Trying:\n' + _indent(example.source) +
+                    'Expecting nothing\n')
+
+    def report_success(self, out, test, example, got):
+        """
+        Report that the given example ran successfully.  (Only
+        displays a message if verbose=True)
+        """
+        if self._verbose:
+            out("ok\n")
+
+    def report_failure(self, out, test, example, got):
+        """
+        Report that the given example failed.
+        """
+        out(self._failure_header(test, example) +
+            self._checker.output_difference(example, got, self.optionflags))
+
+    def report_unexpected_exception(self, out, test, example, exc_info):
+        """
+        Report that the given example raised an unexpected exception.
+        """
+        out(self._failure_header(test, example) +
+            'Exception raised:\n' + _indent(_exception_traceback(exc_info)))
+
+    def _failure_header(self, test, example):
+        out = [self.DIVIDER]
+        if test.filename:
+            if test.lineno is not None and example.lineno is not None:
+                lineno = test.lineno + example.lineno + 1
+            else:
+                lineno = '?'
+            out.append('File "%s", line %s, in %s' %
+                       (test.filename, lineno, test.name))
+        else:
+            out.append('Line %s, in %s' % (example.lineno+1, test.name))
+        out.append('Failed example:')
+        source = example.source
+        out.append(_indent(source))
+        return '\n'.join(out)
+
+    #/////////////////////////////////////////////////////////////////
+    # DocTest Running
+    #/////////////////////////////////////////////////////////////////
+
+    def __run(self, test, compileflags, out):
+        """
+        Run the examples in `test`.  Write the outcome of each example
+        with one of the `DocTestRunner.report_*` methods, using the
+        writer function `out`.  `compileflags` is the set of compiler
+        flags that should be used to execute examples.  Return a tuple
+        `(f, t)`, where `t` is the number of examples tried, and `f`
+        is the number of examples that failed.  The examples are run
+        in the namespace `test.globs`.
+        """
+        # Keep track of the number of failures and tries.
+        failures = tries = 0
+
+        # Save the option flags (since option directives can be used
+        # to modify them).
+        original_optionflags = self.optionflags
+
+        SUCCESS, FAILURE, BOOM = range(3) # `outcome` state
+
+        check = self._checker.check_output
+
+        # Process each example.
+        for examplenum, example in enumerate(test.examples):
+
+            # If REPORT_ONLY_FIRST_FAILURE is set, then supress
+            # reporting after the first failure.
+            quiet = (self.optionflags & REPORT_ONLY_FIRST_FAILURE and
+                     failures > 0)
+
+            # Merge in the example's options.
+            self.optionflags = original_optionflags
+            if example.options:
+                for (optionflag, val) in example.options.items():
+                    if val:
+                        self.optionflags |= optionflag
+                    else:
+                        self.optionflags &= ~optionflag
+
+            # If 'SKIP' is set, then skip this example.
+            if self.optionflags & SKIP:
+                continue
+
+            # Record that we started this example.
+            tries += 1
+            if not quiet:
+                self.report_start(out, test, example)
+
+            # Use a special filename for compile(), so we can retrieve
+            # the source code during interactive debugging (see
+            # __patched_linecache_getlines).
+            filename = '<doctest %s[%d]>' % (test.name, examplenum)
+
+            # Run the example in the given context (globs), and record
+            # any exception that gets raised.  (But don't intercept
+            # keyboard interrupts.)
+            try:
+                # Don't blink!  This is where the user's code gets run.
+                exec compile(example.source, filename, "single",
+                             compileflags, 1) in test.globs
+                self.debugger.set_continue() # ==== Example Finished ====
+                exception = None
+            except KeyboardInterrupt:
+                raise
+            except:
+                exception = sys.exc_info()
+                self.debugger.set_continue() # ==== Example Finished ====
+
+            got = self._fakeout.getvalue()  # the actual output
+            self._fakeout.truncate(0)
+            outcome = FAILURE   # guilty until proved innocent or insane
+
+            # If the example executed without raising any exceptions,
+            # verify its output.
+            if exception is None:
+                if check(example.want, got, self.optionflags):
+                    outcome = SUCCESS
+
+            # The example raised an exception:  check if it was expected.
+            else:
+                exc_info = sys.exc_info()
+                exc_msg = traceback.format_exception_only(*exc_info[:2])[-1]
+                if not quiet:
+                    got += _exception_traceback(exc_info)
+
+                # If `example.exc_msg` is None, then we weren't expecting
+                # an exception.
+                if example.exc_msg is None:
+                    outcome = BOOM
+
+                # We expected an exception:  see whether it matches.
+                elif check(example.exc_msg, exc_msg, self.optionflags):
+                    outcome = SUCCESS
+
+                # Another chance if they didn't care about the detail.
+                elif self.optionflags & IGNORE_EXCEPTION_DETAIL:
+                    m1 = re.match(r'[^:]*:', example.exc_msg)
+                    m2 = re.match(r'[^:]*:', exc_msg)
+                    if m1 and m2 and check(m1.group(0), m2.group(0),
+                                           self.optionflags):
+                        outcome = SUCCESS
+
+            # Report the outcome.
+            if outcome is SUCCESS:
+                if not quiet:
+                    self.report_success(out, test, example, got)
+            elif outcome is FAILURE:
+                if not quiet:
+                    self.report_failure(out, test, example, got)
+                failures += 1
+            elif outcome is BOOM:
+                if not quiet:
+                    self.report_unexpected_exception(out, test, example,
+                                                     exc_info)
+                failures += 1
+            else:
+                assert False, ("unknown outcome", outcome)
+
+        # Restore the option flags (in case they were modified)
+        self.optionflags = original_optionflags
+
+        # Record and return the number of failures and tries.
+        self.__record_outcome(test, failures, tries)
+        return failures, tries
+
+    def __record_outcome(self, test, f, t):
+        """
+        Record the fact that the given DocTest (`test`) generated `f`
+        failures out of `t` tried examples.
+        """
+        f2, t2 = self._name2ft.get(test.name, (0,0))
+        self._name2ft[test.name] = (f+f2, t+t2)
+        self.failures += f
+        self.tries += t
+
+    __LINECACHE_FILENAME_RE = re.compile(r'<doctest '
+                                         r'(?P<name>[\w\.]+)'
+                                         r'\[(?P<examplenum>\d+)\]>$')
+    def __patched_linecache_getlines(self, filename, module_globals=None):
+        m = self.__LINECACHE_FILENAME_RE.match(filename)
+        if m and m.group('name') == self.test.name:
+            example = self.test.examples[int(m.group('examplenum'))]
+            return example.source.splitlines(True)
+        else:
+            return self.save_linecache_getlines(filename, module_globals)
+
+    def run(self, test, compileflags=None, out=None, clear_globs=True):
+        """
+        Run the examples in `test`, and display the results using the
+        writer function `out`.
+
+        The examples are run in the namespace `test.globs`.  If
+        `clear_globs` is true (the default), then this namespace will
+        be cleared after the test runs, to help with garbage
+        collection.  If you would like to examine the namespace after
+        the test completes, then use `clear_globs=False`.
+
+        `compileflags` gives the set of flags that should be used by
+        the Python compiler when running the examples.  If not
+        specified, then it will default to the set of future-import
+        flags that apply to `globs`.
+
+        The output of each example is checked using
+        `DocTestRunner.check_output`, and the results are formatted by
+        the `DocTestRunner.report_*` methods.
+        """
+        self.test = test
+
+        if compileflags is None:
+            compileflags = _extract_future_flags(test.globs)
+
+        save_stdout = sys.stdout
+        if out is None:
+            out = save_stdout.write
+        sys.stdout = self._fakeout
+
+        # Patch pdb.set_trace to restore sys.stdout during interactive
+        # debugging (so it's not still redirected to self._fakeout).
+        # Note that the interactive output will go to *our*
+        # save_stdout, even if that's not the real sys.stdout; this
+        # allows us to write test cases for the set_trace behavior.
+        save_set_trace = pdb.set_trace
+        self.debugger = _OutputRedirectingPdb(save_stdout)
+        self.debugger.reset()
+        pdb.set_trace = self.debugger.set_trace
+
+        # Patch linecache.getlines, so we can see the example's source
+        # when we're inside the debugger.
+        self.save_linecache_getlines = linecache.getlines
+        linecache.getlines = self.__patched_linecache_getlines
+
+        try:
+            return self.__run(test, compileflags, out)
+        finally:
+            sys.stdout = save_stdout
+            pdb.set_trace = save_set_trace
+            linecache.getlines = self.save_linecache_getlines
+            if clear_globs:
+                test.globs.clear()
+
+    #/////////////////////////////////////////////////////////////////
+    # Summarization
+    #/////////////////////////////////////////////////////////////////
+    def summarize(self, verbose=None):
+        """
+        Print a summary of all the test cases that have been run by
+        this DocTestRunner, and return a tuple `(f, t)`, where `f` is
+        the total number of failed examples, and `t` is the total
+        number of tried examples.
+
+        The optional `verbose` argument controls how detailed the
+        summary is.  If the verbosity is not specified, then the
+        DocTestRunner's verbosity is used.
+        """
+        if verbose is None:
+            verbose = self._verbose
+        notests = []
+        passed = []
+        failed = []
+        totalt = totalf = 0
+        for x in self._name2ft.items():
+            name, (f, t) = x
+            assert f <= t
+            totalt += t
+            totalf += f
+            if t == 0:
+                notests.append(name)
+            elif f == 0:
+                passed.append( (name, t) )
+            else:
+                failed.append(x)
+        if verbose:
+            if notests:
+                print len(notests), "items had no tests:"
+                notests.sort()
+                for thing in notests:
+                    print "   ", thing
+            if passed:
+                print len(passed), "items passed all tests:"
+                passed.sort()
+                for thing, count in passed:
+                    print " %3d tests in %s" % (count, thing)
+        if failed:
+            print self.DIVIDER
+            print len(failed), "items had failures:"
+            failed.sort()
+            for thing, (f, t) in failed:
+                print " %3d of %3d in %s" % (f, t, thing)
+        if verbose:
+            print totalt, "tests in", len(self._name2ft), "items."
+            print totalt - totalf, "passed and", totalf, "failed."
+        if totalf:
+            print "***Test Failed***", totalf, "failures."
+        elif verbose:
+            print "Test passed."
+        return totalf, totalt
+
+    #/////////////////////////////////////////////////////////////////
+    # Backward compatibility cruft to maintain doctest.master.
+    #/////////////////////////////////////////////////////////////////
+    def merge(self, other):
+        d = self._name2ft
+        for name, (f, t) in other._name2ft.items():
+            if name in d:
+                print "*** DocTestRunner.merge: '" + name + "' in both" \
+                    " testers; summing outcomes."
+                f2, t2 = d[name]
+                f = f + f2
+                t = t + t2
+            d[name] = f, t
+
+class OutputChecker:
+    """
+    A class used to check the whether the actual output from a doctest
+    example matches the expected output.  `OutputChecker` defines two
+    methods: `check_output`, which compares a given pair of outputs,
+    and returns true if they match; and `output_difference`, which
+    returns a string describing the differences between two outputs.
+    """
+    def check_output(self, want, got, optionflags):
+        """
+        Return True iff the actual output from an example (`got`)
+        matches the expected output (`want`).  These strings are
+        always considered to match if they are identical; but
+        depending on what option flags the test runner is using,
+        several non-exact match types are also possible.  See the
+        documentation for `TestRunner` for more information about
+        option flags.
+        """
+        # Handle the common case first, for efficiency:
+        # if they're string-identical, always return true.
+        if got == want:
+            return True
+
+        # The values True and False replaced 1 and 0 as the return
+        # value for boolean comparisons in Python 2.3.
+        if not (optionflags & DONT_ACCEPT_TRUE_FOR_1):
+            if (got,want) == ("True\n", "1\n"):
+                return True
+            if (got,want) == ("False\n", "0\n"):
+                return True
+
+        # <BLANKLINE> can be used as a special sequence to signify a
+        # blank line, unless the DONT_ACCEPT_BLANKLINE flag is used.
+        if not (optionflags & DONT_ACCEPT_BLANKLINE):
+            # Replace <BLANKLINE> in want with a blank line.
+            want = re.sub('(?m)^%s\s*?$' % re.escape(BLANKLINE_MARKER),
+                          '', want)
+            # If a line in got contains only spaces, then remove the
+            # spaces.
+            got = re.sub('(?m)^\s*?$', '', got)
+            if got == want:
+                return True
+
+        # This flag causes doctest to ignore any differences in the
+        # contents of whitespace strings.  Note that this can be used
+        # in conjunction with the ELLIPSIS flag.
+        if optionflags & NORMALIZE_WHITESPACE:
+            got = ' '.join(got.split())
+            want = ' '.join(want.split())
+            if got == want:
+                return True
+
+        # The ELLIPSIS flag says to let the sequence "..." in `want`
+        # match any substring in `got`.
+        if optionflags & ELLIPSIS:
+            if _ellipsis_match(want, got):
+                return True
+
+        # We didn't find any match; return false.
+        return False
+
+    # Should we do a fancy diff?
+    def _do_a_fancy_diff(self, want, got, optionflags):
+        # Not unless they asked for a fancy diff.
+        if not optionflags & (REPORT_UDIFF |
+                              REPORT_CDIFF |
+                              REPORT_NDIFF):
+            return False
+
+        # If expected output uses ellipsis, a meaningful fancy diff is
+        # too hard ... or maybe not.  In two real-life failures Tim saw,
+        # a diff was a major help anyway, so this is commented out.
+        # [todo] _ellipsis_match() knows which pieces do and don't match,
+        # and could be the basis for a kick-ass diff in this case.
+        ##if optionflags & ELLIPSIS and ELLIPSIS_MARKER in want:
+        ##    return False
+
+        # ndiff does intraline difference marking, so can be useful even
+        # for 1-line differences.
+        if optionflags & REPORT_NDIFF:
+            return True
+
+        # The other diff types need at least a few lines to be helpful.
+        return want.count('\n') > 2 and got.count('\n') > 2
+
+    def output_difference(self, example, got, optionflags):
+        """
+        Return a string describing the differences between the
+        expected output for a given example (`example`) and the actual
+        output (`got`).  `optionflags` is the set of option flags used
+        to compare `want` and `got`.
+        """
+        want = example.want
+        # If <BLANKLINE>s are being used, then replace blank lines
+        # with <BLANKLINE> in the actual output string.
+        if not (optionflags & DONT_ACCEPT_BLANKLINE):
+            got = re.sub('(?m)^[ ]*(?=\n)', BLANKLINE_MARKER, got)
+
+        # Check if we should use diff.
+        if self._do_a_fancy_diff(want, got, optionflags):
+            # Split want & got into lines.
+            want_lines = want.splitlines(True)  # True == keep line ends
+            got_lines = got.splitlines(True)
+            # Use difflib to find their differences.
+            if optionflags & REPORT_UDIFF:
+                diff = difflib.unified_diff(want_lines, got_lines, n=2)
+                diff = list(diff)[2:] # strip the diff header
+                kind = 'unified diff with -expected +actual'
+            elif optionflags & REPORT_CDIFF:
+                diff = difflib.context_diff(want_lines, got_lines, n=2)
+                diff = list(diff)[2:] # strip the diff header
+                kind = 'context diff with expected followed by actual'
+            elif optionflags & REPORT_NDIFF:
+                engine = difflib.Differ(charjunk=difflib.IS_CHARACTER_JUNK)
+                diff = list(engine.compare(want_lines, got_lines))
+                kind = 'ndiff with -expected +actual'
+            else:
+                assert 0, 'Bad diff option'
+            # Remove trailing whitespace on diff output.
+            diff = [line.rstrip() + '\n' for line in diff]
+            return 'Differences (%s):\n' % kind + _indent(''.join(diff))
+
+        # If we're not using diff, then simply list the expected
+        # output followed by the actual output.
+        if want and got:
+            return 'Expected:\n%sGot:\n%s' % (_indent(want), _indent(got))
+        elif want:
+            return 'Expected:\n%sGot nothing\n' % _indent(want)
+        elif got:
+            return 'Expected nothing\nGot:\n%s' % _indent(got)
+        else:
+            return 'Expected nothing\nGot nothing\n'
+
+class DocTestFailure(Exception):
+    """A DocTest example has failed in debugging mode.
+
+    The exception instance has variables:
+
+    - test: the DocTest object being run
+
+    - example: the Example object that failed
+
+    - got: the actual output
+    """
+    def __init__(self, test, example, got):
+        self.test = test
+        self.example = example
+        self.got = got
+
+    def __str__(self):
+        return str(self.test)
+
+class UnexpectedException(Exception):
+    """A DocTest example has encountered an unexpected exception
+
+    The exception instance has variables:
+
+    - test: the DocTest object being run
+
+    - example: the Example object that failed
+
+    - exc_info: the exception info
+    """
+    def __init__(self, test, example, exc_info):
+        self.test = test
+        self.example = example
+        self.exc_info = exc_info
+
+    def __str__(self):
+        return str(self.test)
+
+class DebugRunner(DocTestRunner):
+    r"""Run doc tests but raise an exception as soon as there is a failure.
+
+       If an unexpected exception occurs, an UnexpectedException is raised.
+       It contains the test, the example, and the original exception:
+
+         >>> runner = DebugRunner(verbose=False)
+         >>> test = DocTestParser().get_doctest('>>> raise KeyError\n42',
+         ...                                    {}, 'foo', 'foo.py', 0)
+         >>> try:
+         ...     runner.run(test)
+         ... except UnexpectedException, failure:
+         ...     pass
+
+         >>> failure.test is test
+         True
+
+         >>> failure.example.want
+         '42\n'
+
+         >>> exc_info = failure.exc_info
+         >>> raise exc_info[0], exc_info[1], exc_info[2]
+         Traceback (most recent call last):
+         ...
+         KeyError
+
+       We wrap the original exception to give the calling application
+       access to the test and example information.
+
+       If the output doesn't match, then a DocTestFailure is raised:
+
+         >>> test = DocTestParser().get_doctest('''
+         ...      >>> x = 1
+         ...      >>> x
+         ...      2
+         ...      ''', {}, 'foo', 'foo.py', 0)
+
+         >>> try:
+         ...    runner.run(test)
+         ... except DocTestFailure, failure:
+         ...    pass
+
+       DocTestFailure objects provide access to the test:
+
+         >>> failure.test is test
+         True
+
+       As well as to the example:
+
+         >>> failure.example.want
+         '2\n'
+
+       and the actual output:
+
+         >>> failure.got
+         '1\n'
+
+       If a failure or error occurs, the globals are left intact:
+
+         >>> del test.globs['__builtins__']
+         >>> test.globs
+         {'x': 1}
+
+         >>> test = DocTestParser().get_doctest('''
+         ...      >>> x = 2
+         ...      >>> raise KeyError
+         ...      ''', {}, 'foo', 'foo.py', 0)
+
+         >>> runner.run(test)
+         Traceback (most recent call last):
+         ...
+         UnexpectedException: <DocTest foo from foo.py:0 (2 examples)>
+
+         >>> del test.globs['__builtins__']
+         >>> test.globs
+         {'x': 2}
+
+       But the globals are cleared if there is no error:
+
+         >>> test = DocTestParser().get_doctest('''
+         ...      >>> x = 2
+         ...      ''', {}, 'foo', 'foo.py', 0)
+
+         >>> runner.run(test)
+         (0, 1)
+
+         >>> test.globs
+         {}
+
+       """
+
+    def run(self, test, compileflags=None, out=None, clear_globs=True):
+        r = DocTestRunner.run(self, test, compileflags, out, False)
+        if clear_globs:
+            test.globs.clear()
+        return r
+
+    def report_unexpected_exception(self, out, test, example, exc_info):
+        raise UnexpectedException(test, example, exc_info)
+
+    def report_failure(self, out, test, example, got):
+        raise DocTestFailure(test, example, got)
+
+######################################################################
+## 6. Test Functions
+######################################################################
+# These should be backwards compatible.
+
+# For backward compatibility, a global instance of a DocTestRunner
+# class, updated by testmod.
+master = None
+
+def testmod(m=None, name=None, globs=None, verbose=None,
+            report=True, optionflags=0, extraglobs=None,
+            raise_on_error=False, exclude_empty=False):
+    """m=None, name=None, globs=None, verbose=None, report=True,
+       optionflags=0, extraglobs=None, raise_on_error=False,
+       exclude_empty=False
+
+    Test examples in docstrings in functions and classes reachable
+    from module m (or the current module if m is not supplied), starting
+    with m.__doc__.
+
+    Also test examples reachable from dict m.__test__ if it exists and is
+    not None.  m.__test__ maps names to functions, classes and strings;
+    function and class docstrings are tested even if the name is private;
+    strings are tested directly, as if they were docstrings.
+
+    Return (#failures, #tests).
+
+    See doctest.__doc__ for an overview.
+
+    Optional keyword arg "name" gives the name of the module; by default
+    use m.__name__.
+
+    Optional keyword arg "globs" gives a dict to be used as the globals
+    when executing examples; by default, use m.__dict__.  A copy of this
+    dict is actually used for each docstring, so that each docstring's
+    examples start with a clean slate.
+
+    Optional keyword arg "extraglobs" gives a dictionary that should be
+    merged into the globals that are used to execute examples.  By
+    default, no extra globals are used.  This is new in 2.4.
+
+    Optional keyword arg "verbose" prints lots of stuff if true, prints
+    only failures if false; by default, it's true iff "-v" is in sys.argv.
+
+    Optional keyword arg "report" prints a summary at the end when true,
+    else prints nothing at the end.  In verbose mode, the summary is
+    detailed, else very brief (in fact, empty if all tests passed).
+
+    Optional keyword arg "optionflags" or's together module constants,
+    and defaults to 0.  This is new in 2.3.  Possible values (see the
+    docs for details):
+
+        DONT_ACCEPT_TRUE_FOR_1
+        DONT_ACCEPT_BLANKLINE
+        NORMALIZE_WHITESPACE
+        ELLIPSIS
+        SKIP
+        IGNORE_EXCEPTION_DETAIL
+        REPORT_UDIFF
+        REPORT_CDIFF
+        REPORT_NDIFF
+        REPORT_ONLY_FIRST_FAILURE
+
+    Optional keyword arg "raise_on_error" raises an exception on the
+    first unexpected exception or failure. This allows failures to be
+    post-mortem debugged.
+
+    Advanced tomfoolery:  testmod runs methods of a local instance of
+    class doctest.Tester, then merges the results into (or creates)
+    global Tester instance doctest.master.  Methods of doctest.master
+    can be called directly too, if you want to do something unusual.
+    Passing report=0 to testmod is especially useful then, to delay
+    displaying a summary.  Invoke doctest.master.summarize(verbose)
+    when you're done fiddling.
+    """
+    global master
+
+    # If no module was given, then use __main__.
+    if m is None:
+        # DWA - m will still be None if this wasn't invoked from the command
+        # line, in which case the following TypeError is about as good an error
+        # as we should expect
+        m = sys.modules.get('__main__')
+
+    # Check that we were actually given a module.
+    if not inspect.ismodule(m):
+        raise TypeError("testmod: module required; %r" % (m,))
+
+    # If no name was given, then use the module's name.
+    if name is None:
+        name = m.__name__
+
+    # Find, parse, and run all tests in the given module.
+    finder = DocTestFinder(exclude_empty=exclude_empty)
+
+    if raise_on_error:
+        runner = DebugRunner(verbose=verbose, optionflags=optionflags)
+    else:
+        runner = DocTestRunner(verbose=verbose, optionflags=optionflags)
+
+    for test in finder.find(m, name, globs=globs, extraglobs=extraglobs):
+        runner.run(test)
+
+    if report:
+        runner.summarize()
+
+    if master is None:
+        master = runner
+    else:
+        master.merge(runner)
+
+    return runner.failures, runner.tries
+
+def testfile(filename, module_relative=True, name=None, package=None,
+             globs=None, verbose=None, report=True, optionflags=0,
+             extraglobs=None, raise_on_error=False, parser=DocTestParser(),
+             encoding=None):
+    """
+    Test examples in the given file.  Return (#failures, #tests).
+
+    Optional keyword arg "module_relative" specifies how filenames
+    should be interpreted:
+
+      - If "module_relative" is True (the default), then "filename"
+         specifies a module-relative path.  By default, this path is
+         relative to the calling module's directory; but if the
+         "package" argument is specified, then it is relative to that
+         package.  To ensure os-independence, "filename" should use
+         "/" characters to separate path segments, and should not
+         be an absolute path (i.e., it may not begin with "/").
+
+      - If "module_relative" is False, then "filename" specifies an
+        os-specific path.  The path may be absolute or relative (to
+        the current working directory).
+
+    Optional keyword arg "name" gives the name of the test; by default
+    use the file's basename.
+
+    Optional keyword argument "package" is a Python package or the
+    name of a Python package whose directory should be used as the
+    base directory for a module relative filename.  If no package is
+    specified, then the calling module's directory is used as the base
+    directory for module relative filenames.  It is an error to
+    specify "package" if "module_relative" is False.
+
+    Optional keyword arg "globs" gives a dict to be used as the globals
+    when executing examples; by default, use {}.  A copy of this dict
+    is actually used for each docstring, so that each docstring's
+    examples start with a clean slate.
+
+    Optional keyword arg "extraglobs" gives a dictionary that should be
+    merged into the globals that are used to execute examples.  By
+    default, no extra globals are used.
+
+    Optional keyword arg "verbose" prints lots of stuff if true, prints
+    only failures if false; by default, it's true iff "-v" is in sys.argv.
+
+    Optional keyword arg "report" prints a summary at the end when true,
+    else prints nothing at the end.  In verbose mode, the summary is
+    detailed, else very brief (in fact, empty if all tests passed).
+
+    Optional keyword arg "optionflags" or's together module constants,
+    and defaults to 0.  Possible values (see the docs for details):
+
+        DONT_ACCEPT_TRUE_FOR_1
+        DONT_ACCEPT_BLANKLINE
+        NORMALIZE_WHITESPACE
+        ELLIPSIS
+        SKIP
+        IGNORE_EXCEPTION_DETAIL
+        REPORT_UDIFF
+        REPORT_CDIFF
+        REPORT_NDIFF
+        REPORT_ONLY_FIRST_FAILURE
+
+    Optional keyword arg "raise_on_error" raises an exception on the
+    first unexpected exception or failure. This allows failures to be
+    post-mortem debugged.
+
+    Optional keyword arg "parser" specifies a DocTestParser (or
+    subclass) that should be used to extract tests from the files.
+
+    Optional keyword arg "encoding" specifies an encoding that should
+    be used to convert the file to unicode.
+
+    Advanced tomfoolery:  testmod runs methods of a local instance of
+    class doctest.Tester, then merges the results into (or creates)
+    global Tester instance doctest.master.  Methods of doctest.master
+    can be called directly too, if you want to do something unusual.
+    Passing report=0 to testmod is especially useful then, to delay
+    displaying a summary.  Invoke doctest.master.summarize(verbose)
+    when you're done fiddling.
+    """
+    global master
+
+    if package and not module_relative:
+        raise ValueError("Package may only be specified for module-"
+                         "relative paths.")
+
+    # Relativize the path
+    text, filename = _load_testfile(filename, package, module_relative)
+
+    # If no name was given, then use the file's name.
+    if name is None:
+        name = os.path.basename(filename)
+
+    # Assemble the globals.
+    if globs is None:
+        globs = {}
+    else:
+        globs = globs.copy()
+    if extraglobs is not None:
+        globs.update(extraglobs)
+
+    if raise_on_error:
+        runner = DebugRunner(verbose=verbose, optionflags=optionflags)
+    else:
+        runner = DocTestRunner(verbose=verbose, optionflags=optionflags)
+
+    if encoding is not None:
+        text = text.decode(encoding)
+
+    # Read the file, convert it to a test, and run it.
+    test = parser.get_doctest(text, globs, name, filename, 0)
+    runner.run(test)
+
+    if report:
+        runner.summarize()
+
+    if master is None:
+        master = runner
+    else:
+        master.merge(runner)
+
+    return runner.failures, runner.tries
+
+def run_docstring_examples(f, globs, verbose=False, name="NoName",
+                           compileflags=None, optionflags=0):
+    """
+    Test examples in the given object's docstring (`f`), using `globs`
+    as globals.  Optional argument `name` is used in failure messages.
+    If the optional argument `verbose` is true, then generate output
+    even if there are no failures.
+
+    `compileflags` gives the set of flags that should be used by the
+    Python compiler when running the examples.  If not specified, then
+    it will default to the set of future-import flags that apply to
+    `globs`.
+
+    Optional keyword arg `optionflags` specifies options for the
+    testing and output.  See the documentation for `testmod` for more
+    information.
+    """
+    # Find, parse, and run all tests in the given module.
+    finder = DocTestFinder(verbose=verbose, recurse=False)
+    runner = DocTestRunner(verbose=verbose, optionflags=optionflags)
+    for test in finder.find(f, name, globs=globs):
+        runner.run(test, compileflags=compileflags)
+
+######################################################################
+## 7. Tester
+######################################################################
+# This is provided only for backwards compatibility.  It's not
+# actually used in any way.
+
+class Tester:
+    def __init__(self, mod=None, globs=None, verbose=None, optionflags=0):
+
+        warnings.warn("class Tester is deprecated; "
+                      "use class doctest.DocTestRunner instead",
+                      DeprecationWarning, stacklevel=2)
+        if mod is None and globs is None:
+            raise TypeError("Tester.__init__: must specify mod or globs")
+        if mod is not None and not inspect.ismodule(mod):
+            raise TypeError("Tester.__init__: mod must be a module; %r" %
+                            (mod,))
+        if globs is None:
+            globs = mod.__dict__
+        self.globs = globs
+
+        self.verbose = verbose
+        self.optionflags = optionflags
+        self.testfinder = DocTestFinder()
+        self.testrunner = DocTestRunner(verbose=verbose,
+                                        optionflags=optionflags)
+
+    def runstring(self, s, name):
+        test = DocTestParser().get_doctest(s, self.globs, name, None, None)
+        if self.verbose:
+            print "Running string", name
+        (f,t) = self.testrunner.run(test)
+        if self.verbose:
+            print f, "of", t, "examples failed in string", name
+        return (f,t)
+
+    def rundoc(self, object, name=None, module=None):
+        f = t = 0
+        tests = self.testfinder.find(object, name, module=module,
+                                     globs=self.globs)
+        for test in tests:
+            (f2, t2) = self.testrunner.run(test)
+            (f,t) = (f+f2, t+t2)
+        return (f,t)
+
+    def rundict(self, d, name, module=None):
+        import new
+        m = new.module(name)
+        m.__dict__.update(d)
+        if module is None:
+            module = False
+        return self.rundoc(m, name, module)
+
+    def run__test__(self, d, name):
+        import new
+        m = new.module(name)
+        m.__test__ = d
+        return self.rundoc(m, name)
+
+    def summarize(self, verbose=None):
+        return self.testrunner.summarize(verbose)
+
+    def merge(self, other):
+        self.testrunner.merge(other.testrunner)
+
+######################################################################
+## 8. Unittest Support
+######################################################################
+
+_unittest_reportflags = 0
+
+def set_unittest_reportflags(flags):
+    """Sets the unittest option flags.
+
+    The old flag is returned so that a runner could restore the old
+    value if it wished to:
+
+      >>> import doctest
+      >>> old = doctest._unittest_reportflags
+      >>> doctest.set_unittest_reportflags(REPORT_NDIFF |
+      ...                          REPORT_ONLY_FIRST_FAILURE) == old
+      True
+
+      >>> doctest._unittest_reportflags == (REPORT_NDIFF |
+      ...                                   REPORT_ONLY_FIRST_FAILURE)
+      True
+
+    Only reporting flags can be set:
+
+      >>> doctest.set_unittest_reportflags(ELLIPSIS)
+      Traceback (most recent call last):
+      ...
+      ValueError: ('Only reporting flags allowed', 8)
+
+      >>> doctest.set_unittest_reportflags(old) == (REPORT_NDIFF |
+      ...                                   REPORT_ONLY_FIRST_FAILURE)
+      True
+    """
+    global _unittest_reportflags
+
+    if (flags & REPORTING_FLAGS) != flags:
+        raise ValueError("Only reporting flags allowed", flags)
+    old = _unittest_reportflags
+    _unittest_reportflags = flags
+    return old
+
+
+class DocTestCase(unittest.TestCase):
+
+    def __init__(self, test, optionflags=0, setUp=None, tearDown=None,
+                 checker=None):
+
+        unittest.TestCase.__init__(self)
+        self._dt_optionflags = optionflags
+        self._dt_checker = checker
+        self._dt_test = test
+        self._dt_setUp = setUp
+        self._dt_tearDown = tearDown
+
+    def setUp(self):
+        test = self._dt_test
+
+        if self._dt_setUp is not None:
+            self._dt_setUp(test)
+
+    def tearDown(self):
+        test = self._dt_test
+
+        if self._dt_tearDown is not None:
+            self._dt_tearDown(test)
+
+        test.globs.clear()
+
+    def runTest(self):
+        test = self._dt_test
+        old = sys.stdout
+        new = StringIO()
+        optionflags = self._dt_optionflags
+
+        if not (optionflags & REPORTING_FLAGS):
+            # The option flags don't include any reporting flags,
+            # so add the default reporting flags
+            optionflags |= _unittest_reportflags
+
+        runner = DocTestRunner(optionflags=optionflags,
+                               checker=self._dt_checker, verbose=False)
+
+        try:
+            runner.DIVIDER = "-"*70
+            failures, tries = runner.run(
+                test, out=new.write, clear_globs=False)
+        finally:
+            sys.stdout = old
+
+        if failures:
+            raise self.failureException(self.format_failure(new.getvalue()))
+
+    def format_failure(self, err):
+        test = self._dt_test
+        if test.lineno is None:
+            lineno = 'unknown line number'
+        else:
+            lineno = '%s' % test.lineno
+        lname = '.'.join(test.name.split('.')[-1:])
+        return ('Failed doctest test for %s\n'
+                '  File "%s", line %s, in %s\n\n%s'
+                % (test.name, test.filename, lineno, lname, err)
+                )
+
+    def debug(self):
+        r"""Run the test case without results and without catching exceptions
+
+           The unit test framework includes a debug method on test cases
+           and test suites to support post-mortem debugging.  The test code
+           is run in such a way that errors are not caught.  This way a
+           caller can catch the errors and initiate post-mortem debugging.
+
+           The DocTestCase provides a debug method that raises
+           UnexpectedException errors if there is an unexepcted
+           exception:
+
+             >>> test = DocTestParser().get_doctest('>>> raise KeyError\n42',
+             ...                {}, 'foo', 'foo.py', 0)
+             >>> case = DocTestCase(test)
+             >>> try:
+             ...     case.debug()
+             ... except UnexpectedException, failure:
+             ...     pass
+
+           The UnexpectedException contains the test, the example, and
+           the original exception:
+
+             >>> failure.test is test
+             True
+
+             >>> failure.example.want
+             '42\n'
+
+             >>> exc_info = failure.exc_info
+             >>> raise exc_info[0], exc_info[1], exc_info[2]
+             Traceback (most recent call last):
+             ...
+             KeyError
+
+           If the output doesn't match, then a DocTestFailure is raised:
+
+             >>> test = DocTestParser().get_doctest('''
+             ...      >>> x = 1
+             ...      >>> x
+             ...      2
+             ...      ''', {}, 'foo', 'foo.py', 0)
+             >>> case = DocTestCase(test)
+
+             >>> try:
+             ...    case.debug()
+             ... except DocTestFailure, failure:
+             ...    pass
+
+           DocTestFailure objects provide access to the test:
+
+             >>> failure.test is test
+             True
+
+           As well as to the example:
+
+             >>> failure.example.want
+             '2\n'
+
+           and the actual output:
+
+             >>> failure.got
+             '1\n'
+
+           """
+
+        self.setUp()
+        runner = DebugRunner(optionflags=self._dt_optionflags,
+                             checker=self._dt_checker, verbose=False)
+        runner.run(self._dt_test)
+        self.tearDown()
+
+    def id(self):
+        return self._dt_test.name
+
+    def __repr__(self):
+        name = self._dt_test.name.split('.')
+        return "%s (%s)" % (name[-1], '.'.join(name[:-1]))
+
+    __str__ = __repr__
+
+    def shortDescription(self):
+        return "Doctest: " + self._dt_test.name
+
+def DocTestSuite(module=None, globs=None, extraglobs=None, test_finder=None,
+                 **options):
+    """
+    Convert doctest tests for a module to a unittest test suite.
+
+    This converts each documentation string in a module that
+    contains doctest tests to a unittest test case.  If any of the
+    tests in a doc string fail, then the test case fails.  An exception
+    is raised showing the name of the file containing the test and a
+    (sometimes approximate) line number.
+
+    The `module` argument provides the module to be tested.  The argument
+    can be either a module or a module name.
+
+    If no argument is given, the calling module is used.
+
+    A number of options may be provided as keyword arguments:
+
+    setUp
+      A set-up function.  This is called before running the
+      tests in each file. The setUp function will be passed a DocTest
+      object.  The setUp function can access the test globals as the
+      globs attribute of the test passed.
+
+    tearDown
+      A tear-down function.  This is called after running the
+      tests in each file.  The tearDown function will be passed a DocTest
+      object.  The tearDown function can access the test globals as the
+      globs attribute of the test passed.
+
+    globs
+      A dictionary containing initial global variables for the tests.
+
+    optionflags
+       A set of doctest option flags expressed as an integer.
+    """
+
+    if test_finder is None:
+        test_finder = DocTestFinder()
+
+    module = _normalize_module(module)
+    tests = test_finder.find(module, globs=globs, extraglobs=extraglobs)
+    if globs is None:
+        globs = module.__dict__
+    if not tests:
+        # Why do we want to do this? Because it reveals a bug that might
+        # otherwise be hidden.
+        raise ValueError(module, "has no tests")
+
+    tests.sort()
+    suite = unittest.TestSuite()
+    for test in tests:
+        if len(test.examples) == 0:
+            continue
+        if not test.filename:
+            filename = module.__file__
+            if filename[-4:] in (".pyc", ".pyo"):
+                filename = filename[:-1]
+            test.filename = filename
+        suite.addTest(DocTestCase(test, **options))
+
+    return suite
+
+class DocFileCase(DocTestCase):
+
+    def id(self):
+        return '_'.join(self._dt_test.name.split('.'))
+
+    def __repr__(self):
+        return self._dt_test.filename
+    __str__ = __repr__
+
+    def format_failure(self, err):
+        return ('Failed doctest test for %s\n  File "%s", line 0\n\n%s'
+                % (self._dt_test.name, self._dt_test.filename, err)
+                )
+
+def DocFileTest(path, module_relative=True, package=None,
+                globs=None, parser=DocTestParser(),
+                encoding=None, **options):
+    if globs is None:
+        globs = {}
+    else:
+        globs = globs.copy()
+
+    if package and not module_relative:
+        raise ValueError("Package may only be specified for module-"
+                         "relative paths.")
+
+    # Relativize the path.
+    doc, path = _load_testfile(path, package, module_relative)
+
+    if "__file__" not in globs:
+        globs["__file__"] = path
+
+    # Find the file and read it.
+    name = os.path.basename(path)
+
+    # If an encoding is specified, use it to convert the file to unicode
+    if encoding is not None:
+        doc = doc.decode(encoding)
+
+    # Convert it to a test, and wrap it in a DocFileCase.
+    test = parser.get_doctest(doc, globs, name, path, 0)
+    return DocFileCase(test, **options)
+
+def DocFileSuite(*paths, **kw):
+    """A unittest suite for one or more doctest files.
+
+    The path to each doctest file is given as a string; the
+    interpretation of that string depends on the keyword argument
+    "module_relative".
+
+    A number of options may be provided as keyword arguments:
+
+    module_relative
+      If "module_relative" is True, then the given file paths are
+      interpreted as os-independent module-relative paths.  By
+      default, these paths are relative to the calling module's
+      directory; but if the "package" argument is specified, then
+      they are relative to that package.  To ensure os-independence,
+      "filename" should use "/" characters to separate path
+      segments, and may not be an absolute path (i.e., it may not
+      begin with "/").
+
+      If "module_relative" is False, then the given file paths are
+      interpreted as os-specific paths.  These paths may be absolute
+      or relative (to the current working directory).
+
+    package
+      A Python package or the name of a Python package whose directory
+      should be used as the base directory for module relative paths.
+      If "package" is not specified, then the calling module's
+      directory is used as the base directory for module relative
+      filenames.  It is an error to specify "package" if
+      "module_relative" is False.
+
+    setUp
+      A set-up function.  This is called before running the
+      tests in each file. The setUp function will be passed a DocTest
+      object.  The setUp function can access the test globals as the
+      globs attribute of the test passed.
+
+    tearDown
+      A tear-down function.  This is called after running the
+      tests in each file.  The tearDown function will be passed a DocTest
+      object.  The tearDown function can access the test globals as the
+      globs attribute of the test passed.
+
+    globs
+      A dictionary containing initial global variables for the tests.
+
+    optionflags
+      A set of doctest option flags expressed as an integer.
+
+    parser
+      A DocTestParser (or subclass) that should be used to extract
+      tests from the files.
+
+    encoding
+      An encoding that will be used to convert the files to unicode.
+    """
+    suite = unittest.TestSuite()
+
+    # We do this here so that _normalize_module is called at the right
+    # level.  If it were called in DocFileTest, then this function
+    # would be the caller and we might guess the package incorrectly.
+    if kw.get('module_relative', True):
+        kw['package'] = _normalize_module(kw.get('package'))
+
+    for path in paths:
+        suite.addTest(DocFileTest(path, **kw))
+
+    return suite
+
+######################################################################
+## 9. Debugging Support
+######################################################################
+
+def script_from_examples(s):
+    r"""Extract script from text with examples.
+
+       Converts text with examples to a Python script.  Example input is
+       converted to regular code.  Example output and all other words
+       are converted to comments:
+
+       >>> text = '''
+       ...       Here are examples of simple math.
+       ...
+       ...           Python has super accurate integer addition
+       ...
+       ...           >>> 2 + 2
+       ...           5
+       ...
+       ...           And very friendly error messages:
+       ...
+       ...           >>> 1/0
+       ...           To Infinity
+       ...           And
+       ...           Beyond
+       ...
+       ...           You can use logic if you want:
+       ...
+       ...           >>> if 0:
+       ...           ...    blah
+       ...           ...    blah
+       ...           ...
+       ...
+       ...           Ho hum
+       ...           '''
+
+       >>> print script_from_examples(text)
+       # Here are examples of simple math.
+       #
+       #     Python has super accurate integer addition
+       #
+       2 + 2
+       # Expected:
+       ## 5
+       #
+       #     And very friendly error messages:
+       #
+       1/0
+       # Expected:
+       ## To Infinity
+       ## And
+       ## Beyond
+       #
+       #     You can use logic if you want:
+       #
+       if 0:
+          blah
+          blah
+       #
+       #     Ho hum
+       <BLANKLINE>
+       """
+    output = []
+    for piece in DocTestParser().parse(s):
+        if isinstance(piece, Example):
+            # Add the example's source code (strip trailing NL)
+            output.append(piece.source[:-1])
+            # Add the expected output:
+            want = piece.want
+            if want:
+                output.append('# Expected:')
+                output += ['## '+l for l in want.split('\n')[:-1]]
+        else:
+            # Add non-example text.
+            output += [_comment_line(l)
+                       for l in piece.split('\n')[:-1]]
+
+    # Trim junk on both ends.
+    while output and output[-1] == '#':
+        output.pop()
+    while output and output[0] == '#':
+        output.pop(0)
+    # Combine the output, and return it.
+    # Add a courtesy newline to prevent exec from choking (see bug #1172785)
+    return '\n'.join(output) + '\n'
+
+def testsource(module, name):
+    """Extract the test sources from a doctest docstring as a script.
+
+    Provide the module (or dotted name of the module) containing the
+    test to be debugged and the name (within the module) of the object
+    with the doc string with tests to be debugged.
+    """
+    module = _normalize_module(module)
+    tests = DocTestFinder().find(module)
+    test = [t for t in tests if t.name == name]
+    if not test:
+        raise ValueError(name, "not found in tests")
+    test = test[0]
+    testsrc = script_from_examples(test.docstring)
+    return testsrc
+
+def debug_src(src, pm=False, globs=None):
+    """Debug a single doctest docstring, in argument `src`'"""
+    testsrc = script_from_examples(src)
+    debug_script(testsrc, pm, globs)
+
+def debug_script(src, pm=False, globs=None):
+    "Debug a test script.  `src` is the script, as a string."
+    import pdb
+
+    # Note that tempfile.NameTemporaryFile() cannot be used.  As the
+    # docs say, a file so created cannot be opened by name a second time
+    # on modern Windows boxes, and execfile() needs to open it.
+    srcfilename = tempfile.mktemp(".py", "doctestdebug")
+    f = open(srcfilename, 'w')
+    f.write(src)
+    f.close()
+
+    try:
+        if globs:
+            globs = globs.copy()
+        else:
+            globs = {}
+
+        if pm:
+            try:
+                execfile(srcfilename, globs, globs)
+            except:
+                print sys.exc_info()[1]
+                pdb.post_mortem(sys.exc_info()[2])
+        else:
+            # Note that %r is vital here.  '%s' instead can, e.g., cause
+            # backslashes to get treated as metacharacters on Windows.
+            pdb.run("execfile(%r)" % srcfilename, globs, globs)
+
+    finally:
+        os.remove(srcfilename)
+
+def debug(module, name, pm=False):
+    """Debug a single doctest docstring.
+
+    Provide the module (or dotted name of the module) containing the
+    test to be debugged and the name (within the module) of the object
+    with the docstring with tests to be debugged.
+    """
+    module = _normalize_module(module)
+    testsrc = testsource(module, name)
+    debug_script(testsrc, pm, module.__dict__)
+
+######################################################################
+## 10. Example Usage
+######################################################################
+class _TestClass:
+    """
+    A pointless class, for sanity-checking of docstring testing.
+
+    Methods:
+        square()
+        get()
+
+    >>> _TestClass(13).get() + _TestClass(-12).get()
+    1
+    >>> hex(_TestClass(13).square().get())
+    '0xa9'
+    """
+
+    def __init__(self, val):
+        """val -> _TestClass object with associated value val.
+
+        >>> t = _TestClass(123)
+        >>> print t.get()
+        123
+        """
+
+        self.val = val
+
+    def square(self):
+        """square() -> square TestClass's associated value
+
+        >>> _TestClass(13).square().get()
+        169
+        """
+
+        self.val = self.val ** 2
+        return self
+
+    def get(self):
+        """get() -> return TestClass's associated value.
+
+        >>> x = _TestClass(-42)
+        >>> print x.get()
+        -42
+        """
+
+        return self.val
+
+__test__ = {"_TestClass": _TestClass,
+            "string": r"""
+                      Example of a string object, searched as-is.
+                      >>> x = 1; y = 2
+                      >>> x + y, x * y
+                      (3, 2)
+                      """,
+
+            "bool-int equivalence": r"""
+                                    In 2.2, boolean expressions displayed
+                                    0 or 1.  By default, we still accept
+                                    them.  This can be disabled by passing
+                                    DONT_ACCEPT_TRUE_FOR_1 to the new
+                                    optionflags argument.
+                                    >>> 4 == 4
+                                    1
+                                    >>> 4 == 4
+                                    True
+                                    >>> 4 > 4
+                                    0
+                                    >>> 4 > 4
+                                    False
+                                    """,
+
+            "blank lines": r"""
+                Blank lines can be marked with <BLANKLINE>:
+                    >>> print 'foo\n\nbar\n'
+                    foo
+                    <BLANKLINE>
+                    bar
+                    <BLANKLINE>
+            """,
+
+            "ellipsis": r"""
+                If the ellipsis flag is used, then '...' can be used to
+                elide substrings in the desired output:
+                    >>> print range(1000) #doctest: +ELLIPSIS
+                    [0, 1, 2, ..., 999]
+            """,
+
+            "whitespace normalization": r"""
+                If the whitespace normalization flag is used, then
+                differences in whitespace are ignored.
+                    >>> print range(30) #doctest: +NORMALIZE_WHITESPACE
+                    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+                     15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
+                     27, 28, 29]
+            """,
+           }
+
+def _test():
+    r = unittest.TextTestRunner()
+    r.run(DocTestSuite())
+
+if __name__ == "__main__":
+    _test()

Added: vendor/Python/current/Lib/dumbdbm.py
===================================================================
--- vendor/Python/current/Lib/dumbdbm.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/dumbdbm.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,233 @@
+"""A dumb and slow but simple dbm clone.
+
+For database spam, spam.dir contains the index (a text file),
+spam.bak *may* contain a backup of the index (also a text file),
+while spam.dat contains the data (a binary file).
+
+XXX TO DO:
+
+- seems to contain a bug when updating...
+
+- reclaim free space (currently, space once occupied by deleted or expanded
+items is never reused)
+
+- support concurrent access (currently, if two processes take turns making
+updates, they can mess up the index)
+
+- support efficient access to large databases (currently, the whole index
+is read when the database is opened, and some updates rewrite the whole index)
+
+- support opening for read-only (flag = 'm')
+
+"""
+
+import os as _os
+import __builtin__
+import UserDict
+
+_open = __builtin__.open
+
+_BLOCKSIZE = 512
+
+error = IOError                         # For anydbm
+
+class _Database(UserDict.DictMixin):
+
+    # The on-disk directory and data files can remain in mutually
+    # inconsistent states for an arbitrarily long time (see comments
+    # at the end of __setitem__).  This is only repaired when _commit()
+    # gets called.  One place _commit() gets called is from __del__(),
+    # and if that occurs at program shutdown time, module globals may
+    # already have gotten rebound to None.  Since it's crucial that
+    # _commit() finish successfully, we can't ignore shutdown races
+    # here, and _commit() must not reference any globals.
+    _os = _os       # for _commit()
+    _open = _open   # for _commit()
+
+    def __init__(self, filebasename, mode):
+        self._mode = mode
+
+        # The directory file is a text file.  Each line looks like
+        #    "%r, (%d, %d)\n" % (key, pos, siz)
+        # where key is the string key, pos is the offset into the dat
+        # file of the associated value's first byte, and siz is the number
+        # of bytes in the associated value.
+        self._dirfile = filebasename + _os.extsep + 'dir'
+
+        # The data file is a binary file pointed into by the directory
+        # file, and holds the values associated with keys.  Each value
+        # begins at a _BLOCKSIZE-aligned byte offset, and is a raw
+        # binary 8-bit string value.
+        self._datfile = filebasename + _os.extsep + 'dat'
+        self._bakfile = filebasename + _os.extsep + 'bak'
+
+        # The index is an in-memory dict, mirroring the directory file.
+        self._index = None  # maps keys to (pos, siz) pairs
+
+        # Mod by Jack: create data file if needed
+        try:
+            f = _open(self._datfile, 'r')
+        except IOError:
+            f = _open(self._datfile, 'w', self._mode)
+        f.close()
+        self._update()
+
+    # Read directory file into the in-memory index dict.
+    def _update(self):
+        self._index = {}
+        try:
+            f = _open(self._dirfile)
+        except IOError:
+            pass
+        else:
+            for line in f:
+                line = line.rstrip()
+                key, pos_and_siz_pair = eval(line)
+                self._index[key] = pos_and_siz_pair
+            f.close()
+
+    # Write the index dict to the directory file.  The original directory
+    # file (if any) is renamed with a .bak extension first.  If a .bak
+    # file currently exists, it's deleted.
+    def _commit(self):
+        # CAUTION:  It's vital that _commit() succeed, and _commit() can
+        # be called from __del__().  Therefore we must never reference a
+        # global in this routine.
+        if self._index is None:
+            return  # nothing to do
+
+        try:
+            self._os.unlink(self._bakfile)
+        except self._os.error:
+            pass
+
+        try:
+            self._os.rename(self._dirfile, self._bakfile)
+        except self._os.error:
+            pass
+
+        f = self._open(self._dirfile, 'w', self._mode)
+        for key, pos_and_siz_pair in self._index.iteritems():
+            f.write("%r, %r\n" % (key, pos_and_siz_pair))
+        f.close()
+
+    sync = _commit
+
+    def __getitem__(self, key):
+        pos, siz = self._index[key]     # may raise KeyError
+        f = _open(self._datfile, 'rb')
+        f.seek(pos)
+        dat = f.read(siz)
+        f.close()
+        return dat
+
+    # Append val to the data file, starting at a _BLOCKSIZE-aligned
+    # offset.  The data file is first padded with NUL bytes (if needed)
+    # to get to an aligned offset.  Return pair
+    #     (starting offset of val, len(val))
+    def _addval(self, val):
+        f = _open(self._datfile, 'rb+')
+        f.seek(0, 2)
+        pos = int(f.tell())
+        npos = ((pos + _BLOCKSIZE - 1) // _BLOCKSIZE) * _BLOCKSIZE
+        f.write('\0'*(npos-pos))
+        pos = npos
+        f.write(val)
+        f.close()
+        return (pos, len(val))
+
+    # Write val to the data file, starting at offset pos.  The caller
+    # is responsible for ensuring that there's enough room starting at
+    # pos to hold val, without overwriting some other value.  Return
+    # pair (pos, len(val)).
+    def _setval(self, pos, val):
+        f = _open(self._datfile, 'rb+')
+        f.seek(pos)
+        f.write(val)
+        f.close()
+        return (pos, len(val))
+
+    # key is a new key whose associated value starts in the data file
+    # at offset pos and with length siz.  Add an index record to
+    # the in-memory index dict, and append one to the directory file.
+    def _addkey(self, key, pos_and_siz_pair):
+        self._index[key] = pos_and_siz_pair
+        f = _open(self._dirfile, 'a', self._mode)
+        f.write("%r, %r\n" % (key, pos_and_siz_pair))
+        f.close()
+
+    def __setitem__(self, key, val):
+        if not type(key) == type('') == type(val):
+            raise TypeError, "keys and values must be strings"
+        if key not in self._index:
+            self._addkey(key, self._addval(val))
+        else:
+            # See whether the new value is small enough to fit in the
+            # (padded) space currently occupied by the old value.
+            pos, siz = self._index[key]
+            oldblocks = (siz + _BLOCKSIZE - 1) // _BLOCKSIZE
+            newblocks = (len(val) + _BLOCKSIZE - 1) // _BLOCKSIZE
+            if newblocks <= oldblocks:
+                self._index[key] = self._setval(pos, val)
+            else:
+                # The new value doesn't fit in the (padded) space used
+                # by the old value.  The blocks used by the old value are
+                # forever lost.
+                self._index[key] = self._addval(val)
+
+            # Note that _index may be out of synch with the directory
+            # file now:  _setval() and _addval() don't update the directory
+            # file.  This also means that the on-disk directory and data
+            # files are in a mutually inconsistent state, and they'll
+            # remain that way until _commit() is called.  Note that this
+            # is a disaster (for the database) if the program crashes
+            # (so that _commit() never gets called).
+
+    def __delitem__(self, key):
+        # The blocks used by the associated value are lost.
+        del self._index[key]
+        # XXX It's unclear why we do a _commit() here (the code always
+        # XXX has, so I'm not changing it).  _setitem__ doesn't try to
+        # XXX keep the directory file in synch.  Why should we?  Or
+        # XXX why shouldn't __setitem__?
+        self._commit()
+
+    def keys(self):
+        return self._index.keys()
+
+    def has_key(self, key):
+        return key in self._index
+
+    def __contains__(self, key):
+        return key in self._index
+
+    def iterkeys(self):
+        return self._index.iterkeys()
+    __iter__ = iterkeys
+
+    def __len__(self):
+        return len(self._index)
+
+    def close(self):
+        self._commit()
+        self._index = self._datfile = self._dirfile = self._bakfile = None
+
+    __del__ = close
+
+
+
+def open(file, flag=None, mode=0666):
+    """Open the database file, filename, and return corresponding object.
+
+    The flag argument, used to control how the database is opened in the
+    other DBM implementations, is ignored in the dumbdbm module; the
+    database is always opened for update, and will be created if it does
+    not exist.
+
+    The optional mode argument is the UNIX mode of the file, used only when
+    the database has to be created.  It defaults to octal code 0666 (and
+    will be modified by the prevailing umask).
+
+    """
+    # flag argument is currently ignored
+    return _Database(file, mode)

Added: vendor/Python/current/Lib/dummy_thread.py
===================================================================
--- vendor/Python/current/Lib/dummy_thread.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/dummy_thread.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,152 @@
+"""Drop-in replacement for the thread module.
+
+Meant to be used as a brain-dead substitute so that threaded code does
+not need to be rewritten for when the thread module is not present.
+
+Suggested usage is::
+
+    try:
+        import thread
+    except ImportError:
+        import dummy_thread as thread
+
+"""
+__author__ = "Brett Cannon"
+__email__ = "brett at python.org"
+
+# Exports only things specified by thread documentation
+# (skipping obsolete synonyms allocate(), start_new(), exit_thread())
+__all__ = ['error', 'start_new_thread', 'exit', 'get_ident', 'allocate_lock',
+           'interrupt_main', 'LockType']
+
+import traceback as _traceback
+import warnings
+
+class error(Exception):
+    """Dummy implementation of thread.error."""
+
+    def __init__(self, *args):
+        self.args = args
+
+def start_new_thread(function, args, kwargs={}):
+    """Dummy implementation of thread.start_new_thread().
+
+    Compatibility is maintained by making sure that ``args`` is a
+    tuple and ``kwargs`` is a dictionary.  If an exception is raised
+    and it is SystemExit (which can be done by thread.exit()) it is
+    caught and nothing is done; all other exceptions are printed out
+    by using traceback.print_exc().
+
+    If the executed function calls interrupt_main the KeyboardInterrupt will be
+    raised when the function returns.
+
+    """
+    if type(args) != type(tuple()):
+        raise TypeError("2nd arg must be a tuple")
+    if type(kwargs) != type(dict()):
+        raise TypeError("3rd arg must be a dict")
+    global _main
+    _main = False
+    try:
+        function(*args, **kwargs)
+    except SystemExit:
+        pass
+    except:
+        _traceback.print_exc()
+    _main = True
+    global _interrupt
+    if _interrupt:
+        _interrupt = False
+        raise KeyboardInterrupt
+
+def exit():
+    """Dummy implementation of thread.exit()."""
+    raise SystemExit
+
+def get_ident():
+    """Dummy implementation of thread.get_ident().
+
+    Since this module should only be used when threadmodule is not
+    available, it is safe to assume that the current process is the
+    only thread.  Thus a constant can be safely returned.
+    """
+    return -1
+
+def allocate_lock():
+    """Dummy implementation of thread.allocate_lock()."""
+    return LockType()
+
+def stack_size(size=None):
+    """Dummy implementation of thread.stack_size()."""
+    if size is not None:
+        raise error("setting thread stack size not supported")
+    return 0
+
+class LockType(object):
+    """Class implementing dummy implementation of thread.LockType.
+
+    Compatibility is maintained by maintaining self.locked_status
+    which is a boolean that stores the state of the lock.  Pickling of
+    the lock, though, should not be done since if the thread module is
+    then used with an unpickled ``lock()`` from here problems could
+    occur from this class not having atomic methods.
+
+    """
+
+    def __init__(self):
+        self.locked_status = False
+
+    def acquire(self, waitflag=None):
+        """Dummy implementation of acquire().
+
+        For blocking calls, self.locked_status is automatically set to
+        True and returned appropriately based on value of
+        ``waitflag``.  If it is non-blocking, then the value is
+        actually checked and not set if it is already acquired.  This
+        is all done so that threading.Condition's assert statements
+        aren't triggered and throw a little fit.
+
+        """
+        if waitflag is None:
+            self.locked_status = True
+            return None
+        elif not waitflag:
+            if not self.locked_status:
+                self.locked_status = True
+                return True
+            else:
+                return False
+        else:
+            self.locked_status = True
+            return True
+
+    __enter__ = acquire
+
+    def __exit__(self, typ, val, tb):
+        self.release()
+
+    def release(self):
+        """Release the dummy lock."""
+        # XXX Perhaps shouldn't actually bother to test?  Could lead
+        #     to problems for complex, threaded code.
+        if not self.locked_status:
+            raise error
+        self.locked_status = False
+        return True
+
+    def locked(self):
+        return self.locked_status
+
+# Used to signal that interrupt_main was called in a "thread"
+_interrupt = False
+# True when not executing in a "thread"
+_main = True
+
+def interrupt_main():
+    """Set _interrupt flag to True to have start_new_thread raise
+    KeyboardInterrupt upon exiting."""
+    if _main:
+        raise KeyboardInterrupt
+    else:
+        global _interrupt
+        _interrupt = True

Added: vendor/Python/current/Lib/dummy_threading.py
===================================================================
--- vendor/Python/current/Lib/dummy_threading.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/dummy_threading.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,83 @@
+"""Faux ``threading`` version using ``dummy_thread`` instead of ``thread``.
+
+The module ``_dummy_threading`` is added to ``sys.modules`` in order
+to not have ``threading`` considered imported.  Had ``threading`` been
+directly imported it would have made all subsequent imports succeed
+regardless of whether ``thread`` was available which is not desired.
+
+:Author: Brett Cannon
+:Contact: brett at python.org
+
+XXX: Try to get rid of ``_dummy_threading``.
+
+"""
+from sys import modules as sys_modules
+
+import dummy_thread
+
+# Declaring now so as to not have to nest ``try``s to get proper clean-up.
+holding_thread = False
+holding_threading = False
+holding__threading_local = False
+
+try:
+    # Could have checked if ``thread`` was not in sys.modules and gone
+    # a different route, but decided to mirror technique used with
+    # ``threading`` below.
+    if 'thread' in sys_modules:
+        held_thread = sys_modules['thread']
+        holding_thread = True
+    # Must have some module named ``thread`` that implements its API
+    # in order to initially import ``threading``.
+    sys_modules['thread'] = sys_modules['dummy_thread']
+
+    if 'threading' in sys_modules:
+        # If ``threading`` is already imported, might as well prevent
+        # trying to import it more than needed by saving it if it is
+        # already imported before deleting it.
+        held_threading = sys_modules['threading']
+        holding_threading = True
+        del sys_modules['threading']
+
+    if '_threading_local' in sys_modules:
+        # If ``_threading_local`` is already imported, might as well prevent
+        # trying to import it more than needed by saving it if it is
+        # already imported before deleting it.
+        held__threading_local = sys_modules['_threading_local']
+        holding__threading_local = True
+        del sys_modules['_threading_local']
+
+    import threading
+    # Need a copy of the code kept somewhere...
+    sys_modules['_dummy_threading'] = sys_modules['threading']
+    del sys_modules['threading']
+    sys_modules['_dummy__threading_local'] = sys_modules['_threading_local']
+    del sys_modules['_threading_local']
+    from _dummy_threading import *
+    from _dummy_threading import __all__
+
+finally:
+    # Put back ``threading`` if we overwrote earlier
+
+    if holding_threading:
+        sys_modules['threading'] = held_threading
+        del held_threading
+    del holding_threading
+
+    # Put back ``_threading_local`` if we overwrote earlier
+
+    if holding__threading_local:
+        sys_modules['_threading_local'] = held__threading_local
+        del held__threading_local
+    del holding__threading_local
+
+    # Put back ``thread`` if we overwrote, else del the entry we made
+    if holding_thread:
+        sys_modules['thread'] = held_thread
+        del held_thread
+    else:
+        del sys_modules['thread']
+    del holding_thread
+
+    del dummy_thread
+    del sys_modules

Added: vendor/Python/current/Lib/email/__init__.py
===================================================================
--- vendor/Python/current/Lib/email/__init__.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/__init__.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,123 @@
+# Copyright (C) 2001-2006 Python Software Foundation
+# Author: Barry Warsaw
+# Contact: email-sig at python.org
+
+"""A package for parsing, handling, and generating email messages."""
+
+__version__ = '4.0.1'
+
+__all__ = [
+    # Old names
+    'base64MIME',
+    'Charset',
+    'Encoders',
+    'Errors',
+    'Generator',
+    'Header',
+    'Iterators',
+    'Message',
+    'MIMEAudio',
+    'MIMEBase',
+    'MIMEImage',
+    'MIMEMessage',
+    'MIMEMultipart',
+    'MIMENonMultipart',
+    'MIMEText',
+    'Parser',
+    'quopriMIME',
+    'Utils',
+    'message_from_string',
+    'message_from_file',
+    # new names
+    'base64mime',
+    'charset',
+    'encoders',
+    'errors',
+    'generator',
+    'header',
+    'iterators',
+    'message',
+    'mime',
+    'parser',
+    'quoprimime',
+    'utils',
+    ]
+
+
+
+# Some convenience routines.  Don't import Parser and Message as side-effects
+# of importing email since those cascadingly import most of the rest of the
+# email package.
+def message_from_string(s, *args, **kws):
+    """Parse a string into a Message object model.
+
+    Optional _class and strict are passed to the Parser constructor.
+    """
+    from email.parser import Parser
+    return Parser(*args, **kws).parsestr(s)
+
+
+def message_from_file(fp, *args, **kws):
+    """Read a file and parse its contents into a Message object model.
+
+    Optional _class and strict are passed to the Parser constructor.
+    """
+    from email.parser import Parser
+    return Parser(*args, **kws).parse(fp)
+
+
+
+# Lazy loading to provide name mapping from new-style names (PEP 8 compatible
+# email 4.0 module names), to old-style names (email 3.0 module names).
+import sys
+
+class LazyImporter(object):
+    def __init__(self, module_name):
+        self.__name__ = 'email.' + module_name
+
+    def __getattr__(self, name):
+        __import__(self.__name__)
+        mod = sys.modules[self.__name__]
+        self.__dict__.update(mod.__dict__)
+        return getattr(mod, name)
+
+
+_LOWERNAMES = [
+    # email.<old name> -> email.<new name is lowercased old name>
+    'Charset',
+    'Encoders',
+    'Errors',
+    'FeedParser',
+    'Generator',
+    'Header',
+    'Iterators',
+    'Message',
+    'Parser',
+    'Utils',
+    'base64MIME',
+    'quopriMIME',
+    ]
+
+_MIMENAMES = [
+    # email.MIME<old name> -> email.mime.<new name is lowercased old name>
+    'Audio',
+    'Base',
+    'Image',
+    'Message',
+    'Multipart',
+    'NonMultipart',
+    'Text',
+    ]
+
+for _name in _LOWERNAMES:
+    importer = LazyImporter(_name.lower())
+    sys.modules['email.' + _name] = importer
+    setattr(sys.modules['email'], _name, importer)
+
+
+import email.mime
+for _name in _MIMENAMES:
+    importer = LazyImporter('mime.' + _name.lower())
+    sys.modules['email.MIME' + _name] = importer
+    setattr(sys.modules['email'], 'MIME' + _name, importer)
+    setattr(sys.modules['email.mime'], _name, importer)

Added: vendor/Python/current/Lib/email/_parseaddr.py
===================================================================
--- vendor/Python/current/Lib/email/_parseaddr.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/_parseaddr.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,480 @@
+# Copyright (C) 2002-2007 Python Software Foundation
+# Contact: email-sig at python.org
+
+"""Email address parsing code.
+
+Lifted directly from rfc822.py.  This should eventually be rewritten.
+"""
+
+__all__ = [
+    'mktime_tz',
+    'parsedate',
+    'parsedate_tz',
+    'quote',
+    ]
+
+import time
+
+SPACE = ' '
+EMPTYSTRING = ''
+COMMASPACE = ', '
+
+# Parse a date field
+_monthnames = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul',
+               'aug', 'sep', 'oct', 'nov', 'dec',
+               'january', 'february', 'march', 'april', 'may', 'june', 'july',
+               'august', 'september', 'october', 'november', 'december']
+
+_daynames = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun']
+
+# The timezone table does not include the military time zones defined
+# in RFC822, other than Z.  According to RFC1123, the description in
+# RFC822 gets the signs wrong, so we can't rely on any such time
+# zones.  RFC1123 recommends that numeric timezone indicators be used
+# instead of timezone names.
+
+_timezones = {'UT':0, 'UTC':0, 'GMT':0, 'Z':0,
+              'AST': -400, 'ADT': -300,  # Atlantic (used in Canada)
+              'EST': -500, 'EDT': -400,  # Eastern
+              'CST': -600, 'CDT': -500,  # Central
+              'MST': -700, 'MDT': -600,  # Mountain
+              'PST': -800, 'PDT': -700   # Pacific
+              }
+
+
+def parsedate_tz(data):
+    """Convert a date string to a time tuple.
+
+    Accounts for military timezones.
+    """
+    data = data.split()
+    # The FWS after the comma after the day-of-week is optional, so search and
+    # adjust for this.
+    if data[0].endswith(',') or data[0].lower() in _daynames:
+        # There's a dayname here. Skip it
+        del data[0]
+    else:
+        i = data[0].rfind(',')
+        if i >= 0:
+            data[0] = data[0][i+1:]
+    if len(data) == 3: # RFC 850 date, deprecated
+        stuff = data[0].split('-')
+        if len(stuff) == 3:
+            data = stuff + data[1:]
+    if len(data) == 4:
+        s = data[3]
+        i = s.find('+')
+        if i > 0:
+            data[3:] = [s[:i], s[i+1:]]
+        else:
+            data.append('') # Dummy tz
+    if len(data) < 5:
+        return None
+    data = data[:5]
+    [dd, mm, yy, tm, tz] = data
+    mm = mm.lower()
+    if mm not in _monthnames:
+        dd, mm = mm, dd.lower()
+        if mm not in _monthnames:
+            return None
+    mm = _monthnames.index(mm) + 1
+    if mm > 12:
+        mm -= 12
+    if dd[-1] == ',':
+        dd = dd[:-1]
+    i = yy.find(':')
+    if i > 0:
+        yy, tm = tm, yy
+    if yy[-1] == ',':
+        yy = yy[:-1]
+    if not yy[0].isdigit():
+        yy, tz = tz, yy
+    if tm[-1] == ',':
+        tm = tm[:-1]
+    tm = tm.split(':')
+    if len(tm) == 2:
+        [thh, tmm] = tm
+        tss = '0'
+    elif len(tm) == 3:
+        [thh, tmm, tss] = tm
+    else:
+        return None
+    try:
+        yy = int(yy)
+        dd = int(dd)
+        thh = int(thh)
+        tmm = int(tmm)
+        tss = int(tss)
+    except ValueError:
+        return None
+    tzoffset = None
+    tz = tz.upper()
+    if _timezones.has_key(tz):
+        tzoffset = _timezones[tz]
+    else:
+        try:
+            tzoffset = int(tz)
+        except ValueError:
+            pass
+    # Convert a timezone offset into seconds ; -0500 -> -18000
+    if tzoffset:
+        if tzoffset < 0:
+            tzsign = -1
+            tzoffset = -tzoffset
+        else:
+            tzsign = 1
+        tzoffset = tzsign * ( (tzoffset//100)*3600 + (tzoffset % 100)*60)
+    # Daylight Saving Time flag is set to -1, since DST is unknown.
+    return yy, mm, dd, thh, tmm, tss, 0, 1, -1, tzoffset
+
+
+def parsedate(data):
+    """Convert a time string to a time tuple."""
+    t = parsedate_tz(data)
+    if isinstance(t, tuple):
+        return t[:9]
+    else:
+        return t
+
+
+def mktime_tz(data):
+    """Turn a 10-tuple as returned by parsedate_tz() into a UTC timestamp."""
+    if data[9] is None:
+        # No zone info, so localtime is better assumption than GMT
+        return time.mktime(data[:8] + (-1,))
+    else:
+        t = time.mktime(data[:8] + (0,))
+        return t - data[9] - time.timezone
+
+
+def quote(str):
+    """Add quotes around a string."""
+    return str.replace('\\', '\\\\').replace('"', '\\"')
+
+
+class AddrlistClass:
+    """Address parser class by Ben Escoto.
+
+    To understand what this class does, it helps to have a copy of RFC 2822 in
+    front of you.
+
+    Note: this class interface is deprecated and may be removed in the future.
+    Use rfc822.AddressList instead.
+    """
+
+    def __init__(self, field):
+        """Initialize a new instance.
+
+        `field' is an unparsed address header field, containing
+        one or more addresses.
+        """
+        self.specials = '()<>@,:;.\"[]'
+        self.pos = 0
+        self.LWS = ' \t'
+        self.CR = '\r\n'
+        self.FWS = self.LWS + self.CR
+        self.atomends = self.specials + self.LWS + self.CR
+        # Note that RFC 2822 now specifies `.' as obs-phrase, meaning that it
+        # is obsolete syntax.  RFC 2822 requires that we recognize obsolete
+        # syntax, so allow dots in phrases.
+        self.phraseends = self.atomends.replace('.', '')
+        self.field = field
+        self.commentlist = []
+
+    def gotonext(self):
+        """Parse up to the start of the next address."""
+        while self.pos < len(self.field):
+            if self.field[self.pos] in self.LWS + '\n\r':
+                self.pos += 1
+            elif self.field[self.pos] == '(':
+                self.commentlist.append(self.getcomment())
+            else:
+                break
+
+    def getaddrlist(self):
+        """Parse all addresses.
+
+        Returns a list containing all of the addresses.
+        """
+        result = []
+        while self.pos < len(self.field):
+            ad = self.getaddress()
+            if ad:
+                result += ad
+            else:
+                result.append(('', ''))
+        return result
+
+    def getaddress(self):
+        """Parse the next address."""
+        self.commentlist = []
+        self.gotonext()
+
+        oldpos = self.pos
+        oldcl = self.commentlist
+        plist = self.getphraselist()
+
+        self.gotonext()
+        returnlist = []
+
+        if self.pos >= len(self.field):
+            # Bad email address technically, no domain.
+            if plist:
+                returnlist = [(SPACE.join(self.commentlist), plist[0])]
+
+        elif self.field[self.pos] in '.@':
+            # email address is just an addrspec
+            # this isn't very efficient since we start over
+            self.pos = oldpos
+            self.commentlist = oldcl
+            addrspec = self.getaddrspec()
+            returnlist = [(SPACE.join(self.commentlist), addrspec)]
+
+        elif self.field[self.pos] == ':':
+            # address is a group
+            returnlist = []
+
+            fieldlen = len(self.field)
+            self.pos += 1
+            while self.pos < len(self.field):
+                self.gotonext()
+                if self.pos < fieldlen and self.field[self.pos] == ';':
+                    self.pos += 1
+                    break
+                returnlist = returnlist + self.getaddress()
+
+        elif self.field[self.pos] == '<':
+            # Address is a phrase then a route addr
+            routeaddr = self.getrouteaddr()
+
+            if self.commentlist:
+                returnlist = [(SPACE.join(plist) + ' (' +
+                               ' '.join(self.commentlist) + ')', routeaddr)]
+            else:
+                returnlist = [(SPACE.join(plist), routeaddr)]
+
+        else:
+            if plist:
+                returnlist = [(SPACE.join(self.commentlist), plist[0])]
+            elif self.field[self.pos] in self.specials:
+                self.pos += 1
+
+        self.gotonext()
+        if self.pos < len(self.field) and self.field[self.pos] == ',':
+            self.pos += 1
+        return returnlist
+
+    def getrouteaddr(self):
+        """Parse a route address (Return-path value).
+
+        This method just skips all the route stuff and returns the addrspec.
+        """
+        if self.field[self.pos] != '<':
+            return
+
+        expectroute = False
+        self.pos += 1
+        self.gotonext()
+        adlist = ''
+        while self.pos < len(self.field):
+            if expectroute:
+                self.getdomain()
+                expectroute = False
+            elif self.field[self.pos] == '>':
+                self.pos += 1
+                break
+            elif self.field[self.pos] == '@':
+                self.pos += 1
+                expectroute = True
+            elif self.field[self.pos] == ':':
+                self.pos += 1
+            else:
+                adlist = self.getaddrspec()
+                self.pos += 1
+                break
+            self.gotonext()
+
+        return adlist
+
+    def getaddrspec(self):
+        """Parse an RFC 2822 addr-spec."""
+        aslist = []
+
+        self.gotonext()
+        while self.pos < len(self.field):
+            if self.field[self.pos] == '.':
+                aslist.append('.')
+                self.pos += 1
+            elif self.field[self.pos] == '"':
+                aslist.append('"%s"' % self.getquote())
+            elif self.field[self.pos] in self.atomends:
+                break
+            else:
+                aslist.append(self.getatom())
+            self.gotonext()
+
+        if self.pos >= len(self.field) or self.field[self.pos] != '@':
+            return EMPTYSTRING.join(aslist)
+
+        aslist.append('@')
+        self.pos += 1
+        self.gotonext()
+        return EMPTYSTRING.join(aslist) + self.getdomain()
+
+    def getdomain(self):
+        """Get the complete domain name from an address."""
+        sdlist = []
+        while self.pos < len(self.field):
+            if self.field[self.pos] in self.LWS:
+                self.pos += 1
+            elif self.field[self.pos] == '(':
+                self.commentlist.append(self.getcomment())
+            elif self.field[self.pos] == '[':
+                sdlist.append(self.getdomainliteral())
+            elif self.field[self.pos] == '.':
+                self.pos += 1
+                sdlist.append('.')
+            elif self.field[self.pos] in self.atomends:
+                break
+            else:
+                sdlist.append(self.getatom())
+        return EMPTYSTRING.join(sdlist)
+
+    def getdelimited(self, beginchar, endchars, allowcomments=True):
+        """Parse a header fragment delimited by special characters.
+
+        `beginchar' is the start character for the fragment.
+        If self is not looking at an instance of `beginchar' then
+        getdelimited returns the empty string.
+
+        `endchars' is a sequence of allowable end-delimiting characters.
+        Parsing stops when one of these is encountered.
+
+        If `allowcomments' is non-zero, embedded RFC 2822 comments are allowed
+        within the parsed fragment.
+        """
+        if self.field[self.pos] != beginchar:
+            return ''
+
+        slist = ['']
+        quote = False
+        self.pos += 1
+        while self.pos < len(self.field):
+            if quote:
+                slist.append(self.field[self.pos])
+                quote = False
+            elif self.field[self.pos] in endchars:
+                self.pos += 1
+                break
+            elif allowcomments and self.field[self.pos] == '(':
+                slist.append(self.getcomment())
+                continue        # have already advanced pos from getcomment
+            elif self.field[self.pos] == '\\':
+                quote = True
+            else:
+                slist.append(self.field[self.pos])
+            self.pos += 1
+
+        return EMPTYSTRING.join(slist)
+
+    def getquote(self):
+        """Get a quote-delimited fragment from self's field."""
+        return self.getdelimited('"', '"\r', False)
+
+    def getcomment(self):
+        """Get a parenthesis-delimited fragment from self's field."""
+        return self.getdelimited('(', ')\r', True)
+
+    def getdomainliteral(self):
+        """Parse an RFC 2822 domain-literal."""
+        return '[%s]' % self.getdelimited('[', ']\r', False)
+
+    def getatom(self, atomends=None):
+        """Parse an RFC 2822 atom.
+
+        Optional atomends specifies a different set of end token delimiters
+        (the default is to use self.atomends).  This is used e.g. in
+        getphraselist() since phrase endings must not include the `.' (which
+        is legal in phrases)."""
+        atomlist = ['']
+        if atomends is None:
+            atomends = self.atomends
+
+        while self.pos < len(self.field):
+            if self.field[self.pos] in atomends:
+                break
+            else:
+                atomlist.append(self.field[self.pos])
+            self.pos += 1
+
+        return EMPTYSTRING.join(atomlist)
+
+    def getphraselist(self):
+        """Parse a sequence of RFC 2822 phrases.
+
+        A phrase is a sequence of words, which are in turn either RFC 2822
+        atoms or quoted-strings.  Phrases are canonicalized by squeezing all
+        runs of continuous whitespace into one space.
+        """
+        plist = []
+
+        while self.pos < len(self.field):
+            if self.field[self.pos] in self.FWS:
+                self.pos += 1
+            elif self.field[self.pos] == '"':
+                plist.append(self.getquote())
+            elif self.field[self.pos] == '(':
+                self.commentlist.append(self.getcomment())
+            elif self.field[self.pos] in self.phraseends:
+                break
+            else:
+                plist.append(self.getatom(self.phraseends))
+
+        return plist
+
+class AddressList(AddrlistClass):
+    """An AddressList encapsulates a list of parsed RFC 2822 addresses."""
+    def __init__(self, field):
+        AddrlistClass.__init__(self, field)
+        if field:
+            self.addresslist = self.getaddrlist()
+        else:
+            self.addresslist = []
+
+    def __len__(self):
+        return len(self.addresslist)
+
+    def __add__(self, other):
+        # Set union
+        newaddr = AddressList(None)
+        newaddr.addresslist = self.addresslist[:]
+        for x in other.addresslist:
+            if not x in self.addresslist:
+                newaddr.addresslist.append(x)
+        return newaddr
+
+    def __iadd__(self, other):
+        # Set union, in-place
+        for x in other.addresslist:
+            if not x in self.addresslist:
+                self.addresslist.append(x)
+        return self
+
+    def __sub__(self, other):
+        # Set difference
+        newaddr = AddressList(None)
+        for x in self.addresslist:
+            if not x in other.addresslist:
+                newaddr.addresslist.append(x)
+        return newaddr
+
+    def __isub__(self, other):
+        # Set difference, in-place
+        for x in other.addresslist:
+            if x in self.addresslist:
+                self.addresslist.remove(x)
+        return self
+
+    def __getitem__(self, index):
+        # Make indexing, slices, and 'in' work
+        return self.addresslist[index]

Added: vendor/Python/current/Lib/email/base64mime.py
===================================================================
--- vendor/Python/current/Lib/email/base64mime.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/base64mime.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,184 @@
+# Copyright (C) 2002-2006 Python Software Foundation
+# Author: Ben Gertzfield
+# Contact: email-sig at python.org
+
+"""Base64 content transfer encoding per RFCs 2045-2047.
+
+This module handles the content transfer encoding method defined in RFC 2045
+to encode arbitrary 8-bit data using the three 8-bit bytes in four 7-bit
+characters encoding known as Base64.
+
+It is used in the MIME standards for email to attach images, audio, and text
+using some 8-bit character sets to messages.
+
+This module provides an interface to encode and decode both headers and bodies
+with Base64 encoding.
+
+RFC 2045 defines a method for including character set information in an
+`encoded-word' in a header.  This method is commonly used for 8-bit real names
+in To:, From:, Cc:, etc. fields, as well as Subject: lines.
+
+This module does not do the line wrapping or end-of-line character conversion
+necessary for proper internationalized headers; it only does dumb encoding and
+decoding.  To deal with the various line wrapping issues, use the email.Header
+module.
+"""
+
+__all__ = [
+    'base64_len',
+    'body_decode',
+    'body_encode',
+    'decode',
+    'decodestring',
+    'encode',
+    'encodestring',
+    'header_encode',
+    ]
+
+import re
+
+from binascii import b2a_base64, a2b_base64
+from email.utils import fix_eols
+
+CRLF = '\r\n'
+NL = '\n'
+EMPTYSTRING = ''
+
+# See also Charset.py
+MISC_LEN = 7
+
+
+
+# Helpers
+def base64_len(s):
+    """Return the length of s when it is encoded with base64."""
+    groups_of_3, leftover = divmod(len(s), 3)
+    # 4 bytes out for each 3 bytes (or nonzero fraction thereof) in.
+    # Thanks, Tim!
+    n = groups_of_3 * 4
+    if leftover:
+        n += 4
+    return n
+
+
+
+def header_encode(header, charset='iso-8859-1', keep_eols=False,
+                  maxlinelen=76, eol=NL):
+    """Encode a single header line with Base64 encoding in a given charset.
+
+    Defined in RFC 2045, this Base64 encoding is identical to normal Base64
+    encoding, except that each line must be intelligently wrapped (respecting
+    the Base64 encoding), and subsequent lines must start with a space.
+
+    charset names the character set to use to encode the header.  It defaults
+    to iso-8859-1.
+
+    End-of-line characters (\\r, \\n, \\r\\n) will be automatically converted
+    to the canonical email line separator \\r\\n unless the keep_eols
+    parameter is True (the default is False).
+
+    Each line of the header will be terminated in the value of eol, which
+    defaults to "\\n".  Set this to "\\r\\n" if you are using the result of
+    this function directly in email.
+
+    The resulting string will be in the form:
+
+    "=?charset?b?WW/5ciBtYXp66XLrIHf8eiBhIGhhbXBzdGHuciBBIFlv+XIgbWF6euly?=\\n
+      =?charset?b?6yB3/HogYSBoYW1wc3Rh7nIgQkMgWW/5ciBtYXp66XLrIHf8eiBhIGhh?="
+
+    with each line wrapped at, at most, maxlinelen characters (defaults to 76
+    characters).
+    """
+    # Return empty headers unchanged
+    if not header:
+        return header
+
+    if not keep_eols:
+        header = fix_eols(header)
+
+    # Base64 encode each line, in encoded chunks no greater than maxlinelen in
+    # length, after the RFC chrome is added in.
+    base64ed = []
+    max_encoded = maxlinelen - len(charset) - MISC_LEN
+    max_unencoded = max_encoded * 3 // 4
+
+    for i in range(0, len(header), max_unencoded):
+        base64ed.append(b2a_base64(header[i:i+max_unencoded]))
+
+    # Now add the RFC chrome to each encoded chunk
+    lines = []
+    for line in base64ed:
+        # Ignore the last character of each line if it is a newline
+        if line.endswith(NL):
+            line = line[:-1]
+        # Add the chrome
+        lines.append('=?%s?b?%s?=' % (charset, line))
+    # Glue the lines together and return it.  BAW: should we be able to
+    # specify the leading whitespace in the joiner?
+    joiner = eol + ' '
+    return joiner.join(lines)
+
+
+
+def encode(s, binary=True, maxlinelen=76, eol=NL):
+    """Encode a string with base64.
+
+    Each line will be wrapped at, at most, maxlinelen characters (defaults to
+    76 characters).
+
+    If binary is False, end-of-line characters will be converted to the
+    canonical email end-of-line sequence \\r\\n.  Otherwise they will be left
+    verbatim (this is the default).
+
+    Each line of encoded text will end with eol, which defaults to "\\n".  Set
+    this to "\r\n" if you will be using the result of this function directly
+    in an email.
+    """
+    if not s:
+        return s
+
+    if not binary:
+        s = fix_eols(s)
+
+    encvec = []
+    max_unencoded = maxlinelen * 3 // 4
+    for i in range(0, len(s), max_unencoded):
+        # BAW: should encode() inherit b2a_base64()'s dubious behavior in
+        # adding a newline to the encoded string?
+        enc = b2a_base64(s[i:i + max_unencoded])
+        if enc.endswith(NL) and eol <> NL:
+            enc = enc[:-1] + eol
+        encvec.append(enc)
+    return EMPTYSTRING.join(encvec)
+
+
+# For convenience and backwards compatibility w/ standard base64 module
+body_encode = encode
+encodestring = encode
+
+
+
+def decode(s, convert_eols=None):
+    """Decode a raw base64 string.
+
+    If convert_eols is set to a string value, all canonical email linefeeds,
+    e.g. "\\r\\n", in the decoded text will be converted to the value of
+    convert_eols.  os.linesep is a good choice for convert_eols if you are
+    decoding a text attachment.
+
+    This function does not parse a full MIME header value encoded with
+    base64 (like =?iso-8895-1?b?bmloISBuaWgh?=) -- please use the high
+    level email.Header class for that functionality.
+    """
+    if not s:
+        return s
+
+    dec = a2b_base64(s)
+    if convert_eols:
+        return dec.replace(CRLF, convert_eols)
+    return dec
+
+
+# For convenience and backwards compatibility w/ standard base64 module
+body_decode = decode
+decodestring = decode

Added: vendor/Python/current/Lib/email/charset.py
===================================================================
--- vendor/Python/current/Lib/email/charset.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/charset.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,388 @@
+# Copyright (C) 2001-2006 Python Software Foundation
+# Author: Ben Gertzfield, Barry Warsaw
+# Contact: email-sig at python.org
+
+__all__ = [
+    'Charset',
+    'add_alias',
+    'add_charset',
+    'add_codec',
+    ]
+
+import email.base64mime
+import email.quoprimime
+
+from email import errors
+from email.encoders import encode_7or8bit
+
+
+
+# Flags for types of header encodings
+QP          = 1 # Quoted-Printable
+BASE64      = 2 # Base64
+SHORTEST    = 3 # the shorter of QP and base64, but only for headers
+
+# In "=?charset?q?hello_world?=", the =?, ?q?, and ?= add up to 7
+MISC_LEN = 7
+
+DEFAULT_CHARSET = 'us-ascii'
+
+
+
+# Defaults
+CHARSETS = {
+    # input        header enc  body enc output conv
+    'iso-8859-1':  (QP,        QP,      None),
+    'iso-8859-2':  (QP,        QP,      None),
+    'iso-8859-3':  (QP,        QP,      None),
+    'iso-8859-4':  (QP,        QP,      None),
+    # iso-8859-5 is Cyrillic, and not especially used
+    # iso-8859-6 is Arabic, also not particularly used
+    # iso-8859-7 is Greek, QP will not make it readable
+    # iso-8859-8 is Hebrew, QP will not make it readable
+    'iso-8859-9':  (QP,        QP,      None),
+    'iso-8859-10': (QP,        QP,      None),
+    # iso-8859-11 is Thai, QP will not make it readable
+    'iso-8859-13': (QP,        QP,      None),
+    'iso-8859-14': (QP,        QP,      None),
+    'iso-8859-15': (QP,        QP,      None),
+    'windows-1252':(QP,        QP,      None),
+    'viscii':      (QP,        QP,      None),
+    'us-ascii':    (None,      None,    None),
+    'big5':        (BASE64,    BASE64,  None),
+    'gb2312':      (BASE64,    BASE64,  None),
+    'euc-jp':      (BASE64,    None,    'iso-2022-jp'),
+    'shift_jis':   (BASE64,    None,    'iso-2022-jp'),
+    'iso-2022-jp': (BASE64,    None,    None),
+    'koi8-r':      (BASE64,    BASE64,  None),
+    'utf-8':       (SHORTEST,  BASE64, 'utf-8'),
+    # We're making this one up to represent raw unencoded 8-bit
+    '8bit':        (None,      BASE64, 'utf-8'),
+    }
+
+# Aliases for other commonly-used names for character sets.  Map
+# them to the real ones used in email.
+ALIASES = {
+    'latin_1': 'iso-8859-1',
+    'latin-1': 'iso-8859-1',
+    'latin_2': 'iso-8859-2',
+    'latin-2': 'iso-8859-2',
+    'latin_3': 'iso-8859-3',
+    'latin-3': 'iso-8859-3',
+    'latin_4': 'iso-8859-4',
+    'latin-4': 'iso-8859-4',
+    'latin_5': 'iso-8859-9',
+    'latin-5': 'iso-8859-9',
+    'latin_6': 'iso-8859-10',
+    'latin-6': 'iso-8859-10',
+    'latin_7': 'iso-8859-13',
+    'latin-7': 'iso-8859-13',
+    'latin_8': 'iso-8859-14',
+    'latin-8': 'iso-8859-14',
+    'latin_9': 'iso-8859-15',
+    'latin-9': 'iso-8859-15',
+    'cp949':   'ks_c_5601-1987',
+    'euc_jp':  'euc-jp',
+    'euc_kr':  'euc-kr',
+    'ascii':   'us-ascii',
+    }
+
+
+# Map charsets to their Unicode codec strings.
+CODEC_MAP = {
+    'gb2312':      'eucgb2312_cn',
+    'big5':        'big5_tw',
+    # Hack: We don't want *any* conversion for stuff marked us-ascii, as all
+    # sorts of garbage might be sent to us in the guise of 7-bit us-ascii.
+    # Let that stuff pass through without conversion to/from Unicode.
+    'us-ascii':    None,
+    }
+
+
+
+# Convenience functions for extending the above mappings
+def add_charset(charset, header_enc=None, body_enc=None, output_charset=None):
+    """Add character set properties to the global registry.
+
+    charset is the input character set, and must be the canonical name of a
+    character set.
+
+    Optional header_enc and body_enc is either Charset.QP for
+    quoted-printable, Charset.BASE64 for base64 encoding, Charset.SHORTEST for
+    the shortest of qp or base64 encoding, or None for no encoding.  SHORTEST
+    is only valid for header_enc.  It describes how message headers and
+    message bodies in the input charset are to be encoded.  Default is no
+    encoding.
+
+    Optional output_charset is the character set that the output should be
+    in.  Conversions will proceed from input charset, to Unicode, to the
+    output charset when the method Charset.convert() is called.  The default
+    is to output in the same character set as the input.
+
+    Both input_charset and output_charset must have Unicode codec entries in
+    the module's charset-to-codec mapping; use add_codec(charset, codecname)
+    to add codecs the module does not know about.  See the codecs module's
+    documentation for more information.
+    """
+    if body_enc == SHORTEST:
+        raise ValueError('SHORTEST not allowed for body_enc')
+    CHARSETS[charset] = (header_enc, body_enc, output_charset)
+
+
+def add_alias(alias, canonical):
+    """Add a character set alias.
+
+    alias is the alias name, e.g. latin-1
+    canonical is the character set's canonical name, e.g. iso-8859-1
+    """
+    ALIASES[alias] = canonical
+
+
+def add_codec(charset, codecname):
+    """Add a codec that map characters in the given charset to/from Unicode.
+
+    charset is the canonical name of a character set.  codecname is the name
+    of a Python codec, as appropriate for the second argument to the unicode()
+    built-in, or to the encode() method of a Unicode string.
+    """
+    CODEC_MAP[charset] = codecname
+
+
+
+class Charset:
+    """Map character sets to their email properties.
+
+    This class provides information about the requirements imposed on email
+    for a specific character set.  It also provides convenience routines for
+    converting between character sets, given the availability of the
+    applicable codecs.  Given a character set, it will do its best to provide
+    information on how to use that character set in an email in an
+    RFC-compliant way.
+
+    Certain character sets must be encoded with quoted-printable or base64
+    when used in email headers or bodies.  Certain character sets must be
+    converted outright, and are not allowed in email.  Instances of this
+    module expose the following information about a character set:
+
+    input_charset: The initial character set specified.  Common aliases
+                   are converted to their `official' email names (e.g. latin_1
+                   is converted to iso-8859-1).  Defaults to 7-bit us-ascii.
+
+    header_encoding: If the character set must be encoded before it can be
+                     used in an email header, this attribute will be set to
+                     Charset.QP (for quoted-printable), Charset.BASE64 (for
+                     base64 encoding), or Charset.SHORTEST for the shortest of
+                     QP or BASE64 encoding.  Otherwise, it will be None.
+
+    body_encoding: Same as header_encoding, but describes the encoding for the
+                   mail message's body, which indeed may be different than the
+                   header encoding.  Charset.SHORTEST is not allowed for
+                   body_encoding.
+
+    output_charset: Some character sets must be converted before the can be
+                    used in email headers or bodies.  If the input_charset is
+                    one of them, this attribute will contain the name of the
+                    charset output will be converted to.  Otherwise, it will
+                    be None.
+
+    input_codec: The name of the Python codec used to convert the
+                 input_charset to Unicode.  If no conversion codec is
+                 necessary, this attribute will be None.
+
+    output_codec: The name of the Python codec used to convert Unicode
+                  to the output_charset.  If no conversion codec is necessary,
+                  this attribute will have the same value as the input_codec.
+    """
+    def __init__(self, input_charset=DEFAULT_CHARSET):
+        # RFC 2046, $4.1.2 says charsets are not case sensitive.  We coerce to
+        # unicode because its .lower() is locale insensitive.  If the argument
+        # is already a unicode, we leave it at that, but ensure that the
+        # charset is ASCII, as the standard (RFC XXX) requires.
+        try:
+            if isinstance(input_charset, unicode):
+                input_charset.encode('ascii')
+            else:
+                input_charset = unicode(input_charset, 'ascii')
+        except UnicodeError:
+            raise errors.CharsetError(input_charset)
+        input_charset = input_charset.lower()
+        # Set the input charset after filtering through the aliases
+        self.input_charset = ALIASES.get(input_charset, input_charset)
+        # We can try to guess which encoding and conversion to use by the
+        # charset_map dictionary.  Try that first, but let the user override
+        # it.
+        henc, benc, conv = CHARSETS.get(self.input_charset,
+                                        (SHORTEST, BASE64, None))
+        if not conv:
+            conv = self.input_charset
+        # Set the attributes, allowing the arguments to override the default.
+        self.header_encoding = henc
+        self.body_encoding = benc
+        self.output_charset = ALIASES.get(conv, conv)
+        # Now set the codecs.  If one isn't defined for input_charset,
+        # guess and try a Unicode codec with the same name as input_codec.
+        self.input_codec = CODEC_MAP.get(self.input_charset,
+                                         self.input_charset)
+        self.output_codec = CODEC_MAP.get(self.output_charset,
+                                          self.output_charset)
+
+    def __str__(self):
+        return self.input_charset.lower()
+
+    __repr__ = __str__
+
+    def __eq__(self, other):
+        return str(self) == str(other).lower()
+
+    def __ne__(self, other):
+        return not self.__eq__(other)
+
+    def get_body_encoding(self):
+        """Return the content-transfer-encoding used for body encoding.
+
+        This is either the string `quoted-printable' or `base64' depending on
+        the encoding used, or it is a function in which case you should call
+        the function with a single argument, the Message object being
+        encoded.  The function should then set the Content-Transfer-Encoding
+        header itself to whatever is appropriate.
+
+        Returns "quoted-printable" if self.body_encoding is QP.
+        Returns "base64" if self.body_encoding is BASE64.
+        Returns "7bit" otherwise.
+        """
+        assert self.body_encoding <> SHORTEST
+        if self.body_encoding == QP:
+            return 'quoted-printable'
+        elif self.body_encoding == BASE64:
+            return 'base64'
+        else:
+            return encode_7or8bit
+
+    def convert(self, s):
+        """Convert a string from the input_codec to the output_codec."""
+        if self.input_codec <> self.output_codec:
+            return unicode(s, self.input_codec).encode(self.output_codec)
+        else:
+            return s
+
+    def to_splittable(self, s):
+        """Convert a possibly multibyte string to a safely splittable format.
+
+        Uses the input_codec to try and convert the string to Unicode, so it
+        can be safely split on character boundaries (even for multibyte
+        characters).
+
+        Returns the string as-is if it isn't known how to convert it to
+        Unicode with the input_charset.
+
+        Characters that could not be converted to Unicode will be replaced
+        with the Unicode replacement character U+FFFD.
+        """
+        if isinstance(s, unicode) or self.input_codec is None:
+            return s
+        try:
+            return unicode(s, self.input_codec, 'replace')
+        except LookupError:
+            # Input codec not installed on system, so return the original
+            # string unchanged.
+            return s
+
+    def from_splittable(self, ustr, to_output=True):
+        """Convert a splittable string back into an encoded string.
+
+        Uses the proper codec to try and convert the string from Unicode back
+        into an encoded format.  Return the string as-is if it is not Unicode,
+        or if it could not be converted from Unicode.
+
+        Characters that could not be converted from Unicode will be replaced
+        with an appropriate character (usually '?').
+
+        If to_output is True (the default), uses output_codec to convert to an
+        encoded format.  If to_output is False, uses input_codec.
+        """
+        if to_output:
+            codec = self.output_codec
+        else:
+            codec = self.input_codec
+        if not isinstance(ustr, unicode) or codec is None:
+            return ustr
+        try:
+            return ustr.encode(codec, 'replace')
+        except LookupError:
+            # Output codec not installed
+            return ustr
+
+    def get_output_charset(self):
+        """Return the output character set.
+
+        This is self.output_charset if that is not None, otherwise it is
+        self.input_charset.
+        """
+        return self.output_charset or self.input_charset
+
+    def encoded_header_len(self, s):
+        """Return the length of the encoded header string."""
+        cset = self.get_output_charset()
+        # The len(s) of a 7bit encoding is len(s)
+        if self.header_encoding == BASE64:
+            return email.base64mime.base64_len(s) + len(cset) + MISC_LEN
+        elif self.header_encoding == QP:
+            return email.quoprimime.header_quopri_len(s) + len(cset) + MISC_LEN
+        elif self.header_encoding == SHORTEST:
+            lenb64 = email.base64mime.base64_len(s)
+            lenqp = email.quoprimime.header_quopri_len(s)
+            return min(lenb64, lenqp) + len(cset) + MISC_LEN
+        else:
+            return len(s)
+
+    def header_encode(self, s, convert=False):
+        """Header-encode a string, optionally converting it to output_charset.
+
+        If convert is True, the string will be converted from the input
+        charset to the output charset automatically.  This is not useful for
+        multibyte character sets, which have line length issues (multibyte
+        characters must be split on a character, not a byte boundary); use the
+        high-level Header class to deal with these issues.  convert defaults
+        to False.
+
+        The type of encoding (base64 or quoted-printable) will be based on
+        self.header_encoding.
+        """
+        cset = self.get_output_charset()
+        if convert:
+            s = self.convert(s)
+        # 7bit/8bit encodings return the string unchanged (modulo conversions)
+        if self.header_encoding == BASE64:
+            return email.base64mime.header_encode(s, cset)
+        elif self.header_encoding == QP:
+            return email.quoprimime.header_encode(s, cset, maxlinelen=None)
+        elif self.header_encoding == SHORTEST:
+            lenb64 = email.base64mime.base64_len(s)
+            lenqp = email.quoprimime.header_quopri_len(s)
+            if lenb64 < lenqp:
+                return email.base64mime.header_encode(s, cset)
+            else:
+                return email.quoprimime.header_encode(s, cset, maxlinelen=None)
+        else:
+            return s
+
+    def body_encode(self, s, convert=True):
+        """Body-encode a string and convert it to output_charset.
+
+        If convert is True (the default), the string will be converted from
+        the input charset to output charset automatically.  Unlike
+        header_encode(), there are no issues with byte boundaries and
+        multibyte charsets in email bodies, so this is usually pretty safe.
+
+        The type of encoding (base64 or quoted-printable) will be based on
+        self.body_encoding.
+        """
+        if convert:
+            s = self.convert(s)
+        # 7bit/8bit encodings return the string unchanged (module conversions)
+        if self.body_encoding is BASE64:
+            return email.base64mime.body_encode(s)
+        elif self.body_encoding is QP:
+            return email.quoprimime.body_encode(s)
+        else:
+            return s

Added: vendor/Python/current/Lib/email/encoders.py
===================================================================
--- vendor/Python/current/Lib/email/encoders.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/encoders.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,88 @@
+# Copyright (C) 2001-2006 Python Software Foundation
+# Author: Barry Warsaw
+# Contact: email-sig at python.org
+
+"""Encodings and related functions."""
+
+__all__ = [
+    'encode_7or8bit',
+    'encode_base64',
+    'encode_noop',
+    'encode_quopri',
+    ]
+
+import base64
+
+from quopri import encodestring as _encodestring
+
+
+
+def _qencode(s):
+    enc = _encodestring(s, quotetabs=True)
+    # Must encode spaces, which quopri.encodestring() doesn't do
+    return enc.replace(' ', '=20')
+
+
+def _bencode(s):
+    # We can't quite use base64.encodestring() since it tacks on a "courtesy
+    # newline".  Blech!
+    if not s:
+        return s
+    hasnewline = (s[-1] == '\n')
+    value = base64.encodestring(s)
+    if not hasnewline and value[-1] == '\n':
+        return value[:-1]
+    return value
+
+
+
+def encode_base64(msg):
+    """Encode the message's payload in Base64.
+
+    Also, add an appropriate Content-Transfer-Encoding header.
+    """
+    orig = msg.get_payload()
+    encdata = _bencode(orig)
+    msg.set_payload(encdata)
+    msg['Content-Transfer-Encoding'] = 'base64'
+
+
+
+def encode_quopri(msg):
+    """Encode the message's payload in quoted-printable.
+
+    Also, add an appropriate Content-Transfer-Encoding header.
+    """
+    orig = msg.get_payload()
+    encdata = _qencode(orig)
+    msg.set_payload(encdata)
+    msg['Content-Transfer-Encoding'] = 'quoted-printable'
+
+
+
+def encode_7or8bit(msg):
+    """Set the Content-Transfer-Encoding header to 7bit or 8bit."""
+    orig = msg.get_payload()
+    if orig is None:
+        # There's no payload.  For backwards compatibility we use 7bit
+        msg['Content-Transfer-Encoding'] = '7bit'
+        return
+    # We play a trick to make this go fast.  If encoding to ASCII succeeds, we
+    # know the data must be 7bit, otherwise treat it as 8bit.
+    try:
+        orig.encode('ascii')
+    except UnicodeError:
+        # iso-2022-* is non-ASCII but still 7-bit
+        charset = msg.get_charset()
+        output_cset = charset and charset.output_charset
+        if output_cset and output_cset.lower().startswith('iso-2202-'):
+            msg['Content-Transfer-Encoding'] = '7bit'
+        else:
+            msg['Content-Transfer-Encoding'] = '8bit'
+    else:
+        msg['Content-Transfer-Encoding'] = '7bit'
+
+
+
+def encode_noop(msg):
+    """Do nothing."""

Added: vendor/Python/current/Lib/email/errors.py
===================================================================
--- vendor/Python/current/Lib/email/errors.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/errors.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,57 @@
+# Copyright (C) 2001-2006 Python Software Foundation
+# Author: Barry Warsaw
+# Contact: email-sig at python.org
+
+"""email package exception classes."""
+
+
+
+class MessageError(Exception):
+    """Base class for errors in the email package."""
+
+
+class MessageParseError(MessageError):
+    """Base class for message parsing errors."""
+
+
+class HeaderParseError(MessageParseError):
+    """Error while parsing headers."""
+
+
+class BoundaryError(MessageParseError):
+    """Couldn't find terminating boundary."""
+
+
+class MultipartConversionError(MessageError, TypeError):
+    """Conversion to a multipart is prohibited."""
+
+
+class CharsetError(MessageError):
+    """An illegal charset was given."""
+
+
+
+# These are parsing defects which the parser was able to work around.
+class MessageDefect:
+    """Base class for a message defect."""
+
+    def __init__(self, line=None):
+        self.line = line
+
+class NoBoundaryInMultipartDefect(MessageDefect):
+    """A message claimed to be a multipart but had no boundary parameter."""
+
+class StartBoundaryNotFoundDefect(MessageDefect):
+    """The claimed start boundary was never found."""
+
+class FirstHeaderLineIsContinuationDefect(MessageDefect):
+    """A message had a continuation line as its first header line."""
+
+class MisplacedEnvelopeHeaderDefect(MessageDefect):
+    """A 'Unix-from' header was found in the middle of a header block."""
+
+class MalformedHeaderDefect(MessageDefect):
+    """Found a header that was missing a colon, or was otherwise malformed."""
+
+class MultipartInvariantViolationDefect(MessageDefect):
+    """A message claimed to be a multipart but no subparts were found."""

Added: vendor/Python/current/Lib/email/feedparser.py
===================================================================
--- vendor/Python/current/Lib/email/feedparser.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/feedparser.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,480 @@
+# Copyright (C) 2004-2006 Python Software Foundation
+# Authors: Baxter, Wouters and Warsaw
+# Contact: email-sig at python.org
+
+"""FeedParser - An email feed parser.
+
+The feed parser implements an interface for incrementally parsing an email
+message, line by line.  This has advantages for certain applications, such as
+those reading email messages off a socket.
+
+FeedParser.feed() is the primary interface for pushing new data into the
+parser.  It returns when there's nothing more it can do with the available
+data.  When you have no more data to push into the parser, call .close().
+This completes the parsing and returns the root message object.
+
+The other advantage of this parser is that it will never throw a parsing
+exception.  Instead, when it finds something unexpected, it adds a 'defect' to
+the current message.  Defects are just instances that live on the message
+object's .defects attribute.
+"""
+
+__all__ = ['FeedParser']
+
+import re
+
+from email import errors
+from email import message
+
+NLCRE = re.compile('\r\n|\r|\n')
+NLCRE_bol = re.compile('(\r\n|\r|\n)')
+NLCRE_eol = re.compile('(\r\n|\r|\n)$')
+NLCRE_crack = re.compile('(\r\n|\r|\n)')
+# RFC 2822 $3.6.8 Optional fields.  ftext is %d33-57 / %d59-126, Any character
+# except controls, SP, and ":".
+headerRE = re.compile(r'^(From |[\041-\071\073-\176]{1,}:|[\t ])')
+EMPTYSTRING = ''
+NL = '\n'
+
+NeedMoreData = object()
+
+
+
+class BufferedSubFile(object):
+    """A file-ish object that can have new data loaded into it.
+
+    You can also push and pop line-matching predicates onto a stack.  When the
+    current predicate matches the current line, a false EOF response
+    (i.e. empty string) is returned instead.  This lets the parser adhere to a
+    simple abstraction -- it parses until EOF closes the current message.
+    """
+    def __init__(self):
+        # The last partial line pushed into this object.
+        self._partial = ''
+        # The list of full, pushed lines, in reverse order
+        self._lines = []
+        # The stack of false-EOF checking predicates.
+        self._eofstack = []
+        # A flag indicating whether the file has been closed or not.
+        self._closed = False
+
+    def push_eof_matcher(self, pred):
+        self._eofstack.append(pred)
+
+    def pop_eof_matcher(self):
+        return self._eofstack.pop()
+
+    def close(self):
+        # Don't forget any trailing partial line.
+        self._lines.append(self._partial)
+        self._partial = ''
+        self._closed = True
+
+    def readline(self):
+        if not self._lines:
+            if self._closed:
+                return ''
+            return NeedMoreData
+        # Pop the line off the stack and see if it matches the current
+        # false-EOF predicate.
+        line = self._lines.pop()
+        # RFC 2046, section 5.1.2 requires us to recognize outer level
+        # boundaries at any level of inner nesting.  Do this, but be sure it's
+        # in the order of most to least nested.
+        for ateof in self._eofstack[::-1]:
+            if ateof(line):
+                # We're at the false EOF.  But push the last line back first.
+                self._lines.append(line)
+                return ''
+        return line
+
+    def unreadline(self, line):
+        # Let the consumer push a line back into the buffer.
+        assert line is not NeedMoreData
+        self._lines.append(line)
+
+    def push(self, data):
+        """Push some new data into this object."""
+        # Handle any previous leftovers
+        data, self._partial = self._partial + data, ''
+        # Crack into lines, but preserve the newlines on the end of each
+        parts = NLCRE_crack.split(data)
+        # The *ahem* interesting behaviour of re.split when supplied grouping
+        # parentheses is that the last element of the resulting list is the
+        # data after the final RE.  In the case of a NL/CR terminated string,
+        # this is the empty string.
+        self._partial = parts.pop()
+        # parts is a list of strings, alternating between the line contents
+        # and the eol character(s).  Gather up a list of lines after
+        # re-attaching the newlines.
+        lines = []
+        for i in range(len(parts) // 2):
+            lines.append(parts[i*2] + parts[i*2+1])
+        self.pushlines(lines)
+
+    def pushlines(self, lines):
+        # Reverse and insert at the front of the lines.
+        self._lines[:0] = lines[::-1]
+
+    def is_closed(self):
+        return self._closed
+
+    def __iter__(self):
+        return self
+
+    def next(self):
+        line = self.readline()
+        if line == '':
+            raise StopIteration
+        return line
+
+
+
+class FeedParser:
+    """A feed-style parser of email."""
+
+    def __init__(self, _factory=message.Message):
+        """_factory is called with no arguments to create a new message obj"""
+        self._factory = _factory
+        self._input = BufferedSubFile()
+        self._msgstack = []
+        self._parse = self._parsegen().next
+        self._cur = None
+        self._last = None
+        self._headersonly = False
+
+    # Non-public interface for supporting Parser's headersonly flag
+    def _set_headersonly(self):
+        self._headersonly = True
+
+    def feed(self, data):
+        """Push more data into the parser."""
+        self._input.push(data)
+        self._call_parse()
+
+    def _call_parse(self):
+        try:
+            self._parse()
+        except StopIteration:
+            pass
+
+    def close(self):
+        """Parse all remaining data and return the root message object."""
+        self._input.close()
+        self._call_parse()
+        root = self._pop_message()
+        assert not self._msgstack
+        # Look for final set of defects
+        if root.get_content_maintype() == 'multipart' \
+               and not root.is_multipart():
+            root.defects.append(errors.MultipartInvariantViolationDefect())
+        return root
+
+    def _new_message(self):
+        msg = self._factory()
+        if self._cur and self._cur.get_content_type() == 'multipart/digest':
+            msg.set_default_type('message/rfc822')
+        if self._msgstack:
+            self._msgstack[-1].attach(msg)
+        self._msgstack.append(msg)
+        self._cur = msg
+        self._last = msg
+
+    def _pop_message(self):
+        retval = self._msgstack.pop()
+        if self._msgstack:
+            self._cur = self._msgstack[-1]
+        else:
+            self._cur = None
+        return retval
+
+    def _parsegen(self):
+        # Create a new message and start by parsing headers.
+        self._new_message()
+        headers = []
+        # Collect the headers, searching for a line that doesn't match the RFC
+        # 2822 header or continuation pattern (including an empty line).
+        for line in self._input:
+            if line is NeedMoreData:
+                yield NeedMoreData
+                continue
+            if not headerRE.match(line):
+                # If we saw the RFC defined header/body separator
+                # (i.e. newline), just throw it away. Otherwise the line is
+                # part of the body so push it back.
+                if not NLCRE.match(line):
+                    self._input.unreadline(line)
+                break
+            headers.append(line)
+        # Done with the headers, so parse them and figure out what we're
+        # supposed to see in the body of the message.
+        self._parse_headers(headers)
+        # Headers-only parsing is a backwards compatibility hack, which was
+        # necessary in the older parser, which could throw errors.  All
+        # remaining lines in the input are thrown into the message body.
+        if self._headersonly:
+            lines = []
+            while True:
+                line = self._input.readline()
+                if line is NeedMoreData:
+                    yield NeedMoreData
+                    continue
+                if line == '':
+                    break
+                lines.append(line)
+            self._cur.set_payload(EMPTYSTRING.join(lines))
+            return
+        if self._cur.get_content_type() == 'message/delivery-status':
+            # message/delivery-status contains blocks of headers separated by
+            # a blank line.  We'll represent each header block as a separate
+            # nested message object, but the processing is a bit different
+            # than standard message/* types because there is no body for the
+            # nested messages.  A blank line separates the subparts.
+            while True:
+                self._input.push_eof_matcher(NLCRE.match)
+                for retval in self._parsegen():
+                    if retval is NeedMoreData:
+                        yield NeedMoreData
+                        continue
+                    break
+                msg = self._pop_message()
+                # We need to pop the EOF matcher in order to tell if we're at
+                # the end of the current file, not the end of the last block
+                # of message headers.
+                self._input.pop_eof_matcher()
+                # The input stream must be sitting at the newline or at the
+                # EOF.  We want to see if we're at the end of this subpart, so
+                # first consume the blank line, then test the next line to see
+                # if we're at this subpart's EOF.
+                while True:
+                    line = self._input.readline()
+                    if line is NeedMoreData:
+                        yield NeedMoreData
+                        continue
+                    break
+                while True:
+                    line = self._input.readline()
+                    if line is NeedMoreData:
+                        yield NeedMoreData
+                        continue
+                    break
+                if line == '':
+                    break
+                # Not at EOF so this is a line we're going to need.
+                self._input.unreadline(line)
+            return
+        if self._cur.get_content_maintype() == 'message':
+            # The message claims to be a message/* type, then what follows is
+            # another RFC 2822 message.
+            for retval in self._parsegen():
+                if retval is NeedMoreData:
+                    yield NeedMoreData
+                    continue
+                break
+            self._pop_message()
+            return
+        if self._cur.get_content_maintype() == 'multipart':
+            boundary = self._cur.get_boundary()
+            if boundary is None:
+                # The message /claims/ to be a multipart but it has not
+                # defined a boundary.  That's a problem which we'll handle by
+                # reading everything until the EOF and marking the message as
+                # defective.
+                self._cur.defects.append(errors.NoBoundaryInMultipartDefect())
+                lines = []
+                for line in self._input:
+                    if line is NeedMoreData:
+                        yield NeedMoreData
+                        continue
+                    lines.append(line)
+                self._cur.set_payload(EMPTYSTRING.join(lines))
+                return
+            # Create a line match predicate which matches the inter-part
+            # boundary as well as the end-of-multipart boundary.  Don't push
+            # this onto the input stream until we've scanned past the
+            # preamble.
+            separator = '--' + boundary
+            boundaryre = re.compile(
+                '(?P<sep>' + re.escape(separator) +
+                r')(?P<end>--)?(?P<ws>[ \t]*)(?P<linesep>\r\n|\r|\n)?$')
+            capturing_preamble = True
+            preamble = []
+            linesep = False
+            while True:
+                line = self._input.readline()
+                if line is NeedMoreData:
+                    yield NeedMoreData
+                    continue
+                if line == '':
+                    break
+                mo = boundaryre.match(line)
+                if mo:
+                    # If we're looking at the end boundary, we're done with
+                    # this multipart.  If there was a newline at the end of
+                    # the closing boundary, then we need to initialize the
+                    # epilogue with the empty string (see below).
+                    if mo.group('end'):
+                        linesep = mo.group('linesep')
+                        break
+                    # We saw an inter-part boundary.  Were we in the preamble?
+                    if capturing_preamble:
+                        if preamble:
+                            # According to RFC 2046, the last newline belongs
+                            # to the boundary.
+                            lastline = preamble[-1]
+                            eolmo = NLCRE_eol.search(lastline)
+                            if eolmo:
+                                preamble[-1] = lastline[:-len(eolmo.group(0))]
+                            self._cur.preamble = EMPTYSTRING.join(preamble)
+                        capturing_preamble = False
+                        self._input.unreadline(line)
+                        continue
+                    # We saw a boundary separating two parts.  Consume any
+                    # multiple boundary lines that may be following.  Our
+                    # interpretation of RFC 2046 BNF grammar does not produce
+                    # body parts within such double boundaries.
+                    while True:
+                        line = self._input.readline()
+                        if line is NeedMoreData:
+                            yield NeedMoreData
+                            continue
+                        mo = boundaryre.match(line)
+                        if not mo:
+                            self._input.unreadline(line)
+                            break
+                    # Recurse to parse this subpart; the input stream points
+                    # at the subpart's first line.
+                    self._input.push_eof_matcher(boundaryre.match)
+                    for retval in self._parsegen():
+                        if retval is NeedMoreData:
+                            yield NeedMoreData
+                            continue
+                        break
+                    # Because of RFC 2046, the newline preceding the boundary
+                    # separator actually belongs to the boundary, not the
+                    # previous subpart's payload (or epilogue if the previous
+                    # part is a multipart).
+                    if self._last.get_content_maintype() == 'multipart':
+                        epilogue = self._last.epilogue
+                        if epilogue == '':
+                            self._last.epilogue = None
+                        elif epilogue is not None:
+                            mo = NLCRE_eol.search(epilogue)
+                            if mo:
+                                end = len(mo.group(0))
+                                self._last.epilogue = epilogue[:-end]
+                    else:
+                        payload = self._last.get_payload()
+                        if isinstance(payload, basestring):
+                            mo = NLCRE_eol.search(payload)
+                            if mo:
+                                payload = payload[:-len(mo.group(0))]
+                                self._last.set_payload(payload)
+                    self._input.pop_eof_matcher()
+                    self._pop_message()
+                    # Set the multipart up for newline cleansing, which will
+                    # happen if we're in a nested multipart.
+                    self._last = self._cur
+                else:
+                    # I think we must be in the preamble
+                    assert capturing_preamble
+                    preamble.append(line)
+            # We've seen either the EOF or the end boundary.  If we're still
+            # capturing the preamble, we never saw the start boundary.  Note
+            # that as a defect and store the captured text as the payload.
+            # Everything from here to the EOF is epilogue.
+            if capturing_preamble:
+                self._cur.defects.append(errors.StartBoundaryNotFoundDefect())
+                self._cur.set_payload(EMPTYSTRING.join(preamble))
+                epilogue = []
+                for line in self._input:
+                    if line is NeedMoreData:
+                        yield NeedMoreData
+                        continue
+                self._cur.epilogue = EMPTYSTRING.join(epilogue)
+                return
+            # If the end boundary ended in a newline, we'll need to make sure
+            # the epilogue isn't None
+            if linesep:
+                epilogue = ['']
+            else:
+                epilogue = []
+            for line in self._input:
+                if line is NeedMoreData:
+                    yield NeedMoreData
+                    continue
+                epilogue.append(line)
+            # Any CRLF at the front of the epilogue is not technically part of
+            # the epilogue.  Also, watch out for an empty string epilogue,
+            # which means a single newline.
+            if epilogue:
+                firstline = epilogue[0]
+                bolmo = NLCRE_bol.match(firstline)
+                if bolmo:
+                    epilogue[0] = firstline[len(bolmo.group(0)):]
+            self._cur.epilogue = EMPTYSTRING.join(epilogue)
+            return
+        # Otherwise, it's some non-multipart type, so the entire rest of the
+        # file contents becomes the payload.
+        lines = []
+        for line in self._input:
+            if line is NeedMoreData:
+                yield NeedMoreData
+                continue
+            lines.append(line)
+        self._cur.set_payload(EMPTYSTRING.join(lines))
+
+    def _parse_headers(self, lines):
+        # Passed a list of lines that make up the headers for the current msg
+        lastheader = ''
+        lastvalue = []
+        for lineno, line in enumerate(lines):
+            # Check for continuation
+            if line[0] in ' \t':
+                if not lastheader:
+                    # The first line of the headers was a continuation.  This
+                    # is illegal, so let's note the defect, store the illegal
+                    # line, and ignore it for purposes of headers.
+                    defect = errors.FirstHeaderLineIsContinuationDefect(line)
+                    self._cur.defects.append(defect)
+                    continue
+                lastvalue.append(line)
+                continue
+            if lastheader:
+                # XXX reconsider the joining of folded lines
+                lhdr = EMPTYSTRING.join(lastvalue)[:-1].rstrip('\r\n')
+                self._cur[lastheader] = lhdr
+                lastheader, lastvalue = '', []
+            # Check for envelope header, i.e. unix-from
+            if line.startswith('From '):
+                if lineno == 0:
+                    # Strip off the trailing newline
+                    mo = NLCRE_eol.search(line)
+                    if mo:
+                        line = line[:-len(mo.group(0))]
+                    self._cur.set_unixfrom(line)
+                    continue
+                elif lineno == len(lines) - 1:
+                    # Something looking like a unix-from at the end - it's
+                    # probably the first line of the body, so push back the
+                    # line and stop.
+                    self._input.unreadline(line)
+                    return
+                else:
+                    # Weirdly placed unix-from line.  Note this as a defect
+                    # and ignore it.
+                    defect = errors.MisplacedEnvelopeHeaderDefect(line)
+                    self._cur.defects.append(defect)
+                    continue
+            # Split the line on the colon separating field name from value.
+            i = line.find(':')
+            if i < 0:
+                defect = errors.MalformedHeaderDefect(line)
+                self._cur.defects.append(defect)
+                continue
+            lastheader = line[:i]
+            lastvalue = [line[i+1:].lstrip()]
+        # Done with all the lines, so handle the last header.
+        if lastheader:
+            # XXX reconsider the joining of folded lines
+            self._cur[lastheader] = EMPTYSTRING.join(lastvalue).rstrip('\r\n')

Added: vendor/Python/current/Lib/email/generator.py
===================================================================
--- vendor/Python/current/Lib/email/generator.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/generator.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,348 @@
+# Copyright (C) 2001-2006 Python Software Foundation
+# Author: Barry Warsaw
+# Contact: email-sig at python.org
+
+"""Classes to generate plain text from a message object tree."""
+
+__all__ = ['Generator', 'DecodedGenerator']
+
+import re
+import sys
+import time
+import random
+import warnings
+
+from cStringIO import StringIO
+from email.header import Header
+
+UNDERSCORE = '_'
+NL = '\n'
+
+fcre = re.compile(r'^From ', re.MULTILINE)
+
+def _is8bitstring(s):
+    if isinstance(s, str):
+        try:
+            unicode(s, 'us-ascii')
+        except UnicodeError:
+            return True
+    return False
+
+
+
+class Generator:
+    """Generates output from a Message object tree.
+
+    This basic generator writes the message to the given file object as plain
+    text.
+    """
+    #
+    # Public interface
+    #
+
+    def __init__(self, outfp, mangle_from_=True, maxheaderlen=78):
+        """Create the generator for message flattening.
+
+        outfp is the output file-like object for writing the message to.  It
+        must have a write() method.
+
+        Optional mangle_from_ is a flag that, when True (the default), escapes
+        From_ lines in the body of the message by putting a `>' in front of
+        them.
+
+        Optional maxheaderlen specifies the longest length for a non-continued
+        header.  When a header line is longer (in characters, with tabs
+        expanded to 8 spaces) than maxheaderlen, the header will split as
+        defined in the Header class.  Set maxheaderlen to zero to disable
+        header wrapping.  The default is 78, as recommended (but not required)
+        by RFC 2822.
+        """
+        self._fp = outfp
+        self._mangle_from_ = mangle_from_
+        self._maxheaderlen = maxheaderlen
+
+    def write(self, s):
+        # Just delegate to the file object
+        self._fp.write(s)
+
+    def flatten(self, msg, unixfrom=False):
+        """Print the message object tree rooted at msg to the output file
+        specified when the Generator instance was created.
+
+        unixfrom is a flag that forces the printing of a Unix From_ delimiter
+        before the first object in the message tree.  If the original message
+        has no From_ delimiter, a `standard' one is crafted.  By default, this
+        is False to inhibit the printing of any From_ delimiter.
+
+        Note that for subobjects, no From_ line is printed.
+        """
+        if unixfrom:
+            ufrom = msg.get_unixfrom()
+            if not ufrom:
+                ufrom = 'From nobody ' + time.ctime(time.time())
+            print >> self._fp, ufrom
+        self._write(msg)
+
+    def clone(self, fp):
+        """Clone this generator with the exact same options."""
+        return self.__class__(fp, self._mangle_from_, self._maxheaderlen)
+
+    #
+    # Protected interface - undocumented ;/
+    #
+
+    def _write(self, msg):
+        # We can't write the headers yet because of the following scenario:
+        # say a multipart message includes the boundary string somewhere in
+        # its body.  We'd have to calculate the new boundary /before/ we write
+        # the headers so that we can write the correct Content-Type:
+        # parameter.
+        #
+        # The way we do this, so as to make the _handle_*() methods simpler,
+        # is to cache any subpart writes into a StringIO.  The we write the
+        # headers and the StringIO contents.  That way, subpart handlers can
+        # Do The Right Thing, and can still modify the Content-Type: header if
+        # necessary.
+        oldfp = self._fp
+        try:
+            self._fp = sfp = StringIO()
+            self._dispatch(msg)
+        finally:
+            self._fp = oldfp
+        # Write the headers.  First we see if the message object wants to
+        # handle that itself.  If not, we'll do it generically.
+        meth = getattr(msg, '_write_headers', None)
+        if meth is None:
+            self._write_headers(msg)
+        else:
+            meth(self)
+        self._fp.write(sfp.getvalue())
+
+    def _dispatch(self, msg):
+        # Get the Content-Type: for the message, then try to dispatch to
+        # self._handle_<maintype>_<subtype>().  If there's no handler for the
+        # full MIME type, then dispatch to self._handle_<maintype>().  If
+        # that's missing too, then dispatch to self._writeBody().
+        main = msg.get_content_maintype()
+        sub = msg.get_content_subtype()
+        specific = UNDERSCORE.join((main, sub)).replace('-', '_')
+        meth = getattr(self, '_handle_' + specific, None)
+        if meth is None:
+            generic = main.replace('-', '_')
+            meth = getattr(self, '_handle_' + generic, None)
+            if meth is None:
+                meth = self._writeBody
+        meth(msg)
+
+    #
+    # Default handlers
+    #
+
+    def _write_headers(self, msg):
+        for h, v in msg.items():
+            print >> self._fp, '%s:' % h,
+            if self._maxheaderlen == 0:
+                # Explicit no-wrapping
+                print >> self._fp, v
+            elif isinstance(v, Header):
+                # Header instances know what to do
+                print >> self._fp, v.encode()
+            elif _is8bitstring(v):
+                # If we have raw 8bit data in a byte string, we have no idea
+                # what the encoding is.  There is no safe way to split this
+                # string.  If it's ascii-subset, then we could do a normal
+                # ascii split, but if it's multibyte then we could break the
+                # string.  There's no way to know so the least harm seems to
+                # be to not split the string and risk it being too long.
+                print >> self._fp, v
+            else:
+                # Header's got lots of smarts, so use it.
+                print >> self._fp, Header(
+                    v, maxlinelen=self._maxheaderlen,
+                    header_name=h, continuation_ws='\t').encode()
+        # A blank line always separates headers from body
+        print >> self._fp
+
+    #
+    # Handlers for writing types and subtypes
+    #
+
+    def _handle_text(self, msg):
+        payload = msg.get_payload()
+        if payload is None:
+            return
+        if not isinstance(payload, basestring):
+            raise TypeError('string payload expected: %s' % type(payload))
+        if self._mangle_from_:
+            payload = fcre.sub('>From ', payload)
+        self._fp.write(payload)
+
+    # Default body handler
+    _writeBody = _handle_text
+
+    def _handle_multipart(self, msg):
+        # The trick here is to write out each part separately, merge them all
+        # together, and then make sure that the boundary we've chosen isn't
+        # present in the payload.
+        msgtexts = []
+        subparts = msg.get_payload()
+        if subparts is None:
+            subparts = []
+        elif isinstance(subparts, basestring):
+            # e.g. a non-strict parse of a message with no starting boundary.
+            self._fp.write(subparts)
+            return
+        elif not isinstance(subparts, list):
+            # Scalar payload
+            subparts = [subparts]
+        for part in subparts:
+            s = StringIO()
+            g = self.clone(s)
+            g.flatten(part, unixfrom=False)
+            msgtexts.append(s.getvalue())
+        # Now make sure the boundary we've selected doesn't appear in any of
+        # the message texts.
+        alltext = NL.join(msgtexts)
+        # BAW: What about boundaries that are wrapped in double-quotes?
+        boundary = msg.get_boundary(failobj=_make_boundary(alltext))
+        # If we had to calculate a new boundary because the body text
+        # contained that string, set the new boundary.  We don't do it
+        # unconditionally because, while set_boundary() preserves order, it
+        # doesn't preserve newlines/continuations in headers.  This is no big
+        # deal in practice, but turns out to be inconvenient for the unittest
+        # suite.
+        if msg.get_boundary() <> boundary:
+            msg.set_boundary(boundary)
+        # If there's a preamble, write it out, with a trailing CRLF
+        if msg.preamble is not None:
+            print >> self._fp, msg.preamble
+        # dash-boundary transport-padding CRLF
+        print >> self._fp, '--' + boundary
+        # body-part
+        if msgtexts:
+            self._fp.write(msgtexts.pop(0))
+        # *encapsulation
+        # --> delimiter transport-padding
+        # --> CRLF body-part
+        for body_part in msgtexts:
+            # delimiter transport-padding CRLF
+            print >> self._fp, '\n--' + boundary
+            # body-part
+            self._fp.write(body_part)
+        # close-delimiter transport-padding
+        self._fp.write('\n--' + boundary + '--')
+        if msg.epilogue is not None:
+            print >> self._fp
+            self._fp.write(msg.epilogue)
+
+    def _handle_message_delivery_status(self, msg):
+        # We can't just write the headers directly to self's file object
+        # because this will leave an extra newline between the last header
+        # block and the boundary.  Sigh.
+        blocks = []
+        for part in msg.get_payload():
+            s = StringIO()
+            g = self.clone(s)
+            g.flatten(part, unixfrom=False)
+            text = s.getvalue()
+            lines = text.split('\n')
+            # Strip off the unnecessary trailing empty line
+            if lines and lines[-1] == '':
+                blocks.append(NL.join(lines[:-1]))
+            else:
+                blocks.append(text)
+        # Now join all the blocks with an empty line.  This has the lovely
+        # effect of separating each block with an empty line, but not adding
+        # an extra one after the last one.
+        self._fp.write(NL.join(blocks))
+
+    def _handle_message(self, msg):
+        s = StringIO()
+        g = self.clone(s)
+        # The payload of a message/rfc822 part should be a multipart sequence
+        # of length 1.  The zeroth element of the list should be the Message
+        # object for the subpart.  Extract that object, stringify it, and
+        # write it out.
+        g.flatten(msg.get_payload(0), unixfrom=False)
+        self._fp.write(s.getvalue())
+
+
+
+_FMT = '[Non-text (%(type)s) part of message omitted, filename %(filename)s]'
+
+class DecodedGenerator(Generator):
+    """Generator a text representation of a message.
+
+    Like the Generator base class, except that non-text parts are substituted
+    with a format string representing the part.
+    """
+    def __init__(self, outfp, mangle_from_=True, maxheaderlen=78, fmt=None):
+        """Like Generator.__init__() except that an additional optional
+        argument is allowed.
+
+        Walks through all subparts of a message.  If the subpart is of main
+        type `text', then it prints the decoded payload of the subpart.
+
+        Otherwise, fmt is a format string that is used instead of the message
+        payload.  fmt is expanded with the following keywords (in
+        %(keyword)s format):
+
+        type       : Full MIME type of the non-text part
+        maintype   : Main MIME type of the non-text part
+        subtype    : Sub-MIME type of the non-text part
+        filename   : Filename of the non-text part
+        description: Description associated with the non-text part
+        encoding   : Content transfer encoding of the non-text part
+
+        The default value for fmt is None, meaning
+
+        [Non-text (%(type)s) part of message omitted, filename %(filename)s]
+        """
+        Generator.__init__(self, outfp, mangle_from_, maxheaderlen)
+        if fmt is None:
+            self._fmt = _FMT
+        else:
+            self._fmt = fmt
+
+    def _dispatch(self, msg):
+        for part in msg.walk():
+            maintype = part.get_content_maintype()
+            if maintype == 'text':
+                print >> self, part.get_payload(decode=True)
+            elif maintype == 'multipart':
+                # Just skip this
+                pass
+            else:
+                print >> self, self._fmt % {
+                    'type'       : part.get_content_type(),
+                    'maintype'   : part.get_content_maintype(),
+                    'subtype'    : part.get_content_subtype(),
+                    'filename'   : part.get_filename('[no filename]'),
+                    'description': part.get('Content-Description',
+                                            '[no description]'),
+                    'encoding'   : part.get('Content-Transfer-Encoding',
+                                            '[no encoding]'),
+                    }
+
+
+
+# Helper
+_width = len(repr(sys.maxint-1))
+_fmt = '%%0%dd' % _width
+
+def _make_boundary(text=None):
+    # Craft a random boundary.  If text is given, ensure that the chosen
+    # boundary doesn't appear in the text.
+    token = random.randrange(sys.maxint)
+    boundary = ('=' * 15) + (_fmt % token) + '=='
+    if text is None:
+        return boundary
+    b = boundary
+    counter = 0
+    while True:
+        cre = re.compile('^--' + re.escape(b) + '(--)?$', re.MULTILINE)
+        if not cre.search(text):
+            break
+        b = boundary + '.' + str(counter)
+        counter += 1
+    return b

Added: vendor/Python/current/Lib/email/header.py
===================================================================
--- vendor/Python/current/Lib/email/header.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/header.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,503 @@
+# Copyright (C) 2002-2006 Python Software Foundation
+# Author: Ben Gertzfield, Barry Warsaw
+# Contact: email-sig at python.org
+
+"""Header encoding and decoding functionality."""
+
+__all__ = [
+    'Header',
+    'decode_header',
+    'make_header',
+    ]
+
+import re
+import binascii
+
+import email.quoprimime
+import email.base64mime
+
+from email.errors import HeaderParseError
+from email.charset import Charset
+
+NL = '\n'
+SPACE = ' '
+USPACE = u' '
+SPACE8 = ' ' * 8
+UEMPTYSTRING = u''
+
+MAXLINELEN = 76
+
+USASCII = Charset('us-ascii')
+UTF8 = Charset('utf-8')
+
+# Match encoded-word strings in the form =?charset?q?Hello_World?=
+ecre = re.compile(r'''
+  =\?                   # literal =?
+  (?P<charset>[^?]*?)   # non-greedy up to the next ? is the charset
+  \?                    # literal ?
+  (?P<encoding>[qb])    # either a "q" or a "b", case insensitive
+  \?                    # literal ?
+  (?P<encoded>.*?)      # non-greedy up to the next ?= is the encoded string
+  \?=                   # literal ?=
+  (?=[ \t]|$)           # whitespace or the end of the string
+  ''', re.VERBOSE | re.IGNORECASE | re.MULTILINE)
+
+# Field name regexp, including trailing colon, but not separating whitespace,
+# according to RFC 2822.  Character range is from tilde to exclamation mark.
+# For use with .match()
+fcre = re.compile(r'[\041-\176]+:$')
+
+
+
+# Helpers
+_max_append = email.quoprimime._max_append
+
+
+
+def decode_header(header):
+    """Decode a message header value without converting charset.
+
+    Returns a list of (decoded_string, charset) pairs containing each of the
+    decoded parts of the header.  Charset is None for non-encoded parts of the
+    header, otherwise a lower-case string containing the name of the character
+    set specified in the encoded string.
+
+    An email.Errors.HeaderParseError may be raised when certain decoding error
+    occurs (e.g. a base64 decoding exception).
+    """
+    # If no encoding, just return the header
+    header = str(header)
+    if not ecre.search(header):
+        return [(header, None)]
+    decoded = []
+    dec = ''
+    for line in header.splitlines():
+        # This line might not have an encoding in it
+        if not ecre.search(line):
+            decoded.append((line, None))
+            continue
+        parts = ecre.split(line)
+        while parts:
+            unenc = parts.pop(0).strip()
+            if unenc:
+                # Should we continue a long line?
+                if decoded and decoded[-1][1] is None:
+                    decoded[-1] = (decoded[-1][0] + SPACE + unenc, None)
+                else:
+                    decoded.append((unenc, None))
+            if parts:
+                charset, encoding = [s.lower() for s in parts[0:2]]
+                encoded = parts[2]
+                dec = None
+                if encoding == 'q':
+                    dec = email.quoprimime.header_decode(encoded)
+                elif encoding == 'b':
+                    try:
+                        dec = email.base64mime.decode(encoded)
+                    except binascii.Error:
+                        # Turn this into a higher level exception.  BAW: Right
+                        # now we throw the lower level exception away but
+                        # when/if we get exception chaining, we'll preserve it.
+                        raise HeaderParseError
+                if dec is None:
+                    dec = encoded
+
+                if decoded and decoded[-1][1] == charset:
+                    decoded[-1] = (decoded[-1][0] + dec, decoded[-1][1])
+                else:
+                    decoded.append((dec, charset))
+            del parts[0:3]
+    return decoded
+
+
+
+def make_header(decoded_seq, maxlinelen=None, header_name=None,
+                continuation_ws=' '):
+    """Create a Header from a sequence of pairs as returned by decode_header()
+
+    decode_header() takes a header value string and returns a sequence of
+    pairs of the format (decoded_string, charset) where charset is the string
+    name of the character set.
+
+    This function takes one of those sequence of pairs and returns a Header
+    instance.  Optional maxlinelen, header_name, and continuation_ws are as in
+    the Header constructor.
+    """
+    h = Header(maxlinelen=maxlinelen, header_name=header_name,
+               continuation_ws=continuation_ws)
+    for s, charset in decoded_seq:
+        # None means us-ascii but we can simply pass it on to h.append()
+        if charset is not None and not isinstance(charset, Charset):
+            charset = Charset(charset)
+        h.append(s, charset)
+    return h
+
+
+
+class Header:
+    def __init__(self, s=None, charset=None,
+                 maxlinelen=None, header_name=None,
+                 continuation_ws=' ', errors='strict'):
+        """Create a MIME-compliant header that can contain many character sets.
+
+        Optional s is the initial header value.  If None, the initial header
+        value is not set.  You can later append to the header with .append()
+        method calls.  s may be a byte string or a Unicode string, but see the
+        .append() documentation for semantics.
+
+        Optional charset serves two purposes: it has the same meaning as the
+        charset argument to the .append() method.  It also sets the default
+        character set for all subsequent .append() calls that omit the charset
+        argument.  If charset is not provided in the constructor, the us-ascii
+        charset is used both as s's initial charset and as the default for
+        subsequent .append() calls.
+
+        The maximum line length can be specified explicit via maxlinelen.  For
+        splitting the first line to a shorter value (to account for the field
+        header which isn't included in s, e.g. `Subject') pass in the name of
+        the field in header_name.  The default maxlinelen is 76.
+
+        continuation_ws must be RFC 2822 compliant folding whitespace (usually
+        either a space or a hard tab) which will be prepended to continuation
+        lines.
+
+        errors is passed through to the .append() call.
+        """
+        if charset is None:
+            charset = USASCII
+        if not isinstance(charset, Charset):
+            charset = Charset(charset)
+        self._charset = charset
+        self._continuation_ws = continuation_ws
+        cws_expanded_len = len(continuation_ws.replace('\t', SPACE8))
+        # BAW: I believe `chunks' and `maxlinelen' should be non-public.
+        self._chunks = []
+        if s is not None:
+            self.append(s, charset, errors)
+        if maxlinelen is None:
+            maxlinelen = MAXLINELEN
+        if header_name is None:
+            # We don't know anything about the field header so the first line
+            # is the same length as subsequent lines.
+            self._firstlinelen = maxlinelen
+        else:
+            # The first line should be shorter to take into account the field
+            # header.  Also subtract off 2 extra for the colon and space.
+            self._firstlinelen = maxlinelen - len(header_name) - 2
+        # Second and subsequent lines should subtract off the length in
+        # columns of the continuation whitespace prefix.
+        self._maxlinelen = maxlinelen - cws_expanded_len
+
+    def __str__(self):
+        """A synonym for self.encode()."""
+        return self.encode()
+
+    def __unicode__(self):
+        """Helper for the built-in unicode function."""
+        uchunks = []
+        lastcs = None
+        for s, charset in self._chunks:
+            # We must preserve spaces between encoded and non-encoded word
+            # boundaries, which means for us we need to add a space when we go
+            # from a charset to None/us-ascii, or from None/us-ascii to a
+            # charset.  Only do this for the second and subsequent chunks.
+            nextcs = charset
+            if uchunks:
+                if lastcs not in (None, 'us-ascii'):
+                    if nextcs in (None, 'us-ascii'):
+                        uchunks.append(USPACE)
+                        nextcs = None
+                elif nextcs not in (None, 'us-ascii'):
+                    uchunks.append(USPACE)
+            lastcs = nextcs
+            uchunks.append(unicode(s, str(charset)))
+        return UEMPTYSTRING.join(uchunks)
+
+    # Rich comparison operators for equality only.  BAW: does it make sense to
+    # have or explicitly disable <, <=, >, >= operators?
+    def __eq__(self, other):
+        # other may be a Header or a string.  Both are fine so coerce
+        # ourselves to a string, swap the args and do another comparison.
+        return other == self.encode()
+
+    def __ne__(self, other):
+        return not self == other
+
+    def append(self, s, charset=None, errors='strict'):
+        """Append a string to the MIME header.
+
+        Optional charset, if given, should be a Charset instance or the name
+        of a character set (which will be converted to a Charset instance).  A
+        value of None (the default) means that the charset given in the
+        constructor is used.
+
+        s may be a byte string or a Unicode string.  If it is a byte string
+        (i.e. isinstance(s, str) is true), then charset is the encoding of
+        that byte string, and a UnicodeError will be raised if the string
+        cannot be decoded with that charset.  If s is a Unicode string, then
+        charset is a hint specifying the character set of the characters in
+        the string.  In this case, when producing an RFC 2822 compliant header
+        using RFC 2047 rules, the Unicode string will be encoded using the
+        following charsets in order: us-ascii, the charset hint, utf-8.  The
+        first character set not to provoke a UnicodeError is used.
+
+        Optional `errors' is passed as the third argument to any unicode() or
+        ustr.encode() call.
+        """
+        if charset is None:
+            charset = self._charset
+        elif not isinstance(charset, Charset):
+            charset = Charset(charset)
+        # If the charset is our faux 8bit charset, leave the string unchanged
+        if charset <> '8bit':
+            # We need to test that the string can be converted to unicode and
+            # back to a byte string, given the input and output codecs of the
+            # charset.
+            if isinstance(s, str):
+                # Possibly raise UnicodeError if the byte string can't be
+                # converted to a unicode with the input codec of the charset.
+                incodec = charset.input_codec or 'us-ascii'
+                ustr = unicode(s, incodec, errors)
+                # Now make sure that the unicode could be converted back to a
+                # byte string with the output codec, which may be different
+                # than the iput coded.  Still, use the original byte string.
+                outcodec = charset.output_codec or 'us-ascii'
+                ustr.encode(outcodec, errors)
+            elif isinstance(s, unicode):
+                # Now we have to be sure the unicode string can be converted
+                # to a byte string with a reasonable output codec.  We want to
+                # use the byte string in the chunk.
+                for charset in USASCII, charset, UTF8:
+                    try:
+                        outcodec = charset.output_codec or 'us-ascii'
+                        s = s.encode(outcodec, errors)
+                        break
+                    except UnicodeError:
+                        pass
+                else:
+                    assert False, 'utf-8 conversion failed'
+        self._chunks.append((s, charset))
+
+    def _split(self, s, charset, maxlinelen, splitchars):
+        # Split up a header safely for use with encode_chunks.
+        splittable = charset.to_splittable(s)
+        encoded = charset.from_splittable(splittable, True)
+        elen = charset.encoded_header_len(encoded)
+        # If the line's encoded length first, just return it
+        if elen <= maxlinelen:
+            return [(encoded, charset)]
+        # If we have undetermined raw 8bit characters sitting in a byte
+        # string, we really don't know what the right thing to do is.  We
+        # can't really split it because it might be multibyte data which we
+        # could break if we split it between pairs.  The least harm seems to
+        # be to not split the header at all, but that means they could go out
+        # longer than maxlinelen.
+        if charset == '8bit':
+            return [(s, charset)]
+        # BAW: I'm not sure what the right test here is.  What we're trying to
+        # do is be faithful to RFC 2822's recommendation that ($2.2.3):
+        #
+        # "Note: Though structured field bodies are defined in such a way that
+        #  folding can take place between many of the lexical tokens (and even
+        #  within some of the lexical tokens), folding SHOULD be limited to
+        #  placing the CRLF at higher-level syntactic breaks."
+        #
+        # For now, I can only imagine doing this when the charset is us-ascii,
+        # although it's possible that other charsets may also benefit from the
+        # higher-level syntactic breaks.
+        elif charset == 'us-ascii':
+            return self._split_ascii(s, charset, maxlinelen, splitchars)
+        # BAW: should we use encoded?
+        elif elen == len(s):
+            # We can split on _maxlinelen boundaries because we know that the
+            # encoding won't change the size of the string
+            splitpnt = maxlinelen
+            first = charset.from_splittable(splittable[:splitpnt], False)
+            last = charset.from_splittable(splittable[splitpnt:], False)
+        else:
+            # Binary search for split point
+            first, last = _binsplit(splittable, charset, maxlinelen)
+        # first is of the proper length so just wrap it in the appropriate
+        # chrome.  last must be recursively split.
+        fsplittable = charset.to_splittable(first)
+        fencoded = charset.from_splittable(fsplittable, True)
+        chunk = [(fencoded, charset)]
+        return chunk + self._split(last, charset, self._maxlinelen, splitchars)
+
+    def _split_ascii(self, s, charset, firstlen, splitchars):
+        chunks = _split_ascii(s, firstlen, self._maxlinelen,
+                              self._continuation_ws, splitchars)
+        return zip(chunks, [charset]*len(chunks))
+
+    def _encode_chunks(self, newchunks, maxlinelen):
+        # MIME-encode a header with many different charsets and/or encodings.
+        #
+        # Given a list of pairs (string, charset), return a MIME-encoded
+        # string suitable for use in a header field.  Each pair may have
+        # different charsets and/or encodings, and the resulting header will
+        # accurately reflect each setting.
+        #
+        # Each encoding can be email.Utils.QP (quoted-printable, for
+        # ASCII-like character sets like iso-8859-1), email.Utils.BASE64
+        # (Base64, for non-ASCII like character sets like KOI8-R and
+        # iso-2022-jp), or None (no encoding).
+        #
+        # Each pair will be represented on a separate line; the resulting
+        # string will be in the format:
+        #
+        # =?charset1?q?Mar=EDa_Gonz=E1lez_Alonso?=\n
+        #  =?charset2?b?SvxyZ2VuIEL2aW5n?="
+        chunks = []
+        for header, charset in newchunks:
+            if not header:
+                continue
+            if charset is None or charset.header_encoding is None:
+                s = header
+            else:
+                s = charset.header_encode(header)
+            # Don't add more folding whitespace than necessary
+            if chunks and chunks[-1].endswith(' '):
+                extra = ''
+            else:
+                extra = ' '
+            _max_append(chunks, s, maxlinelen, extra)
+        joiner = NL + self._continuation_ws
+        return joiner.join(chunks)
+
+    def encode(self, splitchars=';, '):
+        """Encode a message header into an RFC-compliant format.
+
+        There are many issues involved in converting a given string for use in
+        an email header.  Only certain character sets are readable in most
+        email clients, and as header strings can only contain a subset of
+        7-bit ASCII, care must be taken to properly convert and encode (with
+        Base64 or quoted-printable) header strings.  In addition, there is a
+        75-character length limit on any given encoded header field, so
+        line-wrapping must be performed, even with double-byte character sets.
+
+        This method will do its best to convert the string to the correct
+        character set used in email, and encode and line wrap it safely with
+        the appropriate scheme for that character set.
+
+        If the given charset is not known or an error occurs during
+        conversion, this function will return the header untouched.
+
+        Optional splitchars is a string containing characters to split long
+        ASCII lines on, in rough support of RFC 2822's `highest level
+        syntactic breaks'.  This doesn't affect RFC 2047 encoded lines.
+        """
+        newchunks = []
+        maxlinelen = self._firstlinelen
+        lastlen = 0
+        for s, charset in self._chunks:
+            # The first bit of the next chunk should be just long enough to
+            # fill the next line.  Don't forget the space separating the
+            # encoded words.
+            targetlen = maxlinelen - lastlen - 1
+            if targetlen < charset.encoded_header_len(''):
+                # Stick it on the next line
+                targetlen = maxlinelen
+            newchunks += self._split(s, charset, targetlen, splitchars)
+            lastchunk, lastcharset = newchunks[-1]
+            lastlen = lastcharset.encoded_header_len(lastchunk)
+        return self._encode_chunks(newchunks, maxlinelen)
+
+
+
+def _split_ascii(s, firstlen, restlen, continuation_ws, splitchars):
+    lines = []
+    maxlen = firstlen
+    for line in s.splitlines():
+        # Ignore any leading whitespace (i.e. continuation whitespace) already
+        # on the line, since we'll be adding our own.
+        line = line.lstrip()
+        if len(line) < maxlen:
+            lines.append(line)
+            maxlen = restlen
+            continue
+        # Attempt to split the line at the highest-level syntactic break
+        # possible.  Note that we don't have a lot of smarts about field
+        # syntax; we just try to break on semi-colons, then commas, then
+        # whitespace.
+        for ch in splitchars:
+            if ch in line:
+                break
+        else:
+            # There's nothing useful to split the line on, not even spaces, so
+            # just append this line unchanged
+            lines.append(line)
+            maxlen = restlen
+            continue
+        # Now split the line on the character plus trailing whitespace
+        cre = re.compile(r'%s\s*' % ch)
+        if ch in ';,':
+            eol = ch
+        else:
+            eol = ''
+        joiner = eol + ' '
+        joinlen = len(joiner)
+        wslen = len(continuation_ws.replace('\t', SPACE8))
+        this = []
+        linelen = 0
+        for part in cre.split(line):
+            curlen = linelen + max(0, len(this)-1) * joinlen
+            partlen = len(part)
+            onfirstline = not lines
+            # We don't want to split after the field name, if we're on the
+            # first line and the field name is present in the header string.
+            if ch == ' ' and onfirstline and \
+                   len(this) == 1 and fcre.match(this[0]):
+                this.append(part)
+                linelen += partlen
+            elif curlen + partlen > maxlen:
+                if this:
+                    lines.append(joiner.join(this) + eol)
+                # If this part is longer than maxlen and we aren't already
+                # splitting on whitespace, try to recursively split this line
+                # on whitespace.
+                if partlen > maxlen and ch <> ' ':
+                    subl = _split_ascii(part, maxlen, restlen,
+                                        continuation_ws, ' ')
+                    lines.extend(subl[:-1])
+                    this = [subl[-1]]
+                else:
+                    this = [part]
+                linelen = wslen + len(this[-1])
+                maxlen = restlen
+            else:
+                this.append(part)
+                linelen += partlen
+        # Put any left over parts on a line by themselves
+        if this:
+            lines.append(joiner.join(this))
+    return lines
+
+
+
+def _binsplit(splittable, charset, maxlinelen):
+    i = 0
+    j = len(splittable)
+    while i < j:
+        # Invariants:
+        # 1. splittable[:k] fits for all k <= i (note that we *assume*,
+        #    at the start, that splittable[:0] fits).
+        # 2. splittable[:k] does not fit for any k > j (at the start,
+        #    this means we shouldn't look at any k > len(splittable)).
+        # 3. We don't know about splittable[:k] for k in i+1..j.
+        # 4. We want to set i to the largest k that fits, with i <= k <= j.
+        #
+        m = (i+j+1) >> 1  # ceiling((i+j)/2); i < m <= j
+        chunk = charset.from_splittable(splittable[:m], True)
+        chunklen = charset.encoded_header_len(chunk)
+        if chunklen <= maxlinelen:
+            # m is acceptable, so is a new lower bound.
+            i = m
+        else:
+            # m is not acceptable, so final i must be < m.
+            j = m - 1
+    # i == j.  Invariant #1 implies that splittable[:i] fits, and
+    # invariant #2 implies that splittable[:i+1] does not fit, so i
+    # is what we're looking for.
+    first = charset.from_splittable(splittable[:i], False)
+    last  = charset.from_splittable(splittable[i:], False)
+    return first, last

Added: vendor/Python/current/Lib/email/iterators.py
===================================================================
--- vendor/Python/current/Lib/email/iterators.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/iterators.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,73 @@
+# Copyright (C) 2001-2006 Python Software Foundation
+# Author: Barry Warsaw
+# Contact: email-sig at python.org
+
+"""Various types of useful iterators and generators."""
+
+__all__ = [
+    'body_line_iterator',
+    'typed_subpart_iterator',
+    'walk',
+    # Do not include _structure() since it's part of the debugging API.
+    ]
+
+import sys
+from cStringIO import StringIO
+
+
+
+# This function will become a method of the Message class
+def walk(self):
+    """Walk over the message tree, yielding each subpart.
+
+    The walk is performed in depth-first order.  This method is a
+    generator.
+    """
+    yield self
+    if self.is_multipart():
+        for subpart in self.get_payload():
+            for subsubpart in subpart.walk():
+                yield subsubpart
+
+
+
+# These two functions are imported into the Iterators.py interface module.
+def body_line_iterator(msg, decode=False):
+    """Iterate over the parts, returning string payloads line-by-line.
+
+    Optional decode (default False) is passed through to .get_payload().
+    """
+    for subpart in msg.walk():
+        payload = subpart.get_payload(decode=decode)
+        if isinstance(payload, basestring):
+            for line in StringIO(payload):
+                yield line
+
+
+def typed_subpart_iterator(msg, maintype='text', subtype=None):
+    """Iterate over the subparts with a given MIME type.
+
+    Use `maintype' as the main MIME type to match against; this defaults to
+    "text".  Optional `subtype' is the MIME subtype to match against; if
+    omitted, only the main type is matched.
+    """
+    for subpart in msg.walk():
+        if subpart.get_content_maintype() == maintype:
+            if subtype is None or subpart.get_content_subtype() == subtype:
+                yield subpart
+
+
+
+def _structure(msg, fp=None, level=0, include_default=False):
+    """A handy debugging aid"""
+    if fp is None:
+        fp = sys.stdout
+    tab = ' ' * (level * 4)
+    print >> fp, tab + msg.get_content_type(),
+    if include_default:
+        print >> fp, '[%s]' % msg.get_default_type()
+    else:
+        print >> fp
+    if msg.is_multipart():
+        for subpart in msg.get_payload():
+            _structure(subpart, fp, level+1, include_default)

Added: vendor/Python/current/Lib/email/message.py
===================================================================
--- vendor/Python/current/Lib/email/message.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/message.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,786 @@
+# Copyright (C) 2001-2006 Python Software Foundation
+# Author: Barry Warsaw
+# Contact: email-sig at python.org
+
+"""Basic message object for the email package object model."""
+
+__all__ = ['Message']
+
+import re
+import uu
+import binascii
+import warnings
+from cStringIO import StringIO
+
+# Intrapackage imports
+import email.charset
+from email import utils
+from email import errors
+
+SEMISPACE = '; '
+
+# Regular expression used to split header parameters.  BAW: this may be too
+# simple.  It isn't strictly RFC 2045 (section 5.1) compliant, but it catches
+# most headers found in the wild.  We may eventually need a full fledged
+# parser eventually.
+paramre = re.compile(r'\s*;\s*')
+# Regular expression that matches `special' characters in parameters, the
+# existance of which force quoting of the parameter value.
+tspecials = re.compile(r'[ \(\)<>@,;:\\"/\[\]\?=]')
+
+
+
+# Helper functions
+def _formatparam(param, value=None, quote=True):
+    """Convenience function to format and return a key=value pair.
+
+    This will quote the value if needed or if quote is true.
+    """
+    if value is not None and len(value) > 0:
+        # A tuple is used for RFC 2231 encoded parameter values where items
+        # are (charset, language, value).  charset is a string, not a Charset
+        # instance.
+        if isinstance(value, tuple):
+            # Encode as per RFC 2231
+            param += '*'
+            value = utils.encode_rfc2231(value[2], value[0], value[1])
+        # BAW: Please check this.  I think that if quote is set it should
+        # force quoting even if not necessary.
+        if quote or tspecials.search(value):
+            return '%s="%s"' % (param, utils.quote(value))
+        else:
+            return '%s=%s' % (param, value)
+    else:
+        return param
+
+def _parseparam(s):
+    plist = []
+    while s[:1] == ';':
+        s = s[1:]
+        end = s.find(';')
+        while end > 0 and s.count('"', 0, end) % 2:
+            end = s.find(';', end + 1)
+        if end < 0:
+            end = len(s)
+        f = s[:end]
+        if '=' in f:
+            i = f.index('=')
+            f = f[:i].strip().lower() + '=' + f[i+1:].strip()
+        plist.append(f.strip())
+        s = s[end:]
+    return plist
+
+
+def _unquotevalue(value):
+    # This is different than utils.collapse_rfc2231_value() because it doesn't
+    # try to convert the value to a unicode.  Message.get_param() and
+    # Message.get_params() are both currently defined to return the tuple in
+    # the face of RFC 2231 parameters.
+    if isinstance(value, tuple):
+        return value[0], value[1], utils.unquote(value[2])
+    else:
+        return utils.unquote(value)
+
+
+
+class Message:
+    """Basic message object.
+
+    A message object is defined as something that has a bunch of RFC 2822
+    headers and a payload.  It may optionally have an envelope header
+    (a.k.a. Unix-From or From_ header).  If the message is a container (i.e. a
+    multipart or a message/rfc822), then the payload is a list of Message
+    objects, otherwise it is a string.
+
+    Message objects implement part of the `mapping' interface, which assumes
+    there is exactly one occurrance of the header per message.  Some headers
+    do in fact appear multiple times (e.g. Received) and for those headers,
+    you must use the explicit API to set or get all the headers.  Not all of
+    the mapping methods are implemented.
+    """
+    def __init__(self):
+        self._headers = []
+        self._unixfrom = None
+        self._payload = None
+        self._charset = None
+        # Defaults for multipart messages
+        self.preamble = self.epilogue = None
+        self.defects = []
+        # Default content type
+        self._default_type = 'text/plain'
+
+    def __str__(self):
+        """Return the entire formatted message as a string.
+        This includes the headers, body, and envelope header.
+        """
+        return self.as_string(unixfrom=True)
+
+    def as_string(self, unixfrom=False):
+        """Return the entire formatted message as a string.
+        Optional `unixfrom' when True, means include the Unix From_ envelope
+        header.
+
+        This is a convenience method and may not generate the message exactly
+        as you intend because by default it mangles lines that begin with
+        "From ".  For more flexibility, use the flatten() method of a
+        Generator instance.
+        """
+        from email.Generator import Generator
+        fp = StringIO()
+        g = Generator(fp)
+        g.flatten(self, unixfrom=unixfrom)
+        return fp.getvalue()
+
+    def is_multipart(self):
+        """Return True if the message consists of multiple parts."""
+        return isinstance(self._payload, list)
+
+    #
+    # Unix From_ line
+    #
+    def set_unixfrom(self, unixfrom):
+        self._unixfrom = unixfrom
+
+    def get_unixfrom(self):
+        return self._unixfrom
+
+    #
+    # Payload manipulation.
+    #
+    def attach(self, payload):
+        """Add the given payload to the current payload.
+
+        The current payload will always be a list of objects after this method
+        is called.  If you want to set the payload to a scalar object, use
+        set_payload() instead.
+        """
+        if self._payload is None:
+            self._payload = [payload]
+        else:
+            self._payload.append(payload)
+
+    def get_payload(self, i=None, decode=False):
+        """Return a reference to the payload.
+
+        The payload will either be a list object or a string.  If you mutate
+        the list object, you modify the message's payload in place.  Optional
+        i returns that index into the payload.
+
+        Optional decode is a flag indicating whether the payload should be
+        decoded or not, according to the Content-Transfer-Encoding header
+        (default is False).
+
+        When True and the message is not a multipart, the payload will be
+        decoded if this header's value is `quoted-printable' or `base64'.  If
+        some other encoding is used, or the header is missing, or if the
+        payload has bogus data (i.e. bogus base64 or uuencoded data), the
+        payload is returned as-is.
+
+        If the message is a multipart and the decode flag is True, then None
+        is returned.
+        """
+        if i is None:
+            payload = self._payload
+        elif not isinstance(self._payload, list):
+            raise TypeError('Expected list, got %s' % type(self._payload))
+        else:
+            payload = self._payload[i]
+        if decode:
+            if self.is_multipart():
+                return None
+            cte = self.get('content-transfer-encoding', '').lower()
+            if cte == 'quoted-printable':
+                return utils._qdecode(payload)
+            elif cte == 'base64':
+                try:
+                    return utils._bdecode(payload)
+                except binascii.Error:
+                    # Incorrect padding
+                    return payload
+            elif cte in ('x-uuencode', 'uuencode', 'uue', 'x-uue'):
+                sfp = StringIO()
+                try:
+                    uu.decode(StringIO(payload+'\n'), sfp, quiet=True)
+                    payload = sfp.getvalue()
+                except uu.Error:
+                    # Some decoding problem
+                    return payload
+        # Everything else, including encodings with 8bit or 7bit are returned
+        # unchanged.
+        return payload
+
+    def set_payload(self, payload, charset=None):
+        """Set the payload to the given value.
+
+        Optional charset sets the message's default character set.  See
+        set_charset() for details.
+        """
+        self._payload = payload
+        if charset is not None:
+            self.set_charset(charset)
+
+    def set_charset(self, charset):
+        """Set the charset of the payload to a given character set.
+
+        charset can be a Charset instance, a string naming a character set, or
+        None.  If it is a string it will be converted to a Charset instance.
+        If charset is None, the charset parameter will be removed from the
+        Content-Type field.  Anything else will generate a TypeError.
+
+        The message will be assumed to be of type text/* encoded with
+        charset.input_charset.  It will be converted to charset.output_charset
+        and encoded properly, if needed, when generating the plain text
+        representation of the message.  MIME headers (MIME-Version,
+        Content-Type, Content-Transfer-Encoding) will be added as needed.
+
+        """
+        if charset is None:
+            self.del_param('charset')
+            self._charset = None
+            return
+        if isinstance(charset, basestring):
+            charset = email.charset.Charset(charset)
+        if not isinstance(charset, email.charset.Charset):
+            raise TypeError(charset)
+        # BAW: should we accept strings that can serve as arguments to the
+        # Charset constructor?
+        self._charset = charset
+        if not self.has_key('MIME-Version'):
+            self.add_header('MIME-Version', '1.0')
+        if not self.has_key('Content-Type'):
+            self.add_header('Content-Type', 'text/plain',
+                            charset=charset.get_output_charset())
+        else:
+            self.set_param('charset', charset.get_output_charset())
+        if str(charset) <> charset.get_output_charset():
+            self._payload = charset.body_encode(self._payload)
+        if not self.has_key('Content-Transfer-Encoding'):
+            cte = charset.get_body_encoding()
+            try:
+                cte(self)
+            except TypeError:
+                self._payload = charset.body_encode(self._payload)
+                self.add_header('Content-Transfer-Encoding', cte)
+
+    def get_charset(self):
+        """Return the Charset instance associated with the message's payload.
+        """
+        return self._charset
+
+    #
+    # MAPPING INTERFACE (partial)
+    #
+    def __len__(self):
+        """Return the total number of headers, including duplicates."""
+        return len(self._headers)
+
+    def __getitem__(self, name):
+        """Get a header value.
+
+        Return None if the header is missing instead of raising an exception.
+
+        Note that if the header appeared multiple times, exactly which
+        occurrance gets returned is undefined.  Use get_all() to get all
+        the values matching a header field name.
+        """
+        return self.get(name)
+
+    def __setitem__(self, name, val):
+        """Set the value of a header.
+
+        Note: this does not overwrite an existing header with the same field
+        name.  Use __delitem__() first to delete any existing headers.
+        """
+        self._headers.append((name, val))
+
+    def __delitem__(self, name):
+        """Delete all occurrences of a header, if present.
+
+        Does not raise an exception if the header is missing.
+        """
+        name = name.lower()
+        newheaders = []
+        for k, v in self._headers:
+            if k.lower() <> name:
+                newheaders.append((k, v))
+        self._headers = newheaders
+
+    def __contains__(self, name):
+        return name.lower() in [k.lower() for k, v in self._headers]
+
+    def has_key(self, name):
+        """Return true if the message contains the header."""
+        missing = object()
+        return self.get(name, missing) is not missing
+
+    def keys(self):
+        """Return a list of all the message's header field names.
+
+        These will be sorted in the order they appeared in the original
+        message, or were added to the message, and may contain duplicates.
+        Any fields deleted and re-inserted are always appended to the header
+        list.
+        """
+        return [k for k, v in self._headers]
+
+    def values(self):
+        """Return a list of all the message's header values.
+
+        These will be sorted in the order they appeared in the original
+        message, or were added to the message, and may contain duplicates.
+        Any fields deleted and re-inserted are always appended to the header
+        list.
+        """
+        return [v for k, v in self._headers]
+
+    def items(self):
+        """Get all the message's header fields and values.
+
+        These will be sorted in the order they appeared in the original
+        message, or were added to the message, and may contain duplicates.
+        Any fields deleted and re-inserted are always appended to the header
+        list.
+        """
+        return self._headers[:]
+
+    def get(self, name, failobj=None):
+        """Get a header value.
+
+        Like __getitem__() but return failobj instead of None when the field
+        is missing.
+        """
+        name = name.lower()
+        for k, v in self._headers:
+            if k.lower() == name:
+                return v
+        return failobj
+
+    #
+    # Additional useful stuff
+    #
+
+    def get_all(self, name, failobj=None):
+        """Return a list of all the values for the named field.
+
+        These will be sorted in the order they appeared in the original
+        message, and may contain duplicates.  Any fields deleted and
+        re-inserted are always appended to the header list.
+
+        If no such fields exist, failobj is returned (defaults to None).
+        """
+        values = []
+        name = name.lower()
+        for k, v in self._headers:
+            if k.lower() == name:
+                values.append(v)
+        if not values:
+            return failobj
+        return values
+
+    def add_header(self, _name, _value, **_params):
+        """Extended header setting.
+
+        name is the header field to add.  keyword arguments can be used to set
+        additional parameters for the header field, with underscores converted
+        to dashes.  Normally the parameter will be added as key="value" unless
+        value is None, in which case only the key will be added.
+
+        Example:
+
+        msg.add_header('content-disposition', 'attachment', filename='bud.gif')
+        """
+        parts = []
+        for k, v in _params.items():
+            if v is None:
+                parts.append(k.replace('_', '-'))
+            else:
+                parts.append(_formatparam(k.replace('_', '-'), v))
+        if _value is not None:
+            parts.insert(0, _value)
+        self._headers.append((_name, SEMISPACE.join(parts)))
+
+    def replace_header(self, _name, _value):
+        """Replace a header.
+
+        Replace the first matching header found in the message, retaining
+        header order and case.  If no matching header was found, a KeyError is
+        raised.
+        """
+        _name = _name.lower()
+        for i, (k, v) in zip(range(len(self._headers)), self._headers):
+            if k.lower() == _name:
+                self._headers[i] = (k, _value)
+                break
+        else:
+            raise KeyError(_name)
+
+    #
+    # Use these three methods instead of the three above.
+    #
+
+    def get_content_type(self):
+        """Return the message's content type.
+
+        The returned string is coerced to lower case of the form
+        `maintype/subtype'.  If there was no Content-Type header in the
+        message, the default type as given by get_default_type() will be
+        returned.  Since according to RFC 2045, messages always have a default
+        type this will always return a value.
+
+        RFC 2045 defines a message's default type to be text/plain unless it
+        appears inside a multipart/digest container, in which case it would be
+        message/rfc822.
+        """
+        missing = object()
+        value = self.get('content-type', missing)
+        if value is missing:
+            # This should have no parameters
+            return self.get_default_type()
+        ctype = paramre.split(value)[0].lower().strip()
+        # RFC 2045, section 5.2 says if its invalid, use text/plain
+        if ctype.count('/') <> 1:
+            return 'text/plain'
+        return ctype
+
+    def get_content_maintype(self):
+        """Return the message's main content type.
+
+        This is the `maintype' part of the string returned by
+        get_content_type().
+        """
+        ctype = self.get_content_type()
+        return ctype.split('/')[0]
+
+    def get_content_subtype(self):
+        """Returns the message's sub-content type.
+
+        This is the `subtype' part of the string returned by
+        get_content_type().
+        """
+        ctype = self.get_content_type()
+        return ctype.split('/')[1]
+
+    def get_default_type(self):
+        """Return the `default' content type.
+
+        Most messages have a default content type of text/plain, except for
+        messages that are subparts of multipart/digest containers.  Such
+        subparts have a default content type of message/rfc822.
+        """
+        return self._default_type
+
+    def set_default_type(self, ctype):
+        """Set the `default' content type.
+
+        ctype should be either "text/plain" or "message/rfc822", although this
+        is not enforced.  The default content type is not stored in the
+        Content-Type header.
+        """
+        self._default_type = ctype
+
+    def _get_params_preserve(self, failobj, header):
+        # Like get_params() but preserves the quoting of values.  BAW:
+        # should this be part of the public interface?
+        missing = object()
+        value = self.get(header, missing)
+        if value is missing:
+            return failobj
+        params = []
+        for p in _parseparam(';' + value):
+            try:
+                name, val = p.split('=', 1)
+                name = name.strip()
+                val = val.strip()
+            except ValueError:
+                # Must have been a bare attribute
+                name = p.strip()
+                val = ''
+            params.append((name, val))
+        params = utils.decode_params(params)
+        return params
+
+    def get_params(self, failobj=None, header='content-type', unquote=True):
+        """Return the message's Content-Type parameters, as a list.
+
+        The elements of the returned list are 2-tuples of key/value pairs, as
+        split on the `=' sign.  The left hand side of the `=' is the key,
+        while the right hand side is the value.  If there is no `=' sign in
+        the parameter the value is the empty string.  The value is as
+        described in the get_param() method.
+
+        Optional failobj is the object to return if there is no Content-Type
+        header.  Optional header is the header to search instead of
+        Content-Type.  If unquote is True, the value is unquoted.
+        """
+        missing = object()
+        params = self._get_params_preserve(missing, header)
+        if params is missing:
+            return failobj
+        if unquote:
+            return [(k, _unquotevalue(v)) for k, v in params]
+        else:
+            return params
+
+    def get_param(self, param, failobj=None, header='content-type',
+                  unquote=True):
+        """Return the parameter value if found in the Content-Type header.
+
+        Optional failobj is the object to return if there is no Content-Type
+        header, or the Content-Type header has no such parameter.  Optional
+        header is the header to search instead of Content-Type.
+
+        Parameter keys are always compared case insensitively.  The return
+        value can either be a string, or a 3-tuple if the parameter was RFC
+        2231 encoded.  When it's a 3-tuple, the elements of the value are of
+        the form (CHARSET, LANGUAGE, VALUE).  Note that both CHARSET and
+        LANGUAGE can be None, in which case you should consider VALUE to be
+        encoded in the us-ascii charset.  You can usually ignore LANGUAGE.
+
+        Your application should be prepared to deal with 3-tuple return
+        values, and can convert the parameter to a Unicode string like so:
+
+            param = msg.get_param('foo')
+            if isinstance(param, tuple):
+                param = unicode(param[2], param[0] or 'us-ascii')
+
+        In any case, the parameter value (either the returned string, or the
+        VALUE item in the 3-tuple) is always unquoted, unless unquote is set
+        to False.
+        """
+        if not self.has_key(header):
+            return failobj
+        for k, v in self._get_params_preserve(failobj, header):
+            if k.lower() == param.lower():
+                if unquote:
+                    return _unquotevalue(v)
+                else:
+                    return v
+        return failobj
+
+    def set_param(self, param, value, header='Content-Type', requote=True,
+                  charset=None, language=''):
+        """Set a parameter in the Content-Type header.
+
+        If the parameter already exists in the header, its value will be
+        replaced with the new value.
+
+        If header is Content-Type and has not yet been defined for this
+        message, it will be set to "text/plain" and the new parameter and
+        value will be appended as per RFC 2045.
+
+        An alternate header can specified in the header argument, and all
+        parameters will be quoted as necessary unless requote is False.
+
+        If charset is specified, the parameter will be encoded according to RFC
+        2231.  Optional language specifies the RFC 2231 language, defaulting
+        to the empty string.  Both charset and language should be strings.
+        """
+        if not isinstance(value, tuple) and charset:
+            value = (charset, language, value)
+
+        if not self.has_key(header) and header.lower() == 'content-type':
+            ctype = 'text/plain'
+        else:
+            ctype = self.get(header)
+        if not self.get_param(param, header=header):
+            if not ctype:
+                ctype = _formatparam(param, value, requote)
+            else:
+                ctype = SEMISPACE.join(
+                    [ctype, _formatparam(param, value, requote)])
+        else:
+            ctype = ''
+            for old_param, old_value in self.get_params(header=header,
+                                                        unquote=requote):
+                append_param = ''
+                if old_param.lower() == param.lower():
+                    append_param = _formatparam(param, value, requote)
+                else:
+                    append_param = _formatparam(old_param, old_value, requote)
+                if not ctype:
+                    ctype = append_param
+                else:
+                    ctype = SEMISPACE.join([ctype, append_param])
+        if ctype <> self.get(header):
+            del self[header]
+            self[header] = ctype
+
+    def del_param(self, param, header='content-type', requote=True):
+        """Remove the given parameter completely from the Content-Type header.
+
+        The header will be re-written in place without the parameter or its
+        value. All values will be quoted as necessary unless requote is
+        False.  Optional header specifies an alternative to the Content-Type
+        header.
+        """
+        if not self.has_key(header):
+            return
+        new_ctype = ''
+        for p, v in self.get_params(header=header, unquote=requote):
+            if p.lower() <> param.lower():
+                if not new_ctype:
+                    new_ctype = _formatparam(p, v, requote)
+                else:
+                    new_ctype = SEMISPACE.join([new_ctype,
+                                                _formatparam(p, v, requote)])
+        if new_ctype <> self.get(header):
+            del self[header]
+            self[header] = new_ctype
+
+    def set_type(self, type, header='Content-Type', requote=True):
+        """Set the main type and subtype for the Content-Type header.
+
+        type must be a string in the form "maintype/subtype", otherwise a
+        ValueError is raised.
+
+        This method replaces the Content-Type header, keeping all the
+        parameters in place.  If requote is False, this leaves the existing
+        header's quoting as is.  Otherwise, the parameters will be quoted (the
+        default).
+
+        An alternative header can be specified in the header argument.  When
+        the Content-Type header is set, we'll always also add a MIME-Version
+        header.
+        """
+        # BAW: should we be strict?
+        if not type.count('/') == 1:
+            raise ValueError
+        # Set the Content-Type, you get a MIME-Version
+        if header.lower() == 'content-type':
+            del self['mime-version']
+            self['MIME-Version'] = '1.0'
+        if not self.has_key(header):
+            self[header] = type
+            return
+        params = self.get_params(header=header, unquote=requote)
+        del self[header]
+        self[header] = type
+        # Skip the first param; it's the old type.
+        for p, v in params[1:]:
+            self.set_param(p, v, header, requote)
+
+    def get_filename(self, failobj=None):
+        """Return the filename associated with the payload if present.
+
+        The filename is extracted from the Content-Disposition header's
+        `filename' parameter, and it is unquoted.  If that header is missing
+        the `filename' parameter, this method falls back to looking for the
+        `name' parameter.
+        """
+        missing = object()
+        filename = self.get_param('filename', missing, 'content-disposition')
+        if filename is missing:
+            filename = self.get_param('name', missing, 'content-disposition')
+        if filename is missing:
+            return failobj
+        return utils.collapse_rfc2231_value(filename).strip()
+
+    def get_boundary(self, failobj=None):
+        """Return the boundary associated with the payload if present.
+
+        The boundary is extracted from the Content-Type header's `boundary'
+        parameter, and it is unquoted.
+        """
+        missing = object()
+        boundary = self.get_param('boundary', missing)
+        if boundary is missing:
+            return failobj
+        # RFC 2046 says that boundaries may begin but not end in w/s
+        return utils.collapse_rfc2231_value(boundary).rstrip()
+
+    def set_boundary(self, boundary):
+        """Set the boundary parameter in Content-Type to 'boundary'.
+
+        This is subtly different than deleting the Content-Type header and
+        adding a new one with a new boundary parameter via add_header().  The
+        main difference is that using the set_boundary() method preserves the
+        order of the Content-Type header in the original message.
+
+        HeaderParseError is raised if the message has no Content-Type header.
+        """
+        missing = object()
+        params = self._get_params_preserve(missing, 'content-type')
+        if params is missing:
+            # There was no Content-Type header, and we don't know what type
+            # to set it to, so raise an exception.
+            raise errors.HeaderParseError('No Content-Type header found')
+        newparams = []
+        foundp = False
+        for pk, pv in params:
+            if pk.lower() == 'boundary':
+                newparams.append(('boundary', '"%s"' % boundary))
+                foundp = True
+            else:
+                newparams.append((pk, pv))
+        if not foundp:
+            # The original Content-Type header had no boundary attribute.
+            # Tack one on the end.  BAW: should we raise an exception
+            # instead???
+            newparams.append(('boundary', '"%s"' % boundary))
+        # Replace the existing Content-Type header with the new value
+        newheaders = []
+        for h, v in self._headers:
+            if h.lower() == 'content-type':
+                parts = []
+                for k, v in newparams:
+                    if v == '':
+                        parts.append(k)
+                    else:
+                        parts.append('%s=%s' % (k, v))
+                newheaders.append((h, SEMISPACE.join(parts)))
+
+            else:
+                newheaders.append((h, v))
+        self._headers = newheaders
+
+    def get_content_charset(self, failobj=None):
+        """Return the charset parameter of the Content-Type header.
+
+        The returned string is always coerced to lower case.  If there is no
+        Content-Type header, or if that header has no charset parameter,
+        failobj is returned.
+        """
+        missing = object()
+        charset = self.get_param('charset', missing)
+        if charset is missing:
+            return failobj
+        if isinstance(charset, tuple):
+            # RFC 2231 encoded, so decode it, and it better end up as ascii.
+            pcharset = charset[0] or 'us-ascii'
+            try:
+                # LookupError will be raised if the charset isn't known to
+                # Python.  UnicodeError will be raised if the encoded text
+                # contains a character not in the charset.
+                charset = unicode(charset[2], pcharset).encode('us-ascii')
+            except (LookupError, UnicodeError):
+                charset = charset[2]
+        # charset character must be in us-ascii range
+        try:
+            if isinstance(charset, str):
+                charset = unicode(charset, 'us-ascii')
+            charset = charset.encode('us-ascii')
+        except UnicodeError:
+            return failobj
+        # RFC 2046, $4.1.2 says charsets are not case sensitive
+        return charset.lower()
+
+    def get_charsets(self, failobj=None):
+        """Return a list containing the charset(s) used in this message.
+
+        The returned list of items describes the Content-Type headers'
+        charset parameter for this message and all the subparts in its
+        payload.
+
+        Each item will either be a string (the value of the charset parameter
+        in the Content-Type header of that part) or the value of the
+        'failobj' parameter (defaults to None), if the part does not have a
+        main MIME type of "text", or the charset is not defined.
+
+        The list will contain one string for each part of the message, plus
+        one for the container message (i.e. self), so that a non-multipart
+        message will still return a list of length 1.
+        """
+        return [part.get_content_charset(failobj) for part in self.walk()]
+
+    # I.e. def walk(self): ...
+    from email.Iterators import walk

Added: vendor/Python/current/Lib/email/mime/__init__.py
===================================================================

Added: vendor/Python/current/Lib/email/mime/application.py
===================================================================
--- vendor/Python/current/Lib/email/mime/application.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/mime/application.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,36 @@
+# Copyright (C) 2001-2006 Python Software Foundation
+# Author: Keith Dart
+# Contact: email-sig at python.org
+
+"""Class representing application/* type MIME documents."""
+
+__all__ = ["MIMEApplication"]
+
+from email import encoders
+from email.mime.nonmultipart import MIMENonMultipart
+
+
+class MIMEApplication(MIMENonMultipart):
+    """Class for generating application/* MIME documents."""
+
+    def __init__(self, _data, _subtype='octet-stream',
+                 _encoder=encoders.encode_base64, **_params):
+        """Create an application/* type MIME document.
+
+        _data is a string containing the raw applicatoin data.
+
+        _subtype is the MIME content type subtype, defaulting to
+        'octet-stream'.
+
+        _encoder is a function which will perform the actual encoding for
+        transport of the application data, defaulting to base64 encoding.
+
+        Any additional keyword arguments are passed to the base class
+        constructor, which turns them into parameters on the Content-Type
+        header.
+        """
+        if _subtype is None:
+            raise TypeError('Invalid application MIME subtype')
+        MIMENonMultipart.__init__(self, 'application', _subtype, **_params)
+        self.set_payload(_data)
+        _encoder(self)

Added: vendor/Python/current/Lib/email/mime/audio.py
===================================================================
--- vendor/Python/current/Lib/email/mime/audio.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/mime/audio.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,73 @@
+# Copyright (C) 2001-2006 Python Software Foundation
+# Author: Anthony Baxter
+# Contact: email-sig at python.org
+
+"""Class representing audio/* type MIME documents."""
+
+__all__ = ['MIMEAudio']
+
+import sndhdr
+
+from cStringIO import StringIO
+from email import encoders
+from email.mime.nonmultipart import MIMENonMultipart
+
+
+
+_sndhdr_MIMEmap = {'au'  : 'basic',
+                   'wav' :'x-wav',
+                   'aiff':'x-aiff',
+                   'aifc':'x-aiff',
+                   }
+
+# There are others in sndhdr that don't have MIME types. :(
+# Additional ones to be added to sndhdr? midi, mp3, realaudio, wma??
+def _whatsnd(data):
+    """Try to identify a sound file type.
+
+    sndhdr.what() has a pretty cruddy interface, unfortunately.  This is why
+    we re-do it here.  It would be easier to reverse engineer the Unix 'file'
+    command and use the standard 'magic' file, as shipped with a modern Unix.
+    """
+    hdr = data[:512]
+    fakefile = StringIO(hdr)
+    for testfn in sndhdr.tests:
+        res = testfn(hdr, fakefile)
+        if res is not None:
+            return _sndhdr_MIMEmap.get(res[0])
+    return None
+
+
+
+class MIMEAudio(MIMENonMultipart):
+    """Class for generating audio/* MIME documents."""
+
+    def __init__(self, _audiodata, _subtype=None,
+                 _encoder=encoders.encode_base64, **_params):
+        """Create an audio/* type MIME document.
+
+        _audiodata is a string containing the raw audio data.  If this data
+        can be decoded by the standard Python `sndhdr' module, then the
+        subtype will be automatically included in the Content-Type header.
+        Otherwise, you can specify  the specific audio subtype via the
+        _subtype parameter.  If _subtype is not given, and no subtype can be
+        guessed, a TypeError is raised.
+
+        _encoder is a function which will perform the actual encoding for
+        transport of the image data.  It takes one argument, which is this
+        Image instance.  It should use get_payload() and set_payload() to
+        change the payload to the encoded form.  It should also add any
+        Content-Transfer-Encoding or other headers to the message as
+        necessary.  The default encoding is Base64.
+
+        Any additional keyword arguments are passed to the base class
+        constructor, which turns them into parameters on the Content-Type
+        header.
+        """
+        if _subtype is None:
+            _subtype = _whatsnd(_audiodata)
+        if _subtype is None:
+            raise TypeError('Could not find audio MIME subtype')
+        MIMENonMultipart.__init__(self, 'audio', _subtype, **_params)
+        self.set_payload(_audiodata)
+        _encoder(self)

Added: vendor/Python/current/Lib/email/mime/base.py
===================================================================
--- vendor/Python/current/Lib/email/mime/base.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/mime/base.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,26 @@
+# Copyright (C) 2001-2006 Python Software Foundation
+# Author: Barry Warsaw
+# Contact: email-sig at python.org
+
+"""Base class for MIME specializations."""
+
+__all__ = ['MIMEBase']
+
+from email import message
+
+
+
+class MIMEBase(message.Message):
+    """Base class for MIME specializations."""
+
+    def __init__(self, _maintype, _subtype, **_params):
+        """This constructor adds a Content-Type: and a MIME-Version: header.
+
+        The Content-Type: header is taken from the _maintype and _subtype
+        arguments.  Additional parameters for this header are taken from the
+        keyword arguments.
+        """
+        message.Message.__init__(self)
+        ctype = '%s/%s' % (_maintype, _subtype)
+        self.add_header('Content-Type', ctype, **_params)
+        self['MIME-Version'] = '1.0'

Added: vendor/Python/current/Lib/email/mime/image.py
===================================================================
--- vendor/Python/current/Lib/email/mime/image.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/mime/image.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,46 @@
+# Copyright (C) 2001-2006 Python Software Foundation
+# Author: Barry Warsaw
+# Contact: email-sig at python.org
+
+"""Class representing image/* type MIME documents."""
+
+__all__ = ['MIMEImage']
+
+import imghdr
+
+from email import encoders
+from email.mime.nonmultipart import MIMENonMultipart
+
+
+
+class MIMEImage(MIMENonMultipart):
+    """Class for generating image/* type MIME documents."""
+
+    def __init__(self, _imagedata, _subtype=None,
+                 _encoder=encoders.encode_base64, **_params):
+        """Create an image/* type MIME document.
+
+        _imagedata is a string containing the raw image data.  If this data
+        can be decoded by the standard Python `imghdr' module, then the
+        subtype will be automatically included in the Content-Type header.
+        Otherwise, you can specify the specific image subtype via the _subtype
+        parameter.
+
+        _encoder is a function which will perform the actual encoding for
+        transport of the image data.  It takes one argument, which is this
+        Image instance.  It should use get_payload() and set_payload() to
+        change the payload to the encoded form.  It should also add any
+        Content-Transfer-Encoding or other headers to the message as
+        necessary.  The default encoding is Base64.
+
+        Any additional keyword arguments are passed to the base class
+        constructor, which turns them into parameters on the Content-Type
+        header.
+        """
+        if _subtype is None:
+            _subtype = imghdr.what(None, _imagedata)
+        if _subtype is None:
+            raise TypeError('Could not guess image MIME subtype')
+        MIMENonMultipart.__init__(self, 'image', _subtype, **_params)
+        self.set_payload(_imagedata)
+        _encoder(self)

Added: vendor/Python/current/Lib/email/mime/message.py
===================================================================
--- vendor/Python/current/Lib/email/mime/message.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/mime/message.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,34 @@
+# Copyright (C) 2001-2006 Python Software Foundation
+# Author: Barry Warsaw
+# Contact: email-sig at python.org
+
+"""Class representing message/* MIME documents."""
+
+__all__ = ['MIMEMessage']
+
+from email import message
+from email.mime.nonmultipart import MIMENonMultipart
+
+
+
+class MIMEMessage(MIMENonMultipart):
+    """Class representing message/* MIME documents."""
+
+    def __init__(self, _msg, _subtype='rfc822'):
+        """Create a message/* type MIME document.
+
+        _msg is a message object and must be an instance of Message, or a
+        derived class of Message, otherwise a TypeError is raised.
+
+        Optional _subtype defines the subtype of the contained message.  The
+        default is "rfc822" (this is defined by the MIME standard, even though
+        the term "rfc822" is technically outdated by RFC 2822).
+        """
+        MIMENonMultipart.__init__(self, 'message', _subtype)
+        if not isinstance(_msg, message.Message):
+            raise TypeError('Argument is not an instance of Message')
+        # It's convenient to use this base class method.  We need to do it
+        # this way or we'll get an exception
+        message.Message.attach(self, _msg)
+        # And be sure our default type is set correctly
+        self.set_default_type('message/rfc822')

Added: vendor/Python/current/Lib/email/mime/multipart.py
===================================================================
--- vendor/Python/current/Lib/email/mime/multipart.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/mime/multipart.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,41 @@
+# Copyright (C) 2002-2006 Python Software Foundation
+# Author: Barry Warsaw
+# Contact: email-sig at python.org
+
+"""Base class for MIME multipart/* type messages."""
+
+__all__ = ['MIMEMultipart']
+
+from email.mime.base import MIMEBase
+
+
+
+class MIMEMultipart(MIMEBase):
+    """Base class for MIME multipart/* type messages."""
+
+    def __init__(self, _subtype='mixed', boundary=None, _subparts=None,
+                 **_params):
+        """Creates a multipart/* type message.
+
+        By default, creates a multipart/mixed message, with proper
+        Content-Type and MIME-Version headers.
+
+        _subtype is the subtype of the multipart content type, defaulting to
+        `mixed'.
+
+        boundary is the multipart boundary string.  By default it is
+        calculated as needed.
+
+        _subparts is a sequence of initial subparts for the payload.  It
+        must be an iterable object, such as a list.  You can always
+        attach new subparts to the message by using the attach() method.
+
+        Additional parameters for the Content-Type header are taken from the
+        keyword arguments (or passed into the _params argument).
+        """
+        MIMEBase.__init__(self, 'multipart', _subtype, **_params)
+        if _subparts:
+            for p in _subparts:
+                self.attach(p)
+        if boundary:
+            self.set_boundary(boundary)

Added: vendor/Python/current/Lib/email/mime/nonmultipart.py
===================================================================
--- vendor/Python/current/Lib/email/mime/nonmultipart.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/mime/nonmultipart.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,26 @@
+# Copyright (C) 2002-2006 Python Software Foundation
+# Author: Barry Warsaw
+# Contact: email-sig at python.org
+
+"""Base class for MIME type messages that are not multipart."""
+
+__all__ = ['MIMENonMultipart']
+
+from email import errors
+from email.mime.base import MIMEBase
+
+
+
+class MIMENonMultipart(MIMEBase):
+    """Base class for MIME multipart/* type messages."""
+
+    __pychecker__ = 'unusednames=payload'
+
+    def attach(self, payload):
+        # The public API prohibits attaching multiple subparts to MIMEBase
+        # derived subtypes since none of them are, by definition, of content
+        # type multipart/*
+        raise errors.MultipartConversionError(
+            'Cannot attach additional subparts to non-multipart/*')
+
+    del __pychecker__

Added: vendor/Python/current/Lib/email/mime/text.py
===================================================================
--- vendor/Python/current/Lib/email/mime/text.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/mime/text.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,30 @@
+# Copyright (C) 2001-2006 Python Software Foundation
+# Author: Barry Warsaw
+# Contact: email-sig at python.org
+
+"""Class representing text/* type MIME documents."""
+
+__all__ = ['MIMEText']
+
+from email.encoders import encode_7or8bit
+from email.mime.nonmultipart import MIMENonMultipart
+
+
+
+class MIMEText(MIMENonMultipart):
+    """Class for generating text/* type MIME documents."""
+
+    def __init__(self, _text, _subtype='plain', _charset='us-ascii'):
+        """Create a text/* type MIME document.
+
+        _text is the string for this message object.
+
+        _subtype is the MIME sub content type, defaulting to "plain".
+
+        _charset is the character set parameter added to the Content-Type
+        header.  This defaults to "us-ascii".  Note that as a side-effect, the
+        Content-Transfer-Encoding header will also be set.
+        """
+        MIMENonMultipart.__init__(self, 'text', _subtype,
+                                  **{'charset': _charset})
+        self.set_payload(_text, _charset)

Added: vendor/Python/current/Lib/email/parser.py
===================================================================
--- vendor/Python/current/Lib/email/parser.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/parser.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,91 @@
+# Copyright (C) 2001-2006 Python Software Foundation
+# Author: Barry Warsaw, Thomas Wouters, Anthony Baxter
+# Contact: email-sig at python.org
+
+"""A parser of RFC 2822 and MIME email messages."""
+
+__all__ = ['Parser', 'HeaderParser']
+
+import warnings
+from cStringIO import StringIO
+
+from email.feedparser import FeedParser
+from email.message import Message
+
+
+
+class Parser:
+    def __init__(self, *args, **kws):
+        """Parser of RFC 2822 and MIME email messages.
+
+        Creates an in-memory object tree representing the email message, which
+        can then be manipulated and turned over to a Generator to return the
+        textual representation of the message.
+
+        The string must be formatted as a block of RFC 2822 headers and header
+        continuation lines, optionally preceeded by a `Unix-from' header.  The
+        header block is terminated either by the end of the string or by a
+        blank line.
+
+        _class is the class to instantiate for new message objects when they
+        must be created.  This class must have a constructor that can take
+        zero arguments.  Default is Message.Message.
+        """
+        if len(args) >= 1:
+            if '_class' in kws:
+                raise TypeError("Multiple values for keyword arg '_class'")
+            kws['_class'] = args[0]
+        if len(args) == 2:
+            if 'strict' in kws:
+                raise TypeError("Multiple values for keyword arg 'strict'")
+            kws['strict'] = args[1]
+        if len(args) > 2:
+            raise TypeError('Too many arguments')
+        if '_class' in kws:
+            self._class = kws['_class']
+            del kws['_class']
+        else:
+            self._class = Message
+        if 'strict' in kws:
+            warnings.warn("'strict' argument is deprecated (and ignored)",
+                          DeprecationWarning, 2)
+            del kws['strict']
+        if kws:
+            raise TypeError('Unexpected keyword arguments')
+
+    def parse(self, fp, headersonly=False):
+        """Create a message structure from the data in a file.
+
+        Reads all the data from the file and returns the root of the message
+        structure.  Optional headersonly is a flag specifying whether to stop
+        parsing after reading the headers or not.  The default is False,
+        meaning it parses the entire contents of the file.
+        """
+        feedparser = FeedParser(self._class)
+        if headersonly:
+            feedparser._set_headersonly()
+        while True:
+            data = fp.read(8192)
+            if not data:
+                break
+            feedparser.feed(data)
+        return feedparser.close()
+
+    def parsestr(self, text, headersonly=False):
+        """Create a message structure from a string.
+
+        Returns the root of the message structure.  Optional headersonly is a
+        flag specifying whether to stop parsing after reading the headers or
+        not.  The default is False, meaning it parses the entire contents of
+        the file.
+        """
+        return self.parse(StringIO(text), headersonly=headersonly)
+
+
+
+class HeaderParser(Parser):
+    def parse(self, fp, headersonly=True):
+        return Parser.parse(self, fp, True)
+
+    def parsestr(self, text, headersonly=True):
+        return Parser.parsestr(self, text, True)

Added: vendor/Python/current/Lib/email/quoprimime.py
===================================================================
--- vendor/Python/current/Lib/email/quoprimime.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/quoprimime.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,336 @@
+# Copyright (C) 2001-2006 Python Software Foundation
+# Author: Ben Gertzfield
+# Contact: email-sig at python.org
+
+"""Quoted-printable content transfer encoding per RFCs 2045-2047.
+
+This module handles the content transfer encoding method defined in RFC 2045
+to encode US ASCII-like 8-bit data called `quoted-printable'.  It is used to
+safely encode text that is in a character set similar to the 7-bit US ASCII
+character set, but that includes some 8-bit characters that are normally not
+allowed in email bodies or headers.
+
+Quoted-printable is very space-inefficient for encoding binary files; use the
+email.base64MIME module for that instead.
+
+This module provides an interface to encode and decode both headers and bodies
+with quoted-printable encoding.
+
+RFC 2045 defines a method for including character set information in an
+`encoded-word' in a header.  This method is commonly used for 8-bit real names
+in To:/From:/Cc: etc. fields, as well as Subject: lines.
+
+This module does not do the line wrapping or end-of-line character
+conversion necessary for proper internationalized headers; it only
+does dumb encoding and decoding.  To deal with the various line
+wrapping issues, use the email.Header module.
+"""
+
+__all__ = [
+    'body_decode',
+    'body_encode',
+    'body_quopri_check',
+    'body_quopri_len',
+    'decode',
+    'decodestring',
+    'encode',
+    'encodestring',
+    'header_decode',
+    'header_encode',
+    'header_quopri_check',
+    'header_quopri_len',
+    'quote',
+    'unquote',
+    ]
+
+import re
+
+from string import hexdigits
+from email.utils import fix_eols
+
+CRLF = '\r\n'
+NL = '\n'
+
+# See also Charset.py
+MISC_LEN = 7
+
+hqre = re.compile(r'[^-a-zA-Z0-9!*+/ ]')
+bqre = re.compile(r'[^ !-<>-~\t]')
+
+
+
+# Helpers
+def header_quopri_check(c):
+    """Return True if the character should be escaped with header quopri."""
+    return bool(hqre.match(c))
+
+
+def body_quopri_check(c):
+    """Return True if the character should be escaped with body quopri."""
+    return bool(bqre.match(c))
+
+
+def header_quopri_len(s):
+    """Return the length of str when it is encoded with header quopri."""
+    count = 0
+    for c in s:
+        if hqre.match(c):
+            count += 3
+        else:
+            count += 1
+    return count
+
+
+def body_quopri_len(str):
+    """Return the length of str when it is encoded with body quopri."""
+    count = 0
+    for c in str:
+        if bqre.match(c):
+            count += 3
+        else:
+            count += 1
+    return count
+
+
+def _max_append(L, s, maxlen, extra=''):
+    if not L:
+        L.append(s.lstrip())
+    elif len(L[-1]) + len(s) <= maxlen:
+        L[-1] += extra + s
+    else:
+        L.append(s.lstrip())
+
+
+def unquote(s):
+    """Turn a string in the form =AB to the ASCII character with value 0xab"""
+    return chr(int(s[1:3], 16))
+
+
+def quote(c):
+    return "=%02X" % ord(c)
+
+
+
+def header_encode(header, charset="iso-8859-1", keep_eols=False,
+                  maxlinelen=76, eol=NL):
+    """Encode a single header line with quoted-printable (like) encoding.
+
+    Defined in RFC 2045, this `Q' encoding is similar to quoted-printable, but
+    used specifically for email header fields to allow charsets with mostly 7
+    bit characters (and some 8 bit) to remain more or less readable in non-RFC
+    2045 aware mail clients.
+
+    charset names the character set to use to encode the header.  It defaults
+    to iso-8859-1.
+
+    The resulting string will be in the form:
+
+    "=?charset?q?I_f=E2rt_in_your_g=E8n=E8ral_dire=E7tion?\\n
+      =?charset?q?Silly_=C8nglish_Kn=EEghts?="
+
+    with each line wrapped safely at, at most, maxlinelen characters (defaults
+    to 76 characters).  If maxlinelen is None, the entire string is encoded in
+    one chunk with no splitting.
+
+    End-of-line characters (\\r, \\n, \\r\\n) will be automatically converted
+    to the canonical email line separator \\r\\n unless the keep_eols
+    parameter is True (the default is False).
+
+    Each line of the header will be terminated in the value of eol, which
+    defaults to "\\n".  Set this to "\\r\\n" if you are using the result of
+    this function directly in email.
+    """
+    # Return empty headers unchanged
+    if not header:
+        return header
+
+    if not keep_eols:
+        header = fix_eols(header)
+
+    # Quopri encode each line, in encoded chunks no greater than maxlinelen in
+    # length, after the RFC chrome is added in.
+    quoted = []
+    if maxlinelen is None:
+        # An obnoxiously large number that's good enough
+        max_encoded = 100000
+    else:
+        max_encoded = maxlinelen - len(charset) - MISC_LEN - 1
+
+    for c in header:
+        # Space may be represented as _ instead of =20 for readability
+        if c == ' ':
+            _max_append(quoted, '_', max_encoded)
+        # These characters can be included verbatim
+        elif not hqre.match(c):
+            _max_append(quoted, c, max_encoded)
+        # Otherwise, replace with hex value like =E2
+        else:
+            _max_append(quoted, "=%02X" % ord(c), max_encoded)
+
+    # Now add the RFC chrome to each encoded chunk and glue the chunks
+    # together.  BAW: should we be able to specify the leading whitespace in
+    # the joiner?
+    joiner = eol + ' '
+    return joiner.join(['=?%s?q?%s?=' % (charset, line) for line in quoted])
+
+
+
+def encode(body, binary=False, maxlinelen=76, eol=NL):
+    """Encode with quoted-printable, wrapping at maxlinelen characters.
+
+    If binary is False (the default), end-of-line characters will be converted
+    to the canonical email end-of-line sequence \\r\\n.  Otherwise they will
+    be left verbatim.
+
+    Each line of encoded text will end with eol, which defaults to "\\n".  Set
+    this to "\\r\\n" if you will be using the result of this function directly
+    in an email.
+
+    Each line will be wrapped at, at most, maxlinelen characters (defaults to
+    76 characters).  Long lines will have the `soft linefeed' quoted-printable
+    character "=" appended to them, so the decoded text will be identical to
+    the original text.
+    """
+    if not body:
+        return body
+
+    if not binary:
+        body = fix_eols(body)
+
+    # BAW: We're accumulating the body text by string concatenation.  That
+    # can't be very efficient, but I don't have time now to rewrite it.  It
+    # just feels like this algorithm could be more efficient.
+    encoded_body = ''
+    lineno = -1
+    # Preserve line endings here so we can check later to see an eol needs to
+    # be added to the output later.
+    lines = body.splitlines(1)
+    for line in lines:
+        # But strip off line-endings for processing this line.
+        if line.endswith(CRLF):
+            line = line[:-2]
+        elif line[-1] in CRLF:
+            line = line[:-1]
+
+        lineno += 1
+        encoded_line = ''
+        prev = None
+        linelen = len(line)
+        # Now we need to examine every character to see if it needs to be
+        # quopri encoded.  BAW: again, string concatenation is inefficient.
+        for j in range(linelen):
+            c = line[j]
+            prev = c
+            if bqre.match(c):
+                c = quote(c)
+            elif j+1 == linelen:
+                # Check for whitespace at end of line; special case
+                if c not in ' \t':
+                    encoded_line += c
+                prev = c
+                continue
+            # Check to see to see if the line has reached its maximum length
+            if len(encoded_line) + len(c) >= maxlinelen:
+                encoded_body += encoded_line + '=' + eol
+                encoded_line = ''
+            encoded_line += c
+        # Now at end of line..
+        if prev and prev in ' \t':
+            # Special case for whitespace at end of file
+            if lineno + 1 == len(lines):
+                prev = quote(prev)
+                if len(encoded_line) + len(prev) > maxlinelen:
+                    encoded_body += encoded_line + '=' + eol + prev
+                else:
+                    encoded_body += encoded_line + prev
+            # Just normal whitespace at end of line
+            else:
+                encoded_body += encoded_line + prev + '=' + eol
+            encoded_line = ''
+        # Now look at the line we just finished and it has a line ending, we
+        # need to add eol to the end of the line.
+        if lines[lineno].endswith(CRLF) or lines[lineno][-1] in CRLF:
+            encoded_body += encoded_line + eol
+        else:
+            encoded_body += encoded_line
+        encoded_line = ''
+    return encoded_body
+
+
+# For convenience and backwards compatibility w/ standard base64 module
+body_encode = encode
+encodestring = encode
+
+
+
+# BAW: I'm not sure if the intent was for the signature of this function to be
+# the same as base64MIME.decode() or not...
+def decode(encoded, eol=NL):
+    """Decode a quoted-printable string.
+
+    Lines are separated with eol, which defaults to \\n.
+    """
+    if not encoded:
+        return encoded
+    # BAW: see comment in encode() above.  Again, we're building up the
+    # decoded string with string concatenation, which could be done much more
+    # efficiently.
+    decoded = ''
+
+    for line in encoded.splitlines():
+        line = line.rstrip()
+        if not line:
+            decoded += eol
+            continue
+
+        i = 0
+        n = len(line)
+        while i < n:
+            c = line[i]
+            if c <> '=':
+                decoded += c
+                i += 1
+            # Otherwise, c == "=".  Are we at the end of the line?  If so, add
+            # a soft line break.
+            elif i+1 == n:
+                i += 1
+                continue
+            # Decode if in form =AB
+            elif i+2 < n and line[i+1] in hexdigits and line[i+2] in hexdigits:
+                decoded += unquote(line[i:i+3])
+                i += 3
+            # Otherwise, not in form =AB, pass literally
+            else:
+                decoded += c
+                i += 1
+
+            if i == n:
+                decoded += eol
+    # Special case if original string did not end with eol
+    if not encoded.endswith(eol) and decoded.endswith(eol):
+        decoded = decoded[:-1]
+    return decoded
+
+
+# For convenience and backwards compatibility w/ standard base64 module
+body_decode = decode
+decodestring = decode
+
+
+
+def _unquote_match(match):
+    """Turn a match in the form =AB to the ASCII character with value 0xab"""
+    s = match.group(0)
+    return unquote(s)
+
+
+# Header decoding is done a bit differently
+def header_decode(s):
+    """Decode a string encoded with RFC 2045 MIME header `Q' encoding.
+
+    This function does not parse a full MIME header value encoded with
+    quoted-printable (like =?iso-8895-1?q?Hello_World?=) -- please use
+    the high level email.Header class for that functionality.
+    """
+    s = s.replace('_', ' ')
+    return re.sub(r'=\w{2}', _unquote_match, s)

Added: vendor/Python/current/Lib/email/test/__init__.py
===================================================================

Added: vendor/Python/current/Lib/email/test/data/PyBanner048.gif
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Lib/email/test/data/PyBanner048.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Lib/email/test/data/audiotest.au
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Lib/email/test/data/audiotest.au
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Lib/email/test/data/msg_01.txt
===================================================================
--- vendor/Python/current/Lib/email/test/data/msg_01.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/test/data/msg_01.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,19 @@
+Return-Path: <bbb at zzz.org>
+Delivered-To: bbb at zzz.org
+Received: by mail.zzz.org (Postfix, from userid 889)
+	id 27CEAD38CC; Fri,  4 May 2001 14:05:44 -0400 (EDT)
+MIME-Version: 1.0
+Content-Type: text/plain; charset=us-ascii
+Content-Transfer-Encoding: 7bit
+Message-ID: <15090.61304.110929.45684 at aaa.zzz.org>
+From: bbb at ddd.com (John X. Doe)
+To: bbb at zzz.org
+Subject: This is a test message
+Date: Fri, 4 May 2001 14:05:44 -0400
+
+
+Hi,
+
+Do you like this message?
+
+-Me

Added: vendor/Python/current/Lib/email/test/data/msg_02.txt
===================================================================
--- vendor/Python/current/Lib/email/test/data/msg_02.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/test/data/msg_02.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,135 @@
+MIME-version: 1.0
+From: ppp-request at zzz.org
+Sender: ppp-admin at zzz.org
+To: ppp at zzz.org
+Subject: Ppp digest, Vol 1 #2 - 5 msgs
+Date: Fri, 20 Apr 2001 20:18:00 -0400 (EDT)
+X-Mailer: Mailman v2.0.4
+X-Mailman-Version: 2.0.4
+Content-Type: multipart/mixed; boundary="192.168.1.2.889.32614.987812255.500.21814"
+
+--192.168.1.2.889.32614.987812255.500.21814
+Content-type: text/plain; charset=us-ascii
+Content-description: Masthead (Ppp digest, Vol 1 #2)
+
+Send Ppp mailing list submissions to
+	ppp at zzz.org
+
+To subscribe or unsubscribe via the World Wide Web, visit
+	http://www.zzz.org/mailman/listinfo/ppp
+or, via email, send a message with subject or body 'help' to
+	ppp-request at zzz.org
+
+You can reach the person managing the list at
+	ppp-admin at zzz.org
+
+When replying, please edit your Subject line so it is more specific
+than "Re: Contents of Ppp digest..."
+
+
+--192.168.1.2.889.32614.987812255.500.21814
+Content-type: text/plain; charset=us-ascii
+Content-description: Today's Topics (5 msgs)
+
+Today's Topics:
+
+   1. testing #1 (Barry A. Warsaw)
+   2. testing #2 (Barry A. Warsaw)
+   3. testing #3 (Barry A. Warsaw)
+   4. testing #4 (Barry A. Warsaw)
+   5. testing #5 (Barry A. Warsaw)
+
+--192.168.1.2.889.32614.987812255.500.21814
+Content-Type: multipart/digest; boundary="__--__--"
+
+--__--__--
+
+Message: 1
+Content-Type: text/plain; charset=us-ascii
+Content-Transfer-Encoding: 7bit
+Date: Fri, 20 Apr 2001 20:16:13 -0400
+To: ppp at zzz.org
+From: barry at digicool.com (Barry A. Warsaw)
+Subject: [Ppp] testing #1
+Precedence: bulk
+
+
+hello
+
+
+--__--__--
+
+Message: 2
+Date: Fri, 20 Apr 2001 20:16:21 -0400
+Content-Type: text/plain; charset=us-ascii
+Content-Transfer-Encoding: 7bit
+To: ppp at zzz.org
+From: barry at digicool.com (Barry A. Warsaw)
+Precedence: bulk
+
+
+hello
+
+
+--__--__--
+
+Message: 3
+Date: Fri, 20 Apr 2001 20:16:25 -0400
+Content-Type: text/plain; charset=us-ascii
+Content-Transfer-Encoding: 7bit
+To: ppp at zzz.org
+From: barry at digicool.com (Barry A. Warsaw)
+Subject: [Ppp] testing #3
+Precedence: bulk
+
+
+hello
+
+
+--__--__--
+
+Message: 4
+Date: Fri, 20 Apr 2001 20:16:28 -0400
+Content-Type: text/plain; charset=us-ascii
+Content-Transfer-Encoding: 7bit
+To: ppp at zzz.org
+From: barry at digicool.com (Barry A. Warsaw)
+Subject: [Ppp] testing #4
+Precedence: bulk
+
+
+hello
+
+
+--__--__--
+
+Message: 5
+Date: Fri, 20 Apr 2001 20:16:32 -0400
+Content-Type: text/plain; charset=us-ascii
+Content-Transfer-Encoding: 7bit
+To: ppp at zzz.org
+From: barry at digicool.com (Barry A. Warsaw)
+Subject: [Ppp] testing #5
+Precedence: bulk
+
+
+hello
+
+
+
+
+--__--__----
+--192.168.1.2.889.32614.987812255.500.21814
+Content-type: text/plain; charset=us-ascii
+Content-description: Digest Footer
+
+_______________________________________________
+Ppp mailing list
+Ppp at zzz.org
+http://www.zzz.org/mailman/listinfo/ppp
+
+
+--192.168.1.2.889.32614.987812255.500.21814--
+
+End of Ppp Digest
+

Added: vendor/Python/current/Lib/email/test/data/msg_03.txt
===================================================================
--- vendor/Python/current/Lib/email/test/data/msg_03.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/test/data/msg_03.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,16 @@
+Return-Path: <bbb at zzz.org>
+Delivered-To: bbb at zzz.org
+Received: by mail.zzz.org (Postfix, from userid 889)
+	id 27CEAD38CC; Fri,  4 May 2001 14:05:44 -0400 (EDT)
+Message-ID: <15090.61304.110929.45684 at aaa.zzz.org>
+From: bbb at ddd.com (John X. Doe)
+To: bbb at zzz.org
+Subject: This is a test message
+Date: Fri, 4 May 2001 14:05:44 -0400
+
+
+Hi,
+
+Do you like this message?
+
+-Me

Added: vendor/Python/current/Lib/email/test/data/msg_04.txt
===================================================================
--- vendor/Python/current/Lib/email/test/data/msg_04.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/test/data/msg_04.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,37 @@
+Return-Path: <barry at python.org>
+Delivered-To: barry at python.org
+Received: by mail.python.org (Postfix, from userid 889)
+	id C2BF0D37C6; Tue, 11 Sep 2001 00:05:05 -0400 (EDT)
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="h90VIIIKmx"
+Content-Transfer-Encoding: 7bit
+Message-ID: <15261.36209.358846.118674 at anthem.python.org>
+From: barry at python.org (Barry A. Warsaw)
+To: barry at python.org
+Subject: a simple multipart
+Date: Tue, 11 Sep 2001 00:05:05 -0400
+X-Mailer: VM 6.95 under 21.4 (patch 4) "Artificial Intelligence" XEmacs Lucid
+X-Attribution: BAW
+X-Oblique-Strategy: Make a door into a window
+
+
+--h90VIIIKmx
+Content-Type: text/plain
+Content-Disposition: inline;
+	filename="msg.txt"
+Content-Transfer-Encoding: 7bit
+
+a simple kind of mirror
+to reflect upon our own
+
+--h90VIIIKmx
+Content-Type: text/plain
+Content-Disposition: inline;
+	filename="msg.txt"
+Content-Transfer-Encoding: 7bit
+
+a simple kind of mirror
+to reflect upon our own
+
+--h90VIIIKmx--
+

Added: vendor/Python/current/Lib/email/test/data/msg_05.txt
===================================================================
--- vendor/Python/current/Lib/email/test/data/msg_05.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/test/data/msg_05.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,28 @@
+From: foo
+Subject: bar
+To: baz
+MIME-Version: 1.0
+Content-Type: multipart/report; report-type=delivery-status;
+	boundary="D1690A7AC1.996856090/mail.example.com"
+Message-Id: <20010803162810.0CA8AA7ACC at mail.example.com>
+
+This is a MIME-encapsulated message.
+
+--D1690A7AC1.996856090/mail.example.com
+Content-Type: text/plain
+
+Yadda yadda yadda
+
+--D1690A7AC1.996856090/mail.example.com
+
+Yadda yadda yadda
+
+--D1690A7AC1.996856090/mail.example.com
+Content-Type: message/rfc822
+
+From: nobody at python.org
+
+Yadda yadda yadda
+
+--D1690A7AC1.996856090/mail.example.com--
+

Added: vendor/Python/current/Lib/email/test/data/msg_06.txt
===================================================================
--- vendor/Python/current/Lib/email/test/data/msg_06.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/test/data/msg_06.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,33 @@
+Return-Path: <barry at python.org>
+Delivered-To: barry at python.org
+MIME-Version: 1.0
+Content-Type: message/rfc822
+Content-Description: forwarded message
+Content-Transfer-Encoding: 7bit
+Message-ID: <15265.9482.641338.555352 at python.org>
+From: barry at zope.com (Barry A. Warsaw)
+Sender: barry at python.org
+To: barry at python.org
+Subject: forwarded message from Barry A. Warsaw
+Date: Thu, 13 Sep 2001 17:28:42 -0400
+X-Mailer: VM 6.95 under 21.4 (patch 4) "Artificial Intelligence" XEmacs Lucid
+X-Attribution: BAW
+X-Oblique-Strategy: Be dirty
+X-Url: http://barry.wooz.org
+
+MIME-Version: 1.0
+Content-Type: text/plain; charset=us-ascii
+Return-Path: <barry at python.org>
+Delivered-To: barry at python.org
+Message-ID: <15265.9468.713530.98441 at python.org>
+From: barry at zope.com (Barry A. Warsaw)
+Sender: barry at python.org
+To: barry at python.org
+Subject: testing
+Date: Thu, 13 Sep 2001 17:28:28 -0400
+X-Mailer: VM 6.95 under 21.4 (patch 4) "Artificial Intelligence" XEmacs Lucid
+X-Attribution: BAW
+X-Oblique-Strategy: Spectrum analysis
+X-Url: http://barry.wooz.org
+
+

Added: vendor/Python/current/Lib/email/test/data/msg_07.txt
===================================================================
--- vendor/Python/current/Lib/email/test/data/msg_07.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/test/data/msg_07.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,83 @@
+MIME-Version: 1.0
+From: Barry <barry at digicool.com>
+To: Dingus Lovers <cravindogs at cravindogs.com>
+Subject: Here is your dingus fish
+Date: Fri, 20 Apr 2001 19:35:02 -0400
+Content-Type: multipart/mixed; boundary="BOUNDARY"
+
+--BOUNDARY
+Content-Type: text/plain; charset="us-ascii"
+
+Hi there,
+
+This is the dingus fish.
+
+--BOUNDARY
+Content-Type: image/gif; name="dingusfish.gif"
+Content-Transfer-Encoding: base64
+content-disposition: attachment; filename="dingusfish.gif"
+
+R0lGODdhAAEAAfAAAP///wAAACwAAAAAAAEAAQAC/oSPqcvtD6OctNqLs968+w+G4kiW5omm6sq2
+7gvH8kzX9o3n+s73/g8MCofEovGITGICTKbyCV0FDNOo9SqpQqpOrJfXzTQj2vD3TGtqL+NtGQ2f
+qTXmxzuOd7WXdcc9DyjU53ewFni4s0fGhdiYaEhGBelICTNoV1j5NUnFcrmUqemjNifJVWpaOqaI
+oFq3SspZsSraE7sHq3jr1MZqWvi662vxV4tD+pvKW6aLDOCLyur8PDwbanyDeq0N3DctbQYeLDvR
+RY6t95m6UB0d3mwIrV7e2VGNvjjffukeJp4w7F65KecGFsTHQGAygOrgrWs1jt28Rc88KESYcGLA
+/obvTkH6p+CinWJiJmIMqXGQwH/y4qk0SYjgQTczT3ajKZGfuI0uJ4kkVI/DT5s3/ejkxI0aT4Y+
+YTYgWbImUaXk9nlLmnSh1qJiJFl0OpUqRK4oOy7NyRQtHWofhoYVxkwWXKUSn0YsS+fUV6lhqfYb
+6ayd3Z5qQdG1B7bvQzaJjwUV2lixMUZ7JVsOlfjWVr/3NB/uFvnySBN6Dcb6rGwaRM3wsormw5cC
+M9NxWy/bWdufudCvy8bOAjXjVVwta/uO21sE5RHBCzNFXtgq9ORtH4eYjVP4Yryo026nvkFmCeyA
+B29efV6ravCMK5JwWd5897Qrx7ll38o6iHDZ/rXPR//feevhF4l7wjUGX3xq1eeRfM4RSJGBIV1D
+z1gKPkfWag3mVBVvva1RlX5bAJTPR/2YqNtw/FkIYYEi/pIZiAdpcxpoHtmnYYoZtvhUftzdx5ZX
+JSKDW405zkGcZzzGZ6KEv4FI224oDmijlEf+xp6MJK5ojY/ASeVUR+wsKRuJ+XFZ5o7ZeEime8t1
+ouUsU6YjF5ZtUihhkGfCdFQLWQFJ3UXxmElfhQnR+eCdcDbkFZp6vTRmj56ApCihn5QGpaToNZmR
+n3NVSpZcQpZ2KEONusaiCsKAug0wkQbJSFO+PTSjneGxOuFjPlUk3ovWvdIerjUg9ZGIOtGq/qeX
+eCYrrCX+1UPsgTKGGRSbzd5q156d/gpfbJxe66eD5iQKrXj7RGgruGxs62qebBHUKS32CKluCiqZ
+qh+pmehmEb71noAUoe5e9Zm17S7773V10pjrtG4CmuurCV/n6zLK5turWNhqOvFXbjhZrMD0YhKe
+wR0zOyuvsh6MWrGoIuzvyWu5y1WIFAqmJselypxXh6dKLNOKEB98L88bS2rkNqqlKzCNJp9c0G0j
+Gzh0iRrCbHSXmPR643QS+4rWhgFmnSbSuXCjS0xAOWkU2UdLqyuUNfHSFdUouy3bm5i5GnDM3tG8
+doJ4r5tqu3pPbRSVfvs8uJzeNXhp3n4j/tZ42SwH7eaWUUOjc3qFV9453UHTXZfcLH+OeNs5g36x
+lBnHvTm7EbMbLeuaLncao8vWCXimfo1o+843Ak6y4ChNeGntvAYvfLK4ezmoyNIbNCLTCXO9ZV3A
+E8/s88RczPzDwI4Ob7XZyl7+9Miban29h+tJZPrE21wgvBphDfrrfPdCTPKJD/y98L1rZwHcV6Jq
+Zab0metpuNIX/qAFPoz171WUaUb4HAhBSzHuHfjzHb3kha/2Cctis/ORArVHNYfFyYRH2pYIRzic
+isVOfPWD1b6mRTqpCRBozzof6UZVvFXRxWIr3GGrEviGYgyPMfahheiSaLs/9QeFu7oZ/ndSY8DD
+ya9x+uPed+7mxN2IzIISBOMLFYWVqC3Pew1T2nFuuCiwZS5/v6II10i4t1OJcUH2U9zxKodHsGGv
+Oa+zkvNUYUOa/TCCRutF9MzDwdlUMJADTCGSbDQ5OV4PTamDoPEi6Ecc/RF5RWwkcdSXvSOaDWSn
+I9LlvubFTQpuc6JKXLcKeb+xdbKRBnwREemXyjg6ME65aJiOuBgrktzykfPLJBKR9ClMavJ62/Ff
+BlNIyod9yX9wcSXexnXFpvkrbXk64xsx5Db7wXKP5fSgsvwIMM/9631VLBfkmtbHRXpqmtei52hG
+pUwSlo+BASQoeILDOBgREECxBBh5/iYmNsQ9dIv5+OI++QkqdsJPc3uykz5fkM+OraeekcQF7X4n
+B5S67za5U967PmooGQhUXfF7afXyCD7ONdRe17QogYjVx38uLwtrS6nhTnm15LQUnu9E2uK6CNI/
+1HOABj0ESwOjut4FEpFQpdNAm4K2LHnDWHNcmKB2ioKBogysVZtMO2nSxUdZ8Yk2kJc7URioLVI0
+YgmtIwZj4LoeKemgnOnbUdGnzZ4Oa6scqiolBGqS6RgWNLu0RMhcaE6rhhU4hiuqFXPAG8fGwTPW
+FKeLMtdVmXLSs5YJGF/YeVm7rREMlY3UYE+yCxbaMXX8y15m5zVHq6GOKDMynzII/jdUHdyVqIy0
+ifX2+r/EgtZcvRzSb72gU9ui87M2VecjKildW/aFqaYhKoryUjfB/g4qtyVuc60xFDGmCxwjW+qu
+zjuwl2GkOWn66+3QiiEctvd04OVvcCVzjgT7lrkvjVGKKHmmlDUKowSeikb5kK/mJReuWOxONx+s
+ULsl+Lqb0CVn0SrVyJ6wt4t6yTeSCafhPhAf0OXn6L60UMxiLolFAtmN35S2Ob1lZpQ1r/n0Qb5D
+oQ1zJiRVDgF8N3Q8TYfbi3DyWCy3lT1nxyBs6FT3S2GOzWRlxwKvlRP0RPJA9SjxEy0UoEnkA+M4
+cnzLMJrBGWLFEaaUb5lvpqbq/loOaU5+DFuHPxo82/OZuM8FXG3oVNZhtWpMpb/0Xu5m/LfLhHZQ
+7yuVI0MqZ7NE43imC8jH3IwGZlbPm0xkJYs7+2U48hXTsFSMqgGDvai0kLxyynKNT/waj+q1c1tz
+GjOpPBgdCSq3UKZxCSsqFIY+O6JbAWGWcV1pwqLyj5sGqCF1xb1F3varUWqrJv6cN3PrUXzijtfZ
+FshpBL3Xwr4GIPvU2N8EjrJgS1zl21rbXQMXeXc5jjFyrhpCzijSv/RQtyPSzHCFMhlME95fHglt
+pRsX+dfSQjUeHAlpWzJ5iOo79Ldnaxai6bXTcGO3fp07ri7HLEmXXPlYi8bv/qVxvNcdra6m7Rlb
+6JBTb5fd66VhFRjGArh2n7R1rDW4P5NOT9K0I183T2scYkeZ3q/VFyLb09U9ajzXBS8Kgkhc4mBS
+kYY9cy3Vy9lUnuNJH8HGIclUilwnBtjUOH0gteGOZ4c/XNrhXLSYDyxfnD8z1pDy7rYRvDolhnbe
+UMzxCZUs40s6s7UIvBnLgc0+vKuOkIXeOrDymlp+Zxra4MZLBbVrqD/jTJ597pDmnw5c4+DbyB88
+9Cg9DodYcSuMZT/114pptqc/EuTjRPvH/z5slzI3tluOEBBLqOXLOX+0I5929tO97wkvl/atCz+y
+xJrdwteW2FNW/NSmBP+f/maYtVs/bYyBC7Ox3jsYZHL05CIrBa/nS+b3bHfiYm4Ueil1YZZSgAUI
+fFZ1dxUmeA2oQRQ3RuGXNGLFV9/XbGFGPV6kfzk1TBBCd+izc7q1H+OHMJwmaBX2IQNYVAKHYepV
+SSGCe6CnbYHHETKGNe43EDvFgZr0gB/nVHPHZ80VV1ojOiI3XDvYIkl4ayo4bxQIgrFXWTvBI0nH
+VElWMuw2aLUWCRHHf8ymVCHjFlJnOSojfevCYyyyZDH0IcvHhrsnQ5O1OsWzONuVVKIxSxiFZ/tR
+fKDAf6xFTnw4O9Qig2VCfW2hJQrmMOuHW0W3dLQmCMO2ccdUd/xyfflH/olTiHZVdGwb8nIwRzSE
+J15jFlOJuBZBZ4CiyHyd2IFylFlB+HgHhYabhWOGwYO1ZH/Og1dtQlFMk352CGRSIFTapnWQEUtN
+l4zv8S0aaCFDyGCBqDUxZYpxGHX01y/JuH1xhn7TOCnNCI4eKDs5WGX4R425F4vF1o3BJ4vO0otq
+I3rimI7jJY1jISqnBxknCIvruF83mF5wN4X7qGLIhR8A2Vg0yFERSIXn9Vv3GHy3Vj/WIkKddlYi
+yIMv2I/VMjTLpW7pt05SWIZR0RPyxpB4SIUM9lBPGBl0GC7oSEEwRYLe4pJpZY2P0zbI1n+Oc44w
+qY3PUnmF0ixjVpDD/mJ9wpOBGTVgXlaCaZiPcIWK5NiKBIiPdGaQ0TWGvAiG7nMchdZb7Vgf8zNi
+MuMyzRdy/lePe9iC4TRx7WhhOQI/QiSVNAmAa2lT/piFbuh7ofJoYSZzrSZ1bvmWw3eN2nKUPVky
+uPN5/VRfohRd0VYZoqhKIlU6TXYhJxmPUIloAwc1bPmHEpaZYZORHNlXUJM07hATwHR8MJYqkwWR
+WaIezFhxSFlc8/Fq82hEnpeRozg3ULhhr9lAGtVEkCg5ZNRuuVleBPaZadhG0ZgkyPmDOTOKzViM
+YgOcpukKqQcbjAWS0IleQ2ROjdh6A+md1qWdBRSX7iSYgFRTtRmBpJioieXJiHfJiMGIR9fJOn8I
+MSfXYhspn4ooSa2mSAj4n+8Bmg03fBJZoPOJgsVZRxu1oOMRPXYYjdqjihFaEoZpXBREanuJoRI6
+cibFinq4ngUKh/wQd/H5ofYCZ0HJXR62opZFaAT0iFIZo4DIiUojkjeqKiuoZirKo5Y1a7AWckGa
+BkuYoD5lpDK6eUs6CkDqpETwl1EqpfhJpVeKpVl6EgUAADs=
+
+--BOUNDARY--

Added: vendor/Python/current/Lib/email/test/data/msg_08.txt
===================================================================
--- vendor/Python/current/Lib/email/test/data/msg_08.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/test/data/msg_08.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,24 @@
+MIME-Version: 1.0
+From: Barry Warsaw <barry at zope.com>
+To: Dingus Lovers <cravindogs at cravindogs.com>
+Subject: Lyrics
+Date: Fri, 20 Apr 2001 19:35:02 -0400
+Content-Type: multipart/mixed; boundary="BOUNDARY"
+
+--BOUNDARY
+Content-Type: text/plain; charset="us-ascii"
+
+
+--BOUNDARY
+Content-Type: text/html; charset="iso-8859-1"
+
+
+--BOUNDARY
+Content-Type: text/plain; charset="iso-8859-2"
+
+
+--BOUNDARY
+Content-Type: text/plain; charset="koi8-r"
+
+
+--BOUNDARY--

Added: vendor/Python/current/Lib/email/test/data/msg_09.txt
===================================================================
--- vendor/Python/current/Lib/email/test/data/msg_09.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/test/data/msg_09.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,24 @@
+MIME-Version: 1.0
+From: Barry Warsaw <barry at zope.com>
+To: Dingus Lovers <cravindogs at cravindogs.com>
+Subject: Lyrics
+Date: Fri, 20 Apr 2001 19:35:02 -0400
+Content-Type: multipart/mixed; boundary="BOUNDARY"
+
+--BOUNDARY
+Content-Type: text/plain; charset="us-ascii"
+
+
+--BOUNDARY
+Content-Type: text/html; charset="iso-8859-1"
+
+
+--BOUNDARY
+Content-Type: text/plain
+
+
+--BOUNDARY
+Content-Type: text/plain; charset="koi8-r"
+
+
+--BOUNDARY--

Added: vendor/Python/current/Lib/email/test/data/msg_10.txt
===================================================================
--- vendor/Python/current/Lib/email/test/data/msg_10.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/test/data/msg_10.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,32 @@
+MIME-Version: 1.0
+From: Barry Warsaw <barry at zope.com>
+To: Dingus Lovers <cravindogs at cravindogs.com>
+Subject: Lyrics
+Date: Fri, 20 Apr 2001 19:35:02 -0400
+Content-Type: multipart/mixed; boundary="BOUNDARY"
+
+--BOUNDARY
+Content-Type: text/plain; charset="us-ascii"
+Content-Transfer-Encoding: 7bit
+
+This is a 7bit encoded message.
+
+--BOUNDARY
+Content-Type: text/html; charset="iso-8859-1"
+Content-Transfer-Encoding: Quoted-Printable
+
+=A1This is a Quoted Printable encoded message!
+
+--BOUNDARY
+Content-Type: text/plain; charset="iso-8859-1"
+Content-Transfer-Encoding: Base64
+
+VGhpcyBpcyBhIEJhc2U2NCBlbmNvZGVkIG1lc3NhZ2Uu
+
+
+--BOUNDARY
+Content-Type: text/plain; charset="iso-8859-1"
+
+This has no Content-Transfer-Encoding: header.
+
+--BOUNDARY--

Added: vendor/Python/current/Lib/email/test/data/msg_11.txt
===================================================================
--- vendor/Python/current/Lib/email/test/data/msg_11.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/test/data/msg_11.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,7 @@
+Content-Type: message/rfc822
+MIME-Version: 1.0
+Subject: The enclosing message
+
+Subject: An enclosed message
+
+Here is the body of the message.

Added: vendor/Python/current/Lib/email/test/data/msg_12.txt
===================================================================
--- vendor/Python/current/Lib/email/test/data/msg_12.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/test/data/msg_12.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,36 @@
+MIME-Version: 1.0
+From: Barry Warsaw <barry at zope.com>
+To: Dingus Lovers <cravindogs at cravindogs.com>
+Subject: Lyrics
+Date: Fri, 20 Apr 2001 19:35:02 -0400
+Content-Type: multipart/mixed; boundary="BOUNDARY"
+
+--BOUNDARY
+Content-Type: text/plain; charset="us-ascii"
+
+
+--BOUNDARY
+Content-Type: text/html; charset="iso-8859-1"
+
+
+--BOUNDARY
+Content-Type: multipart/mixed; boundary="ANOTHER"
+
+--ANOTHER
+Content-Type: text/plain; charset="iso-8859-2"
+
+
+--ANOTHER
+Content-Type: text/plain; charset="iso-8859-3"
+
+--ANOTHER--
+
+--BOUNDARY
+Content-Type: text/plain; charset="us-ascii"
+
+
+--BOUNDARY
+Content-Type: text/plain; charset="koi8-r"
+
+
+--BOUNDARY--

Added: vendor/Python/current/Lib/email/test/data/msg_12a.txt
===================================================================
--- vendor/Python/current/Lib/email/test/data/msg_12a.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/test/data/msg_12a.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,38 @@
+MIME-Version: 1.0
+From: Barry Warsaw <barry at zope.com>
+To: Dingus Lovers <cravindogs at cravindogs.com>
+Subject: Lyrics
+Date: Fri, 20 Apr 2001 19:35:02 -0400
+Content-Type: multipart/mixed; boundary="BOUNDARY"
+
+--BOUNDARY
+Content-Type: text/plain; charset="us-ascii"
+
+
+--BOUNDARY
+Content-Type: text/html; charset="iso-8859-1"
+
+
+--BOUNDARY
+Content-Type: multipart/mixed; boundary="ANOTHER"
+
+--ANOTHER
+Content-Type: text/plain; charset="iso-8859-2"
+
+
+--ANOTHER
+Content-Type: text/plain; charset="iso-8859-3"
+
+
+--ANOTHER--
+
+
+--BOUNDARY
+Content-Type: text/plain; charset="us-ascii"
+
+
+--BOUNDARY
+Content-Type: text/plain; charset="koi8-r"
+
+
+--BOUNDARY--

Added: vendor/Python/current/Lib/email/test/data/msg_13.txt
===================================================================
--- vendor/Python/current/Lib/email/test/data/msg_13.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/test/data/msg_13.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,94 @@
+MIME-Version: 1.0
+From: Barry <barry at digicool.com>
+To: Dingus Lovers <cravindogs at cravindogs.com>
+Subject: Here is your dingus fish
+Date: Fri, 20 Apr 2001 19:35:02 -0400
+Content-Type: multipart/mixed; boundary="OUTER"
+
+--OUTER
+Content-Type: text/plain; charset="us-ascii"
+
+A text/plain part
+
+--OUTER
+Content-Type: multipart/mixed; boundary=BOUNDARY
+
+
+--BOUNDARY
+Content-Type: text/plain; charset="us-ascii"
+
+Hi there,
+
+This is the dingus fish.
+
+--BOUNDARY
+Content-Type: image/gif; name="dingusfish.gif"
+Content-Transfer-Encoding: base64
+content-disposition: attachment; filename="dingusfish.gif"
+
+R0lGODdhAAEAAfAAAP///wAAACwAAAAAAAEAAQAC/oSPqcvtD6OctNqLs968+w+G4kiW5omm6sq2
+7gvH8kzX9o3n+s73/g8MCofEovGITGICTKbyCV0FDNOo9SqpQqpOrJfXzTQj2vD3TGtqL+NtGQ2f
+qTXmxzuOd7WXdcc9DyjU53ewFni4s0fGhdiYaEhGBelICTNoV1j5NUnFcrmUqemjNifJVWpaOqaI
+oFq3SspZsSraE7sHq3jr1MZqWvi662vxV4tD+pvKW6aLDOCLyur8PDwbanyDeq0N3DctbQYeLDvR
+RY6t95m6UB0d3mwIrV7e2VGNvjjffukeJp4w7F65KecGFsTHQGAygOrgrWs1jt28Rc88KESYcGLA
+/obvTkH6p+CinWJiJmIMqXGQwH/y4qk0SYjgQTczT3ajKZGfuI0uJ4kkVI/DT5s3/ejkxI0aT4Y+
+YTYgWbImUaXk9nlLmnSh1qJiJFl0OpUqRK4oOy7NyRQtHWofhoYVxkwWXKUSn0YsS+fUV6lhqfYb
+6ayd3Z5qQdG1B7bvQzaJjwUV2lixMUZ7JVsOlfjWVr/3NB/uFvnySBN6Dcb6rGwaRM3wsormw5cC
+M9NxWy/bWdufudCvy8bOAjXjVVwta/uO21sE5RHBCzNFXtgq9ORtH4eYjVP4Yryo026nvkFmCeyA
+B29efV6ravCMK5JwWd5897Qrx7ll38o6iHDZ/rXPR//feevhF4l7wjUGX3xq1eeRfM4RSJGBIV1D
+z1gKPkfWag3mVBVvva1RlX5bAJTPR/2YqNtw/FkIYYEi/pIZiAdpcxpoHtmnYYoZtvhUftzdx5ZX
+JSKDW405zkGcZzzGZ6KEv4FI224oDmijlEf+xp6MJK5ojY/ASeVUR+wsKRuJ+XFZ5o7ZeEime8t1
+ouUsU6YjF5ZtUihhkGfCdFQLWQFJ3UXxmElfhQnR+eCdcDbkFZp6vTRmj56ApCihn5QGpaToNZmR
+n3NVSpZcQpZ2KEONusaiCsKAug0wkQbJSFO+PTSjneGxOuFjPlUk3ovWvdIerjUg9ZGIOtGq/qeX
+eCYrrCX+1UPsgTKGGRSbzd5q156d/gpfbJxe66eD5iQKrXj7RGgruGxs62qebBHUKS32CKluCiqZ
+qh+pmehmEb71noAUoe5e9Zm17S7773V10pjrtG4CmuurCV/n6zLK5turWNhqOvFXbjhZrMD0YhKe
+wR0zOyuvsh6MWrGoIuzvyWu5y1WIFAqmJselypxXh6dKLNOKEB98L88bS2rkNqqlKzCNJp9c0G0j
+Gzh0iRrCbHSXmPR643QS+4rWhgFmnSbSuXCjS0xAOWkU2UdLqyuUNfHSFdUouy3bm5i5GnDM3tG8
+doJ4r5tqu3pPbRSVfvs8uJzeNXhp3n4j/tZ42SwH7eaWUUOjc3qFV9453UHTXZfcLH+OeNs5g36x
+lBnHvTm7EbMbLeuaLncao8vWCXimfo1o+843Ak6y4ChNeGntvAYvfLK4ezmoyNIbNCLTCXO9ZV3A
+E8/s88RczPzDwI4Ob7XZyl7+9Miban29h+tJZPrE21wgvBphDfrrfPdCTPKJD/y98L1rZwHcV6Jq
+Zab0metpuNIX/qAFPoz171WUaUb4HAhBSzHuHfjzHb3kha/2Cctis/ORArVHNYfFyYRH2pYIRzic
+isVOfPWD1b6mRTqpCRBozzof6UZVvFXRxWIr3GGrEviGYgyPMfahheiSaLs/9QeFu7oZ/ndSY8DD
+ya9x+uPed+7mxN2IzIISBOMLFYWVqC3Pew1T2nFuuCiwZS5/v6II10i4t1OJcUH2U9zxKodHsGGv
+Oa+zkvNUYUOa/TCCRutF9MzDwdlUMJADTCGSbDQ5OV4PTamDoPEi6Ecc/RF5RWwkcdSXvSOaDWSn
+I9LlvubFTQpuc6JKXLcKeb+xdbKRBnwREemXyjg6ME65aJiOuBgrktzykfPLJBKR9ClMavJ62/Ff
+BlNIyod9yX9wcSXexnXFpvkrbXk64xsx5Db7wXKP5fSgsvwIMM/9631VLBfkmtbHRXpqmtei52hG
+pUwSlo+BASQoeILDOBgREECxBBh5/iYmNsQ9dIv5+OI++QkqdsJPc3uykz5fkM+OraeekcQF7X4n
+B5S67za5U967PmooGQhUXfF7afXyCD7ONdRe17QogYjVx38uLwtrS6nhTnm15LQUnu9E2uK6CNI/
+1HOABj0ESwOjut4FEpFQpdNAm4K2LHnDWHNcmKB2ioKBogysVZtMO2nSxUdZ8Yk2kJc7URioLVI0
+YgmtIwZj4LoeKemgnOnbUdGnzZ4Oa6scqiolBGqS6RgWNLu0RMhcaE6rhhU4hiuqFXPAG8fGwTPW
+FKeLMtdVmXLSs5YJGF/YeVm7rREMlY3UYE+yCxbaMXX8y15m5zVHq6GOKDMynzII/jdUHdyVqIy0
+ifX2+r/EgtZcvRzSb72gU9ui87M2VecjKildW/aFqaYhKoryUjfB/g4qtyVuc60xFDGmCxwjW+qu
+zjuwl2GkOWn66+3QiiEctvd04OVvcCVzjgT7lrkvjVGKKHmmlDUKowSeikb5kK/mJReuWOxONx+s
+ULsl+Lqb0CVn0SrVyJ6wt4t6yTeSCafhPhAf0OXn6L60UMxiLolFAtmN35S2Ob1lZpQ1r/n0Qb5D
+oQ1zJiRVDgF8N3Q8TYfbi3DyWCy3lT1nxyBs6FT3S2GOzWRlxwKvlRP0RPJA9SjxEy0UoEnkA+M4
+cnzLMJrBGWLFEaaUb5lvpqbq/loOaU5+DFuHPxo82/OZuM8FXG3oVNZhtWpMpb/0Xu5m/LfLhHZQ
+7yuVI0MqZ7NE43imC8jH3IwGZlbPm0xkJYs7+2U48hXTsFSMqgGDvai0kLxyynKNT/waj+q1c1tz
+GjOpPBgdCSq3UKZxCSsqFIY+O6JbAWGWcV1pwqLyj5sGqCF1xb1F3varUWqrJv6cN3PrUXzijtfZ
+FshpBL3Xwr4GIPvU2N8EjrJgS1zl21rbXQMXeXc5jjFyrhpCzijSv/RQtyPSzHCFMhlME95fHglt
+pRsX+dfSQjUeHAlpWzJ5iOo79Ldnaxai6bXTcGO3fp07ri7HLEmXXPlYi8bv/qVxvNcdra6m7Rlb
+6JBTb5fd66VhFRjGArh2n7R1rDW4P5NOT9K0I183T2scYkeZ3q/VFyLb09U9ajzXBS8Kgkhc4mBS
+kYY9cy3Vy9lUnuNJH8HGIclUilwnBtjUOH0gteGOZ4c/XNrhXLSYDyxfnD8z1pDy7rYRvDolhnbe
+UMzxCZUs40s6s7UIvBnLgc0+vKuOkIXeOrDymlp+Zxra4MZLBbVrqD/jTJ597pDmnw5c4+DbyB88
+9Cg9DodYcSuMZT/114pptqc/EuTjRPvH/z5slzI3tluOEBBLqOXLOX+0I5929tO97wkvl/atCz+y
+xJrdwteW2FNW/NSmBP+f/maYtVs/bYyBC7Ox3jsYZHL05CIrBa/nS+b3bHfiYm4Ueil1YZZSgAUI
+fFZ1dxUmeA2oQRQ3RuGXNGLFV9/XbGFGPV6kfzk1TBBCd+izc7q1H+OHMJwmaBX2IQNYVAKHYepV
+SSGCe6CnbYHHETKGNe43EDvFgZr0gB/nVHPHZ80VV1ojOiI3XDvYIkl4ayo4bxQIgrFXWTvBI0nH
+VElWMuw2aLUWCRHHf8ymVCHjFlJnOSojfevCYyyyZDH0IcvHhrsnQ5O1OsWzONuVVKIxSxiFZ/tR
+fKDAf6xFTnw4O9Qig2VCfW2hJQrmMOuHW0W3dLQmCMO2ccdUd/xyfflH/olTiHZVdGwb8nIwRzSE
+J15jFlOJuBZBZ4CiyHyd2IFylFlB+HgHhYabhWOGwYO1ZH/Og1dtQlFMk352CGRSIFTapnWQEUtN
+l4zv8S0aaCFDyGCBqDUxZYpxGHX01y/JuH1xhn7TOCnNCI4eKDs5WGX4R425F4vF1o3BJ4vO0otq
+I3rimI7jJY1jISqnBxknCIvruF83mF5wN4X7qGLIhR8A2Vg0yFERSIXn9Vv3GHy3Vj/WIkKddlYi
+yIMv2I/VMjTLpW7pt05SWIZR0RPyxpB4SIUM9lBPGBl0GC7oSEEwRYLe4pJpZY2P0zbI1n+Oc44w
+qY3PUnmF0ixjVpDD/mJ9wpOBGTVgXlaCaZiPcIWK5NiKBIiPdGaQ0TWGvAiG7nMchdZb7Vgf8zNi
+MuMyzRdy/lePe9iC4TRx7WhhOQI/QiSVNAmAa2lT/piFbuh7ofJoYSZzrSZ1bvmWw3eN2nKUPVky
+uPN5/VRfohRd0VYZoqhKIlU6TXYhJxmPUIloAwc1bPmHEpaZYZORHNlXUJM07hATwHR8MJYqkwWR
+WaIezFhxSFlc8/Fq82hEnpeRozg3ULhhr9lAGtVEkCg5ZNRuuVleBPaZadhG0ZgkyPmDOTOKzViM
+YgOcpukKqQcbjAWS0IleQ2ROjdh6A+md1qWdBRSX7iSYgFRTtRmBpJioieXJiHfJiMGIR9fJOn8I
+MSfXYhspn4ooSa2mSAj4n+8Bmg03fBJZoPOJgsVZRxu1oOMRPXYYjdqjihFaEoZpXBREanuJoRI6
+cibFinq4ngUKh/wQd/H5ofYCZ0HJXR62opZFaAT0iFIZo4DIiUojkjeqKiuoZirKo5Y1a7AWckGa
+BkuYoD5lpDK6eUs6CkDqpETwl1EqpfhJpVeKpVl6EgUAADs=
+
+--BOUNDARY--
+
+--OUTER--

Added: vendor/Python/current/Lib/email/test/data/msg_14.txt
===================================================================
--- vendor/Python/current/Lib/email/test/data/msg_14.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/test/data/msg_14.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,23 @@
+Return-Path: <bbb at zzz.org>
+Delivered-To: bbb at zzz.org
+Received: by mail.zzz.org (Postfix, from userid 889)
+	id 27CEAD38CC; Fri,  4 May 2001 14:05:44 -0400 (EDT)
+MIME-Version: 1.0
+Content-Type: text; charset=us-ascii
+Content-Transfer-Encoding: 7bit
+Message-ID: <15090.61304.110929.45684 at aaa.zzz.org>
+From: bbb at ddd.com (John X. Doe)
+To: bbb at zzz.org
+Subject: This is a test message
+Date: Fri, 4 May 2001 14:05:44 -0400
+
+
+Hi,
+
+I'm sorry but I'm using a drainbread ISP, which although big and
+wealthy can't seem to generate standard compliant email. :(
+
+This message has a Content-Type: header with no subtype.  I hope you
+can still read it.
+
+-Me

Added: vendor/Python/current/Lib/email/test/data/msg_15.txt
===================================================================
--- vendor/Python/current/Lib/email/test/data/msg_15.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/test/data/msg_15.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,52 @@
+Return-Path: <xx at xx.dk>
+Received: from fepD.post.tele.dk (195.41.46.149) by mail.groupcare.dk (LSMTP for Windows NT v1.1b) with SMTP id <0.0014F8A2 at mail.groupcare.dk>; Mon, 30 Apr 2001 12:17:50 +0200
+User-Agent: Microsoft-Outlook-Express-Macintosh-Edition/5.02.2106
+Subject: XX
+From: xx at xx.dk
+To: XX
+Message-ID: <xxxx>
+Mime-version: 1.0
+Content-type: multipart/mixed;
+   boundary="MS_Mac_OE_3071477847_720252_MIME_Part"
+
+> Denne meddelelse er i MIME-format. Da dit postl¾sningsprogram ikke forstŒr dette format, kan del af eller hele meddelelsen v¾re ul¾selig.
+
+--MS_Mac_OE_3071477847_720252_MIME_Part
+Content-type: multipart/alternative;
+   boundary="MS_Mac_OE_3071477847_720252_MIME_Part"
+
+
+--MS_Mac_OE_3071477847_720252_MIME_Part
+Content-type: text/plain; charset="ISO-8859-1"
+Content-transfer-encoding: quoted-printable
+
+Some removed test. 
+
+--MS_Mac_OE_3071477847_720252_MIME_Part
+Content-type: text/html; charset="ISO-8859-1"
+Content-transfer-encoding: quoted-printable
+
+<HTML>
+<HEAD>
+<TITLE>Some removed HTML</TITLE>
+</HEAD>
+<BODY>
+Some removed text.
+</BODY>
+</HTML>
+
+
+--MS_Mac_OE_3071477847_720252_MIME_Part--
+
+
+--MS_Mac_OE_3071477847_720252_MIME_Part
+Content-type: image/gif; name="xx.gif";
+ x-mac-creator="6F676C65";
+ x-mac-type="47494666"
+Content-disposition: attachment
+Content-transfer-encoding: base64
+
+Some removed base64 encoded chars.
+
+--MS_Mac_OE_3071477847_720252_MIME_Part--
+

Added: vendor/Python/current/Lib/email/test/data/msg_16.txt
===================================================================
--- vendor/Python/current/Lib/email/test/data/msg_16.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/test/data/msg_16.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,123 @@
+Return-Path: <>
+Delivered-To: scr-admin at socal-raves.org
+Received: from cougar.noc.ucla.edu (cougar.noc.ucla.edu [169.232.10.18])
+	by babylon.socal-raves.org (Postfix) with ESMTP id CCC2C51B84
+	for <scr-admin at socal-raves.org>; Sun, 23 Sep 2001 20:13:54 -0700 (PDT)
+Received: from sims-ms-daemon by cougar.noc.ucla.edu
+ (Sun Internet Mail Server sims.3.5.2000.03.23.18.03.p10)
+ id <0GK500B01D0B8Y at cougar.noc.ucla.edu> for scr-admin at socal-raves.org; Sun,
+ 23 Sep 2001 20:14:35 -0700 (PDT)
+Received: from cougar.noc.ucla.edu
+ (Sun Internet Mail Server sims.3.5.2000.03.23.18.03.p10)
+ id <0GK500B01D0B8X at cougar.noc.ucla.edu>; Sun, 23 Sep 2001 20:14:35 -0700 (PDT)
+Date: Sun, 23 Sep 2001 20:14:35 -0700 (PDT)
+From: Internet Mail Delivery <postmaster at ucla.edu>
+Subject: Delivery Notification: Delivery has failed
+To: scr-admin at socal-raves.org
+Message-id: <0GK500B04D0B8X at cougar.noc.ucla.edu>
+MIME-version: 1.0
+Sender: scr-owner at socal-raves.org
+Errors-To: scr-owner at socal-raves.org
+X-BeenThere: scr at socal-raves.org
+X-Mailman-Version: 2.1a3
+Precedence: bulk
+List-Help: <mailto:scr-request at socal-raves.org?subject=help>
+List-Post: <mailto:scr at socal-raves.org>
+List-Subscribe: <http://socal-raves.org/mailman/listinfo/scr>,
+	<mailto:scr-request at socal-raves.org?subject=subscribe>
+List-Id: SoCal-Raves <scr.socal-raves.org>
+List-Unsubscribe: <http://socal-raves.org/mailman/listinfo/scr>,
+	<mailto:scr-request at socal-raves.org?subject=unsubscribe>
+List-Archive: <http://socal-raves.org/mailman/private/scr/>
+Content-Type: multipart/report; boundary="Boundary_(ID_PGS2F2a+z+/jL7hupKgRhA)"
+
+
+--Boundary_(ID_PGS2F2a+z+/jL7hupKgRhA)
+Content-type: text/plain; charset=ISO-8859-1
+
+This report relates to a message you sent with the following header fields:
+
+  Message-id: <002001c144a6$8752e060$56104586 at oxy.edu>
+  Date: Sun, 23 Sep 2001 20:10:55 -0700
+  From: "Ian T. Henry" <henryi at oxy.edu>
+  To: SoCal Raves <scr at socal-raves.org>
+  Subject: [scr] yeah for Ians!!
+
+Your message cannot be delivered to the following recipients:
+
+  Recipient address: jangel1 at cougar.noc.ucla.edu
+  Reason: recipient reached disk quota
+
+
+--Boundary_(ID_PGS2F2a+z+/jL7hupKgRhA)
+Content-type: message/DELIVERY-STATUS
+
+Original-envelope-id: 0GK500B4HD0888 at cougar.noc.ucla.edu
+Reporting-MTA: dns; cougar.noc.ucla.edu
+
+Action: failed
+Status: 5.0.0 (recipient reached disk quota)
+Original-recipient: rfc822;jangel1 at cougar.noc.ucla.edu
+Final-recipient: rfc822;jangel1 at cougar.noc.ucla.edu
+
+--Boundary_(ID_PGS2F2a+z+/jL7hupKgRhA)
+Content-type: MESSAGE/RFC822
+
+Return-path: scr-admin at socal-raves.org
+Received: from sims-ms-daemon by cougar.noc.ucla.edu
+ (Sun Internet Mail Server sims.3.5.2000.03.23.18.03.p10)
+ id <0GK500B01D0B8X at cougar.noc.ucla.edu>; Sun, 23 Sep 2001 20:14:35 -0700 (PDT)
+Received: from panther.noc.ucla.edu by cougar.noc.ucla.edu
+ (Sun Internet Mail Server sims.3.5.2000.03.23.18.03.p10)
+ with ESMTP id <0GK500B4GD0888 at cougar.noc.ucla.edu> for jangel1 at sims-ms-daemon;
+ Sun, 23 Sep 2001 20:14:33 -0700 (PDT)
+Received: from babylon.socal-raves.org
+ (ip-209-85-222-117.dreamhost.com [209.85.222.117])
+ by panther.noc.ucla.edu (8.9.1a/8.9.1) with ESMTP id UAA09793 for
+ <jangel1 at ucla.edu>; Sun, 23 Sep 2001 20:14:32 -0700 (PDT)
+Received: from babylon (localhost [127.0.0.1]) by babylon.socal-raves.org
+ (Postfix) with ESMTP id D3B2951B70; Sun, 23 Sep 2001 20:13:47 -0700 (PDT)
+Received: by babylon.socal-raves.org (Postfix, from userid 60001)
+ id A611F51B82; Sun, 23 Sep 2001 20:13:46 -0700 (PDT)
+Received: from tiger.cc.oxy.edu (tiger.cc.oxy.edu [134.69.3.112])
+ by babylon.socal-raves.org (Postfix) with ESMTP id ADA7351B70 for
+ <scr at socal-raves.org>; Sun, 23 Sep 2001 20:13:44 -0700 (PDT)
+Received: from ent (n16h86.dhcp.oxy.edu [134.69.16.86])
+ by tiger.cc.oxy.edu (8.8.8/8.8.8) with SMTP id UAA08100 for
+ <scr at socal-raves.org>; Sun, 23 Sep 2001 20:14:24 -0700 (PDT)
+Date: Sun, 23 Sep 2001 20:10:55 -0700
+From: "Ian T. Henry" <henryi at oxy.edu>
+Subject: [scr] yeah for Ians!!
+Sender: scr-admin at socal-raves.org
+To: SoCal Raves <scr at socal-raves.org>
+Errors-to: scr-admin at socal-raves.org
+Message-id: <002001c144a6$8752e060$56104586 at oxy.edu>
+MIME-version: 1.0
+X-Mailer: Microsoft Outlook Express 5.50.4522.1200
+Content-type: text/plain; charset=us-ascii
+Precedence: bulk
+Delivered-to: scr-post at babylon.socal-raves.org
+Delivered-to: scr at socal-raves.org
+X-Converted-To-Plain-Text: from multipart/alternative by demime 0.98e
+X-Converted-To-Plain-Text: Alternative section used was text/plain
+X-BeenThere: scr at socal-raves.org
+X-Mailman-Version: 2.1a3
+List-Help: <mailto:scr-request at socal-raves.org?subject=help>
+List-Post: <mailto:scr at socal-raves.org>
+List-Subscribe: <http://socal-raves.org/mailman/listinfo/scr>,
+ <mailto:scr-request at socal-raves.org?subject=subscribe>
+List-Id: SoCal-Raves <scr.socal-raves.org>
+List-Unsubscribe: <http://socal-raves.org/mailman/listinfo/scr>,
+ <mailto:scr-request at socal-raves.org?subject=unsubscribe>
+List-Archive: <http://socal-raves.org/mailman/private/scr/>
+
+I always love to find more Ian's that are over 3 years old!!
+
+Ian
+_______________________________________________
+For event info, list questions, or to unsubscribe, see http://www.socal-raves.org/
+
+
+
+--Boundary_(ID_PGS2F2a+z+/jL7hupKgRhA)--
+

Added: vendor/Python/current/Lib/email/test/data/msg_17.txt
===================================================================
--- vendor/Python/current/Lib/email/test/data/msg_17.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/test/data/msg_17.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,12 @@
+MIME-Version: 1.0
+From: Barry <barry at digicool.com>
+To: Dingus Lovers <cravindogs at cravindogs.com>
+Subject: Here is your dingus fish
+Date: Fri, 20 Apr 2001 19:35:02 -0400
+Content-Type: multipart/mixed; boundary="BOUNDARY"
+
+Hi there,
+
+This is the dingus fish.
+
+[Non-text (image/gif) part of message omitted, filename dingusfish.gif]

Added: vendor/Python/current/Lib/email/test/data/msg_18.txt
===================================================================
--- vendor/Python/current/Lib/email/test/data/msg_18.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/test/data/msg_18.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,6 @@
+Content-Type: text/plain; charset="us-ascii"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Foobar-Spoink-Defrobnit: wasnipoop; giraffes="very-long-necked-animals";
+	spooge="yummy"; hippos="gargantuan"; marshmallows="gooey"
+

Added: vendor/Python/current/Lib/email/test/data/msg_19.txt
===================================================================
--- vendor/Python/current/Lib/email/test/data/msg_19.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/test/data/msg_19.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,43 @@
+Send Ppp mailing list submissions to
+	ppp at zzz.org
+
+To subscribe or unsubscribe via the World Wide Web, visit
+	http://www.zzz.org/mailman/listinfo/ppp
+or, via email, send a message with subject or body 'help' to
+	ppp-request at zzz.org
+
+You can reach the person managing the list at
+	ppp-admin at zzz.org
+
+When replying, please edit your Subject line so it is more specific
+than "Re: Contents of Ppp digest..."
+
+Today's Topics:
+
+   1. testing #1 (Barry A. Warsaw)
+   2. testing #2 (Barry A. Warsaw)
+   3. testing #3 (Barry A. Warsaw)
+   4. testing #4 (Barry A. Warsaw)
+   5. testing #5 (Barry A. Warsaw)
+
+hello
+
+
+hello
+
+
+hello
+
+
+hello
+
+
+hello
+
+
+
+_______________________________________________
+Ppp mailing list
+Ppp at zzz.org
+http://www.zzz.org/mailman/listinfo/ppp
+

Added: vendor/Python/current/Lib/email/test/data/msg_20.txt
===================================================================
--- vendor/Python/current/Lib/email/test/data/msg_20.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/test/data/msg_20.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,22 @@
+Return-Path: <bbb at zzz.org>
+Delivered-To: bbb at zzz.org
+Received: by mail.zzz.org (Postfix, from userid 889)
+	id 27CEAD38CC; Fri,  4 May 2001 14:05:44 -0400 (EDT)
+MIME-Version: 1.0
+Content-Type: text/plain; charset=us-ascii
+Content-Transfer-Encoding: 7bit
+Message-ID: <15090.61304.110929.45684 at aaa.zzz.org>
+From: bbb at ddd.com (John X. Doe)
+To: bbb at zzz.org
+Cc: ccc at zzz.org
+CC: ddd at zzz.org
+cc: eee at zzz.org
+Subject: This is a test message
+Date: Fri, 4 May 2001 14:05:44 -0400
+
+
+Hi,
+
+Do you like this message?
+
+-Me

Added: vendor/Python/current/Lib/email/test/data/msg_21.txt
===================================================================
--- vendor/Python/current/Lib/email/test/data/msg_21.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/test/data/msg_21.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,20 @@
+From: aperson at dom.ain
+To: bperson at dom.ain
+Subject: Test
+Content-Type: multipart/mixed; boundary="BOUNDARY"
+
+MIME message
+--BOUNDARY
+Content-Type: text/plain; charset="us-ascii"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+
+One
+--BOUNDARY
+Content-Type: text/plain; charset="us-ascii"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+
+Two
+--BOUNDARY--
+End of MIME message

Added: vendor/Python/current/Lib/email/test/data/msg_22.txt
===================================================================
--- vendor/Python/current/Lib/email/test/data/msg_22.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/test/data/msg_22.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,46 @@
+Mime-Version: 1.0
+Message-Id: <a05001902b7f1c33773e9@[134.84.183.138]>
+Date: Tue, 16 Oct 2001 13:59:25 +0300
+To: a at example.com
+From: b at example.com
+Content-Type: multipart/mixed; boundary="============_-1208892523==_============"
+
+--============_-1208892523==_============
+Content-Type: text/plain; charset="us-ascii" ; format="flowed"
+
+Text text text.
+--============_-1208892523==_============
+Content-Id: <a05001902b7f1c33773e9@[134.84.183.138].0.0>
+Content-Type: image/jpeg; name="wibble.JPG"
+ ; x-mac-type="4A504547"
+ ; x-mac-creator="474B4F4E"
+Content-Disposition: attachment; filename="wibble.JPG"
+Content-Transfer-Encoding: base64
+
+/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
+AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wAALCAXABIEBAREA
+g6bCjjw/pIZSjO6FWFpldjySOmCNrO7DBZibUXhTwtCixw+GtAijVdqxxaPp0aKvmGXa
+qrbBQvms0mAMeYS/3iTV1dG0hHaRNK01XblnWxtVdjkHLMIgTyqnk9VB7CrP2KzIINpa
+4O7I+zxYO9WV8jZg71Zlb+8rMDkEirAVQFAUAKAFAAAUAYAUDgADgY6DjpRtXj5RxjHA
+4wQRj0wQCMdCAewpaKKK/9k=
+--============_-1208892523==_============
+Content-Id: <a05001902b7f1c33773e9@[134.84.183.138].0.1>
+Content-Type: image/jpeg; name="wibble2.JPG"
+ ; x-mac-type="4A504547"
+ ; x-mac-creator="474B4F4E"
+Content-Disposition: attachment; filename="wibble2.JPG"
+Content-Transfer-Encoding: base64
+
+/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
+AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wAALCAXABJ0BAREA
+/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQA
+W6NFJJBEkU10kKGTcWMDwxuU+0JHvk8qAtOpNwqSR0n8c3BlDyXHlqsUltHEiTvdXLxR
+7vMiGDNJAJWkAMk8ZkCFp5G2oo5W++INrbQtNfTQxJAuXlupz9oS4d5Y1W+E2XlWZJJE
+Y7LWYQxTLE1zuMbfBPxw8X2fibVdIbSbI6nLZxX635t9TjtYreWR7WGKJTLJFFKSlozO
+0ShxIXM43uC3/9k=
+--============_-1208892523==_============
+Content-Type: text/plain; charset="us-ascii" ; format="flowed"
+
+Text text text.
+--============_-1208892523==_============--
+

Added: vendor/Python/current/Lib/email/test/data/msg_23.txt
===================================================================
--- vendor/Python/current/Lib/email/test/data/msg_23.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/test/data/msg_23.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,8 @@
+From: aperson at dom.ain
+Content-Type: multipart/mixed; boundary="BOUNDARY"
+
+--BOUNDARY
+Content-Type: text/plain
+
+A message part
+--BOUNDARY--

Added: vendor/Python/current/Lib/email/test/data/msg_24.txt
===================================================================
--- vendor/Python/current/Lib/email/test/data/msg_24.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/test/data/msg_24.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,10 @@
+Content-Type: multipart/mixed; boundary="BOUNDARY"
+MIME-Version: 1.0
+Subject: A subject
+To: aperson at dom.ain
+From: bperson at dom.ain
+
+--BOUNDARY
+
+
+--BOUNDARY--

Added: vendor/Python/current/Lib/email/test/data/msg_25.txt
===================================================================
--- vendor/Python/current/Lib/email/test/data/msg_25.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/test/data/msg_25.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,117 @@
+From MAILER-DAEMON Fri Apr 06 16:46:09 2001
+Received: from [204.245.199.98] (helo=zinfandel.lacita.com)
+	by www.linux.org.uk with esmtp (Exim 3.13 #1)
+	id 14lYR6-0008Iv-00
+	for linuxuser-admin at www.linux.org.uk; Fri, 06 Apr 2001 16:46:09 +0100
+Received: from localhost (localhost) by zinfandel.lacita.com (8.7.3/8.6.10-MT4.00) with internal id JAB03225; Fri, 6 Apr 2001 09:23:06 -0800 (GMT-0800)
+Date: Fri, 6 Apr 2001 09:23:06 -0800 (GMT-0800)
+From: Mail Delivery Subsystem <MAILER-DAEMON at zinfandel.lacita.com>
+Subject: Returned mail: Too many hops 19 (17 max): from <linuxuser-admin at www.linux.org.uk> via [199.164.235.226], to <scoffman at wellpartner.com>
+Message-Id: <200104061723.JAB03225 at zinfandel.lacita.com>
+To: <linuxuser-admin at www.linux.org.uk>
+To: postmaster at zinfandel.lacita.com
+MIME-Version: 1.0
+Content-Type: multipart/report; report-type=delivery-status;
+	bo
+Auto-Submitted: auto-generated (failure)
+
+This is a MIME-encapsulated message
+
+--JAB03225.986577786/zinfandel.lacita.com
+
+The original message was received at Fri, 6 Apr 2001 09:23:03 -0800 (GMT-0800)
+from [199.164.235.226]
+
+   ----- The following addresses have delivery notifications -----
+<scoffman at wellpartner.com>  (unrecoverable error)
+
+   ----- Transcript of session follows -----
+554 Too many hops 19 (17 max): from <linuxuser-admin at www.linux.org.uk> via [199.164.235.226], to <scoffman at wellpartner.com>
+
+--JAB03225.986577786/zinfandel.lacita.com
+Content-Type: message/delivery-status
+
+Reporting-MTA: dns; zinfandel.lacita.com
+Received-From-MTA: dns; [199.164.235.226]
+Arrival-Date: Fri, 6 Apr 2001 09:23:03 -0800 (GMT-0800)
+
+Final-Recipient: rfc822; scoffman at wellpartner.com
+Action: failed
+Status: 5.4.6
+Last-Attempt-Date: Fri, 6 Apr 2001 09:23:06 -0800 (GMT-0800)
+
+--JAB03225.986577786/zinfandel.lacita.com
+Content-Type: text/rfc822-headers
+
+Return-Path: linuxuser-admin at www.linux.org.uk
+Received: from ns1.wellpartner.net ([199.164.235.226]) by zinfandel.lacita.com (8.7.3/8.6.10-MT4.00) with ESMTP id JAA03225 for <scoffman at wellpartner.com>; Fri, 6 Apr 2001 09:23:03 -0800 (GMT-0800)
+Received: from zinfandel.lacita.com ([204.245.199.98])
+	by
+	fo
+Received: from ns1.wellpartner.net ([199.164.235.226]) by zinfandel.lacita.com (8.7.3/8.6.10-MT4.00) with ESMTP id JAA03221 for <scoffman at wellpartner.com>; Fri, 6 Apr 2001 09:22:18 -0800 (GMT-0800)
+Received: from zinfandel.lacita.com ([204.245.199.98])
+	by
+	fo
+Received: from ns1.wellpartner.net ([199.164.235.226]) by zinfandel.lacita.com (8.7.3/8.6.10-MT4.00) with ESMTP id JAA03217 for <scoffman at wellpartner.com>; Fri, 6 Apr 2001 09:21:37 -0800 (GMT-0800)
+Received: from zinfandel.lacita.com ([204.245.199.98])
+	by
+	fo
+Received: from ns1.wellpartner.net ([199.164.235.226]) by zinfandel.lacita.com (8.7.3/8.6.10-MT4.00) with ESMTP id JAA03213 for <scoffman at wellpartner.com>; Fri, 6 Apr 2001 09:20:56 -0800 (GMT-0800)
+Received: from zinfandel.lacita.com ([204.245.199.98])
+	by
+	fo
+Received: from ns1.wellpartner.net ([199.164.235.226]) by zinfandel.lacita.com (8.7.3/8.6.10-MT4.00) with ESMTP id JAA03209 for <scoffman at wellpartner.com>; Fri, 6 Apr 2001 09:20:15 -0800 (GMT-0800)
+Received: from zinfandel.lacita.com ([204.245.199.98])
+	by
+	fo
+Received: from ns1.wellpartner.net ([199.164.235.226]) by zinfandel.lacita.com (8.7.3/8.6.10-MT4.00) with ESMTP id JAA03205 for <scoffman at wellpartner.com>; Fri, 6 Apr 2001 09:19:33 -0800 (GMT-0800)
+Received: from zinfandel.lacita.com ([204.245.199.98])
+	by
+	fo
+Received: from ns1.wellpartner.net ([199.164.235.226]) by zinfandel.lacita.com (8.7.3/8.6.10-MT4.00) with ESMTP id JAA03201 for <scoffman at wellpartner.com>; Fri, 6 Apr 2001 09:18:52 -0800 (GMT-0800)
+Received: from zinfandel.lacita.com ([204.245.199.98])
+	by
+	fo
+Received: from ns1.wellpartner.net ([199.164.235.226]) by zinfandel.lacita.com (8.7.3/8.6.10-MT4.00) with ESMTP id JAA03197 for <scoffman at wellpartner.com>; Fri, 6 Apr 2001 09:17:54 -0800 (GMT-0800)
+Received: from www.linux.org.uk (parcelfarce.linux.theplanet.co.uk [195.92.249.252])
+	by
+	fo
+Received: from localhost.localdomain
+	([
+	by
+	id
+Received: from [212.1.130.11] (helo=s1.uklinux.net ident=root)
+	by
+	id
+	fo
+Received: from server (ppp-2-22.cvx4.telinco.net [212.1.149.22])
+	by
+	fo
+From: Daniel James <daniel at linuxuser.co.uk>
+Organization: LinuxUser
+To: linuxuser at www.linux.org.uk
+X-Mailer: KMail [version 1.1.99]
+Content-Type: text/plain;
+  c
+MIME-Version: 1.0
+Message-Id: <01040616033903.00962 at server>
+Content-Transfer-Encoding: 8bit
+Subject: [LinuxUser] bulletin no. 45
+Sender: linuxuser-admin at www.linux.org.uk
+Errors-To: linuxuser-admin at www.linux.org.uk
+X-BeenThere: linuxuser at www.linux.org.uk
+X-Mailman-Version: 2.0.3
+Precedence: bulk
+List-Help: <mailto:linuxuser-request at www.linux.org.uk?subject=help>
+List-Post: <mailto:linuxuser at www.linux.org.uk>
+List-Subscribe: <http://www.linux.org.uk/mailman/listinfo/linuxuser>,
+	<m
+List-Id: bulletins from LinuxUser magazine <linuxuser.www.linux.org.uk>
+List-Unsubscribe: <http://www.linux.org.uk/mailman/listinfo/linuxuser>,
+	<m
+List-Archive: <http://www.linux.org.uk/pipermail/linuxuser/>
+Date: Fri, 6 Apr 2001 16:03:39 +0100
+
+--JAB03225.986577786/zinfandel.lacita.com--
+
+

Added: vendor/Python/current/Lib/email/test/data/msg_26.txt
===================================================================
--- vendor/Python/current/Lib/email/test/data/msg_26.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/test/data/msg_26.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,45 @@
+Received: from xcar [192.168.0.2] by jeeves.wooster.local
+  (SMTPD32-7.07 EVAL) id AFF92F0214; Sun, 12 May 2002 08:55:37 +0100
+Date: Sun, 12 May 2002 08:56:15 +0100
+From: Father Time <father.time at xcar.wooster.local>
+To: timbo at jeeves.wooster.local
+Subject: IMAP file test
+Message-ID: <6df65d354b.father.time at rpc.wooster.local>
+X-Organization: Home
+User-Agent: Messenger-Pro/2.50a (MsgServe/1.50) (RISC-OS/4.02) POPstar/2.03
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="1618492860--2051301190--113853680"
+Status: R
+X-UIDL: 319998302
+
+This message is in MIME format which your mailer apparently does not support.
+You either require a newer version of your software which supports MIME, or
+a separate MIME decoding utility.  Alternatively, ask the sender of this
+message to resend it in a different format.
+
+--1618492860--2051301190--113853680
+Content-Type: text/plain; charset=us-ascii
+
+Simple email with attachment.
+
+
+--1618492860--2051301190--113853680
+Content-Type: application/riscos; name="clock.bmp,69c"; type=BMP; load=&fff69c4b; exec=&355dd4d1; access=&03
+Content-Disposition: attachment; filename="clock.bmp"
+Content-Transfer-Encoding: base64
+
+Qk12AgAAAAAAAHYAAAAoAAAAIAAAACAAAAABAAQAAAAAAAAAAADXDQAA1w0AAAAAAAAA
+AAAAAAAAAAAAiAAAiAAAAIiIAIgAAACIAIgAiIgAALu7uwCIiIgAERHdACLuIgAz//8A
+zAAAAN0R3QDu7iIA////AAAAAAAAAAAAAAAAAAAAAAAAAAi3AAAAAAAAADeAAAAAAAAA
+C3ADMzMzMANwAAAAAAAAAAAHMAAAAANwAAAAAAAAAACAMAd3zPfwAwgAAAAAAAAIAwd/
+f8x/f3AwgAAAAAAAgDB0x/f3//zPAwgAAAAAAAcHfM9////8z/AwAAAAAAiwd/f3////
+////A4AAAAAAcEx/f///////zAMAAAAAiwfM9////3///8zwOAAAAAcHf3////B/////
+8DAAAAALB/f3///wd3d3//AwAAAABwTPf//wCQAAD/zAMAAAAAsEx/f///B////8wDAA
+AAAHB39////wf/////AwAAAACwf39///8H/////wMAAAAIcHfM9///B////M8DgAAAAA
+sHTH///wf///xAMAAAAACHB3f3//8H////cDgAAAAAALB3zH//D//M9wMAAAAAAAgLB0
+z39///xHAwgAAAAAAAgLB3d3RHd3cDCAAAAAAAAAgLAHd0R3cAMIAAAAAAAAgAgLcAAA
+AAMwgAgAAAAACDAAAAu7t7cwAAgDgAAAAABzcIAAAAAAAAgDMwAAAAAAN7uwgAAAAAgH
+MzMAAAAACH97tzAAAAALu3c3gAAAAAAL+7tzDABAu7f7cAAAAAAACA+3MA7EQAv/sIAA
+AAAAAAAIAAAAAAAAAIAAAAAA
+
+--1618492860--2051301190--113853680--

Added: vendor/Python/current/Lib/email/test/data/msg_27.txt
===================================================================
--- vendor/Python/current/Lib/email/test/data/msg_27.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/test/data/msg_27.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,15 @@
+Return-Path: <aperson at dom.ain>
+Received: by mail.dom.ain (Postfix, from userid 889)
+	id B9D0AD35DB; Tue,  4 Jun 2002 21:46:59 -0400 (EDT)
+Message-ID: <15613.28051.707126.569693 at dom.ain>
+Date: Tue, 4 Jun 2002 21:46:59 -0400
+MIME-Version: 1.0
+Content-Type: text/plain; charset=us-ascii
+Content-Transfer-Encoding: 7bit
+Subject: bug demonstration
+	12345678911234567892123456789312345678941234567895123456789612345678971234567898112345678911234567892123456789112345678911234567892123456789
+	more text
+From: aperson at dom.ain (Anne P. Erson)
+To: bperson at dom.ain (Barney P. Erson)
+
+test

Added: vendor/Python/current/Lib/email/test/data/msg_28.txt
===================================================================
--- vendor/Python/current/Lib/email/test/data/msg_28.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/test/data/msg_28.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,25 @@
+From: aperson at dom.ain
+MIME-Version: 1.0
+Content-Type: multipart/digest; boundary=BOUNDARY
+
+--BOUNDARY
+Content-Type: message/rfc822
+
+Content-Type: text/plain; charset=us-ascii
+To: aa at bb.org
+From: cc at dd.org
+Subject: ee
+
+message 1
+
+--BOUNDARY
+Content-Type: message/rfc822
+
+Content-Type: text/plain; charset=us-ascii
+To: aa at bb.org
+From: cc at dd.org
+Subject: ee
+
+message 2
+
+--BOUNDARY--

Added: vendor/Python/current/Lib/email/test/data/msg_29.txt
===================================================================
--- vendor/Python/current/Lib/email/test/data/msg_29.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/test/data/msg_29.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,22 @@
+Return-Path: <bbb at zzz.org>
+Delivered-To: bbb at zzz.org
+Received: by mail.zzz.org (Postfix, from userid 889)
+	id 27CEAD38CC; Fri,  4 May 2001 14:05:44 -0400 (EDT)
+MIME-Version: 1.0
+Content-Type: text/plain; charset=us-ascii;
+     title*0*="us-ascii'en'This%20is%20even%20more%20";
+     title*1*="%2A%2A%2Afun%2A%2A%2A%20";
+     title*2="isn't it!"
+Content-Transfer-Encoding: 7bit
+Message-ID: <15090.61304.110929.45684 at aaa.zzz.org>
+From: bbb at ddd.com (John X. Doe)
+To: bbb at zzz.org
+Subject: This is a test message
+Date: Fri, 4 May 2001 14:05:44 -0400
+
+
+Hi,
+
+Do you like this message?
+
+-Me

Added: vendor/Python/current/Lib/email/test/data/msg_30.txt
===================================================================
--- vendor/Python/current/Lib/email/test/data/msg_30.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/test/data/msg_30.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,23 @@
+From: aperson at dom.ain
+MIME-Version: 1.0
+Content-Type: multipart/digest; boundary=BOUNDARY
+
+--BOUNDARY
+
+Content-Type: text/plain; charset=us-ascii
+To: aa at bb.org
+From: cc at dd.org
+Subject: ee
+
+message 1
+
+--BOUNDARY
+
+Content-Type: text/plain; charset=us-ascii
+To: aa at bb.org
+From: cc at dd.org
+Subject: ee
+
+message 2
+
+--BOUNDARY--

Added: vendor/Python/current/Lib/email/test/data/msg_31.txt
===================================================================
--- vendor/Python/current/Lib/email/test/data/msg_31.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/test/data/msg_31.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,15 @@
+From: aperson at dom.ain
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary=BOUNDARY_
+
+--BOUNDARY
+Content-Type: text/plain
+
+message 1
+
+--BOUNDARY
+Content-Type: text/plain
+
+message 2
+
+--BOUNDARY--

Added: vendor/Python/current/Lib/email/test/data/msg_32.txt
===================================================================
--- vendor/Python/current/Lib/email/test/data/msg_32.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/test/data/msg_32.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,14 @@
+Delivered-To: freebsd-isp at freebsd.org
+Date: Tue, 26 Sep 2000 12:23:03 -0500
+From: Anne Person <aperson at example.com>
+To: Barney Dude <bdude at example.com>
+Subject: Re: Limiting Perl CPU Utilization...
+Mime-Version: 1.0
+Content-Type: text/plain; charset*=ansi-x3.4-1968''us-ascii
+Content-Disposition: inline
+User-Agent: Mutt/1.3.8i
+Sender: owner-freebsd-isp at FreeBSD.ORG
+Precedence: bulk
+X-Loop: FreeBSD.org
+
+Some message.

Added: vendor/Python/current/Lib/email/test/data/msg_33.txt
===================================================================
--- vendor/Python/current/Lib/email/test/data/msg_33.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/test/data/msg_33.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,29 @@
+Delivered-To: freebsd-isp at freebsd.org
+Date: Wed, 27 Sep 2000 11:11:09 -0500
+From: Anne Person <aperson at example.com>
+To: Barney Dude <bdude at example.com>
+Subject: Re: Limiting Perl CPU Utilization...
+Mime-Version: 1.0
+Content-Type: multipart/signed; micalg*=ansi-x3.4-1968''pgp-md5;
+	protocol*=ansi-x3.4-1968''application%2Fpgp-signature;
+	boundary*="ansi-x3.4-1968''EeQfGwPcQSOJBaQU"
+Content-Disposition: inline
+Sender: owner-freebsd-isp at FreeBSD.ORG
+Precedence: bulk
+X-Loop: FreeBSD.org
+
+
+--EeQfGwPcQSOJBaQU
+Content-Type: text/plain; charset*=ansi-x3.4-1968''us-ascii
+Content-Disposition: inline
+Content-Transfer-Encoding: quoted-printable
+
+part 1
+
+--EeQfGwPcQSOJBaQU
+Content-Type: text/plain
+Content-Disposition: inline
+
+part 2
+
+--EeQfGwPcQSOJBaQU--

Added: vendor/Python/current/Lib/email/test/data/msg_34.txt
===================================================================
--- vendor/Python/current/Lib/email/test/data/msg_34.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/test/data/msg_34.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,19 @@
+From: aperson at dom.ain
+To: bperson at dom.ain
+Content-Type: multipart/digest; boundary=XYZ
+
+--XYZ
+Content-Type: text/plain
+
+
+This is a text plain part that is counter to recommended practice in
+RFC 2046, $5.1.5, but is not illegal
+
+--XYZ
+
+From: cperson at dom.ain
+To: dperson at dom.ain
+
+A submessage
+
+--XYZ--

Added: vendor/Python/current/Lib/email/test/data/msg_35.txt
===================================================================
--- vendor/Python/current/Lib/email/test/data/msg_35.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/test/data/msg_35.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,4 @@
+From: aperson at dom.ain
+To: bperson at dom.ain
+Subject: here's something interesting
+counter to RFC 2822, there's no separating newline here

Added: vendor/Python/current/Lib/email/test/data/msg_36.txt
===================================================================
--- vendor/Python/current/Lib/email/test/data/msg_36.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/test/data/msg_36.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,40 @@
+Mime-Version: 1.0
+Content-Type: Multipart/Mixed; Boundary="NextPart"
+To: IETF-Announce:;
+From: Internet-Drafts at ietf.org
+Subject: I-D ACTION:draft-ietf-mboned-mix-00.txt
+Date: Tue, 22 Dec 1998 16:55:06 -0500
+
+--NextPart
+
+Blah blah blah
+
+--NextPart
+Content-Type: Multipart/Alternative; Boundary="OtherAccess"
+
+--OtherAccess
+Content-Type: Message/External-body;
+	access-type="mail-server";
+	server="mailserv at ietf.org"
+
+Content-Type: text/plain
+Content-ID: <19981222151406.I-D at ietf.org>
+
+ENCODING mime
+FILE /internet-drafts/draft-ietf-mboned-mix-00.txt
+
+--OtherAccess
+Content-Type: Message/External-body;
+	name="draft-ietf-mboned-mix-00.txt";
+	site="ftp.ietf.org";
+	access-type="anon-ftp";
+	directory="internet-drafts"
+
+Content-Type: text/plain
+Content-ID: <19981222151406.I-D at ietf.org>
+
+
+--OtherAccess--
+
+--NextPart--
+

Added: vendor/Python/current/Lib/email/test/data/msg_37.txt
===================================================================
--- vendor/Python/current/Lib/email/test/data/msg_37.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/test/data/msg_37.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,22 @@
+Content-Type: multipart/mixed; boundary=ABCDE
+
+--ABCDE
+Content-Type: text/x-one
+
+Blah
+
+--ABCDE
+--ABCDE
+Content-Type: text/x-two
+
+Blah
+
+--ABCDE
+--ABCDE
+--ABCDE
+--ABCDE
+Content-Type: text/x-two
+
+Blah
+
+--ABCDE--

Added: vendor/Python/current/Lib/email/test/data/msg_38.txt
===================================================================
--- vendor/Python/current/Lib/email/test/data/msg_38.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/test/data/msg_38.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,101 @@
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="----- =_aaaaaaaaaa0"
+
+------- =_aaaaaaaaaa0
+Content-Type: multipart/mixed; boundary="----- =_aaaaaaaaaa1"
+Content-ID: <20592.1022586929.1 at example.com>
+
+------- =_aaaaaaaaaa1
+Content-Type: multipart/alternative; boundary="----- =_aaaaaaaaaa2"
+Content-ID: <20592.1022586929.2 at example.com>
+
+------- =_aaaaaaaaaa2
+Content-Type: text/plain
+Content-ID: <20592.1022586929.3 at example.com>
+Content-Description: very tricky
+Content-Transfer-Encoding: 7bit
+
+
+Unlike the test test_nested-multiples-with-internal-boundary, this
+piece of text not only contains the outer boundary tags 
+------- =_aaaaaaaaaa1 
+and 
+------- =_aaaaaaaaaa0 
+but puts them at the start of a line! And, to be even nastier, it
+even includes a couple of end tags, such as this one:
+
+------- =_aaaaaaaaaa1--
+
+and this one, which is from a multipart we haven't even seen yet!
+
+------- =_aaaaaaaaaa4--
+
+This will, I'm sure, cause much breakage of MIME parsers. But, as 
+far as I can tell, it's perfectly legal. I have not yet ever seen
+a case of this in the wild, but I've seen *similar* things.
+
+
+------- =_aaaaaaaaaa2
+Content-Type: application/octet-stream
+Content-ID: <20592.1022586929.4 at example.com>
+Content-Description: patch2
+Content-Transfer-Encoding: base64
+
+XXX
+
+------- =_aaaaaaaaaa2--
+
+------- =_aaaaaaaaaa1
+Content-Type: multipart/alternative; boundary="----- =_aaaaaaaaaa3"
+Content-ID: <20592.1022586929.6 at example.com>
+
+------- =_aaaaaaaaaa3
+Content-Type: application/octet-stream
+Content-ID: <20592.1022586929.7 at example.com>
+Content-Description: patch3
+Content-Transfer-Encoding: base64
+
+XXX
+
+------- =_aaaaaaaaaa3
+Content-Type: application/octet-stream
+Content-ID: <20592.1022586929.8 at example.com>
+Content-Description: patch4
+Content-Transfer-Encoding: base64
+
+XXX
+
+------- =_aaaaaaaaaa3--
+
+------- =_aaaaaaaaaa1
+Content-Type: multipart/alternative; boundary="----- =_aaaaaaaaaa4"
+Content-ID: <20592.1022586929.10 at example.com>
+
+------- =_aaaaaaaaaa4
+Content-Type: application/octet-stream
+Content-ID: <20592.1022586929.11 at example.com>
+Content-Description: patch5
+Content-Transfer-Encoding: base64
+
+XXX
+
+------- =_aaaaaaaaaa4
+Content-Type: application/octet-stream
+Content-ID: <20592.1022586929.12 at example.com>
+Content-Description: patch6
+Content-Transfer-Encoding: base64
+
+XXX
+
+------- =_aaaaaaaaaa4--
+
+------- =_aaaaaaaaaa1--
+
+------- =_aaaaaaaaaa0
+Content-Type: text/plain; charset="us-ascii"
+Content-ID: <20592.1022586929.15 at example.com>
+
+--
+It's never too late to have a happy childhood.
+
+------- =_aaaaaaaaaa0--

Added: vendor/Python/current/Lib/email/test/data/msg_39.txt
===================================================================
--- vendor/Python/current/Lib/email/test/data/msg_39.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/test/data/msg_39.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,83 @@
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="----- =_aaaaaaaaaa0"
+
+------- =_aaaaaaaaaa0
+Content-Type: multipart/mixed; boundary="----- =_aaaaaaaaaa1"
+Content-ID: <20592.1022586929.1 at example.com>
+
+------- =_aaaaaaaaaa1
+Content-Type: multipart/alternative; boundary="----- =_aaaaaaaaaa1"
+Content-ID: <20592.1022586929.2 at example.com>
+
+------- =_aaaaaaaaaa1
+Content-Type: application/octet-stream
+Content-ID: <20592.1022586929.3 at example.com>
+Content-Description: patch1
+Content-Transfer-Encoding: base64
+
+XXX
+
+------- =_aaaaaaaaaa1
+Content-Type: application/octet-stream
+Content-ID: <20592.1022586929.4 at example.com>
+Content-Description: patch2
+Content-Transfer-Encoding: base64
+
+XXX
+
+------- =_aaaaaaaaaa1--
+
+------- =_aaaaaaaaaa1
+Content-Type: multipart/alternative; boundary="----- =_aaaaaaaaaa1"
+Content-ID: <20592.1022586929.6 at example.com>
+
+------- =_aaaaaaaaaa1
+Content-Type: application/octet-stream
+Content-ID: <20592.1022586929.7 at example.com>
+Content-Description: patch3
+Content-Transfer-Encoding: base64
+
+XXX
+
+------- =_aaaaaaaaaa1
+Content-Type: application/octet-stream
+Content-ID: <20592.1022586929.8 at example.com>
+Content-Description: patch4
+Content-Transfer-Encoding: base64
+
+XXX
+
+------- =_aaaaaaaaaa1--
+
+------- =_aaaaaaaaaa1
+Content-Type: multipart/alternative; boundary="----- =_aaaaaaaaaa1"
+Content-ID: <20592.1022586929.10 at example.com>
+
+------- =_aaaaaaaaaa1
+Content-Type: application/octet-stream
+Content-ID: <20592.1022586929.11 at example.com>
+Content-Description: patch5
+Content-Transfer-Encoding: base64
+
+XXX
+
+------- =_aaaaaaaaaa1
+Content-Type: application/octet-stream
+Content-ID: <20592.1022586929.12 at example.com>
+Content-Description: patch6
+Content-Transfer-Encoding: base64
+
+XXX
+
+------- =_aaaaaaaaaa1--
+
+------- =_aaaaaaaaaa1--
+
+------- =_aaaaaaaaaa0
+Content-Type: text/plain; charset="us-ascii"
+Content-ID: <20592.1022586929.15 at example.com>
+
+--
+It's never too late to have a happy childhood.
+
+------- =_aaaaaaaaaa0--

Added: vendor/Python/current/Lib/email/test/data/msg_40.txt
===================================================================
--- vendor/Python/current/Lib/email/test/data/msg_40.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/test/data/msg_40.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,10 @@
+MIME-Version: 1.0
+Content-Type: text/html; boundary="--961284236552522269"
+
+----961284236552522269
+Content-Type: text/html;
+Content-Transfer-Encoding: 7Bit
+
+<html></html>
+
+----961284236552522269--

Added: vendor/Python/current/Lib/email/test/data/msg_41.txt
===================================================================
--- vendor/Python/current/Lib/email/test/data/msg_41.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/test/data/msg_41.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,8 @@
+From: "Allison Dunlap" <xxx at example.com>
+To: yyy at example.com
+Subject: 64423
+Date: Sun, 11 Jul 2004 16:09:27 -0300
+MIME-Version: 1.0
+Content-Type: multipart/alternative;
+
+Blah blah blah

Added: vendor/Python/current/Lib/email/test/data/msg_42.txt
===================================================================
--- vendor/Python/current/Lib/email/test/data/msg_42.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/test/data/msg_42.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,20 @@
+Content-Type: multipart/mixed; boundary="AAA"
+From: Mail Delivery Subsystem <xxx at example.com>
+To: yyy at example.com
+
+This is a MIME-encapsulated message
+
+--AAA
+
+Stuff
+
+--AAA
+Content-Type: message/rfc822
+
+From: webmaster at python.org
+To: zzz at example.com
+Content-Type: multipart/mixed; boundary="BBB"
+
+--BBB--
+
+--AAA--

Added: vendor/Python/current/Lib/email/test/data/msg_43.txt
===================================================================
--- vendor/Python/current/Lib/email/test/data/msg_43.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/test/data/msg_43.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,217 @@
+From SRS0=aO/p=ON=bag.python.org=None at bounce2.pobox.com  Fri Nov 26 21:40:36 2004
+X-VM-v5-Data: ([nil nil nil nil nil nil nil nil nil]
+	[nil nil nil nil nil nil nil "MAILER DAEMON <>" "MAILER DAEMON <>" nil nil "Banned file: auto__mail.python.bat in mail from you" "^From:" nil nil nil nil "Banned file: auto__mail.python.bat in mail from you" nil nil nil nil nil nil nil]
+	nil)
+MIME-Version: 1.0
+Message-Id: <edab.7804f5cb8070 at python.org>
+Content-Type: multipart/report; report-type=delivery-status;
+    charset=utf-8;
+    boundary="----------=_1101526904-1956-5"
+X-Virus-Scanned: by XS4ALL Virus Scanner
+X-UIDL: 4\G!!!<c"!UV["!M7C!!
+From: MAILER DAEMON <>
+To: <webmaster at python.org>
+Subject: Banned file: auto__mail.python.bat in mail from you
+Date: Fri, 26 Nov 2004 19:41:44 -0800 (PST)
+
+This is a multi-part message in MIME format...
+
+------------=_1101526904-1956-5
+Content-Type: text/plain; charset="utf-8"
+Content-Disposition: inline
+Content-Transfer-Encoding: 7bit
+
+BANNED FILENAME ALERT
+
+Your message to: xxxxxxx at dot.ca.gov, xxxxxxxxxxxxx at dot.ca.gov, xxxxxxxxxx at dot.ca.gov, xxxxxxxx at dot.ca.gov, xxxxxxxxxx at dot.ca.gov, xxxxxx at dot.ca.gov, xxxxxxxxxx at dot.ca.gov, xxxxxx at dot.ca.gov, xxxxxx at dot.ca.gov, xxxxxxxxxxxxxxxx at dot.ca.gov, xxxxxxxxxxx at dot.ca.gov, xxxxxxxxxx at dot.ca.gov, xxxxxxxxxx at dot.ca.gov, xxxxxxxxxxxx at dot.ca.gov, xxxxxxxxxxxx at dot.ca.gov, xxxxxxx at dot.ca.gov, xxxxxxxxx at dot.ca.gov, xxxxxxxxxx at dot.ca.gov, xxxxxx at dot.ca.gov, xxx at dot.ca.gov, xxxxxxx at dot.ca.gov, xxxxxxx at dot.ca.gov, xxxxxxxxxxxxxxx at dot.ca.gov, xxxxxxxxxx at dot.ca.gov, xxxxxxx at dot.ca.gov, xxx at dot.ca.gov, xxxxxxxx at dot.ca.gov, xxxxxxxxxxxxx at dot.ca.gov, xxxxxxxxxxxxx at dot.ca.gov, xxxxxxxxxxx at dot.ca.gov, xxxxxxxxx at dot.ca.gov, xxxxxxxxxx at dot.ca.gov, xxxxxxxxxxxx at dot.ca.gov, xxxxxxx at dot.ca.gov, xxxxxxxxxxxxxxx at dot.ca.gov, xxxxxxxxxxxxx at dot.ca.gov, xxxx at dot.ca.gov, xxxxxxxx at dot.ca.gov, xxxxxxxxxx at dot.ca.gov, xxxxxxxxxxxxxxxxxx at dot.ca.gov
+was blocked by our Spam Firewall. The email you sent with the following subject has NOT BEEN DELIVERED:
+
+Subject: Delivery_failure_notice
+
+An attachment in that mail was of a file type that the Spam Firewall is set to block.
+
+
+
+------------=_1101526904-1956-5
+Content-Type: message/delivery-status
+Content-Disposition: inline
+Content-Transfer-Encoding: 7bit
+Content-Description: Delivery error report
+
+Reporting-MTA: dns; sacspam01.dot.ca.gov
+Received-From-MTA: smtp; sacspam01.dot.ca.gov ([127.0.0.1])
+Arrival-Date: Fri, 26 Nov 2004 19:41:44 -0800 (PST)
+
+Final-Recipient: rfc822; xxxxxxx at dot.ca.gov
+Action: failed
+Status: 5.7.1
+Diagnostic-Code: smtp; 550 5.7.1 Message content rejected, id=01956-02-2 - BANNED: auto__mail.python.bat
+Last-Attempt-Date: Fri, 26 Nov 2004 19:41:44 -0800 (PST)
+
+Final-Recipient: rfc822; xxxxxxxxxxxxx at dot.ca.gov
+Action: failed
+Status: 5.7.1
+Diagnostic-Code: smtp; 550 5.7.1 Message content rejected, id=01956-02-2 - BANNED: auto__mail.python.bat
+Last-Attempt-Date: Fri, 26 Nov 2004 19:41:44 -0800 (PST)
+
+Final-Recipient: rfc822; xxxxxxxxxx at dot.ca.gov
+Action: failed
+Status: 5.7.1
+Diagnostic-Code: smtp; 550 5.7.1 Message content rejected, id=01956-02-2 - BANNED: auto__mail.python.bat
+Last-Attempt-Date: Fri, 26 Nov 2004 19:41:44 -0800 (PST)
+
+Final-Recipient: rfc822; xxxxxxxx at dot.ca.gov
+Action: failed
+Status: 5.7.1
+Diagnostic-Code: smtp; 550 5.7.1 Message content rejected, id=01956-02-2 - BANNED: auto__mail.python.bat
+Last-Attempt-Date: Fri, 26 Nov 2004 19:41:44 -0800 (PST)
+
+Final-Recipient: rfc822; xxxxxxxxxx at dot.ca.gov
+Action: failed
+Status: 5.7.1
+Diagnostic-Code: smtp; 550 5.7.1 Message content rejected, id=01956-02-2 - BANNED: auto__mail.python.bat
+Last-Attempt-Date: Fri, 26 Nov 2004 19:41:44 -0800 (PST)
+
+Final-Recipient: rfc822; xxxxxx at dot.ca.gov
+Action: failed
+Status: 5.7.1
+Diagnostic-Code: smtp; 550 5.7.1 Message content rejected, id=01956-02-2 - BANNED: auto__mail.python.bat
+Last-Attempt-Date: Fri, 26 Nov 2004 19:41:44 -0800 (PST)
+
+Final-Recipient: rfc822; xxxxxxxxxx at dot.ca.gov
+Action: failed
+Status: 5.7.1
+Diagnostic-Code: smtp; 550 5.7.1 Message content rejected, id=01956-02-2 - BANNED: auto__mail.python.bat
+Last-Attempt-Date: Fri, 26 Nov 2004 19:41:44 -0800 (PST)
+
+Final-Recipient: rfc822; xxxxxx at dot.ca.gov
+Action: failed
+Status: 5.7.1
+Diagnostic-Code: smtp; 550 5.7.1 Message content rejected, id=01956-02-2 - BANNED: auto__mail.python.bat
+Last-Attempt-Date: Fri, 26 Nov 2004 19:41:44 -0800 (PST)
+
+Final-Recipient: rfc822; xxxxxx at dot.ca.gov
+Action: failed
+Status: 5.7.1
+Diagnostic-Code: smtp; 550 5.7.1 Message content rejected, id=01956-02-2 - BANNED: auto__mail.python.bat
+Last-Attempt-Date: Fri, 26 Nov 2004 19:41:44 -0800 (PST)
+
+Final-Recipient: rfc822; xxxxxxxxxxxxxxxx at dot.ca.gov
+Action: failed
+Status: 5.7.1
+Diagnostic-Code: smtp; 550 5.7.1 Message content rejected, id=01956-02-2 - BANNED: auto__mail.python.bat
+Last-Attempt-Date: Fri, 26 Nov 2004 19:41:44 -0800 (PST)
+
+Final-Recipient: rfc822; xxxxxxxxxxx at dot.ca.gov
+Action: failed
+Status: 5.7.1
+Diagnostic-Code: smtp; 550 5.7.1 Message content rejected, id=01956-02-2 - BANNED: auto__mail.python.bat
+Last-Attempt-Date: Fri, 26 Nov 2004 19:41:44 -0800 (PST)
+
+Final-Recipient: rfc822; xxxxxxxxxx at dot.ca.gov
+Action: failed
+Status: 5.7.1
+Diagnostic-Code: smtp; 550 5.7.1 Message content rejected, id=01956-02-2 - BANNED: auto__mail.python.bat
+Last-Attempt-Date: Fri, 26 Nov 2004 19:41:44 -0800 (PST)
+
+Final-Recipient: rfc822; xxxxxxxxxx at dot.ca.gov
+Action: failed
+Status: 5.7.1
+Diagnostic-Code: smtp; 550 5.7.1 Message content rejected, id=01956-02-2 - BANNED: auto__mail.python.bat
+Last-Attempt-Date: Fri, 26 Nov 2004 19:41:44 -0800 (PST)
+
+Final-Recipient: rfc822; xxxxxxxxxxxx at dot.ca.gov
+Action: failed
+Status: 5.7.1
+Diagnostic-Code: smtp; 550 5.7.1 Message content rejected, id=01956-02-2 - BANNED: auto__mail.python.bat
+Last-Attempt-Date: Fri, 26 Nov 2004 19:41:44 -0800 (PST)
+
+Final-Recipient: rfc822; xxxxxxxxxxxx at dot.ca.gov
+Action: failed
+Status: 5.7.1
+Diagnostic-Code: smtp; 550 5.7.1 Message content rejected, id=01956-02-2 - BANNED: auto__mail.python.bat
+Last-Attempt-Date: Fri, 26 Nov 2004 19:41:44 -0800 (PST)
+
+Final-Recipient: rfc822; xxxxxxx at dot.ca.gov
+Action: failed
+Status: 5.7.1
+Diagnostic-Code: smtp; 550 5.7.1 Message content rejected, id=01956-02-2 - BANNED: auto__mail.python.bat
+Last-Attempt-Date: Fri, 26 Nov 2004 19:41:44 -0800 (PST)
+
+Final-Recipient: rfc822; xxxxxxxxx at dot.ca.gov
+Action: failed
+Status: 5.7.1
+Diagnostic-Code: smtp; 550 5.7.1 Message content rejected, id=01956-02-2 - BANNED: auto__mail.python.bat
+Last-Attempt-Date: Fri, 26 Nov 2004 19:41:44 -0800 (PST)
+
+Final-Recipient: rfc822; xxxxxxxxxx at dot.ca.gov
+Action: failed
+Status: 5.7.1
+Diagnostic-Code: smtp; 550 5.7.1 Message content rejected, id=01956-02-2 - BANNED: auto__mail.python.bat
+Last-Attempt-Date: Fri, 26 Nov 2004 19:41:44 -0800 (PST)
+
+Final-Recipient: rfc822; xxxxxx at dot.ca.gov
+Action: failed
+Status: 5.7.1
+Diagnostic-Code: smtp; 550 5.7.1 Message content rejected, id=01956-02-2 - BANNED: auto__mail.python.bat
+Last-Attempt-Date: Fri, 26 Nov 2004 19:41:44 -0800 (PST)
+
+Final-Recipient: rfc822; xxx at dot.ca.gov
+Action: failed
+Status: 5.7.1
+Diagnostic-Code: smtp; 550 5.7.1 Message content rejected, id=01956-02-2 - BANNED: auto__mail.python.bat
+Last-Attempt-Date: Fri, 26 Nov 2004 19:41:44 -0800 (PST)
+
+Final-Recipient: rfc822; xxxxxxx at dot.ca.gov
+Action: failed
+Status: 5.7.1
+Diagnostic-Code: smtp; 550 5.7.1 Message content rejected, id=01956-02-2 - BANNED: auto__mail.python.bat
+Last-Attempt-Date: Fri, 26 Nov 2004 19:41:44 -0800 (PST)
+
+Final-Recipient: rfc822; xxxxxxx at dot.ca.gov
+Action: failed
+Status: 5.7.1
+Diagnostic-Code: smtp; 550 5.7.1 Message content rejected, id=01956-02-2 - BANNED: auto__mail.python.bat
+Last-Attempt-Date: Fri, 26 Nov 2004 19:41:44 -0800 (PST)
+
+Final-Recipient: rfc822; xxxxxxxxxxxxxxx at dot.ca.gov
+Action: failed
+Status: 5.7.1
+Diagnostic-Code: smtp; 550 5.7.1 Message content rejected, id=01956-02-2 - BANNED: auto__mail.python.bat
+Last-Attempt-Date: Fri, 26 Nov 2004 19:41:44 -0800 (PST)
+
+Final-Recipient: rfc822; xxxxxxxxxx at dot.ca.gov
+Action: failed
+Status: 5.7.1
+Diagnostic-Code: smtp; 550 5.7.1 Message content rejected, id=01956-02-2 - BANNED: auto__mail.python.bat
+Last-Attempt-Date: Fri, 26 Nov 2004 19:41:44 -0800 (PST)
+
+Final-Recipient: rfc822; xxxxxxx at dot.ca.gov
+Action: failed
+Status: 5.7.1
+Diagnostic-Code: smtp; 550 5.7.1 Message content rejected, id=01956-02-2 - BANNED: auto__mail.python.bat
+Last-Attempt-Date: Fri, 26 Nov 2004 19:41:44 -0800 (PST)
+
+------------=_1101526904-1956-5
+Content-Type: text/rfc822-headers
+Content-Disposition: inline
+Content-Transfer-Encoding: 7bit
+Content-Description: Undelivered-message headers
+
+Received: from kgsav.org (ppp-70-242-162-63.dsl.spfdmo.swbell.net [70.242.162.63])
+	by sacspam01.dot.ca.gov (Spam Firewall) with SMTP
+	id A232AD03DE3A; Fri, 26 Nov 2004 19:41:35 -0800 (PST)
+From: webmaster at python.org
+To: xxxxx at dot.ca.gov
+Date: Sat, 27 Nov 2004 03:35:30 UTC
+Subject: Delivery_failure_notice
+Importance: Normal
+X-Priority: 3 (Normal)
+X-MSMail-Priority: Normal
+Message-ID: <edab.7804f5cb8070 at python.org>
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="====67bd2b7a5.f99f7"
+Content-Transfer-Encoding: 7bit
+
+------------=_1101526904-1956-5--
+

Added: vendor/Python/current/Lib/email/test/data/msg_44.txt
===================================================================
--- vendor/Python/current/Lib/email/test/data/msg_44.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/test/data/msg_44.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,35 @@
+Return-Path: <barry at python.org>
+Delivered-To: barry at python.org
+Received: by mail.python.org (Postfix, from userid 889)
+	id C2BF0D37C6; Tue, 11 Sep 2001 00:05:05 -0400 (EDT)
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="h90VIIIKmx"
+Content-Transfer-Encoding: 7bit
+Message-ID: <15261.36209.358846.118674 at anthem.python.org>
+From: barry at python.org (Barry A. Warsaw)
+To: barry at python.org
+Subject: a simple multipart
+Date: Tue, 11 Sep 2001 00:05:05 -0400
+X-Mailer: VM 6.95 under 21.4 (patch 4) "Artificial Intelligence" XEmacs Lucid
+X-Attribution: BAW
+X-Oblique-Strategy: Make a door into a window
+
+
+--h90VIIIKmx
+Content-Type: text/plain
+Content-Disposition: inline; name="msg.txt"
+Content-Transfer-Encoding: 7bit
+
+a simple kind of mirror
+to reflect upon our own
+
+--h90VIIIKmx
+Content-Type: text/plain
+Content-Disposition: inline; name="msg.txt"
+Content-Transfer-Encoding: 7bit
+
+a simple kind of mirror
+to reflect upon our own
+
+--h90VIIIKmx--
+

Added: vendor/Python/current/Lib/email/test/test_email.py
===================================================================
--- vendor/Python/current/Lib/email/test/test_email.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/test/test_email.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,3274 @@
+# Copyright (C) 2001-2007 Python Software Foundation
+# Contact: email-sig at python.org
+# email package unit tests
+
+import os
+import sys
+import time
+import base64
+import difflib
+import unittest
+import warnings
+from cStringIO import StringIO
+
+import email
+
+from email.Charset import Charset
+from email.Header import Header, decode_header, make_header
+from email.Parser import Parser, HeaderParser
+from email.Generator import Generator, DecodedGenerator
+from email.Message import Message
+from email.MIMEAudio import MIMEAudio
+from email.MIMEText import MIMEText
+from email.MIMEImage import MIMEImage
+from email.MIMEBase import MIMEBase
+from email.MIMEMessage import MIMEMessage
+from email.MIMEMultipart import MIMEMultipart
+from email import Utils
+from email import Errors
+from email import Encoders
+from email import Iterators
+from email import base64MIME
+from email import quopriMIME
+
+from test.test_support import findfile, run_unittest
+from email.test import __file__ as landmark
+
+
+NL = '\n'
+EMPTYSTRING = ''
+SPACE = ' '
+
+
+
+def openfile(filename, mode='r'):
+    path = os.path.join(os.path.dirname(landmark), 'data', filename)
+    return open(path, mode)
+
+
+
+# Base test class
+class TestEmailBase(unittest.TestCase):
+    def ndiffAssertEqual(self, first, second):
+        """Like failUnlessEqual except use ndiff for readable output."""
+        if first <> second:
+            sfirst = str(first)
+            ssecond = str(second)
+            diff = difflib.ndiff(sfirst.splitlines(), ssecond.splitlines())
+            fp = StringIO()
+            print >> fp, NL, NL.join(diff)
+            raise self.failureException, fp.getvalue()
+
+    def _msgobj(self, filename):
+        fp = openfile(findfile(filename))
+        try:
+            msg = email.message_from_file(fp)
+        finally:
+            fp.close()
+        return msg
+
+
+
+# Test various aspects of the Message class's API
+class TestMessageAPI(TestEmailBase):
+    def test_get_all(self):
+        eq = self.assertEqual
+        msg = self._msgobj('msg_20.txt')
+        eq(msg.get_all('cc'), ['ccc at zzz.org', 'ddd at zzz.org', 'eee at zzz.org'])
+        eq(msg.get_all('xx', 'n/a'), 'n/a')
+
+    def test_getset_charset(self):
+        eq = self.assertEqual
+        msg = Message()
+        eq(msg.get_charset(), None)
+        charset = Charset('iso-8859-1')
+        msg.set_charset(charset)
+        eq(msg['mime-version'], '1.0')
+        eq(msg.get_content_type(), 'text/plain')
+        eq(msg['content-type'], 'text/plain; charset="iso-8859-1"')
+        eq(msg.get_param('charset'), 'iso-8859-1')
+        eq(msg['content-transfer-encoding'], 'quoted-printable')
+        eq(msg.get_charset().input_charset, 'iso-8859-1')
+        # Remove the charset
+        msg.set_charset(None)
+        eq(msg.get_charset(), None)
+        eq(msg['content-type'], 'text/plain')
+        # Try adding a charset when there's already MIME headers present
+        msg = Message()
+        msg['MIME-Version'] = '2.0'
+        msg['Content-Type'] = 'text/x-weird'
+        msg['Content-Transfer-Encoding'] = 'quinted-puntable'
+        msg.set_charset(charset)
+        eq(msg['mime-version'], '2.0')
+        eq(msg['content-type'], 'text/x-weird; charset="iso-8859-1"')
+        eq(msg['content-transfer-encoding'], 'quinted-puntable')
+
+    def test_set_charset_from_string(self):
+        eq = self.assertEqual
+        msg = Message()
+        msg.set_charset('us-ascii')
+        eq(msg.get_charset().input_charset, 'us-ascii')
+        eq(msg['content-type'], 'text/plain; charset="us-ascii"')
+
+    def test_set_payload_with_charset(self):
+        msg = Message()
+        charset = Charset('iso-8859-1')
+        msg.set_payload('This is a string payload', charset)
+        self.assertEqual(msg.get_charset().input_charset, 'iso-8859-1')
+
+    def test_get_charsets(self):
+        eq = self.assertEqual
+
+        msg = self._msgobj('msg_08.txt')
+        charsets = msg.get_charsets()
+        eq(charsets, [None, 'us-ascii', 'iso-8859-1', 'iso-8859-2', 'koi8-r'])
+
+        msg = self._msgobj('msg_09.txt')
+        charsets = msg.get_charsets('dingbat')
+        eq(charsets, ['dingbat', 'us-ascii', 'iso-8859-1', 'dingbat',
+                      'koi8-r'])
+
+        msg = self._msgobj('msg_12.txt')
+        charsets = msg.get_charsets()
+        eq(charsets, [None, 'us-ascii', 'iso-8859-1', None, 'iso-8859-2',
+                      'iso-8859-3', 'us-ascii', 'koi8-r'])
+
+    def test_get_filename(self):
+        eq = self.assertEqual
+
+        msg = self._msgobj('msg_04.txt')
+        filenames = [p.get_filename() for p in msg.get_payload()]
+        eq(filenames, ['msg.txt', 'msg.txt'])
+
+        msg = self._msgobj('msg_07.txt')
+        subpart = msg.get_payload(1)
+        eq(subpart.get_filename(), 'dingusfish.gif')
+
+    def test_get_filename_with_name_parameter(self):
+        eq = self.assertEqual
+
+        msg = self._msgobj('msg_44.txt')
+        filenames = [p.get_filename() for p in msg.get_payload()]
+        eq(filenames, ['msg.txt', 'msg.txt'])
+
+    def test_get_boundary(self):
+        eq = self.assertEqual
+        msg = self._msgobj('msg_07.txt')
+        # No quotes!
+        eq(msg.get_boundary(), 'BOUNDARY')
+
+    def test_set_boundary(self):
+        eq = self.assertEqual
+        # This one has no existing boundary parameter, but the Content-Type:
+        # header appears fifth.
+        msg = self._msgobj('msg_01.txt')
+        msg.set_boundary('BOUNDARY')
+        header, value = msg.items()[4]
+        eq(header.lower(), 'content-type')
+        eq(value, 'text/plain; charset="us-ascii"; boundary="BOUNDARY"')
+        # This one has a Content-Type: header, with a boundary, stuck in the
+        # middle of its headers.  Make sure the order is preserved; it should
+        # be fifth.
+        msg = self._msgobj('msg_04.txt')
+        msg.set_boundary('BOUNDARY')
+        header, value = msg.items()[4]
+        eq(header.lower(), 'content-type')
+        eq(value, 'multipart/mixed; boundary="BOUNDARY"')
+        # And this one has no Content-Type: header at all.
+        msg = self._msgobj('msg_03.txt')
+        self.assertRaises(Errors.HeaderParseError,
+                          msg.set_boundary, 'BOUNDARY')
+
+    def test_get_decoded_payload(self):
+        eq = self.assertEqual
+        msg = self._msgobj('msg_10.txt')
+        # The outer message is a multipart
+        eq(msg.get_payload(decode=True), None)
+        # Subpart 1 is 7bit encoded
+        eq(msg.get_payload(0).get_payload(decode=True),
+           'This is a 7bit encoded message.\n')
+        # Subpart 2 is quopri
+        eq(msg.get_payload(1).get_payload(decode=True),
+           '\xa1This is a Quoted Printable encoded message!\n')
+        # Subpart 3 is base64
+        eq(msg.get_payload(2).get_payload(decode=True),
+           'This is a Base64 encoded message.')
+        # Subpart 4 has no Content-Transfer-Encoding: header.
+        eq(msg.get_payload(3).get_payload(decode=True),
+           'This has no Content-Transfer-Encoding: header.\n')
+
+    def test_get_decoded_uu_payload(self):
+        eq = self.assertEqual
+        msg = Message()
+        msg.set_payload('begin 666 -\n+:&5L;&\\@=V]R;&0 \n \nend\n')
+        for cte in ('x-uuencode', 'uuencode', 'uue', 'x-uue'):
+            msg['content-transfer-encoding'] = cte
+            eq(msg.get_payload(decode=True), 'hello world')
+        # Now try some bogus data
+        msg.set_payload('foo')
+        eq(msg.get_payload(decode=True), 'foo')
+
+    def test_decode_bogus_uu_payload_quietly(self):
+        msg = Message()
+        msg.set_payload('begin 664 foo.txt\n%<W1F=0000H \n \nend\n')
+        msg['Content-Transfer-Encoding'] = 'x-uuencode'
+        old_stderr = sys.stderr
+        try:
+            sys.stderr = sfp = StringIO()
+            # We don't care about the payload
+            msg.get_payload(decode=True)
+        finally:
+            sys.stderr = old_stderr
+        self.assertEqual(sfp.getvalue(), '')
+
+    def test_decoded_generator(self):
+        eq = self.assertEqual
+        msg = self._msgobj('msg_07.txt')
+        fp = openfile('msg_17.txt')
+        try:
+            text = fp.read()
+        finally:
+            fp.close()
+        s = StringIO()
+        g = DecodedGenerator(s)
+        g.flatten(msg)
+        eq(s.getvalue(), text)
+
+    def test__contains__(self):
+        msg = Message()
+        msg['From'] = 'Me'
+        msg['to'] = 'You'
+        # Check for case insensitivity
+        self.failUnless('from' in msg)
+        self.failUnless('From' in msg)
+        self.failUnless('FROM' in msg)
+        self.failUnless('to' in msg)
+        self.failUnless('To' in msg)
+        self.failUnless('TO' in msg)
+
+    def test_as_string(self):
+        eq = self.assertEqual
+        msg = self._msgobj('msg_01.txt')
+        fp = openfile('msg_01.txt')
+        try:
+            text = fp.read()
+        finally:
+            fp.close()
+        eq(text, msg.as_string())
+        fullrepr = str(msg)
+        lines = fullrepr.split('\n')
+        self.failUnless(lines[0].startswith('From '))
+        eq(text, NL.join(lines[1:]))
+
+    def test_bad_param(self):
+        msg = email.message_from_string("Content-Type: blarg; baz; boo\n")
+        self.assertEqual(msg.get_param('baz'), '')
+
+    def test_missing_filename(self):
+        msg = email.message_from_string("From: foo\n")
+        self.assertEqual(msg.get_filename(), None)
+
+    def test_bogus_filename(self):
+        msg = email.message_from_string(
+        "Content-Disposition: blarg; filename\n")
+        self.assertEqual(msg.get_filename(), '')
+
+    def test_missing_boundary(self):
+        msg = email.message_from_string("From: foo\n")
+        self.assertEqual(msg.get_boundary(), None)
+
+    def test_get_params(self):
+        eq = self.assertEqual
+        msg = email.message_from_string(
+            'X-Header: foo=one; bar=two; baz=three\n')
+        eq(msg.get_params(header='x-header'),
+           [('foo', 'one'), ('bar', 'two'), ('baz', 'three')])
+        msg = email.message_from_string(
+            'X-Header: foo; bar=one; baz=two\n')
+        eq(msg.get_params(header='x-header'),
+           [('foo', ''), ('bar', 'one'), ('baz', 'two')])
+        eq(msg.get_params(), None)
+        msg = email.message_from_string(
+            'X-Header: foo; bar="one"; baz=two\n')
+        eq(msg.get_params(header='x-header'),
+           [('foo', ''), ('bar', 'one'), ('baz', 'two')])
+
+    def test_get_param_liberal(self):
+        msg = Message()
+        msg['Content-Type'] = 'Content-Type: Multipart/mixed; boundary = "CPIMSSMTPC06p5f3tG"'
+        self.assertEqual(msg.get_param('boundary'), 'CPIMSSMTPC06p5f3tG')
+
+    def test_get_param(self):
+        eq = self.assertEqual
+        msg = email.message_from_string(
+            "X-Header: foo=one; bar=two; baz=three\n")
+        eq(msg.get_param('bar', header='x-header'), 'two')
+        eq(msg.get_param('quuz', header='x-header'), None)
+        eq(msg.get_param('quuz'), None)
+        msg = email.message_from_string(
+            'X-Header: foo; bar="one"; baz=two\n')
+        eq(msg.get_param('foo', header='x-header'), '')
+        eq(msg.get_param('bar', header='x-header'), 'one')
+        eq(msg.get_param('baz', header='x-header'), 'two')
+        # XXX: We are not RFC-2045 compliant!  We cannot parse:
+        # msg["Content-Type"] = 'text/plain; weird="hey; dolly? [you] @ <\\"home\\">?"'
+        # msg.get_param("weird")
+        # yet.
+
+    def test_get_param_funky_continuation_lines(self):
+        msg = self._msgobj('msg_22.txt')
+        self.assertEqual(msg.get_payload(1).get_param('name'), 'wibble.JPG')
+
+    def test_get_param_with_semis_in_quotes(self):
+        msg = email.message_from_string(
+            'Content-Type: image/pjpeg; name="Jim&amp;&amp;Jill"\n')
+        self.assertEqual(msg.get_param('name'), 'Jim&amp;&amp;Jill')
+        self.assertEqual(msg.get_param('name', unquote=False),
+                         '"Jim&amp;&amp;Jill"')
+
+    def test_has_key(self):
+        msg = email.message_from_string('Header: exists')
+        self.failUnless(msg.has_key('header'))
+        self.failUnless(msg.has_key('Header'))
+        self.failUnless(msg.has_key('HEADER'))
+        self.failIf(msg.has_key('headeri'))
+
+    def test_set_param(self):
+        eq = self.assertEqual
+        msg = Message()
+        msg.set_param('charset', 'iso-2022-jp')
+        eq(msg.get_param('charset'), 'iso-2022-jp')
+        msg.set_param('importance', 'high value')
+        eq(msg.get_param('importance'), 'high value')
+        eq(msg.get_param('importance', unquote=False), '"high value"')
+        eq(msg.get_params(), [('text/plain', ''),
+                              ('charset', 'iso-2022-jp'),
+                              ('importance', 'high value')])
+        eq(msg.get_params(unquote=False), [('text/plain', ''),
+                                       ('charset', '"iso-2022-jp"'),
+                                       ('importance', '"high value"')])
+        msg.set_param('charset', 'iso-9999-xx', header='X-Jimmy')
+        eq(msg.get_param('charset', header='X-Jimmy'), 'iso-9999-xx')
+
+    def test_del_param(self):
+        eq = self.assertEqual
+        msg = self._msgobj('msg_05.txt')
+        eq(msg.get_params(),
+           [('multipart/report', ''), ('report-type', 'delivery-status'),
+            ('boundary', 'D1690A7AC1.996856090/mail.example.com')])
+        old_val = msg.get_param("report-type")
+        msg.del_param("report-type")
+        eq(msg.get_params(),
+           [('multipart/report', ''),
+            ('boundary', 'D1690A7AC1.996856090/mail.example.com')])
+        msg.set_param("report-type", old_val)
+        eq(msg.get_params(),
+           [('multipart/report', ''),
+            ('boundary', 'D1690A7AC1.996856090/mail.example.com'),
+            ('report-type', old_val)])
+
+    def test_del_param_on_other_header(self):
+        msg = Message()
+        msg.add_header('Content-Disposition', 'attachment', filename='bud.gif')
+        msg.del_param('filename', 'content-disposition')
+        self.assertEqual(msg['content-disposition'], 'attachment')
+
+    def test_set_type(self):
+        eq = self.assertEqual
+        msg = Message()
+        self.assertRaises(ValueError, msg.set_type, 'text')
+        msg.set_type('text/plain')
+        eq(msg['content-type'], 'text/plain')
+        msg.set_param('charset', 'us-ascii')
+        eq(msg['content-type'], 'text/plain; charset="us-ascii"')
+        msg.set_type('text/html')
+        eq(msg['content-type'], 'text/html; charset="us-ascii"')
+
+    def test_set_type_on_other_header(self):
+        msg = Message()
+        msg['X-Content-Type'] = 'text/plain'
+        msg.set_type('application/octet-stream', 'X-Content-Type')
+        self.assertEqual(msg['x-content-type'], 'application/octet-stream')
+
+    def test_get_content_type_missing(self):
+        msg = Message()
+        self.assertEqual(msg.get_content_type(), 'text/plain')
+
+    def test_get_content_type_missing_with_default_type(self):
+        msg = Message()
+        msg.set_default_type('message/rfc822')
+        self.assertEqual(msg.get_content_type(), 'message/rfc822')
+
+    def test_get_content_type_from_message_implicit(self):
+        msg = self._msgobj('msg_30.txt')
+        self.assertEqual(msg.get_payload(0).get_content_type(),
+                         'message/rfc822')
+
+    def test_get_content_type_from_message_explicit(self):
+        msg = self._msgobj('msg_28.txt')
+        self.assertEqual(msg.get_payload(0).get_content_type(),
+                         'message/rfc822')
+
+    def test_get_content_type_from_message_text_plain_implicit(self):
+        msg = self._msgobj('msg_03.txt')
+        self.assertEqual(msg.get_content_type(), 'text/plain')
+
+    def test_get_content_type_from_message_text_plain_explicit(self):
+        msg = self._msgobj('msg_01.txt')
+        self.assertEqual(msg.get_content_type(), 'text/plain')
+
+    def test_get_content_maintype_missing(self):
+        msg = Message()
+        self.assertEqual(msg.get_content_maintype(), 'text')
+
+    def test_get_content_maintype_missing_with_default_type(self):
+        msg = Message()
+        msg.set_default_type('message/rfc822')
+        self.assertEqual(msg.get_content_maintype(), 'message')
+
+    def test_get_content_maintype_from_message_implicit(self):
+        msg = self._msgobj('msg_30.txt')
+        self.assertEqual(msg.get_payload(0).get_content_maintype(), 'message')
+
+    def test_get_content_maintype_from_message_explicit(self):
+        msg = self._msgobj('msg_28.txt')
+        self.assertEqual(msg.get_payload(0).get_content_maintype(), 'message')
+
+    def test_get_content_maintype_from_message_text_plain_implicit(self):
+        msg = self._msgobj('msg_03.txt')
+        self.assertEqual(msg.get_content_maintype(), 'text')
+
+    def test_get_content_maintype_from_message_text_plain_explicit(self):
+        msg = self._msgobj('msg_01.txt')
+        self.assertEqual(msg.get_content_maintype(), 'text')
+
+    def test_get_content_subtype_missing(self):
+        msg = Message()
+        self.assertEqual(msg.get_content_subtype(), 'plain')
+
+    def test_get_content_subtype_missing_with_default_type(self):
+        msg = Message()
+        msg.set_default_type('message/rfc822')
+        self.assertEqual(msg.get_content_subtype(), 'rfc822')
+
+    def test_get_content_subtype_from_message_implicit(self):
+        msg = self._msgobj('msg_30.txt')
+        self.assertEqual(msg.get_payload(0).get_content_subtype(), 'rfc822')
+
+    def test_get_content_subtype_from_message_explicit(self):
+        msg = self._msgobj('msg_28.txt')
+        self.assertEqual(msg.get_payload(0).get_content_subtype(), 'rfc822')
+
+    def test_get_content_subtype_from_message_text_plain_implicit(self):
+        msg = self._msgobj('msg_03.txt')
+        self.assertEqual(msg.get_content_subtype(), 'plain')
+
+    def test_get_content_subtype_from_message_text_plain_explicit(self):
+        msg = self._msgobj('msg_01.txt')
+        self.assertEqual(msg.get_content_subtype(), 'plain')
+
+    def test_get_content_maintype_error(self):
+        msg = Message()
+        msg['Content-Type'] = 'no-slash-in-this-string'
+        self.assertEqual(msg.get_content_maintype(), 'text')
+
+    def test_get_content_subtype_error(self):
+        msg = Message()
+        msg['Content-Type'] = 'no-slash-in-this-string'
+        self.assertEqual(msg.get_content_subtype(), 'plain')
+
+    def test_replace_header(self):
+        eq = self.assertEqual
+        msg = Message()
+        msg.add_header('First', 'One')
+        msg.add_header('Second', 'Two')
+        msg.add_header('Third', 'Three')
+        eq(msg.keys(), ['First', 'Second', 'Third'])
+        eq(msg.values(), ['One', 'Two', 'Three'])
+        msg.replace_header('Second', 'Twenty')
+        eq(msg.keys(), ['First', 'Second', 'Third'])
+        eq(msg.values(), ['One', 'Twenty', 'Three'])
+        msg.add_header('First', 'Eleven')
+        msg.replace_header('First', 'One Hundred')
+        eq(msg.keys(), ['First', 'Second', 'Third', 'First'])
+        eq(msg.values(), ['One Hundred', 'Twenty', 'Three', 'Eleven'])
+        self.assertRaises(KeyError, msg.replace_header, 'Fourth', 'Missing')
+
+    def test_broken_base64_payload(self):
+        x = 'AwDp0P7//y6LwKEAcPa/6Q=9'
+        msg = Message()
+        msg['content-type'] = 'audio/x-midi'
+        msg['content-transfer-encoding'] = 'base64'
+        msg.set_payload(x)
+        self.assertEqual(msg.get_payload(decode=True), x)
+
+    def test_get_content_charset(self):
+        msg = Message()
+        msg.set_charset('us-ascii')
+        self.assertEqual('us-ascii', msg.get_content_charset())
+        msg.set_charset(u'us-ascii')
+        self.assertEqual('us-ascii', msg.get_content_charset())
+
+
+
+# Test the email.Encoders module
+class TestEncoders(unittest.TestCase):
+    def test_encode_empty_payload(self):
+        eq = self.assertEqual
+        msg = Message()
+        msg.set_charset('us-ascii')
+        eq(msg['content-transfer-encoding'], '7bit')
+
+    def test_default_cte(self):
+        eq = self.assertEqual
+        msg = MIMEText('hello world')
+        eq(msg['content-transfer-encoding'], '7bit')
+
+    def test_default_cte(self):
+        eq = self.assertEqual
+        # With no explicit _charset its us-ascii, and all are 7-bit
+        msg = MIMEText('hello world')
+        eq(msg['content-transfer-encoding'], '7bit')
+        # Similar, but with 8-bit data
+        msg = MIMEText('hello \xf8 world')
+        eq(msg['content-transfer-encoding'], '8bit')
+        # And now with a different charset
+        msg = MIMEText('hello \xf8 world', _charset='iso-8859-1')
+        eq(msg['content-transfer-encoding'], 'quoted-printable')
+
+
+
+# Test long header wrapping
+class TestLongHeaders(TestEmailBase):
+    def test_split_long_continuation(self):
+        eq = self.ndiffAssertEqual
+        msg = email.message_from_string("""\
+Subject: bug demonstration
+\t12345678911234567892123456789312345678941234567895123456789612345678971234567898112345678911234567892123456789112345678911234567892123456789
+\tmore text
+
+test
+""")
+        sfp = StringIO()
+        g = Generator(sfp)
+        g.flatten(msg)
+        eq(sfp.getvalue(), """\
+Subject: bug demonstration
+\t12345678911234567892123456789312345678941234567895123456789612345678971234567898112345678911234567892123456789112345678911234567892123456789
+\tmore text
+
+test
+""")
+
+    def test_another_long_almost_unsplittable_header(self):
+        eq = self.ndiffAssertEqual
+        hstr = """\
+bug demonstration
+\t12345678911234567892123456789312345678941234567895123456789612345678971234567898112345678911234567892123456789112345678911234567892123456789
+\tmore text"""
+        h = Header(hstr, continuation_ws='\t')
+        eq(h.encode(), """\
+bug demonstration
+\t12345678911234567892123456789312345678941234567895123456789612345678971234567898112345678911234567892123456789112345678911234567892123456789
+\tmore text""")
+        h = Header(hstr)
+        eq(h.encode(), """\
+bug demonstration
+ 12345678911234567892123456789312345678941234567895123456789612345678971234567898112345678911234567892123456789112345678911234567892123456789
+ more text""")
+
+    def test_long_nonstring(self):
+        eq = self.ndiffAssertEqual
+        g = Charset("iso-8859-1")
+        cz = Charset("iso-8859-2")
+        utf8 = Charset("utf-8")
+        g_head = "Die Mieter treten hier ein werden mit einem Foerderband komfortabel den Korridor entlang, an s\xfcdl\xfcndischen Wandgem\xe4lden vorbei, gegen die rotierenden Klingen bef\xf6rdert. "
+        cz_head = "Finan\xe8ni metropole se hroutily pod tlakem jejich d\xf9vtipu.. "
+        utf8_head = u"\u6b63\u78ba\u306b\u8a00\u3046\u3068\u7ffb\u8a33\u306f\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002\u4e00\u90e8\u306f\u30c9\u30a4\u30c4\u8a9e\u3067\u3059\u304c\u3001\u3042\u3068\u306f\u3067\u305f\u3089\u3081\u3067\u3059\u3002\u5b9f\u969b\u306b\u306f\u300cWenn ist das Nunstuck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput.\u300d\u3068\u8a00\u3063\u3066\u3044\u307e\u3059\u3002".encode("utf-8")
+        h = Header(g_head, g, header_name='Subject')
+        h.append(cz_head, cz)
+        h.append(utf8_head, utf8)
+        msg = Message()
+        msg['Subject'] = h
+        sfp = StringIO()
+        g = Generator(sfp)
+        g.flatten(msg)
+        eq(sfp.getvalue(), """\
+Subject: =?iso-8859-1?q?Die_Mieter_treten_hier_ein_werden_mit_einem_Foerd?=
+ =?iso-8859-1?q?erband_komfortabel_den_Korridor_entlang=2C_an_s=FCdl=FCndi?=
+ =?iso-8859-1?q?schen_Wandgem=E4lden_vorbei=2C_gegen_die_rotierenden_Kling?=
+ =?iso-8859-1?q?en_bef=F6rdert=2E_?= =?iso-8859-2?q?Finan=E8ni_met?=
+ =?iso-8859-2?q?ropole_se_hroutily_pod_tlakem_jejich_d=F9vtipu=2E=2E_?=
+ =?utf-8?b?5q2j56K644Gr6KiA44GG44Go57+76Kiz44Gv44GV44KM44Gm44GE?=
+ =?utf-8?b?44G+44Gb44KT44CC5LiA6YOo44Gv44OJ44Kk44OE6Kqe44Gn44GZ44GM44CB?=
+ =?utf-8?b?44GC44Go44Gv44Gn44Gf44KJ44KB44Gn44GZ44CC5a6f6Zqb44Gr44Gv44CM?=
+ =?utf-8?q?Wenn_ist_das_Nunstuck_git_und_Slotermeyer=3F_Ja!_Beiherhund_das?=
+ =?utf-8?b?IE9kZXIgZGllIEZsaXBwZXJ3YWxkdCBnZXJzcHV0LuOAjeOBqOiogOOBow==?=
+ =?utf-8?b?44Gm44GE44G+44GZ44CC?=
+
+""")
+        eq(h.encode(), """\
+=?iso-8859-1?q?Die_Mieter_treten_hier_ein_werden_mit_einem_Foerd?=
+ =?iso-8859-1?q?erband_komfortabel_den_Korridor_entlang=2C_an_s=FCdl=FCndi?=
+ =?iso-8859-1?q?schen_Wandgem=E4lden_vorbei=2C_gegen_die_rotierenden_Kling?=
+ =?iso-8859-1?q?en_bef=F6rdert=2E_?= =?iso-8859-2?q?Finan=E8ni_met?=
+ =?iso-8859-2?q?ropole_se_hroutily_pod_tlakem_jejich_d=F9vtipu=2E=2E_?=
+ =?utf-8?b?5q2j56K644Gr6KiA44GG44Go57+76Kiz44Gv44GV44KM44Gm44GE?=
+ =?utf-8?b?44G+44Gb44KT44CC5LiA6YOo44Gv44OJ44Kk44OE6Kqe44Gn44GZ44GM44CB?=
+ =?utf-8?b?44GC44Go44Gv44Gn44Gf44KJ44KB44Gn44GZ44CC5a6f6Zqb44Gr44Gv44CM?=
+ =?utf-8?q?Wenn_ist_das_Nunstuck_git_und_Slotermeyer=3F_Ja!_Beiherhund_das?=
+ =?utf-8?b?IE9kZXIgZGllIEZsaXBwZXJ3YWxkdCBnZXJzcHV0LuOAjeOBqOiogOOBow==?=
+ =?utf-8?b?44Gm44GE44G+44GZ44CC?=""")
+
+    def test_long_header_encode(self):
+        eq = self.ndiffAssertEqual
+        h = Header('wasnipoop; giraffes="very-long-necked-animals"; '
+                   'spooge="yummy"; hippos="gargantuan"; marshmallows="gooey"',
+                   header_name='X-Foobar-Spoink-Defrobnit')
+        eq(h.encode(), '''\
+wasnipoop; giraffes="very-long-necked-animals";
+ spooge="yummy"; hippos="gargantuan"; marshmallows="gooey"''')
+
+    def test_long_header_encode_with_tab_continuation(self):
+        eq = self.ndiffAssertEqual
+        h = Header('wasnipoop; giraffes="very-long-necked-animals"; '
+                   'spooge="yummy"; hippos="gargantuan"; marshmallows="gooey"',
+                   header_name='X-Foobar-Spoink-Defrobnit',
+                   continuation_ws='\t')
+        eq(h.encode(), '''\
+wasnipoop; giraffes="very-long-necked-animals";
+\tspooge="yummy"; hippos="gargantuan"; marshmallows="gooey"''')
+
+    def test_header_splitter(self):
+        eq = self.ndiffAssertEqual
+        msg = MIMEText('')
+        # It'd be great if we could use add_header() here, but that doesn't
+        # guarantee an order of the parameters.
+        msg['X-Foobar-Spoink-Defrobnit'] = (
+            'wasnipoop; giraffes="very-long-necked-animals"; '
+            'spooge="yummy"; hippos="gargantuan"; marshmallows="gooey"')
+        sfp = StringIO()
+        g = Generator(sfp)
+        g.flatten(msg)
+        eq(sfp.getvalue(), '''\
+Content-Type: text/plain; charset="us-ascii"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Foobar-Spoink-Defrobnit: wasnipoop; giraffes="very-long-necked-animals";
+\tspooge="yummy"; hippos="gargantuan"; marshmallows="gooey"
+
+''')
+
+    def test_no_semis_header_splitter(self):
+        eq = self.ndiffAssertEqual
+        msg = Message()
+        msg['From'] = 'test at dom.ain'
+        msg['References'] = SPACE.join(['<%d at dom.ain>' % i for i in range(10)])
+        msg.set_payload('Test')
+        sfp = StringIO()
+        g = Generator(sfp)
+        g.flatten(msg)
+        eq(sfp.getvalue(), """\
+From: test at dom.ain
+References: <0 at dom.ain> <1 at dom.ain> <2 at dom.ain> <3 at dom.ain> <4 at dom.ain>
+\t<5 at dom.ain> <6 at dom.ain> <7 at dom.ain> <8 at dom.ain> <9 at dom.ain>
+
+Test""")
+
+    def test_no_split_long_header(self):
+        eq = self.ndiffAssertEqual
+        hstr = 'References: ' + 'x' * 80
+        h = Header(hstr, continuation_ws='\t')
+        eq(h.encode(), """\
+References: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx""")
+
+    def test_splitting_multiple_long_lines(self):
+        eq = self.ndiffAssertEqual
+        hstr = """\
+from babylon.socal-raves.org (localhost [127.0.0.1]); by babylon.socal-raves.org (Postfix) with ESMTP id B570E51B81; for <mailman-admin at babylon.socal-raves.org>; Sat, 2 Feb 2002 17:00:06 -0800 (PST)
+\tfrom babylon.socal-raves.org (localhost [127.0.0.1]); by babylon.socal-raves.org (Postfix) with ESMTP id B570E51B81; for <mailman-admin at babylon.socal-raves.org>; Sat, 2 Feb 2002 17:00:06 -0800 (PST)
+\tfrom babylon.socal-raves.org (localhost [127.0.0.1]); by babylon.socal-raves.org (Postfix) with ESMTP id B570E51B81; for <mailman-admin at babylon.socal-raves.org>; Sat, 2 Feb 2002 17:00:06 -0800 (PST)
+"""
+        h = Header(hstr, continuation_ws='\t')
+        eq(h.encode(), """\
+from babylon.socal-raves.org (localhost [127.0.0.1]);
+\tby babylon.socal-raves.org (Postfix) with ESMTP id B570E51B81;
+\tfor <mailman-admin at babylon.socal-raves.org>;
+\tSat, 2 Feb 2002 17:00:06 -0800 (PST)
+\tfrom babylon.socal-raves.org (localhost [127.0.0.1]);
+\tby babylon.socal-raves.org (Postfix) with ESMTP id B570E51B81;
+\tfor <mailman-admin at babylon.socal-raves.org>;
+\tSat, 2 Feb 2002 17:00:06 -0800 (PST)
+\tfrom babylon.socal-raves.org (localhost [127.0.0.1]);
+\tby babylon.socal-raves.org (Postfix) with ESMTP id B570E51B81;
+\tfor <mailman-admin at babylon.socal-raves.org>;
+\tSat, 2 Feb 2002 17:00:06 -0800 (PST)""")
+
+    def test_splitting_first_line_only_is_long(self):
+        eq = self.ndiffAssertEqual
+        hstr = """\
+from modemcable093.139-201-24.que.mc.videotron.ca ([24.201.139.93] helo=cthulhu.gerg.ca)
+\tby kronos.mems-exchange.org with esmtp (Exim 4.05)
+\tid 17k4h5-00034i-00
+\tfor test at mems-exchange.org; Wed, 28 Aug 2002 11:25:20 -0400"""
+        h = Header(hstr, maxlinelen=78, header_name='Received',
+                   continuation_ws='\t')
+        eq(h.encode(), """\
+from modemcable093.139-201-24.que.mc.videotron.ca ([24.201.139.93]
+\thelo=cthulhu.gerg.ca)
+\tby kronos.mems-exchange.org with esmtp (Exim 4.05)
+\tid 17k4h5-00034i-00
+\tfor test at mems-exchange.org; Wed, 28 Aug 2002 11:25:20 -0400""")
+
+    def test_long_8bit_header(self):
+        eq = self.ndiffAssertEqual
+        msg = Message()
+        h = Header('Britische Regierung gibt', 'iso-8859-1',
+                    header_name='Subject')
+        h.append('gr\xfcnes Licht f\xfcr Offshore-Windkraftprojekte')
+        msg['Subject'] = h
+        eq(msg.as_string(), """\
+Subject: =?iso-8859-1?q?Britische_Regierung_gibt?= =?iso-8859-1?q?gr=FCnes?=
+ =?iso-8859-1?q?_Licht_f=FCr_Offshore-Windkraftprojekte?=
+
+""")
+
+    def test_long_8bit_header_no_charset(self):
+        eq = self.ndiffAssertEqual
+        msg = Message()
+        msg['Reply-To'] = 'Britische Regierung gibt gr\xfcnes Licht f\xfcr Offshore-Windkraftprojekte <a-very-long-address at example.com>'
+        eq(msg.as_string(), """\
+Reply-To: Britische Regierung gibt gr\xfcnes Licht f\xfcr Offshore-Windkraftprojekte <a-very-long-address at example.com>
+
+""")
+
+    def test_long_to_header(self):
+        eq = self.ndiffAssertEqual
+        to = '"Someone Test #A" <someone at eecs.umich.edu>,<someone at eecs.umich.edu>,"Someone Test #B" <someone at umich.edu>, "Someone Test #C" <someone at eecs.umich.edu>, "Someone Test #D" <someone at eecs.umich.edu>'
+        msg = Message()
+        msg['To'] = to
+        eq(msg.as_string(0), '''\
+To: "Someone Test #A" <someone at eecs.umich.edu>, <someone at eecs.umich.edu>,
+\t"Someone Test #B" <someone at umich.edu>,
+\t"Someone Test #C" <someone at eecs.umich.edu>,
+\t"Someone Test #D" <someone at eecs.umich.edu>
+
+''')
+
+    def test_long_line_after_append(self):
+        eq = self.ndiffAssertEqual
+        s = 'This is an example of string which has almost the limit of header length.'
+        h = Header(s)
+        h.append('Add another line.')
+        eq(h.encode(), """\
+This is an example of string which has almost the limit of header length.
+ Add another line.""")
+
+    def test_shorter_line_with_append(self):
+        eq = self.ndiffAssertEqual
+        s = 'This is a shorter line.'
+        h = Header(s)
+        h.append('Add another sentence. (Surprise?)')
+        eq(h.encode(),
+           'This is a shorter line. Add another sentence. (Surprise?)')
+
+    def test_long_field_name(self):
+        eq = self.ndiffAssertEqual
+        fn = 'X-Very-Very-Very-Long-Header-Name'
+        gs = "Die Mieter treten hier ein werden mit einem Foerderband komfortabel den Korridor entlang, an s\xfcdl\xfcndischen Wandgem\xe4lden vorbei, gegen die rotierenden Klingen bef\xf6rdert. "
+        h = Header(gs, 'iso-8859-1', header_name=fn)
+        # BAW: this seems broken because the first line is too long
+        eq(h.encode(), """\
+=?iso-8859-1?q?Die_Mieter_treten_hier_?=
+ =?iso-8859-1?q?ein_werden_mit_einem_Foerderband_komfortabel_den_Korridor_?=
+ =?iso-8859-1?q?entlang=2C_an_s=FCdl=FCndischen_Wandgem=E4lden_vorbei=2C_g?=
+ =?iso-8859-1?q?egen_die_rotierenden_Klingen_bef=F6rdert=2E_?=""")
+
+    def test_long_received_header(self):
+        h = 'from FOO.TLD (vizworld.acl.foo.tld [123.452.678.9]) by hrothgar.la.mastaler.com (tmda-ofmipd) with ESMTP; Wed, 05 Mar 2003 18:10:18 -0700'
+        msg = Message()
+        msg['Received-1'] = Header(h, continuation_ws='\t')
+        msg['Received-2'] = h
+        self.assertEqual(msg.as_string(), """\
+Received-1: from FOO.TLD (vizworld.acl.foo.tld [123.452.678.9]) by
+\throthgar.la.mastaler.com (tmda-ofmipd) with ESMTP;
+\tWed, 05 Mar 2003 18:10:18 -0700
+Received-2: from FOO.TLD (vizworld.acl.foo.tld [123.452.678.9]) by
+\throthgar.la.mastaler.com (tmda-ofmipd) with ESMTP;
+\tWed, 05 Mar 2003 18:10:18 -0700
+
+""")
+
+    def test_string_headerinst_eq(self):
+        h = '<15975.17901.207240.414604 at sgigritzmann1.mathematik.tu-muenchen.de> (David Bremner\'s message of "Thu, 6 Mar 2003 13:58:21 +0100")'
+        msg = Message()
+        msg['Received-1'] = Header(h, header_name='Received-1',
+                                   continuation_ws='\t')
+        msg['Received-2'] = h
+        self.assertEqual(msg.as_string(), """\
+Received-1: <15975.17901.207240.414604 at sgigritzmann1.mathematik.tu-muenchen.de>
+\t(David Bremner's message of "Thu, 6 Mar 2003 13:58:21 +0100")
+Received-2: <15975.17901.207240.414604 at sgigritzmann1.mathematik.tu-muenchen.de>
+\t(David Bremner's message of "Thu, 6 Mar 2003 13:58:21 +0100")
+
+""")
+
+    def test_long_unbreakable_lines_with_continuation(self):
+        eq = self.ndiffAssertEqual
+        msg = Message()
+        t = """\
+ iVBORw0KGgoAAAANSUhEUgAAADAAAAAwBAMAAAClLOS0AAAAGFBMVEUAAAAkHiJeRUIcGBi9
+ locQDQ4zJykFBAXJfWDjAAACYUlEQVR4nF2TQY/jIAyFc6lydlG5x8Nyp1Y69wj1PN2I5gzp"""
+        msg['Face-1'] = t
+        msg['Face-2'] = Header(t, header_name='Face-2')
+        eq(msg.as_string(), """\
+Face-1: iVBORw0KGgoAAAANSUhEUgAAADAAAAAwBAMAAAClLOS0AAAAGFBMVEUAAAAkHiJeRUIcGBi9
+\tlocQDQ4zJykFBAXJfWDjAAACYUlEQVR4nF2TQY/jIAyFc6lydlG5x8Nyp1Y69wj1PN2I5gzp
+Face-2: iVBORw0KGgoAAAANSUhEUgAAADAAAAAwBAMAAAClLOS0AAAAGFBMVEUAAAAkHiJeRUIcGBi9
+ locQDQ4zJykFBAXJfWDjAAACYUlEQVR4nF2TQY/jIAyFc6lydlG5x8Nyp1Y69wj1PN2I5gzp
+
+""")
+
+    def test_another_long_multiline_header(self):
+        eq = self.ndiffAssertEqual
+        m = '''\
+Received: from siimage.com ([172.25.1.3]) by zima.siliconimage.com with Microsoft SMTPSVC(5.0.2195.4905);
+\tWed, 16 Oct 2002 07:41:11 -0700'''
+        msg = email.message_from_string(m)
+        eq(msg.as_string(), '''\
+Received: from siimage.com ([172.25.1.3]) by zima.siliconimage.com with
+\tMicrosoft SMTPSVC(5.0.2195.4905); Wed, 16 Oct 2002 07:41:11 -0700
+
+''')
+
+    def test_long_lines_with_different_header(self):
+        eq = self.ndiffAssertEqual
+        h = """\
+List-Unsubscribe: <https://lists.sourceforge.net/lists/listinfo/spamassassin-talk>,
+        <mailto:spamassassin-talk-request at lists.sourceforge.net?subject=unsubscribe>"""
+        msg = Message()
+        msg['List'] = h
+        msg['List'] = Header(h, header_name='List')
+        eq(msg.as_string(), """\
+List: List-Unsubscribe: <https://lists.sourceforge.net/lists/listinfo/spamassassin-talk>,
+\t<mailto:spamassassin-talk-request at lists.sourceforge.net?subject=unsubscribe>
+List: List-Unsubscribe: <https://lists.sourceforge.net/lists/listinfo/spamassassin-talk>,
+ <mailto:spamassassin-talk-request at lists.sourceforge.net?subject=unsubscribe>
+
+""")
+
+
+
+# Test mangling of "From " lines in the body of a message
+class TestFromMangling(unittest.TestCase):
+    def setUp(self):
+        self.msg = Message()
+        self.msg['From'] = 'aaa at bbb.org'
+        self.msg.set_payload("""\
+From the desk of A.A.A.:
+Blah blah blah
+""")
+
+    def test_mangled_from(self):
+        s = StringIO()
+        g = Generator(s, mangle_from_=True)
+        g.flatten(self.msg)
+        self.assertEqual(s.getvalue(), """\
+From: aaa at bbb.org
+
+>From the desk of A.A.A.:
+Blah blah blah
+""")
+
+    def test_dont_mangle_from(self):
+        s = StringIO()
+        g = Generator(s, mangle_from_=False)
+        g.flatten(self.msg)
+        self.assertEqual(s.getvalue(), """\
+From: aaa at bbb.org
+
+From the desk of A.A.A.:
+Blah blah blah
+""")
+
+
+
+# Test the basic MIMEAudio class
+class TestMIMEAudio(unittest.TestCase):
+    def setUp(self):
+        # Make sure we pick up the audiotest.au that lives in email/test/data.
+        # In Python, there's an audiotest.au living in Lib/test but that isn't
+        # included in some binary distros that don't include the test
+        # package.  The trailing empty string on the .join() is significant
+        # since findfile() will do a dirname().
+        datadir = os.path.join(os.path.dirname(landmark), 'data', '')
+        fp = open(findfile('audiotest.au', datadir), 'rb')
+        try:
+            self._audiodata = fp.read()
+        finally:
+            fp.close()
+        self._au = MIMEAudio(self._audiodata)
+
+    def test_guess_minor_type(self):
+        self.assertEqual(self._au.get_content_type(), 'audio/basic')
+
+    def test_encoding(self):
+        payload = self._au.get_payload()
+        self.assertEqual(base64.decodestring(payload), self._audiodata)
+
+    def test_checkSetMinor(self):
+        au = MIMEAudio(self._audiodata, 'fish')
+        self.assertEqual(au.get_content_type(), 'audio/fish')
+
+    def test_add_header(self):
+        eq = self.assertEqual
+        unless = self.failUnless
+        self._au.add_header('Content-Disposition', 'attachment',
+                            filename='audiotest.au')
+        eq(self._au['content-disposition'],
+           'attachment; filename="audiotest.au"')
+        eq(self._au.get_params(header='content-disposition'),
+           [('attachment', ''), ('filename', 'audiotest.au')])
+        eq(self._au.get_param('filename', header='content-disposition'),
+           'audiotest.au')
+        missing = []
+        eq(self._au.get_param('attachment', header='content-disposition'), '')
+        unless(self._au.get_param('foo', failobj=missing,
+                                  header='content-disposition') is missing)
+        # Try some missing stuff
+        unless(self._au.get_param('foobar', missing) is missing)
+        unless(self._au.get_param('attachment', missing,
+                                  header='foobar') is missing)
+
+
+
+# Test the basic MIMEImage class
+class TestMIMEImage(unittest.TestCase):
+    def setUp(self):
+        fp = openfile('PyBanner048.gif')
+        try:
+            self._imgdata = fp.read()
+        finally:
+            fp.close()
+        self._im = MIMEImage(self._imgdata)
+
+    def test_guess_minor_type(self):
+        self.assertEqual(self._im.get_content_type(), 'image/gif')
+
+    def test_encoding(self):
+        payload = self._im.get_payload()
+        self.assertEqual(base64.decodestring(payload), self._imgdata)
+
+    def test_checkSetMinor(self):
+        im = MIMEImage(self._imgdata, 'fish')
+        self.assertEqual(im.get_content_type(), 'image/fish')
+
+    def test_add_header(self):
+        eq = self.assertEqual
+        unless = self.failUnless
+        self._im.add_header('Content-Disposition', 'attachment',
+                            filename='dingusfish.gif')
+        eq(self._im['content-disposition'],
+           'attachment; filename="dingusfish.gif"')
+        eq(self._im.get_params(header='content-disposition'),
+           [('attachment', ''), ('filename', 'dingusfish.gif')])
+        eq(self._im.get_param('filename', header='content-disposition'),
+           'dingusfish.gif')
+        missing = []
+        eq(self._im.get_param('attachment', header='content-disposition'), '')
+        unless(self._im.get_param('foo', failobj=missing,
+                                  header='content-disposition') is missing)
+        # Try some missing stuff
+        unless(self._im.get_param('foobar', missing) is missing)
+        unless(self._im.get_param('attachment', missing,
+                                  header='foobar') is missing)
+
+
+
+# Test the basic MIMEText class
+class TestMIMEText(unittest.TestCase):
+    def setUp(self):
+        self._msg = MIMEText('hello there')
+
+    def test_types(self):
+        eq = self.assertEqual
+        unless = self.failUnless
+        eq(self._msg.get_content_type(), 'text/plain')
+        eq(self._msg.get_param('charset'), 'us-ascii')
+        missing = []
+        unless(self._msg.get_param('foobar', missing) is missing)
+        unless(self._msg.get_param('charset', missing, header='foobar')
+               is missing)
+
+    def test_payload(self):
+        self.assertEqual(self._msg.get_payload(), 'hello there')
+        self.failUnless(not self._msg.is_multipart())
+
+    def test_charset(self):
+        eq = self.assertEqual
+        msg = MIMEText('hello there', _charset='us-ascii')
+        eq(msg.get_charset().input_charset, 'us-ascii')
+        eq(msg['content-type'], 'text/plain; charset="us-ascii"')
+
+
+
+# Test complicated multipart/* messages
+class TestMultipart(TestEmailBase):
+    def setUp(self):
+        fp = openfile('PyBanner048.gif')
+        try:
+            data = fp.read()
+        finally:
+            fp.close()
+
+        container = MIMEBase('multipart', 'mixed', boundary='BOUNDARY')
+        image = MIMEImage(data, name='dingusfish.gif')
+        image.add_header('content-disposition', 'attachment',
+                         filename='dingusfish.gif')
+        intro = MIMEText('''\
+Hi there,
+
+This is the dingus fish.
+''')
+        container.attach(intro)
+        container.attach(image)
+        container['From'] = 'Barry <barry at digicool.com>'
+        container['To'] = 'Dingus Lovers <cravindogs at cravindogs.com>'
+        container['Subject'] = 'Here is your dingus fish'
+
+        now = 987809702.54848599
+        timetuple = time.localtime(now)
+        if timetuple[-1] == 0:
+            tzsecs = time.timezone
+        else:
+            tzsecs = time.altzone
+        if tzsecs > 0:
+            sign = '-'
+        else:
+            sign = '+'
+        tzoffset = ' %s%04d' % (sign, tzsecs / 36)
+        container['Date'] = time.strftime(
+            '%a, %d %b %Y %H:%M:%S',
+            time.localtime(now)) + tzoffset
+        self._msg = container
+        self._im = image
+        self._txt = intro
+
+    def test_hierarchy(self):
+        # convenience
+        eq = self.assertEqual
+        unless = self.failUnless
+        raises = self.assertRaises
+        # tests
+        m = self._msg
+        unless(m.is_multipart())
+        eq(m.get_content_type(), 'multipart/mixed')
+        eq(len(m.get_payload()), 2)
+        raises(IndexError, m.get_payload, 2)
+        m0 = m.get_payload(0)
+        m1 = m.get_payload(1)
+        unless(m0 is self._txt)
+        unless(m1 is self._im)
+        eq(m.get_payload(), [m0, m1])
+        unless(not m0.is_multipart())
+        unless(not m1.is_multipart())
+
+    def test_empty_multipart_idempotent(self):
+        text = """\
+Content-Type: multipart/mixed; boundary="BOUNDARY"
+MIME-Version: 1.0
+Subject: A subject
+To: aperson at dom.ain
+From: bperson at dom.ain
+
+
+--BOUNDARY
+
+
+--BOUNDARY--
+"""
+        msg = Parser().parsestr(text)
+        self.ndiffAssertEqual(text, msg.as_string())
+
+    def test_no_parts_in_a_multipart_with_none_epilogue(self):
+        outer = MIMEBase('multipart', 'mixed')
+        outer['Subject'] = 'A subject'
+        outer['To'] = 'aperson at dom.ain'
+        outer['From'] = 'bperson at dom.ain'
+        outer.set_boundary('BOUNDARY')
+        self.ndiffAssertEqual(outer.as_string(), '''\
+Content-Type: multipart/mixed; boundary="BOUNDARY"
+MIME-Version: 1.0
+Subject: A subject
+To: aperson at dom.ain
+From: bperson at dom.ain
+
+--BOUNDARY
+
+--BOUNDARY--''')
+
+    def test_no_parts_in_a_multipart_with_empty_epilogue(self):
+        outer = MIMEBase('multipart', 'mixed')
+        outer['Subject'] = 'A subject'
+        outer['To'] = 'aperson at dom.ain'
+        outer['From'] = 'bperson at dom.ain'
+        outer.preamble = ''
+        outer.epilogue = ''
+        outer.set_boundary('BOUNDARY')
+        self.ndiffAssertEqual(outer.as_string(), '''\
+Content-Type: multipart/mixed; boundary="BOUNDARY"
+MIME-Version: 1.0
+Subject: A subject
+To: aperson at dom.ain
+From: bperson at dom.ain
+
+
+--BOUNDARY
+
+--BOUNDARY--
+''')
+
+    def test_one_part_in_a_multipart(self):
+        eq = self.ndiffAssertEqual
+        outer = MIMEBase('multipart', 'mixed')
+        outer['Subject'] = 'A subject'
+        outer['To'] = 'aperson at dom.ain'
+        outer['From'] = 'bperson at dom.ain'
+        outer.set_boundary('BOUNDARY')
+        msg = MIMEText('hello world')
+        outer.attach(msg)
+        eq(outer.as_string(), '''\
+Content-Type: multipart/mixed; boundary="BOUNDARY"
+MIME-Version: 1.0
+Subject: A subject
+To: aperson at dom.ain
+From: bperson at dom.ain
+
+--BOUNDARY
+Content-Type: text/plain; charset="us-ascii"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+
+hello world
+--BOUNDARY--''')
+
+    def test_seq_parts_in_a_multipart_with_empty_preamble(self):
+        eq = self.ndiffAssertEqual
+        outer = MIMEBase('multipart', 'mixed')
+        outer['Subject'] = 'A subject'
+        outer['To'] = 'aperson at dom.ain'
+        outer['From'] = 'bperson at dom.ain'
+        outer.preamble = ''
+        msg = MIMEText('hello world')
+        outer.attach(msg)
+        outer.set_boundary('BOUNDARY')
+        eq(outer.as_string(), '''\
+Content-Type: multipart/mixed; boundary="BOUNDARY"
+MIME-Version: 1.0
+Subject: A subject
+To: aperson at dom.ain
+From: bperson at dom.ain
+
+
+--BOUNDARY
+Content-Type: text/plain; charset="us-ascii"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+
+hello world
+--BOUNDARY--''')
+
+
+    def test_seq_parts_in_a_multipart_with_none_preamble(self):
+        eq = self.ndiffAssertEqual
+        outer = MIMEBase('multipart', 'mixed')
+        outer['Subject'] = 'A subject'
+        outer['To'] = 'aperson at dom.ain'
+        outer['From'] = 'bperson at dom.ain'
+        outer.preamble = None
+        msg = MIMEText('hello world')
+        outer.attach(msg)
+        outer.set_boundary('BOUNDARY')
+        eq(outer.as_string(), '''\
+Content-Type: multipart/mixed; boundary="BOUNDARY"
+MIME-Version: 1.0
+Subject: A subject
+To: aperson at dom.ain
+From: bperson at dom.ain
+
+--BOUNDARY
+Content-Type: text/plain; charset="us-ascii"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+
+hello world
+--BOUNDARY--''')
+
+
+    def test_seq_parts_in_a_multipart_with_none_epilogue(self):
+        eq = self.ndiffAssertEqual
+        outer = MIMEBase('multipart', 'mixed')
+        outer['Subject'] = 'A subject'
+        outer['To'] = 'aperson at dom.ain'
+        outer['From'] = 'bperson at dom.ain'
+        outer.epilogue = None
+        msg = MIMEText('hello world')
+        outer.attach(msg)
+        outer.set_boundary('BOUNDARY')
+        eq(outer.as_string(), '''\
+Content-Type: multipart/mixed; boundary="BOUNDARY"
+MIME-Version: 1.0
+Subject: A subject
+To: aperson at dom.ain
+From: bperson at dom.ain
+
+--BOUNDARY
+Content-Type: text/plain; charset="us-ascii"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+
+hello world
+--BOUNDARY--''')
+
+
+    def test_seq_parts_in_a_multipart_with_empty_epilogue(self):
+        eq = self.ndiffAssertEqual
+        outer = MIMEBase('multipart', 'mixed')
+        outer['Subject'] = 'A subject'
+        outer['To'] = 'aperson at dom.ain'
+        outer['From'] = 'bperson at dom.ain'
+        outer.epilogue = ''
+        msg = MIMEText('hello world')
+        outer.attach(msg)
+        outer.set_boundary('BOUNDARY')
+        eq(outer.as_string(), '''\
+Content-Type: multipart/mixed; boundary="BOUNDARY"
+MIME-Version: 1.0
+Subject: A subject
+To: aperson at dom.ain
+From: bperson at dom.ain
+
+--BOUNDARY
+Content-Type: text/plain; charset="us-ascii"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+
+hello world
+--BOUNDARY--
+''')
+
+
+    def test_seq_parts_in_a_multipart_with_nl_epilogue(self):
+        eq = self.ndiffAssertEqual
+        outer = MIMEBase('multipart', 'mixed')
+        outer['Subject'] = 'A subject'
+        outer['To'] = 'aperson at dom.ain'
+        outer['From'] = 'bperson at dom.ain'
+        outer.epilogue = '\n'
+        msg = MIMEText('hello world')
+        outer.attach(msg)
+        outer.set_boundary('BOUNDARY')
+        eq(outer.as_string(), '''\
+Content-Type: multipart/mixed; boundary="BOUNDARY"
+MIME-Version: 1.0
+Subject: A subject
+To: aperson at dom.ain
+From: bperson at dom.ain
+
+--BOUNDARY
+Content-Type: text/plain; charset="us-ascii"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+
+hello world
+--BOUNDARY--
+
+''')
+
+    def test_message_external_body(self):
+        eq = self.assertEqual
+        msg = self._msgobj('msg_36.txt')
+        eq(len(msg.get_payload()), 2)
+        msg1 = msg.get_payload(1)
+        eq(msg1.get_content_type(), 'multipart/alternative')
+        eq(len(msg1.get_payload()), 2)
+        for subpart in msg1.get_payload():
+            eq(subpart.get_content_type(), 'message/external-body')
+            eq(len(subpart.get_payload()), 1)
+            subsubpart = subpart.get_payload(0)
+            eq(subsubpart.get_content_type(), 'text/plain')
+
+    def test_double_boundary(self):
+        # msg_37.txt is a multipart that contains two dash-boundary's in a
+        # row.  Our interpretation of RFC 2046 calls for ignoring the second
+        # and subsequent boundaries.
+        msg = self._msgobj('msg_37.txt')
+        self.assertEqual(len(msg.get_payload()), 3)
+
+    def test_nested_inner_contains_outer_boundary(self):
+        eq = self.ndiffAssertEqual
+        # msg_38.txt has an inner part that contains outer boundaries.  My
+        # interpretation of RFC 2046 (based on sections 5.1 and 5.1.2) say
+        # these are illegal and should be interpreted as unterminated inner
+        # parts.
+        msg = self._msgobj('msg_38.txt')
+        sfp = StringIO()
+        Iterators._structure(msg, sfp)
+        eq(sfp.getvalue(), """\
+multipart/mixed
+    multipart/mixed
+        multipart/alternative
+            text/plain
+        text/plain
+    text/plain
+    text/plain
+""")
+
+    def test_nested_with_same_boundary(self):
+        eq = self.ndiffAssertEqual
+        # msg 39.txt is similarly evil in that it's got inner parts that use
+        # the same boundary as outer parts.  Again, I believe the way this is
+        # parsed is closest to the spirit of RFC 2046
+        msg = self._msgobj('msg_39.txt')
+        sfp = StringIO()
+        Iterators._structure(msg, sfp)
+        eq(sfp.getvalue(), """\
+multipart/mixed
+    multipart/mixed
+        multipart/alternative
+        application/octet-stream
+        application/octet-stream
+    text/plain
+""")
+
+    def test_boundary_in_non_multipart(self):
+        msg = self._msgobj('msg_40.txt')
+        self.assertEqual(msg.as_string(), '''\
+MIME-Version: 1.0
+Content-Type: text/html; boundary="--961284236552522269"
+
+----961284236552522269
+Content-Type: text/html;
+Content-Transfer-Encoding: 7Bit
+
+<html></html>
+
+----961284236552522269--
+''')
+
+    def test_boundary_with_leading_space(self):
+        eq = self.assertEqual
+        msg = email.message_from_string('''\
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="    XXXX"
+
+--    XXXX
+Content-Type: text/plain
+
+
+--    XXXX
+Content-Type: text/plain
+
+--    XXXX--
+''')
+        self.failUnless(msg.is_multipart())
+        eq(msg.get_boundary(), '    XXXX')
+        eq(len(msg.get_payload()), 2)
+
+    def test_boundary_without_trailing_newline(self):
+        m = Parser().parsestr("""\
+Content-Type: multipart/mixed; boundary="===============0012394164=="
+MIME-Version: 1.0
+
+--===============0012394164==
+Content-Type: image/file1.jpg
+MIME-Version: 1.0
+Content-Transfer-Encoding: base64
+
+YXNkZg==
+--===============0012394164==--""")
+        self.assertEquals(m.get_payload(0).get_payload(), 'YXNkZg==')
+
+
+
+# Test some badly formatted messages
+class TestNonConformant(TestEmailBase):
+    def test_parse_missing_minor_type(self):
+        eq = self.assertEqual
+        msg = self._msgobj('msg_14.txt')
+        eq(msg.get_content_type(), 'text/plain')
+        eq(msg.get_content_maintype(), 'text')
+        eq(msg.get_content_subtype(), 'plain')
+
+    def test_same_boundary_inner_outer(self):
+        unless = self.failUnless
+        msg = self._msgobj('msg_15.txt')
+        # XXX We can probably eventually do better
+        inner = msg.get_payload(0)
+        unless(hasattr(inner, 'defects'))
+        self.assertEqual(len(inner.defects), 1)
+        unless(isinstance(inner.defects[0],
+                          Errors.StartBoundaryNotFoundDefect))
+
+    def test_multipart_no_boundary(self):
+        unless = self.failUnless
+        msg = self._msgobj('msg_25.txt')
+        unless(isinstance(msg.get_payload(), str))
+        self.assertEqual(len(msg.defects), 2)
+        unless(isinstance(msg.defects[0], Errors.NoBoundaryInMultipartDefect))
+        unless(isinstance(msg.defects[1],
+                          Errors.MultipartInvariantViolationDefect))
+
+    def test_invalid_content_type(self):
+        eq = self.assertEqual
+        neq = self.ndiffAssertEqual
+        msg = Message()
+        # RFC 2045, $5.2 says invalid yields text/plain
+        msg['Content-Type'] = 'text'
+        eq(msg.get_content_maintype(), 'text')
+        eq(msg.get_content_subtype(), 'plain')
+        eq(msg.get_content_type(), 'text/plain')
+        # Clear the old value and try something /really/ invalid
+        del msg['content-type']
+        msg['Content-Type'] = 'foo'
+        eq(msg.get_content_maintype(), 'text')
+        eq(msg.get_content_subtype(), 'plain')
+        eq(msg.get_content_type(), 'text/plain')
+        # Still, make sure that the message is idempotently generated
+        s = StringIO()
+        g = Generator(s)
+        g.flatten(msg)
+        neq(s.getvalue(), 'Content-Type: foo\n\n')
+
+    def test_no_start_boundary(self):
+        eq = self.ndiffAssertEqual
+        msg = self._msgobj('msg_31.txt')
+        eq(msg.get_payload(), """\
+--BOUNDARY
+Content-Type: text/plain
+
+message 1
+
+--BOUNDARY
+Content-Type: text/plain
+
+message 2
+
+--BOUNDARY--
+""")
+
+    def test_no_separating_blank_line(self):
+        eq = self.ndiffAssertEqual
+        msg = self._msgobj('msg_35.txt')
+        eq(msg.as_string(), """\
+From: aperson at dom.ain
+To: bperson at dom.ain
+Subject: here's something interesting
+
+counter to RFC 2822, there's no separating newline here
+""")
+
+    def test_lying_multipart(self):
+        unless = self.failUnless
+        msg = self._msgobj('msg_41.txt')
+        unless(hasattr(msg, 'defects'))
+        self.assertEqual(len(msg.defects), 2)
+        unless(isinstance(msg.defects[0], Errors.NoBoundaryInMultipartDefect))
+        unless(isinstance(msg.defects[1],
+                          Errors.MultipartInvariantViolationDefect))
+
+    def test_missing_start_boundary(self):
+        outer = self._msgobj('msg_42.txt')
+        # The message structure is:
+        #
+        # multipart/mixed
+        #    text/plain
+        #    message/rfc822
+        #        multipart/mixed [*]
+        #
+        # [*] This message is missing its start boundary
+        bad = outer.get_payload(1).get_payload(0)
+        self.assertEqual(len(bad.defects), 1)
+        self.failUnless(isinstance(bad.defects[0],
+                                   Errors.StartBoundaryNotFoundDefect))
+
+
+
+# Test RFC 2047 header encoding and decoding
+class TestRFC2047(unittest.TestCase):
+    def test_rfc2047_multiline(self):
+        eq = self.assertEqual
+        s = """Re: =?mac-iceland?q?r=8Aksm=9Arg=8Cs?= baz
+ foo bar =?mac-iceland?q?r=8Aksm=9Arg=8Cs?="""
+        dh = decode_header(s)
+        eq(dh, [
+            ('Re:', None),
+            ('r\x8aksm\x9arg\x8cs', 'mac-iceland'),
+            ('baz foo bar', None),
+            ('r\x8aksm\x9arg\x8cs', 'mac-iceland')])
+        eq(str(make_header(dh)),
+           """Re: =?mac-iceland?q?r=8Aksm=9Arg=8Cs?= baz foo bar
+ =?mac-iceland?q?r=8Aksm=9Arg=8Cs?=""")
+
+    def test_whitespace_eater_unicode(self):
+        eq = self.assertEqual
+        s = '=?ISO-8859-1?Q?Andr=E9?= Pirard <pirard at dom.ain>'
+        dh = decode_header(s)
+        eq(dh, [('Andr\xe9', 'iso-8859-1'), ('Pirard <pirard at dom.ain>', None)])
+        hu = unicode(make_header(dh)).encode('latin-1')
+        eq(hu, 'Andr\xe9 Pirard <pirard at dom.ain>')
+
+    def test_whitespace_eater_unicode_2(self):
+        eq = self.assertEqual
+        s = 'The =?iso-8859-1?b?cXVpY2sgYnJvd24gZm94?= jumped over the =?iso-8859-1?b?bGF6eSBkb2c=?='
+        dh = decode_header(s)
+        eq(dh, [('The', None), ('quick brown fox', 'iso-8859-1'),
+                ('jumped over the', None), ('lazy dog', 'iso-8859-1')])
+        hu = make_header(dh).__unicode__()
+        eq(hu, u'The quick brown fox jumped over the lazy dog')
+
+    def test_rfc2047_without_whitespace(self):
+        s = 'Sm=?ISO-8859-1?B?9g==?=rg=?ISO-8859-1?B?5Q==?=sbord'
+        dh = decode_header(s)
+        self.assertEqual(dh, [(s, None)])
+
+    def test_rfc2047_with_whitespace(self):
+        s = 'Sm =?ISO-8859-1?B?9g==?= rg =?ISO-8859-1?B?5Q==?= sbord'
+        dh = decode_header(s)
+        self.assertEqual(dh, [('Sm', None), ('\xf6', 'iso-8859-1'),
+                              ('rg', None), ('\xe5', 'iso-8859-1'),
+                              ('sbord', None)])
+
+
+
+# Test the MIMEMessage class
+class TestMIMEMessage(TestEmailBase):
+    def setUp(self):
+        fp = openfile('msg_11.txt')
+        try:
+            self._text = fp.read()
+        finally:
+            fp.close()
+
+    def test_type_error(self):
+        self.assertRaises(TypeError, MIMEMessage, 'a plain string')
+
+    def test_valid_argument(self):
+        eq = self.assertEqual
+        unless = self.failUnless
+        subject = 'A sub-message'
+        m = Message()
+        m['Subject'] = subject
+        r = MIMEMessage(m)
+        eq(r.get_content_type(), 'message/rfc822')
+        payload = r.get_payload()
+        unless(isinstance(payload, list))
+        eq(len(payload), 1)
+        subpart = payload[0]
+        unless(subpart is m)
+        eq(subpart['subject'], subject)
+
+    def test_bad_multipart(self):
+        eq = self.assertEqual
+        msg1 = Message()
+        msg1['Subject'] = 'subpart 1'
+        msg2 = Message()
+        msg2['Subject'] = 'subpart 2'
+        r = MIMEMessage(msg1)
+        self.assertRaises(Errors.MultipartConversionError, r.attach, msg2)
+
+    def test_generate(self):
+        # First craft the message to be encapsulated
+        m = Message()
+        m['Subject'] = 'An enclosed message'
+        m.set_payload('Here is the body of the message.\n')
+        r = MIMEMessage(m)
+        r['Subject'] = 'The enclosing message'
+        s = StringIO()
+        g = Generator(s)
+        g.flatten(r)
+        self.assertEqual(s.getvalue(), """\
+Content-Type: message/rfc822
+MIME-Version: 1.0
+Subject: The enclosing message
+
+Subject: An enclosed message
+
+Here is the body of the message.
+""")
+
+    def test_parse_message_rfc822(self):
+        eq = self.assertEqual
+        unless = self.failUnless
+        msg = self._msgobj('msg_11.txt')
+        eq(msg.get_content_type(), 'message/rfc822')
+        payload = msg.get_payload()
+        unless(isinstance(payload, list))
+        eq(len(payload), 1)
+        submsg = payload[0]
+        self.failUnless(isinstance(submsg, Message))
+        eq(submsg['subject'], 'An enclosed message')
+        eq(submsg.get_payload(), 'Here is the body of the message.\n')
+
+    def test_dsn(self):
+        eq = self.assertEqual
+        unless = self.failUnless
+        # msg 16 is a Delivery Status Notification, see RFC 1894
+        msg = self._msgobj('msg_16.txt')
+        eq(msg.get_content_type(), 'multipart/report')
+        unless(msg.is_multipart())
+        eq(len(msg.get_payload()), 3)
+        # Subpart 1 is a text/plain, human readable section
+        subpart = msg.get_payload(0)
+        eq(subpart.get_content_type(), 'text/plain')
+        eq(subpart.get_payload(), """\
+This report relates to a message you sent with the following header fields:
+
+  Message-id: <002001c144a6$8752e060$56104586 at oxy.edu>
+  Date: Sun, 23 Sep 2001 20:10:55 -0700
+  From: "Ian T. Henry" <henryi at oxy.edu>
+  To: SoCal Raves <scr at socal-raves.org>
+  Subject: [scr] yeah for Ians!!
+
+Your message cannot be delivered to the following recipients:
+
+  Recipient address: jangel1 at cougar.noc.ucla.edu
+  Reason: recipient reached disk quota
+
+""")
+        # Subpart 2 contains the machine parsable DSN information.  It
+        # consists of two blocks of headers, represented by two nested Message
+        # objects.
+        subpart = msg.get_payload(1)
+        eq(subpart.get_content_type(), 'message/delivery-status')
+        eq(len(subpart.get_payload()), 2)
+        # message/delivery-status should treat each block as a bunch of
+        # headers, i.e. a bunch of Message objects.
+        dsn1 = subpart.get_payload(0)
+        unless(isinstance(dsn1, Message))
+        eq(dsn1['original-envelope-id'], '0GK500B4HD0888 at cougar.noc.ucla.edu')
+        eq(dsn1.get_param('dns', header='reporting-mta'), '')
+        # Try a missing one <wink>
+        eq(dsn1.get_param('nsd', header='reporting-mta'), None)
+        dsn2 = subpart.get_payload(1)
+        unless(isinstance(dsn2, Message))
+        eq(dsn2['action'], 'failed')
+        eq(dsn2.get_params(header='original-recipient'),
+           [('rfc822', ''), ('jangel1 at cougar.noc.ucla.edu', '')])
+        eq(dsn2.get_param('rfc822', header='final-recipient'), '')
+        # Subpart 3 is the original message
+        subpart = msg.get_payload(2)
+        eq(subpart.get_content_type(), 'message/rfc822')
+        payload = subpart.get_payload()
+        unless(isinstance(payload, list))
+        eq(len(payload), 1)
+        subsubpart = payload[0]
+        unless(isinstance(subsubpart, Message))
+        eq(subsubpart.get_content_type(), 'text/plain')
+        eq(subsubpart['message-id'],
+           '<002001c144a6$8752e060$56104586 at oxy.edu>')
+
+    def test_epilogue(self):
+        eq = self.ndiffAssertEqual
+        fp = openfile('msg_21.txt')
+        try:
+            text = fp.read()
+        finally:
+            fp.close()
+        msg = Message()
+        msg['From'] = 'aperson at dom.ain'
+        msg['To'] = 'bperson at dom.ain'
+        msg['Subject'] = 'Test'
+        msg.preamble = 'MIME message'
+        msg.epilogue = 'End of MIME message\n'
+        msg1 = MIMEText('One')
+        msg2 = MIMEText('Two')
+        msg.add_header('Content-Type', 'multipart/mixed', boundary='BOUNDARY')
+        msg.attach(msg1)
+        msg.attach(msg2)
+        sfp = StringIO()
+        g = Generator(sfp)
+        g.flatten(msg)
+        eq(sfp.getvalue(), text)
+
+    def test_no_nl_preamble(self):
+        eq = self.ndiffAssertEqual
+        msg = Message()
+        msg['From'] = 'aperson at dom.ain'
+        msg['To'] = 'bperson at dom.ain'
+        msg['Subject'] = 'Test'
+        msg.preamble = 'MIME message'
+        msg.epilogue = ''
+        msg1 = MIMEText('One')
+        msg2 = MIMEText('Two')
+        msg.add_header('Content-Type', 'multipart/mixed', boundary='BOUNDARY')
+        msg.attach(msg1)
+        msg.attach(msg2)
+        eq(msg.as_string(), """\
+From: aperson at dom.ain
+To: bperson at dom.ain
+Subject: Test
+Content-Type: multipart/mixed; boundary="BOUNDARY"
+
+MIME message
+--BOUNDARY
+Content-Type: text/plain; charset="us-ascii"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+
+One
+--BOUNDARY
+Content-Type: text/plain; charset="us-ascii"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+
+Two
+--BOUNDARY--
+""")
+
+    def test_default_type(self):
+        eq = self.assertEqual
+        fp = openfile('msg_30.txt')
+        try:
+            msg = email.message_from_file(fp)
+        finally:
+            fp.close()
+        container1 = msg.get_payload(0)
+        eq(container1.get_default_type(), 'message/rfc822')
+        eq(container1.get_content_type(), 'message/rfc822')
+        container2 = msg.get_payload(1)
+        eq(container2.get_default_type(), 'message/rfc822')
+        eq(container2.get_content_type(), 'message/rfc822')
+        container1a = container1.get_payload(0)
+        eq(container1a.get_default_type(), 'text/plain')
+        eq(container1a.get_content_type(), 'text/plain')
+        container2a = container2.get_payload(0)
+        eq(container2a.get_default_type(), 'text/plain')
+        eq(container2a.get_content_type(), 'text/plain')
+
+    def test_default_type_with_explicit_container_type(self):
+        eq = self.assertEqual
+        fp = openfile('msg_28.txt')
+        try:
+            msg = email.message_from_file(fp)
+        finally:
+            fp.close()
+        container1 = msg.get_payload(0)
+        eq(container1.get_default_type(), 'message/rfc822')
+        eq(container1.get_content_type(), 'message/rfc822')
+        container2 = msg.get_payload(1)
+        eq(container2.get_default_type(), 'message/rfc822')
+        eq(container2.get_content_type(), 'message/rfc822')
+        container1a = container1.get_payload(0)
+        eq(container1a.get_default_type(), 'text/plain')
+        eq(container1a.get_content_type(), 'text/plain')
+        container2a = container2.get_payload(0)
+        eq(container2a.get_default_type(), 'text/plain')
+        eq(container2a.get_content_type(), 'text/plain')
+
+    def test_default_type_non_parsed(self):
+        eq = self.assertEqual
+        neq = self.ndiffAssertEqual
+        # Set up container
+        container = MIMEMultipart('digest', 'BOUNDARY')
+        container.epilogue = ''
+        # Set up subparts
+        subpart1a = MIMEText('message 1\n')
+        subpart2a = MIMEText('message 2\n')
+        subpart1 = MIMEMessage(subpart1a)
+        subpart2 = MIMEMessage(subpart2a)
+        container.attach(subpart1)
+        container.attach(subpart2)
+        eq(subpart1.get_content_type(), 'message/rfc822')
+        eq(subpart1.get_default_type(), 'message/rfc822')
+        eq(subpart2.get_content_type(), 'message/rfc822')
+        eq(subpart2.get_default_type(), 'message/rfc822')
+        neq(container.as_string(0), '''\
+Content-Type: multipart/digest; boundary="BOUNDARY"
+MIME-Version: 1.0
+
+--BOUNDARY
+Content-Type: message/rfc822
+MIME-Version: 1.0
+
+Content-Type: text/plain; charset="us-ascii"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+
+message 1
+
+--BOUNDARY
+Content-Type: message/rfc822
+MIME-Version: 1.0
+
+Content-Type: text/plain; charset="us-ascii"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+
+message 2
+
+--BOUNDARY--
+''')
+        del subpart1['content-type']
+        del subpart1['mime-version']
+        del subpart2['content-type']
+        del subpart2['mime-version']
+        eq(subpart1.get_content_type(), 'message/rfc822')
+        eq(subpart1.get_default_type(), 'message/rfc822')
+        eq(subpart2.get_content_type(), 'message/rfc822')
+        eq(subpart2.get_default_type(), 'message/rfc822')
+        neq(container.as_string(0), '''\
+Content-Type: multipart/digest; boundary="BOUNDARY"
+MIME-Version: 1.0
+
+--BOUNDARY
+
+Content-Type: text/plain; charset="us-ascii"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+
+message 1
+
+--BOUNDARY
+
+Content-Type: text/plain; charset="us-ascii"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+
+message 2
+
+--BOUNDARY--
+''')
+
+    def test_mime_attachments_in_constructor(self):
+        eq = self.assertEqual
+        text1 = MIMEText('')
+        text2 = MIMEText('')
+        msg = MIMEMultipart(_subparts=(text1, text2))
+        eq(len(msg.get_payload()), 2)
+        eq(msg.get_payload(0), text1)
+        eq(msg.get_payload(1), text2)
+
+
+
+# A general test of parser->model->generator idempotency.  IOW, read a message
+# in, parse it into a message object tree, then without touching the tree,
+# regenerate the plain text.  The original text and the transformed text
+# should be identical.  Note: that we ignore the Unix-From since that may
+# contain a changed date.
+class TestIdempotent(TestEmailBase):
+    def _msgobj(self, filename):
+        fp = openfile(filename)
+        try:
+            data = fp.read()
+        finally:
+            fp.close()
+        msg = email.message_from_string(data)
+        return msg, data
+
+    def _idempotent(self, msg, text):
+        eq = self.ndiffAssertEqual
+        s = StringIO()
+        g = Generator(s, maxheaderlen=0)
+        g.flatten(msg)
+        eq(text, s.getvalue())
+
+    def test_parse_text_message(self):
+        eq = self.assertEquals
+        msg, text = self._msgobj('msg_01.txt')
+        eq(msg.get_content_type(), 'text/plain')
+        eq(msg.get_content_maintype(), 'text')
+        eq(msg.get_content_subtype(), 'plain')
+        eq(msg.get_params()[1], ('charset', 'us-ascii'))
+        eq(msg.get_param('charset'), 'us-ascii')
+        eq(msg.preamble, None)
+        eq(msg.epilogue, None)
+        self._idempotent(msg, text)
+
+    def test_parse_untyped_message(self):
+        eq = self.assertEquals
+        msg, text = self._msgobj('msg_03.txt')
+        eq(msg.get_content_type(), 'text/plain')
+        eq(msg.get_params(), None)
+        eq(msg.get_param('charset'), None)
+        self._idempotent(msg, text)
+
+    def test_simple_multipart(self):
+        msg, text = self._msgobj('msg_04.txt')
+        self._idempotent(msg, text)
+
+    def test_MIME_digest(self):
+        msg, text = self._msgobj('msg_02.txt')
+        self._idempotent(msg, text)
+
+    def test_long_header(self):
+        msg, text = self._msgobj('msg_27.txt')
+        self._idempotent(msg, text)
+
+    def test_MIME_digest_with_part_headers(self):
+        msg, text = self._msgobj('msg_28.txt')
+        self._idempotent(msg, text)
+
+    def test_mixed_with_image(self):
+        msg, text = self._msgobj('msg_06.txt')
+        self._idempotent(msg, text)
+
+    def test_multipart_report(self):
+        msg, text = self._msgobj('msg_05.txt')
+        self._idempotent(msg, text)
+
+    def test_dsn(self):
+        msg, text = self._msgobj('msg_16.txt')
+        self._idempotent(msg, text)
+
+    def test_preamble_epilogue(self):
+        msg, text = self._msgobj('msg_21.txt')
+        self._idempotent(msg, text)
+
+    def test_multipart_one_part(self):
+        msg, text = self._msgobj('msg_23.txt')
+        self._idempotent(msg, text)
+
+    def test_multipart_no_parts(self):
+        msg, text = self._msgobj('msg_24.txt')
+        self._idempotent(msg, text)
+
+    def test_no_start_boundary(self):
+        msg, text = self._msgobj('msg_31.txt')
+        self._idempotent(msg, text)
+
+    def test_rfc2231_charset(self):
+        msg, text = self._msgobj('msg_32.txt')
+        self._idempotent(msg, text)
+
+    def test_more_rfc2231_parameters(self):
+        msg, text = self._msgobj('msg_33.txt')
+        self._idempotent(msg, text)
+
+    def test_text_plain_in_a_multipart_digest(self):
+        msg, text = self._msgobj('msg_34.txt')
+        self._idempotent(msg, text)
+
+    def test_nested_multipart_mixeds(self):
+        msg, text = self._msgobj('msg_12a.txt')
+        self._idempotent(msg, text)
+
+    def test_message_external_body_idempotent(self):
+        msg, text = self._msgobj('msg_36.txt')
+        self._idempotent(msg, text)
+
+    def test_content_type(self):
+        eq = self.assertEquals
+        unless = self.failUnless
+        # Get a message object and reset the seek pointer for other tests
+        msg, text = self._msgobj('msg_05.txt')
+        eq(msg.get_content_type(), 'multipart/report')
+        # Test the Content-Type: parameters
+        params = {}
+        for pk, pv in msg.get_params():
+            params[pk] = pv
+        eq(params['report-type'], 'delivery-status')
+        eq(params['boundary'], 'D1690A7AC1.996856090/mail.example.com')
+        eq(msg.preamble, 'This is a MIME-encapsulated message.\n')
+        eq(msg.epilogue, '\n')
+        eq(len(msg.get_payload()), 3)
+        # Make sure the subparts are what we expect
+        msg1 = msg.get_payload(0)
+        eq(msg1.get_content_type(), 'text/plain')
+        eq(msg1.get_payload(), 'Yadda yadda yadda\n')
+        msg2 = msg.get_payload(1)
+        eq(msg2.get_content_type(), 'text/plain')
+        eq(msg2.get_payload(), 'Yadda yadda yadda\n')
+        msg3 = msg.get_payload(2)
+        eq(msg3.get_content_type(), 'message/rfc822')
+        self.failUnless(isinstance(msg3, Message))
+        payload = msg3.get_payload()
+        unless(isinstance(payload, list))
+        eq(len(payload), 1)
+        msg4 = payload[0]
+        unless(isinstance(msg4, Message))
+        eq(msg4.get_payload(), 'Yadda yadda yadda\n')
+
+    def test_parser(self):
+        eq = self.assertEquals
+        unless = self.failUnless
+        msg, text = self._msgobj('msg_06.txt')
+        # Check some of the outer headers
+        eq(msg.get_content_type(), 'message/rfc822')
+        # Make sure the payload is a list of exactly one sub-Message, and that
+        # that submessage has a type of text/plain
+        payload = msg.get_payload()
+        unless(isinstance(payload, list))
+        eq(len(payload), 1)
+        msg1 = payload[0]
+        self.failUnless(isinstance(msg1, Message))
+        eq(msg1.get_content_type(), 'text/plain')
+        self.failUnless(isinstance(msg1.get_payload(), str))
+        eq(msg1.get_payload(), '\n')
+
+
+
+# Test various other bits of the package's functionality
+class TestMiscellaneous(TestEmailBase):
+    def test_message_from_string(self):
+        fp = openfile('msg_01.txt')
+        try:
+            text = fp.read()
+        finally:
+            fp.close()
+        msg = email.message_from_string(text)
+        s = StringIO()
+        # Don't wrap/continue long headers since we're trying to test
+        # idempotency.
+        g = Generator(s, maxheaderlen=0)
+        g.flatten(msg)
+        self.assertEqual(text, s.getvalue())
+
+    def test_message_from_file(self):
+        fp = openfile('msg_01.txt')
+        try:
+            text = fp.read()
+            fp.seek(0)
+            msg = email.message_from_file(fp)
+            s = StringIO()
+            # Don't wrap/continue long headers since we're trying to test
+            # idempotency.
+            g = Generator(s, maxheaderlen=0)
+            g.flatten(msg)
+            self.assertEqual(text, s.getvalue())
+        finally:
+            fp.close()
+
+    def test_message_from_string_with_class(self):
+        unless = self.failUnless
+        fp = openfile('msg_01.txt')
+        try:
+            text = fp.read()
+        finally:
+            fp.close()
+        # Create a subclass
+        class MyMessage(Message):
+            pass
+
+        msg = email.message_from_string(text, MyMessage)
+        unless(isinstance(msg, MyMessage))
+        # Try something more complicated
+        fp = openfile('msg_02.txt')
+        try:
+            text = fp.read()
+        finally:
+            fp.close()
+        msg = email.message_from_string(text, MyMessage)
+        for subpart in msg.walk():
+            unless(isinstance(subpart, MyMessage))
+
+    def test_message_from_file_with_class(self):
+        unless = self.failUnless
+        # Create a subclass
+        class MyMessage(Message):
+            pass
+
+        fp = openfile('msg_01.txt')
+        try:
+            msg = email.message_from_file(fp, MyMessage)
+        finally:
+            fp.close()
+        unless(isinstance(msg, MyMessage))
+        # Try something more complicated
+        fp = openfile('msg_02.txt')
+        try:
+            msg = email.message_from_file(fp, MyMessage)
+        finally:
+            fp.close()
+        for subpart in msg.walk():
+            unless(isinstance(subpart, MyMessage))
+
+    def test__all__(self):
+        module = __import__('email')
+        all = module.__all__
+        all.sort()
+        self.assertEqual(all, [
+            # Old names
+            'Charset', 'Encoders', 'Errors', 'Generator',
+            'Header', 'Iterators', 'MIMEAudio', 'MIMEBase',
+            'MIMEImage', 'MIMEMessage', 'MIMEMultipart',
+            'MIMENonMultipart', 'MIMEText', 'Message',
+            'Parser', 'Utils', 'base64MIME',
+            # new names
+            'base64mime', 'charset', 'encoders', 'errors', 'generator',
+            'header', 'iterators', 'message', 'message_from_file',
+            'message_from_string', 'mime', 'parser',
+            'quopriMIME', 'quoprimime', 'utils',
+            ])
+
+    def test_formatdate(self):
+        now = time.time()
+        self.assertEqual(Utils.parsedate(Utils.formatdate(now))[:6],
+                         time.gmtime(now)[:6])
+
+    def test_formatdate_localtime(self):
+        now = time.time()
+        self.assertEqual(
+            Utils.parsedate(Utils.formatdate(now, localtime=True))[:6],
+            time.localtime(now)[:6])
+
+    def test_formatdate_usegmt(self):
+        now = time.time()
+        self.assertEqual(
+            Utils.formatdate(now, localtime=False),
+            time.strftime('%a, %d %b %Y %H:%M:%S -0000', time.gmtime(now)))
+        self.assertEqual(
+            Utils.formatdate(now, localtime=False, usegmt=True),
+            time.strftime('%a, %d %b %Y %H:%M:%S GMT', time.gmtime(now)))
+
+    def test_parsedate_none(self):
+        self.assertEqual(Utils.parsedate(''), None)
+
+    def test_parsedate_compact(self):
+        # The FWS after the comma is optional
+        self.assertEqual(Utils.parsedate('Wed,3 Apr 2002 14:58:26 +0800'),
+                         Utils.parsedate('Wed, 3 Apr 2002 14:58:26 +0800'))
+
+    def test_parsedate_no_dayofweek(self):
+        eq = self.assertEqual
+        eq(Utils.parsedate_tz('25 Feb 2003 13:47:26 -0800'),
+           (2003, 2, 25, 13, 47, 26, 0, 1, -1, -28800))
+
+    def test_parsedate_compact_no_dayofweek(self):
+        eq = self.assertEqual
+        eq(Utils.parsedate_tz('5 Feb 2003 13:47:26 -0800'),
+           (2003, 2, 5, 13, 47, 26, 0, 1, -1, -28800))
+
+    def test_parsedate_acceptable_to_time_functions(self):
+        eq = self.assertEqual
+        timetup = Utils.parsedate('5 Feb 2003 13:47:26 -0800')
+        t = int(time.mktime(timetup))
+        eq(time.localtime(t)[:6], timetup[:6])
+        eq(int(time.strftime('%Y', timetup)), 2003)
+        timetup = Utils.parsedate_tz('5 Feb 2003 13:47:26 -0800')
+        t = int(time.mktime(timetup[:9]))
+        eq(time.localtime(t)[:6], timetup[:6])
+        eq(int(time.strftime('%Y', timetup[:9])), 2003)
+
+    def test_parseaddr_empty(self):
+        self.assertEqual(Utils.parseaddr('<>'), ('', ''))
+        self.assertEqual(Utils.formataddr(Utils.parseaddr('<>')), '')
+
+    def test_noquote_dump(self):
+        self.assertEqual(
+            Utils.formataddr(('A Silly Person', 'person at dom.ain')),
+            'A Silly Person <person at dom.ain>')
+
+    def test_escape_dump(self):
+        self.assertEqual(
+            Utils.formataddr(('A (Very) Silly Person', 'person at dom.ain')),
+            r'"A \(Very\) Silly Person" <person at dom.ain>')
+        a = r'A \(Special\) Person'
+        b = 'person at dom.ain'
+        self.assertEqual(Utils.parseaddr(Utils.formataddr((a, b))), (a, b))
+
+    def test_escape_backslashes(self):
+        self.assertEqual(
+            Utils.formataddr(('Arthur \Backslash\ Foobar', 'person at dom.ain')),
+            r'"Arthur \\Backslash\\ Foobar" <person at dom.ain>')
+        a = r'Arthur \Backslash\ Foobar'
+        b = 'person at dom.ain'
+        self.assertEqual(Utils.parseaddr(Utils.formataddr((a, b))), (a, b))
+
+    def test_name_with_dot(self):
+        x = 'John X. Doe <jxd at example.com>'
+        y = '"John X. Doe" <jxd at example.com>'
+        a, b = ('John X. Doe', 'jxd at example.com')
+        self.assertEqual(Utils.parseaddr(x), (a, b))
+        self.assertEqual(Utils.parseaddr(y), (a, b))
+        # formataddr() quotes the name if there's a dot in it
+        self.assertEqual(Utils.formataddr((a, b)), y)
+
+    def test_multiline_from_comment(self):
+        x = """\
+Foo
+\tBar <foo at example.com>"""
+        self.assertEqual(Utils.parseaddr(x), ('Foo Bar', 'foo at example.com'))
+
+    def test_quote_dump(self):
+        self.assertEqual(
+            Utils.formataddr(('A Silly; Person', 'person at dom.ain')),
+            r'"A Silly; Person" <person at dom.ain>')
+
+    def test_fix_eols(self):
+        eq = self.assertEqual
+        eq(Utils.fix_eols('hello'), 'hello')
+        eq(Utils.fix_eols('hello\n'), 'hello\r\n')
+        eq(Utils.fix_eols('hello\r'), 'hello\r\n')
+        eq(Utils.fix_eols('hello\r\n'), 'hello\r\n')
+        eq(Utils.fix_eols('hello\n\r'), 'hello\r\n\r\n')
+
+    def test_charset_richcomparisons(self):
+        eq = self.assertEqual
+        ne = self.failIfEqual
+        cset1 = Charset()
+        cset2 = Charset()
+        eq(cset1, 'us-ascii')
+        eq(cset1, 'US-ASCII')
+        eq(cset1, 'Us-AsCiI')
+        eq('us-ascii', cset1)
+        eq('US-ASCII', cset1)
+        eq('Us-AsCiI', cset1)
+        ne(cset1, 'usascii')
+        ne(cset1, 'USASCII')
+        ne(cset1, 'UsAsCiI')
+        ne('usascii', cset1)
+        ne('USASCII', cset1)
+        ne('UsAsCiI', cset1)
+        eq(cset1, cset2)
+        eq(cset2, cset1)
+
+    def test_getaddresses(self):
+        eq = self.assertEqual
+        eq(Utils.getaddresses(['aperson at dom.ain (Al Person)',
+                               'Bud Person <bperson at dom.ain>']),
+           [('Al Person', 'aperson at dom.ain'),
+            ('Bud Person', 'bperson at dom.ain')])
+
+    def test_getaddresses_nasty(self):
+        eq = self.assertEqual
+        eq(Utils.getaddresses(['foo: ;']), [('', '')])
+        eq(Utils.getaddresses(
+           ['[]*-- =~$']),
+           [('', ''), ('', ''), ('', '*--')])
+        eq(Utils.getaddresses(
+           ['foo: ;', '"Jason R. Mastaler" <jason at dom.ain>']),
+           [('', ''), ('Jason R. Mastaler', 'jason at dom.ain')])
+
+    def test_getaddresses_embedded_comment(self):
+        """Test proper handling of a nested comment"""
+        eq = self.assertEqual
+        addrs = Utils.getaddresses(['User ((nested comment)) <foo at bar.com>'])
+        eq(addrs[0][1], 'foo at bar.com')
+
+    def test_utils_quote_unquote(self):
+        eq = self.assertEqual
+        msg = Message()
+        msg.add_header('content-disposition', 'attachment',
+                       filename='foo\\wacky"name')
+        eq(msg.get_filename(), 'foo\\wacky"name')
+
+    def test_get_body_encoding_with_bogus_charset(self):
+        charset = Charset('not a charset')
+        self.assertEqual(charset.get_body_encoding(), 'base64')
+
+    def test_get_body_encoding_with_uppercase_charset(self):
+        eq = self.assertEqual
+        msg = Message()
+        msg['Content-Type'] = 'text/plain; charset=UTF-8'
+        eq(msg['content-type'], 'text/plain; charset=UTF-8')
+        charsets = msg.get_charsets()
+        eq(len(charsets), 1)
+        eq(charsets[0], 'utf-8')
+        charset = Charset(charsets[0])
+        eq(charset.get_body_encoding(), 'base64')
+        msg.set_payload('hello world', charset=charset)
+        eq(msg.get_payload(), 'aGVsbG8gd29ybGQ=\n')
+        eq(msg.get_payload(decode=True), 'hello world')
+        eq(msg['content-transfer-encoding'], 'base64')
+        # Try another one
+        msg = Message()
+        msg['Content-Type'] = 'text/plain; charset="US-ASCII"'
+        charsets = msg.get_charsets()
+        eq(len(charsets), 1)
+        eq(charsets[0], 'us-ascii')
+        charset = Charset(charsets[0])
+        eq(charset.get_body_encoding(), Encoders.encode_7or8bit)
+        msg.set_payload('hello world', charset=charset)
+        eq(msg.get_payload(), 'hello world')
+        eq(msg['content-transfer-encoding'], '7bit')
+
+    def test_charsets_case_insensitive(self):
+        lc = Charset('us-ascii')
+        uc = Charset('US-ASCII')
+        self.assertEqual(lc.get_body_encoding(), uc.get_body_encoding())
+
+    def test_partial_falls_inside_message_delivery_status(self):
+        eq = self.ndiffAssertEqual
+        # The Parser interface provides chunks of data to FeedParser in 8192
+        # byte gulps.  SF bug #1076485 found one of those chunks inside
+        # message/delivery-status header block, which triggered an
+        # unreadline() of NeedMoreData.
+        msg = self._msgobj('msg_43.txt')
+        sfp = StringIO()
+        Iterators._structure(msg, sfp)
+        eq(sfp.getvalue(), """\
+multipart/report
+    text/plain
+    message/delivery-status
+        text/plain
+        text/plain
+        text/plain
+        text/plain
+        text/plain
+        text/plain
+        text/plain
+        text/plain
+        text/plain
+        text/plain
+        text/plain
+        text/plain
+        text/plain
+        text/plain
+        text/plain
+        text/plain
+        text/plain
+        text/plain
+        text/plain
+        text/plain
+        text/plain
+        text/plain
+        text/plain
+        text/plain
+        text/plain
+        text/plain
+    text/rfc822-headers
+""")
+
+
+
+# Test the iterator/generators
+class TestIterators(TestEmailBase):
+    def test_body_line_iterator(self):
+        eq = self.assertEqual
+        neq = self.ndiffAssertEqual
+        # First a simple non-multipart message
+        msg = self._msgobj('msg_01.txt')
+        it = Iterators.body_line_iterator(msg)
+        lines = list(it)
+        eq(len(lines), 6)
+        neq(EMPTYSTRING.join(lines), msg.get_payload())
+        # Now a more complicated multipart
+        msg = self._msgobj('msg_02.txt')
+        it = Iterators.body_line_iterator(msg)
+        lines = list(it)
+        eq(len(lines), 43)
+        fp = openfile('msg_19.txt')
+        try:
+            neq(EMPTYSTRING.join(lines), fp.read())
+        finally:
+            fp.close()
+
+    def test_typed_subpart_iterator(self):
+        eq = self.assertEqual
+        msg = self._msgobj('msg_04.txt')
+        it = Iterators.typed_subpart_iterator(msg, 'text')
+        lines = []
+        subparts = 0
+        for subpart in it:
+            subparts += 1
+            lines.append(subpart.get_payload())
+        eq(subparts, 2)
+        eq(EMPTYSTRING.join(lines), """\
+a simple kind of mirror
+to reflect upon our own
+a simple kind of mirror
+to reflect upon our own
+""")
+
+    def test_typed_subpart_iterator_default_type(self):
+        eq = self.assertEqual
+        msg = self._msgobj('msg_03.txt')
+        it = Iterators.typed_subpart_iterator(msg, 'text', 'plain')
+        lines = []
+        subparts = 0
+        for subpart in it:
+            subparts += 1
+            lines.append(subpart.get_payload())
+        eq(subparts, 1)
+        eq(EMPTYSTRING.join(lines), """\
+
+Hi,
+
+Do you like this message?
+
+-Me
+""")
+
+
+
+class TestParsers(TestEmailBase):
+    def test_header_parser(self):
+        eq = self.assertEqual
+        # Parse only the headers of a complex multipart MIME document
+        fp = openfile('msg_02.txt')
+        try:
+            msg = HeaderParser().parse(fp)
+        finally:
+            fp.close()
+        eq(msg['from'], 'ppp-request at zzz.org')
+        eq(msg['to'], 'ppp at zzz.org')
+        eq(msg.get_content_type(), 'multipart/mixed')
+        self.failIf(msg.is_multipart())
+        self.failUnless(isinstance(msg.get_payload(), str))
+
+    def test_whitespace_continuation(self):
+        eq = self.assertEqual
+        # This message contains a line after the Subject: header that has only
+        # whitespace, but it is not empty!
+        msg = email.message_from_string("""\
+From: aperson at dom.ain
+To: bperson at dom.ain
+Subject: the next line has a space on it
+\x20
+Date: Mon, 8 Apr 2002 15:09:19 -0400
+Message-ID: spam
+
+Here's the message body
+""")
+        eq(msg['subject'], 'the next line has a space on it\n ')
+        eq(msg['message-id'], 'spam')
+        eq(msg.get_payload(), "Here's the message body\n")
+
+    def test_whitespace_continuation_last_header(self):
+        eq = self.assertEqual
+        # Like the previous test, but the subject line is the last
+        # header.
+        msg = email.message_from_string("""\
+From: aperson at dom.ain
+To: bperson at dom.ain
+Date: Mon, 8 Apr 2002 15:09:19 -0400
+Message-ID: spam
+Subject: the next line has a space on it
+\x20
+
+Here's the message body
+""")
+        eq(msg['subject'], 'the next line has a space on it\n ')
+        eq(msg['message-id'], 'spam')
+        eq(msg.get_payload(), "Here's the message body\n")
+
+    def test_crlf_separation(self):
+        eq = self.assertEqual
+        fp = openfile('msg_26.txt', mode='rb')
+        try:
+            msg = Parser().parse(fp)
+        finally:
+            fp.close()
+        eq(len(msg.get_payload()), 2)
+        part1 = msg.get_payload(0)
+        eq(part1.get_content_type(), 'text/plain')
+        eq(part1.get_payload(), 'Simple email with attachment.\r\n\r\n')
+        part2 = msg.get_payload(1)
+        eq(part2.get_content_type(), 'application/riscos')
+
+    def test_multipart_digest_with_extra_mime_headers(self):
+        eq = self.assertEqual
+        neq = self.ndiffAssertEqual
+        fp = openfile('msg_28.txt')
+        try:
+            msg = email.message_from_file(fp)
+        finally:
+            fp.close()
+        # Structure is:
+        # multipart/digest
+        #   message/rfc822
+        #     text/plain
+        #   message/rfc822
+        #     text/plain
+        eq(msg.is_multipart(), 1)
+        eq(len(msg.get_payload()), 2)
+        part1 = msg.get_payload(0)
+        eq(part1.get_content_type(), 'message/rfc822')
+        eq(part1.is_multipart(), 1)
+        eq(len(part1.get_payload()), 1)
+        part1a = part1.get_payload(0)
+        eq(part1a.is_multipart(), 0)
+        eq(part1a.get_content_type(), 'text/plain')
+        neq(part1a.get_payload(), 'message 1\n')
+        # next message/rfc822
+        part2 = msg.get_payload(1)
+        eq(part2.get_content_type(), 'message/rfc822')
+        eq(part2.is_multipart(), 1)
+        eq(len(part2.get_payload()), 1)
+        part2a = part2.get_payload(0)
+        eq(part2a.is_multipart(), 0)
+        eq(part2a.get_content_type(), 'text/plain')
+        neq(part2a.get_payload(), 'message 2\n')
+
+    def test_three_lines(self):
+        # A bug report by Andrew McNamara
+        lines = ['From: Andrew Person <aperson at dom.ain',
+                 'Subject: Test',
+                 'Date: Tue, 20 Aug 2002 16:43:45 +1000']
+        msg = email.message_from_string(NL.join(lines))
+        self.assertEqual(msg['date'], 'Tue, 20 Aug 2002 16:43:45 +1000')
+
+    def test_strip_line_feed_and_carriage_return_in_headers(self):
+        eq = self.assertEqual
+        # For [ 1002475 ] email message parser doesn't handle \r\n correctly
+        value1 = 'text'
+        value2 = 'more text'
+        m = 'Header: %s\r\nNext-Header: %s\r\n\r\nBody\r\n\r\n' % (
+            value1, value2)
+        msg = email.message_from_string(m)
+        eq(msg.get('Header'), value1)
+        eq(msg.get('Next-Header'), value2)
+
+    def test_rfc2822_header_syntax(self):
+        eq = self.assertEqual
+        m = '>From: foo\nFrom: bar\n!"#QUX;~: zoo\n\nbody'
+        msg = email.message_from_string(m)
+        eq(len(msg.keys()), 3)
+        keys = msg.keys()
+        keys.sort()
+        eq(keys, ['!"#QUX;~', '>From', 'From'])
+        eq(msg.get_payload(), 'body')
+
+    def test_rfc2822_space_not_allowed_in_header(self):
+        eq = self.assertEqual
+        m = '>From foo at example.com 11:25:53\nFrom: bar\n!"#QUX;~: zoo\n\nbody'
+        msg = email.message_from_string(m)
+        eq(len(msg.keys()), 0)
+
+    def test_rfc2822_one_character_header(self):
+        eq = self.assertEqual
+        m = 'A: first header\nB: second header\nCC: third header\n\nbody'
+        msg = email.message_from_string(m)
+        headers = msg.keys()
+        headers.sort()
+        eq(headers, ['A', 'B', 'CC'])
+        eq(msg.get_payload(), 'body')
+
+
+
+class TestBase64(unittest.TestCase):
+    def test_len(self):
+        eq = self.assertEqual
+        eq(base64MIME.base64_len('hello'),
+           len(base64MIME.encode('hello', eol='')))
+        for size in range(15):
+            if   size == 0 : bsize = 0
+            elif size <= 3 : bsize = 4
+            elif size <= 6 : bsize = 8
+            elif size <= 9 : bsize = 12
+            elif size <= 12: bsize = 16
+            else           : bsize = 20
+            eq(base64MIME.base64_len('x'*size), bsize)
+
+    def test_decode(self):
+        eq = self.assertEqual
+        eq(base64MIME.decode(''), '')
+        eq(base64MIME.decode('aGVsbG8='), 'hello')
+        eq(base64MIME.decode('aGVsbG8=', 'X'), 'hello')
+        eq(base64MIME.decode('aGVsbG8NCndvcmxk\n', 'X'), 'helloXworld')
+
+    def test_encode(self):
+        eq = self.assertEqual
+        eq(base64MIME.encode(''), '')
+        eq(base64MIME.encode('hello'), 'aGVsbG8=\n')
+        # Test the binary flag
+        eq(base64MIME.encode('hello\n'), 'aGVsbG8K\n')
+        eq(base64MIME.encode('hello\n', 0), 'aGVsbG8NCg==\n')
+        # Test the maxlinelen arg
+        eq(base64MIME.encode('xxxx ' * 20, maxlinelen=40), """\
+eHh4eCB4eHh4IHh4eHggeHh4eCB4eHh4IHh4eHgg
+eHh4eCB4eHh4IHh4eHggeHh4eCB4eHh4IHh4eHgg
+eHh4eCB4eHh4IHh4eHggeHh4eCB4eHh4IHh4eHgg
+eHh4eCB4eHh4IA==
+""")
+        # Test the eol argument
+        eq(base64MIME.encode('xxxx ' * 20, maxlinelen=40, eol='\r\n'), """\
+eHh4eCB4eHh4IHh4eHggeHh4eCB4eHh4IHh4eHgg\r
+eHh4eCB4eHh4IHh4eHggeHh4eCB4eHh4IHh4eHgg\r
+eHh4eCB4eHh4IHh4eHggeHh4eCB4eHh4IHh4eHgg\r
+eHh4eCB4eHh4IA==\r
+""")
+
+    def test_header_encode(self):
+        eq = self.assertEqual
+        he = base64MIME.header_encode
+        eq(he('hello'), '=?iso-8859-1?b?aGVsbG8=?=')
+        eq(he('hello\nworld'), '=?iso-8859-1?b?aGVsbG8NCndvcmxk?=')
+        # Test the charset option
+        eq(he('hello', charset='iso-8859-2'), '=?iso-8859-2?b?aGVsbG8=?=')
+        # Test the keep_eols flag
+        eq(he('hello\nworld', keep_eols=True),
+           '=?iso-8859-1?b?aGVsbG8Kd29ybGQ=?=')
+        # Test the maxlinelen argument
+        eq(he('xxxx ' * 20, maxlinelen=40), """\
+=?iso-8859-1?b?eHh4eCB4eHh4IHh4eHggeHg=?=
+ =?iso-8859-1?b?eHggeHh4eCB4eHh4IHh4eHg=?=
+ =?iso-8859-1?b?IHh4eHggeHh4eCB4eHh4IHg=?=
+ =?iso-8859-1?b?eHh4IHh4eHggeHh4eCB4eHg=?=
+ =?iso-8859-1?b?eCB4eHh4IHh4eHggeHh4eCA=?=
+ =?iso-8859-1?b?eHh4eCB4eHh4IHh4eHgg?=""")
+        # Test the eol argument
+        eq(he('xxxx ' * 20, maxlinelen=40, eol='\r\n'), """\
+=?iso-8859-1?b?eHh4eCB4eHh4IHh4eHggeHg=?=\r
+ =?iso-8859-1?b?eHggeHh4eCB4eHh4IHh4eHg=?=\r
+ =?iso-8859-1?b?IHh4eHggeHh4eCB4eHh4IHg=?=\r
+ =?iso-8859-1?b?eHh4IHh4eHggeHh4eCB4eHg=?=\r
+ =?iso-8859-1?b?eCB4eHh4IHh4eHggeHh4eCA=?=\r
+ =?iso-8859-1?b?eHh4eCB4eHh4IHh4eHgg?=""")
+
+
+
+class TestQuopri(unittest.TestCase):
+    def setUp(self):
+        self.hlit = [chr(x) for x in range(ord('a'), ord('z')+1)] + \
+                    [chr(x) for x in range(ord('A'), ord('Z')+1)] + \
+                    [chr(x) for x in range(ord('0'), ord('9')+1)] + \
+                    ['!', '*', '+', '-', '/', ' ']
+        self.hnon = [chr(x) for x in range(256) if chr(x) not in self.hlit]
+        assert len(self.hlit) + len(self.hnon) == 256
+        self.blit = [chr(x) for x in range(ord(' '), ord('~')+1)] + ['\t']
+        self.blit.remove('=')
+        self.bnon = [chr(x) for x in range(256) if chr(x) not in self.blit]
+        assert len(self.blit) + len(self.bnon) == 256
+
+    def test_header_quopri_check(self):
+        for c in self.hlit:
+            self.failIf(quopriMIME.header_quopri_check(c))
+        for c in self.hnon:
+            self.failUnless(quopriMIME.header_quopri_check(c))
+
+    def test_body_quopri_check(self):
+        for c in self.blit:
+            self.failIf(quopriMIME.body_quopri_check(c))
+        for c in self.bnon:
+            self.failUnless(quopriMIME.body_quopri_check(c))
+
+    def test_header_quopri_len(self):
+        eq = self.assertEqual
+        hql = quopriMIME.header_quopri_len
+        enc = quopriMIME.header_encode
+        for s in ('hello', 'h at e@l at l@o@'):
+            # Empty charset and no line-endings.  7 == RFC chrome
+            eq(hql(s), len(enc(s, charset='', eol=''))-7)
+        for c in self.hlit:
+            eq(hql(c), 1)
+        for c in self.hnon:
+            eq(hql(c), 3)
+
+    def test_body_quopri_len(self):
+        eq = self.assertEqual
+        bql = quopriMIME.body_quopri_len
+        for c in self.blit:
+            eq(bql(c), 1)
+        for c in self.bnon:
+            eq(bql(c), 3)
+
+    def test_quote_unquote_idempotent(self):
+        for x in range(256):
+            c = chr(x)
+            self.assertEqual(quopriMIME.unquote(quopriMIME.quote(c)), c)
+
+    def test_header_encode(self):
+        eq = self.assertEqual
+        he = quopriMIME.header_encode
+        eq(he('hello'), '=?iso-8859-1?q?hello?=')
+        eq(he('hello\nworld'), '=?iso-8859-1?q?hello=0D=0Aworld?=')
+        # Test the charset option
+        eq(he('hello', charset='iso-8859-2'), '=?iso-8859-2?q?hello?=')
+        # Test the keep_eols flag
+        eq(he('hello\nworld', keep_eols=True), '=?iso-8859-1?q?hello=0Aworld?=')
+        # Test a non-ASCII character
+        eq(he('hello\xc7there'), '=?iso-8859-1?q?hello=C7there?=')
+        # Test the maxlinelen argument
+        eq(he('xxxx ' * 20, maxlinelen=40), """\
+=?iso-8859-1?q?xxxx_xxxx_xxxx_xxxx_xx?=
+ =?iso-8859-1?q?xx_xxxx_xxxx_xxxx_xxxx?=
+ =?iso-8859-1?q?_xxxx_xxxx_xxxx_xxxx_x?=
+ =?iso-8859-1?q?xxx_xxxx_xxxx_xxxx_xxx?=
+ =?iso-8859-1?q?x_xxxx_xxxx_?=""")
+        # Test the eol argument
+        eq(he('xxxx ' * 20, maxlinelen=40, eol='\r\n'), """\
+=?iso-8859-1?q?xxxx_xxxx_xxxx_xxxx_xx?=\r
+ =?iso-8859-1?q?xx_xxxx_xxxx_xxxx_xxxx?=\r
+ =?iso-8859-1?q?_xxxx_xxxx_xxxx_xxxx_x?=\r
+ =?iso-8859-1?q?xxx_xxxx_xxxx_xxxx_xxx?=\r
+ =?iso-8859-1?q?x_xxxx_xxxx_?=""")
+
+    def test_decode(self):
+        eq = self.assertEqual
+        eq(quopriMIME.decode(''), '')
+        eq(quopriMIME.decode('hello'), 'hello')
+        eq(quopriMIME.decode('hello', 'X'), 'hello')
+        eq(quopriMIME.decode('hello\nworld', 'X'), 'helloXworld')
+
+    def test_encode(self):
+        eq = self.assertEqual
+        eq(quopriMIME.encode(''), '')
+        eq(quopriMIME.encode('hello'), 'hello')
+        # Test the binary flag
+        eq(quopriMIME.encode('hello\r\nworld'), 'hello\nworld')
+        eq(quopriMIME.encode('hello\r\nworld', 0), 'hello\nworld')
+        # Test the maxlinelen arg
+        eq(quopriMIME.encode('xxxx ' * 20, maxlinelen=40), """\
+xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx=
+ xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxx=
+x xxxx xxxx xxxx xxxx=20""")
+        # Test the eol argument
+        eq(quopriMIME.encode('xxxx ' * 20, maxlinelen=40, eol='\r\n'), """\
+xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx=\r
+ xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxx=\r
+x xxxx xxxx xxxx xxxx=20""")
+        eq(quopriMIME.encode("""\
+one line
+
+two line"""), """\
+one line
+
+two line""")
+
+
+
+# Test the Charset class
+class TestCharset(unittest.TestCase):
+    def tearDown(self):
+        from email import Charset as CharsetModule
+        try:
+            del CharsetModule.CHARSETS['fake']
+        except KeyError:
+            pass
+
+    def test_idempotent(self):
+        eq = self.assertEqual
+        # Make sure us-ascii = no Unicode conversion
+        c = Charset('us-ascii')
+        s = 'Hello World!'
+        sp = c.to_splittable(s)
+        eq(s, c.from_splittable(sp))
+        # test 8-bit idempotency with us-ascii
+        s = '\xa4\xa2\xa4\xa4\xa4\xa6\xa4\xa8\xa4\xaa'
+        sp = c.to_splittable(s)
+        eq(s, c.from_splittable(sp))
+
+    def test_body_encode(self):
+        eq = self.assertEqual
+        # Try a charset with QP body encoding
+        c = Charset('iso-8859-1')
+        eq('hello w=F6rld', c.body_encode('hello w\xf6rld'))
+        # Try a charset with Base64 body encoding
+        c = Charset('utf-8')
+        eq('aGVsbG8gd29ybGQ=\n', c.body_encode('hello world'))
+        # Try a charset with None body encoding
+        c = Charset('us-ascii')
+        eq('hello world', c.body_encode('hello world'))
+        # Try the convert argument, where input codec <> output codec
+        c = Charset('euc-jp')
+        # With apologies to Tokio Kikuchi ;)
+        try:
+            eq('\x1b$B5FCO;~IW\x1b(B',
+               c.body_encode('\xb5\xc6\xc3\xcf\xbb\xfe\xc9\xd7'))
+            eq('\xb5\xc6\xc3\xcf\xbb\xfe\xc9\xd7',
+               c.body_encode('\xb5\xc6\xc3\xcf\xbb\xfe\xc9\xd7', False))
+        except LookupError:
+            # We probably don't have the Japanese codecs installed
+            pass
+        # Testing SF bug #625509, which we have to fake, since there are no
+        # built-in encodings where the header encoding is QP but the body
+        # encoding is not.
+        from email import Charset as CharsetModule
+        CharsetModule.add_charset('fake', CharsetModule.QP, None)
+        c = Charset('fake')
+        eq('hello w\xf6rld', c.body_encode('hello w\xf6rld'))
+
+    def test_unicode_charset_name(self):
+        charset = Charset(u'us-ascii')
+        self.assertEqual(str(charset), 'us-ascii')
+        self.assertRaises(Errors.CharsetError, Charset, 'asc\xffii')
+
+
+
+# Test multilingual MIME headers.
+class TestHeader(TestEmailBase):
+    def test_simple(self):
+        eq = self.ndiffAssertEqual
+        h = Header('Hello World!')
+        eq(h.encode(), 'Hello World!')
+        h.append(' Goodbye World!')
+        eq(h.encode(), 'Hello World!  Goodbye World!')
+
+    def test_simple_surprise(self):
+        eq = self.ndiffAssertEqual
+        h = Header('Hello World!')
+        eq(h.encode(), 'Hello World!')
+        h.append('Goodbye World!')
+        eq(h.encode(), 'Hello World! Goodbye World!')
+
+    def test_header_needs_no_decoding(self):
+        h = 'no decoding needed'
+        self.assertEqual(decode_header(h), [(h, None)])
+
+    def test_long(self):
+        h = Header("I am the very model of a modern Major-General; I've information vegetable, animal, and mineral; I know the kings of England, and I quote the fights historical from Marathon to Waterloo, in order categorical; I'm very well acquainted, too, with matters mathematical; I understand equations, both the simple and quadratical; about binomial theorem I'm teeming with a lot o' news, with many cheerful facts about the square of the hypotenuse.",
+                   maxlinelen=76)
+        for l in h.encode(splitchars=' ').split('\n '):
+            self.failUnless(len(l) <= 76)
+
+    def test_multilingual(self):
+        eq = self.ndiffAssertEqual
+        g = Charset("iso-8859-1")
+        cz = Charset("iso-8859-2")
+        utf8 = Charset("utf-8")
+        g_head = "Die Mieter treten hier ein werden mit einem Foerderband komfortabel den Korridor entlang, an s\xfcdl\xfcndischen Wandgem\xe4lden vorbei, gegen die rotierenden Klingen bef\xf6rdert. "
+        cz_head = "Finan\xe8ni metropole se hroutily pod tlakem jejich d\xf9vtipu.. "
+        utf8_head = u"\u6b63\u78ba\u306b\u8a00\u3046\u3068\u7ffb\u8a33\u306f\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002\u4e00\u90e8\u306f\u30c9\u30a4\u30c4\u8a9e\u3067\u3059\u304c\u3001\u3042\u3068\u306f\u3067\u305f\u3089\u3081\u3067\u3059\u3002\u5b9f\u969b\u306b\u306f\u300cWenn ist das Nunstuck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput.\u300d\u3068\u8a00\u3063\u3066\u3044\u307e\u3059\u3002".encode("utf-8")
+        h = Header(g_head, g)
+        h.append(cz_head, cz)
+        h.append(utf8_head, utf8)
+        enc = h.encode()
+        eq(enc, """\
+=?iso-8859-1?q?Die_Mieter_treten_hier_ein_werden_mit_einem_Foerderband_ko?=
+ =?iso-8859-1?q?mfortabel_den_Korridor_entlang=2C_an_s=FCdl=FCndischen_Wan?=
+ =?iso-8859-1?q?dgem=E4lden_vorbei=2C_gegen_die_rotierenden_Klingen_bef=F6?=
+ =?iso-8859-1?q?rdert=2E_?= =?iso-8859-2?q?Finan=E8ni_metropole_se_hroutily?=
+ =?iso-8859-2?q?_pod_tlakem_jejich_d=F9vtipu=2E=2E_?= =?utf-8?b?5q2j56K6?=
+ =?utf-8?b?44Gr6KiA44GG44Go57+76Kiz44Gv44GV44KM44Gm44GE44G+44Gb44KT44CC?=
+ =?utf-8?b?5LiA6YOo44Gv44OJ44Kk44OE6Kqe44Gn44GZ44GM44CB44GC44Go44Gv44Gn?=
+ =?utf-8?b?44Gf44KJ44KB44Gn44GZ44CC5a6f6Zqb44Gr44Gv44CMV2VubiBpc3QgZGFz?=
+ =?utf-8?q?_Nunstuck_git_und_Slotermeyer=3F_Ja!_Beiherhund_das_Oder_die_Fl?=
+ =?utf-8?b?aXBwZXJ3YWxkdCBnZXJzcHV0LuOAjeOBqOiogOOBo+OBpuOBhOOBvuOBmQ==?=
+ =?utf-8?b?44CC?=""")
+        eq(decode_header(enc),
+           [(g_head, "iso-8859-1"), (cz_head, "iso-8859-2"),
+            (utf8_head, "utf-8")])
+        ustr = unicode(h)
+        eq(ustr.encode('utf-8'),
+           'Die Mieter treten hier ein werden mit einem Foerderband '
+           'komfortabel den Korridor entlang, an s\xc3\xbcdl\xc3\xbcndischen '
+           'Wandgem\xc3\xa4lden vorbei, gegen die rotierenden Klingen '
+           'bef\xc3\xb6rdert. Finan\xc4\x8dni metropole se hroutily pod '
+           'tlakem jejich d\xc5\xafvtipu.. \xe6\xad\xa3\xe7\xa2\xba\xe3\x81'
+           '\xab\xe8\xa8\x80\xe3\x81\x86\xe3\x81\xa8\xe7\xbf\xbb\xe8\xa8\xb3'
+           '\xe3\x81\xaf\xe3\x81\x95\xe3\x82\x8c\xe3\x81\xa6\xe3\x81\x84\xe3'
+           '\x81\xbe\xe3\x81\x9b\xe3\x82\x93\xe3\x80\x82\xe4\xb8\x80\xe9\x83'
+           '\xa8\xe3\x81\xaf\xe3\x83\x89\xe3\x82\xa4\xe3\x83\x84\xe8\xaa\x9e'
+           '\xe3\x81\xa7\xe3\x81\x99\xe3\x81\x8c\xe3\x80\x81\xe3\x81\x82\xe3'
+           '\x81\xa8\xe3\x81\xaf\xe3\x81\xa7\xe3\x81\x9f\xe3\x82\x89\xe3\x82'
+           '\x81\xe3\x81\xa7\xe3\x81\x99\xe3\x80\x82\xe5\xae\x9f\xe9\x9a\x9b'
+           '\xe3\x81\xab\xe3\x81\xaf\xe3\x80\x8cWenn ist das Nunstuck git '
+           'und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt '
+           'gersput.\xe3\x80\x8d\xe3\x81\xa8\xe8\xa8\x80\xe3\x81\xa3\xe3\x81'
+           '\xa6\xe3\x81\x84\xe3\x81\xbe\xe3\x81\x99\xe3\x80\x82')
+        # Test make_header()
+        newh = make_header(decode_header(enc))
+        eq(newh, enc)
+
+    def test_header_ctor_default_args(self):
+        eq = self.ndiffAssertEqual
+        h = Header()
+        eq(h, '')
+        h.append('foo', Charset('iso-8859-1'))
+        eq(h, '=?iso-8859-1?q?foo?=')
+
+    def test_explicit_maxlinelen(self):
+        eq = self.ndiffAssertEqual
+        hstr = 'A very long line that must get split to something other than at the 76th character boundary to test the non-default behavior'
+        h = Header(hstr)
+        eq(h.encode(), '''\
+A very long line that must get split to something other than at the 76th
+ character boundary to test the non-default behavior''')
+        h = Header(hstr, header_name='Subject')
+        eq(h.encode(), '''\
+A very long line that must get split to something other than at the
+ 76th character boundary to test the non-default behavior''')
+        h = Header(hstr, maxlinelen=1024, header_name='Subject')
+        eq(h.encode(), hstr)
+
+    def test_us_ascii_header(self):
+        eq = self.assertEqual
+        s = 'hello'
+        x = decode_header(s)
+        eq(x, [('hello', None)])
+        h = make_header(x)
+        eq(s, h.encode())
+
+    def test_string_charset(self):
+        eq = self.assertEqual
+        h = Header()
+        h.append('hello', 'iso-8859-1')
+        eq(h, '=?iso-8859-1?q?hello?=')
+
+##    def test_unicode_error(self):
+##        raises = self.assertRaises
+##        raises(UnicodeError, Header, u'[P\xf6stal]', 'us-ascii')
+##        raises(UnicodeError, Header, '[P\xf6stal]', 'us-ascii')
+##        h = Header()
+##        raises(UnicodeError, h.append, u'[P\xf6stal]', 'us-ascii')
+##        raises(UnicodeError, h.append, '[P\xf6stal]', 'us-ascii')
+##        raises(UnicodeError, Header, u'\u83ca\u5730\u6642\u592b', 'iso-8859-1')
+
+    def test_utf8_shortest(self):
+        eq = self.assertEqual
+        h = Header(u'p\xf6stal', 'utf-8')
+        eq(h.encode(), '=?utf-8?q?p=C3=B6stal?=')
+        h = Header(u'\u83ca\u5730\u6642\u592b', 'utf-8')
+        eq(h.encode(), '=?utf-8?b?6I+K5Zyw5pmC5aSr?=')
+
+    def test_bad_8bit_header(self):
+        raises = self.assertRaises
+        eq = self.assertEqual
+        x = 'Ynwp4dUEbay Auction Semiar- No Charge \x96 Earn Big'
+        raises(UnicodeError, Header, x)
+        h = Header()
+        raises(UnicodeError, h.append, x)
+        eq(str(Header(x, errors='replace')), x)
+        h.append(x, errors='replace')
+        eq(str(h), x)
+
+    def test_encoded_adjacent_nonencoded(self):
+        eq = self.assertEqual
+        h = Header()
+        h.append('hello', 'iso-8859-1')
+        h.append('world')
+        s = h.encode()
+        eq(s, '=?iso-8859-1?q?hello?= world')
+        h = make_header(decode_header(s))
+        eq(h.encode(), s)
+
+    def test_whitespace_eater(self):
+        eq = self.assertEqual
+        s = 'Subject: =?koi8-r?b?8NLP18XSy8EgzsEgxsnOwczYztk=?= =?koi8-r?q?=CA?= zz.'
+        parts = decode_header(s)
+        eq(parts, [('Subject:', None), ('\xf0\xd2\xcf\xd7\xc5\xd2\xcb\xc1 \xce\xc1 \xc6\xc9\xce\xc1\xcc\xd8\xce\xd9\xca', 'koi8-r'), ('zz.', None)])
+        hdr = make_header(parts)
+        eq(hdr.encode(),
+           'Subject: =?koi8-r?b?8NLP18XSy8EgzsEgxsnOwczYztnK?= zz.')
+
+    def test_broken_base64_header(self):
+        raises = self.assertRaises
+        s = 'Subject: =?EUC-KR?B?CSixpLDtKSC/7Liuvsax4iC6uLmwMcijIKHaILzSwd/H0SC8+LCjwLsgv7W/+Mj3IQ?='
+        raises(Errors.HeaderParseError, decode_header, s)
+
+
+
+# Test RFC 2231 header parameters (en/de)coding
+class TestRFC2231(TestEmailBase):
+    def test_get_param(self):
+        eq = self.assertEqual
+        msg = self._msgobj('msg_29.txt')
+        eq(msg.get_param('title'),
+           ('us-ascii', 'en', 'This is even more ***fun*** isn\'t it!'))
+        eq(msg.get_param('title', unquote=False),
+           ('us-ascii', 'en', '"This is even more ***fun*** isn\'t it!"'))
+
+    def test_set_param(self):
+        eq = self.assertEqual
+        msg = Message()
+        msg.set_param('title', 'This is even more ***fun*** isn\'t it!',
+                      charset='us-ascii')
+        eq(msg.get_param('title'),
+           ('us-ascii', '', 'This is even more ***fun*** isn\'t it!'))
+        msg.set_param('title', 'This is even more ***fun*** isn\'t it!',
+                      charset='us-ascii', language='en')
+        eq(msg.get_param('title'),
+           ('us-ascii', 'en', 'This is even more ***fun*** isn\'t it!'))
+        msg = self._msgobj('msg_01.txt')
+        msg.set_param('title', 'This is even more ***fun*** isn\'t it!',
+                      charset='us-ascii', language='en')
+        eq(msg.as_string(), """\
+Return-Path: <bbb at zzz.org>
+Delivered-To: bbb at zzz.org
+Received: by mail.zzz.org (Postfix, from userid 889)
+\tid 27CEAD38CC; Fri,  4 May 2001 14:05:44 -0400 (EDT)
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+Message-ID: <15090.61304.110929.45684 at aaa.zzz.org>
+From: bbb at ddd.com (John X. Doe)
+To: bbb at zzz.org
+Subject: This is a test message
+Date: Fri, 4 May 2001 14:05:44 -0400
+Content-Type: text/plain; charset=us-ascii;
+\ttitle*="us-ascii'en'This%20is%20even%20more%20%2A%2A%2Afun%2A%2A%2A%20isn%27t%20it%21"
+
+
+Hi,
+
+Do you like this message?
+
+-Me
+""")
+
+    def test_del_param(self):
+        eq = self.ndiffAssertEqual
+        msg = self._msgobj('msg_01.txt')
+        msg.set_param('foo', 'bar', charset='us-ascii', language='en')
+        msg.set_param('title', 'This is even more ***fun*** isn\'t it!',
+            charset='us-ascii', language='en')
+        msg.del_param('foo', header='Content-Type')
+        eq(msg.as_string(), """\
+Return-Path: <bbb at zzz.org>
+Delivered-To: bbb at zzz.org
+Received: by mail.zzz.org (Postfix, from userid 889)
+\tid 27CEAD38CC; Fri,  4 May 2001 14:05:44 -0400 (EDT)
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+Message-ID: <15090.61304.110929.45684 at aaa.zzz.org>
+From: bbb at ddd.com (John X. Doe)
+To: bbb at zzz.org
+Subject: This is a test message
+Date: Fri, 4 May 2001 14:05:44 -0400
+Content-Type: text/plain; charset="us-ascii";
+\ttitle*="us-ascii'en'This%20is%20even%20more%20%2A%2A%2Afun%2A%2A%2A%20isn%27t%20it%21"
+
+
+Hi,
+
+Do you like this message?
+
+-Me
+""")
+
+    def test_rfc2231_get_content_charset(self):
+        eq = self.assertEqual
+        msg = self._msgobj('msg_32.txt')
+        eq(msg.get_content_charset(), 'us-ascii')
+
+    def test_rfc2231_no_language_or_charset(self):
+        m = '''\
+Content-Transfer-Encoding: 8bit
+Content-Disposition: inline; filename="file____C__DOCUMENTS_20AND_20SETTINGS_FABIEN_LOCAL_20SETTINGS_TEMP_nsmail.htm"
+Content-Type: text/html; NAME*0=file____C__DOCUMENTS_20AND_20SETTINGS_FABIEN_LOCAL_20SETTINGS_TEM; NAME*1=P_nsmail.htm
+
+'''
+        msg = email.message_from_string(m)
+        param = msg.get_param('NAME')
+        self.failIf(isinstance(param, tuple))
+        self.assertEqual(
+            param,
+            'file____C__DOCUMENTS_20AND_20SETTINGS_FABIEN_LOCAL_20SETTINGS_TEMP_nsmail.htm')
+
+    def test_rfc2231_no_language_or_charset_in_filename(self):
+        m = '''\
+Content-Disposition: inline;
+\tfilename*0*="''This%20is%20even%20more%20";
+\tfilename*1*="%2A%2A%2Afun%2A%2A%2A%20";
+\tfilename*2="is it not.pdf"
+
+'''
+        msg = email.message_from_string(m)
+        self.assertEqual(msg.get_filename(),
+                         'This is even more ***fun*** is it not.pdf')
+
+    def test_rfc2231_no_language_or_charset_in_filename_encoded(self):
+        m = '''\
+Content-Disposition: inline;
+\tfilename*0*="''This%20is%20even%20more%20";
+\tfilename*1*="%2A%2A%2Afun%2A%2A%2A%20";
+\tfilename*2="is it not.pdf"
+
+'''
+        msg = email.message_from_string(m)
+        self.assertEqual(msg.get_filename(),
+                         'This is even more ***fun*** is it not.pdf')
+
+    def test_rfc2231_partly_encoded(self):
+        m = '''\
+Content-Disposition: inline;
+\tfilename*0="''This%20is%20even%20more%20";
+\tfilename*1*="%2A%2A%2Afun%2A%2A%2A%20";
+\tfilename*2="is it not.pdf"
+
+'''
+        msg = email.message_from_string(m)
+        self.assertEqual(
+            msg.get_filename(),
+            'This%20is%20even%20more%20***fun*** is it not.pdf')
+
+    def test_rfc2231_partly_nonencoded(self):
+        m = '''\
+Content-Disposition: inline;
+\tfilename*0="This%20is%20even%20more%20";
+\tfilename*1="%2A%2A%2Afun%2A%2A%2A%20";
+\tfilename*2="is it not.pdf"
+
+'''
+        msg = email.message_from_string(m)
+        self.assertEqual(
+            msg.get_filename(),
+            'This%20is%20even%20more%20%2A%2A%2Afun%2A%2A%2A%20is it not.pdf')
+
+    def test_rfc2231_no_language_or_charset_in_boundary(self):
+        m = '''\
+Content-Type: multipart/alternative;
+\tboundary*0*="''This%20is%20even%20more%20";
+\tboundary*1*="%2A%2A%2Afun%2A%2A%2A%20";
+\tboundary*2="is it not.pdf"
+
+'''
+        msg = email.message_from_string(m)
+        self.assertEqual(msg.get_boundary(),
+                         'This is even more ***fun*** is it not.pdf')
+
+    def test_rfc2231_no_language_or_charset_in_charset(self):
+        # This is a nonsensical charset value, but tests the code anyway
+        m = '''\
+Content-Type: text/plain;
+\tcharset*0*="This%20is%20even%20more%20";
+\tcharset*1*="%2A%2A%2Afun%2A%2A%2A%20";
+\tcharset*2="is it not.pdf"
+
+'''
+        msg = email.message_from_string(m)
+        self.assertEqual(msg.get_content_charset(),
+                         'this is even more ***fun*** is it not.pdf')
+
+    def test_rfc2231_bad_encoding_in_filename(self):
+        m = '''\
+Content-Disposition: inline;
+\tfilename*0*="bogus'xx'This%20is%20even%20more%20";
+\tfilename*1*="%2A%2A%2Afun%2A%2A%2A%20";
+\tfilename*2="is it not.pdf"
+
+'''
+        msg = email.message_from_string(m)
+        self.assertEqual(msg.get_filename(),
+                         'This is even more ***fun*** is it not.pdf')
+
+    def test_rfc2231_bad_encoding_in_charset(self):
+        m = """\
+Content-Type: text/plain; charset*=bogus''utf-8%E2%80%9D
+
+"""
+        msg = email.message_from_string(m)
+        # This should return None because non-ascii characters in the charset
+        # are not allowed.
+        self.assertEqual(msg.get_content_charset(), None)
+
+    def test_rfc2231_bad_character_in_charset(self):
+        m = """\
+Content-Type: text/plain; charset*=ascii''utf-8%E2%80%9D
+
+"""
+        msg = email.message_from_string(m)
+        # This should return None because non-ascii characters in the charset
+        # are not allowed.
+        self.assertEqual(msg.get_content_charset(), None)
+
+    def test_rfc2231_bad_character_in_filename(self):
+        m = '''\
+Content-Disposition: inline;
+\tfilename*0*="ascii'xx'This%20is%20even%20more%20";
+\tfilename*1*="%2A%2A%2Afun%2A%2A%2A%20";
+\tfilename*2*="is it not.pdf%E2"
+
+'''
+        msg = email.message_from_string(m)
+        self.assertEqual(msg.get_filename(),
+                         u'This is even more ***fun*** is it not.pdf\ufffd')
+
+    def test_rfc2231_unknown_encoding(self):
+        m = """\
+Content-Transfer-Encoding: 8bit
+Content-Disposition: inline; filename*=X-UNKNOWN''myfile.txt
+
+"""
+        msg = email.message_from_string(m)
+        self.assertEqual(msg.get_filename(), 'myfile.txt')
+
+    def test_rfc2231_single_tick_in_filename_extended(self):
+        eq = self.assertEqual
+        m = """\
+Content-Type: application/x-foo;
+\tname*0*=\"Frank's\"; name*1*=\" Document\"
+
+"""
+        msg = email.message_from_string(m)
+        charset, language, s = msg.get_param('name')
+        eq(charset, None)
+        eq(language, None)
+        eq(s, "Frank's Document")
+
+    def test_rfc2231_single_tick_in_filename(self):
+        m = """\
+Content-Type: application/x-foo; name*0=\"Frank's\"; name*1=\" Document\"
+
+"""
+        msg = email.message_from_string(m)
+        param = msg.get_param('name')
+        self.failIf(isinstance(param, tuple))
+        self.assertEqual(param, "Frank's Document")
+
+    def test_rfc2231_tick_attack_extended(self):
+        eq = self.assertEqual
+        m = """\
+Content-Type: application/x-foo;
+\tname*0*=\"us-ascii'en-us'Frank's\"; name*1*=\" Document\"
+
+"""
+        msg = email.message_from_string(m)
+        charset, language, s = msg.get_param('name')
+        eq(charset, 'us-ascii')
+        eq(language, 'en-us')
+        eq(s, "Frank's Document")
+
+    def test_rfc2231_tick_attack(self):
+        m = """\
+Content-Type: application/x-foo;
+\tname*0=\"us-ascii'en-us'Frank's\"; name*1=\" Document\"
+
+"""
+        msg = email.message_from_string(m)
+        param = msg.get_param('name')
+        self.failIf(isinstance(param, tuple))
+        self.assertEqual(param, "us-ascii'en-us'Frank's Document")
+
+    def test_rfc2231_no_extended_values(self):
+        eq = self.assertEqual
+        m = """\
+Content-Type: application/x-foo; name=\"Frank's Document\"
+
+"""
+        msg = email.message_from_string(m)
+        eq(msg.get_param('name'), "Frank's Document")
+
+    def test_rfc2231_encoded_then_unencoded_segments(self):
+        eq = self.assertEqual
+        m = """\
+Content-Type: application/x-foo;
+\tname*0*=\"us-ascii'en-us'My\";
+\tname*1=\" Document\";
+\tname*2*=\" For You\"
+
+"""
+        msg = email.message_from_string(m)
+        charset, language, s = msg.get_param('name')
+        eq(charset, 'us-ascii')
+        eq(language, 'en-us')
+        eq(s, 'My Document For You')
+
+    def test_rfc2231_unencoded_then_encoded_segments(self):
+        eq = self.assertEqual
+        m = """\
+Content-Type: application/x-foo;
+\tname*0=\"us-ascii'en-us'My\";
+\tname*1*=\" Document\";
+\tname*2*=\" For You\"
+
+"""
+        msg = email.message_from_string(m)
+        charset, language, s = msg.get_param('name')
+        eq(charset, 'us-ascii')
+        eq(language, 'en-us')
+        eq(s, 'My Document For You')
+
+
+
+def _testclasses():
+    mod = sys.modules[__name__]
+    return [getattr(mod, name) for name in dir(mod) if name.startswith('Test')]
+
+
+def suite():
+    suite = unittest.TestSuite()
+    for testclass in _testclasses():
+        suite.addTest(unittest.makeSuite(testclass))
+    return suite
+
+
+def test_main():
+    for testclass in _testclasses():
+        run_unittest(testclass)
+
+
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='suite')

Added: vendor/Python/current/Lib/email/test/test_email_codecs.py
===================================================================
--- vendor/Python/current/Lib/email/test/test_email_codecs.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/test/test_email_codecs.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,77 @@
+# Copyright (C) 2002-2006 Python Software Foundation
+# Contact: email-sig at python.org
+# email package unit tests for (optional) Asian codecs
+
+import unittest
+from test.test_support import TestSkipped, run_unittest
+
+from email.test.test_email import TestEmailBase
+from email.Charset import Charset
+from email.Header import Header, decode_header
+from email.Message import Message
+
+# We're compatible with Python 2.3, but it doesn't have the built-in Asian
+# codecs, so we have to skip all these tests.
+try:
+    unicode('foo', 'euc-jp')
+except LookupError:
+    raise TestSkipped
+
+
+
+class TestEmailAsianCodecs(TestEmailBase):
+    def test_japanese_codecs(self):
+        eq = self.ndiffAssertEqual
+        j = Charset("euc-jp")
+        g = Charset("iso-8859-1")
+        h = Header("Hello World!")
+        jhello = '\xa5\xcf\xa5\xed\xa1\xbc\xa5\xef\xa1\xbc\xa5\xeb\xa5\xc9\xa1\xaa'
+        ghello = 'Gr\xfc\xdf Gott!'
+        h.append(jhello, j)
+        h.append(ghello, g)
+        # BAW: This used to -- and maybe should -- fold the two iso-8859-1
+        # chunks into a single encoded word.  However it doesn't violate the
+        # standard to have them as two encoded chunks and maybe it's
+        # reasonable <wink> for each .append() call to result in a separate
+        # encoded word.
+        eq(h.encode(), """\
+Hello World! =?iso-2022-jp?b?GyRCJU8lbSE8JW8hPCVrJUkhKhsoQg==?=
+ =?iso-8859-1?q?Gr=FC=DF?= =?iso-8859-1?q?_Gott!?=""")
+        eq(decode_header(h.encode()),
+           [('Hello World!', None),
+            ('\x1b$B%O%m!<%o!<%k%I!*\x1b(B', 'iso-2022-jp'),
+            ('Gr\xfc\xdf Gott!', 'iso-8859-1')])
+        long = 'test-ja \xa4\xd8\xc5\xea\xb9\xc6\xa4\xb5\xa4\xec\xa4\xbf\xa5\xe1\xa1\xbc\xa5\xeb\xa4\xcf\xbb\xca\xb2\xf1\xbc\xd4\xa4\xce\xbe\xb5\xc7\xa7\xa4\xf2\xc2\xd4\xa4\xc3\xa4\xc6\xa4\xa4\xa4\xde\xa4\xb9'
+        h = Header(long, j, header_name="Subject")
+        # test a very long header
+        enc = h.encode()
+        # TK: splitting point may differ by codec design and/or Header encoding
+        eq(enc , """\
+=?iso-2022-jp?b?dGVzdC1qYSAbJEIkWEVqOUYkNSRsJD8lYSE8JWskTztKGyhC?=
+ =?iso-2022-jp?b?GyRCMnE8VCROPjVHJyRyQlQkQyRGJCQkXiQ5GyhC?=""")
+        # TK: full decode comparison
+        eq(h.__unicode__().encode('euc-jp'), long)
+
+    def test_payload_encoding(self):
+        jhello = '\xa5\xcf\xa5\xed\xa1\xbc\xa5\xef\xa1\xbc\xa5\xeb\xa5\xc9\xa1\xaa'
+        jcode  = 'euc-jp'
+        msg = Message()
+        msg.set_payload(jhello, jcode)
+        ustr = unicode(msg.get_payload(), msg.get_content_charset())
+        self.assertEqual(jhello, ustr.encode(jcode))
+
+
+
+def suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(TestEmailAsianCodecs))
+    return suite
+
+
+def test_main():
+    run_unittest(TestEmailAsianCodecs)
+
+
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='suite')

Added: vendor/Python/current/Lib/email/test/test_email_codecs_renamed.py
===================================================================
--- vendor/Python/current/Lib/email/test/test_email_codecs_renamed.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/test/test_email_codecs_renamed.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,77 @@
+# Copyright (C) 2002-2006 Python Software Foundation
+# Contact: email-sig at python.org
+# email package unit tests for (optional) Asian codecs
+
+import unittest
+from test.test_support import TestSkipped, run_unittest
+
+from email.test.test_email import TestEmailBase
+from email.charset import Charset
+from email.header import Header, decode_header
+from email.message import Message
+
+# We're compatible with Python 2.3, but it doesn't have the built-in Asian
+# codecs, so we have to skip all these tests.
+try:
+    unicode('foo', 'euc-jp')
+except LookupError:
+    raise TestSkipped
+
+
+
+class TestEmailAsianCodecs(TestEmailBase):
+    def test_japanese_codecs(self):
+        eq = self.ndiffAssertEqual
+        j = Charset("euc-jp")
+        g = Charset("iso-8859-1")
+        h = Header("Hello World!")
+        jhello = '\xa5\xcf\xa5\xed\xa1\xbc\xa5\xef\xa1\xbc\xa5\xeb\xa5\xc9\xa1\xaa'
+        ghello = 'Gr\xfc\xdf Gott!'
+        h.append(jhello, j)
+        h.append(ghello, g)
+        # BAW: This used to -- and maybe should -- fold the two iso-8859-1
+        # chunks into a single encoded word.  However it doesn't violate the
+        # standard to have them as two encoded chunks and maybe it's
+        # reasonable <wink> for each .append() call to result in a separate
+        # encoded word.
+        eq(h.encode(), """\
+Hello World! =?iso-2022-jp?b?GyRCJU8lbSE8JW8hPCVrJUkhKhsoQg==?=
+ =?iso-8859-1?q?Gr=FC=DF?= =?iso-8859-1?q?_Gott!?=""")
+        eq(decode_header(h.encode()),
+           [('Hello World!', None),
+            ('\x1b$B%O%m!<%o!<%k%I!*\x1b(B', 'iso-2022-jp'),
+            ('Gr\xfc\xdf Gott!', 'iso-8859-1')])
+        long = 'test-ja \xa4\xd8\xc5\xea\xb9\xc6\xa4\xb5\xa4\xec\xa4\xbf\xa5\xe1\xa1\xbc\xa5\xeb\xa4\xcf\xbb\xca\xb2\xf1\xbc\xd4\xa4\xce\xbe\xb5\xc7\xa7\xa4\xf2\xc2\xd4\xa4\xc3\xa4\xc6\xa4\xa4\xa4\xde\xa4\xb9'
+        h = Header(long, j, header_name="Subject")
+        # test a very long header
+        enc = h.encode()
+        # TK: splitting point may differ by codec design and/or Header encoding
+        eq(enc , """\
+=?iso-2022-jp?b?dGVzdC1qYSAbJEIkWEVqOUYkNSRsJD8lYSE8JWskTztKGyhC?=
+ =?iso-2022-jp?b?GyRCMnE8VCROPjVHJyRyQlQkQyRGJCQkXiQ5GyhC?=""")
+        # TK: full decode comparison
+        eq(h.__unicode__().encode('euc-jp'), long)
+
+    def test_payload_encoding(self):
+        jhello = '\xa5\xcf\xa5\xed\xa1\xbc\xa5\xef\xa1\xbc\xa5\xeb\xa5\xc9\xa1\xaa'
+        jcode  = 'euc-jp'
+        msg = Message()
+        msg.set_payload(jhello, jcode)
+        ustr = unicode(msg.get_payload(), msg.get_content_charset())
+        self.assertEqual(jhello, ustr.encode(jcode))
+
+
+
+def suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(TestEmailAsianCodecs))
+    return suite
+
+
+def test_main():
+    run_unittest(TestEmailAsianCodecs)
+
+
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='suite')

Added: vendor/Python/current/Lib/email/test/test_email_renamed.py
===================================================================
--- vendor/Python/current/Lib/email/test/test_email_renamed.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/test/test_email_renamed.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,3273 @@
+# Copyright (C) 2001-2007 Python Software Foundation
+# Contact: email-sig at python.org
+# email package unit tests
+
+import os
+import sys
+import time
+import base64
+import difflib
+import unittest
+import warnings
+from cStringIO import StringIO
+
+import email
+
+from email.charset import Charset
+from email.header import Header, decode_header, make_header
+from email.parser import Parser, HeaderParser
+from email.generator import Generator, DecodedGenerator
+from email.message import Message
+from email.mime.application import MIMEApplication
+from email.mime.audio import MIMEAudio
+from email.mime.text import MIMEText
+from email.mime.image import MIMEImage
+from email.mime.base import MIMEBase
+from email.mime.message import MIMEMessage
+from email.mime.multipart import MIMEMultipart
+from email import utils
+from email import errors
+from email import encoders
+from email import iterators
+from email import base64mime
+from email import quoprimime
+
+from test.test_support import findfile, run_unittest
+from email.test import __file__ as landmark
+
+
+NL = '\n'
+EMPTYSTRING = ''
+SPACE = ' '
+
+
+
+def openfile(filename, mode='r'):
+    path = os.path.join(os.path.dirname(landmark), 'data', filename)
+    return open(path, mode)
+
+
+
+# Base test class
+class TestEmailBase(unittest.TestCase):
+    def ndiffAssertEqual(self, first, second):
+        """Like failUnlessEqual except use ndiff for readable output."""
+        if first <> second:
+            sfirst = str(first)
+            ssecond = str(second)
+            diff = difflib.ndiff(sfirst.splitlines(), ssecond.splitlines())
+            fp = StringIO()
+            print >> fp, NL, NL.join(diff)
+            raise self.failureException, fp.getvalue()
+
+    def _msgobj(self, filename):
+        fp = openfile(findfile(filename))
+        try:
+            msg = email.message_from_file(fp)
+        finally:
+            fp.close()
+        return msg
+
+
+
+# Test various aspects of the Message class's API
+class TestMessageAPI(TestEmailBase):
+    def test_get_all(self):
+        eq = self.assertEqual
+        msg = self._msgobj('msg_20.txt')
+        eq(msg.get_all('cc'), ['ccc at zzz.org', 'ddd at zzz.org', 'eee at zzz.org'])
+        eq(msg.get_all('xx', 'n/a'), 'n/a')
+
+    def test_getset_charset(self):
+        eq = self.assertEqual
+        msg = Message()
+        eq(msg.get_charset(), None)
+        charset = Charset('iso-8859-1')
+        msg.set_charset(charset)
+        eq(msg['mime-version'], '1.0')
+        eq(msg.get_content_type(), 'text/plain')
+        eq(msg['content-type'], 'text/plain; charset="iso-8859-1"')
+        eq(msg.get_param('charset'), 'iso-8859-1')
+        eq(msg['content-transfer-encoding'], 'quoted-printable')
+        eq(msg.get_charset().input_charset, 'iso-8859-1')
+        # Remove the charset
+        msg.set_charset(None)
+        eq(msg.get_charset(), None)
+        eq(msg['content-type'], 'text/plain')
+        # Try adding a charset when there's already MIME headers present
+        msg = Message()
+        msg['MIME-Version'] = '2.0'
+        msg['Content-Type'] = 'text/x-weird'
+        msg['Content-Transfer-Encoding'] = 'quinted-puntable'
+        msg.set_charset(charset)
+        eq(msg['mime-version'], '2.0')
+        eq(msg['content-type'], 'text/x-weird; charset="iso-8859-1"')
+        eq(msg['content-transfer-encoding'], 'quinted-puntable')
+
+    def test_set_charset_from_string(self):
+        eq = self.assertEqual
+        msg = Message()
+        msg.set_charset('us-ascii')
+        eq(msg.get_charset().input_charset, 'us-ascii')
+        eq(msg['content-type'], 'text/plain; charset="us-ascii"')
+
+    def test_set_payload_with_charset(self):
+        msg = Message()
+        charset = Charset('iso-8859-1')
+        msg.set_payload('This is a string payload', charset)
+        self.assertEqual(msg.get_charset().input_charset, 'iso-8859-1')
+
+    def test_get_charsets(self):
+        eq = self.assertEqual
+
+        msg = self._msgobj('msg_08.txt')
+        charsets = msg.get_charsets()
+        eq(charsets, [None, 'us-ascii', 'iso-8859-1', 'iso-8859-2', 'koi8-r'])
+
+        msg = self._msgobj('msg_09.txt')
+        charsets = msg.get_charsets('dingbat')
+        eq(charsets, ['dingbat', 'us-ascii', 'iso-8859-1', 'dingbat',
+                      'koi8-r'])
+
+        msg = self._msgobj('msg_12.txt')
+        charsets = msg.get_charsets()
+        eq(charsets, [None, 'us-ascii', 'iso-8859-1', None, 'iso-8859-2',
+                      'iso-8859-3', 'us-ascii', 'koi8-r'])
+
+    def test_get_filename(self):
+        eq = self.assertEqual
+
+        msg = self._msgobj('msg_04.txt')
+        filenames = [p.get_filename() for p in msg.get_payload()]
+        eq(filenames, ['msg.txt', 'msg.txt'])
+
+        msg = self._msgobj('msg_07.txt')
+        subpart = msg.get_payload(1)
+        eq(subpart.get_filename(), 'dingusfish.gif')
+
+    def test_get_filename_with_name_parameter(self):
+        eq = self.assertEqual
+
+        msg = self._msgobj('msg_44.txt')
+        filenames = [p.get_filename() for p in msg.get_payload()]
+        eq(filenames, ['msg.txt', 'msg.txt'])
+
+    def test_get_boundary(self):
+        eq = self.assertEqual
+        msg = self._msgobj('msg_07.txt')
+        # No quotes!
+        eq(msg.get_boundary(), 'BOUNDARY')
+
+    def test_set_boundary(self):
+        eq = self.assertEqual
+        # This one has no existing boundary parameter, but the Content-Type:
+        # header appears fifth.
+        msg = self._msgobj('msg_01.txt')
+        msg.set_boundary('BOUNDARY')
+        header, value = msg.items()[4]
+        eq(header.lower(), 'content-type')
+        eq(value, 'text/plain; charset="us-ascii"; boundary="BOUNDARY"')
+        # This one has a Content-Type: header, with a boundary, stuck in the
+        # middle of its headers.  Make sure the order is preserved; it should
+        # be fifth.
+        msg = self._msgobj('msg_04.txt')
+        msg.set_boundary('BOUNDARY')
+        header, value = msg.items()[4]
+        eq(header.lower(), 'content-type')
+        eq(value, 'multipart/mixed; boundary="BOUNDARY"')
+        # And this one has no Content-Type: header at all.
+        msg = self._msgobj('msg_03.txt')
+        self.assertRaises(errors.HeaderParseError,
+                          msg.set_boundary, 'BOUNDARY')
+
+    def test_get_decoded_payload(self):
+        eq = self.assertEqual
+        msg = self._msgobj('msg_10.txt')
+        # The outer message is a multipart
+        eq(msg.get_payload(decode=True), None)
+        # Subpart 1 is 7bit encoded
+        eq(msg.get_payload(0).get_payload(decode=True),
+           'This is a 7bit encoded message.\n')
+        # Subpart 2 is quopri
+        eq(msg.get_payload(1).get_payload(decode=True),
+           '\xa1This is a Quoted Printable encoded message!\n')
+        # Subpart 3 is base64
+        eq(msg.get_payload(2).get_payload(decode=True),
+           'This is a Base64 encoded message.')
+        # Subpart 4 has no Content-Transfer-Encoding: header.
+        eq(msg.get_payload(3).get_payload(decode=True),
+           'This has no Content-Transfer-Encoding: header.\n')
+
+    def test_get_decoded_uu_payload(self):
+        eq = self.assertEqual
+        msg = Message()
+        msg.set_payload('begin 666 -\n+:&5L;&\\@=V]R;&0 \n \nend\n')
+        for cte in ('x-uuencode', 'uuencode', 'uue', 'x-uue'):
+            msg['content-transfer-encoding'] = cte
+            eq(msg.get_payload(decode=True), 'hello world')
+        # Now try some bogus data
+        msg.set_payload('foo')
+        eq(msg.get_payload(decode=True), 'foo')
+
+    def test_decoded_generator(self):
+        eq = self.assertEqual
+        msg = self._msgobj('msg_07.txt')
+        fp = openfile('msg_17.txt')
+        try:
+            text = fp.read()
+        finally:
+            fp.close()
+        s = StringIO()
+        g = DecodedGenerator(s)
+        g.flatten(msg)
+        eq(s.getvalue(), text)
+
+    def test__contains__(self):
+        msg = Message()
+        msg['From'] = 'Me'
+        msg['to'] = 'You'
+        # Check for case insensitivity
+        self.failUnless('from' in msg)
+        self.failUnless('From' in msg)
+        self.failUnless('FROM' in msg)
+        self.failUnless('to' in msg)
+        self.failUnless('To' in msg)
+        self.failUnless('TO' in msg)
+
+    def test_as_string(self):
+        eq = self.assertEqual
+        msg = self._msgobj('msg_01.txt')
+        fp = openfile('msg_01.txt')
+        try:
+            text = fp.read()
+        finally:
+            fp.close()
+        eq(text, msg.as_string())
+        fullrepr = str(msg)
+        lines = fullrepr.split('\n')
+        self.failUnless(lines[0].startswith('From '))
+        eq(text, NL.join(lines[1:]))
+
+    def test_bad_param(self):
+        msg = email.message_from_string("Content-Type: blarg; baz; boo\n")
+        self.assertEqual(msg.get_param('baz'), '')
+
+    def test_missing_filename(self):
+        msg = email.message_from_string("From: foo\n")
+        self.assertEqual(msg.get_filename(), None)
+
+    def test_bogus_filename(self):
+        msg = email.message_from_string(
+        "Content-Disposition: blarg; filename\n")
+        self.assertEqual(msg.get_filename(), '')
+
+    def test_missing_boundary(self):
+        msg = email.message_from_string("From: foo\n")
+        self.assertEqual(msg.get_boundary(), None)
+
+    def test_get_params(self):
+        eq = self.assertEqual
+        msg = email.message_from_string(
+            'X-Header: foo=one; bar=two; baz=three\n')
+        eq(msg.get_params(header='x-header'),
+           [('foo', 'one'), ('bar', 'two'), ('baz', 'three')])
+        msg = email.message_from_string(
+            'X-Header: foo; bar=one; baz=two\n')
+        eq(msg.get_params(header='x-header'),
+           [('foo', ''), ('bar', 'one'), ('baz', 'two')])
+        eq(msg.get_params(), None)
+        msg = email.message_from_string(
+            'X-Header: foo; bar="one"; baz=two\n')
+        eq(msg.get_params(header='x-header'),
+           [('foo', ''), ('bar', 'one'), ('baz', 'two')])
+
+    def test_get_param_liberal(self):
+        msg = Message()
+        msg['Content-Type'] = 'Content-Type: Multipart/mixed; boundary = "CPIMSSMTPC06p5f3tG"'
+        self.assertEqual(msg.get_param('boundary'), 'CPIMSSMTPC06p5f3tG')
+
+    def test_get_param(self):
+        eq = self.assertEqual
+        msg = email.message_from_string(
+            "X-Header: foo=one; bar=two; baz=three\n")
+        eq(msg.get_param('bar', header='x-header'), 'two')
+        eq(msg.get_param('quuz', header='x-header'), None)
+        eq(msg.get_param('quuz'), None)
+        msg = email.message_from_string(
+            'X-Header: foo; bar="one"; baz=two\n')
+        eq(msg.get_param('foo', header='x-header'), '')
+        eq(msg.get_param('bar', header='x-header'), 'one')
+        eq(msg.get_param('baz', header='x-header'), 'two')
+        # XXX: We are not RFC-2045 compliant!  We cannot parse:
+        # msg["Content-Type"] = 'text/plain; weird="hey; dolly? [you] @ <\\"home\\">?"'
+        # msg.get_param("weird")
+        # yet.
+
+    def test_get_param_funky_continuation_lines(self):
+        msg = self._msgobj('msg_22.txt')
+        self.assertEqual(msg.get_payload(1).get_param('name'), 'wibble.JPG')
+
+    def test_get_param_with_semis_in_quotes(self):
+        msg = email.message_from_string(
+            'Content-Type: image/pjpeg; name="Jim&amp;&amp;Jill"\n')
+        self.assertEqual(msg.get_param('name'), 'Jim&amp;&amp;Jill')
+        self.assertEqual(msg.get_param('name', unquote=False),
+                         '"Jim&amp;&amp;Jill"')
+
+    def test_has_key(self):
+        msg = email.message_from_string('Header: exists')
+        self.failUnless(msg.has_key('header'))
+        self.failUnless(msg.has_key('Header'))
+        self.failUnless(msg.has_key('HEADER'))
+        self.failIf(msg.has_key('headeri'))
+
+    def test_set_param(self):
+        eq = self.assertEqual
+        msg = Message()
+        msg.set_param('charset', 'iso-2022-jp')
+        eq(msg.get_param('charset'), 'iso-2022-jp')
+        msg.set_param('importance', 'high value')
+        eq(msg.get_param('importance'), 'high value')
+        eq(msg.get_param('importance', unquote=False), '"high value"')
+        eq(msg.get_params(), [('text/plain', ''),
+                              ('charset', 'iso-2022-jp'),
+                              ('importance', 'high value')])
+        eq(msg.get_params(unquote=False), [('text/plain', ''),
+                                       ('charset', '"iso-2022-jp"'),
+                                       ('importance', '"high value"')])
+        msg.set_param('charset', 'iso-9999-xx', header='X-Jimmy')
+        eq(msg.get_param('charset', header='X-Jimmy'), 'iso-9999-xx')
+
+    def test_del_param(self):
+        eq = self.assertEqual
+        msg = self._msgobj('msg_05.txt')
+        eq(msg.get_params(),
+           [('multipart/report', ''), ('report-type', 'delivery-status'),
+            ('boundary', 'D1690A7AC1.996856090/mail.example.com')])
+        old_val = msg.get_param("report-type")
+        msg.del_param("report-type")
+        eq(msg.get_params(),
+           [('multipart/report', ''),
+            ('boundary', 'D1690A7AC1.996856090/mail.example.com')])
+        msg.set_param("report-type", old_val)
+        eq(msg.get_params(),
+           [('multipart/report', ''),
+            ('boundary', 'D1690A7AC1.996856090/mail.example.com'),
+            ('report-type', old_val)])
+
+    def test_del_param_on_other_header(self):
+        msg = Message()
+        msg.add_header('Content-Disposition', 'attachment', filename='bud.gif')
+        msg.del_param('filename', 'content-disposition')
+        self.assertEqual(msg['content-disposition'], 'attachment')
+
+    def test_set_type(self):
+        eq = self.assertEqual
+        msg = Message()
+        self.assertRaises(ValueError, msg.set_type, 'text')
+        msg.set_type('text/plain')
+        eq(msg['content-type'], 'text/plain')
+        msg.set_param('charset', 'us-ascii')
+        eq(msg['content-type'], 'text/plain; charset="us-ascii"')
+        msg.set_type('text/html')
+        eq(msg['content-type'], 'text/html; charset="us-ascii"')
+
+    def test_set_type_on_other_header(self):
+        msg = Message()
+        msg['X-Content-Type'] = 'text/plain'
+        msg.set_type('application/octet-stream', 'X-Content-Type')
+        self.assertEqual(msg['x-content-type'], 'application/octet-stream')
+
+    def test_get_content_type_missing(self):
+        msg = Message()
+        self.assertEqual(msg.get_content_type(), 'text/plain')
+
+    def test_get_content_type_missing_with_default_type(self):
+        msg = Message()
+        msg.set_default_type('message/rfc822')
+        self.assertEqual(msg.get_content_type(), 'message/rfc822')
+
+    def test_get_content_type_from_message_implicit(self):
+        msg = self._msgobj('msg_30.txt')
+        self.assertEqual(msg.get_payload(0).get_content_type(),
+                         'message/rfc822')
+
+    def test_get_content_type_from_message_explicit(self):
+        msg = self._msgobj('msg_28.txt')
+        self.assertEqual(msg.get_payload(0).get_content_type(),
+                         'message/rfc822')
+
+    def test_get_content_type_from_message_text_plain_implicit(self):
+        msg = self._msgobj('msg_03.txt')
+        self.assertEqual(msg.get_content_type(), 'text/plain')
+
+    def test_get_content_type_from_message_text_plain_explicit(self):
+        msg = self._msgobj('msg_01.txt')
+        self.assertEqual(msg.get_content_type(), 'text/plain')
+
+    def test_get_content_maintype_missing(self):
+        msg = Message()
+        self.assertEqual(msg.get_content_maintype(), 'text')
+
+    def test_get_content_maintype_missing_with_default_type(self):
+        msg = Message()
+        msg.set_default_type('message/rfc822')
+        self.assertEqual(msg.get_content_maintype(), 'message')
+
+    def test_get_content_maintype_from_message_implicit(self):
+        msg = self._msgobj('msg_30.txt')
+        self.assertEqual(msg.get_payload(0).get_content_maintype(), 'message')
+
+    def test_get_content_maintype_from_message_explicit(self):
+        msg = self._msgobj('msg_28.txt')
+        self.assertEqual(msg.get_payload(0).get_content_maintype(), 'message')
+
+    def test_get_content_maintype_from_message_text_plain_implicit(self):
+        msg = self._msgobj('msg_03.txt')
+        self.assertEqual(msg.get_content_maintype(), 'text')
+
+    def test_get_content_maintype_from_message_text_plain_explicit(self):
+        msg = self._msgobj('msg_01.txt')
+        self.assertEqual(msg.get_content_maintype(), 'text')
+
+    def test_get_content_subtype_missing(self):
+        msg = Message()
+        self.assertEqual(msg.get_content_subtype(), 'plain')
+
+    def test_get_content_subtype_missing_with_default_type(self):
+        msg = Message()
+        msg.set_default_type('message/rfc822')
+        self.assertEqual(msg.get_content_subtype(), 'rfc822')
+
+    def test_get_content_subtype_from_message_implicit(self):
+        msg = self._msgobj('msg_30.txt')
+        self.assertEqual(msg.get_payload(0).get_content_subtype(), 'rfc822')
+
+    def test_get_content_subtype_from_message_explicit(self):
+        msg = self._msgobj('msg_28.txt')
+        self.assertEqual(msg.get_payload(0).get_content_subtype(), 'rfc822')
+
+    def test_get_content_subtype_from_message_text_plain_implicit(self):
+        msg = self._msgobj('msg_03.txt')
+        self.assertEqual(msg.get_content_subtype(), 'plain')
+
+    def test_get_content_subtype_from_message_text_plain_explicit(self):
+        msg = self._msgobj('msg_01.txt')
+        self.assertEqual(msg.get_content_subtype(), 'plain')
+
+    def test_get_content_maintype_error(self):
+        msg = Message()
+        msg['Content-Type'] = 'no-slash-in-this-string'
+        self.assertEqual(msg.get_content_maintype(), 'text')
+
+    def test_get_content_subtype_error(self):
+        msg = Message()
+        msg['Content-Type'] = 'no-slash-in-this-string'
+        self.assertEqual(msg.get_content_subtype(), 'plain')
+
+    def test_replace_header(self):
+        eq = self.assertEqual
+        msg = Message()
+        msg.add_header('First', 'One')
+        msg.add_header('Second', 'Two')
+        msg.add_header('Third', 'Three')
+        eq(msg.keys(), ['First', 'Second', 'Third'])
+        eq(msg.values(), ['One', 'Two', 'Three'])
+        msg.replace_header('Second', 'Twenty')
+        eq(msg.keys(), ['First', 'Second', 'Third'])
+        eq(msg.values(), ['One', 'Twenty', 'Three'])
+        msg.add_header('First', 'Eleven')
+        msg.replace_header('First', 'One Hundred')
+        eq(msg.keys(), ['First', 'Second', 'Third', 'First'])
+        eq(msg.values(), ['One Hundred', 'Twenty', 'Three', 'Eleven'])
+        self.assertRaises(KeyError, msg.replace_header, 'Fourth', 'Missing')
+
+    def test_broken_base64_payload(self):
+        x = 'AwDp0P7//y6LwKEAcPa/6Q=9'
+        msg = Message()
+        msg['content-type'] = 'audio/x-midi'
+        msg['content-transfer-encoding'] = 'base64'
+        msg.set_payload(x)
+        self.assertEqual(msg.get_payload(decode=True), x)
+
+
+
+# Test the email.encoders module
+class TestEncoders(unittest.TestCase):
+    def test_encode_empty_payload(self):
+        eq = self.assertEqual
+        msg = Message()
+        msg.set_charset('us-ascii')
+        eq(msg['content-transfer-encoding'], '7bit')
+
+    def test_default_cte(self):
+        eq = self.assertEqual
+        msg = MIMEText('hello world')
+        eq(msg['content-transfer-encoding'], '7bit')
+
+    def test_default_cte(self):
+        eq = self.assertEqual
+        # With no explicit _charset its us-ascii, and all are 7-bit
+        msg = MIMEText('hello world')
+        eq(msg['content-transfer-encoding'], '7bit')
+        # Similar, but with 8-bit data
+        msg = MIMEText('hello \xf8 world')
+        eq(msg['content-transfer-encoding'], '8bit')
+        # And now with a different charset
+        msg = MIMEText('hello \xf8 world', _charset='iso-8859-1')
+        eq(msg['content-transfer-encoding'], 'quoted-printable')
+
+
+
+# Test long header wrapping
+class TestLongHeaders(TestEmailBase):
+    def test_split_long_continuation(self):
+        eq = self.ndiffAssertEqual
+        msg = email.message_from_string("""\
+Subject: bug demonstration
+\t12345678911234567892123456789312345678941234567895123456789612345678971234567898112345678911234567892123456789112345678911234567892123456789
+\tmore text
+
+test
+""")
+        sfp = StringIO()
+        g = Generator(sfp)
+        g.flatten(msg)
+        eq(sfp.getvalue(), """\
+Subject: bug demonstration
+\t12345678911234567892123456789312345678941234567895123456789612345678971234567898112345678911234567892123456789112345678911234567892123456789
+\tmore text
+
+test
+""")
+
+    def test_another_long_almost_unsplittable_header(self):
+        eq = self.ndiffAssertEqual
+        hstr = """\
+bug demonstration
+\t12345678911234567892123456789312345678941234567895123456789612345678971234567898112345678911234567892123456789112345678911234567892123456789
+\tmore text"""
+        h = Header(hstr, continuation_ws='\t')
+        eq(h.encode(), """\
+bug demonstration
+\t12345678911234567892123456789312345678941234567895123456789612345678971234567898112345678911234567892123456789112345678911234567892123456789
+\tmore text""")
+        h = Header(hstr)
+        eq(h.encode(), """\
+bug demonstration
+ 12345678911234567892123456789312345678941234567895123456789612345678971234567898112345678911234567892123456789112345678911234567892123456789
+ more text""")
+
+    def test_long_nonstring(self):
+        eq = self.ndiffAssertEqual
+        g = Charset("iso-8859-1")
+        cz = Charset("iso-8859-2")
+        utf8 = Charset("utf-8")
+        g_head = "Die Mieter treten hier ein werden mit einem Foerderband komfortabel den Korridor entlang, an s\xfcdl\xfcndischen Wandgem\xe4lden vorbei, gegen die rotierenden Klingen bef\xf6rdert. "
+        cz_head = "Finan\xe8ni metropole se hroutily pod tlakem jejich d\xf9vtipu.. "
+        utf8_head = u"\u6b63\u78ba\u306b\u8a00\u3046\u3068\u7ffb\u8a33\u306f\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002\u4e00\u90e8\u306f\u30c9\u30a4\u30c4\u8a9e\u3067\u3059\u304c\u3001\u3042\u3068\u306f\u3067\u305f\u3089\u3081\u3067\u3059\u3002\u5b9f\u969b\u306b\u306f\u300cWenn ist das Nunstuck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput.\u300d\u3068\u8a00\u3063\u3066\u3044\u307e\u3059\u3002".encode("utf-8")
+        h = Header(g_head, g, header_name='Subject')
+        h.append(cz_head, cz)
+        h.append(utf8_head, utf8)
+        msg = Message()
+        msg['Subject'] = h
+        sfp = StringIO()
+        g = Generator(sfp)
+        g.flatten(msg)
+        eq(sfp.getvalue(), """\
+Subject: =?iso-8859-1?q?Die_Mieter_treten_hier_ein_werden_mit_einem_Foerd?=
+ =?iso-8859-1?q?erband_komfortabel_den_Korridor_entlang=2C_an_s=FCdl=FCndi?=
+ =?iso-8859-1?q?schen_Wandgem=E4lden_vorbei=2C_gegen_die_rotierenden_Kling?=
+ =?iso-8859-1?q?en_bef=F6rdert=2E_?= =?iso-8859-2?q?Finan=E8ni_met?=
+ =?iso-8859-2?q?ropole_se_hroutily_pod_tlakem_jejich_d=F9vtipu=2E=2E_?=
+ =?utf-8?b?5q2j56K644Gr6KiA44GG44Go57+76Kiz44Gv44GV44KM44Gm44GE?=
+ =?utf-8?b?44G+44Gb44KT44CC5LiA6YOo44Gv44OJ44Kk44OE6Kqe44Gn44GZ44GM44CB?=
+ =?utf-8?b?44GC44Go44Gv44Gn44Gf44KJ44KB44Gn44GZ44CC5a6f6Zqb44Gr44Gv44CM?=
+ =?utf-8?q?Wenn_ist_das_Nunstuck_git_und_Slotermeyer=3F_Ja!_Beiherhund_das?=
+ =?utf-8?b?IE9kZXIgZGllIEZsaXBwZXJ3YWxkdCBnZXJzcHV0LuOAjeOBqOiogOOBow==?=
+ =?utf-8?b?44Gm44GE44G+44GZ44CC?=
+
+""")
+        eq(h.encode(), """\
+=?iso-8859-1?q?Die_Mieter_treten_hier_ein_werden_mit_einem_Foerd?=
+ =?iso-8859-1?q?erband_komfortabel_den_Korridor_entlang=2C_an_s=FCdl=FCndi?=
+ =?iso-8859-1?q?schen_Wandgem=E4lden_vorbei=2C_gegen_die_rotierenden_Kling?=
+ =?iso-8859-1?q?en_bef=F6rdert=2E_?= =?iso-8859-2?q?Finan=E8ni_met?=
+ =?iso-8859-2?q?ropole_se_hroutily_pod_tlakem_jejich_d=F9vtipu=2E=2E_?=
+ =?utf-8?b?5q2j56K644Gr6KiA44GG44Go57+76Kiz44Gv44GV44KM44Gm44GE?=
+ =?utf-8?b?44G+44Gb44KT44CC5LiA6YOo44Gv44OJ44Kk44OE6Kqe44Gn44GZ44GM44CB?=
+ =?utf-8?b?44GC44Go44Gv44Gn44Gf44KJ44KB44Gn44GZ44CC5a6f6Zqb44Gr44Gv44CM?=
+ =?utf-8?q?Wenn_ist_das_Nunstuck_git_und_Slotermeyer=3F_Ja!_Beiherhund_das?=
+ =?utf-8?b?IE9kZXIgZGllIEZsaXBwZXJ3YWxkdCBnZXJzcHV0LuOAjeOBqOiogOOBow==?=
+ =?utf-8?b?44Gm44GE44G+44GZ44CC?=""")
+
+    def test_long_header_encode(self):
+        eq = self.ndiffAssertEqual
+        h = Header('wasnipoop; giraffes="very-long-necked-animals"; '
+                   'spooge="yummy"; hippos="gargantuan"; marshmallows="gooey"',
+                   header_name='X-Foobar-Spoink-Defrobnit')
+        eq(h.encode(), '''\
+wasnipoop; giraffes="very-long-necked-animals";
+ spooge="yummy"; hippos="gargantuan"; marshmallows="gooey"''')
+
+    def test_long_header_encode_with_tab_continuation(self):
+        eq = self.ndiffAssertEqual
+        h = Header('wasnipoop; giraffes="very-long-necked-animals"; '
+                   'spooge="yummy"; hippos="gargantuan"; marshmallows="gooey"',
+                   header_name='X-Foobar-Spoink-Defrobnit',
+                   continuation_ws='\t')
+        eq(h.encode(), '''\
+wasnipoop; giraffes="very-long-necked-animals";
+\tspooge="yummy"; hippos="gargantuan"; marshmallows="gooey"''')
+
+    def test_header_splitter(self):
+        eq = self.ndiffAssertEqual
+        msg = MIMEText('')
+        # It'd be great if we could use add_header() here, but that doesn't
+        # guarantee an order of the parameters.
+        msg['X-Foobar-Spoink-Defrobnit'] = (
+            'wasnipoop; giraffes="very-long-necked-animals"; '
+            'spooge="yummy"; hippos="gargantuan"; marshmallows="gooey"')
+        sfp = StringIO()
+        g = Generator(sfp)
+        g.flatten(msg)
+        eq(sfp.getvalue(), '''\
+Content-Type: text/plain; charset="us-ascii"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Foobar-Spoink-Defrobnit: wasnipoop; giraffes="very-long-necked-animals";
+\tspooge="yummy"; hippos="gargantuan"; marshmallows="gooey"
+
+''')
+
+    def test_no_semis_header_splitter(self):
+        eq = self.ndiffAssertEqual
+        msg = Message()
+        msg['From'] = 'test at dom.ain'
+        msg['References'] = SPACE.join(['<%d at dom.ain>' % i for i in range(10)])
+        msg.set_payload('Test')
+        sfp = StringIO()
+        g = Generator(sfp)
+        g.flatten(msg)
+        eq(sfp.getvalue(), """\
+From: test at dom.ain
+References: <0 at dom.ain> <1 at dom.ain> <2 at dom.ain> <3 at dom.ain> <4 at dom.ain>
+\t<5 at dom.ain> <6 at dom.ain> <7 at dom.ain> <8 at dom.ain> <9 at dom.ain>
+
+Test""")
+
+    def test_no_split_long_header(self):
+        eq = self.ndiffAssertEqual
+        hstr = 'References: ' + 'x' * 80
+        h = Header(hstr, continuation_ws='\t')
+        eq(h.encode(), """\
+References: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx""")
+
+    def test_splitting_multiple_long_lines(self):
+        eq = self.ndiffAssertEqual
+        hstr = """\
+from babylon.socal-raves.org (localhost [127.0.0.1]); by babylon.socal-raves.org (Postfix) with ESMTP id B570E51B81; for <mailman-admin at babylon.socal-raves.org>; Sat, 2 Feb 2002 17:00:06 -0800 (PST)
+\tfrom babylon.socal-raves.org (localhost [127.0.0.1]); by babylon.socal-raves.org (Postfix) with ESMTP id B570E51B81; for <mailman-admin at babylon.socal-raves.org>; Sat, 2 Feb 2002 17:00:06 -0800 (PST)
+\tfrom babylon.socal-raves.org (localhost [127.0.0.1]); by babylon.socal-raves.org (Postfix) with ESMTP id B570E51B81; for <mailman-admin at babylon.socal-raves.org>; Sat, 2 Feb 2002 17:00:06 -0800 (PST)
+"""
+        h = Header(hstr, continuation_ws='\t')
+        eq(h.encode(), """\
+from babylon.socal-raves.org (localhost [127.0.0.1]);
+\tby babylon.socal-raves.org (Postfix) with ESMTP id B570E51B81;
+\tfor <mailman-admin at babylon.socal-raves.org>;
+\tSat, 2 Feb 2002 17:00:06 -0800 (PST)
+\tfrom babylon.socal-raves.org (localhost [127.0.0.1]);
+\tby babylon.socal-raves.org (Postfix) with ESMTP id B570E51B81;
+\tfor <mailman-admin at babylon.socal-raves.org>;
+\tSat, 2 Feb 2002 17:00:06 -0800 (PST)
+\tfrom babylon.socal-raves.org (localhost [127.0.0.1]);
+\tby babylon.socal-raves.org (Postfix) with ESMTP id B570E51B81;
+\tfor <mailman-admin at babylon.socal-raves.org>;
+\tSat, 2 Feb 2002 17:00:06 -0800 (PST)""")
+
+    def test_splitting_first_line_only_is_long(self):
+        eq = self.ndiffAssertEqual
+        hstr = """\
+from modemcable093.139-201-24.que.mc.videotron.ca ([24.201.139.93] helo=cthulhu.gerg.ca)
+\tby kronos.mems-exchange.org with esmtp (Exim 4.05)
+\tid 17k4h5-00034i-00
+\tfor test at mems-exchange.org; Wed, 28 Aug 2002 11:25:20 -0400"""
+        h = Header(hstr, maxlinelen=78, header_name='Received',
+                   continuation_ws='\t')
+        eq(h.encode(), """\
+from modemcable093.139-201-24.que.mc.videotron.ca ([24.201.139.93]
+\thelo=cthulhu.gerg.ca)
+\tby kronos.mems-exchange.org with esmtp (Exim 4.05)
+\tid 17k4h5-00034i-00
+\tfor test at mems-exchange.org; Wed, 28 Aug 2002 11:25:20 -0400""")
+
+    def test_long_8bit_header(self):
+        eq = self.ndiffAssertEqual
+        msg = Message()
+        h = Header('Britische Regierung gibt', 'iso-8859-1',
+                    header_name='Subject')
+        h.append('gr\xfcnes Licht f\xfcr Offshore-Windkraftprojekte')
+        msg['Subject'] = h
+        eq(msg.as_string(), """\
+Subject: =?iso-8859-1?q?Britische_Regierung_gibt?= =?iso-8859-1?q?gr=FCnes?=
+ =?iso-8859-1?q?_Licht_f=FCr_Offshore-Windkraftprojekte?=
+
+""")
+
+    def test_long_8bit_header_no_charset(self):
+        eq = self.ndiffAssertEqual
+        msg = Message()
+        msg['Reply-To'] = 'Britische Regierung gibt gr\xfcnes Licht f\xfcr Offshore-Windkraftprojekte <a-very-long-address at example.com>'
+        eq(msg.as_string(), """\
+Reply-To: Britische Regierung gibt gr\xfcnes Licht f\xfcr Offshore-Windkraftprojekte <a-very-long-address at example.com>
+
+""")
+
+    def test_long_to_header(self):
+        eq = self.ndiffAssertEqual
+        to = '"Someone Test #A" <someone at eecs.umich.edu>,<someone at eecs.umich.edu>,"Someone Test #B" <someone at umich.edu>, "Someone Test #C" <someone at eecs.umich.edu>, "Someone Test #D" <someone at eecs.umich.edu>'
+        msg = Message()
+        msg['To'] = to
+        eq(msg.as_string(0), '''\
+To: "Someone Test #A" <someone at eecs.umich.edu>, <someone at eecs.umich.edu>,
+\t"Someone Test #B" <someone at umich.edu>,
+\t"Someone Test #C" <someone at eecs.umich.edu>,
+\t"Someone Test #D" <someone at eecs.umich.edu>
+
+''')
+
+    def test_long_line_after_append(self):
+        eq = self.ndiffAssertEqual
+        s = 'This is an example of string which has almost the limit of header length.'
+        h = Header(s)
+        h.append('Add another line.')
+        eq(h.encode(), """\
+This is an example of string which has almost the limit of header length.
+ Add another line.""")
+
+    def test_shorter_line_with_append(self):
+        eq = self.ndiffAssertEqual
+        s = 'This is a shorter line.'
+        h = Header(s)
+        h.append('Add another sentence. (Surprise?)')
+        eq(h.encode(),
+           'This is a shorter line. Add another sentence. (Surprise?)')
+
+    def test_long_field_name(self):
+        eq = self.ndiffAssertEqual
+        fn = 'X-Very-Very-Very-Long-Header-Name'
+        gs = "Die Mieter treten hier ein werden mit einem Foerderband komfortabel den Korridor entlang, an s\xfcdl\xfcndischen Wandgem\xe4lden vorbei, gegen die rotierenden Klingen bef\xf6rdert. "
+        h = Header(gs, 'iso-8859-1', header_name=fn)
+        # BAW: this seems broken because the first line is too long
+        eq(h.encode(), """\
+=?iso-8859-1?q?Die_Mieter_treten_hier_?=
+ =?iso-8859-1?q?ein_werden_mit_einem_Foerderband_komfortabel_den_Korridor_?=
+ =?iso-8859-1?q?entlang=2C_an_s=FCdl=FCndischen_Wandgem=E4lden_vorbei=2C_g?=
+ =?iso-8859-1?q?egen_die_rotierenden_Klingen_bef=F6rdert=2E_?=""")
+
+    def test_long_received_header(self):
+        h = 'from FOO.TLD (vizworld.acl.foo.tld [123.452.678.9]) by hrothgar.la.mastaler.com (tmda-ofmipd) with ESMTP; Wed, 05 Mar 2003 18:10:18 -0700'
+        msg = Message()
+        msg['Received-1'] = Header(h, continuation_ws='\t')
+        msg['Received-2'] = h
+        self.assertEqual(msg.as_string(), """\
+Received-1: from FOO.TLD (vizworld.acl.foo.tld [123.452.678.9]) by
+\throthgar.la.mastaler.com (tmda-ofmipd) with ESMTP;
+\tWed, 05 Mar 2003 18:10:18 -0700
+Received-2: from FOO.TLD (vizworld.acl.foo.tld [123.452.678.9]) by
+\throthgar.la.mastaler.com (tmda-ofmipd) with ESMTP;
+\tWed, 05 Mar 2003 18:10:18 -0700
+
+""")
+
+    def test_string_headerinst_eq(self):
+        h = '<15975.17901.207240.414604 at sgigritzmann1.mathematik.tu-muenchen.de> (David Bremner\'s message of "Thu, 6 Mar 2003 13:58:21 +0100")'
+        msg = Message()
+        msg['Received-1'] = Header(h, header_name='Received-1',
+                                   continuation_ws='\t')
+        msg['Received-2'] = h
+        self.assertEqual(msg.as_string(), """\
+Received-1: <15975.17901.207240.414604 at sgigritzmann1.mathematik.tu-muenchen.de>
+\t(David Bremner's message of "Thu, 6 Mar 2003 13:58:21 +0100")
+Received-2: <15975.17901.207240.414604 at sgigritzmann1.mathematik.tu-muenchen.de>
+\t(David Bremner's message of "Thu, 6 Mar 2003 13:58:21 +0100")
+
+""")
+
+    def test_long_unbreakable_lines_with_continuation(self):
+        eq = self.ndiffAssertEqual
+        msg = Message()
+        t = """\
+ iVBORw0KGgoAAAANSUhEUgAAADAAAAAwBAMAAAClLOS0AAAAGFBMVEUAAAAkHiJeRUIcGBi9
+ locQDQ4zJykFBAXJfWDjAAACYUlEQVR4nF2TQY/jIAyFc6lydlG5x8Nyp1Y69wj1PN2I5gzp"""
+        msg['Face-1'] = t
+        msg['Face-2'] = Header(t, header_name='Face-2')
+        eq(msg.as_string(), """\
+Face-1: iVBORw0KGgoAAAANSUhEUgAAADAAAAAwBAMAAAClLOS0AAAAGFBMVEUAAAAkHiJeRUIcGBi9
+\tlocQDQ4zJykFBAXJfWDjAAACYUlEQVR4nF2TQY/jIAyFc6lydlG5x8Nyp1Y69wj1PN2I5gzp
+Face-2: iVBORw0KGgoAAAANSUhEUgAAADAAAAAwBAMAAAClLOS0AAAAGFBMVEUAAAAkHiJeRUIcGBi9
+ locQDQ4zJykFBAXJfWDjAAACYUlEQVR4nF2TQY/jIAyFc6lydlG5x8Nyp1Y69wj1PN2I5gzp
+
+""")
+
+    def test_another_long_multiline_header(self):
+        eq = self.ndiffAssertEqual
+        m = '''\
+Received: from siimage.com ([172.25.1.3]) by zima.siliconimage.com with Microsoft SMTPSVC(5.0.2195.4905);
+\tWed, 16 Oct 2002 07:41:11 -0700'''
+        msg = email.message_from_string(m)
+        eq(msg.as_string(), '''\
+Received: from siimage.com ([172.25.1.3]) by zima.siliconimage.com with
+\tMicrosoft SMTPSVC(5.0.2195.4905); Wed, 16 Oct 2002 07:41:11 -0700
+
+''')
+
+    def test_long_lines_with_different_header(self):
+        eq = self.ndiffAssertEqual
+        h = """\
+List-Unsubscribe: <https://lists.sourceforge.net/lists/listinfo/spamassassin-talk>,
+        <mailto:spamassassin-talk-request at lists.sourceforge.net?subject=unsubscribe>"""
+        msg = Message()
+        msg['List'] = h
+        msg['List'] = Header(h, header_name='List')
+        eq(msg.as_string(), """\
+List: List-Unsubscribe: <https://lists.sourceforge.net/lists/listinfo/spamassassin-talk>,
+\t<mailto:spamassassin-talk-request at lists.sourceforge.net?subject=unsubscribe>
+List: List-Unsubscribe: <https://lists.sourceforge.net/lists/listinfo/spamassassin-talk>,
+ <mailto:spamassassin-talk-request at lists.sourceforge.net?subject=unsubscribe>
+
+""")
+
+
+
+# Test mangling of "From " lines in the body of a message
+class TestFromMangling(unittest.TestCase):
+    def setUp(self):
+        self.msg = Message()
+        self.msg['From'] = 'aaa at bbb.org'
+        self.msg.set_payload("""\
+From the desk of A.A.A.:
+Blah blah blah
+""")
+
+    def test_mangled_from(self):
+        s = StringIO()
+        g = Generator(s, mangle_from_=True)
+        g.flatten(self.msg)
+        self.assertEqual(s.getvalue(), """\
+From: aaa at bbb.org
+
+>From the desk of A.A.A.:
+Blah blah blah
+""")
+
+    def test_dont_mangle_from(self):
+        s = StringIO()
+        g = Generator(s, mangle_from_=False)
+        g.flatten(self.msg)
+        self.assertEqual(s.getvalue(), """\
+From: aaa at bbb.org
+
+From the desk of A.A.A.:
+Blah blah blah
+""")
+
+
+
+# Test the basic MIMEAudio class
+class TestMIMEAudio(unittest.TestCase):
+    def setUp(self):
+        # Make sure we pick up the audiotest.au that lives in email/test/data.
+        # In Python, there's an audiotest.au living in Lib/test but that isn't
+        # included in some binary distros that don't include the test
+        # package.  The trailing empty string on the .join() is significant
+        # since findfile() will do a dirname().
+        datadir = os.path.join(os.path.dirname(landmark), 'data', '')
+        fp = open(findfile('audiotest.au', datadir), 'rb')
+        try:
+            self._audiodata = fp.read()
+        finally:
+            fp.close()
+        self._au = MIMEAudio(self._audiodata)
+
+    def test_guess_minor_type(self):
+        self.assertEqual(self._au.get_content_type(), 'audio/basic')
+
+    def test_encoding(self):
+        payload = self._au.get_payload()
+        self.assertEqual(base64.decodestring(payload), self._audiodata)
+
+    def test_checkSetMinor(self):
+        au = MIMEAudio(self._audiodata, 'fish')
+        self.assertEqual(au.get_content_type(), 'audio/fish')
+
+    def test_add_header(self):
+        eq = self.assertEqual
+        unless = self.failUnless
+        self._au.add_header('Content-Disposition', 'attachment',
+                            filename='audiotest.au')
+        eq(self._au['content-disposition'],
+           'attachment; filename="audiotest.au"')
+        eq(self._au.get_params(header='content-disposition'),
+           [('attachment', ''), ('filename', 'audiotest.au')])
+        eq(self._au.get_param('filename', header='content-disposition'),
+           'audiotest.au')
+        missing = []
+        eq(self._au.get_param('attachment', header='content-disposition'), '')
+        unless(self._au.get_param('foo', failobj=missing,
+                                  header='content-disposition') is missing)
+        # Try some missing stuff
+        unless(self._au.get_param('foobar', missing) is missing)
+        unless(self._au.get_param('attachment', missing,
+                                  header='foobar') is missing)
+
+
+
+# Test the basic MIMEImage class
+class TestMIMEImage(unittest.TestCase):
+    def setUp(self):
+        fp = openfile('PyBanner048.gif')
+        try:
+            self._imgdata = fp.read()
+        finally:
+            fp.close()
+        self._im = MIMEImage(self._imgdata)
+
+    def test_guess_minor_type(self):
+        self.assertEqual(self._im.get_content_type(), 'image/gif')
+
+    def test_encoding(self):
+        payload = self._im.get_payload()
+        self.assertEqual(base64.decodestring(payload), self._imgdata)
+
+    def test_checkSetMinor(self):
+        im = MIMEImage(self._imgdata, 'fish')
+        self.assertEqual(im.get_content_type(), 'image/fish')
+
+    def test_add_header(self):
+        eq = self.assertEqual
+        unless = self.failUnless
+        self._im.add_header('Content-Disposition', 'attachment',
+                            filename='dingusfish.gif')
+        eq(self._im['content-disposition'],
+           'attachment; filename="dingusfish.gif"')
+        eq(self._im.get_params(header='content-disposition'),
+           [('attachment', ''), ('filename', 'dingusfish.gif')])
+        eq(self._im.get_param('filename', header='content-disposition'),
+           'dingusfish.gif')
+        missing = []
+        eq(self._im.get_param('attachment', header='content-disposition'), '')
+        unless(self._im.get_param('foo', failobj=missing,
+                                  header='content-disposition') is missing)
+        # Try some missing stuff
+        unless(self._im.get_param('foobar', missing) is missing)
+        unless(self._im.get_param('attachment', missing,
+                                  header='foobar') is missing)
+
+
+
+# Test the basic MIMEApplication class
+class TestMIMEApplication(unittest.TestCase):
+    def test_headers(self):
+        eq = self.assertEqual
+        msg = MIMEApplication('\xfa\xfb\xfc\xfd\xfe\xff')
+        eq(msg.get_content_type(), 'application/octet-stream')
+        eq(msg['content-transfer-encoding'], 'base64')
+
+    def test_body(self):
+        eq = self.assertEqual
+        bytes = '\xfa\xfb\xfc\xfd\xfe\xff'
+        msg = MIMEApplication(bytes)
+        eq(msg.get_payload(), '+vv8/f7/')
+        eq(msg.get_payload(decode=True), bytes)
+
+
+
+# Test the basic MIMEText class
+class TestMIMEText(unittest.TestCase):
+    def setUp(self):
+        self._msg = MIMEText('hello there')
+
+    def test_types(self):
+        eq = self.assertEqual
+        unless = self.failUnless
+        eq(self._msg.get_content_type(), 'text/plain')
+        eq(self._msg.get_param('charset'), 'us-ascii')
+        missing = []
+        unless(self._msg.get_param('foobar', missing) is missing)
+        unless(self._msg.get_param('charset', missing, header='foobar')
+               is missing)
+
+    def test_payload(self):
+        self.assertEqual(self._msg.get_payload(), 'hello there')
+        self.failUnless(not self._msg.is_multipart())
+
+    def test_charset(self):
+        eq = self.assertEqual
+        msg = MIMEText('hello there', _charset='us-ascii')
+        eq(msg.get_charset().input_charset, 'us-ascii')
+        eq(msg['content-type'], 'text/plain; charset="us-ascii"')
+
+
+
+# Test complicated multipart/* messages
+class TestMultipart(TestEmailBase):
+    def setUp(self):
+        fp = openfile('PyBanner048.gif')
+        try:
+            data = fp.read()
+        finally:
+            fp.close()
+
+        container = MIMEBase('multipart', 'mixed', boundary='BOUNDARY')
+        image = MIMEImage(data, name='dingusfish.gif')
+        image.add_header('content-disposition', 'attachment',
+                         filename='dingusfish.gif')
+        intro = MIMEText('''\
+Hi there,
+
+This is the dingus fish.
+''')
+        container.attach(intro)
+        container.attach(image)
+        container['From'] = 'Barry <barry at digicool.com>'
+        container['To'] = 'Dingus Lovers <cravindogs at cravindogs.com>'
+        container['Subject'] = 'Here is your dingus fish'
+
+        now = 987809702.54848599
+        timetuple = time.localtime(now)
+        if timetuple[-1] == 0:
+            tzsecs = time.timezone
+        else:
+            tzsecs = time.altzone
+        if tzsecs > 0:
+            sign = '-'
+        else:
+            sign = '+'
+        tzoffset = ' %s%04d' % (sign, tzsecs / 36)
+        container['Date'] = time.strftime(
+            '%a, %d %b %Y %H:%M:%S',
+            time.localtime(now)) + tzoffset
+        self._msg = container
+        self._im = image
+        self._txt = intro
+
+    def test_hierarchy(self):
+        # convenience
+        eq = self.assertEqual
+        unless = self.failUnless
+        raises = self.assertRaises
+        # tests
+        m = self._msg
+        unless(m.is_multipart())
+        eq(m.get_content_type(), 'multipart/mixed')
+        eq(len(m.get_payload()), 2)
+        raises(IndexError, m.get_payload, 2)
+        m0 = m.get_payload(0)
+        m1 = m.get_payload(1)
+        unless(m0 is self._txt)
+        unless(m1 is self._im)
+        eq(m.get_payload(), [m0, m1])
+        unless(not m0.is_multipart())
+        unless(not m1.is_multipart())
+
+    def test_empty_multipart_idempotent(self):
+        text = """\
+Content-Type: multipart/mixed; boundary="BOUNDARY"
+MIME-Version: 1.0
+Subject: A subject
+To: aperson at dom.ain
+From: bperson at dom.ain
+
+
+--BOUNDARY
+
+
+--BOUNDARY--
+"""
+        msg = Parser().parsestr(text)
+        self.ndiffAssertEqual(text, msg.as_string())
+
+    def test_no_parts_in_a_multipart_with_none_epilogue(self):
+        outer = MIMEBase('multipart', 'mixed')
+        outer['Subject'] = 'A subject'
+        outer['To'] = 'aperson at dom.ain'
+        outer['From'] = 'bperson at dom.ain'
+        outer.set_boundary('BOUNDARY')
+        self.ndiffAssertEqual(outer.as_string(), '''\
+Content-Type: multipart/mixed; boundary="BOUNDARY"
+MIME-Version: 1.0
+Subject: A subject
+To: aperson at dom.ain
+From: bperson at dom.ain
+
+--BOUNDARY
+
+--BOUNDARY--''')
+
+    def test_no_parts_in_a_multipart_with_empty_epilogue(self):
+        outer = MIMEBase('multipart', 'mixed')
+        outer['Subject'] = 'A subject'
+        outer['To'] = 'aperson at dom.ain'
+        outer['From'] = 'bperson at dom.ain'
+        outer.preamble = ''
+        outer.epilogue = ''
+        outer.set_boundary('BOUNDARY')
+        self.ndiffAssertEqual(outer.as_string(), '''\
+Content-Type: multipart/mixed; boundary="BOUNDARY"
+MIME-Version: 1.0
+Subject: A subject
+To: aperson at dom.ain
+From: bperson at dom.ain
+
+
+--BOUNDARY
+
+--BOUNDARY--
+''')
+
+    def test_one_part_in_a_multipart(self):
+        eq = self.ndiffAssertEqual
+        outer = MIMEBase('multipart', 'mixed')
+        outer['Subject'] = 'A subject'
+        outer['To'] = 'aperson at dom.ain'
+        outer['From'] = 'bperson at dom.ain'
+        outer.set_boundary('BOUNDARY')
+        msg = MIMEText('hello world')
+        outer.attach(msg)
+        eq(outer.as_string(), '''\
+Content-Type: multipart/mixed; boundary="BOUNDARY"
+MIME-Version: 1.0
+Subject: A subject
+To: aperson at dom.ain
+From: bperson at dom.ain
+
+--BOUNDARY
+Content-Type: text/plain; charset="us-ascii"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+
+hello world
+--BOUNDARY--''')
+
+    def test_seq_parts_in_a_multipart_with_empty_preamble(self):
+        eq = self.ndiffAssertEqual
+        outer = MIMEBase('multipart', 'mixed')
+        outer['Subject'] = 'A subject'
+        outer['To'] = 'aperson at dom.ain'
+        outer['From'] = 'bperson at dom.ain'
+        outer.preamble = ''
+        msg = MIMEText('hello world')
+        outer.attach(msg)
+        outer.set_boundary('BOUNDARY')
+        eq(outer.as_string(), '''\
+Content-Type: multipart/mixed; boundary="BOUNDARY"
+MIME-Version: 1.0
+Subject: A subject
+To: aperson at dom.ain
+From: bperson at dom.ain
+
+
+--BOUNDARY
+Content-Type: text/plain; charset="us-ascii"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+
+hello world
+--BOUNDARY--''')
+
+
+    def test_seq_parts_in_a_multipart_with_none_preamble(self):
+        eq = self.ndiffAssertEqual
+        outer = MIMEBase('multipart', 'mixed')
+        outer['Subject'] = 'A subject'
+        outer['To'] = 'aperson at dom.ain'
+        outer['From'] = 'bperson at dom.ain'
+        outer.preamble = None
+        msg = MIMEText('hello world')
+        outer.attach(msg)
+        outer.set_boundary('BOUNDARY')
+        eq(outer.as_string(), '''\
+Content-Type: multipart/mixed; boundary="BOUNDARY"
+MIME-Version: 1.0
+Subject: A subject
+To: aperson at dom.ain
+From: bperson at dom.ain
+
+--BOUNDARY
+Content-Type: text/plain; charset="us-ascii"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+
+hello world
+--BOUNDARY--''')
+
+
+    def test_seq_parts_in_a_multipart_with_none_epilogue(self):
+        eq = self.ndiffAssertEqual
+        outer = MIMEBase('multipart', 'mixed')
+        outer['Subject'] = 'A subject'
+        outer['To'] = 'aperson at dom.ain'
+        outer['From'] = 'bperson at dom.ain'
+        outer.epilogue = None
+        msg = MIMEText('hello world')
+        outer.attach(msg)
+        outer.set_boundary('BOUNDARY')
+        eq(outer.as_string(), '''\
+Content-Type: multipart/mixed; boundary="BOUNDARY"
+MIME-Version: 1.0
+Subject: A subject
+To: aperson at dom.ain
+From: bperson at dom.ain
+
+--BOUNDARY
+Content-Type: text/plain; charset="us-ascii"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+
+hello world
+--BOUNDARY--''')
+
+
+    def test_seq_parts_in_a_multipart_with_empty_epilogue(self):
+        eq = self.ndiffAssertEqual
+        outer = MIMEBase('multipart', 'mixed')
+        outer['Subject'] = 'A subject'
+        outer['To'] = 'aperson at dom.ain'
+        outer['From'] = 'bperson at dom.ain'
+        outer.epilogue = ''
+        msg = MIMEText('hello world')
+        outer.attach(msg)
+        outer.set_boundary('BOUNDARY')
+        eq(outer.as_string(), '''\
+Content-Type: multipart/mixed; boundary="BOUNDARY"
+MIME-Version: 1.0
+Subject: A subject
+To: aperson at dom.ain
+From: bperson at dom.ain
+
+--BOUNDARY
+Content-Type: text/plain; charset="us-ascii"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+
+hello world
+--BOUNDARY--
+''')
+
+
+    def test_seq_parts_in_a_multipart_with_nl_epilogue(self):
+        eq = self.ndiffAssertEqual
+        outer = MIMEBase('multipart', 'mixed')
+        outer['Subject'] = 'A subject'
+        outer['To'] = 'aperson at dom.ain'
+        outer['From'] = 'bperson at dom.ain'
+        outer.epilogue = '\n'
+        msg = MIMEText('hello world')
+        outer.attach(msg)
+        outer.set_boundary('BOUNDARY')
+        eq(outer.as_string(), '''\
+Content-Type: multipart/mixed; boundary="BOUNDARY"
+MIME-Version: 1.0
+Subject: A subject
+To: aperson at dom.ain
+From: bperson at dom.ain
+
+--BOUNDARY
+Content-Type: text/plain; charset="us-ascii"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+
+hello world
+--BOUNDARY--
+
+''')
+
+    def test_message_external_body(self):
+        eq = self.assertEqual
+        msg = self._msgobj('msg_36.txt')
+        eq(len(msg.get_payload()), 2)
+        msg1 = msg.get_payload(1)
+        eq(msg1.get_content_type(), 'multipart/alternative')
+        eq(len(msg1.get_payload()), 2)
+        for subpart in msg1.get_payload():
+            eq(subpart.get_content_type(), 'message/external-body')
+            eq(len(subpart.get_payload()), 1)
+            subsubpart = subpart.get_payload(0)
+            eq(subsubpart.get_content_type(), 'text/plain')
+
+    def test_double_boundary(self):
+        # msg_37.txt is a multipart that contains two dash-boundary's in a
+        # row.  Our interpretation of RFC 2046 calls for ignoring the second
+        # and subsequent boundaries.
+        msg = self._msgobj('msg_37.txt')
+        self.assertEqual(len(msg.get_payload()), 3)
+
+    def test_nested_inner_contains_outer_boundary(self):
+        eq = self.ndiffAssertEqual
+        # msg_38.txt has an inner part that contains outer boundaries.  My
+        # interpretation of RFC 2046 (based on sections 5.1 and 5.1.2) say
+        # these are illegal and should be interpreted as unterminated inner
+        # parts.
+        msg = self._msgobj('msg_38.txt')
+        sfp = StringIO()
+        iterators._structure(msg, sfp)
+        eq(sfp.getvalue(), """\
+multipart/mixed
+    multipart/mixed
+        multipart/alternative
+            text/plain
+        text/plain
+    text/plain
+    text/plain
+""")
+
+    def test_nested_with_same_boundary(self):
+        eq = self.ndiffAssertEqual
+        # msg 39.txt is similarly evil in that it's got inner parts that use
+        # the same boundary as outer parts.  Again, I believe the way this is
+        # parsed is closest to the spirit of RFC 2046
+        msg = self._msgobj('msg_39.txt')
+        sfp = StringIO()
+        iterators._structure(msg, sfp)
+        eq(sfp.getvalue(), """\
+multipart/mixed
+    multipart/mixed
+        multipart/alternative
+        application/octet-stream
+        application/octet-stream
+    text/plain
+""")
+
+    def test_boundary_in_non_multipart(self):
+        msg = self._msgobj('msg_40.txt')
+        self.assertEqual(msg.as_string(), '''\
+MIME-Version: 1.0
+Content-Type: text/html; boundary="--961284236552522269"
+
+----961284236552522269
+Content-Type: text/html;
+Content-Transfer-Encoding: 7Bit
+
+<html></html>
+
+----961284236552522269--
+''')
+
+    def test_boundary_with_leading_space(self):
+        eq = self.assertEqual
+        msg = email.message_from_string('''\
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="    XXXX"
+
+--    XXXX
+Content-Type: text/plain
+
+
+--    XXXX
+Content-Type: text/plain
+
+--    XXXX--
+''')
+        self.failUnless(msg.is_multipart())
+        eq(msg.get_boundary(), '    XXXX')
+        eq(len(msg.get_payload()), 2)
+
+    def test_boundary_without_trailing_newline(self):
+        m = Parser().parsestr("""\
+Content-Type: multipart/mixed; boundary="===============0012394164=="
+MIME-Version: 1.0
+
+--===============0012394164==
+Content-Type: image/file1.jpg
+MIME-Version: 1.0
+Content-Transfer-Encoding: base64
+
+YXNkZg==
+--===============0012394164==--""")
+        self.assertEquals(m.get_payload(0).get_payload(), 'YXNkZg==')
+
+
+
+# Test some badly formatted messages
+class TestNonConformant(TestEmailBase):
+    def test_parse_missing_minor_type(self):
+        eq = self.assertEqual
+        msg = self._msgobj('msg_14.txt')
+        eq(msg.get_content_type(), 'text/plain')
+        eq(msg.get_content_maintype(), 'text')
+        eq(msg.get_content_subtype(), 'plain')
+
+    def test_same_boundary_inner_outer(self):
+        unless = self.failUnless
+        msg = self._msgobj('msg_15.txt')
+        # XXX We can probably eventually do better
+        inner = msg.get_payload(0)
+        unless(hasattr(inner, 'defects'))
+        self.assertEqual(len(inner.defects), 1)
+        unless(isinstance(inner.defects[0],
+                          errors.StartBoundaryNotFoundDefect))
+
+    def test_multipart_no_boundary(self):
+        unless = self.failUnless
+        msg = self._msgobj('msg_25.txt')
+        unless(isinstance(msg.get_payload(), str))
+        self.assertEqual(len(msg.defects), 2)
+        unless(isinstance(msg.defects[0], errors.NoBoundaryInMultipartDefect))
+        unless(isinstance(msg.defects[1],
+                          errors.MultipartInvariantViolationDefect))
+
+    def test_invalid_content_type(self):
+        eq = self.assertEqual
+        neq = self.ndiffAssertEqual
+        msg = Message()
+        # RFC 2045, $5.2 says invalid yields text/plain
+        msg['Content-Type'] = 'text'
+        eq(msg.get_content_maintype(), 'text')
+        eq(msg.get_content_subtype(), 'plain')
+        eq(msg.get_content_type(), 'text/plain')
+        # Clear the old value and try something /really/ invalid
+        del msg['content-type']
+        msg['Content-Type'] = 'foo'
+        eq(msg.get_content_maintype(), 'text')
+        eq(msg.get_content_subtype(), 'plain')
+        eq(msg.get_content_type(), 'text/plain')
+        # Still, make sure that the message is idempotently generated
+        s = StringIO()
+        g = Generator(s)
+        g.flatten(msg)
+        neq(s.getvalue(), 'Content-Type: foo\n\n')
+
+    def test_no_start_boundary(self):
+        eq = self.ndiffAssertEqual
+        msg = self._msgobj('msg_31.txt')
+        eq(msg.get_payload(), """\
+--BOUNDARY
+Content-Type: text/plain
+
+message 1
+
+--BOUNDARY
+Content-Type: text/plain
+
+message 2
+
+--BOUNDARY--
+""")
+
+    def test_no_separating_blank_line(self):
+        eq = self.ndiffAssertEqual
+        msg = self._msgobj('msg_35.txt')
+        eq(msg.as_string(), """\
+From: aperson at dom.ain
+To: bperson at dom.ain
+Subject: here's something interesting
+
+counter to RFC 2822, there's no separating newline here
+""")
+
+    def test_lying_multipart(self):
+        unless = self.failUnless
+        msg = self._msgobj('msg_41.txt')
+        unless(hasattr(msg, 'defects'))
+        self.assertEqual(len(msg.defects), 2)
+        unless(isinstance(msg.defects[0], errors.NoBoundaryInMultipartDefect))
+        unless(isinstance(msg.defects[1],
+                          errors.MultipartInvariantViolationDefect))
+
+    def test_missing_start_boundary(self):
+        outer = self._msgobj('msg_42.txt')
+        # The message structure is:
+        #
+        # multipart/mixed
+        #    text/plain
+        #    message/rfc822
+        #        multipart/mixed [*]
+        #
+        # [*] This message is missing its start boundary
+        bad = outer.get_payload(1).get_payload(0)
+        self.assertEqual(len(bad.defects), 1)
+        self.failUnless(isinstance(bad.defects[0],
+                                   errors.StartBoundaryNotFoundDefect))
+
+
+
+# Test RFC 2047 header encoding and decoding
+class TestRFC2047(unittest.TestCase):
+    def test_rfc2047_multiline(self):
+        eq = self.assertEqual
+        s = """Re: =?mac-iceland?q?r=8Aksm=9Arg=8Cs?= baz
+ foo bar =?mac-iceland?q?r=8Aksm=9Arg=8Cs?="""
+        dh = decode_header(s)
+        eq(dh, [
+            ('Re:', None),
+            ('r\x8aksm\x9arg\x8cs', 'mac-iceland'),
+            ('baz foo bar', None),
+            ('r\x8aksm\x9arg\x8cs', 'mac-iceland')])
+        eq(str(make_header(dh)),
+           """Re: =?mac-iceland?q?r=8Aksm=9Arg=8Cs?= baz foo bar
+ =?mac-iceland?q?r=8Aksm=9Arg=8Cs?=""")
+
+    def test_whitespace_eater_unicode(self):
+        eq = self.assertEqual
+        s = '=?ISO-8859-1?Q?Andr=E9?= Pirard <pirard at dom.ain>'
+        dh = decode_header(s)
+        eq(dh, [('Andr\xe9', 'iso-8859-1'), ('Pirard <pirard at dom.ain>', None)])
+        hu = unicode(make_header(dh)).encode('latin-1')
+        eq(hu, 'Andr\xe9 Pirard <pirard at dom.ain>')
+
+    def test_whitespace_eater_unicode_2(self):
+        eq = self.assertEqual
+        s = 'The =?iso-8859-1?b?cXVpY2sgYnJvd24gZm94?= jumped over the =?iso-8859-1?b?bGF6eSBkb2c=?='
+        dh = decode_header(s)
+        eq(dh, [('The', None), ('quick brown fox', 'iso-8859-1'),
+                ('jumped over the', None), ('lazy dog', 'iso-8859-1')])
+        hu = make_header(dh).__unicode__()
+        eq(hu, u'The quick brown fox jumped over the lazy dog')
+
+    def test_rfc2047_missing_whitespace(self):
+        s = 'Sm=?ISO-8859-1?B?9g==?=rg=?ISO-8859-1?B?5Q==?=sbord'
+        dh = decode_header(s)
+        self.assertEqual(dh, [(s, None)])
+
+    def test_rfc2047_with_whitespace(self):
+        s = 'Sm =?ISO-8859-1?B?9g==?= rg =?ISO-8859-1?B?5Q==?= sbord'
+        dh = decode_header(s)
+        self.assertEqual(dh, [('Sm', None), ('\xf6', 'iso-8859-1'),
+                              ('rg', None), ('\xe5', 'iso-8859-1'),
+                              ('sbord', None)])
+
+
+
+# Test the MIMEMessage class
+class TestMIMEMessage(TestEmailBase):
+    def setUp(self):
+        fp = openfile('msg_11.txt')
+        try:
+            self._text = fp.read()
+        finally:
+            fp.close()
+
+    def test_type_error(self):
+        self.assertRaises(TypeError, MIMEMessage, 'a plain string')
+
+    def test_valid_argument(self):
+        eq = self.assertEqual
+        unless = self.failUnless
+        subject = 'A sub-message'
+        m = Message()
+        m['Subject'] = subject
+        r = MIMEMessage(m)
+        eq(r.get_content_type(), 'message/rfc822')
+        payload = r.get_payload()
+        unless(isinstance(payload, list))
+        eq(len(payload), 1)
+        subpart = payload[0]
+        unless(subpart is m)
+        eq(subpart['subject'], subject)
+
+    def test_bad_multipart(self):
+        eq = self.assertEqual
+        msg1 = Message()
+        msg1['Subject'] = 'subpart 1'
+        msg2 = Message()
+        msg2['Subject'] = 'subpart 2'
+        r = MIMEMessage(msg1)
+        self.assertRaises(errors.MultipartConversionError, r.attach, msg2)
+
+    def test_generate(self):
+        # First craft the message to be encapsulated
+        m = Message()
+        m['Subject'] = 'An enclosed message'
+        m.set_payload('Here is the body of the message.\n')
+        r = MIMEMessage(m)
+        r['Subject'] = 'The enclosing message'
+        s = StringIO()
+        g = Generator(s)
+        g.flatten(r)
+        self.assertEqual(s.getvalue(), """\
+Content-Type: message/rfc822
+MIME-Version: 1.0
+Subject: The enclosing message
+
+Subject: An enclosed message
+
+Here is the body of the message.
+""")
+
+    def test_parse_message_rfc822(self):
+        eq = self.assertEqual
+        unless = self.failUnless
+        msg = self._msgobj('msg_11.txt')
+        eq(msg.get_content_type(), 'message/rfc822')
+        payload = msg.get_payload()
+        unless(isinstance(payload, list))
+        eq(len(payload), 1)
+        submsg = payload[0]
+        self.failUnless(isinstance(submsg, Message))
+        eq(submsg['subject'], 'An enclosed message')
+        eq(submsg.get_payload(), 'Here is the body of the message.\n')
+
+    def test_dsn(self):
+        eq = self.assertEqual
+        unless = self.failUnless
+        # msg 16 is a Delivery Status Notification, see RFC 1894
+        msg = self._msgobj('msg_16.txt')
+        eq(msg.get_content_type(), 'multipart/report')
+        unless(msg.is_multipart())
+        eq(len(msg.get_payload()), 3)
+        # Subpart 1 is a text/plain, human readable section
+        subpart = msg.get_payload(0)
+        eq(subpart.get_content_type(), 'text/plain')
+        eq(subpart.get_payload(), """\
+This report relates to a message you sent with the following header fields:
+
+  Message-id: <002001c144a6$8752e060$56104586 at oxy.edu>
+  Date: Sun, 23 Sep 2001 20:10:55 -0700
+  From: "Ian T. Henry" <henryi at oxy.edu>
+  To: SoCal Raves <scr at socal-raves.org>
+  Subject: [scr] yeah for Ians!!
+
+Your message cannot be delivered to the following recipients:
+
+  Recipient address: jangel1 at cougar.noc.ucla.edu
+  Reason: recipient reached disk quota
+
+""")
+        # Subpart 2 contains the machine parsable DSN information.  It
+        # consists of two blocks of headers, represented by two nested Message
+        # objects.
+        subpart = msg.get_payload(1)
+        eq(subpart.get_content_type(), 'message/delivery-status')
+        eq(len(subpart.get_payload()), 2)
+        # message/delivery-status should treat each block as a bunch of
+        # headers, i.e. a bunch of Message objects.
+        dsn1 = subpart.get_payload(0)
+        unless(isinstance(dsn1, Message))
+        eq(dsn1['original-envelope-id'], '0GK500B4HD0888 at cougar.noc.ucla.edu')
+        eq(dsn1.get_param('dns', header='reporting-mta'), '')
+        # Try a missing one <wink>
+        eq(dsn1.get_param('nsd', header='reporting-mta'), None)
+        dsn2 = subpart.get_payload(1)
+        unless(isinstance(dsn2, Message))
+        eq(dsn2['action'], 'failed')
+        eq(dsn2.get_params(header='original-recipient'),
+           [('rfc822', ''), ('jangel1 at cougar.noc.ucla.edu', '')])
+        eq(dsn2.get_param('rfc822', header='final-recipient'), '')
+        # Subpart 3 is the original message
+        subpart = msg.get_payload(2)
+        eq(subpart.get_content_type(), 'message/rfc822')
+        payload = subpart.get_payload()
+        unless(isinstance(payload, list))
+        eq(len(payload), 1)
+        subsubpart = payload[0]
+        unless(isinstance(subsubpart, Message))
+        eq(subsubpart.get_content_type(), 'text/plain')
+        eq(subsubpart['message-id'],
+           '<002001c144a6$8752e060$56104586 at oxy.edu>')
+
+    def test_epilogue(self):
+        eq = self.ndiffAssertEqual
+        fp = openfile('msg_21.txt')
+        try:
+            text = fp.read()
+        finally:
+            fp.close()
+        msg = Message()
+        msg['From'] = 'aperson at dom.ain'
+        msg['To'] = 'bperson at dom.ain'
+        msg['Subject'] = 'Test'
+        msg.preamble = 'MIME message'
+        msg.epilogue = 'End of MIME message\n'
+        msg1 = MIMEText('One')
+        msg2 = MIMEText('Two')
+        msg.add_header('Content-Type', 'multipart/mixed', boundary='BOUNDARY')
+        msg.attach(msg1)
+        msg.attach(msg2)
+        sfp = StringIO()
+        g = Generator(sfp)
+        g.flatten(msg)
+        eq(sfp.getvalue(), text)
+
+    def test_no_nl_preamble(self):
+        eq = self.ndiffAssertEqual
+        msg = Message()
+        msg['From'] = 'aperson at dom.ain'
+        msg['To'] = 'bperson at dom.ain'
+        msg['Subject'] = 'Test'
+        msg.preamble = 'MIME message'
+        msg.epilogue = ''
+        msg1 = MIMEText('One')
+        msg2 = MIMEText('Two')
+        msg.add_header('Content-Type', 'multipart/mixed', boundary='BOUNDARY')
+        msg.attach(msg1)
+        msg.attach(msg2)
+        eq(msg.as_string(), """\
+From: aperson at dom.ain
+To: bperson at dom.ain
+Subject: Test
+Content-Type: multipart/mixed; boundary="BOUNDARY"
+
+MIME message
+--BOUNDARY
+Content-Type: text/plain; charset="us-ascii"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+
+One
+--BOUNDARY
+Content-Type: text/plain; charset="us-ascii"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+
+Two
+--BOUNDARY--
+""")
+
+    def test_default_type(self):
+        eq = self.assertEqual
+        fp = openfile('msg_30.txt')
+        try:
+            msg = email.message_from_file(fp)
+        finally:
+            fp.close()
+        container1 = msg.get_payload(0)
+        eq(container1.get_default_type(), 'message/rfc822')
+        eq(container1.get_content_type(), 'message/rfc822')
+        container2 = msg.get_payload(1)
+        eq(container2.get_default_type(), 'message/rfc822')
+        eq(container2.get_content_type(), 'message/rfc822')
+        container1a = container1.get_payload(0)
+        eq(container1a.get_default_type(), 'text/plain')
+        eq(container1a.get_content_type(), 'text/plain')
+        container2a = container2.get_payload(0)
+        eq(container2a.get_default_type(), 'text/plain')
+        eq(container2a.get_content_type(), 'text/plain')
+
+    def test_default_type_with_explicit_container_type(self):
+        eq = self.assertEqual
+        fp = openfile('msg_28.txt')
+        try:
+            msg = email.message_from_file(fp)
+        finally:
+            fp.close()
+        container1 = msg.get_payload(0)
+        eq(container1.get_default_type(), 'message/rfc822')
+        eq(container1.get_content_type(), 'message/rfc822')
+        container2 = msg.get_payload(1)
+        eq(container2.get_default_type(), 'message/rfc822')
+        eq(container2.get_content_type(), 'message/rfc822')
+        container1a = container1.get_payload(0)
+        eq(container1a.get_default_type(), 'text/plain')
+        eq(container1a.get_content_type(), 'text/plain')
+        container2a = container2.get_payload(0)
+        eq(container2a.get_default_type(), 'text/plain')
+        eq(container2a.get_content_type(), 'text/plain')
+
+    def test_default_type_non_parsed(self):
+        eq = self.assertEqual
+        neq = self.ndiffAssertEqual
+        # Set up container
+        container = MIMEMultipart('digest', 'BOUNDARY')
+        container.epilogue = ''
+        # Set up subparts
+        subpart1a = MIMEText('message 1\n')
+        subpart2a = MIMEText('message 2\n')
+        subpart1 = MIMEMessage(subpart1a)
+        subpart2 = MIMEMessage(subpart2a)
+        container.attach(subpart1)
+        container.attach(subpart2)
+        eq(subpart1.get_content_type(), 'message/rfc822')
+        eq(subpart1.get_default_type(), 'message/rfc822')
+        eq(subpart2.get_content_type(), 'message/rfc822')
+        eq(subpart2.get_default_type(), 'message/rfc822')
+        neq(container.as_string(0), '''\
+Content-Type: multipart/digest; boundary="BOUNDARY"
+MIME-Version: 1.0
+
+--BOUNDARY
+Content-Type: message/rfc822
+MIME-Version: 1.0
+
+Content-Type: text/plain; charset="us-ascii"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+
+message 1
+
+--BOUNDARY
+Content-Type: message/rfc822
+MIME-Version: 1.0
+
+Content-Type: text/plain; charset="us-ascii"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+
+message 2
+
+--BOUNDARY--
+''')
+        del subpart1['content-type']
+        del subpart1['mime-version']
+        del subpart2['content-type']
+        del subpart2['mime-version']
+        eq(subpart1.get_content_type(), 'message/rfc822')
+        eq(subpart1.get_default_type(), 'message/rfc822')
+        eq(subpart2.get_content_type(), 'message/rfc822')
+        eq(subpart2.get_default_type(), 'message/rfc822')
+        neq(container.as_string(0), '''\
+Content-Type: multipart/digest; boundary="BOUNDARY"
+MIME-Version: 1.0
+
+--BOUNDARY
+
+Content-Type: text/plain; charset="us-ascii"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+
+message 1
+
+--BOUNDARY
+
+Content-Type: text/plain; charset="us-ascii"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+
+message 2
+
+--BOUNDARY--
+''')
+
+    def test_mime_attachments_in_constructor(self):
+        eq = self.assertEqual
+        text1 = MIMEText('')
+        text2 = MIMEText('')
+        msg = MIMEMultipart(_subparts=(text1, text2))
+        eq(len(msg.get_payload()), 2)
+        eq(msg.get_payload(0), text1)
+        eq(msg.get_payload(1), text2)
+
+
+
+# A general test of parser->model->generator idempotency.  IOW, read a message
+# in, parse it into a message object tree, then without touching the tree,
+# regenerate the plain text.  The original text and the transformed text
+# should be identical.  Note: that we ignore the Unix-From since that may
+# contain a changed date.
+class TestIdempotent(TestEmailBase):
+    def _msgobj(self, filename):
+        fp = openfile(filename)
+        try:
+            data = fp.read()
+        finally:
+            fp.close()
+        msg = email.message_from_string(data)
+        return msg, data
+
+    def _idempotent(self, msg, text):
+        eq = self.ndiffAssertEqual
+        s = StringIO()
+        g = Generator(s, maxheaderlen=0)
+        g.flatten(msg)
+        eq(text, s.getvalue())
+
+    def test_parse_text_message(self):
+        eq = self.assertEquals
+        msg, text = self._msgobj('msg_01.txt')
+        eq(msg.get_content_type(), 'text/plain')
+        eq(msg.get_content_maintype(), 'text')
+        eq(msg.get_content_subtype(), 'plain')
+        eq(msg.get_params()[1], ('charset', 'us-ascii'))
+        eq(msg.get_param('charset'), 'us-ascii')
+        eq(msg.preamble, None)
+        eq(msg.epilogue, None)
+        self._idempotent(msg, text)
+
+    def test_parse_untyped_message(self):
+        eq = self.assertEquals
+        msg, text = self._msgobj('msg_03.txt')
+        eq(msg.get_content_type(), 'text/plain')
+        eq(msg.get_params(), None)
+        eq(msg.get_param('charset'), None)
+        self._idempotent(msg, text)
+
+    def test_simple_multipart(self):
+        msg, text = self._msgobj('msg_04.txt')
+        self._idempotent(msg, text)
+
+    def test_MIME_digest(self):
+        msg, text = self._msgobj('msg_02.txt')
+        self._idempotent(msg, text)
+
+    def test_long_header(self):
+        msg, text = self._msgobj('msg_27.txt')
+        self._idempotent(msg, text)
+
+    def test_MIME_digest_with_part_headers(self):
+        msg, text = self._msgobj('msg_28.txt')
+        self._idempotent(msg, text)
+
+    def test_mixed_with_image(self):
+        msg, text = self._msgobj('msg_06.txt')
+        self._idempotent(msg, text)
+
+    def test_multipart_report(self):
+        msg, text = self._msgobj('msg_05.txt')
+        self._idempotent(msg, text)
+
+    def test_dsn(self):
+        msg, text = self._msgobj('msg_16.txt')
+        self._idempotent(msg, text)
+
+    def test_preamble_epilogue(self):
+        msg, text = self._msgobj('msg_21.txt')
+        self._idempotent(msg, text)
+
+    def test_multipart_one_part(self):
+        msg, text = self._msgobj('msg_23.txt')
+        self._idempotent(msg, text)
+
+    def test_multipart_no_parts(self):
+        msg, text = self._msgobj('msg_24.txt')
+        self._idempotent(msg, text)
+
+    def test_no_start_boundary(self):
+        msg, text = self._msgobj('msg_31.txt')
+        self._idempotent(msg, text)
+
+    def test_rfc2231_charset(self):
+        msg, text = self._msgobj('msg_32.txt')
+        self._idempotent(msg, text)
+
+    def test_more_rfc2231_parameters(self):
+        msg, text = self._msgobj('msg_33.txt')
+        self._idempotent(msg, text)
+
+    def test_text_plain_in_a_multipart_digest(self):
+        msg, text = self._msgobj('msg_34.txt')
+        self._idempotent(msg, text)
+
+    def test_nested_multipart_mixeds(self):
+        msg, text = self._msgobj('msg_12a.txt')
+        self._idempotent(msg, text)
+
+    def test_message_external_body_idempotent(self):
+        msg, text = self._msgobj('msg_36.txt')
+        self._idempotent(msg, text)
+
+    def test_content_type(self):
+        eq = self.assertEquals
+        unless = self.failUnless
+        # Get a message object and reset the seek pointer for other tests
+        msg, text = self._msgobj('msg_05.txt')
+        eq(msg.get_content_type(), 'multipart/report')
+        # Test the Content-Type: parameters
+        params = {}
+        for pk, pv in msg.get_params():
+            params[pk] = pv
+        eq(params['report-type'], 'delivery-status')
+        eq(params['boundary'], 'D1690A7AC1.996856090/mail.example.com')
+        eq(msg.preamble, 'This is a MIME-encapsulated message.\n')
+        eq(msg.epilogue, '\n')
+        eq(len(msg.get_payload()), 3)
+        # Make sure the subparts are what we expect
+        msg1 = msg.get_payload(0)
+        eq(msg1.get_content_type(), 'text/plain')
+        eq(msg1.get_payload(), 'Yadda yadda yadda\n')
+        msg2 = msg.get_payload(1)
+        eq(msg2.get_content_type(), 'text/plain')
+        eq(msg2.get_payload(), 'Yadda yadda yadda\n')
+        msg3 = msg.get_payload(2)
+        eq(msg3.get_content_type(), 'message/rfc822')
+        self.failUnless(isinstance(msg3, Message))
+        payload = msg3.get_payload()
+        unless(isinstance(payload, list))
+        eq(len(payload), 1)
+        msg4 = payload[0]
+        unless(isinstance(msg4, Message))
+        eq(msg4.get_payload(), 'Yadda yadda yadda\n')
+
+    def test_parser(self):
+        eq = self.assertEquals
+        unless = self.failUnless
+        msg, text = self._msgobj('msg_06.txt')
+        # Check some of the outer headers
+        eq(msg.get_content_type(), 'message/rfc822')
+        # Make sure the payload is a list of exactly one sub-Message, and that
+        # that submessage has a type of text/plain
+        payload = msg.get_payload()
+        unless(isinstance(payload, list))
+        eq(len(payload), 1)
+        msg1 = payload[0]
+        self.failUnless(isinstance(msg1, Message))
+        eq(msg1.get_content_type(), 'text/plain')
+        self.failUnless(isinstance(msg1.get_payload(), str))
+        eq(msg1.get_payload(), '\n')
+
+
+
+# Test various other bits of the package's functionality
+class TestMiscellaneous(TestEmailBase):
+    def test_message_from_string(self):
+        fp = openfile('msg_01.txt')
+        try:
+            text = fp.read()
+        finally:
+            fp.close()
+        msg = email.message_from_string(text)
+        s = StringIO()
+        # Don't wrap/continue long headers since we're trying to test
+        # idempotency.
+        g = Generator(s, maxheaderlen=0)
+        g.flatten(msg)
+        self.assertEqual(text, s.getvalue())
+
+    def test_message_from_file(self):
+        fp = openfile('msg_01.txt')
+        try:
+            text = fp.read()
+            fp.seek(0)
+            msg = email.message_from_file(fp)
+            s = StringIO()
+            # Don't wrap/continue long headers since we're trying to test
+            # idempotency.
+            g = Generator(s, maxheaderlen=0)
+            g.flatten(msg)
+            self.assertEqual(text, s.getvalue())
+        finally:
+            fp.close()
+
+    def test_message_from_string_with_class(self):
+        unless = self.failUnless
+        fp = openfile('msg_01.txt')
+        try:
+            text = fp.read()
+        finally:
+            fp.close()
+        # Create a subclass
+        class MyMessage(Message):
+            pass
+
+        msg = email.message_from_string(text, MyMessage)
+        unless(isinstance(msg, MyMessage))
+        # Try something more complicated
+        fp = openfile('msg_02.txt')
+        try:
+            text = fp.read()
+        finally:
+            fp.close()
+        msg = email.message_from_string(text, MyMessage)
+        for subpart in msg.walk():
+            unless(isinstance(subpart, MyMessage))
+
+    def test_message_from_file_with_class(self):
+        unless = self.failUnless
+        # Create a subclass
+        class MyMessage(Message):
+            pass
+
+        fp = openfile('msg_01.txt')
+        try:
+            msg = email.message_from_file(fp, MyMessage)
+        finally:
+            fp.close()
+        unless(isinstance(msg, MyMessage))
+        # Try something more complicated
+        fp = openfile('msg_02.txt')
+        try:
+            msg = email.message_from_file(fp, MyMessage)
+        finally:
+            fp.close()
+        for subpart in msg.walk():
+            unless(isinstance(subpart, MyMessage))
+
+    def test__all__(self):
+        module = __import__('email')
+        # Can't use sorted() here due to Python 2.3 compatibility
+        all = module.__all__[:]
+        all.sort()
+        self.assertEqual(all, [
+            # Old names
+            'Charset', 'Encoders', 'Errors', 'Generator',
+            'Header', 'Iterators', 'MIMEAudio', 'MIMEBase',
+            'MIMEImage', 'MIMEMessage', 'MIMEMultipart',
+            'MIMENonMultipart', 'MIMEText', 'Message',
+            'Parser', 'Utils', 'base64MIME',
+            # new names
+            'base64mime', 'charset', 'encoders', 'errors', 'generator',
+            'header', 'iterators', 'message', 'message_from_file',
+            'message_from_string', 'mime', 'parser',
+            'quopriMIME', 'quoprimime', 'utils',
+            ])
+
+    def test_formatdate(self):
+        now = time.time()
+        self.assertEqual(utils.parsedate(utils.formatdate(now))[:6],
+                         time.gmtime(now)[:6])
+
+    def test_formatdate_localtime(self):
+        now = time.time()
+        self.assertEqual(
+            utils.parsedate(utils.formatdate(now, localtime=True))[:6],
+            time.localtime(now)[:6])
+
+    def test_formatdate_usegmt(self):
+        now = time.time()
+        self.assertEqual(
+            utils.formatdate(now, localtime=False),
+            time.strftime('%a, %d %b %Y %H:%M:%S -0000', time.gmtime(now)))
+        self.assertEqual(
+            utils.formatdate(now, localtime=False, usegmt=True),
+            time.strftime('%a, %d %b %Y %H:%M:%S GMT', time.gmtime(now)))
+
+    def test_parsedate_none(self):
+        self.assertEqual(utils.parsedate(''), None)
+
+    def test_parsedate_compact(self):
+        # The FWS after the comma is optional
+        self.assertEqual(utils.parsedate('Wed,3 Apr 2002 14:58:26 +0800'),
+                         utils.parsedate('Wed, 3 Apr 2002 14:58:26 +0800'))
+
+    def test_parsedate_no_dayofweek(self):
+        eq = self.assertEqual
+        eq(utils.parsedate_tz('25 Feb 2003 13:47:26 -0800'),
+           (2003, 2, 25, 13, 47, 26, 0, 1, -1, -28800))
+
+    def test_parsedate_compact_no_dayofweek(self):
+        eq = self.assertEqual
+        eq(utils.parsedate_tz('5 Feb 2003 13:47:26 -0800'),
+           (2003, 2, 5, 13, 47, 26, 0, 1, -1, -28800))
+
+    def test_parsedate_acceptable_to_time_functions(self):
+        eq = self.assertEqual
+        timetup = utils.parsedate('5 Feb 2003 13:47:26 -0800')
+        t = int(time.mktime(timetup))
+        eq(time.localtime(t)[:6], timetup[:6])
+        eq(int(time.strftime('%Y', timetup)), 2003)
+        timetup = utils.parsedate_tz('5 Feb 2003 13:47:26 -0800')
+        t = int(time.mktime(timetup[:9]))
+        eq(time.localtime(t)[:6], timetup[:6])
+        eq(int(time.strftime('%Y', timetup[:9])), 2003)
+
+    def test_parseaddr_empty(self):
+        self.assertEqual(utils.parseaddr('<>'), ('', ''))
+        self.assertEqual(utils.formataddr(utils.parseaddr('<>')), '')
+
+    def test_noquote_dump(self):
+        self.assertEqual(
+            utils.formataddr(('A Silly Person', 'person at dom.ain')),
+            'A Silly Person <person at dom.ain>')
+
+    def test_escape_dump(self):
+        self.assertEqual(
+            utils.formataddr(('A (Very) Silly Person', 'person at dom.ain')),
+            r'"A \(Very\) Silly Person" <person at dom.ain>')
+        a = r'A \(Special\) Person'
+        b = 'person at dom.ain'
+        self.assertEqual(utils.parseaddr(utils.formataddr((a, b))), (a, b))
+
+    def test_escape_backslashes(self):
+        self.assertEqual(
+            utils.formataddr(('Arthur \Backslash\ Foobar', 'person at dom.ain')),
+            r'"Arthur \\Backslash\\ Foobar" <person at dom.ain>')
+        a = r'Arthur \Backslash\ Foobar'
+        b = 'person at dom.ain'
+        self.assertEqual(utils.parseaddr(utils.formataddr((a, b))), (a, b))
+
+    def test_name_with_dot(self):
+        x = 'John X. Doe <jxd at example.com>'
+        y = '"John X. Doe" <jxd at example.com>'
+        a, b = ('John X. Doe', 'jxd at example.com')
+        self.assertEqual(utils.parseaddr(x), (a, b))
+        self.assertEqual(utils.parseaddr(y), (a, b))
+        # formataddr() quotes the name if there's a dot in it
+        self.assertEqual(utils.formataddr((a, b)), y)
+
+    def test_multiline_from_comment(self):
+        x = """\
+Foo
+\tBar <foo at example.com>"""
+        self.assertEqual(utils.parseaddr(x), ('Foo Bar', 'foo at example.com'))
+
+    def test_quote_dump(self):
+        self.assertEqual(
+            utils.formataddr(('A Silly; Person', 'person at dom.ain')),
+            r'"A Silly; Person" <person at dom.ain>')
+
+    def test_fix_eols(self):
+        eq = self.assertEqual
+        eq(utils.fix_eols('hello'), 'hello')
+        eq(utils.fix_eols('hello\n'), 'hello\r\n')
+        eq(utils.fix_eols('hello\r'), 'hello\r\n')
+        eq(utils.fix_eols('hello\r\n'), 'hello\r\n')
+        eq(utils.fix_eols('hello\n\r'), 'hello\r\n\r\n')
+
+    def test_charset_richcomparisons(self):
+        eq = self.assertEqual
+        ne = self.failIfEqual
+        cset1 = Charset()
+        cset2 = Charset()
+        eq(cset1, 'us-ascii')
+        eq(cset1, 'US-ASCII')
+        eq(cset1, 'Us-AsCiI')
+        eq('us-ascii', cset1)
+        eq('US-ASCII', cset1)
+        eq('Us-AsCiI', cset1)
+        ne(cset1, 'usascii')
+        ne(cset1, 'USASCII')
+        ne(cset1, 'UsAsCiI')
+        ne('usascii', cset1)
+        ne('USASCII', cset1)
+        ne('UsAsCiI', cset1)
+        eq(cset1, cset2)
+        eq(cset2, cset1)
+
+    def test_getaddresses(self):
+        eq = self.assertEqual
+        eq(utils.getaddresses(['aperson at dom.ain (Al Person)',
+                               'Bud Person <bperson at dom.ain>']),
+           [('Al Person', 'aperson at dom.ain'),
+            ('Bud Person', 'bperson at dom.ain')])
+
+    def test_getaddresses_nasty(self):
+        eq = self.assertEqual
+        eq(utils.getaddresses(['foo: ;']), [('', '')])
+        eq(utils.getaddresses(
+           ['[]*-- =~$']),
+           [('', ''), ('', ''), ('', '*--')])
+        eq(utils.getaddresses(
+           ['foo: ;', '"Jason R. Mastaler" <jason at dom.ain>']),
+           [('', ''), ('Jason R. Mastaler', 'jason at dom.ain')])
+
+    def test_getaddresses_embedded_comment(self):
+        """Test proper handling of a nested comment"""
+        eq = self.assertEqual
+        addrs = utils.getaddresses(['User ((nested comment)) <foo at bar.com>'])
+        eq(addrs[0][1], 'foo at bar.com')
+
+    def test_utils_quote_unquote(self):
+        eq = self.assertEqual
+        msg = Message()
+        msg.add_header('content-disposition', 'attachment',
+                       filename='foo\\wacky"name')
+        eq(msg.get_filename(), 'foo\\wacky"name')
+
+    def test_get_body_encoding_with_bogus_charset(self):
+        charset = Charset('not a charset')
+        self.assertEqual(charset.get_body_encoding(), 'base64')
+
+    def test_get_body_encoding_with_uppercase_charset(self):
+        eq = self.assertEqual
+        msg = Message()
+        msg['Content-Type'] = 'text/plain; charset=UTF-8'
+        eq(msg['content-type'], 'text/plain; charset=UTF-8')
+        charsets = msg.get_charsets()
+        eq(len(charsets), 1)
+        eq(charsets[0], 'utf-8')
+        charset = Charset(charsets[0])
+        eq(charset.get_body_encoding(), 'base64')
+        msg.set_payload('hello world', charset=charset)
+        eq(msg.get_payload(), 'aGVsbG8gd29ybGQ=\n')
+        eq(msg.get_payload(decode=True), 'hello world')
+        eq(msg['content-transfer-encoding'], 'base64')
+        # Try another one
+        msg = Message()
+        msg['Content-Type'] = 'text/plain; charset="US-ASCII"'
+        charsets = msg.get_charsets()
+        eq(len(charsets), 1)
+        eq(charsets[0], 'us-ascii')
+        charset = Charset(charsets[0])
+        eq(charset.get_body_encoding(), encoders.encode_7or8bit)
+        msg.set_payload('hello world', charset=charset)
+        eq(msg.get_payload(), 'hello world')
+        eq(msg['content-transfer-encoding'], '7bit')
+
+    def test_charsets_case_insensitive(self):
+        lc = Charset('us-ascii')
+        uc = Charset('US-ASCII')
+        self.assertEqual(lc.get_body_encoding(), uc.get_body_encoding())
+
+    def test_partial_falls_inside_message_delivery_status(self):
+        eq = self.ndiffAssertEqual
+        # The Parser interface provides chunks of data to FeedParser in 8192
+        # byte gulps.  SF bug #1076485 found one of those chunks inside
+        # message/delivery-status header block, which triggered an
+        # unreadline() of NeedMoreData.
+        msg = self._msgobj('msg_43.txt')
+        sfp = StringIO()
+        iterators._structure(msg, sfp)
+        eq(sfp.getvalue(), """\
+multipart/report
+    text/plain
+    message/delivery-status
+        text/plain
+        text/plain
+        text/plain
+        text/plain
+        text/plain
+        text/plain
+        text/plain
+        text/plain
+        text/plain
+        text/plain
+        text/plain
+        text/plain
+        text/plain
+        text/plain
+        text/plain
+        text/plain
+        text/plain
+        text/plain
+        text/plain
+        text/plain
+        text/plain
+        text/plain
+        text/plain
+        text/plain
+        text/plain
+        text/plain
+    text/rfc822-headers
+""")
+
+
+
+# Test the iterator/generators
+class TestIterators(TestEmailBase):
+    def test_body_line_iterator(self):
+        eq = self.assertEqual
+        neq = self.ndiffAssertEqual
+        # First a simple non-multipart message
+        msg = self._msgobj('msg_01.txt')
+        it = iterators.body_line_iterator(msg)
+        lines = list(it)
+        eq(len(lines), 6)
+        neq(EMPTYSTRING.join(lines), msg.get_payload())
+        # Now a more complicated multipart
+        msg = self._msgobj('msg_02.txt')
+        it = iterators.body_line_iterator(msg)
+        lines = list(it)
+        eq(len(lines), 43)
+        fp = openfile('msg_19.txt')
+        try:
+            neq(EMPTYSTRING.join(lines), fp.read())
+        finally:
+            fp.close()
+
+    def test_typed_subpart_iterator(self):
+        eq = self.assertEqual
+        msg = self._msgobj('msg_04.txt')
+        it = iterators.typed_subpart_iterator(msg, 'text')
+        lines = []
+        subparts = 0
+        for subpart in it:
+            subparts += 1
+            lines.append(subpart.get_payload())
+        eq(subparts, 2)
+        eq(EMPTYSTRING.join(lines), """\
+a simple kind of mirror
+to reflect upon our own
+a simple kind of mirror
+to reflect upon our own
+""")
+
+    def test_typed_subpart_iterator_default_type(self):
+        eq = self.assertEqual
+        msg = self._msgobj('msg_03.txt')
+        it = iterators.typed_subpart_iterator(msg, 'text', 'plain')
+        lines = []
+        subparts = 0
+        for subpart in it:
+            subparts += 1
+            lines.append(subpart.get_payload())
+        eq(subparts, 1)
+        eq(EMPTYSTRING.join(lines), """\
+
+Hi,
+
+Do you like this message?
+
+-Me
+""")
+
+
+
+class TestParsers(TestEmailBase):
+    def test_header_parser(self):
+        eq = self.assertEqual
+        # Parse only the headers of a complex multipart MIME document
+        fp = openfile('msg_02.txt')
+        try:
+            msg = HeaderParser().parse(fp)
+        finally:
+            fp.close()
+        eq(msg['from'], 'ppp-request at zzz.org')
+        eq(msg['to'], 'ppp at zzz.org')
+        eq(msg.get_content_type(), 'multipart/mixed')
+        self.failIf(msg.is_multipart())
+        self.failUnless(isinstance(msg.get_payload(), str))
+
+    def test_whitespace_continuation(self):
+        eq = self.assertEqual
+        # This message contains a line after the Subject: header that has only
+        # whitespace, but it is not empty!
+        msg = email.message_from_string("""\
+From: aperson at dom.ain
+To: bperson at dom.ain
+Subject: the next line has a space on it
+\x20
+Date: Mon, 8 Apr 2002 15:09:19 -0400
+Message-ID: spam
+
+Here's the message body
+""")
+        eq(msg['subject'], 'the next line has a space on it\n ')
+        eq(msg['message-id'], 'spam')
+        eq(msg.get_payload(), "Here's the message body\n")
+
+    def test_whitespace_continuation_last_header(self):
+        eq = self.assertEqual
+        # Like the previous test, but the subject line is the last
+        # header.
+        msg = email.message_from_string("""\
+From: aperson at dom.ain
+To: bperson at dom.ain
+Date: Mon, 8 Apr 2002 15:09:19 -0400
+Message-ID: spam
+Subject: the next line has a space on it
+\x20
+
+Here's the message body
+""")
+        eq(msg['subject'], 'the next line has a space on it\n ')
+        eq(msg['message-id'], 'spam')
+        eq(msg.get_payload(), "Here's the message body\n")
+
+    def test_crlf_separation(self):
+        eq = self.assertEqual
+        fp = openfile('msg_26.txt', mode='rb')
+        try:
+            msg = Parser().parse(fp)
+        finally:
+            fp.close()
+        eq(len(msg.get_payload()), 2)
+        part1 = msg.get_payload(0)
+        eq(part1.get_content_type(), 'text/plain')
+        eq(part1.get_payload(), 'Simple email with attachment.\r\n\r\n')
+        part2 = msg.get_payload(1)
+        eq(part2.get_content_type(), 'application/riscos')
+
+    def test_multipart_digest_with_extra_mime_headers(self):
+        eq = self.assertEqual
+        neq = self.ndiffAssertEqual
+        fp = openfile('msg_28.txt')
+        try:
+            msg = email.message_from_file(fp)
+        finally:
+            fp.close()
+        # Structure is:
+        # multipart/digest
+        #   message/rfc822
+        #     text/plain
+        #   message/rfc822
+        #     text/plain
+        eq(msg.is_multipart(), 1)
+        eq(len(msg.get_payload()), 2)
+        part1 = msg.get_payload(0)
+        eq(part1.get_content_type(), 'message/rfc822')
+        eq(part1.is_multipart(), 1)
+        eq(len(part1.get_payload()), 1)
+        part1a = part1.get_payload(0)
+        eq(part1a.is_multipart(), 0)
+        eq(part1a.get_content_type(), 'text/plain')
+        neq(part1a.get_payload(), 'message 1\n')
+        # next message/rfc822
+        part2 = msg.get_payload(1)
+        eq(part2.get_content_type(), 'message/rfc822')
+        eq(part2.is_multipart(), 1)
+        eq(len(part2.get_payload()), 1)
+        part2a = part2.get_payload(0)
+        eq(part2a.is_multipart(), 0)
+        eq(part2a.get_content_type(), 'text/plain')
+        neq(part2a.get_payload(), 'message 2\n')
+
+    def test_three_lines(self):
+        # A bug report by Andrew McNamara
+        lines = ['From: Andrew Person <aperson at dom.ain',
+                 'Subject: Test',
+                 'Date: Tue, 20 Aug 2002 16:43:45 +1000']
+        msg = email.message_from_string(NL.join(lines))
+        self.assertEqual(msg['date'], 'Tue, 20 Aug 2002 16:43:45 +1000')
+
+    def test_strip_line_feed_and_carriage_return_in_headers(self):
+        eq = self.assertEqual
+        # For [ 1002475 ] email message parser doesn't handle \r\n correctly
+        value1 = 'text'
+        value2 = 'more text'
+        m = 'Header: %s\r\nNext-Header: %s\r\n\r\nBody\r\n\r\n' % (
+            value1, value2)
+        msg = email.message_from_string(m)
+        eq(msg.get('Header'), value1)
+        eq(msg.get('Next-Header'), value2)
+
+    def test_rfc2822_header_syntax(self):
+        eq = self.assertEqual
+        m = '>From: foo\nFrom: bar\n!"#QUX;~: zoo\n\nbody'
+        msg = email.message_from_string(m)
+        eq(len(msg.keys()), 3)
+        keys = msg.keys()
+        keys.sort()
+        eq(keys, ['!"#QUX;~', '>From', 'From'])
+        eq(msg.get_payload(), 'body')
+
+    def test_rfc2822_space_not_allowed_in_header(self):
+        eq = self.assertEqual
+        m = '>From foo at example.com 11:25:53\nFrom: bar\n!"#QUX;~: zoo\n\nbody'
+        msg = email.message_from_string(m)
+        eq(len(msg.keys()), 0)
+
+    def test_rfc2822_one_character_header(self):
+        eq = self.assertEqual
+        m = 'A: first header\nB: second header\nCC: third header\n\nbody'
+        msg = email.message_from_string(m)
+        headers = msg.keys()
+        headers.sort()
+        eq(headers, ['A', 'B', 'CC'])
+        eq(msg.get_payload(), 'body')
+
+
+
+class TestBase64(unittest.TestCase):
+    def test_len(self):
+        eq = self.assertEqual
+        eq(base64mime.base64_len('hello'),
+           len(base64mime.encode('hello', eol='')))
+        for size in range(15):
+            if   size == 0 : bsize = 0
+            elif size <= 3 : bsize = 4
+            elif size <= 6 : bsize = 8
+            elif size <= 9 : bsize = 12
+            elif size <= 12: bsize = 16
+            else           : bsize = 20
+            eq(base64mime.base64_len('x'*size), bsize)
+
+    def test_decode(self):
+        eq = self.assertEqual
+        eq(base64mime.decode(''), '')
+        eq(base64mime.decode('aGVsbG8='), 'hello')
+        eq(base64mime.decode('aGVsbG8=', 'X'), 'hello')
+        eq(base64mime.decode('aGVsbG8NCndvcmxk\n', 'X'), 'helloXworld')
+
+    def test_encode(self):
+        eq = self.assertEqual
+        eq(base64mime.encode(''), '')
+        eq(base64mime.encode('hello'), 'aGVsbG8=\n')
+        # Test the binary flag
+        eq(base64mime.encode('hello\n'), 'aGVsbG8K\n')
+        eq(base64mime.encode('hello\n', 0), 'aGVsbG8NCg==\n')
+        # Test the maxlinelen arg
+        eq(base64mime.encode('xxxx ' * 20, maxlinelen=40), """\
+eHh4eCB4eHh4IHh4eHggeHh4eCB4eHh4IHh4eHgg
+eHh4eCB4eHh4IHh4eHggeHh4eCB4eHh4IHh4eHgg
+eHh4eCB4eHh4IHh4eHggeHh4eCB4eHh4IHh4eHgg
+eHh4eCB4eHh4IA==
+""")
+        # Test the eol argument
+        eq(base64mime.encode('xxxx ' * 20, maxlinelen=40, eol='\r\n'), """\
+eHh4eCB4eHh4IHh4eHggeHh4eCB4eHh4IHh4eHgg\r
+eHh4eCB4eHh4IHh4eHggeHh4eCB4eHh4IHh4eHgg\r
+eHh4eCB4eHh4IHh4eHggeHh4eCB4eHh4IHh4eHgg\r
+eHh4eCB4eHh4IA==\r
+""")
+
+    def test_header_encode(self):
+        eq = self.assertEqual
+        he = base64mime.header_encode
+        eq(he('hello'), '=?iso-8859-1?b?aGVsbG8=?=')
+        eq(he('hello\nworld'), '=?iso-8859-1?b?aGVsbG8NCndvcmxk?=')
+        # Test the charset option
+        eq(he('hello', charset='iso-8859-2'), '=?iso-8859-2?b?aGVsbG8=?=')
+        # Test the keep_eols flag
+        eq(he('hello\nworld', keep_eols=True),
+           '=?iso-8859-1?b?aGVsbG8Kd29ybGQ=?=')
+        # Test the maxlinelen argument
+        eq(he('xxxx ' * 20, maxlinelen=40), """\
+=?iso-8859-1?b?eHh4eCB4eHh4IHh4eHggeHg=?=
+ =?iso-8859-1?b?eHggeHh4eCB4eHh4IHh4eHg=?=
+ =?iso-8859-1?b?IHh4eHggeHh4eCB4eHh4IHg=?=
+ =?iso-8859-1?b?eHh4IHh4eHggeHh4eCB4eHg=?=
+ =?iso-8859-1?b?eCB4eHh4IHh4eHggeHh4eCA=?=
+ =?iso-8859-1?b?eHh4eCB4eHh4IHh4eHgg?=""")
+        # Test the eol argument
+        eq(he('xxxx ' * 20, maxlinelen=40, eol='\r\n'), """\
+=?iso-8859-1?b?eHh4eCB4eHh4IHh4eHggeHg=?=\r
+ =?iso-8859-1?b?eHggeHh4eCB4eHh4IHh4eHg=?=\r
+ =?iso-8859-1?b?IHh4eHggeHh4eCB4eHh4IHg=?=\r
+ =?iso-8859-1?b?eHh4IHh4eHggeHh4eCB4eHg=?=\r
+ =?iso-8859-1?b?eCB4eHh4IHh4eHggeHh4eCA=?=\r
+ =?iso-8859-1?b?eHh4eCB4eHh4IHh4eHgg?=""")
+
+
+
+class TestQuopri(unittest.TestCase):
+    def setUp(self):
+        self.hlit = [chr(x) for x in range(ord('a'), ord('z')+1)] + \
+                    [chr(x) for x in range(ord('A'), ord('Z')+1)] + \
+                    [chr(x) for x in range(ord('0'), ord('9')+1)] + \
+                    ['!', '*', '+', '-', '/', ' ']
+        self.hnon = [chr(x) for x in range(256) if chr(x) not in self.hlit]
+        assert len(self.hlit) + len(self.hnon) == 256
+        self.blit = [chr(x) for x in range(ord(' '), ord('~')+1)] + ['\t']
+        self.blit.remove('=')
+        self.bnon = [chr(x) for x in range(256) if chr(x) not in self.blit]
+        assert len(self.blit) + len(self.bnon) == 256
+
+    def test_header_quopri_check(self):
+        for c in self.hlit:
+            self.failIf(quoprimime.header_quopri_check(c))
+        for c in self.hnon:
+            self.failUnless(quoprimime.header_quopri_check(c))
+
+    def test_body_quopri_check(self):
+        for c in self.blit:
+            self.failIf(quoprimime.body_quopri_check(c))
+        for c in self.bnon:
+            self.failUnless(quoprimime.body_quopri_check(c))
+
+    def test_header_quopri_len(self):
+        eq = self.assertEqual
+        hql = quoprimime.header_quopri_len
+        enc = quoprimime.header_encode
+        for s in ('hello', 'h at e@l at l@o@'):
+            # Empty charset and no line-endings.  7 == RFC chrome
+            eq(hql(s), len(enc(s, charset='', eol=''))-7)
+        for c in self.hlit:
+            eq(hql(c), 1)
+        for c in self.hnon:
+            eq(hql(c), 3)
+
+    def test_body_quopri_len(self):
+        eq = self.assertEqual
+        bql = quoprimime.body_quopri_len
+        for c in self.blit:
+            eq(bql(c), 1)
+        for c in self.bnon:
+            eq(bql(c), 3)
+
+    def test_quote_unquote_idempotent(self):
+        for x in range(256):
+            c = chr(x)
+            self.assertEqual(quoprimime.unquote(quoprimime.quote(c)), c)
+
+    def test_header_encode(self):
+        eq = self.assertEqual
+        he = quoprimime.header_encode
+        eq(he('hello'), '=?iso-8859-1?q?hello?=')
+        eq(he('hello\nworld'), '=?iso-8859-1?q?hello=0D=0Aworld?=')
+        # Test the charset option
+        eq(he('hello', charset='iso-8859-2'), '=?iso-8859-2?q?hello?=')
+        # Test the keep_eols flag
+        eq(he('hello\nworld', keep_eols=True), '=?iso-8859-1?q?hello=0Aworld?=')
+        # Test a non-ASCII character
+        eq(he('hello\xc7there'), '=?iso-8859-1?q?hello=C7there?=')
+        # Test the maxlinelen argument
+        eq(he('xxxx ' * 20, maxlinelen=40), """\
+=?iso-8859-1?q?xxxx_xxxx_xxxx_xxxx_xx?=
+ =?iso-8859-1?q?xx_xxxx_xxxx_xxxx_xxxx?=
+ =?iso-8859-1?q?_xxxx_xxxx_xxxx_xxxx_x?=
+ =?iso-8859-1?q?xxx_xxxx_xxxx_xxxx_xxx?=
+ =?iso-8859-1?q?x_xxxx_xxxx_?=""")
+        # Test the eol argument
+        eq(he('xxxx ' * 20, maxlinelen=40, eol='\r\n'), """\
+=?iso-8859-1?q?xxxx_xxxx_xxxx_xxxx_xx?=\r
+ =?iso-8859-1?q?xx_xxxx_xxxx_xxxx_xxxx?=\r
+ =?iso-8859-1?q?_xxxx_xxxx_xxxx_xxxx_x?=\r
+ =?iso-8859-1?q?xxx_xxxx_xxxx_xxxx_xxx?=\r
+ =?iso-8859-1?q?x_xxxx_xxxx_?=""")
+
+    def test_decode(self):
+        eq = self.assertEqual
+        eq(quoprimime.decode(''), '')
+        eq(quoprimime.decode('hello'), 'hello')
+        eq(quoprimime.decode('hello', 'X'), 'hello')
+        eq(quoprimime.decode('hello\nworld', 'X'), 'helloXworld')
+
+    def test_encode(self):
+        eq = self.assertEqual
+        eq(quoprimime.encode(''), '')
+        eq(quoprimime.encode('hello'), 'hello')
+        # Test the binary flag
+        eq(quoprimime.encode('hello\r\nworld'), 'hello\nworld')
+        eq(quoprimime.encode('hello\r\nworld', 0), 'hello\nworld')
+        # Test the maxlinelen arg
+        eq(quoprimime.encode('xxxx ' * 20, maxlinelen=40), """\
+xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx=
+ xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxx=
+x xxxx xxxx xxxx xxxx=20""")
+        # Test the eol argument
+        eq(quoprimime.encode('xxxx ' * 20, maxlinelen=40, eol='\r\n'), """\
+xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx=\r
+ xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxx=\r
+x xxxx xxxx xxxx xxxx=20""")
+        eq(quoprimime.encode("""\
+one line
+
+two line"""), """\
+one line
+
+two line""")
+
+
+
+# Test the Charset class
+class TestCharset(unittest.TestCase):
+    def tearDown(self):
+        from email import charset as CharsetModule
+        try:
+            del CharsetModule.CHARSETS['fake']
+        except KeyError:
+            pass
+
+    def test_idempotent(self):
+        eq = self.assertEqual
+        # Make sure us-ascii = no Unicode conversion
+        c = Charset('us-ascii')
+        s = 'Hello World!'
+        sp = c.to_splittable(s)
+        eq(s, c.from_splittable(sp))
+        # test 8-bit idempotency with us-ascii
+        s = '\xa4\xa2\xa4\xa4\xa4\xa6\xa4\xa8\xa4\xaa'
+        sp = c.to_splittable(s)
+        eq(s, c.from_splittable(sp))
+
+    def test_body_encode(self):
+        eq = self.assertEqual
+        # Try a charset with QP body encoding
+        c = Charset('iso-8859-1')
+        eq('hello w=F6rld', c.body_encode('hello w\xf6rld'))
+        # Try a charset with Base64 body encoding
+        c = Charset('utf-8')
+        eq('aGVsbG8gd29ybGQ=\n', c.body_encode('hello world'))
+        # Try a charset with None body encoding
+        c = Charset('us-ascii')
+        eq('hello world', c.body_encode('hello world'))
+        # Try the convert argument, where input codec <> output codec
+        c = Charset('euc-jp')
+        # With apologies to Tokio Kikuchi ;)
+        try:
+            eq('\x1b$B5FCO;~IW\x1b(B',
+               c.body_encode('\xb5\xc6\xc3\xcf\xbb\xfe\xc9\xd7'))
+            eq('\xb5\xc6\xc3\xcf\xbb\xfe\xc9\xd7',
+               c.body_encode('\xb5\xc6\xc3\xcf\xbb\xfe\xc9\xd7', False))
+        except LookupError:
+            # We probably don't have the Japanese codecs installed
+            pass
+        # Testing SF bug #625509, which we have to fake, since there are no
+        # built-in encodings where the header encoding is QP but the body
+        # encoding is not.
+        from email import charset as CharsetModule
+        CharsetModule.add_charset('fake', CharsetModule.QP, None)
+        c = Charset('fake')
+        eq('hello w\xf6rld', c.body_encode('hello w\xf6rld'))
+
+    def test_unicode_charset_name(self):
+        charset = Charset(u'us-ascii')
+        self.assertEqual(str(charset), 'us-ascii')
+        self.assertRaises(errors.CharsetError, Charset, 'asc\xffii')
+
+
+
+# Test multilingual MIME headers.
+class TestHeader(TestEmailBase):
+    def test_simple(self):
+        eq = self.ndiffAssertEqual
+        h = Header('Hello World!')
+        eq(h.encode(), 'Hello World!')
+        h.append(' Goodbye World!')
+        eq(h.encode(), 'Hello World!  Goodbye World!')
+
+    def test_simple_surprise(self):
+        eq = self.ndiffAssertEqual
+        h = Header('Hello World!')
+        eq(h.encode(), 'Hello World!')
+        h.append('Goodbye World!')
+        eq(h.encode(), 'Hello World! Goodbye World!')
+
+    def test_header_needs_no_decoding(self):
+        h = 'no decoding needed'
+        self.assertEqual(decode_header(h), [(h, None)])
+
+    def test_long(self):
+        h = Header("I am the very model of a modern Major-General; I've information vegetable, animal, and mineral; I know the kings of England, and I quote the fights historical from Marathon to Waterloo, in order categorical; I'm very well acquainted, too, with matters mathematical; I understand equations, both the simple and quadratical; about binomial theorem I'm teeming with a lot o' news, with many cheerful facts about the square of the hypotenuse.",
+                   maxlinelen=76)
+        for l in h.encode(splitchars=' ').split('\n '):
+            self.failUnless(len(l) <= 76)
+
+    def test_multilingual(self):
+        eq = self.ndiffAssertEqual
+        g = Charset("iso-8859-1")
+        cz = Charset("iso-8859-2")
+        utf8 = Charset("utf-8")
+        g_head = "Die Mieter treten hier ein werden mit einem Foerderband komfortabel den Korridor entlang, an s\xfcdl\xfcndischen Wandgem\xe4lden vorbei, gegen die rotierenden Klingen bef\xf6rdert. "
+        cz_head = "Finan\xe8ni metropole se hroutily pod tlakem jejich d\xf9vtipu.. "
+        utf8_head = u"\u6b63\u78ba\u306b\u8a00\u3046\u3068\u7ffb\u8a33\u306f\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002\u4e00\u90e8\u306f\u30c9\u30a4\u30c4\u8a9e\u3067\u3059\u304c\u3001\u3042\u3068\u306f\u3067\u305f\u3089\u3081\u3067\u3059\u3002\u5b9f\u969b\u306b\u306f\u300cWenn ist das Nunstuck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput.\u300d\u3068\u8a00\u3063\u3066\u3044\u307e\u3059\u3002".encode("utf-8")
+        h = Header(g_head, g)
+        h.append(cz_head, cz)
+        h.append(utf8_head, utf8)
+        enc = h.encode()
+        eq(enc, """\
+=?iso-8859-1?q?Die_Mieter_treten_hier_ein_werden_mit_einem_Foerderband_ko?=
+ =?iso-8859-1?q?mfortabel_den_Korridor_entlang=2C_an_s=FCdl=FCndischen_Wan?=
+ =?iso-8859-1?q?dgem=E4lden_vorbei=2C_gegen_die_rotierenden_Klingen_bef=F6?=
+ =?iso-8859-1?q?rdert=2E_?= =?iso-8859-2?q?Finan=E8ni_metropole_se_hroutily?=
+ =?iso-8859-2?q?_pod_tlakem_jejich_d=F9vtipu=2E=2E_?= =?utf-8?b?5q2j56K6?=
+ =?utf-8?b?44Gr6KiA44GG44Go57+76Kiz44Gv44GV44KM44Gm44GE44G+44Gb44KT44CC?=
+ =?utf-8?b?5LiA6YOo44Gv44OJ44Kk44OE6Kqe44Gn44GZ44GM44CB44GC44Go44Gv44Gn?=
+ =?utf-8?b?44Gf44KJ44KB44Gn44GZ44CC5a6f6Zqb44Gr44Gv44CMV2VubiBpc3QgZGFz?=
+ =?utf-8?q?_Nunstuck_git_und_Slotermeyer=3F_Ja!_Beiherhund_das_Oder_die_Fl?=
+ =?utf-8?b?aXBwZXJ3YWxkdCBnZXJzcHV0LuOAjeOBqOiogOOBo+OBpuOBhOOBvuOBmQ==?=
+ =?utf-8?b?44CC?=""")
+        eq(decode_header(enc),
+           [(g_head, "iso-8859-1"), (cz_head, "iso-8859-2"),
+            (utf8_head, "utf-8")])
+        ustr = unicode(h)
+        eq(ustr.encode('utf-8'),
+           'Die Mieter treten hier ein werden mit einem Foerderband '
+           'komfortabel den Korridor entlang, an s\xc3\xbcdl\xc3\xbcndischen '
+           'Wandgem\xc3\xa4lden vorbei, gegen die rotierenden Klingen '
+           'bef\xc3\xb6rdert. Finan\xc4\x8dni metropole se hroutily pod '
+           'tlakem jejich d\xc5\xafvtipu.. \xe6\xad\xa3\xe7\xa2\xba\xe3\x81'
+           '\xab\xe8\xa8\x80\xe3\x81\x86\xe3\x81\xa8\xe7\xbf\xbb\xe8\xa8\xb3'
+           '\xe3\x81\xaf\xe3\x81\x95\xe3\x82\x8c\xe3\x81\xa6\xe3\x81\x84\xe3'
+           '\x81\xbe\xe3\x81\x9b\xe3\x82\x93\xe3\x80\x82\xe4\xb8\x80\xe9\x83'
+           '\xa8\xe3\x81\xaf\xe3\x83\x89\xe3\x82\xa4\xe3\x83\x84\xe8\xaa\x9e'
+           '\xe3\x81\xa7\xe3\x81\x99\xe3\x81\x8c\xe3\x80\x81\xe3\x81\x82\xe3'
+           '\x81\xa8\xe3\x81\xaf\xe3\x81\xa7\xe3\x81\x9f\xe3\x82\x89\xe3\x82'
+           '\x81\xe3\x81\xa7\xe3\x81\x99\xe3\x80\x82\xe5\xae\x9f\xe9\x9a\x9b'
+           '\xe3\x81\xab\xe3\x81\xaf\xe3\x80\x8cWenn ist das Nunstuck git '
+           'und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt '
+           'gersput.\xe3\x80\x8d\xe3\x81\xa8\xe8\xa8\x80\xe3\x81\xa3\xe3\x81'
+           '\xa6\xe3\x81\x84\xe3\x81\xbe\xe3\x81\x99\xe3\x80\x82')
+        # Test make_header()
+        newh = make_header(decode_header(enc))
+        eq(newh, enc)
+
+    def test_header_ctor_default_args(self):
+        eq = self.ndiffAssertEqual
+        h = Header()
+        eq(h, '')
+        h.append('foo', Charset('iso-8859-1'))
+        eq(h, '=?iso-8859-1?q?foo?=')
+
+    def test_explicit_maxlinelen(self):
+        eq = self.ndiffAssertEqual
+        hstr = 'A very long line that must get split to something other than at the 76th character boundary to test the non-default behavior'
+        h = Header(hstr)
+        eq(h.encode(), '''\
+A very long line that must get split to something other than at the 76th
+ character boundary to test the non-default behavior''')
+        h = Header(hstr, header_name='Subject')
+        eq(h.encode(), '''\
+A very long line that must get split to something other than at the
+ 76th character boundary to test the non-default behavior''')
+        h = Header(hstr, maxlinelen=1024, header_name='Subject')
+        eq(h.encode(), hstr)
+
+    def test_us_ascii_header(self):
+        eq = self.assertEqual
+        s = 'hello'
+        x = decode_header(s)
+        eq(x, [('hello', None)])
+        h = make_header(x)
+        eq(s, h.encode())
+
+    def test_string_charset(self):
+        eq = self.assertEqual
+        h = Header()
+        h.append('hello', 'iso-8859-1')
+        eq(h, '=?iso-8859-1?q?hello?=')
+
+##    def test_unicode_error(self):
+##        raises = self.assertRaises
+##        raises(UnicodeError, Header, u'[P\xf6stal]', 'us-ascii')
+##        raises(UnicodeError, Header, '[P\xf6stal]', 'us-ascii')
+##        h = Header()
+##        raises(UnicodeError, h.append, u'[P\xf6stal]', 'us-ascii')
+##        raises(UnicodeError, h.append, '[P\xf6stal]', 'us-ascii')
+##        raises(UnicodeError, Header, u'\u83ca\u5730\u6642\u592b', 'iso-8859-1')
+
+    def test_utf8_shortest(self):
+        eq = self.assertEqual
+        h = Header(u'p\xf6stal', 'utf-8')
+        eq(h.encode(), '=?utf-8?q?p=C3=B6stal?=')
+        h = Header(u'\u83ca\u5730\u6642\u592b', 'utf-8')
+        eq(h.encode(), '=?utf-8?b?6I+K5Zyw5pmC5aSr?=')
+
+    def test_bad_8bit_header(self):
+        raises = self.assertRaises
+        eq = self.assertEqual
+        x = 'Ynwp4dUEbay Auction Semiar- No Charge \x96 Earn Big'
+        raises(UnicodeError, Header, x)
+        h = Header()
+        raises(UnicodeError, h.append, x)
+        eq(str(Header(x, errors='replace')), x)
+        h.append(x, errors='replace')
+        eq(str(h), x)
+
+    def test_encoded_adjacent_nonencoded(self):
+        eq = self.assertEqual
+        h = Header()
+        h.append('hello', 'iso-8859-1')
+        h.append('world')
+        s = h.encode()
+        eq(s, '=?iso-8859-1?q?hello?= world')
+        h = make_header(decode_header(s))
+        eq(h.encode(), s)
+
+    def test_whitespace_eater(self):
+        eq = self.assertEqual
+        s = 'Subject: =?koi8-r?b?8NLP18XSy8EgzsEgxsnOwczYztk=?= =?koi8-r?q?=CA?= zz.'
+        parts = decode_header(s)
+        eq(parts, [('Subject:', None), ('\xf0\xd2\xcf\xd7\xc5\xd2\xcb\xc1 \xce\xc1 \xc6\xc9\xce\xc1\xcc\xd8\xce\xd9\xca', 'koi8-r'), ('zz.', None)])
+        hdr = make_header(parts)
+        eq(hdr.encode(),
+           'Subject: =?koi8-r?b?8NLP18XSy8EgzsEgxsnOwczYztnK?= zz.')
+
+    def test_broken_base64_header(self):
+        raises = self.assertRaises
+        s = 'Subject: =?EUC-KR?B?CSixpLDtKSC/7Liuvsax4iC6uLmwMcijIKHaILzSwd/H0SC8+LCjwLsgv7W/+Mj3IQ?='
+        raises(errors.HeaderParseError, decode_header, s)
+
+
+
+# Test RFC 2231 header parameters (en/de)coding
+class TestRFC2231(TestEmailBase):
+    def test_get_param(self):
+        eq = self.assertEqual
+        msg = self._msgobj('msg_29.txt')
+        eq(msg.get_param('title'),
+           ('us-ascii', 'en', 'This is even more ***fun*** isn\'t it!'))
+        eq(msg.get_param('title', unquote=False),
+           ('us-ascii', 'en', '"This is even more ***fun*** isn\'t it!"'))
+
+    def test_set_param(self):
+        eq = self.assertEqual
+        msg = Message()
+        msg.set_param('title', 'This is even more ***fun*** isn\'t it!',
+                      charset='us-ascii')
+        eq(msg.get_param('title'),
+           ('us-ascii', '', 'This is even more ***fun*** isn\'t it!'))
+        msg.set_param('title', 'This is even more ***fun*** isn\'t it!',
+                      charset='us-ascii', language='en')
+        eq(msg.get_param('title'),
+           ('us-ascii', 'en', 'This is even more ***fun*** isn\'t it!'))
+        msg = self._msgobj('msg_01.txt')
+        msg.set_param('title', 'This is even more ***fun*** isn\'t it!',
+                      charset='us-ascii', language='en')
+        eq(msg.as_string(), """\
+Return-Path: <bbb at zzz.org>
+Delivered-To: bbb at zzz.org
+Received: by mail.zzz.org (Postfix, from userid 889)
+\tid 27CEAD38CC; Fri,  4 May 2001 14:05:44 -0400 (EDT)
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+Message-ID: <15090.61304.110929.45684 at aaa.zzz.org>
+From: bbb at ddd.com (John X. Doe)
+To: bbb at zzz.org
+Subject: This is a test message
+Date: Fri, 4 May 2001 14:05:44 -0400
+Content-Type: text/plain; charset=us-ascii;
+\ttitle*="us-ascii'en'This%20is%20even%20more%20%2A%2A%2Afun%2A%2A%2A%20isn%27t%20it%21"
+
+
+Hi,
+
+Do you like this message?
+
+-Me
+""")
+
+    def test_del_param(self):
+        eq = self.ndiffAssertEqual
+        msg = self._msgobj('msg_01.txt')
+        msg.set_param('foo', 'bar', charset='us-ascii', language='en')
+        msg.set_param('title', 'This is even more ***fun*** isn\'t it!',
+            charset='us-ascii', language='en')
+        msg.del_param('foo', header='Content-Type')
+        eq(msg.as_string(), """\
+Return-Path: <bbb at zzz.org>
+Delivered-To: bbb at zzz.org
+Received: by mail.zzz.org (Postfix, from userid 889)
+\tid 27CEAD38CC; Fri,  4 May 2001 14:05:44 -0400 (EDT)
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+Message-ID: <15090.61304.110929.45684 at aaa.zzz.org>
+From: bbb at ddd.com (John X. Doe)
+To: bbb at zzz.org
+Subject: This is a test message
+Date: Fri, 4 May 2001 14:05:44 -0400
+Content-Type: text/plain; charset="us-ascii";
+\ttitle*="us-ascii'en'This%20is%20even%20more%20%2A%2A%2Afun%2A%2A%2A%20isn%27t%20it%21"
+
+
+Hi,
+
+Do you like this message?
+
+-Me
+""")
+
+    def test_rfc2231_get_content_charset(self):
+        eq = self.assertEqual
+        msg = self._msgobj('msg_32.txt')
+        eq(msg.get_content_charset(), 'us-ascii')
+
+    def test_rfc2231_no_language_or_charset(self):
+        m = '''\
+Content-Transfer-Encoding: 8bit
+Content-Disposition: inline; filename="file____C__DOCUMENTS_20AND_20SETTINGS_FABIEN_LOCAL_20SETTINGS_TEMP_nsmail.htm"
+Content-Type: text/html; NAME*0=file____C__DOCUMENTS_20AND_20SETTINGS_FABIEN_LOCAL_20SETTINGS_TEM; NAME*1=P_nsmail.htm
+
+'''
+        msg = email.message_from_string(m)
+        param = msg.get_param('NAME')
+        self.failIf(isinstance(param, tuple))
+        self.assertEqual(
+            param,
+            'file____C__DOCUMENTS_20AND_20SETTINGS_FABIEN_LOCAL_20SETTINGS_TEMP_nsmail.htm')
+
+    def test_rfc2231_no_language_or_charset_in_filename(self):
+        m = '''\
+Content-Disposition: inline;
+\tfilename*0*="''This%20is%20even%20more%20";
+\tfilename*1*="%2A%2A%2Afun%2A%2A%2A%20";
+\tfilename*2="is it not.pdf"
+
+'''
+        msg = email.message_from_string(m)
+        self.assertEqual(msg.get_filename(),
+                         'This is even more ***fun*** is it not.pdf')
+
+    def test_rfc2231_no_language_or_charset_in_filename_encoded(self):
+        m = '''\
+Content-Disposition: inline;
+\tfilename*0*="''This%20is%20even%20more%20";
+\tfilename*1*="%2A%2A%2Afun%2A%2A%2A%20";
+\tfilename*2="is it not.pdf"
+
+'''
+        msg = email.message_from_string(m)
+        self.assertEqual(msg.get_filename(),
+                         'This is even more ***fun*** is it not.pdf')
+
+    def test_rfc2231_partly_encoded(self):
+        m = '''\
+Content-Disposition: inline;
+\tfilename*0="''This%20is%20even%20more%20";
+\tfilename*1*="%2A%2A%2Afun%2A%2A%2A%20";
+\tfilename*2="is it not.pdf"
+
+'''
+        msg = email.message_from_string(m)
+        self.assertEqual(
+            msg.get_filename(),
+            'This%20is%20even%20more%20***fun*** is it not.pdf')
+
+    def test_rfc2231_partly_nonencoded(self):
+        m = '''\
+Content-Disposition: inline;
+\tfilename*0="This%20is%20even%20more%20";
+\tfilename*1="%2A%2A%2Afun%2A%2A%2A%20";
+\tfilename*2="is it not.pdf"
+
+'''
+        msg = email.message_from_string(m)
+        self.assertEqual(
+            msg.get_filename(),
+            'This%20is%20even%20more%20%2A%2A%2Afun%2A%2A%2A%20is it not.pdf')
+
+    def test_rfc2231_no_language_or_charset_in_boundary(self):
+        m = '''\
+Content-Type: multipart/alternative;
+\tboundary*0*="''This%20is%20even%20more%20";
+\tboundary*1*="%2A%2A%2Afun%2A%2A%2A%20";
+\tboundary*2="is it not.pdf"
+
+'''
+        msg = email.message_from_string(m)
+        self.assertEqual(msg.get_boundary(),
+                         'This is even more ***fun*** is it not.pdf')
+
+    def test_rfc2231_no_language_or_charset_in_charset(self):
+        # This is a nonsensical charset value, but tests the code anyway
+        m = '''\
+Content-Type: text/plain;
+\tcharset*0*="This%20is%20even%20more%20";
+\tcharset*1*="%2A%2A%2Afun%2A%2A%2A%20";
+\tcharset*2="is it not.pdf"
+
+'''
+        msg = email.message_from_string(m)
+        self.assertEqual(msg.get_content_charset(),
+                         'this is even more ***fun*** is it not.pdf')
+
+    def test_rfc2231_bad_encoding_in_filename(self):
+        m = '''\
+Content-Disposition: inline;
+\tfilename*0*="bogus'xx'This%20is%20even%20more%20";
+\tfilename*1*="%2A%2A%2Afun%2A%2A%2A%20";
+\tfilename*2="is it not.pdf"
+
+'''
+        msg = email.message_from_string(m)
+        self.assertEqual(msg.get_filename(),
+                         'This is even more ***fun*** is it not.pdf')
+
+    def test_rfc2231_bad_encoding_in_charset(self):
+        m = """\
+Content-Type: text/plain; charset*=bogus''utf-8%E2%80%9D
+
+"""
+        msg = email.message_from_string(m)
+        # This should return None because non-ascii characters in the charset
+        # are not allowed.
+        self.assertEqual(msg.get_content_charset(), None)
+
+    def test_rfc2231_bad_character_in_charset(self):
+        m = """\
+Content-Type: text/plain; charset*=ascii''utf-8%E2%80%9D
+
+"""
+        msg = email.message_from_string(m)
+        # This should return None because non-ascii characters in the charset
+        # are not allowed.
+        self.assertEqual(msg.get_content_charset(), None)
+
+    def test_rfc2231_bad_character_in_filename(self):
+        m = '''\
+Content-Disposition: inline;
+\tfilename*0*="ascii'xx'This%20is%20even%20more%20";
+\tfilename*1*="%2A%2A%2Afun%2A%2A%2A%20";
+\tfilename*2*="is it not.pdf%E2"
+
+'''
+        msg = email.message_from_string(m)
+        self.assertEqual(msg.get_filename(),
+                         u'This is even more ***fun*** is it not.pdf\ufffd')
+
+    def test_rfc2231_unknown_encoding(self):
+        m = """\
+Content-Transfer-Encoding: 8bit
+Content-Disposition: inline; filename*=X-UNKNOWN''myfile.txt
+
+"""
+        msg = email.message_from_string(m)
+        self.assertEqual(msg.get_filename(), 'myfile.txt')
+
+    def test_rfc2231_single_tick_in_filename_extended(self):
+        eq = self.assertEqual
+        m = """\
+Content-Type: application/x-foo;
+\tname*0*=\"Frank's\"; name*1*=\" Document\"
+
+"""
+        msg = email.message_from_string(m)
+        charset, language, s = msg.get_param('name')
+        eq(charset, None)
+        eq(language, None)
+        eq(s, "Frank's Document")
+
+    def test_rfc2231_single_tick_in_filename(self):
+        m = """\
+Content-Type: application/x-foo; name*0=\"Frank's\"; name*1=\" Document\"
+
+"""
+        msg = email.message_from_string(m)
+        param = msg.get_param('name')
+        self.failIf(isinstance(param, tuple))
+        self.assertEqual(param, "Frank's Document")
+
+    def test_rfc2231_tick_attack_extended(self):
+        eq = self.assertEqual
+        m = """\
+Content-Type: application/x-foo;
+\tname*0*=\"us-ascii'en-us'Frank's\"; name*1*=\" Document\"
+
+"""
+        msg = email.message_from_string(m)
+        charset, language, s = msg.get_param('name')
+        eq(charset, 'us-ascii')
+        eq(language, 'en-us')
+        eq(s, "Frank's Document")
+
+    def test_rfc2231_tick_attack(self):
+        m = """\
+Content-Type: application/x-foo;
+\tname*0=\"us-ascii'en-us'Frank's\"; name*1=\" Document\"
+
+"""
+        msg = email.message_from_string(m)
+        param = msg.get_param('name')
+        self.failIf(isinstance(param, tuple))
+        self.assertEqual(param, "us-ascii'en-us'Frank's Document")
+
+    def test_rfc2231_no_extended_values(self):
+        eq = self.assertEqual
+        m = """\
+Content-Type: application/x-foo; name=\"Frank's Document\"
+
+"""
+        msg = email.message_from_string(m)
+        eq(msg.get_param('name'), "Frank's Document")
+
+    def test_rfc2231_encoded_then_unencoded_segments(self):
+        eq = self.assertEqual
+        m = """\
+Content-Type: application/x-foo;
+\tname*0*=\"us-ascii'en-us'My\";
+\tname*1=\" Document\";
+\tname*2*=\" For You\"
+
+"""
+        msg = email.message_from_string(m)
+        charset, language, s = msg.get_param('name')
+        eq(charset, 'us-ascii')
+        eq(language, 'en-us')
+        eq(s, 'My Document For You')
+
+    def test_rfc2231_unencoded_then_encoded_segments(self):
+        eq = self.assertEqual
+        m = """\
+Content-Type: application/x-foo;
+\tname*0=\"us-ascii'en-us'My\";
+\tname*1*=\" Document\";
+\tname*2*=\" For You\"
+
+"""
+        msg = email.message_from_string(m)
+        charset, language, s = msg.get_param('name')
+        eq(charset, 'us-ascii')
+        eq(language, 'en-us')
+        eq(s, 'My Document For You')
+
+
+
+def _testclasses():
+    mod = sys.modules[__name__]
+    return [getattr(mod, name) for name in dir(mod) if name.startswith('Test')]
+
+
+def suite():
+    suite = unittest.TestSuite()
+    for testclass in _testclasses():
+        suite.addTest(unittest.makeSuite(testclass))
+    return suite
+
+
+def test_main():
+    for testclass in _testclasses():
+        run_unittest(testclass)
+
+
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='suite')

Added: vendor/Python/current/Lib/email/test/test_email_torture.py
===================================================================
--- vendor/Python/current/Lib/email/test/test_email_torture.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/test/test_email_torture.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,136 @@
+# Copyright (C) 2002-2004 Python Software Foundation
+#
+# A torture test of the email package.  This should not be run as part of the
+# standard Python test suite since it requires several meg of email messages
+# collected in the wild.  These source messages are not checked into the
+# Python distro, but are available as part of the standalone email package at
+# http://sf.net/projects/mimelib
+
+import sys
+import os
+import unittest
+from cStringIO import StringIO
+from types import ListType
+
+from email.test.test_email import TestEmailBase
+from test.test_support import TestSkipped
+
+import email
+from email import __file__ as testfile
+from email.Iterators import _structure
+
+def openfile(filename):
+    from os.path import join, dirname, abspath
+    path = abspath(join(dirname(testfile), os.pardir, 'moredata', filename))
+    return open(path, 'r')
+
+# Prevent this test from running in the Python distro
+try:
+    openfile('crispin-torture.txt')
+except IOError:
+    raise TestSkipped
+
+
+
+class TortureBase(TestEmailBase):
+    def _msgobj(self, filename):
+        fp = openfile(filename)
+        try:
+            msg = email.message_from_file(fp)
+        finally:
+            fp.close()
+        return msg
+
+
+
+class TestCrispinTorture(TortureBase):
+    # Mark Crispin's torture test from the SquirrelMail project
+    def test_mondo_message(self):
+        eq = self.assertEqual
+        neq = self.ndiffAssertEqual
+        msg = self._msgobj('crispin-torture.txt')
+        payload = msg.get_payload()
+        eq(type(payload), ListType)
+        eq(len(payload), 12)
+        eq(msg.preamble, None)
+        eq(msg.epilogue, '\n')
+        # Probably the best way to verify the message is parsed correctly is to
+        # dump its structure and compare it against the known structure.
+        fp = StringIO()
+        _structure(msg, fp=fp)
+        neq(fp.getvalue(), """\
+multipart/mixed
+    text/plain
+    message/rfc822
+        multipart/alternative
+            text/plain
+            multipart/mixed
+                text/richtext
+            application/andrew-inset
+    message/rfc822
+        audio/basic
+    audio/basic
+    image/pbm
+    message/rfc822
+        multipart/mixed
+            multipart/mixed
+                text/plain
+                audio/x-sun
+            multipart/mixed
+                image/gif
+                image/gif
+                application/x-be2
+                application/atomicmail
+            audio/x-sun
+    message/rfc822
+        multipart/mixed
+            text/plain
+            image/pgm
+            text/plain
+    message/rfc822
+        multipart/mixed
+            text/plain
+            image/pbm
+    message/rfc822
+        application/postscript
+    image/gif
+    message/rfc822
+        multipart/mixed
+            audio/basic
+            audio/basic
+    message/rfc822
+        multipart/mixed
+            application/postscript
+            text/plain
+            message/rfc822
+                multipart/mixed
+                    text/plain
+                    multipart/parallel
+                        image/gif
+                        audio/basic
+                    application/atomicmail
+                    message/rfc822
+                        audio/x-sun
+""")
+
+
+def _testclasses():
+    mod = sys.modules[__name__]
+    return [getattr(mod, name) for name in dir(mod) if name.startswith('Test')]
+
+
+def suite():
+    suite = unittest.TestSuite()
+    for testclass in _testclasses():
+        suite.addTest(unittest.makeSuite(testclass))
+    return suite
+
+
+def test_main():
+    for testclass in _testclasses():
+        test_support.run_unittest(testclass)
+
+
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='suite')

Added: vendor/Python/current/Lib/email/utils.py
===================================================================
--- vendor/Python/current/Lib/email/utils.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/email/utils.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,323 @@
+# Copyright (C) 2001-2006 Python Software Foundation
+# Author: Barry Warsaw
+# Contact: email-sig at python.org
+
+"""Miscellaneous utilities."""
+
+__all__ = [
+    'collapse_rfc2231_value',
+    'decode_params',
+    'decode_rfc2231',
+    'encode_rfc2231',
+    'formataddr',
+    'formatdate',
+    'getaddresses',
+    'make_msgid',
+    'parseaddr',
+    'parsedate',
+    'parsedate_tz',
+    'unquote',
+    ]
+
+import os
+import re
+import time
+import base64
+import random
+import socket
+import urllib
+import warnings
+from cStringIO import StringIO
+
+from email._parseaddr import quote
+from email._parseaddr import AddressList as _AddressList
+from email._parseaddr import mktime_tz
+
+# We need wormarounds for bugs in these methods in older Pythons (see below)
+from email._parseaddr import parsedate as _parsedate
+from email._parseaddr import parsedate_tz as _parsedate_tz
+
+from quopri import decodestring as _qdecode
+
+# Intrapackage imports
+from email.encoders import _bencode, _qencode
+
+COMMASPACE = ', '
+EMPTYSTRING = ''
+UEMPTYSTRING = u''
+CRLF = '\r\n'
+TICK = "'"
+
+specialsre = re.compile(r'[][\\()<>@,:;".]')
+escapesre = re.compile(r'[][\\()"]')
+
+
+
+# Helpers
+
+def _identity(s):
+    return s
+
+
+def _bdecode(s):
+    # We can't quite use base64.encodestring() since it tacks on a "courtesy
+    # newline".  Blech!
+    if not s:
+        return s
+    value = base64.decodestring(s)
+    if not s.endswith('\n') and value.endswith('\n'):
+        return value[:-1]
+    return value
+
+
+
+def fix_eols(s):
+    """Replace all line-ending characters with \r\n."""
+    # Fix newlines with no preceding carriage return
+    s = re.sub(r'(?<!\r)\n', CRLF, s)
+    # Fix carriage returns with no following newline
+    s = re.sub(r'\r(?!\n)', CRLF, s)
+    return s
+
+
+
+def formataddr(pair):
+    """The inverse of parseaddr(), this takes a 2-tuple of the form
+    (realname, email_address) and returns the string value suitable
+    for an RFC 2822 From, To or Cc header.
+
+    If the first element of pair is false, then the second element is
+    returned unmodified.
+    """
+    name, address = pair
+    if name:
+        quotes = ''
+        if specialsre.search(name):
+            quotes = '"'
+        name = escapesre.sub(r'\\\g<0>', name)
+        return '%s%s%s <%s>' % (quotes, name, quotes, address)
+    return address
+
+
+
+def getaddresses(fieldvalues):
+    """Return a list of (REALNAME, EMAIL) for each fieldvalue."""
+    all = COMMASPACE.join(fieldvalues)
+    a = _AddressList(all)
+    return a.addresslist
+
+
+
+ecre = re.compile(r'''
+  =\?                   # literal =?
+  (?P<charset>[^?]*?)   # non-greedy up to the next ? is the charset
+  \?                    # literal ?
+  (?P<encoding>[qb])    # either a "q" or a "b", case insensitive
+  \?                    # literal ?
+  (?P<atom>.*?)         # non-greedy up to the next ?= is the atom
+  \?=                   # literal ?=
+  ''', re.VERBOSE | re.IGNORECASE)
+
+
+
+def formatdate(timeval=None, localtime=False, usegmt=False):
+    """Returns a date string as specified by RFC 2822, e.g.:
+
+    Fri, 09 Nov 2001 01:08:47 -0000
+
+    Optional timeval if given is a floating point time value as accepted by
+    gmtime() and localtime(), otherwise the current time is used.
+
+    Optional localtime is a flag that when True, interprets timeval, and
+    returns a date relative to the local timezone instead of UTC, properly
+    taking daylight savings time into account.
+
+    Optional argument usegmt means that the timezone is written out as
+    an ascii string, not numeric one (so "GMT" instead of "+0000"). This
+    is needed for HTTP, and is only used when localtime==False.
+    """
+    # Note: we cannot use strftime() because that honors the locale and RFC
+    # 2822 requires that day and month names be the English abbreviations.
+    if timeval is None:
+        timeval = time.time()
+    if localtime:
+        now = time.localtime(timeval)
+        # Calculate timezone offset, based on whether the local zone has
+        # daylight savings time, and whether DST is in effect.
+        if time.daylight and now[-1]:
+            offset = time.altzone
+        else:
+            offset = time.timezone
+        hours, minutes = divmod(abs(offset), 3600)
+        # Remember offset is in seconds west of UTC, but the timezone is in
+        # minutes east of UTC, so the signs differ.
+        if offset > 0:
+            sign = '-'
+        else:
+            sign = '+'
+        zone = '%s%02d%02d' % (sign, hours, minutes // 60)
+    else:
+        now = time.gmtime(timeval)
+        # Timezone offset is always -0000
+        if usegmt:
+            zone = 'GMT'
+        else:
+            zone = '-0000'
+    return '%s, %02d %s %04d %02d:%02d:%02d %s' % (
+        ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'][now[6]],
+        now[2],
+        ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
+         'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'][now[1] - 1],
+        now[0], now[3], now[4], now[5],
+        zone)
+
+
+
+def make_msgid(idstring=None):
+    """Returns a string suitable for RFC 2822 compliant Message-ID, e.g:
+
+    <20020201195627.33539.96671 at nightshade.la.mastaler.com>
+
+    Optional idstring if given is a string used to strengthen the
+    uniqueness of the message id.
+    """
+    timeval = time.time()
+    utcdate = time.strftime('%Y%m%d%H%M%S', time.gmtime(timeval))
+    pid = os.getpid()
+    randint = random.randrange(100000)
+    if idstring is None:
+        idstring = ''
+    else:
+        idstring = '.' + idstring
+    idhost = socket.getfqdn()
+    msgid = '<%s.%s.%s%s@%s>' % (utcdate, pid, randint, idstring, idhost)
+    return msgid
+
+
+
+# These functions are in the standalone mimelib version only because they've
+# subsequently been fixed in the latest Python versions.  We use this to worm
+# around broken older Pythons.
+def parsedate(data):
+    if not data:
+        return None
+    return _parsedate(data)
+
+
+def parsedate_tz(data):
+    if not data:
+        return None
+    return _parsedate_tz(data)
+
+
+def parseaddr(addr):
+    addrs = _AddressList(addr).addresslist
+    if not addrs:
+        return '', ''
+    return addrs[0]
+
+
+# rfc822.unquote() doesn't properly de-backslash-ify in Python pre-2.3.
+def unquote(str):
+    """Remove quotes from a string."""
+    if len(str) > 1:
+        if str.startswith('"') and str.endswith('"'):
+            return str[1:-1].replace('\\\\', '\\').replace('\\"', '"')
+        if str.startswith('<') and str.endswith('>'):
+            return str[1:-1]
+    return str
+
+
+
+# RFC2231-related functions - parameter encoding and decoding
+def decode_rfc2231(s):
+    """Decode string according to RFC 2231"""
+    parts = s.split(TICK, 2)
+    if len(parts) <= 2:
+        return None, None, s
+    return parts
+
+
+def encode_rfc2231(s, charset=None, language=None):
+    """Encode string according to RFC 2231.
+
+    If neither charset nor language is given, then s is returned as-is.  If
+    charset is given but not language, the string is encoded using the empty
+    string for language.
+    """
+    import urllib
+    s = urllib.quote(s, safe='')
+    if charset is None and language is None:
+        return s
+    if language is None:
+        language = ''
+    return "%s'%s'%s" % (charset, language, s)
+
+
+rfc2231_continuation = re.compile(r'^(?P<name>\w+)\*((?P<num>[0-9]+)\*?)?$')
+
+def decode_params(params):
+    """Decode parameters list according to RFC 2231.
+
+    params is a sequence of 2-tuples containing (param name, string value).
+    """
+    # Copy params so we don't mess with the original
+    params = params[:]
+    new_params = []
+    # Map parameter's name to a list of continuations.  The values are a
+    # 3-tuple of the continuation number, the string value, and a flag
+    # specifying whether a particular segment is %-encoded.
+    rfc2231_params = {}
+    name, value = params.pop(0)
+    new_params.append((name, value))
+    while params:
+        name, value = params.pop(0)
+        if name.endswith('*'):
+            encoded = True
+        else:
+            encoded = False
+        value = unquote(value)
+        mo = rfc2231_continuation.match(name)
+        if mo:
+            name, num = mo.group('name', 'num')
+            if num is not None:
+                num = int(num)
+            rfc2231_params.setdefault(name, []).append((num, value, encoded))
+        else:
+            new_params.append((name, '"%s"' % quote(value)))
+    if rfc2231_params:
+        for name, continuations in rfc2231_params.items():
+            value = []
+            extended = False
+            # Sort by number
+            continuations.sort()
+            # And now append all values in numerical order, converting
+            # %-encodings for the encoded segments.  If any of the
+            # continuation names ends in a *, then the entire string, after
+            # decoding segments and concatenating, must have the charset and
+            # language specifiers at the beginning of the string.
+            for num, s, encoded in continuations:
+                if encoded:
+                    s = urllib.unquote(s)
+                    extended = True
+                value.append(s)
+            value = quote(EMPTYSTRING.join(value))
+            if extended:
+                charset, language, value = decode_rfc2231(value)
+                new_params.append((name, (charset, language, '"%s"' % value)))
+            else:
+                new_params.append((name, '"%s"' % value))
+    return new_params
+
+def collapse_rfc2231_value(value, errors='replace',
+                           fallback_charset='us-ascii'):
+    if isinstance(value, tuple):
+        rawval = unquote(value[2])
+        charset = value[0] or 'us-ascii'
+        try:
+            return unicode(rawval, charset, errors)
+        except LookupError:
+            # XXX charset is unknown to Python.
+            return unicode(rawval, fallback_charset, errors)
+    else:
+        return unquote(value)

Added: vendor/Python/current/Lib/encodings/__init__.py
===================================================================
--- vendor/Python/current/Lib/encodings/__init__.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/__init__.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,154 @@
+""" Standard "encodings" Package
+
+    Standard Python encoding modules are stored in this package
+    directory.
+
+    Codec modules must have names corresponding to normalized encoding
+    names as defined in the normalize_encoding() function below, e.g.
+    'utf-8' must be implemented by the module 'utf_8.py'.
+
+    Each codec module must export the following interface:
+
+    * getregentry() -> codecs.CodecInfo object
+    The getregentry() API must a CodecInfo object with encoder, decoder,
+    incrementalencoder, incrementaldecoder, streamwriter and streamreader
+    atttributes which adhere to the Python Codec Interface Standard.
+
+    In addition, a module may optionally also define the following
+    APIs which are then used by the package's codec search function:
+
+    * getaliases() -> sequence of encoding name strings to use as aliases
+
+    Alias names returned by getaliases() must be normalized encoding
+    names as defined by normalize_encoding().
+
+Written by Marc-Andre Lemburg (mal at lemburg.com).
+
+(c) Copyright CNRI, All Rights Reserved. NO WARRANTY.
+
+"""#"
+
+import codecs, types
+from encodings import aliases
+
+_cache = {}
+_unknown = '--unknown--'
+_import_tail = ['*']
+_norm_encoding_map = ('                                              . '
+                      '0123456789       ABCDEFGHIJKLMNOPQRSTUVWXYZ     '
+                      ' abcdefghijklmnopqrstuvwxyz                     '
+                      '                                                '
+                      '                                                '
+                      '                ')
+_aliases = aliases.aliases
+
+class CodecRegistryError(LookupError, SystemError):
+    pass
+
+def normalize_encoding(encoding):
+
+    """ Normalize an encoding name.
+
+        Normalization works as follows: all non-alphanumeric
+        characters except the dot used for Python package names are
+        collapsed and replaced with a single underscore, e.g. '  -;#'
+        becomes '_'. Leading and trailing underscores are removed.
+
+        Note that encoding names should be ASCII only; if they do use
+        non-ASCII characters, these must be Latin-1 compatible.
+
+    """
+    # Make sure we have an 8-bit string, because .translate() works
+    # differently for Unicode strings.
+    if type(encoding) is types.UnicodeType:
+        # Note that .encode('latin-1') does *not* use the codec
+        # registry, so this call doesn't recurse. (See unicodeobject.c
+        # PyUnicode_AsEncodedString() for details)
+        encoding = encoding.encode('latin-1')
+    return '_'.join(encoding.translate(_norm_encoding_map).split())
+
+def search_function(encoding):
+
+    # Cache lookup
+    entry = _cache.get(encoding, _unknown)
+    if entry is not _unknown:
+        return entry
+
+    # Import the module:
+    #
+    # First try to find an alias for the normalized encoding
+    # name and lookup the module using the aliased name, then try to
+    # lookup the module using the standard import scheme, i.e. first
+    # try in the encodings package, then at top-level.
+    #
+    norm_encoding = normalize_encoding(encoding)
+    aliased_encoding = _aliases.get(norm_encoding) or \
+                       _aliases.get(norm_encoding.replace('.', '_'))
+    if aliased_encoding is not None:
+        modnames = [aliased_encoding,
+                    norm_encoding]
+    else:
+        modnames = [norm_encoding]
+    for modname in modnames:
+        if not modname or '.' in modname:
+            continue
+        try:
+            mod = __import__('encodings.' + modname,
+                             globals(), locals(), _import_tail)
+        except ImportError:
+            pass
+        else:
+            break
+    else:
+        mod = None
+
+    try:
+        getregentry = mod.getregentry
+    except AttributeError:
+        # Not a codec module
+        mod = None
+
+    if mod is None:
+        # Cache misses
+        _cache[encoding] = None
+        return None
+
+    # Now ask the module for the registry entry
+    entry = getregentry()
+    if not isinstance(entry, codecs.CodecInfo):
+        if not 4 <= len(entry) <= 7:
+            raise CodecRegistryError,\
+                 'module "%s" (%s) failed to register' % \
+                  (mod.__name__, mod.__file__)
+        if not callable(entry[0]) or \
+           not callable(entry[1]) or \
+           (entry[2] is not None and not callable(entry[2])) or \
+           (entry[3] is not None and not callable(entry[3])) or \
+           (len(entry) > 4 and entry[4] is not None and not callable(entry[4])) or \
+           (len(entry) > 5 and entry[5] is not None and not callable(entry[5])):
+            raise CodecRegistryError,\
+                'incompatible codecs in module "%s" (%s)' % \
+                (mod.__name__, mod.__file__)
+        if len(entry)<7 or entry[6] is None:
+            entry += (None,)*(6-len(entry)) + (mod.__name__.split(".", 1)[1],)
+        entry = codecs.CodecInfo(*entry)
+
+    # Cache the codec registry entry
+    _cache[encoding] = entry
+
+    # Register its aliases (without overwriting previously registered
+    # aliases)
+    try:
+        codecaliases = mod.getaliases()
+    except AttributeError:
+        pass
+    else:
+        for alias in codecaliases:
+            if not _aliases.has_key(alias):
+                _aliases[alias] = modname
+
+    # Return the registry entry
+    return entry
+
+# Register the search_function in the Python codec registry
+codecs.register(search_function)

Added: vendor/Python/current/Lib/encodings/aliases.py
===================================================================
--- vendor/Python/current/Lib/encodings/aliases.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/aliases.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,508 @@
+""" Encoding Aliases Support
+
+    This module is used by the encodings package search function to
+    map encodings names to module names.
+
+    Note that the search function normalizes the encoding names before
+    doing the lookup, so the mapping will have to map normalized
+    encoding names to module names.
+
+    Contents:
+
+        The following aliases dictionary contains mappings of all IANA
+        character set names for which the Python core library provides
+        codecs. In addition to these, a few Python specific codec
+        aliases have also been added.
+
+"""
+aliases = {
+
+    # Please keep this list sorted alphabetically by value !
+
+    # ascii codec
+    '646'                : 'ascii',
+    'ansi_x3.4_1968'     : 'ascii',
+    'ansi_x3_4_1968'     : 'ascii', # some email headers use this non-standard name
+    'ansi_x3.4_1986'     : 'ascii',
+    'cp367'              : 'ascii',
+    'csascii'            : 'ascii',
+    'ibm367'             : 'ascii',
+    'iso646_us'          : 'ascii',
+    'iso_646.irv_1991'   : 'ascii',
+    'iso_ir_6'           : 'ascii',
+    'us'                 : 'ascii',
+    'us_ascii'           : 'ascii',
+
+    # base64_codec codec
+    'base64'             : 'base64_codec',
+    'base_64'            : 'base64_codec',
+
+    # big5 codec
+    'big5_tw'            : 'big5',
+    'csbig5'             : 'big5',
+
+    # big5hkscs codec
+    'big5_hkscs'         : 'big5hkscs',
+    'hkscs'              : 'big5hkscs',
+
+    # bz2_codec codec
+    'bz2'                : 'bz2_codec',
+
+    # cp037 codec
+    '037'                : 'cp037',
+    'csibm037'           : 'cp037',
+    'ebcdic_cp_ca'       : 'cp037',
+    'ebcdic_cp_nl'       : 'cp037',
+    'ebcdic_cp_us'       : 'cp037',
+    'ebcdic_cp_wt'       : 'cp037',
+    'ibm037'             : 'cp037',
+    'ibm039'             : 'cp037',
+
+    # cp1026 codec
+    '1026'               : 'cp1026',
+    'csibm1026'          : 'cp1026',
+    'ibm1026'            : 'cp1026',
+
+    # cp1140 codec
+    '1140'               : 'cp1140',
+    'ibm1140'            : 'cp1140',
+
+    # cp1250 codec
+    '1250'               : 'cp1250',
+    'windows_1250'       : 'cp1250',
+
+    # cp1251 codec
+    '1251'               : 'cp1251',
+    'windows_1251'       : 'cp1251',
+
+    # cp1252 codec
+    '1252'               : 'cp1252',
+    'windows_1252'       : 'cp1252',
+
+    # cp1253 codec
+    '1253'               : 'cp1253',
+    'windows_1253'       : 'cp1253',
+
+    # cp1254 codec
+    '1254'               : 'cp1254',
+    'windows_1254'       : 'cp1254',
+
+    # cp1255 codec
+    '1255'               : 'cp1255',
+    'windows_1255'       : 'cp1255',
+
+    # cp1256 codec
+    '1256'               : 'cp1256',
+    'windows_1256'       : 'cp1256',
+
+    # cp1257 codec
+    '1257'               : 'cp1257',
+    'windows_1257'       : 'cp1257',
+
+    # cp1258 codec
+    '1258'               : 'cp1258',
+    'windows_1258'       : 'cp1258',
+
+    # cp424 codec
+    '424'                : 'cp424',
+    'csibm424'           : 'cp424',
+    'ebcdic_cp_he'       : 'cp424',
+    'ibm424'             : 'cp424',
+
+    # cp437 codec
+    '437'                : 'cp437',
+    'cspc8codepage437'   : 'cp437',
+    'ibm437'             : 'cp437',
+
+    # cp500 codec
+    '500'                : 'cp500',
+    'csibm500'           : 'cp500',
+    'ebcdic_cp_be'       : 'cp500',
+    'ebcdic_cp_ch'       : 'cp500',
+    'ibm500'             : 'cp500',
+
+    # cp775 codec
+    '775'                : 'cp775',
+    'cspc775baltic'      : 'cp775',
+    'ibm775'             : 'cp775',
+
+    # cp850 codec
+    '850'                : 'cp850',
+    'cspc850multilingual' : 'cp850',
+    'ibm850'             : 'cp850',
+
+    # cp852 codec
+    '852'                : 'cp852',
+    'cspcp852'           : 'cp852',
+    'ibm852'             : 'cp852',
+
+    # cp855 codec
+    '855'                : 'cp855',
+    'csibm855'           : 'cp855',
+    'ibm855'             : 'cp855',
+
+    # cp857 codec
+    '857'                : 'cp857',
+    'csibm857'           : 'cp857',
+    'ibm857'             : 'cp857',
+
+    # cp860 codec
+    '860'                : 'cp860',
+    'csibm860'           : 'cp860',
+    'ibm860'             : 'cp860',
+
+    # cp861 codec
+    '861'                : 'cp861',
+    'cp_is'              : 'cp861',
+    'csibm861'           : 'cp861',
+    'ibm861'             : 'cp861',
+
+    # cp862 codec
+    '862'                : 'cp862',
+    'cspc862latinhebrew' : 'cp862',
+    'ibm862'             : 'cp862',
+
+    # cp863 codec
+    '863'                : 'cp863',
+    'csibm863'           : 'cp863',
+    'ibm863'             : 'cp863',
+
+    # cp864 codec
+    '864'                : 'cp864',
+    'csibm864'           : 'cp864',
+    'ibm864'             : 'cp864',
+
+    # cp865 codec
+    '865'                : 'cp865',
+    'csibm865'           : 'cp865',
+    'ibm865'             : 'cp865',
+
+    # cp866 codec
+    '866'                : 'cp866',
+    'csibm866'           : 'cp866',
+    'ibm866'             : 'cp866',
+
+    # cp869 codec
+    '869'                : 'cp869',
+    'cp_gr'              : 'cp869',
+    'csibm869'           : 'cp869',
+    'ibm869'             : 'cp869',
+
+    # cp932 codec
+    '932'                : 'cp932',
+    'ms932'              : 'cp932',
+    'mskanji'            : 'cp932',
+    'ms_kanji'           : 'cp932',
+
+    # cp949 codec
+    '949'                : 'cp949',
+    'ms949'              : 'cp949',
+    'uhc'                : 'cp949',
+
+    # cp950 codec
+    '950'                : 'cp950',
+    'ms950'              : 'cp950',
+
+    # euc_jis_2004 codec
+    'jisx0213'           : 'euc_jis_2004',
+    'eucjis2004'         : 'euc_jis_2004',
+    'euc_jis2004'        : 'euc_jis_2004',
+
+    # euc_jisx0213 codec
+    'eucjisx0213'        : 'euc_jisx0213',
+
+    # euc_jp codec
+    'eucjp'              : 'euc_jp',
+    'ujis'               : 'euc_jp',
+    'u_jis'              : 'euc_jp',
+
+    # euc_kr codec
+    'euckr'              : 'euc_kr',
+    'korean'             : 'euc_kr',
+    'ksc5601'            : 'euc_kr',
+    'ks_c_5601'          : 'euc_kr',
+    'ks_c_5601_1987'     : 'euc_kr',
+    'ksx1001'            : 'euc_kr',
+    'ks_x_1001'          : 'euc_kr',
+
+    # gb18030 codec
+    'gb18030_2000'       : 'gb18030',
+
+    # gb2312 codec
+    'chinese'            : 'gb2312',
+    'csiso58gb231280'    : 'gb2312',
+    'euc_cn'             : 'gb2312',
+    'euccn'              : 'gb2312',
+    'eucgb2312_cn'       : 'gb2312',
+    'gb2312_1980'        : 'gb2312',
+    'gb2312_80'          : 'gb2312',
+    'iso_ir_58'          : 'gb2312',
+
+    # gbk codec
+    '936'                : 'gbk',
+    'cp936'              : 'gbk',
+    'ms936'              : 'gbk',
+
+    # hex_codec codec
+    'hex'                : 'hex_codec',
+
+    # hp_roman8 codec
+    'roman8'             : 'hp_roman8',
+    'r8'                 : 'hp_roman8',
+    'csHPRoman8'         : 'hp_roman8',
+
+    # hz codec
+    'hzgb'               : 'hz',
+    'hz_gb'              : 'hz',
+    'hz_gb_2312'         : 'hz',
+
+    # iso2022_jp codec
+    'csiso2022jp'        : 'iso2022_jp',
+    'iso2022jp'          : 'iso2022_jp',
+    'iso_2022_jp'        : 'iso2022_jp',
+
+    # iso2022_jp_1 codec
+    'iso2022jp_1'        : 'iso2022_jp_1',
+    'iso_2022_jp_1'      : 'iso2022_jp_1',
+
+    # iso2022_jp_2 codec
+    'iso2022jp_2'        : 'iso2022_jp_2',
+    'iso_2022_jp_2'      : 'iso2022_jp_2',
+
+    # iso2022_jp_2004 codec
+    'iso_2022_jp_2004'   : 'iso2022_jp_2004',
+    'iso2022jp_2004'     : 'iso2022_jp_2004',
+
+    # iso2022_jp_3 codec
+    'iso2022jp_3'        : 'iso2022_jp_3',
+    'iso_2022_jp_3'      : 'iso2022_jp_3',
+
+    # iso2022_jp_ext codec
+    'iso2022jp_ext'      : 'iso2022_jp_ext',
+    'iso_2022_jp_ext'    : 'iso2022_jp_ext',
+
+    # iso2022_kr codec
+    'csiso2022kr'        : 'iso2022_kr',
+    'iso2022kr'          : 'iso2022_kr',
+    'iso_2022_kr'        : 'iso2022_kr',
+
+    # iso8859_10 codec
+    'csisolatin6'        : 'iso8859_10',
+    'iso_8859_10'        : 'iso8859_10',
+    'iso_8859_10_1992'   : 'iso8859_10',
+    'iso_ir_157'         : 'iso8859_10',
+    'l6'                 : 'iso8859_10',
+    'latin6'             : 'iso8859_10',
+
+    # iso8859_11 codec
+    'thai'               : 'iso8859_11',
+    'iso_8859_11'        : 'iso8859_11',
+    'iso_8859_11_2001'   : 'iso8859_11',
+
+    # iso8859_13 codec
+    'iso_8859_13'        : 'iso8859_13',
+
+    # iso8859_14 codec
+    'iso_8859_14'        : 'iso8859_14',
+    'iso_8859_14_1998'   : 'iso8859_14',
+    'iso_celtic'         : 'iso8859_14',
+    'iso_ir_199'         : 'iso8859_14',
+    'l8'                 : 'iso8859_14',
+    'latin8'             : 'iso8859_14',
+
+    # iso8859_15 codec
+    'iso_8859_15'        : 'iso8859_15',
+
+    # iso8859_16 codec
+    'iso_8859_16'        : 'iso8859_16',
+    'iso_8859_16_2001'   : 'iso8859_16',
+    'iso_ir_226'         : 'iso8859_16',
+    'l10'                : 'iso8859_16',
+    'latin10'            : 'iso8859_16',
+
+    # iso8859_2 codec
+    'csisolatin2'        : 'iso8859_2',
+    'iso_8859_2'         : 'iso8859_2',
+    'iso_8859_2_1987'    : 'iso8859_2',
+    'iso_ir_101'         : 'iso8859_2',
+    'l2'                 : 'iso8859_2',
+    'latin2'             : 'iso8859_2',
+
+    # iso8859_3 codec
+    'csisolatin3'        : 'iso8859_3',
+    'iso_8859_3'         : 'iso8859_3',
+    'iso_8859_3_1988'    : 'iso8859_3',
+    'iso_ir_109'         : 'iso8859_3',
+    'l3'                 : 'iso8859_3',
+    'latin3'             : 'iso8859_3',
+
+    # iso8859_4 codec
+    'csisolatin4'        : 'iso8859_4',
+    'iso_8859_4'         : 'iso8859_4',
+    'iso_8859_4_1988'    : 'iso8859_4',
+    'iso_ir_110'         : 'iso8859_4',
+    'l4'                 : 'iso8859_4',
+    'latin4'             : 'iso8859_4',
+
+    # iso8859_5 codec
+    'csisolatincyrillic' : 'iso8859_5',
+    'cyrillic'           : 'iso8859_5',
+    'iso_8859_5'         : 'iso8859_5',
+    'iso_8859_5_1988'    : 'iso8859_5',
+    'iso_ir_144'         : 'iso8859_5',
+
+    # iso8859_6 codec
+    'arabic'             : 'iso8859_6',
+    'asmo_708'           : 'iso8859_6',
+    'csisolatinarabic'   : 'iso8859_6',
+    'ecma_114'           : 'iso8859_6',
+    'iso_8859_6'         : 'iso8859_6',
+    'iso_8859_6_1987'    : 'iso8859_6',
+    'iso_ir_127'         : 'iso8859_6',
+
+    # iso8859_7 codec
+    'csisolatingreek'    : 'iso8859_7',
+    'ecma_118'           : 'iso8859_7',
+    'elot_928'           : 'iso8859_7',
+    'greek'              : 'iso8859_7',
+    'greek8'             : 'iso8859_7',
+    'iso_8859_7'         : 'iso8859_7',
+    'iso_8859_7_1987'    : 'iso8859_7',
+    'iso_ir_126'         : 'iso8859_7',
+
+    # iso8859_8 codec
+    'csisolatinhebrew'   : 'iso8859_8',
+    'hebrew'             : 'iso8859_8',
+    'iso_8859_8'         : 'iso8859_8',
+    'iso_8859_8_1988'    : 'iso8859_8',
+    'iso_ir_138'         : 'iso8859_8',
+
+    # iso8859_9 codec
+    'csisolatin5'        : 'iso8859_9',
+    'iso_8859_9'         : 'iso8859_9',
+    'iso_8859_9_1989'    : 'iso8859_9',
+    'iso_ir_148'         : 'iso8859_9',
+    'l5'                 : 'iso8859_9',
+    'latin5'             : 'iso8859_9',
+
+    # johab codec
+    'cp1361'             : 'johab',
+    'ms1361'             : 'johab',
+
+    # koi8_r codec
+    'cskoi8r'            : 'koi8_r',
+
+    # latin_1 codec
+    #
+    # Note that the latin_1 codec is implemented internally in C and a
+    # lot faster than the charmap codec iso8859_1 which uses the same
+    # encoding. This is why we discourage the use of the iso8859_1
+    # codec and alias it to latin_1 instead.
+    #
+    '8859'               : 'latin_1',
+    'cp819'              : 'latin_1',
+    'csisolatin1'        : 'latin_1',
+    'ibm819'             : 'latin_1',
+    'iso8859'            : 'latin_1',
+    'iso8859_1'          : 'latin_1',
+    'iso_8859_1'         : 'latin_1',
+    'iso_8859_1_1987'    : 'latin_1',
+    'iso_ir_100'         : 'latin_1',
+    'l1'                 : 'latin_1',
+    'latin'              : 'latin_1',
+    'latin1'             : 'latin_1',
+
+    # mac_cyrillic codec
+    'maccyrillic'        : 'mac_cyrillic',
+
+    # mac_greek codec
+    'macgreek'           : 'mac_greek',
+
+    # mac_iceland codec
+    'maciceland'         : 'mac_iceland',
+
+    # mac_latin2 codec
+    'maccentraleurope'   : 'mac_latin2',
+    'maclatin2'          : 'mac_latin2',
+
+    # mac_roman codec
+    'macroman'           : 'mac_roman',
+
+    # mac_turkish codec
+    'macturkish'         : 'mac_turkish',
+
+    # mbcs codec
+    'dbcs'               : 'mbcs',
+
+    # ptcp154 codec
+    'csptcp154'          : 'ptcp154',
+    'pt154'              : 'ptcp154',
+    'cp154'              : 'ptcp154',
+    'cyrillic-asian'     : 'ptcp154',
+
+    # quopri_codec codec
+    'quopri'             : 'quopri_codec',
+    'quoted_printable'   : 'quopri_codec',
+    'quotedprintable'    : 'quopri_codec',
+
+    # rot_13 codec
+    'rot13'              : 'rot_13',
+
+    # shift_jis codec
+    'csshiftjis'         : 'shift_jis',
+    'shiftjis'           : 'shift_jis',
+    'sjis'               : 'shift_jis',
+    's_jis'              : 'shift_jis',
+
+    # shift_jis_2004 codec
+    'shiftjis2004'       : 'shift_jis_2004',
+    'sjis_2004'          : 'shift_jis_2004',
+    's_jis_2004'         : 'shift_jis_2004',
+
+    # shift_jisx0213 codec
+    'shiftjisx0213'      : 'shift_jisx0213',
+    'sjisx0213'          : 'shift_jisx0213',
+    's_jisx0213'         : 'shift_jisx0213',
+
+    # tactis codec
+    'tis260'             : 'tactis',
+
+    # tis_620 codec
+    'tis620'             : 'tis_620',
+    'tis_620_0'          : 'tis_620',
+    'tis_620_2529_0'     : 'tis_620',
+    'tis_620_2529_1'     : 'tis_620',
+    'iso_ir_166'         : 'tis_620',
+
+    # utf_16 codec
+    'u16'                : 'utf_16',
+    'utf16'              : 'utf_16',
+
+    # utf_16_be codec
+    'unicodebigunmarked' : 'utf_16_be',
+    'utf_16be'           : 'utf_16_be',
+
+    # utf_16_le codec
+    'unicodelittleunmarked' : 'utf_16_le',
+    'utf_16le'           : 'utf_16_le',
+
+    # utf_7 codec
+    'u7'                 : 'utf_7',
+    'utf7'               : 'utf_7',
+    'unicode_1_1_utf_7'  : 'utf_7',
+
+    # utf_8 codec
+    'u8'                 : 'utf_8',
+    'utf'                : 'utf_8',
+    'utf8'               : 'utf_8',
+    'utf8_ucs2'          : 'utf_8',
+    'utf8_ucs4'          : 'utf_8',
+
+    # uu_codec codec
+    'uu'                 : 'uu_codec',
+
+    # zlib_codec codec
+    'zip'                : 'zlib_codec',
+    'zlib'               : 'zlib_codec',
+
+}

Added: vendor/Python/current/Lib/encodings/ascii.py
===================================================================
--- vendor/Python/current/Lib/encodings/ascii.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/ascii.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,50 @@
+""" Python 'ascii' Codec
+
+
+Written by Marc-Andre Lemburg (mal at lemburg.com).
+
+(c) Copyright CNRI, All Rights Reserved. NO WARRANTY.
+
+"""
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    # Note: Binding these as C functions will result in the class not
+    # converting them to methods. This is intended.
+    encode = codecs.ascii_encode
+    decode = codecs.ascii_decode
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.ascii_encode(input, self.errors)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.ascii_decode(input, self.errors)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+class StreamConverter(StreamWriter,StreamReader):
+
+    encode = codecs.ascii_decode
+    decode = codecs.ascii_encode
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='ascii',
+        encode=Codec.encode,
+        decode=Codec.decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamwriter=StreamWriter,
+        streamreader=StreamReader,
+    )

Added: vendor/Python/current/Lib/encodings/base64_codec.py
===================================================================
--- vendor/Python/current/Lib/encodings/base64_codec.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/base64_codec.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,79 @@
+""" Python 'base64_codec' Codec - base64 content transfer encoding
+
+    Unlike most of the other codecs which target Unicode, this codec
+    will return Python string objects for both encode and decode.
+
+    Written by Marc-Andre Lemburg (mal at lemburg.com).
+
+"""
+import codecs, base64
+
+### Codec APIs
+
+def base64_encode(input,errors='strict'):
+
+    """ Encodes the object input and returns a tuple (output
+        object, length consumed).
+
+        errors defines the error handling to apply. It defaults to
+        'strict' handling which is the only currently supported
+        error handling for this codec.
+
+    """
+    assert errors == 'strict'
+    output = base64.encodestring(input)
+    return (output, len(input))
+
+def base64_decode(input,errors='strict'):
+
+    """ Decodes the object input and returns a tuple (output
+        object, length consumed).
+
+        input must be an object which provides the bf_getreadbuf
+        buffer slot. Python strings, buffer objects and memory
+        mapped files are examples of objects providing this slot.
+
+        errors defines the error handling to apply. It defaults to
+        'strict' handling which is the only currently supported
+        error handling for this codec.
+
+    """
+    assert errors == 'strict'
+    output = base64.decodestring(input)
+    return (output, len(input))
+
+class Codec(codecs.Codec):
+
+    def encode(self, input,errors='strict'):
+        return base64_encode(input,errors)
+    def decode(self, input,errors='strict'):
+        return base64_decode(input,errors)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        assert self.errors == 'strict'
+        return base64.encodestring(input)
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        assert self.errors == 'strict'
+        return base64.decodestring(input)
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='base64',
+        encode=base64_encode,
+        decode=base64_decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamwriter=StreamWriter,
+        streamreader=StreamReader,
+    )

Added: vendor/Python/current/Lib/encodings/big5.py
===================================================================
--- vendor/Python/current/Lib/encodings/big5.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/big5.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,39 @@
+#
+# big5.py: Python Unicode Codec for BIG5
+#
+# Written by Hye-Shik Chang <perky at FreeBSD.org>
+#
+
+import _codecs_tw, codecs
+import _multibytecodec as mbc
+
+codec = _codecs_tw.getcodec('big5')
+
+class Codec(codecs.Codec):
+    encode = codec.encode
+    decode = codec.decode
+
+class IncrementalEncoder(mbc.MultibyteIncrementalEncoder,
+                         codecs.IncrementalEncoder):
+    codec = codec
+
+class IncrementalDecoder(mbc.MultibyteIncrementalDecoder,
+                         codecs.IncrementalDecoder):
+    codec = codec
+
+class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader):
+    codec = codec
+
+class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter):
+    codec = codec
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='big5',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )

Added: vendor/Python/current/Lib/encodings/big5hkscs.py
===================================================================
--- vendor/Python/current/Lib/encodings/big5hkscs.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/big5hkscs.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,39 @@
+#
+# big5hkscs.py: Python Unicode Codec for BIG5HKSCS
+#
+# Written by Hye-Shik Chang <perky at FreeBSD.org>
+#
+
+import _codecs_hk, codecs
+import _multibytecodec as mbc
+
+codec = _codecs_hk.getcodec('big5hkscs')
+
+class Codec(codecs.Codec):
+    encode = codec.encode
+    decode = codec.decode
+
+class IncrementalEncoder(mbc.MultibyteIncrementalEncoder,
+                         codecs.IncrementalEncoder):
+    codec = codec
+
+class IncrementalDecoder(mbc.MultibyteIncrementalDecoder,
+                         codecs.IncrementalDecoder):
+    codec = codec
+
+class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader):
+    codec = codec
+
+class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter):
+    codec = codec
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='big5hkscs',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )

Added: vendor/Python/current/Lib/encodings/bz2_codec.py
===================================================================
--- vendor/Python/current/Lib/encodings/bz2_codec.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/bz2_codec.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,102 @@
+""" Python 'bz2_codec' Codec - bz2 compression encoding
+
+    Unlike most of the other codecs which target Unicode, this codec
+    will return Python string objects for both encode and decode.
+
+    Adapted by Raymond Hettinger from zlib_codec.py which was written
+    by Marc-Andre Lemburg (mal at lemburg.com).
+
+"""
+import codecs
+import bz2 # this codec needs the optional bz2 module !
+
+### Codec APIs
+
+def bz2_encode(input,errors='strict'):
+
+    """ Encodes the object input and returns a tuple (output
+        object, length consumed).
+
+        errors defines the error handling to apply. It defaults to
+        'strict' handling which is the only currently supported
+        error handling for this codec.
+
+    """
+    assert errors == 'strict'
+    output = bz2.compress(input)
+    return (output, len(input))
+
+def bz2_decode(input,errors='strict'):
+
+    """ Decodes the object input and returns a tuple (output
+        object, length consumed).
+
+        input must be an object which provides the bf_getreadbuf
+        buffer slot. Python strings, buffer objects and memory
+        mapped files are examples of objects providing this slot.
+
+        errors defines the error handling to apply. It defaults to
+        'strict' handling which is the only currently supported
+        error handling for this codec.
+
+    """
+    assert errors == 'strict'
+    output = bz2.decompress(input)
+    return (output, len(input))
+
+class Codec(codecs.Codec):
+
+    def encode(self, input, errors='strict'):
+        return bz2_encode(input, errors)
+    def decode(self, input, errors='strict'):
+        return bz2_decode(input, errors)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def __init__(self, errors='strict'):
+        assert errors == 'strict'
+        self.errors = errors
+        self.compressobj = bz2.BZ2Compressor()
+
+    def encode(self, input, final=False):
+        if final:
+            c = self.compressobj.compress(input)
+            return c + self.compressobj.flush()
+        else:
+            return self.compressobj.compress(input)
+
+    def reset(self):
+        self.compressobj = bz2.BZ2Compressor()
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def __init__(self, errors='strict'):
+        assert errors == 'strict'
+        self.errors = errors
+        self.decompressobj = bz2.BZ2Decompressor()
+
+    def decode(self, input, final=False):
+        try:
+            return self.decompressobj.decompress(input)
+        except EOFError:
+            return ''
+
+    def reset(self):
+        self.decompressobj = bz2.BZ2Decompressor()
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name="bz2",
+        encode=bz2_encode,
+        decode=bz2_decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamwriter=StreamWriter,
+        streamreader=StreamReader,
+    )

Added: vendor/Python/current/Lib/encodings/charmap.py
===================================================================
--- vendor/Python/current/Lib/encodings/charmap.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/charmap.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,69 @@
+""" Generic Python Character Mapping Codec.
+
+    Use this codec directly rather than through the automatic
+    conversion mechanisms supplied by unicode() and .encode().
+
+
+Written by Marc-Andre Lemburg (mal at lemburg.com).
+
+(c) Copyright CNRI, All Rights Reserved. NO WARRANTY.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    # Note: Binding these as C functions will result in the class not
+    # converting them to methods. This is intended.
+    encode = codecs.charmap_encode
+    decode = codecs.charmap_decode
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def __init__(self, errors='strict', mapping=None):
+        codecs.IncrementalEncoder.__init__(self, errors)
+        self.mapping = mapping
+
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input, self.errors, self.mapping)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def __init__(self, errors='strict', mapping=None):
+        codecs.IncrementalDecoder.__init__(self, errors)
+        self.mapping = mapping
+
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input, self.errors, self.mapping)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+
+    def __init__(self,stream,errors='strict',mapping=None):
+        codecs.StreamWriter.__init__(self,stream,errors)
+        self.mapping = mapping
+
+    def encode(self,input,errors='strict'):
+        return Codec.encode(input,errors,self.mapping)
+
+class StreamReader(Codec,codecs.StreamReader):
+
+    def __init__(self,stream,errors='strict',mapping=None):
+        codecs.StreamReader.__init__(self,stream,errors)
+        self.mapping = mapping
+
+    def decode(self,input,errors='strict'):
+        return Codec.decode(input,errors,self.mapping)
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='charmap',
+        encode=Codec.encode,
+        decode=Codec.decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamwriter=StreamWriter,
+        streamreader=StreamReader,
+    )

Added: vendor/Python/current/Lib/encodings/cp037.py
===================================================================
--- vendor/Python/current/Lib/encodings/cp037.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/cp037.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,307 @@
+""" Python Character Mapping Codec cp037 generated from 'MAPPINGS/VENDORS/MICSFT/EBCDIC/CP037.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_table)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_table)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='cp037',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x00 -> NULL
+    u'\x01'     #  0x01 -> START OF HEADING
+    u'\x02'     #  0x02 -> START OF TEXT
+    u'\x03'     #  0x03 -> END OF TEXT
+    u'\x9c'     #  0x04 -> CONTROL
+    u'\t'       #  0x05 -> HORIZONTAL TABULATION
+    u'\x86'     #  0x06 -> CONTROL
+    u'\x7f'     #  0x07 -> DELETE
+    u'\x97'     #  0x08 -> CONTROL
+    u'\x8d'     #  0x09 -> CONTROL
+    u'\x8e'     #  0x0A -> CONTROL
+    u'\x0b'     #  0x0B -> VERTICAL TABULATION
+    u'\x0c'     #  0x0C -> FORM FEED
+    u'\r'       #  0x0D -> CARRIAGE RETURN
+    u'\x0e'     #  0x0E -> SHIFT OUT
+    u'\x0f'     #  0x0F -> SHIFT IN
+    u'\x10'     #  0x10 -> DATA LINK ESCAPE
+    u'\x11'     #  0x11 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x12 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x13 -> DEVICE CONTROL THREE
+    u'\x9d'     #  0x14 -> CONTROL
+    u'\x85'     #  0x15 -> CONTROL
+    u'\x08'     #  0x16 -> BACKSPACE
+    u'\x87'     #  0x17 -> CONTROL
+    u'\x18'     #  0x18 -> CANCEL
+    u'\x19'     #  0x19 -> END OF MEDIUM
+    u'\x92'     #  0x1A -> CONTROL
+    u'\x8f'     #  0x1B -> CONTROL
+    u'\x1c'     #  0x1C -> FILE SEPARATOR
+    u'\x1d'     #  0x1D -> GROUP SEPARATOR
+    u'\x1e'     #  0x1E -> RECORD SEPARATOR
+    u'\x1f'     #  0x1F -> UNIT SEPARATOR
+    u'\x80'     #  0x20 -> CONTROL
+    u'\x81'     #  0x21 -> CONTROL
+    u'\x82'     #  0x22 -> CONTROL
+    u'\x83'     #  0x23 -> CONTROL
+    u'\x84'     #  0x24 -> CONTROL
+    u'\n'       #  0x25 -> LINE FEED
+    u'\x17'     #  0x26 -> END OF TRANSMISSION BLOCK
+    u'\x1b'     #  0x27 -> ESCAPE
+    u'\x88'     #  0x28 -> CONTROL
+    u'\x89'     #  0x29 -> CONTROL
+    u'\x8a'     #  0x2A -> CONTROL
+    u'\x8b'     #  0x2B -> CONTROL
+    u'\x8c'     #  0x2C -> CONTROL
+    u'\x05'     #  0x2D -> ENQUIRY
+    u'\x06'     #  0x2E -> ACKNOWLEDGE
+    u'\x07'     #  0x2F -> BELL
+    u'\x90'     #  0x30 -> CONTROL
+    u'\x91'     #  0x31 -> CONTROL
+    u'\x16'     #  0x32 -> SYNCHRONOUS IDLE
+    u'\x93'     #  0x33 -> CONTROL
+    u'\x94'     #  0x34 -> CONTROL
+    u'\x95'     #  0x35 -> CONTROL
+    u'\x96'     #  0x36 -> CONTROL
+    u'\x04'     #  0x37 -> END OF TRANSMISSION
+    u'\x98'     #  0x38 -> CONTROL
+    u'\x99'     #  0x39 -> CONTROL
+    u'\x9a'     #  0x3A -> CONTROL
+    u'\x9b'     #  0x3B -> CONTROL
+    u'\x14'     #  0x3C -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x3D -> NEGATIVE ACKNOWLEDGE
+    u'\x9e'     #  0x3E -> CONTROL
+    u'\x1a'     #  0x3F -> SUBSTITUTE
+    u' '        #  0x40 -> SPACE
+    u'\xa0'     #  0x41 -> NO-BREAK SPACE
+    u'\xe2'     #  0x42 -> LATIN SMALL LETTER A WITH CIRCUMFLEX
+    u'\xe4'     #  0x43 -> LATIN SMALL LETTER A WITH DIAERESIS
+    u'\xe0'     #  0x44 -> LATIN SMALL LETTER A WITH GRAVE
+    u'\xe1'     #  0x45 -> LATIN SMALL LETTER A WITH ACUTE
+    u'\xe3'     #  0x46 -> LATIN SMALL LETTER A WITH TILDE
+    u'\xe5'     #  0x47 -> LATIN SMALL LETTER A WITH RING ABOVE
+    u'\xe7'     #  0x48 -> LATIN SMALL LETTER C WITH CEDILLA
+    u'\xf1'     #  0x49 -> LATIN SMALL LETTER N WITH TILDE
+    u'\xa2'     #  0x4A -> CENT SIGN
+    u'.'        #  0x4B -> FULL STOP
+    u'<'        #  0x4C -> LESS-THAN SIGN
+    u'('        #  0x4D -> LEFT PARENTHESIS
+    u'+'        #  0x4E -> PLUS SIGN
+    u'|'        #  0x4F -> VERTICAL LINE
+    u'&'        #  0x50 -> AMPERSAND
+    u'\xe9'     #  0x51 -> LATIN SMALL LETTER E WITH ACUTE
+    u'\xea'     #  0x52 -> LATIN SMALL LETTER E WITH CIRCUMFLEX
+    u'\xeb'     #  0x53 -> LATIN SMALL LETTER E WITH DIAERESIS
+    u'\xe8'     #  0x54 -> LATIN SMALL LETTER E WITH GRAVE
+    u'\xed'     #  0x55 -> LATIN SMALL LETTER I WITH ACUTE
+    u'\xee'     #  0x56 -> LATIN SMALL LETTER I WITH CIRCUMFLEX
+    u'\xef'     #  0x57 -> LATIN SMALL LETTER I WITH DIAERESIS
+    u'\xec'     #  0x58 -> LATIN SMALL LETTER I WITH GRAVE
+    u'\xdf'     #  0x59 -> LATIN SMALL LETTER SHARP S (GERMAN)
+    u'!'        #  0x5A -> EXCLAMATION MARK
+    u'$'        #  0x5B -> DOLLAR SIGN
+    u'*'        #  0x5C -> ASTERISK
+    u')'        #  0x5D -> RIGHT PARENTHESIS
+    u';'        #  0x5E -> SEMICOLON
+    u'\xac'     #  0x5F -> NOT SIGN
+    u'-'        #  0x60 -> HYPHEN-MINUS
+    u'/'        #  0x61 -> SOLIDUS
+    u'\xc2'     #  0x62 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+    u'\xc4'     #  0x63 -> LATIN CAPITAL LETTER A WITH DIAERESIS
+    u'\xc0'     #  0x64 -> LATIN CAPITAL LETTER A WITH GRAVE
+    u'\xc1'     #  0x65 -> LATIN CAPITAL LETTER A WITH ACUTE
+    u'\xc3'     #  0x66 -> LATIN CAPITAL LETTER A WITH TILDE
+    u'\xc5'     #  0x67 -> LATIN CAPITAL LETTER A WITH RING ABOVE
+    u'\xc7'     #  0x68 -> LATIN CAPITAL LETTER C WITH CEDILLA
+    u'\xd1'     #  0x69 -> LATIN CAPITAL LETTER N WITH TILDE
+    u'\xa6'     #  0x6A -> BROKEN BAR
+    u','        #  0x6B -> COMMA
+    u'%'        #  0x6C -> PERCENT SIGN
+    u'_'        #  0x6D -> LOW LINE
+    u'>'        #  0x6E -> GREATER-THAN SIGN
+    u'?'        #  0x6F -> QUESTION MARK
+    u'\xf8'     #  0x70 -> LATIN SMALL LETTER O WITH STROKE
+    u'\xc9'     #  0x71 -> LATIN CAPITAL LETTER E WITH ACUTE
+    u'\xca'     #  0x72 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+    u'\xcb'     #  0x73 -> LATIN CAPITAL LETTER E WITH DIAERESIS
+    u'\xc8'     #  0x74 -> LATIN CAPITAL LETTER E WITH GRAVE
+    u'\xcd'     #  0x75 -> LATIN CAPITAL LETTER I WITH ACUTE
+    u'\xce'     #  0x76 -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+    u'\xcf'     #  0x77 -> LATIN CAPITAL LETTER I WITH DIAERESIS
+    u'\xcc'     #  0x78 -> LATIN CAPITAL LETTER I WITH GRAVE
+    u'`'        #  0x79 -> GRAVE ACCENT
+    u':'        #  0x7A -> COLON
+    u'#'        #  0x7B -> NUMBER SIGN
+    u'@'        #  0x7C -> COMMERCIAL AT
+    u"'"        #  0x7D -> APOSTROPHE
+    u'='        #  0x7E -> EQUALS SIGN
+    u'"'        #  0x7F -> QUOTATION MARK
+    u'\xd8'     #  0x80 -> LATIN CAPITAL LETTER O WITH STROKE
+    u'a'        #  0x81 -> LATIN SMALL LETTER A
+    u'b'        #  0x82 -> LATIN SMALL LETTER B
+    u'c'        #  0x83 -> LATIN SMALL LETTER C
+    u'd'        #  0x84 -> LATIN SMALL LETTER D
+    u'e'        #  0x85 -> LATIN SMALL LETTER E
+    u'f'        #  0x86 -> LATIN SMALL LETTER F
+    u'g'        #  0x87 -> LATIN SMALL LETTER G
+    u'h'        #  0x88 -> LATIN SMALL LETTER H
+    u'i'        #  0x89 -> LATIN SMALL LETTER I
+    u'\xab'     #  0x8A -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xbb'     #  0x8B -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xf0'     #  0x8C -> LATIN SMALL LETTER ETH (ICELANDIC)
+    u'\xfd'     #  0x8D -> LATIN SMALL LETTER Y WITH ACUTE
+    u'\xfe'     #  0x8E -> LATIN SMALL LETTER THORN (ICELANDIC)
+    u'\xb1'     #  0x8F -> PLUS-MINUS SIGN
+    u'\xb0'     #  0x90 -> DEGREE SIGN
+    u'j'        #  0x91 -> LATIN SMALL LETTER J
+    u'k'        #  0x92 -> LATIN SMALL LETTER K
+    u'l'        #  0x93 -> LATIN SMALL LETTER L
+    u'm'        #  0x94 -> LATIN SMALL LETTER M
+    u'n'        #  0x95 -> LATIN SMALL LETTER N
+    u'o'        #  0x96 -> LATIN SMALL LETTER O
+    u'p'        #  0x97 -> LATIN SMALL LETTER P
+    u'q'        #  0x98 -> LATIN SMALL LETTER Q
+    u'r'        #  0x99 -> LATIN SMALL LETTER R
+    u'\xaa'     #  0x9A -> FEMININE ORDINAL INDICATOR
+    u'\xba'     #  0x9B -> MASCULINE ORDINAL INDICATOR
+    u'\xe6'     #  0x9C -> LATIN SMALL LIGATURE AE
+    u'\xb8'     #  0x9D -> CEDILLA
+    u'\xc6'     #  0x9E -> LATIN CAPITAL LIGATURE AE
+    u'\xa4'     #  0x9F -> CURRENCY SIGN
+    u'\xb5'     #  0xA0 -> MICRO SIGN
+    u'~'        #  0xA1 -> TILDE
+    u's'        #  0xA2 -> LATIN SMALL LETTER S
+    u't'        #  0xA3 -> LATIN SMALL LETTER T
+    u'u'        #  0xA4 -> LATIN SMALL LETTER U
+    u'v'        #  0xA5 -> LATIN SMALL LETTER V
+    u'w'        #  0xA6 -> LATIN SMALL LETTER W
+    u'x'        #  0xA7 -> LATIN SMALL LETTER X
+    u'y'        #  0xA8 -> LATIN SMALL LETTER Y
+    u'z'        #  0xA9 -> LATIN SMALL LETTER Z
+    u'\xa1'     #  0xAA -> INVERTED EXCLAMATION MARK
+    u'\xbf'     #  0xAB -> INVERTED QUESTION MARK
+    u'\xd0'     #  0xAC -> LATIN CAPITAL LETTER ETH (ICELANDIC)
+    u'\xdd'     #  0xAD -> LATIN CAPITAL LETTER Y WITH ACUTE
+    u'\xde'     #  0xAE -> LATIN CAPITAL LETTER THORN (ICELANDIC)
+    u'\xae'     #  0xAF -> REGISTERED SIGN
+    u'^'        #  0xB0 -> CIRCUMFLEX ACCENT
+    u'\xa3'     #  0xB1 -> POUND SIGN
+    u'\xa5'     #  0xB2 -> YEN SIGN
+    u'\xb7'     #  0xB3 -> MIDDLE DOT
+    u'\xa9'     #  0xB4 -> COPYRIGHT SIGN
+    u'\xa7'     #  0xB5 -> SECTION SIGN
+    u'\xb6'     #  0xB6 -> PILCROW SIGN
+    u'\xbc'     #  0xB7 -> VULGAR FRACTION ONE QUARTER
+    u'\xbd'     #  0xB8 -> VULGAR FRACTION ONE HALF
+    u'\xbe'     #  0xB9 -> VULGAR FRACTION THREE QUARTERS
+    u'['        #  0xBA -> LEFT SQUARE BRACKET
+    u']'        #  0xBB -> RIGHT SQUARE BRACKET
+    u'\xaf'     #  0xBC -> MACRON
+    u'\xa8'     #  0xBD -> DIAERESIS
+    u'\xb4'     #  0xBE -> ACUTE ACCENT
+    u'\xd7'     #  0xBF -> MULTIPLICATION SIGN
+    u'{'        #  0xC0 -> LEFT CURLY BRACKET
+    u'A'        #  0xC1 -> LATIN CAPITAL LETTER A
+    u'B'        #  0xC2 -> LATIN CAPITAL LETTER B
+    u'C'        #  0xC3 -> LATIN CAPITAL LETTER C
+    u'D'        #  0xC4 -> LATIN CAPITAL LETTER D
+    u'E'        #  0xC5 -> LATIN CAPITAL LETTER E
+    u'F'        #  0xC6 -> LATIN CAPITAL LETTER F
+    u'G'        #  0xC7 -> LATIN CAPITAL LETTER G
+    u'H'        #  0xC8 -> LATIN CAPITAL LETTER H
+    u'I'        #  0xC9 -> LATIN CAPITAL LETTER I
+    u'\xad'     #  0xCA -> SOFT HYPHEN
+    u'\xf4'     #  0xCB -> LATIN SMALL LETTER O WITH CIRCUMFLEX
+    u'\xf6'     #  0xCC -> LATIN SMALL LETTER O WITH DIAERESIS
+    u'\xf2'     #  0xCD -> LATIN SMALL LETTER O WITH GRAVE
+    u'\xf3'     #  0xCE -> LATIN SMALL LETTER O WITH ACUTE
+    u'\xf5'     #  0xCF -> LATIN SMALL LETTER O WITH TILDE
+    u'}'        #  0xD0 -> RIGHT CURLY BRACKET
+    u'J'        #  0xD1 -> LATIN CAPITAL LETTER J
+    u'K'        #  0xD2 -> LATIN CAPITAL LETTER K
+    u'L'        #  0xD3 -> LATIN CAPITAL LETTER L
+    u'M'        #  0xD4 -> LATIN CAPITAL LETTER M
+    u'N'        #  0xD5 -> LATIN CAPITAL LETTER N
+    u'O'        #  0xD6 -> LATIN CAPITAL LETTER O
+    u'P'        #  0xD7 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0xD8 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0xD9 -> LATIN CAPITAL LETTER R
+    u'\xb9'     #  0xDA -> SUPERSCRIPT ONE
+    u'\xfb'     #  0xDB -> LATIN SMALL LETTER U WITH CIRCUMFLEX
+    u'\xfc'     #  0xDC -> LATIN SMALL LETTER U WITH DIAERESIS
+    u'\xf9'     #  0xDD -> LATIN SMALL LETTER U WITH GRAVE
+    u'\xfa'     #  0xDE -> LATIN SMALL LETTER U WITH ACUTE
+    u'\xff'     #  0xDF -> LATIN SMALL LETTER Y WITH DIAERESIS
+    u'\\'       #  0xE0 -> REVERSE SOLIDUS
+    u'\xf7'     #  0xE1 -> DIVISION SIGN
+    u'S'        #  0xE2 -> LATIN CAPITAL LETTER S
+    u'T'        #  0xE3 -> LATIN CAPITAL LETTER T
+    u'U'        #  0xE4 -> LATIN CAPITAL LETTER U
+    u'V'        #  0xE5 -> LATIN CAPITAL LETTER V
+    u'W'        #  0xE6 -> LATIN CAPITAL LETTER W
+    u'X'        #  0xE7 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0xE8 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0xE9 -> LATIN CAPITAL LETTER Z
+    u'\xb2'     #  0xEA -> SUPERSCRIPT TWO
+    u'\xd4'     #  0xEB -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+    u'\xd6'     #  0xEC -> LATIN CAPITAL LETTER O WITH DIAERESIS
+    u'\xd2'     #  0xED -> LATIN CAPITAL LETTER O WITH GRAVE
+    u'\xd3'     #  0xEE -> LATIN CAPITAL LETTER O WITH ACUTE
+    u'\xd5'     #  0xEF -> LATIN CAPITAL LETTER O WITH TILDE
+    u'0'        #  0xF0 -> DIGIT ZERO
+    u'1'        #  0xF1 -> DIGIT ONE
+    u'2'        #  0xF2 -> DIGIT TWO
+    u'3'        #  0xF3 -> DIGIT THREE
+    u'4'        #  0xF4 -> DIGIT FOUR
+    u'5'        #  0xF5 -> DIGIT FIVE
+    u'6'        #  0xF6 -> DIGIT SIX
+    u'7'        #  0xF7 -> DIGIT SEVEN
+    u'8'        #  0xF8 -> DIGIT EIGHT
+    u'9'        #  0xF9 -> DIGIT NINE
+    u'\xb3'     #  0xFA -> SUPERSCRIPT THREE
+    u'\xdb'     #  0xFB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+    u'\xdc'     #  0xFC -> LATIN CAPITAL LETTER U WITH DIAERESIS
+    u'\xd9'     #  0xFD -> LATIN CAPITAL LETTER U WITH GRAVE
+    u'\xda'     #  0xFE -> LATIN CAPITAL LETTER U WITH ACUTE
+    u'\x9f'     #  0xFF -> CONTROL
+)
+
+### Encoding table
+encoding_table=codecs.charmap_build(decoding_table)

Added: vendor/Python/current/Lib/encodings/cp1006.py
===================================================================
--- vendor/Python/current/Lib/encodings/cp1006.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/cp1006.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,307 @@
+""" Python Character Mapping Codec cp1006 generated from 'MAPPINGS/VENDORS/MISC/CP1006.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_table)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_table)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='cp1006',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x00 -> NULL
+    u'\x01'     #  0x01 -> START OF HEADING
+    u'\x02'     #  0x02 -> START OF TEXT
+    u'\x03'     #  0x03 -> END OF TEXT
+    u'\x04'     #  0x04 -> END OF TRANSMISSION
+    u'\x05'     #  0x05 -> ENQUIRY
+    u'\x06'     #  0x06 -> ACKNOWLEDGE
+    u'\x07'     #  0x07 -> BELL
+    u'\x08'     #  0x08 -> BACKSPACE
+    u'\t'       #  0x09 -> HORIZONTAL TABULATION
+    u'\n'       #  0x0A -> LINE FEED
+    u'\x0b'     #  0x0B -> VERTICAL TABULATION
+    u'\x0c'     #  0x0C -> FORM FEED
+    u'\r'       #  0x0D -> CARRIAGE RETURN
+    u'\x0e'     #  0x0E -> SHIFT OUT
+    u'\x0f'     #  0x0F -> SHIFT IN
+    u'\x10'     #  0x10 -> DATA LINK ESCAPE
+    u'\x11'     #  0x11 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x12 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x13 -> DEVICE CONTROL THREE
+    u'\x14'     #  0x14 -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x15 -> NEGATIVE ACKNOWLEDGE
+    u'\x16'     #  0x16 -> SYNCHRONOUS IDLE
+    u'\x17'     #  0x17 -> END OF TRANSMISSION BLOCK
+    u'\x18'     #  0x18 -> CANCEL
+    u'\x19'     #  0x19 -> END OF MEDIUM
+    u'\x1a'     #  0x1A -> SUBSTITUTE
+    u'\x1b'     #  0x1B -> ESCAPE
+    u'\x1c'     #  0x1C -> FILE SEPARATOR
+    u'\x1d'     #  0x1D -> GROUP SEPARATOR
+    u'\x1e'     #  0x1E -> RECORD SEPARATOR
+    u'\x1f'     #  0x1F -> UNIT SEPARATOR
+    u' '        #  0x20 -> SPACE
+    u'!'        #  0x21 -> EXCLAMATION MARK
+    u'"'        #  0x22 -> QUOTATION MARK
+    u'#'        #  0x23 -> NUMBER SIGN
+    u'$'        #  0x24 -> DOLLAR SIGN
+    u'%'        #  0x25 -> PERCENT SIGN
+    u'&'        #  0x26 -> AMPERSAND
+    u"'"        #  0x27 -> APOSTROPHE
+    u'('        #  0x28 -> LEFT PARENTHESIS
+    u')'        #  0x29 -> RIGHT PARENTHESIS
+    u'*'        #  0x2A -> ASTERISK
+    u'+'        #  0x2B -> PLUS SIGN
+    u','        #  0x2C -> COMMA
+    u'-'        #  0x2D -> HYPHEN-MINUS
+    u'.'        #  0x2E -> FULL STOP
+    u'/'        #  0x2F -> SOLIDUS
+    u'0'        #  0x30 -> DIGIT ZERO
+    u'1'        #  0x31 -> DIGIT ONE
+    u'2'        #  0x32 -> DIGIT TWO
+    u'3'        #  0x33 -> DIGIT THREE
+    u'4'        #  0x34 -> DIGIT FOUR
+    u'5'        #  0x35 -> DIGIT FIVE
+    u'6'        #  0x36 -> DIGIT SIX
+    u'7'        #  0x37 -> DIGIT SEVEN
+    u'8'        #  0x38 -> DIGIT EIGHT
+    u'9'        #  0x39 -> DIGIT NINE
+    u':'        #  0x3A -> COLON
+    u';'        #  0x3B -> SEMICOLON
+    u'<'        #  0x3C -> LESS-THAN SIGN
+    u'='        #  0x3D -> EQUALS SIGN
+    u'>'        #  0x3E -> GREATER-THAN SIGN
+    u'?'        #  0x3F -> QUESTION MARK
+    u'@'        #  0x40 -> COMMERCIAL AT
+    u'A'        #  0x41 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x42 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x43 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x44 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x45 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x46 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x47 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x48 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x49 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x4A -> LATIN CAPITAL LETTER J
+    u'K'        #  0x4B -> LATIN CAPITAL LETTER K
+    u'L'        #  0x4C -> LATIN CAPITAL LETTER L
+    u'M'        #  0x4D -> LATIN CAPITAL LETTER M
+    u'N'        #  0x4E -> LATIN CAPITAL LETTER N
+    u'O'        #  0x4F -> LATIN CAPITAL LETTER O
+    u'P'        #  0x50 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x51 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x52 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x53 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x54 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x55 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x56 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x57 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x58 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x59 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x5A -> LATIN CAPITAL LETTER Z
+    u'['        #  0x5B -> LEFT SQUARE BRACKET
+    u'\\'       #  0x5C -> REVERSE SOLIDUS
+    u']'        #  0x5D -> RIGHT SQUARE BRACKET
+    u'^'        #  0x5E -> CIRCUMFLEX ACCENT
+    u'_'        #  0x5F -> LOW LINE
+    u'`'        #  0x60 -> GRAVE ACCENT
+    u'a'        #  0x61 -> LATIN SMALL LETTER A
+    u'b'        #  0x62 -> LATIN SMALL LETTER B
+    u'c'        #  0x63 -> LATIN SMALL LETTER C
+    u'd'        #  0x64 -> LATIN SMALL LETTER D
+    u'e'        #  0x65 -> LATIN SMALL LETTER E
+    u'f'        #  0x66 -> LATIN SMALL LETTER F
+    u'g'        #  0x67 -> LATIN SMALL LETTER G
+    u'h'        #  0x68 -> LATIN SMALL LETTER H
+    u'i'        #  0x69 -> LATIN SMALL LETTER I
+    u'j'        #  0x6A -> LATIN SMALL LETTER J
+    u'k'        #  0x6B -> LATIN SMALL LETTER K
+    u'l'        #  0x6C -> LATIN SMALL LETTER L
+    u'm'        #  0x6D -> LATIN SMALL LETTER M
+    u'n'        #  0x6E -> LATIN SMALL LETTER N
+    u'o'        #  0x6F -> LATIN SMALL LETTER O
+    u'p'        #  0x70 -> LATIN SMALL LETTER P
+    u'q'        #  0x71 -> LATIN SMALL LETTER Q
+    u'r'        #  0x72 -> LATIN SMALL LETTER R
+    u's'        #  0x73 -> LATIN SMALL LETTER S
+    u't'        #  0x74 -> LATIN SMALL LETTER T
+    u'u'        #  0x75 -> LATIN SMALL LETTER U
+    u'v'        #  0x76 -> LATIN SMALL LETTER V
+    u'w'        #  0x77 -> LATIN SMALL LETTER W
+    u'x'        #  0x78 -> LATIN SMALL LETTER X
+    u'y'        #  0x79 -> LATIN SMALL LETTER Y
+    u'z'        #  0x7A -> LATIN SMALL LETTER Z
+    u'{'        #  0x7B -> LEFT CURLY BRACKET
+    u'|'        #  0x7C -> VERTICAL LINE
+    u'}'        #  0x7D -> RIGHT CURLY BRACKET
+    u'~'        #  0x7E -> TILDE
+    u'\x7f'     #  0x7F -> DELETE
+    u'\x80'     #  0x80 -> <control>
+    u'\x81'     #  0x81 -> <control>
+    u'\x82'     #  0x82 -> <control>
+    u'\x83'     #  0x83 -> <control>
+    u'\x84'     #  0x84 -> <control>
+    u'\x85'     #  0x85 -> <control>
+    u'\x86'     #  0x86 -> <control>
+    u'\x87'     #  0x87 -> <control>
+    u'\x88'     #  0x88 -> <control>
+    u'\x89'     #  0x89 -> <control>
+    u'\x8a'     #  0x8A -> <control>
+    u'\x8b'     #  0x8B -> <control>
+    u'\x8c'     #  0x8C -> <control>
+    u'\x8d'     #  0x8D -> <control>
+    u'\x8e'     #  0x8E -> <control>
+    u'\x8f'     #  0x8F -> <control>
+    u'\x90'     #  0x90 -> <control>
+    u'\x91'     #  0x91 -> <control>
+    u'\x92'     #  0x92 -> <control>
+    u'\x93'     #  0x93 -> <control>
+    u'\x94'     #  0x94 -> <control>
+    u'\x95'     #  0x95 -> <control>
+    u'\x96'     #  0x96 -> <control>
+    u'\x97'     #  0x97 -> <control>
+    u'\x98'     #  0x98 -> <control>
+    u'\x99'     #  0x99 -> <control>
+    u'\x9a'     #  0x9A -> <control>
+    u'\x9b'     #  0x9B -> <control>
+    u'\x9c'     #  0x9C -> <control>
+    u'\x9d'     #  0x9D -> <control>
+    u'\x9e'     #  0x9E -> <control>
+    u'\x9f'     #  0x9F -> <control>
+    u'\xa0'     #  0xA0 -> NO-BREAK SPACE
+    u'\u06f0'   #  0xA1 -> EXTENDED ARABIC-INDIC DIGIT ZERO
+    u'\u06f1'   #  0xA2 -> EXTENDED ARABIC-INDIC DIGIT ONE
+    u'\u06f2'   #  0xA3 -> EXTENDED ARABIC-INDIC DIGIT TWO
+    u'\u06f3'   #  0xA4 -> EXTENDED ARABIC-INDIC DIGIT THREE
+    u'\u06f4'   #  0xA5 -> EXTENDED ARABIC-INDIC DIGIT FOUR
+    u'\u06f5'   #  0xA6 -> EXTENDED ARABIC-INDIC DIGIT FIVE
+    u'\u06f6'   #  0xA7 -> EXTENDED ARABIC-INDIC DIGIT SIX
+    u'\u06f7'   #  0xA8 -> EXTENDED ARABIC-INDIC DIGIT SEVEN
+    u'\u06f8'   #  0xA9 -> EXTENDED ARABIC-INDIC DIGIT EIGHT
+    u'\u06f9'   #  0xAA -> EXTENDED ARABIC-INDIC DIGIT NINE
+    u'\u060c'   #  0xAB -> ARABIC COMMA
+    u'\u061b'   #  0xAC -> ARABIC SEMICOLON
+    u'\xad'     #  0xAD -> SOFT HYPHEN
+    u'\u061f'   #  0xAE -> ARABIC QUESTION MARK
+    u'\ufe81'   #  0xAF -> ARABIC LETTER ALEF WITH MADDA ABOVE ISOLATED FORM
+    u'\ufe8d'   #  0xB0 -> ARABIC LETTER ALEF ISOLATED FORM
+    u'\ufe8e'   #  0xB1 -> ARABIC LETTER ALEF FINAL FORM
+    u'\ufe8e'   #  0xB2 -> ARABIC LETTER ALEF FINAL FORM
+    u'\ufe8f'   #  0xB3 -> ARABIC LETTER BEH ISOLATED FORM
+    u'\ufe91'   #  0xB4 -> ARABIC LETTER BEH INITIAL FORM
+    u'\ufb56'   #  0xB5 -> ARABIC LETTER PEH ISOLATED FORM
+    u'\ufb58'   #  0xB6 -> ARABIC LETTER PEH INITIAL FORM
+    u'\ufe93'   #  0xB7 -> ARABIC LETTER TEH MARBUTA ISOLATED FORM
+    u'\ufe95'   #  0xB8 -> ARABIC LETTER TEH ISOLATED FORM
+    u'\ufe97'   #  0xB9 -> ARABIC LETTER TEH INITIAL FORM
+    u'\ufb66'   #  0xBA -> ARABIC LETTER TTEH ISOLATED FORM
+    u'\ufb68'   #  0xBB -> ARABIC LETTER TTEH INITIAL FORM
+    u'\ufe99'   #  0xBC -> ARABIC LETTER THEH ISOLATED FORM
+    u'\ufe9b'   #  0xBD -> ARABIC LETTER THEH INITIAL FORM
+    u'\ufe9d'   #  0xBE -> ARABIC LETTER JEEM ISOLATED FORM
+    u'\ufe9f'   #  0xBF -> ARABIC LETTER JEEM INITIAL FORM
+    u'\ufb7a'   #  0xC0 -> ARABIC LETTER TCHEH ISOLATED FORM
+    u'\ufb7c'   #  0xC1 -> ARABIC LETTER TCHEH INITIAL FORM
+    u'\ufea1'   #  0xC2 -> ARABIC LETTER HAH ISOLATED FORM
+    u'\ufea3'   #  0xC3 -> ARABIC LETTER HAH INITIAL FORM
+    u'\ufea5'   #  0xC4 -> ARABIC LETTER KHAH ISOLATED FORM
+    u'\ufea7'   #  0xC5 -> ARABIC LETTER KHAH INITIAL FORM
+    u'\ufea9'   #  0xC6 -> ARABIC LETTER DAL ISOLATED FORM
+    u'\ufb84'   #  0xC7 -> ARABIC LETTER DAHAL ISOLATED FORMN
+    u'\ufeab'   #  0xC8 -> ARABIC LETTER THAL ISOLATED FORM
+    u'\ufead'   #  0xC9 -> ARABIC LETTER REH ISOLATED FORM
+    u'\ufb8c'   #  0xCA -> ARABIC LETTER RREH ISOLATED FORM
+    u'\ufeaf'   #  0xCB -> ARABIC LETTER ZAIN ISOLATED FORM
+    u'\ufb8a'   #  0xCC -> ARABIC LETTER JEH ISOLATED FORM
+    u'\ufeb1'   #  0xCD -> ARABIC LETTER SEEN ISOLATED FORM
+    u'\ufeb3'   #  0xCE -> ARABIC LETTER SEEN INITIAL FORM
+    u'\ufeb5'   #  0xCF -> ARABIC LETTER SHEEN ISOLATED FORM
+    u'\ufeb7'   #  0xD0 -> ARABIC LETTER SHEEN INITIAL FORM
+    u'\ufeb9'   #  0xD1 -> ARABIC LETTER SAD ISOLATED FORM
+    u'\ufebb'   #  0xD2 -> ARABIC LETTER SAD INITIAL FORM
+    u'\ufebd'   #  0xD3 -> ARABIC LETTER DAD ISOLATED FORM
+    u'\ufebf'   #  0xD4 -> ARABIC LETTER DAD INITIAL FORM
+    u'\ufec1'   #  0xD5 -> ARABIC LETTER TAH ISOLATED FORM
+    u'\ufec5'   #  0xD6 -> ARABIC LETTER ZAH ISOLATED FORM
+    u'\ufec9'   #  0xD7 -> ARABIC LETTER AIN ISOLATED FORM
+    u'\ufeca'   #  0xD8 -> ARABIC LETTER AIN FINAL FORM
+    u'\ufecb'   #  0xD9 -> ARABIC LETTER AIN INITIAL FORM
+    u'\ufecc'   #  0xDA -> ARABIC LETTER AIN MEDIAL FORM
+    u'\ufecd'   #  0xDB -> ARABIC LETTER GHAIN ISOLATED FORM
+    u'\ufece'   #  0xDC -> ARABIC LETTER GHAIN FINAL FORM
+    u'\ufecf'   #  0xDD -> ARABIC LETTER GHAIN INITIAL FORM
+    u'\ufed0'   #  0xDE -> ARABIC LETTER GHAIN MEDIAL FORM
+    u'\ufed1'   #  0xDF -> ARABIC LETTER FEH ISOLATED FORM
+    u'\ufed3'   #  0xE0 -> ARABIC LETTER FEH INITIAL FORM
+    u'\ufed5'   #  0xE1 -> ARABIC LETTER QAF ISOLATED FORM
+    u'\ufed7'   #  0xE2 -> ARABIC LETTER QAF INITIAL FORM
+    u'\ufed9'   #  0xE3 -> ARABIC LETTER KAF ISOLATED FORM
+    u'\ufedb'   #  0xE4 -> ARABIC LETTER KAF INITIAL FORM
+    u'\ufb92'   #  0xE5 -> ARABIC LETTER GAF ISOLATED FORM
+    u'\ufb94'   #  0xE6 -> ARABIC LETTER GAF INITIAL FORM
+    u'\ufedd'   #  0xE7 -> ARABIC LETTER LAM ISOLATED FORM
+    u'\ufedf'   #  0xE8 -> ARABIC LETTER LAM INITIAL FORM
+    u'\ufee0'   #  0xE9 -> ARABIC LETTER LAM MEDIAL FORM
+    u'\ufee1'   #  0xEA -> ARABIC LETTER MEEM ISOLATED FORM
+    u'\ufee3'   #  0xEB -> ARABIC LETTER MEEM INITIAL FORM
+    u'\ufb9e'   #  0xEC -> ARABIC LETTER NOON GHUNNA ISOLATED FORM
+    u'\ufee5'   #  0xED -> ARABIC LETTER NOON ISOLATED FORM
+    u'\ufee7'   #  0xEE -> ARABIC LETTER NOON INITIAL FORM
+    u'\ufe85'   #  0xEF -> ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM
+    u'\ufeed'   #  0xF0 -> ARABIC LETTER WAW ISOLATED FORM
+    u'\ufba6'   #  0xF1 -> ARABIC LETTER HEH GOAL ISOLATED FORM
+    u'\ufba8'   #  0xF2 -> ARABIC LETTER HEH GOAL INITIAL FORM
+    u'\ufba9'   #  0xF3 -> ARABIC LETTER HEH GOAL MEDIAL FORM
+    u'\ufbaa'   #  0xF4 -> ARABIC LETTER HEH DOACHASHMEE ISOLATED FORM
+    u'\ufe80'   #  0xF5 -> ARABIC LETTER HAMZA ISOLATED FORM
+    u'\ufe89'   #  0xF6 -> ARABIC LETTER YEH WITH HAMZA ABOVE ISOLATED FORM
+    u'\ufe8a'   #  0xF7 -> ARABIC LETTER YEH WITH HAMZA ABOVE FINAL FORM
+    u'\ufe8b'   #  0xF8 -> ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM
+    u'\ufef1'   #  0xF9 -> ARABIC LETTER YEH ISOLATED FORM
+    u'\ufef2'   #  0xFA -> ARABIC LETTER YEH FINAL FORM
+    u'\ufef3'   #  0xFB -> ARABIC LETTER YEH INITIAL FORM
+    u'\ufbb0'   #  0xFC -> ARABIC LETTER YEH BARREE WITH HAMZA ABOVE ISOLATED FORM
+    u'\ufbae'   #  0xFD -> ARABIC LETTER YEH BARREE ISOLATED FORM
+    u'\ufe7c'   #  0xFE -> ARABIC SHADDA ISOLATED FORM
+    u'\ufe7d'   #  0xFF -> ARABIC SHADDA MEDIAL FORM
+)
+
+### Encoding table
+encoding_table=codecs.charmap_build(decoding_table)

Added: vendor/Python/current/Lib/encodings/cp1026.py
===================================================================
--- vendor/Python/current/Lib/encodings/cp1026.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/cp1026.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,307 @@
+""" Python Character Mapping Codec cp1026 generated from 'MAPPINGS/VENDORS/MICSFT/EBCDIC/CP1026.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_table)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_table)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='cp1026',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x00 -> NULL
+    u'\x01'     #  0x01 -> START OF HEADING
+    u'\x02'     #  0x02 -> START OF TEXT
+    u'\x03'     #  0x03 -> END OF TEXT
+    u'\x9c'     #  0x04 -> CONTROL
+    u'\t'       #  0x05 -> HORIZONTAL TABULATION
+    u'\x86'     #  0x06 -> CONTROL
+    u'\x7f'     #  0x07 -> DELETE
+    u'\x97'     #  0x08 -> CONTROL
+    u'\x8d'     #  0x09 -> CONTROL
+    u'\x8e'     #  0x0A -> CONTROL
+    u'\x0b'     #  0x0B -> VERTICAL TABULATION
+    u'\x0c'     #  0x0C -> FORM FEED
+    u'\r'       #  0x0D -> CARRIAGE RETURN
+    u'\x0e'     #  0x0E -> SHIFT OUT
+    u'\x0f'     #  0x0F -> SHIFT IN
+    u'\x10'     #  0x10 -> DATA LINK ESCAPE
+    u'\x11'     #  0x11 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x12 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x13 -> DEVICE CONTROL THREE
+    u'\x9d'     #  0x14 -> CONTROL
+    u'\x85'     #  0x15 -> CONTROL
+    u'\x08'     #  0x16 -> BACKSPACE
+    u'\x87'     #  0x17 -> CONTROL
+    u'\x18'     #  0x18 -> CANCEL
+    u'\x19'     #  0x19 -> END OF MEDIUM
+    u'\x92'     #  0x1A -> CONTROL
+    u'\x8f'     #  0x1B -> CONTROL
+    u'\x1c'     #  0x1C -> FILE SEPARATOR
+    u'\x1d'     #  0x1D -> GROUP SEPARATOR
+    u'\x1e'     #  0x1E -> RECORD SEPARATOR
+    u'\x1f'     #  0x1F -> UNIT SEPARATOR
+    u'\x80'     #  0x20 -> CONTROL
+    u'\x81'     #  0x21 -> CONTROL
+    u'\x82'     #  0x22 -> CONTROL
+    u'\x83'     #  0x23 -> CONTROL
+    u'\x84'     #  0x24 -> CONTROL
+    u'\n'       #  0x25 -> LINE FEED
+    u'\x17'     #  0x26 -> END OF TRANSMISSION BLOCK
+    u'\x1b'     #  0x27 -> ESCAPE
+    u'\x88'     #  0x28 -> CONTROL
+    u'\x89'     #  0x29 -> CONTROL
+    u'\x8a'     #  0x2A -> CONTROL
+    u'\x8b'     #  0x2B -> CONTROL
+    u'\x8c'     #  0x2C -> CONTROL
+    u'\x05'     #  0x2D -> ENQUIRY
+    u'\x06'     #  0x2E -> ACKNOWLEDGE
+    u'\x07'     #  0x2F -> BELL
+    u'\x90'     #  0x30 -> CONTROL
+    u'\x91'     #  0x31 -> CONTROL
+    u'\x16'     #  0x32 -> SYNCHRONOUS IDLE
+    u'\x93'     #  0x33 -> CONTROL
+    u'\x94'     #  0x34 -> CONTROL
+    u'\x95'     #  0x35 -> CONTROL
+    u'\x96'     #  0x36 -> CONTROL
+    u'\x04'     #  0x37 -> END OF TRANSMISSION
+    u'\x98'     #  0x38 -> CONTROL
+    u'\x99'     #  0x39 -> CONTROL
+    u'\x9a'     #  0x3A -> CONTROL
+    u'\x9b'     #  0x3B -> CONTROL
+    u'\x14'     #  0x3C -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x3D -> NEGATIVE ACKNOWLEDGE
+    u'\x9e'     #  0x3E -> CONTROL
+    u'\x1a'     #  0x3F -> SUBSTITUTE
+    u' '        #  0x40 -> SPACE
+    u'\xa0'     #  0x41 -> NO-BREAK SPACE
+    u'\xe2'     #  0x42 -> LATIN SMALL LETTER A WITH CIRCUMFLEX
+    u'\xe4'     #  0x43 -> LATIN SMALL LETTER A WITH DIAERESIS
+    u'\xe0'     #  0x44 -> LATIN SMALL LETTER A WITH GRAVE
+    u'\xe1'     #  0x45 -> LATIN SMALL LETTER A WITH ACUTE
+    u'\xe3'     #  0x46 -> LATIN SMALL LETTER A WITH TILDE
+    u'\xe5'     #  0x47 -> LATIN SMALL LETTER A WITH RING ABOVE
+    u'{'        #  0x48 -> LEFT CURLY BRACKET
+    u'\xf1'     #  0x49 -> LATIN SMALL LETTER N WITH TILDE
+    u'\xc7'     #  0x4A -> LATIN CAPITAL LETTER C WITH CEDILLA
+    u'.'        #  0x4B -> FULL STOP
+    u'<'        #  0x4C -> LESS-THAN SIGN
+    u'('        #  0x4D -> LEFT PARENTHESIS
+    u'+'        #  0x4E -> PLUS SIGN
+    u'!'        #  0x4F -> EXCLAMATION MARK
+    u'&'        #  0x50 -> AMPERSAND
+    u'\xe9'     #  0x51 -> LATIN SMALL LETTER E WITH ACUTE
+    u'\xea'     #  0x52 -> LATIN SMALL LETTER E WITH CIRCUMFLEX
+    u'\xeb'     #  0x53 -> LATIN SMALL LETTER E WITH DIAERESIS
+    u'\xe8'     #  0x54 -> LATIN SMALL LETTER E WITH GRAVE
+    u'\xed'     #  0x55 -> LATIN SMALL LETTER I WITH ACUTE
+    u'\xee'     #  0x56 -> LATIN SMALL LETTER I WITH CIRCUMFLEX
+    u'\xef'     #  0x57 -> LATIN SMALL LETTER I WITH DIAERESIS
+    u'\xec'     #  0x58 -> LATIN SMALL LETTER I WITH GRAVE
+    u'\xdf'     #  0x59 -> LATIN SMALL LETTER SHARP S (GERMAN)
+    u'\u011e'   #  0x5A -> LATIN CAPITAL LETTER G WITH BREVE
+    u'\u0130'   #  0x5B -> LATIN CAPITAL LETTER I WITH DOT ABOVE
+    u'*'        #  0x5C -> ASTERISK
+    u')'        #  0x5D -> RIGHT PARENTHESIS
+    u';'        #  0x5E -> SEMICOLON
+    u'^'        #  0x5F -> CIRCUMFLEX ACCENT
+    u'-'        #  0x60 -> HYPHEN-MINUS
+    u'/'        #  0x61 -> SOLIDUS
+    u'\xc2'     #  0x62 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+    u'\xc4'     #  0x63 -> LATIN CAPITAL LETTER A WITH DIAERESIS
+    u'\xc0'     #  0x64 -> LATIN CAPITAL LETTER A WITH GRAVE
+    u'\xc1'     #  0x65 -> LATIN CAPITAL LETTER A WITH ACUTE
+    u'\xc3'     #  0x66 -> LATIN CAPITAL LETTER A WITH TILDE
+    u'\xc5'     #  0x67 -> LATIN CAPITAL LETTER A WITH RING ABOVE
+    u'['        #  0x68 -> LEFT SQUARE BRACKET
+    u'\xd1'     #  0x69 -> LATIN CAPITAL LETTER N WITH TILDE
+    u'\u015f'   #  0x6A -> LATIN SMALL LETTER S WITH CEDILLA
+    u','        #  0x6B -> COMMA
+    u'%'        #  0x6C -> PERCENT SIGN
+    u'_'        #  0x6D -> LOW LINE
+    u'>'        #  0x6E -> GREATER-THAN SIGN
+    u'?'        #  0x6F -> QUESTION MARK
+    u'\xf8'     #  0x70 -> LATIN SMALL LETTER O WITH STROKE
+    u'\xc9'     #  0x71 -> LATIN CAPITAL LETTER E WITH ACUTE
+    u'\xca'     #  0x72 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+    u'\xcb'     #  0x73 -> LATIN CAPITAL LETTER E WITH DIAERESIS
+    u'\xc8'     #  0x74 -> LATIN CAPITAL LETTER E WITH GRAVE
+    u'\xcd'     #  0x75 -> LATIN CAPITAL LETTER I WITH ACUTE
+    u'\xce'     #  0x76 -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+    u'\xcf'     #  0x77 -> LATIN CAPITAL LETTER I WITH DIAERESIS
+    u'\xcc'     #  0x78 -> LATIN CAPITAL LETTER I WITH GRAVE
+    u'\u0131'   #  0x79 -> LATIN SMALL LETTER DOTLESS I
+    u':'        #  0x7A -> COLON
+    u'\xd6'     #  0x7B -> LATIN CAPITAL LETTER O WITH DIAERESIS
+    u'\u015e'   #  0x7C -> LATIN CAPITAL LETTER S WITH CEDILLA
+    u"'"        #  0x7D -> APOSTROPHE
+    u'='        #  0x7E -> EQUALS SIGN
+    u'\xdc'     #  0x7F -> LATIN CAPITAL LETTER U WITH DIAERESIS
+    u'\xd8'     #  0x80 -> LATIN CAPITAL LETTER O WITH STROKE
+    u'a'        #  0x81 -> LATIN SMALL LETTER A
+    u'b'        #  0x82 -> LATIN SMALL LETTER B
+    u'c'        #  0x83 -> LATIN SMALL LETTER C
+    u'd'        #  0x84 -> LATIN SMALL LETTER D
+    u'e'        #  0x85 -> LATIN SMALL LETTER E
+    u'f'        #  0x86 -> LATIN SMALL LETTER F
+    u'g'        #  0x87 -> LATIN SMALL LETTER G
+    u'h'        #  0x88 -> LATIN SMALL LETTER H
+    u'i'        #  0x89 -> LATIN SMALL LETTER I
+    u'\xab'     #  0x8A -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xbb'     #  0x8B -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'}'        #  0x8C -> RIGHT CURLY BRACKET
+    u'`'        #  0x8D -> GRAVE ACCENT
+    u'\xa6'     #  0x8E -> BROKEN BAR
+    u'\xb1'     #  0x8F -> PLUS-MINUS SIGN
+    u'\xb0'     #  0x90 -> DEGREE SIGN
+    u'j'        #  0x91 -> LATIN SMALL LETTER J
+    u'k'        #  0x92 -> LATIN SMALL LETTER K
+    u'l'        #  0x93 -> LATIN SMALL LETTER L
+    u'm'        #  0x94 -> LATIN SMALL LETTER M
+    u'n'        #  0x95 -> LATIN SMALL LETTER N
+    u'o'        #  0x96 -> LATIN SMALL LETTER O
+    u'p'        #  0x97 -> LATIN SMALL LETTER P
+    u'q'        #  0x98 -> LATIN SMALL LETTER Q
+    u'r'        #  0x99 -> LATIN SMALL LETTER R
+    u'\xaa'     #  0x9A -> FEMININE ORDINAL INDICATOR
+    u'\xba'     #  0x9B -> MASCULINE ORDINAL INDICATOR
+    u'\xe6'     #  0x9C -> LATIN SMALL LIGATURE AE
+    u'\xb8'     #  0x9D -> CEDILLA
+    u'\xc6'     #  0x9E -> LATIN CAPITAL LIGATURE AE
+    u'\xa4'     #  0x9F -> CURRENCY SIGN
+    u'\xb5'     #  0xA0 -> MICRO SIGN
+    u'\xf6'     #  0xA1 -> LATIN SMALL LETTER O WITH DIAERESIS
+    u's'        #  0xA2 -> LATIN SMALL LETTER S
+    u't'        #  0xA3 -> LATIN SMALL LETTER T
+    u'u'        #  0xA4 -> LATIN SMALL LETTER U
+    u'v'        #  0xA5 -> LATIN SMALL LETTER V
+    u'w'        #  0xA6 -> LATIN SMALL LETTER W
+    u'x'        #  0xA7 -> LATIN SMALL LETTER X
+    u'y'        #  0xA8 -> LATIN SMALL LETTER Y
+    u'z'        #  0xA9 -> LATIN SMALL LETTER Z
+    u'\xa1'     #  0xAA -> INVERTED EXCLAMATION MARK
+    u'\xbf'     #  0xAB -> INVERTED QUESTION MARK
+    u']'        #  0xAC -> RIGHT SQUARE BRACKET
+    u'$'        #  0xAD -> DOLLAR SIGN
+    u'@'        #  0xAE -> COMMERCIAL AT
+    u'\xae'     #  0xAF -> REGISTERED SIGN
+    u'\xa2'     #  0xB0 -> CENT SIGN
+    u'\xa3'     #  0xB1 -> POUND SIGN
+    u'\xa5'     #  0xB2 -> YEN SIGN
+    u'\xb7'     #  0xB3 -> MIDDLE DOT
+    u'\xa9'     #  0xB4 -> COPYRIGHT SIGN
+    u'\xa7'     #  0xB5 -> SECTION SIGN
+    u'\xb6'     #  0xB6 -> PILCROW SIGN
+    u'\xbc'     #  0xB7 -> VULGAR FRACTION ONE QUARTER
+    u'\xbd'     #  0xB8 -> VULGAR FRACTION ONE HALF
+    u'\xbe'     #  0xB9 -> VULGAR FRACTION THREE QUARTERS
+    u'\xac'     #  0xBA -> NOT SIGN
+    u'|'        #  0xBB -> VERTICAL LINE
+    u'\xaf'     #  0xBC -> MACRON
+    u'\xa8'     #  0xBD -> DIAERESIS
+    u'\xb4'     #  0xBE -> ACUTE ACCENT
+    u'\xd7'     #  0xBF -> MULTIPLICATION SIGN
+    u'\xe7'     #  0xC0 -> LATIN SMALL LETTER C WITH CEDILLA
+    u'A'        #  0xC1 -> LATIN CAPITAL LETTER A
+    u'B'        #  0xC2 -> LATIN CAPITAL LETTER B
+    u'C'        #  0xC3 -> LATIN CAPITAL LETTER C
+    u'D'        #  0xC4 -> LATIN CAPITAL LETTER D
+    u'E'        #  0xC5 -> LATIN CAPITAL LETTER E
+    u'F'        #  0xC6 -> LATIN CAPITAL LETTER F
+    u'G'        #  0xC7 -> LATIN CAPITAL LETTER G
+    u'H'        #  0xC8 -> LATIN CAPITAL LETTER H
+    u'I'        #  0xC9 -> LATIN CAPITAL LETTER I
+    u'\xad'     #  0xCA -> SOFT HYPHEN
+    u'\xf4'     #  0xCB -> LATIN SMALL LETTER O WITH CIRCUMFLEX
+    u'~'        #  0xCC -> TILDE
+    u'\xf2'     #  0xCD -> LATIN SMALL LETTER O WITH GRAVE
+    u'\xf3'     #  0xCE -> LATIN SMALL LETTER O WITH ACUTE
+    u'\xf5'     #  0xCF -> LATIN SMALL LETTER O WITH TILDE
+    u'\u011f'   #  0xD0 -> LATIN SMALL LETTER G WITH BREVE
+    u'J'        #  0xD1 -> LATIN CAPITAL LETTER J
+    u'K'        #  0xD2 -> LATIN CAPITAL LETTER K
+    u'L'        #  0xD3 -> LATIN CAPITAL LETTER L
+    u'M'        #  0xD4 -> LATIN CAPITAL LETTER M
+    u'N'        #  0xD5 -> LATIN CAPITAL LETTER N
+    u'O'        #  0xD6 -> LATIN CAPITAL LETTER O
+    u'P'        #  0xD7 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0xD8 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0xD9 -> LATIN CAPITAL LETTER R
+    u'\xb9'     #  0xDA -> SUPERSCRIPT ONE
+    u'\xfb'     #  0xDB -> LATIN SMALL LETTER U WITH CIRCUMFLEX
+    u'\\'       #  0xDC -> REVERSE SOLIDUS
+    u'\xf9'     #  0xDD -> LATIN SMALL LETTER U WITH GRAVE
+    u'\xfa'     #  0xDE -> LATIN SMALL LETTER U WITH ACUTE
+    u'\xff'     #  0xDF -> LATIN SMALL LETTER Y WITH DIAERESIS
+    u'\xfc'     #  0xE0 -> LATIN SMALL LETTER U WITH DIAERESIS
+    u'\xf7'     #  0xE1 -> DIVISION SIGN
+    u'S'        #  0xE2 -> LATIN CAPITAL LETTER S
+    u'T'        #  0xE3 -> LATIN CAPITAL LETTER T
+    u'U'        #  0xE4 -> LATIN CAPITAL LETTER U
+    u'V'        #  0xE5 -> LATIN CAPITAL LETTER V
+    u'W'        #  0xE6 -> LATIN CAPITAL LETTER W
+    u'X'        #  0xE7 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0xE8 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0xE9 -> LATIN CAPITAL LETTER Z
+    u'\xb2'     #  0xEA -> SUPERSCRIPT TWO
+    u'\xd4'     #  0xEB -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+    u'#'        #  0xEC -> NUMBER SIGN
+    u'\xd2'     #  0xED -> LATIN CAPITAL LETTER O WITH GRAVE
+    u'\xd3'     #  0xEE -> LATIN CAPITAL LETTER O WITH ACUTE
+    u'\xd5'     #  0xEF -> LATIN CAPITAL LETTER O WITH TILDE
+    u'0'        #  0xF0 -> DIGIT ZERO
+    u'1'        #  0xF1 -> DIGIT ONE
+    u'2'        #  0xF2 -> DIGIT TWO
+    u'3'        #  0xF3 -> DIGIT THREE
+    u'4'        #  0xF4 -> DIGIT FOUR
+    u'5'        #  0xF5 -> DIGIT FIVE
+    u'6'        #  0xF6 -> DIGIT SIX
+    u'7'        #  0xF7 -> DIGIT SEVEN
+    u'8'        #  0xF8 -> DIGIT EIGHT
+    u'9'        #  0xF9 -> DIGIT NINE
+    u'\xb3'     #  0xFA -> SUPERSCRIPT THREE
+    u'\xdb'     #  0xFB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+    u'"'        #  0xFC -> QUOTATION MARK
+    u'\xd9'     #  0xFD -> LATIN CAPITAL LETTER U WITH GRAVE
+    u'\xda'     #  0xFE -> LATIN CAPITAL LETTER U WITH ACUTE
+    u'\x9f'     #  0xFF -> CONTROL
+)
+
+### Encoding table
+encoding_table=codecs.charmap_build(decoding_table)

Added: vendor/Python/current/Lib/encodings/cp1140.py
===================================================================
--- vendor/Python/current/Lib/encodings/cp1140.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/cp1140.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,307 @@
+""" Python Character Mapping Codec cp1140 generated from 'python-mappings/CP1140.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_table)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_table)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='cp1140',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x00 -> NULL
+    u'\x01'     #  0x01 -> START OF HEADING
+    u'\x02'     #  0x02 -> START OF TEXT
+    u'\x03'     #  0x03 -> END OF TEXT
+    u'\x9c'     #  0x04 -> CONTROL
+    u'\t'       #  0x05 -> HORIZONTAL TABULATION
+    u'\x86'     #  0x06 -> CONTROL
+    u'\x7f'     #  0x07 -> DELETE
+    u'\x97'     #  0x08 -> CONTROL
+    u'\x8d'     #  0x09 -> CONTROL
+    u'\x8e'     #  0x0A -> CONTROL
+    u'\x0b'     #  0x0B -> VERTICAL TABULATION
+    u'\x0c'     #  0x0C -> FORM FEED
+    u'\r'       #  0x0D -> CARRIAGE RETURN
+    u'\x0e'     #  0x0E -> SHIFT OUT
+    u'\x0f'     #  0x0F -> SHIFT IN
+    u'\x10'     #  0x10 -> DATA LINK ESCAPE
+    u'\x11'     #  0x11 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x12 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x13 -> DEVICE CONTROL THREE
+    u'\x9d'     #  0x14 -> CONTROL
+    u'\x85'     #  0x15 -> CONTROL
+    u'\x08'     #  0x16 -> BACKSPACE
+    u'\x87'     #  0x17 -> CONTROL
+    u'\x18'     #  0x18 -> CANCEL
+    u'\x19'     #  0x19 -> END OF MEDIUM
+    u'\x92'     #  0x1A -> CONTROL
+    u'\x8f'     #  0x1B -> CONTROL
+    u'\x1c'     #  0x1C -> FILE SEPARATOR
+    u'\x1d'     #  0x1D -> GROUP SEPARATOR
+    u'\x1e'     #  0x1E -> RECORD SEPARATOR
+    u'\x1f'     #  0x1F -> UNIT SEPARATOR
+    u'\x80'     #  0x20 -> CONTROL
+    u'\x81'     #  0x21 -> CONTROL
+    u'\x82'     #  0x22 -> CONTROL
+    u'\x83'     #  0x23 -> CONTROL
+    u'\x84'     #  0x24 -> CONTROL
+    u'\n'       #  0x25 -> LINE FEED
+    u'\x17'     #  0x26 -> END OF TRANSMISSION BLOCK
+    u'\x1b'     #  0x27 -> ESCAPE
+    u'\x88'     #  0x28 -> CONTROL
+    u'\x89'     #  0x29 -> CONTROL
+    u'\x8a'     #  0x2A -> CONTROL
+    u'\x8b'     #  0x2B -> CONTROL
+    u'\x8c'     #  0x2C -> CONTROL
+    u'\x05'     #  0x2D -> ENQUIRY
+    u'\x06'     #  0x2E -> ACKNOWLEDGE
+    u'\x07'     #  0x2F -> BELL
+    u'\x90'     #  0x30 -> CONTROL
+    u'\x91'     #  0x31 -> CONTROL
+    u'\x16'     #  0x32 -> SYNCHRONOUS IDLE
+    u'\x93'     #  0x33 -> CONTROL
+    u'\x94'     #  0x34 -> CONTROL
+    u'\x95'     #  0x35 -> CONTROL
+    u'\x96'     #  0x36 -> CONTROL
+    u'\x04'     #  0x37 -> END OF TRANSMISSION
+    u'\x98'     #  0x38 -> CONTROL
+    u'\x99'     #  0x39 -> CONTROL
+    u'\x9a'     #  0x3A -> CONTROL
+    u'\x9b'     #  0x3B -> CONTROL
+    u'\x14'     #  0x3C -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x3D -> NEGATIVE ACKNOWLEDGE
+    u'\x9e'     #  0x3E -> CONTROL
+    u'\x1a'     #  0x3F -> SUBSTITUTE
+    u' '        #  0x40 -> SPACE
+    u'\xa0'     #  0x41 -> NO-BREAK SPACE
+    u'\xe2'     #  0x42 -> LATIN SMALL LETTER A WITH CIRCUMFLEX
+    u'\xe4'     #  0x43 -> LATIN SMALL LETTER A WITH DIAERESIS
+    u'\xe0'     #  0x44 -> LATIN SMALL LETTER A WITH GRAVE
+    u'\xe1'     #  0x45 -> LATIN SMALL LETTER A WITH ACUTE
+    u'\xe3'     #  0x46 -> LATIN SMALL LETTER A WITH TILDE
+    u'\xe5'     #  0x47 -> LATIN SMALL LETTER A WITH RING ABOVE
+    u'\xe7'     #  0x48 -> LATIN SMALL LETTER C WITH CEDILLA
+    u'\xf1'     #  0x49 -> LATIN SMALL LETTER N WITH TILDE
+    u'\xa2'     #  0x4A -> CENT SIGN
+    u'.'        #  0x4B -> FULL STOP
+    u'<'        #  0x4C -> LESS-THAN SIGN
+    u'('        #  0x4D -> LEFT PARENTHESIS
+    u'+'        #  0x4E -> PLUS SIGN
+    u'|'        #  0x4F -> VERTICAL LINE
+    u'&'        #  0x50 -> AMPERSAND
+    u'\xe9'     #  0x51 -> LATIN SMALL LETTER E WITH ACUTE
+    u'\xea'     #  0x52 -> LATIN SMALL LETTER E WITH CIRCUMFLEX
+    u'\xeb'     #  0x53 -> LATIN SMALL LETTER E WITH DIAERESIS
+    u'\xe8'     #  0x54 -> LATIN SMALL LETTER E WITH GRAVE
+    u'\xed'     #  0x55 -> LATIN SMALL LETTER I WITH ACUTE
+    u'\xee'     #  0x56 -> LATIN SMALL LETTER I WITH CIRCUMFLEX
+    u'\xef'     #  0x57 -> LATIN SMALL LETTER I WITH DIAERESIS
+    u'\xec'     #  0x58 -> LATIN SMALL LETTER I WITH GRAVE
+    u'\xdf'     #  0x59 -> LATIN SMALL LETTER SHARP S (GERMAN)
+    u'!'        #  0x5A -> EXCLAMATION MARK
+    u'$'        #  0x5B -> DOLLAR SIGN
+    u'*'        #  0x5C -> ASTERISK
+    u')'        #  0x5D -> RIGHT PARENTHESIS
+    u';'        #  0x5E -> SEMICOLON
+    u'\xac'     #  0x5F -> NOT SIGN
+    u'-'        #  0x60 -> HYPHEN-MINUS
+    u'/'        #  0x61 -> SOLIDUS
+    u'\xc2'     #  0x62 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+    u'\xc4'     #  0x63 -> LATIN CAPITAL LETTER A WITH DIAERESIS
+    u'\xc0'     #  0x64 -> LATIN CAPITAL LETTER A WITH GRAVE
+    u'\xc1'     #  0x65 -> LATIN CAPITAL LETTER A WITH ACUTE
+    u'\xc3'     #  0x66 -> LATIN CAPITAL LETTER A WITH TILDE
+    u'\xc5'     #  0x67 -> LATIN CAPITAL LETTER A WITH RING ABOVE
+    u'\xc7'     #  0x68 -> LATIN CAPITAL LETTER C WITH CEDILLA
+    u'\xd1'     #  0x69 -> LATIN CAPITAL LETTER N WITH TILDE
+    u'\xa6'     #  0x6A -> BROKEN BAR
+    u','        #  0x6B -> COMMA
+    u'%'        #  0x6C -> PERCENT SIGN
+    u'_'        #  0x6D -> LOW LINE
+    u'>'        #  0x6E -> GREATER-THAN SIGN
+    u'?'        #  0x6F -> QUESTION MARK
+    u'\xf8'     #  0x70 -> LATIN SMALL LETTER O WITH STROKE
+    u'\xc9'     #  0x71 -> LATIN CAPITAL LETTER E WITH ACUTE
+    u'\xca'     #  0x72 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+    u'\xcb'     #  0x73 -> LATIN CAPITAL LETTER E WITH DIAERESIS
+    u'\xc8'     #  0x74 -> LATIN CAPITAL LETTER E WITH GRAVE
+    u'\xcd'     #  0x75 -> LATIN CAPITAL LETTER I WITH ACUTE
+    u'\xce'     #  0x76 -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+    u'\xcf'     #  0x77 -> LATIN CAPITAL LETTER I WITH DIAERESIS
+    u'\xcc'     #  0x78 -> LATIN CAPITAL LETTER I WITH GRAVE
+    u'`'        #  0x79 -> GRAVE ACCENT
+    u':'        #  0x7A -> COLON
+    u'#'        #  0x7B -> NUMBER SIGN
+    u'@'        #  0x7C -> COMMERCIAL AT
+    u"'"        #  0x7D -> APOSTROPHE
+    u'='        #  0x7E -> EQUALS SIGN
+    u'"'        #  0x7F -> QUOTATION MARK
+    u'\xd8'     #  0x80 -> LATIN CAPITAL LETTER O WITH STROKE
+    u'a'        #  0x81 -> LATIN SMALL LETTER A
+    u'b'        #  0x82 -> LATIN SMALL LETTER B
+    u'c'        #  0x83 -> LATIN SMALL LETTER C
+    u'd'        #  0x84 -> LATIN SMALL LETTER D
+    u'e'        #  0x85 -> LATIN SMALL LETTER E
+    u'f'        #  0x86 -> LATIN SMALL LETTER F
+    u'g'        #  0x87 -> LATIN SMALL LETTER G
+    u'h'        #  0x88 -> LATIN SMALL LETTER H
+    u'i'        #  0x89 -> LATIN SMALL LETTER I
+    u'\xab'     #  0x8A -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xbb'     #  0x8B -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xf0'     #  0x8C -> LATIN SMALL LETTER ETH (ICELANDIC)
+    u'\xfd'     #  0x8D -> LATIN SMALL LETTER Y WITH ACUTE
+    u'\xfe'     #  0x8E -> LATIN SMALL LETTER THORN (ICELANDIC)
+    u'\xb1'     #  0x8F -> PLUS-MINUS SIGN
+    u'\xb0'     #  0x90 -> DEGREE SIGN
+    u'j'        #  0x91 -> LATIN SMALL LETTER J
+    u'k'        #  0x92 -> LATIN SMALL LETTER K
+    u'l'        #  0x93 -> LATIN SMALL LETTER L
+    u'm'        #  0x94 -> LATIN SMALL LETTER M
+    u'n'        #  0x95 -> LATIN SMALL LETTER N
+    u'o'        #  0x96 -> LATIN SMALL LETTER O
+    u'p'        #  0x97 -> LATIN SMALL LETTER P
+    u'q'        #  0x98 -> LATIN SMALL LETTER Q
+    u'r'        #  0x99 -> LATIN SMALL LETTER R
+    u'\xaa'     #  0x9A -> FEMININE ORDINAL INDICATOR
+    u'\xba'     #  0x9B -> MASCULINE ORDINAL INDICATOR
+    u'\xe6'     #  0x9C -> LATIN SMALL LIGATURE AE
+    u'\xb8'     #  0x9D -> CEDILLA
+    u'\xc6'     #  0x9E -> LATIN CAPITAL LIGATURE AE
+    u'\u20ac'   #  0x9F -> EURO SIGN
+    u'\xb5'     #  0xA0 -> MICRO SIGN
+    u'~'        #  0xA1 -> TILDE
+    u's'        #  0xA2 -> LATIN SMALL LETTER S
+    u't'        #  0xA3 -> LATIN SMALL LETTER T
+    u'u'        #  0xA4 -> LATIN SMALL LETTER U
+    u'v'        #  0xA5 -> LATIN SMALL LETTER V
+    u'w'        #  0xA6 -> LATIN SMALL LETTER W
+    u'x'        #  0xA7 -> LATIN SMALL LETTER X
+    u'y'        #  0xA8 -> LATIN SMALL LETTER Y
+    u'z'        #  0xA9 -> LATIN SMALL LETTER Z
+    u'\xa1'     #  0xAA -> INVERTED EXCLAMATION MARK
+    u'\xbf'     #  0xAB -> INVERTED QUESTION MARK
+    u'\xd0'     #  0xAC -> LATIN CAPITAL LETTER ETH (ICELANDIC)
+    u'\xdd'     #  0xAD -> LATIN CAPITAL LETTER Y WITH ACUTE
+    u'\xde'     #  0xAE -> LATIN CAPITAL LETTER THORN (ICELANDIC)
+    u'\xae'     #  0xAF -> REGISTERED SIGN
+    u'^'        #  0xB0 -> CIRCUMFLEX ACCENT
+    u'\xa3'     #  0xB1 -> POUND SIGN
+    u'\xa5'     #  0xB2 -> YEN SIGN
+    u'\xb7'     #  0xB3 -> MIDDLE DOT
+    u'\xa9'     #  0xB4 -> COPYRIGHT SIGN
+    u'\xa7'     #  0xB5 -> SECTION SIGN
+    u'\xb6'     #  0xB6 -> PILCROW SIGN
+    u'\xbc'     #  0xB7 -> VULGAR FRACTION ONE QUARTER
+    u'\xbd'     #  0xB8 -> VULGAR FRACTION ONE HALF
+    u'\xbe'     #  0xB9 -> VULGAR FRACTION THREE QUARTERS
+    u'['        #  0xBA -> LEFT SQUARE BRACKET
+    u']'        #  0xBB -> RIGHT SQUARE BRACKET
+    u'\xaf'     #  0xBC -> MACRON
+    u'\xa8'     #  0xBD -> DIAERESIS
+    u'\xb4'     #  0xBE -> ACUTE ACCENT
+    u'\xd7'     #  0xBF -> MULTIPLICATION SIGN
+    u'{'        #  0xC0 -> LEFT CURLY BRACKET
+    u'A'        #  0xC1 -> LATIN CAPITAL LETTER A
+    u'B'        #  0xC2 -> LATIN CAPITAL LETTER B
+    u'C'        #  0xC3 -> LATIN CAPITAL LETTER C
+    u'D'        #  0xC4 -> LATIN CAPITAL LETTER D
+    u'E'        #  0xC5 -> LATIN CAPITAL LETTER E
+    u'F'        #  0xC6 -> LATIN CAPITAL LETTER F
+    u'G'        #  0xC7 -> LATIN CAPITAL LETTER G
+    u'H'        #  0xC8 -> LATIN CAPITAL LETTER H
+    u'I'        #  0xC9 -> LATIN CAPITAL LETTER I
+    u'\xad'     #  0xCA -> SOFT HYPHEN
+    u'\xf4'     #  0xCB -> LATIN SMALL LETTER O WITH CIRCUMFLEX
+    u'\xf6'     #  0xCC -> LATIN SMALL LETTER O WITH DIAERESIS
+    u'\xf2'     #  0xCD -> LATIN SMALL LETTER O WITH GRAVE
+    u'\xf3'     #  0xCE -> LATIN SMALL LETTER O WITH ACUTE
+    u'\xf5'     #  0xCF -> LATIN SMALL LETTER O WITH TILDE
+    u'}'        #  0xD0 -> RIGHT CURLY BRACKET
+    u'J'        #  0xD1 -> LATIN CAPITAL LETTER J
+    u'K'        #  0xD2 -> LATIN CAPITAL LETTER K
+    u'L'        #  0xD3 -> LATIN CAPITAL LETTER L
+    u'M'        #  0xD4 -> LATIN CAPITAL LETTER M
+    u'N'        #  0xD5 -> LATIN CAPITAL LETTER N
+    u'O'        #  0xD6 -> LATIN CAPITAL LETTER O
+    u'P'        #  0xD7 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0xD8 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0xD9 -> LATIN CAPITAL LETTER R
+    u'\xb9'     #  0xDA -> SUPERSCRIPT ONE
+    u'\xfb'     #  0xDB -> LATIN SMALL LETTER U WITH CIRCUMFLEX
+    u'\xfc'     #  0xDC -> LATIN SMALL LETTER U WITH DIAERESIS
+    u'\xf9'     #  0xDD -> LATIN SMALL LETTER U WITH GRAVE
+    u'\xfa'     #  0xDE -> LATIN SMALL LETTER U WITH ACUTE
+    u'\xff'     #  0xDF -> LATIN SMALL LETTER Y WITH DIAERESIS
+    u'\\'       #  0xE0 -> REVERSE SOLIDUS
+    u'\xf7'     #  0xE1 -> DIVISION SIGN
+    u'S'        #  0xE2 -> LATIN CAPITAL LETTER S
+    u'T'        #  0xE3 -> LATIN CAPITAL LETTER T
+    u'U'        #  0xE4 -> LATIN CAPITAL LETTER U
+    u'V'        #  0xE5 -> LATIN CAPITAL LETTER V
+    u'W'        #  0xE6 -> LATIN CAPITAL LETTER W
+    u'X'        #  0xE7 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0xE8 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0xE9 -> LATIN CAPITAL LETTER Z
+    u'\xb2'     #  0xEA -> SUPERSCRIPT TWO
+    u'\xd4'     #  0xEB -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+    u'\xd6'     #  0xEC -> LATIN CAPITAL LETTER O WITH DIAERESIS
+    u'\xd2'     #  0xED -> LATIN CAPITAL LETTER O WITH GRAVE
+    u'\xd3'     #  0xEE -> LATIN CAPITAL LETTER O WITH ACUTE
+    u'\xd5'     #  0xEF -> LATIN CAPITAL LETTER O WITH TILDE
+    u'0'        #  0xF0 -> DIGIT ZERO
+    u'1'        #  0xF1 -> DIGIT ONE
+    u'2'        #  0xF2 -> DIGIT TWO
+    u'3'        #  0xF3 -> DIGIT THREE
+    u'4'        #  0xF4 -> DIGIT FOUR
+    u'5'        #  0xF5 -> DIGIT FIVE
+    u'6'        #  0xF6 -> DIGIT SIX
+    u'7'        #  0xF7 -> DIGIT SEVEN
+    u'8'        #  0xF8 -> DIGIT EIGHT
+    u'9'        #  0xF9 -> DIGIT NINE
+    u'\xb3'     #  0xFA -> SUPERSCRIPT THREE
+    u'\xdb'     #  0xFB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+    u'\xdc'     #  0xFC -> LATIN CAPITAL LETTER U WITH DIAERESIS
+    u'\xd9'     #  0xFD -> LATIN CAPITAL LETTER U WITH GRAVE
+    u'\xda'     #  0xFE -> LATIN CAPITAL LETTER U WITH ACUTE
+    u'\x9f'     #  0xFF -> CONTROL
+)
+
+### Encoding table
+encoding_table=codecs.charmap_build(decoding_table)

Added: vendor/Python/current/Lib/encodings/cp1250.py
===================================================================
--- vendor/Python/current/Lib/encodings/cp1250.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/cp1250.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,307 @@
+""" Python Character Mapping Codec cp1250 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1250.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_table)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_table)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='cp1250',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x00 -> NULL
+    u'\x01'     #  0x01 -> START OF HEADING
+    u'\x02'     #  0x02 -> START OF TEXT
+    u'\x03'     #  0x03 -> END OF TEXT
+    u'\x04'     #  0x04 -> END OF TRANSMISSION
+    u'\x05'     #  0x05 -> ENQUIRY
+    u'\x06'     #  0x06 -> ACKNOWLEDGE
+    u'\x07'     #  0x07 -> BELL
+    u'\x08'     #  0x08 -> BACKSPACE
+    u'\t'       #  0x09 -> HORIZONTAL TABULATION
+    u'\n'       #  0x0A -> LINE FEED
+    u'\x0b'     #  0x0B -> VERTICAL TABULATION
+    u'\x0c'     #  0x0C -> FORM FEED
+    u'\r'       #  0x0D -> CARRIAGE RETURN
+    u'\x0e'     #  0x0E -> SHIFT OUT
+    u'\x0f'     #  0x0F -> SHIFT IN
+    u'\x10'     #  0x10 -> DATA LINK ESCAPE
+    u'\x11'     #  0x11 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x12 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x13 -> DEVICE CONTROL THREE
+    u'\x14'     #  0x14 -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x15 -> NEGATIVE ACKNOWLEDGE
+    u'\x16'     #  0x16 -> SYNCHRONOUS IDLE
+    u'\x17'     #  0x17 -> END OF TRANSMISSION BLOCK
+    u'\x18'     #  0x18 -> CANCEL
+    u'\x19'     #  0x19 -> END OF MEDIUM
+    u'\x1a'     #  0x1A -> SUBSTITUTE
+    u'\x1b'     #  0x1B -> ESCAPE
+    u'\x1c'     #  0x1C -> FILE SEPARATOR
+    u'\x1d'     #  0x1D -> GROUP SEPARATOR
+    u'\x1e'     #  0x1E -> RECORD SEPARATOR
+    u'\x1f'     #  0x1F -> UNIT SEPARATOR
+    u' '        #  0x20 -> SPACE
+    u'!'        #  0x21 -> EXCLAMATION MARK
+    u'"'        #  0x22 -> QUOTATION MARK
+    u'#'        #  0x23 -> NUMBER SIGN
+    u'$'        #  0x24 -> DOLLAR SIGN
+    u'%'        #  0x25 -> PERCENT SIGN
+    u'&'        #  0x26 -> AMPERSAND
+    u"'"        #  0x27 -> APOSTROPHE
+    u'('        #  0x28 -> LEFT PARENTHESIS
+    u')'        #  0x29 -> RIGHT PARENTHESIS
+    u'*'        #  0x2A -> ASTERISK
+    u'+'        #  0x2B -> PLUS SIGN
+    u','        #  0x2C -> COMMA
+    u'-'        #  0x2D -> HYPHEN-MINUS
+    u'.'        #  0x2E -> FULL STOP
+    u'/'        #  0x2F -> SOLIDUS
+    u'0'        #  0x30 -> DIGIT ZERO
+    u'1'        #  0x31 -> DIGIT ONE
+    u'2'        #  0x32 -> DIGIT TWO
+    u'3'        #  0x33 -> DIGIT THREE
+    u'4'        #  0x34 -> DIGIT FOUR
+    u'5'        #  0x35 -> DIGIT FIVE
+    u'6'        #  0x36 -> DIGIT SIX
+    u'7'        #  0x37 -> DIGIT SEVEN
+    u'8'        #  0x38 -> DIGIT EIGHT
+    u'9'        #  0x39 -> DIGIT NINE
+    u':'        #  0x3A -> COLON
+    u';'        #  0x3B -> SEMICOLON
+    u'<'        #  0x3C -> LESS-THAN SIGN
+    u'='        #  0x3D -> EQUALS SIGN
+    u'>'        #  0x3E -> GREATER-THAN SIGN
+    u'?'        #  0x3F -> QUESTION MARK
+    u'@'        #  0x40 -> COMMERCIAL AT
+    u'A'        #  0x41 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x42 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x43 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x44 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x45 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x46 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x47 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x48 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x49 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x4A -> LATIN CAPITAL LETTER J
+    u'K'        #  0x4B -> LATIN CAPITAL LETTER K
+    u'L'        #  0x4C -> LATIN CAPITAL LETTER L
+    u'M'        #  0x4D -> LATIN CAPITAL LETTER M
+    u'N'        #  0x4E -> LATIN CAPITAL LETTER N
+    u'O'        #  0x4F -> LATIN CAPITAL LETTER O
+    u'P'        #  0x50 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x51 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x52 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x53 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x54 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x55 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x56 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x57 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x58 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x59 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x5A -> LATIN CAPITAL LETTER Z
+    u'['        #  0x5B -> LEFT SQUARE BRACKET
+    u'\\'       #  0x5C -> REVERSE SOLIDUS
+    u']'        #  0x5D -> RIGHT SQUARE BRACKET
+    u'^'        #  0x5E -> CIRCUMFLEX ACCENT
+    u'_'        #  0x5F -> LOW LINE
+    u'`'        #  0x60 -> GRAVE ACCENT
+    u'a'        #  0x61 -> LATIN SMALL LETTER A
+    u'b'        #  0x62 -> LATIN SMALL LETTER B
+    u'c'        #  0x63 -> LATIN SMALL LETTER C
+    u'd'        #  0x64 -> LATIN SMALL LETTER D
+    u'e'        #  0x65 -> LATIN SMALL LETTER E
+    u'f'        #  0x66 -> LATIN SMALL LETTER F
+    u'g'        #  0x67 -> LATIN SMALL LETTER G
+    u'h'        #  0x68 -> LATIN SMALL LETTER H
+    u'i'        #  0x69 -> LATIN SMALL LETTER I
+    u'j'        #  0x6A -> LATIN SMALL LETTER J
+    u'k'        #  0x6B -> LATIN SMALL LETTER K
+    u'l'        #  0x6C -> LATIN SMALL LETTER L
+    u'm'        #  0x6D -> LATIN SMALL LETTER M
+    u'n'        #  0x6E -> LATIN SMALL LETTER N
+    u'o'        #  0x6F -> LATIN SMALL LETTER O
+    u'p'        #  0x70 -> LATIN SMALL LETTER P
+    u'q'        #  0x71 -> LATIN SMALL LETTER Q
+    u'r'        #  0x72 -> LATIN SMALL LETTER R
+    u's'        #  0x73 -> LATIN SMALL LETTER S
+    u't'        #  0x74 -> LATIN SMALL LETTER T
+    u'u'        #  0x75 -> LATIN SMALL LETTER U
+    u'v'        #  0x76 -> LATIN SMALL LETTER V
+    u'w'        #  0x77 -> LATIN SMALL LETTER W
+    u'x'        #  0x78 -> LATIN SMALL LETTER X
+    u'y'        #  0x79 -> LATIN SMALL LETTER Y
+    u'z'        #  0x7A -> LATIN SMALL LETTER Z
+    u'{'        #  0x7B -> LEFT CURLY BRACKET
+    u'|'        #  0x7C -> VERTICAL LINE
+    u'}'        #  0x7D -> RIGHT CURLY BRACKET
+    u'~'        #  0x7E -> TILDE
+    u'\x7f'     #  0x7F -> DELETE
+    u'\u20ac'   #  0x80 -> EURO SIGN
+    u'\ufffe'   #  0x81 -> UNDEFINED
+    u'\u201a'   #  0x82 -> SINGLE LOW-9 QUOTATION MARK
+    u'\ufffe'   #  0x83 -> UNDEFINED
+    u'\u201e'   #  0x84 -> DOUBLE LOW-9 QUOTATION MARK
+    u'\u2026'   #  0x85 -> HORIZONTAL ELLIPSIS
+    u'\u2020'   #  0x86 -> DAGGER
+    u'\u2021'   #  0x87 -> DOUBLE DAGGER
+    u'\ufffe'   #  0x88 -> UNDEFINED
+    u'\u2030'   #  0x89 -> PER MILLE SIGN
+    u'\u0160'   #  0x8A -> LATIN CAPITAL LETTER S WITH CARON
+    u'\u2039'   #  0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+    u'\u015a'   #  0x8C -> LATIN CAPITAL LETTER S WITH ACUTE
+    u'\u0164'   #  0x8D -> LATIN CAPITAL LETTER T WITH CARON
+    u'\u017d'   #  0x8E -> LATIN CAPITAL LETTER Z WITH CARON
+    u'\u0179'   #  0x8F -> LATIN CAPITAL LETTER Z WITH ACUTE
+    u'\ufffe'   #  0x90 -> UNDEFINED
+    u'\u2018'   #  0x91 -> LEFT SINGLE QUOTATION MARK
+    u'\u2019'   #  0x92 -> RIGHT SINGLE QUOTATION MARK
+    u'\u201c'   #  0x93 -> LEFT DOUBLE QUOTATION MARK
+    u'\u201d'   #  0x94 -> RIGHT DOUBLE QUOTATION MARK
+    u'\u2022'   #  0x95 -> BULLET
+    u'\u2013'   #  0x96 -> EN DASH
+    u'\u2014'   #  0x97 -> EM DASH
+    u'\ufffe'   #  0x98 -> UNDEFINED
+    u'\u2122'   #  0x99 -> TRADE MARK SIGN
+    u'\u0161'   #  0x9A -> LATIN SMALL LETTER S WITH CARON
+    u'\u203a'   #  0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+    u'\u015b'   #  0x9C -> LATIN SMALL LETTER S WITH ACUTE
+    u'\u0165'   #  0x9D -> LATIN SMALL LETTER T WITH CARON
+    u'\u017e'   #  0x9E -> LATIN SMALL LETTER Z WITH CARON
+    u'\u017a'   #  0x9F -> LATIN SMALL LETTER Z WITH ACUTE
+    u'\xa0'     #  0xA0 -> NO-BREAK SPACE
+    u'\u02c7'   #  0xA1 -> CARON
+    u'\u02d8'   #  0xA2 -> BREVE
+    u'\u0141'   #  0xA3 -> LATIN CAPITAL LETTER L WITH STROKE
+    u'\xa4'     #  0xA4 -> CURRENCY SIGN
+    u'\u0104'   #  0xA5 -> LATIN CAPITAL LETTER A WITH OGONEK
+    u'\xa6'     #  0xA6 -> BROKEN BAR
+    u'\xa7'     #  0xA7 -> SECTION SIGN
+    u'\xa8'     #  0xA8 -> DIAERESIS
+    u'\xa9'     #  0xA9 -> COPYRIGHT SIGN
+    u'\u015e'   #  0xAA -> LATIN CAPITAL LETTER S WITH CEDILLA
+    u'\xab'     #  0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xac'     #  0xAC -> NOT SIGN
+    u'\xad'     #  0xAD -> SOFT HYPHEN
+    u'\xae'     #  0xAE -> REGISTERED SIGN
+    u'\u017b'   #  0xAF -> LATIN CAPITAL LETTER Z WITH DOT ABOVE
+    u'\xb0'     #  0xB0 -> DEGREE SIGN
+    u'\xb1'     #  0xB1 -> PLUS-MINUS SIGN
+    u'\u02db'   #  0xB2 -> OGONEK
+    u'\u0142'   #  0xB3 -> LATIN SMALL LETTER L WITH STROKE
+    u'\xb4'     #  0xB4 -> ACUTE ACCENT
+    u'\xb5'     #  0xB5 -> MICRO SIGN
+    u'\xb6'     #  0xB6 -> PILCROW SIGN
+    u'\xb7'     #  0xB7 -> MIDDLE DOT
+    u'\xb8'     #  0xB8 -> CEDILLA
+    u'\u0105'   #  0xB9 -> LATIN SMALL LETTER A WITH OGONEK
+    u'\u015f'   #  0xBA -> LATIN SMALL LETTER S WITH CEDILLA
+    u'\xbb'     #  0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\u013d'   #  0xBC -> LATIN CAPITAL LETTER L WITH CARON
+    u'\u02dd'   #  0xBD -> DOUBLE ACUTE ACCENT
+    u'\u013e'   #  0xBE -> LATIN SMALL LETTER L WITH CARON
+    u'\u017c'   #  0xBF -> LATIN SMALL LETTER Z WITH DOT ABOVE
+    u'\u0154'   #  0xC0 -> LATIN CAPITAL LETTER R WITH ACUTE
+    u'\xc1'     #  0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE
+    u'\xc2'     #  0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+    u'\u0102'   #  0xC3 -> LATIN CAPITAL LETTER A WITH BREVE
+    u'\xc4'     #  0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS
+    u'\u0139'   #  0xC5 -> LATIN CAPITAL LETTER L WITH ACUTE
+    u'\u0106'   #  0xC6 -> LATIN CAPITAL LETTER C WITH ACUTE
+    u'\xc7'     #  0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA
+    u'\u010c'   #  0xC8 -> LATIN CAPITAL LETTER C WITH CARON
+    u'\xc9'     #  0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE
+    u'\u0118'   #  0xCA -> LATIN CAPITAL LETTER E WITH OGONEK
+    u'\xcb'     #  0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS
+    u'\u011a'   #  0xCC -> LATIN CAPITAL LETTER E WITH CARON
+    u'\xcd'     #  0xCD -> LATIN CAPITAL LETTER I WITH ACUTE
+    u'\xce'     #  0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+    u'\u010e'   #  0xCF -> LATIN CAPITAL LETTER D WITH CARON
+    u'\u0110'   #  0xD0 -> LATIN CAPITAL LETTER D WITH STROKE
+    u'\u0143'   #  0xD1 -> LATIN CAPITAL LETTER N WITH ACUTE
+    u'\u0147'   #  0xD2 -> LATIN CAPITAL LETTER N WITH CARON
+    u'\xd3'     #  0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE
+    u'\xd4'     #  0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+    u'\u0150'   #  0xD5 -> LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
+    u'\xd6'     #  0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS
+    u'\xd7'     #  0xD7 -> MULTIPLICATION SIGN
+    u'\u0158'   #  0xD8 -> LATIN CAPITAL LETTER R WITH CARON
+    u'\u016e'   #  0xD9 -> LATIN CAPITAL LETTER U WITH RING ABOVE
+    u'\xda'     #  0xDA -> LATIN CAPITAL LETTER U WITH ACUTE
+    u'\u0170'   #  0xDB -> LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
+    u'\xdc'     #  0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS
+    u'\xdd'     #  0xDD -> LATIN CAPITAL LETTER Y WITH ACUTE
+    u'\u0162'   #  0xDE -> LATIN CAPITAL LETTER T WITH CEDILLA
+    u'\xdf'     #  0xDF -> LATIN SMALL LETTER SHARP S
+    u'\u0155'   #  0xE0 -> LATIN SMALL LETTER R WITH ACUTE
+    u'\xe1'     #  0xE1 -> LATIN SMALL LETTER A WITH ACUTE
+    u'\xe2'     #  0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX
+    u'\u0103'   #  0xE3 -> LATIN SMALL LETTER A WITH BREVE
+    u'\xe4'     #  0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS
+    u'\u013a'   #  0xE5 -> LATIN SMALL LETTER L WITH ACUTE
+    u'\u0107'   #  0xE6 -> LATIN SMALL LETTER C WITH ACUTE
+    u'\xe7'     #  0xE7 -> LATIN SMALL LETTER C WITH CEDILLA
+    u'\u010d'   #  0xE8 -> LATIN SMALL LETTER C WITH CARON
+    u'\xe9'     #  0xE9 -> LATIN SMALL LETTER E WITH ACUTE
+    u'\u0119'   #  0xEA -> LATIN SMALL LETTER E WITH OGONEK
+    u'\xeb'     #  0xEB -> LATIN SMALL LETTER E WITH DIAERESIS
+    u'\u011b'   #  0xEC -> LATIN SMALL LETTER E WITH CARON
+    u'\xed'     #  0xED -> LATIN SMALL LETTER I WITH ACUTE
+    u'\xee'     #  0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX
+    u'\u010f'   #  0xEF -> LATIN SMALL LETTER D WITH CARON
+    u'\u0111'   #  0xF0 -> LATIN SMALL LETTER D WITH STROKE
+    u'\u0144'   #  0xF1 -> LATIN SMALL LETTER N WITH ACUTE
+    u'\u0148'   #  0xF2 -> LATIN SMALL LETTER N WITH CARON
+    u'\xf3'     #  0xF3 -> LATIN SMALL LETTER O WITH ACUTE
+    u'\xf4'     #  0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX
+    u'\u0151'   #  0xF5 -> LATIN SMALL LETTER O WITH DOUBLE ACUTE
+    u'\xf6'     #  0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS
+    u'\xf7'     #  0xF7 -> DIVISION SIGN
+    u'\u0159'   #  0xF8 -> LATIN SMALL LETTER R WITH CARON
+    u'\u016f'   #  0xF9 -> LATIN SMALL LETTER U WITH RING ABOVE
+    u'\xfa'     #  0xFA -> LATIN SMALL LETTER U WITH ACUTE
+    u'\u0171'   #  0xFB -> LATIN SMALL LETTER U WITH DOUBLE ACUTE
+    u'\xfc'     #  0xFC -> LATIN SMALL LETTER U WITH DIAERESIS
+    u'\xfd'     #  0xFD -> LATIN SMALL LETTER Y WITH ACUTE
+    u'\u0163'   #  0xFE -> LATIN SMALL LETTER T WITH CEDILLA
+    u'\u02d9'   #  0xFF -> DOT ABOVE
+)
+
+### Encoding table
+encoding_table=codecs.charmap_build(decoding_table)

Added: vendor/Python/current/Lib/encodings/cp1251.py
===================================================================
--- vendor/Python/current/Lib/encodings/cp1251.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/cp1251.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,307 @@
+""" Python Character Mapping Codec cp1251 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1251.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_table)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_table)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='cp1251',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x00 -> NULL
+    u'\x01'     #  0x01 -> START OF HEADING
+    u'\x02'     #  0x02 -> START OF TEXT
+    u'\x03'     #  0x03 -> END OF TEXT
+    u'\x04'     #  0x04 -> END OF TRANSMISSION
+    u'\x05'     #  0x05 -> ENQUIRY
+    u'\x06'     #  0x06 -> ACKNOWLEDGE
+    u'\x07'     #  0x07 -> BELL
+    u'\x08'     #  0x08 -> BACKSPACE
+    u'\t'       #  0x09 -> HORIZONTAL TABULATION
+    u'\n'       #  0x0A -> LINE FEED
+    u'\x0b'     #  0x0B -> VERTICAL TABULATION
+    u'\x0c'     #  0x0C -> FORM FEED
+    u'\r'       #  0x0D -> CARRIAGE RETURN
+    u'\x0e'     #  0x0E -> SHIFT OUT
+    u'\x0f'     #  0x0F -> SHIFT IN
+    u'\x10'     #  0x10 -> DATA LINK ESCAPE
+    u'\x11'     #  0x11 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x12 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x13 -> DEVICE CONTROL THREE
+    u'\x14'     #  0x14 -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x15 -> NEGATIVE ACKNOWLEDGE
+    u'\x16'     #  0x16 -> SYNCHRONOUS IDLE
+    u'\x17'     #  0x17 -> END OF TRANSMISSION BLOCK
+    u'\x18'     #  0x18 -> CANCEL
+    u'\x19'     #  0x19 -> END OF MEDIUM
+    u'\x1a'     #  0x1A -> SUBSTITUTE
+    u'\x1b'     #  0x1B -> ESCAPE
+    u'\x1c'     #  0x1C -> FILE SEPARATOR
+    u'\x1d'     #  0x1D -> GROUP SEPARATOR
+    u'\x1e'     #  0x1E -> RECORD SEPARATOR
+    u'\x1f'     #  0x1F -> UNIT SEPARATOR
+    u' '        #  0x20 -> SPACE
+    u'!'        #  0x21 -> EXCLAMATION MARK
+    u'"'        #  0x22 -> QUOTATION MARK
+    u'#'        #  0x23 -> NUMBER SIGN
+    u'$'        #  0x24 -> DOLLAR SIGN
+    u'%'        #  0x25 -> PERCENT SIGN
+    u'&'        #  0x26 -> AMPERSAND
+    u"'"        #  0x27 -> APOSTROPHE
+    u'('        #  0x28 -> LEFT PARENTHESIS
+    u')'        #  0x29 -> RIGHT PARENTHESIS
+    u'*'        #  0x2A -> ASTERISK
+    u'+'        #  0x2B -> PLUS SIGN
+    u','        #  0x2C -> COMMA
+    u'-'        #  0x2D -> HYPHEN-MINUS
+    u'.'        #  0x2E -> FULL STOP
+    u'/'        #  0x2F -> SOLIDUS
+    u'0'        #  0x30 -> DIGIT ZERO
+    u'1'        #  0x31 -> DIGIT ONE
+    u'2'        #  0x32 -> DIGIT TWO
+    u'3'        #  0x33 -> DIGIT THREE
+    u'4'        #  0x34 -> DIGIT FOUR
+    u'5'        #  0x35 -> DIGIT FIVE
+    u'6'        #  0x36 -> DIGIT SIX
+    u'7'        #  0x37 -> DIGIT SEVEN
+    u'8'        #  0x38 -> DIGIT EIGHT
+    u'9'        #  0x39 -> DIGIT NINE
+    u':'        #  0x3A -> COLON
+    u';'        #  0x3B -> SEMICOLON
+    u'<'        #  0x3C -> LESS-THAN SIGN
+    u'='        #  0x3D -> EQUALS SIGN
+    u'>'        #  0x3E -> GREATER-THAN SIGN
+    u'?'        #  0x3F -> QUESTION MARK
+    u'@'        #  0x40 -> COMMERCIAL AT
+    u'A'        #  0x41 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x42 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x43 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x44 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x45 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x46 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x47 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x48 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x49 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x4A -> LATIN CAPITAL LETTER J
+    u'K'        #  0x4B -> LATIN CAPITAL LETTER K
+    u'L'        #  0x4C -> LATIN CAPITAL LETTER L
+    u'M'        #  0x4D -> LATIN CAPITAL LETTER M
+    u'N'        #  0x4E -> LATIN CAPITAL LETTER N
+    u'O'        #  0x4F -> LATIN CAPITAL LETTER O
+    u'P'        #  0x50 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x51 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x52 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x53 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x54 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x55 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x56 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x57 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x58 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x59 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x5A -> LATIN CAPITAL LETTER Z
+    u'['        #  0x5B -> LEFT SQUARE BRACKET
+    u'\\'       #  0x5C -> REVERSE SOLIDUS
+    u']'        #  0x5D -> RIGHT SQUARE BRACKET
+    u'^'        #  0x5E -> CIRCUMFLEX ACCENT
+    u'_'        #  0x5F -> LOW LINE
+    u'`'        #  0x60 -> GRAVE ACCENT
+    u'a'        #  0x61 -> LATIN SMALL LETTER A
+    u'b'        #  0x62 -> LATIN SMALL LETTER B
+    u'c'        #  0x63 -> LATIN SMALL LETTER C
+    u'd'        #  0x64 -> LATIN SMALL LETTER D
+    u'e'        #  0x65 -> LATIN SMALL LETTER E
+    u'f'        #  0x66 -> LATIN SMALL LETTER F
+    u'g'        #  0x67 -> LATIN SMALL LETTER G
+    u'h'        #  0x68 -> LATIN SMALL LETTER H
+    u'i'        #  0x69 -> LATIN SMALL LETTER I
+    u'j'        #  0x6A -> LATIN SMALL LETTER J
+    u'k'        #  0x6B -> LATIN SMALL LETTER K
+    u'l'        #  0x6C -> LATIN SMALL LETTER L
+    u'm'        #  0x6D -> LATIN SMALL LETTER M
+    u'n'        #  0x6E -> LATIN SMALL LETTER N
+    u'o'        #  0x6F -> LATIN SMALL LETTER O
+    u'p'        #  0x70 -> LATIN SMALL LETTER P
+    u'q'        #  0x71 -> LATIN SMALL LETTER Q
+    u'r'        #  0x72 -> LATIN SMALL LETTER R
+    u's'        #  0x73 -> LATIN SMALL LETTER S
+    u't'        #  0x74 -> LATIN SMALL LETTER T
+    u'u'        #  0x75 -> LATIN SMALL LETTER U
+    u'v'        #  0x76 -> LATIN SMALL LETTER V
+    u'w'        #  0x77 -> LATIN SMALL LETTER W
+    u'x'        #  0x78 -> LATIN SMALL LETTER X
+    u'y'        #  0x79 -> LATIN SMALL LETTER Y
+    u'z'        #  0x7A -> LATIN SMALL LETTER Z
+    u'{'        #  0x7B -> LEFT CURLY BRACKET
+    u'|'        #  0x7C -> VERTICAL LINE
+    u'}'        #  0x7D -> RIGHT CURLY BRACKET
+    u'~'        #  0x7E -> TILDE
+    u'\x7f'     #  0x7F -> DELETE
+    u'\u0402'   #  0x80 -> CYRILLIC CAPITAL LETTER DJE
+    u'\u0403'   #  0x81 -> CYRILLIC CAPITAL LETTER GJE
+    u'\u201a'   #  0x82 -> SINGLE LOW-9 QUOTATION MARK
+    u'\u0453'   #  0x83 -> CYRILLIC SMALL LETTER GJE
+    u'\u201e'   #  0x84 -> DOUBLE LOW-9 QUOTATION MARK
+    u'\u2026'   #  0x85 -> HORIZONTAL ELLIPSIS
+    u'\u2020'   #  0x86 -> DAGGER
+    u'\u2021'   #  0x87 -> DOUBLE DAGGER
+    u'\u20ac'   #  0x88 -> EURO SIGN
+    u'\u2030'   #  0x89 -> PER MILLE SIGN
+    u'\u0409'   #  0x8A -> CYRILLIC CAPITAL LETTER LJE
+    u'\u2039'   #  0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+    u'\u040a'   #  0x8C -> CYRILLIC CAPITAL LETTER NJE
+    u'\u040c'   #  0x8D -> CYRILLIC CAPITAL LETTER KJE
+    u'\u040b'   #  0x8E -> CYRILLIC CAPITAL LETTER TSHE
+    u'\u040f'   #  0x8F -> CYRILLIC CAPITAL LETTER DZHE
+    u'\u0452'   #  0x90 -> CYRILLIC SMALL LETTER DJE
+    u'\u2018'   #  0x91 -> LEFT SINGLE QUOTATION MARK
+    u'\u2019'   #  0x92 -> RIGHT SINGLE QUOTATION MARK
+    u'\u201c'   #  0x93 -> LEFT DOUBLE QUOTATION MARK
+    u'\u201d'   #  0x94 -> RIGHT DOUBLE QUOTATION MARK
+    u'\u2022'   #  0x95 -> BULLET
+    u'\u2013'   #  0x96 -> EN DASH
+    u'\u2014'   #  0x97 -> EM DASH
+    u'\ufffe'   #  0x98 -> UNDEFINED
+    u'\u2122'   #  0x99 -> TRADE MARK SIGN
+    u'\u0459'   #  0x9A -> CYRILLIC SMALL LETTER LJE
+    u'\u203a'   #  0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+    u'\u045a'   #  0x9C -> CYRILLIC SMALL LETTER NJE
+    u'\u045c'   #  0x9D -> CYRILLIC SMALL LETTER KJE
+    u'\u045b'   #  0x9E -> CYRILLIC SMALL LETTER TSHE
+    u'\u045f'   #  0x9F -> CYRILLIC SMALL LETTER DZHE
+    u'\xa0'     #  0xA0 -> NO-BREAK SPACE
+    u'\u040e'   #  0xA1 -> CYRILLIC CAPITAL LETTER SHORT U
+    u'\u045e'   #  0xA2 -> CYRILLIC SMALL LETTER SHORT U
+    u'\u0408'   #  0xA3 -> CYRILLIC CAPITAL LETTER JE
+    u'\xa4'     #  0xA4 -> CURRENCY SIGN
+    u'\u0490'   #  0xA5 -> CYRILLIC CAPITAL LETTER GHE WITH UPTURN
+    u'\xa6'     #  0xA6 -> BROKEN BAR
+    u'\xa7'     #  0xA7 -> SECTION SIGN
+    u'\u0401'   #  0xA8 -> CYRILLIC CAPITAL LETTER IO
+    u'\xa9'     #  0xA9 -> COPYRIGHT SIGN
+    u'\u0404'   #  0xAA -> CYRILLIC CAPITAL LETTER UKRAINIAN IE
+    u'\xab'     #  0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xac'     #  0xAC -> NOT SIGN
+    u'\xad'     #  0xAD -> SOFT HYPHEN
+    u'\xae'     #  0xAE -> REGISTERED SIGN
+    u'\u0407'   #  0xAF -> CYRILLIC CAPITAL LETTER YI
+    u'\xb0'     #  0xB0 -> DEGREE SIGN
+    u'\xb1'     #  0xB1 -> PLUS-MINUS SIGN
+    u'\u0406'   #  0xB2 -> CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I
+    u'\u0456'   #  0xB3 -> CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
+    u'\u0491'   #  0xB4 -> CYRILLIC SMALL LETTER GHE WITH UPTURN
+    u'\xb5'     #  0xB5 -> MICRO SIGN
+    u'\xb6'     #  0xB6 -> PILCROW SIGN
+    u'\xb7'     #  0xB7 -> MIDDLE DOT
+    u'\u0451'   #  0xB8 -> CYRILLIC SMALL LETTER IO
+    u'\u2116'   #  0xB9 -> NUMERO SIGN
+    u'\u0454'   #  0xBA -> CYRILLIC SMALL LETTER UKRAINIAN IE
+    u'\xbb'     #  0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\u0458'   #  0xBC -> CYRILLIC SMALL LETTER JE
+    u'\u0405'   #  0xBD -> CYRILLIC CAPITAL LETTER DZE
+    u'\u0455'   #  0xBE -> CYRILLIC SMALL LETTER DZE
+    u'\u0457'   #  0xBF -> CYRILLIC SMALL LETTER YI
+    u'\u0410'   #  0xC0 -> CYRILLIC CAPITAL LETTER A
+    u'\u0411'   #  0xC1 -> CYRILLIC CAPITAL LETTER BE
+    u'\u0412'   #  0xC2 -> CYRILLIC CAPITAL LETTER VE
+    u'\u0413'   #  0xC3 -> CYRILLIC CAPITAL LETTER GHE
+    u'\u0414'   #  0xC4 -> CYRILLIC CAPITAL LETTER DE
+    u'\u0415'   #  0xC5 -> CYRILLIC CAPITAL LETTER IE
+    u'\u0416'   #  0xC6 -> CYRILLIC CAPITAL LETTER ZHE
+    u'\u0417'   #  0xC7 -> CYRILLIC CAPITAL LETTER ZE
+    u'\u0418'   #  0xC8 -> CYRILLIC CAPITAL LETTER I
+    u'\u0419'   #  0xC9 -> CYRILLIC CAPITAL LETTER SHORT I
+    u'\u041a'   #  0xCA -> CYRILLIC CAPITAL LETTER KA
+    u'\u041b'   #  0xCB -> CYRILLIC CAPITAL LETTER EL
+    u'\u041c'   #  0xCC -> CYRILLIC CAPITAL LETTER EM
+    u'\u041d'   #  0xCD -> CYRILLIC CAPITAL LETTER EN
+    u'\u041e'   #  0xCE -> CYRILLIC CAPITAL LETTER O
+    u'\u041f'   #  0xCF -> CYRILLIC CAPITAL LETTER PE
+    u'\u0420'   #  0xD0 -> CYRILLIC CAPITAL LETTER ER
+    u'\u0421'   #  0xD1 -> CYRILLIC CAPITAL LETTER ES
+    u'\u0422'   #  0xD2 -> CYRILLIC CAPITAL LETTER TE
+    u'\u0423'   #  0xD3 -> CYRILLIC CAPITAL LETTER U
+    u'\u0424'   #  0xD4 -> CYRILLIC CAPITAL LETTER EF
+    u'\u0425'   #  0xD5 -> CYRILLIC CAPITAL LETTER HA
+    u'\u0426'   #  0xD6 -> CYRILLIC CAPITAL LETTER TSE
+    u'\u0427'   #  0xD7 -> CYRILLIC CAPITAL LETTER CHE
+    u'\u0428'   #  0xD8 -> CYRILLIC CAPITAL LETTER SHA
+    u'\u0429'   #  0xD9 -> CYRILLIC CAPITAL LETTER SHCHA
+    u'\u042a'   #  0xDA -> CYRILLIC CAPITAL LETTER HARD SIGN
+    u'\u042b'   #  0xDB -> CYRILLIC CAPITAL LETTER YERU
+    u'\u042c'   #  0xDC -> CYRILLIC CAPITAL LETTER SOFT SIGN
+    u'\u042d'   #  0xDD -> CYRILLIC CAPITAL LETTER E
+    u'\u042e'   #  0xDE -> CYRILLIC CAPITAL LETTER YU
+    u'\u042f'   #  0xDF -> CYRILLIC CAPITAL LETTER YA
+    u'\u0430'   #  0xE0 -> CYRILLIC SMALL LETTER A
+    u'\u0431'   #  0xE1 -> CYRILLIC SMALL LETTER BE
+    u'\u0432'   #  0xE2 -> CYRILLIC SMALL LETTER VE
+    u'\u0433'   #  0xE3 -> CYRILLIC SMALL LETTER GHE
+    u'\u0434'   #  0xE4 -> CYRILLIC SMALL LETTER DE
+    u'\u0435'   #  0xE5 -> CYRILLIC SMALL LETTER IE
+    u'\u0436'   #  0xE6 -> CYRILLIC SMALL LETTER ZHE
+    u'\u0437'   #  0xE7 -> CYRILLIC SMALL LETTER ZE
+    u'\u0438'   #  0xE8 -> CYRILLIC SMALL LETTER I
+    u'\u0439'   #  0xE9 -> CYRILLIC SMALL LETTER SHORT I
+    u'\u043a'   #  0xEA -> CYRILLIC SMALL LETTER KA
+    u'\u043b'   #  0xEB -> CYRILLIC SMALL LETTER EL
+    u'\u043c'   #  0xEC -> CYRILLIC SMALL LETTER EM
+    u'\u043d'   #  0xED -> CYRILLIC SMALL LETTER EN
+    u'\u043e'   #  0xEE -> CYRILLIC SMALL LETTER O
+    u'\u043f'   #  0xEF -> CYRILLIC SMALL LETTER PE
+    u'\u0440'   #  0xF0 -> CYRILLIC SMALL LETTER ER
+    u'\u0441'   #  0xF1 -> CYRILLIC SMALL LETTER ES
+    u'\u0442'   #  0xF2 -> CYRILLIC SMALL LETTER TE
+    u'\u0443'   #  0xF3 -> CYRILLIC SMALL LETTER U
+    u'\u0444'   #  0xF4 -> CYRILLIC SMALL LETTER EF
+    u'\u0445'   #  0xF5 -> CYRILLIC SMALL LETTER HA
+    u'\u0446'   #  0xF6 -> CYRILLIC SMALL LETTER TSE
+    u'\u0447'   #  0xF7 -> CYRILLIC SMALL LETTER CHE
+    u'\u0448'   #  0xF8 -> CYRILLIC SMALL LETTER SHA
+    u'\u0449'   #  0xF9 -> CYRILLIC SMALL LETTER SHCHA
+    u'\u044a'   #  0xFA -> CYRILLIC SMALL LETTER HARD SIGN
+    u'\u044b'   #  0xFB -> CYRILLIC SMALL LETTER YERU
+    u'\u044c'   #  0xFC -> CYRILLIC SMALL LETTER SOFT SIGN
+    u'\u044d'   #  0xFD -> CYRILLIC SMALL LETTER E
+    u'\u044e'   #  0xFE -> CYRILLIC SMALL LETTER YU
+    u'\u044f'   #  0xFF -> CYRILLIC SMALL LETTER YA
+)
+
+### Encoding table
+encoding_table=codecs.charmap_build(decoding_table)

Added: vendor/Python/current/Lib/encodings/cp1252.py
===================================================================
--- vendor/Python/current/Lib/encodings/cp1252.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/cp1252.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,307 @@
+""" Python Character Mapping Codec cp1252 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1252.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_table)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_table)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='cp1252',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x00 -> NULL
+    u'\x01'     #  0x01 -> START OF HEADING
+    u'\x02'     #  0x02 -> START OF TEXT
+    u'\x03'     #  0x03 -> END OF TEXT
+    u'\x04'     #  0x04 -> END OF TRANSMISSION
+    u'\x05'     #  0x05 -> ENQUIRY
+    u'\x06'     #  0x06 -> ACKNOWLEDGE
+    u'\x07'     #  0x07 -> BELL
+    u'\x08'     #  0x08 -> BACKSPACE
+    u'\t'       #  0x09 -> HORIZONTAL TABULATION
+    u'\n'       #  0x0A -> LINE FEED
+    u'\x0b'     #  0x0B -> VERTICAL TABULATION
+    u'\x0c'     #  0x0C -> FORM FEED
+    u'\r'       #  0x0D -> CARRIAGE RETURN
+    u'\x0e'     #  0x0E -> SHIFT OUT
+    u'\x0f'     #  0x0F -> SHIFT IN
+    u'\x10'     #  0x10 -> DATA LINK ESCAPE
+    u'\x11'     #  0x11 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x12 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x13 -> DEVICE CONTROL THREE
+    u'\x14'     #  0x14 -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x15 -> NEGATIVE ACKNOWLEDGE
+    u'\x16'     #  0x16 -> SYNCHRONOUS IDLE
+    u'\x17'     #  0x17 -> END OF TRANSMISSION BLOCK
+    u'\x18'     #  0x18 -> CANCEL
+    u'\x19'     #  0x19 -> END OF MEDIUM
+    u'\x1a'     #  0x1A -> SUBSTITUTE
+    u'\x1b'     #  0x1B -> ESCAPE
+    u'\x1c'     #  0x1C -> FILE SEPARATOR
+    u'\x1d'     #  0x1D -> GROUP SEPARATOR
+    u'\x1e'     #  0x1E -> RECORD SEPARATOR
+    u'\x1f'     #  0x1F -> UNIT SEPARATOR
+    u' '        #  0x20 -> SPACE
+    u'!'        #  0x21 -> EXCLAMATION MARK
+    u'"'        #  0x22 -> QUOTATION MARK
+    u'#'        #  0x23 -> NUMBER SIGN
+    u'$'        #  0x24 -> DOLLAR SIGN
+    u'%'        #  0x25 -> PERCENT SIGN
+    u'&'        #  0x26 -> AMPERSAND
+    u"'"        #  0x27 -> APOSTROPHE
+    u'('        #  0x28 -> LEFT PARENTHESIS
+    u')'        #  0x29 -> RIGHT PARENTHESIS
+    u'*'        #  0x2A -> ASTERISK
+    u'+'        #  0x2B -> PLUS SIGN
+    u','        #  0x2C -> COMMA
+    u'-'        #  0x2D -> HYPHEN-MINUS
+    u'.'        #  0x2E -> FULL STOP
+    u'/'        #  0x2F -> SOLIDUS
+    u'0'        #  0x30 -> DIGIT ZERO
+    u'1'        #  0x31 -> DIGIT ONE
+    u'2'        #  0x32 -> DIGIT TWO
+    u'3'        #  0x33 -> DIGIT THREE
+    u'4'        #  0x34 -> DIGIT FOUR
+    u'5'        #  0x35 -> DIGIT FIVE
+    u'6'        #  0x36 -> DIGIT SIX
+    u'7'        #  0x37 -> DIGIT SEVEN
+    u'8'        #  0x38 -> DIGIT EIGHT
+    u'9'        #  0x39 -> DIGIT NINE
+    u':'        #  0x3A -> COLON
+    u';'        #  0x3B -> SEMICOLON
+    u'<'        #  0x3C -> LESS-THAN SIGN
+    u'='        #  0x3D -> EQUALS SIGN
+    u'>'        #  0x3E -> GREATER-THAN SIGN
+    u'?'        #  0x3F -> QUESTION MARK
+    u'@'        #  0x40 -> COMMERCIAL AT
+    u'A'        #  0x41 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x42 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x43 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x44 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x45 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x46 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x47 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x48 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x49 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x4A -> LATIN CAPITAL LETTER J
+    u'K'        #  0x4B -> LATIN CAPITAL LETTER K
+    u'L'        #  0x4C -> LATIN CAPITAL LETTER L
+    u'M'        #  0x4D -> LATIN CAPITAL LETTER M
+    u'N'        #  0x4E -> LATIN CAPITAL LETTER N
+    u'O'        #  0x4F -> LATIN CAPITAL LETTER O
+    u'P'        #  0x50 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x51 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x52 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x53 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x54 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x55 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x56 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x57 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x58 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x59 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x5A -> LATIN CAPITAL LETTER Z
+    u'['        #  0x5B -> LEFT SQUARE BRACKET
+    u'\\'       #  0x5C -> REVERSE SOLIDUS
+    u']'        #  0x5D -> RIGHT SQUARE BRACKET
+    u'^'        #  0x5E -> CIRCUMFLEX ACCENT
+    u'_'        #  0x5F -> LOW LINE
+    u'`'        #  0x60 -> GRAVE ACCENT
+    u'a'        #  0x61 -> LATIN SMALL LETTER A
+    u'b'        #  0x62 -> LATIN SMALL LETTER B
+    u'c'        #  0x63 -> LATIN SMALL LETTER C
+    u'd'        #  0x64 -> LATIN SMALL LETTER D
+    u'e'        #  0x65 -> LATIN SMALL LETTER E
+    u'f'        #  0x66 -> LATIN SMALL LETTER F
+    u'g'        #  0x67 -> LATIN SMALL LETTER G
+    u'h'        #  0x68 -> LATIN SMALL LETTER H
+    u'i'        #  0x69 -> LATIN SMALL LETTER I
+    u'j'        #  0x6A -> LATIN SMALL LETTER J
+    u'k'        #  0x6B -> LATIN SMALL LETTER K
+    u'l'        #  0x6C -> LATIN SMALL LETTER L
+    u'm'        #  0x6D -> LATIN SMALL LETTER M
+    u'n'        #  0x6E -> LATIN SMALL LETTER N
+    u'o'        #  0x6F -> LATIN SMALL LETTER O
+    u'p'        #  0x70 -> LATIN SMALL LETTER P
+    u'q'        #  0x71 -> LATIN SMALL LETTER Q
+    u'r'        #  0x72 -> LATIN SMALL LETTER R
+    u's'        #  0x73 -> LATIN SMALL LETTER S
+    u't'        #  0x74 -> LATIN SMALL LETTER T
+    u'u'        #  0x75 -> LATIN SMALL LETTER U
+    u'v'        #  0x76 -> LATIN SMALL LETTER V
+    u'w'        #  0x77 -> LATIN SMALL LETTER W
+    u'x'        #  0x78 -> LATIN SMALL LETTER X
+    u'y'        #  0x79 -> LATIN SMALL LETTER Y
+    u'z'        #  0x7A -> LATIN SMALL LETTER Z
+    u'{'        #  0x7B -> LEFT CURLY BRACKET
+    u'|'        #  0x7C -> VERTICAL LINE
+    u'}'        #  0x7D -> RIGHT CURLY BRACKET
+    u'~'        #  0x7E -> TILDE
+    u'\x7f'     #  0x7F -> DELETE
+    u'\u20ac'   #  0x80 -> EURO SIGN
+    u'\ufffe'   #  0x81 -> UNDEFINED
+    u'\u201a'   #  0x82 -> SINGLE LOW-9 QUOTATION MARK
+    u'\u0192'   #  0x83 -> LATIN SMALL LETTER F WITH HOOK
+    u'\u201e'   #  0x84 -> DOUBLE LOW-9 QUOTATION MARK
+    u'\u2026'   #  0x85 -> HORIZONTAL ELLIPSIS
+    u'\u2020'   #  0x86 -> DAGGER
+    u'\u2021'   #  0x87 -> DOUBLE DAGGER
+    u'\u02c6'   #  0x88 -> MODIFIER LETTER CIRCUMFLEX ACCENT
+    u'\u2030'   #  0x89 -> PER MILLE SIGN
+    u'\u0160'   #  0x8A -> LATIN CAPITAL LETTER S WITH CARON
+    u'\u2039'   #  0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+    u'\u0152'   #  0x8C -> LATIN CAPITAL LIGATURE OE
+    u'\ufffe'   #  0x8D -> UNDEFINED
+    u'\u017d'   #  0x8E -> LATIN CAPITAL LETTER Z WITH CARON
+    u'\ufffe'   #  0x8F -> UNDEFINED
+    u'\ufffe'   #  0x90 -> UNDEFINED
+    u'\u2018'   #  0x91 -> LEFT SINGLE QUOTATION MARK
+    u'\u2019'   #  0x92 -> RIGHT SINGLE QUOTATION MARK
+    u'\u201c'   #  0x93 -> LEFT DOUBLE QUOTATION MARK
+    u'\u201d'   #  0x94 -> RIGHT DOUBLE QUOTATION MARK
+    u'\u2022'   #  0x95 -> BULLET
+    u'\u2013'   #  0x96 -> EN DASH
+    u'\u2014'   #  0x97 -> EM DASH
+    u'\u02dc'   #  0x98 -> SMALL TILDE
+    u'\u2122'   #  0x99 -> TRADE MARK SIGN
+    u'\u0161'   #  0x9A -> LATIN SMALL LETTER S WITH CARON
+    u'\u203a'   #  0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+    u'\u0153'   #  0x9C -> LATIN SMALL LIGATURE OE
+    u'\ufffe'   #  0x9D -> UNDEFINED
+    u'\u017e'   #  0x9E -> LATIN SMALL LETTER Z WITH CARON
+    u'\u0178'   #  0x9F -> LATIN CAPITAL LETTER Y WITH DIAERESIS
+    u'\xa0'     #  0xA0 -> NO-BREAK SPACE
+    u'\xa1'     #  0xA1 -> INVERTED EXCLAMATION MARK
+    u'\xa2'     #  0xA2 -> CENT SIGN
+    u'\xa3'     #  0xA3 -> POUND SIGN
+    u'\xa4'     #  0xA4 -> CURRENCY SIGN
+    u'\xa5'     #  0xA5 -> YEN SIGN
+    u'\xa6'     #  0xA6 -> BROKEN BAR
+    u'\xa7'     #  0xA7 -> SECTION SIGN
+    u'\xa8'     #  0xA8 -> DIAERESIS
+    u'\xa9'     #  0xA9 -> COPYRIGHT SIGN
+    u'\xaa'     #  0xAA -> FEMININE ORDINAL INDICATOR
+    u'\xab'     #  0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xac'     #  0xAC -> NOT SIGN
+    u'\xad'     #  0xAD -> SOFT HYPHEN
+    u'\xae'     #  0xAE -> REGISTERED SIGN
+    u'\xaf'     #  0xAF -> MACRON
+    u'\xb0'     #  0xB0 -> DEGREE SIGN
+    u'\xb1'     #  0xB1 -> PLUS-MINUS SIGN
+    u'\xb2'     #  0xB2 -> SUPERSCRIPT TWO
+    u'\xb3'     #  0xB3 -> SUPERSCRIPT THREE
+    u'\xb4'     #  0xB4 -> ACUTE ACCENT
+    u'\xb5'     #  0xB5 -> MICRO SIGN
+    u'\xb6'     #  0xB6 -> PILCROW SIGN
+    u'\xb7'     #  0xB7 -> MIDDLE DOT
+    u'\xb8'     #  0xB8 -> CEDILLA
+    u'\xb9'     #  0xB9 -> SUPERSCRIPT ONE
+    u'\xba'     #  0xBA -> MASCULINE ORDINAL INDICATOR
+    u'\xbb'     #  0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xbc'     #  0xBC -> VULGAR FRACTION ONE QUARTER
+    u'\xbd'     #  0xBD -> VULGAR FRACTION ONE HALF
+    u'\xbe'     #  0xBE -> VULGAR FRACTION THREE QUARTERS
+    u'\xbf'     #  0xBF -> INVERTED QUESTION MARK
+    u'\xc0'     #  0xC0 -> LATIN CAPITAL LETTER A WITH GRAVE
+    u'\xc1'     #  0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE
+    u'\xc2'     #  0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+    u'\xc3'     #  0xC3 -> LATIN CAPITAL LETTER A WITH TILDE
+    u'\xc4'     #  0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS
+    u'\xc5'     #  0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE
+    u'\xc6'     #  0xC6 -> LATIN CAPITAL LETTER AE
+    u'\xc7'     #  0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA
+    u'\xc8'     #  0xC8 -> LATIN CAPITAL LETTER E WITH GRAVE
+    u'\xc9'     #  0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE
+    u'\xca'     #  0xCA -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+    u'\xcb'     #  0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS
+    u'\xcc'     #  0xCC -> LATIN CAPITAL LETTER I WITH GRAVE
+    u'\xcd'     #  0xCD -> LATIN CAPITAL LETTER I WITH ACUTE
+    u'\xce'     #  0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+    u'\xcf'     #  0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS
+    u'\xd0'     #  0xD0 -> LATIN CAPITAL LETTER ETH
+    u'\xd1'     #  0xD1 -> LATIN CAPITAL LETTER N WITH TILDE
+    u'\xd2'     #  0xD2 -> LATIN CAPITAL LETTER O WITH GRAVE
+    u'\xd3'     #  0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE
+    u'\xd4'     #  0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+    u'\xd5'     #  0xD5 -> LATIN CAPITAL LETTER O WITH TILDE
+    u'\xd6'     #  0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS
+    u'\xd7'     #  0xD7 -> MULTIPLICATION SIGN
+    u'\xd8'     #  0xD8 -> LATIN CAPITAL LETTER O WITH STROKE
+    u'\xd9'     #  0xD9 -> LATIN CAPITAL LETTER U WITH GRAVE
+    u'\xda'     #  0xDA -> LATIN CAPITAL LETTER U WITH ACUTE
+    u'\xdb'     #  0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+    u'\xdc'     #  0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS
+    u'\xdd'     #  0xDD -> LATIN CAPITAL LETTER Y WITH ACUTE
+    u'\xde'     #  0xDE -> LATIN CAPITAL LETTER THORN
+    u'\xdf'     #  0xDF -> LATIN SMALL LETTER SHARP S
+    u'\xe0'     #  0xE0 -> LATIN SMALL LETTER A WITH GRAVE
+    u'\xe1'     #  0xE1 -> LATIN SMALL LETTER A WITH ACUTE
+    u'\xe2'     #  0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX
+    u'\xe3'     #  0xE3 -> LATIN SMALL LETTER A WITH TILDE
+    u'\xe4'     #  0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS
+    u'\xe5'     #  0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE
+    u'\xe6'     #  0xE6 -> LATIN SMALL LETTER AE
+    u'\xe7'     #  0xE7 -> LATIN SMALL LETTER C WITH CEDILLA
+    u'\xe8'     #  0xE8 -> LATIN SMALL LETTER E WITH GRAVE
+    u'\xe9'     #  0xE9 -> LATIN SMALL LETTER E WITH ACUTE
+    u'\xea'     #  0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX
+    u'\xeb'     #  0xEB -> LATIN SMALL LETTER E WITH DIAERESIS
+    u'\xec'     #  0xEC -> LATIN SMALL LETTER I WITH GRAVE
+    u'\xed'     #  0xED -> LATIN SMALL LETTER I WITH ACUTE
+    u'\xee'     #  0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX
+    u'\xef'     #  0xEF -> LATIN SMALL LETTER I WITH DIAERESIS
+    u'\xf0'     #  0xF0 -> LATIN SMALL LETTER ETH
+    u'\xf1'     #  0xF1 -> LATIN SMALL LETTER N WITH TILDE
+    u'\xf2'     #  0xF2 -> LATIN SMALL LETTER O WITH GRAVE
+    u'\xf3'     #  0xF3 -> LATIN SMALL LETTER O WITH ACUTE
+    u'\xf4'     #  0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX
+    u'\xf5'     #  0xF5 -> LATIN SMALL LETTER O WITH TILDE
+    u'\xf6'     #  0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS
+    u'\xf7'     #  0xF7 -> DIVISION SIGN
+    u'\xf8'     #  0xF8 -> LATIN SMALL LETTER O WITH STROKE
+    u'\xf9'     #  0xF9 -> LATIN SMALL LETTER U WITH GRAVE
+    u'\xfa'     #  0xFA -> LATIN SMALL LETTER U WITH ACUTE
+    u'\xfb'     #  0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX
+    u'\xfc'     #  0xFC -> LATIN SMALL LETTER U WITH DIAERESIS
+    u'\xfd'     #  0xFD -> LATIN SMALL LETTER Y WITH ACUTE
+    u'\xfe'     #  0xFE -> LATIN SMALL LETTER THORN
+    u'\xff'     #  0xFF -> LATIN SMALL LETTER Y WITH DIAERESIS
+)
+
+### Encoding table
+encoding_table=codecs.charmap_build(decoding_table)

Added: vendor/Python/current/Lib/encodings/cp1253.py
===================================================================
--- vendor/Python/current/Lib/encodings/cp1253.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/cp1253.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,307 @@
+""" Python Character Mapping Codec cp1253 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1253.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_table)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_table)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='cp1253',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x00 -> NULL
+    u'\x01'     #  0x01 -> START OF HEADING
+    u'\x02'     #  0x02 -> START OF TEXT
+    u'\x03'     #  0x03 -> END OF TEXT
+    u'\x04'     #  0x04 -> END OF TRANSMISSION
+    u'\x05'     #  0x05 -> ENQUIRY
+    u'\x06'     #  0x06 -> ACKNOWLEDGE
+    u'\x07'     #  0x07 -> BELL
+    u'\x08'     #  0x08 -> BACKSPACE
+    u'\t'       #  0x09 -> HORIZONTAL TABULATION
+    u'\n'       #  0x0A -> LINE FEED
+    u'\x0b'     #  0x0B -> VERTICAL TABULATION
+    u'\x0c'     #  0x0C -> FORM FEED
+    u'\r'       #  0x0D -> CARRIAGE RETURN
+    u'\x0e'     #  0x0E -> SHIFT OUT
+    u'\x0f'     #  0x0F -> SHIFT IN
+    u'\x10'     #  0x10 -> DATA LINK ESCAPE
+    u'\x11'     #  0x11 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x12 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x13 -> DEVICE CONTROL THREE
+    u'\x14'     #  0x14 -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x15 -> NEGATIVE ACKNOWLEDGE
+    u'\x16'     #  0x16 -> SYNCHRONOUS IDLE
+    u'\x17'     #  0x17 -> END OF TRANSMISSION BLOCK
+    u'\x18'     #  0x18 -> CANCEL
+    u'\x19'     #  0x19 -> END OF MEDIUM
+    u'\x1a'     #  0x1A -> SUBSTITUTE
+    u'\x1b'     #  0x1B -> ESCAPE
+    u'\x1c'     #  0x1C -> FILE SEPARATOR
+    u'\x1d'     #  0x1D -> GROUP SEPARATOR
+    u'\x1e'     #  0x1E -> RECORD SEPARATOR
+    u'\x1f'     #  0x1F -> UNIT SEPARATOR
+    u' '        #  0x20 -> SPACE
+    u'!'        #  0x21 -> EXCLAMATION MARK
+    u'"'        #  0x22 -> QUOTATION MARK
+    u'#'        #  0x23 -> NUMBER SIGN
+    u'$'        #  0x24 -> DOLLAR SIGN
+    u'%'        #  0x25 -> PERCENT SIGN
+    u'&'        #  0x26 -> AMPERSAND
+    u"'"        #  0x27 -> APOSTROPHE
+    u'('        #  0x28 -> LEFT PARENTHESIS
+    u')'        #  0x29 -> RIGHT PARENTHESIS
+    u'*'        #  0x2A -> ASTERISK
+    u'+'        #  0x2B -> PLUS SIGN
+    u','        #  0x2C -> COMMA
+    u'-'        #  0x2D -> HYPHEN-MINUS
+    u'.'        #  0x2E -> FULL STOP
+    u'/'        #  0x2F -> SOLIDUS
+    u'0'        #  0x30 -> DIGIT ZERO
+    u'1'        #  0x31 -> DIGIT ONE
+    u'2'        #  0x32 -> DIGIT TWO
+    u'3'        #  0x33 -> DIGIT THREE
+    u'4'        #  0x34 -> DIGIT FOUR
+    u'5'        #  0x35 -> DIGIT FIVE
+    u'6'        #  0x36 -> DIGIT SIX
+    u'7'        #  0x37 -> DIGIT SEVEN
+    u'8'        #  0x38 -> DIGIT EIGHT
+    u'9'        #  0x39 -> DIGIT NINE
+    u':'        #  0x3A -> COLON
+    u';'        #  0x3B -> SEMICOLON
+    u'<'        #  0x3C -> LESS-THAN SIGN
+    u'='        #  0x3D -> EQUALS SIGN
+    u'>'        #  0x3E -> GREATER-THAN SIGN
+    u'?'        #  0x3F -> QUESTION MARK
+    u'@'        #  0x40 -> COMMERCIAL AT
+    u'A'        #  0x41 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x42 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x43 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x44 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x45 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x46 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x47 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x48 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x49 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x4A -> LATIN CAPITAL LETTER J
+    u'K'        #  0x4B -> LATIN CAPITAL LETTER K
+    u'L'        #  0x4C -> LATIN CAPITAL LETTER L
+    u'M'        #  0x4D -> LATIN CAPITAL LETTER M
+    u'N'        #  0x4E -> LATIN CAPITAL LETTER N
+    u'O'        #  0x4F -> LATIN CAPITAL LETTER O
+    u'P'        #  0x50 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x51 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x52 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x53 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x54 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x55 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x56 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x57 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x58 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x59 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x5A -> LATIN CAPITAL LETTER Z
+    u'['        #  0x5B -> LEFT SQUARE BRACKET
+    u'\\'       #  0x5C -> REVERSE SOLIDUS
+    u']'        #  0x5D -> RIGHT SQUARE BRACKET
+    u'^'        #  0x5E -> CIRCUMFLEX ACCENT
+    u'_'        #  0x5F -> LOW LINE
+    u'`'        #  0x60 -> GRAVE ACCENT
+    u'a'        #  0x61 -> LATIN SMALL LETTER A
+    u'b'        #  0x62 -> LATIN SMALL LETTER B
+    u'c'        #  0x63 -> LATIN SMALL LETTER C
+    u'd'        #  0x64 -> LATIN SMALL LETTER D
+    u'e'        #  0x65 -> LATIN SMALL LETTER E
+    u'f'        #  0x66 -> LATIN SMALL LETTER F
+    u'g'        #  0x67 -> LATIN SMALL LETTER G
+    u'h'        #  0x68 -> LATIN SMALL LETTER H
+    u'i'        #  0x69 -> LATIN SMALL LETTER I
+    u'j'        #  0x6A -> LATIN SMALL LETTER J
+    u'k'        #  0x6B -> LATIN SMALL LETTER K
+    u'l'        #  0x6C -> LATIN SMALL LETTER L
+    u'm'        #  0x6D -> LATIN SMALL LETTER M
+    u'n'        #  0x6E -> LATIN SMALL LETTER N
+    u'o'        #  0x6F -> LATIN SMALL LETTER O
+    u'p'        #  0x70 -> LATIN SMALL LETTER P
+    u'q'        #  0x71 -> LATIN SMALL LETTER Q
+    u'r'        #  0x72 -> LATIN SMALL LETTER R
+    u's'        #  0x73 -> LATIN SMALL LETTER S
+    u't'        #  0x74 -> LATIN SMALL LETTER T
+    u'u'        #  0x75 -> LATIN SMALL LETTER U
+    u'v'        #  0x76 -> LATIN SMALL LETTER V
+    u'w'        #  0x77 -> LATIN SMALL LETTER W
+    u'x'        #  0x78 -> LATIN SMALL LETTER X
+    u'y'        #  0x79 -> LATIN SMALL LETTER Y
+    u'z'        #  0x7A -> LATIN SMALL LETTER Z
+    u'{'        #  0x7B -> LEFT CURLY BRACKET
+    u'|'        #  0x7C -> VERTICAL LINE
+    u'}'        #  0x7D -> RIGHT CURLY BRACKET
+    u'~'        #  0x7E -> TILDE
+    u'\x7f'     #  0x7F -> DELETE
+    u'\u20ac'   #  0x80 -> EURO SIGN
+    u'\ufffe'   #  0x81 -> UNDEFINED
+    u'\u201a'   #  0x82 -> SINGLE LOW-9 QUOTATION MARK
+    u'\u0192'   #  0x83 -> LATIN SMALL LETTER F WITH HOOK
+    u'\u201e'   #  0x84 -> DOUBLE LOW-9 QUOTATION MARK
+    u'\u2026'   #  0x85 -> HORIZONTAL ELLIPSIS
+    u'\u2020'   #  0x86 -> DAGGER
+    u'\u2021'   #  0x87 -> DOUBLE DAGGER
+    u'\ufffe'   #  0x88 -> UNDEFINED
+    u'\u2030'   #  0x89 -> PER MILLE SIGN
+    u'\ufffe'   #  0x8A -> UNDEFINED
+    u'\u2039'   #  0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+    u'\ufffe'   #  0x8C -> UNDEFINED
+    u'\ufffe'   #  0x8D -> UNDEFINED
+    u'\ufffe'   #  0x8E -> UNDEFINED
+    u'\ufffe'   #  0x8F -> UNDEFINED
+    u'\ufffe'   #  0x90 -> UNDEFINED
+    u'\u2018'   #  0x91 -> LEFT SINGLE QUOTATION MARK
+    u'\u2019'   #  0x92 -> RIGHT SINGLE QUOTATION MARK
+    u'\u201c'   #  0x93 -> LEFT DOUBLE QUOTATION MARK
+    u'\u201d'   #  0x94 -> RIGHT DOUBLE QUOTATION MARK
+    u'\u2022'   #  0x95 -> BULLET
+    u'\u2013'   #  0x96 -> EN DASH
+    u'\u2014'   #  0x97 -> EM DASH
+    u'\ufffe'   #  0x98 -> UNDEFINED
+    u'\u2122'   #  0x99 -> TRADE MARK SIGN
+    u'\ufffe'   #  0x9A -> UNDEFINED
+    u'\u203a'   #  0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+    u'\ufffe'   #  0x9C -> UNDEFINED
+    u'\ufffe'   #  0x9D -> UNDEFINED
+    u'\ufffe'   #  0x9E -> UNDEFINED
+    u'\ufffe'   #  0x9F -> UNDEFINED
+    u'\xa0'     #  0xA0 -> NO-BREAK SPACE
+    u'\u0385'   #  0xA1 -> GREEK DIALYTIKA TONOS
+    u'\u0386'   #  0xA2 -> GREEK CAPITAL LETTER ALPHA WITH TONOS
+    u'\xa3'     #  0xA3 -> POUND SIGN
+    u'\xa4'     #  0xA4 -> CURRENCY SIGN
+    u'\xa5'     #  0xA5 -> YEN SIGN
+    u'\xa6'     #  0xA6 -> BROKEN BAR
+    u'\xa7'     #  0xA7 -> SECTION SIGN
+    u'\xa8'     #  0xA8 -> DIAERESIS
+    u'\xa9'     #  0xA9 -> COPYRIGHT SIGN
+    u'\ufffe'   #  0xAA -> UNDEFINED
+    u'\xab'     #  0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xac'     #  0xAC -> NOT SIGN
+    u'\xad'     #  0xAD -> SOFT HYPHEN
+    u'\xae'     #  0xAE -> REGISTERED SIGN
+    u'\u2015'   #  0xAF -> HORIZONTAL BAR
+    u'\xb0'     #  0xB0 -> DEGREE SIGN
+    u'\xb1'     #  0xB1 -> PLUS-MINUS SIGN
+    u'\xb2'     #  0xB2 -> SUPERSCRIPT TWO
+    u'\xb3'     #  0xB3 -> SUPERSCRIPT THREE
+    u'\u0384'   #  0xB4 -> GREEK TONOS
+    u'\xb5'     #  0xB5 -> MICRO SIGN
+    u'\xb6'     #  0xB6 -> PILCROW SIGN
+    u'\xb7'     #  0xB7 -> MIDDLE DOT
+    u'\u0388'   #  0xB8 -> GREEK CAPITAL LETTER EPSILON WITH TONOS
+    u'\u0389'   #  0xB9 -> GREEK CAPITAL LETTER ETA WITH TONOS
+    u'\u038a'   #  0xBA -> GREEK CAPITAL LETTER IOTA WITH TONOS
+    u'\xbb'     #  0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\u038c'   #  0xBC -> GREEK CAPITAL LETTER OMICRON WITH TONOS
+    u'\xbd'     #  0xBD -> VULGAR FRACTION ONE HALF
+    u'\u038e'   #  0xBE -> GREEK CAPITAL LETTER UPSILON WITH TONOS
+    u'\u038f'   #  0xBF -> GREEK CAPITAL LETTER OMEGA WITH TONOS
+    u'\u0390'   #  0xC0 -> GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
+    u'\u0391'   #  0xC1 -> GREEK CAPITAL LETTER ALPHA
+    u'\u0392'   #  0xC2 -> GREEK CAPITAL LETTER BETA
+    u'\u0393'   #  0xC3 -> GREEK CAPITAL LETTER GAMMA
+    u'\u0394'   #  0xC4 -> GREEK CAPITAL LETTER DELTA
+    u'\u0395'   #  0xC5 -> GREEK CAPITAL LETTER EPSILON
+    u'\u0396'   #  0xC6 -> GREEK CAPITAL LETTER ZETA
+    u'\u0397'   #  0xC7 -> GREEK CAPITAL LETTER ETA
+    u'\u0398'   #  0xC8 -> GREEK CAPITAL LETTER THETA
+    u'\u0399'   #  0xC9 -> GREEK CAPITAL LETTER IOTA
+    u'\u039a'   #  0xCA -> GREEK CAPITAL LETTER KAPPA
+    u'\u039b'   #  0xCB -> GREEK CAPITAL LETTER LAMDA
+    u'\u039c'   #  0xCC -> GREEK CAPITAL LETTER MU
+    u'\u039d'   #  0xCD -> GREEK CAPITAL LETTER NU
+    u'\u039e'   #  0xCE -> GREEK CAPITAL LETTER XI
+    u'\u039f'   #  0xCF -> GREEK CAPITAL LETTER OMICRON
+    u'\u03a0'   #  0xD0 -> GREEK CAPITAL LETTER PI
+    u'\u03a1'   #  0xD1 -> GREEK CAPITAL LETTER RHO
+    u'\ufffe'   #  0xD2 -> UNDEFINED
+    u'\u03a3'   #  0xD3 -> GREEK CAPITAL LETTER SIGMA
+    u'\u03a4'   #  0xD4 -> GREEK CAPITAL LETTER TAU
+    u'\u03a5'   #  0xD5 -> GREEK CAPITAL LETTER UPSILON
+    u'\u03a6'   #  0xD6 -> GREEK CAPITAL LETTER PHI
+    u'\u03a7'   #  0xD7 -> GREEK CAPITAL LETTER CHI
+    u'\u03a8'   #  0xD8 -> GREEK CAPITAL LETTER PSI
+    u'\u03a9'   #  0xD9 -> GREEK CAPITAL LETTER OMEGA
+    u'\u03aa'   #  0xDA -> GREEK CAPITAL LETTER IOTA WITH DIALYTIKA
+    u'\u03ab'   #  0xDB -> GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA
+    u'\u03ac'   #  0xDC -> GREEK SMALL LETTER ALPHA WITH TONOS
+    u'\u03ad'   #  0xDD -> GREEK SMALL LETTER EPSILON WITH TONOS
+    u'\u03ae'   #  0xDE -> GREEK SMALL LETTER ETA WITH TONOS
+    u'\u03af'   #  0xDF -> GREEK SMALL LETTER IOTA WITH TONOS
+    u'\u03b0'   #  0xE0 -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS
+    u'\u03b1'   #  0xE1 -> GREEK SMALL LETTER ALPHA
+    u'\u03b2'   #  0xE2 -> GREEK SMALL LETTER BETA
+    u'\u03b3'   #  0xE3 -> GREEK SMALL LETTER GAMMA
+    u'\u03b4'   #  0xE4 -> GREEK SMALL LETTER DELTA
+    u'\u03b5'   #  0xE5 -> GREEK SMALL LETTER EPSILON
+    u'\u03b6'   #  0xE6 -> GREEK SMALL LETTER ZETA
+    u'\u03b7'   #  0xE7 -> GREEK SMALL LETTER ETA
+    u'\u03b8'   #  0xE8 -> GREEK SMALL LETTER THETA
+    u'\u03b9'   #  0xE9 -> GREEK SMALL LETTER IOTA
+    u'\u03ba'   #  0xEA -> GREEK SMALL LETTER KAPPA
+    u'\u03bb'   #  0xEB -> GREEK SMALL LETTER LAMDA
+    u'\u03bc'   #  0xEC -> GREEK SMALL LETTER MU
+    u'\u03bd'   #  0xED -> GREEK SMALL LETTER NU
+    u'\u03be'   #  0xEE -> GREEK SMALL LETTER XI
+    u'\u03bf'   #  0xEF -> GREEK SMALL LETTER OMICRON
+    u'\u03c0'   #  0xF0 -> GREEK SMALL LETTER PI
+    u'\u03c1'   #  0xF1 -> GREEK SMALL LETTER RHO
+    u'\u03c2'   #  0xF2 -> GREEK SMALL LETTER FINAL SIGMA
+    u'\u03c3'   #  0xF3 -> GREEK SMALL LETTER SIGMA
+    u'\u03c4'   #  0xF4 -> GREEK SMALL LETTER TAU
+    u'\u03c5'   #  0xF5 -> GREEK SMALL LETTER UPSILON
+    u'\u03c6'   #  0xF6 -> GREEK SMALL LETTER PHI
+    u'\u03c7'   #  0xF7 -> GREEK SMALL LETTER CHI
+    u'\u03c8'   #  0xF8 -> GREEK SMALL LETTER PSI
+    u'\u03c9'   #  0xF9 -> GREEK SMALL LETTER OMEGA
+    u'\u03ca'   #  0xFA -> GREEK SMALL LETTER IOTA WITH DIALYTIKA
+    u'\u03cb'   #  0xFB -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA
+    u'\u03cc'   #  0xFC -> GREEK SMALL LETTER OMICRON WITH TONOS
+    u'\u03cd'   #  0xFD -> GREEK SMALL LETTER UPSILON WITH TONOS
+    u'\u03ce'   #  0xFE -> GREEK SMALL LETTER OMEGA WITH TONOS
+    u'\ufffe'   #  0xFF -> UNDEFINED
+)
+
+### Encoding table
+encoding_table=codecs.charmap_build(decoding_table)

Added: vendor/Python/current/Lib/encodings/cp1254.py
===================================================================
--- vendor/Python/current/Lib/encodings/cp1254.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/cp1254.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,307 @@
+""" Python Character Mapping Codec cp1254 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1254.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_table)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_table)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='cp1254',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x00 -> NULL
+    u'\x01'     #  0x01 -> START OF HEADING
+    u'\x02'     #  0x02 -> START OF TEXT
+    u'\x03'     #  0x03 -> END OF TEXT
+    u'\x04'     #  0x04 -> END OF TRANSMISSION
+    u'\x05'     #  0x05 -> ENQUIRY
+    u'\x06'     #  0x06 -> ACKNOWLEDGE
+    u'\x07'     #  0x07 -> BELL
+    u'\x08'     #  0x08 -> BACKSPACE
+    u'\t'       #  0x09 -> HORIZONTAL TABULATION
+    u'\n'       #  0x0A -> LINE FEED
+    u'\x0b'     #  0x0B -> VERTICAL TABULATION
+    u'\x0c'     #  0x0C -> FORM FEED
+    u'\r'       #  0x0D -> CARRIAGE RETURN
+    u'\x0e'     #  0x0E -> SHIFT OUT
+    u'\x0f'     #  0x0F -> SHIFT IN
+    u'\x10'     #  0x10 -> DATA LINK ESCAPE
+    u'\x11'     #  0x11 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x12 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x13 -> DEVICE CONTROL THREE
+    u'\x14'     #  0x14 -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x15 -> NEGATIVE ACKNOWLEDGE
+    u'\x16'     #  0x16 -> SYNCHRONOUS IDLE
+    u'\x17'     #  0x17 -> END OF TRANSMISSION BLOCK
+    u'\x18'     #  0x18 -> CANCEL
+    u'\x19'     #  0x19 -> END OF MEDIUM
+    u'\x1a'     #  0x1A -> SUBSTITUTE
+    u'\x1b'     #  0x1B -> ESCAPE
+    u'\x1c'     #  0x1C -> FILE SEPARATOR
+    u'\x1d'     #  0x1D -> GROUP SEPARATOR
+    u'\x1e'     #  0x1E -> RECORD SEPARATOR
+    u'\x1f'     #  0x1F -> UNIT SEPARATOR
+    u' '        #  0x20 -> SPACE
+    u'!'        #  0x21 -> EXCLAMATION MARK
+    u'"'        #  0x22 -> QUOTATION MARK
+    u'#'        #  0x23 -> NUMBER SIGN
+    u'$'        #  0x24 -> DOLLAR SIGN
+    u'%'        #  0x25 -> PERCENT SIGN
+    u'&'        #  0x26 -> AMPERSAND
+    u"'"        #  0x27 -> APOSTROPHE
+    u'('        #  0x28 -> LEFT PARENTHESIS
+    u')'        #  0x29 -> RIGHT PARENTHESIS
+    u'*'        #  0x2A -> ASTERISK
+    u'+'        #  0x2B -> PLUS SIGN
+    u','        #  0x2C -> COMMA
+    u'-'        #  0x2D -> HYPHEN-MINUS
+    u'.'        #  0x2E -> FULL STOP
+    u'/'        #  0x2F -> SOLIDUS
+    u'0'        #  0x30 -> DIGIT ZERO
+    u'1'        #  0x31 -> DIGIT ONE
+    u'2'        #  0x32 -> DIGIT TWO
+    u'3'        #  0x33 -> DIGIT THREE
+    u'4'        #  0x34 -> DIGIT FOUR
+    u'5'        #  0x35 -> DIGIT FIVE
+    u'6'        #  0x36 -> DIGIT SIX
+    u'7'        #  0x37 -> DIGIT SEVEN
+    u'8'        #  0x38 -> DIGIT EIGHT
+    u'9'        #  0x39 -> DIGIT NINE
+    u':'        #  0x3A -> COLON
+    u';'        #  0x3B -> SEMICOLON
+    u'<'        #  0x3C -> LESS-THAN SIGN
+    u'='        #  0x3D -> EQUALS SIGN
+    u'>'        #  0x3E -> GREATER-THAN SIGN
+    u'?'        #  0x3F -> QUESTION MARK
+    u'@'        #  0x40 -> COMMERCIAL AT
+    u'A'        #  0x41 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x42 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x43 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x44 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x45 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x46 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x47 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x48 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x49 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x4A -> LATIN CAPITAL LETTER J
+    u'K'        #  0x4B -> LATIN CAPITAL LETTER K
+    u'L'        #  0x4C -> LATIN CAPITAL LETTER L
+    u'M'        #  0x4D -> LATIN CAPITAL LETTER M
+    u'N'        #  0x4E -> LATIN CAPITAL LETTER N
+    u'O'        #  0x4F -> LATIN CAPITAL LETTER O
+    u'P'        #  0x50 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x51 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x52 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x53 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x54 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x55 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x56 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x57 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x58 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x59 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x5A -> LATIN CAPITAL LETTER Z
+    u'['        #  0x5B -> LEFT SQUARE BRACKET
+    u'\\'       #  0x5C -> REVERSE SOLIDUS
+    u']'        #  0x5D -> RIGHT SQUARE BRACKET
+    u'^'        #  0x5E -> CIRCUMFLEX ACCENT
+    u'_'        #  0x5F -> LOW LINE
+    u'`'        #  0x60 -> GRAVE ACCENT
+    u'a'        #  0x61 -> LATIN SMALL LETTER A
+    u'b'        #  0x62 -> LATIN SMALL LETTER B
+    u'c'        #  0x63 -> LATIN SMALL LETTER C
+    u'd'        #  0x64 -> LATIN SMALL LETTER D
+    u'e'        #  0x65 -> LATIN SMALL LETTER E
+    u'f'        #  0x66 -> LATIN SMALL LETTER F
+    u'g'        #  0x67 -> LATIN SMALL LETTER G
+    u'h'        #  0x68 -> LATIN SMALL LETTER H
+    u'i'        #  0x69 -> LATIN SMALL LETTER I
+    u'j'        #  0x6A -> LATIN SMALL LETTER J
+    u'k'        #  0x6B -> LATIN SMALL LETTER K
+    u'l'        #  0x6C -> LATIN SMALL LETTER L
+    u'm'        #  0x6D -> LATIN SMALL LETTER M
+    u'n'        #  0x6E -> LATIN SMALL LETTER N
+    u'o'        #  0x6F -> LATIN SMALL LETTER O
+    u'p'        #  0x70 -> LATIN SMALL LETTER P
+    u'q'        #  0x71 -> LATIN SMALL LETTER Q
+    u'r'        #  0x72 -> LATIN SMALL LETTER R
+    u's'        #  0x73 -> LATIN SMALL LETTER S
+    u't'        #  0x74 -> LATIN SMALL LETTER T
+    u'u'        #  0x75 -> LATIN SMALL LETTER U
+    u'v'        #  0x76 -> LATIN SMALL LETTER V
+    u'w'        #  0x77 -> LATIN SMALL LETTER W
+    u'x'        #  0x78 -> LATIN SMALL LETTER X
+    u'y'        #  0x79 -> LATIN SMALL LETTER Y
+    u'z'        #  0x7A -> LATIN SMALL LETTER Z
+    u'{'        #  0x7B -> LEFT CURLY BRACKET
+    u'|'        #  0x7C -> VERTICAL LINE
+    u'}'        #  0x7D -> RIGHT CURLY BRACKET
+    u'~'        #  0x7E -> TILDE
+    u'\x7f'     #  0x7F -> DELETE
+    u'\u20ac'   #  0x80 -> EURO SIGN
+    u'\ufffe'   #  0x81 -> UNDEFINED
+    u'\u201a'   #  0x82 -> SINGLE LOW-9 QUOTATION MARK
+    u'\u0192'   #  0x83 -> LATIN SMALL LETTER F WITH HOOK
+    u'\u201e'   #  0x84 -> DOUBLE LOW-9 QUOTATION MARK
+    u'\u2026'   #  0x85 -> HORIZONTAL ELLIPSIS
+    u'\u2020'   #  0x86 -> DAGGER
+    u'\u2021'   #  0x87 -> DOUBLE DAGGER
+    u'\u02c6'   #  0x88 -> MODIFIER LETTER CIRCUMFLEX ACCENT
+    u'\u2030'   #  0x89 -> PER MILLE SIGN
+    u'\u0160'   #  0x8A -> LATIN CAPITAL LETTER S WITH CARON
+    u'\u2039'   #  0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+    u'\u0152'   #  0x8C -> LATIN CAPITAL LIGATURE OE
+    u'\ufffe'   #  0x8D -> UNDEFINED
+    u'\ufffe'   #  0x8E -> UNDEFINED
+    u'\ufffe'   #  0x8F -> UNDEFINED
+    u'\ufffe'   #  0x90 -> UNDEFINED
+    u'\u2018'   #  0x91 -> LEFT SINGLE QUOTATION MARK
+    u'\u2019'   #  0x92 -> RIGHT SINGLE QUOTATION MARK
+    u'\u201c'   #  0x93 -> LEFT DOUBLE QUOTATION MARK
+    u'\u201d'   #  0x94 -> RIGHT DOUBLE QUOTATION MARK
+    u'\u2022'   #  0x95 -> BULLET
+    u'\u2013'   #  0x96 -> EN DASH
+    u'\u2014'   #  0x97 -> EM DASH
+    u'\u02dc'   #  0x98 -> SMALL TILDE
+    u'\u2122'   #  0x99 -> TRADE MARK SIGN
+    u'\u0161'   #  0x9A -> LATIN SMALL LETTER S WITH CARON
+    u'\u203a'   #  0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+    u'\u0153'   #  0x9C -> LATIN SMALL LIGATURE OE
+    u'\ufffe'   #  0x9D -> UNDEFINED
+    u'\ufffe'   #  0x9E -> UNDEFINED
+    u'\u0178'   #  0x9F -> LATIN CAPITAL LETTER Y WITH DIAERESIS
+    u'\xa0'     #  0xA0 -> NO-BREAK SPACE
+    u'\xa1'     #  0xA1 -> INVERTED EXCLAMATION MARK
+    u'\xa2'     #  0xA2 -> CENT SIGN
+    u'\xa3'     #  0xA3 -> POUND SIGN
+    u'\xa4'     #  0xA4 -> CURRENCY SIGN
+    u'\xa5'     #  0xA5 -> YEN SIGN
+    u'\xa6'     #  0xA6 -> BROKEN BAR
+    u'\xa7'     #  0xA7 -> SECTION SIGN
+    u'\xa8'     #  0xA8 -> DIAERESIS
+    u'\xa9'     #  0xA9 -> COPYRIGHT SIGN
+    u'\xaa'     #  0xAA -> FEMININE ORDINAL INDICATOR
+    u'\xab'     #  0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xac'     #  0xAC -> NOT SIGN
+    u'\xad'     #  0xAD -> SOFT HYPHEN
+    u'\xae'     #  0xAE -> REGISTERED SIGN
+    u'\xaf'     #  0xAF -> MACRON
+    u'\xb0'     #  0xB0 -> DEGREE SIGN
+    u'\xb1'     #  0xB1 -> PLUS-MINUS SIGN
+    u'\xb2'     #  0xB2 -> SUPERSCRIPT TWO
+    u'\xb3'     #  0xB3 -> SUPERSCRIPT THREE
+    u'\xb4'     #  0xB4 -> ACUTE ACCENT
+    u'\xb5'     #  0xB5 -> MICRO SIGN
+    u'\xb6'     #  0xB6 -> PILCROW SIGN
+    u'\xb7'     #  0xB7 -> MIDDLE DOT
+    u'\xb8'     #  0xB8 -> CEDILLA
+    u'\xb9'     #  0xB9 -> SUPERSCRIPT ONE
+    u'\xba'     #  0xBA -> MASCULINE ORDINAL INDICATOR
+    u'\xbb'     #  0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xbc'     #  0xBC -> VULGAR FRACTION ONE QUARTER
+    u'\xbd'     #  0xBD -> VULGAR FRACTION ONE HALF
+    u'\xbe'     #  0xBE -> VULGAR FRACTION THREE QUARTERS
+    u'\xbf'     #  0xBF -> INVERTED QUESTION MARK
+    u'\xc0'     #  0xC0 -> LATIN CAPITAL LETTER A WITH GRAVE
+    u'\xc1'     #  0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE
+    u'\xc2'     #  0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+    u'\xc3'     #  0xC3 -> LATIN CAPITAL LETTER A WITH TILDE
+    u'\xc4'     #  0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS
+    u'\xc5'     #  0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE
+    u'\xc6'     #  0xC6 -> LATIN CAPITAL LETTER AE
+    u'\xc7'     #  0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA
+    u'\xc8'     #  0xC8 -> LATIN CAPITAL LETTER E WITH GRAVE
+    u'\xc9'     #  0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE
+    u'\xca'     #  0xCA -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+    u'\xcb'     #  0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS
+    u'\xcc'     #  0xCC -> LATIN CAPITAL LETTER I WITH GRAVE
+    u'\xcd'     #  0xCD -> LATIN CAPITAL LETTER I WITH ACUTE
+    u'\xce'     #  0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+    u'\xcf'     #  0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS
+    u'\u011e'   #  0xD0 -> LATIN CAPITAL LETTER G WITH BREVE
+    u'\xd1'     #  0xD1 -> LATIN CAPITAL LETTER N WITH TILDE
+    u'\xd2'     #  0xD2 -> LATIN CAPITAL LETTER O WITH GRAVE
+    u'\xd3'     #  0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE
+    u'\xd4'     #  0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+    u'\xd5'     #  0xD5 -> LATIN CAPITAL LETTER O WITH TILDE
+    u'\xd6'     #  0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS
+    u'\xd7'     #  0xD7 -> MULTIPLICATION SIGN
+    u'\xd8'     #  0xD8 -> LATIN CAPITAL LETTER O WITH STROKE
+    u'\xd9'     #  0xD9 -> LATIN CAPITAL LETTER U WITH GRAVE
+    u'\xda'     #  0xDA -> LATIN CAPITAL LETTER U WITH ACUTE
+    u'\xdb'     #  0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+    u'\xdc'     #  0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS
+    u'\u0130'   #  0xDD -> LATIN CAPITAL LETTER I WITH DOT ABOVE
+    u'\u015e'   #  0xDE -> LATIN CAPITAL LETTER S WITH CEDILLA
+    u'\xdf'     #  0xDF -> LATIN SMALL LETTER SHARP S
+    u'\xe0'     #  0xE0 -> LATIN SMALL LETTER A WITH GRAVE
+    u'\xe1'     #  0xE1 -> LATIN SMALL LETTER A WITH ACUTE
+    u'\xe2'     #  0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX
+    u'\xe3'     #  0xE3 -> LATIN SMALL LETTER A WITH TILDE
+    u'\xe4'     #  0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS
+    u'\xe5'     #  0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE
+    u'\xe6'     #  0xE6 -> LATIN SMALL LETTER AE
+    u'\xe7'     #  0xE7 -> LATIN SMALL LETTER C WITH CEDILLA
+    u'\xe8'     #  0xE8 -> LATIN SMALL LETTER E WITH GRAVE
+    u'\xe9'     #  0xE9 -> LATIN SMALL LETTER E WITH ACUTE
+    u'\xea'     #  0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX
+    u'\xeb'     #  0xEB -> LATIN SMALL LETTER E WITH DIAERESIS
+    u'\xec'     #  0xEC -> LATIN SMALL LETTER I WITH GRAVE
+    u'\xed'     #  0xED -> LATIN SMALL LETTER I WITH ACUTE
+    u'\xee'     #  0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX
+    u'\xef'     #  0xEF -> LATIN SMALL LETTER I WITH DIAERESIS
+    u'\u011f'   #  0xF0 -> LATIN SMALL LETTER G WITH BREVE
+    u'\xf1'     #  0xF1 -> LATIN SMALL LETTER N WITH TILDE
+    u'\xf2'     #  0xF2 -> LATIN SMALL LETTER O WITH GRAVE
+    u'\xf3'     #  0xF3 -> LATIN SMALL LETTER O WITH ACUTE
+    u'\xf4'     #  0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX
+    u'\xf5'     #  0xF5 -> LATIN SMALL LETTER O WITH TILDE
+    u'\xf6'     #  0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS
+    u'\xf7'     #  0xF7 -> DIVISION SIGN
+    u'\xf8'     #  0xF8 -> LATIN SMALL LETTER O WITH STROKE
+    u'\xf9'     #  0xF9 -> LATIN SMALL LETTER U WITH GRAVE
+    u'\xfa'     #  0xFA -> LATIN SMALL LETTER U WITH ACUTE
+    u'\xfb'     #  0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX
+    u'\xfc'     #  0xFC -> LATIN SMALL LETTER U WITH DIAERESIS
+    u'\u0131'   #  0xFD -> LATIN SMALL LETTER DOTLESS I
+    u'\u015f'   #  0xFE -> LATIN SMALL LETTER S WITH CEDILLA
+    u'\xff'     #  0xFF -> LATIN SMALL LETTER Y WITH DIAERESIS
+)
+
+### Encoding table
+encoding_table=codecs.charmap_build(decoding_table)

Added: vendor/Python/current/Lib/encodings/cp1255.py
===================================================================
--- vendor/Python/current/Lib/encodings/cp1255.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/cp1255.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,307 @@
+""" Python Character Mapping Codec cp1255 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1255.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_table)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_table)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='cp1255',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x00 -> NULL
+    u'\x01'     #  0x01 -> START OF HEADING
+    u'\x02'     #  0x02 -> START OF TEXT
+    u'\x03'     #  0x03 -> END OF TEXT
+    u'\x04'     #  0x04 -> END OF TRANSMISSION
+    u'\x05'     #  0x05 -> ENQUIRY
+    u'\x06'     #  0x06 -> ACKNOWLEDGE
+    u'\x07'     #  0x07 -> BELL
+    u'\x08'     #  0x08 -> BACKSPACE
+    u'\t'       #  0x09 -> HORIZONTAL TABULATION
+    u'\n'       #  0x0A -> LINE FEED
+    u'\x0b'     #  0x0B -> VERTICAL TABULATION
+    u'\x0c'     #  0x0C -> FORM FEED
+    u'\r'       #  0x0D -> CARRIAGE RETURN
+    u'\x0e'     #  0x0E -> SHIFT OUT
+    u'\x0f'     #  0x0F -> SHIFT IN
+    u'\x10'     #  0x10 -> DATA LINK ESCAPE
+    u'\x11'     #  0x11 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x12 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x13 -> DEVICE CONTROL THREE
+    u'\x14'     #  0x14 -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x15 -> NEGATIVE ACKNOWLEDGE
+    u'\x16'     #  0x16 -> SYNCHRONOUS IDLE
+    u'\x17'     #  0x17 -> END OF TRANSMISSION BLOCK
+    u'\x18'     #  0x18 -> CANCEL
+    u'\x19'     #  0x19 -> END OF MEDIUM
+    u'\x1a'     #  0x1A -> SUBSTITUTE
+    u'\x1b'     #  0x1B -> ESCAPE
+    u'\x1c'     #  0x1C -> FILE SEPARATOR
+    u'\x1d'     #  0x1D -> GROUP SEPARATOR
+    u'\x1e'     #  0x1E -> RECORD SEPARATOR
+    u'\x1f'     #  0x1F -> UNIT SEPARATOR
+    u' '        #  0x20 -> SPACE
+    u'!'        #  0x21 -> EXCLAMATION MARK
+    u'"'        #  0x22 -> QUOTATION MARK
+    u'#'        #  0x23 -> NUMBER SIGN
+    u'$'        #  0x24 -> DOLLAR SIGN
+    u'%'        #  0x25 -> PERCENT SIGN
+    u'&'        #  0x26 -> AMPERSAND
+    u"'"        #  0x27 -> APOSTROPHE
+    u'('        #  0x28 -> LEFT PARENTHESIS
+    u')'        #  0x29 -> RIGHT PARENTHESIS
+    u'*'        #  0x2A -> ASTERISK
+    u'+'        #  0x2B -> PLUS SIGN
+    u','        #  0x2C -> COMMA
+    u'-'        #  0x2D -> HYPHEN-MINUS
+    u'.'        #  0x2E -> FULL STOP
+    u'/'        #  0x2F -> SOLIDUS
+    u'0'        #  0x30 -> DIGIT ZERO
+    u'1'        #  0x31 -> DIGIT ONE
+    u'2'        #  0x32 -> DIGIT TWO
+    u'3'        #  0x33 -> DIGIT THREE
+    u'4'        #  0x34 -> DIGIT FOUR
+    u'5'        #  0x35 -> DIGIT FIVE
+    u'6'        #  0x36 -> DIGIT SIX
+    u'7'        #  0x37 -> DIGIT SEVEN
+    u'8'        #  0x38 -> DIGIT EIGHT
+    u'9'        #  0x39 -> DIGIT NINE
+    u':'        #  0x3A -> COLON
+    u';'        #  0x3B -> SEMICOLON
+    u'<'        #  0x3C -> LESS-THAN SIGN
+    u'='        #  0x3D -> EQUALS SIGN
+    u'>'        #  0x3E -> GREATER-THAN SIGN
+    u'?'        #  0x3F -> QUESTION MARK
+    u'@'        #  0x40 -> COMMERCIAL AT
+    u'A'        #  0x41 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x42 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x43 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x44 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x45 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x46 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x47 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x48 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x49 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x4A -> LATIN CAPITAL LETTER J
+    u'K'        #  0x4B -> LATIN CAPITAL LETTER K
+    u'L'        #  0x4C -> LATIN CAPITAL LETTER L
+    u'M'        #  0x4D -> LATIN CAPITAL LETTER M
+    u'N'        #  0x4E -> LATIN CAPITAL LETTER N
+    u'O'        #  0x4F -> LATIN CAPITAL LETTER O
+    u'P'        #  0x50 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x51 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x52 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x53 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x54 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x55 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x56 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x57 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x58 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x59 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x5A -> LATIN CAPITAL LETTER Z
+    u'['        #  0x5B -> LEFT SQUARE BRACKET
+    u'\\'       #  0x5C -> REVERSE SOLIDUS
+    u']'        #  0x5D -> RIGHT SQUARE BRACKET
+    u'^'        #  0x5E -> CIRCUMFLEX ACCENT
+    u'_'        #  0x5F -> LOW LINE
+    u'`'        #  0x60 -> GRAVE ACCENT
+    u'a'        #  0x61 -> LATIN SMALL LETTER A
+    u'b'        #  0x62 -> LATIN SMALL LETTER B
+    u'c'        #  0x63 -> LATIN SMALL LETTER C
+    u'd'        #  0x64 -> LATIN SMALL LETTER D
+    u'e'        #  0x65 -> LATIN SMALL LETTER E
+    u'f'        #  0x66 -> LATIN SMALL LETTER F
+    u'g'        #  0x67 -> LATIN SMALL LETTER G
+    u'h'        #  0x68 -> LATIN SMALL LETTER H
+    u'i'        #  0x69 -> LATIN SMALL LETTER I
+    u'j'        #  0x6A -> LATIN SMALL LETTER J
+    u'k'        #  0x6B -> LATIN SMALL LETTER K
+    u'l'        #  0x6C -> LATIN SMALL LETTER L
+    u'm'        #  0x6D -> LATIN SMALL LETTER M
+    u'n'        #  0x6E -> LATIN SMALL LETTER N
+    u'o'        #  0x6F -> LATIN SMALL LETTER O
+    u'p'        #  0x70 -> LATIN SMALL LETTER P
+    u'q'        #  0x71 -> LATIN SMALL LETTER Q
+    u'r'        #  0x72 -> LATIN SMALL LETTER R
+    u's'        #  0x73 -> LATIN SMALL LETTER S
+    u't'        #  0x74 -> LATIN SMALL LETTER T
+    u'u'        #  0x75 -> LATIN SMALL LETTER U
+    u'v'        #  0x76 -> LATIN SMALL LETTER V
+    u'w'        #  0x77 -> LATIN SMALL LETTER W
+    u'x'        #  0x78 -> LATIN SMALL LETTER X
+    u'y'        #  0x79 -> LATIN SMALL LETTER Y
+    u'z'        #  0x7A -> LATIN SMALL LETTER Z
+    u'{'        #  0x7B -> LEFT CURLY BRACKET
+    u'|'        #  0x7C -> VERTICAL LINE
+    u'}'        #  0x7D -> RIGHT CURLY BRACKET
+    u'~'        #  0x7E -> TILDE
+    u'\x7f'     #  0x7F -> DELETE
+    u'\u20ac'   #  0x80 -> EURO SIGN
+    u'\ufffe'   #  0x81 -> UNDEFINED
+    u'\u201a'   #  0x82 -> SINGLE LOW-9 QUOTATION MARK
+    u'\u0192'   #  0x83 -> LATIN SMALL LETTER F WITH HOOK
+    u'\u201e'   #  0x84 -> DOUBLE LOW-9 QUOTATION MARK
+    u'\u2026'   #  0x85 -> HORIZONTAL ELLIPSIS
+    u'\u2020'   #  0x86 -> DAGGER
+    u'\u2021'   #  0x87 -> DOUBLE DAGGER
+    u'\u02c6'   #  0x88 -> MODIFIER LETTER CIRCUMFLEX ACCENT
+    u'\u2030'   #  0x89 -> PER MILLE SIGN
+    u'\ufffe'   #  0x8A -> UNDEFINED
+    u'\u2039'   #  0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+    u'\ufffe'   #  0x8C -> UNDEFINED
+    u'\ufffe'   #  0x8D -> UNDEFINED
+    u'\ufffe'   #  0x8E -> UNDEFINED
+    u'\ufffe'   #  0x8F -> UNDEFINED
+    u'\ufffe'   #  0x90 -> UNDEFINED
+    u'\u2018'   #  0x91 -> LEFT SINGLE QUOTATION MARK
+    u'\u2019'   #  0x92 -> RIGHT SINGLE QUOTATION MARK
+    u'\u201c'   #  0x93 -> LEFT DOUBLE QUOTATION MARK
+    u'\u201d'   #  0x94 -> RIGHT DOUBLE QUOTATION MARK
+    u'\u2022'   #  0x95 -> BULLET
+    u'\u2013'   #  0x96 -> EN DASH
+    u'\u2014'   #  0x97 -> EM DASH
+    u'\u02dc'   #  0x98 -> SMALL TILDE
+    u'\u2122'   #  0x99 -> TRADE MARK SIGN
+    u'\ufffe'   #  0x9A -> UNDEFINED
+    u'\u203a'   #  0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+    u'\ufffe'   #  0x9C -> UNDEFINED
+    u'\ufffe'   #  0x9D -> UNDEFINED
+    u'\ufffe'   #  0x9E -> UNDEFINED
+    u'\ufffe'   #  0x9F -> UNDEFINED
+    u'\xa0'     #  0xA0 -> NO-BREAK SPACE
+    u'\xa1'     #  0xA1 -> INVERTED EXCLAMATION MARK
+    u'\xa2'     #  0xA2 -> CENT SIGN
+    u'\xa3'     #  0xA3 -> POUND SIGN
+    u'\u20aa'   #  0xA4 -> NEW SHEQEL SIGN
+    u'\xa5'     #  0xA5 -> YEN SIGN
+    u'\xa6'     #  0xA6 -> BROKEN BAR
+    u'\xa7'     #  0xA7 -> SECTION SIGN
+    u'\xa8'     #  0xA8 -> DIAERESIS
+    u'\xa9'     #  0xA9 -> COPYRIGHT SIGN
+    u'\xd7'     #  0xAA -> MULTIPLICATION SIGN
+    u'\xab'     #  0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xac'     #  0xAC -> NOT SIGN
+    u'\xad'     #  0xAD -> SOFT HYPHEN
+    u'\xae'     #  0xAE -> REGISTERED SIGN
+    u'\xaf'     #  0xAF -> MACRON
+    u'\xb0'     #  0xB0 -> DEGREE SIGN
+    u'\xb1'     #  0xB1 -> PLUS-MINUS SIGN
+    u'\xb2'     #  0xB2 -> SUPERSCRIPT TWO
+    u'\xb3'     #  0xB3 -> SUPERSCRIPT THREE
+    u'\xb4'     #  0xB4 -> ACUTE ACCENT
+    u'\xb5'     #  0xB5 -> MICRO SIGN
+    u'\xb6'     #  0xB6 -> PILCROW SIGN
+    u'\xb7'     #  0xB7 -> MIDDLE DOT
+    u'\xb8'     #  0xB8 -> CEDILLA
+    u'\xb9'     #  0xB9 -> SUPERSCRIPT ONE
+    u'\xf7'     #  0xBA -> DIVISION SIGN
+    u'\xbb'     #  0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xbc'     #  0xBC -> VULGAR FRACTION ONE QUARTER
+    u'\xbd'     #  0xBD -> VULGAR FRACTION ONE HALF
+    u'\xbe'     #  0xBE -> VULGAR FRACTION THREE QUARTERS
+    u'\xbf'     #  0xBF -> INVERTED QUESTION MARK
+    u'\u05b0'   #  0xC0 -> HEBREW POINT SHEVA
+    u'\u05b1'   #  0xC1 -> HEBREW POINT HATAF SEGOL
+    u'\u05b2'   #  0xC2 -> HEBREW POINT HATAF PATAH
+    u'\u05b3'   #  0xC3 -> HEBREW POINT HATAF QAMATS
+    u'\u05b4'   #  0xC4 -> HEBREW POINT HIRIQ
+    u'\u05b5'   #  0xC5 -> HEBREW POINT TSERE
+    u'\u05b6'   #  0xC6 -> HEBREW POINT SEGOL
+    u'\u05b7'   #  0xC7 -> HEBREW POINT PATAH
+    u'\u05b8'   #  0xC8 -> HEBREW POINT QAMATS
+    u'\u05b9'   #  0xC9 -> HEBREW POINT HOLAM
+    u'\ufffe'   #  0xCA -> UNDEFINED
+    u'\u05bb'   #  0xCB -> HEBREW POINT QUBUTS
+    u'\u05bc'   #  0xCC -> HEBREW POINT DAGESH OR MAPIQ
+    u'\u05bd'   #  0xCD -> HEBREW POINT METEG
+    u'\u05be'   #  0xCE -> HEBREW PUNCTUATION MAQAF
+    u'\u05bf'   #  0xCF -> HEBREW POINT RAFE
+    u'\u05c0'   #  0xD0 -> HEBREW PUNCTUATION PASEQ
+    u'\u05c1'   #  0xD1 -> HEBREW POINT SHIN DOT
+    u'\u05c2'   #  0xD2 -> HEBREW POINT SIN DOT
+    u'\u05c3'   #  0xD3 -> HEBREW PUNCTUATION SOF PASUQ
+    u'\u05f0'   #  0xD4 -> HEBREW LIGATURE YIDDISH DOUBLE VAV
+    u'\u05f1'   #  0xD5 -> HEBREW LIGATURE YIDDISH VAV YOD
+    u'\u05f2'   #  0xD6 -> HEBREW LIGATURE YIDDISH DOUBLE YOD
+    u'\u05f3'   #  0xD7 -> HEBREW PUNCTUATION GERESH
+    u'\u05f4'   #  0xD8 -> HEBREW PUNCTUATION GERSHAYIM
+    u'\ufffe'   #  0xD9 -> UNDEFINED
+    u'\ufffe'   #  0xDA -> UNDEFINED
+    u'\ufffe'   #  0xDB -> UNDEFINED
+    u'\ufffe'   #  0xDC -> UNDEFINED
+    u'\ufffe'   #  0xDD -> UNDEFINED
+    u'\ufffe'   #  0xDE -> UNDEFINED
+    u'\ufffe'   #  0xDF -> UNDEFINED
+    u'\u05d0'   #  0xE0 -> HEBREW LETTER ALEF
+    u'\u05d1'   #  0xE1 -> HEBREW LETTER BET
+    u'\u05d2'   #  0xE2 -> HEBREW LETTER GIMEL
+    u'\u05d3'   #  0xE3 -> HEBREW LETTER DALET
+    u'\u05d4'   #  0xE4 -> HEBREW LETTER HE
+    u'\u05d5'   #  0xE5 -> HEBREW LETTER VAV
+    u'\u05d6'   #  0xE6 -> HEBREW LETTER ZAYIN
+    u'\u05d7'   #  0xE7 -> HEBREW LETTER HET
+    u'\u05d8'   #  0xE8 -> HEBREW LETTER TET
+    u'\u05d9'   #  0xE9 -> HEBREW LETTER YOD
+    u'\u05da'   #  0xEA -> HEBREW LETTER FINAL KAF
+    u'\u05db'   #  0xEB -> HEBREW LETTER KAF
+    u'\u05dc'   #  0xEC -> HEBREW LETTER LAMED
+    u'\u05dd'   #  0xED -> HEBREW LETTER FINAL MEM
+    u'\u05de'   #  0xEE -> HEBREW LETTER MEM
+    u'\u05df'   #  0xEF -> HEBREW LETTER FINAL NUN
+    u'\u05e0'   #  0xF0 -> HEBREW LETTER NUN
+    u'\u05e1'   #  0xF1 -> HEBREW LETTER SAMEKH
+    u'\u05e2'   #  0xF2 -> HEBREW LETTER AYIN
+    u'\u05e3'   #  0xF3 -> HEBREW LETTER FINAL PE
+    u'\u05e4'   #  0xF4 -> HEBREW LETTER PE
+    u'\u05e5'   #  0xF5 -> HEBREW LETTER FINAL TSADI
+    u'\u05e6'   #  0xF6 -> HEBREW LETTER TSADI
+    u'\u05e7'   #  0xF7 -> HEBREW LETTER QOF
+    u'\u05e8'   #  0xF8 -> HEBREW LETTER RESH
+    u'\u05e9'   #  0xF9 -> HEBREW LETTER SHIN
+    u'\u05ea'   #  0xFA -> HEBREW LETTER TAV
+    u'\ufffe'   #  0xFB -> UNDEFINED
+    u'\ufffe'   #  0xFC -> UNDEFINED
+    u'\u200e'   #  0xFD -> LEFT-TO-RIGHT MARK
+    u'\u200f'   #  0xFE -> RIGHT-TO-LEFT MARK
+    u'\ufffe'   #  0xFF -> UNDEFINED
+)
+
+### Encoding table
+encoding_table=codecs.charmap_build(decoding_table)

Added: vendor/Python/current/Lib/encodings/cp1256.py
===================================================================
--- vendor/Python/current/Lib/encodings/cp1256.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/cp1256.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,307 @@
+""" Python Character Mapping Codec cp1256 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1256.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_table)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_table)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='cp1256',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x00 -> NULL
+    u'\x01'     #  0x01 -> START OF HEADING
+    u'\x02'     #  0x02 -> START OF TEXT
+    u'\x03'     #  0x03 -> END OF TEXT
+    u'\x04'     #  0x04 -> END OF TRANSMISSION
+    u'\x05'     #  0x05 -> ENQUIRY
+    u'\x06'     #  0x06 -> ACKNOWLEDGE
+    u'\x07'     #  0x07 -> BELL
+    u'\x08'     #  0x08 -> BACKSPACE
+    u'\t'       #  0x09 -> HORIZONTAL TABULATION
+    u'\n'       #  0x0A -> LINE FEED
+    u'\x0b'     #  0x0B -> VERTICAL TABULATION
+    u'\x0c'     #  0x0C -> FORM FEED
+    u'\r'       #  0x0D -> CARRIAGE RETURN
+    u'\x0e'     #  0x0E -> SHIFT OUT
+    u'\x0f'     #  0x0F -> SHIFT IN
+    u'\x10'     #  0x10 -> DATA LINK ESCAPE
+    u'\x11'     #  0x11 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x12 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x13 -> DEVICE CONTROL THREE
+    u'\x14'     #  0x14 -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x15 -> NEGATIVE ACKNOWLEDGE
+    u'\x16'     #  0x16 -> SYNCHRONOUS IDLE
+    u'\x17'     #  0x17 -> END OF TRANSMISSION BLOCK
+    u'\x18'     #  0x18 -> CANCEL
+    u'\x19'     #  0x19 -> END OF MEDIUM
+    u'\x1a'     #  0x1A -> SUBSTITUTE
+    u'\x1b'     #  0x1B -> ESCAPE
+    u'\x1c'     #  0x1C -> FILE SEPARATOR
+    u'\x1d'     #  0x1D -> GROUP SEPARATOR
+    u'\x1e'     #  0x1E -> RECORD SEPARATOR
+    u'\x1f'     #  0x1F -> UNIT SEPARATOR
+    u' '        #  0x20 -> SPACE
+    u'!'        #  0x21 -> EXCLAMATION MARK
+    u'"'        #  0x22 -> QUOTATION MARK
+    u'#'        #  0x23 -> NUMBER SIGN
+    u'$'        #  0x24 -> DOLLAR SIGN
+    u'%'        #  0x25 -> PERCENT SIGN
+    u'&'        #  0x26 -> AMPERSAND
+    u"'"        #  0x27 -> APOSTROPHE
+    u'('        #  0x28 -> LEFT PARENTHESIS
+    u')'        #  0x29 -> RIGHT PARENTHESIS
+    u'*'        #  0x2A -> ASTERISK
+    u'+'        #  0x2B -> PLUS SIGN
+    u','        #  0x2C -> COMMA
+    u'-'        #  0x2D -> HYPHEN-MINUS
+    u'.'        #  0x2E -> FULL STOP
+    u'/'        #  0x2F -> SOLIDUS
+    u'0'        #  0x30 -> DIGIT ZERO
+    u'1'        #  0x31 -> DIGIT ONE
+    u'2'        #  0x32 -> DIGIT TWO
+    u'3'        #  0x33 -> DIGIT THREE
+    u'4'        #  0x34 -> DIGIT FOUR
+    u'5'        #  0x35 -> DIGIT FIVE
+    u'6'        #  0x36 -> DIGIT SIX
+    u'7'        #  0x37 -> DIGIT SEVEN
+    u'8'        #  0x38 -> DIGIT EIGHT
+    u'9'        #  0x39 -> DIGIT NINE
+    u':'        #  0x3A -> COLON
+    u';'        #  0x3B -> SEMICOLON
+    u'<'        #  0x3C -> LESS-THAN SIGN
+    u'='        #  0x3D -> EQUALS SIGN
+    u'>'        #  0x3E -> GREATER-THAN SIGN
+    u'?'        #  0x3F -> QUESTION MARK
+    u'@'        #  0x40 -> COMMERCIAL AT
+    u'A'        #  0x41 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x42 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x43 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x44 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x45 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x46 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x47 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x48 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x49 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x4A -> LATIN CAPITAL LETTER J
+    u'K'        #  0x4B -> LATIN CAPITAL LETTER K
+    u'L'        #  0x4C -> LATIN CAPITAL LETTER L
+    u'M'        #  0x4D -> LATIN CAPITAL LETTER M
+    u'N'        #  0x4E -> LATIN CAPITAL LETTER N
+    u'O'        #  0x4F -> LATIN CAPITAL LETTER O
+    u'P'        #  0x50 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x51 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x52 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x53 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x54 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x55 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x56 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x57 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x58 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x59 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x5A -> LATIN CAPITAL LETTER Z
+    u'['        #  0x5B -> LEFT SQUARE BRACKET
+    u'\\'       #  0x5C -> REVERSE SOLIDUS
+    u']'        #  0x5D -> RIGHT SQUARE BRACKET
+    u'^'        #  0x5E -> CIRCUMFLEX ACCENT
+    u'_'        #  0x5F -> LOW LINE
+    u'`'        #  0x60 -> GRAVE ACCENT
+    u'a'        #  0x61 -> LATIN SMALL LETTER A
+    u'b'        #  0x62 -> LATIN SMALL LETTER B
+    u'c'        #  0x63 -> LATIN SMALL LETTER C
+    u'd'        #  0x64 -> LATIN SMALL LETTER D
+    u'e'        #  0x65 -> LATIN SMALL LETTER E
+    u'f'        #  0x66 -> LATIN SMALL LETTER F
+    u'g'        #  0x67 -> LATIN SMALL LETTER G
+    u'h'        #  0x68 -> LATIN SMALL LETTER H
+    u'i'        #  0x69 -> LATIN SMALL LETTER I
+    u'j'        #  0x6A -> LATIN SMALL LETTER J
+    u'k'        #  0x6B -> LATIN SMALL LETTER K
+    u'l'        #  0x6C -> LATIN SMALL LETTER L
+    u'm'        #  0x6D -> LATIN SMALL LETTER M
+    u'n'        #  0x6E -> LATIN SMALL LETTER N
+    u'o'        #  0x6F -> LATIN SMALL LETTER O
+    u'p'        #  0x70 -> LATIN SMALL LETTER P
+    u'q'        #  0x71 -> LATIN SMALL LETTER Q
+    u'r'        #  0x72 -> LATIN SMALL LETTER R
+    u's'        #  0x73 -> LATIN SMALL LETTER S
+    u't'        #  0x74 -> LATIN SMALL LETTER T
+    u'u'        #  0x75 -> LATIN SMALL LETTER U
+    u'v'        #  0x76 -> LATIN SMALL LETTER V
+    u'w'        #  0x77 -> LATIN SMALL LETTER W
+    u'x'        #  0x78 -> LATIN SMALL LETTER X
+    u'y'        #  0x79 -> LATIN SMALL LETTER Y
+    u'z'        #  0x7A -> LATIN SMALL LETTER Z
+    u'{'        #  0x7B -> LEFT CURLY BRACKET
+    u'|'        #  0x7C -> VERTICAL LINE
+    u'}'        #  0x7D -> RIGHT CURLY BRACKET
+    u'~'        #  0x7E -> TILDE
+    u'\x7f'     #  0x7F -> DELETE
+    u'\u20ac'   #  0x80 -> EURO SIGN
+    u'\u067e'   #  0x81 -> ARABIC LETTER PEH
+    u'\u201a'   #  0x82 -> SINGLE LOW-9 QUOTATION MARK
+    u'\u0192'   #  0x83 -> LATIN SMALL LETTER F WITH HOOK
+    u'\u201e'   #  0x84 -> DOUBLE LOW-9 QUOTATION MARK
+    u'\u2026'   #  0x85 -> HORIZONTAL ELLIPSIS
+    u'\u2020'   #  0x86 -> DAGGER
+    u'\u2021'   #  0x87 -> DOUBLE DAGGER
+    u'\u02c6'   #  0x88 -> MODIFIER LETTER CIRCUMFLEX ACCENT
+    u'\u2030'   #  0x89 -> PER MILLE SIGN
+    u'\u0679'   #  0x8A -> ARABIC LETTER TTEH
+    u'\u2039'   #  0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+    u'\u0152'   #  0x8C -> LATIN CAPITAL LIGATURE OE
+    u'\u0686'   #  0x8D -> ARABIC LETTER TCHEH
+    u'\u0698'   #  0x8E -> ARABIC LETTER JEH
+    u'\u0688'   #  0x8F -> ARABIC LETTER DDAL
+    u'\u06af'   #  0x90 -> ARABIC LETTER GAF
+    u'\u2018'   #  0x91 -> LEFT SINGLE QUOTATION MARK
+    u'\u2019'   #  0x92 -> RIGHT SINGLE QUOTATION MARK
+    u'\u201c'   #  0x93 -> LEFT DOUBLE QUOTATION MARK
+    u'\u201d'   #  0x94 -> RIGHT DOUBLE QUOTATION MARK
+    u'\u2022'   #  0x95 -> BULLET
+    u'\u2013'   #  0x96 -> EN DASH
+    u'\u2014'   #  0x97 -> EM DASH
+    u'\u06a9'   #  0x98 -> ARABIC LETTER KEHEH
+    u'\u2122'   #  0x99 -> TRADE MARK SIGN
+    u'\u0691'   #  0x9A -> ARABIC LETTER RREH
+    u'\u203a'   #  0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+    u'\u0153'   #  0x9C -> LATIN SMALL LIGATURE OE
+    u'\u200c'   #  0x9D -> ZERO WIDTH NON-JOINER
+    u'\u200d'   #  0x9E -> ZERO WIDTH JOINER
+    u'\u06ba'   #  0x9F -> ARABIC LETTER NOON GHUNNA
+    u'\xa0'     #  0xA0 -> NO-BREAK SPACE
+    u'\u060c'   #  0xA1 -> ARABIC COMMA
+    u'\xa2'     #  0xA2 -> CENT SIGN
+    u'\xa3'     #  0xA3 -> POUND SIGN
+    u'\xa4'     #  0xA4 -> CURRENCY SIGN
+    u'\xa5'     #  0xA5 -> YEN SIGN
+    u'\xa6'     #  0xA6 -> BROKEN BAR
+    u'\xa7'     #  0xA7 -> SECTION SIGN
+    u'\xa8'     #  0xA8 -> DIAERESIS
+    u'\xa9'     #  0xA9 -> COPYRIGHT SIGN
+    u'\u06be'   #  0xAA -> ARABIC LETTER HEH DOACHASHMEE
+    u'\xab'     #  0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xac'     #  0xAC -> NOT SIGN
+    u'\xad'     #  0xAD -> SOFT HYPHEN
+    u'\xae'     #  0xAE -> REGISTERED SIGN
+    u'\xaf'     #  0xAF -> MACRON
+    u'\xb0'     #  0xB0 -> DEGREE SIGN
+    u'\xb1'     #  0xB1 -> PLUS-MINUS SIGN
+    u'\xb2'     #  0xB2 -> SUPERSCRIPT TWO
+    u'\xb3'     #  0xB3 -> SUPERSCRIPT THREE
+    u'\xb4'     #  0xB4 -> ACUTE ACCENT
+    u'\xb5'     #  0xB5 -> MICRO SIGN
+    u'\xb6'     #  0xB6 -> PILCROW SIGN
+    u'\xb7'     #  0xB7 -> MIDDLE DOT
+    u'\xb8'     #  0xB8 -> CEDILLA
+    u'\xb9'     #  0xB9 -> SUPERSCRIPT ONE
+    u'\u061b'   #  0xBA -> ARABIC SEMICOLON
+    u'\xbb'     #  0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xbc'     #  0xBC -> VULGAR FRACTION ONE QUARTER
+    u'\xbd'     #  0xBD -> VULGAR FRACTION ONE HALF
+    u'\xbe'     #  0xBE -> VULGAR FRACTION THREE QUARTERS
+    u'\u061f'   #  0xBF -> ARABIC QUESTION MARK
+    u'\u06c1'   #  0xC0 -> ARABIC LETTER HEH GOAL
+    u'\u0621'   #  0xC1 -> ARABIC LETTER HAMZA
+    u'\u0622'   #  0xC2 -> ARABIC LETTER ALEF WITH MADDA ABOVE
+    u'\u0623'   #  0xC3 -> ARABIC LETTER ALEF WITH HAMZA ABOVE
+    u'\u0624'   #  0xC4 -> ARABIC LETTER WAW WITH HAMZA ABOVE
+    u'\u0625'   #  0xC5 -> ARABIC LETTER ALEF WITH HAMZA BELOW
+    u'\u0626'   #  0xC6 -> ARABIC LETTER YEH WITH HAMZA ABOVE
+    u'\u0627'   #  0xC7 -> ARABIC LETTER ALEF
+    u'\u0628'   #  0xC8 -> ARABIC LETTER BEH
+    u'\u0629'   #  0xC9 -> ARABIC LETTER TEH MARBUTA
+    u'\u062a'   #  0xCA -> ARABIC LETTER TEH
+    u'\u062b'   #  0xCB -> ARABIC LETTER THEH
+    u'\u062c'   #  0xCC -> ARABIC LETTER JEEM
+    u'\u062d'   #  0xCD -> ARABIC LETTER HAH
+    u'\u062e'   #  0xCE -> ARABIC LETTER KHAH
+    u'\u062f'   #  0xCF -> ARABIC LETTER DAL
+    u'\u0630'   #  0xD0 -> ARABIC LETTER THAL
+    u'\u0631'   #  0xD1 -> ARABIC LETTER REH
+    u'\u0632'   #  0xD2 -> ARABIC LETTER ZAIN
+    u'\u0633'   #  0xD3 -> ARABIC LETTER SEEN
+    u'\u0634'   #  0xD4 -> ARABIC LETTER SHEEN
+    u'\u0635'   #  0xD5 -> ARABIC LETTER SAD
+    u'\u0636'   #  0xD6 -> ARABIC LETTER DAD
+    u'\xd7'     #  0xD7 -> MULTIPLICATION SIGN
+    u'\u0637'   #  0xD8 -> ARABIC LETTER TAH
+    u'\u0638'   #  0xD9 -> ARABIC LETTER ZAH
+    u'\u0639'   #  0xDA -> ARABIC LETTER AIN
+    u'\u063a'   #  0xDB -> ARABIC LETTER GHAIN
+    u'\u0640'   #  0xDC -> ARABIC TATWEEL
+    u'\u0641'   #  0xDD -> ARABIC LETTER FEH
+    u'\u0642'   #  0xDE -> ARABIC LETTER QAF
+    u'\u0643'   #  0xDF -> ARABIC LETTER KAF
+    u'\xe0'     #  0xE0 -> LATIN SMALL LETTER A WITH GRAVE
+    u'\u0644'   #  0xE1 -> ARABIC LETTER LAM
+    u'\xe2'     #  0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX
+    u'\u0645'   #  0xE3 -> ARABIC LETTER MEEM
+    u'\u0646'   #  0xE4 -> ARABIC LETTER NOON
+    u'\u0647'   #  0xE5 -> ARABIC LETTER HEH
+    u'\u0648'   #  0xE6 -> ARABIC LETTER WAW
+    u'\xe7'     #  0xE7 -> LATIN SMALL LETTER C WITH CEDILLA
+    u'\xe8'     #  0xE8 -> LATIN SMALL LETTER E WITH GRAVE
+    u'\xe9'     #  0xE9 -> LATIN SMALL LETTER E WITH ACUTE
+    u'\xea'     #  0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX
+    u'\xeb'     #  0xEB -> LATIN SMALL LETTER E WITH DIAERESIS
+    u'\u0649'   #  0xEC -> ARABIC LETTER ALEF MAKSURA
+    u'\u064a'   #  0xED -> ARABIC LETTER YEH
+    u'\xee'     #  0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX
+    u'\xef'     #  0xEF -> LATIN SMALL LETTER I WITH DIAERESIS
+    u'\u064b'   #  0xF0 -> ARABIC FATHATAN
+    u'\u064c'   #  0xF1 -> ARABIC DAMMATAN
+    u'\u064d'   #  0xF2 -> ARABIC KASRATAN
+    u'\u064e'   #  0xF3 -> ARABIC FATHA
+    u'\xf4'     #  0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX
+    u'\u064f'   #  0xF5 -> ARABIC DAMMA
+    u'\u0650'   #  0xF6 -> ARABIC KASRA
+    u'\xf7'     #  0xF7 -> DIVISION SIGN
+    u'\u0651'   #  0xF8 -> ARABIC SHADDA
+    u'\xf9'     #  0xF9 -> LATIN SMALL LETTER U WITH GRAVE
+    u'\u0652'   #  0xFA -> ARABIC SUKUN
+    u'\xfb'     #  0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX
+    u'\xfc'     #  0xFC -> LATIN SMALL LETTER U WITH DIAERESIS
+    u'\u200e'   #  0xFD -> LEFT-TO-RIGHT MARK
+    u'\u200f'   #  0xFE -> RIGHT-TO-LEFT MARK
+    u'\u06d2'   #  0xFF -> ARABIC LETTER YEH BARREE
+)
+
+### Encoding table
+encoding_table=codecs.charmap_build(decoding_table)

Added: vendor/Python/current/Lib/encodings/cp1257.py
===================================================================
--- vendor/Python/current/Lib/encodings/cp1257.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/cp1257.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,307 @@
+""" Python Character Mapping Codec cp1257 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1257.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_table)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_table)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='cp1257',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x00 -> NULL
+    u'\x01'     #  0x01 -> START OF HEADING
+    u'\x02'     #  0x02 -> START OF TEXT
+    u'\x03'     #  0x03 -> END OF TEXT
+    u'\x04'     #  0x04 -> END OF TRANSMISSION
+    u'\x05'     #  0x05 -> ENQUIRY
+    u'\x06'     #  0x06 -> ACKNOWLEDGE
+    u'\x07'     #  0x07 -> BELL
+    u'\x08'     #  0x08 -> BACKSPACE
+    u'\t'       #  0x09 -> HORIZONTAL TABULATION
+    u'\n'       #  0x0A -> LINE FEED
+    u'\x0b'     #  0x0B -> VERTICAL TABULATION
+    u'\x0c'     #  0x0C -> FORM FEED
+    u'\r'       #  0x0D -> CARRIAGE RETURN
+    u'\x0e'     #  0x0E -> SHIFT OUT
+    u'\x0f'     #  0x0F -> SHIFT IN
+    u'\x10'     #  0x10 -> DATA LINK ESCAPE
+    u'\x11'     #  0x11 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x12 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x13 -> DEVICE CONTROL THREE
+    u'\x14'     #  0x14 -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x15 -> NEGATIVE ACKNOWLEDGE
+    u'\x16'     #  0x16 -> SYNCHRONOUS IDLE
+    u'\x17'     #  0x17 -> END OF TRANSMISSION BLOCK
+    u'\x18'     #  0x18 -> CANCEL
+    u'\x19'     #  0x19 -> END OF MEDIUM
+    u'\x1a'     #  0x1A -> SUBSTITUTE
+    u'\x1b'     #  0x1B -> ESCAPE
+    u'\x1c'     #  0x1C -> FILE SEPARATOR
+    u'\x1d'     #  0x1D -> GROUP SEPARATOR
+    u'\x1e'     #  0x1E -> RECORD SEPARATOR
+    u'\x1f'     #  0x1F -> UNIT SEPARATOR
+    u' '        #  0x20 -> SPACE
+    u'!'        #  0x21 -> EXCLAMATION MARK
+    u'"'        #  0x22 -> QUOTATION MARK
+    u'#'        #  0x23 -> NUMBER SIGN
+    u'$'        #  0x24 -> DOLLAR SIGN
+    u'%'        #  0x25 -> PERCENT SIGN
+    u'&'        #  0x26 -> AMPERSAND
+    u"'"        #  0x27 -> APOSTROPHE
+    u'('        #  0x28 -> LEFT PARENTHESIS
+    u')'        #  0x29 -> RIGHT PARENTHESIS
+    u'*'        #  0x2A -> ASTERISK
+    u'+'        #  0x2B -> PLUS SIGN
+    u','        #  0x2C -> COMMA
+    u'-'        #  0x2D -> HYPHEN-MINUS
+    u'.'        #  0x2E -> FULL STOP
+    u'/'        #  0x2F -> SOLIDUS
+    u'0'        #  0x30 -> DIGIT ZERO
+    u'1'        #  0x31 -> DIGIT ONE
+    u'2'        #  0x32 -> DIGIT TWO
+    u'3'        #  0x33 -> DIGIT THREE
+    u'4'        #  0x34 -> DIGIT FOUR
+    u'5'        #  0x35 -> DIGIT FIVE
+    u'6'        #  0x36 -> DIGIT SIX
+    u'7'        #  0x37 -> DIGIT SEVEN
+    u'8'        #  0x38 -> DIGIT EIGHT
+    u'9'        #  0x39 -> DIGIT NINE
+    u':'        #  0x3A -> COLON
+    u';'        #  0x3B -> SEMICOLON
+    u'<'        #  0x3C -> LESS-THAN SIGN
+    u'='        #  0x3D -> EQUALS SIGN
+    u'>'        #  0x3E -> GREATER-THAN SIGN
+    u'?'        #  0x3F -> QUESTION MARK
+    u'@'        #  0x40 -> COMMERCIAL AT
+    u'A'        #  0x41 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x42 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x43 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x44 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x45 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x46 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x47 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x48 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x49 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x4A -> LATIN CAPITAL LETTER J
+    u'K'        #  0x4B -> LATIN CAPITAL LETTER K
+    u'L'        #  0x4C -> LATIN CAPITAL LETTER L
+    u'M'        #  0x4D -> LATIN CAPITAL LETTER M
+    u'N'        #  0x4E -> LATIN CAPITAL LETTER N
+    u'O'        #  0x4F -> LATIN CAPITAL LETTER O
+    u'P'        #  0x50 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x51 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x52 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x53 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x54 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x55 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x56 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x57 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x58 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x59 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x5A -> LATIN CAPITAL LETTER Z
+    u'['        #  0x5B -> LEFT SQUARE BRACKET
+    u'\\'       #  0x5C -> REVERSE SOLIDUS
+    u']'        #  0x5D -> RIGHT SQUARE BRACKET
+    u'^'        #  0x5E -> CIRCUMFLEX ACCENT
+    u'_'        #  0x5F -> LOW LINE
+    u'`'        #  0x60 -> GRAVE ACCENT
+    u'a'        #  0x61 -> LATIN SMALL LETTER A
+    u'b'        #  0x62 -> LATIN SMALL LETTER B
+    u'c'        #  0x63 -> LATIN SMALL LETTER C
+    u'd'        #  0x64 -> LATIN SMALL LETTER D
+    u'e'        #  0x65 -> LATIN SMALL LETTER E
+    u'f'        #  0x66 -> LATIN SMALL LETTER F
+    u'g'        #  0x67 -> LATIN SMALL LETTER G
+    u'h'        #  0x68 -> LATIN SMALL LETTER H
+    u'i'        #  0x69 -> LATIN SMALL LETTER I
+    u'j'        #  0x6A -> LATIN SMALL LETTER J
+    u'k'        #  0x6B -> LATIN SMALL LETTER K
+    u'l'        #  0x6C -> LATIN SMALL LETTER L
+    u'm'        #  0x6D -> LATIN SMALL LETTER M
+    u'n'        #  0x6E -> LATIN SMALL LETTER N
+    u'o'        #  0x6F -> LATIN SMALL LETTER O
+    u'p'        #  0x70 -> LATIN SMALL LETTER P
+    u'q'        #  0x71 -> LATIN SMALL LETTER Q
+    u'r'        #  0x72 -> LATIN SMALL LETTER R
+    u's'        #  0x73 -> LATIN SMALL LETTER S
+    u't'        #  0x74 -> LATIN SMALL LETTER T
+    u'u'        #  0x75 -> LATIN SMALL LETTER U
+    u'v'        #  0x76 -> LATIN SMALL LETTER V
+    u'w'        #  0x77 -> LATIN SMALL LETTER W
+    u'x'        #  0x78 -> LATIN SMALL LETTER X
+    u'y'        #  0x79 -> LATIN SMALL LETTER Y
+    u'z'        #  0x7A -> LATIN SMALL LETTER Z
+    u'{'        #  0x7B -> LEFT CURLY BRACKET
+    u'|'        #  0x7C -> VERTICAL LINE
+    u'}'        #  0x7D -> RIGHT CURLY BRACKET
+    u'~'        #  0x7E -> TILDE
+    u'\x7f'     #  0x7F -> DELETE
+    u'\u20ac'   #  0x80 -> EURO SIGN
+    u'\ufffe'   #  0x81 -> UNDEFINED
+    u'\u201a'   #  0x82 -> SINGLE LOW-9 QUOTATION MARK
+    u'\ufffe'   #  0x83 -> UNDEFINED
+    u'\u201e'   #  0x84 -> DOUBLE LOW-9 QUOTATION MARK
+    u'\u2026'   #  0x85 -> HORIZONTAL ELLIPSIS
+    u'\u2020'   #  0x86 -> DAGGER
+    u'\u2021'   #  0x87 -> DOUBLE DAGGER
+    u'\ufffe'   #  0x88 -> UNDEFINED
+    u'\u2030'   #  0x89 -> PER MILLE SIGN
+    u'\ufffe'   #  0x8A -> UNDEFINED
+    u'\u2039'   #  0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+    u'\ufffe'   #  0x8C -> UNDEFINED
+    u'\xa8'     #  0x8D -> DIAERESIS
+    u'\u02c7'   #  0x8E -> CARON
+    u'\xb8'     #  0x8F -> CEDILLA
+    u'\ufffe'   #  0x90 -> UNDEFINED
+    u'\u2018'   #  0x91 -> LEFT SINGLE QUOTATION MARK
+    u'\u2019'   #  0x92 -> RIGHT SINGLE QUOTATION MARK
+    u'\u201c'   #  0x93 -> LEFT DOUBLE QUOTATION MARK
+    u'\u201d'   #  0x94 -> RIGHT DOUBLE QUOTATION MARK
+    u'\u2022'   #  0x95 -> BULLET
+    u'\u2013'   #  0x96 -> EN DASH
+    u'\u2014'   #  0x97 -> EM DASH
+    u'\ufffe'   #  0x98 -> UNDEFINED
+    u'\u2122'   #  0x99 -> TRADE MARK SIGN
+    u'\ufffe'   #  0x9A -> UNDEFINED
+    u'\u203a'   #  0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+    u'\ufffe'   #  0x9C -> UNDEFINED
+    u'\xaf'     #  0x9D -> MACRON
+    u'\u02db'   #  0x9E -> OGONEK
+    u'\ufffe'   #  0x9F -> UNDEFINED
+    u'\xa0'     #  0xA0 -> NO-BREAK SPACE
+    u'\ufffe'   #  0xA1 -> UNDEFINED
+    u'\xa2'     #  0xA2 -> CENT SIGN
+    u'\xa3'     #  0xA3 -> POUND SIGN
+    u'\xa4'     #  0xA4 -> CURRENCY SIGN
+    u'\ufffe'   #  0xA5 -> UNDEFINED
+    u'\xa6'     #  0xA6 -> BROKEN BAR
+    u'\xa7'     #  0xA7 -> SECTION SIGN
+    u'\xd8'     #  0xA8 -> LATIN CAPITAL LETTER O WITH STROKE
+    u'\xa9'     #  0xA9 -> COPYRIGHT SIGN
+    u'\u0156'   #  0xAA -> LATIN CAPITAL LETTER R WITH CEDILLA
+    u'\xab'     #  0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xac'     #  0xAC -> NOT SIGN
+    u'\xad'     #  0xAD -> SOFT HYPHEN
+    u'\xae'     #  0xAE -> REGISTERED SIGN
+    u'\xc6'     #  0xAF -> LATIN CAPITAL LETTER AE
+    u'\xb0'     #  0xB0 -> DEGREE SIGN
+    u'\xb1'     #  0xB1 -> PLUS-MINUS SIGN
+    u'\xb2'     #  0xB2 -> SUPERSCRIPT TWO
+    u'\xb3'     #  0xB3 -> SUPERSCRIPT THREE
+    u'\xb4'     #  0xB4 -> ACUTE ACCENT
+    u'\xb5'     #  0xB5 -> MICRO SIGN
+    u'\xb6'     #  0xB6 -> PILCROW SIGN
+    u'\xb7'     #  0xB7 -> MIDDLE DOT
+    u'\xf8'     #  0xB8 -> LATIN SMALL LETTER O WITH STROKE
+    u'\xb9'     #  0xB9 -> SUPERSCRIPT ONE
+    u'\u0157'   #  0xBA -> LATIN SMALL LETTER R WITH CEDILLA
+    u'\xbb'     #  0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xbc'     #  0xBC -> VULGAR FRACTION ONE QUARTER
+    u'\xbd'     #  0xBD -> VULGAR FRACTION ONE HALF
+    u'\xbe'     #  0xBE -> VULGAR FRACTION THREE QUARTERS
+    u'\xe6'     #  0xBF -> LATIN SMALL LETTER AE
+    u'\u0104'   #  0xC0 -> LATIN CAPITAL LETTER A WITH OGONEK
+    u'\u012e'   #  0xC1 -> LATIN CAPITAL LETTER I WITH OGONEK
+    u'\u0100'   #  0xC2 -> LATIN CAPITAL LETTER A WITH MACRON
+    u'\u0106'   #  0xC3 -> LATIN CAPITAL LETTER C WITH ACUTE
+    u'\xc4'     #  0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS
+    u'\xc5'     #  0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE
+    u'\u0118'   #  0xC6 -> LATIN CAPITAL LETTER E WITH OGONEK
+    u'\u0112'   #  0xC7 -> LATIN CAPITAL LETTER E WITH MACRON
+    u'\u010c'   #  0xC8 -> LATIN CAPITAL LETTER C WITH CARON
+    u'\xc9'     #  0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE
+    u'\u0179'   #  0xCA -> LATIN CAPITAL LETTER Z WITH ACUTE
+    u'\u0116'   #  0xCB -> LATIN CAPITAL LETTER E WITH DOT ABOVE
+    u'\u0122'   #  0xCC -> LATIN CAPITAL LETTER G WITH CEDILLA
+    u'\u0136'   #  0xCD -> LATIN CAPITAL LETTER K WITH CEDILLA
+    u'\u012a'   #  0xCE -> LATIN CAPITAL LETTER I WITH MACRON
+    u'\u013b'   #  0xCF -> LATIN CAPITAL LETTER L WITH CEDILLA
+    u'\u0160'   #  0xD0 -> LATIN CAPITAL LETTER S WITH CARON
+    u'\u0143'   #  0xD1 -> LATIN CAPITAL LETTER N WITH ACUTE
+    u'\u0145'   #  0xD2 -> LATIN CAPITAL LETTER N WITH CEDILLA
+    u'\xd3'     #  0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE
+    u'\u014c'   #  0xD4 -> LATIN CAPITAL LETTER O WITH MACRON
+    u'\xd5'     #  0xD5 -> LATIN CAPITAL LETTER O WITH TILDE
+    u'\xd6'     #  0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS
+    u'\xd7'     #  0xD7 -> MULTIPLICATION SIGN
+    u'\u0172'   #  0xD8 -> LATIN CAPITAL LETTER U WITH OGONEK
+    u'\u0141'   #  0xD9 -> LATIN CAPITAL LETTER L WITH STROKE
+    u'\u015a'   #  0xDA -> LATIN CAPITAL LETTER S WITH ACUTE
+    u'\u016a'   #  0xDB -> LATIN CAPITAL LETTER U WITH MACRON
+    u'\xdc'     #  0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS
+    u'\u017b'   #  0xDD -> LATIN CAPITAL LETTER Z WITH DOT ABOVE
+    u'\u017d'   #  0xDE -> LATIN CAPITAL LETTER Z WITH CARON
+    u'\xdf'     #  0xDF -> LATIN SMALL LETTER SHARP S
+    u'\u0105'   #  0xE0 -> LATIN SMALL LETTER A WITH OGONEK
+    u'\u012f'   #  0xE1 -> LATIN SMALL LETTER I WITH OGONEK
+    u'\u0101'   #  0xE2 -> LATIN SMALL LETTER A WITH MACRON
+    u'\u0107'   #  0xE3 -> LATIN SMALL LETTER C WITH ACUTE
+    u'\xe4'     #  0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS
+    u'\xe5'     #  0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE
+    u'\u0119'   #  0xE6 -> LATIN SMALL LETTER E WITH OGONEK
+    u'\u0113'   #  0xE7 -> LATIN SMALL LETTER E WITH MACRON
+    u'\u010d'   #  0xE8 -> LATIN SMALL LETTER C WITH CARON
+    u'\xe9'     #  0xE9 -> LATIN SMALL LETTER E WITH ACUTE
+    u'\u017a'   #  0xEA -> LATIN SMALL LETTER Z WITH ACUTE
+    u'\u0117'   #  0xEB -> LATIN SMALL LETTER E WITH DOT ABOVE
+    u'\u0123'   #  0xEC -> LATIN SMALL LETTER G WITH CEDILLA
+    u'\u0137'   #  0xED -> LATIN SMALL LETTER K WITH CEDILLA
+    u'\u012b'   #  0xEE -> LATIN SMALL LETTER I WITH MACRON
+    u'\u013c'   #  0xEF -> LATIN SMALL LETTER L WITH CEDILLA
+    u'\u0161'   #  0xF0 -> LATIN SMALL LETTER S WITH CARON
+    u'\u0144'   #  0xF1 -> LATIN SMALL LETTER N WITH ACUTE
+    u'\u0146'   #  0xF2 -> LATIN SMALL LETTER N WITH CEDILLA
+    u'\xf3'     #  0xF3 -> LATIN SMALL LETTER O WITH ACUTE
+    u'\u014d'   #  0xF4 -> LATIN SMALL LETTER O WITH MACRON
+    u'\xf5'     #  0xF5 -> LATIN SMALL LETTER O WITH TILDE
+    u'\xf6'     #  0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS
+    u'\xf7'     #  0xF7 -> DIVISION SIGN
+    u'\u0173'   #  0xF8 -> LATIN SMALL LETTER U WITH OGONEK
+    u'\u0142'   #  0xF9 -> LATIN SMALL LETTER L WITH STROKE
+    u'\u015b'   #  0xFA -> LATIN SMALL LETTER S WITH ACUTE
+    u'\u016b'   #  0xFB -> LATIN SMALL LETTER U WITH MACRON
+    u'\xfc'     #  0xFC -> LATIN SMALL LETTER U WITH DIAERESIS
+    u'\u017c'   #  0xFD -> LATIN SMALL LETTER Z WITH DOT ABOVE
+    u'\u017e'   #  0xFE -> LATIN SMALL LETTER Z WITH CARON
+    u'\u02d9'   #  0xFF -> DOT ABOVE
+)
+
+### Encoding table
+encoding_table=codecs.charmap_build(decoding_table)

Added: vendor/Python/current/Lib/encodings/cp1258.py
===================================================================
--- vendor/Python/current/Lib/encodings/cp1258.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/cp1258.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,307 @@
+""" Python Character Mapping Codec cp1258 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1258.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_table)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_table)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='cp1258',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x00 -> NULL
+    u'\x01'     #  0x01 -> START OF HEADING
+    u'\x02'     #  0x02 -> START OF TEXT
+    u'\x03'     #  0x03 -> END OF TEXT
+    u'\x04'     #  0x04 -> END OF TRANSMISSION
+    u'\x05'     #  0x05 -> ENQUIRY
+    u'\x06'     #  0x06 -> ACKNOWLEDGE
+    u'\x07'     #  0x07 -> BELL
+    u'\x08'     #  0x08 -> BACKSPACE
+    u'\t'       #  0x09 -> HORIZONTAL TABULATION
+    u'\n'       #  0x0A -> LINE FEED
+    u'\x0b'     #  0x0B -> VERTICAL TABULATION
+    u'\x0c'     #  0x0C -> FORM FEED
+    u'\r'       #  0x0D -> CARRIAGE RETURN
+    u'\x0e'     #  0x0E -> SHIFT OUT
+    u'\x0f'     #  0x0F -> SHIFT IN
+    u'\x10'     #  0x10 -> DATA LINK ESCAPE
+    u'\x11'     #  0x11 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x12 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x13 -> DEVICE CONTROL THREE
+    u'\x14'     #  0x14 -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x15 -> NEGATIVE ACKNOWLEDGE
+    u'\x16'     #  0x16 -> SYNCHRONOUS IDLE
+    u'\x17'     #  0x17 -> END OF TRANSMISSION BLOCK
+    u'\x18'     #  0x18 -> CANCEL
+    u'\x19'     #  0x19 -> END OF MEDIUM
+    u'\x1a'     #  0x1A -> SUBSTITUTE
+    u'\x1b'     #  0x1B -> ESCAPE
+    u'\x1c'     #  0x1C -> FILE SEPARATOR
+    u'\x1d'     #  0x1D -> GROUP SEPARATOR
+    u'\x1e'     #  0x1E -> RECORD SEPARATOR
+    u'\x1f'     #  0x1F -> UNIT SEPARATOR
+    u' '        #  0x20 -> SPACE
+    u'!'        #  0x21 -> EXCLAMATION MARK
+    u'"'        #  0x22 -> QUOTATION MARK
+    u'#'        #  0x23 -> NUMBER SIGN
+    u'$'        #  0x24 -> DOLLAR SIGN
+    u'%'        #  0x25 -> PERCENT SIGN
+    u'&'        #  0x26 -> AMPERSAND
+    u"'"        #  0x27 -> APOSTROPHE
+    u'('        #  0x28 -> LEFT PARENTHESIS
+    u')'        #  0x29 -> RIGHT PARENTHESIS
+    u'*'        #  0x2A -> ASTERISK
+    u'+'        #  0x2B -> PLUS SIGN
+    u','        #  0x2C -> COMMA
+    u'-'        #  0x2D -> HYPHEN-MINUS
+    u'.'        #  0x2E -> FULL STOP
+    u'/'        #  0x2F -> SOLIDUS
+    u'0'        #  0x30 -> DIGIT ZERO
+    u'1'        #  0x31 -> DIGIT ONE
+    u'2'        #  0x32 -> DIGIT TWO
+    u'3'        #  0x33 -> DIGIT THREE
+    u'4'        #  0x34 -> DIGIT FOUR
+    u'5'        #  0x35 -> DIGIT FIVE
+    u'6'        #  0x36 -> DIGIT SIX
+    u'7'        #  0x37 -> DIGIT SEVEN
+    u'8'        #  0x38 -> DIGIT EIGHT
+    u'9'        #  0x39 -> DIGIT NINE
+    u':'        #  0x3A -> COLON
+    u';'        #  0x3B -> SEMICOLON
+    u'<'        #  0x3C -> LESS-THAN SIGN
+    u'='        #  0x3D -> EQUALS SIGN
+    u'>'        #  0x3E -> GREATER-THAN SIGN
+    u'?'        #  0x3F -> QUESTION MARK
+    u'@'        #  0x40 -> COMMERCIAL AT
+    u'A'        #  0x41 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x42 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x43 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x44 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x45 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x46 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x47 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x48 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x49 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x4A -> LATIN CAPITAL LETTER J
+    u'K'        #  0x4B -> LATIN CAPITAL LETTER K
+    u'L'        #  0x4C -> LATIN CAPITAL LETTER L
+    u'M'        #  0x4D -> LATIN CAPITAL LETTER M
+    u'N'        #  0x4E -> LATIN CAPITAL LETTER N
+    u'O'        #  0x4F -> LATIN CAPITAL LETTER O
+    u'P'        #  0x50 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x51 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x52 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x53 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x54 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x55 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x56 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x57 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x58 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x59 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x5A -> LATIN CAPITAL LETTER Z
+    u'['        #  0x5B -> LEFT SQUARE BRACKET
+    u'\\'       #  0x5C -> REVERSE SOLIDUS
+    u']'        #  0x5D -> RIGHT SQUARE BRACKET
+    u'^'        #  0x5E -> CIRCUMFLEX ACCENT
+    u'_'        #  0x5F -> LOW LINE
+    u'`'        #  0x60 -> GRAVE ACCENT
+    u'a'        #  0x61 -> LATIN SMALL LETTER A
+    u'b'        #  0x62 -> LATIN SMALL LETTER B
+    u'c'        #  0x63 -> LATIN SMALL LETTER C
+    u'd'        #  0x64 -> LATIN SMALL LETTER D
+    u'e'        #  0x65 -> LATIN SMALL LETTER E
+    u'f'        #  0x66 -> LATIN SMALL LETTER F
+    u'g'        #  0x67 -> LATIN SMALL LETTER G
+    u'h'        #  0x68 -> LATIN SMALL LETTER H
+    u'i'        #  0x69 -> LATIN SMALL LETTER I
+    u'j'        #  0x6A -> LATIN SMALL LETTER J
+    u'k'        #  0x6B -> LATIN SMALL LETTER K
+    u'l'        #  0x6C -> LATIN SMALL LETTER L
+    u'm'        #  0x6D -> LATIN SMALL LETTER M
+    u'n'        #  0x6E -> LATIN SMALL LETTER N
+    u'o'        #  0x6F -> LATIN SMALL LETTER O
+    u'p'        #  0x70 -> LATIN SMALL LETTER P
+    u'q'        #  0x71 -> LATIN SMALL LETTER Q
+    u'r'        #  0x72 -> LATIN SMALL LETTER R
+    u's'        #  0x73 -> LATIN SMALL LETTER S
+    u't'        #  0x74 -> LATIN SMALL LETTER T
+    u'u'        #  0x75 -> LATIN SMALL LETTER U
+    u'v'        #  0x76 -> LATIN SMALL LETTER V
+    u'w'        #  0x77 -> LATIN SMALL LETTER W
+    u'x'        #  0x78 -> LATIN SMALL LETTER X
+    u'y'        #  0x79 -> LATIN SMALL LETTER Y
+    u'z'        #  0x7A -> LATIN SMALL LETTER Z
+    u'{'        #  0x7B -> LEFT CURLY BRACKET
+    u'|'        #  0x7C -> VERTICAL LINE
+    u'}'        #  0x7D -> RIGHT CURLY BRACKET
+    u'~'        #  0x7E -> TILDE
+    u'\x7f'     #  0x7F -> DELETE
+    u'\u20ac'   #  0x80 -> EURO SIGN
+    u'\ufffe'   #  0x81 -> UNDEFINED
+    u'\u201a'   #  0x82 -> SINGLE LOW-9 QUOTATION MARK
+    u'\u0192'   #  0x83 -> LATIN SMALL LETTER F WITH HOOK
+    u'\u201e'   #  0x84 -> DOUBLE LOW-9 QUOTATION MARK
+    u'\u2026'   #  0x85 -> HORIZONTAL ELLIPSIS
+    u'\u2020'   #  0x86 -> DAGGER
+    u'\u2021'   #  0x87 -> DOUBLE DAGGER
+    u'\u02c6'   #  0x88 -> MODIFIER LETTER CIRCUMFLEX ACCENT
+    u'\u2030'   #  0x89 -> PER MILLE SIGN
+    u'\ufffe'   #  0x8A -> UNDEFINED
+    u'\u2039'   #  0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+    u'\u0152'   #  0x8C -> LATIN CAPITAL LIGATURE OE
+    u'\ufffe'   #  0x8D -> UNDEFINED
+    u'\ufffe'   #  0x8E -> UNDEFINED
+    u'\ufffe'   #  0x8F -> UNDEFINED
+    u'\ufffe'   #  0x90 -> UNDEFINED
+    u'\u2018'   #  0x91 -> LEFT SINGLE QUOTATION MARK
+    u'\u2019'   #  0x92 -> RIGHT SINGLE QUOTATION MARK
+    u'\u201c'   #  0x93 -> LEFT DOUBLE QUOTATION MARK
+    u'\u201d'   #  0x94 -> RIGHT DOUBLE QUOTATION MARK
+    u'\u2022'   #  0x95 -> BULLET
+    u'\u2013'   #  0x96 -> EN DASH
+    u'\u2014'   #  0x97 -> EM DASH
+    u'\u02dc'   #  0x98 -> SMALL TILDE
+    u'\u2122'   #  0x99 -> TRADE MARK SIGN
+    u'\ufffe'   #  0x9A -> UNDEFINED
+    u'\u203a'   #  0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+    u'\u0153'   #  0x9C -> LATIN SMALL LIGATURE OE
+    u'\ufffe'   #  0x9D -> UNDEFINED
+    u'\ufffe'   #  0x9E -> UNDEFINED
+    u'\u0178'   #  0x9F -> LATIN CAPITAL LETTER Y WITH DIAERESIS
+    u'\xa0'     #  0xA0 -> NO-BREAK SPACE
+    u'\xa1'     #  0xA1 -> INVERTED EXCLAMATION MARK
+    u'\xa2'     #  0xA2 -> CENT SIGN
+    u'\xa3'     #  0xA3 -> POUND SIGN
+    u'\xa4'     #  0xA4 -> CURRENCY SIGN
+    u'\xa5'     #  0xA5 -> YEN SIGN
+    u'\xa6'     #  0xA6 -> BROKEN BAR
+    u'\xa7'     #  0xA7 -> SECTION SIGN
+    u'\xa8'     #  0xA8 -> DIAERESIS
+    u'\xa9'     #  0xA9 -> COPYRIGHT SIGN
+    u'\xaa'     #  0xAA -> FEMININE ORDINAL INDICATOR
+    u'\xab'     #  0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xac'     #  0xAC -> NOT SIGN
+    u'\xad'     #  0xAD -> SOFT HYPHEN
+    u'\xae'     #  0xAE -> REGISTERED SIGN
+    u'\xaf'     #  0xAF -> MACRON
+    u'\xb0'     #  0xB0 -> DEGREE SIGN
+    u'\xb1'     #  0xB1 -> PLUS-MINUS SIGN
+    u'\xb2'     #  0xB2 -> SUPERSCRIPT TWO
+    u'\xb3'     #  0xB3 -> SUPERSCRIPT THREE
+    u'\xb4'     #  0xB4 -> ACUTE ACCENT
+    u'\xb5'     #  0xB5 -> MICRO SIGN
+    u'\xb6'     #  0xB6 -> PILCROW SIGN
+    u'\xb7'     #  0xB7 -> MIDDLE DOT
+    u'\xb8'     #  0xB8 -> CEDILLA
+    u'\xb9'     #  0xB9 -> SUPERSCRIPT ONE
+    u'\xba'     #  0xBA -> MASCULINE ORDINAL INDICATOR
+    u'\xbb'     #  0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xbc'     #  0xBC -> VULGAR FRACTION ONE QUARTER
+    u'\xbd'     #  0xBD -> VULGAR FRACTION ONE HALF
+    u'\xbe'     #  0xBE -> VULGAR FRACTION THREE QUARTERS
+    u'\xbf'     #  0xBF -> INVERTED QUESTION MARK
+    u'\xc0'     #  0xC0 -> LATIN CAPITAL LETTER A WITH GRAVE
+    u'\xc1'     #  0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE
+    u'\xc2'     #  0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+    u'\u0102'   #  0xC3 -> LATIN CAPITAL LETTER A WITH BREVE
+    u'\xc4'     #  0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS
+    u'\xc5'     #  0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE
+    u'\xc6'     #  0xC6 -> LATIN CAPITAL LETTER AE
+    u'\xc7'     #  0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA
+    u'\xc8'     #  0xC8 -> LATIN CAPITAL LETTER E WITH GRAVE
+    u'\xc9'     #  0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE
+    u'\xca'     #  0xCA -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+    u'\xcb'     #  0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS
+    u'\u0300'   #  0xCC -> COMBINING GRAVE ACCENT
+    u'\xcd'     #  0xCD -> LATIN CAPITAL LETTER I WITH ACUTE
+    u'\xce'     #  0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+    u'\xcf'     #  0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS
+    u'\u0110'   #  0xD0 -> LATIN CAPITAL LETTER D WITH STROKE
+    u'\xd1'     #  0xD1 -> LATIN CAPITAL LETTER N WITH TILDE
+    u'\u0309'   #  0xD2 -> COMBINING HOOK ABOVE
+    u'\xd3'     #  0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE
+    u'\xd4'     #  0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+    u'\u01a0'   #  0xD5 -> LATIN CAPITAL LETTER O WITH HORN
+    u'\xd6'     #  0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS
+    u'\xd7'     #  0xD7 -> MULTIPLICATION SIGN
+    u'\xd8'     #  0xD8 -> LATIN CAPITAL LETTER O WITH STROKE
+    u'\xd9'     #  0xD9 -> LATIN CAPITAL LETTER U WITH GRAVE
+    u'\xda'     #  0xDA -> LATIN CAPITAL LETTER U WITH ACUTE
+    u'\xdb'     #  0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+    u'\xdc'     #  0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS
+    u'\u01af'   #  0xDD -> LATIN CAPITAL LETTER U WITH HORN
+    u'\u0303'   #  0xDE -> COMBINING TILDE
+    u'\xdf'     #  0xDF -> LATIN SMALL LETTER SHARP S
+    u'\xe0'     #  0xE0 -> LATIN SMALL LETTER A WITH GRAVE
+    u'\xe1'     #  0xE1 -> LATIN SMALL LETTER A WITH ACUTE
+    u'\xe2'     #  0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX
+    u'\u0103'   #  0xE3 -> LATIN SMALL LETTER A WITH BREVE
+    u'\xe4'     #  0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS
+    u'\xe5'     #  0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE
+    u'\xe6'     #  0xE6 -> LATIN SMALL LETTER AE
+    u'\xe7'     #  0xE7 -> LATIN SMALL LETTER C WITH CEDILLA
+    u'\xe8'     #  0xE8 -> LATIN SMALL LETTER E WITH GRAVE
+    u'\xe9'     #  0xE9 -> LATIN SMALL LETTER E WITH ACUTE
+    u'\xea'     #  0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX
+    u'\xeb'     #  0xEB -> LATIN SMALL LETTER E WITH DIAERESIS
+    u'\u0301'   #  0xEC -> COMBINING ACUTE ACCENT
+    u'\xed'     #  0xED -> LATIN SMALL LETTER I WITH ACUTE
+    u'\xee'     #  0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX
+    u'\xef'     #  0xEF -> LATIN SMALL LETTER I WITH DIAERESIS
+    u'\u0111'   #  0xF0 -> LATIN SMALL LETTER D WITH STROKE
+    u'\xf1'     #  0xF1 -> LATIN SMALL LETTER N WITH TILDE
+    u'\u0323'   #  0xF2 -> COMBINING DOT BELOW
+    u'\xf3'     #  0xF3 -> LATIN SMALL LETTER O WITH ACUTE
+    u'\xf4'     #  0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX
+    u'\u01a1'   #  0xF5 -> LATIN SMALL LETTER O WITH HORN
+    u'\xf6'     #  0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS
+    u'\xf7'     #  0xF7 -> DIVISION SIGN
+    u'\xf8'     #  0xF8 -> LATIN SMALL LETTER O WITH STROKE
+    u'\xf9'     #  0xF9 -> LATIN SMALL LETTER U WITH GRAVE
+    u'\xfa'     #  0xFA -> LATIN SMALL LETTER U WITH ACUTE
+    u'\xfb'     #  0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX
+    u'\xfc'     #  0xFC -> LATIN SMALL LETTER U WITH DIAERESIS
+    u'\u01b0'   #  0xFD -> LATIN SMALL LETTER U WITH HORN
+    u'\u20ab'   #  0xFE -> DONG SIGN
+    u'\xff'     #  0xFF -> LATIN SMALL LETTER Y WITH DIAERESIS
+)
+
+### Encoding table
+encoding_table=codecs.charmap_build(decoding_table)

Added: vendor/Python/current/Lib/encodings/cp424.py
===================================================================
--- vendor/Python/current/Lib/encodings/cp424.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/cp424.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,307 @@
+""" Python Character Mapping Codec cp424 generated from 'MAPPINGS/VENDORS/MISC/CP424.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_table)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_table)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='cp424',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x00 -> NULL
+    u'\x01'     #  0x01 -> START OF HEADING
+    u'\x02'     #  0x02 -> START OF TEXT
+    u'\x03'     #  0x03 -> END OF TEXT
+    u'\x9c'     #  0x04 -> SELECT
+    u'\t'       #  0x05 -> HORIZONTAL TABULATION
+    u'\x86'     #  0x06 -> REQUIRED NEW LINE
+    u'\x7f'     #  0x07 -> DELETE
+    u'\x97'     #  0x08 -> GRAPHIC ESCAPE
+    u'\x8d'     #  0x09 -> SUPERSCRIPT
+    u'\x8e'     #  0x0A -> REPEAT
+    u'\x0b'     #  0x0B -> VERTICAL TABULATION
+    u'\x0c'     #  0x0C -> FORM FEED
+    u'\r'       #  0x0D -> CARRIAGE RETURN
+    u'\x0e'     #  0x0E -> SHIFT OUT
+    u'\x0f'     #  0x0F -> SHIFT IN
+    u'\x10'     #  0x10 -> DATA LINK ESCAPE
+    u'\x11'     #  0x11 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x12 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x13 -> DEVICE CONTROL THREE
+    u'\x9d'     #  0x14 -> RESTORE/ENABLE PRESENTATION
+    u'\x85'     #  0x15 -> NEW LINE
+    u'\x08'     #  0x16 -> BACKSPACE
+    u'\x87'     #  0x17 -> PROGRAM OPERATOR COMMUNICATION
+    u'\x18'     #  0x18 -> CANCEL
+    u'\x19'     #  0x19 -> END OF MEDIUM
+    u'\x92'     #  0x1A -> UNIT BACK SPACE
+    u'\x8f'     #  0x1B -> CUSTOMER USE ONE
+    u'\x1c'     #  0x1C -> FILE SEPARATOR
+    u'\x1d'     #  0x1D -> GROUP SEPARATOR
+    u'\x1e'     #  0x1E -> RECORD SEPARATOR
+    u'\x1f'     #  0x1F -> UNIT SEPARATOR
+    u'\x80'     #  0x20 -> DIGIT SELECT
+    u'\x81'     #  0x21 -> START OF SIGNIFICANCE
+    u'\x82'     #  0x22 -> FIELD SEPARATOR
+    u'\x83'     #  0x23 -> WORD UNDERSCORE
+    u'\x84'     #  0x24 -> BYPASS OR INHIBIT PRESENTATION
+    u'\n'       #  0x25 -> LINE FEED
+    u'\x17'     #  0x26 -> END OF TRANSMISSION BLOCK
+    u'\x1b'     #  0x27 -> ESCAPE
+    u'\x88'     #  0x28 -> SET ATTRIBUTE
+    u'\x89'     #  0x29 -> START FIELD EXTENDED
+    u'\x8a'     #  0x2A -> SET MODE OR SWITCH
+    u'\x8b'     #  0x2B -> CONTROL SEQUENCE PREFIX
+    u'\x8c'     #  0x2C -> MODIFY FIELD ATTRIBUTE
+    u'\x05'     #  0x2D -> ENQUIRY
+    u'\x06'     #  0x2E -> ACKNOWLEDGE
+    u'\x07'     #  0x2F -> BELL
+    u'\x90'     #  0x30 -> <reserved>
+    u'\x91'     #  0x31 -> <reserved>
+    u'\x16'     #  0x32 -> SYNCHRONOUS IDLE
+    u'\x93'     #  0x33 -> INDEX RETURN
+    u'\x94'     #  0x34 -> PRESENTATION POSITION
+    u'\x95'     #  0x35 -> TRANSPARENT
+    u'\x96'     #  0x36 -> NUMERIC BACKSPACE
+    u'\x04'     #  0x37 -> END OF TRANSMISSION
+    u'\x98'     #  0x38 -> SUBSCRIPT
+    u'\x99'     #  0x39 -> INDENT TABULATION
+    u'\x9a'     #  0x3A -> REVERSE FORM FEED
+    u'\x9b'     #  0x3B -> CUSTOMER USE THREE
+    u'\x14'     #  0x3C -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x3D -> NEGATIVE ACKNOWLEDGE
+    u'\x9e'     #  0x3E -> <reserved>
+    u'\x1a'     #  0x3F -> SUBSTITUTE
+    u' '        #  0x40 -> SPACE
+    u'\u05d0'   #  0x41 -> HEBREW LETTER ALEF
+    u'\u05d1'   #  0x42 -> HEBREW LETTER BET
+    u'\u05d2'   #  0x43 -> HEBREW LETTER GIMEL
+    u'\u05d3'   #  0x44 -> HEBREW LETTER DALET
+    u'\u05d4'   #  0x45 -> HEBREW LETTER HE
+    u'\u05d5'   #  0x46 -> HEBREW LETTER VAV
+    u'\u05d6'   #  0x47 -> HEBREW LETTER ZAYIN
+    u'\u05d7'   #  0x48 -> HEBREW LETTER HET
+    u'\u05d8'   #  0x49 -> HEBREW LETTER TET
+    u'\xa2'     #  0x4A -> CENT SIGN
+    u'.'        #  0x4B -> FULL STOP
+    u'<'        #  0x4C -> LESS-THAN SIGN
+    u'('        #  0x4D -> LEFT PARENTHESIS
+    u'+'        #  0x4E -> PLUS SIGN
+    u'|'        #  0x4F -> VERTICAL LINE
+    u'&'        #  0x50 -> AMPERSAND
+    u'\u05d9'   #  0x51 -> HEBREW LETTER YOD
+    u'\u05da'   #  0x52 -> HEBREW LETTER FINAL KAF
+    u'\u05db'   #  0x53 -> HEBREW LETTER KAF
+    u'\u05dc'   #  0x54 -> HEBREW LETTER LAMED
+    u'\u05dd'   #  0x55 -> HEBREW LETTER FINAL MEM
+    u'\u05de'   #  0x56 -> HEBREW LETTER MEM
+    u'\u05df'   #  0x57 -> HEBREW LETTER FINAL NUN
+    u'\u05e0'   #  0x58 -> HEBREW LETTER NUN
+    u'\u05e1'   #  0x59 -> HEBREW LETTER SAMEKH
+    u'!'        #  0x5A -> EXCLAMATION MARK
+    u'$'        #  0x5B -> DOLLAR SIGN
+    u'*'        #  0x5C -> ASTERISK
+    u')'        #  0x5D -> RIGHT PARENTHESIS
+    u';'        #  0x5E -> SEMICOLON
+    u'\xac'     #  0x5F -> NOT SIGN
+    u'-'        #  0x60 -> HYPHEN-MINUS
+    u'/'        #  0x61 -> SOLIDUS
+    u'\u05e2'   #  0x62 -> HEBREW LETTER AYIN
+    u'\u05e3'   #  0x63 -> HEBREW LETTER FINAL PE
+    u'\u05e4'   #  0x64 -> HEBREW LETTER PE
+    u'\u05e5'   #  0x65 -> HEBREW LETTER FINAL TSADI
+    u'\u05e6'   #  0x66 -> HEBREW LETTER TSADI
+    u'\u05e7'   #  0x67 -> HEBREW LETTER QOF
+    u'\u05e8'   #  0x68 -> HEBREW LETTER RESH
+    u'\u05e9'   #  0x69 -> HEBREW LETTER SHIN
+    u'\xa6'     #  0x6A -> BROKEN BAR
+    u','        #  0x6B -> COMMA
+    u'%'        #  0x6C -> PERCENT SIGN
+    u'_'        #  0x6D -> LOW LINE
+    u'>'        #  0x6E -> GREATER-THAN SIGN
+    u'?'        #  0x6F -> QUESTION MARK
+    u'\ufffe'   #  0x70 -> UNDEFINED
+    u'\u05ea'   #  0x71 -> HEBREW LETTER TAV
+    u'\ufffe'   #  0x72 -> UNDEFINED
+    u'\ufffe'   #  0x73 -> UNDEFINED
+    u'\xa0'     #  0x74 -> NO-BREAK SPACE
+    u'\ufffe'   #  0x75 -> UNDEFINED
+    u'\ufffe'   #  0x76 -> UNDEFINED
+    u'\ufffe'   #  0x77 -> UNDEFINED
+    u'\u2017'   #  0x78 -> DOUBLE LOW LINE
+    u'`'        #  0x79 -> GRAVE ACCENT
+    u':'        #  0x7A -> COLON
+    u'#'        #  0x7B -> NUMBER SIGN
+    u'@'        #  0x7C -> COMMERCIAL AT
+    u"'"        #  0x7D -> APOSTROPHE
+    u'='        #  0x7E -> EQUALS SIGN
+    u'"'        #  0x7F -> QUOTATION MARK
+    u'\ufffe'   #  0x80 -> UNDEFINED
+    u'a'        #  0x81 -> LATIN SMALL LETTER A
+    u'b'        #  0x82 -> LATIN SMALL LETTER B
+    u'c'        #  0x83 -> LATIN SMALL LETTER C
+    u'd'        #  0x84 -> LATIN SMALL LETTER D
+    u'e'        #  0x85 -> LATIN SMALL LETTER E
+    u'f'        #  0x86 -> LATIN SMALL LETTER F
+    u'g'        #  0x87 -> LATIN SMALL LETTER G
+    u'h'        #  0x88 -> LATIN SMALL LETTER H
+    u'i'        #  0x89 -> LATIN SMALL LETTER I
+    u'\xab'     #  0x8A -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xbb'     #  0x8B -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\ufffe'   #  0x8C -> UNDEFINED
+    u'\ufffe'   #  0x8D -> UNDEFINED
+    u'\ufffe'   #  0x8E -> UNDEFINED
+    u'\xb1'     #  0x8F -> PLUS-MINUS SIGN
+    u'\xb0'     #  0x90 -> DEGREE SIGN
+    u'j'        #  0x91 -> LATIN SMALL LETTER J
+    u'k'        #  0x92 -> LATIN SMALL LETTER K
+    u'l'        #  0x93 -> LATIN SMALL LETTER L
+    u'm'        #  0x94 -> LATIN SMALL LETTER M
+    u'n'        #  0x95 -> LATIN SMALL LETTER N
+    u'o'        #  0x96 -> LATIN SMALL LETTER O
+    u'p'        #  0x97 -> LATIN SMALL LETTER P
+    u'q'        #  0x98 -> LATIN SMALL LETTER Q
+    u'r'        #  0x99 -> LATIN SMALL LETTER R
+    u'\ufffe'   #  0x9A -> UNDEFINED
+    u'\ufffe'   #  0x9B -> UNDEFINED
+    u'\ufffe'   #  0x9C -> UNDEFINED
+    u'\xb8'     #  0x9D -> CEDILLA
+    u'\ufffe'   #  0x9E -> UNDEFINED
+    u'\xa4'     #  0x9F -> CURRENCY SIGN
+    u'\xb5'     #  0xA0 -> MICRO SIGN
+    u'~'        #  0xA1 -> TILDE
+    u's'        #  0xA2 -> LATIN SMALL LETTER S
+    u't'        #  0xA3 -> LATIN SMALL LETTER T
+    u'u'        #  0xA4 -> LATIN SMALL LETTER U
+    u'v'        #  0xA5 -> LATIN SMALL LETTER V
+    u'w'        #  0xA6 -> LATIN SMALL LETTER W
+    u'x'        #  0xA7 -> LATIN SMALL LETTER X
+    u'y'        #  0xA8 -> LATIN SMALL LETTER Y
+    u'z'        #  0xA9 -> LATIN SMALL LETTER Z
+    u'\ufffe'   #  0xAA -> UNDEFINED
+    u'\ufffe'   #  0xAB -> UNDEFINED
+    u'\ufffe'   #  0xAC -> UNDEFINED
+    u'\ufffe'   #  0xAD -> UNDEFINED
+    u'\ufffe'   #  0xAE -> UNDEFINED
+    u'\xae'     #  0xAF -> REGISTERED SIGN
+    u'^'        #  0xB0 -> CIRCUMFLEX ACCENT
+    u'\xa3'     #  0xB1 -> POUND SIGN
+    u'\xa5'     #  0xB2 -> YEN SIGN
+    u'\xb7'     #  0xB3 -> MIDDLE DOT
+    u'\xa9'     #  0xB4 -> COPYRIGHT SIGN
+    u'\xa7'     #  0xB5 -> SECTION SIGN
+    u'\xb6'     #  0xB6 -> PILCROW SIGN
+    u'\xbc'     #  0xB7 -> VULGAR FRACTION ONE QUARTER
+    u'\xbd'     #  0xB8 -> VULGAR FRACTION ONE HALF
+    u'\xbe'     #  0xB9 -> VULGAR FRACTION THREE QUARTERS
+    u'['        #  0xBA -> LEFT SQUARE BRACKET
+    u']'        #  0xBB -> RIGHT SQUARE BRACKET
+    u'\xaf'     #  0xBC -> MACRON
+    u'\xa8'     #  0xBD -> DIAERESIS
+    u'\xb4'     #  0xBE -> ACUTE ACCENT
+    u'\xd7'     #  0xBF -> MULTIPLICATION SIGN
+    u'{'        #  0xC0 -> LEFT CURLY BRACKET
+    u'A'        #  0xC1 -> LATIN CAPITAL LETTER A
+    u'B'        #  0xC2 -> LATIN CAPITAL LETTER B
+    u'C'        #  0xC3 -> LATIN CAPITAL LETTER C
+    u'D'        #  0xC4 -> LATIN CAPITAL LETTER D
+    u'E'        #  0xC5 -> LATIN CAPITAL LETTER E
+    u'F'        #  0xC6 -> LATIN CAPITAL LETTER F
+    u'G'        #  0xC7 -> LATIN CAPITAL LETTER G
+    u'H'        #  0xC8 -> LATIN CAPITAL LETTER H
+    u'I'        #  0xC9 -> LATIN CAPITAL LETTER I
+    u'\xad'     #  0xCA -> SOFT HYPHEN
+    u'\ufffe'   #  0xCB -> UNDEFINED
+    u'\ufffe'   #  0xCC -> UNDEFINED
+    u'\ufffe'   #  0xCD -> UNDEFINED
+    u'\ufffe'   #  0xCE -> UNDEFINED
+    u'\ufffe'   #  0xCF -> UNDEFINED
+    u'}'        #  0xD0 -> RIGHT CURLY BRACKET
+    u'J'        #  0xD1 -> LATIN CAPITAL LETTER J
+    u'K'        #  0xD2 -> LATIN CAPITAL LETTER K
+    u'L'        #  0xD3 -> LATIN CAPITAL LETTER L
+    u'M'        #  0xD4 -> LATIN CAPITAL LETTER M
+    u'N'        #  0xD5 -> LATIN CAPITAL LETTER N
+    u'O'        #  0xD6 -> LATIN CAPITAL LETTER O
+    u'P'        #  0xD7 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0xD8 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0xD9 -> LATIN CAPITAL LETTER R
+    u'\xb9'     #  0xDA -> SUPERSCRIPT ONE
+    u'\ufffe'   #  0xDB -> UNDEFINED
+    u'\ufffe'   #  0xDC -> UNDEFINED
+    u'\ufffe'   #  0xDD -> UNDEFINED
+    u'\ufffe'   #  0xDE -> UNDEFINED
+    u'\ufffe'   #  0xDF -> UNDEFINED
+    u'\\'       #  0xE0 -> REVERSE SOLIDUS
+    u'\xf7'     #  0xE1 -> DIVISION SIGN
+    u'S'        #  0xE2 -> LATIN CAPITAL LETTER S
+    u'T'        #  0xE3 -> LATIN CAPITAL LETTER T
+    u'U'        #  0xE4 -> LATIN CAPITAL LETTER U
+    u'V'        #  0xE5 -> LATIN CAPITAL LETTER V
+    u'W'        #  0xE6 -> LATIN CAPITAL LETTER W
+    u'X'        #  0xE7 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0xE8 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0xE9 -> LATIN CAPITAL LETTER Z
+    u'\xb2'     #  0xEA -> SUPERSCRIPT TWO
+    u'\ufffe'   #  0xEB -> UNDEFINED
+    u'\ufffe'   #  0xEC -> UNDEFINED
+    u'\ufffe'   #  0xED -> UNDEFINED
+    u'\ufffe'   #  0xEE -> UNDEFINED
+    u'\ufffe'   #  0xEF -> UNDEFINED
+    u'0'        #  0xF0 -> DIGIT ZERO
+    u'1'        #  0xF1 -> DIGIT ONE
+    u'2'        #  0xF2 -> DIGIT TWO
+    u'3'        #  0xF3 -> DIGIT THREE
+    u'4'        #  0xF4 -> DIGIT FOUR
+    u'5'        #  0xF5 -> DIGIT FIVE
+    u'6'        #  0xF6 -> DIGIT SIX
+    u'7'        #  0xF7 -> DIGIT SEVEN
+    u'8'        #  0xF8 -> DIGIT EIGHT
+    u'9'        #  0xF9 -> DIGIT NINE
+    u'\xb3'     #  0xFA -> SUPERSCRIPT THREE
+    u'\ufffe'   #  0xFB -> UNDEFINED
+    u'\ufffe'   #  0xFC -> UNDEFINED
+    u'\ufffe'   #  0xFD -> UNDEFINED
+    u'\ufffe'   #  0xFE -> UNDEFINED
+    u'\x9f'     #  0xFF -> EIGHT ONES
+)
+
+### Encoding table
+encoding_table=codecs.charmap_build(decoding_table)

Added: vendor/Python/current/Lib/encodings/cp437.py
===================================================================
--- vendor/Python/current/Lib/encodings/cp437.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/cp437.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,698 @@
+""" Python Character Mapping Codec cp437 generated from 'VENDORS/MICSFT/PC/CP437.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_map)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='cp437',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+### Decoding Map
+
+decoding_map = codecs.make_identity_dict(range(256))
+decoding_map.update({
+    0x0080: 0x00c7,     #  LATIN CAPITAL LETTER C WITH CEDILLA
+    0x0081: 0x00fc,     #  LATIN SMALL LETTER U WITH DIAERESIS
+    0x0082: 0x00e9,     #  LATIN SMALL LETTER E WITH ACUTE
+    0x0083: 0x00e2,     #  LATIN SMALL LETTER A WITH CIRCUMFLEX
+    0x0084: 0x00e4,     #  LATIN SMALL LETTER A WITH DIAERESIS
+    0x0085: 0x00e0,     #  LATIN SMALL LETTER A WITH GRAVE
+    0x0086: 0x00e5,     #  LATIN SMALL LETTER A WITH RING ABOVE
+    0x0087: 0x00e7,     #  LATIN SMALL LETTER C WITH CEDILLA
+    0x0088: 0x00ea,     #  LATIN SMALL LETTER E WITH CIRCUMFLEX
+    0x0089: 0x00eb,     #  LATIN SMALL LETTER E WITH DIAERESIS
+    0x008a: 0x00e8,     #  LATIN SMALL LETTER E WITH GRAVE
+    0x008b: 0x00ef,     #  LATIN SMALL LETTER I WITH DIAERESIS
+    0x008c: 0x00ee,     #  LATIN SMALL LETTER I WITH CIRCUMFLEX
+    0x008d: 0x00ec,     #  LATIN SMALL LETTER I WITH GRAVE
+    0x008e: 0x00c4,     #  LATIN CAPITAL LETTER A WITH DIAERESIS
+    0x008f: 0x00c5,     #  LATIN CAPITAL LETTER A WITH RING ABOVE
+    0x0090: 0x00c9,     #  LATIN CAPITAL LETTER E WITH ACUTE
+    0x0091: 0x00e6,     #  LATIN SMALL LIGATURE AE
+    0x0092: 0x00c6,     #  LATIN CAPITAL LIGATURE AE
+    0x0093: 0x00f4,     #  LATIN SMALL LETTER O WITH CIRCUMFLEX
+    0x0094: 0x00f6,     #  LATIN SMALL LETTER O WITH DIAERESIS
+    0x0095: 0x00f2,     #  LATIN SMALL LETTER O WITH GRAVE
+    0x0096: 0x00fb,     #  LATIN SMALL LETTER U WITH CIRCUMFLEX
+    0x0097: 0x00f9,     #  LATIN SMALL LETTER U WITH GRAVE
+    0x0098: 0x00ff,     #  LATIN SMALL LETTER Y WITH DIAERESIS
+    0x0099: 0x00d6,     #  LATIN CAPITAL LETTER O WITH DIAERESIS
+    0x009a: 0x00dc,     #  LATIN CAPITAL LETTER U WITH DIAERESIS
+    0x009b: 0x00a2,     #  CENT SIGN
+    0x009c: 0x00a3,     #  POUND SIGN
+    0x009d: 0x00a5,     #  YEN SIGN
+    0x009e: 0x20a7,     #  PESETA SIGN
+    0x009f: 0x0192,     #  LATIN SMALL LETTER F WITH HOOK
+    0x00a0: 0x00e1,     #  LATIN SMALL LETTER A WITH ACUTE
+    0x00a1: 0x00ed,     #  LATIN SMALL LETTER I WITH ACUTE
+    0x00a2: 0x00f3,     #  LATIN SMALL LETTER O WITH ACUTE
+    0x00a3: 0x00fa,     #  LATIN SMALL LETTER U WITH ACUTE
+    0x00a4: 0x00f1,     #  LATIN SMALL LETTER N WITH TILDE
+    0x00a5: 0x00d1,     #  LATIN CAPITAL LETTER N WITH TILDE
+    0x00a6: 0x00aa,     #  FEMININE ORDINAL INDICATOR
+    0x00a7: 0x00ba,     #  MASCULINE ORDINAL INDICATOR
+    0x00a8: 0x00bf,     #  INVERTED QUESTION MARK
+    0x00a9: 0x2310,     #  REVERSED NOT SIGN
+    0x00aa: 0x00ac,     #  NOT SIGN
+    0x00ab: 0x00bd,     #  VULGAR FRACTION ONE HALF
+    0x00ac: 0x00bc,     #  VULGAR FRACTION ONE QUARTER
+    0x00ad: 0x00a1,     #  INVERTED EXCLAMATION MARK
+    0x00ae: 0x00ab,     #  LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    0x00af: 0x00bb,     #  RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    0x00b0: 0x2591,     #  LIGHT SHADE
+    0x00b1: 0x2592,     #  MEDIUM SHADE
+    0x00b2: 0x2593,     #  DARK SHADE
+    0x00b3: 0x2502,     #  BOX DRAWINGS LIGHT VERTICAL
+    0x00b4: 0x2524,     #  BOX DRAWINGS LIGHT VERTICAL AND LEFT
+    0x00b5: 0x2561,     #  BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+    0x00b6: 0x2562,     #  BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
+    0x00b7: 0x2556,     #  BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
+    0x00b8: 0x2555,     #  BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
+    0x00b9: 0x2563,     #  BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+    0x00ba: 0x2551,     #  BOX DRAWINGS DOUBLE VERTICAL
+    0x00bb: 0x2557,     #  BOX DRAWINGS DOUBLE DOWN AND LEFT
+    0x00bc: 0x255d,     #  BOX DRAWINGS DOUBLE UP AND LEFT
+    0x00bd: 0x255c,     #  BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
+    0x00be: 0x255b,     #  BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+    0x00bf: 0x2510,     #  BOX DRAWINGS LIGHT DOWN AND LEFT
+    0x00c0: 0x2514,     #  BOX DRAWINGS LIGHT UP AND RIGHT
+    0x00c1: 0x2534,     #  BOX DRAWINGS LIGHT UP AND HORIZONTAL
+    0x00c2: 0x252c,     #  BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+    0x00c3: 0x251c,     #  BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+    0x00c4: 0x2500,     #  BOX DRAWINGS LIGHT HORIZONTAL
+    0x00c5: 0x253c,     #  BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+    0x00c6: 0x255e,     #  BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+    0x00c7: 0x255f,     #  BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+    0x00c8: 0x255a,     #  BOX DRAWINGS DOUBLE UP AND RIGHT
+    0x00c9: 0x2554,     #  BOX DRAWINGS DOUBLE DOWN AND RIGHT
+    0x00ca: 0x2569,     #  BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+    0x00cb: 0x2566,     #  BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+    0x00cc: 0x2560,     #  BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+    0x00cd: 0x2550,     #  BOX DRAWINGS DOUBLE HORIZONTAL
+    0x00ce: 0x256c,     #  BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+    0x00cf: 0x2567,     #  BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+    0x00d0: 0x2568,     #  BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+    0x00d1: 0x2564,     #  BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
+    0x00d2: 0x2565,     #  BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
+    0x00d3: 0x2559,     #  BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+    0x00d4: 0x2558,     #  BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+    0x00d5: 0x2552,     #  BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+    0x00d6: 0x2553,     #  BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
+    0x00d7: 0x256b,     #  BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
+    0x00d8: 0x256a,     #  BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+    0x00d9: 0x2518,     #  BOX DRAWINGS LIGHT UP AND LEFT
+    0x00da: 0x250c,     #  BOX DRAWINGS LIGHT DOWN AND RIGHT
+    0x00db: 0x2588,     #  FULL BLOCK
+    0x00dc: 0x2584,     #  LOWER HALF BLOCK
+    0x00dd: 0x258c,     #  LEFT HALF BLOCK
+    0x00de: 0x2590,     #  RIGHT HALF BLOCK
+    0x00df: 0x2580,     #  UPPER HALF BLOCK
+    0x00e0: 0x03b1,     #  GREEK SMALL LETTER ALPHA
+    0x00e1: 0x00df,     #  LATIN SMALL LETTER SHARP S
+    0x00e2: 0x0393,     #  GREEK CAPITAL LETTER GAMMA
+    0x00e3: 0x03c0,     #  GREEK SMALL LETTER PI
+    0x00e4: 0x03a3,     #  GREEK CAPITAL LETTER SIGMA
+    0x00e5: 0x03c3,     #  GREEK SMALL LETTER SIGMA
+    0x00e6: 0x00b5,     #  MICRO SIGN
+    0x00e7: 0x03c4,     #  GREEK SMALL LETTER TAU
+    0x00e8: 0x03a6,     #  GREEK CAPITAL LETTER PHI
+    0x00e9: 0x0398,     #  GREEK CAPITAL LETTER THETA
+    0x00ea: 0x03a9,     #  GREEK CAPITAL LETTER OMEGA
+    0x00eb: 0x03b4,     #  GREEK SMALL LETTER DELTA
+    0x00ec: 0x221e,     #  INFINITY
+    0x00ed: 0x03c6,     #  GREEK SMALL LETTER PHI
+    0x00ee: 0x03b5,     #  GREEK SMALL LETTER EPSILON
+    0x00ef: 0x2229,     #  INTERSECTION
+    0x00f0: 0x2261,     #  IDENTICAL TO
+    0x00f1: 0x00b1,     #  PLUS-MINUS SIGN
+    0x00f2: 0x2265,     #  GREATER-THAN OR EQUAL TO
+    0x00f3: 0x2264,     #  LESS-THAN OR EQUAL TO
+    0x00f4: 0x2320,     #  TOP HALF INTEGRAL
+    0x00f5: 0x2321,     #  BOTTOM HALF INTEGRAL
+    0x00f6: 0x00f7,     #  DIVISION SIGN
+    0x00f7: 0x2248,     #  ALMOST EQUAL TO
+    0x00f8: 0x00b0,     #  DEGREE SIGN
+    0x00f9: 0x2219,     #  BULLET OPERATOR
+    0x00fa: 0x00b7,     #  MIDDLE DOT
+    0x00fb: 0x221a,     #  SQUARE ROOT
+    0x00fc: 0x207f,     #  SUPERSCRIPT LATIN SMALL LETTER N
+    0x00fd: 0x00b2,     #  SUPERSCRIPT TWO
+    0x00fe: 0x25a0,     #  BLACK SQUARE
+    0x00ff: 0x00a0,     #  NO-BREAK SPACE
+})
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x0000 -> NULL
+    u'\x01'     #  0x0001 -> START OF HEADING
+    u'\x02'     #  0x0002 -> START OF TEXT
+    u'\x03'     #  0x0003 -> END OF TEXT
+    u'\x04'     #  0x0004 -> END OF TRANSMISSION
+    u'\x05'     #  0x0005 -> ENQUIRY
+    u'\x06'     #  0x0006 -> ACKNOWLEDGE
+    u'\x07'     #  0x0007 -> BELL
+    u'\x08'     #  0x0008 -> BACKSPACE
+    u'\t'       #  0x0009 -> HORIZONTAL TABULATION
+    u'\n'       #  0x000a -> LINE FEED
+    u'\x0b'     #  0x000b -> VERTICAL TABULATION
+    u'\x0c'     #  0x000c -> FORM FEED
+    u'\r'       #  0x000d -> CARRIAGE RETURN
+    u'\x0e'     #  0x000e -> SHIFT OUT
+    u'\x0f'     #  0x000f -> SHIFT IN
+    u'\x10'     #  0x0010 -> DATA LINK ESCAPE
+    u'\x11'     #  0x0011 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x0012 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x0013 -> DEVICE CONTROL THREE
+    u'\x14'     #  0x0014 -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x0015 -> NEGATIVE ACKNOWLEDGE
+    u'\x16'     #  0x0016 -> SYNCHRONOUS IDLE
+    u'\x17'     #  0x0017 -> END OF TRANSMISSION BLOCK
+    u'\x18'     #  0x0018 -> CANCEL
+    u'\x19'     #  0x0019 -> END OF MEDIUM
+    u'\x1a'     #  0x001a -> SUBSTITUTE
+    u'\x1b'     #  0x001b -> ESCAPE
+    u'\x1c'     #  0x001c -> FILE SEPARATOR
+    u'\x1d'     #  0x001d -> GROUP SEPARATOR
+    u'\x1e'     #  0x001e -> RECORD SEPARATOR
+    u'\x1f'     #  0x001f -> UNIT SEPARATOR
+    u' '        #  0x0020 -> SPACE
+    u'!'        #  0x0021 -> EXCLAMATION MARK
+    u'"'        #  0x0022 -> QUOTATION MARK
+    u'#'        #  0x0023 -> NUMBER SIGN
+    u'$'        #  0x0024 -> DOLLAR SIGN
+    u'%'        #  0x0025 -> PERCENT SIGN
+    u'&'        #  0x0026 -> AMPERSAND
+    u"'"        #  0x0027 -> APOSTROPHE
+    u'('        #  0x0028 -> LEFT PARENTHESIS
+    u')'        #  0x0029 -> RIGHT PARENTHESIS
+    u'*'        #  0x002a -> ASTERISK
+    u'+'        #  0x002b -> PLUS SIGN
+    u','        #  0x002c -> COMMA
+    u'-'        #  0x002d -> HYPHEN-MINUS
+    u'.'        #  0x002e -> FULL STOP
+    u'/'        #  0x002f -> SOLIDUS
+    u'0'        #  0x0030 -> DIGIT ZERO
+    u'1'        #  0x0031 -> DIGIT ONE
+    u'2'        #  0x0032 -> DIGIT TWO
+    u'3'        #  0x0033 -> DIGIT THREE
+    u'4'        #  0x0034 -> DIGIT FOUR
+    u'5'        #  0x0035 -> DIGIT FIVE
+    u'6'        #  0x0036 -> DIGIT SIX
+    u'7'        #  0x0037 -> DIGIT SEVEN
+    u'8'        #  0x0038 -> DIGIT EIGHT
+    u'9'        #  0x0039 -> DIGIT NINE
+    u':'        #  0x003a -> COLON
+    u';'        #  0x003b -> SEMICOLON
+    u'<'        #  0x003c -> LESS-THAN SIGN
+    u'='        #  0x003d -> EQUALS SIGN
+    u'>'        #  0x003e -> GREATER-THAN SIGN
+    u'?'        #  0x003f -> QUESTION MARK
+    u'@'        #  0x0040 -> COMMERCIAL AT
+    u'A'        #  0x0041 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x0042 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x0043 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x0044 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x0045 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x0046 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x0047 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x0048 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x0049 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x004a -> LATIN CAPITAL LETTER J
+    u'K'        #  0x004b -> LATIN CAPITAL LETTER K
+    u'L'        #  0x004c -> LATIN CAPITAL LETTER L
+    u'M'        #  0x004d -> LATIN CAPITAL LETTER M
+    u'N'        #  0x004e -> LATIN CAPITAL LETTER N
+    u'O'        #  0x004f -> LATIN CAPITAL LETTER O
+    u'P'        #  0x0050 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x0051 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x0052 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x0053 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x0054 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x0055 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x0056 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x0057 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x0058 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x0059 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x005a -> LATIN CAPITAL LETTER Z
+    u'['        #  0x005b -> LEFT SQUARE BRACKET
+    u'\\'       #  0x005c -> REVERSE SOLIDUS
+    u']'        #  0x005d -> RIGHT SQUARE BRACKET
+    u'^'        #  0x005e -> CIRCUMFLEX ACCENT
+    u'_'        #  0x005f -> LOW LINE
+    u'`'        #  0x0060 -> GRAVE ACCENT
+    u'a'        #  0x0061 -> LATIN SMALL LETTER A
+    u'b'        #  0x0062 -> LATIN SMALL LETTER B
+    u'c'        #  0x0063 -> LATIN SMALL LETTER C
+    u'd'        #  0x0064 -> LATIN SMALL LETTER D
+    u'e'        #  0x0065 -> LATIN SMALL LETTER E
+    u'f'        #  0x0066 -> LATIN SMALL LETTER F
+    u'g'        #  0x0067 -> LATIN SMALL LETTER G
+    u'h'        #  0x0068 -> LATIN SMALL LETTER H
+    u'i'        #  0x0069 -> LATIN SMALL LETTER I
+    u'j'        #  0x006a -> LATIN SMALL LETTER J
+    u'k'        #  0x006b -> LATIN SMALL LETTER K
+    u'l'        #  0x006c -> LATIN SMALL LETTER L
+    u'm'        #  0x006d -> LATIN SMALL LETTER M
+    u'n'        #  0x006e -> LATIN SMALL LETTER N
+    u'o'        #  0x006f -> LATIN SMALL LETTER O
+    u'p'        #  0x0070 -> LATIN SMALL LETTER P
+    u'q'        #  0x0071 -> LATIN SMALL LETTER Q
+    u'r'        #  0x0072 -> LATIN SMALL LETTER R
+    u's'        #  0x0073 -> LATIN SMALL LETTER S
+    u't'        #  0x0074 -> LATIN SMALL LETTER T
+    u'u'        #  0x0075 -> LATIN SMALL LETTER U
+    u'v'        #  0x0076 -> LATIN SMALL LETTER V
+    u'w'        #  0x0077 -> LATIN SMALL LETTER W
+    u'x'        #  0x0078 -> LATIN SMALL LETTER X
+    u'y'        #  0x0079 -> LATIN SMALL LETTER Y
+    u'z'        #  0x007a -> LATIN SMALL LETTER Z
+    u'{'        #  0x007b -> LEFT CURLY BRACKET
+    u'|'        #  0x007c -> VERTICAL LINE
+    u'}'        #  0x007d -> RIGHT CURLY BRACKET
+    u'~'        #  0x007e -> TILDE
+    u'\x7f'     #  0x007f -> DELETE
+    u'\xc7'     #  0x0080 -> LATIN CAPITAL LETTER C WITH CEDILLA
+    u'\xfc'     #  0x0081 -> LATIN SMALL LETTER U WITH DIAERESIS
+    u'\xe9'     #  0x0082 -> LATIN SMALL LETTER E WITH ACUTE
+    u'\xe2'     #  0x0083 -> LATIN SMALL LETTER A WITH CIRCUMFLEX
+    u'\xe4'     #  0x0084 -> LATIN SMALL LETTER A WITH DIAERESIS
+    u'\xe0'     #  0x0085 -> LATIN SMALL LETTER A WITH GRAVE
+    u'\xe5'     #  0x0086 -> LATIN SMALL LETTER A WITH RING ABOVE
+    u'\xe7'     #  0x0087 -> LATIN SMALL LETTER C WITH CEDILLA
+    u'\xea'     #  0x0088 -> LATIN SMALL LETTER E WITH CIRCUMFLEX
+    u'\xeb'     #  0x0089 -> LATIN SMALL LETTER E WITH DIAERESIS
+    u'\xe8'     #  0x008a -> LATIN SMALL LETTER E WITH GRAVE
+    u'\xef'     #  0x008b -> LATIN SMALL LETTER I WITH DIAERESIS
+    u'\xee'     #  0x008c -> LATIN SMALL LETTER I WITH CIRCUMFLEX
+    u'\xec'     #  0x008d -> LATIN SMALL LETTER I WITH GRAVE
+    u'\xc4'     #  0x008e -> LATIN CAPITAL LETTER A WITH DIAERESIS
+    u'\xc5'     #  0x008f -> LATIN CAPITAL LETTER A WITH RING ABOVE
+    u'\xc9'     #  0x0090 -> LATIN CAPITAL LETTER E WITH ACUTE
+    u'\xe6'     #  0x0091 -> LATIN SMALL LIGATURE AE
+    u'\xc6'     #  0x0092 -> LATIN CAPITAL LIGATURE AE
+    u'\xf4'     #  0x0093 -> LATIN SMALL LETTER O WITH CIRCUMFLEX
+    u'\xf6'     #  0x0094 -> LATIN SMALL LETTER O WITH DIAERESIS
+    u'\xf2'     #  0x0095 -> LATIN SMALL LETTER O WITH GRAVE
+    u'\xfb'     #  0x0096 -> LATIN SMALL LETTER U WITH CIRCUMFLEX
+    u'\xf9'     #  0x0097 -> LATIN SMALL LETTER U WITH GRAVE
+    u'\xff'     #  0x0098 -> LATIN SMALL LETTER Y WITH DIAERESIS
+    u'\xd6'     #  0x0099 -> LATIN CAPITAL LETTER O WITH DIAERESIS
+    u'\xdc'     #  0x009a -> LATIN CAPITAL LETTER U WITH DIAERESIS
+    u'\xa2'     #  0x009b -> CENT SIGN
+    u'\xa3'     #  0x009c -> POUND SIGN
+    u'\xa5'     #  0x009d -> YEN SIGN
+    u'\u20a7'   #  0x009e -> PESETA SIGN
+    u'\u0192'   #  0x009f -> LATIN SMALL LETTER F WITH HOOK
+    u'\xe1'     #  0x00a0 -> LATIN SMALL LETTER A WITH ACUTE
+    u'\xed'     #  0x00a1 -> LATIN SMALL LETTER I WITH ACUTE
+    u'\xf3'     #  0x00a2 -> LATIN SMALL LETTER O WITH ACUTE
+    u'\xfa'     #  0x00a3 -> LATIN SMALL LETTER U WITH ACUTE
+    u'\xf1'     #  0x00a4 -> LATIN SMALL LETTER N WITH TILDE
+    u'\xd1'     #  0x00a5 -> LATIN CAPITAL LETTER N WITH TILDE
+    u'\xaa'     #  0x00a6 -> FEMININE ORDINAL INDICATOR
+    u'\xba'     #  0x00a7 -> MASCULINE ORDINAL INDICATOR
+    u'\xbf'     #  0x00a8 -> INVERTED QUESTION MARK
+    u'\u2310'   #  0x00a9 -> REVERSED NOT SIGN
+    u'\xac'     #  0x00aa -> NOT SIGN
+    u'\xbd'     #  0x00ab -> VULGAR FRACTION ONE HALF
+    u'\xbc'     #  0x00ac -> VULGAR FRACTION ONE QUARTER
+    u'\xa1'     #  0x00ad -> INVERTED EXCLAMATION MARK
+    u'\xab'     #  0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xbb'     #  0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\u2591'   #  0x00b0 -> LIGHT SHADE
+    u'\u2592'   #  0x00b1 -> MEDIUM SHADE
+    u'\u2593'   #  0x00b2 -> DARK SHADE
+    u'\u2502'   #  0x00b3 -> BOX DRAWINGS LIGHT VERTICAL
+    u'\u2524'   #  0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT
+    u'\u2561'   #  0x00b5 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+    u'\u2562'   #  0x00b6 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
+    u'\u2556'   #  0x00b7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
+    u'\u2555'   #  0x00b8 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
+    u'\u2563'   #  0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+    u'\u2551'   #  0x00ba -> BOX DRAWINGS DOUBLE VERTICAL
+    u'\u2557'   #  0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT
+    u'\u255d'   #  0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT
+    u'\u255c'   #  0x00bd -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
+    u'\u255b'   #  0x00be -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+    u'\u2510'   #  0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT
+    u'\u2514'   #  0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT
+    u'\u2534'   #  0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL
+    u'\u252c'   #  0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+    u'\u251c'   #  0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+    u'\u2500'   #  0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL
+    u'\u253c'   #  0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+    u'\u255e'   #  0x00c6 -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+    u'\u255f'   #  0x00c7 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+    u'\u255a'   #  0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT
+    u'\u2554'   #  0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT
+    u'\u2569'   #  0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+    u'\u2566'   #  0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+    u'\u2560'   #  0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+    u'\u2550'   #  0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL
+    u'\u256c'   #  0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+    u'\u2567'   #  0x00cf -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+    u'\u2568'   #  0x00d0 -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+    u'\u2564'   #  0x00d1 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
+    u'\u2565'   #  0x00d2 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
+    u'\u2559'   #  0x00d3 -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+    u'\u2558'   #  0x00d4 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+    u'\u2552'   #  0x00d5 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+    u'\u2553'   #  0x00d6 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
+    u'\u256b'   #  0x00d7 -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
+    u'\u256a'   #  0x00d8 -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+    u'\u2518'   #  0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT
+    u'\u250c'   #  0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT
+    u'\u2588'   #  0x00db -> FULL BLOCK
+    u'\u2584'   #  0x00dc -> LOWER HALF BLOCK
+    u'\u258c'   #  0x00dd -> LEFT HALF BLOCK
+    u'\u2590'   #  0x00de -> RIGHT HALF BLOCK
+    u'\u2580'   #  0x00df -> UPPER HALF BLOCK
+    u'\u03b1'   #  0x00e0 -> GREEK SMALL LETTER ALPHA
+    u'\xdf'     #  0x00e1 -> LATIN SMALL LETTER SHARP S
+    u'\u0393'   #  0x00e2 -> GREEK CAPITAL LETTER GAMMA
+    u'\u03c0'   #  0x00e3 -> GREEK SMALL LETTER PI
+    u'\u03a3'   #  0x00e4 -> GREEK CAPITAL LETTER SIGMA
+    u'\u03c3'   #  0x00e5 -> GREEK SMALL LETTER SIGMA
+    u'\xb5'     #  0x00e6 -> MICRO SIGN
+    u'\u03c4'   #  0x00e7 -> GREEK SMALL LETTER TAU
+    u'\u03a6'   #  0x00e8 -> GREEK CAPITAL LETTER PHI
+    u'\u0398'   #  0x00e9 -> GREEK CAPITAL LETTER THETA
+    u'\u03a9'   #  0x00ea -> GREEK CAPITAL LETTER OMEGA
+    u'\u03b4'   #  0x00eb -> GREEK SMALL LETTER DELTA
+    u'\u221e'   #  0x00ec -> INFINITY
+    u'\u03c6'   #  0x00ed -> GREEK SMALL LETTER PHI
+    u'\u03b5'   #  0x00ee -> GREEK SMALL LETTER EPSILON
+    u'\u2229'   #  0x00ef -> INTERSECTION
+    u'\u2261'   #  0x00f0 -> IDENTICAL TO
+    u'\xb1'     #  0x00f1 -> PLUS-MINUS SIGN
+    u'\u2265'   #  0x00f2 -> GREATER-THAN OR EQUAL TO
+    u'\u2264'   #  0x00f3 -> LESS-THAN OR EQUAL TO
+    u'\u2320'   #  0x00f4 -> TOP HALF INTEGRAL
+    u'\u2321'   #  0x00f5 -> BOTTOM HALF INTEGRAL
+    u'\xf7'     #  0x00f6 -> DIVISION SIGN
+    u'\u2248'   #  0x00f7 -> ALMOST EQUAL TO
+    u'\xb0'     #  0x00f8 -> DEGREE SIGN
+    u'\u2219'   #  0x00f9 -> BULLET OPERATOR
+    u'\xb7'     #  0x00fa -> MIDDLE DOT
+    u'\u221a'   #  0x00fb -> SQUARE ROOT
+    u'\u207f'   #  0x00fc -> SUPERSCRIPT LATIN SMALL LETTER N
+    u'\xb2'     #  0x00fd -> SUPERSCRIPT TWO
+    u'\u25a0'   #  0x00fe -> BLACK SQUARE
+    u'\xa0'     #  0x00ff -> NO-BREAK SPACE
+)
+
+### Encoding Map
+
+encoding_map = {
+    0x0000: 0x0000,     #  NULL
+    0x0001: 0x0001,     #  START OF HEADING
+    0x0002: 0x0002,     #  START OF TEXT
+    0x0003: 0x0003,     #  END OF TEXT
+    0x0004: 0x0004,     #  END OF TRANSMISSION
+    0x0005: 0x0005,     #  ENQUIRY
+    0x0006: 0x0006,     #  ACKNOWLEDGE
+    0x0007: 0x0007,     #  BELL
+    0x0008: 0x0008,     #  BACKSPACE
+    0x0009: 0x0009,     #  HORIZONTAL TABULATION
+    0x000a: 0x000a,     #  LINE FEED
+    0x000b: 0x000b,     #  VERTICAL TABULATION
+    0x000c: 0x000c,     #  FORM FEED
+    0x000d: 0x000d,     #  CARRIAGE RETURN
+    0x000e: 0x000e,     #  SHIFT OUT
+    0x000f: 0x000f,     #  SHIFT IN
+    0x0010: 0x0010,     #  DATA LINK ESCAPE
+    0x0011: 0x0011,     #  DEVICE CONTROL ONE
+    0x0012: 0x0012,     #  DEVICE CONTROL TWO
+    0x0013: 0x0013,     #  DEVICE CONTROL THREE
+    0x0014: 0x0014,     #  DEVICE CONTROL FOUR
+    0x0015: 0x0015,     #  NEGATIVE ACKNOWLEDGE
+    0x0016: 0x0016,     #  SYNCHRONOUS IDLE
+    0x0017: 0x0017,     #  END OF TRANSMISSION BLOCK
+    0x0018: 0x0018,     #  CANCEL
+    0x0019: 0x0019,     #  END OF MEDIUM
+    0x001a: 0x001a,     #  SUBSTITUTE
+    0x001b: 0x001b,     #  ESCAPE
+    0x001c: 0x001c,     #  FILE SEPARATOR
+    0x001d: 0x001d,     #  GROUP SEPARATOR
+    0x001e: 0x001e,     #  RECORD SEPARATOR
+    0x001f: 0x001f,     #  UNIT SEPARATOR
+    0x0020: 0x0020,     #  SPACE
+    0x0021: 0x0021,     #  EXCLAMATION MARK
+    0x0022: 0x0022,     #  QUOTATION MARK
+    0x0023: 0x0023,     #  NUMBER SIGN
+    0x0024: 0x0024,     #  DOLLAR SIGN
+    0x0025: 0x0025,     #  PERCENT SIGN
+    0x0026: 0x0026,     #  AMPERSAND
+    0x0027: 0x0027,     #  APOSTROPHE
+    0x0028: 0x0028,     #  LEFT PARENTHESIS
+    0x0029: 0x0029,     #  RIGHT PARENTHESIS
+    0x002a: 0x002a,     #  ASTERISK
+    0x002b: 0x002b,     #  PLUS SIGN
+    0x002c: 0x002c,     #  COMMA
+    0x002d: 0x002d,     #  HYPHEN-MINUS
+    0x002e: 0x002e,     #  FULL STOP
+    0x002f: 0x002f,     #  SOLIDUS
+    0x0030: 0x0030,     #  DIGIT ZERO
+    0x0031: 0x0031,     #  DIGIT ONE
+    0x0032: 0x0032,     #  DIGIT TWO
+    0x0033: 0x0033,     #  DIGIT THREE
+    0x0034: 0x0034,     #  DIGIT FOUR
+    0x0035: 0x0035,     #  DIGIT FIVE
+    0x0036: 0x0036,     #  DIGIT SIX
+    0x0037: 0x0037,     #  DIGIT SEVEN
+    0x0038: 0x0038,     #  DIGIT EIGHT
+    0x0039: 0x0039,     #  DIGIT NINE
+    0x003a: 0x003a,     #  COLON
+    0x003b: 0x003b,     #  SEMICOLON
+    0x003c: 0x003c,     #  LESS-THAN SIGN
+    0x003d: 0x003d,     #  EQUALS SIGN
+    0x003e: 0x003e,     #  GREATER-THAN SIGN
+    0x003f: 0x003f,     #  QUESTION MARK
+    0x0040: 0x0040,     #  COMMERCIAL AT
+    0x0041: 0x0041,     #  LATIN CAPITAL LETTER A
+    0x0042: 0x0042,     #  LATIN CAPITAL LETTER B
+    0x0043: 0x0043,     #  LATIN CAPITAL LETTER C
+    0x0044: 0x0044,     #  LATIN CAPITAL LETTER D
+    0x0045: 0x0045,     #  LATIN CAPITAL LETTER E
+    0x0046: 0x0046,     #  LATIN CAPITAL LETTER F
+    0x0047: 0x0047,     #  LATIN CAPITAL LETTER G
+    0x0048: 0x0048,     #  LATIN CAPITAL LETTER H
+    0x0049: 0x0049,     #  LATIN CAPITAL LETTER I
+    0x004a: 0x004a,     #  LATIN CAPITAL LETTER J
+    0x004b: 0x004b,     #  LATIN CAPITAL LETTER K
+    0x004c: 0x004c,     #  LATIN CAPITAL LETTER L
+    0x004d: 0x004d,     #  LATIN CAPITAL LETTER M
+    0x004e: 0x004e,     #  LATIN CAPITAL LETTER N
+    0x004f: 0x004f,     #  LATIN CAPITAL LETTER O
+    0x0050: 0x0050,     #  LATIN CAPITAL LETTER P
+    0x0051: 0x0051,     #  LATIN CAPITAL LETTER Q
+    0x0052: 0x0052,     #  LATIN CAPITAL LETTER R
+    0x0053: 0x0053,     #  LATIN CAPITAL LETTER S
+    0x0054: 0x0054,     #  LATIN CAPITAL LETTER T
+    0x0055: 0x0055,     #  LATIN CAPITAL LETTER U
+    0x0056: 0x0056,     #  LATIN CAPITAL LETTER V
+    0x0057: 0x0057,     #  LATIN CAPITAL LETTER W
+    0x0058: 0x0058,     #  LATIN CAPITAL LETTER X
+    0x0059: 0x0059,     #  LATIN CAPITAL LETTER Y
+    0x005a: 0x005a,     #  LATIN CAPITAL LETTER Z
+    0x005b: 0x005b,     #  LEFT SQUARE BRACKET
+    0x005c: 0x005c,     #  REVERSE SOLIDUS
+    0x005d: 0x005d,     #  RIGHT SQUARE BRACKET
+    0x005e: 0x005e,     #  CIRCUMFLEX ACCENT
+    0x005f: 0x005f,     #  LOW LINE
+    0x0060: 0x0060,     #  GRAVE ACCENT
+    0x0061: 0x0061,     #  LATIN SMALL LETTER A
+    0x0062: 0x0062,     #  LATIN SMALL LETTER B
+    0x0063: 0x0063,     #  LATIN SMALL LETTER C
+    0x0064: 0x0064,     #  LATIN SMALL LETTER D
+    0x0065: 0x0065,     #  LATIN SMALL LETTER E
+    0x0066: 0x0066,     #  LATIN SMALL LETTER F
+    0x0067: 0x0067,     #  LATIN SMALL LETTER G
+    0x0068: 0x0068,     #  LATIN SMALL LETTER H
+    0x0069: 0x0069,     #  LATIN SMALL LETTER I
+    0x006a: 0x006a,     #  LATIN SMALL LETTER J
+    0x006b: 0x006b,     #  LATIN SMALL LETTER K
+    0x006c: 0x006c,     #  LATIN SMALL LETTER L
+    0x006d: 0x006d,     #  LATIN SMALL LETTER M
+    0x006e: 0x006e,     #  LATIN SMALL LETTER N
+    0x006f: 0x006f,     #  LATIN SMALL LETTER O
+    0x0070: 0x0070,     #  LATIN SMALL LETTER P
+    0x0071: 0x0071,     #  LATIN SMALL LETTER Q
+    0x0072: 0x0072,     #  LATIN SMALL LETTER R
+    0x0073: 0x0073,     #  LATIN SMALL LETTER S
+    0x0074: 0x0074,     #  LATIN SMALL LETTER T
+    0x0075: 0x0075,     #  LATIN SMALL LETTER U
+    0x0076: 0x0076,     #  LATIN SMALL LETTER V
+    0x0077: 0x0077,     #  LATIN SMALL LETTER W
+    0x0078: 0x0078,     #  LATIN SMALL LETTER X
+    0x0079: 0x0079,     #  LATIN SMALL LETTER Y
+    0x007a: 0x007a,     #  LATIN SMALL LETTER Z
+    0x007b: 0x007b,     #  LEFT CURLY BRACKET
+    0x007c: 0x007c,     #  VERTICAL LINE
+    0x007d: 0x007d,     #  RIGHT CURLY BRACKET
+    0x007e: 0x007e,     #  TILDE
+    0x007f: 0x007f,     #  DELETE
+    0x00a0: 0x00ff,     #  NO-BREAK SPACE
+    0x00a1: 0x00ad,     #  INVERTED EXCLAMATION MARK
+    0x00a2: 0x009b,     #  CENT SIGN
+    0x00a3: 0x009c,     #  POUND SIGN
+    0x00a5: 0x009d,     #  YEN SIGN
+    0x00aa: 0x00a6,     #  FEMININE ORDINAL INDICATOR
+    0x00ab: 0x00ae,     #  LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    0x00ac: 0x00aa,     #  NOT SIGN
+    0x00b0: 0x00f8,     #  DEGREE SIGN
+    0x00b1: 0x00f1,     #  PLUS-MINUS SIGN
+    0x00b2: 0x00fd,     #  SUPERSCRIPT TWO
+    0x00b5: 0x00e6,     #  MICRO SIGN
+    0x00b7: 0x00fa,     #  MIDDLE DOT
+    0x00ba: 0x00a7,     #  MASCULINE ORDINAL INDICATOR
+    0x00bb: 0x00af,     #  RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    0x00bc: 0x00ac,     #  VULGAR FRACTION ONE QUARTER
+    0x00bd: 0x00ab,     #  VULGAR FRACTION ONE HALF
+    0x00bf: 0x00a8,     #  INVERTED QUESTION MARK
+    0x00c4: 0x008e,     #  LATIN CAPITAL LETTER A WITH DIAERESIS
+    0x00c5: 0x008f,     #  LATIN CAPITAL LETTER A WITH RING ABOVE
+    0x00c6: 0x0092,     #  LATIN CAPITAL LIGATURE AE
+    0x00c7: 0x0080,     #  LATIN CAPITAL LETTER C WITH CEDILLA
+    0x00c9: 0x0090,     #  LATIN CAPITAL LETTER E WITH ACUTE
+    0x00d1: 0x00a5,     #  LATIN CAPITAL LETTER N WITH TILDE
+    0x00d6: 0x0099,     #  LATIN CAPITAL LETTER O WITH DIAERESIS
+    0x00dc: 0x009a,     #  LATIN CAPITAL LETTER U WITH DIAERESIS
+    0x00df: 0x00e1,     #  LATIN SMALL LETTER SHARP S
+    0x00e0: 0x0085,     #  LATIN SMALL LETTER A WITH GRAVE
+    0x00e1: 0x00a0,     #  LATIN SMALL LETTER A WITH ACUTE
+    0x00e2: 0x0083,     #  LATIN SMALL LETTER A WITH CIRCUMFLEX
+    0x00e4: 0x0084,     #  LATIN SMALL LETTER A WITH DIAERESIS
+    0x00e5: 0x0086,     #  LATIN SMALL LETTER A WITH RING ABOVE
+    0x00e6: 0x0091,     #  LATIN SMALL LIGATURE AE
+    0x00e7: 0x0087,     #  LATIN SMALL LETTER C WITH CEDILLA
+    0x00e8: 0x008a,     #  LATIN SMALL LETTER E WITH GRAVE
+    0x00e9: 0x0082,     #  LATIN SMALL LETTER E WITH ACUTE
+    0x00ea: 0x0088,     #  LATIN SMALL LETTER E WITH CIRCUMFLEX
+    0x00eb: 0x0089,     #  LATIN SMALL LETTER E WITH DIAERESIS
+    0x00ec: 0x008d,     #  LATIN SMALL LETTER I WITH GRAVE
+    0x00ed: 0x00a1,     #  LATIN SMALL LETTER I WITH ACUTE
+    0x00ee: 0x008c,     #  LATIN SMALL LETTER I WITH CIRCUMFLEX
+    0x00ef: 0x008b,     #  LATIN SMALL LETTER I WITH DIAERESIS
+    0x00f1: 0x00a4,     #  LATIN SMALL LETTER N WITH TILDE
+    0x00f2: 0x0095,     #  LATIN SMALL LETTER O WITH GRAVE
+    0x00f3: 0x00a2,     #  LATIN SMALL LETTER O WITH ACUTE
+    0x00f4: 0x0093,     #  LATIN SMALL LETTER O WITH CIRCUMFLEX
+    0x00f6: 0x0094,     #  LATIN SMALL LETTER O WITH DIAERESIS
+    0x00f7: 0x00f6,     #  DIVISION SIGN
+    0x00f9: 0x0097,     #  LATIN SMALL LETTER U WITH GRAVE
+    0x00fa: 0x00a3,     #  LATIN SMALL LETTER U WITH ACUTE
+    0x00fb: 0x0096,     #  LATIN SMALL LETTER U WITH CIRCUMFLEX
+    0x00fc: 0x0081,     #  LATIN SMALL LETTER U WITH DIAERESIS
+    0x00ff: 0x0098,     #  LATIN SMALL LETTER Y WITH DIAERESIS
+    0x0192: 0x009f,     #  LATIN SMALL LETTER F WITH HOOK
+    0x0393: 0x00e2,     #  GREEK CAPITAL LETTER GAMMA
+    0x0398: 0x00e9,     #  GREEK CAPITAL LETTER THETA
+    0x03a3: 0x00e4,     #  GREEK CAPITAL LETTER SIGMA
+    0x03a6: 0x00e8,     #  GREEK CAPITAL LETTER PHI
+    0x03a9: 0x00ea,     #  GREEK CAPITAL LETTER OMEGA
+    0x03b1: 0x00e0,     #  GREEK SMALL LETTER ALPHA
+    0x03b4: 0x00eb,     #  GREEK SMALL LETTER DELTA
+    0x03b5: 0x00ee,     #  GREEK SMALL LETTER EPSILON
+    0x03c0: 0x00e3,     #  GREEK SMALL LETTER PI
+    0x03c3: 0x00e5,     #  GREEK SMALL LETTER SIGMA
+    0x03c4: 0x00e7,     #  GREEK SMALL LETTER TAU
+    0x03c6: 0x00ed,     #  GREEK SMALL LETTER PHI
+    0x207f: 0x00fc,     #  SUPERSCRIPT LATIN SMALL LETTER N
+    0x20a7: 0x009e,     #  PESETA SIGN
+    0x2219: 0x00f9,     #  BULLET OPERATOR
+    0x221a: 0x00fb,     #  SQUARE ROOT
+    0x221e: 0x00ec,     #  INFINITY
+    0x2229: 0x00ef,     #  INTERSECTION
+    0x2248: 0x00f7,     #  ALMOST EQUAL TO
+    0x2261: 0x00f0,     #  IDENTICAL TO
+    0x2264: 0x00f3,     #  LESS-THAN OR EQUAL TO
+    0x2265: 0x00f2,     #  GREATER-THAN OR EQUAL TO
+    0x2310: 0x00a9,     #  REVERSED NOT SIGN
+    0x2320: 0x00f4,     #  TOP HALF INTEGRAL
+    0x2321: 0x00f5,     #  BOTTOM HALF INTEGRAL
+    0x2500: 0x00c4,     #  BOX DRAWINGS LIGHT HORIZONTAL
+    0x2502: 0x00b3,     #  BOX DRAWINGS LIGHT VERTICAL
+    0x250c: 0x00da,     #  BOX DRAWINGS LIGHT DOWN AND RIGHT
+    0x2510: 0x00bf,     #  BOX DRAWINGS LIGHT DOWN AND LEFT
+    0x2514: 0x00c0,     #  BOX DRAWINGS LIGHT UP AND RIGHT
+    0x2518: 0x00d9,     #  BOX DRAWINGS LIGHT UP AND LEFT
+    0x251c: 0x00c3,     #  BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+    0x2524: 0x00b4,     #  BOX DRAWINGS LIGHT VERTICAL AND LEFT
+    0x252c: 0x00c2,     #  BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+    0x2534: 0x00c1,     #  BOX DRAWINGS LIGHT UP AND HORIZONTAL
+    0x253c: 0x00c5,     #  BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+    0x2550: 0x00cd,     #  BOX DRAWINGS DOUBLE HORIZONTAL
+    0x2551: 0x00ba,     #  BOX DRAWINGS DOUBLE VERTICAL
+    0x2552: 0x00d5,     #  BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+    0x2553: 0x00d6,     #  BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
+    0x2554: 0x00c9,     #  BOX DRAWINGS DOUBLE DOWN AND RIGHT
+    0x2555: 0x00b8,     #  BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
+    0x2556: 0x00b7,     #  BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
+    0x2557: 0x00bb,     #  BOX DRAWINGS DOUBLE DOWN AND LEFT
+    0x2558: 0x00d4,     #  BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+    0x2559: 0x00d3,     #  BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+    0x255a: 0x00c8,     #  BOX DRAWINGS DOUBLE UP AND RIGHT
+    0x255b: 0x00be,     #  BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+    0x255c: 0x00bd,     #  BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
+    0x255d: 0x00bc,     #  BOX DRAWINGS DOUBLE UP AND LEFT
+    0x255e: 0x00c6,     #  BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+    0x255f: 0x00c7,     #  BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+    0x2560: 0x00cc,     #  BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+    0x2561: 0x00b5,     #  BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+    0x2562: 0x00b6,     #  BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
+    0x2563: 0x00b9,     #  BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+    0x2564: 0x00d1,     #  BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
+    0x2565: 0x00d2,     #  BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
+    0x2566: 0x00cb,     #  BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+    0x2567: 0x00cf,     #  BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+    0x2568: 0x00d0,     #  BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+    0x2569: 0x00ca,     #  BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+    0x256a: 0x00d8,     #  BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+    0x256b: 0x00d7,     #  BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
+    0x256c: 0x00ce,     #  BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+    0x2580: 0x00df,     #  UPPER HALF BLOCK
+    0x2584: 0x00dc,     #  LOWER HALF BLOCK
+    0x2588: 0x00db,     #  FULL BLOCK
+    0x258c: 0x00dd,     #  LEFT HALF BLOCK
+    0x2590: 0x00de,     #  RIGHT HALF BLOCK
+    0x2591: 0x00b0,     #  LIGHT SHADE
+    0x2592: 0x00b1,     #  MEDIUM SHADE
+    0x2593: 0x00b2,     #  DARK SHADE
+    0x25a0: 0x00fe,     #  BLACK SQUARE
+}

Added: vendor/Python/current/Lib/encodings/cp500.py
===================================================================
--- vendor/Python/current/Lib/encodings/cp500.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/cp500.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,307 @@
+""" Python Character Mapping Codec cp500 generated from 'MAPPINGS/VENDORS/MICSFT/EBCDIC/CP500.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_table)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_table)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='cp500',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x00 -> NULL
+    u'\x01'     #  0x01 -> START OF HEADING
+    u'\x02'     #  0x02 -> START OF TEXT
+    u'\x03'     #  0x03 -> END OF TEXT
+    u'\x9c'     #  0x04 -> CONTROL
+    u'\t'       #  0x05 -> HORIZONTAL TABULATION
+    u'\x86'     #  0x06 -> CONTROL
+    u'\x7f'     #  0x07 -> DELETE
+    u'\x97'     #  0x08 -> CONTROL
+    u'\x8d'     #  0x09 -> CONTROL
+    u'\x8e'     #  0x0A -> CONTROL
+    u'\x0b'     #  0x0B -> VERTICAL TABULATION
+    u'\x0c'     #  0x0C -> FORM FEED
+    u'\r'       #  0x0D -> CARRIAGE RETURN
+    u'\x0e'     #  0x0E -> SHIFT OUT
+    u'\x0f'     #  0x0F -> SHIFT IN
+    u'\x10'     #  0x10 -> DATA LINK ESCAPE
+    u'\x11'     #  0x11 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x12 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x13 -> DEVICE CONTROL THREE
+    u'\x9d'     #  0x14 -> CONTROL
+    u'\x85'     #  0x15 -> CONTROL
+    u'\x08'     #  0x16 -> BACKSPACE
+    u'\x87'     #  0x17 -> CONTROL
+    u'\x18'     #  0x18 -> CANCEL
+    u'\x19'     #  0x19 -> END OF MEDIUM
+    u'\x92'     #  0x1A -> CONTROL
+    u'\x8f'     #  0x1B -> CONTROL
+    u'\x1c'     #  0x1C -> FILE SEPARATOR
+    u'\x1d'     #  0x1D -> GROUP SEPARATOR
+    u'\x1e'     #  0x1E -> RECORD SEPARATOR
+    u'\x1f'     #  0x1F -> UNIT SEPARATOR
+    u'\x80'     #  0x20 -> CONTROL
+    u'\x81'     #  0x21 -> CONTROL
+    u'\x82'     #  0x22 -> CONTROL
+    u'\x83'     #  0x23 -> CONTROL
+    u'\x84'     #  0x24 -> CONTROL
+    u'\n'       #  0x25 -> LINE FEED
+    u'\x17'     #  0x26 -> END OF TRANSMISSION BLOCK
+    u'\x1b'     #  0x27 -> ESCAPE
+    u'\x88'     #  0x28 -> CONTROL
+    u'\x89'     #  0x29 -> CONTROL
+    u'\x8a'     #  0x2A -> CONTROL
+    u'\x8b'     #  0x2B -> CONTROL
+    u'\x8c'     #  0x2C -> CONTROL
+    u'\x05'     #  0x2D -> ENQUIRY
+    u'\x06'     #  0x2E -> ACKNOWLEDGE
+    u'\x07'     #  0x2F -> BELL
+    u'\x90'     #  0x30 -> CONTROL
+    u'\x91'     #  0x31 -> CONTROL
+    u'\x16'     #  0x32 -> SYNCHRONOUS IDLE
+    u'\x93'     #  0x33 -> CONTROL
+    u'\x94'     #  0x34 -> CONTROL
+    u'\x95'     #  0x35 -> CONTROL
+    u'\x96'     #  0x36 -> CONTROL
+    u'\x04'     #  0x37 -> END OF TRANSMISSION
+    u'\x98'     #  0x38 -> CONTROL
+    u'\x99'     #  0x39 -> CONTROL
+    u'\x9a'     #  0x3A -> CONTROL
+    u'\x9b'     #  0x3B -> CONTROL
+    u'\x14'     #  0x3C -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x3D -> NEGATIVE ACKNOWLEDGE
+    u'\x9e'     #  0x3E -> CONTROL
+    u'\x1a'     #  0x3F -> SUBSTITUTE
+    u' '        #  0x40 -> SPACE
+    u'\xa0'     #  0x41 -> NO-BREAK SPACE
+    u'\xe2'     #  0x42 -> LATIN SMALL LETTER A WITH CIRCUMFLEX
+    u'\xe4'     #  0x43 -> LATIN SMALL LETTER A WITH DIAERESIS
+    u'\xe0'     #  0x44 -> LATIN SMALL LETTER A WITH GRAVE
+    u'\xe1'     #  0x45 -> LATIN SMALL LETTER A WITH ACUTE
+    u'\xe3'     #  0x46 -> LATIN SMALL LETTER A WITH TILDE
+    u'\xe5'     #  0x47 -> LATIN SMALL LETTER A WITH RING ABOVE
+    u'\xe7'     #  0x48 -> LATIN SMALL LETTER C WITH CEDILLA
+    u'\xf1'     #  0x49 -> LATIN SMALL LETTER N WITH TILDE
+    u'['        #  0x4A -> LEFT SQUARE BRACKET
+    u'.'        #  0x4B -> FULL STOP
+    u'<'        #  0x4C -> LESS-THAN SIGN
+    u'('        #  0x4D -> LEFT PARENTHESIS
+    u'+'        #  0x4E -> PLUS SIGN
+    u'!'        #  0x4F -> EXCLAMATION MARK
+    u'&'        #  0x50 -> AMPERSAND
+    u'\xe9'     #  0x51 -> LATIN SMALL LETTER E WITH ACUTE
+    u'\xea'     #  0x52 -> LATIN SMALL LETTER E WITH CIRCUMFLEX
+    u'\xeb'     #  0x53 -> LATIN SMALL LETTER E WITH DIAERESIS
+    u'\xe8'     #  0x54 -> LATIN SMALL LETTER E WITH GRAVE
+    u'\xed'     #  0x55 -> LATIN SMALL LETTER I WITH ACUTE
+    u'\xee'     #  0x56 -> LATIN SMALL LETTER I WITH CIRCUMFLEX
+    u'\xef'     #  0x57 -> LATIN SMALL LETTER I WITH DIAERESIS
+    u'\xec'     #  0x58 -> LATIN SMALL LETTER I WITH GRAVE
+    u'\xdf'     #  0x59 -> LATIN SMALL LETTER SHARP S (GERMAN)
+    u']'        #  0x5A -> RIGHT SQUARE BRACKET
+    u'$'        #  0x5B -> DOLLAR SIGN
+    u'*'        #  0x5C -> ASTERISK
+    u')'        #  0x5D -> RIGHT PARENTHESIS
+    u';'        #  0x5E -> SEMICOLON
+    u'^'        #  0x5F -> CIRCUMFLEX ACCENT
+    u'-'        #  0x60 -> HYPHEN-MINUS
+    u'/'        #  0x61 -> SOLIDUS
+    u'\xc2'     #  0x62 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+    u'\xc4'     #  0x63 -> LATIN CAPITAL LETTER A WITH DIAERESIS
+    u'\xc0'     #  0x64 -> LATIN CAPITAL LETTER A WITH GRAVE
+    u'\xc1'     #  0x65 -> LATIN CAPITAL LETTER A WITH ACUTE
+    u'\xc3'     #  0x66 -> LATIN CAPITAL LETTER A WITH TILDE
+    u'\xc5'     #  0x67 -> LATIN CAPITAL LETTER A WITH RING ABOVE
+    u'\xc7'     #  0x68 -> LATIN CAPITAL LETTER C WITH CEDILLA
+    u'\xd1'     #  0x69 -> LATIN CAPITAL LETTER N WITH TILDE
+    u'\xa6'     #  0x6A -> BROKEN BAR
+    u','        #  0x6B -> COMMA
+    u'%'        #  0x6C -> PERCENT SIGN
+    u'_'        #  0x6D -> LOW LINE
+    u'>'        #  0x6E -> GREATER-THAN SIGN
+    u'?'        #  0x6F -> QUESTION MARK
+    u'\xf8'     #  0x70 -> LATIN SMALL LETTER O WITH STROKE
+    u'\xc9'     #  0x71 -> LATIN CAPITAL LETTER E WITH ACUTE
+    u'\xca'     #  0x72 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+    u'\xcb'     #  0x73 -> LATIN CAPITAL LETTER E WITH DIAERESIS
+    u'\xc8'     #  0x74 -> LATIN CAPITAL LETTER E WITH GRAVE
+    u'\xcd'     #  0x75 -> LATIN CAPITAL LETTER I WITH ACUTE
+    u'\xce'     #  0x76 -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+    u'\xcf'     #  0x77 -> LATIN CAPITAL LETTER I WITH DIAERESIS
+    u'\xcc'     #  0x78 -> LATIN CAPITAL LETTER I WITH GRAVE
+    u'`'        #  0x79 -> GRAVE ACCENT
+    u':'        #  0x7A -> COLON
+    u'#'        #  0x7B -> NUMBER SIGN
+    u'@'        #  0x7C -> COMMERCIAL AT
+    u"'"        #  0x7D -> APOSTROPHE
+    u'='        #  0x7E -> EQUALS SIGN
+    u'"'        #  0x7F -> QUOTATION MARK
+    u'\xd8'     #  0x80 -> LATIN CAPITAL LETTER O WITH STROKE
+    u'a'        #  0x81 -> LATIN SMALL LETTER A
+    u'b'        #  0x82 -> LATIN SMALL LETTER B
+    u'c'        #  0x83 -> LATIN SMALL LETTER C
+    u'd'        #  0x84 -> LATIN SMALL LETTER D
+    u'e'        #  0x85 -> LATIN SMALL LETTER E
+    u'f'        #  0x86 -> LATIN SMALL LETTER F
+    u'g'        #  0x87 -> LATIN SMALL LETTER G
+    u'h'        #  0x88 -> LATIN SMALL LETTER H
+    u'i'        #  0x89 -> LATIN SMALL LETTER I
+    u'\xab'     #  0x8A -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xbb'     #  0x8B -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xf0'     #  0x8C -> LATIN SMALL LETTER ETH (ICELANDIC)
+    u'\xfd'     #  0x8D -> LATIN SMALL LETTER Y WITH ACUTE
+    u'\xfe'     #  0x8E -> LATIN SMALL LETTER THORN (ICELANDIC)
+    u'\xb1'     #  0x8F -> PLUS-MINUS SIGN
+    u'\xb0'     #  0x90 -> DEGREE SIGN
+    u'j'        #  0x91 -> LATIN SMALL LETTER J
+    u'k'        #  0x92 -> LATIN SMALL LETTER K
+    u'l'        #  0x93 -> LATIN SMALL LETTER L
+    u'm'        #  0x94 -> LATIN SMALL LETTER M
+    u'n'        #  0x95 -> LATIN SMALL LETTER N
+    u'o'        #  0x96 -> LATIN SMALL LETTER O
+    u'p'        #  0x97 -> LATIN SMALL LETTER P
+    u'q'        #  0x98 -> LATIN SMALL LETTER Q
+    u'r'        #  0x99 -> LATIN SMALL LETTER R
+    u'\xaa'     #  0x9A -> FEMININE ORDINAL INDICATOR
+    u'\xba'     #  0x9B -> MASCULINE ORDINAL INDICATOR
+    u'\xe6'     #  0x9C -> LATIN SMALL LIGATURE AE
+    u'\xb8'     #  0x9D -> CEDILLA
+    u'\xc6'     #  0x9E -> LATIN CAPITAL LIGATURE AE
+    u'\xa4'     #  0x9F -> CURRENCY SIGN
+    u'\xb5'     #  0xA0 -> MICRO SIGN
+    u'~'        #  0xA1 -> TILDE
+    u's'        #  0xA2 -> LATIN SMALL LETTER S
+    u't'        #  0xA3 -> LATIN SMALL LETTER T
+    u'u'        #  0xA4 -> LATIN SMALL LETTER U
+    u'v'        #  0xA5 -> LATIN SMALL LETTER V
+    u'w'        #  0xA6 -> LATIN SMALL LETTER W
+    u'x'        #  0xA7 -> LATIN SMALL LETTER X
+    u'y'        #  0xA8 -> LATIN SMALL LETTER Y
+    u'z'        #  0xA9 -> LATIN SMALL LETTER Z
+    u'\xa1'     #  0xAA -> INVERTED EXCLAMATION MARK
+    u'\xbf'     #  0xAB -> INVERTED QUESTION MARK
+    u'\xd0'     #  0xAC -> LATIN CAPITAL LETTER ETH (ICELANDIC)
+    u'\xdd'     #  0xAD -> LATIN CAPITAL LETTER Y WITH ACUTE
+    u'\xde'     #  0xAE -> LATIN CAPITAL LETTER THORN (ICELANDIC)
+    u'\xae'     #  0xAF -> REGISTERED SIGN
+    u'\xa2'     #  0xB0 -> CENT SIGN
+    u'\xa3'     #  0xB1 -> POUND SIGN
+    u'\xa5'     #  0xB2 -> YEN SIGN
+    u'\xb7'     #  0xB3 -> MIDDLE DOT
+    u'\xa9'     #  0xB4 -> COPYRIGHT SIGN
+    u'\xa7'     #  0xB5 -> SECTION SIGN
+    u'\xb6'     #  0xB6 -> PILCROW SIGN
+    u'\xbc'     #  0xB7 -> VULGAR FRACTION ONE QUARTER
+    u'\xbd'     #  0xB8 -> VULGAR FRACTION ONE HALF
+    u'\xbe'     #  0xB9 -> VULGAR FRACTION THREE QUARTERS
+    u'\xac'     #  0xBA -> NOT SIGN
+    u'|'        #  0xBB -> VERTICAL LINE
+    u'\xaf'     #  0xBC -> MACRON
+    u'\xa8'     #  0xBD -> DIAERESIS
+    u'\xb4'     #  0xBE -> ACUTE ACCENT
+    u'\xd7'     #  0xBF -> MULTIPLICATION SIGN
+    u'{'        #  0xC0 -> LEFT CURLY BRACKET
+    u'A'        #  0xC1 -> LATIN CAPITAL LETTER A
+    u'B'        #  0xC2 -> LATIN CAPITAL LETTER B
+    u'C'        #  0xC3 -> LATIN CAPITAL LETTER C
+    u'D'        #  0xC4 -> LATIN CAPITAL LETTER D
+    u'E'        #  0xC5 -> LATIN CAPITAL LETTER E
+    u'F'        #  0xC6 -> LATIN CAPITAL LETTER F
+    u'G'        #  0xC7 -> LATIN CAPITAL LETTER G
+    u'H'        #  0xC8 -> LATIN CAPITAL LETTER H
+    u'I'        #  0xC9 -> LATIN CAPITAL LETTER I
+    u'\xad'     #  0xCA -> SOFT HYPHEN
+    u'\xf4'     #  0xCB -> LATIN SMALL LETTER O WITH CIRCUMFLEX
+    u'\xf6'     #  0xCC -> LATIN SMALL LETTER O WITH DIAERESIS
+    u'\xf2'     #  0xCD -> LATIN SMALL LETTER O WITH GRAVE
+    u'\xf3'     #  0xCE -> LATIN SMALL LETTER O WITH ACUTE
+    u'\xf5'     #  0xCF -> LATIN SMALL LETTER O WITH TILDE
+    u'}'        #  0xD0 -> RIGHT CURLY BRACKET
+    u'J'        #  0xD1 -> LATIN CAPITAL LETTER J
+    u'K'        #  0xD2 -> LATIN CAPITAL LETTER K
+    u'L'        #  0xD3 -> LATIN CAPITAL LETTER L
+    u'M'        #  0xD4 -> LATIN CAPITAL LETTER M
+    u'N'        #  0xD5 -> LATIN CAPITAL LETTER N
+    u'O'        #  0xD6 -> LATIN CAPITAL LETTER O
+    u'P'        #  0xD7 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0xD8 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0xD9 -> LATIN CAPITAL LETTER R
+    u'\xb9'     #  0xDA -> SUPERSCRIPT ONE
+    u'\xfb'     #  0xDB -> LATIN SMALL LETTER U WITH CIRCUMFLEX
+    u'\xfc'     #  0xDC -> LATIN SMALL LETTER U WITH DIAERESIS
+    u'\xf9'     #  0xDD -> LATIN SMALL LETTER U WITH GRAVE
+    u'\xfa'     #  0xDE -> LATIN SMALL LETTER U WITH ACUTE
+    u'\xff'     #  0xDF -> LATIN SMALL LETTER Y WITH DIAERESIS
+    u'\\'       #  0xE0 -> REVERSE SOLIDUS
+    u'\xf7'     #  0xE1 -> DIVISION SIGN
+    u'S'        #  0xE2 -> LATIN CAPITAL LETTER S
+    u'T'        #  0xE3 -> LATIN CAPITAL LETTER T
+    u'U'        #  0xE4 -> LATIN CAPITAL LETTER U
+    u'V'        #  0xE5 -> LATIN CAPITAL LETTER V
+    u'W'        #  0xE6 -> LATIN CAPITAL LETTER W
+    u'X'        #  0xE7 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0xE8 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0xE9 -> LATIN CAPITAL LETTER Z
+    u'\xb2'     #  0xEA -> SUPERSCRIPT TWO
+    u'\xd4'     #  0xEB -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+    u'\xd6'     #  0xEC -> LATIN CAPITAL LETTER O WITH DIAERESIS
+    u'\xd2'     #  0xED -> LATIN CAPITAL LETTER O WITH GRAVE
+    u'\xd3'     #  0xEE -> LATIN CAPITAL LETTER O WITH ACUTE
+    u'\xd5'     #  0xEF -> LATIN CAPITAL LETTER O WITH TILDE
+    u'0'        #  0xF0 -> DIGIT ZERO
+    u'1'        #  0xF1 -> DIGIT ONE
+    u'2'        #  0xF2 -> DIGIT TWO
+    u'3'        #  0xF3 -> DIGIT THREE
+    u'4'        #  0xF4 -> DIGIT FOUR
+    u'5'        #  0xF5 -> DIGIT FIVE
+    u'6'        #  0xF6 -> DIGIT SIX
+    u'7'        #  0xF7 -> DIGIT SEVEN
+    u'8'        #  0xF8 -> DIGIT EIGHT
+    u'9'        #  0xF9 -> DIGIT NINE
+    u'\xb3'     #  0xFA -> SUPERSCRIPT THREE
+    u'\xdb'     #  0xFB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+    u'\xdc'     #  0xFC -> LATIN CAPITAL LETTER U WITH DIAERESIS
+    u'\xd9'     #  0xFD -> LATIN CAPITAL LETTER U WITH GRAVE
+    u'\xda'     #  0xFE -> LATIN CAPITAL LETTER U WITH ACUTE
+    u'\x9f'     #  0xFF -> CONTROL
+)
+
+### Encoding table
+encoding_table=codecs.charmap_build(decoding_table)

Added: vendor/Python/current/Lib/encodings/cp737.py
===================================================================
--- vendor/Python/current/Lib/encodings/cp737.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/cp737.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,698 @@
+""" Python Character Mapping Codec cp737 generated from 'VENDORS/MICSFT/PC/CP737.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_map)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='cp737',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+### Decoding Map
+
+decoding_map = codecs.make_identity_dict(range(256))
+decoding_map.update({
+    0x0080: 0x0391,     #  GREEK CAPITAL LETTER ALPHA
+    0x0081: 0x0392,     #  GREEK CAPITAL LETTER BETA
+    0x0082: 0x0393,     #  GREEK CAPITAL LETTER GAMMA
+    0x0083: 0x0394,     #  GREEK CAPITAL LETTER DELTA
+    0x0084: 0x0395,     #  GREEK CAPITAL LETTER EPSILON
+    0x0085: 0x0396,     #  GREEK CAPITAL LETTER ZETA
+    0x0086: 0x0397,     #  GREEK CAPITAL LETTER ETA
+    0x0087: 0x0398,     #  GREEK CAPITAL LETTER THETA
+    0x0088: 0x0399,     #  GREEK CAPITAL LETTER IOTA
+    0x0089: 0x039a,     #  GREEK CAPITAL LETTER KAPPA
+    0x008a: 0x039b,     #  GREEK CAPITAL LETTER LAMDA
+    0x008b: 0x039c,     #  GREEK CAPITAL LETTER MU
+    0x008c: 0x039d,     #  GREEK CAPITAL LETTER NU
+    0x008d: 0x039e,     #  GREEK CAPITAL LETTER XI
+    0x008e: 0x039f,     #  GREEK CAPITAL LETTER OMICRON
+    0x008f: 0x03a0,     #  GREEK CAPITAL LETTER PI
+    0x0090: 0x03a1,     #  GREEK CAPITAL LETTER RHO
+    0x0091: 0x03a3,     #  GREEK CAPITAL LETTER SIGMA
+    0x0092: 0x03a4,     #  GREEK CAPITAL LETTER TAU
+    0x0093: 0x03a5,     #  GREEK CAPITAL LETTER UPSILON
+    0x0094: 0x03a6,     #  GREEK CAPITAL LETTER PHI
+    0x0095: 0x03a7,     #  GREEK CAPITAL LETTER CHI
+    0x0096: 0x03a8,     #  GREEK CAPITAL LETTER PSI
+    0x0097: 0x03a9,     #  GREEK CAPITAL LETTER OMEGA
+    0x0098: 0x03b1,     #  GREEK SMALL LETTER ALPHA
+    0x0099: 0x03b2,     #  GREEK SMALL LETTER BETA
+    0x009a: 0x03b3,     #  GREEK SMALL LETTER GAMMA
+    0x009b: 0x03b4,     #  GREEK SMALL LETTER DELTA
+    0x009c: 0x03b5,     #  GREEK SMALL LETTER EPSILON
+    0x009d: 0x03b6,     #  GREEK SMALL LETTER ZETA
+    0x009e: 0x03b7,     #  GREEK SMALL LETTER ETA
+    0x009f: 0x03b8,     #  GREEK SMALL LETTER THETA
+    0x00a0: 0x03b9,     #  GREEK SMALL LETTER IOTA
+    0x00a1: 0x03ba,     #  GREEK SMALL LETTER KAPPA
+    0x00a2: 0x03bb,     #  GREEK SMALL LETTER LAMDA
+    0x00a3: 0x03bc,     #  GREEK SMALL LETTER MU
+    0x00a4: 0x03bd,     #  GREEK SMALL LETTER NU
+    0x00a5: 0x03be,     #  GREEK SMALL LETTER XI
+    0x00a6: 0x03bf,     #  GREEK SMALL LETTER OMICRON
+    0x00a7: 0x03c0,     #  GREEK SMALL LETTER PI
+    0x00a8: 0x03c1,     #  GREEK SMALL LETTER RHO
+    0x00a9: 0x03c3,     #  GREEK SMALL LETTER SIGMA
+    0x00aa: 0x03c2,     #  GREEK SMALL LETTER FINAL SIGMA
+    0x00ab: 0x03c4,     #  GREEK SMALL LETTER TAU
+    0x00ac: 0x03c5,     #  GREEK SMALL LETTER UPSILON
+    0x00ad: 0x03c6,     #  GREEK SMALL LETTER PHI
+    0x00ae: 0x03c7,     #  GREEK SMALL LETTER CHI
+    0x00af: 0x03c8,     #  GREEK SMALL LETTER PSI
+    0x00b0: 0x2591,     #  LIGHT SHADE
+    0x00b1: 0x2592,     #  MEDIUM SHADE
+    0x00b2: 0x2593,     #  DARK SHADE
+    0x00b3: 0x2502,     #  BOX DRAWINGS LIGHT VERTICAL
+    0x00b4: 0x2524,     #  BOX DRAWINGS LIGHT VERTICAL AND LEFT
+    0x00b5: 0x2561,     #  BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+    0x00b6: 0x2562,     #  BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
+    0x00b7: 0x2556,     #  BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
+    0x00b8: 0x2555,     #  BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
+    0x00b9: 0x2563,     #  BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+    0x00ba: 0x2551,     #  BOX DRAWINGS DOUBLE VERTICAL
+    0x00bb: 0x2557,     #  BOX DRAWINGS DOUBLE DOWN AND LEFT
+    0x00bc: 0x255d,     #  BOX DRAWINGS DOUBLE UP AND LEFT
+    0x00bd: 0x255c,     #  BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
+    0x00be: 0x255b,     #  BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+    0x00bf: 0x2510,     #  BOX DRAWINGS LIGHT DOWN AND LEFT
+    0x00c0: 0x2514,     #  BOX DRAWINGS LIGHT UP AND RIGHT
+    0x00c1: 0x2534,     #  BOX DRAWINGS LIGHT UP AND HORIZONTAL
+    0x00c2: 0x252c,     #  BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+    0x00c3: 0x251c,     #  BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+    0x00c4: 0x2500,     #  BOX DRAWINGS LIGHT HORIZONTAL
+    0x00c5: 0x253c,     #  BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+    0x00c6: 0x255e,     #  BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+    0x00c7: 0x255f,     #  BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+    0x00c8: 0x255a,     #  BOX DRAWINGS DOUBLE UP AND RIGHT
+    0x00c9: 0x2554,     #  BOX DRAWINGS DOUBLE DOWN AND RIGHT
+    0x00ca: 0x2569,     #  BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+    0x00cb: 0x2566,     #  BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+    0x00cc: 0x2560,     #  BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+    0x00cd: 0x2550,     #  BOX DRAWINGS DOUBLE HORIZONTAL
+    0x00ce: 0x256c,     #  BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+    0x00cf: 0x2567,     #  BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+    0x00d0: 0x2568,     #  BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+    0x00d1: 0x2564,     #  BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
+    0x00d2: 0x2565,     #  BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
+    0x00d3: 0x2559,     #  BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+    0x00d4: 0x2558,     #  BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+    0x00d5: 0x2552,     #  BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+    0x00d6: 0x2553,     #  BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
+    0x00d7: 0x256b,     #  BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
+    0x00d8: 0x256a,     #  BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+    0x00d9: 0x2518,     #  BOX DRAWINGS LIGHT UP AND LEFT
+    0x00da: 0x250c,     #  BOX DRAWINGS LIGHT DOWN AND RIGHT
+    0x00db: 0x2588,     #  FULL BLOCK
+    0x00dc: 0x2584,     #  LOWER HALF BLOCK
+    0x00dd: 0x258c,     #  LEFT HALF BLOCK
+    0x00de: 0x2590,     #  RIGHT HALF BLOCK
+    0x00df: 0x2580,     #  UPPER HALF BLOCK
+    0x00e0: 0x03c9,     #  GREEK SMALL LETTER OMEGA
+    0x00e1: 0x03ac,     #  GREEK SMALL LETTER ALPHA WITH TONOS
+    0x00e2: 0x03ad,     #  GREEK SMALL LETTER EPSILON WITH TONOS
+    0x00e3: 0x03ae,     #  GREEK SMALL LETTER ETA WITH TONOS
+    0x00e4: 0x03ca,     #  GREEK SMALL LETTER IOTA WITH DIALYTIKA
+    0x00e5: 0x03af,     #  GREEK SMALL LETTER IOTA WITH TONOS
+    0x00e6: 0x03cc,     #  GREEK SMALL LETTER OMICRON WITH TONOS
+    0x00e7: 0x03cd,     #  GREEK SMALL LETTER UPSILON WITH TONOS
+    0x00e8: 0x03cb,     #  GREEK SMALL LETTER UPSILON WITH DIALYTIKA
+    0x00e9: 0x03ce,     #  GREEK SMALL LETTER OMEGA WITH TONOS
+    0x00ea: 0x0386,     #  GREEK CAPITAL LETTER ALPHA WITH TONOS
+    0x00eb: 0x0388,     #  GREEK CAPITAL LETTER EPSILON WITH TONOS
+    0x00ec: 0x0389,     #  GREEK CAPITAL LETTER ETA WITH TONOS
+    0x00ed: 0x038a,     #  GREEK CAPITAL LETTER IOTA WITH TONOS
+    0x00ee: 0x038c,     #  GREEK CAPITAL LETTER OMICRON WITH TONOS
+    0x00ef: 0x038e,     #  GREEK CAPITAL LETTER UPSILON WITH TONOS
+    0x00f0: 0x038f,     #  GREEK CAPITAL LETTER OMEGA WITH TONOS
+    0x00f1: 0x00b1,     #  PLUS-MINUS SIGN
+    0x00f2: 0x2265,     #  GREATER-THAN OR EQUAL TO
+    0x00f3: 0x2264,     #  LESS-THAN OR EQUAL TO
+    0x00f4: 0x03aa,     #  GREEK CAPITAL LETTER IOTA WITH DIALYTIKA
+    0x00f5: 0x03ab,     #  GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA
+    0x00f6: 0x00f7,     #  DIVISION SIGN
+    0x00f7: 0x2248,     #  ALMOST EQUAL TO
+    0x00f8: 0x00b0,     #  DEGREE SIGN
+    0x00f9: 0x2219,     #  BULLET OPERATOR
+    0x00fa: 0x00b7,     #  MIDDLE DOT
+    0x00fb: 0x221a,     #  SQUARE ROOT
+    0x00fc: 0x207f,     #  SUPERSCRIPT LATIN SMALL LETTER N
+    0x00fd: 0x00b2,     #  SUPERSCRIPT TWO
+    0x00fe: 0x25a0,     #  BLACK SQUARE
+    0x00ff: 0x00a0,     #  NO-BREAK SPACE
+})
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x0000 -> NULL
+    u'\x01'     #  0x0001 -> START OF HEADING
+    u'\x02'     #  0x0002 -> START OF TEXT
+    u'\x03'     #  0x0003 -> END OF TEXT
+    u'\x04'     #  0x0004 -> END OF TRANSMISSION
+    u'\x05'     #  0x0005 -> ENQUIRY
+    u'\x06'     #  0x0006 -> ACKNOWLEDGE
+    u'\x07'     #  0x0007 -> BELL
+    u'\x08'     #  0x0008 -> BACKSPACE
+    u'\t'       #  0x0009 -> HORIZONTAL TABULATION
+    u'\n'       #  0x000a -> LINE FEED
+    u'\x0b'     #  0x000b -> VERTICAL TABULATION
+    u'\x0c'     #  0x000c -> FORM FEED
+    u'\r'       #  0x000d -> CARRIAGE RETURN
+    u'\x0e'     #  0x000e -> SHIFT OUT
+    u'\x0f'     #  0x000f -> SHIFT IN
+    u'\x10'     #  0x0010 -> DATA LINK ESCAPE
+    u'\x11'     #  0x0011 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x0012 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x0013 -> DEVICE CONTROL THREE
+    u'\x14'     #  0x0014 -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x0015 -> NEGATIVE ACKNOWLEDGE
+    u'\x16'     #  0x0016 -> SYNCHRONOUS IDLE
+    u'\x17'     #  0x0017 -> END OF TRANSMISSION BLOCK
+    u'\x18'     #  0x0018 -> CANCEL
+    u'\x19'     #  0x0019 -> END OF MEDIUM
+    u'\x1a'     #  0x001a -> SUBSTITUTE
+    u'\x1b'     #  0x001b -> ESCAPE
+    u'\x1c'     #  0x001c -> FILE SEPARATOR
+    u'\x1d'     #  0x001d -> GROUP SEPARATOR
+    u'\x1e'     #  0x001e -> RECORD SEPARATOR
+    u'\x1f'     #  0x001f -> UNIT SEPARATOR
+    u' '        #  0x0020 -> SPACE
+    u'!'        #  0x0021 -> EXCLAMATION MARK
+    u'"'        #  0x0022 -> QUOTATION MARK
+    u'#'        #  0x0023 -> NUMBER SIGN
+    u'$'        #  0x0024 -> DOLLAR SIGN
+    u'%'        #  0x0025 -> PERCENT SIGN
+    u'&'        #  0x0026 -> AMPERSAND
+    u"'"        #  0x0027 -> APOSTROPHE
+    u'('        #  0x0028 -> LEFT PARENTHESIS
+    u')'        #  0x0029 -> RIGHT PARENTHESIS
+    u'*'        #  0x002a -> ASTERISK
+    u'+'        #  0x002b -> PLUS SIGN
+    u','        #  0x002c -> COMMA
+    u'-'        #  0x002d -> HYPHEN-MINUS
+    u'.'        #  0x002e -> FULL STOP
+    u'/'        #  0x002f -> SOLIDUS
+    u'0'        #  0x0030 -> DIGIT ZERO
+    u'1'        #  0x0031 -> DIGIT ONE
+    u'2'        #  0x0032 -> DIGIT TWO
+    u'3'        #  0x0033 -> DIGIT THREE
+    u'4'        #  0x0034 -> DIGIT FOUR
+    u'5'        #  0x0035 -> DIGIT FIVE
+    u'6'        #  0x0036 -> DIGIT SIX
+    u'7'        #  0x0037 -> DIGIT SEVEN
+    u'8'        #  0x0038 -> DIGIT EIGHT
+    u'9'        #  0x0039 -> DIGIT NINE
+    u':'        #  0x003a -> COLON
+    u';'        #  0x003b -> SEMICOLON
+    u'<'        #  0x003c -> LESS-THAN SIGN
+    u'='        #  0x003d -> EQUALS SIGN
+    u'>'        #  0x003e -> GREATER-THAN SIGN
+    u'?'        #  0x003f -> QUESTION MARK
+    u'@'        #  0x0040 -> COMMERCIAL AT
+    u'A'        #  0x0041 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x0042 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x0043 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x0044 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x0045 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x0046 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x0047 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x0048 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x0049 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x004a -> LATIN CAPITAL LETTER J
+    u'K'        #  0x004b -> LATIN CAPITAL LETTER K
+    u'L'        #  0x004c -> LATIN CAPITAL LETTER L
+    u'M'        #  0x004d -> LATIN CAPITAL LETTER M
+    u'N'        #  0x004e -> LATIN CAPITAL LETTER N
+    u'O'        #  0x004f -> LATIN CAPITAL LETTER O
+    u'P'        #  0x0050 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x0051 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x0052 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x0053 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x0054 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x0055 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x0056 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x0057 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x0058 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x0059 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x005a -> LATIN CAPITAL LETTER Z
+    u'['        #  0x005b -> LEFT SQUARE BRACKET
+    u'\\'       #  0x005c -> REVERSE SOLIDUS
+    u']'        #  0x005d -> RIGHT SQUARE BRACKET
+    u'^'        #  0x005e -> CIRCUMFLEX ACCENT
+    u'_'        #  0x005f -> LOW LINE
+    u'`'        #  0x0060 -> GRAVE ACCENT
+    u'a'        #  0x0061 -> LATIN SMALL LETTER A
+    u'b'        #  0x0062 -> LATIN SMALL LETTER B
+    u'c'        #  0x0063 -> LATIN SMALL LETTER C
+    u'd'        #  0x0064 -> LATIN SMALL LETTER D
+    u'e'        #  0x0065 -> LATIN SMALL LETTER E
+    u'f'        #  0x0066 -> LATIN SMALL LETTER F
+    u'g'        #  0x0067 -> LATIN SMALL LETTER G
+    u'h'        #  0x0068 -> LATIN SMALL LETTER H
+    u'i'        #  0x0069 -> LATIN SMALL LETTER I
+    u'j'        #  0x006a -> LATIN SMALL LETTER J
+    u'k'        #  0x006b -> LATIN SMALL LETTER K
+    u'l'        #  0x006c -> LATIN SMALL LETTER L
+    u'm'        #  0x006d -> LATIN SMALL LETTER M
+    u'n'        #  0x006e -> LATIN SMALL LETTER N
+    u'o'        #  0x006f -> LATIN SMALL LETTER O
+    u'p'        #  0x0070 -> LATIN SMALL LETTER P
+    u'q'        #  0x0071 -> LATIN SMALL LETTER Q
+    u'r'        #  0x0072 -> LATIN SMALL LETTER R
+    u's'        #  0x0073 -> LATIN SMALL LETTER S
+    u't'        #  0x0074 -> LATIN SMALL LETTER T
+    u'u'        #  0x0075 -> LATIN SMALL LETTER U
+    u'v'        #  0x0076 -> LATIN SMALL LETTER V
+    u'w'        #  0x0077 -> LATIN SMALL LETTER W
+    u'x'        #  0x0078 -> LATIN SMALL LETTER X
+    u'y'        #  0x0079 -> LATIN SMALL LETTER Y
+    u'z'        #  0x007a -> LATIN SMALL LETTER Z
+    u'{'        #  0x007b -> LEFT CURLY BRACKET
+    u'|'        #  0x007c -> VERTICAL LINE
+    u'}'        #  0x007d -> RIGHT CURLY BRACKET
+    u'~'        #  0x007e -> TILDE
+    u'\x7f'     #  0x007f -> DELETE
+    u'\u0391'   #  0x0080 -> GREEK CAPITAL LETTER ALPHA
+    u'\u0392'   #  0x0081 -> GREEK CAPITAL LETTER BETA
+    u'\u0393'   #  0x0082 -> GREEK CAPITAL LETTER GAMMA
+    u'\u0394'   #  0x0083 -> GREEK CAPITAL LETTER DELTA
+    u'\u0395'   #  0x0084 -> GREEK CAPITAL LETTER EPSILON
+    u'\u0396'   #  0x0085 -> GREEK CAPITAL LETTER ZETA
+    u'\u0397'   #  0x0086 -> GREEK CAPITAL LETTER ETA
+    u'\u0398'   #  0x0087 -> GREEK CAPITAL LETTER THETA
+    u'\u0399'   #  0x0088 -> GREEK CAPITAL LETTER IOTA
+    u'\u039a'   #  0x0089 -> GREEK CAPITAL LETTER KAPPA
+    u'\u039b'   #  0x008a -> GREEK CAPITAL LETTER LAMDA
+    u'\u039c'   #  0x008b -> GREEK CAPITAL LETTER MU
+    u'\u039d'   #  0x008c -> GREEK CAPITAL LETTER NU
+    u'\u039e'   #  0x008d -> GREEK CAPITAL LETTER XI
+    u'\u039f'   #  0x008e -> GREEK CAPITAL LETTER OMICRON
+    u'\u03a0'   #  0x008f -> GREEK CAPITAL LETTER PI
+    u'\u03a1'   #  0x0090 -> GREEK CAPITAL LETTER RHO
+    u'\u03a3'   #  0x0091 -> GREEK CAPITAL LETTER SIGMA
+    u'\u03a4'   #  0x0092 -> GREEK CAPITAL LETTER TAU
+    u'\u03a5'   #  0x0093 -> GREEK CAPITAL LETTER UPSILON
+    u'\u03a6'   #  0x0094 -> GREEK CAPITAL LETTER PHI
+    u'\u03a7'   #  0x0095 -> GREEK CAPITAL LETTER CHI
+    u'\u03a8'   #  0x0096 -> GREEK CAPITAL LETTER PSI
+    u'\u03a9'   #  0x0097 -> GREEK CAPITAL LETTER OMEGA
+    u'\u03b1'   #  0x0098 -> GREEK SMALL LETTER ALPHA
+    u'\u03b2'   #  0x0099 -> GREEK SMALL LETTER BETA
+    u'\u03b3'   #  0x009a -> GREEK SMALL LETTER GAMMA
+    u'\u03b4'   #  0x009b -> GREEK SMALL LETTER DELTA
+    u'\u03b5'   #  0x009c -> GREEK SMALL LETTER EPSILON
+    u'\u03b6'   #  0x009d -> GREEK SMALL LETTER ZETA
+    u'\u03b7'   #  0x009e -> GREEK SMALL LETTER ETA
+    u'\u03b8'   #  0x009f -> GREEK SMALL LETTER THETA
+    u'\u03b9'   #  0x00a0 -> GREEK SMALL LETTER IOTA
+    u'\u03ba'   #  0x00a1 -> GREEK SMALL LETTER KAPPA
+    u'\u03bb'   #  0x00a2 -> GREEK SMALL LETTER LAMDA
+    u'\u03bc'   #  0x00a3 -> GREEK SMALL LETTER MU
+    u'\u03bd'   #  0x00a4 -> GREEK SMALL LETTER NU
+    u'\u03be'   #  0x00a5 -> GREEK SMALL LETTER XI
+    u'\u03bf'   #  0x00a6 -> GREEK SMALL LETTER OMICRON
+    u'\u03c0'   #  0x00a7 -> GREEK SMALL LETTER PI
+    u'\u03c1'   #  0x00a8 -> GREEK SMALL LETTER RHO
+    u'\u03c3'   #  0x00a9 -> GREEK SMALL LETTER SIGMA
+    u'\u03c2'   #  0x00aa -> GREEK SMALL LETTER FINAL SIGMA
+    u'\u03c4'   #  0x00ab -> GREEK SMALL LETTER TAU
+    u'\u03c5'   #  0x00ac -> GREEK SMALL LETTER UPSILON
+    u'\u03c6'   #  0x00ad -> GREEK SMALL LETTER PHI
+    u'\u03c7'   #  0x00ae -> GREEK SMALL LETTER CHI
+    u'\u03c8'   #  0x00af -> GREEK SMALL LETTER PSI
+    u'\u2591'   #  0x00b0 -> LIGHT SHADE
+    u'\u2592'   #  0x00b1 -> MEDIUM SHADE
+    u'\u2593'   #  0x00b2 -> DARK SHADE
+    u'\u2502'   #  0x00b3 -> BOX DRAWINGS LIGHT VERTICAL
+    u'\u2524'   #  0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT
+    u'\u2561'   #  0x00b5 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+    u'\u2562'   #  0x00b6 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
+    u'\u2556'   #  0x00b7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
+    u'\u2555'   #  0x00b8 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
+    u'\u2563'   #  0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+    u'\u2551'   #  0x00ba -> BOX DRAWINGS DOUBLE VERTICAL
+    u'\u2557'   #  0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT
+    u'\u255d'   #  0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT
+    u'\u255c'   #  0x00bd -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
+    u'\u255b'   #  0x00be -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+    u'\u2510'   #  0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT
+    u'\u2514'   #  0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT
+    u'\u2534'   #  0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL
+    u'\u252c'   #  0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+    u'\u251c'   #  0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+    u'\u2500'   #  0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL
+    u'\u253c'   #  0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+    u'\u255e'   #  0x00c6 -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+    u'\u255f'   #  0x00c7 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+    u'\u255a'   #  0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT
+    u'\u2554'   #  0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT
+    u'\u2569'   #  0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+    u'\u2566'   #  0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+    u'\u2560'   #  0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+    u'\u2550'   #  0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL
+    u'\u256c'   #  0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+    u'\u2567'   #  0x00cf -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+    u'\u2568'   #  0x00d0 -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+    u'\u2564'   #  0x00d1 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
+    u'\u2565'   #  0x00d2 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
+    u'\u2559'   #  0x00d3 -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+    u'\u2558'   #  0x00d4 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+    u'\u2552'   #  0x00d5 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+    u'\u2553'   #  0x00d6 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
+    u'\u256b'   #  0x00d7 -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
+    u'\u256a'   #  0x00d8 -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+    u'\u2518'   #  0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT
+    u'\u250c'   #  0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT
+    u'\u2588'   #  0x00db -> FULL BLOCK
+    u'\u2584'   #  0x00dc -> LOWER HALF BLOCK
+    u'\u258c'   #  0x00dd -> LEFT HALF BLOCK
+    u'\u2590'   #  0x00de -> RIGHT HALF BLOCK
+    u'\u2580'   #  0x00df -> UPPER HALF BLOCK
+    u'\u03c9'   #  0x00e0 -> GREEK SMALL LETTER OMEGA
+    u'\u03ac'   #  0x00e1 -> GREEK SMALL LETTER ALPHA WITH TONOS
+    u'\u03ad'   #  0x00e2 -> GREEK SMALL LETTER EPSILON WITH TONOS
+    u'\u03ae'   #  0x00e3 -> GREEK SMALL LETTER ETA WITH TONOS
+    u'\u03ca'   #  0x00e4 -> GREEK SMALL LETTER IOTA WITH DIALYTIKA
+    u'\u03af'   #  0x00e5 -> GREEK SMALL LETTER IOTA WITH TONOS
+    u'\u03cc'   #  0x00e6 -> GREEK SMALL LETTER OMICRON WITH TONOS
+    u'\u03cd'   #  0x00e7 -> GREEK SMALL LETTER UPSILON WITH TONOS
+    u'\u03cb'   #  0x00e8 -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA
+    u'\u03ce'   #  0x00e9 -> GREEK SMALL LETTER OMEGA WITH TONOS
+    u'\u0386'   #  0x00ea -> GREEK CAPITAL LETTER ALPHA WITH TONOS
+    u'\u0388'   #  0x00eb -> GREEK CAPITAL LETTER EPSILON WITH TONOS
+    u'\u0389'   #  0x00ec -> GREEK CAPITAL LETTER ETA WITH TONOS
+    u'\u038a'   #  0x00ed -> GREEK CAPITAL LETTER IOTA WITH TONOS
+    u'\u038c'   #  0x00ee -> GREEK CAPITAL LETTER OMICRON WITH TONOS
+    u'\u038e'   #  0x00ef -> GREEK CAPITAL LETTER UPSILON WITH TONOS
+    u'\u038f'   #  0x00f0 -> GREEK CAPITAL LETTER OMEGA WITH TONOS
+    u'\xb1'     #  0x00f1 -> PLUS-MINUS SIGN
+    u'\u2265'   #  0x00f2 -> GREATER-THAN OR EQUAL TO
+    u'\u2264'   #  0x00f3 -> LESS-THAN OR EQUAL TO
+    u'\u03aa'   #  0x00f4 -> GREEK CAPITAL LETTER IOTA WITH DIALYTIKA
+    u'\u03ab'   #  0x00f5 -> GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA
+    u'\xf7'     #  0x00f6 -> DIVISION SIGN
+    u'\u2248'   #  0x00f7 -> ALMOST EQUAL TO
+    u'\xb0'     #  0x00f8 -> DEGREE SIGN
+    u'\u2219'   #  0x00f9 -> BULLET OPERATOR
+    u'\xb7'     #  0x00fa -> MIDDLE DOT
+    u'\u221a'   #  0x00fb -> SQUARE ROOT
+    u'\u207f'   #  0x00fc -> SUPERSCRIPT LATIN SMALL LETTER N
+    u'\xb2'     #  0x00fd -> SUPERSCRIPT TWO
+    u'\u25a0'   #  0x00fe -> BLACK SQUARE
+    u'\xa0'     #  0x00ff -> NO-BREAK SPACE
+)
+
+### Encoding Map
+
+encoding_map = {
+    0x0000: 0x0000,     #  NULL
+    0x0001: 0x0001,     #  START OF HEADING
+    0x0002: 0x0002,     #  START OF TEXT
+    0x0003: 0x0003,     #  END OF TEXT
+    0x0004: 0x0004,     #  END OF TRANSMISSION
+    0x0005: 0x0005,     #  ENQUIRY
+    0x0006: 0x0006,     #  ACKNOWLEDGE
+    0x0007: 0x0007,     #  BELL
+    0x0008: 0x0008,     #  BACKSPACE
+    0x0009: 0x0009,     #  HORIZONTAL TABULATION
+    0x000a: 0x000a,     #  LINE FEED
+    0x000b: 0x000b,     #  VERTICAL TABULATION
+    0x000c: 0x000c,     #  FORM FEED
+    0x000d: 0x000d,     #  CARRIAGE RETURN
+    0x000e: 0x000e,     #  SHIFT OUT
+    0x000f: 0x000f,     #  SHIFT IN
+    0x0010: 0x0010,     #  DATA LINK ESCAPE
+    0x0011: 0x0011,     #  DEVICE CONTROL ONE
+    0x0012: 0x0012,     #  DEVICE CONTROL TWO
+    0x0013: 0x0013,     #  DEVICE CONTROL THREE
+    0x0014: 0x0014,     #  DEVICE CONTROL FOUR
+    0x0015: 0x0015,     #  NEGATIVE ACKNOWLEDGE
+    0x0016: 0x0016,     #  SYNCHRONOUS IDLE
+    0x0017: 0x0017,     #  END OF TRANSMISSION BLOCK
+    0x0018: 0x0018,     #  CANCEL
+    0x0019: 0x0019,     #  END OF MEDIUM
+    0x001a: 0x001a,     #  SUBSTITUTE
+    0x001b: 0x001b,     #  ESCAPE
+    0x001c: 0x001c,     #  FILE SEPARATOR
+    0x001d: 0x001d,     #  GROUP SEPARATOR
+    0x001e: 0x001e,     #  RECORD SEPARATOR
+    0x001f: 0x001f,     #  UNIT SEPARATOR
+    0x0020: 0x0020,     #  SPACE
+    0x0021: 0x0021,     #  EXCLAMATION MARK
+    0x0022: 0x0022,     #  QUOTATION MARK
+    0x0023: 0x0023,     #  NUMBER SIGN
+    0x0024: 0x0024,     #  DOLLAR SIGN
+    0x0025: 0x0025,     #  PERCENT SIGN
+    0x0026: 0x0026,     #  AMPERSAND
+    0x0027: 0x0027,     #  APOSTROPHE
+    0x0028: 0x0028,     #  LEFT PARENTHESIS
+    0x0029: 0x0029,     #  RIGHT PARENTHESIS
+    0x002a: 0x002a,     #  ASTERISK
+    0x002b: 0x002b,     #  PLUS SIGN
+    0x002c: 0x002c,     #  COMMA
+    0x002d: 0x002d,     #  HYPHEN-MINUS
+    0x002e: 0x002e,     #  FULL STOP
+    0x002f: 0x002f,     #  SOLIDUS
+    0x0030: 0x0030,     #  DIGIT ZERO
+    0x0031: 0x0031,     #  DIGIT ONE
+    0x0032: 0x0032,     #  DIGIT TWO
+    0x0033: 0x0033,     #  DIGIT THREE
+    0x0034: 0x0034,     #  DIGIT FOUR
+    0x0035: 0x0035,     #  DIGIT FIVE
+    0x0036: 0x0036,     #  DIGIT SIX
+    0x0037: 0x0037,     #  DIGIT SEVEN
+    0x0038: 0x0038,     #  DIGIT EIGHT
+    0x0039: 0x0039,     #  DIGIT NINE
+    0x003a: 0x003a,     #  COLON
+    0x003b: 0x003b,     #  SEMICOLON
+    0x003c: 0x003c,     #  LESS-THAN SIGN
+    0x003d: 0x003d,     #  EQUALS SIGN
+    0x003e: 0x003e,     #  GREATER-THAN SIGN
+    0x003f: 0x003f,     #  QUESTION MARK
+    0x0040: 0x0040,     #  COMMERCIAL AT
+    0x0041: 0x0041,     #  LATIN CAPITAL LETTER A
+    0x0042: 0x0042,     #  LATIN CAPITAL LETTER B
+    0x0043: 0x0043,     #  LATIN CAPITAL LETTER C
+    0x0044: 0x0044,     #  LATIN CAPITAL LETTER D
+    0x0045: 0x0045,     #  LATIN CAPITAL LETTER E
+    0x0046: 0x0046,     #  LATIN CAPITAL LETTER F
+    0x0047: 0x0047,     #  LATIN CAPITAL LETTER G
+    0x0048: 0x0048,     #  LATIN CAPITAL LETTER H
+    0x0049: 0x0049,     #  LATIN CAPITAL LETTER I
+    0x004a: 0x004a,     #  LATIN CAPITAL LETTER J
+    0x004b: 0x004b,     #  LATIN CAPITAL LETTER K
+    0x004c: 0x004c,     #  LATIN CAPITAL LETTER L
+    0x004d: 0x004d,     #  LATIN CAPITAL LETTER M
+    0x004e: 0x004e,     #  LATIN CAPITAL LETTER N
+    0x004f: 0x004f,     #  LATIN CAPITAL LETTER O
+    0x0050: 0x0050,     #  LATIN CAPITAL LETTER P
+    0x0051: 0x0051,     #  LATIN CAPITAL LETTER Q
+    0x0052: 0x0052,     #  LATIN CAPITAL LETTER R
+    0x0053: 0x0053,     #  LATIN CAPITAL LETTER S
+    0x0054: 0x0054,     #  LATIN CAPITAL LETTER T
+    0x0055: 0x0055,     #  LATIN CAPITAL LETTER U
+    0x0056: 0x0056,     #  LATIN CAPITAL LETTER V
+    0x0057: 0x0057,     #  LATIN CAPITAL LETTER W
+    0x0058: 0x0058,     #  LATIN CAPITAL LETTER X
+    0x0059: 0x0059,     #  LATIN CAPITAL LETTER Y
+    0x005a: 0x005a,     #  LATIN CAPITAL LETTER Z
+    0x005b: 0x005b,     #  LEFT SQUARE BRACKET
+    0x005c: 0x005c,     #  REVERSE SOLIDUS
+    0x005d: 0x005d,     #  RIGHT SQUARE BRACKET
+    0x005e: 0x005e,     #  CIRCUMFLEX ACCENT
+    0x005f: 0x005f,     #  LOW LINE
+    0x0060: 0x0060,     #  GRAVE ACCENT
+    0x0061: 0x0061,     #  LATIN SMALL LETTER A
+    0x0062: 0x0062,     #  LATIN SMALL LETTER B
+    0x0063: 0x0063,     #  LATIN SMALL LETTER C
+    0x0064: 0x0064,     #  LATIN SMALL LETTER D
+    0x0065: 0x0065,     #  LATIN SMALL LETTER E
+    0x0066: 0x0066,     #  LATIN SMALL LETTER F
+    0x0067: 0x0067,     #  LATIN SMALL LETTER G
+    0x0068: 0x0068,     #  LATIN SMALL LETTER H
+    0x0069: 0x0069,     #  LATIN SMALL LETTER I
+    0x006a: 0x006a,     #  LATIN SMALL LETTER J
+    0x006b: 0x006b,     #  LATIN SMALL LETTER K
+    0x006c: 0x006c,     #  LATIN SMALL LETTER L
+    0x006d: 0x006d,     #  LATIN SMALL LETTER M
+    0x006e: 0x006e,     #  LATIN SMALL LETTER N
+    0x006f: 0x006f,     #  LATIN SMALL LETTER O
+    0x0070: 0x0070,     #  LATIN SMALL LETTER P
+    0x0071: 0x0071,     #  LATIN SMALL LETTER Q
+    0x0072: 0x0072,     #  LATIN SMALL LETTER R
+    0x0073: 0x0073,     #  LATIN SMALL LETTER S
+    0x0074: 0x0074,     #  LATIN SMALL LETTER T
+    0x0075: 0x0075,     #  LATIN SMALL LETTER U
+    0x0076: 0x0076,     #  LATIN SMALL LETTER V
+    0x0077: 0x0077,     #  LATIN SMALL LETTER W
+    0x0078: 0x0078,     #  LATIN SMALL LETTER X
+    0x0079: 0x0079,     #  LATIN SMALL LETTER Y
+    0x007a: 0x007a,     #  LATIN SMALL LETTER Z
+    0x007b: 0x007b,     #  LEFT CURLY BRACKET
+    0x007c: 0x007c,     #  VERTICAL LINE
+    0x007d: 0x007d,     #  RIGHT CURLY BRACKET
+    0x007e: 0x007e,     #  TILDE
+    0x007f: 0x007f,     #  DELETE
+    0x00a0: 0x00ff,     #  NO-BREAK SPACE
+    0x00b0: 0x00f8,     #  DEGREE SIGN
+    0x00b1: 0x00f1,     #  PLUS-MINUS SIGN
+    0x00b2: 0x00fd,     #  SUPERSCRIPT TWO
+    0x00b7: 0x00fa,     #  MIDDLE DOT
+    0x00f7: 0x00f6,     #  DIVISION SIGN
+    0x0386: 0x00ea,     #  GREEK CAPITAL LETTER ALPHA WITH TONOS
+    0x0388: 0x00eb,     #  GREEK CAPITAL LETTER EPSILON WITH TONOS
+    0x0389: 0x00ec,     #  GREEK CAPITAL LETTER ETA WITH TONOS
+    0x038a: 0x00ed,     #  GREEK CAPITAL LETTER IOTA WITH TONOS
+    0x038c: 0x00ee,     #  GREEK CAPITAL LETTER OMICRON WITH TONOS
+    0x038e: 0x00ef,     #  GREEK CAPITAL LETTER UPSILON WITH TONOS
+    0x038f: 0x00f0,     #  GREEK CAPITAL LETTER OMEGA WITH TONOS
+    0x0391: 0x0080,     #  GREEK CAPITAL LETTER ALPHA
+    0x0392: 0x0081,     #  GREEK CAPITAL LETTER BETA
+    0x0393: 0x0082,     #  GREEK CAPITAL LETTER GAMMA
+    0x0394: 0x0083,     #  GREEK CAPITAL LETTER DELTA
+    0x0395: 0x0084,     #  GREEK CAPITAL LETTER EPSILON
+    0x0396: 0x0085,     #  GREEK CAPITAL LETTER ZETA
+    0x0397: 0x0086,     #  GREEK CAPITAL LETTER ETA
+    0x0398: 0x0087,     #  GREEK CAPITAL LETTER THETA
+    0x0399: 0x0088,     #  GREEK CAPITAL LETTER IOTA
+    0x039a: 0x0089,     #  GREEK CAPITAL LETTER KAPPA
+    0x039b: 0x008a,     #  GREEK CAPITAL LETTER LAMDA
+    0x039c: 0x008b,     #  GREEK CAPITAL LETTER MU
+    0x039d: 0x008c,     #  GREEK CAPITAL LETTER NU
+    0x039e: 0x008d,     #  GREEK CAPITAL LETTER XI
+    0x039f: 0x008e,     #  GREEK CAPITAL LETTER OMICRON
+    0x03a0: 0x008f,     #  GREEK CAPITAL LETTER PI
+    0x03a1: 0x0090,     #  GREEK CAPITAL LETTER RHO
+    0x03a3: 0x0091,     #  GREEK CAPITAL LETTER SIGMA
+    0x03a4: 0x0092,     #  GREEK CAPITAL LETTER TAU
+    0x03a5: 0x0093,     #  GREEK CAPITAL LETTER UPSILON
+    0x03a6: 0x0094,     #  GREEK CAPITAL LETTER PHI
+    0x03a7: 0x0095,     #  GREEK CAPITAL LETTER CHI
+    0x03a8: 0x0096,     #  GREEK CAPITAL LETTER PSI
+    0x03a9: 0x0097,     #  GREEK CAPITAL LETTER OMEGA
+    0x03aa: 0x00f4,     #  GREEK CAPITAL LETTER IOTA WITH DIALYTIKA
+    0x03ab: 0x00f5,     #  GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA
+    0x03ac: 0x00e1,     #  GREEK SMALL LETTER ALPHA WITH TONOS
+    0x03ad: 0x00e2,     #  GREEK SMALL LETTER EPSILON WITH TONOS
+    0x03ae: 0x00e3,     #  GREEK SMALL LETTER ETA WITH TONOS
+    0x03af: 0x00e5,     #  GREEK SMALL LETTER IOTA WITH TONOS
+    0x03b1: 0x0098,     #  GREEK SMALL LETTER ALPHA
+    0x03b2: 0x0099,     #  GREEK SMALL LETTER BETA
+    0x03b3: 0x009a,     #  GREEK SMALL LETTER GAMMA
+    0x03b4: 0x009b,     #  GREEK SMALL LETTER DELTA
+    0x03b5: 0x009c,     #  GREEK SMALL LETTER EPSILON
+    0x03b6: 0x009d,     #  GREEK SMALL LETTER ZETA
+    0x03b7: 0x009e,     #  GREEK SMALL LETTER ETA
+    0x03b8: 0x009f,     #  GREEK SMALL LETTER THETA
+    0x03b9: 0x00a0,     #  GREEK SMALL LETTER IOTA
+    0x03ba: 0x00a1,     #  GREEK SMALL LETTER KAPPA
+    0x03bb: 0x00a2,     #  GREEK SMALL LETTER LAMDA
+    0x03bc: 0x00a3,     #  GREEK SMALL LETTER MU
+    0x03bd: 0x00a4,     #  GREEK SMALL LETTER NU
+    0x03be: 0x00a5,     #  GREEK SMALL LETTER XI
+    0x03bf: 0x00a6,     #  GREEK SMALL LETTER OMICRON
+    0x03c0: 0x00a7,     #  GREEK SMALL LETTER PI
+    0x03c1: 0x00a8,     #  GREEK SMALL LETTER RHO
+    0x03c2: 0x00aa,     #  GREEK SMALL LETTER FINAL SIGMA
+    0x03c3: 0x00a9,     #  GREEK SMALL LETTER SIGMA
+    0x03c4: 0x00ab,     #  GREEK SMALL LETTER TAU
+    0x03c5: 0x00ac,     #  GREEK SMALL LETTER UPSILON
+    0x03c6: 0x00ad,     #  GREEK SMALL LETTER PHI
+    0x03c7: 0x00ae,     #  GREEK SMALL LETTER CHI
+    0x03c8: 0x00af,     #  GREEK SMALL LETTER PSI
+    0x03c9: 0x00e0,     #  GREEK SMALL LETTER OMEGA
+    0x03ca: 0x00e4,     #  GREEK SMALL LETTER IOTA WITH DIALYTIKA
+    0x03cb: 0x00e8,     #  GREEK SMALL LETTER UPSILON WITH DIALYTIKA
+    0x03cc: 0x00e6,     #  GREEK SMALL LETTER OMICRON WITH TONOS
+    0x03cd: 0x00e7,     #  GREEK SMALL LETTER UPSILON WITH TONOS
+    0x03ce: 0x00e9,     #  GREEK SMALL LETTER OMEGA WITH TONOS
+    0x207f: 0x00fc,     #  SUPERSCRIPT LATIN SMALL LETTER N
+    0x2219: 0x00f9,     #  BULLET OPERATOR
+    0x221a: 0x00fb,     #  SQUARE ROOT
+    0x2248: 0x00f7,     #  ALMOST EQUAL TO
+    0x2264: 0x00f3,     #  LESS-THAN OR EQUAL TO
+    0x2265: 0x00f2,     #  GREATER-THAN OR EQUAL TO
+    0x2500: 0x00c4,     #  BOX DRAWINGS LIGHT HORIZONTAL
+    0x2502: 0x00b3,     #  BOX DRAWINGS LIGHT VERTICAL
+    0x250c: 0x00da,     #  BOX DRAWINGS LIGHT DOWN AND RIGHT
+    0x2510: 0x00bf,     #  BOX DRAWINGS LIGHT DOWN AND LEFT
+    0x2514: 0x00c0,     #  BOX DRAWINGS LIGHT UP AND RIGHT
+    0x2518: 0x00d9,     #  BOX DRAWINGS LIGHT UP AND LEFT
+    0x251c: 0x00c3,     #  BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+    0x2524: 0x00b4,     #  BOX DRAWINGS LIGHT VERTICAL AND LEFT
+    0x252c: 0x00c2,     #  BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+    0x2534: 0x00c1,     #  BOX DRAWINGS LIGHT UP AND HORIZONTAL
+    0x253c: 0x00c5,     #  BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+    0x2550: 0x00cd,     #  BOX DRAWINGS DOUBLE HORIZONTAL
+    0x2551: 0x00ba,     #  BOX DRAWINGS DOUBLE VERTICAL
+    0x2552: 0x00d5,     #  BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+    0x2553: 0x00d6,     #  BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
+    0x2554: 0x00c9,     #  BOX DRAWINGS DOUBLE DOWN AND RIGHT
+    0x2555: 0x00b8,     #  BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
+    0x2556: 0x00b7,     #  BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
+    0x2557: 0x00bb,     #  BOX DRAWINGS DOUBLE DOWN AND LEFT
+    0x2558: 0x00d4,     #  BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+    0x2559: 0x00d3,     #  BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+    0x255a: 0x00c8,     #  BOX DRAWINGS DOUBLE UP AND RIGHT
+    0x255b: 0x00be,     #  BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+    0x255c: 0x00bd,     #  BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
+    0x255d: 0x00bc,     #  BOX DRAWINGS DOUBLE UP AND LEFT
+    0x255e: 0x00c6,     #  BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+    0x255f: 0x00c7,     #  BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+    0x2560: 0x00cc,     #  BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+    0x2561: 0x00b5,     #  BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+    0x2562: 0x00b6,     #  BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
+    0x2563: 0x00b9,     #  BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+    0x2564: 0x00d1,     #  BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
+    0x2565: 0x00d2,     #  BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
+    0x2566: 0x00cb,     #  BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+    0x2567: 0x00cf,     #  BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+    0x2568: 0x00d0,     #  BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+    0x2569: 0x00ca,     #  BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+    0x256a: 0x00d8,     #  BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+    0x256b: 0x00d7,     #  BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
+    0x256c: 0x00ce,     #  BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+    0x2580: 0x00df,     #  UPPER HALF BLOCK
+    0x2584: 0x00dc,     #  LOWER HALF BLOCK
+    0x2588: 0x00db,     #  FULL BLOCK
+    0x258c: 0x00dd,     #  LEFT HALF BLOCK
+    0x2590: 0x00de,     #  RIGHT HALF BLOCK
+    0x2591: 0x00b0,     #  LIGHT SHADE
+    0x2592: 0x00b1,     #  MEDIUM SHADE
+    0x2593: 0x00b2,     #  DARK SHADE
+    0x25a0: 0x00fe,     #  BLACK SQUARE
+}

Added: vendor/Python/current/Lib/encodings/cp775.py
===================================================================
--- vendor/Python/current/Lib/encodings/cp775.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/cp775.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,697 @@
+""" Python Character Mapping Codec cp775 generated from 'VENDORS/MICSFT/PC/CP775.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_map)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='cp775',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+### Decoding Map
+
+decoding_map = codecs.make_identity_dict(range(256))
+decoding_map.update({
+    0x0080: 0x0106,     #  LATIN CAPITAL LETTER C WITH ACUTE
+    0x0081: 0x00fc,     #  LATIN SMALL LETTER U WITH DIAERESIS
+    0x0082: 0x00e9,     #  LATIN SMALL LETTER E WITH ACUTE
+    0x0083: 0x0101,     #  LATIN SMALL LETTER A WITH MACRON
+    0x0084: 0x00e4,     #  LATIN SMALL LETTER A WITH DIAERESIS
+    0x0085: 0x0123,     #  LATIN SMALL LETTER G WITH CEDILLA
+    0x0086: 0x00e5,     #  LATIN SMALL LETTER A WITH RING ABOVE
+    0x0087: 0x0107,     #  LATIN SMALL LETTER C WITH ACUTE
+    0x0088: 0x0142,     #  LATIN SMALL LETTER L WITH STROKE
+    0x0089: 0x0113,     #  LATIN SMALL LETTER E WITH MACRON
+    0x008a: 0x0156,     #  LATIN CAPITAL LETTER R WITH CEDILLA
+    0x008b: 0x0157,     #  LATIN SMALL LETTER R WITH CEDILLA
+    0x008c: 0x012b,     #  LATIN SMALL LETTER I WITH MACRON
+    0x008d: 0x0179,     #  LATIN CAPITAL LETTER Z WITH ACUTE
+    0x008e: 0x00c4,     #  LATIN CAPITAL LETTER A WITH DIAERESIS
+    0x008f: 0x00c5,     #  LATIN CAPITAL LETTER A WITH RING ABOVE
+    0x0090: 0x00c9,     #  LATIN CAPITAL LETTER E WITH ACUTE
+    0x0091: 0x00e6,     #  LATIN SMALL LIGATURE AE
+    0x0092: 0x00c6,     #  LATIN CAPITAL LIGATURE AE
+    0x0093: 0x014d,     #  LATIN SMALL LETTER O WITH MACRON
+    0x0094: 0x00f6,     #  LATIN SMALL LETTER O WITH DIAERESIS
+    0x0095: 0x0122,     #  LATIN CAPITAL LETTER G WITH CEDILLA
+    0x0096: 0x00a2,     #  CENT SIGN
+    0x0097: 0x015a,     #  LATIN CAPITAL LETTER S WITH ACUTE
+    0x0098: 0x015b,     #  LATIN SMALL LETTER S WITH ACUTE
+    0x0099: 0x00d6,     #  LATIN CAPITAL LETTER O WITH DIAERESIS
+    0x009a: 0x00dc,     #  LATIN CAPITAL LETTER U WITH DIAERESIS
+    0x009b: 0x00f8,     #  LATIN SMALL LETTER O WITH STROKE
+    0x009c: 0x00a3,     #  POUND SIGN
+    0x009d: 0x00d8,     #  LATIN CAPITAL LETTER O WITH STROKE
+    0x009e: 0x00d7,     #  MULTIPLICATION SIGN
+    0x009f: 0x00a4,     #  CURRENCY SIGN
+    0x00a0: 0x0100,     #  LATIN CAPITAL LETTER A WITH MACRON
+    0x00a1: 0x012a,     #  LATIN CAPITAL LETTER I WITH MACRON
+    0x00a2: 0x00f3,     #  LATIN SMALL LETTER O WITH ACUTE
+    0x00a3: 0x017b,     #  LATIN CAPITAL LETTER Z WITH DOT ABOVE
+    0x00a4: 0x017c,     #  LATIN SMALL LETTER Z WITH DOT ABOVE
+    0x00a5: 0x017a,     #  LATIN SMALL LETTER Z WITH ACUTE
+    0x00a6: 0x201d,     #  RIGHT DOUBLE QUOTATION MARK
+    0x00a7: 0x00a6,     #  BROKEN BAR
+    0x00a8: 0x00a9,     #  COPYRIGHT SIGN
+    0x00a9: 0x00ae,     #  REGISTERED SIGN
+    0x00aa: 0x00ac,     #  NOT SIGN
+    0x00ab: 0x00bd,     #  VULGAR FRACTION ONE HALF
+    0x00ac: 0x00bc,     #  VULGAR FRACTION ONE QUARTER
+    0x00ad: 0x0141,     #  LATIN CAPITAL LETTER L WITH STROKE
+    0x00ae: 0x00ab,     #  LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    0x00af: 0x00bb,     #  RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    0x00b0: 0x2591,     #  LIGHT SHADE
+    0x00b1: 0x2592,     #  MEDIUM SHADE
+    0x00b2: 0x2593,     #  DARK SHADE
+    0x00b3: 0x2502,     #  BOX DRAWINGS LIGHT VERTICAL
+    0x00b4: 0x2524,     #  BOX DRAWINGS LIGHT VERTICAL AND LEFT
+    0x00b5: 0x0104,     #  LATIN CAPITAL LETTER A WITH OGONEK
+    0x00b6: 0x010c,     #  LATIN CAPITAL LETTER C WITH CARON
+    0x00b7: 0x0118,     #  LATIN CAPITAL LETTER E WITH OGONEK
+    0x00b8: 0x0116,     #  LATIN CAPITAL LETTER E WITH DOT ABOVE
+    0x00b9: 0x2563,     #  BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+    0x00ba: 0x2551,     #  BOX DRAWINGS DOUBLE VERTICAL
+    0x00bb: 0x2557,     #  BOX DRAWINGS DOUBLE DOWN AND LEFT
+    0x00bc: 0x255d,     #  BOX DRAWINGS DOUBLE UP AND LEFT
+    0x00bd: 0x012e,     #  LATIN CAPITAL LETTER I WITH OGONEK
+    0x00be: 0x0160,     #  LATIN CAPITAL LETTER S WITH CARON
+    0x00bf: 0x2510,     #  BOX DRAWINGS LIGHT DOWN AND LEFT
+    0x00c0: 0x2514,     #  BOX DRAWINGS LIGHT UP AND RIGHT
+    0x00c1: 0x2534,     #  BOX DRAWINGS LIGHT UP AND HORIZONTAL
+    0x00c2: 0x252c,     #  BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+    0x00c3: 0x251c,     #  BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+    0x00c4: 0x2500,     #  BOX DRAWINGS LIGHT HORIZONTAL
+    0x00c5: 0x253c,     #  BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+    0x00c6: 0x0172,     #  LATIN CAPITAL LETTER U WITH OGONEK
+    0x00c7: 0x016a,     #  LATIN CAPITAL LETTER U WITH MACRON
+    0x00c8: 0x255a,     #  BOX DRAWINGS DOUBLE UP AND RIGHT
+    0x00c9: 0x2554,     #  BOX DRAWINGS DOUBLE DOWN AND RIGHT
+    0x00ca: 0x2569,     #  BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+    0x00cb: 0x2566,     #  BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+    0x00cc: 0x2560,     #  BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+    0x00cd: 0x2550,     #  BOX DRAWINGS DOUBLE HORIZONTAL
+    0x00ce: 0x256c,     #  BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+    0x00cf: 0x017d,     #  LATIN CAPITAL LETTER Z WITH CARON
+    0x00d0: 0x0105,     #  LATIN SMALL LETTER A WITH OGONEK
+    0x00d1: 0x010d,     #  LATIN SMALL LETTER C WITH CARON
+    0x00d2: 0x0119,     #  LATIN SMALL LETTER E WITH OGONEK
+    0x00d3: 0x0117,     #  LATIN SMALL LETTER E WITH DOT ABOVE
+    0x00d4: 0x012f,     #  LATIN SMALL LETTER I WITH OGONEK
+    0x00d5: 0x0161,     #  LATIN SMALL LETTER S WITH CARON
+    0x00d6: 0x0173,     #  LATIN SMALL LETTER U WITH OGONEK
+    0x00d7: 0x016b,     #  LATIN SMALL LETTER U WITH MACRON
+    0x00d8: 0x017e,     #  LATIN SMALL LETTER Z WITH CARON
+    0x00d9: 0x2518,     #  BOX DRAWINGS LIGHT UP AND LEFT
+    0x00da: 0x250c,     #  BOX DRAWINGS LIGHT DOWN AND RIGHT
+    0x00db: 0x2588,     #  FULL BLOCK
+    0x00dc: 0x2584,     #  LOWER HALF BLOCK
+    0x00dd: 0x258c,     #  LEFT HALF BLOCK
+    0x00de: 0x2590,     #  RIGHT HALF BLOCK
+    0x00df: 0x2580,     #  UPPER HALF BLOCK
+    0x00e0: 0x00d3,     #  LATIN CAPITAL LETTER O WITH ACUTE
+    0x00e1: 0x00df,     #  LATIN SMALL LETTER SHARP S (GERMAN)
+    0x00e2: 0x014c,     #  LATIN CAPITAL LETTER O WITH MACRON
+    0x00e3: 0x0143,     #  LATIN CAPITAL LETTER N WITH ACUTE
+    0x00e4: 0x00f5,     #  LATIN SMALL LETTER O WITH TILDE
+    0x00e5: 0x00d5,     #  LATIN CAPITAL LETTER O WITH TILDE
+    0x00e6: 0x00b5,     #  MICRO SIGN
+    0x00e7: 0x0144,     #  LATIN SMALL LETTER N WITH ACUTE
+    0x00e8: 0x0136,     #  LATIN CAPITAL LETTER K WITH CEDILLA
+    0x00e9: 0x0137,     #  LATIN SMALL LETTER K WITH CEDILLA
+    0x00ea: 0x013b,     #  LATIN CAPITAL LETTER L WITH CEDILLA
+    0x00eb: 0x013c,     #  LATIN SMALL LETTER L WITH CEDILLA
+    0x00ec: 0x0146,     #  LATIN SMALL LETTER N WITH CEDILLA
+    0x00ed: 0x0112,     #  LATIN CAPITAL LETTER E WITH MACRON
+    0x00ee: 0x0145,     #  LATIN CAPITAL LETTER N WITH CEDILLA
+    0x00ef: 0x2019,     #  RIGHT SINGLE QUOTATION MARK
+    0x00f0: 0x00ad,     #  SOFT HYPHEN
+    0x00f1: 0x00b1,     #  PLUS-MINUS SIGN
+    0x00f2: 0x201c,     #  LEFT DOUBLE QUOTATION MARK
+    0x00f3: 0x00be,     #  VULGAR FRACTION THREE QUARTERS
+    0x00f4: 0x00b6,     #  PILCROW SIGN
+    0x00f5: 0x00a7,     #  SECTION SIGN
+    0x00f6: 0x00f7,     #  DIVISION SIGN
+    0x00f7: 0x201e,     #  DOUBLE LOW-9 QUOTATION MARK
+    0x00f8: 0x00b0,     #  DEGREE SIGN
+    0x00f9: 0x2219,     #  BULLET OPERATOR
+    0x00fa: 0x00b7,     #  MIDDLE DOT
+    0x00fb: 0x00b9,     #  SUPERSCRIPT ONE
+    0x00fc: 0x00b3,     #  SUPERSCRIPT THREE
+    0x00fd: 0x00b2,     #  SUPERSCRIPT TWO
+    0x00fe: 0x25a0,     #  BLACK SQUARE
+    0x00ff: 0x00a0,     #  NO-BREAK SPACE
+})
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x0000 -> NULL
+    u'\x01'     #  0x0001 -> START OF HEADING
+    u'\x02'     #  0x0002 -> START OF TEXT
+    u'\x03'     #  0x0003 -> END OF TEXT
+    u'\x04'     #  0x0004 -> END OF TRANSMISSION
+    u'\x05'     #  0x0005 -> ENQUIRY
+    u'\x06'     #  0x0006 -> ACKNOWLEDGE
+    u'\x07'     #  0x0007 -> BELL
+    u'\x08'     #  0x0008 -> BACKSPACE
+    u'\t'       #  0x0009 -> HORIZONTAL TABULATION
+    u'\n'       #  0x000a -> LINE FEED
+    u'\x0b'     #  0x000b -> VERTICAL TABULATION
+    u'\x0c'     #  0x000c -> FORM FEED
+    u'\r'       #  0x000d -> CARRIAGE RETURN
+    u'\x0e'     #  0x000e -> SHIFT OUT
+    u'\x0f'     #  0x000f -> SHIFT IN
+    u'\x10'     #  0x0010 -> DATA LINK ESCAPE
+    u'\x11'     #  0x0011 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x0012 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x0013 -> DEVICE CONTROL THREE
+    u'\x14'     #  0x0014 -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x0015 -> NEGATIVE ACKNOWLEDGE
+    u'\x16'     #  0x0016 -> SYNCHRONOUS IDLE
+    u'\x17'     #  0x0017 -> END OF TRANSMISSION BLOCK
+    u'\x18'     #  0x0018 -> CANCEL
+    u'\x19'     #  0x0019 -> END OF MEDIUM
+    u'\x1a'     #  0x001a -> SUBSTITUTE
+    u'\x1b'     #  0x001b -> ESCAPE
+    u'\x1c'     #  0x001c -> FILE SEPARATOR
+    u'\x1d'     #  0x001d -> GROUP SEPARATOR
+    u'\x1e'     #  0x001e -> RECORD SEPARATOR
+    u'\x1f'     #  0x001f -> UNIT SEPARATOR
+    u' '        #  0x0020 -> SPACE
+    u'!'        #  0x0021 -> EXCLAMATION MARK
+    u'"'        #  0x0022 -> QUOTATION MARK
+    u'#'        #  0x0023 -> NUMBER SIGN
+    u'$'        #  0x0024 -> DOLLAR SIGN
+    u'%'        #  0x0025 -> PERCENT SIGN
+    u'&'        #  0x0026 -> AMPERSAND
+    u"'"        #  0x0027 -> APOSTROPHE
+    u'('        #  0x0028 -> LEFT PARENTHESIS
+    u')'        #  0x0029 -> RIGHT PARENTHESIS
+    u'*'        #  0x002a -> ASTERISK
+    u'+'        #  0x002b -> PLUS SIGN
+    u','        #  0x002c -> COMMA
+    u'-'        #  0x002d -> HYPHEN-MINUS
+    u'.'        #  0x002e -> FULL STOP
+    u'/'        #  0x002f -> SOLIDUS
+    u'0'        #  0x0030 -> DIGIT ZERO
+    u'1'        #  0x0031 -> DIGIT ONE
+    u'2'        #  0x0032 -> DIGIT TWO
+    u'3'        #  0x0033 -> DIGIT THREE
+    u'4'        #  0x0034 -> DIGIT FOUR
+    u'5'        #  0x0035 -> DIGIT FIVE
+    u'6'        #  0x0036 -> DIGIT SIX
+    u'7'        #  0x0037 -> DIGIT SEVEN
+    u'8'        #  0x0038 -> DIGIT EIGHT
+    u'9'        #  0x0039 -> DIGIT NINE
+    u':'        #  0x003a -> COLON
+    u';'        #  0x003b -> SEMICOLON
+    u'<'        #  0x003c -> LESS-THAN SIGN
+    u'='        #  0x003d -> EQUALS SIGN
+    u'>'        #  0x003e -> GREATER-THAN SIGN
+    u'?'        #  0x003f -> QUESTION MARK
+    u'@'        #  0x0040 -> COMMERCIAL AT
+    u'A'        #  0x0041 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x0042 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x0043 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x0044 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x0045 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x0046 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x0047 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x0048 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x0049 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x004a -> LATIN CAPITAL LETTER J
+    u'K'        #  0x004b -> LATIN CAPITAL LETTER K
+    u'L'        #  0x004c -> LATIN CAPITAL LETTER L
+    u'M'        #  0x004d -> LATIN CAPITAL LETTER M
+    u'N'        #  0x004e -> LATIN CAPITAL LETTER N
+    u'O'        #  0x004f -> LATIN CAPITAL LETTER O
+    u'P'        #  0x0050 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x0051 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x0052 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x0053 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x0054 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x0055 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x0056 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x0057 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x0058 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x0059 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x005a -> LATIN CAPITAL LETTER Z
+    u'['        #  0x005b -> LEFT SQUARE BRACKET
+    u'\\'       #  0x005c -> REVERSE SOLIDUS
+    u']'        #  0x005d -> RIGHT SQUARE BRACKET
+    u'^'        #  0x005e -> CIRCUMFLEX ACCENT
+    u'_'        #  0x005f -> LOW LINE
+    u'`'        #  0x0060 -> GRAVE ACCENT
+    u'a'        #  0x0061 -> LATIN SMALL LETTER A
+    u'b'        #  0x0062 -> LATIN SMALL LETTER B
+    u'c'        #  0x0063 -> LATIN SMALL LETTER C
+    u'd'        #  0x0064 -> LATIN SMALL LETTER D
+    u'e'        #  0x0065 -> LATIN SMALL LETTER E
+    u'f'        #  0x0066 -> LATIN SMALL LETTER F
+    u'g'        #  0x0067 -> LATIN SMALL LETTER G
+    u'h'        #  0x0068 -> LATIN SMALL LETTER H
+    u'i'        #  0x0069 -> LATIN SMALL LETTER I
+    u'j'        #  0x006a -> LATIN SMALL LETTER J
+    u'k'        #  0x006b -> LATIN SMALL LETTER K
+    u'l'        #  0x006c -> LATIN SMALL LETTER L
+    u'm'        #  0x006d -> LATIN SMALL LETTER M
+    u'n'        #  0x006e -> LATIN SMALL LETTER N
+    u'o'        #  0x006f -> LATIN SMALL LETTER O
+    u'p'        #  0x0070 -> LATIN SMALL LETTER P
+    u'q'        #  0x0071 -> LATIN SMALL LETTER Q
+    u'r'        #  0x0072 -> LATIN SMALL LETTER R
+    u's'        #  0x0073 -> LATIN SMALL LETTER S
+    u't'        #  0x0074 -> LATIN SMALL LETTER T
+    u'u'        #  0x0075 -> LATIN SMALL LETTER U
+    u'v'        #  0x0076 -> LATIN SMALL LETTER V
+    u'w'        #  0x0077 -> LATIN SMALL LETTER W
+    u'x'        #  0x0078 -> LATIN SMALL LETTER X
+    u'y'        #  0x0079 -> LATIN SMALL LETTER Y
+    u'z'        #  0x007a -> LATIN SMALL LETTER Z
+    u'{'        #  0x007b -> LEFT CURLY BRACKET
+    u'|'        #  0x007c -> VERTICAL LINE
+    u'}'        #  0x007d -> RIGHT CURLY BRACKET
+    u'~'        #  0x007e -> TILDE
+    u'\x7f'     #  0x007f -> DELETE
+    u'\u0106'   #  0x0080 -> LATIN CAPITAL LETTER C WITH ACUTE
+    u'\xfc'     #  0x0081 -> LATIN SMALL LETTER U WITH DIAERESIS
+    u'\xe9'     #  0x0082 -> LATIN SMALL LETTER E WITH ACUTE
+    u'\u0101'   #  0x0083 -> LATIN SMALL LETTER A WITH MACRON
+    u'\xe4'     #  0x0084 -> LATIN SMALL LETTER A WITH DIAERESIS
+    u'\u0123'   #  0x0085 -> LATIN SMALL LETTER G WITH CEDILLA
+    u'\xe5'     #  0x0086 -> LATIN SMALL LETTER A WITH RING ABOVE
+    u'\u0107'   #  0x0087 -> LATIN SMALL LETTER C WITH ACUTE
+    u'\u0142'   #  0x0088 -> LATIN SMALL LETTER L WITH STROKE
+    u'\u0113'   #  0x0089 -> LATIN SMALL LETTER E WITH MACRON
+    u'\u0156'   #  0x008a -> LATIN CAPITAL LETTER R WITH CEDILLA
+    u'\u0157'   #  0x008b -> LATIN SMALL LETTER R WITH CEDILLA
+    u'\u012b'   #  0x008c -> LATIN SMALL LETTER I WITH MACRON
+    u'\u0179'   #  0x008d -> LATIN CAPITAL LETTER Z WITH ACUTE
+    u'\xc4'     #  0x008e -> LATIN CAPITAL LETTER A WITH DIAERESIS
+    u'\xc5'     #  0x008f -> LATIN CAPITAL LETTER A WITH RING ABOVE
+    u'\xc9'     #  0x0090 -> LATIN CAPITAL LETTER E WITH ACUTE
+    u'\xe6'     #  0x0091 -> LATIN SMALL LIGATURE AE
+    u'\xc6'     #  0x0092 -> LATIN CAPITAL LIGATURE AE
+    u'\u014d'   #  0x0093 -> LATIN SMALL LETTER O WITH MACRON
+    u'\xf6'     #  0x0094 -> LATIN SMALL LETTER O WITH DIAERESIS
+    u'\u0122'   #  0x0095 -> LATIN CAPITAL LETTER G WITH CEDILLA
+    u'\xa2'     #  0x0096 -> CENT SIGN
+    u'\u015a'   #  0x0097 -> LATIN CAPITAL LETTER S WITH ACUTE
+    u'\u015b'   #  0x0098 -> LATIN SMALL LETTER S WITH ACUTE
+    u'\xd6'     #  0x0099 -> LATIN CAPITAL LETTER O WITH DIAERESIS
+    u'\xdc'     #  0x009a -> LATIN CAPITAL LETTER U WITH DIAERESIS
+    u'\xf8'     #  0x009b -> LATIN SMALL LETTER O WITH STROKE
+    u'\xa3'     #  0x009c -> POUND SIGN
+    u'\xd8'     #  0x009d -> LATIN CAPITAL LETTER O WITH STROKE
+    u'\xd7'     #  0x009e -> MULTIPLICATION SIGN
+    u'\xa4'     #  0x009f -> CURRENCY SIGN
+    u'\u0100'   #  0x00a0 -> LATIN CAPITAL LETTER A WITH MACRON
+    u'\u012a'   #  0x00a1 -> LATIN CAPITAL LETTER I WITH MACRON
+    u'\xf3'     #  0x00a2 -> LATIN SMALL LETTER O WITH ACUTE
+    u'\u017b'   #  0x00a3 -> LATIN CAPITAL LETTER Z WITH DOT ABOVE
+    u'\u017c'   #  0x00a4 -> LATIN SMALL LETTER Z WITH DOT ABOVE
+    u'\u017a'   #  0x00a5 -> LATIN SMALL LETTER Z WITH ACUTE
+    u'\u201d'   #  0x00a6 -> RIGHT DOUBLE QUOTATION MARK
+    u'\xa6'     #  0x00a7 -> BROKEN BAR
+    u'\xa9'     #  0x00a8 -> COPYRIGHT SIGN
+    u'\xae'     #  0x00a9 -> REGISTERED SIGN
+    u'\xac'     #  0x00aa -> NOT SIGN
+    u'\xbd'     #  0x00ab -> VULGAR FRACTION ONE HALF
+    u'\xbc'     #  0x00ac -> VULGAR FRACTION ONE QUARTER
+    u'\u0141'   #  0x00ad -> LATIN CAPITAL LETTER L WITH STROKE
+    u'\xab'     #  0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xbb'     #  0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\u2591'   #  0x00b0 -> LIGHT SHADE
+    u'\u2592'   #  0x00b1 -> MEDIUM SHADE
+    u'\u2593'   #  0x00b2 -> DARK SHADE
+    u'\u2502'   #  0x00b3 -> BOX DRAWINGS LIGHT VERTICAL
+    u'\u2524'   #  0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT
+    u'\u0104'   #  0x00b5 -> LATIN CAPITAL LETTER A WITH OGONEK
+    u'\u010c'   #  0x00b6 -> LATIN CAPITAL LETTER C WITH CARON
+    u'\u0118'   #  0x00b7 -> LATIN CAPITAL LETTER E WITH OGONEK
+    u'\u0116'   #  0x00b8 -> LATIN CAPITAL LETTER E WITH DOT ABOVE
+    u'\u2563'   #  0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+    u'\u2551'   #  0x00ba -> BOX DRAWINGS DOUBLE VERTICAL
+    u'\u2557'   #  0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT
+    u'\u255d'   #  0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT
+    u'\u012e'   #  0x00bd -> LATIN CAPITAL LETTER I WITH OGONEK
+    u'\u0160'   #  0x00be -> LATIN CAPITAL LETTER S WITH CARON
+    u'\u2510'   #  0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT
+    u'\u2514'   #  0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT
+    u'\u2534'   #  0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL
+    u'\u252c'   #  0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+    u'\u251c'   #  0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+    u'\u2500'   #  0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL
+    u'\u253c'   #  0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+    u'\u0172'   #  0x00c6 -> LATIN CAPITAL LETTER U WITH OGONEK
+    u'\u016a'   #  0x00c7 -> LATIN CAPITAL LETTER U WITH MACRON
+    u'\u255a'   #  0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT
+    u'\u2554'   #  0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT
+    u'\u2569'   #  0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+    u'\u2566'   #  0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+    u'\u2560'   #  0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+    u'\u2550'   #  0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL
+    u'\u256c'   #  0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+    u'\u017d'   #  0x00cf -> LATIN CAPITAL LETTER Z WITH CARON
+    u'\u0105'   #  0x00d0 -> LATIN SMALL LETTER A WITH OGONEK
+    u'\u010d'   #  0x00d1 -> LATIN SMALL LETTER C WITH CARON
+    u'\u0119'   #  0x00d2 -> LATIN SMALL LETTER E WITH OGONEK
+    u'\u0117'   #  0x00d3 -> LATIN SMALL LETTER E WITH DOT ABOVE
+    u'\u012f'   #  0x00d4 -> LATIN SMALL LETTER I WITH OGONEK
+    u'\u0161'   #  0x00d5 -> LATIN SMALL LETTER S WITH CARON
+    u'\u0173'   #  0x00d6 -> LATIN SMALL LETTER U WITH OGONEK
+    u'\u016b'   #  0x00d7 -> LATIN SMALL LETTER U WITH MACRON
+    u'\u017e'   #  0x00d8 -> LATIN SMALL LETTER Z WITH CARON
+    u'\u2518'   #  0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT
+    u'\u250c'   #  0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT
+    u'\u2588'   #  0x00db -> FULL BLOCK
+    u'\u2584'   #  0x00dc -> LOWER HALF BLOCK
+    u'\u258c'   #  0x00dd -> LEFT HALF BLOCK
+    u'\u2590'   #  0x00de -> RIGHT HALF BLOCK
+    u'\u2580'   #  0x00df -> UPPER HALF BLOCK
+    u'\xd3'     #  0x00e0 -> LATIN CAPITAL LETTER O WITH ACUTE
+    u'\xdf'     #  0x00e1 -> LATIN SMALL LETTER SHARP S (GERMAN)
+    u'\u014c'   #  0x00e2 -> LATIN CAPITAL LETTER O WITH MACRON
+    u'\u0143'   #  0x00e3 -> LATIN CAPITAL LETTER N WITH ACUTE
+    u'\xf5'     #  0x00e4 -> LATIN SMALL LETTER O WITH TILDE
+    u'\xd5'     #  0x00e5 -> LATIN CAPITAL LETTER O WITH TILDE
+    u'\xb5'     #  0x00e6 -> MICRO SIGN
+    u'\u0144'   #  0x00e7 -> LATIN SMALL LETTER N WITH ACUTE
+    u'\u0136'   #  0x00e8 -> LATIN CAPITAL LETTER K WITH CEDILLA
+    u'\u0137'   #  0x00e9 -> LATIN SMALL LETTER K WITH CEDILLA
+    u'\u013b'   #  0x00ea -> LATIN CAPITAL LETTER L WITH CEDILLA
+    u'\u013c'   #  0x00eb -> LATIN SMALL LETTER L WITH CEDILLA
+    u'\u0146'   #  0x00ec -> LATIN SMALL LETTER N WITH CEDILLA
+    u'\u0112'   #  0x00ed -> LATIN CAPITAL LETTER E WITH MACRON
+    u'\u0145'   #  0x00ee -> LATIN CAPITAL LETTER N WITH CEDILLA
+    u'\u2019'   #  0x00ef -> RIGHT SINGLE QUOTATION MARK
+    u'\xad'     #  0x00f0 -> SOFT HYPHEN
+    u'\xb1'     #  0x00f1 -> PLUS-MINUS SIGN
+    u'\u201c'   #  0x00f2 -> LEFT DOUBLE QUOTATION MARK
+    u'\xbe'     #  0x00f3 -> VULGAR FRACTION THREE QUARTERS
+    u'\xb6'     #  0x00f4 -> PILCROW SIGN
+    u'\xa7'     #  0x00f5 -> SECTION SIGN
+    u'\xf7'     #  0x00f6 -> DIVISION SIGN
+    u'\u201e'   #  0x00f7 -> DOUBLE LOW-9 QUOTATION MARK
+    u'\xb0'     #  0x00f8 -> DEGREE SIGN
+    u'\u2219'   #  0x00f9 -> BULLET OPERATOR
+    u'\xb7'     #  0x00fa -> MIDDLE DOT
+    u'\xb9'     #  0x00fb -> SUPERSCRIPT ONE
+    u'\xb3'     #  0x00fc -> SUPERSCRIPT THREE
+    u'\xb2'     #  0x00fd -> SUPERSCRIPT TWO
+    u'\u25a0'   #  0x00fe -> BLACK SQUARE
+    u'\xa0'     #  0x00ff -> NO-BREAK SPACE
+)
+
+### Encoding Map
+
+encoding_map = {
+    0x0000: 0x0000,     #  NULL
+    0x0001: 0x0001,     #  START OF HEADING
+    0x0002: 0x0002,     #  START OF TEXT
+    0x0003: 0x0003,     #  END OF TEXT
+    0x0004: 0x0004,     #  END OF TRANSMISSION
+    0x0005: 0x0005,     #  ENQUIRY
+    0x0006: 0x0006,     #  ACKNOWLEDGE
+    0x0007: 0x0007,     #  BELL
+    0x0008: 0x0008,     #  BACKSPACE
+    0x0009: 0x0009,     #  HORIZONTAL TABULATION
+    0x000a: 0x000a,     #  LINE FEED
+    0x000b: 0x000b,     #  VERTICAL TABULATION
+    0x000c: 0x000c,     #  FORM FEED
+    0x000d: 0x000d,     #  CARRIAGE RETURN
+    0x000e: 0x000e,     #  SHIFT OUT
+    0x000f: 0x000f,     #  SHIFT IN
+    0x0010: 0x0010,     #  DATA LINK ESCAPE
+    0x0011: 0x0011,     #  DEVICE CONTROL ONE
+    0x0012: 0x0012,     #  DEVICE CONTROL TWO
+    0x0013: 0x0013,     #  DEVICE CONTROL THREE
+    0x0014: 0x0014,     #  DEVICE CONTROL FOUR
+    0x0015: 0x0015,     #  NEGATIVE ACKNOWLEDGE
+    0x0016: 0x0016,     #  SYNCHRONOUS IDLE
+    0x0017: 0x0017,     #  END OF TRANSMISSION BLOCK
+    0x0018: 0x0018,     #  CANCEL
+    0x0019: 0x0019,     #  END OF MEDIUM
+    0x001a: 0x001a,     #  SUBSTITUTE
+    0x001b: 0x001b,     #  ESCAPE
+    0x001c: 0x001c,     #  FILE SEPARATOR
+    0x001d: 0x001d,     #  GROUP SEPARATOR
+    0x001e: 0x001e,     #  RECORD SEPARATOR
+    0x001f: 0x001f,     #  UNIT SEPARATOR
+    0x0020: 0x0020,     #  SPACE
+    0x0021: 0x0021,     #  EXCLAMATION MARK
+    0x0022: 0x0022,     #  QUOTATION MARK
+    0x0023: 0x0023,     #  NUMBER SIGN
+    0x0024: 0x0024,     #  DOLLAR SIGN
+    0x0025: 0x0025,     #  PERCENT SIGN
+    0x0026: 0x0026,     #  AMPERSAND
+    0x0027: 0x0027,     #  APOSTROPHE
+    0x0028: 0x0028,     #  LEFT PARENTHESIS
+    0x0029: 0x0029,     #  RIGHT PARENTHESIS
+    0x002a: 0x002a,     #  ASTERISK
+    0x002b: 0x002b,     #  PLUS SIGN
+    0x002c: 0x002c,     #  COMMA
+    0x002d: 0x002d,     #  HYPHEN-MINUS
+    0x002e: 0x002e,     #  FULL STOP
+    0x002f: 0x002f,     #  SOLIDUS
+    0x0030: 0x0030,     #  DIGIT ZERO
+    0x0031: 0x0031,     #  DIGIT ONE
+    0x0032: 0x0032,     #  DIGIT TWO
+    0x0033: 0x0033,     #  DIGIT THREE
+    0x0034: 0x0034,     #  DIGIT FOUR
+    0x0035: 0x0035,     #  DIGIT FIVE
+    0x0036: 0x0036,     #  DIGIT SIX
+    0x0037: 0x0037,     #  DIGIT SEVEN
+    0x0038: 0x0038,     #  DIGIT EIGHT
+    0x0039: 0x0039,     #  DIGIT NINE
+    0x003a: 0x003a,     #  COLON
+    0x003b: 0x003b,     #  SEMICOLON
+    0x003c: 0x003c,     #  LESS-THAN SIGN
+    0x003d: 0x003d,     #  EQUALS SIGN
+    0x003e: 0x003e,     #  GREATER-THAN SIGN
+    0x003f: 0x003f,     #  QUESTION MARK
+    0x0040: 0x0040,     #  COMMERCIAL AT
+    0x0041: 0x0041,     #  LATIN CAPITAL LETTER A
+    0x0042: 0x0042,     #  LATIN CAPITAL LETTER B
+    0x0043: 0x0043,     #  LATIN CAPITAL LETTER C
+    0x0044: 0x0044,     #  LATIN CAPITAL LETTER D
+    0x0045: 0x0045,     #  LATIN CAPITAL LETTER E
+    0x0046: 0x0046,     #  LATIN CAPITAL LETTER F
+    0x0047: 0x0047,     #  LATIN CAPITAL LETTER G
+    0x0048: 0x0048,     #  LATIN CAPITAL LETTER H
+    0x0049: 0x0049,     #  LATIN CAPITAL LETTER I
+    0x004a: 0x004a,     #  LATIN CAPITAL LETTER J
+    0x004b: 0x004b,     #  LATIN CAPITAL LETTER K
+    0x004c: 0x004c,     #  LATIN CAPITAL LETTER L
+    0x004d: 0x004d,     #  LATIN CAPITAL LETTER M
+    0x004e: 0x004e,     #  LATIN CAPITAL LETTER N
+    0x004f: 0x004f,     #  LATIN CAPITAL LETTER O
+    0x0050: 0x0050,     #  LATIN CAPITAL LETTER P
+    0x0051: 0x0051,     #  LATIN CAPITAL LETTER Q
+    0x0052: 0x0052,     #  LATIN CAPITAL LETTER R
+    0x0053: 0x0053,     #  LATIN CAPITAL LETTER S
+    0x0054: 0x0054,     #  LATIN CAPITAL LETTER T
+    0x0055: 0x0055,     #  LATIN CAPITAL LETTER U
+    0x0056: 0x0056,     #  LATIN CAPITAL LETTER V
+    0x0057: 0x0057,     #  LATIN CAPITAL LETTER W
+    0x0058: 0x0058,     #  LATIN CAPITAL LETTER X
+    0x0059: 0x0059,     #  LATIN CAPITAL LETTER Y
+    0x005a: 0x005a,     #  LATIN CAPITAL LETTER Z
+    0x005b: 0x005b,     #  LEFT SQUARE BRACKET
+    0x005c: 0x005c,     #  REVERSE SOLIDUS
+    0x005d: 0x005d,     #  RIGHT SQUARE BRACKET
+    0x005e: 0x005e,     #  CIRCUMFLEX ACCENT
+    0x005f: 0x005f,     #  LOW LINE
+    0x0060: 0x0060,     #  GRAVE ACCENT
+    0x0061: 0x0061,     #  LATIN SMALL LETTER A
+    0x0062: 0x0062,     #  LATIN SMALL LETTER B
+    0x0063: 0x0063,     #  LATIN SMALL LETTER C
+    0x0064: 0x0064,     #  LATIN SMALL LETTER D
+    0x0065: 0x0065,     #  LATIN SMALL LETTER E
+    0x0066: 0x0066,     #  LATIN SMALL LETTER F
+    0x0067: 0x0067,     #  LATIN SMALL LETTER G
+    0x0068: 0x0068,     #  LATIN SMALL LETTER H
+    0x0069: 0x0069,     #  LATIN SMALL LETTER I
+    0x006a: 0x006a,     #  LATIN SMALL LETTER J
+    0x006b: 0x006b,     #  LATIN SMALL LETTER K
+    0x006c: 0x006c,     #  LATIN SMALL LETTER L
+    0x006d: 0x006d,     #  LATIN SMALL LETTER M
+    0x006e: 0x006e,     #  LATIN SMALL LETTER N
+    0x006f: 0x006f,     #  LATIN SMALL LETTER O
+    0x0070: 0x0070,     #  LATIN SMALL LETTER P
+    0x0071: 0x0071,     #  LATIN SMALL LETTER Q
+    0x0072: 0x0072,     #  LATIN SMALL LETTER R
+    0x0073: 0x0073,     #  LATIN SMALL LETTER S
+    0x0074: 0x0074,     #  LATIN SMALL LETTER T
+    0x0075: 0x0075,     #  LATIN SMALL LETTER U
+    0x0076: 0x0076,     #  LATIN SMALL LETTER V
+    0x0077: 0x0077,     #  LATIN SMALL LETTER W
+    0x0078: 0x0078,     #  LATIN SMALL LETTER X
+    0x0079: 0x0079,     #  LATIN SMALL LETTER Y
+    0x007a: 0x007a,     #  LATIN SMALL LETTER Z
+    0x007b: 0x007b,     #  LEFT CURLY BRACKET
+    0x007c: 0x007c,     #  VERTICAL LINE
+    0x007d: 0x007d,     #  RIGHT CURLY BRACKET
+    0x007e: 0x007e,     #  TILDE
+    0x007f: 0x007f,     #  DELETE
+    0x00a0: 0x00ff,     #  NO-BREAK SPACE
+    0x00a2: 0x0096,     #  CENT SIGN
+    0x00a3: 0x009c,     #  POUND SIGN
+    0x00a4: 0x009f,     #  CURRENCY SIGN
+    0x00a6: 0x00a7,     #  BROKEN BAR
+    0x00a7: 0x00f5,     #  SECTION SIGN
+    0x00a9: 0x00a8,     #  COPYRIGHT SIGN
+    0x00ab: 0x00ae,     #  LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    0x00ac: 0x00aa,     #  NOT SIGN
+    0x00ad: 0x00f0,     #  SOFT HYPHEN
+    0x00ae: 0x00a9,     #  REGISTERED SIGN
+    0x00b0: 0x00f8,     #  DEGREE SIGN
+    0x00b1: 0x00f1,     #  PLUS-MINUS SIGN
+    0x00b2: 0x00fd,     #  SUPERSCRIPT TWO
+    0x00b3: 0x00fc,     #  SUPERSCRIPT THREE
+    0x00b5: 0x00e6,     #  MICRO SIGN
+    0x00b6: 0x00f4,     #  PILCROW SIGN
+    0x00b7: 0x00fa,     #  MIDDLE DOT
+    0x00b9: 0x00fb,     #  SUPERSCRIPT ONE
+    0x00bb: 0x00af,     #  RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    0x00bc: 0x00ac,     #  VULGAR FRACTION ONE QUARTER
+    0x00bd: 0x00ab,     #  VULGAR FRACTION ONE HALF
+    0x00be: 0x00f3,     #  VULGAR FRACTION THREE QUARTERS
+    0x00c4: 0x008e,     #  LATIN CAPITAL LETTER A WITH DIAERESIS
+    0x00c5: 0x008f,     #  LATIN CAPITAL LETTER A WITH RING ABOVE
+    0x00c6: 0x0092,     #  LATIN CAPITAL LIGATURE AE
+    0x00c9: 0x0090,     #  LATIN CAPITAL LETTER E WITH ACUTE
+    0x00d3: 0x00e0,     #  LATIN CAPITAL LETTER O WITH ACUTE
+    0x00d5: 0x00e5,     #  LATIN CAPITAL LETTER O WITH TILDE
+    0x00d6: 0x0099,     #  LATIN CAPITAL LETTER O WITH DIAERESIS
+    0x00d7: 0x009e,     #  MULTIPLICATION SIGN
+    0x00d8: 0x009d,     #  LATIN CAPITAL LETTER O WITH STROKE
+    0x00dc: 0x009a,     #  LATIN CAPITAL LETTER U WITH DIAERESIS
+    0x00df: 0x00e1,     #  LATIN SMALL LETTER SHARP S (GERMAN)
+    0x00e4: 0x0084,     #  LATIN SMALL LETTER A WITH DIAERESIS
+    0x00e5: 0x0086,     #  LATIN SMALL LETTER A WITH RING ABOVE
+    0x00e6: 0x0091,     #  LATIN SMALL LIGATURE AE
+    0x00e9: 0x0082,     #  LATIN SMALL LETTER E WITH ACUTE
+    0x00f3: 0x00a2,     #  LATIN SMALL LETTER O WITH ACUTE
+    0x00f5: 0x00e4,     #  LATIN SMALL LETTER O WITH TILDE
+    0x00f6: 0x0094,     #  LATIN SMALL LETTER O WITH DIAERESIS
+    0x00f7: 0x00f6,     #  DIVISION SIGN
+    0x00f8: 0x009b,     #  LATIN SMALL LETTER O WITH STROKE
+    0x00fc: 0x0081,     #  LATIN SMALL LETTER U WITH DIAERESIS
+    0x0100: 0x00a0,     #  LATIN CAPITAL LETTER A WITH MACRON
+    0x0101: 0x0083,     #  LATIN SMALL LETTER A WITH MACRON
+    0x0104: 0x00b5,     #  LATIN CAPITAL LETTER A WITH OGONEK
+    0x0105: 0x00d0,     #  LATIN SMALL LETTER A WITH OGONEK
+    0x0106: 0x0080,     #  LATIN CAPITAL LETTER C WITH ACUTE
+    0x0107: 0x0087,     #  LATIN SMALL LETTER C WITH ACUTE
+    0x010c: 0x00b6,     #  LATIN CAPITAL LETTER C WITH CARON
+    0x010d: 0x00d1,     #  LATIN SMALL LETTER C WITH CARON
+    0x0112: 0x00ed,     #  LATIN CAPITAL LETTER E WITH MACRON
+    0x0113: 0x0089,     #  LATIN SMALL LETTER E WITH MACRON
+    0x0116: 0x00b8,     #  LATIN CAPITAL LETTER E WITH DOT ABOVE
+    0x0117: 0x00d3,     #  LATIN SMALL LETTER E WITH DOT ABOVE
+    0x0118: 0x00b7,     #  LATIN CAPITAL LETTER E WITH OGONEK
+    0x0119: 0x00d2,     #  LATIN SMALL LETTER E WITH OGONEK
+    0x0122: 0x0095,     #  LATIN CAPITAL LETTER G WITH CEDILLA
+    0x0123: 0x0085,     #  LATIN SMALL LETTER G WITH CEDILLA
+    0x012a: 0x00a1,     #  LATIN CAPITAL LETTER I WITH MACRON
+    0x012b: 0x008c,     #  LATIN SMALL LETTER I WITH MACRON
+    0x012e: 0x00bd,     #  LATIN CAPITAL LETTER I WITH OGONEK
+    0x012f: 0x00d4,     #  LATIN SMALL LETTER I WITH OGONEK
+    0x0136: 0x00e8,     #  LATIN CAPITAL LETTER K WITH CEDILLA
+    0x0137: 0x00e9,     #  LATIN SMALL LETTER K WITH CEDILLA
+    0x013b: 0x00ea,     #  LATIN CAPITAL LETTER L WITH CEDILLA
+    0x013c: 0x00eb,     #  LATIN SMALL LETTER L WITH CEDILLA
+    0x0141: 0x00ad,     #  LATIN CAPITAL LETTER L WITH STROKE
+    0x0142: 0x0088,     #  LATIN SMALL LETTER L WITH STROKE
+    0x0143: 0x00e3,     #  LATIN CAPITAL LETTER N WITH ACUTE
+    0x0144: 0x00e7,     #  LATIN SMALL LETTER N WITH ACUTE
+    0x0145: 0x00ee,     #  LATIN CAPITAL LETTER N WITH CEDILLA
+    0x0146: 0x00ec,     #  LATIN SMALL LETTER N WITH CEDILLA
+    0x014c: 0x00e2,     #  LATIN CAPITAL LETTER O WITH MACRON
+    0x014d: 0x0093,     #  LATIN SMALL LETTER O WITH MACRON
+    0x0156: 0x008a,     #  LATIN CAPITAL LETTER R WITH CEDILLA
+    0x0157: 0x008b,     #  LATIN SMALL LETTER R WITH CEDILLA
+    0x015a: 0x0097,     #  LATIN CAPITAL LETTER S WITH ACUTE
+    0x015b: 0x0098,     #  LATIN SMALL LETTER S WITH ACUTE
+    0x0160: 0x00be,     #  LATIN CAPITAL LETTER S WITH CARON
+    0x0161: 0x00d5,     #  LATIN SMALL LETTER S WITH CARON
+    0x016a: 0x00c7,     #  LATIN CAPITAL LETTER U WITH MACRON
+    0x016b: 0x00d7,     #  LATIN SMALL LETTER U WITH MACRON
+    0x0172: 0x00c6,     #  LATIN CAPITAL LETTER U WITH OGONEK
+    0x0173: 0x00d6,     #  LATIN SMALL LETTER U WITH OGONEK
+    0x0179: 0x008d,     #  LATIN CAPITAL LETTER Z WITH ACUTE
+    0x017a: 0x00a5,     #  LATIN SMALL LETTER Z WITH ACUTE
+    0x017b: 0x00a3,     #  LATIN CAPITAL LETTER Z WITH DOT ABOVE
+    0x017c: 0x00a4,     #  LATIN SMALL LETTER Z WITH DOT ABOVE
+    0x017d: 0x00cf,     #  LATIN CAPITAL LETTER Z WITH CARON
+    0x017e: 0x00d8,     #  LATIN SMALL LETTER Z WITH CARON
+    0x2019: 0x00ef,     #  RIGHT SINGLE QUOTATION MARK
+    0x201c: 0x00f2,     #  LEFT DOUBLE QUOTATION MARK
+    0x201d: 0x00a6,     #  RIGHT DOUBLE QUOTATION MARK
+    0x201e: 0x00f7,     #  DOUBLE LOW-9 QUOTATION MARK
+    0x2219: 0x00f9,     #  BULLET OPERATOR
+    0x2500: 0x00c4,     #  BOX DRAWINGS LIGHT HORIZONTAL
+    0x2502: 0x00b3,     #  BOX DRAWINGS LIGHT VERTICAL
+    0x250c: 0x00da,     #  BOX DRAWINGS LIGHT DOWN AND RIGHT
+    0x2510: 0x00bf,     #  BOX DRAWINGS LIGHT DOWN AND LEFT
+    0x2514: 0x00c0,     #  BOX DRAWINGS LIGHT UP AND RIGHT
+    0x2518: 0x00d9,     #  BOX DRAWINGS LIGHT UP AND LEFT
+    0x251c: 0x00c3,     #  BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+    0x2524: 0x00b4,     #  BOX DRAWINGS LIGHT VERTICAL AND LEFT
+    0x252c: 0x00c2,     #  BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+    0x2534: 0x00c1,     #  BOX DRAWINGS LIGHT UP AND HORIZONTAL
+    0x253c: 0x00c5,     #  BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+    0x2550: 0x00cd,     #  BOX DRAWINGS DOUBLE HORIZONTAL
+    0x2551: 0x00ba,     #  BOX DRAWINGS DOUBLE VERTICAL
+    0x2554: 0x00c9,     #  BOX DRAWINGS DOUBLE DOWN AND RIGHT
+    0x2557: 0x00bb,     #  BOX DRAWINGS DOUBLE DOWN AND LEFT
+    0x255a: 0x00c8,     #  BOX DRAWINGS DOUBLE UP AND RIGHT
+    0x255d: 0x00bc,     #  BOX DRAWINGS DOUBLE UP AND LEFT
+    0x2560: 0x00cc,     #  BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+    0x2563: 0x00b9,     #  BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+    0x2566: 0x00cb,     #  BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+    0x2569: 0x00ca,     #  BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+    0x256c: 0x00ce,     #  BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+    0x2580: 0x00df,     #  UPPER HALF BLOCK
+    0x2584: 0x00dc,     #  LOWER HALF BLOCK
+    0x2588: 0x00db,     #  FULL BLOCK
+    0x258c: 0x00dd,     #  LEFT HALF BLOCK
+    0x2590: 0x00de,     #  RIGHT HALF BLOCK
+    0x2591: 0x00b0,     #  LIGHT SHADE
+    0x2592: 0x00b1,     #  MEDIUM SHADE
+    0x2593: 0x00b2,     #  DARK SHADE
+    0x25a0: 0x00fe,     #  BLACK SQUARE
+}

Added: vendor/Python/current/Lib/encodings/cp850.py
===================================================================
--- vendor/Python/current/Lib/encodings/cp850.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/cp850.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,698 @@
+""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP850.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_map)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='cp850',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+### Decoding Map
+
+decoding_map = codecs.make_identity_dict(range(256))
+decoding_map.update({
+    0x0080: 0x00c7,     #  LATIN CAPITAL LETTER C WITH CEDILLA
+    0x0081: 0x00fc,     #  LATIN SMALL LETTER U WITH DIAERESIS
+    0x0082: 0x00e9,     #  LATIN SMALL LETTER E WITH ACUTE
+    0x0083: 0x00e2,     #  LATIN SMALL LETTER A WITH CIRCUMFLEX
+    0x0084: 0x00e4,     #  LATIN SMALL LETTER A WITH DIAERESIS
+    0x0085: 0x00e0,     #  LATIN SMALL LETTER A WITH GRAVE
+    0x0086: 0x00e5,     #  LATIN SMALL LETTER A WITH RING ABOVE
+    0x0087: 0x00e7,     #  LATIN SMALL LETTER C WITH CEDILLA
+    0x0088: 0x00ea,     #  LATIN SMALL LETTER E WITH CIRCUMFLEX
+    0x0089: 0x00eb,     #  LATIN SMALL LETTER E WITH DIAERESIS
+    0x008a: 0x00e8,     #  LATIN SMALL LETTER E WITH GRAVE
+    0x008b: 0x00ef,     #  LATIN SMALL LETTER I WITH DIAERESIS
+    0x008c: 0x00ee,     #  LATIN SMALL LETTER I WITH CIRCUMFLEX
+    0x008d: 0x00ec,     #  LATIN SMALL LETTER I WITH GRAVE
+    0x008e: 0x00c4,     #  LATIN CAPITAL LETTER A WITH DIAERESIS
+    0x008f: 0x00c5,     #  LATIN CAPITAL LETTER A WITH RING ABOVE
+    0x0090: 0x00c9,     #  LATIN CAPITAL LETTER E WITH ACUTE
+    0x0091: 0x00e6,     #  LATIN SMALL LIGATURE AE
+    0x0092: 0x00c6,     #  LATIN CAPITAL LIGATURE AE
+    0x0093: 0x00f4,     #  LATIN SMALL LETTER O WITH CIRCUMFLEX
+    0x0094: 0x00f6,     #  LATIN SMALL LETTER O WITH DIAERESIS
+    0x0095: 0x00f2,     #  LATIN SMALL LETTER O WITH GRAVE
+    0x0096: 0x00fb,     #  LATIN SMALL LETTER U WITH CIRCUMFLEX
+    0x0097: 0x00f9,     #  LATIN SMALL LETTER U WITH GRAVE
+    0x0098: 0x00ff,     #  LATIN SMALL LETTER Y WITH DIAERESIS
+    0x0099: 0x00d6,     #  LATIN CAPITAL LETTER O WITH DIAERESIS
+    0x009a: 0x00dc,     #  LATIN CAPITAL LETTER U WITH DIAERESIS
+    0x009b: 0x00f8,     #  LATIN SMALL LETTER O WITH STROKE
+    0x009c: 0x00a3,     #  POUND SIGN
+    0x009d: 0x00d8,     #  LATIN CAPITAL LETTER O WITH STROKE
+    0x009e: 0x00d7,     #  MULTIPLICATION SIGN
+    0x009f: 0x0192,     #  LATIN SMALL LETTER F WITH HOOK
+    0x00a0: 0x00e1,     #  LATIN SMALL LETTER A WITH ACUTE
+    0x00a1: 0x00ed,     #  LATIN SMALL LETTER I WITH ACUTE
+    0x00a2: 0x00f3,     #  LATIN SMALL LETTER O WITH ACUTE
+    0x00a3: 0x00fa,     #  LATIN SMALL LETTER U WITH ACUTE
+    0x00a4: 0x00f1,     #  LATIN SMALL LETTER N WITH TILDE
+    0x00a5: 0x00d1,     #  LATIN CAPITAL LETTER N WITH TILDE
+    0x00a6: 0x00aa,     #  FEMININE ORDINAL INDICATOR
+    0x00a7: 0x00ba,     #  MASCULINE ORDINAL INDICATOR
+    0x00a8: 0x00bf,     #  INVERTED QUESTION MARK
+    0x00a9: 0x00ae,     #  REGISTERED SIGN
+    0x00aa: 0x00ac,     #  NOT SIGN
+    0x00ab: 0x00bd,     #  VULGAR FRACTION ONE HALF
+    0x00ac: 0x00bc,     #  VULGAR FRACTION ONE QUARTER
+    0x00ad: 0x00a1,     #  INVERTED EXCLAMATION MARK
+    0x00ae: 0x00ab,     #  LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    0x00af: 0x00bb,     #  RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    0x00b0: 0x2591,     #  LIGHT SHADE
+    0x00b1: 0x2592,     #  MEDIUM SHADE
+    0x00b2: 0x2593,     #  DARK SHADE
+    0x00b3: 0x2502,     #  BOX DRAWINGS LIGHT VERTICAL
+    0x00b4: 0x2524,     #  BOX DRAWINGS LIGHT VERTICAL AND LEFT
+    0x00b5: 0x00c1,     #  LATIN CAPITAL LETTER A WITH ACUTE
+    0x00b6: 0x00c2,     #  LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+    0x00b7: 0x00c0,     #  LATIN CAPITAL LETTER A WITH GRAVE
+    0x00b8: 0x00a9,     #  COPYRIGHT SIGN
+    0x00b9: 0x2563,     #  BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+    0x00ba: 0x2551,     #  BOX DRAWINGS DOUBLE VERTICAL
+    0x00bb: 0x2557,     #  BOX DRAWINGS DOUBLE DOWN AND LEFT
+    0x00bc: 0x255d,     #  BOX DRAWINGS DOUBLE UP AND LEFT
+    0x00bd: 0x00a2,     #  CENT SIGN
+    0x00be: 0x00a5,     #  YEN SIGN
+    0x00bf: 0x2510,     #  BOX DRAWINGS LIGHT DOWN AND LEFT
+    0x00c0: 0x2514,     #  BOX DRAWINGS LIGHT UP AND RIGHT
+    0x00c1: 0x2534,     #  BOX DRAWINGS LIGHT UP AND HORIZONTAL
+    0x00c2: 0x252c,     #  BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+    0x00c3: 0x251c,     #  BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+    0x00c4: 0x2500,     #  BOX DRAWINGS LIGHT HORIZONTAL
+    0x00c5: 0x253c,     #  BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+    0x00c6: 0x00e3,     #  LATIN SMALL LETTER A WITH TILDE
+    0x00c7: 0x00c3,     #  LATIN CAPITAL LETTER A WITH TILDE
+    0x00c8: 0x255a,     #  BOX DRAWINGS DOUBLE UP AND RIGHT
+    0x00c9: 0x2554,     #  BOX DRAWINGS DOUBLE DOWN AND RIGHT
+    0x00ca: 0x2569,     #  BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+    0x00cb: 0x2566,     #  BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+    0x00cc: 0x2560,     #  BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+    0x00cd: 0x2550,     #  BOX DRAWINGS DOUBLE HORIZONTAL
+    0x00ce: 0x256c,     #  BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+    0x00cf: 0x00a4,     #  CURRENCY SIGN
+    0x00d0: 0x00f0,     #  LATIN SMALL LETTER ETH
+    0x00d1: 0x00d0,     #  LATIN CAPITAL LETTER ETH
+    0x00d2: 0x00ca,     #  LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+    0x00d3: 0x00cb,     #  LATIN CAPITAL LETTER E WITH DIAERESIS
+    0x00d4: 0x00c8,     #  LATIN CAPITAL LETTER E WITH GRAVE
+    0x00d5: 0x0131,     #  LATIN SMALL LETTER DOTLESS I
+    0x00d6: 0x00cd,     #  LATIN CAPITAL LETTER I WITH ACUTE
+    0x00d7: 0x00ce,     #  LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+    0x00d8: 0x00cf,     #  LATIN CAPITAL LETTER I WITH DIAERESIS
+    0x00d9: 0x2518,     #  BOX DRAWINGS LIGHT UP AND LEFT
+    0x00da: 0x250c,     #  BOX DRAWINGS LIGHT DOWN AND RIGHT
+    0x00db: 0x2588,     #  FULL BLOCK
+    0x00dc: 0x2584,     #  LOWER HALF BLOCK
+    0x00dd: 0x00a6,     #  BROKEN BAR
+    0x00de: 0x00cc,     #  LATIN CAPITAL LETTER I WITH GRAVE
+    0x00df: 0x2580,     #  UPPER HALF BLOCK
+    0x00e0: 0x00d3,     #  LATIN CAPITAL LETTER O WITH ACUTE
+    0x00e1: 0x00df,     #  LATIN SMALL LETTER SHARP S
+    0x00e2: 0x00d4,     #  LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+    0x00e3: 0x00d2,     #  LATIN CAPITAL LETTER O WITH GRAVE
+    0x00e4: 0x00f5,     #  LATIN SMALL LETTER O WITH TILDE
+    0x00e5: 0x00d5,     #  LATIN CAPITAL LETTER O WITH TILDE
+    0x00e6: 0x00b5,     #  MICRO SIGN
+    0x00e7: 0x00fe,     #  LATIN SMALL LETTER THORN
+    0x00e8: 0x00de,     #  LATIN CAPITAL LETTER THORN
+    0x00e9: 0x00da,     #  LATIN CAPITAL LETTER U WITH ACUTE
+    0x00ea: 0x00db,     #  LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+    0x00eb: 0x00d9,     #  LATIN CAPITAL LETTER U WITH GRAVE
+    0x00ec: 0x00fd,     #  LATIN SMALL LETTER Y WITH ACUTE
+    0x00ed: 0x00dd,     #  LATIN CAPITAL LETTER Y WITH ACUTE
+    0x00ee: 0x00af,     #  MACRON
+    0x00ef: 0x00b4,     #  ACUTE ACCENT
+    0x00f0: 0x00ad,     #  SOFT HYPHEN
+    0x00f1: 0x00b1,     #  PLUS-MINUS SIGN
+    0x00f2: 0x2017,     #  DOUBLE LOW LINE
+    0x00f3: 0x00be,     #  VULGAR FRACTION THREE QUARTERS
+    0x00f4: 0x00b6,     #  PILCROW SIGN
+    0x00f5: 0x00a7,     #  SECTION SIGN
+    0x00f6: 0x00f7,     #  DIVISION SIGN
+    0x00f7: 0x00b8,     #  CEDILLA
+    0x00f8: 0x00b0,     #  DEGREE SIGN
+    0x00f9: 0x00a8,     #  DIAERESIS
+    0x00fa: 0x00b7,     #  MIDDLE DOT
+    0x00fb: 0x00b9,     #  SUPERSCRIPT ONE
+    0x00fc: 0x00b3,     #  SUPERSCRIPT THREE
+    0x00fd: 0x00b2,     #  SUPERSCRIPT TWO
+    0x00fe: 0x25a0,     #  BLACK SQUARE
+    0x00ff: 0x00a0,     #  NO-BREAK SPACE
+})
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x0000 -> NULL
+    u'\x01'     #  0x0001 -> START OF HEADING
+    u'\x02'     #  0x0002 -> START OF TEXT
+    u'\x03'     #  0x0003 -> END OF TEXT
+    u'\x04'     #  0x0004 -> END OF TRANSMISSION
+    u'\x05'     #  0x0005 -> ENQUIRY
+    u'\x06'     #  0x0006 -> ACKNOWLEDGE
+    u'\x07'     #  0x0007 -> BELL
+    u'\x08'     #  0x0008 -> BACKSPACE
+    u'\t'       #  0x0009 -> HORIZONTAL TABULATION
+    u'\n'       #  0x000a -> LINE FEED
+    u'\x0b'     #  0x000b -> VERTICAL TABULATION
+    u'\x0c'     #  0x000c -> FORM FEED
+    u'\r'       #  0x000d -> CARRIAGE RETURN
+    u'\x0e'     #  0x000e -> SHIFT OUT
+    u'\x0f'     #  0x000f -> SHIFT IN
+    u'\x10'     #  0x0010 -> DATA LINK ESCAPE
+    u'\x11'     #  0x0011 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x0012 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x0013 -> DEVICE CONTROL THREE
+    u'\x14'     #  0x0014 -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x0015 -> NEGATIVE ACKNOWLEDGE
+    u'\x16'     #  0x0016 -> SYNCHRONOUS IDLE
+    u'\x17'     #  0x0017 -> END OF TRANSMISSION BLOCK
+    u'\x18'     #  0x0018 -> CANCEL
+    u'\x19'     #  0x0019 -> END OF MEDIUM
+    u'\x1a'     #  0x001a -> SUBSTITUTE
+    u'\x1b'     #  0x001b -> ESCAPE
+    u'\x1c'     #  0x001c -> FILE SEPARATOR
+    u'\x1d'     #  0x001d -> GROUP SEPARATOR
+    u'\x1e'     #  0x001e -> RECORD SEPARATOR
+    u'\x1f'     #  0x001f -> UNIT SEPARATOR
+    u' '        #  0x0020 -> SPACE
+    u'!'        #  0x0021 -> EXCLAMATION MARK
+    u'"'        #  0x0022 -> QUOTATION MARK
+    u'#'        #  0x0023 -> NUMBER SIGN
+    u'$'        #  0x0024 -> DOLLAR SIGN
+    u'%'        #  0x0025 -> PERCENT SIGN
+    u'&'        #  0x0026 -> AMPERSAND
+    u"'"        #  0x0027 -> APOSTROPHE
+    u'('        #  0x0028 -> LEFT PARENTHESIS
+    u')'        #  0x0029 -> RIGHT PARENTHESIS
+    u'*'        #  0x002a -> ASTERISK
+    u'+'        #  0x002b -> PLUS SIGN
+    u','        #  0x002c -> COMMA
+    u'-'        #  0x002d -> HYPHEN-MINUS
+    u'.'        #  0x002e -> FULL STOP
+    u'/'        #  0x002f -> SOLIDUS
+    u'0'        #  0x0030 -> DIGIT ZERO
+    u'1'        #  0x0031 -> DIGIT ONE
+    u'2'        #  0x0032 -> DIGIT TWO
+    u'3'        #  0x0033 -> DIGIT THREE
+    u'4'        #  0x0034 -> DIGIT FOUR
+    u'5'        #  0x0035 -> DIGIT FIVE
+    u'6'        #  0x0036 -> DIGIT SIX
+    u'7'        #  0x0037 -> DIGIT SEVEN
+    u'8'        #  0x0038 -> DIGIT EIGHT
+    u'9'        #  0x0039 -> DIGIT NINE
+    u':'        #  0x003a -> COLON
+    u';'        #  0x003b -> SEMICOLON
+    u'<'        #  0x003c -> LESS-THAN SIGN
+    u'='        #  0x003d -> EQUALS SIGN
+    u'>'        #  0x003e -> GREATER-THAN SIGN
+    u'?'        #  0x003f -> QUESTION MARK
+    u'@'        #  0x0040 -> COMMERCIAL AT
+    u'A'        #  0x0041 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x0042 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x0043 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x0044 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x0045 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x0046 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x0047 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x0048 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x0049 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x004a -> LATIN CAPITAL LETTER J
+    u'K'        #  0x004b -> LATIN CAPITAL LETTER K
+    u'L'        #  0x004c -> LATIN CAPITAL LETTER L
+    u'M'        #  0x004d -> LATIN CAPITAL LETTER M
+    u'N'        #  0x004e -> LATIN CAPITAL LETTER N
+    u'O'        #  0x004f -> LATIN CAPITAL LETTER O
+    u'P'        #  0x0050 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x0051 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x0052 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x0053 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x0054 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x0055 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x0056 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x0057 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x0058 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x0059 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x005a -> LATIN CAPITAL LETTER Z
+    u'['        #  0x005b -> LEFT SQUARE BRACKET
+    u'\\'       #  0x005c -> REVERSE SOLIDUS
+    u']'        #  0x005d -> RIGHT SQUARE BRACKET
+    u'^'        #  0x005e -> CIRCUMFLEX ACCENT
+    u'_'        #  0x005f -> LOW LINE
+    u'`'        #  0x0060 -> GRAVE ACCENT
+    u'a'        #  0x0061 -> LATIN SMALL LETTER A
+    u'b'        #  0x0062 -> LATIN SMALL LETTER B
+    u'c'        #  0x0063 -> LATIN SMALL LETTER C
+    u'd'        #  0x0064 -> LATIN SMALL LETTER D
+    u'e'        #  0x0065 -> LATIN SMALL LETTER E
+    u'f'        #  0x0066 -> LATIN SMALL LETTER F
+    u'g'        #  0x0067 -> LATIN SMALL LETTER G
+    u'h'        #  0x0068 -> LATIN SMALL LETTER H
+    u'i'        #  0x0069 -> LATIN SMALL LETTER I
+    u'j'        #  0x006a -> LATIN SMALL LETTER J
+    u'k'        #  0x006b -> LATIN SMALL LETTER K
+    u'l'        #  0x006c -> LATIN SMALL LETTER L
+    u'm'        #  0x006d -> LATIN SMALL LETTER M
+    u'n'        #  0x006e -> LATIN SMALL LETTER N
+    u'o'        #  0x006f -> LATIN SMALL LETTER O
+    u'p'        #  0x0070 -> LATIN SMALL LETTER P
+    u'q'        #  0x0071 -> LATIN SMALL LETTER Q
+    u'r'        #  0x0072 -> LATIN SMALL LETTER R
+    u's'        #  0x0073 -> LATIN SMALL LETTER S
+    u't'        #  0x0074 -> LATIN SMALL LETTER T
+    u'u'        #  0x0075 -> LATIN SMALL LETTER U
+    u'v'        #  0x0076 -> LATIN SMALL LETTER V
+    u'w'        #  0x0077 -> LATIN SMALL LETTER W
+    u'x'        #  0x0078 -> LATIN SMALL LETTER X
+    u'y'        #  0x0079 -> LATIN SMALL LETTER Y
+    u'z'        #  0x007a -> LATIN SMALL LETTER Z
+    u'{'        #  0x007b -> LEFT CURLY BRACKET
+    u'|'        #  0x007c -> VERTICAL LINE
+    u'}'        #  0x007d -> RIGHT CURLY BRACKET
+    u'~'        #  0x007e -> TILDE
+    u'\x7f'     #  0x007f -> DELETE
+    u'\xc7'     #  0x0080 -> LATIN CAPITAL LETTER C WITH CEDILLA
+    u'\xfc'     #  0x0081 -> LATIN SMALL LETTER U WITH DIAERESIS
+    u'\xe9'     #  0x0082 -> LATIN SMALL LETTER E WITH ACUTE
+    u'\xe2'     #  0x0083 -> LATIN SMALL LETTER A WITH CIRCUMFLEX
+    u'\xe4'     #  0x0084 -> LATIN SMALL LETTER A WITH DIAERESIS
+    u'\xe0'     #  0x0085 -> LATIN SMALL LETTER A WITH GRAVE
+    u'\xe5'     #  0x0086 -> LATIN SMALL LETTER A WITH RING ABOVE
+    u'\xe7'     #  0x0087 -> LATIN SMALL LETTER C WITH CEDILLA
+    u'\xea'     #  0x0088 -> LATIN SMALL LETTER E WITH CIRCUMFLEX
+    u'\xeb'     #  0x0089 -> LATIN SMALL LETTER E WITH DIAERESIS
+    u'\xe8'     #  0x008a -> LATIN SMALL LETTER E WITH GRAVE
+    u'\xef'     #  0x008b -> LATIN SMALL LETTER I WITH DIAERESIS
+    u'\xee'     #  0x008c -> LATIN SMALL LETTER I WITH CIRCUMFLEX
+    u'\xec'     #  0x008d -> LATIN SMALL LETTER I WITH GRAVE
+    u'\xc4'     #  0x008e -> LATIN CAPITAL LETTER A WITH DIAERESIS
+    u'\xc5'     #  0x008f -> LATIN CAPITAL LETTER A WITH RING ABOVE
+    u'\xc9'     #  0x0090 -> LATIN CAPITAL LETTER E WITH ACUTE
+    u'\xe6'     #  0x0091 -> LATIN SMALL LIGATURE AE
+    u'\xc6'     #  0x0092 -> LATIN CAPITAL LIGATURE AE
+    u'\xf4'     #  0x0093 -> LATIN SMALL LETTER O WITH CIRCUMFLEX
+    u'\xf6'     #  0x0094 -> LATIN SMALL LETTER O WITH DIAERESIS
+    u'\xf2'     #  0x0095 -> LATIN SMALL LETTER O WITH GRAVE
+    u'\xfb'     #  0x0096 -> LATIN SMALL LETTER U WITH CIRCUMFLEX
+    u'\xf9'     #  0x0097 -> LATIN SMALL LETTER U WITH GRAVE
+    u'\xff'     #  0x0098 -> LATIN SMALL LETTER Y WITH DIAERESIS
+    u'\xd6'     #  0x0099 -> LATIN CAPITAL LETTER O WITH DIAERESIS
+    u'\xdc'     #  0x009a -> LATIN CAPITAL LETTER U WITH DIAERESIS
+    u'\xf8'     #  0x009b -> LATIN SMALL LETTER O WITH STROKE
+    u'\xa3'     #  0x009c -> POUND SIGN
+    u'\xd8'     #  0x009d -> LATIN CAPITAL LETTER O WITH STROKE
+    u'\xd7'     #  0x009e -> MULTIPLICATION SIGN
+    u'\u0192'   #  0x009f -> LATIN SMALL LETTER F WITH HOOK
+    u'\xe1'     #  0x00a0 -> LATIN SMALL LETTER A WITH ACUTE
+    u'\xed'     #  0x00a1 -> LATIN SMALL LETTER I WITH ACUTE
+    u'\xf3'     #  0x00a2 -> LATIN SMALL LETTER O WITH ACUTE
+    u'\xfa'     #  0x00a3 -> LATIN SMALL LETTER U WITH ACUTE
+    u'\xf1'     #  0x00a4 -> LATIN SMALL LETTER N WITH TILDE
+    u'\xd1'     #  0x00a5 -> LATIN CAPITAL LETTER N WITH TILDE
+    u'\xaa'     #  0x00a6 -> FEMININE ORDINAL INDICATOR
+    u'\xba'     #  0x00a7 -> MASCULINE ORDINAL INDICATOR
+    u'\xbf'     #  0x00a8 -> INVERTED QUESTION MARK
+    u'\xae'     #  0x00a9 -> REGISTERED SIGN
+    u'\xac'     #  0x00aa -> NOT SIGN
+    u'\xbd'     #  0x00ab -> VULGAR FRACTION ONE HALF
+    u'\xbc'     #  0x00ac -> VULGAR FRACTION ONE QUARTER
+    u'\xa1'     #  0x00ad -> INVERTED EXCLAMATION MARK
+    u'\xab'     #  0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xbb'     #  0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\u2591'   #  0x00b0 -> LIGHT SHADE
+    u'\u2592'   #  0x00b1 -> MEDIUM SHADE
+    u'\u2593'   #  0x00b2 -> DARK SHADE
+    u'\u2502'   #  0x00b3 -> BOX DRAWINGS LIGHT VERTICAL
+    u'\u2524'   #  0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT
+    u'\xc1'     #  0x00b5 -> LATIN CAPITAL LETTER A WITH ACUTE
+    u'\xc2'     #  0x00b6 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+    u'\xc0'     #  0x00b7 -> LATIN CAPITAL LETTER A WITH GRAVE
+    u'\xa9'     #  0x00b8 -> COPYRIGHT SIGN
+    u'\u2563'   #  0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+    u'\u2551'   #  0x00ba -> BOX DRAWINGS DOUBLE VERTICAL
+    u'\u2557'   #  0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT
+    u'\u255d'   #  0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT
+    u'\xa2'     #  0x00bd -> CENT SIGN
+    u'\xa5'     #  0x00be -> YEN SIGN
+    u'\u2510'   #  0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT
+    u'\u2514'   #  0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT
+    u'\u2534'   #  0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL
+    u'\u252c'   #  0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+    u'\u251c'   #  0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+    u'\u2500'   #  0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL
+    u'\u253c'   #  0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+    u'\xe3'     #  0x00c6 -> LATIN SMALL LETTER A WITH TILDE
+    u'\xc3'     #  0x00c7 -> LATIN CAPITAL LETTER A WITH TILDE
+    u'\u255a'   #  0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT
+    u'\u2554'   #  0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT
+    u'\u2569'   #  0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+    u'\u2566'   #  0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+    u'\u2560'   #  0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+    u'\u2550'   #  0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL
+    u'\u256c'   #  0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+    u'\xa4'     #  0x00cf -> CURRENCY SIGN
+    u'\xf0'     #  0x00d0 -> LATIN SMALL LETTER ETH
+    u'\xd0'     #  0x00d1 -> LATIN CAPITAL LETTER ETH
+    u'\xca'     #  0x00d2 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+    u'\xcb'     #  0x00d3 -> LATIN CAPITAL LETTER E WITH DIAERESIS
+    u'\xc8'     #  0x00d4 -> LATIN CAPITAL LETTER E WITH GRAVE
+    u'\u0131'   #  0x00d5 -> LATIN SMALL LETTER DOTLESS I
+    u'\xcd'     #  0x00d6 -> LATIN CAPITAL LETTER I WITH ACUTE
+    u'\xce'     #  0x00d7 -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+    u'\xcf'     #  0x00d8 -> LATIN CAPITAL LETTER I WITH DIAERESIS
+    u'\u2518'   #  0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT
+    u'\u250c'   #  0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT
+    u'\u2588'   #  0x00db -> FULL BLOCK
+    u'\u2584'   #  0x00dc -> LOWER HALF BLOCK
+    u'\xa6'     #  0x00dd -> BROKEN BAR
+    u'\xcc'     #  0x00de -> LATIN CAPITAL LETTER I WITH GRAVE
+    u'\u2580'   #  0x00df -> UPPER HALF BLOCK
+    u'\xd3'     #  0x00e0 -> LATIN CAPITAL LETTER O WITH ACUTE
+    u'\xdf'     #  0x00e1 -> LATIN SMALL LETTER SHARP S
+    u'\xd4'     #  0x00e2 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+    u'\xd2'     #  0x00e3 -> LATIN CAPITAL LETTER O WITH GRAVE
+    u'\xf5'     #  0x00e4 -> LATIN SMALL LETTER O WITH TILDE
+    u'\xd5'     #  0x00e5 -> LATIN CAPITAL LETTER O WITH TILDE
+    u'\xb5'     #  0x00e6 -> MICRO SIGN
+    u'\xfe'     #  0x00e7 -> LATIN SMALL LETTER THORN
+    u'\xde'     #  0x00e8 -> LATIN CAPITAL LETTER THORN
+    u'\xda'     #  0x00e9 -> LATIN CAPITAL LETTER U WITH ACUTE
+    u'\xdb'     #  0x00ea -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+    u'\xd9'     #  0x00eb -> LATIN CAPITAL LETTER U WITH GRAVE
+    u'\xfd'     #  0x00ec -> LATIN SMALL LETTER Y WITH ACUTE
+    u'\xdd'     #  0x00ed -> LATIN CAPITAL LETTER Y WITH ACUTE
+    u'\xaf'     #  0x00ee -> MACRON
+    u'\xb4'     #  0x00ef -> ACUTE ACCENT
+    u'\xad'     #  0x00f0 -> SOFT HYPHEN
+    u'\xb1'     #  0x00f1 -> PLUS-MINUS SIGN
+    u'\u2017'   #  0x00f2 -> DOUBLE LOW LINE
+    u'\xbe'     #  0x00f3 -> VULGAR FRACTION THREE QUARTERS
+    u'\xb6'     #  0x00f4 -> PILCROW SIGN
+    u'\xa7'     #  0x00f5 -> SECTION SIGN
+    u'\xf7'     #  0x00f6 -> DIVISION SIGN
+    u'\xb8'     #  0x00f7 -> CEDILLA
+    u'\xb0'     #  0x00f8 -> DEGREE SIGN
+    u'\xa8'     #  0x00f9 -> DIAERESIS
+    u'\xb7'     #  0x00fa -> MIDDLE DOT
+    u'\xb9'     #  0x00fb -> SUPERSCRIPT ONE
+    u'\xb3'     #  0x00fc -> SUPERSCRIPT THREE
+    u'\xb2'     #  0x00fd -> SUPERSCRIPT TWO
+    u'\u25a0'   #  0x00fe -> BLACK SQUARE
+    u'\xa0'     #  0x00ff -> NO-BREAK SPACE
+)
+
+### Encoding Map
+
+encoding_map = {
+    0x0000: 0x0000,     #  NULL
+    0x0001: 0x0001,     #  START OF HEADING
+    0x0002: 0x0002,     #  START OF TEXT
+    0x0003: 0x0003,     #  END OF TEXT
+    0x0004: 0x0004,     #  END OF TRANSMISSION
+    0x0005: 0x0005,     #  ENQUIRY
+    0x0006: 0x0006,     #  ACKNOWLEDGE
+    0x0007: 0x0007,     #  BELL
+    0x0008: 0x0008,     #  BACKSPACE
+    0x0009: 0x0009,     #  HORIZONTAL TABULATION
+    0x000a: 0x000a,     #  LINE FEED
+    0x000b: 0x000b,     #  VERTICAL TABULATION
+    0x000c: 0x000c,     #  FORM FEED
+    0x000d: 0x000d,     #  CARRIAGE RETURN
+    0x000e: 0x000e,     #  SHIFT OUT
+    0x000f: 0x000f,     #  SHIFT IN
+    0x0010: 0x0010,     #  DATA LINK ESCAPE
+    0x0011: 0x0011,     #  DEVICE CONTROL ONE
+    0x0012: 0x0012,     #  DEVICE CONTROL TWO
+    0x0013: 0x0013,     #  DEVICE CONTROL THREE
+    0x0014: 0x0014,     #  DEVICE CONTROL FOUR
+    0x0015: 0x0015,     #  NEGATIVE ACKNOWLEDGE
+    0x0016: 0x0016,     #  SYNCHRONOUS IDLE
+    0x0017: 0x0017,     #  END OF TRANSMISSION BLOCK
+    0x0018: 0x0018,     #  CANCEL
+    0x0019: 0x0019,     #  END OF MEDIUM
+    0x001a: 0x001a,     #  SUBSTITUTE
+    0x001b: 0x001b,     #  ESCAPE
+    0x001c: 0x001c,     #  FILE SEPARATOR
+    0x001d: 0x001d,     #  GROUP SEPARATOR
+    0x001e: 0x001e,     #  RECORD SEPARATOR
+    0x001f: 0x001f,     #  UNIT SEPARATOR
+    0x0020: 0x0020,     #  SPACE
+    0x0021: 0x0021,     #  EXCLAMATION MARK
+    0x0022: 0x0022,     #  QUOTATION MARK
+    0x0023: 0x0023,     #  NUMBER SIGN
+    0x0024: 0x0024,     #  DOLLAR SIGN
+    0x0025: 0x0025,     #  PERCENT SIGN
+    0x0026: 0x0026,     #  AMPERSAND
+    0x0027: 0x0027,     #  APOSTROPHE
+    0x0028: 0x0028,     #  LEFT PARENTHESIS
+    0x0029: 0x0029,     #  RIGHT PARENTHESIS
+    0x002a: 0x002a,     #  ASTERISK
+    0x002b: 0x002b,     #  PLUS SIGN
+    0x002c: 0x002c,     #  COMMA
+    0x002d: 0x002d,     #  HYPHEN-MINUS
+    0x002e: 0x002e,     #  FULL STOP
+    0x002f: 0x002f,     #  SOLIDUS
+    0x0030: 0x0030,     #  DIGIT ZERO
+    0x0031: 0x0031,     #  DIGIT ONE
+    0x0032: 0x0032,     #  DIGIT TWO
+    0x0033: 0x0033,     #  DIGIT THREE
+    0x0034: 0x0034,     #  DIGIT FOUR
+    0x0035: 0x0035,     #  DIGIT FIVE
+    0x0036: 0x0036,     #  DIGIT SIX
+    0x0037: 0x0037,     #  DIGIT SEVEN
+    0x0038: 0x0038,     #  DIGIT EIGHT
+    0x0039: 0x0039,     #  DIGIT NINE
+    0x003a: 0x003a,     #  COLON
+    0x003b: 0x003b,     #  SEMICOLON
+    0x003c: 0x003c,     #  LESS-THAN SIGN
+    0x003d: 0x003d,     #  EQUALS SIGN
+    0x003e: 0x003e,     #  GREATER-THAN SIGN
+    0x003f: 0x003f,     #  QUESTION MARK
+    0x0040: 0x0040,     #  COMMERCIAL AT
+    0x0041: 0x0041,     #  LATIN CAPITAL LETTER A
+    0x0042: 0x0042,     #  LATIN CAPITAL LETTER B
+    0x0043: 0x0043,     #  LATIN CAPITAL LETTER C
+    0x0044: 0x0044,     #  LATIN CAPITAL LETTER D
+    0x0045: 0x0045,     #  LATIN CAPITAL LETTER E
+    0x0046: 0x0046,     #  LATIN CAPITAL LETTER F
+    0x0047: 0x0047,     #  LATIN CAPITAL LETTER G
+    0x0048: 0x0048,     #  LATIN CAPITAL LETTER H
+    0x0049: 0x0049,     #  LATIN CAPITAL LETTER I
+    0x004a: 0x004a,     #  LATIN CAPITAL LETTER J
+    0x004b: 0x004b,     #  LATIN CAPITAL LETTER K
+    0x004c: 0x004c,     #  LATIN CAPITAL LETTER L
+    0x004d: 0x004d,     #  LATIN CAPITAL LETTER M
+    0x004e: 0x004e,     #  LATIN CAPITAL LETTER N
+    0x004f: 0x004f,     #  LATIN CAPITAL LETTER O
+    0x0050: 0x0050,     #  LATIN CAPITAL LETTER P
+    0x0051: 0x0051,     #  LATIN CAPITAL LETTER Q
+    0x0052: 0x0052,     #  LATIN CAPITAL LETTER R
+    0x0053: 0x0053,     #  LATIN CAPITAL LETTER S
+    0x0054: 0x0054,     #  LATIN CAPITAL LETTER T
+    0x0055: 0x0055,     #  LATIN CAPITAL LETTER U
+    0x0056: 0x0056,     #  LATIN CAPITAL LETTER V
+    0x0057: 0x0057,     #  LATIN CAPITAL LETTER W
+    0x0058: 0x0058,     #  LATIN CAPITAL LETTER X
+    0x0059: 0x0059,     #  LATIN CAPITAL LETTER Y
+    0x005a: 0x005a,     #  LATIN CAPITAL LETTER Z
+    0x005b: 0x005b,     #  LEFT SQUARE BRACKET
+    0x005c: 0x005c,     #  REVERSE SOLIDUS
+    0x005d: 0x005d,     #  RIGHT SQUARE BRACKET
+    0x005e: 0x005e,     #  CIRCUMFLEX ACCENT
+    0x005f: 0x005f,     #  LOW LINE
+    0x0060: 0x0060,     #  GRAVE ACCENT
+    0x0061: 0x0061,     #  LATIN SMALL LETTER A
+    0x0062: 0x0062,     #  LATIN SMALL LETTER B
+    0x0063: 0x0063,     #  LATIN SMALL LETTER C
+    0x0064: 0x0064,     #  LATIN SMALL LETTER D
+    0x0065: 0x0065,     #  LATIN SMALL LETTER E
+    0x0066: 0x0066,     #  LATIN SMALL LETTER F
+    0x0067: 0x0067,     #  LATIN SMALL LETTER G
+    0x0068: 0x0068,     #  LATIN SMALL LETTER H
+    0x0069: 0x0069,     #  LATIN SMALL LETTER I
+    0x006a: 0x006a,     #  LATIN SMALL LETTER J
+    0x006b: 0x006b,     #  LATIN SMALL LETTER K
+    0x006c: 0x006c,     #  LATIN SMALL LETTER L
+    0x006d: 0x006d,     #  LATIN SMALL LETTER M
+    0x006e: 0x006e,     #  LATIN SMALL LETTER N
+    0x006f: 0x006f,     #  LATIN SMALL LETTER O
+    0x0070: 0x0070,     #  LATIN SMALL LETTER P
+    0x0071: 0x0071,     #  LATIN SMALL LETTER Q
+    0x0072: 0x0072,     #  LATIN SMALL LETTER R
+    0x0073: 0x0073,     #  LATIN SMALL LETTER S
+    0x0074: 0x0074,     #  LATIN SMALL LETTER T
+    0x0075: 0x0075,     #  LATIN SMALL LETTER U
+    0x0076: 0x0076,     #  LATIN SMALL LETTER V
+    0x0077: 0x0077,     #  LATIN SMALL LETTER W
+    0x0078: 0x0078,     #  LATIN SMALL LETTER X
+    0x0079: 0x0079,     #  LATIN SMALL LETTER Y
+    0x007a: 0x007a,     #  LATIN SMALL LETTER Z
+    0x007b: 0x007b,     #  LEFT CURLY BRACKET
+    0x007c: 0x007c,     #  VERTICAL LINE
+    0x007d: 0x007d,     #  RIGHT CURLY BRACKET
+    0x007e: 0x007e,     #  TILDE
+    0x007f: 0x007f,     #  DELETE
+    0x00a0: 0x00ff,     #  NO-BREAK SPACE
+    0x00a1: 0x00ad,     #  INVERTED EXCLAMATION MARK
+    0x00a2: 0x00bd,     #  CENT SIGN
+    0x00a3: 0x009c,     #  POUND SIGN
+    0x00a4: 0x00cf,     #  CURRENCY SIGN
+    0x00a5: 0x00be,     #  YEN SIGN
+    0x00a6: 0x00dd,     #  BROKEN BAR
+    0x00a7: 0x00f5,     #  SECTION SIGN
+    0x00a8: 0x00f9,     #  DIAERESIS
+    0x00a9: 0x00b8,     #  COPYRIGHT SIGN
+    0x00aa: 0x00a6,     #  FEMININE ORDINAL INDICATOR
+    0x00ab: 0x00ae,     #  LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    0x00ac: 0x00aa,     #  NOT SIGN
+    0x00ad: 0x00f0,     #  SOFT HYPHEN
+    0x00ae: 0x00a9,     #  REGISTERED SIGN
+    0x00af: 0x00ee,     #  MACRON
+    0x00b0: 0x00f8,     #  DEGREE SIGN
+    0x00b1: 0x00f1,     #  PLUS-MINUS SIGN
+    0x00b2: 0x00fd,     #  SUPERSCRIPT TWO
+    0x00b3: 0x00fc,     #  SUPERSCRIPT THREE
+    0x00b4: 0x00ef,     #  ACUTE ACCENT
+    0x00b5: 0x00e6,     #  MICRO SIGN
+    0x00b6: 0x00f4,     #  PILCROW SIGN
+    0x00b7: 0x00fa,     #  MIDDLE DOT
+    0x00b8: 0x00f7,     #  CEDILLA
+    0x00b9: 0x00fb,     #  SUPERSCRIPT ONE
+    0x00ba: 0x00a7,     #  MASCULINE ORDINAL INDICATOR
+    0x00bb: 0x00af,     #  RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    0x00bc: 0x00ac,     #  VULGAR FRACTION ONE QUARTER
+    0x00bd: 0x00ab,     #  VULGAR FRACTION ONE HALF
+    0x00be: 0x00f3,     #  VULGAR FRACTION THREE QUARTERS
+    0x00bf: 0x00a8,     #  INVERTED QUESTION MARK
+    0x00c0: 0x00b7,     #  LATIN CAPITAL LETTER A WITH GRAVE
+    0x00c1: 0x00b5,     #  LATIN CAPITAL LETTER A WITH ACUTE
+    0x00c2: 0x00b6,     #  LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+    0x00c3: 0x00c7,     #  LATIN CAPITAL LETTER A WITH TILDE
+    0x00c4: 0x008e,     #  LATIN CAPITAL LETTER A WITH DIAERESIS
+    0x00c5: 0x008f,     #  LATIN CAPITAL LETTER A WITH RING ABOVE
+    0x00c6: 0x0092,     #  LATIN CAPITAL LIGATURE AE
+    0x00c7: 0x0080,     #  LATIN CAPITAL LETTER C WITH CEDILLA
+    0x00c8: 0x00d4,     #  LATIN CAPITAL LETTER E WITH GRAVE
+    0x00c9: 0x0090,     #  LATIN CAPITAL LETTER E WITH ACUTE
+    0x00ca: 0x00d2,     #  LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+    0x00cb: 0x00d3,     #  LATIN CAPITAL LETTER E WITH DIAERESIS
+    0x00cc: 0x00de,     #  LATIN CAPITAL LETTER I WITH GRAVE
+    0x00cd: 0x00d6,     #  LATIN CAPITAL LETTER I WITH ACUTE
+    0x00ce: 0x00d7,     #  LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+    0x00cf: 0x00d8,     #  LATIN CAPITAL LETTER I WITH DIAERESIS
+    0x00d0: 0x00d1,     #  LATIN CAPITAL LETTER ETH
+    0x00d1: 0x00a5,     #  LATIN CAPITAL LETTER N WITH TILDE
+    0x00d2: 0x00e3,     #  LATIN CAPITAL LETTER O WITH GRAVE
+    0x00d3: 0x00e0,     #  LATIN CAPITAL LETTER O WITH ACUTE
+    0x00d4: 0x00e2,     #  LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+    0x00d5: 0x00e5,     #  LATIN CAPITAL LETTER O WITH TILDE
+    0x00d6: 0x0099,     #  LATIN CAPITAL LETTER O WITH DIAERESIS
+    0x00d7: 0x009e,     #  MULTIPLICATION SIGN
+    0x00d8: 0x009d,     #  LATIN CAPITAL LETTER O WITH STROKE
+    0x00d9: 0x00eb,     #  LATIN CAPITAL LETTER U WITH GRAVE
+    0x00da: 0x00e9,     #  LATIN CAPITAL LETTER U WITH ACUTE
+    0x00db: 0x00ea,     #  LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+    0x00dc: 0x009a,     #  LATIN CAPITAL LETTER U WITH DIAERESIS
+    0x00dd: 0x00ed,     #  LATIN CAPITAL LETTER Y WITH ACUTE
+    0x00de: 0x00e8,     #  LATIN CAPITAL LETTER THORN
+    0x00df: 0x00e1,     #  LATIN SMALL LETTER SHARP S
+    0x00e0: 0x0085,     #  LATIN SMALL LETTER A WITH GRAVE
+    0x00e1: 0x00a0,     #  LATIN SMALL LETTER A WITH ACUTE
+    0x00e2: 0x0083,     #  LATIN SMALL LETTER A WITH CIRCUMFLEX
+    0x00e3: 0x00c6,     #  LATIN SMALL LETTER A WITH TILDE
+    0x00e4: 0x0084,     #  LATIN SMALL LETTER A WITH DIAERESIS
+    0x00e5: 0x0086,     #  LATIN SMALL LETTER A WITH RING ABOVE
+    0x00e6: 0x0091,     #  LATIN SMALL LIGATURE AE
+    0x00e7: 0x0087,     #  LATIN SMALL LETTER C WITH CEDILLA
+    0x00e8: 0x008a,     #  LATIN SMALL LETTER E WITH GRAVE
+    0x00e9: 0x0082,     #  LATIN SMALL LETTER E WITH ACUTE
+    0x00ea: 0x0088,     #  LATIN SMALL LETTER E WITH CIRCUMFLEX
+    0x00eb: 0x0089,     #  LATIN SMALL LETTER E WITH DIAERESIS
+    0x00ec: 0x008d,     #  LATIN SMALL LETTER I WITH GRAVE
+    0x00ed: 0x00a1,     #  LATIN SMALL LETTER I WITH ACUTE
+    0x00ee: 0x008c,     #  LATIN SMALL LETTER I WITH CIRCUMFLEX
+    0x00ef: 0x008b,     #  LATIN SMALL LETTER I WITH DIAERESIS
+    0x00f0: 0x00d0,     #  LATIN SMALL LETTER ETH
+    0x00f1: 0x00a4,     #  LATIN SMALL LETTER N WITH TILDE
+    0x00f2: 0x0095,     #  LATIN SMALL LETTER O WITH GRAVE
+    0x00f3: 0x00a2,     #  LATIN SMALL LETTER O WITH ACUTE
+    0x00f4: 0x0093,     #  LATIN SMALL LETTER O WITH CIRCUMFLEX
+    0x00f5: 0x00e4,     #  LATIN SMALL LETTER O WITH TILDE
+    0x00f6: 0x0094,     #  LATIN SMALL LETTER O WITH DIAERESIS
+    0x00f7: 0x00f6,     #  DIVISION SIGN
+    0x00f8: 0x009b,     #  LATIN SMALL LETTER O WITH STROKE
+    0x00f9: 0x0097,     #  LATIN SMALL LETTER U WITH GRAVE
+    0x00fa: 0x00a3,     #  LATIN SMALL LETTER U WITH ACUTE
+    0x00fb: 0x0096,     #  LATIN SMALL LETTER U WITH CIRCUMFLEX
+    0x00fc: 0x0081,     #  LATIN SMALL LETTER U WITH DIAERESIS
+    0x00fd: 0x00ec,     #  LATIN SMALL LETTER Y WITH ACUTE
+    0x00fe: 0x00e7,     #  LATIN SMALL LETTER THORN
+    0x00ff: 0x0098,     #  LATIN SMALL LETTER Y WITH DIAERESIS
+    0x0131: 0x00d5,     #  LATIN SMALL LETTER DOTLESS I
+    0x0192: 0x009f,     #  LATIN SMALL LETTER F WITH HOOK
+    0x2017: 0x00f2,     #  DOUBLE LOW LINE
+    0x2500: 0x00c4,     #  BOX DRAWINGS LIGHT HORIZONTAL
+    0x2502: 0x00b3,     #  BOX DRAWINGS LIGHT VERTICAL
+    0x250c: 0x00da,     #  BOX DRAWINGS LIGHT DOWN AND RIGHT
+    0x2510: 0x00bf,     #  BOX DRAWINGS LIGHT DOWN AND LEFT
+    0x2514: 0x00c0,     #  BOX DRAWINGS LIGHT UP AND RIGHT
+    0x2518: 0x00d9,     #  BOX DRAWINGS LIGHT UP AND LEFT
+    0x251c: 0x00c3,     #  BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+    0x2524: 0x00b4,     #  BOX DRAWINGS LIGHT VERTICAL AND LEFT
+    0x252c: 0x00c2,     #  BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+    0x2534: 0x00c1,     #  BOX DRAWINGS LIGHT UP AND HORIZONTAL
+    0x253c: 0x00c5,     #  BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+    0x2550: 0x00cd,     #  BOX DRAWINGS DOUBLE HORIZONTAL
+    0x2551: 0x00ba,     #  BOX DRAWINGS DOUBLE VERTICAL
+    0x2554: 0x00c9,     #  BOX DRAWINGS DOUBLE DOWN AND RIGHT
+    0x2557: 0x00bb,     #  BOX DRAWINGS DOUBLE DOWN AND LEFT
+    0x255a: 0x00c8,     #  BOX DRAWINGS DOUBLE UP AND RIGHT
+    0x255d: 0x00bc,     #  BOX DRAWINGS DOUBLE UP AND LEFT
+    0x2560: 0x00cc,     #  BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+    0x2563: 0x00b9,     #  BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+    0x2566: 0x00cb,     #  BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+    0x2569: 0x00ca,     #  BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+    0x256c: 0x00ce,     #  BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+    0x2580: 0x00df,     #  UPPER HALF BLOCK
+    0x2584: 0x00dc,     #  LOWER HALF BLOCK
+    0x2588: 0x00db,     #  FULL BLOCK
+    0x2591: 0x00b0,     #  LIGHT SHADE
+    0x2592: 0x00b1,     #  MEDIUM SHADE
+    0x2593: 0x00b2,     #  DARK SHADE
+    0x25a0: 0x00fe,     #  BLACK SQUARE
+}

Added: vendor/Python/current/Lib/encodings/cp852.py
===================================================================
--- vendor/Python/current/Lib/encodings/cp852.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/cp852.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,698 @@
+""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP852.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_map)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='cp852',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+### Decoding Map
+
+decoding_map = codecs.make_identity_dict(range(256))
+decoding_map.update({
+    0x0080: 0x00c7,     #  LATIN CAPITAL LETTER C WITH CEDILLA
+    0x0081: 0x00fc,     #  LATIN SMALL LETTER U WITH DIAERESIS
+    0x0082: 0x00e9,     #  LATIN SMALL LETTER E WITH ACUTE
+    0x0083: 0x00e2,     #  LATIN SMALL LETTER A WITH CIRCUMFLEX
+    0x0084: 0x00e4,     #  LATIN SMALL LETTER A WITH DIAERESIS
+    0x0085: 0x016f,     #  LATIN SMALL LETTER U WITH RING ABOVE
+    0x0086: 0x0107,     #  LATIN SMALL LETTER C WITH ACUTE
+    0x0087: 0x00e7,     #  LATIN SMALL LETTER C WITH CEDILLA
+    0x0088: 0x0142,     #  LATIN SMALL LETTER L WITH STROKE
+    0x0089: 0x00eb,     #  LATIN SMALL LETTER E WITH DIAERESIS
+    0x008a: 0x0150,     #  LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
+    0x008b: 0x0151,     #  LATIN SMALL LETTER O WITH DOUBLE ACUTE
+    0x008c: 0x00ee,     #  LATIN SMALL LETTER I WITH CIRCUMFLEX
+    0x008d: 0x0179,     #  LATIN CAPITAL LETTER Z WITH ACUTE
+    0x008e: 0x00c4,     #  LATIN CAPITAL LETTER A WITH DIAERESIS
+    0x008f: 0x0106,     #  LATIN CAPITAL LETTER C WITH ACUTE
+    0x0090: 0x00c9,     #  LATIN CAPITAL LETTER E WITH ACUTE
+    0x0091: 0x0139,     #  LATIN CAPITAL LETTER L WITH ACUTE
+    0x0092: 0x013a,     #  LATIN SMALL LETTER L WITH ACUTE
+    0x0093: 0x00f4,     #  LATIN SMALL LETTER O WITH CIRCUMFLEX
+    0x0094: 0x00f6,     #  LATIN SMALL LETTER O WITH DIAERESIS
+    0x0095: 0x013d,     #  LATIN CAPITAL LETTER L WITH CARON
+    0x0096: 0x013e,     #  LATIN SMALL LETTER L WITH CARON
+    0x0097: 0x015a,     #  LATIN CAPITAL LETTER S WITH ACUTE
+    0x0098: 0x015b,     #  LATIN SMALL LETTER S WITH ACUTE
+    0x0099: 0x00d6,     #  LATIN CAPITAL LETTER O WITH DIAERESIS
+    0x009a: 0x00dc,     #  LATIN CAPITAL LETTER U WITH DIAERESIS
+    0x009b: 0x0164,     #  LATIN CAPITAL LETTER T WITH CARON
+    0x009c: 0x0165,     #  LATIN SMALL LETTER T WITH CARON
+    0x009d: 0x0141,     #  LATIN CAPITAL LETTER L WITH STROKE
+    0x009e: 0x00d7,     #  MULTIPLICATION SIGN
+    0x009f: 0x010d,     #  LATIN SMALL LETTER C WITH CARON
+    0x00a0: 0x00e1,     #  LATIN SMALL LETTER A WITH ACUTE
+    0x00a1: 0x00ed,     #  LATIN SMALL LETTER I WITH ACUTE
+    0x00a2: 0x00f3,     #  LATIN SMALL LETTER O WITH ACUTE
+    0x00a3: 0x00fa,     #  LATIN SMALL LETTER U WITH ACUTE
+    0x00a4: 0x0104,     #  LATIN CAPITAL LETTER A WITH OGONEK
+    0x00a5: 0x0105,     #  LATIN SMALL LETTER A WITH OGONEK
+    0x00a6: 0x017d,     #  LATIN CAPITAL LETTER Z WITH CARON
+    0x00a7: 0x017e,     #  LATIN SMALL LETTER Z WITH CARON
+    0x00a8: 0x0118,     #  LATIN CAPITAL LETTER E WITH OGONEK
+    0x00a9: 0x0119,     #  LATIN SMALL LETTER E WITH OGONEK
+    0x00aa: 0x00ac,     #  NOT SIGN
+    0x00ab: 0x017a,     #  LATIN SMALL LETTER Z WITH ACUTE
+    0x00ac: 0x010c,     #  LATIN CAPITAL LETTER C WITH CARON
+    0x00ad: 0x015f,     #  LATIN SMALL LETTER S WITH CEDILLA
+    0x00ae: 0x00ab,     #  LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    0x00af: 0x00bb,     #  RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    0x00b0: 0x2591,     #  LIGHT SHADE
+    0x00b1: 0x2592,     #  MEDIUM SHADE
+    0x00b2: 0x2593,     #  DARK SHADE
+    0x00b3: 0x2502,     #  BOX DRAWINGS LIGHT VERTICAL
+    0x00b4: 0x2524,     #  BOX DRAWINGS LIGHT VERTICAL AND LEFT
+    0x00b5: 0x00c1,     #  LATIN CAPITAL LETTER A WITH ACUTE
+    0x00b6: 0x00c2,     #  LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+    0x00b7: 0x011a,     #  LATIN CAPITAL LETTER E WITH CARON
+    0x00b8: 0x015e,     #  LATIN CAPITAL LETTER S WITH CEDILLA
+    0x00b9: 0x2563,     #  BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+    0x00ba: 0x2551,     #  BOX DRAWINGS DOUBLE VERTICAL
+    0x00bb: 0x2557,     #  BOX DRAWINGS DOUBLE DOWN AND LEFT
+    0x00bc: 0x255d,     #  BOX DRAWINGS DOUBLE UP AND LEFT
+    0x00bd: 0x017b,     #  LATIN CAPITAL LETTER Z WITH DOT ABOVE
+    0x00be: 0x017c,     #  LATIN SMALL LETTER Z WITH DOT ABOVE
+    0x00bf: 0x2510,     #  BOX DRAWINGS LIGHT DOWN AND LEFT
+    0x00c0: 0x2514,     #  BOX DRAWINGS LIGHT UP AND RIGHT
+    0x00c1: 0x2534,     #  BOX DRAWINGS LIGHT UP AND HORIZONTAL
+    0x00c2: 0x252c,     #  BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+    0x00c3: 0x251c,     #  BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+    0x00c4: 0x2500,     #  BOX DRAWINGS LIGHT HORIZONTAL
+    0x00c5: 0x253c,     #  BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+    0x00c6: 0x0102,     #  LATIN CAPITAL LETTER A WITH BREVE
+    0x00c7: 0x0103,     #  LATIN SMALL LETTER A WITH BREVE
+    0x00c8: 0x255a,     #  BOX DRAWINGS DOUBLE UP AND RIGHT
+    0x00c9: 0x2554,     #  BOX DRAWINGS DOUBLE DOWN AND RIGHT
+    0x00ca: 0x2569,     #  BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+    0x00cb: 0x2566,     #  BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+    0x00cc: 0x2560,     #  BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+    0x00cd: 0x2550,     #  BOX DRAWINGS DOUBLE HORIZONTAL
+    0x00ce: 0x256c,     #  BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+    0x00cf: 0x00a4,     #  CURRENCY SIGN
+    0x00d0: 0x0111,     #  LATIN SMALL LETTER D WITH STROKE
+    0x00d1: 0x0110,     #  LATIN CAPITAL LETTER D WITH STROKE
+    0x00d2: 0x010e,     #  LATIN CAPITAL LETTER D WITH CARON
+    0x00d3: 0x00cb,     #  LATIN CAPITAL LETTER E WITH DIAERESIS
+    0x00d4: 0x010f,     #  LATIN SMALL LETTER D WITH CARON
+    0x00d5: 0x0147,     #  LATIN CAPITAL LETTER N WITH CARON
+    0x00d6: 0x00cd,     #  LATIN CAPITAL LETTER I WITH ACUTE
+    0x00d7: 0x00ce,     #  LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+    0x00d8: 0x011b,     #  LATIN SMALL LETTER E WITH CARON
+    0x00d9: 0x2518,     #  BOX DRAWINGS LIGHT UP AND LEFT
+    0x00da: 0x250c,     #  BOX DRAWINGS LIGHT DOWN AND RIGHT
+    0x00db: 0x2588,     #  FULL BLOCK
+    0x00dc: 0x2584,     #  LOWER HALF BLOCK
+    0x00dd: 0x0162,     #  LATIN CAPITAL LETTER T WITH CEDILLA
+    0x00de: 0x016e,     #  LATIN CAPITAL LETTER U WITH RING ABOVE
+    0x00df: 0x2580,     #  UPPER HALF BLOCK
+    0x00e0: 0x00d3,     #  LATIN CAPITAL LETTER O WITH ACUTE
+    0x00e1: 0x00df,     #  LATIN SMALL LETTER SHARP S
+    0x00e2: 0x00d4,     #  LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+    0x00e3: 0x0143,     #  LATIN CAPITAL LETTER N WITH ACUTE
+    0x00e4: 0x0144,     #  LATIN SMALL LETTER N WITH ACUTE
+    0x00e5: 0x0148,     #  LATIN SMALL LETTER N WITH CARON
+    0x00e6: 0x0160,     #  LATIN CAPITAL LETTER S WITH CARON
+    0x00e7: 0x0161,     #  LATIN SMALL LETTER S WITH CARON
+    0x00e8: 0x0154,     #  LATIN CAPITAL LETTER R WITH ACUTE
+    0x00e9: 0x00da,     #  LATIN CAPITAL LETTER U WITH ACUTE
+    0x00ea: 0x0155,     #  LATIN SMALL LETTER R WITH ACUTE
+    0x00eb: 0x0170,     #  LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
+    0x00ec: 0x00fd,     #  LATIN SMALL LETTER Y WITH ACUTE
+    0x00ed: 0x00dd,     #  LATIN CAPITAL LETTER Y WITH ACUTE
+    0x00ee: 0x0163,     #  LATIN SMALL LETTER T WITH CEDILLA
+    0x00ef: 0x00b4,     #  ACUTE ACCENT
+    0x00f0: 0x00ad,     #  SOFT HYPHEN
+    0x00f1: 0x02dd,     #  DOUBLE ACUTE ACCENT
+    0x00f2: 0x02db,     #  OGONEK
+    0x00f3: 0x02c7,     #  CARON
+    0x00f4: 0x02d8,     #  BREVE
+    0x00f5: 0x00a7,     #  SECTION SIGN
+    0x00f6: 0x00f7,     #  DIVISION SIGN
+    0x00f7: 0x00b8,     #  CEDILLA
+    0x00f8: 0x00b0,     #  DEGREE SIGN
+    0x00f9: 0x00a8,     #  DIAERESIS
+    0x00fa: 0x02d9,     #  DOT ABOVE
+    0x00fb: 0x0171,     #  LATIN SMALL LETTER U WITH DOUBLE ACUTE
+    0x00fc: 0x0158,     #  LATIN CAPITAL LETTER R WITH CARON
+    0x00fd: 0x0159,     #  LATIN SMALL LETTER R WITH CARON
+    0x00fe: 0x25a0,     #  BLACK SQUARE
+    0x00ff: 0x00a0,     #  NO-BREAK SPACE
+})
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x0000 -> NULL
+    u'\x01'     #  0x0001 -> START OF HEADING
+    u'\x02'     #  0x0002 -> START OF TEXT
+    u'\x03'     #  0x0003 -> END OF TEXT
+    u'\x04'     #  0x0004 -> END OF TRANSMISSION
+    u'\x05'     #  0x0005 -> ENQUIRY
+    u'\x06'     #  0x0006 -> ACKNOWLEDGE
+    u'\x07'     #  0x0007 -> BELL
+    u'\x08'     #  0x0008 -> BACKSPACE
+    u'\t'       #  0x0009 -> HORIZONTAL TABULATION
+    u'\n'       #  0x000a -> LINE FEED
+    u'\x0b'     #  0x000b -> VERTICAL TABULATION
+    u'\x0c'     #  0x000c -> FORM FEED
+    u'\r'       #  0x000d -> CARRIAGE RETURN
+    u'\x0e'     #  0x000e -> SHIFT OUT
+    u'\x0f'     #  0x000f -> SHIFT IN
+    u'\x10'     #  0x0010 -> DATA LINK ESCAPE
+    u'\x11'     #  0x0011 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x0012 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x0013 -> DEVICE CONTROL THREE
+    u'\x14'     #  0x0014 -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x0015 -> NEGATIVE ACKNOWLEDGE
+    u'\x16'     #  0x0016 -> SYNCHRONOUS IDLE
+    u'\x17'     #  0x0017 -> END OF TRANSMISSION BLOCK
+    u'\x18'     #  0x0018 -> CANCEL
+    u'\x19'     #  0x0019 -> END OF MEDIUM
+    u'\x1a'     #  0x001a -> SUBSTITUTE
+    u'\x1b'     #  0x001b -> ESCAPE
+    u'\x1c'     #  0x001c -> FILE SEPARATOR
+    u'\x1d'     #  0x001d -> GROUP SEPARATOR
+    u'\x1e'     #  0x001e -> RECORD SEPARATOR
+    u'\x1f'     #  0x001f -> UNIT SEPARATOR
+    u' '        #  0x0020 -> SPACE
+    u'!'        #  0x0021 -> EXCLAMATION MARK
+    u'"'        #  0x0022 -> QUOTATION MARK
+    u'#'        #  0x0023 -> NUMBER SIGN
+    u'$'        #  0x0024 -> DOLLAR SIGN
+    u'%'        #  0x0025 -> PERCENT SIGN
+    u'&'        #  0x0026 -> AMPERSAND
+    u"'"        #  0x0027 -> APOSTROPHE
+    u'('        #  0x0028 -> LEFT PARENTHESIS
+    u')'        #  0x0029 -> RIGHT PARENTHESIS
+    u'*'        #  0x002a -> ASTERISK
+    u'+'        #  0x002b -> PLUS SIGN
+    u','        #  0x002c -> COMMA
+    u'-'        #  0x002d -> HYPHEN-MINUS
+    u'.'        #  0x002e -> FULL STOP
+    u'/'        #  0x002f -> SOLIDUS
+    u'0'        #  0x0030 -> DIGIT ZERO
+    u'1'        #  0x0031 -> DIGIT ONE
+    u'2'        #  0x0032 -> DIGIT TWO
+    u'3'        #  0x0033 -> DIGIT THREE
+    u'4'        #  0x0034 -> DIGIT FOUR
+    u'5'        #  0x0035 -> DIGIT FIVE
+    u'6'        #  0x0036 -> DIGIT SIX
+    u'7'        #  0x0037 -> DIGIT SEVEN
+    u'8'        #  0x0038 -> DIGIT EIGHT
+    u'9'        #  0x0039 -> DIGIT NINE
+    u':'        #  0x003a -> COLON
+    u';'        #  0x003b -> SEMICOLON
+    u'<'        #  0x003c -> LESS-THAN SIGN
+    u'='        #  0x003d -> EQUALS SIGN
+    u'>'        #  0x003e -> GREATER-THAN SIGN
+    u'?'        #  0x003f -> QUESTION MARK
+    u'@'        #  0x0040 -> COMMERCIAL AT
+    u'A'        #  0x0041 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x0042 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x0043 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x0044 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x0045 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x0046 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x0047 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x0048 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x0049 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x004a -> LATIN CAPITAL LETTER J
+    u'K'        #  0x004b -> LATIN CAPITAL LETTER K
+    u'L'        #  0x004c -> LATIN CAPITAL LETTER L
+    u'M'        #  0x004d -> LATIN CAPITAL LETTER M
+    u'N'        #  0x004e -> LATIN CAPITAL LETTER N
+    u'O'        #  0x004f -> LATIN CAPITAL LETTER O
+    u'P'        #  0x0050 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x0051 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x0052 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x0053 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x0054 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x0055 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x0056 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x0057 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x0058 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x0059 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x005a -> LATIN CAPITAL LETTER Z
+    u'['        #  0x005b -> LEFT SQUARE BRACKET
+    u'\\'       #  0x005c -> REVERSE SOLIDUS
+    u']'        #  0x005d -> RIGHT SQUARE BRACKET
+    u'^'        #  0x005e -> CIRCUMFLEX ACCENT
+    u'_'        #  0x005f -> LOW LINE
+    u'`'        #  0x0060 -> GRAVE ACCENT
+    u'a'        #  0x0061 -> LATIN SMALL LETTER A
+    u'b'        #  0x0062 -> LATIN SMALL LETTER B
+    u'c'        #  0x0063 -> LATIN SMALL LETTER C
+    u'd'        #  0x0064 -> LATIN SMALL LETTER D
+    u'e'        #  0x0065 -> LATIN SMALL LETTER E
+    u'f'        #  0x0066 -> LATIN SMALL LETTER F
+    u'g'        #  0x0067 -> LATIN SMALL LETTER G
+    u'h'        #  0x0068 -> LATIN SMALL LETTER H
+    u'i'        #  0x0069 -> LATIN SMALL LETTER I
+    u'j'        #  0x006a -> LATIN SMALL LETTER J
+    u'k'        #  0x006b -> LATIN SMALL LETTER K
+    u'l'        #  0x006c -> LATIN SMALL LETTER L
+    u'm'        #  0x006d -> LATIN SMALL LETTER M
+    u'n'        #  0x006e -> LATIN SMALL LETTER N
+    u'o'        #  0x006f -> LATIN SMALL LETTER O
+    u'p'        #  0x0070 -> LATIN SMALL LETTER P
+    u'q'        #  0x0071 -> LATIN SMALL LETTER Q
+    u'r'        #  0x0072 -> LATIN SMALL LETTER R
+    u's'        #  0x0073 -> LATIN SMALL LETTER S
+    u't'        #  0x0074 -> LATIN SMALL LETTER T
+    u'u'        #  0x0075 -> LATIN SMALL LETTER U
+    u'v'        #  0x0076 -> LATIN SMALL LETTER V
+    u'w'        #  0x0077 -> LATIN SMALL LETTER W
+    u'x'        #  0x0078 -> LATIN SMALL LETTER X
+    u'y'        #  0x0079 -> LATIN SMALL LETTER Y
+    u'z'        #  0x007a -> LATIN SMALL LETTER Z
+    u'{'        #  0x007b -> LEFT CURLY BRACKET
+    u'|'        #  0x007c -> VERTICAL LINE
+    u'}'        #  0x007d -> RIGHT CURLY BRACKET
+    u'~'        #  0x007e -> TILDE
+    u'\x7f'     #  0x007f -> DELETE
+    u'\xc7'     #  0x0080 -> LATIN CAPITAL LETTER C WITH CEDILLA
+    u'\xfc'     #  0x0081 -> LATIN SMALL LETTER U WITH DIAERESIS
+    u'\xe9'     #  0x0082 -> LATIN SMALL LETTER E WITH ACUTE
+    u'\xe2'     #  0x0083 -> LATIN SMALL LETTER A WITH CIRCUMFLEX
+    u'\xe4'     #  0x0084 -> LATIN SMALL LETTER A WITH DIAERESIS
+    u'\u016f'   #  0x0085 -> LATIN SMALL LETTER U WITH RING ABOVE
+    u'\u0107'   #  0x0086 -> LATIN SMALL LETTER C WITH ACUTE
+    u'\xe7'     #  0x0087 -> LATIN SMALL LETTER C WITH CEDILLA
+    u'\u0142'   #  0x0088 -> LATIN SMALL LETTER L WITH STROKE
+    u'\xeb'     #  0x0089 -> LATIN SMALL LETTER E WITH DIAERESIS
+    u'\u0150'   #  0x008a -> LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
+    u'\u0151'   #  0x008b -> LATIN SMALL LETTER O WITH DOUBLE ACUTE
+    u'\xee'     #  0x008c -> LATIN SMALL LETTER I WITH CIRCUMFLEX
+    u'\u0179'   #  0x008d -> LATIN CAPITAL LETTER Z WITH ACUTE
+    u'\xc4'     #  0x008e -> LATIN CAPITAL LETTER A WITH DIAERESIS
+    u'\u0106'   #  0x008f -> LATIN CAPITAL LETTER C WITH ACUTE
+    u'\xc9'     #  0x0090 -> LATIN CAPITAL LETTER E WITH ACUTE
+    u'\u0139'   #  0x0091 -> LATIN CAPITAL LETTER L WITH ACUTE
+    u'\u013a'   #  0x0092 -> LATIN SMALL LETTER L WITH ACUTE
+    u'\xf4'     #  0x0093 -> LATIN SMALL LETTER O WITH CIRCUMFLEX
+    u'\xf6'     #  0x0094 -> LATIN SMALL LETTER O WITH DIAERESIS
+    u'\u013d'   #  0x0095 -> LATIN CAPITAL LETTER L WITH CARON
+    u'\u013e'   #  0x0096 -> LATIN SMALL LETTER L WITH CARON
+    u'\u015a'   #  0x0097 -> LATIN CAPITAL LETTER S WITH ACUTE
+    u'\u015b'   #  0x0098 -> LATIN SMALL LETTER S WITH ACUTE
+    u'\xd6'     #  0x0099 -> LATIN CAPITAL LETTER O WITH DIAERESIS
+    u'\xdc'     #  0x009a -> LATIN CAPITAL LETTER U WITH DIAERESIS
+    u'\u0164'   #  0x009b -> LATIN CAPITAL LETTER T WITH CARON
+    u'\u0165'   #  0x009c -> LATIN SMALL LETTER T WITH CARON
+    u'\u0141'   #  0x009d -> LATIN CAPITAL LETTER L WITH STROKE
+    u'\xd7'     #  0x009e -> MULTIPLICATION SIGN
+    u'\u010d'   #  0x009f -> LATIN SMALL LETTER C WITH CARON
+    u'\xe1'     #  0x00a0 -> LATIN SMALL LETTER A WITH ACUTE
+    u'\xed'     #  0x00a1 -> LATIN SMALL LETTER I WITH ACUTE
+    u'\xf3'     #  0x00a2 -> LATIN SMALL LETTER O WITH ACUTE
+    u'\xfa'     #  0x00a3 -> LATIN SMALL LETTER U WITH ACUTE
+    u'\u0104'   #  0x00a4 -> LATIN CAPITAL LETTER A WITH OGONEK
+    u'\u0105'   #  0x00a5 -> LATIN SMALL LETTER A WITH OGONEK
+    u'\u017d'   #  0x00a6 -> LATIN CAPITAL LETTER Z WITH CARON
+    u'\u017e'   #  0x00a7 -> LATIN SMALL LETTER Z WITH CARON
+    u'\u0118'   #  0x00a8 -> LATIN CAPITAL LETTER E WITH OGONEK
+    u'\u0119'   #  0x00a9 -> LATIN SMALL LETTER E WITH OGONEK
+    u'\xac'     #  0x00aa -> NOT SIGN
+    u'\u017a'   #  0x00ab -> LATIN SMALL LETTER Z WITH ACUTE
+    u'\u010c'   #  0x00ac -> LATIN CAPITAL LETTER C WITH CARON
+    u'\u015f'   #  0x00ad -> LATIN SMALL LETTER S WITH CEDILLA
+    u'\xab'     #  0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xbb'     #  0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\u2591'   #  0x00b0 -> LIGHT SHADE
+    u'\u2592'   #  0x00b1 -> MEDIUM SHADE
+    u'\u2593'   #  0x00b2 -> DARK SHADE
+    u'\u2502'   #  0x00b3 -> BOX DRAWINGS LIGHT VERTICAL
+    u'\u2524'   #  0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT
+    u'\xc1'     #  0x00b5 -> LATIN CAPITAL LETTER A WITH ACUTE
+    u'\xc2'     #  0x00b6 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+    u'\u011a'   #  0x00b7 -> LATIN CAPITAL LETTER E WITH CARON
+    u'\u015e'   #  0x00b8 -> LATIN CAPITAL LETTER S WITH CEDILLA
+    u'\u2563'   #  0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+    u'\u2551'   #  0x00ba -> BOX DRAWINGS DOUBLE VERTICAL
+    u'\u2557'   #  0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT
+    u'\u255d'   #  0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT
+    u'\u017b'   #  0x00bd -> LATIN CAPITAL LETTER Z WITH DOT ABOVE
+    u'\u017c'   #  0x00be -> LATIN SMALL LETTER Z WITH DOT ABOVE
+    u'\u2510'   #  0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT
+    u'\u2514'   #  0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT
+    u'\u2534'   #  0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL
+    u'\u252c'   #  0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+    u'\u251c'   #  0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+    u'\u2500'   #  0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL
+    u'\u253c'   #  0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+    u'\u0102'   #  0x00c6 -> LATIN CAPITAL LETTER A WITH BREVE
+    u'\u0103'   #  0x00c7 -> LATIN SMALL LETTER A WITH BREVE
+    u'\u255a'   #  0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT
+    u'\u2554'   #  0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT
+    u'\u2569'   #  0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+    u'\u2566'   #  0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+    u'\u2560'   #  0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+    u'\u2550'   #  0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL
+    u'\u256c'   #  0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+    u'\xa4'     #  0x00cf -> CURRENCY SIGN
+    u'\u0111'   #  0x00d0 -> LATIN SMALL LETTER D WITH STROKE
+    u'\u0110'   #  0x00d1 -> LATIN CAPITAL LETTER D WITH STROKE
+    u'\u010e'   #  0x00d2 -> LATIN CAPITAL LETTER D WITH CARON
+    u'\xcb'     #  0x00d3 -> LATIN CAPITAL LETTER E WITH DIAERESIS
+    u'\u010f'   #  0x00d4 -> LATIN SMALL LETTER D WITH CARON
+    u'\u0147'   #  0x00d5 -> LATIN CAPITAL LETTER N WITH CARON
+    u'\xcd'     #  0x00d6 -> LATIN CAPITAL LETTER I WITH ACUTE
+    u'\xce'     #  0x00d7 -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+    u'\u011b'   #  0x00d8 -> LATIN SMALL LETTER E WITH CARON
+    u'\u2518'   #  0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT
+    u'\u250c'   #  0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT
+    u'\u2588'   #  0x00db -> FULL BLOCK
+    u'\u2584'   #  0x00dc -> LOWER HALF BLOCK
+    u'\u0162'   #  0x00dd -> LATIN CAPITAL LETTER T WITH CEDILLA
+    u'\u016e'   #  0x00de -> LATIN CAPITAL LETTER U WITH RING ABOVE
+    u'\u2580'   #  0x00df -> UPPER HALF BLOCK
+    u'\xd3'     #  0x00e0 -> LATIN CAPITAL LETTER O WITH ACUTE
+    u'\xdf'     #  0x00e1 -> LATIN SMALL LETTER SHARP S
+    u'\xd4'     #  0x00e2 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+    u'\u0143'   #  0x00e3 -> LATIN CAPITAL LETTER N WITH ACUTE
+    u'\u0144'   #  0x00e4 -> LATIN SMALL LETTER N WITH ACUTE
+    u'\u0148'   #  0x00e5 -> LATIN SMALL LETTER N WITH CARON
+    u'\u0160'   #  0x00e6 -> LATIN CAPITAL LETTER S WITH CARON
+    u'\u0161'   #  0x00e7 -> LATIN SMALL LETTER S WITH CARON
+    u'\u0154'   #  0x00e8 -> LATIN CAPITAL LETTER R WITH ACUTE
+    u'\xda'     #  0x00e9 -> LATIN CAPITAL LETTER U WITH ACUTE
+    u'\u0155'   #  0x00ea -> LATIN SMALL LETTER R WITH ACUTE
+    u'\u0170'   #  0x00eb -> LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
+    u'\xfd'     #  0x00ec -> LATIN SMALL LETTER Y WITH ACUTE
+    u'\xdd'     #  0x00ed -> LATIN CAPITAL LETTER Y WITH ACUTE
+    u'\u0163'   #  0x00ee -> LATIN SMALL LETTER T WITH CEDILLA
+    u'\xb4'     #  0x00ef -> ACUTE ACCENT
+    u'\xad'     #  0x00f0 -> SOFT HYPHEN
+    u'\u02dd'   #  0x00f1 -> DOUBLE ACUTE ACCENT
+    u'\u02db'   #  0x00f2 -> OGONEK
+    u'\u02c7'   #  0x00f3 -> CARON
+    u'\u02d8'   #  0x00f4 -> BREVE
+    u'\xa7'     #  0x00f5 -> SECTION SIGN
+    u'\xf7'     #  0x00f6 -> DIVISION SIGN
+    u'\xb8'     #  0x00f7 -> CEDILLA
+    u'\xb0'     #  0x00f8 -> DEGREE SIGN
+    u'\xa8'     #  0x00f9 -> DIAERESIS
+    u'\u02d9'   #  0x00fa -> DOT ABOVE
+    u'\u0171'   #  0x00fb -> LATIN SMALL LETTER U WITH DOUBLE ACUTE
+    u'\u0158'   #  0x00fc -> LATIN CAPITAL LETTER R WITH CARON
+    u'\u0159'   #  0x00fd -> LATIN SMALL LETTER R WITH CARON
+    u'\u25a0'   #  0x00fe -> BLACK SQUARE
+    u'\xa0'     #  0x00ff -> NO-BREAK SPACE
+)
+
+### Encoding Map
+
+encoding_map = {
+    0x0000: 0x0000,     #  NULL
+    0x0001: 0x0001,     #  START OF HEADING
+    0x0002: 0x0002,     #  START OF TEXT
+    0x0003: 0x0003,     #  END OF TEXT
+    0x0004: 0x0004,     #  END OF TRANSMISSION
+    0x0005: 0x0005,     #  ENQUIRY
+    0x0006: 0x0006,     #  ACKNOWLEDGE
+    0x0007: 0x0007,     #  BELL
+    0x0008: 0x0008,     #  BACKSPACE
+    0x0009: 0x0009,     #  HORIZONTAL TABULATION
+    0x000a: 0x000a,     #  LINE FEED
+    0x000b: 0x000b,     #  VERTICAL TABULATION
+    0x000c: 0x000c,     #  FORM FEED
+    0x000d: 0x000d,     #  CARRIAGE RETURN
+    0x000e: 0x000e,     #  SHIFT OUT
+    0x000f: 0x000f,     #  SHIFT IN
+    0x0010: 0x0010,     #  DATA LINK ESCAPE
+    0x0011: 0x0011,     #  DEVICE CONTROL ONE
+    0x0012: 0x0012,     #  DEVICE CONTROL TWO
+    0x0013: 0x0013,     #  DEVICE CONTROL THREE
+    0x0014: 0x0014,     #  DEVICE CONTROL FOUR
+    0x0015: 0x0015,     #  NEGATIVE ACKNOWLEDGE
+    0x0016: 0x0016,     #  SYNCHRONOUS IDLE
+    0x0017: 0x0017,     #  END OF TRANSMISSION BLOCK
+    0x0018: 0x0018,     #  CANCEL
+    0x0019: 0x0019,     #  END OF MEDIUM
+    0x001a: 0x001a,     #  SUBSTITUTE
+    0x001b: 0x001b,     #  ESCAPE
+    0x001c: 0x001c,     #  FILE SEPARATOR
+    0x001d: 0x001d,     #  GROUP SEPARATOR
+    0x001e: 0x001e,     #  RECORD SEPARATOR
+    0x001f: 0x001f,     #  UNIT SEPARATOR
+    0x0020: 0x0020,     #  SPACE
+    0x0021: 0x0021,     #  EXCLAMATION MARK
+    0x0022: 0x0022,     #  QUOTATION MARK
+    0x0023: 0x0023,     #  NUMBER SIGN
+    0x0024: 0x0024,     #  DOLLAR SIGN
+    0x0025: 0x0025,     #  PERCENT SIGN
+    0x0026: 0x0026,     #  AMPERSAND
+    0x0027: 0x0027,     #  APOSTROPHE
+    0x0028: 0x0028,     #  LEFT PARENTHESIS
+    0x0029: 0x0029,     #  RIGHT PARENTHESIS
+    0x002a: 0x002a,     #  ASTERISK
+    0x002b: 0x002b,     #  PLUS SIGN
+    0x002c: 0x002c,     #  COMMA
+    0x002d: 0x002d,     #  HYPHEN-MINUS
+    0x002e: 0x002e,     #  FULL STOP
+    0x002f: 0x002f,     #  SOLIDUS
+    0x0030: 0x0030,     #  DIGIT ZERO
+    0x0031: 0x0031,     #  DIGIT ONE
+    0x0032: 0x0032,     #  DIGIT TWO
+    0x0033: 0x0033,     #  DIGIT THREE
+    0x0034: 0x0034,     #  DIGIT FOUR
+    0x0035: 0x0035,     #  DIGIT FIVE
+    0x0036: 0x0036,     #  DIGIT SIX
+    0x0037: 0x0037,     #  DIGIT SEVEN
+    0x0038: 0x0038,     #  DIGIT EIGHT
+    0x0039: 0x0039,     #  DIGIT NINE
+    0x003a: 0x003a,     #  COLON
+    0x003b: 0x003b,     #  SEMICOLON
+    0x003c: 0x003c,     #  LESS-THAN SIGN
+    0x003d: 0x003d,     #  EQUALS SIGN
+    0x003e: 0x003e,     #  GREATER-THAN SIGN
+    0x003f: 0x003f,     #  QUESTION MARK
+    0x0040: 0x0040,     #  COMMERCIAL AT
+    0x0041: 0x0041,     #  LATIN CAPITAL LETTER A
+    0x0042: 0x0042,     #  LATIN CAPITAL LETTER B
+    0x0043: 0x0043,     #  LATIN CAPITAL LETTER C
+    0x0044: 0x0044,     #  LATIN CAPITAL LETTER D
+    0x0045: 0x0045,     #  LATIN CAPITAL LETTER E
+    0x0046: 0x0046,     #  LATIN CAPITAL LETTER F
+    0x0047: 0x0047,     #  LATIN CAPITAL LETTER G
+    0x0048: 0x0048,     #  LATIN CAPITAL LETTER H
+    0x0049: 0x0049,     #  LATIN CAPITAL LETTER I
+    0x004a: 0x004a,     #  LATIN CAPITAL LETTER J
+    0x004b: 0x004b,     #  LATIN CAPITAL LETTER K
+    0x004c: 0x004c,     #  LATIN CAPITAL LETTER L
+    0x004d: 0x004d,     #  LATIN CAPITAL LETTER M
+    0x004e: 0x004e,     #  LATIN CAPITAL LETTER N
+    0x004f: 0x004f,     #  LATIN CAPITAL LETTER O
+    0x0050: 0x0050,     #  LATIN CAPITAL LETTER P
+    0x0051: 0x0051,     #  LATIN CAPITAL LETTER Q
+    0x0052: 0x0052,     #  LATIN CAPITAL LETTER R
+    0x0053: 0x0053,     #  LATIN CAPITAL LETTER S
+    0x0054: 0x0054,     #  LATIN CAPITAL LETTER T
+    0x0055: 0x0055,     #  LATIN CAPITAL LETTER U
+    0x0056: 0x0056,     #  LATIN CAPITAL LETTER V
+    0x0057: 0x0057,     #  LATIN CAPITAL LETTER W
+    0x0058: 0x0058,     #  LATIN CAPITAL LETTER X
+    0x0059: 0x0059,     #  LATIN CAPITAL LETTER Y
+    0x005a: 0x005a,     #  LATIN CAPITAL LETTER Z
+    0x005b: 0x005b,     #  LEFT SQUARE BRACKET
+    0x005c: 0x005c,     #  REVERSE SOLIDUS
+    0x005d: 0x005d,     #  RIGHT SQUARE BRACKET
+    0x005e: 0x005e,     #  CIRCUMFLEX ACCENT
+    0x005f: 0x005f,     #  LOW LINE
+    0x0060: 0x0060,     #  GRAVE ACCENT
+    0x0061: 0x0061,     #  LATIN SMALL LETTER A
+    0x0062: 0x0062,     #  LATIN SMALL LETTER B
+    0x0063: 0x0063,     #  LATIN SMALL LETTER C
+    0x0064: 0x0064,     #  LATIN SMALL LETTER D
+    0x0065: 0x0065,     #  LATIN SMALL LETTER E
+    0x0066: 0x0066,     #  LATIN SMALL LETTER F
+    0x0067: 0x0067,     #  LATIN SMALL LETTER G
+    0x0068: 0x0068,     #  LATIN SMALL LETTER H
+    0x0069: 0x0069,     #  LATIN SMALL LETTER I
+    0x006a: 0x006a,     #  LATIN SMALL LETTER J
+    0x006b: 0x006b,     #  LATIN SMALL LETTER K
+    0x006c: 0x006c,     #  LATIN SMALL LETTER L
+    0x006d: 0x006d,     #  LATIN SMALL LETTER M
+    0x006e: 0x006e,     #  LATIN SMALL LETTER N
+    0x006f: 0x006f,     #  LATIN SMALL LETTER O
+    0x0070: 0x0070,     #  LATIN SMALL LETTER P
+    0x0071: 0x0071,     #  LATIN SMALL LETTER Q
+    0x0072: 0x0072,     #  LATIN SMALL LETTER R
+    0x0073: 0x0073,     #  LATIN SMALL LETTER S
+    0x0074: 0x0074,     #  LATIN SMALL LETTER T
+    0x0075: 0x0075,     #  LATIN SMALL LETTER U
+    0x0076: 0x0076,     #  LATIN SMALL LETTER V
+    0x0077: 0x0077,     #  LATIN SMALL LETTER W
+    0x0078: 0x0078,     #  LATIN SMALL LETTER X
+    0x0079: 0x0079,     #  LATIN SMALL LETTER Y
+    0x007a: 0x007a,     #  LATIN SMALL LETTER Z
+    0x007b: 0x007b,     #  LEFT CURLY BRACKET
+    0x007c: 0x007c,     #  VERTICAL LINE
+    0x007d: 0x007d,     #  RIGHT CURLY BRACKET
+    0x007e: 0x007e,     #  TILDE
+    0x007f: 0x007f,     #  DELETE
+    0x00a0: 0x00ff,     #  NO-BREAK SPACE
+    0x00a4: 0x00cf,     #  CURRENCY SIGN
+    0x00a7: 0x00f5,     #  SECTION SIGN
+    0x00a8: 0x00f9,     #  DIAERESIS
+    0x00ab: 0x00ae,     #  LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    0x00ac: 0x00aa,     #  NOT SIGN
+    0x00ad: 0x00f0,     #  SOFT HYPHEN
+    0x00b0: 0x00f8,     #  DEGREE SIGN
+    0x00b4: 0x00ef,     #  ACUTE ACCENT
+    0x00b8: 0x00f7,     #  CEDILLA
+    0x00bb: 0x00af,     #  RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    0x00c1: 0x00b5,     #  LATIN CAPITAL LETTER A WITH ACUTE
+    0x00c2: 0x00b6,     #  LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+    0x00c4: 0x008e,     #  LATIN CAPITAL LETTER A WITH DIAERESIS
+    0x00c7: 0x0080,     #  LATIN CAPITAL LETTER C WITH CEDILLA
+    0x00c9: 0x0090,     #  LATIN CAPITAL LETTER E WITH ACUTE
+    0x00cb: 0x00d3,     #  LATIN CAPITAL LETTER E WITH DIAERESIS
+    0x00cd: 0x00d6,     #  LATIN CAPITAL LETTER I WITH ACUTE
+    0x00ce: 0x00d7,     #  LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+    0x00d3: 0x00e0,     #  LATIN CAPITAL LETTER O WITH ACUTE
+    0x00d4: 0x00e2,     #  LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+    0x00d6: 0x0099,     #  LATIN CAPITAL LETTER O WITH DIAERESIS
+    0x00d7: 0x009e,     #  MULTIPLICATION SIGN
+    0x00da: 0x00e9,     #  LATIN CAPITAL LETTER U WITH ACUTE
+    0x00dc: 0x009a,     #  LATIN CAPITAL LETTER U WITH DIAERESIS
+    0x00dd: 0x00ed,     #  LATIN CAPITAL LETTER Y WITH ACUTE
+    0x00df: 0x00e1,     #  LATIN SMALL LETTER SHARP S
+    0x00e1: 0x00a0,     #  LATIN SMALL LETTER A WITH ACUTE
+    0x00e2: 0x0083,     #  LATIN SMALL LETTER A WITH CIRCUMFLEX
+    0x00e4: 0x0084,     #  LATIN SMALL LETTER A WITH DIAERESIS
+    0x00e7: 0x0087,     #  LATIN SMALL LETTER C WITH CEDILLA
+    0x00e9: 0x0082,     #  LATIN SMALL LETTER E WITH ACUTE
+    0x00eb: 0x0089,     #  LATIN SMALL LETTER E WITH DIAERESIS
+    0x00ed: 0x00a1,     #  LATIN SMALL LETTER I WITH ACUTE
+    0x00ee: 0x008c,     #  LATIN SMALL LETTER I WITH CIRCUMFLEX
+    0x00f3: 0x00a2,     #  LATIN SMALL LETTER O WITH ACUTE
+    0x00f4: 0x0093,     #  LATIN SMALL LETTER O WITH CIRCUMFLEX
+    0x00f6: 0x0094,     #  LATIN SMALL LETTER O WITH DIAERESIS
+    0x00f7: 0x00f6,     #  DIVISION SIGN
+    0x00fa: 0x00a3,     #  LATIN SMALL LETTER U WITH ACUTE
+    0x00fc: 0x0081,     #  LATIN SMALL LETTER U WITH DIAERESIS
+    0x00fd: 0x00ec,     #  LATIN SMALL LETTER Y WITH ACUTE
+    0x0102: 0x00c6,     #  LATIN CAPITAL LETTER A WITH BREVE
+    0x0103: 0x00c7,     #  LATIN SMALL LETTER A WITH BREVE
+    0x0104: 0x00a4,     #  LATIN CAPITAL LETTER A WITH OGONEK
+    0x0105: 0x00a5,     #  LATIN SMALL LETTER A WITH OGONEK
+    0x0106: 0x008f,     #  LATIN CAPITAL LETTER C WITH ACUTE
+    0x0107: 0x0086,     #  LATIN SMALL LETTER C WITH ACUTE
+    0x010c: 0x00ac,     #  LATIN CAPITAL LETTER C WITH CARON
+    0x010d: 0x009f,     #  LATIN SMALL LETTER C WITH CARON
+    0x010e: 0x00d2,     #  LATIN CAPITAL LETTER D WITH CARON
+    0x010f: 0x00d4,     #  LATIN SMALL LETTER D WITH CARON
+    0x0110: 0x00d1,     #  LATIN CAPITAL LETTER D WITH STROKE
+    0x0111: 0x00d0,     #  LATIN SMALL LETTER D WITH STROKE
+    0x0118: 0x00a8,     #  LATIN CAPITAL LETTER E WITH OGONEK
+    0x0119: 0x00a9,     #  LATIN SMALL LETTER E WITH OGONEK
+    0x011a: 0x00b7,     #  LATIN CAPITAL LETTER E WITH CARON
+    0x011b: 0x00d8,     #  LATIN SMALL LETTER E WITH CARON
+    0x0139: 0x0091,     #  LATIN CAPITAL LETTER L WITH ACUTE
+    0x013a: 0x0092,     #  LATIN SMALL LETTER L WITH ACUTE
+    0x013d: 0x0095,     #  LATIN CAPITAL LETTER L WITH CARON
+    0x013e: 0x0096,     #  LATIN SMALL LETTER L WITH CARON
+    0x0141: 0x009d,     #  LATIN CAPITAL LETTER L WITH STROKE
+    0x0142: 0x0088,     #  LATIN SMALL LETTER L WITH STROKE
+    0x0143: 0x00e3,     #  LATIN CAPITAL LETTER N WITH ACUTE
+    0x0144: 0x00e4,     #  LATIN SMALL LETTER N WITH ACUTE
+    0x0147: 0x00d5,     #  LATIN CAPITAL LETTER N WITH CARON
+    0x0148: 0x00e5,     #  LATIN SMALL LETTER N WITH CARON
+    0x0150: 0x008a,     #  LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
+    0x0151: 0x008b,     #  LATIN SMALL LETTER O WITH DOUBLE ACUTE
+    0x0154: 0x00e8,     #  LATIN CAPITAL LETTER R WITH ACUTE
+    0x0155: 0x00ea,     #  LATIN SMALL LETTER R WITH ACUTE
+    0x0158: 0x00fc,     #  LATIN CAPITAL LETTER R WITH CARON
+    0x0159: 0x00fd,     #  LATIN SMALL LETTER R WITH CARON
+    0x015a: 0x0097,     #  LATIN CAPITAL LETTER S WITH ACUTE
+    0x015b: 0x0098,     #  LATIN SMALL LETTER S WITH ACUTE
+    0x015e: 0x00b8,     #  LATIN CAPITAL LETTER S WITH CEDILLA
+    0x015f: 0x00ad,     #  LATIN SMALL LETTER S WITH CEDILLA
+    0x0160: 0x00e6,     #  LATIN CAPITAL LETTER S WITH CARON
+    0x0161: 0x00e7,     #  LATIN SMALL LETTER S WITH CARON
+    0x0162: 0x00dd,     #  LATIN CAPITAL LETTER T WITH CEDILLA
+    0x0163: 0x00ee,     #  LATIN SMALL LETTER T WITH CEDILLA
+    0x0164: 0x009b,     #  LATIN CAPITAL LETTER T WITH CARON
+    0x0165: 0x009c,     #  LATIN SMALL LETTER T WITH CARON
+    0x016e: 0x00de,     #  LATIN CAPITAL LETTER U WITH RING ABOVE
+    0x016f: 0x0085,     #  LATIN SMALL LETTER U WITH RING ABOVE
+    0x0170: 0x00eb,     #  LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
+    0x0171: 0x00fb,     #  LATIN SMALL LETTER U WITH DOUBLE ACUTE
+    0x0179: 0x008d,     #  LATIN CAPITAL LETTER Z WITH ACUTE
+    0x017a: 0x00ab,     #  LATIN SMALL LETTER Z WITH ACUTE
+    0x017b: 0x00bd,     #  LATIN CAPITAL LETTER Z WITH DOT ABOVE
+    0x017c: 0x00be,     #  LATIN SMALL LETTER Z WITH DOT ABOVE
+    0x017d: 0x00a6,     #  LATIN CAPITAL LETTER Z WITH CARON
+    0x017e: 0x00a7,     #  LATIN SMALL LETTER Z WITH CARON
+    0x02c7: 0x00f3,     #  CARON
+    0x02d8: 0x00f4,     #  BREVE
+    0x02d9: 0x00fa,     #  DOT ABOVE
+    0x02db: 0x00f2,     #  OGONEK
+    0x02dd: 0x00f1,     #  DOUBLE ACUTE ACCENT
+    0x2500: 0x00c4,     #  BOX DRAWINGS LIGHT HORIZONTAL
+    0x2502: 0x00b3,     #  BOX DRAWINGS LIGHT VERTICAL
+    0x250c: 0x00da,     #  BOX DRAWINGS LIGHT DOWN AND RIGHT
+    0x2510: 0x00bf,     #  BOX DRAWINGS LIGHT DOWN AND LEFT
+    0x2514: 0x00c0,     #  BOX DRAWINGS LIGHT UP AND RIGHT
+    0x2518: 0x00d9,     #  BOX DRAWINGS LIGHT UP AND LEFT
+    0x251c: 0x00c3,     #  BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+    0x2524: 0x00b4,     #  BOX DRAWINGS LIGHT VERTICAL AND LEFT
+    0x252c: 0x00c2,     #  BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+    0x2534: 0x00c1,     #  BOX DRAWINGS LIGHT UP AND HORIZONTAL
+    0x253c: 0x00c5,     #  BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+    0x2550: 0x00cd,     #  BOX DRAWINGS DOUBLE HORIZONTAL
+    0x2551: 0x00ba,     #  BOX DRAWINGS DOUBLE VERTICAL
+    0x2554: 0x00c9,     #  BOX DRAWINGS DOUBLE DOWN AND RIGHT
+    0x2557: 0x00bb,     #  BOX DRAWINGS DOUBLE DOWN AND LEFT
+    0x255a: 0x00c8,     #  BOX DRAWINGS DOUBLE UP AND RIGHT
+    0x255d: 0x00bc,     #  BOX DRAWINGS DOUBLE UP AND LEFT
+    0x2560: 0x00cc,     #  BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+    0x2563: 0x00b9,     #  BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+    0x2566: 0x00cb,     #  BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+    0x2569: 0x00ca,     #  BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+    0x256c: 0x00ce,     #  BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+    0x2580: 0x00df,     #  UPPER HALF BLOCK
+    0x2584: 0x00dc,     #  LOWER HALF BLOCK
+    0x2588: 0x00db,     #  FULL BLOCK
+    0x2591: 0x00b0,     #  LIGHT SHADE
+    0x2592: 0x00b1,     #  MEDIUM SHADE
+    0x2593: 0x00b2,     #  DARK SHADE
+    0x25a0: 0x00fe,     #  BLACK SQUARE
+}

Added: vendor/Python/current/Lib/encodings/cp855.py
===================================================================
--- vendor/Python/current/Lib/encodings/cp855.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/cp855.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,698 @@
+""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP855.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_map)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='cp855',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+### Decoding Map
+
+decoding_map = codecs.make_identity_dict(range(256))
+decoding_map.update({
+    0x0080: 0x0452,     #  CYRILLIC SMALL LETTER DJE
+    0x0081: 0x0402,     #  CYRILLIC CAPITAL LETTER DJE
+    0x0082: 0x0453,     #  CYRILLIC SMALL LETTER GJE
+    0x0083: 0x0403,     #  CYRILLIC CAPITAL LETTER GJE
+    0x0084: 0x0451,     #  CYRILLIC SMALL LETTER IO
+    0x0085: 0x0401,     #  CYRILLIC CAPITAL LETTER IO
+    0x0086: 0x0454,     #  CYRILLIC SMALL LETTER UKRAINIAN IE
+    0x0087: 0x0404,     #  CYRILLIC CAPITAL LETTER UKRAINIAN IE
+    0x0088: 0x0455,     #  CYRILLIC SMALL LETTER DZE
+    0x0089: 0x0405,     #  CYRILLIC CAPITAL LETTER DZE
+    0x008a: 0x0456,     #  CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
+    0x008b: 0x0406,     #  CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I
+    0x008c: 0x0457,     #  CYRILLIC SMALL LETTER YI
+    0x008d: 0x0407,     #  CYRILLIC CAPITAL LETTER YI
+    0x008e: 0x0458,     #  CYRILLIC SMALL LETTER JE
+    0x008f: 0x0408,     #  CYRILLIC CAPITAL LETTER JE
+    0x0090: 0x0459,     #  CYRILLIC SMALL LETTER LJE
+    0x0091: 0x0409,     #  CYRILLIC CAPITAL LETTER LJE
+    0x0092: 0x045a,     #  CYRILLIC SMALL LETTER NJE
+    0x0093: 0x040a,     #  CYRILLIC CAPITAL LETTER NJE
+    0x0094: 0x045b,     #  CYRILLIC SMALL LETTER TSHE
+    0x0095: 0x040b,     #  CYRILLIC CAPITAL LETTER TSHE
+    0x0096: 0x045c,     #  CYRILLIC SMALL LETTER KJE
+    0x0097: 0x040c,     #  CYRILLIC CAPITAL LETTER KJE
+    0x0098: 0x045e,     #  CYRILLIC SMALL LETTER SHORT U
+    0x0099: 0x040e,     #  CYRILLIC CAPITAL LETTER SHORT U
+    0x009a: 0x045f,     #  CYRILLIC SMALL LETTER DZHE
+    0x009b: 0x040f,     #  CYRILLIC CAPITAL LETTER DZHE
+    0x009c: 0x044e,     #  CYRILLIC SMALL LETTER YU
+    0x009d: 0x042e,     #  CYRILLIC CAPITAL LETTER YU
+    0x009e: 0x044a,     #  CYRILLIC SMALL LETTER HARD SIGN
+    0x009f: 0x042a,     #  CYRILLIC CAPITAL LETTER HARD SIGN
+    0x00a0: 0x0430,     #  CYRILLIC SMALL LETTER A
+    0x00a1: 0x0410,     #  CYRILLIC CAPITAL LETTER A
+    0x00a2: 0x0431,     #  CYRILLIC SMALL LETTER BE
+    0x00a3: 0x0411,     #  CYRILLIC CAPITAL LETTER BE
+    0x00a4: 0x0446,     #  CYRILLIC SMALL LETTER TSE
+    0x00a5: 0x0426,     #  CYRILLIC CAPITAL LETTER TSE
+    0x00a6: 0x0434,     #  CYRILLIC SMALL LETTER DE
+    0x00a7: 0x0414,     #  CYRILLIC CAPITAL LETTER DE
+    0x00a8: 0x0435,     #  CYRILLIC SMALL LETTER IE
+    0x00a9: 0x0415,     #  CYRILLIC CAPITAL LETTER IE
+    0x00aa: 0x0444,     #  CYRILLIC SMALL LETTER EF
+    0x00ab: 0x0424,     #  CYRILLIC CAPITAL LETTER EF
+    0x00ac: 0x0433,     #  CYRILLIC SMALL LETTER GHE
+    0x00ad: 0x0413,     #  CYRILLIC CAPITAL LETTER GHE
+    0x00ae: 0x00ab,     #  LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    0x00af: 0x00bb,     #  RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    0x00b0: 0x2591,     #  LIGHT SHADE
+    0x00b1: 0x2592,     #  MEDIUM SHADE
+    0x00b2: 0x2593,     #  DARK SHADE
+    0x00b3: 0x2502,     #  BOX DRAWINGS LIGHT VERTICAL
+    0x00b4: 0x2524,     #  BOX DRAWINGS LIGHT VERTICAL AND LEFT
+    0x00b5: 0x0445,     #  CYRILLIC SMALL LETTER HA
+    0x00b6: 0x0425,     #  CYRILLIC CAPITAL LETTER HA
+    0x00b7: 0x0438,     #  CYRILLIC SMALL LETTER I
+    0x00b8: 0x0418,     #  CYRILLIC CAPITAL LETTER I
+    0x00b9: 0x2563,     #  BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+    0x00ba: 0x2551,     #  BOX DRAWINGS DOUBLE VERTICAL
+    0x00bb: 0x2557,     #  BOX DRAWINGS DOUBLE DOWN AND LEFT
+    0x00bc: 0x255d,     #  BOX DRAWINGS DOUBLE UP AND LEFT
+    0x00bd: 0x0439,     #  CYRILLIC SMALL LETTER SHORT I
+    0x00be: 0x0419,     #  CYRILLIC CAPITAL LETTER SHORT I
+    0x00bf: 0x2510,     #  BOX DRAWINGS LIGHT DOWN AND LEFT
+    0x00c0: 0x2514,     #  BOX DRAWINGS LIGHT UP AND RIGHT
+    0x00c1: 0x2534,     #  BOX DRAWINGS LIGHT UP AND HORIZONTAL
+    0x00c2: 0x252c,     #  BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+    0x00c3: 0x251c,     #  BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+    0x00c4: 0x2500,     #  BOX DRAWINGS LIGHT HORIZONTAL
+    0x00c5: 0x253c,     #  BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+    0x00c6: 0x043a,     #  CYRILLIC SMALL LETTER KA
+    0x00c7: 0x041a,     #  CYRILLIC CAPITAL LETTER KA
+    0x00c8: 0x255a,     #  BOX DRAWINGS DOUBLE UP AND RIGHT
+    0x00c9: 0x2554,     #  BOX DRAWINGS DOUBLE DOWN AND RIGHT
+    0x00ca: 0x2569,     #  BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+    0x00cb: 0x2566,     #  BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+    0x00cc: 0x2560,     #  BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+    0x00cd: 0x2550,     #  BOX DRAWINGS DOUBLE HORIZONTAL
+    0x00ce: 0x256c,     #  BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+    0x00cf: 0x00a4,     #  CURRENCY SIGN
+    0x00d0: 0x043b,     #  CYRILLIC SMALL LETTER EL
+    0x00d1: 0x041b,     #  CYRILLIC CAPITAL LETTER EL
+    0x00d2: 0x043c,     #  CYRILLIC SMALL LETTER EM
+    0x00d3: 0x041c,     #  CYRILLIC CAPITAL LETTER EM
+    0x00d4: 0x043d,     #  CYRILLIC SMALL LETTER EN
+    0x00d5: 0x041d,     #  CYRILLIC CAPITAL LETTER EN
+    0x00d6: 0x043e,     #  CYRILLIC SMALL LETTER O
+    0x00d7: 0x041e,     #  CYRILLIC CAPITAL LETTER O
+    0x00d8: 0x043f,     #  CYRILLIC SMALL LETTER PE
+    0x00d9: 0x2518,     #  BOX DRAWINGS LIGHT UP AND LEFT
+    0x00da: 0x250c,     #  BOX DRAWINGS LIGHT DOWN AND RIGHT
+    0x00db: 0x2588,     #  FULL BLOCK
+    0x00dc: 0x2584,     #  LOWER HALF BLOCK
+    0x00dd: 0x041f,     #  CYRILLIC CAPITAL LETTER PE
+    0x00de: 0x044f,     #  CYRILLIC SMALL LETTER YA
+    0x00df: 0x2580,     #  UPPER HALF BLOCK
+    0x00e0: 0x042f,     #  CYRILLIC CAPITAL LETTER YA
+    0x00e1: 0x0440,     #  CYRILLIC SMALL LETTER ER
+    0x00e2: 0x0420,     #  CYRILLIC CAPITAL LETTER ER
+    0x00e3: 0x0441,     #  CYRILLIC SMALL LETTER ES
+    0x00e4: 0x0421,     #  CYRILLIC CAPITAL LETTER ES
+    0x00e5: 0x0442,     #  CYRILLIC SMALL LETTER TE
+    0x00e6: 0x0422,     #  CYRILLIC CAPITAL LETTER TE
+    0x00e7: 0x0443,     #  CYRILLIC SMALL LETTER U
+    0x00e8: 0x0423,     #  CYRILLIC CAPITAL LETTER U
+    0x00e9: 0x0436,     #  CYRILLIC SMALL LETTER ZHE
+    0x00ea: 0x0416,     #  CYRILLIC CAPITAL LETTER ZHE
+    0x00eb: 0x0432,     #  CYRILLIC SMALL LETTER VE
+    0x00ec: 0x0412,     #  CYRILLIC CAPITAL LETTER VE
+    0x00ed: 0x044c,     #  CYRILLIC SMALL LETTER SOFT SIGN
+    0x00ee: 0x042c,     #  CYRILLIC CAPITAL LETTER SOFT SIGN
+    0x00ef: 0x2116,     #  NUMERO SIGN
+    0x00f0: 0x00ad,     #  SOFT HYPHEN
+    0x00f1: 0x044b,     #  CYRILLIC SMALL LETTER YERU
+    0x00f2: 0x042b,     #  CYRILLIC CAPITAL LETTER YERU
+    0x00f3: 0x0437,     #  CYRILLIC SMALL LETTER ZE
+    0x00f4: 0x0417,     #  CYRILLIC CAPITAL LETTER ZE
+    0x00f5: 0x0448,     #  CYRILLIC SMALL LETTER SHA
+    0x00f6: 0x0428,     #  CYRILLIC CAPITAL LETTER SHA
+    0x00f7: 0x044d,     #  CYRILLIC SMALL LETTER E
+    0x00f8: 0x042d,     #  CYRILLIC CAPITAL LETTER E
+    0x00f9: 0x0449,     #  CYRILLIC SMALL LETTER SHCHA
+    0x00fa: 0x0429,     #  CYRILLIC CAPITAL LETTER SHCHA
+    0x00fb: 0x0447,     #  CYRILLIC SMALL LETTER CHE
+    0x00fc: 0x0427,     #  CYRILLIC CAPITAL LETTER CHE
+    0x00fd: 0x00a7,     #  SECTION SIGN
+    0x00fe: 0x25a0,     #  BLACK SQUARE
+    0x00ff: 0x00a0,     #  NO-BREAK SPACE
+})
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x0000 -> NULL
+    u'\x01'     #  0x0001 -> START OF HEADING
+    u'\x02'     #  0x0002 -> START OF TEXT
+    u'\x03'     #  0x0003 -> END OF TEXT
+    u'\x04'     #  0x0004 -> END OF TRANSMISSION
+    u'\x05'     #  0x0005 -> ENQUIRY
+    u'\x06'     #  0x0006 -> ACKNOWLEDGE
+    u'\x07'     #  0x0007 -> BELL
+    u'\x08'     #  0x0008 -> BACKSPACE
+    u'\t'       #  0x0009 -> HORIZONTAL TABULATION
+    u'\n'       #  0x000a -> LINE FEED
+    u'\x0b'     #  0x000b -> VERTICAL TABULATION
+    u'\x0c'     #  0x000c -> FORM FEED
+    u'\r'       #  0x000d -> CARRIAGE RETURN
+    u'\x0e'     #  0x000e -> SHIFT OUT
+    u'\x0f'     #  0x000f -> SHIFT IN
+    u'\x10'     #  0x0010 -> DATA LINK ESCAPE
+    u'\x11'     #  0x0011 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x0012 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x0013 -> DEVICE CONTROL THREE
+    u'\x14'     #  0x0014 -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x0015 -> NEGATIVE ACKNOWLEDGE
+    u'\x16'     #  0x0016 -> SYNCHRONOUS IDLE
+    u'\x17'     #  0x0017 -> END OF TRANSMISSION BLOCK
+    u'\x18'     #  0x0018 -> CANCEL
+    u'\x19'     #  0x0019 -> END OF MEDIUM
+    u'\x1a'     #  0x001a -> SUBSTITUTE
+    u'\x1b'     #  0x001b -> ESCAPE
+    u'\x1c'     #  0x001c -> FILE SEPARATOR
+    u'\x1d'     #  0x001d -> GROUP SEPARATOR
+    u'\x1e'     #  0x001e -> RECORD SEPARATOR
+    u'\x1f'     #  0x001f -> UNIT SEPARATOR
+    u' '        #  0x0020 -> SPACE
+    u'!'        #  0x0021 -> EXCLAMATION MARK
+    u'"'        #  0x0022 -> QUOTATION MARK
+    u'#'        #  0x0023 -> NUMBER SIGN
+    u'$'        #  0x0024 -> DOLLAR SIGN
+    u'%'        #  0x0025 -> PERCENT SIGN
+    u'&'        #  0x0026 -> AMPERSAND
+    u"'"        #  0x0027 -> APOSTROPHE
+    u'('        #  0x0028 -> LEFT PARENTHESIS
+    u')'        #  0x0029 -> RIGHT PARENTHESIS
+    u'*'        #  0x002a -> ASTERISK
+    u'+'        #  0x002b -> PLUS SIGN
+    u','        #  0x002c -> COMMA
+    u'-'        #  0x002d -> HYPHEN-MINUS
+    u'.'        #  0x002e -> FULL STOP
+    u'/'        #  0x002f -> SOLIDUS
+    u'0'        #  0x0030 -> DIGIT ZERO
+    u'1'        #  0x0031 -> DIGIT ONE
+    u'2'        #  0x0032 -> DIGIT TWO
+    u'3'        #  0x0033 -> DIGIT THREE
+    u'4'        #  0x0034 -> DIGIT FOUR
+    u'5'        #  0x0035 -> DIGIT FIVE
+    u'6'        #  0x0036 -> DIGIT SIX
+    u'7'        #  0x0037 -> DIGIT SEVEN
+    u'8'        #  0x0038 -> DIGIT EIGHT
+    u'9'        #  0x0039 -> DIGIT NINE
+    u':'        #  0x003a -> COLON
+    u';'        #  0x003b -> SEMICOLON
+    u'<'        #  0x003c -> LESS-THAN SIGN
+    u'='        #  0x003d -> EQUALS SIGN
+    u'>'        #  0x003e -> GREATER-THAN SIGN
+    u'?'        #  0x003f -> QUESTION MARK
+    u'@'        #  0x0040 -> COMMERCIAL AT
+    u'A'        #  0x0041 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x0042 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x0043 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x0044 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x0045 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x0046 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x0047 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x0048 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x0049 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x004a -> LATIN CAPITAL LETTER J
+    u'K'        #  0x004b -> LATIN CAPITAL LETTER K
+    u'L'        #  0x004c -> LATIN CAPITAL LETTER L
+    u'M'        #  0x004d -> LATIN CAPITAL LETTER M
+    u'N'        #  0x004e -> LATIN CAPITAL LETTER N
+    u'O'        #  0x004f -> LATIN CAPITAL LETTER O
+    u'P'        #  0x0050 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x0051 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x0052 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x0053 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x0054 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x0055 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x0056 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x0057 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x0058 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x0059 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x005a -> LATIN CAPITAL LETTER Z
+    u'['        #  0x005b -> LEFT SQUARE BRACKET
+    u'\\'       #  0x005c -> REVERSE SOLIDUS
+    u']'        #  0x005d -> RIGHT SQUARE BRACKET
+    u'^'        #  0x005e -> CIRCUMFLEX ACCENT
+    u'_'        #  0x005f -> LOW LINE
+    u'`'        #  0x0060 -> GRAVE ACCENT
+    u'a'        #  0x0061 -> LATIN SMALL LETTER A
+    u'b'        #  0x0062 -> LATIN SMALL LETTER B
+    u'c'        #  0x0063 -> LATIN SMALL LETTER C
+    u'd'        #  0x0064 -> LATIN SMALL LETTER D
+    u'e'        #  0x0065 -> LATIN SMALL LETTER E
+    u'f'        #  0x0066 -> LATIN SMALL LETTER F
+    u'g'        #  0x0067 -> LATIN SMALL LETTER G
+    u'h'        #  0x0068 -> LATIN SMALL LETTER H
+    u'i'        #  0x0069 -> LATIN SMALL LETTER I
+    u'j'        #  0x006a -> LATIN SMALL LETTER J
+    u'k'        #  0x006b -> LATIN SMALL LETTER K
+    u'l'        #  0x006c -> LATIN SMALL LETTER L
+    u'm'        #  0x006d -> LATIN SMALL LETTER M
+    u'n'        #  0x006e -> LATIN SMALL LETTER N
+    u'o'        #  0x006f -> LATIN SMALL LETTER O
+    u'p'        #  0x0070 -> LATIN SMALL LETTER P
+    u'q'        #  0x0071 -> LATIN SMALL LETTER Q
+    u'r'        #  0x0072 -> LATIN SMALL LETTER R
+    u's'        #  0x0073 -> LATIN SMALL LETTER S
+    u't'        #  0x0074 -> LATIN SMALL LETTER T
+    u'u'        #  0x0075 -> LATIN SMALL LETTER U
+    u'v'        #  0x0076 -> LATIN SMALL LETTER V
+    u'w'        #  0x0077 -> LATIN SMALL LETTER W
+    u'x'        #  0x0078 -> LATIN SMALL LETTER X
+    u'y'        #  0x0079 -> LATIN SMALL LETTER Y
+    u'z'        #  0x007a -> LATIN SMALL LETTER Z
+    u'{'        #  0x007b -> LEFT CURLY BRACKET
+    u'|'        #  0x007c -> VERTICAL LINE
+    u'}'        #  0x007d -> RIGHT CURLY BRACKET
+    u'~'        #  0x007e -> TILDE
+    u'\x7f'     #  0x007f -> DELETE
+    u'\u0452'   #  0x0080 -> CYRILLIC SMALL LETTER DJE
+    u'\u0402'   #  0x0081 -> CYRILLIC CAPITAL LETTER DJE
+    u'\u0453'   #  0x0082 -> CYRILLIC SMALL LETTER GJE
+    u'\u0403'   #  0x0083 -> CYRILLIC CAPITAL LETTER GJE
+    u'\u0451'   #  0x0084 -> CYRILLIC SMALL LETTER IO
+    u'\u0401'   #  0x0085 -> CYRILLIC CAPITAL LETTER IO
+    u'\u0454'   #  0x0086 -> CYRILLIC SMALL LETTER UKRAINIAN IE
+    u'\u0404'   #  0x0087 -> CYRILLIC CAPITAL LETTER UKRAINIAN IE
+    u'\u0455'   #  0x0088 -> CYRILLIC SMALL LETTER DZE
+    u'\u0405'   #  0x0089 -> CYRILLIC CAPITAL LETTER DZE
+    u'\u0456'   #  0x008a -> CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
+    u'\u0406'   #  0x008b -> CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I
+    u'\u0457'   #  0x008c -> CYRILLIC SMALL LETTER YI
+    u'\u0407'   #  0x008d -> CYRILLIC CAPITAL LETTER YI
+    u'\u0458'   #  0x008e -> CYRILLIC SMALL LETTER JE
+    u'\u0408'   #  0x008f -> CYRILLIC CAPITAL LETTER JE
+    u'\u0459'   #  0x0090 -> CYRILLIC SMALL LETTER LJE
+    u'\u0409'   #  0x0091 -> CYRILLIC CAPITAL LETTER LJE
+    u'\u045a'   #  0x0092 -> CYRILLIC SMALL LETTER NJE
+    u'\u040a'   #  0x0093 -> CYRILLIC CAPITAL LETTER NJE
+    u'\u045b'   #  0x0094 -> CYRILLIC SMALL LETTER TSHE
+    u'\u040b'   #  0x0095 -> CYRILLIC CAPITAL LETTER TSHE
+    u'\u045c'   #  0x0096 -> CYRILLIC SMALL LETTER KJE
+    u'\u040c'   #  0x0097 -> CYRILLIC CAPITAL LETTER KJE
+    u'\u045e'   #  0x0098 -> CYRILLIC SMALL LETTER SHORT U
+    u'\u040e'   #  0x0099 -> CYRILLIC CAPITAL LETTER SHORT U
+    u'\u045f'   #  0x009a -> CYRILLIC SMALL LETTER DZHE
+    u'\u040f'   #  0x009b -> CYRILLIC CAPITAL LETTER DZHE
+    u'\u044e'   #  0x009c -> CYRILLIC SMALL LETTER YU
+    u'\u042e'   #  0x009d -> CYRILLIC CAPITAL LETTER YU
+    u'\u044a'   #  0x009e -> CYRILLIC SMALL LETTER HARD SIGN
+    u'\u042a'   #  0x009f -> CYRILLIC CAPITAL LETTER HARD SIGN
+    u'\u0430'   #  0x00a0 -> CYRILLIC SMALL LETTER A
+    u'\u0410'   #  0x00a1 -> CYRILLIC CAPITAL LETTER A
+    u'\u0431'   #  0x00a2 -> CYRILLIC SMALL LETTER BE
+    u'\u0411'   #  0x00a3 -> CYRILLIC CAPITAL LETTER BE
+    u'\u0446'   #  0x00a4 -> CYRILLIC SMALL LETTER TSE
+    u'\u0426'   #  0x00a5 -> CYRILLIC CAPITAL LETTER TSE
+    u'\u0434'   #  0x00a6 -> CYRILLIC SMALL LETTER DE
+    u'\u0414'   #  0x00a7 -> CYRILLIC CAPITAL LETTER DE
+    u'\u0435'   #  0x00a8 -> CYRILLIC SMALL LETTER IE
+    u'\u0415'   #  0x00a9 -> CYRILLIC CAPITAL LETTER IE
+    u'\u0444'   #  0x00aa -> CYRILLIC SMALL LETTER EF
+    u'\u0424'   #  0x00ab -> CYRILLIC CAPITAL LETTER EF
+    u'\u0433'   #  0x00ac -> CYRILLIC SMALL LETTER GHE
+    u'\u0413'   #  0x00ad -> CYRILLIC CAPITAL LETTER GHE
+    u'\xab'     #  0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xbb'     #  0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\u2591'   #  0x00b0 -> LIGHT SHADE
+    u'\u2592'   #  0x00b1 -> MEDIUM SHADE
+    u'\u2593'   #  0x00b2 -> DARK SHADE
+    u'\u2502'   #  0x00b3 -> BOX DRAWINGS LIGHT VERTICAL
+    u'\u2524'   #  0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT
+    u'\u0445'   #  0x00b5 -> CYRILLIC SMALL LETTER HA
+    u'\u0425'   #  0x00b6 -> CYRILLIC CAPITAL LETTER HA
+    u'\u0438'   #  0x00b7 -> CYRILLIC SMALL LETTER I
+    u'\u0418'   #  0x00b8 -> CYRILLIC CAPITAL LETTER I
+    u'\u2563'   #  0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+    u'\u2551'   #  0x00ba -> BOX DRAWINGS DOUBLE VERTICAL
+    u'\u2557'   #  0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT
+    u'\u255d'   #  0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT
+    u'\u0439'   #  0x00bd -> CYRILLIC SMALL LETTER SHORT I
+    u'\u0419'   #  0x00be -> CYRILLIC CAPITAL LETTER SHORT I
+    u'\u2510'   #  0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT
+    u'\u2514'   #  0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT
+    u'\u2534'   #  0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL
+    u'\u252c'   #  0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+    u'\u251c'   #  0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+    u'\u2500'   #  0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL
+    u'\u253c'   #  0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+    u'\u043a'   #  0x00c6 -> CYRILLIC SMALL LETTER KA
+    u'\u041a'   #  0x00c7 -> CYRILLIC CAPITAL LETTER KA
+    u'\u255a'   #  0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT
+    u'\u2554'   #  0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT
+    u'\u2569'   #  0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+    u'\u2566'   #  0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+    u'\u2560'   #  0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+    u'\u2550'   #  0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL
+    u'\u256c'   #  0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+    u'\xa4'     #  0x00cf -> CURRENCY SIGN
+    u'\u043b'   #  0x00d0 -> CYRILLIC SMALL LETTER EL
+    u'\u041b'   #  0x00d1 -> CYRILLIC CAPITAL LETTER EL
+    u'\u043c'   #  0x00d2 -> CYRILLIC SMALL LETTER EM
+    u'\u041c'   #  0x00d3 -> CYRILLIC CAPITAL LETTER EM
+    u'\u043d'   #  0x00d4 -> CYRILLIC SMALL LETTER EN
+    u'\u041d'   #  0x00d5 -> CYRILLIC CAPITAL LETTER EN
+    u'\u043e'   #  0x00d6 -> CYRILLIC SMALL LETTER O
+    u'\u041e'   #  0x00d7 -> CYRILLIC CAPITAL LETTER O
+    u'\u043f'   #  0x00d8 -> CYRILLIC SMALL LETTER PE
+    u'\u2518'   #  0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT
+    u'\u250c'   #  0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT
+    u'\u2588'   #  0x00db -> FULL BLOCK
+    u'\u2584'   #  0x00dc -> LOWER HALF BLOCK
+    u'\u041f'   #  0x00dd -> CYRILLIC CAPITAL LETTER PE
+    u'\u044f'   #  0x00de -> CYRILLIC SMALL LETTER YA
+    u'\u2580'   #  0x00df -> UPPER HALF BLOCK
+    u'\u042f'   #  0x00e0 -> CYRILLIC CAPITAL LETTER YA
+    u'\u0440'   #  0x00e1 -> CYRILLIC SMALL LETTER ER
+    u'\u0420'   #  0x00e2 -> CYRILLIC CAPITAL LETTER ER
+    u'\u0441'   #  0x00e3 -> CYRILLIC SMALL LETTER ES
+    u'\u0421'   #  0x00e4 -> CYRILLIC CAPITAL LETTER ES
+    u'\u0442'   #  0x00e5 -> CYRILLIC SMALL LETTER TE
+    u'\u0422'   #  0x00e6 -> CYRILLIC CAPITAL LETTER TE
+    u'\u0443'   #  0x00e7 -> CYRILLIC SMALL LETTER U
+    u'\u0423'   #  0x00e8 -> CYRILLIC CAPITAL LETTER U
+    u'\u0436'   #  0x00e9 -> CYRILLIC SMALL LETTER ZHE
+    u'\u0416'   #  0x00ea -> CYRILLIC CAPITAL LETTER ZHE
+    u'\u0432'   #  0x00eb -> CYRILLIC SMALL LETTER VE
+    u'\u0412'   #  0x00ec -> CYRILLIC CAPITAL LETTER VE
+    u'\u044c'   #  0x00ed -> CYRILLIC SMALL LETTER SOFT SIGN
+    u'\u042c'   #  0x00ee -> CYRILLIC CAPITAL LETTER SOFT SIGN
+    u'\u2116'   #  0x00ef -> NUMERO SIGN
+    u'\xad'     #  0x00f0 -> SOFT HYPHEN
+    u'\u044b'   #  0x00f1 -> CYRILLIC SMALL LETTER YERU
+    u'\u042b'   #  0x00f2 -> CYRILLIC CAPITAL LETTER YERU
+    u'\u0437'   #  0x00f3 -> CYRILLIC SMALL LETTER ZE
+    u'\u0417'   #  0x00f4 -> CYRILLIC CAPITAL LETTER ZE
+    u'\u0448'   #  0x00f5 -> CYRILLIC SMALL LETTER SHA
+    u'\u0428'   #  0x00f6 -> CYRILLIC CAPITAL LETTER SHA
+    u'\u044d'   #  0x00f7 -> CYRILLIC SMALL LETTER E
+    u'\u042d'   #  0x00f8 -> CYRILLIC CAPITAL LETTER E
+    u'\u0449'   #  0x00f9 -> CYRILLIC SMALL LETTER SHCHA
+    u'\u0429'   #  0x00fa -> CYRILLIC CAPITAL LETTER SHCHA
+    u'\u0447'   #  0x00fb -> CYRILLIC SMALL LETTER CHE
+    u'\u0427'   #  0x00fc -> CYRILLIC CAPITAL LETTER CHE
+    u'\xa7'     #  0x00fd -> SECTION SIGN
+    u'\u25a0'   #  0x00fe -> BLACK SQUARE
+    u'\xa0'     #  0x00ff -> NO-BREAK SPACE
+)
+
+### Encoding Map
+
+encoding_map = {
+    0x0000: 0x0000,     #  NULL
+    0x0001: 0x0001,     #  START OF HEADING
+    0x0002: 0x0002,     #  START OF TEXT
+    0x0003: 0x0003,     #  END OF TEXT
+    0x0004: 0x0004,     #  END OF TRANSMISSION
+    0x0005: 0x0005,     #  ENQUIRY
+    0x0006: 0x0006,     #  ACKNOWLEDGE
+    0x0007: 0x0007,     #  BELL
+    0x0008: 0x0008,     #  BACKSPACE
+    0x0009: 0x0009,     #  HORIZONTAL TABULATION
+    0x000a: 0x000a,     #  LINE FEED
+    0x000b: 0x000b,     #  VERTICAL TABULATION
+    0x000c: 0x000c,     #  FORM FEED
+    0x000d: 0x000d,     #  CARRIAGE RETURN
+    0x000e: 0x000e,     #  SHIFT OUT
+    0x000f: 0x000f,     #  SHIFT IN
+    0x0010: 0x0010,     #  DATA LINK ESCAPE
+    0x0011: 0x0011,     #  DEVICE CONTROL ONE
+    0x0012: 0x0012,     #  DEVICE CONTROL TWO
+    0x0013: 0x0013,     #  DEVICE CONTROL THREE
+    0x0014: 0x0014,     #  DEVICE CONTROL FOUR
+    0x0015: 0x0015,     #  NEGATIVE ACKNOWLEDGE
+    0x0016: 0x0016,     #  SYNCHRONOUS IDLE
+    0x0017: 0x0017,     #  END OF TRANSMISSION BLOCK
+    0x0018: 0x0018,     #  CANCEL
+    0x0019: 0x0019,     #  END OF MEDIUM
+    0x001a: 0x001a,     #  SUBSTITUTE
+    0x001b: 0x001b,     #  ESCAPE
+    0x001c: 0x001c,     #  FILE SEPARATOR
+    0x001d: 0x001d,     #  GROUP SEPARATOR
+    0x001e: 0x001e,     #  RECORD SEPARATOR
+    0x001f: 0x001f,     #  UNIT SEPARATOR
+    0x0020: 0x0020,     #  SPACE
+    0x0021: 0x0021,     #  EXCLAMATION MARK
+    0x0022: 0x0022,     #  QUOTATION MARK
+    0x0023: 0x0023,     #  NUMBER SIGN
+    0x0024: 0x0024,     #  DOLLAR SIGN
+    0x0025: 0x0025,     #  PERCENT SIGN
+    0x0026: 0x0026,     #  AMPERSAND
+    0x0027: 0x0027,     #  APOSTROPHE
+    0x0028: 0x0028,     #  LEFT PARENTHESIS
+    0x0029: 0x0029,     #  RIGHT PARENTHESIS
+    0x002a: 0x002a,     #  ASTERISK
+    0x002b: 0x002b,     #  PLUS SIGN
+    0x002c: 0x002c,     #  COMMA
+    0x002d: 0x002d,     #  HYPHEN-MINUS
+    0x002e: 0x002e,     #  FULL STOP
+    0x002f: 0x002f,     #  SOLIDUS
+    0x0030: 0x0030,     #  DIGIT ZERO
+    0x0031: 0x0031,     #  DIGIT ONE
+    0x0032: 0x0032,     #  DIGIT TWO
+    0x0033: 0x0033,     #  DIGIT THREE
+    0x0034: 0x0034,     #  DIGIT FOUR
+    0x0035: 0x0035,     #  DIGIT FIVE
+    0x0036: 0x0036,     #  DIGIT SIX
+    0x0037: 0x0037,     #  DIGIT SEVEN
+    0x0038: 0x0038,     #  DIGIT EIGHT
+    0x0039: 0x0039,     #  DIGIT NINE
+    0x003a: 0x003a,     #  COLON
+    0x003b: 0x003b,     #  SEMICOLON
+    0x003c: 0x003c,     #  LESS-THAN SIGN
+    0x003d: 0x003d,     #  EQUALS SIGN
+    0x003e: 0x003e,     #  GREATER-THAN SIGN
+    0x003f: 0x003f,     #  QUESTION MARK
+    0x0040: 0x0040,     #  COMMERCIAL AT
+    0x0041: 0x0041,     #  LATIN CAPITAL LETTER A
+    0x0042: 0x0042,     #  LATIN CAPITAL LETTER B
+    0x0043: 0x0043,     #  LATIN CAPITAL LETTER C
+    0x0044: 0x0044,     #  LATIN CAPITAL LETTER D
+    0x0045: 0x0045,     #  LATIN CAPITAL LETTER E
+    0x0046: 0x0046,     #  LATIN CAPITAL LETTER F
+    0x0047: 0x0047,     #  LATIN CAPITAL LETTER G
+    0x0048: 0x0048,     #  LATIN CAPITAL LETTER H
+    0x0049: 0x0049,     #  LATIN CAPITAL LETTER I
+    0x004a: 0x004a,     #  LATIN CAPITAL LETTER J
+    0x004b: 0x004b,     #  LATIN CAPITAL LETTER K
+    0x004c: 0x004c,     #  LATIN CAPITAL LETTER L
+    0x004d: 0x004d,     #  LATIN CAPITAL LETTER M
+    0x004e: 0x004e,     #  LATIN CAPITAL LETTER N
+    0x004f: 0x004f,     #  LATIN CAPITAL LETTER O
+    0x0050: 0x0050,     #  LATIN CAPITAL LETTER P
+    0x0051: 0x0051,     #  LATIN CAPITAL LETTER Q
+    0x0052: 0x0052,     #  LATIN CAPITAL LETTER R
+    0x0053: 0x0053,     #  LATIN CAPITAL LETTER S
+    0x0054: 0x0054,     #  LATIN CAPITAL LETTER T
+    0x0055: 0x0055,     #  LATIN CAPITAL LETTER U
+    0x0056: 0x0056,     #  LATIN CAPITAL LETTER V
+    0x0057: 0x0057,     #  LATIN CAPITAL LETTER W
+    0x0058: 0x0058,     #  LATIN CAPITAL LETTER X
+    0x0059: 0x0059,     #  LATIN CAPITAL LETTER Y
+    0x005a: 0x005a,     #  LATIN CAPITAL LETTER Z
+    0x005b: 0x005b,     #  LEFT SQUARE BRACKET
+    0x005c: 0x005c,     #  REVERSE SOLIDUS
+    0x005d: 0x005d,     #  RIGHT SQUARE BRACKET
+    0x005e: 0x005e,     #  CIRCUMFLEX ACCENT
+    0x005f: 0x005f,     #  LOW LINE
+    0x0060: 0x0060,     #  GRAVE ACCENT
+    0x0061: 0x0061,     #  LATIN SMALL LETTER A
+    0x0062: 0x0062,     #  LATIN SMALL LETTER B
+    0x0063: 0x0063,     #  LATIN SMALL LETTER C
+    0x0064: 0x0064,     #  LATIN SMALL LETTER D
+    0x0065: 0x0065,     #  LATIN SMALL LETTER E
+    0x0066: 0x0066,     #  LATIN SMALL LETTER F
+    0x0067: 0x0067,     #  LATIN SMALL LETTER G
+    0x0068: 0x0068,     #  LATIN SMALL LETTER H
+    0x0069: 0x0069,     #  LATIN SMALL LETTER I
+    0x006a: 0x006a,     #  LATIN SMALL LETTER J
+    0x006b: 0x006b,     #  LATIN SMALL LETTER K
+    0x006c: 0x006c,     #  LATIN SMALL LETTER L
+    0x006d: 0x006d,     #  LATIN SMALL LETTER M
+    0x006e: 0x006e,     #  LATIN SMALL LETTER N
+    0x006f: 0x006f,     #  LATIN SMALL LETTER O
+    0x0070: 0x0070,     #  LATIN SMALL LETTER P
+    0x0071: 0x0071,     #  LATIN SMALL LETTER Q
+    0x0072: 0x0072,     #  LATIN SMALL LETTER R
+    0x0073: 0x0073,     #  LATIN SMALL LETTER S
+    0x0074: 0x0074,     #  LATIN SMALL LETTER T
+    0x0075: 0x0075,     #  LATIN SMALL LETTER U
+    0x0076: 0x0076,     #  LATIN SMALL LETTER V
+    0x0077: 0x0077,     #  LATIN SMALL LETTER W
+    0x0078: 0x0078,     #  LATIN SMALL LETTER X
+    0x0079: 0x0079,     #  LATIN SMALL LETTER Y
+    0x007a: 0x007a,     #  LATIN SMALL LETTER Z
+    0x007b: 0x007b,     #  LEFT CURLY BRACKET
+    0x007c: 0x007c,     #  VERTICAL LINE
+    0x007d: 0x007d,     #  RIGHT CURLY BRACKET
+    0x007e: 0x007e,     #  TILDE
+    0x007f: 0x007f,     #  DELETE
+    0x00a0: 0x00ff,     #  NO-BREAK SPACE
+    0x00a4: 0x00cf,     #  CURRENCY SIGN
+    0x00a7: 0x00fd,     #  SECTION SIGN
+    0x00ab: 0x00ae,     #  LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    0x00ad: 0x00f0,     #  SOFT HYPHEN
+    0x00bb: 0x00af,     #  RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    0x0401: 0x0085,     #  CYRILLIC CAPITAL LETTER IO
+    0x0402: 0x0081,     #  CYRILLIC CAPITAL LETTER DJE
+    0x0403: 0x0083,     #  CYRILLIC CAPITAL LETTER GJE
+    0x0404: 0x0087,     #  CYRILLIC CAPITAL LETTER UKRAINIAN IE
+    0x0405: 0x0089,     #  CYRILLIC CAPITAL LETTER DZE
+    0x0406: 0x008b,     #  CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I
+    0x0407: 0x008d,     #  CYRILLIC CAPITAL LETTER YI
+    0x0408: 0x008f,     #  CYRILLIC CAPITAL LETTER JE
+    0x0409: 0x0091,     #  CYRILLIC CAPITAL LETTER LJE
+    0x040a: 0x0093,     #  CYRILLIC CAPITAL LETTER NJE
+    0x040b: 0x0095,     #  CYRILLIC CAPITAL LETTER TSHE
+    0x040c: 0x0097,     #  CYRILLIC CAPITAL LETTER KJE
+    0x040e: 0x0099,     #  CYRILLIC CAPITAL LETTER SHORT U
+    0x040f: 0x009b,     #  CYRILLIC CAPITAL LETTER DZHE
+    0x0410: 0x00a1,     #  CYRILLIC CAPITAL LETTER A
+    0x0411: 0x00a3,     #  CYRILLIC CAPITAL LETTER BE
+    0x0412: 0x00ec,     #  CYRILLIC CAPITAL LETTER VE
+    0x0413: 0x00ad,     #  CYRILLIC CAPITAL LETTER GHE
+    0x0414: 0x00a7,     #  CYRILLIC CAPITAL LETTER DE
+    0x0415: 0x00a9,     #  CYRILLIC CAPITAL LETTER IE
+    0x0416: 0x00ea,     #  CYRILLIC CAPITAL LETTER ZHE
+    0x0417: 0x00f4,     #  CYRILLIC CAPITAL LETTER ZE
+    0x0418: 0x00b8,     #  CYRILLIC CAPITAL LETTER I
+    0x0419: 0x00be,     #  CYRILLIC CAPITAL LETTER SHORT I
+    0x041a: 0x00c7,     #  CYRILLIC CAPITAL LETTER KA
+    0x041b: 0x00d1,     #  CYRILLIC CAPITAL LETTER EL
+    0x041c: 0x00d3,     #  CYRILLIC CAPITAL LETTER EM
+    0x041d: 0x00d5,     #  CYRILLIC CAPITAL LETTER EN
+    0x041e: 0x00d7,     #  CYRILLIC CAPITAL LETTER O
+    0x041f: 0x00dd,     #  CYRILLIC CAPITAL LETTER PE
+    0x0420: 0x00e2,     #  CYRILLIC CAPITAL LETTER ER
+    0x0421: 0x00e4,     #  CYRILLIC CAPITAL LETTER ES
+    0x0422: 0x00e6,     #  CYRILLIC CAPITAL LETTER TE
+    0x0423: 0x00e8,     #  CYRILLIC CAPITAL LETTER U
+    0x0424: 0x00ab,     #  CYRILLIC CAPITAL LETTER EF
+    0x0425: 0x00b6,     #  CYRILLIC CAPITAL LETTER HA
+    0x0426: 0x00a5,     #  CYRILLIC CAPITAL LETTER TSE
+    0x0427: 0x00fc,     #  CYRILLIC CAPITAL LETTER CHE
+    0x0428: 0x00f6,     #  CYRILLIC CAPITAL LETTER SHA
+    0x0429: 0x00fa,     #  CYRILLIC CAPITAL LETTER SHCHA
+    0x042a: 0x009f,     #  CYRILLIC CAPITAL LETTER HARD SIGN
+    0x042b: 0x00f2,     #  CYRILLIC CAPITAL LETTER YERU
+    0x042c: 0x00ee,     #  CYRILLIC CAPITAL LETTER SOFT SIGN
+    0x042d: 0x00f8,     #  CYRILLIC CAPITAL LETTER E
+    0x042e: 0x009d,     #  CYRILLIC CAPITAL LETTER YU
+    0x042f: 0x00e0,     #  CYRILLIC CAPITAL LETTER YA
+    0x0430: 0x00a0,     #  CYRILLIC SMALL LETTER A
+    0x0431: 0x00a2,     #  CYRILLIC SMALL LETTER BE
+    0x0432: 0x00eb,     #  CYRILLIC SMALL LETTER VE
+    0x0433: 0x00ac,     #  CYRILLIC SMALL LETTER GHE
+    0x0434: 0x00a6,     #  CYRILLIC SMALL LETTER DE
+    0x0435: 0x00a8,     #  CYRILLIC SMALL LETTER IE
+    0x0436: 0x00e9,     #  CYRILLIC SMALL LETTER ZHE
+    0x0437: 0x00f3,     #  CYRILLIC SMALL LETTER ZE
+    0x0438: 0x00b7,     #  CYRILLIC SMALL LETTER I
+    0x0439: 0x00bd,     #  CYRILLIC SMALL LETTER SHORT I
+    0x043a: 0x00c6,     #  CYRILLIC SMALL LETTER KA
+    0x043b: 0x00d0,     #  CYRILLIC SMALL LETTER EL
+    0x043c: 0x00d2,     #  CYRILLIC SMALL LETTER EM
+    0x043d: 0x00d4,     #  CYRILLIC SMALL LETTER EN
+    0x043e: 0x00d6,     #  CYRILLIC SMALL LETTER O
+    0x043f: 0x00d8,     #  CYRILLIC SMALL LETTER PE
+    0x0440: 0x00e1,     #  CYRILLIC SMALL LETTER ER
+    0x0441: 0x00e3,     #  CYRILLIC SMALL LETTER ES
+    0x0442: 0x00e5,     #  CYRILLIC SMALL LETTER TE
+    0x0443: 0x00e7,     #  CYRILLIC SMALL LETTER U
+    0x0444: 0x00aa,     #  CYRILLIC SMALL LETTER EF
+    0x0445: 0x00b5,     #  CYRILLIC SMALL LETTER HA
+    0x0446: 0x00a4,     #  CYRILLIC SMALL LETTER TSE
+    0x0447: 0x00fb,     #  CYRILLIC SMALL LETTER CHE
+    0x0448: 0x00f5,     #  CYRILLIC SMALL LETTER SHA
+    0x0449: 0x00f9,     #  CYRILLIC SMALL LETTER SHCHA
+    0x044a: 0x009e,     #  CYRILLIC SMALL LETTER HARD SIGN
+    0x044b: 0x00f1,     #  CYRILLIC SMALL LETTER YERU
+    0x044c: 0x00ed,     #  CYRILLIC SMALL LETTER SOFT SIGN
+    0x044d: 0x00f7,     #  CYRILLIC SMALL LETTER E
+    0x044e: 0x009c,     #  CYRILLIC SMALL LETTER YU
+    0x044f: 0x00de,     #  CYRILLIC SMALL LETTER YA
+    0x0451: 0x0084,     #  CYRILLIC SMALL LETTER IO
+    0x0452: 0x0080,     #  CYRILLIC SMALL LETTER DJE
+    0x0453: 0x0082,     #  CYRILLIC SMALL LETTER GJE
+    0x0454: 0x0086,     #  CYRILLIC SMALL LETTER UKRAINIAN IE
+    0x0455: 0x0088,     #  CYRILLIC SMALL LETTER DZE
+    0x0456: 0x008a,     #  CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
+    0x0457: 0x008c,     #  CYRILLIC SMALL LETTER YI
+    0x0458: 0x008e,     #  CYRILLIC SMALL LETTER JE
+    0x0459: 0x0090,     #  CYRILLIC SMALL LETTER LJE
+    0x045a: 0x0092,     #  CYRILLIC SMALL LETTER NJE
+    0x045b: 0x0094,     #  CYRILLIC SMALL LETTER TSHE
+    0x045c: 0x0096,     #  CYRILLIC SMALL LETTER KJE
+    0x045e: 0x0098,     #  CYRILLIC SMALL LETTER SHORT U
+    0x045f: 0x009a,     #  CYRILLIC SMALL LETTER DZHE
+    0x2116: 0x00ef,     #  NUMERO SIGN
+    0x2500: 0x00c4,     #  BOX DRAWINGS LIGHT HORIZONTAL
+    0x2502: 0x00b3,     #  BOX DRAWINGS LIGHT VERTICAL
+    0x250c: 0x00da,     #  BOX DRAWINGS LIGHT DOWN AND RIGHT
+    0x2510: 0x00bf,     #  BOX DRAWINGS LIGHT DOWN AND LEFT
+    0x2514: 0x00c0,     #  BOX DRAWINGS LIGHT UP AND RIGHT
+    0x2518: 0x00d9,     #  BOX DRAWINGS LIGHT UP AND LEFT
+    0x251c: 0x00c3,     #  BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+    0x2524: 0x00b4,     #  BOX DRAWINGS LIGHT VERTICAL AND LEFT
+    0x252c: 0x00c2,     #  BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+    0x2534: 0x00c1,     #  BOX DRAWINGS LIGHT UP AND HORIZONTAL
+    0x253c: 0x00c5,     #  BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+    0x2550: 0x00cd,     #  BOX DRAWINGS DOUBLE HORIZONTAL
+    0x2551: 0x00ba,     #  BOX DRAWINGS DOUBLE VERTICAL
+    0x2554: 0x00c9,     #  BOX DRAWINGS DOUBLE DOWN AND RIGHT
+    0x2557: 0x00bb,     #  BOX DRAWINGS DOUBLE DOWN AND LEFT
+    0x255a: 0x00c8,     #  BOX DRAWINGS DOUBLE UP AND RIGHT
+    0x255d: 0x00bc,     #  BOX DRAWINGS DOUBLE UP AND LEFT
+    0x2560: 0x00cc,     #  BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+    0x2563: 0x00b9,     #  BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+    0x2566: 0x00cb,     #  BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+    0x2569: 0x00ca,     #  BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+    0x256c: 0x00ce,     #  BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+    0x2580: 0x00df,     #  UPPER HALF BLOCK
+    0x2584: 0x00dc,     #  LOWER HALF BLOCK
+    0x2588: 0x00db,     #  FULL BLOCK
+    0x2591: 0x00b0,     #  LIGHT SHADE
+    0x2592: 0x00b1,     #  MEDIUM SHADE
+    0x2593: 0x00b2,     #  DARK SHADE
+    0x25a0: 0x00fe,     #  BLACK SQUARE
+}

Added: vendor/Python/current/Lib/encodings/cp856.py
===================================================================
--- vendor/Python/current/Lib/encodings/cp856.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/cp856.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,307 @@
+""" Python Character Mapping Codec cp856 generated from 'MAPPINGS/VENDORS/MISC/CP856.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_table)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_table)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='cp856',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x00 -> NULL
+    u'\x01'     #  0x01 -> START OF HEADING
+    u'\x02'     #  0x02 -> START OF TEXT
+    u'\x03'     #  0x03 -> END OF TEXT
+    u'\x04'     #  0x04 -> END OF TRANSMISSION
+    u'\x05'     #  0x05 -> ENQUIRY
+    u'\x06'     #  0x06 -> ACKNOWLEDGE
+    u'\x07'     #  0x07 -> BELL
+    u'\x08'     #  0x08 -> BACKSPACE
+    u'\t'       #  0x09 -> HORIZONTAL TABULATION
+    u'\n'       #  0x0A -> LINE FEED
+    u'\x0b'     #  0x0B -> VERTICAL TABULATION
+    u'\x0c'     #  0x0C -> FORM FEED
+    u'\r'       #  0x0D -> CARRIAGE RETURN
+    u'\x0e'     #  0x0E -> SHIFT OUT
+    u'\x0f'     #  0x0F -> SHIFT IN
+    u'\x10'     #  0x10 -> DATA LINK ESCAPE
+    u'\x11'     #  0x11 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x12 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x13 -> DEVICE CONTROL THREE
+    u'\x14'     #  0x14 -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x15 -> NEGATIVE ACKNOWLEDGE
+    u'\x16'     #  0x16 -> SYNCHRONOUS IDLE
+    u'\x17'     #  0x17 -> END OF TRANSMISSION BLOCK
+    u'\x18'     #  0x18 -> CANCEL
+    u'\x19'     #  0x19 -> END OF MEDIUM
+    u'\x1a'     #  0x1A -> SUBSTITUTE
+    u'\x1b'     #  0x1B -> ESCAPE
+    u'\x1c'     #  0x1C -> FILE SEPARATOR
+    u'\x1d'     #  0x1D -> GROUP SEPARATOR
+    u'\x1e'     #  0x1E -> RECORD SEPARATOR
+    u'\x1f'     #  0x1F -> UNIT SEPARATOR
+    u' '        #  0x20 -> SPACE
+    u'!'        #  0x21 -> EXCLAMATION MARK
+    u'"'        #  0x22 -> QUOTATION MARK
+    u'#'        #  0x23 -> NUMBER SIGN
+    u'$'        #  0x24 -> DOLLAR SIGN
+    u'%'        #  0x25 -> PERCENT SIGN
+    u'&'        #  0x26 -> AMPERSAND
+    u"'"        #  0x27 -> APOSTROPHE
+    u'('        #  0x28 -> LEFT PARENTHESIS
+    u')'        #  0x29 -> RIGHT PARENTHESIS
+    u'*'        #  0x2A -> ASTERISK
+    u'+'        #  0x2B -> PLUS SIGN
+    u','        #  0x2C -> COMMA
+    u'-'        #  0x2D -> HYPHEN-MINUS
+    u'.'        #  0x2E -> FULL STOP
+    u'/'        #  0x2F -> SOLIDUS
+    u'0'        #  0x30 -> DIGIT ZERO
+    u'1'        #  0x31 -> DIGIT ONE
+    u'2'        #  0x32 -> DIGIT TWO
+    u'3'        #  0x33 -> DIGIT THREE
+    u'4'        #  0x34 -> DIGIT FOUR
+    u'5'        #  0x35 -> DIGIT FIVE
+    u'6'        #  0x36 -> DIGIT SIX
+    u'7'        #  0x37 -> DIGIT SEVEN
+    u'8'        #  0x38 -> DIGIT EIGHT
+    u'9'        #  0x39 -> DIGIT NINE
+    u':'        #  0x3A -> COLON
+    u';'        #  0x3B -> SEMICOLON
+    u'<'        #  0x3C -> LESS-THAN SIGN
+    u'='        #  0x3D -> EQUALS SIGN
+    u'>'        #  0x3E -> GREATER-THAN SIGN
+    u'?'        #  0x3F -> QUESTION MARK
+    u'@'        #  0x40 -> COMMERCIAL AT
+    u'A'        #  0x41 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x42 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x43 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x44 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x45 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x46 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x47 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x48 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x49 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x4A -> LATIN CAPITAL LETTER J
+    u'K'        #  0x4B -> LATIN CAPITAL LETTER K
+    u'L'        #  0x4C -> LATIN CAPITAL LETTER L
+    u'M'        #  0x4D -> LATIN CAPITAL LETTER M
+    u'N'        #  0x4E -> LATIN CAPITAL LETTER N
+    u'O'        #  0x4F -> LATIN CAPITAL LETTER O
+    u'P'        #  0x50 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x51 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x52 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x53 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x54 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x55 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x56 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x57 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x58 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x59 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x5A -> LATIN CAPITAL LETTER Z
+    u'['        #  0x5B -> LEFT SQUARE BRACKET
+    u'\\'       #  0x5C -> REVERSE SOLIDUS
+    u']'        #  0x5D -> RIGHT SQUARE BRACKET
+    u'^'        #  0x5E -> CIRCUMFLEX ACCENT
+    u'_'        #  0x5F -> LOW LINE
+    u'`'        #  0x60 -> GRAVE ACCENT
+    u'a'        #  0x61 -> LATIN SMALL LETTER A
+    u'b'        #  0x62 -> LATIN SMALL LETTER B
+    u'c'        #  0x63 -> LATIN SMALL LETTER C
+    u'd'        #  0x64 -> LATIN SMALL LETTER D
+    u'e'        #  0x65 -> LATIN SMALL LETTER E
+    u'f'        #  0x66 -> LATIN SMALL LETTER F
+    u'g'        #  0x67 -> LATIN SMALL LETTER G
+    u'h'        #  0x68 -> LATIN SMALL LETTER H
+    u'i'        #  0x69 -> LATIN SMALL LETTER I
+    u'j'        #  0x6A -> LATIN SMALL LETTER J
+    u'k'        #  0x6B -> LATIN SMALL LETTER K
+    u'l'        #  0x6C -> LATIN SMALL LETTER L
+    u'm'        #  0x6D -> LATIN SMALL LETTER M
+    u'n'        #  0x6E -> LATIN SMALL LETTER N
+    u'o'        #  0x6F -> LATIN SMALL LETTER O
+    u'p'        #  0x70 -> LATIN SMALL LETTER P
+    u'q'        #  0x71 -> LATIN SMALL LETTER Q
+    u'r'        #  0x72 -> LATIN SMALL LETTER R
+    u's'        #  0x73 -> LATIN SMALL LETTER S
+    u't'        #  0x74 -> LATIN SMALL LETTER T
+    u'u'        #  0x75 -> LATIN SMALL LETTER U
+    u'v'        #  0x76 -> LATIN SMALL LETTER V
+    u'w'        #  0x77 -> LATIN SMALL LETTER W
+    u'x'        #  0x78 -> LATIN SMALL LETTER X
+    u'y'        #  0x79 -> LATIN SMALL LETTER Y
+    u'z'        #  0x7A -> LATIN SMALL LETTER Z
+    u'{'        #  0x7B -> LEFT CURLY BRACKET
+    u'|'        #  0x7C -> VERTICAL LINE
+    u'}'        #  0x7D -> RIGHT CURLY BRACKET
+    u'~'        #  0x7E -> TILDE
+    u'\x7f'     #  0x7F -> DELETE
+    u'\u05d0'   #  0x80 -> HEBREW LETTER ALEF
+    u'\u05d1'   #  0x81 -> HEBREW LETTER BET
+    u'\u05d2'   #  0x82 -> HEBREW LETTER GIMEL
+    u'\u05d3'   #  0x83 -> HEBREW LETTER DALET
+    u'\u05d4'   #  0x84 -> HEBREW LETTER HE
+    u'\u05d5'   #  0x85 -> HEBREW LETTER VAV
+    u'\u05d6'   #  0x86 -> HEBREW LETTER ZAYIN
+    u'\u05d7'   #  0x87 -> HEBREW LETTER HET
+    u'\u05d8'   #  0x88 -> HEBREW LETTER TET
+    u'\u05d9'   #  0x89 -> HEBREW LETTER YOD
+    u'\u05da'   #  0x8A -> HEBREW LETTER FINAL KAF
+    u'\u05db'   #  0x8B -> HEBREW LETTER KAF
+    u'\u05dc'   #  0x8C -> HEBREW LETTER LAMED
+    u'\u05dd'   #  0x8D -> HEBREW LETTER FINAL MEM
+    u'\u05de'   #  0x8E -> HEBREW LETTER MEM
+    u'\u05df'   #  0x8F -> HEBREW LETTER FINAL NUN
+    u'\u05e0'   #  0x90 -> HEBREW LETTER NUN
+    u'\u05e1'   #  0x91 -> HEBREW LETTER SAMEKH
+    u'\u05e2'   #  0x92 -> HEBREW LETTER AYIN
+    u'\u05e3'   #  0x93 -> HEBREW LETTER FINAL PE
+    u'\u05e4'   #  0x94 -> HEBREW LETTER PE
+    u'\u05e5'   #  0x95 -> HEBREW LETTER FINAL TSADI
+    u'\u05e6'   #  0x96 -> HEBREW LETTER TSADI
+    u'\u05e7'   #  0x97 -> HEBREW LETTER QOF
+    u'\u05e8'   #  0x98 -> HEBREW LETTER RESH
+    u'\u05e9'   #  0x99 -> HEBREW LETTER SHIN
+    u'\u05ea'   #  0x9A -> HEBREW LETTER TAV
+    u'\ufffe'   #  0x9B -> UNDEFINED
+    u'\xa3'     #  0x9C -> POUND SIGN
+    u'\ufffe'   #  0x9D -> UNDEFINED
+    u'\xd7'     #  0x9E -> MULTIPLICATION SIGN
+    u'\ufffe'   #  0x9F -> UNDEFINED
+    u'\ufffe'   #  0xA0 -> UNDEFINED
+    u'\ufffe'   #  0xA1 -> UNDEFINED
+    u'\ufffe'   #  0xA2 -> UNDEFINED
+    u'\ufffe'   #  0xA3 -> UNDEFINED
+    u'\ufffe'   #  0xA4 -> UNDEFINED
+    u'\ufffe'   #  0xA5 -> UNDEFINED
+    u'\ufffe'   #  0xA6 -> UNDEFINED
+    u'\ufffe'   #  0xA7 -> UNDEFINED
+    u'\ufffe'   #  0xA8 -> UNDEFINED
+    u'\xae'     #  0xA9 -> REGISTERED SIGN
+    u'\xac'     #  0xAA -> NOT SIGN
+    u'\xbd'     #  0xAB -> VULGAR FRACTION ONE HALF
+    u'\xbc'     #  0xAC -> VULGAR FRACTION ONE QUARTER
+    u'\ufffe'   #  0xAD -> UNDEFINED
+    u'\xab'     #  0xAE -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xbb'     #  0xAF -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\u2591'   #  0xB0 -> LIGHT SHADE
+    u'\u2592'   #  0xB1 -> MEDIUM SHADE
+    u'\u2593'   #  0xB2 -> DARK SHADE
+    u'\u2502'   #  0xB3 -> BOX DRAWINGS LIGHT VERTICAL
+    u'\u2524'   #  0xB4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT
+    u'\ufffe'   #  0xB5 -> UNDEFINED
+    u'\ufffe'   #  0xB6 -> UNDEFINED
+    u'\ufffe'   #  0xB7 -> UNDEFINED
+    u'\xa9'     #  0xB8 -> COPYRIGHT SIGN
+    u'\u2563'   #  0xB9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+    u'\u2551'   #  0xBA -> BOX DRAWINGS DOUBLE VERTICAL
+    u'\u2557'   #  0xBB -> BOX DRAWINGS DOUBLE DOWN AND LEFT
+    u'\u255d'   #  0xBC -> BOX DRAWINGS DOUBLE UP AND LEFT
+    u'\xa2'     #  0xBD -> CENT SIGN
+    u'\xa5'     #  0xBE -> YEN SIGN
+    u'\u2510'   #  0xBF -> BOX DRAWINGS LIGHT DOWN AND LEFT
+    u'\u2514'   #  0xC0 -> BOX DRAWINGS LIGHT UP AND RIGHT
+    u'\u2534'   #  0xC1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL
+    u'\u252c'   #  0xC2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+    u'\u251c'   #  0xC3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+    u'\u2500'   #  0xC4 -> BOX DRAWINGS LIGHT HORIZONTAL
+    u'\u253c'   #  0xC5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+    u'\ufffe'   #  0xC6 -> UNDEFINED
+    u'\ufffe'   #  0xC7 -> UNDEFINED
+    u'\u255a'   #  0xC8 -> BOX DRAWINGS DOUBLE UP AND RIGHT
+    u'\u2554'   #  0xC9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT
+    u'\u2569'   #  0xCA -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+    u'\u2566'   #  0xCB -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+    u'\u2560'   #  0xCC -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+    u'\u2550'   #  0xCD -> BOX DRAWINGS DOUBLE HORIZONTAL
+    u'\u256c'   #  0xCE -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+    u'\xa4'     #  0xCF -> CURRENCY SIGN
+    u'\ufffe'   #  0xD0 -> UNDEFINED
+    u'\ufffe'   #  0xD1 -> UNDEFINED
+    u'\ufffe'   #  0xD2 -> UNDEFINED
+    u'\ufffe'   #  0xD3 -> UNDEFINEDS
+    u'\ufffe'   #  0xD4 -> UNDEFINED
+    u'\ufffe'   #  0xD5 -> UNDEFINED
+    u'\ufffe'   #  0xD6 -> UNDEFINEDE
+    u'\ufffe'   #  0xD7 -> UNDEFINED
+    u'\ufffe'   #  0xD8 -> UNDEFINED
+    u'\u2518'   #  0xD9 -> BOX DRAWINGS LIGHT UP AND LEFT
+    u'\u250c'   #  0xDA -> BOX DRAWINGS LIGHT DOWN AND RIGHT
+    u'\u2588'   #  0xDB -> FULL BLOCK
+    u'\u2584'   #  0xDC -> LOWER HALF BLOCK
+    u'\xa6'     #  0xDD -> BROKEN BAR
+    u'\ufffe'   #  0xDE -> UNDEFINED
+    u'\u2580'   #  0xDF -> UPPER HALF BLOCK
+    u'\ufffe'   #  0xE0 -> UNDEFINED
+    u'\ufffe'   #  0xE1 -> UNDEFINED
+    u'\ufffe'   #  0xE2 -> UNDEFINED
+    u'\ufffe'   #  0xE3 -> UNDEFINED
+    u'\ufffe'   #  0xE4 -> UNDEFINED
+    u'\ufffe'   #  0xE5 -> UNDEFINED
+    u'\xb5'     #  0xE6 -> MICRO SIGN
+    u'\ufffe'   #  0xE7 -> UNDEFINED
+    u'\ufffe'   #  0xE8 -> UNDEFINED
+    u'\ufffe'   #  0xE9 -> UNDEFINED
+    u'\ufffe'   #  0xEA -> UNDEFINED
+    u'\ufffe'   #  0xEB -> UNDEFINED
+    u'\ufffe'   #  0xEC -> UNDEFINED
+    u'\ufffe'   #  0xED -> UNDEFINED
+    u'\xaf'     #  0xEE -> MACRON
+    u'\xb4'     #  0xEF -> ACUTE ACCENT
+    u'\xad'     #  0xF0 -> SOFT HYPHEN
+    u'\xb1'     #  0xF1 -> PLUS-MINUS SIGN
+    u'\u2017'   #  0xF2 -> DOUBLE LOW LINE
+    u'\xbe'     #  0xF3 -> VULGAR FRACTION THREE QUARTERS
+    u'\xb6'     #  0xF4 -> PILCROW SIGN
+    u'\xa7'     #  0xF5 -> SECTION SIGN
+    u'\xf7'     #  0xF6 -> DIVISION SIGN
+    u'\xb8'     #  0xF7 -> CEDILLA
+    u'\xb0'     #  0xF8 -> DEGREE SIGN
+    u'\xa8'     #  0xF9 -> DIAERESIS
+    u'\xb7'     #  0xFA -> MIDDLE DOT
+    u'\xb9'     #  0xFB -> SUPERSCRIPT ONE
+    u'\xb3'     #  0xFC -> SUPERSCRIPT THREE
+    u'\xb2'     #  0xFD -> SUPERSCRIPT TWO
+    u'\u25a0'   #  0xFE -> BLACK SQUARE
+    u'\xa0'     #  0xFF -> NO-BREAK SPACE
+)
+
+### Encoding table
+encoding_table=codecs.charmap_build(decoding_table)

Added: vendor/Python/current/Lib/encodings/cp857.py
===================================================================
--- vendor/Python/current/Lib/encodings/cp857.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/cp857.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,694 @@
+""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP857.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_map)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='cp857',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+### Decoding Map
+
+decoding_map = codecs.make_identity_dict(range(256))
+decoding_map.update({
+    0x0080: 0x00c7,     #  LATIN CAPITAL LETTER C WITH CEDILLA
+    0x0081: 0x00fc,     #  LATIN SMALL LETTER U WITH DIAERESIS
+    0x0082: 0x00e9,     #  LATIN SMALL LETTER E WITH ACUTE
+    0x0083: 0x00e2,     #  LATIN SMALL LETTER A WITH CIRCUMFLEX
+    0x0084: 0x00e4,     #  LATIN SMALL LETTER A WITH DIAERESIS
+    0x0085: 0x00e0,     #  LATIN SMALL LETTER A WITH GRAVE
+    0x0086: 0x00e5,     #  LATIN SMALL LETTER A WITH RING ABOVE
+    0x0087: 0x00e7,     #  LATIN SMALL LETTER C WITH CEDILLA
+    0x0088: 0x00ea,     #  LATIN SMALL LETTER E WITH CIRCUMFLEX
+    0x0089: 0x00eb,     #  LATIN SMALL LETTER E WITH DIAERESIS
+    0x008a: 0x00e8,     #  LATIN SMALL LETTER E WITH GRAVE
+    0x008b: 0x00ef,     #  LATIN SMALL LETTER I WITH DIAERESIS
+    0x008c: 0x00ee,     #  LATIN SMALL LETTER I WITH CIRCUMFLEX
+    0x008d: 0x0131,     #  LATIN SMALL LETTER DOTLESS I
+    0x008e: 0x00c4,     #  LATIN CAPITAL LETTER A WITH DIAERESIS
+    0x008f: 0x00c5,     #  LATIN CAPITAL LETTER A WITH RING ABOVE
+    0x0090: 0x00c9,     #  LATIN CAPITAL LETTER E WITH ACUTE
+    0x0091: 0x00e6,     #  LATIN SMALL LIGATURE AE
+    0x0092: 0x00c6,     #  LATIN CAPITAL LIGATURE AE
+    0x0093: 0x00f4,     #  LATIN SMALL LETTER O WITH CIRCUMFLEX
+    0x0094: 0x00f6,     #  LATIN SMALL LETTER O WITH DIAERESIS
+    0x0095: 0x00f2,     #  LATIN SMALL LETTER O WITH GRAVE
+    0x0096: 0x00fb,     #  LATIN SMALL LETTER U WITH CIRCUMFLEX
+    0x0097: 0x00f9,     #  LATIN SMALL LETTER U WITH GRAVE
+    0x0098: 0x0130,     #  LATIN CAPITAL LETTER I WITH DOT ABOVE
+    0x0099: 0x00d6,     #  LATIN CAPITAL LETTER O WITH DIAERESIS
+    0x009a: 0x00dc,     #  LATIN CAPITAL LETTER U WITH DIAERESIS
+    0x009b: 0x00f8,     #  LATIN SMALL LETTER O WITH STROKE
+    0x009c: 0x00a3,     #  POUND SIGN
+    0x009d: 0x00d8,     #  LATIN CAPITAL LETTER O WITH STROKE
+    0x009e: 0x015e,     #  LATIN CAPITAL LETTER S WITH CEDILLA
+    0x009f: 0x015f,     #  LATIN SMALL LETTER S WITH CEDILLA
+    0x00a0: 0x00e1,     #  LATIN SMALL LETTER A WITH ACUTE
+    0x00a1: 0x00ed,     #  LATIN SMALL LETTER I WITH ACUTE
+    0x00a2: 0x00f3,     #  LATIN SMALL LETTER O WITH ACUTE
+    0x00a3: 0x00fa,     #  LATIN SMALL LETTER U WITH ACUTE
+    0x00a4: 0x00f1,     #  LATIN SMALL LETTER N WITH TILDE
+    0x00a5: 0x00d1,     #  LATIN CAPITAL LETTER N WITH TILDE
+    0x00a6: 0x011e,     #  LATIN CAPITAL LETTER G WITH BREVE
+    0x00a7: 0x011f,     #  LATIN SMALL LETTER G WITH BREVE
+    0x00a8: 0x00bf,     #  INVERTED QUESTION MARK
+    0x00a9: 0x00ae,     #  REGISTERED SIGN
+    0x00aa: 0x00ac,     #  NOT SIGN
+    0x00ab: 0x00bd,     #  VULGAR FRACTION ONE HALF
+    0x00ac: 0x00bc,     #  VULGAR FRACTION ONE QUARTER
+    0x00ad: 0x00a1,     #  INVERTED EXCLAMATION MARK
+    0x00ae: 0x00ab,     #  LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    0x00af: 0x00bb,     #  RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    0x00b0: 0x2591,     #  LIGHT SHADE
+    0x00b1: 0x2592,     #  MEDIUM SHADE
+    0x00b2: 0x2593,     #  DARK SHADE
+    0x00b3: 0x2502,     #  BOX DRAWINGS LIGHT VERTICAL
+    0x00b4: 0x2524,     #  BOX DRAWINGS LIGHT VERTICAL AND LEFT
+    0x00b5: 0x00c1,     #  LATIN CAPITAL LETTER A WITH ACUTE
+    0x00b6: 0x00c2,     #  LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+    0x00b7: 0x00c0,     #  LATIN CAPITAL LETTER A WITH GRAVE
+    0x00b8: 0x00a9,     #  COPYRIGHT SIGN
+    0x00b9: 0x2563,     #  BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+    0x00ba: 0x2551,     #  BOX DRAWINGS DOUBLE VERTICAL
+    0x00bb: 0x2557,     #  BOX DRAWINGS DOUBLE DOWN AND LEFT
+    0x00bc: 0x255d,     #  BOX DRAWINGS DOUBLE UP AND LEFT
+    0x00bd: 0x00a2,     #  CENT SIGN
+    0x00be: 0x00a5,     #  YEN SIGN
+    0x00bf: 0x2510,     #  BOX DRAWINGS LIGHT DOWN AND LEFT
+    0x00c0: 0x2514,     #  BOX DRAWINGS LIGHT UP AND RIGHT
+    0x00c1: 0x2534,     #  BOX DRAWINGS LIGHT UP AND HORIZONTAL
+    0x00c2: 0x252c,     #  BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+    0x00c3: 0x251c,     #  BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+    0x00c4: 0x2500,     #  BOX DRAWINGS LIGHT HORIZONTAL
+    0x00c5: 0x253c,     #  BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+    0x00c6: 0x00e3,     #  LATIN SMALL LETTER A WITH TILDE
+    0x00c7: 0x00c3,     #  LATIN CAPITAL LETTER A WITH TILDE
+    0x00c8: 0x255a,     #  BOX DRAWINGS DOUBLE UP AND RIGHT
+    0x00c9: 0x2554,     #  BOX DRAWINGS DOUBLE DOWN AND RIGHT
+    0x00ca: 0x2569,     #  BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+    0x00cb: 0x2566,     #  BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+    0x00cc: 0x2560,     #  BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+    0x00cd: 0x2550,     #  BOX DRAWINGS DOUBLE HORIZONTAL
+    0x00ce: 0x256c,     #  BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+    0x00cf: 0x00a4,     #  CURRENCY SIGN
+    0x00d0: 0x00ba,     #  MASCULINE ORDINAL INDICATOR
+    0x00d1: 0x00aa,     #  FEMININE ORDINAL INDICATOR
+    0x00d2: 0x00ca,     #  LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+    0x00d3: 0x00cb,     #  LATIN CAPITAL LETTER E WITH DIAERESIS
+    0x00d4: 0x00c8,     #  LATIN CAPITAL LETTER E WITH GRAVE
+    0x00d5: None,       #  UNDEFINED
+    0x00d6: 0x00cd,     #  LATIN CAPITAL LETTER I WITH ACUTE
+    0x00d7: 0x00ce,     #  LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+    0x00d8: 0x00cf,     #  LATIN CAPITAL LETTER I WITH DIAERESIS
+    0x00d9: 0x2518,     #  BOX DRAWINGS LIGHT UP AND LEFT
+    0x00da: 0x250c,     #  BOX DRAWINGS LIGHT DOWN AND RIGHT
+    0x00db: 0x2588,     #  FULL BLOCK
+    0x00dc: 0x2584,     #  LOWER HALF BLOCK
+    0x00dd: 0x00a6,     #  BROKEN BAR
+    0x00de: 0x00cc,     #  LATIN CAPITAL LETTER I WITH GRAVE
+    0x00df: 0x2580,     #  UPPER HALF BLOCK
+    0x00e0: 0x00d3,     #  LATIN CAPITAL LETTER O WITH ACUTE
+    0x00e1: 0x00df,     #  LATIN SMALL LETTER SHARP S
+    0x00e2: 0x00d4,     #  LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+    0x00e3: 0x00d2,     #  LATIN CAPITAL LETTER O WITH GRAVE
+    0x00e4: 0x00f5,     #  LATIN SMALL LETTER O WITH TILDE
+    0x00e5: 0x00d5,     #  LATIN CAPITAL LETTER O WITH TILDE
+    0x00e6: 0x00b5,     #  MICRO SIGN
+    0x00e7: None,       #  UNDEFINED
+    0x00e8: 0x00d7,     #  MULTIPLICATION SIGN
+    0x00e9: 0x00da,     #  LATIN CAPITAL LETTER U WITH ACUTE
+    0x00ea: 0x00db,     #  LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+    0x00eb: 0x00d9,     #  LATIN CAPITAL LETTER U WITH GRAVE
+    0x00ed: 0x00ff,     #  LATIN SMALL LETTER Y WITH DIAERESIS
+    0x00ee: 0x00af,     #  MACRON
+    0x00ef: 0x00b4,     #  ACUTE ACCENT
+    0x00f0: 0x00ad,     #  SOFT HYPHEN
+    0x00f1: 0x00b1,     #  PLUS-MINUS SIGN
+    0x00f2: None,       #  UNDEFINED
+    0x00f3: 0x00be,     #  VULGAR FRACTION THREE QUARTERS
+    0x00f4: 0x00b6,     #  PILCROW SIGN
+    0x00f5: 0x00a7,     #  SECTION SIGN
+    0x00f6: 0x00f7,     #  DIVISION SIGN
+    0x00f7: 0x00b8,     #  CEDILLA
+    0x00f8: 0x00b0,     #  DEGREE SIGN
+    0x00f9: 0x00a8,     #  DIAERESIS
+    0x00fa: 0x00b7,     #  MIDDLE DOT
+    0x00fb: 0x00b9,     #  SUPERSCRIPT ONE
+    0x00fc: 0x00b3,     #  SUPERSCRIPT THREE
+    0x00fd: 0x00b2,     #  SUPERSCRIPT TWO
+    0x00fe: 0x25a0,     #  BLACK SQUARE
+    0x00ff: 0x00a0,     #  NO-BREAK SPACE
+})
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x0000 -> NULL
+    u'\x01'     #  0x0001 -> START OF HEADING
+    u'\x02'     #  0x0002 -> START OF TEXT
+    u'\x03'     #  0x0003 -> END OF TEXT
+    u'\x04'     #  0x0004 -> END OF TRANSMISSION
+    u'\x05'     #  0x0005 -> ENQUIRY
+    u'\x06'     #  0x0006 -> ACKNOWLEDGE
+    u'\x07'     #  0x0007 -> BELL
+    u'\x08'     #  0x0008 -> BACKSPACE
+    u'\t'       #  0x0009 -> HORIZONTAL TABULATION
+    u'\n'       #  0x000a -> LINE FEED
+    u'\x0b'     #  0x000b -> VERTICAL TABULATION
+    u'\x0c'     #  0x000c -> FORM FEED
+    u'\r'       #  0x000d -> CARRIAGE RETURN
+    u'\x0e'     #  0x000e -> SHIFT OUT
+    u'\x0f'     #  0x000f -> SHIFT IN
+    u'\x10'     #  0x0010 -> DATA LINK ESCAPE
+    u'\x11'     #  0x0011 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x0012 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x0013 -> DEVICE CONTROL THREE
+    u'\x14'     #  0x0014 -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x0015 -> NEGATIVE ACKNOWLEDGE
+    u'\x16'     #  0x0016 -> SYNCHRONOUS IDLE
+    u'\x17'     #  0x0017 -> END OF TRANSMISSION BLOCK
+    u'\x18'     #  0x0018 -> CANCEL
+    u'\x19'     #  0x0019 -> END OF MEDIUM
+    u'\x1a'     #  0x001a -> SUBSTITUTE
+    u'\x1b'     #  0x001b -> ESCAPE
+    u'\x1c'     #  0x001c -> FILE SEPARATOR
+    u'\x1d'     #  0x001d -> GROUP SEPARATOR
+    u'\x1e'     #  0x001e -> RECORD SEPARATOR
+    u'\x1f'     #  0x001f -> UNIT SEPARATOR
+    u' '        #  0x0020 -> SPACE
+    u'!'        #  0x0021 -> EXCLAMATION MARK
+    u'"'        #  0x0022 -> QUOTATION MARK
+    u'#'        #  0x0023 -> NUMBER SIGN
+    u'$'        #  0x0024 -> DOLLAR SIGN
+    u'%'        #  0x0025 -> PERCENT SIGN
+    u'&'        #  0x0026 -> AMPERSAND
+    u"'"        #  0x0027 -> APOSTROPHE
+    u'('        #  0x0028 -> LEFT PARENTHESIS
+    u')'        #  0x0029 -> RIGHT PARENTHESIS
+    u'*'        #  0x002a -> ASTERISK
+    u'+'        #  0x002b -> PLUS SIGN
+    u','        #  0x002c -> COMMA
+    u'-'        #  0x002d -> HYPHEN-MINUS
+    u'.'        #  0x002e -> FULL STOP
+    u'/'        #  0x002f -> SOLIDUS
+    u'0'        #  0x0030 -> DIGIT ZERO
+    u'1'        #  0x0031 -> DIGIT ONE
+    u'2'        #  0x0032 -> DIGIT TWO
+    u'3'        #  0x0033 -> DIGIT THREE
+    u'4'        #  0x0034 -> DIGIT FOUR
+    u'5'        #  0x0035 -> DIGIT FIVE
+    u'6'        #  0x0036 -> DIGIT SIX
+    u'7'        #  0x0037 -> DIGIT SEVEN
+    u'8'        #  0x0038 -> DIGIT EIGHT
+    u'9'        #  0x0039 -> DIGIT NINE
+    u':'        #  0x003a -> COLON
+    u';'        #  0x003b -> SEMICOLON
+    u'<'        #  0x003c -> LESS-THAN SIGN
+    u'='        #  0x003d -> EQUALS SIGN
+    u'>'        #  0x003e -> GREATER-THAN SIGN
+    u'?'        #  0x003f -> QUESTION MARK
+    u'@'        #  0x0040 -> COMMERCIAL AT
+    u'A'        #  0x0041 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x0042 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x0043 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x0044 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x0045 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x0046 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x0047 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x0048 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x0049 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x004a -> LATIN CAPITAL LETTER J
+    u'K'        #  0x004b -> LATIN CAPITAL LETTER K
+    u'L'        #  0x004c -> LATIN CAPITAL LETTER L
+    u'M'        #  0x004d -> LATIN CAPITAL LETTER M
+    u'N'        #  0x004e -> LATIN CAPITAL LETTER N
+    u'O'        #  0x004f -> LATIN CAPITAL LETTER O
+    u'P'        #  0x0050 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x0051 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x0052 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x0053 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x0054 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x0055 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x0056 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x0057 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x0058 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x0059 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x005a -> LATIN CAPITAL LETTER Z
+    u'['        #  0x005b -> LEFT SQUARE BRACKET
+    u'\\'       #  0x005c -> REVERSE SOLIDUS
+    u']'        #  0x005d -> RIGHT SQUARE BRACKET
+    u'^'        #  0x005e -> CIRCUMFLEX ACCENT
+    u'_'        #  0x005f -> LOW LINE
+    u'`'        #  0x0060 -> GRAVE ACCENT
+    u'a'        #  0x0061 -> LATIN SMALL LETTER A
+    u'b'        #  0x0062 -> LATIN SMALL LETTER B
+    u'c'        #  0x0063 -> LATIN SMALL LETTER C
+    u'd'        #  0x0064 -> LATIN SMALL LETTER D
+    u'e'        #  0x0065 -> LATIN SMALL LETTER E
+    u'f'        #  0x0066 -> LATIN SMALL LETTER F
+    u'g'        #  0x0067 -> LATIN SMALL LETTER G
+    u'h'        #  0x0068 -> LATIN SMALL LETTER H
+    u'i'        #  0x0069 -> LATIN SMALL LETTER I
+    u'j'        #  0x006a -> LATIN SMALL LETTER J
+    u'k'        #  0x006b -> LATIN SMALL LETTER K
+    u'l'        #  0x006c -> LATIN SMALL LETTER L
+    u'm'        #  0x006d -> LATIN SMALL LETTER M
+    u'n'        #  0x006e -> LATIN SMALL LETTER N
+    u'o'        #  0x006f -> LATIN SMALL LETTER O
+    u'p'        #  0x0070 -> LATIN SMALL LETTER P
+    u'q'        #  0x0071 -> LATIN SMALL LETTER Q
+    u'r'        #  0x0072 -> LATIN SMALL LETTER R
+    u's'        #  0x0073 -> LATIN SMALL LETTER S
+    u't'        #  0x0074 -> LATIN SMALL LETTER T
+    u'u'        #  0x0075 -> LATIN SMALL LETTER U
+    u'v'        #  0x0076 -> LATIN SMALL LETTER V
+    u'w'        #  0x0077 -> LATIN SMALL LETTER W
+    u'x'        #  0x0078 -> LATIN SMALL LETTER X
+    u'y'        #  0x0079 -> LATIN SMALL LETTER Y
+    u'z'        #  0x007a -> LATIN SMALL LETTER Z
+    u'{'        #  0x007b -> LEFT CURLY BRACKET
+    u'|'        #  0x007c -> VERTICAL LINE
+    u'}'        #  0x007d -> RIGHT CURLY BRACKET
+    u'~'        #  0x007e -> TILDE
+    u'\x7f'     #  0x007f -> DELETE
+    u'\xc7'     #  0x0080 -> LATIN CAPITAL LETTER C WITH CEDILLA
+    u'\xfc'     #  0x0081 -> LATIN SMALL LETTER U WITH DIAERESIS
+    u'\xe9'     #  0x0082 -> LATIN SMALL LETTER E WITH ACUTE
+    u'\xe2'     #  0x0083 -> LATIN SMALL LETTER A WITH CIRCUMFLEX
+    u'\xe4'     #  0x0084 -> LATIN SMALL LETTER A WITH DIAERESIS
+    u'\xe0'     #  0x0085 -> LATIN SMALL LETTER A WITH GRAVE
+    u'\xe5'     #  0x0086 -> LATIN SMALL LETTER A WITH RING ABOVE
+    u'\xe7'     #  0x0087 -> LATIN SMALL LETTER C WITH CEDILLA
+    u'\xea'     #  0x0088 -> LATIN SMALL LETTER E WITH CIRCUMFLEX
+    u'\xeb'     #  0x0089 -> LATIN SMALL LETTER E WITH DIAERESIS
+    u'\xe8'     #  0x008a -> LATIN SMALL LETTER E WITH GRAVE
+    u'\xef'     #  0x008b -> LATIN SMALL LETTER I WITH DIAERESIS
+    u'\xee'     #  0x008c -> LATIN SMALL LETTER I WITH CIRCUMFLEX
+    u'\u0131'   #  0x008d -> LATIN SMALL LETTER DOTLESS I
+    u'\xc4'     #  0x008e -> LATIN CAPITAL LETTER A WITH DIAERESIS
+    u'\xc5'     #  0x008f -> LATIN CAPITAL LETTER A WITH RING ABOVE
+    u'\xc9'     #  0x0090 -> LATIN CAPITAL LETTER E WITH ACUTE
+    u'\xe6'     #  0x0091 -> LATIN SMALL LIGATURE AE
+    u'\xc6'     #  0x0092 -> LATIN CAPITAL LIGATURE AE
+    u'\xf4'     #  0x0093 -> LATIN SMALL LETTER O WITH CIRCUMFLEX
+    u'\xf6'     #  0x0094 -> LATIN SMALL LETTER O WITH DIAERESIS
+    u'\xf2'     #  0x0095 -> LATIN SMALL LETTER O WITH GRAVE
+    u'\xfb'     #  0x0096 -> LATIN SMALL LETTER U WITH CIRCUMFLEX
+    u'\xf9'     #  0x0097 -> LATIN SMALL LETTER U WITH GRAVE
+    u'\u0130'   #  0x0098 -> LATIN CAPITAL LETTER I WITH DOT ABOVE
+    u'\xd6'     #  0x0099 -> LATIN CAPITAL LETTER O WITH DIAERESIS
+    u'\xdc'     #  0x009a -> LATIN CAPITAL LETTER U WITH DIAERESIS
+    u'\xf8'     #  0x009b -> LATIN SMALL LETTER O WITH STROKE
+    u'\xa3'     #  0x009c -> POUND SIGN
+    u'\xd8'     #  0x009d -> LATIN CAPITAL LETTER O WITH STROKE
+    u'\u015e'   #  0x009e -> LATIN CAPITAL LETTER S WITH CEDILLA
+    u'\u015f'   #  0x009f -> LATIN SMALL LETTER S WITH CEDILLA
+    u'\xe1'     #  0x00a0 -> LATIN SMALL LETTER A WITH ACUTE
+    u'\xed'     #  0x00a1 -> LATIN SMALL LETTER I WITH ACUTE
+    u'\xf3'     #  0x00a2 -> LATIN SMALL LETTER O WITH ACUTE
+    u'\xfa'     #  0x00a3 -> LATIN SMALL LETTER U WITH ACUTE
+    u'\xf1'     #  0x00a4 -> LATIN SMALL LETTER N WITH TILDE
+    u'\xd1'     #  0x00a5 -> LATIN CAPITAL LETTER N WITH TILDE
+    u'\u011e'   #  0x00a6 -> LATIN CAPITAL LETTER G WITH BREVE
+    u'\u011f'   #  0x00a7 -> LATIN SMALL LETTER G WITH BREVE
+    u'\xbf'     #  0x00a8 -> INVERTED QUESTION MARK
+    u'\xae'     #  0x00a9 -> REGISTERED SIGN
+    u'\xac'     #  0x00aa -> NOT SIGN
+    u'\xbd'     #  0x00ab -> VULGAR FRACTION ONE HALF
+    u'\xbc'     #  0x00ac -> VULGAR FRACTION ONE QUARTER
+    u'\xa1'     #  0x00ad -> INVERTED EXCLAMATION MARK
+    u'\xab'     #  0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xbb'     #  0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\u2591'   #  0x00b0 -> LIGHT SHADE
+    u'\u2592'   #  0x00b1 -> MEDIUM SHADE
+    u'\u2593'   #  0x00b2 -> DARK SHADE
+    u'\u2502'   #  0x00b3 -> BOX DRAWINGS LIGHT VERTICAL
+    u'\u2524'   #  0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT
+    u'\xc1'     #  0x00b5 -> LATIN CAPITAL LETTER A WITH ACUTE
+    u'\xc2'     #  0x00b6 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+    u'\xc0'     #  0x00b7 -> LATIN CAPITAL LETTER A WITH GRAVE
+    u'\xa9'     #  0x00b8 -> COPYRIGHT SIGN
+    u'\u2563'   #  0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+    u'\u2551'   #  0x00ba -> BOX DRAWINGS DOUBLE VERTICAL
+    u'\u2557'   #  0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT
+    u'\u255d'   #  0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT
+    u'\xa2'     #  0x00bd -> CENT SIGN
+    u'\xa5'     #  0x00be -> YEN SIGN
+    u'\u2510'   #  0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT
+    u'\u2514'   #  0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT
+    u'\u2534'   #  0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL
+    u'\u252c'   #  0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+    u'\u251c'   #  0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+    u'\u2500'   #  0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL
+    u'\u253c'   #  0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+    u'\xe3'     #  0x00c6 -> LATIN SMALL LETTER A WITH TILDE
+    u'\xc3'     #  0x00c7 -> LATIN CAPITAL LETTER A WITH TILDE
+    u'\u255a'   #  0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT
+    u'\u2554'   #  0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT
+    u'\u2569'   #  0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+    u'\u2566'   #  0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+    u'\u2560'   #  0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+    u'\u2550'   #  0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL
+    u'\u256c'   #  0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+    u'\xa4'     #  0x00cf -> CURRENCY SIGN
+    u'\xba'     #  0x00d0 -> MASCULINE ORDINAL INDICATOR
+    u'\xaa'     #  0x00d1 -> FEMININE ORDINAL INDICATOR
+    u'\xca'     #  0x00d2 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+    u'\xcb'     #  0x00d3 -> LATIN CAPITAL LETTER E WITH DIAERESIS
+    u'\xc8'     #  0x00d4 -> LATIN CAPITAL LETTER E WITH GRAVE
+    u'\ufffe'   #  0x00d5 -> UNDEFINED
+    u'\xcd'     #  0x00d6 -> LATIN CAPITAL LETTER I WITH ACUTE
+    u'\xce'     #  0x00d7 -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+    u'\xcf'     #  0x00d8 -> LATIN CAPITAL LETTER I WITH DIAERESIS
+    u'\u2518'   #  0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT
+    u'\u250c'   #  0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT
+    u'\u2588'   #  0x00db -> FULL BLOCK
+    u'\u2584'   #  0x00dc -> LOWER HALF BLOCK
+    u'\xa6'     #  0x00dd -> BROKEN BAR
+    u'\xcc'     #  0x00de -> LATIN CAPITAL LETTER I WITH GRAVE
+    u'\u2580'   #  0x00df -> UPPER HALF BLOCK
+    u'\xd3'     #  0x00e0 -> LATIN CAPITAL LETTER O WITH ACUTE
+    u'\xdf'     #  0x00e1 -> LATIN SMALL LETTER SHARP S
+    u'\xd4'     #  0x00e2 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+    u'\xd2'     #  0x00e3 -> LATIN CAPITAL LETTER O WITH GRAVE
+    u'\xf5'     #  0x00e4 -> LATIN SMALL LETTER O WITH TILDE
+    u'\xd5'     #  0x00e5 -> LATIN CAPITAL LETTER O WITH TILDE
+    u'\xb5'     #  0x00e6 -> MICRO SIGN
+    u'\ufffe'   #  0x00e7 -> UNDEFINED
+    u'\xd7'     #  0x00e8 -> MULTIPLICATION SIGN
+    u'\xda'     #  0x00e9 -> LATIN CAPITAL LETTER U WITH ACUTE
+    u'\xdb'     #  0x00ea -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+    u'\xd9'     #  0x00eb -> LATIN CAPITAL LETTER U WITH GRAVE
+    u'\xec'     #  0x00ec -> LATIN SMALL LETTER I WITH GRAVE
+    u'\xff'     #  0x00ed -> LATIN SMALL LETTER Y WITH DIAERESIS
+    u'\xaf'     #  0x00ee -> MACRON
+    u'\xb4'     #  0x00ef -> ACUTE ACCENT
+    u'\xad'     #  0x00f0 -> SOFT HYPHEN
+    u'\xb1'     #  0x00f1 -> PLUS-MINUS SIGN
+    u'\ufffe'   #  0x00f2 -> UNDEFINED
+    u'\xbe'     #  0x00f3 -> VULGAR FRACTION THREE QUARTERS
+    u'\xb6'     #  0x00f4 -> PILCROW SIGN
+    u'\xa7'     #  0x00f5 -> SECTION SIGN
+    u'\xf7'     #  0x00f6 -> DIVISION SIGN
+    u'\xb8'     #  0x00f7 -> CEDILLA
+    u'\xb0'     #  0x00f8 -> DEGREE SIGN
+    u'\xa8'     #  0x00f9 -> DIAERESIS
+    u'\xb7'     #  0x00fa -> MIDDLE DOT
+    u'\xb9'     #  0x00fb -> SUPERSCRIPT ONE
+    u'\xb3'     #  0x00fc -> SUPERSCRIPT THREE
+    u'\xb2'     #  0x00fd -> SUPERSCRIPT TWO
+    u'\u25a0'   #  0x00fe -> BLACK SQUARE
+    u'\xa0'     #  0x00ff -> NO-BREAK SPACE
+)
+
+### Encoding Map
+
+encoding_map = {
+    0x0000: 0x0000,     #  NULL
+    0x0001: 0x0001,     #  START OF HEADING
+    0x0002: 0x0002,     #  START OF TEXT
+    0x0003: 0x0003,     #  END OF TEXT
+    0x0004: 0x0004,     #  END OF TRANSMISSION
+    0x0005: 0x0005,     #  ENQUIRY
+    0x0006: 0x0006,     #  ACKNOWLEDGE
+    0x0007: 0x0007,     #  BELL
+    0x0008: 0x0008,     #  BACKSPACE
+    0x0009: 0x0009,     #  HORIZONTAL TABULATION
+    0x000a: 0x000a,     #  LINE FEED
+    0x000b: 0x000b,     #  VERTICAL TABULATION
+    0x000c: 0x000c,     #  FORM FEED
+    0x000d: 0x000d,     #  CARRIAGE RETURN
+    0x000e: 0x000e,     #  SHIFT OUT
+    0x000f: 0x000f,     #  SHIFT IN
+    0x0010: 0x0010,     #  DATA LINK ESCAPE
+    0x0011: 0x0011,     #  DEVICE CONTROL ONE
+    0x0012: 0x0012,     #  DEVICE CONTROL TWO
+    0x0013: 0x0013,     #  DEVICE CONTROL THREE
+    0x0014: 0x0014,     #  DEVICE CONTROL FOUR
+    0x0015: 0x0015,     #  NEGATIVE ACKNOWLEDGE
+    0x0016: 0x0016,     #  SYNCHRONOUS IDLE
+    0x0017: 0x0017,     #  END OF TRANSMISSION BLOCK
+    0x0018: 0x0018,     #  CANCEL
+    0x0019: 0x0019,     #  END OF MEDIUM
+    0x001a: 0x001a,     #  SUBSTITUTE
+    0x001b: 0x001b,     #  ESCAPE
+    0x001c: 0x001c,     #  FILE SEPARATOR
+    0x001d: 0x001d,     #  GROUP SEPARATOR
+    0x001e: 0x001e,     #  RECORD SEPARATOR
+    0x001f: 0x001f,     #  UNIT SEPARATOR
+    0x0020: 0x0020,     #  SPACE
+    0x0021: 0x0021,     #  EXCLAMATION MARK
+    0x0022: 0x0022,     #  QUOTATION MARK
+    0x0023: 0x0023,     #  NUMBER SIGN
+    0x0024: 0x0024,     #  DOLLAR SIGN
+    0x0025: 0x0025,     #  PERCENT SIGN
+    0x0026: 0x0026,     #  AMPERSAND
+    0x0027: 0x0027,     #  APOSTROPHE
+    0x0028: 0x0028,     #  LEFT PARENTHESIS
+    0x0029: 0x0029,     #  RIGHT PARENTHESIS
+    0x002a: 0x002a,     #  ASTERISK
+    0x002b: 0x002b,     #  PLUS SIGN
+    0x002c: 0x002c,     #  COMMA
+    0x002d: 0x002d,     #  HYPHEN-MINUS
+    0x002e: 0x002e,     #  FULL STOP
+    0x002f: 0x002f,     #  SOLIDUS
+    0x0030: 0x0030,     #  DIGIT ZERO
+    0x0031: 0x0031,     #  DIGIT ONE
+    0x0032: 0x0032,     #  DIGIT TWO
+    0x0033: 0x0033,     #  DIGIT THREE
+    0x0034: 0x0034,     #  DIGIT FOUR
+    0x0035: 0x0035,     #  DIGIT FIVE
+    0x0036: 0x0036,     #  DIGIT SIX
+    0x0037: 0x0037,     #  DIGIT SEVEN
+    0x0038: 0x0038,     #  DIGIT EIGHT
+    0x0039: 0x0039,     #  DIGIT NINE
+    0x003a: 0x003a,     #  COLON
+    0x003b: 0x003b,     #  SEMICOLON
+    0x003c: 0x003c,     #  LESS-THAN SIGN
+    0x003d: 0x003d,     #  EQUALS SIGN
+    0x003e: 0x003e,     #  GREATER-THAN SIGN
+    0x003f: 0x003f,     #  QUESTION MARK
+    0x0040: 0x0040,     #  COMMERCIAL AT
+    0x0041: 0x0041,     #  LATIN CAPITAL LETTER A
+    0x0042: 0x0042,     #  LATIN CAPITAL LETTER B
+    0x0043: 0x0043,     #  LATIN CAPITAL LETTER C
+    0x0044: 0x0044,     #  LATIN CAPITAL LETTER D
+    0x0045: 0x0045,     #  LATIN CAPITAL LETTER E
+    0x0046: 0x0046,     #  LATIN CAPITAL LETTER F
+    0x0047: 0x0047,     #  LATIN CAPITAL LETTER G
+    0x0048: 0x0048,     #  LATIN CAPITAL LETTER H
+    0x0049: 0x0049,     #  LATIN CAPITAL LETTER I
+    0x004a: 0x004a,     #  LATIN CAPITAL LETTER J
+    0x004b: 0x004b,     #  LATIN CAPITAL LETTER K
+    0x004c: 0x004c,     #  LATIN CAPITAL LETTER L
+    0x004d: 0x004d,     #  LATIN CAPITAL LETTER M
+    0x004e: 0x004e,     #  LATIN CAPITAL LETTER N
+    0x004f: 0x004f,     #  LATIN CAPITAL LETTER O
+    0x0050: 0x0050,     #  LATIN CAPITAL LETTER P
+    0x0051: 0x0051,     #  LATIN CAPITAL LETTER Q
+    0x0052: 0x0052,     #  LATIN CAPITAL LETTER R
+    0x0053: 0x0053,     #  LATIN CAPITAL LETTER S
+    0x0054: 0x0054,     #  LATIN CAPITAL LETTER T
+    0x0055: 0x0055,     #  LATIN CAPITAL LETTER U
+    0x0056: 0x0056,     #  LATIN CAPITAL LETTER V
+    0x0057: 0x0057,     #  LATIN CAPITAL LETTER W
+    0x0058: 0x0058,     #  LATIN CAPITAL LETTER X
+    0x0059: 0x0059,     #  LATIN CAPITAL LETTER Y
+    0x005a: 0x005a,     #  LATIN CAPITAL LETTER Z
+    0x005b: 0x005b,     #  LEFT SQUARE BRACKET
+    0x005c: 0x005c,     #  REVERSE SOLIDUS
+    0x005d: 0x005d,     #  RIGHT SQUARE BRACKET
+    0x005e: 0x005e,     #  CIRCUMFLEX ACCENT
+    0x005f: 0x005f,     #  LOW LINE
+    0x0060: 0x0060,     #  GRAVE ACCENT
+    0x0061: 0x0061,     #  LATIN SMALL LETTER A
+    0x0062: 0x0062,     #  LATIN SMALL LETTER B
+    0x0063: 0x0063,     #  LATIN SMALL LETTER C
+    0x0064: 0x0064,     #  LATIN SMALL LETTER D
+    0x0065: 0x0065,     #  LATIN SMALL LETTER E
+    0x0066: 0x0066,     #  LATIN SMALL LETTER F
+    0x0067: 0x0067,     #  LATIN SMALL LETTER G
+    0x0068: 0x0068,     #  LATIN SMALL LETTER H
+    0x0069: 0x0069,     #  LATIN SMALL LETTER I
+    0x006a: 0x006a,     #  LATIN SMALL LETTER J
+    0x006b: 0x006b,     #  LATIN SMALL LETTER K
+    0x006c: 0x006c,     #  LATIN SMALL LETTER L
+    0x006d: 0x006d,     #  LATIN SMALL LETTER M
+    0x006e: 0x006e,     #  LATIN SMALL LETTER N
+    0x006f: 0x006f,     #  LATIN SMALL LETTER O
+    0x0070: 0x0070,     #  LATIN SMALL LETTER P
+    0x0071: 0x0071,     #  LATIN SMALL LETTER Q
+    0x0072: 0x0072,     #  LATIN SMALL LETTER R
+    0x0073: 0x0073,     #  LATIN SMALL LETTER S
+    0x0074: 0x0074,     #  LATIN SMALL LETTER T
+    0x0075: 0x0075,     #  LATIN SMALL LETTER U
+    0x0076: 0x0076,     #  LATIN SMALL LETTER V
+    0x0077: 0x0077,     #  LATIN SMALL LETTER W
+    0x0078: 0x0078,     #  LATIN SMALL LETTER X
+    0x0079: 0x0079,     #  LATIN SMALL LETTER Y
+    0x007a: 0x007a,     #  LATIN SMALL LETTER Z
+    0x007b: 0x007b,     #  LEFT CURLY BRACKET
+    0x007c: 0x007c,     #  VERTICAL LINE
+    0x007d: 0x007d,     #  RIGHT CURLY BRACKET
+    0x007e: 0x007e,     #  TILDE
+    0x007f: 0x007f,     #  DELETE
+    0x00a0: 0x00ff,     #  NO-BREAK SPACE
+    0x00a1: 0x00ad,     #  INVERTED EXCLAMATION MARK
+    0x00a2: 0x00bd,     #  CENT SIGN
+    0x00a3: 0x009c,     #  POUND SIGN
+    0x00a4: 0x00cf,     #  CURRENCY SIGN
+    0x00a5: 0x00be,     #  YEN SIGN
+    0x00a6: 0x00dd,     #  BROKEN BAR
+    0x00a7: 0x00f5,     #  SECTION SIGN
+    0x00a8: 0x00f9,     #  DIAERESIS
+    0x00a9: 0x00b8,     #  COPYRIGHT SIGN
+    0x00aa: 0x00d1,     #  FEMININE ORDINAL INDICATOR
+    0x00ab: 0x00ae,     #  LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    0x00ac: 0x00aa,     #  NOT SIGN
+    0x00ad: 0x00f0,     #  SOFT HYPHEN
+    0x00ae: 0x00a9,     #  REGISTERED SIGN
+    0x00af: 0x00ee,     #  MACRON
+    0x00b0: 0x00f8,     #  DEGREE SIGN
+    0x00b1: 0x00f1,     #  PLUS-MINUS SIGN
+    0x00b2: 0x00fd,     #  SUPERSCRIPT TWO
+    0x00b3: 0x00fc,     #  SUPERSCRIPT THREE
+    0x00b4: 0x00ef,     #  ACUTE ACCENT
+    0x00b5: 0x00e6,     #  MICRO SIGN
+    0x00b6: 0x00f4,     #  PILCROW SIGN
+    0x00b7: 0x00fa,     #  MIDDLE DOT
+    0x00b8: 0x00f7,     #  CEDILLA
+    0x00b9: 0x00fb,     #  SUPERSCRIPT ONE
+    0x00ba: 0x00d0,     #  MASCULINE ORDINAL INDICATOR
+    0x00bb: 0x00af,     #  RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    0x00bc: 0x00ac,     #  VULGAR FRACTION ONE QUARTER
+    0x00bd: 0x00ab,     #  VULGAR FRACTION ONE HALF
+    0x00be: 0x00f3,     #  VULGAR FRACTION THREE QUARTERS
+    0x00bf: 0x00a8,     #  INVERTED QUESTION MARK
+    0x00c0: 0x00b7,     #  LATIN CAPITAL LETTER A WITH GRAVE
+    0x00c1: 0x00b5,     #  LATIN CAPITAL LETTER A WITH ACUTE
+    0x00c2: 0x00b6,     #  LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+    0x00c3: 0x00c7,     #  LATIN CAPITAL LETTER A WITH TILDE
+    0x00c4: 0x008e,     #  LATIN CAPITAL LETTER A WITH DIAERESIS
+    0x00c5: 0x008f,     #  LATIN CAPITAL LETTER A WITH RING ABOVE
+    0x00c6: 0x0092,     #  LATIN CAPITAL LIGATURE AE
+    0x00c7: 0x0080,     #  LATIN CAPITAL LETTER C WITH CEDILLA
+    0x00c8: 0x00d4,     #  LATIN CAPITAL LETTER E WITH GRAVE
+    0x00c9: 0x0090,     #  LATIN CAPITAL LETTER E WITH ACUTE
+    0x00ca: 0x00d2,     #  LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+    0x00cb: 0x00d3,     #  LATIN CAPITAL LETTER E WITH DIAERESIS
+    0x00cc: 0x00de,     #  LATIN CAPITAL LETTER I WITH GRAVE
+    0x00cd: 0x00d6,     #  LATIN CAPITAL LETTER I WITH ACUTE
+    0x00ce: 0x00d7,     #  LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+    0x00cf: 0x00d8,     #  LATIN CAPITAL LETTER I WITH DIAERESIS
+    0x00d1: 0x00a5,     #  LATIN CAPITAL LETTER N WITH TILDE
+    0x00d2: 0x00e3,     #  LATIN CAPITAL LETTER O WITH GRAVE
+    0x00d3: 0x00e0,     #  LATIN CAPITAL LETTER O WITH ACUTE
+    0x00d4: 0x00e2,     #  LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+    0x00d5: 0x00e5,     #  LATIN CAPITAL LETTER O WITH TILDE
+    0x00d6: 0x0099,     #  LATIN CAPITAL LETTER O WITH DIAERESIS
+    0x00d7: 0x00e8,     #  MULTIPLICATION SIGN
+    0x00d8: 0x009d,     #  LATIN CAPITAL LETTER O WITH STROKE
+    0x00d9: 0x00eb,     #  LATIN CAPITAL LETTER U WITH GRAVE
+    0x00da: 0x00e9,     #  LATIN CAPITAL LETTER U WITH ACUTE
+    0x00db: 0x00ea,     #  LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+    0x00dc: 0x009a,     #  LATIN CAPITAL LETTER U WITH DIAERESIS
+    0x00df: 0x00e1,     #  LATIN SMALL LETTER SHARP S
+    0x00e0: 0x0085,     #  LATIN SMALL LETTER A WITH GRAVE
+    0x00e1: 0x00a0,     #  LATIN SMALL LETTER A WITH ACUTE
+    0x00e2: 0x0083,     #  LATIN SMALL LETTER A WITH CIRCUMFLEX
+    0x00e3: 0x00c6,     #  LATIN SMALL LETTER A WITH TILDE
+    0x00e4: 0x0084,     #  LATIN SMALL LETTER A WITH DIAERESIS
+    0x00e5: 0x0086,     #  LATIN SMALL LETTER A WITH RING ABOVE
+    0x00e6: 0x0091,     #  LATIN SMALL LIGATURE AE
+    0x00e7: 0x0087,     #  LATIN SMALL LETTER C WITH CEDILLA
+    0x00e8: 0x008a,     #  LATIN SMALL LETTER E WITH GRAVE
+    0x00e9: 0x0082,     #  LATIN SMALL LETTER E WITH ACUTE
+    0x00ea: 0x0088,     #  LATIN SMALL LETTER E WITH CIRCUMFLEX
+    0x00eb: 0x0089,     #  LATIN SMALL LETTER E WITH DIAERESIS
+    0x00ec: 0x00ec,     #  LATIN SMALL LETTER I WITH GRAVE
+    0x00ed: 0x00a1,     #  LATIN SMALL LETTER I WITH ACUTE
+    0x00ee: 0x008c,     #  LATIN SMALL LETTER I WITH CIRCUMFLEX
+    0x00ef: 0x008b,     #  LATIN SMALL LETTER I WITH DIAERESIS
+    0x00f1: 0x00a4,     #  LATIN SMALL LETTER N WITH TILDE
+    0x00f2: 0x0095,     #  LATIN SMALL LETTER O WITH GRAVE
+    0x00f3: 0x00a2,     #  LATIN SMALL LETTER O WITH ACUTE
+    0x00f4: 0x0093,     #  LATIN SMALL LETTER O WITH CIRCUMFLEX
+    0x00f5: 0x00e4,     #  LATIN SMALL LETTER O WITH TILDE
+    0x00f6: 0x0094,     #  LATIN SMALL LETTER O WITH DIAERESIS
+    0x00f7: 0x00f6,     #  DIVISION SIGN
+    0x00f8: 0x009b,     #  LATIN SMALL LETTER O WITH STROKE
+    0x00f9: 0x0097,     #  LATIN SMALL LETTER U WITH GRAVE
+    0x00fa: 0x00a3,     #  LATIN SMALL LETTER U WITH ACUTE
+    0x00fb: 0x0096,     #  LATIN SMALL LETTER U WITH CIRCUMFLEX
+    0x00fc: 0x0081,     #  LATIN SMALL LETTER U WITH DIAERESIS
+    0x00ff: 0x00ed,     #  LATIN SMALL LETTER Y WITH DIAERESIS
+    0x011e: 0x00a6,     #  LATIN CAPITAL LETTER G WITH BREVE
+    0x011f: 0x00a7,     #  LATIN SMALL LETTER G WITH BREVE
+    0x0130: 0x0098,     #  LATIN CAPITAL LETTER I WITH DOT ABOVE
+    0x0131: 0x008d,     #  LATIN SMALL LETTER DOTLESS I
+    0x015e: 0x009e,     #  LATIN CAPITAL LETTER S WITH CEDILLA
+    0x015f: 0x009f,     #  LATIN SMALL LETTER S WITH CEDILLA
+    0x2500: 0x00c4,     #  BOX DRAWINGS LIGHT HORIZONTAL
+    0x2502: 0x00b3,     #  BOX DRAWINGS LIGHT VERTICAL
+    0x250c: 0x00da,     #  BOX DRAWINGS LIGHT DOWN AND RIGHT
+    0x2510: 0x00bf,     #  BOX DRAWINGS LIGHT DOWN AND LEFT
+    0x2514: 0x00c0,     #  BOX DRAWINGS LIGHT UP AND RIGHT
+    0x2518: 0x00d9,     #  BOX DRAWINGS LIGHT UP AND LEFT
+    0x251c: 0x00c3,     #  BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+    0x2524: 0x00b4,     #  BOX DRAWINGS LIGHT VERTICAL AND LEFT
+    0x252c: 0x00c2,     #  BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+    0x2534: 0x00c1,     #  BOX DRAWINGS LIGHT UP AND HORIZONTAL
+    0x253c: 0x00c5,     #  BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+    0x2550: 0x00cd,     #  BOX DRAWINGS DOUBLE HORIZONTAL
+    0x2551: 0x00ba,     #  BOX DRAWINGS DOUBLE VERTICAL
+    0x2554: 0x00c9,     #  BOX DRAWINGS DOUBLE DOWN AND RIGHT
+    0x2557: 0x00bb,     #  BOX DRAWINGS DOUBLE DOWN AND LEFT
+    0x255a: 0x00c8,     #  BOX DRAWINGS DOUBLE UP AND RIGHT
+    0x255d: 0x00bc,     #  BOX DRAWINGS DOUBLE UP AND LEFT
+    0x2560: 0x00cc,     #  BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+    0x2563: 0x00b9,     #  BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+    0x2566: 0x00cb,     #  BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+    0x2569: 0x00ca,     #  BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+    0x256c: 0x00ce,     #  BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+    0x2580: 0x00df,     #  UPPER HALF BLOCK
+    0x2584: 0x00dc,     #  LOWER HALF BLOCK
+    0x2588: 0x00db,     #  FULL BLOCK
+    0x2591: 0x00b0,     #  LIGHT SHADE
+    0x2592: 0x00b1,     #  MEDIUM SHADE
+    0x2593: 0x00b2,     #  DARK SHADE
+    0x25a0: 0x00fe,     #  BLACK SQUARE
+}

Added: vendor/Python/current/Lib/encodings/cp860.py
===================================================================
--- vendor/Python/current/Lib/encodings/cp860.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/cp860.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,698 @@
+""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP860.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_map)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='cp860',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+### Decoding Map
+
+decoding_map = codecs.make_identity_dict(range(256))
+decoding_map.update({
+    0x0080: 0x00c7,     #  LATIN CAPITAL LETTER C WITH CEDILLA
+    0x0081: 0x00fc,     #  LATIN SMALL LETTER U WITH DIAERESIS
+    0x0082: 0x00e9,     #  LATIN SMALL LETTER E WITH ACUTE
+    0x0083: 0x00e2,     #  LATIN SMALL LETTER A WITH CIRCUMFLEX
+    0x0084: 0x00e3,     #  LATIN SMALL LETTER A WITH TILDE
+    0x0085: 0x00e0,     #  LATIN SMALL LETTER A WITH GRAVE
+    0x0086: 0x00c1,     #  LATIN CAPITAL LETTER A WITH ACUTE
+    0x0087: 0x00e7,     #  LATIN SMALL LETTER C WITH CEDILLA
+    0x0088: 0x00ea,     #  LATIN SMALL LETTER E WITH CIRCUMFLEX
+    0x0089: 0x00ca,     #  LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+    0x008a: 0x00e8,     #  LATIN SMALL LETTER E WITH GRAVE
+    0x008b: 0x00cd,     #  LATIN CAPITAL LETTER I WITH ACUTE
+    0x008c: 0x00d4,     #  LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+    0x008d: 0x00ec,     #  LATIN SMALL LETTER I WITH GRAVE
+    0x008e: 0x00c3,     #  LATIN CAPITAL LETTER A WITH TILDE
+    0x008f: 0x00c2,     #  LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+    0x0090: 0x00c9,     #  LATIN CAPITAL LETTER E WITH ACUTE
+    0x0091: 0x00c0,     #  LATIN CAPITAL LETTER A WITH GRAVE
+    0x0092: 0x00c8,     #  LATIN CAPITAL LETTER E WITH GRAVE
+    0x0093: 0x00f4,     #  LATIN SMALL LETTER O WITH CIRCUMFLEX
+    0x0094: 0x00f5,     #  LATIN SMALL LETTER O WITH TILDE
+    0x0095: 0x00f2,     #  LATIN SMALL LETTER O WITH GRAVE
+    0x0096: 0x00da,     #  LATIN CAPITAL LETTER U WITH ACUTE
+    0x0097: 0x00f9,     #  LATIN SMALL LETTER U WITH GRAVE
+    0x0098: 0x00cc,     #  LATIN CAPITAL LETTER I WITH GRAVE
+    0x0099: 0x00d5,     #  LATIN CAPITAL LETTER O WITH TILDE
+    0x009a: 0x00dc,     #  LATIN CAPITAL LETTER U WITH DIAERESIS
+    0x009b: 0x00a2,     #  CENT SIGN
+    0x009c: 0x00a3,     #  POUND SIGN
+    0x009d: 0x00d9,     #  LATIN CAPITAL LETTER U WITH GRAVE
+    0x009e: 0x20a7,     #  PESETA SIGN
+    0x009f: 0x00d3,     #  LATIN CAPITAL LETTER O WITH ACUTE
+    0x00a0: 0x00e1,     #  LATIN SMALL LETTER A WITH ACUTE
+    0x00a1: 0x00ed,     #  LATIN SMALL LETTER I WITH ACUTE
+    0x00a2: 0x00f3,     #  LATIN SMALL LETTER O WITH ACUTE
+    0x00a3: 0x00fa,     #  LATIN SMALL LETTER U WITH ACUTE
+    0x00a4: 0x00f1,     #  LATIN SMALL LETTER N WITH TILDE
+    0x00a5: 0x00d1,     #  LATIN CAPITAL LETTER N WITH TILDE
+    0x00a6: 0x00aa,     #  FEMININE ORDINAL INDICATOR
+    0x00a7: 0x00ba,     #  MASCULINE ORDINAL INDICATOR
+    0x00a8: 0x00bf,     #  INVERTED QUESTION MARK
+    0x00a9: 0x00d2,     #  LATIN CAPITAL LETTER O WITH GRAVE
+    0x00aa: 0x00ac,     #  NOT SIGN
+    0x00ab: 0x00bd,     #  VULGAR FRACTION ONE HALF
+    0x00ac: 0x00bc,     #  VULGAR FRACTION ONE QUARTER
+    0x00ad: 0x00a1,     #  INVERTED EXCLAMATION MARK
+    0x00ae: 0x00ab,     #  LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    0x00af: 0x00bb,     #  RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    0x00b0: 0x2591,     #  LIGHT SHADE
+    0x00b1: 0x2592,     #  MEDIUM SHADE
+    0x00b2: 0x2593,     #  DARK SHADE
+    0x00b3: 0x2502,     #  BOX DRAWINGS LIGHT VERTICAL
+    0x00b4: 0x2524,     #  BOX DRAWINGS LIGHT VERTICAL AND LEFT
+    0x00b5: 0x2561,     #  BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+    0x00b6: 0x2562,     #  BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
+    0x00b7: 0x2556,     #  BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
+    0x00b8: 0x2555,     #  BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
+    0x00b9: 0x2563,     #  BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+    0x00ba: 0x2551,     #  BOX DRAWINGS DOUBLE VERTICAL
+    0x00bb: 0x2557,     #  BOX DRAWINGS DOUBLE DOWN AND LEFT
+    0x00bc: 0x255d,     #  BOX DRAWINGS DOUBLE UP AND LEFT
+    0x00bd: 0x255c,     #  BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
+    0x00be: 0x255b,     #  BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+    0x00bf: 0x2510,     #  BOX DRAWINGS LIGHT DOWN AND LEFT
+    0x00c0: 0x2514,     #  BOX DRAWINGS LIGHT UP AND RIGHT
+    0x00c1: 0x2534,     #  BOX DRAWINGS LIGHT UP AND HORIZONTAL
+    0x00c2: 0x252c,     #  BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+    0x00c3: 0x251c,     #  BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+    0x00c4: 0x2500,     #  BOX DRAWINGS LIGHT HORIZONTAL
+    0x00c5: 0x253c,     #  BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+    0x00c6: 0x255e,     #  BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+    0x00c7: 0x255f,     #  BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+    0x00c8: 0x255a,     #  BOX DRAWINGS DOUBLE UP AND RIGHT
+    0x00c9: 0x2554,     #  BOX DRAWINGS DOUBLE DOWN AND RIGHT
+    0x00ca: 0x2569,     #  BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+    0x00cb: 0x2566,     #  BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+    0x00cc: 0x2560,     #  BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+    0x00cd: 0x2550,     #  BOX DRAWINGS DOUBLE HORIZONTAL
+    0x00ce: 0x256c,     #  BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+    0x00cf: 0x2567,     #  BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+    0x00d0: 0x2568,     #  BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+    0x00d1: 0x2564,     #  BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
+    0x00d2: 0x2565,     #  BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
+    0x00d3: 0x2559,     #  BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+    0x00d4: 0x2558,     #  BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+    0x00d5: 0x2552,     #  BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+    0x00d6: 0x2553,     #  BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
+    0x00d7: 0x256b,     #  BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
+    0x00d8: 0x256a,     #  BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+    0x00d9: 0x2518,     #  BOX DRAWINGS LIGHT UP AND LEFT
+    0x00da: 0x250c,     #  BOX DRAWINGS LIGHT DOWN AND RIGHT
+    0x00db: 0x2588,     #  FULL BLOCK
+    0x00dc: 0x2584,     #  LOWER HALF BLOCK
+    0x00dd: 0x258c,     #  LEFT HALF BLOCK
+    0x00de: 0x2590,     #  RIGHT HALF BLOCK
+    0x00df: 0x2580,     #  UPPER HALF BLOCK
+    0x00e0: 0x03b1,     #  GREEK SMALL LETTER ALPHA
+    0x00e1: 0x00df,     #  LATIN SMALL LETTER SHARP S
+    0x00e2: 0x0393,     #  GREEK CAPITAL LETTER GAMMA
+    0x00e3: 0x03c0,     #  GREEK SMALL LETTER PI
+    0x00e4: 0x03a3,     #  GREEK CAPITAL LETTER SIGMA
+    0x00e5: 0x03c3,     #  GREEK SMALL LETTER SIGMA
+    0x00e6: 0x00b5,     #  MICRO SIGN
+    0x00e7: 0x03c4,     #  GREEK SMALL LETTER TAU
+    0x00e8: 0x03a6,     #  GREEK CAPITAL LETTER PHI
+    0x00e9: 0x0398,     #  GREEK CAPITAL LETTER THETA
+    0x00ea: 0x03a9,     #  GREEK CAPITAL LETTER OMEGA
+    0x00eb: 0x03b4,     #  GREEK SMALL LETTER DELTA
+    0x00ec: 0x221e,     #  INFINITY
+    0x00ed: 0x03c6,     #  GREEK SMALL LETTER PHI
+    0x00ee: 0x03b5,     #  GREEK SMALL LETTER EPSILON
+    0x00ef: 0x2229,     #  INTERSECTION
+    0x00f0: 0x2261,     #  IDENTICAL TO
+    0x00f1: 0x00b1,     #  PLUS-MINUS SIGN
+    0x00f2: 0x2265,     #  GREATER-THAN OR EQUAL TO
+    0x00f3: 0x2264,     #  LESS-THAN OR EQUAL TO
+    0x00f4: 0x2320,     #  TOP HALF INTEGRAL
+    0x00f5: 0x2321,     #  BOTTOM HALF INTEGRAL
+    0x00f6: 0x00f7,     #  DIVISION SIGN
+    0x00f7: 0x2248,     #  ALMOST EQUAL TO
+    0x00f8: 0x00b0,     #  DEGREE SIGN
+    0x00f9: 0x2219,     #  BULLET OPERATOR
+    0x00fa: 0x00b7,     #  MIDDLE DOT
+    0x00fb: 0x221a,     #  SQUARE ROOT
+    0x00fc: 0x207f,     #  SUPERSCRIPT LATIN SMALL LETTER N
+    0x00fd: 0x00b2,     #  SUPERSCRIPT TWO
+    0x00fe: 0x25a0,     #  BLACK SQUARE
+    0x00ff: 0x00a0,     #  NO-BREAK SPACE
+})
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x0000 -> NULL
+    u'\x01'     #  0x0001 -> START OF HEADING
+    u'\x02'     #  0x0002 -> START OF TEXT
+    u'\x03'     #  0x0003 -> END OF TEXT
+    u'\x04'     #  0x0004 -> END OF TRANSMISSION
+    u'\x05'     #  0x0005 -> ENQUIRY
+    u'\x06'     #  0x0006 -> ACKNOWLEDGE
+    u'\x07'     #  0x0007 -> BELL
+    u'\x08'     #  0x0008 -> BACKSPACE
+    u'\t'       #  0x0009 -> HORIZONTAL TABULATION
+    u'\n'       #  0x000a -> LINE FEED
+    u'\x0b'     #  0x000b -> VERTICAL TABULATION
+    u'\x0c'     #  0x000c -> FORM FEED
+    u'\r'       #  0x000d -> CARRIAGE RETURN
+    u'\x0e'     #  0x000e -> SHIFT OUT
+    u'\x0f'     #  0x000f -> SHIFT IN
+    u'\x10'     #  0x0010 -> DATA LINK ESCAPE
+    u'\x11'     #  0x0011 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x0012 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x0013 -> DEVICE CONTROL THREE
+    u'\x14'     #  0x0014 -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x0015 -> NEGATIVE ACKNOWLEDGE
+    u'\x16'     #  0x0016 -> SYNCHRONOUS IDLE
+    u'\x17'     #  0x0017 -> END OF TRANSMISSION BLOCK
+    u'\x18'     #  0x0018 -> CANCEL
+    u'\x19'     #  0x0019 -> END OF MEDIUM
+    u'\x1a'     #  0x001a -> SUBSTITUTE
+    u'\x1b'     #  0x001b -> ESCAPE
+    u'\x1c'     #  0x001c -> FILE SEPARATOR
+    u'\x1d'     #  0x001d -> GROUP SEPARATOR
+    u'\x1e'     #  0x001e -> RECORD SEPARATOR
+    u'\x1f'     #  0x001f -> UNIT SEPARATOR
+    u' '        #  0x0020 -> SPACE
+    u'!'        #  0x0021 -> EXCLAMATION MARK
+    u'"'        #  0x0022 -> QUOTATION MARK
+    u'#'        #  0x0023 -> NUMBER SIGN
+    u'$'        #  0x0024 -> DOLLAR SIGN
+    u'%'        #  0x0025 -> PERCENT SIGN
+    u'&'        #  0x0026 -> AMPERSAND
+    u"'"        #  0x0027 -> APOSTROPHE
+    u'('        #  0x0028 -> LEFT PARENTHESIS
+    u')'        #  0x0029 -> RIGHT PARENTHESIS
+    u'*'        #  0x002a -> ASTERISK
+    u'+'        #  0x002b -> PLUS SIGN
+    u','        #  0x002c -> COMMA
+    u'-'        #  0x002d -> HYPHEN-MINUS
+    u'.'        #  0x002e -> FULL STOP
+    u'/'        #  0x002f -> SOLIDUS
+    u'0'        #  0x0030 -> DIGIT ZERO
+    u'1'        #  0x0031 -> DIGIT ONE
+    u'2'        #  0x0032 -> DIGIT TWO
+    u'3'        #  0x0033 -> DIGIT THREE
+    u'4'        #  0x0034 -> DIGIT FOUR
+    u'5'        #  0x0035 -> DIGIT FIVE
+    u'6'        #  0x0036 -> DIGIT SIX
+    u'7'        #  0x0037 -> DIGIT SEVEN
+    u'8'        #  0x0038 -> DIGIT EIGHT
+    u'9'        #  0x0039 -> DIGIT NINE
+    u':'        #  0x003a -> COLON
+    u';'        #  0x003b -> SEMICOLON
+    u'<'        #  0x003c -> LESS-THAN SIGN
+    u'='        #  0x003d -> EQUALS SIGN
+    u'>'        #  0x003e -> GREATER-THAN SIGN
+    u'?'        #  0x003f -> QUESTION MARK
+    u'@'        #  0x0040 -> COMMERCIAL AT
+    u'A'        #  0x0041 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x0042 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x0043 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x0044 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x0045 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x0046 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x0047 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x0048 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x0049 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x004a -> LATIN CAPITAL LETTER J
+    u'K'        #  0x004b -> LATIN CAPITAL LETTER K
+    u'L'        #  0x004c -> LATIN CAPITAL LETTER L
+    u'M'        #  0x004d -> LATIN CAPITAL LETTER M
+    u'N'        #  0x004e -> LATIN CAPITAL LETTER N
+    u'O'        #  0x004f -> LATIN CAPITAL LETTER O
+    u'P'        #  0x0050 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x0051 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x0052 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x0053 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x0054 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x0055 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x0056 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x0057 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x0058 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x0059 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x005a -> LATIN CAPITAL LETTER Z
+    u'['        #  0x005b -> LEFT SQUARE BRACKET
+    u'\\'       #  0x005c -> REVERSE SOLIDUS
+    u']'        #  0x005d -> RIGHT SQUARE BRACKET
+    u'^'        #  0x005e -> CIRCUMFLEX ACCENT
+    u'_'        #  0x005f -> LOW LINE
+    u'`'        #  0x0060 -> GRAVE ACCENT
+    u'a'        #  0x0061 -> LATIN SMALL LETTER A
+    u'b'        #  0x0062 -> LATIN SMALL LETTER B
+    u'c'        #  0x0063 -> LATIN SMALL LETTER C
+    u'd'        #  0x0064 -> LATIN SMALL LETTER D
+    u'e'        #  0x0065 -> LATIN SMALL LETTER E
+    u'f'        #  0x0066 -> LATIN SMALL LETTER F
+    u'g'        #  0x0067 -> LATIN SMALL LETTER G
+    u'h'        #  0x0068 -> LATIN SMALL LETTER H
+    u'i'        #  0x0069 -> LATIN SMALL LETTER I
+    u'j'        #  0x006a -> LATIN SMALL LETTER J
+    u'k'        #  0x006b -> LATIN SMALL LETTER K
+    u'l'        #  0x006c -> LATIN SMALL LETTER L
+    u'm'        #  0x006d -> LATIN SMALL LETTER M
+    u'n'        #  0x006e -> LATIN SMALL LETTER N
+    u'o'        #  0x006f -> LATIN SMALL LETTER O
+    u'p'        #  0x0070 -> LATIN SMALL LETTER P
+    u'q'        #  0x0071 -> LATIN SMALL LETTER Q
+    u'r'        #  0x0072 -> LATIN SMALL LETTER R
+    u's'        #  0x0073 -> LATIN SMALL LETTER S
+    u't'        #  0x0074 -> LATIN SMALL LETTER T
+    u'u'        #  0x0075 -> LATIN SMALL LETTER U
+    u'v'        #  0x0076 -> LATIN SMALL LETTER V
+    u'w'        #  0x0077 -> LATIN SMALL LETTER W
+    u'x'        #  0x0078 -> LATIN SMALL LETTER X
+    u'y'        #  0x0079 -> LATIN SMALL LETTER Y
+    u'z'        #  0x007a -> LATIN SMALL LETTER Z
+    u'{'        #  0x007b -> LEFT CURLY BRACKET
+    u'|'        #  0x007c -> VERTICAL LINE
+    u'}'        #  0x007d -> RIGHT CURLY BRACKET
+    u'~'        #  0x007e -> TILDE
+    u'\x7f'     #  0x007f -> DELETE
+    u'\xc7'     #  0x0080 -> LATIN CAPITAL LETTER C WITH CEDILLA
+    u'\xfc'     #  0x0081 -> LATIN SMALL LETTER U WITH DIAERESIS
+    u'\xe9'     #  0x0082 -> LATIN SMALL LETTER E WITH ACUTE
+    u'\xe2'     #  0x0083 -> LATIN SMALL LETTER A WITH CIRCUMFLEX
+    u'\xe3'     #  0x0084 -> LATIN SMALL LETTER A WITH TILDE
+    u'\xe0'     #  0x0085 -> LATIN SMALL LETTER A WITH GRAVE
+    u'\xc1'     #  0x0086 -> LATIN CAPITAL LETTER A WITH ACUTE
+    u'\xe7'     #  0x0087 -> LATIN SMALL LETTER C WITH CEDILLA
+    u'\xea'     #  0x0088 -> LATIN SMALL LETTER E WITH CIRCUMFLEX
+    u'\xca'     #  0x0089 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+    u'\xe8'     #  0x008a -> LATIN SMALL LETTER E WITH GRAVE
+    u'\xcd'     #  0x008b -> LATIN CAPITAL LETTER I WITH ACUTE
+    u'\xd4'     #  0x008c -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+    u'\xec'     #  0x008d -> LATIN SMALL LETTER I WITH GRAVE
+    u'\xc3'     #  0x008e -> LATIN CAPITAL LETTER A WITH TILDE
+    u'\xc2'     #  0x008f -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+    u'\xc9'     #  0x0090 -> LATIN CAPITAL LETTER E WITH ACUTE
+    u'\xc0'     #  0x0091 -> LATIN CAPITAL LETTER A WITH GRAVE
+    u'\xc8'     #  0x0092 -> LATIN CAPITAL LETTER E WITH GRAVE
+    u'\xf4'     #  0x0093 -> LATIN SMALL LETTER O WITH CIRCUMFLEX
+    u'\xf5'     #  0x0094 -> LATIN SMALL LETTER O WITH TILDE
+    u'\xf2'     #  0x0095 -> LATIN SMALL LETTER O WITH GRAVE
+    u'\xda'     #  0x0096 -> LATIN CAPITAL LETTER U WITH ACUTE
+    u'\xf9'     #  0x0097 -> LATIN SMALL LETTER U WITH GRAVE
+    u'\xcc'     #  0x0098 -> LATIN CAPITAL LETTER I WITH GRAVE
+    u'\xd5'     #  0x0099 -> LATIN CAPITAL LETTER O WITH TILDE
+    u'\xdc'     #  0x009a -> LATIN CAPITAL LETTER U WITH DIAERESIS
+    u'\xa2'     #  0x009b -> CENT SIGN
+    u'\xa3'     #  0x009c -> POUND SIGN
+    u'\xd9'     #  0x009d -> LATIN CAPITAL LETTER U WITH GRAVE
+    u'\u20a7'   #  0x009e -> PESETA SIGN
+    u'\xd3'     #  0x009f -> LATIN CAPITAL LETTER O WITH ACUTE
+    u'\xe1'     #  0x00a0 -> LATIN SMALL LETTER A WITH ACUTE
+    u'\xed'     #  0x00a1 -> LATIN SMALL LETTER I WITH ACUTE
+    u'\xf3'     #  0x00a2 -> LATIN SMALL LETTER O WITH ACUTE
+    u'\xfa'     #  0x00a3 -> LATIN SMALL LETTER U WITH ACUTE
+    u'\xf1'     #  0x00a4 -> LATIN SMALL LETTER N WITH TILDE
+    u'\xd1'     #  0x00a5 -> LATIN CAPITAL LETTER N WITH TILDE
+    u'\xaa'     #  0x00a6 -> FEMININE ORDINAL INDICATOR
+    u'\xba'     #  0x00a7 -> MASCULINE ORDINAL INDICATOR
+    u'\xbf'     #  0x00a8 -> INVERTED QUESTION MARK
+    u'\xd2'     #  0x00a9 -> LATIN CAPITAL LETTER O WITH GRAVE
+    u'\xac'     #  0x00aa -> NOT SIGN
+    u'\xbd'     #  0x00ab -> VULGAR FRACTION ONE HALF
+    u'\xbc'     #  0x00ac -> VULGAR FRACTION ONE QUARTER
+    u'\xa1'     #  0x00ad -> INVERTED EXCLAMATION MARK
+    u'\xab'     #  0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xbb'     #  0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\u2591'   #  0x00b0 -> LIGHT SHADE
+    u'\u2592'   #  0x00b1 -> MEDIUM SHADE
+    u'\u2593'   #  0x00b2 -> DARK SHADE
+    u'\u2502'   #  0x00b3 -> BOX DRAWINGS LIGHT VERTICAL
+    u'\u2524'   #  0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT
+    u'\u2561'   #  0x00b5 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+    u'\u2562'   #  0x00b6 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
+    u'\u2556'   #  0x00b7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
+    u'\u2555'   #  0x00b8 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
+    u'\u2563'   #  0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+    u'\u2551'   #  0x00ba -> BOX DRAWINGS DOUBLE VERTICAL
+    u'\u2557'   #  0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT
+    u'\u255d'   #  0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT
+    u'\u255c'   #  0x00bd -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
+    u'\u255b'   #  0x00be -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+    u'\u2510'   #  0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT
+    u'\u2514'   #  0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT
+    u'\u2534'   #  0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL
+    u'\u252c'   #  0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+    u'\u251c'   #  0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+    u'\u2500'   #  0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL
+    u'\u253c'   #  0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+    u'\u255e'   #  0x00c6 -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+    u'\u255f'   #  0x00c7 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+    u'\u255a'   #  0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT
+    u'\u2554'   #  0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT
+    u'\u2569'   #  0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+    u'\u2566'   #  0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+    u'\u2560'   #  0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+    u'\u2550'   #  0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL
+    u'\u256c'   #  0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+    u'\u2567'   #  0x00cf -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+    u'\u2568'   #  0x00d0 -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+    u'\u2564'   #  0x00d1 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
+    u'\u2565'   #  0x00d2 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
+    u'\u2559'   #  0x00d3 -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+    u'\u2558'   #  0x00d4 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+    u'\u2552'   #  0x00d5 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+    u'\u2553'   #  0x00d6 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
+    u'\u256b'   #  0x00d7 -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
+    u'\u256a'   #  0x00d8 -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+    u'\u2518'   #  0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT
+    u'\u250c'   #  0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT
+    u'\u2588'   #  0x00db -> FULL BLOCK
+    u'\u2584'   #  0x00dc -> LOWER HALF BLOCK
+    u'\u258c'   #  0x00dd -> LEFT HALF BLOCK
+    u'\u2590'   #  0x00de -> RIGHT HALF BLOCK
+    u'\u2580'   #  0x00df -> UPPER HALF BLOCK
+    u'\u03b1'   #  0x00e0 -> GREEK SMALL LETTER ALPHA
+    u'\xdf'     #  0x00e1 -> LATIN SMALL LETTER SHARP S
+    u'\u0393'   #  0x00e2 -> GREEK CAPITAL LETTER GAMMA
+    u'\u03c0'   #  0x00e3 -> GREEK SMALL LETTER PI
+    u'\u03a3'   #  0x00e4 -> GREEK CAPITAL LETTER SIGMA
+    u'\u03c3'   #  0x00e5 -> GREEK SMALL LETTER SIGMA
+    u'\xb5'     #  0x00e6 -> MICRO SIGN
+    u'\u03c4'   #  0x00e7 -> GREEK SMALL LETTER TAU
+    u'\u03a6'   #  0x00e8 -> GREEK CAPITAL LETTER PHI
+    u'\u0398'   #  0x00e9 -> GREEK CAPITAL LETTER THETA
+    u'\u03a9'   #  0x00ea -> GREEK CAPITAL LETTER OMEGA
+    u'\u03b4'   #  0x00eb -> GREEK SMALL LETTER DELTA
+    u'\u221e'   #  0x00ec -> INFINITY
+    u'\u03c6'   #  0x00ed -> GREEK SMALL LETTER PHI
+    u'\u03b5'   #  0x00ee -> GREEK SMALL LETTER EPSILON
+    u'\u2229'   #  0x00ef -> INTERSECTION
+    u'\u2261'   #  0x00f0 -> IDENTICAL TO
+    u'\xb1'     #  0x00f1 -> PLUS-MINUS SIGN
+    u'\u2265'   #  0x00f2 -> GREATER-THAN OR EQUAL TO
+    u'\u2264'   #  0x00f3 -> LESS-THAN OR EQUAL TO
+    u'\u2320'   #  0x00f4 -> TOP HALF INTEGRAL
+    u'\u2321'   #  0x00f5 -> BOTTOM HALF INTEGRAL
+    u'\xf7'     #  0x00f6 -> DIVISION SIGN
+    u'\u2248'   #  0x00f7 -> ALMOST EQUAL TO
+    u'\xb0'     #  0x00f8 -> DEGREE SIGN
+    u'\u2219'   #  0x00f9 -> BULLET OPERATOR
+    u'\xb7'     #  0x00fa -> MIDDLE DOT
+    u'\u221a'   #  0x00fb -> SQUARE ROOT
+    u'\u207f'   #  0x00fc -> SUPERSCRIPT LATIN SMALL LETTER N
+    u'\xb2'     #  0x00fd -> SUPERSCRIPT TWO
+    u'\u25a0'   #  0x00fe -> BLACK SQUARE
+    u'\xa0'     #  0x00ff -> NO-BREAK SPACE
+)
+
+### Encoding Map
+
+encoding_map = {
+    0x0000: 0x0000,     #  NULL
+    0x0001: 0x0001,     #  START OF HEADING
+    0x0002: 0x0002,     #  START OF TEXT
+    0x0003: 0x0003,     #  END OF TEXT
+    0x0004: 0x0004,     #  END OF TRANSMISSION
+    0x0005: 0x0005,     #  ENQUIRY
+    0x0006: 0x0006,     #  ACKNOWLEDGE
+    0x0007: 0x0007,     #  BELL
+    0x0008: 0x0008,     #  BACKSPACE
+    0x0009: 0x0009,     #  HORIZONTAL TABULATION
+    0x000a: 0x000a,     #  LINE FEED
+    0x000b: 0x000b,     #  VERTICAL TABULATION
+    0x000c: 0x000c,     #  FORM FEED
+    0x000d: 0x000d,     #  CARRIAGE RETURN
+    0x000e: 0x000e,     #  SHIFT OUT
+    0x000f: 0x000f,     #  SHIFT IN
+    0x0010: 0x0010,     #  DATA LINK ESCAPE
+    0x0011: 0x0011,     #  DEVICE CONTROL ONE
+    0x0012: 0x0012,     #  DEVICE CONTROL TWO
+    0x0013: 0x0013,     #  DEVICE CONTROL THREE
+    0x0014: 0x0014,     #  DEVICE CONTROL FOUR
+    0x0015: 0x0015,     #  NEGATIVE ACKNOWLEDGE
+    0x0016: 0x0016,     #  SYNCHRONOUS IDLE
+    0x0017: 0x0017,     #  END OF TRANSMISSION BLOCK
+    0x0018: 0x0018,     #  CANCEL
+    0x0019: 0x0019,     #  END OF MEDIUM
+    0x001a: 0x001a,     #  SUBSTITUTE
+    0x001b: 0x001b,     #  ESCAPE
+    0x001c: 0x001c,     #  FILE SEPARATOR
+    0x001d: 0x001d,     #  GROUP SEPARATOR
+    0x001e: 0x001e,     #  RECORD SEPARATOR
+    0x001f: 0x001f,     #  UNIT SEPARATOR
+    0x0020: 0x0020,     #  SPACE
+    0x0021: 0x0021,     #  EXCLAMATION MARK
+    0x0022: 0x0022,     #  QUOTATION MARK
+    0x0023: 0x0023,     #  NUMBER SIGN
+    0x0024: 0x0024,     #  DOLLAR SIGN
+    0x0025: 0x0025,     #  PERCENT SIGN
+    0x0026: 0x0026,     #  AMPERSAND
+    0x0027: 0x0027,     #  APOSTROPHE
+    0x0028: 0x0028,     #  LEFT PARENTHESIS
+    0x0029: 0x0029,     #  RIGHT PARENTHESIS
+    0x002a: 0x002a,     #  ASTERISK
+    0x002b: 0x002b,     #  PLUS SIGN
+    0x002c: 0x002c,     #  COMMA
+    0x002d: 0x002d,     #  HYPHEN-MINUS
+    0x002e: 0x002e,     #  FULL STOP
+    0x002f: 0x002f,     #  SOLIDUS
+    0x0030: 0x0030,     #  DIGIT ZERO
+    0x0031: 0x0031,     #  DIGIT ONE
+    0x0032: 0x0032,     #  DIGIT TWO
+    0x0033: 0x0033,     #  DIGIT THREE
+    0x0034: 0x0034,     #  DIGIT FOUR
+    0x0035: 0x0035,     #  DIGIT FIVE
+    0x0036: 0x0036,     #  DIGIT SIX
+    0x0037: 0x0037,     #  DIGIT SEVEN
+    0x0038: 0x0038,     #  DIGIT EIGHT
+    0x0039: 0x0039,     #  DIGIT NINE
+    0x003a: 0x003a,     #  COLON
+    0x003b: 0x003b,     #  SEMICOLON
+    0x003c: 0x003c,     #  LESS-THAN SIGN
+    0x003d: 0x003d,     #  EQUALS SIGN
+    0x003e: 0x003e,     #  GREATER-THAN SIGN
+    0x003f: 0x003f,     #  QUESTION MARK
+    0x0040: 0x0040,     #  COMMERCIAL AT
+    0x0041: 0x0041,     #  LATIN CAPITAL LETTER A
+    0x0042: 0x0042,     #  LATIN CAPITAL LETTER B
+    0x0043: 0x0043,     #  LATIN CAPITAL LETTER C
+    0x0044: 0x0044,     #  LATIN CAPITAL LETTER D
+    0x0045: 0x0045,     #  LATIN CAPITAL LETTER E
+    0x0046: 0x0046,     #  LATIN CAPITAL LETTER F
+    0x0047: 0x0047,     #  LATIN CAPITAL LETTER G
+    0x0048: 0x0048,     #  LATIN CAPITAL LETTER H
+    0x0049: 0x0049,     #  LATIN CAPITAL LETTER I
+    0x004a: 0x004a,     #  LATIN CAPITAL LETTER J
+    0x004b: 0x004b,     #  LATIN CAPITAL LETTER K
+    0x004c: 0x004c,     #  LATIN CAPITAL LETTER L
+    0x004d: 0x004d,     #  LATIN CAPITAL LETTER M
+    0x004e: 0x004e,     #  LATIN CAPITAL LETTER N
+    0x004f: 0x004f,     #  LATIN CAPITAL LETTER O
+    0x0050: 0x0050,     #  LATIN CAPITAL LETTER P
+    0x0051: 0x0051,     #  LATIN CAPITAL LETTER Q
+    0x0052: 0x0052,     #  LATIN CAPITAL LETTER R
+    0x0053: 0x0053,     #  LATIN CAPITAL LETTER S
+    0x0054: 0x0054,     #  LATIN CAPITAL LETTER T
+    0x0055: 0x0055,     #  LATIN CAPITAL LETTER U
+    0x0056: 0x0056,     #  LATIN CAPITAL LETTER V
+    0x0057: 0x0057,     #  LATIN CAPITAL LETTER W
+    0x0058: 0x0058,     #  LATIN CAPITAL LETTER X
+    0x0059: 0x0059,     #  LATIN CAPITAL LETTER Y
+    0x005a: 0x005a,     #  LATIN CAPITAL LETTER Z
+    0x005b: 0x005b,     #  LEFT SQUARE BRACKET
+    0x005c: 0x005c,     #  REVERSE SOLIDUS
+    0x005d: 0x005d,     #  RIGHT SQUARE BRACKET
+    0x005e: 0x005e,     #  CIRCUMFLEX ACCENT
+    0x005f: 0x005f,     #  LOW LINE
+    0x0060: 0x0060,     #  GRAVE ACCENT
+    0x0061: 0x0061,     #  LATIN SMALL LETTER A
+    0x0062: 0x0062,     #  LATIN SMALL LETTER B
+    0x0063: 0x0063,     #  LATIN SMALL LETTER C
+    0x0064: 0x0064,     #  LATIN SMALL LETTER D
+    0x0065: 0x0065,     #  LATIN SMALL LETTER E
+    0x0066: 0x0066,     #  LATIN SMALL LETTER F
+    0x0067: 0x0067,     #  LATIN SMALL LETTER G
+    0x0068: 0x0068,     #  LATIN SMALL LETTER H
+    0x0069: 0x0069,     #  LATIN SMALL LETTER I
+    0x006a: 0x006a,     #  LATIN SMALL LETTER J
+    0x006b: 0x006b,     #  LATIN SMALL LETTER K
+    0x006c: 0x006c,     #  LATIN SMALL LETTER L
+    0x006d: 0x006d,     #  LATIN SMALL LETTER M
+    0x006e: 0x006e,     #  LATIN SMALL LETTER N
+    0x006f: 0x006f,     #  LATIN SMALL LETTER O
+    0x0070: 0x0070,     #  LATIN SMALL LETTER P
+    0x0071: 0x0071,     #  LATIN SMALL LETTER Q
+    0x0072: 0x0072,     #  LATIN SMALL LETTER R
+    0x0073: 0x0073,     #  LATIN SMALL LETTER S
+    0x0074: 0x0074,     #  LATIN SMALL LETTER T
+    0x0075: 0x0075,     #  LATIN SMALL LETTER U
+    0x0076: 0x0076,     #  LATIN SMALL LETTER V
+    0x0077: 0x0077,     #  LATIN SMALL LETTER W
+    0x0078: 0x0078,     #  LATIN SMALL LETTER X
+    0x0079: 0x0079,     #  LATIN SMALL LETTER Y
+    0x007a: 0x007a,     #  LATIN SMALL LETTER Z
+    0x007b: 0x007b,     #  LEFT CURLY BRACKET
+    0x007c: 0x007c,     #  VERTICAL LINE
+    0x007d: 0x007d,     #  RIGHT CURLY BRACKET
+    0x007e: 0x007e,     #  TILDE
+    0x007f: 0x007f,     #  DELETE
+    0x00a0: 0x00ff,     #  NO-BREAK SPACE
+    0x00a1: 0x00ad,     #  INVERTED EXCLAMATION MARK
+    0x00a2: 0x009b,     #  CENT SIGN
+    0x00a3: 0x009c,     #  POUND SIGN
+    0x00aa: 0x00a6,     #  FEMININE ORDINAL INDICATOR
+    0x00ab: 0x00ae,     #  LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    0x00ac: 0x00aa,     #  NOT SIGN
+    0x00b0: 0x00f8,     #  DEGREE SIGN
+    0x00b1: 0x00f1,     #  PLUS-MINUS SIGN
+    0x00b2: 0x00fd,     #  SUPERSCRIPT TWO
+    0x00b5: 0x00e6,     #  MICRO SIGN
+    0x00b7: 0x00fa,     #  MIDDLE DOT
+    0x00ba: 0x00a7,     #  MASCULINE ORDINAL INDICATOR
+    0x00bb: 0x00af,     #  RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    0x00bc: 0x00ac,     #  VULGAR FRACTION ONE QUARTER
+    0x00bd: 0x00ab,     #  VULGAR FRACTION ONE HALF
+    0x00bf: 0x00a8,     #  INVERTED QUESTION MARK
+    0x00c0: 0x0091,     #  LATIN CAPITAL LETTER A WITH GRAVE
+    0x00c1: 0x0086,     #  LATIN CAPITAL LETTER A WITH ACUTE
+    0x00c2: 0x008f,     #  LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+    0x00c3: 0x008e,     #  LATIN CAPITAL LETTER A WITH TILDE
+    0x00c7: 0x0080,     #  LATIN CAPITAL LETTER C WITH CEDILLA
+    0x00c8: 0x0092,     #  LATIN CAPITAL LETTER E WITH GRAVE
+    0x00c9: 0x0090,     #  LATIN CAPITAL LETTER E WITH ACUTE
+    0x00ca: 0x0089,     #  LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+    0x00cc: 0x0098,     #  LATIN CAPITAL LETTER I WITH GRAVE
+    0x00cd: 0x008b,     #  LATIN CAPITAL LETTER I WITH ACUTE
+    0x00d1: 0x00a5,     #  LATIN CAPITAL LETTER N WITH TILDE
+    0x00d2: 0x00a9,     #  LATIN CAPITAL LETTER O WITH GRAVE
+    0x00d3: 0x009f,     #  LATIN CAPITAL LETTER O WITH ACUTE
+    0x00d4: 0x008c,     #  LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+    0x00d5: 0x0099,     #  LATIN CAPITAL LETTER O WITH TILDE
+    0x00d9: 0x009d,     #  LATIN CAPITAL LETTER U WITH GRAVE
+    0x00da: 0x0096,     #  LATIN CAPITAL LETTER U WITH ACUTE
+    0x00dc: 0x009a,     #  LATIN CAPITAL LETTER U WITH DIAERESIS
+    0x00df: 0x00e1,     #  LATIN SMALL LETTER SHARP S
+    0x00e0: 0x0085,     #  LATIN SMALL LETTER A WITH GRAVE
+    0x00e1: 0x00a0,     #  LATIN SMALL LETTER A WITH ACUTE
+    0x00e2: 0x0083,     #  LATIN SMALL LETTER A WITH CIRCUMFLEX
+    0x00e3: 0x0084,     #  LATIN SMALL LETTER A WITH TILDE
+    0x00e7: 0x0087,     #  LATIN SMALL LETTER C WITH CEDILLA
+    0x00e8: 0x008a,     #  LATIN SMALL LETTER E WITH GRAVE
+    0x00e9: 0x0082,     #  LATIN SMALL LETTER E WITH ACUTE
+    0x00ea: 0x0088,     #  LATIN SMALL LETTER E WITH CIRCUMFLEX
+    0x00ec: 0x008d,     #  LATIN SMALL LETTER I WITH GRAVE
+    0x00ed: 0x00a1,     #  LATIN SMALL LETTER I WITH ACUTE
+    0x00f1: 0x00a4,     #  LATIN SMALL LETTER N WITH TILDE
+    0x00f2: 0x0095,     #  LATIN SMALL LETTER O WITH GRAVE
+    0x00f3: 0x00a2,     #  LATIN SMALL LETTER O WITH ACUTE
+    0x00f4: 0x0093,     #  LATIN SMALL LETTER O WITH CIRCUMFLEX
+    0x00f5: 0x0094,     #  LATIN SMALL LETTER O WITH TILDE
+    0x00f7: 0x00f6,     #  DIVISION SIGN
+    0x00f9: 0x0097,     #  LATIN SMALL LETTER U WITH GRAVE
+    0x00fa: 0x00a3,     #  LATIN SMALL LETTER U WITH ACUTE
+    0x00fc: 0x0081,     #  LATIN SMALL LETTER U WITH DIAERESIS
+    0x0393: 0x00e2,     #  GREEK CAPITAL LETTER GAMMA
+    0x0398: 0x00e9,     #  GREEK CAPITAL LETTER THETA
+    0x03a3: 0x00e4,     #  GREEK CAPITAL LETTER SIGMA
+    0x03a6: 0x00e8,     #  GREEK CAPITAL LETTER PHI
+    0x03a9: 0x00ea,     #  GREEK CAPITAL LETTER OMEGA
+    0x03b1: 0x00e0,     #  GREEK SMALL LETTER ALPHA
+    0x03b4: 0x00eb,     #  GREEK SMALL LETTER DELTA
+    0x03b5: 0x00ee,     #  GREEK SMALL LETTER EPSILON
+    0x03c0: 0x00e3,     #  GREEK SMALL LETTER PI
+    0x03c3: 0x00e5,     #  GREEK SMALL LETTER SIGMA
+    0x03c4: 0x00e7,     #  GREEK SMALL LETTER TAU
+    0x03c6: 0x00ed,     #  GREEK SMALL LETTER PHI
+    0x207f: 0x00fc,     #  SUPERSCRIPT LATIN SMALL LETTER N
+    0x20a7: 0x009e,     #  PESETA SIGN
+    0x2219: 0x00f9,     #  BULLET OPERATOR
+    0x221a: 0x00fb,     #  SQUARE ROOT
+    0x221e: 0x00ec,     #  INFINITY
+    0x2229: 0x00ef,     #  INTERSECTION
+    0x2248: 0x00f7,     #  ALMOST EQUAL TO
+    0x2261: 0x00f0,     #  IDENTICAL TO
+    0x2264: 0x00f3,     #  LESS-THAN OR EQUAL TO
+    0x2265: 0x00f2,     #  GREATER-THAN OR EQUAL TO
+    0x2320: 0x00f4,     #  TOP HALF INTEGRAL
+    0x2321: 0x00f5,     #  BOTTOM HALF INTEGRAL
+    0x2500: 0x00c4,     #  BOX DRAWINGS LIGHT HORIZONTAL
+    0x2502: 0x00b3,     #  BOX DRAWINGS LIGHT VERTICAL
+    0x250c: 0x00da,     #  BOX DRAWINGS LIGHT DOWN AND RIGHT
+    0x2510: 0x00bf,     #  BOX DRAWINGS LIGHT DOWN AND LEFT
+    0x2514: 0x00c0,     #  BOX DRAWINGS LIGHT UP AND RIGHT
+    0x2518: 0x00d9,     #  BOX DRAWINGS LIGHT UP AND LEFT
+    0x251c: 0x00c3,     #  BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+    0x2524: 0x00b4,     #  BOX DRAWINGS LIGHT VERTICAL AND LEFT
+    0x252c: 0x00c2,     #  BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+    0x2534: 0x00c1,     #  BOX DRAWINGS LIGHT UP AND HORIZONTAL
+    0x253c: 0x00c5,     #  BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+    0x2550: 0x00cd,     #  BOX DRAWINGS DOUBLE HORIZONTAL
+    0x2551: 0x00ba,     #  BOX DRAWINGS DOUBLE VERTICAL
+    0x2552: 0x00d5,     #  BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+    0x2553: 0x00d6,     #  BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
+    0x2554: 0x00c9,     #  BOX DRAWINGS DOUBLE DOWN AND RIGHT
+    0x2555: 0x00b8,     #  BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
+    0x2556: 0x00b7,     #  BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
+    0x2557: 0x00bb,     #  BOX DRAWINGS DOUBLE DOWN AND LEFT
+    0x2558: 0x00d4,     #  BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+    0x2559: 0x00d3,     #  BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+    0x255a: 0x00c8,     #  BOX DRAWINGS DOUBLE UP AND RIGHT
+    0x255b: 0x00be,     #  BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+    0x255c: 0x00bd,     #  BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
+    0x255d: 0x00bc,     #  BOX DRAWINGS DOUBLE UP AND LEFT
+    0x255e: 0x00c6,     #  BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+    0x255f: 0x00c7,     #  BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+    0x2560: 0x00cc,     #  BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+    0x2561: 0x00b5,     #  BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+    0x2562: 0x00b6,     #  BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
+    0x2563: 0x00b9,     #  BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+    0x2564: 0x00d1,     #  BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
+    0x2565: 0x00d2,     #  BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
+    0x2566: 0x00cb,     #  BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+    0x2567: 0x00cf,     #  BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+    0x2568: 0x00d0,     #  BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+    0x2569: 0x00ca,     #  BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+    0x256a: 0x00d8,     #  BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+    0x256b: 0x00d7,     #  BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
+    0x256c: 0x00ce,     #  BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+    0x2580: 0x00df,     #  UPPER HALF BLOCK
+    0x2584: 0x00dc,     #  LOWER HALF BLOCK
+    0x2588: 0x00db,     #  FULL BLOCK
+    0x258c: 0x00dd,     #  LEFT HALF BLOCK
+    0x2590: 0x00de,     #  RIGHT HALF BLOCK
+    0x2591: 0x00b0,     #  LIGHT SHADE
+    0x2592: 0x00b1,     #  MEDIUM SHADE
+    0x2593: 0x00b2,     #  DARK SHADE
+    0x25a0: 0x00fe,     #  BLACK SQUARE
+}

Added: vendor/Python/current/Lib/encodings/cp861.py
===================================================================
--- vendor/Python/current/Lib/encodings/cp861.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/cp861.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,698 @@
+""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP861.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_map)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='cp861',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+### Decoding Map
+
+decoding_map = codecs.make_identity_dict(range(256))
+decoding_map.update({
+    0x0080: 0x00c7,     #  LATIN CAPITAL LETTER C WITH CEDILLA
+    0x0081: 0x00fc,     #  LATIN SMALL LETTER U WITH DIAERESIS
+    0x0082: 0x00e9,     #  LATIN SMALL LETTER E WITH ACUTE
+    0x0083: 0x00e2,     #  LATIN SMALL LETTER A WITH CIRCUMFLEX
+    0x0084: 0x00e4,     #  LATIN SMALL LETTER A WITH DIAERESIS
+    0x0085: 0x00e0,     #  LATIN SMALL LETTER A WITH GRAVE
+    0x0086: 0x00e5,     #  LATIN SMALL LETTER A WITH RING ABOVE
+    0x0087: 0x00e7,     #  LATIN SMALL LETTER C WITH CEDILLA
+    0x0088: 0x00ea,     #  LATIN SMALL LETTER E WITH CIRCUMFLEX
+    0x0089: 0x00eb,     #  LATIN SMALL LETTER E WITH DIAERESIS
+    0x008a: 0x00e8,     #  LATIN SMALL LETTER E WITH GRAVE
+    0x008b: 0x00d0,     #  LATIN CAPITAL LETTER ETH
+    0x008c: 0x00f0,     #  LATIN SMALL LETTER ETH
+    0x008d: 0x00de,     #  LATIN CAPITAL LETTER THORN
+    0x008e: 0x00c4,     #  LATIN CAPITAL LETTER A WITH DIAERESIS
+    0x008f: 0x00c5,     #  LATIN CAPITAL LETTER A WITH RING ABOVE
+    0x0090: 0x00c9,     #  LATIN CAPITAL LETTER E WITH ACUTE
+    0x0091: 0x00e6,     #  LATIN SMALL LIGATURE AE
+    0x0092: 0x00c6,     #  LATIN CAPITAL LIGATURE AE
+    0x0093: 0x00f4,     #  LATIN SMALL LETTER O WITH CIRCUMFLEX
+    0x0094: 0x00f6,     #  LATIN SMALL LETTER O WITH DIAERESIS
+    0x0095: 0x00fe,     #  LATIN SMALL LETTER THORN
+    0x0096: 0x00fb,     #  LATIN SMALL LETTER U WITH CIRCUMFLEX
+    0x0097: 0x00dd,     #  LATIN CAPITAL LETTER Y WITH ACUTE
+    0x0098: 0x00fd,     #  LATIN SMALL LETTER Y WITH ACUTE
+    0x0099: 0x00d6,     #  LATIN CAPITAL LETTER O WITH DIAERESIS
+    0x009a: 0x00dc,     #  LATIN CAPITAL LETTER U WITH DIAERESIS
+    0x009b: 0x00f8,     #  LATIN SMALL LETTER O WITH STROKE
+    0x009c: 0x00a3,     #  POUND SIGN
+    0x009d: 0x00d8,     #  LATIN CAPITAL LETTER O WITH STROKE
+    0x009e: 0x20a7,     #  PESETA SIGN
+    0x009f: 0x0192,     #  LATIN SMALL LETTER F WITH HOOK
+    0x00a0: 0x00e1,     #  LATIN SMALL LETTER A WITH ACUTE
+    0x00a1: 0x00ed,     #  LATIN SMALL LETTER I WITH ACUTE
+    0x00a2: 0x00f3,     #  LATIN SMALL LETTER O WITH ACUTE
+    0x00a3: 0x00fa,     #  LATIN SMALL LETTER U WITH ACUTE
+    0x00a4: 0x00c1,     #  LATIN CAPITAL LETTER A WITH ACUTE
+    0x00a5: 0x00cd,     #  LATIN CAPITAL LETTER I WITH ACUTE
+    0x00a6: 0x00d3,     #  LATIN CAPITAL LETTER O WITH ACUTE
+    0x00a7: 0x00da,     #  LATIN CAPITAL LETTER U WITH ACUTE
+    0x00a8: 0x00bf,     #  INVERTED QUESTION MARK
+    0x00a9: 0x2310,     #  REVERSED NOT SIGN
+    0x00aa: 0x00ac,     #  NOT SIGN
+    0x00ab: 0x00bd,     #  VULGAR FRACTION ONE HALF
+    0x00ac: 0x00bc,     #  VULGAR FRACTION ONE QUARTER
+    0x00ad: 0x00a1,     #  INVERTED EXCLAMATION MARK
+    0x00ae: 0x00ab,     #  LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    0x00af: 0x00bb,     #  RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    0x00b0: 0x2591,     #  LIGHT SHADE
+    0x00b1: 0x2592,     #  MEDIUM SHADE
+    0x00b2: 0x2593,     #  DARK SHADE
+    0x00b3: 0x2502,     #  BOX DRAWINGS LIGHT VERTICAL
+    0x00b4: 0x2524,     #  BOX DRAWINGS LIGHT VERTICAL AND LEFT
+    0x00b5: 0x2561,     #  BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+    0x00b6: 0x2562,     #  BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
+    0x00b7: 0x2556,     #  BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
+    0x00b8: 0x2555,     #  BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
+    0x00b9: 0x2563,     #  BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+    0x00ba: 0x2551,     #  BOX DRAWINGS DOUBLE VERTICAL
+    0x00bb: 0x2557,     #  BOX DRAWINGS DOUBLE DOWN AND LEFT
+    0x00bc: 0x255d,     #  BOX DRAWINGS DOUBLE UP AND LEFT
+    0x00bd: 0x255c,     #  BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
+    0x00be: 0x255b,     #  BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+    0x00bf: 0x2510,     #  BOX DRAWINGS LIGHT DOWN AND LEFT
+    0x00c0: 0x2514,     #  BOX DRAWINGS LIGHT UP AND RIGHT
+    0x00c1: 0x2534,     #  BOX DRAWINGS LIGHT UP AND HORIZONTAL
+    0x00c2: 0x252c,     #  BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+    0x00c3: 0x251c,     #  BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+    0x00c4: 0x2500,     #  BOX DRAWINGS LIGHT HORIZONTAL
+    0x00c5: 0x253c,     #  BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+    0x00c6: 0x255e,     #  BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+    0x00c7: 0x255f,     #  BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+    0x00c8: 0x255a,     #  BOX DRAWINGS DOUBLE UP AND RIGHT
+    0x00c9: 0x2554,     #  BOX DRAWINGS DOUBLE DOWN AND RIGHT
+    0x00ca: 0x2569,     #  BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+    0x00cb: 0x2566,     #  BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+    0x00cc: 0x2560,     #  BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+    0x00cd: 0x2550,     #  BOX DRAWINGS DOUBLE HORIZONTAL
+    0x00ce: 0x256c,     #  BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+    0x00cf: 0x2567,     #  BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+    0x00d0: 0x2568,     #  BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+    0x00d1: 0x2564,     #  BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
+    0x00d2: 0x2565,     #  BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
+    0x00d3: 0x2559,     #  BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+    0x00d4: 0x2558,     #  BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+    0x00d5: 0x2552,     #  BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+    0x00d6: 0x2553,     #  BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
+    0x00d7: 0x256b,     #  BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
+    0x00d8: 0x256a,     #  BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+    0x00d9: 0x2518,     #  BOX DRAWINGS LIGHT UP AND LEFT
+    0x00da: 0x250c,     #  BOX DRAWINGS LIGHT DOWN AND RIGHT
+    0x00db: 0x2588,     #  FULL BLOCK
+    0x00dc: 0x2584,     #  LOWER HALF BLOCK
+    0x00dd: 0x258c,     #  LEFT HALF BLOCK
+    0x00de: 0x2590,     #  RIGHT HALF BLOCK
+    0x00df: 0x2580,     #  UPPER HALF BLOCK
+    0x00e0: 0x03b1,     #  GREEK SMALL LETTER ALPHA
+    0x00e1: 0x00df,     #  LATIN SMALL LETTER SHARP S
+    0x00e2: 0x0393,     #  GREEK CAPITAL LETTER GAMMA
+    0x00e3: 0x03c0,     #  GREEK SMALL LETTER PI
+    0x00e4: 0x03a3,     #  GREEK CAPITAL LETTER SIGMA
+    0x00e5: 0x03c3,     #  GREEK SMALL LETTER SIGMA
+    0x00e6: 0x00b5,     #  MICRO SIGN
+    0x00e7: 0x03c4,     #  GREEK SMALL LETTER TAU
+    0x00e8: 0x03a6,     #  GREEK CAPITAL LETTER PHI
+    0x00e9: 0x0398,     #  GREEK CAPITAL LETTER THETA
+    0x00ea: 0x03a9,     #  GREEK CAPITAL LETTER OMEGA
+    0x00eb: 0x03b4,     #  GREEK SMALL LETTER DELTA
+    0x00ec: 0x221e,     #  INFINITY
+    0x00ed: 0x03c6,     #  GREEK SMALL LETTER PHI
+    0x00ee: 0x03b5,     #  GREEK SMALL LETTER EPSILON
+    0x00ef: 0x2229,     #  INTERSECTION
+    0x00f0: 0x2261,     #  IDENTICAL TO
+    0x00f1: 0x00b1,     #  PLUS-MINUS SIGN
+    0x00f2: 0x2265,     #  GREATER-THAN OR EQUAL TO
+    0x00f3: 0x2264,     #  LESS-THAN OR EQUAL TO
+    0x00f4: 0x2320,     #  TOP HALF INTEGRAL
+    0x00f5: 0x2321,     #  BOTTOM HALF INTEGRAL
+    0x00f6: 0x00f7,     #  DIVISION SIGN
+    0x00f7: 0x2248,     #  ALMOST EQUAL TO
+    0x00f8: 0x00b0,     #  DEGREE SIGN
+    0x00f9: 0x2219,     #  BULLET OPERATOR
+    0x00fa: 0x00b7,     #  MIDDLE DOT
+    0x00fb: 0x221a,     #  SQUARE ROOT
+    0x00fc: 0x207f,     #  SUPERSCRIPT LATIN SMALL LETTER N
+    0x00fd: 0x00b2,     #  SUPERSCRIPT TWO
+    0x00fe: 0x25a0,     #  BLACK SQUARE
+    0x00ff: 0x00a0,     #  NO-BREAK SPACE
+})
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x0000 -> NULL
+    u'\x01'     #  0x0001 -> START OF HEADING
+    u'\x02'     #  0x0002 -> START OF TEXT
+    u'\x03'     #  0x0003 -> END OF TEXT
+    u'\x04'     #  0x0004 -> END OF TRANSMISSION
+    u'\x05'     #  0x0005 -> ENQUIRY
+    u'\x06'     #  0x0006 -> ACKNOWLEDGE
+    u'\x07'     #  0x0007 -> BELL
+    u'\x08'     #  0x0008 -> BACKSPACE
+    u'\t'       #  0x0009 -> HORIZONTAL TABULATION
+    u'\n'       #  0x000a -> LINE FEED
+    u'\x0b'     #  0x000b -> VERTICAL TABULATION
+    u'\x0c'     #  0x000c -> FORM FEED
+    u'\r'       #  0x000d -> CARRIAGE RETURN
+    u'\x0e'     #  0x000e -> SHIFT OUT
+    u'\x0f'     #  0x000f -> SHIFT IN
+    u'\x10'     #  0x0010 -> DATA LINK ESCAPE
+    u'\x11'     #  0x0011 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x0012 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x0013 -> DEVICE CONTROL THREE
+    u'\x14'     #  0x0014 -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x0015 -> NEGATIVE ACKNOWLEDGE
+    u'\x16'     #  0x0016 -> SYNCHRONOUS IDLE
+    u'\x17'     #  0x0017 -> END OF TRANSMISSION BLOCK
+    u'\x18'     #  0x0018 -> CANCEL
+    u'\x19'     #  0x0019 -> END OF MEDIUM
+    u'\x1a'     #  0x001a -> SUBSTITUTE
+    u'\x1b'     #  0x001b -> ESCAPE
+    u'\x1c'     #  0x001c -> FILE SEPARATOR
+    u'\x1d'     #  0x001d -> GROUP SEPARATOR
+    u'\x1e'     #  0x001e -> RECORD SEPARATOR
+    u'\x1f'     #  0x001f -> UNIT SEPARATOR
+    u' '        #  0x0020 -> SPACE
+    u'!'        #  0x0021 -> EXCLAMATION MARK
+    u'"'        #  0x0022 -> QUOTATION MARK
+    u'#'        #  0x0023 -> NUMBER SIGN
+    u'$'        #  0x0024 -> DOLLAR SIGN
+    u'%'        #  0x0025 -> PERCENT SIGN
+    u'&'        #  0x0026 -> AMPERSAND
+    u"'"        #  0x0027 -> APOSTROPHE
+    u'('        #  0x0028 -> LEFT PARENTHESIS
+    u')'        #  0x0029 -> RIGHT PARENTHESIS
+    u'*'        #  0x002a -> ASTERISK
+    u'+'        #  0x002b -> PLUS SIGN
+    u','        #  0x002c -> COMMA
+    u'-'        #  0x002d -> HYPHEN-MINUS
+    u'.'        #  0x002e -> FULL STOP
+    u'/'        #  0x002f -> SOLIDUS
+    u'0'        #  0x0030 -> DIGIT ZERO
+    u'1'        #  0x0031 -> DIGIT ONE
+    u'2'        #  0x0032 -> DIGIT TWO
+    u'3'        #  0x0033 -> DIGIT THREE
+    u'4'        #  0x0034 -> DIGIT FOUR
+    u'5'        #  0x0035 -> DIGIT FIVE
+    u'6'        #  0x0036 -> DIGIT SIX
+    u'7'        #  0x0037 -> DIGIT SEVEN
+    u'8'        #  0x0038 -> DIGIT EIGHT
+    u'9'        #  0x0039 -> DIGIT NINE
+    u':'        #  0x003a -> COLON
+    u';'        #  0x003b -> SEMICOLON
+    u'<'        #  0x003c -> LESS-THAN SIGN
+    u'='        #  0x003d -> EQUALS SIGN
+    u'>'        #  0x003e -> GREATER-THAN SIGN
+    u'?'        #  0x003f -> QUESTION MARK
+    u'@'        #  0x0040 -> COMMERCIAL AT
+    u'A'        #  0x0041 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x0042 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x0043 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x0044 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x0045 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x0046 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x0047 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x0048 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x0049 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x004a -> LATIN CAPITAL LETTER J
+    u'K'        #  0x004b -> LATIN CAPITAL LETTER K
+    u'L'        #  0x004c -> LATIN CAPITAL LETTER L
+    u'M'        #  0x004d -> LATIN CAPITAL LETTER M
+    u'N'        #  0x004e -> LATIN CAPITAL LETTER N
+    u'O'        #  0x004f -> LATIN CAPITAL LETTER O
+    u'P'        #  0x0050 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x0051 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x0052 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x0053 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x0054 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x0055 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x0056 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x0057 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x0058 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x0059 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x005a -> LATIN CAPITAL LETTER Z
+    u'['        #  0x005b -> LEFT SQUARE BRACKET
+    u'\\'       #  0x005c -> REVERSE SOLIDUS
+    u']'        #  0x005d -> RIGHT SQUARE BRACKET
+    u'^'        #  0x005e -> CIRCUMFLEX ACCENT
+    u'_'        #  0x005f -> LOW LINE
+    u'`'        #  0x0060 -> GRAVE ACCENT
+    u'a'        #  0x0061 -> LATIN SMALL LETTER A
+    u'b'        #  0x0062 -> LATIN SMALL LETTER B
+    u'c'        #  0x0063 -> LATIN SMALL LETTER C
+    u'd'        #  0x0064 -> LATIN SMALL LETTER D
+    u'e'        #  0x0065 -> LATIN SMALL LETTER E
+    u'f'        #  0x0066 -> LATIN SMALL LETTER F
+    u'g'        #  0x0067 -> LATIN SMALL LETTER G
+    u'h'        #  0x0068 -> LATIN SMALL LETTER H
+    u'i'        #  0x0069 -> LATIN SMALL LETTER I
+    u'j'        #  0x006a -> LATIN SMALL LETTER J
+    u'k'        #  0x006b -> LATIN SMALL LETTER K
+    u'l'        #  0x006c -> LATIN SMALL LETTER L
+    u'm'        #  0x006d -> LATIN SMALL LETTER M
+    u'n'        #  0x006e -> LATIN SMALL LETTER N
+    u'o'        #  0x006f -> LATIN SMALL LETTER O
+    u'p'        #  0x0070 -> LATIN SMALL LETTER P
+    u'q'        #  0x0071 -> LATIN SMALL LETTER Q
+    u'r'        #  0x0072 -> LATIN SMALL LETTER R
+    u's'        #  0x0073 -> LATIN SMALL LETTER S
+    u't'        #  0x0074 -> LATIN SMALL LETTER T
+    u'u'        #  0x0075 -> LATIN SMALL LETTER U
+    u'v'        #  0x0076 -> LATIN SMALL LETTER V
+    u'w'        #  0x0077 -> LATIN SMALL LETTER W
+    u'x'        #  0x0078 -> LATIN SMALL LETTER X
+    u'y'        #  0x0079 -> LATIN SMALL LETTER Y
+    u'z'        #  0x007a -> LATIN SMALL LETTER Z
+    u'{'        #  0x007b -> LEFT CURLY BRACKET
+    u'|'        #  0x007c -> VERTICAL LINE
+    u'}'        #  0x007d -> RIGHT CURLY BRACKET
+    u'~'        #  0x007e -> TILDE
+    u'\x7f'     #  0x007f -> DELETE
+    u'\xc7'     #  0x0080 -> LATIN CAPITAL LETTER C WITH CEDILLA
+    u'\xfc'     #  0x0081 -> LATIN SMALL LETTER U WITH DIAERESIS
+    u'\xe9'     #  0x0082 -> LATIN SMALL LETTER E WITH ACUTE
+    u'\xe2'     #  0x0083 -> LATIN SMALL LETTER A WITH CIRCUMFLEX
+    u'\xe4'     #  0x0084 -> LATIN SMALL LETTER A WITH DIAERESIS
+    u'\xe0'     #  0x0085 -> LATIN SMALL LETTER A WITH GRAVE
+    u'\xe5'     #  0x0086 -> LATIN SMALL LETTER A WITH RING ABOVE
+    u'\xe7'     #  0x0087 -> LATIN SMALL LETTER C WITH CEDILLA
+    u'\xea'     #  0x0088 -> LATIN SMALL LETTER E WITH CIRCUMFLEX
+    u'\xeb'     #  0x0089 -> LATIN SMALL LETTER E WITH DIAERESIS
+    u'\xe8'     #  0x008a -> LATIN SMALL LETTER E WITH GRAVE
+    u'\xd0'     #  0x008b -> LATIN CAPITAL LETTER ETH
+    u'\xf0'     #  0x008c -> LATIN SMALL LETTER ETH
+    u'\xde'     #  0x008d -> LATIN CAPITAL LETTER THORN
+    u'\xc4'     #  0x008e -> LATIN CAPITAL LETTER A WITH DIAERESIS
+    u'\xc5'     #  0x008f -> LATIN CAPITAL LETTER A WITH RING ABOVE
+    u'\xc9'     #  0x0090 -> LATIN CAPITAL LETTER E WITH ACUTE
+    u'\xe6'     #  0x0091 -> LATIN SMALL LIGATURE AE
+    u'\xc6'     #  0x0092 -> LATIN CAPITAL LIGATURE AE
+    u'\xf4'     #  0x0093 -> LATIN SMALL LETTER O WITH CIRCUMFLEX
+    u'\xf6'     #  0x0094 -> LATIN SMALL LETTER O WITH DIAERESIS
+    u'\xfe'     #  0x0095 -> LATIN SMALL LETTER THORN
+    u'\xfb'     #  0x0096 -> LATIN SMALL LETTER U WITH CIRCUMFLEX
+    u'\xdd'     #  0x0097 -> LATIN CAPITAL LETTER Y WITH ACUTE
+    u'\xfd'     #  0x0098 -> LATIN SMALL LETTER Y WITH ACUTE
+    u'\xd6'     #  0x0099 -> LATIN CAPITAL LETTER O WITH DIAERESIS
+    u'\xdc'     #  0x009a -> LATIN CAPITAL LETTER U WITH DIAERESIS
+    u'\xf8'     #  0x009b -> LATIN SMALL LETTER O WITH STROKE
+    u'\xa3'     #  0x009c -> POUND SIGN
+    u'\xd8'     #  0x009d -> LATIN CAPITAL LETTER O WITH STROKE
+    u'\u20a7'   #  0x009e -> PESETA SIGN
+    u'\u0192'   #  0x009f -> LATIN SMALL LETTER F WITH HOOK
+    u'\xe1'     #  0x00a0 -> LATIN SMALL LETTER A WITH ACUTE
+    u'\xed'     #  0x00a1 -> LATIN SMALL LETTER I WITH ACUTE
+    u'\xf3'     #  0x00a2 -> LATIN SMALL LETTER O WITH ACUTE
+    u'\xfa'     #  0x00a3 -> LATIN SMALL LETTER U WITH ACUTE
+    u'\xc1'     #  0x00a4 -> LATIN CAPITAL LETTER A WITH ACUTE
+    u'\xcd'     #  0x00a5 -> LATIN CAPITAL LETTER I WITH ACUTE
+    u'\xd3'     #  0x00a6 -> LATIN CAPITAL LETTER O WITH ACUTE
+    u'\xda'     #  0x00a7 -> LATIN CAPITAL LETTER U WITH ACUTE
+    u'\xbf'     #  0x00a8 -> INVERTED QUESTION MARK
+    u'\u2310'   #  0x00a9 -> REVERSED NOT SIGN
+    u'\xac'     #  0x00aa -> NOT SIGN
+    u'\xbd'     #  0x00ab -> VULGAR FRACTION ONE HALF
+    u'\xbc'     #  0x00ac -> VULGAR FRACTION ONE QUARTER
+    u'\xa1'     #  0x00ad -> INVERTED EXCLAMATION MARK
+    u'\xab'     #  0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xbb'     #  0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\u2591'   #  0x00b0 -> LIGHT SHADE
+    u'\u2592'   #  0x00b1 -> MEDIUM SHADE
+    u'\u2593'   #  0x00b2 -> DARK SHADE
+    u'\u2502'   #  0x00b3 -> BOX DRAWINGS LIGHT VERTICAL
+    u'\u2524'   #  0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT
+    u'\u2561'   #  0x00b5 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+    u'\u2562'   #  0x00b6 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
+    u'\u2556'   #  0x00b7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
+    u'\u2555'   #  0x00b8 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
+    u'\u2563'   #  0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+    u'\u2551'   #  0x00ba -> BOX DRAWINGS DOUBLE VERTICAL
+    u'\u2557'   #  0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT
+    u'\u255d'   #  0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT
+    u'\u255c'   #  0x00bd -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
+    u'\u255b'   #  0x00be -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+    u'\u2510'   #  0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT
+    u'\u2514'   #  0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT
+    u'\u2534'   #  0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL
+    u'\u252c'   #  0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+    u'\u251c'   #  0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+    u'\u2500'   #  0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL
+    u'\u253c'   #  0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+    u'\u255e'   #  0x00c6 -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+    u'\u255f'   #  0x00c7 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+    u'\u255a'   #  0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT
+    u'\u2554'   #  0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT
+    u'\u2569'   #  0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+    u'\u2566'   #  0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+    u'\u2560'   #  0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+    u'\u2550'   #  0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL
+    u'\u256c'   #  0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+    u'\u2567'   #  0x00cf -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+    u'\u2568'   #  0x00d0 -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+    u'\u2564'   #  0x00d1 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
+    u'\u2565'   #  0x00d2 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
+    u'\u2559'   #  0x00d3 -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+    u'\u2558'   #  0x00d4 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+    u'\u2552'   #  0x00d5 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+    u'\u2553'   #  0x00d6 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
+    u'\u256b'   #  0x00d7 -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
+    u'\u256a'   #  0x00d8 -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+    u'\u2518'   #  0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT
+    u'\u250c'   #  0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT
+    u'\u2588'   #  0x00db -> FULL BLOCK
+    u'\u2584'   #  0x00dc -> LOWER HALF BLOCK
+    u'\u258c'   #  0x00dd -> LEFT HALF BLOCK
+    u'\u2590'   #  0x00de -> RIGHT HALF BLOCK
+    u'\u2580'   #  0x00df -> UPPER HALF BLOCK
+    u'\u03b1'   #  0x00e0 -> GREEK SMALL LETTER ALPHA
+    u'\xdf'     #  0x00e1 -> LATIN SMALL LETTER SHARP S
+    u'\u0393'   #  0x00e2 -> GREEK CAPITAL LETTER GAMMA
+    u'\u03c0'   #  0x00e3 -> GREEK SMALL LETTER PI
+    u'\u03a3'   #  0x00e4 -> GREEK CAPITAL LETTER SIGMA
+    u'\u03c3'   #  0x00e5 -> GREEK SMALL LETTER SIGMA
+    u'\xb5'     #  0x00e6 -> MICRO SIGN
+    u'\u03c4'   #  0x00e7 -> GREEK SMALL LETTER TAU
+    u'\u03a6'   #  0x00e8 -> GREEK CAPITAL LETTER PHI
+    u'\u0398'   #  0x00e9 -> GREEK CAPITAL LETTER THETA
+    u'\u03a9'   #  0x00ea -> GREEK CAPITAL LETTER OMEGA
+    u'\u03b4'   #  0x00eb -> GREEK SMALL LETTER DELTA
+    u'\u221e'   #  0x00ec -> INFINITY
+    u'\u03c6'   #  0x00ed -> GREEK SMALL LETTER PHI
+    u'\u03b5'   #  0x00ee -> GREEK SMALL LETTER EPSILON
+    u'\u2229'   #  0x00ef -> INTERSECTION
+    u'\u2261'   #  0x00f0 -> IDENTICAL TO
+    u'\xb1'     #  0x00f1 -> PLUS-MINUS SIGN
+    u'\u2265'   #  0x00f2 -> GREATER-THAN OR EQUAL TO
+    u'\u2264'   #  0x00f3 -> LESS-THAN OR EQUAL TO
+    u'\u2320'   #  0x00f4 -> TOP HALF INTEGRAL
+    u'\u2321'   #  0x00f5 -> BOTTOM HALF INTEGRAL
+    u'\xf7'     #  0x00f6 -> DIVISION SIGN
+    u'\u2248'   #  0x00f7 -> ALMOST EQUAL TO
+    u'\xb0'     #  0x00f8 -> DEGREE SIGN
+    u'\u2219'   #  0x00f9 -> BULLET OPERATOR
+    u'\xb7'     #  0x00fa -> MIDDLE DOT
+    u'\u221a'   #  0x00fb -> SQUARE ROOT
+    u'\u207f'   #  0x00fc -> SUPERSCRIPT LATIN SMALL LETTER N
+    u'\xb2'     #  0x00fd -> SUPERSCRIPT TWO
+    u'\u25a0'   #  0x00fe -> BLACK SQUARE
+    u'\xa0'     #  0x00ff -> NO-BREAK SPACE
+)
+
+### Encoding Map
+
+encoding_map = {
+    0x0000: 0x0000,     #  NULL
+    0x0001: 0x0001,     #  START OF HEADING
+    0x0002: 0x0002,     #  START OF TEXT
+    0x0003: 0x0003,     #  END OF TEXT
+    0x0004: 0x0004,     #  END OF TRANSMISSION
+    0x0005: 0x0005,     #  ENQUIRY
+    0x0006: 0x0006,     #  ACKNOWLEDGE
+    0x0007: 0x0007,     #  BELL
+    0x0008: 0x0008,     #  BACKSPACE
+    0x0009: 0x0009,     #  HORIZONTAL TABULATION
+    0x000a: 0x000a,     #  LINE FEED
+    0x000b: 0x000b,     #  VERTICAL TABULATION
+    0x000c: 0x000c,     #  FORM FEED
+    0x000d: 0x000d,     #  CARRIAGE RETURN
+    0x000e: 0x000e,     #  SHIFT OUT
+    0x000f: 0x000f,     #  SHIFT IN
+    0x0010: 0x0010,     #  DATA LINK ESCAPE
+    0x0011: 0x0011,     #  DEVICE CONTROL ONE
+    0x0012: 0x0012,     #  DEVICE CONTROL TWO
+    0x0013: 0x0013,     #  DEVICE CONTROL THREE
+    0x0014: 0x0014,     #  DEVICE CONTROL FOUR
+    0x0015: 0x0015,     #  NEGATIVE ACKNOWLEDGE
+    0x0016: 0x0016,     #  SYNCHRONOUS IDLE
+    0x0017: 0x0017,     #  END OF TRANSMISSION BLOCK
+    0x0018: 0x0018,     #  CANCEL
+    0x0019: 0x0019,     #  END OF MEDIUM
+    0x001a: 0x001a,     #  SUBSTITUTE
+    0x001b: 0x001b,     #  ESCAPE
+    0x001c: 0x001c,     #  FILE SEPARATOR
+    0x001d: 0x001d,     #  GROUP SEPARATOR
+    0x001e: 0x001e,     #  RECORD SEPARATOR
+    0x001f: 0x001f,     #  UNIT SEPARATOR
+    0x0020: 0x0020,     #  SPACE
+    0x0021: 0x0021,     #  EXCLAMATION MARK
+    0x0022: 0x0022,     #  QUOTATION MARK
+    0x0023: 0x0023,     #  NUMBER SIGN
+    0x0024: 0x0024,     #  DOLLAR SIGN
+    0x0025: 0x0025,     #  PERCENT SIGN
+    0x0026: 0x0026,     #  AMPERSAND
+    0x0027: 0x0027,     #  APOSTROPHE
+    0x0028: 0x0028,     #  LEFT PARENTHESIS
+    0x0029: 0x0029,     #  RIGHT PARENTHESIS
+    0x002a: 0x002a,     #  ASTERISK
+    0x002b: 0x002b,     #  PLUS SIGN
+    0x002c: 0x002c,     #  COMMA
+    0x002d: 0x002d,     #  HYPHEN-MINUS
+    0x002e: 0x002e,     #  FULL STOP
+    0x002f: 0x002f,     #  SOLIDUS
+    0x0030: 0x0030,     #  DIGIT ZERO
+    0x0031: 0x0031,     #  DIGIT ONE
+    0x0032: 0x0032,     #  DIGIT TWO
+    0x0033: 0x0033,     #  DIGIT THREE
+    0x0034: 0x0034,     #  DIGIT FOUR
+    0x0035: 0x0035,     #  DIGIT FIVE
+    0x0036: 0x0036,     #  DIGIT SIX
+    0x0037: 0x0037,     #  DIGIT SEVEN
+    0x0038: 0x0038,     #  DIGIT EIGHT
+    0x0039: 0x0039,     #  DIGIT NINE
+    0x003a: 0x003a,     #  COLON
+    0x003b: 0x003b,     #  SEMICOLON
+    0x003c: 0x003c,     #  LESS-THAN SIGN
+    0x003d: 0x003d,     #  EQUALS SIGN
+    0x003e: 0x003e,     #  GREATER-THAN SIGN
+    0x003f: 0x003f,     #  QUESTION MARK
+    0x0040: 0x0040,     #  COMMERCIAL AT
+    0x0041: 0x0041,     #  LATIN CAPITAL LETTER A
+    0x0042: 0x0042,     #  LATIN CAPITAL LETTER B
+    0x0043: 0x0043,     #  LATIN CAPITAL LETTER C
+    0x0044: 0x0044,     #  LATIN CAPITAL LETTER D
+    0x0045: 0x0045,     #  LATIN CAPITAL LETTER E
+    0x0046: 0x0046,     #  LATIN CAPITAL LETTER F
+    0x0047: 0x0047,     #  LATIN CAPITAL LETTER G
+    0x0048: 0x0048,     #  LATIN CAPITAL LETTER H
+    0x0049: 0x0049,     #  LATIN CAPITAL LETTER I
+    0x004a: 0x004a,     #  LATIN CAPITAL LETTER J
+    0x004b: 0x004b,     #  LATIN CAPITAL LETTER K
+    0x004c: 0x004c,     #  LATIN CAPITAL LETTER L
+    0x004d: 0x004d,     #  LATIN CAPITAL LETTER M
+    0x004e: 0x004e,     #  LATIN CAPITAL LETTER N
+    0x004f: 0x004f,     #  LATIN CAPITAL LETTER O
+    0x0050: 0x0050,     #  LATIN CAPITAL LETTER P
+    0x0051: 0x0051,     #  LATIN CAPITAL LETTER Q
+    0x0052: 0x0052,     #  LATIN CAPITAL LETTER R
+    0x0053: 0x0053,     #  LATIN CAPITAL LETTER S
+    0x0054: 0x0054,     #  LATIN CAPITAL LETTER T
+    0x0055: 0x0055,     #  LATIN CAPITAL LETTER U
+    0x0056: 0x0056,     #  LATIN CAPITAL LETTER V
+    0x0057: 0x0057,     #  LATIN CAPITAL LETTER W
+    0x0058: 0x0058,     #  LATIN CAPITAL LETTER X
+    0x0059: 0x0059,     #  LATIN CAPITAL LETTER Y
+    0x005a: 0x005a,     #  LATIN CAPITAL LETTER Z
+    0x005b: 0x005b,     #  LEFT SQUARE BRACKET
+    0x005c: 0x005c,     #  REVERSE SOLIDUS
+    0x005d: 0x005d,     #  RIGHT SQUARE BRACKET
+    0x005e: 0x005e,     #  CIRCUMFLEX ACCENT
+    0x005f: 0x005f,     #  LOW LINE
+    0x0060: 0x0060,     #  GRAVE ACCENT
+    0x0061: 0x0061,     #  LATIN SMALL LETTER A
+    0x0062: 0x0062,     #  LATIN SMALL LETTER B
+    0x0063: 0x0063,     #  LATIN SMALL LETTER C
+    0x0064: 0x0064,     #  LATIN SMALL LETTER D
+    0x0065: 0x0065,     #  LATIN SMALL LETTER E
+    0x0066: 0x0066,     #  LATIN SMALL LETTER F
+    0x0067: 0x0067,     #  LATIN SMALL LETTER G
+    0x0068: 0x0068,     #  LATIN SMALL LETTER H
+    0x0069: 0x0069,     #  LATIN SMALL LETTER I
+    0x006a: 0x006a,     #  LATIN SMALL LETTER J
+    0x006b: 0x006b,     #  LATIN SMALL LETTER K
+    0x006c: 0x006c,     #  LATIN SMALL LETTER L
+    0x006d: 0x006d,     #  LATIN SMALL LETTER M
+    0x006e: 0x006e,     #  LATIN SMALL LETTER N
+    0x006f: 0x006f,     #  LATIN SMALL LETTER O
+    0x0070: 0x0070,     #  LATIN SMALL LETTER P
+    0x0071: 0x0071,     #  LATIN SMALL LETTER Q
+    0x0072: 0x0072,     #  LATIN SMALL LETTER R
+    0x0073: 0x0073,     #  LATIN SMALL LETTER S
+    0x0074: 0x0074,     #  LATIN SMALL LETTER T
+    0x0075: 0x0075,     #  LATIN SMALL LETTER U
+    0x0076: 0x0076,     #  LATIN SMALL LETTER V
+    0x0077: 0x0077,     #  LATIN SMALL LETTER W
+    0x0078: 0x0078,     #  LATIN SMALL LETTER X
+    0x0079: 0x0079,     #  LATIN SMALL LETTER Y
+    0x007a: 0x007a,     #  LATIN SMALL LETTER Z
+    0x007b: 0x007b,     #  LEFT CURLY BRACKET
+    0x007c: 0x007c,     #  VERTICAL LINE
+    0x007d: 0x007d,     #  RIGHT CURLY BRACKET
+    0x007e: 0x007e,     #  TILDE
+    0x007f: 0x007f,     #  DELETE
+    0x00a0: 0x00ff,     #  NO-BREAK SPACE
+    0x00a1: 0x00ad,     #  INVERTED EXCLAMATION MARK
+    0x00a3: 0x009c,     #  POUND SIGN
+    0x00ab: 0x00ae,     #  LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    0x00ac: 0x00aa,     #  NOT SIGN
+    0x00b0: 0x00f8,     #  DEGREE SIGN
+    0x00b1: 0x00f1,     #  PLUS-MINUS SIGN
+    0x00b2: 0x00fd,     #  SUPERSCRIPT TWO
+    0x00b5: 0x00e6,     #  MICRO SIGN
+    0x00b7: 0x00fa,     #  MIDDLE DOT
+    0x00bb: 0x00af,     #  RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    0x00bc: 0x00ac,     #  VULGAR FRACTION ONE QUARTER
+    0x00bd: 0x00ab,     #  VULGAR FRACTION ONE HALF
+    0x00bf: 0x00a8,     #  INVERTED QUESTION MARK
+    0x00c1: 0x00a4,     #  LATIN CAPITAL LETTER A WITH ACUTE
+    0x00c4: 0x008e,     #  LATIN CAPITAL LETTER A WITH DIAERESIS
+    0x00c5: 0x008f,     #  LATIN CAPITAL LETTER A WITH RING ABOVE
+    0x00c6: 0x0092,     #  LATIN CAPITAL LIGATURE AE
+    0x00c7: 0x0080,     #  LATIN CAPITAL LETTER C WITH CEDILLA
+    0x00c9: 0x0090,     #  LATIN CAPITAL LETTER E WITH ACUTE
+    0x00cd: 0x00a5,     #  LATIN CAPITAL LETTER I WITH ACUTE
+    0x00d0: 0x008b,     #  LATIN CAPITAL LETTER ETH
+    0x00d3: 0x00a6,     #  LATIN CAPITAL LETTER O WITH ACUTE
+    0x00d6: 0x0099,     #  LATIN CAPITAL LETTER O WITH DIAERESIS
+    0x00d8: 0x009d,     #  LATIN CAPITAL LETTER O WITH STROKE
+    0x00da: 0x00a7,     #  LATIN CAPITAL LETTER U WITH ACUTE
+    0x00dc: 0x009a,     #  LATIN CAPITAL LETTER U WITH DIAERESIS
+    0x00dd: 0x0097,     #  LATIN CAPITAL LETTER Y WITH ACUTE
+    0x00de: 0x008d,     #  LATIN CAPITAL LETTER THORN
+    0x00df: 0x00e1,     #  LATIN SMALL LETTER SHARP S
+    0x00e0: 0x0085,     #  LATIN SMALL LETTER A WITH GRAVE
+    0x00e1: 0x00a0,     #  LATIN SMALL LETTER A WITH ACUTE
+    0x00e2: 0x0083,     #  LATIN SMALL LETTER A WITH CIRCUMFLEX
+    0x00e4: 0x0084,     #  LATIN SMALL LETTER A WITH DIAERESIS
+    0x00e5: 0x0086,     #  LATIN SMALL LETTER A WITH RING ABOVE
+    0x00e6: 0x0091,     #  LATIN SMALL LIGATURE AE
+    0x00e7: 0x0087,     #  LATIN SMALL LETTER C WITH CEDILLA
+    0x00e8: 0x008a,     #  LATIN SMALL LETTER E WITH GRAVE
+    0x00e9: 0x0082,     #  LATIN SMALL LETTER E WITH ACUTE
+    0x00ea: 0x0088,     #  LATIN SMALL LETTER E WITH CIRCUMFLEX
+    0x00eb: 0x0089,     #  LATIN SMALL LETTER E WITH DIAERESIS
+    0x00ed: 0x00a1,     #  LATIN SMALL LETTER I WITH ACUTE
+    0x00f0: 0x008c,     #  LATIN SMALL LETTER ETH
+    0x00f3: 0x00a2,     #  LATIN SMALL LETTER O WITH ACUTE
+    0x00f4: 0x0093,     #  LATIN SMALL LETTER O WITH CIRCUMFLEX
+    0x00f6: 0x0094,     #  LATIN SMALL LETTER O WITH DIAERESIS
+    0x00f7: 0x00f6,     #  DIVISION SIGN
+    0x00f8: 0x009b,     #  LATIN SMALL LETTER O WITH STROKE
+    0x00fa: 0x00a3,     #  LATIN SMALL LETTER U WITH ACUTE
+    0x00fb: 0x0096,     #  LATIN SMALL LETTER U WITH CIRCUMFLEX
+    0x00fc: 0x0081,     #  LATIN SMALL LETTER U WITH DIAERESIS
+    0x00fd: 0x0098,     #  LATIN SMALL LETTER Y WITH ACUTE
+    0x00fe: 0x0095,     #  LATIN SMALL LETTER THORN
+    0x0192: 0x009f,     #  LATIN SMALL LETTER F WITH HOOK
+    0x0393: 0x00e2,     #  GREEK CAPITAL LETTER GAMMA
+    0x0398: 0x00e9,     #  GREEK CAPITAL LETTER THETA
+    0x03a3: 0x00e4,     #  GREEK CAPITAL LETTER SIGMA
+    0x03a6: 0x00e8,     #  GREEK CAPITAL LETTER PHI
+    0x03a9: 0x00ea,     #  GREEK CAPITAL LETTER OMEGA
+    0x03b1: 0x00e0,     #  GREEK SMALL LETTER ALPHA
+    0x03b4: 0x00eb,     #  GREEK SMALL LETTER DELTA
+    0x03b5: 0x00ee,     #  GREEK SMALL LETTER EPSILON
+    0x03c0: 0x00e3,     #  GREEK SMALL LETTER PI
+    0x03c3: 0x00e5,     #  GREEK SMALL LETTER SIGMA
+    0x03c4: 0x00e7,     #  GREEK SMALL LETTER TAU
+    0x03c6: 0x00ed,     #  GREEK SMALL LETTER PHI
+    0x207f: 0x00fc,     #  SUPERSCRIPT LATIN SMALL LETTER N
+    0x20a7: 0x009e,     #  PESETA SIGN
+    0x2219: 0x00f9,     #  BULLET OPERATOR
+    0x221a: 0x00fb,     #  SQUARE ROOT
+    0x221e: 0x00ec,     #  INFINITY
+    0x2229: 0x00ef,     #  INTERSECTION
+    0x2248: 0x00f7,     #  ALMOST EQUAL TO
+    0x2261: 0x00f0,     #  IDENTICAL TO
+    0x2264: 0x00f3,     #  LESS-THAN OR EQUAL TO
+    0x2265: 0x00f2,     #  GREATER-THAN OR EQUAL TO
+    0x2310: 0x00a9,     #  REVERSED NOT SIGN
+    0x2320: 0x00f4,     #  TOP HALF INTEGRAL
+    0x2321: 0x00f5,     #  BOTTOM HALF INTEGRAL
+    0x2500: 0x00c4,     #  BOX DRAWINGS LIGHT HORIZONTAL
+    0x2502: 0x00b3,     #  BOX DRAWINGS LIGHT VERTICAL
+    0x250c: 0x00da,     #  BOX DRAWINGS LIGHT DOWN AND RIGHT
+    0x2510: 0x00bf,     #  BOX DRAWINGS LIGHT DOWN AND LEFT
+    0x2514: 0x00c0,     #  BOX DRAWINGS LIGHT UP AND RIGHT
+    0x2518: 0x00d9,     #  BOX DRAWINGS LIGHT UP AND LEFT
+    0x251c: 0x00c3,     #  BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+    0x2524: 0x00b4,     #  BOX DRAWINGS LIGHT VERTICAL AND LEFT
+    0x252c: 0x00c2,     #  BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+    0x2534: 0x00c1,     #  BOX DRAWINGS LIGHT UP AND HORIZONTAL
+    0x253c: 0x00c5,     #  BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+    0x2550: 0x00cd,     #  BOX DRAWINGS DOUBLE HORIZONTAL
+    0x2551: 0x00ba,     #  BOX DRAWINGS DOUBLE VERTICAL
+    0x2552: 0x00d5,     #  BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+    0x2553: 0x00d6,     #  BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
+    0x2554: 0x00c9,     #  BOX DRAWINGS DOUBLE DOWN AND RIGHT
+    0x2555: 0x00b8,     #  BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
+    0x2556: 0x00b7,     #  BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
+    0x2557: 0x00bb,     #  BOX DRAWINGS DOUBLE DOWN AND LEFT
+    0x2558: 0x00d4,     #  BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+    0x2559: 0x00d3,     #  BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+    0x255a: 0x00c8,     #  BOX DRAWINGS DOUBLE UP AND RIGHT
+    0x255b: 0x00be,     #  BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+    0x255c: 0x00bd,     #  BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
+    0x255d: 0x00bc,     #  BOX DRAWINGS DOUBLE UP AND LEFT
+    0x255e: 0x00c6,     #  BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+    0x255f: 0x00c7,     #  BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+    0x2560: 0x00cc,     #  BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+    0x2561: 0x00b5,     #  BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+    0x2562: 0x00b6,     #  BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
+    0x2563: 0x00b9,     #  BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+    0x2564: 0x00d1,     #  BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
+    0x2565: 0x00d2,     #  BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
+    0x2566: 0x00cb,     #  BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+    0x2567: 0x00cf,     #  BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+    0x2568: 0x00d0,     #  BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+    0x2569: 0x00ca,     #  BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+    0x256a: 0x00d8,     #  BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+    0x256b: 0x00d7,     #  BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
+    0x256c: 0x00ce,     #  BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+    0x2580: 0x00df,     #  UPPER HALF BLOCK
+    0x2584: 0x00dc,     #  LOWER HALF BLOCK
+    0x2588: 0x00db,     #  FULL BLOCK
+    0x258c: 0x00dd,     #  LEFT HALF BLOCK
+    0x2590: 0x00de,     #  RIGHT HALF BLOCK
+    0x2591: 0x00b0,     #  LIGHT SHADE
+    0x2592: 0x00b1,     #  MEDIUM SHADE
+    0x2593: 0x00b2,     #  DARK SHADE
+    0x25a0: 0x00fe,     #  BLACK SQUARE
+}

Added: vendor/Python/current/Lib/encodings/cp862.py
===================================================================
--- vendor/Python/current/Lib/encodings/cp862.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/cp862.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,698 @@
+""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP862.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_map)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='cp862',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+### Decoding Map
+
+decoding_map = codecs.make_identity_dict(range(256))
+decoding_map.update({
+    0x0080: 0x05d0,     #  HEBREW LETTER ALEF
+    0x0081: 0x05d1,     #  HEBREW LETTER BET
+    0x0082: 0x05d2,     #  HEBREW LETTER GIMEL
+    0x0083: 0x05d3,     #  HEBREW LETTER DALET
+    0x0084: 0x05d4,     #  HEBREW LETTER HE
+    0x0085: 0x05d5,     #  HEBREW LETTER VAV
+    0x0086: 0x05d6,     #  HEBREW LETTER ZAYIN
+    0x0087: 0x05d7,     #  HEBREW LETTER HET
+    0x0088: 0x05d8,     #  HEBREW LETTER TET
+    0x0089: 0x05d9,     #  HEBREW LETTER YOD
+    0x008a: 0x05da,     #  HEBREW LETTER FINAL KAF
+    0x008b: 0x05db,     #  HEBREW LETTER KAF
+    0x008c: 0x05dc,     #  HEBREW LETTER LAMED
+    0x008d: 0x05dd,     #  HEBREW LETTER FINAL MEM
+    0x008e: 0x05de,     #  HEBREW LETTER MEM
+    0x008f: 0x05df,     #  HEBREW LETTER FINAL NUN
+    0x0090: 0x05e0,     #  HEBREW LETTER NUN
+    0x0091: 0x05e1,     #  HEBREW LETTER SAMEKH
+    0x0092: 0x05e2,     #  HEBREW LETTER AYIN
+    0x0093: 0x05e3,     #  HEBREW LETTER FINAL PE
+    0x0094: 0x05e4,     #  HEBREW LETTER PE
+    0x0095: 0x05e5,     #  HEBREW LETTER FINAL TSADI
+    0x0096: 0x05e6,     #  HEBREW LETTER TSADI
+    0x0097: 0x05e7,     #  HEBREW LETTER QOF
+    0x0098: 0x05e8,     #  HEBREW LETTER RESH
+    0x0099: 0x05e9,     #  HEBREW LETTER SHIN
+    0x009a: 0x05ea,     #  HEBREW LETTER TAV
+    0x009b: 0x00a2,     #  CENT SIGN
+    0x009c: 0x00a3,     #  POUND SIGN
+    0x009d: 0x00a5,     #  YEN SIGN
+    0x009e: 0x20a7,     #  PESETA SIGN
+    0x009f: 0x0192,     #  LATIN SMALL LETTER F WITH HOOK
+    0x00a0: 0x00e1,     #  LATIN SMALL LETTER A WITH ACUTE
+    0x00a1: 0x00ed,     #  LATIN SMALL LETTER I WITH ACUTE
+    0x00a2: 0x00f3,     #  LATIN SMALL LETTER O WITH ACUTE
+    0x00a3: 0x00fa,     #  LATIN SMALL LETTER U WITH ACUTE
+    0x00a4: 0x00f1,     #  LATIN SMALL LETTER N WITH TILDE
+    0x00a5: 0x00d1,     #  LATIN CAPITAL LETTER N WITH TILDE
+    0x00a6: 0x00aa,     #  FEMININE ORDINAL INDICATOR
+    0x00a7: 0x00ba,     #  MASCULINE ORDINAL INDICATOR
+    0x00a8: 0x00bf,     #  INVERTED QUESTION MARK
+    0x00a9: 0x2310,     #  REVERSED NOT SIGN
+    0x00aa: 0x00ac,     #  NOT SIGN
+    0x00ab: 0x00bd,     #  VULGAR FRACTION ONE HALF
+    0x00ac: 0x00bc,     #  VULGAR FRACTION ONE QUARTER
+    0x00ad: 0x00a1,     #  INVERTED EXCLAMATION MARK
+    0x00ae: 0x00ab,     #  LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    0x00af: 0x00bb,     #  RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    0x00b0: 0x2591,     #  LIGHT SHADE
+    0x00b1: 0x2592,     #  MEDIUM SHADE
+    0x00b2: 0x2593,     #  DARK SHADE
+    0x00b3: 0x2502,     #  BOX DRAWINGS LIGHT VERTICAL
+    0x00b4: 0x2524,     #  BOX DRAWINGS LIGHT VERTICAL AND LEFT
+    0x00b5: 0x2561,     #  BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+    0x00b6: 0x2562,     #  BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
+    0x00b7: 0x2556,     #  BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
+    0x00b8: 0x2555,     #  BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
+    0x00b9: 0x2563,     #  BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+    0x00ba: 0x2551,     #  BOX DRAWINGS DOUBLE VERTICAL
+    0x00bb: 0x2557,     #  BOX DRAWINGS DOUBLE DOWN AND LEFT
+    0x00bc: 0x255d,     #  BOX DRAWINGS DOUBLE UP AND LEFT
+    0x00bd: 0x255c,     #  BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
+    0x00be: 0x255b,     #  BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+    0x00bf: 0x2510,     #  BOX DRAWINGS LIGHT DOWN AND LEFT
+    0x00c0: 0x2514,     #  BOX DRAWINGS LIGHT UP AND RIGHT
+    0x00c1: 0x2534,     #  BOX DRAWINGS LIGHT UP AND HORIZONTAL
+    0x00c2: 0x252c,     #  BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+    0x00c3: 0x251c,     #  BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+    0x00c4: 0x2500,     #  BOX DRAWINGS LIGHT HORIZONTAL
+    0x00c5: 0x253c,     #  BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+    0x00c6: 0x255e,     #  BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+    0x00c7: 0x255f,     #  BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+    0x00c8: 0x255a,     #  BOX DRAWINGS DOUBLE UP AND RIGHT
+    0x00c9: 0x2554,     #  BOX DRAWINGS DOUBLE DOWN AND RIGHT
+    0x00ca: 0x2569,     #  BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+    0x00cb: 0x2566,     #  BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+    0x00cc: 0x2560,     #  BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+    0x00cd: 0x2550,     #  BOX DRAWINGS DOUBLE HORIZONTAL
+    0x00ce: 0x256c,     #  BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+    0x00cf: 0x2567,     #  BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+    0x00d0: 0x2568,     #  BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+    0x00d1: 0x2564,     #  BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
+    0x00d2: 0x2565,     #  BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
+    0x00d3: 0x2559,     #  BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+    0x00d4: 0x2558,     #  BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+    0x00d5: 0x2552,     #  BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+    0x00d6: 0x2553,     #  BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
+    0x00d7: 0x256b,     #  BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
+    0x00d8: 0x256a,     #  BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+    0x00d9: 0x2518,     #  BOX DRAWINGS LIGHT UP AND LEFT
+    0x00da: 0x250c,     #  BOX DRAWINGS LIGHT DOWN AND RIGHT
+    0x00db: 0x2588,     #  FULL BLOCK
+    0x00dc: 0x2584,     #  LOWER HALF BLOCK
+    0x00dd: 0x258c,     #  LEFT HALF BLOCK
+    0x00de: 0x2590,     #  RIGHT HALF BLOCK
+    0x00df: 0x2580,     #  UPPER HALF BLOCK
+    0x00e0: 0x03b1,     #  GREEK SMALL LETTER ALPHA
+    0x00e1: 0x00df,     #  LATIN SMALL LETTER SHARP S (GERMAN)
+    0x00e2: 0x0393,     #  GREEK CAPITAL LETTER GAMMA
+    0x00e3: 0x03c0,     #  GREEK SMALL LETTER PI
+    0x00e4: 0x03a3,     #  GREEK CAPITAL LETTER SIGMA
+    0x00e5: 0x03c3,     #  GREEK SMALL LETTER SIGMA
+    0x00e6: 0x00b5,     #  MICRO SIGN
+    0x00e7: 0x03c4,     #  GREEK SMALL LETTER TAU
+    0x00e8: 0x03a6,     #  GREEK CAPITAL LETTER PHI
+    0x00e9: 0x0398,     #  GREEK CAPITAL LETTER THETA
+    0x00ea: 0x03a9,     #  GREEK CAPITAL LETTER OMEGA
+    0x00eb: 0x03b4,     #  GREEK SMALL LETTER DELTA
+    0x00ec: 0x221e,     #  INFINITY
+    0x00ed: 0x03c6,     #  GREEK SMALL LETTER PHI
+    0x00ee: 0x03b5,     #  GREEK SMALL LETTER EPSILON
+    0x00ef: 0x2229,     #  INTERSECTION
+    0x00f0: 0x2261,     #  IDENTICAL TO
+    0x00f1: 0x00b1,     #  PLUS-MINUS SIGN
+    0x00f2: 0x2265,     #  GREATER-THAN OR EQUAL TO
+    0x00f3: 0x2264,     #  LESS-THAN OR EQUAL TO
+    0x00f4: 0x2320,     #  TOP HALF INTEGRAL
+    0x00f5: 0x2321,     #  BOTTOM HALF INTEGRAL
+    0x00f6: 0x00f7,     #  DIVISION SIGN
+    0x00f7: 0x2248,     #  ALMOST EQUAL TO
+    0x00f8: 0x00b0,     #  DEGREE SIGN
+    0x00f9: 0x2219,     #  BULLET OPERATOR
+    0x00fa: 0x00b7,     #  MIDDLE DOT
+    0x00fb: 0x221a,     #  SQUARE ROOT
+    0x00fc: 0x207f,     #  SUPERSCRIPT LATIN SMALL LETTER N
+    0x00fd: 0x00b2,     #  SUPERSCRIPT TWO
+    0x00fe: 0x25a0,     #  BLACK SQUARE
+    0x00ff: 0x00a0,     #  NO-BREAK SPACE
+})
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x0000 -> NULL
+    u'\x01'     #  0x0001 -> START OF HEADING
+    u'\x02'     #  0x0002 -> START OF TEXT
+    u'\x03'     #  0x0003 -> END OF TEXT
+    u'\x04'     #  0x0004 -> END OF TRANSMISSION
+    u'\x05'     #  0x0005 -> ENQUIRY
+    u'\x06'     #  0x0006 -> ACKNOWLEDGE
+    u'\x07'     #  0x0007 -> BELL
+    u'\x08'     #  0x0008 -> BACKSPACE
+    u'\t'       #  0x0009 -> HORIZONTAL TABULATION
+    u'\n'       #  0x000a -> LINE FEED
+    u'\x0b'     #  0x000b -> VERTICAL TABULATION
+    u'\x0c'     #  0x000c -> FORM FEED
+    u'\r'       #  0x000d -> CARRIAGE RETURN
+    u'\x0e'     #  0x000e -> SHIFT OUT
+    u'\x0f'     #  0x000f -> SHIFT IN
+    u'\x10'     #  0x0010 -> DATA LINK ESCAPE
+    u'\x11'     #  0x0011 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x0012 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x0013 -> DEVICE CONTROL THREE
+    u'\x14'     #  0x0014 -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x0015 -> NEGATIVE ACKNOWLEDGE
+    u'\x16'     #  0x0016 -> SYNCHRONOUS IDLE
+    u'\x17'     #  0x0017 -> END OF TRANSMISSION BLOCK
+    u'\x18'     #  0x0018 -> CANCEL
+    u'\x19'     #  0x0019 -> END OF MEDIUM
+    u'\x1a'     #  0x001a -> SUBSTITUTE
+    u'\x1b'     #  0x001b -> ESCAPE
+    u'\x1c'     #  0x001c -> FILE SEPARATOR
+    u'\x1d'     #  0x001d -> GROUP SEPARATOR
+    u'\x1e'     #  0x001e -> RECORD SEPARATOR
+    u'\x1f'     #  0x001f -> UNIT SEPARATOR
+    u' '        #  0x0020 -> SPACE
+    u'!'        #  0x0021 -> EXCLAMATION MARK
+    u'"'        #  0x0022 -> QUOTATION MARK
+    u'#'        #  0x0023 -> NUMBER SIGN
+    u'$'        #  0x0024 -> DOLLAR SIGN
+    u'%'        #  0x0025 -> PERCENT SIGN
+    u'&'        #  0x0026 -> AMPERSAND
+    u"'"        #  0x0027 -> APOSTROPHE
+    u'('        #  0x0028 -> LEFT PARENTHESIS
+    u')'        #  0x0029 -> RIGHT PARENTHESIS
+    u'*'        #  0x002a -> ASTERISK
+    u'+'        #  0x002b -> PLUS SIGN
+    u','        #  0x002c -> COMMA
+    u'-'        #  0x002d -> HYPHEN-MINUS
+    u'.'        #  0x002e -> FULL STOP
+    u'/'        #  0x002f -> SOLIDUS
+    u'0'        #  0x0030 -> DIGIT ZERO
+    u'1'        #  0x0031 -> DIGIT ONE
+    u'2'        #  0x0032 -> DIGIT TWO
+    u'3'        #  0x0033 -> DIGIT THREE
+    u'4'        #  0x0034 -> DIGIT FOUR
+    u'5'        #  0x0035 -> DIGIT FIVE
+    u'6'        #  0x0036 -> DIGIT SIX
+    u'7'        #  0x0037 -> DIGIT SEVEN
+    u'8'        #  0x0038 -> DIGIT EIGHT
+    u'9'        #  0x0039 -> DIGIT NINE
+    u':'        #  0x003a -> COLON
+    u';'        #  0x003b -> SEMICOLON
+    u'<'        #  0x003c -> LESS-THAN SIGN
+    u'='        #  0x003d -> EQUALS SIGN
+    u'>'        #  0x003e -> GREATER-THAN SIGN
+    u'?'        #  0x003f -> QUESTION MARK
+    u'@'        #  0x0040 -> COMMERCIAL AT
+    u'A'        #  0x0041 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x0042 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x0043 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x0044 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x0045 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x0046 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x0047 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x0048 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x0049 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x004a -> LATIN CAPITAL LETTER J
+    u'K'        #  0x004b -> LATIN CAPITAL LETTER K
+    u'L'        #  0x004c -> LATIN CAPITAL LETTER L
+    u'M'        #  0x004d -> LATIN CAPITAL LETTER M
+    u'N'        #  0x004e -> LATIN CAPITAL LETTER N
+    u'O'        #  0x004f -> LATIN CAPITAL LETTER O
+    u'P'        #  0x0050 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x0051 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x0052 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x0053 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x0054 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x0055 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x0056 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x0057 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x0058 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x0059 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x005a -> LATIN CAPITAL LETTER Z
+    u'['        #  0x005b -> LEFT SQUARE BRACKET
+    u'\\'       #  0x005c -> REVERSE SOLIDUS
+    u']'        #  0x005d -> RIGHT SQUARE BRACKET
+    u'^'        #  0x005e -> CIRCUMFLEX ACCENT
+    u'_'        #  0x005f -> LOW LINE
+    u'`'        #  0x0060 -> GRAVE ACCENT
+    u'a'        #  0x0061 -> LATIN SMALL LETTER A
+    u'b'        #  0x0062 -> LATIN SMALL LETTER B
+    u'c'        #  0x0063 -> LATIN SMALL LETTER C
+    u'd'        #  0x0064 -> LATIN SMALL LETTER D
+    u'e'        #  0x0065 -> LATIN SMALL LETTER E
+    u'f'        #  0x0066 -> LATIN SMALL LETTER F
+    u'g'        #  0x0067 -> LATIN SMALL LETTER G
+    u'h'        #  0x0068 -> LATIN SMALL LETTER H
+    u'i'        #  0x0069 -> LATIN SMALL LETTER I
+    u'j'        #  0x006a -> LATIN SMALL LETTER J
+    u'k'        #  0x006b -> LATIN SMALL LETTER K
+    u'l'        #  0x006c -> LATIN SMALL LETTER L
+    u'm'        #  0x006d -> LATIN SMALL LETTER M
+    u'n'        #  0x006e -> LATIN SMALL LETTER N
+    u'o'        #  0x006f -> LATIN SMALL LETTER O
+    u'p'        #  0x0070 -> LATIN SMALL LETTER P
+    u'q'        #  0x0071 -> LATIN SMALL LETTER Q
+    u'r'        #  0x0072 -> LATIN SMALL LETTER R
+    u's'        #  0x0073 -> LATIN SMALL LETTER S
+    u't'        #  0x0074 -> LATIN SMALL LETTER T
+    u'u'        #  0x0075 -> LATIN SMALL LETTER U
+    u'v'        #  0x0076 -> LATIN SMALL LETTER V
+    u'w'        #  0x0077 -> LATIN SMALL LETTER W
+    u'x'        #  0x0078 -> LATIN SMALL LETTER X
+    u'y'        #  0x0079 -> LATIN SMALL LETTER Y
+    u'z'        #  0x007a -> LATIN SMALL LETTER Z
+    u'{'        #  0x007b -> LEFT CURLY BRACKET
+    u'|'        #  0x007c -> VERTICAL LINE
+    u'}'        #  0x007d -> RIGHT CURLY BRACKET
+    u'~'        #  0x007e -> TILDE
+    u'\x7f'     #  0x007f -> DELETE
+    u'\u05d0'   #  0x0080 -> HEBREW LETTER ALEF
+    u'\u05d1'   #  0x0081 -> HEBREW LETTER BET
+    u'\u05d2'   #  0x0082 -> HEBREW LETTER GIMEL
+    u'\u05d3'   #  0x0083 -> HEBREW LETTER DALET
+    u'\u05d4'   #  0x0084 -> HEBREW LETTER HE
+    u'\u05d5'   #  0x0085 -> HEBREW LETTER VAV
+    u'\u05d6'   #  0x0086 -> HEBREW LETTER ZAYIN
+    u'\u05d7'   #  0x0087 -> HEBREW LETTER HET
+    u'\u05d8'   #  0x0088 -> HEBREW LETTER TET
+    u'\u05d9'   #  0x0089 -> HEBREW LETTER YOD
+    u'\u05da'   #  0x008a -> HEBREW LETTER FINAL KAF
+    u'\u05db'   #  0x008b -> HEBREW LETTER KAF
+    u'\u05dc'   #  0x008c -> HEBREW LETTER LAMED
+    u'\u05dd'   #  0x008d -> HEBREW LETTER FINAL MEM
+    u'\u05de'   #  0x008e -> HEBREW LETTER MEM
+    u'\u05df'   #  0x008f -> HEBREW LETTER FINAL NUN
+    u'\u05e0'   #  0x0090 -> HEBREW LETTER NUN
+    u'\u05e1'   #  0x0091 -> HEBREW LETTER SAMEKH
+    u'\u05e2'   #  0x0092 -> HEBREW LETTER AYIN
+    u'\u05e3'   #  0x0093 -> HEBREW LETTER FINAL PE
+    u'\u05e4'   #  0x0094 -> HEBREW LETTER PE
+    u'\u05e5'   #  0x0095 -> HEBREW LETTER FINAL TSADI
+    u'\u05e6'   #  0x0096 -> HEBREW LETTER TSADI
+    u'\u05e7'   #  0x0097 -> HEBREW LETTER QOF
+    u'\u05e8'   #  0x0098 -> HEBREW LETTER RESH
+    u'\u05e9'   #  0x0099 -> HEBREW LETTER SHIN
+    u'\u05ea'   #  0x009a -> HEBREW LETTER TAV
+    u'\xa2'     #  0x009b -> CENT SIGN
+    u'\xa3'     #  0x009c -> POUND SIGN
+    u'\xa5'     #  0x009d -> YEN SIGN
+    u'\u20a7'   #  0x009e -> PESETA SIGN
+    u'\u0192'   #  0x009f -> LATIN SMALL LETTER F WITH HOOK
+    u'\xe1'     #  0x00a0 -> LATIN SMALL LETTER A WITH ACUTE
+    u'\xed'     #  0x00a1 -> LATIN SMALL LETTER I WITH ACUTE
+    u'\xf3'     #  0x00a2 -> LATIN SMALL LETTER O WITH ACUTE
+    u'\xfa'     #  0x00a3 -> LATIN SMALL LETTER U WITH ACUTE
+    u'\xf1'     #  0x00a4 -> LATIN SMALL LETTER N WITH TILDE
+    u'\xd1'     #  0x00a5 -> LATIN CAPITAL LETTER N WITH TILDE
+    u'\xaa'     #  0x00a6 -> FEMININE ORDINAL INDICATOR
+    u'\xba'     #  0x00a7 -> MASCULINE ORDINAL INDICATOR
+    u'\xbf'     #  0x00a8 -> INVERTED QUESTION MARK
+    u'\u2310'   #  0x00a9 -> REVERSED NOT SIGN
+    u'\xac'     #  0x00aa -> NOT SIGN
+    u'\xbd'     #  0x00ab -> VULGAR FRACTION ONE HALF
+    u'\xbc'     #  0x00ac -> VULGAR FRACTION ONE QUARTER
+    u'\xa1'     #  0x00ad -> INVERTED EXCLAMATION MARK
+    u'\xab'     #  0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xbb'     #  0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\u2591'   #  0x00b0 -> LIGHT SHADE
+    u'\u2592'   #  0x00b1 -> MEDIUM SHADE
+    u'\u2593'   #  0x00b2 -> DARK SHADE
+    u'\u2502'   #  0x00b3 -> BOX DRAWINGS LIGHT VERTICAL
+    u'\u2524'   #  0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT
+    u'\u2561'   #  0x00b5 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+    u'\u2562'   #  0x00b6 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
+    u'\u2556'   #  0x00b7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
+    u'\u2555'   #  0x00b8 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
+    u'\u2563'   #  0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+    u'\u2551'   #  0x00ba -> BOX DRAWINGS DOUBLE VERTICAL
+    u'\u2557'   #  0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT
+    u'\u255d'   #  0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT
+    u'\u255c'   #  0x00bd -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
+    u'\u255b'   #  0x00be -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+    u'\u2510'   #  0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT
+    u'\u2514'   #  0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT
+    u'\u2534'   #  0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL
+    u'\u252c'   #  0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+    u'\u251c'   #  0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+    u'\u2500'   #  0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL
+    u'\u253c'   #  0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+    u'\u255e'   #  0x00c6 -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+    u'\u255f'   #  0x00c7 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+    u'\u255a'   #  0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT
+    u'\u2554'   #  0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT
+    u'\u2569'   #  0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+    u'\u2566'   #  0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+    u'\u2560'   #  0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+    u'\u2550'   #  0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL
+    u'\u256c'   #  0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+    u'\u2567'   #  0x00cf -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+    u'\u2568'   #  0x00d0 -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+    u'\u2564'   #  0x00d1 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
+    u'\u2565'   #  0x00d2 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
+    u'\u2559'   #  0x00d3 -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+    u'\u2558'   #  0x00d4 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+    u'\u2552'   #  0x00d5 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+    u'\u2553'   #  0x00d6 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
+    u'\u256b'   #  0x00d7 -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
+    u'\u256a'   #  0x00d8 -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+    u'\u2518'   #  0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT
+    u'\u250c'   #  0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT
+    u'\u2588'   #  0x00db -> FULL BLOCK
+    u'\u2584'   #  0x00dc -> LOWER HALF BLOCK
+    u'\u258c'   #  0x00dd -> LEFT HALF BLOCK
+    u'\u2590'   #  0x00de -> RIGHT HALF BLOCK
+    u'\u2580'   #  0x00df -> UPPER HALF BLOCK
+    u'\u03b1'   #  0x00e0 -> GREEK SMALL LETTER ALPHA
+    u'\xdf'     #  0x00e1 -> LATIN SMALL LETTER SHARP S (GERMAN)
+    u'\u0393'   #  0x00e2 -> GREEK CAPITAL LETTER GAMMA
+    u'\u03c0'   #  0x00e3 -> GREEK SMALL LETTER PI
+    u'\u03a3'   #  0x00e4 -> GREEK CAPITAL LETTER SIGMA
+    u'\u03c3'   #  0x00e5 -> GREEK SMALL LETTER SIGMA
+    u'\xb5'     #  0x00e6 -> MICRO SIGN
+    u'\u03c4'   #  0x00e7 -> GREEK SMALL LETTER TAU
+    u'\u03a6'   #  0x00e8 -> GREEK CAPITAL LETTER PHI
+    u'\u0398'   #  0x00e9 -> GREEK CAPITAL LETTER THETA
+    u'\u03a9'   #  0x00ea -> GREEK CAPITAL LETTER OMEGA
+    u'\u03b4'   #  0x00eb -> GREEK SMALL LETTER DELTA
+    u'\u221e'   #  0x00ec -> INFINITY
+    u'\u03c6'   #  0x00ed -> GREEK SMALL LETTER PHI
+    u'\u03b5'   #  0x00ee -> GREEK SMALL LETTER EPSILON
+    u'\u2229'   #  0x00ef -> INTERSECTION
+    u'\u2261'   #  0x00f0 -> IDENTICAL TO
+    u'\xb1'     #  0x00f1 -> PLUS-MINUS SIGN
+    u'\u2265'   #  0x00f2 -> GREATER-THAN OR EQUAL TO
+    u'\u2264'   #  0x00f3 -> LESS-THAN OR EQUAL TO
+    u'\u2320'   #  0x00f4 -> TOP HALF INTEGRAL
+    u'\u2321'   #  0x00f5 -> BOTTOM HALF INTEGRAL
+    u'\xf7'     #  0x00f6 -> DIVISION SIGN
+    u'\u2248'   #  0x00f7 -> ALMOST EQUAL TO
+    u'\xb0'     #  0x00f8 -> DEGREE SIGN
+    u'\u2219'   #  0x00f9 -> BULLET OPERATOR
+    u'\xb7'     #  0x00fa -> MIDDLE DOT
+    u'\u221a'   #  0x00fb -> SQUARE ROOT
+    u'\u207f'   #  0x00fc -> SUPERSCRIPT LATIN SMALL LETTER N
+    u'\xb2'     #  0x00fd -> SUPERSCRIPT TWO
+    u'\u25a0'   #  0x00fe -> BLACK SQUARE
+    u'\xa0'     #  0x00ff -> NO-BREAK SPACE
+)
+
+### Encoding Map
+
+encoding_map = {
+    0x0000: 0x0000,     #  NULL
+    0x0001: 0x0001,     #  START OF HEADING
+    0x0002: 0x0002,     #  START OF TEXT
+    0x0003: 0x0003,     #  END OF TEXT
+    0x0004: 0x0004,     #  END OF TRANSMISSION
+    0x0005: 0x0005,     #  ENQUIRY
+    0x0006: 0x0006,     #  ACKNOWLEDGE
+    0x0007: 0x0007,     #  BELL
+    0x0008: 0x0008,     #  BACKSPACE
+    0x0009: 0x0009,     #  HORIZONTAL TABULATION
+    0x000a: 0x000a,     #  LINE FEED
+    0x000b: 0x000b,     #  VERTICAL TABULATION
+    0x000c: 0x000c,     #  FORM FEED
+    0x000d: 0x000d,     #  CARRIAGE RETURN
+    0x000e: 0x000e,     #  SHIFT OUT
+    0x000f: 0x000f,     #  SHIFT IN
+    0x0010: 0x0010,     #  DATA LINK ESCAPE
+    0x0011: 0x0011,     #  DEVICE CONTROL ONE
+    0x0012: 0x0012,     #  DEVICE CONTROL TWO
+    0x0013: 0x0013,     #  DEVICE CONTROL THREE
+    0x0014: 0x0014,     #  DEVICE CONTROL FOUR
+    0x0015: 0x0015,     #  NEGATIVE ACKNOWLEDGE
+    0x0016: 0x0016,     #  SYNCHRONOUS IDLE
+    0x0017: 0x0017,     #  END OF TRANSMISSION BLOCK
+    0x0018: 0x0018,     #  CANCEL
+    0x0019: 0x0019,     #  END OF MEDIUM
+    0x001a: 0x001a,     #  SUBSTITUTE
+    0x001b: 0x001b,     #  ESCAPE
+    0x001c: 0x001c,     #  FILE SEPARATOR
+    0x001d: 0x001d,     #  GROUP SEPARATOR
+    0x001e: 0x001e,     #  RECORD SEPARATOR
+    0x001f: 0x001f,     #  UNIT SEPARATOR
+    0x0020: 0x0020,     #  SPACE
+    0x0021: 0x0021,     #  EXCLAMATION MARK
+    0x0022: 0x0022,     #  QUOTATION MARK
+    0x0023: 0x0023,     #  NUMBER SIGN
+    0x0024: 0x0024,     #  DOLLAR SIGN
+    0x0025: 0x0025,     #  PERCENT SIGN
+    0x0026: 0x0026,     #  AMPERSAND
+    0x0027: 0x0027,     #  APOSTROPHE
+    0x0028: 0x0028,     #  LEFT PARENTHESIS
+    0x0029: 0x0029,     #  RIGHT PARENTHESIS
+    0x002a: 0x002a,     #  ASTERISK
+    0x002b: 0x002b,     #  PLUS SIGN
+    0x002c: 0x002c,     #  COMMA
+    0x002d: 0x002d,     #  HYPHEN-MINUS
+    0x002e: 0x002e,     #  FULL STOP
+    0x002f: 0x002f,     #  SOLIDUS
+    0x0030: 0x0030,     #  DIGIT ZERO
+    0x0031: 0x0031,     #  DIGIT ONE
+    0x0032: 0x0032,     #  DIGIT TWO
+    0x0033: 0x0033,     #  DIGIT THREE
+    0x0034: 0x0034,     #  DIGIT FOUR
+    0x0035: 0x0035,     #  DIGIT FIVE
+    0x0036: 0x0036,     #  DIGIT SIX
+    0x0037: 0x0037,     #  DIGIT SEVEN
+    0x0038: 0x0038,     #  DIGIT EIGHT
+    0x0039: 0x0039,     #  DIGIT NINE
+    0x003a: 0x003a,     #  COLON
+    0x003b: 0x003b,     #  SEMICOLON
+    0x003c: 0x003c,     #  LESS-THAN SIGN
+    0x003d: 0x003d,     #  EQUALS SIGN
+    0x003e: 0x003e,     #  GREATER-THAN SIGN
+    0x003f: 0x003f,     #  QUESTION MARK
+    0x0040: 0x0040,     #  COMMERCIAL AT
+    0x0041: 0x0041,     #  LATIN CAPITAL LETTER A
+    0x0042: 0x0042,     #  LATIN CAPITAL LETTER B
+    0x0043: 0x0043,     #  LATIN CAPITAL LETTER C
+    0x0044: 0x0044,     #  LATIN CAPITAL LETTER D
+    0x0045: 0x0045,     #  LATIN CAPITAL LETTER E
+    0x0046: 0x0046,     #  LATIN CAPITAL LETTER F
+    0x0047: 0x0047,     #  LATIN CAPITAL LETTER G
+    0x0048: 0x0048,     #  LATIN CAPITAL LETTER H
+    0x0049: 0x0049,     #  LATIN CAPITAL LETTER I
+    0x004a: 0x004a,     #  LATIN CAPITAL LETTER J
+    0x004b: 0x004b,     #  LATIN CAPITAL LETTER K
+    0x004c: 0x004c,     #  LATIN CAPITAL LETTER L
+    0x004d: 0x004d,     #  LATIN CAPITAL LETTER M
+    0x004e: 0x004e,     #  LATIN CAPITAL LETTER N
+    0x004f: 0x004f,     #  LATIN CAPITAL LETTER O
+    0x0050: 0x0050,     #  LATIN CAPITAL LETTER P
+    0x0051: 0x0051,     #  LATIN CAPITAL LETTER Q
+    0x0052: 0x0052,     #  LATIN CAPITAL LETTER R
+    0x0053: 0x0053,     #  LATIN CAPITAL LETTER S
+    0x0054: 0x0054,     #  LATIN CAPITAL LETTER T
+    0x0055: 0x0055,     #  LATIN CAPITAL LETTER U
+    0x0056: 0x0056,     #  LATIN CAPITAL LETTER V
+    0x0057: 0x0057,     #  LATIN CAPITAL LETTER W
+    0x0058: 0x0058,     #  LATIN CAPITAL LETTER X
+    0x0059: 0x0059,     #  LATIN CAPITAL LETTER Y
+    0x005a: 0x005a,     #  LATIN CAPITAL LETTER Z
+    0x005b: 0x005b,     #  LEFT SQUARE BRACKET
+    0x005c: 0x005c,     #  REVERSE SOLIDUS
+    0x005d: 0x005d,     #  RIGHT SQUARE BRACKET
+    0x005e: 0x005e,     #  CIRCUMFLEX ACCENT
+    0x005f: 0x005f,     #  LOW LINE
+    0x0060: 0x0060,     #  GRAVE ACCENT
+    0x0061: 0x0061,     #  LATIN SMALL LETTER A
+    0x0062: 0x0062,     #  LATIN SMALL LETTER B
+    0x0063: 0x0063,     #  LATIN SMALL LETTER C
+    0x0064: 0x0064,     #  LATIN SMALL LETTER D
+    0x0065: 0x0065,     #  LATIN SMALL LETTER E
+    0x0066: 0x0066,     #  LATIN SMALL LETTER F
+    0x0067: 0x0067,     #  LATIN SMALL LETTER G
+    0x0068: 0x0068,     #  LATIN SMALL LETTER H
+    0x0069: 0x0069,     #  LATIN SMALL LETTER I
+    0x006a: 0x006a,     #  LATIN SMALL LETTER J
+    0x006b: 0x006b,     #  LATIN SMALL LETTER K
+    0x006c: 0x006c,     #  LATIN SMALL LETTER L
+    0x006d: 0x006d,     #  LATIN SMALL LETTER M
+    0x006e: 0x006e,     #  LATIN SMALL LETTER N
+    0x006f: 0x006f,     #  LATIN SMALL LETTER O
+    0x0070: 0x0070,     #  LATIN SMALL LETTER P
+    0x0071: 0x0071,     #  LATIN SMALL LETTER Q
+    0x0072: 0x0072,     #  LATIN SMALL LETTER R
+    0x0073: 0x0073,     #  LATIN SMALL LETTER S
+    0x0074: 0x0074,     #  LATIN SMALL LETTER T
+    0x0075: 0x0075,     #  LATIN SMALL LETTER U
+    0x0076: 0x0076,     #  LATIN SMALL LETTER V
+    0x0077: 0x0077,     #  LATIN SMALL LETTER W
+    0x0078: 0x0078,     #  LATIN SMALL LETTER X
+    0x0079: 0x0079,     #  LATIN SMALL LETTER Y
+    0x007a: 0x007a,     #  LATIN SMALL LETTER Z
+    0x007b: 0x007b,     #  LEFT CURLY BRACKET
+    0x007c: 0x007c,     #  VERTICAL LINE
+    0x007d: 0x007d,     #  RIGHT CURLY BRACKET
+    0x007e: 0x007e,     #  TILDE
+    0x007f: 0x007f,     #  DELETE
+    0x00a0: 0x00ff,     #  NO-BREAK SPACE
+    0x00a1: 0x00ad,     #  INVERTED EXCLAMATION MARK
+    0x00a2: 0x009b,     #  CENT SIGN
+    0x00a3: 0x009c,     #  POUND SIGN
+    0x00a5: 0x009d,     #  YEN SIGN
+    0x00aa: 0x00a6,     #  FEMININE ORDINAL INDICATOR
+    0x00ab: 0x00ae,     #  LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    0x00ac: 0x00aa,     #  NOT SIGN
+    0x00b0: 0x00f8,     #  DEGREE SIGN
+    0x00b1: 0x00f1,     #  PLUS-MINUS SIGN
+    0x00b2: 0x00fd,     #  SUPERSCRIPT TWO
+    0x00b5: 0x00e6,     #  MICRO SIGN
+    0x00b7: 0x00fa,     #  MIDDLE DOT
+    0x00ba: 0x00a7,     #  MASCULINE ORDINAL INDICATOR
+    0x00bb: 0x00af,     #  RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    0x00bc: 0x00ac,     #  VULGAR FRACTION ONE QUARTER
+    0x00bd: 0x00ab,     #  VULGAR FRACTION ONE HALF
+    0x00bf: 0x00a8,     #  INVERTED QUESTION MARK
+    0x00d1: 0x00a5,     #  LATIN CAPITAL LETTER N WITH TILDE
+    0x00df: 0x00e1,     #  LATIN SMALL LETTER SHARP S (GERMAN)
+    0x00e1: 0x00a0,     #  LATIN SMALL LETTER A WITH ACUTE
+    0x00ed: 0x00a1,     #  LATIN SMALL LETTER I WITH ACUTE
+    0x00f1: 0x00a4,     #  LATIN SMALL LETTER N WITH TILDE
+    0x00f3: 0x00a2,     #  LATIN SMALL LETTER O WITH ACUTE
+    0x00f7: 0x00f6,     #  DIVISION SIGN
+    0x00fa: 0x00a3,     #  LATIN SMALL LETTER U WITH ACUTE
+    0x0192: 0x009f,     #  LATIN SMALL LETTER F WITH HOOK
+    0x0393: 0x00e2,     #  GREEK CAPITAL LETTER GAMMA
+    0x0398: 0x00e9,     #  GREEK CAPITAL LETTER THETA
+    0x03a3: 0x00e4,     #  GREEK CAPITAL LETTER SIGMA
+    0x03a6: 0x00e8,     #  GREEK CAPITAL LETTER PHI
+    0x03a9: 0x00ea,     #  GREEK CAPITAL LETTER OMEGA
+    0x03b1: 0x00e0,     #  GREEK SMALL LETTER ALPHA
+    0x03b4: 0x00eb,     #  GREEK SMALL LETTER DELTA
+    0x03b5: 0x00ee,     #  GREEK SMALL LETTER EPSILON
+    0x03c0: 0x00e3,     #  GREEK SMALL LETTER PI
+    0x03c3: 0x00e5,     #  GREEK SMALL LETTER SIGMA
+    0x03c4: 0x00e7,     #  GREEK SMALL LETTER TAU
+    0x03c6: 0x00ed,     #  GREEK SMALL LETTER PHI
+    0x05d0: 0x0080,     #  HEBREW LETTER ALEF
+    0x05d1: 0x0081,     #  HEBREW LETTER BET
+    0x05d2: 0x0082,     #  HEBREW LETTER GIMEL
+    0x05d3: 0x0083,     #  HEBREW LETTER DALET
+    0x05d4: 0x0084,     #  HEBREW LETTER HE
+    0x05d5: 0x0085,     #  HEBREW LETTER VAV
+    0x05d6: 0x0086,     #  HEBREW LETTER ZAYIN
+    0x05d7: 0x0087,     #  HEBREW LETTER HET
+    0x05d8: 0x0088,     #  HEBREW LETTER TET
+    0x05d9: 0x0089,     #  HEBREW LETTER YOD
+    0x05da: 0x008a,     #  HEBREW LETTER FINAL KAF
+    0x05db: 0x008b,     #  HEBREW LETTER KAF
+    0x05dc: 0x008c,     #  HEBREW LETTER LAMED
+    0x05dd: 0x008d,     #  HEBREW LETTER FINAL MEM
+    0x05de: 0x008e,     #  HEBREW LETTER MEM
+    0x05df: 0x008f,     #  HEBREW LETTER FINAL NUN
+    0x05e0: 0x0090,     #  HEBREW LETTER NUN
+    0x05e1: 0x0091,     #  HEBREW LETTER SAMEKH
+    0x05e2: 0x0092,     #  HEBREW LETTER AYIN
+    0x05e3: 0x0093,     #  HEBREW LETTER FINAL PE
+    0x05e4: 0x0094,     #  HEBREW LETTER PE
+    0x05e5: 0x0095,     #  HEBREW LETTER FINAL TSADI
+    0x05e6: 0x0096,     #  HEBREW LETTER TSADI
+    0x05e7: 0x0097,     #  HEBREW LETTER QOF
+    0x05e8: 0x0098,     #  HEBREW LETTER RESH
+    0x05e9: 0x0099,     #  HEBREW LETTER SHIN
+    0x05ea: 0x009a,     #  HEBREW LETTER TAV
+    0x207f: 0x00fc,     #  SUPERSCRIPT LATIN SMALL LETTER N
+    0x20a7: 0x009e,     #  PESETA SIGN
+    0x2219: 0x00f9,     #  BULLET OPERATOR
+    0x221a: 0x00fb,     #  SQUARE ROOT
+    0x221e: 0x00ec,     #  INFINITY
+    0x2229: 0x00ef,     #  INTERSECTION
+    0x2248: 0x00f7,     #  ALMOST EQUAL TO
+    0x2261: 0x00f0,     #  IDENTICAL TO
+    0x2264: 0x00f3,     #  LESS-THAN OR EQUAL TO
+    0x2265: 0x00f2,     #  GREATER-THAN OR EQUAL TO
+    0x2310: 0x00a9,     #  REVERSED NOT SIGN
+    0x2320: 0x00f4,     #  TOP HALF INTEGRAL
+    0x2321: 0x00f5,     #  BOTTOM HALF INTEGRAL
+    0x2500: 0x00c4,     #  BOX DRAWINGS LIGHT HORIZONTAL
+    0x2502: 0x00b3,     #  BOX DRAWINGS LIGHT VERTICAL
+    0x250c: 0x00da,     #  BOX DRAWINGS LIGHT DOWN AND RIGHT
+    0x2510: 0x00bf,     #  BOX DRAWINGS LIGHT DOWN AND LEFT
+    0x2514: 0x00c0,     #  BOX DRAWINGS LIGHT UP AND RIGHT
+    0x2518: 0x00d9,     #  BOX DRAWINGS LIGHT UP AND LEFT
+    0x251c: 0x00c3,     #  BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+    0x2524: 0x00b4,     #  BOX DRAWINGS LIGHT VERTICAL AND LEFT
+    0x252c: 0x00c2,     #  BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+    0x2534: 0x00c1,     #  BOX DRAWINGS LIGHT UP AND HORIZONTAL
+    0x253c: 0x00c5,     #  BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+    0x2550: 0x00cd,     #  BOX DRAWINGS DOUBLE HORIZONTAL
+    0x2551: 0x00ba,     #  BOX DRAWINGS DOUBLE VERTICAL
+    0x2552: 0x00d5,     #  BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+    0x2553: 0x00d6,     #  BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
+    0x2554: 0x00c9,     #  BOX DRAWINGS DOUBLE DOWN AND RIGHT
+    0x2555: 0x00b8,     #  BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
+    0x2556: 0x00b7,     #  BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
+    0x2557: 0x00bb,     #  BOX DRAWINGS DOUBLE DOWN AND LEFT
+    0x2558: 0x00d4,     #  BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+    0x2559: 0x00d3,     #  BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+    0x255a: 0x00c8,     #  BOX DRAWINGS DOUBLE UP AND RIGHT
+    0x255b: 0x00be,     #  BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+    0x255c: 0x00bd,     #  BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
+    0x255d: 0x00bc,     #  BOX DRAWINGS DOUBLE UP AND LEFT
+    0x255e: 0x00c6,     #  BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+    0x255f: 0x00c7,     #  BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+    0x2560: 0x00cc,     #  BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+    0x2561: 0x00b5,     #  BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+    0x2562: 0x00b6,     #  BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
+    0x2563: 0x00b9,     #  BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+    0x2564: 0x00d1,     #  BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
+    0x2565: 0x00d2,     #  BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
+    0x2566: 0x00cb,     #  BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+    0x2567: 0x00cf,     #  BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+    0x2568: 0x00d0,     #  BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+    0x2569: 0x00ca,     #  BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+    0x256a: 0x00d8,     #  BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+    0x256b: 0x00d7,     #  BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
+    0x256c: 0x00ce,     #  BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+    0x2580: 0x00df,     #  UPPER HALF BLOCK
+    0x2584: 0x00dc,     #  LOWER HALF BLOCK
+    0x2588: 0x00db,     #  FULL BLOCK
+    0x258c: 0x00dd,     #  LEFT HALF BLOCK
+    0x2590: 0x00de,     #  RIGHT HALF BLOCK
+    0x2591: 0x00b0,     #  LIGHT SHADE
+    0x2592: 0x00b1,     #  MEDIUM SHADE
+    0x2593: 0x00b2,     #  DARK SHADE
+    0x25a0: 0x00fe,     #  BLACK SQUARE
+}

Added: vendor/Python/current/Lib/encodings/cp863.py
===================================================================
--- vendor/Python/current/Lib/encodings/cp863.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/cp863.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,698 @@
+""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP863.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_map)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='cp863',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+### Decoding Map
+
+decoding_map = codecs.make_identity_dict(range(256))
+decoding_map.update({
+    0x0080: 0x00c7,     #  LATIN CAPITAL LETTER C WITH CEDILLA
+    0x0081: 0x00fc,     #  LATIN SMALL LETTER U WITH DIAERESIS
+    0x0082: 0x00e9,     #  LATIN SMALL LETTER E WITH ACUTE
+    0x0083: 0x00e2,     #  LATIN SMALL LETTER A WITH CIRCUMFLEX
+    0x0084: 0x00c2,     #  LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+    0x0085: 0x00e0,     #  LATIN SMALL LETTER A WITH GRAVE
+    0x0086: 0x00b6,     #  PILCROW SIGN
+    0x0087: 0x00e7,     #  LATIN SMALL LETTER C WITH CEDILLA
+    0x0088: 0x00ea,     #  LATIN SMALL LETTER E WITH CIRCUMFLEX
+    0x0089: 0x00eb,     #  LATIN SMALL LETTER E WITH DIAERESIS
+    0x008a: 0x00e8,     #  LATIN SMALL LETTER E WITH GRAVE
+    0x008b: 0x00ef,     #  LATIN SMALL LETTER I WITH DIAERESIS
+    0x008c: 0x00ee,     #  LATIN SMALL LETTER I WITH CIRCUMFLEX
+    0x008d: 0x2017,     #  DOUBLE LOW LINE
+    0x008e: 0x00c0,     #  LATIN CAPITAL LETTER A WITH GRAVE
+    0x008f: 0x00a7,     #  SECTION SIGN
+    0x0090: 0x00c9,     #  LATIN CAPITAL LETTER E WITH ACUTE
+    0x0091: 0x00c8,     #  LATIN CAPITAL LETTER E WITH GRAVE
+    0x0092: 0x00ca,     #  LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+    0x0093: 0x00f4,     #  LATIN SMALL LETTER O WITH CIRCUMFLEX
+    0x0094: 0x00cb,     #  LATIN CAPITAL LETTER E WITH DIAERESIS
+    0x0095: 0x00cf,     #  LATIN CAPITAL LETTER I WITH DIAERESIS
+    0x0096: 0x00fb,     #  LATIN SMALL LETTER U WITH CIRCUMFLEX
+    0x0097: 0x00f9,     #  LATIN SMALL LETTER U WITH GRAVE
+    0x0098: 0x00a4,     #  CURRENCY SIGN
+    0x0099: 0x00d4,     #  LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+    0x009a: 0x00dc,     #  LATIN CAPITAL LETTER U WITH DIAERESIS
+    0x009b: 0x00a2,     #  CENT SIGN
+    0x009c: 0x00a3,     #  POUND SIGN
+    0x009d: 0x00d9,     #  LATIN CAPITAL LETTER U WITH GRAVE
+    0x009e: 0x00db,     #  LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+    0x009f: 0x0192,     #  LATIN SMALL LETTER F WITH HOOK
+    0x00a0: 0x00a6,     #  BROKEN BAR
+    0x00a1: 0x00b4,     #  ACUTE ACCENT
+    0x00a2: 0x00f3,     #  LATIN SMALL LETTER O WITH ACUTE
+    0x00a3: 0x00fa,     #  LATIN SMALL LETTER U WITH ACUTE
+    0x00a4: 0x00a8,     #  DIAERESIS
+    0x00a5: 0x00b8,     #  CEDILLA
+    0x00a6: 0x00b3,     #  SUPERSCRIPT THREE
+    0x00a7: 0x00af,     #  MACRON
+    0x00a8: 0x00ce,     #  LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+    0x00a9: 0x2310,     #  REVERSED NOT SIGN
+    0x00aa: 0x00ac,     #  NOT SIGN
+    0x00ab: 0x00bd,     #  VULGAR FRACTION ONE HALF
+    0x00ac: 0x00bc,     #  VULGAR FRACTION ONE QUARTER
+    0x00ad: 0x00be,     #  VULGAR FRACTION THREE QUARTERS
+    0x00ae: 0x00ab,     #  LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    0x00af: 0x00bb,     #  RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    0x00b0: 0x2591,     #  LIGHT SHADE
+    0x00b1: 0x2592,     #  MEDIUM SHADE
+    0x00b2: 0x2593,     #  DARK SHADE
+    0x00b3: 0x2502,     #  BOX DRAWINGS LIGHT VERTICAL
+    0x00b4: 0x2524,     #  BOX DRAWINGS LIGHT VERTICAL AND LEFT
+    0x00b5: 0x2561,     #  BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+    0x00b6: 0x2562,     #  BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
+    0x00b7: 0x2556,     #  BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
+    0x00b8: 0x2555,     #  BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
+    0x00b9: 0x2563,     #  BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+    0x00ba: 0x2551,     #  BOX DRAWINGS DOUBLE VERTICAL
+    0x00bb: 0x2557,     #  BOX DRAWINGS DOUBLE DOWN AND LEFT
+    0x00bc: 0x255d,     #  BOX DRAWINGS DOUBLE UP AND LEFT
+    0x00bd: 0x255c,     #  BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
+    0x00be: 0x255b,     #  BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+    0x00bf: 0x2510,     #  BOX DRAWINGS LIGHT DOWN AND LEFT
+    0x00c0: 0x2514,     #  BOX DRAWINGS LIGHT UP AND RIGHT
+    0x00c1: 0x2534,     #  BOX DRAWINGS LIGHT UP AND HORIZONTAL
+    0x00c2: 0x252c,     #  BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+    0x00c3: 0x251c,     #  BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+    0x00c4: 0x2500,     #  BOX DRAWINGS LIGHT HORIZONTAL
+    0x00c5: 0x253c,     #  BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+    0x00c6: 0x255e,     #  BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+    0x00c7: 0x255f,     #  BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+    0x00c8: 0x255a,     #  BOX DRAWINGS DOUBLE UP AND RIGHT
+    0x00c9: 0x2554,     #  BOX DRAWINGS DOUBLE DOWN AND RIGHT
+    0x00ca: 0x2569,     #  BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+    0x00cb: 0x2566,     #  BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+    0x00cc: 0x2560,     #  BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+    0x00cd: 0x2550,     #  BOX DRAWINGS DOUBLE HORIZONTAL
+    0x00ce: 0x256c,     #  BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+    0x00cf: 0x2567,     #  BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+    0x00d0: 0x2568,     #  BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+    0x00d1: 0x2564,     #  BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
+    0x00d2: 0x2565,     #  BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
+    0x00d3: 0x2559,     #  BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+    0x00d4: 0x2558,     #  BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+    0x00d5: 0x2552,     #  BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+    0x00d6: 0x2553,     #  BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
+    0x00d7: 0x256b,     #  BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
+    0x00d8: 0x256a,     #  BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+    0x00d9: 0x2518,     #  BOX DRAWINGS LIGHT UP AND LEFT
+    0x00da: 0x250c,     #  BOX DRAWINGS LIGHT DOWN AND RIGHT
+    0x00db: 0x2588,     #  FULL BLOCK
+    0x00dc: 0x2584,     #  LOWER HALF BLOCK
+    0x00dd: 0x258c,     #  LEFT HALF BLOCK
+    0x00de: 0x2590,     #  RIGHT HALF BLOCK
+    0x00df: 0x2580,     #  UPPER HALF BLOCK
+    0x00e0: 0x03b1,     #  GREEK SMALL LETTER ALPHA
+    0x00e1: 0x00df,     #  LATIN SMALL LETTER SHARP S
+    0x00e2: 0x0393,     #  GREEK CAPITAL LETTER GAMMA
+    0x00e3: 0x03c0,     #  GREEK SMALL LETTER PI
+    0x00e4: 0x03a3,     #  GREEK CAPITAL LETTER SIGMA
+    0x00e5: 0x03c3,     #  GREEK SMALL LETTER SIGMA
+    0x00e6: 0x00b5,     #  MICRO SIGN
+    0x00e7: 0x03c4,     #  GREEK SMALL LETTER TAU
+    0x00e8: 0x03a6,     #  GREEK CAPITAL LETTER PHI
+    0x00e9: 0x0398,     #  GREEK CAPITAL LETTER THETA
+    0x00ea: 0x03a9,     #  GREEK CAPITAL LETTER OMEGA
+    0x00eb: 0x03b4,     #  GREEK SMALL LETTER DELTA
+    0x00ec: 0x221e,     #  INFINITY
+    0x00ed: 0x03c6,     #  GREEK SMALL LETTER PHI
+    0x00ee: 0x03b5,     #  GREEK SMALL LETTER EPSILON
+    0x00ef: 0x2229,     #  INTERSECTION
+    0x00f0: 0x2261,     #  IDENTICAL TO
+    0x00f1: 0x00b1,     #  PLUS-MINUS SIGN
+    0x00f2: 0x2265,     #  GREATER-THAN OR EQUAL TO
+    0x00f3: 0x2264,     #  LESS-THAN OR EQUAL TO
+    0x00f4: 0x2320,     #  TOP HALF INTEGRAL
+    0x00f5: 0x2321,     #  BOTTOM HALF INTEGRAL
+    0x00f6: 0x00f7,     #  DIVISION SIGN
+    0x00f7: 0x2248,     #  ALMOST EQUAL TO
+    0x00f8: 0x00b0,     #  DEGREE SIGN
+    0x00f9: 0x2219,     #  BULLET OPERATOR
+    0x00fa: 0x00b7,     #  MIDDLE DOT
+    0x00fb: 0x221a,     #  SQUARE ROOT
+    0x00fc: 0x207f,     #  SUPERSCRIPT LATIN SMALL LETTER N
+    0x00fd: 0x00b2,     #  SUPERSCRIPT TWO
+    0x00fe: 0x25a0,     #  BLACK SQUARE
+    0x00ff: 0x00a0,     #  NO-BREAK SPACE
+})
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x0000 -> NULL
+    u'\x01'     #  0x0001 -> START OF HEADING
+    u'\x02'     #  0x0002 -> START OF TEXT
+    u'\x03'     #  0x0003 -> END OF TEXT
+    u'\x04'     #  0x0004 -> END OF TRANSMISSION
+    u'\x05'     #  0x0005 -> ENQUIRY
+    u'\x06'     #  0x0006 -> ACKNOWLEDGE
+    u'\x07'     #  0x0007 -> BELL
+    u'\x08'     #  0x0008 -> BACKSPACE
+    u'\t'       #  0x0009 -> HORIZONTAL TABULATION
+    u'\n'       #  0x000a -> LINE FEED
+    u'\x0b'     #  0x000b -> VERTICAL TABULATION
+    u'\x0c'     #  0x000c -> FORM FEED
+    u'\r'       #  0x000d -> CARRIAGE RETURN
+    u'\x0e'     #  0x000e -> SHIFT OUT
+    u'\x0f'     #  0x000f -> SHIFT IN
+    u'\x10'     #  0x0010 -> DATA LINK ESCAPE
+    u'\x11'     #  0x0011 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x0012 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x0013 -> DEVICE CONTROL THREE
+    u'\x14'     #  0x0014 -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x0015 -> NEGATIVE ACKNOWLEDGE
+    u'\x16'     #  0x0016 -> SYNCHRONOUS IDLE
+    u'\x17'     #  0x0017 -> END OF TRANSMISSION BLOCK
+    u'\x18'     #  0x0018 -> CANCEL
+    u'\x19'     #  0x0019 -> END OF MEDIUM
+    u'\x1a'     #  0x001a -> SUBSTITUTE
+    u'\x1b'     #  0x001b -> ESCAPE
+    u'\x1c'     #  0x001c -> FILE SEPARATOR
+    u'\x1d'     #  0x001d -> GROUP SEPARATOR
+    u'\x1e'     #  0x001e -> RECORD SEPARATOR
+    u'\x1f'     #  0x001f -> UNIT SEPARATOR
+    u' '        #  0x0020 -> SPACE
+    u'!'        #  0x0021 -> EXCLAMATION MARK
+    u'"'        #  0x0022 -> QUOTATION MARK
+    u'#'        #  0x0023 -> NUMBER SIGN
+    u'$'        #  0x0024 -> DOLLAR SIGN
+    u'%'        #  0x0025 -> PERCENT SIGN
+    u'&'        #  0x0026 -> AMPERSAND
+    u"'"        #  0x0027 -> APOSTROPHE
+    u'('        #  0x0028 -> LEFT PARENTHESIS
+    u')'        #  0x0029 -> RIGHT PARENTHESIS
+    u'*'        #  0x002a -> ASTERISK
+    u'+'        #  0x002b -> PLUS SIGN
+    u','        #  0x002c -> COMMA
+    u'-'        #  0x002d -> HYPHEN-MINUS
+    u'.'        #  0x002e -> FULL STOP
+    u'/'        #  0x002f -> SOLIDUS
+    u'0'        #  0x0030 -> DIGIT ZERO
+    u'1'        #  0x0031 -> DIGIT ONE
+    u'2'        #  0x0032 -> DIGIT TWO
+    u'3'        #  0x0033 -> DIGIT THREE
+    u'4'        #  0x0034 -> DIGIT FOUR
+    u'5'        #  0x0035 -> DIGIT FIVE
+    u'6'        #  0x0036 -> DIGIT SIX
+    u'7'        #  0x0037 -> DIGIT SEVEN
+    u'8'        #  0x0038 -> DIGIT EIGHT
+    u'9'        #  0x0039 -> DIGIT NINE
+    u':'        #  0x003a -> COLON
+    u';'        #  0x003b -> SEMICOLON
+    u'<'        #  0x003c -> LESS-THAN SIGN
+    u'='        #  0x003d -> EQUALS SIGN
+    u'>'        #  0x003e -> GREATER-THAN SIGN
+    u'?'        #  0x003f -> QUESTION MARK
+    u'@'        #  0x0040 -> COMMERCIAL AT
+    u'A'        #  0x0041 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x0042 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x0043 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x0044 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x0045 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x0046 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x0047 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x0048 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x0049 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x004a -> LATIN CAPITAL LETTER J
+    u'K'        #  0x004b -> LATIN CAPITAL LETTER K
+    u'L'        #  0x004c -> LATIN CAPITAL LETTER L
+    u'M'        #  0x004d -> LATIN CAPITAL LETTER M
+    u'N'        #  0x004e -> LATIN CAPITAL LETTER N
+    u'O'        #  0x004f -> LATIN CAPITAL LETTER O
+    u'P'        #  0x0050 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x0051 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x0052 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x0053 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x0054 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x0055 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x0056 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x0057 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x0058 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x0059 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x005a -> LATIN CAPITAL LETTER Z
+    u'['        #  0x005b -> LEFT SQUARE BRACKET
+    u'\\'       #  0x005c -> REVERSE SOLIDUS
+    u']'        #  0x005d -> RIGHT SQUARE BRACKET
+    u'^'        #  0x005e -> CIRCUMFLEX ACCENT
+    u'_'        #  0x005f -> LOW LINE
+    u'`'        #  0x0060 -> GRAVE ACCENT
+    u'a'        #  0x0061 -> LATIN SMALL LETTER A
+    u'b'        #  0x0062 -> LATIN SMALL LETTER B
+    u'c'        #  0x0063 -> LATIN SMALL LETTER C
+    u'd'        #  0x0064 -> LATIN SMALL LETTER D
+    u'e'        #  0x0065 -> LATIN SMALL LETTER E
+    u'f'        #  0x0066 -> LATIN SMALL LETTER F
+    u'g'        #  0x0067 -> LATIN SMALL LETTER G
+    u'h'        #  0x0068 -> LATIN SMALL LETTER H
+    u'i'        #  0x0069 -> LATIN SMALL LETTER I
+    u'j'        #  0x006a -> LATIN SMALL LETTER J
+    u'k'        #  0x006b -> LATIN SMALL LETTER K
+    u'l'        #  0x006c -> LATIN SMALL LETTER L
+    u'm'        #  0x006d -> LATIN SMALL LETTER M
+    u'n'        #  0x006e -> LATIN SMALL LETTER N
+    u'o'        #  0x006f -> LATIN SMALL LETTER O
+    u'p'        #  0x0070 -> LATIN SMALL LETTER P
+    u'q'        #  0x0071 -> LATIN SMALL LETTER Q
+    u'r'        #  0x0072 -> LATIN SMALL LETTER R
+    u's'        #  0x0073 -> LATIN SMALL LETTER S
+    u't'        #  0x0074 -> LATIN SMALL LETTER T
+    u'u'        #  0x0075 -> LATIN SMALL LETTER U
+    u'v'        #  0x0076 -> LATIN SMALL LETTER V
+    u'w'        #  0x0077 -> LATIN SMALL LETTER W
+    u'x'        #  0x0078 -> LATIN SMALL LETTER X
+    u'y'        #  0x0079 -> LATIN SMALL LETTER Y
+    u'z'        #  0x007a -> LATIN SMALL LETTER Z
+    u'{'        #  0x007b -> LEFT CURLY BRACKET
+    u'|'        #  0x007c -> VERTICAL LINE
+    u'}'        #  0x007d -> RIGHT CURLY BRACKET
+    u'~'        #  0x007e -> TILDE
+    u'\x7f'     #  0x007f -> DELETE
+    u'\xc7'     #  0x0080 -> LATIN CAPITAL LETTER C WITH CEDILLA
+    u'\xfc'     #  0x0081 -> LATIN SMALL LETTER U WITH DIAERESIS
+    u'\xe9'     #  0x0082 -> LATIN SMALL LETTER E WITH ACUTE
+    u'\xe2'     #  0x0083 -> LATIN SMALL LETTER A WITH CIRCUMFLEX
+    u'\xc2'     #  0x0084 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+    u'\xe0'     #  0x0085 -> LATIN SMALL LETTER A WITH GRAVE
+    u'\xb6'     #  0x0086 -> PILCROW SIGN
+    u'\xe7'     #  0x0087 -> LATIN SMALL LETTER C WITH CEDILLA
+    u'\xea'     #  0x0088 -> LATIN SMALL LETTER E WITH CIRCUMFLEX
+    u'\xeb'     #  0x0089 -> LATIN SMALL LETTER E WITH DIAERESIS
+    u'\xe8'     #  0x008a -> LATIN SMALL LETTER E WITH GRAVE
+    u'\xef'     #  0x008b -> LATIN SMALL LETTER I WITH DIAERESIS
+    u'\xee'     #  0x008c -> LATIN SMALL LETTER I WITH CIRCUMFLEX
+    u'\u2017'   #  0x008d -> DOUBLE LOW LINE
+    u'\xc0'     #  0x008e -> LATIN CAPITAL LETTER A WITH GRAVE
+    u'\xa7'     #  0x008f -> SECTION SIGN
+    u'\xc9'     #  0x0090 -> LATIN CAPITAL LETTER E WITH ACUTE
+    u'\xc8'     #  0x0091 -> LATIN CAPITAL LETTER E WITH GRAVE
+    u'\xca'     #  0x0092 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+    u'\xf4'     #  0x0093 -> LATIN SMALL LETTER O WITH CIRCUMFLEX
+    u'\xcb'     #  0x0094 -> LATIN CAPITAL LETTER E WITH DIAERESIS
+    u'\xcf'     #  0x0095 -> LATIN CAPITAL LETTER I WITH DIAERESIS
+    u'\xfb'     #  0x0096 -> LATIN SMALL LETTER U WITH CIRCUMFLEX
+    u'\xf9'     #  0x0097 -> LATIN SMALL LETTER U WITH GRAVE
+    u'\xa4'     #  0x0098 -> CURRENCY SIGN
+    u'\xd4'     #  0x0099 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+    u'\xdc'     #  0x009a -> LATIN CAPITAL LETTER U WITH DIAERESIS
+    u'\xa2'     #  0x009b -> CENT SIGN
+    u'\xa3'     #  0x009c -> POUND SIGN
+    u'\xd9'     #  0x009d -> LATIN CAPITAL LETTER U WITH GRAVE
+    u'\xdb'     #  0x009e -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+    u'\u0192'   #  0x009f -> LATIN SMALL LETTER F WITH HOOK
+    u'\xa6'     #  0x00a0 -> BROKEN BAR
+    u'\xb4'     #  0x00a1 -> ACUTE ACCENT
+    u'\xf3'     #  0x00a2 -> LATIN SMALL LETTER O WITH ACUTE
+    u'\xfa'     #  0x00a3 -> LATIN SMALL LETTER U WITH ACUTE
+    u'\xa8'     #  0x00a4 -> DIAERESIS
+    u'\xb8'     #  0x00a5 -> CEDILLA
+    u'\xb3'     #  0x00a6 -> SUPERSCRIPT THREE
+    u'\xaf'     #  0x00a7 -> MACRON
+    u'\xce'     #  0x00a8 -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+    u'\u2310'   #  0x00a9 -> REVERSED NOT SIGN
+    u'\xac'     #  0x00aa -> NOT SIGN
+    u'\xbd'     #  0x00ab -> VULGAR FRACTION ONE HALF
+    u'\xbc'     #  0x00ac -> VULGAR FRACTION ONE QUARTER
+    u'\xbe'     #  0x00ad -> VULGAR FRACTION THREE QUARTERS
+    u'\xab'     #  0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xbb'     #  0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\u2591'   #  0x00b0 -> LIGHT SHADE
+    u'\u2592'   #  0x00b1 -> MEDIUM SHADE
+    u'\u2593'   #  0x00b2 -> DARK SHADE
+    u'\u2502'   #  0x00b3 -> BOX DRAWINGS LIGHT VERTICAL
+    u'\u2524'   #  0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT
+    u'\u2561'   #  0x00b5 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+    u'\u2562'   #  0x00b6 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
+    u'\u2556'   #  0x00b7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
+    u'\u2555'   #  0x00b8 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
+    u'\u2563'   #  0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+    u'\u2551'   #  0x00ba -> BOX DRAWINGS DOUBLE VERTICAL
+    u'\u2557'   #  0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT
+    u'\u255d'   #  0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT
+    u'\u255c'   #  0x00bd -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
+    u'\u255b'   #  0x00be -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+    u'\u2510'   #  0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT
+    u'\u2514'   #  0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT
+    u'\u2534'   #  0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL
+    u'\u252c'   #  0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+    u'\u251c'   #  0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+    u'\u2500'   #  0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL
+    u'\u253c'   #  0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+    u'\u255e'   #  0x00c6 -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+    u'\u255f'   #  0x00c7 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+    u'\u255a'   #  0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT
+    u'\u2554'   #  0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT
+    u'\u2569'   #  0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+    u'\u2566'   #  0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+    u'\u2560'   #  0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+    u'\u2550'   #  0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL
+    u'\u256c'   #  0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+    u'\u2567'   #  0x00cf -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+    u'\u2568'   #  0x00d0 -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+    u'\u2564'   #  0x00d1 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
+    u'\u2565'   #  0x00d2 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
+    u'\u2559'   #  0x00d3 -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+    u'\u2558'   #  0x00d4 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+    u'\u2552'   #  0x00d5 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+    u'\u2553'   #  0x00d6 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
+    u'\u256b'   #  0x00d7 -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
+    u'\u256a'   #  0x00d8 -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+    u'\u2518'   #  0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT
+    u'\u250c'   #  0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT
+    u'\u2588'   #  0x00db -> FULL BLOCK
+    u'\u2584'   #  0x00dc -> LOWER HALF BLOCK
+    u'\u258c'   #  0x00dd -> LEFT HALF BLOCK
+    u'\u2590'   #  0x00de -> RIGHT HALF BLOCK
+    u'\u2580'   #  0x00df -> UPPER HALF BLOCK
+    u'\u03b1'   #  0x00e0 -> GREEK SMALL LETTER ALPHA
+    u'\xdf'     #  0x00e1 -> LATIN SMALL LETTER SHARP S
+    u'\u0393'   #  0x00e2 -> GREEK CAPITAL LETTER GAMMA
+    u'\u03c0'   #  0x00e3 -> GREEK SMALL LETTER PI
+    u'\u03a3'   #  0x00e4 -> GREEK CAPITAL LETTER SIGMA
+    u'\u03c3'   #  0x00e5 -> GREEK SMALL LETTER SIGMA
+    u'\xb5'     #  0x00e6 -> MICRO SIGN
+    u'\u03c4'   #  0x00e7 -> GREEK SMALL LETTER TAU
+    u'\u03a6'   #  0x00e8 -> GREEK CAPITAL LETTER PHI
+    u'\u0398'   #  0x00e9 -> GREEK CAPITAL LETTER THETA
+    u'\u03a9'   #  0x00ea -> GREEK CAPITAL LETTER OMEGA
+    u'\u03b4'   #  0x00eb -> GREEK SMALL LETTER DELTA
+    u'\u221e'   #  0x00ec -> INFINITY
+    u'\u03c6'   #  0x00ed -> GREEK SMALL LETTER PHI
+    u'\u03b5'   #  0x00ee -> GREEK SMALL LETTER EPSILON
+    u'\u2229'   #  0x00ef -> INTERSECTION
+    u'\u2261'   #  0x00f0 -> IDENTICAL TO
+    u'\xb1'     #  0x00f1 -> PLUS-MINUS SIGN
+    u'\u2265'   #  0x00f2 -> GREATER-THAN OR EQUAL TO
+    u'\u2264'   #  0x00f3 -> LESS-THAN OR EQUAL TO
+    u'\u2320'   #  0x00f4 -> TOP HALF INTEGRAL
+    u'\u2321'   #  0x00f5 -> BOTTOM HALF INTEGRAL
+    u'\xf7'     #  0x00f6 -> DIVISION SIGN
+    u'\u2248'   #  0x00f7 -> ALMOST EQUAL TO
+    u'\xb0'     #  0x00f8 -> DEGREE SIGN
+    u'\u2219'   #  0x00f9 -> BULLET OPERATOR
+    u'\xb7'     #  0x00fa -> MIDDLE DOT
+    u'\u221a'   #  0x00fb -> SQUARE ROOT
+    u'\u207f'   #  0x00fc -> SUPERSCRIPT LATIN SMALL LETTER N
+    u'\xb2'     #  0x00fd -> SUPERSCRIPT TWO
+    u'\u25a0'   #  0x00fe -> BLACK SQUARE
+    u'\xa0'     #  0x00ff -> NO-BREAK SPACE
+)
+
+### Encoding Map
+
+encoding_map = {
+    0x0000: 0x0000,     #  NULL
+    0x0001: 0x0001,     #  START OF HEADING
+    0x0002: 0x0002,     #  START OF TEXT
+    0x0003: 0x0003,     #  END OF TEXT
+    0x0004: 0x0004,     #  END OF TRANSMISSION
+    0x0005: 0x0005,     #  ENQUIRY
+    0x0006: 0x0006,     #  ACKNOWLEDGE
+    0x0007: 0x0007,     #  BELL
+    0x0008: 0x0008,     #  BACKSPACE
+    0x0009: 0x0009,     #  HORIZONTAL TABULATION
+    0x000a: 0x000a,     #  LINE FEED
+    0x000b: 0x000b,     #  VERTICAL TABULATION
+    0x000c: 0x000c,     #  FORM FEED
+    0x000d: 0x000d,     #  CARRIAGE RETURN
+    0x000e: 0x000e,     #  SHIFT OUT
+    0x000f: 0x000f,     #  SHIFT IN
+    0x0010: 0x0010,     #  DATA LINK ESCAPE
+    0x0011: 0x0011,     #  DEVICE CONTROL ONE
+    0x0012: 0x0012,     #  DEVICE CONTROL TWO
+    0x0013: 0x0013,     #  DEVICE CONTROL THREE
+    0x0014: 0x0014,     #  DEVICE CONTROL FOUR
+    0x0015: 0x0015,     #  NEGATIVE ACKNOWLEDGE
+    0x0016: 0x0016,     #  SYNCHRONOUS IDLE
+    0x0017: 0x0017,     #  END OF TRANSMISSION BLOCK
+    0x0018: 0x0018,     #  CANCEL
+    0x0019: 0x0019,     #  END OF MEDIUM
+    0x001a: 0x001a,     #  SUBSTITUTE
+    0x001b: 0x001b,     #  ESCAPE
+    0x001c: 0x001c,     #  FILE SEPARATOR
+    0x001d: 0x001d,     #  GROUP SEPARATOR
+    0x001e: 0x001e,     #  RECORD SEPARATOR
+    0x001f: 0x001f,     #  UNIT SEPARATOR
+    0x0020: 0x0020,     #  SPACE
+    0x0021: 0x0021,     #  EXCLAMATION MARK
+    0x0022: 0x0022,     #  QUOTATION MARK
+    0x0023: 0x0023,     #  NUMBER SIGN
+    0x0024: 0x0024,     #  DOLLAR SIGN
+    0x0025: 0x0025,     #  PERCENT SIGN
+    0x0026: 0x0026,     #  AMPERSAND
+    0x0027: 0x0027,     #  APOSTROPHE
+    0x0028: 0x0028,     #  LEFT PARENTHESIS
+    0x0029: 0x0029,     #  RIGHT PARENTHESIS
+    0x002a: 0x002a,     #  ASTERISK
+    0x002b: 0x002b,     #  PLUS SIGN
+    0x002c: 0x002c,     #  COMMA
+    0x002d: 0x002d,     #  HYPHEN-MINUS
+    0x002e: 0x002e,     #  FULL STOP
+    0x002f: 0x002f,     #  SOLIDUS
+    0x0030: 0x0030,     #  DIGIT ZERO
+    0x0031: 0x0031,     #  DIGIT ONE
+    0x0032: 0x0032,     #  DIGIT TWO
+    0x0033: 0x0033,     #  DIGIT THREE
+    0x0034: 0x0034,     #  DIGIT FOUR
+    0x0035: 0x0035,     #  DIGIT FIVE
+    0x0036: 0x0036,     #  DIGIT SIX
+    0x0037: 0x0037,     #  DIGIT SEVEN
+    0x0038: 0x0038,     #  DIGIT EIGHT
+    0x0039: 0x0039,     #  DIGIT NINE
+    0x003a: 0x003a,     #  COLON
+    0x003b: 0x003b,     #  SEMICOLON
+    0x003c: 0x003c,     #  LESS-THAN SIGN
+    0x003d: 0x003d,     #  EQUALS SIGN
+    0x003e: 0x003e,     #  GREATER-THAN SIGN
+    0x003f: 0x003f,     #  QUESTION MARK
+    0x0040: 0x0040,     #  COMMERCIAL AT
+    0x0041: 0x0041,     #  LATIN CAPITAL LETTER A
+    0x0042: 0x0042,     #  LATIN CAPITAL LETTER B
+    0x0043: 0x0043,     #  LATIN CAPITAL LETTER C
+    0x0044: 0x0044,     #  LATIN CAPITAL LETTER D
+    0x0045: 0x0045,     #  LATIN CAPITAL LETTER E
+    0x0046: 0x0046,     #  LATIN CAPITAL LETTER F
+    0x0047: 0x0047,     #  LATIN CAPITAL LETTER G
+    0x0048: 0x0048,     #  LATIN CAPITAL LETTER H
+    0x0049: 0x0049,     #  LATIN CAPITAL LETTER I
+    0x004a: 0x004a,     #  LATIN CAPITAL LETTER J
+    0x004b: 0x004b,     #  LATIN CAPITAL LETTER K
+    0x004c: 0x004c,     #  LATIN CAPITAL LETTER L
+    0x004d: 0x004d,     #  LATIN CAPITAL LETTER M
+    0x004e: 0x004e,     #  LATIN CAPITAL LETTER N
+    0x004f: 0x004f,     #  LATIN CAPITAL LETTER O
+    0x0050: 0x0050,     #  LATIN CAPITAL LETTER P
+    0x0051: 0x0051,     #  LATIN CAPITAL LETTER Q
+    0x0052: 0x0052,     #  LATIN CAPITAL LETTER R
+    0x0053: 0x0053,     #  LATIN CAPITAL LETTER S
+    0x0054: 0x0054,     #  LATIN CAPITAL LETTER T
+    0x0055: 0x0055,     #  LATIN CAPITAL LETTER U
+    0x0056: 0x0056,     #  LATIN CAPITAL LETTER V
+    0x0057: 0x0057,     #  LATIN CAPITAL LETTER W
+    0x0058: 0x0058,     #  LATIN CAPITAL LETTER X
+    0x0059: 0x0059,     #  LATIN CAPITAL LETTER Y
+    0x005a: 0x005a,     #  LATIN CAPITAL LETTER Z
+    0x005b: 0x005b,     #  LEFT SQUARE BRACKET
+    0x005c: 0x005c,     #  REVERSE SOLIDUS
+    0x005d: 0x005d,     #  RIGHT SQUARE BRACKET
+    0x005e: 0x005e,     #  CIRCUMFLEX ACCENT
+    0x005f: 0x005f,     #  LOW LINE
+    0x0060: 0x0060,     #  GRAVE ACCENT
+    0x0061: 0x0061,     #  LATIN SMALL LETTER A
+    0x0062: 0x0062,     #  LATIN SMALL LETTER B
+    0x0063: 0x0063,     #  LATIN SMALL LETTER C
+    0x0064: 0x0064,     #  LATIN SMALL LETTER D
+    0x0065: 0x0065,     #  LATIN SMALL LETTER E
+    0x0066: 0x0066,     #  LATIN SMALL LETTER F
+    0x0067: 0x0067,     #  LATIN SMALL LETTER G
+    0x0068: 0x0068,     #  LATIN SMALL LETTER H
+    0x0069: 0x0069,     #  LATIN SMALL LETTER I
+    0x006a: 0x006a,     #  LATIN SMALL LETTER J
+    0x006b: 0x006b,     #  LATIN SMALL LETTER K
+    0x006c: 0x006c,     #  LATIN SMALL LETTER L
+    0x006d: 0x006d,     #  LATIN SMALL LETTER M
+    0x006e: 0x006e,     #  LATIN SMALL LETTER N
+    0x006f: 0x006f,     #  LATIN SMALL LETTER O
+    0x0070: 0x0070,     #  LATIN SMALL LETTER P
+    0x0071: 0x0071,     #  LATIN SMALL LETTER Q
+    0x0072: 0x0072,     #  LATIN SMALL LETTER R
+    0x0073: 0x0073,     #  LATIN SMALL LETTER S
+    0x0074: 0x0074,     #  LATIN SMALL LETTER T
+    0x0075: 0x0075,     #  LATIN SMALL LETTER U
+    0x0076: 0x0076,     #  LATIN SMALL LETTER V
+    0x0077: 0x0077,     #  LATIN SMALL LETTER W
+    0x0078: 0x0078,     #  LATIN SMALL LETTER X
+    0x0079: 0x0079,     #  LATIN SMALL LETTER Y
+    0x007a: 0x007a,     #  LATIN SMALL LETTER Z
+    0x007b: 0x007b,     #  LEFT CURLY BRACKET
+    0x007c: 0x007c,     #  VERTICAL LINE
+    0x007d: 0x007d,     #  RIGHT CURLY BRACKET
+    0x007e: 0x007e,     #  TILDE
+    0x007f: 0x007f,     #  DELETE
+    0x00a0: 0x00ff,     #  NO-BREAK SPACE
+    0x00a2: 0x009b,     #  CENT SIGN
+    0x00a3: 0x009c,     #  POUND SIGN
+    0x00a4: 0x0098,     #  CURRENCY SIGN
+    0x00a6: 0x00a0,     #  BROKEN BAR
+    0x00a7: 0x008f,     #  SECTION SIGN
+    0x00a8: 0x00a4,     #  DIAERESIS
+    0x00ab: 0x00ae,     #  LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    0x00ac: 0x00aa,     #  NOT SIGN
+    0x00af: 0x00a7,     #  MACRON
+    0x00b0: 0x00f8,     #  DEGREE SIGN
+    0x00b1: 0x00f1,     #  PLUS-MINUS SIGN
+    0x00b2: 0x00fd,     #  SUPERSCRIPT TWO
+    0x00b3: 0x00a6,     #  SUPERSCRIPT THREE
+    0x00b4: 0x00a1,     #  ACUTE ACCENT
+    0x00b5: 0x00e6,     #  MICRO SIGN
+    0x00b6: 0x0086,     #  PILCROW SIGN
+    0x00b7: 0x00fa,     #  MIDDLE DOT
+    0x00b8: 0x00a5,     #  CEDILLA
+    0x00bb: 0x00af,     #  RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    0x00bc: 0x00ac,     #  VULGAR FRACTION ONE QUARTER
+    0x00bd: 0x00ab,     #  VULGAR FRACTION ONE HALF
+    0x00be: 0x00ad,     #  VULGAR FRACTION THREE QUARTERS
+    0x00c0: 0x008e,     #  LATIN CAPITAL LETTER A WITH GRAVE
+    0x00c2: 0x0084,     #  LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+    0x00c7: 0x0080,     #  LATIN CAPITAL LETTER C WITH CEDILLA
+    0x00c8: 0x0091,     #  LATIN CAPITAL LETTER E WITH GRAVE
+    0x00c9: 0x0090,     #  LATIN CAPITAL LETTER E WITH ACUTE
+    0x00ca: 0x0092,     #  LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+    0x00cb: 0x0094,     #  LATIN CAPITAL LETTER E WITH DIAERESIS
+    0x00ce: 0x00a8,     #  LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+    0x00cf: 0x0095,     #  LATIN CAPITAL LETTER I WITH DIAERESIS
+    0x00d4: 0x0099,     #  LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+    0x00d9: 0x009d,     #  LATIN CAPITAL LETTER U WITH GRAVE
+    0x00db: 0x009e,     #  LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+    0x00dc: 0x009a,     #  LATIN CAPITAL LETTER U WITH DIAERESIS
+    0x00df: 0x00e1,     #  LATIN SMALL LETTER SHARP S
+    0x00e0: 0x0085,     #  LATIN SMALL LETTER A WITH GRAVE
+    0x00e2: 0x0083,     #  LATIN SMALL LETTER A WITH CIRCUMFLEX
+    0x00e7: 0x0087,     #  LATIN SMALL LETTER C WITH CEDILLA
+    0x00e8: 0x008a,     #  LATIN SMALL LETTER E WITH GRAVE
+    0x00e9: 0x0082,     #  LATIN SMALL LETTER E WITH ACUTE
+    0x00ea: 0x0088,     #  LATIN SMALL LETTER E WITH CIRCUMFLEX
+    0x00eb: 0x0089,     #  LATIN SMALL LETTER E WITH DIAERESIS
+    0x00ee: 0x008c,     #  LATIN SMALL LETTER I WITH CIRCUMFLEX
+    0x00ef: 0x008b,     #  LATIN SMALL LETTER I WITH DIAERESIS
+    0x00f3: 0x00a2,     #  LATIN SMALL LETTER O WITH ACUTE
+    0x00f4: 0x0093,     #  LATIN SMALL LETTER O WITH CIRCUMFLEX
+    0x00f7: 0x00f6,     #  DIVISION SIGN
+    0x00f9: 0x0097,     #  LATIN SMALL LETTER U WITH GRAVE
+    0x00fa: 0x00a3,     #  LATIN SMALL LETTER U WITH ACUTE
+    0x00fb: 0x0096,     #  LATIN SMALL LETTER U WITH CIRCUMFLEX
+    0x00fc: 0x0081,     #  LATIN SMALL LETTER U WITH DIAERESIS
+    0x0192: 0x009f,     #  LATIN SMALL LETTER F WITH HOOK
+    0x0393: 0x00e2,     #  GREEK CAPITAL LETTER GAMMA
+    0x0398: 0x00e9,     #  GREEK CAPITAL LETTER THETA
+    0x03a3: 0x00e4,     #  GREEK CAPITAL LETTER SIGMA
+    0x03a6: 0x00e8,     #  GREEK CAPITAL LETTER PHI
+    0x03a9: 0x00ea,     #  GREEK CAPITAL LETTER OMEGA
+    0x03b1: 0x00e0,     #  GREEK SMALL LETTER ALPHA
+    0x03b4: 0x00eb,     #  GREEK SMALL LETTER DELTA
+    0x03b5: 0x00ee,     #  GREEK SMALL LETTER EPSILON
+    0x03c0: 0x00e3,     #  GREEK SMALL LETTER PI
+    0x03c3: 0x00e5,     #  GREEK SMALL LETTER SIGMA
+    0x03c4: 0x00e7,     #  GREEK SMALL LETTER TAU
+    0x03c6: 0x00ed,     #  GREEK SMALL LETTER PHI
+    0x2017: 0x008d,     #  DOUBLE LOW LINE
+    0x207f: 0x00fc,     #  SUPERSCRIPT LATIN SMALL LETTER N
+    0x2219: 0x00f9,     #  BULLET OPERATOR
+    0x221a: 0x00fb,     #  SQUARE ROOT
+    0x221e: 0x00ec,     #  INFINITY
+    0x2229: 0x00ef,     #  INTERSECTION
+    0x2248: 0x00f7,     #  ALMOST EQUAL TO
+    0x2261: 0x00f0,     #  IDENTICAL TO
+    0x2264: 0x00f3,     #  LESS-THAN OR EQUAL TO
+    0x2265: 0x00f2,     #  GREATER-THAN OR EQUAL TO
+    0x2310: 0x00a9,     #  REVERSED NOT SIGN
+    0x2320: 0x00f4,     #  TOP HALF INTEGRAL
+    0x2321: 0x00f5,     #  BOTTOM HALF INTEGRAL
+    0x2500: 0x00c4,     #  BOX DRAWINGS LIGHT HORIZONTAL
+    0x2502: 0x00b3,     #  BOX DRAWINGS LIGHT VERTICAL
+    0x250c: 0x00da,     #  BOX DRAWINGS LIGHT DOWN AND RIGHT
+    0x2510: 0x00bf,     #  BOX DRAWINGS LIGHT DOWN AND LEFT
+    0x2514: 0x00c0,     #  BOX DRAWINGS LIGHT UP AND RIGHT
+    0x2518: 0x00d9,     #  BOX DRAWINGS LIGHT UP AND LEFT
+    0x251c: 0x00c3,     #  BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+    0x2524: 0x00b4,     #  BOX DRAWINGS LIGHT VERTICAL AND LEFT
+    0x252c: 0x00c2,     #  BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+    0x2534: 0x00c1,     #  BOX DRAWINGS LIGHT UP AND HORIZONTAL
+    0x253c: 0x00c5,     #  BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+    0x2550: 0x00cd,     #  BOX DRAWINGS DOUBLE HORIZONTAL
+    0x2551: 0x00ba,     #  BOX DRAWINGS DOUBLE VERTICAL
+    0x2552: 0x00d5,     #  BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+    0x2553: 0x00d6,     #  BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
+    0x2554: 0x00c9,     #  BOX DRAWINGS DOUBLE DOWN AND RIGHT
+    0x2555: 0x00b8,     #  BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
+    0x2556: 0x00b7,     #  BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
+    0x2557: 0x00bb,     #  BOX DRAWINGS DOUBLE DOWN AND LEFT
+    0x2558: 0x00d4,     #  BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+    0x2559: 0x00d3,     #  BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+    0x255a: 0x00c8,     #  BOX DRAWINGS DOUBLE UP AND RIGHT
+    0x255b: 0x00be,     #  BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+    0x255c: 0x00bd,     #  BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
+    0x255d: 0x00bc,     #  BOX DRAWINGS DOUBLE UP AND LEFT
+    0x255e: 0x00c6,     #  BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+    0x255f: 0x00c7,     #  BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+    0x2560: 0x00cc,     #  BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+    0x2561: 0x00b5,     #  BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+    0x2562: 0x00b6,     #  BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
+    0x2563: 0x00b9,     #  BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+    0x2564: 0x00d1,     #  BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
+    0x2565: 0x00d2,     #  BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
+    0x2566: 0x00cb,     #  BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+    0x2567: 0x00cf,     #  BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+    0x2568: 0x00d0,     #  BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+    0x2569: 0x00ca,     #  BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+    0x256a: 0x00d8,     #  BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+    0x256b: 0x00d7,     #  BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
+    0x256c: 0x00ce,     #  BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+    0x2580: 0x00df,     #  UPPER HALF BLOCK
+    0x2584: 0x00dc,     #  LOWER HALF BLOCK
+    0x2588: 0x00db,     #  FULL BLOCK
+    0x258c: 0x00dd,     #  LEFT HALF BLOCK
+    0x2590: 0x00de,     #  RIGHT HALF BLOCK
+    0x2591: 0x00b0,     #  LIGHT SHADE
+    0x2592: 0x00b1,     #  MEDIUM SHADE
+    0x2593: 0x00b2,     #  DARK SHADE
+    0x25a0: 0x00fe,     #  BLACK SQUARE
+}

Added: vendor/Python/current/Lib/encodings/cp864.py
===================================================================
--- vendor/Python/current/Lib/encodings/cp864.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/cp864.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,690 @@
+""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP864.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_map)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='cp864',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+### Decoding Map
+
+decoding_map = codecs.make_identity_dict(range(256))
+decoding_map.update({
+    0x0025: 0x066a,     #  ARABIC PERCENT SIGN
+    0x0080: 0x00b0,     #  DEGREE SIGN
+    0x0081: 0x00b7,     #  MIDDLE DOT
+    0x0082: 0x2219,     #  BULLET OPERATOR
+    0x0083: 0x221a,     #  SQUARE ROOT
+    0x0084: 0x2592,     #  MEDIUM SHADE
+    0x0085: 0x2500,     #  FORMS LIGHT HORIZONTAL
+    0x0086: 0x2502,     #  FORMS LIGHT VERTICAL
+    0x0087: 0x253c,     #  FORMS LIGHT VERTICAL AND HORIZONTAL
+    0x0088: 0x2524,     #  FORMS LIGHT VERTICAL AND LEFT
+    0x0089: 0x252c,     #  FORMS LIGHT DOWN AND HORIZONTAL
+    0x008a: 0x251c,     #  FORMS LIGHT VERTICAL AND RIGHT
+    0x008b: 0x2534,     #  FORMS LIGHT UP AND HORIZONTAL
+    0x008c: 0x2510,     #  FORMS LIGHT DOWN AND LEFT
+    0x008d: 0x250c,     #  FORMS LIGHT DOWN AND RIGHT
+    0x008e: 0x2514,     #  FORMS LIGHT UP AND RIGHT
+    0x008f: 0x2518,     #  FORMS LIGHT UP AND LEFT
+    0x0090: 0x03b2,     #  GREEK SMALL BETA
+    0x0091: 0x221e,     #  INFINITY
+    0x0092: 0x03c6,     #  GREEK SMALL PHI
+    0x0093: 0x00b1,     #  PLUS-OR-MINUS SIGN
+    0x0094: 0x00bd,     #  FRACTION 1/2
+    0x0095: 0x00bc,     #  FRACTION 1/4
+    0x0096: 0x2248,     #  ALMOST EQUAL TO
+    0x0097: 0x00ab,     #  LEFT POINTING GUILLEMET
+    0x0098: 0x00bb,     #  RIGHT POINTING GUILLEMET
+    0x0099: 0xfef7,     #  ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM
+    0x009a: 0xfef8,     #  ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM
+    0x009b: None,       #  UNDEFINED
+    0x009c: None,       #  UNDEFINED
+    0x009d: 0xfefb,     #  ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM
+    0x009e: 0xfefc,     #  ARABIC LIGATURE LAM WITH ALEF FINAL FORM
+    0x009f: None,       #  UNDEFINED
+    0x00a1: 0x00ad,     #  SOFT HYPHEN
+    0x00a2: 0xfe82,     #  ARABIC LETTER ALEF WITH MADDA ABOVE FINAL FORM
+    0x00a5: 0xfe84,     #  ARABIC LETTER ALEF WITH HAMZA ABOVE FINAL FORM
+    0x00a6: None,       #  UNDEFINED
+    0x00a7: None,       #  UNDEFINED
+    0x00a8: 0xfe8e,     #  ARABIC LETTER ALEF FINAL FORM
+    0x00a9: 0xfe8f,     #  ARABIC LETTER BEH ISOLATED FORM
+    0x00aa: 0xfe95,     #  ARABIC LETTER TEH ISOLATED FORM
+    0x00ab: 0xfe99,     #  ARABIC LETTER THEH ISOLATED FORM
+    0x00ac: 0x060c,     #  ARABIC COMMA
+    0x00ad: 0xfe9d,     #  ARABIC LETTER JEEM ISOLATED FORM
+    0x00ae: 0xfea1,     #  ARABIC LETTER HAH ISOLATED FORM
+    0x00af: 0xfea5,     #  ARABIC LETTER KHAH ISOLATED FORM
+    0x00b0: 0x0660,     #  ARABIC-INDIC DIGIT ZERO
+    0x00b1: 0x0661,     #  ARABIC-INDIC DIGIT ONE
+    0x00b2: 0x0662,     #  ARABIC-INDIC DIGIT TWO
+    0x00b3: 0x0663,     #  ARABIC-INDIC DIGIT THREE
+    0x00b4: 0x0664,     #  ARABIC-INDIC DIGIT FOUR
+    0x00b5: 0x0665,     #  ARABIC-INDIC DIGIT FIVE
+    0x00b6: 0x0666,     #  ARABIC-INDIC DIGIT SIX
+    0x00b7: 0x0667,     #  ARABIC-INDIC DIGIT SEVEN
+    0x00b8: 0x0668,     #  ARABIC-INDIC DIGIT EIGHT
+    0x00b9: 0x0669,     #  ARABIC-INDIC DIGIT NINE
+    0x00ba: 0xfed1,     #  ARABIC LETTER FEH ISOLATED FORM
+    0x00bb: 0x061b,     #  ARABIC SEMICOLON
+    0x00bc: 0xfeb1,     #  ARABIC LETTER SEEN ISOLATED FORM
+    0x00bd: 0xfeb5,     #  ARABIC LETTER SHEEN ISOLATED FORM
+    0x00be: 0xfeb9,     #  ARABIC LETTER SAD ISOLATED FORM
+    0x00bf: 0x061f,     #  ARABIC QUESTION MARK
+    0x00c0: 0x00a2,     #  CENT SIGN
+    0x00c1: 0xfe80,     #  ARABIC LETTER HAMZA ISOLATED FORM
+    0x00c2: 0xfe81,     #  ARABIC LETTER ALEF WITH MADDA ABOVE ISOLATED FORM
+    0x00c3: 0xfe83,     #  ARABIC LETTER ALEF WITH HAMZA ABOVE ISOLATED FORM
+    0x00c4: 0xfe85,     #  ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM
+    0x00c5: 0xfeca,     #  ARABIC LETTER AIN FINAL FORM
+    0x00c6: 0xfe8b,     #  ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM
+    0x00c7: 0xfe8d,     #  ARABIC LETTER ALEF ISOLATED FORM
+    0x00c8: 0xfe91,     #  ARABIC LETTER BEH INITIAL FORM
+    0x00c9: 0xfe93,     #  ARABIC LETTER TEH MARBUTA ISOLATED FORM
+    0x00ca: 0xfe97,     #  ARABIC LETTER TEH INITIAL FORM
+    0x00cb: 0xfe9b,     #  ARABIC LETTER THEH INITIAL FORM
+    0x00cc: 0xfe9f,     #  ARABIC LETTER JEEM INITIAL FORM
+    0x00cd: 0xfea3,     #  ARABIC LETTER HAH INITIAL FORM
+    0x00ce: 0xfea7,     #  ARABIC LETTER KHAH INITIAL FORM
+    0x00cf: 0xfea9,     #  ARABIC LETTER DAL ISOLATED FORM
+    0x00d0: 0xfeab,     #  ARABIC LETTER THAL ISOLATED FORM
+    0x00d1: 0xfead,     #  ARABIC LETTER REH ISOLATED FORM
+    0x00d2: 0xfeaf,     #  ARABIC LETTER ZAIN ISOLATED FORM
+    0x00d3: 0xfeb3,     #  ARABIC LETTER SEEN INITIAL FORM
+    0x00d4: 0xfeb7,     #  ARABIC LETTER SHEEN INITIAL FORM
+    0x00d5: 0xfebb,     #  ARABIC LETTER SAD INITIAL FORM
+    0x00d6: 0xfebf,     #  ARABIC LETTER DAD INITIAL FORM
+    0x00d7: 0xfec1,     #  ARABIC LETTER TAH ISOLATED FORM
+    0x00d8: 0xfec5,     #  ARABIC LETTER ZAH ISOLATED FORM
+    0x00d9: 0xfecb,     #  ARABIC LETTER AIN INITIAL FORM
+    0x00da: 0xfecf,     #  ARABIC LETTER GHAIN INITIAL FORM
+    0x00db: 0x00a6,     #  BROKEN VERTICAL BAR
+    0x00dc: 0x00ac,     #  NOT SIGN
+    0x00dd: 0x00f7,     #  DIVISION SIGN
+    0x00de: 0x00d7,     #  MULTIPLICATION SIGN
+    0x00df: 0xfec9,     #  ARABIC LETTER AIN ISOLATED FORM
+    0x00e0: 0x0640,     #  ARABIC TATWEEL
+    0x00e1: 0xfed3,     #  ARABIC LETTER FEH INITIAL FORM
+    0x00e2: 0xfed7,     #  ARABIC LETTER QAF INITIAL FORM
+    0x00e3: 0xfedb,     #  ARABIC LETTER KAF INITIAL FORM
+    0x00e4: 0xfedf,     #  ARABIC LETTER LAM INITIAL FORM
+    0x00e5: 0xfee3,     #  ARABIC LETTER MEEM INITIAL FORM
+    0x00e6: 0xfee7,     #  ARABIC LETTER NOON INITIAL FORM
+    0x00e7: 0xfeeb,     #  ARABIC LETTER HEH INITIAL FORM
+    0x00e8: 0xfeed,     #  ARABIC LETTER WAW ISOLATED FORM
+    0x00e9: 0xfeef,     #  ARABIC LETTER ALEF MAKSURA ISOLATED FORM
+    0x00ea: 0xfef3,     #  ARABIC LETTER YEH INITIAL FORM
+    0x00eb: 0xfebd,     #  ARABIC LETTER DAD ISOLATED FORM
+    0x00ec: 0xfecc,     #  ARABIC LETTER AIN MEDIAL FORM
+    0x00ed: 0xfece,     #  ARABIC LETTER GHAIN FINAL FORM
+    0x00ee: 0xfecd,     #  ARABIC LETTER GHAIN ISOLATED FORM
+    0x00ef: 0xfee1,     #  ARABIC LETTER MEEM ISOLATED FORM
+    0x00f0: 0xfe7d,     #  ARABIC SHADDA MEDIAL FORM
+    0x00f1: 0x0651,     #  ARABIC SHADDAH
+    0x00f2: 0xfee5,     #  ARABIC LETTER NOON ISOLATED FORM
+    0x00f3: 0xfee9,     #  ARABIC LETTER HEH ISOLATED FORM
+    0x00f4: 0xfeec,     #  ARABIC LETTER HEH MEDIAL FORM
+    0x00f5: 0xfef0,     #  ARABIC LETTER ALEF MAKSURA FINAL FORM
+    0x00f6: 0xfef2,     #  ARABIC LETTER YEH FINAL FORM
+    0x00f7: 0xfed0,     #  ARABIC LETTER GHAIN MEDIAL FORM
+    0x00f8: 0xfed5,     #  ARABIC LETTER QAF ISOLATED FORM
+    0x00f9: 0xfef5,     #  ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM
+    0x00fa: 0xfef6,     #  ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM
+    0x00fb: 0xfedd,     #  ARABIC LETTER LAM ISOLATED FORM
+    0x00fc: 0xfed9,     #  ARABIC LETTER KAF ISOLATED FORM
+    0x00fd: 0xfef1,     #  ARABIC LETTER YEH ISOLATED FORM
+    0x00fe: 0x25a0,     #  BLACK SQUARE
+    0x00ff: None,       #  UNDEFINED
+})
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x0000 -> NULL
+    u'\x01'     #  0x0001 -> START OF HEADING
+    u'\x02'     #  0x0002 -> START OF TEXT
+    u'\x03'     #  0x0003 -> END OF TEXT
+    u'\x04'     #  0x0004 -> END OF TRANSMISSION
+    u'\x05'     #  0x0005 -> ENQUIRY
+    u'\x06'     #  0x0006 -> ACKNOWLEDGE
+    u'\x07'     #  0x0007 -> BELL
+    u'\x08'     #  0x0008 -> BACKSPACE
+    u'\t'       #  0x0009 -> HORIZONTAL TABULATION
+    u'\n'       #  0x000a -> LINE FEED
+    u'\x0b'     #  0x000b -> VERTICAL TABULATION
+    u'\x0c'     #  0x000c -> FORM FEED
+    u'\r'       #  0x000d -> CARRIAGE RETURN
+    u'\x0e'     #  0x000e -> SHIFT OUT
+    u'\x0f'     #  0x000f -> SHIFT IN
+    u'\x10'     #  0x0010 -> DATA LINK ESCAPE
+    u'\x11'     #  0x0011 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x0012 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x0013 -> DEVICE CONTROL THREE
+    u'\x14'     #  0x0014 -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x0015 -> NEGATIVE ACKNOWLEDGE
+    u'\x16'     #  0x0016 -> SYNCHRONOUS IDLE
+    u'\x17'     #  0x0017 -> END OF TRANSMISSION BLOCK
+    u'\x18'     #  0x0018 -> CANCEL
+    u'\x19'     #  0x0019 -> END OF MEDIUM
+    u'\x1a'     #  0x001a -> SUBSTITUTE
+    u'\x1b'     #  0x001b -> ESCAPE
+    u'\x1c'     #  0x001c -> FILE SEPARATOR
+    u'\x1d'     #  0x001d -> GROUP SEPARATOR
+    u'\x1e'     #  0x001e -> RECORD SEPARATOR
+    u'\x1f'     #  0x001f -> UNIT SEPARATOR
+    u' '        #  0x0020 -> SPACE
+    u'!'        #  0x0021 -> EXCLAMATION MARK
+    u'"'        #  0x0022 -> QUOTATION MARK
+    u'#'        #  0x0023 -> NUMBER SIGN
+    u'$'        #  0x0024 -> DOLLAR SIGN
+    u'\u066a'   #  0x0025 -> ARABIC PERCENT SIGN
+    u'&'        #  0x0026 -> AMPERSAND
+    u"'"        #  0x0027 -> APOSTROPHE
+    u'('        #  0x0028 -> LEFT PARENTHESIS
+    u')'        #  0x0029 -> RIGHT PARENTHESIS
+    u'*'        #  0x002a -> ASTERISK
+    u'+'        #  0x002b -> PLUS SIGN
+    u','        #  0x002c -> COMMA
+    u'-'        #  0x002d -> HYPHEN-MINUS
+    u'.'        #  0x002e -> FULL STOP
+    u'/'        #  0x002f -> SOLIDUS
+    u'0'        #  0x0030 -> DIGIT ZERO
+    u'1'        #  0x0031 -> DIGIT ONE
+    u'2'        #  0x0032 -> DIGIT TWO
+    u'3'        #  0x0033 -> DIGIT THREE
+    u'4'        #  0x0034 -> DIGIT FOUR
+    u'5'        #  0x0035 -> DIGIT FIVE
+    u'6'        #  0x0036 -> DIGIT SIX
+    u'7'        #  0x0037 -> DIGIT SEVEN
+    u'8'        #  0x0038 -> DIGIT EIGHT
+    u'9'        #  0x0039 -> DIGIT NINE
+    u':'        #  0x003a -> COLON
+    u';'        #  0x003b -> SEMICOLON
+    u'<'        #  0x003c -> LESS-THAN SIGN
+    u'='        #  0x003d -> EQUALS SIGN
+    u'>'        #  0x003e -> GREATER-THAN SIGN
+    u'?'        #  0x003f -> QUESTION MARK
+    u'@'        #  0x0040 -> COMMERCIAL AT
+    u'A'        #  0x0041 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x0042 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x0043 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x0044 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x0045 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x0046 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x0047 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x0048 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x0049 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x004a -> LATIN CAPITAL LETTER J
+    u'K'        #  0x004b -> LATIN CAPITAL LETTER K
+    u'L'        #  0x004c -> LATIN CAPITAL LETTER L
+    u'M'        #  0x004d -> LATIN CAPITAL LETTER M
+    u'N'        #  0x004e -> LATIN CAPITAL LETTER N
+    u'O'        #  0x004f -> LATIN CAPITAL LETTER O
+    u'P'        #  0x0050 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x0051 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x0052 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x0053 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x0054 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x0055 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x0056 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x0057 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x0058 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x0059 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x005a -> LATIN CAPITAL LETTER Z
+    u'['        #  0x005b -> LEFT SQUARE BRACKET
+    u'\\'       #  0x005c -> REVERSE SOLIDUS
+    u']'        #  0x005d -> RIGHT SQUARE BRACKET
+    u'^'        #  0x005e -> CIRCUMFLEX ACCENT
+    u'_'        #  0x005f -> LOW LINE
+    u'`'        #  0x0060 -> GRAVE ACCENT
+    u'a'        #  0x0061 -> LATIN SMALL LETTER A
+    u'b'        #  0x0062 -> LATIN SMALL LETTER B
+    u'c'        #  0x0063 -> LATIN SMALL LETTER C
+    u'd'        #  0x0064 -> LATIN SMALL LETTER D
+    u'e'        #  0x0065 -> LATIN SMALL LETTER E
+    u'f'        #  0x0066 -> LATIN SMALL LETTER F
+    u'g'        #  0x0067 -> LATIN SMALL LETTER G
+    u'h'        #  0x0068 -> LATIN SMALL LETTER H
+    u'i'        #  0x0069 -> LATIN SMALL LETTER I
+    u'j'        #  0x006a -> LATIN SMALL LETTER J
+    u'k'        #  0x006b -> LATIN SMALL LETTER K
+    u'l'        #  0x006c -> LATIN SMALL LETTER L
+    u'm'        #  0x006d -> LATIN SMALL LETTER M
+    u'n'        #  0x006e -> LATIN SMALL LETTER N
+    u'o'        #  0x006f -> LATIN SMALL LETTER O
+    u'p'        #  0x0070 -> LATIN SMALL LETTER P
+    u'q'        #  0x0071 -> LATIN SMALL LETTER Q
+    u'r'        #  0x0072 -> LATIN SMALL LETTER R
+    u's'        #  0x0073 -> LATIN SMALL LETTER S
+    u't'        #  0x0074 -> LATIN SMALL LETTER T
+    u'u'        #  0x0075 -> LATIN SMALL LETTER U
+    u'v'        #  0x0076 -> LATIN SMALL LETTER V
+    u'w'        #  0x0077 -> LATIN SMALL LETTER W
+    u'x'        #  0x0078 -> LATIN SMALL LETTER X
+    u'y'        #  0x0079 -> LATIN SMALL LETTER Y
+    u'z'        #  0x007a -> LATIN SMALL LETTER Z
+    u'{'        #  0x007b -> LEFT CURLY BRACKET
+    u'|'        #  0x007c -> VERTICAL LINE
+    u'}'        #  0x007d -> RIGHT CURLY BRACKET
+    u'~'        #  0x007e -> TILDE
+    u'\x7f'     #  0x007f -> DELETE
+    u'\xb0'     #  0x0080 -> DEGREE SIGN
+    u'\xb7'     #  0x0081 -> MIDDLE DOT
+    u'\u2219'   #  0x0082 -> BULLET OPERATOR
+    u'\u221a'   #  0x0083 -> SQUARE ROOT
+    u'\u2592'   #  0x0084 -> MEDIUM SHADE
+    u'\u2500'   #  0x0085 -> FORMS LIGHT HORIZONTAL
+    u'\u2502'   #  0x0086 -> FORMS LIGHT VERTICAL
+    u'\u253c'   #  0x0087 -> FORMS LIGHT VERTICAL AND HORIZONTAL
+    u'\u2524'   #  0x0088 -> FORMS LIGHT VERTICAL AND LEFT
+    u'\u252c'   #  0x0089 -> FORMS LIGHT DOWN AND HORIZONTAL
+    u'\u251c'   #  0x008a -> FORMS LIGHT VERTICAL AND RIGHT
+    u'\u2534'   #  0x008b -> FORMS LIGHT UP AND HORIZONTAL
+    u'\u2510'   #  0x008c -> FORMS LIGHT DOWN AND LEFT
+    u'\u250c'   #  0x008d -> FORMS LIGHT DOWN AND RIGHT
+    u'\u2514'   #  0x008e -> FORMS LIGHT UP AND RIGHT
+    u'\u2518'   #  0x008f -> FORMS LIGHT UP AND LEFT
+    u'\u03b2'   #  0x0090 -> GREEK SMALL BETA
+    u'\u221e'   #  0x0091 -> INFINITY
+    u'\u03c6'   #  0x0092 -> GREEK SMALL PHI
+    u'\xb1'     #  0x0093 -> PLUS-OR-MINUS SIGN
+    u'\xbd'     #  0x0094 -> FRACTION 1/2
+    u'\xbc'     #  0x0095 -> FRACTION 1/4
+    u'\u2248'   #  0x0096 -> ALMOST EQUAL TO
+    u'\xab'     #  0x0097 -> LEFT POINTING GUILLEMET
+    u'\xbb'     #  0x0098 -> RIGHT POINTING GUILLEMET
+    u'\ufef7'   #  0x0099 -> ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM
+    u'\ufef8'   #  0x009a -> ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM
+    u'\ufffe'   #  0x009b -> UNDEFINED
+    u'\ufffe'   #  0x009c -> UNDEFINED
+    u'\ufefb'   #  0x009d -> ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM
+    u'\ufefc'   #  0x009e -> ARABIC LIGATURE LAM WITH ALEF FINAL FORM
+    u'\ufffe'   #  0x009f -> UNDEFINED
+    u'\xa0'     #  0x00a0 -> NON-BREAKING SPACE
+    u'\xad'     #  0x00a1 -> SOFT HYPHEN
+    u'\ufe82'   #  0x00a2 -> ARABIC LETTER ALEF WITH MADDA ABOVE FINAL FORM
+    u'\xa3'     #  0x00a3 -> POUND SIGN
+    u'\xa4'     #  0x00a4 -> CURRENCY SIGN
+    u'\ufe84'   #  0x00a5 -> ARABIC LETTER ALEF WITH HAMZA ABOVE FINAL FORM
+    u'\ufffe'   #  0x00a6 -> UNDEFINED
+    u'\ufffe'   #  0x00a7 -> UNDEFINED
+    u'\ufe8e'   #  0x00a8 -> ARABIC LETTER ALEF FINAL FORM
+    u'\ufe8f'   #  0x00a9 -> ARABIC LETTER BEH ISOLATED FORM
+    u'\ufe95'   #  0x00aa -> ARABIC LETTER TEH ISOLATED FORM
+    u'\ufe99'   #  0x00ab -> ARABIC LETTER THEH ISOLATED FORM
+    u'\u060c'   #  0x00ac -> ARABIC COMMA
+    u'\ufe9d'   #  0x00ad -> ARABIC LETTER JEEM ISOLATED FORM
+    u'\ufea1'   #  0x00ae -> ARABIC LETTER HAH ISOLATED FORM
+    u'\ufea5'   #  0x00af -> ARABIC LETTER KHAH ISOLATED FORM
+    u'\u0660'   #  0x00b0 -> ARABIC-INDIC DIGIT ZERO
+    u'\u0661'   #  0x00b1 -> ARABIC-INDIC DIGIT ONE
+    u'\u0662'   #  0x00b2 -> ARABIC-INDIC DIGIT TWO
+    u'\u0663'   #  0x00b3 -> ARABIC-INDIC DIGIT THREE
+    u'\u0664'   #  0x00b4 -> ARABIC-INDIC DIGIT FOUR
+    u'\u0665'   #  0x00b5 -> ARABIC-INDIC DIGIT FIVE
+    u'\u0666'   #  0x00b6 -> ARABIC-INDIC DIGIT SIX
+    u'\u0667'   #  0x00b7 -> ARABIC-INDIC DIGIT SEVEN
+    u'\u0668'   #  0x00b8 -> ARABIC-INDIC DIGIT EIGHT
+    u'\u0669'   #  0x00b9 -> ARABIC-INDIC DIGIT NINE
+    u'\ufed1'   #  0x00ba -> ARABIC LETTER FEH ISOLATED FORM
+    u'\u061b'   #  0x00bb -> ARABIC SEMICOLON
+    u'\ufeb1'   #  0x00bc -> ARABIC LETTER SEEN ISOLATED FORM
+    u'\ufeb5'   #  0x00bd -> ARABIC LETTER SHEEN ISOLATED FORM
+    u'\ufeb9'   #  0x00be -> ARABIC LETTER SAD ISOLATED FORM
+    u'\u061f'   #  0x00bf -> ARABIC QUESTION MARK
+    u'\xa2'     #  0x00c0 -> CENT SIGN
+    u'\ufe80'   #  0x00c1 -> ARABIC LETTER HAMZA ISOLATED FORM
+    u'\ufe81'   #  0x00c2 -> ARABIC LETTER ALEF WITH MADDA ABOVE ISOLATED FORM
+    u'\ufe83'   #  0x00c3 -> ARABIC LETTER ALEF WITH HAMZA ABOVE ISOLATED FORM
+    u'\ufe85'   #  0x00c4 -> ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM
+    u'\ufeca'   #  0x00c5 -> ARABIC LETTER AIN FINAL FORM
+    u'\ufe8b'   #  0x00c6 -> ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM
+    u'\ufe8d'   #  0x00c7 -> ARABIC LETTER ALEF ISOLATED FORM
+    u'\ufe91'   #  0x00c8 -> ARABIC LETTER BEH INITIAL FORM
+    u'\ufe93'   #  0x00c9 -> ARABIC LETTER TEH MARBUTA ISOLATED FORM
+    u'\ufe97'   #  0x00ca -> ARABIC LETTER TEH INITIAL FORM
+    u'\ufe9b'   #  0x00cb -> ARABIC LETTER THEH INITIAL FORM
+    u'\ufe9f'   #  0x00cc -> ARABIC LETTER JEEM INITIAL FORM
+    u'\ufea3'   #  0x00cd -> ARABIC LETTER HAH INITIAL FORM
+    u'\ufea7'   #  0x00ce -> ARABIC LETTER KHAH INITIAL FORM
+    u'\ufea9'   #  0x00cf -> ARABIC LETTER DAL ISOLATED FORM
+    u'\ufeab'   #  0x00d0 -> ARABIC LETTER THAL ISOLATED FORM
+    u'\ufead'   #  0x00d1 -> ARABIC LETTER REH ISOLATED FORM
+    u'\ufeaf'   #  0x00d2 -> ARABIC LETTER ZAIN ISOLATED FORM
+    u'\ufeb3'   #  0x00d3 -> ARABIC LETTER SEEN INITIAL FORM
+    u'\ufeb7'   #  0x00d4 -> ARABIC LETTER SHEEN INITIAL FORM
+    u'\ufebb'   #  0x00d5 -> ARABIC LETTER SAD INITIAL FORM
+    u'\ufebf'   #  0x00d6 -> ARABIC LETTER DAD INITIAL FORM
+    u'\ufec1'   #  0x00d7 -> ARABIC LETTER TAH ISOLATED FORM
+    u'\ufec5'   #  0x00d8 -> ARABIC LETTER ZAH ISOLATED FORM
+    u'\ufecb'   #  0x00d9 -> ARABIC LETTER AIN INITIAL FORM
+    u'\ufecf'   #  0x00da -> ARABIC LETTER GHAIN INITIAL FORM
+    u'\xa6'     #  0x00db -> BROKEN VERTICAL BAR
+    u'\xac'     #  0x00dc -> NOT SIGN
+    u'\xf7'     #  0x00dd -> DIVISION SIGN
+    u'\xd7'     #  0x00de -> MULTIPLICATION SIGN
+    u'\ufec9'   #  0x00df -> ARABIC LETTER AIN ISOLATED FORM
+    u'\u0640'   #  0x00e0 -> ARABIC TATWEEL
+    u'\ufed3'   #  0x00e1 -> ARABIC LETTER FEH INITIAL FORM
+    u'\ufed7'   #  0x00e2 -> ARABIC LETTER QAF INITIAL FORM
+    u'\ufedb'   #  0x00e3 -> ARABIC LETTER KAF INITIAL FORM
+    u'\ufedf'   #  0x00e4 -> ARABIC LETTER LAM INITIAL FORM
+    u'\ufee3'   #  0x00e5 -> ARABIC LETTER MEEM INITIAL FORM
+    u'\ufee7'   #  0x00e6 -> ARABIC LETTER NOON INITIAL FORM
+    u'\ufeeb'   #  0x00e7 -> ARABIC LETTER HEH INITIAL FORM
+    u'\ufeed'   #  0x00e8 -> ARABIC LETTER WAW ISOLATED FORM
+    u'\ufeef'   #  0x00e9 -> ARABIC LETTER ALEF MAKSURA ISOLATED FORM
+    u'\ufef3'   #  0x00ea -> ARABIC LETTER YEH INITIAL FORM
+    u'\ufebd'   #  0x00eb -> ARABIC LETTER DAD ISOLATED FORM
+    u'\ufecc'   #  0x00ec -> ARABIC LETTER AIN MEDIAL FORM
+    u'\ufece'   #  0x00ed -> ARABIC LETTER GHAIN FINAL FORM
+    u'\ufecd'   #  0x00ee -> ARABIC LETTER GHAIN ISOLATED FORM
+    u'\ufee1'   #  0x00ef -> ARABIC LETTER MEEM ISOLATED FORM
+    u'\ufe7d'   #  0x00f0 -> ARABIC SHADDA MEDIAL FORM
+    u'\u0651'   #  0x00f1 -> ARABIC SHADDAH
+    u'\ufee5'   #  0x00f2 -> ARABIC LETTER NOON ISOLATED FORM
+    u'\ufee9'   #  0x00f3 -> ARABIC LETTER HEH ISOLATED FORM
+    u'\ufeec'   #  0x00f4 -> ARABIC LETTER HEH MEDIAL FORM
+    u'\ufef0'   #  0x00f5 -> ARABIC LETTER ALEF MAKSURA FINAL FORM
+    u'\ufef2'   #  0x00f6 -> ARABIC LETTER YEH FINAL FORM
+    u'\ufed0'   #  0x00f7 -> ARABIC LETTER GHAIN MEDIAL FORM
+    u'\ufed5'   #  0x00f8 -> ARABIC LETTER QAF ISOLATED FORM
+    u'\ufef5'   #  0x00f9 -> ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM
+    u'\ufef6'   #  0x00fa -> ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM
+    u'\ufedd'   #  0x00fb -> ARABIC LETTER LAM ISOLATED FORM
+    u'\ufed9'   #  0x00fc -> ARABIC LETTER KAF ISOLATED FORM
+    u'\ufef1'   #  0x00fd -> ARABIC LETTER YEH ISOLATED FORM
+    u'\u25a0'   #  0x00fe -> BLACK SQUARE
+    u'\ufffe'   #  0x00ff -> UNDEFINED
+)
+
+### Encoding Map
+
+encoding_map = {
+    0x0000: 0x0000,     #  NULL
+    0x0001: 0x0001,     #  START OF HEADING
+    0x0002: 0x0002,     #  START OF TEXT
+    0x0003: 0x0003,     #  END OF TEXT
+    0x0004: 0x0004,     #  END OF TRANSMISSION
+    0x0005: 0x0005,     #  ENQUIRY
+    0x0006: 0x0006,     #  ACKNOWLEDGE
+    0x0007: 0x0007,     #  BELL
+    0x0008: 0x0008,     #  BACKSPACE
+    0x0009: 0x0009,     #  HORIZONTAL TABULATION
+    0x000a: 0x000a,     #  LINE FEED
+    0x000b: 0x000b,     #  VERTICAL TABULATION
+    0x000c: 0x000c,     #  FORM FEED
+    0x000d: 0x000d,     #  CARRIAGE RETURN
+    0x000e: 0x000e,     #  SHIFT OUT
+    0x000f: 0x000f,     #  SHIFT IN
+    0x0010: 0x0010,     #  DATA LINK ESCAPE
+    0x0011: 0x0011,     #  DEVICE CONTROL ONE
+    0x0012: 0x0012,     #  DEVICE CONTROL TWO
+    0x0013: 0x0013,     #  DEVICE CONTROL THREE
+    0x0014: 0x0014,     #  DEVICE CONTROL FOUR
+    0x0015: 0x0015,     #  NEGATIVE ACKNOWLEDGE
+    0x0016: 0x0016,     #  SYNCHRONOUS IDLE
+    0x0017: 0x0017,     #  END OF TRANSMISSION BLOCK
+    0x0018: 0x0018,     #  CANCEL
+    0x0019: 0x0019,     #  END OF MEDIUM
+    0x001a: 0x001a,     #  SUBSTITUTE
+    0x001b: 0x001b,     #  ESCAPE
+    0x001c: 0x001c,     #  FILE SEPARATOR
+    0x001d: 0x001d,     #  GROUP SEPARATOR
+    0x001e: 0x001e,     #  RECORD SEPARATOR
+    0x001f: 0x001f,     #  UNIT SEPARATOR
+    0x0020: 0x0020,     #  SPACE
+    0x0021: 0x0021,     #  EXCLAMATION MARK
+    0x0022: 0x0022,     #  QUOTATION MARK
+    0x0023: 0x0023,     #  NUMBER SIGN
+    0x0024: 0x0024,     #  DOLLAR SIGN
+    0x0026: 0x0026,     #  AMPERSAND
+    0x0027: 0x0027,     #  APOSTROPHE
+    0x0028: 0x0028,     #  LEFT PARENTHESIS
+    0x0029: 0x0029,     #  RIGHT PARENTHESIS
+    0x002a: 0x002a,     #  ASTERISK
+    0x002b: 0x002b,     #  PLUS SIGN
+    0x002c: 0x002c,     #  COMMA
+    0x002d: 0x002d,     #  HYPHEN-MINUS
+    0x002e: 0x002e,     #  FULL STOP
+    0x002f: 0x002f,     #  SOLIDUS
+    0x0030: 0x0030,     #  DIGIT ZERO
+    0x0031: 0x0031,     #  DIGIT ONE
+    0x0032: 0x0032,     #  DIGIT TWO
+    0x0033: 0x0033,     #  DIGIT THREE
+    0x0034: 0x0034,     #  DIGIT FOUR
+    0x0035: 0x0035,     #  DIGIT FIVE
+    0x0036: 0x0036,     #  DIGIT SIX
+    0x0037: 0x0037,     #  DIGIT SEVEN
+    0x0038: 0x0038,     #  DIGIT EIGHT
+    0x0039: 0x0039,     #  DIGIT NINE
+    0x003a: 0x003a,     #  COLON
+    0x003b: 0x003b,     #  SEMICOLON
+    0x003c: 0x003c,     #  LESS-THAN SIGN
+    0x003d: 0x003d,     #  EQUALS SIGN
+    0x003e: 0x003e,     #  GREATER-THAN SIGN
+    0x003f: 0x003f,     #  QUESTION MARK
+    0x0040: 0x0040,     #  COMMERCIAL AT
+    0x0041: 0x0041,     #  LATIN CAPITAL LETTER A
+    0x0042: 0x0042,     #  LATIN CAPITAL LETTER B
+    0x0043: 0x0043,     #  LATIN CAPITAL LETTER C
+    0x0044: 0x0044,     #  LATIN CAPITAL LETTER D
+    0x0045: 0x0045,     #  LATIN CAPITAL LETTER E
+    0x0046: 0x0046,     #  LATIN CAPITAL LETTER F
+    0x0047: 0x0047,     #  LATIN CAPITAL LETTER G
+    0x0048: 0x0048,     #  LATIN CAPITAL LETTER H
+    0x0049: 0x0049,     #  LATIN CAPITAL LETTER I
+    0x004a: 0x004a,     #  LATIN CAPITAL LETTER J
+    0x004b: 0x004b,     #  LATIN CAPITAL LETTER K
+    0x004c: 0x004c,     #  LATIN CAPITAL LETTER L
+    0x004d: 0x004d,     #  LATIN CAPITAL LETTER M
+    0x004e: 0x004e,     #  LATIN CAPITAL LETTER N
+    0x004f: 0x004f,     #  LATIN CAPITAL LETTER O
+    0x0050: 0x0050,     #  LATIN CAPITAL LETTER P
+    0x0051: 0x0051,     #  LATIN CAPITAL LETTER Q
+    0x0052: 0x0052,     #  LATIN CAPITAL LETTER R
+    0x0053: 0x0053,     #  LATIN CAPITAL LETTER S
+    0x0054: 0x0054,     #  LATIN CAPITAL LETTER T
+    0x0055: 0x0055,     #  LATIN CAPITAL LETTER U
+    0x0056: 0x0056,     #  LATIN CAPITAL LETTER V
+    0x0057: 0x0057,     #  LATIN CAPITAL LETTER W
+    0x0058: 0x0058,     #  LATIN CAPITAL LETTER X
+    0x0059: 0x0059,     #  LATIN CAPITAL LETTER Y
+    0x005a: 0x005a,     #  LATIN CAPITAL LETTER Z
+    0x005b: 0x005b,     #  LEFT SQUARE BRACKET
+    0x005c: 0x005c,     #  REVERSE SOLIDUS
+    0x005d: 0x005d,     #  RIGHT SQUARE BRACKET
+    0x005e: 0x005e,     #  CIRCUMFLEX ACCENT
+    0x005f: 0x005f,     #  LOW LINE
+    0x0060: 0x0060,     #  GRAVE ACCENT
+    0x0061: 0x0061,     #  LATIN SMALL LETTER A
+    0x0062: 0x0062,     #  LATIN SMALL LETTER B
+    0x0063: 0x0063,     #  LATIN SMALL LETTER C
+    0x0064: 0x0064,     #  LATIN SMALL LETTER D
+    0x0065: 0x0065,     #  LATIN SMALL LETTER E
+    0x0066: 0x0066,     #  LATIN SMALL LETTER F
+    0x0067: 0x0067,     #  LATIN SMALL LETTER G
+    0x0068: 0x0068,     #  LATIN SMALL LETTER H
+    0x0069: 0x0069,     #  LATIN SMALL LETTER I
+    0x006a: 0x006a,     #  LATIN SMALL LETTER J
+    0x006b: 0x006b,     #  LATIN SMALL LETTER K
+    0x006c: 0x006c,     #  LATIN SMALL LETTER L
+    0x006d: 0x006d,     #  LATIN SMALL LETTER M
+    0x006e: 0x006e,     #  LATIN SMALL LETTER N
+    0x006f: 0x006f,     #  LATIN SMALL LETTER O
+    0x0070: 0x0070,     #  LATIN SMALL LETTER P
+    0x0071: 0x0071,     #  LATIN SMALL LETTER Q
+    0x0072: 0x0072,     #  LATIN SMALL LETTER R
+    0x0073: 0x0073,     #  LATIN SMALL LETTER S
+    0x0074: 0x0074,     #  LATIN SMALL LETTER T
+    0x0075: 0x0075,     #  LATIN SMALL LETTER U
+    0x0076: 0x0076,     #  LATIN SMALL LETTER V
+    0x0077: 0x0077,     #  LATIN SMALL LETTER W
+    0x0078: 0x0078,     #  LATIN SMALL LETTER X
+    0x0079: 0x0079,     #  LATIN SMALL LETTER Y
+    0x007a: 0x007a,     #  LATIN SMALL LETTER Z
+    0x007b: 0x007b,     #  LEFT CURLY BRACKET
+    0x007c: 0x007c,     #  VERTICAL LINE
+    0x007d: 0x007d,     #  RIGHT CURLY BRACKET
+    0x007e: 0x007e,     #  TILDE
+    0x007f: 0x007f,     #  DELETE
+    0x00a0: 0x00a0,     #  NON-BREAKING SPACE
+    0x00a2: 0x00c0,     #  CENT SIGN
+    0x00a3: 0x00a3,     #  POUND SIGN
+    0x00a4: 0x00a4,     #  CURRENCY SIGN
+    0x00a6: 0x00db,     #  BROKEN VERTICAL BAR
+    0x00ab: 0x0097,     #  LEFT POINTING GUILLEMET
+    0x00ac: 0x00dc,     #  NOT SIGN
+    0x00ad: 0x00a1,     #  SOFT HYPHEN
+    0x00b0: 0x0080,     #  DEGREE SIGN
+    0x00b1: 0x0093,     #  PLUS-OR-MINUS SIGN
+    0x00b7: 0x0081,     #  MIDDLE DOT
+    0x00bb: 0x0098,     #  RIGHT POINTING GUILLEMET
+    0x00bc: 0x0095,     #  FRACTION 1/4
+    0x00bd: 0x0094,     #  FRACTION 1/2
+    0x00d7: 0x00de,     #  MULTIPLICATION SIGN
+    0x00f7: 0x00dd,     #  DIVISION SIGN
+    0x03b2: 0x0090,     #  GREEK SMALL BETA
+    0x03c6: 0x0092,     #  GREEK SMALL PHI
+    0x060c: 0x00ac,     #  ARABIC COMMA
+    0x061b: 0x00bb,     #  ARABIC SEMICOLON
+    0x061f: 0x00bf,     #  ARABIC QUESTION MARK
+    0x0640: 0x00e0,     #  ARABIC TATWEEL
+    0x0651: 0x00f1,     #  ARABIC SHADDAH
+    0x0660: 0x00b0,     #  ARABIC-INDIC DIGIT ZERO
+    0x0661: 0x00b1,     #  ARABIC-INDIC DIGIT ONE
+    0x0662: 0x00b2,     #  ARABIC-INDIC DIGIT TWO
+    0x0663: 0x00b3,     #  ARABIC-INDIC DIGIT THREE
+    0x0664: 0x00b4,     #  ARABIC-INDIC DIGIT FOUR
+    0x0665: 0x00b5,     #  ARABIC-INDIC DIGIT FIVE
+    0x0666: 0x00b6,     #  ARABIC-INDIC DIGIT SIX
+    0x0667: 0x00b7,     #  ARABIC-INDIC DIGIT SEVEN
+    0x0668: 0x00b8,     #  ARABIC-INDIC DIGIT EIGHT
+    0x0669: 0x00b9,     #  ARABIC-INDIC DIGIT NINE
+    0x066a: 0x0025,     #  ARABIC PERCENT SIGN
+    0x2219: 0x0082,     #  BULLET OPERATOR
+    0x221a: 0x0083,     #  SQUARE ROOT
+    0x221e: 0x0091,     #  INFINITY
+    0x2248: 0x0096,     #  ALMOST EQUAL TO
+    0x2500: 0x0085,     #  FORMS LIGHT HORIZONTAL
+    0x2502: 0x0086,     #  FORMS LIGHT VERTICAL
+    0x250c: 0x008d,     #  FORMS LIGHT DOWN AND RIGHT
+    0x2510: 0x008c,     #  FORMS LIGHT DOWN AND LEFT
+    0x2514: 0x008e,     #  FORMS LIGHT UP AND RIGHT
+    0x2518: 0x008f,     #  FORMS LIGHT UP AND LEFT
+    0x251c: 0x008a,     #  FORMS LIGHT VERTICAL AND RIGHT
+    0x2524: 0x0088,     #  FORMS LIGHT VERTICAL AND LEFT
+    0x252c: 0x0089,     #  FORMS LIGHT DOWN AND HORIZONTAL
+    0x2534: 0x008b,     #  FORMS LIGHT UP AND HORIZONTAL
+    0x253c: 0x0087,     #  FORMS LIGHT VERTICAL AND HORIZONTAL
+    0x2592: 0x0084,     #  MEDIUM SHADE
+    0x25a0: 0x00fe,     #  BLACK SQUARE
+    0xfe7d: 0x00f0,     #  ARABIC SHADDA MEDIAL FORM
+    0xfe80: 0x00c1,     #  ARABIC LETTER HAMZA ISOLATED FORM
+    0xfe81: 0x00c2,     #  ARABIC LETTER ALEF WITH MADDA ABOVE ISOLATED FORM
+    0xfe82: 0x00a2,     #  ARABIC LETTER ALEF WITH MADDA ABOVE FINAL FORM
+    0xfe83: 0x00c3,     #  ARABIC LETTER ALEF WITH HAMZA ABOVE ISOLATED FORM
+    0xfe84: 0x00a5,     #  ARABIC LETTER ALEF WITH HAMZA ABOVE FINAL FORM
+    0xfe85: 0x00c4,     #  ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM
+    0xfe8b: 0x00c6,     #  ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM
+    0xfe8d: 0x00c7,     #  ARABIC LETTER ALEF ISOLATED FORM
+    0xfe8e: 0x00a8,     #  ARABIC LETTER ALEF FINAL FORM
+    0xfe8f: 0x00a9,     #  ARABIC LETTER BEH ISOLATED FORM
+    0xfe91: 0x00c8,     #  ARABIC LETTER BEH INITIAL FORM
+    0xfe93: 0x00c9,     #  ARABIC LETTER TEH MARBUTA ISOLATED FORM
+    0xfe95: 0x00aa,     #  ARABIC LETTER TEH ISOLATED FORM
+    0xfe97: 0x00ca,     #  ARABIC LETTER TEH INITIAL FORM
+    0xfe99: 0x00ab,     #  ARABIC LETTER THEH ISOLATED FORM
+    0xfe9b: 0x00cb,     #  ARABIC LETTER THEH INITIAL FORM
+    0xfe9d: 0x00ad,     #  ARABIC LETTER JEEM ISOLATED FORM
+    0xfe9f: 0x00cc,     #  ARABIC LETTER JEEM INITIAL FORM
+    0xfea1: 0x00ae,     #  ARABIC LETTER HAH ISOLATED FORM
+    0xfea3: 0x00cd,     #  ARABIC LETTER HAH INITIAL FORM
+    0xfea5: 0x00af,     #  ARABIC LETTER KHAH ISOLATED FORM
+    0xfea7: 0x00ce,     #  ARABIC LETTER KHAH INITIAL FORM
+    0xfea9: 0x00cf,     #  ARABIC LETTER DAL ISOLATED FORM
+    0xfeab: 0x00d0,     #  ARABIC LETTER THAL ISOLATED FORM
+    0xfead: 0x00d1,     #  ARABIC LETTER REH ISOLATED FORM
+    0xfeaf: 0x00d2,     #  ARABIC LETTER ZAIN ISOLATED FORM
+    0xfeb1: 0x00bc,     #  ARABIC LETTER SEEN ISOLATED FORM
+    0xfeb3: 0x00d3,     #  ARABIC LETTER SEEN INITIAL FORM
+    0xfeb5: 0x00bd,     #  ARABIC LETTER SHEEN ISOLATED FORM
+    0xfeb7: 0x00d4,     #  ARABIC LETTER SHEEN INITIAL FORM
+    0xfeb9: 0x00be,     #  ARABIC LETTER SAD ISOLATED FORM
+    0xfebb: 0x00d5,     #  ARABIC LETTER SAD INITIAL FORM
+    0xfebd: 0x00eb,     #  ARABIC LETTER DAD ISOLATED FORM
+    0xfebf: 0x00d6,     #  ARABIC LETTER DAD INITIAL FORM
+    0xfec1: 0x00d7,     #  ARABIC LETTER TAH ISOLATED FORM
+    0xfec5: 0x00d8,     #  ARABIC LETTER ZAH ISOLATED FORM
+    0xfec9: 0x00df,     #  ARABIC LETTER AIN ISOLATED FORM
+    0xfeca: 0x00c5,     #  ARABIC LETTER AIN FINAL FORM
+    0xfecb: 0x00d9,     #  ARABIC LETTER AIN INITIAL FORM
+    0xfecc: 0x00ec,     #  ARABIC LETTER AIN MEDIAL FORM
+    0xfecd: 0x00ee,     #  ARABIC LETTER GHAIN ISOLATED FORM
+    0xfece: 0x00ed,     #  ARABIC LETTER GHAIN FINAL FORM
+    0xfecf: 0x00da,     #  ARABIC LETTER GHAIN INITIAL FORM
+    0xfed0: 0x00f7,     #  ARABIC LETTER GHAIN MEDIAL FORM
+    0xfed1: 0x00ba,     #  ARABIC LETTER FEH ISOLATED FORM
+    0xfed3: 0x00e1,     #  ARABIC LETTER FEH INITIAL FORM
+    0xfed5: 0x00f8,     #  ARABIC LETTER QAF ISOLATED FORM
+    0xfed7: 0x00e2,     #  ARABIC LETTER QAF INITIAL FORM
+    0xfed9: 0x00fc,     #  ARABIC LETTER KAF ISOLATED FORM
+    0xfedb: 0x00e3,     #  ARABIC LETTER KAF INITIAL FORM
+    0xfedd: 0x00fb,     #  ARABIC LETTER LAM ISOLATED FORM
+    0xfedf: 0x00e4,     #  ARABIC LETTER LAM INITIAL FORM
+    0xfee1: 0x00ef,     #  ARABIC LETTER MEEM ISOLATED FORM
+    0xfee3: 0x00e5,     #  ARABIC LETTER MEEM INITIAL FORM
+    0xfee5: 0x00f2,     #  ARABIC LETTER NOON ISOLATED FORM
+    0xfee7: 0x00e6,     #  ARABIC LETTER NOON INITIAL FORM
+    0xfee9: 0x00f3,     #  ARABIC LETTER HEH ISOLATED FORM
+    0xfeeb: 0x00e7,     #  ARABIC LETTER HEH INITIAL FORM
+    0xfeec: 0x00f4,     #  ARABIC LETTER HEH MEDIAL FORM
+    0xfeed: 0x00e8,     #  ARABIC LETTER WAW ISOLATED FORM
+    0xfeef: 0x00e9,     #  ARABIC LETTER ALEF MAKSURA ISOLATED FORM
+    0xfef0: 0x00f5,     #  ARABIC LETTER ALEF MAKSURA FINAL FORM
+    0xfef1: 0x00fd,     #  ARABIC LETTER YEH ISOLATED FORM
+    0xfef2: 0x00f6,     #  ARABIC LETTER YEH FINAL FORM
+    0xfef3: 0x00ea,     #  ARABIC LETTER YEH INITIAL FORM
+    0xfef5: 0x00f9,     #  ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM
+    0xfef6: 0x00fa,     #  ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM
+    0xfef7: 0x0099,     #  ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM
+    0xfef8: 0x009a,     #  ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM
+    0xfefb: 0x009d,     #  ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM
+    0xfefc: 0x009e,     #  ARABIC LIGATURE LAM WITH ALEF FINAL FORM
+}

Added: vendor/Python/current/Lib/encodings/cp865.py
===================================================================
--- vendor/Python/current/Lib/encodings/cp865.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/cp865.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,698 @@
+""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP865.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_map)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='cp865',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+### Decoding Map
+
+decoding_map = codecs.make_identity_dict(range(256))
+decoding_map.update({
+    0x0080: 0x00c7,     #  LATIN CAPITAL LETTER C WITH CEDILLA
+    0x0081: 0x00fc,     #  LATIN SMALL LETTER U WITH DIAERESIS
+    0x0082: 0x00e9,     #  LATIN SMALL LETTER E WITH ACUTE
+    0x0083: 0x00e2,     #  LATIN SMALL LETTER A WITH CIRCUMFLEX
+    0x0084: 0x00e4,     #  LATIN SMALL LETTER A WITH DIAERESIS
+    0x0085: 0x00e0,     #  LATIN SMALL LETTER A WITH GRAVE
+    0x0086: 0x00e5,     #  LATIN SMALL LETTER A WITH RING ABOVE
+    0x0087: 0x00e7,     #  LATIN SMALL LETTER C WITH CEDILLA
+    0x0088: 0x00ea,     #  LATIN SMALL LETTER E WITH CIRCUMFLEX
+    0x0089: 0x00eb,     #  LATIN SMALL LETTER E WITH DIAERESIS
+    0x008a: 0x00e8,     #  LATIN SMALL LETTER E WITH GRAVE
+    0x008b: 0x00ef,     #  LATIN SMALL LETTER I WITH DIAERESIS
+    0x008c: 0x00ee,     #  LATIN SMALL LETTER I WITH CIRCUMFLEX
+    0x008d: 0x00ec,     #  LATIN SMALL LETTER I WITH GRAVE
+    0x008e: 0x00c4,     #  LATIN CAPITAL LETTER A WITH DIAERESIS
+    0x008f: 0x00c5,     #  LATIN CAPITAL LETTER A WITH RING ABOVE
+    0x0090: 0x00c9,     #  LATIN CAPITAL LETTER E WITH ACUTE
+    0x0091: 0x00e6,     #  LATIN SMALL LIGATURE AE
+    0x0092: 0x00c6,     #  LATIN CAPITAL LIGATURE AE
+    0x0093: 0x00f4,     #  LATIN SMALL LETTER O WITH CIRCUMFLEX
+    0x0094: 0x00f6,     #  LATIN SMALL LETTER O WITH DIAERESIS
+    0x0095: 0x00f2,     #  LATIN SMALL LETTER O WITH GRAVE
+    0x0096: 0x00fb,     #  LATIN SMALL LETTER U WITH CIRCUMFLEX
+    0x0097: 0x00f9,     #  LATIN SMALL LETTER U WITH GRAVE
+    0x0098: 0x00ff,     #  LATIN SMALL LETTER Y WITH DIAERESIS
+    0x0099: 0x00d6,     #  LATIN CAPITAL LETTER O WITH DIAERESIS
+    0x009a: 0x00dc,     #  LATIN CAPITAL LETTER U WITH DIAERESIS
+    0x009b: 0x00f8,     #  LATIN SMALL LETTER O WITH STROKE
+    0x009c: 0x00a3,     #  POUND SIGN
+    0x009d: 0x00d8,     #  LATIN CAPITAL LETTER O WITH STROKE
+    0x009e: 0x20a7,     #  PESETA SIGN
+    0x009f: 0x0192,     #  LATIN SMALL LETTER F WITH HOOK
+    0x00a0: 0x00e1,     #  LATIN SMALL LETTER A WITH ACUTE
+    0x00a1: 0x00ed,     #  LATIN SMALL LETTER I WITH ACUTE
+    0x00a2: 0x00f3,     #  LATIN SMALL LETTER O WITH ACUTE
+    0x00a3: 0x00fa,     #  LATIN SMALL LETTER U WITH ACUTE
+    0x00a4: 0x00f1,     #  LATIN SMALL LETTER N WITH TILDE
+    0x00a5: 0x00d1,     #  LATIN CAPITAL LETTER N WITH TILDE
+    0x00a6: 0x00aa,     #  FEMININE ORDINAL INDICATOR
+    0x00a7: 0x00ba,     #  MASCULINE ORDINAL INDICATOR
+    0x00a8: 0x00bf,     #  INVERTED QUESTION MARK
+    0x00a9: 0x2310,     #  REVERSED NOT SIGN
+    0x00aa: 0x00ac,     #  NOT SIGN
+    0x00ab: 0x00bd,     #  VULGAR FRACTION ONE HALF
+    0x00ac: 0x00bc,     #  VULGAR FRACTION ONE QUARTER
+    0x00ad: 0x00a1,     #  INVERTED EXCLAMATION MARK
+    0x00ae: 0x00ab,     #  LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    0x00af: 0x00a4,     #  CURRENCY SIGN
+    0x00b0: 0x2591,     #  LIGHT SHADE
+    0x00b1: 0x2592,     #  MEDIUM SHADE
+    0x00b2: 0x2593,     #  DARK SHADE
+    0x00b3: 0x2502,     #  BOX DRAWINGS LIGHT VERTICAL
+    0x00b4: 0x2524,     #  BOX DRAWINGS LIGHT VERTICAL AND LEFT
+    0x00b5: 0x2561,     #  BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+    0x00b6: 0x2562,     #  BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
+    0x00b7: 0x2556,     #  BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
+    0x00b8: 0x2555,     #  BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
+    0x00b9: 0x2563,     #  BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+    0x00ba: 0x2551,     #  BOX DRAWINGS DOUBLE VERTICAL
+    0x00bb: 0x2557,     #  BOX DRAWINGS DOUBLE DOWN AND LEFT
+    0x00bc: 0x255d,     #  BOX DRAWINGS DOUBLE UP AND LEFT
+    0x00bd: 0x255c,     #  BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
+    0x00be: 0x255b,     #  BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+    0x00bf: 0x2510,     #  BOX DRAWINGS LIGHT DOWN AND LEFT
+    0x00c0: 0x2514,     #  BOX DRAWINGS LIGHT UP AND RIGHT
+    0x00c1: 0x2534,     #  BOX DRAWINGS LIGHT UP AND HORIZONTAL
+    0x00c2: 0x252c,     #  BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+    0x00c3: 0x251c,     #  BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+    0x00c4: 0x2500,     #  BOX DRAWINGS LIGHT HORIZONTAL
+    0x00c5: 0x253c,     #  BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+    0x00c6: 0x255e,     #  BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+    0x00c7: 0x255f,     #  BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+    0x00c8: 0x255a,     #  BOX DRAWINGS DOUBLE UP AND RIGHT
+    0x00c9: 0x2554,     #  BOX DRAWINGS DOUBLE DOWN AND RIGHT
+    0x00ca: 0x2569,     #  BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+    0x00cb: 0x2566,     #  BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+    0x00cc: 0x2560,     #  BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+    0x00cd: 0x2550,     #  BOX DRAWINGS DOUBLE HORIZONTAL
+    0x00ce: 0x256c,     #  BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+    0x00cf: 0x2567,     #  BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+    0x00d0: 0x2568,     #  BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+    0x00d1: 0x2564,     #  BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
+    0x00d2: 0x2565,     #  BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
+    0x00d3: 0x2559,     #  BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+    0x00d4: 0x2558,     #  BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+    0x00d5: 0x2552,     #  BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+    0x00d6: 0x2553,     #  BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
+    0x00d7: 0x256b,     #  BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
+    0x00d8: 0x256a,     #  BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+    0x00d9: 0x2518,     #  BOX DRAWINGS LIGHT UP AND LEFT
+    0x00da: 0x250c,     #  BOX DRAWINGS LIGHT DOWN AND RIGHT
+    0x00db: 0x2588,     #  FULL BLOCK
+    0x00dc: 0x2584,     #  LOWER HALF BLOCK
+    0x00dd: 0x258c,     #  LEFT HALF BLOCK
+    0x00de: 0x2590,     #  RIGHT HALF BLOCK
+    0x00df: 0x2580,     #  UPPER HALF BLOCK
+    0x00e0: 0x03b1,     #  GREEK SMALL LETTER ALPHA
+    0x00e1: 0x00df,     #  LATIN SMALL LETTER SHARP S
+    0x00e2: 0x0393,     #  GREEK CAPITAL LETTER GAMMA
+    0x00e3: 0x03c0,     #  GREEK SMALL LETTER PI
+    0x00e4: 0x03a3,     #  GREEK CAPITAL LETTER SIGMA
+    0x00e5: 0x03c3,     #  GREEK SMALL LETTER SIGMA
+    0x00e6: 0x00b5,     #  MICRO SIGN
+    0x00e7: 0x03c4,     #  GREEK SMALL LETTER TAU
+    0x00e8: 0x03a6,     #  GREEK CAPITAL LETTER PHI
+    0x00e9: 0x0398,     #  GREEK CAPITAL LETTER THETA
+    0x00ea: 0x03a9,     #  GREEK CAPITAL LETTER OMEGA
+    0x00eb: 0x03b4,     #  GREEK SMALL LETTER DELTA
+    0x00ec: 0x221e,     #  INFINITY
+    0x00ed: 0x03c6,     #  GREEK SMALL LETTER PHI
+    0x00ee: 0x03b5,     #  GREEK SMALL LETTER EPSILON
+    0x00ef: 0x2229,     #  INTERSECTION
+    0x00f0: 0x2261,     #  IDENTICAL TO
+    0x00f1: 0x00b1,     #  PLUS-MINUS SIGN
+    0x00f2: 0x2265,     #  GREATER-THAN OR EQUAL TO
+    0x00f3: 0x2264,     #  LESS-THAN OR EQUAL TO
+    0x00f4: 0x2320,     #  TOP HALF INTEGRAL
+    0x00f5: 0x2321,     #  BOTTOM HALF INTEGRAL
+    0x00f6: 0x00f7,     #  DIVISION SIGN
+    0x00f7: 0x2248,     #  ALMOST EQUAL TO
+    0x00f8: 0x00b0,     #  DEGREE SIGN
+    0x00f9: 0x2219,     #  BULLET OPERATOR
+    0x00fa: 0x00b7,     #  MIDDLE DOT
+    0x00fb: 0x221a,     #  SQUARE ROOT
+    0x00fc: 0x207f,     #  SUPERSCRIPT LATIN SMALL LETTER N
+    0x00fd: 0x00b2,     #  SUPERSCRIPT TWO
+    0x00fe: 0x25a0,     #  BLACK SQUARE
+    0x00ff: 0x00a0,     #  NO-BREAK SPACE
+})
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x0000 -> NULL
+    u'\x01'     #  0x0001 -> START OF HEADING
+    u'\x02'     #  0x0002 -> START OF TEXT
+    u'\x03'     #  0x0003 -> END OF TEXT
+    u'\x04'     #  0x0004 -> END OF TRANSMISSION
+    u'\x05'     #  0x0005 -> ENQUIRY
+    u'\x06'     #  0x0006 -> ACKNOWLEDGE
+    u'\x07'     #  0x0007 -> BELL
+    u'\x08'     #  0x0008 -> BACKSPACE
+    u'\t'       #  0x0009 -> HORIZONTAL TABULATION
+    u'\n'       #  0x000a -> LINE FEED
+    u'\x0b'     #  0x000b -> VERTICAL TABULATION
+    u'\x0c'     #  0x000c -> FORM FEED
+    u'\r'       #  0x000d -> CARRIAGE RETURN
+    u'\x0e'     #  0x000e -> SHIFT OUT
+    u'\x0f'     #  0x000f -> SHIFT IN
+    u'\x10'     #  0x0010 -> DATA LINK ESCAPE
+    u'\x11'     #  0x0011 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x0012 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x0013 -> DEVICE CONTROL THREE
+    u'\x14'     #  0x0014 -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x0015 -> NEGATIVE ACKNOWLEDGE
+    u'\x16'     #  0x0016 -> SYNCHRONOUS IDLE
+    u'\x17'     #  0x0017 -> END OF TRANSMISSION BLOCK
+    u'\x18'     #  0x0018 -> CANCEL
+    u'\x19'     #  0x0019 -> END OF MEDIUM
+    u'\x1a'     #  0x001a -> SUBSTITUTE
+    u'\x1b'     #  0x001b -> ESCAPE
+    u'\x1c'     #  0x001c -> FILE SEPARATOR
+    u'\x1d'     #  0x001d -> GROUP SEPARATOR
+    u'\x1e'     #  0x001e -> RECORD SEPARATOR
+    u'\x1f'     #  0x001f -> UNIT SEPARATOR
+    u' '        #  0x0020 -> SPACE
+    u'!'        #  0x0021 -> EXCLAMATION MARK
+    u'"'        #  0x0022 -> QUOTATION MARK
+    u'#'        #  0x0023 -> NUMBER SIGN
+    u'$'        #  0x0024 -> DOLLAR SIGN
+    u'%'        #  0x0025 -> PERCENT SIGN
+    u'&'        #  0x0026 -> AMPERSAND
+    u"'"        #  0x0027 -> APOSTROPHE
+    u'('        #  0x0028 -> LEFT PARENTHESIS
+    u')'        #  0x0029 -> RIGHT PARENTHESIS
+    u'*'        #  0x002a -> ASTERISK
+    u'+'        #  0x002b -> PLUS SIGN
+    u','        #  0x002c -> COMMA
+    u'-'        #  0x002d -> HYPHEN-MINUS
+    u'.'        #  0x002e -> FULL STOP
+    u'/'        #  0x002f -> SOLIDUS
+    u'0'        #  0x0030 -> DIGIT ZERO
+    u'1'        #  0x0031 -> DIGIT ONE
+    u'2'        #  0x0032 -> DIGIT TWO
+    u'3'        #  0x0033 -> DIGIT THREE
+    u'4'        #  0x0034 -> DIGIT FOUR
+    u'5'        #  0x0035 -> DIGIT FIVE
+    u'6'        #  0x0036 -> DIGIT SIX
+    u'7'        #  0x0037 -> DIGIT SEVEN
+    u'8'        #  0x0038 -> DIGIT EIGHT
+    u'9'        #  0x0039 -> DIGIT NINE
+    u':'        #  0x003a -> COLON
+    u';'        #  0x003b -> SEMICOLON
+    u'<'        #  0x003c -> LESS-THAN SIGN
+    u'='        #  0x003d -> EQUALS SIGN
+    u'>'        #  0x003e -> GREATER-THAN SIGN
+    u'?'        #  0x003f -> QUESTION MARK
+    u'@'        #  0x0040 -> COMMERCIAL AT
+    u'A'        #  0x0041 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x0042 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x0043 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x0044 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x0045 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x0046 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x0047 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x0048 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x0049 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x004a -> LATIN CAPITAL LETTER J
+    u'K'        #  0x004b -> LATIN CAPITAL LETTER K
+    u'L'        #  0x004c -> LATIN CAPITAL LETTER L
+    u'M'        #  0x004d -> LATIN CAPITAL LETTER M
+    u'N'        #  0x004e -> LATIN CAPITAL LETTER N
+    u'O'        #  0x004f -> LATIN CAPITAL LETTER O
+    u'P'        #  0x0050 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x0051 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x0052 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x0053 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x0054 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x0055 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x0056 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x0057 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x0058 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x0059 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x005a -> LATIN CAPITAL LETTER Z
+    u'['        #  0x005b -> LEFT SQUARE BRACKET
+    u'\\'       #  0x005c -> REVERSE SOLIDUS
+    u']'        #  0x005d -> RIGHT SQUARE BRACKET
+    u'^'        #  0x005e -> CIRCUMFLEX ACCENT
+    u'_'        #  0x005f -> LOW LINE
+    u'`'        #  0x0060 -> GRAVE ACCENT
+    u'a'        #  0x0061 -> LATIN SMALL LETTER A
+    u'b'        #  0x0062 -> LATIN SMALL LETTER B
+    u'c'        #  0x0063 -> LATIN SMALL LETTER C
+    u'd'        #  0x0064 -> LATIN SMALL LETTER D
+    u'e'        #  0x0065 -> LATIN SMALL LETTER E
+    u'f'        #  0x0066 -> LATIN SMALL LETTER F
+    u'g'        #  0x0067 -> LATIN SMALL LETTER G
+    u'h'        #  0x0068 -> LATIN SMALL LETTER H
+    u'i'        #  0x0069 -> LATIN SMALL LETTER I
+    u'j'        #  0x006a -> LATIN SMALL LETTER J
+    u'k'        #  0x006b -> LATIN SMALL LETTER K
+    u'l'        #  0x006c -> LATIN SMALL LETTER L
+    u'm'        #  0x006d -> LATIN SMALL LETTER M
+    u'n'        #  0x006e -> LATIN SMALL LETTER N
+    u'o'        #  0x006f -> LATIN SMALL LETTER O
+    u'p'        #  0x0070 -> LATIN SMALL LETTER P
+    u'q'        #  0x0071 -> LATIN SMALL LETTER Q
+    u'r'        #  0x0072 -> LATIN SMALL LETTER R
+    u's'        #  0x0073 -> LATIN SMALL LETTER S
+    u't'        #  0x0074 -> LATIN SMALL LETTER T
+    u'u'        #  0x0075 -> LATIN SMALL LETTER U
+    u'v'        #  0x0076 -> LATIN SMALL LETTER V
+    u'w'        #  0x0077 -> LATIN SMALL LETTER W
+    u'x'        #  0x0078 -> LATIN SMALL LETTER X
+    u'y'        #  0x0079 -> LATIN SMALL LETTER Y
+    u'z'        #  0x007a -> LATIN SMALL LETTER Z
+    u'{'        #  0x007b -> LEFT CURLY BRACKET
+    u'|'        #  0x007c -> VERTICAL LINE
+    u'}'        #  0x007d -> RIGHT CURLY BRACKET
+    u'~'        #  0x007e -> TILDE
+    u'\x7f'     #  0x007f -> DELETE
+    u'\xc7'     #  0x0080 -> LATIN CAPITAL LETTER C WITH CEDILLA
+    u'\xfc'     #  0x0081 -> LATIN SMALL LETTER U WITH DIAERESIS
+    u'\xe9'     #  0x0082 -> LATIN SMALL LETTER E WITH ACUTE
+    u'\xe2'     #  0x0083 -> LATIN SMALL LETTER A WITH CIRCUMFLEX
+    u'\xe4'     #  0x0084 -> LATIN SMALL LETTER A WITH DIAERESIS
+    u'\xe0'     #  0x0085 -> LATIN SMALL LETTER A WITH GRAVE
+    u'\xe5'     #  0x0086 -> LATIN SMALL LETTER A WITH RING ABOVE
+    u'\xe7'     #  0x0087 -> LATIN SMALL LETTER C WITH CEDILLA
+    u'\xea'     #  0x0088 -> LATIN SMALL LETTER E WITH CIRCUMFLEX
+    u'\xeb'     #  0x0089 -> LATIN SMALL LETTER E WITH DIAERESIS
+    u'\xe8'     #  0x008a -> LATIN SMALL LETTER E WITH GRAVE
+    u'\xef'     #  0x008b -> LATIN SMALL LETTER I WITH DIAERESIS
+    u'\xee'     #  0x008c -> LATIN SMALL LETTER I WITH CIRCUMFLEX
+    u'\xec'     #  0x008d -> LATIN SMALL LETTER I WITH GRAVE
+    u'\xc4'     #  0x008e -> LATIN CAPITAL LETTER A WITH DIAERESIS
+    u'\xc5'     #  0x008f -> LATIN CAPITAL LETTER A WITH RING ABOVE
+    u'\xc9'     #  0x0090 -> LATIN CAPITAL LETTER E WITH ACUTE
+    u'\xe6'     #  0x0091 -> LATIN SMALL LIGATURE AE
+    u'\xc6'     #  0x0092 -> LATIN CAPITAL LIGATURE AE
+    u'\xf4'     #  0x0093 -> LATIN SMALL LETTER O WITH CIRCUMFLEX
+    u'\xf6'     #  0x0094 -> LATIN SMALL LETTER O WITH DIAERESIS
+    u'\xf2'     #  0x0095 -> LATIN SMALL LETTER O WITH GRAVE
+    u'\xfb'     #  0x0096 -> LATIN SMALL LETTER U WITH CIRCUMFLEX
+    u'\xf9'     #  0x0097 -> LATIN SMALL LETTER U WITH GRAVE
+    u'\xff'     #  0x0098 -> LATIN SMALL LETTER Y WITH DIAERESIS
+    u'\xd6'     #  0x0099 -> LATIN CAPITAL LETTER O WITH DIAERESIS
+    u'\xdc'     #  0x009a -> LATIN CAPITAL LETTER U WITH DIAERESIS
+    u'\xf8'     #  0x009b -> LATIN SMALL LETTER O WITH STROKE
+    u'\xa3'     #  0x009c -> POUND SIGN
+    u'\xd8'     #  0x009d -> LATIN CAPITAL LETTER O WITH STROKE
+    u'\u20a7'   #  0x009e -> PESETA SIGN
+    u'\u0192'   #  0x009f -> LATIN SMALL LETTER F WITH HOOK
+    u'\xe1'     #  0x00a0 -> LATIN SMALL LETTER A WITH ACUTE
+    u'\xed'     #  0x00a1 -> LATIN SMALL LETTER I WITH ACUTE
+    u'\xf3'     #  0x00a2 -> LATIN SMALL LETTER O WITH ACUTE
+    u'\xfa'     #  0x00a3 -> LATIN SMALL LETTER U WITH ACUTE
+    u'\xf1'     #  0x00a4 -> LATIN SMALL LETTER N WITH TILDE
+    u'\xd1'     #  0x00a5 -> LATIN CAPITAL LETTER N WITH TILDE
+    u'\xaa'     #  0x00a6 -> FEMININE ORDINAL INDICATOR
+    u'\xba'     #  0x00a7 -> MASCULINE ORDINAL INDICATOR
+    u'\xbf'     #  0x00a8 -> INVERTED QUESTION MARK
+    u'\u2310'   #  0x00a9 -> REVERSED NOT SIGN
+    u'\xac'     #  0x00aa -> NOT SIGN
+    u'\xbd'     #  0x00ab -> VULGAR FRACTION ONE HALF
+    u'\xbc'     #  0x00ac -> VULGAR FRACTION ONE QUARTER
+    u'\xa1'     #  0x00ad -> INVERTED EXCLAMATION MARK
+    u'\xab'     #  0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xa4'     #  0x00af -> CURRENCY SIGN
+    u'\u2591'   #  0x00b0 -> LIGHT SHADE
+    u'\u2592'   #  0x00b1 -> MEDIUM SHADE
+    u'\u2593'   #  0x00b2 -> DARK SHADE
+    u'\u2502'   #  0x00b3 -> BOX DRAWINGS LIGHT VERTICAL
+    u'\u2524'   #  0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT
+    u'\u2561'   #  0x00b5 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+    u'\u2562'   #  0x00b6 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
+    u'\u2556'   #  0x00b7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
+    u'\u2555'   #  0x00b8 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
+    u'\u2563'   #  0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+    u'\u2551'   #  0x00ba -> BOX DRAWINGS DOUBLE VERTICAL
+    u'\u2557'   #  0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT
+    u'\u255d'   #  0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT
+    u'\u255c'   #  0x00bd -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
+    u'\u255b'   #  0x00be -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+    u'\u2510'   #  0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT
+    u'\u2514'   #  0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT
+    u'\u2534'   #  0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL
+    u'\u252c'   #  0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+    u'\u251c'   #  0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+    u'\u2500'   #  0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL
+    u'\u253c'   #  0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+    u'\u255e'   #  0x00c6 -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+    u'\u255f'   #  0x00c7 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+    u'\u255a'   #  0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT
+    u'\u2554'   #  0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT
+    u'\u2569'   #  0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+    u'\u2566'   #  0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+    u'\u2560'   #  0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+    u'\u2550'   #  0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL
+    u'\u256c'   #  0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+    u'\u2567'   #  0x00cf -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+    u'\u2568'   #  0x00d0 -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+    u'\u2564'   #  0x00d1 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
+    u'\u2565'   #  0x00d2 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
+    u'\u2559'   #  0x00d3 -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+    u'\u2558'   #  0x00d4 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+    u'\u2552'   #  0x00d5 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+    u'\u2553'   #  0x00d6 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
+    u'\u256b'   #  0x00d7 -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
+    u'\u256a'   #  0x00d8 -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+    u'\u2518'   #  0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT
+    u'\u250c'   #  0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT
+    u'\u2588'   #  0x00db -> FULL BLOCK
+    u'\u2584'   #  0x00dc -> LOWER HALF BLOCK
+    u'\u258c'   #  0x00dd -> LEFT HALF BLOCK
+    u'\u2590'   #  0x00de -> RIGHT HALF BLOCK
+    u'\u2580'   #  0x00df -> UPPER HALF BLOCK
+    u'\u03b1'   #  0x00e0 -> GREEK SMALL LETTER ALPHA
+    u'\xdf'     #  0x00e1 -> LATIN SMALL LETTER SHARP S
+    u'\u0393'   #  0x00e2 -> GREEK CAPITAL LETTER GAMMA
+    u'\u03c0'   #  0x00e3 -> GREEK SMALL LETTER PI
+    u'\u03a3'   #  0x00e4 -> GREEK CAPITAL LETTER SIGMA
+    u'\u03c3'   #  0x00e5 -> GREEK SMALL LETTER SIGMA
+    u'\xb5'     #  0x00e6 -> MICRO SIGN
+    u'\u03c4'   #  0x00e7 -> GREEK SMALL LETTER TAU
+    u'\u03a6'   #  0x00e8 -> GREEK CAPITAL LETTER PHI
+    u'\u0398'   #  0x00e9 -> GREEK CAPITAL LETTER THETA
+    u'\u03a9'   #  0x00ea -> GREEK CAPITAL LETTER OMEGA
+    u'\u03b4'   #  0x00eb -> GREEK SMALL LETTER DELTA
+    u'\u221e'   #  0x00ec -> INFINITY
+    u'\u03c6'   #  0x00ed -> GREEK SMALL LETTER PHI
+    u'\u03b5'   #  0x00ee -> GREEK SMALL LETTER EPSILON
+    u'\u2229'   #  0x00ef -> INTERSECTION
+    u'\u2261'   #  0x00f0 -> IDENTICAL TO
+    u'\xb1'     #  0x00f1 -> PLUS-MINUS SIGN
+    u'\u2265'   #  0x00f2 -> GREATER-THAN OR EQUAL TO
+    u'\u2264'   #  0x00f3 -> LESS-THAN OR EQUAL TO
+    u'\u2320'   #  0x00f4 -> TOP HALF INTEGRAL
+    u'\u2321'   #  0x00f5 -> BOTTOM HALF INTEGRAL
+    u'\xf7'     #  0x00f6 -> DIVISION SIGN
+    u'\u2248'   #  0x00f7 -> ALMOST EQUAL TO
+    u'\xb0'     #  0x00f8 -> DEGREE SIGN
+    u'\u2219'   #  0x00f9 -> BULLET OPERATOR
+    u'\xb7'     #  0x00fa -> MIDDLE DOT
+    u'\u221a'   #  0x00fb -> SQUARE ROOT
+    u'\u207f'   #  0x00fc -> SUPERSCRIPT LATIN SMALL LETTER N
+    u'\xb2'     #  0x00fd -> SUPERSCRIPT TWO
+    u'\u25a0'   #  0x00fe -> BLACK SQUARE
+    u'\xa0'     #  0x00ff -> NO-BREAK SPACE
+)
+
+### Encoding Map
+
+encoding_map = {
+    0x0000: 0x0000,     #  NULL
+    0x0001: 0x0001,     #  START OF HEADING
+    0x0002: 0x0002,     #  START OF TEXT
+    0x0003: 0x0003,     #  END OF TEXT
+    0x0004: 0x0004,     #  END OF TRANSMISSION
+    0x0005: 0x0005,     #  ENQUIRY
+    0x0006: 0x0006,     #  ACKNOWLEDGE
+    0x0007: 0x0007,     #  BELL
+    0x0008: 0x0008,     #  BACKSPACE
+    0x0009: 0x0009,     #  HORIZONTAL TABULATION
+    0x000a: 0x000a,     #  LINE FEED
+    0x000b: 0x000b,     #  VERTICAL TABULATION
+    0x000c: 0x000c,     #  FORM FEED
+    0x000d: 0x000d,     #  CARRIAGE RETURN
+    0x000e: 0x000e,     #  SHIFT OUT
+    0x000f: 0x000f,     #  SHIFT IN
+    0x0010: 0x0010,     #  DATA LINK ESCAPE
+    0x0011: 0x0011,     #  DEVICE CONTROL ONE
+    0x0012: 0x0012,     #  DEVICE CONTROL TWO
+    0x0013: 0x0013,     #  DEVICE CONTROL THREE
+    0x0014: 0x0014,     #  DEVICE CONTROL FOUR
+    0x0015: 0x0015,     #  NEGATIVE ACKNOWLEDGE
+    0x0016: 0x0016,     #  SYNCHRONOUS IDLE
+    0x0017: 0x0017,     #  END OF TRANSMISSION BLOCK
+    0x0018: 0x0018,     #  CANCEL
+    0x0019: 0x0019,     #  END OF MEDIUM
+    0x001a: 0x001a,     #  SUBSTITUTE
+    0x001b: 0x001b,     #  ESCAPE
+    0x001c: 0x001c,     #  FILE SEPARATOR
+    0x001d: 0x001d,     #  GROUP SEPARATOR
+    0x001e: 0x001e,     #  RECORD SEPARATOR
+    0x001f: 0x001f,     #  UNIT SEPARATOR
+    0x0020: 0x0020,     #  SPACE
+    0x0021: 0x0021,     #  EXCLAMATION MARK
+    0x0022: 0x0022,     #  QUOTATION MARK
+    0x0023: 0x0023,     #  NUMBER SIGN
+    0x0024: 0x0024,     #  DOLLAR SIGN
+    0x0025: 0x0025,     #  PERCENT SIGN
+    0x0026: 0x0026,     #  AMPERSAND
+    0x0027: 0x0027,     #  APOSTROPHE
+    0x0028: 0x0028,     #  LEFT PARENTHESIS
+    0x0029: 0x0029,     #  RIGHT PARENTHESIS
+    0x002a: 0x002a,     #  ASTERISK
+    0x002b: 0x002b,     #  PLUS SIGN
+    0x002c: 0x002c,     #  COMMA
+    0x002d: 0x002d,     #  HYPHEN-MINUS
+    0x002e: 0x002e,     #  FULL STOP
+    0x002f: 0x002f,     #  SOLIDUS
+    0x0030: 0x0030,     #  DIGIT ZERO
+    0x0031: 0x0031,     #  DIGIT ONE
+    0x0032: 0x0032,     #  DIGIT TWO
+    0x0033: 0x0033,     #  DIGIT THREE
+    0x0034: 0x0034,     #  DIGIT FOUR
+    0x0035: 0x0035,     #  DIGIT FIVE
+    0x0036: 0x0036,     #  DIGIT SIX
+    0x0037: 0x0037,     #  DIGIT SEVEN
+    0x0038: 0x0038,     #  DIGIT EIGHT
+    0x0039: 0x0039,     #  DIGIT NINE
+    0x003a: 0x003a,     #  COLON
+    0x003b: 0x003b,     #  SEMICOLON
+    0x003c: 0x003c,     #  LESS-THAN SIGN
+    0x003d: 0x003d,     #  EQUALS SIGN
+    0x003e: 0x003e,     #  GREATER-THAN SIGN
+    0x003f: 0x003f,     #  QUESTION MARK
+    0x0040: 0x0040,     #  COMMERCIAL AT
+    0x0041: 0x0041,     #  LATIN CAPITAL LETTER A
+    0x0042: 0x0042,     #  LATIN CAPITAL LETTER B
+    0x0043: 0x0043,     #  LATIN CAPITAL LETTER C
+    0x0044: 0x0044,     #  LATIN CAPITAL LETTER D
+    0x0045: 0x0045,     #  LATIN CAPITAL LETTER E
+    0x0046: 0x0046,     #  LATIN CAPITAL LETTER F
+    0x0047: 0x0047,     #  LATIN CAPITAL LETTER G
+    0x0048: 0x0048,     #  LATIN CAPITAL LETTER H
+    0x0049: 0x0049,     #  LATIN CAPITAL LETTER I
+    0x004a: 0x004a,     #  LATIN CAPITAL LETTER J
+    0x004b: 0x004b,     #  LATIN CAPITAL LETTER K
+    0x004c: 0x004c,     #  LATIN CAPITAL LETTER L
+    0x004d: 0x004d,     #  LATIN CAPITAL LETTER M
+    0x004e: 0x004e,     #  LATIN CAPITAL LETTER N
+    0x004f: 0x004f,     #  LATIN CAPITAL LETTER O
+    0x0050: 0x0050,     #  LATIN CAPITAL LETTER P
+    0x0051: 0x0051,     #  LATIN CAPITAL LETTER Q
+    0x0052: 0x0052,     #  LATIN CAPITAL LETTER R
+    0x0053: 0x0053,     #  LATIN CAPITAL LETTER S
+    0x0054: 0x0054,     #  LATIN CAPITAL LETTER T
+    0x0055: 0x0055,     #  LATIN CAPITAL LETTER U
+    0x0056: 0x0056,     #  LATIN CAPITAL LETTER V
+    0x0057: 0x0057,     #  LATIN CAPITAL LETTER W
+    0x0058: 0x0058,     #  LATIN CAPITAL LETTER X
+    0x0059: 0x0059,     #  LATIN CAPITAL LETTER Y
+    0x005a: 0x005a,     #  LATIN CAPITAL LETTER Z
+    0x005b: 0x005b,     #  LEFT SQUARE BRACKET
+    0x005c: 0x005c,     #  REVERSE SOLIDUS
+    0x005d: 0x005d,     #  RIGHT SQUARE BRACKET
+    0x005e: 0x005e,     #  CIRCUMFLEX ACCENT
+    0x005f: 0x005f,     #  LOW LINE
+    0x0060: 0x0060,     #  GRAVE ACCENT
+    0x0061: 0x0061,     #  LATIN SMALL LETTER A
+    0x0062: 0x0062,     #  LATIN SMALL LETTER B
+    0x0063: 0x0063,     #  LATIN SMALL LETTER C
+    0x0064: 0x0064,     #  LATIN SMALL LETTER D
+    0x0065: 0x0065,     #  LATIN SMALL LETTER E
+    0x0066: 0x0066,     #  LATIN SMALL LETTER F
+    0x0067: 0x0067,     #  LATIN SMALL LETTER G
+    0x0068: 0x0068,     #  LATIN SMALL LETTER H
+    0x0069: 0x0069,     #  LATIN SMALL LETTER I
+    0x006a: 0x006a,     #  LATIN SMALL LETTER J
+    0x006b: 0x006b,     #  LATIN SMALL LETTER K
+    0x006c: 0x006c,     #  LATIN SMALL LETTER L
+    0x006d: 0x006d,     #  LATIN SMALL LETTER M
+    0x006e: 0x006e,     #  LATIN SMALL LETTER N
+    0x006f: 0x006f,     #  LATIN SMALL LETTER O
+    0x0070: 0x0070,     #  LATIN SMALL LETTER P
+    0x0071: 0x0071,     #  LATIN SMALL LETTER Q
+    0x0072: 0x0072,     #  LATIN SMALL LETTER R
+    0x0073: 0x0073,     #  LATIN SMALL LETTER S
+    0x0074: 0x0074,     #  LATIN SMALL LETTER T
+    0x0075: 0x0075,     #  LATIN SMALL LETTER U
+    0x0076: 0x0076,     #  LATIN SMALL LETTER V
+    0x0077: 0x0077,     #  LATIN SMALL LETTER W
+    0x0078: 0x0078,     #  LATIN SMALL LETTER X
+    0x0079: 0x0079,     #  LATIN SMALL LETTER Y
+    0x007a: 0x007a,     #  LATIN SMALL LETTER Z
+    0x007b: 0x007b,     #  LEFT CURLY BRACKET
+    0x007c: 0x007c,     #  VERTICAL LINE
+    0x007d: 0x007d,     #  RIGHT CURLY BRACKET
+    0x007e: 0x007e,     #  TILDE
+    0x007f: 0x007f,     #  DELETE
+    0x00a0: 0x00ff,     #  NO-BREAK SPACE
+    0x00a1: 0x00ad,     #  INVERTED EXCLAMATION MARK
+    0x00a3: 0x009c,     #  POUND SIGN
+    0x00a4: 0x00af,     #  CURRENCY SIGN
+    0x00aa: 0x00a6,     #  FEMININE ORDINAL INDICATOR
+    0x00ab: 0x00ae,     #  LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    0x00ac: 0x00aa,     #  NOT SIGN
+    0x00b0: 0x00f8,     #  DEGREE SIGN
+    0x00b1: 0x00f1,     #  PLUS-MINUS SIGN
+    0x00b2: 0x00fd,     #  SUPERSCRIPT TWO
+    0x00b5: 0x00e6,     #  MICRO SIGN
+    0x00b7: 0x00fa,     #  MIDDLE DOT
+    0x00ba: 0x00a7,     #  MASCULINE ORDINAL INDICATOR
+    0x00bc: 0x00ac,     #  VULGAR FRACTION ONE QUARTER
+    0x00bd: 0x00ab,     #  VULGAR FRACTION ONE HALF
+    0x00bf: 0x00a8,     #  INVERTED QUESTION MARK
+    0x00c4: 0x008e,     #  LATIN CAPITAL LETTER A WITH DIAERESIS
+    0x00c5: 0x008f,     #  LATIN CAPITAL LETTER A WITH RING ABOVE
+    0x00c6: 0x0092,     #  LATIN CAPITAL LIGATURE AE
+    0x00c7: 0x0080,     #  LATIN CAPITAL LETTER C WITH CEDILLA
+    0x00c9: 0x0090,     #  LATIN CAPITAL LETTER E WITH ACUTE
+    0x00d1: 0x00a5,     #  LATIN CAPITAL LETTER N WITH TILDE
+    0x00d6: 0x0099,     #  LATIN CAPITAL LETTER O WITH DIAERESIS
+    0x00d8: 0x009d,     #  LATIN CAPITAL LETTER O WITH STROKE
+    0x00dc: 0x009a,     #  LATIN CAPITAL LETTER U WITH DIAERESIS
+    0x00df: 0x00e1,     #  LATIN SMALL LETTER SHARP S
+    0x00e0: 0x0085,     #  LATIN SMALL LETTER A WITH GRAVE
+    0x00e1: 0x00a0,     #  LATIN SMALL LETTER A WITH ACUTE
+    0x00e2: 0x0083,     #  LATIN SMALL LETTER A WITH CIRCUMFLEX
+    0x00e4: 0x0084,     #  LATIN SMALL LETTER A WITH DIAERESIS
+    0x00e5: 0x0086,     #  LATIN SMALL LETTER A WITH RING ABOVE
+    0x00e6: 0x0091,     #  LATIN SMALL LIGATURE AE
+    0x00e7: 0x0087,     #  LATIN SMALL LETTER C WITH CEDILLA
+    0x00e8: 0x008a,     #  LATIN SMALL LETTER E WITH GRAVE
+    0x00e9: 0x0082,     #  LATIN SMALL LETTER E WITH ACUTE
+    0x00ea: 0x0088,     #  LATIN SMALL LETTER E WITH CIRCUMFLEX
+    0x00eb: 0x0089,     #  LATIN SMALL LETTER E WITH DIAERESIS
+    0x00ec: 0x008d,     #  LATIN SMALL LETTER I WITH GRAVE
+    0x00ed: 0x00a1,     #  LATIN SMALL LETTER I WITH ACUTE
+    0x00ee: 0x008c,     #  LATIN SMALL LETTER I WITH CIRCUMFLEX
+    0x00ef: 0x008b,     #  LATIN SMALL LETTER I WITH DIAERESIS
+    0x00f1: 0x00a4,     #  LATIN SMALL LETTER N WITH TILDE
+    0x00f2: 0x0095,     #  LATIN SMALL LETTER O WITH GRAVE
+    0x00f3: 0x00a2,     #  LATIN SMALL LETTER O WITH ACUTE
+    0x00f4: 0x0093,     #  LATIN SMALL LETTER O WITH CIRCUMFLEX
+    0x00f6: 0x0094,     #  LATIN SMALL LETTER O WITH DIAERESIS
+    0x00f7: 0x00f6,     #  DIVISION SIGN
+    0x00f8: 0x009b,     #  LATIN SMALL LETTER O WITH STROKE
+    0x00f9: 0x0097,     #  LATIN SMALL LETTER U WITH GRAVE
+    0x00fa: 0x00a3,     #  LATIN SMALL LETTER U WITH ACUTE
+    0x00fb: 0x0096,     #  LATIN SMALL LETTER U WITH CIRCUMFLEX
+    0x00fc: 0x0081,     #  LATIN SMALL LETTER U WITH DIAERESIS
+    0x00ff: 0x0098,     #  LATIN SMALL LETTER Y WITH DIAERESIS
+    0x0192: 0x009f,     #  LATIN SMALL LETTER F WITH HOOK
+    0x0393: 0x00e2,     #  GREEK CAPITAL LETTER GAMMA
+    0x0398: 0x00e9,     #  GREEK CAPITAL LETTER THETA
+    0x03a3: 0x00e4,     #  GREEK CAPITAL LETTER SIGMA
+    0x03a6: 0x00e8,     #  GREEK CAPITAL LETTER PHI
+    0x03a9: 0x00ea,     #  GREEK CAPITAL LETTER OMEGA
+    0x03b1: 0x00e0,     #  GREEK SMALL LETTER ALPHA
+    0x03b4: 0x00eb,     #  GREEK SMALL LETTER DELTA
+    0x03b5: 0x00ee,     #  GREEK SMALL LETTER EPSILON
+    0x03c0: 0x00e3,     #  GREEK SMALL LETTER PI
+    0x03c3: 0x00e5,     #  GREEK SMALL LETTER SIGMA
+    0x03c4: 0x00e7,     #  GREEK SMALL LETTER TAU
+    0x03c6: 0x00ed,     #  GREEK SMALL LETTER PHI
+    0x207f: 0x00fc,     #  SUPERSCRIPT LATIN SMALL LETTER N
+    0x20a7: 0x009e,     #  PESETA SIGN
+    0x2219: 0x00f9,     #  BULLET OPERATOR
+    0x221a: 0x00fb,     #  SQUARE ROOT
+    0x221e: 0x00ec,     #  INFINITY
+    0x2229: 0x00ef,     #  INTERSECTION
+    0x2248: 0x00f7,     #  ALMOST EQUAL TO
+    0x2261: 0x00f0,     #  IDENTICAL TO
+    0x2264: 0x00f3,     #  LESS-THAN OR EQUAL TO
+    0x2265: 0x00f2,     #  GREATER-THAN OR EQUAL TO
+    0x2310: 0x00a9,     #  REVERSED NOT SIGN
+    0x2320: 0x00f4,     #  TOP HALF INTEGRAL
+    0x2321: 0x00f5,     #  BOTTOM HALF INTEGRAL
+    0x2500: 0x00c4,     #  BOX DRAWINGS LIGHT HORIZONTAL
+    0x2502: 0x00b3,     #  BOX DRAWINGS LIGHT VERTICAL
+    0x250c: 0x00da,     #  BOX DRAWINGS LIGHT DOWN AND RIGHT
+    0x2510: 0x00bf,     #  BOX DRAWINGS LIGHT DOWN AND LEFT
+    0x2514: 0x00c0,     #  BOX DRAWINGS LIGHT UP AND RIGHT
+    0x2518: 0x00d9,     #  BOX DRAWINGS LIGHT UP AND LEFT
+    0x251c: 0x00c3,     #  BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+    0x2524: 0x00b4,     #  BOX DRAWINGS LIGHT VERTICAL AND LEFT
+    0x252c: 0x00c2,     #  BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+    0x2534: 0x00c1,     #  BOX DRAWINGS LIGHT UP AND HORIZONTAL
+    0x253c: 0x00c5,     #  BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+    0x2550: 0x00cd,     #  BOX DRAWINGS DOUBLE HORIZONTAL
+    0x2551: 0x00ba,     #  BOX DRAWINGS DOUBLE VERTICAL
+    0x2552: 0x00d5,     #  BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+    0x2553: 0x00d6,     #  BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
+    0x2554: 0x00c9,     #  BOX DRAWINGS DOUBLE DOWN AND RIGHT
+    0x2555: 0x00b8,     #  BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
+    0x2556: 0x00b7,     #  BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
+    0x2557: 0x00bb,     #  BOX DRAWINGS DOUBLE DOWN AND LEFT
+    0x2558: 0x00d4,     #  BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+    0x2559: 0x00d3,     #  BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+    0x255a: 0x00c8,     #  BOX DRAWINGS DOUBLE UP AND RIGHT
+    0x255b: 0x00be,     #  BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+    0x255c: 0x00bd,     #  BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
+    0x255d: 0x00bc,     #  BOX DRAWINGS DOUBLE UP AND LEFT
+    0x255e: 0x00c6,     #  BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+    0x255f: 0x00c7,     #  BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+    0x2560: 0x00cc,     #  BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+    0x2561: 0x00b5,     #  BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+    0x2562: 0x00b6,     #  BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
+    0x2563: 0x00b9,     #  BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+    0x2564: 0x00d1,     #  BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
+    0x2565: 0x00d2,     #  BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
+    0x2566: 0x00cb,     #  BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+    0x2567: 0x00cf,     #  BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+    0x2568: 0x00d0,     #  BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+    0x2569: 0x00ca,     #  BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+    0x256a: 0x00d8,     #  BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+    0x256b: 0x00d7,     #  BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
+    0x256c: 0x00ce,     #  BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+    0x2580: 0x00df,     #  UPPER HALF BLOCK
+    0x2584: 0x00dc,     #  LOWER HALF BLOCK
+    0x2588: 0x00db,     #  FULL BLOCK
+    0x258c: 0x00dd,     #  LEFT HALF BLOCK
+    0x2590: 0x00de,     #  RIGHT HALF BLOCK
+    0x2591: 0x00b0,     #  LIGHT SHADE
+    0x2592: 0x00b1,     #  MEDIUM SHADE
+    0x2593: 0x00b2,     #  DARK SHADE
+    0x25a0: 0x00fe,     #  BLACK SQUARE
+}

Added: vendor/Python/current/Lib/encodings/cp866.py
===================================================================
--- vendor/Python/current/Lib/encodings/cp866.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/cp866.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,698 @@
+""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP866.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_map)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='cp866',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+### Decoding Map
+
+decoding_map = codecs.make_identity_dict(range(256))
+decoding_map.update({
+    0x0080: 0x0410,     #  CYRILLIC CAPITAL LETTER A
+    0x0081: 0x0411,     #  CYRILLIC CAPITAL LETTER BE
+    0x0082: 0x0412,     #  CYRILLIC CAPITAL LETTER VE
+    0x0083: 0x0413,     #  CYRILLIC CAPITAL LETTER GHE
+    0x0084: 0x0414,     #  CYRILLIC CAPITAL LETTER DE
+    0x0085: 0x0415,     #  CYRILLIC CAPITAL LETTER IE
+    0x0086: 0x0416,     #  CYRILLIC CAPITAL LETTER ZHE
+    0x0087: 0x0417,     #  CYRILLIC CAPITAL LETTER ZE
+    0x0088: 0x0418,     #  CYRILLIC CAPITAL LETTER I
+    0x0089: 0x0419,     #  CYRILLIC CAPITAL LETTER SHORT I
+    0x008a: 0x041a,     #  CYRILLIC CAPITAL LETTER KA
+    0x008b: 0x041b,     #  CYRILLIC CAPITAL LETTER EL
+    0x008c: 0x041c,     #  CYRILLIC CAPITAL LETTER EM
+    0x008d: 0x041d,     #  CYRILLIC CAPITAL LETTER EN
+    0x008e: 0x041e,     #  CYRILLIC CAPITAL LETTER O
+    0x008f: 0x041f,     #  CYRILLIC CAPITAL LETTER PE
+    0x0090: 0x0420,     #  CYRILLIC CAPITAL LETTER ER
+    0x0091: 0x0421,     #  CYRILLIC CAPITAL LETTER ES
+    0x0092: 0x0422,     #  CYRILLIC CAPITAL LETTER TE
+    0x0093: 0x0423,     #  CYRILLIC CAPITAL LETTER U
+    0x0094: 0x0424,     #  CYRILLIC CAPITAL LETTER EF
+    0x0095: 0x0425,     #  CYRILLIC CAPITAL LETTER HA
+    0x0096: 0x0426,     #  CYRILLIC CAPITAL LETTER TSE
+    0x0097: 0x0427,     #  CYRILLIC CAPITAL LETTER CHE
+    0x0098: 0x0428,     #  CYRILLIC CAPITAL LETTER SHA
+    0x0099: 0x0429,     #  CYRILLIC CAPITAL LETTER SHCHA
+    0x009a: 0x042a,     #  CYRILLIC CAPITAL LETTER HARD SIGN
+    0x009b: 0x042b,     #  CYRILLIC CAPITAL LETTER YERU
+    0x009c: 0x042c,     #  CYRILLIC CAPITAL LETTER SOFT SIGN
+    0x009d: 0x042d,     #  CYRILLIC CAPITAL LETTER E
+    0x009e: 0x042e,     #  CYRILLIC CAPITAL LETTER YU
+    0x009f: 0x042f,     #  CYRILLIC CAPITAL LETTER YA
+    0x00a0: 0x0430,     #  CYRILLIC SMALL LETTER A
+    0x00a1: 0x0431,     #  CYRILLIC SMALL LETTER BE
+    0x00a2: 0x0432,     #  CYRILLIC SMALL LETTER VE
+    0x00a3: 0x0433,     #  CYRILLIC SMALL LETTER GHE
+    0x00a4: 0x0434,     #  CYRILLIC SMALL LETTER DE
+    0x00a5: 0x0435,     #  CYRILLIC SMALL LETTER IE
+    0x00a6: 0x0436,     #  CYRILLIC SMALL LETTER ZHE
+    0x00a7: 0x0437,     #  CYRILLIC SMALL LETTER ZE
+    0x00a8: 0x0438,     #  CYRILLIC SMALL LETTER I
+    0x00a9: 0x0439,     #  CYRILLIC SMALL LETTER SHORT I
+    0x00aa: 0x043a,     #  CYRILLIC SMALL LETTER KA
+    0x00ab: 0x043b,     #  CYRILLIC SMALL LETTER EL
+    0x00ac: 0x043c,     #  CYRILLIC SMALL LETTER EM
+    0x00ad: 0x043d,     #  CYRILLIC SMALL LETTER EN
+    0x00ae: 0x043e,     #  CYRILLIC SMALL LETTER O
+    0x00af: 0x043f,     #  CYRILLIC SMALL LETTER PE
+    0x00b0: 0x2591,     #  LIGHT SHADE
+    0x00b1: 0x2592,     #  MEDIUM SHADE
+    0x00b2: 0x2593,     #  DARK SHADE
+    0x00b3: 0x2502,     #  BOX DRAWINGS LIGHT VERTICAL
+    0x00b4: 0x2524,     #  BOX DRAWINGS LIGHT VERTICAL AND LEFT
+    0x00b5: 0x2561,     #  BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+    0x00b6: 0x2562,     #  BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
+    0x00b7: 0x2556,     #  BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
+    0x00b8: 0x2555,     #  BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
+    0x00b9: 0x2563,     #  BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+    0x00ba: 0x2551,     #  BOX DRAWINGS DOUBLE VERTICAL
+    0x00bb: 0x2557,     #  BOX DRAWINGS DOUBLE DOWN AND LEFT
+    0x00bc: 0x255d,     #  BOX DRAWINGS DOUBLE UP AND LEFT
+    0x00bd: 0x255c,     #  BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
+    0x00be: 0x255b,     #  BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+    0x00bf: 0x2510,     #  BOX DRAWINGS LIGHT DOWN AND LEFT
+    0x00c0: 0x2514,     #  BOX DRAWINGS LIGHT UP AND RIGHT
+    0x00c1: 0x2534,     #  BOX DRAWINGS LIGHT UP AND HORIZONTAL
+    0x00c2: 0x252c,     #  BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+    0x00c3: 0x251c,     #  BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+    0x00c4: 0x2500,     #  BOX DRAWINGS LIGHT HORIZONTAL
+    0x00c5: 0x253c,     #  BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+    0x00c6: 0x255e,     #  BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+    0x00c7: 0x255f,     #  BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+    0x00c8: 0x255a,     #  BOX DRAWINGS DOUBLE UP AND RIGHT
+    0x00c9: 0x2554,     #  BOX DRAWINGS DOUBLE DOWN AND RIGHT
+    0x00ca: 0x2569,     #  BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+    0x00cb: 0x2566,     #  BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+    0x00cc: 0x2560,     #  BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+    0x00cd: 0x2550,     #  BOX DRAWINGS DOUBLE HORIZONTAL
+    0x00ce: 0x256c,     #  BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+    0x00cf: 0x2567,     #  BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+    0x00d0: 0x2568,     #  BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+    0x00d1: 0x2564,     #  BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
+    0x00d2: 0x2565,     #  BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
+    0x00d3: 0x2559,     #  BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+    0x00d4: 0x2558,     #  BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+    0x00d5: 0x2552,     #  BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+    0x00d6: 0x2553,     #  BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
+    0x00d7: 0x256b,     #  BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
+    0x00d8: 0x256a,     #  BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+    0x00d9: 0x2518,     #  BOX DRAWINGS LIGHT UP AND LEFT
+    0x00da: 0x250c,     #  BOX DRAWINGS LIGHT DOWN AND RIGHT
+    0x00db: 0x2588,     #  FULL BLOCK
+    0x00dc: 0x2584,     #  LOWER HALF BLOCK
+    0x00dd: 0x258c,     #  LEFT HALF BLOCK
+    0x00de: 0x2590,     #  RIGHT HALF BLOCK
+    0x00df: 0x2580,     #  UPPER HALF BLOCK
+    0x00e0: 0x0440,     #  CYRILLIC SMALL LETTER ER
+    0x00e1: 0x0441,     #  CYRILLIC SMALL LETTER ES
+    0x00e2: 0x0442,     #  CYRILLIC SMALL LETTER TE
+    0x00e3: 0x0443,     #  CYRILLIC SMALL LETTER U
+    0x00e4: 0x0444,     #  CYRILLIC SMALL LETTER EF
+    0x00e5: 0x0445,     #  CYRILLIC SMALL LETTER HA
+    0x00e6: 0x0446,     #  CYRILLIC SMALL LETTER TSE
+    0x00e7: 0x0447,     #  CYRILLIC SMALL LETTER CHE
+    0x00e8: 0x0448,     #  CYRILLIC SMALL LETTER SHA
+    0x00e9: 0x0449,     #  CYRILLIC SMALL LETTER SHCHA
+    0x00ea: 0x044a,     #  CYRILLIC SMALL LETTER HARD SIGN
+    0x00eb: 0x044b,     #  CYRILLIC SMALL LETTER YERU
+    0x00ec: 0x044c,     #  CYRILLIC SMALL LETTER SOFT SIGN
+    0x00ed: 0x044d,     #  CYRILLIC SMALL LETTER E
+    0x00ee: 0x044e,     #  CYRILLIC SMALL LETTER YU
+    0x00ef: 0x044f,     #  CYRILLIC SMALL LETTER YA
+    0x00f0: 0x0401,     #  CYRILLIC CAPITAL LETTER IO
+    0x00f1: 0x0451,     #  CYRILLIC SMALL LETTER IO
+    0x00f2: 0x0404,     #  CYRILLIC CAPITAL LETTER UKRAINIAN IE
+    0x00f3: 0x0454,     #  CYRILLIC SMALL LETTER UKRAINIAN IE
+    0x00f4: 0x0407,     #  CYRILLIC CAPITAL LETTER YI
+    0x00f5: 0x0457,     #  CYRILLIC SMALL LETTER YI
+    0x00f6: 0x040e,     #  CYRILLIC CAPITAL LETTER SHORT U
+    0x00f7: 0x045e,     #  CYRILLIC SMALL LETTER SHORT U
+    0x00f8: 0x00b0,     #  DEGREE SIGN
+    0x00f9: 0x2219,     #  BULLET OPERATOR
+    0x00fa: 0x00b7,     #  MIDDLE DOT
+    0x00fb: 0x221a,     #  SQUARE ROOT
+    0x00fc: 0x2116,     #  NUMERO SIGN
+    0x00fd: 0x00a4,     #  CURRENCY SIGN
+    0x00fe: 0x25a0,     #  BLACK SQUARE
+    0x00ff: 0x00a0,     #  NO-BREAK SPACE
+})
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x0000 -> NULL
+    u'\x01'     #  0x0001 -> START OF HEADING
+    u'\x02'     #  0x0002 -> START OF TEXT
+    u'\x03'     #  0x0003 -> END OF TEXT
+    u'\x04'     #  0x0004 -> END OF TRANSMISSION
+    u'\x05'     #  0x0005 -> ENQUIRY
+    u'\x06'     #  0x0006 -> ACKNOWLEDGE
+    u'\x07'     #  0x0007 -> BELL
+    u'\x08'     #  0x0008 -> BACKSPACE
+    u'\t'       #  0x0009 -> HORIZONTAL TABULATION
+    u'\n'       #  0x000a -> LINE FEED
+    u'\x0b'     #  0x000b -> VERTICAL TABULATION
+    u'\x0c'     #  0x000c -> FORM FEED
+    u'\r'       #  0x000d -> CARRIAGE RETURN
+    u'\x0e'     #  0x000e -> SHIFT OUT
+    u'\x0f'     #  0x000f -> SHIFT IN
+    u'\x10'     #  0x0010 -> DATA LINK ESCAPE
+    u'\x11'     #  0x0011 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x0012 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x0013 -> DEVICE CONTROL THREE
+    u'\x14'     #  0x0014 -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x0015 -> NEGATIVE ACKNOWLEDGE
+    u'\x16'     #  0x0016 -> SYNCHRONOUS IDLE
+    u'\x17'     #  0x0017 -> END OF TRANSMISSION BLOCK
+    u'\x18'     #  0x0018 -> CANCEL
+    u'\x19'     #  0x0019 -> END OF MEDIUM
+    u'\x1a'     #  0x001a -> SUBSTITUTE
+    u'\x1b'     #  0x001b -> ESCAPE
+    u'\x1c'     #  0x001c -> FILE SEPARATOR
+    u'\x1d'     #  0x001d -> GROUP SEPARATOR
+    u'\x1e'     #  0x001e -> RECORD SEPARATOR
+    u'\x1f'     #  0x001f -> UNIT SEPARATOR
+    u' '        #  0x0020 -> SPACE
+    u'!'        #  0x0021 -> EXCLAMATION MARK
+    u'"'        #  0x0022 -> QUOTATION MARK
+    u'#'        #  0x0023 -> NUMBER SIGN
+    u'$'        #  0x0024 -> DOLLAR SIGN
+    u'%'        #  0x0025 -> PERCENT SIGN
+    u'&'        #  0x0026 -> AMPERSAND
+    u"'"        #  0x0027 -> APOSTROPHE
+    u'('        #  0x0028 -> LEFT PARENTHESIS
+    u')'        #  0x0029 -> RIGHT PARENTHESIS
+    u'*'        #  0x002a -> ASTERISK
+    u'+'        #  0x002b -> PLUS SIGN
+    u','        #  0x002c -> COMMA
+    u'-'        #  0x002d -> HYPHEN-MINUS
+    u'.'        #  0x002e -> FULL STOP
+    u'/'        #  0x002f -> SOLIDUS
+    u'0'        #  0x0030 -> DIGIT ZERO
+    u'1'        #  0x0031 -> DIGIT ONE
+    u'2'        #  0x0032 -> DIGIT TWO
+    u'3'        #  0x0033 -> DIGIT THREE
+    u'4'        #  0x0034 -> DIGIT FOUR
+    u'5'        #  0x0035 -> DIGIT FIVE
+    u'6'        #  0x0036 -> DIGIT SIX
+    u'7'        #  0x0037 -> DIGIT SEVEN
+    u'8'        #  0x0038 -> DIGIT EIGHT
+    u'9'        #  0x0039 -> DIGIT NINE
+    u':'        #  0x003a -> COLON
+    u';'        #  0x003b -> SEMICOLON
+    u'<'        #  0x003c -> LESS-THAN SIGN
+    u'='        #  0x003d -> EQUALS SIGN
+    u'>'        #  0x003e -> GREATER-THAN SIGN
+    u'?'        #  0x003f -> QUESTION MARK
+    u'@'        #  0x0040 -> COMMERCIAL AT
+    u'A'        #  0x0041 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x0042 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x0043 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x0044 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x0045 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x0046 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x0047 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x0048 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x0049 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x004a -> LATIN CAPITAL LETTER J
+    u'K'        #  0x004b -> LATIN CAPITAL LETTER K
+    u'L'        #  0x004c -> LATIN CAPITAL LETTER L
+    u'M'        #  0x004d -> LATIN CAPITAL LETTER M
+    u'N'        #  0x004e -> LATIN CAPITAL LETTER N
+    u'O'        #  0x004f -> LATIN CAPITAL LETTER O
+    u'P'        #  0x0050 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x0051 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x0052 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x0053 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x0054 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x0055 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x0056 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x0057 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x0058 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x0059 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x005a -> LATIN CAPITAL LETTER Z
+    u'['        #  0x005b -> LEFT SQUARE BRACKET
+    u'\\'       #  0x005c -> REVERSE SOLIDUS
+    u']'        #  0x005d -> RIGHT SQUARE BRACKET
+    u'^'        #  0x005e -> CIRCUMFLEX ACCENT
+    u'_'        #  0x005f -> LOW LINE
+    u'`'        #  0x0060 -> GRAVE ACCENT
+    u'a'        #  0x0061 -> LATIN SMALL LETTER A
+    u'b'        #  0x0062 -> LATIN SMALL LETTER B
+    u'c'        #  0x0063 -> LATIN SMALL LETTER C
+    u'd'        #  0x0064 -> LATIN SMALL LETTER D
+    u'e'        #  0x0065 -> LATIN SMALL LETTER E
+    u'f'        #  0x0066 -> LATIN SMALL LETTER F
+    u'g'        #  0x0067 -> LATIN SMALL LETTER G
+    u'h'        #  0x0068 -> LATIN SMALL LETTER H
+    u'i'        #  0x0069 -> LATIN SMALL LETTER I
+    u'j'        #  0x006a -> LATIN SMALL LETTER J
+    u'k'        #  0x006b -> LATIN SMALL LETTER K
+    u'l'        #  0x006c -> LATIN SMALL LETTER L
+    u'm'        #  0x006d -> LATIN SMALL LETTER M
+    u'n'        #  0x006e -> LATIN SMALL LETTER N
+    u'o'        #  0x006f -> LATIN SMALL LETTER O
+    u'p'        #  0x0070 -> LATIN SMALL LETTER P
+    u'q'        #  0x0071 -> LATIN SMALL LETTER Q
+    u'r'        #  0x0072 -> LATIN SMALL LETTER R
+    u's'        #  0x0073 -> LATIN SMALL LETTER S
+    u't'        #  0x0074 -> LATIN SMALL LETTER T
+    u'u'        #  0x0075 -> LATIN SMALL LETTER U
+    u'v'        #  0x0076 -> LATIN SMALL LETTER V
+    u'w'        #  0x0077 -> LATIN SMALL LETTER W
+    u'x'        #  0x0078 -> LATIN SMALL LETTER X
+    u'y'        #  0x0079 -> LATIN SMALL LETTER Y
+    u'z'        #  0x007a -> LATIN SMALL LETTER Z
+    u'{'        #  0x007b -> LEFT CURLY BRACKET
+    u'|'        #  0x007c -> VERTICAL LINE
+    u'}'        #  0x007d -> RIGHT CURLY BRACKET
+    u'~'        #  0x007e -> TILDE
+    u'\x7f'     #  0x007f -> DELETE
+    u'\u0410'   #  0x0080 -> CYRILLIC CAPITAL LETTER A
+    u'\u0411'   #  0x0081 -> CYRILLIC CAPITAL LETTER BE
+    u'\u0412'   #  0x0082 -> CYRILLIC CAPITAL LETTER VE
+    u'\u0413'   #  0x0083 -> CYRILLIC CAPITAL LETTER GHE
+    u'\u0414'   #  0x0084 -> CYRILLIC CAPITAL LETTER DE
+    u'\u0415'   #  0x0085 -> CYRILLIC CAPITAL LETTER IE
+    u'\u0416'   #  0x0086 -> CYRILLIC CAPITAL LETTER ZHE
+    u'\u0417'   #  0x0087 -> CYRILLIC CAPITAL LETTER ZE
+    u'\u0418'   #  0x0088 -> CYRILLIC CAPITAL LETTER I
+    u'\u0419'   #  0x0089 -> CYRILLIC CAPITAL LETTER SHORT I
+    u'\u041a'   #  0x008a -> CYRILLIC CAPITAL LETTER KA
+    u'\u041b'   #  0x008b -> CYRILLIC CAPITAL LETTER EL
+    u'\u041c'   #  0x008c -> CYRILLIC CAPITAL LETTER EM
+    u'\u041d'   #  0x008d -> CYRILLIC CAPITAL LETTER EN
+    u'\u041e'   #  0x008e -> CYRILLIC CAPITAL LETTER O
+    u'\u041f'   #  0x008f -> CYRILLIC CAPITAL LETTER PE
+    u'\u0420'   #  0x0090 -> CYRILLIC CAPITAL LETTER ER
+    u'\u0421'   #  0x0091 -> CYRILLIC CAPITAL LETTER ES
+    u'\u0422'   #  0x0092 -> CYRILLIC CAPITAL LETTER TE
+    u'\u0423'   #  0x0093 -> CYRILLIC CAPITAL LETTER U
+    u'\u0424'   #  0x0094 -> CYRILLIC CAPITAL LETTER EF
+    u'\u0425'   #  0x0095 -> CYRILLIC CAPITAL LETTER HA
+    u'\u0426'   #  0x0096 -> CYRILLIC CAPITAL LETTER TSE
+    u'\u0427'   #  0x0097 -> CYRILLIC CAPITAL LETTER CHE
+    u'\u0428'   #  0x0098 -> CYRILLIC CAPITAL LETTER SHA
+    u'\u0429'   #  0x0099 -> CYRILLIC CAPITAL LETTER SHCHA
+    u'\u042a'   #  0x009a -> CYRILLIC CAPITAL LETTER HARD SIGN
+    u'\u042b'   #  0x009b -> CYRILLIC CAPITAL LETTER YERU
+    u'\u042c'   #  0x009c -> CYRILLIC CAPITAL LETTER SOFT SIGN
+    u'\u042d'   #  0x009d -> CYRILLIC CAPITAL LETTER E
+    u'\u042e'   #  0x009e -> CYRILLIC CAPITAL LETTER YU
+    u'\u042f'   #  0x009f -> CYRILLIC CAPITAL LETTER YA
+    u'\u0430'   #  0x00a0 -> CYRILLIC SMALL LETTER A
+    u'\u0431'   #  0x00a1 -> CYRILLIC SMALL LETTER BE
+    u'\u0432'   #  0x00a2 -> CYRILLIC SMALL LETTER VE
+    u'\u0433'   #  0x00a3 -> CYRILLIC SMALL LETTER GHE
+    u'\u0434'   #  0x00a4 -> CYRILLIC SMALL LETTER DE
+    u'\u0435'   #  0x00a5 -> CYRILLIC SMALL LETTER IE
+    u'\u0436'   #  0x00a6 -> CYRILLIC SMALL LETTER ZHE
+    u'\u0437'   #  0x00a7 -> CYRILLIC SMALL LETTER ZE
+    u'\u0438'   #  0x00a8 -> CYRILLIC SMALL LETTER I
+    u'\u0439'   #  0x00a9 -> CYRILLIC SMALL LETTER SHORT I
+    u'\u043a'   #  0x00aa -> CYRILLIC SMALL LETTER KA
+    u'\u043b'   #  0x00ab -> CYRILLIC SMALL LETTER EL
+    u'\u043c'   #  0x00ac -> CYRILLIC SMALL LETTER EM
+    u'\u043d'   #  0x00ad -> CYRILLIC SMALL LETTER EN
+    u'\u043e'   #  0x00ae -> CYRILLIC SMALL LETTER O
+    u'\u043f'   #  0x00af -> CYRILLIC SMALL LETTER PE
+    u'\u2591'   #  0x00b0 -> LIGHT SHADE
+    u'\u2592'   #  0x00b1 -> MEDIUM SHADE
+    u'\u2593'   #  0x00b2 -> DARK SHADE
+    u'\u2502'   #  0x00b3 -> BOX DRAWINGS LIGHT VERTICAL
+    u'\u2524'   #  0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT
+    u'\u2561'   #  0x00b5 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+    u'\u2562'   #  0x00b6 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
+    u'\u2556'   #  0x00b7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
+    u'\u2555'   #  0x00b8 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
+    u'\u2563'   #  0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+    u'\u2551'   #  0x00ba -> BOX DRAWINGS DOUBLE VERTICAL
+    u'\u2557'   #  0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT
+    u'\u255d'   #  0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT
+    u'\u255c'   #  0x00bd -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
+    u'\u255b'   #  0x00be -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+    u'\u2510'   #  0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT
+    u'\u2514'   #  0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT
+    u'\u2534'   #  0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL
+    u'\u252c'   #  0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+    u'\u251c'   #  0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+    u'\u2500'   #  0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL
+    u'\u253c'   #  0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+    u'\u255e'   #  0x00c6 -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+    u'\u255f'   #  0x00c7 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+    u'\u255a'   #  0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT
+    u'\u2554'   #  0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT
+    u'\u2569'   #  0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+    u'\u2566'   #  0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+    u'\u2560'   #  0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+    u'\u2550'   #  0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL
+    u'\u256c'   #  0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+    u'\u2567'   #  0x00cf -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+    u'\u2568'   #  0x00d0 -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+    u'\u2564'   #  0x00d1 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
+    u'\u2565'   #  0x00d2 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
+    u'\u2559'   #  0x00d3 -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+    u'\u2558'   #  0x00d4 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+    u'\u2552'   #  0x00d5 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+    u'\u2553'   #  0x00d6 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
+    u'\u256b'   #  0x00d7 -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
+    u'\u256a'   #  0x00d8 -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+    u'\u2518'   #  0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT
+    u'\u250c'   #  0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT
+    u'\u2588'   #  0x00db -> FULL BLOCK
+    u'\u2584'   #  0x00dc -> LOWER HALF BLOCK
+    u'\u258c'   #  0x00dd -> LEFT HALF BLOCK
+    u'\u2590'   #  0x00de -> RIGHT HALF BLOCK
+    u'\u2580'   #  0x00df -> UPPER HALF BLOCK
+    u'\u0440'   #  0x00e0 -> CYRILLIC SMALL LETTER ER
+    u'\u0441'   #  0x00e1 -> CYRILLIC SMALL LETTER ES
+    u'\u0442'   #  0x00e2 -> CYRILLIC SMALL LETTER TE
+    u'\u0443'   #  0x00e3 -> CYRILLIC SMALL LETTER U
+    u'\u0444'   #  0x00e4 -> CYRILLIC SMALL LETTER EF
+    u'\u0445'   #  0x00e5 -> CYRILLIC SMALL LETTER HA
+    u'\u0446'   #  0x00e6 -> CYRILLIC SMALL LETTER TSE
+    u'\u0447'   #  0x00e7 -> CYRILLIC SMALL LETTER CHE
+    u'\u0448'   #  0x00e8 -> CYRILLIC SMALL LETTER SHA
+    u'\u0449'   #  0x00e9 -> CYRILLIC SMALL LETTER SHCHA
+    u'\u044a'   #  0x00ea -> CYRILLIC SMALL LETTER HARD SIGN
+    u'\u044b'   #  0x00eb -> CYRILLIC SMALL LETTER YERU
+    u'\u044c'   #  0x00ec -> CYRILLIC SMALL LETTER SOFT SIGN
+    u'\u044d'   #  0x00ed -> CYRILLIC SMALL LETTER E
+    u'\u044e'   #  0x00ee -> CYRILLIC SMALL LETTER YU
+    u'\u044f'   #  0x00ef -> CYRILLIC SMALL LETTER YA
+    u'\u0401'   #  0x00f0 -> CYRILLIC CAPITAL LETTER IO
+    u'\u0451'   #  0x00f1 -> CYRILLIC SMALL LETTER IO
+    u'\u0404'   #  0x00f2 -> CYRILLIC CAPITAL LETTER UKRAINIAN IE
+    u'\u0454'   #  0x00f3 -> CYRILLIC SMALL LETTER UKRAINIAN IE
+    u'\u0407'   #  0x00f4 -> CYRILLIC CAPITAL LETTER YI
+    u'\u0457'   #  0x00f5 -> CYRILLIC SMALL LETTER YI
+    u'\u040e'   #  0x00f6 -> CYRILLIC CAPITAL LETTER SHORT U
+    u'\u045e'   #  0x00f7 -> CYRILLIC SMALL LETTER SHORT U
+    u'\xb0'     #  0x00f8 -> DEGREE SIGN
+    u'\u2219'   #  0x00f9 -> BULLET OPERATOR
+    u'\xb7'     #  0x00fa -> MIDDLE DOT
+    u'\u221a'   #  0x00fb -> SQUARE ROOT
+    u'\u2116'   #  0x00fc -> NUMERO SIGN
+    u'\xa4'     #  0x00fd -> CURRENCY SIGN
+    u'\u25a0'   #  0x00fe -> BLACK SQUARE
+    u'\xa0'     #  0x00ff -> NO-BREAK SPACE
+)
+
+### Encoding Map
+
+encoding_map = {
+    0x0000: 0x0000,     #  NULL
+    0x0001: 0x0001,     #  START OF HEADING
+    0x0002: 0x0002,     #  START OF TEXT
+    0x0003: 0x0003,     #  END OF TEXT
+    0x0004: 0x0004,     #  END OF TRANSMISSION
+    0x0005: 0x0005,     #  ENQUIRY
+    0x0006: 0x0006,     #  ACKNOWLEDGE
+    0x0007: 0x0007,     #  BELL
+    0x0008: 0x0008,     #  BACKSPACE
+    0x0009: 0x0009,     #  HORIZONTAL TABULATION
+    0x000a: 0x000a,     #  LINE FEED
+    0x000b: 0x000b,     #  VERTICAL TABULATION
+    0x000c: 0x000c,     #  FORM FEED
+    0x000d: 0x000d,     #  CARRIAGE RETURN
+    0x000e: 0x000e,     #  SHIFT OUT
+    0x000f: 0x000f,     #  SHIFT IN
+    0x0010: 0x0010,     #  DATA LINK ESCAPE
+    0x0011: 0x0011,     #  DEVICE CONTROL ONE
+    0x0012: 0x0012,     #  DEVICE CONTROL TWO
+    0x0013: 0x0013,     #  DEVICE CONTROL THREE
+    0x0014: 0x0014,     #  DEVICE CONTROL FOUR
+    0x0015: 0x0015,     #  NEGATIVE ACKNOWLEDGE
+    0x0016: 0x0016,     #  SYNCHRONOUS IDLE
+    0x0017: 0x0017,     #  END OF TRANSMISSION BLOCK
+    0x0018: 0x0018,     #  CANCEL
+    0x0019: 0x0019,     #  END OF MEDIUM
+    0x001a: 0x001a,     #  SUBSTITUTE
+    0x001b: 0x001b,     #  ESCAPE
+    0x001c: 0x001c,     #  FILE SEPARATOR
+    0x001d: 0x001d,     #  GROUP SEPARATOR
+    0x001e: 0x001e,     #  RECORD SEPARATOR
+    0x001f: 0x001f,     #  UNIT SEPARATOR
+    0x0020: 0x0020,     #  SPACE
+    0x0021: 0x0021,     #  EXCLAMATION MARK
+    0x0022: 0x0022,     #  QUOTATION MARK
+    0x0023: 0x0023,     #  NUMBER SIGN
+    0x0024: 0x0024,     #  DOLLAR SIGN
+    0x0025: 0x0025,     #  PERCENT SIGN
+    0x0026: 0x0026,     #  AMPERSAND
+    0x0027: 0x0027,     #  APOSTROPHE
+    0x0028: 0x0028,     #  LEFT PARENTHESIS
+    0x0029: 0x0029,     #  RIGHT PARENTHESIS
+    0x002a: 0x002a,     #  ASTERISK
+    0x002b: 0x002b,     #  PLUS SIGN
+    0x002c: 0x002c,     #  COMMA
+    0x002d: 0x002d,     #  HYPHEN-MINUS
+    0x002e: 0x002e,     #  FULL STOP
+    0x002f: 0x002f,     #  SOLIDUS
+    0x0030: 0x0030,     #  DIGIT ZERO
+    0x0031: 0x0031,     #  DIGIT ONE
+    0x0032: 0x0032,     #  DIGIT TWO
+    0x0033: 0x0033,     #  DIGIT THREE
+    0x0034: 0x0034,     #  DIGIT FOUR
+    0x0035: 0x0035,     #  DIGIT FIVE
+    0x0036: 0x0036,     #  DIGIT SIX
+    0x0037: 0x0037,     #  DIGIT SEVEN
+    0x0038: 0x0038,     #  DIGIT EIGHT
+    0x0039: 0x0039,     #  DIGIT NINE
+    0x003a: 0x003a,     #  COLON
+    0x003b: 0x003b,     #  SEMICOLON
+    0x003c: 0x003c,     #  LESS-THAN SIGN
+    0x003d: 0x003d,     #  EQUALS SIGN
+    0x003e: 0x003e,     #  GREATER-THAN SIGN
+    0x003f: 0x003f,     #  QUESTION MARK
+    0x0040: 0x0040,     #  COMMERCIAL AT
+    0x0041: 0x0041,     #  LATIN CAPITAL LETTER A
+    0x0042: 0x0042,     #  LATIN CAPITAL LETTER B
+    0x0043: 0x0043,     #  LATIN CAPITAL LETTER C
+    0x0044: 0x0044,     #  LATIN CAPITAL LETTER D
+    0x0045: 0x0045,     #  LATIN CAPITAL LETTER E
+    0x0046: 0x0046,     #  LATIN CAPITAL LETTER F
+    0x0047: 0x0047,     #  LATIN CAPITAL LETTER G
+    0x0048: 0x0048,     #  LATIN CAPITAL LETTER H
+    0x0049: 0x0049,     #  LATIN CAPITAL LETTER I
+    0x004a: 0x004a,     #  LATIN CAPITAL LETTER J
+    0x004b: 0x004b,     #  LATIN CAPITAL LETTER K
+    0x004c: 0x004c,     #  LATIN CAPITAL LETTER L
+    0x004d: 0x004d,     #  LATIN CAPITAL LETTER M
+    0x004e: 0x004e,     #  LATIN CAPITAL LETTER N
+    0x004f: 0x004f,     #  LATIN CAPITAL LETTER O
+    0x0050: 0x0050,     #  LATIN CAPITAL LETTER P
+    0x0051: 0x0051,     #  LATIN CAPITAL LETTER Q
+    0x0052: 0x0052,     #  LATIN CAPITAL LETTER R
+    0x0053: 0x0053,     #  LATIN CAPITAL LETTER S
+    0x0054: 0x0054,     #  LATIN CAPITAL LETTER T
+    0x0055: 0x0055,     #  LATIN CAPITAL LETTER U
+    0x0056: 0x0056,     #  LATIN CAPITAL LETTER V
+    0x0057: 0x0057,     #  LATIN CAPITAL LETTER W
+    0x0058: 0x0058,     #  LATIN CAPITAL LETTER X
+    0x0059: 0x0059,     #  LATIN CAPITAL LETTER Y
+    0x005a: 0x005a,     #  LATIN CAPITAL LETTER Z
+    0x005b: 0x005b,     #  LEFT SQUARE BRACKET
+    0x005c: 0x005c,     #  REVERSE SOLIDUS
+    0x005d: 0x005d,     #  RIGHT SQUARE BRACKET
+    0x005e: 0x005e,     #  CIRCUMFLEX ACCENT
+    0x005f: 0x005f,     #  LOW LINE
+    0x0060: 0x0060,     #  GRAVE ACCENT
+    0x0061: 0x0061,     #  LATIN SMALL LETTER A
+    0x0062: 0x0062,     #  LATIN SMALL LETTER B
+    0x0063: 0x0063,     #  LATIN SMALL LETTER C
+    0x0064: 0x0064,     #  LATIN SMALL LETTER D
+    0x0065: 0x0065,     #  LATIN SMALL LETTER E
+    0x0066: 0x0066,     #  LATIN SMALL LETTER F
+    0x0067: 0x0067,     #  LATIN SMALL LETTER G
+    0x0068: 0x0068,     #  LATIN SMALL LETTER H
+    0x0069: 0x0069,     #  LATIN SMALL LETTER I
+    0x006a: 0x006a,     #  LATIN SMALL LETTER J
+    0x006b: 0x006b,     #  LATIN SMALL LETTER K
+    0x006c: 0x006c,     #  LATIN SMALL LETTER L
+    0x006d: 0x006d,     #  LATIN SMALL LETTER M
+    0x006e: 0x006e,     #  LATIN SMALL LETTER N
+    0x006f: 0x006f,     #  LATIN SMALL LETTER O
+    0x0070: 0x0070,     #  LATIN SMALL LETTER P
+    0x0071: 0x0071,     #  LATIN SMALL LETTER Q
+    0x0072: 0x0072,     #  LATIN SMALL LETTER R
+    0x0073: 0x0073,     #  LATIN SMALL LETTER S
+    0x0074: 0x0074,     #  LATIN SMALL LETTER T
+    0x0075: 0x0075,     #  LATIN SMALL LETTER U
+    0x0076: 0x0076,     #  LATIN SMALL LETTER V
+    0x0077: 0x0077,     #  LATIN SMALL LETTER W
+    0x0078: 0x0078,     #  LATIN SMALL LETTER X
+    0x0079: 0x0079,     #  LATIN SMALL LETTER Y
+    0x007a: 0x007a,     #  LATIN SMALL LETTER Z
+    0x007b: 0x007b,     #  LEFT CURLY BRACKET
+    0x007c: 0x007c,     #  VERTICAL LINE
+    0x007d: 0x007d,     #  RIGHT CURLY BRACKET
+    0x007e: 0x007e,     #  TILDE
+    0x007f: 0x007f,     #  DELETE
+    0x00a0: 0x00ff,     #  NO-BREAK SPACE
+    0x00a4: 0x00fd,     #  CURRENCY SIGN
+    0x00b0: 0x00f8,     #  DEGREE SIGN
+    0x00b7: 0x00fa,     #  MIDDLE DOT
+    0x0401: 0x00f0,     #  CYRILLIC CAPITAL LETTER IO
+    0x0404: 0x00f2,     #  CYRILLIC CAPITAL LETTER UKRAINIAN IE
+    0x0407: 0x00f4,     #  CYRILLIC CAPITAL LETTER YI
+    0x040e: 0x00f6,     #  CYRILLIC CAPITAL LETTER SHORT U
+    0x0410: 0x0080,     #  CYRILLIC CAPITAL LETTER A
+    0x0411: 0x0081,     #  CYRILLIC CAPITAL LETTER BE
+    0x0412: 0x0082,     #  CYRILLIC CAPITAL LETTER VE
+    0x0413: 0x0083,     #  CYRILLIC CAPITAL LETTER GHE
+    0x0414: 0x0084,     #  CYRILLIC CAPITAL LETTER DE
+    0x0415: 0x0085,     #  CYRILLIC CAPITAL LETTER IE
+    0x0416: 0x0086,     #  CYRILLIC CAPITAL LETTER ZHE
+    0x0417: 0x0087,     #  CYRILLIC CAPITAL LETTER ZE
+    0x0418: 0x0088,     #  CYRILLIC CAPITAL LETTER I
+    0x0419: 0x0089,     #  CYRILLIC CAPITAL LETTER SHORT I
+    0x041a: 0x008a,     #  CYRILLIC CAPITAL LETTER KA
+    0x041b: 0x008b,     #  CYRILLIC CAPITAL LETTER EL
+    0x041c: 0x008c,     #  CYRILLIC CAPITAL LETTER EM
+    0x041d: 0x008d,     #  CYRILLIC CAPITAL LETTER EN
+    0x041e: 0x008e,     #  CYRILLIC CAPITAL LETTER O
+    0x041f: 0x008f,     #  CYRILLIC CAPITAL LETTER PE
+    0x0420: 0x0090,     #  CYRILLIC CAPITAL LETTER ER
+    0x0421: 0x0091,     #  CYRILLIC CAPITAL LETTER ES
+    0x0422: 0x0092,     #  CYRILLIC CAPITAL LETTER TE
+    0x0423: 0x0093,     #  CYRILLIC CAPITAL LETTER U
+    0x0424: 0x0094,     #  CYRILLIC CAPITAL LETTER EF
+    0x0425: 0x0095,     #  CYRILLIC CAPITAL LETTER HA
+    0x0426: 0x0096,     #  CYRILLIC CAPITAL LETTER TSE
+    0x0427: 0x0097,     #  CYRILLIC CAPITAL LETTER CHE
+    0x0428: 0x0098,     #  CYRILLIC CAPITAL LETTER SHA
+    0x0429: 0x0099,     #  CYRILLIC CAPITAL LETTER SHCHA
+    0x042a: 0x009a,     #  CYRILLIC CAPITAL LETTER HARD SIGN
+    0x042b: 0x009b,     #  CYRILLIC CAPITAL LETTER YERU
+    0x042c: 0x009c,     #  CYRILLIC CAPITAL LETTER SOFT SIGN
+    0x042d: 0x009d,     #  CYRILLIC CAPITAL LETTER E
+    0x042e: 0x009e,     #  CYRILLIC CAPITAL LETTER YU
+    0x042f: 0x009f,     #  CYRILLIC CAPITAL LETTER YA
+    0x0430: 0x00a0,     #  CYRILLIC SMALL LETTER A
+    0x0431: 0x00a1,     #  CYRILLIC SMALL LETTER BE
+    0x0432: 0x00a2,     #  CYRILLIC SMALL LETTER VE
+    0x0433: 0x00a3,     #  CYRILLIC SMALL LETTER GHE
+    0x0434: 0x00a4,     #  CYRILLIC SMALL LETTER DE
+    0x0435: 0x00a5,     #  CYRILLIC SMALL LETTER IE
+    0x0436: 0x00a6,     #  CYRILLIC SMALL LETTER ZHE
+    0x0437: 0x00a7,     #  CYRILLIC SMALL LETTER ZE
+    0x0438: 0x00a8,     #  CYRILLIC SMALL LETTER I
+    0x0439: 0x00a9,     #  CYRILLIC SMALL LETTER SHORT I
+    0x043a: 0x00aa,     #  CYRILLIC SMALL LETTER KA
+    0x043b: 0x00ab,     #  CYRILLIC SMALL LETTER EL
+    0x043c: 0x00ac,     #  CYRILLIC SMALL LETTER EM
+    0x043d: 0x00ad,     #  CYRILLIC SMALL LETTER EN
+    0x043e: 0x00ae,     #  CYRILLIC SMALL LETTER O
+    0x043f: 0x00af,     #  CYRILLIC SMALL LETTER PE
+    0x0440: 0x00e0,     #  CYRILLIC SMALL LETTER ER
+    0x0441: 0x00e1,     #  CYRILLIC SMALL LETTER ES
+    0x0442: 0x00e2,     #  CYRILLIC SMALL LETTER TE
+    0x0443: 0x00e3,     #  CYRILLIC SMALL LETTER U
+    0x0444: 0x00e4,     #  CYRILLIC SMALL LETTER EF
+    0x0445: 0x00e5,     #  CYRILLIC SMALL LETTER HA
+    0x0446: 0x00e6,     #  CYRILLIC SMALL LETTER TSE
+    0x0447: 0x00e7,     #  CYRILLIC SMALL LETTER CHE
+    0x0448: 0x00e8,     #  CYRILLIC SMALL LETTER SHA
+    0x0449: 0x00e9,     #  CYRILLIC SMALL LETTER SHCHA
+    0x044a: 0x00ea,     #  CYRILLIC SMALL LETTER HARD SIGN
+    0x044b: 0x00eb,     #  CYRILLIC SMALL LETTER YERU
+    0x044c: 0x00ec,     #  CYRILLIC SMALL LETTER SOFT SIGN
+    0x044d: 0x00ed,     #  CYRILLIC SMALL LETTER E
+    0x044e: 0x00ee,     #  CYRILLIC SMALL LETTER YU
+    0x044f: 0x00ef,     #  CYRILLIC SMALL LETTER YA
+    0x0451: 0x00f1,     #  CYRILLIC SMALL LETTER IO
+    0x0454: 0x00f3,     #  CYRILLIC SMALL LETTER UKRAINIAN IE
+    0x0457: 0x00f5,     #  CYRILLIC SMALL LETTER YI
+    0x045e: 0x00f7,     #  CYRILLIC SMALL LETTER SHORT U
+    0x2116: 0x00fc,     #  NUMERO SIGN
+    0x2219: 0x00f9,     #  BULLET OPERATOR
+    0x221a: 0x00fb,     #  SQUARE ROOT
+    0x2500: 0x00c4,     #  BOX DRAWINGS LIGHT HORIZONTAL
+    0x2502: 0x00b3,     #  BOX DRAWINGS LIGHT VERTICAL
+    0x250c: 0x00da,     #  BOX DRAWINGS LIGHT DOWN AND RIGHT
+    0x2510: 0x00bf,     #  BOX DRAWINGS LIGHT DOWN AND LEFT
+    0x2514: 0x00c0,     #  BOX DRAWINGS LIGHT UP AND RIGHT
+    0x2518: 0x00d9,     #  BOX DRAWINGS LIGHT UP AND LEFT
+    0x251c: 0x00c3,     #  BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+    0x2524: 0x00b4,     #  BOX DRAWINGS LIGHT VERTICAL AND LEFT
+    0x252c: 0x00c2,     #  BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+    0x2534: 0x00c1,     #  BOX DRAWINGS LIGHT UP AND HORIZONTAL
+    0x253c: 0x00c5,     #  BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+    0x2550: 0x00cd,     #  BOX DRAWINGS DOUBLE HORIZONTAL
+    0x2551: 0x00ba,     #  BOX DRAWINGS DOUBLE VERTICAL
+    0x2552: 0x00d5,     #  BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+    0x2553: 0x00d6,     #  BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
+    0x2554: 0x00c9,     #  BOX DRAWINGS DOUBLE DOWN AND RIGHT
+    0x2555: 0x00b8,     #  BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
+    0x2556: 0x00b7,     #  BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
+    0x2557: 0x00bb,     #  BOX DRAWINGS DOUBLE DOWN AND LEFT
+    0x2558: 0x00d4,     #  BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+    0x2559: 0x00d3,     #  BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+    0x255a: 0x00c8,     #  BOX DRAWINGS DOUBLE UP AND RIGHT
+    0x255b: 0x00be,     #  BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+    0x255c: 0x00bd,     #  BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
+    0x255d: 0x00bc,     #  BOX DRAWINGS DOUBLE UP AND LEFT
+    0x255e: 0x00c6,     #  BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+    0x255f: 0x00c7,     #  BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+    0x2560: 0x00cc,     #  BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+    0x2561: 0x00b5,     #  BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+    0x2562: 0x00b6,     #  BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
+    0x2563: 0x00b9,     #  BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+    0x2564: 0x00d1,     #  BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
+    0x2565: 0x00d2,     #  BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
+    0x2566: 0x00cb,     #  BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+    0x2567: 0x00cf,     #  BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+    0x2568: 0x00d0,     #  BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+    0x2569: 0x00ca,     #  BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+    0x256a: 0x00d8,     #  BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+    0x256b: 0x00d7,     #  BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
+    0x256c: 0x00ce,     #  BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+    0x2580: 0x00df,     #  UPPER HALF BLOCK
+    0x2584: 0x00dc,     #  LOWER HALF BLOCK
+    0x2588: 0x00db,     #  FULL BLOCK
+    0x258c: 0x00dd,     #  LEFT HALF BLOCK
+    0x2590: 0x00de,     #  RIGHT HALF BLOCK
+    0x2591: 0x00b0,     #  LIGHT SHADE
+    0x2592: 0x00b1,     #  MEDIUM SHADE
+    0x2593: 0x00b2,     #  DARK SHADE
+    0x25a0: 0x00fe,     #  BLACK SQUARE
+}

Added: vendor/Python/current/Lib/encodings/cp869.py
===================================================================
--- vendor/Python/current/Lib/encodings/cp869.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/cp869.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,689 @@
+""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP869.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_map)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='cp869',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+### Decoding Map
+
+decoding_map = codecs.make_identity_dict(range(256))
+decoding_map.update({
+    0x0080: None,       #  UNDEFINED
+    0x0081: None,       #  UNDEFINED
+    0x0082: None,       #  UNDEFINED
+    0x0083: None,       #  UNDEFINED
+    0x0084: None,       #  UNDEFINED
+    0x0085: None,       #  UNDEFINED
+    0x0086: 0x0386,     #  GREEK CAPITAL LETTER ALPHA WITH TONOS
+    0x0087: None,       #  UNDEFINED
+    0x0088: 0x00b7,     #  MIDDLE DOT
+    0x0089: 0x00ac,     #  NOT SIGN
+    0x008a: 0x00a6,     #  BROKEN BAR
+    0x008b: 0x2018,     #  LEFT SINGLE QUOTATION MARK
+    0x008c: 0x2019,     #  RIGHT SINGLE QUOTATION MARK
+    0x008d: 0x0388,     #  GREEK CAPITAL LETTER EPSILON WITH TONOS
+    0x008e: 0x2015,     #  HORIZONTAL BAR
+    0x008f: 0x0389,     #  GREEK CAPITAL LETTER ETA WITH TONOS
+    0x0090: 0x038a,     #  GREEK CAPITAL LETTER IOTA WITH TONOS
+    0x0091: 0x03aa,     #  GREEK CAPITAL LETTER IOTA WITH DIALYTIKA
+    0x0092: 0x038c,     #  GREEK CAPITAL LETTER OMICRON WITH TONOS
+    0x0093: None,       #  UNDEFINED
+    0x0094: None,       #  UNDEFINED
+    0x0095: 0x038e,     #  GREEK CAPITAL LETTER UPSILON WITH TONOS
+    0x0096: 0x03ab,     #  GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA
+    0x0097: 0x00a9,     #  COPYRIGHT SIGN
+    0x0098: 0x038f,     #  GREEK CAPITAL LETTER OMEGA WITH TONOS
+    0x0099: 0x00b2,     #  SUPERSCRIPT TWO
+    0x009a: 0x00b3,     #  SUPERSCRIPT THREE
+    0x009b: 0x03ac,     #  GREEK SMALL LETTER ALPHA WITH TONOS
+    0x009c: 0x00a3,     #  POUND SIGN
+    0x009d: 0x03ad,     #  GREEK SMALL LETTER EPSILON WITH TONOS
+    0x009e: 0x03ae,     #  GREEK SMALL LETTER ETA WITH TONOS
+    0x009f: 0x03af,     #  GREEK SMALL LETTER IOTA WITH TONOS
+    0x00a0: 0x03ca,     #  GREEK SMALL LETTER IOTA WITH DIALYTIKA
+    0x00a1: 0x0390,     #  GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
+    0x00a2: 0x03cc,     #  GREEK SMALL LETTER OMICRON WITH TONOS
+    0x00a3: 0x03cd,     #  GREEK SMALL LETTER UPSILON WITH TONOS
+    0x00a4: 0x0391,     #  GREEK CAPITAL LETTER ALPHA
+    0x00a5: 0x0392,     #  GREEK CAPITAL LETTER BETA
+    0x00a6: 0x0393,     #  GREEK CAPITAL LETTER GAMMA
+    0x00a7: 0x0394,     #  GREEK CAPITAL LETTER DELTA
+    0x00a8: 0x0395,     #  GREEK CAPITAL LETTER EPSILON
+    0x00a9: 0x0396,     #  GREEK CAPITAL LETTER ZETA
+    0x00aa: 0x0397,     #  GREEK CAPITAL LETTER ETA
+    0x00ab: 0x00bd,     #  VULGAR FRACTION ONE HALF
+    0x00ac: 0x0398,     #  GREEK CAPITAL LETTER THETA
+    0x00ad: 0x0399,     #  GREEK CAPITAL LETTER IOTA
+    0x00ae: 0x00ab,     #  LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    0x00af: 0x00bb,     #  RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    0x00b0: 0x2591,     #  LIGHT SHADE
+    0x00b1: 0x2592,     #  MEDIUM SHADE
+    0x00b2: 0x2593,     #  DARK SHADE
+    0x00b3: 0x2502,     #  BOX DRAWINGS LIGHT VERTICAL
+    0x00b4: 0x2524,     #  BOX DRAWINGS LIGHT VERTICAL AND LEFT
+    0x00b5: 0x039a,     #  GREEK CAPITAL LETTER KAPPA
+    0x00b6: 0x039b,     #  GREEK CAPITAL LETTER LAMDA
+    0x00b7: 0x039c,     #  GREEK CAPITAL LETTER MU
+    0x00b8: 0x039d,     #  GREEK CAPITAL LETTER NU
+    0x00b9: 0x2563,     #  BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+    0x00ba: 0x2551,     #  BOX DRAWINGS DOUBLE VERTICAL
+    0x00bb: 0x2557,     #  BOX DRAWINGS DOUBLE DOWN AND LEFT
+    0x00bc: 0x255d,     #  BOX DRAWINGS DOUBLE UP AND LEFT
+    0x00bd: 0x039e,     #  GREEK CAPITAL LETTER XI
+    0x00be: 0x039f,     #  GREEK CAPITAL LETTER OMICRON
+    0x00bf: 0x2510,     #  BOX DRAWINGS LIGHT DOWN AND LEFT
+    0x00c0: 0x2514,     #  BOX DRAWINGS LIGHT UP AND RIGHT
+    0x00c1: 0x2534,     #  BOX DRAWINGS LIGHT UP AND HORIZONTAL
+    0x00c2: 0x252c,     #  BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+    0x00c3: 0x251c,     #  BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+    0x00c4: 0x2500,     #  BOX DRAWINGS LIGHT HORIZONTAL
+    0x00c5: 0x253c,     #  BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+    0x00c6: 0x03a0,     #  GREEK CAPITAL LETTER PI
+    0x00c7: 0x03a1,     #  GREEK CAPITAL LETTER RHO
+    0x00c8: 0x255a,     #  BOX DRAWINGS DOUBLE UP AND RIGHT
+    0x00c9: 0x2554,     #  BOX DRAWINGS DOUBLE DOWN AND RIGHT
+    0x00ca: 0x2569,     #  BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+    0x00cb: 0x2566,     #  BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+    0x00cc: 0x2560,     #  BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+    0x00cd: 0x2550,     #  BOX DRAWINGS DOUBLE HORIZONTAL
+    0x00ce: 0x256c,     #  BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+    0x00cf: 0x03a3,     #  GREEK CAPITAL LETTER SIGMA
+    0x00d0: 0x03a4,     #  GREEK CAPITAL LETTER TAU
+    0x00d1: 0x03a5,     #  GREEK CAPITAL LETTER UPSILON
+    0x00d2: 0x03a6,     #  GREEK CAPITAL LETTER PHI
+    0x00d3: 0x03a7,     #  GREEK CAPITAL LETTER CHI
+    0x00d4: 0x03a8,     #  GREEK CAPITAL LETTER PSI
+    0x00d5: 0x03a9,     #  GREEK CAPITAL LETTER OMEGA
+    0x00d6: 0x03b1,     #  GREEK SMALL LETTER ALPHA
+    0x00d7: 0x03b2,     #  GREEK SMALL LETTER BETA
+    0x00d8: 0x03b3,     #  GREEK SMALL LETTER GAMMA
+    0x00d9: 0x2518,     #  BOX DRAWINGS LIGHT UP AND LEFT
+    0x00da: 0x250c,     #  BOX DRAWINGS LIGHT DOWN AND RIGHT
+    0x00db: 0x2588,     #  FULL BLOCK
+    0x00dc: 0x2584,     #  LOWER HALF BLOCK
+    0x00dd: 0x03b4,     #  GREEK SMALL LETTER DELTA
+    0x00de: 0x03b5,     #  GREEK SMALL LETTER EPSILON
+    0x00df: 0x2580,     #  UPPER HALF BLOCK
+    0x00e0: 0x03b6,     #  GREEK SMALL LETTER ZETA
+    0x00e1: 0x03b7,     #  GREEK SMALL LETTER ETA
+    0x00e2: 0x03b8,     #  GREEK SMALL LETTER THETA
+    0x00e3: 0x03b9,     #  GREEK SMALL LETTER IOTA
+    0x00e4: 0x03ba,     #  GREEK SMALL LETTER KAPPA
+    0x00e5: 0x03bb,     #  GREEK SMALL LETTER LAMDA
+    0x00e6: 0x03bc,     #  GREEK SMALL LETTER MU
+    0x00e7: 0x03bd,     #  GREEK SMALL LETTER NU
+    0x00e8: 0x03be,     #  GREEK SMALL LETTER XI
+    0x00e9: 0x03bf,     #  GREEK SMALL LETTER OMICRON
+    0x00ea: 0x03c0,     #  GREEK SMALL LETTER PI
+    0x00eb: 0x03c1,     #  GREEK SMALL LETTER RHO
+    0x00ec: 0x03c3,     #  GREEK SMALL LETTER SIGMA
+    0x00ed: 0x03c2,     #  GREEK SMALL LETTER FINAL SIGMA
+    0x00ee: 0x03c4,     #  GREEK SMALL LETTER TAU
+    0x00ef: 0x0384,     #  GREEK TONOS
+    0x00f0: 0x00ad,     #  SOFT HYPHEN
+    0x00f1: 0x00b1,     #  PLUS-MINUS SIGN
+    0x00f2: 0x03c5,     #  GREEK SMALL LETTER UPSILON
+    0x00f3: 0x03c6,     #  GREEK SMALL LETTER PHI
+    0x00f4: 0x03c7,     #  GREEK SMALL LETTER CHI
+    0x00f5: 0x00a7,     #  SECTION SIGN
+    0x00f6: 0x03c8,     #  GREEK SMALL LETTER PSI
+    0x00f7: 0x0385,     #  GREEK DIALYTIKA TONOS
+    0x00f8: 0x00b0,     #  DEGREE SIGN
+    0x00f9: 0x00a8,     #  DIAERESIS
+    0x00fa: 0x03c9,     #  GREEK SMALL LETTER OMEGA
+    0x00fb: 0x03cb,     #  GREEK SMALL LETTER UPSILON WITH DIALYTIKA
+    0x00fc: 0x03b0,     #  GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS
+    0x00fd: 0x03ce,     #  GREEK SMALL LETTER OMEGA WITH TONOS
+    0x00fe: 0x25a0,     #  BLACK SQUARE
+    0x00ff: 0x00a0,     #  NO-BREAK SPACE
+})
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x0000 -> NULL
+    u'\x01'     #  0x0001 -> START OF HEADING
+    u'\x02'     #  0x0002 -> START OF TEXT
+    u'\x03'     #  0x0003 -> END OF TEXT
+    u'\x04'     #  0x0004 -> END OF TRANSMISSION
+    u'\x05'     #  0x0005 -> ENQUIRY
+    u'\x06'     #  0x0006 -> ACKNOWLEDGE
+    u'\x07'     #  0x0007 -> BELL
+    u'\x08'     #  0x0008 -> BACKSPACE
+    u'\t'       #  0x0009 -> HORIZONTAL TABULATION
+    u'\n'       #  0x000a -> LINE FEED
+    u'\x0b'     #  0x000b -> VERTICAL TABULATION
+    u'\x0c'     #  0x000c -> FORM FEED
+    u'\r'       #  0x000d -> CARRIAGE RETURN
+    u'\x0e'     #  0x000e -> SHIFT OUT
+    u'\x0f'     #  0x000f -> SHIFT IN
+    u'\x10'     #  0x0010 -> DATA LINK ESCAPE
+    u'\x11'     #  0x0011 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x0012 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x0013 -> DEVICE CONTROL THREE
+    u'\x14'     #  0x0014 -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x0015 -> NEGATIVE ACKNOWLEDGE
+    u'\x16'     #  0x0016 -> SYNCHRONOUS IDLE
+    u'\x17'     #  0x0017 -> END OF TRANSMISSION BLOCK
+    u'\x18'     #  0x0018 -> CANCEL
+    u'\x19'     #  0x0019 -> END OF MEDIUM
+    u'\x1a'     #  0x001a -> SUBSTITUTE
+    u'\x1b'     #  0x001b -> ESCAPE
+    u'\x1c'     #  0x001c -> FILE SEPARATOR
+    u'\x1d'     #  0x001d -> GROUP SEPARATOR
+    u'\x1e'     #  0x001e -> RECORD SEPARATOR
+    u'\x1f'     #  0x001f -> UNIT SEPARATOR
+    u' '        #  0x0020 -> SPACE
+    u'!'        #  0x0021 -> EXCLAMATION MARK
+    u'"'        #  0x0022 -> QUOTATION MARK
+    u'#'        #  0x0023 -> NUMBER SIGN
+    u'$'        #  0x0024 -> DOLLAR SIGN
+    u'%'        #  0x0025 -> PERCENT SIGN
+    u'&'        #  0x0026 -> AMPERSAND
+    u"'"        #  0x0027 -> APOSTROPHE
+    u'('        #  0x0028 -> LEFT PARENTHESIS
+    u')'        #  0x0029 -> RIGHT PARENTHESIS
+    u'*'        #  0x002a -> ASTERISK
+    u'+'        #  0x002b -> PLUS SIGN
+    u','        #  0x002c -> COMMA
+    u'-'        #  0x002d -> HYPHEN-MINUS
+    u'.'        #  0x002e -> FULL STOP
+    u'/'        #  0x002f -> SOLIDUS
+    u'0'        #  0x0030 -> DIGIT ZERO
+    u'1'        #  0x0031 -> DIGIT ONE
+    u'2'        #  0x0032 -> DIGIT TWO
+    u'3'        #  0x0033 -> DIGIT THREE
+    u'4'        #  0x0034 -> DIGIT FOUR
+    u'5'        #  0x0035 -> DIGIT FIVE
+    u'6'        #  0x0036 -> DIGIT SIX
+    u'7'        #  0x0037 -> DIGIT SEVEN
+    u'8'        #  0x0038 -> DIGIT EIGHT
+    u'9'        #  0x0039 -> DIGIT NINE
+    u':'        #  0x003a -> COLON
+    u';'        #  0x003b -> SEMICOLON
+    u'<'        #  0x003c -> LESS-THAN SIGN
+    u'='        #  0x003d -> EQUALS SIGN
+    u'>'        #  0x003e -> GREATER-THAN SIGN
+    u'?'        #  0x003f -> QUESTION MARK
+    u'@'        #  0x0040 -> COMMERCIAL AT
+    u'A'        #  0x0041 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x0042 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x0043 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x0044 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x0045 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x0046 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x0047 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x0048 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x0049 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x004a -> LATIN CAPITAL LETTER J
+    u'K'        #  0x004b -> LATIN CAPITAL LETTER K
+    u'L'        #  0x004c -> LATIN CAPITAL LETTER L
+    u'M'        #  0x004d -> LATIN CAPITAL LETTER M
+    u'N'        #  0x004e -> LATIN CAPITAL LETTER N
+    u'O'        #  0x004f -> LATIN CAPITAL LETTER O
+    u'P'        #  0x0050 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x0051 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x0052 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x0053 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x0054 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x0055 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x0056 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x0057 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x0058 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x0059 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x005a -> LATIN CAPITAL LETTER Z
+    u'['        #  0x005b -> LEFT SQUARE BRACKET
+    u'\\'       #  0x005c -> REVERSE SOLIDUS
+    u']'        #  0x005d -> RIGHT SQUARE BRACKET
+    u'^'        #  0x005e -> CIRCUMFLEX ACCENT
+    u'_'        #  0x005f -> LOW LINE
+    u'`'        #  0x0060 -> GRAVE ACCENT
+    u'a'        #  0x0061 -> LATIN SMALL LETTER A
+    u'b'        #  0x0062 -> LATIN SMALL LETTER B
+    u'c'        #  0x0063 -> LATIN SMALL LETTER C
+    u'd'        #  0x0064 -> LATIN SMALL LETTER D
+    u'e'        #  0x0065 -> LATIN SMALL LETTER E
+    u'f'        #  0x0066 -> LATIN SMALL LETTER F
+    u'g'        #  0x0067 -> LATIN SMALL LETTER G
+    u'h'        #  0x0068 -> LATIN SMALL LETTER H
+    u'i'        #  0x0069 -> LATIN SMALL LETTER I
+    u'j'        #  0x006a -> LATIN SMALL LETTER J
+    u'k'        #  0x006b -> LATIN SMALL LETTER K
+    u'l'        #  0x006c -> LATIN SMALL LETTER L
+    u'm'        #  0x006d -> LATIN SMALL LETTER M
+    u'n'        #  0x006e -> LATIN SMALL LETTER N
+    u'o'        #  0x006f -> LATIN SMALL LETTER O
+    u'p'        #  0x0070 -> LATIN SMALL LETTER P
+    u'q'        #  0x0071 -> LATIN SMALL LETTER Q
+    u'r'        #  0x0072 -> LATIN SMALL LETTER R
+    u's'        #  0x0073 -> LATIN SMALL LETTER S
+    u't'        #  0x0074 -> LATIN SMALL LETTER T
+    u'u'        #  0x0075 -> LATIN SMALL LETTER U
+    u'v'        #  0x0076 -> LATIN SMALL LETTER V
+    u'w'        #  0x0077 -> LATIN SMALL LETTER W
+    u'x'        #  0x0078 -> LATIN SMALL LETTER X
+    u'y'        #  0x0079 -> LATIN SMALL LETTER Y
+    u'z'        #  0x007a -> LATIN SMALL LETTER Z
+    u'{'        #  0x007b -> LEFT CURLY BRACKET
+    u'|'        #  0x007c -> VERTICAL LINE
+    u'}'        #  0x007d -> RIGHT CURLY BRACKET
+    u'~'        #  0x007e -> TILDE
+    u'\x7f'     #  0x007f -> DELETE
+    u'\ufffe'   #  0x0080 -> UNDEFINED
+    u'\ufffe'   #  0x0081 -> UNDEFINED
+    u'\ufffe'   #  0x0082 -> UNDEFINED
+    u'\ufffe'   #  0x0083 -> UNDEFINED
+    u'\ufffe'   #  0x0084 -> UNDEFINED
+    u'\ufffe'   #  0x0085 -> UNDEFINED
+    u'\u0386'   #  0x0086 -> GREEK CAPITAL LETTER ALPHA WITH TONOS
+    u'\ufffe'   #  0x0087 -> UNDEFINED
+    u'\xb7'     #  0x0088 -> MIDDLE DOT
+    u'\xac'     #  0x0089 -> NOT SIGN
+    u'\xa6'     #  0x008a -> BROKEN BAR
+    u'\u2018'   #  0x008b -> LEFT SINGLE QUOTATION MARK
+    u'\u2019'   #  0x008c -> RIGHT SINGLE QUOTATION MARK
+    u'\u0388'   #  0x008d -> GREEK CAPITAL LETTER EPSILON WITH TONOS
+    u'\u2015'   #  0x008e -> HORIZONTAL BAR
+    u'\u0389'   #  0x008f -> GREEK CAPITAL LETTER ETA WITH TONOS
+    u'\u038a'   #  0x0090 -> GREEK CAPITAL LETTER IOTA WITH TONOS
+    u'\u03aa'   #  0x0091 -> GREEK CAPITAL LETTER IOTA WITH DIALYTIKA
+    u'\u038c'   #  0x0092 -> GREEK CAPITAL LETTER OMICRON WITH TONOS
+    u'\ufffe'   #  0x0093 -> UNDEFINED
+    u'\ufffe'   #  0x0094 -> UNDEFINED
+    u'\u038e'   #  0x0095 -> GREEK CAPITAL LETTER UPSILON WITH TONOS
+    u'\u03ab'   #  0x0096 -> GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA
+    u'\xa9'     #  0x0097 -> COPYRIGHT SIGN
+    u'\u038f'   #  0x0098 -> GREEK CAPITAL LETTER OMEGA WITH TONOS
+    u'\xb2'     #  0x0099 -> SUPERSCRIPT TWO
+    u'\xb3'     #  0x009a -> SUPERSCRIPT THREE
+    u'\u03ac'   #  0x009b -> GREEK SMALL LETTER ALPHA WITH TONOS
+    u'\xa3'     #  0x009c -> POUND SIGN
+    u'\u03ad'   #  0x009d -> GREEK SMALL LETTER EPSILON WITH TONOS
+    u'\u03ae'   #  0x009e -> GREEK SMALL LETTER ETA WITH TONOS
+    u'\u03af'   #  0x009f -> GREEK SMALL LETTER IOTA WITH TONOS
+    u'\u03ca'   #  0x00a0 -> GREEK SMALL LETTER IOTA WITH DIALYTIKA
+    u'\u0390'   #  0x00a1 -> GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
+    u'\u03cc'   #  0x00a2 -> GREEK SMALL LETTER OMICRON WITH TONOS
+    u'\u03cd'   #  0x00a3 -> GREEK SMALL LETTER UPSILON WITH TONOS
+    u'\u0391'   #  0x00a4 -> GREEK CAPITAL LETTER ALPHA
+    u'\u0392'   #  0x00a5 -> GREEK CAPITAL LETTER BETA
+    u'\u0393'   #  0x00a6 -> GREEK CAPITAL LETTER GAMMA
+    u'\u0394'   #  0x00a7 -> GREEK CAPITAL LETTER DELTA
+    u'\u0395'   #  0x00a8 -> GREEK CAPITAL LETTER EPSILON
+    u'\u0396'   #  0x00a9 -> GREEK CAPITAL LETTER ZETA
+    u'\u0397'   #  0x00aa -> GREEK CAPITAL LETTER ETA
+    u'\xbd'     #  0x00ab -> VULGAR FRACTION ONE HALF
+    u'\u0398'   #  0x00ac -> GREEK CAPITAL LETTER THETA
+    u'\u0399'   #  0x00ad -> GREEK CAPITAL LETTER IOTA
+    u'\xab'     #  0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xbb'     #  0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\u2591'   #  0x00b0 -> LIGHT SHADE
+    u'\u2592'   #  0x00b1 -> MEDIUM SHADE
+    u'\u2593'   #  0x00b2 -> DARK SHADE
+    u'\u2502'   #  0x00b3 -> BOX DRAWINGS LIGHT VERTICAL
+    u'\u2524'   #  0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT
+    u'\u039a'   #  0x00b5 -> GREEK CAPITAL LETTER KAPPA
+    u'\u039b'   #  0x00b6 -> GREEK CAPITAL LETTER LAMDA
+    u'\u039c'   #  0x00b7 -> GREEK CAPITAL LETTER MU
+    u'\u039d'   #  0x00b8 -> GREEK CAPITAL LETTER NU
+    u'\u2563'   #  0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+    u'\u2551'   #  0x00ba -> BOX DRAWINGS DOUBLE VERTICAL
+    u'\u2557'   #  0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT
+    u'\u255d'   #  0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT
+    u'\u039e'   #  0x00bd -> GREEK CAPITAL LETTER XI
+    u'\u039f'   #  0x00be -> GREEK CAPITAL LETTER OMICRON
+    u'\u2510'   #  0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT
+    u'\u2514'   #  0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT
+    u'\u2534'   #  0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL
+    u'\u252c'   #  0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+    u'\u251c'   #  0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+    u'\u2500'   #  0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL
+    u'\u253c'   #  0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+    u'\u03a0'   #  0x00c6 -> GREEK CAPITAL LETTER PI
+    u'\u03a1'   #  0x00c7 -> GREEK CAPITAL LETTER RHO
+    u'\u255a'   #  0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT
+    u'\u2554'   #  0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT
+    u'\u2569'   #  0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+    u'\u2566'   #  0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+    u'\u2560'   #  0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+    u'\u2550'   #  0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL
+    u'\u256c'   #  0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+    u'\u03a3'   #  0x00cf -> GREEK CAPITAL LETTER SIGMA
+    u'\u03a4'   #  0x00d0 -> GREEK CAPITAL LETTER TAU
+    u'\u03a5'   #  0x00d1 -> GREEK CAPITAL LETTER UPSILON
+    u'\u03a6'   #  0x00d2 -> GREEK CAPITAL LETTER PHI
+    u'\u03a7'   #  0x00d3 -> GREEK CAPITAL LETTER CHI
+    u'\u03a8'   #  0x00d4 -> GREEK CAPITAL LETTER PSI
+    u'\u03a9'   #  0x00d5 -> GREEK CAPITAL LETTER OMEGA
+    u'\u03b1'   #  0x00d6 -> GREEK SMALL LETTER ALPHA
+    u'\u03b2'   #  0x00d7 -> GREEK SMALL LETTER BETA
+    u'\u03b3'   #  0x00d8 -> GREEK SMALL LETTER GAMMA
+    u'\u2518'   #  0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT
+    u'\u250c'   #  0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT
+    u'\u2588'   #  0x00db -> FULL BLOCK
+    u'\u2584'   #  0x00dc -> LOWER HALF BLOCK
+    u'\u03b4'   #  0x00dd -> GREEK SMALL LETTER DELTA
+    u'\u03b5'   #  0x00de -> GREEK SMALL LETTER EPSILON
+    u'\u2580'   #  0x00df -> UPPER HALF BLOCK
+    u'\u03b6'   #  0x00e0 -> GREEK SMALL LETTER ZETA
+    u'\u03b7'   #  0x00e1 -> GREEK SMALL LETTER ETA
+    u'\u03b8'   #  0x00e2 -> GREEK SMALL LETTER THETA
+    u'\u03b9'   #  0x00e3 -> GREEK SMALL LETTER IOTA
+    u'\u03ba'   #  0x00e4 -> GREEK SMALL LETTER KAPPA
+    u'\u03bb'   #  0x00e5 -> GREEK SMALL LETTER LAMDA
+    u'\u03bc'   #  0x00e6 -> GREEK SMALL LETTER MU
+    u'\u03bd'   #  0x00e7 -> GREEK SMALL LETTER NU
+    u'\u03be'   #  0x00e8 -> GREEK SMALL LETTER XI
+    u'\u03bf'   #  0x00e9 -> GREEK SMALL LETTER OMICRON
+    u'\u03c0'   #  0x00ea -> GREEK SMALL LETTER PI
+    u'\u03c1'   #  0x00eb -> GREEK SMALL LETTER RHO
+    u'\u03c3'   #  0x00ec -> GREEK SMALL LETTER SIGMA
+    u'\u03c2'   #  0x00ed -> GREEK SMALL LETTER FINAL SIGMA
+    u'\u03c4'   #  0x00ee -> GREEK SMALL LETTER TAU
+    u'\u0384'   #  0x00ef -> GREEK TONOS
+    u'\xad'     #  0x00f0 -> SOFT HYPHEN
+    u'\xb1'     #  0x00f1 -> PLUS-MINUS SIGN
+    u'\u03c5'   #  0x00f2 -> GREEK SMALL LETTER UPSILON
+    u'\u03c6'   #  0x00f3 -> GREEK SMALL LETTER PHI
+    u'\u03c7'   #  0x00f4 -> GREEK SMALL LETTER CHI
+    u'\xa7'     #  0x00f5 -> SECTION SIGN
+    u'\u03c8'   #  0x00f6 -> GREEK SMALL LETTER PSI
+    u'\u0385'   #  0x00f7 -> GREEK DIALYTIKA TONOS
+    u'\xb0'     #  0x00f8 -> DEGREE SIGN
+    u'\xa8'     #  0x00f9 -> DIAERESIS
+    u'\u03c9'   #  0x00fa -> GREEK SMALL LETTER OMEGA
+    u'\u03cb'   #  0x00fb -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA
+    u'\u03b0'   #  0x00fc -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS
+    u'\u03ce'   #  0x00fd -> GREEK SMALL LETTER OMEGA WITH TONOS
+    u'\u25a0'   #  0x00fe -> BLACK SQUARE
+    u'\xa0'     #  0x00ff -> NO-BREAK SPACE
+)
+
+### Encoding Map
+
+encoding_map = {
+    0x0000: 0x0000,     #  NULL
+    0x0001: 0x0001,     #  START OF HEADING
+    0x0002: 0x0002,     #  START OF TEXT
+    0x0003: 0x0003,     #  END OF TEXT
+    0x0004: 0x0004,     #  END OF TRANSMISSION
+    0x0005: 0x0005,     #  ENQUIRY
+    0x0006: 0x0006,     #  ACKNOWLEDGE
+    0x0007: 0x0007,     #  BELL
+    0x0008: 0x0008,     #  BACKSPACE
+    0x0009: 0x0009,     #  HORIZONTAL TABULATION
+    0x000a: 0x000a,     #  LINE FEED
+    0x000b: 0x000b,     #  VERTICAL TABULATION
+    0x000c: 0x000c,     #  FORM FEED
+    0x000d: 0x000d,     #  CARRIAGE RETURN
+    0x000e: 0x000e,     #  SHIFT OUT
+    0x000f: 0x000f,     #  SHIFT IN
+    0x0010: 0x0010,     #  DATA LINK ESCAPE
+    0x0011: 0x0011,     #  DEVICE CONTROL ONE
+    0x0012: 0x0012,     #  DEVICE CONTROL TWO
+    0x0013: 0x0013,     #  DEVICE CONTROL THREE
+    0x0014: 0x0014,     #  DEVICE CONTROL FOUR
+    0x0015: 0x0015,     #  NEGATIVE ACKNOWLEDGE
+    0x0016: 0x0016,     #  SYNCHRONOUS IDLE
+    0x0017: 0x0017,     #  END OF TRANSMISSION BLOCK
+    0x0018: 0x0018,     #  CANCEL
+    0x0019: 0x0019,     #  END OF MEDIUM
+    0x001a: 0x001a,     #  SUBSTITUTE
+    0x001b: 0x001b,     #  ESCAPE
+    0x001c: 0x001c,     #  FILE SEPARATOR
+    0x001d: 0x001d,     #  GROUP SEPARATOR
+    0x001e: 0x001e,     #  RECORD SEPARATOR
+    0x001f: 0x001f,     #  UNIT SEPARATOR
+    0x0020: 0x0020,     #  SPACE
+    0x0021: 0x0021,     #  EXCLAMATION MARK
+    0x0022: 0x0022,     #  QUOTATION MARK
+    0x0023: 0x0023,     #  NUMBER SIGN
+    0x0024: 0x0024,     #  DOLLAR SIGN
+    0x0025: 0x0025,     #  PERCENT SIGN
+    0x0026: 0x0026,     #  AMPERSAND
+    0x0027: 0x0027,     #  APOSTROPHE
+    0x0028: 0x0028,     #  LEFT PARENTHESIS
+    0x0029: 0x0029,     #  RIGHT PARENTHESIS
+    0x002a: 0x002a,     #  ASTERISK
+    0x002b: 0x002b,     #  PLUS SIGN
+    0x002c: 0x002c,     #  COMMA
+    0x002d: 0x002d,     #  HYPHEN-MINUS
+    0x002e: 0x002e,     #  FULL STOP
+    0x002f: 0x002f,     #  SOLIDUS
+    0x0030: 0x0030,     #  DIGIT ZERO
+    0x0031: 0x0031,     #  DIGIT ONE
+    0x0032: 0x0032,     #  DIGIT TWO
+    0x0033: 0x0033,     #  DIGIT THREE
+    0x0034: 0x0034,     #  DIGIT FOUR
+    0x0035: 0x0035,     #  DIGIT FIVE
+    0x0036: 0x0036,     #  DIGIT SIX
+    0x0037: 0x0037,     #  DIGIT SEVEN
+    0x0038: 0x0038,     #  DIGIT EIGHT
+    0x0039: 0x0039,     #  DIGIT NINE
+    0x003a: 0x003a,     #  COLON
+    0x003b: 0x003b,     #  SEMICOLON
+    0x003c: 0x003c,     #  LESS-THAN SIGN
+    0x003d: 0x003d,     #  EQUALS SIGN
+    0x003e: 0x003e,     #  GREATER-THAN SIGN
+    0x003f: 0x003f,     #  QUESTION MARK
+    0x0040: 0x0040,     #  COMMERCIAL AT
+    0x0041: 0x0041,     #  LATIN CAPITAL LETTER A
+    0x0042: 0x0042,     #  LATIN CAPITAL LETTER B
+    0x0043: 0x0043,     #  LATIN CAPITAL LETTER C
+    0x0044: 0x0044,     #  LATIN CAPITAL LETTER D
+    0x0045: 0x0045,     #  LATIN CAPITAL LETTER E
+    0x0046: 0x0046,     #  LATIN CAPITAL LETTER F
+    0x0047: 0x0047,     #  LATIN CAPITAL LETTER G
+    0x0048: 0x0048,     #  LATIN CAPITAL LETTER H
+    0x0049: 0x0049,     #  LATIN CAPITAL LETTER I
+    0x004a: 0x004a,     #  LATIN CAPITAL LETTER J
+    0x004b: 0x004b,     #  LATIN CAPITAL LETTER K
+    0x004c: 0x004c,     #  LATIN CAPITAL LETTER L
+    0x004d: 0x004d,     #  LATIN CAPITAL LETTER M
+    0x004e: 0x004e,     #  LATIN CAPITAL LETTER N
+    0x004f: 0x004f,     #  LATIN CAPITAL LETTER O
+    0x0050: 0x0050,     #  LATIN CAPITAL LETTER P
+    0x0051: 0x0051,     #  LATIN CAPITAL LETTER Q
+    0x0052: 0x0052,     #  LATIN CAPITAL LETTER R
+    0x0053: 0x0053,     #  LATIN CAPITAL LETTER S
+    0x0054: 0x0054,     #  LATIN CAPITAL LETTER T
+    0x0055: 0x0055,     #  LATIN CAPITAL LETTER U
+    0x0056: 0x0056,     #  LATIN CAPITAL LETTER V
+    0x0057: 0x0057,     #  LATIN CAPITAL LETTER W
+    0x0058: 0x0058,     #  LATIN CAPITAL LETTER X
+    0x0059: 0x0059,     #  LATIN CAPITAL LETTER Y
+    0x005a: 0x005a,     #  LATIN CAPITAL LETTER Z
+    0x005b: 0x005b,     #  LEFT SQUARE BRACKET
+    0x005c: 0x005c,     #  REVERSE SOLIDUS
+    0x005d: 0x005d,     #  RIGHT SQUARE BRACKET
+    0x005e: 0x005e,     #  CIRCUMFLEX ACCENT
+    0x005f: 0x005f,     #  LOW LINE
+    0x0060: 0x0060,     #  GRAVE ACCENT
+    0x0061: 0x0061,     #  LATIN SMALL LETTER A
+    0x0062: 0x0062,     #  LATIN SMALL LETTER B
+    0x0063: 0x0063,     #  LATIN SMALL LETTER C
+    0x0064: 0x0064,     #  LATIN SMALL LETTER D
+    0x0065: 0x0065,     #  LATIN SMALL LETTER E
+    0x0066: 0x0066,     #  LATIN SMALL LETTER F
+    0x0067: 0x0067,     #  LATIN SMALL LETTER G
+    0x0068: 0x0068,     #  LATIN SMALL LETTER H
+    0x0069: 0x0069,     #  LATIN SMALL LETTER I
+    0x006a: 0x006a,     #  LATIN SMALL LETTER J
+    0x006b: 0x006b,     #  LATIN SMALL LETTER K
+    0x006c: 0x006c,     #  LATIN SMALL LETTER L
+    0x006d: 0x006d,     #  LATIN SMALL LETTER M
+    0x006e: 0x006e,     #  LATIN SMALL LETTER N
+    0x006f: 0x006f,     #  LATIN SMALL LETTER O
+    0x0070: 0x0070,     #  LATIN SMALL LETTER P
+    0x0071: 0x0071,     #  LATIN SMALL LETTER Q
+    0x0072: 0x0072,     #  LATIN SMALL LETTER R
+    0x0073: 0x0073,     #  LATIN SMALL LETTER S
+    0x0074: 0x0074,     #  LATIN SMALL LETTER T
+    0x0075: 0x0075,     #  LATIN SMALL LETTER U
+    0x0076: 0x0076,     #  LATIN SMALL LETTER V
+    0x0077: 0x0077,     #  LATIN SMALL LETTER W
+    0x0078: 0x0078,     #  LATIN SMALL LETTER X
+    0x0079: 0x0079,     #  LATIN SMALL LETTER Y
+    0x007a: 0x007a,     #  LATIN SMALL LETTER Z
+    0x007b: 0x007b,     #  LEFT CURLY BRACKET
+    0x007c: 0x007c,     #  VERTICAL LINE
+    0x007d: 0x007d,     #  RIGHT CURLY BRACKET
+    0x007e: 0x007e,     #  TILDE
+    0x007f: 0x007f,     #  DELETE
+    0x00a0: 0x00ff,     #  NO-BREAK SPACE
+    0x00a3: 0x009c,     #  POUND SIGN
+    0x00a6: 0x008a,     #  BROKEN BAR
+    0x00a7: 0x00f5,     #  SECTION SIGN
+    0x00a8: 0x00f9,     #  DIAERESIS
+    0x00a9: 0x0097,     #  COPYRIGHT SIGN
+    0x00ab: 0x00ae,     #  LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    0x00ac: 0x0089,     #  NOT SIGN
+    0x00ad: 0x00f0,     #  SOFT HYPHEN
+    0x00b0: 0x00f8,     #  DEGREE SIGN
+    0x00b1: 0x00f1,     #  PLUS-MINUS SIGN
+    0x00b2: 0x0099,     #  SUPERSCRIPT TWO
+    0x00b3: 0x009a,     #  SUPERSCRIPT THREE
+    0x00b7: 0x0088,     #  MIDDLE DOT
+    0x00bb: 0x00af,     #  RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    0x00bd: 0x00ab,     #  VULGAR FRACTION ONE HALF
+    0x0384: 0x00ef,     #  GREEK TONOS
+    0x0385: 0x00f7,     #  GREEK DIALYTIKA TONOS
+    0x0386: 0x0086,     #  GREEK CAPITAL LETTER ALPHA WITH TONOS
+    0x0388: 0x008d,     #  GREEK CAPITAL LETTER EPSILON WITH TONOS
+    0x0389: 0x008f,     #  GREEK CAPITAL LETTER ETA WITH TONOS
+    0x038a: 0x0090,     #  GREEK CAPITAL LETTER IOTA WITH TONOS
+    0x038c: 0x0092,     #  GREEK CAPITAL LETTER OMICRON WITH TONOS
+    0x038e: 0x0095,     #  GREEK CAPITAL LETTER UPSILON WITH TONOS
+    0x038f: 0x0098,     #  GREEK CAPITAL LETTER OMEGA WITH TONOS
+    0x0390: 0x00a1,     #  GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
+    0x0391: 0x00a4,     #  GREEK CAPITAL LETTER ALPHA
+    0x0392: 0x00a5,     #  GREEK CAPITAL LETTER BETA
+    0x0393: 0x00a6,     #  GREEK CAPITAL LETTER GAMMA
+    0x0394: 0x00a7,     #  GREEK CAPITAL LETTER DELTA
+    0x0395: 0x00a8,     #  GREEK CAPITAL LETTER EPSILON
+    0x0396: 0x00a9,     #  GREEK CAPITAL LETTER ZETA
+    0x0397: 0x00aa,     #  GREEK CAPITAL LETTER ETA
+    0x0398: 0x00ac,     #  GREEK CAPITAL LETTER THETA
+    0x0399: 0x00ad,     #  GREEK CAPITAL LETTER IOTA
+    0x039a: 0x00b5,     #  GREEK CAPITAL LETTER KAPPA
+    0x039b: 0x00b6,     #  GREEK CAPITAL LETTER LAMDA
+    0x039c: 0x00b7,     #  GREEK CAPITAL LETTER MU
+    0x039d: 0x00b8,     #  GREEK CAPITAL LETTER NU
+    0x039e: 0x00bd,     #  GREEK CAPITAL LETTER XI
+    0x039f: 0x00be,     #  GREEK CAPITAL LETTER OMICRON
+    0x03a0: 0x00c6,     #  GREEK CAPITAL LETTER PI
+    0x03a1: 0x00c7,     #  GREEK CAPITAL LETTER RHO
+    0x03a3: 0x00cf,     #  GREEK CAPITAL LETTER SIGMA
+    0x03a4: 0x00d0,     #  GREEK CAPITAL LETTER TAU
+    0x03a5: 0x00d1,     #  GREEK CAPITAL LETTER UPSILON
+    0x03a6: 0x00d2,     #  GREEK CAPITAL LETTER PHI
+    0x03a7: 0x00d3,     #  GREEK CAPITAL LETTER CHI
+    0x03a8: 0x00d4,     #  GREEK CAPITAL LETTER PSI
+    0x03a9: 0x00d5,     #  GREEK CAPITAL LETTER OMEGA
+    0x03aa: 0x0091,     #  GREEK CAPITAL LETTER IOTA WITH DIALYTIKA
+    0x03ab: 0x0096,     #  GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA
+    0x03ac: 0x009b,     #  GREEK SMALL LETTER ALPHA WITH TONOS
+    0x03ad: 0x009d,     #  GREEK SMALL LETTER EPSILON WITH TONOS
+    0x03ae: 0x009e,     #  GREEK SMALL LETTER ETA WITH TONOS
+    0x03af: 0x009f,     #  GREEK SMALL LETTER IOTA WITH TONOS
+    0x03b0: 0x00fc,     #  GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS
+    0x03b1: 0x00d6,     #  GREEK SMALL LETTER ALPHA
+    0x03b2: 0x00d7,     #  GREEK SMALL LETTER BETA
+    0x03b3: 0x00d8,     #  GREEK SMALL LETTER GAMMA
+    0x03b4: 0x00dd,     #  GREEK SMALL LETTER DELTA
+    0x03b5: 0x00de,     #  GREEK SMALL LETTER EPSILON
+    0x03b6: 0x00e0,     #  GREEK SMALL LETTER ZETA
+    0x03b7: 0x00e1,     #  GREEK SMALL LETTER ETA
+    0x03b8: 0x00e2,     #  GREEK SMALL LETTER THETA
+    0x03b9: 0x00e3,     #  GREEK SMALL LETTER IOTA
+    0x03ba: 0x00e4,     #  GREEK SMALL LETTER KAPPA
+    0x03bb: 0x00e5,     #  GREEK SMALL LETTER LAMDA
+    0x03bc: 0x00e6,     #  GREEK SMALL LETTER MU
+    0x03bd: 0x00e7,     #  GREEK SMALL LETTER NU
+    0x03be: 0x00e8,     #  GREEK SMALL LETTER XI
+    0x03bf: 0x00e9,     #  GREEK SMALL LETTER OMICRON
+    0x03c0: 0x00ea,     #  GREEK SMALL LETTER PI
+    0x03c1: 0x00eb,     #  GREEK SMALL LETTER RHO
+    0x03c2: 0x00ed,     #  GREEK SMALL LETTER FINAL SIGMA
+    0x03c3: 0x00ec,     #  GREEK SMALL LETTER SIGMA
+    0x03c4: 0x00ee,     #  GREEK SMALL LETTER TAU
+    0x03c5: 0x00f2,     #  GREEK SMALL LETTER UPSILON
+    0x03c6: 0x00f3,     #  GREEK SMALL LETTER PHI
+    0x03c7: 0x00f4,     #  GREEK SMALL LETTER CHI
+    0x03c8: 0x00f6,     #  GREEK SMALL LETTER PSI
+    0x03c9: 0x00fa,     #  GREEK SMALL LETTER OMEGA
+    0x03ca: 0x00a0,     #  GREEK SMALL LETTER IOTA WITH DIALYTIKA
+    0x03cb: 0x00fb,     #  GREEK SMALL LETTER UPSILON WITH DIALYTIKA
+    0x03cc: 0x00a2,     #  GREEK SMALL LETTER OMICRON WITH TONOS
+    0x03cd: 0x00a3,     #  GREEK SMALL LETTER UPSILON WITH TONOS
+    0x03ce: 0x00fd,     #  GREEK SMALL LETTER OMEGA WITH TONOS
+    0x2015: 0x008e,     #  HORIZONTAL BAR
+    0x2018: 0x008b,     #  LEFT SINGLE QUOTATION MARK
+    0x2019: 0x008c,     #  RIGHT SINGLE QUOTATION MARK
+    0x2500: 0x00c4,     #  BOX DRAWINGS LIGHT HORIZONTAL
+    0x2502: 0x00b3,     #  BOX DRAWINGS LIGHT VERTICAL
+    0x250c: 0x00da,     #  BOX DRAWINGS LIGHT DOWN AND RIGHT
+    0x2510: 0x00bf,     #  BOX DRAWINGS LIGHT DOWN AND LEFT
+    0x2514: 0x00c0,     #  BOX DRAWINGS LIGHT UP AND RIGHT
+    0x2518: 0x00d9,     #  BOX DRAWINGS LIGHT UP AND LEFT
+    0x251c: 0x00c3,     #  BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+    0x2524: 0x00b4,     #  BOX DRAWINGS LIGHT VERTICAL AND LEFT
+    0x252c: 0x00c2,     #  BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+    0x2534: 0x00c1,     #  BOX DRAWINGS LIGHT UP AND HORIZONTAL
+    0x253c: 0x00c5,     #  BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+    0x2550: 0x00cd,     #  BOX DRAWINGS DOUBLE HORIZONTAL
+    0x2551: 0x00ba,     #  BOX DRAWINGS DOUBLE VERTICAL
+    0x2554: 0x00c9,     #  BOX DRAWINGS DOUBLE DOWN AND RIGHT
+    0x2557: 0x00bb,     #  BOX DRAWINGS DOUBLE DOWN AND LEFT
+    0x255a: 0x00c8,     #  BOX DRAWINGS DOUBLE UP AND RIGHT
+    0x255d: 0x00bc,     #  BOX DRAWINGS DOUBLE UP AND LEFT
+    0x2560: 0x00cc,     #  BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+    0x2563: 0x00b9,     #  BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+    0x2566: 0x00cb,     #  BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+    0x2569: 0x00ca,     #  BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+    0x256c: 0x00ce,     #  BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+    0x2580: 0x00df,     #  UPPER HALF BLOCK
+    0x2584: 0x00dc,     #  LOWER HALF BLOCK
+    0x2588: 0x00db,     #  FULL BLOCK
+    0x2591: 0x00b0,     #  LIGHT SHADE
+    0x2592: 0x00b1,     #  MEDIUM SHADE
+    0x2593: 0x00b2,     #  DARK SHADE
+    0x25a0: 0x00fe,     #  BLACK SQUARE
+}

Added: vendor/Python/current/Lib/encodings/cp874.py
===================================================================
--- vendor/Python/current/Lib/encodings/cp874.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/cp874.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,307 @@
+""" Python Character Mapping Codec cp874 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP874.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_table)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_table)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='cp874',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x00 -> NULL
+    u'\x01'     #  0x01 -> START OF HEADING
+    u'\x02'     #  0x02 -> START OF TEXT
+    u'\x03'     #  0x03 -> END OF TEXT
+    u'\x04'     #  0x04 -> END OF TRANSMISSION
+    u'\x05'     #  0x05 -> ENQUIRY
+    u'\x06'     #  0x06 -> ACKNOWLEDGE
+    u'\x07'     #  0x07 -> BELL
+    u'\x08'     #  0x08 -> BACKSPACE
+    u'\t'       #  0x09 -> HORIZONTAL TABULATION
+    u'\n'       #  0x0A -> LINE FEED
+    u'\x0b'     #  0x0B -> VERTICAL TABULATION
+    u'\x0c'     #  0x0C -> FORM FEED
+    u'\r'       #  0x0D -> CARRIAGE RETURN
+    u'\x0e'     #  0x0E -> SHIFT OUT
+    u'\x0f'     #  0x0F -> SHIFT IN
+    u'\x10'     #  0x10 -> DATA LINK ESCAPE
+    u'\x11'     #  0x11 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x12 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x13 -> DEVICE CONTROL THREE
+    u'\x14'     #  0x14 -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x15 -> NEGATIVE ACKNOWLEDGE
+    u'\x16'     #  0x16 -> SYNCHRONOUS IDLE
+    u'\x17'     #  0x17 -> END OF TRANSMISSION BLOCK
+    u'\x18'     #  0x18 -> CANCEL
+    u'\x19'     #  0x19 -> END OF MEDIUM
+    u'\x1a'     #  0x1A -> SUBSTITUTE
+    u'\x1b'     #  0x1B -> ESCAPE
+    u'\x1c'     #  0x1C -> FILE SEPARATOR
+    u'\x1d'     #  0x1D -> GROUP SEPARATOR
+    u'\x1e'     #  0x1E -> RECORD SEPARATOR
+    u'\x1f'     #  0x1F -> UNIT SEPARATOR
+    u' '        #  0x20 -> SPACE
+    u'!'        #  0x21 -> EXCLAMATION MARK
+    u'"'        #  0x22 -> QUOTATION MARK
+    u'#'        #  0x23 -> NUMBER SIGN
+    u'$'        #  0x24 -> DOLLAR SIGN
+    u'%'        #  0x25 -> PERCENT SIGN
+    u'&'        #  0x26 -> AMPERSAND
+    u"'"        #  0x27 -> APOSTROPHE
+    u'('        #  0x28 -> LEFT PARENTHESIS
+    u')'        #  0x29 -> RIGHT PARENTHESIS
+    u'*'        #  0x2A -> ASTERISK
+    u'+'        #  0x2B -> PLUS SIGN
+    u','        #  0x2C -> COMMA
+    u'-'        #  0x2D -> HYPHEN-MINUS
+    u'.'        #  0x2E -> FULL STOP
+    u'/'        #  0x2F -> SOLIDUS
+    u'0'        #  0x30 -> DIGIT ZERO
+    u'1'        #  0x31 -> DIGIT ONE
+    u'2'        #  0x32 -> DIGIT TWO
+    u'3'        #  0x33 -> DIGIT THREE
+    u'4'        #  0x34 -> DIGIT FOUR
+    u'5'        #  0x35 -> DIGIT FIVE
+    u'6'        #  0x36 -> DIGIT SIX
+    u'7'        #  0x37 -> DIGIT SEVEN
+    u'8'        #  0x38 -> DIGIT EIGHT
+    u'9'        #  0x39 -> DIGIT NINE
+    u':'        #  0x3A -> COLON
+    u';'        #  0x3B -> SEMICOLON
+    u'<'        #  0x3C -> LESS-THAN SIGN
+    u'='        #  0x3D -> EQUALS SIGN
+    u'>'        #  0x3E -> GREATER-THAN SIGN
+    u'?'        #  0x3F -> QUESTION MARK
+    u'@'        #  0x40 -> COMMERCIAL AT
+    u'A'        #  0x41 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x42 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x43 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x44 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x45 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x46 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x47 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x48 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x49 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x4A -> LATIN CAPITAL LETTER J
+    u'K'        #  0x4B -> LATIN CAPITAL LETTER K
+    u'L'        #  0x4C -> LATIN CAPITAL LETTER L
+    u'M'        #  0x4D -> LATIN CAPITAL LETTER M
+    u'N'        #  0x4E -> LATIN CAPITAL LETTER N
+    u'O'        #  0x4F -> LATIN CAPITAL LETTER O
+    u'P'        #  0x50 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x51 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x52 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x53 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x54 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x55 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x56 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x57 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x58 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x59 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x5A -> LATIN CAPITAL LETTER Z
+    u'['        #  0x5B -> LEFT SQUARE BRACKET
+    u'\\'       #  0x5C -> REVERSE SOLIDUS
+    u']'        #  0x5D -> RIGHT SQUARE BRACKET
+    u'^'        #  0x5E -> CIRCUMFLEX ACCENT
+    u'_'        #  0x5F -> LOW LINE
+    u'`'        #  0x60 -> GRAVE ACCENT
+    u'a'        #  0x61 -> LATIN SMALL LETTER A
+    u'b'        #  0x62 -> LATIN SMALL LETTER B
+    u'c'        #  0x63 -> LATIN SMALL LETTER C
+    u'd'        #  0x64 -> LATIN SMALL LETTER D
+    u'e'        #  0x65 -> LATIN SMALL LETTER E
+    u'f'        #  0x66 -> LATIN SMALL LETTER F
+    u'g'        #  0x67 -> LATIN SMALL LETTER G
+    u'h'        #  0x68 -> LATIN SMALL LETTER H
+    u'i'        #  0x69 -> LATIN SMALL LETTER I
+    u'j'        #  0x6A -> LATIN SMALL LETTER J
+    u'k'        #  0x6B -> LATIN SMALL LETTER K
+    u'l'        #  0x6C -> LATIN SMALL LETTER L
+    u'm'        #  0x6D -> LATIN SMALL LETTER M
+    u'n'        #  0x6E -> LATIN SMALL LETTER N
+    u'o'        #  0x6F -> LATIN SMALL LETTER O
+    u'p'        #  0x70 -> LATIN SMALL LETTER P
+    u'q'        #  0x71 -> LATIN SMALL LETTER Q
+    u'r'        #  0x72 -> LATIN SMALL LETTER R
+    u's'        #  0x73 -> LATIN SMALL LETTER S
+    u't'        #  0x74 -> LATIN SMALL LETTER T
+    u'u'        #  0x75 -> LATIN SMALL LETTER U
+    u'v'        #  0x76 -> LATIN SMALL LETTER V
+    u'w'        #  0x77 -> LATIN SMALL LETTER W
+    u'x'        #  0x78 -> LATIN SMALL LETTER X
+    u'y'        #  0x79 -> LATIN SMALL LETTER Y
+    u'z'        #  0x7A -> LATIN SMALL LETTER Z
+    u'{'        #  0x7B -> LEFT CURLY BRACKET
+    u'|'        #  0x7C -> VERTICAL LINE
+    u'}'        #  0x7D -> RIGHT CURLY BRACKET
+    u'~'        #  0x7E -> TILDE
+    u'\x7f'     #  0x7F -> DELETE
+    u'\u20ac'   #  0x80 -> EURO SIGN
+    u'\ufffe'   #  0x81 -> UNDEFINED
+    u'\ufffe'   #  0x82 -> UNDEFINED
+    u'\ufffe'   #  0x83 -> UNDEFINED
+    u'\ufffe'   #  0x84 -> UNDEFINED
+    u'\u2026'   #  0x85 -> HORIZONTAL ELLIPSIS
+    u'\ufffe'   #  0x86 -> UNDEFINED
+    u'\ufffe'   #  0x87 -> UNDEFINED
+    u'\ufffe'   #  0x88 -> UNDEFINED
+    u'\ufffe'   #  0x89 -> UNDEFINED
+    u'\ufffe'   #  0x8A -> UNDEFINED
+    u'\ufffe'   #  0x8B -> UNDEFINED
+    u'\ufffe'   #  0x8C -> UNDEFINED
+    u'\ufffe'   #  0x8D -> UNDEFINED
+    u'\ufffe'   #  0x8E -> UNDEFINED
+    u'\ufffe'   #  0x8F -> UNDEFINED
+    u'\ufffe'   #  0x90 -> UNDEFINED
+    u'\u2018'   #  0x91 -> LEFT SINGLE QUOTATION MARK
+    u'\u2019'   #  0x92 -> RIGHT SINGLE QUOTATION MARK
+    u'\u201c'   #  0x93 -> LEFT DOUBLE QUOTATION MARK
+    u'\u201d'   #  0x94 -> RIGHT DOUBLE QUOTATION MARK
+    u'\u2022'   #  0x95 -> BULLET
+    u'\u2013'   #  0x96 -> EN DASH
+    u'\u2014'   #  0x97 -> EM DASH
+    u'\ufffe'   #  0x98 -> UNDEFINED
+    u'\ufffe'   #  0x99 -> UNDEFINED
+    u'\ufffe'   #  0x9A -> UNDEFINED
+    u'\ufffe'   #  0x9B -> UNDEFINED
+    u'\ufffe'   #  0x9C -> UNDEFINED
+    u'\ufffe'   #  0x9D -> UNDEFINED
+    u'\ufffe'   #  0x9E -> UNDEFINED
+    u'\ufffe'   #  0x9F -> UNDEFINED
+    u'\xa0'     #  0xA0 -> NO-BREAK SPACE
+    u'\u0e01'   #  0xA1 -> THAI CHARACTER KO KAI
+    u'\u0e02'   #  0xA2 -> THAI CHARACTER KHO KHAI
+    u'\u0e03'   #  0xA3 -> THAI CHARACTER KHO KHUAT
+    u'\u0e04'   #  0xA4 -> THAI CHARACTER KHO KHWAI
+    u'\u0e05'   #  0xA5 -> THAI CHARACTER KHO KHON
+    u'\u0e06'   #  0xA6 -> THAI CHARACTER KHO RAKHANG
+    u'\u0e07'   #  0xA7 -> THAI CHARACTER NGO NGU
+    u'\u0e08'   #  0xA8 -> THAI CHARACTER CHO CHAN
+    u'\u0e09'   #  0xA9 -> THAI CHARACTER CHO CHING
+    u'\u0e0a'   #  0xAA -> THAI CHARACTER CHO CHANG
+    u'\u0e0b'   #  0xAB -> THAI CHARACTER SO SO
+    u'\u0e0c'   #  0xAC -> THAI CHARACTER CHO CHOE
+    u'\u0e0d'   #  0xAD -> THAI CHARACTER YO YING
+    u'\u0e0e'   #  0xAE -> THAI CHARACTER DO CHADA
+    u'\u0e0f'   #  0xAF -> THAI CHARACTER TO PATAK
+    u'\u0e10'   #  0xB0 -> THAI CHARACTER THO THAN
+    u'\u0e11'   #  0xB1 -> THAI CHARACTER THO NANGMONTHO
+    u'\u0e12'   #  0xB2 -> THAI CHARACTER THO PHUTHAO
+    u'\u0e13'   #  0xB3 -> THAI CHARACTER NO NEN
+    u'\u0e14'   #  0xB4 -> THAI CHARACTER DO DEK
+    u'\u0e15'   #  0xB5 -> THAI CHARACTER TO TAO
+    u'\u0e16'   #  0xB6 -> THAI CHARACTER THO THUNG
+    u'\u0e17'   #  0xB7 -> THAI CHARACTER THO THAHAN
+    u'\u0e18'   #  0xB8 -> THAI CHARACTER THO THONG
+    u'\u0e19'   #  0xB9 -> THAI CHARACTER NO NU
+    u'\u0e1a'   #  0xBA -> THAI CHARACTER BO BAIMAI
+    u'\u0e1b'   #  0xBB -> THAI CHARACTER PO PLA
+    u'\u0e1c'   #  0xBC -> THAI CHARACTER PHO PHUNG
+    u'\u0e1d'   #  0xBD -> THAI CHARACTER FO FA
+    u'\u0e1e'   #  0xBE -> THAI CHARACTER PHO PHAN
+    u'\u0e1f'   #  0xBF -> THAI CHARACTER FO FAN
+    u'\u0e20'   #  0xC0 -> THAI CHARACTER PHO SAMPHAO
+    u'\u0e21'   #  0xC1 -> THAI CHARACTER MO MA
+    u'\u0e22'   #  0xC2 -> THAI CHARACTER YO YAK
+    u'\u0e23'   #  0xC3 -> THAI CHARACTER RO RUA
+    u'\u0e24'   #  0xC4 -> THAI CHARACTER RU
+    u'\u0e25'   #  0xC5 -> THAI CHARACTER LO LING
+    u'\u0e26'   #  0xC6 -> THAI CHARACTER LU
+    u'\u0e27'   #  0xC7 -> THAI CHARACTER WO WAEN
+    u'\u0e28'   #  0xC8 -> THAI CHARACTER SO SALA
+    u'\u0e29'   #  0xC9 -> THAI CHARACTER SO RUSI
+    u'\u0e2a'   #  0xCA -> THAI CHARACTER SO SUA
+    u'\u0e2b'   #  0xCB -> THAI CHARACTER HO HIP
+    u'\u0e2c'   #  0xCC -> THAI CHARACTER LO CHULA
+    u'\u0e2d'   #  0xCD -> THAI CHARACTER O ANG
+    u'\u0e2e'   #  0xCE -> THAI CHARACTER HO NOKHUK
+    u'\u0e2f'   #  0xCF -> THAI CHARACTER PAIYANNOI
+    u'\u0e30'   #  0xD0 -> THAI CHARACTER SARA A
+    u'\u0e31'   #  0xD1 -> THAI CHARACTER MAI HAN-AKAT
+    u'\u0e32'   #  0xD2 -> THAI CHARACTER SARA AA
+    u'\u0e33'   #  0xD3 -> THAI CHARACTER SARA AM
+    u'\u0e34'   #  0xD4 -> THAI CHARACTER SARA I
+    u'\u0e35'   #  0xD5 -> THAI CHARACTER SARA II
+    u'\u0e36'   #  0xD6 -> THAI CHARACTER SARA UE
+    u'\u0e37'   #  0xD7 -> THAI CHARACTER SARA UEE
+    u'\u0e38'   #  0xD8 -> THAI CHARACTER SARA U
+    u'\u0e39'   #  0xD9 -> THAI CHARACTER SARA UU
+    u'\u0e3a'   #  0xDA -> THAI CHARACTER PHINTHU
+    u'\ufffe'   #  0xDB -> UNDEFINED
+    u'\ufffe'   #  0xDC -> UNDEFINED
+    u'\ufffe'   #  0xDD -> UNDEFINED
+    u'\ufffe'   #  0xDE -> UNDEFINED
+    u'\u0e3f'   #  0xDF -> THAI CURRENCY SYMBOL BAHT
+    u'\u0e40'   #  0xE0 -> THAI CHARACTER SARA E
+    u'\u0e41'   #  0xE1 -> THAI CHARACTER SARA AE
+    u'\u0e42'   #  0xE2 -> THAI CHARACTER SARA O
+    u'\u0e43'   #  0xE3 -> THAI CHARACTER SARA AI MAIMUAN
+    u'\u0e44'   #  0xE4 -> THAI CHARACTER SARA AI MAIMALAI
+    u'\u0e45'   #  0xE5 -> THAI CHARACTER LAKKHANGYAO
+    u'\u0e46'   #  0xE6 -> THAI CHARACTER MAIYAMOK
+    u'\u0e47'   #  0xE7 -> THAI CHARACTER MAITAIKHU
+    u'\u0e48'   #  0xE8 -> THAI CHARACTER MAI EK
+    u'\u0e49'   #  0xE9 -> THAI CHARACTER MAI THO
+    u'\u0e4a'   #  0xEA -> THAI CHARACTER MAI TRI
+    u'\u0e4b'   #  0xEB -> THAI CHARACTER MAI CHATTAWA
+    u'\u0e4c'   #  0xEC -> THAI CHARACTER THANTHAKHAT
+    u'\u0e4d'   #  0xED -> THAI CHARACTER NIKHAHIT
+    u'\u0e4e'   #  0xEE -> THAI CHARACTER YAMAKKAN
+    u'\u0e4f'   #  0xEF -> THAI CHARACTER FONGMAN
+    u'\u0e50'   #  0xF0 -> THAI DIGIT ZERO
+    u'\u0e51'   #  0xF1 -> THAI DIGIT ONE
+    u'\u0e52'   #  0xF2 -> THAI DIGIT TWO
+    u'\u0e53'   #  0xF3 -> THAI DIGIT THREE
+    u'\u0e54'   #  0xF4 -> THAI DIGIT FOUR
+    u'\u0e55'   #  0xF5 -> THAI DIGIT FIVE
+    u'\u0e56'   #  0xF6 -> THAI DIGIT SIX
+    u'\u0e57'   #  0xF7 -> THAI DIGIT SEVEN
+    u'\u0e58'   #  0xF8 -> THAI DIGIT EIGHT
+    u'\u0e59'   #  0xF9 -> THAI DIGIT NINE
+    u'\u0e5a'   #  0xFA -> THAI CHARACTER ANGKHANKHU
+    u'\u0e5b'   #  0xFB -> THAI CHARACTER KHOMUT
+    u'\ufffe'   #  0xFC -> UNDEFINED
+    u'\ufffe'   #  0xFD -> UNDEFINED
+    u'\ufffe'   #  0xFE -> UNDEFINED
+    u'\ufffe'   #  0xFF -> UNDEFINED
+)
+
+### Encoding table
+encoding_table=codecs.charmap_build(decoding_table)

Added: vendor/Python/current/Lib/encodings/cp875.py
===================================================================
--- vendor/Python/current/Lib/encodings/cp875.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/cp875.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,307 @@
+""" Python Character Mapping Codec cp875 generated from 'MAPPINGS/VENDORS/MICSFT/EBCDIC/CP875.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_table)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_table)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='cp875',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x00 -> NULL
+    u'\x01'     #  0x01 -> START OF HEADING
+    u'\x02'     #  0x02 -> START OF TEXT
+    u'\x03'     #  0x03 -> END OF TEXT
+    u'\x9c'     #  0x04 -> CONTROL
+    u'\t'       #  0x05 -> HORIZONTAL TABULATION
+    u'\x86'     #  0x06 -> CONTROL
+    u'\x7f'     #  0x07 -> DELETE
+    u'\x97'     #  0x08 -> CONTROL
+    u'\x8d'     #  0x09 -> CONTROL
+    u'\x8e'     #  0x0A -> CONTROL
+    u'\x0b'     #  0x0B -> VERTICAL TABULATION
+    u'\x0c'     #  0x0C -> FORM FEED
+    u'\r'       #  0x0D -> CARRIAGE RETURN
+    u'\x0e'     #  0x0E -> SHIFT OUT
+    u'\x0f'     #  0x0F -> SHIFT IN
+    u'\x10'     #  0x10 -> DATA LINK ESCAPE
+    u'\x11'     #  0x11 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x12 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x13 -> DEVICE CONTROL THREE
+    u'\x9d'     #  0x14 -> CONTROL
+    u'\x85'     #  0x15 -> CONTROL
+    u'\x08'     #  0x16 -> BACKSPACE
+    u'\x87'     #  0x17 -> CONTROL
+    u'\x18'     #  0x18 -> CANCEL
+    u'\x19'     #  0x19 -> END OF MEDIUM
+    u'\x92'     #  0x1A -> CONTROL
+    u'\x8f'     #  0x1B -> CONTROL
+    u'\x1c'     #  0x1C -> FILE SEPARATOR
+    u'\x1d'     #  0x1D -> GROUP SEPARATOR
+    u'\x1e'     #  0x1E -> RECORD SEPARATOR
+    u'\x1f'     #  0x1F -> UNIT SEPARATOR
+    u'\x80'     #  0x20 -> CONTROL
+    u'\x81'     #  0x21 -> CONTROL
+    u'\x82'     #  0x22 -> CONTROL
+    u'\x83'     #  0x23 -> CONTROL
+    u'\x84'     #  0x24 -> CONTROL
+    u'\n'       #  0x25 -> LINE FEED
+    u'\x17'     #  0x26 -> END OF TRANSMISSION BLOCK
+    u'\x1b'     #  0x27 -> ESCAPE
+    u'\x88'     #  0x28 -> CONTROL
+    u'\x89'     #  0x29 -> CONTROL
+    u'\x8a'     #  0x2A -> CONTROL
+    u'\x8b'     #  0x2B -> CONTROL
+    u'\x8c'     #  0x2C -> CONTROL
+    u'\x05'     #  0x2D -> ENQUIRY
+    u'\x06'     #  0x2E -> ACKNOWLEDGE
+    u'\x07'     #  0x2F -> BELL
+    u'\x90'     #  0x30 -> CONTROL
+    u'\x91'     #  0x31 -> CONTROL
+    u'\x16'     #  0x32 -> SYNCHRONOUS IDLE
+    u'\x93'     #  0x33 -> CONTROL
+    u'\x94'     #  0x34 -> CONTROL
+    u'\x95'     #  0x35 -> CONTROL
+    u'\x96'     #  0x36 -> CONTROL
+    u'\x04'     #  0x37 -> END OF TRANSMISSION
+    u'\x98'     #  0x38 -> CONTROL
+    u'\x99'     #  0x39 -> CONTROL
+    u'\x9a'     #  0x3A -> CONTROL
+    u'\x9b'     #  0x3B -> CONTROL
+    u'\x14'     #  0x3C -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x3D -> NEGATIVE ACKNOWLEDGE
+    u'\x9e'     #  0x3E -> CONTROL
+    u'\x1a'     #  0x3F -> SUBSTITUTE
+    u' '        #  0x40 -> SPACE
+    u'\u0391'   #  0x41 -> GREEK CAPITAL LETTER ALPHA
+    u'\u0392'   #  0x42 -> GREEK CAPITAL LETTER BETA
+    u'\u0393'   #  0x43 -> GREEK CAPITAL LETTER GAMMA
+    u'\u0394'   #  0x44 -> GREEK CAPITAL LETTER DELTA
+    u'\u0395'   #  0x45 -> GREEK CAPITAL LETTER EPSILON
+    u'\u0396'   #  0x46 -> GREEK CAPITAL LETTER ZETA
+    u'\u0397'   #  0x47 -> GREEK CAPITAL LETTER ETA
+    u'\u0398'   #  0x48 -> GREEK CAPITAL LETTER THETA
+    u'\u0399'   #  0x49 -> GREEK CAPITAL LETTER IOTA
+    u'['        #  0x4A -> LEFT SQUARE BRACKET
+    u'.'        #  0x4B -> FULL STOP
+    u'<'        #  0x4C -> LESS-THAN SIGN
+    u'('        #  0x4D -> LEFT PARENTHESIS
+    u'+'        #  0x4E -> PLUS SIGN
+    u'!'        #  0x4F -> EXCLAMATION MARK
+    u'&'        #  0x50 -> AMPERSAND
+    u'\u039a'   #  0x51 -> GREEK CAPITAL LETTER KAPPA
+    u'\u039b'   #  0x52 -> GREEK CAPITAL LETTER LAMDA
+    u'\u039c'   #  0x53 -> GREEK CAPITAL LETTER MU
+    u'\u039d'   #  0x54 -> GREEK CAPITAL LETTER NU
+    u'\u039e'   #  0x55 -> GREEK CAPITAL LETTER XI
+    u'\u039f'   #  0x56 -> GREEK CAPITAL LETTER OMICRON
+    u'\u03a0'   #  0x57 -> GREEK CAPITAL LETTER PI
+    u'\u03a1'   #  0x58 -> GREEK CAPITAL LETTER RHO
+    u'\u03a3'   #  0x59 -> GREEK CAPITAL LETTER SIGMA
+    u']'        #  0x5A -> RIGHT SQUARE BRACKET
+    u'$'        #  0x5B -> DOLLAR SIGN
+    u'*'        #  0x5C -> ASTERISK
+    u')'        #  0x5D -> RIGHT PARENTHESIS
+    u';'        #  0x5E -> SEMICOLON
+    u'^'        #  0x5F -> CIRCUMFLEX ACCENT
+    u'-'        #  0x60 -> HYPHEN-MINUS
+    u'/'        #  0x61 -> SOLIDUS
+    u'\u03a4'   #  0x62 -> GREEK CAPITAL LETTER TAU
+    u'\u03a5'   #  0x63 -> GREEK CAPITAL LETTER UPSILON
+    u'\u03a6'   #  0x64 -> GREEK CAPITAL LETTER PHI
+    u'\u03a7'   #  0x65 -> GREEK CAPITAL LETTER CHI
+    u'\u03a8'   #  0x66 -> GREEK CAPITAL LETTER PSI
+    u'\u03a9'   #  0x67 -> GREEK CAPITAL LETTER OMEGA
+    u'\u03aa'   #  0x68 -> GREEK CAPITAL LETTER IOTA WITH DIALYTIKA
+    u'\u03ab'   #  0x69 -> GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA
+    u'|'        #  0x6A -> VERTICAL LINE
+    u','        #  0x6B -> COMMA
+    u'%'        #  0x6C -> PERCENT SIGN
+    u'_'        #  0x6D -> LOW LINE
+    u'>'        #  0x6E -> GREATER-THAN SIGN
+    u'?'        #  0x6F -> QUESTION MARK
+    u'\xa8'     #  0x70 -> DIAERESIS
+    u'\u0386'   #  0x71 -> GREEK CAPITAL LETTER ALPHA WITH TONOS
+    u'\u0388'   #  0x72 -> GREEK CAPITAL LETTER EPSILON WITH TONOS
+    u'\u0389'   #  0x73 -> GREEK CAPITAL LETTER ETA WITH TONOS
+    u'\xa0'     #  0x74 -> NO-BREAK SPACE
+    u'\u038a'   #  0x75 -> GREEK CAPITAL LETTER IOTA WITH TONOS
+    u'\u038c'   #  0x76 -> GREEK CAPITAL LETTER OMICRON WITH TONOS
+    u'\u038e'   #  0x77 -> GREEK CAPITAL LETTER UPSILON WITH TONOS
+    u'\u038f'   #  0x78 -> GREEK CAPITAL LETTER OMEGA WITH TONOS
+    u'`'        #  0x79 -> GRAVE ACCENT
+    u':'        #  0x7A -> COLON
+    u'#'        #  0x7B -> NUMBER SIGN
+    u'@'        #  0x7C -> COMMERCIAL AT
+    u"'"        #  0x7D -> APOSTROPHE
+    u'='        #  0x7E -> EQUALS SIGN
+    u'"'        #  0x7F -> QUOTATION MARK
+    u'\u0385'   #  0x80 -> GREEK DIALYTIKA TONOS
+    u'a'        #  0x81 -> LATIN SMALL LETTER A
+    u'b'        #  0x82 -> LATIN SMALL LETTER B
+    u'c'        #  0x83 -> LATIN SMALL LETTER C
+    u'd'        #  0x84 -> LATIN SMALL LETTER D
+    u'e'        #  0x85 -> LATIN SMALL LETTER E
+    u'f'        #  0x86 -> LATIN SMALL LETTER F
+    u'g'        #  0x87 -> LATIN SMALL LETTER G
+    u'h'        #  0x88 -> LATIN SMALL LETTER H
+    u'i'        #  0x89 -> LATIN SMALL LETTER I
+    u'\u03b1'   #  0x8A -> GREEK SMALL LETTER ALPHA
+    u'\u03b2'   #  0x8B -> GREEK SMALL LETTER BETA
+    u'\u03b3'   #  0x8C -> GREEK SMALL LETTER GAMMA
+    u'\u03b4'   #  0x8D -> GREEK SMALL LETTER DELTA
+    u'\u03b5'   #  0x8E -> GREEK SMALL LETTER EPSILON
+    u'\u03b6'   #  0x8F -> GREEK SMALL LETTER ZETA
+    u'\xb0'     #  0x90 -> DEGREE SIGN
+    u'j'        #  0x91 -> LATIN SMALL LETTER J
+    u'k'        #  0x92 -> LATIN SMALL LETTER K
+    u'l'        #  0x93 -> LATIN SMALL LETTER L
+    u'm'        #  0x94 -> LATIN SMALL LETTER M
+    u'n'        #  0x95 -> LATIN SMALL LETTER N
+    u'o'        #  0x96 -> LATIN SMALL LETTER O
+    u'p'        #  0x97 -> LATIN SMALL LETTER P
+    u'q'        #  0x98 -> LATIN SMALL LETTER Q
+    u'r'        #  0x99 -> LATIN SMALL LETTER R
+    u'\u03b7'   #  0x9A -> GREEK SMALL LETTER ETA
+    u'\u03b8'   #  0x9B -> GREEK SMALL LETTER THETA
+    u'\u03b9'   #  0x9C -> GREEK SMALL LETTER IOTA
+    u'\u03ba'   #  0x9D -> GREEK SMALL LETTER KAPPA
+    u'\u03bb'   #  0x9E -> GREEK SMALL LETTER LAMDA
+    u'\u03bc'   #  0x9F -> GREEK SMALL LETTER MU
+    u'\xb4'     #  0xA0 -> ACUTE ACCENT
+    u'~'        #  0xA1 -> TILDE
+    u's'        #  0xA2 -> LATIN SMALL LETTER S
+    u't'        #  0xA3 -> LATIN SMALL LETTER T
+    u'u'        #  0xA4 -> LATIN SMALL LETTER U
+    u'v'        #  0xA5 -> LATIN SMALL LETTER V
+    u'w'        #  0xA6 -> LATIN SMALL LETTER W
+    u'x'        #  0xA7 -> LATIN SMALL LETTER X
+    u'y'        #  0xA8 -> LATIN SMALL LETTER Y
+    u'z'        #  0xA9 -> LATIN SMALL LETTER Z
+    u'\u03bd'   #  0xAA -> GREEK SMALL LETTER NU
+    u'\u03be'   #  0xAB -> GREEK SMALL LETTER XI
+    u'\u03bf'   #  0xAC -> GREEK SMALL LETTER OMICRON
+    u'\u03c0'   #  0xAD -> GREEK SMALL LETTER PI
+    u'\u03c1'   #  0xAE -> GREEK SMALL LETTER RHO
+    u'\u03c3'   #  0xAF -> GREEK SMALL LETTER SIGMA
+    u'\xa3'     #  0xB0 -> POUND SIGN
+    u'\u03ac'   #  0xB1 -> GREEK SMALL LETTER ALPHA WITH TONOS
+    u'\u03ad'   #  0xB2 -> GREEK SMALL LETTER EPSILON WITH TONOS
+    u'\u03ae'   #  0xB3 -> GREEK SMALL LETTER ETA WITH TONOS
+    u'\u03ca'   #  0xB4 -> GREEK SMALL LETTER IOTA WITH DIALYTIKA
+    u'\u03af'   #  0xB5 -> GREEK SMALL LETTER IOTA WITH TONOS
+    u'\u03cc'   #  0xB6 -> GREEK SMALL LETTER OMICRON WITH TONOS
+    u'\u03cd'   #  0xB7 -> GREEK SMALL LETTER UPSILON WITH TONOS
+    u'\u03cb'   #  0xB8 -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA
+    u'\u03ce'   #  0xB9 -> GREEK SMALL LETTER OMEGA WITH TONOS
+    u'\u03c2'   #  0xBA -> GREEK SMALL LETTER FINAL SIGMA
+    u'\u03c4'   #  0xBB -> GREEK SMALL LETTER TAU
+    u'\u03c5'   #  0xBC -> GREEK SMALL LETTER UPSILON
+    u'\u03c6'   #  0xBD -> GREEK SMALL LETTER PHI
+    u'\u03c7'   #  0xBE -> GREEK SMALL LETTER CHI
+    u'\u03c8'   #  0xBF -> GREEK SMALL LETTER PSI
+    u'{'        #  0xC0 -> LEFT CURLY BRACKET
+    u'A'        #  0xC1 -> LATIN CAPITAL LETTER A
+    u'B'        #  0xC2 -> LATIN CAPITAL LETTER B
+    u'C'        #  0xC3 -> LATIN CAPITAL LETTER C
+    u'D'        #  0xC4 -> LATIN CAPITAL LETTER D
+    u'E'        #  0xC5 -> LATIN CAPITAL LETTER E
+    u'F'        #  0xC6 -> LATIN CAPITAL LETTER F
+    u'G'        #  0xC7 -> LATIN CAPITAL LETTER G
+    u'H'        #  0xC8 -> LATIN CAPITAL LETTER H
+    u'I'        #  0xC9 -> LATIN CAPITAL LETTER I
+    u'\xad'     #  0xCA -> SOFT HYPHEN
+    u'\u03c9'   #  0xCB -> GREEK SMALL LETTER OMEGA
+    u'\u0390'   #  0xCC -> GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
+    u'\u03b0'   #  0xCD -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS
+    u'\u2018'   #  0xCE -> LEFT SINGLE QUOTATION MARK
+    u'\u2015'   #  0xCF -> HORIZONTAL BAR
+    u'}'        #  0xD0 -> RIGHT CURLY BRACKET
+    u'J'        #  0xD1 -> LATIN CAPITAL LETTER J
+    u'K'        #  0xD2 -> LATIN CAPITAL LETTER K
+    u'L'        #  0xD3 -> LATIN CAPITAL LETTER L
+    u'M'        #  0xD4 -> LATIN CAPITAL LETTER M
+    u'N'        #  0xD5 -> LATIN CAPITAL LETTER N
+    u'O'        #  0xD6 -> LATIN CAPITAL LETTER O
+    u'P'        #  0xD7 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0xD8 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0xD9 -> LATIN CAPITAL LETTER R
+    u'\xb1'     #  0xDA -> PLUS-MINUS SIGN
+    u'\xbd'     #  0xDB -> VULGAR FRACTION ONE HALF
+    u'\x1a'     #  0xDC -> SUBSTITUTE
+    u'\u0387'   #  0xDD -> GREEK ANO TELEIA
+    u'\u2019'   #  0xDE -> RIGHT SINGLE QUOTATION MARK
+    u'\xa6'     #  0xDF -> BROKEN BAR
+    u'\\'       #  0xE0 -> REVERSE SOLIDUS
+    u'\x1a'     #  0xE1 -> SUBSTITUTE
+    u'S'        #  0xE2 -> LATIN CAPITAL LETTER S
+    u'T'        #  0xE3 -> LATIN CAPITAL LETTER T
+    u'U'        #  0xE4 -> LATIN CAPITAL LETTER U
+    u'V'        #  0xE5 -> LATIN CAPITAL LETTER V
+    u'W'        #  0xE6 -> LATIN CAPITAL LETTER W
+    u'X'        #  0xE7 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0xE8 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0xE9 -> LATIN CAPITAL LETTER Z
+    u'\xb2'     #  0xEA -> SUPERSCRIPT TWO
+    u'\xa7'     #  0xEB -> SECTION SIGN
+    u'\x1a'     #  0xEC -> SUBSTITUTE
+    u'\x1a'     #  0xED -> SUBSTITUTE
+    u'\xab'     #  0xEE -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xac'     #  0xEF -> NOT SIGN
+    u'0'        #  0xF0 -> DIGIT ZERO
+    u'1'        #  0xF1 -> DIGIT ONE
+    u'2'        #  0xF2 -> DIGIT TWO
+    u'3'        #  0xF3 -> DIGIT THREE
+    u'4'        #  0xF4 -> DIGIT FOUR
+    u'5'        #  0xF5 -> DIGIT FIVE
+    u'6'        #  0xF6 -> DIGIT SIX
+    u'7'        #  0xF7 -> DIGIT SEVEN
+    u'8'        #  0xF8 -> DIGIT EIGHT
+    u'9'        #  0xF9 -> DIGIT NINE
+    u'\xb3'     #  0xFA -> SUPERSCRIPT THREE
+    u'\xa9'     #  0xFB -> COPYRIGHT SIGN
+    u'\x1a'     #  0xFC -> SUBSTITUTE
+    u'\x1a'     #  0xFD -> SUBSTITUTE
+    u'\xbb'     #  0xFE -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\x9f'     #  0xFF -> CONTROL
+)
+
+### Encoding table
+encoding_table=codecs.charmap_build(decoding_table)

Added: vendor/Python/current/Lib/encodings/cp932.py
===================================================================
--- vendor/Python/current/Lib/encodings/cp932.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/cp932.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,39 @@
+#
+# cp932.py: Python Unicode Codec for CP932
+#
+# Written by Hye-Shik Chang <perky at FreeBSD.org>
+#
+
+import _codecs_jp, codecs
+import _multibytecodec as mbc
+
+codec = _codecs_jp.getcodec('cp932')
+
+class Codec(codecs.Codec):
+    encode = codec.encode
+    decode = codec.decode
+
+class IncrementalEncoder(mbc.MultibyteIncrementalEncoder,
+                         codecs.IncrementalEncoder):
+    codec = codec
+
+class IncrementalDecoder(mbc.MultibyteIncrementalDecoder,
+                         codecs.IncrementalDecoder):
+    codec = codec
+
+class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader):
+    codec = codec
+
+class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter):
+    codec = codec
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='cp932',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )

Added: vendor/Python/current/Lib/encodings/cp949.py
===================================================================
--- vendor/Python/current/Lib/encodings/cp949.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/cp949.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,39 @@
+#
+# cp949.py: Python Unicode Codec for CP949
+#
+# Written by Hye-Shik Chang <perky at FreeBSD.org>
+#
+
+import _codecs_kr, codecs
+import _multibytecodec as mbc
+
+codec = _codecs_kr.getcodec('cp949')
+
+class Codec(codecs.Codec):
+    encode = codec.encode
+    decode = codec.decode
+
+class IncrementalEncoder(mbc.MultibyteIncrementalEncoder,
+                         codecs.IncrementalEncoder):
+    codec = codec
+
+class IncrementalDecoder(mbc.MultibyteIncrementalDecoder,
+                         codecs.IncrementalDecoder):
+    codec = codec
+
+class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader):
+    codec = codec
+
+class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter):
+    codec = codec
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='cp949',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )

Added: vendor/Python/current/Lib/encodings/cp950.py
===================================================================
--- vendor/Python/current/Lib/encodings/cp950.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/cp950.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,39 @@
+#
+# cp950.py: Python Unicode Codec for CP950
+#
+# Written by Hye-Shik Chang <perky at FreeBSD.org>
+#
+
+import _codecs_tw, codecs
+import _multibytecodec as mbc
+
+codec = _codecs_tw.getcodec('cp950')
+
+class Codec(codecs.Codec):
+    encode = codec.encode
+    decode = codec.decode
+
+class IncrementalEncoder(mbc.MultibyteIncrementalEncoder,
+                         codecs.IncrementalEncoder):
+    codec = codec
+
+class IncrementalDecoder(mbc.MultibyteIncrementalDecoder,
+                         codecs.IncrementalDecoder):
+    codec = codec
+
+class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader):
+    codec = codec
+
+class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter):
+    codec = codec
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='cp950',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )

Added: vendor/Python/current/Lib/encodings/euc_jis_2004.py
===================================================================
--- vendor/Python/current/Lib/encodings/euc_jis_2004.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/euc_jis_2004.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,39 @@
+#
+# euc_jis_2004.py: Python Unicode Codec for EUC_JIS_2004
+#
+# Written by Hye-Shik Chang <perky at FreeBSD.org>
+#
+
+import _codecs_jp, codecs
+import _multibytecodec as mbc
+
+codec = _codecs_jp.getcodec('euc_jis_2004')
+
+class Codec(codecs.Codec):
+    encode = codec.encode
+    decode = codec.decode
+
+class IncrementalEncoder(mbc.MultibyteIncrementalEncoder,
+                         codecs.IncrementalEncoder):
+    codec = codec
+
+class IncrementalDecoder(mbc.MultibyteIncrementalDecoder,
+                         codecs.IncrementalDecoder):
+    codec = codec
+
+class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader):
+    codec = codec
+
+class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter):
+    codec = codec
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='euc_jis_2004',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )

Added: vendor/Python/current/Lib/encodings/euc_jisx0213.py
===================================================================
--- vendor/Python/current/Lib/encodings/euc_jisx0213.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/euc_jisx0213.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,39 @@
+#
+# euc_jisx0213.py: Python Unicode Codec for EUC_JISX0213
+#
+# Written by Hye-Shik Chang <perky at FreeBSD.org>
+#
+
+import _codecs_jp, codecs
+import _multibytecodec as mbc
+
+codec = _codecs_jp.getcodec('euc_jisx0213')
+
+class Codec(codecs.Codec):
+    encode = codec.encode
+    decode = codec.decode
+
+class IncrementalEncoder(mbc.MultibyteIncrementalEncoder,
+                         codecs.IncrementalEncoder):
+    codec = codec
+
+class IncrementalDecoder(mbc.MultibyteIncrementalDecoder,
+                         codecs.IncrementalDecoder):
+    codec = codec
+
+class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader):
+    codec = codec
+
+class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter):
+    codec = codec
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='euc_jisx0213',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )

Added: vendor/Python/current/Lib/encodings/euc_jp.py
===================================================================
--- vendor/Python/current/Lib/encodings/euc_jp.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/euc_jp.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,39 @@
+#
+# euc_jp.py: Python Unicode Codec for EUC_JP
+#
+# Written by Hye-Shik Chang <perky at FreeBSD.org>
+#
+
+import _codecs_jp, codecs
+import _multibytecodec as mbc
+
+codec = _codecs_jp.getcodec('euc_jp')
+
+class Codec(codecs.Codec):
+    encode = codec.encode
+    decode = codec.decode
+
+class IncrementalEncoder(mbc.MultibyteIncrementalEncoder,
+                         codecs.IncrementalEncoder):
+    codec = codec
+
+class IncrementalDecoder(mbc.MultibyteIncrementalDecoder,
+                         codecs.IncrementalDecoder):
+    codec = codec
+
+class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader):
+    codec = codec
+
+class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter):
+    codec = codec
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='euc_jp',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )

Added: vendor/Python/current/Lib/encodings/euc_kr.py
===================================================================
--- vendor/Python/current/Lib/encodings/euc_kr.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/euc_kr.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,39 @@
+#
+# euc_kr.py: Python Unicode Codec for EUC_KR
+#
+# Written by Hye-Shik Chang <perky at FreeBSD.org>
+#
+
+import _codecs_kr, codecs
+import _multibytecodec as mbc
+
+codec = _codecs_kr.getcodec('euc_kr')
+
+class Codec(codecs.Codec):
+    encode = codec.encode
+    decode = codec.decode
+
+class IncrementalEncoder(mbc.MultibyteIncrementalEncoder,
+                         codecs.IncrementalEncoder):
+    codec = codec
+
+class IncrementalDecoder(mbc.MultibyteIncrementalDecoder,
+                         codecs.IncrementalDecoder):
+    codec = codec
+
+class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader):
+    codec = codec
+
+class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter):
+    codec = codec
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='euc_kr',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )

Added: vendor/Python/current/Lib/encodings/gb18030.py
===================================================================
--- vendor/Python/current/Lib/encodings/gb18030.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/gb18030.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,39 @@
+#
+# gb18030.py: Python Unicode Codec for GB18030
+#
+# Written by Hye-Shik Chang <perky at FreeBSD.org>
+#
+
+import _codecs_cn, codecs
+import _multibytecodec as mbc
+
+codec = _codecs_cn.getcodec('gb18030')
+
+class Codec(codecs.Codec):
+    encode = codec.encode
+    decode = codec.decode
+
+class IncrementalEncoder(mbc.MultibyteIncrementalEncoder,
+                         codecs.IncrementalEncoder):
+    codec = codec
+
+class IncrementalDecoder(mbc.MultibyteIncrementalDecoder,
+                         codecs.IncrementalDecoder):
+    codec = codec
+
+class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader):
+    codec = codec
+
+class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter):
+    codec = codec
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='gb18030',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )

Added: vendor/Python/current/Lib/encodings/gb2312.py
===================================================================
--- vendor/Python/current/Lib/encodings/gb2312.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/gb2312.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,39 @@
+#
+# gb2312.py: Python Unicode Codec for GB2312
+#
+# Written by Hye-Shik Chang <perky at FreeBSD.org>
+#
+
+import _codecs_cn, codecs
+import _multibytecodec as mbc
+
+codec = _codecs_cn.getcodec('gb2312')
+
+class Codec(codecs.Codec):
+    encode = codec.encode
+    decode = codec.decode
+
+class IncrementalEncoder(mbc.MultibyteIncrementalEncoder,
+                         codecs.IncrementalEncoder):
+    codec = codec
+
+class IncrementalDecoder(mbc.MultibyteIncrementalDecoder,
+                         codecs.IncrementalDecoder):
+    codec = codec
+
+class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader):
+    codec = codec
+
+class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter):
+    codec = codec
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='gb2312',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )

Added: vendor/Python/current/Lib/encodings/gbk.py
===================================================================
--- vendor/Python/current/Lib/encodings/gbk.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/gbk.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,39 @@
+#
+# gbk.py: Python Unicode Codec for GBK
+#
+# Written by Hye-Shik Chang <perky at FreeBSD.org>
+#
+
+import _codecs_cn, codecs
+import _multibytecodec as mbc
+
+codec = _codecs_cn.getcodec('gbk')
+
+class Codec(codecs.Codec):
+    encode = codec.encode
+    decode = codec.decode
+
+class IncrementalEncoder(mbc.MultibyteIncrementalEncoder,
+                         codecs.IncrementalEncoder):
+    codec = codec
+
+class IncrementalDecoder(mbc.MultibyteIncrementalDecoder,
+                         codecs.IncrementalDecoder):
+    codec = codec
+
+class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader):
+    codec = codec
+
+class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter):
+    codec = codec
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='gbk',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )

Added: vendor/Python/current/Lib/encodings/hex_codec.py
===================================================================
--- vendor/Python/current/Lib/encodings/hex_codec.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/hex_codec.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,79 @@
+""" Python 'hex_codec' Codec - 2-digit hex content transfer encoding
+
+    Unlike most of the other codecs which target Unicode, this codec
+    will return Python string objects for both encode and decode.
+
+    Written by Marc-Andre Lemburg (mal at lemburg.com).
+
+"""
+import codecs, binascii
+
+### Codec APIs
+
+def hex_encode(input,errors='strict'):
+
+    """ Encodes the object input and returns a tuple (output
+        object, length consumed).
+
+        errors defines the error handling to apply. It defaults to
+        'strict' handling which is the only currently supported
+        error handling for this codec.
+
+    """
+    assert errors == 'strict'
+    output = binascii.b2a_hex(input)
+    return (output, len(input))
+
+def hex_decode(input,errors='strict'):
+
+    """ Decodes the object input and returns a tuple (output
+        object, length consumed).
+
+        input must be an object which provides the bf_getreadbuf
+        buffer slot. Python strings, buffer objects and memory
+        mapped files are examples of objects providing this slot.
+
+        errors defines the error handling to apply. It defaults to
+        'strict' handling which is the only currently supported
+        error handling for this codec.
+
+    """
+    assert errors == 'strict'
+    output = binascii.a2b_hex(input)
+    return (output, len(input))
+
+class Codec(codecs.Codec):
+
+    def encode(self, input,errors='strict'):
+        return hex_encode(input,errors)
+    def decode(self, input,errors='strict'):
+        return hex_decode(input,errors)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        assert self.errors == 'strict'
+        return binascii.b2a_hex(input)
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        assert self.errors == 'strict'
+        return binascii.a2b_hex(input)
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='hex',
+        encode=hex_encode,
+        decode=hex_decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamwriter=StreamWriter,
+        streamreader=StreamReader,
+    )

Added: vendor/Python/current/Lib/encodings/hp_roman8.py
===================================================================
--- vendor/Python/current/Lib/encodings/hp_roman8.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/hp_roman8.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,152 @@
+""" Python Character Mapping Codec generated from 'hp_roman8.txt' with gencodec.py.
+
+    Based on data from ftp://dkuug.dk/i18n/charmaps/HP-ROMAN8 (Keld Simonsen)
+
+    Original source: LaserJet IIP Printer User's Manual HP part no
+    33471-90901, Hewlet-Packard, June 1989.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_map)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_map)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_map)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='hp-roman8',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamwriter=StreamWriter,
+        streamreader=StreamReader,
+    )
+
+### Decoding Map
+
+decoding_map = codecs.make_identity_dict(range(256))
+decoding_map.update({
+        0x00a1: 0x00c0, #       LATIN CAPITAL LETTER A WITH GRAVE
+        0x00a2: 0x00c2, #       LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+        0x00a3: 0x00c8, #       LATIN CAPITAL LETTER E WITH GRAVE
+        0x00a4: 0x00ca, #       LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+        0x00a5: 0x00cb, #       LATIN CAPITAL LETTER E WITH DIAERESIS
+        0x00a6: 0x00ce, #       LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+        0x00a7: 0x00cf, #       LATIN CAPITAL LETTER I WITH DIAERESIS
+        0x00a8: 0x00b4, #       ACUTE ACCENT
+        0x00a9: 0x02cb, #       MODIFIER LETTER GRAVE ACCENT (Mandarin Chinese fourth tone)
+        0x00aa: 0x02c6, #       MODIFIER LETTER CIRCUMFLEX ACCENT
+        0x00ab: 0x00a8, #       DIAERESIS
+        0x00ac: 0x02dc, #       SMALL TILDE
+        0x00ad: 0x00d9, #       LATIN CAPITAL LETTER U WITH GRAVE
+        0x00ae: 0x00db, #       LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+        0x00af: 0x20a4, #       LIRA SIGN
+        0x00b0: 0x00af, #       MACRON
+        0x00b1: 0x00dd, #       LATIN CAPITAL LETTER Y WITH ACUTE
+        0x00b2: 0x00fd, #       LATIN SMALL LETTER Y WITH ACUTE
+        0x00b3: 0x00b0, #       DEGREE SIGN
+        0x00b4: 0x00c7, #       LATIN CAPITAL LETTER C WITH CEDILLA
+        0x00b5: 0x00e7, #       LATIN SMALL LETTER C WITH CEDILLA
+        0x00b6: 0x00d1, #       LATIN CAPITAL LETTER N WITH TILDE
+        0x00b7: 0x00f1, #       LATIN SMALL LETTER N WITH TILDE
+        0x00b8: 0x00a1, #       INVERTED EXCLAMATION MARK
+        0x00b9: 0x00bf, #       INVERTED QUESTION MARK
+        0x00ba: 0x00a4, #       CURRENCY SIGN
+        0x00bb: 0x00a3, #       POUND SIGN
+        0x00bc: 0x00a5, #       YEN SIGN
+        0x00bd: 0x00a7, #       SECTION SIGN
+        0x00be: 0x0192, #       LATIN SMALL LETTER F WITH HOOK
+        0x00bf: 0x00a2, #       CENT SIGN
+        0x00c0: 0x00e2, #       LATIN SMALL LETTER A WITH CIRCUMFLEX
+        0x00c1: 0x00ea, #       LATIN SMALL LETTER E WITH CIRCUMFLEX
+        0x00c2: 0x00f4, #       LATIN SMALL LETTER O WITH CIRCUMFLEX
+        0x00c3: 0x00fb, #       LATIN SMALL LETTER U WITH CIRCUMFLEX
+        0x00c4: 0x00e1, #       LATIN SMALL LETTER A WITH ACUTE
+        0x00c5: 0x00e9, #       LATIN SMALL LETTER E WITH ACUTE
+        0x00c6: 0x00f3, #       LATIN SMALL LETTER O WITH ACUTE
+        0x00c7: 0x00fa, #       LATIN SMALL LETTER U WITH ACUTE
+        0x00c8: 0x00e0, #       LATIN SMALL LETTER A WITH GRAVE
+        0x00c9: 0x00e8, #       LATIN SMALL LETTER E WITH GRAVE
+        0x00ca: 0x00f2, #       LATIN SMALL LETTER O WITH GRAVE
+        0x00cb: 0x00f9, #       LATIN SMALL LETTER U WITH GRAVE
+        0x00cc: 0x00e4, #       LATIN SMALL LETTER A WITH DIAERESIS
+        0x00cd: 0x00eb, #       LATIN SMALL LETTER E WITH DIAERESIS
+        0x00ce: 0x00f6, #       LATIN SMALL LETTER O WITH DIAERESIS
+        0x00cf: 0x00fc, #       LATIN SMALL LETTER U WITH DIAERESIS
+        0x00d0: 0x00c5, #       LATIN CAPITAL LETTER A WITH RING ABOVE
+        0x00d1: 0x00ee, #       LATIN SMALL LETTER I WITH CIRCUMFLEX
+        0x00d2: 0x00d8, #       LATIN CAPITAL LETTER O WITH STROKE
+        0x00d3: 0x00c6, #       LATIN CAPITAL LETTER AE
+        0x00d4: 0x00e5, #       LATIN SMALL LETTER A WITH RING ABOVE
+        0x00d5: 0x00ed, #       LATIN SMALL LETTER I WITH ACUTE
+        0x00d6: 0x00f8, #       LATIN SMALL LETTER O WITH STROKE
+        0x00d7: 0x00e6, #       LATIN SMALL LETTER AE
+        0x00d8: 0x00c4, #       LATIN CAPITAL LETTER A WITH DIAERESIS
+        0x00d9: 0x00ec, #       LATIN SMALL LETTER I WITH GRAVE
+        0x00da: 0x00d6, #       LATIN CAPITAL LETTER O WITH DIAERESIS
+        0x00db: 0x00dc, #       LATIN CAPITAL LETTER U WITH DIAERESIS
+        0x00dc: 0x00c9, #       LATIN CAPITAL LETTER E WITH ACUTE
+        0x00dd: 0x00ef, #       LATIN SMALL LETTER I WITH DIAERESIS
+        0x00de: 0x00df, #       LATIN SMALL LETTER SHARP S (German)
+        0x00df: 0x00d4, #       LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+        0x00e0: 0x00c1, #       LATIN CAPITAL LETTER A WITH ACUTE
+        0x00e1: 0x00c3, #       LATIN CAPITAL LETTER A WITH TILDE
+        0x00e2: 0x00e3, #       LATIN SMALL LETTER A WITH TILDE
+        0x00e3: 0x00d0, #       LATIN CAPITAL LETTER ETH (Icelandic)
+        0x00e4: 0x00f0, #       LATIN SMALL LETTER ETH (Icelandic)
+        0x00e5: 0x00cd, #       LATIN CAPITAL LETTER I WITH ACUTE
+        0x00e6: 0x00cc, #       LATIN CAPITAL LETTER I WITH GRAVE
+        0x00e7: 0x00d3, #       LATIN CAPITAL LETTER O WITH ACUTE
+        0x00e8: 0x00d2, #       LATIN CAPITAL LETTER O WITH GRAVE
+        0x00e9: 0x00d5, #       LATIN CAPITAL LETTER O WITH TILDE
+        0x00ea: 0x00f5, #       LATIN SMALL LETTER O WITH TILDE
+        0x00eb: 0x0160, #       LATIN CAPITAL LETTER S WITH CARON
+        0x00ec: 0x0161, #       LATIN SMALL LETTER S WITH CARON
+        0x00ed: 0x00da, #       LATIN CAPITAL LETTER U WITH ACUTE
+        0x00ee: 0x0178, #       LATIN CAPITAL LETTER Y WITH DIAERESIS
+        0x00ef: 0x00ff, #       LATIN SMALL LETTER Y WITH DIAERESIS
+        0x00f0: 0x00de, #       LATIN CAPITAL LETTER THORN (Icelandic)
+        0x00f1: 0x00fe, #       LATIN SMALL LETTER THORN (Icelandic)
+        0x00f2: 0x00b7, #       MIDDLE DOT
+        0x00f3: 0x00b5, #       MICRO SIGN
+        0x00f4: 0x00b6, #       PILCROW SIGN
+        0x00f5: 0x00be, #       VULGAR FRACTION THREE QUARTERS
+        0x00f6: 0x2014, #       EM DASH
+        0x00f7: 0x00bc, #       VULGAR FRACTION ONE QUARTER
+        0x00f8: 0x00bd, #       VULGAR FRACTION ONE HALF
+        0x00f9: 0x00aa, #       FEMININE ORDINAL INDICATOR
+        0x00fa: 0x00ba, #       MASCULINE ORDINAL INDICATOR
+        0x00fb: 0x00ab, #       LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+        0x00fc: 0x25a0, #       BLACK SQUARE
+        0x00fd: 0x00bb, #       RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+        0x00fe: 0x00b1, #       PLUS-MINUS SIGN
+        0x00ff: None,
+})
+
+### Encoding Map
+
+encoding_map = codecs.make_encoding_map(decoding_map)

Added: vendor/Python/current/Lib/encodings/hz.py
===================================================================
--- vendor/Python/current/Lib/encodings/hz.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/hz.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,39 @@
+#
+# hz.py: Python Unicode Codec for HZ
+#
+# Written by Hye-Shik Chang <perky at FreeBSD.org>
+#
+
+import _codecs_cn, codecs
+import _multibytecodec as mbc
+
+codec = _codecs_cn.getcodec('hz')
+
+class Codec(codecs.Codec):
+    encode = codec.encode
+    decode = codec.decode
+
+class IncrementalEncoder(mbc.MultibyteIncrementalEncoder,
+                         codecs.IncrementalEncoder):
+    codec = codec
+
+class IncrementalDecoder(mbc.MultibyteIncrementalDecoder,
+                         codecs.IncrementalDecoder):
+    codec = codec
+
+class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader):
+    codec = codec
+
+class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter):
+    codec = codec
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='hz',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )

Added: vendor/Python/current/Lib/encodings/idna.py
===================================================================
--- vendor/Python/current/Lib/encodings/idna.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/idna.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,288 @@
+# This module implements the RFCs 3490 (IDNA) and 3491 (Nameprep)
+
+import stringprep, re, codecs
+from unicodedata import ucd_3_2_0 as unicodedata
+
+# IDNA section 3.1
+dots = re.compile(u"[\u002E\u3002\uFF0E\uFF61]")
+
+# IDNA section 5
+ace_prefix = "xn--"
+uace_prefix = unicode(ace_prefix, "ascii")
+
+# This assumes query strings, so AllowUnassigned is true
+def nameprep(label):
+    # Map
+    newlabel = []
+    for c in label:
+        if stringprep.in_table_b1(c):
+            # Map to nothing
+            continue
+        newlabel.append(stringprep.map_table_b2(c))
+    label = u"".join(newlabel)
+
+    # Normalize
+    label = unicodedata.normalize("NFKC", label)
+
+    # Prohibit
+    for c in label:
+        if stringprep.in_table_c12(c) or \
+           stringprep.in_table_c22(c) or \
+           stringprep.in_table_c3(c) or \
+           stringprep.in_table_c4(c) or \
+           stringprep.in_table_c5(c) or \
+           stringprep.in_table_c6(c) or \
+           stringprep.in_table_c7(c) or \
+           stringprep.in_table_c8(c) or \
+           stringprep.in_table_c9(c):
+            raise UnicodeError("Invalid character %r" % c)
+
+    # Check bidi
+    RandAL = map(stringprep.in_table_d1, label)
+    for c in RandAL:
+        if c:
+            # There is a RandAL char in the string. Must perform further
+            # tests:
+            # 1) The characters in section 5.8 MUST be prohibited.
+            # This is table C.8, which was already checked
+            # 2) If a string contains any RandALCat character, the string
+            # MUST NOT contain any LCat character.
+            if filter(stringprep.in_table_d2, label):
+                raise UnicodeError("Violation of BIDI requirement 2")
+
+            # 3) If a string contains any RandALCat character, a
+            # RandALCat character MUST be the first character of the
+            # string, and a RandALCat character MUST be the last
+            # character of the string.
+            if not RandAL[0] or not RandAL[-1]:
+                raise UnicodeError("Violation of BIDI requirement 3")
+
+    return label
+
+def ToASCII(label):
+    try:
+        # Step 1: try ASCII
+        label = label.encode("ascii")
+    except UnicodeError:
+        pass
+    else:
+        # Skip to step 3: UseSTD3ASCIIRules is false, so
+        # Skip to step 8.
+        if 0 < len(label) < 64:
+            return label
+        raise UnicodeError("label empty or too long")
+
+    # Step 2: nameprep
+    label = nameprep(label)
+
+    # Step 3: UseSTD3ASCIIRules is false
+    # Step 4: try ASCII
+    try:
+        label = label.encode("ascii")
+    except UnicodeError:
+        pass
+    else:
+        # Skip to step 8.
+        if 0 < len(label) < 64:
+            return label
+        raise UnicodeError("label empty or too long")
+
+    # Step 5: Check ACE prefix
+    if label.startswith(uace_prefix):
+        raise UnicodeError("Label starts with ACE prefix")
+
+    # Step 6: Encode with PUNYCODE
+    label = label.encode("punycode")
+
+    # Step 7: Prepend ACE prefix
+    label = ace_prefix + label
+
+    # Step 8: Check size
+    if 0 < len(label) < 64:
+        return label
+    raise UnicodeError("label empty or too long")
+
+def ToUnicode(label):
+    # Step 1: Check for ASCII
+    if isinstance(label, str):
+        pure_ascii = True
+    else:
+        try:
+            label = label.encode("ascii")
+            pure_ascii = True
+        except UnicodeError:
+            pure_ascii = False
+    if not pure_ascii:
+        # Step 2: Perform nameprep
+        label = nameprep(label)
+        # It doesn't say this, but apparently, it should be ASCII now
+        try:
+            label = label.encode("ascii")
+        except UnicodeError:
+            raise UnicodeError("Invalid character in IDN label")
+    # Step 3: Check for ACE prefix
+    if not label.startswith(ace_prefix):
+        return unicode(label, "ascii")
+
+    # Step 4: Remove ACE prefix
+    label1 = label[len(ace_prefix):]
+
+    # Step 5: Decode using PUNYCODE
+    result = label1.decode("punycode")
+
+    # Step 6: Apply ToASCII
+    label2 = ToASCII(result)
+
+    # Step 7: Compare the result of step 6 with the one of step 3
+    # label2 will already be in lower case.
+    if label.lower() != label2:
+        raise UnicodeError("IDNA does not round-trip", label, label2)
+
+    # Step 8: return the result of step 5
+    return result
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+    def encode(self,input,errors='strict'):
+
+        if errors != 'strict':
+            # IDNA is quite clear that implementations must be strict
+            raise UnicodeError("unsupported error handling "+errors)
+
+        if not input:
+            return "", 0
+
+        result = []
+        labels = dots.split(input)
+        if labels and len(labels[-1])==0:
+            trailing_dot = '.'
+            del labels[-1]
+        else:
+            trailing_dot = ''
+        for label in labels:
+            result.append(ToASCII(label))
+        # Join with U+002E
+        return ".".join(result)+trailing_dot, len(input)
+
+    def decode(self,input,errors='strict'):
+
+        if errors != 'strict':
+            raise UnicodeError("Unsupported error handling "+errors)
+
+        if not input:
+            return u"", 0
+
+        # IDNA allows decoding to operate on Unicode strings, too.
+        if isinstance(input, unicode):
+            labels = dots.split(input)
+        else:
+            # Must be ASCII string
+            input = str(input)
+            unicode(input, "ascii")
+            labels = input.split(".")
+
+        if labels and len(labels[-1]) == 0:
+            trailing_dot = u'.'
+            del labels[-1]
+        else:
+            trailing_dot = u''
+
+        result = []
+        for label in labels:
+            result.append(ToUnicode(label))
+
+        return u".".join(result)+trailing_dot, len(input)
+
+class IncrementalEncoder(codecs.BufferedIncrementalEncoder):
+    def _buffer_encode(self, input, errors, final):
+        if errors != 'strict':
+            # IDNA is quite clear that implementations must be strict
+            raise UnicodeError("unsupported error handling "+errors)
+
+        if not input:
+            return ("", 0)
+
+        labels = dots.split(input)
+        trailing_dot = u''
+        if labels:
+            if not labels[-1]:
+                trailing_dot = '.'
+                del labels[-1]
+            elif not final:
+                # Keep potentially unfinished label until the next call
+                del labels[-1]
+                if labels:
+                    trailing_dot = '.'
+
+        result = []
+        size = 0
+        for label in labels:
+            result.append(ToASCII(label))
+            if size:
+                size += 1
+            size += len(label)
+
+        # Join with U+002E
+        result = ".".join(result) + trailing_dot
+        size += len(trailing_dot)
+        return (result, size)
+
+class IncrementalDecoder(codecs.BufferedIncrementalDecoder):
+    def _buffer_decode(self, input, errors, final):
+        if errors != 'strict':
+            raise UnicodeError("Unsupported error handling "+errors)
+
+        if not input:
+            return (u"", 0)
+
+        # IDNA allows decoding to operate on Unicode strings, too.
+        if isinstance(input, unicode):
+            labels = dots.split(input)
+        else:
+            # Must be ASCII string
+            input = str(input)
+            unicode(input, "ascii")
+            labels = input.split(".")
+
+        trailing_dot = u''
+        if labels:
+            if not labels[-1]:
+                trailing_dot = u'.'
+                del labels[-1]
+            elif not final:
+                # Keep potentially unfinished label until the next call
+                del labels[-1]
+                if labels:
+                    trailing_dot = u'.'
+
+        result = []
+        size = 0
+        for label in labels:
+            result.append(ToUnicode(label))
+            if size:
+                size += 1
+            size += len(label)
+
+        result = u".".join(result) + trailing_dot
+        size += len(trailing_dot)
+        return (result, size)
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='idna',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamwriter=StreamWriter,
+        streamreader=StreamReader,
+    )

Added: vendor/Python/current/Lib/encodings/iso2022_jp.py
===================================================================
--- vendor/Python/current/Lib/encodings/iso2022_jp.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/iso2022_jp.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,39 @@
+#
+# iso2022_jp.py: Python Unicode Codec for ISO2022_JP
+#
+# Written by Hye-Shik Chang <perky at FreeBSD.org>
+#
+
+import _codecs_iso2022, codecs
+import _multibytecodec as mbc
+
+codec = _codecs_iso2022.getcodec('iso2022_jp')
+
+class Codec(codecs.Codec):
+    encode = codec.encode
+    decode = codec.decode
+
+class IncrementalEncoder(mbc.MultibyteIncrementalEncoder,
+                         codecs.IncrementalEncoder):
+    codec = codec
+
+class IncrementalDecoder(mbc.MultibyteIncrementalDecoder,
+                         codecs.IncrementalDecoder):
+    codec = codec
+
+class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader):
+    codec = codec
+
+class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter):
+    codec = codec
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='iso2022_jp',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )

Added: vendor/Python/current/Lib/encodings/iso2022_jp_1.py
===================================================================
--- vendor/Python/current/Lib/encodings/iso2022_jp_1.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/iso2022_jp_1.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,39 @@
+#
+# iso2022_jp_1.py: Python Unicode Codec for ISO2022_JP_1
+#
+# Written by Hye-Shik Chang <perky at FreeBSD.org>
+#
+
+import _codecs_iso2022, codecs
+import _multibytecodec as mbc
+
+codec = _codecs_iso2022.getcodec('iso2022_jp_1')
+
+class Codec(codecs.Codec):
+    encode = codec.encode
+    decode = codec.decode
+
+class IncrementalEncoder(mbc.MultibyteIncrementalEncoder,
+                         codecs.IncrementalEncoder):
+    codec = codec
+
+class IncrementalDecoder(mbc.MultibyteIncrementalDecoder,
+                         codecs.IncrementalDecoder):
+    codec = codec
+
+class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader):
+    codec = codec
+
+class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter):
+    codec = codec
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='iso2022_jp_1',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )

Added: vendor/Python/current/Lib/encodings/iso2022_jp_2.py
===================================================================
--- vendor/Python/current/Lib/encodings/iso2022_jp_2.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/iso2022_jp_2.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,39 @@
+#
+# iso2022_jp_2.py: Python Unicode Codec for ISO2022_JP_2
+#
+# Written by Hye-Shik Chang <perky at FreeBSD.org>
+#
+
+import _codecs_iso2022, codecs
+import _multibytecodec as mbc
+
+codec = _codecs_iso2022.getcodec('iso2022_jp_2')
+
+class Codec(codecs.Codec):
+    encode = codec.encode
+    decode = codec.decode
+
+class IncrementalEncoder(mbc.MultibyteIncrementalEncoder,
+                         codecs.IncrementalEncoder):
+    codec = codec
+
+class IncrementalDecoder(mbc.MultibyteIncrementalDecoder,
+                         codecs.IncrementalDecoder):
+    codec = codec
+
+class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader):
+    codec = codec
+
+class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter):
+    codec = codec
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='iso2022_jp_2',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )

Added: vendor/Python/current/Lib/encodings/iso2022_jp_2004.py
===================================================================
--- vendor/Python/current/Lib/encodings/iso2022_jp_2004.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/iso2022_jp_2004.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,39 @@
+#
+# iso2022_jp_2004.py: Python Unicode Codec for ISO2022_JP_2004
+#
+# Written by Hye-Shik Chang <perky at FreeBSD.org>
+#
+
+import _codecs_iso2022, codecs
+import _multibytecodec as mbc
+
+codec = _codecs_iso2022.getcodec('iso2022_jp_2004')
+
+class Codec(codecs.Codec):
+    encode = codec.encode
+    decode = codec.decode
+
+class IncrementalEncoder(mbc.MultibyteIncrementalEncoder,
+                         codecs.IncrementalEncoder):
+    codec = codec
+
+class IncrementalDecoder(mbc.MultibyteIncrementalDecoder,
+                         codecs.IncrementalDecoder):
+    codec = codec
+
+class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader):
+    codec = codec
+
+class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter):
+    codec = codec
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='iso2022_jp_2004',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )

Added: vendor/Python/current/Lib/encodings/iso2022_jp_3.py
===================================================================
--- vendor/Python/current/Lib/encodings/iso2022_jp_3.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/iso2022_jp_3.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,39 @@
+#
+# iso2022_jp_3.py: Python Unicode Codec for ISO2022_JP_3
+#
+# Written by Hye-Shik Chang <perky at FreeBSD.org>
+#
+
+import _codecs_iso2022, codecs
+import _multibytecodec as mbc
+
+codec = _codecs_iso2022.getcodec('iso2022_jp_3')
+
+class Codec(codecs.Codec):
+    encode = codec.encode
+    decode = codec.decode
+
+class IncrementalEncoder(mbc.MultibyteIncrementalEncoder,
+                         codecs.IncrementalEncoder):
+    codec = codec
+
+class IncrementalDecoder(mbc.MultibyteIncrementalDecoder,
+                         codecs.IncrementalDecoder):
+    codec = codec
+
+class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader):
+    codec = codec
+
+class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter):
+    codec = codec
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='iso2022_jp_3',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )

Added: vendor/Python/current/Lib/encodings/iso2022_jp_ext.py
===================================================================
--- vendor/Python/current/Lib/encodings/iso2022_jp_ext.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/iso2022_jp_ext.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,39 @@
+#
+# iso2022_jp_ext.py: Python Unicode Codec for ISO2022_JP_EXT
+#
+# Written by Hye-Shik Chang <perky at FreeBSD.org>
+#
+
+import _codecs_iso2022, codecs
+import _multibytecodec as mbc
+
+codec = _codecs_iso2022.getcodec('iso2022_jp_ext')
+
+class Codec(codecs.Codec):
+    encode = codec.encode
+    decode = codec.decode
+
+class IncrementalEncoder(mbc.MultibyteIncrementalEncoder,
+                         codecs.IncrementalEncoder):
+    codec = codec
+
+class IncrementalDecoder(mbc.MultibyteIncrementalDecoder,
+                         codecs.IncrementalDecoder):
+    codec = codec
+
+class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader):
+    codec = codec
+
+class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter):
+    codec = codec
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='iso2022_jp_ext',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )

Added: vendor/Python/current/Lib/encodings/iso2022_kr.py
===================================================================
--- vendor/Python/current/Lib/encodings/iso2022_kr.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/iso2022_kr.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,39 @@
+#
+# iso2022_kr.py: Python Unicode Codec for ISO2022_KR
+#
+# Written by Hye-Shik Chang <perky at FreeBSD.org>
+#
+
+import _codecs_iso2022, codecs
+import _multibytecodec as mbc
+
+codec = _codecs_iso2022.getcodec('iso2022_kr')
+
+class Codec(codecs.Codec):
+    encode = codec.encode
+    decode = codec.decode
+
+class IncrementalEncoder(mbc.MultibyteIncrementalEncoder,
+                         codecs.IncrementalEncoder):
+    codec = codec
+
+class IncrementalDecoder(mbc.MultibyteIncrementalDecoder,
+                         codecs.IncrementalDecoder):
+    codec = codec
+
+class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader):
+    codec = codec
+
+class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter):
+    codec = codec
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='iso2022_kr',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )

Added: vendor/Python/current/Lib/encodings/iso8859_1.py
===================================================================
--- vendor/Python/current/Lib/encodings/iso8859_1.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/iso8859_1.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,307 @@
+""" Python Character Mapping Codec iso8859_1 generated from 'MAPPINGS/ISO8859/8859-1.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_table)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_table)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='iso8859-1',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x00 -> NULL
+    u'\x01'     #  0x01 -> START OF HEADING
+    u'\x02'     #  0x02 -> START OF TEXT
+    u'\x03'     #  0x03 -> END OF TEXT
+    u'\x04'     #  0x04 -> END OF TRANSMISSION
+    u'\x05'     #  0x05 -> ENQUIRY
+    u'\x06'     #  0x06 -> ACKNOWLEDGE
+    u'\x07'     #  0x07 -> BELL
+    u'\x08'     #  0x08 -> BACKSPACE
+    u'\t'       #  0x09 -> HORIZONTAL TABULATION
+    u'\n'       #  0x0A -> LINE FEED
+    u'\x0b'     #  0x0B -> VERTICAL TABULATION
+    u'\x0c'     #  0x0C -> FORM FEED
+    u'\r'       #  0x0D -> CARRIAGE RETURN
+    u'\x0e'     #  0x0E -> SHIFT OUT
+    u'\x0f'     #  0x0F -> SHIFT IN
+    u'\x10'     #  0x10 -> DATA LINK ESCAPE
+    u'\x11'     #  0x11 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x12 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x13 -> DEVICE CONTROL THREE
+    u'\x14'     #  0x14 -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x15 -> NEGATIVE ACKNOWLEDGE
+    u'\x16'     #  0x16 -> SYNCHRONOUS IDLE
+    u'\x17'     #  0x17 -> END OF TRANSMISSION BLOCK
+    u'\x18'     #  0x18 -> CANCEL
+    u'\x19'     #  0x19 -> END OF MEDIUM
+    u'\x1a'     #  0x1A -> SUBSTITUTE
+    u'\x1b'     #  0x1B -> ESCAPE
+    u'\x1c'     #  0x1C -> FILE SEPARATOR
+    u'\x1d'     #  0x1D -> GROUP SEPARATOR
+    u'\x1e'     #  0x1E -> RECORD SEPARATOR
+    u'\x1f'     #  0x1F -> UNIT SEPARATOR
+    u' '        #  0x20 -> SPACE
+    u'!'        #  0x21 -> EXCLAMATION MARK
+    u'"'        #  0x22 -> QUOTATION MARK
+    u'#'        #  0x23 -> NUMBER SIGN
+    u'$'        #  0x24 -> DOLLAR SIGN
+    u'%'        #  0x25 -> PERCENT SIGN
+    u'&'        #  0x26 -> AMPERSAND
+    u"'"        #  0x27 -> APOSTROPHE
+    u'('        #  0x28 -> LEFT PARENTHESIS
+    u')'        #  0x29 -> RIGHT PARENTHESIS
+    u'*'        #  0x2A -> ASTERISK
+    u'+'        #  0x2B -> PLUS SIGN
+    u','        #  0x2C -> COMMA
+    u'-'        #  0x2D -> HYPHEN-MINUS
+    u'.'        #  0x2E -> FULL STOP
+    u'/'        #  0x2F -> SOLIDUS
+    u'0'        #  0x30 -> DIGIT ZERO
+    u'1'        #  0x31 -> DIGIT ONE
+    u'2'        #  0x32 -> DIGIT TWO
+    u'3'        #  0x33 -> DIGIT THREE
+    u'4'        #  0x34 -> DIGIT FOUR
+    u'5'        #  0x35 -> DIGIT FIVE
+    u'6'        #  0x36 -> DIGIT SIX
+    u'7'        #  0x37 -> DIGIT SEVEN
+    u'8'        #  0x38 -> DIGIT EIGHT
+    u'9'        #  0x39 -> DIGIT NINE
+    u':'        #  0x3A -> COLON
+    u';'        #  0x3B -> SEMICOLON
+    u'<'        #  0x3C -> LESS-THAN SIGN
+    u'='        #  0x3D -> EQUALS SIGN
+    u'>'        #  0x3E -> GREATER-THAN SIGN
+    u'?'        #  0x3F -> QUESTION MARK
+    u'@'        #  0x40 -> COMMERCIAL AT
+    u'A'        #  0x41 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x42 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x43 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x44 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x45 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x46 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x47 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x48 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x49 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x4A -> LATIN CAPITAL LETTER J
+    u'K'        #  0x4B -> LATIN CAPITAL LETTER K
+    u'L'        #  0x4C -> LATIN CAPITAL LETTER L
+    u'M'        #  0x4D -> LATIN CAPITAL LETTER M
+    u'N'        #  0x4E -> LATIN CAPITAL LETTER N
+    u'O'        #  0x4F -> LATIN CAPITAL LETTER O
+    u'P'        #  0x50 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x51 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x52 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x53 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x54 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x55 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x56 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x57 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x58 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x59 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x5A -> LATIN CAPITAL LETTER Z
+    u'['        #  0x5B -> LEFT SQUARE BRACKET
+    u'\\'       #  0x5C -> REVERSE SOLIDUS
+    u']'        #  0x5D -> RIGHT SQUARE BRACKET
+    u'^'        #  0x5E -> CIRCUMFLEX ACCENT
+    u'_'        #  0x5F -> LOW LINE
+    u'`'        #  0x60 -> GRAVE ACCENT
+    u'a'        #  0x61 -> LATIN SMALL LETTER A
+    u'b'        #  0x62 -> LATIN SMALL LETTER B
+    u'c'        #  0x63 -> LATIN SMALL LETTER C
+    u'd'        #  0x64 -> LATIN SMALL LETTER D
+    u'e'        #  0x65 -> LATIN SMALL LETTER E
+    u'f'        #  0x66 -> LATIN SMALL LETTER F
+    u'g'        #  0x67 -> LATIN SMALL LETTER G
+    u'h'        #  0x68 -> LATIN SMALL LETTER H
+    u'i'        #  0x69 -> LATIN SMALL LETTER I
+    u'j'        #  0x6A -> LATIN SMALL LETTER J
+    u'k'        #  0x6B -> LATIN SMALL LETTER K
+    u'l'        #  0x6C -> LATIN SMALL LETTER L
+    u'm'        #  0x6D -> LATIN SMALL LETTER M
+    u'n'        #  0x6E -> LATIN SMALL LETTER N
+    u'o'        #  0x6F -> LATIN SMALL LETTER O
+    u'p'        #  0x70 -> LATIN SMALL LETTER P
+    u'q'        #  0x71 -> LATIN SMALL LETTER Q
+    u'r'        #  0x72 -> LATIN SMALL LETTER R
+    u's'        #  0x73 -> LATIN SMALL LETTER S
+    u't'        #  0x74 -> LATIN SMALL LETTER T
+    u'u'        #  0x75 -> LATIN SMALL LETTER U
+    u'v'        #  0x76 -> LATIN SMALL LETTER V
+    u'w'        #  0x77 -> LATIN SMALL LETTER W
+    u'x'        #  0x78 -> LATIN SMALL LETTER X
+    u'y'        #  0x79 -> LATIN SMALL LETTER Y
+    u'z'        #  0x7A -> LATIN SMALL LETTER Z
+    u'{'        #  0x7B -> LEFT CURLY BRACKET
+    u'|'        #  0x7C -> VERTICAL LINE
+    u'}'        #  0x7D -> RIGHT CURLY BRACKET
+    u'~'        #  0x7E -> TILDE
+    u'\x7f'     #  0x7F -> DELETE
+    u'\x80'     #  0x80 -> <control>
+    u'\x81'     #  0x81 -> <control>
+    u'\x82'     #  0x82 -> <control>
+    u'\x83'     #  0x83 -> <control>
+    u'\x84'     #  0x84 -> <control>
+    u'\x85'     #  0x85 -> <control>
+    u'\x86'     #  0x86 -> <control>
+    u'\x87'     #  0x87 -> <control>
+    u'\x88'     #  0x88 -> <control>
+    u'\x89'     #  0x89 -> <control>
+    u'\x8a'     #  0x8A -> <control>
+    u'\x8b'     #  0x8B -> <control>
+    u'\x8c'     #  0x8C -> <control>
+    u'\x8d'     #  0x8D -> <control>
+    u'\x8e'     #  0x8E -> <control>
+    u'\x8f'     #  0x8F -> <control>
+    u'\x90'     #  0x90 -> <control>
+    u'\x91'     #  0x91 -> <control>
+    u'\x92'     #  0x92 -> <control>
+    u'\x93'     #  0x93 -> <control>
+    u'\x94'     #  0x94 -> <control>
+    u'\x95'     #  0x95 -> <control>
+    u'\x96'     #  0x96 -> <control>
+    u'\x97'     #  0x97 -> <control>
+    u'\x98'     #  0x98 -> <control>
+    u'\x99'     #  0x99 -> <control>
+    u'\x9a'     #  0x9A -> <control>
+    u'\x9b'     #  0x9B -> <control>
+    u'\x9c'     #  0x9C -> <control>
+    u'\x9d'     #  0x9D -> <control>
+    u'\x9e'     #  0x9E -> <control>
+    u'\x9f'     #  0x9F -> <control>
+    u'\xa0'     #  0xA0 -> NO-BREAK SPACE
+    u'\xa1'     #  0xA1 -> INVERTED EXCLAMATION MARK
+    u'\xa2'     #  0xA2 -> CENT SIGN
+    u'\xa3'     #  0xA3 -> POUND SIGN
+    u'\xa4'     #  0xA4 -> CURRENCY SIGN
+    u'\xa5'     #  0xA5 -> YEN SIGN
+    u'\xa6'     #  0xA6 -> BROKEN BAR
+    u'\xa7'     #  0xA7 -> SECTION SIGN
+    u'\xa8'     #  0xA8 -> DIAERESIS
+    u'\xa9'     #  0xA9 -> COPYRIGHT SIGN
+    u'\xaa'     #  0xAA -> FEMININE ORDINAL INDICATOR
+    u'\xab'     #  0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xac'     #  0xAC -> NOT SIGN
+    u'\xad'     #  0xAD -> SOFT HYPHEN
+    u'\xae'     #  0xAE -> REGISTERED SIGN
+    u'\xaf'     #  0xAF -> MACRON
+    u'\xb0'     #  0xB0 -> DEGREE SIGN
+    u'\xb1'     #  0xB1 -> PLUS-MINUS SIGN
+    u'\xb2'     #  0xB2 -> SUPERSCRIPT TWO
+    u'\xb3'     #  0xB3 -> SUPERSCRIPT THREE
+    u'\xb4'     #  0xB4 -> ACUTE ACCENT
+    u'\xb5'     #  0xB5 -> MICRO SIGN
+    u'\xb6'     #  0xB6 -> PILCROW SIGN
+    u'\xb7'     #  0xB7 -> MIDDLE DOT
+    u'\xb8'     #  0xB8 -> CEDILLA
+    u'\xb9'     #  0xB9 -> SUPERSCRIPT ONE
+    u'\xba'     #  0xBA -> MASCULINE ORDINAL INDICATOR
+    u'\xbb'     #  0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xbc'     #  0xBC -> VULGAR FRACTION ONE QUARTER
+    u'\xbd'     #  0xBD -> VULGAR FRACTION ONE HALF
+    u'\xbe'     #  0xBE -> VULGAR FRACTION THREE QUARTERS
+    u'\xbf'     #  0xBF -> INVERTED QUESTION MARK
+    u'\xc0'     #  0xC0 -> LATIN CAPITAL LETTER A WITH GRAVE
+    u'\xc1'     #  0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE
+    u'\xc2'     #  0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+    u'\xc3'     #  0xC3 -> LATIN CAPITAL LETTER A WITH TILDE
+    u'\xc4'     #  0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS
+    u'\xc5'     #  0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE
+    u'\xc6'     #  0xC6 -> LATIN CAPITAL LETTER AE
+    u'\xc7'     #  0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA
+    u'\xc8'     #  0xC8 -> LATIN CAPITAL LETTER E WITH GRAVE
+    u'\xc9'     #  0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE
+    u'\xca'     #  0xCA -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+    u'\xcb'     #  0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS
+    u'\xcc'     #  0xCC -> LATIN CAPITAL LETTER I WITH GRAVE
+    u'\xcd'     #  0xCD -> LATIN CAPITAL LETTER I WITH ACUTE
+    u'\xce'     #  0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+    u'\xcf'     #  0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS
+    u'\xd0'     #  0xD0 -> LATIN CAPITAL LETTER ETH (Icelandic)
+    u'\xd1'     #  0xD1 -> LATIN CAPITAL LETTER N WITH TILDE
+    u'\xd2'     #  0xD2 -> LATIN CAPITAL LETTER O WITH GRAVE
+    u'\xd3'     #  0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE
+    u'\xd4'     #  0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+    u'\xd5'     #  0xD5 -> LATIN CAPITAL LETTER O WITH TILDE
+    u'\xd6'     #  0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS
+    u'\xd7'     #  0xD7 -> MULTIPLICATION SIGN
+    u'\xd8'     #  0xD8 -> LATIN CAPITAL LETTER O WITH STROKE
+    u'\xd9'     #  0xD9 -> LATIN CAPITAL LETTER U WITH GRAVE
+    u'\xda'     #  0xDA -> LATIN CAPITAL LETTER U WITH ACUTE
+    u'\xdb'     #  0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+    u'\xdc'     #  0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS
+    u'\xdd'     #  0xDD -> LATIN CAPITAL LETTER Y WITH ACUTE
+    u'\xde'     #  0xDE -> LATIN CAPITAL LETTER THORN (Icelandic)
+    u'\xdf'     #  0xDF -> LATIN SMALL LETTER SHARP S (German)
+    u'\xe0'     #  0xE0 -> LATIN SMALL LETTER A WITH GRAVE
+    u'\xe1'     #  0xE1 -> LATIN SMALL LETTER A WITH ACUTE
+    u'\xe2'     #  0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX
+    u'\xe3'     #  0xE3 -> LATIN SMALL LETTER A WITH TILDE
+    u'\xe4'     #  0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS
+    u'\xe5'     #  0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE
+    u'\xe6'     #  0xE6 -> LATIN SMALL LETTER AE
+    u'\xe7'     #  0xE7 -> LATIN SMALL LETTER C WITH CEDILLA
+    u'\xe8'     #  0xE8 -> LATIN SMALL LETTER E WITH GRAVE
+    u'\xe9'     #  0xE9 -> LATIN SMALL LETTER E WITH ACUTE
+    u'\xea'     #  0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX
+    u'\xeb'     #  0xEB -> LATIN SMALL LETTER E WITH DIAERESIS
+    u'\xec'     #  0xEC -> LATIN SMALL LETTER I WITH GRAVE
+    u'\xed'     #  0xED -> LATIN SMALL LETTER I WITH ACUTE
+    u'\xee'     #  0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX
+    u'\xef'     #  0xEF -> LATIN SMALL LETTER I WITH DIAERESIS
+    u'\xf0'     #  0xF0 -> LATIN SMALL LETTER ETH (Icelandic)
+    u'\xf1'     #  0xF1 -> LATIN SMALL LETTER N WITH TILDE
+    u'\xf2'     #  0xF2 -> LATIN SMALL LETTER O WITH GRAVE
+    u'\xf3'     #  0xF3 -> LATIN SMALL LETTER O WITH ACUTE
+    u'\xf4'     #  0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX
+    u'\xf5'     #  0xF5 -> LATIN SMALL LETTER O WITH TILDE
+    u'\xf6'     #  0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS
+    u'\xf7'     #  0xF7 -> DIVISION SIGN
+    u'\xf8'     #  0xF8 -> LATIN SMALL LETTER O WITH STROKE
+    u'\xf9'     #  0xF9 -> LATIN SMALL LETTER U WITH GRAVE
+    u'\xfa'     #  0xFA -> LATIN SMALL LETTER U WITH ACUTE
+    u'\xfb'     #  0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX
+    u'\xfc'     #  0xFC -> LATIN SMALL LETTER U WITH DIAERESIS
+    u'\xfd'     #  0xFD -> LATIN SMALL LETTER Y WITH ACUTE
+    u'\xfe'     #  0xFE -> LATIN SMALL LETTER THORN (Icelandic)
+    u'\xff'     #  0xFF -> LATIN SMALL LETTER Y WITH DIAERESIS
+)
+
+### Encoding table
+encoding_table=codecs.charmap_build(decoding_table)

Added: vendor/Python/current/Lib/encodings/iso8859_10.py
===================================================================
--- vendor/Python/current/Lib/encodings/iso8859_10.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/iso8859_10.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,307 @@
+""" Python Character Mapping Codec iso8859_10 generated from 'MAPPINGS/ISO8859/8859-10.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_table)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_table)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='iso8859-10',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x00 -> NULL
+    u'\x01'     #  0x01 -> START OF HEADING
+    u'\x02'     #  0x02 -> START OF TEXT
+    u'\x03'     #  0x03 -> END OF TEXT
+    u'\x04'     #  0x04 -> END OF TRANSMISSION
+    u'\x05'     #  0x05 -> ENQUIRY
+    u'\x06'     #  0x06 -> ACKNOWLEDGE
+    u'\x07'     #  0x07 -> BELL
+    u'\x08'     #  0x08 -> BACKSPACE
+    u'\t'       #  0x09 -> HORIZONTAL TABULATION
+    u'\n'       #  0x0A -> LINE FEED
+    u'\x0b'     #  0x0B -> VERTICAL TABULATION
+    u'\x0c'     #  0x0C -> FORM FEED
+    u'\r'       #  0x0D -> CARRIAGE RETURN
+    u'\x0e'     #  0x0E -> SHIFT OUT
+    u'\x0f'     #  0x0F -> SHIFT IN
+    u'\x10'     #  0x10 -> DATA LINK ESCAPE
+    u'\x11'     #  0x11 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x12 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x13 -> DEVICE CONTROL THREE
+    u'\x14'     #  0x14 -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x15 -> NEGATIVE ACKNOWLEDGE
+    u'\x16'     #  0x16 -> SYNCHRONOUS IDLE
+    u'\x17'     #  0x17 -> END OF TRANSMISSION BLOCK
+    u'\x18'     #  0x18 -> CANCEL
+    u'\x19'     #  0x19 -> END OF MEDIUM
+    u'\x1a'     #  0x1A -> SUBSTITUTE
+    u'\x1b'     #  0x1B -> ESCAPE
+    u'\x1c'     #  0x1C -> FILE SEPARATOR
+    u'\x1d'     #  0x1D -> GROUP SEPARATOR
+    u'\x1e'     #  0x1E -> RECORD SEPARATOR
+    u'\x1f'     #  0x1F -> UNIT SEPARATOR
+    u' '        #  0x20 -> SPACE
+    u'!'        #  0x21 -> EXCLAMATION MARK
+    u'"'        #  0x22 -> QUOTATION MARK
+    u'#'        #  0x23 -> NUMBER SIGN
+    u'$'        #  0x24 -> DOLLAR SIGN
+    u'%'        #  0x25 -> PERCENT SIGN
+    u'&'        #  0x26 -> AMPERSAND
+    u"'"        #  0x27 -> APOSTROPHE
+    u'('        #  0x28 -> LEFT PARENTHESIS
+    u')'        #  0x29 -> RIGHT PARENTHESIS
+    u'*'        #  0x2A -> ASTERISK
+    u'+'        #  0x2B -> PLUS SIGN
+    u','        #  0x2C -> COMMA
+    u'-'        #  0x2D -> HYPHEN-MINUS
+    u'.'        #  0x2E -> FULL STOP
+    u'/'        #  0x2F -> SOLIDUS
+    u'0'        #  0x30 -> DIGIT ZERO
+    u'1'        #  0x31 -> DIGIT ONE
+    u'2'        #  0x32 -> DIGIT TWO
+    u'3'        #  0x33 -> DIGIT THREE
+    u'4'        #  0x34 -> DIGIT FOUR
+    u'5'        #  0x35 -> DIGIT FIVE
+    u'6'        #  0x36 -> DIGIT SIX
+    u'7'        #  0x37 -> DIGIT SEVEN
+    u'8'        #  0x38 -> DIGIT EIGHT
+    u'9'        #  0x39 -> DIGIT NINE
+    u':'        #  0x3A -> COLON
+    u';'        #  0x3B -> SEMICOLON
+    u'<'        #  0x3C -> LESS-THAN SIGN
+    u'='        #  0x3D -> EQUALS SIGN
+    u'>'        #  0x3E -> GREATER-THAN SIGN
+    u'?'        #  0x3F -> QUESTION MARK
+    u'@'        #  0x40 -> COMMERCIAL AT
+    u'A'        #  0x41 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x42 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x43 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x44 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x45 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x46 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x47 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x48 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x49 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x4A -> LATIN CAPITAL LETTER J
+    u'K'        #  0x4B -> LATIN CAPITAL LETTER K
+    u'L'        #  0x4C -> LATIN CAPITAL LETTER L
+    u'M'        #  0x4D -> LATIN CAPITAL LETTER M
+    u'N'        #  0x4E -> LATIN CAPITAL LETTER N
+    u'O'        #  0x4F -> LATIN CAPITAL LETTER O
+    u'P'        #  0x50 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x51 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x52 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x53 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x54 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x55 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x56 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x57 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x58 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x59 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x5A -> LATIN CAPITAL LETTER Z
+    u'['        #  0x5B -> LEFT SQUARE BRACKET
+    u'\\'       #  0x5C -> REVERSE SOLIDUS
+    u']'        #  0x5D -> RIGHT SQUARE BRACKET
+    u'^'        #  0x5E -> CIRCUMFLEX ACCENT
+    u'_'        #  0x5F -> LOW LINE
+    u'`'        #  0x60 -> GRAVE ACCENT
+    u'a'        #  0x61 -> LATIN SMALL LETTER A
+    u'b'        #  0x62 -> LATIN SMALL LETTER B
+    u'c'        #  0x63 -> LATIN SMALL LETTER C
+    u'd'        #  0x64 -> LATIN SMALL LETTER D
+    u'e'        #  0x65 -> LATIN SMALL LETTER E
+    u'f'        #  0x66 -> LATIN SMALL LETTER F
+    u'g'        #  0x67 -> LATIN SMALL LETTER G
+    u'h'        #  0x68 -> LATIN SMALL LETTER H
+    u'i'        #  0x69 -> LATIN SMALL LETTER I
+    u'j'        #  0x6A -> LATIN SMALL LETTER J
+    u'k'        #  0x6B -> LATIN SMALL LETTER K
+    u'l'        #  0x6C -> LATIN SMALL LETTER L
+    u'm'        #  0x6D -> LATIN SMALL LETTER M
+    u'n'        #  0x6E -> LATIN SMALL LETTER N
+    u'o'        #  0x6F -> LATIN SMALL LETTER O
+    u'p'        #  0x70 -> LATIN SMALL LETTER P
+    u'q'        #  0x71 -> LATIN SMALL LETTER Q
+    u'r'        #  0x72 -> LATIN SMALL LETTER R
+    u's'        #  0x73 -> LATIN SMALL LETTER S
+    u't'        #  0x74 -> LATIN SMALL LETTER T
+    u'u'        #  0x75 -> LATIN SMALL LETTER U
+    u'v'        #  0x76 -> LATIN SMALL LETTER V
+    u'w'        #  0x77 -> LATIN SMALL LETTER W
+    u'x'        #  0x78 -> LATIN SMALL LETTER X
+    u'y'        #  0x79 -> LATIN SMALL LETTER Y
+    u'z'        #  0x7A -> LATIN SMALL LETTER Z
+    u'{'        #  0x7B -> LEFT CURLY BRACKET
+    u'|'        #  0x7C -> VERTICAL LINE
+    u'}'        #  0x7D -> RIGHT CURLY BRACKET
+    u'~'        #  0x7E -> TILDE
+    u'\x7f'     #  0x7F -> DELETE
+    u'\x80'     #  0x80 -> <control>
+    u'\x81'     #  0x81 -> <control>
+    u'\x82'     #  0x82 -> <control>
+    u'\x83'     #  0x83 -> <control>
+    u'\x84'     #  0x84 -> <control>
+    u'\x85'     #  0x85 -> <control>
+    u'\x86'     #  0x86 -> <control>
+    u'\x87'     #  0x87 -> <control>
+    u'\x88'     #  0x88 -> <control>
+    u'\x89'     #  0x89 -> <control>
+    u'\x8a'     #  0x8A -> <control>
+    u'\x8b'     #  0x8B -> <control>
+    u'\x8c'     #  0x8C -> <control>
+    u'\x8d'     #  0x8D -> <control>
+    u'\x8e'     #  0x8E -> <control>
+    u'\x8f'     #  0x8F -> <control>
+    u'\x90'     #  0x90 -> <control>
+    u'\x91'     #  0x91 -> <control>
+    u'\x92'     #  0x92 -> <control>
+    u'\x93'     #  0x93 -> <control>
+    u'\x94'     #  0x94 -> <control>
+    u'\x95'     #  0x95 -> <control>
+    u'\x96'     #  0x96 -> <control>
+    u'\x97'     #  0x97 -> <control>
+    u'\x98'     #  0x98 -> <control>
+    u'\x99'     #  0x99 -> <control>
+    u'\x9a'     #  0x9A -> <control>
+    u'\x9b'     #  0x9B -> <control>
+    u'\x9c'     #  0x9C -> <control>
+    u'\x9d'     #  0x9D -> <control>
+    u'\x9e'     #  0x9E -> <control>
+    u'\x9f'     #  0x9F -> <control>
+    u'\xa0'     #  0xA0 -> NO-BREAK SPACE
+    u'\u0104'   #  0xA1 -> LATIN CAPITAL LETTER A WITH OGONEK
+    u'\u0112'   #  0xA2 -> LATIN CAPITAL LETTER E WITH MACRON
+    u'\u0122'   #  0xA3 -> LATIN CAPITAL LETTER G WITH CEDILLA
+    u'\u012a'   #  0xA4 -> LATIN CAPITAL LETTER I WITH MACRON
+    u'\u0128'   #  0xA5 -> LATIN CAPITAL LETTER I WITH TILDE
+    u'\u0136'   #  0xA6 -> LATIN CAPITAL LETTER K WITH CEDILLA
+    u'\xa7'     #  0xA7 -> SECTION SIGN
+    u'\u013b'   #  0xA8 -> LATIN CAPITAL LETTER L WITH CEDILLA
+    u'\u0110'   #  0xA9 -> LATIN CAPITAL LETTER D WITH STROKE
+    u'\u0160'   #  0xAA -> LATIN CAPITAL LETTER S WITH CARON
+    u'\u0166'   #  0xAB -> LATIN CAPITAL LETTER T WITH STROKE
+    u'\u017d'   #  0xAC -> LATIN CAPITAL LETTER Z WITH CARON
+    u'\xad'     #  0xAD -> SOFT HYPHEN
+    u'\u016a'   #  0xAE -> LATIN CAPITAL LETTER U WITH MACRON
+    u'\u014a'   #  0xAF -> LATIN CAPITAL LETTER ENG
+    u'\xb0'     #  0xB0 -> DEGREE SIGN
+    u'\u0105'   #  0xB1 -> LATIN SMALL LETTER A WITH OGONEK
+    u'\u0113'   #  0xB2 -> LATIN SMALL LETTER E WITH MACRON
+    u'\u0123'   #  0xB3 -> LATIN SMALL LETTER G WITH CEDILLA
+    u'\u012b'   #  0xB4 -> LATIN SMALL LETTER I WITH MACRON
+    u'\u0129'   #  0xB5 -> LATIN SMALL LETTER I WITH TILDE
+    u'\u0137'   #  0xB6 -> LATIN SMALL LETTER K WITH CEDILLA
+    u'\xb7'     #  0xB7 -> MIDDLE DOT
+    u'\u013c'   #  0xB8 -> LATIN SMALL LETTER L WITH CEDILLA
+    u'\u0111'   #  0xB9 -> LATIN SMALL LETTER D WITH STROKE
+    u'\u0161'   #  0xBA -> LATIN SMALL LETTER S WITH CARON
+    u'\u0167'   #  0xBB -> LATIN SMALL LETTER T WITH STROKE
+    u'\u017e'   #  0xBC -> LATIN SMALL LETTER Z WITH CARON
+    u'\u2015'   #  0xBD -> HORIZONTAL BAR
+    u'\u016b'   #  0xBE -> LATIN SMALL LETTER U WITH MACRON
+    u'\u014b'   #  0xBF -> LATIN SMALL LETTER ENG
+    u'\u0100'   #  0xC0 -> LATIN CAPITAL LETTER A WITH MACRON
+    u'\xc1'     #  0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE
+    u'\xc2'     #  0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+    u'\xc3'     #  0xC3 -> LATIN CAPITAL LETTER A WITH TILDE
+    u'\xc4'     #  0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS
+    u'\xc5'     #  0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE
+    u'\xc6'     #  0xC6 -> LATIN CAPITAL LETTER AE
+    u'\u012e'   #  0xC7 -> LATIN CAPITAL LETTER I WITH OGONEK
+    u'\u010c'   #  0xC8 -> LATIN CAPITAL LETTER C WITH CARON
+    u'\xc9'     #  0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE
+    u'\u0118'   #  0xCA -> LATIN CAPITAL LETTER E WITH OGONEK
+    u'\xcb'     #  0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS
+    u'\u0116'   #  0xCC -> LATIN CAPITAL LETTER E WITH DOT ABOVE
+    u'\xcd'     #  0xCD -> LATIN CAPITAL LETTER I WITH ACUTE
+    u'\xce'     #  0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+    u'\xcf'     #  0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS
+    u'\xd0'     #  0xD0 -> LATIN CAPITAL LETTER ETH (Icelandic)
+    u'\u0145'   #  0xD1 -> LATIN CAPITAL LETTER N WITH CEDILLA
+    u'\u014c'   #  0xD2 -> LATIN CAPITAL LETTER O WITH MACRON
+    u'\xd3'     #  0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE
+    u'\xd4'     #  0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+    u'\xd5'     #  0xD5 -> LATIN CAPITAL LETTER O WITH TILDE
+    u'\xd6'     #  0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS
+    u'\u0168'   #  0xD7 -> LATIN CAPITAL LETTER U WITH TILDE
+    u'\xd8'     #  0xD8 -> LATIN CAPITAL LETTER O WITH STROKE
+    u'\u0172'   #  0xD9 -> LATIN CAPITAL LETTER U WITH OGONEK
+    u'\xda'     #  0xDA -> LATIN CAPITAL LETTER U WITH ACUTE
+    u'\xdb'     #  0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+    u'\xdc'     #  0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS
+    u'\xdd'     #  0xDD -> LATIN CAPITAL LETTER Y WITH ACUTE
+    u'\xde'     #  0xDE -> LATIN CAPITAL LETTER THORN (Icelandic)
+    u'\xdf'     #  0xDF -> LATIN SMALL LETTER SHARP S (German)
+    u'\u0101'   #  0xE0 -> LATIN SMALL LETTER A WITH MACRON
+    u'\xe1'     #  0xE1 -> LATIN SMALL LETTER A WITH ACUTE
+    u'\xe2'     #  0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX
+    u'\xe3'     #  0xE3 -> LATIN SMALL LETTER A WITH TILDE
+    u'\xe4'     #  0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS
+    u'\xe5'     #  0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE
+    u'\xe6'     #  0xE6 -> LATIN SMALL LETTER AE
+    u'\u012f'   #  0xE7 -> LATIN SMALL LETTER I WITH OGONEK
+    u'\u010d'   #  0xE8 -> LATIN SMALL LETTER C WITH CARON
+    u'\xe9'     #  0xE9 -> LATIN SMALL LETTER E WITH ACUTE
+    u'\u0119'   #  0xEA -> LATIN SMALL LETTER E WITH OGONEK
+    u'\xeb'     #  0xEB -> LATIN SMALL LETTER E WITH DIAERESIS
+    u'\u0117'   #  0xEC -> LATIN SMALL LETTER E WITH DOT ABOVE
+    u'\xed'     #  0xED -> LATIN SMALL LETTER I WITH ACUTE
+    u'\xee'     #  0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX
+    u'\xef'     #  0xEF -> LATIN SMALL LETTER I WITH DIAERESIS
+    u'\xf0'     #  0xF0 -> LATIN SMALL LETTER ETH (Icelandic)
+    u'\u0146'   #  0xF1 -> LATIN SMALL LETTER N WITH CEDILLA
+    u'\u014d'   #  0xF2 -> LATIN SMALL LETTER O WITH MACRON
+    u'\xf3'     #  0xF3 -> LATIN SMALL LETTER O WITH ACUTE
+    u'\xf4'     #  0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX
+    u'\xf5'     #  0xF5 -> LATIN SMALL LETTER O WITH TILDE
+    u'\xf6'     #  0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS
+    u'\u0169'   #  0xF7 -> LATIN SMALL LETTER U WITH TILDE
+    u'\xf8'     #  0xF8 -> LATIN SMALL LETTER O WITH STROKE
+    u'\u0173'   #  0xF9 -> LATIN SMALL LETTER U WITH OGONEK
+    u'\xfa'     #  0xFA -> LATIN SMALL LETTER U WITH ACUTE
+    u'\xfb'     #  0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX
+    u'\xfc'     #  0xFC -> LATIN SMALL LETTER U WITH DIAERESIS
+    u'\xfd'     #  0xFD -> LATIN SMALL LETTER Y WITH ACUTE
+    u'\xfe'     #  0xFE -> LATIN SMALL LETTER THORN (Icelandic)
+    u'\u0138'   #  0xFF -> LATIN SMALL LETTER KRA
+)
+
+### Encoding table
+encoding_table=codecs.charmap_build(decoding_table)

Added: vendor/Python/current/Lib/encodings/iso8859_11.py
===================================================================
--- vendor/Python/current/Lib/encodings/iso8859_11.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/iso8859_11.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,307 @@
+""" Python Character Mapping Codec iso8859_11 generated from 'MAPPINGS/ISO8859/8859-11.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_table)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_table)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='iso8859-11',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x00 -> NULL
+    u'\x01'     #  0x01 -> START OF HEADING
+    u'\x02'     #  0x02 -> START OF TEXT
+    u'\x03'     #  0x03 -> END OF TEXT
+    u'\x04'     #  0x04 -> END OF TRANSMISSION
+    u'\x05'     #  0x05 -> ENQUIRY
+    u'\x06'     #  0x06 -> ACKNOWLEDGE
+    u'\x07'     #  0x07 -> BELL
+    u'\x08'     #  0x08 -> BACKSPACE
+    u'\t'       #  0x09 -> HORIZONTAL TABULATION
+    u'\n'       #  0x0A -> LINE FEED
+    u'\x0b'     #  0x0B -> VERTICAL TABULATION
+    u'\x0c'     #  0x0C -> FORM FEED
+    u'\r'       #  0x0D -> CARRIAGE RETURN
+    u'\x0e'     #  0x0E -> SHIFT OUT
+    u'\x0f'     #  0x0F -> SHIFT IN
+    u'\x10'     #  0x10 -> DATA LINK ESCAPE
+    u'\x11'     #  0x11 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x12 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x13 -> DEVICE CONTROL THREE
+    u'\x14'     #  0x14 -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x15 -> NEGATIVE ACKNOWLEDGE
+    u'\x16'     #  0x16 -> SYNCHRONOUS IDLE
+    u'\x17'     #  0x17 -> END OF TRANSMISSION BLOCK
+    u'\x18'     #  0x18 -> CANCEL
+    u'\x19'     #  0x19 -> END OF MEDIUM
+    u'\x1a'     #  0x1A -> SUBSTITUTE
+    u'\x1b'     #  0x1B -> ESCAPE
+    u'\x1c'     #  0x1C -> FILE SEPARATOR
+    u'\x1d'     #  0x1D -> GROUP SEPARATOR
+    u'\x1e'     #  0x1E -> RECORD SEPARATOR
+    u'\x1f'     #  0x1F -> UNIT SEPARATOR
+    u' '        #  0x20 -> SPACE
+    u'!'        #  0x21 -> EXCLAMATION MARK
+    u'"'        #  0x22 -> QUOTATION MARK
+    u'#'        #  0x23 -> NUMBER SIGN
+    u'$'        #  0x24 -> DOLLAR SIGN
+    u'%'        #  0x25 -> PERCENT SIGN
+    u'&'        #  0x26 -> AMPERSAND
+    u"'"        #  0x27 -> APOSTROPHE
+    u'('        #  0x28 -> LEFT PARENTHESIS
+    u')'        #  0x29 -> RIGHT PARENTHESIS
+    u'*'        #  0x2A -> ASTERISK
+    u'+'        #  0x2B -> PLUS SIGN
+    u','        #  0x2C -> COMMA
+    u'-'        #  0x2D -> HYPHEN-MINUS
+    u'.'        #  0x2E -> FULL STOP
+    u'/'        #  0x2F -> SOLIDUS
+    u'0'        #  0x30 -> DIGIT ZERO
+    u'1'        #  0x31 -> DIGIT ONE
+    u'2'        #  0x32 -> DIGIT TWO
+    u'3'        #  0x33 -> DIGIT THREE
+    u'4'        #  0x34 -> DIGIT FOUR
+    u'5'        #  0x35 -> DIGIT FIVE
+    u'6'        #  0x36 -> DIGIT SIX
+    u'7'        #  0x37 -> DIGIT SEVEN
+    u'8'        #  0x38 -> DIGIT EIGHT
+    u'9'        #  0x39 -> DIGIT NINE
+    u':'        #  0x3A -> COLON
+    u';'        #  0x3B -> SEMICOLON
+    u'<'        #  0x3C -> LESS-THAN SIGN
+    u'='        #  0x3D -> EQUALS SIGN
+    u'>'        #  0x3E -> GREATER-THAN SIGN
+    u'?'        #  0x3F -> QUESTION MARK
+    u'@'        #  0x40 -> COMMERCIAL AT
+    u'A'        #  0x41 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x42 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x43 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x44 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x45 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x46 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x47 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x48 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x49 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x4A -> LATIN CAPITAL LETTER J
+    u'K'        #  0x4B -> LATIN CAPITAL LETTER K
+    u'L'        #  0x4C -> LATIN CAPITAL LETTER L
+    u'M'        #  0x4D -> LATIN CAPITAL LETTER M
+    u'N'        #  0x4E -> LATIN CAPITAL LETTER N
+    u'O'        #  0x4F -> LATIN CAPITAL LETTER O
+    u'P'        #  0x50 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x51 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x52 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x53 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x54 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x55 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x56 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x57 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x58 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x59 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x5A -> LATIN CAPITAL LETTER Z
+    u'['        #  0x5B -> LEFT SQUARE BRACKET
+    u'\\'       #  0x5C -> REVERSE SOLIDUS
+    u']'        #  0x5D -> RIGHT SQUARE BRACKET
+    u'^'        #  0x5E -> CIRCUMFLEX ACCENT
+    u'_'        #  0x5F -> LOW LINE
+    u'`'        #  0x60 -> GRAVE ACCENT
+    u'a'        #  0x61 -> LATIN SMALL LETTER A
+    u'b'        #  0x62 -> LATIN SMALL LETTER B
+    u'c'        #  0x63 -> LATIN SMALL LETTER C
+    u'd'        #  0x64 -> LATIN SMALL LETTER D
+    u'e'        #  0x65 -> LATIN SMALL LETTER E
+    u'f'        #  0x66 -> LATIN SMALL LETTER F
+    u'g'        #  0x67 -> LATIN SMALL LETTER G
+    u'h'        #  0x68 -> LATIN SMALL LETTER H
+    u'i'        #  0x69 -> LATIN SMALL LETTER I
+    u'j'        #  0x6A -> LATIN SMALL LETTER J
+    u'k'        #  0x6B -> LATIN SMALL LETTER K
+    u'l'        #  0x6C -> LATIN SMALL LETTER L
+    u'm'        #  0x6D -> LATIN SMALL LETTER M
+    u'n'        #  0x6E -> LATIN SMALL LETTER N
+    u'o'        #  0x6F -> LATIN SMALL LETTER O
+    u'p'        #  0x70 -> LATIN SMALL LETTER P
+    u'q'        #  0x71 -> LATIN SMALL LETTER Q
+    u'r'        #  0x72 -> LATIN SMALL LETTER R
+    u's'        #  0x73 -> LATIN SMALL LETTER S
+    u't'        #  0x74 -> LATIN SMALL LETTER T
+    u'u'        #  0x75 -> LATIN SMALL LETTER U
+    u'v'        #  0x76 -> LATIN SMALL LETTER V
+    u'w'        #  0x77 -> LATIN SMALL LETTER W
+    u'x'        #  0x78 -> LATIN SMALL LETTER X
+    u'y'        #  0x79 -> LATIN SMALL LETTER Y
+    u'z'        #  0x7A -> LATIN SMALL LETTER Z
+    u'{'        #  0x7B -> LEFT CURLY BRACKET
+    u'|'        #  0x7C -> VERTICAL LINE
+    u'}'        #  0x7D -> RIGHT CURLY BRACKET
+    u'~'        #  0x7E -> TILDE
+    u'\x7f'     #  0x7F -> DELETE
+    u'\x80'     #  0x80 -> <control>
+    u'\x81'     #  0x81 -> <control>
+    u'\x82'     #  0x82 -> <control>
+    u'\x83'     #  0x83 -> <control>
+    u'\x84'     #  0x84 -> <control>
+    u'\x85'     #  0x85 -> <control>
+    u'\x86'     #  0x86 -> <control>
+    u'\x87'     #  0x87 -> <control>
+    u'\x88'     #  0x88 -> <control>
+    u'\x89'     #  0x89 -> <control>
+    u'\x8a'     #  0x8A -> <control>
+    u'\x8b'     #  0x8B -> <control>
+    u'\x8c'     #  0x8C -> <control>
+    u'\x8d'     #  0x8D -> <control>
+    u'\x8e'     #  0x8E -> <control>
+    u'\x8f'     #  0x8F -> <control>
+    u'\x90'     #  0x90 -> <control>
+    u'\x91'     #  0x91 -> <control>
+    u'\x92'     #  0x92 -> <control>
+    u'\x93'     #  0x93 -> <control>
+    u'\x94'     #  0x94 -> <control>
+    u'\x95'     #  0x95 -> <control>
+    u'\x96'     #  0x96 -> <control>
+    u'\x97'     #  0x97 -> <control>
+    u'\x98'     #  0x98 -> <control>
+    u'\x99'     #  0x99 -> <control>
+    u'\x9a'     #  0x9A -> <control>
+    u'\x9b'     #  0x9B -> <control>
+    u'\x9c'     #  0x9C -> <control>
+    u'\x9d'     #  0x9D -> <control>
+    u'\x9e'     #  0x9E -> <control>
+    u'\x9f'     #  0x9F -> <control>
+    u'\xa0'     #  0xA0 -> NO-BREAK SPACE
+    u'\u0e01'   #  0xA1 -> THAI CHARACTER KO KAI
+    u'\u0e02'   #  0xA2 -> THAI CHARACTER KHO KHAI
+    u'\u0e03'   #  0xA3 -> THAI CHARACTER KHO KHUAT
+    u'\u0e04'   #  0xA4 -> THAI CHARACTER KHO KHWAI
+    u'\u0e05'   #  0xA5 -> THAI CHARACTER KHO KHON
+    u'\u0e06'   #  0xA6 -> THAI CHARACTER KHO RAKHANG
+    u'\u0e07'   #  0xA7 -> THAI CHARACTER NGO NGU
+    u'\u0e08'   #  0xA8 -> THAI CHARACTER CHO CHAN
+    u'\u0e09'   #  0xA9 -> THAI CHARACTER CHO CHING
+    u'\u0e0a'   #  0xAA -> THAI CHARACTER CHO CHANG
+    u'\u0e0b'   #  0xAB -> THAI CHARACTER SO SO
+    u'\u0e0c'   #  0xAC -> THAI CHARACTER CHO CHOE
+    u'\u0e0d'   #  0xAD -> THAI CHARACTER YO YING
+    u'\u0e0e'   #  0xAE -> THAI CHARACTER DO CHADA
+    u'\u0e0f'   #  0xAF -> THAI CHARACTER TO PATAK
+    u'\u0e10'   #  0xB0 -> THAI CHARACTER THO THAN
+    u'\u0e11'   #  0xB1 -> THAI CHARACTER THO NANGMONTHO
+    u'\u0e12'   #  0xB2 -> THAI CHARACTER THO PHUTHAO
+    u'\u0e13'   #  0xB3 -> THAI CHARACTER NO NEN
+    u'\u0e14'   #  0xB4 -> THAI CHARACTER DO DEK
+    u'\u0e15'   #  0xB5 -> THAI CHARACTER TO TAO
+    u'\u0e16'   #  0xB6 -> THAI CHARACTER THO THUNG
+    u'\u0e17'   #  0xB7 -> THAI CHARACTER THO THAHAN
+    u'\u0e18'   #  0xB8 -> THAI CHARACTER THO THONG
+    u'\u0e19'   #  0xB9 -> THAI CHARACTER NO NU
+    u'\u0e1a'   #  0xBA -> THAI CHARACTER BO BAIMAI
+    u'\u0e1b'   #  0xBB -> THAI CHARACTER PO PLA
+    u'\u0e1c'   #  0xBC -> THAI CHARACTER PHO PHUNG
+    u'\u0e1d'   #  0xBD -> THAI CHARACTER FO FA
+    u'\u0e1e'   #  0xBE -> THAI CHARACTER PHO PHAN
+    u'\u0e1f'   #  0xBF -> THAI CHARACTER FO FAN
+    u'\u0e20'   #  0xC0 -> THAI CHARACTER PHO SAMPHAO
+    u'\u0e21'   #  0xC1 -> THAI CHARACTER MO MA
+    u'\u0e22'   #  0xC2 -> THAI CHARACTER YO YAK
+    u'\u0e23'   #  0xC3 -> THAI CHARACTER RO RUA
+    u'\u0e24'   #  0xC4 -> THAI CHARACTER RU
+    u'\u0e25'   #  0xC5 -> THAI CHARACTER LO LING
+    u'\u0e26'   #  0xC6 -> THAI CHARACTER LU
+    u'\u0e27'   #  0xC7 -> THAI CHARACTER WO WAEN
+    u'\u0e28'   #  0xC8 -> THAI CHARACTER SO SALA
+    u'\u0e29'   #  0xC9 -> THAI CHARACTER SO RUSI
+    u'\u0e2a'   #  0xCA -> THAI CHARACTER SO SUA
+    u'\u0e2b'   #  0xCB -> THAI CHARACTER HO HIP
+    u'\u0e2c'   #  0xCC -> THAI CHARACTER LO CHULA
+    u'\u0e2d'   #  0xCD -> THAI CHARACTER O ANG
+    u'\u0e2e'   #  0xCE -> THAI CHARACTER HO NOKHUK
+    u'\u0e2f'   #  0xCF -> THAI CHARACTER PAIYANNOI
+    u'\u0e30'   #  0xD0 -> THAI CHARACTER SARA A
+    u'\u0e31'   #  0xD1 -> THAI CHARACTER MAI HAN-AKAT
+    u'\u0e32'   #  0xD2 -> THAI CHARACTER SARA AA
+    u'\u0e33'   #  0xD3 -> THAI CHARACTER SARA AM
+    u'\u0e34'   #  0xD4 -> THAI CHARACTER SARA I
+    u'\u0e35'   #  0xD5 -> THAI CHARACTER SARA II
+    u'\u0e36'   #  0xD6 -> THAI CHARACTER SARA UE
+    u'\u0e37'   #  0xD7 -> THAI CHARACTER SARA UEE
+    u'\u0e38'   #  0xD8 -> THAI CHARACTER SARA U
+    u'\u0e39'   #  0xD9 -> THAI CHARACTER SARA UU
+    u'\u0e3a'   #  0xDA -> THAI CHARACTER PHINTHU
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\u0e3f'   #  0xDF -> THAI CURRENCY SYMBOL BAHT
+    u'\u0e40'   #  0xE0 -> THAI CHARACTER SARA E
+    u'\u0e41'   #  0xE1 -> THAI CHARACTER SARA AE
+    u'\u0e42'   #  0xE2 -> THAI CHARACTER SARA O
+    u'\u0e43'   #  0xE3 -> THAI CHARACTER SARA AI MAIMUAN
+    u'\u0e44'   #  0xE4 -> THAI CHARACTER SARA AI MAIMALAI
+    u'\u0e45'   #  0xE5 -> THAI CHARACTER LAKKHANGYAO
+    u'\u0e46'   #  0xE6 -> THAI CHARACTER MAIYAMOK
+    u'\u0e47'   #  0xE7 -> THAI CHARACTER MAITAIKHU
+    u'\u0e48'   #  0xE8 -> THAI CHARACTER MAI EK
+    u'\u0e49'   #  0xE9 -> THAI CHARACTER MAI THO
+    u'\u0e4a'   #  0xEA -> THAI CHARACTER MAI TRI
+    u'\u0e4b'   #  0xEB -> THAI CHARACTER MAI CHATTAWA
+    u'\u0e4c'   #  0xEC -> THAI CHARACTER THANTHAKHAT
+    u'\u0e4d'   #  0xED -> THAI CHARACTER NIKHAHIT
+    u'\u0e4e'   #  0xEE -> THAI CHARACTER YAMAKKAN
+    u'\u0e4f'   #  0xEF -> THAI CHARACTER FONGMAN
+    u'\u0e50'   #  0xF0 -> THAI DIGIT ZERO
+    u'\u0e51'   #  0xF1 -> THAI DIGIT ONE
+    u'\u0e52'   #  0xF2 -> THAI DIGIT TWO
+    u'\u0e53'   #  0xF3 -> THAI DIGIT THREE
+    u'\u0e54'   #  0xF4 -> THAI DIGIT FOUR
+    u'\u0e55'   #  0xF5 -> THAI DIGIT FIVE
+    u'\u0e56'   #  0xF6 -> THAI DIGIT SIX
+    u'\u0e57'   #  0xF7 -> THAI DIGIT SEVEN
+    u'\u0e58'   #  0xF8 -> THAI DIGIT EIGHT
+    u'\u0e59'   #  0xF9 -> THAI DIGIT NINE
+    u'\u0e5a'   #  0xFA -> THAI CHARACTER ANGKHANKHU
+    u'\u0e5b'   #  0xFB -> THAI CHARACTER KHOMUT
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+)
+
+### Encoding table
+encoding_table=codecs.charmap_build(decoding_table)

Added: vendor/Python/current/Lib/encodings/iso8859_13.py
===================================================================
--- vendor/Python/current/Lib/encodings/iso8859_13.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/iso8859_13.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,307 @@
+""" Python Character Mapping Codec iso8859_13 generated from 'MAPPINGS/ISO8859/8859-13.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_table)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_table)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='iso8859-13',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x00 -> NULL
+    u'\x01'     #  0x01 -> START OF HEADING
+    u'\x02'     #  0x02 -> START OF TEXT
+    u'\x03'     #  0x03 -> END OF TEXT
+    u'\x04'     #  0x04 -> END OF TRANSMISSION
+    u'\x05'     #  0x05 -> ENQUIRY
+    u'\x06'     #  0x06 -> ACKNOWLEDGE
+    u'\x07'     #  0x07 -> BELL
+    u'\x08'     #  0x08 -> BACKSPACE
+    u'\t'       #  0x09 -> HORIZONTAL TABULATION
+    u'\n'       #  0x0A -> LINE FEED
+    u'\x0b'     #  0x0B -> VERTICAL TABULATION
+    u'\x0c'     #  0x0C -> FORM FEED
+    u'\r'       #  0x0D -> CARRIAGE RETURN
+    u'\x0e'     #  0x0E -> SHIFT OUT
+    u'\x0f'     #  0x0F -> SHIFT IN
+    u'\x10'     #  0x10 -> DATA LINK ESCAPE
+    u'\x11'     #  0x11 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x12 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x13 -> DEVICE CONTROL THREE
+    u'\x14'     #  0x14 -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x15 -> NEGATIVE ACKNOWLEDGE
+    u'\x16'     #  0x16 -> SYNCHRONOUS IDLE
+    u'\x17'     #  0x17 -> END OF TRANSMISSION BLOCK
+    u'\x18'     #  0x18 -> CANCEL
+    u'\x19'     #  0x19 -> END OF MEDIUM
+    u'\x1a'     #  0x1A -> SUBSTITUTE
+    u'\x1b'     #  0x1B -> ESCAPE
+    u'\x1c'     #  0x1C -> FILE SEPARATOR
+    u'\x1d'     #  0x1D -> GROUP SEPARATOR
+    u'\x1e'     #  0x1E -> RECORD SEPARATOR
+    u'\x1f'     #  0x1F -> UNIT SEPARATOR
+    u' '        #  0x20 -> SPACE
+    u'!'        #  0x21 -> EXCLAMATION MARK
+    u'"'        #  0x22 -> QUOTATION MARK
+    u'#'        #  0x23 -> NUMBER SIGN
+    u'$'        #  0x24 -> DOLLAR SIGN
+    u'%'        #  0x25 -> PERCENT SIGN
+    u'&'        #  0x26 -> AMPERSAND
+    u"'"        #  0x27 -> APOSTROPHE
+    u'('        #  0x28 -> LEFT PARENTHESIS
+    u')'        #  0x29 -> RIGHT PARENTHESIS
+    u'*'        #  0x2A -> ASTERISK
+    u'+'        #  0x2B -> PLUS SIGN
+    u','        #  0x2C -> COMMA
+    u'-'        #  0x2D -> HYPHEN-MINUS
+    u'.'        #  0x2E -> FULL STOP
+    u'/'        #  0x2F -> SOLIDUS
+    u'0'        #  0x30 -> DIGIT ZERO
+    u'1'        #  0x31 -> DIGIT ONE
+    u'2'        #  0x32 -> DIGIT TWO
+    u'3'        #  0x33 -> DIGIT THREE
+    u'4'        #  0x34 -> DIGIT FOUR
+    u'5'        #  0x35 -> DIGIT FIVE
+    u'6'        #  0x36 -> DIGIT SIX
+    u'7'        #  0x37 -> DIGIT SEVEN
+    u'8'        #  0x38 -> DIGIT EIGHT
+    u'9'        #  0x39 -> DIGIT NINE
+    u':'        #  0x3A -> COLON
+    u';'        #  0x3B -> SEMICOLON
+    u'<'        #  0x3C -> LESS-THAN SIGN
+    u'='        #  0x3D -> EQUALS SIGN
+    u'>'        #  0x3E -> GREATER-THAN SIGN
+    u'?'        #  0x3F -> QUESTION MARK
+    u'@'        #  0x40 -> COMMERCIAL AT
+    u'A'        #  0x41 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x42 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x43 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x44 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x45 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x46 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x47 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x48 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x49 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x4A -> LATIN CAPITAL LETTER J
+    u'K'        #  0x4B -> LATIN CAPITAL LETTER K
+    u'L'        #  0x4C -> LATIN CAPITAL LETTER L
+    u'M'        #  0x4D -> LATIN CAPITAL LETTER M
+    u'N'        #  0x4E -> LATIN CAPITAL LETTER N
+    u'O'        #  0x4F -> LATIN CAPITAL LETTER O
+    u'P'        #  0x50 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x51 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x52 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x53 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x54 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x55 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x56 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x57 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x58 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x59 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x5A -> LATIN CAPITAL LETTER Z
+    u'['        #  0x5B -> LEFT SQUARE BRACKET
+    u'\\'       #  0x5C -> REVERSE SOLIDUS
+    u']'        #  0x5D -> RIGHT SQUARE BRACKET
+    u'^'        #  0x5E -> CIRCUMFLEX ACCENT
+    u'_'        #  0x5F -> LOW LINE
+    u'`'        #  0x60 -> GRAVE ACCENT
+    u'a'        #  0x61 -> LATIN SMALL LETTER A
+    u'b'        #  0x62 -> LATIN SMALL LETTER B
+    u'c'        #  0x63 -> LATIN SMALL LETTER C
+    u'd'        #  0x64 -> LATIN SMALL LETTER D
+    u'e'        #  0x65 -> LATIN SMALL LETTER E
+    u'f'        #  0x66 -> LATIN SMALL LETTER F
+    u'g'        #  0x67 -> LATIN SMALL LETTER G
+    u'h'        #  0x68 -> LATIN SMALL LETTER H
+    u'i'        #  0x69 -> LATIN SMALL LETTER I
+    u'j'        #  0x6A -> LATIN SMALL LETTER J
+    u'k'        #  0x6B -> LATIN SMALL LETTER K
+    u'l'        #  0x6C -> LATIN SMALL LETTER L
+    u'm'        #  0x6D -> LATIN SMALL LETTER M
+    u'n'        #  0x6E -> LATIN SMALL LETTER N
+    u'o'        #  0x6F -> LATIN SMALL LETTER O
+    u'p'        #  0x70 -> LATIN SMALL LETTER P
+    u'q'        #  0x71 -> LATIN SMALL LETTER Q
+    u'r'        #  0x72 -> LATIN SMALL LETTER R
+    u's'        #  0x73 -> LATIN SMALL LETTER S
+    u't'        #  0x74 -> LATIN SMALL LETTER T
+    u'u'        #  0x75 -> LATIN SMALL LETTER U
+    u'v'        #  0x76 -> LATIN SMALL LETTER V
+    u'w'        #  0x77 -> LATIN SMALL LETTER W
+    u'x'        #  0x78 -> LATIN SMALL LETTER X
+    u'y'        #  0x79 -> LATIN SMALL LETTER Y
+    u'z'        #  0x7A -> LATIN SMALL LETTER Z
+    u'{'        #  0x7B -> LEFT CURLY BRACKET
+    u'|'        #  0x7C -> VERTICAL LINE
+    u'}'        #  0x7D -> RIGHT CURLY BRACKET
+    u'~'        #  0x7E -> TILDE
+    u'\x7f'     #  0x7F -> DELETE
+    u'\x80'     #  0x80 -> <control>
+    u'\x81'     #  0x81 -> <control>
+    u'\x82'     #  0x82 -> <control>
+    u'\x83'     #  0x83 -> <control>
+    u'\x84'     #  0x84 -> <control>
+    u'\x85'     #  0x85 -> <control>
+    u'\x86'     #  0x86 -> <control>
+    u'\x87'     #  0x87 -> <control>
+    u'\x88'     #  0x88 -> <control>
+    u'\x89'     #  0x89 -> <control>
+    u'\x8a'     #  0x8A -> <control>
+    u'\x8b'     #  0x8B -> <control>
+    u'\x8c'     #  0x8C -> <control>
+    u'\x8d'     #  0x8D -> <control>
+    u'\x8e'     #  0x8E -> <control>
+    u'\x8f'     #  0x8F -> <control>
+    u'\x90'     #  0x90 -> <control>
+    u'\x91'     #  0x91 -> <control>
+    u'\x92'     #  0x92 -> <control>
+    u'\x93'     #  0x93 -> <control>
+    u'\x94'     #  0x94 -> <control>
+    u'\x95'     #  0x95 -> <control>
+    u'\x96'     #  0x96 -> <control>
+    u'\x97'     #  0x97 -> <control>
+    u'\x98'     #  0x98 -> <control>
+    u'\x99'     #  0x99 -> <control>
+    u'\x9a'     #  0x9A -> <control>
+    u'\x9b'     #  0x9B -> <control>
+    u'\x9c'     #  0x9C -> <control>
+    u'\x9d'     #  0x9D -> <control>
+    u'\x9e'     #  0x9E -> <control>
+    u'\x9f'     #  0x9F -> <control>
+    u'\xa0'     #  0xA0 -> NO-BREAK SPACE
+    u'\u201d'   #  0xA1 -> RIGHT DOUBLE QUOTATION MARK
+    u'\xa2'     #  0xA2 -> CENT SIGN
+    u'\xa3'     #  0xA3 -> POUND SIGN
+    u'\xa4'     #  0xA4 -> CURRENCY SIGN
+    u'\u201e'   #  0xA5 -> DOUBLE LOW-9 QUOTATION MARK
+    u'\xa6'     #  0xA6 -> BROKEN BAR
+    u'\xa7'     #  0xA7 -> SECTION SIGN
+    u'\xd8'     #  0xA8 -> LATIN CAPITAL LETTER O WITH STROKE
+    u'\xa9'     #  0xA9 -> COPYRIGHT SIGN
+    u'\u0156'   #  0xAA -> LATIN CAPITAL LETTER R WITH CEDILLA
+    u'\xab'     #  0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xac'     #  0xAC -> NOT SIGN
+    u'\xad'     #  0xAD -> SOFT HYPHEN
+    u'\xae'     #  0xAE -> REGISTERED SIGN
+    u'\xc6'     #  0xAF -> LATIN CAPITAL LETTER AE
+    u'\xb0'     #  0xB0 -> DEGREE SIGN
+    u'\xb1'     #  0xB1 -> PLUS-MINUS SIGN
+    u'\xb2'     #  0xB2 -> SUPERSCRIPT TWO
+    u'\xb3'     #  0xB3 -> SUPERSCRIPT THREE
+    u'\u201c'   #  0xB4 -> LEFT DOUBLE QUOTATION MARK
+    u'\xb5'     #  0xB5 -> MICRO SIGN
+    u'\xb6'     #  0xB6 -> PILCROW SIGN
+    u'\xb7'     #  0xB7 -> MIDDLE DOT
+    u'\xf8'     #  0xB8 -> LATIN SMALL LETTER O WITH STROKE
+    u'\xb9'     #  0xB9 -> SUPERSCRIPT ONE
+    u'\u0157'   #  0xBA -> LATIN SMALL LETTER R WITH CEDILLA
+    u'\xbb'     #  0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xbc'     #  0xBC -> VULGAR FRACTION ONE QUARTER
+    u'\xbd'     #  0xBD -> VULGAR FRACTION ONE HALF
+    u'\xbe'     #  0xBE -> VULGAR FRACTION THREE QUARTERS
+    u'\xe6'     #  0xBF -> LATIN SMALL LETTER AE
+    u'\u0104'   #  0xC0 -> LATIN CAPITAL LETTER A WITH OGONEK
+    u'\u012e'   #  0xC1 -> LATIN CAPITAL LETTER I WITH OGONEK
+    u'\u0100'   #  0xC2 -> LATIN CAPITAL LETTER A WITH MACRON
+    u'\u0106'   #  0xC3 -> LATIN CAPITAL LETTER C WITH ACUTE
+    u'\xc4'     #  0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS
+    u'\xc5'     #  0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE
+    u'\u0118'   #  0xC6 -> LATIN CAPITAL LETTER E WITH OGONEK
+    u'\u0112'   #  0xC7 -> LATIN CAPITAL LETTER E WITH MACRON
+    u'\u010c'   #  0xC8 -> LATIN CAPITAL LETTER C WITH CARON
+    u'\xc9'     #  0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE
+    u'\u0179'   #  0xCA -> LATIN CAPITAL LETTER Z WITH ACUTE
+    u'\u0116'   #  0xCB -> LATIN CAPITAL LETTER E WITH DOT ABOVE
+    u'\u0122'   #  0xCC -> LATIN CAPITAL LETTER G WITH CEDILLA
+    u'\u0136'   #  0xCD -> LATIN CAPITAL LETTER K WITH CEDILLA
+    u'\u012a'   #  0xCE -> LATIN CAPITAL LETTER I WITH MACRON
+    u'\u013b'   #  0xCF -> LATIN CAPITAL LETTER L WITH CEDILLA
+    u'\u0160'   #  0xD0 -> LATIN CAPITAL LETTER S WITH CARON
+    u'\u0143'   #  0xD1 -> LATIN CAPITAL LETTER N WITH ACUTE
+    u'\u0145'   #  0xD2 -> LATIN CAPITAL LETTER N WITH CEDILLA
+    u'\xd3'     #  0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE
+    u'\u014c'   #  0xD4 -> LATIN CAPITAL LETTER O WITH MACRON
+    u'\xd5'     #  0xD5 -> LATIN CAPITAL LETTER O WITH TILDE
+    u'\xd6'     #  0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS
+    u'\xd7'     #  0xD7 -> MULTIPLICATION SIGN
+    u'\u0172'   #  0xD8 -> LATIN CAPITAL LETTER U WITH OGONEK
+    u'\u0141'   #  0xD9 -> LATIN CAPITAL LETTER L WITH STROKE
+    u'\u015a'   #  0xDA -> LATIN CAPITAL LETTER S WITH ACUTE
+    u'\u016a'   #  0xDB -> LATIN CAPITAL LETTER U WITH MACRON
+    u'\xdc'     #  0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS
+    u'\u017b'   #  0xDD -> LATIN CAPITAL LETTER Z WITH DOT ABOVE
+    u'\u017d'   #  0xDE -> LATIN CAPITAL LETTER Z WITH CARON
+    u'\xdf'     #  0xDF -> LATIN SMALL LETTER SHARP S (German)
+    u'\u0105'   #  0xE0 -> LATIN SMALL LETTER A WITH OGONEK
+    u'\u012f'   #  0xE1 -> LATIN SMALL LETTER I WITH OGONEK
+    u'\u0101'   #  0xE2 -> LATIN SMALL LETTER A WITH MACRON
+    u'\u0107'   #  0xE3 -> LATIN SMALL LETTER C WITH ACUTE
+    u'\xe4'     #  0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS
+    u'\xe5'     #  0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE
+    u'\u0119'   #  0xE6 -> LATIN SMALL LETTER E WITH OGONEK
+    u'\u0113'   #  0xE7 -> LATIN SMALL LETTER E WITH MACRON
+    u'\u010d'   #  0xE8 -> LATIN SMALL LETTER C WITH CARON
+    u'\xe9'     #  0xE9 -> LATIN SMALL LETTER E WITH ACUTE
+    u'\u017a'   #  0xEA -> LATIN SMALL LETTER Z WITH ACUTE
+    u'\u0117'   #  0xEB -> LATIN SMALL LETTER E WITH DOT ABOVE
+    u'\u0123'   #  0xEC -> LATIN SMALL LETTER G WITH CEDILLA
+    u'\u0137'   #  0xED -> LATIN SMALL LETTER K WITH CEDILLA
+    u'\u012b'   #  0xEE -> LATIN SMALL LETTER I WITH MACRON
+    u'\u013c'   #  0xEF -> LATIN SMALL LETTER L WITH CEDILLA
+    u'\u0161'   #  0xF0 -> LATIN SMALL LETTER S WITH CARON
+    u'\u0144'   #  0xF1 -> LATIN SMALL LETTER N WITH ACUTE
+    u'\u0146'   #  0xF2 -> LATIN SMALL LETTER N WITH CEDILLA
+    u'\xf3'     #  0xF3 -> LATIN SMALL LETTER O WITH ACUTE
+    u'\u014d'   #  0xF4 -> LATIN SMALL LETTER O WITH MACRON
+    u'\xf5'     #  0xF5 -> LATIN SMALL LETTER O WITH TILDE
+    u'\xf6'     #  0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS
+    u'\xf7'     #  0xF7 -> DIVISION SIGN
+    u'\u0173'   #  0xF8 -> LATIN SMALL LETTER U WITH OGONEK
+    u'\u0142'   #  0xF9 -> LATIN SMALL LETTER L WITH STROKE
+    u'\u015b'   #  0xFA -> LATIN SMALL LETTER S WITH ACUTE
+    u'\u016b'   #  0xFB -> LATIN SMALL LETTER U WITH MACRON
+    u'\xfc'     #  0xFC -> LATIN SMALL LETTER U WITH DIAERESIS
+    u'\u017c'   #  0xFD -> LATIN SMALL LETTER Z WITH DOT ABOVE
+    u'\u017e'   #  0xFE -> LATIN SMALL LETTER Z WITH CARON
+    u'\u2019'   #  0xFF -> RIGHT SINGLE QUOTATION MARK
+)
+
+### Encoding table
+encoding_table=codecs.charmap_build(decoding_table)

Added: vendor/Python/current/Lib/encodings/iso8859_14.py
===================================================================
--- vendor/Python/current/Lib/encodings/iso8859_14.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/iso8859_14.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,307 @@
+""" Python Character Mapping Codec iso8859_14 generated from 'MAPPINGS/ISO8859/8859-14.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_table)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_table)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='iso8859-14',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x00 -> NULL
+    u'\x01'     #  0x01 -> START OF HEADING
+    u'\x02'     #  0x02 -> START OF TEXT
+    u'\x03'     #  0x03 -> END OF TEXT
+    u'\x04'     #  0x04 -> END OF TRANSMISSION
+    u'\x05'     #  0x05 -> ENQUIRY
+    u'\x06'     #  0x06 -> ACKNOWLEDGE
+    u'\x07'     #  0x07 -> BELL
+    u'\x08'     #  0x08 -> BACKSPACE
+    u'\t'       #  0x09 -> HORIZONTAL TABULATION
+    u'\n'       #  0x0A -> LINE FEED
+    u'\x0b'     #  0x0B -> VERTICAL TABULATION
+    u'\x0c'     #  0x0C -> FORM FEED
+    u'\r'       #  0x0D -> CARRIAGE RETURN
+    u'\x0e'     #  0x0E -> SHIFT OUT
+    u'\x0f'     #  0x0F -> SHIFT IN
+    u'\x10'     #  0x10 -> DATA LINK ESCAPE
+    u'\x11'     #  0x11 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x12 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x13 -> DEVICE CONTROL THREE
+    u'\x14'     #  0x14 -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x15 -> NEGATIVE ACKNOWLEDGE
+    u'\x16'     #  0x16 -> SYNCHRONOUS IDLE
+    u'\x17'     #  0x17 -> END OF TRANSMISSION BLOCK
+    u'\x18'     #  0x18 -> CANCEL
+    u'\x19'     #  0x19 -> END OF MEDIUM
+    u'\x1a'     #  0x1A -> SUBSTITUTE
+    u'\x1b'     #  0x1B -> ESCAPE
+    u'\x1c'     #  0x1C -> FILE SEPARATOR
+    u'\x1d'     #  0x1D -> GROUP SEPARATOR
+    u'\x1e'     #  0x1E -> RECORD SEPARATOR
+    u'\x1f'     #  0x1F -> UNIT SEPARATOR
+    u' '        #  0x20 -> SPACE
+    u'!'        #  0x21 -> EXCLAMATION MARK
+    u'"'        #  0x22 -> QUOTATION MARK
+    u'#'        #  0x23 -> NUMBER SIGN
+    u'$'        #  0x24 -> DOLLAR SIGN
+    u'%'        #  0x25 -> PERCENT SIGN
+    u'&'        #  0x26 -> AMPERSAND
+    u"'"        #  0x27 -> APOSTROPHE
+    u'('        #  0x28 -> LEFT PARENTHESIS
+    u')'        #  0x29 -> RIGHT PARENTHESIS
+    u'*'        #  0x2A -> ASTERISK
+    u'+'        #  0x2B -> PLUS SIGN
+    u','        #  0x2C -> COMMA
+    u'-'        #  0x2D -> HYPHEN-MINUS
+    u'.'        #  0x2E -> FULL STOP
+    u'/'        #  0x2F -> SOLIDUS
+    u'0'        #  0x30 -> DIGIT ZERO
+    u'1'        #  0x31 -> DIGIT ONE
+    u'2'        #  0x32 -> DIGIT TWO
+    u'3'        #  0x33 -> DIGIT THREE
+    u'4'        #  0x34 -> DIGIT FOUR
+    u'5'        #  0x35 -> DIGIT FIVE
+    u'6'        #  0x36 -> DIGIT SIX
+    u'7'        #  0x37 -> DIGIT SEVEN
+    u'8'        #  0x38 -> DIGIT EIGHT
+    u'9'        #  0x39 -> DIGIT NINE
+    u':'        #  0x3A -> COLON
+    u';'        #  0x3B -> SEMICOLON
+    u'<'        #  0x3C -> LESS-THAN SIGN
+    u'='        #  0x3D -> EQUALS SIGN
+    u'>'        #  0x3E -> GREATER-THAN SIGN
+    u'?'        #  0x3F -> QUESTION MARK
+    u'@'        #  0x40 -> COMMERCIAL AT
+    u'A'        #  0x41 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x42 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x43 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x44 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x45 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x46 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x47 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x48 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x49 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x4A -> LATIN CAPITAL LETTER J
+    u'K'        #  0x4B -> LATIN CAPITAL LETTER K
+    u'L'        #  0x4C -> LATIN CAPITAL LETTER L
+    u'M'        #  0x4D -> LATIN CAPITAL LETTER M
+    u'N'        #  0x4E -> LATIN CAPITAL LETTER N
+    u'O'        #  0x4F -> LATIN CAPITAL LETTER O
+    u'P'        #  0x50 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x51 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x52 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x53 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x54 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x55 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x56 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x57 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x58 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x59 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x5A -> LATIN CAPITAL LETTER Z
+    u'['        #  0x5B -> LEFT SQUARE BRACKET
+    u'\\'       #  0x5C -> REVERSE SOLIDUS
+    u']'        #  0x5D -> RIGHT SQUARE BRACKET
+    u'^'        #  0x5E -> CIRCUMFLEX ACCENT
+    u'_'        #  0x5F -> LOW LINE
+    u'`'        #  0x60 -> GRAVE ACCENT
+    u'a'        #  0x61 -> LATIN SMALL LETTER A
+    u'b'        #  0x62 -> LATIN SMALL LETTER B
+    u'c'        #  0x63 -> LATIN SMALL LETTER C
+    u'd'        #  0x64 -> LATIN SMALL LETTER D
+    u'e'        #  0x65 -> LATIN SMALL LETTER E
+    u'f'        #  0x66 -> LATIN SMALL LETTER F
+    u'g'        #  0x67 -> LATIN SMALL LETTER G
+    u'h'        #  0x68 -> LATIN SMALL LETTER H
+    u'i'        #  0x69 -> LATIN SMALL LETTER I
+    u'j'        #  0x6A -> LATIN SMALL LETTER J
+    u'k'        #  0x6B -> LATIN SMALL LETTER K
+    u'l'        #  0x6C -> LATIN SMALL LETTER L
+    u'm'        #  0x6D -> LATIN SMALL LETTER M
+    u'n'        #  0x6E -> LATIN SMALL LETTER N
+    u'o'        #  0x6F -> LATIN SMALL LETTER O
+    u'p'        #  0x70 -> LATIN SMALL LETTER P
+    u'q'        #  0x71 -> LATIN SMALL LETTER Q
+    u'r'        #  0x72 -> LATIN SMALL LETTER R
+    u's'        #  0x73 -> LATIN SMALL LETTER S
+    u't'        #  0x74 -> LATIN SMALL LETTER T
+    u'u'        #  0x75 -> LATIN SMALL LETTER U
+    u'v'        #  0x76 -> LATIN SMALL LETTER V
+    u'w'        #  0x77 -> LATIN SMALL LETTER W
+    u'x'        #  0x78 -> LATIN SMALL LETTER X
+    u'y'        #  0x79 -> LATIN SMALL LETTER Y
+    u'z'        #  0x7A -> LATIN SMALL LETTER Z
+    u'{'        #  0x7B -> LEFT CURLY BRACKET
+    u'|'        #  0x7C -> VERTICAL LINE
+    u'}'        #  0x7D -> RIGHT CURLY BRACKET
+    u'~'        #  0x7E -> TILDE
+    u'\x7f'     #  0x7F -> DELETE
+    u'\x80'     #  0x80 -> <control>
+    u'\x81'     #  0x81 -> <control>
+    u'\x82'     #  0x82 -> <control>
+    u'\x83'     #  0x83 -> <control>
+    u'\x84'     #  0x84 -> <control>
+    u'\x85'     #  0x85 -> <control>
+    u'\x86'     #  0x86 -> <control>
+    u'\x87'     #  0x87 -> <control>
+    u'\x88'     #  0x88 -> <control>
+    u'\x89'     #  0x89 -> <control>
+    u'\x8a'     #  0x8A -> <control>
+    u'\x8b'     #  0x8B -> <control>
+    u'\x8c'     #  0x8C -> <control>
+    u'\x8d'     #  0x8D -> <control>
+    u'\x8e'     #  0x8E -> <control>
+    u'\x8f'     #  0x8F -> <control>
+    u'\x90'     #  0x90 -> <control>
+    u'\x91'     #  0x91 -> <control>
+    u'\x92'     #  0x92 -> <control>
+    u'\x93'     #  0x93 -> <control>
+    u'\x94'     #  0x94 -> <control>
+    u'\x95'     #  0x95 -> <control>
+    u'\x96'     #  0x96 -> <control>
+    u'\x97'     #  0x97 -> <control>
+    u'\x98'     #  0x98 -> <control>
+    u'\x99'     #  0x99 -> <control>
+    u'\x9a'     #  0x9A -> <control>
+    u'\x9b'     #  0x9B -> <control>
+    u'\x9c'     #  0x9C -> <control>
+    u'\x9d'     #  0x9D -> <control>
+    u'\x9e'     #  0x9E -> <control>
+    u'\x9f'     #  0x9F -> <control>
+    u'\xa0'     #  0xA0 -> NO-BREAK SPACE
+    u'\u1e02'   #  0xA1 -> LATIN CAPITAL LETTER B WITH DOT ABOVE
+    u'\u1e03'   #  0xA2 -> LATIN SMALL LETTER B WITH DOT ABOVE
+    u'\xa3'     #  0xA3 -> POUND SIGN
+    u'\u010a'   #  0xA4 -> LATIN CAPITAL LETTER C WITH DOT ABOVE
+    u'\u010b'   #  0xA5 -> LATIN SMALL LETTER C WITH DOT ABOVE
+    u'\u1e0a'   #  0xA6 -> LATIN CAPITAL LETTER D WITH DOT ABOVE
+    u'\xa7'     #  0xA7 -> SECTION SIGN
+    u'\u1e80'   #  0xA8 -> LATIN CAPITAL LETTER W WITH GRAVE
+    u'\xa9'     #  0xA9 -> COPYRIGHT SIGN
+    u'\u1e82'   #  0xAA -> LATIN CAPITAL LETTER W WITH ACUTE
+    u'\u1e0b'   #  0xAB -> LATIN SMALL LETTER D WITH DOT ABOVE
+    u'\u1ef2'   #  0xAC -> LATIN CAPITAL LETTER Y WITH GRAVE
+    u'\xad'     #  0xAD -> SOFT HYPHEN
+    u'\xae'     #  0xAE -> REGISTERED SIGN
+    u'\u0178'   #  0xAF -> LATIN CAPITAL LETTER Y WITH DIAERESIS
+    u'\u1e1e'   #  0xB0 -> LATIN CAPITAL LETTER F WITH DOT ABOVE
+    u'\u1e1f'   #  0xB1 -> LATIN SMALL LETTER F WITH DOT ABOVE
+    u'\u0120'   #  0xB2 -> LATIN CAPITAL LETTER G WITH DOT ABOVE
+    u'\u0121'   #  0xB3 -> LATIN SMALL LETTER G WITH DOT ABOVE
+    u'\u1e40'   #  0xB4 -> LATIN CAPITAL LETTER M WITH DOT ABOVE
+    u'\u1e41'   #  0xB5 -> LATIN SMALL LETTER M WITH DOT ABOVE
+    u'\xb6'     #  0xB6 -> PILCROW SIGN
+    u'\u1e56'   #  0xB7 -> LATIN CAPITAL LETTER P WITH DOT ABOVE
+    u'\u1e81'   #  0xB8 -> LATIN SMALL LETTER W WITH GRAVE
+    u'\u1e57'   #  0xB9 -> LATIN SMALL LETTER P WITH DOT ABOVE
+    u'\u1e83'   #  0xBA -> LATIN SMALL LETTER W WITH ACUTE
+    u'\u1e60'   #  0xBB -> LATIN CAPITAL LETTER S WITH DOT ABOVE
+    u'\u1ef3'   #  0xBC -> LATIN SMALL LETTER Y WITH GRAVE
+    u'\u1e84'   #  0xBD -> LATIN CAPITAL LETTER W WITH DIAERESIS
+    u'\u1e85'   #  0xBE -> LATIN SMALL LETTER W WITH DIAERESIS
+    u'\u1e61'   #  0xBF -> LATIN SMALL LETTER S WITH DOT ABOVE
+    u'\xc0'     #  0xC0 -> LATIN CAPITAL LETTER A WITH GRAVE
+    u'\xc1'     #  0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE
+    u'\xc2'     #  0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+    u'\xc3'     #  0xC3 -> LATIN CAPITAL LETTER A WITH TILDE
+    u'\xc4'     #  0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS
+    u'\xc5'     #  0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE
+    u'\xc6'     #  0xC6 -> LATIN CAPITAL LETTER AE
+    u'\xc7'     #  0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA
+    u'\xc8'     #  0xC8 -> LATIN CAPITAL LETTER E WITH GRAVE
+    u'\xc9'     #  0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE
+    u'\xca'     #  0xCA -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+    u'\xcb'     #  0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS
+    u'\xcc'     #  0xCC -> LATIN CAPITAL LETTER I WITH GRAVE
+    u'\xcd'     #  0xCD -> LATIN CAPITAL LETTER I WITH ACUTE
+    u'\xce'     #  0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+    u'\xcf'     #  0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS
+    u'\u0174'   #  0xD0 -> LATIN CAPITAL LETTER W WITH CIRCUMFLEX
+    u'\xd1'     #  0xD1 -> LATIN CAPITAL LETTER N WITH TILDE
+    u'\xd2'     #  0xD2 -> LATIN CAPITAL LETTER O WITH GRAVE
+    u'\xd3'     #  0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE
+    u'\xd4'     #  0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+    u'\xd5'     #  0xD5 -> LATIN CAPITAL LETTER O WITH TILDE
+    u'\xd6'     #  0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS
+    u'\u1e6a'   #  0xD7 -> LATIN CAPITAL LETTER T WITH DOT ABOVE
+    u'\xd8'     #  0xD8 -> LATIN CAPITAL LETTER O WITH STROKE
+    u'\xd9'     #  0xD9 -> LATIN CAPITAL LETTER U WITH GRAVE
+    u'\xda'     #  0xDA -> LATIN CAPITAL LETTER U WITH ACUTE
+    u'\xdb'     #  0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+    u'\xdc'     #  0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS
+    u'\xdd'     #  0xDD -> LATIN CAPITAL LETTER Y WITH ACUTE
+    u'\u0176'   #  0xDE -> LATIN CAPITAL LETTER Y WITH CIRCUMFLEX
+    u'\xdf'     #  0xDF -> LATIN SMALL LETTER SHARP S
+    u'\xe0'     #  0xE0 -> LATIN SMALL LETTER A WITH GRAVE
+    u'\xe1'     #  0xE1 -> LATIN SMALL LETTER A WITH ACUTE
+    u'\xe2'     #  0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX
+    u'\xe3'     #  0xE3 -> LATIN SMALL LETTER A WITH TILDE
+    u'\xe4'     #  0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS
+    u'\xe5'     #  0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE
+    u'\xe6'     #  0xE6 -> LATIN SMALL LETTER AE
+    u'\xe7'     #  0xE7 -> LATIN SMALL LETTER C WITH CEDILLA
+    u'\xe8'     #  0xE8 -> LATIN SMALL LETTER E WITH GRAVE
+    u'\xe9'     #  0xE9 -> LATIN SMALL LETTER E WITH ACUTE
+    u'\xea'     #  0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX
+    u'\xeb'     #  0xEB -> LATIN SMALL LETTER E WITH DIAERESIS
+    u'\xec'     #  0xEC -> LATIN SMALL LETTER I WITH GRAVE
+    u'\xed'     #  0xED -> LATIN SMALL LETTER I WITH ACUTE
+    u'\xee'     #  0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX
+    u'\xef'     #  0xEF -> LATIN SMALL LETTER I WITH DIAERESIS
+    u'\u0175'   #  0xF0 -> LATIN SMALL LETTER W WITH CIRCUMFLEX
+    u'\xf1'     #  0xF1 -> LATIN SMALL LETTER N WITH TILDE
+    u'\xf2'     #  0xF2 -> LATIN SMALL LETTER O WITH GRAVE
+    u'\xf3'     #  0xF3 -> LATIN SMALL LETTER O WITH ACUTE
+    u'\xf4'     #  0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX
+    u'\xf5'     #  0xF5 -> LATIN SMALL LETTER O WITH TILDE
+    u'\xf6'     #  0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS
+    u'\u1e6b'   #  0xF7 -> LATIN SMALL LETTER T WITH DOT ABOVE
+    u'\xf8'     #  0xF8 -> LATIN SMALL LETTER O WITH STROKE
+    u'\xf9'     #  0xF9 -> LATIN SMALL LETTER U WITH GRAVE
+    u'\xfa'     #  0xFA -> LATIN SMALL LETTER U WITH ACUTE
+    u'\xfb'     #  0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX
+    u'\xfc'     #  0xFC -> LATIN SMALL LETTER U WITH DIAERESIS
+    u'\xfd'     #  0xFD -> LATIN SMALL LETTER Y WITH ACUTE
+    u'\u0177'   #  0xFE -> LATIN SMALL LETTER Y WITH CIRCUMFLEX
+    u'\xff'     #  0xFF -> LATIN SMALL LETTER Y WITH DIAERESIS
+)
+
+### Encoding table
+encoding_table=codecs.charmap_build(decoding_table)

Added: vendor/Python/current/Lib/encodings/iso8859_15.py
===================================================================
--- vendor/Python/current/Lib/encodings/iso8859_15.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/iso8859_15.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,307 @@
+""" Python Character Mapping Codec iso8859_15 generated from 'MAPPINGS/ISO8859/8859-15.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_table)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_table)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='iso8859-15',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x00 -> NULL
+    u'\x01'     #  0x01 -> START OF HEADING
+    u'\x02'     #  0x02 -> START OF TEXT
+    u'\x03'     #  0x03 -> END OF TEXT
+    u'\x04'     #  0x04 -> END OF TRANSMISSION
+    u'\x05'     #  0x05 -> ENQUIRY
+    u'\x06'     #  0x06 -> ACKNOWLEDGE
+    u'\x07'     #  0x07 -> BELL
+    u'\x08'     #  0x08 -> BACKSPACE
+    u'\t'       #  0x09 -> HORIZONTAL TABULATION
+    u'\n'       #  0x0A -> LINE FEED
+    u'\x0b'     #  0x0B -> VERTICAL TABULATION
+    u'\x0c'     #  0x0C -> FORM FEED
+    u'\r'       #  0x0D -> CARRIAGE RETURN
+    u'\x0e'     #  0x0E -> SHIFT OUT
+    u'\x0f'     #  0x0F -> SHIFT IN
+    u'\x10'     #  0x10 -> DATA LINK ESCAPE
+    u'\x11'     #  0x11 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x12 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x13 -> DEVICE CONTROL THREE
+    u'\x14'     #  0x14 -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x15 -> NEGATIVE ACKNOWLEDGE
+    u'\x16'     #  0x16 -> SYNCHRONOUS IDLE
+    u'\x17'     #  0x17 -> END OF TRANSMISSION BLOCK
+    u'\x18'     #  0x18 -> CANCEL
+    u'\x19'     #  0x19 -> END OF MEDIUM
+    u'\x1a'     #  0x1A -> SUBSTITUTE
+    u'\x1b'     #  0x1B -> ESCAPE
+    u'\x1c'     #  0x1C -> FILE SEPARATOR
+    u'\x1d'     #  0x1D -> GROUP SEPARATOR
+    u'\x1e'     #  0x1E -> RECORD SEPARATOR
+    u'\x1f'     #  0x1F -> UNIT SEPARATOR
+    u' '        #  0x20 -> SPACE
+    u'!'        #  0x21 -> EXCLAMATION MARK
+    u'"'        #  0x22 -> QUOTATION MARK
+    u'#'        #  0x23 -> NUMBER SIGN
+    u'$'        #  0x24 -> DOLLAR SIGN
+    u'%'        #  0x25 -> PERCENT SIGN
+    u'&'        #  0x26 -> AMPERSAND
+    u"'"        #  0x27 -> APOSTROPHE
+    u'('        #  0x28 -> LEFT PARENTHESIS
+    u')'        #  0x29 -> RIGHT PARENTHESIS
+    u'*'        #  0x2A -> ASTERISK
+    u'+'        #  0x2B -> PLUS SIGN
+    u','        #  0x2C -> COMMA
+    u'-'        #  0x2D -> HYPHEN-MINUS
+    u'.'        #  0x2E -> FULL STOP
+    u'/'        #  0x2F -> SOLIDUS
+    u'0'        #  0x30 -> DIGIT ZERO
+    u'1'        #  0x31 -> DIGIT ONE
+    u'2'        #  0x32 -> DIGIT TWO
+    u'3'        #  0x33 -> DIGIT THREE
+    u'4'        #  0x34 -> DIGIT FOUR
+    u'5'        #  0x35 -> DIGIT FIVE
+    u'6'        #  0x36 -> DIGIT SIX
+    u'7'        #  0x37 -> DIGIT SEVEN
+    u'8'        #  0x38 -> DIGIT EIGHT
+    u'9'        #  0x39 -> DIGIT NINE
+    u':'        #  0x3A -> COLON
+    u';'        #  0x3B -> SEMICOLON
+    u'<'        #  0x3C -> LESS-THAN SIGN
+    u'='        #  0x3D -> EQUALS SIGN
+    u'>'        #  0x3E -> GREATER-THAN SIGN
+    u'?'        #  0x3F -> QUESTION MARK
+    u'@'        #  0x40 -> COMMERCIAL AT
+    u'A'        #  0x41 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x42 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x43 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x44 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x45 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x46 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x47 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x48 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x49 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x4A -> LATIN CAPITAL LETTER J
+    u'K'        #  0x4B -> LATIN CAPITAL LETTER K
+    u'L'        #  0x4C -> LATIN CAPITAL LETTER L
+    u'M'        #  0x4D -> LATIN CAPITAL LETTER M
+    u'N'        #  0x4E -> LATIN CAPITAL LETTER N
+    u'O'        #  0x4F -> LATIN CAPITAL LETTER O
+    u'P'        #  0x50 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x51 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x52 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x53 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x54 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x55 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x56 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x57 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x58 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x59 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x5A -> LATIN CAPITAL LETTER Z
+    u'['        #  0x5B -> LEFT SQUARE BRACKET
+    u'\\'       #  0x5C -> REVERSE SOLIDUS
+    u']'        #  0x5D -> RIGHT SQUARE BRACKET
+    u'^'        #  0x5E -> CIRCUMFLEX ACCENT
+    u'_'        #  0x5F -> LOW LINE
+    u'`'        #  0x60 -> GRAVE ACCENT
+    u'a'        #  0x61 -> LATIN SMALL LETTER A
+    u'b'        #  0x62 -> LATIN SMALL LETTER B
+    u'c'        #  0x63 -> LATIN SMALL LETTER C
+    u'd'        #  0x64 -> LATIN SMALL LETTER D
+    u'e'        #  0x65 -> LATIN SMALL LETTER E
+    u'f'        #  0x66 -> LATIN SMALL LETTER F
+    u'g'        #  0x67 -> LATIN SMALL LETTER G
+    u'h'        #  0x68 -> LATIN SMALL LETTER H
+    u'i'        #  0x69 -> LATIN SMALL LETTER I
+    u'j'        #  0x6A -> LATIN SMALL LETTER J
+    u'k'        #  0x6B -> LATIN SMALL LETTER K
+    u'l'        #  0x6C -> LATIN SMALL LETTER L
+    u'm'        #  0x6D -> LATIN SMALL LETTER M
+    u'n'        #  0x6E -> LATIN SMALL LETTER N
+    u'o'        #  0x6F -> LATIN SMALL LETTER O
+    u'p'        #  0x70 -> LATIN SMALL LETTER P
+    u'q'        #  0x71 -> LATIN SMALL LETTER Q
+    u'r'        #  0x72 -> LATIN SMALL LETTER R
+    u's'        #  0x73 -> LATIN SMALL LETTER S
+    u't'        #  0x74 -> LATIN SMALL LETTER T
+    u'u'        #  0x75 -> LATIN SMALL LETTER U
+    u'v'        #  0x76 -> LATIN SMALL LETTER V
+    u'w'        #  0x77 -> LATIN SMALL LETTER W
+    u'x'        #  0x78 -> LATIN SMALL LETTER X
+    u'y'        #  0x79 -> LATIN SMALL LETTER Y
+    u'z'        #  0x7A -> LATIN SMALL LETTER Z
+    u'{'        #  0x7B -> LEFT CURLY BRACKET
+    u'|'        #  0x7C -> VERTICAL LINE
+    u'}'        #  0x7D -> RIGHT CURLY BRACKET
+    u'~'        #  0x7E -> TILDE
+    u'\x7f'     #  0x7F -> DELETE
+    u'\x80'     #  0x80 -> <control>
+    u'\x81'     #  0x81 -> <control>
+    u'\x82'     #  0x82 -> <control>
+    u'\x83'     #  0x83 -> <control>
+    u'\x84'     #  0x84 -> <control>
+    u'\x85'     #  0x85 -> <control>
+    u'\x86'     #  0x86 -> <control>
+    u'\x87'     #  0x87 -> <control>
+    u'\x88'     #  0x88 -> <control>
+    u'\x89'     #  0x89 -> <control>
+    u'\x8a'     #  0x8A -> <control>
+    u'\x8b'     #  0x8B -> <control>
+    u'\x8c'     #  0x8C -> <control>
+    u'\x8d'     #  0x8D -> <control>
+    u'\x8e'     #  0x8E -> <control>
+    u'\x8f'     #  0x8F -> <control>
+    u'\x90'     #  0x90 -> <control>
+    u'\x91'     #  0x91 -> <control>
+    u'\x92'     #  0x92 -> <control>
+    u'\x93'     #  0x93 -> <control>
+    u'\x94'     #  0x94 -> <control>
+    u'\x95'     #  0x95 -> <control>
+    u'\x96'     #  0x96 -> <control>
+    u'\x97'     #  0x97 -> <control>
+    u'\x98'     #  0x98 -> <control>
+    u'\x99'     #  0x99 -> <control>
+    u'\x9a'     #  0x9A -> <control>
+    u'\x9b'     #  0x9B -> <control>
+    u'\x9c'     #  0x9C -> <control>
+    u'\x9d'     #  0x9D -> <control>
+    u'\x9e'     #  0x9E -> <control>
+    u'\x9f'     #  0x9F -> <control>
+    u'\xa0'     #  0xA0 -> NO-BREAK SPACE
+    u'\xa1'     #  0xA1 -> INVERTED EXCLAMATION MARK
+    u'\xa2'     #  0xA2 -> CENT SIGN
+    u'\xa3'     #  0xA3 -> POUND SIGN
+    u'\u20ac'   #  0xA4 -> EURO SIGN
+    u'\xa5'     #  0xA5 -> YEN SIGN
+    u'\u0160'   #  0xA6 -> LATIN CAPITAL LETTER S WITH CARON
+    u'\xa7'     #  0xA7 -> SECTION SIGN
+    u'\u0161'   #  0xA8 -> LATIN SMALL LETTER S WITH CARON
+    u'\xa9'     #  0xA9 -> COPYRIGHT SIGN
+    u'\xaa'     #  0xAA -> FEMININE ORDINAL INDICATOR
+    u'\xab'     #  0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xac'     #  0xAC -> NOT SIGN
+    u'\xad'     #  0xAD -> SOFT HYPHEN
+    u'\xae'     #  0xAE -> REGISTERED SIGN
+    u'\xaf'     #  0xAF -> MACRON
+    u'\xb0'     #  0xB0 -> DEGREE SIGN
+    u'\xb1'     #  0xB1 -> PLUS-MINUS SIGN
+    u'\xb2'     #  0xB2 -> SUPERSCRIPT TWO
+    u'\xb3'     #  0xB3 -> SUPERSCRIPT THREE
+    u'\u017d'   #  0xB4 -> LATIN CAPITAL LETTER Z WITH CARON
+    u'\xb5'     #  0xB5 -> MICRO SIGN
+    u'\xb6'     #  0xB6 -> PILCROW SIGN
+    u'\xb7'     #  0xB7 -> MIDDLE DOT
+    u'\u017e'   #  0xB8 -> LATIN SMALL LETTER Z WITH CARON
+    u'\xb9'     #  0xB9 -> SUPERSCRIPT ONE
+    u'\xba'     #  0xBA -> MASCULINE ORDINAL INDICATOR
+    u'\xbb'     #  0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\u0152'   #  0xBC -> LATIN CAPITAL LIGATURE OE
+    u'\u0153'   #  0xBD -> LATIN SMALL LIGATURE OE
+    u'\u0178'   #  0xBE -> LATIN CAPITAL LETTER Y WITH DIAERESIS
+    u'\xbf'     #  0xBF -> INVERTED QUESTION MARK
+    u'\xc0'     #  0xC0 -> LATIN CAPITAL LETTER A WITH GRAVE
+    u'\xc1'     #  0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE
+    u'\xc2'     #  0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+    u'\xc3'     #  0xC3 -> LATIN CAPITAL LETTER A WITH TILDE
+    u'\xc4'     #  0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS
+    u'\xc5'     #  0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE
+    u'\xc6'     #  0xC6 -> LATIN CAPITAL LETTER AE
+    u'\xc7'     #  0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA
+    u'\xc8'     #  0xC8 -> LATIN CAPITAL LETTER E WITH GRAVE
+    u'\xc9'     #  0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE
+    u'\xca'     #  0xCA -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+    u'\xcb'     #  0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS
+    u'\xcc'     #  0xCC -> LATIN CAPITAL LETTER I WITH GRAVE
+    u'\xcd'     #  0xCD -> LATIN CAPITAL LETTER I WITH ACUTE
+    u'\xce'     #  0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+    u'\xcf'     #  0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS
+    u'\xd0'     #  0xD0 -> LATIN CAPITAL LETTER ETH
+    u'\xd1'     #  0xD1 -> LATIN CAPITAL LETTER N WITH TILDE
+    u'\xd2'     #  0xD2 -> LATIN CAPITAL LETTER O WITH GRAVE
+    u'\xd3'     #  0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE
+    u'\xd4'     #  0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+    u'\xd5'     #  0xD5 -> LATIN CAPITAL LETTER O WITH TILDE
+    u'\xd6'     #  0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS
+    u'\xd7'     #  0xD7 -> MULTIPLICATION SIGN
+    u'\xd8'     #  0xD8 -> LATIN CAPITAL LETTER O WITH STROKE
+    u'\xd9'     #  0xD9 -> LATIN CAPITAL LETTER U WITH GRAVE
+    u'\xda'     #  0xDA -> LATIN CAPITAL LETTER U WITH ACUTE
+    u'\xdb'     #  0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+    u'\xdc'     #  0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS
+    u'\xdd'     #  0xDD -> LATIN CAPITAL LETTER Y WITH ACUTE
+    u'\xde'     #  0xDE -> LATIN CAPITAL LETTER THORN
+    u'\xdf'     #  0xDF -> LATIN SMALL LETTER SHARP S
+    u'\xe0'     #  0xE0 -> LATIN SMALL LETTER A WITH GRAVE
+    u'\xe1'     #  0xE1 -> LATIN SMALL LETTER A WITH ACUTE
+    u'\xe2'     #  0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX
+    u'\xe3'     #  0xE3 -> LATIN SMALL LETTER A WITH TILDE
+    u'\xe4'     #  0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS
+    u'\xe5'     #  0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE
+    u'\xe6'     #  0xE6 -> LATIN SMALL LETTER AE
+    u'\xe7'     #  0xE7 -> LATIN SMALL LETTER C WITH CEDILLA
+    u'\xe8'     #  0xE8 -> LATIN SMALL LETTER E WITH GRAVE
+    u'\xe9'     #  0xE9 -> LATIN SMALL LETTER E WITH ACUTE
+    u'\xea'     #  0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX
+    u'\xeb'     #  0xEB -> LATIN SMALL LETTER E WITH DIAERESIS
+    u'\xec'     #  0xEC -> LATIN SMALL LETTER I WITH GRAVE
+    u'\xed'     #  0xED -> LATIN SMALL LETTER I WITH ACUTE
+    u'\xee'     #  0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX
+    u'\xef'     #  0xEF -> LATIN SMALL LETTER I WITH DIAERESIS
+    u'\xf0'     #  0xF0 -> LATIN SMALL LETTER ETH
+    u'\xf1'     #  0xF1 -> LATIN SMALL LETTER N WITH TILDE
+    u'\xf2'     #  0xF2 -> LATIN SMALL LETTER O WITH GRAVE
+    u'\xf3'     #  0xF3 -> LATIN SMALL LETTER O WITH ACUTE
+    u'\xf4'     #  0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX
+    u'\xf5'     #  0xF5 -> LATIN SMALL LETTER O WITH TILDE
+    u'\xf6'     #  0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS
+    u'\xf7'     #  0xF7 -> DIVISION SIGN
+    u'\xf8'     #  0xF8 -> LATIN SMALL LETTER O WITH STROKE
+    u'\xf9'     #  0xF9 -> LATIN SMALL LETTER U WITH GRAVE
+    u'\xfa'     #  0xFA -> LATIN SMALL LETTER U WITH ACUTE
+    u'\xfb'     #  0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX
+    u'\xfc'     #  0xFC -> LATIN SMALL LETTER U WITH DIAERESIS
+    u'\xfd'     #  0xFD -> LATIN SMALL LETTER Y WITH ACUTE
+    u'\xfe'     #  0xFE -> LATIN SMALL LETTER THORN
+    u'\xff'     #  0xFF -> LATIN SMALL LETTER Y WITH DIAERESIS
+)
+
+### Encoding table
+encoding_table=codecs.charmap_build(decoding_table)

Added: vendor/Python/current/Lib/encodings/iso8859_16.py
===================================================================
--- vendor/Python/current/Lib/encodings/iso8859_16.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/iso8859_16.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,307 @@
+""" Python Character Mapping Codec iso8859_16 generated from 'MAPPINGS/ISO8859/8859-16.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_table)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_table)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='iso8859-16',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x00 -> NULL
+    u'\x01'     #  0x01 -> START OF HEADING
+    u'\x02'     #  0x02 -> START OF TEXT
+    u'\x03'     #  0x03 -> END OF TEXT
+    u'\x04'     #  0x04 -> END OF TRANSMISSION
+    u'\x05'     #  0x05 -> ENQUIRY
+    u'\x06'     #  0x06 -> ACKNOWLEDGE
+    u'\x07'     #  0x07 -> BELL
+    u'\x08'     #  0x08 -> BACKSPACE
+    u'\t'       #  0x09 -> HORIZONTAL TABULATION
+    u'\n'       #  0x0A -> LINE FEED
+    u'\x0b'     #  0x0B -> VERTICAL TABULATION
+    u'\x0c'     #  0x0C -> FORM FEED
+    u'\r'       #  0x0D -> CARRIAGE RETURN
+    u'\x0e'     #  0x0E -> SHIFT OUT
+    u'\x0f'     #  0x0F -> SHIFT IN
+    u'\x10'     #  0x10 -> DATA LINK ESCAPE
+    u'\x11'     #  0x11 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x12 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x13 -> DEVICE CONTROL THREE
+    u'\x14'     #  0x14 -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x15 -> NEGATIVE ACKNOWLEDGE
+    u'\x16'     #  0x16 -> SYNCHRONOUS IDLE
+    u'\x17'     #  0x17 -> END OF TRANSMISSION BLOCK
+    u'\x18'     #  0x18 -> CANCEL
+    u'\x19'     #  0x19 -> END OF MEDIUM
+    u'\x1a'     #  0x1A -> SUBSTITUTE
+    u'\x1b'     #  0x1B -> ESCAPE
+    u'\x1c'     #  0x1C -> FILE SEPARATOR
+    u'\x1d'     #  0x1D -> GROUP SEPARATOR
+    u'\x1e'     #  0x1E -> RECORD SEPARATOR
+    u'\x1f'     #  0x1F -> UNIT SEPARATOR
+    u' '        #  0x20 -> SPACE
+    u'!'        #  0x21 -> EXCLAMATION MARK
+    u'"'        #  0x22 -> QUOTATION MARK
+    u'#'        #  0x23 -> NUMBER SIGN
+    u'$'        #  0x24 -> DOLLAR SIGN
+    u'%'        #  0x25 -> PERCENT SIGN
+    u'&'        #  0x26 -> AMPERSAND
+    u"'"        #  0x27 -> APOSTROPHE
+    u'('        #  0x28 -> LEFT PARENTHESIS
+    u')'        #  0x29 -> RIGHT PARENTHESIS
+    u'*'        #  0x2A -> ASTERISK
+    u'+'        #  0x2B -> PLUS SIGN
+    u','        #  0x2C -> COMMA
+    u'-'        #  0x2D -> HYPHEN-MINUS
+    u'.'        #  0x2E -> FULL STOP
+    u'/'        #  0x2F -> SOLIDUS
+    u'0'        #  0x30 -> DIGIT ZERO
+    u'1'        #  0x31 -> DIGIT ONE
+    u'2'        #  0x32 -> DIGIT TWO
+    u'3'        #  0x33 -> DIGIT THREE
+    u'4'        #  0x34 -> DIGIT FOUR
+    u'5'        #  0x35 -> DIGIT FIVE
+    u'6'        #  0x36 -> DIGIT SIX
+    u'7'        #  0x37 -> DIGIT SEVEN
+    u'8'        #  0x38 -> DIGIT EIGHT
+    u'9'        #  0x39 -> DIGIT NINE
+    u':'        #  0x3A -> COLON
+    u';'        #  0x3B -> SEMICOLON
+    u'<'        #  0x3C -> LESS-THAN SIGN
+    u'='        #  0x3D -> EQUALS SIGN
+    u'>'        #  0x3E -> GREATER-THAN SIGN
+    u'?'        #  0x3F -> QUESTION MARK
+    u'@'        #  0x40 -> COMMERCIAL AT
+    u'A'        #  0x41 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x42 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x43 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x44 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x45 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x46 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x47 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x48 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x49 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x4A -> LATIN CAPITAL LETTER J
+    u'K'        #  0x4B -> LATIN CAPITAL LETTER K
+    u'L'        #  0x4C -> LATIN CAPITAL LETTER L
+    u'M'        #  0x4D -> LATIN CAPITAL LETTER M
+    u'N'        #  0x4E -> LATIN CAPITAL LETTER N
+    u'O'        #  0x4F -> LATIN CAPITAL LETTER O
+    u'P'        #  0x50 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x51 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x52 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x53 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x54 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x55 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x56 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x57 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x58 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x59 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x5A -> LATIN CAPITAL LETTER Z
+    u'['        #  0x5B -> LEFT SQUARE BRACKET
+    u'\\'       #  0x5C -> REVERSE SOLIDUS
+    u']'        #  0x5D -> RIGHT SQUARE BRACKET
+    u'^'        #  0x5E -> CIRCUMFLEX ACCENT
+    u'_'        #  0x5F -> LOW LINE
+    u'`'        #  0x60 -> GRAVE ACCENT
+    u'a'        #  0x61 -> LATIN SMALL LETTER A
+    u'b'        #  0x62 -> LATIN SMALL LETTER B
+    u'c'        #  0x63 -> LATIN SMALL LETTER C
+    u'd'        #  0x64 -> LATIN SMALL LETTER D
+    u'e'        #  0x65 -> LATIN SMALL LETTER E
+    u'f'        #  0x66 -> LATIN SMALL LETTER F
+    u'g'        #  0x67 -> LATIN SMALL LETTER G
+    u'h'        #  0x68 -> LATIN SMALL LETTER H
+    u'i'        #  0x69 -> LATIN SMALL LETTER I
+    u'j'        #  0x6A -> LATIN SMALL LETTER J
+    u'k'        #  0x6B -> LATIN SMALL LETTER K
+    u'l'        #  0x6C -> LATIN SMALL LETTER L
+    u'm'        #  0x6D -> LATIN SMALL LETTER M
+    u'n'        #  0x6E -> LATIN SMALL LETTER N
+    u'o'        #  0x6F -> LATIN SMALL LETTER O
+    u'p'        #  0x70 -> LATIN SMALL LETTER P
+    u'q'        #  0x71 -> LATIN SMALL LETTER Q
+    u'r'        #  0x72 -> LATIN SMALL LETTER R
+    u's'        #  0x73 -> LATIN SMALL LETTER S
+    u't'        #  0x74 -> LATIN SMALL LETTER T
+    u'u'        #  0x75 -> LATIN SMALL LETTER U
+    u'v'        #  0x76 -> LATIN SMALL LETTER V
+    u'w'        #  0x77 -> LATIN SMALL LETTER W
+    u'x'        #  0x78 -> LATIN SMALL LETTER X
+    u'y'        #  0x79 -> LATIN SMALL LETTER Y
+    u'z'        #  0x7A -> LATIN SMALL LETTER Z
+    u'{'        #  0x7B -> LEFT CURLY BRACKET
+    u'|'        #  0x7C -> VERTICAL LINE
+    u'}'        #  0x7D -> RIGHT CURLY BRACKET
+    u'~'        #  0x7E -> TILDE
+    u'\x7f'     #  0x7F -> DELETE
+    u'\x80'     #  0x80 -> <control>
+    u'\x81'     #  0x81 -> <control>
+    u'\x82'     #  0x82 -> <control>
+    u'\x83'     #  0x83 -> <control>
+    u'\x84'     #  0x84 -> <control>
+    u'\x85'     #  0x85 -> <control>
+    u'\x86'     #  0x86 -> <control>
+    u'\x87'     #  0x87 -> <control>
+    u'\x88'     #  0x88 -> <control>
+    u'\x89'     #  0x89 -> <control>
+    u'\x8a'     #  0x8A -> <control>
+    u'\x8b'     #  0x8B -> <control>
+    u'\x8c'     #  0x8C -> <control>
+    u'\x8d'     #  0x8D -> <control>
+    u'\x8e'     #  0x8E -> <control>
+    u'\x8f'     #  0x8F -> <control>
+    u'\x90'     #  0x90 -> <control>
+    u'\x91'     #  0x91 -> <control>
+    u'\x92'     #  0x92 -> <control>
+    u'\x93'     #  0x93 -> <control>
+    u'\x94'     #  0x94 -> <control>
+    u'\x95'     #  0x95 -> <control>
+    u'\x96'     #  0x96 -> <control>
+    u'\x97'     #  0x97 -> <control>
+    u'\x98'     #  0x98 -> <control>
+    u'\x99'     #  0x99 -> <control>
+    u'\x9a'     #  0x9A -> <control>
+    u'\x9b'     #  0x9B -> <control>
+    u'\x9c'     #  0x9C -> <control>
+    u'\x9d'     #  0x9D -> <control>
+    u'\x9e'     #  0x9E -> <control>
+    u'\x9f'     #  0x9F -> <control>
+    u'\xa0'     #  0xA0 -> NO-BREAK SPACE
+    u'\u0104'   #  0xA1 -> LATIN CAPITAL LETTER A WITH OGONEK
+    u'\u0105'   #  0xA2 -> LATIN SMALL LETTER A WITH OGONEK
+    u'\u0141'   #  0xA3 -> LATIN CAPITAL LETTER L WITH STROKE
+    u'\u20ac'   #  0xA4 -> EURO SIGN
+    u'\u201e'   #  0xA5 -> DOUBLE LOW-9 QUOTATION MARK
+    u'\u0160'   #  0xA6 -> LATIN CAPITAL LETTER S WITH CARON
+    u'\xa7'     #  0xA7 -> SECTION SIGN
+    u'\u0161'   #  0xA8 -> LATIN SMALL LETTER S WITH CARON
+    u'\xa9'     #  0xA9 -> COPYRIGHT SIGN
+    u'\u0218'   #  0xAA -> LATIN CAPITAL LETTER S WITH COMMA BELOW
+    u'\xab'     #  0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\u0179'   #  0xAC -> LATIN CAPITAL LETTER Z WITH ACUTE
+    u'\xad'     #  0xAD -> SOFT HYPHEN
+    u'\u017a'   #  0xAE -> LATIN SMALL LETTER Z WITH ACUTE
+    u'\u017b'   #  0xAF -> LATIN CAPITAL LETTER Z WITH DOT ABOVE
+    u'\xb0'     #  0xB0 -> DEGREE SIGN
+    u'\xb1'     #  0xB1 -> PLUS-MINUS SIGN
+    u'\u010c'   #  0xB2 -> LATIN CAPITAL LETTER C WITH CARON
+    u'\u0142'   #  0xB3 -> LATIN SMALL LETTER L WITH STROKE
+    u'\u017d'   #  0xB4 -> LATIN CAPITAL LETTER Z WITH CARON
+    u'\u201d'   #  0xB5 -> RIGHT DOUBLE QUOTATION MARK
+    u'\xb6'     #  0xB6 -> PILCROW SIGN
+    u'\xb7'     #  0xB7 -> MIDDLE DOT
+    u'\u017e'   #  0xB8 -> LATIN SMALL LETTER Z WITH CARON
+    u'\u010d'   #  0xB9 -> LATIN SMALL LETTER C WITH CARON
+    u'\u0219'   #  0xBA -> LATIN SMALL LETTER S WITH COMMA BELOW
+    u'\xbb'     #  0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\u0152'   #  0xBC -> LATIN CAPITAL LIGATURE OE
+    u'\u0153'   #  0xBD -> LATIN SMALL LIGATURE OE
+    u'\u0178'   #  0xBE -> LATIN CAPITAL LETTER Y WITH DIAERESIS
+    u'\u017c'   #  0xBF -> LATIN SMALL LETTER Z WITH DOT ABOVE
+    u'\xc0'     #  0xC0 -> LATIN CAPITAL LETTER A WITH GRAVE
+    u'\xc1'     #  0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE
+    u'\xc2'     #  0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+    u'\u0102'   #  0xC3 -> LATIN CAPITAL LETTER A WITH BREVE
+    u'\xc4'     #  0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS
+    u'\u0106'   #  0xC5 -> LATIN CAPITAL LETTER C WITH ACUTE
+    u'\xc6'     #  0xC6 -> LATIN CAPITAL LETTER AE
+    u'\xc7'     #  0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA
+    u'\xc8'     #  0xC8 -> LATIN CAPITAL LETTER E WITH GRAVE
+    u'\xc9'     #  0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE
+    u'\xca'     #  0xCA -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+    u'\xcb'     #  0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS
+    u'\xcc'     #  0xCC -> LATIN CAPITAL LETTER I WITH GRAVE
+    u'\xcd'     #  0xCD -> LATIN CAPITAL LETTER I WITH ACUTE
+    u'\xce'     #  0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+    u'\xcf'     #  0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS
+    u'\u0110'   #  0xD0 -> LATIN CAPITAL LETTER D WITH STROKE
+    u'\u0143'   #  0xD1 -> LATIN CAPITAL LETTER N WITH ACUTE
+    u'\xd2'     #  0xD2 -> LATIN CAPITAL LETTER O WITH GRAVE
+    u'\xd3'     #  0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE
+    u'\xd4'     #  0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+    u'\u0150'   #  0xD5 -> LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
+    u'\xd6'     #  0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS
+    u'\u015a'   #  0xD7 -> LATIN CAPITAL LETTER S WITH ACUTE
+    u'\u0170'   #  0xD8 -> LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
+    u'\xd9'     #  0xD9 -> LATIN CAPITAL LETTER U WITH GRAVE
+    u'\xda'     #  0xDA -> LATIN CAPITAL LETTER U WITH ACUTE
+    u'\xdb'     #  0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+    u'\xdc'     #  0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS
+    u'\u0118'   #  0xDD -> LATIN CAPITAL LETTER E WITH OGONEK
+    u'\u021a'   #  0xDE -> LATIN CAPITAL LETTER T WITH COMMA BELOW
+    u'\xdf'     #  0xDF -> LATIN SMALL LETTER SHARP S
+    u'\xe0'     #  0xE0 -> LATIN SMALL LETTER A WITH GRAVE
+    u'\xe1'     #  0xE1 -> LATIN SMALL LETTER A WITH ACUTE
+    u'\xe2'     #  0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX
+    u'\u0103'   #  0xE3 -> LATIN SMALL LETTER A WITH BREVE
+    u'\xe4'     #  0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS
+    u'\u0107'   #  0xE5 -> LATIN SMALL LETTER C WITH ACUTE
+    u'\xe6'     #  0xE6 -> LATIN SMALL LETTER AE
+    u'\xe7'     #  0xE7 -> LATIN SMALL LETTER C WITH CEDILLA
+    u'\xe8'     #  0xE8 -> LATIN SMALL LETTER E WITH GRAVE
+    u'\xe9'     #  0xE9 -> LATIN SMALL LETTER E WITH ACUTE
+    u'\xea'     #  0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX
+    u'\xeb'     #  0xEB -> LATIN SMALL LETTER E WITH DIAERESIS
+    u'\xec'     #  0xEC -> LATIN SMALL LETTER I WITH GRAVE
+    u'\xed'     #  0xED -> LATIN SMALL LETTER I WITH ACUTE
+    u'\xee'     #  0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX
+    u'\xef'     #  0xEF -> LATIN SMALL LETTER I WITH DIAERESIS
+    u'\u0111'   #  0xF0 -> LATIN SMALL LETTER D WITH STROKE
+    u'\u0144'   #  0xF1 -> LATIN SMALL LETTER N WITH ACUTE
+    u'\xf2'     #  0xF2 -> LATIN SMALL LETTER O WITH GRAVE
+    u'\xf3'     #  0xF3 -> LATIN SMALL LETTER O WITH ACUTE
+    u'\xf4'     #  0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX
+    u'\u0151'   #  0xF5 -> LATIN SMALL LETTER O WITH DOUBLE ACUTE
+    u'\xf6'     #  0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS
+    u'\u015b'   #  0xF7 -> LATIN SMALL LETTER S WITH ACUTE
+    u'\u0171'   #  0xF8 -> LATIN SMALL LETTER U WITH DOUBLE ACUTE
+    u'\xf9'     #  0xF9 -> LATIN SMALL LETTER U WITH GRAVE
+    u'\xfa'     #  0xFA -> LATIN SMALL LETTER U WITH ACUTE
+    u'\xfb'     #  0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX
+    u'\xfc'     #  0xFC -> LATIN SMALL LETTER U WITH DIAERESIS
+    u'\u0119'   #  0xFD -> LATIN SMALL LETTER E WITH OGONEK
+    u'\u021b'   #  0xFE -> LATIN SMALL LETTER T WITH COMMA BELOW
+    u'\xff'     #  0xFF -> LATIN SMALL LETTER Y WITH DIAERESIS
+)
+
+### Encoding table
+encoding_table=codecs.charmap_build(decoding_table)

Added: vendor/Python/current/Lib/encodings/iso8859_2.py
===================================================================
--- vendor/Python/current/Lib/encodings/iso8859_2.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/iso8859_2.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,307 @@
+""" Python Character Mapping Codec iso8859_2 generated from 'MAPPINGS/ISO8859/8859-2.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_table)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_table)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='iso8859-2',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x00 -> NULL
+    u'\x01'     #  0x01 -> START OF HEADING
+    u'\x02'     #  0x02 -> START OF TEXT
+    u'\x03'     #  0x03 -> END OF TEXT
+    u'\x04'     #  0x04 -> END OF TRANSMISSION
+    u'\x05'     #  0x05 -> ENQUIRY
+    u'\x06'     #  0x06 -> ACKNOWLEDGE
+    u'\x07'     #  0x07 -> BELL
+    u'\x08'     #  0x08 -> BACKSPACE
+    u'\t'       #  0x09 -> HORIZONTAL TABULATION
+    u'\n'       #  0x0A -> LINE FEED
+    u'\x0b'     #  0x0B -> VERTICAL TABULATION
+    u'\x0c'     #  0x0C -> FORM FEED
+    u'\r'       #  0x0D -> CARRIAGE RETURN
+    u'\x0e'     #  0x0E -> SHIFT OUT
+    u'\x0f'     #  0x0F -> SHIFT IN
+    u'\x10'     #  0x10 -> DATA LINK ESCAPE
+    u'\x11'     #  0x11 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x12 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x13 -> DEVICE CONTROL THREE
+    u'\x14'     #  0x14 -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x15 -> NEGATIVE ACKNOWLEDGE
+    u'\x16'     #  0x16 -> SYNCHRONOUS IDLE
+    u'\x17'     #  0x17 -> END OF TRANSMISSION BLOCK
+    u'\x18'     #  0x18 -> CANCEL
+    u'\x19'     #  0x19 -> END OF MEDIUM
+    u'\x1a'     #  0x1A -> SUBSTITUTE
+    u'\x1b'     #  0x1B -> ESCAPE
+    u'\x1c'     #  0x1C -> FILE SEPARATOR
+    u'\x1d'     #  0x1D -> GROUP SEPARATOR
+    u'\x1e'     #  0x1E -> RECORD SEPARATOR
+    u'\x1f'     #  0x1F -> UNIT SEPARATOR
+    u' '        #  0x20 -> SPACE
+    u'!'        #  0x21 -> EXCLAMATION MARK
+    u'"'        #  0x22 -> QUOTATION MARK
+    u'#'        #  0x23 -> NUMBER SIGN
+    u'$'        #  0x24 -> DOLLAR SIGN
+    u'%'        #  0x25 -> PERCENT SIGN
+    u'&'        #  0x26 -> AMPERSAND
+    u"'"        #  0x27 -> APOSTROPHE
+    u'('        #  0x28 -> LEFT PARENTHESIS
+    u')'        #  0x29 -> RIGHT PARENTHESIS
+    u'*'        #  0x2A -> ASTERISK
+    u'+'        #  0x2B -> PLUS SIGN
+    u','        #  0x2C -> COMMA
+    u'-'        #  0x2D -> HYPHEN-MINUS
+    u'.'        #  0x2E -> FULL STOP
+    u'/'        #  0x2F -> SOLIDUS
+    u'0'        #  0x30 -> DIGIT ZERO
+    u'1'        #  0x31 -> DIGIT ONE
+    u'2'        #  0x32 -> DIGIT TWO
+    u'3'        #  0x33 -> DIGIT THREE
+    u'4'        #  0x34 -> DIGIT FOUR
+    u'5'        #  0x35 -> DIGIT FIVE
+    u'6'        #  0x36 -> DIGIT SIX
+    u'7'        #  0x37 -> DIGIT SEVEN
+    u'8'        #  0x38 -> DIGIT EIGHT
+    u'9'        #  0x39 -> DIGIT NINE
+    u':'        #  0x3A -> COLON
+    u';'        #  0x3B -> SEMICOLON
+    u'<'        #  0x3C -> LESS-THAN SIGN
+    u'='        #  0x3D -> EQUALS SIGN
+    u'>'        #  0x3E -> GREATER-THAN SIGN
+    u'?'        #  0x3F -> QUESTION MARK
+    u'@'        #  0x40 -> COMMERCIAL AT
+    u'A'        #  0x41 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x42 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x43 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x44 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x45 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x46 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x47 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x48 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x49 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x4A -> LATIN CAPITAL LETTER J
+    u'K'        #  0x4B -> LATIN CAPITAL LETTER K
+    u'L'        #  0x4C -> LATIN CAPITAL LETTER L
+    u'M'        #  0x4D -> LATIN CAPITAL LETTER M
+    u'N'        #  0x4E -> LATIN CAPITAL LETTER N
+    u'O'        #  0x4F -> LATIN CAPITAL LETTER O
+    u'P'        #  0x50 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x51 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x52 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x53 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x54 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x55 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x56 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x57 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x58 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x59 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x5A -> LATIN CAPITAL LETTER Z
+    u'['        #  0x5B -> LEFT SQUARE BRACKET
+    u'\\'       #  0x5C -> REVERSE SOLIDUS
+    u']'        #  0x5D -> RIGHT SQUARE BRACKET
+    u'^'        #  0x5E -> CIRCUMFLEX ACCENT
+    u'_'        #  0x5F -> LOW LINE
+    u'`'        #  0x60 -> GRAVE ACCENT
+    u'a'        #  0x61 -> LATIN SMALL LETTER A
+    u'b'        #  0x62 -> LATIN SMALL LETTER B
+    u'c'        #  0x63 -> LATIN SMALL LETTER C
+    u'd'        #  0x64 -> LATIN SMALL LETTER D
+    u'e'        #  0x65 -> LATIN SMALL LETTER E
+    u'f'        #  0x66 -> LATIN SMALL LETTER F
+    u'g'        #  0x67 -> LATIN SMALL LETTER G
+    u'h'        #  0x68 -> LATIN SMALL LETTER H
+    u'i'        #  0x69 -> LATIN SMALL LETTER I
+    u'j'        #  0x6A -> LATIN SMALL LETTER J
+    u'k'        #  0x6B -> LATIN SMALL LETTER K
+    u'l'        #  0x6C -> LATIN SMALL LETTER L
+    u'm'        #  0x6D -> LATIN SMALL LETTER M
+    u'n'        #  0x6E -> LATIN SMALL LETTER N
+    u'o'        #  0x6F -> LATIN SMALL LETTER O
+    u'p'        #  0x70 -> LATIN SMALL LETTER P
+    u'q'        #  0x71 -> LATIN SMALL LETTER Q
+    u'r'        #  0x72 -> LATIN SMALL LETTER R
+    u's'        #  0x73 -> LATIN SMALL LETTER S
+    u't'        #  0x74 -> LATIN SMALL LETTER T
+    u'u'        #  0x75 -> LATIN SMALL LETTER U
+    u'v'        #  0x76 -> LATIN SMALL LETTER V
+    u'w'        #  0x77 -> LATIN SMALL LETTER W
+    u'x'        #  0x78 -> LATIN SMALL LETTER X
+    u'y'        #  0x79 -> LATIN SMALL LETTER Y
+    u'z'        #  0x7A -> LATIN SMALL LETTER Z
+    u'{'        #  0x7B -> LEFT CURLY BRACKET
+    u'|'        #  0x7C -> VERTICAL LINE
+    u'}'        #  0x7D -> RIGHT CURLY BRACKET
+    u'~'        #  0x7E -> TILDE
+    u'\x7f'     #  0x7F -> DELETE
+    u'\x80'     #  0x80 -> <control>
+    u'\x81'     #  0x81 -> <control>
+    u'\x82'     #  0x82 -> <control>
+    u'\x83'     #  0x83 -> <control>
+    u'\x84'     #  0x84 -> <control>
+    u'\x85'     #  0x85 -> <control>
+    u'\x86'     #  0x86 -> <control>
+    u'\x87'     #  0x87 -> <control>
+    u'\x88'     #  0x88 -> <control>
+    u'\x89'     #  0x89 -> <control>
+    u'\x8a'     #  0x8A -> <control>
+    u'\x8b'     #  0x8B -> <control>
+    u'\x8c'     #  0x8C -> <control>
+    u'\x8d'     #  0x8D -> <control>
+    u'\x8e'     #  0x8E -> <control>
+    u'\x8f'     #  0x8F -> <control>
+    u'\x90'     #  0x90 -> <control>
+    u'\x91'     #  0x91 -> <control>
+    u'\x92'     #  0x92 -> <control>
+    u'\x93'     #  0x93 -> <control>
+    u'\x94'     #  0x94 -> <control>
+    u'\x95'     #  0x95 -> <control>
+    u'\x96'     #  0x96 -> <control>
+    u'\x97'     #  0x97 -> <control>
+    u'\x98'     #  0x98 -> <control>
+    u'\x99'     #  0x99 -> <control>
+    u'\x9a'     #  0x9A -> <control>
+    u'\x9b'     #  0x9B -> <control>
+    u'\x9c'     #  0x9C -> <control>
+    u'\x9d'     #  0x9D -> <control>
+    u'\x9e'     #  0x9E -> <control>
+    u'\x9f'     #  0x9F -> <control>
+    u'\xa0'     #  0xA0 -> NO-BREAK SPACE
+    u'\u0104'   #  0xA1 -> LATIN CAPITAL LETTER A WITH OGONEK
+    u'\u02d8'   #  0xA2 -> BREVE
+    u'\u0141'   #  0xA3 -> LATIN CAPITAL LETTER L WITH STROKE
+    u'\xa4'     #  0xA4 -> CURRENCY SIGN
+    u'\u013d'   #  0xA5 -> LATIN CAPITAL LETTER L WITH CARON
+    u'\u015a'   #  0xA6 -> LATIN CAPITAL LETTER S WITH ACUTE
+    u'\xa7'     #  0xA7 -> SECTION SIGN
+    u'\xa8'     #  0xA8 -> DIAERESIS
+    u'\u0160'   #  0xA9 -> LATIN CAPITAL LETTER S WITH CARON
+    u'\u015e'   #  0xAA -> LATIN CAPITAL LETTER S WITH CEDILLA
+    u'\u0164'   #  0xAB -> LATIN CAPITAL LETTER T WITH CARON
+    u'\u0179'   #  0xAC -> LATIN CAPITAL LETTER Z WITH ACUTE
+    u'\xad'     #  0xAD -> SOFT HYPHEN
+    u'\u017d'   #  0xAE -> LATIN CAPITAL LETTER Z WITH CARON
+    u'\u017b'   #  0xAF -> LATIN CAPITAL LETTER Z WITH DOT ABOVE
+    u'\xb0'     #  0xB0 -> DEGREE SIGN
+    u'\u0105'   #  0xB1 -> LATIN SMALL LETTER A WITH OGONEK
+    u'\u02db'   #  0xB2 -> OGONEK
+    u'\u0142'   #  0xB3 -> LATIN SMALL LETTER L WITH STROKE
+    u'\xb4'     #  0xB4 -> ACUTE ACCENT
+    u'\u013e'   #  0xB5 -> LATIN SMALL LETTER L WITH CARON
+    u'\u015b'   #  0xB6 -> LATIN SMALL LETTER S WITH ACUTE
+    u'\u02c7'   #  0xB7 -> CARON
+    u'\xb8'     #  0xB8 -> CEDILLA
+    u'\u0161'   #  0xB9 -> LATIN SMALL LETTER S WITH CARON
+    u'\u015f'   #  0xBA -> LATIN SMALL LETTER S WITH CEDILLA
+    u'\u0165'   #  0xBB -> LATIN SMALL LETTER T WITH CARON
+    u'\u017a'   #  0xBC -> LATIN SMALL LETTER Z WITH ACUTE
+    u'\u02dd'   #  0xBD -> DOUBLE ACUTE ACCENT
+    u'\u017e'   #  0xBE -> LATIN SMALL LETTER Z WITH CARON
+    u'\u017c'   #  0xBF -> LATIN SMALL LETTER Z WITH DOT ABOVE
+    u'\u0154'   #  0xC0 -> LATIN CAPITAL LETTER R WITH ACUTE
+    u'\xc1'     #  0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE
+    u'\xc2'     #  0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+    u'\u0102'   #  0xC3 -> LATIN CAPITAL LETTER A WITH BREVE
+    u'\xc4'     #  0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS
+    u'\u0139'   #  0xC5 -> LATIN CAPITAL LETTER L WITH ACUTE
+    u'\u0106'   #  0xC6 -> LATIN CAPITAL LETTER C WITH ACUTE
+    u'\xc7'     #  0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA
+    u'\u010c'   #  0xC8 -> LATIN CAPITAL LETTER C WITH CARON
+    u'\xc9'     #  0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE
+    u'\u0118'   #  0xCA -> LATIN CAPITAL LETTER E WITH OGONEK
+    u'\xcb'     #  0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS
+    u'\u011a'   #  0xCC -> LATIN CAPITAL LETTER E WITH CARON
+    u'\xcd'     #  0xCD -> LATIN CAPITAL LETTER I WITH ACUTE
+    u'\xce'     #  0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+    u'\u010e'   #  0xCF -> LATIN CAPITAL LETTER D WITH CARON
+    u'\u0110'   #  0xD0 -> LATIN CAPITAL LETTER D WITH STROKE
+    u'\u0143'   #  0xD1 -> LATIN CAPITAL LETTER N WITH ACUTE
+    u'\u0147'   #  0xD2 -> LATIN CAPITAL LETTER N WITH CARON
+    u'\xd3'     #  0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE
+    u'\xd4'     #  0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+    u'\u0150'   #  0xD5 -> LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
+    u'\xd6'     #  0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS
+    u'\xd7'     #  0xD7 -> MULTIPLICATION SIGN
+    u'\u0158'   #  0xD8 -> LATIN CAPITAL LETTER R WITH CARON
+    u'\u016e'   #  0xD9 -> LATIN CAPITAL LETTER U WITH RING ABOVE
+    u'\xda'     #  0xDA -> LATIN CAPITAL LETTER U WITH ACUTE
+    u'\u0170'   #  0xDB -> LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
+    u'\xdc'     #  0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS
+    u'\xdd'     #  0xDD -> LATIN CAPITAL LETTER Y WITH ACUTE
+    u'\u0162'   #  0xDE -> LATIN CAPITAL LETTER T WITH CEDILLA
+    u'\xdf'     #  0xDF -> LATIN SMALL LETTER SHARP S
+    u'\u0155'   #  0xE0 -> LATIN SMALL LETTER R WITH ACUTE
+    u'\xe1'     #  0xE1 -> LATIN SMALL LETTER A WITH ACUTE
+    u'\xe2'     #  0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX
+    u'\u0103'   #  0xE3 -> LATIN SMALL LETTER A WITH BREVE
+    u'\xe4'     #  0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS
+    u'\u013a'   #  0xE5 -> LATIN SMALL LETTER L WITH ACUTE
+    u'\u0107'   #  0xE6 -> LATIN SMALL LETTER C WITH ACUTE
+    u'\xe7'     #  0xE7 -> LATIN SMALL LETTER C WITH CEDILLA
+    u'\u010d'   #  0xE8 -> LATIN SMALL LETTER C WITH CARON
+    u'\xe9'     #  0xE9 -> LATIN SMALL LETTER E WITH ACUTE
+    u'\u0119'   #  0xEA -> LATIN SMALL LETTER E WITH OGONEK
+    u'\xeb'     #  0xEB -> LATIN SMALL LETTER E WITH DIAERESIS
+    u'\u011b'   #  0xEC -> LATIN SMALL LETTER E WITH CARON
+    u'\xed'     #  0xED -> LATIN SMALL LETTER I WITH ACUTE
+    u'\xee'     #  0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX
+    u'\u010f'   #  0xEF -> LATIN SMALL LETTER D WITH CARON
+    u'\u0111'   #  0xF0 -> LATIN SMALL LETTER D WITH STROKE
+    u'\u0144'   #  0xF1 -> LATIN SMALL LETTER N WITH ACUTE
+    u'\u0148'   #  0xF2 -> LATIN SMALL LETTER N WITH CARON
+    u'\xf3'     #  0xF3 -> LATIN SMALL LETTER O WITH ACUTE
+    u'\xf4'     #  0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX
+    u'\u0151'   #  0xF5 -> LATIN SMALL LETTER O WITH DOUBLE ACUTE
+    u'\xf6'     #  0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS
+    u'\xf7'     #  0xF7 -> DIVISION SIGN
+    u'\u0159'   #  0xF8 -> LATIN SMALL LETTER R WITH CARON
+    u'\u016f'   #  0xF9 -> LATIN SMALL LETTER U WITH RING ABOVE
+    u'\xfa'     #  0xFA -> LATIN SMALL LETTER U WITH ACUTE
+    u'\u0171'   #  0xFB -> LATIN SMALL LETTER U WITH DOUBLE ACUTE
+    u'\xfc'     #  0xFC -> LATIN SMALL LETTER U WITH DIAERESIS
+    u'\xfd'     #  0xFD -> LATIN SMALL LETTER Y WITH ACUTE
+    u'\u0163'   #  0xFE -> LATIN SMALL LETTER T WITH CEDILLA
+    u'\u02d9'   #  0xFF -> DOT ABOVE
+)
+
+### Encoding table
+encoding_table=codecs.charmap_build(decoding_table)

Added: vendor/Python/current/Lib/encodings/iso8859_3.py
===================================================================
--- vendor/Python/current/Lib/encodings/iso8859_3.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/iso8859_3.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,307 @@
+""" Python Character Mapping Codec iso8859_3 generated from 'MAPPINGS/ISO8859/8859-3.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_table)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_table)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='iso8859-3',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x00 -> NULL
+    u'\x01'     #  0x01 -> START OF HEADING
+    u'\x02'     #  0x02 -> START OF TEXT
+    u'\x03'     #  0x03 -> END OF TEXT
+    u'\x04'     #  0x04 -> END OF TRANSMISSION
+    u'\x05'     #  0x05 -> ENQUIRY
+    u'\x06'     #  0x06 -> ACKNOWLEDGE
+    u'\x07'     #  0x07 -> BELL
+    u'\x08'     #  0x08 -> BACKSPACE
+    u'\t'       #  0x09 -> HORIZONTAL TABULATION
+    u'\n'       #  0x0A -> LINE FEED
+    u'\x0b'     #  0x0B -> VERTICAL TABULATION
+    u'\x0c'     #  0x0C -> FORM FEED
+    u'\r'       #  0x0D -> CARRIAGE RETURN
+    u'\x0e'     #  0x0E -> SHIFT OUT
+    u'\x0f'     #  0x0F -> SHIFT IN
+    u'\x10'     #  0x10 -> DATA LINK ESCAPE
+    u'\x11'     #  0x11 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x12 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x13 -> DEVICE CONTROL THREE
+    u'\x14'     #  0x14 -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x15 -> NEGATIVE ACKNOWLEDGE
+    u'\x16'     #  0x16 -> SYNCHRONOUS IDLE
+    u'\x17'     #  0x17 -> END OF TRANSMISSION BLOCK
+    u'\x18'     #  0x18 -> CANCEL
+    u'\x19'     #  0x19 -> END OF MEDIUM
+    u'\x1a'     #  0x1A -> SUBSTITUTE
+    u'\x1b'     #  0x1B -> ESCAPE
+    u'\x1c'     #  0x1C -> FILE SEPARATOR
+    u'\x1d'     #  0x1D -> GROUP SEPARATOR
+    u'\x1e'     #  0x1E -> RECORD SEPARATOR
+    u'\x1f'     #  0x1F -> UNIT SEPARATOR
+    u' '        #  0x20 -> SPACE
+    u'!'        #  0x21 -> EXCLAMATION MARK
+    u'"'        #  0x22 -> QUOTATION MARK
+    u'#'        #  0x23 -> NUMBER SIGN
+    u'$'        #  0x24 -> DOLLAR SIGN
+    u'%'        #  0x25 -> PERCENT SIGN
+    u'&'        #  0x26 -> AMPERSAND
+    u"'"        #  0x27 -> APOSTROPHE
+    u'('        #  0x28 -> LEFT PARENTHESIS
+    u')'        #  0x29 -> RIGHT PARENTHESIS
+    u'*'        #  0x2A -> ASTERISK
+    u'+'        #  0x2B -> PLUS SIGN
+    u','        #  0x2C -> COMMA
+    u'-'        #  0x2D -> HYPHEN-MINUS
+    u'.'        #  0x2E -> FULL STOP
+    u'/'        #  0x2F -> SOLIDUS
+    u'0'        #  0x30 -> DIGIT ZERO
+    u'1'        #  0x31 -> DIGIT ONE
+    u'2'        #  0x32 -> DIGIT TWO
+    u'3'        #  0x33 -> DIGIT THREE
+    u'4'        #  0x34 -> DIGIT FOUR
+    u'5'        #  0x35 -> DIGIT FIVE
+    u'6'        #  0x36 -> DIGIT SIX
+    u'7'        #  0x37 -> DIGIT SEVEN
+    u'8'        #  0x38 -> DIGIT EIGHT
+    u'9'        #  0x39 -> DIGIT NINE
+    u':'        #  0x3A -> COLON
+    u';'        #  0x3B -> SEMICOLON
+    u'<'        #  0x3C -> LESS-THAN SIGN
+    u'='        #  0x3D -> EQUALS SIGN
+    u'>'        #  0x3E -> GREATER-THAN SIGN
+    u'?'        #  0x3F -> QUESTION MARK
+    u'@'        #  0x40 -> COMMERCIAL AT
+    u'A'        #  0x41 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x42 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x43 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x44 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x45 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x46 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x47 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x48 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x49 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x4A -> LATIN CAPITAL LETTER J
+    u'K'        #  0x4B -> LATIN CAPITAL LETTER K
+    u'L'        #  0x4C -> LATIN CAPITAL LETTER L
+    u'M'        #  0x4D -> LATIN CAPITAL LETTER M
+    u'N'        #  0x4E -> LATIN CAPITAL LETTER N
+    u'O'        #  0x4F -> LATIN CAPITAL LETTER O
+    u'P'        #  0x50 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x51 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x52 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x53 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x54 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x55 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x56 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x57 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x58 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x59 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x5A -> LATIN CAPITAL LETTER Z
+    u'['        #  0x5B -> LEFT SQUARE BRACKET
+    u'\\'       #  0x5C -> REVERSE SOLIDUS
+    u']'        #  0x5D -> RIGHT SQUARE BRACKET
+    u'^'        #  0x5E -> CIRCUMFLEX ACCENT
+    u'_'        #  0x5F -> LOW LINE
+    u'`'        #  0x60 -> GRAVE ACCENT
+    u'a'        #  0x61 -> LATIN SMALL LETTER A
+    u'b'        #  0x62 -> LATIN SMALL LETTER B
+    u'c'        #  0x63 -> LATIN SMALL LETTER C
+    u'd'        #  0x64 -> LATIN SMALL LETTER D
+    u'e'        #  0x65 -> LATIN SMALL LETTER E
+    u'f'        #  0x66 -> LATIN SMALL LETTER F
+    u'g'        #  0x67 -> LATIN SMALL LETTER G
+    u'h'        #  0x68 -> LATIN SMALL LETTER H
+    u'i'        #  0x69 -> LATIN SMALL LETTER I
+    u'j'        #  0x6A -> LATIN SMALL LETTER J
+    u'k'        #  0x6B -> LATIN SMALL LETTER K
+    u'l'        #  0x6C -> LATIN SMALL LETTER L
+    u'm'        #  0x6D -> LATIN SMALL LETTER M
+    u'n'        #  0x6E -> LATIN SMALL LETTER N
+    u'o'        #  0x6F -> LATIN SMALL LETTER O
+    u'p'        #  0x70 -> LATIN SMALL LETTER P
+    u'q'        #  0x71 -> LATIN SMALL LETTER Q
+    u'r'        #  0x72 -> LATIN SMALL LETTER R
+    u's'        #  0x73 -> LATIN SMALL LETTER S
+    u't'        #  0x74 -> LATIN SMALL LETTER T
+    u'u'        #  0x75 -> LATIN SMALL LETTER U
+    u'v'        #  0x76 -> LATIN SMALL LETTER V
+    u'w'        #  0x77 -> LATIN SMALL LETTER W
+    u'x'        #  0x78 -> LATIN SMALL LETTER X
+    u'y'        #  0x79 -> LATIN SMALL LETTER Y
+    u'z'        #  0x7A -> LATIN SMALL LETTER Z
+    u'{'        #  0x7B -> LEFT CURLY BRACKET
+    u'|'        #  0x7C -> VERTICAL LINE
+    u'}'        #  0x7D -> RIGHT CURLY BRACKET
+    u'~'        #  0x7E -> TILDE
+    u'\x7f'     #  0x7F -> DELETE
+    u'\x80'     #  0x80 -> <control>
+    u'\x81'     #  0x81 -> <control>
+    u'\x82'     #  0x82 -> <control>
+    u'\x83'     #  0x83 -> <control>
+    u'\x84'     #  0x84 -> <control>
+    u'\x85'     #  0x85 -> <control>
+    u'\x86'     #  0x86 -> <control>
+    u'\x87'     #  0x87 -> <control>
+    u'\x88'     #  0x88 -> <control>
+    u'\x89'     #  0x89 -> <control>
+    u'\x8a'     #  0x8A -> <control>
+    u'\x8b'     #  0x8B -> <control>
+    u'\x8c'     #  0x8C -> <control>
+    u'\x8d'     #  0x8D -> <control>
+    u'\x8e'     #  0x8E -> <control>
+    u'\x8f'     #  0x8F -> <control>
+    u'\x90'     #  0x90 -> <control>
+    u'\x91'     #  0x91 -> <control>
+    u'\x92'     #  0x92 -> <control>
+    u'\x93'     #  0x93 -> <control>
+    u'\x94'     #  0x94 -> <control>
+    u'\x95'     #  0x95 -> <control>
+    u'\x96'     #  0x96 -> <control>
+    u'\x97'     #  0x97 -> <control>
+    u'\x98'     #  0x98 -> <control>
+    u'\x99'     #  0x99 -> <control>
+    u'\x9a'     #  0x9A -> <control>
+    u'\x9b'     #  0x9B -> <control>
+    u'\x9c'     #  0x9C -> <control>
+    u'\x9d'     #  0x9D -> <control>
+    u'\x9e'     #  0x9E -> <control>
+    u'\x9f'     #  0x9F -> <control>
+    u'\xa0'     #  0xA0 -> NO-BREAK SPACE
+    u'\u0126'   #  0xA1 -> LATIN CAPITAL LETTER H WITH STROKE
+    u'\u02d8'   #  0xA2 -> BREVE
+    u'\xa3'     #  0xA3 -> POUND SIGN
+    u'\xa4'     #  0xA4 -> CURRENCY SIGN
+    u'\ufffe'
+    u'\u0124'   #  0xA6 -> LATIN CAPITAL LETTER H WITH CIRCUMFLEX
+    u'\xa7'     #  0xA7 -> SECTION SIGN
+    u'\xa8'     #  0xA8 -> DIAERESIS
+    u'\u0130'   #  0xA9 -> LATIN CAPITAL LETTER I WITH DOT ABOVE
+    u'\u015e'   #  0xAA -> LATIN CAPITAL LETTER S WITH CEDILLA
+    u'\u011e'   #  0xAB -> LATIN CAPITAL LETTER G WITH BREVE
+    u'\u0134'   #  0xAC -> LATIN CAPITAL LETTER J WITH CIRCUMFLEX
+    u'\xad'     #  0xAD -> SOFT HYPHEN
+    u'\ufffe'
+    u'\u017b'   #  0xAF -> LATIN CAPITAL LETTER Z WITH DOT ABOVE
+    u'\xb0'     #  0xB0 -> DEGREE SIGN
+    u'\u0127'   #  0xB1 -> LATIN SMALL LETTER H WITH STROKE
+    u'\xb2'     #  0xB2 -> SUPERSCRIPT TWO
+    u'\xb3'     #  0xB3 -> SUPERSCRIPT THREE
+    u'\xb4'     #  0xB4 -> ACUTE ACCENT
+    u'\xb5'     #  0xB5 -> MICRO SIGN
+    u'\u0125'   #  0xB6 -> LATIN SMALL LETTER H WITH CIRCUMFLEX
+    u'\xb7'     #  0xB7 -> MIDDLE DOT
+    u'\xb8'     #  0xB8 -> CEDILLA
+    u'\u0131'   #  0xB9 -> LATIN SMALL LETTER DOTLESS I
+    u'\u015f'   #  0xBA -> LATIN SMALL LETTER S WITH CEDILLA
+    u'\u011f'   #  0xBB -> LATIN SMALL LETTER G WITH BREVE
+    u'\u0135'   #  0xBC -> LATIN SMALL LETTER J WITH CIRCUMFLEX
+    u'\xbd'     #  0xBD -> VULGAR FRACTION ONE HALF
+    u'\ufffe'
+    u'\u017c'   #  0xBF -> LATIN SMALL LETTER Z WITH DOT ABOVE
+    u'\xc0'     #  0xC0 -> LATIN CAPITAL LETTER A WITH GRAVE
+    u'\xc1'     #  0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE
+    u'\xc2'     #  0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+    u'\ufffe'
+    u'\xc4'     #  0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS
+    u'\u010a'   #  0xC5 -> LATIN CAPITAL LETTER C WITH DOT ABOVE
+    u'\u0108'   #  0xC6 -> LATIN CAPITAL LETTER C WITH CIRCUMFLEX
+    u'\xc7'     #  0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA
+    u'\xc8'     #  0xC8 -> LATIN CAPITAL LETTER E WITH GRAVE
+    u'\xc9'     #  0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE
+    u'\xca'     #  0xCA -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+    u'\xcb'     #  0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS
+    u'\xcc'     #  0xCC -> LATIN CAPITAL LETTER I WITH GRAVE
+    u'\xcd'     #  0xCD -> LATIN CAPITAL LETTER I WITH ACUTE
+    u'\xce'     #  0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+    u'\xcf'     #  0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS
+    u'\ufffe'
+    u'\xd1'     #  0xD1 -> LATIN CAPITAL LETTER N WITH TILDE
+    u'\xd2'     #  0xD2 -> LATIN CAPITAL LETTER O WITH GRAVE
+    u'\xd3'     #  0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE
+    u'\xd4'     #  0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+    u'\u0120'   #  0xD5 -> LATIN CAPITAL LETTER G WITH DOT ABOVE
+    u'\xd6'     #  0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS
+    u'\xd7'     #  0xD7 -> MULTIPLICATION SIGN
+    u'\u011c'   #  0xD8 -> LATIN CAPITAL LETTER G WITH CIRCUMFLEX
+    u'\xd9'     #  0xD9 -> LATIN CAPITAL LETTER U WITH GRAVE
+    u'\xda'     #  0xDA -> LATIN CAPITAL LETTER U WITH ACUTE
+    u'\xdb'     #  0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+    u'\xdc'     #  0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS
+    u'\u016c'   #  0xDD -> LATIN CAPITAL LETTER U WITH BREVE
+    u'\u015c'   #  0xDE -> LATIN CAPITAL LETTER S WITH CIRCUMFLEX
+    u'\xdf'     #  0xDF -> LATIN SMALL LETTER SHARP S
+    u'\xe0'     #  0xE0 -> LATIN SMALL LETTER A WITH GRAVE
+    u'\xe1'     #  0xE1 -> LATIN SMALL LETTER A WITH ACUTE
+    u'\xe2'     #  0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX
+    u'\ufffe'
+    u'\xe4'     #  0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS
+    u'\u010b'   #  0xE5 -> LATIN SMALL LETTER C WITH DOT ABOVE
+    u'\u0109'   #  0xE6 -> LATIN SMALL LETTER C WITH CIRCUMFLEX
+    u'\xe7'     #  0xE7 -> LATIN SMALL LETTER C WITH CEDILLA
+    u'\xe8'     #  0xE8 -> LATIN SMALL LETTER E WITH GRAVE
+    u'\xe9'     #  0xE9 -> LATIN SMALL LETTER E WITH ACUTE
+    u'\xea'     #  0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX
+    u'\xeb'     #  0xEB -> LATIN SMALL LETTER E WITH DIAERESIS
+    u'\xec'     #  0xEC -> LATIN SMALL LETTER I WITH GRAVE
+    u'\xed'     #  0xED -> LATIN SMALL LETTER I WITH ACUTE
+    u'\xee'     #  0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX
+    u'\xef'     #  0xEF -> LATIN SMALL LETTER I WITH DIAERESIS
+    u'\ufffe'
+    u'\xf1'     #  0xF1 -> LATIN SMALL LETTER N WITH TILDE
+    u'\xf2'     #  0xF2 -> LATIN SMALL LETTER O WITH GRAVE
+    u'\xf3'     #  0xF3 -> LATIN SMALL LETTER O WITH ACUTE
+    u'\xf4'     #  0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX
+    u'\u0121'   #  0xF5 -> LATIN SMALL LETTER G WITH DOT ABOVE
+    u'\xf6'     #  0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS
+    u'\xf7'     #  0xF7 -> DIVISION SIGN
+    u'\u011d'   #  0xF8 -> LATIN SMALL LETTER G WITH CIRCUMFLEX
+    u'\xf9'     #  0xF9 -> LATIN SMALL LETTER U WITH GRAVE
+    u'\xfa'     #  0xFA -> LATIN SMALL LETTER U WITH ACUTE
+    u'\xfb'     #  0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX
+    u'\xfc'     #  0xFC -> LATIN SMALL LETTER U WITH DIAERESIS
+    u'\u016d'   #  0xFD -> LATIN SMALL LETTER U WITH BREVE
+    u'\u015d'   #  0xFE -> LATIN SMALL LETTER S WITH CIRCUMFLEX
+    u'\u02d9'   #  0xFF -> DOT ABOVE
+)
+
+### Encoding table
+encoding_table=codecs.charmap_build(decoding_table)

Added: vendor/Python/current/Lib/encodings/iso8859_4.py
===================================================================
--- vendor/Python/current/Lib/encodings/iso8859_4.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/iso8859_4.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,307 @@
+""" Python Character Mapping Codec iso8859_4 generated from 'MAPPINGS/ISO8859/8859-4.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_table)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_table)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='iso8859-4',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x00 -> NULL
+    u'\x01'     #  0x01 -> START OF HEADING
+    u'\x02'     #  0x02 -> START OF TEXT
+    u'\x03'     #  0x03 -> END OF TEXT
+    u'\x04'     #  0x04 -> END OF TRANSMISSION
+    u'\x05'     #  0x05 -> ENQUIRY
+    u'\x06'     #  0x06 -> ACKNOWLEDGE
+    u'\x07'     #  0x07 -> BELL
+    u'\x08'     #  0x08 -> BACKSPACE
+    u'\t'       #  0x09 -> HORIZONTAL TABULATION
+    u'\n'       #  0x0A -> LINE FEED
+    u'\x0b'     #  0x0B -> VERTICAL TABULATION
+    u'\x0c'     #  0x0C -> FORM FEED
+    u'\r'       #  0x0D -> CARRIAGE RETURN
+    u'\x0e'     #  0x0E -> SHIFT OUT
+    u'\x0f'     #  0x0F -> SHIFT IN
+    u'\x10'     #  0x10 -> DATA LINK ESCAPE
+    u'\x11'     #  0x11 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x12 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x13 -> DEVICE CONTROL THREE
+    u'\x14'     #  0x14 -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x15 -> NEGATIVE ACKNOWLEDGE
+    u'\x16'     #  0x16 -> SYNCHRONOUS IDLE
+    u'\x17'     #  0x17 -> END OF TRANSMISSION BLOCK
+    u'\x18'     #  0x18 -> CANCEL
+    u'\x19'     #  0x19 -> END OF MEDIUM
+    u'\x1a'     #  0x1A -> SUBSTITUTE
+    u'\x1b'     #  0x1B -> ESCAPE
+    u'\x1c'     #  0x1C -> FILE SEPARATOR
+    u'\x1d'     #  0x1D -> GROUP SEPARATOR
+    u'\x1e'     #  0x1E -> RECORD SEPARATOR
+    u'\x1f'     #  0x1F -> UNIT SEPARATOR
+    u' '        #  0x20 -> SPACE
+    u'!'        #  0x21 -> EXCLAMATION MARK
+    u'"'        #  0x22 -> QUOTATION MARK
+    u'#'        #  0x23 -> NUMBER SIGN
+    u'$'        #  0x24 -> DOLLAR SIGN
+    u'%'        #  0x25 -> PERCENT SIGN
+    u'&'        #  0x26 -> AMPERSAND
+    u"'"        #  0x27 -> APOSTROPHE
+    u'('        #  0x28 -> LEFT PARENTHESIS
+    u')'        #  0x29 -> RIGHT PARENTHESIS
+    u'*'        #  0x2A -> ASTERISK
+    u'+'        #  0x2B -> PLUS SIGN
+    u','        #  0x2C -> COMMA
+    u'-'        #  0x2D -> HYPHEN-MINUS
+    u'.'        #  0x2E -> FULL STOP
+    u'/'        #  0x2F -> SOLIDUS
+    u'0'        #  0x30 -> DIGIT ZERO
+    u'1'        #  0x31 -> DIGIT ONE
+    u'2'        #  0x32 -> DIGIT TWO
+    u'3'        #  0x33 -> DIGIT THREE
+    u'4'        #  0x34 -> DIGIT FOUR
+    u'5'        #  0x35 -> DIGIT FIVE
+    u'6'        #  0x36 -> DIGIT SIX
+    u'7'        #  0x37 -> DIGIT SEVEN
+    u'8'        #  0x38 -> DIGIT EIGHT
+    u'9'        #  0x39 -> DIGIT NINE
+    u':'        #  0x3A -> COLON
+    u';'        #  0x3B -> SEMICOLON
+    u'<'        #  0x3C -> LESS-THAN SIGN
+    u'='        #  0x3D -> EQUALS SIGN
+    u'>'        #  0x3E -> GREATER-THAN SIGN
+    u'?'        #  0x3F -> QUESTION MARK
+    u'@'        #  0x40 -> COMMERCIAL AT
+    u'A'        #  0x41 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x42 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x43 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x44 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x45 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x46 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x47 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x48 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x49 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x4A -> LATIN CAPITAL LETTER J
+    u'K'        #  0x4B -> LATIN CAPITAL LETTER K
+    u'L'        #  0x4C -> LATIN CAPITAL LETTER L
+    u'M'        #  0x4D -> LATIN CAPITAL LETTER M
+    u'N'        #  0x4E -> LATIN CAPITAL LETTER N
+    u'O'        #  0x4F -> LATIN CAPITAL LETTER O
+    u'P'        #  0x50 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x51 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x52 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x53 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x54 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x55 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x56 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x57 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x58 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x59 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x5A -> LATIN CAPITAL LETTER Z
+    u'['        #  0x5B -> LEFT SQUARE BRACKET
+    u'\\'       #  0x5C -> REVERSE SOLIDUS
+    u']'        #  0x5D -> RIGHT SQUARE BRACKET
+    u'^'        #  0x5E -> CIRCUMFLEX ACCENT
+    u'_'        #  0x5F -> LOW LINE
+    u'`'        #  0x60 -> GRAVE ACCENT
+    u'a'        #  0x61 -> LATIN SMALL LETTER A
+    u'b'        #  0x62 -> LATIN SMALL LETTER B
+    u'c'        #  0x63 -> LATIN SMALL LETTER C
+    u'd'        #  0x64 -> LATIN SMALL LETTER D
+    u'e'        #  0x65 -> LATIN SMALL LETTER E
+    u'f'        #  0x66 -> LATIN SMALL LETTER F
+    u'g'        #  0x67 -> LATIN SMALL LETTER G
+    u'h'        #  0x68 -> LATIN SMALL LETTER H
+    u'i'        #  0x69 -> LATIN SMALL LETTER I
+    u'j'        #  0x6A -> LATIN SMALL LETTER J
+    u'k'        #  0x6B -> LATIN SMALL LETTER K
+    u'l'        #  0x6C -> LATIN SMALL LETTER L
+    u'm'        #  0x6D -> LATIN SMALL LETTER M
+    u'n'        #  0x6E -> LATIN SMALL LETTER N
+    u'o'        #  0x6F -> LATIN SMALL LETTER O
+    u'p'        #  0x70 -> LATIN SMALL LETTER P
+    u'q'        #  0x71 -> LATIN SMALL LETTER Q
+    u'r'        #  0x72 -> LATIN SMALL LETTER R
+    u's'        #  0x73 -> LATIN SMALL LETTER S
+    u't'        #  0x74 -> LATIN SMALL LETTER T
+    u'u'        #  0x75 -> LATIN SMALL LETTER U
+    u'v'        #  0x76 -> LATIN SMALL LETTER V
+    u'w'        #  0x77 -> LATIN SMALL LETTER W
+    u'x'        #  0x78 -> LATIN SMALL LETTER X
+    u'y'        #  0x79 -> LATIN SMALL LETTER Y
+    u'z'        #  0x7A -> LATIN SMALL LETTER Z
+    u'{'        #  0x7B -> LEFT CURLY BRACKET
+    u'|'        #  0x7C -> VERTICAL LINE
+    u'}'        #  0x7D -> RIGHT CURLY BRACKET
+    u'~'        #  0x7E -> TILDE
+    u'\x7f'     #  0x7F -> DELETE
+    u'\x80'     #  0x80 -> <control>
+    u'\x81'     #  0x81 -> <control>
+    u'\x82'     #  0x82 -> <control>
+    u'\x83'     #  0x83 -> <control>
+    u'\x84'     #  0x84 -> <control>
+    u'\x85'     #  0x85 -> <control>
+    u'\x86'     #  0x86 -> <control>
+    u'\x87'     #  0x87 -> <control>
+    u'\x88'     #  0x88 -> <control>
+    u'\x89'     #  0x89 -> <control>
+    u'\x8a'     #  0x8A -> <control>
+    u'\x8b'     #  0x8B -> <control>
+    u'\x8c'     #  0x8C -> <control>
+    u'\x8d'     #  0x8D -> <control>
+    u'\x8e'     #  0x8E -> <control>
+    u'\x8f'     #  0x8F -> <control>
+    u'\x90'     #  0x90 -> <control>
+    u'\x91'     #  0x91 -> <control>
+    u'\x92'     #  0x92 -> <control>
+    u'\x93'     #  0x93 -> <control>
+    u'\x94'     #  0x94 -> <control>
+    u'\x95'     #  0x95 -> <control>
+    u'\x96'     #  0x96 -> <control>
+    u'\x97'     #  0x97 -> <control>
+    u'\x98'     #  0x98 -> <control>
+    u'\x99'     #  0x99 -> <control>
+    u'\x9a'     #  0x9A -> <control>
+    u'\x9b'     #  0x9B -> <control>
+    u'\x9c'     #  0x9C -> <control>
+    u'\x9d'     #  0x9D -> <control>
+    u'\x9e'     #  0x9E -> <control>
+    u'\x9f'     #  0x9F -> <control>
+    u'\xa0'     #  0xA0 -> NO-BREAK SPACE
+    u'\u0104'   #  0xA1 -> LATIN CAPITAL LETTER A WITH OGONEK
+    u'\u0138'   #  0xA2 -> LATIN SMALL LETTER KRA
+    u'\u0156'   #  0xA3 -> LATIN CAPITAL LETTER R WITH CEDILLA
+    u'\xa4'     #  0xA4 -> CURRENCY SIGN
+    u'\u0128'   #  0xA5 -> LATIN CAPITAL LETTER I WITH TILDE
+    u'\u013b'   #  0xA6 -> LATIN CAPITAL LETTER L WITH CEDILLA
+    u'\xa7'     #  0xA7 -> SECTION SIGN
+    u'\xa8'     #  0xA8 -> DIAERESIS
+    u'\u0160'   #  0xA9 -> LATIN CAPITAL LETTER S WITH CARON
+    u'\u0112'   #  0xAA -> LATIN CAPITAL LETTER E WITH MACRON
+    u'\u0122'   #  0xAB -> LATIN CAPITAL LETTER G WITH CEDILLA
+    u'\u0166'   #  0xAC -> LATIN CAPITAL LETTER T WITH STROKE
+    u'\xad'     #  0xAD -> SOFT HYPHEN
+    u'\u017d'   #  0xAE -> LATIN CAPITAL LETTER Z WITH CARON
+    u'\xaf'     #  0xAF -> MACRON
+    u'\xb0'     #  0xB0 -> DEGREE SIGN
+    u'\u0105'   #  0xB1 -> LATIN SMALL LETTER A WITH OGONEK
+    u'\u02db'   #  0xB2 -> OGONEK
+    u'\u0157'   #  0xB3 -> LATIN SMALL LETTER R WITH CEDILLA
+    u'\xb4'     #  0xB4 -> ACUTE ACCENT
+    u'\u0129'   #  0xB5 -> LATIN SMALL LETTER I WITH TILDE
+    u'\u013c'   #  0xB6 -> LATIN SMALL LETTER L WITH CEDILLA
+    u'\u02c7'   #  0xB7 -> CARON
+    u'\xb8'     #  0xB8 -> CEDILLA
+    u'\u0161'   #  0xB9 -> LATIN SMALL LETTER S WITH CARON
+    u'\u0113'   #  0xBA -> LATIN SMALL LETTER E WITH MACRON
+    u'\u0123'   #  0xBB -> LATIN SMALL LETTER G WITH CEDILLA
+    u'\u0167'   #  0xBC -> LATIN SMALL LETTER T WITH STROKE
+    u'\u014a'   #  0xBD -> LATIN CAPITAL LETTER ENG
+    u'\u017e'   #  0xBE -> LATIN SMALL LETTER Z WITH CARON
+    u'\u014b'   #  0xBF -> LATIN SMALL LETTER ENG
+    u'\u0100'   #  0xC0 -> LATIN CAPITAL LETTER A WITH MACRON
+    u'\xc1'     #  0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE
+    u'\xc2'     #  0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+    u'\xc3'     #  0xC3 -> LATIN CAPITAL LETTER A WITH TILDE
+    u'\xc4'     #  0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS
+    u'\xc5'     #  0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE
+    u'\xc6'     #  0xC6 -> LATIN CAPITAL LETTER AE
+    u'\u012e'   #  0xC7 -> LATIN CAPITAL LETTER I WITH OGONEK
+    u'\u010c'   #  0xC8 -> LATIN CAPITAL LETTER C WITH CARON
+    u'\xc9'     #  0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE
+    u'\u0118'   #  0xCA -> LATIN CAPITAL LETTER E WITH OGONEK
+    u'\xcb'     #  0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS
+    u'\u0116'   #  0xCC -> LATIN CAPITAL LETTER E WITH DOT ABOVE
+    u'\xcd'     #  0xCD -> LATIN CAPITAL LETTER I WITH ACUTE
+    u'\xce'     #  0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+    u'\u012a'   #  0xCF -> LATIN CAPITAL LETTER I WITH MACRON
+    u'\u0110'   #  0xD0 -> LATIN CAPITAL LETTER D WITH STROKE
+    u'\u0145'   #  0xD1 -> LATIN CAPITAL LETTER N WITH CEDILLA
+    u'\u014c'   #  0xD2 -> LATIN CAPITAL LETTER O WITH MACRON
+    u'\u0136'   #  0xD3 -> LATIN CAPITAL LETTER K WITH CEDILLA
+    u'\xd4'     #  0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+    u'\xd5'     #  0xD5 -> LATIN CAPITAL LETTER O WITH TILDE
+    u'\xd6'     #  0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS
+    u'\xd7'     #  0xD7 -> MULTIPLICATION SIGN
+    u'\xd8'     #  0xD8 -> LATIN CAPITAL LETTER O WITH STROKE
+    u'\u0172'   #  0xD9 -> LATIN CAPITAL LETTER U WITH OGONEK
+    u'\xda'     #  0xDA -> LATIN CAPITAL LETTER U WITH ACUTE
+    u'\xdb'     #  0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+    u'\xdc'     #  0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS
+    u'\u0168'   #  0xDD -> LATIN CAPITAL LETTER U WITH TILDE
+    u'\u016a'   #  0xDE -> LATIN CAPITAL LETTER U WITH MACRON
+    u'\xdf'     #  0xDF -> LATIN SMALL LETTER SHARP S
+    u'\u0101'   #  0xE0 -> LATIN SMALL LETTER A WITH MACRON
+    u'\xe1'     #  0xE1 -> LATIN SMALL LETTER A WITH ACUTE
+    u'\xe2'     #  0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX
+    u'\xe3'     #  0xE3 -> LATIN SMALL LETTER A WITH TILDE
+    u'\xe4'     #  0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS
+    u'\xe5'     #  0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE
+    u'\xe6'     #  0xE6 -> LATIN SMALL LETTER AE
+    u'\u012f'   #  0xE7 -> LATIN SMALL LETTER I WITH OGONEK
+    u'\u010d'   #  0xE8 -> LATIN SMALL LETTER C WITH CARON
+    u'\xe9'     #  0xE9 -> LATIN SMALL LETTER E WITH ACUTE
+    u'\u0119'   #  0xEA -> LATIN SMALL LETTER E WITH OGONEK
+    u'\xeb'     #  0xEB -> LATIN SMALL LETTER E WITH DIAERESIS
+    u'\u0117'   #  0xEC -> LATIN SMALL LETTER E WITH DOT ABOVE
+    u'\xed'     #  0xED -> LATIN SMALL LETTER I WITH ACUTE
+    u'\xee'     #  0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX
+    u'\u012b'   #  0xEF -> LATIN SMALL LETTER I WITH MACRON
+    u'\u0111'   #  0xF0 -> LATIN SMALL LETTER D WITH STROKE
+    u'\u0146'   #  0xF1 -> LATIN SMALL LETTER N WITH CEDILLA
+    u'\u014d'   #  0xF2 -> LATIN SMALL LETTER O WITH MACRON
+    u'\u0137'   #  0xF3 -> LATIN SMALL LETTER K WITH CEDILLA
+    u'\xf4'     #  0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX
+    u'\xf5'     #  0xF5 -> LATIN SMALL LETTER O WITH TILDE
+    u'\xf6'     #  0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS
+    u'\xf7'     #  0xF7 -> DIVISION SIGN
+    u'\xf8'     #  0xF8 -> LATIN SMALL LETTER O WITH STROKE
+    u'\u0173'   #  0xF9 -> LATIN SMALL LETTER U WITH OGONEK
+    u'\xfa'     #  0xFA -> LATIN SMALL LETTER U WITH ACUTE
+    u'\xfb'     #  0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX
+    u'\xfc'     #  0xFC -> LATIN SMALL LETTER U WITH DIAERESIS
+    u'\u0169'   #  0xFD -> LATIN SMALL LETTER U WITH TILDE
+    u'\u016b'   #  0xFE -> LATIN SMALL LETTER U WITH MACRON
+    u'\u02d9'   #  0xFF -> DOT ABOVE
+)
+
+### Encoding table
+encoding_table=codecs.charmap_build(decoding_table)

Added: vendor/Python/current/Lib/encodings/iso8859_5.py
===================================================================
--- vendor/Python/current/Lib/encodings/iso8859_5.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/iso8859_5.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,307 @@
+""" Python Character Mapping Codec iso8859_5 generated from 'MAPPINGS/ISO8859/8859-5.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_table)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_table)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='iso8859-5',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x00 -> NULL
+    u'\x01'     #  0x01 -> START OF HEADING
+    u'\x02'     #  0x02 -> START OF TEXT
+    u'\x03'     #  0x03 -> END OF TEXT
+    u'\x04'     #  0x04 -> END OF TRANSMISSION
+    u'\x05'     #  0x05 -> ENQUIRY
+    u'\x06'     #  0x06 -> ACKNOWLEDGE
+    u'\x07'     #  0x07 -> BELL
+    u'\x08'     #  0x08 -> BACKSPACE
+    u'\t'       #  0x09 -> HORIZONTAL TABULATION
+    u'\n'       #  0x0A -> LINE FEED
+    u'\x0b'     #  0x0B -> VERTICAL TABULATION
+    u'\x0c'     #  0x0C -> FORM FEED
+    u'\r'       #  0x0D -> CARRIAGE RETURN
+    u'\x0e'     #  0x0E -> SHIFT OUT
+    u'\x0f'     #  0x0F -> SHIFT IN
+    u'\x10'     #  0x10 -> DATA LINK ESCAPE
+    u'\x11'     #  0x11 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x12 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x13 -> DEVICE CONTROL THREE
+    u'\x14'     #  0x14 -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x15 -> NEGATIVE ACKNOWLEDGE
+    u'\x16'     #  0x16 -> SYNCHRONOUS IDLE
+    u'\x17'     #  0x17 -> END OF TRANSMISSION BLOCK
+    u'\x18'     #  0x18 -> CANCEL
+    u'\x19'     #  0x19 -> END OF MEDIUM
+    u'\x1a'     #  0x1A -> SUBSTITUTE
+    u'\x1b'     #  0x1B -> ESCAPE
+    u'\x1c'     #  0x1C -> FILE SEPARATOR
+    u'\x1d'     #  0x1D -> GROUP SEPARATOR
+    u'\x1e'     #  0x1E -> RECORD SEPARATOR
+    u'\x1f'     #  0x1F -> UNIT SEPARATOR
+    u' '        #  0x20 -> SPACE
+    u'!'        #  0x21 -> EXCLAMATION MARK
+    u'"'        #  0x22 -> QUOTATION MARK
+    u'#'        #  0x23 -> NUMBER SIGN
+    u'$'        #  0x24 -> DOLLAR SIGN
+    u'%'        #  0x25 -> PERCENT SIGN
+    u'&'        #  0x26 -> AMPERSAND
+    u"'"        #  0x27 -> APOSTROPHE
+    u'('        #  0x28 -> LEFT PARENTHESIS
+    u')'        #  0x29 -> RIGHT PARENTHESIS
+    u'*'        #  0x2A -> ASTERISK
+    u'+'        #  0x2B -> PLUS SIGN
+    u','        #  0x2C -> COMMA
+    u'-'        #  0x2D -> HYPHEN-MINUS
+    u'.'        #  0x2E -> FULL STOP
+    u'/'        #  0x2F -> SOLIDUS
+    u'0'        #  0x30 -> DIGIT ZERO
+    u'1'        #  0x31 -> DIGIT ONE
+    u'2'        #  0x32 -> DIGIT TWO
+    u'3'        #  0x33 -> DIGIT THREE
+    u'4'        #  0x34 -> DIGIT FOUR
+    u'5'        #  0x35 -> DIGIT FIVE
+    u'6'        #  0x36 -> DIGIT SIX
+    u'7'        #  0x37 -> DIGIT SEVEN
+    u'8'        #  0x38 -> DIGIT EIGHT
+    u'9'        #  0x39 -> DIGIT NINE
+    u':'        #  0x3A -> COLON
+    u';'        #  0x3B -> SEMICOLON
+    u'<'        #  0x3C -> LESS-THAN SIGN
+    u'='        #  0x3D -> EQUALS SIGN
+    u'>'        #  0x3E -> GREATER-THAN SIGN
+    u'?'        #  0x3F -> QUESTION MARK
+    u'@'        #  0x40 -> COMMERCIAL AT
+    u'A'        #  0x41 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x42 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x43 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x44 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x45 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x46 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x47 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x48 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x49 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x4A -> LATIN CAPITAL LETTER J
+    u'K'        #  0x4B -> LATIN CAPITAL LETTER K
+    u'L'        #  0x4C -> LATIN CAPITAL LETTER L
+    u'M'        #  0x4D -> LATIN CAPITAL LETTER M
+    u'N'        #  0x4E -> LATIN CAPITAL LETTER N
+    u'O'        #  0x4F -> LATIN CAPITAL LETTER O
+    u'P'        #  0x50 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x51 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x52 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x53 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x54 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x55 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x56 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x57 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x58 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x59 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x5A -> LATIN CAPITAL LETTER Z
+    u'['        #  0x5B -> LEFT SQUARE BRACKET
+    u'\\'       #  0x5C -> REVERSE SOLIDUS
+    u']'        #  0x5D -> RIGHT SQUARE BRACKET
+    u'^'        #  0x5E -> CIRCUMFLEX ACCENT
+    u'_'        #  0x5F -> LOW LINE
+    u'`'        #  0x60 -> GRAVE ACCENT
+    u'a'        #  0x61 -> LATIN SMALL LETTER A
+    u'b'        #  0x62 -> LATIN SMALL LETTER B
+    u'c'        #  0x63 -> LATIN SMALL LETTER C
+    u'd'        #  0x64 -> LATIN SMALL LETTER D
+    u'e'        #  0x65 -> LATIN SMALL LETTER E
+    u'f'        #  0x66 -> LATIN SMALL LETTER F
+    u'g'        #  0x67 -> LATIN SMALL LETTER G
+    u'h'        #  0x68 -> LATIN SMALL LETTER H
+    u'i'        #  0x69 -> LATIN SMALL LETTER I
+    u'j'        #  0x6A -> LATIN SMALL LETTER J
+    u'k'        #  0x6B -> LATIN SMALL LETTER K
+    u'l'        #  0x6C -> LATIN SMALL LETTER L
+    u'm'        #  0x6D -> LATIN SMALL LETTER M
+    u'n'        #  0x6E -> LATIN SMALL LETTER N
+    u'o'        #  0x6F -> LATIN SMALL LETTER O
+    u'p'        #  0x70 -> LATIN SMALL LETTER P
+    u'q'        #  0x71 -> LATIN SMALL LETTER Q
+    u'r'        #  0x72 -> LATIN SMALL LETTER R
+    u's'        #  0x73 -> LATIN SMALL LETTER S
+    u't'        #  0x74 -> LATIN SMALL LETTER T
+    u'u'        #  0x75 -> LATIN SMALL LETTER U
+    u'v'        #  0x76 -> LATIN SMALL LETTER V
+    u'w'        #  0x77 -> LATIN SMALL LETTER W
+    u'x'        #  0x78 -> LATIN SMALL LETTER X
+    u'y'        #  0x79 -> LATIN SMALL LETTER Y
+    u'z'        #  0x7A -> LATIN SMALL LETTER Z
+    u'{'        #  0x7B -> LEFT CURLY BRACKET
+    u'|'        #  0x7C -> VERTICAL LINE
+    u'}'        #  0x7D -> RIGHT CURLY BRACKET
+    u'~'        #  0x7E -> TILDE
+    u'\x7f'     #  0x7F -> DELETE
+    u'\x80'     #  0x80 -> <control>
+    u'\x81'     #  0x81 -> <control>
+    u'\x82'     #  0x82 -> <control>
+    u'\x83'     #  0x83 -> <control>
+    u'\x84'     #  0x84 -> <control>
+    u'\x85'     #  0x85 -> <control>
+    u'\x86'     #  0x86 -> <control>
+    u'\x87'     #  0x87 -> <control>
+    u'\x88'     #  0x88 -> <control>
+    u'\x89'     #  0x89 -> <control>
+    u'\x8a'     #  0x8A -> <control>
+    u'\x8b'     #  0x8B -> <control>
+    u'\x8c'     #  0x8C -> <control>
+    u'\x8d'     #  0x8D -> <control>
+    u'\x8e'     #  0x8E -> <control>
+    u'\x8f'     #  0x8F -> <control>
+    u'\x90'     #  0x90 -> <control>
+    u'\x91'     #  0x91 -> <control>
+    u'\x92'     #  0x92 -> <control>
+    u'\x93'     #  0x93 -> <control>
+    u'\x94'     #  0x94 -> <control>
+    u'\x95'     #  0x95 -> <control>
+    u'\x96'     #  0x96 -> <control>
+    u'\x97'     #  0x97 -> <control>
+    u'\x98'     #  0x98 -> <control>
+    u'\x99'     #  0x99 -> <control>
+    u'\x9a'     #  0x9A -> <control>
+    u'\x9b'     #  0x9B -> <control>
+    u'\x9c'     #  0x9C -> <control>
+    u'\x9d'     #  0x9D -> <control>
+    u'\x9e'     #  0x9E -> <control>
+    u'\x9f'     #  0x9F -> <control>
+    u'\xa0'     #  0xA0 -> NO-BREAK SPACE
+    u'\u0401'   #  0xA1 -> CYRILLIC CAPITAL LETTER IO
+    u'\u0402'   #  0xA2 -> CYRILLIC CAPITAL LETTER DJE
+    u'\u0403'   #  0xA3 -> CYRILLIC CAPITAL LETTER GJE
+    u'\u0404'   #  0xA4 -> CYRILLIC CAPITAL LETTER UKRAINIAN IE
+    u'\u0405'   #  0xA5 -> CYRILLIC CAPITAL LETTER DZE
+    u'\u0406'   #  0xA6 -> CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I
+    u'\u0407'   #  0xA7 -> CYRILLIC CAPITAL LETTER YI
+    u'\u0408'   #  0xA8 -> CYRILLIC CAPITAL LETTER JE
+    u'\u0409'   #  0xA9 -> CYRILLIC CAPITAL LETTER LJE
+    u'\u040a'   #  0xAA -> CYRILLIC CAPITAL LETTER NJE
+    u'\u040b'   #  0xAB -> CYRILLIC CAPITAL LETTER TSHE
+    u'\u040c'   #  0xAC -> CYRILLIC CAPITAL LETTER KJE
+    u'\xad'     #  0xAD -> SOFT HYPHEN
+    u'\u040e'   #  0xAE -> CYRILLIC CAPITAL LETTER SHORT U
+    u'\u040f'   #  0xAF -> CYRILLIC CAPITAL LETTER DZHE
+    u'\u0410'   #  0xB0 -> CYRILLIC CAPITAL LETTER A
+    u'\u0411'   #  0xB1 -> CYRILLIC CAPITAL LETTER BE
+    u'\u0412'   #  0xB2 -> CYRILLIC CAPITAL LETTER VE
+    u'\u0413'   #  0xB3 -> CYRILLIC CAPITAL LETTER GHE
+    u'\u0414'   #  0xB4 -> CYRILLIC CAPITAL LETTER DE
+    u'\u0415'   #  0xB5 -> CYRILLIC CAPITAL LETTER IE
+    u'\u0416'   #  0xB6 -> CYRILLIC CAPITAL LETTER ZHE
+    u'\u0417'   #  0xB7 -> CYRILLIC CAPITAL LETTER ZE
+    u'\u0418'   #  0xB8 -> CYRILLIC CAPITAL LETTER I
+    u'\u0419'   #  0xB9 -> CYRILLIC CAPITAL LETTER SHORT I
+    u'\u041a'   #  0xBA -> CYRILLIC CAPITAL LETTER KA
+    u'\u041b'   #  0xBB -> CYRILLIC CAPITAL LETTER EL
+    u'\u041c'   #  0xBC -> CYRILLIC CAPITAL LETTER EM
+    u'\u041d'   #  0xBD -> CYRILLIC CAPITAL LETTER EN
+    u'\u041e'   #  0xBE -> CYRILLIC CAPITAL LETTER O
+    u'\u041f'   #  0xBF -> CYRILLIC CAPITAL LETTER PE
+    u'\u0420'   #  0xC0 -> CYRILLIC CAPITAL LETTER ER
+    u'\u0421'   #  0xC1 -> CYRILLIC CAPITAL LETTER ES
+    u'\u0422'   #  0xC2 -> CYRILLIC CAPITAL LETTER TE
+    u'\u0423'   #  0xC3 -> CYRILLIC CAPITAL LETTER U
+    u'\u0424'   #  0xC4 -> CYRILLIC CAPITAL LETTER EF
+    u'\u0425'   #  0xC5 -> CYRILLIC CAPITAL LETTER HA
+    u'\u0426'   #  0xC6 -> CYRILLIC CAPITAL LETTER TSE
+    u'\u0427'   #  0xC7 -> CYRILLIC CAPITAL LETTER CHE
+    u'\u0428'   #  0xC8 -> CYRILLIC CAPITAL LETTER SHA
+    u'\u0429'   #  0xC9 -> CYRILLIC CAPITAL LETTER SHCHA
+    u'\u042a'   #  0xCA -> CYRILLIC CAPITAL LETTER HARD SIGN
+    u'\u042b'   #  0xCB -> CYRILLIC CAPITAL LETTER YERU
+    u'\u042c'   #  0xCC -> CYRILLIC CAPITAL LETTER SOFT SIGN
+    u'\u042d'   #  0xCD -> CYRILLIC CAPITAL LETTER E
+    u'\u042e'   #  0xCE -> CYRILLIC CAPITAL LETTER YU
+    u'\u042f'   #  0xCF -> CYRILLIC CAPITAL LETTER YA
+    u'\u0430'   #  0xD0 -> CYRILLIC SMALL LETTER A
+    u'\u0431'   #  0xD1 -> CYRILLIC SMALL LETTER BE
+    u'\u0432'   #  0xD2 -> CYRILLIC SMALL LETTER VE
+    u'\u0433'   #  0xD3 -> CYRILLIC SMALL LETTER GHE
+    u'\u0434'   #  0xD4 -> CYRILLIC SMALL LETTER DE
+    u'\u0435'   #  0xD5 -> CYRILLIC SMALL LETTER IE
+    u'\u0436'   #  0xD6 -> CYRILLIC SMALL LETTER ZHE
+    u'\u0437'   #  0xD7 -> CYRILLIC SMALL LETTER ZE
+    u'\u0438'   #  0xD8 -> CYRILLIC SMALL LETTER I
+    u'\u0439'   #  0xD9 -> CYRILLIC SMALL LETTER SHORT I
+    u'\u043a'   #  0xDA -> CYRILLIC SMALL LETTER KA
+    u'\u043b'   #  0xDB -> CYRILLIC SMALL LETTER EL
+    u'\u043c'   #  0xDC -> CYRILLIC SMALL LETTER EM
+    u'\u043d'   #  0xDD -> CYRILLIC SMALL LETTER EN
+    u'\u043e'   #  0xDE -> CYRILLIC SMALL LETTER O
+    u'\u043f'   #  0xDF -> CYRILLIC SMALL LETTER PE
+    u'\u0440'   #  0xE0 -> CYRILLIC SMALL LETTER ER
+    u'\u0441'   #  0xE1 -> CYRILLIC SMALL LETTER ES
+    u'\u0442'   #  0xE2 -> CYRILLIC SMALL LETTER TE
+    u'\u0443'   #  0xE3 -> CYRILLIC SMALL LETTER U
+    u'\u0444'   #  0xE4 -> CYRILLIC SMALL LETTER EF
+    u'\u0445'   #  0xE5 -> CYRILLIC SMALL LETTER HA
+    u'\u0446'   #  0xE6 -> CYRILLIC SMALL LETTER TSE
+    u'\u0447'   #  0xE7 -> CYRILLIC SMALL LETTER CHE
+    u'\u0448'   #  0xE8 -> CYRILLIC SMALL LETTER SHA
+    u'\u0449'   #  0xE9 -> CYRILLIC SMALL LETTER SHCHA
+    u'\u044a'   #  0xEA -> CYRILLIC SMALL LETTER HARD SIGN
+    u'\u044b'   #  0xEB -> CYRILLIC SMALL LETTER YERU
+    u'\u044c'   #  0xEC -> CYRILLIC SMALL LETTER SOFT SIGN
+    u'\u044d'   #  0xED -> CYRILLIC SMALL LETTER E
+    u'\u044e'   #  0xEE -> CYRILLIC SMALL LETTER YU
+    u'\u044f'   #  0xEF -> CYRILLIC SMALL LETTER YA
+    u'\u2116'   #  0xF0 -> NUMERO SIGN
+    u'\u0451'   #  0xF1 -> CYRILLIC SMALL LETTER IO
+    u'\u0452'   #  0xF2 -> CYRILLIC SMALL LETTER DJE
+    u'\u0453'   #  0xF3 -> CYRILLIC SMALL LETTER GJE
+    u'\u0454'   #  0xF4 -> CYRILLIC SMALL LETTER UKRAINIAN IE
+    u'\u0455'   #  0xF5 -> CYRILLIC SMALL LETTER DZE
+    u'\u0456'   #  0xF6 -> CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
+    u'\u0457'   #  0xF7 -> CYRILLIC SMALL LETTER YI
+    u'\u0458'   #  0xF8 -> CYRILLIC SMALL LETTER JE
+    u'\u0459'   #  0xF9 -> CYRILLIC SMALL LETTER LJE
+    u'\u045a'   #  0xFA -> CYRILLIC SMALL LETTER NJE
+    u'\u045b'   #  0xFB -> CYRILLIC SMALL LETTER TSHE
+    u'\u045c'   #  0xFC -> CYRILLIC SMALL LETTER KJE
+    u'\xa7'     #  0xFD -> SECTION SIGN
+    u'\u045e'   #  0xFE -> CYRILLIC SMALL LETTER SHORT U
+    u'\u045f'   #  0xFF -> CYRILLIC SMALL LETTER DZHE
+)
+
+### Encoding table
+encoding_table=codecs.charmap_build(decoding_table)

Added: vendor/Python/current/Lib/encodings/iso8859_6.py
===================================================================
--- vendor/Python/current/Lib/encodings/iso8859_6.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/iso8859_6.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,307 @@
+""" Python Character Mapping Codec iso8859_6 generated from 'MAPPINGS/ISO8859/8859-6.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_table)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_table)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='iso8859-6',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x00 -> NULL
+    u'\x01'     #  0x01 -> START OF HEADING
+    u'\x02'     #  0x02 -> START OF TEXT
+    u'\x03'     #  0x03 -> END OF TEXT
+    u'\x04'     #  0x04 -> END OF TRANSMISSION
+    u'\x05'     #  0x05 -> ENQUIRY
+    u'\x06'     #  0x06 -> ACKNOWLEDGE
+    u'\x07'     #  0x07 -> BELL
+    u'\x08'     #  0x08 -> BACKSPACE
+    u'\t'       #  0x09 -> HORIZONTAL TABULATION
+    u'\n'       #  0x0A -> LINE FEED
+    u'\x0b'     #  0x0B -> VERTICAL TABULATION
+    u'\x0c'     #  0x0C -> FORM FEED
+    u'\r'       #  0x0D -> CARRIAGE RETURN
+    u'\x0e'     #  0x0E -> SHIFT OUT
+    u'\x0f'     #  0x0F -> SHIFT IN
+    u'\x10'     #  0x10 -> DATA LINK ESCAPE
+    u'\x11'     #  0x11 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x12 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x13 -> DEVICE CONTROL THREE
+    u'\x14'     #  0x14 -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x15 -> NEGATIVE ACKNOWLEDGE
+    u'\x16'     #  0x16 -> SYNCHRONOUS IDLE
+    u'\x17'     #  0x17 -> END OF TRANSMISSION BLOCK
+    u'\x18'     #  0x18 -> CANCEL
+    u'\x19'     #  0x19 -> END OF MEDIUM
+    u'\x1a'     #  0x1A -> SUBSTITUTE
+    u'\x1b'     #  0x1B -> ESCAPE
+    u'\x1c'     #  0x1C -> FILE SEPARATOR
+    u'\x1d'     #  0x1D -> GROUP SEPARATOR
+    u'\x1e'     #  0x1E -> RECORD SEPARATOR
+    u'\x1f'     #  0x1F -> UNIT SEPARATOR
+    u' '        #  0x20 -> SPACE
+    u'!'        #  0x21 -> EXCLAMATION MARK
+    u'"'        #  0x22 -> QUOTATION MARK
+    u'#'        #  0x23 -> NUMBER SIGN
+    u'$'        #  0x24 -> DOLLAR SIGN
+    u'%'        #  0x25 -> PERCENT SIGN
+    u'&'        #  0x26 -> AMPERSAND
+    u"'"        #  0x27 -> APOSTROPHE
+    u'('        #  0x28 -> LEFT PARENTHESIS
+    u')'        #  0x29 -> RIGHT PARENTHESIS
+    u'*'        #  0x2A -> ASTERISK
+    u'+'        #  0x2B -> PLUS SIGN
+    u','        #  0x2C -> COMMA
+    u'-'        #  0x2D -> HYPHEN-MINUS
+    u'.'        #  0x2E -> FULL STOP
+    u'/'        #  0x2F -> SOLIDUS
+    u'0'        #  0x30 -> DIGIT ZERO
+    u'1'        #  0x31 -> DIGIT ONE
+    u'2'        #  0x32 -> DIGIT TWO
+    u'3'        #  0x33 -> DIGIT THREE
+    u'4'        #  0x34 -> DIGIT FOUR
+    u'5'        #  0x35 -> DIGIT FIVE
+    u'6'        #  0x36 -> DIGIT SIX
+    u'7'        #  0x37 -> DIGIT SEVEN
+    u'8'        #  0x38 -> DIGIT EIGHT
+    u'9'        #  0x39 -> DIGIT NINE
+    u':'        #  0x3A -> COLON
+    u';'        #  0x3B -> SEMICOLON
+    u'<'        #  0x3C -> LESS-THAN SIGN
+    u'='        #  0x3D -> EQUALS SIGN
+    u'>'        #  0x3E -> GREATER-THAN SIGN
+    u'?'        #  0x3F -> QUESTION MARK
+    u'@'        #  0x40 -> COMMERCIAL AT
+    u'A'        #  0x41 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x42 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x43 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x44 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x45 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x46 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x47 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x48 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x49 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x4A -> LATIN CAPITAL LETTER J
+    u'K'        #  0x4B -> LATIN CAPITAL LETTER K
+    u'L'        #  0x4C -> LATIN CAPITAL LETTER L
+    u'M'        #  0x4D -> LATIN CAPITAL LETTER M
+    u'N'        #  0x4E -> LATIN CAPITAL LETTER N
+    u'O'        #  0x4F -> LATIN CAPITAL LETTER O
+    u'P'        #  0x50 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x51 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x52 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x53 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x54 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x55 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x56 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x57 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x58 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x59 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x5A -> LATIN CAPITAL LETTER Z
+    u'['        #  0x5B -> LEFT SQUARE BRACKET
+    u'\\'       #  0x5C -> REVERSE SOLIDUS
+    u']'        #  0x5D -> RIGHT SQUARE BRACKET
+    u'^'        #  0x5E -> CIRCUMFLEX ACCENT
+    u'_'        #  0x5F -> LOW LINE
+    u'`'        #  0x60 -> GRAVE ACCENT
+    u'a'        #  0x61 -> LATIN SMALL LETTER A
+    u'b'        #  0x62 -> LATIN SMALL LETTER B
+    u'c'        #  0x63 -> LATIN SMALL LETTER C
+    u'd'        #  0x64 -> LATIN SMALL LETTER D
+    u'e'        #  0x65 -> LATIN SMALL LETTER E
+    u'f'        #  0x66 -> LATIN SMALL LETTER F
+    u'g'        #  0x67 -> LATIN SMALL LETTER G
+    u'h'        #  0x68 -> LATIN SMALL LETTER H
+    u'i'        #  0x69 -> LATIN SMALL LETTER I
+    u'j'        #  0x6A -> LATIN SMALL LETTER J
+    u'k'        #  0x6B -> LATIN SMALL LETTER K
+    u'l'        #  0x6C -> LATIN SMALL LETTER L
+    u'm'        #  0x6D -> LATIN SMALL LETTER M
+    u'n'        #  0x6E -> LATIN SMALL LETTER N
+    u'o'        #  0x6F -> LATIN SMALL LETTER O
+    u'p'        #  0x70 -> LATIN SMALL LETTER P
+    u'q'        #  0x71 -> LATIN SMALL LETTER Q
+    u'r'        #  0x72 -> LATIN SMALL LETTER R
+    u's'        #  0x73 -> LATIN SMALL LETTER S
+    u't'        #  0x74 -> LATIN SMALL LETTER T
+    u'u'        #  0x75 -> LATIN SMALL LETTER U
+    u'v'        #  0x76 -> LATIN SMALL LETTER V
+    u'w'        #  0x77 -> LATIN SMALL LETTER W
+    u'x'        #  0x78 -> LATIN SMALL LETTER X
+    u'y'        #  0x79 -> LATIN SMALL LETTER Y
+    u'z'        #  0x7A -> LATIN SMALL LETTER Z
+    u'{'        #  0x7B -> LEFT CURLY BRACKET
+    u'|'        #  0x7C -> VERTICAL LINE
+    u'}'        #  0x7D -> RIGHT CURLY BRACKET
+    u'~'        #  0x7E -> TILDE
+    u'\x7f'     #  0x7F -> DELETE
+    u'\x80'     #  0x80 -> <control>
+    u'\x81'     #  0x81 -> <control>
+    u'\x82'     #  0x82 -> <control>
+    u'\x83'     #  0x83 -> <control>
+    u'\x84'     #  0x84 -> <control>
+    u'\x85'     #  0x85 -> <control>
+    u'\x86'     #  0x86 -> <control>
+    u'\x87'     #  0x87 -> <control>
+    u'\x88'     #  0x88 -> <control>
+    u'\x89'     #  0x89 -> <control>
+    u'\x8a'     #  0x8A -> <control>
+    u'\x8b'     #  0x8B -> <control>
+    u'\x8c'     #  0x8C -> <control>
+    u'\x8d'     #  0x8D -> <control>
+    u'\x8e'     #  0x8E -> <control>
+    u'\x8f'     #  0x8F -> <control>
+    u'\x90'     #  0x90 -> <control>
+    u'\x91'     #  0x91 -> <control>
+    u'\x92'     #  0x92 -> <control>
+    u'\x93'     #  0x93 -> <control>
+    u'\x94'     #  0x94 -> <control>
+    u'\x95'     #  0x95 -> <control>
+    u'\x96'     #  0x96 -> <control>
+    u'\x97'     #  0x97 -> <control>
+    u'\x98'     #  0x98 -> <control>
+    u'\x99'     #  0x99 -> <control>
+    u'\x9a'     #  0x9A -> <control>
+    u'\x9b'     #  0x9B -> <control>
+    u'\x9c'     #  0x9C -> <control>
+    u'\x9d'     #  0x9D -> <control>
+    u'\x9e'     #  0x9E -> <control>
+    u'\x9f'     #  0x9F -> <control>
+    u'\xa0'     #  0xA0 -> NO-BREAK SPACE
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\xa4'     #  0xA4 -> CURRENCY SIGN
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\u060c'   #  0xAC -> ARABIC COMMA
+    u'\xad'     #  0xAD -> SOFT HYPHEN
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\u061b'   #  0xBB -> ARABIC SEMICOLON
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\u061f'   #  0xBF -> ARABIC QUESTION MARK
+    u'\ufffe'
+    u'\u0621'   #  0xC1 -> ARABIC LETTER HAMZA
+    u'\u0622'   #  0xC2 -> ARABIC LETTER ALEF WITH MADDA ABOVE
+    u'\u0623'   #  0xC3 -> ARABIC LETTER ALEF WITH HAMZA ABOVE
+    u'\u0624'   #  0xC4 -> ARABIC LETTER WAW WITH HAMZA ABOVE
+    u'\u0625'   #  0xC5 -> ARABIC LETTER ALEF WITH HAMZA BELOW
+    u'\u0626'   #  0xC6 -> ARABIC LETTER YEH WITH HAMZA ABOVE
+    u'\u0627'   #  0xC7 -> ARABIC LETTER ALEF
+    u'\u0628'   #  0xC8 -> ARABIC LETTER BEH
+    u'\u0629'   #  0xC9 -> ARABIC LETTER TEH MARBUTA
+    u'\u062a'   #  0xCA -> ARABIC LETTER TEH
+    u'\u062b'   #  0xCB -> ARABIC LETTER THEH
+    u'\u062c'   #  0xCC -> ARABIC LETTER JEEM
+    u'\u062d'   #  0xCD -> ARABIC LETTER HAH
+    u'\u062e'   #  0xCE -> ARABIC LETTER KHAH
+    u'\u062f'   #  0xCF -> ARABIC LETTER DAL
+    u'\u0630'   #  0xD0 -> ARABIC LETTER THAL
+    u'\u0631'   #  0xD1 -> ARABIC LETTER REH
+    u'\u0632'   #  0xD2 -> ARABIC LETTER ZAIN
+    u'\u0633'   #  0xD3 -> ARABIC LETTER SEEN
+    u'\u0634'   #  0xD4 -> ARABIC LETTER SHEEN
+    u'\u0635'   #  0xD5 -> ARABIC LETTER SAD
+    u'\u0636'   #  0xD6 -> ARABIC LETTER DAD
+    u'\u0637'   #  0xD7 -> ARABIC LETTER TAH
+    u'\u0638'   #  0xD8 -> ARABIC LETTER ZAH
+    u'\u0639'   #  0xD9 -> ARABIC LETTER AIN
+    u'\u063a'   #  0xDA -> ARABIC LETTER GHAIN
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\u0640'   #  0xE0 -> ARABIC TATWEEL
+    u'\u0641'   #  0xE1 -> ARABIC LETTER FEH
+    u'\u0642'   #  0xE2 -> ARABIC LETTER QAF
+    u'\u0643'   #  0xE3 -> ARABIC LETTER KAF
+    u'\u0644'   #  0xE4 -> ARABIC LETTER LAM
+    u'\u0645'   #  0xE5 -> ARABIC LETTER MEEM
+    u'\u0646'   #  0xE6 -> ARABIC LETTER NOON
+    u'\u0647'   #  0xE7 -> ARABIC LETTER HEH
+    u'\u0648'   #  0xE8 -> ARABIC LETTER WAW
+    u'\u0649'   #  0xE9 -> ARABIC LETTER ALEF MAKSURA
+    u'\u064a'   #  0xEA -> ARABIC LETTER YEH
+    u'\u064b'   #  0xEB -> ARABIC FATHATAN
+    u'\u064c'   #  0xEC -> ARABIC DAMMATAN
+    u'\u064d'   #  0xED -> ARABIC KASRATAN
+    u'\u064e'   #  0xEE -> ARABIC FATHA
+    u'\u064f'   #  0xEF -> ARABIC DAMMA
+    u'\u0650'   #  0xF0 -> ARABIC KASRA
+    u'\u0651'   #  0xF1 -> ARABIC SHADDA
+    u'\u0652'   #  0xF2 -> ARABIC SUKUN
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+)
+
+### Encoding table
+encoding_table=codecs.charmap_build(decoding_table)

Added: vendor/Python/current/Lib/encodings/iso8859_7.py
===================================================================
--- vendor/Python/current/Lib/encodings/iso8859_7.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/iso8859_7.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,307 @@
+""" Python Character Mapping Codec iso8859_7 generated from 'MAPPINGS/ISO8859/8859-7.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_table)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_table)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='iso8859-7',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x00 -> NULL
+    u'\x01'     #  0x01 -> START OF HEADING
+    u'\x02'     #  0x02 -> START OF TEXT
+    u'\x03'     #  0x03 -> END OF TEXT
+    u'\x04'     #  0x04 -> END OF TRANSMISSION
+    u'\x05'     #  0x05 -> ENQUIRY
+    u'\x06'     #  0x06 -> ACKNOWLEDGE
+    u'\x07'     #  0x07 -> BELL
+    u'\x08'     #  0x08 -> BACKSPACE
+    u'\t'       #  0x09 -> HORIZONTAL TABULATION
+    u'\n'       #  0x0A -> LINE FEED
+    u'\x0b'     #  0x0B -> VERTICAL TABULATION
+    u'\x0c'     #  0x0C -> FORM FEED
+    u'\r'       #  0x0D -> CARRIAGE RETURN
+    u'\x0e'     #  0x0E -> SHIFT OUT
+    u'\x0f'     #  0x0F -> SHIFT IN
+    u'\x10'     #  0x10 -> DATA LINK ESCAPE
+    u'\x11'     #  0x11 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x12 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x13 -> DEVICE CONTROL THREE
+    u'\x14'     #  0x14 -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x15 -> NEGATIVE ACKNOWLEDGE
+    u'\x16'     #  0x16 -> SYNCHRONOUS IDLE
+    u'\x17'     #  0x17 -> END OF TRANSMISSION BLOCK
+    u'\x18'     #  0x18 -> CANCEL
+    u'\x19'     #  0x19 -> END OF MEDIUM
+    u'\x1a'     #  0x1A -> SUBSTITUTE
+    u'\x1b'     #  0x1B -> ESCAPE
+    u'\x1c'     #  0x1C -> FILE SEPARATOR
+    u'\x1d'     #  0x1D -> GROUP SEPARATOR
+    u'\x1e'     #  0x1E -> RECORD SEPARATOR
+    u'\x1f'     #  0x1F -> UNIT SEPARATOR
+    u' '        #  0x20 -> SPACE
+    u'!'        #  0x21 -> EXCLAMATION MARK
+    u'"'        #  0x22 -> QUOTATION MARK
+    u'#'        #  0x23 -> NUMBER SIGN
+    u'$'        #  0x24 -> DOLLAR SIGN
+    u'%'        #  0x25 -> PERCENT SIGN
+    u'&'        #  0x26 -> AMPERSAND
+    u"'"        #  0x27 -> APOSTROPHE
+    u'('        #  0x28 -> LEFT PARENTHESIS
+    u')'        #  0x29 -> RIGHT PARENTHESIS
+    u'*'        #  0x2A -> ASTERISK
+    u'+'        #  0x2B -> PLUS SIGN
+    u','        #  0x2C -> COMMA
+    u'-'        #  0x2D -> HYPHEN-MINUS
+    u'.'        #  0x2E -> FULL STOP
+    u'/'        #  0x2F -> SOLIDUS
+    u'0'        #  0x30 -> DIGIT ZERO
+    u'1'        #  0x31 -> DIGIT ONE
+    u'2'        #  0x32 -> DIGIT TWO
+    u'3'        #  0x33 -> DIGIT THREE
+    u'4'        #  0x34 -> DIGIT FOUR
+    u'5'        #  0x35 -> DIGIT FIVE
+    u'6'        #  0x36 -> DIGIT SIX
+    u'7'        #  0x37 -> DIGIT SEVEN
+    u'8'        #  0x38 -> DIGIT EIGHT
+    u'9'        #  0x39 -> DIGIT NINE
+    u':'        #  0x3A -> COLON
+    u';'        #  0x3B -> SEMICOLON
+    u'<'        #  0x3C -> LESS-THAN SIGN
+    u'='        #  0x3D -> EQUALS SIGN
+    u'>'        #  0x3E -> GREATER-THAN SIGN
+    u'?'        #  0x3F -> QUESTION MARK
+    u'@'        #  0x40 -> COMMERCIAL AT
+    u'A'        #  0x41 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x42 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x43 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x44 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x45 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x46 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x47 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x48 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x49 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x4A -> LATIN CAPITAL LETTER J
+    u'K'        #  0x4B -> LATIN CAPITAL LETTER K
+    u'L'        #  0x4C -> LATIN CAPITAL LETTER L
+    u'M'        #  0x4D -> LATIN CAPITAL LETTER M
+    u'N'        #  0x4E -> LATIN CAPITAL LETTER N
+    u'O'        #  0x4F -> LATIN CAPITAL LETTER O
+    u'P'        #  0x50 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x51 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x52 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x53 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x54 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x55 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x56 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x57 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x58 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x59 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x5A -> LATIN CAPITAL LETTER Z
+    u'['        #  0x5B -> LEFT SQUARE BRACKET
+    u'\\'       #  0x5C -> REVERSE SOLIDUS
+    u']'        #  0x5D -> RIGHT SQUARE BRACKET
+    u'^'        #  0x5E -> CIRCUMFLEX ACCENT
+    u'_'        #  0x5F -> LOW LINE
+    u'`'        #  0x60 -> GRAVE ACCENT
+    u'a'        #  0x61 -> LATIN SMALL LETTER A
+    u'b'        #  0x62 -> LATIN SMALL LETTER B
+    u'c'        #  0x63 -> LATIN SMALL LETTER C
+    u'd'        #  0x64 -> LATIN SMALL LETTER D
+    u'e'        #  0x65 -> LATIN SMALL LETTER E
+    u'f'        #  0x66 -> LATIN SMALL LETTER F
+    u'g'        #  0x67 -> LATIN SMALL LETTER G
+    u'h'        #  0x68 -> LATIN SMALL LETTER H
+    u'i'        #  0x69 -> LATIN SMALL LETTER I
+    u'j'        #  0x6A -> LATIN SMALL LETTER J
+    u'k'        #  0x6B -> LATIN SMALL LETTER K
+    u'l'        #  0x6C -> LATIN SMALL LETTER L
+    u'm'        #  0x6D -> LATIN SMALL LETTER M
+    u'n'        #  0x6E -> LATIN SMALL LETTER N
+    u'o'        #  0x6F -> LATIN SMALL LETTER O
+    u'p'        #  0x70 -> LATIN SMALL LETTER P
+    u'q'        #  0x71 -> LATIN SMALL LETTER Q
+    u'r'        #  0x72 -> LATIN SMALL LETTER R
+    u's'        #  0x73 -> LATIN SMALL LETTER S
+    u't'        #  0x74 -> LATIN SMALL LETTER T
+    u'u'        #  0x75 -> LATIN SMALL LETTER U
+    u'v'        #  0x76 -> LATIN SMALL LETTER V
+    u'w'        #  0x77 -> LATIN SMALL LETTER W
+    u'x'        #  0x78 -> LATIN SMALL LETTER X
+    u'y'        #  0x79 -> LATIN SMALL LETTER Y
+    u'z'        #  0x7A -> LATIN SMALL LETTER Z
+    u'{'        #  0x7B -> LEFT CURLY BRACKET
+    u'|'        #  0x7C -> VERTICAL LINE
+    u'}'        #  0x7D -> RIGHT CURLY BRACKET
+    u'~'        #  0x7E -> TILDE
+    u'\x7f'     #  0x7F -> DELETE
+    u'\x80'     #  0x80 -> <control>
+    u'\x81'     #  0x81 -> <control>
+    u'\x82'     #  0x82 -> <control>
+    u'\x83'     #  0x83 -> <control>
+    u'\x84'     #  0x84 -> <control>
+    u'\x85'     #  0x85 -> <control>
+    u'\x86'     #  0x86 -> <control>
+    u'\x87'     #  0x87 -> <control>
+    u'\x88'     #  0x88 -> <control>
+    u'\x89'     #  0x89 -> <control>
+    u'\x8a'     #  0x8A -> <control>
+    u'\x8b'     #  0x8B -> <control>
+    u'\x8c'     #  0x8C -> <control>
+    u'\x8d'     #  0x8D -> <control>
+    u'\x8e'     #  0x8E -> <control>
+    u'\x8f'     #  0x8F -> <control>
+    u'\x90'     #  0x90 -> <control>
+    u'\x91'     #  0x91 -> <control>
+    u'\x92'     #  0x92 -> <control>
+    u'\x93'     #  0x93 -> <control>
+    u'\x94'     #  0x94 -> <control>
+    u'\x95'     #  0x95 -> <control>
+    u'\x96'     #  0x96 -> <control>
+    u'\x97'     #  0x97 -> <control>
+    u'\x98'     #  0x98 -> <control>
+    u'\x99'     #  0x99 -> <control>
+    u'\x9a'     #  0x9A -> <control>
+    u'\x9b'     #  0x9B -> <control>
+    u'\x9c'     #  0x9C -> <control>
+    u'\x9d'     #  0x9D -> <control>
+    u'\x9e'     #  0x9E -> <control>
+    u'\x9f'     #  0x9F -> <control>
+    u'\xa0'     #  0xA0 -> NO-BREAK SPACE
+    u'\u2018'   #  0xA1 -> LEFT SINGLE QUOTATION MARK
+    u'\u2019'   #  0xA2 -> RIGHT SINGLE QUOTATION MARK
+    u'\xa3'     #  0xA3 -> POUND SIGN
+    u'\u20ac'   #  0xA4 -> EURO SIGN
+    u'\u20af'   #  0xA5 -> DRACHMA SIGN
+    u'\xa6'     #  0xA6 -> BROKEN BAR
+    u'\xa7'     #  0xA7 -> SECTION SIGN
+    u'\xa8'     #  0xA8 -> DIAERESIS
+    u'\xa9'     #  0xA9 -> COPYRIGHT SIGN
+    u'\u037a'   #  0xAA -> GREEK YPOGEGRAMMENI
+    u'\xab'     #  0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xac'     #  0xAC -> NOT SIGN
+    u'\xad'     #  0xAD -> SOFT HYPHEN
+    u'\ufffe'
+    u'\u2015'   #  0xAF -> HORIZONTAL BAR
+    u'\xb0'     #  0xB0 -> DEGREE SIGN
+    u'\xb1'     #  0xB1 -> PLUS-MINUS SIGN
+    u'\xb2'     #  0xB2 -> SUPERSCRIPT TWO
+    u'\xb3'     #  0xB3 -> SUPERSCRIPT THREE
+    u'\u0384'   #  0xB4 -> GREEK TONOS
+    u'\u0385'   #  0xB5 -> GREEK DIALYTIKA TONOS
+    u'\u0386'   #  0xB6 -> GREEK CAPITAL LETTER ALPHA WITH TONOS
+    u'\xb7'     #  0xB7 -> MIDDLE DOT
+    u'\u0388'   #  0xB8 -> GREEK CAPITAL LETTER EPSILON WITH TONOS
+    u'\u0389'   #  0xB9 -> GREEK CAPITAL LETTER ETA WITH TONOS
+    u'\u038a'   #  0xBA -> GREEK CAPITAL LETTER IOTA WITH TONOS
+    u'\xbb'     #  0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\u038c'   #  0xBC -> GREEK CAPITAL LETTER OMICRON WITH TONOS
+    u'\xbd'     #  0xBD -> VULGAR FRACTION ONE HALF
+    u'\u038e'   #  0xBE -> GREEK CAPITAL LETTER UPSILON WITH TONOS
+    u'\u038f'   #  0xBF -> GREEK CAPITAL LETTER OMEGA WITH TONOS
+    u'\u0390'   #  0xC0 -> GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
+    u'\u0391'   #  0xC1 -> GREEK CAPITAL LETTER ALPHA
+    u'\u0392'   #  0xC2 -> GREEK CAPITAL LETTER BETA
+    u'\u0393'   #  0xC3 -> GREEK CAPITAL LETTER GAMMA
+    u'\u0394'   #  0xC4 -> GREEK CAPITAL LETTER DELTA
+    u'\u0395'   #  0xC5 -> GREEK CAPITAL LETTER EPSILON
+    u'\u0396'   #  0xC6 -> GREEK CAPITAL LETTER ZETA
+    u'\u0397'   #  0xC7 -> GREEK CAPITAL LETTER ETA
+    u'\u0398'   #  0xC8 -> GREEK CAPITAL LETTER THETA
+    u'\u0399'   #  0xC9 -> GREEK CAPITAL LETTER IOTA
+    u'\u039a'   #  0xCA -> GREEK CAPITAL LETTER KAPPA
+    u'\u039b'   #  0xCB -> GREEK CAPITAL LETTER LAMDA
+    u'\u039c'   #  0xCC -> GREEK CAPITAL LETTER MU
+    u'\u039d'   #  0xCD -> GREEK CAPITAL LETTER NU
+    u'\u039e'   #  0xCE -> GREEK CAPITAL LETTER XI
+    u'\u039f'   #  0xCF -> GREEK CAPITAL LETTER OMICRON
+    u'\u03a0'   #  0xD0 -> GREEK CAPITAL LETTER PI
+    u'\u03a1'   #  0xD1 -> GREEK CAPITAL LETTER RHO
+    u'\ufffe'
+    u'\u03a3'   #  0xD3 -> GREEK CAPITAL LETTER SIGMA
+    u'\u03a4'   #  0xD4 -> GREEK CAPITAL LETTER TAU
+    u'\u03a5'   #  0xD5 -> GREEK CAPITAL LETTER UPSILON
+    u'\u03a6'   #  0xD6 -> GREEK CAPITAL LETTER PHI
+    u'\u03a7'   #  0xD7 -> GREEK CAPITAL LETTER CHI
+    u'\u03a8'   #  0xD8 -> GREEK CAPITAL LETTER PSI
+    u'\u03a9'   #  0xD9 -> GREEK CAPITAL LETTER OMEGA
+    u'\u03aa'   #  0xDA -> GREEK CAPITAL LETTER IOTA WITH DIALYTIKA
+    u'\u03ab'   #  0xDB -> GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA
+    u'\u03ac'   #  0xDC -> GREEK SMALL LETTER ALPHA WITH TONOS
+    u'\u03ad'   #  0xDD -> GREEK SMALL LETTER EPSILON WITH TONOS
+    u'\u03ae'   #  0xDE -> GREEK SMALL LETTER ETA WITH TONOS
+    u'\u03af'   #  0xDF -> GREEK SMALL LETTER IOTA WITH TONOS
+    u'\u03b0'   #  0xE0 -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS
+    u'\u03b1'   #  0xE1 -> GREEK SMALL LETTER ALPHA
+    u'\u03b2'   #  0xE2 -> GREEK SMALL LETTER BETA
+    u'\u03b3'   #  0xE3 -> GREEK SMALL LETTER GAMMA
+    u'\u03b4'   #  0xE4 -> GREEK SMALL LETTER DELTA
+    u'\u03b5'   #  0xE5 -> GREEK SMALL LETTER EPSILON
+    u'\u03b6'   #  0xE6 -> GREEK SMALL LETTER ZETA
+    u'\u03b7'   #  0xE7 -> GREEK SMALL LETTER ETA
+    u'\u03b8'   #  0xE8 -> GREEK SMALL LETTER THETA
+    u'\u03b9'   #  0xE9 -> GREEK SMALL LETTER IOTA
+    u'\u03ba'   #  0xEA -> GREEK SMALL LETTER KAPPA
+    u'\u03bb'   #  0xEB -> GREEK SMALL LETTER LAMDA
+    u'\u03bc'   #  0xEC -> GREEK SMALL LETTER MU
+    u'\u03bd'   #  0xED -> GREEK SMALL LETTER NU
+    u'\u03be'   #  0xEE -> GREEK SMALL LETTER XI
+    u'\u03bf'   #  0xEF -> GREEK SMALL LETTER OMICRON
+    u'\u03c0'   #  0xF0 -> GREEK SMALL LETTER PI
+    u'\u03c1'   #  0xF1 -> GREEK SMALL LETTER RHO
+    u'\u03c2'   #  0xF2 -> GREEK SMALL LETTER FINAL SIGMA
+    u'\u03c3'   #  0xF3 -> GREEK SMALL LETTER SIGMA
+    u'\u03c4'   #  0xF4 -> GREEK SMALL LETTER TAU
+    u'\u03c5'   #  0xF5 -> GREEK SMALL LETTER UPSILON
+    u'\u03c6'   #  0xF6 -> GREEK SMALL LETTER PHI
+    u'\u03c7'   #  0xF7 -> GREEK SMALL LETTER CHI
+    u'\u03c8'   #  0xF8 -> GREEK SMALL LETTER PSI
+    u'\u03c9'   #  0xF9 -> GREEK SMALL LETTER OMEGA
+    u'\u03ca'   #  0xFA -> GREEK SMALL LETTER IOTA WITH DIALYTIKA
+    u'\u03cb'   #  0xFB -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA
+    u'\u03cc'   #  0xFC -> GREEK SMALL LETTER OMICRON WITH TONOS
+    u'\u03cd'   #  0xFD -> GREEK SMALL LETTER UPSILON WITH TONOS
+    u'\u03ce'   #  0xFE -> GREEK SMALL LETTER OMEGA WITH TONOS
+    u'\ufffe'
+)
+
+### Encoding table
+encoding_table=codecs.charmap_build(decoding_table)

Added: vendor/Python/current/Lib/encodings/iso8859_8.py
===================================================================
--- vendor/Python/current/Lib/encodings/iso8859_8.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/iso8859_8.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,307 @@
+""" Python Character Mapping Codec iso8859_8 generated from 'MAPPINGS/ISO8859/8859-8.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_table)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_table)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='iso8859-8',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x00 -> NULL
+    u'\x01'     #  0x01 -> START OF HEADING
+    u'\x02'     #  0x02 -> START OF TEXT
+    u'\x03'     #  0x03 -> END OF TEXT
+    u'\x04'     #  0x04 -> END OF TRANSMISSION
+    u'\x05'     #  0x05 -> ENQUIRY
+    u'\x06'     #  0x06 -> ACKNOWLEDGE
+    u'\x07'     #  0x07 -> BELL
+    u'\x08'     #  0x08 -> BACKSPACE
+    u'\t'       #  0x09 -> HORIZONTAL TABULATION
+    u'\n'       #  0x0A -> LINE FEED
+    u'\x0b'     #  0x0B -> VERTICAL TABULATION
+    u'\x0c'     #  0x0C -> FORM FEED
+    u'\r'       #  0x0D -> CARRIAGE RETURN
+    u'\x0e'     #  0x0E -> SHIFT OUT
+    u'\x0f'     #  0x0F -> SHIFT IN
+    u'\x10'     #  0x10 -> DATA LINK ESCAPE
+    u'\x11'     #  0x11 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x12 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x13 -> DEVICE CONTROL THREE
+    u'\x14'     #  0x14 -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x15 -> NEGATIVE ACKNOWLEDGE
+    u'\x16'     #  0x16 -> SYNCHRONOUS IDLE
+    u'\x17'     #  0x17 -> END OF TRANSMISSION BLOCK
+    u'\x18'     #  0x18 -> CANCEL
+    u'\x19'     #  0x19 -> END OF MEDIUM
+    u'\x1a'     #  0x1A -> SUBSTITUTE
+    u'\x1b'     #  0x1B -> ESCAPE
+    u'\x1c'     #  0x1C -> FILE SEPARATOR
+    u'\x1d'     #  0x1D -> GROUP SEPARATOR
+    u'\x1e'     #  0x1E -> RECORD SEPARATOR
+    u'\x1f'     #  0x1F -> UNIT SEPARATOR
+    u' '        #  0x20 -> SPACE
+    u'!'        #  0x21 -> EXCLAMATION MARK
+    u'"'        #  0x22 -> QUOTATION MARK
+    u'#'        #  0x23 -> NUMBER SIGN
+    u'$'        #  0x24 -> DOLLAR SIGN
+    u'%'        #  0x25 -> PERCENT SIGN
+    u'&'        #  0x26 -> AMPERSAND
+    u"'"        #  0x27 -> APOSTROPHE
+    u'('        #  0x28 -> LEFT PARENTHESIS
+    u')'        #  0x29 -> RIGHT PARENTHESIS
+    u'*'        #  0x2A -> ASTERISK
+    u'+'        #  0x2B -> PLUS SIGN
+    u','        #  0x2C -> COMMA
+    u'-'        #  0x2D -> HYPHEN-MINUS
+    u'.'        #  0x2E -> FULL STOP
+    u'/'        #  0x2F -> SOLIDUS
+    u'0'        #  0x30 -> DIGIT ZERO
+    u'1'        #  0x31 -> DIGIT ONE
+    u'2'        #  0x32 -> DIGIT TWO
+    u'3'        #  0x33 -> DIGIT THREE
+    u'4'        #  0x34 -> DIGIT FOUR
+    u'5'        #  0x35 -> DIGIT FIVE
+    u'6'        #  0x36 -> DIGIT SIX
+    u'7'        #  0x37 -> DIGIT SEVEN
+    u'8'        #  0x38 -> DIGIT EIGHT
+    u'9'        #  0x39 -> DIGIT NINE
+    u':'        #  0x3A -> COLON
+    u';'        #  0x3B -> SEMICOLON
+    u'<'        #  0x3C -> LESS-THAN SIGN
+    u'='        #  0x3D -> EQUALS SIGN
+    u'>'        #  0x3E -> GREATER-THAN SIGN
+    u'?'        #  0x3F -> QUESTION MARK
+    u'@'        #  0x40 -> COMMERCIAL AT
+    u'A'        #  0x41 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x42 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x43 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x44 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x45 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x46 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x47 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x48 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x49 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x4A -> LATIN CAPITAL LETTER J
+    u'K'        #  0x4B -> LATIN CAPITAL LETTER K
+    u'L'        #  0x4C -> LATIN CAPITAL LETTER L
+    u'M'        #  0x4D -> LATIN CAPITAL LETTER M
+    u'N'        #  0x4E -> LATIN CAPITAL LETTER N
+    u'O'        #  0x4F -> LATIN CAPITAL LETTER O
+    u'P'        #  0x50 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x51 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x52 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x53 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x54 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x55 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x56 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x57 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x58 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x59 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x5A -> LATIN CAPITAL LETTER Z
+    u'['        #  0x5B -> LEFT SQUARE BRACKET
+    u'\\'       #  0x5C -> REVERSE SOLIDUS
+    u']'        #  0x5D -> RIGHT SQUARE BRACKET
+    u'^'        #  0x5E -> CIRCUMFLEX ACCENT
+    u'_'        #  0x5F -> LOW LINE
+    u'`'        #  0x60 -> GRAVE ACCENT
+    u'a'        #  0x61 -> LATIN SMALL LETTER A
+    u'b'        #  0x62 -> LATIN SMALL LETTER B
+    u'c'        #  0x63 -> LATIN SMALL LETTER C
+    u'd'        #  0x64 -> LATIN SMALL LETTER D
+    u'e'        #  0x65 -> LATIN SMALL LETTER E
+    u'f'        #  0x66 -> LATIN SMALL LETTER F
+    u'g'        #  0x67 -> LATIN SMALL LETTER G
+    u'h'        #  0x68 -> LATIN SMALL LETTER H
+    u'i'        #  0x69 -> LATIN SMALL LETTER I
+    u'j'        #  0x6A -> LATIN SMALL LETTER J
+    u'k'        #  0x6B -> LATIN SMALL LETTER K
+    u'l'        #  0x6C -> LATIN SMALL LETTER L
+    u'm'        #  0x6D -> LATIN SMALL LETTER M
+    u'n'        #  0x6E -> LATIN SMALL LETTER N
+    u'o'        #  0x6F -> LATIN SMALL LETTER O
+    u'p'        #  0x70 -> LATIN SMALL LETTER P
+    u'q'        #  0x71 -> LATIN SMALL LETTER Q
+    u'r'        #  0x72 -> LATIN SMALL LETTER R
+    u's'        #  0x73 -> LATIN SMALL LETTER S
+    u't'        #  0x74 -> LATIN SMALL LETTER T
+    u'u'        #  0x75 -> LATIN SMALL LETTER U
+    u'v'        #  0x76 -> LATIN SMALL LETTER V
+    u'w'        #  0x77 -> LATIN SMALL LETTER W
+    u'x'        #  0x78 -> LATIN SMALL LETTER X
+    u'y'        #  0x79 -> LATIN SMALL LETTER Y
+    u'z'        #  0x7A -> LATIN SMALL LETTER Z
+    u'{'        #  0x7B -> LEFT CURLY BRACKET
+    u'|'        #  0x7C -> VERTICAL LINE
+    u'}'        #  0x7D -> RIGHT CURLY BRACKET
+    u'~'        #  0x7E -> TILDE
+    u'\x7f'     #  0x7F -> DELETE
+    u'\x80'     #  0x80 -> <control>
+    u'\x81'     #  0x81 -> <control>
+    u'\x82'     #  0x82 -> <control>
+    u'\x83'     #  0x83 -> <control>
+    u'\x84'     #  0x84 -> <control>
+    u'\x85'     #  0x85 -> <control>
+    u'\x86'     #  0x86 -> <control>
+    u'\x87'     #  0x87 -> <control>
+    u'\x88'     #  0x88 -> <control>
+    u'\x89'     #  0x89 -> <control>
+    u'\x8a'     #  0x8A -> <control>
+    u'\x8b'     #  0x8B -> <control>
+    u'\x8c'     #  0x8C -> <control>
+    u'\x8d'     #  0x8D -> <control>
+    u'\x8e'     #  0x8E -> <control>
+    u'\x8f'     #  0x8F -> <control>
+    u'\x90'     #  0x90 -> <control>
+    u'\x91'     #  0x91 -> <control>
+    u'\x92'     #  0x92 -> <control>
+    u'\x93'     #  0x93 -> <control>
+    u'\x94'     #  0x94 -> <control>
+    u'\x95'     #  0x95 -> <control>
+    u'\x96'     #  0x96 -> <control>
+    u'\x97'     #  0x97 -> <control>
+    u'\x98'     #  0x98 -> <control>
+    u'\x99'     #  0x99 -> <control>
+    u'\x9a'     #  0x9A -> <control>
+    u'\x9b'     #  0x9B -> <control>
+    u'\x9c'     #  0x9C -> <control>
+    u'\x9d'     #  0x9D -> <control>
+    u'\x9e'     #  0x9E -> <control>
+    u'\x9f'     #  0x9F -> <control>
+    u'\xa0'     #  0xA0 -> NO-BREAK SPACE
+    u'\ufffe'
+    u'\xa2'     #  0xA2 -> CENT SIGN
+    u'\xa3'     #  0xA3 -> POUND SIGN
+    u'\xa4'     #  0xA4 -> CURRENCY SIGN
+    u'\xa5'     #  0xA5 -> YEN SIGN
+    u'\xa6'     #  0xA6 -> BROKEN BAR
+    u'\xa7'     #  0xA7 -> SECTION SIGN
+    u'\xa8'     #  0xA8 -> DIAERESIS
+    u'\xa9'     #  0xA9 -> COPYRIGHT SIGN
+    u'\xd7'     #  0xAA -> MULTIPLICATION SIGN
+    u'\xab'     #  0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xac'     #  0xAC -> NOT SIGN
+    u'\xad'     #  0xAD -> SOFT HYPHEN
+    u'\xae'     #  0xAE -> REGISTERED SIGN
+    u'\xaf'     #  0xAF -> MACRON
+    u'\xb0'     #  0xB0 -> DEGREE SIGN
+    u'\xb1'     #  0xB1 -> PLUS-MINUS SIGN
+    u'\xb2'     #  0xB2 -> SUPERSCRIPT TWO
+    u'\xb3'     #  0xB3 -> SUPERSCRIPT THREE
+    u'\xb4'     #  0xB4 -> ACUTE ACCENT
+    u'\xb5'     #  0xB5 -> MICRO SIGN
+    u'\xb6'     #  0xB6 -> PILCROW SIGN
+    u'\xb7'     #  0xB7 -> MIDDLE DOT
+    u'\xb8'     #  0xB8 -> CEDILLA
+    u'\xb9'     #  0xB9 -> SUPERSCRIPT ONE
+    u'\xf7'     #  0xBA -> DIVISION SIGN
+    u'\xbb'     #  0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xbc'     #  0xBC -> VULGAR FRACTION ONE QUARTER
+    u'\xbd'     #  0xBD -> VULGAR FRACTION ONE HALF
+    u'\xbe'     #  0xBE -> VULGAR FRACTION THREE QUARTERS
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\u2017'   #  0xDF -> DOUBLE LOW LINE
+    u'\u05d0'   #  0xE0 -> HEBREW LETTER ALEF
+    u'\u05d1'   #  0xE1 -> HEBREW LETTER BET
+    u'\u05d2'   #  0xE2 -> HEBREW LETTER GIMEL
+    u'\u05d3'   #  0xE3 -> HEBREW LETTER DALET
+    u'\u05d4'   #  0xE4 -> HEBREW LETTER HE
+    u'\u05d5'   #  0xE5 -> HEBREW LETTER VAV
+    u'\u05d6'   #  0xE6 -> HEBREW LETTER ZAYIN
+    u'\u05d7'   #  0xE7 -> HEBREW LETTER HET
+    u'\u05d8'   #  0xE8 -> HEBREW LETTER TET
+    u'\u05d9'   #  0xE9 -> HEBREW LETTER YOD
+    u'\u05da'   #  0xEA -> HEBREW LETTER FINAL KAF
+    u'\u05db'   #  0xEB -> HEBREW LETTER KAF
+    u'\u05dc'   #  0xEC -> HEBREW LETTER LAMED
+    u'\u05dd'   #  0xED -> HEBREW LETTER FINAL MEM
+    u'\u05de'   #  0xEE -> HEBREW LETTER MEM
+    u'\u05df'   #  0xEF -> HEBREW LETTER FINAL NUN
+    u'\u05e0'   #  0xF0 -> HEBREW LETTER NUN
+    u'\u05e1'   #  0xF1 -> HEBREW LETTER SAMEKH
+    u'\u05e2'   #  0xF2 -> HEBREW LETTER AYIN
+    u'\u05e3'   #  0xF3 -> HEBREW LETTER FINAL PE
+    u'\u05e4'   #  0xF4 -> HEBREW LETTER PE
+    u'\u05e5'   #  0xF5 -> HEBREW LETTER FINAL TSADI
+    u'\u05e6'   #  0xF6 -> HEBREW LETTER TSADI
+    u'\u05e7'   #  0xF7 -> HEBREW LETTER QOF
+    u'\u05e8'   #  0xF8 -> HEBREW LETTER RESH
+    u'\u05e9'   #  0xF9 -> HEBREW LETTER SHIN
+    u'\u05ea'   #  0xFA -> HEBREW LETTER TAV
+    u'\ufffe'
+    u'\ufffe'
+    u'\u200e'   #  0xFD -> LEFT-TO-RIGHT MARK
+    u'\u200f'   #  0xFE -> RIGHT-TO-LEFT MARK
+    u'\ufffe'
+)
+
+### Encoding table
+encoding_table=codecs.charmap_build(decoding_table)

Added: vendor/Python/current/Lib/encodings/iso8859_9.py
===================================================================
--- vendor/Python/current/Lib/encodings/iso8859_9.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/iso8859_9.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,307 @@
+""" Python Character Mapping Codec iso8859_9 generated from 'MAPPINGS/ISO8859/8859-9.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_table)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_table)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='iso8859-9',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x00 -> NULL
+    u'\x01'     #  0x01 -> START OF HEADING
+    u'\x02'     #  0x02 -> START OF TEXT
+    u'\x03'     #  0x03 -> END OF TEXT
+    u'\x04'     #  0x04 -> END OF TRANSMISSION
+    u'\x05'     #  0x05 -> ENQUIRY
+    u'\x06'     #  0x06 -> ACKNOWLEDGE
+    u'\x07'     #  0x07 -> BELL
+    u'\x08'     #  0x08 -> BACKSPACE
+    u'\t'       #  0x09 -> HORIZONTAL TABULATION
+    u'\n'       #  0x0A -> LINE FEED
+    u'\x0b'     #  0x0B -> VERTICAL TABULATION
+    u'\x0c'     #  0x0C -> FORM FEED
+    u'\r'       #  0x0D -> CARRIAGE RETURN
+    u'\x0e'     #  0x0E -> SHIFT OUT
+    u'\x0f'     #  0x0F -> SHIFT IN
+    u'\x10'     #  0x10 -> DATA LINK ESCAPE
+    u'\x11'     #  0x11 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x12 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x13 -> DEVICE CONTROL THREE
+    u'\x14'     #  0x14 -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x15 -> NEGATIVE ACKNOWLEDGE
+    u'\x16'     #  0x16 -> SYNCHRONOUS IDLE
+    u'\x17'     #  0x17 -> END OF TRANSMISSION BLOCK
+    u'\x18'     #  0x18 -> CANCEL
+    u'\x19'     #  0x19 -> END OF MEDIUM
+    u'\x1a'     #  0x1A -> SUBSTITUTE
+    u'\x1b'     #  0x1B -> ESCAPE
+    u'\x1c'     #  0x1C -> FILE SEPARATOR
+    u'\x1d'     #  0x1D -> GROUP SEPARATOR
+    u'\x1e'     #  0x1E -> RECORD SEPARATOR
+    u'\x1f'     #  0x1F -> UNIT SEPARATOR
+    u' '        #  0x20 -> SPACE
+    u'!'        #  0x21 -> EXCLAMATION MARK
+    u'"'        #  0x22 -> QUOTATION MARK
+    u'#'        #  0x23 -> NUMBER SIGN
+    u'$'        #  0x24 -> DOLLAR SIGN
+    u'%'        #  0x25 -> PERCENT SIGN
+    u'&'        #  0x26 -> AMPERSAND
+    u"'"        #  0x27 -> APOSTROPHE
+    u'('        #  0x28 -> LEFT PARENTHESIS
+    u')'        #  0x29 -> RIGHT PARENTHESIS
+    u'*'        #  0x2A -> ASTERISK
+    u'+'        #  0x2B -> PLUS SIGN
+    u','        #  0x2C -> COMMA
+    u'-'        #  0x2D -> HYPHEN-MINUS
+    u'.'        #  0x2E -> FULL STOP
+    u'/'        #  0x2F -> SOLIDUS
+    u'0'        #  0x30 -> DIGIT ZERO
+    u'1'        #  0x31 -> DIGIT ONE
+    u'2'        #  0x32 -> DIGIT TWO
+    u'3'        #  0x33 -> DIGIT THREE
+    u'4'        #  0x34 -> DIGIT FOUR
+    u'5'        #  0x35 -> DIGIT FIVE
+    u'6'        #  0x36 -> DIGIT SIX
+    u'7'        #  0x37 -> DIGIT SEVEN
+    u'8'        #  0x38 -> DIGIT EIGHT
+    u'9'        #  0x39 -> DIGIT NINE
+    u':'        #  0x3A -> COLON
+    u';'        #  0x3B -> SEMICOLON
+    u'<'        #  0x3C -> LESS-THAN SIGN
+    u'='        #  0x3D -> EQUALS SIGN
+    u'>'        #  0x3E -> GREATER-THAN SIGN
+    u'?'        #  0x3F -> QUESTION MARK
+    u'@'        #  0x40 -> COMMERCIAL AT
+    u'A'        #  0x41 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x42 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x43 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x44 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x45 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x46 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x47 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x48 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x49 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x4A -> LATIN CAPITAL LETTER J
+    u'K'        #  0x4B -> LATIN CAPITAL LETTER K
+    u'L'        #  0x4C -> LATIN CAPITAL LETTER L
+    u'M'        #  0x4D -> LATIN CAPITAL LETTER M
+    u'N'        #  0x4E -> LATIN CAPITAL LETTER N
+    u'O'        #  0x4F -> LATIN CAPITAL LETTER O
+    u'P'        #  0x50 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x51 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x52 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x53 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x54 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x55 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x56 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x57 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x58 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x59 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x5A -> LATIN CAPITAL LETTER Z
+    u'['        #  0x5B -> LEFT SQUARE BRACKET
+    u'\\'       #  0x5C -> REVERSE SOLIDUS
+    u']'        #  0x5D -> RIGHT SQUARE BRACKET
+    u'^'        #  0x5E -> CIRCUMFLEX ACCENT
+    u'_'        #  0x5F -> LOW LINE
+    u'`'        #  0x60 -> GRAVE ACCENT
+    u'a'        #  0x61 -> LATIN SMALL LETTER A
+    u'b'        #  0x62 -> LATIN SMALL LETTER B
+    u'c'        #  0x63 -> LATIN SMALL LETTER C
+    u'd'        #  0x64 -> LATIN SMALL LETTER D
+    u'e'        #  0x65 -> LATIN SMALL LETTER E
+    u'f'        #  0x66 -> LATIN SMALL LETTER F
+    u'g'        #  0x67 -> LATIN SMALL LETTER G
+    u'h'        #  0x68 -> LATIN SMALL LETTER H
+    u'i'        #  0x69 -> LATIN SMALL LETTER I
+    u'j'        #  0x6A -> LATIN SMALL LETTER J
+    u'k'        #  0x6B -> LATIN SMALL LETTER K
+    u'l'        #  0x6C -> LATIN SMALL LETTER L
+    u'm'        #  0x6D -> LATIN SMALL LETTER M
+    u'n'        #  0x6E -> LATIN SMALL LETTER N
+    u'o'        #  0x6F -> LATIN SMALL LETTER O
+    u'p'        #  0x70 -> LATIN SMALL LETTER P
+    u'q'        #  0x71 -> LATIN SMALL LETTER Q
+    u'r'        #  0x72 -> LATIN SMALL LETTER R
+    u's'        #  0x73 -> LATIN SMALL LETTER S
+    u't'        #  0x74 -> LATIN SMALL LETTER T
+    u'u'        #  0x75 -> LATIN SMALL LETTER U
+    u'v'        #  0x76 -> LATIN SMALL LETTER V
+    u'w'        #  0x77 -> LATIN SMALL LETTER W
+    u'x'        #  0x78 -> LATIN SMALL LETTER X
+    u'y'        #  0x79 -> LATIN SMALL LETTER Y
+    u'z'        #  0x7A -> LATIN SMALL LETTER Z
+    u'{'        #  0x7B -> LEFT CURLY BRACKET
+    u'|'        #  0x7C -> VERTICAL LINE
+    u'}'        #  0x7D -> RIGHT CURLY BRACKET
+    u'~'        #  0x7E -> TILDE
+    u'\x7f'     #  0x7F -> DELETE
+    u'\x80'     #  0x80 -> <control>
+    u'\x81'     #  0x81 -> <control>
+    u'\x82'     #  0x82 -> <control>
+    u'\x83'     #  0x83 -> <control>
+    u'\x84'     #  0x84 -> <control>
+    u'\x85'     #  0x85 -> <control>
+    u'\x86'     #  0x86 -> <control>
+    u'\x87'     #  0x87 -> <control>
+    u'\x88'     #  0x88 -> <control>
+    u'\x89'     #  0x89 -> <control>
+    u'\x8a'     #  0x8A -> <control>
+    u'\x8b'     #  0x8B -> <control>
+    u'\x8c'     #  0x8C -> <control>
+    u'\x8d'     #  0x8D -> <control>
+    u'\x8e'     #  0x8E -> <control>
+    u'\x8f'     #  0x8F -> <control>
+    u'\x90'     #  0x90 -> <control>
+    u'\x91'     #  0x91 -> <control>
+    u'\x92'     #  0x92 -> <control>
+    u'\x93'     #  0x93 -> <control>
+    u'\x94'     #  0x94 -> <control>
+    u'\x95'     #  0x95 -> <control>
+    u'\x96'     #  0x96 -> <control>
+    u'\x97'     #  0x97 -> <control>
+    u'\x98'     #  0x98 -> <control>
+    u'\x99'     #  0x99 -> <control>
+    u'\x9a'     #  0x9A -> <control>
+    u'\x9b'     #  0x9B -> <control>
+    u'\x9c'     #  0x9C -> <control>
+    u'\x9d'     #  0x9D -> <control>
+    u'\x9e'     #  0x9E -> <control>
+    u'\x9f'     #  0x9F -> <control>
+    u'\xa0'     #  0xA0 -> NO-BREAK SPACE
+    u'\xa1'     #  0xA1 -> INVERTED EXCLAMATION MARK
+    u'\xa2'     #  0xA2 -> CENT SIGN
+    u'\xa3'     #  0xA3 -> POUND SIGN
+    u'\xa4'     #  0xA4 -> CURRENCY SIGN
+    u'\xa5'     #  0xA5 -> YEN SIGN
+    u'\xa6'     #  0xA6 -> BROKEN BAR
+    u'\xa7'     #  0xA7 -> SECTION SIGN
+    u'\xa8'     #  0xA8 -> DIAERESIS
+    u'\xa9'     #  0xA9 -> COPYRIGHT SIGN
+    u'\xaa'     #  0xAA -> FEMININE ORDINAL INDICATOR
+    u'\xab'     #  0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xac'     #  0xAC -> NOT SIGN
+    u'\xad'     #  0xAD -> SOFT HYPHEN
+    u'\xae'     #  0xAE -> REGISTERED SIGN
+    u'\xaf'     #  0xAF -> MACRON
+    u'\xb0'     #  0xB0 -> DEGREE SIGN
+    u'\xb1'     #  0xB1 -> PLUS-MINUS SIGN
+    u'\xb2'     #  0xB2 -> SUPERSCRIPT TWO
+    u'\xb3'     #  0xB3 -> SUPERSCRIPT THREE
+    u'\xb4'     #  0xB4 -> ACUTE ACCENT
+    u'\xb5'     #  0xB5 -> MICRO SIGN
+    u'\xb6'     #  0xB6 -> PILCROW SIGN
+    u'\xb7'     #  0xB7 -> MIDDLE DOT
+    u'\xb8'     #  0xB8 -> CEDILLA
+    u'\xb9'     #  0xB9 -> SUPERSCRIPT ONE
+    u'\xba'     #  0xBA -> MASCULINE ORDINAL INDICATOR
+    u'\xbb'     #  0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xbc'     #  0xBC -> VULGAR FRACTION ONE QUARTER
+    u'\xbd'     #  0xBD -> VULGAR FRACTION ONE HALF
+    u'\xbe'     #  0xBE -> VULGAR FRACTION THREE QUARTERS
+    u'\xbf'     #  0xBF -> INVERTED QUESTION MARK
+    u'\xc0'     #  0xC0 -> LATIN CAPITAL LETTER A WITH GRAVE
+    u'\xc1'     #  0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE
+    u'\xc2'     #  0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+    u'\xc3'     #  0xC3 -> LATIN CAPITAL LETTER A WITH TILDE
+    u'\xc4'     #  0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS
+    u'\xc5'     #  0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE
+    u'\xc6'     #  0xC6 -> LATIN CAPITAL LETTER AE
+    u'\xc7'     #  0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA
+    u'\xc8'     #  0xC8 -> LATIN CAPITAL LETTER E WITH GRAVE
+    u'\xc9'     #  0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE
+    u'\xca'     #  0xCA -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+    u'\xcb'     #  0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS
+    u'\xcc'     #  0xCC -> LATIN CAPITAL LETTER I WITH GRAVE
+    u'\xcd'     #  0xCD -> LATIN CAPITAL LETTER I WITH ACUTE
+    u'\xce'     #  0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+    u'\xcf'     #  0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS
+    u'\u011e'   #  0xD0 -> LATIN CAPITAL LETTER G WITH BREVE
+    u'\xd1'     #  0xD1 -> LATIN CAPITAL LETTER N WITH TILDE
+    u'\xd2'     #  0xD2 -> LATIN CAPITAL LETTER O WITH GRAVE
+    u'\xd3'     #  0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE
+    u'\xd4'     #  0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+    u'\xd5'     #  0xD5 -> LATIN CAPITAL LETTER O WITH TILDE
+    u'\xd6'     #  0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS
+    u'\xd7'     #  0xD7 -> MULTIPLICATION SIGN
+    u'\xd8'     #  0xD8 -> LATIN CAPITAL LETTER O WITH STROKE
+    u'\xd9'     #  0xD9 -> LATIN CAPITAL LETTER U WITH GRAVE
+    u'\xda'     #  0xDA -> LATIN CAPITAL LETTER U WITH ACUTE
+    u'\xdb'     #  0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+    u'\xdc'     #  0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS
+    u'\u0130'   #  0xDD -> LATIN CAPITAL LETTER I WITH DOT ABOVE
+    u'\u015e'   #  0xDE -> LATIN CAPITAL LETTER S WITH CEDILLA
+    u'\xdf'     #  0xDF -> LATIN SMALL LETTER SHARP S
+    u'\xe0'     #  0xE0 -> LATIN SMALL LETTER A WITH GRAVE
+    u'\xe1'     #  0xE1 -> LATIN SMALL LETTER A WITH ACUTE
+    u'\xe2'     #  0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX
+    u'\xe3'     #  0xE3 -> LATIN SMALL LETTER A WITH TILDE
+    u'\xe4'     #  0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS
+    u'\xe5'     #  0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE
+    u'\xe6'     #  0xE6 -> LATIN SMALL LETTER AE
+    u'\xe7'     #  0xE7 -> LATIN SMALL LETTER C WITH CEDILLA
+    u'\xe8'     #  0xE8 -> LATIN SMALL LETTER E WITH GRAVE
+    u'\xe9'     #  0xE9 -> LATIN SMALL LETTER E WITH ACUTE
+    u'\xea'     #  0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX
+    u'\xeb'     #  0xEB -> LATIN SMALL LETTER E WITH DIAERESIS
+    u'\xec'     #  0xEC -> LATIN SMALL LETTER I WITH GRAVE
+    u'\xed'     #  0xED -> LATIN SMALL LETTER I WITH ACUTE
+    u'\xee'     #  0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX
+    u'\xef'     #  0xEF -> LATIN SMALL LETTER I WITH DIAERESIS
+    u'\u011f'   #  0xF0 -> LATIN SMALL LETTER G WITH BREVE
+    u'\xf1'     #  0xF1 -> LATIN SMALL LETTER N WITH TILDE
+    u'\xf2'     #  0xF2 -> LATIN SMALL LETTER O WITH GRAVE
+    u'\xf3'     #  0xF3 -> LATIN SMALL LETTER O WITH ACUTE
+    u'\xf4'     #  0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX
+    u'\xf5'     #  0xF5 -> LATIN SMALL LETTER O WITH TILDE
+    u'\xf6'     #  0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS
+    u'\xf7'     #  0xF7 -> DIVISION SIGN
+    u'\xf8'     #  0xF8 -> LATIN SMALL LETTER O WITH STROKE
+    u'\xf9'     #  0xF9 -> LATIN SMALL LETTER U WITH GRAVE
+    u'\xfa'     #  0xFA -> LATIN SMALL LETTER U WITH ACUTE
+    u'\xfb'     #  0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX
+    u'\xfc'     #  0xFC -> LATIN SMALL LETTER U WITH DIAERESIS
+    u'\u0131'   #  0xFD -> LATIN SMALL LETTER DOTLESS I
+    u'\u015f'   #  0xFE -> LATIN SMALL LETTER S WITH CEDILLA
+    u'\xff'     #  0xFF -> LATIN SMALL LETTER Y WITH DIAERESIS
+)
+
+### Encoding table
+encoding_table=codecs.charmap_build(decoding_table)

Added: vendor/Python/current/Lib/encodings/johab.py
===================================================================
--- vendor/Python/current/Lib/encodings/johab.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/johab.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,39 @@
+#
+# johab.py: Python Unicode Codec for JOHAB
+#
+# Written by Hye-Shik Chang <perky at FreeBSD.org>
+#
+
+import _codecs_kr, codecs
+import _multibytecodec as mbc
+
+codec = _codecs_kr.getcodec('johab')
+
+class Codec(codecs.Codec):
+    encode = codec.encode
+    decode = codec.decode
+
+class IncrementalEncoder(mbc.MultibyteIncrementalEncoder,
+                         codecs.IncrementalEncoder):
+    codec = codec
+
+class IncrementalDecoder(mbc.MultibyteIncrementalDecoder,
+                         codecs.IncrementalDecoder):
+    codec = codec
+
+class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader):
+    codec = codec
+
+class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter):
+    codec = codec
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='johab',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )

Added: vendor/Python/current/Lib/encodings/koi8_r.py
===================================================================
--- vendor/Python/current/Lib/encodings/koi8_r.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/koi8_r.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,307 @@
+""" Python Character Mapping Codec koi8_r generated from 'MAPPINGS/VENDORS/MISC/KOI8-R.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_table)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_table)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='koi8-r',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x00 -> NULL
+    u'\x01'     #  0x01 -> START OF HEADING
+    u'\x02'     #  0x02 -> START OF TEXT
+    u'\x03'     #  0x03 -> END OF TEXT
+    u'\x04'     #  0x04 -> END OF TRANSMISSION
+    u'\x05'     #  0x05 -> ENQUIRY
+    u'\x06'     #  0x06 -> ACKNOWLEDGE
+    u'\x07'     #  0x07 -> BELL
+    u'\x08'     #  0x08 -> BACKSPACE
+    u'\t'       #  0x09 -> HORIZONTAL TABULATION
+    u'\n'       #  0x0A -> LINE FEED
+    u'\x0b'     #  0x0B -> VERTICAL TABULATION
+    u'\x0c'     #  0x0C -> FORM FEED
+    u'\r'       #  0x0D -> CARRIAGE RETURN
+    u'\x0e'     #  0x0E -> SHIFT OUT
+    u'\x0f'     #  0x0F -> SHIFT IN
+    u'\x10'     #  0x10 -> DATA LINK ESCAPE
+    u'\x11'     #  0x11 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x12 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x13 -> DEVICE CONTROL THREE
+    u'\x14'     #  0x14 -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x15 -> NEGATIVE ACKNOWLEDGE
+    u'\x16'     #  0x16 -> SYNCHRONOUS IDLE
+    u'\x17'     #  0x17 -> END OF TRANSMISSION BLOCK
+    u'\x18'     #  0x18 -> CANCEL
+    u'\x19'     #  0x19 -> END OF MEDIUM
+    u'\x1a'     #  0x1A -> SUBSTITUTE
+    u'\x1b'     #  0x1B -> ESCAPE
+    u'\x1c'     #  0x1C -> FILE SEPARATOR
+    u'\x1d'     #  0x1D -> GROUP SEPARATOR
+    u'\x1e'     #  0x1E -> RECORD SEPARATOR
+    u'\x1f'     #  0x1F -> UNIT SEPARATOR
+    u' '        #  0x20 -> SPACE
+    u'!'        #  0x21 -> EXCLAMATION MARK
+    u'"'        #  0x22 -> QUOTATION MARK
+    u'#'        #  0x23 -> NUMBER SIGN
+    u'$'        #  0x24 -> DOLLAR SIGN
+    u'%'        #  0x25 -> PERCENT SIGN
+    u'&'        #  0x26 -> AMPERSAND
+    u"'"        #  0x27 -> APOSTROPHE
+    u'('        #  0x28 -> LEFT PARENTHESIS
+    u')'        #  0x29 -> RIGHT PARENTHESIS
+    u'*'        #  0x2A -> ASTERISK
+    u'+'        #  0x2B -> PLUS SIGN
+    u','        #  0x2C -> COMMA
+    u'-'        #  0x2D -> HYPHEN-MINUS
+    u'.'        #  0x2E -> FULL STOP
+    u'/'        #  0x2F -> SOLIDUS
+    u'0'        #  0x30 -> DIGIT ZERO
+    u'1'        #  0x31 -> DIGIT ONE
+    u'2'        #  0x32 -> DIGIT TWO
+    u'3'        #  0x33 -> DIGIT THREE
+    u'4'        #  0x34 -> DIGIT FOUR
+    u'5'        #  0x35 -> DIGIT FIVE
+    u'6'        #  0x36 -> DIGIT SIX
+    u'7'        #  0x37 -> DIGIT SEVEN
+    u'8'        #  0x38 -> DIGIT EIGHT
+    u'9'        #  0x39 -> DIGIT NINE
+    u':'        #  0x3A -> COLON
+    u';'        #  0x3B -> SEMICOLON
+    u'<'        #  0x3C -> LESS-THAN SIGN
+    u'='        #  0x3D -> EQUALS SIGN
+    u'>'        #  0x3E -> GREATER-THAN SIGN
+    u'?'        #  0x3F -> QUESTION MARK
+    u'@'        #  0x40 -> COMMERCIAL AT
+    u'A'        #  0x41 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x42 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x43 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x44 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x45 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x46 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x47 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x48 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x49 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x4A -> LATIN CAPITAL LETTER J
+    u'K'        #  0x4B -> LATIN CAPITAL LETTER K
+    u'L'        #  0x4C -> LATIN CAPITAL LETTER L
+    u'M'        #  0x4D -> LATIN CAPITAL LETTER M
+    u'N'        #  0x4E -> LATIN CAPITAL LETTER N
+    u'O'        #  0x4F -> LATIN CAPITAL LETTER O
+    u'P'        #  0x50 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x51 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x52 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x53 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x54 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x55 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x56 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x57 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x58 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x59 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x5A -> LATIN CAPITAL LETTER Z
+    u'['        #  0x5B -> LEFT SQUARE BRACKET
+    u'\\'       #  0x5C -> REVERSE SOLIDUS
+    u']'        #  0x5D -> RIGHT SQUARE BRACKET
+    u'^'        #  0x5E -> CIRCUMFLEX ACCENT
+    u'_'        #  0x5F -> LOW LINE
+    u'`'        #  0x60 -> GRAVE ACCENT
+    u'a'        #  0x61 -> LATIN SMALL LETTER A
+    u'b'        #  0x62 -> LATIN SMALL LETTER B
+    u'c'        #  0x63 -> LATIN SMALL LETTER C
+    u'd'        #  0x64 -> LATIN SMALL LETTER D
+    u'e'        #  0x65 -> LATIN SMALL LETTER E
+    u'f'        #  0x66 -> LATIN SMALL LETTER F
+    u'g'        #  0x67 -> LATIN SMALL LETTER G
+    u'h'        #  0x68 -> LATIN SMALL LETTER H
+    u'i'        #  0x69 -> LATIN SMALL LETTER I
+    u'j'        #  0x6A -> LATIN SMALL LETTER J
+    u'k'        #  0x6B -> LATIN SMALL LETTER K
+    u'l'        #  0x6C -> LATIN SMALL LETTER L
+    u'm'        #  0x6D -> LATIN SMALL LETTER M
+    u'n'        #  0x6E -> LATIN SMALL LETTER N
+    u'o'        #  0x6F -> LATIN SMALL LETTER O
+    u'p'        #  0x70 -> LATIN SMALL LETTER P
+    u'q'        #  0x71 -> LATIN SMALL LETTER Q
+    u'r'        #  0x72 -> LATIN SMALL LETTER R
+    u's'        #  0x73 -> LATIN SMALL LETTER S
+    u't'        #  0x74 -> LATIN SMALL LETTER T
+    u'u'        #  0x75 -> LATIN SMALL LETTER U
+    u'v'        #  0x76 -> LATIN SMALL LETTER V
+    u'w'        #  0x77 -> LATIN SMALL LETTER W
+    u'x'        #  0x78 -> LATIN SMALL LETTER X
+    u'y'        #  0x79 -> LATIN SMALL LETTER Y
+    u'z'        #  0x7A -> LATIN SMALL LETTER Z
+    u'{'        #  0x7B -> LEFT CURLY BRACKET
+    u'|'        #  0x7C -> VERTICAL LINE
+    u'}'        #  0x7D -> RIGHT CURLY BRACKET
+    u'~'        #  0x7E -> TILDE
+    u'\x7f'     #  0x7F -> DELETE
+    u'\u2500'   #  0x80 -> BOX DRAWINGS LIGHT HORIZONTAL
+    u'\u2502'   #  0x81 -> BOX DRAWINGS LIGHT VERTICAL
+    u'\u250c'   #  0x82 -> BOX DRAWINGS LIGHT DOWN AND RIGHT
+    u'\u2510'   #  0x83 -> BOX DRAWINGS LIGHT DOWN AND LEFT
+    u'\u2514'   #  0x84 -> BOX DRAWINGS LIGHT UP AND RIGHT
+    u'\u2518'   #  0x85 -> BOX DRAWINGS LIGHT UP AND LEFT
+    u'\u251c'   #  0x86 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+    u'\u2524'   #  0x87 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT
+    u'\u252c'   #  0x88 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+    u'\u2534'   #  0x89 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL
+    u'\u253c'   #  0x8A -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+    u'\u2580'   #  0x8B -> UPPER HALF BLOCK
+    u'\u2584'   #  0x8C -> LOWER HALF BLOCK
+    u'\u2588'   #  0x8D -> FULL BLOCK
+    u'\u258c'   #  0x8E -> LEFT HALF BLOCK
+    u'\u2590'   #  0x8F -> RIGHT HALF BLOCK
+    u'\u2591'   #  0x90 -> LIGHT SHADE
+    u'\u2592'   #  0x91 -> MEDIUM SHADE
+    u'\u2593'   #  0x92 -> DARK SHADE
+    u'\u2320'   #  0x93 -> TOP HALF INTEGRAL
+    u'\u25a0'   #  0x94 -> BLACK SQUARE
+    u'\u2219'   #  0x95 -> BULLET OPERATOR
+    u'\u221a'   #  0x96 -> SQUARE ROOT
+    u'\u2248'   #  0x97 -> ALMOST EQUAL TO
+    u'\u2264'   #  0x98 -> LESS-THAN OR EQUAL TO
+    u'\u2265'   #  0x99 -> GREATER-THAN OR EQUAL TO
+    u'\xa0'     #  0x9A -> NO-BREAK SPACE
+    u'\u2321'   #  0x9B -> BOTTOM HALF INTEGRAL
+    u'\xb0'     #  0x9C -> DEGREE SIGN
+    u'\xb2'     #  0x9D -> SUPERSCRIPT TWO
+    u'\xb7'     #  0x9E -> MIDDLE DOT
+    u'\xf7'     #  0x9F -> DIVISION SIGN
+    u'\u2550'   #  0xA0 -> BOX DRAWINGS DOUBLE HORIZONTAL
+    u'\u2551'   #  0xA1 -> BOX DRAWINGS DOUBLE VERTICAL
+    u'\u2552'   #  0xA2 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+    u'\u0451'   #  0xA3 -> CYRILLIC SMALL LETTER IO
+    u'\u2553'   #  0xA4 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
+    u'\u2554'   #  0xA5 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT
+    u'\u2555'   #  0xA6 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
+    u'\u2556'   #  0xA7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
+    u'\u2557'   #  0xA8 -> BOX DRAWINGS DOUBLE DOWN AND LEFT
+    u'\u2558'   #  0xA9 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+    u'\u2559'   #  0xAA -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+    u'\u255a'   #  0xAB -> BOX DRAWINGS DOUBLE UP AND RIGHT
+    u'\u255b'   #  0xAC -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+    u'\u255c'   #  0xAD -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
+    u'\u255d'   #  0xAE -> BOX DRAWINGS DOUBLE UP AND LEFT
+    u'\u255e'   #  0xAF -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+    u'\u255f'   #  0xB0 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+    u'\u2560'   #  0xB1 -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+    u'\u2561'   #  0xB2 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+    u'\u0401'   #  0xB3 -> CYRILLIC CAPITAL LETTER IO
+    u'\u2562'   #  0xB4 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
+    u'\u2563'   #  0xB5 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+    u'\u2564'   #  0xB6 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
+    u'\u2565'   #  0xB7 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
+    u'\u2566'   #  0xB8 -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+    u'\u2567'   #  0xB9 -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+    u'\u2568'   #  0xBA -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+    u'\u2569'   #  0xBB -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+    u'\u256a'   #  0xBC -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+    u'\u256b'   #  0xBD -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
+    u'\u256c'   #  0xBE -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+    u'\xa9'     #  0xBF -> COPYRIGHT SIGN
+    u'\u044e'   #  0xC0 -> CYRILLIC SMALL LETTER YU
+    u'\u0430'   #  0xC1 -> CYRILLIC SMALL LETTER A
+    u'\u0431'   #  0xC2 -> CYRILLIC SMALL LETTER BE
+    u'\u0446'   #  0xC3 -> CYRILLIC SMALL LETTER TSE
+    u'\u0434'   #  0xC4 -> CYRILLIC SMALL LETTER DE
+    u'\u0435'   #  0xC5 -> CYRILLIC SMALL LETTER IE
+    u'\u0444'   #  0xC6 -> CYRILLIC SMALL LETTER EF
+    u'\u0433'   #  0xC7 -> CYRILLIC SMALL LETTER GHE
+    u'\u0445'   #  0xC8 -> CYRILLIC SMALL LETTER HA
+    u'\u0438'   #  0xC9 -> CYRILLIC SMALL LETTER I
+    u'\u0439'   #  0xCA -> CYRILLIC SMALL LETTER SHORT I
+    u'\u043a'   #  0xCB -> CYRILLIC SMALL LETTER KA
+    u'\u043b'   #  0xCC -> CYRILLIC SMALL LETTER EL
+    u'\u043c'   #  0xCD -> CYRILLIC SMALL LETTER EM
+    u'\u043d'   #  0xCE -> CYRILLIC SMALL LETTER EN
+    u'\u043e'   #  0xCF -> CYRILLIC SMALL LETTER O
+    u'\u043f'   #  0xD0 -> CYRILLIC SMALL LETTER PE
+    u'\u044f'   #  0xD1 -> CYRILLIC SMALL LETTER YA
+    u'\u0440'   #  0xD2 -> CYRILLIC SMALL LETTER ER
+    u'\u0441'   #  0xD3 -> CYRILLIC SMALL LETTER ES
+    u'\u0442'   #  0xD4 -> CYRILLIC SMALL LETTER TE
+    u'\u0443'   #  0xD5 -> CYRILLIC SMALL LETTER U
+    u'\u0436'   #  0xD6 -> CYRILLIC SMALL LETTER ZHE
+    u'\u0432'   #  0xD7 -> CYRILLIC SMALL LETTER VE
+    u'\u044c'   #  0xD8 -> CYRILLIC SMALL LETTER SOFT SIGN
+    u'\u044b'   #  0xD9 -> CYRILLIC SMALL LETTER YERU
+    u'\u0437'   #  0xDA -> CYRILLIC SMALL LETTER ZE
+    u'\u0448'   #  0xDB -> CYRILLIC SMALL LETTER SHA
+    u'\u044d'   #  0xDC -> CYRILLIC SMALL LETTER E
+    u'\u0449'   #  0xDD -> CYRILLIC SMALL LETTER SHCHA
+    u'\u0447'   #  0xDE -> CYRILLIC SMALL LETTER CHE
+    u'\u044a'   #  0xDF -> CYRILLIC SMALL LETTER HARD SIGN
+    u'\u042e'   #  0xE0 -> CYRILLIC CAPITAL LETTER YU
+    u'\u0410'   #  0xE1 -> CYRILLIC CAPITAL LETTER A
+    u'\u0411'   #  0xE2 -> CYRILLIC CAPITAL LETTER BE
+    u'\u0426'   #  0xE3 -> CYRILLIC CAPITAL LETTER TSE
+    u'\u0414'   #  0xE4 -> CYRILLIC CAPITAL LETTER DE
+    u'\u0415'   #  0xE5 -> CYRILLIC CAPITAL LETTER IE
+    u'\u0424'   #  0xE6 -> CYRILLIC CAPITAL LETTER EF
+    u'\u0413'   #  0xE7 -> CYRILLIC CAPITAL LETTER GHE
+    u'\u0425'   #  0xE8 -> CYRILLIC CAPITAL LETTER HA
+    u'\u0418'   #  0xE9 -> CYRILLIC CAPITAL LETTER I
+    u'\u0419'   #  0xEA -> CYRILLIC CAPITAL LETTER SHORT I
+    u'\u041a'   #  0xEB -> CYRILLIC CAPITAL LETTER KA
+    u'\u041b'   #  0xEC -> CYRILLIC CAPITAL LETTER EL
+    u'\u041c'   #  0xED -> CYRILLIC CAPITAL LETTER EM
+    u'\u041d'   #  0xEE -> CYRILLIC CAPITAL LETTER EN
+    u'\u041e'   #  0xEF -> CYRILLIC CAPITAL LETTER O
+    u'\u041f'   #  0xF0 -> CYRILLIC CAPITAL LETTER PE
+    u'\u042f'   #  0xF1 -> CYRILLIC CAPITAL LETTER YA
+    u'\u0420'   #  0xF2 -> CYRILLIC CAPITAL LETTER ER
+    u'\u0421'   #  0xF3 -> CYRILLIC CAPITAL LETTER ES
+    u'\u0422'   #  0xF4 -> CYRILLIC CAPITAL LETTER TE
+    u'\u0423'   #  0xF5 -> CYRILLIC CAPITAL LETTER U
+    u'\u0416'   #  0xF6 -> CYRILLIC CAPITAL LETTER ZHE
+    u'\u0412'   #  0xF7 -> CYRILLIC CAPITAL LETTER VE
+    u'\u042c'   #  0xF8 -> CYRILLIC CAPITAL LETTER SOFT SIGN
+    u'\u042b'   #  0xF9 -> CYRILLIC CAPITAL LETTER YERU
+    u'\u0417'   #  0xFA -> CYRILLIC CAPITAL LETTER ZE
+    u'\u0428'   #  0xFB -> CYRILLIC CAPITAL LETTER SHA
+    u'\u042d'   #  0xFC -> CYRILLIC CAPITAL LETTER E
+    u'\u0429'   #  0xFD -> CYRILLIC CAPITAL LETTER SHCHA
+    u'\u0427'   #  0xFE -> CYRILLIC CAPITAL LETTER CHE
+    u'\u042a'   #  0xFF -> CYRILLIC CAPITAL LETTER HARD SIGN
+)
+
+### Encoding table
+encoding_table=codecs.charmap_build(decoding_table)

Added: vendor/Python/current/Lib/encodings/koi8_u.py
===================================================================
--- vendor/Python/current/Lib/encodings/koi8_u.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/koi8_u.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,307 @@
+""" Python Character Mapping Codec koi8_u generated from 'python-mappings/KOI8-U.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_table)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_table)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='koi8-u',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x00 -> NULL
+    u'\x01'     #  0x01 -> START OF HEADING
+    u'\x02'     #  0x02 -> START OF TEXT
+    u'\x03'     #  0x03 -> END OF TEXT
+    u'\x04'     #  0x04 -> END OF TRANSMISSION
+    u'\x05'     #  0x05 -> ENQUIRY
+    u'\x06'     #  0x06 -> ACKNOWLEDGE
+    u'\x07'     #  0x07 -> BELL
+    u'\x08'     #  0x08 -> BACKSPACE
+    u'\t'       #  0x09 -> HORIZONTAL TABULATION
+    u'\n'       #  0x0A -> LINE FEED
+    u'\x0b'     #  0x0B -> VERTICAL TABULATION
+    u'\x0c'     #  0x0C -> FORM FEED
+    u'\r'       #  0x0D -> CARRIAGE RETURN
+    u'\x0e'     #  0x0E -> SHIFT OUT
+    u'\x0f'     #  0x0F -> SHIFT IN
+    u'\x10'     #  0x10 -> DATA LINK ESCAPE
+    u'\x11'     #  0x11 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x12 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x13 -> DEVICE CONTROL THREE
+    u'\x14'     #  0x14 -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x15 -> NEGATIVE ACKNOWLEDGE
+    u'\x16'     #  0x16 -> SYNCHRONOUS IDLE
+    u'\x17'     #  0x17 -> END OF TRANSMISSION BLOCK
+    u'\x18'     #  0x18 -> CANCEL
+    u'\x19'     #  0x19 -> END OF MEDIUM
+    u'\x1a'     #  0x1A -> SUBSTITUTE
+    u'\x1b'     #  0x1B -> ESCAPE
+    u'\x1c'     #  0x1C -> FILE SEPARATOR
+    u'\x1d'     #  0x1D -> GROUP SEPARATOR
+    u'\x1e'     #  0x1E -> RECORD SEPARATOR
+    u'\x1f'     #  0x1F -> UNIT SEPARATOR
+    u' '        #  0x20 -> SPACE
+    u'!'        #  0x21 -> EXCLAMATION MARK
+    u'"'        #  0x22 -> QUOTATION MARK
+    u'#'        #  0x23 -> NUMBER SIGN
+    u'$'        #  0x24 -> DOLLAR SIGN
+    u'%'        #  0x25 -> PERCENT SIGN
+    u'&'        #  0x26 -> AMPERSAND
+    u"'"        #  0x27 -> APOSTROPHE
+    u'('        #  0x28 -> LEFT PARENTHESIS
+    u')'        #  0x29 -> RIGHT PARENTHESIS
+    u'*'        #  0x2A -> ASTERISK
+    u'+'        #  0x2B -> PLUS SIGN
+    u','        #  0x2C -> COMMA
+    u'-'        #  0x2D -> HYPHEN-MINUS
+    u'.'        #  0x2E -> FULL STOP
+    u'/'        #  0x2F -> SOLIDUS
+    u'0'        #  0x30 -> DIGIT ZERO
+    u'1'        #  0x31 -> DIGIT ONE
+    u'2'        #  0x32 -> DIGIT TWO
+    u'3'        #  0x33 -> DIGIT THREE
+    u'4'        #  0x34 -> DIGIT FOUR
+    u'5'        #  0x35 -> DIGIT FIVE
+    u'6'        #  0x36 -> DIGIT SIX
+    u'7'        #  0x37 -> DIGIT SEVEN
+    u'8'        #  0x38 -> DIGIT EIGHT
+    u'9'        #  0x39 -> DIGIT NINE
+    u':'        #  0x3A -> COLON
+    u';'        #  0x3B -> SEMICOLON
+    u'<'        #  0x3C -> LESS-THAN SIGN
+    u'='        #  0x3D -> EQUALS SIGN
+    u'>'        #  0x3E -> GREATER-THAN SIGN
+    u'?'        #  0x3F -> QUESTION MARK
+    u'@'        #  0x40 -> COMMERCIAL AT
+    u'A'        #  0x41 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x42 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x43 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x44 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x45 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x46 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x47 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x48 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x49 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x4A -> LATIN CAPITAL LETTER J
+    u'K'        #  0x4B -> LATIN CAPITAL LETTER K
+    u'L'        #  0x4C -> LATIN CAPITAL LETTER L
+    u'M'        #  0x4D -> LATIN CAPITAL LETTER M
+    u'N'        #  0x4E -> LATIN CAPITAL LETTER N
+    u'O'        #  0x4F -> LATIN CAPITAL LETTER O
+    u'P'        #  0x50 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x51 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x52 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x53 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x54 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x55 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x56 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x57 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x58 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x59 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x5A -> LATIN CAPITAL LETTER Z
+    u'['        #  0x5B -> LEFT SQUARE BRACKET
+    u'\\'       #  0x5C -> REVERSE SOLIDUS
+    u']'        #  0x5D -> RIGHT SQUARE BRACKET
+    u'^'        #  0x5E -> CIRCUMFLEX ACCENT
+    u'_'        #  0x5F -> LOW LINE
+    u'`'        #  0x60 -> GRAVE ACCENT
+    u'a'        #  0x61 -> LATIN SMALL LETTER A
+    u'b'        #  0x62 -> LATIN SMALL LETTER B
+    u'c'        #  0x63 -> LATIN SMALL LETTER C
+    u'd'        #  0x64 -> LATIN SMALL LETTER D
+    u'e'        #  0x65 -> LATIN SMALL LETTER E
+    u'f'        #  0x66 -> LATIN SMALL LETTER F
+    u'g'        #  0x67 -> LATIN SMALL LETTER G
+    u'h'        #  0x68 -> LATIN SMALL LETTER H
+    u'i'        #  0x69 -> LATIN SMALL LETTER I
+    u'j'        #  0x6A -> LATIN SMALL LETTER J
+    u'k'        #  0x6B -> LATIN SMALL LETTER K
+    u'l'        #  0x6C -> LATIN SMALL LETTER L
+    u'm'        #  0x6D -> LATIN SMALL LETTER M
+    u'n'        #  0x6E -> LATIN SMALL LETTER N
+    u'o'        #  0x6F -> LATIN SMALL LETTER O
+    u'p'        #  0x70 -> LATIN SMALL LETTER P
+    u'q'        #  0x71 -> LATIN SMALL LETTER Q
+    u'r'        #  0x72 -> LATIN SMALL LETTER R
+    u's'        #  0x73 -> LATIN SMALL LETTER S
+    u't'        #  0x74 -> LATIN SMALL LETTER T
+    u'u'        #  0x75 -> LATIN SMALL LETTER U
+    u'v'        #  0x76 -> LATIN SMALL LETTER V
+    u'w'        #  0x77 -> LATIN SMALL LETTER W
+    u'x'        #  0x78 -> LATIN SMALL LETTER X
+    u'y'        #  0x79 -> LATIN SMALL LETTER Y
+    u'z'        #  0x7A -> LATIN SMALL LETTER Z
+    u'{'        #  0x7B -> LEFT CURLY BRACKET
+    u'|'        #  0x7C -> VERTICAL LINE
+    u'}'        #  0x7D -> RIGHT CURLY BRACKET
+    u'~'        #  0x7E -> TILDE
+    u'\x7f'     #  0x7F -> DELETE
+    u'\u2500'   #  0x80 -> BOX DRAWINGS LIGHT HORIZONTAL
+    u'\u2502'   #  0x81 -> BOX DRAWINGS LIGHT VERTICAL
+    u'\u250c'   #  0x82 -> BOX DRAWINGS LIGHT DOWN AND RIGHT
+    u'\u2510'   #  0x83 -> BOX DRAWINGS LIGHT DOWN AND LEFT
+    u'\u2514'   #  0x84 -> BOX DRAWINGS LIGHT UP AND RIGHT
+    u'\u2518'   #  0x85 -> BOX DRAWINGS LIGHT UP AND LEFT
+    u'\u251c'   #  0x86 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+    u'\u2524'   #  0x87 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT
+    u'\u252c'   #  0x88 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+    u'\u2534'   #  0x89 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL
+    u'\u253c'   #  0x8A -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+    u'\u2580'   #  0x8B -> UPPER HALF BLOCK
+    u'\u2584'   #  0x8C -> LOWER HALF BLOCK
+    u'\u2588'   #  0x8D -> FULL BLOCK
+    u'\u258c'   #  0x8E -> LEFT HALF BLOCK
+    u'\u2590'   #  0x8F -> RIGHT HALF BLOCK
+    u'\u2591'   #  0x90 -> LIGHT SHADE
+    u'\u2592'   #  0x91 -> MEDIUM SHADE
+    u'\u2593'   #  0x92 -> DARK SHADE
+    u'\u2320'   #  0x93 -> TOP HALF INTEGRAL
+    u'\u25a0'   #  0x94 -> BLACK SQUARE
+    u'\u2219'   #  0x95 -> BULLET OPERATOR
+    u'\u221a'   #  0x96 -> SQUARE ROOT
+    u'\u2248'   #  0x97 -> ALMOST EQUAL TO
+    u'\u2264'   #  0x98 -> LESS-THAN OR EQUAL TO
+    u'\u2265'   #  0x99 -> GREATER-THAN OR EQUAL TO
+    u'\xa0'     #  0x9A -> NO-BREAK SPACE
+    u'\u2321'   #  0x9B -> BOTTOM HALF INTEGRAL
+    u'\xb0'     #  0x9C -> DEGREE SIGN
+    u'\xb2'     #  0x9D -> SUPERSCRIPT TWO
+    u'\xb7'     #  0x9E -> MIDDLE DOT
+    u'\xf7'     #  0x9F -> DIVISION SIGN
+    u'\u2550'   #  0xA0 -> BOX DRAWINGS DOUBLE HORIZONTAL
+    u'\u2551'   #  0xA1 -> BOX DRAWINGS DOUBLE VERTICAL
+    u'\u2552'   #  0xA2 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+    u'\u0451'   #  0xA3 -> CYRILLIC SMALL LETTER IO
+    u'\u0454'   #  0xA4 -> CYRILLIC SMALL LETTER UKRAINIAN IE
+    u'\u2554'   #  0xA5 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT
+    u'\u0456'   #  0xA6 -> CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
+    u'\u0457'   #  0xA7 -> CYRILLIC SMALL LETTER YI (UKRAINIAN)
+    u'\u2557'   #  0xA8 -> BOX DRAWINGS DOUBLE DOWN AND LEFT
+    u'\u2558'   #  0xA9 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+    u'\u2559'   #  0xAA -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+    u'\u255a'   #  0xAB -> BOX DRAWINGS DOUBLE UP AND RIGHT
+    u'\u255b'   #  0xAC -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+    u'\u0491'   #  0xAD -> CYRILLIC SMALL LETTER UKRAINIAN GHE WITH UPTURN
+    u'\u255d'   #  0xAE -> BOX DRAWINGS DOUBLE UP AND LEFT
+    u'\u255e'   #  0xAF -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+    u'\u255f'   #  0xB0 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+    u'\u2560'   #  0xB1 -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+    u'\u2561'   #  0xB2 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+    u'\u0401'   #  0xB3 -> CYRILLIC CAPITAL LETTER IO
+    u'\u0404'   #  0xB4 -> CYRILLIC CAPITAL LETTER UKRAINIAN IE
+    u'\u2563'   #  0xB5 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+    u'\u0406'   #  0xB6 -> CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I
+    u'\u0407'   #  0xB7 -> CYRILLIC CAPITAL LETTER YI (UKRAINIAN)
+    u'\u2566'   #  0xB8 -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+    u'\u2567'   #  0xB9 -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+    u'\u2568'   #  0xBA -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+    u'\u2569'   #  0xBB -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+    u'\u256a'   #  0xBC -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+    u'\u0490'   #  0xBD -> CYRILLIC CAPITAL LETTER UKRAINIAN GHE WITH UPTURN
+    u'\u256c'   #  0xBE -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+    u'\xa9'     #  0xBF -> COPYRIGHT SIGN
+    u'\u044e'   #  0xC0 -> CYRILLIC SMALL LETTER YU
+    u'\u0430'   #  0xC1 -> CYRILLIC SMALL LETTER A
+    u'\u0431'   #  0xC2 -> CYRILLIC SMALL LETTER BE
+    u'\u0446'   #  0xC3 -> CYRILLIC SMALL LETTER TSE
+    u'\u0434'   #  0xC4 -> CYRILLIC SMALL LETTER DE
+    u'\u0435'   #  0xC5 -> CYRILLIC SMALL LETTER IE
+    u'\u0444'   #  0xC6 -> CYRILLIC SMALL LETTER EF
+    u'\u0433'   #  0xC7 -> CYRILLIC SMALL LETTER GHE
+    u'\u0445'   #  0xC8 -> CYRILLIC SMALL LETTER HA
+    u'\u0438'   #  0xC9 -> CYRILLIC SMALL LETTER I
+    u'\u0439'   #  0xCA -> CYRILLIC SMALL LETTER SHORT I
+    u'\u043a'   #  0xCB -> CYRILLIC SMALL LETTER KA
+    u'\u043b'   #  0xCC -> CYRILLIC SMALL LETTER EL
+    u'\u043c'   #  0xCD -> CYRILLIC SMALL LETTER EM
+    u'\u043d'   #  0xCE -> CYRILLIC SMALL LETTER EN
+    u'\u043e'   #  0xCF -> CYRILLIC SMALL LETTER O
+    u'\u043f'   #  0xD0 -> CYRILLIC SMALL LETTER PE
+    u'\u044f'   #  0xD1 -> CYRILLIC SMALL LETTER YA
+    u'\u0440'   #  0xD2 -> CYRILLIC SMALL LETTER ER
+    u'\u0441'   #  0xD3 -> CYRILLIC SMALL LETTER ES
+    u'\u0442'   #  0xD4 -> CYRILLIC SMALL LETTER TE
+    u'\u0443'   #  0xD5 -> CYRILLIC SMALL LETTER U
+    u'\u0436'   #  0xD6 -> CYRILLIC SMALL LETTER ZHE
+    u'\u0432'   #  0xD7 -> CYRILLIC SMALL LETTER VE
+    u'\u044c'   #  0xD8 -> CYRILLIC SMALL LETTER SOFT SIGN
+    u'\u044b'   #  0xD9 -> CYRILLIC SMALL LETTER YERU
+    u'\u0437'   #  0xDA -> CYRILLIC SMALL LETTER ZE
+    u'\u0448'   #  0xDB -> CYRILLIC SMALL LETTER SHA
+    u'\u044d'   #  0xDC -> CYRILLIC SMALL LETTER E
+    u'\u0449'   #  0xDD -> CYRILLIC SMALL LETTER SHCHA
+    u'\u0447'   #  0xDE -> CYRILLIC SMALL LETTER CHE
+    u'\u044a'   #  0xDF -> CYRILLIC SMALL LETTER HARD SIGN
+    u'\u042e'   #  0xE0 -> CYRILLIC CAPITAL LETTER YU
+    u'\u0410'   #  0xE1 -> CYRILLIC CAPITAL LETTER A
+    u'\u0411'   #  0xE2 -> CYRILLIC CAPITAL LETTER BE
+    u'\u0426'   #  0xE3 -> CYRILLIC CAPITAL LETTER TSE
+    u'\u0414'   #  0xE4 -> CYRILLIC CAPITAL LETTER DE
+    u'\u0415'   #  0xE5 -> CYRILLIC CAPITAL LETTER IE
+    u'\u0424'   #  0xE6 -> CYRILLIC CAPITAL LETTER EF
+    u'\u0413'   #  0xE7 -> CYRILLIC CAPITAL LETTER GHE
+    u'\u0425'   #  0xE8 -> CYRILLIC CAPITAL LETTER HA
+    u'\u0418'   #  0xE9 -> CYRILLIC CAPITAL LETTER I
+    u'\u0419'   #  0xEA -> CYRILLIC CAPITAL LETTER SHORT I
+    u'\u041a'   #  0xEB -> CYRILLIC CAPITAL LETTER KA
+    u'\u041b'   #  0xEC -> CYRILLIC CAPITAL LETTER EL
+    u'\u041c'   #  0xED -> CYRILLIC CAPITAL LETTER EM
+    u'\u041d'   #  0xEE -> CYRILLIC CAPITAL LETTER EN
+    u'\u041e'   #  0xEF -> CYRILLIC CAPITAL LETTER O
+    u'\u041f'   #  0xF0 -> CYRILLIC CAPITAL LETTER PE
+    u'\u042f'   #  0xF1 -> CYRILLIC CAPITAL LETTER YA
+    u'\u0420'   #  0xF2 -> CYRILLIC CAPITAL LETTER ER
+    u'\u0421'   #  0xF3 -> CYRILLIC CAPITAL LETTER ES
+    u'\u0422'   #  0xF4 -> CYRILLIC CAPITAL LETTER TE
+    u'\u0423'   #  0xF5 -> CYRILLIC CAPITAL LETTER U
+    u'\u0416'   #  0xF6 -> CYRILLIC CAPITAL LETTER ZHE
+    u'\u0412'   #  0xF7 -> CYRILLIC CAPITAL LETTER VE
+    u'\u042c'   #  0xF8 -> CYRILLIC CAPITAL LETTER SOFT SIGN
+    u'\u042b'   #  0xF9 -> CYRILLIC CAPITAL LETTER YERU
+    u'\u0417'   #  0xFA -> CYRILLIC CAPITAL LETTER ZE
+    u'\u0428'   #  0xFB -> CYRILLIC CAPITAL LETTER SHA
+    u'\u042d'   #  0xFC -> CYRILLIC CAPITAL LETTER E
+    u'\u0429'   #  0xFD -> CYRILLIC CAPITAL LETTER SHCHA
+    u'\u0427'   #  0xFE -> CYRILLIC CAPITAL LETTER CHE
+    u'\u042a'   #  0xFF -> CYRILLIC CAPITAL LETTER HARD SIGN
+)
+
+### Encoding table
+encoding_table=codecs.charmap_build(decoding_table)

Added: vendor/Python/current/Lib/encodings/latin_1.py
===================================================================
--- vendor/Python/current/Lib/encodings/latin_1.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/latin_1.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,50 @@
+""" Python 'latin-1' Codec
+
+
+Written by Marc-Andre Lemburg (mal at lemburg.com).
+
+(c) Copyright CNRI, All Rights Reserved. NO WARRANTY.
+
+"""
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    # Note: Binding these as C functions will result in the class not
+    # converting them to methods. This is intended.
+    encode = codecs.latin_1_encode
+    decode = codecs.latin_1_decode
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.latin_1_encode(input,self.errors)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.latin_1_decode(input,self.errors)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+class StreamConverter(StreamWriter,StreamReader):
+
+    encode = codecs.latin_1_decode
+    decode = codecs.latin_1_encode
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='iso8859-1',
+        encode=Codec.encode,
+        decode=Codec.decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )

Added: vendor/Python/current/Lib/encodings/mac_arabic.py
===================================================================
--- vendor/Python/current/Lib/encodings/mac_arabic.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/mac_arabic.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,698 @@
+""" Python Character Mapping Codec generated from 'VENDORS/APPLE/ARABIC.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_map)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='mac-arabic',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+### Decoding Map
+
+decoding_map = codecs.make_identity_dict(range(256))
+decoding_map.update({
+    0x0080: 0x00c4,     #  LATIN CAPITAL LETTER A WITH DIAERESIS
+    0x0081: 0x00a0,     #  NO-BREAK SPACE, right-left
+    0x0082: 0x00c7,     #  LATIN CAPITAL LETTER C WITH CEDILLA
+    0x0083: 0x00c9,     #  LATIN CAPITAL LETTER E WITH ACUTE
+    0x0084: 0x00d1,     #  LATIN CAPITAL LETTER N WITH TILDE
+    0x0085: 0x00d6,     #  LATIN CAPITAL LETTER O WITH DIAERESIS
+    0x0086: 0x00dc,     #  LATIN CAPITAL LETTER U WITH DIAERESIS
+    0x0087: 0x00e1,     #  LATIN SMALL LETTER A WITH ACUTE
+    0x0088: 0x00e0,     #  LATIN SMALL LETTER A WITH GRAVE
+    0x0089: 0x00e2,     #  LATIN SMALL LETTER A WITH CIRCUMFLEX
+    0x008a: 0x00e4,     #  LATIN SMALL LETTER A WITH DIAERESIS
+    0x008b: 0x06ba,     #  ARABIC LETTER NOON GHUNNA
+    0x008c: 0x00ab,     #  LEFT-POINTING DOUBLE ANGLE QUOTATION MARK, right-left
+    0x008d: 0x00e7,     #  LATIN SMALL LETTER C WITH CEDILLA
+    0x008e: 0x00e9,     #  LATIN SMALL LETTER E WITH ACUTE
+    0x008f: 0x00e8,     #  LATIN SMALL LETTER E WITH GRAVE
+    0x0090: 0x00ea,     #  LATIN SMALL LETTER E WITH CIRCUMFLEX
+    0x0091: 0x00eb,     #  LATIN SMALL LETTER E WITH DIAERESIS
+    0x0092: 0x00ed,     #  LATIN SMALL LETTER I WITH ACUTE
+    0x0093: 0x2026,     #  HORIZONTAL ELLIPSIS, right-left
+    0x0094: 0x00ee,     #  LATIN SMALL LETTER I WITH CIRCUMFLEX
+    0x0095: 0x00ef,     #  LATIN SMALL LETTER I WITH DIAERESIS
+    0x0096: 0x00f1,     #  LATIN SMALL LETTER N WITH TILDE
+    0x0097: 0x00f3,     #  LATIN SMALL LETTER O WITH ACUTE
+    0x0098: 0x00bb,     #  RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK, right-left
+    0x0099: 0x00f4,     #  LATIN SMALL LETTER O WITH CIRCUMFLEX
+    0x009a: 0x00f6,     #  LATIN SMALL LETTER O WITH DIAERESIS
+    0x009b: 0x00f7,     #  DIVISION SIGN, right-left
+    0x009c: 0x00fa,     #  LATIN SMALL LETTER U WITH ACUTE
+    0x009d: 0x00f9,     #  LATIN SMALL LETTER U WITH GRAVE
+    0x009e: 0x00fb,     #  LATIN SMALL LETTER U WITH CIRCUMFLEX
+    0x009f: 0x00fc,     #  LATIN SMALL LETTER U WITH DIAERESIS
+    0x00a0: 0x0020,     #  SPACE, right-left
+    0x00a1: 0x0021,     #  EXCLAMATION MARK, right-left
+    0x00a2: 0x0022,     #  QUOTATION MARK, right-left
+    0x00a3: 0x0023,     #  NUMBER SIGN, right-left
+    0x00a4: 0x0024,     #  DOLLAR SIGN, right-left
+    0x00a5: 0x066a,     #  ARABIC PERCENT SIGN
+    0x00a6: 0x0026,     #  AMPERSAND, right-left
+    0x00a7: 0x0027,     #  APOSTROPHE, right-left
+    0x00a8: 0x0028,     #  LEFT PARENTHESIS, right-left
+    0x00a9: 0x0029,     #  RIGHT PARENTHESIS, right-left
+    0x00aa: 0x002a,     #  ASTERISK, right-left
+    0x00ab: 0x002b,     #  PLUS SIGN, right-left
+    0x00ac: 0x060c,     #  ARABIC COMMA
+    0x00ad: 0x002d,     #  HYPHEN-MINUS, right-left
+    0x00ae: 0x002e,     #  FULL STOP, right-left
+    0x00af: 0x002f,     #  SOLIDUS, right-left
+    0x00b0: 0x0660,     #  ARABIC-INDIC DIGIT ZERO, right-left (need override)
+    0x00b1: 0x0661,     #  ARABIC-INDIC DIGIT ONE, right-left (need override)
+    0x00b2: 0x0662,     #  ARABIC-INDIC DIGIT TWO, right-left (need override)
+    0x00b3: 0x0663,     #  ARABIC-INDIC DIGIT THREE, right-left (need override)
+    0x00b4: 0x0664,     #  ARABIC-INDIC DIGIT FOUR, right-left (need override)
+    0x00b5: 0x0665,     #  ARABIC-INDIC DIGIT FIVE, right-left (need override)
+    0x00b6: 0x0666,     #  ARABIC-INDIC DIGIT SIX, right-left (need override)
+    0x00b7: 0x0667,     #  ARABIC-INDIC DIGIT SEVEN, right-left (need override)
+    0x00b8: 0x0668,     #  ARABIC-INDIC DIGIT EIGHT, right-left (need override)
+    0x00b9: 0x0669,     #  ARABIC-INDIC DIGIT NINE, right-left (need override)
+    0x00ba: 0x003a,     #  COLON, right-left
+    0x00bb: 0x061b,     #  ARABIC SEMICOLON
+    0x00bc: 0x003c,     #  LESS-THAN SIGN, right-left
+    0x00bd: 0x003d,     #  EQUALS SIGN, right-left
+    0x00be: 0x003e,     #  GREATER-THAN SIGN, right-left
+    0x00bf: 0x061f,     #  ARABIC QUESTION MARK
+    0x00c0: 0x274a,     #  EIGHT TEARDROP-SPOKED PROPELLER ASTERISK, right-left
+    0x00c1: 0x0621,     #  ARABIC LETTER HAMZA
+    0x00c2: 0x0622,     #  ARABIC LETTER ALEF WITH MADDA ABOVE
+    0x00c3: 0x0623,     #  ARABIC LETTER ALEF WITH HAMZA ABOVE
+    0x00c4: 0x0624,     #  ARABIC LETTER WAW WITH HAMZA ABOVE
+    0x00c5: 0x0625,     #  ARABIC LETTER ALEF WITH HAMZA BELOW
+    0x00c6: 0x0626,     #  ARABIC LETTER YEH WITH HAMZA ABOVE
+    0x00c7: 0x0627,     #  ARABIC LETTER ALEF
+    0x00c8: 0x0628,     #  ARABIC LETTER BEH
+    0x00c9: 0x0629,     #  ARABIC LETTER TEH MARBUTA
+    0x00ca: 0x062a,     #  ARABIC LETTER TEH
+    0x00cb: 0x062b,     #  ARABIC LETTER THEH
+    0x00cc: 0x062c,     #  ARABIC LETTER JEEM
+    0x00cd: 0x062d,     #  ARABIC LETTER HAH
+    0x00ce: 0x062e,     #  ARABIC LETTER KHAH
+    0x00cf: 0x062f,     #  ARABIC LETTER DAL
+    0x00d0: 0x0630,     #  ARABIC LETTER THAL
+    0x00d1: 0x0631,     #  ARABIC LETTER REH
+    0x00d2: 0x0632,     #  ARABIC LETTER ZAIN
+    0x00d3: 0x0633,     #  ARABIC LETTER SEEN
+    0x00d4: 0x0634,     #  ARABIC LETTER SHEEN
+    0x00d5: 0x0635,     #  ARABIC LETTER SAD
+    0x00d6: 0x0636,     #  ARABIC LETTER DAD
+    0x00d7: 0x0637,     #  ARABIC LETTER TAH
+    0x00d8: 0x0638,     #  ARABIC LETTER ZAH
+    0x00d9: 0x0639,     #  ARABIC LETTER AIN
+    0x00da: 0x063a,     #  ARABIC LETTER GHAIN
+    0x00db: 0x005b,     #  LEFT SQUARE BRACKET, right-left
+    0x00dc: 0x005c,     #  REVERSE SOLIDUS, right-left
+    0x00dd: 0x005d,     #  RIGHT SQUARE BRACKET, right-left
+    0x00de: 0x005e,     #  CIRCUMFLEX ACCENT, right-left
+    0x00df: 0x005f,     #  LOW LINE, right-left
+    0x00e0: 0x0640,     #  ARABIC TATWEEL
+    0x00e1: 0x0641,     #  ARABIC LETTER FEH
+    0x00e2: 0x0642,     #  ARABIC LETTER QAF
+    0x00e3: 0x0643,     #  ARABIC LETTER KAF
+    0x00e4: 0x0644,     #  ARABIC LETTER LAM
+    0x00e5: 0x0645,     #  ARABIC LETTER MEEM
+    0x00e6: 0x0646,     #  ARABIC LETTER NOON
+    0x00e7: 0x0647,     #  ARABIC LETTER HEH
+    0x00e8: 0x0648,     #  ARABIC LETTER WAW
+    0x00e9: 0x0649,     #  ARABIC LETTER ALEF MAKSURA
+    0x00ea: 0x064a,     #  ARABIC LETTER YEH
+    0x00eb: 0x064b,     #  ARABIC FATHATAN
+    0x00ec: 0x064c,     #  ARABIC DAMMATAN
+    0x00ed: 0x064d,     #  ARABIC KASRATAN
+    0x00ee: 0x064e,     #  ARABIC FATHA
+    0x00ef: 0x064f,     #  ARABIC DAMMA
+    0x00f0: 0x0650,     #  ARABIC KASRA
+    0x00f1: 0x0651,     #  ARABIC SHADDA
+    0x00f2: 0x0652,     #  ARABIC SUKUN
+    0x00f3: 0x067e,     #  ARABIC LETTER PEH
+    0x00f4: 0x0679,     #  ARABIC LETTER TTEH
+    0x00f5: 0x0686,     #  ARABIC LETTER TCHEH
+    0x00f6: 0x06d5,     #  ARABIC LETTER AE
+    0x00f7: 0x06a4,     #  ARABIC LETTER VEH
+    0x00f8: 0x06af,     #  ARABIC LETTER GAF
+    0x00f9: 0x0688,     #  ARABIC LETTER DDAL
+    0x00fa: 0x0691,     #  ARABIC LETTER RREH
+    0x00fb: 0x007b,     #  LEFT CURLY BRACKET, right-left
+    0x00fc: 0x007c,     #  VERTICAL LINE, right-left
+    0x00fd: 0x007d,     #  RIGHT CURLY BRACKET, right-left
+    0x00fe: 0x0698,     #  ARABIC LETTER JEH
+    0x00ff: 0x06d2,     #  ARABIC LETTER YEH BARREE
+})
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x0000 -> CONTROL CHARACTER
+    u'\x01'     #  0x0001 -> CONTROL CHARACTER
+    u'\x02'     #  0x0002 -> CONTROL CHARACTER
+    u'\x03'     #  0x0003 -> CONTROL CHARACTER
+    u'\x04'     #  0x0004 -> CONTROL CHARACTER
+    u'\x05'     #  0x0005 -> CONTROL CHARACTER
+    u'\x06'     #  0x0006 -> CONTROL CHARACTER
+    u'\x07'     #  0x0007 -> CONTROL CHARACTER
+    u'\x08'     #  0x0008 -> CONTROL CHARACTER
+    u'\t'       #  0x0009 -> CONTROL CHARACTER
+    u'\n'       #  0x000a -> CONTROL CHARACTER
+    u'\x0b'     #  0x000b -> CONTROL CHARACTER
+    u'\x0c'     #  0x000c -> CONTROL CHARACTER
+    u'\r'       #  0x000d -> CONTROL CHARACTER
+    u'\x0e'     #  0x000e -> CONTROL CHARACTER
+    u'\x0f'     #  0x000f -> CONTROL CHARACTER
+    u'\x10'     #  0x0010 -> CONTROL CHARACTER
+    u'\x11'     #  0x0011 -> CONTROL CHARACTER
+    u'\x12'     #  0x0012 -> CONTROL CHARACTER
+    u'\x13'     #  0x0013 -> CONTROL CHARACTER
+    u'\x14'     #  0x0014 -> CONTROL CHARACTER
+    u'\x15'     #  0x0015 -> CONTROL CHARACTER
+    u'\x16'     #  0x0016 -> CONTROL CHARACTER
+    u'\x17'     #  0x0017 -> CONTROL CHARACTER
+    u'\x18'     #  0x0018 -> CONTROL CHARACTER
+    u'\x19'     #  0x0019 -> CONTROL CHARACTER
+    u'\x1a'     #  0x001a -> CONTROL CHARACTER
+    u'\x1b'     #  0x001b -> CONTROL CHARACTER
+    u'\x1c'     #  0x001c -> CONTROL CHARACTER
+    u'\x1d'     #  0x001d -> CONTROL CHARACTER
+    u'\x1e'     #  0x001e -> CONTROL CHARACTER
+    u'\x1f'     #  0x001f -> CONTROL CHARACTER
+    u' '        #  0x0020 -> SPACE, left-right
+    u'!'        #  0x0021 -> EXCLAMATION MARK, left-right
+    u'"'        #  0x0022 -> QUOTATION MARK, left-right
+    u'#'        #  0x0023 -> NUMBER SIGN, left-right
+    u'$'        #  0x0024 -> DOLLAR SIGN, left-right
+    u'%'        #  0x0025 -> PERCENT SIGN, left-right
+    u'&'        #  0x0026 -> AMPERSAND, left-right
+    u"'"        #  0x0027 -> APOSTROPHE, left-right
+    u'('        #  0x0028 -> LEFT PARENTHESIS, left-right
+    u')'        #  0x0029 -> RIGHT PARENTHESIS, left-right
+    u'*'        #  0x002a -> ASTERISK, left-right
+    u'+'        #  0x002b -> PLUS SIGN, left-right
+    u','        #  0x002c -> COMMA, left-right; in Arabic-script context, displayed as 0x066C ARABIC THOUSANDS SEPARATOR
+    u'-'        #  0x002d -> HYPHEN-MINUS, left-right
+    u'.'        #  0x002e -> FULL STOP, left-right; in Arabic-script context, displayed as 0x066B ARABIC DECIMAL SEPARATOR
+    u'/'        #  0x002f -> SOLIDUS, left-right
+    u'0'        #  0x0030 -> DIGIT ZERO;  in Arabic-script context, displayed as 0x0660 ARABIC-INDIC DIGIT ZERO
+    u'1'        #  0x0031 -> DIGIT ONE;   in Arabic-script context, displayed as 0x0661 ARABIC-INDIC DIGIT ONE
+    u'2'        #  0x0032 -> DIGIT TWO;   in Arabic-script context, displayed as 0x0662 ARABIC-INDIC DIGIT TWO
+    u'3'        #  0x0033 -> DIGIT THREE; in Arabic-script context, displayed as 0x0663 ARABIC-INDIC DIGIT THREE
+    u'4'        #  0x0034 -> DIGIT FOUR;  in Arabic-script context, displayed as 0x0664 ARABIC-INDIC DIGIT FOUR
+    u'5'        #  0x0035 -> DIGIT FIVE;  in Arabic-script context, displayed as 0x0665 ARABIC-INDIC DIGIT FIVE
+    u'6'        #  0x0036 -> DIGIT SIX;   in Arabic-script context, displayed as 0x0666 ARABIC-INDIC DIGIT SIX
+    u'7'        #  0x0037 -> DIGIT SEVEN; in Arabic-script context, displayed as 0x0667 ARABIC-INDIC DIGIT SEVEN
+    u'8'        #  0x0038 -> DIGIT EIGHT; in Arabic-script context, displayed as 0x0668 ARABIC-INDIC DIGIT EIGHT
+    u'9'        #  0x0039 -> DIGIT NINE;  in Arabic-script context, displayed as 0x0669 ARABIC-INDIC DIGIT NINE
+    u':'        #  0x003a -> COLON, left-right
+    u';'        #  0x003b -> SEMICOLON, left-right
+    u'<'        #  0x003c -> LESS-THAN SIGN, left-right
+    u'='        #  0x003d -> EQUALS SIGN, left-right
+    u'>'        #  0x003e -> GREATER-THAN SIGN, left-right
+    u'?'        #  0x003f -> QUESTION MARK, left-right
+    u'@'        #  0x0040 -> COMMERCIAL AT
+    u'A'        #  0x0041 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x0042 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x0043 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x0044 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x0045 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x0046 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x0047 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x0048 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x0049 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x004a -> LATIN CAPITAL LETTER J
+    u'K'        #  0x004b -> LATIN CAPITAL LETTER K
+    u'L'        #  0x004c -> LATIN CAPITAL LETTER L
+    u'M'        #  0x004d -> LATIN CAPITAL LETTER M
+    u'N'        #  0x004e -> LATIN CAPITAL LETTER N
+    u'O'        #  0x004f -> LATIN CAPITAL LETTER O
+    u'P'        #  0x0050 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x0051 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x0052 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x0053 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x0054 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x0055 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x0056 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x0057 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x0058 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x0059 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x005a -> LATIN CAPITAL LETTER Z
+    u'['        #  0x005b -> LEFT SQUARE BRACKET, left-right
+    u'\\'       #  0x005c -> REVERSE SOLIDUS, left-right
+    u']'        #  0x005d -> RIGHT SQUARE BRACKET, left-right
+    u'^'        #  0x005e -> CIRCUMFLEX ACCENT, left-right
+    u'_'        #  0x005f -> LOW LINE, left-right
+    u'`'        #  0x0060 -> GRAVE ACCENT
+    u'a'        #  0x0061 -> LATIN SMALL LETTER A
+    u'b'        #  0x0062 -> LATIN SMALL LETTER B
+    u'c'        #  0x0063 -> LATIN SMALL LETTER C
+    u'd'        #  0x0064 -> LATIN SMALL LETTER D
+    u'e'        #  0x0065 -> LATIN SMALL LETTER E
+    u'f'        #  0x0066 -> LATIN SMALL LETTER F
+    u'g'        #  0x0067 -> LATIN SMALL LETTER G
+    u'h'        #  0x0068 -> LATIN SMALL LETTER H
+    u'i'        #  0x0069 -> LATIN SMALL LETTER I
+    u'j'        #  0x006a -> LATIN SMALL LETTER J
+    u'k'        #  0x006b -> LATIN SMALL LETTER K
+    u'l'        #  0x006c -> LATIN SMALL LETTER L
+    u'm'        #  0x006d -> LATIN SMALL LETTER M
+    u'n'        #  0x006e -> LATIN SMALL LETTER N
+    u'o'        #  0x006f -> LATIN SMALL LETTER O
+    u'p'        #  0x0070 -> LATIN SMALL LETTER P
+    u'q'        #  0x0071 -> LATIN SMALL LETTER Q
+    u'r'        #  0x0072 -> LATIN SMALL LETTER R
+    u's'        #  0x0073 -> LATIN SMALL LETTER S
+    u't'        #  0x0074 -> LATIN SMALL LETTER T
+    u'u'        #  0x0075 -> LATIN SMALL LETTER U
+    u'v'        #  0x0076 -> LATIN SMALL LETTER V
+    u'w'        #  0x0077 -> LATIN SMALL LETTER W
+    u'x'        #  0x0078 -> LATIN SMALL LETTER X
+    u'y'        #  0x0079 -> LATIN SMALL LETTER Y
+    u'z'        #  0x007a -> LATIN SMALL LETTER Z
+    u'{'        #  0x007b -> LEFT CURLY BRACKET, left-right
+    u'|'        #  0x007c -> VERTICAL LINE, left-right
+    u'}'        #  0x007d -> RIGHT CURLY BRACKET, left-right
+    u'~'        #  0x007e -> TILDE
+    u'\x7f'     #  0x007f -> CONTROL CHARACTER
+    u'\xc4'     #  0x0080 -> LATIN CAPITAL LETTER A WITH DIAERESIS
+    u'\xa0'     #  0x0081 -> NO-BREAK SPACE, right-left
+    u'\xc7'     #  0x0082 -> LATIN CAPITAL LETTER C WITH CEDILLA
+    u'\xc9'     #  0x0083 -> LATIN CAPITAL LETTER E WITH ACUTE
+    u'\xd1'     #  0x0084 -> LATIN CAPITAL LETTER N WITH TILDE
+    u'\xd6'     #  0x0085 -> LATIN CAPITAL LETTER O WITH DIAERESIS
+    u'\xdc'     #  0x0086 -> LATIN CAPITAL LETTER U WITH DIAERESIS
+    u'\xe1'     #  0x0087 -> LATIN SMALL LETTER A WITH ACUTE
+    u'\xe0'     #  0x0088 -> LATIN SMALL LETTER A WITH GRAVE
+    u'\xe2'     #  0x0089 -> LATIN SMALL LETTER A WITH CIRCUMFLEX
+    u'\xe4'     #  0x008a -> LATIN SMALL LETTER A WITH DIAERESIS
+    u'\u06ba'   #  0x008b -> ARABIC LETTER NOON GHUNNA
+    u'\xab'     #  0x008c -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK, right-left
+    u'\xe7'     #  0x008d -> LATIN SMALL LETTER C WITH CEDILLA
+    u'\xe9'     #  0x008e -> LATIN SMALL LETTER E WITH ACUTE
+    u'\xe8'     #  0x008f -> LATIN SMALL LETTER E WITH GRAVE
+    u'\xea'     #  0x0090 -> LATIN SMALL LETTER E WITH CIRCUMFLEX
+    u'\xeb'     #  0x0091 -> LATIN SMALL LETTER E WITH DIAERESIS
+    u'\xed'     #  0x0092 -> LATIN SMALL LETTER I WITH ACUTE
+    u'\u2026'   #  0x0093 -> HORIZONTAL ELLIPSIS, right-left
+    u'\xee'     #  0x0094 -> LATIN SMALL LETTER I WITH CIRCUMFLEX
+    u'\xef'     #  0x0095 -> LATIN SMALL LETTER I WITH DIAERESIS
+    u'\xf1'     #  0x0096 -> LATIN SMALL LETTER N WITH TILDE
+    u'\xf3'     #  0x0097 -> LATIN SMALL LETTER O WITH ACUTE
+    u'\xbb'     #  0x0098 -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK, right-left
+    u'\xf4'     #  0x0099 -> LATIN SMALL LETTER O WITH CIRCUMFLEX
+    u'\xf6'     #  0x009a -> LATIN SMALL LETTER O WITH DIAERESIS
+    u'\xf7'     #  0x009b -> DIVISION SIGN, right-left
+    u'\xfa'     #  0x009c -> LATIN SMALL LETTER U WITH ACUTE
+    u'\xf9'     #  0x009d -> LATIN SMALL LETTER U WITH GRAVE
+    u'\xfb'     #  0x009e -> LATIN SMALL LETTER U WITH CIRCUMFLEX
+    u'\xfc'     #  0x009f -> LATIN SMALL LETTER U WITH DIAERESIS
+    u' '        #  0x00a0 -> SPACE, right-left
+    u'!'        #  0x00a1 -> EXCLAMATION MARK, right-left
+    u'"'        #  0x00a2 -> QUOTATION MARK, right-left
+    u'#'        #  0x00a3 -> NUMBER SIGN, right-left
+    u'$'        #  0x00a4 -> DOLLAR SIGN, right-left
+    u'\u066a'   #  0x00a5 -> ARABIC PERCENT SIGN
+    u'&'        #  0x00a6 -> AMPERSAND, right-left
+    u"'"        #  0x00a7 -> APOSTROPHE, right-left
+    u'('        #  0x00a8 -> LEFT PARENTHESIS, right-left
+    u')'        #  0x00a9 -> RIGHT PARENTHESIS, right-left
+    u'*'        #  0x00aa -> ASTERISK, right-left
+    u'+'        #  0x00ab -> PLUS SIGN, right-left
+    u'\u060c'   #  0x00ac -> ARABIC COMMA
+    u'-'        #  0x00ad -> HYPHEN-MINUS, right-left
+    u'.'        #  0x00ae -> FULL STOP, right-left
+    u'/'        #  0x00af -> SOLIDUS, right-left
+    u'\u0660'   #  0x00b0 -> ARABIC-INDIC DIGIT ZERO, right-left (need override)
+    u'\u0661'   #  0x00b1 -> ARABIC-INDIC DIGIT ONE, right-left (need override)
+    u'\u0662'   #  0x00b2 -> ARABIC-INDIC DIGIT TWO, right-left (need override)
+    u'\u0663'   #  0x00b3 -> ARABIC-INDIC DIGIT THREE, right-left (need override)
+    u'\u0664'   #  0x00b4 -> ARABIC-INDIC DIGIT FOUR, right-left (need override)
+    u'\u0665'   #  0x00b5 -> ARABIC-INDIC DIGIT FIVE, right-left (need override)
+    u'\u0666'   #  0x00b6 -> ARABIC-INDIC DIGIT SIX, right-left (need override)
+    u'\u0667'   #  0x00b7 -> ARABIC-INDIC DIGIT SEVEN, right-left (need override)
+    u'\u0668'   #  0x00b8 -> ARABIC-INDIC DIGIT EIGHT, right-left (need override)
+    u'\u0669'   #  0x00b9 -> ARABIC-INDIC DIGIT NINE, right-left (need override)
+    u':'        #  0x00ba -> COLON, right-left
+    u'\u061b'   #  0x00bb -> ARABIC SEMICOLON
+    u'<'        #  0x00bc -> LESS-THAN SIGN, right-left
+    u'='        #  0x00bd -> EQUALS SIGN, right-left
+    u'>'        #  0x00be -> GREATER-THAN SIGN, right-left
+    u'\u061f'   #  0x00bf -> ARABIC QUESTION MARK
+    u'\u274a'   #  0x00c0 -> EIGHT TEARDROP-SPOKED PROPELLER ASTERISK, right-left
+    u'\u0621'   #  0x00c1 -> ARABIC LETTER HAMZA
+    u'\u0622'   #  0x00c2 -> ARABIC LETTER ALEF WITH MADDA ABOVE
+    u'\u0623'   #  0x00c3 -> ARABIC LETTER ALEF WITH HAMZA ABOVE
+    u'\u0624'   #  0x00c4 -> ARABIC LETTER WAW WITH HAMZA ABOVE
+    u'\u0625'   #  0x00c5 -> ARABIC LETTER ALEF WITH HAMZA BELOW
+    u'\u0626'   #  0x00c6 -> ARABIC LETTER YEH WITH HAMZA ABOVE
+    u'\u0627'   #  0x00c7 -> ARABIC LETTER ALEF
+    u'\u0628'   #  0x00c8 -> ARABIC LETTER BEH
+    u'\u0629'   #  0x00c9 -> ARABIC LETTER TEH MARBUTA
+    u'\u062a'   #  0x00ca -> ARABIC LETTER TEH
+    u'\u062b'   #  0x00cb -> ARABIC LETTER THEH
+    u'\u062c'   #  0x00cc -> ARABIC LETTER JEEM
+    u'\u062d'   #  0x00cd -> ARABIC LETTER HAH
+    u'\u062e'   #  0x00ce -> ARABIC LETTER KHAH
+    u'\u062f'   #  0x00cf -> ARABIC LETTER DAL
+    u'\u0630'   #  0x00d0 -> ARABIC LETTER THAL
+    u'\u0631'   #  0x00d1 -> ARABIC LETTER REH
+    u'\u0632'   #  0x00d2 -> ARABIC LETTER ZAIN
+    u'\u0633'   #  0x00d3 -> ARABIC LETTER SEEN
+    u'\u0634'   #  0x00d4 -> ARABIC LETTER SHEEN
+    u'\u0635'   #  0x00d5 -> ARABIC LETTER SAD
+    u'\u0636'   #  0x00d6 -> ARABIC LETTER DAD
+    u'\u0637'   #  0x00d7 -> ARABIC LETTER TAH
+    u'\u0638'   #  0x00d8 -> ARABIC LETTER ZAH
+    u'\u0639'   #  0x00d9 -> ARABIC LETTER AIN
+    u'\u063a'   #  0x00da -> ARABIC LETTER GHAIN
+    u'['        #  0x00db -> LEFT SQUARE BRACKET, right-left
+    u'\\'       #  0x00dc -> REVERSE SOLIDUS, right-left
+    u']'        #  0x00dd -> RIGHT SQUARE BRACKET, right-left
+    u'^'        #  0x00de -> CIRCUMFLEX ACCENT, right-left
+    u'_'        #  0x00df -> LOW LINE, right-left
+    u'\u0640'   #  0x00e0 -> ARABIC TATWEEL
+    u'\u0641'   #  0x00e1 -> ARABIC LETTER FEH
+    u'\u0642'   #  0x00e2 -> ARABIC LETTER QAF
+    u'\u0643'   #  0x00e3 -> ARABIC LETTER KAF
+    u'\u0644'   #  0x00e4 -> ARABIC LETTER LAM
+    u'\u0645'   #  0x00e5 -> ARABIC LETTER MEEM
+    u'\u0646'   #  0x00e6 -> ARABIC LETTER NOON
+    u'\u0647'   #  0x00e7 -> ARABIC LETTER HEH
+    u'\u0648'   #  0x00e8 -> ARABIC LETTER WAW
+    u'\u0649'   #  0x00e9 -> ARABIC LETTER ALEF MAKSURA
+    u'\u064a'   #  0x00ea -> ARABIC LETTER YEH
+    u'\u064b'   #  0x00eb -> ARABIC FATHATAN
+    u'\u064c'   #  0x00ec -> ARABIC DAMMATAN
+    u'\u064d'   #  0x00ed -> ARABIC KASRATAN
+    u'\u064e'   #  0x00ee -> ARABIC FATHA
+    u'\u064f'   #  0x00ef -> ARABIC DAMMA
+    u'\u0650'   #  0x00f0 -> ARABIC KASRA
+    u'\u0651'   #  0x00f1 -> ARABIC SHADDA
+    u'\u0652'   #  0x00f2 -> ARABIC SUKUN
+    u'\u067e'   #  0x00f3 -> ARABIC LETTER PEH
+    u'\u0679'   #  0x00f4 -> ARABIC LETTER TTEH
+    u'\u0686'   #  0x00f5 -> ARABIC LETTER TCHEH
+    u'\u06d5'   #  0x00f6 -> ARABIC LETTER AE
+    u'\u06a4'   #  0x00f7 -> ARABIC LETTER VEH
+    u'\u06af'   #  0x00f8 -> ARABIC LETTER GAF
+    u'\u0688'   #  0x00f9 -> ARABIC LETTER DDAL
+    u'\u0691'   #  0x00fa -> ARABIC LETTER RREH
+    u'{'        #  0x00fb -> LEFT CURLY BRACKET, right-left
+    u'|'        #  0x00fc -> VERTICAL LINE, right-left
+    u'}'        #  0x00fd -> RIGHT CURLY BRACKET, right-left
+    u'\u0698'   #  0x00fe -> ARABIC LETTER JEH
+    u'\u06d2'   #  0x00ff -> ARABIC LETTER YEH BARREE
+)
+
+### Encoding Map
+
+encoding_map = {
+    0x0000: 0x0000,     #  CONTROL CHARACTER
+    0x0001: 0x0001,     #  CONTROL CHARACTER
+    0x0002: 0x0002,     #  CONTROL CHARACTER
+    0x0003: 0x0003,     #  CONTROL CHARACTER
+    0x0004: 0x0004,     #  CONTROL CHARACTER
+    0x0005: 0x0005,     #  CONTROL CHARACTER
+    0x0006: 0x0006,     #  CONTROL CHARACTER
+    0x0007: 0x0007,     #  CONTROL CHARACTER
+    0x0008: 0x0008,     #  CONTROL CHARACTER
+    0x0009: 0x0009,     #  CONTROL CHARACTER
+    0x000a: 0x000a,     #  CONTROL CHARACTER
+    0x000b: 0x000b,     #  CONTROL CHARACTER
+    0x000c: 0x000c,     #  CONTROL CHARACTER
+    0x000d: 0x000d,     #  CONTROL CHARACTER
+    0x000e: 0x000e,     #  CONTROL CHARACTER
+    0x000f: 0x000f,     #  CONTROL CHARACTER
+    0x0010: 0x0010,     #  CONTROL CHARACTER
+    0x0011: 0x0011,     #  CONTROL CHARACTER
+    0x0012: 0x0012,     #  CONTROL CHARACTER
+    0x0013: 0x0013,     #  CONTROL CHARACTER
+    0x0014: 0x0014,     #  CONTROL CHARACTER
+    0x0015: 0x0015,     #  CONTROL CHARACTER
+    0x0016: 0x0016,     #  CONTROL CHARACTER
+    0x0017: 0x0017,     #  CONTROL CHARACTER
+    0x0018: 0x0018,     #  CONTROL CHARACTER
+    0x0019: 0x0019,     #  CONTROL CHARACTER
+    0x001a: 0x001a,     #  CONTROL CHARACTER
+    0x001b: 0x001b,     #  CONTROL CHARACTER
+    0x001c: 0x001c,     #  CONTROL CHARACTER
+    0x001d: 0x001d,     #  CONTROL CHARACTER
+    0x001e: 0x001e,     #  CONTROL CHARACTER
+    0x001f: 0x001f,     #  CONTROL CHARACTER
+    0x0020: 0x0020,     #  SPACE, left-right
+    0x0020: 0x00a0,     #  SPACE, right-left
+    0x0021: 0x0021,     #  EXCLAMATION MARK, left-right
+    0x0021: 0x00a1,     #  EXCLAMATION MARK, right-left
+    0x0022: 0x0022,     #  QUOTATION MARK, left-right
+    0x0022: 0x00a2,     #  QUOTATION MARK, right-left
+    0x0023: 0x0023,     #  NUMBER SIGN, left-right
+    0x0023: 0x00a3,     #  NUMBER SIGN, right-left
+    0x0024: 0x0024,     #  DOLLAR SIGN, left-right
+    0x0024: 0x00a4,     #  DOLLAR SIGN, right-left
+    0x0025: 0x0025,     #  PERCENT SIGN, left-right
+    0x0026: 0x0026,     #  AMPERSAND, left-right
+    0x0026: 0x00a6,     #  AMPERSAND, right-left
+    0x0027: 0x0027,     #  APOSTROPHE, left-right
+    0x0027: 0x00a7,     #  APOSTROPHE, right-left
+    0x0028: 0x0028,     #  LEFT PARENTHESIS, left-right
+    0x0028: 0x00a8,     #  LEFT PARENTHESIS, right-left
+    0x0029: 0x0029,     #  RIGHT PARENTHESIS, left-right
+    0x0029: 0x00a9,     #  RIGHT PARENTHESIS, right-left
+    0x002a: 0x002a,     #  ASTERISK, left-right
+    0x002a: 0x00aa,     #  ASTERISK, right-left
+    0x002b: 0x002b,     #  PLUS SIGN, left-right
+    0x002b: 0x00ab,     #  PLUS SIGN, right-left
+    0x002c: 0x002c,     #  COMMA, left-right; in Arabic-script context, displayed as 0x066C ARABIC THOUSANDS SEPARATOR
+    0x002d: 0x002d,     #  HYPHEN-MINUS, left-right
+    0x002d: 0x00ad,     #  HYPHEN-MINUS, right-left
+    0x002e: 0x002e,     #  FULL STOP, left-right; in Arabic-script context, displayed as 0x066B ARABIC DECIMAL SEPARATOR
+    0x002e: 0x00ae,     #  FULL STOP, right-left
+    0x002f: 0x002f,     #  SOLIDUS, left-right
+    0x002f: 0x00af,     #  SOLIDUS, right-left
+    0x0030: 0x0030,     #  DIGIT ZERO;  in Arabic-script context, displayed as 0x0660 ARABIC-INDIC DIGIT ZERO
+    0x0031: 0x0031,     #  DIGIT ONE;   in Arabic-script context, displayed as 0x0661 ARABIC-INDIC DIGIT ONE
+    0x0032: 0x0032,     #  DIGIT TWO;   in Arabic-script context, displayed as 0x0662 ARABIC-INDIC DIGIT TWO
+    0x0033: 0x0033,     #  DIGIT THREE; in Arabic-script context, displayed as 0x0663 ARABIC-INDIC DIGIT THREE
+    0x0034: 0x0034,     #  DIGIT FOUR;  in Arabic-script context, displayed as 0x0664 ARABIC-INDIC DIGIT FOUR
+    0x0035: 0x0035,     #  DIGIT FIVE;  in Arabic-script context, displayed as 0x0665 ARABIC-INDIC DIGIT FIVE
+    0x0036: 0x0036,     #  DIGIT SIX;   in Arabic-script context, displayed as 0x0666 ARABIC-INDIC DIGIT SIX
+    0x0037: 0x0037,     #  DIGIT SEVEN; in Arabic-script context, displayed as 0x0667 ARABIC-INDIC DIGIT SEVEN
+    0x0038: 0x0038,     #  DIGIT EIGHT; in Arabic-script context, displayed as 0x0668 ARABIC-INDIC DIGIT EIGHT
+    0x0039: 0x0039,     #  DIGIT NINE;  in Arabic-script context, displayed as 0x0669 ARABIC-INDIC DIGIT NINE
+    0x003a: 0x003a,     #  COLON, left-right
+    0x003a: 0x00ba,     #  COLON, right-left
+    0x003b: 0x003b,     #  SEMICOLON, left-right
+    0x003c: 0x003c,     #  LESS-THAN SIGN, left-right
+    0x003c: 0x00bc,     #  LESS-THAN SIGN, right-left
+    0x003d: 0x003d,     #  EQUALS SIGN, left-right
+    0x003d: 0x00bd,     #  EQUALS SIGN, right-left
+    0x003e: 0x003e,     #  GREATER-THAN SIGN, left-right
+    0x003e: 0x00be,     #  GREATER-THAN SIGN, right-left
+    0x003f: 0x003f,     #  QUESTION MARK, left-right
+    0x0040: 0x0040,     #  COMMERCIAL AT
+    0x0041: 0x0041,     #  LATIN CAPITAL LETTER A
+    0x0042: 0x0042,     #  LATIN CAPITAL LETTER B
+    0x0043: 0x0043,     #  LATIN CAPITAL LETTER C
+    0x0044: 0x0044,     #  LATIN CAPITAL LETTER D
+    0x0045: 0x0045,     #  LATIN CAPITAL LETTER E
+    0x0046: 0x0046,     #  LATIN CAPITAL LETTER F
+    0x0047: 0x0047,     #  LATIN CAPITAL LETTER G
+    0x0048: 0x0048,     #  LATIN CAPITAL LETTER H
+    0x0049: 0x0049,     #  LATIN CAPITAL LETTER I
+    0x004a: 0x004a,     #  LATIN CAPITAL LETTER J
+    0x004b: 0x004b,     #  LATIN CAPITAL LETTER K
+    0x004c: 0x004c,     #  LATIN CAPITAL LETTER L
+    0x004d: 0x004d,     #  LATIN CAPITAL LETTER M
+    0x004e: 0x004e,     #  LATIN CAPITAL LETTER N
+    0x004f: 0x004f,     #  LATIN CAPITAL LETTER O
+    0x0050: 0x0050,     #  LATIN CAPITAL LETTER P
+    0x0051: 0x0051,     #  LATIN CAPITAL LETTER Q
+    0x0052: 0x0052,     #  LATIN CAPITAL LETTER R
+    0x0053: 0x0053,     #  LATIN CAPITAL LETTER S
+    0x0054: 0x0054,     #  LATIN CAPITAL LETTER T
+    0x0055: 0x0055,     #  LATIN CAPITAL LETTER U
+    0x0056: 0x0056,     #  LATIN CAPITAL LETTER V
+    0x0057: 0x0057,     #  LATIN CAPITAL LETTER W
+    0x0058: 0x0058,     #  LATIN CAPITAL LETTER X
+    0x0059: 0x0059,     #  LATIN CAPITAL LETTER Y
+    0x005a: 0x005a,     #  LATIN CAPITAL LETTER Z
+    0x005b: 0x005b,     #  LEFT SQUARE BRACKET, left-right
+    0x005b: 0x00db,     #  LEFT SQUARE BRACKET, right-left
+    0x005c: 0x005c,     #  REVERSE SOLIDUS, left-right
+    0x005c: 0x00dc,     #  REVERSE SOLIDUS, right-left
+    0x005d: 0x005d,     #  RIGHT SQUARE BRACKET, left-right
+    0x005d: 0x00dd,     #  RIGHT SQUARE BRACKET, right-left
+    0x005e: 0x005e,     #  CIRCUMFLEX ACCENT, left-right
+    0x005e: 0x00de,     #  CIRCUMFLEX ACCENT, right-left
+    0x005f: 0x005f,     #  LOW LINE, left-right
+    0x005f: 0x00df,     #  LOW LINE, right-left
+    0x0060: 0x0060,     #  GRAVE ACCENT
+    0x0061: 0x0061,     #  LATIN SMALL LETTER A
+    0x0062: 0x0062,     #  LATIN SMALL LETTER B
+    0x0063: 0x0063,     #  LATIN SMALL LETTER C
+    0x0064: 0x0064,     #  LATIN SMALL LETTER D
+    0x0065: 0x0065,     #  LATIN SMALL LETTER E
+    0x0066: 0x0066,     #  LATIN SMALL LETTER F
+    0x0067: 0x0067,     #  LATIN SMALL LETTER G
+    0x0068: 0x0068,     #  LATIN SMALL LETTER H
+    0x0069: 0x0069,     #  LATIN SMALL LETTER I
+    0x006a: 0x006a,     #  LATIN SMALL LETTER J
+    0x006b: 0x006b,     #  LATIN SMALL LETTER K
+    0x006c: 0x006c,     #  LATIN SMALL LETTER L
+    0x006d: 0x006d,     #  LATIN SMALL LETTER M
+    0x006e: 0x006e,     #  LATIN SMALL LETTER N
+    0x006f: 0x006f,     #  LATIN SMALL LETTER O
+    0x0070: 0x0070,     #  LATIN SMALL LETTER P
+    0x0071: 0x0071,     #  LATIN SMALL LETTER Q
+    0x0072: 0x0072,     #  LATIN SMALL LETTER R
+    0x0073: 0x0073,     #  LATIN SMALL LETTER S
+    0x0074: 0x0074,     #  LATIN SMALL LETTER T
+    0x0075: 0x0075,     #  LATIN SMALL LETTER U
+    0x0076: 0x0076,     #  LATIN SMALL LETTER V
+    0x0077: 0x0077,     #  LATIN SMALL LETTER W
+    0x0078: 0x0078,     #  LATIN SMALL LETTER X
+    0x0079: 0x0079,     #  LATIN SMALL LETTER Y
+    0x007a: 0x007a,     #  LATIN SMALL LETTER Z
+    0x007b: 0x007b,     #  LEFT CURLY BRACKET, left-right
+    0x007b: 0x00fb,     #  LEFT CURLY BRACKET, right-left
+    0x007c: 0x007c,     #  VERTICAL LINE, left-right
+    0x007c: 0x00fc,     #  VERTICAL LINE, right-left
+    0x007d: 0x007d,     #  RIGHT CURLY BRACKET, left-right
+    0x007d: 0x00fd,     #  RIGHT CURLY BRACKET, right-left
+    0x007e: 0x007e,     #  TILDE
+    0x007f: 0x007f,     #  CONTROL CHARACTER
+    0x00a0: 0x0081,     #  NO-BREAK SPACE, right-left
+    0x00ab: 0x008c,     #  LEFT-POINTING DOUBLE ANGLE QUOTATION MARK, right-left
+    0x00bb: 0x0098,     #  RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK, right-left
+    0x00c4: 0x0080,     #  LATIN CAPITAL LETTER A WITH DIAERESIS
+    0x00c7: 0x0082,     #  LATIN CAPITAL LETTER C WITH CEDILLA
+    0x00c9: 0x0083,     #  LATIN CAPITAL LETTER E WITH ACUTE
+    0x00d1: 0x0084,     #  LATIN CAPITAL LETTER N WITH TILDE
+    0x00d6: 0x0085,     #  LATIN CAPITAL LETTER O WITH DIAERESIS
+    0x00dc: 0x0086,     #  LATIN CAPITAL LETTER U WITH DIAERESIS
+    0x00e0: 0x0088,     #  LATIN SMALL LETTER A WITH GRAVE
+    0x00e1: 0x0087,     #  LATIN SMALL LETTER A WITH ACUTE
+    0x00e2: 0x0089,     #  LATIN SMALL LETTER A WITH CIRCUMFLEX
+    0x00e4: 0x008a,     #  LATIN SMALL LETTER A WITH DIAERESIS
+    0x00e7: 0x008d,     #  LATIN SMALL LETTER C WITH CEDILLA
+    0x00e8: 0x008f,     #  LATIN SMALL LETTER E WITH GRAVE
+    0x00e9: 0x008e,     #  LATIN SMALL LETTER E WITH ACUTE
+    0x00ea: 0x0090,     #  LATIN SMALL LETTER E WITH CIRCUMFLEX
+    0x00eb: 0x0091,     #  LATIN SMALL LETTER E WITH DIAERESIS
+    0x00ed: 0x0092,     #  LATIN SMALL LETTER I WITH ACUTE
+    0x00ee: 0x0094,     #  LATIN SMALL LETTER I WITH CIRCUMFLEX
+    0x00ef: 0x0095,     #  LATIN SMALL LETTER I WITH DIAERESIS
+    0x00f1: 0x0096,     #  LATIN SMALL LETTER N WITH TILDE
+    0x00f3: 0x0097,     #  LATIN SMALL LETTER O WITH ACUTE
+    0x00f4: 0x0099,     #  LATIN SMALL LETTER O WITH CIRCUMFLEX
+    0x00f6: 0x009a,     #  LATIN SMALL LETTER O WITH DIAERESIS
+    0x00f7: 0x009b,     #  DIVISION SIGN, right-left
+    0x00f9: 0x009d,     #  LATIN SMALL LETTER U WITH GRAVE
+    0x00fa: 0x009c,     #  LATIN SMALL LETTER U WITH ACUTE
+    0x00fb: 0x009e,     #  LATIN SMALL LETTER U WITH CIRCUMFLEX
+    0x00fc: 0x009f,     #  LATIN SMALL LETTER U WITH DIAERESIS
+    0x060c: 0x00ac,     #  ARABIC COMMA
+    0x061b: 0x00bb,     #  ARABIC SEMICOLON
+    0x061f: 0x00bf,     #  ARABIC QUESTION MARK
+    0x0621: 0x00c1,     #  ARABIC LETTER HAMZA
+    0x0622: 0x00c2,     #  ARABIC LETTER ALEF WITH MADDA ABOVE
+    0x0623: 0x00c3,     #  ARABIC LETTER ALEF WITH HAMZA ABOVE
+    0x0624: 0x00c4,     #  ARABIC LETTER WAW WITH HAMZA ABOVE
+    0x0625: 0x00c5,     #  ARABIC LETTER ALEF WITH HAMZA BELOW
+    0x0626: 0x00c6,     #  ARABIC LETTER YEH WITH HAMZA ABOVE
+    0x0627: 0x00c7,     #  ARABIC LETTER ALEF
+    0x0628: 0x00c8,     #  ARABIC LETTER BEH
+    0x0629: 0x00c9,     #  ARABIC LETTER TEH MARBUTA
+    0x062a: 0x00ca,     #  ARABIC LETTER TEH
+    0x062b: 0x00cb,     #  ARABIC LETTER THEH
+    0x062c: 0x00cc,     #  ARABIC LETTER JEEM
+    0x062d: 0x00cd,     #  ARABIC LETTER HAH
+    0x062e: 0x00ce,     #  ARABIC LETTER KHAH
+    0x062f: 0x00cf,     #  ARABIC LETTER DAL
+    0x0630: 0x00d0,     #  ARABIC LETTER THAL
+    0x0631: 0x00d1,     #  ARABIC LETTER REH
+    0x0632: 0x00d2,     #  ARABIC LETTER ZAIN
+    0x0633: 0x00d3,     #  ARABIC LETTER SEEN
+    0x0634: 0x00d4,     #  ARABIC LETTER SHEEN
+    0x0635: 0x00d5,     #  ARABIC LETTER SAD
+    0x0636: 0x00d6,     #  ARABIC LETTER DAD
+    0x0637: 0x00d7,     #  ARABIC LETTER TAH
+    0x0638: 0x00d8,     #  ARABIC LETTER ZAH
+    0x0639: 0x00d9,     #  ARABIC LETTER AIN
+    0x063a: 0x00da,     #  ARABIC LETTER GHAIN
+    0x0640: 0x00e0,     #  ARABIC TATWEEL
+    0x0641: 0x00e1,     #  ARABIC LETTER FEH
+    0x0642: 0x00e2,     #  ARABIC LETTER QAF
+    0x0643: 0x00e3,     #  ARABIC LETTER KAF
+    0x0644: 0x00e4,     #  ARABIC LETTER LAM
+    0x0645: 0x00e5,     #  ARABIC LETTER MEEM
+    0x0646: 0x00e6,     #  ARABIC LETTER NOON
+    0x0647: 0x00e7,     #  ARABIC LETTER HEH
+    0x0648: 0x00e8,     #  ARABIC LETTER WAW
+    0x0649: 0x00e9,     #  ARABIC LETTER ALEF MAKSURA
+    0x064a: 0x00ea,     #  ARABIC LETTER YEH
+    0x064b: 0x00eb,     #  ARABIC FATHATAN
+    0x064c: 0x00ec,     #  ARABIC DAMMATAN
+    0x064d: 0x00ed,     #  ARABIC KASRATAN
+    0x064e: 0x00ee,     #  ARABIC FATHA
+    0x064f: 0x00ef,     #  ARABIC DAMMA
+    0x0650: 0x00f0,     #  ARABIC KASRA
+    0x0651: 0x00f1,     #  ARABIC SHADDA
+    0x0652: 0x00f2,     #  ARABIC SUKUN
+    0x0660: 0x00b0,     #  ARABIC-INDIC DIGIT ZERO, right-left (need override)
+    0x0661: 0x00b1,     #  ARABIC-INDIC DIGIT ONE, right-left (need override)
+    0x0662: 0x00b2,     #  ARABIC-INDIC DIGIT TWO, right-left (need override)
+    0x0663: 0x00b3,     #  ARABIC-INDIC DIGIT THREE, right-left (need override)
+    0x0664: 0x00b4,     #  ARABIC-INDIC DIGIT FOUR, right-left (need override)
+    0x0665: 0x00b5,     #  ARABIC-INDIC DIGIT FIVE, right-left (need override)
+    0x0666: 0x00b6,     #  ARABIC-INDIC DIGIT SIX, right-left (need override)
+    0x0667: 0x00b7,     #  ARABIC-INDIC DIGIT SEVEN, right-left (need override)
+    0x0668: 0x00b8,     #  ARABIC-INDIC DIGIT EIGHT, right-left (need override)
+    0x0669: 0x00b9,     #  ARABIC-INDIC DIGIT NINE, right-left (need override)
+    0x066a: 0x00a5,     #  ARABIC PERCENT SIGN
+    0x0679: 0x00f4,     #  ARABIC LETTER TTEH
+    0x067e: 0x00f3,     #  ARABIC LETTER PEH
+    0x0686: 0x00f5,     #  ARABIC LETTER TCHEH
+    0x0688: 0x00f9,     #  ARABIC LETTER DDAL
+    0x0691: 0x00fa,     #  ARABIC LETTER RREH
+    0x0698: 0x00fe,     #  ARABIC LETTER JEH
+    0x06a4: 0x00f7,     #  ARABIC LETTER VEH
+    0x06af: 0x00f8,     #  ARABIC LETTER GAF
+    0x06ba: 0x008b,     #  ARABIC LETTER NOON GHUNNA
+    0x06d2: 0x00ff,     #  ARABIC LETTER YEH BARREE
+    0x06d5: 0x00f6,     #  ARABIC LETTER AE
+    0x2026: 0x0093,     #  HORIZONTAL ELLIPSIS, right-left
+    0x274a: 0x00c0,     #  EIGHT TEARDROP-SPOKED PROPELLER ASTERISK, right-left
+}

Added: vendor/Python/current/Lib/encodings/mac_centeuro.py
===================================================================
--- vendor/Python/current/Lib/encodings/mac_centeuro.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/mac_centeuro.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,307 @@
+""" Python Character Mapping Codec mac_centeuro generated from 'MAPPINGS/VENDORS/APPLE/CENTEURO.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_table)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_table)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='mac-centeuro',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x00 -> CONTROL CHARACTER
+    u'\x01'     #  0x01 -> CONTROL CHARACTER
+    u'\x02'     #  0x02 -> CONTROL CHARACTER
+    u'\x03'     #  0x03 -> CONTROL CHARACTER
+    u'\x04'     #  0x04 -> CONTROL CHARACTER
+    u'\x05'     #  0x05 -> CONTROL CHARACTER
+    u'\x06'     #  0x06 -> CONTROL CHARACTER
+    u'\x07'     #  0x07 -> CONTROL CHARACTER
+    u'\x08'     #  0x08 -> CONTROL CHARACTER
+    u'\t'       #  0x09 -> CONTROL CHARACTER
+    u'\n'       #  0x0A -> CONTROL CHARACTER
+    u'\x0b'     #  0x0B -> CONTROL CHARACTER
+    u'\x0c'     #  0x0C -> CONTROL CHARACTER
+    u'\r'       #  0x0D -> CONTROL CHARACTER
+    u'\x0e'     #  0x0E -> CONTROL CHARACTER
+    u'\x0f'     #  0x0F -> CONTROL CHARACTER
+    u'\x10'     #  0x10 -> CONTROL CHARACTER
+    u'\x11'     #  0x11 -> CONTROL CHARACTER
+    u'\x12'     #  0x12 -> CONTROL CHARACTER
+    u'\x13'     #  0x13 -> CONTROL CHARACTER
+    u'\x14'     #  0x14 -> CONTROL CHARACTER
+    u'\x15'     #  0x15 -> CONTROL CHARACTER
+    u'\x16'     #  0x16 -> CONTROL CHARACTER
+    u'\x17'     #  0x17 -> CONTROL CHARACTER
+    u'\x18'     #  0x18 -> CONTROL CHARACTER
+    u'\x19'     #  0x19 -> CONTROL CHARACTER
+    u'\x1a'     #  0x1A -> CONTROL CHARACTER
+    u'\x1b'     #  0x1B -> CONTROL CHARACTER
+    u'\x1c'     #  0x1C -> CONTROL CHARACTER
+    u'\x1d'     #  0x1D -> CONTROL CHARACTER
+    u'\x1e'     #  0x1E -> CONTROL CHARACTER
+    u'\x1f'     #  0x1F -> CONTROL CHARACTER
+    u' '        #  0x20 -> SPACE
+    u'!'        #  0x21 -> EXCLAMATION MARK
+    u'"'        #  0x22 -> QUOTATION MARK
+    u'#'        #  0x23 -> NUMBER SIGN
+    u'$'        #  0x24 -> DOLLAR SIGN
+    u'%'        #  0x25 -> PERCENT SIGN
+    u'&'        #  0x26 -> AMPERSAND
+    u"'"        #  0x27 -> APOSTROPHE
+    u'('        #  0x28 -> LEFT PARENTHESIS
+    u')'        #  0x29 -> RIGHT PARENTHESIS
+    u'*'        #  0x2A -> ASTERISK
+    u'+'        #  0x2B -> PLUS SIGN
+    u','        #  0x2C -> COMMA
+    u'-'        #  0x2D -> HYPHEN-MINUS
+    u'.'        #  0x2E -> FULL STOP
+    u'/'        #  0x2F -> SOLIDUS
+    u'0'        #  0x30 -> DIGIT ZERO
+    u'1'        #  0x31 -> DIGIT ONE
+    u'2'        #  0x32 -> DIGIT TWO
+    u'3'        #  0x33 -> DIGIT THREE
+    u'4'        #  0x34 -> DIGIT FOUR
+    u'5'        #  0x35 -> DIGIT FIVE
+    u'6'        #  0x36 -> DIGIT SIX
+    u'7'        #  0x37 -> DIGIT SEVEN
+    u'8'        #  0x38 -> DIGIT EIGHT
+    u'9'        #  0x39 -> DIGIT NINE
+    u':'        #  0x3A -> COLON
+    u';'        #  0x3B -> SEMICOLON
+    u'<'        #  0x3C -> LESS-THAN SIGN
+    u'='        #  0x3D -> EQUALS SIGN
+    u'>'        #  0x3E -> GREATER-THAN SIGN
+    u'?'        #  0x3F -> QUESTION MARK
+    u'@'        #  0x40 -> COMMERCIAL AT
+    u'A'        #  0x41 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x42 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x43 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x44 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x45 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x46 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x47 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x48 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x49 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x4A -> LATIN CAPITAL LETTER J
+    u'K'        #  0x4B -> LATIN CAPITAL LETTER K
+    u'L'        #  0x4C -> LATIN CAPITAL LETTER L
+    u'M'        #  0x4D -> LATIN CAPITAL LETTER M
+    u'N'        #  0x4E -> LATIN CAPITAL LETTER N
+    u'O'        #  0x4F -> LATIN CAPITAL LETTER O
+    u'P'        #  0x50 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x51 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x52 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x53 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x54 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x55 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x56 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x57 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x58 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x59 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x5A -> LATIN CAPITAL LETTER Z
+    u'['        #  0x5B -> LEFT SQUARE BRACKET
+    u'\\'       #  0x5C -> REVERSE SOLIDUS
+    u']'        #  0x5D -> RIGHT SQUARE BRACKET
+    u'^'        #  0x5E -> CIRCUMFLEX ACCENT
+    u'_'        #  0x5F -> LOW LINE
+    u'`'        #  0x60 -> GRAVE ACCENT
+    u'a'        #  0x61 -> LATIN SMALL LETTER A
+    u'b'        #  0x62 -> LATIN SMALL LETTER B
+    u'c'        #  0x63 -> LATIN SMALL LETTER C
+    u'd'        #  0x64 -> LATIN SMALL LETTER D
+    u'e'        #  0x65 -> LATIN SMALL LETTER E
+    u'f'        #  0x66 -> LATIN SMALL LETTER F
+    u'g'        #  0x67 -> LATIN SMALL LETTER G
+    u'h'        #  0x68 -> LATIN SMALL LETTER H
+    u'i'        #  0x69 -> LATIN SMALL LETTER I
+    u'j'        #  0x6A -> LATIN SMALL LETTER J
+    u'k'        #  0x6B -> LATIN SMALL LETTER K
+    u'l'        #  0x6C -> LATIN SMALL LETTER L
+    u'm'        #  0x6D -> LATIN SMALL LETTER M
+    u'n'        #  0x6E -> LATIN SMALL LETTER N
+    u'o'        #  0x6F -> LATIN SMALL LETTER O
+    u'p'        #  0x70 -> LATIN SMALL LETTER P
+    u'q'        #  0x71 -> LATIN SMALL LETTER Q
+    u'r'        #  0x72 -> LATIN SMALL LETTER R
+    u's'        #  0x73 -> LATIN SMALL LETTER S
+    u't'        #  0x74 -> LATIN SMALL LETTER T
+    u'u'        #  0x75 -> LATIN SMALL LETTER U
+    u'v'        #  0x76 -> LATIN SMALL LETTER V
+    u'w'        #  0x77 -> LATIN SMALL LETTER W
+    u'x'        #  0x78 -> LATIN SMALL LETTER X
+    u'y'        #  0x79 -> LATIN SMALL LETTER Y
+    u'z'        #  0x7A -> LATIN SMALL LETTER Z
+    u'{'        #  0x7B -> LEFT CURLY BRACKET
+    u'|'        #  0x7C -> VERTICAL LINE
+    u'}'        #  0x7D -> RIGHT CURLY BRACKET
+    u'~'        #  0x7E -> TILDE
+    u'\x7f'     #  0x7F -> CONTROL CHARACTER
+    u'\xc4'     #  0x80 -> LATIN CAPITAL LETTER A WITH DIAERESIS
+    u'\u0100'   #  0x81 -> LATIN CAPITAL LETTER A WITH MACRON
+    u'\u0101'   #  0x82 -> LATIN SMALL LETTER A WITH MACRON
+    u'\xc9'     #  0x83 -> LATIN CAPITAL LETTER E WITH ACUTE
+    u'\u0104'   #  0x84 -> LATIN CAPITAL LETTER A WITH OGONEK
+    u'\xd6'     #  0x85 -> LATIN CAPITAL LETTER O WITH DIAERESIS
+    u'\xdc'     #  0x86 -> LATIN CAPITAL LETTER U WITH DIAERESIS
+    u'\xe1'     #  0x87 -> LATIN SMALL LETTER A WITH ACUTE
+    u'\u0105'   #  0x88 -> LATIN SMALL LETTER A WITH OGONEK
+    u'\u010c'   #  0x89 -> LATIN CAPITAL LETTER C WITH CARON
+    u'\xe4'     #  0x8A -> LATIN SMALL LETTER A WITH DIAERESIS
+    u'\u010d'   #  0x8B -> LATIN SMALL LETTER C WITH CARON
+    u'\u0106'   #  0x8C -> LATIN CAPITAL LETTER C WITH ACUTE
+    u'\u0107'   #  0x8D -> LATIN SMALL LETTER C WITH ACUTE
+    u'\xe9'     #  0x8E -> LATIN SMALL LETTER E WITH ACUTE
+    u'\u0179'   #  0x8F -> LATIN CAPITAL LETTER Z WITH ACUTE
+    u'\u017a'   #  0x90 -> LATIN SMALL LETTER Z WITH ACUTE
+    u'\u010e'   #  0x91 -> LATIN CAPITAL LETTER D WITH CARON
+    u'\xed'     #  0x92 -> LATIN SMALL LETTER I WITH ACUTE
+    u'\u010f'   #  0x93 -> LATIN SMALL LETTER D WITH CARON
+    u'\u0112'   #  0x94 -> LATIN CAPITAL LETTER E WITH MACRON
+    u'\u0113'   #  0x95 -> LATIN SMALL LETTER E WITH MACRON
+    u'\u0116'   #  0x96 -> LATIN CAPITAL LETTER E WITH DOT ABOVE
+    u'\xf3'     #  0x97 -> LATIN SMALL LETTER O WITH ACUTE
+    u'\u0117'   #  0x98 -> LATIN SMALL LETTER E WITH DOT ABOVE
+    u'\xf4'     #  0x99 -> LATIN SMALL LETTER O WITH CIRCUMFLEX
+    u'\xf6'     #  0x9A -> LATIN SMALL LETTER O WITH DIAERESIS
+    u'\xf5'     #  0x9B -> LATIN SMALL LETTER O WITH TILDE
+    u'\xfa'     #  0x9C -> LATIN SMALL LETTER U WITH ACUTE
+    u'\u011a'   #  0x9D -> LATIN CAPITAL LETTER E WITH CARON
+    u'\u011b'   #  0x9E -> LATIN SMALL LETTER E WITH CARON
+    u'\xfc'     #  0x9F -> LATIN SMALL LETTER U WITH DIAERESIS
+    u'\u2020'   #  0xA0 -> DAGGER
+    u'\xb0'     #  0xA1 -> DEGREE SIGN
+    u'\u0118'   #  0xA2 -> LATIN CAPITAL LETTER E WITH OGONEK
+    u'\xa3'     #  0xA3 -> POUND SIGN
+    u'\xa7'     #  0xA4 -> SECTION SIGN
+    u'\u2022'   #  0xA5 -> BULLET
+    u'\xb6'     #  0xA6 -> PILCROW SIGN
+    u'\xdf'     #  0xA7 -> LATIN SMALL LETTER SHARP S
+    u'\xae'     #  0xA8 -> REGISTERED SIGN
+    u'\xa9'     #  0xA9 -> COPYRIGHT SIGN
+    u'\u2122'   #  0xAA -> TRADE MARK SIGN
+    u'\u0119'   #  0xAB -> LATIN SMALL LETTER E WITH OGONEK
+    u'\xa8'     #  0xAC -> DIAERESIS
+    u'\u2260'   #  0xAD -> NOT EQUAL TO
+    u'\u0123'   #  0xAE -> LATIN SMALL LETTER G WITH CEDILLA
+    u'\u012e'   #  0xAF -> LATIN CAPITAL LETTER I WITH OGONEK
+    u'\u012f'   #  0xB0 -> LATIN SMALL LETTER I WITH OGONEK
+    u'\u012a'   #  0xB1 -> LATIN CAPITAL LETTER I WITH MACRON
+    u'\u2264'   #  0xB2 -> LESS-THAN OR EQUAL TO
+    u'\u2265'   #  0xB3 -> GREATER-THAN OR EQUAL TO
+    u'\u012b'   #  0xB4 -> LATIN SMALL LETTER I WITH MACRON
+    u'\u0136'   #  0xB5 -> LATIN CAPITAL LETTER K WITH CEDILLA
+    u'\u2202'   #  0xB6 -> PARTIAL DIFFERENTIAL
+    u'\u2211'   #  0xB7 -> N-ARY SUMMATION
+    u'\u0142'   #  0xB8 -> LATIN SMALL LETTER L WITH STROKE
+    u'\u013b'   #  0xB9 -> LATIN CAPITAL LETTER L WITH CEDILLA
+    u'\u013c'   #  0xBA -> LATIN SMALL LETTER L WITH CEDILLA
+    u'\u013d'   #  0xBB -> LATIN CAPITAL LETTER L WITH CARON
+    u'\u013e'   #  0xBC -> LATIN SMALL LETTER L WITH CARON
+    u'\u0139'   #  0xBD -> LATIN CAPITAL LETTER L WITH ACUTE
+    u'\u013a'   #  0xBE -> LATIN SMALL LETTER L WITH ACUTE
+    u'\u0145'   #  0xBF -> LATIN CAPITAL LETTER N WITH CEDILLA
+    u'\u0146'   #  0xC0 -> LATIN SMALL LETTER N WITH CEDILLA
+    u'\u0143'   #  0xC1 -> LATIN CAPITAL LETTER N WITH ACUTE
+    u'\xac'     #  0xC2 -> NOT SIGN
+    u'\u221a'   #  0xC3 -> SQUARE ROOT
+    u'\u0144'   #  0xC4 -> LATIN SMALL LETTER N WITH ACUTE
+    u'\u0147'   #  0xC5 -> LATIN CAPITAL LETTER N WITH CARON
+    u'\u2206'   #  0xC6 -> INCREMENT
+    u'\xab'     #  0xC7 -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xbb'     #  0xC8 -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\u2026'   #  0xC9 -> HORIZONTAL ELLIPSIS
+    u'\xa0'     #  0xCA -> NO-BREAK SPACE
+    u'\u0148'   #  0xCB -> LATIN SMALL LETTER N WITH CARON
+    u'\u0150'   #  0xCC -> LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
+    u'\xd5'     #  0xCD -> LATIN CAPITAL LETTER O WITH TILDE
+    u'\u0151'   #  0xCE -> LATIN SMALL LETTER O WITH DOUBLE ACUTE
+    u'\u014c'   #  0xCF -> LATIN CAPITAL LETTER O WITH MACRON
+    u'\u2013'   #  0xD0 -> EN DASH
+    u'\u2014'   #  0xD1 -> EM DASH
+    u'\u201c'   #  0xD2 -> LEFT DOUBLE QUOTATION MARK
+    u'\u201d'   #  0xD3 -> RIGHT DOUBLE QUOTATION MARK
+    u'\u2018'   #  0xD4 -> LEFT SINGLE QUOTATION MARK
+    u'\u2019'   #  0xD5 -> RIGHT SINGLE QUOTATION MARK
+    u'\xf7'     #  0xD6 -> DIVISION SIGN
+    u'\u25ca'   #  0xD7 -> LOZENGE
+    u'\u014d'   #  0xD8 -> LATIN SMALL LETTER O WITH MACRON
+    u'\u0154'   #  0xD9 -> LATIN CAPITAL LETTER R WITH ACUTE
+    u'\u0155'   #  0xDA -> LATIN SMALL LETTER R WITH ACUTE
+    u'\u0158'   #  0xDB -> LATIN CAPITAL LETTER R WITH CARON
+    u'\u2039'   #  0xDC -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+    u'\u203a'   #  0xDD -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+    u'\u0159'   #  0xDE -> LATIN SMALL LETTER R WITH CARON
+    u'\u0156'   #  0xDF -> LATIN CAPITAL LETTER R WITH CEDILLA
+    u'\u0157'   #  0xE0 -> LATIN SMALL LETTER R WITH CEDILLA
+    u'\u0160'   #  0xE1 -> LATIN CAPITAL LETTER S WITH CARON
+    u'\u201a'   #  0xE2 -> SINGLE LOW-9 QUOTATION MARK
+    u'\u201e'   #  0xE3 -> DOUBLE LOW-9 QUOTATION MARK
+    u'\u0161'   #  0xE4 -> LATIN SMALL LETTER S WITH CARON
+    u'\u015a'   #  0xE5 -> LATIN CAPITAL LETTER S WITH ACUTE
+    u'\u015b'   #  0xE6 -> LATIN SMALL LETTER S WITH ACUTE
+    u'\xc1'     #  0xE7 -> LATIN CAPITAL LETTER A WITH ACUTE
+    u'\u0164'   #  0xE8 -> LATIN CAPITAL LETTER T WITH CARON
+    u'\u0165'   #  0xE9 -> LATIN SMALL LETTER T WITH CARON
+    u'\xcd'     #  0xEA -> LATIN CAPITAL LETTER I WITH ACUTE
+    u'\u017d'   #  0xEB -> LATIN CAPITAL LETTER Z WITH CARON
+    u'\u017e'   #  0xEC -> LATIN SMALL LETTER Z WITH CARON
+    u'\u016a'   #  0xED -> LATIN CAPITAL LETTER U WITH MACRON
+    u'\xd3'     #  0xEE -> LATIN CAPITAL LETTER O WITH ACUTE
+    u'\xd4'     #  0xEF -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+    u'\u016b'   #  0xF0 -> LATIN SMALL LETTER U WITH MACRON
+    u'\u016e'   #  0xF1 -> LATIN CAPITAL LETTER U WITH RING ABOVE
+    u'\xda'     #  0xF2 -> LATIN CAPITAL LETTER U WITH ACUTE
+    u'\u016f'   #  0xF3 -> LATIN SMALL LETTER U WITH RING ABOVE
+    u'\u0170'   #  0xF4 -> LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
+    u'\u0171'   #  0xF5 -> LATIN SMALL LETTER U WITH DOUBLE ACUTE
+    u'\u0172'   #  0xF6 -> LATIN CAPITAL LETTER U WITH OGONEK
+    u'\u0173'   #  0xF7 -> LATIN SMALL LETTER U WITH OGONEK
+    u'\xdd'     #  0xF8 -> LATIN CAPITAL LETTER Y WITH ACUTE
+    u'\xfd'     #  0xF9 -> LATIN SMALL LETTER Y WITH ACUTE
+    u'\u0137'   #  0xFA -> LATIN SMALL LETTER K WITH CEDILLA
+    u'\u017b'   #  0xFB -> LATIN CAPITAL LETTER Z WITH DOT ABOVE
+    u'\u0141'   #  0xFC -> LATIN CAPITAL LETTER L WITH STROKE
+    u'\u017c'   #  0xFD -> LATIN SMALL LETTER Z WITH DOT ABOVE
+    u'\u0122'   #  0xFE -> LATIN CAPITAL LETTER G WITH CEDILLA
+    u'\u02c7'   #  0xFF -> CARON
+)
+
+### Encoding table
+encoding_table=codecs.charmap_build(decoding_table)

Added: vendor/Python/current/Lib/encodings/mac_croatian.py
===================================================================
--- vendor/Python/current/Lib/encodings/mac_croatian.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/mac_croatian.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,307 @@
+""" Python Character Mapping Codec mac_croatian generated from 'MAPPINGS/VENDORS/APPLE/CROATIAN.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_table)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_table)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='mac-croatian',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x00 -> CONTROL CHARACTER
+    u'\x01'     #  0x01 -> CONTROL CHARACTER
+    u'\x02'     #  0x02 -> CONTROL CHARACTER
+    u'\x03'     #  0x03 -> CONTROL CHARACTER
+    u'\x04'     #  0x04 -> CONTROL CHARACTER
+    u'\x05'     #  0x05 -> CONTROL CHARACTER
+    u'\x06'     #  0x06 -> CONTROL CHARACTER
+    u'\x07'     #  0x07 -> CONTROL CHARACTER
+    u'\x08'     #  0x08 -> CONTROL CHARACTER
+    u'\t'       #  0x09 -> CONTROL CHARACTER
+    u'\n'       #  0x0A -> CONTROL CHARACTER
+    u'\x0b'     #  0x0B -> CONTROL CHARACTER
+    u'\x0c'     #  0x0C -> CONTROL CHARACTER
+    u'\r'       #  0x0D -> CONTROL CHARACTER
+    u'\x0e'     #  0x0E -> CONTROL CHARACTER
+    u'\x0f'     #  0x0F -> CONTROL CHARACTER
+    u'\x10'     #  0x10 -> CONTROL CHARACTER
+    u'\x11'     #  0x11 -> CONTROL CHARACTER
+    u'\x12'     #  0x12 -> CONTROL CHARACTER
+    u'\x13'     #  0x13 -> CONTROL CHARACTER
+    u'\x14'     #  0x14 -> CONTROL CHARACTER
+    u'\x15'     #  0x15 -> CONTROL CHARACTER
+    u'\x16'     #  0x16 -> CONTROL CHARACTER
+    u'\x17'     #  0x17 -> CONTROL CHARACTER
+    u'\x18'     #  0x18 -> CONTROL CHARACTER
+    u'\x19'     #  0x19 -> CONTROL CHARACTER
+    u'\x1a'     #  0x1A -> CONTROL CHARACTER
+    u'\x1b'     #  0x1B -> CONTROL CHARACTER
+    u'\x1c'     #  0x1C -> CONTROL CHARACTER
+    u'\x1d'     #  0x1D -> CONTROL CHARACTER
+    u'\x1e'     #  0x1E -> CONTROL CHARACTER
+    u'\x1f'     #  0x1F -> CONTROL CHARACTER
+    u' '        #  0x20 -> SPACE
+    u'!'        #  0x21 -> EXCLAMATION MARK
+    u'"'        #  0x22 -> QUOTATION MARK
+    u'#'        #  0x23 -> NUMBER SIGN
+    u'$'        #  0x24 -> DOLLAR SIGN
+    u'%'        #  0x25 -> PERCENT SIGN
+    u'&'        #  0x26 -> AMPERSAND
+    u"'"        #  0x27 -> APOSTROPHE
+    u'('        #  0x28 -> LEFT PARENTHESIS
+    u')'        #  0x29 -> RIGHT PARENTHESIS
+    u'*'        #  0x2A -> ASTERISK
+    u'+'        #  0x2B -> PLUS SIGN
+    u','        #  0x2C -> COMMA
+    u'-'        #  0x2D -> HYPHEN-MINUS
+    u'.'        #  0x2E -> FULL STOP
+    u'/'        #  0x2F -> SOLIDUS
+    u'0'        #  0x30 -> DIGIT ZERO
+    u'1'        #  0x31 -> DIGIT ONE
+    u'2'        #  0x32 -> DIGIT TWO
+    u'3'        #  0x33 -> DIGIT THREE
+    u'4'        #  0x34 -> DIGIT FOUR
+    u'5'        #  0x35 -> DIGIT FIVE
+    u'6'        #  0x36 -> DIGIT SIX
+    u'7'        #  0x37 -> DIGIT SEVEN
+    u'8'        #  0x38 -> DIGIT EIGHT
+    u'9'        #  0x39 -> DIGIT NINE
+    u':'        #  0x3A -> COLON
+    u';'        #  0x3B -> SEMICOLON
+    u'<'        #  0x3C -> LESS-THAN SIGN
+    u'='        #  0x3D -> EQUALS SIGN
+    u'>'        #  0x3E -> GREATER-THAN SIGN
+    u'?'        #  0x3F -> QUESTION MARK
+    u'@'        #  0x40 -> COMMERCIAL AT
+    u'A'        #  0x41 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x42 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x43 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x44 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x45 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x46 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x47 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x48 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x49 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x4A -> LATIN CAPITAL LETTER J
+    u'K'        #  0x4B -> LATIN CAPITAL LETTER K
+    u'L'        #  0x4C -> LATIN CAPITAL LETTER L
+    u'M'        #  0x4D -> LATIN CAPITAL LETTER M
+    u'N'        #  0x4E -> LATIN CAPITAL LETTER N
+    u'O'        #  0x4F -> LATIN CAPITAL LETTER O
+    u'P'        #  0x50 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x51 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x52 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x53 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x54 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x55 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x56 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x57 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x58 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x59 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x5A -> LATIN CAPITAL LETTER Z
+    u'['        #  0x5B -> LEFT SQUARE BRACKET
+    u'\\'       #  0x5C -> REVERSE SOLIDUS
+    u']'        #  0x5D -> RIGHT SQUARE BRACKET
+    u'^'        #  0x5E -> CIRCUMFLEX ACCENT
+    u'_'        #  0x5F -> LOW LINE
+    u'`'        #  0x60 -> GRAVE ACCENT
+    u'a'        #  0x61 -> LATIN SMALL LETTER A
+    u'b'        #  0x62 -> LATIN SMALL LETTER B
+    u'c'        #  0x63 -> LATIN SMALL LETTER C
+    u'd'        #  0x64 -> LATIN SMALL LETTER D
+    u'e'        #  0x65 -> LATIN SMALL LETTER E
+    u'f'        #  0x66 -> LATIN SMALL LETTER F
+    u'g'        #  0x67 -> LATIN SMALL LETTER G
+    u'h'        #  0x68 -> LATIN SMALL LETTER H
+    u'i'        #  0x69 -> LATIN SMALL LETTER I
+    u'j'        #  0x6A -> LATIN SMALL LETTER J
+    u'k'        #  0x6B -> LATIN SMALL LETTER K
+    u'l'        #  0x6C -> LATIN SMALL LETTER L
+    u'm'        #  0x6D -> LATIN SMALL LETTER M
+    u'n'        #  0x6E -> LATIN SMALL LETTER N
+    u'o'        #  0x6F -> LATIN SMALL LETTER O
+    u'p'        #  0x70 -> LATIN SMALL LETTER P
+    u'q'        #  0x71 -> LATIN SMALL LETTER Q
+    u'r'        #  0x72 -> LATIN SMALL LETTER R
+    u's'        #  0x73 -> LATIN SMALL LETTER S
+    u't'        #  0x74 -> LATIN SMALL LETTER T
+    u'u'        #  0x75 -> LATIN SMALL LETTER U
+    u'v'        #  0x76 -> LATIN SMALL LETTER V
+    u'w'        #  0x77 -> LATIN SMALL LETTER W
+    u'x'        #  0x78 -> LATIN SMALL LETTER X
+    u'y'        #  0x79 -> LATIN SMALL LETTER Y
+    u'z'        #  0x7A -> LATIN SMALL LETTER Z
+    u'{'        #  0x7B -> LEFT CURLY BRACKET
+    u'|'        #  0x7C -> VERTICAL LINE
+    u'}'        #  0x7D -> RIGHT CURLY BRACKET
+    u'~'        #  0x7E -> TILDE
+    u'\x7f'     #  0x7F -> CONTROL CHARACTER
+    u'\xc4'     #  0x80 -> LATIN CAPITAL LETTER A WITH DIAERESIS
+    u'\xc5'     #  0x81 -> LATIN CAPITAL LETTER A WITH RING ABOVE
+    u'\xc7'     #  0x82 -> LATIN CAPITAL LETTER C WITH CEDILLA
+    u'\xc9'     #  0x83 -> LATIN CAPITAL LETTER E WITH ACUTE
+    u'\xd1'     #  0x84 -> LATIN CAPITAL LETTER N WITH TILDE
+    u'\xd6'     #  0x85 -> LATIN CAPITAL LETTER O WITH DIAERESIS
+    u'\xdc'     #  0x86 -> LATIN CAPITAL LETTER U WITH DIAERESIS
+    u'\xe1'     #  0x87 -> LATIN SMALL LETTER A WITH ACUTE
+    u'\xe0'     #  0x88 -> LATIN SMALL LETTER A WITH GRAVE
+    u'\xe2'     #  0x89 -> LATIN SMALL LETTER A WITH CIRCUMFLEX
+    u'\xe4'     #  0x8A -> LATIN SMALL LETTER A WITH DIAERESIS
+    u'\xe3'     #  0x8B -> LATIN SMALL LETTER A WITH TILDE
+    u'\xe5'     #  0x8C -> LATIN SMALL LETTER A WITH RING ABOVE
+    u'\xe7'     #  0x8D -> LATIN SMALL LETTER C WITH CEDILLA
+    u'\xe9'     #  0x8E -> LATIN SMALL LETTER E WITH ACUTE
+    u'\xe8'     #  0x8F -> LATIN SMALL LETTER E WITH GRAVE
+    u'\xea'     #  0x90 -> LATIN SMALL LETTER E WITH CIRCUMFLEX
+    u'\xeb'     #  0x91 -> LATIN SMALL LETTER E WITH DIAERESIS
+    u'\xed'     #  0x92 -> LATIN SMALL LETTER I WITH ACUTE
+    u'\xec'     #  0x93 -> LATIN SMALL LETTER I WITH GRAVE
+    u'\xee'     #  0x94 -> LATIN SMALL LETTER I WITH CIRCUMFLEX
+    u'\xef'     #  0x95 -> LATIN SMALL LETTER I WITH DIAERESIS
+    u'\xf1'     #  0x96 -> LATIN SMALL LETTER N WITH TILDE
+    u'\xf3'     #  0x97 -> LATIN SMALL LETTER O WITH ACUTE
+    u'\xf2'     #  0x98 -> LATIN SMALL LETTER O WITH GRAVE
+    u'\xf4'     #  0x99 -> LATIN SMALL LETTER O WITH CIRCUMFLEX
+    u'\xf6'     #  0x9A -> LATIN SMALL LETTER O WITH DIAERESIS
+    u'\xf5'     #  0x9B -> LATIN SMALL LETTER O WITH TILDE
+    u'\xfa'     #  0x9C -> LATIN SMALL LETTER U WITH ACUTE
+    u'\xf9'     #  0x9D -> LATIN SMALL LETTER U WITH GRAVE
+    u'\xfb'     #  0x9E -> LATIN SMALL LETTER U WITH CIRCUMFLEX
+    u'\xfc'     #  0x9F -> LATIN SMALL LETTER U WITH DIAERESIS
+    u'\u2020'   #  0xA0 -> DAGGER
+    u'\xb0'     #  0xA1 -> DEGREE SIGN
+    u'\xa2'     #  0xA2 -> CENT SIGN
+    u'\xa3'     #  0xA3 -> POUND SIGN
+    u'\xa7'     #  0xA4 -> SECTION SIGN
+    u'\u2022'   #  0xA5 -> BULLET
+    u'\xb6'     #  0xA6 -> PILCROW SIGN
+    u'\xdf'     #  0xA7 -> LATIN SMALL LETTER SHARP S
+    u'\xae'     #  0xA8 -> REGISTERED SIGN
+    u'\u0160'   #  0xA9 -> LATIN CAPITAL LETTER S WITH CARON
+    u'\u2122'   #  0xAA -> TRADE MARK SIGN
+    u'\xb4'     #  0xAB -> ACUTE ACCENT
+    u'\xa8'     #  0xAC -> DIAERESIS
+    u'\u2260'   #  0xAD -> NOT EQUAL TO
+    u'\u017d'   #  0xAE -> LATIN CAPITAL LETTER Z WITH CARON
+    u'\xd8'     #  0xAF -> LATIN CAPITAL LETTER O WITH STROKE
+    u'\u221e'   #  0xB0 -> INFINITY
+    u'\xb1'     #  0xB1 -> PLUS-MINUS SIGN
+    u'\u2264'   #  0xB2 -> LESS-THAN OR EQUAL TO
+    u'\u2265'   #  0xB3 -> GREATER-THAN OR EQUAL TO
+    u'\u2206'   #  0xB4 -> INCREMENT
+    u'\xb5'     #  0xB5 -> MICRO SIGN
+    u'\u2202'   #  0xB6 -> PARTIAL DIFFERENTIAL
+    u'\u2211'   #  0xB7 -> N-ARY SUMMATION
+    u'\u220f'   #  0xB8 -> N-ARY PRODUCT
+    u'\u0161'   #  0xB9 -> LATIN SMALL LETTER S WITH CARON
+    u'\u222b'   #  0xBA -> INTEGRAL
+    u'\xaa'     #  0xBB -> FEMININE ORDINAL INDICATOR
+    u'\xba'     #  0xBC -> MASCULINE ORDINAL INDICATOR
+    u'\u03a9'   #  0xBD -> GREEK CAPITAL LETTER OMEGA
+    u'\u017e'   #  0xBE -> LATIN SMALL LETTER Z WITH CARON
+    u'\xf8'     #  0xBF -> LATIN SMALL LETTER O WITH STROKE
+    u'\xbf'     #  0xC0 -> INVERTED QUESTION MARK
+    u'\xa1'     #  0xC1 -> INVERTED EXCLAMATION MARK
+    u'\xac'     #  0xC2 -> NOT SIGN
+    u'\u221a'   #  0xC3 -> SQUARE ROOT
+    u'\u0192'   #  0xC4 -> LATIN SMALL LETTER F WITH HOOK
+    u'\u2248'   #  0xC5 -> ALMOST EQUAL TO
+    u'\u0106'   #  0xC6 -> LATIN CAPITAL LETTER C WITH ACUTE
+    u'\xab'     #  0xC7 -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\u010c'   #  0xC8 -> LATIN CAPITAL LETTER C WITH CARON
+    u'\u2026'   #  0xC9 -> HORIZONTAL ELLIPSIS
+    u'\xa0'     #  0xCA -> NO-BREAK SPACE
+    u'\xc0'     #  0xCB -> LATIN CAPITAL LETTER A WITH GRAVE
+    u'\xc3'     #  0xCC -> LATIN CAPITAL LETTER A WITH TILDE
+    u'\xd5'     #  0xCD -> LATIN CAPITAL LETTER O WITH TILDE
+    u'\u0152'   #  0xCE -> LATIN CAPITAL LIGATURE OE
+    u'\u0153'   #  0xCF -> LATIN SMALL LIGATURE OE
+    u'\u0110'   #  0xD0 -> LATIN CAPITAL LETTER D WITH STROKE
+    u'\u2014'   #  0xD1 -> EM DASH
+    u'\u201c'   #  0xD2 -> LEFT DOUBLE QUOTATION MARK
+    u'\u201d'   #  0xD3 -> RIGHT DOUBLE QUOTATION MARK
+    u'\u2018'   #  0xD4 -> LEFT SINGLE QUOTATION MARK
+    u'\u2019'   #  0xD5 -> RIGHT SINGLE QUOTATION MARK
+    u'\xf7'     #  0xD6 -> DIVISION SIGN
+    u'\u25ca'   #  0xD7 -> LOZENGE
+    u'\uf8ff'   #  0xD8 -> Apple logo
+    u'\xa9'     #  0xD9 -> COPYRIGHT SIGN
+    u'\u2044'   #  0xDA -> FRACTION SLASH
+    u'\u20ac'   #  0xDB -> EURO SIGN
+    u'\u2039'   #  0xDC -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+    u'\u203a'   #  0xDD -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+    u'\xc6'     #  0xDE -> LATIN CAPITAL LETTER AE
+    u'\xbb'     #  0xDF -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\u2013'   #  0xE0 -> EN DASH
+    u'\xb7'     #  0xE1 -> MIDDLE DOT
+    u'\u201a'   #  0xE2 -> SINGLE LOW-9 QUOTATION MARK
+    u'\u201e'   #  0xE3 -> DOUBLE LOW-9 QUOTATION MARK
+    u'\u2030'   #  0xE4 -> PER MILLE SIGN
+    u'\xc2'     #  0xE5 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+    u'\u0107'   #  0xE6 -> LATIN SMALL LETTER C WITH ACUTE
+    u'\xc1'     #  0xE7 -> LATIN CAPITAL LETTER A WITH ACUTE
+    u'\u010d'   #  0xE8 -> LATIN SMALL LETTER C WITH CARON
+    u'\xc8'     #  0xE9 -> LATIN CAPITAL LETTER E WITH GRAVE
+    u'\xcd'     #  0xEA -> LATIN CAPITAL LETTER I WITH ACUTE
+    u'\xce'     #  0xEB -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+    u'\xcf'     #  0xEC -> LATIN CAPITAL LETTER I WITH DIAERESIS
+    u'\xcc'     #  0xED -> LATIN CAPITAL LETTER I WITH GRAVE
+    u'\xd3'     #  0xEE -> LATIN CAPITAL LETTER O WITH ACUTE
+    u'\xd4'     #  0xEF -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+    u'\u0111'   #  0xF0 -> LATIN SMALL LETTER D WITH STROKE
+    u'\xd2'     #  0xF1 -> LATIN CAPITAL LETTER O WITH GRAVE
+    u'\xda'     #  0xF2 -> LATIN CAPITAL LETTER U WITH ACUTE
+    u'\xdb'     #  0xF3 -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+    u'\xd9'     #  0xF4 -> LATIN CAPITAL LETTER U WITH GRAVE
+    u'\u0131'   #  0xF5 -> LATIN SMALL LETTER DOTLESS I
+    u'\u02c6'   #  0xF6 -> MODIFIER LETTER CIRCUMFLEX ACCENT
+    u'\u02dc'   #  0xF7 -> SMALL TILDE
+    u'\xaf'     #  0xF8 -> MACRON
+    u'\u03c0'   #  0xF9 -> GREEK SMALL LETTER PI
+    u'\xcb'     #  0xFA -> LATIN CAPITAL LETTER E WITH DIAERESIS
+    u'\u02da'   #  0xFB -> RING ABOVE
+    u'\xb8'     #  0xFC -> CEDILLA
+    u'\xca'     #  0xFD -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+    u'\xe6'     #  0xFE -> LATIN SMALL LETTER AE
+    u'\u02c7'   #  0xFF -> CARON
+)
+
+### Encoding table
+encoding_table=codecs.charmap_build(decoding_table)

Added: vendor/Python/current/Lib/encodings/mac_cyrillic.py
===================================================================
--- vendor/Python/current/Lib/encodings/mac_cyrillic.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/mac_cyrillic.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,307 @@
+""" Python Character Mapping Codec mac_cyrillic generated from 'MAPPINGS/VENDORS/APPLE/CYRILLIC.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_table)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_table)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='mac-cyrillic',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x00 -> CONTROL CHARACTER
+    u'\x01'     #  0x01 -> CONTROL CHARACTER
+    u'\x02'     #  0x02 -> CONTROL CHARACTER
+    u'\x03'     #  0x03 -> CONTROL CHARACTER
+    u'\x04'     #  0x04 -> CONTROL CHARACTER
+    u'\x05'     #  0x05 -> CONTROL CHARACTER
+    u'\x06'     #  0x06 -> CONTROL CHARACTER
+    u'\x07'     #  0x07 -> CONTROL CHARACTER
+    u'\x08'     #  0x08 -> CONTROL CHARACTER
+    u'\t'       #  0x09 -> CONTROL CHARACTER
+    u'\n'       #  0x0A -> CONTROL CHARACTER
+    u'\x0b'     #  0x0B -> CONTROL CHARACTER
+    u'\x0c'     #  0x0C -> CONTROL CHARACTER
+    u'\r'       #  0x0D -> CONTROL CHARACTER
+    u'\x0e'     #  0x0E -> CONTROL CHARACTER
+    u'\x0f'     #  0x0F -> CONTROL CHARACTER
+    u'\x10'     #  0x10 -> CONTROL CHARACTER
+    u'\x11'     #  0x11 -> CONTROL CHARACTER
+    u'\x12'     #  0x12 -> CONTROL CHARACTER
+    u'\x13'     #  0x13 -> CONTROL CHARACTER
+    u'\x14'     #  0x14 -> CONTROL CHARACTER
+    u'\x15'     #  0x15 -> CONTROL CHARACTER
+    u'\x16'     #  0x16 -> CONTROL CHARACTER
+    u'\x17'     #  0x17 -> CONTROL CHARACTER
+    u'\x18'     #  0x18 -> CONTROL CHARACTER
+    u'\x19'     #  0x19 -> CONTROL CHARACTER
+    u'\x1a'     #  0x1A -> CONTROL CHARACTER
+    u'\x1b'     #  0x1B -> CONTROL CHARACTER
+    u'\x1c'     #  0x1C -> CONTROL CHARACTER
+    u'\x1d'     #  0x1D -> CONTROL CHARACTER
+    u'\x1e'     #  0x1E -> CONTROL CHARACTER
+    u'\x1f'     #  0x1F -> CONTROL CHARACTER
+    u' '        #  0x20 -> SPACE
+    u'!'        #  0x21 -> EXCLAMATION MARK
+    u'"'        #  0x22 -> QUOTATION MARK
+    u'#'        #  0x23 -> NUMBER SIGN
+    u'$'        #  0x24 -> DOLLAR SIGN
+    u'%'        #  0x25 -> PERCENT SIGN
+    u'&'        #  0x26 -> AMPERSAND
+    u"'"        #  0x27 -> APOSTROPHE
+    u'('        #  0x28 -> LEFT PARENTHESIS
+    u')'        #  0x29 -> RIGHT PARENTHESIS
+    u'*'        #  0x2A -> ASTERISK
+    u'+'        #  0x2B -> PLUS SIGN
+    u','        #  0x2C -> COMMA
+    u'-'        #  0x2D -> HYPHEN-MINUS
+    u'.'        #  0x2E -> FULL STOP
+    u'/'        #  0x2F -> SOLIDUS
+    u'0'        #  0x30 -> DIGIT ZERO
+    u'1'        #  0x31 -> DIGIT ONE
+    u'2'        #  0x32 -> DIGIT TWO
+    u'3'        #  0x33 -> DIGIT THREE
+    u'4'        #  0x34 -> DIGIT FOUR
+    u'5'        #  0x35 -> DIGIT FIVE
+    u'6'        #  0x36 -> DIGIT SIX
+    u'7'        #  0x37 -> DIGIT SEVEN
+    u'8'        #  0x38 -> DIGIT EIGHT
+    u'9'        #  0x39 -> DIGIT NINE
+    u':'        #  0x3A -> COLON
+    u';'        #  0x3B -> SEMICOLON
+    u'<'        #  0x3C -> LESS-THAN SIGN
+    u'='        #  0x3D -> EQUALS SIGN
+    u'>'        #  0x3E -> GREATER-THAN SIGN
+    u'?'        #  0x3F -> QUESTION MARK
+    u'@'        #  0x40 -> COMMERCIAL AT
+    u'A'        #  0x41 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x42 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x43 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x44 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x45 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x46 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x47 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x48 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x49 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x4A -> LATIN CAPITAL LETTER J
+    u'K'        #  0x4B -> LATIN CAPITAL LETTER K
+    u'L'        #  0x4C -> LATIN CAPITAL LETTER L
+    u'M'        #  0x4D -> LATIN CAPITAL LETTER M
+    u'N'        #  0x4E -> LATIN CAPITAL LETTER N
+    u'O'        #  0x4F -> LATIN CAPITAL LETTER O
+    u'P'        #  0x50 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x51 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x52 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x53 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x54 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x55 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x56 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x57 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x58 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x59 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x5A -> LATIN CAPITAL LETTER Z
+    u'['        #  0x5B -> LEFT SQUARE BRACKET
+    u'\\'       #  0x5C -> REVERSE SOLIDUS
+    u']'        #  0x5D -> RIGHT SQUARE BRACKET
+    u'^'        #  0x5E -> CIRCUMFLEX ACCENT
+    u'_'        #  0x5F -> LOW LINE
+    u'`'        #  0x60 -> GRAVE ACCENT
+    u'a'        #  0x61 -> LATIN SMALL LETTER A
+    u'b'        #  0x62 -> LATIN SMALL LETTER B
+    u'c'        #  0x63 -> LATIN SMALL LETTER C
+    u'd'        #  0x64 -> LATIN SMALL LETTER D
+    u'e'        #  0x65 -> LATIN SMALL LETTER E
+    u'f'        #  0x66 -> LATIN SMALL LETTER F
+    u'g'        #  0x67 -> LATIN SMALL LETTER G
+    u'h'        #  0x68 -> LATIN SMALL LETTER H
+    u'i'        #  0x69 -> LATIN SMALL LETTER I
+    u'j'        #  0x6A -> LATIN SMALL LETTER J
+    u'k'        #  0x6B -> LATIN SMALL LETTER K
+    u'l'        #  0x6C -> LATIN SMALL LETTER L
+    u'm'        #  0x6D -> LATIN SMALL LETTER M
+    u'n'        #  0x6E -> LATIN SMALL LETTER N
+    u'o'        #  0x6F -> LATIN SMALL LETTER O
+    u'p'        #  0x70 -> LATIN SMALL LETTER P
+    u'q'        #  0x71 -> LATIN SMALL LETTER Q
+    u'r'        #  0x72 -> LATIN SMALL LETTER R
+    u's'        #  0x73 -> LATIN SMALL LETTER S
+    u't'        #  0x74 -> LATIN SMALL LETTER T
+    u'u'        #  0x75 -> LATIN SMALL LETTER U
+    u'v'        #  0x76 -> LATIN SMALL LETTER V
+    u'w'        #  0x77 -> LATIN SMALL LETTER W
+    u'x'        #  0x78 -> LATIN SMALL LETTER X
+    u'y'        #  0x79 -> LATIN SMALL LETTER Y
+    u'z'        #  0x7A -> LATIN SMALL LETTER Z
+    u'{'        #  0x7B -> LEFT CURLY BRACKET
+    u'|'        #  0x7C -> VERTICAL LINE
+    u'}'        #  0x7D -> RIGHT CURLY BRACKET
+    u'~'        #  0x7E -> TILDE
+    u'\x7f'     #  0x7F -> CONTROL CHARACTER
+    u'\u0410'   #  0x80 -> CYRILLIC CAPITAL LETTER A
+    u'\u0411'   #  0x81 -> CYRILLIC CAPITAL LETTER BE
+    u'\u0412'   #  0x82 -> CYRILLIC CAPITAL LETTER VE
+    u'\u0413'   #  0x83 -> CYRILLIC CAPITAL LETTER GHE
+    u'\u0414'   #  0x84 -> CYRILLIC CAPITAL LETTER DE
+    u'\u0415'   #  0x85 -> CYRILLIC CAPITAL LETTER IE
+    u'\u0416'   #  0x86 -> CYRILLIC CAPITAL LETTER ZHE
+    u'\u0417'   #  0x87 -> CYRILLIC CAPITAL LETTER ZE
+    u'\u0418'   #  0x88 -> CYRILLIC CAPITAL LETTER I
+    u'\u0419'   #  0x89 -> CYRILLIC CAPITAL LETTER SHORT I
+    u'\u041a'   #  0x8A -> CYRILLIC CAPITAL LETTER KA
+    u'\u041b'   #  0x8B -> CYRILLIC CAPITAL LETTER EL
+    u'\u041c'   #  0x8C -> CYRILLIC CAPITAL LETTER EM
+    u'\u041d'   #  0x8D -> CYRILLIC CAPITAL LETTER EN
+    u'\u041e'   #  0x8E -> CYRILLIC CAPITAL LETTER O
+    u'\u041f'   #  0x8F -> CYRILLIC CAPITAL LETTER PE
+    u'\u0420'   #  0x90 -> CYRILLIC CAPITAL LETTER ER
+    u'\u0421'   #  0x91 -> CYRILLIC CAPITAL LETTER ES
+    u'\u0422'   #  0x92 -> CYRILLIC CAPITAL LETTER TE
+    u'\u0423'   #  0x93 -> CYRILLIC CAPITAL LETTER U
+    u'\u0424'   #  0x94 -> CYRILLIC CAPITAL LETTER EF
+    u'\u0425'   #  0x95 -> CYRILLIC CAPITAL LETTER HA
+    u'\u0426'   #  0x96 -> CYRILLIC CAPITAL LETTER TSE
+    u'\u0427'   #  0x97 -> CYRILLIC CAPITAL LETTER CHE
+    u'\u0428'   #  0x98 -> CYRILLIC CAPITAL LETTER SHA
+    u'\u0429'   #  0x99 -> CYRILLIC CAPITAL LETTER SHCHA
+    u'\u042a'   #  0x9A -> CYRILLIC CAPITAL LETTER HARD SIGN
+    u'\u042b'   #  0x9B -> CYRILLIC CAPITAL LETTER YERU
+    u'\u042c'   #  0x9C -> CYRILLIC CAPITAL LETTER SOFT SIGN
+    u'\u042d'   #  0x9D -> CYRILLIC CAPITAL LETTER E
+    u'\u042e'   #  0x9E -> CYRILLIC CAPITAL LETTER YU
+    u'\u042f'   #  0x9F -> CYRILLIC CAPITAL LETTER YA
+    u'\u2020'   #  0xA0 -> DAGGER
+    u'\xb0'     #  0xA1 -> DEGREE SIGN
+    u'\u0490'   #  0xA2 -> CYRILLIC CAPITAL LETTER GHE WITH UPTURN
+    u'\xa3'     #  0xA3 -> POUND SIGN
+    u'\xa7'     #  0xA4 -> SECTION SIGN
+    u'\u2022'   #  0xA5 -> BULLET
+    u'\xb6'     #  0xA6 -> PILCROW SIGN
+    u'\u0406'   #  0xA7 -> CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I
+    u'\xae'     #  0xA8 -> REGISTERED SIGN
+    u'\xa9'     #  0xA9 -> COPYRIGHT SIGN
+    u'\u2122'   #  0xAA -> TRADE MARK SIGN
+    u'\u0402'   #  0xAB -> CYRILLIC CAPITAL LETTER DJE
+    u'\u0452'   #  0xAC -> CYRILLIC SMALL LETTER DJE
+    u'\u2260'   #  0xAD -> NOT EQUAL TO
+    u'\u0403'   #  0xAE -> CYRILLIC CAPITAL LETTER GJE
+    u'\u0453'   #  0xAF -> CYRILLIC SMALL LETTER GJE
+    u'\u221e'   #  0xB0 -> INFINITY
+    u'\xb1'     #  0xB1 -> PLUS-MINUS SIGN
+    u'\u2264'   #  0xB2 -> LESS-THAN OR EQUAL TO
+    u'\u2265'   #  0xB3 -> GREATER-THAN OR EQUAL TO
+    u'\u0456'   #  0xB4 -> CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
+    u'\xb5'     #  0xB5 -> MICRO SIGN
+    u'\u0491'   #  0xB6 -> CYRILLIC SMALL LETTER GHE WITH UPTURN
+    u'\u0408'   #  0xB7 -> CYRILLIC CAPITAL LETTER JE
+    u'\u0404'   #  0xB8 -> CYRILLIC CAPITAL LETTER UKRAINIAN IE
+    u'\u0454'   #  0xB9 -> CYRILLIC SMALL LETTER UKRAINIAN IE
+    u'\u0407'   #  0xBA -> CYRILLIC CAPITAL LETTER YI
+    u'\u0457'   #  0xBB -> CYRILLIC SMALL LETTER YI
+    u'\u0409'   #  0xBC -> CYRILLIC CAPITAL LETTER LJE
+    u'\u0459'   #  0xBD -> CYRILLIC SMALL LETTER LJE
+    u'\u040a'   #  0xBE -> CYRILLIC CAPITAL LETTER NJE
+    u'\u045a'   #  0xBF -> CYRILLIC SMALL LETTER NJE
+    u'\u0458'   #  0xC0 -> CYRILLIC SMALL LETTER JE
+    u'\u0405'   #  0xC1 -> CYRILLIC CAPITAL LETTER DZE
+    u'\xac'     #  0xC2 -> NOT SIGN
+    u'\u221a'   #  0xC3 -> SQUARE ROOT
+    u'\u0192'   #  0xC4 -> LATIN SMALL LETTER F WITH HOOK
+    u'\u2248'   #  0xC5 -> ALMOST EQUAL TO
+    u'\u2206'   #  0xC6 -> INCREMENT
+    u'\xab'     #  0xC7 -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xbb'     #  0xC8 -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\u2026'   #  0xC9 -> HORIZONTAL ELLIPSIS
+    u'\xa0'     #  0xCA -> NO-BREAK SPACE
+    u'\u040b'   #  0xCB -> CYRILLIC CAPITAL LETTER TSHE
+    u'\u045b'   #  0xCC -> CYRILLIC SMALL LETTER TSHE
+    u'\u040c'   #  0xCD -> CYRILLIC CAPITAL LETTER KJE
+    u'\u045c'   #  0xCE -> CYRILLIC SMALL LETTER KJE
+    u'\u0455'   #  0xCF -> CYRILLIC SMALL LETTER DZE
+    u'\u2013'   #  0xD0 -> EN DASH
+    u'\u2014'   #  0xD1 -> EM DASH
+    u'\u201c'   #  0xD2 -> LEFT DOUBLE QUOTATION MARK
+    u'\u201d'   #  0xD3 -> RIGHT DOUBLE QUOTATION MARK
+    u'\u2018'   #  0xD4 -> LEFT SINGLE QUOTATION MARK
+    u'\u2019'   #  0xD5 -> RIGHT SINGLE QUOTATION MARK
+    u'\xf7'     #  0xD6 -> DIVISION SIGN
+    u'\u201e'   #  0xD7 -> DOUBLE LOW-9 QUOTATION MARK
+    u'\u040e'   #  0xD8 -> CYRILLIC CAPITAL LETTER SHORT U
+    u'\u045e'   #  0xD9 -> CYRILLIC SMALL LETTER SHORT U
+    u'\u040f'   #  0xDA -> CYRILLIC CAPITAL LETTER DZHE
+    u'\u045f'   #  0xDB -> CYRILLIC SMALL LETTER DZHE
+    u'\u2116'   #  0xDC -> NUMERO SIGN
+    u'\u0401'   #  0xDD -> CYRILLIC CAPITAL LETTER IO
+    u'\u0451'   #  0xDE -> CYRILLIC SMALL LETTER IO
+    u'\u044f'   #  0xDF -> CYRILLIC SMALL LETTER YA
+    u'\u0430'   #  0xE0 -> CYRILLIC SMALL LETTER A
+    u'\u0431'   #  0xE1 -> CYRILLIC SMALL LETTER BE
+    u'\u0432'   #  0xE2 -> CYRILLIC SMALL LETTER VE
+    u'\u0433'   #  0xE3 -> CYRILLIC SMALL LETTER GHE
+    u'\u0434'   #  0xE4 -> CYRILLIC SMALL LETTER DE
+    u'\u0435'   #  0xE5 -> CYRILLIC SMALL LETTER IE
+    u'\u0436'   #  0xE6 -> CYRILLIC SMALL LETTER ZHE
+    u'\u0437'   #  0xE7 -> CYRILLIC SMALL LETTER ZE
+    u'\u0438'   #  0xE8 -> CYRILLIC SMALL LETTER I
+    u'\u0439'   #  0xE9 -> CYRILLIC SMALL LETTER SHORT I
+    u'\u043a'   #  0xEA -> CYRILLIC SMALL LETTER KA
+    u'\u043b'   #  0xEB -> CYRILLIC SMALL LETTER EL
+    u'\u043c'   #  0xEC -> CYRILLIC SMALL LETTER EM
+    u'\u043d'   #  0xED -> CYRILLIC SMALL LETTER EN
+    u'\u043e'   #  0xEE -> CYRILLIC SMALL LETTER O
+    u'\u043f'   #  0xEF -> CYRILLIC SMALL LETTER PE
+    u'\u0440'   #  0xF0 -> CYRILLIC SMALL LETTER ER
+    u'\u0441'   #  0xF1 -> CYRILLIC SMALL LETTER ES
+    u'\u0442'   #  0xF2 -> CYRILLIC SMALL LETTER TE
+    u'\u0443'   #  0xF3 -> CYRILLIC SMALL LETTER U
+    u'\u0444'   #  0xF4 -> CYRILLIC SMALL LETTER EF
+    u'\u0445'   #  0xF5 -> CYRILLIC SMALL LETTER HA
+    u'\u0446'   #  0xF6 -> CYRILLIC SMALL LETTER TSE
+    u'\u0447'   #  0xF7 -> CYRILLIC SMALL LETTER CHE
+    u'\u0448'   #  0xF8 -> CYRILLIC SMALL LETTER SHA
+    u'\u0449'   #  0xF9 -> CYRILLIC SMALL LETTER SHCHA
+    u'\u044a'   #  0xFA -> CYRILLIC SMALL LETTER HARD SIGN
+    u'\u044b'   #  0xFB -> CYRILLIC SMALL LETTER YERU
+    u'\u044c'   #  0xFC -> CYRILLIC SMALL LETTER SOFT SIGN
+    u'\u044d'   #  0xFD -> CYRILLIC SMALL LETTER E
+    u'\u044e'   #  0xFE -> CYRILLIC SMALL LETTER YU
+    u'\u20ac'   #  0xFF -> EURO SIGN
+)
+
+### Encoding table
+encoding_table=codecs.charmap_build(decoding_table)

Added: vendor/Python/current/Lib/encodings/mac_farsi.py
===================================================================
--- vendor/Python/current/Lib/encodings/mac_farsi.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/mac_farsi.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,307 @@
+""" Python Character Mapping Codec mac_farsi generated from 'MAPPINGS/VENDORS/APPLE/FARSI.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_table)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_table)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='mac-farsi',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x00 -> CONTROL CHARACTER
+    u'\x01'     #  0x01 -> CONTROL CHARACTER
+    u'\x02'     #  0x02 -> CONTROL CHARACTER
+    u'\x03'     #  0x03 -> CONTROL CHARACTER
+    u'\x04'     #  0x04 -> CONTROL CHARACTER
+    u'\x05'     #  0x05 -> CONTROL CHARACTER
+    u'\x06'     #  0x06 -> CONTROL CHARACTER
+    u'\x07'     #  0x07 -> CONTROL CHARACTER
+    u'\x08'     #  0x08 -> CONTROL CHARACTER
+    u'\t'       #  0x09 -> CONTROL CHARACTER
+    u'\n'       #  0x0A -> CONTROL CHARACTER
+    u'\x0b'     #  0x0B -> CONTROL CHARACTER
+    u'\x0c'     #  0x0C -> CONTROL CHARACTER
+    u'\r'       #  0x0D -> CONTROL CHARACTER
+    u'\x0e'     #  0x0E -> CONTROL CHARACTER
+    u'\x0f'     #  0x0F -> CONTROL CHARACTER
+    u'\x10'     #  0x10 -> CONTROL CHARACTER
+    u'\x11'     #  0x11 -> CONTROL CHARACTER
+    u'\x12'     #  0x12 -> CONTROL CHARACTER
+    u'\x13'     #  0x13 -> CONTROL CHARACTER
+    u'\x14'     #  0x14 -> CONTROL CHARACTER
+    u'\x15'     #  0x15 -> CONTROL CHARACTER
+    u'\x16'     #  0x16 -> CONTROL CHARACTER
+    u'\x17'     #  0x17 -> CONTROL CHARACTER
+    u'\x18'     #  0x18 -> CONTROL CHARACTER
+    u'\x19'     #  0x19 -> CONTROL CHARACTER
+    u'\x1a'     #  0x1A -> CONTROL CHARACTER
+    u'\x1b'     #  0x1B -> CONTROL CHARACTER
+    u'\x1c'     #  0x1C -> CONTROL CHARACTER
+    u'\x1d'     #  0x1D -> CONTROL CHARACTER
+    u'\x1e'     #  0x1E -> CONTROL CHARACTER
+    u'\x1f'     #  0x1F -> CONTROL CHARACTER
+    u' '        #  0x20 -> SPACE, left-right
+    u'!'        #  0x21 -> EXCLAMATION MARK, left-right
+    u'"'        #  0x22 -> QUOTATION MARK, left-right
+    u'#'        #  0x23 -> NUMBER SIGN, left-right
+    u'$'        #  0x24 -> DOLLAR SIGN, left-right
+    u'%'        #  0x25 -> PERCENT SIGN, left-right
+    u'&'        #  0x26 -> AMPERSAND, left-right
+    u"'"        #  0x27 -> APOSTROPHE, left-right
+    u'('        #  0x28 -> LEFT PARENTHESIS, left-right
+    u')'        #  0x29 -> RIGHT PARENTHESIS, left-right
+    u'*'        #  0x2A -> ASTERISK, left-right
+    u'+'        #  0x2B -> PLUS SIGN, left-right
+    u','        #  0x2C -> COMMA, left-right; in Arabic-script context, displayed as 0x066C ARABIC THOUSANDS SEPARATOR
+    u'-'        #  0x2D -> HYPHEN-MINUS, left-right
+    u'.'        #  0x2E -> FULL STOP, left-right; in Arabic-script context, displayed as 0x066B ARABIC DECIMAL SEPARATOR
+    u'/'        #  0x2F -> SOLIDUS, left-right
+    u'0'        #  0x30 -> DIGIT ZERO;  in Arabic-script context, displayed as 0x06F0 EXTENDED ARABIC-INDIC DIGIT ZERO
+    u'1'        #  0x31 -> DIGIT ONE;   in Arabic-script context, displayed as 0x06F1 EXTENDED ARABIC-INDIC DIGIT ONE
+    u'2'        #  0x32 -> DIGIT TWO;   in Arabic-script context, displayed as 0x06F2 EXTENDED ARABIC-INDIC DIGIT TWO
+    u'3'        #  0x33 -> DIGIT THREE; in Arabic-script context, displayed as 0x06F3 EXTENDED ARABIC-INDIC DIGIT THREE
+    u'4'        #  0x34 -> DIGIT FOUR;  in Arabic-script context, displayed as 0x06F4 EXTENDED ARABIC-INDIC DIGIT FOUR
+    u'5'        #  0x35 -> DIGIT FIVE;  in Arabic-script context, displayed as 0x06F5 EXTENDED ARABIC-INDIC DIGIT FIVE
+    u'6'        #  0x36 -> DIGIT SIX;   in Arabic-script context, displayed as 0x06F6 EXTENDED ARABIC-INDIC DIGIT SIX
+    u'7'        #  0x37 -> DIGIT SEVEN; in Arabic-script context, displayed as 0x06F7 EXTENDED ARABIC-INDIC DIGIT SEVEN
+    u'8'        #  0x38 -> DIGIT EIGHT; in Arabic-script context, displayed as 0x06F8 EXTENDED ARABIC-INDIC DIGIT EIGHT
+    u'9'        #  0x39 -> DIGIT NINE;  in Arabic-script context, displayed as 0x06F9 EXTENDED ARABIC-INDIC DIGIT NINE
+    u':'        #  0x3A -> COLON, left-right
+    u';'        #  0x3B -> SEMICOLON, left-right
+    u'<'        #  0x3C -> LESS-THAN SIGN, left-right
+    u'='        #  0x3D -> EQUALS SIGN, left-right
+    u'>'        #  0x3E -> GREATER-THAN SIGN, left-right
+    u'?'        #  0x3F -> QUESTION MARK, left-right
+    u'@'        #  0x40 -> COMMERCIAL AT
+    u'A'        #  0x41 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x42 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x43 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x44 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x45 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x46 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x47 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x48 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x49 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x4A -> LATIN CAPITAL LETTER J
+    u'K'        #  0x4B -> LATIN CAPITAL LETTER K
+    u'L'        #  0x4C -> LATIN CAPITAL LETTER L
+    u'M'        #  0x4D -> LATIN CAPITAL LETTER M
+    u'N'        #  0x4E -> LATIN CAPITAL LETTER N
+    u'O'        #  0x4F -> LATIN CAPITAL LETTER O
+    u'P'        #  0x50 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x51 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x52 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x53 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x54 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x55 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x56 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x57 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x58 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x59 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x5A -> LATIN CAPITAL LETTER Z
+    u'['        #  0x5B -> LEFT SQUARE BRACKET, left-right
+    u'\\'       #  0x5C -> REVERSE SOLIDUS, left-right
+    u']'        #  0x5D -> RIGHT SQUARE BRACKET, left-right
+    u'^'        #  0x5E -> CIRCUMFLEX ACCENT, left-right
+    u'_'        #  0x5F -> LOW LINE, left-right
+    u'`'        #  0x60 -> GRAVE ACCENT
+    u'a'        #  0x61 -> LATIN SMALL LETTER A
+    u'b'        #  0x62 -> LATIN SMALL LETTER B
+    u'c'        #  0x63 -> LATIN SMALL LETTER C
+    u'd'        #  0x64 -> LATIN SMALL LETTER D
+    u'e'        #  0x65 -> LATIN SMALL LETTER E
+    u'f'        #  0x66 -> LATIN SMALL LETTER F
+    u'g'        #  0x67 -> LATIN SMALL LETTER G
+    u'h'        #  0x68 -> LATIN SMALL LETTER H
+    u'i'        #  0x69 -> LATIN SMALL LETTER I
+    u'j'        #  0x6A -> LATIN SMALL LETTER J
+    u'k'        #  0x6B -> LATIN SMALL LETTER K
+    u'l'        #  0x6C -> LATIN SMALL LETTER L
+    u'm'        #  0x6D -> LATIN SMALL LETTER M
+    u'n'        #  0x6E -> LATIN SMALL LETTER N
+    u'o'        #  0x6F -> LATIN SMALL LETTER O
+    u'p'        #  0x70 -> LATIN SMALL LETTER P
+    u'q'        #  0x71 -> LATIN SMALL LETTER Q
+    u'r'        #  0x72 -> LATIN SMALL LETTER R
+    u's'        #  0x73 -> LATIN SMALL LETTER S
+    u't'        #  0x74 -> LATIN SMALL LETTER T
+    u'u'        #  0x75 -> LATIN SMALL LETTER U
+    u'v'        #  0x76 -> LATIN SMALL LETTER V
+    u'w'        #  0x77 -> LATIN SMALL LETTER W
+    u'x'        #  0x78 -> LATIN SMALL LETTER X
+    u'y'        #  0x79 -> LATIN SMALL LETTER Y
+    u'z'        #  0x7A -> LATIN SMALL LETTER Z
+    u'{'        #  0x7B -> LEFT CURLY BRACKET, left-right
+    u'|'        #  0x7C -> VERTICAL LINE, left-right
+    u'}'        #  0x7D -> RIGHT CURLY BRACKET, left-right
+    u'~'        #  0x7E -> TILDE
+    u'\x7f'     #  0x7F -> CONTROL CHARACTER
+    u'\xc4'     #  0x80 -> LATIN CAPITAL LETTER A WITH DIAERESIS
+    u'\xa0'     #  0x81 -> NO-BREAK SPACE, right-left
+    u'\xc7'     #  0x82 -> LATIN CAPITAL LETTER C WITH CEDILLA
+    u'\xc9'     #  0x83 -> LATIN CAPITAL LETTER E WITH ACUTE
+    u'\xd1'     #  0x84 -> LATIN CAPITAL LETTER N WITH TILDE
+    u'\xd6'     #  0x85 -> LATIN CAPITAL LETTER O WITH DIAERESIS
+    u'\xdc'     #  0x86 -> LATIN CAPITAL LETTER U WITH DIAERESIS
+    u'\xe1'     #  0x87 -> LATIN SMALL LETTER A WITH ACUTE
+    u'\xe0'     #  0x88 -> LATIN SMALL LETTER A WITH GRAVE
+    u'\xe2'     #  0x89 -> LATIN SMALL LETTER A WITH CIRCUMFLEX
+    u'\xe4'     #  0x8A -> LATIN SMALL LETTER A WITH DIAERESIS
+    u'\u06ba'   #  0x8B -> ARABIC LETTER NOON GHUNNA
+    u'\xab'     #  0x8C -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK, right-left
+    u'\xe7'     #  0x8D -> LATIN SMALL LETTER C WITH CEDILLA
+    u'\xe9'     #  0x8E -> LATIN SMALL LETTER E WITH ACUTE
+    u'\xe8'     #  0x8F -> LATIN SMALL LETTER E WITH GRAVE
+    u'\xea'     #  0x90 -> LATIN SMALL LETTER E WITH CIRCUMFLEX
+    u'\xeb'     #  0x91 -> LATIN SMALL LETTER E WITH DIAERESIS
+    u'\xed'     #  0x92 -> LATIN SMALL LETTER I WITH ACUTE
+    u'\u2026'   #  0x93 -> HORIZONTAL ELLIPSIS, right-left
+    u'\xee'     #  0x94 -> LATIN SMALL LETTER I WITH CIRCUMFLEX
+    u'\xef'     #  0x95 -> LATIN SMALL LETTER I WITH DIAERESIS
+    u'\xf1'     #  0x96 -> LATIN SMALL LETTER N WITH TILDE
+    u'\xf3'     #  0x97 -> LATIN SMALL LETTER O WITH ACUTE
+    u'\xbb'     #  0x98 -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK, right-left
+    u'\xf4'     #  0x99 -> LATIN SMALL LETTER O WITH CIRCUMFLEX
+    u'\xf6'     #  0x9A -> LATIN SMALL LETTER O WITH DIAERESIS
+    u'\xf7'     #  0x9B -> DIVISION SIGN, right-left
+    u'\xfa'     #  0x9C -> LATIN SMALL LETTER U WITH ACUTE
+    u'\xf9'     #  0x9D -> LATIN SMALL LETTER U WITH GRAVE
+    u'\xfb'     #  0x9E -> LATIN SMALL LETTER U WITH CIRCUMFLEX
+    u'\xfc'     #  0x9F -> LATIN SMALL LETTER U WITH DIAERESIS
+    u' '        #  0xA0 -> SPACE, right-left
+    u'!'        #  0xA1 -> EXCLAMATION MARK, right-left
+    u'"'        #  0xA2 -> QUOTATION MARK, right-left
+    u'#'        #  0xA3 -> NUMBER SIGN, right-left
+    u'$'        #  0xA4 -> DOLLAR SIGN, right-left
+    u'\u066a'   #  0xA5 -> ARABIC PERCENT SIGN
+    u'&'        #  0xA6 -> AMPERSAND, right-left
+    u"'"        #  0xA7 -> APOSTROPHE, right-left
+    u'('        #  0xA8 -> LEFT PARENTHESIS, right-left
+    u')'        #  0xA9 -> RIGHT PARENTHESIS, right-left
+    u'*'        #  0xAA -> ASTERISK, right-left
+    u'+'        #  0xAB -> PLUS SIGN, right-left
+    u'\u060c'   #  0xAC -> ARABIC COMMA
+    u'-'        #  0xAD -> HYPHEN-MINUS, right-left
+    u'.'        #  0xAE -> FULL STOP, right-left
+    u'/'        #  0xAF -> SOLIDUS, right-left
+    u'\u06f0'   #  0xB0 -> EXTENDED ARABIC-INDIC DIGIT ZERO, right-left (need override)
+    u'\u06f1'   #  0xB1 -> EXTENDED ARABIC-INDIC DIGIT ONE, right-left (need override)
+    u'\u06f2'   #  0xB2 -> EXTENDED ARABIC-INDIC DIGIT TWO, right-left (need override)
+    u'\u06f3'   #  0xB3 -> EXTENDED ARABIC-INDIC DIGIT THREE, right-left (need override)
+    u'\u06f4'   #  0xB4 -> EXTENDED ARABIC-INDIC DIGIT FOUR, right-left (need override)
+    u'\u06f5'   #  0xB5 -> EXTENDED ARABIC-INDIC DIGIT FIVE, right-left (need override)
+    u'\u06f6'   #  0xB6 -> EXTENDED ARABIC-INDIC DIGIT SIX, right-left (need override)
+    u'\u06f7'   #  0xB7 -> EXTENDED ARABIC-INDIC DIGIT SEVEN, right-left (need override)
+    u'\u06f8'   #  0xB8 -> EXTENDED ARABIC-INDIC DIGIT EIGHT, right-left (need override)
+    u'\u06f9'   #  0xB9 -> EXTENDED ARABIC-INDIC DIGIT NINE, right-left (need override)
+    u':'        #  0xBA -> COLON, right-left
+    u'\u061b'   #  0xBB -> ARABIC SEMICOLON
+    u'<'        #  0xBC -> LESS-THAN SIGN, right-left
+    u'='        #  0xBD -> EQUALS SIGN, right-left
+    u'>'        #  0xBE -> GREATER-THAN SIGN, right-left
+    u'\u061f'   #  0xBF -> ARABIC QUESTION MARK
+    u'\u274a'   #  0xC0 -> EIGHT TEARDROP-SPOKED PROPELLER ASTERISK, right-left
+    u'\u0621'   #  0xC1 -> ARABIC LETTER HAMZA
+    u'\u0622'   #  0xC2 -> ARABIC LETTER ALEF WITH MADDA ABOVE
+    u'\u0623'   #  0xC3 -> ARABIC LETTER ALEF WITH HAMZA ABOVE
+    u'\u0624'   #  0xC4 -> ARABIC LETTER WAW WITH HAMZA ABOVE
+    u'\u0625'   #  0xC5 -> ARABIC LETTER ALEF WITH HAMZA BELOW
+    u'\u0626'   #  0xC6 -> ARABIC LETTER YEH WITH HAMZA ABOVE
+    u'\u0627'   #  0xC7 -> ARABIC LETTER ALEF
+    u'\u0628'   #  0xC8 -> ARABIC LETTER BEH
+    u'\u0629'   #  0xC9 -> ARABIC LETTER TEH MARBUTA
+    u'\u062a'   #  0xCA -> ARABIC LETTER TEH
+    u'\u062b'   #  0xCB -> ARABIC LETTER THEH
+    u'\u062c'   #  0xCC -> ARABIC LETTER JEEM
+    u'\u062d'   #  0xCD -> ARABIC LETTER HAH
+    u'\u062e'   #  0xCE -> ARABIC LETTER KHAH
+    u'\u062f'   #  0xCF -> ARABIC LETTER DAL
+    u'\u0630'   #  0xD0 -> ARABIC LETTER THAL
+    u'\u0631'   #  0xD1 -> ARABIC LETTER REH
+    u'\u0632'   #  0xD2 -> ARABIC LETTER ZAIN
+    u'\u0633'   #  0xD3 -> ARABIC LETTER SEEN
+    u'\u0634'   #  0xD4 -> ARABIC LETTER SHEEN
+    u'\u0635'   #  0xD5 -> ARABIC LETTER SAD
+    u'\u0636'   #  0xD6 -> ARABIC LETTER DAD
+    u'\u0637'   #  0xD7 -> ARABIC LETTER TAH
+    u'\u0638'   #  0xD8 -> ARABIC LETTER ZAH
+    u'\u0639'   #  0xD9 -> ARABIC LETTER AIN
+    u'\u063a'   #  0xDA -> ARABIC LETTER GHAIN
+    u'['        #  0xDB -> LEFT SQUARE BRACKET, right-left
+    u'\\'       #  0xDC -> REVERSE SOLIDUS, right-left
+    u']'        #  0xDD -> RIGHT SQUARE BRACKET, right-left
+    u'^'        #  0xDE -> CIRCUMFLEX ACCENT, right-left
+    u'_'        #  0xDF -> LOW LINE, right-left
+    u'\u0640'   #  0xE0 -> ARABIC TATWEEL
+    u'\u0641'   #  0xE1 -> ARABIC LETTER FEH
+    u'\u0642'   #  0xE2 -> ARABIC LETTER QAF
+    u'\u0643'   #  0xE3 -> ARABIC LETTER KAF
+    u'\u0644'   #  0xE4 -> ARABIC LETTER LAM
+    u'\u0645'   #  0xE5 -> ARABIC LETTER MEEM
+    u'\u0646'   #  0xE6 -> ARABIC LETTER NOON
+    u'\u0647'   #  0xE7 -> ARABIC LETTER HEH
+    u'\u0648'   #  0xE8 -> ARABIC LETTER WAW
+    u'\u0649'   #  0xE9 -> ARABIC LETTER ALEF MAKSURA
+    u'\u064a'   #  0xEA -> ARABIC LETTER YEH
+    u'\u064b'   #  0xEB -> ARABIC FATHATAN
+    u'\u064c'   #  0xEC -> ARABIC DAMMATAN
+    u'\u064d'   #  0xED -> ARABIC KASRATAN
+    u'\u064e'   #  0xEE -> ARABIC FATHA
+    u'\u064f'   #  0xEF -> ARABIC DAMMA
+    u'\u0650'   #  0xF0 -> ARABIC KASRA
+    u'\u0651'   #  0xF1 -> ARABIC SHADDA
+    u'\u0652'   #  0xF2 -> ARABIC SUKUN
+    u'\u067e'   #  0xF3 -> ARABIC LETTER PEH
+    u'\u0679'   #  0xF4 -> ARABIC LETTER TTEH
+    u'\u0686'   #  0xF5 -> ARABIC LETTER TCHEH
+    u'\u06d5'   #  0xF6 -> ARABIC LETTER AE
+    u'\u06a4'   #  0xF7 -> ARABIC LETTER VEH
+    u'\u06af'   #  0xF8 -> ARABIC LETTER GAF
+    u'\u0688'   #  0xF9 -> ARABIC LETTER DDAL
+    u'\u0691'   #  0xFA -> ARABIC LETTER RREH
+    u'{'        #  0xFB -> LEFT CURLY BRACKET, right-left
+    u'|'        #  0xFC -> VERTICAL LINE, right-left
+    u'}'        #  0xFD -> RIGHT CURLY BRACKET, right-left
+    u'\u0698'   #  0xFE -> ARABIC LETTER JEH
+    u'\u06d2'   #  0xFF -> ARABIC LETTER YEH BARREE
+)
+
+### Encoding table
+encoding_table=codecs.charmap_build(decoding_table)

Added: vendor/Python/current/Lib/encodings/mac_greek.py
===================================================================
--- vendor/Python/current/Lib/encodings/mac_greek.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/mac_greek.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,307 @@
+""" Python Character Mapping Codec mac_greek generated from 'MAPPINGS/VENDORS/APPLE/GREEK.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_table)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_table)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='mac-greek',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x00 -> CONTROL CHARACTER
+    u'\x01'     #  0x01 -> CONTROL CHARACTER
+    u'\x02'     #  0x02 -> CONTROL CHARACTER
+    u'\x03'     #  0x03 -> CONTROL CHARACTER
+    u'\x04'     #  0x04 -> CONTROL CHARACTER
+    u'\x05'     #  0x05 -> CONTROL CHARACTER
+    u'\x06'     #  0x06 -> CONTROL CHARACTER
+    u'\x07'     #  0x07 -> CONTROL CHARACTER
+    u'\x08'     #  0x08 -> CONTROL CHARACTER
+    u'\t'       #  0x09 -> CONTROL CHARACTER
+    u'\n'       #  0x0A -> CONTROL CHARACTER
+    u'\x0b'     #  0x0B -> CONTROL CHARACTER
+    u'\x0c'     #  0x0C -> CONTROL CHARACTER
+    u'\r'       #  0x0D -> CONTROL CHARACTER
+    u'\x0e'     #  0x0E -> CONTROL CHARACTER
+    u'\x0f'     #  0x0F -> CONTROL CHARACTER
+    u'\x10'     #  0x10 -> CONTROL CHARACTER
+    u'\x11'     #  0x11 -> CONTROL CHARACTER
+    u'\x12'     #  0x12 -> CONTROL CHARACTER
+    u'\x13'     #  0x13 -> CONTROL CHARACTER
+    u'\x14'     #  0x14 -> CONTROL CHARACTER
+    u'\x15'     #  0x15 -> CONTROL CHARACTER
+    u'\x16'     #  0x16 -> CONTROL CHARACTER
+    u'\x17'     #  0x17 -> CONTROL CHARACTER
+    u'\x18'     #  0x18 -> CONTROL CHARACTER
+    u'\x19'     #  0x19 -> CONTROL CHARACTER
+    u'\x1a'     #  0x1A -> CONTROL CHARACTER
+    u'\x1b'     #  0x1B -> CONTROL CHARACTER
+    u'\x1c'     #  0x1C -> CONTROL CHARACTER
+    u'\x1d'     #  0x1D -> CONTROL CHARACTER
+    u'\x1e'     #  0x1E -> CONTROL CHARACTER
+    u'\x1f'     #  0x1F -> CONTROL CHARACTER
+    u' '        #  0x20 -> SPACE
+    u'!'        #  0x21 -> EXCLAMATION MARK
+    u'"'        #  0x22 -> QUOTATION MARK
+    u'#'        #  0x23 -> NUMBER SIGN
+    u'$'        #  0x24 -> DOLLAR SIGN
+    u'%'        #  0x25 -> PERCENT SIGN
+    u'&'        #  0x26 -> AMPERSAND
+    u"'"        #  0x27 -> APOSTROPHE
+    u'('        #  0x28 -> LEFT PARENTHESIS
+    u')'        #  0x29 -> RIGHT PARENTHESIS
+    u'*'        #  0x2A -> ASTERISK
+    u'+'        #  0x2B -> PLUS SIGN
+    u','        #  0x2C -> COMMA
+    u'-'        #  0x2D -> HYPHEN-MINUS
+    u'.'        #  0x2E -> FULL STOP
+    u'/'        #  0x2F -> SOLIDUS
+    u'0'        #  0x30 -> DIGIT ZERO
+    u'1'        #  0x31 -> DIGIT ONE
+    u'2'        #  0x32 -> DIGIT TWO
+    u'3'        #  0x33 -> DIGIT THREE
+    u'4'        #  0x34 -> DIGIT FOUR
+    u'5'        #  0x35 -> DIGIT FIVE
+    u'6'        #  0x36 -> DIGIT SIX
+    u'7'        #  0x37 -> DIGIT SEVEN
+    u'8'        #  0x38 -> DIGIT EIGHT
+    u'9'        #  0x39 -> DIGIT NINE
+    u':'        #  0x3A -> COLON
+    u';'        #  0x3B -> SEMICOLON
+    u'<'        #  0x3C -> LESS-THAN SIGN
+    u'='        #  0x3D -> EQUALS SIGN
+    u'>'        #  0x3E -> GREATER-THAN SIGN
+    u'?'        #  0x3F -> QUESTION MARK
+    u'@'        #  0x40 -> COMMERCIAL AT
+    u'A'        #  0x41 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x42 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x43 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x44 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x45 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x46 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x47 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x48 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x49 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x4A -> LATIN CAPITAL LETTER J
+    u'K'        #  0x4B -> LATIN CAPITAL LETTER K
+    u'L'        #  0x4C -> LATIN CAPITAL LETTER L
+    u'M'        #  0x4D -> LATIN CAPITAL LETTER M
+    u'N'        #  0x4E -> LATIN CAPITAL LETTER N
+    u'O'        #  0x4F -> LATIN CAPITAL LETTER O
+    u'P'        #  0x50 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x51 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x52 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x53 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x54 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x55 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x56 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x57 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x58 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x59 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x5A -> LATIN CAPITAL LETTER Z
+    u'['        #  0x5B -> LEFT SQUARE BRACKET
+    u'\\'       #  0x5C -> REVERSE SOLIDUS
+    u']'        #  0x5D -> RIGHT SQUARE BRACKET
+    u'^'        #  0x5E -> CIRCUMFLEX ACCENT
+    u'_'        #  0x5F -> LOW LINE
+    u'`'        #  0x60 -> GRAVE ACCENT
+    u'a'        #  0x61 -> LATIN SMALL LETTER A
+    u'b'        #  0x62 -> LATIN SMALL LETTER B
+    u'c'        #  0x63 -> LATIN SMALL LETTER C
+    u'd'        #  0x64 -> LATIN SMALL LETTER D
+    u'e'        #  0x65 -> LATIN SMALL LETTER E
+    u'f'        #  0x66 -> LATIN SMALL LETTER F
+    u'g'        #  0x67 -> LATIN SMALL LETTER G
+    u'h'        #  0x68 -> LATIN SMALL LETTER H
+    u'i'        #  0x69 -> LATIN SMALL LETTER I
+    u'j'        #  0x6A -> LATIN SMALL LETTER J
+    u'k'        #  0x6B -> LATIN SMALL LETTER K
+    u'l'        #  0x6C -> LATIN SMALL LETTER L
+    u'm'        #  0x6D -> LATIN SMALL LETTER M
+    u'n'        #  0x6E -> LATIN SMALL LETTER N
+    u'o'        #  0x6F -> LATIN SMALL LETTER O
+    u'p'        #  0x70 -> LATIN SMALL LETTER P
+    u'q'        #  0x71 -> LATIN SMALL LETTER Q
+    u'r'        #  0x72 -> LATIN SMALL LETTER R
+    u's'        #  0x73 -> LATIN SMALL LETTER S
+    u't'        #  0x74 -> LATIN SMALL LETTER T
+    u'u'        #  0x75 -> LATIN SMALL LETTER U
+    u'v'        #  0x76 -> LATIN SMALL LETTER V
+    u'w'        #  0x77 -> LATIN SMALL LETTER W
+    u'x'        #  0x78 -> LATIN SMALL LETTER X
+    u'y'        #  0x79 -> LATIN SMALL LETTER Y
+    u'z'        #  0x7A -> LATIN SMALL LETTER Z
+    u'{'        #  0x7B -> LEFT CURLY BRACKET
+    u'|'        #  0x7C -> VERTICAL LINE
+    u'}'        #  0x7D -> RIGHT CURLY BRACKET
+    u'~'        #  0x7E -> TILDE
+    u'\x7f'     #  0x7F -> CONTROL CHARACTER
+    u'\xc4'     #  0x80 -> LATIN CAPITAL LETTER A WITH DIAERESIS
+    u'\xb9'     #  0x81 -> SUPERSCRIPT ONE
+    u'\xb2'     #  0x82 -> SUPERSCRIPT TWO
+    u'\xc9'     #  0x83 -> LATIN CAPITAL LETTER E WITH ACUTE
+    u'\xb3'     #  0x84 -> SUPERSCRIPT THREE
+    u'\xd6'     #  0x85 -> LATIN CAPITAL LETTER O WITH DIAERESIS
+    u'\xdc'     #  0x86 -> LATIN CAPITAL LETTER U WITH DIAERESIS
+    u'\u0385'   #  0x87 -> GREEK DIALYTIKA TONOS
+    u'\xe0'     #  0x88 -> LATIN SMALL LETTER A WITH GRAVE
+    u'\xe2'     #  0x89 -> LATIN SMALL LETTER A WITH CIRCUMFLEX
+    u'\xe4'     #  0x8A -> LATIN SMALL LETTER A WITH DIAERESIS
+    u'\u0384'   #  0x8B -> GREEK TONOS
+    u'\xa8'     #  0x8C -> DIAERESIS
+    u'\xe7'     #  0x8D -> LATIN SMALL LETTER C WITH CEDILLA
+    u'\xe9'     #  0x8E -> LATIN SMALL LETTER E WITH ACUTE
+    u'\xe8'     #  0x8F -> LATIN SMALL LETTER E WITH GRAVE
+    u'\xea'     #  0x90 -> LATIN SMALL LETTER E WITH CIRCUMFLEX
+    u'\xeb'     #  0x91 -> LATIN SMALL LETTER E WITH DIAERESIS
+    u'\xa3'     #  0x92 -> POUND SIGN
+    u'\u2122'   #  0x93 -> TRADE MARK SIGN
+    u'\xee'     #  0x94 -> LATIN SMALL LETTER I WITH CIRCUMFLEX
+    u'\xef'     #  0x95 -> LATIN SMALL LETTER I WITH DIAERESIS
+    u'\u2022'   #  0x96 -> BULLET
+    u'\xbd'     #  0x97 -> VULGAR FRACTION ONE HALF
+    u'\u2030'   #  0x98 -> PER MILLE SIGN
+    u'\xf4'     #  0x99 -> LATIN SMALL LETTER O WITH CIRCUMFLEX
+    u'\xf6'     #  0x9A -> LATIN SMALL LETTER O WITH DIAERESIS
+    u'\xa6'     #  0x9B -> BROKEN BAR
+    u'\u20ac'   #  0x9C -> EURO SIGN # before Mac OS 9.2.2, was SOFT HYPHEN
+    u'\xf9'     #  0x9D -> LATIN SMALL LETTER U WITH GRAVE
+    u'\xfb'     #  0x9E -> LATIN SMALL LETTER U WITH CIRCUMFLEX
+    u'\xfc'     #  0x9F -> LATIN SMALL LETTER U WITH DIAERESIS
+    u'\u2020'   #  0xA0 -> DAGGER
+    u'\u0393'   #  0xA1 -> GREEK CAPITAL LETTER GAMMA
+    u'\u0394'   #  0xA2 -> GREEK CAPITAL LETTER DELTA
+    u'\u0398'   #  0xA3 -> GREEK CAPITAL LETTER THETA
+    u'\u039b'   #  0xA4 -> GREEK CAPITAL LETTER LAMDA
+    u'\u039e'   #  0xA5 -> GREEK CAPITAL LETTER XI
+    u'\u03a0'   #  0xA6 -> GREEK CAPITAL LETTER PI
+    u'\xdf'     #  0xA7 -> LATIN SMALL LETTER SHARP S
+    u'\xae'     #  0xA8 -> REGISTERED SIGN
+    u'\xa9'     #  0xA9 -> COPYRIGHT SIGN
+    u'\u03a3'   #  0xAA -> GREEK CAPITAL LETTER SIGMA
+    u'\u03aa'   #  0xAB -> GREEK CAPITAL LETTER IOTA WITH DIALYTIKA
+    u'\xa7'     #  0xAC -> SECTION SIGN
+    u'\u2260'   #  0xAD -> NOT EQUAL TO
+    u'\xb0'     #  0xAE -> DEGREE SIGN
+    u'\xb7'     #  0xAF -> MIDDLE DOT
+    u'\u0391'   #  0xB0 -> GREEK CAPITAL LETTER ALPHA
+    u'\xb1'     #  0xB1 -> PLUS-MINUS SIGN
+    u'\u2264'   #  0xB2 -> LESS-THAN OR EQUAL TO
+    u'\u2265'   #  0xB3 -> GREATER-THAN OR EQUAL TO
+    u'\xa5'     #  0xB4 -> YEN SIGN
+    u'\u0392'   #  0xB5 -> GREEK CAPITAL LETTER BETA
+    u'\u0395'   #  0xB6 -> GREEK CAPITAL LETTER EPSILON
+    u'\u0396'   #  0xB7 -> GREEK CAPITAL LETTER ZETA
+    u'\u0397'   #  0xB8 -> GREEK CAPITAL LETTER ETA
+    u'\u0399'   #  0xB9 -> GREEK CAPITAL LETTER IOTA
+    u'\u039a'   #  0xBA -> GREEK CAPITAL LETTER KAPPA
+    u'\u039c'   #  0xBB -> GREEK CAPITAL LETTER MU
+    u'\u03a6'   #  0xBC -> GREEK CAPITAL LETTER PHI
+    u'\u03ab'   #  0xBD -> GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA
+    u'\u03a8'   #  0xBE -> GREEK CAPITAL LETTER PSI
+    u'\u03a9'   #  0xBF -> GREEK CAPITAL LETTER OMEGA
+    u'\u03ac'   #  0xC0 -> GREEK SMALL LETTER ALPHA WITH TONOS
+    u'\u039d'   #  0xC1 -> GREEK CAPITAL LETTER NU
+    u'\xac'     #  0xC2 -> NOT SIGN
+    u'\u039f'   #  0xC3 -> GREEK CAPITAL LETTER OMICRON
+    u'\u03a1'   #  0xC4 -> GREEK CAPITAL LETTER RHO
+    u'\u2248'   #  0xC5 -> ALMOST EQUAL TO
+    u'\u03a4'   #  0xC6 -> GREEK CAPITAL LETTER TAU
+    u'\xab'     #  0xC7 -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xbb'     #  0xC8 -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\u2026'   #  0xC9 -> HORIZONTAL ELLIPSIS
+    u'\xa0'     #  0xCA -> NO-BREAK SPACE
+    u'\u03a5'   #  0xCB -> GREEK CAPITAL LETTER UPSILON
+    u'\u03a7'   #  0xCC -> GREEK CAPITAL LETTER CHI
+    u'\u0386'   #  0xCD -> GREEK CAPITAL LETTER ALPHA WITH TONOS
+    u'\u0388'   #  0xCE -> GREEK CAPITAL LETTER EPSILON WITH TONOS
+    u'\u0153'   #  0xCF -> LATIN SMALL LIGATURE OE
+    u'\u2013'   #  0xD0 -> EN DASH
+    u'\u2015'   #  0xD1 -> HORIZONTAL BAR
+    u'\u201c'   #  0xD2 -> LEFT DOUBLE QUOTATION MARK
+    u'\u201d'   #  0xD3 -> RIGHT DOUBLE QUOTATION MARK
+    u'\u2018'   #  0xD4 -> LEFT SINGLE QUOTATION MARK
+    u'\u2019'   #  0xD5 -> RIGHT SINGLE QUOTATION MARK
+    u'\xf7'     #  0xD6 -> DIVISION SIGN
+    u'\u0389'   #  0xD7 -> GREEK CAPITAL LETTER ETA WITH TONOS
+    u'\u038a'   #  0xD8 -> GREEK CAPITAL LETTER IOTA WITH TONOS
+    u'\u038c'   #  0xD9 -> GREEK CAPITAL LETTER OMICRON WITH TONOS
+    u'\u038e'   #  0xDA -> GREEK CAPITAL LETTER UPSILON WITH TONOS
+    u'\u03ad'   #  0xDB -> GREEK SMALL LETTER EPSILON WITH TONOS
+    u'\u03ae'   #  0xDC -> GREEK SMALL LETTER ETA WITH TONOS
+    u'\u03af'   #  0xDD -> GREEK SMALL LETTER IOTA WITH TONOS
+    u'\u03cc'   #  0xDE -> GREEK SMALL LETTER OMICRON WITH TONOS
+    u'\u038f'   #  0xDF -> GREEK CAPITAL LETTER OMEGA WITH TONOS
+    u'\u03cd'   #  0xE0 -> GREEK SMALL LETTER UPSILON WITH TONOS
+    u'\u03b1'   #  0xE1 -> GREEK SMALL LETTER ALPHA
+    u'\u03b2'   #  0xE2 -> GREEK SMALL LETTER BETA
+    u'\u03c8'   #  0xE3 -> GREEK SMALL LETTER PSI
+    u'\u03b4'   #  0xE4 -> GREEK SMALL LETTER DELTA
+    u'\u03b5'   #  0xE5 -> GREEK SMALL LETTER EPSILON
+    u'\u03c6'   #  0xE6 -> GREEK SMALL LETTER PHI
+    u'\u03b3'   #  0xE7 -> GREEK SMALL LETTER GAMMA
+    u'\u03b7'   #  0xE8 -> GREEK SMALL LETTER ETA
+    u'\u03b9'   #  0xE9 -> GREEK SMALL LETTER IOTA
+    u'\u03be'   #  0xEA -> GREEK SMALL LETTER XI
+    u'\u03ba'   #  0xEB -> GREEK SMALL LETTER KAPPA
+    u'\u03bb'   #  0xEC -> GREEK SMALL LETTER LAMDA
+    u'\u03bc'   #  0xED -> GREEK SMALL LETTER MU
+    u'\u03bd'   #  0xEE -> GREEK SMALL LETTER NU
+    u'\u03bf'   #  0xEF -> GREEK SMALL LETTER OMICRON
+    u'\u03c0'   #  0xF0 -> GREEK SMALL LETTER PI
+    u'\u03ce'   #  0xF1 -> GREEK SMALL LETTER OMEGA WITH TONOS
+    u'\u03c1'   #  0xF2 -> GREEK SMALL LETTER RHO
+    u'\u03c3'   #  0xF3 -> GREEK SMALL LETTER SIGMA
+    u'\u03c4'   #  0xF4 -> GREEK SMALL LETTER TAU
+    u'\u03b8'   #  0xF5 -> GREEK SMALL LETTER THETA
+    u'\u03c9'   #  0xF6 -> GREEK SMALL LETTER OMEGA
+    u'\u03c2'   #  0xF7 -> GREEK SMALL LETTER FINAL SIGMA
+    u'\u03c7'   #  0xF8 -> GREEK SMALL LETTER CHI
+    u'\u03c5'   #  0xF9 -> GREEK SMALL LETTER UPSILON
+    u'\u03b6'   #  0xFA -> GREEK SMALL LETTER ZETA
+    u'\u03ca'   #  0xFB -> GREEK SMALL LETTER IOTA WITH DIALYTIKA
+    u'\u03cb'   #  0xFC -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA
+    u'\u0390'   #  0xFD -> GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
+    u'\u03b0'   #  0xFE -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS
+    u'\xad'     #  0xFF -> SOFT HYPHEN # before Mac OS 9.2.2, was undefined
+)
+
+### Encoding table
+encoding_table=codecs.charmap_build(decoding_table)

Added: vendor/Python/current/Lib/encodings/mac_iceland.py
===================================================================
--- vendor/Python/current/Lib/encodings/mac_iceland.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/mac_iceland.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,307 @@
+""" Python Character Mapping Codec mac_iceland generated from 'MAPPINGS/VENDORS/APPLE/ICELAND.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_table)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_table)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='mac-iceland',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x00 -> CONTROL CHARACTER
+    u'\x01'     #  0x01 -> CONTROL CHARACTER
+    u'\x02'     #  0x02 -> CONTROL CHARACTER
+    u'\x03'     #  0x03 -> CONTROL CHARACTER
+    u'\x04'     #  0x04 -> CONTROL CHARACTER
+    u'\x05'     #  0x05 -> CONTROL CHARACTER
+    u'\x06'     #  0x06 -> CONTROL CHARACTER
+    u'\x07'     #  0x07 -> CONTROL CHARACTER
+    u'\x08'     #  0x08 -> CONTROL CHARACTER
+    u'\t'       #  0x09 -> CONTROL CHARACTER
+    u'\n'       #  0x0A -> CONTROL CHARACTER
+    u'\x0b'     #  0x0B -> CONTROL CHARACTER
+    u'\x0c'     #  0x0C -> CONTROL CHARACTER
+    u'\r'       #  0x0D -> CONTROL CHARACTER
+    u'\x0e'     #  0x0E -> CONTROL CHARACTER
+    u'\x0f'     #  0x0F -> CONTROL CHARACTER
+    u'\x10'     #  0x10 -> CONTROL CHARACTER
+    u'\x11'     #  0x11 -> CONTROL CHARACTER
+    u'\x12'     #  0x12 -> CONTROL CHARACTER
+    u'\x13'     #  0x13 -> CONTROL CHARACTER
+    u'\x14'     #  0x14 -> CONTROL CHARACTER
+    u'\x15'     #  0x15 -> CONTROL CHARACTER
+    u'\x16'     #  0x16 -> CONTROL CHARACTER
+    u'\x17'     #  0x17 -> CONTROL CHARACTER
+    u'\x18'     #  0x18 -> CONTROL CHARACTER
+    u'\x19'     #  0x19 -> CONTROL CHARACTER
+    u'\x1a'     #  0x1A -> CONTROL CHARACTER
+    u'\x1b'     #  0x1B -> CONTROL CHARACTER
+    u'\x1c'     #  0x1C -> CONTROL CHARACTER
+    u'\x1d'     #  0x1D -> CONTROL CHARACTER
+    u'\x1e'     #  0x1E -> CONTROL CHARACTER
+    u'\x1f'     #  0x1F -> CONTROL CHARACTER
+    u' '        #  0x20 -> SPACE
+    u'!'        #  0x21 -> EXCLAMATION MARK
+    u'"'        #  0x22 -> QUOTATION MARK
+    u'#'        #  0x23 -> NUMBER SIGN
+    u'$'        #  0x24 -> DOLLAR SIGN
+    u'%'        #  0x25 -> PERCENT SIGN
+    u'&'        #  0x26 -> AMPERSAND
+    u"'"        #  0x27 -> APOSTROPHE
+    u'('        #  0x28 -> LEFT PARENTHESIS
+    u')'        #  0x29 -> RIGHT PARENTHESIS
+    u'*'        #  0x2A -> ASTERISK
+    u'+'        #  0x2B -> PLUS SIGN
+    u','        #  0x2C -> COMMA
+    u'-'        #  0x2D -> HYPHEN-MINUS
+    u'.'        #  0x2E -> FULL STOP
+    u'/'        #  0x2F -> SOLIDUS
+    u'0'        #  0x30 -> DIGIT ZERO
+    u'1'        #  0x31 -> DIGIT ONE
+    u'2'        #  0x32 -> DIGIT TWO
+    u'3'        #  0x33 -> DIGIT THREE
+    u'4'        #  0x34 -> DIGIT FOUR
+    u'5'        #  0x35 -> DIGIT FIVE
+    u'6'        #  0x36 -> DIGIT SIX
+    u'7'        #  0x37 -> DIGIT SEVEN
+    u'8'        #  0x38 -> DIGIT EIGHT
+    u'9'        #  0x39 -> DIGIT NINE
+    u':'        #  0x3A -> COLON
+    u';'        #  0x3B -> SEMICOLON
+    u'<'        #  0x3C -> LESS-THAN SIGN
+    u'='        #  0x3D -> EQUALS SIGN
+    u'>'        #  0x3E -> GREATER-THAN SIGN
+    u'?'        #  0x3F -> QUESTION MARK
+    u'@'        #  0x40 -> COMMERCIAL AT
+    u'A'        #  0x41 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x42 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x43 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x44 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x45 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x46 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x47 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x48 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x49 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x4A -> LATIN CAPITAL LETTER J
+    u'K'        #  0x4B -> LATIN CAPITAL LETTER K
+    u'L'        #  0x4C -> LATIN CAPITAL LETTER L
+    u'M'        #  0x4D -> LATIN CAPITAL LETTER M
+    u'N'        #  0x4E -> LATIN CAPITAL LETTER N
+    u'O'        #  0x4F -> LATIN CAPITAL LETTER O
+    u'P'        #  0x50 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x51 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x52 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x53 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x54 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x55 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x56 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x57 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x58 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x59 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x5A -> LATIN CAPITAL LETTER Z
+    u'['        #  0x5B -> LEFT SQUARE BRACKET
+    u'\\'       #  0x5C -> REVERSE SOLIDUS
+    u']'        #  0x5D -> RIGHT SQUARE BRACKET
+    u'^'        #  0x5E -> CIRCUMFLEX ACCENT
+    u'_'        #  0x5F -> LOW LINE
+    u'`'        #  0x60 -> GRAVE ACCENT
+    u'a'        #  0x61 -> LATIN SMALL LETTER A
+    u'b'        #  0x62 -> LATIN SMALL LETTER B
+    u'c'        #  0x63 -> LATIN SMALL LETTER C
+    u'd'        #  0x64 -> LATIN SMALL LETTER D
+    u'e'        #  0x65 -> LATIN SMALL LETTER E
+    u'f'        #  0x66 -> LATIN SMALL LETTER F
+    u'g'        #  0x67 -> LATIN SMALL LETTER G
+    u'h'        #  0x68 -> LATIN SMALL LETTER H
+    u'i'        #  0x69 -> LATIN SMALL LETTER I
+    u'j'        #  0x6A -> LATIN SMALL LETTER J
+    u'k'        #  0x6B -> LATIN SMALL LETTER K
+    u'l'        #  0x6C -> LATIN SMALL LETTER L
+    u'm'        #  0x6D -> LATIN SMALL LETTER M
+    u'n'        #  0x6E -> LATIN SMALL LETTER N
+    u'o'        #  0x6F -> LATIN SMALL LETTER O
+    u'p'        #  0x70 -> LATIN SMALL LETTER P
+    u'q'        #  0x71 -> LATIN SMALL LETTER Q
+    u'r'        #  0x72 -> LATIN SMALL LETTER R
+    u's'        #  0x73 -> LATIN SMALL LETTER S
+    u't'        #  0x74 -> LATIN SMALL LETTER T
+    u'u'        #  0x75 -> LATIN SMALL LETTER U
+    u'v'        #  0x76 -> LATIN SMALL LETTER V
+    u'w'        #  0x77 -> LATIN SMALL LETTER W
+    u'x'        #  0x78 -> LATIN SMALL LETTER X
+    u'y'        #  0x79 -> LATIN SMALL LETTER Y
+    u'z'        #  0x7A -> LATIN SMALL LETTER Z
+    u'{'        #  0x7B -> LEFT CURLY BRACKET
+    u'|'        #  0x7C -> VERTICAL LINE
+    u'}'        #  0x7D -> RIGHT CURLY BRACKET
+    u'~'        #  0x7E -> TILDE
+    u'\x7f'     #  0x7F -> CONTROL CHARACTER
+    u'\xc4'     #  0x80 -> LATIN CAPITAL LETTER A WITH DIAERESIS
+    u'\xc5'     #  0x81 -> LATIN CAPITAL LETTER A WITH RING ABOVE
+    u'\xc7'     #  0x82 -> LATIN CAPITAL LETTER C WITH CEDILLA
+    u'\xc9'     #  0x83 -> LATIN CAPITAL LETTER E WITH ACUTE
+    u'\xd1'     #  0x84 -> LATIN CAPITAL LETTER N WITH TILDE
+    u'\xd6'     #  0x85 -> LATIN CAPITAL LETTER O WITH DIAERESIS
+    u'\xdc'     #  0x86 -> LATIN CAPITAL LETTER U WITH DIAERESIS
+    u'\xe1'     #  0x87 -> LATIN SMALL LETTER A WITH ACUTE
+    u'\xe0'     #  0x88 -> LATIN SMALL LETTER A WITH GRAVE
+    u'\xe2'     #  0x89 -> LATIN SMALL LETTER A WITH CIRCUMFLEX
+    u'\xe4'     #  0x8A -> LATIN SMALL LETTER A WITH DIAERESIS
+    u'\xe3'     #  0x8B -> LATIN SMALL LETTER A WITH TILDE
+    u'\xe5'     #  0x8C -> LATIN SMALL LETTER A WITH RING ABOVE
+    u'\xe7'     #  0x8D -> LATIN SMALL LETTER C WITH CEDILLA
+    u'\xe9'     #  0x8E -> LATIN SMALL LETTER E WITH ACUTE
+    u'\xe8'     #  0x8F -> LATIN SMALL LETTER E WITH GRAVE
+    u'\xea'     #  0x90 -> LATIN SMALL LETTER E WITH CIRCUMFLEX
+    u'\xeb'     #  0x91 -> LATIN SMALL LETTER E WITH DIAERESIS
+    u'\xed'     #  0x92 -> LATIN SMALL LETTER I WITH ACUTE
+    u'\xec'     #  0x93 -> LATIN SMALL LETTER I WITH GRAVE
+    u'\xee'     #  0x94 -> LATIN SMALL LETTER I WITH CIRCUMFLEX
+    u'\xef'     #  0x95 -> LATIN SMALL LETTER I WITH DIAERESIS
+    u'\xf1'     #  0x96 -> LATIN SMALL LETTER N WITH TILDE
+    u'\xf3'     #  0x97 -> LATIN SMALL LETTER O WITH ACUTE
+    u'\xf2'     #  0x98 -> LATIN SMALL LETTER O WITH GRAVE
+    u'\xf4'     #  0x99 -> LATIN SMALL LETTER O WITH CIRCUMFLEX
+    u'\xf6'     #  0x9A -> LATIN SMALL LETTER O WITH DIAERESIS
+    u'\xf5'     #  0x9B -> LATIN SMALL LETTER O WITH TILDE
+    u'\xfa'     #  0x9C -> LATIN SMALL LETTER U WITH ACUTE
+    u'\xf9'     #  0x9D -> LATIN SMALL LETTER U WITH GRAVE
+    u'\xfb'     #  0x9E -> LATIN SMALL LETTER U WITH CIRCUMFLEX
+    u'\xfc'     #  0x9F -> LATIN SMALL LETTER U WITH DIAERESIS
+    u'\xdd'     #  0xA0 -> LATIN CAPITAL LETTER Y WITH ACUTE
+    u'\xb0'     #  0xA1 -> DEGREE SIGN
+    u'\xa2'     #  0xA2 -> CENT SIGN
+    u'\xa3'     #  0xA3 -> POUND SIGN
+    u'\xa7'     #  0xA4 -> SECTION SIGN
+    u'\u2022'   #  0xA5 -> BULLET
+    u'\xb6'     #  0xA6 -> PILCROW SIGN
+    u'\xdf'     #  0xA7 -> LATIN SMALL LETTER SHARP S
+    u'\xae'     #  0xA8 -> REGISTERED SIGN
+    u'\xa9'     #  0xA9 -> COPYRIGHT SIGN
+    u'\u2122'   #  0xAA -> TRADE MARK SIGN
+    u'\xb4'     #  0xAB -> ACUTE ACCENT
+    u'\xa8'     #  0xAC -> DIAERESIS
+    u'\u2260'   #  0xAD -> NOT EQUAL TO
+    u'\xc6'     #  0xAE -> LATIN CAPITAL LETTER AE
+    u'\xd8'     #  0xAF -> LATIN CAPITAL LETTER O WITH STROKE
+    u'\u221e'   #  0xB0 -> INFINITY
+    u'\xb1'     #  0xB1 -> PLUS-MINUS SIGN
+    u'\u2264'   #  0xB2 -> LESS-THAN OR EQUAL TO
+    u'\u2265'   #  0xB3 -> GREATER-THAN OR EQUAL TO
+    u'\xa5'     #  0xB4 -> YEN SIGN
+    u'\xb5'     #  0xB5 -> MICRO SIGN
+    u'\u2202'   #  0xB6 -> PARTIAL DIFFERENTIAL
+    u'\u2211'   #  0xB7 -> N-ARY SUMMATION
+    u'\u220f'   #  0xB8 -> N-ARY PRODUCT
+    u'\u03c0'   #  0xB9 -> GREEK SMALL LETTER PI
+    u'\u222b'   #  0xBA -> INTEGRAL
+    u'\xaa'     #  0xBB -> FEMININE ORDINAL INDICATOR
+    u'\xba'     #  0xBC -> MASCULINE ORDINAL INDICATOR
+    u'\u03a9'   #  0xBD -> GREEK CAPITAL LETTER OMEGA
+    u'\xe6'     #  0xBE -> LATIN SMALL LETTER AE
+    u'\xf8'     #  0xBF -> LATIN SMALL LETTER O WITH STROKE
+    u'\xbf'     #  0xC0 -> INVERTED QUESTION MARK
+    u'\xa1'     #  0xC1 -> INVERTED EXCLAMATION MARK
+    u'\xac'     #  0xC2 -> NOT SIGN
+    u'\u221a'   #  0xC3 -> SQUARE ROOT
+    u'\u0192'   #  0xC4 -> LATIN SMALL LETTER F WITH HOOK
+    u'\u2248'   #  0xC5 -> ALMOST EQUAL TO
+    u'\u2206'   #  0xC6 -> INCREMENT
+    u'\xab'     #  0xC7 -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xbb'     #  0xC8 -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\u2026'   #  0xC9 -> HORIZONTAL ELLIPSIS
+    u'\xa0'     #  0xCA -> NO-BREAK SPACE
+    u'\xc0'     #  0xCB -> LATIN CAPITAL LETTER A WITH GRAVE
+    u'\xc3'     #  0xCC -> LATIN CAPITAL LETTER A WITH TILDE
+    u'\xd5'     #  0xCD -> LATIN CAPITAL LETTER O WITH TILDE
+    u'\u0152'   #  0xCE -> LATIN CAPITAL LIGATURE OE
+    u'\u0153'   #  0xCF -> LATIN SMALL LIGATURE OE
+    u'\u2013'   #  0xD0 -> EN DASH
+    u'\u2014'   #  0xD1 -> EM DASH
+    u'\u201c'   #  0xD2 -> LEFT DOUBLE QUOTATION MARK
+    u'\u201d'   #  0xD3 -> RIGHT DOUBLE QUOTATION MARK
+    u'\u2018'   #  0xD4 -> LEFT SINGLE QUOTATION MARK
+    u'\u2019'   #  0xD5 -> RIGHT SINGLE QUOTATION MARK
+    u'\xf7'     #  0xD6 -> DIVISION SIGN
+    u'\u25ca'   #  0xD7 -> LOZENGE
+    u'\xff'     #  0xD8 -> LATIN SMALL LETTER Y WITH DIAERESIS
+    u'\u0178'   #  0xD9 -> LATIN CAPITAL LETTER Y WITH DIAERESIS
+    u'\u2044'   #  0xDA -> FRACTION SLASH
+    u'\u20ac'   #  0xDB -> EURO SIGN
+    u'\xd0'     #  0xDC -> LATIN CAPITAL LETTER ETH
+    u'\xf0'     #  0xDD -> LATIN SMALL LETTER ETH
+    u'\xde'     #  0xDE -> LATIN CAPITAL LETTER THORN
+    u'\xfe'     #  0xDF -> LATIN SMALL LETTER THORN
+    u'\xfd'     #  0xE0 -> LATIN SMALL LETTER Y WITH ACUTE
+    u'\xb7'     #  0xE1 -> MIDDLE DOT
+    u'\u201a'   #  0xE2 -> SINGLE LOW-9 QUOTATION MARK
+    u'\u201e'   #  0xE3 -> DOUBLE LOW-9 QUOTATION MARK
+    u'\u2030'   #  0xE4 -> PER MILLE SIGN
+    u'\xc2'     #  0xE5 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+    u'\xca'     #  0xE6 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+    u'\xc1'     #  0xE7 -> LATIN CAPITAL LETTER A WITH ACUTE
+    u'\xcb'     #  0xE8 -> LATIN CAPITAL LETTER E WITH DIAERESIS
+    u'\xc8'     #  0xE9 -> LATIN CAPITAL LETTER E WITH GRAVE
+    u'\xcd'     #  0xEA -> LATIN CAPITAL LETTER I WITH ACUTE
+    u'\xce'     #  0xEB -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+    u'\xcf'     #  0xEC -> LATIN CAPITAL LETTER I WITH DIAERESIS
+    u'\xcc'     #  0xED -> LATIN CAPITAL LETTER I WITH GRAVE
+    u'\xd3'     #  0xEE -> LATIN CAPITAL LETTER O WITH ACUTE
+    u'\xd4'     #  0xEF -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+    u'\uf8ff'   #  0xF0 -> Apple logo
+    u'\xd2'     #  0xF1 -> LATIN CAPITAL LETTER O WITH GRAVE
+    u'\xda'     #  0xF2 -> LATIN CAPITAL LETTER U WITH ACUTE
+    u'\xdb'     #  0xF3 -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+    u'\xd9'     #  0xF4 -> LATIN CAPITAL LETTER U WITH GRAVE
+    u'\u0131'   #  0xF5 -> LATIN SMALL LETTER DOTLESS I
+    u'\u02c6'   #  0xF6 -> MODIFIER LETTER CIRCUMFLEX ACCENT
+    u'\u02dc'   #  0xF7 -> SMALL TILDE
+    u'\xaf'     #  0xF8 -> MACRON
+    u'\u02d8'   #  0xF9 -> BREVE
+    u'\u02d9'   #  0xFA -> DOT ABOVE
+    u'\u02da'   #  0xFB -> RING ABOVE
+    u'\xb8'     #  0xFC -> CEDILLA
+    u'\u02dd'   #  0xFD -> DOUBLE ACUTE ACCENT
+    u'\u02db'   #  0xFE -> OGONEK
+    u'\u02c7'   #  0xFF -> CARON
+)
+
+### Encoding table
+encoding_table=codecs.charmap_build(decoding_table)

Added: vendor/Python/current/Lib/encodings/mac_latin2.py
===================================================================
--- vendor/Python/current/Lib/encodings/mac_latin2.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/mac_latin2.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,183 @@
+""" Python Character Mapping Codec generated from 'LATIN2.TXT' with gencodec.py.
+
+Written by Marc-Andre Lemburg (mal at lemburg.com).
+
+(c) Copyright CNRI, All Rights Reserved. NO WARRANTY.
+(c) Copyright 2000 Guido van Rossum.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_map)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_map)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_map)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='mac-latin2',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+### Decoding Map
+
+decoding_map = codecs.make_identity_dict(range(256))
+decoding_map.update({
+        0x0080: 0x00c4, # LATIN CAPITAL LETTER A WITH DIAERESIS
+        0x0081: 0x0100, # LATIN CAPITAL LETTER A WITH MACRON
+        0x0082: 0x0101, # LATIN SMALL LETTER A WITH MACRON
+        0x0083: 0x00c9, # LATIN CAPITAL LETTER E WITH ACUTE
+        0x0084: 0x0104, # LATIN CAPITAL LETTER A WITH OGONEK
+        0x0085: 0x00d6, # LATIN CAPITAL LETTER O WITH DIAERESIS
+        0x0086: 0x00dc, # LATIN CAPITAL LETTER U WITH DIAERESIS
+        0x0087: 0x00e1, # LATIN SMALL LETTER A WITH ACUTE
+        0x0088: 0x0105, # LATIN SMALL LETTER A WITH OGONEK
+        0x0089: 0x010c, # LATIN CAPITAL LETTER C WITH CARON
+        0x008a: 0x00e4, # LATIN SMALL LETTER A WITH DIAERESIS
+        0x008b: 0x010d, # LATIN SMALL LETTER C WITH CARON
+        0x008c: 0x0106, # LATIN CAPITAL LETTER C WITH ACUTE
+        0x008d: 0x0107, # LATIN SMALL LETTER C WITH ACUTE
+        0x008e: 0x00e9, # LATIN SMALL LETTER E WITH ACUTE
+        0x008f: 0x0179, # LATIN CAPITAL LETTER Z WITH ACUTE
+        0x0090: 0x017a, # LATIN SMALL LETTER Z WITH ACUTE
+        0x0091: 0x010e, # LATIN CAPITAL LETTER D WITH CARON
+        0x0092: 0x00ed, # LATIN SMALL LETTER I WITH ACUTE
+        0x0093: 0x010f, # LATIN SMALL LETTER D WITH CARON
+        0x0094: 0x0112, # LATIN CAPITAL LETTER E WITH MACRON
+        0x0095: 0x0113, # LATIN SMALL LETTER E WITH MACRON
+        0x0096: 0x0116, # LATIN CAPITAL LETTER E WITH DOT ABOVE
+        0x0097: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE
+        0x0098: 0x0117, # LATIN SMALL LETTER E WITH DOT ABOVE
+        0x0099: 0x00f4, # LATIN SMALL LETTER O WITH CIRCUMFLEX
+        0x009a: 0x00f6, # LATIN SMALL LETTER O WITH DIAERESIS
+        0x009b: 0x00f5, # LATIN SMALL LETTER O WITH TILDE
+        0x009c: 0x00fa, # LATIN SMALL LETTER U WITH ACUTE
+        0x009d: 0x011a, # LATIN CAPITAL LETTER E WITH CARON
+        0x009e: 0x011b, # LATIN SMALL LETTER E WITH CARON
+        0x009f: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS
+        0x00a0: 0x2020, # DAGGER
+        0x00a1: 0x00b0, # DEGREE SIGN
+        0x00a2: 0x0118, # LATIN CAPITAL LETTER E WITH OGONEK
+        0x00a4: 0x00a7, # SECTION SIGN
+        0x00a5: 0x2022, # BULLET
+        0x00a6: 0x00b6, # PILCROW SIGN
+        0x00a7: 0x00df, # LATIN SMALL LETTER SHARP S
+        0x00a8: 0x00ae, # REGISTERED SIGN
+        0x00aa: 0x2122, # TRADE MARK SIGN
+        0x00ab: 0x0119, # LATIN SMALL LETTER E WITH OGONEK
+        0x00ac: 0x00a8, # DIAERESIS
+        0x00ad: 0x2260, # NOT EQUAL TO
+        0x00ae: 0x0123, # LATIN SMALL LETTER G WITH CEDILLA
+        0x00af: 0x012e, # LATIN CAPITAL LETTER I WITH OGONEK
+        0x00b0: 0x012f, # LATIN SMALL LETTER I WITH OGONEK
+        0x00b1: 0x012a, # LATIN CAPITAL LETTER I WITH MACRON
+        0x00b2: 0x2264, # LESS-THAN OR EQUAL TO
+        0x00b3: 0x2265, # GREATER-THAN OR EQUAL TO
+        0x00b4: 0x012b, # LATIN SMALL LETTER I WITH MACRON
+        0x00b5: 0x0136, # LATIN CAPITAL LETTER K WITH CEDILLA
+        0x00b6: 0x2202, # PARTIAL DIFFERENTIAL
+        0x00b7: 0x2211, # N-ARY SUMMATION
+        0x00b8: 0x0142, # LATIN SMALL LETTER L WITH STROKE
+        0x00b9: 0x013b, # LATIN CAPITAL LETTER L WITH CEDILLA
+        0x00ba: 0x013c, # LATIN SMALL LETTER L WITH CEDILLA
+        0x00bb: 0x013d, # LATIN CAPITAL LETTER L WITH CARON
+        0x00bc: 0x013e, # LATIN SMALL LETTER L WITH CARON
+        0x00bd: 0x0139, # LATIN CAPITAL LETTER L WITH ACUTE
+        0x00be: 0x013a, # LATIN SMALL LETTER L WITH ACUTE
+        0x00bf: 0x0145, # LATIN CAPITAL LETTER N WITH CEDILLA
+        0x00c0: 0x0146, # LATIN SMALL LETTER N WITH CEDILLA
+        0x00c1: 0x0143, # LATIN CAPITAL LETTER N WITH ACUTE
+        0x00c2: 0x00ac, # NOT SIGN
+        0x00c3: 0x221a, # SQUARE ROOT
+        0x00c4: 0x0144, # LATIN SMALL LETTER N WITH ACUTE
+        0x00c5: 0x0147, # LATIN CAPITAL LETTER N WITH CARON
+        0x00c6: 0x2206, # INCREMENT
+        0x00c7: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+        0x00c8: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+        0x00c9: 0x2026, # HORIZONTAL ELLIPSIS
+        0x00ca: 0x00a0, # NO-BREAK SPACE
+        0x00cb: 0x0148, # LATIN SMALL LETTER N WITH CARON
+        0x00cc: 0x0150, # LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
+        0x00cd: 0x00d5, # LATIN CAPITAL LETTER O WITH TILDE
+        0x00ce: 0x0151, # LATIN SMALL LETTER O WITH DOUBLE ACUTE
+        0x00cf: 0x014c, # LATIN CAPITAL LETTER O WITH MACRON
+        0x00d0: 0x2013, # EN DASH
+        0x00d1: 0x2014, # EM DASH
+        0x00d2: 0x201c, # LEFT DOUBLE QUOTATION MARK
+        0x00d3: 0x201d, # RIGHT DOUBLE QUOTATION MARK
+        0x00d4: 0x2018, # LEFT SINGLE QUOTATION MARK
+        0x00d5: 0x2019, # RIGHT SINGLE QUOTATION MARK
+        0x00d6: 0x00f7, # DIVISION SIGN
+        0x00d7: 0x25ca, # LOZENGE
+        0x00d8: 0x014d, # LATIN SMALL LETTER O WITH MACRON
+        0x00d9: 0x0154, # LATIN CAPITAL LETTER R WITH ACUTE
+        0x00da: 0x0155, # LATIN SMALL LETTER R WITH ACUTE
+        0x00db: 0x0158, # LATIN CAPITAL LETTER R WITH CARON
+        0x00dc: 0x2039, # SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+        0x00dd: 0x203a, # SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+        0x00de: 0x0159, # LATIN SMALL LETTER R WITH CARON
+        0x00df: 0x0156, # LATIN CAPITAL LETTER R WITH CEDILLA
+        0x00e0: 0x0157, # LATIN SMALL LETTER R WITH CEDILLA
+        0x00e1: 0x0160, # LATIN CAPITAL LETTER S WITH CARON
+        0x00e2: 0x201a, # SINGLE LOW-9 QUOTATION MARK
+        0x00e3: 0x201e, # DOUBLE LOW-9 QUOTATION MARK
+        0x00e4: 0x0161, # LATIN SMALL LETTER S WITH CARON
+        0x00e5: 0x015a, # LATIN CAPITAL LETTER S WITH ACUTE
+        0x00e6: 0x015b, # LATIN SMALL LETTER S WITH ACUTE
+        0x00e7: 0x00c1, # LATIN CAPITAL LETTER A WITH ACUTE
+        0x00e8: 0x0164, # LATIN CAPITAL LETTER T WITH CARON
+        0x00e9: 0x0165, # LATIN SMALL LETTER T WITH CARON
+        0x00ea: 0x00cd, # LATIN CAPITAL LETTER I WITH ACUTE
+        0x00eb: 0x017d, # LATIN CAPITAL LETTER Z WITH CARON
+        0x00ec: 0x017e, # LATIN SMALL LETTER Z WITH CARON
+        0x00ed: 0x016a, # LATIN CAPITAL LETTER U WITH MACRON
+        0x00ee: 0x00d3, # LATIN CAPITAL LETTER O WITH ACUTE
+        0x00ef: 0x00d4, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+        0x00f0: 0x016b, # LATIN SMALL LETTER U WITH MACRON
+        0x00f1: 0x016e, # LATIN CAPITAL LETTER U WITH RING ABOVE
+        0x00f2: 0x00da, # LATIN CAPITAL LETTER U WITH ACUTE
+        0x00f3: 0x016f, # LATIN SMALL LETTER U WITH RING ABOVE
+        0x00f4: 0x0170, # LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
+        0x00f5: 0x0171, # LATIN SMALL LETTER U WITH DOUBLE ACUTE
+        0x00f6: 0x0172, # LATIN CAPITAL LETTER U WITH OGONEK
+        0x00f7: 0x0173, # LATIN SMALL LETTER U WITH OGONEK
+        0x00f8: 0x00dd, # LATIN CAPITAL LETTER Y WITH ACUTE
+        0x00f9: 0x00fd, # LATIN SMALL LETTER Y WITH ACUTE
+        0x00fa: 0x0137, # LATIN SMALL LETTER K WITH CEDILLA
+        0x00fb: 0x017b, # LATIN CAPITAL LETTER Z WITH DOT ABOVE
+        0x00fc: 0x0141, # LATIN CAPITAL LETTER L WITH STROKE
+        0x00fd: 0x017c, # LATIN SMALL LETTER Z WITH DOT ABOVE
+        0x00fe: 0x0122, # LATIN CAPITAL LETTER G WITH CEDILLA
+        0x00ff: 0x02c7, # CARON
+})
+
+### Encoding Map
+
+encoding_map = codecs.make_encoding_map(decoding_map)

Added: vendor/Python/current/Lib/encodings/mac_roman.py
===================================================================
--- vendor/Python/current/Lib/encodings/mac_roman.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/mac_roman.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,307 @@
+""" Python Character Mapping Codec mac_roman generated from 'MAPPINGS/VENDORS/APPLE/ROMAN.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_table)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_table)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='mac-roman',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x00 -> CONTROL CHARACTER
+    u'\x01'     #  0x01 -> CONTROL CHARACTER
+    u'\x02'     #  0x02 -> CONTROL CHARACTER
+    u'\x03'     #  0x03 -> CONTROL CHARACTER
+    u'\x04'     #  0x04 -> CONTROL CHARACTER
+    u'\x05'     #  0x05 -> CONTROL CHARACTER
+    u'\x06'     #  0x06 -> CONTROL CHARACTER
+    u'\x07'     #  0x07 -> CONTROL CHARACTER
+    u'\x08'     #  0x08 -> CONTROL CHARACTER
+    u'\t'       #  0x09 -> CONTROL CHARACTER
+    u'\n'       #  0x0A -> CONTROL CHARACTER
+    u'\x0b'     #  0x0B -> CONTROL CHARACTER
+    u'\x0c'     #  0x0C -> CONTROL CHARACTER
+    u'\r'       #  0x0D -> CONTROL CHARACTER
+    u'\x0e'     #  0x0E -> CONTROL CHARACTER
+    u'\x0f'     #  0x0F -> CONTROL CHARACTER
+    u'\x10'     #  0x10 -> CONTROL CHARACTER
+    u'\x11'     #  0x11 -> CONTROL CHARACTER
+    u'\x12'     #  0x12 -> CONTROL CHARACTER
+    u'\x13'     #  0x13 -> CONTROL CHARACTER
+    u'\x14'     #  0x14 -> CONTROL CHARACTER
+    u'\x15'     #  0x15 -> CONTROL CHARACTER
+    u'\x16'     #  0x16 -> CONTROL CHARACTER
+    u'\x17'     #  0x17 -> CONTROL CHARACTER
+    u'\x18'     #  0x18 -> CONTROL CHARACTER
+    u'\x19'     #  0x19 -> CONTROL CHARACTER
+    u'\x1a'     #  0x1A -> CONTROL CHARACTER
+    u'\x1b'     #  0x1B -> CONTROL CHARACTER
+    u'\x1c'     #  0x1C -> CONTROL CHARACTER
+    u'\x1d'     #  0x1D -> CONTROL CHARACTER
+    u'\x1e'     #  0x1E -> CONTROL CHARACTER
+    u'\x1f'     #  0x1F -> CONTROL CHARACTER
+    u' '        #  0x20 -> SPACE
+    u'!'        #  0x21 -> EXCLAMATION MARK
+    u'"'        #  0x22 -> QUOTATION MARK
+    u'#'        #  0x23 -> NUMBER SIGN
+    u'$'        #  0x24 -> DOLLAR SIGN
+    u'%'        #  0x25 -> PERCENT SIGN
+    u'&'        #  0x26 -> AMPERSAND
+    u"'"        #  0x27 -> APOSTROPHE
+    u'('        #  0x28 -> LEFT PARENTHESIS
+    u')'        #  0x29 -> RIGHT PARENTHESIS
+    u'*'        #  0x2A -> ASTERISK
+    u'+'        #  0x2B -> PLUS SIGN
+    u','        #  0x2C -> COMMA
+    u'-'        #  0x2D -> HYPHEN-MINUS
+    u'.'        #  0x2E -> FULL STOP
+    u'/'        #  0x2F -> SOLIDUS
+    u'0'        #  0x30 -> DIGIT ZERO
+    u'1'        #  0x31 -> DIGIT ONE
+    u'2'        #  0x32 -> DIGIT TWO
+    u'3'        #  0x33 -> DIGIT THREE
+    u'4'        #  0x34 -> DIGIT FOUR
+    u'5'        #  0x35 -> DIGIT FIVE
+    u'6'        #  0x36 -> DIGIT SIX
+    u'7'        #  0x37 -> DIGIT SEVEN
+    u'8'        #  0x38 -> DIGIT EIGHT
+    u'9'        #  0x39 -> DIGIT NINE
+    u':'        #  0x3A -> COLON
+    u';'        #  0x3B -> SEMICOLON
+    u'<'        #  0x3C -> LESS-THAN SIGN
+    u'='        #  0x3D -> EQUALS SIGN
+    u'>'        #  0x3E -> GREATER-THAN SIGN
+    u'?'        #  0x3F -> QUESTION MARK
+    u'@'        #  0x40 -> COMMERCIAL AT
+    u'A'        #  0x41 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x42 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x43 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x44 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x45 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x46 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x47 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x48 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x49 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x4A -> LATIN CAPITAL LETTER J
+    u'K'        #  0x4B -> LATIN CAPITAL LETTER K
+    u'L'        #  0x4C -> LATIN CAPITAL LETTER L
+    u'M'        #  0x4D -> LATIN CAPITAL LETTER M
+    u'N'        #  0x4E -> LATIN CAPITAL LETTER N
+    u'O'        #  0x4F -> LATIN CAPITAL LETTER O
+    u'P'        #  0x50 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x51 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x52 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x53 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x54 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x55 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x56 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x57 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x58 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x59 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x5A -> LATIN CAPITAL LETTER Z
+    u'['        #  0x5B -> LEFT SQUARE BRACKET
+    u'\\'       #  0x5C -> REVERSE SOLIDUS
+    u']'        #  0x5D -> RIGHT SQUARE BRACKET
+    u'^'        #  0x5E -> CIRCUMFLEX ACCENT
+    u'_'        #  0x5F -> LOW LINE
+    u'`'        #  0x60 -> GRAVE ACCENT
+    u'a'        #  0x61 -> LATIN SMALL LETTER A
+    u'b'        #  0x62 -> LATIN SMALL LETTER B
+    u'c'        #  0x63 -> LATIN SMALL LETTER C
+    u'd'        #  0x64 -> LATIN SMALL LETTER D
+    u'e'        #  0x65 -> LATIN SMALL LETTER E
+    u'f'        #  0x66 -> LATIN SMALL LETTER F
+    u'g'        #  0x67 -> LATIN SMALL LETTER G
+    u'h'        #  0x68 -> LATIN SMALL LETTER H
+    u'i'        #  0x69 -> LATIN SMALL LETTER I
+    u'j'        #  0x6A -> LATIN SMALL LETTER J
+    u'k'        #  0x6B -> LATIN SMALL LETTER K
+    u'l'        #  0x6C -> LATIN SMALL LETTER L
+    u'm'        #  0x6D -> LATIN SMALL LETTER M
+    u'n'        #  0x6E -> LATIN SMALL LETTER N
+    u'o'        #  0x6F -> LATIN SMALL LETTER O
+    u'p'        #  0x70 -> LATIN SMALL LETTER P
+    u'q'        #  0x71 -> LATIN SMALL LETTER Q
+    u'r'        #  0x72 -> LATIN SMALL LETTER R
+    u's'        #  0x73 -> LATIN SMALL LETTER S
+    u't'        #  0x74 -> LATIN SMALL LETTER T
+    u'u'        #  0x75 -> LATIN SMALL LETTER U
+    u'v'        #  0x76 -> LATIN SMALL LETTER V
+    u'w'        #  0x77 -> LATIN SMALL LETTER W
+    u'x'        #  0x78 -> LATIN SMALL LETTER X
+    u'y'        #  0x79 -> LATIN SMALL LETTER Y
+    u'z'        #  0x7A -> LATIN SMALL LETTER Z
+    u'{'        #  0x7B -> LEFT CURLY BRACKET
+    u'|'        #  0x7C -> VERTICAL LINE
+    u'}'        #  0x7D -> RIGHT CURLY BRACKET
+    u'~'        #  0x7E -> TILDE
+    u'\x7f'     #  0x7F -> CONTROL CHARACTER
+    u'\xc4'     #  0x80 -> LATIN CAPITAL LETTER A WITH DIAERESIS
+    u'\xc5'     #  0x81 -> LATIN CAPITAL LETTER A WITH RING ABOVE
+    u'\xc7'     #  0x82 -> LATIN CAPITAL LETTER C WITH CEDILLA
+    u'\xc9'     #  0x83 -> LATIN CAPITAL LETTER E WITH ACUTE
+    u'\xd1'     #  0x84 -> LATIN CAPITAL LETTER N WITH TILDE
+    u'\xd6'     #  0x85 -> LATIN CAPITAL LETTER O WITH DIAERESIS
+    u'\xdc'     #  0x86 -> LATIN CAPITAL LETTER U WITH DIAERESIS
+    u'\xe1'     #  0x87 -> LATIN SMALL LETTER A WITH ACUTE
+    u'\xe0'     #  0x88 -> LATIN SMALL LETTER A WITH GRAVE
+    u'\xe2'     #  0x89 -> LATIN SMALL LETTER A WITH CIRCUMFLEX
+    u'\xe4'     #  0x8A -> LATIN SMALL LETTER A WITH DIAERESIS
+    u'\xe3'     #  0x8B -> LATIN SMALL LETTER A WITH TILDE
+    u'\xe5'     #  0x8C -> LATIN SMALL LETTER A WITH RING ABOVE
+    u'\xe7'     #  0x8D -> LATIN SMALL LETTER C WITH CEDILLA
+    u'\xe9'     #  0x8E -> LATIN SMALL LETTER E WITH ACUTE
+    u'\xe8'     #  0x8F -> LATIN SMALL LETTER E WITH GRAVE
+    u'\xea'     #  0x90 -> LATIN SMALL LETTER E WITH CIRCUMFLEX
+    u'\xeb'     #  0x91 -> LATIN SMALL LETTER E WITH DIAERESIS
+    u'\xed'     #  0x92 -> LATIN SMALL LETTER I WITH ACUTE
+    u'\xec'     #  0x93 -> LATIN SMALL LETTER I WITH GRAVE
+    u'\xee'     #  0x94 -> LATIN SMALL LETTER I WITH CIRCUMFLEX
+    u'\xef'     #  0x95 -> LATIN SMALL LETTER I WITH DIAERESIS
+    u'\xf1'     #  0x96 -> LATIN SMALL LETTER N WITH TILDE
+    u'\xf3'     #  0x97 -> LATIN SMALL LETTER O WITH ACUTE
+    u'\xf2'     #  0x98 -> LATIN SMALL LETTER O WITH GRAVE
+    u'\xf4'     #  0x99 -> LATIN SMALL LETTER O WITH CIRCUMFLEX
+    u'\xf6'     #  0x9A -> LATIN SMALL LETTER O WITH DIAERESIS
+    u'\xf5'     #  0x9B -> LATIN SMALL LETTER O WITH TILDE
+    u'\xfa'     #  0x9C -> LATIN SMALL LETTER U WITH ACUTE
+    u'\xf9'     #  0x9D -> LATIN SMALL LETTER U WITH GRAVE
+    u'\xfb'     #  0x9E -> LATIN SMALL LETTER U WITH CIRCUMFLEX
+    u'\xfc'     #  0x9F -> LATIN SMALL LETTER U WITH DIAERESIS
+    u'\u2020'   #  0xA0 -> DAGGER
+    u'\xb0'     #  0xA1 -> DEGREE SIGN
+    u'\xa2'     #  0xA2 -> CENT SIGN
+    u'\xa3'     #  0xA3 -> POUND SIGN
+    u'\xa7'     #  0xA4 -> SECTION SIGN
+    u'\u2022'   #  0xA5 -> BULLET
+    u'\xb6'     #  0xA6 -> PILCROW SIGN
+    u'\xdf'     #  0xA7 -> LATIN SMALL LETTER SHARP S
+    u'\xae'     #  0xA8 -> REGISTERED SIGN
+    u'\xa9'     #  0xA9 -> COPYRIGHT SIGN
+    u'\u2122'   #  0xAA -> TRADE MARK SIGN
+    u'\xb4'     #  0xAB -> ACUTE ACCENT
+    u'\xa8'     #  0xAC -> DIAERESIS
+    u'\u2260'   #  0xAD -> NOT EQUAL TO
+    u'\xc6'     #  0xAE -> LATIN CAPITAL LETTER AE
+    u'\xd8'     #  0xAF -> LATIN CAPITAL LETTER O WITH STROKE
+    u'\u221e'   #  0xB0 -> INFINITY
+    u'\xb1'     #  0xB1 -> PLUS-MINUS SIGN
+    u'\u2264'   #  0xB2 -> LESS-THAN OR EQUAL TO
+    u'\u2265'   #  0xB3 -> GREATER-THAN OR EQUAL TO
+    u'\xa5'     #  0xB4 -> YEN SIGN
+    u'\xb5'     #  0xB5 -> MICRO SIGN
+    u'\u2202'   #  0xB6 -> PARTIAL DIFFERENTIAL
+    u'\u2211'   #  0xB7 -> N-ARY SUMMATION
+    u'\u220f'   #  0xB8 -> N-ARY PRODUCT
+    u'\u03c0'   #  0xB9 -> GREEK SMALL LETTER PI
+    u'\u222b'   #  0xBA -> INTEGRAL
+    u'\xaa'     #  0xBB -> FEMININE ORDINAL INDICATOR
+    u'\xba'     #  0xBC -> MASCULINE ORDINAL INDICATOR
+    u'\u03a9'   #  0xBD -> GREEK CAPITAL LETTER OMEGA
+    u'\xe6'     #  0xBE -> LATIN SMALL LETTER AE
+    u'\xf8'     #  0xBF -> LATIN SMALL LETTER O WITH STROKE
+    u'\xbf'     #  0xC0 -> INVERTED QUESTION MARK
+    u'\xa1'     #  0xC1 -> INVERTED EXCLAMATION MARK
+    u'\xac'     #  0xC2 -> NOT SIGN
+    u'\u221a'   #  0xC3 -> SQUARE ROOT
+    u'\u0192'   #  0xC4 -> LATIN SMALL LETTER F WITH HOOK
+    u'\u2248'   #  0xC5 -> ALMOST EQUAL TO
+    u'\u2206'   #  0xC6 -> INCREMENT
+    u'\xab'     #  0xC7 -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xbb'     #  0xC8 -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\u2026'   #  0xC9 -> HORIZONTAL ELLIPSIS
+    u'\xa0'     #  0xCA -> NO-BREAK SPACE
+    u'\xc0'     #  0xCB -> LATIN CAPITAL LETTER A WITH GRAVE
+    u'\xc3'     #  0xCC -> LATIN CAPITAL LETTER A WITH TILDE
+    u'\xd5'     #  0xCD -> LATIN CAPITAL LETTER O WITH TILDE
+    u'\u0152'   #  0xCE -> LATIN CAPITAL LIGATURE OE
+    u'\u0153'   #  0xCF -> LATIN SMALL LIGATURE OE
+    u'\u2013'   #  0xD0 -> EN DASH
+    u'\u2014'   #  0xD1 -> EM DASH
+    u'\u201c'   #  0xD2 -> LEFT DOUBLE QUOTATION MARK
+    u'\u201d'   #  0xD3 -> RIGHT DOUBLE QUOTATION MARK
+    u'\u2018'   #  0xD4 -> LEFT SINGLE QUOTATION MARK
+    u'\u2019'   #  0xD5 -> RIGHT SINGLE QUOTATION MARK
+    u'\xf7'     #  0xD6 -> DIVISION SIGN
+    u'\u25ca'   #  0xD7 -> LOZENGE
+    u'\xff'     #  0xD8 -> LATIN SMALL LETTER Y WITH DIAERESIS
+    u'\u0178'   #  0xD9 -> LATIN CAPITAL LETTER Y WITH DIAERESIS
+    u'\u2044'   #  0xDA -> FRACTION SLASH
+    u'\u20ac'   #  0xDB -> EURO SIGN
+    u'\u2039'   #  0xDC -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+    u'\u203a'   #  0xDD -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+    u'\ufb01'   #  0xDE -> LATIN SMALL LIGATURE FI
+    u'\ufb02'   #  0xDF -> LATIN SMALL LIGATURE FL
+    u'\u2021'   #  0xE0 -> DOUBLE DAGGER
+    u'\xb7'     #  0xE1 -> MIDDLE DOT
+    u'\u201a'   #  0xE2 -> SINGLE LOW-9 QUOTATION MARK
+    u'\u201e'   #  0xE3 -> DOUBLE LOW-9 QUOTATION MARK
+    u'\u2030'   #  0xE4 -> PER MILLE SIGN
+    u'\xc2'     #  0xE5 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+    u'\xca'     #  0xE6 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+    u'\xc1'     #  0xE7 -> LATIN CAPITAL LETTER A WITH ACUTE
+    u'\xcb'     #  0xE8 -> LATIN CAPITAL LETTER E WITH DIAERESIS
+    u'\xc8'     #  0xE9 -> LATIN CAPITAL LETTER E WITH GRAVE
+    u'\xcd'     #  0xEA -> LATIN CAPITAL LETTER I WITH ACUTE
+    u'\xce'     #  0xEB -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+    u'\xcf'     #  0xEC -> LATIN CAPITAL LETTER I WITH DIAERESIS
+    u'\xcc'     #  0xED -> LATIN CAPITAL LETTER I WITH GRAVE
+    u'\xd3'     #  0xEE -> LATIN CAPITAL LETTER O WITH ACUTE
+    u'\xd4'     #  0xEF -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+    u'\uf8ff'   #  0xF0 -> Apple logo
+    u'\xd2'     #  0xF1 -> LATIN CAPITAL LETTER O WITH GRAVE
+    u'\xda'     #  0xF2 -> LATIN CAPITAL LETTER U WITH ACUTE
+    u'\xdb'     #  0xF3 -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+    u'\xd9'     #  0xF4 -> LATIN CAPITAL LETTER U WITH GRAVE
+    u'\u0131'   #  0xF5 -> LATIN SMALL LETTER DOTLESS I
+    u'\u02c6'   #  0xF6 -> MODIFIER LETTER CIRCUMFLEX ACCENT
+    u'\u02dc'   #  0xF7 -> SMALL TILDE
+    u'\xaf'     #  0xF8 -> MACRON
+    u'\u02d8'   #  0xF9 -> BREVE
+    u'\u02d9'   #  0xFA -> DOT ABOVE
+    u'\u02da'   #  0xFB -> RING ABOVE
+    u'\xb8'     #  0xFC -> CEDILLA
+    u'\u02dd'   #  0xFD -> DOUBLE ACUTE ACCENT
+    u'\u02db'   #  0xFE -> OGONEK
+    u'\u02c7'   #  0xFF -> CARON
+)
+
+### Encoding table
+encoding_table=codecs.charmap_build(decoding_table)

Added: vendor/Python/current/Lib/encodings/mac_romanian.py
===================================================================
--- vendor/Python/current/Lib/encodings/mac_romanian.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/mac_romanian.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,307 @@
+""" Python Character Mapping Codec mac_romanian generated from 'MAPPINGS/VENDORS/APPLE/ROMANIAN.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_table)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_table)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='mac-romanian',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x00 -> CONTROL CHARACTER
+    u'\x01'     #  0x01 -> CONTROL CHARACTER
+    u'\x02'     #  0x02 -> CONTROL CHARACTER
+    u'\x03'     #  0x03 -> CONTROL CHARACTER
+    u'\x04'     #  0x04 -> CONTROL CHARACTER
+    u'\x05'     #  0x05 -> CONTROL CHARACTER
+    u'\x06'     #  0x06 -> CONTROL CHARACTER
+    u'\x07'     #  0x07 -> CONTROL CHARACTER
+    u'\x08'     #  0x08 -> CONTROL CHARACTER
+    u'\t'       #  0x09 -> CONTROL CHARACTER
+    u'\n'       #  0x0A -> CONTROL CHARACTER
+    u'\x0b'     #  0x0B -> CONTROL CHARACTER
+    u'\x0c'     #  0x0C -> CONTROL CHARACTER
+    u'\r'       #  0x0D -> CONTROL CHARACTER
+    u'\x0e'     #  0x0E -> CONTROL CHARACTER
+    u'\x0f'     #  0x0F -> CONTROL CHARACTER
+    u'\x10'     #  0x10 -> CONTROL CHARACTER
+    u'\x11'     #  0x11 -> CONTROL CHARACTER
+    u'\x12'     #  0x12 -> CONTROL CHARACTER
+    u'\x13'     #  0x13 -> CONTROL CHARACTER
+    u'\x14'     #  0x14 -> CONTROL CHARACTER
+    u'\x15'     #  0x15 -> CONTROL CHARACTER
+    u'\x16'     #  0x16 -> CONTROL CHARACTER
+    u'\x17'     #  0x17 -> CONTROL CHARACTER
+    u'\x18'     #  0x18 -> CONTROL CHARACTER
+    u'\x19'     #  0x19 -> CONTROL CHARACTER
+    u'\x1a'     #  0x1A -> CONTROL CHARACTER
+    u'\x1b'     #  0x1B -> CONTROL CHARACTER
+    u'\x1c'     #  0x1C -> CONTROL CHARACTER
+    u'\x1d'     #  0x1D -> CONTROL CHARACTER
+    u'\x1e'     #  0x1E -> CONTROL CHARACTER
+    u'\x1f'     #  0x1F -> CONTROL CHARACTER
+    u' '        #  0x20 -> SPACE
+    u'!'        #  0x21 -> EXCLAMATION MARK
+    u'"'        #  0x22 -> QUOTATION MARK
+    u'#'        #  0x23 -> NUMBER SIGN
+    u'$'        #  0x24 -> DOLLAR SIGN
+    u'%'        #  0x25 -> PERCENT SIGN
+    u'&'        #  0x26 -> AMPERSAND
+    u"'"        #  0x27 -> APOSTROPHE
+    u'('        #  0x28 -> LEFT PARENTHESIS
+    u')'        #  0x29 -> RIGHT PARENTHESIS
+    u'*'        #  0x2A -> ASTERISK
+    u'+'        #  0x2B -> PLUS SIGN
+    u','        #  0x2C -> COMMA
+    u'-'        #  0x2D -> HYPHEN-MINUS
+    u'.'        #  0x2E -> FULL STOP
+    u'/'        #  0x2F -> SOLIDUS
+    u'0'        #  0x30 -> DIGIT ZERO
+    u'1'        #  0x31 -> DIGIT ONE
+    u'2'        #  0x32 -> DIGIT TWO
+    u'3'        #  0x33 -> DIGIT THREE
+    u'4'        #  0x34 -> DIGIT FOUR
+    u'5'        #  0x35 -> DIGIT FIVE
+    u'6'        #  0x36 -> DIGIT SIX
+    u'7'        #  0x37 -> DIGIT SEVEN
+    u'8'        #  0x38 -> DIGIT EIGHT
+    u'9'        #  0x39 -> DIGIT NINE
+    u':'        #  0x3A -> COLON
+    u';'        #  0x3B -> SEMICOLON
+    u'<'        #  0x3C -> LESS-THAN SIGN
+    u'='        #  0x3D -> EQUALS SIGN
+    u'>'        #  0x3E -> GREATER-THAN SIGN
+    u'?'        #  0x3F -> QUESTION MARK
+    u'@'        #  0x40 -> COMMERCIAL AT
+    u'A'        #  0x41 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x42 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x43 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x44 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x45 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x46 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x47 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x48 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x49 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x4A -> LATIN CAPITAL LETTER J
+    u'K'        #  0x4B -> LATIN CAPITAL LETTER K
+    u'L'        #  0x4C -> LATIN CAPITAL LETTER L
+    u'M'        #  0x4D -> LATIN CAPITAL LETTER M
+    u'N'        #  0x4E -> LATIN CAPITAL LETTER N
+    u'O'        #  0x4F -> LATIN CAPITAL LETTER O
+    u'P'        #  0x50 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x51 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x52 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x53 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x54 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x55 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x56 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x57 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x58 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x59 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x5A -> LATIN CAPITAL LETTER Z
+    u'['        #  0x5B -> LEFT SQUARE BRACKET
+    u'\\'       #  0x5C -> REVERSE SOLIDUS
+    u']'        #  0x5D -> RIGHT SQUARE BRACKET
+    u'^'        #  0x5E -> CIRCUMFLEX ACCENT
+    u'_'        #  0x5F -> LOW LINE
+    u'`'        #  0x60 -> GRAVE ACCENT
+    u'a'        #  0x61 -> LATIN SMALL LETTER A
+    u'b'        #  0x62 -> LATIN SMALL LETTER B
+    u'c'        #  0x63 -> LATIN SMALL LETTER C
+    u'd'        #  0x64 -> LATIN SMALL LETTER D
+    u'e'        #  0x65 -> LATIN SMALL LETTER E
+    u'f'        #  0x66 -> LATIN SMALL LETTER F
+    u'g'        #  0x67 -> LATIN SMALL LETTER G
+    u'h'        #  0x68 -> LATIN SMALL LETTER H
+    u'i'        #  0x69 -> LATIN SMALL LETTER I
+    u'j'        #  0x6A -> LATIN SMALL LETTER J
+    u'k'        #  0x6B -> LATIN SMALL LETTER K
+    u'l'        #  0x6C -> LATIN SMALL LETTER L
+    u'm'        #  0x6D -> LATIN SMALL LETTER M
+    u'n'        #  0x6E -> LATIN SMALL LETTER N
+    u'o'        #  0x6F -> LATIN SMALL LETTER O
+    u'p'        #  0x70 -> LATIN SMALL LETTER P
+    u'q'        #  0x71 -> LATIN SMALL LETTER Q
+    u'r'        #  0x72 -> LATIN SMALL LETTER R
+    u's'        #  0x73 -> LATIN SMALL LETTER S
+    u't'        #  0x74 -> LATIN SMALL LETTER T
+    u'u'        #  0x75 -> LATIN SMALL LETTER U
+    u'v'        #  0x76 -> LATIN SMALL LETTER V
+    u'w'        #  0x77 -> LATIN SMALL LETTER W
+    u'x'        #  0x78 -> LATIN SMALL LETTER X
+    u'y'        #  0x79 -> LATIN SMALL LETTER Y
+    u'z'        #  0x7A -> LATIN SMALL LETTER Z
+    u'{'        #  0x7B -> LEFT CURLY BRACKET
+    u'|'        #  0x7C -> VERTICAL LINE
+    u'}'        #  0x7D -> RIGHT CURLY BRACKET
+    u'~'        #  0x7E -> TILDE
+    u'\x7f'     #  0x7F -> CONTROL CHARACTER
+    u'\xc4'     #  0x80 -> LATIN CAPITAL LETTER A WITH DIAERESIS
+    u'\xc5'     #  0x81 -> LATIN CAPITAL LETTER A WITH RING ABOVE
+    u'\xc7'     #  0x82 -> LATIN CAPITAL LETTER C WITH CEDILLA
+    u'\xc9'     #  0x83 -> LATIN CAPITAL LETTER E WITH ACUTE
+    u'\xd1'     #  0x84 -> LATIN CAPITAL LETTER N WITH TILDE
+    u'\xd6'     #  0x85 -> LATIN CAPITAL LETTER O WITH DIAERESIS
+    u'\xdc'     #  0x86 -> LATIN CAPITAL LETTER U WITH DIAERESIS
+    u'\xe1'     #  0x87 -> LATIN SMALL LETTER A WITH ACUTE
+    u'\xe0'     #  0x88 -> LATIN SMALL LETTER A WITH GRAVE
+    u'\xe2'     #  0x89 -> LATIN SMALL LETTER A WITH CIRCUMFLEX
+    u'\xe4'     #  0x8A -> LATIN SMALL LETTER A WITH DIAERESIS
+    u'\xe3'     #  0x8B -> LATIN SMALL LETTER A WITH TILDE
+    u'\xe5'     #  0x8C -> LATIN SMALL LETTER A WITH RING ABOVE
+    u'\xe7'     #  0x8D -> LATIN SMALL LETTER C WITH CEDILLA
+    u'\xe9'     #  0x8E -> LATIN SMALL LETTER E WITH ACUTE
+    u'\xe8'     #  0x8F -> LATIN SMALL LETTER E WITH GRAVE
+    u'\xea'     #  0x90 -> LATIN SMALL LETTER E WITH CIRCUMFLEX
+    u'\xeb'     #  0x91 -> LATIN SMALL LETTER E WITH DIAERESIS
+    u'\xed'     #  0x92 -> LATIN SMALL LETTER I WITH ACUTE
+    u'\xec'     #  0x93 -> LATIN SMALL LETTER I WITH GRAVE
+    u'\xee'     #  0x94 -> LATIN SMALL LETTER I WITH CIRCUMFLEX
+    u'\xef'     #  0x95 -> LATIN SMALL LETTER I WITH DIAERESIS
+    u'\xf1'     #  0x96 -> LATIN SMALL LETTER N WITH TILDE
+    u'\xf3'     #  0x97 -> LATIN SMALL LETTER O WITH ACUTE
+    u'\xf2'     #  0x98 -> LATIN SMALL LETTER O WITH GRAVE
+    u'\xf4'     #  0x99 -> LATIN SMALL LETTER O WITH CIRCUMFLEX
+    u'\xf6'     #  0x9A -> LATIN SMALL LETTER O WITH DIAERESIS
+    u'\xf5'     #  0x9B -> LATIN SMALL LETTER O WITH TILDE
+    u'\xfa'     #  0x9C -> LATIN SMALL LETTER U WITH ACUTE
+    u'\xf9'     #  0x9D -> LATIN SMALL LETTER U WITH GRAVE
+    u'\xfb'     #  0x9E -> LATIN SMALL LETTER U WITH CIRCUMFLEX
+    u'\xfc'     #  0x9F -> LATIN SMALL LETTER U WITH DIAERESIS
+    u'\u2020'   #  0xA0 -> DAGGER
+    u'\xb0'     #  0xA1 -> DEGREE SIGN
+    u'\xa2'     #  0xA2 -> CENT SIGN
+    u'\xa3'     #  0xA3 -> POUND SIGN
+    u'\xa7'     #  0xA4 -> SECTION SIGN
+    u'\u2022'   #  0xA5 -> BULLET
+    u'\xb6'     #  0xA6 -> PILCROW SIGN
+    u'\xdf'     #  0xA7 -> LATIN SMALL LETTER SHARP S
+    u'\xae'     #  0xA8 -> REGISTERED SIGN
+    u'\xa9'     #  0xA9 -> COPYRIGHT SIGN
+    u'\u2122'   #  0xAA -> TRADE MARK SIGN
+    u'\xb4'     #  0xAB -> ACUTE ACCENT
+    u'\xa8'     #  0xAC -> DIAERESIS
+    u'\u2260'   #  0xAD -> NOT EQUAL TO
+    u'\u0102'   #  0xAE -> LATIN CAPITAL LETTER A WITH BREVE
+    u'\u0218'   #  0xAF -> LATIN CAPITAL LETTER S WITH COMMA BELOW # for Unicode 3.0 and later
+    u'\u221e'   #  0xB0 -> INFINITY
+    u'\xb1'     #  0xB1 -> PLUS-MINUS SIGN
+    u'\u2264'   #  0xB2 -> LESS-THAN OR EQUAL TO
+    u'\u2265'   #  0xB3 -> GREATER-THAN OR EQUAL TO
+    u'\xa5'     #  0xB4 -> YEN SIGN
+    u'\xb5'     #  0xB5 -> MICRO SIGN
+    u'\u2202'   #  0xB6 -> PARTIAL DIFFERENTIAL
+    u'\u2211'   #  0xB7 -> N-ARY SUMMATION
+    u'\u220f'   #  0xB8 -> N-ARY PRODUCT
+    u'\u03c0'   #  0xB9 -> GREEK SMALL LETTER PI
+    u'\u222b'   #  0xBA -> INTEGRAL
+    u'\xaa'     #  0xBB -> FEMININE ORDINAL INDICATOR
+    u'\xba'     #  0xBC -> MASCULINE ORDINAL INDICATOR
+    u'\u03a9'   #  0xBD -> GREEK CAPITAL LETTER OMEGA
+    u'\u0103'   #  0xBE -> LATIN SMALL LETTER A WITH BREVE
+    u'\u0219'   #  0xBF -> LATIN SMALL LETTER S WITH COMMA BELOW # for Unicode 3.0 and later
+    u'\xbf'     #  0xC0 -> INVERTED QUESTION MARK
+    u'\xa1'     #  0xC1 -> INVERTED EXCLAMATION MARK
+    u'\xac'     #  0xC2 -> NOT SIGN
+    u'\u221a'   #  0xC3 -> SQUARE ROOT
+    u'\u0192'   #  0xC4 -> LATIN SMALL LETTER F WITH HOOK
+    u'\u2248'   #  0xC5 -> ALMOST EQUAL TO
+    u'\u2206'   #  0xC6 -> INCREMENT
+    u'\xab'     #  0xC7 -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xbb'     #  0xC8 -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\u2026'   #  0xC9 -> HORIZONTAL ELLIPSIS
+    u'\xa0'     #  0xCA -> NO-BREAK SPACE
+    u'\xc0'     #  0xCB -> LATIN CAPITAL LETTER A WITH GRAVE
+    u'\xc3'     #  0xCC -> LATIN CAPITAL LETTER A WITH TILDE
+    u'\xd5'     #  0xCD -> LATIN CAPITAL LETTER O WITH TILDE
+    u'\u0152'   #  0xCE -> LATIN CAPITAL LIGATURE OE
+    u'\u0153'   #  0xCF -> LATIN SMALL LIGATURE OE
+    u'\u2013'   #  0xD0 -> EN DASH
+    u'\u2014'   #  0xD1 -> EM DASH
+    u'\u201c'   #  0xD2 -> LEFT DOUBLE QUOTATION MARK
+    u'\u201d'   #  0xD3 -> RIGHT DOUBLE QUOTATION MARK
+    u'\u2018'   #  0xD4 -> LEFT SINGLE QUOTATION MARK
+    u'\u2019'   #  0xD5 -> RIGHT SINGLE QUOTATION MARK
+    u'\xf7'     #  0xD6 -> DIVISION SIGN
+    u'\u25ca'   #  0xD7 -> LOZENGE
+    u'\xff'     #  0xD8 -> LATIN SMALL LETTER Y WITH DIAERESIS
+    u'\u0178'   #  0xD9 -> LATIN CAPITAL LETTER Y WITH DIAERESIS
+    u'\u2044'   #  0xDA -> FRACTION SLASH
+    u'\u20ac'   #  0xDB -> EURO SIGN
+    u'\u2039'   #  0xDC -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+    u'\u203a'   #  0xDD -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+    u'\u021a'   #  0xDE -> LATIN CAPITAL LETTER T WITH COMMA BELOW # for Unicode 3.0 and later
+    u'\u021b'   #  0xDF -> LATIN SMALL LETTER T WITH COMMA BELOW # for Unicode 3.0 and later
+    u'\u2021'   #  0xE0 -> DOUBLE DAGGER
+    u'\xb7'     #  0xE1 -> MIDDLE DOT
+    u'\u201a'   #  0xE2 -> SINGLE LOW-9 QUOTATION MARK
+    u'\u201e'   #  0xE3 -> DOUBLE LOW-9 QUOTATION MARK
+    u'\u2030'   #  0xE4 -> PER MILLE SIGN
+    u'\xc2'     #  0xE5 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+    u'\xca'     #  0xE6 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+    u'\xc1'     #  0xE7 -> LATIN CAPITAL LETTER A WITH ACUTE
+    u'\xcb'     #  0xE8 -> LATIN CAPITAL LETTER E WITH DIAERESIS
+    u'\xc8'     #  0xE9 -> LATIN CAPITAL LETTER E WITH GRAVE
+    u'\xcd'     #  0xEA -> LATIN CAPITAL LETTER I WITH ACUTE
+    u'\xce'     #  0xEB -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+    u'\xcf'     #  0xEC -> LATIN CAPITAL LETTER I WITH DIAERESIS
+    u'\xcc'     #  0xED -> LATIN CAPITAL LETTER I WITH GRAVE
+    u'\xd3'     #  0xEE -> LATIN CAPITAL LETTER O WITH ACUTE
+    u'\xd4'     #  0xEF -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+    u'\uf8ff'   #  0xF0 -> Apple logo
+    u'\xd2'     #  0xF1 -> LATIN CAPITAL LETTER O WITH GRAVE
+    u'\xda'     #  0xF2 -> LATIN CAPITAL LETTER U WITH ACUTE
+    u'\xdb'     #  0xF3 -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+    u'\xd9'     #  0xF4 -> LATIN CAPITAL LETTER U WITH GRAVE
+    u'\u0131'   #  0xF5 -> LATIN SMALL LETTER DOTLESS I
+    u'\u02c6'   #  0xF6 -> MODIFIER LETTER CIRCUMFLEX ACCENT
+    u'\u02dc'   #  0xF7 -> SMALL TILDE
+    u'\xaf'     #  0xF8 -> MACRON
+    u'\u02d8'   #  0xF9 -> BREVE
+    u'\u02d9'   #  0xFA -> DOT ABOVE
+    u'\u02da'   #  0xFB -> RING ABOVE
+    u'\xb8'     #  0xFC -> CEDILLA
+    u'\u02dd'   #  0xFD -> DOUBLE ACUTE ACCENT
+    u'\u02db'   #  0xFE -> OGONEK
+    u'\u02c7'   #  0xFF -> CARON
+)
+
+### Encoding table
+encoding_table=codecs.charmap_build(decoding_table)

Added: vendor/Python/current/Lib/encodings/mac_turkish.py
===================================================================
--- vendor/Python/current/Lib/encodings/mac_turkish.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/mac_turkish.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,307 @@
+""" Python Character Mapping Codec mac_turkish generated from 'MAPPINGS/VENDORS/APPLE/TURKISH.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_table)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_table)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='mac-turkish',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x00 -> CONTROL CHARACTER
+    u'\x01'     #  0x01 -> CONTROL CHARACTER
+    u'\x02'     #  0x02 -> CONTROL CHARACTER
+    u'\x03'     #  0x03 -> CONTROL CHARACTER
+    u'\x04'     #  0x04 -> CONTROL CHARACTER
+    u'\x05'     #  0x05 -> CONTROL CHARACTER
+    u'\x06'     #  0x06 -> CONTROL CHARACTER
+    u'\x07'     #  0x07 -> CONTROL CHARACTER
+    u'\x08'     #  0x08 -> CONTROL CHARACTER
+    u'\t'       #  0x09 -> CONTROL CHARACTER
+    u'\n'       #  0x0A -> CONTROL CHARACTER
+    u'\x0b'     #  0x0B -> CONTROL CHARACTER
+    u'\x0c'     #  0x0C -> CONTROL CHARACTER
+    u'\r'       #  0x0D -> CONTROL CHARACTER
+    u'\x0e'     #  0x0E -> CONTROL CHARACTER
+    u'\x0f'     #  0x0F -> CONTROL CHARACTER
+    u'\x10'     #  0x10 -> CONTROL CHARACTER
+    u'\x11'     #  0x11 -> CONTROL CHARACTER
+    u'\x12'     #  0x12 -> CONTROL CHARACTER
+    u'\x13'     #  0x13 -> CONTROL CHARACTER
+    u'\x14'     #  0x14 -> CONTROL CHARACTER
+    u'\x15'     #  0x15 -> CONTROL CHARACTER
+    u'\x16'     #  0x16 -> CONTROL CHARACTER
+    u'\x17'     #  0x17 -> CONTROL CHARACTER
+    u'\x18'     #  0x18 -> CONTROL CHARACTER
+    u'\x19'     #  0x19 -> CONTROL CHARACTER
+    u'\x1a'     #  0x1A -> CONTROL CHARACTER
+    u'\x1b'     #  0x1B -> CONTROL CHARACTER
+    u'\x1c'     #  0x1C -> CONTROL CHARACTER
+    u'\x1d'     #  0x1D -> CONTROL CHARACTER
+    u'\x1e'     #  0x1E -> CONTROL CHARACTER
+    u'\x1f'     #  0x1F -> CONTROL CHARACTER
+    u' '        #  0x20 -> SPACE
+    u'!'        #  0x21 -> EXCLAMATION MARK
+    u'"'        #  0x22 -> QUOTATION MARK
+    u'#'        #  0x23 -> NUMBER SIGN
+    u'$'        #  0x24 -> DOLLAR SIGN
+    u'%'        #  0x25 -> PERCENT SIGN
+    u'&'        #  0x26 -> AMPERSAND
+    u"'"        #  0x27 -> APOSTROPHE
+    u'('        #  0x28 -> LEFT PARENTHESIS
+    u')'        #  0x29 -> RIGHT PARENTHESIS
+    u'*'        #  0x2A -> ASTERISK
+    u'+'        #  0x2B -> PLUS SIGN
+    u','        #  0x2C -> COMMA
+    u'-'        #  0x2D -> HYPHEN-MINUS
+    u'.'        #  0x2E -> FULL STOP
+    u'/'        #  0x2F -> SOLIDUS
+    u'0'        #  0x30 -> DIGIT ZERO
+    u'1'        #  0x31 -> DIGIT ONE
+    u'2'        #  0x32 -> DIGIT TWO
+    u'3'        #  0x33 -> DIGIT THREE
+    u'4'        #  0x34 -> DIGIT FOUR
+    u'5'        #  0x35 -> DIGIT FIVE
+    u'6'        #  0x36 -> DIGIT SIX
+    u'7'        #  0x37 -> DIGIT SEVEN
+    u'8'        #  0x38 -> DIGIT EIGHT
+    u'9'        #  0x39 -> DIGIT NINE
+    u':'        #  0x3A -> COLON
+    u';'        #  0x3B -> SEMICOLON
+    u'<'        #  0x3C -> LESS-THAN SIGN
+    u'='        #  0x3D -> EQUALS SIGN
+    u'>'        #  0x3E -> GREATER-THAN SIGN
+    u'?'        #  0x3F -> QUESTION MARK
+    u'@'        #  0x40 -> COMMERCIAL AT
+    u'A'        #  0x41 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x42 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x43 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x44 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x45 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x46 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x47 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x48 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x49 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x4A -> LATIN CAPITAL LETTER J
+    u'K'        #  0x4B -> LATIN CAPITAL LETTER K
+    u'L'        #  0x4C -> LATIN CAPITAL LETTER L
+    u'M'        #  0x4D -> LATIN CAPITAL LETTER M
+    u'N'        #  0x4E -> LATIN CAPITAL LETTER N
+    u'O'        #  0x4F -> LATIN CAPITAL LETTER O
+    u'P'        #  0x50 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x51 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x52 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x53 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x54 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x55 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x56 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x57 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x58 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x59 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x5A -> LATIN CAPITAL LETTER Z
+    u'['        #  0x5B -> LEFT SQUARE BRACKET
+    u'\\'       #  0x5C -> REVERSE SOLIDUS
+    u']'        #  0x5D -> RIGHT SQUARE BRACKET
+    u'^'        #  0x5E -> CIRCUMFLEX ACCENT
+    u'_'        #  0x5F -> LOW LINE
+    u'`'        #  0x60 -> GRAVE ACCENT
+    u'a'        #  0x61 -> LATIN SMALL LETTER A
+    u'b'        #  0x62 -> LATIN SMALL LETTER B
+    u'c'        #  0x63 -> LATIN SMALL LETTER C
+    u'd'        #  0x64 -> LATIN SMALL LETTER D
+    u'e'        #  0x65 -> LATIN SMALL LETTER E
+    u'f'        #  0x66 -> LATIN SMALL LETTER F
+    u'g'        #  0x67 -> LATIN SMALL LETTER G
+    u'h'        #  0x68 -> LATIN SMALL LETTER H
+    u'i'        #  0x69 -> LATIN SMALL LETTER I
+    u'j'        #  0x6A -> LATIN SMALL LETTER J
+    u'k'        #  0x6B -> LATIN SMALL LETTER K
+    u'l'        #  0x6C -> LATIN SMALL LETTER L
+    u'm'        #  0x6D -> LATIN SMALL LETTER M
+    u'n'        #  0x6E -> LATIN SMALL LETTER N
+    u'o'        #  0x6F -> LATIN SMALL LETTER O
+    u'p'        #  0x70 -> LATIN SMALL LETTER P
+    u'q'        #  0x71 -> LATIN SMALL LETTER Q
+    u'r'        #  0x72 -> LATIN SMALL LETTER R
+    u's'        #  0x73 -> LATIN SMALL LETTER S
+    u't'        #  0x74 -> LATIN SMALL LETTER T
+    u'u'        #  0x75 -> LATIN SMALL LETTER U
+    u'v'        #  0x76 -> LATIN SMALL LETTER V
+    u'w'        #  0x77 -> LATIN SMALL LETTER W
+    u'x'        #  0x78 -> LATIN SMALL LETTER X
+    u'y'        #  0x79 -> LATIN SMALL LETTER Y
+    u'z'        #  0x7A -> LATIN SMALL LETTER Z
+    u'{'        #  0x7B -> LEFT CURLY BRACKET
+    u'|'        #  0x7C -> VERTICAL LINE
+    u'}'        #  0x7D -> RIGHT CURLY BRACKET
+    u'~'        #  0x7E -> TILDE
+    u'\x7f'     #  0x7F -> CONTROL CHARACTER
+    u'\xc4'     #  0x80 -> LATIN CAPITAL LETTER A WITH DIAERESIS
+    u'\xc5'     #  0x81 -> LATIN CAPITAL LETTER A WITH RING ABOVE
+    u'\xc7'     #  0x82 -> LATIN CAPITAL LETTER C WITH CEDILLA
+    u'\xc9'     #  0x83 -> LATIN CAPITAL LETTER E WITH ACUTE
+    u'\xd1'     #  0x84 -> LATIN CAPITAL LETTER N WITH TILDE
+    u'\xd6'     #  0x85 -> LATIN CAPITAL LETTER O WITH DIAERESIS
+    u'\xdc'     #  0x86 -> LATIN CAPITAL LETTER U WITH DIAERESIS
+    u'\xe1'     #  0x87 -> LATIN SMALL LETTER A WITH ACUTE
+    u'\xe0'     #  0x88 -> LATIN SMALL LETTER A WITH GRAVE
+    u'\xe2'     #  0x89 -> LATIN SMALL LETTER A WITH CIRCUMFLEX
+    u'\xe4'     #  0x8A -> LATIN SMALL LETTER A WITH DIAERESIS
+    u'\xe3'     #  0x8B -> LATIN SMALL LETTER A WITH TILDE
+    u'\xe5'     #  0x8C -> LATIN SMALL LETTER A WITH RING ABOVE
+    u'\xe7'     #  0x8D -> LATIN SMALL LETTER C WITH CEDILLA
+    u'\xe9'     #  0x8E -> LATIN SMALL LETTER E WITH ACUTE
+    u'\xe8'     #  0x8F -> LATIN SMALL LETTER E WITH GRAVE
+    u'\xea'     #  0x90 -> LATIN SMALL LETTER E WITH CIRCUMFLEX
+    u'\xeb'     #  0x91 -> LATIN SMALL LETTER E WITH DIAERESIS
+    u'\xed'     #  0x92 -> LATIN SMALL LETTER I WITH ACUTE
+    u'\xec'     #  0x93 -> LATIN SMALL LETTER I WITH GRAVE
+    u'\xee'     #  0x94 -> LATIN SMALL LETTER I WITH CIRCUMFLEX
+    u'\xef'     #  0x95 -> LATIN SMALL LETTER I WITH DIAERESIS
+    u'\xf1'     #  0x96 -> LATIN SMALL LETTER N WITH TILDE
+    u'\xf3'     #  0x97 -> LATIN SMALL LETTER O WITH ACUTE
+    u'\xf2'     #  0x98 -> LATIN SMALL LETTER O WITH GRAVE
+    u'\xf4'     #  0x99 -> LATIN SMALL LETTER O WITH CIRCUMFLEX
+    u'\xf6'     #  0x9A -> LATIN SMALL LETTER O WITH DIAERESIS
+    u'\xf5'     #  0x9B -> LATIN SMALL LETTER O WITH TILDE
+    u'\xfa'     #  0x9C -> LATIN SMALL LETTER U WITH ACUTE
+    u'\xf9'     #  0x9D -> LATIN SMALL LETTER U WITH GRAVE
+    u'\xfb'     #  0x9E -> LATIN SMALL LETTER U WITH CIRCUMFLEX
+    u'\xfc'     #  0x9F -> LATIN SMALL LETTER U WITH DIAERESIS
+    u'\u2020'   #  0xA0 -> DAGGER
+    u'\xb0'     #  0xA1 -> DEGREE SIGN
+    u'\xa2'     #  0xA2 -> CENT SIGN
+    u'\xa3'     #  0xA3 -> POUND SIGN
+    u'\xa7'     #  0xA4 -> SECTION SIGN
+    u'\u2022'   #  0xA5 -> BULLET
+    u'\xb6'     #  0xA6 -> PILCROW SIGN
+    u'\xdf'     #  0xA7 -> LATIN SMALL LETTER SHARP S
+    u'\xae'     #  0xA8 -> REGISTERED SIGN
+    u'\xa9'     #  0xA9 -> COPYRIGHT SIGN
+    u'\u2122'   #  0xAA -> TRADE MARK SIGN
+    u'\xb4'     #  0xAB -> ACUTE ACCENT
+    u'\xa8'     #  0xAC -> DIAERESIS
+    u'\u2260'   #  0xAD -> NOT EQUAL TO
+    u'\xc6'     #  0xAE -> LATIN CAPITAL LETTER AE
+    u'\xd8'     #  0xAF -> LATIN CAPITAL LETTER O WITH STROKE
+    u'\u221e'   #  0xB0 -> INFINITY
+    u'\xb1'     #  0xB1 -> PLUS-MINUS SIGN
+    u'\u2264'   #  0xB2 -> LESS-THAN OR EQUAL TO
+    u'\u2265'   #  0xB3 -> GREATER-THAN OR EQUAL TO
+    u'\xa5'     #  0xB4 -> YEN SIGN
+    u'\xb5'     #  0xB5 -> MICRO SIGN
+    u'\u2202'   #  0xB6 -> PARTIAL DIFFERENTIAL
+    u'\u2211'   #  0xB7 -> N-ARY SUMMATION
+    u'\u220f'   #  0xB8 -> N-ARY PRODUCT
+    u'\u03c0'   #  0xB9 -> GREEK SMALL LETTER PI
+    u'\u222b'   #  0xBA -> INTEGRAL
+    u'\xaa'     #  0xBB -> FEMININE ORDINAL INDICATOR
+    u'\xba'     #  0xBC -> MASCULINE ORDINAL INDICATOR
+    u'\u03a9'   #  0xBD -> GREEK CAPITAL LETTER OMEGA
+    u'\xe6'     #  0xBE -> LATIN SMALL LETTER AE
+    u'\xf8'     #  0xBF -> LATIN SMALL LETTER O WITH STROKE
+    u'\xbf'     #  0xC0 -> INVERTED QUESTION MARK
+    u'\xa1'     #  0xC1 -> INVERTED EXCLAMATION MARK
+    u'\xac'     #  0xC2 -> NOT SIGN
+    u'\u221a'   #  0xC3 -> SQUARE ROOT
+    u'\u0192'   #  0xC4 -> LATIN SMALL LETTER F WITH HOOK
+    u'\u2248'   #  0xC5 -> ALMOST EQUAL TO
+    u'\u2206'   #  0xC6 -> INCREMENT
+    u'\xab'     #  0xC7 -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\xbb'     #  0xC8 -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    u'\u2026'   #  0xC9 -> HORIZONTAL ELLIPSIS
+    u'\xa0'     #  0xCA -> NO-BREAK SPACE
+    u'\xc0'     #  0xCB -> LATIN CAPITAL LETTER A WITH GRAVE
+    u'\xc3'     #  0xCC -> LATIN CAPITAL LETTER A WITH TILDE
+    u'\xd5'     #  0xCD -> LATIN CAPITAL LETTER O WITH TILDE
+    u'\u0152'   #  0xCE -> LATIN CAPITAL LIGATURE OE
+    u'\u0153'   #  0xCF -> LATIN SMALL LIGATURE OE
+    u'\u2013'   #  0xD0 -> EN DASH
+    u'\u2014'   #  0xD1 -> EM DASH
+    u'\u201c'   #  0xD2 -> LEFT DOUBLE QUOTATION MARK
+    u'\u201d'   #  0xD3 -> RIGHT DOUBLE QUOTATION MARK
+    u'\u2018'   #  0xD4 -> LEFT SINGLE QUOTATION MARK
+    u'\u2019'   #  0xD5 -> RIGHT SINGLE QUOTATION MARK
+    u'\xf7'     #  0xD6 -> DIVISION SIGN
+    u'\u25ca'   #  0xD7 -> LOZENGE
+    u'\xff'     #  0xD8 -> LATIN SMALL LETTER Y WITH DIAERESIS
+    u'\u0178'   #  0xD9 -> LATIN CAPITAL LETTER Y WITH DIAERESIS
+    u'\u011e'   #  0xDA -> LATIN CAPITAL LETTER G WITH BREVE
+    u'\u011f'   #  0xDB -> LATIN SMALL LETTER G WITH BREVE
+    u'\u0130'   #  0xDC -> LATIN CAPITAL LETTER I WITH DOT ABOVE
+    u'\u0131'   #  0xDD -> LATIN SMALL LETTER DOTLESS I
+    u'\u015e'   #  0xDE -> LATIN CAPITAL LETTER S WITH CEDILLA
+    u'\u015f'   #  0xDF -> LATIN SMALL LETTER S WITH CEDILLA
+    u'\u2021'   #  0xE0 -> DOUBLE DAGGER
+    u'\xb7'     #  0xE1 -> MIDDLE DOT
+    u'\u201a'   #  0xE2 -> SINGLE LOW-9 QUOTATION MARK
+    u'\u201e'   #  0xE3 -> DOUBLE LOW-9 QUOTATION MARK
+    u'\u2030'   #  0xE4 -> PER MILLE SIGN
+    u'\xc2'     #  0xE5 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+    u'\xca'     #  0xE6 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+    u'\xc1'     #  0xE7 -> LATIN CAPITAL LETTER A WITH ACUTE
+    u'\xcb'     #  0xE8 -> LATIN CAPITAL LETTER E WITH DIAERESIS
+    u'\xc8'     #  0xE9 -> LATIN CAPITAL LETTER E WITH GRAVE
+    u'\xcd'     #  0xEA -> LATIN CAPITAL LETTER I WITH ACUTE
+    u'\xce'     #  0xEB -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+    u'\xcf'     #  0xEC -> LATIN CAPITAL LETTER I WITH DIAERESIS
+    u'\xcc'     #  0xED -> LATIN CAPITAL LETTER I WITH GRAVE
+    u'\xd3'     #  0xEE -> LATIN CAPITAL LETTER O WITH ACUTE
+    u'\xd4'     #  0xEF -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+    u'\uf8ff'   #  0xF0 -> Apple logo
+    u'\xd2'     #  0xF1 -> LATIN CAPITAL LETTER O WITH GRAVE
+    u'\xda'     #  0xF2 -> LATIN CAPITAL LETTER U WITH ACUTE
+    u'\xdb'     #  0xF3 -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+    u'\xd9'     #  0xF4 -> LATIN CAPITAL LETTER U WITH GRAVE
+    u'\uf8a0'   #  0xF5 -> undefined1
+    u'\u02c6'   #  0xF6 -> MODIFIER LETTER CIRCUMFLEX ACCENT
+    u'\u02dc'   #  0xF7 -> SMALL TILDE
+    u'\xaf'     #  0xF8 -> MACRON
+    u'\u02d8'   #  0xF9 -> BREVE
+    u'\u02d9'   #  0xFA -> DOT ABOVE
+    u'\u02da'   #  0xFB -> RING ABOVE
+    u'\xb8'     #  0xFC -> CEDILLA
+    u'\u02dd'   #  0xFD -> DOUBLE ACUTE ACCENT
+    u'\u02db'   #  0xFE -> OGONEK
+    u'\u02c7'   #  0xFF -> CARON
+)
+
+### Encoding table
+encoding_table=codecs.charmap_build(decoding_table)

Added: vendor/Python/current/Lib/encodings/mbcs.py
===================================================================
--- vendor/Python/current/Lib/encodings/mbcs.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/mbcs.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,47 @@
+""" Python 'mbcs' Codec for Windows
+
+
+Cloned by Mark Hammond (mhammond at skippinet.com.au) from ascii.py,
+which was written by Marc-Andre Lemburg (mal at lemburg.com).
+
+(c) Copyright CNRI, All Rights Reserved. NO WARRANTY.
+
+"""
+# Import them explicitly to cause an ImportError
+# on non-Windows systems
+from codecs import mbcs_encode, mbcs_decode
+# for IncrementalDecoder, IncrementalEncoder, ...
+import codecs
+
+### Codec APIs
+
+encode = mbcs_encode
+
+def decode(input, errors='strict'):
+    return mbcs_decode(input, errors, True)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return mbcs_encode(input, self.errors)[0]
+
+class IncrementalDecoder(codecs.BufferedIncrementalDecoder):
+    _buffer_decode = mbcs_decode
+
+class StreamWriter(codecs.StreamWriter):
+    encode = mbcs_encode
+
+class StreamReader(codecs.StreamReader):
+    decode = mbcs_decode
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='mbcs',
+        encode=encode,
+        decode=decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )

Added: vendor/Python/current/Lib/encodings/palmos.py
===================================================================
--- vendor/Python/current/Lib/encodings/palmos.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/palmos.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,83 @@
+""" Python Character Mapping Codec for PalmOS 3.5.
+
+Written by Sjoerd Mullender (sjoerd at acm.org); based on iso8859_15.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_map)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_map)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_map)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='palmos',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+### Decoding Map
+
+decoding_map = codecs.make_identity_dict(range(256))
+
+# The PalmOS character set is mostly iso-8859-1 with some differences.
+decoding_map.update({
+        0x0080: 0x20ac, #       EURO SIGN
+        0x0082: 0x201a, #       SINGLE LOW-9 QUOTATION MARK
+        0x0083: 0x0192, #       LATIN SMALL LETTER F WITH HOOK
+        0x0084: 0x201e, #       DOUBLE LOW-9 QUOTATION MARK
+        0x0085: 0x2026, #       HORIZONTAL ELLIPSIS
+        0x0086: 0x2020, #       DAGGER
+        0x0087: 0x2021, #       DOUBLE DAGGER
+        0x0088: 0x02c6, #       MODIFIER LETTER CIRCUMFLEX ACCENT
+        0x0089: 0x2030, #       PER MILLE SIGN
+        0x008a: 0x0160, #       LATIN CAPITAL LETTER S WITH CARON
+        0x008b: 0x2039, #       SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+        0x008c: 0x0152, #       LATIN CAPITAL LIGATURE OE
+        0x008d: 0x2666, #       BLACK DIAMOND SUIT
+        0x008e: 0x2663, #       BLACK CLUB SUIT
+        0x008f: 0x2665, #       BLACK HEART SUIT
+        0x0090: 0x2660, #       BLACK SPADE SUIT
+        0x0091: 0x2018, #       LEFT SINGLE QUOTATION MARK
+        0x0092: 0x2019, #       RIGHT SINGLE QUOTATION MARK
+        0x0093: 0x201c, #       LEFT DOUBLE QUOTATION MARK
+        0x0094: 0x201d, #       RIGHT DOUBLE QUOTATION MARK
+        0x0095: 0x2022, #       BULLET
+        0x0096: 0x2013, #       EN DASH
+        0x0097: 0x2014, #       EM DASH
+        0x0098: 0x02dc, #       SMALL TILDE
+        0x0099: 0x2122, #       TRADE MARK SIGN
+        0x009a: 0x0161, #       LATIN SMALL LETTER S WITH CARON
+        0x009c: 0x0153, #       LATIN SMALL LIGATURE OE
+        0x009f: 0x0178, #       LATIN CAPITAL LETTER Y WITH DIAERESIS
+})
+
+### Encoding Map
+
+encoding_map = codecs.make_encoding_map(decoding_map)

Added: vendor/Python/current/Lib/encodings/ptcp154.py
===================================================================
--- vendor/Python/current/Lib/encodings/ptcp154.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/ptcp154.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,175 @@
+""" Python Character Mapping Codec generated from 'PTCP154.txt' with gencodec.py.
+
+Written by Marc-Andre Lemburg (mal at lemburg.com).
+
+(c) Copyright CNRI, All Rights Reserved. NO WARRANTY.
+(c) Copyright 2000 Guido van Rossum.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_map)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_map)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_map)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='ptcp154',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+### Decoding Map
+
+decoding_map = codecs.make_identity_dict(range(256))
+decoding_map.update({
+        0x0080: 0x0496, #        CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER
+        0x0081: 0x0492, #        CYRILLIC CAPITAL LETTER GHE WITH STROKE
+        0x0082: 0x04ee, #        CYRILLIC CAPITAL LETTER U WITH MACRON
+        0x0083: 0x0493, #        CYRILLIC SMALL LETTER GHE WITH STROKE
+        0x0084: 0x201e, #        DOUBLE LOW-9 QUOTATION MARK
+        0x0085: 0x2026, #        HORIZONTAL ELLIPSIS
+        0x0086: 0x04b6, #        CYRILLIC CAPITAL LETTER CHE WITH DESCENDER
+        0x0087: 0x04ae, #        CYRILLIC CAPITAL LETTER STRAIGHT U
+        0x0088: 0x04b2, #        CYRILLIC CAPITAL LETTER HA WITH DESCENDER
+        0x0089: 0x04af, #        CYRILLIC SMALL LETTER STRAIGHT U
+        0x008a: 0x04a0, #        CYRILLIC CAPITAL LETTER BASHKIR KA
+        0x008b: 0x04e2, #        CYRILLIC CAPITAL LETTER I WITH MACRON
+        0x008c: 0x04a2, #        CYRILLIC CAPITAL LETTER EN WITH DESCENDER
+        0x008d: 0x049a, #        CYRILLIC CAPITAL LETTER KA WITH DESCENDER
+        0x008e: 0x04ba, #        CYRILLIC CAPITAL LETTER SHHA
+        0x008f: 0x04b8, #        CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE
+        0x0090: 0x0497, #        CYRILLIC SMALL LETTER ZHE WITH DESCENDER
+        0x0091: 0x2018, #        LEFT SINGLE QUOTATION MARK
+        0x0092: 0x2019, #        RIGHT SINGLE QUOTATION MARK
+        0x0093: 0x201c, #        LEFT DOUBLE QUOTATION MARK
+        0x0094: 0x201d, #        RIGHT DOUBLE QUOTATION MARK
+        0x0095: 0x2022, #        BULLET
+        0x0096: 0x2013, #        EN DASH
+        0x0097: 0x2014, #        EM DASH
+        0x0098: 0x04b3, #        CYRILLIC SMALL LETTER HA WITH DESCENDER
+        0x0099: 0x04b7, #        CYRILLIC SMALL LETTER CHE WITH DESCENDER
+        0x009a: 0x04a1, #        CYRILLIC SMALL LETTER BASHKIR KA
+        0x009b: 0x04e3, #        CYRILLIC SMALL LETTER I WITH MACRON
+        0x009c: 0x04a3, #        CYRILLIC SMALL LETTER EN WITH DESCENDER
+        0x009d: 0x049b, #        CYRILLIC SMALL LETTER KA WITH DESCENDER
+        0x009e: 0x04bb, #        CYRILLIC SMALL LETTER SHHA
+        0x009f: 0x04b9, #        CYRILLIC SMALL LETTER CHE WITH VERTICAL STROKE
+        0x00a1: 0x040e, #        CYRILLIC CAPITAL LETTER SHORT U (Byelorussian)
+        0x00a2: 0x045e, #        CYRILLIC SMALL LETTER SHORT U (Byelorussian)
+        0x00a3: 0x0408, #        CYRILLIC CAPITAL LETTER JE
+        0x00a4: 0x04e8, #        CYRILLIC CAPITAL LETTER BARRED O
+        0x00a5: 0x0498, #        CYRILLIC CAPITAL LETTER ZE WITH DESCENDER
+        0x00a6: 0x04b0, #        CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE
+        0x00a8: 0x0401, #        CYRILLIC CAPITAL LETTER IO
+        0x00aa: 0x04d8, #        CYRILLIC CAPITAL LETTER SCHWA
+        0x00ad: 0x04ef, #        CYRILLIC SMALL LETTER U WITH MACRON
+        0x00af: 0x049c, #        CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE
+        0x00b1: 0x04b1, #        CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE
+        0x00b2: 0x0406, #        CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I
+        0x00b3: 0x0456, #        CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
+        0x00b4: 0x0499, #        CYRILLIC SMALL LETTER ZE WITH DESCENDER
+        0x00b5: 0x04e9, #        CYRILLIC SMALL LETTER BARRED O
+        0x00b8: 0x0451, #        CYRILLIC SMALL LETTER IO
+        0x00b9: 0x2116, #        NUMERO SIGN
+        0x00ba: 0x04d9, #        CYRILLIC SMALL LETTER SCHWA
+        0x00bc: 0x0458, #        CYRILLIC SMALL LETTER JE
+        0x00bd: 0x04aa, #        CYRILLIC CAPITAL LETTER ES WITH DESCENDER
+        0x00be: 0x04ab, #        CYRILLIC SMALL LETTER ES WITH DESCENDER
+        0x00bf: 0x049d, #        CYRILLIC SMALL LETTER KA WITH VERTICAL STROKE
+        0x00c0: 0x0410, #        CYRILLIC CAPITAL LETTER A
+        0x00c1: 0x0411, #        CYRILLIC CAPITAL LETTER BE
+        0x00c2: 0x0412, #        CYRILLIC CAPITAL LETTER VE
+        0x00c3: 0x0413, #        CYRILLIC CAPITAL LETTER GHE
+        0x00c4: 0x0414, #        CYRILLIC CAPITAL LETTER DE
+        0x00c5: 0x0415, #        CYRILLIC CAPITAL LETTER IE
+        0x00c6: 0x0416, #        CYRILLIC CAPITAL LETTER ZHE
+        0x00c7: 0x0417, #        CYRILLIC CAPITAL LETTER ZE
+        0x00c8: 0x0418, #        CYRILLIC CAPITAL LETTER I
+        0x00c9: 0x0419, #        CYRILLIC CAPITAL LETTER SHORT I
+        0x00ca: 0x041a, #        CYRILLIC CAPITAL LETTER KA
+        0x00cb: 0x041b, #        CYRILLIC CAPITAL LETTER EL
+        0x00cc: 0x041c, #        CYRILLIC CAPITAL LETTER EM
+        0x00cd: 0x041d, #        CYRILLIC CAPITAL LETTER EN
+        0x00ce: 0x041e, #        CYRILLIC CAPITAL LETTER O
+        0x00cf: 0x041f, #        CYRILLIC CAPITAL LETTER PE
+        0x00d0: 0x0420, #        CYRILLIC CAPITAL LETTER ER
+        0x00d1: 0x0421, #        CYRILLIC CAPITAL LETTER ES
+        0x00d2: 0x0422, #        CYRILLIC CAPITAL LETTER TE
+        0x00d3: 0x0423, #        CYRILLIC CAPITAL LETTER U
+        0x00d4: 0x0424, #        CYRILLIC CAPITAL LETTER EF
+        0x00d5: 0x0425, #        CYRILLIC CAPITAL LETTER HA
+        0x00d6: 0x0426, #        CYRILLIC CAPITAL LETTER TSE
+        0x00d7: 0x0427, #        CYRILLIC CAPITAL LETTER CHE
+        0x00d8: 0x0428, #        CYRILLIC CAPITAL LETTER SHA
+        0x00d9: 0x0429, #        CYRILLIC CAPITAL LETTER SHCHA
+        0x00da: 0x042a, #        CYRILLIC CAPITAL LETTER HARD SIGN
+        0x00db: 0x042b, #        CYRILLIC CAPITAL LETTER YERU
+        0x00dc: 0x042c, #        CYRILLIC CAPITAL LETTER SOFT SIGN
+        0x00dd: 0x042d, #        CYRILLIC CAPITAL LETTER E
+        0x00de: 0x042e, #        CYRILLIC CAPITAL LETTER YU
+        0x00df: 0x042f, #        CYRILLIC CAPITAL LETTER YA
+        0x00e0: 0x0430, #        CYRILLIC SMALL LETTER A
+        0x00e1: 0x0431, #        CYRILLIC SMALL LETTER BE
+        0x00e2: 0x0432, #        CYRILLIC SMALL LETTER VE
+        0x00e3: 0x0433, #        CYRILLIC SMALL LETTER GHE
+        0x00e4: 0x0434, #        CYRILLIC SMALL LETTER DE
+        0x00e5: 0x0435, #        CYRILLIC SMALL LETTER IE
+        0x00e6: 0x0436, #        CYRILLIC SMALL LETTER ZHE
+        0x00e7: 0x0437, #        CYRILLIC SMALL LETTER ZE
+        0x00e8: 0x0438, #        CYRILLIC SMALL LETTER I
+        0x00e9: 0x0439, #        CYRILLIC SMALL LETTER SHORT I
+        0x00ea: 0x043a, #        CYRILLIC SMALL LETTER KA
+        0x00eb: 0x043b, #        CYRILLIC SMALL LETTER EL
+        0x00ec: 0x043c, #        CYRILLIC SMALL LETTER EM
+        0x00ed: 0x043d, #        CYRILLIC SMALL LETTER EN
+        0x00ee: 0x043e, #        CYRILLIC SMALL LETTER O
+        0x00ef: 0x043f, #        CYRILLIC SMALL LETTER PE
+        0x00f0: 0x0440, #        CYRILLIC SMALL LETTER ER
+        0x00f1: 0x0441, #        CYRILLIC SMALL LETTER ES
+        0x00f2: 0x0442, #        CYRILLIC SMALL LETTER TE
+        0x00f3: 0x0443, #        CYRILLIC SMALL LETTER U
+        0x00f4: 0x0444, #        CYRILLIC SMALL LETTER EF
+        0x00f5: 0x0445, #        CYRILLIC SMALL LETTER HA
+        0x00f6: 0x0446, #        CYRILLIC SMALL LETTER TSE
+        0x00f7: 0x0447, #        CYRILLIC SMALL LETTER CHE
+        0x00f8: 0x0448, #        CYRILLIC SMALL LETTER SHA
+        0x00f9: 0x0449, #        CYRILLIC SMALL LETTER SHCHA
+        0x00fa: 0x044a, #        CYRILLIC SMALL LETTER HARD SIGN
+        0x00fb: 0x044b, #        CYRILLIC SMALL LETTER YERU
+        0x00fc: 0x044c, #        CYRILLIC SMALL LETTER SOFT SIGN
+        0x00fd: 0x044d, #        CYRILLIC SMALL LETTER E
+        0x00fe: 0x044e, #        CYRILLIC SMALL LETTER YU
+        0x00ff: 0x044f, #        CYRILLIC SMALL LETTER YA
+})
+
+### Encoding Map
+
+encoding_map = codecs.make_encoding_map(decoding_map)

Added: vendor/Python/current/Lib/encodings/punycode.py
===================================================================
--- vendor/Python/current/Lib/encodings/punycode.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/punycode.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,238 @@
+# -*- coding: iso-8859-1 -*-
+""" Codec for the Punicode encoding, as specified in RFC 3492
+
+Written by Martin v. Löwis.
+"""
+
+import codecs
+
+##################### Encoding #####################################
+
+def segregate(str):
+    """3.1 Basic code point segregation"""
+    base = []
+    extended = {}
+    for c in str:
+        if ord(c) < 128:
+            base.append(c)
+        else:
+            extended[c] = 1
+    extended = extended.keys()
+    extended.sort()
+    return "".join(base).encode("ascii"),extended
+
+def selective_len(str, max):
+    """Return the length of str, considering only characters below max."""
+    res = 0
+    for c in str:
+        if ord(c) < max:
+            res += 1
+    return res
+
+def selective_find(str, char, index, pos):
+    """Return a pair (index, pos), indicating the next occurrence of
+    char in str. index is the position of the character considering
+    only ordinals up to and including char, and pos is the position in
+    the full string. index/pos is the starting position in the full
+    string."""
+
+    l = len(str)
+    while 1:
+        pos += 1
+        if pos == l:
+            return (-1, -1)
+        c = str[pos]
+        if c == char:
+            return index+1, pos
+        elif c < char:
+            index += 1
+
+def insertion_unsort(str, extended):
+    """3.2 Insertion unsort coding"""
+    oldchar = 0x80
+    result = []
+    oldindex = -1
+    for c in extended:
+        index = pos = -1
+        char = ord(c)
+        curlen = selective_len(str, char)
+        delta = (curlen+1) * (char - oldchar)
+        while 1:
+            index,pos = selective_find(str,c,index,pos)
+            if index == -1:
+                break
+            delta += index - oldindex
+            result.append(delta-1)
+            oldindex = index
+            delta = 0
+        oldchar = char
+
+    return result
+
+def T(j, bias):
+    # Punycode parameters: tmin = 1, tmax = 26, base = 36
+    res = 36 * (j + 1) - bias
+    if res < 1: return 1
+    if res > 26: return 26
+    return res
+
+digits = "abcdefghijklmnopqrstuvwxyz0123456789"
+def generate_generalized_integer(N, bias):
+    """3.3 Generalized variable-length integers"""
+    result = []
+    j = 0
+    while 1:
+        t = T(j, bias)
+        if N < t:
+            result.append(digits[N])
+            return result
+        result.append(digits[t + ((N - t) % (36 - t))])
+        N = (N - t) // (36 - t)
+        j += 1
+
+def adapt(delta, first, numchars):
+    if first:
+        delta //= 700
+    else:
+        delta //= 2
+    delta += delta // numchars
+    # ((base - tmin) * tmax) // 2 == 455
+    divisions = 0
+    while delta > 455:
+        delta = delta // 35 # base - tmin
+        divisions += 36
+    bias = divisions + (36 * delta // (delta + 38))
+    return bias
+
+
+def generate_integers(baselen, deltas):
+    """3.4 Bias adaptation"""
+    # Punycode parameters: initial bias = 72, damp = 700, skew = 38
+    result = []
+    bias = 72
+    for points, delta in enumerate(deltas):
+        s = generate_generalized_integer(delta, bias)
+        result.extend(s)
+        bias = adapt(delta, points==0, baselen+points+1)
+    return "".join(result)
+
+def punycode_encode(text):
+    base, extended = segregate(text)
+    base = base.encode("ascii")
+    deltas = insertion_unsort(text, extended)
+    extended = generate_integers(len(base), deltas)
+    if base:
+        return base + "-" + extended
+    return extended
+
+##################### Decoding #####################################
+
+def decode_generalized_number(extended, extpos, bias, errors):
+    """3.3 Generalized variable-length integers"""
+    result = 0
+    w = 1
+    j = 0
+    while 1:
+        try:
+            char = ord(extended[extpos])
+        except IndexError:
+            if errors == "strict":
+                raise UnicodeError, "incomplete punicode string"
+            return extpos + 1, None
+        extpos += 1
+        if 0x41 <= char <= 0x5A: # A-Z
+            digit = char - 0x41
+        elif 0x30 <= char <= 0x39:
+            digit = char - 22 # 0x30-26
+        elif errors == "strict":
+            raise UnicodeError("Invalid extended code point '%s'"
+                               % extended[extpos])
+        else:
+            return extpos, None
+        t = T(j, bias)
+        result += digit * w
+        if digit < t:
+            return extpos, result
+        w = w * (36 - t)
+        j += 1
+
+
+def insertion_sort(base, extended, errors):
+    """3.2 Insertion unsort coding"""
+    char = 0x80
+    pos = -1
+    bias = 72
+    extpos = 0
+    while extpos < len(extended):
+        newpos, delta = decode_generalized_number(extended, extpos,
+                                                  bias, errors)
+        if delta is None:
+            # There was an error in decoding. We can't continue because
+            # synchronization is lost.
+            return base
+        pos += delta+1
+        char += pos // (len(base) + 1)
+        if char > 0x10FFFF:
+            if errors == "strict":
+                raise UnicodeError, ("Invalid character U+%x" % char)
+            char = ord('?')
+        pos = pos % (len(base) + 1)
+        base = base[:pos] + unichr(char) + base[pos:]
+        bias = adapt(delta, (extpos == 0), len(base))
+        extpos = newpos
+    return base
+
+def punycode_decode(text, errors):
+    pos = text.rfind("-")
+    if pos == -1:
+        base = ""
+        extended = text
+    else:
+        base = text[:pos]
+        extended = text[pos+1:]
+    base = unicode(base, "ascii", errors)
+    extended = extended.upper()
+    return insertion_sort(base, extended, errors)
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        res = punycode_encode(input)
+        return res, len(input)
+
+    def decode(self,input,errors='strict'):
+        if errors not in ('strict', 'replace', 'ignore'):
+            raise UnicodeError, "Unsupported error handling "+errors
+        res = punycode_decode(input, errors)
+        return res, len(input)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return punycode_encode(input)
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        if self.errors not in ('strict', 'replace', 'ignore'):
+            raise UnicodeError, "Unsupported error handling "+self.errors
+        return punycode_decode(input, self.errors)
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='punycode',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamwriter=StreamWriter,
+        streamreader=StreamReader,
+    )

Added: vendor/Python/current/Lib/encodings/quopri_codec.py
===================================================================
--- vendor/Python/current/Lib/encodings/quopri_codec.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/quopri_codec.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,74 @@
+"""Codec for quoted-printable encoding.
+
+Like base64 and rot13, this returns Python strings, not Unicode.
+"""
+
+import codecs, quopri
+try:
+    from cStringIO import StringIO
+except ImportError:
+    from StringIO import StringIO
+
+def quopri_encode(input, errors='strict'):
+    """Encode the input, returning a tuple (output object, length consumed).
+
+    errors defines the error handling to apply. It defaults to
+    'strict' handling which is the only currently supported
+    error handling for this codec.
+
+    """
+    assert errors == 'strict'
+    f = StringIO(input)
+    g = StringIO()
+    quopri.encode(f, g, 1)
+    output = g.getvalue()
+    return (output, len(input))
+
+def quopri_decode(input, errors='strict'):
+    """Decode the input, returning a tuple (output object, length consumed).
+
+    errors defines the error handling to apply. It defaults to
+    'strict' handling which is the only currently supported
+    error handling for this codec.
+
+    """
+    assert errors == 'strict'
+    f = StringIO(input)
+    g = StringIO()
+    quopri.decode(f, g)
+    output = g.getvalue()
+    return (output, len(input))
+
+class Codec(codecs.Codec):
+
+    def encode(self, input,errors='strict'):
+        return quopri_encode(input,errors)
+    def decode(self, input,errors='strict'):
+        return quopri_decode(input,errors)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return quopri_encode(input, self.errors)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return quopri_decode(input, self.errors)[0]
+
+class StreamWriter(Codec, codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+# encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='quopri',
+        encode=quopri_encode,
+        decode=quopri_decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamwriter=StreamWriter,
+        streamreader=StreamReader,
+    )

Added: vendor/Python/current/Lib/encodings/raw_unicode_escape.py
===================================================================
--- vendor/Python/current/Lib/encodings/raw_unicode_escape.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/raw_unicode_escape.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,45 @@
+""" Python 'raw-unicode-escape' Codec
+
+
+Written by Marc-Andre Lemburg (mal at lemburg.com).
+
+(c) Copyright CNRI, All Rights Reserved. NO WARRANTY.
+
+"""
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    # Note: Binding these as C functions will result in the class not
+    # converting them to methods. This is intended.
+    encode = codecs.raw_unicode_escape_encode
+    decode = codecs.raw_unicode_escape_decode
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.raw_unicode_escape_encode(input, self.errors)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.raw_unicode_escape_decode(input, self.errors)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='raw-unicode-escape',
+        encode=Codec.encode,
+        decode=Codec.decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamwriter=StreamWriter,
+        streamreader=StreamReader,
+    )

Added: vendor/Python/current/Lib/encodings/rot_13.py
===================================================================
--- vendor/Python/current/Lib/encodings/rot_13.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/rot_13.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,118 @@
+#!/usr/bin/env python
+""" Python Character Mapping Codec for ROT13.
+
+    See http://ucsub.colorado.edu/~kominek/rot13/ for details.
+
+    Written by Marc-Andre Lemburg (mal at lemburg.com).
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_map)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_map)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_map)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='rot-13',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamwriter=StreamWriter,
+        streamreader=StreamReader,
+    )
+
+### Decoding Map
+
+decoding_map = codecs.make_identity_dict(range(256))
+decoding_map.update({
+   0x0041: 0x004e,
+   0x0042: 0x004f,
+   0x0043: 0x0050,
+   0x0044: 0x0051,
+   0x0045: 0x0052,
+   0x0046: 0x0053,
+   0x0047: 0x0054,
+   0x0048: 0x0055,
+   0x0049: 0x0056,
+   0x004a: 0x0057,
+   0x004b: 0x0058,
+   0x004c: 0x0059,
+   0x004d: 0x005a,
+   0x004e: 0x0041,
+   0x004f: 0x0042,
+   0x0050: 0x0043,
+   0x0051: 0x0044,
+   0x0052: 0x0045,
+   0x0053: 0x0046,
+   0x0054: 0x0047,
+   0x0055: 0x0048,
+   0x0056: 0x0049,
+   0x0057: 0x004a,
+   0x0058: 0x004b,
+   0x0059: 0x004c,
+   0x005a: 0x004d,
+   0x0061: 0x006e,
+   0x0062: 0x006f,
+   0x0063: 0x0070,
+   0x0064: 0x0071,
+   0x0065: 0x0072,
+   0x0066: 0x0073,
+   0x0067: 0x0074,
+   0x0068: 0x0075,
+   0x0069: 0x0076,
+   0x006a: 0x0077,
+   0x006b: 0x0078,
+   0x006c: 0x0079,
+   0x006d: 0x007a,
+   0x006e: 0x0061,
+   0x006f: 0x0062,
+   0x0070: 0x0063,
+   0x0071: 0x0064,
+   0x0072: 0x0065,
+   0x0073: 0x0066,
+   0x0074: 0x0067,
+   0x0075: 0x0068,
+   0x0076: 0x0069,
+   0x0077: 0x006a,
+   0x0078: 0x006b,
+   0x0079: 0x006c,
+   0x007a: 0x006d,
+})
+
+### Encoding Map
+
+encoding_map = codecs.make_encoding_map(decoding_map)
+
+### Filter API
+
+def rot13(infile, outfile):
+    outfile.write(infile.read().encode('rot-13'))
+
+if __name__ == '__main__':
+    import sys
+    rot13(sys.stdin, sys.stdout)

Added: vendor/Python/current/Lib/encodings/shift_jis.py
===================================================================
--- vendor/Python/current/Lib/encodings/shift_jis.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/shift_jis.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,39 @@
+#
+# shift_jis.py: Python Unicode Codec for SHIFT_JIS
+#
+# Written by Hye-Shik Chang <perky at FreeBSD.org>
+#
+
+import _codecs_jp, codecs
+import _multibytecodec as mbc
+
+codec = _codecs_jp.getcodec('shift_jis')
+
+class Codec(codecs.Codec):
+    encode = codec.encode
+    decode = codec.decode
+
+class IncrementalEncoder(mbc.MultibyteIncrementalEncoder,
+                         codecs.IncrementalEncoder):
+    codec = codec
+
+class IncrementalDecoder(mbc.MultibyteIncrementalDecoder,
+                         codecs.IncrementalDecoder):
+    codec = codec
+
+class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader):
+    codec = codec
+
+class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter):
+    codec = codec
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='shift_jis',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )

Added: vendor/Python/current/Lib/encodings/shift_jis_2004.py
===================================================================
--- vendor/Python/current/Lib/encodings/shift_jis_2004.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/shift_jis_2004.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,39 @@
+#
+# shift_jis_2004.py: Python Unicode Codec for SHIFT_JIS_2004
+#
+# Written by Hye-Shik Chang <perky at FreeBSD.org>
+#
+
+import _codecs_jp, codecs
+import _multibytecodec as mbc
+
+codec = _codecs_jp.getcodec('shift_jis_2004')
+
+class Codec(codecs.Codec):
+    encode = codec.encode
+    decode = codec.decode
+
+class IncrementalEncoder(mbc.MultibyteIncrementalEncoder,
+                         codecs.IncrementalEncoder):
+    codec = codec
+
+class IncrementalDecoder(mbc.MultibyteIncrementalDecoder,
+                         codecs.IncrementalDecoder):
+    codec = codec
+
+class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader):
+    codec = codec
+
+class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter):
+    codec = codec
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='shift_jis_2004',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )

Added: vendor/Python/current/Lib/encodings/shift_jisx0213.py
===================================================================
--- vendor/Python/current/Lib/encodings/shift_jisx0213.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/shift_jisx0213.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,39 @@
+#
+# shift_jisx0213.py: Python Unicode Codec for SHIFT_JISX0213
+#
+# Written by Hye-Shik Chang <perky at FreeBSD.org>
+#
+
+import _codecs_jp, codecs
+import _multibytecodec as mbc
+
+codec = _codecs_jp.getcodec('shift_jisx0213')
+
+class Codec(codecs.Codec):
+    encode = codec.encode
+    decode = codec.decode
+
+class IncrementalEncoder(mbc.MultibyteIncrementalEncoder,
+                         codecs.IncrementalEncoder):
+    codec = codec
+
+class IncrementalDecoder(mbc.MultibyteIncrementalDecoder,
+                         codecs.IncrementalDecoder):
+    codec = codec
+
+class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader):
+    codec = codec
+
+class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter):
+    codec = codec
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='shift_jisx0213',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )

Added: vendor/Python/current/Lib/encodings/string_escape.py
===================================================================
--- vendor/Python/current/Lib/encodings/string_escape.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/string_escape.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,38 @@
+# -*- coding: iso-8859-1 -*-
+""" Python 'escape' Codec
+
+
+Written by Martin v. Löwis (martin at v.loewis.de).
+
+"""
+import codecs
+
+class Codec(codecs.Codec):
+
+    encode = codecs.escape_encode
+    decode = codecs.escape_decode
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.escape_encode(input, self.errors)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.escape_decode(input, self.errors)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='string-escape',
+        encode=Codec.encode,
+        decode=Codec.decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamwriter=StreamWriter,
+        streamreader=StreamReader,
+    )

Added: vendor/Python/current/Lib/encodings/tis_620.py
===================================================================
--- vendor/Python/current/Lib/encodings/tis_620.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/tis_620.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,307 @@
+""" Python Character Mapping Codec tis_620 generated from 'python-mappings/TIS-620.TXT' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_table)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_table)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_table)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='tis-620',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+
+
+### Decoding Table
+
+decoding_table = (
+    u'\x00'     #  0x00 -> NULL
+    u'\x01'     #  0x01 -> START OF HEADING
+    u'\x02'     #  0x02 -> START OF TEXT
+    u'\x03'     #  0x03 -> END OF TEXT
+    u'\x04'     #  0x04 -> END OF TRANSMISSION
+    u'\x05'     #  0x05 -> ENQUIRY
+    u'\x06'     #  0x06 -> ACKNOWLEDGE
+    u'\x07'     #  0x07 -> BELL
+    u'\x08'     #  0x08 -> BACKSPACE
+    u'\t'       #  0x09 -> HORIZONTAL TABULATION
+    u'\n'       #  0x0A -> LINE FEED
+    u'\x0b'     #  0x0B -> VERTICAL TABULATION
+    u'\x0c'     #  0x0C -> FORM FEED
+    u'\r'       #  0x0D -> CARRIAGE RETURN
+    u'\x0e'     #  0x0E -> SHIFT OUT
+    u'\x0f'     #  0x0F -> SHIFT IN
+    u'\x10'     #  0x10 -> DATA LINK ESCAPE
+    u'\x11'     #  0x11 -> DEVICE CONTROL ONE
+    u'\x12'     #  0x12 -> DEVICE CONTROL TWO
+    u'\x13'     #  0x13 -> DEVICE CONTROL THREE
+    u'\x14'     #  0x14 -> DEVICE CONTROL FOUR
+    u'\x15'     #  0x15 -> NEGATIVE ACKNOWLEDGE
+    u'\x16'     #  0x16 -> SYNCHRONOUS IDLE
+    u'\x17'     #  0x17 -> END OF TRANSMISSION BLOCK
+    u'\x18'     #  0x18 -> CANCEL
+    u'\x19'     #  0x19 -> END OF MEDIUM
+    u'\x1a'     #  0x1A -> SUBSTITUTE
+    u'\x1b'     #  0x1B -> ESCAPE
+    u'\x1c'     #  0x1C -> FILE SEPARATOR
+    u'\x1d'     #  0x1D -> GROUP SEPARATOR
+    u'\x1e'     #  0x1E -> RECORD SEPARATOR
+    u'\x1f'     #  0x1F -> UNIT SEPARATOR
+    u' '        #  0x20 -> SPACE
+    u'!'        #  0x21 -> EXCLAMATION MARK
+    u'"'        #  0x22 -> QUOTATION MARK
+    u'#'        #  0x23 -> NUMBER SIGN
+    u'$'        #  0x24 -> DOLLAR SIGN
+    u'%'        #  0x25 -> PERCENT SIGN
+    u'&'        #  0x26 -> AMPERSAND
+    u"'"        #  0x27 -> APOSTROPHE
+    u'('        #  0x28 -> LEFT PARENTHESIS
+    u')'        #  0x29 -> RIGHT PARENTHESIS
+    u'*'        #  0x2A -> ASTERISK
+    u'+'        #  0x2B -> PLUS SIGN
+    u','        #  0x2C -> COMMA
+    u'-'        #  0x2D -> HYPHEN-MINUS
+    u'.'        #  0x2E -> FULL STOP
+    u'/'        #  0x2F -> SOLIDUS
+    u'0'        #  0x30 -> DIGIT ZERO
+    u'1'        #  0x31 -> DIGIT ONE
+    u'2'        #  0x32 -> DIGIT TWO
+    u'3'        #  0x33 -> DIGIT THREE
+    u'4'        #  0x34 -> DIGIT FOUR
+    u'5'        #  0x35 -> DIGIT FIVE
+    u'6'        #  0x36 -> DIGIT SIX
+    u'7'        #  0x37 -> DIGIT SEVEN
+    u'8'        #  0x38 -> DIGIT EIGHT
+    u'9'        #  0x39 -> DIGIT NINE
+    u':'        #  0x3A -> COLON
+    u';'        #  0x3B -> SEMICOLON
+    u'<'        #  0x3C -> LESS-THAN SIGN
+    u'='        #  0x3D -> EQUALS SIGN
+    u'>'        #  0x3E -> GREATER-THAN SIGN
+    u'?'        #  0x3F -> QUESTION MARK
+    u'@'        #  0x40 -> COMMERCIAL AT
+    u'A'        #  0x41 -> LATIN CAPITAL LETTER A
+    u'B'        #  0x42 -> LATIN CAPITAL LETTER B
+    u'C'        #  0x43 -> LATIN CAPITAL LETTER C
+    u'D'        #  0x44 -> LATIN CAPITAL LETTER D
+    u'E'        #  0x45 -> LATIN CAPITAL LETTER E
+    u'F'        #  0x46 -> LATIN CAPITAL LETTER F
+    u'G'        #  0x47 -> LATIN CAPITAL LETTER G
+    u'H'        #  0x48 -> LATIN CAPITAL LETTER H
+    u'I'        #  0x49 -> LATIN CAPITAL LETTER I
+    u'J'        #  0x4A -> LATIN CAPITAL LETTER J
+    u'K'        #  0x4B -> LATIN CAPITAL LETTER K
+    u'L'        #  0x4C -> LATIN CAPITAL LETTER L
+    u'M'        #  0x4D -> LATIN CAPITAL LETTER M
+    u'N'        #  0x4E -> LATIN CAPITAL LETTER N
+    u'O'        #  0x4F -> LATIN CAPITAL LETTER O
+    u'P'        #  0x50 -> LATIN CAPITAL LETTER P
+    u'Q'        #  0x51 -> LATIN CAPITAL LETTER Q
+    u'R'        #  0x52 -> LATIN CAPITAL LETTER R
+    u'S'        #  0x53 -> LATIN CAPITAL LETTER S
+    u'T'        #  0x54 -> LATIN CAPITAL LETTER T
+    u'U'        #  0x55 -> LATIN CAPITAL LETTER U
+    u'V'        #  0x56 -> LATIN CAPITAL LETTER V
+    u'W'        #  0x57 -> LATIN CAPITAL LETTER W
+    u'X'        #  0x58 -> LATIN CAPITAL LETTER X
+    u'Y'        #  0x59 -> LATIN CAPITAL LETTER Y
+    u'Z'        #  0x5A -> LATIN CAPITAL LETTER Z
+    u'['        #  0x5B -> LEFT SQUARE BRACKET
+    u'\\'       #  0x5C -> REVERSE SOLIDUS
+    u']'        #  0x5D -> RIGHT SQUARE BRACKET
+    u'^'        #  0x5E -> CIRCUMFLEX ACCENT
+    u'_'        #  0x5F -> LOW LINE
+    u'`'        #  0x60 -> GRAVE ACCENT
+    u'a'        #  0x61 -> LATIN SMALL LETTER A
+    u'b'        #  0x62 -> LATIN SMALL LETTER B
+    u'c'        #  0x63 -> LATIN SMALL LETTER C
+    u'd'        #  0x64 -> LATIN SMALL LETTER D
+    u'e'        #  0x65 -> LATIN SMALL LETTER E
+    u'f'        #  0x66 -> LATIN SMALL LETTER F
+    u'g'        #  0x67 -> LATIN SMALL LETTER G
+    u'h'        #  0x68 -> LATIN SMALL LETTER H
+    u'i'        #  0x69 -> LATIN SMALL LETTER I
+    u'j'        #  0x6A -> LATIN SMALL LETTER J
+    u'k'        #  0x6B -> LATIN SMALL LETTER K
+    u'l'        #  0x6C -> LATIN SMALL LETTER L
+    u'm'        #  0x6D -> LATIN SMALL LETTER M
+    u'n'        #  0x6E -> LATIN SMALL LETTER N
+    u'o'        #  0x6F -> LATIN SMALL LETTER O
+    u'p'        #  0x70 -> LATIN SMALL LETTER P
+    u'q'        #  0x71 -> LATIN SMALL LETTER Q
+    u'r'        #  0x72 -> LATIN SMALL LETTER R
+    u's'        #  0x73 -> LATIN SMALL LETTER S
+    u't'        #  0x74 -> LATIN SMALL LETTER T
+    u'u'        #  0x75 -> LATIN SMALL LETTER U
+    u'v'        #  0x76 -> LATIN SMALL LETTER V
+    u'w'        #  0x77 -> LATIN SMALL LETTER W
+    u'x'        #  0x78 -> LATIN SMALL LETTER X
+    u'y'        #  0x79 -> LATIN SMALL LETTER Y
+    u'z'        #  0x7A -> LATIN SMALL LETTER Z
+    u'{'        #  0x7B -> LEFT CURLY BRACKET
+    u'|'        #  0x7C -> VERTICAL LINE
+    u'}'        #  0x7D -> RIGHT CURLY BRACKET
+    u'~'        #  0x7E -> TILDE
+    u'\x7f'     #  0x7F -> DELETE
+    u'\x80'     #  0x80 -> <control>
+    u'\x81'     #  0x81 -> <control>
+    u'\x82'     #  0x82 -> <control>
+    u'\x83'     #  0x83 -> <control>
+    u'\x84'     #  0x84 -> <control>
+    u'\x85'     #  0x85 -> <control>
+    u'\x86'     #  0x86 -> <control>
+    u'\x87'     #  0x87 -> <control>
+    u'\x88'     #  0x88 -> <control>
+    u'\x89'     #  0x89 -> <control>
+    u'\x8a'     #  0x8A -> <control>
+    u'\x8b'     #  0x8B -> <control>
+    u'\x8c'     #  0x8C -> <control>
+    u'\x8d'     #  0x8D -> <control>
+    u'\x8e'     #  0x8E -> <control>
+    u'\x8f'     #  0x8F -> <control>
+    u'\x90'     #  0x90 -> <control>
+    u'\x91'     #  0x91 -> <control>
+    u'\x92'     #  0x92 -> <control>
+    u'\x93'     #  0x93 -> <control>
+    u'\x94'     #  0x94 -> <control>
+    u'\x95'     #  0x95 -> <control>
+    u'\x96'     #  0x96 -> <control>
+    u'\x97'     #  0x97 -> <control>
+    u'\x98'     #  0x98 -> <control>
+    u'\x99'     #  0x99 -> <control>
+    u'\x9a'     #  0x9A -> <control>
+    u'\x9b'     #  0x9B -> <control>
+    u'\x9c'     #  0x9C -> <control>
+    u'\x9d'     #  0x9D -> <control>
+    u'\x9e'     #  0x9E -> <control>
+    u'\x9f'     #  0x9F -> <control>
+    u'\ufffe'
+    u'\u0e01'   #  0xA1 -> THAI CHARACTER KO KAI
+    u'\u0e02'   #  0xA2 -> THAI CHARACTER KHO KHAI
+    u'\u0e03'   #  0xA3 -> THAI CHARACTER KHO KHUAT
+    u'\u0e04'   #  0xA4 -> THAI CHARACTER KHO KHWAI
+    u'\u0e05'   #  0xA5 -> THAI CHARACTER KHO KHON
+    u'\u0e06'   #  0xA6 -> THAI CHARACTER KHO RAKHANG
+    u'\u0e07'   #  0xA7 -> THAI CHARACTER NGO NGU
+    u'\u0e08'   #  0xA8 -> THAI CHARACTER CHO CHAN
+    u'\u0e09'   #  0xA9 -> THAI CHARACTER CHO CHING
+    u'\u0e0a'   #  0xAA -> THAI CHARACTER CHO CHANG
+    u'\u0e0b'   #  0xAB -> THAI CHARACTER SO SO
+    u'\u0e0c'   #  0xAC -> THAI CHARACTER CHO CHOE
+    u'\u0e0d'   #  0xAD -> THAI CHARACTER YO YING
+    u'\u0e0e'   #  0xAE -> THAI CHARACTER DO CHADA
+    u'\u0e0f'   #  0xAF -> THAI CHARACTER TO PATAK
+    u'\u0e10'   #  0xB0 -> THAI CHARACTER THO THAN
+    u'\u0e11'   #  0xB1 -> THAI CHARACTER THO NANGMONTHO
+    u'\u0e12'   #  0xB2 -> THAI CHARACTER THO PHUTHAO
+    u'\u0e13'   #  0xB3 -> THAI CHARACTER NO NEN
+    u'\u0e14'   #  0xB4 -> THAI CHARACTER DO DEK
+    u'\u0e15'   #  0xB5 -> THAI CHARACTER TO TAO
+    u'\u0e16'   #  0xB6 -> THAI CHARACTER THO THUNG
+    u'\u0e17'   #  0xB7 -> THAI CHARACTER THO THAHAN
+    u'\u0e18'   #  0xB8 -> THAI CHARACTER THO THONG
+    u'\u0e19'   #  0xB9 -> THAI CHARACTER NO NU
+    u'\u0e1a'   #  0xBA -> THAI CHARACTER BO BAIMAI
+    u'\u0e1b'   #  0xBB -> THAI CHARACTER PO PLA
+    u'\u0e1c'   #  0xBC -> THAI CHARACTER PHO PHUNG
+    u'\u0e1d'   #  0xBD -> THAI CHARACTER FO FA
+    u'\u0e1e'   #  0xBE -> THAI CHARACTER PHO PHAN
+    u'\u0e1f'   #  0xBF -> THAI CHARACTER FO FAN
+    u'\u0e20'   #  0xC0 -> THAI CHARACTER PHO SAMPHAO
+    u'\u0e21'   #  0xC1 -> THAI CHARACTER MO MA
+    u'\u0e22'   #  0xC2 -> THAI CHARACTER YO YAK
+    u'\u0e23'   #  0xC3 -> THAI CHARACTER RO RUA
+    u'\u0e24'   #  0xC4 -> THAI CHARACTER RU
+    u'\u0e25'   #  0xC5 -> THAI CHARACTER LO LING
+    u'\u0e26'   #  0xC6 -> THAI CHARACTER LU
+    u'\u0e27'   #  0xC7 -> THAI CHARACTER WO WAEN
+    u'\u0e28'   #  0xC8 -> THAI CHARACTER SO SALA
+    u'\u0e29'   #  0xC9 -> THAI CHARACTER SO RUSI
+    u'\u0e2a'   #  0xCA -> THAI CHARACTER SO SUA
+    u'\u0e2b'   #  0xCB -> THAI CHARACTER HO HIP
+    u'\u0e2c'   #  0xCC -> THAI CHARACTER LO CHULA
+    u'\u0e2d'   #  0xCD -> THAI CHARACTER O ANG
+    u'\u0e2e'   #  0xCE -> THAI CHARACTER HO NOKHUK
+    u'\u0e2f'   #  0xCF -> THAI CHARACTER PAIYANNOI
+    u'\u0e30'   #  0xD0 -> THAI CHARACTER SARA A
+    u'\u0e31'   #  0xD1 -> THAI CHARACTER MAI HAN-AKAT
+    u'\u0e32'   #  0xD2 -> THAI CHARACTER SARA AA
+    u'\u0e33'   #  0xD3 -> THAI CHARACTER SARA AM
+    u'\u0e34'   #  0xD4 -> THAI CHARACTER SARA I
+    u'\u0e35'   #  0xD5 -> THAI CHARACTER SARA II
+    u'\u0e36'   #  0xD6 -> THAI CHARACTER SARA UE
+    u'\u0e37'   #  0xD7 -> THAI CHARACTER SARA UEE
+    u'\u0e38'   #  0xD8 -> THAI CHARACTER SARA U
+    u'\u0e39'   #  0xD9 -> THAI CHARACTER SARA UU
+    u'\u0e3a'   #  0xDA -> THAI CHARACTER PHINTHU
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\u0e3f'   #  0xDF -> THAI CURRENCY SYMBOL BAHT
+    u'\u0e40'   #  0xE0 -> THAI CHARACTER SARA E
+    u'\u0e41'   #  0xE1 -> THAI CHARACTER SARA AE
+    u'\u0e42'   #  0xE2 -> THAI CHARACTER SARA O
+    u'\u0e43'   #  0xE3 -> THAI CHARACTER SARA AI MAIMUAN
+    u'\u0e44'   #  0xE4 -> THAI CHARACTER SARA AI MAIMALAI
+    u'\u0e45'   #  0xE5 -> THAI CHARACTER LAKKHANGYAO
+    u'\u0e46'   #  0xE6 -> THAI CHARACTER MAIYAMOK
+    u'\u0e47'   #  0xE7 -> THAI CHARACTER MAITAIKHU
+    u'\u0e48'   #  0xE8 -> THAI CHARACTER MAI EK
+    u'\u0e49'   #  0xE9 -> THAI CHARACTER MAI THO
+    u'\u0e4a'   #  0xEA -> THAI CHARACTER MAI TRI
+    u'\u0e4b'   #  0xEB -> THAI CHARACTER MAI CHATTAWA
+    u'\u0e4c'   #  0xEC -> THAI CHARACTER THANTHAKHAT
+    u'\u0e4d'   #  0xED -> THAI CHARACTER NIKHAHIT
+    u'\u0e4e'   #  0xEE -> THAI CHARACTER YAMAKKAN
+    u'\u0e4f'   #  0xEF -> THAI CHARACTER FONGMAN
+    u'\u0e50'   #  0xF0 -> THAI DIGIT ZERO
+    u'\u0e51'   #  0xF1 -> THAI DIGIT ONE
+    u'\u0e52'   #  0xF2 -> THAI DIGIT TWO
+    u'\u0e53'   #  0xF3 -> THAI DIGIT THREE
+    u'\u0e54'   #  0xF4 -> THAI DIGIT FOUR
+    u'\u0e55'   #  0xF5 -> THAI DIGIT FIVE
+    u'\u0e56'   #  0xF6 -> THAI DIGIT SIX
+    u'\u0e57'   #  0xF7 -> THAI DIGIT SEVEN
+    u'\u0e58'   #  0xF8 -> THAI DIGIT EIGHT
+    u'\u0e59'   #  0xF9 -> THAI DIGIT NINE
+    u'\u0e5a'   #  0xFA -> THAI CHARACTER ANGKHANKHU
+    u'\u0e5b'   #  0xFB -> THAI CHARACTER KHOMUT
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+    u'\ufffe'
+)
+
+### Encoding table
+encoding_table=codecs.charmap_build(decoding_table)

Added: vendor/Python/current/Lib/encodings/undefined.py
===================================================================
--- vendor/Python/current/Lib/encodings/undefined.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/undefined.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,49 @@
+""" Python 'undefined' Codec
+
+    This codec will always raise a ValueError exception when being
+    used. It is intended for use by the site.py file to switch off
+    automatic string to Unicode coercion.
+
+Written by Marc-Andre Lemburg (mal at lemburg.com).
+
+(c) Copyright CNRI, All Rights Reserved. NO WARRANTY.
+
+"""
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        raise UnicodeError("undefined encoding")
+
+    def decode(self,input,errors='strict'):
+        raise UnicodeError("undefined encoding")
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        raise UnicodeError("undefined encoding")
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        raise UnicodeError("undefined encoding")
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='undefined',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamwriter=StreamWriter,
+        streamreader=StreamReader,
+    )

Added: vendor/Python/current/Lib/encodings/unicode_escape.py
===================================================================
--- vendor/Python/current/Lib/encodings/unicode_escape.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/unicode_escape.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,45 @@
+""" Python 'unicode-escape' Codec
+
+
+Written by Marc-Andre Lemburg (mal at lemburg.com).
+
+(c) Copyright CNRI, All Rights Reserved. NO WARRANTY.
+
+"""
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    # Note: Binding these as C functions will result in the class not
+    # converting them to methods. This is intended.
+    encode = codecs.unicode_escape_encode
+    decode = codecs.unicode_escape_decode
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.unicode_escape_encode(input, self.errors)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.unicode_escape_decode(input, self.errors)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='unicode-escape',
+        encode=Codec.encode,
+        decode=Codec.decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamwriter=StreamWriter,
+        streamreader=StreamReader,
+    )

Added: vendor/Python/current/Lib/encodings/unicode_internal.py
===================================================================
--- vendor/Python/current/Lib/encodings/unicode_internal.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/unicode_internal.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,45 @@
+""" Python 'unicode-internal' Codec
+
+
+Written by Marc-Andre Lemburg (mal at lemburg.com).
+
+(c) Copyright CNRI, All Rights Reserved. NO WARRANTY.
+
+"""
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    # Note: Binding these as C functions will result in the class not
+    # converting them to methods. This is intended.
+    encode = codecs.unicode_internal_encode
+    decode = codecs.unicode_internal_decode
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.unicode_internal_encode(input, self.errors)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.unicode_internal_decode(input, self.errors)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='unicode-internal',
+        encode=Codec.encode,
+        decode=Codec.decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamwriter=StreamWriter,
+        streamreader=StreamReader,
+    )

Added: vendor/Python/current/Lib/encodings/utf_16.py
===================================================================
--- vendor/Python/current/Lib/encodings/utf_16.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/utf_16.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,104 @@
+""" Python 'utf-16' Codec
+
+
+Written by Marc-Andre Lemburg (mal at lemburg.com).
+
+(c) Copyright CNRI, All Rights Reserved. NO WARRANTY.
+
+"""
+import codecs, sys
+
+### Codec APIs
+
+encode = codecs.utf_16_encode
+
+def decode(input, errors='strict'):
+    return codecs.utf_16_decode(input, errors, True)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def __init__(self, errors='strict'):
+        codecs.IncrementalEncoder.__init__(self, errors)
+        self.encoder = None
+
+    def encode(self, input, final=False):
+        if self.encoder is None:
+            result = codecs.utf_16_encode(input, self.errors)[0]
+            if sys.byteorder == 'little':
+                self.encoder = codecs.utf_16_le_encode
+            else:
+                self.encoder = codecs.utf_16_be_encode
+            return result
+        return self.encoder(input, self.errors)[0]
+
+    def reset(self):
+        codecs.IncrementalEncoder.reset(self)
+        self.encoder = None
+
+class IncrementalDecoder(codecs.BufferedIncrementalDecoder):
+    def __init__(self, errors='strict'):
+        codecs.BufferedIncrementalDecoder.__init__(self, errors)
+        self.decoder = None
+
+    def _buffer_decode(self, input, errors, final):
+        if self.decoder is None:
+            (output, consumed, byteorder) = \
+                codecs.utf_16_ex_decode(input, errors, 0, final)
+            if byteorder == -1:
+                self.decoder = codecs.utf_16_le_decode
+            elif byteorder == 1:
+                self.decoder = codecs.utf_16_be_decode
+            elif consumed >= 2:
+                raise UnicodeError("UTF-16 stream does not start with BOM")
+            return (output, consumed)
+        return self.decoder(input, self.errors, final)
+
+    def reset(self):
+        codecs.BufferedIncrementalDecoder.reset(self)
+        self.decoder = None
+
+class StreamWriter(codecs.StreamWriter):
+    def __init__(self, stream, errors='strict'):
+        self.bom_written = False
+        codecs.StreamWriter.__init__(self, stream, errors)
+
+    def encode(self, input, errors='strict'):
+        self.bom_written = True
+        result = codecs.utf_16_encode(input, errors)
+        if sys.byteorder == 'little':
+            self.encode = codecs.utf_16_le_encode
+        else:
+            self.encode = codecs.utf_16_be_encode
+        return result
+
+class StreamReader(codecs.StreamReader):
+
+    def reset(self):
+        codecs.StreamReader.reset(self)
+        try:
+            del self.decode
+        except AttributeError:
+            pass
+
+    def decode(self, input, errors='strict'):
+        (object, consumed, byteorder) = \
+            codecs.utf_16_ex_decode(input, errors, 0, False)
+        if byteorder == -1:
+            self.decode = codecs.utf_16_le_decode
+        elif byteorder == 1:
+            self.decode = codecs.utf_16_be_decode
+        elif consumed>=2:
+            raise UnicodeError,"UTF-16 stream does not start with BOM"
+        return (object, consumed)
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='utf-16',
+        encode=encode,
+        decode=decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )

Added: vendor/Python/current/Lib/encodings/utf_16_be.py
===================================================================
--- vendor/Python/current/Lib/encodings/utf_16_be.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/utf_16_be.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,42 @@
+""" Python 'utf-16-be' Codec
+
+
+Written by Marc-Andre Lemburg (mal at lemburg.com).
+
+(c) Copyright CNRI, All Rights Reserved. NO WARRANTY.
+
+"""
+import codecs
+
+### Codec APIs
+
+encode = codecs.utf_16_be_encode
+
+def decode(input, errors='strict'):
+    return codecs.utf_16_be_decode(input, errors, True)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.utf_16_be_encode(input, self.errors)[0]
+
+class IncrementalDecoder(codecs.BufferedIncrementalDecoder):
+    _buffer_decode = codecs.utf_16_be_decode
+
+class StreamWriter(codecs.StreamWriter):
+    encode = codecs.utf_16_be_encode
+
+class StreamReader(codecs.StreamReader):
+    decode = codecs.utf_16_be_decode
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='utf-16-be',
+        encode=encode,
+        decode=decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )

Added: vendor/Python/current/Lib/encodings/utf_16_le.py
===================================================================
--- vendor/Python/current/Lib/encodings/utf_16_le.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/utf_16_le.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,42 @@
+""" Python 'utf-16-le' Codec
+
+
+Written by Marc-Andre Lemburg (mal at lemburg.com).
+
+(c) Copyright CNRI, All Rights Reserved. NO WARRANTY.
+
+"""
+import codecs
+
+### Codec APIs
+
+encode = codecs.utf_16_le_encode
+
+def decode(input, errors='strict'):
+    return codecs.utf_16_le_decode(input, errors, True)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.utf_16_le_encode(input, self.errors)[0]
+
+class IncrementalDecoder(codecs.BufferedIncrementalDecoder):
+    _buffer_decode = codecs.utf_16_le_decode
+
+class StreamWriter(codecs.StreamWriter):
+    encode = codecs.utf_16_le_encode
+
+class StreamReader(codecs.StreamReader):
+    decode = codecs.utf_16_le_decode
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='utf-16-le',
+        encode=encode,
+        decode=decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )

Added: vendor/Python/current/Lib/encodings/utf_7.py
===================================================================
--- vendor/Python/current/Lib/encodings/utf_7.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/utf_7.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,41 @@
+""" Python 'utf-7' Codec
+
+Written by Brian Quinlan (brian at sweetapp.com).
+"""
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    # Note: Binding these as C functions will result in the class not
+    # converting them to methods. This is intended.
+    encode = codecs.utf_7_encode
+    decode = codecs.utf_7_decode
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.utf_7_encode(input, self.errors)[0]
+
+class IncrementalDecoder(codecs.BufferedIncrementalDecoder):
+    def _buffer_decode(self, input, errors, final):
+        return codecs.utf_7_decode(input, self.errors)
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='utf-7',
+        encode=Codec.encode,
+        decode=Codec.decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )

Added: vendor/Python/current/Lib/encodings/utf_8.py
===================================================================
--- vendor/Python/current/Lib/encodings/utf_8.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/utf_8.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,42 @@
+""" Python 'utf-8' Codec
+
+
+Written by Marc-Andre Lemburg (mal at lemburg.com).
+
+(c) Copyright CNRI, All Rights Reserved. NO WARRANTY.
+
+"""
+import codecs
+
+### Codec APIs
+
+encode = codecs.utf_8_encode
+
+def decode(input, errors='strict'):
+    return codecs.utf_8_decode(input, errors, True)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.utf_8_encode(input, self.errors)[0]
+
+class IncrementalDecoder(codecs.BufferedIncrementalDecoder):
+    _buffer_decode = codecs.utf_8_decode
+
+class StreamWriter(codecs.StreamWriter):
+    encode = codecs.utf_8_encode
+
+class StreamReader(codecs.StreamReader):
+    decode = codecs.utf_8_decode
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='utf-8',
+        encode=encode,
+        decode=decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )

Added: vendor/Python/current/Lib/encodings/utf_8_sig.py
===================================================================
--- vendor/Python/current/Lib/encodings/utf_8_sig.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/utf_8_sig.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,100 @@
+""" Python 'utf-8-sig' Codec
+This work similar to UTF-8 with the following changes:
+
+* On encoding/writing a UTF-8 encoded BOM will be prepended/written as the
+  first three bytes.
+
+* On decoding/reading if the first three bytes are a UTF-8 encoded BOM, these
+  bytes will be skipped.
+"""
+import codecs
+
+### Codec APIs
+
+def encode(input, errors='strict'):
+    return (codecs.BOM_UTF8 + codecs.utf_8_encode(input, errors)[0], len(input))
+
+def decode(input, errors='strict'):
+    prefix = 0
+    if input[:3] == codecs.BOM_UTF8:
+        input = input[3:]
+        prefix = 3
+    (output, consumed) = codecs.utf_8_decode(input, errors, True)
+    return (output, consumed+prefix)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def __init__(self, errors='strict'):
+        codecs.IncrementalEncoder.__init__(self, errors)
+        self.first = True
+
+    def encode(self, input, final=False):
+        if self.first:
+            self.first = False
+            return codecs.BOM_UTF8 + codecs.utf_8_encode(input, self.errors)[0]
+        else:
+            return codecs.utf_8_encode(input, self.errors)[0]
+
+    def reset(self):
+        codecs.IncrementalEncoder.reset(self)
+        self.first = True
+
+class IncrementalDecoder(codecs.BufferedIncrementalDecoder):
+    def __init__(self, errors='strict'):
+        codecs.BufferedIncrementalDecoder.__init__(self, errors)
+        self.first = True
+
+    def _buffer_decode(self, input, errors, final):
+        if self.first and codecs.BOM_UTF8.startswith(input): # might be a BOM
+            if len(input) < 3:
+                # not enough data to decide if this really is a BOM
+                # => try again on the next call
+                return (u"", 0)
+            (output, consumed) = codecs.utf_8_decode(input[3:], errors, final)
+            self.first = False
+            return (output, consumed+3)
+        return codecs.utf_8_decode(input, errors, final)
+
+    def reset(self):
+        codecs.BufferedIncrementalDecoder.reset(self)
+        self.first = True
+
+class StreamWriter(codecs.StreamWriter):
+    def reset(self):
+        codecs.StreamWriter.reset(self)
+        try:
+            del self.encode
+        except AttributeError:
+            pass
+
+    def encode(self, input, errors='strict'):
+        self.encode = codecs.utf_8_encode
+        return encode(input, errors)
+
+class StreamReader(codecs.StreamReader):
+    def reset(self):
+        codecs.StreamReader.reset(self)
+        try:
+            del self.decode
+        except AttributeError:
+            pass
+
+    def decode(self, input, errors='strict'):
+        if len(input) < 3 and codecs.BOM_UTF8.startswith(input):
+            # not enough data to decide if this is a BOM
+            # => try again on the next call
+            return (u"", 0)
+        self.decode = codecs.utf_8_decode
+        return decode(input, errors)
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='utf-8-sig',
+        encode=encode,
+        decode=decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )

Added: vendor/Python/current/Lib/encodings/uu_codec.py
===================================================================
--- vendor/Python/current/Lib/encodings/uu_codec.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/uu_codec.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,128 @@
+""" Python 'uu_codec' Codec - UU content transfer encoding
+
+    Unlike most of the other codecs which target Unicode, this codec
+    will return Python string objects for both encode and decode.
+
+    Written by Marc-Andre Lemburg (mal at lemburg.com). Some details were
+    adapted from uu.py which was written by Lance Ellinghouse and
+    modified by Jack Jansen and Fredrik Lundh.
+
+"""
+import codecs, binascii
+
+### Codec APIs
+
+def uu_encode(input,errors='strict',filename='<data>',mode=0666):
+
+    """ Encodes the object input and returns a tuple (output
+        object, length consumed).
+
+        errors defines the error handling to apply. It defaults to
+        'strict' handling which is the only currently supported
+        error handling for this codec.
+
+    """
+    assert errors == 'strict'
+    from cStringIO import StringIO
+    from binascii import b2a_uu
+    infile = StringIO(input)
+    outfile = StringIO()
+    read = infile.read
+    write = outfile.write
+
+    # Encode
+    write('begin %o %s\n' % (mode & 0777, filename))
+    chunk = read(45)
+    while chunk:
+        write(b2a_uu(chunk))
+        chunk = read(45)
+    write(' \nend\n')
+
+    return (outfile.getvalue(), len(input))
+
+def uu_decode(input,errors='strict'):
+
+    """ Decodes the object input and returns a tuple (output
+        object, length consumed).
+
+        input must be an object which provides the bf_getreadbuf
+        buffer slot. Python strings, buffer objects and memory
+        mapped files are examples of objects providing this slot.
+
+        errors defines the error handling to apply. It defaults to
+        'strict' handling which is the only currently supported
+        error handling for this codec.
+
+        Note: filename and file mode information in the input data is
+        ignored.
+
+    """
+    assert errors == 'strict'
+    from cStringIO import StringIO
+    from binascii import a2b_uu
+    infile = StringIO(input)
+    outfile = StringIO()
+    readline = infile.readline
+    write = outfile.write
+
+    # Find start of encoded data
+    while 1:
+        s = readline()
+        if not s:
+            raise ValueError, 'Missing "begin" line in input data'
+        if s[:5] == 'begin':
+            break
+
+    # Decode
+    while 1:
+        s = readline()
+        if not s or \
+           s == 'end\n':
+            break
+        try:
+            data = a2b_uu(s)
+        except binascii.Error, v:
+            # Workaround for broken uuencoders by /Fredrik Lundh
+            nbytes = (((ord(s[0])-32) & 63) * 4 + 5) / 3
+            data = a2b_uu(s[:nbytes])
+            #sys.stderr.write("Warning: %s\n" % str(v))
+        write(data)
+    if not s:
+        raise ValueError, 'Truncated input data'
+
+    return (outfile.getvalue(), len(input))
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return uu_encode(input,errors)
+
+    def decode(self,input,errors='strict'):
+        return uu_decode(input,errors)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return uu_encode(input, self.errors)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return uu_decode(input, self.errors)[0]
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='uu',
+        encode=uu_encode,
+        decode=uu_decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )

Added: vendor/Python/current/Lib/encodings/zlib_codec.py
===================================================================
--- vendor/Python/current/Lib/encodings/zlib_codec.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/encodings/zlib_codec.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,102 @@
+""" Python 'zlib_codec' Codec - zlib compression encoding
+
+    Unlike most of the other codecs which target Unicode, this codec
+    will return Python string objects for both encode and decode.
+
+    Written by Marc-Andre Lemburg (mal at lemburg.com).
+
+"""
+import codecs
+import zlib # this codec needs the optional zlib module !
+
+### Codec APIs
+
+def zlib_encode(input,errors='strict'):
+
+    """ Encodes the object input and returns a tuple (output
+        object, length consumed).
+
+        errors defines the error handling to apply. It defaults to
+        'strict' handling which is the only currently supported
+        error handling for this codec.
+
+    """
+    assert errors == 'strict'
+    output = zlib.compress(input)
+    return (output, len(input))
+
+def zlib_decode(input,errors='strict'):
+
+    """ Decodes the object input and returns a tuple (output
+        object, length consumed).
+
+        input must be an object which provides the bf_getreadbuf
+        buffer slot. Python strings, buffer objects and memory
+        mapped files are examples of objects providing this slot.
+
+        errors defines the error handling to apply. It defaults to
+        'strict' handling which is the only currently supported
+        error handling for this codec.
+
+    """
+    assert errors == 'strict'
+    output = zlib.decompress(input)
+    return (output, len(input))
+
+class Codec(codecs.Codec):
+
+    def encode(self, input, errors='strict'):
+        return zlib_encode(input, errors)
+    def decode(self, input, errors='strict'):
+        return zlib_decode(input, errors)
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def __init__(self, errors='strict'):
+        assert errors == 'strict'
+        self.errors = errors
+        self.compressobj = zlib.compressobj()
+
+    def encode(self, input, final=False):
+        if final:
+            c = self.compressobj.compress(input)
+            return c + self.compressobj.flush()
+        else:
+            return self.compressobj.compress(input)
+
+    def reset(self):
+        self.compressobj = zlib.compressobj()
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def __init__(self, errors='strict'):
+        assert errors == 'strict'
+        self.errors = errors
+        self.decompressobj = zlib.decompressobj()
+
+    def decode(self, input, final=False):
+        if final:
+            c = self.decompressobj.decompress(input)
+            return c + self.decompressobj.flush()
+        else:
+            return self.decompressobj.decompress(input)
+
+    def reset(self):
+        self.decompressobj = zlib.decompressobj()
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='zlib',
+        encode=zlib_encode,
+        decode=zlib_decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )

Added: vendor/Python/current/Lib/filecmp.py
===================================================================
--- vendor/Python/current/Lib/filecmp.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/filecmp.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,297 @@
+"""Utilities for comparing files and directories.
+
+Classes:
+    dircmp
+
+Functions:
+    cmp(f1, f2, shallow=1) -> int
+    cmpfiles(a, b, common) -> ([], [], [])
+
+"""
+
+import os
+import stat
+import warnings
+from itertools import ifilter, ifilterfalse, imap, izip
+
+__all__ = ["cmp","dircmp","cmpfiles"]
+
+_cache = {}
+BUFSIZE=8*1024
+
+def cmp(f1, f2, shallow=1):
+    """Compare two files.
+
+    Arguments:
+
+    f1 -- First file name
+
+    f2 -- Second file name
+
+    shallow -- Just check stat signature (do not read the files).
+               defaults to 1.
+
+    Return value:
+
+    True if the files are the same, False otherwise.
+
+    This function uses a cache for past comparisons and the results,
+    with a cache invalidation mechanism relying on stale signatures.
+
+    """
+
+    s1 = _sig(os.stat(f1))
+    s2 = _sig(os.stat(f2))
+    if s1[0] != stat.S_IFREG or s2[0] != stat.S_IFREG:
+        return False
+    if shallow and s1 == s2:
+        return True
+    if s1[1] != s2[1]:
+        return False
+
+    result = _cache.get((f1, f2))
+    if result and (s1, s2) == result[:2]:
+        return result[2]
+    outcome = _do_cmp(f1, f2)
+    _cache[f1, f2] = s1, s2, outcome
+    return outcome
+
+def _sig(st):
+    return (stat.S_IFMT(st.st_mode),
+            st.st_size,
+            st.st_mtime)
+
+def _do_cmp(f1, f2):
+    bufsize = BUFSIZE
+    fp1 = open(f1, 'rb')
+    fp2 = open(f2, 'rb')
+    while True:
+        b1 = fp1.read(bufsize)
+        b2 = fp2.read(bufsize)
+        if b1 != b2:
+            return False
+        if not b1:
+            return True
+
+# Directory comparison class.
+#
+class dircmp:
+    """A class that manages the comparison of 2 directories.
+
+    dircmp(a,b,ignore=None,hide=None)
+      A and B are directories.
+      IGNORE is a list of names to ignore,
+        defaults to ['RCS', 'CVS', 'tags'].
+      HIDE is a list of names to hide,
+        defaults to [os.curdir, os.pardir].
+
+    High level usage:
+      x = dircmp(dir1, dir2)
+      x.report() -> prints a report on the differences between dir1 and dir2
+       or
+      x.report_partial_closure() -> prints report on differences between dir1
+            and dir2, and reports on common immediate subdirectories.
+      x.report_full_closure() -> like report_partial_closure,
+            but fully recursive.
+
+    Attributes:
+     left_list, right_list: The files in dir1 and dir2,
+        filtered by hide and ignore.
+     common: a list of names in both dir1 and dir2.
+     left_only, right_only: names only in dir1, dir2.
+     common_dirs: subdirectories in both dir1 and dir2.
+     common_files: files in both dir1 and dir2.
+     common_funny: names in both dir1 and dir2 where the type differs between
+        dir1 and dir2, or the name is not stat-able.
+     same_files: list of identical files.
+     diff_files: list of filenames which differ.
+     funny_files: list of files which could not be compared.
+     subdirs: a dictionary of dircmp objects, keyed by names in common_dirs.
+     """
+
+    def __init__(self, a, b, ignore=None, hide=None): # Initialize
+        self.left = a
+        self.right = b
+        if hide is None:
+            self.hide = [os.curdir, os.pardir] # Names never to be shown
+        else:
+            self.hide = hide
+        if ignore is None:
+            self.ignore = ['RCS', 'CVS', 'tags'] # Names ignored in comparison
+        else:
+            self.ignore = ignore
+
+    def phase0(self): # Compare everything except common subdirectories
+        self.left_list = _filter(os.listdir(self.left),
+                                 self.hide+self.ignore)
+        self.right_list = _filter(os.listdir(self.right),
+                                  self.hide+self.ignore)
+        self.left_list.sort()
+        self.right_list.sort()
+
+    def phase1(self): # Compute common names
+        a = dict(izip(imap(os.path.normcase, self.left_list), self.left_list))
+        b = dict(izip(imap(os.path.normcase, self.right_list), self.right_list))
+        self.common = map(a.__getitem__, ifilter(b.has_key, a))
+        self.left_only = map(a.__getitem__, ifilterfalse(b.has_key, a))
+        self.right_only = map(b.__getitem__, ifilterfalse(a.has_key, b))
+
+    def phase2(self): # Distinguish files, directories, funnies
+        self.common_dirs = []
+        self.common_files = []
+        self.common_funny = []
+
+        for x in self.common:
+            a_path = os.path.join(self.left, x)
+            b_path = os.path.join(self.right, x)
+
+            ok = 1
+            try:
+                a_stat = os.stat(a_path)
+            except os.error, why:
+                # print 'Can\'t stat', a_path, ':', why[1]
+                ok = 0
+            try:
+                b_stat = os.stat(b_path)
+            except os.error, why:
+                # print 'Can\'t stat', b_path, ':', why[1]
+                ok = 0
+
+            if ok:
+                a_type = stat.S_IFMT(a_stat.st_mode)
+                b_type = stat.S_IFMT(b_stat.st_mode)
+                if a_type != b_type:
+                    self.common_funny.append(x)
+                elif stat.S_ISDIR(a_type):
+                    self.common_dirs.append(x)
+                elif stat.S_ISREG(a_type):
+                    self.common_files.append(x)
+                else:
+                    self.common_funny.append(x)
+            else:
+                self.common_funny.append(x)
+
+    def phase3(self): # Find out differences between common files
+        xx = cmpfiles(self.left, self.right, self.common_files)
+        self.same_files, self.diff_files, self.funny_files = xx
+
+    def phase4(self): # Find out differences between common subdirectories
+        # A new dircmp object is created for each common subdirectory,
+        # these are stored in a dictionary indexed by filename.
+        # The hide and ignore properties are inherited from the parent
+        self.subdirs = {}
+        for x in self.common_dirs:
+            a_x = os.path.join(self.left, x)
+            b_x = os.path.join(self.right, x)
+            self.subdirs[x]  = dircmp(a_x, b_x, self.ignore, self.hide)
+
+    def phase4_closure(self): # Recursively call phase4() on subdirectories
+        self.phase4()
+        for sd in self.subdirs.itervalues():
+            sd.phase4_closure()
+
+    def report(self): # Print a report on the differences between a and b
+        # Output format is purposely lousy
+        print 'diff', self.left, self.right
+        if self.left_only:
+            self.left_only.sort()
+            print 'Only in', self.left, ':', self.left_only
+        if self.right_only:
+            self.right_only.sort()
+            print 'Only in', self.right, ':', self.right_only
+        if self.same_files:
+            self.same_files.sort()
+            print 'Identical files :', self.same_files
+        if self.diff_files:
+            self.diff_files.sort()
+            print 'Differing files :', self.diff_files
+        if self.funny_files:
+            self.funny_files.sort()
+            print 'Trouble with common files :', self.funny_files
+        if self.common_dirs:
+            self.common_dirs.sort()
+            print 'Common subdirectories :', self.common_dirs
+        if self.common_funny:
+            self.common_funny.sort()
+            print 'Common funny cases :', self.common_funny
+
+    def report_partial_closure(self): # Print reports on self and on subdirs
+        self.report()
+        for sd in self.subdirs.itervalues():
+            print
+            sd.report()
+
+    def report_full_closure(self): # Report on self and subdirs recursively
+        self.report()
+        for sd in self.subdirs.itervalues():
+            print
+            sd.report_full_closure()
+
+    methodmap = dict(subdirs=phase4,
+                     same_files=phase3, diff_files=phase3, funny_files=phase3,
+                     common_dirs = phase2, common_files=phase2, common_funny=phase2,
+                     common=phase1, left_only=phase1, right_only=phase1,
+                     left_list=phase0, right_list=phase0)
+
+    def __getattr__(self, attr):
+        if attr not in self.methodmap:
+            raise AttributeError, attr
+        self.methodmap[attr](self)
+        return getattr(self, attr)
+
+def cmpfiles(a, b, common, shallow=1):
+    """Compare common files in two directories.
+
+    a, b -- directory names
+    common -- list of file names found in both directories
+    shallow -- if true, do comparison based solely on stat() information
+
+    Returns a tuple of three lists:
+      files that compare equal
+      files that are different
+      filenames that aren't regular files.
+
+    """
+    res = ([], [], [])
+    for x in common:
+        ax = os.path.join(a, x)
+        bx = os.path.join(b, x)
+        res[_cmp(ax, bx, shallow)].append(x)
+    return res
+
+
+# Compare two files.
+# Return:
+#       0 for equal
+#       1 for different
+#       2 for funny cases (can't stat, etc.)
+#
+def _cmp(a, b, sh, abs=abs, cmp=cmp):
+    try:
+        return not abs(cmp(a, b, sh))
+    except os.error:
+        return 2
+
+
+# Return a copy with items that occur in skip removed.
+#
+def _filter(flist, skip):
+    return list(ifilterfalse(skip.__contains__, flist))
+
+
+# Demonstration and testing.
+#
+def demo():
+    import sys
+    import getopt
+    options, args = getopt.getopt(sys.argv[1:], 'r')
+    if len(args) != 2:
+        raise getopt.GetoptError('need exactly two args', None)
+    dd = dircmp(args[0], args[1])
+    if ('-r', '') in options:
+        dd.report_full_closure()
+    else:
+        dd.report()
+
+if __name__ == '__main__':
+    demo()

Added: vendor/Python/current/Lib/fileinput.py
===================================================================
--- vendor/Python/current/Lib/fileinput.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/fileinput.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,413 @@
+"""Helper class to quickly write a loop over all standard input files.
+
+Typical use is:
+
+    import fileinput
+    for line in fileinput.input():
+        process(line)
+
+This iterates over the lines of all files listed in sys.argv[1:],
+defaulting to sys.stdin if the list is empty.  If a filename is '-' it
+is also replaced by sys.stdin.  To specify an alternative list of
+filenames, pass it as the argument to input().  A single file name is
+also allowed.
+
+Functions filename(), lineno() return the filename and cumulative line
+number of the line that has just been read; filelineno() returns its
+line number in the current file; isfirstline() returns true iff the
+line just read is the first line of its file; isstdin() returns true
+iff the line was read from sys.stdin.  Function nextfile() closes the
+current file so that the next iteration will read the first line from
+the next file (if any); lines not read from the file will not count
+towards the cumulative line count; the filename is not changed until
+after the first line of the next file has been read.  Function close()
+closes the sequence.
+
+Before any lines have been read, filename() returns None and both line
+numbers are zero; nextfile() has no effect.  After all lines have been
+read, filename() and the line number functions return the values
+pertaining to the last line read; nextfile() has no effect.
+
+All files are opened in text mode by default, you can override this by
+setting the mode parameter to input() or FileInput.__init__().
+If an I/O error occurs during opening or reading a file, the IOError
+exception is raised.
+
+If sys.stdin is used more than once, the second and further use will
+return no lines, except perhaps for interactive use, or if it has been
+explicitly reset (e.g. using sys.stdin.seek(0)).
+
+Empty files are opened and immediately closed; the only time their
+presence in the list of filenames is noticeable at all is when the
+last file opened is empty.
+
+It is possible that the last line of a file doesn't end in a newline
+character; otherwise lines are returned including the trailing
+newline.
+
+Class FileInput is the implementation; its methods filename(),
+lineno(), fileline(), isfirstline(), isstdin(), nextfile() and close()
+correspond to the functions in the module.  In addition it has a
+readline() method which returns the next input line, and a
+__getitem__() method which implements the sequence behavior.  The
+sequence must be accessed in strictly sequential order; sequence
+access and readline() cannot be mixed.
+
+Optional in-place filtering: if the keyword argument inplace=1 is
+passed to input() or to the FileInput constructor, the file is moved
+to a backup file and standard output is directed to the input file.
+This makes it possible to write a filter that rewrites its input file
+in place.  If the keyword argument backup=".<some extension>" is also
+given, it specifies the extension for the backup file, and the backup
+file remains around; by default, the extension is ".bak" and it is
+deleted when the output file is closed.  In-place filtering is
+disabled when standard input is read.  XXX The current implementation
+does not work for MS-DOS 8+3 filesystems.
+
+Performance: this module is unfortunately one of the slower ways of
+processing large numbers of input lines.  Nevertheless, a significant
+speed-up has been obtained by using readlines(bufsize) instead of
+readline().  A new keyword argument, bufsize=N, is present on the
+input() function and the FileInput() class to override the default
+buffer size.
+
+XXX Possible additions:
+
+- optional getopt argument processing
+- isatty()
+- read(), read(size), even readlines()
+
+"""
+
+import sys, os
+
+__all__ = ["input","close","nextfile","filename","lineno","filelineno",
+           "isfirstline","isstdin","FileInput"]
+
+_state = None
+
+DEFAULT_BUFSIZE = 8*1024
+
+def input(files=None, inplace=0, backup="", bufsize=0,
+          mode="r", openhook=None):
+    """input([files[, inplace[, backup[, mode[, openhook]]]]])
+
+    Create an instance of the FileInput class. The instance will be used
+    as global state for the functions of this module, and is also returned
+    to use during iteration. The parameters to this function will be passed
+    along to the constructor of the FileInput class.
+    """
+    global _state
+    if _state and _state._file:
+        raise RuntimeError, "input() already active"
+    _state = FileInput(files, inplace, backup, bufsize, mode, openhook)
+    return _state
+
+def close():
+    """Close the sequence."""
+    global _state
+    state = _state
+    _state = None
+    if state:
+        state.close()
+
+def nextfile():
+    """
+    Close the current file so that the next iteration will read the first
+    line from the next file (if any); lines not read from the file will
+    not count towards the cumulative line count. The filename is not
+    changed until after the first line of the next file has been read.
+    Before the first line has been read, this function has no effect;
+    it cannot be used to skip the first file. After the last line of the
+    last file has been read, this function has no effect.
+    """
+    if not _state:
+        raise RuntimeError, "no active input()"
+    return _state.nextfile()
+
+def filename():
+    """
+    Return the name of the file currently being read.
+    Before the first line has been read, returns None.
+    """
+    if not _state:
+        raise RuntimeError, "no active input()"
+    return _state.filename()
+
+def lineno():
+    """
+    Return the cumulative line number of the line that has just been read.
+    Before the first line has been read, returns 0. After the last line
+    of the last file has been read, returns the line number of that line.
+    """
+    if not _state:
+        raise RuntimeError, "no active input()"
+    return _state.lineno()
+
+def filelineno():
+    """
+    Return the line number in the current file. Before the first line
+    has been read, returns 0. After the last line of the last file has
+    been read, returns the line number of that line within the file.
+    """
+    if not _state:
+        raise RuntimeError, "no active input()"
+    return _state.filelineno()
+
+def fileno():
+    """
+    Return the file number of the current file. When no file is currently
+    opened, returns -1.
+    """
+    if not _state:
+        raise RuntimeError, "no active input()"
+    return _state.fileno()
+
+def isfirstline():
+    """
+    Returns true the line just read is the first line of its file,
+    otherwise returns false.
+    """
+    if not _state:
+        raise RuntimeError, "no active input()"
+    return _state.isfirstline()
+
+def isstdin():
+    """
+    Returns true if the last line was read from sys.stdin,
+    otherwise returns false.
+    """
+    if not _state:
+        raise RuntimeError, "no active input()"
+    return _state.isstdin()
+
+class FileInput:
+    """class FileInput([files[, inplace[, backup[, mode[, openhook]]]]])
+
+    Class FileInput is the implementation of the module; its methods
+    filename(), lineno(), fileline(), isfirstline(), isstdin(), fileno(),
+    nextfile() and close() correspond to the functions of the same name
+    in the module.
+    In addition it has a readline() method which returns the next
+    input line, and a __getitem__() method which implements the
+    sequence behavior. The sequence must be accessed in strictly
+    sequential order; random access and readline() cannot be mixed.
+    """
+
+    def __init__(self, files=None, inplace=0, backup="", bufsize=0,
+                 mode="r", openhook=None):
+        if isinstance(files, basestring):
+            files = (files,)
+        else:
+            if files is None:
+                files = sys.argv[1:]
+            if not files:
+                files = ('-',)
+            else:
+                files = tuple(files)
+        self._files = files
+        self._inplace = inplace
+        self._backup = backup
+        self._bufsize = bufsize or DEFAULT_BUFSIZE
+        self._savestdout = None
+        self._output = None
+        self._filename = None
+        self._lineno = 0
+        self._filelineno = 0
+        self._file = None
+        self._isstdin = False
+        self._backupfilename = None
+        self._buffer = []
+        self._bufindex = 0
+        # restrict mode argument to reading modes
+        if mode not in ('r', 'rU', 'U', 'rb'):
+            raise ValueError("FileInput opening mode must be one of "
+                             "'r', 'rU', 'U' and 'rb'")
+        self._mode = mode
+        if inplace and openhook:
+            raise ValueError("FileInput cannot use an opening hook in inplace mode")
+        elif openhook and not callable(openhook):
+            raise ValueError("FileInput openhook must be callable")
+        self._openhook = openhook
+
+    def __del__(self):
+        self.close()
+
+    def close(self):
+        self.nextfile()
+        self._files = ()
+
+    def __iter__(self):
+        return self
+
+    def next(self):
+        try:
+            line = self._buffer[self._bufindex]
+        except IndexError:
+            pass
+        else:
+            self._bufindex += 1
+            self._lineno += 1
+            self._filelineno += 1
+            return line
+        line = self.readline()
+        if not line:
+            raise StopIteration
+        return line
+
+    def __getitem__(self, i):
+        if i != self._lineno:
+            raise RuntimeError, "accessing lines out of order"
+        try:
+            return self.next()
+        except StopIteration:
+            raise IndexError, "end of input reached"
+
+    def nextfile(self):
+        savestdout = self._savestdout
+        self._savestdout = 0
+        if savestdout:
+            sys.stdout = savestdout
+
+        output = self._output
+        self._output = 0
+        if output:
+            output.close()
+
+        file = self._file
+        self._file = 0
+        if file and not self._isstdin:
+            file.close()
+
+        backupfilename = self._backupfilename
+        self._backupfilename = 0
+        if backupfilename and not self._backup:
+            try: os.unlink(backupfilename)
+            except OSError: pass
+
+        self._isstdin = False
+        self._buffer = []
+        self._bufindex = 0
+
+    def readline(self):
+        try:
+            line = self._buffer[self._bufindex]
+        except IndexError:
+            pass
+        else:
+            self._bufindex += 1
+            self._lineno += 1
+            self._filelineno += 1
+            return line
+        if not self._file:
+            if not self._files:
+                return ""
+            self._filename = self._files[0]
+            self._files = self._files[1:]
+            self._filelineno = 0
+            self._file = None
+            self._isstdin = False
+            self._backupfilename = 0
+            if self._filename == '-':
+                self._filename = '<stdin>'
+                self._file = sys.stdin
+                self._isstdin = True
+            else:
+                if self._inplace:
+                    self._backupfilename = (
+                        self._filename + (self._backup or os.extsep+"bak"))
+                    try: os.unlink(self._backupfilename)
+                    except os.error: pass
+                    # The next few lines may raise IOError
+                    os.rename(self._filename, self._backupfilename)
+                    self._file = open(self._backupfilename, self._mode)
+                    try:
+                        perm = os.fstat(self._file.fileno()).st_mode
+                    except OSError:
+                        self._output = open(self._filename, "w")
+                    else:
+                        fd = os.open(self._filename,
+                                     os.O_CREAT | os.O_WRONLY | os.O_TRUNC,
+                                     perm)
+                        self._output = os.fdopen(fd, "w")
+                        try:
+                            if hasattr(os, 'chmod'):
+                                os.chmod(self._filename, perm)
+                        except OSError:
+                            pass
+                    self._savestdout = sys.stdout
+                    sys.stdout = self._output
+                else:
+                    # This may raise IOError
+                    if self._openhook:
+                        self._file = self._openhook(self._filename, self._mode)
+                    else:
+                        self._file = open(self._filename, self._mode)
+        self._buffer = self._file.readlines(self._bufsize)
+        self._bufindex = 0
+        if not self._buffer:
+            self.nextfile()
+        # Recursive call
+        return self.readline()
+
+    def filename(self):
+        return self._filename
+
+    def lineno(self):
+        return self._lineno
+
+    def filelineno(self):
+        return self._filelineno
+
+    def fileno(self):
+        if self._file:
+            try:
+                return self._file.fileno()
+            except ValueError:
+                return -1
+        else:
+            return -1
+
+    def isfirstline(self):
+        return self._filelineno == 1
+
+    def isstdin(self):
+        return self._isstdin
+
+
+def hook_compressed(filename, mode):
+    ext = os.path.splitext(filename)[1]
+    if ext == '.gz':
+        import gzip
+        return gzip.open(filename, mode)
+    elif ext == '.bz2':
+        import bz2
+        return bz2.BZ2File(filename, mode)
+    else:
+        return open(filename, mode)
+
+
+def hook_encoded(encoding):
+    import codecs
+    def openhook(filename, mode):
+        return codecs.open(filename, mode, encoding)
+    return openhook
+
+
+def _test():
+    import getopt
+    inplace = 0
+    backup = 0
+    opts, args = getopt.getopt(sys.argv[1:], "ib:")
+    for o, a in opts:
+        if o == '-i': inplace = 1
+        if o == '-b': backup = a
+    for line in input(args, inplace=inplace, backup=backup):
+        if line[-1:] == '\n': line = line[:-1]
+        if line[-1:] == '\r': line = line[:-1]
+        print "%d: %s[%d]%s %s" % (lineno(), filename(), filelineno(),
+                                   isfirstline() and "*" or "", line)
+    print "%d: %s[%d]" % (lineno(), filename(), filelineno())
+
+if __name__ == '__main__':
+    _test()

Added: vendor/Python/current/Lib/fnmatch.py
===================================================================
--- vendor/Python/current/Lib/fnmatch.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/fnmatch.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,107 @@
+"""Filename matching with shell patterns.
+
+fnmatch(FILENAME, PATTERN) matches according to the local convention.
+fnmatchcase(FILENAME, PATTERN) always takes case in account.
+
+The functions operate by translating the pattern into a regular
+expression.  They cache the compiled regular expressions for speed.
+
+The function translate(PATTERN) returns a regular expression
+corresponding to PATTERN.  (It does not compile it.)
+"""
+
+import re
+
+__all__ = ["filter", "fnmatch","fnmatchcase","translate"]
+
+_cache = {}
+
+def fnmatch(name, pat):
+    """Test whether FILENAME matches PATTERN.
+
+    Patterns are Unix shell style:
+
+    *       matches everything
+    ?       matches any single character
+    [seq]   matches any character in seq
+    [!seq]  matches any char not in seq
+
+    An initial period in FILENAME is not special.
+    Both FILENAME and PATTERN are first case-normalized
+    if the operating system requires it.
+    If you don't want this, use fnmatchcase(FILENAME, PATTERN).
+    """
+
+    import os
+    name = os.path.normcase(name)
+    pat = os.path.normcase(pat)
+    return fnmatchcase(name, pat)
+
+def filter(names, pat):
+    """Return the subset of the list NAMES that match PAT"""
+    import os,posixpath
+    result=[]
+    pat=os.path.normcase(pat)
+    if not pat in _cache:
+        res = translate(pat)
+        _cache[pat] = re.compile(res)
+    match=_cache[pat].match
+    if os.path is posixpath:
+        # normcase on posix is NOP. Optimize it away from the loop.
+        for name in names:
+            if match(name):
+                result.append(name)
+    else:
+        for name in names:
+            if match(os.path.normcase(name)):
+                result.append(name)
+    return result
+
+def fnmatchcase(name, pat):
+    """Test whether FILENAME matches PATTERN, including case.
+
+    This is a version of fnmatch() which doesn't case-normalize
+    its arguments.
+    """
+
+    if not pat in _cache:
+        res = translate(pat)
+        _cache[pat] = re.compile(res)
+    return _cache[pat].match(name) is not None
+
+def translate(pat):
+    """Translate a shell PATTERN to a regular expression.
+
+    There is no way to quote meta-characters.
+    """
+
+    i, n = 0, len(pat)
+    res = ''
+    while i < n:
+        c = pat[i]
+        i = i+1
+        if c == '*':
+            res = res + '.*'
+        elif c == '?':
+            res = res + '.'
+        elif c == '[':
+            j = i
+            if j < n and pat[j] == '!':
+                j = j+1
+            if j < n and pat[j] == ']':
+                j = j+1
+            while j < n and pat[j] != ']':
+                j = j+1
+            if j >= n:
+                res = res + '\\['
+            else:
+                stuff = pat[i:j].replace('\\','\\\\')
+                i = j+1
+                if stuff[0] == '!':
+                    stuff = '^' + stuff[1:]
+                elif stuff[0] == '^':
+                    stuff = '\\' + stuff
+                res = '%s[%s]' % (res, stuff)
+        else:
+            res = res + re.escape(c)
+    return res + "$"

Added: vendor/Python/current/Lib/formatter.py
===================================================================
--- vendor/Python/current/Lib/formatter.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/formatter.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,447 @@
+"""Generic output formatting.
+
+Formatter objects transform an abstract flow of formatting events into
+specific output events on writer objects. Formatters manage several stack
+structures to allow various properties of a writer object to be changed and
+restored; writers need not be able to handle relative changes nor any sort
+of ``change back'' operation. Specific writer properties which may be
+controlled via formatter objects are horizontal alignment, font, and left
+margin indentations. A mechanism is provided which supports providing
+arbitrary, non-exclusive style settings to a writer as well. Additional
+interfaces facilitate formatting events which are not reversible, such as
+paragraph separation.
+
+Writer objects encapsulate device interfaces. Abstract devices, such as
+file formats, are supported as well as physical devices. The provided
+implementations all work with abstract devices. The interface makes
+available mechanisms for setting the properties which formatter objects
+manage and inserting data into the output.
+"""
+
+import sys
+
+
+AS_IS = None
+
+
+class NullFormatter:
+    """A formatter which does nothing.
+
+    If the writer parameter is omitted, a NullWriter instance is created.
+    No methods of the writer are called by NullFormatter instances.
+
+    Implementations should inherit from this class if implementing a writer
+    interface but don't need to inherit any implementation.
+
+    """
+
+    def __init__(self, writer=None):
+        if writer is None:
+            writer = NullWriter()
+        self.writer = writer
+    def end_paragraph(self, blankline): pass
+    def add_line_break(self): pass
+    def add_hor_rule(self, *args, **kw): pass
+    def add_label_data(self, format, counter, blankline=None): pass
+    def add_flowing_data(self, data): pass
+    def add_literal_data(self, data): pass
+    def flush_softspace(self): pass
+    def push_alignment(self, align): pass
+    def pop_alignment(self): pass
+    def push_font(self, x): pass
+    def pop_font(self): pass
+    def push_margin(self, margin): pass
+    def pop_margin(self): pass
+    def set_spacing(self, spacing): pass
+    def push_style(self, *styles): pass
+    def pop_style(self, n=1): pass
+    def assert_line_data(self, flag=1): pass
+
+
+class AbstractFormatter:
+    """The standard formatter.
+
+    This implementation has demonstrated wide applicability to many writers,
+    and may be used directly in most circumstances.  It has been used to
+    implement a full-featured World Wide Web browser.
+
+    """
+
+    #  Space handling policy:  blank spaces at the boundary between elements
+    #  are handled by the outermost context.  "Literal" data is not checked
+    #  to determine context, so spaces in literal data are handled directly
+    #  in all circumstances.
+
+    def __init__(self, writer):
+        self.writer = writer            # Output device
+        self.align = None               # Current alignment
+        self.align_stack = []           # Alignment stack
+        self.font_stack = []            # Font state
+        self.margin_stack = []          # Margin state
+        self.spacing = None             # Vertical spacing state
+        self.style_stack = []           # Other state, e.g. color
+        self.nospace = 1                # Should leading space be suppressed
+        self.softspace = 0              # Should a space be inserted
+        self.para_end = 1               # Just ended a paragraph
+        self.parskip = 0                # Skipped space between paragraphs?
+        self.hard_break = 1             # Have a hard break
+        self.have_label = 0
+
+    def end_paragraph(self, blankline):
+        if not self.hard_break:
+            self.writer.send_line_break()
+            self.have_label = 0
+        if self.parskip < blankline and not self.have_label:
+            self.writer.send_paragraph(blankline - self.parskip)
+            self.parskip = blankline
+            self.have_label = 0
+        self.hard_break = self.nospace = self.para_end = 1
+        self.softspace = 0
+
+    def add_line_break(self):
+        if not (self.hard_break or self.para_end):
+            self.writer.send_line_break()
+            self.have_label = self.parskip = 0
+        self.hard_break = self.nospace = 1
+        self.softspace = 0
+
+    def add_hor_rule(self, *args, **kw):
+        if not self.hard_break:
+            self.writer.send_line_break()
+        self.writer.send_hor_rule(*args, **kw)
+        self.hard_break = self.nospace = 1
+        self.have_label = self.para_end = self.softspace = self.parskip = 0
+
+    def add_label_data(self, format, counter, blankline = None):
+        if self.have_label or not self.hard_break:
+            self.writer.send_line_break()
+        if not self.para_end:
+            self.writer.send_paragraph((blankline and 1) or 0)
+        if isinstance(format, str):
+            self.writer.send_label_data(self.format_counter(format, counter))
+        else:
+            self.writer.send_label_data(format)
+        self.nospace = self.have_label = self.hard_break = self.para_end = 1
+        self.softspace = self.parskip = 0
+
+    def format_counter(self, format, counter):
+        label = ''
+        for c in format:
+            if c == '1':
+                label = label + ('%d' % counter)
+            elif c in 'aA':
+                if counter > 0:
+                    label = label + self.format_letter(c, counter)
+            elif c in 'iI':
+                if counter > 0:
+                    label = label + self.format_roman(c, counter)
+            else:
+                label = label + c
+        return label
+
+    def format_letter(self, case, counter):
+        label = ''
+        while counter > 0:
+            counter, x = divmod(counter-1, 26)
+            # This makes a strong assumption that lowercase letters
+            # and uppercase letters form two contiguous blocks, with
+            # letters in order!
+            s = chr(ord(case) + x)
+            label = s + label
+        return label
+
+    def format_roman(self, case, counter):
+        ones = ['i', 'x', 'c', 'm']
+        fives = ['v', 'l', 'd']
+        label, index = '', 0
+        # This will die of IndexError when counter is too big
+        while counter > 0:
+            counter, x = divmod(counter, 10)
+            if x == 9:
+                label = ones[index] + ones[index+1] + label
+            elif x == 4:
+                label = ones[index] + fives[index] + label
+            else:
+                if x >= 5:
+                    s = fives[index]
+                    x = x-5
+                else:
+                    s = ''
+                s = s + ones[index]*x
+                label = s + label
+            index = index + 1
+        if case == 'I':
+            return label.upper()
+        return label
+
+    def add_flowing_data(self, data):
+        if not data: return
+        prespace = data[:1].isspace()
+        postspace = data[-1:].isspace()
+        data = " ".join(data.split())
+        if self.nospace and not data:
+            return
+        elif prespace or self.softspace:
+            if not data:
+                if not self.nospace:
+                    self.softspace = 1
+                    self.parskip = 0
+                return
+            if not self.nospace:
+                data = ' ' + data
+        self.hard_break = self.nospace = self.para_end = \
+                          self.parskip = self.have_label = 0
+        self.softspace = postspace
+        self.writer.send_flowing_data(data)
+
+    def add_literal_data(self, data):
+        if not data: return
+        if self.softspace:
+            self.writer.send_flowing_data(" ")
+        self.hard_break = data[-1:] == '\n'
+        self.nospace = self.para_end = self.softspace = \
+                       self.parskip = self.have_label = 0
+        self.writer.send_literal_data(data)
+
+    def flush_softspace(self):
+        if self.softspace:
+            self.hard_break = self.para_end = self.parskip = \
+                              self.have_label = self.softspace = 0
+            self.nospace = 1
+            self.writer.send_flowing_data(' ')
+
+    def push_alignment(self, align):
+        if align and align != self.align:
+            self.writer.new_alignment(align)
+            self.align = align
+            self.align_stack.append(align)
+        else:
+            self.align_stack.append(self.align)
+
+    def pop_alignment(self):
+        if self.align_stack:
+            del self.align_stack[-1]
+        if self.align_stack:
+            self.align = align = self.align_stack[-1]
+            self.writer.new_alignment(align)
+        else:
+            self.align = None
+            self.writer.new_alignment(None)
+
+    def push_font(self, (size, i, b, tt)):
+        if self.softspace:
+            self.hard_break = self.para_end = self.softspace = 0
+            self.nospace = 1
+            self.writer.send_flowing_data(' ')
+        if self.font_stack:
+            csize, ci, cb, ctt = self.font_stack[-1]
+            if size is AS_IS: size = csize
+            if i is AS_IS: i = ci
+            if b is AS_IS: b = cb
+            if tt is AS_IS: tt = ctt
+        font = (size, i, b, tt)
+        self.font_stack.append(font)
+        self.writer.new_font(font)
+
+    def pop_font(self):
+        if self.font_stack:
+            del self.font_stack[-1]
+        if self.font_stack:
+            font = self.font_stack[-1]
+        else:
+            font = None
+        self.writer.new_font(font)
+
+    def push_margin(self, margin):
+        self.margin_stack.append(margin)
+        fstack = filter(None, self.margin_stack)
+        if not margin and fstack:
+            margin = fstack[-1]
+        self.writer.new_margin(margin, len(fstack))
+
+    def pop_margin(self):
+        if self.margin_stack:
+            del self.margin_stack[-1]
+        fstack = filter(None, self.margin_stack)
+        if fstack:
+            margin = fstack[-1]
+        else:
+            margin = None
+        self.writer.new_margin(margin, len(fstack))
+
+    def set_spacing(self, spacing):
+        self.spacing = spacing
+        self.writer.new_spacing(spacing)
+
+    def push_style(self, *styles):
+        if self.softspace:
+            self.hard_break = self.para_end = self.softspace = 0
+            self.nospace = 1
+            self.writer.send_flowing_data(' ')
+        for style in styles:
+            self.style_stack.append(style)
+        self.writer.new_styles(tuple(self.style_stack))
+
+    def pop_style(self, n=1):
+        del self.style_stack[-n:]
+        self.writer.new_styles(tuple(self.style_stack))
+
+    def assert_line_data(self, flag=1):
+        self.nospace = self.hard_break = not flag
+        self.para_end = self.parskip = self.have_label = 0
+
+
+class NullWriter:
+    """Minimal writer interface to use in testing & inheritance.
+
+    A writer which only provides the interface definition; no actions are
+    taken on any methods.  This should be the base class for all writers
+    which do not need to inherit any implementation methods.
+
+    """
+    def __init__(self): pass
+    def flush(self): pass
+    def new_alignment(self, align): pass
+    def new_font(self, font): pass
+    def new_margin(self, margin, level): pass
+    def new_spacing(self, spacing): pass
+    def new_styles(self, styles): pass
+    def send_paragraph(self, blankline): pass
+    def send_line_break(self): pass
+    def send_hor_rule(self, *args, **kw): pass
+    def send_label_data(self, data): pass
+    def send_flowing_data(self, data): pass
+    def send_literal_data(self, data): pass
+
+
+class AbstractWriter(NullWriter):
+    """A writer which can be used in debugging formatters, but not much else.
+
+    Each method simply announces itself by printing its name and
+    arguments on standard output.
+
+    """
+
+    def new_alignment(self, align):
+        print "new_alignment(%r)" % (align,)
+
+    def new_font(self, font):
+        print "new_font(%r)" % (font,)
+
+    def new_margin(self, margin, level):
+        print "new_margin(%r, %d)" % (margin, level)
+
+    def new_spacing(self, spacing):
+        print "new_spacing(%r)" % (spacing,)
+
+    def new_styles(self, styles):
+        print "new_styles(%r)" % (styles,)
+
+    def send_paragraph(self, blankline):
+        print "send_paragraph(%r)" % (blankline,)
+
+    def send_line_break(self):
+        print "send_line_break()"
+
+    def send_hor_rule(self, *args, **kw):
+        print "send_hor_rule()"
+
+    def send_label_data(self, data):
+        print "send_label_data(%r)" % (data,)
+
+    def send_flowing_data(self, data):
+        print "send_flowing_data(%r)" % (data,)
+
+    def send_literal_data(self, data):
+        print "send_literal_data(%r)" % (data,)
+
+
+class DumbWriter(NullWriter):
+    """Simple writer class which writes output on the file object passed in
+    as the file parameter or, if file is omitted, on standard output.  The
+    output is simply word-wrapped to the number of columns specified by
+    the maxcol parameter.  This class is suitable for reflowing a sequence
+    of paragraphs.
+
+    """
+
+    def __init__(self, file=None, maxcol=72):
+        self.file = file or sys.stdout
+        self.maxcol = maxcol
+        NullWriter.__init__(self)
+        self.reset()
+
+    def reset(self):
+        self.col = 0
+        self.atbreak = 0
+
+    def send_paragraph(self, blankline):
+        self.file.write('\n'*blankline)
+        self.col = 0
+        self.atbreak = 0
+
+    def send_line_break(self):
+        self.file.write('\n')
+        self.col = 0
+        self.atbreak = 0
+
+    def send_hor_rule(self, *args, **kw):
+        self.file.write('\n')
+        self.file.write('-'*self.maxcol)
+        self.file.write('\n')
+        self.col = 0
+        self.atbreak = 0
+
+    def send_literal_data(self, data):
+        self.file.write(data)
+        i = data.rfind('\n')
+        if i >= 0:
+            self.col = 0
+            data = data[i+1:]
+        data = data.expandtabs()
+        self.col = self.col + len(data)
+        self.atbreak = 0
+
+    def send_flowing_data(self, data):
+        if not data: return
+        atbreak = self.atbreak or data[0].isspace()
+        col = self.col
+        maxcol = self.maxcol
+        write = self.file.write
+        for word in data.split():
+            if atbreak:
+                if col + len(word) >= maxcol:
+                    write('\n')
+                    col = 0
+                else:
+                    write(' ')
+                    col = col + 1
+            write(word)
+            col = col + len(word)
+            atbreak = 1
+        self.col = col
+        self.atbreak = data[-1].isspace()
+
+
+def test(file = None):
+    w = DumbWriter()
+    f = AbstractFormatter(w)
+    if file is not None:
+        fp = open(file)
+    elif sys.argv[1:]:
+        fp = open(sys.argv[1])
+    else:
+        fp = sys.stdin
+    while 1:
+        line = fp.readline()
+        if not line:
+            break
+        if line == '\n':
+            f.end_paragraph(1)
+        else:
+            f.add_flowing_data(line)
+    f.end_paragraph(0)
+
+
+if __name__ == '__main__':
+    test()

Added: vendor/Python/current/Lib/fpformat.py
===================================================================
--- vendor/Python/current/Lib/fpformat.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/fpformat.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,142 @@
+"""General floating point formatting functions.
+
+Functions:
+fix(x, digits_behind)
+sci(x, digits_behind)
+
+Each takes a number or a string and a number of digits as arguments.
+
+Parameters:
+x:             number to be formatted; or a string resembling a number
+digits_behind: number of digits behind the decimal point
+"""
+
+import re
+
+__all__ = ["fix","sci","NotANumber"]
+
+# Compiled regular expression to "decode" a number
+decoder = re.compile(r'^([-+]?)0*(\d*)((?:\.\d*)?)(([eE][-+]?\d+)?)$')
+# \0 the whole thing
+# \1 leading sign or empty
+# \2 digits left of decimal point
+# \3 fraction (empty or begins with point)
+# \4 exponent part (empty or begins with 'e' or 'E')
+
+try:
+    class NotANumber(ValueError):
+        pass
+except TypeError:
+    NotANumber = 'fpformat.NotANumber'
+
+def extract(s):
+    """Return (sign, intpart, fraction, expo) or raise an exception:
+    sign is '+' or '-'
+    intpart is 0 or more digits beginning with a nonzero
+    fraction is 0 or more digits
+    expo is an integer"""
+    res = decoder.match(s)
+    if res is None: raise NotANumber, s
+    sign, intpart, fraction, exppart = res.group(1,2,3,4)
+    if sign == '+': sign = ''
+    if fraction: fraction = fraction[1:]
+    if exppart: expo = int(exppart[1:])
+    else: expo = 0
+    return sign, intpart, fraction, expo
+
+def unexpo(intpart, fraction, expo):
+    """Remove the exponent by changing intpart and fraction."""
+    if expo > 0: # Move the point left
+        f = len(fraction)
+        intpart, fraction = intpart + fraction[:expo], fraction[expo:]
+        if expo > f:
+            intpart = intpart + '0'*(expo-f)
+    elif expo < 0: # Move the point right
+        i = len(intpart)
+        intpart, fraction = intpart[:expo], intpart[expo:] + fraction
+        if expo < -i:
+            fraction = '0'*(-expo-i) + fraction
+    return intpart, fraction
+
+def roundfrac(intpart, fraction, digs):
+    """Round or extend the fraction to size digs."""
+    f = len(fraction)
+    if f <= digs:
+        return intpart, fraction + '0'*(digs-f)
+    i = len(intpart)
+    if i+digs < 0:
+        return '0'*-digs, ''
+    total = intpart + fraction
+    nextdigit = total[i+digs]
+    if nextdigit >= '5': # Hard case: increment last digit, may have carry!
+        n = i + digs - 1
+        while n >= 0:
+            if total[n] != '9': break
+            n = n-1
+        else:
+            total = '0' + total
+            i = i+1
+            n = 0
+        total = total[:n] + chr(ord(total[n]) + 1) + '0'*(len(total)-n-1)
+        intpart, fraction = total[:i], total[i:]
+    if digs >= 0:
+        return intpart, fraction[:digs]
+    else:
+        return intpart[:digs] + '0'*-digs, ''
+
+def fix(x, digs):
+    """Format x as [-]ddd.ddd with 'digs' digits after the point
+    and at least one digit before.
+    If digs <= 0, the point is suppressed."""
+    if type(x) != type(''): x = repr(x)
+    try:
+        sign, intpart, fraction, expo = extract(x)
+    except NotANumber:
+        return x
+    intpart, fraction = unexpo(intpart, fraction, expo)
+    intpart, fraction = roundfrac(intpart, fraction, digs)
+    while intpart and intpart[0] == '0': intpart = intpart[1:]
+    if intpart == '': intpart = '0'
+    if digs > 0: return sign + intpart + '.' + fraction
+    else: return sign + intpart
+
+def sci(x, digs):
+    """Format x as [-]d.dddE[+-]ddd with 'digs' digits after the point
+    and exactly one digit before.
+    If digs is <= 0, one digit is kept and the point is suppressed."""
+    if type(x) != type(''): x = repr(x)
+    sign, intpart, fraction, expo = extract(x)
+    if not intpart:
+        while fraction and fraction[0] == '0':
+            fraction = fraction[1:]
+            expo = expo - 1
+        if fraction:
+            intpart, fraction = fraction[0], fraction[1:]
+            expo = expo - 1
+        else:
+            intpart = '0'
+    else:
+        expo = expo + len(intpart) - 1
+        intpart, fraction = intpart[0], intpart[1:] + fraction
+    digs = max(0, digs)
+    intpart, fraction = roundfrac(intpart, fraction, digs)
+    if len(intpart) > 1:
+        intpart, fraction, expo = \
+            intpart[0], intpart[1:] + fraction[:-1], \
+            expo + len(intpart) - 1
+    s = sign + intpart
+    if digs > 0: s = s + '.' + fraction
+    e = repr(abs(expo))
+    e = '0'*(3-len(e)) + e
+    if expo < 0: e = '-' + e
+    else: e = '+' + e
+    return s + 'e' + e
+
+def test():
+    """Interactive test run."""
+    try:
+        while 1:
+            x, digs = input('Enter (x, digs): ')
+            print x, fix(x, digs), sci(x, digs)
+    except (EOFError, KeyboardInterrupt):
+        pass

Added: vendor/Python/current/Lib/ftplib.py
===================================================================
--- vendor/Python/current/Lib/ftplib.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ftplib.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,823 @@
+"""An FTP client class and some helper functions.
+
+Based on RFC 959: File Transfer Protocol (FTP), by J. Postel and J. Reynolds
+
+Example:
+
+>>> from ftplib import FTP
+>>> ftp = FTP('ftp.python.org') # connect to host, default port
+>>> ftp.login() # default, i.e.: user anonymous, passwd anonymous@
+'230 Guest login ok, access restrictions apply.'
+>>> ftp.retrlines('LIST') # list directory contents
+total 9
+drwxr-xr-x   8 root     wheel        1024 Jan  3  1994 .
+drwxr-xr-x   8 root     wheel        1024 Jan  3  1994 ..
+drwxr-xr-x   2 root     wheel        1024 Jan  3  1994 bin
+drwxr-xr-x   2 root     wheel        1024 Jan  3  1994 etc
+d-wxrwxr-x   2 ftp      wheel        1024 Sep  5 13:43 incoming
+drwxr-xr-x   2 root     wheel        1024 Nov 17  1993 lib
+drwxr-xr-x   6 1094     wheel        1024 Sep 13 19:07 pub
+drwxr-xr-x   3 root     wheel        1024 Jan  3  1994 usr
+-rw-r--r--   1 root     root          312 Aug  1  1994 welcome.msg
+'226 Transfer complete.'
+>>> ftp.quit()
+'221 Goodbye.'
+>>>
+
+A nice test that reveals some of the network dialogue would be:
+python ftplib.py -d localhost -l -p -l
+"""
+
+#
+# Changes and improvements suggested by Steve Majewski.
+# Modified by Jack to work on the mac.
+# Modified by Siebren to support docstrings and PASV.
+#
+
+import os
+import sys
+
+# Import SOCKS module if it exists, else standard socket module socket
+try:
+    import SOCKS; socket = SOCKS; del SOCKS # import SOCKS as socket
+    from socket import getfqdn; socket.getfqdn = getfqdn; del getfqdn
+except ImportError:
+    import socket
+
+__all__ = ["FTP","Netrc"]
+
+# Magic number from <socket.h>
+MSG_OOB = 0x1                           # Process data out of band
+
+
+# The standard FTP server control port
+FTP_PORT = 21
+
+
+# Exception raised when an error or invalid response is received
+class Error(Exception): pass
+class error_reply(Error): pass          # unexpected [123]xx reply
+class error_temp(Error): pass           # 4xx errors
+class error_perm(Error): pass           # 5xx errors
+class error_proto(Error): pass          # response does not begin with [1-5]
+
+
+# All exceptions (hopefully) that may be raised here and that aren't
+# (always) programming errors on our side
+all_errors = (Error, socket.error, IOError, EOFError)
+
+
+# Line terminators (we always output CRLF, but accept any of CRLF, CR, LF)
+CRLF = '\r\n'
+
+
+# The class itself
+class FTP:
+
+    '''An FTP client class.
+
+    To create a connection, call the class using these argument:
+            host, user, passwd, acct
+    These are all strings, and have default value ''.
+    Then use self.connect() with optional host and port argument.
+
+    To download a file, use ftp.retrlines('RETR ' + filename),
+    or ftp.retrbinary() with slightly different arguments.
+    To upload a file, use ftp.storlines() or ftp.storbinary(),
+    which have an open file as argument (see their definitions
+    below for details).
+    The download/upload functions first issue appropriate TYPE
+    and PORT or PASV commands.
+'''
+
+    debugging = 0
+    host = ''
+    port = FTP_PORT
+    sock = None
+    file = None
+    welcome = None
+    passiveserver = 1
+
+    # Initialization method (called by class instantiation).
+    # Initialize host to localhost, port to standard ftp port
+    # Optional arguments are host (for connect()),
+    # and user, passwd, acct (for login())
+    def __init__(self, host='', user='', passwd='', acct=''):
+        if host:
+            self.connect(host)
+            if user: self.login(user, passwd, acct)
+
+    def connect(self, host = '', port = 0):
+        '''Connect to host.  Arguments are:
+        - host: hostname to connect to (string, default previous host)
+        - port: port to connect to (integer, default previous port)'''
+        if host: self.host = host
+        if port: self.port = port
+        msg = "getaddrinfo returns an empty list"
+        for res in socket.getaddrinfo(self.host, self.port, 0, socket.SOCK_STREAM):
+            af, socktype, proto, canonname, sa = res
+            try:
+                self.sock = socket.socket(af, socktype, proto)
+                self.sock.connect(sa)
+            except socket.error, msg:
+                if self.sock:
+                    self.sock.close()
+                self.sock = None
+                continue
+            break
+        if not self.sock:
+            raise socket.error, msg
+        self.af = af
+        self.file = self.sock.makefile('rb')
+        self.welcome = self.getresp()
+        return self.welcome
+
+    def getwelcome(self):
+        '''Get the welcome message from the server.
+        (this is read and squirreled away by connect())'''
+        if self.debugging:
+            print '*welcome*', self.sanitize(self.welcome)
+        return self.welcome
+
+    def set_debuglevel(self, level):
+        '''Set the debugging level.
+        The required argument level means:
+        0: no debugging output (default)
+        1: print commands and responses but not body text etc.
+        2: also print raw lines read and sent before stripping CR/LF'''
+        self.debugging = level
+    debug = set_debuglevel
+
+    def set_pasv(self, val):
+        '''Use passive or active mode for data transfers.
+        With a false argument, use the normal PORT mode,
+        With a true argument, use the PASV command.'''
+        self.passiveserver = val
+
+    # Internal: "sanitize" a string for printing
+    def sanitize(self, s):
+        if s[:5] == 'pass ' or s[:5] == 'PASS ':
+            i = len(s)
+            while i > 5 and s[i-1] in '\r\n':
+                i = i-1
+            s = s[:5] + '*'*(i-5) + s[i:]
+        return repr(s)
+
+    # Internal: send one line to the server, appending CRLF
+    def putline(self, line):
+        line = line + CRLF
+        if self.debugging > 1: print '*put*', self.sanitize(line)
+        self.sock.sendall(line)
+
+    # Internal: send one command to the server (through putline())
+    def putcmd(self, line):
+        if self.debugging: print '*cmd*', self.sanitize(line)
+        self.putline(line)
+
+    # Internal: return one line from the server, stripping CRLF.
+    # Raise EOFError if the connection is closed
+    def getline(self):
+        line = self.file.readline()
+        if self.debugging > 1:
+            print '*get*', self.sanitize(line)
+        if not line: raise EOFError
+        if line[-2:] == CRLF: line = line[:-2]
+        elif line[-1:] in CRLF: line = line[:-1]
+        return line
+
+    # Internal: get a response from the server, which may possibly
+    # consist of multiple lines.  Return a single string with no
+    # trailing CRLF.  If the response consists of multiple lines,
+    # these are separated by '\n' characters in the string
+    def getmultiline(self):
+        line = self.getline()
+        if line[3:4] == '-':
+            code = line[:3]
+            while 1:
+                nextline = self.getline()
+                line = line + ('\n' + nextline)
+                if nextline[:3] == code and \
+                        nextline[3:4] != '-':
+                    break
+        return line
+
+    # Internal: get a response from the server.
+    # Raise various errors if the response indicates an error
+    def getresp(self):
+        resp = self.getmultiline()
+        if self.debugging: print '*resp*', self.sanitize(resp)
+        self.lastresp = resp[:3]
+        c = resp[:1]
+        if c in ('1', '2', '3'):
+            return resp
+        if c == '4':
+            raise error_temp, resp
+        if c == '5':
+            raise error_perm, resp
+        raise error_proto, resp
+
+    def voidresp(self):
+        """Expect a response beginning with '2'."""
+        resp = self.getresp()
+        if resp[0] != '2':
+            raise error_reply, resp
+        return resp
+
+    def abort(self):
+        '''Abort a file transfer.  Uses out-of-band data.
+        This does not follow the procedure from the RFC to send Telnet
+        IP and Synch; that doesn't seem to work with the servers I've
+        tried.  Instead, just send the ABOR command as OOB data.'''
+        line = 'ABOR' + CRLF
+        if self.debugging > 1: print '*put urgent*', self.sanitize(line)
+        self.sock.sendall(line, MSG_OOB)
+        resp = self.getmultiline()
+        if resp[:3] not in ('426', '226'):
+            raise error_proto, resp
+
+    def sendcmd(self, cmd):
+        '''Send a command and return the response.'''
+        self.putcmd(cmd)
+        return self.getresp()
+
+    def voidcmd(self, cmd):
+        """Send a command and expect a response beginning with '2'."""
+        self.putcmd(cmd)
+        return self.voidresp()
+
+    def sendport(self, host, port):
+        '''Send a PORT command with the current host and the given
+        port number.
+        '''
+        hbytes = host.split('.')
+        pbytes = [repr(port/256), repr(port%256)]
+        bytes = hbytes + pbytes
+        cmd = 'PORT ' + ','.join(bytes)
+        return self.voidcmd(cmd)
+
+    def sendeprt(self, host, port):
+        '''Send a EPRT command with the current host and the given port number.'''
+        af = 0
+        if self.af == socket.AF_INET:
+            af = 1
+        if self.af == socket.AF_INET6:
+            af = 2
+        if af == 0:
+            raise error_proto, 'unsupported address family'
+        fields = ['', repr(af), host, repr(port), '']
+        cmd = 'EPRT ' + '|'.join(fields)
+        return self.voidcmd(cmd)
+
+    def makeport(self):
+        '''Create a new socket and send a PORT command for it.'''
+        msg = "getaddrinfo returns an empty list"
+        sock = None
+        for res in socket.getaddrinfo(None, 0, self.af, socket.SOCK_STREAM, 0, socket.AI_PASSIVE):
+            af, socktype, proto, canonname, sa = res
+            try:
+                sock = socket.socket(af, socktype, proto)
+                sock.bind(sa)
+            except socket.error, msg:
+                if sock:
+                    sock.close()
+                sock = None
+                continue
+            break
+        if not sock:
+            raise socket.error, msg
+        sock.listen(1)
+        port = sock.getsockname()[1] # Get proper port
+        host = self.sock.getsockname()[0] # Get proper host
+        if self.af == socket.AF_INET:
+            resp = self.sendport(host, port)
+        else:
+            resp = self.sendeprt(host, port)
+        return sock
+
+    def makepasv(self):
+        if self.af == socket.AF_INET:
+            host, port = parse227(self.sendcmd('PASV'))
+        else:
+            host, port = parse229(self.sendcmd('EPSV'), self.sock.getpeername())
+        return host, port
+
+    def ntransfercmd(self, cmd, rest=None):
+        """Initiate a transfer over the data connection.
+
+        If the transfer is active, send a port command and the
+        transfer command, and accept the connection.  If the server is
+        passive, send a pasv command, connect to it, and start the
+        transfer command.  Either way, return the socket for the
+        connection and the expected size of the transfer.  The
+        expected size may be None if it could not be determined.
+
+        Optional `rest' argument can be a string that is sent as the
+        argument to a RESTART command.  This is essentially a server
+        marker used to tell the server to skip over any data up to the
+        given marker.
+        """
+        size = None
+        if self.passiveserver:
+            host, port = self.makepasv()
+            af, socktype, proto, canon, sa = socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM)[0]
+            conn = socket.socket(af, socktype, proto)
+            conn.connect(sa)
+            if rest is not None:
+                self.sendcmd("REST %s" % rest)
+            resp = self.sendcmd(cmd)
+            # Some servers apparently send a 200 reply to
+            # a LIST or STOR command, before the 150 reply
+            # (and way before the 226 reply). This seems to
+            # be in violation of the protocol (which only allows
+            # 1xx or error messages for LIST), so we just discard
+            # this response.
+            if resp[0] == '2':
+               resp = self.getresp()
+            if resp[0] != '1':
+                raise error_reply, resp
+        else:
+            sock = self.makeport()
+            if rest is not None:
+                self.sendcmd("REST %s" % rest)
+            resp = self.sendcmd(cmd)
+            # See above.
+            if resp[0] == '2':
+               resp = self.getresp()
+            if resp[0] != '1':
+                raise error_reply, resp
+            conn, sockaddr = sock.accept()
+        if resp[:3] == '150':
+            # this is conditional in case we received a 125
+            size = parse150(resp)
+        return conn, size
+
+    def transfercmd(self, cmd, rest=None):
+        """Like ntransfercmd() but returns only the socket."""
+        return self.ntransfercmd(cmd, rest)[0]
+
+    def login(self, user = '', passwd = '', acct = ''):
+        '''Login, default anonymous.'''
+        if not user: user = 'anonymous'
+        if not passwd: passwd = ''
+        if not acct: acct = ''
+        if user == 'anonymous' and passwd in ('', '-'):
+            # If there is no anonymous ftp password specified
+            # then we'll just use anonymous@
+            # We don't send any other thing because:
+            # - We want to remain anonymous
+            # - We want to stop SPAM
+            # - We don't want to let ftp sites to discriminate by the user,
+            #   host or country.
+            passwd = passwd + 'anonymous@'
+        resp = self.sendcmd('USER ' + user)
+        if resp[0] == '3': resp = self.sendcmd('PASS ' + passwd)
+        if resp[0] == '3': resp = self.sendcmd('ACCT ' + acct)
+        if resp[0] != '2':
+            raise error_reply, resp
+        return resp
+
+    def retrbinary(self, cmd, callback, blocksize=8192, rest=None):
+        """Retrieve data in binary mode.
+
+        `cmd' is a RETR command.  `callback' is a callback function is
+        called for each block.  No more than `blocksize' number of
+        bytes will be read from the socket.  Optional `rest' is passed
+        to transfercmd().
+
+        A new port is created for you.  Return the response code.
+        """
+        self.voidcmd('TYPE I')
+        conn = self.transfercmd(cmd, rest)
+        while 1:
+            data = conn.recv(blocksize)
+            if not data:
+                break
+            callback(data)
+        conn.close()
+        return self.voidresp()
+
+    def retrlines(self, cmd, callback = None):
+        '''Retrieve data in line mode.
+        The argument is a RETR or LIST command.
+        The callback function (2nd argument) is called for each line,
+        with trailing CRLF stripped.  This creates a new port for you.
+        print_line() is the default callback.'''
+        if callback is None: callback = print_line
+        resp = self.sendcmd('TYPE A')
+        conn = self.transfercmd(cmd)
+        fp = conn.makefile('rb')
+        while 1:
+            line = fp.readline()
+            if self.debugging > 2: print '*retr*', repr(line)
+            if not line:
+                break
+            if line[-2:] == CRLF:
+                line = line[:-2]
+            elif line[-1:] == '\n':
+                line = line[:-1]
+            callback(line)
+        fp.close()
+        conn.close()
+        return self.voidresp()
+
+    def storbinary(self, cmd, fp, blocksize=8192):
+        '''Store a file in binary mode.'''
+        self.voidcmd('TYPE I')
+        conn = self.transfercmd(cmd)
+        while 1:
+            buf = fp.read(blocksize)
+            if not buf: break
+            conn.sendall(buf)
+        conn.close()
+        return self.voidresp()
+
+    def storlines(self, cmd, fp):
+        '''Store a file in line mode.'''
+        self.voidcmd('TYPE A')
+        conn = self.transfercmd(cmd)
+        while 1:
+            buf = fp.readline()
+            if not buf: break
+            if buf[-2:] != CRLF:
+                if buf[-1] in CRLF: buf = buf[:-1]
+                buf = buf + CRLF
+            conn.sendall(buf)
+        conn.close()
+        return self.voidresp()
+
+    def acct(self, password):
+        '''Send new account name.'''
+        cmd = 'ACCT ' + password
+        return self.voidcmd(cmd)
+
+    def nlst(self, *args):
+        '''Return a list of files in a given directory (default the current).'''
+        cmd = 'NLST'
+        for arg in args:
+            cmd = cmd + (' ' + arg)
+        files = []
+        self.retrlines(cmd, files.append)
+        return files
+
+    def dir(self, *args):
+        '''List a directory in long form.
+        By default list current directory to stdout.
+        Optional last argument is callback function; all
+        non-empty arguments before it are concatenated to the
+        LIST command.  (This *should* only be used for a pathname.)'''
+        cmd = 'LIST'
+        func = None
+        if args[-1:] and type(args[-1]) != type(''):
+            args, func = args[:-1], args[-1]
+        for arg in args:
+            if arg:
+                cmd = cmd + (' ' + arg)
+        self.retrlines(cmd, func)
+
+    def rename(self, fromname, toname):
+        '''Rename a file.'''
+        resp = self.sendcmd('RNFR ' + fromname)
+        if resp[0] != '3':
+            raise error_reply, resp
+        return self.voidcmd('RNTO ' + toname)
+
+    def delete(self, filename):
+        '''Delete a file.'''
+        resp = self.sendcmd('DELE ' + filename)
+        if resp[:3] in ('250', '200'):
+            return resp
+        elif resp[:1] == '5':
+            raise error_perm, resp
+        else:
+            raise error_reply, resp
+
+    def cwd(self, dirname):
+        '''Change to a directory.'''
+        if dirname == '..':
+            try:
+                return self.voidcmd('CDUP')
+            except error_perm, msg:
+                if msg.args[0][:3] != '500':
+                    raise
+        elif dirname == '':
+            dirname = '.'  # does nothing, but could return error
+        cmd = 'CWD ' + dirname
+        return self.voidcmd(cmd)
+
+    def size(self, filename):
+        '''Retrieve the size of a file.'''
+        # Note that the RFC doesn't say anything about 'SIZE'
+        resp = self.sendcmd('SIZE ' + filename)
+        if resp[:3] == '213':
+            s = resp[3:].strip()
+            try:
+                return int(s)
+            except (OverflowError, ValueError):
+                return long(s)
+
+    def mkd(self, dirname):
+        '''Make a directory, return its full pathname.'''
+        resp = self.sendcmd('MKD ' + dirname)
+        return parse257(resp)
+
+    def rmd(self, dirname):
+        '''Remove a directory.'''
+        return self.voidcmd('RMD ' + dirname)
+
+    def pwd(self):
+        '''Return current working directory.'''
+        resp = self.sendcmd('PWD')
+        return parse257(resp)
+
+    def quit(self):
+        '''Quit, and close the connection.'''
+        resp = self.voidcmd('QUIT')
+        self.close()
+        return resp
+
+    def close(self):
+        '''Close the connection without assuming anything about it.'''
+        if self.file:
+            self.file.close()
+            self.sock.close()
+            self.file = self.sock = None
+
+
+_150_re = None
+
+def parse150(resp):
+    '''Parse the '150' response for a RETR request.
+    Returns the expected transfer size or None; size is not guaranteed to
+    be present in the 150 message.
+    '''
+    if resp[:3] != '150':
+        raise error_reply, resp
+    global _150_re
+    if _150_re is None:
+        import re
+        _150_re = re.compile("150 .* \((\d+) bytes\)", re.IGNORECASE)
+    m = _150_re.match(resp)
+    if not m:
+        return None
+    s = m.group(1)
+    try:
+        return int(s)
+    except (OverflowError, ValueError):
+        return long(s)
+
+
+_227_re = None
+
+def parse227(resp):
+    '''Parse the '227' response for a PASV request.
+    Raises error_proto if it does not contain '(h1,h2,h3,h4,p1,p2)'
+    Return ('host.addr.as.numbers', port#) tuple.'''
+
+    if resp[:3] != '227':
+        raise error_reply, resp
+    global _227_re
+    if _227_re is None:
+        import re
+        _227_re = re.compile(r'(\d+),(\d+),(\d+),(\d+),(\d+),(\d+)')
+    m = _227_re.search(resp)
+    if not m:
+        raise error_proto, resp
+    numbers = m.groups()
+    host = '.'.join(numbers[:4])
+    port = (int(numbers[4]) << 8) + int(numbers[5])
+    return host, port
+
+
+def parse229(resp, peer):
+    '''Parse the '229' response for a EPSV request.
+    Raises error_proto if it does not contain '(|||port|)'
+    Return ('host.addr.as.numbers', port#) tuple.'''
+
+    if resp[:3] != '229':
+        raise error_reply, resp
+    left = resp.find('(')
+    if left < 0: raise error_proto, resp
+    right = resp.find(')', left + 1)
+    if right < 0:
+        raise error_proto, resp # should contain '(|||port|)'
+    if resp[left + 1] != resp[right - 1]:
+        raise error_proto, resp
+    parts = resp[left + 1:right].split(resp[left+1])
+    if len(parts) != 5:
+        raise error_proto, resp
+    host = peer[0]
+    port = int(parts[3])
+    return host, port
+
+
+def parse257(resp):
+    '''Parse the '257' response for a MKD or PWD request.
+    This is a response to a MKD or PWD request: a directory name.
+    Returns the directoryname in the 257 reply.'''
+
+    if resp[:3] != '257':
+        raise error_reply, resp
+    if resp[3:5] != ' "':
+        return '' # Not compliant to RFC 959, but UNIX ftpd does this
+    dirname = ''
+    i = 5
+    n = len(resp)
+    while i < n:
+        c = resp[i]
+        i = i+1
+        if c == '"':
+            if i >= n or resp[i] != '"':
+                break
+            i = i+1
+        dirname = dirname + c
+    return dirname
+
+
+def print_line(line):
+    '''Default retrlines callback to print a line.'''
+    print line
+
+
+def ftpcp(source, sourcename, target, targetname = '', type = 'I'):
+    '''Copy file from one FTP-instance to another.'''
+    if not targetname: targetname = sourcename
+    type = 'TYPE ' + type
+    source.voidcmd(type)
+    target.voidcmd(type)
+    sourcehost, sourceport = parse227(source.sendcmd('PASV'))
+    target.sendport(sourcehost, sourceport)
+    # RFC 959: the user must "listen" [...] BEFORE sending the
+    # transfer request.
+    # So: STOR before RETR, because here the target is a "user".
+    treply = target.sendcmd('STOR ' + targetname)
+    if treply[:3] not in ('125', '150'): raise error_proto  # RFC 959
+    sreply = source.sendcmd('RETR ' + sourcename)
+    if sreply[:3] not in ('125', '150'): raise error_proto  # RFC 959
+    source.voidresp()
+    target.voidresp()
+
+
+class Netrc:
+    """Class to parse & provide access to 'netrc' format files.
+
+    See the netrc(4) man page for information on the file format.
+
+    WARNING: This class is obsolete -- use module netrc instead.
+
+    """
+    __defuser = None
+    __defpasswd = None
+    __defacct = None
+
+    def __init__(self, filename=None):
+        if filename is None:
+            if "HOME" in os.environ:
+                filename = os.path.join(os.environ["HOME"],
+                                        ".netrc")
+            else:
+                raise IOError, \
+                      "specify file to load or set $HOME"
+        self.__hosts = {}
+        self.__macros = {}
+        fp = open(filename, "r")
+        in_macro = 0
+        while 1:
+            line = fp.readline()
+            if not line: break
+            if in_macro and line.strip():
+                macro_lines.append(line)
+                continue
+            elif in_macro:
+                self.__macros[macro_name] = tuple(macro_lines)
+                in_macro = 0
+            words = line.split()
+            host = user = passwd = acct = None
+            default = 0
+            i = 0
+            while i < len(words):
+                w1 = words[i]
+                if i+1 < len(words):
+                    w2 = words[i + 1]
+                else:
+                    w2 = None
+                if w1 == 'default':
+                    default = 1
+                elif w1 == 'machine' and w2:
+                    host = w2.lower()
+                    i = i + 1
+                elif w1 == 'login' and w2:
+                    user = w2
+                    i = i + 1
+                elif w1 == 'password' and w2:
+                    passwd = w2
+                    i = i + 1
+                elif w1 == 'account' and w2:
+                    acct = w2
+                    i = i + 1
+                elif w1 == 'macdef' and w2:
+                    macro_name = w2
+                    macro_lines = []
+                    in_macro = 1
+                    break
+                i = i + 1
+            if default:
+                self.__defuser = user or self.__defuser
+                self.__defpasswd = passwd or self.__defpasswd
+                self.__defacct = acct or self.__defacct
+            if host:
+                if host in self.__hosts:
+                    ouser, opasswd, oacct = \
+                           self.__hosts[host]
+                    user = user or ouser
+                    passwd = passwd or opasswd
+                    acct = acct or oacct
+                self.__hosts[host] = user, passwd, acct
+        fp.close()
+
+    def get_hosts(self):
+        """Return a list of hosts mentioned in the .netrc file."""
+        return self.__hosts.keys()
+
+    def get_account(self, host):
+        """Returns login information for the named host.
+
+        The return value is a triple containing userid,
+        password, and the accounting field.
+
+        """
+        host = host.lower()
+        user = passwd = acct = None
+        if host in self.__hosts:
+            user, passwd, acct = self.__hosts[host]
+        user = user or self.__defuser
+        passwd = passwd or self.__defpasswd
+        acct = acct or self.__defacct
+        return user, passwd, acct
+
+    def get_macros(self):
+        """Return a list of all defined macro names."""
+        return self.__macros.keys()
+
+    def get_macro(self, macro):
+        """Return a sequence of lines which define a named macro."""
+        return self.__macros[macro]
+
+
+
+def test():
+    '''Test program.
+    Usage: ftp [-d] [-r[file]] host [-l[dir]] [-d[dir]] [-p] [file] ...
+
+    -d dir
+    -l list
+    -p password
+    '''
+
+    if len(sys.argv) < 2:
+        print test.__doc__
+        sys.exit(0)
+
+    debugging = 0
+    rcfile = None
+    while sys.argv[1] == '-d':
+        debugging = debugging+1
+        del sys.argv[1]
+    if sys.argv[1][:2] == '-r':
+        # get name of alternate ~/.netrc file:
+        rcfile = sys.argv[1][2:]
+        del sys.argv[1]
+    host = sys.argv[1]
+    ftp = FTP(host)
+    ftp.set_debuglevel(debugging)
+    userid = passwd = acct = ''
+    try:
+        netrc = Netrc(rcfile)
+    except IOError:
+        if rcfile is not None:
+            sys.stderr.write("Could not open account file"
+                             " -- using anonymous login.")
+    else:
+        try:
+            userid, passwd, acct = netrc.get_account(host)
+        except KeyError:
+            # no account for host
+            sys.stderr.write(
+                    "No account -- using anonymous login.")
+    ftp.login(userid, passwd, acct)
+    for file in sys.argv[2:]:
+        if file[:2] == '-l':
+            ftp.dir(file[2:])
+        elif file[:2] == '-d':
+            cmd = 'CWD'
+            if file[2:]: cmd = cmd + ' ' + file[2:]
+            resp = ftp.sendcmd(cmd)
+        elif file == '-p':
+            ftp.set_pasv(not ftp.passiveserver)
+        else:
+            ftp.retrbinary('RETR ' + file, \
+                           sys.stdout.write, 1024)
+    ftp.quit()
+
+
+if __name__ == '__main__':
+    test()

Added: vendor/Python/current/Lib/functools.py
===================================================================
--- vendor/Python/current/Lib/functools.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/functools.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,51 @@
+"""functools.py - Tools for working with functions and callable objects
+"""
+# Python module wrapper for _functools C module
+# to allow utilities written in Python to be added
+# to the functools module.
+# Written by Nick Coghlan <ncoghlan at gmail.com>
+#   Copyright (C) 2006 Python Software Foundation.
+# See C source code for _functools credits/copyright
+
+from _functools import partial
+
+# update_wrapper() and wraps() are tools to help write
+# wrapper functions that can handle naive introspection
+
+WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__doc__')
+WRAPPER_UPDATES = ('__dict__',)
+def update_wrapper(wrapper,
+                   wrapped,
+                   assigned = WRAPPER_ASSIGNMENTS,
+                   updated = WRAPPER_UPDATES):
+    """Update a wrapper function to look like the wrapped function
+
+       wrapper is the function to be updated
+       wrapped is the original function
+       assigned is a tuple naming the attributes assigned directly
+       from the wrapped function to the wrapper function (defaults to
+       functools.WRAPPER_ASSIGNMENTS)
+       updated is a tuple naming the attributes off the wrapper that
+       are updated with the corresponding attribute from the wrapped
+       function (defaults to functools.WRAPPER_UPDATES)
+    """
+    for attr in assigned:
+        setattr(wrapper, attr, getattr(wrapped, attr))
+    for attr in updated:
+        getattr(wrapper, attr).update(getattr(wrapped, attr, {}))
+    # Return the wrapper so this can be used as a decorator via partial()
+    return wrapper
+
+def wraps(wrapped,
+          assigned = WRAPPER_ASSIGNMENTS,
+          updated = WRAPPER_UPDATES):
+    """Decorator factory to apply update_wrapper() to a wrapper function
+
+       Returns a decorator that invokes update_wrapper() with the decorated
+       function as the wrapper argument and the arguments to wraps() as the
+       remaining arguments. Default arguments are as for update_wrapper().
+       This is a convenience function to simplify applying partial() to
+       update_wrapper().
+    """
+    return partial(update_wrapper, wrapped=wrapped,
+                   assigned=assigned, updated=updated)

Added: vendor/Python/current/Lib/getopt.py
===================================================================
--- vendor/Python/current/Lib/getopt.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/getopt.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,211 @@
+# -*- coding: iso-8859-1 -*-
+"""Parser for command line options.
+
+This module helps scripts to parse the command line arguments in
+sys.argv.  It supports the same conventions as the Unix getopt()
+function (including the special meanings of arguments of the form `-'
+and `--').  Long options similar to those supported by GNU software
+may be used as well via an optional third argument.  This module
+provides two functions and an exception:
+
+getopt() -- Parse command line options
+gnu_getopt() -- Like getopt(), but allow option and non-option arguments
+to be intermixed.
+GetoptError -- exception (class) raised with 'opt' attribute, which is the
+option involved with the exception.
+"""
+
+# Long option support added by Lars Wirzenius <liw at iki.fi>.
+#
+# Gerrit Holl <gerrit at nl.linux.org> moved the string-based exceptions
+# to class-based exceptions.
+#
+# Peter Åstrand <astrand at lysator.liu.se> added gnu_getopt().
+#
+# TODO for gnu_getopt():
+#
+# - GNU getopt_long_only mechanism
+# - allow the caller to specify ordering
+# - RETURN_IN_ORDER option
+# - GNU extension with '-' as first character of option string
+# - optional arguments, specified by double colons
+# - a option string with a W followed by semicolon should
+#   treat "-W foo" as "--foo"
+
+__all__ = ["GetoptError","error","getopt","gnu_getopt"]
+
+import os
+
+class GetoptError(Exception):
+    opt = ''
+    msg = ''
+    def __init__(self, msg, opt=''):
+        self.msg = msg
+        self.opt = opt
+        Exception.__init__(self, msg, opt)
+
+    def __str__(self):
+        return self.msg
+
+error = GetoptError # backward compatibility
+
+def getopt(args, shortopts, longopts = []):
+    """getopt(args, options[, long_options]) -> opts, args
+
+    Parses command line options and parameter list.  args is the
+    argument list to be parsed, without the leading reference to the
+    running program.  Typically, this means "sys.argv[1:]".  shortopts
+    is the string of option letters that the script wants to
+    recognize, with options that require an argument followed by a
+    colon (i.e., the same format that Unix getopt() uses).  If
+    specified, longopts is a list of strings with the names of the
+    long options which should be supported.  The leading '--'
+    characters should not be included in the option name.  Options
+    which require an argument should be followed by an equal sign
+    ('=').
+
+    The return value consists of two elements: the first is a list of
+    (option, value) pairs; the second is the list of program arguments
+    left after the option list was stripped (this is a trailing slice
+    of the first argument).  Each option-and-value pair returned has
+    the option as its first element, prefixed with a hyphen (e.g.,
+    '-x'), and the option argument as its second element, or an empty
+    string if the option has no argument.  The options occur in the
+    list in the same order in which they were found, thus allowing
+    multiple occurrences.  Long and short options may be mixed.
+
+    """
+
+    opts = []
+    if type(longopts) == type(""):
+        longopts = [longopts]
+    else:
+        longopts = list(longopts)
+    while args and args[0].startswith('-') and args[0] != '-':
+        if args[0] == '--':
+            args = args[1:]
+            break
+        if args[0].startswith('--'):
+            opts, args = do_longs(opts, args[0][2:], longopts, args[1:])
+        else:
+            opts, args = do_shorts(opts, args[0][1:], shortopts, args[1:])
+
+    return opts, args
+
+def gnu_getopt(args, shortopts, longopts = []):
+    """getopt(args, options[, long_options]) -> opts, args
+
+    This function works like getopt(), except that GNU style scanning
+    mode is used by default. This means that option and non-option
+    arguments may be intermixed. The getopt() function stops
+    processing options as soon as a non-option argument is
+    encountered.
+
+    If the first character of the option string is `+', or if the
+    environment variable POSIXLY_CORRECT is set, then option
+    processing stops as soon as a non-option argument is encountered.
+
+    """
+
+    opts = []
+    prog_args = []
+    if isinstance(longopts, str):
+        longopts = [longopts]
+    else:
+        longopts = list(longopts)
+
+    # Allow options after non-option arguments?
+    if shortopts.startswith('+'):
+        shortopts = shortopts[1:]
+        all_options_first = True
+    elif os.environ.get("POSIXLY_CORRECT"):
+        all_options_first = True
+    else:
+        all_options_first = False
+
+    while args:
+        if args[0] == '--':
+            prog_args += args[1:]
+            break
+
+        if args[0][:2] == '--':
+            opts, args = do_longs(opts, args[0][2:], longopts, args[1:])
+        elif args[0][:1] == '-':
+            opts, args = do_shorts(opts, args[0][1:], shortopts, args[1:])
+        else:
+            if all_options_first:
+                prog_args += args
+                break
+            else:
+                prog_args.append(args[0])
+                args = args[1:]
+
+    return opts, prog_args
+
+def do_longs(opts, opt, longopts, args):
+    try:
+        i = opt.index('=')
+    except ValueError:
+        optarg = None
+    else:
+        opt, optarg = opt[:i], opt[i+1:]
+
+    has_arg, opt = long_has_args(opt, longopts)
+    if has_arg:
+        if optarg is None:
+            if not args:
+                raise GetoptError('option --%s requires argument' % opt, opt)
+            optarg, args = args[0], args[1:]
+    elif optarg:
+        raise GetoptError('option --%s must not have an argument' % opt, opt)
+    opts.append(('--' + opt, optarg or ''))
+    return opts, args
+
+# Return:
+#   has_arg?
+#   full option name
+def long_has_args(opt, longopts):
+    possibilities = [o for o in longopts if o.startswith(opt)]
+    if not possibilities:
+        raise GetoptError('option --%s not recognized' % opt, opt)
+    # Is there an exact match?
+    if opt in possibilities:
+        return False, opt
+    elif opt + '=' in possibilities:
+        return True, opt
+    # No exact match, so better be unique.
+    if len(possibilities) > 1:
+        # XXX since possibilities contains all valid continuations, might be
+        # nice to work them into the error msg
+        raise GetoptError('option --%s not a unique prefix' % opt, opt)
+    assert len(possibilities) == 1
+    unique_match = possibilities[0]
+    has_arg = unique_match.endswith('=')
+    if has_arg:
+        unique_match = unique_match[:-1]
+    return has_arg, unique_match
+
+def do_shorts(opts, optstring, shortopts, args):
+    while optstring != '':
+        opt, optstring = optstring[0], optstring[1:]
+        if short_has_arg(opt, shortopts):
+            if optstring == '':
+                if not args:
+                    raise GetoptError('option -%s requires argument' % opt,
+                                      opt)
+                optstring, args = args[0], args[1:]
+            optarg, optstring = optstring, ''
+        else:
+            optarg = ''
+        opts.append(('-' + opt, optarg))
+    return opts, args
+
+def short_has_arg(opt, shortopts):
+    for i in range(len(shortopts)):
+        if opt == shortopts[i] != ':':
+            return shortopts.startswith(':', i+1)
+    raise GetoptError('option -%s not recognized' % opt, opt)
+
+if __name__ == '__main__':
+    import sys
+    print getopt(sys.argv[1:], "a:b", ["alpha=", "beta"])

Added: vendor/Python/current/Lib/getpass.py
===================================================================
--- vendor/Python/current/Lib/getpass.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/getpass.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,128 @@
+"""Utilities to get a password and/or the current user name.
+
+getpass(prompt) - prompt for a password, with echo turned off
+getuser() - get the user name from the environment or password database
+
+On Windows, the msvcrt module will be used.
+On the Mac EasyDialogs.AskPassword is used, if available.
+
+"""
+
+# Authors: Piers Lauder (original)
+#          Guido van Rossum (Windows support and cleanup)
+
+import sys
+
+__all__ = ["getpass","getuser"]
+
+def unix_getpass(prompt='Password: ', stream=None):
+    """Prompt for a password, with echo turned off.
+    The prompt is written on stream, by default stdout.
+
+    Restore terminal settings at end.
+    """
+    if stream is None:
+        stream = sys.stdout
+
+    try:
+        fd = sys.stdin.fileno()
+    except:
+        return default_getpass(prompt)
+
+    old = termios.tcgetattr(fd)     # a copy to save
+    new = old[:]
+
+    new[3] = new[3] & ~termios.ECHO # 3 == 'lflags'
+    try:
+        termios.tcsetattr(fd, termios.TCSADRAIN, new)
+        passwd = _raw_input(prompt, stream)
+    finally:
+        termios.tcsetattr(fd, termios.TCSADRAIN, old)
+
+    stream.write('\n')
+    return passwd
+
+
+def win_getpass(prompt='Password: ', stream=None):
+    """Prompt for password with echo off, using Windows getch()."""
+    if sys.stdin is not sys.__stdin__:
+        return default_getpass(prompt, stream)
+    import msvcrt
+    for c in prompt:
+        msvcrt.putch(c)
+    pw = ""
+    while 1:
+        c = msvcrt.getch()
+        if c == '\r' or c == '\n':
+            break
+        if c == '\003':
+            raise KeyboardInterrupt
+        if c == '\b':
+            pw = pw[:-1]
+        else:
+            pw = pw + c
+    msvcrt.putch('\r')
+    msvcrt.putch('\n')
+    return pw
+
+
+def default_getpass(prompt='Password: ', stream=None):
+    print >>sys.stderr, "Warning: Problem with getpass. Passwords may be echoed."
+    return _raw_input(prompt, stream)
+
+
+def _raw_input(prompt="", stream=None):
+    # A raw_input() replacement that doesn't save the string in the
+    # GNU readline history.
+    if stream is None:
+        stream = sys.stdout
+    prompt = str(prompt)
+    if prompt:
+        stream.write(prompt)
+    line = sys.stdin.readline()
+    if not line:
+        raise EOFError
+    if line[-1] == '\n':
+        line = line[:-1]
+    return line
+
+
+def getuser():
+    """Get the username from the environment or password database.
+
+    First try various environment variables, then the password
+    database.  This works on Windows as long as USERNAME is set.
+
+    """
+
+    import os
+
+    for name in ('LOGNAME', 'USER', 'LNAME', 'USERNAME'):
+        user = os.environ.get(name)
+        if user:
+            return user
+
+    # If this fails, the exception will "explain" why
+    import pwd
+    return pwd.getpwuid(os.getuid())[0]
+
+# Bind the name getpass to the appropriate function
+try:
+    import termios
+    # it's possible there is an incompatible termios from the
+    # McMillan Installer, make sure we have a UNIX-compatible termios
+    termios.tcgetattr, termios.tcsetattr
+except (ImportError, AttributeError):
+    try:
+        import msvcrt
+    except ImportError:
+        try:
+            from EasyDialogs import AskPassword
+        except ImportError:
+            getpass = default_getpass
+        else:
+            getpass = AskPassword
+    else:
+        getpass = win_getpass
+else:
+    getpass = unix_getpass

Added: vendor/Python/current/Lib/gettext.py
===================================================================
--- vendor/Python/current/Lib/gettext.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/gettext.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,591 @@
+"""Internationalization and localization support.
+
+This module provides internationalization (I18N) and localization (L10N)
+support for your Python programs by providing an interface to the GNU gettext
+message catalog library.
+
+I18N refers to the operation by which a program is made aware of multiple
+languages.  L10N refers to the adaptation of your program, once
+internationalized, to the local language and cultural habits.
+
+"""
+
+# This module represents the integration of work, contributions, feedback, and
+# suggestions from the following people:
+#
+# Martin von Loewis, who wrote the initial implementation of the underlying
+# C-based libintlmodule (later renamed _gettext), along with a skeletal
+# gettext.py implementation.
+#
+# Peter Funk, who wrote fintl.py, a fairly complete wrapper around intlmodule,
+# which also included a pure-Python implementation to read .mo files if
+# intlmodule wasn't available.
+#
+# James Henstridge, who also wrote a gettext.py module, which has some
+# interesting, but currently unsupported experimental features: the notion of
+# a Catalog class and instances, and the ability to add to a catalog file via
+# a Python API.
+#
+# Barry Warsaw integrated these modules, wrote the .install() API and code,
+# and conformed all C and Python code to Python's coding standards.
+#
+# Francois Pinard and Marc-Andre Lemburg also contributed valuably to this
+# module.
+#
+# J. David Ibanez implemented plural forms. Bruno Haible fixed some bugs.
+#
+# TODO:
+# - Lazy loading of .mo files.  Currently the entire catalog is loaded into
+#   memory, but that's probably bad for large translated programs.  Instead,
+#   the lexical sort of original strings in GNU .mo files should be exploited
+#   to do binary searches and lazy initializations.  Or you might want to use
+#   the undocumented double-hash algorithm for .mo files with hash tables, but
+#   you'll need to study the GNU gettext code to do this.
+#
+# - Support Solaris .mo file formats.  Unfortunately, we've been unable to
+#   find this format documented anywhere.
+
+
+import locale, copy, os, re, struct, sys
+from errno import ENOENT
+
+
+__all__ = ['NullTranslations', 'GNUTranslations', 'Catalog',
+           'find', 'translation', 'install', 'textdomain', 'bindtextdomain',
+           'dgettext', 'dngettext', 'gettext', 'ngettext',
+           ]
+
+_default_localedir = os.path.join(sys.prefix, 'share', 'locale')
+
+
+def test(condition, true, false):
+    """
+    Implements the C expression:
+
+      condition ? true : false
+
+    Required to correctly interpret plural forms.
+    """
+    if condition:
+        return true
+    else:
+        return false
+
+
+def c2py(plural):
+    """Gets a C expression as used in PO files for plural forms and returns a
+    Python lambda function that implements an equivalent expression.
+    """
+    # Security check, allow only the "n" identifier
+    try:
+        from cStringIO import StringIO
+    except ImportError:
+        from StringIO import StringIO
+    import token, tokenize
+    tokens = tokenize.generate_tokens(StringIO(plural).readline)
+    try:
+        danger = [x for x in tokens if x[0] == token.NAME and x[1] != 'n']
+    except tokenize.TokenError:
+        raise ValueError, \
+              'plural forms expression error, maybe unbalanced parenthesis'
+    else:
+        if danger:
+            raise ValueError, 'plural forms expression could be dangerous'
+
+    # Replace some C operators by their Python equivalents
+    plural = plural.replace('&&', ' and ')
+    plural = plural.replace('||', ' or ')
+
+    expr = re.compile(r'\!([^=])')
+    plural = expr.sub(' not \\1', plural)
+
+    # Regular expression and replacement function used to transform
+    # "a?b:c" to "test(a,b,c)".
+    expr = re.compile(r'(.*?)\?(.*?):(.*)')
+    def repl(x):
+        return "test(%s, %s, %s)" % (x.group(1), x.group(2),
+                                     expr.sub(repl, x.group(3)))
+
+    # Code to transform the plural expression, taking care of parentheses
+    stack = ['']
+    for c in plural:
+        if c == '(':
+            stack.append('')
+        elif c == ')':
+            if len(stack) == 1:
+                # Actually, we never reach this code, because unbalanced
+                # parentheses get caught in the security check at the
+                # beginning.
+                raise ValueError, 'unbalanced parenthesis in plural form'
+            s = expr.sub(repl, stack.pop())
+            stack[-1] += '(%s)' % s
+        else:
+            stack[-1] += c
+    plural = expr.sub(repl, stack.pop())
+
+    return eval('lambda n: int(%s)' % plural)
+
+
+
+def _expand_lang(locale):
+    from locale import normalize
+    locale = normalize(locale)
+    COMPONENT_CODESET   = 1 << 0
+    COMPONENT_TERRITORY = 1 << 1
+    COMPONENT_MODIFIER  = 1 << 2
+    # split up the locale into its base components
+    mask = 0
+    pos = locale.find('@')
+    if pos >= 0:
+        modifier = locale[pos:]
+        locale = locale[:pos]
+        mask |= COMPONENT_MODIFIER
+    else:
+        modifier = ''
+    pos = locale.find('.')
+    if pos >= 0:
+        codeset = locale[pos:]
+        locale = locale[:pos]
+        mask |= COMPONENT_CODESET
+    else:
+        codeset = ''
+    pos = locale.find('_')
+    if pos >= 0:
+        territory = locale[pos:]
+        locale = locale[:pos]
+        mask |= COMPONENT_TERRITORY
+    else:
+        territory = ''
+    language = locale
+    ret = []
+    for i in range(mask+1):
+        if not (i & ~mask):  # if all components for this combo exist ...
+            val = language
+            if i & COMPONENT_TERRITORY: val += territory
+            if i & COMPONENT_CODESET:   val += codeset
+            if i & COMPONENT_MODIFIER:  val += modifier
+            ret.append(val)
+    ret.reverse()
+    return ret
+
+
+
+class NullTranslations:
+    def __init__(self, fp=None):
+        self._info = {}
+        self._charset = None
+        self._output_charset = None
+        self._fallback = None
+        if fp is not None:
+            self._parse(fp)
+
+    def _parse(self, fp):
+        pass
+
+    def add_fallback(self, fallback):
+        if self._fallback:
+            self._fallback.add_fallback(fallback)
+        else:
+            self._fallback = fallback
+
+    def gettext(self, message):
+        if self._fallback:
+            return self._fallback.gettext(message)
+        return message
+
+    def lgettext(self, message):
+        if self._fallback:
+            return self._fallback.lgettext(message)
+        return message
+
+    def ngettext(self, msgid1, msgid2, n):
+        if self._fallback:
+            return self._fallback.ngettext(msgid1, msgid2, n)
+        if n == 1:
+            return msgid1
+        else:
+            return msgid2
+
+    def lngettext(self, msgid1, msgid2, n):
+        if self._fallback:
+            return self._fallback.lngettext(msgid1, msgid2, n)
+        if n == 1:
+            return msgid1
+        else:
+            return msgid2
+
+    def ugettext(self, message):
+        if self._fallback:
+            return self._fallback.ugettext(message)
+        return unicode(message)
+
+    def ungettext(self, msgid1, msgid2, n):
+        if self._fallback:
+            return self._fallback.ungettext(msgid1, msgid2, n)
+        if n == 1:
+            return unicode(msgid1)
+        else:
+            return unicode(msgid2)
+
+    def info(self):
+        return self._info
+
+    def charset(self):
+        return self._charset
+
+    def output_charset(self):
+        return self._output_charset
+
+    def set_output_charset(self, charset):
+        self._output_charset = charset
+
+    def install(self, unicode=False, names=None):
+        import __builtin__
+        __builtin__.__dict__['_'] = unicode and self.ugettext or self.gettext
+        if hasattr(names, "__contains__"):
+            if "gettext" in names:
+                __builtin__.__dict__['gettext'] = __builtin__.__dict__['_']
+            if "ngettext" in names:
+                __builtin__.__dict__['ngettext'] = (unicode and self.ungettext
+                                                             or self.ngettext)
+            if "lgettext" in names:
+                __builtin__.__dict__['lgettext'] = self.lgettext
+            if "lngettext" in names:
+                __builtin__.__dict__['lngettext'] = self.lngettext
+
+
+class GNUTranslations(NullTranslations):
+    # Magic number of .mo files
+    LE_MAGIC = 0x950412deL
+    BE_MAGIC = 0xde120495L
+
+    def _parse(self, fp):
+        """Override this method to support alternative .mo formats."""
+        unpack = struct.unpack
+        filename = getattr(fp, 'name', '')
+        # Parse the .mo file header, which consists of 5 little endian 32
+        # bit words.
+        self._catalog = catalog = {}
+        self.plural = lambda n: int(n != 1) # germanic plural by default
+        buf = fp.read()
+        buflen = len(buf)
+        # Are we big endian or little endian?
+        magic = unpack('<I', buf[:4])[0]
+        if magic == self.LE_MAGIC:
+            version, msgcount, masteridx, transidx = unpack('<4I', buf[4:20])
+            ii = '<II'
+        elif magic == self.BE_MAGIC:
+            version, msgcount, masteridx, transidx = unpack('>4I', buf[4:20])
+            ii = '>II'
+        else:
+            raise IOError(0, 'Bad magic number', filename)
+        # Now put all messages from the .mo file buffer into the catalog
+        # dictionary.
+        for i in xrange(0, msgcount):
+            mlen, moff = unpack(ii, buf[masteridx:masteridx+8])
+            mend = moff + mlen
+            tlen, toff = unpack(ii, buf[transidx:transidx+8])
+            tend = toff + tlen
+            if mend < buflen and tend < buflen:
+                msg = buf[moff:mend]
+                tmsg = buf[toff:tend]
+            else:
+                raise IOError(0, 'File is corrupt', filename)
+            # See if we're looking at GNU .mo conventions for metadata
+            if mlen == 0:
+                # Catalog description
+                lastk = k = None
+                for item in tmsg.splitlines():
+                    item = item.strip()
+                    if not item:
+                        continue
+                    if ':' in item:
+                        k, v = item.split(':', 1)
+                        k = k.strip().lower()
+                        v = v.strip()
+                        self._info[k] = v
+                        lastk = k
+                    elif lastk:
+                        self._info[lastk] += '\n' + item
+                    if k == 'content-type':
+                        self._charset = v.split('charset=')[1]
+                    elif k == 'plural-forms':
+                        v = v.split(';')
+                        plural = v[1].split('plural=')[1]
+                        self.plural = c2py(plural)
+            # Note: we unconditionally convert both msgids and msgstrs to
+            # Unicode using the character encoding specified in the charset
+            # parameter of the Content-Type header.  The gettext documentation
+            # strongly encourages msgids to be us-ascii, but some appliations
+            # require alternative encodings (e.g. Zope's ZCML and ZPT).  For
+            # traditional gettext applications, the msgid conversion will
+            # cause no problems since us-ascii should always be a subset of
+            # the charset encoding.  We may want to fall back to 8-bit msgids
+            # if the Unicode conversion fails.
+            if '\x00' in msg:
+                # Plural forms
+                msgid1, msgid2 = msg.split('\x00')
+                tmsg = tmsg.split('\x00')
+                if self._charset:
+                    msgid1 = unicode(msgid1, self._charset)
+                    tmsg = [unicode(x, self._charset) for x in tmsg]
+                for i in range(len(tmsg)):
+                    catalog[(msgid1, i)] = tmsg[i]
+            else:
+                if self._charset:
+                    msg = unicode(msg, self._charset)
+                    tmsg = unicode(tmsg, self._charset)
+                catalog[msg] = tmsg
+            # advance to next entry in the seek tables
+            masteridx += 8
+            transidx += 8
+
+    def gettext(self, message):
+        missing = object()
+        tmsg = self._catalog.get(message, missing)
+        if tmsg is missing:
+            if self._fallback:
+                return self._fallback.gettext(message)
+            return message
+        # Encode the Unicode tmsg back to an 8-bit string, if possible
+        if self._output_charset:
+            return tmsg.encode(self._output_charset)
+        elif self._charset:
+            return tmsg.encode(self._charset)
+        return tmsg
+
+    def lgettext(self, message):
+        missing = object()
+        tmsg = self._catalog.get(message, missing)
+        if tmsg is missing:
+            if self._fallback:
+                return self._fallback.lgettext(message)
+            return message
+        if self._output_charset:
+            return tmsg.encode(self._output_charset)
+        return tmsg.encode(locale.getpreferredencoding())
+
+    def ngettext(self, msgid1, msgid2, n):
+        try:
+            tmsg = self._catalog[(msgid1, self.plural(n))]
+            if self._output_charset:
+                return tmsg.encode(self._output_charset)
+            elif self._charset:
+                return tmsg.encode(self._charset)
+            return tmsg
+        except KeyError:
+            if self._fallback:
+                return self._fallback.ngettext(msgid1, msgid2, n)
+            if n == 1:
+                return msgid1
+            else:
+                return msgid2
+
+    def lngettext(self, msgid1, msgid2, n):
+        try:
+            tmsg = self._catalog[(msgid1, self.plural(n))]
+            if self._output_charset:
+                return tmsg.encode(self._output_charset)
+            return tmsg.encode(locale.getpreferredencoding())
+        except KeyError:
+            if self._fallback:
+                return self._fallback.lngettext(msgid1, msgid2, n)
+            if n == 1:
+                return msgid1
+            else:
+                return msgid2
+
+    def ugettext(self, message):
+        missing = object()
+        tmsg = self._catalog.get(message, missing)
+        if tmsg is missing:
+            if self._fallback:
+                return self._fallback.ugettext(message)
+            return unicode(message)
+        return tmsg
+
+    def ungettext(self, msgid1, msgid2, n):
+        try:
+            tmsg = self._catalog[(msgid1, self.plural(n))]
+        except KeyError:
+            if self._fallback:
+                return self._fallback.ungettext(msgid1, msgid2, n)
+            if n == 1:
+                tmsg = unicode(msgid1)
+            else:
+                tmsg = unicode(msgid2)
+        return tmsg
+
+
+# Locate a .mo file using the gettext strategy
+def find(domain, localedir=None, languages=None, all=0):
+    # Get some reasonable defaults for arguments that were not supplied
+    if localedir is None:
+        localedir = _default_localedir
+    if languages is None:
+        languages = []
+        for envar in ('LANGUAGE', 'LC_ALL', 'LC_MESSAGES', 'LANG'):
+            val = os.environ.get(envar)
+            if val:
+                languages = val.split(':')
+                break
+        if 'C' not in languages:
+            languages.append('C')
+    # now normalize and expand the languages
+    nelangs = []
+    for lang in languages:
+        for nelang in _expand_lang(lang):
+            if nelang not in nelangs:
+                nelangs.append(nelang)
+    # select a language
+    if all:
+        result = []
+    else:
+        result = None
+    for lang in nelangs:
+        if lang == 'C':
+            break
+        mofile = os.path.join(localedir, lang, 'LC_MESSAGES', '%s.mo' % domain)
+        if os.path.exists(mofile):
+            if all:
+                result.append(mofile)
+            else:
+                return mofile
+    return result
+
+
+
+# a mapping between absolute .mo file path and Translation object
+_translations = {}
+
+def translation(domain, localedir=None, languages=None,
+                class_=None, fallback=False, codeset=None):
+    if class_ is None:
+        class_ = GNUTranslations
+    mofiles = find(domain, localedir, languages, all=1)
+    if not mofiles:
+        if fallback:
+            return NullTranslations()
+        raise IOError(ENOENT, 'No translation file found for domain', domain)
+    # TBD: do we need to worry about the file pointer getting collected?
+    # Avoid opening, reading, and parsing the .mo file after it's been done
+    # once.
+    result = None
+    for mofile in mofiles:
+        key = os.path.abspath(mofile)
+        t = _translations.get(key)
+        if t is None:
+            t = _translations.setdefault(key, class_(open(mofile, 'rb')))
+        # Copy the translation object to allow setting fallbacks and
+        # output charset. All other instance data is shared with the
+        # cached object.
+        t = copy.copy(t)
+        if codeset:
+            t.set_output_charset(codeset)
+        if result is None:
+            result = t
+        else:
+            result.add_fallback(t)
+    return result
+
+
+def install(domain, localedir=None, unicode=False, codeset=None, names=None):
+    t = translation(domain, localedir, fallback=True, codeset=codeset)
+    t.install(unicode, names)
+
+
+
+# a mapping b/w domains and locale directories
+_localedirs = {}
+# a mapping b/w domains and codesets
+_localecodesets = {}
+# current global domain, `messages' used for compatibility w/ GNU gettext
+_current_domain = 'messages'
+
+
+def textdomain(domain=None):
+    global _current_domain
+    if domain is not None:
+        _current_domain = domain
+    return _current_domain
+
+
+def bindtextdomain(domain, localedir=None):
+    global _localedirs
+    if localedir is not None:
+        _localedirs[domain] = localedir
+    return _localedirs.get(domain, _default_localedir)
+
+
+def bind_textdomain_codeset(domain, codeset=None):
+    global _localecodesets
+    if codeset is not None:
+        _localecodesets[domain] = codeset
+    return _localecodesets.get(domain)
+
+
+def dgettext(domain, message):
+    try:
+        t = translation(domain, _localedirs.get(domain, None),
+                        codeset=_localecodesets.get(domain))
+    except IOError:
+        return message
+    return t.gettext(message)
+
+def ldgettext(domain, message):
+    try:
+        t = translation(domain, _localedirs.get(domain, None),
+                        codeset=_localecodesets.get(domain))
+    except IOError:
+        return message
+    return t.lgettext(message)
+
+def dngettext(domain, msgid1, msgid2, n):
+    try:
+        t = translation(domain, _localedirs.get(domain, None),
+                        codeset=_localecodesets.get(domain))
+    except IOError:
+        if n == 1:
+            return msgid1
+        else:
+            return msgid2
+    return t.ngettext(msgid1, msgid2, n)
+
+def ldngettext(domain, msgid1, msgid2, n):
+    try:
+        t = translation(domain, _localedirs.get(domain, None),
+                        codeset=_localecodesets.get(domain))
+    except IOError:
+        if n == 1:
+            return msgid1
+        else:
+            return msgid2
+    return t.lngettext(msgid1, msgid2, n)
+
+def gettext(message):
+    return dgettext(_current_domain, message)
+
+def lgettext(message):
+    return ldgettext(_current_domain, message)
+
+def ngettext(msgid1, msgid2, n):
+    return dngettext(_current_domain, msgid1, msgid2, n)
+
+def lngettext(msgid1, msgid2, n):
+    return ldngettext(_current_domain, msgid1, msgid2, n)
+
+# dcgettext() has been deemed unnecessary and is not implemented.
+
+# James Henstridge's Catalog constructor from GNOME gettext.  Documented usage
+# was:
+#
+#    import gettext
+#    cat = gettext.Catalog(PACKAGE, localedir=LOCALEDIR)
+#    _ = cat.gettext
+#    print _('Hello World')
+
+# The resulting catalog object currently don't support access through a
+# dictionary API, which was supported (but apparently unused) in GNOME
+# gettext.
+
+Catalog = translation

Added: vendor/Python/current/Lib/glob.py
===================================================================
--- vendor/Python/current/Lib/glob.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/glob.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,74 @@
+"""Filename globbing utility."""
+
+import os
+import fnmatch
+import re
+
+__all__ = ["glob", "iglob"]
+
+def glob(pathname):
+    """Return a list of paths matching a pathname pattern.
+
+    The pattern may contain simple shell-style wildcards a la fnmatch.
+
+    """
+    return list(iglob(pathname))
+
+def iglob(pathname):
+    """Return a list of paths matching a pathname pattern.
+
+    The pattern may contain simple shell-style wildcards a la fnmatch.
+
+    """
+    if not has_magic(pathname):
+        if os.path.lexists(pathname):
+            yield pathname
+        return
+    dirname, basename = os.path.split(pathname)
+    if not dirname:
+        for name in glob1(os.curdir, basename):
+            yield name
+        return
+    if has_magic(dirname):
+        dirs = iglob(dirname)
+    else:
+        dirs = [dirname]
+    if has_magic(basename):
+        glob_in_dir = glob1
+    else:
+        glob_in_dir = glob0
+    for dirname in dirs:
+        for name in glob_in_dir(dirname, basename):
+            yield os.path.join(dirname, name)
+
+# These 2 helper functions non-recursively glob inside a literal directory.
+# They return a list of basenames. `glob1` accepts a pattern while `glob0`
+# takes a literal basename (so it only has to check for its existence).
+
+def glob1(dirname, pattern):
+    if not dirname:
+        dirname = os.curdir
+    try:
+        names = os.listdir(dirname)
+    except os.error:
+        return []
+    if pattern[0]!='.':
+        names=filter(lambda x: x[0]!='.',names)
+    return fnmatch.filter(names,pattern)
+
+def glob0(dirname, basename):
+    if basename == '':
+        # `os.path.split()` returns an empty basename for paths ending with a
+        # directory separator.  'q*x/' should match only directories.
+        if os.path.isdir(dirname):
+            return [basename]
+    else:
+        if os.path.lexists(os.path.join(dirname, basename)):
+            return [basename]
+    return []
+
+
+magic_check = re.compile('[*?[]')
+
+def has_magic(s):
+    return magic_check.search(s) is not None

Added: vendor/Python/current/Lib/gopherlib.py
===================================================================
--- vendor/Python/current/Lib/gopherlib.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/gopherlib.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,209 @@
+"""Gopher protocol client interface."""
+
+__all__ = ["send_selector","send_query"]
+
+import warnings
+warnings.warn("the gopherlib module is deprecated", DeprecationWarning,
+              stacklevel=2)
+
+# Default selector, host and port
+DEF_SELECTOR = '1/'
+DEF_HOST     = 'gopher.micro.umn.edu'
+DEF_PORT     = 70
+
+# Recognized file types
+A_TEXT       = '0'
+A_MENU       = '1'
+A_CSO        = '2'
+A_ERROR      = '3'
+A_MACBINHEX  = '4'
+A_PCBINHEX   = '5'
+A_UUENCODED  = '6'
+A_INDEX      = '7'
+A_TELNET     = '8'
+A_BINARY     = '9'
+A_DUPLICATE  = '+'
+A_SOUND      = 's'
+A_EVENT      = 'e'
+A_CALENDAR   = 'c'
+A_HTML       = 'h'
+A_TN3270     = 'T'
+A_MIME       = 'M'
+A_IMAGE      = 'I'
+A_WHOIS      = 'w'
+A_QUERY      = 'q'
+A_GIF        = 'g'
+A_HTML       = 'h'          # HTML file
+A_WWW        = 'w'          # WWW address
+A_PLUS_IMAGE = ':'
+A_PLUS_MOVIE = ';'
+A_PLUS_SOUND = '<'
+
+
+_names = dir()
+_type_to_name_map = {}
+def type_to_name(gtype):
+    """Map all file types to strings; unknown types become TYPE='x'."""
+    global _type_to_name_map
+    if _type_to_name_map=={}:
+        for name in _names:
+            if name[:2] == 'A_':
+                _type_to_name_map[eval(name)] = name[2:]
+    if gtype in _type_to_name_map:
+        return _type_to_name_map[gtype]
+    return 'TYPE=%r' % (gtype,)
+
+# Names for characters and strings
+CRLF = '\r\n'
+TAB = '\t'
+
+def send_selector(selector, host, port = 0):
+    """Send a selector to a given host and port, return a file with the reply."""
+    import socket
+    if not port:
+        i = host.find(':')
+        if i >= 0:
+            host, port = host[:i], int(host[i+1:])
+    if not port:
+        port = DEF_PORT
+    elif type(port) == type(''):
+        port = int(port)
+    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+    s.connect((host, port))
+    s.sendall(selector + CRLF)
+    s.shutdown(1)
+    return s.makefile('rb')
+
+def send_query(selector, query, host, port = 0):
+    """Send a selector and a query string."""
+    return send_selector(selector + '\t' + query, host, port)
+
+def path_to_selector(path):
+    """Takes a path as returned by urlparse and returns the appropriate selector."""
+    if path=="/":
+        return "/"
+    else:
+        return path[2:] # Cuts initial slash and data type identifier
+
+def path_to_datatype_name(path):
+    """Takes a path as returned by urlparse and maps it to a string.
+    See section 3.4 of RFC 1738 for details."""
+    if path=="/":
+        # No way to tell, although "INDEX" is likely
+        return "TYPE='unknown'"
+    else:
+        return type_to_name(path[1])
+
+# The following functions interpret the data returned by the gopher
+# server according to the expected type, e.g. textfile or directory
+
+def get_directory(f):
+    """Get a directory in the form of a list of entries."""
+    entries = []
+    while 1:
+        line = f.readline()
+        if not line:
+            print '(Unexpected EOF from server)'
+            break
+        if line[-2:] == CRLF:
+            line = line[:-2]
+        elif line[-1:] in CRLF:
+            line = line[:-1]
+        if line == '.':
+            break
+        if not line:
+            print '(Empty line from server)'
+            continue
+        gtype = line[0]
+        parts = line[1:].split(TAB)
+        if len(parts) < 4:
+            print '(Bad line from server: %r)' % (line,)
+            continue
+        if len(parts) > 4:
+            if parts[4:] != ['+']:
+                print '(Extra info from server:',
+                print parts[4:], ')'
+        else:
+            parts.append('')
+        parts.insert(0, gtype)
+        entries.append(parts)
+    return entries
+
+def get_textfile(f):
+    """Get a text file as a list of lines, with trailing CRLF stripped."""
+    lines = []
+    get_alt_textfile(f, lines.append)
+    return lines
+
+def get_alt_textfile(f, func):
+    """Get a text file and pass each line to a function, with trailing CRLF stripped."""
+    while 1:
+        line = f.readline()
+        if not line:
+            print '(Unexpected EOF from server)'
+            break
+        if line[-2:] == CRLF:
+            line = line[:-2]
+        elif line[-1:] in CRLF:
+            line = line[:-1]
+        if line == '.':
+            break
+        if line[:2] == '..':
+            line = line[1:]
+        func(line)
+
+def get_binary(f):
+    """Get a binary file as one solid data block."""
+    data = f.read()
+    return data
+
+def get_alt_binary(f, func, blocksize):
+    """Get a binary file and pass each block to a function."""
+    while 1:
+        data = f.read(blocksize)
+        if not data:
+            break
+        func(data)
+
+def test():
+    """Trivial test program."""
+    import sys
+    import getopt
+    opts, args = getopt.getopt(sys.argv[1:], '')
+    selector = DEF_SELECTOR
+    type = selector[0]
+    host = DEF_HOST
+    if args:
+        host = args[0]
+        args = args[1:]
+    if args:
+        type = args[0]
+        args = args[1:]
+        if len(type) > 1:
+            type, selector = type[0], type
+        else:
+            selector = ''
+            if args:
+                selector = args[0]
+                args = args[1:]
+        query = ''
+        if args:
+            query = args[0]
+            args = args[1:]
+    if type == A_INDEX:
+        f = send_query(selector, query, host)
+    else:
+        f = send_selector(selector, host)
+    if type == A_TEXT:
+        lines = get_textfile(f)
+        for item in lines: print item
+    elif type in (A_MENU, A_INDEX):
+        entries = get_directory(f)
+        for item in entries: print item
+    else:
+        data = get_binary(f)
+        print 'binary data:', len(data), 'bytes:', repr(data[:100])[:40]
+
+# Run the test when run as script
+if __name__ == '__main__':
+    test()

Added: vendor/Python/current/Lib/gzip.py
===================================================================
--- vendor/Python/current/Lib/gzip.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/gzip.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,490 @@
+"""Functions that read and write gzipped files.
+
+The user of the file doesn't have to worry about the compression,
+but random access is not allowed."""
+
+# based on Andrew Kuchling's minigzip.py distributed with the zlib module
+
+import struct, sys, time
+import zlib
+import __builtin__
+
+__all__ = ["GzipFile","open"]
+
+FTEXT, FHCRC, FEXTRA, FNAME, FCOMMENT = 1, 2, 4, 8, 16
+
+READ, WRITE = 1, 2
+
+def U32(i):
+    """Return i as an unsigned integer, assuming it fits in 32 bits.
+
+    If it's >= 2GB when viewed as a 32-bit unsigned int, return a long.
+    """
+    if i < 0:
+        i += 1L << 32
+    return i
+
+def LOWU32(i):
+    """Return the low-order 32 bits of an int, as a non-negative int."""
+    return i & 0xFFFFFFFFL
+
+def write32(output, value):
+    output.write(struct.pack("<l", value))
+
+def write32u(output, value):
+    # The L format writes the bit pattern correctly whether signed
+    # or unsigned.
+    output.write(struct.pack("<L", value))
+
+def read32(input):
+    return struct.unpack("<l", input.read(4))[0]
+
+def open(filename, mode="rb", compresslevel=9):
+    """Shorthand for GzipFile(filename, mode, compresslevel).
+
+    The filename argument is required; mode defaults to 'rb'
+    and compresslevel defaults to 9.
+
+    """
+    return GzipFile(filename, mode, compresslevel)
+
+class GzipFile:
+    """The GzipFile class simulates most of the methods of a file object with
+    the exception of the readinto() and truncate() methods.
+
+    """
+
+    myfileobj = None
+    max_read_chunk = 10 * 1024 * 1024   # 10Mb
+
+    def __init__(self, filename=None, mode=None,
+                 compresslevel=9, fileobj=None):
+        """Constructor for the GzipFile class.
+
+        At least one of fileobj and filename must be given a
+        non-trivial value.
+
+        The new class instance is based on fileobj, which can be a regular
+        file, a StringIO object, or any other object which simulates a file.
+        It defaults to None, in which case filename is opened to provide
+        a file object.
+
+        When fileobj is not None, the filename argument is only used to be
+        included in the gzip file header, which may includes the original
+        filename of the uncompressed file.  It defaults to the filename of
+        fileobj, if discernible; otherwise, it defaults to the empty string,
+        and in this case the original filename is not included in the header.
+
+        The mode argument can be any of 'r', 'rb', 'a', 'ab', 'w', or 'wb',
+        depending on whether the file will be read or written.  The default
+        is the mode of fileobj if discernible; otherwise, the default is 'rb'.
+        Be aware that only the 'rb', 'ab', and 'wb' values should be used
+        for cross-platform portability.
+
+        The compresslevel argument is an integer from 1 to 9 controlling the
+        level of compression; 1 is fastest and produces the least compression,
+        and 9 is slowest and produces the most compression.  The default is 9.
+
+        """
+
+        # guarantee the file is opened in binary mode on platforms
+        # that care about that sort of thing
+        if mode and 'b' not in mode:
+            mode += 'b'
+        if fileobj is None:
+            fileobj = self.myfileobj = __builtin__.open(filename, mode or 'rb')
+        if filename is None:
+            if hasattr(fileobj, 'name'): filename = fileobj.name
+            else: filename = ''
+        if mode is None:
+            if hasattr(fileobj, 'mode'): mode = fileobj.mode
+            else: mode = 'rb'
+
+        if mode[0:1] == 'r':
+            self.mode = READ
+            # Set flag indicating start of a new member
+            self._new_member = True
+            self.extrabuf = ""
+            self.extrasize = 0
+            self.filename = filename
+            # Starts small, scales exponentially
+            self.min_readsize = 100
+
+        elif mode[0:1] == 'w' or mode[0:1] == 'a':
+            self.mode = WRITE
+            self._init_write(filename)
+            self.compress = zlib.compressobj(compresslevel,
+                                             zlib.DEFLATED,
+                                             -zlib.MAX_WBITS,
+                                             zlib.DEF_MEM_LEVEL,
+                                             0)
+        else:
+            raise IOError, "Mode " + mode + " not supported"
+
+        self.fileobj = fileobj
+        self.offset = 0
+
+        if self.mode == WRITE:
+            self._write_gzip_header()
+
+    def __repr__(self):
+        s = repr(self.fileobj)
+        return '<gzip ' + s[1:-1] + ' ' + hex(id(self)) + '>'
+
+    def _init_write(self, filename):
+        if filename[-3:] != '.gz':
+            filename = filename + '.gz'
+        self.filename = filename
+        self.crc = zlib.crc32("")
+        self.size = 0
+        self.writebuf = []
+        self.bufsize = 0
+
+    def _write_gzip_header(self):
+        self.fileobj.write('\037\213')             # magic header
+        self.fileobj.write('\010')                 # compression method
+        fname = self.filename[:-3]
+        flags = 0
+        if fname:
+            flags = FNAME
+        self.fileobj.write(chr(flags))
+        write32u(self.fileobj, long(time.time()))
+        self.fileobj.write('\002')
+        self.fileobj.write('\377')
+        if fname:
+            self.fileobj.write(fname + '\000')
+
+    def _init_read(self):
+        self.crc = zlib.crc32("")
+        self.size = 0
+
+    def _read_gzip_header(self):
+        magic = self.fileobj.read(2)
+        if magic != '\037\213':
+            raise IOError, 'Not a gzipped file'
+        method = ord( self.fileobj.read(1) )
+        if method != 8:
+            raise IOError, 'Unknown compression method'
+        flag = ord( self.fileobj.read(1) )
+        # modtime = self.fileobj.read(4)
+        # extraflag = self.fileobj.read(1)
+        # os = self.fileobj.read(1)
+        self.fileobj.read(6)
+
+        if flag & FEXTRA:
+            # Read & discard the extra field, if present
+            xlen = ord(self.fileobj.read(1))
+            xlen = xlen + 256*ord(self.fileobj.read(1))
+            self.fileobj.read(xlen)
+        if flag & FNAME:
+            # Read and discard a null-terminated string containing the filename
+            while True:
+                s = self.fileobj.read(1)
+                if not s or s=='\000':
+                    break
+        if flag & FCOMMENT:
+            # Read and discard a null-terminated string containing a comment
+            while True:
+                s = self.fileobj.read(1)
+                if not s or s=='\000':
+                    break
+        if flag & FHCRC:
+            self.fileobj.read(2)     # Read & discard the 16-bit header CRC
+
+
+    def write(self,data):
+        if self.mode != WRITE:
+            import errno
+            raise IOError(errno.EBADF, "write() on read-only GzipFile object")
+
+        if self.fileobj is None:
+            raise ValueError, "write() on closed GzipFile object"
+        if len(data) > 0:
+            self.size = self.size + len(data)
+            self.crc = zlib.crc32(data, self.crc)
+            self.fileobj.write( self.compress.compress(data) )
+            self.offset += len(data)
+
+    def read(self, size=-1):
+        if self.mode != READ:
+            import errno
+            raise IOError(errno.EBADF, "read() on write-only GzipFile object")
+
+        if self.extrasize <= 0 and self.fileobj is None:
+            return ''
+
+        readsize = 1024
+        if size < 0:        # get the whole thing
+            try:
+                while True:
+                    self._read(readsize)
+                    readsize = min(self.max_read_chunk, readsize * 2)
+            except EOFError:
+                size = self.extrasize
+        else:               # just get some more of it
+            try:
+                while size > self.extrasize:
+                    self._read(readsize)
+                    readsize = min(self.max_read_chunk, readsize * 2)
+            except EOFError:
+                if size > self.extrasize:
+                    size = self.extrasize
+
+        chunk = self.extrabuf[:size]
+        self.extrabuf = self.extrabuf[size:]
+        self.extrasize = self.extrasize - size
+
+        self.offset += size
+        return chunk
+
+    def _unread(self, buf):
+        self.extrabuf = buf + self.extrabuf
+        self.extrasize = len(buf) + self.extrasize
+        self.offset -= len(buf)
+
+    def _read(self, size=1024):
+        if self.fileobj is None:
+            raise EOFError, "Reached EOF"
+
+        if self._new_member:
+            # If the _new_member flag is set, we have to
+            # jump to the next member, if there is one.
+            #
+            # First, check if we're at the end of the file;
+            # if so, it's time to stop; no more members to read.
+            pos = self.fileobj.tell()   # Save current position
+            self.fileobj.seek(0, 2)     # Seek to end of file
+            if pos == self.fileobj.tell():
+                raise EOFError, "Reached EOF"
+            else:
+                self.fileobj.seek( pos ) # Return to original position
+
+            self._init_read()
+            self._read_gzip_header()
+            self.decompress = zlib.decompressobj(-zlib.MAX_WBITS)
+            self._new_member = False
+
+        # Read a chunk of data from the file
+        buf = self.fileobj.read(size)
+
+        # If the EOF has been reached, flush the decompression object
+        # and mark this object as finished.
+
+        if buf == "":
+            uncompress = self.decompress.flush()
+            self._read_eof()
+            self._add_read_data( uncompress )
+            raise EOFError, 'Reached EOF'
+
+        uncompress = self.decompress.decompress(buf)
+        self._add_read_data( uncompress )
+
+        if self.decompress.unused_data != "":
+            # Ending case: we've come to the end of a member in the file,
+            # so seek back to the start of the unused data, finish up
+            # this member, and read a new gzip header.
+            # (The number of bytes to seek back is the length of the unused
+            # data, minus 8 because _read_eof() will rewind a further 8 bytes)
+            self.fileobj.seek( -len(self.decompress.unused_data)+8, 1)
+
+            # Check the CRC and file size, and set the flag so we read
+            # a new member on the next call
+            self._read_eof()
+            self._new_member = True
+
+    def _add_read_data(self, data):
+        self.crc = zlib.crc32(data, self.crc)
+        self.extrabuf = self.extrabuf + data
+        self.extrasize = self.extrasize + len(data)
+        self.size = self.size + len(data)
+
+    def _read_eof(self):
+        # We've read to the end of the file, so we have to rewind in order
+        # to reread the 8 bytes containing the CRC and the file size.
+        # We check the that the computed CRC and size of the
+        # uncompressed data matches the stored values.  Note that the size
+        # stored is the true file size mod 2**32.
+        self.fileobj.seek(-8, 1)
+        crc32 = read32(self.fileobj)
+        isize = U32(read32(self.fileobj))   # may exceed 2GB
+        if U32(crc32) != U32(self.crc):
+            raise IOError, "CRC check failed"
+        elif isize != LOWU32(self.size):
+            raise IOError, "Incorrect length of data produced"
+
+    def close(self):
+        if self.mode == WRITE:
+            self.fileobj.write(self.compress.flush())
+            # The native zlib crc is an unsigned 32-bit integer, but
+            # the Python wrapper implicitly casts that to a signed C
+            # long.  So, on a 32-bit box self.crc may "look negative",
+            # while the same crc on a 64-bit box may "look positive".
+            # To avoid irksome warnings from the `struct` module, force
+            # it to look positive on all boxes.
+            write32u(self.fileobj, LOWU32(self.crc))
+            # self.size may exceed 2GB, or even 4GB
+            write32u(self.fileobj, LOWU32(self.size))
+            self.fileobj = None
+        elif self.mode == READ:
+            self.fileobj = None
+        if self.myfileobj:
+            self.myfileobj.close()
+            self.myfileobj = None
+
+    def __del__(self):
+        try:
+            if (self.myfileobj is None and
+                self.fileobj is None):
+                return
+        except AttributeError:
+            return
+        self.close()
+
+    def flush(self,zlib_mode=zlib.Z_SYNC_FLUSH):
+        if self.mode == WRITE:
+            # Ensure the compressor's buffer is flushed
+            self.fileobj.write(self.compress.flush(zlib_mode))
+        self.fileobj.flush()
+
+    def fileno(self):
+        """Invoke the underlying file object's fileno() method.
+
+        This will raise AttributeError if the underlying file object
+        doesn't support fileno().
+        """
+        return self.fileobj.fileno()
+
+    def isatty(self):
+        return False
+
+    def tell(self):
+        return self.offset
+
+    def rewind(self):
+        '''Return the uncompressed stream file position indicator to the
+        beginning of the file'''
+        if self.mode != READ:
+            raise IOError("Can't rewind in write mode")
+        self.fileobj.seek(0)
+        self._new_member = True
+        self.extrabuf = ""
+        self.extrasize = 0
+        self.offset = 0
+
+    def seek(self, offset):
+        if self.mode == WRITE:
+            if offset < self.offset:
+                raise IOError('Negative seek in write mode')
+            count = offset - self.offset
+            for i in range(count // 1024):
+                self.write(1024 * '\0')
+            self.write((count % 1024) * '\0')
+        elif self.mode == READ:
+            if offset < self.offset:
+                # for negative seek, rewind and do positive seek
+                self.rewind()
+            count = offset - self.offset
+            for i in range(count // 1024):
+                self.read(1024)
+            self.read(count % 1024)
+
+    def readline(self, size=-1):
+        if size < 0:
+            size = sys.maxint
+            readsize = self.min_readsize
+        else:
+            readsize = size
+        bufs = []
+        while size != 0:
+            c = self.read(readsize)
+            i = c.find('\n')
+
+            # We set i=size to break out of the loop under two
+            # conditions: 1) there's no newline, and the chunk is
+            # larger than size, or 2) there is a newline, but the
+            # resulting line would be longer than 'size'.
+            if (size <= i) or (i == -1 and len(c) > size):
+                i = size - 1
+
+            if i >= 0 or c == '':
+                bufs.append(c[:i + 1])    # Add portion of last chunk
+                self._unread(c[i + 1:])   # Push back rest of chunk
+                break
+
+            # Append chunk to list, decrease 'size',
+            bufs.append(c)
+            size = size - len(c)
+            readsize = min(size, readsize * 2)
+        if readsize > self.min_readsize:
+            self.min_readsize = min(readsize, self.min_readsize * 2, 512)
+        return ''.join(bufs) # Return resulting line
+
+    def readlines(self, sizehint=0):
+        # Negative numbers result in reading all the lines
+        if sizehint <= 0:
+            sizehint = sys.maxint
+        L = []
+        while sizehint > 0:
+            line = self.readline()
+            if line == "":
+                break
+            L.append(line)
+            sizehint = sizehint - len(line)
+
+        return L
+
+    def writelines(self, L):
+        for line in L:
+            self.write(line)
+
+    def __iter__(self):
+        return self
+
+    def next(self):
+        line = self.readline()
+        if line:
+            return line
+        else:
+            raise StopIteration
+
+
+def _test():
+    # Act like gzip; with -d, act like gunzip.
+    # The input file is not deleted, however, nor are any other gzip
+    # options or features supported.
+    args = sys.argv[1:]
+    decompress = args and args[0] == "-d"
+    if decompress:
+        args = args[1:]
+    if not args:
+        args = ["-"]
+    for arg in args:
+        if decompress:
+            if arg == "-":
+                f = GzipFile(filename="", mode="rb", fileobj=sys.stdin)
+                g = sys.stdout
+            else:
+                if arg[-3:] != ".gz":
+                    print "filename doesn't end in .gz:", repr(arg)
+                    continue
+                f = open(arg, "rb")
+                g = __builtin__.open(arg[:-3], "wb")
+        else:
+            if arg == "-":
+                f = sys.stdin
+                g = GzipFile(filename="", mode="wb", fileobj=sys.stdout)
+            else:
+                f = __builtin__.open(arg, "rb")
+                g = open(arg + ".gz", "wb")
+        while True:
+            chunk = f.read(1024)
+            if not chunk:
+                break
+            g.write(chunk)
+        if g is not sys.stdout:
+            g.close()
+        if f is not sys.stdin:
+            f.close()
+
+if __name__ == '__main__':
+    _test()

Added: vendor/Python/current/Lib/hashlib.py
===================================================================
--- vendor/Python/current/Lib/hashlib.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/hashlib.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,138 @@
+# $Id: hashlib.py 52533 2006-10-29 18:01:12Z georg.brandl $
+#
+#  Copyright (C) 2005   Gregory P. Smith (greg at electricrain.com)
+#  Licensed to PSF under a Contributor Agreement.
+#
+
+__doc__ = """hashlib module - A common interface to many hash functions.
+
+new(name, string='') - returns a new hash object implementing the
+                       given hash function; initializing the hash
+                       using the given string data.
+
+Named constructor functions are also available, these are much faster
+than using new():
+
+md5(), sha1(), sha224(), sha256(), sha384(), and sha512()
+
+More algorithms may be available on your platform but the above are
+guaranteed to exist.
+
+Choose your hash function wisely.  Some have known collision weaknesses.
+sha384 and sha512 will be slow on 32 bit platforms.
+
+Hash objects have these methods:
+ - update(arg): Update the hash object with the string arg. Repeated calls
+                are equivalent to a single call with the concatenation of all
+                the arguments.
+ - digest():    Return the digest of the strings passed to the update() method
+                so far. This may contain non-ASCII characters, including
+                NUL bytes.
+ - hexdigest(): Like digest() except the digest is returned as a string of
+                double length, containing only hexadecimal digits.
+ - copy():      Return a copy (clone) of the hash object. This can be used to
+                efficiently compute the digests of strings that share a common
+                initial substring.
+
+For example, to obtain the digest of the string 'Nobody inspects the
+spammish repetition':
+
+    >>> import hashlib
+    >>> m = hashlib.md5()
+    >>> m.update("Nobody inspects")
+    >>> m.update(" the spammish repetition")
+    >>> m.digest()
+    '\xbbd\x9c\x83\xdd\x1e\xa5\xc9\xd9\xde\xc9\xa1\x8d\xf0\xff\xe9'
+
+More condensed:
+
+    >>> hashlib.sha224("Nobody inspects the spammish repetition").hexdigest()
+    'a4337bc45a8fc544c03f52dc550cd6e1e87021bc896588bd79e901e2'
+
+"""
+
+
+def __get_builtin_constructor(name):
+    if name in ('SHA1', 'sha1'):
+        import _sha
+        return _sha.new
+    elif name in ('MD5', 'md5'):
+        import _md5
+        return _md5.new
+    elif name in ('SHA256', 'sha256', 'SHA224', 'sha224'):
+        import _sha256
+        bs = name[3:]
+        if bs == '256':
+            return _sha256.sha256
+        elif bs == '224':
+            return _sha256.sha224
+    elif name in ('SHA512', 'sha512', 'SHA384', 'sha384'):
+        import _sha512
+        bs = name[3:]
+        if bs == '512':
+            return _sha512.sha512
+        elif bs == '384':
+            return _sha512.sha384
+
+    raise ValueError, "unsupported hash type"
+
+
+def __py_new(name, string=''):
+    """new(name, string='') - Return a new hashing object using the named algorithm;
+    optionally initialized with a string.
+    """
+    return __get_builtin_constructor(name)(string)
+
+
+def __hash_new(name, string=''):
+    """new(name, string='') - Return a new hashing object using the named algorithm;
+    optionally initialized with a string.
+    """
+    try:
+        return _hashlib.new(name, string)
+    except ValueError:
+        # If the _hashlib module (OpenSSL) doesn't support the named
+        # hash, try using our builtin implementations.
+        # This allows for SHA224/256 and SHA384/512 support even though
+        # the OpenSSL library prior to 0.9.8 doesn't provide them.
+        return __get_builtin_constructor(name)(string)
+
+
+try:
+    import _hashlib
+    # use the wrapper of the C implementation
+    new = __hash_new
+
+    for opensslFuncName in filter(lambda n: n.startswith('openssl_'), dir(_hashlib)):
+        funcName = opensslFuncName[len('openssl_'):]
+        try:
+            # try them all, some may not work due to the OpenSSL
+            # version not supporting that algorithm.
+            f = getattr(_hashlib, opensslFuncName)
+            f()
+            # Use the C function directly (very fast)
+            exec funcName + ' = f'
+        except ValueError:
+            try:
+                # Use the builtin implementation directly (fast)
+                exec funcName + ' = __get_builtin_constructor(funcName)'
+            except ValueError:
+                # this one has no builtin implementation, don't define it
+                pass
+    # clean up our locals
+    del f
+    del opensslFuncName
+    del funcName
+
+except ImportError:
+    # We don't have the _hashlib OpenSSL module?
+    # use the built in legacy interfaces via a wrapper function
+    new = __py_new
+
+    # lookup the C function to use directly for the named constructors
+    md5 = __get_builtin_constructor('md5')
+    sha1 = __get_builtin_constructor('sha1')
+    sha224 = __get_builtin_constructor('sha224')
+    sha256 = __get_builtin_constructor('sha256')
+    sha384 = __get_builtin_constructor('sha384')
+    sha512 = __get_builtin_constructor('sha512')

Added: vendor/Python/current/Lib/heapq.py
===================================================================
--- vendor/Python/current/Lib/heapq.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/heapq.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,343 @@
+# -*- coding: Latin-1 -*-
+
+"""Heap queue algorithm (a.k.a. priority queue).
+
+Heaps are arrays for which a[k] <= a[2*k+1] and a[k] <= a[2*k+2] for
+all k, counting elements from 0.  For the sake of comparison,
+non-existing elements are considered to be infinite.  The interesting
+property of a heap is that a[0] is always its smallest element.
+
+Usage:
+
+heap = []            # creates an empty heap
+heappush(heap, item) # pushes a new item on the heap
+item = heappop(heap) # pops the smallest item from the heap
+item = heap[0]       # smallest item on the heap without popping it
+heapify(x)           # transforms list into a heap, in-place, in linear time
+item = heapreplace(heap, item) # pops and returns smallest item, and adds
+                               # new item; the heap size is unchanged
+
+Our API differs from textbook heap algorithms as follows:
+
+- We use 0-based indexing.  This makes the relationship between the
+  index for a node and the indexes for its children slightly less
+  obvious, but is more suitable since Python uses 0-based indexing.
+
+- Our heappop() method returns the smallest item, not the largest.
+
+These two make it possible to view the heap as a regular Python list
+without surprises: heap[0] is the smallest item, and heap.sort()
+maintains the heap invariant!
+"""
+
+# Original code by Kevin O'Connor, augmented by Tim Peters and Raymond Hettinger
+
+__about__ = """Heap queues
+
+[explanation by François Pinard]
+
+Heaps are arrays for which a[k] <= a[2*k+1] and a[k] <= a[2*k+2] for
+all k, counting elements from 0.  For the sake of comparison,
+non-existing elements are considered to be infinite.  The interesting
+property of a heap is that a[0] is always its smallest element.
+
+The strange invariant above is meant to be an efficient memory
+representation for a tournament.  The numbers below are `k', not a[k]:
+
+                                   0
+
+                  1                                 2
+
+          3               4                5               6
+
+      7       8       9       10      11      12      13      14
+
+    15 16   17 18   19 20   21 22   23 24   25 26   27 28   29 30
+
+
+In the tree above, each cell `k' is topping `2*k+1' and `2*k+2'.  In
+an usual binary tournament we see in sports, each cell is the winner
+over the two cells it tops, and we can trace the winner down the tree
+to see all opponents s/he had.  However, in many computer applications
+of such tournaments, we do not need to trace the history of a winner.
+To be more memory efficient, when a winner is promoted, we try to
+replace it by something else at a lower level, and the rule becomes
+that a cell and the two cells it tops contain three different items,
+but the top cell "wins" over the two topped cells.
+
+If this heap invariant is protected at all time, index 0 is clearly
+the overall winner.  The simplest algorithmic way to remove it and
+find the "next" winner is to move some loser (let's say cell 30 in the
+diagram above) into the 0 position, and then percolate this new 0 down
+the tree, exchanging values, until the invariant is re-established.
+This is clearly logarithmic on the total number of items in the tree.
+By iterating over all items, you get an O(n ln n) sort.
+
+A nice feature of this sort is that you can efficiently insert new
+items while the sort is going on, provided that the inserted items are
+not "better" than the last 0'th element you extracted.  This is
+especially useful in simulation contexts, where the tree holds all
+incoming events, and the "win" condition means the smallest scheduled
+time.  When an event schedule other events for execution, they are
+scheduled into the future, so they can easily go into the heap.  So, a
+heap is a good structure for implementing schedulers (this is what I
+used for my MIDI sequencer :-).
+
+Various structures for implementing schedulers have been extensively
+studied, and heaps are good for this, as they are reasonably speedy,
+the speed is almost constant, and the worst case is not much different
+than the average case.  However, there are other representations which
+are more efficient overall, yet the worst cases might be terrible.
+
+Heaps are also very useful in big disk sorts.  You most probably all
+know that a big sort implies producing "runs" (which are pre-sorted
+sequences, which size is usually related to the amount of CPU memory),
+followed by a merging passes for these runs, which merging is often
+very cleverly organised[1].  It is very important that the initial
+sort produces the longest runs possible.  Tournaments are a good way
+to that.  If, using all the memory available to hold a tournament, you
+replace and percolate items that happen to fit the current run, you'll
+produce runs which are twice the size of the memory for random input,
+and much better for input fuzzily ordered.
+
+Moreover, if you output the 0'th item on disk and get an input which
+may not fit in the current tournament (because the value "wins" over
+the last output value), it cannot fit in the heap, so the size of the
+heap decreases.  The freed memory could be cleverly reused immediately
+for progressively building a second heap, which grows at exactly the
+same rate the first heap is melting.  When the first heap completely
+vanishes, you switch heaps and start a new run.  Clever and quite
+effective!
+
+In a word, heaps are useful memory structures to know.  I use them in
+a few applications, and I think it is good to keep a `heap' module
+around. :-)
+
+--------------------
+[1] The disk balancing algorithms which are current, nowadays, are
+more annoying than clever, and this is a consequence of the seeking
+capabilities of the disks.  On devices which cannot seek, like big
+tape drives, the story was quite different, and one had to be very
+clever to ensure (far in advance) that each tape movement will be the
+most effective possible (that is, will best participate at
+"progressing" the merge).  Some tapes were even able to read
+backwards, and this was also used to avoid the rewinding time.
+Believe me, real good tape sorts were quite spectacular to watch!
+From all times, sorting has always been a Great Art! :-)
+"""
+
+__all__ = ['heappush', 'heappop', 'heapify', 'heapreplace', 'nlargest',
+           'nsmallest']
+
+from itertools import islice, repeat, count, imap, izip, tee
+from operator import itemgetter, neg
+import bisect
+
+def heappush(heap, item):
+    """Push item onto heap, maintaining the heap invariant."""
+    heap.append(item)
+    _siftdown(heap, 0, len(heap)-1)
+
+def heappop(heap):
+    """Pop the smallest item off the heap, maintaining the heap invariant."""
+    lastelt = heap.pop()    # raises appropriate IndexError if heap is empty
+    if heap:
+        returnitem = heap[0]
+        heap[0] = lastelt
+        _siftup(heap, 0)
+    else:
+        returnitem = lastelt
+    return returnitem
+
+def heapreplace(heap, item):
+    """Pop and return the current smallest value, and add the new item.
+
+    This is more efficient than heappop() followed by heappush(), and can be
+    more appropriate when using a fixed-size heap.  Note that the value
+    returned may be larger than item!  That constrains reasonable uses of
+    this routine unless written as part of a conditional replacement:
+
+        if item > heap[0]:
+            item = heapreplace(heap, item)
+    """
+    returnitem = heap[0]    # raises appropriate IndexError if heap is empty
+    heap[0] = item
+    _siftup(heap, 0)
+    return returnitem
+
+def heapify(x):
+    """Transform list into a heap, in-place, in O(len(heap)) time."""
+    n = len(x)
+    # Transform bottom-up.  The largest index there's any point to looking at
+    # is the largest with a child index in-range, so must have 2*i + 1 < n,
+    # or i < (n-1)/2.  If n is even = 2*j, this is (2*j-1)/2 = j-1/2 so
+    # j-1 is the largest, which is n//2 - 1.  If n is odd = 2*j+1, this is
+    # (2*j+1-1)/2 = j so j-1 is the largest, and that's again n//2-1.
+    for i in reversed(xrange(n//2)):
+        _siftup(x, i)
+
+def nlargest(n, iterable):
+    """Find the n largest elements in a dataset.
+
+    Equivalent to:  sorted(iterable, reverse=True)[:n]
+    """
+    it = iter(iterable)
+    result = list(islice(it, n))
+    if not result:
+        return result
+    heapify(result)
+    _heapreplace = heapreplace
+    sol = result[0]         # sol --> smallest of the nlargest
+    for elem in it:
+        if elem <= sol:
+            continue
+        _heapreplace(result, elem)
+        sol = result[0]
+    result.sort(reverse=True)
+    return result
+
+def nsmallest(n, iterable):
+    """Find the n smallest elements in a dataset.
+
+    Equivalent to:  sorted(iterable)[:n]
+    """
+    if hasattr(iterable, '__len__') and n * 10 <= len(iterable):
+        # For smaller values of n, the bisect method is faster than a minheap.
+        # It is also memory efficient, consuming only n elements of space.
+        it = iter(iterable)
+        result = sorted(islice(it, 0, n))
+        if not result:
+            return result
+        insort = bisect.insort
+        pop = result.pop
+        los = result[-1]    # los --> Largest of the nsmallest
+        for elem in it:
+            if los <= elem:
+                continue
+            insort(result, elem)
+            pop()
+            los = result[-1]
+        return result
+    # An alternative approach manifests the whole iterable in memory but
+    # saves comparisons by heapifying all at once.  Also, saves time
+    # over bisect.insort() which has O(n) data movement time for every
+    # insertion.  Finding the n smallest of an m length iterable requires
+    #    O(m) + O(n log m) comparisons.
+    h = list(iterable)
+    heapify(h)
+    return map(heappop, repeat(h, min(n, len(h))))
+
+# 'heap' is a heap at all indices >= startpos, except possibly for pos.  pos
+# is the index of a leaf with a possibly out-of-order value.  Restore the
+# heap invariant.
+def _siftdown(heap, startpos, pos):
+    newitem = heap[pos]
+    # Follow the path to the root, moving parents down until finding a place
+    # newitem fits.
+    while pos > startpos:
+        parentpos = (pos - 1) >> 1
+        parent = heap[parentpos]
+        if parent <= newitem:
+            break
+        heap[pos] = parent
+        pos = parentpos
+    heap[pos] = newitem
+
+# The child indices of heap index pos are already heaps, and we want to make
+# a heap at index pos too.  We do this by bubbling the smaller child of
+# pos up (and so on with that child's children, etc) until hitting a leaf,
+# then using _siftdown to move the oddball originally at index pos into place.
+#
+# We *could* break out of the loop as soon as we find a pos where newitem <=
+# both its children, but turns out that's not a good idea, and despite that
+# many books write the algorithm that way.  During a heap pop, the last array
+# element is sifted in, and that tends to be large, so that comparing it
+# against values starting from the root usually doesn't pay (= usually doesn't
+# get us out of the loop early).  See Knuth, Volume 3, where this is
+# explained and quantified in an exercise.
+#
+# Cutting the # of comparisons is important, since these routines have no
+# way to extract "the priority" from an array element, so that intelligence
+# is likely to be hiding in custom __cmp__ methods, or in array elements
+# storing (priority, record) tuples.  Comparisons are thus potentially
+# expensive.
+#
+# On random arrays of length 1000, making this change cut the number of
+# comparisons made by heapify() a little, and those made by exhaustive
+# heappop() a lot, in accord with theory.  Here are typical results from 3
+# runs (3 just to demonstrate how small the variance is):
+#
+# Compares needed by heapify     Compares needed by 1000 heappops
+# --------------------------     --------------------------------
+# 1837 cut to 1663               14996 cut to 8680
+# 1855 cut to 1659               14966 cut to 8678
+# 1847 cut to 1660               15024 cut to 8703
+#
+# Building the heap by using heappush() 1000 times instead required
+# 2198, 2148, and 2219 compares:  heapify() is more efficient, when
+# you can use it.
+#
+# The total compares needed by list.sort() on the same lists were 8627,
+# 8627, and 8632 (this should be compared to the sum of heapify() and
+# heappop() compares):  list.sort() is (unsurprisingly!) more efficient
+# for sorting.
+
+def _siftup(heap, pos):
+    endpos = len(heap)
+    startpos = pos
+    newitem = heap[pos]
+    # Bubble up the smaller child until hitting a leaf.
+    childpos = 2*pos + 1    # leftmost child position
+    while childpos < endpos:
+        # Set childpos to index of smaller child.
+        rightpos = childpos + 1
+        if rightpos < endpos and heap[rightpos] <= heap[childpos]:
+            childpos = rightpos
+        # Move the smaller child up.
+        heap[pos] = heap[childpos]
+        pos = childpos
+        childpos = 2*pos + 1
+    # The leaf at pos is empty now.  Put newitem there, and bubble it up
+    # to its final resting place (by sifting its parents down).
+    heap[pos] = newitem
+    _siftdown(heap, startpos, pos)
+
+# If available, use C implementation
+try:
+    from _heapq import heappush, heappop, heapify, heapreplace, nlargest, nsmallest
+except ImportError:
+    pass
+
+# Extend the implementations of nsmallest and nlargest to use a key= argument
+_nsmallest = nsmallest
+def nsmallest(n, iterable, key=None):
+    """Find the n smallest elements in a dataset.
+
+    Equivalent to:  sorted(iterable, key=key)[:n]
+    """
+    in1, in2 = tee(iterable)
+    it = izip(imap(key, in1), count(), in2)                 # decorate
+    result = _nsmallest(n, it)
+    return map(itemgetter(2), result)                       # undecorate
+
+_nlargest = nlargest
+def nlargest(n, iterable, key=None):
+    """Find the n largest elements in a dataset.
+
+    Equivalent to:  sorted(iterable, key=key, reverse=True)[:n]
+    """
+    in1, in2 = tee(iterable)
+    it = izip(imap(key, in1), imap(neg, count()), in2)      # decorate
+    result = _nlargest(n, it)
+    return map(itemgetter(2), result)                       # undecorate
+
+if __name__ == "__main__":
+    # Simple sanity test
+    heap = []
+    data = [1, 3, 5, 7, 9, 2, 4, 6, 8, 0]
+    for item in data:
+        heappush(heap, item)
+    sort = []
+    while heap:
+        sort.append(heappop(heap))
+    print sort

Added: vendor/Python/current/Lib/hmac.py
===================================================================
--- vendor/Python/current/Lib/hmac.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/hmac.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,113 @@
+"""HMAC (Keyed-Hashing for Message Authentication) Python module.
+
+Implements the HMAC algorithm as described by RFC 2104.
+"""
+
+def _strxor(s1, s2):
+    """Utility method. XOR the two strings s1 and s2 (must have same length).
+    """
+    return "".join(map(lambda x, y: chr(ord(x) ^ ord(y)), s1, s2))
+
+# The size of the digests returned by HMAC depends on the underlying
+# hashing module used.
+digest_size = None
+
+# A unique object passed by HMAC.copy() to the HMAC constructor, in order
+# that the latter return very quickly.  HMAC("") in contrast is quite
+# expensive.
+_secret_backdoor_key = []
+
+class HMAC:
+    """RFC2104 HMAC class.
+
+    This supports the API for Cryptographic Hash Functions (PEP 247).
+    """
+
+    def __init__(self, key, msg = None, digestmod = None):
+        """Create a new HMAC object.
+
+        key:       key for the keyed hash object.
+        msg:       Initial input for the hash, if provided.
+        digestmod: A module supporting PEP 247.  *OR*
+                   A hashlib constructor returning a new hash object.
+                   Defaults to hashlib.md5.
+        """
+
+        if key is _secret_backdoor_key: # cheap
+            return
+
+        if digestmod is None:
+            import hashlib
+            digestmod = hashlib.md5
+
+        if callable(digestmod):
+            self.digest_cons = digestmod
+        else:
+            self.digest_cons = lambda d='': digestmod.new(d)
+
+        self.outer = self.digest_cons()
+        self.inner = self.digest_cons()
+        self.digest_size = self.inner.digest_size
+
+        blocksize = 64
+        ipad = "\x36" * blocksize
+        opad = "\x5C" * blocksize
+
+        if len(key) > blocksize:
+            key = self.digest_cons(key).digest()
+
+        key = key + chr(0) * (blocksize - len(key))
+        self.outer.update(_strxor(key, opad))
+        self.inner.update(_strxor(key, ipad))
+        if msg is not None:
+            self.update(msg)
+
+##    def clear(self):
+##        raise NotImplementedError, "clear() method not available in HMAC."
+
+    def update(self, msg):
+        """Update this hashing object with the string msg.
+        """
+        self.inner.update(msg)
+
+    def copy(self):
+        """Return a separate copy of this hashing object.
+
+        An update to this copy won't affect the original object.
+        """
+        other = HMAC(_secret_backdoor_key)
+        other.digest_cons = self.digest_cons
+        other.digest_size = self.digest_size
+        other.inner = self.inner.copy()
+        other.outer = self.outer.copy()
+        return other
+
+    def digest(self):
+        """Return the hash value of this hashing object.
+
+        This returns a string containing 8-bit data.  The object is
+        not altered in any way by this function; you can continue
+        updating the object after calling this function.
+        """
+        h = self.outer.copy()
+        h.update(self.inner.digest())
+        return h.digest()
+
+    def hexdigest(self):
+        """Like digest(), but returns a string of hexadecimal digits instead.
+        """
+        return "".join([hex(ord(x))[2:].zfill(2)
+                        for x in tuple(self.digest())])
+
+def new(key, msg = None, digestmod = None):
+    """Create a new hashing object and return it.
+
+    key: The starting key for the hash.
+    msg: if available, will immediately be hashed into the object's starting
+    state.
+
+    You can now feed arbitrary strings into the object using its update()
+    method, and can ask for the hash value at any time by calling its digest()
+    method.
+    """
+    return HMAC(key, msg, digestmod)

Added: vendor/Python/current/Lib/hotshot/__init__.py
===================================================================
--- vendor/Python/current/Lib/hotshot/__init__.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/hotshot/__init__.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,76 @@
+"""High-perfomance logging profiler, mostly written in C."""
+
+import _hotshot
+
+from _hotshot import ProfilerError
+
+
+class Profile:
+    def __init__(self, logfn, lineevents=0, linetimings=1):
+        self.lineevents = lineevents and 1 or 0
+        self.linetimings = (linetimings and lineevents) and 1 or 0
+        self._prof = p = _hotshot.profiler(
+            logfn, self.lineevents, self.linetimings)
+
+        # Attempt to avoid confusing results caused by the presence of
+        # Python wrappers around these functions, but only if we can
+        # be sure the methods have not been overridden or extended.
+        if self.__class__ is Profile:
+            self.close = p.close
+            self.start = p.start
+            self.stop = p.stop
+            self.addinfo = p.addinfo
+
+    def close(self):
+        """Close the logfile and terminate the profiler."""
+        self._prof.close()
+
+    def fileno(self):
+        """Return the file descriptor of the profiler's log file."""
+        return self._prof.fileno()
+
+    def start(self):
+        """Start the profiler."""
+        self._prof.start()
+
+    def stop(self):
+        """Stop the profiler."""
+        self._prof.stop()
+
+    def addinfo(self, key, value):
+        """Add an arbitrary labelled value to the profile log."""
+        self._prof.addinfo(key, value)
+
+    # These methods offer the same interface as the profile.Profile class,
+    # but delegate most of the work to the C implementation underneath.
+
+    def run(self, cmd):
+        """Profile an exec-compatible string in the script
+        environment.
+
+        The globals from the __main__ module are used as both the
+        globals and locals for the script.
+        """
+        import __main__
+        dict = __main__.__dict__
+        return self.runctx(cmd, dict, dict)
+
+    def runctx(self, cmd, globals, locals):
+        """Evaluate an exec-compatible string in a specific
+        environment.
+
+        The string is compiled before profiling begins.
+        """
+        code = compile(cmd, "<string>", "exec")
+        self._prof.runcode(code, globals, locals)
+        return self
+
+    def runcall(self, func, *args, **kw):
+        """Profile a single call of a callable.
+
+        Additional positional and keyword arguments may be passed
+        along; the result of the call is returned, and exceptions are
+        allowed to propogate cleanly, while ensuring that profiling is
+        disabled on the way out.
+        """
+        return self._prof.runcall(func, args, kw)

Added: vendor/Python/current/Lib/hotshot/log.py
===================================================================
--- vendor/Python/current/Lib/hotshot/log.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/hotshot/log.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,192 @@
+import _hotshot
+import os.path
+import parser
+import symbol
+import sys
+
+from _hotshot import \
+     WHAT_ENTER, \
+     WHAT_EXIT, \
+     WHAT_LINENO, \
+     WHAT_DEFINE_FILE, \
+     WHAT_DEFINE_FUNC, \
+     WHAT_ADD_INFO
+
+
+__all__ = ["LogReader", "ENTER", "EXIT", "LINE"]
+
+
+ENTER = WHAT_ENTER
+EXIT  = WHAT_EXIT
+LINE  = WHAT_LINENO
+
+
+class LogReader:
+    def __init__(self, logfn):
+        # fileno -> filename
+        self._filemap = {}
+        # (fileno, lineno) -> filename, funcname
+        self._funcmap = {}
+
+        self._reader = _hotshot.logreader(logfn)
+        self._nextitem = self._reader.next
+        self._info = self._reader.info
+        if self._info.has_key('current-directory'):
+            self.cwd = self._info['current-directory']
+        else:
+            self.cwd = None
+
+        # This mirrors the call stack of the profiled code as the log
+        # is read back in.  It contains tuples of the form:
+        #
+        #   (file name, line number of function def, function name)
+        #
+        self._stack = []
+        self._append = self._stack.append
+        self._pop = self._stack.pop
+
+    def close(self):
+        self._reader.close()
+
+    def fileno(self):
+        """Return the file descriptor of the log reader's log file."""
+        return self._reader.fileno()
+
+    def addinfo(self, key, value):
+        """This method is called for each additional ADD_INFO record.
+
+        This can be overridden by applications that want to receive
+        these events.  The default implementation does not need to be
+        called by alternate implementations.
+
+        The initial set of ADD_INFO records do not pass through this
+        mechanism; this is only needed to receive notification when
+        new values are added.  Subclasses can inspect self._info after
+        calling LogReader.__init__().
+        """
+        pass
+
+    def get_filename(self, fileno):
+        try:
+            return self._filemap[fileno]
+        except KeyError:
+            raise ValueError, "unknown fileno"
+
+    def get_filenames(self):
+        return self._filemap.values()
+
+    def get_fileno(self, filename):
+        filename = os.path.normcase(os.path.normpath(filename))
+        for fileno, name in self._filemap.items():
+            if name == filename:
+                return fileno
+        raise ValueError, "unknown filename"
+
+    def get_funcname(self, fileno, lineno):
+        try:
+            return self._funcmap[(fileno, lineno)]
+        except KeyError:
+            raise ValueError, "unknown function location"
+
+    # Iteration support:
+    # This adds an optional (& ignored) parameter to next() so that the
+    # same bound method can be used as the __getitem__() method -- this
+    # avoids using an additional method call which kills the performance.
+
+    def next(self, index=0):
+        while 1:
+            # This call may raise StopIteration:
+            what, tdelta, fileno, lineno = self._nextitem()
+
+            # handle the most common cases first
+
+            if what == WHAT_ENTER:
+                filename, funcname = self._decode_location(fileno, lineno)
+                t = (filename, lineno, funcname)
+                self._append(t)
+                return what, t, tdelta
+
+            if what == WHAT_EXIT:
+                return what, self._pop(), tdelta
+
+            if what == WHAT_LINENO:
+                filename, firstlineno, funcname = self._stack[-1]
+                return what, (filename, lineno, funcname), tdelta
+
+            if what == WHAT_DEFINE_FILE:
+                filename = os.path.normcase(os.path.normpath(tdelta))
+                self._filemap[fileno] = filename
+            elif what == WHAT_DEFINE_FUNC:
+                filename = self._filemap[fileno]
+                self._funcmap[(fileno, lineno)] = (filename, tdelta)
+            elif what == WHAT_ADD_INFO:
+                # value already loaded into self.info; call the
+                # overridable addinfo() handler so higher-level code
+                # can pick up the new value
+                if tdelta == 'current-directory':
+                    self.cwd = lineno
+                self.addinfo(tdelta, lineno)
+            else:
+                raise ValueError, "unknown event type"
+
+    def __iter__(self):
+        return self
+
+    #
+    #  helpers
+    #
+
+    def _decode_location(self, fileno, lineno):
+        try:
+            return self._funcmap[(fileno, lineno)]
+        except KeyError:
+            #
+            # This should only be needed when the log file does not
+            # contain all the DEFINE_FUNC records needed to allow the
+            # function name to be retrieved from the log file.
+            #
+            if self._loadfile(fileno):
+                filename = funcname = None
+            try:
+                filename, funcname = self._funcmap[(fileno, lineno)]
+            except KeyError:
+                filename = self._filemap.get(fileno)
+                funcname = None
+                self._funcmap[(fileno, lineno)] = (filename, funcname)
+        return filename, funcname
+
+    def _loadfile(self, fileno):
+        try:
+            filename = self._filemap[fileno]
+        except KeyError:
+            print "Could not identify fileId", fileno
+            return 1
+        if filename is None:
+            return 1
+        absname = os.path.normcase(os.path.join(self.cwd, filename))
+
+        try:
+            fp = open(absname)
+        except IOError:
+            return
+        st = parser.suite(fp.read())
+        fp.close()
+
+        # Scan the tree looking for def and lambda nodes, filling in
+        # self._funcmap with all the available information.
+        funcdef = symbol.funcdef
+        lambdef = symbol.lambdef
+
+        stack = [st.totuple(1)]
+
+        while stack:
+            tree = stack.pop()
+            try:
+                sym = tree[0]
+            except (IndexError, TypeError):
+                continue
+            if sym == funcdef:
+                self._funcmap[(fileno, tree[2][2])] = filename, tree[2][1]
+            elif sym == lambdef:
+                self._funcmap[(fileno, tree[1][2])] = filename, "<lambda>"
+            stack.extend(list(tree[1:]))

Added: vendor/Python/current/Lib/hotshot/stats.py
===================================================================
--- vendor/Python/current/Lib/hotshot/stats.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/hotshot/stats.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,93 @@
+"""Statistics analyzer for HotShot."""
+
+import profile
+import pstats
+
+import hotshot.log
+
+from hotshot.log import ENTER, EXIT
+
+
+def load(filename):
+    return StatsLoader(filename).load()
+
+
+class StatsLoader:
+    def __init__(self, logfn):
+        self._logfn = logfn
+        self._code = {}
+        self._stack = []
+        self.pop_frame = self._stack.pop
+
+    def load(self):
+        # The timer selected by the profiler should never be used, so make
+        # sure it doesn't work:
+        p = Profile()
+        p.get_time = _brokentimer
+        log = hotshot.log.LogReader(self._logfn)
+        taccum = 0
+        for event in log:
+            what, (filename, lineno, funcname), tdelta = event
+            if tdelta > 0:
+                taccum += tdelta
+
+            # We multiply taccum to convert from the microseconds we
+            # have to the seconds that the profile/pstats module work
+            # with; this allows the numbers to have some basis in
+            # reality (ignoring calibration issues for now).
+
+            if what == ENTER:
+                frame = self.new_frame(filename, lineno, funcname)
+                p.trace_dispatch_call(frame, taccum * .000001)
+                taccum = 0
+
+            elif what == EXIT:
+                frame = self.pop_frame()
+                p.trace_dispatch_return(frame, taccum * .000001)
+                taccum = 0
+
+            # no further work for line events
+
+        assert not self._stack
+        return pstats.Stats(p)
+
+    def new_frame(self, *args):
+        # args must be filename, firstlineno, funcname
+        # our code objects are cached since we don't need to create
+        # new ones every time
+        try:
+            code = self._code[args]
+        except KeyError:
+            code = FakeCode(*args)
+            self._code[args] = code
+        # frame objects are create fresh, since the back pointer will
+        # vary considerably
+        if self._stack:
+            back = self._stack[-1]
+        else:
+            back = None
+        frame = FakeFrame(code, back)
+        self._stack.append(frame)
+        return frame
+
+
+class Profile(profile.Profile):
+    def simulate_cmd_complete(self):
+        pass
+
+
+class FakeCode:
+    def __init__(self, filename, firstlineno, funcname):
+        self.co_filename = filename
+        self.co_firstlineno = firstlineno
+        self.co_name = self.__name__ = funcname
+
+
+class FakeFrame:
+    def __init__(self, code, back):
+        self.f_back = back
+        self.f_code = code
+
+
+def _brokentimer():
+    raise RuntimeError, "this timer should not be called"

Added: vendor/Python/current/Lib/hotshot/stones.py
===================================================================
--- vendor/Python/current/Lib/hotshot/stones.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/hotshot/stones.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,31 @@
+import errno
+import hotshot
+import hotshot.stats
+import os
+import sys
+import test.pystone
+
+def main(logfile):
+    p = hotshot.Profile(logfile)
+    benchtime, stones = p.runcall(test.pystone.pystones)
+    p.close()
+
+    print "Pystone(%s) time for %d passes = %g" % \
+          (test.pystone.__version__, test.pystone.LOOPS, benchtime)
+    print "This machine benchmarks at %g pystones/second" % stones
+
+    stats = hotshot.stats.load(logfile)
+    stats.strip_dirs()
+    stats.sort_stats('time', 'calls')
+    try:
+        stats.print_stats(20)
+    except IOError, e:
+        if e.errno != errno.EPIPE:
+            raise
+
+if __name__ == '__main__':
+    if sys.argv[1:]:
+        main(sys.argv[1])
+    else:
+        import tempfile
+        main(tempfile.NamedTemporaryFile().name)

Added: vendor/Python/current/Lib/htmlentitydefs.py
===================================================================
--- vendor/Python/current/Lib/htmlentitydefs.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/htmlentitydefs.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,273 @@
+"""HTML character entity references."""
+
+# maps the HTML entity name to the Unicode codepoint
+name2codepoint = {
+    'AElig':    0x00c6, # latin capital letter AE = latin capital ligature AE, U+00C6 ISOlat1
+    'Aacute':   0x00c1, # latin capital letter A with acute, U+00C1 ISOlat1
+    'Acirc':    0x00c2, # latin capital letter A with circumflex, U+00C2 ISOlat1
+    'Agrave':   0x00c0, # latin capital letter A with grave = latin capital letter A grave, U+00C0 ISOlat1
+    'Alpha':    0x0391, # greek capital letter alpha, U+0391
+    'Aring':    0x00c5, # latin capital letter A with ring above = latin capital letter A ring, U+00C5 ISOlat1
+    'Atilde':   0x00c3, # latin capital letter A with tilde, U+00C3 ISOlat1
+    'Auml':     0x00c4, # latin capital letter A with diaeresis, U+00C4 ISOlat1
+    'Beta':     0x0392, # greek capital letter beta, U+0392
+    'Ccedil':   0x00c7, # latin capital letter C with cedilla, U+00C7 ISOlat1
+    'Chi':      0x03a7, # greek capital letter chi, U+03A7
+    'Dagger':   0x2021, # double dagger, U+2021 ISOpub
+    'Delta':    0x0394, # greek capital letter delta, U+0394 ISOgrk3
+    'ETH':      0x00d0, # latin capital letter ETH, U+00D0 ISOlat1
+    'Eacute':   0x00c9, # latin capital letter E with acute, U+00C9 ISOlat1
+    'Ecirc':    0x00ca, # latin capital letter E with circumflex, U+00CA ISOlat1
+    'Egrave':   0x00c8, # latin capital letter E with grave, U+00C8 ISOlat1
+    'Epsilon':  0x0395, # greek capital letter epsilon, U+0395
+    'Eta':      0x0397, # greek capital letter eta, U+0397
+    'Euml':     0x00cb, # latin capital letter E with diaeresis, U+00CB ISOlat1
+    'Gamma':    0x0393, # greek capital letter gamma, U+0393 ISOgrk3
+    'Iacute':   0x00cd, # latin capital letter I with acute, U+00CD ISOlat1
+    'Icirc':    0x00ce, # latin capital letter I with circumflex, U+00CE ISOlat1
+    'Igrave':   0x00cc, # latin capital letter I with grave, U+00CC ISOlat1
+    'Iota':     0x0399, # greek capital letter iota, U+0399
+    'Iuml':     0x00cf, # latin capital letter I with diaeresis, U+00CF ISOlat1
+    'Kappa':    0x039a, # greek capital letter kappa, U+039A
+    'Lambda':   0x039b, # greek capital letter lambda, U+039B ISOgrk3
+    'Mu':       0x039c, # greek capital letter mu, U+039C
+    'Ntilde':   0x00d1, # latin capital letter N with tilde, U+00D1 ISOlat1
+    'Nu':       0x039d, # greek capital letter nu, U+039D
+    'OElig':    0x0152, # latin capital ligature OE, U+0152 ISOlat2
+    'Oacute':   0x00d3, # latin capital letter O with acute, U+00D3 ISOlat1
+    'Ocirc':    0x00d4, # latin capital letter O with circumflex, U+00D4 ISOlat1
+    'Ograve':   0x00d2, # latin capital letter O with grave, U+00D2 ISOlat1
+    'Omega':    0x03a9, # greek capital letter omega, U+03A9 ISOgrk3
+    'Omicron':  0x039f, # greek capital letter omicron, U+039F
+    'Oslash':   0x00d8, # latin capital letter O with stroke = latin capital letter O slash, U+00D8 ISOlat1
+    'Otilde':   0x00d5, # latin capital letter O with tilde, U+00D5 ISOlat1
+    'Ouml':     0x00d6, # latin capital letter O with diaeresis, U+00D6 ISOlat1
+    'Phi':      0x03a6, # greek capital letter phi, U+03A6 ISOgrk3
+    'Pi':       0x03a0, # greek capital letter pi, U+03A0 ISOgrk3
+    'Prime':    0x2033, # double prime = seconds = inches, U+2033 ISOtech
+    'Psi':      0x03a8, # greek capital letter psi, U+03A8 ISOgrk3
+    'Rho':      0x03a1, # greek capital letter rho, U+03A1
+    'Scaron':   0x0160, # latin capital letter S with caron, U+0160 ISOlat2
+    'Sigma':    0x03a3, # greek capital letter sigma, U+03A3 ISOgrk3
+    'THORN':    0x00de, # latin capital letter THORN, U+00DE ISOlat1
+    'Tau':      0x03a4, # greek capital letter tau, U+03A4
+    'Theta':    0x0398, # greek capital letter theta, U+0398 ISOgrk3
+    'Uacute':   0x00da, # latin capital letter U with acute, U+00DA ISOlat1
+    'Ucirc':    0x00db, # latin capital letter U with circumflex, U+00DB ISOlat1
+    'Ugrave':   0x00d9, # latin capital letter U with grave, U+00D9 ISOlat1
+    'Upsilon':  0x03a5, # greek capital letter upsilon, U+03A5 ISOgrk3
+    'Uuml':     0x00dc, # latin capital letter U with diaeresis, U+00DC ISOlat1
+    'Xi':       0x039e, # greek capital letter xi, U+039E ISOgrk3
+    'Yacute':   0x00dd, # latin capital letter Y with acute, U+00DD ISOlat1
+    'Yuml':     0x0178, # latin capital letter Y with diaeresis, U+0178 ISOlat2
+    'Zeta':     0x0396, # greek capital letter zeta, U+0396
+    'aacute':   0x00e1, # latin small letter a with acute, U+00E1 ISOlat1
+    'acirc':    0x00e2, # latin small letter a with circumflex, U+00E2 ISOlat1
+    'acute':    0x00b4, # acute accent = spacing acute, U+00B4 ISOdia
+    'aelig':    0x00e6, # latin small letter ae = latin small ligature ae, U+00E6 ISOlat1
+    'agrave':   0x00e0, # latin small letter a with grave = latin small letter a grave, U+00E0 ISOlat1
+    'alefsym':  0x2135, # alef symbol = first transfinite cardinal, U+2135 NEW
+    'alpha':    0x03b1, # greek small letter alpha, U+03B1 ISOgrk3
+    'amp':      0x0026, # ampersand, U+0026 ISOnum
+    'and':      0x2227, # logical and = wedge, U+2227 ISOtech
+    'ang':      0x2220, # angle, U+2220 ISOamso
+    'aring':    0x00e5, # latin small letter a with ring above = latin small letter a ring, U+00E5 ISOlat1
+    'asymp':    0x2248, # almost equal to = asymptotic to, U+2248 ISOamsr
+    'atilde':   0x00e3, # latin small letter a with tilde, U+00E3 ISOlat1
+    'auml':     0x00e4, # latin small letter a with diaeresis, U+00E4 ISOlat1
+    'bdquo':    0x201e, # double low-9 quotation mark, U+201E NEW
+    'beta':     0x03b2, # greek small letter beta, U+03B2 ISOgrk3
+    'brvbar':   0x00a6, # broken bar = broken vertical bar, U+00A6 ISOnum
+    'bull':     0x2022, # bullet = black small circle, U+2022 ISOpub
+    'cap':      0x2229, # intersection = cap, U+2229 ISOtech
+    'ccedil':   0x00e7, # latin small letter c with cedilla, U+00E7 ISOlat1
+    'cedil':    0x00b8, # cedilla = spacing cedilla, U+00B8 ISOdia
+    'cent':     0x00a2, # cent sign, U+00A2 ISOnum
+    'chi':      0x03c7, # greek small letter chi, U+03C7 ISOgrk3
+    'circ':     0x02c6, # modifier letter circumflex accent, U+02C6 ISOpub
+    'clubs':    0x2663, # black club suit = shamrock, U+2663 ISOpub
+    'cong':     0x2245, # approximately equal to, U+2245 ISOtech
+    'copy':     0x00a9, # copyright sign, U+00A9 ISOnum
+    'crarr':    0x21b5, # downwards arrow with corner leftwards = carriage return, U+21B5 NEW
+    'cup':      0x222a, # union = cup, U+222A ISOtech
+    'curren':   0x00a4, # currency sign, U+00A4 ISOnum
+    'dArr':     0x21d3, # downwards double arrow, U+21D3 ISOamsa
+    'dagger':   0x2020, # dagger, U+2020 ISOpub
+    'darr':     0x2193, # downwards arrow, U+2193 ISOnum
+    'deg':      0x00b0, # degree sign, U+00B0 ISOnum
+    'delta':    0x03b4, # greek small letter delta, U+03B4 ISOgrk3
+    'diams':    0x2666, # black diamond suit, U+2666 ISOpub
+    'divide':   0x00f7, # division sign, U+00F7 ISOnum
+    'eacute':   0x00e9, # latin small letter e with acute, U+00E9 ISOlat1
+    'ecirc':    0x00ea, # latin small letter e with circumflex, U+00EA ISOlat1
+    'egrave':   0x00e8, # latin small letter e with grave, U+00E8 ISOlat1
+    'empty':    0x2205, # empty set = null set = diameter, U+2205 ISOamso
+    'emsp':     0x2003, # em space, U+2003 ISOpub
+    'ensp':     0x2002, # en space, U+2002 ISOpub
+    'epsilon':  0x03b5, # greek small letter epsilon, U+03B5 ISOgrk3
+    'equiv':    0x2261, # identical to, U+2261 ISOtech
+    'eta':      0x03b7, # greek small letter eta, U+03B7 ISOgrk3
+    'eth':      0x00f0, # latin small letter eth, U+00F0 ISOlat1
+    'euml':     0x00eb, # latin small letter e with diaeresis, U+00EB ISOlat1
+    'euro':     0x20ac, # euro sign, U+20AC NEW
+    'exist':    0x2203, # there exists, U+2203 ISOtech
+    'fnof':     0x0192, # latin small f with hook = function = florin, U+0192 ISOtech
+    'forall':   0x2200, # for all, U+2200 ISOtech
+    'frac12':   0x00bd, # vulgar fraction one half = fraction one half, U+00BD ISOnum
+    'frac14':   0x00bc, # vulgar fraction one quarter = fraction one quarter, U+00BC ISOnum
+    'frac34':   0x00be, # vulgar fraction three quarters = fraction three quarters, U+00BE ISOnum
+    'frasl':    0x2044, # fraction slash, U+2044 NEW
+    'gamma':    0x03b3, # greek small letter gamma, U+03B3 ISOgrk3
+    'ge':       0x2265, # greater-than or equal to, U+2265 ISOtech
+    'gt':       0x003e, # greater-than sign, U+003E ISOnum
+    'hArr':     0x21d4, # left right double arrow, U+21D4 ISOamsa
+    'harr':     0x2194, # left right arrow, U+2194 ISOamsa
+    'hearts':   0x2665, # black heart suit = valentine, U+2665 ISOpub
+    'hellip':   0x2026, # horizontal ellipsis = three dot leader, U+2026 ISOpub
+    'iacute':   0x00ed, # latin small letter i with acute, U+00ED ISOlat1
+    'icirc':    0x00ee, # latin small letter i with circumflex, U+00EE ISOlat1
+    'iexcl':    0x00a1, # inverted exclamation mark, U+00A1 ISOnum
+    'igrave':   0x00ec, # latin small letter i with grave, U+00EC ISOlat1
+    'image':    0x2111, # blackletter capital I = imaginary part, U+2111 ISOamso
+    'infin':    0x221e, # infinity, U+221E ISOtech
+    'int':      0x222b, # integral, U+222B ISOtech
+    'iota':     0x03b9, # greek small letter iota, U+03B9 ISOgrk3
+    'iquest':   0x00bf, # inverted question mark = turned question mark, U+00BF ISOnum
+    'isin':     0x2208, # element of, U+2208 ISOtech
+    'iuml':     0x00ef, # latin small letter i with diaeresis, U+00EF ISOlat1
+    'kappa':    0x03ba, # greek small letter kappa, U+03BA ISOgrk3
+    'lArr':     0x21d0, # leftwards double arrow, U+21D0 ISOtech
+    'lambda':   0x03bb, # greek small letter lambda, U+03BB ISOgrk3
+    'lang':     0x2329, # left-pointing angle bracket = bra, U+2329 ISOtech
+    'laquo':    0x00ab, # left-pointing double angle quotation mark = left pointing guillemet, U+00AB ISOnum
+    'larr':     0x2190, # leftwards arrow, U+2190 ISOnum
+    'lceil':    0x2308, # left ceiling = apl upstile, U+2308 ISOamsc
+    'ldquo':    0x201c, # left double quotation mark, U+201C ISOnum
+    'le':       0x2264, # less-than or equal to, U+2264 ISOtech
+    'lfloor':   0x230a, # left floor = apl downstile, U+230A ISOamsc
+    'lowast':   0x2217, # asterisk operator, U+2217 ISOtech
+    'loz':      0x25ca, # lozenge, U+25CA ISOpub
+    'lrm':      0x200e, # left-to-right mark, U+200E NEW RFC 2070
+    'lsaquo':   0x2039, # single left-pointing angle quotation mark, U+2039 ISO proposed
+    'lsquo':    0x2018, # left single quotation mark, U+2018 ISOnum
+    'lt':       0x003c, # less-than sign, U+003C ISOnum
+    'macr':     0x00af, # macron = spacing macron = overline = APL overbar, U+00AF ISOdia
+    'mdash':    0x2014, # em dash, U+2014 ISOpub
+    'micro':    0x00b5, # micro sign, U+00B5 ISOnum
+    'middot':   0x00b7, # middle dot = Georgian comma = Greek middle dot, U+00B7 ISOnum
+    'minus':    0x2212, # minus sign, U+2212 ISOtech
+    'mu':       0x03bc, # greek small letter mu, U+03BC ISOgrk3
+    'nabla':    0x2207, # nabla = backward difference, U+2207 ISOtech
+    'nbsp':     0x00a0, # no-break space = non-breaking space, U+00A0 ISOnum
+    'ndash':    0x2013, # en dash, U+2013 ISOpub
+    'ne':       0x2260, # not equal to, U+2260 ISOtech
+    'ni':       0x220b, # contains as member, U+220B ISOtech
+    'not':      0x00ac, # not sign, U+00AC ISOnum
+    'notin':    0x2209, # not an element of, U+2209 ISOtech
+    'nsub':     0x2284, # not a subset of, U+2284 ISOamsn
+    'ntilde':   0x00f1, # latin small letter n with tilde, U+00F1 ISOlat1
+    'nu':       0x03bd, # greek small letter nu, U+03BD ISOgrk3
+    'oacute':   0x00f3, # latin small letter o with acute, U+00F3 ISOlat1
+    'ocirc':    0x00f4, # latin small letter o with circumflex, U+00F4 ISOlat1
+    'oelig':    0x0153, # latin small ligature oe, U+0153 ISOlat2
+    'ograve':   0x00f2, # latin small letter o with grave, U+00F2 ISOlat1
+    'oline':    0x203e, # overline = spacing overscore, U+203E NEW
+    'omega':    0x03c9, # greek small letter omega, U+03C9 ISOgrk3
+    'omicron':  0x03bf, # greek small letter omicron, U+03BF NEW
+    'oplus':    0x2295, # circled plus = direct sum, U+2295 ISOamsb
+    'or':       0x2228, # logical or = vee, U+2228 ISOtech
+    'ordf':     0x00aa, # feminine ordinal indicator, U+00AA ISOnum
+    'ordm':     0x00ba, # masculine ordinal indicator, U+00BA ISOnum
+    'oslash':   0x00f8, # latin small letter o with stroke, = latin small letter o slash, U+00F8 ISOlat1
+    'otilde':   0x00f5, # latin small letter o with tilde, U+00F5 ISOlat1
+    'otimes':   0x2297, # circled times = vector product, U+2297 ISOamsb
+    'ouml':     0x00f6, # latin small letter o with diaeresis, U+00F6 ISOlat1
+    'para':     0x00b6, # pilcrow sign = paragraph sign, U+00B6 ISOnum
+    'part':     0x2202, # partial differential, U+2202 ISOtech
+    'permil':   0x2030, # per mille sign, U+2030 ISOtech
+    'perp':     0x22a5, # up tack = orthogonal to = perpendicular, U+22A5 ISOtech
+    'phi':      0x03c6, # greek small letter phi, U+03C6 ISOgrk3
+    'pi':       0x03c0, # greek small letter pi, U+03C0 ISOgrk3
+    'piv':      0x03d6, # greek pi symbol, U+03D6 ISOgrk3
+    'plusmn':   0x00b1, # plus-minus sign = plus-or-minus sign, U+00B1 ISOnum
+    'pound':    0x00a3, # pound sign, U+00A3 ISOnum
+    'prime':    0x2032, # prime = minutes = feet, U+2032 ISOtech
+    'prod':     0x220f, # n-ary product = product sign, U+220F ISOamsb
+    'prop':     0x221d, # proportional to, U+221D ISOtech
+    'psi':      0x03c8, # greek small letter psi, U+03C8 ISOgrk3
+    'quot':     0x0022, # quotation mark = APL quote, U+0022 ISOnum
+    'rArr':     0x21d2, # rightwards double arrow, U+21D2 ISOtech
+    'radic':    0x221a, # square root = radical sign, U+221A ISOtech
+    'rang':     0x232a, # right-pointing angle bracket = ket, U+232A ISOtech
+    'raquo':    0x00bb, # right-pointing double angle quotation mark = right pointing guillemet, U+00BB ISOnum
+    'rarr':     0x2192, # rightwards arrow, U+2192 ISOnum
+    'rceil':    0x2309, # right ceiling, U+2309 ISOamsc
+    'rdquo':    0x201d, # right double quotation mark, U+201D ISOnum
+    'real':     0x211c, # blackletter capital R = real part symbol, U+211C ISOamso
+    'reg':      0x00ae, # registered sign = registered trade mark sign, U+00AE ISOnum
+    'rfloor':   0x230b, # right floor, U+230B ISOamsc
+    'rho':      0x03c1, # greek small letter rho, U+03C1 ISOgrk3
+    'rlm':      0x200f, # right-to-left mark, U+200F NEW RFC 2070
+    'rsaquo':   0x203a, # single right-pointing angle quotation mark, U+203A ISO proposed
+    'rsquo':    0x2019, # right single quotation mark, U+2019 ISOnum
+    'sbquo':    0x201a, # single low-9 quotation mark, U+201A NEW
+    'scaron':   0x0161, # latin small letter s with caron, U+0161 ISOlat2
+    'sdot':     0x22c5, # dot operator, U+22C5 ISOamsb
+    'sect':     0x00a7, # section sign, U+00A7 ISOnum
+    'shy':      0x00ad, # soft hyphen = discretionary hyphen, U+00AD ISOnum
+    'sigma':    0x03c3, # greek small letter sigma, U+03C3 ISOgrk3
+    'sigmaf':   0x03c2, # greek small letter final sigma, U+03C2 ISOgrk3
+    'sim':      0x223c, # tilde operator = varies with = similar to, U+223C ISOtech
+    'spades':   0x2660, # black spade suit, U+2660 ISOpub
+    'sub':      0x2282, # subset of, U+2282 ISOtech
+    'sube':     0x2286, # subset of or equal to, U+2286 ISOtech
+    'sum':      0x2211, # n-ary sumation, U+2211 ISOamsb
+    'sup':      0x2283, # superset of, U+2283 ISOtech
+    'sup1':     0x00b9, # superscript one = superscript digit one, U+00B9 ISOnum
+    'sup2':     0x00b2, # superscript two = superscript digit two = squared, U+00B2 ISOnum
+    'sup3':     0x00b3, # superscript three = superscript digit three = cubed, U+00B3 ISOnum
+    'supe':     0x2287, # superset of or equal to, U+2287 ISOtech
+    'szlig':    0x00df, # latin small letter sharp s = ess-zed, U+00DF ISOlat1
+    'tau':      0x03c4, # greek small letter tau, U+03C4 ISOgrk3
+    'there4':   0x2234, # therefore, U+2234 ISOtech
+    'theta':    0x03b8, # greek small letter theta, U+03B8 ISOgrk3
+    'thetasym': 0x03d1, # greek small letter theta symbol, U+03D1 NEW
+    'thinsp':   0x2009, # thin space, U+2009 ISOpub
+    'thorn':    0x00fe, # latin small letter thorn with, U+00FE ISOlat1
+    'tilde':    0x02dc, # small tilde, U+02DC ISOdia
+    'times':    0x00d7, # multiplication sign, U+00D7 ISOnum
+    'trade':    0x2122, # trade mark sign, U+2122 ISOnum
+    'uArr':     0x21d1, # upwards double arrow, U+21D1 ISOamsa
+    'uacute':   0x00fa, # latin small letter u with acute, U+00FA ISOlat1
+    'uarr':     0x2191, # upwards arrow, U+2191 ISOnum
+    'ucirc':    0x00fb, # latin small letter u with circumflex, U+00FB ISOlat1
+    'ugrave':   0x00f9, # latin small letter u with grave, U+00F9 ISOlat1
+    'uml':      0x00a8, # diaeresis = spacing diaeresis, U+00A8 ISOdia
+    'upsih':    0x03d2, # greek upsilon with hook symbol, U+03D2 NEW
+    'upsilon':  0x03c5, # greek small letter upsilon, U+03C5 ISOgrk3
+    'uuml':     0x00fc, # latin small letter u with diaeresis, U+00FC ISOlat1
+    'weierp':   0x2118, # script capital P = power set = Weierstrass p, U+2118 ISOamso
+    'xi':       0x03be, # greek small letter xi, U+03BE ISOgrk3
+    'yacute':   0x00fd, # latin small letter y with acute, U+00FD ISOlat1
+    'yen':      0x00a5, # yen sign = yuan sign, U+00A5 ISOnum
+    'yuml':     0x00ff, # latin small letter y with diaeresis, U+00FF ISOlat1
+    'zeta':     0x03b6, # greek small letter zeta, U+03B6 ISOgrk3
+    'zwj':      0x200d, # zero width joiner, U+200D NEW RFC 2070
+    'zwnj':     0x200c, # zero width non-joiner, U+200C NEW RFC 2070
+}
+
+# maps the Unicode codepoint to the HTML entity name
+codepoint2name = {}
+
+# maps the HTML entity name to the character
+# (or a character reference if the character is outside the Latin-1 range)
+entitydefs = {}
+
+for (name, codepoint) in name2codepoint.iteritems():
+    codepoint2name[codepoint] = name
+    if codepoint <= 0xff:
+        entitydefs[name] = chr(codepoint)
+    else:
+        entitydefs[name] = '&#%d;' % codepoint
+
+del name, codepoint

Added: vendor/Python/current/Lib/htmllib.py
===================================================================
--- vendor/Python/current/Lib/htmllib.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/htmllib.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,486 @@
+"""HTML 2.0 parser.
+
+See the HTML 2.0 specification:
+http://www.w3.org/hypertext/WWW/MarkUp/html-spec/html-spec_toc.html
+"""
+
+import sgmllib
+
+from formatter import AS_IS
+
+__all__ = ["HTMLParser", "HTMLParseError"]
+
+
+class HTMLParseError(sgmllib.SGMLParseError):
+    """Error raised when an HTML document can't be parsed."""
+
+
+class HTMLParser(sgmllib.SGMLParser):
+    """This is the basic HTML parser class.
+
+    It supports all entity names required by the XHTML 1.0 Recommendation.
+    It also defines handlers for all HTML 2.0 and many HTML 3.0 and 3.2
+    elements.
+
+    """
+
+    from htmlentitydefs import entitydefs
+
+    def __init__(self, formatter, verbose=0):
+        """Creates an instance of the HTMLParser class.
+
+        The formatter parameter is the formatter instance associated with
+        the parser.
+
+        """
+        sgmllib.SGMLParser.__init__(self, verbose)
+        self.formatter = formatter
+
+    def error(self, message):
+        raise HTMLParseError(message)
+
+    def reset(self):
+        sgmllib.SGMLParser.reset(self)
+        self.savedata = None
+        self.isindex = 0
+        self.title = None
+        self.base = None
+        self.anchor = None
+        self.anchorlist = []
+        self.nofill = 0
+        self.list_stack = []
+
+    # ------ Methods used internally; some may be overridden
+
+    # --- Formatter interface, taking care of 'savedata' mode;
+    # shouldn't need to be overridden
+
+    def handle_data(self, data):
+        if self.savedata is not None:
+            self.savedata = self.savedata + data
+        else:
+            if self.nofill:
+                self.formatter.add_literal_data(data)
+            else:
+                self.formatter.add_flowing_data(data)
+
+    # --- Hooks to save data; shouldn't need to be overridden
+
+    def save_bgn(self):
+        """Begins saving character data in a buffer instead of sending it
+        to the formatter object.
+
+        Retrieve the stored data via the save_end() method.  Use of the
+        save_bgn() / save_end() pair may not be nested.
+
+        """
+        self.savedata = ''
+
+    def save_end(self):
+        """Ends buffering character data and returns all data saved since
+        the preceding call to the save_bgn() method.
+
+        If the nofill flag is false, whitespace is collapsed to single
+        spaces.  A call to this method without a preceding call to the
+        save_bgn() method will raise a TypeError exception.
+
+        """
+        data = self.savedata
+        self.savedata = None
+        if not self.nofill:
+            data = ' '.join(data.split())
+        return data
+
+    # --- Hooks for anchors; should probably be overridden
+
+    def anchor_bgn(self, href, name, type):
+        """This method is called at the start of an anchor region.
+
+        The arguments correspond to the attributes of the <A> tag with
+        the same names.  The default implementation maintains a list of
+        hyperlinks (defined by the HREF attribute for <A> tags) within
+        the document.  The list of hyperlinks is available as the data
+        attribute anchorlist.
+
+        """
+        self.anchor = href
+        if self.anchor:
+            self.anchorlist.append(href)
+
+    def anchor_end(self):
+        """This method is called at the end of an anchor region.
+
+        The default implementation adds a textual footnote marker using an
+        index into the list of hyperlinks created by the anchor_bgn()method.
+
+        """
+        if self.anchor:
+            self.handle_data("[%d]" % len(self.anchorlist))
+            self.anchor = None
+
+    # --- Hook for images; should probably be overridden
+
+    def handle_image(self, src, alt, *args):
+        """This method is called to handle images.
+
+        The default implementation simply passes the alt value to the
+        handle_data() method.
+
+        """
+        self.handle_data(alt)
+
+    # --------- Top level elememts
+
+    def start_html(self, attrs): pass
+    def end_html(self): pass
+
+    def start_head(self, attrs): pass
+    def end_head(self): pass
+
+    def start_body(self, attrs): pass
+    def end_body(self): pass
+
+    # ------ Head elements
+
+    def start_title(self, attrs):
+        self.save_bgn()
+
+    def end_title(self):
+        self.title = self.save_end()
+
+    def do_base(self, attrs):
+        for a, v in attrs:
+            if a == 'href':
+                self.base = v
+
+    def do_isindex(self, attrs):
+        self.isindex = 1
+
+    def do_link(self, attrs):
+        pass
+
+    def do_meta(self, attrs):
+        pass
+
+    def do_nextid(self, attrs): # Deprecated
+        pass
+
+    # ------ Body elements
+
+    # --- Headings
+
+    def start_h1(self, attrs):
+        self.formatter.end_paragraph(1)
+        self.formatter.push_font(('h1', 0, 1, 0))
+
+    def end_h1(self):
+        self.formatter.end_paragraph(1)
+        self.formatter.pop_font()
+
+    def start_h2(self, attrs):
+        self.formatter.end_paragraph(1)
+        self.formatter.push_font(('h2', 0, 1, 0))
+
+    def end_h2(self):
+        self.formatter.end_paragraph(1)
+        self.formatter.pop_font()
+
+    def start_h3(self, attrs):
+        self.formatter.end_paragraph(1)
+        self.formatter.push_font(('h3', 0, 1, 0))
+
+    def end_h3(self):
+        self.formatter.end_paragraph(1)
+        self.formatter.pop_font()
+
+    def start_h4(self, attrs):
+        self.formatter.end_paragraph(1)
+        self.formatter.push_font(('h4', 0, 1, 0))
+
+    def end_h4(self):
+        self.formatter.end_paragraph(1)
+        self.formatter.pop_font()
+
+    def start_h5(self, attrs):
+        self.formatter.end_paragraph(1)
+        self.formatter.push_font(('h5', 0, 1, 0))
+
+    def end_h5(self):
+        self.formatter.end_paragraph(1)
+        self.formatter.pop_font()
+
+    def start_h6(self, attrs):
+        self.formatter.end_paragraph(1)
+        self.formatter.push_font(('h6', 0, 1, 0))
+
+    def end_h6(self):
+        self.formatter.end_paragraph(1)
+        self.formatter.pop_font()
+
+    # --- Block Structuring Elements
+
+    def do_p(self, attrs):
+        self.formatter.end_paragraph(1)
+
+    def start_pre(self, attrs):
+        self.formatter.end_paragraph(1)
+        self.formatter.push_font((AS_IS, AS_IS, AS_IS, 1))
+        self.nofill = self.nofill + 1
+
+    def end_pre(self):
+        self.formatter.end_paragraph(1)
+        self.formatter.pop_font()
+        self.nofill = max(0, self.nofill - 1)
+
+    def start_xmp(self, attrs):
+        self.start_pre(attrs)
+        self.setliteral('xmp') # Tell SGML parser
+
+    def end_xmp(self):
+        self.end_pre()
+
+    def start_listing(self, attrs):
+        self.start_pre(attrs)
+        self.setliteral('listing') # Tell SGML parser
+
+    def end_listing(self):
+        self.end_pre()
+
+    def start_address(self, attrs):
+        self.formatter.end_paragraph(0)
+        self.formatter.push_font((AS_IS, 1, AS_IS, AS_IS))
+
+    def end_address(self):
+        self.formatter.end_paragraph(0)
+        self.formatter.pop_font()
+
+    def start_blockquote(self, attrs):
+        self.formatter.end_paragraph(1)
+        self.formatter.push_margin('blockquote')
+
+    def end_blockquote(self):
+        self.formatter.end_paragraph(1)
+        self.formatter.pop_margin()
+
+    # --- List Elements
+
+    def start_ul(self, attrs):
+        self.formatter.end_paragraph(not self.list_stack)
+        self.formatter.push_margin('ul')
+        self.list_stack.append(['ul', '*', 0])
+
+    def end_ul(self):
+        if self.list_stack: del self.list_stack[-1]
+        self.formatter.end_paragraph(not self.list_stack)
+        self.formatter.pop_margin()
+
+    def do_li(self, attrs):
+        self.formatter.end_paragraph(0)
+        if self.list_stack:
+            [dummy, label, counter] = top = self.list_stack[-1]
+            top[2] = counter = counter+1
+        else:
+            label, counter = '*', 0
+        self.formatter.add_label_data(label, counter)
+
+    def start_ol(self, attrs):
+        self.formatter.end_paragraph(not self.list_stack)
+        self.formatter.push_margin('ol')
+        label = '1.'
+        for a, v in attrs:
+            if a == 'type':
+                if len(v) == 1: v = v + '.'
+                label = v
+        self.list_stack.append(['ol', label, 0])
+
+    def end_ol(self):
+        if self.list_stack: del self.list_stack[-1]
+        self.formatter.end_paragraph(not self.list_stack)
+        self.formatter.pop_margin()
+
+    def start_menu(self, attrs):
+        self.start_ul(attrs)
+
+    def end_menu(self):
+        self.end_ul()
+
+    def start_dir(self, attrs):
+        self.start_ul(attrs)
+
+    def end_dir(self):
+        self.end_ul()
+
+    def start_dl(self, attrs):
+        self.formatter.end_paragraph(1)
+        self.list_stack.append(['dl', '', 0])
+
+    def end_dl(self):
+        self.ddpop(1)
+        if self.list_stack: del self.list_stack[-1]
+
+    def do_dt(self, attrs):
+        self.ddpop()
+
+    def do_dd(self, attrs):
+        self.ddpop()
+        self.formatter.push_margin('dd')
+        self.list_stack.append(['dd', '', 0])
+
+    def ddpop(self, bl=0):
+        self.formatter.end_paragraph(bl)
+        if self.list_stack:
+            if self.list_stack[-1][0] == 'dd':
+                del self.list_stack[-1]
+                self.formatter.pop_margin()
+
+    # --- Phrase Markup
+
+    # Idiomatic Elements
+
+    def start_cite(self, attrs): self.start_i(attrs)
+    def end_cite(self): self.end_i()
+
+    def start_code(self, attrs): self.start_tt(attrs)
+    def end_code(self): self.end_tt()
+
+    def start_em(self, attrs): self.start_i(attrs)
+    def end_em(self): self.end_i()
+
+    def start_kbd(self, attrs): self.start_tt(attrs)
+    def end_kbd(self): self.end_tt()
+
+    def start_samp(self, attrs): self.start_tt(attrs)
+    def end_samp(self): self.end_tt()
+
+    def start_strong(self, attrs): self.start_b(attrs)
+    def end_strong(self): self.end_b()
+
+    def start_var(self, attrs): self.start_i(attrs)
+    def end_var(self): self.end_i()
+
+    # Typographic Elements
+
+    def start_i(self, attrs):
+        self.formatter.push_font((AS_IS, 1, AS_IS, AS_IS))
+    def end_i(self):
+        self.formatter.pop_font()
+
+    def start_b(self, attrs):
+        self.formatter.push_font((AS_IS, AS_IS, 1, AS_IS))
+    def end_b(self):
+        self.formatter.pop_font()
+
+    def start_tt(self, attrs):
+        self.formatter.push_font((AS_IS, AS_IS, AS_IS, 1))
+    def end_tt(self):
+        self.formatter.pop_font()
+
+    def start_a(self, attrs):
+        href = ''
+        name = ''
+        type = ''
+        for attrname, value in attrs:
+            value = value.strip()
+            if attrname == 'href':
+                href = value
+            if attrname == 'name':
+                name = value
+            if attrname == 'type':
+                type = value.lower()
+        self.anchor_bgn(href, name, type)
+
+    def end_a(self):
+        self.anchor_end()
+
+    # --- Line Break
+
+    def do_br(self, attrs):
+        self.formatter.add_line_break()
+
+    # --- Horizontal Rule
+
+    def do_hr(self, attrs):
+        self.formatter.add_hor_rule()
+
+    # --- Image
+
+    def do_img(self, attrs):
+        align = ''
+        alt = '(image)'
+        ismap = ''
+        src = ''
+        width = 0
+        height = 0
+        for attrname, value in attrs:
+            if attrname == 'align':
+                align = value
+            if attrname == 'alt':
+                alt = value
+            if attrname == 'ismap':
+                ismap = value
+            if attrname == 'src':
+                src = value
+            if attrname == 'width':
+                try: width = int(value)
+                except ValueError: pass
+            if attrname == 'height':
+                try: height = int(value)
+                except ValueError: pass
+        self.handle_image(src, alt, ismap, align, width, height)
+
+    # --- Really Old Unofficial Deprecated Stuff
+
+    def do_plaintext(self, attrs):
+        self.start_pre(attrs)
+        self.setnomoretags() # Tell SGML parser
+
+    # --- Unhandled tags
+
+    def unknown_starttag(self, tag, attrs):
+        pass
+
+    def unknown_endtag(self, tag):
+        pass
+
+
+def test(args = None):
+    import sys, formatter
+
+    if not args:
+        args = sys.argv[1:]
+
+    silent = args and args[0] == '-s'
+    if silent:
+        del args[0]
+
+    if args:
+        file = args[0]
+    else:
+        file = 'test.html'
+
+    if file == '-':
+        f = sys.stdin
+    else:
+        try:
+            f = open(file, 'r')
+        except IOError, msg:
+            print file, ":", msg
+            sys.exit(1)
+
+    data = f.read()
+
+    if f is not sys.stdin:
+        f.close()
+
+    if silent:
+        f = formatter.NullFormatter()
+    else:
+        f = formatter.AbstractFormatter(formatter.DumbWriter())
+
+    p = HTMLParser(f)
+    p.feed(data)
+    p.close()
+
+
+if __name__ == '__main__':
+    test()

Added: vendor/Python/current/Lib/httplib.py
===================================================================
--- vendor/Python/current/Lib/httplib.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/httplib.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1428 @@
+"""HTTP/1.1 client library
+
+<intro stuff goes here>
+<other stuff, too>
+
+HTTPConnection goes through a number of "states", which define when a client
+may legally make another request or fetch the response for a particular
+request. This diagram details these state transitions:
+
+    (null)
+      |
+      | HTTPConnection()
+      v
+    Idle
+      |
+      | putrequest()
+      v
+    Request-started
+      |
+      | ( putheader() )*  endheaders()
+      v
+    Request-sent
+      |
+      | response = getresponse()
+      v
+    Unread-response   [Response-headers-read]
+      |\____________________
+      |                     |
+      | response.read()     | putrequest()
+      v                     v
+    Idle                  Req-started-unread-response
+                     ______/|
+                   /        |
+   response.read() |        | ( putheader() )*  endheaders()
+                   v        v
+       Request-started    Req-sent-unread-response
+                            |
+                            | response.read()
+                            v
+                          Request-sent
+
+This diagram presents the following rules:
+  -- a second request may not be started until {response-headers-read}
+  -- a response [object] cannot be retrieved until {request-sent}
+  -- there is no differentiation between an unread response body and a
+     partially read response body
+
+Note: this enforcement is applied by the HTTPConnection class. The
+      HTTPResponse class does not enforce this state machine, which
+      implies sophisticated clients may accelerate the request/response
+      pipeline. Caution should be taken, though: accelerating the states
+      beyond the above pattern may imply knowledge of the server's
+      connection-close behavior for certain requests. For example, it
+      is impossible to tell whether the server will close the connection
+      UNTIL the response headers have been read; this means that further
+      requests cannot be placed into the pipeline until it is known that
+      the server will NOT be closing the connection.
+
+Logical State                  __state            __response
+-------------                  -------            ----------
+Idle                           _CS_IDLE           None
+Request-started                _CS_REQ_STARTED    None
+Request-sent                   _CS_REQ_SENT       None
+Unread-response                _CS_IDLE           <response_class>
+Req-started-unread-response    _CS_REQ_STARTED    <response_class>
+Req-sent-unread-response       _CS_REQ_SENT       <response_class>
+"""
+
+import errno
+import mimetools
+import socket
+from urlparse import urlsplit
+
+try:
+    from cStringIO import StringIO
+except ImportError:
+    from StringIO import StringIO
+
+__all__ = ["HTTP", "HTTPResponse", "HTTPConnection", "HTTPSConnection",
+           "HTTPException", "NotConnected", "UnknownProtocol",
+           "UnknownTransferEncoding", "UnimplementedFileMode",
+           "IncompleteRead", "InvalidURL", "ImproperConnectionState",
+           "CannotSendRequest", "CannotSendHeader", "ResponseNotReady",
+           "BadStatusLine", "error", "responses"]
+
+HTTP_PORT = 80
+HTTPS_PORT = 443
+
+_UNKNOWN = 'UNKNOWN'
+
+# connection states
+_CS_IDLE = 'Idle'
+_CS_REQ_STARTED = 'Request-started'
+_CS_REQ_SENT = 'Request-sent'
+
+# status codes
+# informational
+CONTINUE = 100
+SWITCHING_PROTOCOLS = 101
+PROCESSING = 102
+
+# successful
+OK = 200
+CREATED = 201
+ACCEPTED = 202
+NON_AUTHORITATIVE_INFORMATION = 203
+NO_CONTENT = 204
+RESET_CONTENT = 205
+PARTIAL_CONTENT = 206
+MULTI_STATUS = 207
+IM_USED = 226
+
+# redirection
+MULTIPLE_CHOICES = 300
+MOVED_PERMANENTLY = 301
+FOUND = 302
+SEE_OTHER = 303
+NOT_MODIFIED = 304
+USE_PROXY = 305
+TEMPORARY_REDIRECT = 307
+
+# client error
+BAD_REQUEST = 400
+UNAUTHORIZED = 401
+PAYMENT_REQUIRED = 402
+FORBIDDEN = 403
+NOT_FOUND = 404
+METHOD_NOT_ALLOWED = 405
+NOT_ACCEPTABLE = 406
+PROXY_AUTHENTICATION_REQUIRED = 407
+REQUEST_TIMEOUT = 408
+CONFLICT = 409
+GONE = 410
+LENGTH_REQUIRED = 411
+PRECONDITION_FAILED = 412
+REQUEST_ENTITY_TOO_LARGE = 413
+REQUEST_URI_TOO_LONG = 414
+UNSUPPORTED_MEDIA_TYPE = 415
+REQUESTED_RANGE_NOT_SATISFIABLE = 416
+EXPECTATION_FAILED = 417
+UNPROCESSABLE_ENTITY = 422
+LOCKED = 423
+FAILED_DEPENDENCY = 424
+UPGRADE_REQUIRED = 426
+
+# server error
+INTERNAL_SERVER_ERROR = 500
+NOT_IMPLEMENTED = 501
+BAD_GATEWAY = 502
+SERVICE_UNAVAILABLE = 503
+GATEWAY_TIMEOUT = 504
+HTTP_VERSION_NOT_SUPPORTED = 505
+INSUFFICIENT_STORAGE = 507
+NOT_EXTENDED = 510
+
+# Mapping status codes to official W3C names
+responses = {
+    100: 'Continue',
+    101: 'Switching Protocols',
+
+    200: 'OK',
+    201: 'Created',
+    202: 'Accepted',
+    203: 'Non-Authoritative Information',
+    204: 'No Content',
+    205: 'Reset Content',
+    206: 'Partial Content',
+
+    300: 'Multiple Choices',
+    301: 'Moved Permanently',
+    302: 'Found',
+    303: 'See Other',
+    304: 'Not Modified',
+    305: 'Use Proxy',
+    306: '(Unused)',
+    307: 'Temporary Redirect',
+
+    400: 'Bad Request',
+    401: 'Unauthorized',
+    402: 'Payment Required',
+    403: 'Forbidden',
+    404: 'Not Found',
+    405: 'Method Not Allowed',
+    406: 'Not Acceptable',
+    407: 'Proxy Authentication Required',
+    408: 'Request Timeout',
+    409: 'Conflict',
+    410: 'Gone',
+    411: 'Length Required',
+    412: 'Precondition Failed',
+    413: 'Request Entity Too Large',
+    414: 'Request-URI Too Long',
+    415: 'Unsupported Media Type',
+    416: 'Requested Range Not Satisfiable',
+    417: 'Expectation Failed',
+
+    500: 'Internal Server Error',
+    501: 'Not Implemented',
+    502: 'Bad Gateway',
+    503: 'Service Unavailable',
+    504: 'Gateway Timeout',
+    505: 'HTTP Version Not Supported',
+}
+
+# maximal amount of data to read at one time in _safe_read
+MAXAMOUNT = 1048576
+
+class HTTPMessage(mimetools.Message):
+
+    def addheader(self, key, value):
+        """Add header for field key handling repeats."""
+        prev = self.dict.get(key)
+        if prev is None:
+            self.dict[key] = value
+        else:
+            combined = ", ".join((prev, value))
+            self.dict[key] = combined
+
+    def addcontinue(self, key, more):
+        """Add more field data from a continuation line."""
+        prev = self.dict[key]
+        self.dict[key] = prev + "\n " + more
+
+    def readheaders(self):
+        """Read header lines.
+
+        Read header lines up to the entirely blank line that terminates them.
+        The (normally blank) line that ends the headers is skipped, but not
+        included in the returned list.  If a non-header line ends the headers,
+        (which is an error), an attempt is made to backspace over it; it is
+        never included in the returned list.
+
+        The variable self.status is set to the empty string if all went well,
+        otherwise it is an error message.  The variable self.headers is a
+        completely uninterpreted list of lines contained in the header (so
+        printing them will reproduce the header exactly as it appears in the
+        file).
+
+        If multiple header fields with the same name occur, they are combined
+        according to the rules in RFC 2616 sec 4.2:
+
+        Appending each subsequent field-value to the first, each separated
+        by a comma. The order in which header fields with the same field-name
+        are received is significant to the interpretation of the combined
+        field value.
+        """
+        # XXX The implementation overrides the readheaders() method of
+        # rfc822.Message.  The base class design isn't amenable to
+        # customized behavior here so the method here is a copy of the
+        # base class code with a few small changes.
+
+        self.dict = {}
+        self.unixfrom = ''
+        self.headers = hlist = []
+        self.status = ''
+        headerseen = ""
+        firstline = 1
+        startofline = unread = tell = None
+        if hasattr(self.fp, 'unread'):
+            unread = self.fp.unread
+        elif self.seekable:
+            tell = self.fp.tell
+        while True:
+            if tell:
+                try:
+                    startofline = tell()
+                except IOError:
+                    startofline = tell = None
+                    self.seekable = 0
+            line = self.fp.readline()
+            if not line:
+                self.status = 'EOF in headers'
+                break
+            # Skip unix From name time lines
+            if firstline and line.startswith('From '):
+                self.unixfrom = self.unixfrom + line
+                continue
+            firstline = 0
+            if headerseen and line[0] in ' \t':
+                # XXX Not sure if continuation lines are handled properly
+                # for http and/or for repeating headers
+                # It's a continuation line.
+                hlist.append(line)
+                self.addcontinue(headerseen, line.strip())
+                continue
+            elif self.iscomment(line):
+                # It's a comment.  Ignore it.
+                continue
+            elif self.islast(line):
+                # Note! No pushback here!  The delimiter line gets eaten.
+                break
+            headerseen = self.isheader(line)
+            if headerseen:
+                # It's a legal header line, save it.
+                hlist.append(line)
+                self.addheader(headerseen, line[len(headerseen)+1:].strip())
+                continue
+            else:
+                # It's not a header line; throw it back and stop here.
+                if not self.dict:
+                    self.status = 'No headers'
+                else:
+                    self.status = 'Non-header line where header expected'
+                # Try to undo the read.
+                if unread:
+                    unread(line)
+                elif tell:
+                    self.fp.seek(startofline)
+                else:
+                    self.status = self.status + '; bad seek'
+                break
+
+class HTTPResponse:
+
+    # strict: If true, raise BadStatusLine if the status line can't be
+    # parsed as a valid HTTP/1.0 or 1.1 status line.  By default it is
+    # false because it prevents clients from talking to HTTP/0.9
+    # servers.  Note that a response with a sufficiently corrupted
+    # status line will look like an HTTP/0.9 response.
+
+    # See RFC 2616 sec 19.6 and RFC 1945 sec 6 for details.
+
+    def __init__(self, sock, debuglevel=0, strict=0, method=None):
+        self.fp = sock.makefile('rb', 0)
+        self.debuglevel = debuglevel
+        self.strict = strict
+        self._method = method
+
+        self.msg = None
+
+        # from the Status-Line of the response
+        self.version = _UNKNOWN # HTTP-Version
+        self.status = _UNKNOWN  # Status-Code
+        self.reason = _UNKNOWN  # Reason-Phrase
+
+        self.chunked = _UNKNOWN         # is "chunked" being used?
+        self.chunk_left = _UNKNOWN      # bytes left to read in current chunk
+        self.length = _UNKNOWN          # number of bytes left in response
+        self.will_close = _UNKNOWN      # conn will close at end of response
+
+    def _read_status(self):
+        # Initialize with Simple-Response defaults
+        line = self.fp.readline()
+        if self.debuglevel > 0:
+            print "reply:", repr(line)
+        if not line:
+            # Presumably, the server closed the connection before
+            # sending a valid response.
+            raise BadStatusLine(line)
+        try:
+            [version, status, reason] = line.split(None, 2)
+        except ValueError:
+            try:
+                [version, status] = line.split(None, 1)
+                reason = ""
+            except ValueError:
+                # empty version will cause next test to fail and status
+                # will be treated as 0.9 response.
+                version = ""
+        if not version.startswith('HTTP/'):
+            if self.strict:
+                self.close()
+                raise BadStatusLine(line)
+            else:
+                # assume it's a Simple-Response from an 0.9 server
+                self.fp = LineAndFileWrapper(line, self.fp)
+                return "HTTP/0.9", 200, ""
+
+        # The status code is a three-digit number
+        try:
+            status = int(status)
+            if status < 100 or status > 999:
+                raise BadStatusLine(line)
+        except ValueError:
+            raise BadStatusLine(line)
+        return version, status, reason
+
+    def begin(self):
+        if self.msg is not None:
+            # we've already started reading the response
+            return
+
+        # read until we get a non-100 response
+        while True:
+            version, status, reason = self._read_status()
+            if status != CONTINUE:
+                break
+            # skip the header from the 100 response
+            while True:
+                skip = self.fp.readline().strip()
+                if not skip:
+                    break
+                if self.debuglevel > 0:
+                    print "header:", skip
+
+        self.status = status
+        self.reason = reason.strip()
+        if version == 'HTTP/1.0':
+            self.version = 10
+        elif version.startswith('HTTP/1.'):
+            self.version = 11   # use HTTP/1.1 code for HTTP/1.x where x>=1
+        elif version == 'HTTP/0.9':
+            self.version = 9
+        else:
+            raise UnknownProtocol(version)
+
+        if self.version == 9:
+            self.length = None
+            self.chunked = 0
+            self.will_close = 1
+            self.msg = HTTPMessage(StringIO())
+            return
+
+        self.msg = HTTPMessage(self.fp, 0)
+        if self.debuglevel > 0:
+            for hdr in self.msg.headers:
+                print "header:", hdr,
+
+        # don't let the msg keep an fp
+        self.msg.fp = None
+
+        # are we using the chunked-style of transfer encoding?
+        tr_enc = self.msg.getheader('transfer-encoding')
+        if tr_enc and tr_enc.lower() == "chunked":
+            self.chunked = 1
+            self.chunk_left = None
+        else:
+            self.chunked = 0
+
+        # will the connection close at the end of the response?
+        self.will_close = self._check_close()
+
+        # do we have a Content-Length?
+        # NOTE: RFC 2616, S4.4, #3 says we ignore this if tr_enc is "chunked"
+        length = self.msg.getheader('content-length')
+        if length and not self.chunked:
+            try:
+                self.length = int(length)
+            except ValueError:
+                self.length = None
+        else:
+            self.length = None
+
+        # does the body have a fixed length? (of zero)
+        if (status == NO_CONTENT or status == NOT_MODIFIED or
+            100 <= status < 200 or      # 1xx codes
+            self._method == 'HEAD'):
+            self.length = 0
+
+        # if the connection remains open, and we aren't using chunked, and
+        # a content-length was not provided, then assume that the connection
+        # WILL close.
+        if not self.will_close and \
+           not self.chunked and \
+           self.length is None:
+            self.will_close = 1
+
+    def _check_close(self):
+        conn = self.msg.getheader('connection')
+        if self.version == 11:
+            # An HTTP/1.1 proxy is assumed to stay open unless
+            # explicitly closed.
+            conn = self.msg.getheader('connection')
+            if conn and "close" in conn.lower():
+                return True
+            return False
+
+        # Some HTTP/1.0 implementations have support for persistent
+        # connections, using rules different than HTTP/1.1.
+
+        # For older HTTP, Keep-Alive indiciates persistent connection.
+        if self.msg.getheader('keep-alive'):
+            return False
+
+        # At least Akamai returns a "Connection: Keep-Alive" header,
+        # which was supposed to be sent by the client.
+        if conn and "keep-alive" in conn.lower():
+            return False
+
+        # Proxy-Connection is a netscape hack.
+        pconn = self.msg.getheader('proxy-connection')
+        if pconn and "keep-alive" in pconn.lower():
+            return False
+
+        # otherwise, assume it will close
+        return True
+
+    def close(self):
+        if self.fp:
+            self.fp.close()
+            self.fp = None
+
+    def isclosed(self):
+        # NOTE: it is possible that we will not ever call self.close(). This
+        #       case occurs when will_close is TRUE, length is None, and we
+        #       read up to the last byte, but NOT past it.
+        #
+        # IMPLIES: if will_close is FALSE, then self.close() will ALWAYS be
+        #          called, meaning self.isclosed() is meaningful.
+        return self.fp is None
+
+    # XXX It would be nice to have readline and __iter__ for this, too.
+
+    def read(self, amt=None):
+        if self.fp is None:
+            return ''
+
+        if self.chunked:
+            return self._read_chunked(amt)
+
+        if amt is None:
+            # unbounded read
+            if self.length is None:
+                s = self.fp.read()
+            else:
+                s = self._safe_read(self.length)
+                self.length = 0
+            self.close()        # we read everything
+            return s
+
+        if self.length is not None:
+            if amt > self.length:
+                # clip the read to the "end of response"
+                amt = self.length
+
+        # we do not use _safe_read() here because this may be a .will_close
+        # connection, and the user is reading more bytes than will be provided
+        # (for example, reading in 1k chunks)
+        s = self.fp.read(amt)
+        if self.length is not None:
+            self.length -= len(s)
+
+        return s
+
+    def _read_chunked(self, amt):
+        assert self.chunked != _UNKNOWN
+        chunk_left = self.chunk_left
+        value = ''
+
+        # XXX This accumulates chunks by repeated string concatenation,
+        # which is not efficient as the number or size of chunks gets big.
+        while True:
+            if chunk_left is None:
+                line = self.fp.readline()
+                i = line.find(';')
+                if i >= 0:
+                    line = line[:i] # strip chunk-extensions
+                chunk_left = int(line, 16)
+                if chunk_left == 0:
+                    break
+            if amt is None:
+                value += self._safe_read(chunk_left)
+            elif amt < chunk_left:
+                value += self._safe_read(amt)
+                self.chunk_left = chunk_left - amt
+                return value
+            elif amt == chunk_left:
+                value += self._safe_read(amt)
+                self._safe_read(2)  # toss the CRLF at the end of the chunk
+                self.chunk_left = None
+                return value
+            else:
+                value += self._safe_read(chunk_left)
+                amt -= chunk_left
+
+            # we read the whole chunk, get another
+            self._safe_read(2)      # toss the CRLF at the end of the chunk
+            chunk_left = None
+
+        # read and discard trailer up to the CRLF terminator
+        ### note: we shouldn't have any trailers!
+        while True:
+            line = self.fp.readline()
+            if line == '\r\n':
+                break
+
+        # we read everything; close the "file"
+        self.close()
+
+        return value
+
+    def _safe_read(self, amt):
+        """Read the number of bytes requested, compensating for partial reads.
+
+        Normally, we have a blocking socket, but a read() can be interrupted
+        by a signal (resulting in a partial read).
+
+        Note that we cannot distinguish between EOF and an interrupt when zero
+        bytes have been read. IncompleteRead() will be raised in this
+        situation.
+
+        This function should be used when <amt> bytes "should" be present for
+        reading. If the bytes are truly not available (due to EOF), then the
+        IncompleteRead exception can be used to detect the problem.
+        """
+        s = []
+        while amt > 0:
+            chunk = self.fp.read(min(amt, MAXAMOUNT))
+            if not chunk:
+                raise IncompleteRead(s)
+            s.append(chunk)
+            amt -= len(chunk)
+        return ''.join(s)
+
+    def getheader(self, name, default=None):
+        if self.msg is None:
+            raise ResponseNotReady()
+        return self.msg.getheader(name, default)
+
+    def getheaders(self):
+        """Return list of (header, value) tuples."""
+        if self.msg is None:
+            raise ResponseNotReady()
+        return self.msg.items()
+
+
+class HTTPConnection:
+
+    _http_vsn = 11
+    _http_vsn_str = 'HTTP/1.1'
+
+    response_class = HTTPResponse
+    default_port = HTTP_PORT
+    auto_open = 1
+    debuglevel = 0
+    strict = 0
+
+    def __init__(self, host, port=None, strict=None):
+        self.sock = None
+        self._buffer = []
+        self.__response = None
+        self.__state = _CS_IDLE
+        self._method = None
+
+        self._set_hostport(host, port)
+        if strict is not None:
+            self.strict = strict
+
+    def _set_hostport(self, host, port):
+        if port is None:
+            i = host.rfind(':')
+            j = host.rfind(']')         # ipv6 addresses have [...]
+            if i > j:
+                try:
+                    port = int(host[i+1:])
+                except ValueError:
+                    raise InvalidURL("nonnumeric port: '%s'" % host[i+1:])
+                host = host[:i]
+            else:
+                port = self.default_port
+            if host and host[0] == '[' and host[-1] == ']':
+                host = host[1:-1]
+        self.host = host
+        self.port = port
+
+    def set_debuglevel(self, level):
+        self.debuglevel = level
+
+    def connect(self):
+        """Connect to the host and port specified in __init__."""
+        msg = "getaddrinfo returns an empty list"
+        for res in socket.getaddrinfo(self.host, self.port, 0,
+                                      socket.SOCK_STREAM):
+            af, socktype, proto, canonname, sa = res
+            try:
+                self.sock = socket.socket(af, socktype, proto)
+                if self.debuglevel > 0:
+                    print "connect: (%s, %s)" % (self.host, self.port)
+                self.sock.connect(sa)
+            except socket.error, msg:
+                if self.debuglevel > 0:
+                    print 'connect fail:', (self.host, self.port)
+                if self.sock:
+                    self.sock.close()
+                self.sock = None
+                continue
+            break
+        if not self.sock:
+            raise socket.error, msg
+
+    def close(self):
+        """Close the connection to the HTTP server."""
+        if self.sock:
+            self.sock.close()   # close it manually... there may be other refs
+            self.sock = None
+        if self.__response:
+            self.__response.close()
+            self.__response = None
+        self.__state = _CS_IDLE
+
+    def send(self, str):
+        """Send `str' to the server."""
+        if self.sock is None:
+            if self.auto_open:
+                self.connect()
+            else:
+                raise NotConnected()
+
+        # send the data to the server. if we get a broken pipe, then close
+        # the socket. we want to reconnect when somebody tries to send again.
+        #
+        # NOTE: we DO propagate the error, though, because we cannot simply
+        #       ignore the error... the caller will know if they can retry.
+        if self.debuglevel > 0:
+            print "send:", repr(str)
+        try:
+            self.sock.sendall(str)
+        except socket.error, v:
+            if v[0] == 32:      # Broken pipe
+                self.close()
+            raise
+
+    def _output(self, s):
+        """Add a line of output to the current request buffer.
+
+        Assumes that the line does *not* end with \\r\\n.
+        """
+        self._buffer.append(s)
+
+    def _send_output(self):
+        """Send the currently buffered request and clear the buffer.
+
+        Appends an extra \\r\\n to the buffer.
+        """
+        self._buffer.extend(("", ""))
+        msg = "\r\n".join(self._buffer)
+        del self._buffer[:]
+        self.send(msg)
+
+    def putrequest(self, method, url, skip_host=0, skip_accept_encoding=0):
+        """Send a request to the server.
+
+        `method' specifies an HTTP request method, e.g. 'GET'.
+        `url' specifies the object being requested, e.g. '/index.html'.
+        `skip_host' if True does not add automatically a 'Host:' header
+        `skip_accept_encoding' if True does not add automatically an
+           'Accept-Encoding:' header
+        """
+
+        # if a prior response has been completed, then forget about it.
+        if self.__response and self.__response.isclosed():
+            self.__response = None
+
+
+        # in certain cases, we cannot issue another request on this connection.
+        # this occurs when:
+        #   1) we are in the process of sending a request.   (_CS_REQ_STARTED)
+        #   2) a response to a previous request has signalled that it is going
+        #      to close the connection upon completion.
+        #   3) the headers for the previous response have not been read, thus
+        #      we cannot determine whether point (2) is true.   (_CS_REQ_SENT)
+        #
+        # if there is no prior response, then we can request at will.
+        #
+        # if point (2) is true, then we will have passed the socket to the
+        # response (effectively meaning, "there is no prior response"), and
+        # will open a new one when a new request is made.
+        #
+        # Note: if a prior response exists, then we *can* start a new request.
+        #       We are not allowed to begin fetching the response to this new
+        #       request, however, until that prior response is complete.
+        #
+        if self.__state == _CS_IDLE:
+            self.__state = _CS_REQ_STARTED
+        else:
+            raise CannotSendRequest()
+
+        # Save the method we use, we need it later in the response phase
+        self._method = method
+        if not url:
+            url = '/'
+        str = '%s %s %s' % (method, url, self._http_vsn_str)
+
+        self._output(str)
+
+        if self._http_vsn == 11:
+            # Issue some standard headers for better HTTP/1.1 compliance
+
+            if not skip_host:
+                # this header is issued *only* for HTTP/1.1
+                # connections. more specifically, this means it is
+                # only issued when the client uses the new
+                # HTTPConnection() class. backwards-compat clients
+                # will be using HTTP/1.0 and those clients may be
+                # issuing this header themselves. we should NOT issue
+                # it twice; some web servers (such as Apache) barf
+                # when they see two Host: headers
+
+                # If we need a non-standard port,include it in the
+                # header.  If the request is going through a proxy,
+                # but the host of the actual URL, not the host of the
+                # proxy.
+
+                netloc = ''
+                if url.startswith('http'):
+                    nil, netloc, nil, nil, nil = urlsplit(url)
+
+                if netloc:
+                    try:
+                        netloc_enc = netloc.encode("ascii")
+                    except UnicodeEncodeError:
+                        netloc_enc = netloc.encode("idna")
+                    self.putheader('Host', netloc_enc)
+                else:
+                    try:
+                        host_enc = self.host.encode("ascii")
+                    except UnicodeEncodeError:
+                        host_enc = self.host.encode("idna")
+                    if self.port == HTTP_PORT:
+                        self.putheader('Host', host_enc)
+                    else:
+                        self.putheader('Host', "%s:%s" % (host_enc, self.port))
+
+            # note: we are assuming that clients will not attempt to set these
+            #       headers since *this* library must deal with the
+            #       consequences. this also means that when the supporting
+            #       libraries are updated to recognize other forms, then this
+            #       code should be changed (removed or updated).
+
+            # we only want a Content-Encoding of "identity" since we don't
+            # support encodings such as x-gzip or x-deflate.
+            if not skip_accept_encoding:
+                self.putheader('Accept-Encoding', 'identity')
+
+            # we can accept "chunked" Transfer-Encodings, but no others
+            # NOTE: no TE header implies *only* "chunked"
+            #self.putheader('TE', 'chunked')
+
+            # if TE is supplied in the header, then it must appear in a
+            # Connection header.
+            #self.putheader('Connection', 'TE')
+
+        else:
+            # For HTTP/1.0, the server will assume "not chunked"
+            pass
+
+    def putheader(self, header, value):
+        """Send a request header line to the server.
+
+        For example: h.putheader('Accept', 'text/html')
+        """
+        if self.__state != _CS_REQ_STARTED:
+            raise CannotSendHeader()
+
+        str = '%s: %s' % (header, value)
+        self._output(str)
+
+    def endheaders(self):
+        """Indicate that the last header line has been sent to the server."""
+
+        if self.__state == _CS_REQ_STARTED:
+            self.__state = _CS_REQ_SENT
+        else:
+            raise CannotSendHeader()
+
+        self._send_output()
+
+    def request(self, method, url, body=None, headers={}):
+        """Send a complete request to the server."""
+
+        try:
+            self._send_request(method, url, body, headers)
+        except socket.error, v:
+            # trap 'Broken pipe' if we're allowed to automatically reconnect
+            if v[0] != 32 or not self.auto_open:
+                raise
+            # try one more time
+            self._send_request(method, url, body, headers)
+
+    def _send_request(self, method, url, body, headers):
+        # honour explicitly requested Host: and Accept-Encoding headers
+        header_names = dict.fromkeys([k.lower() for k in headers])
+        skips = {}
+        if 'host' in header_names:
+            skips['skip_host'] = 1
+        if 'accept-encoding' in header_names:
+            skips['skip_accept_encoding'] = 1
+
+        self.putrequest(method, url, **skips)
+
+        if body and ('content-length' not in header_names):
+            self.putheader('Content-Length', str(len(body)))
+        for hdr, value in headers.iteritems():
+            self.putheader(hdr, value)
+        self.endheaders()
+
+        if body:
+            self.send(body)
+
+    def getresponse(self):
+        "Get the response from the server."
+
+        # if a prior response has been completed, then forget about it.
+        if self.__response and self.__response.isclosed():
+            self.__response = None
+
+        #
+        # if a prior response exists, then it must be completed (otherwise, we
+        # cannot read this response's header to determine the connection-close
+        # behavior)
+        #
+        # note: if a prior response existed, but was connection-close, then the
+        # socket and response were made independent of this HTTPConnection
+        # object since a new request requires that we open a whole new
+        # connection
+        #
+        # this means the prior response had one of two states:
+        #   1) will_close: this connection was reset and the prior socket and
+        #                  response operate independently
+        #   2) persistent: the response was retained and we await its
+        #                  isclosed() status to become true.
+        #
+        if self.__state != _CS_REQ_SENT or self.__response:
+            raise ResponseNotReady()
+
+        if self.debuglevel > 0:
+            response = self.response_class(self.sock, self.debuglevel,
+                                           strict=self.strict,
+                                           method=self._method)
+        else:
+            response = self.response_class(self.sock, strict=self.strict,
+                                           method=self._method)
+
+        response.begin()
+        assert response.will_close != _UNKNOWN
+        self.__state = _CS_IDLE
+
+        if response.will_close:
+            # this effectively passes the connection to the response
+            self.close()
+        else:
+            # remember this, so we can tell when it is complete
+            self.__response = response
+
+        return response
+
+# The next several classes are used to define FakeSocket, a socket-like
+# interface to an SSL connection.
+
+# The primary complexity comes from faking a makefile() method.  The
+# standard socket makefile() implementation calls dup() on the socket
+# file descriptor.  As a consequence, clients can call close() on the
+# parent socket and its makefile children in any order.  The underlying
+# socket isn't closed until they are all closed.
+
+# The implementation uses reference counting to keep the socket open
+# until the last client calls close().  SharedSocket keeps track of
+# the reference counting and SharedSocketClient provides an constructor
+# and close() method that call incref() and decref() correctly.
+
+class SharedSocket:
+
+    def __init__(self, sock):
+        self.sock = sock
+        self._refcnt = 0
+
+    def incref(self):
+        self._refcnt += 1
+
+    def decref(self):
+        self._refcnt -= 1
+        assert self._refcnt >= 0
+        if self._refcnt == 0:
+            self.sock.close()
+
+    def __del__(self):
+        self.sock.close()
+
+class SharedSocketClient:
+
+    def __init__(self, shared):
+        self._closed = 0
+        self._shared = shared
+        self._shared.incref()
+        self._sock = shared.sock
+
+    def close(self):
+        if not self._closed:
+            self._shared.decref()
+            self._closed = 1
+            self._shared = None
+
+class SSLFile(SharedSocketClient):
+    """File-like object wrapping an SSL socket."""
+
+    BUFSIZE = 8192
+
+    def __init__(self, sock, ssl, bufsize=None):
+        SharedSocketClient.__init__(self, sock)
+        self._ssl = ssl
+        self._buf = ''
+        self._bufsize = bufsize or self.__class__.BUFSIZE
+
+    def _read(self):
+        buf = ''
+        # put in a loop so that we retry on transient errors
+        while True:
+            try:
+                buf = self._ssl.read(self._bufsize)
+            except socket.sslerror, err:
+                if (err[0] == socket.SSL_ERROR_WANT_READ
+                    or err[0] == socket.SSL_ERROR_WANT_WRITE):
+                    continue
+                if (err[0] == socket.SSL_ERROR_ZERO_RETURN
+                    or err[0] == socket.SSL_ERROR_EOF):
+                    break
+                raise
+            except socket.error, err:
+                if err[0] == errno.EINTR:
+                    continue
+                if err[0] == errno.EBADF:
+                    # XXX socket was closed?
+                    break
+                raise
+            else:
+                break
+        return buf
+
+    def read(self, size=None):
+        L = [self._buf]
+        avail = len(self._buf)
+        while size is None or avail < size:
+            s = self._read()
+            if s == '':
+                break
+            L.append(s)
+            avail += len(s)
+        all = "".join(L)
+        if size is None:
+            self._buf = ''
+            return all
+        else:
+            self._buf = all[size:]
+            return all[:size]
+
+    def readline(self):
+        L = [self._buf]
+        self._buf = ''
+        while 1:
+            i = L[-1].find("\n")
+            if i >= 0:
+                break
+            s = self._read()
+            if s == '':
+                break
+            L.append(s)
+        if i == -1:
+            # loop exited because there is no more data
+            return "".join(L)
+        else:
+            all = "".join(L)
+            # XXX could do enough bookkeeping not to do a 2nd search
+            i = all.find("\n") + 1
+            line = all[:i]
+            self._buf = all[i:]
+            return line
+
+    def readlines(self, sizehint=0):
+        total = 0
+        list = []
+        while True:
+            line = self.readline()
+            if not line:
+                break
+            list.append(line)
+            total += len(line)
+            if sizehint and total >= sizehint:
+                break
+        return list
+
+    def fileno(self):
+        return self._sock.fileno()
+
+    def __iter__(self):
+        return self
+
+    def next(self):
+        line = self.readline()
+        if not line:
+            raise StopIteration
+        return line
+
+class FakeSocket(SharedSocketClient):
+
+    class _closedsocket:
+        def __getattr__(self, name):
+            raise error(9, 'Bad file descriptor')
+
+    def __init__(self, sock, ssl):
+        sock = SharedSocket(sock)
+        SharedSocketClient.__init__(self, sock)
+        self._ssl = ssl
+
+    def close(self):
+        SharedSocketClient.close(self)
+        self._sock = self.__class__._closedsocket()
+
+    def makefile(self, mode, bufsize=None):
+        if mode != 'r' and mode != 'rb':
+            raise UnimplementedFileMode()
+        return SSLFile(self._shared, self._ssl, bufsize)
+
+    def send(self, stuff, flags = 0):
+        return self._ssl.write(stuff)
+
+    sendall = send
+
+    def recv(self, len = 1024, flags = 0):
+        return self._ssl.read(len)
+
+    def __getattr__(self, attr):
+        return getattr(self._sock, attr)
+
+
+class HTTPSConnection(HTTPConnection):
+    "This class allows communication via SSL."
+
+    default_port = HTTPS_PORT
+
+    def __init__(self, host, port=None, key_file=None, cert_file=None,
+                 strict=None):
+        HTTPConnection.__init__(self, host, port, strict)
+        self.key_file = key_file
+        self.cert_file = cert_file
+
+    def connect(self):
+        "Connect to a host on a given (SSL) port."
+
+        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        sock.connect((self.host, self.port))
+        ssl = socket.ssl(sock, self.key_file, self.cert_file)
+        self.sock = FakeSocket(sock, ssl)
+
+
+class HTTP:
+    "Compatibility class with httplib.py from 1.5."
+
+    _http_vsn = 10
+    _http_vsn_str = 'HTTP/1.0'
+
+    debuglevel = 0
+
+    _connection_class = HTTPConnection
+
+    def __init__(self, host='', port=None, strict=None):
+        "Provide a default host, since the superclass requires one."
+
+        # some joker passed 0 explicitly, meaning default port
+        if port == 0:
+            port = None
+
+        # Note that we may pass an empty string as the host; this will throw
+        # an error when we attempt to connect. Presumably, the client code
+        # will call connect before then, with a proper host.
+        self._setup(self._connection_class(host, port, strict))
+
+    def _setup(self, conn):
+        self._conn = conn
+
+        # set up delegation to flesh out interface
+        self.send = conn.send
+        self.putrequest = conn.putrequest
+        self.endheaders = conn.endheaders
+        self.set_debuglevel = conn.set_debuglevel
+
+        conn._http_vsn = self._http_vsn
+        conn._http_vsn_str = self._http_vsn_str
+
+        self.file = None
+
+    def connect(self, host=None, port=None):
+        "Accept arguments to set the host/port, since the superclass doesn't."
+
+        if host is not None:
+            self._conn._set_hostport(host, port)
+        self._conn.connect()
+
+    def getfile(self):
+        "Provide a getfile, since the superclass' does not use this concept."
+        return self.file
+
+    def putheader(self, header, *values):
+        "The superclass allows only one value argument."
+        self._conn.putheader(header, '\r\n\t'.join(values))
+
+    def getreply(self):
+        """Compat definition since superclass does not define it.
+
+        Returns a tuple consisting of:
+        - server status code (e.g. '200' if all goes well)
+        - server "reason" corresponding to status code
+        - any RFC822 headers in the response from the server
+        """
+        try:
+            response = self._conn.getresponse()
+        except BadStatusLine, e:
+            ### hmm. if getresponse() ever closes the socket on a bad request,
+            ### then we are going to have problems with self.sock
+
+            ### should we keep this behavior? do people use it?
+            # keep the socket open (as a file), and return it
+            self.file = self._conn.sock.makefile('rb', 0)
+
+            # close our socket -- we want to restart after any protocol error
+            self.close()
+
+            self.headers = None
+            return -1, e.line, None
+
+        self.headers = response.msg
+        self.file = response.fp
+        return response.status, response.reason, response.msg
+
+    def close(self):
+        self._conn.close()
+
+        # note that self.file == response.fp, which gets closed by the
+        # superclass. just clear the object ref here.
+        ### hmm. messy. if status==-1, then self.file is owned by us.
+        ### well... we aren't explicitly closing, but losing this ref will
+        ### do it
+        self.file = None
+
+if hasattr(socket, 'ssl'):
+    class HTTPS(HTTP):
+        """Compatibility with 1.5 httplib interface
+
+        Python 1.5.2 did not have an HTTPS class, but it defined an
+        interface for sending http requests that is also useful for
+        https.
+        """
+
+        _connection_class = HTTPSConnection
+
+        def __init__(self, host='', port=None, key_file=None, cert_file=None,
+                     strict=None):
+            # provide a default host, pass the X509 cert info
+
+            # urf. compensate for bad input.
+            if port == 0:
+                port = None
+            self._setup(self._connection_class(host, port, key_file,
+                                               cert_file, strict))
+
+            # we never actually use these for anything, but we keep them
+            # here for compatibility with post-1.5.2 CVS.
+            self.key_file = key_file
+            self.cert_file = cert_file
+
+
+class HTTPException(Exception):
+    # Subclasses that define an __init__ must call Exception.__init__
+    # or define self.args.  Otherwise, str() will fail.
+    pass
+
+class NotConnected(HTTPException):
+    pass
+
+class InvalidURL(HTTPException):
+    pass
+
+class UnknownProtocol(HTTPException):
+    def __init__(self, version):
+        self.args = version,
+        self.version = version
+
+class UnknownTransferEncoding(HTTPException):
+    pass
+
+class UnimplementedFileMode(HTTPException):
+    pass
+
+class IncompleteRead(HTTPException):
+    def __init__(self, partial):
+        self.args = partial,
+        self.partial = partial
+
+class ImproperConnectionState(HTTPException):
+    pass
+
+class CannotSendRequest(ImproperConnectionState):
+    pass
+
+class CannotSendHeader(ImproperConnectionState):
+    pass
+
+class ResponseNotReady(ImproperConnectionState):
+    pass
+
+class BadStatusLine(HTTPException):
+    def __init__(self, line):
+        self.args = line,
+        self.line = line
+
+# for backwards compatibility
+error = HTTPException
+
+class LineAndFileWrapper:
+    """A limited file-like object for HTTP/0.9 responses."""
+
+    # The status-line parsing code calls readline(), which normally
+    # get the HTTP status line.  For a 0.9 response, however, this is
+    # actually the first line of the body!  Clients need to get a
+    # readable file object that contains that line.
+
+    def __init__(self, line, file):
+        self._line = line
+        self._file = file
+        self._line_consumed = 0
+        self._line_offset = 0
+        self._line_left = len(line)
+
+    def __getattr__(self, attr):
+        return getattr(self._file, attr)
+
+    def _done(self):
+        # called when the last byte is read from the line.  After the
+        # call, all read methods are delegated to the underlying file
+        # object.
+        self._line_consumed = 1
+        self.read = self._file.read
+        self.readline = self._file.readline
+        self.readlines = self._file.readlines
+
+    def read(self, amt=None):
+        if self._line_consumed:
+            return self._file.read(amt)
+        assert self._line_left
+        if amt is None or amt > self._line_left:
+            s = self._line[self._line_offset:]
+            self._done()
+            if amt is None:
+                return s + self._file.read()
+            else:
+                return s + self._file.read(amt - len(s))
+        else:
+            assert amt <= self._line_left
+            i = self._line_offset
+            j = i + amt
+            s = self._line[i:j]
+            self._line_offset = j
+            self._line_left -= amt
+            if self._line_left == 0:
+                self._done()
+            return s
+
+    def readline(self):
+        if self._line_consumed:
+            return self._file.readline()
+        assert self._line_left
+        s = self._line[self._line_offset:]
+        self._done()
+        return s
+
+    def readlines(self, size=None):
+        if self._line_consumed:
+            return self._file.readlines(size)
+        assert self._line_left
+        L = [self._line[self._line_offset:]]
+        self._done()
+        if size is None:
+            return L + self._file.readlines()
+        else:
+            return L + self._file.readlines(size)
+
+def test():
+    """Test this module.
+
+    A hodge podge of tests collected here, because they have too many
+    external dependencies for the regular test suite.
+    """
+
+    import sys
+    import getopt
+    opts, args = getopt.getopt(sys.argv[1:], 'd')
+    dl = 0
+    for o, a in opts:
+        if o == '-d': dl = dl + 1
+    host = 'www.python.org'
+    selector = '/'
+    if args[0:]: host = args[0]
+    if args[1:]: selector = args[1]
+    h = HTTP()
+    h.set_debuglevel(dl)
+    h.connect(host)
+    h.putrequest('GET', selector)
+    h.endheaders()
+    status, reason, headers = h.getreply()
+    print 'status =', status
+    print 'reason =', reason
+    print "read", len(h.getfile().read())
+    print
+    if headers:
+        for header in headers.headers: print header.strip()
+    print
+
+    # minimal test that code to extract host from url works
+    class HTTP11(HTTP):
+        _http_vsn = 11
+        _http_vsn_str = 'HTTP/1.1'
+
+    h = HTTP11('www.python.org')
+    h.putrequest('GET', 'http://www.python.org/~jeremy/')
+    h.endheaders()
+    h.getreply()
+    h.close()
+
+    if hasattr(socket, 'ssl'):
+
+        for host, selector in (('sourceforge.net', '/projects/python'),
+                               ):
+            print "https://%s%s" % (host, selector)
+            hs = HTTPS()
+            hs.set_debuglevel(dl)
+            hs.connect(host)
+            hs.putrequest('GET', selector)
+            hs.endheaders()
+            status, reason, headers = hs.getreply()
+            print 'status =', status
+            print 'reason =', reason
+            print "read", len(hs.getfile().read())
+            print
+            if headers:
+                for header in headers.headers: print header.strip()
+            print
+
+if __name__ == '__main__':
+    test()

Added: vendor/Python/current/Lib/idlelib/AutoComplete.py
===================================================================
--- vendor/Python/current/Lib/idlelib/AutoComplete.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/AutoComplete.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,226 @@
+"""AutoComplete.py - An IDLE extension for automatically completing names.
+
+This extension can complete either attribute names of file names. It can pop
+a window with all available names, for the user to select from.
+"""
+import os
+import sys
+import string
+
+from configHandler import idleConf
+
+import AutoCompleteWindow
+from HyperParser import HyperParser
+
+import __main__
+
+# This string includes all chars that may be in a file name (without a path
+# separator)
+FILENAME_CHARS = string.ascii_letters + string.digits + os.curdir + "._~#$:-"
+# This string includes all chars that may be in an identifier
+ID_CHARS = string.ascii_letters + string.digits + "_"
+
+# These constants represent the two different types of completions
+COMPLETE_ATTRIBUTES, COMPLETE_FILES = range(1, 2+1)
+
+class AutoComplete:
+
+    menudefs = [
+        ('edit', [
+            ("Show completions", "<<force-open-completions>>"),
+        ])
+    ]
+
+    popupwait = idleConf.GetOption("extensions", "AutoComplete",
+                                   "popupwait", type="int", default=0)
+
+    def __init__(self, editwin=None):
+        if editwin == None:  # subprocess and test
+            self.editwin = None
+            return
+        self.editwin = editwin
+        self.text = editwin.text
+        self.autocompletewindow = None
+
+        # id of delayed call, and the index of the text insert when the delayed
+        # call was issued. If _delayed_completion_id is None, there is no
+        # delayed call.
+        self._delayed_completion_id = None
+        self._delayed_completion_index = None
+
+    def _make_autocomplete_window(self):
+        return AutoCompleteWindow.AutoCompleteWindow(self.text)
+
+    def _remove_autocomplete_window(self, event=None):
+        if self.autocompletewindow:
+            self.autocompletewindow.hide_window()
+            self.autocompletewindow = None
+
+    def force_open_completions_event(self, event):
+        """Happens when the user really wants to open a completion list, even
+        if a function call is needed.
+        """
+        self.open_completions(True, False, True)
+
+    def try_open_completions_event(self, event):
+        """Happens when it would be nice to open a completion list, but not
+        really neccesary, for example after an dot, so function
+        calls won't be made.
+        """
+        lastchar = self.text.get("insert-1c")
+        if lastchar == ".":
+            self._open_completions_later(False, False, False,
+                                         COMPLETE_ATTRIBUTES)
+        elif lastchar == os.sep:
+            self._open_completions_later(False, False, False,
+                                         COMPLETE_FILES)
+
+    def autocomplete_event(self, event):
+        """Happens when the user wants to complete his word, and if neccesary,
+        open a completion list after that (if there is more than one
+        completion)
+        """
+        if hasattr(event, "mc_state") and event.mc_state:
+            # A modifier was pressed along with the tab, continue as usual.
+            return
+        if self.autocompletewindow and self.autocompletewindow.is_active():
+            self.autocompletewindow.complete()
+            return "break"
+        else:
+            opened = self.open_completions(False, True, True)
+            if opened:
+                return "break"
+
+    def _open_completions_later(self, *args):
+        self._delayed_completion_index = self.text.index("insert")
+        if self._delayed_completion_id is not None:
+            self.text.after_cancel(self._delayed_completion_id)
+        self._delayed_completion_id = \
+            self.text.after(self.popupwait, self._delayed_open_completions,
+                            *args)
+
+    def _delayed_open_completions(self, *args):
+        self._delayed_completion_id = None
+        if self.text.index("insert") != self._delayed_completion_index:
+            return
+        self.open_completions(*args)
+
+    def open_completions(self, evalfuncs, complete, userWantsWin, mode=None):
+        """Find the completions and create the AutoCompleteWindow.
+        Return True if successful (no syntax error or so found).
+        if complete is True, then if there's nothing to complete and no
+        start of completion, won't open completions and return False.
+        If mode is given, will open a completion list only in this mode.
+        """
+        # Cancel another delayed call, if it exists.
+        if self._delayed_completion_id is not None:
+            self.text.after_cancel(self._delayed_completion_id)
+            self._delayed_completion_id = None
+
+        hp = HyperParser(self.editwin, "insert")
+        curline = self.text.get("insert linestart", "insert")
+        i = j = len(curline)
+        if hp.is_in_string() and (not mode or mode==COMPLETE_FILES):
+            self._remove_autocomplete_window()
+            mode = COMPLETE_FILES
+            while i and curline[i-1] in FILENAME_CHARS:
+                i -= 1
+            comp_start = curline[i:j]
+            j = i
+            while i and curline[i-1] in FILENAME_CHARS+os.sep:
+                i -= 1
+            comp_what = curline[i:j]
+        elif hp.is_in_code() and (not mode or mode==COMPLETE_ATTRIBUTES):
+            self._remove_autocomplete_window()
+            mode = COMPLETE_ATTRIBUTES
+            while i and curline[i-1] in ID_CHARS:
+                i -= 1
+            comp_start = curline[i:j]
+            if i and curline[i-1] == '.':
+                hp.set_index("insert-%dc" % (len(curline)-(i-1)))
+                comp_what = hp.get_expression()
+                if not comp_what or \
+                   (not evalfuncs and comp_what.find('(') != -1):
+                    return
+            else:
+                comp_what = ""
+        else:
+            return
+
+        if complete and not comp_what and not comp_start:
+            return
+        comp_lists = self.fetch_completions(comp_what, mode)
+        if not comp_lists[0]:
+            return
+        self.autocompletewindow = self._make_autocomplete_window()
+        self.autocompletewindow.show_window(comp_lists,
+                                            "insert-%dc" % len(comp_start),
+                                            complete,
+                                            mode,
+                                            userWantsWin)
+        return True
+
+    def fetch_completions(self, what, mode):
+        """Return a pair of lists of completions for something. The first list
+        is a sublist of the second. Both are sorted.
+
+        If there is a Python subprocess, get the comp. list there.  Otherwise,
+        either fetch_completions() is running in the subprocess itself or it
+        was called in an IDLE EditorWindow before any script had been run.
+
+        The subprocess environment is that of the most recently run script.  If
+        two unrelated modules are being edited some calltips in the current
+        module may be inoperative if the module was not the last to run.
+        """
+        try:
+            rpcclt = self.editwin.flist.pyshell.interp.rpcclt
+        except:
+            rpcclt = None
+        if rpcclt:
+            return rpcclt.remotecall("exec", "get_the_completion_list",
+                                     (what, mode), {})
+        else:
+            if mode == COMPLETE_ATTRIBUTES:
+                if what == "":
+                    namespace = __main__.__dict__.copy()
+                    namespace.update(__main__.__builtins__.__dict__)
+                    bigl = eval("dir()", namespace)
+                    bigl.sort()
+                    if "__all__" in bigl:
+                        smalll = eval("__all__", namespace)
+                        smalll.sort()
+                    else:
+                        smalll = filter(lambda s: s[:1] != '_', bigl)
+                else:
+                    try:
+                        entity = self.get_entity(what)
+                        bigl = dir(entity)
+                        bigl.sort()
+                        if "__all__" in bigl:
+                            smalll = entity.__all__
+                            smalll.sort()
+                        else:
+                            smalll = filter(lambda s: s[:1] != '_', bigl)
+                    except:
+                        return [], []
+
+            elif mode == COMPLETE_FILES:
+                if what == "":
+                    what = "."
+                try:
+                    expandedpath = os.path.expanduser(what)
+                    bigl = os.listdir(expandedpath)
+                    bigl.sort()
+                    smalll = filter(lambda s: s[:1] != '.', bigl)
+                except OSError:
+                    return [], []
+
+            if not smalll:
+                smalll = bigl
+            return smalll, bigl
+
+    def get_entity(self, name):
+        """Lookup name in a namespace spanning sys.modules and __main.dict__"""
+        namespace = sys.modules.copy()
+        namespace.update(__main__.__dict__)
+        return eval(name, namespace)

Added: vendor/Python/current/Lib/idlelib/AutoCompleteWindow.py
===================================================================
--- vendor/Python/current/Lib/idlelib/AutoCompleteWindow.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/AutoCompleteWindow.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,393 @@
+"""
+An auto-completion window for IDLE, used by the AutoComplete extension
+"""
+from Tkinter import *
+from MultiCall import MC_SHIFT
+import AutoComplete
+
+HIDE_VIRTUAL_EVENT_NAME = "<<autocompletewindow-hide>>"
+HIDE_SEQUENCES = ("<FocusOut>", "<ButtonPress>")
+KEYPRESS_VIRTUAL_EVENT_NAME = "<<autocompletewindow-keypress>>"
+# We need to bind event beyond <Key> so that the function will be called
+# before the default specific IDLE function
+KEYPRESS_SEQUENCES = ("<Key>", "<Key-BackSpace>", "<Key-Return>",
+                      "<Key-Up>", "<Key-Down>", "<Key-Home>", "<Key-End>")
+KEYRELEASE_VIRTUAL_EVENT_NAME = "<<autocompletewindow-keyrelease>>"
+KEYRELEASE_SEQUENCE = "<KeyRelease>"
+LISTUPDATE_SEQUENCE = "<ButtonRelease>"
+WINCONFIG_SEQUENCE = "<Configure>"
+DOUBLECLICK_SEQUENCE = "<Double-ButtonRelease>"
+
+class AutoCompleteWindow:
+
+    def __init__(self, widget):
+        # The widget (Text) on which we place the AutoCompleteWindow
+        self.widget = widget
+        # The widgets we create
+        self.autocompletewindow = self.listbox = self.scrollbar = None
+        # The default foreground and background of a selection. Saved because
+        # they are changed to the regular colors of list items when the
+        # completion start is not a prefix of the selected completion
+        self.origselforeground = self.origselbackground = None
+        # The list of completions
+        self.completions = None
+        # A list with more completions, or None
+        self.morecompletions = None
+        # The completion mode. Either AutoComplete.COMPLETE_ATTRIBUTES or
+        # AutoComplete.COMPLETE_FILES
+        self.mode = None
+        # The current completion start, on the text box (a string)
+        self.start = None
+        # The index of the start of the completion
+        self.startindex = None
+        # The last typed start, used so that when the selection changes,
+        # the new start will be as close as possible to the last typed one.
+        self.lasttypedstart = None
+        # Do we have an indication that the user wants the completion window
+        # (for example, he clicked the list)
+        self.userwantswindow = None
+        # event ids
+        self.hideid = self.keypressid = self.listupdateid = self.winconfigid \
+        = self.keyreleaseid = self.doubleclickid                         = None
+
+    def _change_start(self, newstart):
+        i = 0
+        while i < len(self.start) and i < len(newstart) and \
+              self.start[i] == newstart[i]:
+            i += 1
+        if i < len(self.start):
+            self.widget.delete("%s+%dc" % (self.startindex, i),
+                               "%s+%dc" % (self.startindex, len(self.start)))
+        if i < len(newstart):
+            self.widget.insert("%s+%dc" % (self.startindex, i),
+                               newstart[i:])
+        self.start = newstart
+
+    def _binary_search(self, s):
+        """Find the first index in self.completions where completions[i] is
+        greater or equal to s, or the last index if there is no such
+        one."""
+        i = 0; j = len(self.completions)
+        while j > i:
+            m = (i + j) // 2
+            if self.completions[m] >= s:
+                j = m
+            else:
+                i = m + 1
+        return min(i, len(self.completions)-1)
+
+    def _complete_string(self, s):
+        """Assuming that s is the prefix of a string in self.completions,
+        return the longest string which is a prefix of all the strings which
+        s is a prefix of them. If s is not a prefix of a string, return s."""
+        first = self._binary_search(s)
+        if self.completions[first][:len(s)] != s:
+            # There is not even one completion which s is a prefix of.
+            return s
+        # Find the end of the range of completions where s is a prefix of.
+        i = first + 1
+        j = len(self.completions)
+        while j > i:
+            m = (i + j) // 2
+            if self.completions[m][:len(s)] != s:
+                j = m
+            else:
+                i = m + 1
+        last = i-1
+
+        # We should return the maximum prefix of first and last
+        i = len(s)
+        while len(self.completions[first]) > i and \
+              len(self.completions[last]) > i and \
+              self.completions[first][i] == self.completions[last][i]:
+            i += 1
+        return self.completions[first][:i]
+
+    def _selection_changed(self):
+        """Should be called when the selection of the Listbox has changed.
+        Updates the Listbox display and calls _change_start."""
+        cursel = int(self.listbox.curselection()[0])
+
+        self.listbox.see(cursel)
+
+        lts = self.lasttypedstart
+        selstart = self.completions[cursel]
+        if self._binary_search(lts) == cursel:
+            newstart = lts
+        else:
+            i = 0
+            while i < len(lts) and i < len(selstart) and lts[i] == selstart[i]:
+                i += 1
+            while cursel > 0 and selstart[:i] <= self.completions[cursel-1]:
+                i += 1
+            newstart = selstart[:i]
+        self._change_start(newstart)
+
+        if self.completions[cursel][:len(self.start)] == self.start:
+            # start is a prefix of the selected completion
+            self.listbox.configure(selectbackground=self.origselbackground,
+                                   selectforeground=self.origselforeground)
+        else:
+            self.listbox.configure(selectbackground=self.listbox.cget("bg"),
+                                   selectforeground=self.listbox.cget("fg"))
+            # If there are more completions, show them, and call me again.
+            if self.morecompletions:
+                self.completions = self.morecompletions
+                self.morecompletions = None
+                self.listbox.delete(0, END)
+                for item in self.completions:
+                    self.listbox.insert(END, item)
+                self.listbox.select_set(self._binary_search(self.start))
+                self._selection_changed()
+
+    def show_window(self, comp_lists, index, complete, mode, userWantsWin):
+        """Show the autocomplete list, bind events.
+        If complete is True, complete the text, and if there is exactly one
+        matching completion, don't open a list."""
+        # Handle the start we already have
+        self.completions, self.morecompletions = comp_lists
+        self.mode = mode
+        self.startindex = self.widget.index(index)
+        self.start = self.widget.get(self.startindex, "insert")
+        if complete:
+            completed = self._complete_string(self.start)
+            self._change_start(completed)
+            i = self._binary_search(completed)
+            if self.completions[i] == completed and \
+               (i == len(self.completions)-1 or
+                self.completions[i+1][:len(completed)] != completed):
+                # There is exactly one matching completion
+                return
+        self.userwantswindow = userWantsWin
+        self.lasttypedstart = self.start
+
+        # Put widgets in place
+        self.autocompletewindow = acw = Toplevel(self.widget)
+        # Put it in a position so that it is not seen.
+        acw.wm_geometry("+10000+10000")
+        # Make it float
+        acw.wm_overrideredirect(1)
+        try:
+            # This command is only needed and available on Tk >= 8.4.0 for OSX
+            # Without it, call tips intrude on the typing process by grabbing
+            # the focus.
+            acw.tk.call("::tk::unsupported::MacWindowStyle", "style", acw._w,
+                        "help", "noActivates")
+        except TclError:
+            pass
+        self.scrollbar = scrollbar = Scrollbar(acw, orient=VERTICAL)
+        self.listbox = listbox = Listbox(acw, yscrollcommand=scrollbar.set,
+                                         exportselection=False, bg="white")
+        for item in self.completions:
+            listbox.insert(END, item)
+        self.origselforeground = listbox.cget("selectforeground")
+        self.origselbackground = listbox.cget("selectbackground")
+        scrollbar.config(command=listbox.yview)
+        scrollbar.pack(side=RIGHT, fill=Y)
+        listbox.pack(side=LEFT, fill=BOTH, expand=True)
+
+        # Initialize the listbox selection
+        self.listbox.select_set(self._binary_search(self.start))
+        self._selection_changed()
+
+        # bind events
+        self.hideid = self.widget.bind(HIDE_VIRTUAL_EVENT_NAME,
+                                       self.hide_event)
+        for seq in HIDE_SEQUENCES:
+            self.widget.event_add(HIDE_VIRTUAL_EVENT_NAME, seq)
+        self.keypressid = self.widget.bind(KEYPRESS_VIRTUAL_EVENT_NAME,
+                                           self.keypress_event)
+        for seq in KEYPRESS_SEQUENCES:
+            self.widget.event_add(KEYPRESS_VIRTUAL_EVENT_NAME, seq)
+        self.keyreleaseid = self.widget.bind(KEYRELEASE_VIRTUAL_EVENT_NAME,
+                                             self.keyrelease_event)
+        self.widget.event_add(KEYRELEASE_VIRTUAL_EVENT_NAME,KEYRELEASE_SEQUENCE)
+        self.listupdateid = listbox.bind(LISTUPDATE_SEQUENCE,
+                                         self.listupdate_event)
+        self.winconfigid = acw.bind(WINCONFIG_SEQUENCE, self.winconfig_event)
+        self.doubleclickid = listbox.bind(DOUBLECLICK_SEQUENCE,
+                                          self.doubleclick_event)
+
+    def winconfig_event(self, event):
+        if not self.is_active():
+            return
+        # Position the completion list window
+        acw = self.autocompletewindow
+        self.widget.see(self.startindex)
+        x, y, cx, cy = self.widget.bbox(self.startindex)
+        acw.wm_geometry("+%d+%d" % (x + self.widget.winfo_rootx(),
+                                    y + self.widget.winfo_rooty() \
+                                    -acw.winfo_height()))
+
+
+    def hide_event(self, event):
+        if not self.is_active():
+            return
+        self.hide_window()
+
+    def listupdate_event(self, event):
+        if not self.is_active():
+            return
+        self.userwantswindow = True
+        self._selection_changed()
+
+    def doubleclick_event(self, event):
+        # Put the selected completion in the text, and close the list
+        cursel = int(self.listbox.curselection()[0])
+        self._change_start(self.completions[cursel])
+        self.hide_window()
+
+    def keypress_event(self, event):
+        if not self.is_active():
+            return
+        keysym = event.keysym
+        if hasattr(event, "mc_state"):
+            state = event.mc_state
+        else:
+            state = 0
+
+        if (len(keysym) == 1 or keysym in ("underscore", "BackSpace")
+            or (self.mode==AutoComplete.COMPLETE_FILES and keysym in
+                ("period", "minus"))) \
+           and not (state & ~MC_SHIFT):
+            # Normal editing of text
+            if len(keysym) == 1:
+                self._change_start(self.start + keysym)
+            elif keysym == "underscore":
+                self._change_start(self.start + '_')
+            elif keysym == "period":
+                self._change_start(self.start + '.')
+            elif keysym == "minus":
+                self._change_start(self.start + '-')
+            else:
+                # keysym == "BackSpace"
+                if len(self.start) == 0:
+                    self.hide_window()
+                    return
+                self._change_start(self.start[:-1])
+            self.lasttypedstart = self.start
+            self.listbox.select_clear(0, int(self.listbox.curselection()[0]))
+            self.listbox.select_set(self._binary_search(self.start))
+            self._selection_changed()
+            return "break"
+
+        elif keysym == "Return" and not state:
+            # If start is a prefix of the selection, or there was an indication
+            # that the user used the completion window, put the selected
+            # completion in the text, and close the list.
+            # Otherwise, close the window and let the event through.
+            cursel = int(self.listbox.curselection()[0])
+            if self.completions[cursel][:len(self.start)] == self.start or \
+               self.userwantswindow:
+                self._change_start(self.completions[cursel])
+                self.hide_window()
+                return "break"
+            else:
+                self.hide_window()
+                return
+
+        elif (self.mode == AutoComplete.COMPLETE_ATTRIBUTES and keysym in
+              ("period", "space", "parenleft", "parenright", "bracketleft",
+               "bracketright")) or \
+             (self.mode == AutoComplete.COMPLETE_FILES and keysym in
+              ("slash", "backslash", "quotedbl", "apostrophe")) \
+             and not (state & ~MC_SHIFT):
+            # If start is a prefix of the selection, but is not '' when
+            # completing file names, put the whole
+            # selected completion. Anyway, close the list.
+            cursel = int(self.listbox.curselection()[0])
+            if self.completions[cursel][:len(self.start)] == self.start \
+               and (self.mode==AutoComplete.COMPLETE_ATTRIBUTES or self.start):
+                self._change_start(self.completions[cursel])
+            self.hide_window()
+            return
+
+        elif keysym in ("Home", "End", "Prior", "Next", "Up", "Down") and \
+             not state:
+            # Move the selection in the listbox
+            self.userwantswindow = True
+            cursel = int(self.listbox.curselection()[0])
+            if keysym == "Home":
+                newsel = 0
+            elif keysym == "End":
+                newsel = len(self.completions)-1
+            elif keysym in ("Prior", "Next"):
+                jump = self.listbox.nearest(self.listbox.winfo_height()) - \
+                       self.listbox.nearest(0)
+                if keysym == "Prior":
+                    newsel = max(0, cursel-jump)
+                else:
+                    assert keysym == "Next"
+                    newsel = min(len(self.completions)-1, cursel+jump)
+            elif keysym == "Up":
+                newsel = max(0, cursel-1)
+            else:
+                assert keysym == "Down"
+                newsel = min(len(self.completions)-1, cursel+1)
+            self.listbox.select_clear(cursel)
+            self.listbox.select_set(newsel)
+            self._selection_changed()
+            return "break"
+
+        elif (keysym == "Tab" and not state):
+            # The user wants a completion, but it is handled by AutoComplete
+            # (not AutoCompleteWindow), so ignore.
+            self.userwantswindow = True
+            return
+
+        elif reduce(lambda x, y: x or y,
+                    [keysym.find(s) != -1 for s in ("Shift", "Control", "Alt",
+                                                    "Meta", "Command", "Option")
+                     ]):
+            # A modifier key, so ignore
+            return
+
+        else:
+            # Unknown event, close the window and let it through.
+            self.hide_window()
+            return
+
+    def keyrelease_event(self, event):
+        if not self.is_active():
+            return
+        if self.widget.index("insert") != \
+           self.widget.index("%s+%dc" % (self.startindex, len(self.start))):
+            # If we didn't catch an event which moved the insert, close window
+            self.hide_window()
+
+    def is_active(self):
+        return self.autocompletewindow is not None
+
+    def complete(self):
+        self._change_start(self._complete_string(self.start))
+        # The selection doesn't change.
+
+    def hide_window(self):
+        if not self.is_active():
+            return
+
+        # unbind events
+        for seq in HIDE_SEQUENCES:
+            self.widget.event_delete(HIDE_VIRTUAL_EVENT_NAME, seq)
+        self.widget.unbind(HIDE_VIRTUAL_EVENT_NAME, self.hideid)
+        self.hideid = None
+        for seq in KEYPRESS_SEQUENCES:
+            self.widget.event_delete(KEYPRESS_VIRTUAL_EVENT_NAME, seq)
+        self.widget.unbind(KEYPRESS_VIRTUAL_EVENT_NAME, self.keypressid)
+        self.keypressid = None
+        self.widget.event_delete(KEYRELEASE_VIRTUAL_EVENT_NAME,
+                                 KEYRELEASE_SEQUENCE)
+        self.widget.unbind(KEYRELEASE_VIRTUAL_EVENT_NAME, self.keyreleaseid)
+        self.keyreleaseid = None
+        self.listbox.unbind(LISTUPDATE_SEQUENCE, self.listupdateid)
+        self.listupdateid = None
+        self.autocompletewindow.unbind(WINCONFIG_SEQUENCE, self.winconfigid)
+        self.winconfigid = None
+
+        # destroy widgets
+        self.scrollbar.destroy()
+        self.scrollbar = None
+        self.listbox.destroy()
+        self.listbox = None
+        self.autocompletewindow.destroy()
+        self.autocompletewindow = None

Added: vendor/Python/current/Lib/idlelib/AutoExpand.py
===================================================================
--- vendor/Python/current/Lib/idlelib/AutoExpand.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/AutoExpand.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,83 @@
+import string
+import re
+
+###$ event <<expand-word>>
+###$ win <Alt-slash>
+###$ unix <Alt-slash>
+
+class AutoExpand:
+
+    menudefs = [
+        ('edit', [
+            ('E_xpand Word', '<<expand-word>>'),
+         ]),
+    ]
+
+    wordchars = string.ascii_letters + string.digits + "_"
+
+    def __init__(self, editwin):
+        self.text = editwin.text
+        self.state = None
+
+    def expand_word_event(self, event):
+        curinsert = self.text.index("insert")
+        curline = self.text.get("insert linestart", "insert lineend")
+        if not self.state:
+            words = self.getwords()
+            index = 0
+        else:
+            words, index, insert, line = self.state
+            if insert != curinsert or line != curline:
+                words = self.getwords()
+                index = 0
+        if not words:
+            self.text.bell()
+            return "break"
+        word = self.getprevword()
+        self.text.delete("insert - %d chars" % len(word), "insert")
+        newword = words[index]
+        index = (index + 1) % len(words)
+        if index == 0:
+            self.text.bell()            # Warn we cycled around
+        self.text.insert("insert", newword)
+        curinsert = self.text.index("insert")
+        curline = self.text.get("insert linestart", "insert lineend")
+        self.state = words, index, curinsert, curline
+        return "break"
+
+    def getwords(self):
+        word = self.getprevword()
+        if not word:
+            return []
+        before = self.text.get("1.0", "insert wordstart")
+        wbefore = re.findall(r"\b" + word + r"\w+\b", before)
+        del before
+        after = self.text.get("insert wordend", "end")
+        wafter = re.findall(r"\b" + word + r"\w+\b", after)
+        del after
+        if not wbefore and not wafter:
+            return []
+        words = []
+        dict = {}
+        # search backwards through words before
+        wbefore.reverse()
+        for w in wbefore:
+            if dict.get(w):
+                continue
+            words.append(w)
+            dict[w] = w
+        # search onwards through words after
+        for w in wafter:
+            if dict.get(w):
+                continue
+            words.append(w)
+            dict[w] = w
+        words.append(word)
+        return words
+
+    def getprevword(self):
+        line = self.text.get("insert linestart", "insert")
+        i = len(line)
+        while i > 0 and line[i-1] in self.wordchars:
+            i = i-1
+        return line[i:]

Added: vendor/Python/current/Lib/idlelib/Bindings.py
===================================================================
--- vendor/Python/current/Lib/idlelib/Bindings.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/Bindings.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,111 @@
+"""Define the menu contents, hotkeys, and event bindings.
+
+There is additional configuration information in the EditorWindow class (and
+subclasses): the menus are created there based on the menu_specs (class)
+variable, and menus not created are silently skipped in the code here.  This
+makes it possible, for example, to define a Debug menu which is only present in
+the PythonShell window, and a Format menu which is only present in the Editor
+windows.
+
+"""
+import sys
+from configHandler import idleConf
+
+menudefs = [
+ # underscore prefixes character to underscore
+ ('file', [
+   ('_New Window', '<<open-new-window>>'),
+   ('_Open...', '<<open-window-from-file>>'),
+   ('Open _Module...', '<<open-module>>'),
+   ('Class _Browser', '<<open-class-browser>>'),
+   ('_Path Browser', '<<open-path-browser>>'),
+   None,
+   ('_Save', '<<save-window>>'),
+   ('Save _As...', '<<save-window-as-file>>'),
+   ('Save Cop_y As...', '<<save-copy-of-window-as-file>>'),
+   None,
+   ('Prin_t Window', '<<print-window>>'),
+   None,
+   ('_Close', '<<close-window>>'),
+   ('E_xit', '<<close-all-windows>>'),
+  ]),
+ ('edit', [
+   ('_Undo', '<<undo>>'),
+   ('_Redo', '<<redo>>'),
+   None,
+   ('Cu_t', '<<cut>>'),
+   ('_Copy', '<<copy>>'),
+   ('_Paste', '<<paste>>'),
+   ('Select _All', '<<select-all>>'),
+   None,
+   ('_Find...', '<<find>>'),
+   ('Find A_gain', '<<find-again>>'),
+   ('Find _Selection', '<<find-selection>>'),
+   ('Find in Files...', '<<find-in-files>>'),
+   ('R_eplace...', '<<replace>>'),
+   ('Go to _Line', '<<goto-line>>'),
+  ]),
+('format', [
+   ('_Indent Region', '<<indent-region>>'),
+   ('_Dedent Region', '<<dedent-region>>'),
+   ('Comment _Out Region', '<<comment-region>>'),
+   ('U_ncomment Region', '<<uncomment-region>>'),
+   ('Tabify Region', '<<tabify-region>>'),
+   ('Untabify Region', '<<untabify-region>>'),
+   ('Toggle Tabs', '<<toggle-tabs>>'),
+   ('New Indent Width', '<<change-indentwidth>>'),
+   ]),
+ ('run', [
+   ('Python Shell', '<<open-python-shell>>'),
+   ]),
+ ('shell', [
+   ('_View Last Restart', '<<view-restart>>'),
+   ('_Restart Shell', '<<restart-shell>>'),
+   ]),
+ ('debug', [
+   ('_Go to File/Line', '<<goto-file-line>>'),
+   ('!_Debugger', '<<toggle-debugger>>'),
+   ('_Stack Viewer', '<<open-stack-viewer>>'),
+   ('!_Auto-open Stack Viewer', '<<toggle-jit-stack-viewer>>'),
+   ]),
+ ('options', [
+   ('_Configure IDLE...', '<<open-config-dialog>>'),
+   None,
+   ]),
+ ('help', [
+   ('_About IDLE', '<<about-idle>>'),
+   None,
+   ('_IDLE Help', '<<help>>'),
+   ('Python _Docs', '<<python-docs>>'),
+   ]),
+]
+
+import sys
+if sys.platform == 'darwin' and '.app' in sys.executable:
+    # Running as a proper MacOS application bundle. This block restructures
+    # the menus a little to make them conform better to the HIG.
+
+    quitItem = menudefs[0][1][-1]
+    closeItem = menudefs[0][1][-2]
+
+    # Remove the last 3 items of the file menu: a separator, close window and
+    # quit. Close window will be reinserted just above the save item, where
+    # it should be according to the HIG. Quit is in the application menu.
+    del menudefs[0][1][-3:]
+    menudefs[0][1].insert(6, closeItem)
+
+    # Remove the 'About' entry from the help menu, it is in the application
+    # menu
+    del menudefs[-1][1][0:2]
+
+    menudefs.insert(0,
+            ('application', [
+                ('About IDLE', '<<about-idle>>'),
+                None,
+                ('_Preferences....', '<<open-config-dialog>>'),
+            ]))
+
+
+default_keydefs = idleConf.GetCurrentKeySet()
+
+del sys

Added: vendor/Python/current/Lib/idlelib/CREDITS.txt
===================================================================
--- vendor/Python/current/Lib/idlelib/CREDITS.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/CREDITS.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,36 @@
+Guido van Rossum, as well as being the creator of the Python language, is the
+original creator of IDLE.  Other contributors prior to Version 0.8 include
+Mark Hammond, Jeremy Hylton, Tim Peters, and Moshe Zadka.
+
+IDLE's recent development has been carried out in the IDLEfork project.
+The objective was to develop a version of IDLE which had an execution
+environment which could be initialized prior to each run of user code.
+
+The IDLEfork project was initiated by David Scherer, with some help from Peter
+Schneider-Kamp and Nicholas Riley.  David wrote the first version of the RPC
+code and designed a fast turn-around environment for VPython.  Guido developed
+the RPC code and Remote Debugger currently integrated in IDLE.  Bruce Sherwood
+contributed considerable time testing and suggesting improvements.
+
+Besides David and Guido, the main developers who have been active on IDLEfork
+are Stephen M. Gava, who implemented the configuration GUI, the new
+configuration system, and the About dialog, and Kurt B. Kaiser, who completed
+the integration of the RPC and remote debugger, implemented the threaded
+subprocess, and made a number of usability enhancements.
+
+Other contributors include Raymond Hettinger, Tony Lownds (Mac integration),
+Neal Norwitz (code check and clean-up), Ronald Oussoren (Mac integration),
+Noam Raphael (Code Context, Call Tips, many other patches), and Chui Tey (RPC
+integration, debugger integration and persistent breakpoints).
+
+Scott David Daniels, Tal Einat, Hernan Foffani, Christos Georgiou,
+Jim Jewett, Martin v. Löwis, Jason Orendorff, Josh Robb, Nigel Rowe,
+Bruce Sherwood, and Jeff Shute have submitted useful patches.  Thanks, guys!
+
+For additional details refer to NEWS.txt and Changelog.
+
+Please contact the IDLE maintainer (kbk at shore.net) to have yourself included
+here if you are one of those we missed!
+
+
+

Added: vendor/Python/current/Lib/idlelib/CallTipWindow.py
===================================================================
--- vendor/Python/current/Lib/idlelib/CallTipWindow.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/CallTipWindow.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,171 @@
+"""A CallTip window class for Tkinter/IDLE.
+
+After ToolTip.py, which uses ideas gleaned from PySol
+Used by the CallTips IDLE extension.
+
+"""
+from Tkinter import *
+
+HIDE_VIRTUAL_EVENT_NAME = "<<calltipwindow-hide>>"
+HIDE_SEQUENCES = ("<Key-Escape>", "<FocusOut>")
+CHECKHIDE_VIRTUAL_EVENT_NAME = "<<calltipwindow-checkhide>>"
+CHECKHIDE_SEQUENCES = ("<KeyRelease>", "<ButtonRelease>")
+CHECKHIDE_TIME = 100 # miliseconds
+
+MARK_RIGHT = "calltipwindowregion_right"
+
+class CallTip:
+
+    def __init__(self, widget):
+        self.widget = widget
+        self.tipwindow = self.label = None
+        self.parenline = self.parencol = None
+        self.lastline = None
+        self.hideid = self.checkhideid = None
+
+    def position_window(self):
+        """Check if needs to reposition the window, and if so - do it."""
+        curline = int(self.widget.index("insert").split('.')[0])
+        if curline == self.lastline:
+            return
+        self.lastline = curline
+        self.widget.see("insert")
+        if curline == self.parenline:
+            box = self.widget.bbox("%d.%d" % (self.parenline,
+                                              self.parencol))
+        else:
+            box = self.widget.bbox("%d.0" % curline)
+        if not box:
+            box = list(self.widget.bbox("insert"))
+            # align to left of window
+            box[0] = 0
+            box[2] = 0
+        x = box[0] + self.widget.winfo_rootx() + 2
+        y = box[1] + box[3] + self.widget.winfo_rooty()
+        self.tipwindow.wm_geometry("+%d+%d" % (x, y))
+
+    def showtip(self, text, parenleft, parenright):
+        """Show the calltip, bind events which will close it and reposition it.
+        """
+        # truncate overly long calltip
+        if len(text) >= 79:
+            textlines = text.splitlines()
+            for i, line in enumerate(textlines):
+                if len(line) > 79:
+                    textlines[i] = line[:75] + ' ...'
+            text = '\n'.join(textlines)
+        self.text = text
+        if self.tipwindow or not self.text:
+            return
+
+        self.widget.mark_set(MARK_RIGHT, parenright)
+        self.parenline, self.parencol = map(
+            int, self.widget.index(parenleft).split("."))
+
+        self.tipwindow = tw = Toplevel(self.widget)
+        self.position_window()
+        # remove border on calltip window
+        tw.wm_overrideredirect(1)
+        try:
+            # This command is only needed and available on Tk >= 8.4.0 for OSX
+            # Without it, call tips intrude on the typing process by grabbing
+            # the focus.
+            tw.tk.call("::tk::unsupported::MacWindowStyle", "style", tw._w,
+                       "help", "noActivates")
+        except TclError:
+            pass
+        self.label = Label(tw, text=self.text, justify=LEFT,
+                           background="#ffffe0", relief=SOLID, borderwidth=1,
+                           font = self.widget['font'])
+        self.label.pack()
+
+        self.checkhideid = self.widget.bind(CHECKHIDE_VIRTUAL_EVENT_NAME,
+                                            self.checkhide_event)
+        for seq in CHECKHIDE_SEQUENCES:
+            self.widget.event_add(CHECKHIDE_VIRTUAL_EVENT_NAME, seq)
+        self.widget.after(CHECKHIDE_TIME, self.checkhide_event)
+        self.hideid = self.widget.bind(HIDE_VIRTUAL_EVENT_NAME,
+                                       self.hide_event)
+        for seq in HIDE_SEQUENCES:
+            self.widget.event_add(HIDE_VIRTUAL_EVENT_NAME, seq)
+
+    def checkhide_event(self, event=None):
+        if not self.tipwindow:
+            # If the event was triggered by the same event that unbinded
+            # this function, the function will be called nevertheless,
+            # so do nothing in this case.
+            return
+        curline, curcol = map(int, self.widget.index("insert").split('.'))
+        if curline < self.parenline or \
+           (curline == self.parenline and curcol <= self.parencol) or \
+           self.widget.compare("insert", ">", MARK_RIGHT):
+            self.hidetip()
+        else:
+            self.position_window()
+            self.widget.after(CHECKHIDE_TIME, self.checkhide_event)
+
+    def hide_event(self, event):
+        if not self.tipwindow:
+            # See the explanation in checkhide_event.
+            return
+        self.hidetip()
+
+    def hidetip(self):
+        if not self.tipwindow:
+            return
+
+        for seq in CHECKHIDE_SEQUENCES:
+            self.widget.event_delete(CHECKHIDE_VIRTUAL_EVENT_NAME, seq)
+        self.widget.unbind(CHECKHIDE_VIRTUAL_EVENT_NAME, self.checkhideid)
+        self.checkhideid = None
+        for seq in HIDE_SEQUENCES:
+            self.widget.event_delete(HIDE_VIRTUAL_EVENT_NAME, seq)
+        self.widget.unbind(HIDE_VIRTUAL_EVENT_NAME, self.hideid)
+        self.hideid = None
+
+        self.label.destroy()
+        self.label = None
+        self.tipwindow.destroy()
+        self.tipwindow = None
+
+        self.widget.mark_unset(MARK_RIGHT)
+        self.parenline = self.parencol = self.lastline = None
+
+    def is_active(self):
+        return bool(self.tipwindow)
+
+
+
+###############################
+#
+# Test Code
+#
+class container: # Conceptually an editor_window
+    def __init__(self):
+        root = Tk()
+        text = self.text = Text(root)
+        text.pack(side=LEFT, fill=BOTH, expand=1)
+        text.insert("insert", "string.split")
+        root.update()
+        self.calltip = CallTip(text)
+
+        text.event_add("<<calltip-show>>", "(")
+        text.event_add("<<calltip-hide>>", ")")
+        text.bind("<<calltip-show>>", self.calltip_show)
+        text.bind("<<calltip-hide>>", self.calltip_hide)
+
+        text.focus_set()
+        root.mainloop()
+
+    def calltip_show(self, event):
+        self.calltip.showtip("Hello world")
+
+    def calltip_hide(self, event):
+        self.calltip.hidetip()
+
+def main():
+    # Test code
+    c=container()
+
+if __name__=='__main__':
+    main()

Added: vendor/Python/current/Lib/idlelib/CallTips.py
===================================================================
--- vendor/Python/current/Lib/idlelib/CallTips.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/CallTips.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,212 @@
+"""CallTips.py - An IDLE Extension to Jog Your Memory
+
+Call Tips are floating windows which display function, class, and method
+parameter and docstring information when you type an opening parenthesis, and
+which disappear when you type a closing parenthesis.
+"""
+import sys
+import types
+
+import CallTipWindow
+from HyperParser import HyperParser
+
+import __main__
+
+class CallTips:
+
+    menudefs = [
+        ('edit', [
+            ("Show call tip", "<<force-open-calltip>>"),
+        ])
+    ]
+
+    def __init__(self, editwin=None):
+        if editwin is None:  # subprocess and test
+            self.editwin = None
+            return
+        self.editwin = editwin
+        self.text = editwin.text
+        self.calltip = None
+        self._make_calltip_window = self._make_tk_calltip_window
+
+    def close(self):
+        self._make_calltip_window = None
+
+    def _make_tk_calltip_window(self):
+        # See __init__ for usage
+        return CallTipWindow.CallTip(self.text)
+
+    def _remove_calltip_window(self, event=None):
+        if self.calltip:
+            self.calltip.hidetip()
+            self.calltip = None
+
+    def force_open_calltip_event(self, event):
+        """Happens when the user really wants to open a CallTip, even if a
+        function call is needed.
+        """
+        self.open_calltip(True)
+
+    def try_open_calltip_event(self, event):
+        """Happens when it would be nice to open a CallTip, but not really
+        neccesary, for example after an opening bracket, so function calls
+        won't be made.
+        """
+        self.open_calltip(False)
+
+    def refresh_calltip_event(self, event):
+        """If there is already a calltip window, check if it is still needed,
+        and if so, reload it.
+        """
+        if self.calltip and self.calltip.is_active():
+            self.open_calltip(False)
+
+    def open_calltip(self, evalfuncs):
+        self._remove_calltip_window()
+
+        hp = HyperParser(self.editwin, "insert")
+        sur_paren = hp.get_surrounding_brackets('(')
+        if not sur_paren:
+            return
+        hp.set_index(sur_paren[0])
+        name = hp.get_expression()
+        if not name or (not evalfuncs and name.find('(') != -1):
+            return
+        arg_text = self.fetch_tip(name)
+        if not arg_text:
+            return
+        self.calltip = self._make_calltip_window()
+        self.calltip.showtip(arg_text, sur_paren[0], sur_paren[1])
+
+    def fetch_tip(self, name):
+        """Return the argument list and docstring of a function or class
+
+        If there is a Python subprocess, get the calltip there.  Otherwise,
+        either fetch_tip() is running in the subprocess itself or it was called
+        in an IDLE EditorWindow before any script had been run.
+
+        The subprocess environment is that of the most recently run script.  If
+        two unrelated modules are being edited some calltips in the current
+        module may be inoperative if the module was not the last to run.
+
+        """
+        try:
+            rpcclt = self.editwin.flist.pyshell.interp.rpcclt
+        except:
+            rpcclt = None
+        if rpcclt:
+            return rpcclt.remotecall("exec", "get_the_calltip",
+                                     (name,), {})
+        else:
+            entity = self.get_entity(name)
+            return get_arg_text(entity)
+
+    def get_entity(self, name):
+        "Lookup name in a namespace spanning sys.modules and __main.dict__"
+        if name:
+            namespace = sys.modules.copy()
+            namespace.update(__main__.__dict__)
+            try:
+                return eval(name, namespace)
+            except:
+                return None
+
+def _find_constructor(class_ob):
+    # Given a class object, return a function object used for the
+    # constructor (ie, __init__() ) or None if we can't find one.
+    try:
+        return class_ob.__init__.im_func
+    except AttributeError:
+        for base in class_ob.__bases__:
+            rc = _find_constructor(base)
+            if rc is not None: return rc
+    return None
+
+def get_arg_text(ob):
+    """Get a string describing the arguments for the given object"""
+    argText = ""
+    if ob is not None:
+        argOffset = 0
+        if type(ob) in (types.ClassType, types.TypeType):
+            # Look for the highest __init__ in the class chain.
+            fob = _find_constructor(ob)
+            if fob is None:
+                fob = lambda: None
+            else:
+                argOffset = 1
+        elif type(ob)==types.MethodType:
+            # bit of a hack for methods - turn it into a function
+            # but we drop the "self" param.
+            fob = ob.im_func
+            argOffset = 1
+        else:
+            fob = ob
+        # Try and build one for Python defined functions
+        if type(fob) in [types.FunctionType, types.LambdaType]:
+            try:
+                realArgs = fob.func_code.co_varnames[argOffset:fob.func_code.co_argcount]
+                defaults = fob.func_defaults or []
+                defaults = list(map(lambda name: "=%s" % repr(name), defaults))
+                defaults = [""] * (len(realArgs)-len(defaults)) + defaults
+                items = map(lambda arg, dflt: arg+dflt, realArgs, defaults)
+                if fob.func_code.co_flags & 0x4:
+                    items.append("...")
+                if fob.func_code.co_flags & 0x8:
+                    items.append("***")
+                argText = ", ".join(items)
+                argText = "(%s)" % argText
+            except:
+                pass
+        # See if we can use the docstring
+        doc = getattr(ob, "__doc__", "")
+        if doc:
+            doc = doc.lstrip()
+            pos = doc.find("\n")
+            if pos < 0 or pos > 70:
+                pos = 70
+            if argText:
+                argText += "\n"
+            argText += doc[:pos]
+    return argText
+
+#################################################
+#
+# Test code
+#
+if __name__=='__main__':
+
+    def t1(): "()"
+    def t2(a, b=None): "(a, b=None)"
+    def t3(a, *args): "(a, ...)"
+    def t4(*args): "(...)"
+    def t5(a, *args): "(a, ...)"
+    def t6(a, b=None, *args, **kw): "(a, b=None, ..., ***)"
+
+    class TC:
+        "(a=None, ...)"
+        def __init__(self, a=None, *b): "(a=None, ...)"
+        def t1(self): "()"
+        def t2(self, a, b=None): "(a, b=None)"
+        def t3(self, a, *args): "(a, ...)"
+        def t4(self, *args): "(...)"
+        def t5(self, a, *args): "(a, ...)"
+        def t6(self, a, b=None, *args, **kw): "(a, b=None, ..., ***)"
+
+    def test(tests):
+        ct = CallTips()
+        failed=[]
+        for t in tests:
+            expected = t.__doc__ + "\n" + t.__doc__
+            name = t.__name__
+            arg_text = ct.fetch_tip(name)
+            if arg_text != expected:
+                failed.append(t)
+                print "%s - expected %s, but got %s" % (t, expected,
+                                                        get_arg_text(entity))
+        print "%d of %d tests failed" % (len(failed), len(tests))
+
+    tc = TC()
+    tests = (t1, t2, t3, t4, t5, t6,
+             TC, tc.t1, tc.t2, tc.t3, tc.t4, tc.t5, tc.t6)
+
+    test(tests)

Added: vendor/Python/current/Lib/idlelib/ChangeLog
===================================================================
--- vendor/Python/current/Lib/idlelib/ChangeLog	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/ChangeLog	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1591 @@
+Please refer to the IDLEfork and IDLE CVS repositories for
+change details subsequent to the 0.8.1 release.
+
+
+IDLEfork ChangeLog
+==================
+
+2001-07-20 11:35  elguavas
+
+	* README.txt, NEWS.txt: bring up to date for 0.8.1 release
+
+2001-07-19 16:40  elguavas
+
+	* IDLEFORK.html: replaced by IDLEFORK-index.html
+
+2001-07-19 16:39  elguavas
+
+	* IDLEFORK-index.html: updated placeholder idlefork homepage
+
+2001-07-19 14:49  elguavas
+
+	* ChangeLog, EditorWindow.py, INSTALLATION, NEWS.txt, README.txt,
+	TODO.txt, idlever.py: 
+	minor tidy-ups ready for 0.8.1 alpha tarball release
+
+2001-07-17 15:12  kbk
+
+	* INSTALLATION, setup.py: INSTALLATION: Remove the coexist.patch
+	instructions
+	
+	**************** setup.py:
+	
+	Remove the idles script, add some words on IDLE Fork to the
+	long_description, and clean up some line spacing.
+
+2001-07-17 15:01  kbk
+
+	* coexist.patch: Put this in the attic, at least for now...
+
+2001-07-17 14:59  kbk
+
+	* PyShell.py, idle, idles: Implement idle command interface as
+	suggested by GvR [idle-dev] 16 July **************** PyShell: Added
+	functionality:
+	
+	usage: idle.py [-c command] [-d] [-i] [-r script] [-s] [-t title]
+	[arg] ...
+	
+	idle file(s)	(without options) edit the file(s)
+	
+	-c cmd	   run the command in a shell -d	 enable the
+	debugger -i	    open an interactive shell -i file(s) open a
+	shell and also an editor window for each file -r script  run a file
+	as a script in a shell -s	  run $IDLESTARTUP or
+	$PYTHONSTARTUP before anything else -t title   set title of shell
+	window
+	
+	Remaining arguments are applied to the command (-c) or script (-r).
+	
+	****************** idles: Removed the idles script, not needed
+	
+	****************** idle:  Removed the IdleConf references, not
+	required anymore
+
+2001-07-16 17:08  kbk
+
+	* INSTALLATION, coexist.patch: Added installation instructions.
+	
+	Added a patch which modifies idlefork so that it can co-exist with
+	"official" IDLE in the site-packages directory. This patch is not
+	necessary if only idlefork IDLE is installed. See INSTALLATION for
+	further details.
+
+2001-07-16 15:50  kbk
+
+	* idles: Add a script "idles" which opens a Python Shell window.
+	
+	The default behaviour of idlefork idle is to open an editor window
+	instead of a shell. Complex expressions may be run in a fresh
+	environment by selecting "run".  There are times, however, when a
+	shell is desired.  Though one can be started by "idle -t 'foo'",
+	this script is more convenient.  In addition, a shell and an editor
+	window can be started in parallel by "idles -e foo.py".
+
+2001-07-16 15:25  kbk
+
+	* PyShell.py: Call out IDLE Fork in startup message.
+
+2001-07-16 14:00  kbk
+
+	* PyShell.py, setup.py: Add a script "idles" which opens a Python
+	Shell window.
+	
+	The default behaviour of idlefork idle is to open an editor window
+	instead of a shell. Complex expressions may be run in a fresh
+	environment by selecting "run".  There are times, however, when a
+	shell is desired.  Though one can be started by "idle -t 'foo'",
+	this script is more convenient.  In addition, a shell and an editor
+	window can be started in parallel by "idles -e foo.py".
+
+2001-07-15 03:06  kbk
+
+	* pyclbr.py, tabnanny.py: tabnanny and pyclbr are now found in /Lib
+
+2001-07-15 02:29  kbk
+
+	* BrowserControl.py: Remove, was retained for 1.5.2 support
+
+2001-07-14 15:48  kbk
+
+	* setup.py: Installing Idle to site-packages via Distutils does not
+	copy the Idle help.txt file.
+	
+	Ref SF Python Patch 422471
+
+2001-07-14 15:26  kbk
+
+	* keydefs.py: py-cvs-2001_07_13 (Rev 1.3) merge
+	
+	"Make copy, cut and paste events case insensitive.  Reported by
+	Patrick K. O'Brien on idle-dev. (Should other bindings follow
+	suit?)" --GvR
+
+2001-07-14 15:21  kbk
+
+	* idle.py: py-cvs-2001_07_13 (Rev 1.4) merge
+	
+	"Move the action of loading the configuration to the IdleConf
+	module rather than the idle.py script.	This has advantages and
+	disadvantages; the biggest advantage being that we can more easily
+	have an alternative main program."  --GvR
+
+2001-07-14 15:18  kbk
+
+	* extend.txt: py-cvs-2001_07_13 (Rev 1.4) merge
+	
+	"Quick update to the extension mechanism (extend.py is gone, long
+	live config.txt)" --GvR
+
+2001-07-14 15:15  kbk
+
+	* StackViewer.py: py-cvs-2001_07_13 (Rev 1.16) merge
+	
+	"Refactored, with some future plans in mind. This now uses the new
+	gotofileline() method defined in FileList.py"  --GvR
+
+2001-07-14 15:10  kbk
+
+	* PyShell.py: py-cvs-2001_07_13 (Rev 1.34) merge
+	
+	"Amazing.  A very subtle change in policy in descr-branch actually
+	found a bug here.  Here's the deal: Class PyShell derives from
+	class OutputWindow.  Method PyShell.close() wants to invoke its
+	parent method, but because PyShell long ago was inherited from
+	class PyShellEditorWindow, it invokes
+	PyShelEditorWindow.close(self).  Now, class PyShellEditorWindow
+	itself derives from class OutputWindow, and inherits the close()
+	method from there without overriding it.  Under the old rules,
+	PyShellEditorWindow.close would return an unbound method restricted
+	to the class that defined the implementation of close(), which was
+	OutputWindow.close.  Under the new rules, the unbound method is
+	restricted to the class whose method was requested, that is
+	PyShellEditorWindow, and this was correctly trapped as an error."
+	--GvR
+
+2001-07-14 14:59  kbk
+
+	* PyParse.py: py-cvs-2001_07_13 (Rel 1.9) merge
+	
+	"Taught IDLE's autoident parser that "yield" is a keyword that
+	begins a stmt.	Along w/ the preceding change to keyword.py, making
+	all this work w/ a future-stmt just looks harder and harder."
+	--tim_one
+	
+	(From Rel 1.8: "Hack to make this still work with Python 1.5.2. 
+	;-( " --fdrake)
+
+2001-07-14 14:51  kbk
+
+	* IdleConf.py: py-cvs-2001_07_13 (Rel 1.7) merge
+	
+	"Move the action of loading the configuration to the IdleConf
+	module rather than the idle.py script.	This has advantages and
+	disadvantages; the biggest advantage being that we can more easily
+	have an alternative main program." --GvR
+
+2001-07-14 14:45  kbk
+
+	* FileList.py: py-cvs-2000_07_13 (Rev 1.9) merge
+	
+	"Delete goodname() method, which is unused. Add gotofileline(), a
+	convenience method which I intend to use in a variant. Rename
+	test() to _test()."  --GvR
+	
+	This was an interesting merge. The join completely missed removing
+	goodname(), which was adjacent, but outside of, a small conflict. 
+	I only caught it by comparing the 1.1.3.2/1.1.3.3 diff.  CVS ain't
+	infallible.
+
+2001-07-14 13:58  kbk
+
+	* EditorWindow.py: py-cvs-2000_07_13 (Rev 1.38) merge "Remove
+	legacy support for the BrowserControl module; the webbrowser module
+	has been included since Python 2.0, and that is the preferred
+	interface." --fdrake
+
+2001-07-14 13:32  kbk
+
+	* EditorWindow.py, FileList.py, IdleConf.py, PyParse.py,
+	PyShell.py, StackViewer.py, extend.txt, idle.py, keydefs.py: Import
+	the 2001 July 13 23:59 GMT version of Python CVS IDLE on the
+	existing 1.1.3 vendor branch named py-cvs-vendor-branch. Release
+	tag is py-cvs-2001_07_13.
+
+2001-07-14 12:02  kbk
+
+	* Icons/python.gif: py-cvs-rel2_1 (Rev 1.2) merge Copied py-cvs rev
+	1.2 changed file to idlefork MAIN
+
+2001-07-14 11:58  kbk
+
+	* Icons/minusnode.gif: py-cvs-rel2_1 (Rev 1.2) merge Copied py-cvs
+	1.2 changed file to idlefork MAIN
+
+2001-07-14 11:23  kbk
+
+	* ScrolledList.py: py-cvs-rel2_1 (rev 1.5) merge - whitespace
+	normalization
+
+2001-07-14 11:20  kbk
+
+	* Separator.py: py-cvs-rel2_1 (Rev 1.3) merge - whitespace
+	normalization
+
+2001-07-14 11:16  kbk
+
+	* StackViewer.py: py-cvs-rel2_1 (Rev 1.15) merge - whitespace
+	normalization
+
+2001-07-14 11:14  kbk
+
+	* ToolTip.py: py-cvs-rel2_1 (Rev 1.2) merge - whitespace
+	normalization
+
+2001-07-14 10:13  kbk
+
+	* PyShell.py: cvs-py-rel2_1 (Rev 1.29 - 1.33) merge
+	
+	Merged the following py-cvs revs without conflict: 1.29 Reduce
+	copyright text output at startup 1.30 Delay setting sys.args until
+	Tkinter is fully initialized 1.31 Whitespace normalization 1.32
+	Turn syntax warning into error when interactive 1.33 Fix warning
+	initialization bug
+	
+	Note that module is extensively modified wrt py-cvs
+
+2001-07-14 06:33  kbk
+
+	* PyParse.py: py-cvs-rel2_1 (Rev 1.6 - 1.8) merge Fix autoindent
+	bug and deflect Unicode from text.get()
+
+2001-07-14 06:00  kbk
+
+	* Percolator.py: py-cvs-rel2_1 (Rev 1.3) "move "from Tkinter import
+	*" to module level" --jhylton
+
+2001-07-14 05:57  kbk
+
+	* PathBrowser.py: py-cvs-rel2_1 (Rev 1.6) merge - whitespace
+	normalization
+
+2001-07-14 05:49  kbk
+
+	* ParenMatch.py: cvs-py-rel2_1 (Rev 1.5) merge - whitespace
+	normalization
+
+2001-07-14 03:57  kbk
+
+	* ObjectBrowser.py: py-cvs-rel2_1 (Rev 1.3) merge "Make the test
+	program work outside IDLE."  -- GvR
+
+2001-07-14 03:52  kbk
+
+	* MultiStatusBar.py: py-cvs-rel2_1 (Rev 1.2) merge - whitespace
+	normalization
+
+2001-07-14 03:44  kbk
+
+	* MultiScrolledLists.py: py-cvs-rel2_1 (Rev 1.2) merge - whitespace
+	normalization
+
+2001-07-14 03:40  kbk
+
+	* IdleHistory.py: py-cvs-rel2_1 (Rev 1.4) merge - whitespace
+	normalization
+
+2001-07-14 03:38  kbk
+
+	* IdleConf.py: py-cvs-rel2_1 (Rev 1.6) merge - whitespace
+	normalization
+
+2001-07-13 14:18  kbk
+
+	* IOBinding.py: py-cvs-rel2_1 (Rev 1.4) merge - move "import *" to
+	module level
+
+2001-07-13 14:12  kbk
+
+	* FormatParagraph.py: py-cvs-rel2_1 (Rev 1.9) merge - whitespace
+	normalization
+
+2001-07-13 14:07  kbk
+
+	* FileList.py: py-cvs-rel2_1 (Rev 1.8) merge - whitespace
+	normalization
+
+2001-07-13 13:35  kbk
+
+	* EditorWindow.py: py-cvs-rel2_1 (Rev 1.33 - 1.37) merge
+	
+	VP IDLE version depended on VP's ExecBinding.py and spawn.py to get
+	the path to the Windows Doc directory (relative to python.exe).
+	Removed this conflicting code in favor of py-cvs updates which on
+	Windows use a hard coded path relative to the location of this
+	module. py-cvs updates include support for webbrowser.py.  Module
+	still has BrowserControl.py for 1.5.2 support.
+	
+	At this point, the differences wrt py-cvs relate to menu
+	functionality.
+
+2001-07-13 11:30  kbk
+
+	* ConfigParser.py: py-cvs-rel2_1 merge - Remove, lives in /Lib
+
+2001-07-13 10:10  kbk
+
+	* Delegator.py: py-cvs-rel2_1 (Rev 1.3) merge - whitespace
+	normalization
+
+2001-07-13 10:07  kbk
+
+	* Debugger.py: py-cvs-rel2_1 (Rev 1.15) merge - whitespace
+	normalization
+
+2001-07-13 10:04  kbk
+
+	* ColorDelegator.py: py-cvs-rel2_1 (Rev 1.11 and 1.12) merge
+	Colorize "as" after "import" / use DEBUG instead of __debug__
+
+2001-07-13 09:54  kbk
+
+	* ClassBrowser.py: py-cvs-rel2_1 (Rev 1.12) merge - whitespace
+	normalization
+
+2001-07-13 09:41  kbk
+
+	* BrowserControl.py: py-cvs-rel2_1 (Rev 1.1) merge - New File -
+	Force HEAD to trunk with -f Note: browser.py was renamed
+	BrowserControl.py 10 May 2000. It provides a collection of classes
+	and convenience functions to control external browsers "for 1.5.2
+	support". It was removed from py-cvs 18 April 2001.
+
+2001-07-13 09:10  kbk
+
+	* CallTips.py: py-cvs-rel2_1 (Rev 1.8) merge - whitespace
+	normalization
+
+2001-07-13 08:26  kbk
+
+	* CallTipWindow.py: py-cvs-rel2_1 (Rev 1.3) merge - whitespace
+	normalization
+
+2001-07-13 08:13  kbk
+
+	* AutoExpand.py: py-cvs-rel1_2 (Rev 1.4) merge, "Add Alt-slash to
+	Unix keydefs (I somehow need it on RH 6.2).  Get rid of assignment
+	to unused self.text.wordlist."	--GvR
+
+2001-07-12 16:54  elguavas
+
+	* ReplaceDialog.py: py-cvs merge, python 1.5.2 compatibility
+
+2001-07-12 16:46  elguavas
+
+	* ScriptBinding.py: py-cvs merge, better error dialog
+
+2001-07-12 16:38  elguavas
+
+	* TODO.txt: py-cvs merge, additions
+
+2001-07-12 15:35  elguavas
+
+	* WindowList.py: py-cvs merge, correct indentation
+
+2001-07-12 15:24  elguavas
+
+	* config.txt: py-cvs merge, correct typo
+
+2001-07-12 15:21  elguavas
+
+	* help.txt: py-cvs merge, update colour changing info
+
+2001-07-12 14:51  elguavas
+
+	* idle.py: py-cvs merge, idle_dir loading changed
+
+2001-07-12 14:44  elguavas
+
+	* idlever.py: py-cvs merge, version update
+
+2001-07-11 12:53  kbk
+
+	* BrowserControl.py: Initial revision
+
+2001-07-11 12:53  kbk
+
+	* AutoExpand.py, BrowserControl.py, CallTipWindow.py, CallTips.py,
+	ClassBrowser.py, ColorDelegator.py, Debugger.py, Delegator.py,
+	EditorWindow.py, FileList.py, FormatParagraph.py, IOBinding.py,
+	IdleConf.py, IdleHistory.py, MultiScrolledLists.py,
+	MultiStatusBar.py, ObjectBrowser.py, OutputWindow.py,
+	ParenMatch.py, PathBrowser.py, Percolator.py, PyParse.py,
+	PyShell.py, RemoteInterp.py, ReplaceDialog.py, ScriptBinding.py,
+	ScrolledList.py, Separator.py, StackViewer.py, TODO.txt,
+	ToolTip.py, WindowList.py, config.txt, help.txt, idle, idle.bat,
+	idle.py, idlever.py, setup.py, Icons/minusnode.gif,
+	Icons/python.gif: Import the release 2.1 version of Python CVS IDLE
+	on the existing 1.1.3 vendor branch named py-cvs-vendor-branch,
+	with release tag py-cvs-rel2_1.
+
+2001-07-11 12:34  kbk
+
+	* AutoExpand.py, AutoIndent.py, Bindings.py, CallTipWindow.py,
+	CallTips.py, ChangeLog, ClassBrowser.py, ColorDelegator.py,
+	Debugger.py, Delegator.py, EditorWindow.py, FileList.py,
+	FormatParagraph.py, FrameViewer.py, GrepDialog.py, IOBinding.py,
+	IdleConf.py, IdleHistory.py, MultiScrolledLists.py,
+	MultiStatusBar.py, NEWS.txt, ObjectBrowser.py, OldStackViewer.py,
+	OutputWindow.py, ParenMatch.py, PathBrowser.py, Percolator.py,
+	PyParse.py, PyShell.py, README.txt, RemoteInterp.py,
+	ReplaceDialog.py, ScriptBinding.py, ScrolledList.py,
+	SearchBinding.py, SearchDialog.py, SearchDialogBase.py,
+	SearchEngine.py, Separator.py, StackViewer.py, TODO.txt,
+	ToolTip.py, TreeWidget.py, UndoDelegator.py, WidgetRedirector.py,
+	WindowList.py, ZoomHeight.py, __init__.py, config-unix.txt,
+	config-win.txt, config.txt, eventparse.py, extend.txt, help.txt,
+	idle.bat, idle.py, idle.pyw, idlever.py, keydefs.py, pyclbr.py,
+	tabnanny.py, testcode.py, Icons/folder.gif, Icons/minusnode.gif,
+	Icons/openfolder.gif, Icons/plusnode.gif, Icons/python.gif,
+	Icons/tk.gif: Import the 9 March 2000 version of Python CVS IDLE as
+	1.1.3 vendor branch named py-cvs-vendor-branch.
+
+2001-07-04 13:43  kbk
+
+	* Icons/: folder.gif, minusnode.gif, openfolder.gif, plusnode.gif,
+	python.gif, tk.gif: Null commit with -f option to force an uprev
+	and put HEADs firmly on the trunk.
+
+2001-07-04 13:15  kbk
+
+	* AutoExpand.py, AutoIndent.py, Bindings.py, CallTipWindow.py,
+	CallTips.py, ChangeLog, ClassBrowser.py, ColorDelegator.py,
+	ConfigParser.py, Debugger.py, Delegator.py, EditorWindow.py,
+	ExecBinding.py, FileList.py, FormatParagraph.py, FrameViewer.py,
+	GrepDialog.py, IDLEFORK.html, IOBinding.py, IdleConf.py,
+	IdleHistory.py, MultiScrolledLists.py, MultiStatusBar.py, NEWS.txt,
+	ObjectBrowser.py, OldStackViewer.py, OutputWindow.py,
+	ParenMatch.py, PathBrowser.py, Percolator.py, PyParse.py,
+	PyShell.py, README.txt, Remote.py, RemoteInterp.py,
+	ReplaceDialog.py, ScriptBinding.py, ScrolledList.py,
+	SearchBinding.py, SearchDialog.py, SearchDialogBase.py,
+	SearchEngine.py, Separator.py, StackViewer.py, TODO.txt,
+	ToolTip.py, TreeWidget.py, UndoDelegator.py, WidgetRedirector.py,
+	WindowList.py, ZoomHeight.py, __init__.py, config-unix.txt,
+	config-win.txt, config.txt, eventparse.py, extend.txt, help.txt,
+	idle, idle.bat, idle.py, idle.pyw, idlever.py, keydefs.py,
+	loader.py, protocol.py, pyclbr.py, setup.py, spawn.py, tabnanny.py,
+	testcode.py: Null commit with -f option to force an uprev and put
+	HEADs firmly on the trunk.
+
+2001-06-27 10:24  elguavas
+
+	* IDLEFORK.html: updated contact details
+
+2001-06-25 17:23  elguavas
+
+	* idle, RemoteInterp.py, setup.py: Initial revision
+
+2001-06-25 17:23  elguavas
+
+	* idle, RemoteInterp.py, setup.py: import current python cvs idle
+	as a vendor branch
+
+2001-06-24 15:10  elguavas
+
+	* IDLEFORK.html: tiny change to test new syncmail setup
+
+2001-06-24 14:41  elguavas
+
+	* IDLEFORK.html: change to new developer contact, also a test
+	commit for new syncmail setup
+
+2001-06-23 18:15  elguavas
+
+	* IDLEFORK.html: tiny test update for revitalised idle-fork
+
+2000-09-24 17:29  nriley
+
+	* protocol.py: Fixes for Python 1.6 compatibility - socket bind and
+	connect get a tuple instead two arguments.
+
+2000-09-24 17:28  nriley
+
+	* spawn.py: Change for Python 1.6 compatibility - UNIX's 'os'
+	module defines 'spawnv' now, so we check for 'fork' first.
+
+2000-08-15 22:51  nowonder
+
+	* IDLEFORK.html: 
+	corrected email address
+
+2000-08-15 22:47  nowonder
+
+	* IDLEFORK.html: 
+	added .html file for http://idlefork.sourceforge.net
+
+2000-08-15 11:13  dscherer
+
+	* AutoExpand.py, AutoIndent.py, Bindings.py, CallTipWindow.py,
+	CallTips.py, __init__.py, ChangeLog, ClassBrowser.py,
+	ColorDelegator.py, ConfigParser.py, Debugger.py, Delegator.py,
+	FileList.py, FormatParagraph.py, FrameViewer.py, GrepDialog.py,
+	IOBinding.py, IdleConf.py, IdleHistory.py, MultiScrolledLists.py,
+	MultiStatusBar.py, NEWS.txt, ObjectBrowser.py, OldStackViewer.py,
+	OutputWindow.py, ParenMatch.py, PathBrowser.py, Percolator.py,
+	PyParse.py, PyShell.py, README.txt, ReplaceDialog.py,
+	ScriptBinding.py, ScrolledList.py, SearchBinding.py,
+	SearchDialog.py, SearchDialogBase.py, SearchEngine.py,
+	Separator.py, StackViewer.py, TODO.txt, ToolTip.py, TreeWidget.py,
+	UndoDelegator.py, WidgetRedirector.py, WindowList.py, help.txt,
+	ZoomHeight.py, config-unix.txt, config-win.txt, config.txt,
+	eventparse.py, extend.txt, idle.bat, idle.py, idle.pyw, idlever.py,
+	keydefs.py, loader.py, pyclbr.py, tabnanny.py, testcode.py,
+	EditorWindow.py, ExecBinding.py, Remote.py, protocol.py, spawn.py,
+	Icons/folder.gif, Icons/minusnode.gif, Icons/openfolder.gif,
+	Icons/plusnode.gif, Icons/python.gif, Icons/tk.gif: Initial
+	revision
+
+2000-08-15 11:13  dscherer
+
+	* AutoExpand.py, AutoIndent.py, Bindings.py, CallTipWindow.py,
+	CallTips.py, __init__.py, ChangeLog, ClassBrowser.py,
+	ColorDelegator.py, ConfigParser.py, Debugger.py, Delegator.py,
+	FileList.py, FormatParagraph.py, FrameViewer.py, GrepDialog.py,
+	IOBinding.py, IdleConf.py, IdleHistory.py, MultiScrolledLists.py,
+	MultiStatusBar.py, NEWS.txt, ObjectBrowser.py, OldStackViewer.py,
+	OutputWindow.py, ParenMatch.py, PathBrowser.py, Percolator.py,
+	PyParse.py, PyShell.py, README.txt, ReplaceDialog.py,
+	ScriptBinding.py, ScrolledList.py, SearchBinding.py,
+	SearchDialog.py, SearchDialogBase.py, SearchEngine.py,
+	Separator.py, StackViewer.py, TODO.txt, ToolTip.py, TreeWidget.py,
+	UndoDelegator.py, WidgetRedirector.py, WindowList.py, help.txt,
+	ZoomHeight.py, config-unix.txt, config-win.txt, config.txt,
+	eventparse.py, extend.txt, idle.bat, idle.py, idle.pyw, idlever.py,
+	keydefs.py, loader.py, pyclbr.py, tabnanny.py, testcode.py,
+	EditorWindow.py, ExecBinding.py, Remote.py, protocol.py, spawn.py,
+	Icons/folder.gif, Icons/minusnode.gif, Icons/openfolder.gif,
+	Icons/plusnode.gif, Icons/python.gif, Icons/tk.gif: Modified IDLE
+	from VPython 0.2
+
+
+original IDLE ChangeLog:
+========================
+
+Tue Feb 15 18:08:19 2000  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* NEWS.txt: Notice status bar and stack viewer.
+
+	* EditorWindow.py: Support for Moshe's status bar.
+
+	* MultiStatusBar.py: Status bar code -- by Moshe Zadka.
+
+	* OldStackViewer.py:
+	Adding the old stack viewer implementation back, for the debugger.
+
+	* StackViewer.py: New stack viewer, uses a tree widget.
+	(XXX: the debugger doesn't yet use this.)
+
+	* WindowList.py:
+	Correct a typo and remove an unqualified except that was hiding the error.
+
+	* ClassBrowser.py: Add an XXX comment about the ClassBrowser AIP.
+
+	* ChangeLog: Updated change log.
+
+	* NEWS.txt: News update.  Probably incomplete; what else is new?
+
+	* README.txt:
+	Updated for pending IDLE 0.5 release (still very rough -- just getting
+	it out in a more convenient format than CVS).
+
+	* TODO.txt: Tiny addition.
+
+Thu Sep  9 14:16:02 1999  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* TODO.txt: A few new TODO entries.
+
+Thu Aug 26 23:06:22 1999  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* Bindings.py: Add Python Documentation entry to Help menu.
+
+	* EditorWindow.py:
+	Find the help.txt file relative to __file__ or ".", not in sys.path.
+	(Suggested by Moshe Zadka, but implemented differently.)
+
+	Add <<python-docs>> event which, on Unix, brings up Netscape pointing
+	to http://www.python.doc/current/ (a local copy would be nice but its
+	location can't be predicted).  Windows solution TBD.
+
+Wed Aug 11 14:55:43 1999  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* TreeWidget.py:
+	Moshe noticed an inconsistency in his comment, so I'm rephrasing it to
+	be clearer.
+
+	* TreeWidget.py:
+	Patch inspired by Moshe Zadka to search for the Icons directory in the
+	same directory as __file__, rather than searching for it along sys.path.
+	This works better when idle is a package.
+
+Thu Jul 15 13:11:02 1999  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* TODO.txt: New wishes.
+
+Sat Jul 10 13:17:35 1999  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* IdlePrefs.py:
+	Make the color for stderr red (i.e. the standard warning/danger/stop
+	color) rather than green.  Suggested by Sam Schulenburg.
+
+Fri Jun 25 17:26:34 1999  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* PyShell.py: Close debugger when closing.  This may break a cycle.
+
+	* Debugger.py: Break cycle on close.
+
+	* ClassBrowser.py: Destroy the tree when closing.
+
+	* TreeWidget.py: Add destroy() method to recursively destroy a tree.
+
+	* PyShell.py: Extend _close() to break cycles.
+	Break some other cycles too (and destroy the root when done).
+
+	* EditorWindow.py:
+	Add _close() method that does the actual cleanup (close() asks the
+	user what they want first if there's unsaved stuff, and may cancel).
+	It closes more than before.
+
+	Add unload_extensions() method to unload all extensions; called from
+	_close().  It calls an extension's close() method if it has one.
+
+	* Percolator.py: Add close() method that breaks cycles.
+
+	* WidgetRedirector.py: Add unregister() method.
+	Unregister everything at closing.
+	Don't call close() in __del__, rely on explicit call to close().
+
+	* IOBinding.py, FormatParagraph.py, CallTips.py:
+	Add close() method that breaks a cycle.
+
+Fri Jun 11 15:03:00 1999  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* AutoIndent.py, EditorWindow.py, FormatParagraph.py:
+	Tim Peters smart.patch:
+
+	EditorWindow.py:
+
+	+ Added get_tabwidth & set_tabwidth "virtual text" methods, that get/set the
+	widget's view of what a tab means.
+
+	+ Moved TK_TABWIDTH_DEFAULT here from AutoIndent.
+
+	+ Renamed Mark's get_selection_index to get_selection_indices (sorry, Mark,
+	but the name was plain wrong <wink>).
+
+	FormatParagraph.py:  renamed use of get_selection_index.
+
+	AutoIndent.py:
+
+	+ Moved TK_TABWIDTH_DEFAULT to EditorWindow.
+
+	+ Rewrote set_indentation_params to use new VTW get/set_tabwidth methods.
+
+	+ Changed smart_backspace_event to delete whitespace back to closest
+	preceding virtual tab stop or real character (note that this may require
+	inserting characters if backspacing over a tab!).
+
+	+ Nuked almost references to the selection tag, in favor of using
+	get_selection_indices.  The sole exception is in set_region, for which no
+	"set_selection" abstraction has yet been agreed upon.
+
+	+ Had too much fun using the spiffy new features of the format-paragraph
+	cmd.
+
+Thu Jun 10 17:48:02 1999  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* FormatParagraph.py:
+	Code by Mark Hammond to format paragraphs embedded in comments.
+	Read the comments (which I reformatted using the new feature :-)
+	for some limitations.
+
+	* EditorWindow.py:
+	Added abstraction get_selection_index() (Mark Hammond).  Also
+	reformatted some comment blocks to show off a cool feature I'm about
+	to check in next.
+
+	* ClassBrowser.py:
+	Adapt to the new pyclbr's support of listing top-level functions.  If
+	this functionality is not present (e.g. when used with a vintage
+	Python 1.5.2 installation) top-level functions are not listed.
+
+	(Hmm...  Any distribution of IDLE 0.5 should probably include a copy
+	of the new pyclbr.py!)
+
+	* AutoIndent.py:
+	Fix off-by-one error in Tim's recent change to comment_region(): the
+	list of lines returned by get_region() contains an empty line at the
+	end representing the start of the next line, and this shouldn't be
+	commented out!
+
+	* CallTips.py:
+	Mark Hammond writes: Here is another change that allows it to work for
+	class creation - tries to locate an __init__ function.  Also updated
+	the test code to reflect your new "***" change.
+
+	* CallTipWindow.py:
+	Mark Hammond writes: Tim's suggestion of copying the font for the
+	CallTipWindow from the text control makes sense, and actually makes
+	the control look better IMO.
+
+Wed Jun  9 20:34:57 1999  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* CallTips.py:
+	Append "..." if the appropriate flag (for varargs) in co_flags is set.
+	Ditto "***" for kwargs.
+
+Tue Jun  8 13:06:07 1999  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* ReplaceDialog.py:
+	Hmm...  Tim didn't turn "replace all" into a single undo block.
+	I think I like it better if it os, so here.
+
+	* ReplaceDialog.py: Tim Peters: made replacement atomic for undo/redo.
+
+	* AutoIndent.py: Tim Peters:
+
+	+ Set usetabs=1.  Editing pyclbr.py was driving me nuts <0.6 wink>.
+	usetabs=1 is the Emacs pymode default too, and thanks to indentwidth !=
+	tabwidth magical usetabs disabling, new files are still created with tabs
+	turned off.  The only implication is that if you open a file whose first
+	indent is a single tab, IDLE will now magically use tabs for that file (and
+	set indentwidth to 8).  Note that the whole scheme doesn't work right for
+	PythonWin, though, since Windows users typically set tabwidth to 4; Mark
+	probably has to hide the IDLE algorithm from them (which he already knows).
+
+	+ Changed comment_region_event to stick "##" in front of every line.  The
+	"holes" previously left on blank lines were visually confusing (made it
+	needlessly hard to figure out what to uncomment later).
+
+Mon Jun  7 15:38:40 1999  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* TreeWidget.py, ObjectBrowser.py:
+	Remove unnecessary reference to pyclbr from test() code.
+
+	* PyParse.py: Tim Peters:
+
+	Smarter logic for finding a parse synch point.
+
+	Does a half to a fifth the work in normal cases; don't notice the speedup,
+	but makes  more breathing room for other extensions.
+
+	Speeds terrible cases by at least a factor of 10. "Terrible" == e.g. you put
+	""" at the start of Tkinter.py, undo it, zoom to the bottom, and start
+	typing in code.  Used to take about 8 seconds for ENTER to respond, now some
+	large fraction of a second.  The new code gets indented correctly, despite
+	that it all remains "string colored" until the colorizer catches up (after
+	which, ENTER appears instantaneous again).
+
+Fri Jun  4 19:21:19 1999  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* extend.py: Might as well enable CallTips by default.
+	If there are too many complaints I'll remove it again or fix it.
+
+Thu Jun  3 14:32:16 1999  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* AutoIndent.py, EditorWindow.py, PyParse.py:
+	New offerings by Tim Peters; he writes:
+
+	IDLE is now the first Python editor in the Universe not confused by my
+	doctest.py <wink>.
+
+	As threatened, this defines IDLE's is_char_in_string function as a
+	method of EditorWindow.  You just need to define one similarly in
+	whatever it is you pass as editwin to AutoIndent; looking at the
+	EditorWindow.py part of the patch should make this clear.
+
+	* GrepDialog.py: Enclose pattern in quotes in status message.
+
+	* CallTips.py:
+	Mark Hammond fixed some comments and improved the way the tip text is
+	constructed.
+
+Wed Jun  2 18:18:57 1999  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* CallTips.py:
+	My fix to Mark's code: restore the universal check on <KeyRelease>.
+	Always cancel on <Key-Escape> or <ButtonPress>.
+
+	* CallTips.py:
+	A version that Mark Hammond posted to the newsgroup.  Has some newer
+	stuff for getting the tip.  Had to fix the Key-( and Key-) events
+	for Unix.  Will have to re-apply my patch for catching KeyRelease and
+	ButtonRelease events.
+
+	* CallTipWindow.py, CallTips.py:
+	Call tips by Mark Hammond (plus tiny fix by me.)
+
+	* IdleHistory.py:
+	Changes by Mark Hammond: (1) support optional output_sep argument to
+	the constructor so he can eliminate the sys.ps2 that PythonWin leaves
+	in the source; (2) remove duplicate history items.
+
+	* AutoIndent.py:
+	Changes by Mark Hammond to allow using IDLE extensions in PythonWin as
+	well: make three dialog routines instance variables.
+
+	* EditorWindow.py:
+	Change by Mark Hammond to allow using IDLE extensions in PythonWin as
+	well: make three dialog routines instance variables.
+
+Tue Jun  1 20:06:44 1999  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* AutoIndent.py: Hah!  A fix of my own to Tim's code!
+	Unix bindings for <<toggle-tabs>> and <<change-indentwidth>> were
+	missing, and somehow that meant the events were never generated,
+	even though they were in the menu.  The new Unix bindings are now
+	the same as the Windows bindings (M-t and M-u).
+
+	* AutoIndent.py, PyParse.py, PyShell.py: Tim Peters again:
+
+	The new version (attached) is fast enough all the time in every real module
+	I have <whew!>.  You can make it slow by, e.g., creating an open list with
+	5,000 90-character identifiers (+ trailing comma) each on its own line, then
+	adding an item to the end -- but that still consumes less than a second on
+	my P5-166.  Response time in real code appears instantaneous.
+
+	Fixed some bugs.
+
+	New feature:  when hitting ENTER and the cursor is beyond the line's leading
+	indentation, whitespace is removed on both sides of the cursor; before
+	whitespace was removed only on the left; e.g., assuming the cursor is
+	between the comma and the space:
+
+	def something(arg1, arg2):
+	                   ^ cursor to the left of here, and hit ENTER
+	               arg2):   # new line used to end up here
+	              arg2):    # but now lines up the way you expect
+
+	New hack:  AutoIndent has grown a context_use_ps1 Boolean config option,
+	defaulting to 0 (false) and set to 1 (only) by PyShell.  Reason:  handling
+	the fancy stuff requires looking backward for a parsing synch point; ps1
+	lines are the only sensible thing to look for in a shell window, but are a
+	bad thing to look for in a file window (ps1 lines show up in my module
+	docstrings often).  PythonWin's shell should set this true too.
+
+	Persistent problem:  strings containing def/class can still screw things up
+	completely.  No improvement.  Simplest workaround is on the user's head, and
+	consists of inserting e.g.
+
+	def _(): pass
+
+	(or any other def/class) after the end of the multiline string that's
+	screwing them up.  This is especially irksome because IDLE's syntax coloring
+	is *not* confused, so when this happens the colors don't match the
+	indentation behavior they see.
+
+	* AutoIndent.py: Tim Peters again:
+
+	[Tim, after adding some bracket smarts to AutoIndent.py]
+	> ...
+	> What it can't possibly do without reparsing large gobs of text is
+	> suggest a reasonable indent level after you've *closed* a bracket
+	> left open on some previous line.
+	> ...
+
+	The attached can, and actually fast enough to use -- most of the time.  The
+	code is tricky beyond belief to achieve that, but it works so far; e.g.,
+
+	        return len(string.expandtabs(str[self.stmt_start :
+	                                         ^ indents to caret
+	                                         i],
+	                                     ^ indents to caret
+	                                     self.tabwidth)) + 1
+	    ^ indents to caret
+
+	It's about as smart as pymode now, wrt both bracket and backslash
+	continuation rules.  It does require reparsing large gobs of text, and if it
+	happens to find something that looks like a "def" or "class" or sys.ps1
+	buried in a multiline string, but didn't suck up enough preceding text to
+	see the start of the string, it's completely hosed.  I can't repair that --
+	it's just too slow to reparse from the start of the file all the time.
+
+	AutoIndent has grown a new num_context_lines tuple attribute that controls
+	how far to look back, and-- like other params --this could/should be made
+	user-overridable at startup and per-file on the fly.
+
+	* PyParse.py: New file by Tim Peters:
+
+	One new file in the attached, PyParse.py.  The LineStudier (whatever it was
+	called <wink>) class was removed from AutoIndent; PyParse subsumes its
+	functionality.
+
+	* AutoIndent.py: Tim Peters keeps revising this module (more to come):
+
+	Removed "New tabwidth" menu binding.
+
+	Added "a tab means how many spaces?" dialog to block tabify and untabify.  I
+	think prompting for this is good now:  they're usually at-most-once-per-file
+	commands, and IDLE can't let them change tabwidth from the Tk default
+	anymore, so IDLE can no longer presume to have any idea what a tab means.
+
+	Irony:  for the purpose of keeping comments aligned via tabs, Tk's
+	non-default approach is much nicer than the Emacs/Notepad/Codewright/vi/etc
+	approach.
+
+	* EditorWindow.py:
+	1. Catch NameError on import (could be raised by case mismatch on Windows).
+	2. No longer need to reset pyclbr cache and show watch cursor when calling
+	   ClassBrowser -- the ClassBrowser takes care of pyclbr and the TreeWidget
+	   takes care of the watch cursor.
+	3. Reset the focus to the current window after error message about class
+	   browser on buffer without filename.
+
+	* Icons/minusnode.gif, Icons/plusnode.gif: Missed a few.
+
+	* ClassBrowser.py, PathBrowser.py: Rewritten based on TreeWidget.py
+
+	* ObjectBrowser.py: Object browser, based on TreeWidget.py.
+
+	* TreeWidget.py: Tree widget done right.
+
+	* ToolTip.py: As yet unused code for tool tips.
+
+	* ScriptBinding.py:
+	Ensure sys.argv[0] is the script name on Run Script.
+
+	* ZoomHeight.py: Move zoom height functionality to separate function.
+
+	* Icons/folder.gif, Icons/openfolder.gif, Icons/python.gif, Icons/tk.gif:
+	A few icons used by ../TreeWidget.py and its callers.
+
+	* AutoIndent.py: New version by Tim Peters improves block opening test.
+
+Fri May 21 04:46:17 1999  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* Attic/History.py, PyShell.py: Rename History to IdleHistory.
+	Add isatty() to pseudo files.
+
+	* StackViewer.py: Make initial stack viewer wider
+
+	* TODO.txt: New wishes
+
+	* AutoIndent.py, EditorWindow.py, PyShell.py:
+	Much improved autoindent and handling of tabs,
+	by Tim Peters.
+
+Mon May  3 15:49:52 1999  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* AutoIndent.py, EditorWindow.py, FormatParagraph.py, UndoDelegator.py:
+	Tim Peters writes:
+
+	I'm still unsure, but couldn't stand the virtual event trickery so tried a
+	different sin (adding undo_block_start/stop methods to the Text instance in
+	EditorWindow.py).  Like it or not, it's efficient and works <wink>.  Better
+	idea?
+
+	Give the attached a whirl.  Even if you hate the implementation, I think
+	you'll like the results.  Think I caught all the "block edit" cmds,
+	including Format Paragraph, plus subtler ones involving smart indents and
+	backspacing.
+
+	* WidgetRedirector.py: Tim Peters writes:
+
+	[W]hile trying to dope out how redirection works, stumbled into two
+	possible glitches.  In the first, it doesn't appear to make sense to try to
+	rename a command that's already been destroyed; in the second, the name
+	"previous" doesn't really bring to mind "ignore the previous value" <wink>.
+
+Fri Apr 30 19:39:25 1999  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* __init__.py: Support for using idle as a package.
+
+	* PathBrowser.py:
+	Avoid listing files more than once (e.g. foomodule.so has two hits:
+	once for foo + module.so, once for foomodule + .so).
+
+Mon Apr 26 22:20:38 1999  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* ChangeLog, ColorDelegator.py, PyShell.py: Tim Peters strikes again:
+
+	Ho ho ho -- that's trickier than it sounded!  The colorizer is working with
+	"line.col" strings instead of Text marks, and the absolute coordinates of
+	the point of interest can change across the self.update call (voice of
+	baffled experience, when two quick backspaces no longer fooled it, but a
+	backspace followed by a quick ENTER did <wink>).
+
+	Anyway, the attached appears to do the trick.  CPU usage goes way up when
+	typing quickly into a long triple-quoted string, but the latency is fine for
+	me (a relatively fast typist on a relatively slow machine).  Most of the
+	changes here are left over from reducing the # of vrbl names to help me
+	reason about the logic better; I hope the code is a *little* easier to
+
+Fri Apr 23 14:01:25 1999  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* EditorWindow.py:
+	Provide full arguments to __import__ so it works in packagized IDLE.
+
+Thu Apr 22 23:20:17 1999  Guido van Rossum  <guido at cnri.reston.va.us>
+
+        * help.txt:
+        Bunch of updates necessary due to recent changes; added docs for File
+        menu, command line and color preferences.
+
+        * Bindings.py: Remove obsolete 'script' menu.
+
+	* TODO.txt: Several wishes fulfilled.
+
+	* OutputWindow.py:
+	Moved classes OnDemandOutputWindow and PseudoFile here,
+	from ScriptBinding.py where they are no longer needed.
+
+	* ScriptBinding.py:
+	Mostly rewritten.  Instead of the old Run module and Debug module,
+	there are two new commands:
+
+	Import module (F5) imports or reloads the module and also adds its
+	name to the __main__ namespace.  This gets executed in the PyShell
+	window under control of its debug settings.
+
+	Run script (Control-F5) is similar but executes the contents of the
+	file directly in the __main__ namespace.
+
+	* PyShell.py: Nits: document use of $IDLESTARTUP; display idle version
+
+	* idlever.py: New version to celebrate new command line
+
+	* OutputWindow.py: Added flush(), for completeness.
+
+	* PyShell.py:
+	A lot of changes to make the command line more useful.  You can now do:
+	  idle.py -e file ...    -- to edit files
+	  idle.py script arg ... -- to run a script
+	  idle.py -c cmd arg ... -- to run a command
+	Other options, see also the usage message (also new!) for more details:
+	  -d       -- enable debugger
+	  -s       -- run $IDLESTARTUP or $PYTHONSTARTUP
+	  -t title -- set Python Shell window's title
+	sys.argv is set accordingly, unless -e is used.
+	sys.path is absolutized, and all relevant paths are inserted into it.
+
+	Other changes:
+	- the environment in which commands are executed is now the
+	  __main__ module
+	- explicitly save sys.stdout etc., don't restore from sys.__stdout__
+	- new interpreter methods execsource(), execfile(), stuffsource()
+	- a few small nits
+
+	* TODO.txt:
+	Some more TODO items.  Made up my mind about command line args,
+	Run/Import, __main__.
+
+	* ColorDelegator.py:
+	Super-elegant patch by Tim Peters that speeds up colorization
+	dramatically (up to 15 times he claims).  Works by reading more than
+	one line at a time, up to 100-line chunks (starting with one line and
+	then doubling up to the limit).  On a typical machine (e.g. Tim's
+	P5-166) this doesn't reduce interactive responsiveness in a noticeable
+	way.
+
+Wed Apr 21 15:49:34 1999  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* ColorDelegator.py:
+	Patch by Tim Peters to speed up colorizing of big multiline strings.
+
+Tue Apr 20 17:32:52 1999  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* extend.txt:
+	For an event 'foo-bar', the corresponding method must be called
+	foo_bar_event().  Therefore, fix the references to zoom_height() in
+	the example.
+
+	* IdlePrefs.py: Restored the original IDLE color scheme.
+
+	* PyShell.py, IdlePrefs.py, ColorDelegator.py, EditorWindow.py:
+	Color preferences code by Loren Luke (massaged by me somewhat)
+
+	* SearchEngine.py:
+	Patch by Mark Favas: it fixes the search engine behaviour where an
+	unsuccessful search wraps around and re-searches that part of the file
+	between the start of the search and the end of the file - only really
+	an issue for very large files, but... (also removes a redundant
+	m.span() call).
+
+Mon Apr 19 16:26:02 1999  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* TODO.txt: A few wishes are now fulfilled.
+
+	* AutoIndent.py: Tim Peters implements some of my wishes:
+
+	o Makes the tab key intelligently insert spaces when appropriate
+	(see Help list banter twixt David Ascher and me; idea stolen from
+	every other editor on earth <wink>).
+
+	o newline_and_indent_event trims trailing whitespace on the old
+	line (pymode and Codewright).
+
+	o newline_and_indent_event no longer fooled by trailing whitespace or
+	comment after ":" (pymode, PTUI).
+
+	o newline_and_indent_event now reduces the new line's indentation after
+	return, break, continue, raise and pass stmts (pymode).
+
+	The last two are easy to fool in the presence of strings &
+	continuations, but pymode requires Emacs's high-powered C parsing
+	functions to avoid that in finite time.
+
+======================================================================
+	Python release 1.5.2c1, IDLE version 0.4
+======================================================================
+
+Wed Apr  7 18:41:59 1999  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* README.txt, NEWS.txt: New version.
+
+	* idlever.py: Version bump awaiting impending new release.
+	(Not much has changed :-( )
+
+Mon Mar 29 14:52:28 1999  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* ScriptBinding.py, PyShell.py:
+	At Tim Peters' recommendation, add a dummy flush() method to
+	PseudoFile.
+
+Thu Mar 11 23:21:23 1999  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* PathBrowser.py: Don't crash when sys.path contains an empty string.
+
+	* Attic/Outline.py: This file was never supposed to be part of IDLE.
+
+	* PathBrowser.py:
+	- Don't crash in the case where a superclass is a string instead of a
+	pyclbr.Class object; this can happen when the superclass is
+	unrecognizable (to pyclbr), e.g. when module renaming is used.
+
+	- Show a watch cursor when calling pyclbr (since it may take a while
+	recursively parsing imported modules!).
+
+Wed Mar 10 05:18:02 1999  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* EditorWindow.py, Bindings.py: Add PathBrowser to File module
+
+	* PathBrowser.py: "Path browser" - 4 scrolled lists displaying:
+	    directories on sys.path
+	    modules in selected directory
+	    classes in selected module
+	    methods of selected class
+
+	Sinlge clicking in a directory, module or class item updates the next
+	column with info about the selected item.  Double clicking in a
+	module, class or method item opens the file (and selects the clicked
+	item if it is a class or method).
+
+	I guess eventually I should be using a tree widget for this, but the
+	ones I've seen don't work well enough, so for now I use the old
+	Smalltalk or NeXT style multi-column hierarchical browser.
+
+	* MultiScrolledLists.py:
+	New utility: multiple scrolled lists in parallel
+
+	* ScrolledList.py: - White background.
+	- Display "(None)" (or text of your choosing) when empty.
+	- Don't set the focus.
+
+======================================================================
+	Python release 1.5.2b2, IDLE version 0.3
+======================================================================
+	
+Wed Feb 17 22:47:41 1999  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* NEWS.txt: News in 0.3.
+
+	* README.txt, idlever.py: Bump version to 0.3.
+
+	* EditorWindow.py:
+	After all, we don't need to call the callbacks ourselves!
+
+	* WindowList.py:
+	When deleting, call the callbacks *after* deleting the window from our list!
+
+	* EditorWindow.py:
+	Fix up the Windows menu via the new callback mechanism instead of
+	depending on menu post commands (which don't work when the menu is
+	torn off).
+
+	* WindowList.py:
+	Support callbacks to patch up Windows menus everywhere.
+
+	* ChangeLog: Oh, why not.  Checking in the Emacs-generated change log.
+
+Tue Feb 16 22:34:17 1999  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* ScriptBinding.py:
+	Only pop up the stack viewer when requested in the Debug menu.
+
+Mon Feb  8 22:27:49 1999  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* WindowList.py: Don't crash if a window no longer exists.
+
+	* TODO.txt: Restructured a bit.
+
+Mon Feb  1 23:06:17 1999  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* PyShell.py: Add current dir or paths of file args to sys.path.
+
+	* Debugger.py: Add canonic() function -- for brand new bdb.py feature.
+
+	* StackViewer.py: Protect against accessing an empty stack.
+
+Fri Jan 29 20:44:45 1999  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* ZoomHeight.py:
+	Use only the height to decide whether to zoom in or out.
+
+Thu Jan 28 22:24:30 1999  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* EditorWindow.py, FileList.py:
+	Make sure the Tcl variables are shared between windows.
+
+	* PyShell.py, EditorWindow.py, Bindings.py:
+	Move menu/key binding code from Bindings.py to EditorWindow.py,
+	with changed APIs -- it makes much more sense there.
+	Also add a new feature: if the first character of a menu label is
+	a '!', it gets a checkbox.  Checkboxes are bound to Boolean Tcl variables
+	that can be accessed through the new getvar/setvar/getrawvar API;
+	the variable is named after the event to which the menu is bound.
+
+	* Debugger.py: Add Quit button to the debugger window.
+
+	* SearchDialog.py:
+	When find_again() finds exactly the current selection, it's a failure.
+
+	* idle.py, Attic/idle: Rename idle -> idle.py
+
+Mon Jan 18 15:18:57 1999  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* EditorWindow.py, WindowList.py: Only deiconify when iconic.
+
+	* TODO.txt: Misc
+
+Tue Jan 12 22:14:34 1999  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* testcode.py, Attic/test.py:
+	Renamed test.py to testcode.py so one can import Python's
+	test package from inside IDLE.  (Suggested by Jack Jansen.)
+
+	* EditorWindow.py, ColorDelegator.py:
+	Hack to close a window that is colorizing.
+
+	* Separator.py: Vladimir Marangozov's patch:
+	The separator dances too much and seems to jump by arbitrary amounts
+	in arbitrary directions when I try to move it for resizing the frames.
+	This patch makes it more quiet.
+
+Mon Jan 11 14:52:40 1999  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* TODO.txt: Some requests have been fulfilled.
+
+	* EditorWindow.py:
+	Set the cursor to a watch when opening the class browser (which may
+	take quite a while, browsing multiple files).
+
+	Newer, better center() -- but assumes no wrapping.
+
+	* SearchBinding.py:
+	Got rid of debug print statement in goto_line_event().
+
+	* ScriptBinding.py:
+	I think I like it better if it prints the traceback even when it displays
+	the stack viewer.
+
+	* Debugger.py: Bind ESC to close-window.
+
+	* ClassBrowser.py: Use a HSeparator between the classes and the items.
+	Make the list of classes wider by default (40 chars).
+	Bind ESC to close-window.
+
+	* Separator.py:
+	Separator classes (draggable divider between two panes).
+
+Sat Jan  9 22:01:33 1999  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* WindowList.py:
+	Don't traceback when wakeup() is called when the window has been destroyed.
+	This can happen when a torn-of Windows menu references closed windows.
+	And Tim Peters claims that the Windows menu is his favorite to tear off...
+
+	* EditorWindow.py: Allow tearing off of the Windows menu.
+
+	* StackViewer.py: Close on ESC.
+
+	* help.txt: Updated a bunch of things (it was mostly still 0.1!)
+
+	* extend.py: Added ScriptBinding to standard bindings.
+
+	* ScriptBinding.py:
+	This now actually works.  See doc string.  It can run a module (i.e.
+	import or reload) or debug it (same with debugger control).  Output
+	goes to a fresh output window, only created when needed.
+
+======================================================================
+	Python release 1.5.2b1, IDLE version 0.2
+======================================================================
+	
+Fri Jan  8 17:26:02 1999  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* README.txt, NEWS.txt: What's new in this release.
+
+	* Bindings.py, PyShell.py:
+	Paul Prescod's patches to allow the stack viewer to pop up when a
+	traceback is printed.
+
+Thu Jan  7 00:12:15 1999  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* FormatParagraph.py:
+	Change paragraph width limit to 70 (like Emacs M-Q).
+
+	* README.txt:
+	Separating TODO from README.  Slight reformulation of features.  No
+	exact release date.
+
+	* TODO.txt: Separating TODO from README.
+
+Mon Jan  4 21:19:09 1999  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* FormatParagraph.py:
+	Hm.  There was a boundary condition error at the end of the file too.
+
+	* SearchBinding.py: Hm.  Add Unix binding for replace, too.
+
+	* keydefs.py: Ran eventparse.py again.
+
+	* FormatParagraph.py: Added Unix Meta-q key binding;
+	fix find_paragraph when at start of file.
+
+	* AutoExpand.py: Added Meta-/ binding for Unix as alt for Alt-/.
+
+	* SearchBinding.py:
+	Add unix binding for grep (otherwise the menu entry doesn't work!)
+
+	* ZoomHeight.py: Adjusted Unix height to work with fvwm96. :=(
+
+	* GrepDialog.py: Need to import sys!
+
+	* help.txt, extend.txt, README.txt: Formatted some paragraphs
+
+	* extend.py, FormatParagraph.py:
+	Add new extension to reformat a (text) paragraph.
+
+	* ZoomHeight.py: Typo in Win specific height setting.
+
+Sun Jan  3 00:47:35 1999  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* AutoIndent.py: Added something like Tim Peters' backspace patch.
+
+	* ZoomHeight.py: Adapted to Unix (i.e., more hardcoded constants).
+
+Sat Jan  2 21:28:54 1999  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* keydefs.py, idlever.py, idle.pyw, idle.bat, help.txt, extend.txt, extend.py, eventparse.py, ZoomHeight.py, WindowList.py, UndoDelegator.py, StackViewer.py, SearchEngine.py, SearchDialogBase.py, SearchDialog.py, ScrolledList.py, SearchBinding.py, ScriptBinding.py, ReplaceDialog.py, Attic/README, README.txt, PyShell.py, Attic/PopupMenu.py, OutputWindow.py, IOBinding.py, Attic/HelpWindow.py, History.py, GrepDialog.py, FileList.py, FrameViewer.py, EditorWindow.py, Debugger.py, Delegator.py, ColorDelegator.py, Bindings.py, ClassBrowser.py, AutoExpand.py, AutoIndent.py:
+	Checking in IDLE 0.2.
+
+	Much has changed -- too much, in fact, to write down.
+	The big news is that there's a standard way to write IDLE extensions;
+	see extend.txt.  Some sample extensions have been provided, and
+	some existing code has been converted to extensions.  Probably the
+	biggest new user feature is a new search dialog with more options,
+	search and replace, and even search in files (grep).
+
+	This is exactly as downloaded from my laptop after returning
+	from the holidays -- it hasn't even been tested on Unix yet.
+
+Fri Dec 18 15:52:54 1998  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* FileList.py, ClassBrowser.py:
+	Fix the class browser to work even when the file is not on sys.path.
+
+Tue Dec  8 20:39:36 1998  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* Attic/turtle.py: Moved to Python 1.5.2/Lib
+
+Fri Nov 27 03:19:20 1998  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* help.txt: Typo
+
+	* EditorWindow.py, FileList.py: Support underlining of menu labels
+
+	* Bindings.py:
+	New approach, separate tables for menus (platform-independent) and key
+	definitions (platform-specific), and generating accelerator strings
+	automatically from the key definitions.
+
+Mon Nov 16 18:37:42 1998  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* Attic/README: Clarify portability and main program.
+
+	* Attic/README: Added intro for 0.1 release and append Grail notes.
+
+Mon Oct 26 18:49:00 1998  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* Attic/turtle.py: root is now a global called _root
+
+Sat Oct 24 16:38:38 1998  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* Attic/turtle.py: Raise the root window on reset().
+	Different action on WM_DELETE_WINDOW is more likely to do the right thing,
+	allowing us to destroy old windows.
+
+	* Attic/turtle.py:
+	Split the goto() function in two: _goto() is the internal one,
+	using Canvas coordinates, and goto() uses turtle coordinates
+	and accepts variable argument lists.
+
+	* Attic/turtle.py: Cope with destruction of the window
+
+	* Attic/turtle.py: Turtle graphics
+
+	* Debugger.py: Use of Breakpoint class should be bdb.Breakpoint.
+
+Mon Oct 19 03:33:40 1998  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* SearchBinding.py:
+	Speed up the search a bit -- don't drag a mark around...
+
+	* PyShell.py:
+	Change our special entries from <console#N> to <pyshell#N>.
+	Patch linecache.checkcache() to keep our special entries alive.
+	Add popup menu to all editor windows to set a breakpoint.
+
+	* Debugger.py:
+	Use and pass through the 'force' flag to set_dict() where appropriate.
+	Default source and globals checkboxes to false.
+	Don't interact in user_return().
+	Add primitive set_breakpoint() method.
+
+	* ColorDelegator.py:
+	Raise priority of 'sel' tag so its foreground (on Windows) will take
+	priority over text colorization (which on Windows is almost the
+	same color as the selection background).
+
+	Define a tag and color for breakpoints ("BREAK").
+
+	* Attic/PopupMenu.py: Disable "Open stack viewer" and "help" commands.
+
+	* StackViewer.py:
+	Add optional 'force' argument (default 0) to load_dict().
+	If set, redo the display even if it's the same dict.
+
+Fri Oct 16 21:10:12 1998  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* StackViewer.py: Do nothing when loading the same dict as before.
+
+	* PyShell.py: Details for debugger interface.
+
+	* Debugger.py:
+	Restructured and more consistent.  Save checkboxes across instantiations.
+
+	* EditorWindow.py, Attic/README, Bindings.py:
+	Get rid of conflicting ^X binding.  Use ^W.
+
+	* Debugger.py, StackViewer.py:
+	Debugger can now show local and global variables.
+
+	* Debugger.py: Oops
+
+	* Debugger.py, PyShell.py: Better debugger support (show stack etc).
+
+	* Attic/PopupMenu.py: Follow renames in StackViewer module
+
+	* StackViewer.py:
+	Rename classes to StackViewer (the widget) and StackBrowser (the toplevel).
+
+	* ScrolledList.py: Add close() method
+
+	* EditorWindow.py: Clarify 'Open Module' dialog text
+
+	* StackViewer.py: Restructured into a browser and a widget.
+
+Thu Oct 15 23:27:08 1998  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* ClassBrowser.py, ScrolledList.py:
+	Generalized the scrolled list which is the base for the class and
+	method browser into a separate class in its own module.
+
+	* Attic/test.py: Cosmetic change
+
+	* Debugger.py: Don't show function name if there is none
+
+Wed Oct 14 03:43:05 1998  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* Debugger.py, PyShell.py: Polish the Debugger GUI a bit.
+	Closing it now also does the right thing.
+
+Tue Oct 13 23:51:13 1998  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* Debugger.py, PyShell.py, Bindings.py:
+	Ad primitive debugger interface (so far it will step and show you the
+	source, but it doesn't yet show the stack).
+
+	* Attic/README: Misc
+
+	* StackViewer.py: Whoops -- referenced self.top before it was set.
+
+	* help.txt: Added history and completion commands.
+
+	* help.txt: Updated
+
+	* FileList.py: Add class browser functionality.
+
+	* StackViewer.py:
+	Add a close() method and bind to WM_DELETE_WINDOW protocol
+
+	* PyShell.py: Clear the linecache before printing a traceback
+
+	* Bindings.py: Added class browser binding.
+
+	* ClassBrowser.py: Much improved, much left to do.
+
+	* PyShell.py: Make the return key do what I mean more often.
+
+	* ClassBrowser.py:
+	Adding the beginnings of a Class browser.  Incomplete, yet.
+
+	* EditorWindow.py, Bindings.py:
+	Add new command, "Open module".  You select or type a module name,
+	and it opens the source.
+
+Mon Oct 12 23:59:27 1998  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* PyShell.py: Subsume functionality from Popup menu in Debug menu.
+	Other stuff so the PyShell window can be resurrected from the Windows menu.
+
+	* FileList.py: Get rid of PopUp menu.
+	Create a simple Windows menu.  (Imperfect when Untitled windows exist.)
+	Add wakeup() method: deiconify, raise, focus.
+
+	* EditorWindow.py: Generalize menu creation.
+
+	* Bindings.py: Add Debug and Help menu items.
+
+	* EditorWindow.py: Added a menu bar to every window.
+
+	* Bindings.py: Add menu configuration to the event configuration.
+
+	* Attic/PopupMenu.py: Pass a root to the help window.
+
+	* SearchBinding.py:
+	Add parent argument to 'to to line number' dialog box.
+
+Sat Oct 10 19:15:32 1998  Guido van Rossum  <guido at cnri.reston.va.us>
+
+	* StackViewer.py:
+	Add a label at the top showing (very basic) help for the stack viewer.
+	Add a label at the bottom showing the exception info.
+
+	* Attic/test.py, Attic/idle: Add Unix main script and test program.
+
+	* idle.pyw, help.txt, WidgetRedirector.py, UndoDelegator.py, StackViewer.py, SearchBinding.py, Attic/README, PyShell.py, Attic/PopupMenu.py, Percolator.py, Outline.py, IOBinding.py, History.py, Attic/HelpWindow.py, FrameViewer.py, FileList.py, EditorWindow.py, Delegator.py, ColorDelegator.py, Bindings.py, AutoIndent.py, AutoExpand.py:
+	Initial checking of Tk-based Python IDE.
+	Features: text editor with syntax coloring and undo;
+	subclassed into interactive Python shell which adds history.
+

Added: vendor/Python/current/Lib/idlelib/ClassBrowser.py
===================================================================
--- vendor/Python/current/Lib/idlelib/ClassBrowser.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/ClassBrowser.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,221 @@
+"""Class browser.
+
+XXX TO DO:
+
+- reparse when source changed (maybe just a button would be OK?)
+    (or recheck on window popup)
+- add popup menu with more options (e.g. doc strings, base classes, imports)
+- show function argument list? (have to do pattern matching on source)
+- should the classes and methods lists also be in the module's menu bar?
+- add base classes to class browser tree
+"""
+
+import os
+import sys
+import pyclbr
+
+import PyShell
+from WindowList import ListedToplevel
+from TreeWidget import TreeNode, TreeItem, ScrolledCanvas
+from configHandler import idleConf
+
+class ClassBrowser:
+
+    def __init__(self, flist, name, path):
+        # XXX This API should change, if the file doesn't end in ".py"
+        # XXX the code here is bogus!
+        self.name = name
+        self.file = os.path.join(path[0], self.name + ".py")
+        self.init(flist)
+
+    def close(self, event=None):
+        self.top.destroy()
+        self.node.destroy()
+
+    def init(self, flist):
+        self.flist = flist
+        # reset pyclbr
+        pyclbr._modules.clear()
+        # create top
+        self.top = top = ListedToplevel(flist.root)
+        top.protocol("WM_DELETE_WINDOW", self.close)
+        top.bind("<Escape>", self.close)
+        self.settitle()
+        top.focus_set()
+        # create scrolled canvas
+        theme = idleConf.GetOption('main','Theme','name')
+        background = idleConf.GetHighlight(theme, 'normal')['background']
+        sc = ScrolledCanvas(top, bg=background, highlightthickness=0, takefocus=1)
+        sc.frame.pack(expand=1, fill="both")
+        item = self.rootnode()
+        self.node = node = TreeNode(sc.canvas, None, item)
+        node.update()
+        node.expand()
+
+    def settitle(self):
+        self.top.wm_title("Class Browser - " + self.name)
+        self.top.wm_iconname("Class Browser")
+
+    def rootnode(self):
+        return ModuleBrowserTreeItem(self.file)
+
+class ModuleBrowserTreeItem(TreeItem):
+
+    def __init__(self, file):
+        self.file = file
+
+    def GetText(self):
+        return os.path.basename(self.file)
+
+    def GetIconName(self):
+        return "python"
+
+    def GetSubList(self):
+        sublist = []
+        for name in self.listclasses():
+            item = ClassBrowserTreeItem(name, self.classes, self.file)
+            sublist.append(item)
+        return sublist
+
+    def OnDoubleClick(self):
+        if os.path.normcase(self.file[-3:]) != ".py":
+            return
+        if not os.path.exists(self.file):
+            return
+        PyShell.flist.open(self.file)
+
+    def IsExpandable(self):
+        return os.path.normcase(self.file[-3:]) == ".py"
+
+    def listclasses(self):
+        dir, file = os.path.split(self.file)
+        name, ext = os.path.splitext(file)
+        if os.path.normcase(ext) != ".py":
+            return []
+        try:
+            dict = pyclbr.readmodule_ex(name, [dir] + sys.path)
+        except ImportError, msg:
+            return []
+        items = []
+        self.classes = {}
+        for key, cl in dict.items():
+            if cl.module == name:
+                s = key
+                if hasattr(cl, 'super') and cl.super:
+                    supers = []
+                    for sup in cl.super:
+                        if type(sup) is type(''):
+                            sname = sup
+                        else:
+                            sname = sup.name
+                            if sup.module != cl.module:
+                                sname = "%s.%s" % (sup.module, sname)
+                        supers.append(sname)
+                    s = s + "(%s)" % ", ".join(supers)
+                items.append((cl.lineno, s))
+                self.classes[s] = cl
+        items.sort()
+        list = []
+        for item, s in items:
+            list.append(s)
+        return list
+
+class ClassBrowserTreeItem(TreeItem):
+
+    def __init__(self, name, classes, file):
+        self.name = name
+        self.classes = classes
+        self.file = file
+        try:
+            self.cl = self.classes[self.name]
+        except (IndexError, KeyError):
+            self.cl = None
+        self.isfunction = isinstance(self.cl, pyclbr.Function)
+
+    def GetText(self):
+        if self.isfunction:
+            return "def " + self.name + "(...)"
+        else:
+            return "class " + self.name
+
+    def GetIconName(self):
+        if self.isfunction:
+            return "python"
+        else:
+            return "folder"
+
+    def IsExpandable(self):
+        if self.cl:
+            try:
+                return not not self.cl.methods
+            except AttributeError:
+                return False
+
+    def GetSubList(self):
+        if not self.cl:
+            return []
+        sublist = []
+        for name in self.listmethods():
+            item = MethodBrowserTreeItem(name, self.cl, self.file)
+            sublist.append(item)
+        return sublist
+
+    def OnDoubleClick(self):
+        if not os.path.exists(self.file):
+            return
+        edit = PyShell.flist.open(self.file)
+        if hasattr(self.cl, 'lineno'):
+            lineno = self.cl.lineno
+            edit.gotoline(lineno)
+
+    def listmethods(self):
+        if not self.cl:
+            return []
+        items = []
+        for name, lineno in self.cl.methods.items():
+            items.append((lineno, name))
+        items.sort()
+        list = []
+        for item, name in items:
+            list.append(name)
+        return list
+
+class MethodBrowserTreeItem(TreeItem):
+
+    def __init__(self, name, cl, file):
+        self.name = name
+        self.cl = cl
+        self.file = file
+
+    def GetText(self):
+        return "def " + self.name + "(...)"
+
+    def GetIconName(self):
+        return "python" # XXX
+
+    def IsExpandable(self):
+        return 0
+
+    def OnDoubleClick(self):
+        if not os.path.exists(self.file):
+            return
+        edit = PyShell.flist.open(self.file)
+        edit.gotoline(self.cl.methods[self.name])
+
+def main():
+    try:
+        file = __file__
+    except NameError:
+        file = sys.argv[0]
+        if sys.argv[1:]:
+            file = sys.argv[1]
+        else:
+            file = sys.argv[0]
+    dir, file = os.path.split(file)
+    name = os.path.splitext(file)[0]
+    ClassBrowser(PyShell.flist, name, [dir])
+    if sys.stdin is sys.__stdin__:
+        mainloop()
+
+if __name__ == "__main__":
+    main()

Added: vendor/Python/current/Lib/idlelib/CodeContext.py
===================================================================
--- vendor/Python/current/Lib/idlelib/CodeContext.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/CodeContext.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,167 @@
+"""CodeContext - Extension to display the block context above the edit window
+
+Once code has scrolled off the top of a window, it can be difficult to
+determine which block you are in.  This extension implements a pane at the top
+of each IDLE edit window which provides block structure hints.  These hints are
+the lines which contain the block opening keywords, e.g. 'if', for the
+enclosing block.  The number of hint lines is determined by the numlines
+variable in the CodeContext section of config-extensions.def. Lines which do
+not open blocks are not shown in the context hints pane.
+
+"""
+import Tkinter
+from configHandler import idleConf
+import re
+from sys import maxint as INFINITY
+
+BLOCKOPENERS = set(["class", "def", "elif", "else", "except", "finally", "for",
+                    "if", "try", "while", "with"])
+UPDATEINTERVAL = 100 # millisec
+FONTUPDATEINTERVAL = 1000 # millisec
+
+getspacesfirstword =\
+                   lambda s, c=re.compile(r"^(\s*)(\w*)"): c.match(s).groups()
+
+class CodeContext:
+    menudefs = [('options', [('!Code Conte_xt', '<<toggle-code-context>>')])]
+
+    context_depth = idleConf.GetOption("extensions", "CodeContext",
+                                       "numlines", type="int", default=3)
+    bgcolor = idleConf.GetOption("extensions", "CodeContext",
+                                 "bgcolor", type="str", default="LightGray")
+    fgcolor = idleConf.GetOption("extensions", "CodeContext",
+                                 "fgcolor", type="str", default="Black")
+    def __init__(self, editwin):
+        self.editwin = editwin
+        self.text = editwin.text
+        self.textfont = self.text["font"]
+        self.label = None
+        # self.info is a list of (line number, indent level, line text, block
+        # keyword) tuples providing the block structure associated with
+        # self.topvisible (the linenumber of the line displayed at the top of
+        # the edit window). self.info[0] is initialized as a 'dummy' line which
+        # starts the toplevel 'block' of the module.
+        self.info = [(0, -1, "", False)]
+        self.topvisible = 1
+        visible = idleConf.GetOption("extensions", "CodeContext",
+                                     "visible", type="bool", default=False)
+        if visible:
+            self.toggle_code_context_event()
+            self.editwin.setvar('<<toggle-code-context>>', True)
+        # Start two update cycles, one for context lines, one for font changes.
+        self.text.after(UPDATEINTERVAL, self.timer_event)
+        self.text.after(FONTUPDATEINTERVAL, self.font_timer_event)
+
+    def toggle_code_context_event(self, event=None):
+        if not self.label:
+            self.pad_frame = Tkinter.Frame(self.editwin.top,
+                                           bg=self.bgcolor, border=2,
+                                           relief="sunken")
+            self.label = Tkinter.Label(self.pad_frame,
+                                      text="\n" * (self.context_depth - 1),
+                                      anchor="w", justify="left",
+                                      font=self.textfont,
+                                      bg=self.bgcolor, fg=self.fgcolor,
+                                      border=0,
+                                      width=1, # Don't request more than we get
+                                      )
+            self.label.pack(side="top", fill="x", expand=True,
+                            padx=4, pady=0)
+            self.pad_frame.pack(side="top", fill="x", expand=False,
+                                padx=0, pady=0,
+                                after=self.editwin.status_bar)
+        else:
+            self.label.destroy()
+            self.pad_frame.destroy()
+            self.label = None
+        idleConf.SetOption("extensions", "CodeContext", "visible",
+                           str(self.label is not None))
+        idleConf.SaveUserCfgFiles()
+
+    def get_line_info(self, linenum):
+        """Get the line indent value, text, and any block start keyword
+
+        If the line does not start a block, the keyword value is False.
+        The indentation of empty lines (or comment lines) is INFINITY.
+
+        """
+        text = self.text.get("%d.0" % linenum, "%d.end" % linenum)
+        spaces, firstword = getspacesfirstword(text)
+        opener = firstword in BLOCKOPENERS and firstword
+        if len(text) == len(spaces) or text[len(spaces)] == '#':
+            indent = INFINITY
+        else:
+            indent = len(spaces)
+        return indent, text, opener
+
+    def get_context(self, new_topvisible, stopline=1, stopindent=0):
+        """Get context lines, starting at new_topvisible and working backwards.
+
+        Stop when stopline or stopindent is reached. Return a tuple of context
+        data and the indent level at the top of the region inspected.
+
+        """
+        assert stopline > 0
+        lines = []
+        # The indentation level we are currently in:
+        lastindent = INFINITY
+        # For a line to be interesting, it must begin with a block opening
+        # keyword, and have less indentation than lastindent.
+        for linenum in xrange(new_topvisible, stopline-1, -1):
+            indent, text, opener = self.get_line_info(linenum)
+            if indent < lastindent:
+                lastindent = indent
+                if opener in ("else", "elif"):
+                    # We also show the if statement
+                    lastindent += 1
+                if opener and linenum < new_topvisible and indent >= stopindent:
+                    lines.append((linenum, indent, text, opener))
+                if lastindent <= stopindent:
+                    break
+        lines.reverse()
+        return lines, lastindent
+
+    def update_code_context(self):
+        """Update context information and lines visible in the context pane.
+
+        """
+        new_topvisible = int(self.text.index("@0,0").split('.')[0])
+        if self.topvisible == new_topvisible:      # haven't scrolled
+            return
+        if self.topvisible < new_topvisible:       # scroll down
+            lines, lastindent = self.get_context(new_topvisible,
+                                                 self.topvisible)
+            # retain only context info applicable to the region
+            # between topvisible and new_topvisible:
+            while self.info[-1][1] >= lastindent:
+                del self.info[-1]
+        elif self.topvisible > new_topvisible:     # scroll up
+            stopindent = self.info[-1][1] + 1
+            # retain only context info associated
+            # with lines above new_topvisible:
+            while self.info[-1][0] >= new_topvisible:
+                stopindent = self.info[-1][1]
+                del self.info[-1]
+            lines, lastindent = self.get_context(new_topvisible,
+                                                 self.info[-1][0]+1,
+                                                 stopindent)
+        self.info.extend(lines)
+        self.topvisible = new_topvisible
+
+        # empty lines in context pane:
+        context_strings = [""] * max(0, self.context_depth - len(self.info))
+        # followed by the context hint lines:
+        context_strings += [x[2] for x in self.info[-self.context_depth:]]
+        self.label["text"] = '\n'.join(context_strings)
+
+    def timer_event(self):
+        if self.label:
+            self.update_code_context()
+        self.text.after(UPDATEINTERVAL, self.timer_event)
+
+    def font_timer_event(self):
+        newtextfont = self.text["font"]
+        if self.label and newtextfont != self.textfont:
+            self.textfont = newtextfont
+            self.label["font"] = self.textfont
+        self.text.after(FONTUPDATEINTERVAL, self.font_timer_event)

Added: vendor/Python/current/Lib/idlelib/ColorDelegator.py
===================================================================
--- vendor/Python/current/Lib/idlelib/ColorDelegator.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/ColorDelegator.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,263 @@
+import time
+import re
+import keyword
+import __builtin__
+from Tkinter import *
+from Delegator import Delegator
+from configHandler import idleConf
+
+DEBUG = False
+
+def any(name, alternates):
+    "Return a named group pattern matching list of alternates."
+    return "(?P<%s>" % name + "|".join(alternates) + ")"
+
+def make_pat():
+    kw = r"\b" + any("KEYWORD", keyword.kwlist) + r"\b"
+    builtinlist = [str(name) for name in dir(__builtin__)
+                                        if not name.startswith('_')]
+    # self.file = file("file") :
+    # 1st 'file' colorized normal, 2nd as builtin, 3rd as string
+    builtin = r"([^.'\"\\#]\b|^)" + any("BUILTIN", builtinlist) + r"\b"
+    comment = any("COMMENT", [r"#[^\n]*"])
+    sqstring = r"(\b[rRuU])?'[^'\\\n]*(\\.[^'\\\n]*)*'?"
+    dqstring = r'(\b[rRuU])?"[^"\\\n]*(\\.[^"\\\n]*)*"?'
+    sq3string = r"(\b[rRuU])?'''[^'\\]*((\\.|'(?!''))[^'\\]*)*(''')?"
+    dq3string = r'(\b[rRuU])?"""[^"\\]*((\\.|"(?!""))[^"\\]*)*(""")?'
+    string = any("STRING", [sq3string, dq3string, sqstring, dqstring])
+    return kw + "|" + builtin + "|" + comment + "|" + string +\
+           "|" + any("SYNC", [r"\n"])
+
+prog = re.compile(make_pat(), re.S)
+idprog = re.compile(r"\s+(\w+)", re.S)
+asprog = re.compile(r".*?\b(as)\b")
+
+class ColorDelegator(Delegator):
+
+    def __init__(self):
+        Delegator.__init__(self)
+        self.prog = prog
+        self.idprog = idprog
+        self.asprog = asprog
+        self.LoadTagDefs()
+
+    def setdelegate(self, delegate):
+        if self.delegate is not None:
+            self.unbind("<<toggle-auto-coloring>>")
+        Delegator.setdelegate(self, delegate)
+        if delegate is not None:
+            self.config_colors()
+            self.bind("<<toggle-auto-coloring>>", self.toggle_colorize_event)
+            self.notify_range("1.0", "end")
+
+    def config_colors(self):
+        for tag, cnf in self.tagdefs.items():
+            if cnf:
+                self.tag_configure(tag, **cnf)
+        self.tag_raise('sel')
+
+    def LoadTagDefs(self):
+        theme = idleConf.GetOption('main','Theme','name')
+        self.tagdefs = {
+            "COMMENT": idleConf.GetHighlight(theme, "comment"),
+            "KEYWORD": idleConf.GetHighlight(theme, "keyword"),
+            "BUILTIN": idleConf.GetHighlight(theme, "builtin"),
+            "STRING": idleConf.GetHighlight(theme, "string"),
+            "DEFINITION": idleConf.GetHighlight(theme, "definition"),
+            "SYNC": {'background':None,'foreground':None},
+            "TODO": {'background':None,'foreground':None},
+            "BREAK": idleConf.GetHighlight(theme, "break"),
+            "ERROR": idleConf.GetHighlight(theme, "error"),
+            # The following is used by ReplaceDialog:
+            "hit": idleConf.GetHighlight(theme, "hit"),
+            }
+
+        if DEBUG: print 'tagdefs',self.tagdefs
+
+    def insert(self, index, chars, tags=None):
+        index = self.index(index)
+        self.delegate.insert(index, chars, tags)
+        self.notify_range(index, index + "+%dc" % len(chars))
+
+    def delete(self, index1, index2=None):
+        index1 = self.index(index1)
+        self.delegate.delete(index1, index2)
+        self.notify_range(index1)
+
+    after_id = None
+    allow_colorizing = True
+    colorizing = False
+
+    def notify_range(self, index1, index2=None):
+        self.tag_add("TODO", index1, index2)
+        if self.after_id:
+            if DEBUG: print "colorizing already scheduled"
+            return
+        if self.colorizing:
+            self.stop_colorizing = True
+            if DEBUG: print "stop colorizing"
+        if self.allow_colorizing:
+            if DEBUG: print "schedule colorizing"
+            self.after_id = self.after(1, self.recolorize)
+
+    close_when_done = None # Window to be closed when done colorizing
+
+    def close(self, close_when_done=None):
+        if self.after_id:
+            after_id = self.after_id
+            self.after_id = None
+            if DEBUG: print "cancel scheduled recolorizer"
+            self.after_cancel(after_id)
+        self.allow_colorizing = False
+        self.stop_colorizing = True
+        if close_when_done:
+            if not self.colorizing:
+                close_when_done.destroy()
+            else:
+                self.close_when_done = close_when_done
+
+    def toggle_colorize_event(self, event):
+        if self.after_id:
+            after_id = self.after_id
+            self.after_id = None
+            if DEBUG: print "cancel scheduled recolorizer"
+            self.after_cancel(after_id)
+        if self.allow_colorizing and self.colorizing:
+            if DEBUG: print "stop colorizing"
+            self.stop_colorizing = True
+        self.allow_colorizing = not self.allow_colorizing
+        if self.allow_colorizing and not self.colorizing:
+            self.after_id = self.after(1, self.recolorize)
+        if DEBUG:
+            print "auto colorizing turned",\
+                  self.allow_colorizing and "on" or "off"
+        return "break"
+
+    def recolorize(self):
+        self.after_id = None
+        if not self.delegate:
+            if DEBUG: print "no delegate"
+            return
+        if not self.allow_colorizing:
+            if DEBUG: print "auto colorizing is off"
+            return
+        if self.colorizing:
+            if DEBUG: print "already colorizing"
+            return
+        try:
+            self.stop_colorizing = False
+            self.colorizing = True
+            if DEBUG: print "colorizing..."
+            t0 = time.clock()
+            self.recolorize_main()
+            t1 = time.clock()
+            if DEBUG: print "%.3f seconds" % (t1-t0)
+        finally:
+            self.colorizing = False
+        if self.allow_colorizing and self.tag_nextrange("TODO", "1.0"):
+            if DEBUG: print "reschedule colorizing"
+            self.after_id = self.after(1, self.recolorize)
+        if self.close_when_done:
+            top = self.close_when_done
+            self.close_when_done = None
+            top.destroy()
+
+    def recolorize_main(self):
+        next = "1.0"
+        while True:
+            item = self.tag_nextrange("TODO", next)
+            if not item:
+                break
+            head, tail = item
+            self.tag_remove("SYNC", head, tail)
+            item = self.tag_prevrange("SYNC", head)
+            if item:
+                head = item[1]
+            else:
+                head = "1.0"
+
+            chars = ""
+            next = head
+            lines_to_get = 1
+            ok = False
+            while not ok:
+                mark = next
+                next = self.index(mark + "+%d lines linestart" %
+                                         lines_to_get)
+                lines_to_get = min(lines_to_get * 2, 100)
+                ok = "SYNC" in self.tag_names(next + "-1c")
+                line = self.get(mark, next)
+                ##print head, "get", mark, next, "->", repr(line)
+                if not line:
+                    return
+                for tag in self.tagdefs.keys():
+                    self.tag_remove(tag, mark, next)
+                chars = chars + line
+                m = self.prog.search(chars)
+                while m:
+                    for key, value in m.groupdict().items():
+                        if value:
+                            a, b = m.span(key)
+                            self.tag_add(key,
+                                         head + "+%dc" % a,
+                                         head + "+%dc" % b)
+                            if value in ("def", "class"):
+                                m1 = self.idprog.match(chars, b)
+                                if m1:
+                                    a, b = m1.span(1)
+                                    self.tag_add("DEFINITION",
+                                                 head + "+%dc" % a,
+                                                 head + "+%dc" % b)
+                            elif value == "import":
+                                # color all the "as" words on same line, except
+                                # if in a comment; cheap approximation to the
+                                # truth
+                                if '#' in chars:
+                                    endpos = chars.index('#')
+                                else:
+                                    endpos = len(chars)
+                                while True:
+                                    m1 = self.asprog.match(chars, b, endpos)
+                                    if not m1:
+                                        break
+                                    a, b = m1.span(1)
+                                    self.tag_add("KEYWORD",
+                                                 head + "+%dc" % a,
+                                                 head + "+%dc" % b)
+                    m = self.prog.search(chars, m.end())
+                if "SYNC" in self.tag_names(next + "-1c"):
+                    head = next
+                    chars = ""
+                else:
+                    ok = False
+                if not ok:
+                    # We're in an inconsistent state, and the call to
+                    # update may tell us to stop.  It may also change
+                    # the correct value for "next" (since this is a
+                    # line.col string, not a true mark).  So leave a
+                    # crumb telling the next invocation to resume here
+                    # in case update tells us to leave.
+                    self.tag_add("TODO", next)
+                self.update()
+                if self.stop_colorizing:
+                    if DEBUG: print "colorizing stopped"
+                    return
+
+    def removecolors(self):
+        for tag in self.tagdefs.keys():
+            self.tag_remove(tag, "1.0", "end")
+
+def main():
+    from Percolator import Percolator
+    root = Tk()
+    root.wm_protocol("WM_DELETE_WINDOW", root.quit)
+    text = Text(background="white")
+    text.pack(expand=1, fill="both")
+    text.focus_set()
+    p = Percolator(text)
+    d = ColorDelegator()
+    p.insertfilter(d)
+    root.mainloop()
+
+if __name__ == "__main__":
+    main()

Added: vendor/Python/current/Lib/idlelib/Debugger.py
===================================================================
--- vendor/Python/current/Lib/idlelib/Debugger.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/Debugger.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,481 @@
+import os
+import bdb
+import types
+from Tkinter import *
+from WindowList import ListedToplevel
+from ScrolledList import ScrolledList
+import macosxSupport
+
+
+class Idb(bdb.Bdb):
+
+    def __init__(self, gui):
+        self.gui = gui
+        bdb.Bdb.__init__(self)
+
+    def user_line(self, frame):
+        if self.in_rpc_code(frame):
+            self.set_step()
+            return
+        message = self.__frame2message(frame)
+        self.gui.interaction(message, frame)
+
+    def user_exception(self, frame, info):
+        if self.in_rpc_code(frame):
+            self.set_step()
+            return
+        message = self.__frame2message(frame)
+        self.gui.interaction(message, frame, info)
+
+    def in_rpc_code(self, frame):
+        if frame.f_code.co_filename.count('rpc.py'):
+            return True
+        else:
+            prev_frame = frame.f_back
+            if prev_frame.f_code.co_filename.count('Debugger.py'):
+                # (that test will catch both Debugger.py and RemoteDebugger.py)
+                return False
+            return self.in_rpc_code(prev_frame)
+
+    def __frame2message(self, frame):
+        code = frame.f_code
+        filename = code.co_filename
+        lineno = frame.f_lineno
+        basename = os.path.basename(filename)
+        message = "%s:%s" % (basename, lineno)
+        if code.co_name != "?":
+            message = "%s: %s()" % (message, code.co_name)
+        return message
+
+
+class Debugger:
+
+    vstack = vsource = vlocals = vglobals = None
+
+    def __init__(self, pyshell, idb=None):
+        if idb is None:
+            idb = Idb(self)
+        self.pyshell = pyshell
+        self.idb = idb
+        self.frame = None
+        self.make_gui()
+        self.interacting = 0
+
+    def run(self, *args):
+        try:
+            self.interacting = 1
+            return self.idb.run(*args)
+        finally:
+            self.interacting = 0
+
+    def close(self, event=None):
+        if self.interacting:
+            self.top.bell()
+            return
+        if self.stackviewer:
+            self.stackviewer.close(); self.stackviewer = None
+        # Clean up pyshell if user clicked debugger control close widget.
+        # (Causes a harmless extra cycle through close_debugger() if user
+        # toggled debugger from pyshell Debug menu)
+        self.pyshell.close_debugger()
+        # Now close the debugger control window....
+        self.top.destroy()
+
+    def make_gui(self):
+        pyshell = self.pyshell
+        self.flist = pyshell.flist
+        self.root = root = pyshell.root
+        self.top = top = ListedToplevel(root)
+        self.top.wm_title("Debug Control")
+        self.top.wm_iconname("Debug")
+        top.wm_protocol("WM_DELETE_WINDOW", self.close)
+        self.top.bind("<Escape>", self.close)
+        #
+        self.bframe = bframe = Frame(top)
+        self.bframe.pack(anchor="w")
+        self.buttons = bl = []
+        #
+        self.bcont = b = Button(bframe, text="Go", command=self.cont)
+        bl.append(b)
+        self.bstep = b = Button(bframe, text="Step", command=self.step)
+        bl.append(b)
+        self.bnext = b = Button(bframe, text="Over", command=self.next)
+        bl.append(b)
+        self.bret = b = Button(bframe, text="Out", command=self.ret)
+        bl.append(b)
+        self.bret = b = Button(bframe, text="Quit", command=self.quit)
+        bl.append(b)
+        #
+        for b in bl:
+            b.configure(state="disabled")
+            b.pack(side="left")
+        #
+        self.cframe = cframe = Frame(bframe)
+        self.cframe.pack(side="left")
+        #
+        if not self.vstack:
+            self.__class__.vstack = BooleanVar(top)
+            self.vstack.set(1)
+        self.bstack = Checkbutton(cframe,
+            text="Stack", command=self.show_stack, variable=self.vstack)
+        self.bstack.grid(row=0, column=0)
+        if not self.vsource:
+            self.__class__.vsource = BooleanVar(top)
+        self.bsource = Checkbutton(cframe,
+            text="Source", command=self.show_source, variable=self.vsource)
+        self.bsource.grid(row=0, column=1)
+        if not self.vlocals:
+            self.__class__.vlocals = BooleanVar(top)
+            self.vlocals.set(1)
+        self.blocals = Checkbutton(cframe,
+            text="Locals", command=self.show_locals, variable=self.vlocals)
+        self.blocals.grid(row=1, column=0)
+        if not self.vglobals:
+            self.__class__.vglobals = BooleanVar(top)
+        self.bglobals = Checkbutton(cframe,
+            text="Globals", command=self.show_globals, variable=self.vglobals)
+        self.bglobals.grid(row=1, column=1)
+        #
+        self.status = Label(top, anchor="w")
+        self.status.pack(anchor="w")
+        self.error = Label(top, anchor="w")
+        self.error.pack(anchor="w", fill="x")
+        self.errorbg = self.error.cget("background")
+        #
+        self.fstack = Frame(top, height=1)
+        self.fstack.pack(expand=1, fill="both")
+        self.flocals = Frame(top)
+        self.flocals.pack(expand=1, fill="both")
+        self.fglobals = Frame(top, height=1)
+        self.fglobals.pack(expand=1, fill="both")
+        #
+        if self.vstack.get():
+            self.show_stack()
+        if self.vlocals.get():
+            self.show_locals()
+        if self.vglobals.get():
+            self.show_globals()
+
+    def interaction(self, message, frame, info=None):
+        self.frame = frame
+        self.status.configure(text=message)
+        #
+        if info:
+            type, value, tb = info
+            try:
+                m1 = type.__name__
+            except AttributeError:
+                m1 = "%s" % str(type)
+            if value is not None:
+                try:
+                    m1 = "%s: %s" % (m1, str(value))
+                except:
+                    pass
+            bg = "yellow"
+        else:
+            m1 = ""
+            tb = None
+            bg = self.errorbg
+        self.error.configure(text=m1, background=bg)
+        #
+        sv = self.stackviewer
+        if sv:
+            stack, i = self.idb.get_stack(self.frame, tb)
+            sv.load_stack(stack, i)
+        #
+        self.show_variables(1)
+        #
+        if self.vsource.get():
+            self.sync_source_line()
+        #
+        for b in self.buttons:
+            b.configure(state="normal")
+        #
+        self.top.wakeup()
+        self.root.mainloop()
+        #
+        for b in self.buttons:
+            b.configure(state="disabled")
+        self.status.configure(text="")
+        self.error.configure(text="", background=self.errorbg)
+        self.frame = None
+
+    def sync_source_line(self):
+        frame = self.frame
+        if not frame:
+            return
+        filename, lineno = self.__frame2fileline(frame)
+        if filename[:1] + filename[-1:] != "<>" and os.path.exists(filename):
+            self.flist.gotofileline(filename, lineno)
+
+    def __frame2fileline(self, frame):
+        code = frame.f_code
+        filename = code.co_filename
+        lineno = frame.f_lineno
+        return filename, lineno
+
+    def cont(self):
+        self.idb.set_continue()
+        self.root.quit()
+
+    def step(self):
+        self.idb.set_step()
+        self.root.quit()
+
+    def next(self):
+        self.idb.set_next(self.frame)
+        self.root.quit()
+
+    def ret(self):
+        self.idb.set_return(self.frame)
+        self.root.quit()
+
+    def quit(self):
+        self.idb.set_quit()
+        self.root.quit()
+
+    stackviewer = None
+
+    def show_stack(self):
+        if not self.stackviewer and self.vstack.get():
+            self.stackviewer = sv = StackViewer(self.fstack, self.flist, self)
+            if self.frame:
+                stack, i = self.idb.get_stack(self.frame, None)
+                sv.load_stack(stack, i)
+        else:
+            sv = self.stackviewer
+            if sv and not self.vstack.get():
+                self.stackviewer = None
+                sv.close()
+            self.fstack['height'] = 1
+
+    def show_source(self):
+        if self.vsource.get():
+            self.sync_source_line()
+
+    def show_frame(self, (frame, lineno)):
+        self.frame = frame
+        self.show_variables()
+
+    localsviewer = None
+    globalsviewer = None
+
+    def show_locals(self):
+        lv = self.localsviewer
+        if self.vlocals.get():
+            if not lv:
+                self.localsviewer = NamespaceViewer(self.flocals, "Locals")
+        else:
+            if lv:
+                self.localsviewer = None
+                lv.close()
+                self.flocals['height'] = 1
+        self.show_variables()
+
+    def show_globals(self):
+        gv = self.globalsviewer
+        if self.vglobals.get():
+            if not gv:
+                self.globalsviewer = NamespaceViewer(self.fglobals, "Globals")
+        else:
+            if gv:
+                self.globalsviewer = None
+                gv.close()
+                self.fglobals['height'] = 1
+        self.show_variables()
+
+    def show_variables(self, force=0):
+        lv = self.localsviewer
+        gv = self.globalsviewer
+        frame = self.frame
+        if not frame:
+            ldict = gdict = None
+        else:
+            ldict = frame.f_locals
+            gdict = frame.f_globals
+            if lv and gv and ldict is gdict:
+                ldict = None
+        if lv:
+            lv.load_dict(ldict, force, self.pyshell.interp.rpcclt)
+        if gv:
+            gv.load_dict(gdict, force, self.pyshell.interp.rpcclt)
+
+    def set_breakpoint_here(self, filename, lineno):
+        self.idb.set_break(filename, lineno)
+
+    def clear_breakpoint_here(self, filename, lineno):
+        self.idb.clear_break(filename, lineno)
+
+    def clear_file_breaks(self, filename):
+        self.idb.clear_all_file_breaks(filename)
+
+    def load_breakpoints(self):
+        "Load PyShellEditorWindow breakpoints into subprocess debugger"
+        pyshell_edit_windows = self.pyshell.flist.inversedict.keys()
+        for editwin in pyshell_edit_windows:
+            filename = editwin.io.filename
+            try:
+                for lineno in editwin.breakpoints:
+                    self.set_breakpoint_here(filename, lineno)
+            except AttributeError:
+                continue
+
+class StackViewer(ScrolledList):
+
+    def __init__(self, master, flist, gui):
+        if macosxSupport.runningAsOSXApp():
+            # At least on with the stock AquaTk version on OSX 10.4 you'll
+            # get an shaking GUI that eventually kills IDLE if the width
+            # argument is specified.
+            ScrolledList.__init__(self, master)
+        else:
+            ScrolledList.__init__(self, master, width=80)
+        self.flist = flist
+        self.gui = gui
+        self.stack = []
+
+    def load_stack(self, stack, index=None):
+        self.stack = stack
+        self.clear()
+        for i in range(len(stack)):
+            frame, lineno = stack[i]
+            try:
+                modname = frame.f_globals["__name__"]
+            except:
+                modname = "?"
+            code = frame.f_code
+            filename = code.co_filename
+            funcname = code.co_name
+            import linecache
+            sourceline = linecache.getline(filename, lineno)
+            import string
+            sourceline = string.strip(sourceline)
+            if funcname in ("?", "", None):
+                item = "%s, line %d: %s" % (modname, lineno, sourceline)
+            else:
+                item = "%s.%s(), line %d: %s" % (modname, funcname,
+                                                 lineno, sourceline)
+            if i == index:
+                item = "> " + item
+            self.append(item)
+        if index is not None:
+            self.select(index)
+
+    def popup_event(self, event):
+        "override base method"
+        if self.stack:
+            return ScrolledList.popup_event(self, event)
+
+    def fill_menu(self):
+        "override base method"
+        menu = self.menu
+        menu.add_command(label="Go to source line",
+                         command=self.goto_source_line)
+        menu.add_command(label="Show stack frame",
+                         command=self.show_stack_frame)
+
+    def on_select(self, index):
+        "override base method"
+        if 0 <= index < len(self.stack):
+            self.gui.show_frame(self.stack[index])
+
+    def on_double(self, index):
+        "override base method"
+        self.show_source(index)
+
+    def goto_source_line(self):
+        index = self.listbox.index("active")
+        self.show_source(index)
+
+    def show_stack_frame(self):
+        index = self.listbox.index("active")
+        if 0 <= index < len(self.stack):
+            self.gui.show_frame(self.stack[index])
+
+    def show_source(self, index):
+        if not (0 <= index < len(self.stack)):
+            return
+        frame, lineno = self.stack[index]
+        code = frame.f_code
+        filename = code.co_filename
+        if os.path.isfile(filename):
+            edit = self.flist.open(filename)
+            if edit:
+                edit.gotoline(lineno)
+
+
+class NamespaceViewer:
+
+    def __init__(self, master, title, dict=None):
+        width = 0
+        height = 40
+        if dict:
+            height = 20*len(dict) # XXX 20 == observed height of Entry widget
+        self.master = master
+        self.title = title
+        import repr
+        self.repr = repr.Repr()
+        self.repr.maxstring = 60
+        self.repr.maxother = 60
+        self.frame = frame = Frame(master)
+        self.frame.pack(expand=1, fill="both")
+        self.label = Label(frame, text=title, borderwidth=2, relief="groove")
+        self.label.pack(fill="x")
+        self.vbar = vbar = Scrollbar(frame, name="vbar")
+        vbar.pack(side="right", fill="y")
+        self.canvas = canvas = Canvas(frame,
+                                      height=min(300, max(40, height)),
+                                      scrollregion=(0, 0, width, height))
+        canvas.pack(side="left", fill="both", expand=1)
+        vbar["command"] = canvas.yview
+        canvas["yscrollcommand"] = vbar.set
+        self.subframe = subframe = Frame(canvas)
+        self.sfid = canvas.create_window(0, 0, window=subframe, anchor="nw")
+        self.load_dict(dict)
+
+    dict = -1
+
+    def load_dict(self, dict, force=0, rpc_client=None):
+        if dict is self.dict and not force:
+            return
+        subframe = self.subframe
+        frame = self.frame
+        for c in subframe.children.values():
+            c.destroy()
+        self.dict = None
+        if not dict:
+            l = Label(subframe, text="None")
+            l.grid(row=0, column=0)
+        else:
+            names = dict.keys()
+            names.sort()
+            row = 0
+            for name in names:
+                value = dict[name]
+                svalue = self.repr.repr(value) # repr(value)
+                # Strip extra quotes caused by calling repr on the (already)
+                # repr'd value sent across the RPC interface:
+                if rpc_client:
+                    svalue = svalue[1:-1]
+                l = Label(subframe, text=name)
+                l.grid(row=row, column=0, sticky="nw")
+                l = Entry(subframe, width=0, borderwidth=0)
+                l.insert(0, svalue)
+                l.grid(row=row, column=1, sticky="nw")
+                row = row+1
+        self.dict = dict
+        # XXX Could we use a <Configure> callback for the following?
+        subframe.update_idletasks() # Alas!
+        width = subframe.winfo_reqwidth()
+        height = subframe.winfo_reqheight()
+        canvas = self.canvas
+        self.canvas["scrollregion"] = (0, 0, width, height)
+        if height > 300:
+            canvas["height"] = 300
+            frame.pack(expand=1)
+        else:
+            canvas["height"] = height
+            frame.pack(expand=0)
+
+    def close(self):
+        self.frame.destroy()

Added: vendor/Python/current/Lib/idlelib/Delegator.py
===================================================================
--- vendor/Python/current/Lib/idlelib/Delegator.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/Delegator.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,33 @@
+class Delegator:
+
+    # The cache is only used to be able to change delegates!
+
+    def __init__(self, delegate=None):
+        self.delegate = delegate
+        self.__cache = {}
+
+    def __getattr__(self, name):
+        attr = getattr(self.delegate, name) # May raise AttributeError
+        setattr(self, name, attr)
+        self.__cache[name] = attr
+        return attr
+
+    def resetcache(self):
+        for key in self.__cache.keys():
+            try:
+                delattr(self, key)
+            except AttributeError:
+                pass
+        self.__cache.clear()
+
+    def cachereport(self):
+        keys = self.__cache.keys()
+        keys.sort()
+        print keys
+
+    def setdelegate(self, delegate):
+        self.resetcache()
+        self.delegate = delegate
+
+    def getdelegate(self):
+        return self.delegate

Added: vendor/Python/current/Lib/idlelib/EditorWindow.py
===================================================================
--- vendor/Python/current/Lib/idlelib/EditorWindow.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/EditorWindow.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1511 @@
+import sys
+import os
+import re
+import imp
+from itertools import count
+from Tkinter import *
+import tkSimpleDialog
+import tkMessageBox
+from MultiCall import MultiCallCreator
+
+import webbrowser
+import idlever
+import WindowList
+import SearchDialog
+import GrepDialog
+import ReplaceDialog
+import PyParse
+from configHandler import idleConf
+import aboutDialog, textView, configDialog
+import macosxSupport
+
+# The default tab setting for a Text widget, in average-width characters.
+TK_TABWIDTH_DEFAULT = 8
+
+def _find_module(fullname, path=None):
+    """Version of imp.find_module() that handles hierarchical module names"""
+
+    file = None
+    for tgt in fullname.split('.'):
+        if file is not None:
+            file.close()            # close intermediate files
+        (file, filename, descr) = imp.find_module(tgt, path)
+        if descr[2] == imp.PY_SOURCE:
+            break                   # find but not load the source file
+        module = imp.load_module(tgt, file, filename, descr)
+        try:
+            path = module.__path__
+        except AttributeError:
+            raise ImportError, 'No source for module ' + module.__name__
+    return file, filename, descr
+
+class EditorWindow(object):
+    from Percolator import Percolator
+    from ColorDelegator import ColorDelegator
+    from UndoDelegator import UndoDelegator
+    from IOBinding import IOBinding, filesystemencoding, encoding
+    import Bindings
+    from Tkinter import Toplevel
+    from MultiStatusBar import MultiStatusBar
+
+    help_url = None
+
+    def __init__(self, flist=None, filename=None, key=None, root=None):
+        if EditorWindow.help_url is None:
+            dochome =  os.path.join(sys.prefix, 'Doc', 'index.html')
+            if sys.platform.count('linux'):
+                # look for html docs in a couple of standard places
+                pyver = 'python-docs-' + '%s.%s.%s' % sys.version_info[:3]
+                if os.path.isdir('/var/www/html/python/'):  # "python2" rpm
+                    dochome = '/var/www/html/python/index.html'
+                else:
+                    basepath = '/usr/share/doc/'  # standard location
+                    dochome = os.path.join(basepath, pyver,
+                                           'Doc', 'index.html')
+            elif sys.platform[:3] == 'win':
+                chmfile = os.path.join(sys.prefix, 'Doc',
+                                       'Python%d%d.chm' % sys.version_info[:2])
+                if os.path.isfile(chmfile):
+                    dochome = chmfile
+
+            elif macosxSupport.runningAsOSXApp():
+                # documentation is stored inside the python framework
+                dochome = os.path.join(sys.prefix,
+                        'Resources/English.lproj/Documentation/index.html')
+
+            dochome = os.path.normpath(dochome)
+            if os.path.isfile(dochome):
+                EditorWindow.help_url = dochome
+                if sys.platform == 'darwin':
+                    # Safari requires real file:-URLs
+                    EditorWindow.help_url = 'file://' + EditorWindow.help_url
+            else:
+                EditorWindow.help_url = "http://www.python.org/doc/current"
+        currentTheme=idleConf.CurrentTheme()
+        self.flist = flist
+        root = root or flist.root
+        self.root = root
+        try:
+            sys.ps1
+        except AttributeError:
+            sys.ps1 = '>>> '
+        self.menubar = Menu(root)
+        self.top = top = WindowList.ListedToplevel(root, menu=self.menubar)
+        if flist:
+            self.tkinter_vars = flist.vars
+            #self.top.instance_dict makes flist.inversedict avalable to
+            #configDialog.py so it can access all EditorWindow instaces
+            self.top.instance_dict = flist.inversedict
+        else:
+            self.tkinter_vars = {}  # keys: Tkinter event names
+                                    # values: Tkinter variable instances
+            self.top.instance_dict = {}
+        self.recent_files_path = os.path.join(idleConf.GetUserCfgDir(),
+                'recent-files.lst')
+        self.vbar = vbar = Scrollbar(top, name='vbar')
+        self.text_frame = text_frame = Frame(top)
+        self.width = idleConf.GetOption('main','EditorWindow','width')
+        self.text = text = MultiCallCreator(Text)(
+                text_frame, name='text', padx=5, wrap='none',
+                foreground=idleConf.GetHighlight(currentTheme,
+                        'normal',fgBg='fg'),
+                background=idleConf.GetHighlight(currentTheme,
+                        'normal',fgBg='bg'),
+                highlightcolor=idleConf.GetHighlight(currentTheme,
+                        'hilite',fgBg='fg'),
+                highlightbackground=idleConf.GetHighlight(currentTheme,
+                        'hilite',fgBg='bg'),
+                insertbackground=idleConf.GetHighlight(currentTheme,
+                        'cursor',fgBg='fg'),
+                width=self.width,
+                height=idleConf.GetOption('main','EditorWindow','height') )
+        self.top.focused_widget = self.text
+
+        self.createmenubar()
+        self.apply_bindings()
+
+        self.top.protocol("WM_DELETE_WINDOW", self.close)
+        self.top.bind("<<close-window>>", self.close_event)
+        if macosxSupport.runningAsOSXApp():
+            # Command-W on editorwindows doesn't work without this.
+            text.bind('<<close-window>>', self.close_event)
+        text.bind("<<cut>>", self.cut)
+        text.bind("<<copy>>", self.copy)
+        text.bind("<<paste>>", self.paste)
+        text.bind("<<center-insert>>", self.center_insert_event)
+        text.bind("<<help>>", self.help_dialog)
+        text.bind("<<python-docs>>", self.python_docs)
+        text.bind("<<about-idle>>", self.about_dialog)
+        text.bind("<<open-config-dialog>>", self.config_dialog)
+        text.bind("<<open-module>>", self.open_module)
+        text.bind("<<do-nothing>>", lambda event: "break")
+        text.bind("<<select-all>>", self.select_all)
+        text.bind("<<remove-selection>>", self.remove_selection)
+        text.bind("<<find>>", self.find_event)
+        text.bind("<<find-again>>", self.find_again_event)
+        text.bind("<<find-in-files>>", self.find_in_files_event)
+        text.bind("<<find-selection>>", self.find_selection_event)
+        text.bind("<<replace>>", self.replace_event)
+        text.bind("<<goto-line>>", self.goto_line_event)
+        text.bind("<3>", self.right_menu_event)
+        text.bind("<<smart-backspace>>",self.smart_backspace_event)
+        text.bind("<<newline-and-indent>>",self.newline_and_indent_event)
+        text.bind("<<smart-indent>>",self.smart_indent_event)
+        text.bind("<<indent-region>>",self.indent_region_event)
+        text.bind("<<dedent-region>>",self.dedent_region_event)
+        text.bind("<<comment-region>>",self.comment_region_event)
+        text.bind("<<uncomment-region>>",self.uncomment_region_event)
+        text.bind("<<tabify-region>>",self.tabify_region_event)
+        text.bind("<<untabify-region>>",self.untabify_region_event)
+        text.bind("<<toggle-tabs>>",self.toggle_tabs_event)
+        text.bind("<<change-indentwidth>>",self.change_indentwidth_event)
+        text.bind("<Left>", self.move_at_edge_if_selection(0))
+        text.bind("<Right>", self.move_at_edge_if_selection(1))
+        text.bind("<<del-word-left>>", self.del_word_left)
+        text.bind("<<del-word-right>>", self.del_word_right)
+
+        if flist:
+            flist.inversedict[self] = key
+            if key:
+                flist.dict[key] = self
+            text.bind("<<open-new-window>>", self.new_callback)
+            text.bind("<<close-all-windows>>", self.flist.close_all_callback)
+            text.bind("<<open-class-browser>>", self.open_class_browser)
+            text.bind("<<open-path-browser>>", self.open_path_browser)
+
+        self.set_status_bar()
+        vbar['command'] = text.yview
+        vbar.pack(side=RIGHT, fill=Y)
+        text['yscrollcommand'] = vbar.set
+        fontWeight = 'normal'
+        if idleConf.GetOption('main', 'EditorWindow', 'font-bold', type='bool'):
+            fontWeight='bold'
+        text.config(font=(idleConf.GetOption('main', 'EditorWindow', 'font'),
+                          idleConf.GetOption('main', 'EditorWindow', 'font-size'),
+                          fontWeight))
+        text_frame.pack(side=LEFT, fill=BOTH, expand=1)
+        text.pack(side=TOP, fill=BOTH, expand=1)
+        text.focus_set()
+
+        # usetabs true  -> literal tab characters are used by indent and
+        #                  dedent cmds, possibly mixed with spaces if
+        #                  indentwidth is not a multiple of tabwidth,
+        #                  which will cause Tabnanny to nag!
+        #         false -> tab characters are converted to spaces by indent
+        #                  and dedent cmds, and ditto TAB keystrokes
+        # Although use-spaces=0 can be configured manually in config-main.def,
+        # configuration of tabs v. spaces is not supported in the configuration
+        # dialog.  IDLE promotes the preferred Python indentation: use spaces!
+        usespaces = idleConf.GetOption('main', 'Indent', 'use-spaces', type='bool')
+        self.usetabs = not usespaces
+
+        # tabwidth is the display width of a literal tab character.
+        # CAUTION:  telling Tk to use anything other than its default
+        # tab setting causes it to use an entirely different tabbing algorithm,
+        # treating tab stops as fixed distances from the left margin.
+        # Nobody expects this, so for now tabwidth should never be changed.
+        self.tabwidth = 8    # must remain 8 until Tk is fixed.
+
+        # indentwidth is the number of screen characters per indent level.
+        # The recommended Python indentation is four spaces.
+        self.indentwidth = self.tabwidth
+        self.set_notabs_indentwidth()
+
+        # If context_use_ps1 is true, parsing searches back for a ps1 line;
+        # else searches for a popular (if, def, ...) Python stmt.
+        self.context_use_ps1 = False
+
+        # When searching backwards for a reliable place to begin parsing,
+        # first start num_context_lines[0] lines back, then
+        # num_context_lines[1] lines back if that didn't work, and so on.
+        # The last value should be huge (larger than the # of lines in a
+        # conceivable file).
+        # Making the initial values larger slows things down more often.
+        self.num_context_lines = 50, 500, 5000000
+
+        self.per = per = self.Percolator(text)
+        if self.ispythonsource(filename):
+            self.color = color = self.ColorDelegator()
+            per.insertfilter(color)
+        else:
+            self.color = None
+
+        self.undo = undo = self.UndoDelegator()
+        per.insertfilter(undo)
+        text.undo_block_start = undo.undo_block_start
+        text.undo_block_stop = undo.undo_block_stop
+        undo.set_saved_change_hook(self.saved_change_hook)
+
+        # IOBinding implements file I/O and printing functionality
+        self.io = io = self.IOBinding(self)
+        io.set_filename_change_hook(self.filename_change_hook)
+
+        # Create the recent files submenu
+        self.recent_files_menu = Menu(self.menubar)
+        self.menudict['file'].insert_cascade(3, label='Recent Files',
+                                             underline=0,
+                                             menu=self.recent_files_menu)
+        self.update_recent_files_list()
+
+        if filename:
+            if os.path.exists(filename) and not os.path.isdir(filename):
+                io.loadfile(filename)
+            else:
+                io.set_filename(filename)
+        self.saved_change_hook()
+
+        self.set_indentation_params(self.ispythonsource(filename))
+
+        self.load_extensions()
+
+        menu = self.menudict.get('windows')
+        if menu:
+            end = menu.index("end")
+            if end is None:
+                end = -1
+            if end >= 0:
+                menu.add_separator()
+                end = end + 1
+            self.wmenu_end = end
+            WindowList.register_callback(self.postwindowsmenu)
+
+        # Some abstractions so IDLE extensions are cross-IDE
+        self.askyesno = tkMessageBox.askyesno
+        self.askinteger = tkSimpleDialog.askinteger
+        self.showerror = tkMessageBox.showerror
+
+    def _filename_to_unicode(self, filename):
+        """convert filename to unicode in order to display it in Tk"""
+        if isinstance(filename, unicode) or not filename:
+            return filename
+        else:
+            try:
+                return filename.decode(self.filesystemencoding)
+            except UnicodeDecodeError:
+                # XXX
+                try:
+                    return filename.decode(self.encoding)
+                except UnicodeDecodeError:
+                    # byte-to-byte conversion
+                    return filename.decode('iso8859-1')
+
+    def new_callback(self, event):
+        dirname, basename = self.io.defaultfilename()
+        self.flist.new(dirname)
+        return "break"
+
+    def set_status_bar(self):
+        self.status_bar = self.MultiStatusBar(self.top)
+        if macosxSupport.runningAsOSXApp():
+            # Insert some padding to avoid obscuring some of the statusbar
+            # by the resize widget.
+            self.status_bar.set_label('_padding1', '    ', side=RIGHT)
+        self.status_bar.set_label('column', 'Col: ?', side=RIGHT)
+        self.status_bar.set_label('line', 'Ln: ?', side=RIGHT)
+        self.status_bar.pack(side=BOTTOM, fill=X)
+        self.text.bind("<<set-line-and-column>>", self.set_line_and_column)
+        self.text.event_add("<<set-line-and-column>>",
+                            "<KeyRelease>", "<ButtonRelease>")
+        self.text.after_idle(self.set_line_and_column)
+
+    def set_line_and_column(self, event=None):
+        line, column = self.text.index(INSERT).split('.')
+        self.status_bar.set_label('column', 'Col: %s' % column)
+        self.status_bar.set_label('line', 'Ln: %s' % line)
+
+    menu_specs = [
+        ("file", "_File"),
+        ("edit", "_Edit"),
+        ("format", "F_ormat"),
+        ("run", "_Run"),
+        ("options", "_Options"),
+        ("windows", "_Windows"),
+        ("help", "_Help"),
+    ]
+
+    if macosxSupport.runningAsOSXApp():
+        del menu_specs[-3]
+        menu_specs[-2] = ("windows", "_Window")
+
+
+    def createmenubar(self):
+        mbar = self.menubar
+        self.menudict = menudict = {}
+        for name, label in self.menu_specs:
+            underline, label = prepstr(label)
+            menudict[name] = menu = Menu(mbar, name=name)
+            mbar.add_cascade(label=label, menu=menu, underline=underline)
+
+        if sys.platform == 'darwin' and '.framework' in sys.executable:
+            # Insert the application menu
+            menudict['application'] = menu = Menu(mbar, name='apple')
+            mbar.add_cascade(label='IDLE', menu=menu)
+
+        self.fill_menus()
+        self.base_helpmenu_length = self.menudict['help'].index(END)
+        self.reset_help_menu_entries()
+
+    def postwindowsmenu(self):
+        # Only called when Windows menu exists
+        menu = self.menudict['windows']
+        end = menu.index("end")
+        if end is None:
+            end = -1
+        if end > self.wmenu_end:
+            menu.delete(self.wmenu_end+1, end)
+        WindowList.add_windows_to_menu(menu)
+
+    rmenu = None
+
+    def right_menu_event(self, event):
+        self.text.tag_remove("sel", "1.0", "end")
+        self.text.mark_set("insert", "@%d,%d" % (event.x, event.y))
+        if not self.rmenu:
+            self.make_rmenu()
+        rmenu = self.rmenu
+        self.event = event
+        iswin = sys.platform[:3] == 'win'
+        if iswin:
+            self.text.config(cursor="arrow")
+        rmenu.tk_popup(event.x_root, event.y_root)
+        if iswin:
+            self.text.config(cursor="ibeam")
+
+    rmenu_specs = [
+        # ("Label", "<<virtual-event>>"), ...
+        ("Close", "<<close-window>>"), # Example
+    ]
+
+    def make_rmenu(self):
+        rmenu = Menu(self.text, tearoff=0)
+        for label, eventname in self.rmenu_specs:
+            def command(text=self.text, eventname=eventname):
+                text.event_generate(eventname)
+            rmenu.add_command(label=label, command=command)
+        self.rmenu = rmenu
+
+    def about_dialog(self, event=None):
+        aboutDialog.AboutDialog(self.top,'About IDLE')
+
+    def config_dialog(self, event=None):
+        configDialog.ConfigDialog(self.top,'Settings')
+
+    def help_dialog(self, event=None):
+        fn=os.path.join(os.path.abspath(os.path.dirname(__file__)),'help.txt')
+        textView.TextViewer(self.top,'Help',fn)
+
+    def python_docs(self, event=None):
+        if sys.platform[:3] == 'win':
+            os.startfile(self.help_url)
+        else:
+            webbrowser.open(self.help_url)
+        return "break"
+
+    def cut(self,event):
+        self.text.event_generate("<<Cut>>")
+        return "break"
+
+    def copy(self,event):
+        if not self.text.tag_ranges("sel"):
+            # There is no selection, so do nothing and maybe interrupt.
+            return
+        self.text.event_generate("<<Copy>>")
+        return "break"
+
+    def paste(self,event):
+        self.text.event_generate("<<Paste>>")
+        return "break"
+
+    def select_all(self, event=None):
+        self.text.tag_add("sel", "1.0", "end-1c")
+        self.text.mark_set("insert", "1.0")
+        self.text.see("insert")
+        return "break"
+
+    def remove_selection(self, event=None):
+        self.text.tag_remove("sel", "1.0", "end")
+        self.text.see("insert")
+
+    def move_at_edge_if_selection(self, edge_index):
+        """Cursor move begins at start or end of selection
+
+        When a left/right cursor key is pressed create and return to Tkinter a
+        function which causes a cursor move from the associated edge of the
+        selection.
+
+        """
+        self_text_index = self.text.index
+        self_text_mark_set = self.text.mark_set
+        edges_table = ("sel.first+1c", "sel.last-1c")
+        def move_at_edge(event):
+            if (event.state & 5) == 0: # no shift(==1) or control(==4) pressed
+                try:
+                    self_text_index("sel.first")
+                    self_text_mark_set("insert", edges_table[edge_index])
+                except TclError:
+                    pass
+        return move_at_edge
+
+    def del_word_left(self, event):
+        self.text.event_generate('<Meta-Delete>')
+        return "break"
+
+    def del_word_right(self, event):
+        self.text.event_generate('<Meta-d>')
+        return "break"
+
+    def find_event(self, event):
+        SearchDialog.find(self.text)
+        return "break"
+
+    def find_again_event(self, event):
+        SearchDialog.find_again(self.text)
+        return "break"
+
+    def find_selection_event(self, event):
+        SearchDialog.find_selection(self.text)
+        return "break"
+
+    def find_in_files_event(self, event):
+        GrepDialog.grep(self.text, self.io, self.flist)
+        return "break"
+
+    def replace_event(self, event):
+        ReplaceDialog.replace(self.text)
+        return "break"
+
+    def goto_line_event(self, event):
+        text = self.text
+        lineno = tkSimpleDialog.askinteger("Goto",
+                "Go to line number:",parent=text)
+        if lineno is None:
+            return "break"
+        if lineno <= 0:
+            text.bell()
+            return "break"
+        text.mark_set("insert", "%d.0" % lineno)
+        text.see("insert")
+
+    def open_module(self, event=None):
+        # XXX Shouldn't this be in IOBinding or in FileList?
+        try:
+            name = self.text.get("sel.first", "sel.last")
+        except TclError:
+            name = ""
+        else:
+            name = name.strip()
+        name = tkSimpleDialog.askstring("Module",
+                 "Enter the name of a Python module\n"
+                 "to search on sys.path and open:",
+                 parent=self.text, initialvalue=name)
+        if name:
+            name = name.strip()
+        if not name:
+            return
+        # XXX Ought to insert current file's directory in front of path
+        try:
+            (f, file, (suffix, mode, type)) = _find_module(name)
+        except (NameError, ImportError), msg:
+            tkMessageBox.showerror("Import error", str(msg), parent=self.text)
+            return
+        if type != imp.PY_SOURCE:
+            tkMessageBox.showerror("Unsupported type",
+                "%s is not a source module" % name, parent=self.text)
+            return
+        if f:
+            f.close()
+        if self.flist:
+            self.flist.open(file)
+        else:
+            self.io.loadfile(file)
+
+    def open_class_browser(self, event=None):
+        filename = self.io.filename
+        if not filename:
+            tkMessageBox.showerror(
+                "No filename",
+                "This buffer has no associated filename",
+                master=self.text)
+            self.text.focus_set()
+            return None
+        head, tail = os.path.split(filename)
+        base, ext = os.path.splitext(tail)
+        import ClassBrowser
+        ClassBrowser.ClassBrowser(self.flist, base, [head])
+
+    def open_path_browser(self, event=None):
+        import PathBrowser
+        PathBrowser.PathBrowser(self.flist)
+
+    def gotoline(self, lineno):
+        if lineno is not None and lineno > 0:
+            self.text.mark_set("insert", "%d.0" % lineno)
+            self.text.tag_remove("sel", "1.0", "end")
+            self.text.tag_add("sel", "insert", "insert +1l")
+            self.center()
+
+    def ispythonsource(self, filename):
+        if not filename or os.path.isdir(filename):
+            return True
+        base, ext = os.path.splitext(os.path.basename(filename))
+        if os.path.normcase(ext) in (".py", ".pyw"):
+            return True
+        try:
+            f = open(filename)
+            line = f.readline()
+            f.close()
+        except IOError:
+            return False
+        return line.startswith('#!') and line.find('python') >= 0
+
+    def close_hook(self):
+        if self.flist:
+            self.flist.close_edit(self)
+
+    def set_close_hook(self, close_hook):
+        self.close_hook = close_hook
+
+    def filename_change_hook(self):
+        if self.flist:
+            self.flist.filename_changed_edit(self)
+        self.saved_change_hook()
+        self.top.update_windowlist_registry(self)
+        if self.ispythonsource(self.io.filename):
+            self.addcolorizer()
+        else:
+            self.rmcolorizer()
+
+    def addcolorizer(self):
+        if self.color:
+            return
+        self.per.removefilter(self.undo)
+        self.color = self.ColorDelegator()
+        self.per.insertfilter(self.color)
+        self.per.insertfilter(self.undo)
+
+    def rmcolorizer(self):
+        if not self.color:
+            return
+        self.color.removecolors()
+        self.per.removefilter(self.undo)
+        self.per.removefilter(self.color)
+        self.color = None
+        self.per.insertfilter(self.undo)
+
+    def ResetColorizer(self):
+        "Update the colour theme if it is changed"
+        # Called from configDialog.py
+        if self.color:
+            self.color = self.ColorDelegator()
+            self.per.insertfilter(self.color)
+        theme = idleConf.GetOption('main','Theme','name')
+        self.text.config(idleConf.GetHighlight(theme, "normal"))
+
+    def ResetFont(self):
+        "Update the text widgets' font if it is changed"
+        # Called from configDialog.py
+        fontWeight='normal'
+        if idleConf.GetOption('main','EditorWindow','font-bold',type='bool'):
+            fontWeight='bold'
+        self.text.config(font=(idleConf.GetOption('main','EditorWindow','font'),
+                idleConf.GetOption('main','EditorWindow','font-size'),
+                fontWeight))
+
+    def RemoveKeybindings(self):
+        "Remove the keybindings before they are changed."
+        # Called from configDialog.py
+        self.Bindings.default_keydefs = keydefs = idleConf.GetCurrentKeySet()
+        for event, keylist in keydefs.items():
+            self.text.event_delete(event, *keylist)
+        for extensionName in self.get_standard_extension_names():
+            xkeydefs = idleConf.GetExtensionBindings(extensionName)
+            if xkeydefs:
+                for event, keylist in xkeydefs.items():
+                    self.text.event_delete(event, *keylist)
+
+    def ApplyKeybindings(self):
+        "Update the keybindings after they are changed"
+        # Called from configDialog.py
+        self.Bindings.default_keydefs = keydefs = idleConf.GetCurrentKeySet()
+        self.apply_bindings()
+        for extensionName in self.get_standard_extension_names():
+            xkeydefs = idleConf.GetExtensionBindings(extensionName)
+            if xkeydefs:
+                self.apply_bindings(xkeydefs)
+        #update menu accelerators
+        menuEventDict = {}
+        for menu in self.Bindings.menudefs:
+            menuEventDict[menu[0]] = {}
+            for item in menu[1]:
+                if item:
+                    menuEventDict[menu[0]][prepstr(item[0])[1]] = item[1]
+        for menubarItem in self.menudict.keys():
+            menu = self.menudict[menubarItem]
+            end = menu.index(END) + 1
+            for index in range(0, end):
+                if menu.type(index) == 'command':
+                    accel = menu.entrycget(index, 'accelerator')
+                    if accel:
+                        itemName = menu.entrycget(index, 'label')
+                        event = ''
+                        if menuEventDict.has_key(menubarItem):
+                            if menuEventDict[menubarItem].has_key(itemName):
+                                event = menuEventDict[menubarItem][itemName]
+                        if event:
+                            accel = get_accelerator(keydefs, event)
+                            menu.entryconfig(index, accelerator=accel)
+
+    def set_notabs_indentwidth(self):
+        "Update the indentwidth if changed and not using tabs in this window"
+        # Called from configDialog.py
+        if not self.usetabs:
+            self.indentwidth = idleConf.GetOption('main', 'Indent','num-spaces',
+                                                  type='int')
+
+    def reset_help_menu_entries(self):
+        "Update the additional help entries on the Help menu"
+        help_list = idleConf.GetAllExtraHelpSourcesList()
+        helpmenu = self.menudict['help']
+        # first delete the extra help entries, if any
+        helpmenu_length = helpmenu.index(END)
+        if helpmenu_length > self.base_helpmenu_length:
+            helpmenu.delete((self.base_helpmenu_length + 1), helpmenu_length)
+        # then rebuild them
+        if help_list:
+            helpmenu.add_separator()
+            for entry in help_list:
+                cmd = self.__extra_help_callback(entry[1])
+                helpmenu.add_command(label=entry[0], command=cmd)
+        # and update the menu dictionary
+        self.menudict['help'] = helpmenu
+
+    def __extra_help_callback(self, helpfile):
+        "Create a callback with the helpfile value frozen at definition time"
+        def display_extra_help(helpfile=helpfile):
+            if not helpfile.startswith(('www', 'http')):
+                url = os.path.normpath(helpfile)
+            if sys.platform[:3] == 'win':
+                os.startfile(helpfile)
+            else:
+                webbrowser.open(helpfile)
+        return display_extra_help
+
+    def update_recent_files_list(self, new_file=None):
+        "Load and update the recent files list and menus"
+        rf_list = []
+        if os.path.exists(self.recent_files_path):
+            rf_list_file = open(self.recent_files_path,'r')
+            try:
+                rf_list = rf_list_file.readlines()
+            finally:
+                rf_list_file.close()
+        if new_file:
+            new_file = os.path.abspath(new_file) + '\n'
+            if new_file in rf_list:
+                rf_list.remove(new_file)  # move to top
+            rf_list.insert(0, new_file)
+        # clean and save the recent files list
+        bad_paths = []
+        for path in rf_list:
+            if '\0' in path or not os.path.exists(path[0:-1]):
+                bad_paths.append(path)
+        rf_list = [path for path in rf_list if path not in bad_paths]
+        ulchars = "1234567890ABCDEFGHIJK"
+        rf_list = rf_list[0:len(ulchars)]
+        rf_file = open(self.recent_files_path, 'w')
+        try:
+            rf_file.writelines(rf_list)
+        finally:
+            rf_file.close()
+        # for each edit window instance, construct the recent files menu
+        for instance in self.top.instance_dict.keys():
+            menu = instance.recent_files_menu
+            menu.delete(1, END)  # clear, and rebuild:
+            for i, file in zip(count(), rf_list):
+                file_name = file[0:-1]  # zap \n
+                # make unicode string to display non-ASCII chars correctly
+                ufile_name = self._filename_to_unicode(file_name)
+                callback = instance.__recent_file_callback(file_name)
+                menu.add_command(label=ulchars[i] + " " + ufile_name,
+                                 command=callback,
+                                 underline=0)
+
+    def __recent_file_callback(self, file_name):
+        def open_recent_file(fn_closure=file_name):
+            self.io.open(editFile=fn_closure)
+        return open_recent_file
+
+    def saved_change_hook(self):
+        short = self.short_title()
+        long = self.long_title()
+        if short and long:
+            title = short + " - " + long
+        elif short:
+            title = short
+        elif long:
+            title = long
+        else:
+            title = "Untitled"
+        icon = short or long or title
+        if not self.get_saved():
+            title = "*%s*" % title
+            icon = "*%s" % icon
+        self.top.wm_title(title)
+        self.top.wm_iconname(icon)
+
+    def get_saved(self):
+        return self.undo.get_saved()
+
+    def set_saved(self, flag):
+        self.undo.set_saved(flag)
+
+    def reset_undo(self):
+        self.undo.reset_undo()
+
+    def short_title(self):
+        filename = self.io.filename
+        if filename:
+            filename = os.path.basename(filename)
+        # return unicode string to display non-ASCII chars correctly
+        return self._filename_to_unicode(filename)
+
+    def long_title(self):
+        # return unicode string to display non-ASCII chars correctly
+        return self._filename_to_unicode(self.io.filename or "")
+
+    def center_insert_event(self, event):
+        self.center()
+
+    def center(self, mark="insert"):
+        text = self.text
+        top, bot = self.getwindowlines()
+        lineno = self.getlineno(mark)
+        height = bot - top
+        newtop = max(1, lineno - height//2)
+        text.yview(float(newtop))
+
+    def getwindowlines(self):
+        text = self.text
+        top = self.getlineno("@0,0")
+        bot = self.getlineno("@0,65535")
+        if top == bot and text.winfo_height() == 1:
+            # Geometry manager hasn't run yet
+            height = int(text['height'])
+            bot = top + height - 1
+        return top, bot
+
+    def getlineno(self, mark="insert"):
+        text = self.text
+        return int(float(text.index(mark)))
+
+    def get_geometry(self):
+        "Return (width, height, x, y)"
+        geom = self.top.wm_geometry()
+        m = re.match(r"(\d+)x(\d+)\+(-?\d+)\+(-?\d+)", geom)
+        tuple = (map(int, m.groups()))
+        return tuple
+
+    def close_event(self, event):
+        self.close()
+
+    def maybesave(self):
+        if self.io:
+            if not self.get_saved():
+                if self.top.state()!='normal':
+                    self.top.deiconify()
+                self.top.lower()
+                self.top.lift()
+            return self.io.maybesave()
+
+    def close(self):
+        reply = self.maybesave()
+        if str(reply) != "cancel":
+            self._close()
+        return reply
+
+    def _close(self):
+        if self.io.filename:
+            self.update_recent_files_list(new_file=self.io.filename)
+        WindowList.unregister_callback(self.postwindowsmenu)
+        if self.close_hook:
+            self.close_hook()
+        self.flist = None
+        colorizing = 0
+        self.unload_extensions()
+        self.io.close(); self.io = None
+        self.undo = None # XXX
+        if self.color:
+            colorizing = self.color.colorizing
+            doh = colorizing and self.top
+            self.color.close(doh) # Cancel colorization
+        self.text = None
+        self.tkinter_vars = None
+        self.per.close(); self.per = None
+        if not colorizing:
+            self.top.destroy()
+
+    def load_extensions(self):
+        self.extensions = {}
+        self.load_standard_extensions()
+
+    def unload_extensions(self):
+        for ins in self.extensions.values():
+            if hasattr(ins, "close"):
+                ins.close()
+        self.extensions = {}
+
+    def load_standard_extensions(self):
+        for name in self.get_standard_extension_names():
+            try:
+                self.load_extension(name)
+            except:
+                print "Failed to load extension", repr(name)
+                import traceback
+                traceback.print_exc()
+
+    def get_standard_extension_names(self):
+        return idleConf.GetExtensions(editor_only=True)
+
+    def load_extension(self, name):
+        try:
+            mod = __import__(name, globals(), locals(), [])
+        except ImportError:
+            print "\nFailed to import extension: ", name
+            return
+        cls = getattr(mod, name)
+        keydefs = idleConf.GetExtensionBindings(name)
+        if hasattr(cls, "menudefs"):
+            self.fill_menus(cls.menudefs, keydefs)
+        ins = cls(self)
+        self.extensions[name] = ins
+        if keydefs:
+            self.apply_bindings(keydefs)
+            for vevent in keydefs.keys():
+                methodname = vevent.replace("-", "_")
+                while methodname[:1] == '<':
+                    methodname = methodname[1:]
+                while methodname[-1:] == '>':
+                    methodname = methodname[:-1]
+                methodname = methodname + "_event"
+                if hasattr(ins, methodname):
+                    self.text.bind(vevent, getattr(ins, methodname))
+
+    def apply_bindings(self, keydefs=None):
+        if keydefs is None:
+            keydefs = self.Bindings.default_keydefs
+        text = self.text
+        text.keydefs = keydefs
+        for event, keylist in keydefs.items():
+            if keylist:
+                text.event_add(event, *keylist)
+
+    def fill_menus(self, menudefs=None, keydefs=None):
+        """Add appropriate entries to the menus and submenus
+
+        Menus that are absent or None in self.menudict are ignored.
+        """
+        if menudefs is None:
+            menudefs = self.Bindings.menudefs
+        if keydefs is None:
+            keydefs = self.Bindings.default_keydefs
+        menudict = self.menudict
+        text = self.text
+        for mname, entrylist in menudefs:
+            menu = menudict.get(mname)
+            if not menu:
+                continue
+            for entry in entrylist:
+                if not entry:
+                    menu.add_separator()
+                else:
+                    label, eventname = entry
+                    checkbutton = (label[:1] == '!')
+                    if checkbutton:
+                        label = label[1:]
+                    underline, label = prepstr(label)
+                    accelerator = get_accelerator(keydefs, eventname)
+                    def command(text=text, eventname=eventname):
+                        text.event_generate(eventname)
+                    if checkbutton:
+                        var = self.get_var_obj(eventname, BooleanVar)
+                        menu.add_checkbutton(label=label, underline=underline,
+                            command=command, accelerator=accelerator,
+                            variable=var)
+                    else:
+                        menu.add_command(label=label, underline=underline,
+                                         command=command,
+                                         accelerator=accelerator)
+
+    def getvar(self, name):
+        var = self.get_var_obj(name)
+        if var:
+            value = var.get()
+            return value
+        else:
+            raise NameError, name
+
+    def setvar(self, name, value, vartype=None):
+        var = self.get_var_obj(name, vartype)
+        if var:
+            var.set(value)
+        else:
+            raise NameError, name
+
+    def get_var_obj(self, name, vartype=None):
+        var = self.tkinter_vars.get(name)
+        if not var and vartype:
+            # create a Tkinter variable object with self.text as master:
+            self.tkinter_vars[name] = var = vartype(self.text)
+        return var
+
+    # Tk implementations of "virtual text methods" -- each platform
+    # reusing IDLE's support code needs to define these for its GUI's
+    # flavor of widget.
+
+    # Is character at text_index in a Python string?  Return 0 for
+    # "guaranteed no", true for anything else.  This info is expensive
+    # to compute ab initio, but is probably already known by the
+    # platform's colorizer.
+
+    def is_char_in_string(self, text_index):
+        if self.color:
+            # Return true iff colorizer hasn't (re)gotten this far
+            # yet, or the character is tagged as being in a string
+            return self.text.tag_prevrange("TODO", text_index) or \
+                   "STRING" in self.text.tag_names(text_index)
+        else:
+            # The colorizer is missing: assume the worst
+            return 1
+
+    # If a selection is defined in the text widget, return (start,
+    # end) as Tkinter text indices, otherwise return (None, None)
+    def get_selection_indices(self):
+        try:
+            first = self.text.index("sel.first")
+            last = self.text.index("sel.last")
+            return first, last
+        except TclError:
+            return None, None
+
+    # Return the text widget's current view of what a tab stop means
+    # (equivalent width in spaces).
+
+    def get_tabwidth(self):
+        current = self.text['tabs'] or TK_TABWIDTH_DEFAULT
+        return int(current)
+
+    # Set the text widget's current view of what a tab stop means.
+
+    def set_tabwidth(self, newtabwidth):
+        text = self.text
+        if self.get_tabwidth() != newtabwidth:
+            pixels = text.tk.call("font", "measure", text["font"],
+                                  "-displayof", text.master,
+                                  "n" * newtabwidth)
+            text.configure(tabs=pixels)
+
+    # If ispythonsource and guess are true, guess a good value for
+    # indentwidth based on file content (if possible), and if
+    # indentwidth != tabwidth set usetabs false.
+    # In any case, adjust the Text widget's view of what a tab
+    # character means.
+
+    def set_indentation_params(self, ispythonsource, guess=True):
+        if guess and ispythonsource:
+            i = self.guess_indent()
+            if 2 <= i <= 8:
+                self.indentwidth = i
+            if self.indentwidth != self.tabwidth:
+                self.usetabs = False
+        self.set_tabwidth(self.tabwidth)
+
+    def smart_backspace_event(self, event):
+        text = self.text
+        first, last = self.get_selection_indices()
+        if first and last:
+            text.delete(first, last)
+            text.mark_set("insert", first)
+            return "break"
+        # Delete whitespace left, until hitting a real char or closest
+        # preceding virtual tab stop.
+        chars = text.get("insert linestart", "insert")
+        if chars == '':
+            if text.compare("insert", ">", "1.0"):
+                # easy: delete preceding newline
+                text.delete("insert-1c")
+            else:
+                text.bell()     # at start of buffer
+            return "break"
+        if  chars[-1] not in " \t":
+            # easy: delete preceding real char
+            text.delete("insert-1c")
+            return "break"
+        # Ick.  It may require *inserting* spaces if we back up over a
+        # tab character!  This is written to be clear, not fast.
+        tabwidth = self.tabwidth
+        have = len(chars.expandtabs(tabwidth))
+        assert have > 0
+        want = ((have - 1) // self.indentwidth) * self.indentwidth
+        # Debug prompt is multilined....
+        last_line_of_prompt = sys.ps1.split('\n')[-1]
+        ncharsdeleted = 0
+        while 1:
+            if chars == last_line_of_prompt:
+                break
+            chars = chars[:-1]
+            ncharsdeleted = ncharsdeleted + 1
+            have = len(chars.expandtabs(tabwidth))
+            if have <= want or chars[-1] not in " \t":
+                break
+        text.undo_block_start()
+        text.delete("insert-%dc" % ncharsdeleted, "insert")
+        if have < want:
+            text.insert("insert", ' ' * (want - have))
+        text.undo_block_stop()
+        return "break"
+
+    def smart_indent_event(self, event):
+        # if intraline selection:
+        #     delete it
+        # elif multiline selection:
+        #     do indent-region
+        # else:
+        #     indent one level
+        text = self.text
+        first, last = self.get_selection_indices()
+        text.undo_block_start()
+        try:
+            if first and last:
+                if index2line(first) != index2line(last):
+                    return self.indent_region_event(event)
+                text.delete(first, last)
+                text.mark_set("insert", first)
+            prefix = text.get("insert linestart", "insert")
+            raw, effective = classifyws(prefix, self.tabwidth)
+            if raw == len(prefix):
+                # only whitespace to the left
+                self.reindent_to(effective + self.indentwidth)
+            else:
+                # tab to the next 'stop' within or to right of line's text:
+                if self.usetabs:
+                    pad = '\t'
+                else:
+                    effective = len(prefix.expandtabs(self.tabwidth))
+                    n = self.indentwidth
+                    pad = ' ' * (n - effective % n)
+                text.insert("insert", pad)
+            text.see("insert")
+            return "break"
+        finally:
+            text.undo_block_stop()
+
+    def newline_and_indent_event(self, event):
+        text = self.text
+        first, last = self.get_selection_indices()
+        text.undo_block_start()
+        try:
+            if first and last:
+                text.delete(first, last)
+                text.mark_set("insert", first)
+            line = text.get("insert linestart", "insert")
+            i, n = 0, len(line)
+            while i < n and line[i] in " \t":
+                i = i+1
+            if i == n:
+                # the cursor is in or at leading indentation in a continuation
+                # line; just inject an empty line at the start
+                text.insert("insert linestart", '\n')
+                return "break"
+            indent = line[:i]
+            # strip whitespace before insert point unless it's in the prompt
+            i = 0
+            last_line_of_prompt = sys.ps1.split('\n')[-1]
+            while line and line[-1] in " \t" and line != last_line_of_prompt:
+                line = line[:-1]
+                i = i+1
+            if i:
+                text.delete("insert - %d chars" % i, "insert")
+            # strip whitespace after insert point
+            while text.get("insert") in " \t":
+                text.delete("insert")
+            # start new line
+            text.insert("insert", '\n')
+
+            # adjust indentation for continuations and block
+            # open/close first need to find the last stmt
+            lno = index2line(text.index('insert'))
+            y = PyParse.Parser(self.indentwidth, self.tabwidth)
+            if not self.context_use_ps1:
+                for context in self.num_context_lines:
+                    startat = max(lno - context, 1)
+                    startatindex = `startat` + ".0"
+                    rawtext = text.get(startatindex, "insert")
+                    y.set_str(rawtext)
+                    bod = y.find_good_parse_start(
+                              self.context_use_ps1,
+                              self._build_char_in_string_func(startatindex))
+                    if bod is not None or startat == 1:
+                        break
+                y.set_lo(bod or 0)
+            else:
+                r = text.tag_prevrange("console", "insert")
+                if r:
+                    startatindex = r[1]
+                else:
+                    startatindex = "1.0"
+                rawtext = text.get(startatindex, "insert")
+                y.set_str(rawtext)
+                y.set_lo(0)
+
+            c = y.get_continuation_type()
+            if c != PyParse.C_NONE:
+                # The current stmt hasn't ended yet.
+                if c == PyParse.C_STRING_FIRST_LINE:
+                    # after the first line of a string; do not indent at all
+                    pass
+                elif c == PyParse.C_STRING_NEXT_LINES:
+                    # inside a string which started before this line;
+                    # just mimic the current indent
+                    text.insert("insert", indent)
+                elif c == PyParse.C_BRACKET:
+                    # line up with the first (if any) element of the
+                    # last open bracket structure; else indent one
+                    # level beyond the indent of the line with the
+                    # last open bracket
+                    self.reindent_to(y.compute_bracket_indent())
+                elif c == PyParse.C_BACKSLASH:
+                    # if more than one line in this stmt already, just
+                    # mimic the current indent; else if initial line
+                    # has a start on an assignment stmt, indent to
+                    # beyond leftmost =; else to beyond first chunk of
+                    # non-whitespace on initial line
+                    if y.get_num_lines_in_stmt() > 1:
+                        text.insert("insert", indent)
+                    else:
+                        self.reindent_to(y.compute_backslash_indent())
+                else:
+                    assert 0, "bogus continuation type %r" % (c,)
+                return "break"
+
+            # This line starts a brand new stmt; indent relative to
+            # indentation of initial line of closest preceding
+            # interesting stmt.
+            indent = y.get_base_indent_string()
+            text.insert("insert", indent)
+            if y.is_block_opener():
+                self.smart_indent_event(event)
+            elif indent and y.is_block_closer():
+                self.smart_backspace_event(event)
+            return "break"
+        finally:
+            text.see("insert")
+            text.undo_block_stop()
+
+    # Our editwin provides a is_char_in_string function that works
+    # with a Tk text index, but PyParse only knows about offsets into
+    # a string. This builds a function for PyParse that accepts an
+    # offset.
+
+    def _build_char_in_string_func(self, startindex):
+        def inner(offset, _startindex=startindex,
+                  _icis=self.is_char_in_string):
+            return _icis(_startindex + "+%dc" % offset)
+        return inner
+
+    def indent_region_event(self, event):
+        head, tail, chars, lines = self.get_region()
+        for pos in range(len(lines)):
+            line = lines[pos]
+            if line:
+                raw, effective = classifyws(line, self.tabwidth)
+                effective = effective + self.indentwidth
+                lines[pos] = self._make_blanks(effective) + line[raw:]
+        self.set_region(head, tail, chars, lines)
+        return "break"
+
+    def dedent_region_event(self, event):
+        head, tail, chars, lines = self.get_region()
+        for pos in range(len(lines)):
+            line = lines[pos]
+            if line:
+                raw, effective = classifyws(line, self.tabwidth)
+                effective = max(effective - self.indentwidth, 0)
+                lines[pos] = self._make_blanks(effective) + line[raw:]
+        self.set_region(head, tail, chars, lines)
+        return "break"
+
+    def comment_region_event(self, event):
+        head, tail, chars, lines = self.get_region()
+        for pos in range(len(lines) - 1):
+            line = lines[pos]
+            lines[pos] = '##' + line
+        self.set_region(head, tail, chars, lines)
+
+    def uncomment_region_event(self, event):
+        head, tail, chars, lines = self.get_region()
+        for pos in range(len(lines)):
+            line = lines[pos]
+            if not line:
+                continue
+            if line[:2] == '##':
+                line = line[2:]
+            elif line[:1] == '#':
+                line = line[1:]
+            lines[pos] = line
+        self.set_region(head, tail, chars, lines)
+
+    def tabify_region_event(self, event):
+        head, tail, chars, lines = self.get_region()
+        tabwidth = self._asktabwidth()
+        for pos in range(len(lines)):
+            line = lines[pos]
+            if line:
+                raw, effective = classifyws(line, tabwidth)
+                ntabs, nspaces = divmod(effective, tabwidth)
+                lines[pos] = '\t' * ntabs + ' ' * nspaces + line[raw:]
+        self.set_region(head, tail, chars, lines)
+
+    def untabify_region_event(self, event):
+        head, tail, chars, lines = self.get_region()
+        tabwidth = self._asktabwidth()
+        for pos in range(len(lines)):
+            lines[pos] = lines[pos].expandtabs(tabwidth)
+        self.set_region(head, tail, chars, lines)
+
+    def toggle_tabs_event(self, event):
+        if self.askyesno(
+              "Toggle tabs",
+              "Turn tabs " + ("on", "off")[self.usetabs] +
+              "?\nIndent width " +
+              ("will be", "remains at")[self.usetabs] + " 8." +
+              "\n Note: a tab is always 8 columns",
+              parent=self.text):
+            self.usetabs = not self.usetabs
+            # Try to prevent inconsistent indentation.
+            # User must change indent width manually after using tabs.
+            self.indentwidth = 8
+        return "break"
+
+    # XXX this isn't bound to anything -- see tabwidth comments
+##     def change_tabwidth_event(self, event):
+##         new = self._asktabwidth()
+##         if new != self.tabwidth:
+##             self.tabwidth = new
+##             self.set_indentation_params(0, guess=0)
+##         return "break"
+
+    def change_indentwidth_event(self, event):
+        new = self.askinteger(
+                  "Indent width",
+                  "New indent width (2-16)\n(Always use 8 when using tabs)",
+                  parent=self.text,
+                  initialvalue=self.indentwidth,
+                  minvalue=2,
+                  maxvalue=16)
+        if new and new != self.indentwidth and not self.usetabs:
+            self.indentwidth = new
+        return "break"
+
+    def get_region(self):
+        text = self.text
+        first, last = self.get_selection_indices()
+        if first and last:
+            head = text.index(first + " linestart")
+            tail = text.index(last + "-1c lineend +1c")
+        else:
+            head = text.index("insert linestart")
+            tail = text.index("insert lineend +1c")
+        chars = text.get(head, tail)
+        lines = chars.split("\n")
+        return head, tail, chars, lines
+
+    def set_region(self, head, tail, chars, lines):
+        text = self.text
+        newchars = "\n".join(lines)
+        if newchars == chars:
+            text.bell()
+            return
+        text.tag_remove("sel", "1.0", "end")
+        text.mark_set("insert", head)
+        text.undo_block_start()
+        text.delete(head, tail)
+        text.insert(head, newchars)
+        text.undo_block_stop()
+        text.tag_add("sel", head, "insert")
+
+    # Make string that displays as n leading blanks.
+
+    def _make_blanks(self, n):
+        if self.usetabs:
+            ntabs, nspaces = divmod(n, self.tabwidth)
+            return '\t' * ntabs + ' ' * nspaces
+        else:
+            return ' ' * n
+
+    # Delete from beginning of line to insert point, then reinsert
+    # column logical (meaning use tabs if appropriate) spaces.
+
+    def reindent_to(self, column):
+        text = self.text
+        text.undo_block_start()
+        if text.compare("insert linestart", "!=", "insert"):
+            text.delete("insert linestart", "insert")
+        if column:
+            text.insert("insert", self._make_blanks(column))
+        text.undo_block_stop()
+
+    def _asktabwidth(self):
+        return self.askinteger(
+            "Tab width",
+            "Columns per tab? (2-16)",
+            parent=self.text,
+            initialvalue=self.indentwidth,
+            minvalue=2,
+            maxvalue=16) or self.tabwidth
+
+    # Guess indentwidth from text content.
+    # Return guessed indentwidth.  This should not be believed unless
+    # it's in a reasonable range (e.g., it will be 0 if no indented
+    # blocks are found).
+
+    def guess_indent(self):
+        opener, indented = IndentSearcher(self.text, self.tabwidth).run()
+        if opener and indented:
+            raw, indentsmall = classifyws(opener, self.tabwidth)
+            raw, indentlarge = classifyws(indented, self.tabwidth)
+        else:
+            indentsmall = indentlarge = 0
+        return indentlarge - indentsmall
+
+# "line.col" -> line, as an int
+def index2line(index):
+    return int(float(index))
+
+# Look at the leading whitespace in s.
+# Return pair (# of leading ws characters,
+#              effective # of leading blanks after expanding
+#              tabs to width tabwidth)
+
+def classifyws(s, tabwidth):
+    raw = effective = 0
+    for ch in s:
+        if ch == ' ':
+            raw = raw + 1
+            effective = effective + 1
+        elif ch == '\t':
+            raw = raw + 1
+            effective = (effective // tabwidth + 1) * tabwidth
+        else:
+            break
+    return raw, effective
+
+import tokenize
+_tokenize = tokenize
+del tokenize
+
+class IndentSearcher(object):
+
+    # .run() chews over the Text widget, looking for a block opener
+    # and the stmt following it.  Returns a pair,
+    #     (line containing block opener, line containing stmt)
+    # Either or both may be None.
+
+    def __init__(self, text, tabwidth):
+        self.text = text
+        self.tabwidth = tabwidth
+        self.i = self.finished = 0
+        self.blkopenline = self.indentedline = None
+
+    def readline(self):
+        if self.finished:
+            return ""
+        i = self.i = self.i + 1
+        mark = repr(i) + ".0"
+        if self.text.compare(mark, ">=", "end"):
+            return ""
+        return self.text.get(mark, mark + " lineend+1c")
+
+    def tokeneater(self, type, token, start, end, line,
+                   INDENT=_tokenize.INDENT,
+                   NAME=_tokenize.NAME,
+                   OPENERS=('class', 'def', 'for', 'if', 'try', 'while')):
+        if self.finished:
+            pass
+        elif type == NAME and token in OPENERS:
+            self.blkopenline = line
+        elif type == INDENT and self.blkopenline:
+            self.indentedline = line
+            self.finished = 1
+
+    def run(self):
+        save_tabsize = _tokenize.tabsize
+        _tokenize.tabsize = self.tabwidth
+        try:
+            try:
+                _tokenize.tokenize(self.readline, self.tokeneater)
+            except _tokenize.TokenError:
+                # since we cut off the tokenizer early, we can trigger
+                # spurious errors
+                pass
+        finally:
+            _tokenize.tabsize = save_tabsize
+        return self.blkopenline, self.indentedline
+
+### end autoindent code ###
+
+def prepstr(s):
+    # Helper to extract the underscore from a string, e.g.
+    # prepstr("Co_py") returns (2, "Copy").
+    i = s.find('_')
+    if i >= 0:
+        s = s[:i] + s[i+1:]
+    return i, s
+
+
+keynames = {
+ 'bracketleft': '[',
+ 'bracketright': ']',
+ 'slash': '/',
+}
+
+def get_accelerator(keydefs, eventname):
+    keylist = keydefs.get(eventname)
+    if not keylist:
+        return ""
+    s = keylist[0]
+    s = re.sub(r"-[a-z]\b", lambda m: m.group().upper(), s)
+    s = re.sub(r"\b\w+\b", lambda m: keynames.get(m.group(), m.group()), s)
+    s = re.sub("Key-", "", s)
+    s = re.sub("Cancel","Ctrl-Break",s)   # dscherer at cmu.edu
+    s = re.sub("Control-", "Ctrl-", s)
+    s = re.sub("-", "+", s)
+    s = re.sub("><", " ", s)
+    s = re.sub("<", "", s)
+    s = re.sub(">", "", s)
+    return s
+
+
+def fixwordbreaks(root):
+    # Make sure that Tk's double-click and next/previous word
+    # operations use our definition of a word (i.e. an identifier)
+    tk = root.tk
+    tk.call('tcl_wordBreakAfter', 'a b', 0) # make sure word.tcl is loaded
+    tk.call('set', 'tcl_wordchars', '[a-zA-Z0-9_]')
+    tk.call('set', 'tcl_nonwordchars', '[^a-zA-Z0-9_]')
+
+
+def test():
+    root = Tk()
+    fixwordbreaks(root)
+    root.withdraw()
+    if sys.argv[1:]:
+        filename = sys.argv[1]
+    else:
+        filename = None
+    edit = EditorWindow(root=root, filename=filename)
+    edit.set_close_hook(root.quit)
+    root.mainloop()
+    root.destroy()
+
+if __name__ == '__main__':
+    test()

Added: vendor/Python/current/Lib/idlelib/FileList.py
===================================================================
--- vendor/Python/current/Lib/idlelib/FileList.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/FileList.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,124 @@
+import os
+from Tkinter import *
+import tkMessageBox
+
+
+class FileList:
+
+    from EditorWindow import EditorWindow  # class variable, may be overridden
+                                           # e.g. by PyShellFileList
+
+    def __init__(self, root):
+        self.root = root
+        self.dict = {}
+        self.inversedict = {}
+        self.vars = {} # For EditorWindow.getrawvar (shared Tcl variables)
+
+    def open(self, filename, action=None):
+        assert filename
+        filename = self.canonize(filename)
+        if os.path.isdir(filename):
+            # This can happen when bad filename is passed on command line:
+            tkMessageBox.showerror(
+                "File Error",
+                "%r is a directory." % (filename,),
+                master=self.root)
+            return None
+        key = os.path.normcase(filename)
+        if self.dict.has_key(key):
+            edit = self.dict[key]
+            edit.top.wakeup()
+            return edit
+        if action:
+            # Don't create window, perform 'action', e.g. open in same window
+            return action(filename)
+        else:
+            return self.EditorWindow(self, filename, key)
+
+    def gotofileline(self, filename, lineno=None):
+        edit = self.open(filename)
+        if edit is not None and lineno is not None:
+            edit.gotoline(lineno)
+
+    def new(self, filename=None):
+        return self.EditorWindow(self, filename)
+
+    def close_all_callback(self, event):
+        for edit in self.inversedict.keys():
+            reply = edit.close()
+            if reply == "cancel":
+                break
+        return "break"
+
+    def close_edit(self, edit):
+        try:
+            key = self.inversedict[edit]
+        except KeyError:
+            print "Don't know this EditorWindow object.  (close)"
+            return
+        if key:
+            del self.dict[key]
+        del self.inversedict[edit]
+        if not self.inversedict:
+            self.root.quit()
+
+    def filename_changed_edit(self, edit):
+        edit.saved_change_hook()
+        try:
+            key = self.inversedict[edit]
+        except KeyError:
+            print "Don't know this EditorWindow object.  (rename)"
+            return
+        filename = edit.io.filename
+        if not filename:
+            if key:
+                del self.dict[key]
+            self.inversedict[edit] = None
+            return
+        filename = self.canonize(filename)
+        newkey = os.path.normcase(filename)
+        if newkey == key:
+            return
+        if self.dict.has_key(newkey):
+            conflict = self.dict[newkey]
+            self.inversedict[conflict] = None
+            tkMessageBox.showerror(
+                "Name Conflict",
+                "You now have multiple edit windows open for %r" % (filename,),
+                master=self.root)
+        self.dict[newkey] = edit
+        self.inversedict[edit] = newkey
+        if key:
+            try:
+                del self.dict[key]
+            except KeyError:
+                pass
+
+    def canonize(self, filename):
+        if not os.path.isabs(filename):
+            try:
+                pwd = os.getcwd()
+            except os.error:
+                pass
+            else:
+                filename = os.path.join(pwd, filename)
+        return os.path.normpath(filename)
+
+
+def _test():
+    from EditorWindow import fixwordbreaks
+    import sys
+    root = Tk()
+    fixwordbreaks(root)
+    root.withdraw()
+    flist = FileList(root)
+    if sys.argv[1:]:
+        for filename in sys.argv[1:]:
+            flist.open(filename)
+    else:
+        flist.new()
+    if flist.inversedict:
+        root.mainloop()
+
+if __name__ == '__main__':
+    _test()

Added: vendor/Python/current/Lib/idlelib/FormatParagraph.py
===================================================================
--- vendor/Python/current/Lib/idlelib/FormatParagraph.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/FormatParagraph.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,148 @@
+# Extension to format a paragraph
+
+# Does basic, standard text formatting, and also understands Python
+# comment blocks.  Thus, for editing Python source code, this
+# extension is really only suitable for reformatting these comment
+# blocks or triple-quoted strings.
+
+# Known problems with comment reformatting:
+# * If there is a selection marked, and the first line of the
+#   selection is not complete, the block will probably not be detected
+#   as comments, and will have the normal "text formatting" rules
+#   applied.
+# * If a comment block has leading whitespace that mixes tabs and
+#   spaces, they will not be considered part of the same block.
+# * Fancy comments, like this bulleted list, arent handled :-)
+
+import re
+from configHandler import idleConf
+
+class FormatParagraph:
+
+    menudefs = [
+        ('format', [   # /s/edit/format   dscherer at cmu.edu
+            ('Format Paragraph', '<<format-paragraph>>'),
+         ])
+    ]
+
+    def __init__(self, editwin):
+        self.editwin = editwin
+
+    def close(self):
+        self.editwin = None
+
+    def format_paragraph_event(self, event):
+        maxformatwidth = int(idleConf.GetOption('main','FormatParagraph','paragraph'))
+        text = self.editwin.text
+        first, last = self.editwin.get_selection_indices()
+        if first and last:
+            data = text.get(first, last)
+            comment_header = ''
+        else:
+            first, last, comment_header, data = \
+                    find_paragraph(text, text.index("insert"))
+        if comment_header:
+            # Reformat the comment lines - convert to text sans header.
+            lines = data.split("\n")
+            lines = map(lambda st, l=len(comment_header): st[l:], lines)
+            data = "\n".join(lines)
+            # Reformat to maxformatwidth chars or a 20 char width, whichever is greater.
+            format_width = max(maxformatwidth - len(comment_header), 20)
+            newdata = reformat_paragraph(data, format_width)
+            # re-split and re-insert the comment header.
+            newdata = newdata.split("\n")
+            # If the block ends in a \n, we dont want the comment
+            # prefix inserted after it. (Im not sure it makes sense to
+            # reformat a comment block that isnt made of complete
+            # lines, but whatever!)  Can't think of a clean soltution,
+            # so we hack away
+            block_suffix = ""
+            if not newdata[-1]:
+                block_suffix = "\n"
+                newdata = newdata[:-1]
+            builder = lambda item, prefix=comment_header: prefix+item
+            newdata = '\n'.join(map(builder, newdata)) + block_suffix
+        else:
+            # Just a normal text format
+            newdata = reformat_paragraph(data, maxformatwidth)
+        text.tag_remove("sel", "1.0", "end")
+        if newdata != data:
+            text.mark_set("insert", first)
+            text.undo_block_start()
+            text.delete(first, last)
+            text.insert(first, newdata)
+            text.undo_block_stop()
+        else:
+            text.mark_set("insert", last)
+        text.see("insert")
+
+def find_paragraph(text, mark):
+    lineno, col = map(int, mark.split("."))
+    line = text.get("%d.0" % lineno, "%d.0 lineend" % lineno)
+    while text.compare("%d.0" % lineno, "<", "end") and is_all_white(line):
+        lineno = lineno + 1
+        line = text.get("%d.0" % lineno, "%d.0 lineend" % lineno)
+    first_lineno = lineno
+    comment_header = get_comment_header(line)
+    comment_header_len = len(comment_header)
+    while get_comment_header(line)==comment_header and \
+              not is_all_white(line[comment_header_len:]):
+        lineno = lineno + 1
+        line = text.get("%d.0" % lineno, "%d.0 lineend" % lineno)
+    last = "%d.0" % lineno
+    # Search back to beginning of paragraph
+    lineno = first_lineno - 1
+    line = text.get("%d.0" % lineno, "%d.0 lineend" % lineno)
+    while lineno > 0 and \
+              get_comment_header(line)==comment_header and \
+              not is_all_white(line[comment_header_len:]):
+        lineno = lineno - 1
+        line = text.get("%d.0" % lineno, "%d.0 lineend" % lineno)
+    first = "%d.0" % (lineno+1)
+    return first, last, comment_header, text.get(first, last)
+
+def reformat_paragraph(data, limit):
+    lines = data.split("\n")
+    i = 0
+    n = len(lines)
+    while i < n and is_all_white(lines[i]):
+        i = i+1
+    if i >= n:
+        return data
+    indent1 = get_indent(lines[i])
+    if i+1 < n and not is_all_white(lines[i+1]):
+        indent2 = get_indent(lines[i+1])
+    else:
+        indent2 = indent1
+    new = lines[:i]
+    partial = indent1
+    while i < n and not is_all_white(lines[i]):
+        # XXX Should take double space after period (etc.) into account
+        words = re.split("(\s+)", lines[i])
+        for j in range(0, len(words), 2):
+            word = words[j]
+            if not word:
+                continue # Can happen when line ends in whitespace
+            if len((partial + word).expandtabs()) > limit and \
+               partial != indent1:
+                new.append(partial.rstrip())
+                partial = indent2
+            partial = partial + word + " "
+            if j+1 < len(words) and words[j+1] != " ":
+                partial = partial + " "
+        i = i+1
+    new.append(partial.rstrip())
+    # XXX Should reformat remaining paragraphs as well
+    new.extend(lines[i:])
+    return "\n".join(new)
+
+def is_all_white(line):
+    return re.match(r"^\s*$", line) is not None
+
+def get_indent(line):
+    return re.match(r"^(\s*)", line).group()
+
+def get_comment_header(line):
+    m = re.match(r"^(\s*#*)", line)
+    if m is None: return ""
+    return m.group(1)

Added: vendor/Python/current/Lib/idlelib/GrepDialog.py
===================================================================
--- vendor/Python/current/Lib/idlelib/GrepDialog.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/GrepDialog.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,133 @@
+import os
+import fnmatch
+import sys
+from Tkinter import *
+import SearchEngine
+from SearchDialogBase import SearchDialogBase
+
+def grep(text, io=None, flist=None):
+    root = text._root()
+    engine = SearchEngine.get(root)
+    if not hasattr(engine, "_grepdialog"):
+        engine._grepdialog = GrepDialog(root, engine, flist)
+    dialog = engine._grepdialog
+    searchphrase = text.get("sel.first", "sel.last")
+    dialog.open(text, searchphrase, io)
+
+class GrepDialog(SearchDialogBase):
+
+    title = "Find in Files Dialog"
+    icon = "Grep"
+    needwrapbutton = 0
+
+    def __init__(self, root, engine, flist):
+        SearchDialogBase.__init__(self, root, engine)
+        self.flist = flist
+        self.globvar = StringVar(root)
+        self.recvar = BooleanVar(root)
+
+    def open(self, text, searchphrase, io=None):
+        SearchDialogBase.open(self, text, searchphrase)
+        if io:
+            path = io.filename or ""
+        else:
+            path = ""
+        dir, base = os.path.split(path)
+        head, tail = os.path.splitext(base)
+        if not tail:
+            tail = ".py"
+        self.globvar.set(os.path.join(dir, "*" + tail))
+
+    def create_entries(self):
+        SearchDialogBase.create_entries(self)
+        self.globent = self.make_entry("In files:", self.globvar)
+
+    def create_other_buttons(self):
+        f = self.make_frame()
+
+        btn = Checkbutton(f, anchor="w",
+                variable=self.recvar,
+                text="Recurse down subdirectories")
+        btn.pack(side="top", fill="both")
+        btn.select()
+
+    def create_command_buttons(self):
+        SearchDialogBase.create_command_buttons(self)
+        self.make_button("Search Files", self.default_command, 1)
+
+    def default_command(self, event=None):
+        prog = self.engine.getprog()
+        if not prog:
+            return
+        path = self.globvar.get()
+        if not path:
+            self.top.bell()
+            return
+        from OutputWindow import OutputWindow
+        save = sys.stdout
+        try:
+            sys.stdout = OutputWindow(self.flist)
+            self.grep_it(prog, path)
+        finally:
+            sys.stdout = save
+
+    def grep_it(self, prog, path):
+        dir, base = os.path.split(path)
+        list = self.findfiles(dir, base, self.recvar.get())
+        list.sort()
+        self.close()
+        pat = self.engine.getpat()
+        print "Searching %r in %s ..." % (pat, path)
+        hits = 0
+        for fn in list:
+            try:
+                f = open(fn)
+            except IOError, msg:
+                print msg
+                continue
+            lineno = 0
+            while 1:
+                block = f.readlines(100000)
+                if not block:
+                    break
+                for line in block:
+                    lineno = lineno + 1
+                    if line[-1:] == '\n':
+                        line = line[:-1]
+                    if prog.search(line):
+                        sys.stdout.write("%s: %s: %s\n" % (fn, lineno, line))
+                        hits = hits + 1
+        if hits:
+            if hits == 1:
+                s = ""
+            else:
+                s = "s"
+            print "Found", hits, "hit%s." % s
+            print "(Hint: right-click to open locations.)"
+        else:
+            print "No hits."
+
+    def findfiles(self, dir, base, rec):
+        try:
+            names = os.listdir(dir or os.curdir)
+        except os.error, msg:
+            print msg
+            return []
+        list = []
+        subdirs = []
+        for name in names:
+            fn = os.path.join(dir, name)
+            if os.path.isdir(fn):
+                subdirs.append(fn)
+            else:
+                if fnmatch.fnmatch(name, base):
+                    list.append(fn)
+        if rec:
+            for subdir in subdirs:
+                list.extend(self.findfiles(subdir, base, rec))
+        return list
+
+    def close(self, event=None):
+        if self.top:
+            self.top.grab_release()
+            self.top.withdraw()

Added: vendor/Python/current/Lib/idlelib/HISTORY.txt
===================================================================
--- vendor/Python/current/Lib/idlelib/HISTORY.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/HISTORY.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,296 @@
+IDLE History
+============
+
+This file contains the release messages for previous IDLE releases.
+As you read on you go back to the dark ages of IDLE's history.
+
+
+What's New in IDLEfork 0.8.1?
+=============================
+
+*Release date: 22-Jul-2001*
+
+- New tarball released as a result of the 'revitalisation' of the IDLEfork
+  project. 
+
+- This release requires python 2.1 or better. Compatability with earlier
+  versions of python (especially ancient ones like 1.5x) is no longer a
+  priority in IDLEfork development.
+
+- This release is based on a merging of the earlier IDLE fork work with current
+  cvs IDLE (post IDLE version 0.8), with some minor additional coding by Kurt
+  B. Kaiser and Stephen M. Gava.
+
+- This release is basically functional but also contains some known breakages,
+  particularly with running things from the shell window. Also the debugger is
+  not working, but I believe this was the case with the previous IDLE fork
+  release (0.7.1) as well.
+
+- This release is being made now to mark the point at which IDLEfork is 
+  launching into a new stage of development. 
+
+- IDLEfork CVS will now be branched to enable further development and
+  exploration of the two "execution in a remote process" patches submitted by
+  David Scherer (David's is currently in IDLEfork) and GvR, while stabilisation
+  and development of less heavyweight improvements (like user customisation)
+  can continue on the trunk.
+
+
+What's New in IDLEfork 0.7.1?
+==============================
+
+*Release date: 15-Aug-2000*
+
+- First project tarball released.
+
+- This was the first release of IDLE fork, which at this stage was a
+  combination of IDLE 0.5 and the VPython idle fork, with additional changes
+  coded by David Scherer, Peter Schneider-Kamp and Nicholas Riley.
+
+
+
+IDLEfork 0.7.1 - 29 May 2000
+-----------------------------
+
+   David Scherer  <dscherer at cmu.edu>
+
+- This is a modification of the CVS version of IDLE 0.5, updated as of
+  2000-03-09.  It is alpha software and might be unstable.  If it breaks, you
+  get to keep both pieces.
+
+- If you have problems or suggestions, you should either contact me or post to
+  the list at http://www.python.org/mailman/listinfo/idle-dev (making it clear
+  that you are using this modified version of IDLE).
+
+- Changes:
+
+  - The ExecBinding module, a replacement for ScriptBinding, executes programs
+    in a separate process, piping standard I/O through an RPC mechanism to an
+    OnDemandOutputWindow in IDLE.  It supports executing unnamed programs
+    (through a temporary file).  It does not yet support debugging.
+
+  - When running programs with ExecBinding, tracebacks will be clipped to
+    exclude system modules.  If, however, a system module calls back into the
+    user program, that part of the traceback will be shown.
+
+  - The OnDemandOutputWindow class has been improved.  In particular, it now
+    supports a readline() function used to implement user input, and a
+    scroll_clear() operation which is used to hide the output of a previous run
+    by scrolling it out of the window.
+
+  - Startup behavior has been changed.  By default IDLE starts up with just a
+    blank editor window, rather than an interactive window.  Opening a file in
+    such a blank window replaces the (nonexistent) contents of that window
+    instead of creating another window.  Because of the need to have a
+    well-known port for the ExecBinding protocol, only one copy of IDLE can be
+    running.  Additional invocations use the RPC mechanism to report their
+    command line arguments to the copy already running.
+
+  - The menus have been reorganized.  In particular, the excessively large
+    'edit' menu has been split up into 'edit', 'format', and 'run'.
+
+  - 'Python Documentation' now works on Windows, if the win32api module is
+    present.
+
+  - A few key bindings have been changed: F1 now loads Python Documentation
+    instead of the IDLE help; shift-TAB is now a synonym for unindent.
+
+- New modules:
+  
+  ExecBinding.py         Executes program through loader
+  loader.py              Bootstraps user program
+  protocol.py            RPC protocol
+  Remote.py              User-process interpreter
+  spawn.py               OS-specific code to start programs
+
+- Files modified:
+
+  autoindent.py          ( bindings tweaked )
+  bindings.py            ( menus reorganized )
+  config.txt             ( execbinding enabled )
+  editorwindow.py        ( new menus, fixed 'Python Documentation' )
+  filelist.py            ( hook for "open in same window" )
+  formatparagraph.py     ( bindings tweaked )
+  idle.bat               ( removed absolute pathname )
+  idle.pyw               ( weird bug due to import with same name? )
+  iobinding.py           ( open in same window, EOL convention )
+  keydefs.py             ( bindings tweaked )
+  outputwindow.py        ( readline, scroll_clear, etc )
+  pyshell.py             ( changed startup behavior )
+  readme.txt             ( <Recursion on file with id=1234567> )
+
+
+
+IDLE 0.5 - February 2000 - Release Notes
+----------------------------------------
+
+This is an early release of IDLE, my own attempt at a Tkinter-based
+IDE for Python.
+
+(For a more detailed change log, see the file ChangeLog.)
+
+FEATURES
+
+IDLE has the following features:
+
+- coded in 100% pure Python, using the Tkinter GUI toolkit (i.e. Tcl/Tk)
+
+- cross-platform: works on Windows and Unix (on the Mac, there are
+currently problems with Tcl/Tk)
+
+- multi-window text editor with multiple undo, Python colorizing
+and many other features, e.g. smart indent and call tips
+
+- Python shell window (a.k.a. interactive interpreter)
+
+- debugger (not complete, but you can set breakpoints, view  and step)
+
+USAGE
+
+The main program is in the file "idle.py"; on Unix, you should be able
+to run it by typing "./idle.py" to your shell.  On Windows, you can
+run it by double-clicking it; you can use idle.pyw to avoid popping up
+a DOS console.  If you want to pass command line arguments on Windows,
+use the batch file idle.bat.
+
+Command line arguments: files passed on the command line are executed,
+not opened for editing, unless you give the -e command line option.
+Try "./idle.py -h" to see other command line options.
+
+IDLE requires Python 1.5.2, so it is currently only usable with a
+Python 1.5.2 distribution.  (An older version of IDLE is distributed
+with Python 1.5.2; you can drop this version on top of it.)
+
+COPYRIGHT
+
+IDLE is covered by the standard Python copyright notice
+(http://www.python.org/doc/Copyright.html).
+
+
+New in IDLE 0.5 (2/15/2000)
+---------------------------
+
+Tons of stuff, much of it contributed by Tim Peters and Mark Hammond:
+
+- Status bar, displaying current line/column (Moshe Zadka).
+
+- Better stack viewer, using tree widget.  (XXX Only used by Stack
+Viewer menu, not by the debugger.)
+
+- Format paragraph now recognizes Python block comments and reformats
+them correctly (MH)
+
+- New version of pyclbr.py parses top-level functions and understands
+much more of Python's syntax; this is reflected in the class and path
+browsers (TP)
+
+- Much better auto-indent; knows how to indent the insides of
+multi-line statements (TP)
+
+- Call tip window pops up when you type the name of a known function
+followed by an open parenthesis.  Hit ESC or click elsewhere in the
+window to close the tip window (MH)
+
+- Comment out region now inserts ## to make it stand out more (TP)
+
+- New path and class browsers based on a tree widget that looks
+familiar to Windows users
+
+- Reworked script running commands to be more intuitive: I/O now
+always goes to the *Python Shell* window, and raw_input() works
+correctly.  You use F5 to import/reload a module: this adds the module
+name to the __main__ namespace.  You use Control-F5 to run a script:
+this runs the script *in* the __main__ namespace.  The latter also
+sets sys.argv[] to the script name
+
+
+New in IDLE 0.4 (4/7/99)
+------------------------
+
+Most important change: a new menu entry "File -> Path browser", shows
+a 4-column hierarchical browser which lets you browse sys.path,
+directories, modules, and classes.  Yes, it's a superset of the Class
+browser menu entry.  There's also a new internal module,
+MultiScrolledLists.py, which provides the framework for this dialog.
+
+
+New in IDLE 0.3 (2/17/99)
+-------------------------
+
+Most important changes:
+
+- Enabled support for running a module, with or without the debugger.
+Output goes to a new window.  Pressing F5 in a module is effectively a
+reload of that module; Control-F5 loads it under the debugger.
+
+- Re-enable tearing off the Windows menu, and make a torn-off Windows
+menu update itself whenever a window is opened or closed.
+
+- Menu items can now be have a checkbox (when the menu label starts
+with "!"); use this for the Debugger and "Auto-open stack viewer"
+(was: JIT stack viewer) menu items.
+
+- Added a Quit button to the Debugger API.
+
+- The current directory is explicitly inserted into sys.path.
+
+- Fix the debugger (when using Python 1.5.2b2) to use canonical
+filenames for breakpoints, so these actually work.  (There's still a
+lot of work to be done to the management of breakpoints in the
+debugger though.)
+
+- Closing a window that is still colorizing now actually works.
+
+- Allow dragging of the separator between the two list boxes in the
+class browser.
+
+- Bind ESC to "close window" of the debugger, stack viewer and class
+browser.  It removes the selection highlighting in regular text
+windows.  (These are standard Windows conventions.)
+
+
+New in IDLE 0.2 (1/8/99)
+------------------------
+
+Lots of changes; here are the highlights:
+
+General:
+
+- You can now write and configure your own IDLE extension modules; see
+extend.txt.
+
+
+File menu:
+
+The command to open the Python shell window is now in the File menu.
+
+
+Edit menu:
+
+New Find dialog with more options; replace dialog; find in files dialog.
+
+Commands to tabify or untabify a region.
+
+Command to format a paragraph.
+
+
+Debug menu:
+
+JIT (Just-In-Time) stack viewer toggle -- if set, the stack viewer
+automaticall pops up when you get a traceback.
+
+Windows menu:
+
+Zoom height -- make the window full height.
+
+
+Help menu:
+
+The help text now show up in a regular window so you can search and
+even edit it if you like.
+
+
+
+IDLE 0.1 was distributed with the Python 1.5.2b1 release on 12/22/98.
+
+======================================================================

Added: vendor/Python/current/Lib/idlelib/HyperParser.py
===================================================================
--- vendor/Python/current/Lib/idlelib/HyperParser.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/HyperParser.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,241 @@
+"""
+HyperParser
+===========
+This module defines the HyperParser class, which provides advanced parsing
+abilities for the ParenMatch and other extensions.
+The HyperParser uses PyParser. PyParser is intended mostly to give information
+on the proper indentation of code. HyperParser gives some information on the
+structure of code, used by extensions to help the user.
+"""
+
+import string
+import keyword
+import PyParse
+
+class HyperParser:
+
+    def __init__(self, editwin, index):
+        """Initialize the HyperParser to analyze the surroundings of the given
+        index.
+        """
+
+        self.editwin = editwin
+        self.text = text = editwin.text
+
+        parser = PyParse.Parser(editwin.indentwidth, editwin.tabwidth)
+
+        def index2line(index):
+            return int(float(index))
+        lno = index2line(text.index(index))
+
+        if not editwin.context_use_ps1:
+            for context in editwin.num_context_lines:
+                startat = max(lno - context, 1)
+                startatindex = `startat` + ".0"
+                stopatindex = "%d.end" % lno
+                # We add the newline because PyParse requires a newline at end.
+                # We add a space so that index won't be at end of line, so that
+                # its status will be the same as the char before it, if should.
+                parser.set_str(text.get(startatindex, stopatindex)+' \n')
+                bod = parser.find_good_parse_start(
+                          editwin._build_char_in_string_func(startatindex))
+                if bod is not None or startat == 1:
+                    break
+            parser.set_lo(bod or 0)
+        else:
+            r = text.tag_prevrange("console", index)
+            if r:
+                startatindex = r[1]
+            else:
+                startatindex = "1.0"
+            stopatindex = "%d.end" % lno
+            # We add the newline because PyParse requires a newline at end.
+            # We add a space so that index won't be at end of line, so that
+            # its status will be the same as the char before it, if should.
+            parser.set_str(text.get(startatindex, stopatindex)+' \n')
+            parser.set_lo(0)
+
+        # We want what the parser has, except for the last newline and space.
+        self.rawtext = parser.str[:-2]
+        # As far as I can see, parser.str preserves the statement we are in,
+        # so that stopatindex can be used to synchronize the string with the
+        # text box indices.
+        self.stopatindex = stopatindex
+        self.bracketing = parser.get_last_stmt_bracketing()
+        # find which pairs of bracketing are openers. These always correspond
+        # to a character of rawtext.
+        self.isopener = [i>0 and self.bracketing[i][1] > self.bracketing[i-1][1]
+                         for i in range(len(self.bracketing))]
+
+        self.set_index(index)
+
+    def set_index(self, index):
+        """Set the index to which the functions relate. Note that it must be
+        in the same statement.
+        """
+        indexinrawtext = \
+            len(self.rawtext) - len(self.text.get(index, self.stopatindex))
+        if indexinrawtext < 0:
+            raise ValueError("The index given is before the analyzed statement")
+        self.indexinrawtext = indexinrawtext
+        # find the rightmost bracket to which index belongs
+        self.indexbracket = 0
+        while self.indexbracket < len(self.bracketing)-1 and \
+              self.bracketing[self.indexbracket+1][0] < self.indexinrawtext:
+            self.indexbracket += 1
+        if self.indexbracket < len(self.bracketing)-1 and \
+           self.bracketing[self.indexbracket+1][0] == self.indexinrawtext and \
+           not self.isopener[self.indexbracket+1]:
+            self.indexbracket += 1
+
+    def is_in_string(self):
+        """Is the index given to the HyperParser is in a string?"""
+        # The bracket to which we belong should be an opener.
+        # If it's an opener, it has to have a character.
+        return self.isopener[self.indexbracket] and \
+               self.rawtext[self.bracketing[self.indexbracket][0]] in ('"', "'")
+
+    def is_in_code(self):
+        """Is the index given to the HyperParser is in a normal code?"""
+        return not self.isopener[self.indexbracket] or \
+               self.rawtext[self.bracketing[self.indexbracket][0]] not in \
+                                                                ('#', '"', "'")
+
+    def get_surrounding_brackets(self, openers='([{', mustclose=False):
+        """If the index given to the HyperParser is surrounded by a bracket
+        defined in openers (or at least has one before it), return the
+        indices of the opening bracket and the closing bracket (or the
+        end of line, whichever comes first).
+        If it is not surrounded by brackets, or the end of line comes before
+        the closing bracket and mustclose is True, returns None.
+        """
+        bracketinglevel = self.bracketing[self.indexbracket][1]
+        before = self.indexbracket
+        while not self.isopener[before] or \
+              self.rawtext[self.bracketing[before][0]] not in openers or \
+              self.bracketing[before][1] > bracketinglevel:
+            before -= 1
+            if before < 0:
+                return None
+            bracketinglevel = min(bracketinglevel, self.bracketing[before][1])
+        after = self.indexbracket + 1
+        while after < len(self.bracketing) and \
+              self.bracketing[after][1] >= bracketinglevel:
+            after += 1
+
+        beforeindex = self.text.index("%s-%dc" %
+            (self.stopatindex, len(self.rawtext)-self.bracketing[before][0]))
+        if after >= len(self.bracketing) or \
+           self.bracketing[after][0] > len(self.rawtext):
+            if mustclose:
+                return None
+            afterindex = self.stopatindex
+        else:
+            # We are after a real char, so it is a ')' and we give the index
+            # before it.
+            afterindex = self.text.index("%s-%dc" %
+                (self.stopatindex,
+                 len(self.rawtext)-(self.bracketing[after][0]-1)))
+
+        return beforeindex, afterindex
+
+    # This string includes all chars that may be in a white space
+    _whitespace_chars = " \t\n\\"
+    # This string includes all chars that may be in an identifier
+    _id_chars = string.ascii_letters + string.digits + "_"
+    # This string includes all chars that may be the first char of an identifier
+    _id_first_chars = string.ascii_letters + "_"
+
+    # Given a string and pos, return the number of chars in the identifier
+    # which ends at pos, or 0 if there is no such one. Saved words are not
+    # identifiers.
+    def _eat_identifier(self, str, limit, pos):
+        i = pos
+        while i > limit and str[i-1] in self._id_chars:
+            i -= 1
+        if i < pos and (str[i] not in self._id_first_chars or \
+                        keyword.iskeyword(str[i:pos])):
+            i = pos
+        return pos - i
+
+    def get_expression(self):
+        """Return a string with the Python expression which ends at the given
+        index, which is empty if there is no real one.
+        """
+        if not self.is_in_code():
+            raise ValueError("get_expression should only be called if index "\
+                             "is inside a code.")
+
+        rawtext = self.rawtext
+        bracketing = self.bracketing
+
+        brck_index = self.indexbracket
+        brck_limit = bracketing[brck_index][0]
+        pos = self.indexinrawtext
+
+        last_identifier_pos = pos
+        postdot_phase = True
+
+        while 1:
+            # Eat whitespaces, comments, and if postdot_phase is False - one dot
+            while 1:
+                if pos>brck_limit and rawtext[pos-1] in self._whitespace_chars:
+                    # Eat a whitespace
+                    pos -= 1
+                elif not postdot_phase and \
+                     pos > brck_limit and rawtext[pos-1] == '.':
+                    # Eat a dot
+                    pos -= 1
+                    postdot_phase = True
+                # The next line will fail if we are *inside* a comment, but we
+                # shouldn't be.
+                elif pos == brck_limit and brck_index > 0 and \
+                     rawtext[bracketing[brck_index-1][0]] == '#':
+                    # Eat a comment
+                    brck_index -= 2
+                    brck_limit = bracketing[brck_index][0]
+                    pos = bracketing[brck_index+1][0]
+                else:
+                    # If we didn't eat anything, quit.
+                    break
+
+            if not postdot_phase:
+                # We didn't find a dot, so the expression end at the last
+                # identifier pos.
+                break
+
+            ret = self._eat_identifier(rawtext, brck_limit, pos)
+            if ret:
+                # There is an identifier to eat
+                pos = pos - ret
+                last_identifier_pos = pos
+                # Now, in order to continue the search, we must find a dot.
+                postdot_phase = False
+                # (the loop continues now)
+
+            elif pos == brck_limit:
+                # We are at a bracketing limit. If it is a closing bracket,
+                # eat the bracket, otherwise, stop the search.
+                level = bracketing[brck_index][1]
+                while brck_index > 0 and bracketing[brck_index-1][1] > level:
+                    brck_index -= 1
+                if bracketing[brck_index][0] == brck_limit:
+                    # We were not at the end of a closing bracket
+                    break
+                pos = bracketing[brck_index][0]
+                brck_index -= 1
+                brck_limit = bracketing[brck_index][0]
+                last_identifier_pos = pos
+                if rawtext[pos] in "([":
+                    # [] and () may be used after an identifier, so we
+                    # continue. postdot_phase is True, so we don't allow a dot.
+                    pass
+                else:
+                    # We can't continue after other types of brackets
+                    break
+
+            else:
+                # We've found an operator or something.
+                break
+
+        return rawtext[last_identifier_pos:self.indexinrawtext]

Added: vendor/Python/current/Lib/idlelib/IOBinding.py
===================================================================
--- vendor/Python/current/Lib/idlelib/IOBinding.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/IOBinding.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,584 @@
+# changes by dscherer at cmu.edu
+#   - IOBinding.open() replaces the current window with the opened file,
+#     if the current window is both unmodified and unnamed
+#   - IOBinding.loadfile() interprets Windows, UNIX, and Macintosh
+#     end-of-line conventions, instead of relying on the standard library,
+#     which will only understand the local convention.
+
+import os
+import types
+import sys
+import codecs
+import tempfile
+import tkFileDialog
+import tkMessageBox
+import re
+from Tkinter import *
+from SimpleDialog import SimpleDialog
+
+from configHandler import idleConf
+
+try:
+    from codecs import BOM_UTF8
+except ImportError:
+    # only available since Python 2.3
+    BOM_UTF8 = '\xef\xbb\xbf'
+
+# Try setting the locale, so that we can find out
+# what encoding to use
+try:
+    import locale
+    locale.setlocale(locale.LC_CTYPE, "")
+except (ImportError, locale.Error):
+    pass
+
+# Encoding for file names
+filesystemencoding = sys.getfilesystemencoding()
+
+encoding = "ascii"
+if sys.platform == 'win32':
+    # On Windows, we could use "mbcs". However, to give the user
+    # a portable encoding name, we need to find the code page
+    try:
+        encoding = locale.getdefaultlocale()[1]
+        codecs.lookup(encoding)
+    except LookupError:
+        pass
+else:
+    try:
+        # Different things can fail here: the locale module may not be
+        # loaded, it may not offer nl_langinfo, or CODESET, or the
+        # resulting codeset may be unknown to Python. We ignore all
+        # these problems, falling back to ASCII
+        encoding = locale.nl_langinfo(locale.CODESET)
+        if encoding is None or encoding is '':
+            # situation occurs on Mac OS X
+            encoding = 'ascii'
+        codecs.lookup(encoding)
+    except (NameError, AttributeError, LookupError):
+        # Try getdefaultlocale well: it parses environment variables,
+        # which may give a clue. Unfortunately, getdefaultlocale has
+        # bugs that can cause ValueError.
+        try:
+            encoding = locale.getdefaultlocale()[1]
+            if encoding is None or encoding is '':
+                # situation occurs on Mac OS X
+                encoding = 'ascii'
+            codecs.lookup(encoding)
+        except (ValueError, LookupError):
+            pass
+
+encoding = encoding.lower()
+
+coding_re = re.compile("coding[:=]\s*([-\w_.]+)")
+
+class EncodingMessage(SimpleDialog):
+    "Inform user that an encoding declaration is needed."
+    def __init__(self, master, enc):
+        self.should_edit = False
+
+        self.root = top = Toplevel(master)
+        top.bind("<Return>", self.return_event)
+        top.bind("<Escape>", self.do_ok)
+        top.protocol("WM_DELETE_WINDOW", self.wm_delete_window)
+        top.wm_title("I/O Warning")
+        top.wm_iconname("I/O Warning")
+        self.top = top
+
+        l1 = Label(top,
+            text="Non-ASCII found, yet no encoding declared. Add a line like")
+        l1.pack(side=TOP, anchor=W)
+        l2 = Entry(top, font="courier")
+        l2.insert(0, "# -*- coding: %s -*-" % enc)
+        # For some reason, the text is not selectable anymore if the
+        # widget is disabled.
+        # l2['state'] = DISABLED
+        l2.pack(side=TOP, anchor = W, fill=X)
+        l3 = Label(top, text="to your file\n"
+                   "Choose OK to save this file as %s\n"
+                   "Edit your general options to silence this warning" % enc)
+        l3.pack(side=TOP, anchor = W)
+
+        buttons = Frame(top)
+        buttons.pack(side=TOP, fill=X)
+        # Both return and cancel mean the same thing: do nothing
+        self.default = self.cancel = 0
+        b1 = Button(buttons, text="Ok", default="active",
+                    command=self.do_ok)
+        b1.pack(side=LEFT, fill=BOTH, expand=1)
+        b2 = Button(buttons, text="Edit my file",
+                    command=self.do_edit)
+        b2.pack(side=LEFT, fill=BOTH, expand=1)
+
+        self._set_transient(master)
+
+    def do_ok(self):
+        self.done(0)
+
+    def do_edit(self):
+        self.done(1)
+
+def coding_spec(str):
+    """Return the encoding declaration according to PEP 263.
+
+    Raise LookupError if the encoding is declared but unknown.
+    """
+    # Only consider the first two lines
+    str = str.split("\n")[:2]
+    str = "\n".join(str)
+
+    match = coding_re.search(str)
+    if not match:
+        return None
+    name = match.group(1)
+    # Check whether the encoding is known
+    import codecs
+    try:
+        codecs.lookup(name)
+    except LookupError:
+        # The standard encoding error does not indicate the encoding
+        raise LookupError, "Unknown encoding "+name
+    return name
+
+
+class IOBinding:
+
+    def __init__(self, editwin):
+        self.editwin = editwin
+        self.text = editwin.text
+        self.__id_open = self.text.bind("<<open-window-from-file>>", self.open)
+        self.__id_save = self.text.bind("<<save-window>>", self.save)
+        self.__id_saveas = self.text.bind("<<save-window-as-file>>",
+                                          self.save_as)
+        self.__id_savecopy = self.text.bind("<<save-copy-of-window-as-file>>",
+                                            self.save_a_copy)
+        self.fileencoding = None
+        self.__id_print = self.text.bind("<<print-window>>", self.print_window)
+
+    def close(self):
+        # Undo command bindings
+        self.text.unbind("<<open-window-from-file>>", self.__id_open)
+        self.text.unbind("<<save-window>>", self.__id_save)
+        self.text.unbind("<<save-window-as-file>>",self.__id_saveas)
+        self.text.unbind("<<save-copy-of-window-as-file>>", self.__id_savecopy)
+        self.text.unbind("<<print-window>>", self.__id_print)
+        # Break cycles
+        self.editwin = None
+        self.text = None
+        self.filename_change_hook = None
+
+    def get_saved(self):
+        return self.editwin.get_saved()
+
+    def set_saved(self, flag):
+        self.editwin.set_saved(flag)
+
+    def reset_undo(self):
+        self.editwin.reset_undo()
+
+    filename_change_hook = None
+
+    def set_filename_change_hook(self, hook):
+        self.filename_change_hook = hook
+
+    filename = None
+    dirname = None
+
+    def set_filename(self, filename):
+        if filename and os.path.isdir(filename):
+            self.filename = None
+            self.dirname = filename
+        else:
+            self.filename = filename
+            self.dirname = None
+            self.set_saved(1)
+            if self.filename_change_hook:
+                self.filename_change_hook()
+
+    def open(self, event=None, editFile=None):
+        if self.editwin.flist:
+            if not editFile:
+                filename = self.askopenfile()
+            else:
+                filename=editFile
+            if filename:
+                # If the current window has no filename and hasn't been
+                # modified, we replace its contents (no loss).  Otherwise
+                # we open a new window.  But we won't replace the
+                # shell window (which has an interp(reter) attribute), which
+                # gets set to "not modified" at every new prompt.
+                try:
+                    interp = self.editwin.interp
+                except:
+                    interp = None
+                if not self.filename and self.get_saved() and not interp:
+                    self.editwin.flist.open(filename, self.loadfile)
+                else:
+                    self.editwin.flist.open(filename)
+            else:
+                self.text.focus_set()
+            return "break"
+        #
+        # Code for use outside IDLE:
+        if self.get_saved():
+            reply = self.maybesave()
+            if reply == "cancel":
+                self.text.focus_set()
+                return "break"
+        if not editFile:
+            filename = self.askopenfile()
+        else:
+            filename=editFile
+        if filename:
+            self.loadfile(filename)
+        else:
+            self.text.focus_set()
+        return "break"
+
+    eol = r"(\r\n)|\n|\r"  # \r\n (Windows), \n (UNIX), or \r (Mac)
+    eol_re = re.compile(eol)
+    eol_convention = os.linesep # Default
+
+    def loadfile(self, filename):
+        try:
+            # open the file in binary mode so that we can handle
+            #   end-of-line convention ourselves.
+            f = open(filename,'rb')
+            chars = f.read()
+            f.close()
+        except IOError, msg:
+            tkMessageBox.showerror("I/O Error", str(msg), master=self.text)
+            return False
+
+        chars = self.decode(chars)
+        # We now convert all end-of-lines to '\n's
+        firsteol = self.eol_re.search(chars)
+        if firsteol:
+            self.eol_convention = firsteol.group(0)
+            if isinstance(self.eol_convention, unicode):
+                # Make sure it is an ASCII string
+                self.eol_convention = self.eol_convention.encode("ascii")
+            chars = self.eol_re.sub(r"\n", chars)
+
+        self.text.delete("1.0", "end")
+        self.set_filename(None)
+        self.text.insert("1.0", chars)
+        self.reset_undo()
+        self.set_filename(filename)
+        self.text.mark_set("insert", "1.0")
+        self.text.see("insert")
+        self.updaterecentfileslist(filename)
+        return True
+
+    def decode(self, chars):
+        """Create a Unicode string
+
+        If that fails, let Tcl try its best
+        """
+        # Check presence of a UTF-8 signature first
+        if chars.startswith(BOM_UTF8):
+            try:
+                chars = chars[3:].decode("utf-8")
+            except UnicodeError:
+                # has UTF-8 signature, but fails to decode...
+                return chars
+            else:
+                # Indicates that this file originally had a BOM
+                self.fileencoding = BOM_UTF8
+                return chars
+        # Next look for coding specification
+        try:
+            enc = coding_spec(chars)
+        except LookupError, name:
+            tkMessageBox.showerror(
+                title="Error loading the file",
+                message="The encoding '%s' is not known to this Python "\
+                "installation. The file may not display correctly" % name,
+                master = self.text)
+            enc = None
+        if enc:
+            try:
+                return unicode(chars, enc)
+            except UnicodeError:
+                pass
+        # If it is ASCII, we need not to record anything
+        try:
+            return unicode(chars, 'ascii')
+        except UnicodeError:
+            pass
+        # Finally, try the locale's encoding. This is deprecated;
+        # the user should declare a non-ASCII encoding
+        try:
+            chars = unicode(chars, encoding)
+            self.fileencoding = encoding
+        except UnicodeError:
+            pass
+        return chars
+
+    def maybesave(self):
+        if self.get_saved():
+            return "yes"
+        message = "Do you want to save %s before closing?" % (
+            self.filename or "this untitled document")
+        m = tkMessageBox.Message(
+            title="Save On Close",
+            message=message,
+            icon=tkMessageBox.QUESTION,
+            type=tkMessageBox.YESNOCANCEL,
+            master=self.text)
+        reply = m.show()
+        if reply == "yes":
+            self.save(None)
+            if not self.get_saved():
+                reply = "cancel"
+        self.text.focus_set()
+        return reply
+
+    def save(self, event):
+        if not self.filename:
+            self.save_as(event)
+        else:
+            if self.writefile(self.filename):
+                self.set_saved(1)
+                try:
+                    self.editwin.store_file_breaks()
+                except AttributeError:  # may be a PyShell
+                    pass
+        self.text.focus_set()
+        return "break"
+
+    def save_as(self, event):
+        filename = self.asksavefile()
+        if filename:
+            if self.writefile(filename):
+                self.set_filename(filename)
+                self.set_saved(1)
+                try:
+                    self.editwin.store_file_breaks()
+                except AttributeError:
+                    pass
+        self.text.focus_set()
+        self.updaterecentfileslist(filename)
+        return "break"
+
+    def save_a_copy(self, event):
+        filename = self.asksavefile()
+        if filename:
+            self.writefile(filename)
+        self.text.focus_set()
+        self.updaterecentfileslist(filename)
+        return "break"
+
+    def writefile(self, filename):
+        self.fixlastline()
+        chars = self.encode(self.text.get("1.0", "end-1c"))
+        if self.eol_convention != "\n":
+            chars = chars.replace("\n", self.eol_convention)
+        try:
+            f = open(filename, "wb")
+            f.write(chars)
+            f.flush()
+            f.close()
+            return True
+        except IOError, msg:
+            tkMessageBox.showerror("I/O Error", str(msg),
+                                   master=self.text)
+            return False
+
+    def encode(self, chars):
+        if isinstance(chars, types.StringType):
+            # This is either plain ASCII, or Tk was returning mixed-encoding
+            # text to us. Don't try to guess further.
+            return chars
+        # See whether there is anything non-ASCII in it.
+        # If not, no need to figure out the encoding.
+        try:
+            return chars.encode('ascii')
+        except UnicodeError:
+            pass
+        # If there is an encoding declared, try this first.
+        try:
+            enc = coding_spec(chars)
+            failed = None
+        except LookupError, msg:
+            failed = msg
+            enc = None
+        if enc:
+            try:
+                return chars.encode(enc)
+            except UnicodeError:
+                failed = "Invalid encoding '%s'" % enc
+        if failed:
+            tkMessageBox.showerror(
+                "I/O Error",
+                "%s. Saving as UTF-8" % failed,
+                master = self.text)
+        # If there was a UTF-8 signature, use that. This should not fail
+        if self.fileencoding == BOM_UTF8 or failed:
+            return BOM_UTF8 + chars.encode("utf-8")
+        # Try the original file encoding next, if any
+        if self.fileencoding:
+            try:
+                return chars.encode(self.fileencoding)
+            except UnicodeError:
+                tkMessageBox.showerror(
+                    "I/O Error",
+                    "Cannot save this as '%s' anymore. Saving as UTF-8" \
+                    % self.fileencoding,
+                    master = self.text)
+                return BOM_UTF8 + chars.encode("utf-8")
+        # Nothing was declared, and we had not determined an encoding
+        # on loading. Recommend an encoding line.
+        config_encoding = idleConf.GetOption("main","EditorWindow",
+                                             "encoding")
+        if config_encoding == 'utf-8':
+            # User has requested that we save files as UTF-8
+            return BOM_UTF8 + chars.encode("utf-8")
+        ask_user = True
+        try:
+            chars = chars.encode(encoding)
+            enc = encoding
+            if config_encoding == 'locale':
+                ask_user = False
+        except UnicodeError:
+            chars = BOM_UTF8 + chars.encode("utf-8")
+            enc = "utf-8"
+        if not ask_user:
+            return chars
+        dialog = EncodingMessage(self.editwin.top, enc)
+        dialog.go()
+        if dialog.num == 1:
+            # User asked us to edit the file
+            encline = "# -*- coding: %s -*-\n" % enc
+            firstline = self.text.get("1.0", "2.0")
+            if firstline.startswith("#!"):
+                # Insert encoding after #! line
+                self.text.insert("2.0", encline)
+            else:
+                self.text.insert("1.0", encline)
+            return self.encode(self.text.get("1.0", "end-1c"))
+        return chars
+
+    def fixlastline(self):
+        c = self.text.get("end-2c")
+        if c != '\n':
+            self.text.insert("end-1c", "\n")
+
+    def print_window(self, event):
+        tempfilename = None
+        saved = self.get_saved()
+        if saved:
+            filename = self.filename
+        # shell undo is reset after every prompt, looks saved, probably isn't
+        if not saved or filename is None:
+            # XXX KBK 08Jun03 Wouldn't it be better to ask the user to save?
+            (tfd, tempfilename) = tempfile.mkstemp(prefix='IDLE_tmp_')
+            filename = tempfilename
+            os.close(tfd)
+            if not self.writefile(tempfilename):
+                os.unlink(tempfilename)
+                return "break"
+        platform=os.name
+        printPlatform=1
+        if platform == 'posix': #posix platform
+            command = idleConf.GetOption('main','General',
+                                         'print-command-posix')
+            command = command + " 2>&1"
+        elif platform == 'nt': #win32 platform
+            command = idleConf.GetOption('main','General','print-command-win')
+        else: #no printing for this platform
+            printPlatform=0
+        if printPlatform:  #we can try to print for this platform
+            command = command % filename
+            pipe = os.popen(command, "r")
+            # things can get ugly on NT if there is no printer available.
+            output = pipe.read().strip()
+            status = pipe.close()
+            if status:
+                output = "Printing failed (exit status 0x%x)\n" % \
+                         status + output
+            if output:
+                output = "Printing command: %s\n" % repr(command) + output
+                tkMessageBox.showerror("Print status", output, master=self.text)
+        else:  #no printing for this platform
+            message="Printing is not enabled for this platform: %s" % platform
+            tkMessageBox.showinfo("Print status", message, master=self.text)
+        if tempfilename:
+            os.unlink(tempfilename)
+        return "break"
+
+    opendialog = None
+    savedialog = None
+
+    filetypes = [
+        ("Python and text files", "*.py *.pyw *.txt", "TEXT"),
+        ("All text files", "*", "TEXT"),
+        ("All files", "*"),
+        ]
+
+    def askopenfile(self):
+        dir, base = self.defaultfilename("open")
+        if not self.opendialog:
+            self.opendialog = tkFileDialog.Open(master=self.text,
+                                                filetypes=self.filetypes)
+        filename = self.opendialog.show(initialdir=dir, initialfile=base)
+        if isinstance(filename, unicode):
+            filename = filename.encode(filesystemencoding)
+        return filename
+
+    def defaultfilename(self, mode="open"):
+        if self.filename:
+            return os.path.split(self.filename)
+        elif self.dirname:
+            return self.dirname, ""
+        else:
+            try:
+                pwd = os.getcwd()
+            except os.error:
+                pwd = ""
+            return pwd, ""
+
+    def asksavefile(self):
+        dir, base = self.defaultfilename("save")
+        if not self.savedialog:
+            self.savedialog = tkFileDialog.SaveAs(master=self.text,
+                                                  filetypes=self.filetypes)
+        filename = self.savedialog.show(initialdir=dir, initialfile=base)
+        if isinstance(filename, unicode):
+            filename = filename.encode(filesystemencoding)
+        return filename
+
+    def updaterecentfileslist(self,filename):
+        "Update recent file list on all editor windows"
+        self.editwin.update_recent_files_list(filename)
+
+def test():
+    root = Tk()
+    class MyEditWin:
+        def __init__(self, text):
+            self.text = text
+            self.flist = None
+            self.text.bind("<Control-o>", self.open)
+            self.text.bind("<Control-s>", self.save)
+            self.text.bind("<Alt-s>", self.save_as)
+            self.text.bind("<Alt-z>", self.save_a_copy)
+        def get_saved(self): return 0
+        def set_saved(self, flag): pass
+        def reset_undo(self): pass
+        def open(self, event):
+            self.text.event_generate("<<open-window-from-file>>")
+        def save(self, event):
+            self.text.event_generate("<<save-window>>")
+        def save_as(self, event):
+            self.text.event_generate("<<save-window-as-file>>")
+        def save_a_copy(self, event):
+            self.text.event_generate("<<save-copy-of-window-as-file>>")
+    text = Text(root)
+    text.pack()
+    text.focus_set()
+    editwin = MyEditWin(text)
+    io = IOBinding(editwin)
+    root.mainloop()
+
+if __name__ == "__main__":
+    test()

Added: vendor/Python/current/Lib/idlelib/Icons/folder.gif
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Lib/idlelib/Icons/folder.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Lib/idlelib/Icons/idle.icns
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Lib/idlelib/Icons/idle.icns
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Lib/idlelib/Icons/minusnode.gif
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Lib/idlelib/Icons/minusnode.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Lib/idlelib/Icons/openfolder.gif
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Lib/idlelib/Icons/openfolder.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Lib/idlelib/Icons/plusnode.gif
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Lib/idlelib/Icons/plusnode.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Lib/idlelib/Icons/python.gif
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Lib/idlelib/Icons/python.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Lib/idlelib/Icons/tk.gif
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Lib/idlelib/Icons/tk.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Lib/idlelib/IdleHistory.py
===================================================================
--- vendor/Python/current/Lib/idlelib/IdleHistory.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/IdleHistory.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,88 @@
+from configHandler import idleConf
+
+class History:
+
+    def __init__(self, text, output_sep = "\n"):
+        self.text = text
+        self.history = []
+        self.history_prefix = None
+        self.history_pointer = None
+        self.output_sep = output_sep
+        self.cyclic = idleConf.GetOption("main", "History", "cyclic", 1, "bool")
+        text.bind("<<history-previous>>", self.history_prev)
+        text.bind("<<history-next>>", self.history_next)
+
+    def history_next(self, event):
+        self.history_do(0)
+        return "break"
+
+    def history_prev(self, event):
+        self.history_do(1)
+        return "break"
+
+    def _get_source(self, start, end):
+        # Get source code from start index to end index.  Lines in the
+        # text control may be separated by sys.ps2 .
+        lines = self.text.get(start, end).split(self.output_sep)
+        return "\n".join(lines)
+
+    def _put_source(self, where, source):
+        output = self.output_sep.join(source.split("\n"))
+        self.text.insert(where, output)
+
+    def history_do(self, reverse):
+        nhist = len(self.history)
+        pointer = self.history_pointer
+        prefix = self.history_prefix
+        if pointer is not None and prefix is not None:
+            if self.text.compare("insert", "!=", "end-1c") or \
+               self._get_source("iomark", "end-1c") != self.history[pointer]:
+                pointer = prefix = None
+        if pointer is None or prefix is None:
+            prefix = self._get_source("iomark", "end-1c")
+            if reverse:
+                pointer = nhist
+            else:
+                if self.cyclic:
+                    pointer = -1
+                else:
+                    self.text.bell()
+                    return
+        nprefix = len(prefix)
+        while 1:
+            if reverse:
+                pointer = pointer - 1
+            else:
+                pointer = pointer + 1
+            if pointer < 0 or pointer >= nhist:
+                self.text.bell()
+                if not self.cyclic and pointer < 0:
+                    return
+                else:
+                    if self._get_source("iomark", "end-1c") != prefix:
+                        self.text.delete("iomark", "end-1c")
+                        self._put_source("iomark", prefix)
+                    pointer = prefix = None
+                break
+            item = self.history[pointer]
+            if item[:nprefix] == prefix and len(item) > nprefix:
+                self.text.delete("iomark", "end-1c")
+                self._put_source("iomark", item)
+                break
+        self.text.mark_set("insert", "end-1c")
+        self.text.see("insert")
+        self.text.tag_remove("sel", "1.0", "end")
+        self.history_pointer = pointer
+        self.history_prefix = prefix
+
+    def history_store(self, source):
+        source = source.strip()
+        if len(source) > 2:
+            # avoid duplicates
+            try:
+                self.history.remove(source)
+            except ValueError:
+                pass
+            self.history.append(source)
+        self.history_pointer = None
+        self.history_prefix = None

Added: vendor/Python/current/Lib/idlelib/MultiCall.py
===================================================================
--- vendor/Python/current/Lib/idlelib/MultiCall.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/MultiCall.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,406 @@
+"""
+MultiCall - a class which inherits its methods from a Tkinter widget (Text, for
+example), but enables multiple calls of functions per virtual event - all
+matching events will be called, not only the most specific one. This is done
+by wrapping the event functions - event_add, event_delete and event_info.
+MultiCall recognizes only a subset of legal event sequences. Sequences which
+are not recognized are treated by the original Tk handling mechanism. A
+more-specific event will be called before a less-specific event.
+
+The recognized sequences are complete one-event sequences (no emacs-style
+Ctrl-X Ctrl-C, no shortcuts like <3>), for all types of events.
+Key/Button Press/Release events can have modifiers.
+The recognized modifiers are Shift, Control, Option and Command for Mac, and
+Control, Alt, Shift, Meta/M for other platforms.
+
+For all events which were handled by MultiCall, a new member is added to the
+event instance passed to the binded functions - mc_type. This is one of the
+event type constants defined in this module (such as MC_KEYPRESS).
+For Key/Button events (which are handled by MultiCall and may receive
+modifiers), another member is added - mc_state. This member gives the state
+of the recognized modifiers, as a combination of the modifier constants
+also defined in this module (for example, MC_SHIFT).
+Using these members is absolutely portable.
+
+The order by which events are called is defined by these rules:
+1. A more-specific event will be called before a less-specific event.
+2. A recently-binded event will be called before a previously-binded event,
+   unless this conflicts with the first rule.
+Each function will be called at most once for each event.
+"""
+
+import sys
+import os
+import string
+import re
+import Tkinter
+
+# the event type constants, which define the meaning of mc_type
+MC_KEYPRESS=0; MC_KEYRELEASE=1; MC_BUTTONPRESS=2; MC_BUTTONRELEASE=3;
+MC_ACTIVATE=4; MC_CIRCULATE=5; MC_COLORMAP=6; MC_CONFIGURE=7;
+MC_DEACTIVATE=8; MC_DESTROY=9; MC_ENTER=10; MC_EXPOSE=11; MC_FOCUSIN=12;
+MC_FOCUSOUT=13; MC_GRAVITY=14; MC_LEAVE=15; MC_MAP=16; MC_MOTION=17;
+MC_MOUSEWHEEL=18; MC_PROPERTY=19; MC_REPARENT=20; MC_UNMAP=21; MC_VISIBILITY=22;
+# the modifier state constants, which define the meaning of mc_state
+MC_SHIFT = 1<<0; MC_CONTROL = 1<<2; MC_ALT = 1<<3; MC_META = 1<<5
+MC_OPTION = 1<<6; MC_COMMAND = 1<<7
+
+# define the list of modifiers, to be used in complex event types.
+if sys.platform == "darwin" and sys.executable.count(".app"):
+    _modifiers = (("Shift",), ("Control",), ("Option",), ("Command",))
+    _modifier_masks = (MC_SHIFT, MC_CONTROL, MC_OPTION, MC_COMMAND)
+else:
+    _modifiers = (("Control",), ("Alt",), ("Shift",), ("Meta", "M"))
+    _modifier_masks = (MC_CONTROL, MC_ALT, MC_SHIFT, MC_META)
+
+# a dictionary to map a modifier name into its number
+_modifier_names = dict([(name, number)
+                         for number in range(len(_modifiers))
+                         for name in _modifiers[number]])
+
+# A binder is a class which binds functions to one type of event. It has two
+# methods: bind and unbind, which get a function and a parsed sequence, as
+# returned by _parse_sequence(). There are two types of binders:
+# _SimpleBinder handles event types with no modifiers and no detail.
+# No Python functions are called when no events are binded.
+# _ComplexBinder handles event types with modifiers and a detail.
+# A Python function is called each time an event is generated.
+
+class _SimpleBinder:
+    def __init__(self, type, widget, widgetinst):
+        self.type = type
+        self.sequence = '<'+_types[type][0]+'>'
+        self.widget = widget
+        self.widgetinst = widgetinst
+        self.bindedfuncs = []
+        self.handlerid = None
+
+    def bind(self, triplet, func):
+        if not self.handlerid:
+            def handler(event, l = self.bindedfuncs, mc_type = self.type):
+                event.mc_type = mc_type
+                wascalled = {}
+                for i in range(len(l)-1, -1, -1):
+                    func = l[i]
+                    if func not in wascalled:
+                        wascalled[func] = True
+                        r = func(event)
+                        if r:
+                            return r
+            self.handlerid = self.widget.bind(self.widgetinst,
+                                              self.sequence, handler)
+        self.bindedfuncs.append(func)
+
+    def unbind(self, triplet, func):
+        self.bindedfuncs.remove(func)
+        if not self.bindedfuncs:
+            self.widget.unbind(self.widgetinst, self.sequence, self.handlerid)
+            self.handlerid = None
+
+    def __del__(self):
+        if self.handlerid:
+            self.widget.unbind(self.widgetinst, self.sequence, self.handlerid)
+
+# An int in range(1 << len(_modifiers)) represents a combination of modifiers
+# (if the least significent bit is on, _modifiers[0] is on, and so on).
+# _state_subsets gives for each combination of modifiers, or *state*,
+# a list of the states which are a subset of it. This list is ordered by the
+# number of modifiers is the state - the most specific state comes first.
+_states = range(1 << len(_modifiers))
+_state_names = [reduce(lambda x, y: x + y,
+                       [_modifiers[i][0]+'-' for i in range(len(_modifiers))
+                        if (1 << i) & s],
+                       "")
+                for s in _states]
+_state_subsets = map(lambda i: filter(lambda j: not (j & (~i)), _states),
+                      _states)
+for l in _state_subsets:
+    l.sort(lambda a, b, nummod = lambda x: len(filter(lambda i: (1<<i) & x,
+                                                      range(len(_modifiers)))):
+           nummod(b) - nummod(a))
+# _state_codes gives for each state, the portable code to be passed as mc_state
+_state_codes = [reduce(lambda x, y: x | y,
+                       [_modifier_masks[i] for i in range(len(_modifiers))
+                        if (1 << i) & s],
+                       0)
+                for s in _states]
+
+class _ComplexBinder:
+    # This class binds many functions, and only unbinds them when it is deleted.
+    # self.handlerids is the list of seqs and ids of binded handler functions.
+    # The binded functions sit in a dictionary of lists of lists, which maps
+    # a detail (or None) and a state into a list of functions.
+    # When a new detail is discovered, handlers for all the possible states
+    # are binded.
+
+    def __create_handler(self, lists, mc_type, mc_state):
+        def handler(event, lists = lists,
+                    mc_type = mc_type, mc_state = mc_state,
+                    ishandlerrunning = self.ishandlerrunning,
+                    doafterhandler = self.doafterhandler):
+            ishandlerrunning[:] = [True]
+            event.mc_type = mc_type
+            event.mc_state = mc_state
+            wascalled = {}
+            r = None
+            for l in lists:
+                for i in range(len(l)-1, -1, -1):
+                    func = l[i]
+                    if func not in wascalled:
+                        wascalled[func] = True
+                        r = l[i](event)
+                        if r:
+                            break
+                if r:
+                    break
+            ishandlerrunning[:] = []
+            # Call all functions in doafterhandler and remove them from list
+            while doafterhandler:
+                doafterhandler.pop()()
+            if r:
+                return r
+        return handler
+
+    def __init__(self, type, widget, widgetinst):
+        self.type = type
+        self.typename = _types[type][0]
+        self.widget = widget
+        self.widgetinst = widgetinst
+        self.bindedfuncs = {None: [[] for s in _states]}
+        self.handlerids = []
+        # we don't want to change the lists of functions while a handler is
+        # running - it will mess up the loop and anyway, we usually want the
+        # change to happen from the next event. So we have a list of functions
+        # for the handler to run after it finishes calling the binded functions.
+        # It calls them only once.
+        # ishandlerrunning is a list. An empty one means no, otherwise - yes.
+        # this is done so that it would be mutable.
+        self.ishandlerrunning = []
+        self.doafterhandler = []
+        for s in _states:
+            lists = [self.bindedfuncs[None][i] for i in _state_subsets[s]]
+            handler = self.__create_handler(lists, type, _state_codes[s])
+            seq = '<'+_state_names[s]+self.typename+'>'
+            self.handlerids.append((seq, self.widget.bind(self.widgetinst,
+                                                          seq, handler)))
+
+    def bind(self, triplet, func):
+        if not self.bindedfuncs.has_key(triplet[2]):
+            self.bindedfuncs[triplet[2]] = [[] for s in _states]
+            for s in _states:
+                lists = [ self.bindedfuncs[detail][i]
+                          for detail in (triplet[2], None)
+                          for i in _state_subsets[s]       ]
+                handler = self.__create_handler(lists, self.type,
+                                                _state_codes[s])
+                seq = "<%s%s-%s>"% (_state_names[s], self.typename, triplet[2])
+                self.handlerids.append((seq, self.widget.bind(self.widgetinst,
+                                                              seq, handler)))
+        doit = lambda: self.bindedfuncs[triplet[2]][triplet[0]].append(func)
+        if not self.ishandlerrunning:
+            doit()
+        else:
+            self.doafterhandler.append(doit)
+
+    def unbind(self, triplet, func):
+        doit = lambda: self.bindedfuncs[triplet[2]][triplet[0]].remove(func)
+        if not self.ishandlerrunning:
+            doit()
+        else:
+            self.doafterhandler.append(doit)
+
+    def __del__(self):
+        for seq, id in self.handlerids:
+            self.widget.unbind(self.widgetinst, seq, id)
+
+# define the list of event types to be handled by MultiEvent. the order is
+# compatible with the definition of event type constants.
+_types = (
+    ("KeyPress", "Key"), ("KeyRelease",), ("ButtonPress", "Button"),
+    ("ButtonRelease",), ("Activate",), ("Circulate",), ("Colormap",),
+    ("Configure",), ("Deactivate",), ("Destroy",), ("Enter",), ("Expose",),
+    ("FocusIn",), ("FocusOut",), ("Gravity",), ("Leave",), ("Map",),
+    ("Motion",), ("MouseWheel",), ("Property",), ("Reparent",), ("Unmap",),
+    ("Visibility",),
+)
+
+# which binder should be used for every event type?
+_binder_classes = (_ComplexBinder,) * 4 + (_SimpleBinder,) * (len(_types)-4)
+
+# A dictionary to map a type name into its number
+_type_names = dict([(name, number)
+                     for number in range(len(_types))
+                     for name in _types[number]])
+
+_keysym_re = re.compile(r"^\w+$")
+_button_re = re.compile(r"^[1-5]$")
+def _parse_sequence(sequence):
+    """Get a string which should describe an event sequence. If it is
+    successfully parsed as one, return a tuple containing the state (as an int),
+    the event type (as an index of _types), and the detail - None if none, or a
+    string if there is one. If the parsing is unsuccessful, return None.
+    """
+    if not sequence or sequence[0] != '<' or sequence[-1] != '>':
+        return None
+    words = string.split(sequence[1:-1], '-')
+
+    modifiers = 0
+    while words and words[0] in _modifier_names:
+        modifiers |= 1 << _modifier_names[words[0]]
+        del words[0]
+
+    if words and words[0] in _type_names:
+        type = _type_names[words[0]]
+        del words[0]
+    else:
+        return None
+
+    if _binder_classes[type] is _SimpleBinder:
+        if modifiers or words:
+            return None
+        else:
+            detail = None
+    else:
+        # _ComplexBinder
+        if type in [_type_names[s] for s in ("KeyPress", "KeyRelease")]:
+            type_re = _keysym_re
+        else:
+            type_re = _button_re
+
+        if not words:
+            detail = None
+        elif len(words) == 1 and type_re.match(words[0]):
+            detail = words[0]
+        else:
+            return None
+
+    return modifiers, type, detail
+
+def _triplet_to_sequence(triplet):
+    if triplet[2]:
+        return '<'+_state_names[triplet[0]]+_types[triplet[1]][0]+'-'+ \
+               triplet[2]+'>'
+    else:
+        return '<'+_state_names[triplet[0]]+_types[triplet[1]][0]+'>'
+
+_multicall_dict = {}
+def MultiCallCreator(widget):
+    """Return a MultiCall class which inherits its methods from the
+    given widget class (for example, Tkinter.Text). This is used
+    instead of a templating mechanism.
+    """
+    if widget in _multicall_dict:
+        return _multicall_dict[widget]
+
+    class MultiCall (widget):
+        assert issubclass(widget, Tkinter.Misc)
+
+        def __init__(self, *args, **kwargs):
+            apply(widget.__init__, (self,)+args, kwargs)
+            # a dictionary which maps a virtual event to a tuple with:
+            #  0. the function binded
+            #  1. a list of triplets - the sequences it is binded to
+            self.__eventinfo = {}
+            self.__binders = [_binder_classes[i](i, widget, self)
+                              for i in range(len(_types))]
+
+        def bind(self, sequence=None, func=None, add=None):
+            #print "bind(%s, %s, %s) called." % (sequence, func, add)
+            if type(sequence) is str and len(sequence) > 2 and \
+               sequence[:2] == "<<" and sequence[-2:] == ">>":
+                if sequence in self.__eventinfo:
+                    ei = self.__eventinfo[sequence]
+                    if ei[0] is not None:
+                        for triplet in ei[1]:
+                            self.__binders[triplet[1]].unbind(triplet, ei[0])
+                    ei[0] = func
+                    if ei[0] is not None:
+                        for triplet in ei[1]:
+                            self.__binders[triplet[1]].bind(triplet, func)
+                else:
+                    self.__eventinfo[sequence] = [func, []]
+            return widget.bind(self, sequence, func, add)
+
+        def unbind(self, sequence, funcid=None):
+            if type(sequence) is str and len(sequence) > 2 and \
+               sequence[:2] == "<<" and sequence[-2:] == ">>" and \
+               sequence in self.__eventinfo:
+                func, triplets = self.__eventinfo[sequence]
+                if func is not None:
+                    for triplet in triplets:
+                        self.__binders[triplet[1]].unbind(triplet, func)
+                    self.__eventinfo[sequence][0] = None
+            return widget.unbind(self, sequence, funcid)
+
+        def event_add(self, virtual, *sequences):
+            #print "event_add(%s,%s) was called"%(repr(virtual),repr(sequences))
+            if virtual not in self.__eventinfo:
+                self.__eventinfo[virtual] = [None, []]
+
+            func, triplets = self.__eventinfo[virtual]
+            for seq in sequences:
+                triplet = _parse_sequence(seq)
+                if triplet is None:
+                    #print >> sys.stderr, "Seq. %s was added by Tkinter."%seq
+                    widget.event_add(self, virtual, seq)
+                else:
+                    if func is not None:
+                        self.__binders[triplet[1]].bind(triplet, func)
+                    triplets.append(triplet)
+
+        def event_delete(self, virtual, *sequences):
+            if virtual not in self.__eventinfo:
+                return
+            func, triplets = self.__eventinfo[virtual]
+            for seq in sequences:
+                triplet = _parse_sequence(seq)
+                if triplet is None:
+                    #print >> sys.stderr, "Seq. %s was deleted by Tkinter."%seq
+                    widget.event_delete(self, virtual, seq)
+                else:
+                    if func is not None:
+                        self.__binders[triplet[1]].unbind(triplet, func)
+                    triplets.remove(triplet)
+
+        def event_info(self, virtual=None):
+            if virtual is None or virtual not in self.__eventinfo:
+                return widget.event_info(self, virtual)
+            else:
+                return tuple(map(_triplet_to_sequence,
+                                 self.__eventinfo[virtual][1])) + \
+                       widget.event_info(self, virtual)
+
+        def __del__(self):
+            for virtual in self.__eventinfo:
+                func, triplets = self.__eventinfo[virtual]
+                if func:
+                    for triplet in triplets:
+                        self.__binders[triplet[1]].unbind(triplet, func)
+
+
+    _multicall_dict[widget] = MultiCall
+    return MultiCall
+
+if __name__ == "__main__":
+    # Test
+    root = Tkinter.Tk()
+    text = MultiCallCreator(Tkinter.Text)(root)
+    text.pack()
+    def bindseq(seq, n=[0]):
+        def handler(event):
+            print seq
+        text.bind("<<handler%d>>"%n[0], handler)
+        text.event_add("<<handler%d>>"%n[0], seq)
+        n[0] += 1
+    bindseq("<Key>")
+    bindseq("<Control-Key>")
+    bindseq("<Alt-Key-a>")
+    bindseq("<Control-Key-a>")
+    bindseq("<Alt-Control-Key-a>")
+    bindseq("<Key-b>")
+    bindseq("<Control-Button-1>")
+    bindseq("<Alt-Button-1>")
+    bindseq("<FocusOut>")
+    bindseq("<Enter>")
+    bindseq("<Leave>")
+    root.mainloop()

Added: vendor/Python/current/Lib/idlelib/MultiStatusBar.py
===================================================================
--- vendor/Python/current/Lib/idlelib/MultiStatusBar.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/MultiStatusBar.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,32 @@
+from Tkinter import *
+
+class MultiStatusBar(Frame):
+
+    def __init__(self, master=None, **kw):
+        if master is None:
+            master = Tk()
+        Frame.__init__(self, master, **kw)
+        self.labels = {}
+
+    def set_label(self, name, text='', side=LEFT):
+        if not self.labels.has_key(name):
+            label = Label(self, bd=1, relief=SUNKEN, anchor=W)
+            label.pack(side=side)
+            self.labels[name] = label
+        else:
+            label = self.labels[name]
+        label.config(text=text)
+
+def _test():
+    b = Frame()
+    c = Text(b)
+    c.pack(side=TOP)
+    a = MultiStatusBar(b)
+    a.set_label("one", "hello")
+    a.set_label("two", "world")
+    a.pack(side=BOTTOM, fill=X)
+    b.pack()
+    b.mainloop()
+
+if __name__ == '__main__':
+    _test()

Added: vendor/Python/current/Lib/idlelib/NEWS.txt
===================================================================
--- vendor/Python/current/Lib/idlelib/NEWS.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/NEWS.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,613 @@
+What's New in IDLE 1.2.1?
+=========================
+
+*Release date: 18-APR-2007*
+
+What's New in IDLE 1.2.1c1?
+===========================
+
+*Release date: 05-APR-2007*
+
+What's New in IDLE 1.2?
+=======================
+
+*Release date: 19-SEP-2006*
+
+What's New in IDLE 1.2c2?
+=========================
+
+*Release date: 12-SEP-2006*
+
+What's New in IDLE 1.2c1?
+=========================
+
+*Release date: 17-AUG-2006*
+
+- File menu hotkeys: there were three 'p' assignments.  Reassign the
+  'Save Copy As' and 'Print' hotkeys to 'y' and 't'.  Change the
+  Shell hotkey from 's' to 'l'.
+
+- IDLE honors new quit() and exit() commands from site.py Quitter() object.
+  Patch 1540892, Jim Jewett
+
+- The 'with' statement is now a Code Context block opener.
+  Patch 1540851, Jim Jewett
+
+- Retrieval of previous shell command was not always preserving indentation
+  (since 1.2a1) Patch 1528468 Tal Einat.
+
+- Changing tokenize (39046) to detect dedent broke tabnanny check (since 1.2a1)
+
+- ToggleTab dialog was setting indent to 8 even if cancelled (since 1.2a1).
+
+- When used w/o subprocess, all exceptions were preceded by an error
+  message claiming they were IDLE internal errors (since 1.2a1).
+
+What's New in IDLE 1.2b3?
+=========================
+
+*Release date: 03-AUG-2006*
+
+- EditorWindow.test() was failing.  Bug 1417598
+
+- EditorWindow failed when used stand-alone if sys.ps1 not set.
+  Bug 1010370 Dave Florek
+
+- Tooltips failed on new-syle class __init__ args.  Bug 1027566 Loren Guthrie
+
+- Avoid occasional failure to detect closing paren properly.
+  Patch 1407280 Tal Einat
+
+- Rebinding Tab key was inserting 'tab' instead of 'Tab'.  Bug 1179168.
+
+- Colorizer now handles #<builtin> correctly, also unicode strings and
+  'as' keyword in comment directly following import command. Closes 1325071.
+  Patch 1479219 Tal Einat
+
+What's New in IDLE 1.2b2?
+=========================
+
+*Release date: 11-JUL-2006*
+
+What's New in IDLE 1.2b1?
+=========================
+
+*Release date: 20-JUN-2006*
+
+What's New in IDLE 1.2a2?
+=========================
+
+*Release date: 27-APR-2006*
+
+What's New in IDLE 1.2a1?
+=========================
+
+*Release date: 05-APR-2006*
+
+- Source file f.flush() after writing; trying to avoid lossage if user
+  kills GUI.
+
+- Options / Keys / Advanced dialog made functional.  Also, allow binding
+  of 'movement' keys.
+
+- 'syntax' patch adds improved calltips and a new class attribute listbox.
+  MultiCall module allows binding multiple actions to an event.
+  Patch 906702 Noam Raphael
+
+- Better indentation after first line of string continuation.
+  IDLEfork Patch 681992, Noam Raphael
+
+- Fixed CodeContext alignment problem, following suggestion from Tal Einat.
+
+- Increased performance in CodeContext extension  Patch 936169 Noam Raphael
+
+- Mac line endings were incorrect when pasting code from some browsers
+  when using X11 and the Fink distribution.  Python Bug 1263656.
+
+- <Enter> when cursor is on a previous command retrieves that command.  Instead
+  of replacing the input line, the previous command is now appended to the
+  input line. Indentation is preserved, and undo is enabled.
+  Patch 1196917  Jeff Shute
+
+- Clarify "tab/space" Error Dialog and "Tab Width" Dialog associated with
+  the Untabify command.
+
+- Corrected "tab/space" Error Dialog to show correct menu for Untabify.
+  Patch 1196980 Jeff Shute
+
+- New files are colorized by default, and colorizing is removed when
+  saving as non-Python files. Patch 1196895 Jeff Shute
+  Closes Python Bugs 775012 and 800432, partial fix IDLEfork 763524
+
+- Improve subprocess link error notification.
+
+- run.py: use Queue's blocking feature instead of sleeping in the main
+  loop.  Patch # 1190163 Michiel de Hoon
+
+- Add config-main option to make the 'history' feature non-cyclic.
+  Default remains cyclic.  Python Patch 914546 Noam Raphael.
+
+- Removed ability to configure tabs indent from Options dialog.  This 'feature'
+  has never worked and no one has complained.  It is still possible to set a
+  default tabs (v. spaces) indent 'manually' via config-main.def (or to turn on
+  tabs for the current EditorWindow via the Format menu) but IDLE will
+  encourage indentation via spaces.
+
+- Enable setting the indentation width using the Options dialog.
+  Bug # 783877
+
+- Add keybindings for del-word-left and del-word-right.
+
+- Discourage using an indent width other than 8 when using tabs to indent
+  Python code.
+
+- Restore use of EditorWindow.set_indentation_params(), was dead code since
+  Autoindent was merged into EditorWindow.  This allows IDLE to conform to the
+  indentation width of a loaded file.  (But it still will not switch to tabs
+  even if the file uses tabs.)  Any change in indent width is local to that
+  window.
+
+- Add Tabnanny check before Run/F5, not just when Checking module.
+
+- If an extension can't be loaded, print warning and skip it instead of
+  erroring out.
+
+- Improve error handling when .idlerc can't be created (warn and exit).
+
+- The GUI was hanging if the shell window was closed while a raw_input()
+  was pending.  Restored the quit() of the readline() mainloop().
+  http://mail.python.org/pipermail/idle-dev/2004-December/002307.html
+
+- The remote procedure call module rpc.py can now access data attributes of
+  remote registered objects.  Changes to these attributes are local, however.
+
+What's New in IDLE 1.1?
+=======================
+
+*Release date: 30-NOV-2004*
+
+- On OpenBSD, terminating IDLE with ctrl-c from the command line caused a
+  stuck subprocess MainThread because only the SocketThread was exiting.
+
+What's New in IDLE 1.1b3/rc1?
+=============================
+
+*Release date: 18-NOV-2004*
+
+- Saving a Keyset w/o making changes (by using the "Save as New Custom Key Set"
+  button) caused IDLE to fail on restart (no new keyset was created in
+  config-keys.cfg).  Also true for Theme/highlights.  Python Bug 1064535.
+
+- A change to the linecache.py API caused IDLE to exit when an exception was
+  raised while running without the subprocess (-n switch).  Python Bug 1063840.
+
+What's New in IDLE 1.1b2?
+=========================
+
+*Release date: 03-NOV-2004*
+
+- When paragraph reformat width was made configurable, a bug was
+  introduced that caused reformatting of comment blocks to ignore how
+  far the block was indented, effectively adding the indentation width
+  to the reformat width.  This has been repaired, and the reformat
+  width is again a bound on the total width of reformatted lines.
+
+What's New in IDLE 1.1b1?
+=========================
+
+*Release date: 15-OCT-2004*
+
+
+What's New in IDLE 1.1a3?
+=========================
+
+*Release date: 02-SEP-2004*
+
+- Improve keyboard focus binding, especially in Windows menu.  Improve
+  window raising, especially in the Windows menu and in the debugger.
+  IDLEfork 763524.
+
+- If user passes a non-existant filename on the commandline, just
+  open a new file, don't raise a dialog.  IDLEfork 854928.
+
+
+What's New in IDLE 1.1a2?
+=========================
+
+*Release date: 05-AUG-2004*
+
+- EditorWindow.py was not finding the .chm help file on Windows.  Typo
+  at Rev 1.54.  Python Bug 990954
+
+- checking sys.platform for substring 'win' was breaking IDLE docs on Mac
+  (darwin).  Also, Mac Safari browser requires full file:// URIs.  SF 900580.
+
+
+What's New in IDLE 1.1a1?
+=========================
+
+*Release date: 08-JUL-2004*
+
+- Redirect the warning stream to the shell during the ScriptBinding check of
+  user code and format the warning similarly to an exception for both that
+  check and for runtime warnings raised in the subprocess.
+
+- CodeContext hint pane visibility state is now persistent across sessions.
+  The pane no longer appears in the shell window.  Added capability to limit
+  extensions to shell window or editor windows.  Noam Raphael addition
+  to Patch 936169.
+
+- Paragraph reformat width is now a configurable parameter in the
+  Options GUI.
+
+- New Extension: CodeContext.  Provides block structuring hints for code
+  which has scrolled above an edit window. Patch 936169 Noam Raphael.
+
+- If nulls somehow got into the strings in recent-files.lst
+  EditorWindow.update_recent_files_list() was failing.  Python Bug 931336.
+
+- If the normal background is changed via Configure/Highlighting, it will
+  update immediately, thanks to the previously mentioned patch by Nigel Rowe.
+
+- Add a highlight theme for builtin keywords.  Python Patch 805830 Nigel Rowe
+  This also fixed IDLEfork bug [ 693418 ] Normal text background color not
+  refreshed and Python bug [897872 ] Unknown color name on HP-UX
+
+- rpc.py:SocketIO - Large modules were generating large pickles when downloaded
+  to the execution server.  The return of the OK response from the subprocess
+  initialization was interfering and causing the sending socket to be not
+  ready.  Add an IO ready test to fix this.  Moved the polling IO ready test
+  into pollpacket().
+
+- Fix typo in rpc.py, s/b "pickle.PicklingError" not "pickle.UnpicklingError".
+
+- Added a Tk error dialog to run.py inform the user if the subprocess can't
+  connect to the user GUI process.  Added a timeout to the GUI's listening
+  socket.  Added Tk error dialogs to PyShell.py to announce a failure to bind
+  the port or connect to the subprocess.  Clean up error handling during
+  connection initiation phase.  This is an update of Python Patch 778323.
+
+- Print correct exception even if source file changed since shell was
+  restarted.  IDLEfork Patch 869012 Noam Raphael
+
+- Keybindings with the Shift modifier now work correctly.  So do bindings which
+  use the Space key.  Limit unmodified user keybindings to the function keys.
+  Python Bug 775353, IDLEfork Bugs 755647, 761557
+
+- After an exception, run.py was not setting the exception vector. Noam
+  Raphael suggested correcting this so pdb's postmortem pm() would work.
+  IDLEfork Patch 844675
+
+- IDLE now does not fail to save the file anymore if the Tk buffer is not a
+  Unicode string, yet eol_convention is.  Python Bugs 774680, 788378
+
+- IDLE didn't start correctly when Python was installed in "Program Files" on
+  W2K and XP.  Python Bugs 780451, 784183
+
+- config-main.def documentation incorrectly referred to idle- instead of
+  config-  filenames.  SF 782759  Also added note about .idlerc location.
+
+
+What's New in IDLE 1.0?
+=======================
+
+*Release date: 29-Jul-2003*
+
+- Added a banner to the shell discussing warnings possibly raised by personal
+  firewall software.  Added same comment to README.txt.
+
+
+What's New in IDLE 1.0 release candidate 2?
+===========================================
+
+*Release date: 24-Jul-2003*
+
+- Calltip error when docstring was None  Python Bug 775541
+
+
+What's New in IDLE 1.0 release candidate 1?
+===========================================
+
+*Release date: 18-Jul-2003*
+
+- Updated extend.txt, help.txt, and config-extensions.def to correctly
+  reflect the current status of the configuration system.  Python Bug 768469
+
+- Fixed: Call Tip Trimming May Loop Forever. Python Patch 769142 (Daniels)
+
+- Replaced apply(f, args, kwds) with f(*args, **kwargs) to improve performance
+  Python Patch 768187
+
+- Break or continue statements outside a loop were causing IDLE crash
+  Python Bug 767794
+
+- Convert Unicode strings from readline to IOBinding.encoding.  Also set
+  sys.std{in|out|err}.encoding, for both the local and the subprocess case.
+  SF IDLEfork patch 682347.
+
+
+What's New in IDLE 1.0b2?
+=========================
+
+*Release date: 29-Jun-2003*
+
+- Extend AboutDialog.ViewFile() to support file encodings.  Make the CREDITS
+  file Latin-1.
+
+- Updated the About dialog to reflect re-integration into Python.  Provide
+  buttons to display Python's NEWS, License, and Credits, plus additional
+  buttons for IDLE's README and NEWS.
+
+- TextViewer() now has a third parameter which allows inserting text into the
+  viewer instead of reading from a file.
+
+- (Created the .../Lib/idlelib directory in the Python CVS, which is a clone of
+  IDLEfork modified to install in the Python environment.  The code in the
+  interrupt module has been moved to thread.interrupt_main(). )
+
+- Printing the Shell window was failing if it was not saved first SF 748975
+
+- When using the Search in Files dialog, if the user had a selection
+  highlighted in his Editor window, insert it into the dialog search field.
+
+- The Python Shell entry was disappearing from the Windows menu.
+
+- Update the Windows file list when a file name change occurs
+
+- Change to File / Open Module: always pop up the dialog, using the current
+  selection as the default value.  This is easier to use habitually.
+
+- Avoided a problem with starting the subprocess when 'localhost' doesn't
+  resolve to the user's loopback interface.  SF 747772
+
+- Fixed an issue with highlighted errors never de-colorizing.  SF 747677.  Also
+  improved notification of Tabnanny Token Error.
+
+- File / New will by default save in the directory of the Edit window from
+  which it was initiated.  SF 748973 Guido van Rossum patch.
+
+
+What's New in IDLEfork 0.9b1?
+=============================
+
+*Release date: 02-Jun-2003*
+
+- The current working directory of the execution environment (and shell
+  following completion of execution) is now that of the module being run.
+
+- Added the delete-exitfunc option to config-main.def.  (This option is not
+  included in the Options dialog.)  Setting this to True (the default) will
+  cause IDLE to not run sys.exitfunc/atexit when the subprocess exits.
+
+- IDLE now preserves the line ending codes when editing a file produced on
+  a different platform. SF 661759,  SF 538584
+
+- Reduced default editor font size to 10 point and increased window height
+  to provide a better initial impression on Windows.
+
+- Options / Fonts/Tabs / Set Base Editor Font: List box was not highlighting
+  the default font when first installed on Windows.  SF 661676
+
+- Added Autosave feature: when user runs code from edit window, if the file
+  has been modified IDLE will silently save it if Autosave is enabled.  The
+  option is set in the Options dialog, and the default is to prompt the
+  user to save the file.   SF 661318 Bruce Sherwood patch.
+
+- Improved the RESTART annotation in the shell window when the user restarts
+  the shell while it is generating output.  Also improved annotation when user
+  repeatedly hammers the Ctrl-F6 restart.
+
+- Allow IDLE to run when not installed and cwd is not the IDLE directory
+  SF Patch 686254 "Run IDLEfork from any directory without set-up" - Raphael
+
+- When a module is run from an EditorWindow: if its directory is not in
+  sys.path, prepend it.  This allows the module to import other modules in
+  the same directory.  Do the same for a script run from the command line.
+
+- Correctly restart the subprocess if it is running user code and the user
+  attempts to run some other module or restarts the shell.  Do the same if
+  the link is broken and it is possible to restart the subprocess and re-
+  connect to the GUI.   SF RFE 661321.
+
+- Improved exception reporting when running commands or scripts from the
+  command line.
+
+- Added a -n command line switch to start IDLE without the subprocess.
+  Removed the Shell menu when running in that mode.  Updated help messages.
+
+- Added a comment to the shell startup header to indicate when IDLE is not
+  using the subprocess.
+
+- Restore the ability to run without the subprocess.  This can be important for
+  some platforms or configurations.  (Running without the subprocess allows the
+  debugger to trace through parts of IDLE itself, which may or may not be
+  desirable, depending on your point of view.  In addition, the traditional
+  reload/import tricks must be use if user source code is changed.)  This is
+  helpful for developing IDLE using IDLE, because one instance can be used to
+  edit the code and a separate instance run to test changes.  (Multiple
+  concurrent IDLE instances with subprocesses is a future feature)
+
+- Improve the error message a user gets when saving a file with non-ASCII
+  characters and no source encoding is specified.  Done by adding a dialog
+  'EncodingMessage', which contains the line to add in a fixed-font entry
+  widget, and which has a button to add that line to the file automatically.
+  Also, add a configuration option 'EditorWindow/encoding', which has three
+  possible values: none, utf-8, and locale. None is the default: IDLE will show
+  this dialog when non-ASCII characters are encountered. utf-8 means that files
+  with non-ASCII characters are saved as utf-8-with-bom. locale means that
+  files are saved in the locale's encoding; the dialog is only displayed if the
+  source contains characters outside the locale's charset.  SF 710733 - Loewis
+
+- Improved I/O response by tweaking the wait parameter in various
+  calls to signal.signal().
+
+- Implemented a threaded subprocess which allows interrupting a pass
+  loop in user code using the 'interrupt' extension.  User code runs
+  in MainThread, while the RPCServer is handled by SockThread.  This is
+  necessary because Windows doesn't support signals.
+
+- Implemented the 'interrupt' extension module, which allows a subthread
+  to raise a KeyboardInterrupt in the main thread.
+
+- Attempting to save the shell raised an error related to saving
+  breakpoints, which are not implemented in the shell
+
+- Provide a correct message when 'exit' or 'quit' are entered at the
+  IDLE command prompt  SF 695861
+
+- Eliminate extra blank line in shell output caused by not flushing
+  stdout when user code ends with an unterminated print. SF 695861
+
+- Moved responsibility for exception formatting (i.e. pruning IDLE internal
+  calls) out of rpc.py into the client and server.
+
+- Exit IDLE cleanly even when doing subprocess I/O
+
+- Handle subprocess interrupt with an RPC message.
+
+- Restart the subprocess if it terminates itself. (VPython programs do that)
+
+- Support subclassing of exceptions, including in the shell, by moving the
+  exception formatting to the subprocess.
+
+
+
+What's New in IDLEfork 0.9 Alpha 2?
+===================================
+
+*Release date: 27-Jan-2003*
+
+- Updated INSTALL.txt to claify use of the python2 rpm.
+
+- Improved formatting in IDLE Help.
+
+- Run menu: Replace "Run Script" with "Run Module".
+
+- Code encountering an unhandled exception under the debugger now shows
+  the correct traceback, with IDLE internal levels pruned out.
+
+- If an exception occurs entirely in IDLE, don't prune the IDLE internal
+  modules from the traceback displayed.
+
+- Class Browser and Path Browser now use Alt-Key-2 for vertical zoom.
+
+- IDLE icons will now install correctly even when setup.py is run from the
+  build directory
+
+- Class Browser now compatible with Python2.3 version of pyclbr.py
+
+- Left cursor move in presence of selected text now moves from left end
+  of the selection.
+
+- Add Meta keybindings to "IDLE Classic Windows" to handle reversed
+  Alt/Meta on some Linux distros.
+
+- Change default: IDLE now starts with Python Shell.
+
+- Removed the File Path from the Additional Help Sources scrolled list.
+
+- Add capability to access Additional Help Sources on the web if the
+  Help File Path begins with //http or www.  (Otherwise local path is
+  validated, as before.)
+
+- Additional Help Sources were not being posted on the Help menu in the
+  order entered.  Implement sorting the list by [HelpFiles] 'option'
+  number.
+
+- Add Browse button to New Help Source dialog.  Arrange to start in
+  Python/Doc if platform is Windows, otherwise start in current directory.
+
+- Put the Additional Help Sources directly on the Help menu instead of in
+  an Extra Help cascade menu.  Rearrange the Help menu so the Additional
+  Help Sources come last.  Update help.txt appropriately.
+
+- Fix Tk root pop-ups in configSectionNameDialog.py  and configDialog.py
+
+- Uniform capitalization in General tab of ConfigDialog, update the doc string.
+
+- Fix bug in ConfigDialog where SaveAllChangedConfig() was unexpectedly
+  deleting Additional Help Sources from the user's config file.
+
+- Make configHelpSourceEdit OK button the default and bind <Return>
+
+- Fix Tk root pop-ups in configHelpSourceEdit: error dialogs not attached
+  to parents.
+
+- Use os.startfile() to open both Additional Help and Python Help on the
+  Windows platform.  The application associated with the file type will act as
+  the viewer.  Windows help files (.chm) are now supported via the
+  Settings/General/Additional Help facility.
+
+- If Python Help files are installed locally on Linux, use them instead of
+  accessing python.org.
+
+- Make the methods for finding the Python help docs more robust, and make
+  them work in the installed configuration, also.
+
+- On the Save Before Run dialog, make the OK button the default.  One
+  less mouse action!
+
+- Add a method: EditorWindow.get_geometry() for future use in implementing
+  window location persistence.
+
+- Removed the "Help/Advice" menu entry.  Thanks, David!  We'll remember!
+
+- Change the "Classic Windows" theme's paste key to be <ctrl-v>.
+
+- Rearrange the Shell menu to put Stack Viewer entries adjacent.
+
+- Add the ability to restart the subprocess interpreter from the shell window;
+  add an associated menu entry "Shell/Restart" with binding Control-F6.  Update
+  IDLE help.
+
+- Upon a restart, annotate the shell window with a "restart boundary".  Add a
+  shell window menu "Shell/View Restart" with binding F6 to jump to the most
+  recent restart boundary.
+
+- Add Shell menu to Python Shell; change "Settings" to "Options".
+
+- Remove incorrect comment in setup.py: IDLEfork is now installed as a package.
+
+- Add INSTALL.txt, HISTORY.txt, NEWS.txt to installed configuration.
+
+- In installer text, fix reference to Visual Python, should be VPython.
+  Properly credit David Scherer.
+
+- Modified idle, idle.py, idle.pyw to improve exception handling.
+
+
+What's New in IDLEfork 0.9 Alpha 1?
+===================================
+
+*Release date: 31-Dec-2002*
+
+- First release of major new functionality.  For further details refer to
+  Idle-dev and/or the Sourceforge CVS.
+
+- Adapted to the Mac platform.
+
+- Overhauled the IDLE startup options and revised the idle -h help message,
+  which provides details of command line usage.
+
+- Multiple bug fixes and usability enhancements.
+
+- Introduced the new RPC implementation, which includes a debugger.  The output
+  of user code is to the shell, and the shell may be used to inspect the
+  environment after the run has finished.  (In version 0.8.1 the shell
+  environment was separate from the environment of the user code.)
+
+- Introduced the configuration GUI and a new About dialog.
+
+- Removed David Scherer's Remote Procedure Call code and replaced with Guido
+  van Rossum's.  GvR code has support for the IDLE debugger and uses the shell
+  to inspect the environment of code Run from an Edit window.  Files removed:
+  ExecBinding.py, loader.py, protocol.py, Remote.py, spawn.py
+
+--------------------------------------------------------------------
+Refer to HISTORY.txt for additional information on earlier releases.
+--------------------------------------------------------------------
+
+
+
+
+

Added: vendor/Python/current/Lib/idlelib/ObjectBrowser.py
===================================================================
--- vendor/Python/current/Lib/idlelib/ObjectBrowser.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/ObjectBrowser.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,151 @@
+# XXX TO DO:
+# - popup menu
+# - support partial or total redisplay
+# - more doc strings
+# - tooltips
+
+# object browser
+
+# XXX TO DO:
+# - for classes/modules, add "open source" to object browser
+
+from TreeWidget import TreeItem, TreeNode, ScrolledCanvas
+
+from repr import Repr
+
+myrepr = Repr()
+myrepr.maxstring = 100
+myrepr.maxother = 100
+
+class ObjectTreeItem(TreeItem):
+    def __init__(self, labeltext, object, setfunction=None):
+        self.labeltext = labeltext
+        self.object = object
+        self.setfunction = setfunction
+    def GetLabelText(self):
+        return self.labeltext
+    def GetText(self):
+        return myrepr.repr(self.object)
+    def GetIconName(self):
+        if not self.IsExpandable():
+            return "python"
+    def IsEditable(self):
+        return self.setfunction is not None
+    def SetText(self, text):
+        try:
+            value = eval(text)
+            self.setfunction(value)
+        except:
+            pass
+        else:
+            self.object = value
+    def IsExpandable(self):
+        return not not dir(self.object)
+    def GetSubList(self):
+        keys = dir(self.object)
+        sublist = []
+        for key in keys:
+            try:
+                value = getattr(self.object, key)
+            except AttributeError:
+                continue
+            item = make_objecttreeitem(
+                str(key) + " =",
+                value,
+                lambda value, key=key, object=self.object:
+                    setattr(object, key, value))
+            sublist.append(item)
+        return sublist
+
+class InstanceTreeItem(ObjectTreeItem):
+    def IsExpandable(self):
+        return True
+    def GetSubList(self):
+        sublist = ObjectTreeItem.GetSubList(self)
+        sublist.insert(0,
+            make_objecttreeitem("__class__ =", self.object.__class__))
+        return sublist
+
+class ClassTreeItem(ObjectTreeItem):
+    def IsExpandable(self):
+        return True
+    def GetSubList(self):
+        sublist = ObjectTreeItem.GetSubList(self)
+        if len(self.object.__bases__) == 1:
+            item = make_objecttreeitem("__bases__[0] =",
+                self.object.__bases__[0])
+        else:
+            item = make_objecttreeitem("__bases__ =", self.object.__bases__)
+        sublist.insert(0, item)
+        return sublist
+
+class AtomicObjectTreeItem(ObjectTreeItem):
+    def IsExpandable(self):
+        return 0
+
+class SequenceTreeItem(ObjectTreeItem):
+    def IsExpandable(self):
+        return len(self.object) > 0
+    def keys(self):
+        return range(len(self.object))
+    def GetSubList(self):
+        sublist = []
+        for key in self.keys():
+            try:
+                value = self.object[key]
+            except KeyError:
+                continue
+            def setfunction(value, key=key, object=self.object):
+                object[key] = value
+            item = make_objecttreeitem("%r:" % (key,), value, setfunction)
+            sublist.append(item)
+        return sublist
+
+class DictTreeItem(SequenceTreeItem):
+    def keys(self):
+        keys = self.object.keys()
+        try:
+            keys.sort()
+        except:
+            pass
+        return keys
+
+from types import *
+
+dispatch = {
+    IntType: AtomicObjectTreeItem,
+    LongType: AtomicObjectTreeItem,
+    FloatType: AtomicObjectTreeItem,
+    StringType: AtomicObjectTreeItem,
+    TupleType: SequenceTreeItem,
+    ListType: SequenceTreeItem,
+    DictType: DictTreeItem,
+    InstanceType: InstanceTreeItem,
+    ClassType: ClassTreeItem,
+}
+
+def make_objecttreeitem(labeltext, object, setfunction=None):
+    t = type(object)
+    if dispatch.has_key(t):
+        c = dispatch[t]
+    else:
+        c = ObjectTreeItem
+    return c(labeltext, object, setfunction)
+
+# Test script
+
+def _test():
+    import sys
+    from Tkinter import Tk
+    root = Tk()
+    root.configure(bd=0, bg="yellow")
+    root.focus_set()
+    sc = ScrolledCanvas(root, bg="white", highlightthickness=0, takefocus=1)
+    sc.frame.pack(expand=1, fill="both")
+    item = make_objecttreeitem("sys", sys)
+    node = TreeNode(sc.canvas, None, item)
+    node.update()
+    root.mainloop()
+
+if __name__ == '__main__':
+    _test()

Added: vendor/Python/current/Lib/idlelib/OutputWindow.py
===================================================================
--- vendor/Python/current/Lib/idlelib/OutputWindow.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/OutputWindow.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,157 @@
+from Tkinter import *
+from EditorWindow import EditorWindow
+import re
+import tkMessageBox
+import IOBinding
+
+class OutputWindow(EditorWindow):
+
+    """An editor window that can serve as an output file.
+
+    Also the future base class for the Python shell window.
+    This class has no input facilities.
+    """
+
+    def __init__(self, *args):
+        EditorWindow.__init__(self, *args)
+        self.text.bind("<<goto-file-line>>", self.goto_file_line)
+
+    # Customize EditorWindow
+
+    def ispythonsource(self, filename):
+        # No colorization needed
+        return 0
+
+    def short_title(self):
+        return "Output"
+
+    def maybesave(self):
+        # Override base class method -- don't ask any questions
+        if self.get_saved():
+            return "yes"
+        else:
+            return "no"
+
+    # Act as output file
+
+    def write(self, s, tags=(), mark="insert"):
+        # Tk assumes that byte strings are Latin-1;
+        # we assume that they are in the locale's encoding
+        if isinstance(s, str):
+            try:
+                s = unicode(s, IOBinding.encoding)
+            except UnicodeError:
+                # some other encoding; let Tcl deal with it
+                pass
+        self.text.insert(mark, s, tags)
+        self.text.see(mark)
+        self.text.update()
+
+    def writelines(self, l):
+        map(self.write, l)
+
+    def flush(self):
+        pass
+
+    # Our own right-button menu
+
+    rmenu_specs = [
+        ("Go to file/line", "<<goto-file-line>>"),
+    ]
+
+    file_line_pats = [
+        r'file "([^"]*)", line (\d+)',
+        r'([^\s]+)\((\d+)\)',
+        r'([^\s]+):\s*(\d+):',
+    ]
+
+    file_line_progs = None
+
+    def goto_file_line(self, event=None):
+        if self.file_line_progs is None:
+            l = []
+            for pat in self.file_line_pats:
+                l.append(re.compile(pat, re.IGNORECASE))
+            self.file_line_progs = l
+        # x, y = self.event.x, self.event.y
+        # self.text.mark_set("insert", "@%d,%d" % (x, y))
+        line = self.text.get("insert linestart", "insert lineend")
+        result = self._file_line_helper(line)
+        if not result:
+            # Try the previous line.  This is handy e.g. in tracebacks,
+            # where you tend to right-click on the displayed source line
+            line = self.text.get("insert -1line linestart",
+                                 "insert -1line lineend")
+            result = self._file_line_helper(line)
+            if not result:
+                tkMessageBox.showerror(
+                    "No special line",
+                    "The line you point at doesn't look like "
+                    "a valid file name followed by a line number.",
+                    master=self.text)
+                return
+        filename, lineno = result
+        edit = self.flist.open(filename)
+        edit.gotoline(lineno)
+
+    def _file_line_helper(self, line):
+        for prog in self.file_line_progs:
+            m = prog.search(line)
+            if m:
+                break
+        else:
+            return None
+        filename, lineno = m.group(1, 2)
+        try:
+            f = open(filename, "r")
+            f.close()
+        except IOError:
+            return None
+        try:
+            return filename, int(lineno)
+        except TypeError:
+            return None
+
+# These classes are currently not used but might come in handy
+
+class OnDemandOutputWindow:
+
+    tagdefs = {
+        # XXX Should use IdlePrefs.ColorPrefs
+        "stdout":  {"foreground": "blue"},
+        "stderr":  {"foreground": "#007700"},
+    }
+
+    def __init__(self, flist):
+        self.flist = flist
+        self.owin = None
+
+    def write(self, s, tags, mark):
+        if not self.owin:
+            self.setup()
+        self.owin.write(s, tags, mark)
+
+    def setup(self):
+        self.owin = owin = OutputWindow(self.flist)
+        text = owin.text
+        for tag, cnf in self.tagdefs.items():
+            if cnf:
+                text.tag_configure(tag, **cnf)
+        text.tag_raise('sel')
+        self.write = self.owin.write
+
+#class PseudoFile:
+#
+#      def __init__(self, owin, tags, mark="end"):
+#          self.owin = owin
+#          self.tags = tags
+#          self.mark = mark
+
+#      def write(self, s):
+#          self.owin.write(s, self.tags, self.mark)
+
+#      def writelines(self, l):
+#          map(self.write, l)
+
+#      def flush(self):
+#          pass

Added: vendor/Python/current/Lib/idlelib/ParenMatch.py
===================================================================
--- vendor/Python/current/Lib/idlelib/ParenMatch.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/ParenMatch.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,172 @@
+"""ParenMatch -- An IDLE extension for parenthesis matching.
+
+When you hit a right paren, the cursor should move briefly to the left
+paren.  Paren here is used generically; the matching applies to
+parentheses, square brackets, and curly braces.
+"""
+
+from HyperParser import HyperParser
+from configHandler import idleConf
+
+_openers = {')':'(',']':'[','}':'{'}
+CHECK_DELAY = 100 # miliseconds
+
+class ParenMatch:
+    """Highlight matching parentheses
+
+    There are three supported style of paren matching, based loosely
+    on the Emacs options.  The style is select based on the
+    HILITE_STYLE attribute; it can be changed used the set_style
+    method.
+
+    The supported styles are:
+
+    default -- When a right paren is typed, highlight the matching
+        left paren for 1/2 sec.
+
+    expression -- When a right paren is typed, highlight the entire
+        expression from the left paren to the right paren.
+
+    TODO:
+        - extend IDLE with configuration dialog to change options
+        - implement rest of Emacs highlight styles (see below)
+        - print mismatch warning in IDLE status window
+
+    Note: In Emacs, there are several styles of highlight where the
+    matching paren is highlighted whenever the cursor is immediately
+    to the right of a right paren.  I don't know how to do that in Tk,
+    so I haven't bothered.
+    """
+    menudefs = [
+        ('edit', [
+            ("Show surrounding parens", "<<flash-paren>>"),
+        ])
+    ]
+    STYLE = idleConf.GetOption('extensions','ParenMatch','style',
+            default='expression')
+    FLASH_DELAY = idleConf.GetOption('extensions','ParenMatch','flash-delay',
+            type='int',default=500)
+    HILITE_CONFIG = idleConf.GetHighlight(idleConf.CurrentTheme(),'hilite')
+    BELL = idleConf.GetOption('extensions','ParenMatch','bell',
+            type='bool',default=1)
+
+    RESTORE_VIRTUAL_EVENT_NAME = "<<parenmatch-check-restore>>"
+    # We want the restore event be called before the usual return and
+    # backspace events.
+    RESTORE_SEQUENCES = ("<KeyPress>", "<ButtonPress>",
+                         "<Key-Return>", "<Key-BackSpace>")
+
+    def __init__(self, editwin):
+        self.editwin = editwin
+        self.text = editwin.text
+        # Bind the check-restore event to the function restore_event,
+        # so that we can then use activate_restore (which calls event_add)
+        # and deactivate_restore (which calls event_delete).
+        editwin.text.bind(self.RESTORE_VIRTUAL_EVENT_NAME,
+                          self.restore_event)
+        self.counter = 0
+        self.is_restore_active = 0
+        self.set_style(self.STYLE)
+
+    def activate_restore(self):
+        if not self.is_restore_active:
+            for seq in self.RESTORE_SEQUENCES:
+                self.text.event_add(self.RESTORE_VIRTUAL_EVENT_NAME, seq)
+            self.is_restore_active = True
+
+    def deactivate_restore(self):
+        if self.is_restore_active:
+            for seq in self.RESTORE_SEQUENCES:
+                self.text.event_delete(self.RESTORE_VIRTUAL_EVENT_NAME, seq)
+            self.is_restore_active = False
+
+    def set_style(self, style):
+        self.STYLE = style
+        if style == "default":
+            self.create_tag = self.create_tag_default
+            self.set_timeout = self.set_timeout_last
+        elif style == "expression":
+            self.create_tag = self.create_tag_expression
+            self.set_timeout = self.set_timeout_none
+
+    def flash_paren_event(self, event):
+        indices = HyperParser(self.editwin, "insert").get_surrounding_brackets()
+        if indices is None:
+            self.warn_mismatched()
+            return
+        self.activate_restore()
+        self.create_tag(indices)
+        self.set_timeout_last()
+
+    def paren_closed_event(self, event):
+        # If it was a shortcut and not really a closing paren, quit.
+        closer = self.text.get("insert-1c")
+        if closer not in _openers:
+            return
+        hp = HyperParser(self.editwin, "insert-1c")
+        if not hp.is_in_code():
+            return
+        indices = hp.get_surrounding_brackets(_openers[closer], True)
+        if indices is None:
+            self.warn_mismatched()
+            return
+        self.activate_restore()
+        self.create_tag(indices)
+        self.set_timeout()
+
+    def restore_event(self, event=None):
+        self.text.tag_delete("paren")
+        self.deactivate_restore()
+        self.counter += 1   # disable the last timer, if there is one.
+
+    def handle_restore_timer(self, timer_count):
+        if timer_count == self.counter:
+            self.restore_event()
+
+    def warn_mismatched(self):
+        if self.BELL:
+            self.text.bell()
+
+    # any one of the create_tag_XXX methods can be used depending on
+    # the style
+
+    def create_tag_default(self, indices):
+        """Highlight the single paren that matches"""
+        self.text.tag_add("paren", indices[0])
+        self.text.tag_config("paren", self.HILITE_CONFIG)
+
+    def create_tag_expression(self, indices):
+        """Highlight the entire expression"""
+        if self.text.get(indices[1]) in (')', ']', '}'):
+            rightindex = indices[1]+"+1c"
+        else:
+            rightindex = indices[1]
+        self.text.tag_add("paren", indices[0], rightindex)
+        self.text.tag_config("paren", self.HILITE_CONFIG)
+
+    # any one of the set_timeout_XXX methods can be used depending on
+    # the style
+
+    def set_timeout_none(self):
+        """Highlight will remain until user input turns it off
+        or the insert has moved"""
+        # After CHECK_DELAY, call a function which disables the "paren" tag
+        # if the event is for the most recent timer and the insert has changed,
+        # or schedules another call for itself.
+        self.counter += 1
+        def callme(callme, self=self, c=self.counter,
+                   index=self.text.index("insert")):
+            if index != self.text.index("insert"):
+                self.handle_restore_timer(c)
+            else:
+                self.editwin.text_frame.after(CHECK_DELAY, callme, callme)
+        self.editwin.text_frame.after(CHECK_DELAY, callme, callme)
+
+    def set_timeout_last(self):
+        """The last highlight created will be removed after .5 sec"""
+        # associate a counter with an event; only disable the "paren"
+        # tag if the event is for the most recent timer.
+        self.counter += 1
+        self.editwin.text_frame.after(self.FLASH_DELAY,
+                                      lambda self=self, c=self.counter: \
+                                      self.handle_restore_timer(c))

Added: vendor/Python/current/Lib/idlelib/PathBrowser.py
===================================================================
--- vendor/Python/current/Lib/idlelib/PathBrowser.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/PathBrowser.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,95 @@
+import os
+import sys
+import imp
+
+from TreeWidget import TreeItem
+from ClassBrowser import ClassBrowser, ModuleBrowserTreeItem
+
+class PathBrowser(ClassBrowser):
+
+    def __init__(self, flist):
+        self.init(flist)
+
+    def settitle(self):
+        self.top.wm_title("Path Browser")
+        self.top.wm_iconname("Path Browser")
+
+    def rootnode(self):
+        return PathBrowserTreeItem()
+
+class PathBrowserTreeItem(TreeItem):
+
+    def GetText(self):
+        return "sys.path"
+
+    def GetSubList(self):
+        sublist = []
+        for dir in sys.path:
+            item = DirBrowserTreeItem(dir)
+            sublist.append(item)
+        return sublist
+
+class DirBrowserTreeItem(TreeItem):
+
+    def __init__(self, dir, packages=[]):
+        self.dir = dir
+        self.packages = packages
+
+    def GetText(self):
+        if not self.packages:
+            return self.dir
+        else:
+            return self.packages[-1] + ": package"
+
+    def GetSubList(self):
+        try:
+            names = os.listdir(self.dir or os.curdir)
+        except os.error:
+            return []
+        packages = []
+        for name in names:
+            file = os.path.join(self.dir, name)
+            if self.ispackagedir(file):
+                nn = os.path.normcase(name)
+                packages.append((nn, name, file))
+        packages.sort()
+        sublist = []
+        for nn, name, file in packages:
+            item = DirBrowserTreeItem(file, self.packages + [name])
+            sublist.append(item)
+        for nn, name in self.listmodules(names):
+            item = ModuleBrowserTreeItem(os.path.join(self.dir, name))
+            sublist.append(item)
+        return sublist
+
+    def ispackagedir(self, file):
+        if not os.path.isdir(file):
+            return 0
+        init = os.path.join(file, "__init__.py")
+        return os.path.exists(init)
+
+    def listmodules(self, allnames):
+        modules = {}
+        suffixes = imp.get_suffixes()
+        sorted = []
+        for suff, mode, flag in suffixes:
+            i = -len(suff)
+            for name in allnames[:]:
+                normed_name = os.path.normcase(name)
+                if normed_name[i:] == suff:
+                    mod_name = name[:i]
+                    if not modules.has_key(mod_name):
+                        modules[mod_name] = None
+                        sorted.append((normed_name, name))
+                        allnames.remove(name)
+        sorted.sort()
+        return sorted
+
+def main():
+    import PyShell
+    PathBrowser(PyShell.flist)
+    if sys.stdin is sys.__stdin__:
+        mainloop()
+
+if __name__ == "__main__":
+    main()

Added: vendor/Python/current/Lib/idlelib/Percolator.py
===================================================================
--- vendor/Python/current/Lib/idlelib/Percolator.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/Percolator.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,85 @@
+from WidgetRedirector import WidgetRedirector
+from Delegator import Delegator
+
+class Percolator:
+
+    def __init__(self, text):
+        # XXX would be nice to inherit from Delegator
+        self.text = text
+        self.redir = WidgetRedirector(text)
+        self.top = self.bottom = Delegator(text)
+        self.bottom.insert = self.redir.register("insert", self.insert)
+        self.bottom.delete = self.redir.register("delete", self.delete)
+        self.filters = []
+
+    def close(self):
+        while self.top is not self.bottom:
+            self.removefilter(self.top)
+        self.top = None
+        self.bottom.setdelegate(None); self.bottom = None
+        self.redir.close(); self.redir = None
+        self.text = None
+
+    def insert(self, index, chars, tags=None):
+        # Could go away if inheriting from Delegator
+        self.top.insert(index, chars, tags)
+
+    def delete(self, index1, index2=None):
+        # Could go away if inheriting from Delegator
+        self.top.delete(index1, index2)
+
+    def insertfilter(self, filter):
+        # Perhaps rename to pushfilter()?
+        assert isinstance(filter, Delegator)
+        assert filter.delegate is None
+        filter.setdelegate(self.top)
+        self.top = filter
+
+    def removefilter(self, filter):
+        # XXX Perhaps should only support popfilter()?
+        assert isinstance(filter, Delegator)
+        assert filter.delegate is not None
+        f = self.top
+        if f is filter:
+            self.top = filter.delegate
+            filter.setdelegate(None)
+        else:
+            while f.delegate is not filter:
+                assert f is not self.bottom
+                f.resetcache()
+                f = f.delegate
+            f.setdelegate(filter.delegate)
+            filter.setdelegate(None)
+
+
+def main():
+    class Tracer(Delegator):
+        def __init__(self, name):
+            self.name = name
+            Delegator.__init__(self, None)
+        def insert(self, *args):
+            print self.name, ": insert", args
+            self.delegate.insert(*args)
+        def delete(self, *args):
+            print self.name, ": delete", args
+            self.delegate.delete(*args)
+    root = Tk()
+    root.wm_protocol("WM_DELETE_WINDOW", root.quit)
+    text = Text()
+    text.pack()
+    text.focus_set()
+    p = Percolator(text)
+    t1 = Tracer("t1")
+    t2 = Tracer("t2")
+    p.insertfilter(t1)
+    p.insertfilter(t2)
+    root.mainloop()
+    p.removefilter(t2)
+    root.mainloop()
+    p.insertfilter(t2)
+    p.removefilter(t1)
+    root.mainloop()
+
+if __name__ == "__main__":
+    from Tkinter import *
+    main()

Added: vendor/Python/current/Lib/idlelib/PyParse.py
===================================================================
--- vendor/Python/current/Lib/idlelib/PyParse.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/PyParse.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,594 @@
+import re
+import sys
+
+# Reason last stmt is continued (or C_NONE if it's not).
+(C_NONE, C_BACKSLASH, C_STRING_FIRST_LINE,
+ C_STRING_NEXT_LINES, C_BRACKET) = range(5)
+
+if 0:   # for throwaway debugging output
+    def dump(*stuff):
+        sys.__stdout__.write(" ".join(map(str, stuff)) + "\n")
+
+# Find what looks like the start of a popular stmt.
+
+_synchre = re.compile(r"""
+    ^
+    [ \t]*
+    (?: while
+    |   else
+    |   def
+    |   return
+    |   assert
+    |   break
+    |   class
+    |   continue
+    |   elif
+    |   try
+    |   except
+    |   raise
+    |   import
+    |   yield
+    )
+    \b
+""", re.VERBOSE | re.MULTILINE).search
+
+# Match blank line or non-indenting comment line.
+
+_junkre = re.compile(r"""
+    [ \t]*
+    (?: \# \S .* )?
+    \n
+""", re.VERBOSE).match
+
+# Match any flavor of string; the terminating quote is optional
+# so that we're robust in the face of incomplete program text.
+
+_match_stringre = re.compile(r"""
+    \""" [^"\\]* (?:
+                     (?: \\. | "(?!"") )
+                     [^"\\]*
+                 )*
+    (?: \""" )?
+
+|   " [^"\\\n]* (?: \\. [^"\\\n]* )* "?
+
+|   ''' [^'\\]* (?:
+                   (?: \\. | '(?!'') )
+                   [^'\\]*
+                )*
+    (?: ''' )?
+
+|   ' [^'\\\n]* (?: \\. [^'\\\n]* )* '?
+""", re.VERBOSE | re.DOTALL).match
+
+# Match a line that starts with something interesting;
+# used to find the first item of a bracket structure.
+
+_itemre = re.compile(r"""
+    [ \t]*
+    [^\s#\\]    # if we match, m.end()-1 is the interesting char
+""", re.VERBOSE).match
+
+# Match start of stmts that should be followed by a dedent.
+
+_closere = re.compile(r"""
+    \s*
+    (?: return
+    |   break
+    |   continue
+    |   raise
+    |   pass
+    )
+    \b
+""", re.VERBOSE).match
+
+# Chew up non-special chars as quickly as possible.  If match is
+# successful, m.end() less 1 is the index of the last boring char
+# matched.  If match is unsuccessful, the string starts with an
+# interesting char.
+
+_chew_ordinaryre = re.compile(r"""
+    [^[\](){}#'"\\]+
+""", re.VERBOSE).match
+
+# Build translation table to map uninteresting chars to "x", open
+# brackets to "(", and close brackets to ")".
+
+_tran = ['x'] * 256
+for ch in "({[":
+    _tran[ord(ch)] = '('
+for ch in ")}]":
+    _tran[ord(ch)] = ')'
+for ch in "\"'\\\n#":
+    _tran[ord(ch)] = ch
+_tran = ''.join(_tran)
+del ch
+
+try:
+    UnicodeType = type(unicode(""))
+except NameError:
+    UnicodeType = None
+
+class Parser:
+
+    def __init__(self, indentwidth, tabwidth):
+        self.indentwidth = indentwidth
+        self.tabwidth = tabwidth
+
+    def set_str(self, str):
+        assert len(str) == 0 or str[-1] == '\n'
+        if type(str) is UnicodeType:
+            # The parse functions have no idea what to do with Unicode, so
+            # replace all Unicode characters with "x".  This is "safe"
+            # so long as the only characters germane to parsing the structure
+            # of Python are 7-bit ASCII.  It's *necessary* because Unicode
+            # strings don't have a .translate() method that supports
+            # deletechars.
+            uniphooey = str
+            str = []
+            push = str.append
+            for raw in map(ord, uniphooey):
+                push(raw < 127 and chr(raw) or "x")
+            str = "".join(str)
+        self.str = str
+        self.study_level = 0
+
+    # Return index of a good place to begin parsing, as close to the
+    # end of the string as possible.  This will be the start of some
+    # popular stmt like "if" or "def".  Return None if none found:
+    # the caller should pass more prior context then, if possible, or
+    # if not (the entire program text up until the point of interest
+    # has already been tried) pass 0 to set_lo.
+    #
+    # This will be reliable iff given a reliable is_char_in_string
+    # function, meaning that when it says "no", it's absolutely
+    # guaranteed that the char is not in a string.
+
+    def find_good_parse_start(self, is_char_in_string=None,
+                              _synchre=_synchre):
+        str, pos = self.str, None
+
+        if not is_char_in_string:
+            # no clue -- make the caller pass everything
+            return None
+
+        # Peek back from the end for a good place to start,
+        # but don't try too often; pos will be left None, or
+        # bumped to a legitimate synch point.
+        limit = len(str)
+        for tries in range(5):
+            i = str.rfind(":\n", 0, limit)
+            if i < 0:
+                break
+            i = str.rfind('\n', 0, i) + 1  # start of colon line
+            m = _synchre(str, i, limit)
+            if m and not is_char_in_string(m.start()):
+                pos = m.start()
+                break
+            limit = i
+        if pos is None:
+            # Nothing looks like a block-opener, or stuff does
+            # but is_char_in_string keeps returning true; most likely
+            # we're in or near a giant string, the colorizer hasn't
+            # caught up enough to be helpful, or there simply *aren't*
+            # any interesting stmts.  In any of these cases we're
+            # going to have to parse the whole thing to be sure, so
+            # give it one last try from the start, but stop wasting
+            # time here regardless of the outcome.
+            m = _synchre(str)
+            if m and not is_char_in_string(m.start()):
+                pos = m.start()
+            return pos
+
+        # Peeking back worked; look forward until _synchre no longer
+        # matches.
+        i = pos + 1
+        while 1:
+            m = _synchre(str, i)
+            if m:
+                s, i = m.span()
+                if not is_char_in_string(s):
+                    pos = s
+            else:
+                break
+        return pos
+
+    # Throw away the start of the string.  Intended to be called with
+    # find_good_parse_start's result.
+
+    def set_lo(self, lo):
+        assert lo == 0 or self.str[lo-1] == '\n'
+        if lo > 0:
+            self.str = self.str[lo:]
+
+    # As quickly as humanly possible <wink>, find the line numbers (0-
+    # based) of the non-continuation lines.
+    # Creates self.{goodlines, continuation}.
+
+    def _study1(self):
+        if self.study_level >= 1:
+            return
+        self.study_level = 1
+
+        # Map all uninteresting characters to "x", all open brackets
+        # to "(", all close brackets to ")", then collapse runs of
+        # uninteresting characters.  This can cut the number of chars
+        # by a factor of 10-40, and so greatly speed the following loop.
+        str = self.str
+        str = str.translate(_tran)
+        str = str.replace('xxxxxxxx', 'x')
+        str = str.replace('xxxx', 'x')
+        str = str.replace('xx', 'x')
+        str = str.replace('xx', 'x')
+        str = str.replace('\nx', '\n')
+        # note that replacing x\n with \n would be incorrect, because
+        # x may be preceded by a backslash
+
+        # March over the squashed version of the program, accumulating
+        # the line numbers of non-continued stmts, and determining
+        # whether & why the last stmt is a continuation.
+        continuation = C_NONE
+        level = lno = 0     # level is nesting level; lno is line number
+        self.goodlines = goodlines = [0]
+        push_good = goodlines.append
+        i, n = 0, len(str)
+        while i < n:
+            ch = str[i]
+            i = i+1
+
+            # cases are checked in decreasing order of frequency
+            if ch == 'x':
+                continue
+
+            if ch == '\n':
+                lno = lno + 1
+                if level == 0:
+                    push_good(lno)
+                    # else we're in an unclosed bracket structure
+                continue
+
+            if ch == '(':
+                level = level + 1
+                continue
+
+            if ch == ')':
+                if level:
+                    level = level - 1
+                    # else the program is invalid, but we can't complain
+                continue
+
+            if ch == '"' or ch == "'":
+                # consume the string
+                quote = ch
+                if str[i-1:i+2] == quote * 3:
+                    quote = quote * 3
+                firstlno = lno
+                w = len(quote) - 1
+                i = i+w
+                while i < n:
+                    ch = str[i]
+                    i = i+1
+
+                    if ch == 'x':
+                        continue
+
+                    if str[i-1:i+w] == quote:
+                        i = i+w
+                        break
+
+                    if ch == '\n':
+                        lno = lno + 1
+                        if w == 0:
+                            # unterminated single-quoted string
+                            if level == 0:
+                                push_good(lno)
+                            break
+                        continue
+
+                    if ch == '\\':
+                        assert i < n
+                        if str[i] == '\n':
+                            lno = lno + 1
+                        i = i+1
+                        continue
+
+                    # else comment char or paren inside string
+
+                else:
+                    # didn't break out of the loop, so we're still
+                    # inside a string
+                    if (lno - 1) == firstlno:
+                        # before the previous \n in str, we were in the first
+                        # line of the string
+                        continuation = C_STRING_FIRST_LINE
+                    else:
+                        continuation = C_STRING_NEXT_LINES
+                continue    # with outer loop
+
+            if ch == '#':
+                # consume the comment
+                i = str.find('\n', i)
+                assert i >= 0
+                continue
+
+            assert ch == '\\'
+            assert i < n
+            if str[i] == '\n':
+                lno = lno + 1
+                if i+1 == n:
+                    continuation = C_BACKSLASH
+            i = i+1
+
+        # The last stmt may be continued for all 3 reasons.
+        # String continuation takes precedence over bracket
+        # continuation, which beats backslash continuation.
+        if (continuation != C_STRING_FIRST_LINE
+            and continuation != C_STRING_NEXT_LINES and level > 0):
+            continuation = C_BRACKET
+        self.continuation = continuation
+
+        # Push the final line number as a sentinel value, regardless of
+        # whether it's continued.
+        assert (continuation == C_NONE) == (goodlines[-1] == lno)
+        if goodlines[-1] != lno:
+            push_good(lno)
+
+    def get_continuation_type(self):
+        self._study1()
+        return self.continuation
+
+    # study1 was sufficient to determine the continuation status,
+    # but doing more requires looking at every character.  study2
+    # does this for the last interesting statement in the block.
+    # Creates:
+    #     self.stmt_start, stmt_end
+    #         slice indices of last interesting stmt
+    #     self.stmt_bracketing
+    #         the bracketing structure of the last interesting stmt;
+    #         for example, for the statement "say(boo) or die", stmt_bracketing
+    #         will be [(0, 0), (3, 1), (8, 0)]. Strings and comments are
+    #         treated as brackets, for the matter.
+    #     self.lastch
+    #         last non-whitespace character before optional trailing
+    #         comment
+    #     self.lastopenbracketpos
+    #         if continuation is C_BRACKET, index of last open bracket
+
+    def _study2(self):
+        if self.study_level >= 2:
+            return
+        self._study1()
+        self.study_level = 2
+
+        # Set p and q to slice indices of last interesting stmt.
+        str, goodlines = self.str, self.goodlines
+        i = len(goodlines) - 1
+        p = len(str)    # index of newest line
+        while i:
+            assert p
+            # p is the index of the stmt at line number goodlines[i].
+            # Move p back to the stmt at line number goodlines[i-1].
+            q = p
+            for nothing in range(goodlines[i-1], goodlines[i]):
+                # tricky: sets p to 0 if no preceding newline
+                p = str.rfind('\n', 0, p-1) + 1
+            # The stmt str[p:q] isn't a continuation, but may be blank
+            # or a non-indenting comment line.
+            if  _junkre(str, p):
+                i = i-1
+            else:
+                break
+        if i == 0:
+            # nothing but junk!
+            assert p == 0
+            q = p
+        self.stmt_start, self.stmt_end = p, q
+
+        # Analyze this stmt, to find the last open bracket (if any)
+        # and last interesting character (if any).
+        lastch = ""
+        stack = []  # stack of open bracket indices
+        push_stack = stack.append
+        bracketing = [(p, 0)]
+        while p < q:
+            # suck up all except ()[]{}'"#\\
+            m = _chew_ordinaryre(str, p, q)
+            if m:
+                # we skipped at least one boring char
+                newp = m.end()
+                # back up over totally boring whitespace
+                i = newp - 1    # index of last boring char
+                while i >= p and str[i] in " \t\n":
+                    i = i-1
+                if i >= p:
+                    lastch = str[i]
+                p = newp
+                if p >= q:
+                    break
+
+            ch = str[p]
+
+            if ch in "([{":
+                push_stack(p)
+                bracketing.append((p, len(stack)))
+                lastch = ch
+                p = p+1
+                continue
+
+            if ch in ")]}":
+                if stack:
+                    del stack[-1]
+                lastch = ch
+                p = p+1
+                bracketing.append((p, len(stack)))
+                continue
+
+            if ch == '"' or ch == "'":
+                # consume string
+                # Note that study1 did this with a Python loop, but
+                # we use a regexp here; the reason is speed in both
+                # cases; the string may be huge, but study1 pre-squashed
+                # strings to a couple of characters per line.  study1
+                # also needed to keep track of newlines, and we don't
+                # have to.
+                bracketing.append((p, len(stack)+1))
+                lastch = ch
+                p = _match_stringre(str, p, q).end()
+                bracketing.append((p, len(stack)))
+                continue
+
+            if ch == '#':
+                # consume comment and trailing newline
+                bracketing.append((p, len(stack)+1))
+                p = str.find('\n', p, q) + 1
+                assert p > 0
+                bracketing.append((p, len(stack)))
+                continue
+
+            assert ch == '\\'
+            p = p+1     # beyond backslash
+            assert p < q
+            if str[p] != '\n':
+                # the program is invalid, but can't complain
+                lastch = ch + str[p]
+            p = p+1     # beyond escaped char
+
+        # end while p < q:
+
+        self.lastch = lastch
+        if stack:
+            self.lastopenbracketpos = stack[-1]
+        self.stmt_bracketing = tuple(bracketing)
+
+    # Assuming continuation is C_BRACKET, return the number
+    # of spaces the next line should be indented.
+
+    def compute_bracket_indent(self):
+        self._study2()
+        assert self.continuation == C_BRACKET
+        j = self.lastopenbracketpos
+        str = self.str
+        n = len(str)
+        origi = i = str.rfind('\n', 0, j) + 1
+        j = j+1     # one beyond open bracket
+        # find first list item; set i to start of its line
+        while j < n:
+            m = _itemre(str, j)
+            if m:
+                j = m.end() - 1     # index of first interesting char
+                extra = 0
+                break
+            else:
+                # this line is junk; advance to next line
+                i = j = str.find('\n', j) + 1
+        else:
+            # nothing interesting follows the bracket;
+            # reproduce the bracket line's indentation + a level
+            j = i = origi
+            while str[j] in " \t":
+                j = j+1
+            extra = self.indentwidth
+        return len(str[i:j].expandtabs(self.tabwidth)) + extra
+
+    # Return number of physical lines in last stmt (whether or not
+    # it's an interesting stmt!  this is intended to be called when
+    # continuation is C_BACKSLASH).
+
+    def get_num_lines_in_stmt(self):
+        self._study1()
+        goodlines = self.goodlines
+        return goodlines[-1] - goodlines[-2]
+
+    # Assuming continuation is C_BACKSLASH, return the number of spaces
+    # the next line should be indented.  Also assuming the new line is
+    # the first one following the initial line of the stmt.
+
+    def compute_backslash_indent(self):
+        self._study2()
+        assert self.continuation == C_BACKSLASH
+        str = self.str
+        i = self.stmt_start
+        while str[i] in " \t":
+            i = i+1
+        startpos = i
+
+        # See whether the initial line starts an assignment stmt; i.e.,
+        # look for an = operator
+        endpos = str.find('\n', startpos) + 1
+        found = level = 0
+        while i < endpos:
+            ch = str[i]
+            if ch in "([{":
+                level = level + 1
+                i = i+1
+            elif ch in ")]}":
+                if level:
+                    level = level - 1
+                i = i+1
+            elif ch == '"' or ch == "'":
+                i = _match_stringre(str, i, endpos).end()
+            elif ch == '#':
+                break
+            elif level == 0 and ch == '=' and \
+                   (i == 0 or str[i-1] not in "=<>!") and \
+                   str[i+1] != '=':
+                found = 1
+                break
+            else:
+                i = i+1
+
+        if found:
+            # found a legit =, but it may be the last interesting
+            # thing on the line
+            i = i+1     # move beyond the =
+            found = re.match(r"\s*\\", str[i:endpos]) is None
+
+        if not found:
+            # oh well ... settle for moving beyond the first chunk
+            # of non-whitespace chars
+            i = startpos
+            while str[i] not in " \t\n":
+                i = i+1
+
+        return len(str[self.stmt_start:i].expandtabs(\
+                                     self.tabwidth)) + 1
+
+    # Return the leading whitespace on the initial line of the last
+    # interesting stmt.
+
+    def get_base_indent_string(self):
+        self._study2()
+        i, n = self.stmt_start, self.stmt_end
+        j = i
+        str = self.str
+        while j < n and str[j] in " \t":
+            j = j + 1
+        return str[i:j]
+
+    # Did the last interesting stmt open a block?
+
+    def is_block_opener(self):
+        self._study2()
+        return self.lastch == ':'
+
+    # Did the last interesting stmt close a block?
+
+    def is_block_closer(self):
+        self._study2()
+        return _closere(self.str, self.stmt_start) is not None
+
+    # index of last open bracket ({[, or None if none
+    lastopenbracketpos = None
+
+    def get_last_open_bracket_pos(self):
+        self._study2()
+        return self.lastopenbracketpos
+
+    # the structure of the bracketing of the last interesting statement,
+    # in the format defined in _study2, or None if the text didn't contain
+    # anything
+    stmt_bracketing = None
+
+    def get_last_stmt_bracketing(self):
+        self._study2()
+        return self.stmt_bracketing

Added: vendor/Python/current/Lib/idlelib/PyShell.py
===================================================================
--- vendor/Python/current/Lib/idlelib/PyShell.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/PyShell.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1441 @@
+#! /usr/bin/env python
+
+import os
+import os.path
+import sys
+import string
+import getopt
+import re
+import socket
+import time
+import threading
+import traceback
+import types
+import macosxSupport
+
+import linecache
+from code import InteractiveInterpreter
+
+try:
+    from Tkinter import *
+except ImportError:
+    print>>sys.__stderr__, "** IDLE can't import Tkinter.  " \
+                           "Your Python may not be configured for Tk. **"
+    sys.exit(1)
+import tkMessageBox
+
+from EditorWindow import EditorWindow, fixwordbreaks
+from FileList import FileList
+from ColorDelegator import ColorDelegator
+from UndoDelegator import UndoDelegator
+from OutputWindow import OutputWindow
+from configHandler import idleConf
+import idlever
+
+import rpc
+import Debugger
+import RemoteDebugger
+
+IDENTCHARS = string.ascii_letters + string.digits + "_"
+LOCALHOST = '127.0.0.1'
+
+try:
+    from signal import SIGTERM
+except ImportError:
+    SIGTERM = 15
+
+# Override warnings module to write to warning_stream.  Initialize to send IDLE
+# internal warnings to the console.  ScriptBinding.check_syntax() will
+# temporarily redirect the stream to the shell window to display warnings when
+# checking user's code.
+global warning_stream
+warning_stream = sys.__stderr__
+try:
+    import warnings
+except ImportError:
+    pass
+else:
+    def idle_showwarning(message, category, filename, lineno):
+        file = warning_stream
+        try:
+            file.write(warnings.formatwarning(message, category, filename, lineno))
+        except IOError:
+            pass  ## file (probably __stderr__) is invalid, warning dropped.
+    warnings.showwarning = idle_showwarning
+    def idle_formatwarning(message, category, filename, lineno):
+        """Format warnings the IDLE way"""
+        s = "\nWarning (from warnings module):\n"
+        s += '  File \"%s\", line %s\n' % (filename, lineno)
+        line = linecache.getline(filename, lineno).strip()
+        if line:
+            s += "    %s\n" % line
+        s += "%s: %s\n>>> " % (category.__name__, message)
+        return s
+    warnings.formatwarning = idle_formatwarning
+
+def extended_linecache_checkcache(filename=None,
+                                  orig_checkcache=linecache.checkcache):
+    """Extend linecache.checkcache to preserve the <pyshell#...> entries
+
+    Rather than repeating the linecache code, patch it to save the
+    <pyshell#...> entries, call the original linecache.checkcache()
+    (which destroys them), and then restore the saved entries.
+
+    orig_checkcache is bound at definition time to the original
+    method, allowing it to be patched.
+
+    """
+    cache = linecache.cache
+    save = {}
+    for filename in cache.keys():
+        if filename[:1] + filename[-1:] == '<>':
+            save[filename] = cache[filename]
+    orig_checkcache()
+    cache.update(save)
+
+# Patch linecache.checkcache():
+linecache.checkcache = extended_linecache_checkcache
+
+
+class PyShellEditorWindow(EditorWindow):
+    "Regular text edit window in IDLE, supports breakpoints"
+
+    def __init__(self, *args):
+        self.breakpoints = []
+        EditorWindow.__init__(self, *args)
+        self.text.bind("<<set-breakpoint-here>>", self.set_breakpoint_here)
+        self.text.bind("<<clear-breakpoint-here>>", self.clear_breakpoint_here)
+        self.text.bind("<<open-python-shell>>", self.flist.open_shell)
+
+        self.breakpointPath = os.path.join(idleConf.GetUserCfgDir(),
+                                           'breakpoints.lst')
+        # whenever a file is changed, restore breakpoints
+        if self.io.filename: self.restore_file_breaks()
+        def filename_changed_hook(old_hook=self.io.filename_change_hook,
+                                  self=self):
+            self.restore_file_breaks()
+            old_hook()
+        self.io.set_filename_change_hook(filename_changed_hook)
+
+    rmenu_specs = [("Set Breakpoint", "<<set-breakpoint-here>>"),
+                   ("Clear Breakpoint", "<<clear-breakpoint-here>>")]
+
+    def set_breakpoint(self, lineno):
+        text = self.text
+        filename = self.io.filename
+        text.tag_add("BREAK", "%d.0" % lineno, "%d.0" % (lineno+1))
+        try:
+            i = self.breakpoints.index(lineno)
+        except ValueError:  # only add if missing, i.e. do once
+            self.breakpoints.append(lineno)
+        try:    # update the subprocess debugger
+            debug = self.flist.pyshell.interp.debugger
+            debug.set_breakpoint_here(filename, lineno)
+        except: # but debugger may not be active right now....
+            pass
+
+    def set_breakpoint_here(self, event=None):
+        text = self.text
+        filename = self.io.filename
+        if not filename:
+            text.bell()
+            return
+        lineno = int(float(text.index("insert")))
+        self.set_breakpoint(lineno)
+
+    def clear_breakpoint_here(self, event=None):
+        text = self.text
+        filename = self.io.filename
+        if not filename:
+            text.bell()
+            return
+        lineno = int(float(text.index("insert")))
+        try:
+            self.breakpoints.remove(lineno)
+        except:
+            pass
+        text.tag_remove("BREAK", "insert linestart",\
+                        "insert lineend +1char")
+        try:
+            debug = self.flist.pyshell.interp.debugger
+            debug.clear_breakpoint_here(filename, lineno)
+        except:
+            pass
+
+    def clear_file_breaks(self):
+        if self.breakpoints:
+            text = self.text
+            filename = self.io.filename
+            if not filename:
+                text.bell()
+                return
+            self.breakpoints = []
+            text.tag_remove("BREAK", "1.0", END)
+            try:
+                debug = self.flist.pyshell.interp.debugger
+                debug.clear_file_breaks(filename)
+            except:
+                pass
+
+    def store_file_breaks(self):
+        "Save breakpoints when file is saved"
+        # XXX 13 Dec 2002 KBK Currently the file must be saved before it can
+        #     be run.  The breaks are saved at that time.  If we introduce
+        #     a temporary file save feature the save breaks functionality
+        #     needs to be re-verified, since the breaks at the time the
+        #     temp file is created may differ from the breaks at the last
+        #     permanent save of the file.  Currently, a break introduced
+        #     after a save will be effective, but not persistent.
+        #     This is necessary to keep the saved breaks synched with the
+        #     saved file.
+        #
+        #     Breakpoints are set as tagged ranges in the text.  Certain
+        #     kinds of edits cause these ranges to be deleted: Inserting
+        #     or deleting a line just before a breakpoint, and certain
+        #     deletions prior to a breakpoint.  These issues need to be
+        #     investigated and understood.  It's not clear if they are
+        #     Tk issues or IDLE issues, or whether they can actually
+        #     be fixed.  Since a modified file has to be saved before it is
+        #     run, and since self.breakpoints (from which the subprocess
+        #     debugger is loaded) is updated during the save, the visible
+        #     breaks stay synched with the subprocess even if one of these
+        #     unexpected breakpoint deletions occurs.
+        breaks = self.breakpoints
+        filename = self.io.filename
+        try:
+            lines = open(self.breakpointPath,"r").readlines()
+        except IOError:
+            lines = []
+        new_file = open(self.breakpointPath,"w")
+        for line in lines:
+            if not line.startswith(filename + '='):
+                new_file.write(line)
+        self.update_breakpoints()
+        breaks = self.breakpoints
+        if breaks:
+            new_file.write(filename + '=' + str(breaks) + '\n')
+        new_file.close()
+
+    def restore_file_breaks(self):
+        self.text.update()   # this enables setting "BREAK" tags to be visible
+        filename = self.io.filename
+        if filename is None:
+            return
+        if os.path.isfile(self.breakpointPath):
+            lines = open(self.breakpointPath,"r").readlines()
+            for line in lines:
+                if line.startswith(filename + '='):
+                    breakpoint_linenumbers = eval(line[len(filename)+1:])
+                    for breakpoint_linenumber in breakpoint_linenumbers:
+                        self.set_breakpoint(breakpoint_linenumber)
+
+    def update_breakpoints(self):
+        "Retrieves all the breakpoints in the current window"
+        text = self.text
+        ranges = text.tag_ranges("BREAK")
+        linenumber_list = self.ranges_to_linenumbers(ranges)
+        self.breakpoints = linenumber_list
+
+    def ranges_to_linenumbers(self, ranges):
+        lines = []
+        for index in range(0, len(ranges), 2):
+            lineno = int(float(ranges[index]))
+            end = int(float(ranges[index+1]))
+            while lineno < end:
+                lines.append(lineno)
+                lineno += 1
+        return lines
+
+# XXX 13 Dec 2002 KBK Not used currently
+#    def saved_change_hook(self):
+#        "Extend base method - clear breaks if module is modified"
+#        if not self.get_saved():
+#            self.clear_file_breaks()
+#        EditorWindow.saved_change_hook(self)
+
+    def _close(self):
+        "Extend base method - clear breaks when module is closed"
+        self.clear_file_breaks()
+        EditorWindow._close(self)
+
+
+class PyShellFileList(FileList):
+    "Extend base class: IDLE supports a shell and breakpoints"
+
+    # override FileList's class variable, instances return PyShellEditorWindow
+    # instead of EditorWindow when new edit windows are created.
+    EditorWindow = PyShellEditorWindow
+
+    pyshell = None
+
+    def open_shell(self, event=None):
+        if self.pyshell:
+            self.pyshell.top.wakeup()
+        else:
+            self.pyshell = PyShell(self)
+            if self.pyshell:
+                if not self.pyshell.begin():
+                    return None
+        return self.pyshell
+
+
+class ModifiedColorDelegator(ColorDelegator):
+    "Extend base class: colorizer for the shell window itself"
+
+    def __init__(self):
+        ColorDelegator.__init__(self)
+        self.LoadTagDefs()
+
+    def recolorize_main(self):
+        self.tag_remove("TODO", "1.0", "iomark")
+        self.tag_add("SYNC", "1.0", "iomark")
+        ColorDelegator.recolorize_main(self)
+
+    def LoadTagDefs(self):
+        ColorDelegator.LoadTagDefs(self)
+        theme = idleConf.GetOption('main','Theme','name')
+        self.tagdefs.update({
+            "stdin": {'background':None,'foreground':None},
+            "stdout": idleConf.GetHighlight(theme, "stdout"),
+            "stderr": idleConf.GetHighlight(theme, "stderr"),
+            "console": idleConf.GetHighlight(theme, "console"),
+            None: idleConf.GetHighlight(theme, "normal"),
+        })
+
+class ModifiedUndoDelegator(UndoDelegator):
+    "Extend base class: forbid insert/delete before the I/O mark"
+
+    def insert(self, index, chars, tags=None):
+        try:
+            if self.delegate.compare(index, "<", "iomark"):
+                self.delegate.bell()
+                return
+        except TclError:
+            pass
+        UndoDelegator.insert(self, index, chars, tags)
+
+    def delete(self, index1, index2=None):
+        try:
+            if self.delegate.compare(index1, "<", "iomark"):
+                self.delegate.bell()
+                return
+        except TclError:
+            pass
+        UndoDelegator.delete(self, index1, index2)
+
+
+class MyRPCClient(rpc.RPCClient):
+
+    def handle_EOF(self):
+        "Override the base class - just re-raise EOFError"
+        raise EOFError
+
+
+class ModifiedInterpreter(InteractiveInterpreter):
+
+    def __init__(self, tkconsole):
+        self.tkconsole = tkconsole
+        locals = sys.modules['__main__'].__dict__
+        InteractiveInterpreter.__init__(self, locals=locals)
+        self.save_warnings_filters = None
+        self.restarting = False
+        self.subprocess_arglist = self.build_subprocess_arglist()
+
+    port = 8833
+    rpcclt = None
+    rpcpid = None
+
+    def spawn_subprocess(self):
+        args = self.subprocess_arglist
+        self.rpcpid = os.spawnv(os.P_NOWAIT, sys.executable, args)
+
+    def build_subprocess_arglist(self):
+        w = ['-W' + s for s in sys.warnoptions]
+        if 1/2 > 0: # account for new division
+            w.append('-Qnew')
+        # Maybe IDLE is installed and is being accessed via sys.path,
+        # or maybe it's not installed and the idle.py script is being
+        # run from the IDLE source directory.
+        del_exitf = idleConf.GetOption('main', 'General', 'delete-exitfunc',
+                                       default=False, type='bool')
+        if __name__ == 'idlelib.PyShell':
+            command = "__import__('idlelib.run').run.main(%r)" % (del_exitf,)
+        else:
+            command = "__import__('run').main(%r)" % (del_exitf,)
+        if sys.platform[:3] == 'win' and ' ' in sys.executable:
+            # handle embedded space in path by quoting the argument
+            decorated_exec = '"%s"' % sys.executable
+        else:
+            decorated_exec = sys.executable
+        return [decorated_exec] + w + ["-c", command, str(self.port)]
+
+    def start_subprocess(self):
+        # spawning first avoids passing a listening socket to the subprocess
+        self.spawn_subprocess()
+        #time.sleep(20) # test to simulate GUI not accepting connection
+        addr = (LOCALHOST, self.port)
+        # Idle starts listening for connection on localhost
+        for i in range(3):
+            time.sleep(i)
+            try:
+                self.rpcclt = MyRPCClient(addr)
+                break
+            except socket.error, err:
+                pass
+        else:
+            self.display_port_binding_error()
+            return None
+        # Accept the connection from the Python execution server
+        self.rpcclt.listening_sock.settimeout(10)
+        try:
+            self.rpcclt.accept()
+        except socket.timeout, err:
+            self.display_no_subprocess_error()
+            return None
+        self.rpcclt.register("stdin", self.tkconsole)
+        self.rpcclt.register("stdout", self.tkconsole.stdout)
+        self.rpcclt.register("stderr", self.tkconsole.stderr)
+        self.rpcclt.register("flist", self.tkconsole.flist)
+        self.rpcclt.register("linecache", linecache)
+        self.rpcclt.register("interp", self)
+        self.transfer_path()
+        self.poll_subprocess()
+        return self.rpcclt
+
+    def restart_subprocess(self):
+        if self.restarting:
+            return self.rpcclt
+        self.restarting = True
+        # close only the subprocess debugger
+        debug = self.getdebugger()
+        if debug:
+            try:
+                # Only close subprocess debugger, don't unregister gui_adap!
+                RemoteDebugger.close_subprocess_debugger(self.rpcclt)
+            except:
+                pass
+        # Kill subprocess, spawn a new one, accept connection.
+        self.rpcclt.close()
+        self.unix_terminate()
+        console = self.tkconsole
+        was_executing = console.executing
+        console.executing = False
+        self.spawn_subprocess()
+        try:
+            self.rpcclt.accept()
+        except socket.timeout, err:
+            self.display_no_subprocess_error()
+            return None
+        self.transfer_path()
+        # annotate restart in shell window and mark it
+        console.text.delete("iomark", "end-1c")
+        if was_executing:
+            console.write('\n')
+            console.showprompt()
+        halfbar = ((int(console.width) - 16) // 2) * '='
+        console.write(halfbar + ' RESTART ' + halfbar)
+        console.text.mark_set("restart", "end-1c")
+        console.text.mark_gravity("restart", "left")
+        console.showprompt()
+        # restart subprocess debugger
+        if debug:
+            # Restarted debugger connects to current instance of debug GUI
+            gui = RemoteDebugger.restart_subprocess_debugger(self.rpcclt)
+            # reload remote debugger breakpoints for all PyShellEditWindows
+            debug.load_breakpoints()
+        self.restarting = False
+        return self.rpcclt
+
+    def __request_interrupt(self):
+        self.rpcclt.remotecall("exec", "interrupt_the_server", (), {})
+
+    def interrupt_subprocess(self):
+        threading.Thread(target=self.__request_interrupt).start()
+
+    def kill_subprocess(self):
+        try:
+            self.rpcclt.close()
+        except AttributeError:  # no socket
+            pass
+        self.unix_terminate()
+        self.tkconsole.executing = False
+        self.rpcclt = None
+
+    def unix_terminate(self):
+        "UNIX: make sure subprocess is terminated and collect status"
+        if hasattr(os, 'kill'):
+            try:
+                os.kill(self.rpcpid, SIGTERM)
+            except OSError:
+                # process already terminated:
+                return
+            else:
+                try:
+                    os.waitpid(self.rpcpid, 0)
+                except OSError:
+                    return
+
+    def transfer_path(self):
+        self.runcommand("""if 1:
+        import sys as _sys
+        _sys.path = %r
+        del _sys
+        \n""" % (sys.path,))
+
+    active_seq = None
+
+    def poll_subprocess(self):
+        clt = self.rpcclt
+        if clt is None:
+            return
+        try:
+            response = clt.pollresponse(self.active_seq, wait=0.05)
+        except (EOFError, IOError, KeyboardInterrupt):
+            # lost connection or subprocess terminated itself, restart
+            # [the KBI is from rpc.SocketIO.handle_EOF()]
+            if self.tkconsole.closing:
+                return
+            response = None
+            self.restart_subprocess()
+        if response:
+            self.tkconsole.resetoutput()
+            self.active_seq = None
+            how, what = response
+            console = self.tkconsole.console
+            if how == "OK":
+                if what is not None:
+                    print >>console, repr(what)
+            elif how == "EXCEPTION":
+                if self.tkconsole.getvar("<<toggle-jit-stack-viewer>>"):
+                    self.remote_stack_viewer()
+            elif how == "ERROR":
+                errmsg = "PyShell.ModifiedInterpreter: Subprocess ERROR:\n"
+                print >>sys.__stderr__, errmsg, what
+                print >>console, errmsg, what
+            # we received a response to the currently active seq number:
+            try:
+                self.tkconsole.endexecuting()
+            except AttributeError:  # shell may have closed
+                pass
+        # Reschedule myself
+        if not self.tkconsole.closing:
+            self.tkconsole.text.after(self.tkconsole.pollinterval,
+                                      self.poll_subprocess)
+
+    debugger = None
+
+    def setdebugger(self, debugger):
+        self.debugger = debugger
+
+    def getdebugger(self):
+        return self.debugger
+
+    def open_remote_stack_viewer(self):
+        """Initiate the remote stack viewer from a separate thread.
+
+        This method is called from the subprocess, and by returning from this
+        method we allow the subprocess to unblock.  After a bit the shell
+        requests the subprocess to open the remote stack viewer which returns a
+        static object looking at the last exceptiopn.  It is queried through
+        the RPC mechanism.
+
+        """
+        self.tkconsole.text.after(300, self.remote_stack_viewer)
+        return
+
+    def remote_stack_viewer(self):
+        import RemoteObjectBrowser
+        oid = self.rpcclt.remotequeue("exec", "stackviewer", ("flist",), {})
+        if oid is None:
+            self.tkconsole.root.bell()
+            return
+        item = RemoteObjectBrowser.StubObjectTreeItem(self.rpcclt, oid)
+        from TreeWidget import ScrolledCanvas, TreeNode
+        top = Toplevel(self.tkconsole.root)
+        theme = idleConf.GetOption('main','Theme','name')
+        background = idleConf.GetHighlight(theme, 'normal')['background']
+        sc = ScrolledCanvas(top, bg=background, highlightthickness=0)
+        sc.frame.pack(expand=1, fill="both")
+        node = TreeNode(sc.canvas, None, item)
+        node.expand()
+        # XXX Should GC the remote tree when closing the window
+
+    gid = 0
+
+    def execsource(self, source):
+        "Like runsource() but assumes complete exec source"
+        filename = self.stuffsource(source)
+        self.execfile(filename, source)
+
+    def execfile(self, filename, source=None):
+        "Execute an existing file"
+        if source is None:
+            source = open(filename, "r").read()
+        try:
+            code = compile(source, filename, "exec")
+        except (OverflowError, SyntaxError):
+            self.tkconsole.resetoutput()
+            tkerr = self.tkconsole.stderr
+            print>>tkerr, '*** Error in script or command!\n'
+            print>>tkerr, 'Traceback (most recent call last):'
+            InteractiveInterpreter.showsyntaxerror(self, filename)
+            self.tkconsole.showprompt()
+        else:
+            self.runcode(code)
+
+    def runsource(self, source):
+        "Extend base class method: Stuff the source in the line cache first"
+        filename = self.stuffsource(source)
+        self.more = 0
+        self.save_warnings_filters = warnings.filters[:]
+        warnings.filterwarnings(action="error", category=SyntaxWarning)
+        if isinstance(source, types.UnicodeType):
+            import IOBinding
+            try:
+                source = source.encode(IOBinding.encoding)
+            except UnicodeError:
+                self.tkconsole.resetoutput()
+                self.write("Unsupported characters in input\n")
+                return
+        try:
+            # InteractiveInterpreter.runsource() calls its runcode() method,
+            # which is overridden (see below)
+            return InteractiveInterpreter.runsource(self, source, filename)
+        finally:
+            if self.save_warnings_filters is not None:
+                warnings.filters[:] = self.save_warnings_filters
+                self.save_warnings_filters = None
+
+    def stuffsource(self, source):
+        "Stuff source in the filename cache"
+        filename = "<pyshell#%d>" % self.gid
+        self.gid = self.gid + 1
+        lines = source.split("\n")
+        linecache.cache[filename] = len(source)+1, 0, lines, filename
+        return filename
+
+    def prepend_syspath(self, filename):
+        "Prepend sys.path with file's directory if not already included"
+        self.runcommand("""if 1:
+            _filename = %r
+            import sys as _sys
+            from os.path import dirname as _dirname
+            _dir = _dirname(_filename)
+            if not _dir in _sys.path:
+                _sys.path.insert(0, _dir)
+            del _filename, _sys, _dirname, _dir
+            \n""" % (filename,))
+
+    def showsyntaxerror(self, filename=None):
+        """Extend base class method: Add Colorizing
+
+        Color the offending position instead of printing it and pointing at it
+        with a caret.
+
+        """
+        text = self.tkconsole.text
+        stuff = self.unpackerror()
+        if stuff:
+            msg, lineno, offset, line = stuff
+            if lineno == 1:
+                pos = "iomark + %d chars" % (offset-1)
+            else:
+                pos = "iomark linestart + %d lines + %d chars" % \
+                      (lineno-1, offset-1)
+            text.tag_add("ERROR", pos)
+            text.see(pos)
+            char = text.get(pos)
+            if char and char in IDENTCHARS:
+                text.tag_add("ERROR", pos + " wordstart", pos)
+            self.tkconsole.resetoutput()
+            self.write("SyntaxError: %s\n" % str(msg))
+        else:
+            self.tkconsole.resetoutput()
+            InteractiveInterpreter.showsyntaxerror(self, filename)
+        self.tkconsole.showprompt()
+
+    def unpackerror(self):
+        type, value, tb = sys.exc_info()
+        ok = type is SyntaxError
+        if ok:
+            try:
+                msg, (dummy_filename, lineno, offset, line) = value
+                if not offset:
+                    offset = 0
+            except:
+                ok = 0
+        if ok:
+            return msg, lineno, offset, line
+        else:
+            return None
+
+    def showtraceback(self):
+        "Extend base class method to reset output properly"
+        self.tkconsole.resetoutput()
+        self.checklinecache()
+        InteractiveInterpreter.showtraceback(self)
+        if self.tkconsole.getvar("<<toggle-jit-stack-viewer>>"):
+            self.tkconsole.open_stack_viewer()
+
+    def checklinecache(self):
+        c = linecache.cache
+        for key in c.keys():
+            if key[:1] + key[-1:] != "<>":
+                del c[key]
+
+    def runcommand(self, code):
+        "Run the code without invoking the debugger"
+        # The code better not raise an exception!
+        if self.tkconsole.executing:
+            self.display_executing_dialog()
+            return 0
+        if self.rpcclt:
+            self.rpcclt.remotequeue("exec", "runcode", (code,), {})
+        else:
+            exec code in self.locals
+        return 1
+
+    def runcode(self, code):
+        "Override base class method"
+        if self.tkconsole.executing:
+            self.interp.restart_subprocess()
+        self.checklinecache()
+        if self.save_warnings_filters is not None:
+            warnings.filters[:] = self.save_warnings_filters
+            self.save_warnings_filters = None
+        debugger = self.debugger
+        try:
+            self.tkconsole.beginexecuting()
+            try:
+                if not debugger and self.rpcclt is not None:
+                    self.active_seq = self.rpcclt.asyncqueue("exec", "runcode",
+                                                            (code,), {})
+                elif debugger:
+                    debugger.run(code, self.locals)
+                else:
+                    exec code in self.locals
+            except SystemExit:
+                if not self.tkconsole.closing:
+                    if tkMessageBox.askyesno(
+                        "Exit?",
+                        "Do you want to exit altogether?",
+                        default="yes",
+                        master=self.tkconsole.text):
+                        raise
+                    else:
+                        self.showtraceback()
+                else:
+                    raise
+            except:
+                if use_subprocess:
+                    print >> self.tkconsole.stderr, \
+                             "IDLE internal error in runcode()"
+                self.showtraceback()
+                if use_subprocess:
+                    self.tkconsole.endexecuting()
+        finally:
+            if not use_subprocess:
+                try:
+                    self.tkconsole.endexecuting()
+                except AttributeError:  # shell may have closed
+                    pass
+
+    def write(self, s):
+        "Override base class method"
+        self.tkconsole.stderr.write(s)
+
+    def display_port_binding_error(self):
+        tkMessageBox.showerror(
+            "Port Binding Error",
+            "IDLE can't bind TCP/IP port 8833, which is necessary to "
+            "communicate with its Python execution server.  Either "
+            "no networking is installed on this computer or another "
+            "process (another IDLE?) is using the port.  Run IDLE with the -n "
+            "command line switch to start without a subprocess and refer to "
+            "Help/IDLE Help 'Running without a subprocess' for further "
+            "details.",
+            master=self.tkconsole.text)
+
+    def display_no_subprocess_error(self):
+        tkMessageBox.showerror(
+            "Subprocess Startup Error",
+            "IDLE's subprocess didn't make connection.  Either IDLE can't "
+            "start a subprocess or personal firewall software is blocking "
+            "the connection.",
+            master=self.tkconsole.text)
+
+    def display_executing_dialog(self):
+        tkMessageBox.showerror(
+            "Already executing",
+            "The Python Shell window is already executing a command; "
+            "please wait until it is finished.",
+            master=self.tkconsole.text)
+
+
+class PyShell(OutputWindow):
+
+    shell_title = "Python Shell"
+
+    # Override classes
+    ColorDelegator = ModifiedColorDelegator
+    UndoDelegator = ModifiedUndoDelegator
+
+    # Override menus
+    menu_specs = [
+        ("file", "_File"),
+        ("edit", "_Edit"),
+        ("debug", "_Debug"),
+        ("options", "_Options"),
+        ("windows", "_Windows"),
+        ("help", "_Help"),
+    ]
+
+    if macosxSupport.runningAsOSXApp():
+        del menu_specs[-3]
+        menu_specs[-2] = ("windows", "_Window")
+
+
+    # New classes
+    from IdleHistory import History
+
+    def __init__(self, flist=None):
+        if use_subprocess:
+            ms = self.menu_specs
+            if ms[2][0] != "shell":
+                ms.insert(2, ("shell", "She_ll"))
+        self.interp = ModifiedInterpreter(self)
+        if flist is None:
+            root = Tk()
+            fixwordbreaks(root)
+            root.withdraw()
+            flist = PyShellFileList(root)
+        #
+        OutputWindow.__init__(self, flist, None, None)
+        #
+##        self.config(usetabs=1, indentwidth=8, context_use_ps1=1)
+        self.usetabs = True
+        # indentwidth must be 8 when using tabs.  See note in EditorWindow:
+        self.indentwidth = 8
+        self.context_use_ps1 = True
+        #
+        text = self.text
+        text.configure(wrap="char")
+        text.bind("<<newline-and-indent>>", self.enter_callback)
+        text.bind("<<plain-newline-and-indent>>", self.linefeed_callback)
+        text.bind("<<interrupt-execution>>", self.cancel_callback)
+        text.bind("<<beginning-of-line>>", self.home_callback)
+        text.bind("<<end-of-file>>", self.eof_callback)
+        text.bind("<<open-stack-viewer>>", self.open_stack_viewer)
+        text.bind("<<toggle-debugger>>", self.toggle_debugger)
+        text.bind("<<toggle-jit-stack-viewer>>", self.toggle_jit_stack_viewer)
+        if use_subprocess:
+            text.bind("<<view-restart>>", self.view_restart_mark)
+            text.bind("<<restart-shell>>", self.restart_shell)
+        #
+        self.save_stdout = sys.stdout
+        self.save_stderr = sys.stderr
+        self.save_stdin = sys.stdin
+        import IOBinding
+        self.stdout = PseudoFile(self, "stdout", IOBinding.encoding)
+        self.stderr = PseudoFile(self, "stderr", IOBinding.encoding)
+        self.console = PseudoFile(self, "console", IOBinding.encoding)
+        if not use_subprocess:
+            sys.stdout = self.stdout
+            sys.stderr = self.stderr
+            sys.stdin = self
+        #
+        self.history = self.History(self.text)
+        #
+        self.pollinterval = 50  # millisec
+
+    def get_standard_extension_names(self):
+        return idleConf.GetExtensions(shell_only=True)
+
+    reading = False
+    executing = False
+    canceled = False
+    endoffile = False
+    closing = False
+
+    def set_warning_stream(self, stream):
+        global warning_stream
+        warning_stream = stream
+
+    def get_warning_stream(self):
+        return warning_stream
+
+    def toggle_debugger(self, event=None):
+        if self.executing:
+            tkMessageBox.showerror("Don't debug now",
+                "You can only toggle the debugger when idle",
+                master=self.text)
+            self.set_debugger_indicator()
+            return "break"
+        else:
+            db = self.interp.getdebugger()
+            if db:
+                self.close_debugger()
+            else:
+                self.open_debugger()
+
+    def set_debugger_indicator(self):
+        db = self.interp.getdebugger()
+        self.setvar("<<toggle-debugger>>", not not db)
+
+    def toggle_jit_stack_viewer(self, event=None):
+        pass # All we need is the variable
+
+    def close_debugger(self):
+        db = self.interp.getdebugger()
+        if db:
+            self.interp.setdebugger(None)
+            db.close()
+            if self.interp.rpcclt:
+                RemoteDebugger.close_remote_debugger(self.interp.rpcclt)
+            self.resetoutput()
+            self.console.write("[DEBUG OFF]\n")
+            sys.ps1 = ">>> "
+            self.showprompt()
+        self.set_debugger_indicator()
+
+    def open_debugger(self):
+        if self.interp.rpcclt:
+            dbg_gui = RemoteDebugger.start_remote_debugger(self.interp.rpcclt,
+                                                           self)
+        else:
+            dbg_gui = Debugger.Debugger(self)
+        self.interp.setdebugger(dbg_gui)
+        dbg_gui.load_breakpoints()
+        sys.ps1 = "[DEBUG ON]\n>>> "
+        self.showprompt()
+        self.set_debugger_indicator()
+
+    def beginexecuting(self):
+        "Helper for ModifiedInterpreter"
+        self.resetoutput()
+        self.executing = 1
+
+    def endexecuting(self):
+        "Helper for ModifiedInterpreter"
+        self.executing = 0
+        self.canceled = 0
+        self.showprompt()
+
+    def close(self):
+        "Extend EditorWindow.close()"
+        if self.executing:
+            response = tkMessageBox.askokcancel(
+                "Kill?",
+                "The program is still running!\n Do you want to kill it?",
+                default="ok",
+                parent=self.text)
+            if response == False:
+                return "cancel"
+        if self.reading:
+            self.top.quit()
+        self.canceled = True
+        self.closing = True
+        # Wait for poll_subprocess() rescheduling to stop
+        self.text.after(2 * self.pollinterval, self.close2)
+
+    def close2(self):
+        return EditorWindow.close(self)
+
+    def _close(self):
+        "Extend EditorWindow._close(), shut down debugger and execution server"
+        self.close_debugger()
+        if use_subprocess:
+            self.interp.kill_subprocess()
+        # Restore std streams
+        sys.stdout = self.save_stdout
+        sys.stderr = self.save_stderr
+        sys.stdin = self.save_stdin
+        # Break cycles
+        self.interp = None
+        self.console = None
+        self.flist.pyshell = None
+        self.history = None
+        EditorWindow._close(self)
+
+    def ispythonsource(self, filename):
+        "Override EditorWindow method: never remove the colorizer"
+        return True
+
+    def short_title(self):
+        return self.shell_title
+
+    COPYRIGHT = \
+          'Type "copyright", "credits" or "license()" for more information.'
+
+    firewallmessage = """
+    ****************************************************************
+    Personal firewall software may warn about the connection IDLE
+    makes to its subprocess using this computer's internal loopback
+    interface.  This connection is not visible on any external
+    interface and no data is sent to or received from the Internet.
+    ****************************************************************
+    """
+
+    def begin(self):
+        self.resetoutput()
+        if use_subprocess:
+            nosub = ''
+            client = self.interp.start_subprocess()
+            if not client:
+                self.close()
+                return False
+        else:
+            nosub = "==== No Subprocess ===="
+        self.write("Python %s on %s\n%s\n%s\nIDLE %s      %s\n" %
+                   (sys.version, sys.platform, self.COPYRIGHT,
+                    self.firewallmessage, idlever.IDLE_VERSION, nosub))
+        self.showprompt()
+        import Tkinter
+        Tkinter._default_root = None # 03Jan04 KBK What's this?
+        return True
+
+    def readline(self):
+        save = self.reading
+        try:
+            self.reading = 1
+            self.top.mainloop()  # nested mainloop()
+        finally:
+            self.reading = save
+        line = self.text.get("iomark", "end-1c")
+        if len(line) == 0:  # may be EOF if we quit our mainloop with Ctrl-C
+            line = "\n"
+        if isinstance(line, unicode):
+            import IOBinding
+            try:
+                line = line.encode(IOBinding.encoding)
+            except UnicodeError:
+                pass
+        self.resetoutput()
+        if self.canceled:
+            self.canceled = 0
+            if not use_subprocess:
+                raise KeyboardInterrupt
+        if self.endoffile:
+            self.endoffile = 0
+            line = ""
+        return line
+
+    def isatty(self):
+        return True
+
+    def cancel_callback(self, event=None):
+        try:
+            if self.text.compare("sel.first", "!=", "sel.last"):
+                return # Active selection -- always use default binding
+        except:
+            pass
+        if not (self.executing or self.reading):
+            self.resetoutput()
+            self.interp.write("KeyboardInterrupt\n")
+            self.showprompt()
+            return "break"
+        self.endoffile = 0
+        self.canceled = 1
+        if (self.executing and self.interp.rpcclt):
+            if self.interp.getdebugger():
+                self.interp.restart_subprocess()
+            else:
+                self.interp.interrupt_subprocess()
+        if self.reading:
+            self.top.quit()  # exit the nested mainloop() in readline()
+        return "break"
+
+    def eof_callback(self, event):
+        if self.executing and not self.reading:
+            return # Let the default binding (delete next char) take over
+        if not (self.text.compare("iomark", "==", "insert") and
+                self.text.compare("insert", "==", "end-1c")):
+            return # Let the default binding (delete next char) take over
+        if not self.executing:
+            self.resetoutput()
+            self.close()
+        else:
+            self.canceled = 0
+            self.endoffile = 1
+            self.top.quit()
+        return "break"
+
+    def home_callback(self, event):
+        if event.state != 0 and event.keysym == "Home":
+            return # <Modifier-Home>; fall back to class binding
+        if self.text.compare("iomark", "<=", "insert") and \
+           self.text.compare("insert linestart", "<=", "iomark"):
+            self.text.mark_set("insert", "iomark")
+            self.text.tag_remove("sel", "1.0", "end")
+            self.text.see("insert")
+            return "break"
+
+    def linefeed_callback(self, event):
+        # Insert a linefeed without entering anything (still autoindented)
+        if self.reading:
+            self.text.insert("insert", "\n")
+            self.text.see("insert")
+        else:
+            self.newline_and_indent_event(event)
+        return "break"
+
+    def enter_callback(self, event):
+        if self.executing and not self.reading:
+            return # Let the default binding (insert '\n') take over
+        # If some text is selected, recall the selection
+        # (but only if this before the I/O mark)
+        try:
+            sel = self.text.get("sel.first", "sel.last")
+            if sel:
+                if self.text.compare("sel.last", "<=", "iomark"):
+                    self.recall(sel, event)
+                    return "break"
+        except:
+            pass
+        # If we're strictly before the line containing iomark, recall
+        # the current line, less a leading prompt, less leading or
+        # trailing whitespace
+        if self.text.compare("insert", "<", "iomark linestart"):
+            # Check if there's a relevant stdin range -- if so, use it
+            prev = self.text.tag_prevrange("stdin", "insert")
+            if prev and self.text.compare("insert", "<", prev[1]):
+                self.recall(self.text.get(prev[0], prev[1]), event)
+                return "break"
+            next = self.text.tag_nextrange("stdin", "insert")
+            if next and self.text.compare("insert lineend", ">=", next[0]):
+                self.recall(self.text.get(next[0], next[1]), event)
+                return "break"
+            # No stdin mark -- just get the current line, less any prompt
+            indices = self.text.tag_nextrange("console", "insert linestart")
+            if indices and \
+               self.text.compare(indices[0], "<=", "insert linestart"):
+                self.recall(self.text.get(indices[1], "insert lineend"), event)
+            else:
+                self.recall(self.text.get("insert linestart", "insert lineend"), event)
+            return "break"
+        # If we're between the beginning of the line and the iomark, i.e.
+        # in the prompt area, move to the end of the prompt
+        if self.text.compare("insert", "<", "iomark"):
+            self.text.mark_set("insert", "iomark")
+        # If we're in the current input and there's only whitespace
+        # beyond the cursor, erase that whitespace first
+        s = self.text.get("insert", "end-1c")
+        if s and not s.strip():
+            self.text.delete("insert", "end-1c")
+        # If we're in the current input before its last line,
+        # insert a newline right at the insert point
+        if self.text.compare("insert", "<", "end-1c linestart"):
+            self.newline_and_indent_event(event)
+            return "break"
+        # We're in the last line; append a newline and submit it
+        self.text.mark_set("insert", "end-1c")
+        if self.reading:
+            self.text.insert("insert", "\n")
+            self.text.see("insert")
+        else:
+            self.newline_and_indent_event(event)
+        self.text.tag_add("stdin", "iomark", "end-1c")
+        self.text.update_idletasks()
+        if self.reading:
+            self.top.quit() # Break out of recursive mainloop() in raw_input()
+        else:
+            self.runit()
+        return "break"
+
+    def recall(self, s, event):
+        # remove leading and trailing empty or whitespace lines
+        s = re.sub(r'^\s*\n', '' , s)
+        s = re.sub(r'\n\s*$', '', s)
+        lines = s.split('\n')
+        self.text.undo_block_start()
+        try:
+            self.text.tag_remove("sel", "1.0", "end")
+            self.text.mark_set("insert", "end-1c")
+            prefix = self.text.get("insert linestart", "insert")
+            if prefix.rstrip().endswith(':'):
+                self.newline_and_indent_event(event)
+                prefix = self.text.get("insert linestart", "insert")
+            self.text.insert("insert", lines[0].strip())
+            if len(lines) > 1:
+                orig_base_indent = re.search(r'^([ \t]*)', lines[0]).group(0)
+                new_base_indent  = re.search(r'^([ \t]*)', prefix).group(0)
+                for line in lines[1:]:
+                    if line.startswith(orig_base_indent):
+                        # replace orig base indentation with new indentation
+                        line = new_base_indent + line[len(orig_base_indent):]
+                    self.text.insert('insert', '\n'+line.rstrip())
+        finally:
+            self.text.see("insert")
+            self.text.undo_block_stop()
+
+    def runit(self):
+        line = self.text.get("iomark", "end-1c")
+        # Strip off last newline and surrounding whitespace.
+        # (To allow you to hit return twice to end a statement.)
+        i = len(line)
+        while i > 0 and line[i-1] in " \t":
+            i = i-1
+        if i > 0 and line[i-1] == "\n":
+            i = i-1
+        while i > 0 and line[i-1] in " \t":
+            i = i-1
+        line = line[:i]
+        more = self.interp.runsource(line)
+
+    def open_stack_viewer(self, event=None):
+        if self.interp.rpcclt:
+            return self.interp.remote_stack_viewer()
+        try:
+            sys.last_traceback
+        except:
+            tkMessageBox.showerror("No stack trace",
+                "There is no stack trace yet.\n"
+                "(sys.last_traceback is not defined)",
+                master=self.text)
+            return
+        from StackViewer import StackBrowser
+        sv = StackBrowser(self.root, self.flist)
+
+    def view_restart_mark(self, event=None):
+        self.text.see("iomark")
+        self.text.see("restart")
+
+    def restart_shell(self, event=None):
+        self.interp.restart_subprocess()
+
+    def showprompt(self):
+        self.resetoutput()
+        try:
+            s = str(sys.ps1)
+        except:
+            s = ""
+        self.console.write(s)
+        self.text.mark_set("insert", "end-1c")
+        self.set_line_and_column()
+        self.io.reset_undo()
+
+    def resetoutput(self):
+        source = self.text.get("iomark", "end-1c")
+        if self.history:
+            self.history.history_store(source)
+        if self.text.get("end-2c") != "\n":
+            self.text.insert("end-1c", "\n")
+        self.text.mark_set("iomark", "end-1c")
+        self.set_line_and_column()
+        sys.stdout.softspace = 0
+
+    def write(self, s, tags=()):
+        try:
+            self.text.mark_gravity("iomark", "right")
+            OutputWindow.write(self, s, tags, "iomark")
+            self.text.mark_gravity("iomark", "left")
+        except:
+            pass
+        if self.canceled:
+            self.canceled = 0
+            if not use_subprocess:
+                raise KeyboardInterrupt
+
+class PseudoFile(object):
+
+    def __init__(self, shell, tags, encoding=None):
+        self.shell = shell
+        self.tags = tags
+        self.softspace = 0
+        self.encoding = encoding
+
+    def write(self, s):
+        self.shell.write(s, self.tags)
+
+    def writelines(self, l):
+        map(self.write, l)
+
+    def flush(self):
+        pass
+
+    def isatty(self):
+        return True
+
+
+usage_msg = """\
+
+USAGE: idle  [-deins] [-t title] [file]*
+       idle  [-dns] [-t title] (-c cmd | -r file) [arg]*
+       idle  [-dns] [-t title] - [arg]*
+
+  -h         print this help message and exit
+  -n         run IDLE without a subprocess (see Help/IDLE Help for details)
+
+The following options will override the IDLE 'settings' configuration:
+
+  -e         open an edit window
+  -i         open a shell window
+
+The following options imply -i and will open a shell:
+
+  -c cmd     run the command in a shell, or
+  -r file    run script from file
+
+  -d         enable the debugger
+  -s         run $IDLESTARTUP or $PYTHONSTARTUP before anything else
+  -t title   set title of shell window
+
+A default edit window will be bypassed when -c, -r, or - are used.
+
+[arg]* are passed to the command (-c) or script (-r) in sys.argv[1:].
+
+Examples:
+
+idle
+        Open an edit window or shell depending on IDLE's configuration.
+
+idle foo.py foobar.py
+        Edit the files, also open a shell if configured to start with shell.
+
+idle -est "Baz" foo.py
+        Run $IDLESTARTUP or $PYTHONSTARTUP, edit foo.py, and open a shell
+        window with the title "Baz".
+
+idle -c "import sys; print sys.argv" "foo"
+        Open a shell window and run the command, passing "-c" in sys.argv[0]
+        and "foo" in sys.argv[1].
+
+idle -d -s -r foo.py "Hello World"
+        Open a shell window, run a startup script, enable the debugger, and
+        run foo.py, passing "foo.py" in sys.argv[0] and "Hello World" in
+        sys.argv[1].
+
+echo "import sys; print sys.argv" | idle - "foobar"
+        Open a shell window, run the script piped in, passing '' in sys.argv[0]
+        and "foobar" in sys.argv[1].
+"""
+
+def main():
+    global flist, root, use_subprocess
+
+    use_subprocess = True
+    enable_shell = False
+    enable_edit = False
+    debug = False
+    cmd = None
+    script = None
+    startup = False
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], "c:deihnr:st:")
+    except getopt.error, msg:
+        sys.stderr.write("Error: %s\n" % str(msg))
+        sys.stderr.write(usage_msg)
+        sys.exit(2)
+    for o, a in opts:
+        if o == '-c':
+            cmd = a
+            enable_shell = True
+        if o == '-d':
+            debug = True
+            enable_shell = True
+        if o == '-e':
+            enable_edit = True
+        if o == '-h':
+            sys.stdout.write(usage_msg)
+            sys.exit()
+        if o == '-i':
+            enable_shell = True
+        if o == '-n':
+            use_subprocess = False
+        if o == '-r':
+            script = a
+            if os.path.isfile(script):
+                pass
+            else:
+                print "No script file: ", script
+                sys.exit()
+            enable_shell = True
+        if o == '-s':
+            startup = True
+            enable_shell = True
+        if o == '-t':
+            PyShell.shell_title = a
+            enable_shell = True
+    if args and args[0] == '-':
+        cmd = sys.stdin.read()
+        enable_shell = True
+    # process sys.argv and sys.path:
+    for i in range(len(sys.path)):
+        sys.path[i] = os.path.abspath(sys.path[i])
+    if args and args[0] == '-':
+        sys.argv = [''] + args[1:]
+    elif cmd:
+        sys.argv = ['-c'] + args
+    elif script:
+        sys.argv = [script] + args
+    elif args:
+        enable_edit = True
+        pathx = []
+        for filename in args:
+            pathx.append(os.path.dirname(filename))
+        for dir in pathx:
+            dir = os.path.abspath(dir)
+            if not dir in sys.path:
+                sys.path.insert(0, dir)
+    else:
+        dir = os.getcwd()
+        if not dir in sys.path:
+            sys.path.insert(0, dir)
+    # check the IDLE settings configuration (but command line overrides)
+    edit_start = idleConf.GetOption('main', 'General',
+                                    'editor-on-startup', type='bool')
+    enable_edit = enable_edit or edit_start
+    enable_shell = enable_shell or not edit_start
+    # start editor and/or shell windows:
+    root = Tk(className="Idle")
+
+    fixwordbreaks(root)
+    root.withdraw()
+    flist = PyShellFileList(root)
+    macosxSupport.setupApp(root, flist)
+
+    if enable_edit:
+        if not (cmd or script):
+            for filename in args:
+                flist.open(filename)
+            if not args:
+                flist.new()
+    if enable_shell:
+        shell = flist.open_shell()
+        if not shell:
+            return # couldn't open shell
+
+        if macosxSupport.runningAsOSXApp() and flist.dict:
+            # On OSX: when the user has double-clicked on a file that causes
+            # IDLE to be launched the shell window will open just in front of
+            # the file she wants to see. Lower the interpreter window when
+            # there are open files.
+            shell.top.lower()
+
+    shell = flist.pyshell
+    # handle remaining options:
+    if debug:
+        shell.open_debugger()
+    if startup:
+        filename = os.environ.get("IDLESTARTUP") or \
+                   os.environ.get("PYTHONSTARTUP")
+        if filename and os.path.isfile(filename):
+            shell.interp.execfile(filename)
+    if shell and cmd or script:
+        shell.interp.runcommand("""if 1:
+            import sys as _sys
+            _sys.argv = %r
+            del _sys
+            \n""" % (sys.argv,))
+        if cmd:
+            shell.interp.execsource(cmd)
+        elif script:
+            shell.interp.prepend_syspath(script)
+            shell.interp.execfile(script)
+
+    root.mainloop()
+    root.destroy()
+
+if __name__ == "__main__":
+    sys.modules['PyShell'] = sys.modules['__main__']
+    main()

Added: vendor/Python/current/Lib/idlelib/README.txt
===================================================================
--- vendor/Python/current/Lib/idlelib/README.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/README.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,63 @@
+IDLE is Python's Tkinter-based Integrated DeveLopment Environment.
+
+IDLE emphasizes a lightweight, clean design with a simple user interface.
+Although it is suitable for beginners, even advanced users will find that
+IDLE has everything they really need to develop pure Python code.
+
+IDLE features a multi-window text editor with multiple undo, Python colorizing,
+and many other capabilities, e.g. smart indent, call tips, and autocompletion.
+
+The editor has comprehensive search functions, including searching through
+multiple files.  Class browsers and path browsers provide fast access to
+code objects from a top level viewpoint without dealing with code folding.
+
+There is a Python Shell window which features colorizing and command recall.
+
+IDLE executes Python code in a separate process, which is restarted for each
+Run (F5) initiated from an editor window.  The environment can also be 
+restarted from the Shell window without restarting IDLE.
+
+This enhancement has often been requested, and is now finally available.  The
+magic "reload/import *" incantations are no longer required when editing and
+testing a module two or three steps down the import chain.
+
+(Personal firewall software may warn about the connection IDLE makes to its
+subprocess using this computer's internal loopback interface.  This connection
+is not visible on any external interface and no data is sent to or received
+from the Internet.)
+
+It is possible to interrupt tightly looping user code, even on Windows.
+
+Applications which cannot support subprocesses and/or sockets can still run
+IDLE in a single process.
+
+IDLE has an integrated debugger with stepping, persistent breakpoints, and call
+stack visibility.
+
+There is a GUI configuration manager which makes it easy to select fonts,
+colors, keybindings, and startup options.  This facility includes a feature
+which allows the user to specify additional help sources, either locally or on
+the web.
+
+IDLE is coded in 100% pure Python, using the Tkinter GUI toolkit (Tk/Tcl)
+and is cross-platform, working on Unix, Mac, and Windows.
+
+IDLE accepts command line arguments.  Try idle -h to see the options.
+
+
+If you find bugs or have suggestions, let us know about them by using the
+Python Bug Tracker:
+
+http://sourceforge.net/projects/python
+
+Patches are always appreciated at the Python Patch Tracker, and change
+requests should be posted to the RFE Tracker.
+
+For further details and links, read the Help files and check the IDLE home
+page at
+
+http://www.python.org/idle/
+
+There is a mail list for IDLE: idle-dev at python.org.  You can join at
+
+http://mail.python.org/mailman/listinfo/idle-dev

Added: vendor/Python/current/Lib/idlelib/RemoteDebugger.py
===================================================================
--- vendor/Python/current/Lib/idlelib/RemoteDebugger.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/RemoteDebugger.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,381 @@
+"""Support for remote Python debugging.
+
+Some ASCII art to describe the structure:
+
+       IN PYTHON SUBPROCESS          #             IN IDLE PROCESS
+                                     #
+                                     #        oid='gui_adapter'
+                 +----------+        #       +------------+          +-----+
+                 | GUIProxy |--remote#call-->| GUIAdapter |--calls-->| GUI |
++-----+--calls-->+----------+        #       +------------+          +-----+
+| Idb |                               #                             /
++-----+<-calls--+------------+         #      +----------+<--calls-/
+                | IdbAdapter |<--remote#call--| IdbProxy |
+                +------------+         #      +----------+
+                oid='idb_adapter'      #
+
+The purpose of the Proxy and Adapter classes is to translate certain
+arguments and return values that cannot be transported through the RPC
+barrier, in particular frame and traceback objects.
+
+"""
+
+import sys
+import types
+import rpc
+import Debugger
+
+debugging = 0
+
+idb_adap_oid = "idb_adapter"
+gui_adap_oid = "gui_adapter"
+
+#=======================================
+#
+# In the PYTHON subprocess:
+
+frametable = {}
+dicttable = {}
+codetable = {}
+tracebacktable = {}
+
+def wrap_frame(frame):
+    fid = id(frame)
+    frametable[fid] = frame
+    return fid
+
+def wrap_info(info):
+    "replace info[2], a traceback instance, by its ID"
+    if info is None:
+        return None
+    else:
+        traceback = info[2]
+        assert isinstance(traceback, types.TracebackType)
+        traceback_id = id(traceback)
+        tracebacktable[traceback_id] = traceback
+        modified_info = (info[0], info[1], traceback_id)
+        return modified_info
+
+class GUIProxy:
+
+    def __init__(self, conn, gui_adap_oid):
+        self.conn = conn
+        self.oid = gui_adap_oid
+
+    def interaction(self, message, frame, info=None):
+        # calls rpc.SocketIO.remotecall() via run.MyHandler instance
+        # pass frame and traceback object IDs instead of the objects themselves
+        self.conn.remotecall(self.oid, "interaction",
+                             (message, wrap_frame(frame), wrap_info(info)),
+                             {})
+
+class IdbAdapter:
+
+    def __init__(self, idb):
+        self.idb = idb
+
+    #----------called by an IdbProxy----------
+
+    def set_step(self):
+        self.idb.set_step()
+
+    def set_quit(self):
+        self.idb.set_quit()
+
+    def set_continue(self):
+        self.idb.set_continue()
+
+    def set_next(self, fid):
+        frame = frametable[fid]
+        self.idb.set_next(frame)
+
+    def set_return(self, fid):
+        frame = frametable[fid]
+        self.idb.set_return(frame)
+
+    def get_stack(self, fid, tbid):
+        ##print >>sys.__stderr__, "get_stack(%r, %r)" % (fid, tbid)
+        frame = frametable[fid]
+        if tbid is None:
+            tb = None
+        else:
+            tb = tracebacktable[tbid]
+        stack, i = self.idb.get_stack(frame, tb)
+        ##print >>sys.__stderr__, "get_stack() ->", stack
+        stack = [(wrap_frame(frame), k) for frame, k in stack]
+        ##print >>sys.__stderr__, "get_stack() ->", stack
+        return stack, i
+
+    def run(self, cmd):
+        import __main__
+        self.idb.run(cmd, __main__.__dict__)
+
+    def set_break(self, filename, lineno):
+        msg = self.idb.set_break(filename, lineno)
+        return msg
+
+    def clear_break(self, filename, lineno):
+        msg = self.idb.clear_break(filename, lineno)
+        return msg
+
+    def clear_all_file_breaks(self, filename):
+        msg = self.idb.clear_all_file_breaks(filename)
+        return msg
+
+    #----------called by a FrameProxy----------
+
+    def frame_attr(self, fid, name):
+        frame = frametable[fid]
+        return getattr(frame, name)
+
+    def frame_globals(self, fid):
+        frame = frametable[fid]
+        dict = frame.f_globals
+        did = id(dict)
+        dicttable[did] = dict
+        return did
+
+    def frame_locals(self, fid):
+        frame = frametable[fid]
+        dict = frame.f_locals
+        did = id(dict)
+        dicttable[did] = dict
+        return did
+
+    def frame_code(self, fid):
+        frame = frametable[fid]
+        code = frame.f_code
+        cid = id(code)
+        codetable[cid] = code
+        return cid
+
+    #----------called by a CodeProxy----------
+
+    def code_name(self, cid):
+        code = codetable[cid]
+        return code.co_name
+
+    def code_filename(self, cid):
+        code = codetable[cid]
+        return code.co_filename
+
+    #----------called by a DictProxy----------
+
+    def dict_keys(self, did):
+        dict = dicttable[did]
+        return dict.keys()
+
+    def dict_item(self, did, key):
+        dict = dicttable[did]
+        value = dict[key]
+        value = repr(value)
+        return value
+
+#----------end class IdbAdapter----------
+
+
+def start_debugger(rpchandler, gui_adap_oid):
+    """Start the debugger and its RPC link in the Python subprocess
+
+    Start the subprocess side of the split debugger and set up that side of the
+    RPC link by instantiating the GUIProxy, Idb debugger, and IdbAdapter
+    objects and linking them together.  Register the IdbAdapter with the
+    RPCServer to handle RPC requests from the split debugger GUI via the
+    IdbProxy.
+
+    """
+    gui_proxy = GUIProxy(rpchandler, gui_adap_oid)
+    idb = Debugger.Idb(gui_proxy)
+    idb_adap = IdbAdapter(idb)
+    rpchandler.register(idb_adap_oid, idb_adap)
+    return idb_adap_oid
+
+
+#=======================================
+#
+# In the IDLE process:
+
+
+class FrameProxy:
+
+    def __init__(self, conn, fid):
+        self._conn = conn
+        self._fid = fid
+        self._oid = "idb_adapter"
+        self._dictcache = {}
+
+    def __getattr__(self, name):
+        if name[:1] == "_":
+            raise AttributeError, name
+        if name == "f_code":
+            return self._get_f_code()
+        if name == "f_globals":
+            return self._get_f_globals()
+        if name == "f_locals":
+            return self._get_f_locals()
+        return self._conn.remotecall(self._oid, "frame_attr",
+                                     (self._fid, name), {})
+
+    def _get_f_code(self):
+        cid = self._conn.remotecall(self._oid, "frame_code", (self._fid,), {})
+        return CodeProxy(self._conn, self._oid, cid)
+
+    def _get_f_globals(self):
+        did = self._conn.remotecall(self._oid, "frame_globals",
+                                    (self._fid,), {})
+        return self._get_dict_proxy(did)
+
+    def _get_f_locals(self):
+        did = self._conn.remotecall(self._oid, "frame_locals",
+                                    (self._fid,), {})
+        return self._get_dict_proxy(did)
+
+    def _get_dict_proxy(self, did):
+        if self._dictcache.has_key(did):
+            return self._dictcache[did]
+        dp = DictProxy(self._conn, self._oid, did)
+        self._dictcache[did] = dp
+        return dp
+
+
+class CodeProxy:
+
+    def __init__(self, conn, oid, cid):
+        self._conn = conn
+        self._oid = oid
+        self._cid = cid
+
+    def __getattr__(self, name):
+        if name == "co_name":
+            return self._conn.remotecall(self._oid, "code_name",
+                                         (self._cid,), {})
+        if name == "co_filename":
+            return self._conn.remotecall(self._oid, "code_filename",
+                                         (self._cid,), {})
+
+
+class DictProxy:
+
+    def __init__(self, conn, oid, did):
+        self._conn = conn
+        self._oid = oid
+        self._did = did
+
+    def keys(self):
+        return self._conn.remotecall(self._oid, "dict_keys", (self._did,), {})
+
+    def __getitem__(self, key):
+        return self._conn.remotecall(self._oid, "dict_item",
+                                     (self._did, key), {})
+
+    def __getattr__(self, name):
+        ##print >>sys.__stderr__, "failed DictProxy.__getattr__:", name
+        raise AttributeError, name
+
+
+class GUIAdapter:
+
+    def __init__(self, conn, gui):
+        self.conn = conn
+        self.gui = gui
+
+    def interaction(self, message, fid, modified_info):
+        ##print "interaction: (%s, %s, %s)" % (message, fid, modified_info)
+        frame = FrameProxy(self.conn, fid)
+        self.gui.interaction(message, frame, modified_info)
+
+
+class IdbProxy:
+
+    def __init__(self, conn, shell, oid):
+        self.oid = oid
+        self.conn = conn
+        self.shell = shell
+
+    def call(self, methodname, *args, **kwargs):
+        ##print "**IdbProxy.call %s %s %s" % (methodname, args, kwargs)
+        value = self.conn.remotecall(self.oid, methodname, args, kwargs)
+        ##print "**IdbProxy.call %s returns %r" % (methodname, value)
+        return value
+
+    def run(self, cmd, locals):
+        # Ignores locals on purpose!
+        seq = self.conn.asyncqueue(self.oid, "run", (cmd,), {})
+        self.shell.interp.active_seq = seq
+
+    def get_stack(self, frame, tbid):
+        # passing frame and traceback IDs, not the objects themselves
+        stack, i = self.call("get_stack", frame._fid, tbid)
+        stack = [(FrameProxy(self.conn, fid), k) for fid, k in stack]
+        return stack, i
+
+    def set_continue(self):
+        self.call("set_continue")
+
+    def set_step(self):
+        self.call("set_step")
+
+    def set_next(self, frame):
+        self.call("set_next", frame._fid)
+
+    def set_return(self, frame):
+        self.call("set_return", frame._fid)
+
+    def set_quit(self):
+        self.call("set_quit")
+
+    def set_break(self, filename, lineno):
+        msg = self.call("set_break", filename, lineno)
+        return msg
+
+    def clear_break(self, filename, lineno):
+        msg = self.call("clear_break", filename, lineno)
+        return msg
+
+    def clear_all_file_breaks(self, filename):
+        msg = self.call("clear_all_file_breaks", filename)
+        return msg
+
+def start_remote_debugger(rpcclt, pyshell):
+    """Start the subprocess debugger, initialize the debugger GUI and RPC link
+
+    Request the RPCServer start the Python subprocess debugger and link.  Set
+    up the Idle side of the split debugger by instantiating the IdbProxy,
+    debugger GUI, and debugger GUIAdapter objects and linking them together.
+
+    Register the GUIAdapter with the RPCClient to handle debugger GUI
+    interaction requests coming from the subprocess debugger via the GUIProxy.
+
+    The IdbAdapter will pass execution and environment requests coming from the
+    Idle debugger GUI to the subprocess debugger via the IdbProxy.
+
+    """
+    global idb_adap_oid
+
+    idb_adap_oid = rpcclt.remotecall("exec", "start_the_debugger",\
+                                   (gui_adap_oid,), {})
+    idb_proxy = IdbProxy(rpcclt, pyshell, idb_adap_oid)
+    gui = Debugger.Debugger(pyshell, idb_proxy)
+    gui_adap = GUIAdapter(rpcclt, gui)
+    rpcclt.register(gui_adap_oid, gui_adap)
+    return gui
+
+def close_remote_debugger(rpcclt):
+    """Shut down subprocess debugger and Idle side of debugger RPC link
+
+    Request that the RPCServer shut down the subprocess debugger and link.
+    Unregister the GUIAdapter, which will cause a GC on the Idle process
+    debugger and RPC link objects.  (The second reference to the debugger GUI
+    is deleted in PyShell.close_remote_debugger().)
+
+    """
+    close_subprocess_debugger(rpcclt)
+    rpcclt.unregister(gui_adap_oid)
+
+def close_subprocess_debugger(rpcclt):
+    rpcclt.remotecall("exec", "stop_the_debugger", (idb_adap_oid,), {})
+
+def restart_subprocess_debugger(rpcclt):
+    idb_adap_oid_ret = rpcclt.remotecall("exec", "start_the_debugger",\
+                                         (gui_adap_oid,), {})
+    assert idb_adap_oid_ret == idb_adap_oid, 'Idb restarted with different oid'

Added: vendor/Python/current/Lib/idlelib/RemoteObjectBrowser.py
===================================================================
--- vendor/Python/current/Lib/idlelib/RemoteObjectBrowser.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/RemoteObjectBrowser.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,36 @@
+import rpc
+
+def remote_object_tree_item(item):
+    wrapper = WrappedObjectTreeItem(item)
+    oid = id(wrapper)
+    rpc.objecttable[oid] = wrapper
+    return oid
+
+class WrappedObjectTreeItem:
+    # Lives in PYTHON subprocess
+
+    def __init__(self, item):
+        self.__item = item
+
+    def __getattr__(self, name):
+        value = getattr(self.__item, name)
+        return value
+
+    def _GetSubList(self):
+        list = self.__item._GetSubList()
+        return map(remote_object_tree_item, list)
+
+class StubObjectTreeItem:
+    # Lives in IDLE process
+
+    def __init__(self, sockio, oid):
+        self.sockio = sockio
+        self.oid = oid
+
+    def __getattr__(self, name):
+        value = rpc.MethodProxy(self.sockio, self.oid, name)
+        return value
+
+    def _GetSubList(self):
+        list = self.sockio.remotecall(self.oid, "_GetSubList", (), {})
+        return [StubObjectTreeItem(self.sockio, oid) for oid in list]

Added: vendor/Python/current/Lib/idlelib/ReplaceDialog.py
===================================================================
--- vendor/Python/current/Lib/idlelib/ReplaceDialog.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/ReplaceDialog.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,167 @@
+from Tkinter import *
+import SearchEngine
+from SearchDialogBase import SearchDialogBase
+
+def replace(text):
+    root = text._root()
+    engine = SearchEngine.get(root)
+    if not hasattr(engine, "_replacedialog"):
+        engine._replacedialog = ReplaceDialog(root, engine)
+    dialog = engine._replacedialog
+    dialog.open(text)
+
+class ReplaceDialog(SearchDialogBase):
+
+    title = "Replace Dialog"
+    icon = "Replace"
+
+    def __init__(self, root, engine):
+        SearchDialogBase.__init__(self, root, engine)
+        self.replvar = StringVar(root)
+
+    def open(self, text):
+        SearchDialogBase.open(self, text)
+        try:
+            first = text.index("sel.first")
+        except TclError:
+            first = None
+        try:
+            last = text.index("sel.last")
+        except TclError:
+            last = None
+        first = first or text.index("insert")
+        last = last or first
+        self.show_hit(first, last)
+        self.ok = 1
+
+    def create_entries(self):
+        SearchDialogBase.create_entries(self)
+        self.replent = self.make_entry("Replace with:", self.replvar)
+
+    def create_command_buttons(self):
+        SearchDialogBase.create_command_buttons(self)
+        self.make_button("Find", self.find_it)
+        self.make_button("Replace", self.replace_it)
+        self.make_button("Replace+Find", self.default_command, 1)
+        self.make_button("Replace All", self.replace_all)
+
+    def find_it(self, event=None):
+        self.do_find(0)
+
+    def replace_it(self, event=None):
+        if self.do_find(self.ok):
+            self.do_replace()
+
+    def default_command(self, event=None):
+        if self.do_find(self.ok):
+            self.do_replace()
+            self.do_find(0)
+
+    def replace_all(self, event=None):
+        prog = self.engine.getprog()
+        if not prog:
+            return
+        repl = self.replvar.get()
+        text = self.text
+        res = self.engine.search_text(text, prog)
+        if not res:
+            text.bell()
+            return
+        text.tag_remove("sel", "1.0", "end")
+        text.tag_remove("hit", "1.0", "end")
+        line = res[0]
+        col = res[1].start()
+        if self.engine.iswrap():
+            line = 1
+            col = 0
+        ok = 1
+        first = last = None
+        # XXX ought to replace circular instead of top-to-bottom when wrapping
+        text.undo_block_start()
+        while 1:
+            res = self.engine.search_forward(text, prog, line, col, 0, ok)
+            if not res:
+                break
+            line, m = res
+            chars = text.get("%d.0" % line, "%d.0" % (line+1))
+            orig = m.group()
+            new = m.expand(repl)
+            i, j = m.span()
+            first = "%d.%d" % (line, i)
+            last = "%d.%d" % (line, j)
+            if new == orig:
+                text.mark_set("insert", last)
+            else:
+                text.mark_set("insert", first)
+                if first != last:
+                    text.delete(first, last)
+                if new:
+                    text.insert(first, new)
+            col = i + len(new)
+            ok = 0
+        text.undo_block_stop()
+        if first and last:
+            self.show_hit(first, last)
+        self.close()
+
+    def do_find(self, ok=0):
+        if not self.engine.getprog():
+            return False
+        text = self.text
+        res = self.engine.search_text(text, None, ok)
+        if not res:
+            text.bell()
+            return False
+        line, m = res
+        i, j = m.span()
+        first = "%d.%d" % (line, i)
+        last = "%d.%d" % (line, j)
+        self.show_hit(first, last)
+        self.ok = 1
+        return True
+
+    def do_replace(self):
+        prog = self.engine.getprog()
+        if not prog:
+            return False
+        text = self.text
+        try:
+            first = pos = text.index("sel.first")
+            last = text.index("sel.last")
+        except TclError:
+            pos = None
+        if not pos:
+            first = last = pos = text.index("insert")
+        line, col = SearchEngine.get_line_col(pos)
+        chars = text.get("%d.0" % line, "%d.0" % (line+1))
+        m = prog.match(chars, col)
+        if not prog:
+            return False
+        new = m.expand(self.replvar.get())
+        text.mark_set("insert", first)
+        text.undo_block_start()
+        if m.group():
+            text.delete(first, last)
+        if new:
+            text.insert(first, new)
+        text.undo_block_stop()
+        self.show_hit(first, text.index("insert"))
+        self.ok = 0
+        return True
+
+    def show_hit(self, first, last):
+        text = self.text
+        text.mark_set("insert", first)
+        text.tag_remove("sel", "1.0", "end")
+        text.tag_add("sel", first, last)
+        text.tag_remove("hit", "1.0", "end")
+        if first == last:
+            text.tag_add("hit", first)
+        else:
+            text.tag_add("hit", first, last)
+        text.see("insert")
+        text.update_idletasks()
+
+    def close(self, event=None):
+        SearchDialogBase.close(self, event)
+        self.text.tag_remove("hit", "1.0", "end")

Added: vendor/Python/current/Lib/idlelib/ScriptBinding.py
===================================================================
--- vendor/Python/current/Lib/idlelib/ScriptBinding.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/ScriptBinding.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,210 @@
+"""Extension to execute code outside the Python shell window.
+
+This adds the following commands:
+
+- Check module does a full syntax check of the current module.
+  It also runs the tabnanny to catch any inconsistent tabs.
+
+- Run module executes the module's code in the __main__ namespace.  The window
+  must have been saved previously. The module is added to sys.modules, and is
+  also added to the __main__ namespace.
+
+XXX GvR Redesign this interface (yet again) as follows:
+
+- Present a dialog box for ``Run Module''
+
+- Allow specify command line arguments in the dialog box
+
+"""
+
+import os
+import re
+import string
+import tabnanny
+import tokenize
+import tkMessageBox
+import PyShell
+
+from configHandler import idleConf
+
+IDENTCHARS = string.ascii_letters + string.digits + "_"
+
+indent_message = """Error: Inconsistent indentation detected!
+
+1) Your indentation is outright incorrect (easy to fix), OR
+
+2) Your indentation mixes tabs and spaces.
+
+To fix case 2, change all tabs to spaces by using Edit->Select All followed \
+by Format->Untabify Region and specify the number of columns used by each tab.
+"""
+
+class ScriptBinding:
+
+    menudefs = [
+        ('run', [None,
+                 ('Check Module', '<<check-module>>'),
+                 ('Run Module', '<<run-module>>'), ]), ]
+
+    def __init__(self, editwin):
+        self.editwin = editwin
+        # Provide instance variables referenced by Debugger
+        # XXX This should be done differently
+        self.flist = self.editwin.flist
+        self.root = self.editwin.root
+
+    def check_module_event(self, event):
+        filename = self.getfilename()
+        if not filename:
+            return
+        if not self.tabnanny(filename):
+            return
+        self.checksyntax(filename)
+
+    def tabnanny(self, filename):
+        f = open(filename, 'r')
+        try:
+            tabnanny.process_tokens(tokenize.generate_tokens(f.readline))
+        except tokenize.TokenError, msg:
+            msgtxt, (lineno, start) = msg
+            self.editwin.gotoline(lineno)
+            self.errorbox("Tabnanny Tokenizing Error",
+                          "Token Error: %s" % msgtxt)
+            return False
+        except tabnanny.NannyNag, nag:
+            # The error messages from tabnanny are too confusing...
+            self.editwin.gotoline(nag.get_lineno())
+            self.errorbox("Tab/space error", indent_message)
+            return False
+        except IndentationError:
+            # From tokenize(), let compile() in checksyntax find it again.
+            pass
+        return True
+
+    def checksyntax(self, filename):
+        self.shell = shell = self.flist.open_shell()
+        saved_stream = shell.get_warning_stream()
+        shell.set_warning_stream(shell.stderr)
+        f = open(filename, 'r')
+        source = f.read()
+        f.close()
+        if '\r' in source:
+            source = re.sub(r"\r\n", "\n", source)
+            source = re.sub(r"\r", "\n", source)
+        if source and source[-1] != '\n':
+            source = source + '\n'
+        text = self.editwin.text
+        text.tag_remove("ERROR", "1.0", "end")
+        try:
+            try:
+                # If successful, return the compiled code
+                return compile(source, filename, "exec")
+            except (SyntaxError, OverflowError), err:
+                try:
+                    msg, (errorfilename, lineno, offset, line) = err
+                    if not errorfilename:
+                        err.args = msg, (filename, lineno, offset, line)
+                        err.filename = filename
+                    self.colorize_syntax_error(msg, lineno, offset)
+                except:
+                    msg = "*** " + str(err)
+                self.errorbox("Syntax error",
+                              "There's an error in your program:\n" + msg)
+                return False
+        finally:
+            shell.set_warning_stream(saved_stream)
+
+    def colorize_syntax_error(self, msg, lineno, offset):
+        text = self.editwin.text
+        pos = "0.0 + %d lines + %d chars" % (lineno-1, offset-1)
+        text.tag_add("ERROR", pos)
+        char = text.get(pos)
+        if char and char in IDENTCHARS:
+            text.tag_add("ERROR", pos + " wordstart", pos)
+        if '\n' == text.get(pos):   # error at line end
+            text.mark_set("insert", pos)
+        else:
+            text.mark_set("insert", pos + "+1c")
+        text.see(pos)
+
+    def run_module_event(self, event):
+        """Run the module after setting up the environment.
+
+        First check the syntax.  If OK, make sure the shell is active and
+        then transfer the arguments, set the run environment's working
+        directory to the directory of the module being executed and also
+        add that directory to its sys.path if not already included.
+
+        """
+        filename = self.getfilename()
+        if not filename:
+            return
+        if not self.tabnanny(filename):
+            return
+        code = self.checksyntax(filename)
+        if not code:
+            return
+        shell = self.shell
+        interp = shell.interp
+        if PyShell.use_subprocess:
+            shell.restart_shell()
+        dirname = os.path.dirname(filename)
+        # XXX Too often this discards arguments the user just set...
+        interp.runcommand("""if 1:
+            _filename = %r
+            import sys as _sys
+            from os.path import basename as _basename
+            if (not _sys.argv or
+                _basename(_sys.argv[0]) != _basename(_filename)):
+                _sys.argv = [_filename]
+            import os as _os
+            _os.chdir(%r)
+            del _filename, _sys, _basename, _os
+            \n""" % (filename, dirname))
+        interp.prepend_syspath(filename)
+        # XXX KBK 03Jul04 When run w/o subprocess, runtime warnings still
+        #         go to __stderr__.  With subprocess, they go to the shell.
+        #         Need to change streams in PyShell.ModifiedInterpreter.
+        interp.runcode(code)
+
+    def getfilename(self):
+        """Get source filename.  If not saved, offer to save (or create) file
+
+        The debugger requires a source file.  Make sure there is one, and that
+        the current version of the source buffer has been saved.  If the user
+        declines to save or cancels the Save As dialog, return None.
+
+        If the user has configured IDLE for Autosave, the file will be
+        silently saved if it already exists and is dirty.
+
+        """
+        filename = self.editwin.io.filename
+        if not self.editwin.get_saved():
+            autosave = idleConf.GetOption('main', 'General',
+                                          'autosave', type='bool')
+            if autosave and filename:
+                self.editwin.io.save(None)
+            else:
+                reply = self.ask_save_dialog()
+                self.editwin.text.focus_set()
+                if reply == "ok":
+                    self.editwin.io.save(None)
+                    filename = self.editwin.io.filename
+                else:
+                    filename = None
+        return filename
+
+    def ask_save_dialog(self):
+        msg = "Source Must Be Saved\n" + 5*' ' + "OK to Save?"
+        mb = tkMessageBox.Message(title="Save Before Run or Check",
+                                  message=msg,
+                                  icon=tkMessageBox.QUESTION,
+                                  type=tkMessageBox.OKCANCEL,
+                                  default=tkMessageBox.OK,
+                                  master=self.editwin.text)
+        return mb.show()
+
+    def errorbox(self, title, message):
+        # XXX This should really be a function of EditorWindow...
+        tkMessageBox.showerror(title, message, master=self.editwin.text)
+        self.editwin.text.focus_set()

Added: vendor/Python/current/Lib/idlelib/ScrolledList.py
===================================================================
--- vendor/Python/current/Lib/idlelib/ScrolledList.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/ScrolledList.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,139 @@
+from Tkinter import *
+
+class ScrolledList:
+
+    default = "(None)"
+
+    def __init__(self, master, **options):
+        # Create top frame, with scrollbar and listbox
+        self.master = master
+        self.frame = frame = Frame(master)
+        self.frame.pack(fill="both", expand=1)
+        self.vbar = vbar = Scrollbar(frame, name="vbar")
+        self.vbar.pack(side="right", fill="y")
+        self.listbox = listbox = Listbox(frame, exportselection=0,
+            background="white")
+        if options:
+            listbox.configure(options)
+        listbox.pack(expand=1, fill="both")
+        # Tie listbox and scrollbar together
+        vbar["command"] = listbox.yview
+        listbox["yscrollcommand"] = vbar.set
+        # Bind events to the list box
+        listbox.bind("<ButtonRelease-1>", self.click_event)
+        listbox.bind("<Double-ButtonRelease-1>", self.double_click_event)
+        listbox.bind("<ButtonPress-3>", self.popup_event)
+        listbox.bind("<Key-Up>", self.up_event)
+        listbox.bind("<Key-Down>", self.down_event)
+        # Mark as empty
+        self.clear()
+
+    def close(self):
+        self.frame.destroy()
+
+    def clear(self):
+        self.listbox.delete(0, "end")
+        self.empty = 1
+        self.listbox.insert("end", self.default)
+
+    def append(self, item):
+        if self.empty:
+            self.listbox.delete(0, "end")
+            self.empty = 0
+        self.listbox.insert("end", str(item))
+
+    def get(self, index):
+        return self.listbox.get(index)
+
+    def click_event(self, event):
+        self.listbox.activate("@%d,%d" % (event.x, event.y))
+        index = self.listbox.index("active")
+        self.select(index)
+        self.on_select(index)
+        return "break"
+
+    def double_click_event(self, event):
+        index = self.listbox.index("active")
+        self.select(index)
+        self.on_double(index)
+        return "break"
+
+    menu = None
+
+    def popup_event(self, event):
+        if not self.menu:
+            self.make_menu()
+        menu = self.menu
+        self.listbox.activate("@%d,%d" % (event.x, event.y))
+        index = self.listbox.index("active")
+        self.select(index)
+        menu.tk_popup(event.x_root, event.y_root)
+
+    def make_menu(self):
+        menu = Menu(self.listbox, tearoff=0)
+        self.menu = menu
+        self.fill_menu()
+
+    def up_event(self, event):
+        index = self.listbox.index("active")
+        if self.listbox.selection_includes(index):
+            index = index - 1
+        else:
+            index = self.listbox.size() - 1
+        if index < 0:
+            self.listbox.bell()
+        else:
+            self.select(index)
+            self.on_select(index)
+        return "break"
+
+    def down_event(self, event):
+        index = self.listbox.index("active")
+        if self.listbox.selection_includes(index):
+            index = index + 1
+        else:
+            index = 0
+        if index >= self.listbox.size():
+            self.listbox.bell()
+        else:
+            self.select(index)
+            self.on_select(index)
+        return "break"
+
+    def select(self, index):
+        self.listbox.focus_set()
+        self.listbox.activate(index)
+        self.listbox.selection_clear(0, "end")
+        self.listbox.selection_set(index)
+        self.listbox.see(index)
+
+    # Methods to override for specific actions
+
+    def fill_menu(self):
+        pass
+
+    def on_select(self, index):
+        pass
+
+    def on_double(self, index):
+        pass
+
+
+def test():
+    root = Tk()
+    root.protocol("WM_DELETE_WINDOW", root.destroy)
+    class MyScrolledList(ScrolledList):
+        def fill_menu(self): self.menu.add_command(label="pass")
+        def on_select(self, index): print "select", self.get(index)
+        def on_double(self, index): print "double", self.get(index)
+    s = MyScrolledList(root)
+    for i in range(30):
+        s.append("item %02d" % i)
+    return root
+
+def main():
+    root = test()
+    root.mainloop()
+
+if __name__ == '__main__':
+    main()

Added: vendor/Python/current/Lib/idlelib/SearchDialog.py
===================================================================
--- vendor/Python/current/Lib/idlelib/SearchDialog.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/SearchDialog.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,68 @@
+from Tkinter import *
+import SearchEngine
+from SearchDialogBase import SearchDialogBase
+
+
+def _setup(text):
+    root = text._root()
+    engine = SearchEngine.get(root)
+    if not hasattr(engine, "_searchdialog"):
+        engine._searchdialog = SearchDialog(root, engine)
+    return engine._searchdialog
+
+def find(text):
+    pat = text.get("sel.first", "sel.last")
+    return _setup(text).open(text,pat)
+
+def find_again(text):
+    return _setup(text).find_again(text)
+
+def find_selection(text):
+    return _setup(text).find_selection(text)
+
+class SearchDialog(SearchDialogBase):
+
+    def create_widgets(self):
+        f = SearchDialogBase.create_widgets(self)
+        self.make_button("Find", self.default_command, 1)
+
+    def default_command(self, event=None):
+        if not self.engine.getprog():
+            return
+        if self.find_again(self.text):
+            self.close()
+
+    def find_again(self, text):
+        if not self.engine.getpat():
+            self.open(text)
+            return False
+        if not self.engine.getprog():
+            return False
+        res = self.engine.search_text(text)
+        if res:
+            line, m = res
+            i, j = m.span()
+            first = "%d.%d" % (line, i)
+            last = "%d.%d" % (line, j)
+            try:
+                selfirst = text.index("sel.first")
+                sellast = text.index("sel.last")
+                if selfirst == first and sellast == last:
+                    text.bell()
+                    return False
+            except TclError:
+                pass
+            text.tag_remove("sel", "1.0", "end")
+            text.tag_add("sel", first, last)
+            text.mark_set("insert", self.engine.isback() and first or last)
+            text.see("insert")
+            return True
+        else:
+            text.bell()
+            return False
+
+    def find_selection(self, text):
+        pat = text.get("sel.first", "sel.last")
+        if pat:
+            self.engine.setcookedpat(pat)
+        return self.find_again(text)

Added: vendor/Python/current/Lib/idlelib/SearchDialogBase.py
===================================================================
--- vendor/Python/current/Lib/idlelib/SearchDialogBase.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/SearchDialogBase.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,140 @@
+from Tkinter import *
+
+class SearchDialogBase:
+
+    title = "Search Dialog"
+    icon = "Search"
+    needwrapbutton = 1
+
+    def __init__(self, root, engine):
+        self.root = root
+        self.engine = engine
+        self.top = None
+
+    def open(self, text, searchphrase=None):
+        self.text = text
+        if not self.top:
+            self.create_widgets()
+        else:
+            self.top.deiconify()
+            self.top.tkraise()
+        if searchphrase:
+            self.ent.delete(0,"end")
+            self.ent.insert("end",searchphrase)
+        self.ent.focus_set()
+        self.ent.selection_range(0, "end")
+        self.ent.icursor(0)
+        self.top.grab_set()
+
+    def close(self, event=None):
+        if self.top:
+            self.top.grab_release()
+            self.top.withdraw()
+
+    def create_widgets(self):
+        top = Toplevel(self.root)
+        top.bind("<Return>", self.default_command)
+        top.bind("<Escape>", self.close)
+        top.protocol("WM_DELETE_WINDOW", self.close)
+        top.wm_title(self.title)
+        top.wm_iconname(self.icon)
+        self.top = top
+
+        self.row = 0
+        self.top.grid_columnconfigure(0, pad=2, weight=0)
+        self.top.grid_columnconfigure(1, pad=2, minsize=100, weight=100)
+
+        self.create_entries()
+        self.create_option_buttons()
+        self.create_other_buttons()
+        return self.create_command_buttons()
+
+    def make_entry(self, label, var):
+        l = Label(self.top, text=label)
+        l.grid(row=self.row, column=0, sticky="nw")
+        e = Entry(self.top, textvariable=var, exportselection=0)
+        e.grid(row=self.row, column=1, sticky="nwe")
+        self.row = self.row + 1
+        return e
+
+    def make_frame(self,labeltext=None):
+        if labeltext:
+            l = Label(self.top, text=labeltext)
+            l.grid(row=self.row, column=0, sticky="nw")
+        f = Frame(self.top)
+        f.grid(row=self.row, column=1, columnspan=1, sticky="nwe")
+        self.row = self.row + 1
+        return f
+
+    def make_button(self, label, command, isdef=0):
+        b = Button(self.buttonframe,
+                   text=label, command=command,
+                   default=isdef and "active" or "normal")
+        cols,rows=self.buttonframe.grid_size()
+        b.grid(pady=1,row=rows,column=0,sticky="ew")
+        self.buttonframe.grid(rowspan=rows+1)
+        return b
+
+    def create_entries(self):
+        self.ent = self.make_entry("Find:", self.engine.patvar)
+
+    def create_option_buttons(self):
+        f = self.make_frame("Options")
+
+        btn = Checkbutton(f, anchor="w",
+                variable=self.engine.revar,
+                text="Regular expression")
+        btn.pack(side="left", fill="both")
+        if self.engine.isre():
+            btn.select()
+
+        btn = Checkbutton(f, anchor="w",
+                variable=self.engine.casevar,
+                text="Match case")
+        btn.pack(side="left", fill="both")
+        if self.engine.iscase():
+            btn.select()
+
+        btn = Checkbutton(f, anchor="w",
+                variable=self.engine.wordvar,
+                text="Whole word")
+        btn.pack(side="left", fill="both")
+        if self.engine.isword():
+            btn.select()
+
+        if self.needwrapbutton:
+            btn = Checkbutton(f, anchor="w",
+                    variable=self.engine.wrapvar,
+                    text="Wrap around")
+            btn.pack(side="left", fill="both")
+            if self.engine.iswrap():
+                btn.select()
+
+    def create_other_buttons(self):
+        f = self.make_frame("Direction")
+
+        #lbl = Label(f, text="Direction: ")
+        #lbl.pack(side="left")
+
+        btn = Radiobutton(f, anchor="w",
+                variable=self.engine.backvar, value=1,
+                text="Up")
+        btn.pack(side="left", fill="both")
+        if self.engine.isback():
+            btn.select()
+
+        btn = Radiobutton(f, anchor="w",
+                variable=self.engine.backvar, value=0,
+                text="Down")
+        btn.pack(side="left", fill="both")
+        if not self.engine.isback():
+            btn.select()
+
+    def create_command_buttons(self):
+        #
+        # place button frame on the right
+        f = self.buttonframe = Frame(self.top)
+        f.grid(row=0,column=2,padx=2,pady=2,ipadx=2,ipady=2)
+
+        b = self.make_button("close", self.close)
+        b.lower()

Added: vendor/Python/current/Lib/idlelib/SearchEngine.py
===================================================================
--- vendor/Python/current/Lib/idlelib/SearchEngine.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/SearchEngine.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,220 @@
+import re
+from Tkinter import *
+import tkMessageBox
+
+def get(root):
+    if not hasattr(root, "_searchengine"):
+        root._searchengine = SearchEngine(root)
+        # XXX This will never garbage-collect -- who cares
+    return root._searchengine
+
+class SearchEngine:
+
+    def __init__(self, root):
+        self.root = root
+        # State shared by search, replace, and grep;
+        # the search dialogs bind these to UI elements.
+        self.patvar = StringVar(root)           # search pattern
+        self.revar = BooleanVar(root)           # regular expression?
+        self.casevar = BooleanVar(root)         # match case?
+        self.wordvar = BooleanVar(root)         # match whole word?
+        self.wrapvar = BooleanVar(root)         # wrap around buffer?
+        self.wrapvar.set(1)                     # (on by default)
+        self.backvar = BooleanVar(root)         # search backwards?
+
+    # Access methods
+
+    def getpat(self):
+        return self.patvar.get()
+
+    def setpat(self, pat):
+        self.patvar.set(pat)
+
+    def isre(self):
+        return self.revar.get()
+
+    def iscase(self):
+        return self.casevar.get()
+
+    def isword(self):
+        return self.wordvar.get()
+
+    def iswrap(self):
+        return self.wrapvar.get()
+
+    def isback(self):
+        return self.backvar.get()
+
+    # Higher level access methods
+
+    def getcookedpat(self):
+        pat = self.getpat()
+        if not self.isre():
+            pat = re.escape(pat)
+        if self.isword():
+            pat = r"\b%s\b" % pat
+        return pat
+
+    def getprog(self):
+        pat = self.getpat()
+        if not pat:
+            self.report_error(pat, "Empty regular expression")
+            return None
+        pat = self.getcookedpat()
+        flags = 0
+        if not self.iscase():
+            flags = flags | re.IGNORECASE
+        try:
+            prog = re.compile(pat, flags)
+        except re.error, what:
+            try:
+                msg, col = what
+            except:
+                msg = str(what)
+                col = -1
+            self.report_error(pat, msg, col)
+            return None
+        return prog
+
+    def report_error(self, pat, msg, col=-1):
+        # Derived class could overrid this with something fancier
+        msg = "Error: " + str(msg)
+        if pat:
+            msg = msg + "\np\Pattern: " + str(pat)
+        if col >= 0:
+            msg = msg + "\nOffset: " + str(col)
+        tkMessageBox.showerror("Regular expression error",
+                               msg, master=self.root)
+
+    def setcookedpat(self, pat):
+        if self.isre():
+            pat = re.escape(pat)
+        self.setpat(pat)
+
+    def search_text(self, text, prog=None, ok=0):
+        """Search a text widget for the pattern.
+
+        If prog is given, it should be the precompiled pattern.
+        Return a tuple (lineno, matchobj); None if not found.
+
+        This obeys the wrap and direction (back) settings.
+
+        The search starts at the selection (if there is one) or
+        at the insert mark (otherwise).  If the search is forward,
+        it starts at the right of the selection; for a backward
+        search, it starts at the left end.  An empty match exactly
+        at either end of the selection (or at the insert mark if
+        there is no selection) is ignored  unless the ok flag is true
+        -- this is done to guarantee progress.
+
+        If the search is allowed to wrap around, it will return the
+        original selection if (and only if) it is the only match.
+
+        """
+        if not prog:
+            prog = self.getprog()
+            if not prog:
+                return None # Compilation failed -- stop
+        wrap = self.wrapvar.get()
+        first, last = get_selection(text)
+        if self.isback():
+            if ok:
+                start = last
+            else:
+                start = first
+            line, col = get_line_col(start)
+            res = self.search_backward(text, prog, line, col, wrap, ok)
+        else:
+            if ok:
+                start = first
+            else:
+                start = last
+            line, col = get_line_col(start)
+            res = self.search_forward(text, prog, line, col, wrap, ok)
+        return res
+
+    def search_forward(self, text, prog, line, col, wrap, ok=0):
+        wrapped = 0
+        startline = line
+        chars = text.get("%d.0" % line, "%d.0" % (line+1))
+        while chars:
+            m = prog.search(chars[:-1], col)
+            if m:
+                if ok or m.end() > col:
+                    return line, m
+            line = line + 1
+            if wrapped and line > startline:
+                break
+            col = 0
+            ok = 1
+            chars = text.get("%d.0" % line, "%d.0" % (line+1))
+            if not chars and wrap:
+                wrapped = 1
+                wrap = 0
+                line = 1
+                chars = text.get("1.0", "2.0")
+        return None
+
+    def search_backward(self, text, prog, line, col, wrap, ok=0):
+        wrapped = 0
+        startline = line
+        chars = text.get("%d.0" % line, "%d.0" % (line+1))
+        while 1:
+            m = search_reverse(prog, chars[:-1], col)
+            if m:
+                if ok or m.start() < col:
+                    return line, m
+            line = line - 1
+            if wrapped and line < startline:
+                break
+            ok = 1
+            if line <= 0:
+                if not wrap:
+                    break
+                wrapped = 1
+                wrap = 0
+                pos = text.index("end-1c")
+                line, col = map(int, pos.split("."))
+            chars = text.get("%d.0" % line, "%d.0" % (line+1))
+            col = len(chars) - 1
+        return None
+
+# Helper to search backwards in a string.
+# (Optimized for the case where the pattern isn't found.)
+
+def search_reverse(prog, chars, col):
+    m = prog.search(chars)
+    if not m:
+        return None
+    found = None
+    i, j = m.span()
+    while i < col and j <= col:
+        found = m
+        if i == j:
+            j = j+1
+        m = prog.search(chars, j)
+        if not m:
+            break
+        i, j = m.span()
+    return found
+
+# Helper to get selection end points, defaulting to insert mark.
+# Return a tuple of indices ("line.col" strings).
+
+def get_selection(text):
+    try:
+        first = text.index("sel.first")
+        last = text.index("sel.last")
+    except TclError:
+        first = last = None
+    if not first:
+        first = text.index("insert")
+    if not last:
+        last = first
+    return first, last
+
+# Helper to parse a text index into a (line, col) tuple.
+
+def get_line_col(index):
+    line, col = map(int, index.split(".")) # Fails on invalid index
+    return line, col

Added: vendor/Python/current/Lib/idlelib/StackViewer.py
===================================================================
--- vendor/Python/current/Lib/idlelib/StackViewer.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/StackViewer.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,137 @@
+import os
+import sys
+import linecache
+
+from TreeWidget import TreeNode, TreeItem, ScrolledCanvas
+from ObjectBrowser import ObjectTreeItem, make_objecttreeitem
+
+def StackBrowser(root, flist=None, tb=None, top=None):
+    if top is None:
+        from Tkinter import Toplevel
+        top = Toplevel(root)
+    sc = ScrolledCanvas(top, bg="white", highlightthickness=0)
+    sc.frame.pack(expand=1, fill="both")
+    item = StackTreeItem(flist, tb)
+    node = TreeNode(sc.canvas, None, item)
+    node.expand()
+
+class StackTreeItem(TreeItem):
+
+    def __init__(self, flist=None, tb=None):
+        self.flist = flist
+        self.stack = self.get_stack(tb)
+        self.text = self.get_exception()
+
+    def get_stack(self, tb):
+        if tb is None:
+            tb = sys.last_traceback
+        stack = []
+        if tb and tb.tb_frame is None:
+            tb = tb.tb_next
+        while tb is not None:
+            stack.append((tb.tb_frame, tb.tb_lineno))
+            tb = tb.tb_next
+        return stack
+
+    def get_exception(self):
+        type = sys.last_type
+        value = sys.last_value
+        if hasattr(type, "__name__"):
+            type = type.__name__
+        s = str(type)
+        if value is not None:
+            s = s + ": " + str(value)
+        return s
+
+    def GetText(self):
+        return self.text
+
+    def GetSubList(self):
+        sublist = []
+        for info in self.stack:
+            item = FrameTreeItem(info, self.flist)
+            sublist.append(item)
+        return sublist
+
+class FrameTreeItem(TreeItem):
+
+    def __init__(self, info, flist):
+        self.info = info
+        self.flist = flist
+
+    def GetText(self):
+        frame, lineno = self.info
+        try:
+            modname = frame.f_globals["__name__"]
+        except:
+            modname = "?"
+        code = frame.f_code
+        filename = code.co_filename
+        funcname = code.co_name
+        sourceline = linecache.getline(filename, lineno)
+        sourceline = sourceline.strip()
+        if funcname in ("?", "", None):
+            item = "%s, line %d: %s" % (modname, lineno, sourceline)
+        else:
+            item = "%s.%s(...), line %d: %s" % (modname, funcname,
+                                             lineno, sourceline)
+        return item
+
+    def GetSubList(self):
+        frame, lineno = self.info
+        sublist = []
+        if frame.f_globals is not frame.f_locals:
+            item = VariablesTreeItem("<locals>", frame.f_locals, self.flist)
+            sublist.append(item)
+        item = VariablesTreeItem("<globals>", frame.f_globals, self.flist)
+        sublist.append(item)
+        return sublist
+
+    def OnDoubleClick(self):
+        if self.flist:
+            frame, lineno = self.info
+            filename = frame.f_code.co_filename
+            if os.path.isfile(filename):
+                self.flist.gotofileline(filename, lineno)
+
+class VariablesTreeItem(ObjectTreeItem):
+
+    def GetText(self):
+        return self.labeltext
+
+    def GetLabelText(self):
+        return None
+
+    def IsExpandable(self):
+        return len(self.object) > 0
+
+    def keys(self):
+        return self.object.keys()
+
+    def GetSubList(self):
+        sublist = []
+        for key in self.keys():
+            try:
+                value = self.object[key]
+            except KeyError:
+                continue
+            def setfunction(value, key=key, object=self.object):
+                object[key] = value
+            item = make_objecttreeitem(key + " =", value, setfunction)
+            sublist.append(item)
+        return sublist
+
+
+def _test():
+    try:
+        import testcode
+        reload(testcode)
+    except:
+        sys.last_type, sys.last_value, sys.last_traceback = sys.exc_info()
+    from Tkinter import Tk
+    root = Tk()
+    StackBrowser(None, top=root)
+    root.mainloop()
+
+if __name__ == "__main__":
+    _test()

Added: vendor/Python/current/Lib/idlelib/TODO.txt
===================================================================
--- vendor/Python/current/Lib/idlelib/TODO.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/TODO.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,210 @@
+Original IDLE todo, much of it now outdated:
+============================================
+TO DO:
+
+- improve debugger:
+    - manage breakpoints globally, allow bp deletion, tbreak, cbreak etc.
+    - real object browser
+    - help on how to use it (a simple help button will do wonders)
+    - performance?  (updates of large sets of locals are slow)
+    - better integration of "debug module"
+    - debugger should be global resource (attached to flist, not to shell)
+    - fix the stupid bug where you need to step twice
+    - display class name in stack viewer entries for methods
+    - suppress tracing through IDLE internals (e.g. print) DONE
+    - add a button to suppress through a specific module or class or method
+    - more object inspection to stack viewer, e.g. to view all array items
+- insert the initial current directory into sys.path DONE
+- default directory attribute for each window instead of only for windows
+  that have an associated filename
+- command expansion from keywords, module contents, other buffers, etc.
+- "Recent documents" menu item DONE
+- Filter region command
+- Optional horizontal scroll bar
+- more Emacsisms:
+    - ^K should cut to buffer
+    - M-[, M-] to move by paragraphs
+    - incremental search?
+- search should indicate wrap-around in some way
+- restructure state sensitive code to avoid testing flags all the time
+- persistent user state (e.g. window and cursor positions, bindings)
+- make backups when saving
+- check file mtimes at various points
+- Pluggable interface with RCS/CVS/Perforce/Clearcase
+- better help?
+- don't open second class browser on same module (nor second path browser)
+- unify class and path browsers
+- Need to define a standard way whereby one can determine one is running
+  inside IDLE (needed for Tk mainloop, also handy for $PYTHONSTARTUP)
+- Add more utility methods for use by extensions (a la get_selection)
+- Way to run command in totally separate interpreter (fork+os.system?) DONE
+- Way to find definition of fully-qualified name:
+  In other words, select "UserDict.UserDict", hit some magic key and
+  it loads up UserDict.py and finds the first def or class for UserDict.
+- need a way to force colorization on/off
+- need a way to force auto-indent on/off
+
+Details:
+
+- ^O (on Unix -- open-line) should honor autoindent
+- after paste, show end of pasted text
+- on Windows, should turn short filename to long filename (not only in argv!)
+  (shouldn't this be done -- or undone -- by ntpath.normpath?)
+- new autoindent after colon even indents when the colon is in a comment!
+- sometimes forward slashes in pathname remain
+- sometimes star in window name remains in Windows menu
+- With unix bindings, ESC by itself is ignored
+- Sometimes for no apparent reason a selection from the cursor to the
+  end of the command buffer appears, which is hard to get rid of
+  because it stays when you are typing!
+- The Line/Col in the status bar can be wrong initially in PyShell DONE
+
+Structural problems:
+
+- too much knowledge in FileList about EditorWindow (for example)
+- should add some primitives for accessing the selection etc.
+  to repeat cumbersome code over and over
+
+======================================================================
+
+Jeff Bauer suggests:
+
+- Open Module doesn't appear to handle hierarchical packages.
+- Class browser should also allow hierarchical packages.
+- Open and Open Module could benefit from a history, DONE
+  either command line style, or Microsoft recent-file
+  style.
+- Add a Smalltalk-style inspector  (i.e. Tkinspect)
+
+The last suggestion is already a reality, but not yet
+integrated into IDLE.  I use a module called inspector.py,
+that used to be available from python.org(?)  It no longer
+appears to be in the contributed section, and the source
+has no author attribution.
+
+In any case, the code is useful for visually navigating
+an object's attributes, including its container hierarchy.
+
+    >>> from inspector import Tkinspect
+    >>> Tkinspect(None, myObject)
+
+Tkinspect could probably be extended and refined to
+integrate better into IDLE.
+
+======================================================================
+
+Comparison to PTUI
+------------------
+
++ PTUI's help is better (HTML!)
+
++ PTUI can attach a shell to any module
+
++ PTUI has some more I/O commands:
+  open multiple
+  append
+  examine (what's that?)
+
+======================================================================
+
+Notes after trying to run Grail
+-------------------------------
+
+- Grail does stuff to sys.path based on sys.argv[0]; you must set
+sys.argv[0] to something decent first (it is normally set to the path of
+the idle script).
+
+- Grail must be exec'ed in __main__ because that's imported by some
+other parts of Grail.
+
+- Grail uses a module called History and so does idle :-(
+
+======================================================================
+
+Robin Friedrich's items:
+
+Things I'd like to see:
+    - I'd like support for shift-click extending the selection. There's a
+      bug now that it doesn't work the first time you try it.
+    - Printing is needed. How hard can that be on Windows? FIRST CUT DONE
+    - The python-mode trick of autoindenting a line with <tab> is neat and
+      very handy.
+    - (someday) a spellchecker for docstrings and comments.
+    - a pagedown/up command key which moves to next class/def statement (top
+      level)
+    - split window capability
+    - DnD text relocation/copying
+
+Things I don't want to see.
+    - line numbers...  will probably slow things down way too much.
+    - Please use another icon for the tree browser leaf. The small snake
+      isn't cutting it.
+
+----------------------------------------------------------------------
+
+- Customizable views (multi-window or multi-pane).  (Markus Gritsch)
+
+- Being able to double click (maybe double right click) on a callable
+object in the editor which shows the source of the object, if
+possible.  (Gerrit Holl)
+
+- Hooks into the guts, like in Emacs.  (Mike Romberg)
+
+- Sharing the editor with a remote tutor.  (Martijn Faassen)
+
+- Multiple views on the same file.  (Tony J Ibbs)
+
+- Store breakpoints in a global (per-project) database (GvR); Dirk
+Heise adds: save some space-trimmed context and search around when
+reopening a file that might have been edited by someone else.
+
+- Capture menu events in extensions without changing the IDLE source.
+(Matthias Barmeier)
+
+- Use overlapping panels (a "notebook" in MFC terms I think) for info
+that doesn't need to be accessible simultaneously (e.g. HTML source
+and output).  Use multi-pane windows for info that does need to be
+shown together (e.g. class browser and source).  (Albert Brandl)
+
+- A project should invisibly track all symbols, for instant search,
+replace and cross-ref.  Projects should be allowed to span multiple
+directories, hosts, etc.  Project management files are placed in a
+directory you specify.  A global mapping between project names and
+project directories should exist [not so sure --GvR].  (Tim Peters)
+
+- Merge attr-tips and auto-expand.  (Mark Hammond, Tim Peters)
+
+- Python Shell should behave more like a "shell window" as users know
+it -- i.e. you can only edit the current command, and the cursor can't
+escape from the command area.  (Albert Brandl)
+
+- Set X11 class to "idle/Idle", set icon and title to something
+beginning with "idle" -- for window manangers.  (Randall Hopper)
+
+- Config files editable through a preferences dialog.  (me) DONE
+
+- Config files still editable outside the preferences dialog.
+(Randall Hopper) DONE
+
+- When you're editing a command in PyShell, and there are only blank
+lines below the cursor, hitting Return should ignore or delete those
+blank lines rather than deciding you're not on the last line.  (me)
+
+- Run command (F5 c.s.) should be more like Pythonwin's Run -- a
+dialog with options to give command line arguments, run the debugger,
+etc.  (me)
+
+- Shouldn't be able to delete part of the prompt (or any text before
+it) in the PyShell.  (Martijn Faassen)   DONE
+
+- Emacs style auto-fill (also smart about comments and strings).
+(Jeremy Hylton)
+
+- Output of Run Script should go to a separate output window, not to
+the shell window.  Output of separate runs should all go to the same
+window but clearly delimited.  (David Scherer) REJECT FIRST, LATTER DONE
+
+- GUI form designer to kick VB's butt.  (Robert Geiger) THAT'S NOT IDLE
+
+- Printing!  Possibly via generation of PDF files which the user must
+then send to the printer separately.  (Dinu Gherman)  FIRST CUT

Added: vendor/Python/current/Lib/idlelib/ToolTip.py
===================================================================
--- vendor/Python/current/Lib/idlelib/ToolTip.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/ToolTip.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,89 @@
+# general purpose 'tooltip' routines - currently unused in idlefork
+# (although the 'calltips' extension is partly based on this code)
+# may be useful for some purposes in (or almost in ;) the current project scope
+# Ideas gleaned from PySol
+
+from Tkinter import *
+
+class ToolTipBase:
+
+    def __init__(self, button):
+        self.button = button
+        self.tipwindow = None
+        self.id = None
+        self.x = self.y = 0
+        self._id1 = self.button.bind("<Enter>", self.enter)
+        self._id2 = self.button.bind("<Leave>", self.leave)
+        self._id3 = self.button.bind("<ButtonPress>", self.leave)
+
+    def enter(self, event=None):
+        self.schedule()
+
+    def leave(self, event=None):
+        self.unschedule()
+        self.hidetip()
+
+    def schedule(self):
+        self.unschedule()
+        self.id = self.button.after(1500, self.showtip)
+
+    def unschedule(self):
+        id = self.id
+        self.id = None
+        if id:
+            self.button.after_cancel(id)
+
+    def showtip(self):
+        if self.tipwindow:
+            return
+        # The tip window must be completely outside the button;
+        # otherwise when the mouse enters the tip window we get
+        # a leave event and it disappears, and then we get an enter
+        # event and it reappears, and so on forever :-(
+        x = self.button.winfo_rootx() + 20
+        y = self.button.winfo_rooty() + self.button.winfo_height() + 1
+        self.tipwindow = tw = Toplevel(self.button)
+        tw.wm_overrideredirect(1)
+        tw.wm_geometry("+%d+%d" % (x, y))
+        self.showcontents()
+
+    def showcontents(self, text="Your text here"):
+        # Override this in derived class
+        label = Label(self.tipwindow, text=text, justify=LEFT,
+                      background="#ffffe0", relief=SOLID, borderwidth=1)
+        label.pack()
+
+    def hidetip(self):
+        tw = self.tipwindow
+        self.tipwindow = None
+        if tw:
+            tw.destroy()
+
+class ToolTip(ToolTipBase):
+    def __init__(self, button, text):
+        ToolTipBase.__init__(self, button)
+        self.text = text
+    def showcontents(self):
+        ToolTipBase.showcontents(self, self.text)
+
+class ListboxToolTip(ToolTipBase):
+    def __init__(self, button, items):
+        ToolTipBase.__init__(self, button)
+        self.items = items
+    def showcontents(self):
+        listbox = Listbox(self.tipwindow, background="#ffffe0")
+        listbox.pack()
+        for item in self.items:
+            listbox.insert(END, item)
+
+def main():
+    # Test code
+    root = Tk()
+    b = Button(root, text="Hello", command=root.destroy)
+    b.pack()
+    root.update()
+    tip = ListboxToolTip(b, ["Hello", "world"])
+    root.mainloop()
+
+if __name__ == '__main__':
+    main()

Added: vendor/Python/current/Lib/idlelib/TreeWidget.py
===================================================================
--- vendor/Python/current/Lib/idlelib/TreeWidget.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/TreeWidget.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,478 @@
+# XXX TO DO:
+# - popup menu
+# - support partial or total redisplay
+# - key bindings (instead of quick-n-dirty bindings on Canvas):
+#   - up/down arrow keys to move focus around
+#   - ditto for page up/down, home/end
+#   - left/right arrows to expand/collapse & move out/in
+# - more doc strings
+# - add icons for "file", "module", "class", "method"; better "python" icon
+# - callback for selection???
+# - multiple-item selection
+# - tooltips
+# - redo geometry without magic numbers
+# - keep track of object ids to allow more careful cleaning
+# - optimize tree redraw after expand of subnode
+
+import os
+import sys
+from Tkinter import *
+import imp
+
+import ZoomHeight
+from configHandler import idleConf
+
+ICONDIR = "Icons"
+
+# Look for Icons subdirectory in the same directory as this module
+try:
+    _icondir = os.path.join(os.path.dirname(__file__), ICONDIR)
+except NameError:
+    _icondir = ICONDIR
+if os.path.isdir(_icondir):
+    ICONDIR = _icondir
+elif not os.path.isdir(ICONDIR):
+    raise RuntimeError, "can't find icon directory (%r)" % (ICONDIR,)
+
+def listicons(icondir=ICONDIR):
+    """Utility to display the available icons."""
+    root = Tk()
+    import glob
+    list = glob.glob(os.path.join(icondir, "*.gif"))
+    list.sort()
+    images = []
+    row = column = 0
+    for file in list:
+        name = os.path.splitext(os.path.basename(file))[0]
+        image = PhotoImage(file=file, master=root)
+        images.append(image)
+        label = Label(root, image=image, bd=1, relief="raised")
+        label.grid(row=row, column=column)
+        label = Label(root, text=name)
+        label.grid(row=row+1, column=column)
+        column = column + 1
+        if column >= 10:
+            row = row+2
+            column = 0
+    root.images = images
+
+
+class TreeNode:
+
+    def __init__(self, canvas, parent, item):
+        self.canvas = canvas
+        self.parent = parent
+        self.item = item
+        self.state = 'collapsed'
+        self.selected = False
+        self.children = []
+        self.x = self.y = None
+        self.iconimages = {} # cache of PhotoImage instances for icons
+
+    def destroy(self):
+        for c in self.children[:]:
+            self.children.remove(c)
+            c.destroy()
+        self.parent = None
+
+    def geticonimage(self, name):
+        try:
+            return self.iconimages[name]
+        except KeyError:
+            pass
+        file, ext = os.path.splitext(name)
+        ext = ext or ".gif"
+        fullname = os.path.join(ICONDIR, file + ext)
+        image = PhotoImage(master=self.canvas, file=fullname)
+        self.iconimages[name] = image
+        return image
+
+    def select(self, event=None):
+        if self.selected:
+            return
+        self.deselectall()
+        self.selected = True
+        self.canvas.delete(self.image_id)
+        self.drawicon()
+        self.drawtext()
+
+    def deselect(self, event=None):
+        if not self.selected:
+            return
+        self.selected = False
+        self.canvas.delete(self.image_id)
+        self.drawicon()
+        self.drawtext()
+
+    def deselectall(self):
+        if self.parent:
+            self.parent.deselectall()
+        else:
+            self.deselecttree()
+
+    def deselecttree(self):
+        if self.selected:
+            self.deselect()
+        for child in self.children:
+            child.deselecttree()
+
+    def flip(self, event=None):
+        if self.state == 'expanded':
+            self.collapse()
+        else:
+            self.expand()
+        self.item.OnDoubleClick()
+        return "break"
+
+    def expand(self, event=None):
+        if not self.item._IsExpandable():
+            return
+        if self.state != 'expanded':
+            self.state = 'expanded'
+            self.update()
+            self.view()
+
+    def collapse(self, event=None):
+        if self.state != 'collapsed':
+            self.state = 'collapsed'
+            self.update()
+
+    def view(self):
+        top = self.y - 2
+        bottom = self.lastvisiblechild().y + 17
+        height = bottom - top
+        visible_top = self.canvas.canvasy(0)
+        visible_height = self.canvas.winfo_height()
+        visible_bottom = self.canvas.canvasy(visible_height)
+        if visible_top <= top and bottom <= visible_bottom:
+            return
+        x0, y0, x1, y1 = self.canvas._getints(self.canvas['scrollregion'])
+        if top >= visible_top and height <= visible_height:
+            fraction = top + height - visible_height
+        else:
+            fraction = top
+        fraction = float(fraction) / y1
+        self.canvas.yview_moveto(fraction)
+
+    def lastvisiblechild(self):
+        if self.children and self.state == 'expanded':
+            return self.children[-1].lastvisiblechild()
+        else:
+            return self
+
+    def update(self):
+        if self.parent:
+            self.parent.update()
+        else:
+            oldcursor = self.canvas['cursor']
+            self.canvas['cursor'] = "watch"
+            self.canvas.update()
+            self.canvas.delete(ALL)     # XXX could be more subtle
+            self.draw(7, 2)
+            x0, y0, x1, y1 = self.canvas.bbox(ALL)
+            self.canvas.configure(scrollregion=(0, 0, x1, y1))
+            self.canvas['cursor'] = oldcursor
+
+    def draw(self, x, y):
+        # XXX This hard-codes too many geometry constants!
+        self.x, self.y = x, y
+        self.drawicon()
+        self.drawtext()
+        if self.state != 'expanded':
+            return y+17
+        # draw children
+        if not self.children:
+            sublist = self.item._GetSubList()
+            if not sublist:
+                # _IsExpandable() was mistaken; that's allowed
+                return y+17
+            for item in sublist:
+                child = self.__class__(self.canvas, self, item)
+                self.children.append(child)
+        cx = x+20
+        cy = y+17
+        cylast = 0
+        for child in self.children:
+            cylast = cy
+            self.canvas.create_line(x+9, cy+7, cx, cy+7, fill="gray50")
+            cy = child.draw(cx, cy)
+            if child.item._IsExpandable():
+                if child.state == 'expanded':
+                    iconname = "minusnode"
+                    callback = child.collapse
+                else:
+                    iconname = "plusnode"
+                    callback = child.expand
+                image = self.geticonimage(iconname)
+                id = self.canvas.create_image(x+9, cylast+7, image=image)
+                # XXX This leaks bindings until canvas is deleted:
+                self.canvas.tag_bind(id, "<1>", callback)
+                self.canvas.tag_bind(id, "<Double-1>", lambda x: None)
+        id = self.canvas.create_line(x+9, y+10, x+9, cylast+7,
+            ##stipple="gray50",     # XXX Seems broken in Tk 8.0.x
+            fill="gray50")
+        self.canvas.tag_lower(id) # XXX .lower(id) before Python 1.5.2
+        return cy
+
+    def drawicon(self):
+        if self.selected:
+            imagename = (self.item.GetSelectedIconName() or
+                         self.item.GetIconName() or
+                         "openfolder")
+        else:
+            imagename = self.item.GetIconName() or "folder"
+        image = self.geticonimage(imagename)
+        id = self.canvas.create_image(self.x, self.y, anchor="nw", image=image)
+        self.image_id = id
+        self.canvas.tag_bind(id, "<1>", self.select)
+        self.canvas.tag_bind(id, "<Double-1>", self.flip)
+
+    def drawtext(self):
+        textx = self.x+20-1
+        texty = self.y-1
+        labeltext = self.item.GetLabelText()
+        if labeltext:
+            id = self.canvas.create_text(textx, texty, anchor="nw",
+                                         text=labeltext)
+            self.canvas.tag_bind(id, "<1>", self.select)
+            self.canvas.tag_bind(id, "<Double-1>", self.flip)
+            x0, y0, x1, y1 = self.canvas.bbox(id)
+            textx = max(x1, 200) + 10
+        text = self.item.GetText() or "<no text>"
+        try:
+            self.entry
+        except AttributeError:
+            pass
+        else:
+            self.edit_finish()
+        try:
+            label = self.label
+        except AttributeError:
+            # padding carefully selected (on Windows) to match Entry widget:
+            self.label = Label(self.canvas, text=text, bd=0, padx=2, pady=2)
+        theme = idleConf.GetOption('main','Theme','name')
+        if self.selected:
+            self.label.configure(idleConf.GetHighlight(theme, 'hilite'))
+        else:
+            self.label.configure(idleConf.GetHighlight(theme, 'normal'))
+        id = self.canvas.create_window(textx, texty,
+                                       anchor="nw", window=self.label)
+        self.label.bind("<1>", self.select_or_edit)
+        self.label.bind("<Double-1>", self.flip)
+        self.text_id = id
+
+    def select_or_edit(self, event=None):
+        if self.selected and self.item.IsEditable():
+            self.edit(event)
+        else:
+            self.select(event)
+
+    def edit(self, event=None):
+        self.entry = Entry(self.label, bd=0, highlightthickness=1, width=0)
+        self.entry.insert(0, self.label['text'])
+        self.entry.selection_range(0, END)
+        self.entry.pack(ipadx=5)
+        self.entry.focus_set()
+        self.entry.bind("<Return>", self.edit_finish)
+        self.entry.bind("<Escape>", self.edit_cancel)
+
+    def edit_finish(self, event=None):
+        try:
+            entry = self.entry
+            del self.entry
+        except AttributeError:
+            return
+        text = entry.get()
+        entry.destroy()
+        if text and text != self.item.GetText():
+            self.item.SetText(text)
+        text = self.item.GetText()
+        self.label['text'] = text
+        self.drawtext()
+        self.canvas.focus_set()
+
+    def edit_cancel(self, event=None):
+        try:
+            entry = self.entry
+            del self.entry
+        except AttributeError:
+            return
+        entry.destroy()
+        self.drawtext()
+        self.canvas.focus_set()
+
+
+class TreeItem:
+
+    """Abstract class representing tree items.
+
+    Methods should typically be overridden, otherwise a default action
+    is used.
+
+    """
+
+    def __init__(self):
+        """Constructor.  Do whatever you need to do."""
+
+    def GetText(self):
+        """Return text string to display."""
+
+    def GetLabelText(self):
+        """Return label text string to display in front of text (if any)."""
+
+    expandable = None
+
+    def _IsExpandable(self):
+        """Do not override!  Called by TreeNode."""
+        if self.expandable is None:
+            self.expandable = self.IsExpandable()
+        return self.expandable
+
+    def IsExpandable(self):
+        """Return whether there are subitems."""
+        return 1
+
+    def _GetSubList(self):
+        """Do not override!  Called by TreeNode."""
+        if not self.IsExpandable():
+            return []
+        sublist = self.GetSubList()
+        if not sublist:
+            self.expandable = 0
+        return sublist
+
+    def IsEditable(self):
+        """Return whether the item's text may be edited."""
+
+    def SetText(self, text):
+        """Change the item's text (if it is editable)."""
+
+    def GetIconName(self):
+        """Return name of icon to be displayed normally."""
+
+    def GetSelectedIconName(self):
+        """Return name of icon to be displayed when selected."""
+
+    def GetSubList(self):
+        """Return list of items forming sublist."""
+
+    def OnDoubleClick(self):
+        """Called on a double-click on the item."""
+
+
+# Example application
+
+class FileTreeItem(TreeItem):
+
+    """Example TreeItem subclass -- browse the file system."""
+
+    def __init__(self, path):
+        self.path = path
+
+    def GetText(self):
+        return os.path.basename(self.path) or self.path
+
+    def IsEditable(self):
+        return os.path.basename(self.path) != ""
+
+    def SetText(self, text):
+        newpath = os.path.dirname(self.path)
+        newpath = os.path.join(newpath, text)
+        if os.path.dirname(newpath) != os.path.dirname(self.path):
+            return
+        try:
+            os.rename(self.path, newpath)
+            self.path = newpath
+        except os.error:
+            pass
+
+    def GetIconName(self):
+        if not self.IsExpandable():
+            return "python" # XXX wish there was a "file" icon
+
+    def IsExpandable(self):
+        return os.path.isdir(self.path)
+
+    def GetSubList(self):
+        try:
+            names = os.listdir(self.path)
+        except os.error:
+            return []
+        names.sort(lambda a, b: cmp(os.path.normcase(a), os.path.normcase(b)))
+        sublist = []
+        for name in names:
+            item = FileTreeItem(os.path.join(self.path, name))
+            sublist.append(item)
+        return sublist
+
+
+# A canvas widget with scroll bars and some useful bindings
+
+class ScrolledCanvas:
+    def __init__(self, master, **opts):
+        if not opts.has_key('yscrollincrement'):
+            opts['yscrollincrement'] = 17
+        self.master = master
+        self.frame = Frame(master)
+        self.frame.rowconfigure(0, weight=1)
+        self.frame.columnconfigure(0, weight=1)
+        self.canvas = Canvas(self.frame, **opts)
+        self.canvas.grid(row=0, column=0, sticky="nsew")
+        self.vbar = Scrollbar(self.frame, name="vbar")
+        self.vbar.grid(row=0, column=1, sticky="nse")
+        self.hbar = Scrollbar(self.frame, name="hbar", orient="horizontal")
+        self.hbar.grid(row=1, column=0, sticky="ews")
+        self.canvas['yscrollcommand'] = self.vbar.set
+        self.vbar['command'] = self.canvas.yview
+        self.canvas['xscrollcommand'] = self.hbar.set
+        self.hbar['command'] = self.canvas.xview
+        self.canvas.bind("<Key-Prior>", self.page_up)
+        self.canvas.bind("<Key-Next>", self.page_down)
+        self.canvas.bind("<Key-Up>", self.unit_up)
+        self.canvas.bind("<Key-Down>", self.unit_down)
+        #if isinstance(master, Toplevel) or isinstance(master, Tk):
+        self.canvas.bind("<Alt-Key-2>", self.zoom_height)
+        self.canvas.focus_set()
+    def page_up(self, event):
+        self.canvas.yview_scroll(-1, "page")
+        return "break"
+    def page_down(self, event):
+        self.canvas.yview_scroll(1, "page")
+        return "break"
+    def unit_up(self, event):
+        self.canvas.yview_scroll(-1, "unit")
+        return "break"
+    def unit_down(self, event):
+        self.canvas.yview_scroll(1, "unit")
+        return "break"
+    def zoom_height(self, event):
+        ZoomHeight.zoom_height(self.master)
+        return "break"
+
+
+# Testing functions
+
+def test():
+    import PyShell
+    root = Toplevel(PyShell.root)
+    root.configure(bd=0, bg="yellow")
+    root.focus_set()
+    sc = ScrolledCanvas(root, bg="white", highlightthickness=0, takefocus=1)
+    sc.frame.pack(expand=1, fill="both")
+    item = FileTreeItem("C:/windows/desktop")
+    node = TreeNode(sc.canvas, None, item)
+    node.expand()
+
+def test2():
+    # test w/o scrolling canvas
+    root = Tk()
+    root.configure(bd=0)
+    canvas = Canvas(root, bg="white", highlightthickness=0)
+    canvas.pack(expand=1, fill="both")
+    item = FileTreeItem(os.curdir)
+    node = TreeNode(canvas, None, item)
+    node.update()
+    canvas.focus_set()
+
+if __name__ == '__main__':
+    test()

Added: vendor/Python/current/Lib/idlelib/UndoDelegator.py
===================================================================
--- vendor/Python/current/Lib/idlelib/UndoDelegator.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/UndoDelegator.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,352 @@
+import sys
+import string
+from Tkinter import *
+from Delegator import Delegator
+
+#$ event <<redo>>
+#$ win <Control-y>
+#$ unix <Alt-z>
+
+#$ event <<undo>>
+#$ win <Control-z>
+#$ unix <Control-z>
+
+#$ event <<dump-undo-state>>
+#$ win <Control-backslash>
+#$ unix <Control-backslash>
+
+
+class UndoDelegator(Delegator):
+
+    max_undo = 1000
+
+    def __init__(self):
+        Delegator.__init__(self)
+        self.reset_undo()
+
+    def setdelegate(self, delegate):
+        if self.delegate is not None:
+            self.unbind("<<undo>>")
+            self.unbind("<<redo>>")
+            self.unbind("<<dump-undo-state>>")
+        Delegator.setdelegate(self, delegate)
+        if delegate is not None:
+            self.bind("<<undo>>", self.undo_event)
+            self.bind("<<redo>>", self.redo_event)
+            self.bind("<<dump-undo-state>>", self.dump_event)
+
+    def dump_event(self, event):
+        from pprint import pprint
+        pprint(self.undolist[:self.pointer])
+        print "pointer:", self.pointer,
+        print "saved:", self.saved,
+        print "can_merge:", self.can_merge,
+        print "get_saved():", self.get_saved()
+        pprint(self.undolist[self.pointer:])
+        return "break"
+
+    def reset_undo(self):
+        self.was_saved = -1
+        self.pointer = 0
+        self.undolist = []
+        self.undoblock = 0  # or a CommandSequence instance
+        self.set_saved(1)
+
+    def set_saved(self, flag):
+        if flag:
+            self.saved = self.pointer
+        else:
+            self.saved = -1
+        self.can_merge = False
+        self.check_saved()
+
+    def get_saved(self):
+        return self.saved == self.pointer
+
+    saved_change_hook = None
+
+    def set_saved_change_hook(self, hook):
+        self.saved_change_hook = hook
+
+    was_saved = -1
+
+    def check_saved(self):
+        is_saved = self.get_saved()
+        if is_saved != self.was_saved:
+            self.was_saved = is_saved
+            if self.saved_change_hook:
+                self.saved_change_hook()
+
+    def insert(self, index, chars, tags=None):
+        self.addcmd(InsertCommand(index, chars, tags))
+
+    def delete(self, index1, index2=None):
+        self.addcmd(DeleteCommand(index1, index2))
+
+    # Clients should call undo_block_start() and undo_block_stop()
+    # around a sequence of editing cmds to be treated as a unit by
+    # undo & redo.  Nested matching calls are OK, and the inner calls
+    # then act like nops.  OK too if no editing cmds, or only one
+    # editing cmd, is issued in between:  if no cmds, the whole
+    # sequence has no effect; and if only one cmd, that cmd is entered
+    # directly into the undo list, as if undo_block_xxx hadn't been
+    # called.  The intent of all that is to make this scheme easy
+    # to use:  all the client has to worry about is making sure each
+    # _start() call is matched by a _stop() call.
+
+    def undo_block_start(self):
+        if self.undoblock == 0:
+            self.undoblock = CommandSequence()
+        self.undoblock.bump_depth()
+
+    def undo_block_stop(self):
+        if self.undoblock.bump_depth(-1) == 0:
+            cmd = self.undoblock
+            self.undoblock = 0
+            if len(cmd) > 0:
+                if len(cmd) == 1:
+                    # no need to wrap a single cmd
+                    cmd = cmd.getcmd(0)
+                # this blk of cmds, or single cmd, has already
+                # been done, so don't execute it again
+                self.addcmd(cmd, 0)
+
+    def addcmd(self, cmd, execute=True):
+        if execute:
+            cmd.do(self.delegate)
+        if self.undoblock != 0:
+            self.undoblock.append(cmd)
+            return
+        if self.can_merge and self.pointer > 0:
+            lastcmd = self.undolist[self.pointer-1]
+            if lastcmd.merge(cmd):
+                return
+        self.undolist[self.pointer:] = [cmd]
+        if self.saved > self.pointer:
+            self.saved = -1
+        self.pointer = self.pointer + 1
+        if len(self.undolist) > self.max_undo:
+            ##print "truncating undo list"
+            del self.undolist[0]
+            self.pointer = self.pointer - 1
+            if self.saved >= 0:
+                self.saved = self.saved - 1
+        self.can_merge = True
+        self.check_saved()
+
+    def undo_event(self, event):
+        if self.pointer == 0:
+            self.bell()
+            return "break"
+        cmd = self.undolist[self.pointer - 1]
+        cmd.undo(self.delegate)
+        self.pointer = self.pointer - 1
+        self.can_merge = False
+        self.check_saved()
+        return "break"
+
+    def redo_event(self, event):
+        if self.pointer >= len(self.undolist):
+            self.bell()
+            return "break"
+        cmd = self.undolist[self.pointer]
+        cmd.redo(self.delegate)
+        self.pointer = self.pointer + 1
+        self.can_merge = False
+        self.check_saved()
+        return "break"
+
+
+class Command:
+
+    # Base class for Undoable commands
+
+    tags = None
+
+    def __init__(self, index1, index2, chars, tags=None):
+        self.marks_before = {}
+        self.marks_after = {}
+        self.index1 = index1
+        self.index2 = index2
+        self.chars = chars
+        if tags:
+            self.tags = tags
+
+    def __repr__(self):
+        s = self.__class__.__name__
+        t = (self.index1, self.index2, self.chars, self.tags)
+        if self.tags is None:
+            t = t[:-1]
+        return s + repr(t)
+
+    def do(self, text):
+        pass
+
+    def redo(self, text):
+        pass
+
+    def undo(self, text):
+        pass
+
+    def merge(self, cmd):
+        return 0
+
+    def save_marks(self, text):
+        marks = {}
+        for name in text.mark_names():
+            if name != "insert" and name != "current":
+                marks[name] = text.index(name)
+        return marks
+
+    def set_marks(self, text, marks):
+        for name, index in marks.items():
+            text.mark_set(name, index)
+
+
+class InsertCommand(Command):
+
+    # Undoable insert command
+
+    def __init__(self, index1, chars, tags=None):
+        Command.__init__(self, index1, None, chars, tags)
+
+    def do(self, text):
+        self.marks_before = self.save_marks(text)
+        self.index1 = text.index(self.index1)
+        if text.compare(self.index1, ">", "end-1c"):
+            # Insert before the final newline
+            self.index1 = text.index("end-1c")
+        text.insert(self.index1, self.chars, self.tags)
+        self.index2 = text.index("%s+%dc" % (self.index1, len(self.chars)))
+        self.marks_after = self.save_marks(text)
+        ##sys.__stderr__.write("do: %s\n" % self)
+
+    def redo(self, text):
+        text.mark_set('insert', self.index1)
+        text.insert(self.index1, self.chars, self.tags)
+        self.set_marks(text, self.marks_after)
+        text.see('insert')
+        ##sys.__stderr__.write("redo: %s\n" % self)
+
+    def undo(self, text):
+        text.mark_set('insert', self.index1)
+        text.delete(self.index1, self.index2)
+        self.set_marks(text, self.marks_before)
+        text.see('insert')
+        ##sys.__stderr__.write("undo: %s\n" % self)
+
+    def merge(self, cmd):
+        if self.__class__ is not cmd.__class__:
+            return False
+        if self.index2 != cmd.index1:
+            return False
+        if self.tags != cmd.tags:
+            return False
+        if len(cmd.chars) != 1:
+            return False
+        if self.chars and \
+           self.classify(self.chars[-1]) != self.classify(cmd.chars):
+            return False
+        self.index2 = cmd.index2
+        self.chars = self.chars + cmd.chars
+        return True
+
+    alphanumeric = string.ascii_letters + string.digits + "_"
+
+    def classify(self, c):
+        if c in self.alphanumeric:
+            return "alphanumeric"
+        if c == "\n":
+            return "newline"
+        return "punctuation"
+
+
+class DeleteCommand(Command):
+
+    # Undoable delete command
+
+    def __init__(self, index1, index2=None):
+        Command.__init__(self, index1, index2, None, None)
+
+    def do(self, text):
+        self.marks_before = self.save_marks(text)
+        self.index1 = text.index(self.index1)
+        if self.index2:
+            self.index2 = text.index(self.index2)
+        else:
+            self.index2 = text.index(self.index1 + " +1c")
+        if text.compare(self.index2, ">", "end-1c"):
+            # Don't delete the final newline
+            self.index2 = text.index("end-1c")
+        self.chars = text.get(self.index1, self.index2)
+        text.delete(self.index1, self.index2)
+        self.marks_after = self.save_marks(text)
+        ##sys.__stderr__.write("do: %s\n" % self)
+
+    def redo(self, text):
+        text.mark_set('insert', self.index1)
+        text.delete(self.index1, self.index2)
+        self.set_marks(text, self.marks_after)
+        text.see('insert')
+        ##sys.__stderr__.write("redo: %s\n" % self)
+
+    def undo(self, text):
+        text.mark_set('insert', self.index1)
+        text.insert(self.index1, self.chars)
+        self.set_marks(text, self.marks_before)
+        text.see('insert')
+        ##sys.__stderr__.write("undo: %s\n" % self)
+
+class CommandSequence(Command):
+
+    # Wrapper for a sequence of undoable cmds to be undone/redone
+    # as a unit
+
+    def __init__(self):
+        self.cmds = []
+        self.depth = 0
+
+    def __repr__(self):
+        s = self.__class__.__name__
+        strs = []
+        for cmd in self.cmds:
+            strs.append("    %r" % (cmd,))
+        return s + "(\n" + ",\n".join(strs) + "\n)"
+
+    def __len__(self):
+        return len(self.cmds)
+
+    def append(self, cmd):
+        self.cmds.append(cmd)
+
+    def getcmd(self, i):
+        return self.cmds[i]
+
+    def redo(self, text):
+        for cmd in self.cmds:
+            cmd.redo(text)
+
+    def undo(self, text):
+        cmds = self.cmds[:]
+        cmds.reverse()
+        for cmd in cmds:
+            cmd.undo(text)
+
+    def bump_depth(self, incr=1):
+        self.depth = self.depth + incr
+        return self.depth
+
+def main():
+    from Percolator import Percolator
+    root = Tk()
+    root.wm_protocol("WM_DELETE_WINDOW", root.quit)
+    text = Text()
+    text.pack()
+    text.focus_set()
+    p = Percolator(text)
+    d = UndoDelegator()
+    p.insertfilter(d)
+    root.mainloop()
+
+if __name__ == "__main__":
+    main()

Added: vendor/Python/current/Lib/idlelib/WidgetRedirector.py
===================================================================
--- vendor/Python/current/Lib/idlelib/WidgetRedirector.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/WidgetRedirector.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,92 @@
+from Tkinter import *
+
+
+class WidgetRedirector:
+
+    """Support for redirecting arbitrary widget subcommands."""
+
+    def __init__(self, widget):
+        self.dict = {}
+        self.widget = widget
+        self.tk = tk = widget.tk
+        w = widget._w
+        self.orig = w + "_orig"
+        tk.call("rename", w, self.orig)
+        tk.createcommand(w, self.dispatch)
+
+    def __repr__(self):
+        return "WidgetRedirector(%s<%s>)" % (self.widget.__class__.__name__,
+                                             self.widget._w)
+
+    def close(self):
+        for name in self.dict.keys():
+            self.unregister(name)
+        widget = self.widget; del self.widget
+        orig = self.orig; del self.orig
+        tk = widget.tk
+        w = widget._w
+        tk.deletecommand(w)
+        tk.call("rename", orig, w)
+
+    def register(self, name, function):
+        if self.dict.has_key(name):
+            previous = dict[name]
+        else:
+            previous = OriginalCommand(self, name)
+        self.dict[name] = function
+        setattr(self.widget, name, function)
+        return previous
+
+    def unregister(self, name):
+        if self.dict.has_key(name):
+            function = self.dict[name]
+            del self.dict[name]
+            if hasattr(self.widget, name):
+                delattr(self.widget, name)
+            return function
+        else:
+            return None
+
+    def dispatch(self, cmd, *args):
+        m = self.dict.get(cmd)
+        try:
+            if m:
+                return m(*args)
+            else:
+                return self.tk.call((self.orig, cmd) + args)
+        except TclError:
+            return ""
+
+
+class OriginalCommand:
+
+    def __init__(self, redir, name):
+        self.redir = redir
+        self.name = name
+        self.tk = redir.tk
+        self.orig = redir.orig
+        self.tk_call = self.tk.call
+        self.orig_and_name = (self.orig, self.name)
+
+    def __repr__(self):
+        return "OriginalCommand(%r, %r)" % (self.redir, self.name)
+
+    def __call__(self, *args):
+        return self.tk_call(self.orig_and_name + args)
+
+
+def main():
+    root = Tk()
+    text = Text()
+    text.pack()
+    text.focus_set()
+    redir = WidgetRedirector(text)
+    global orig_insert
+    def my_insert(*args):
+        print "insert", args
+        orig_insert(*args)
+    orig_insert = redir.register("insert", my_insert)
+    root.mainloop()
+
+if __name__ == "__main__":
+    main()

Added: vendor/Python/current/Lib/idlelib/WindowList.py
===================================================================
--- vendor/Python/current/Lib/idlelib/WindowList.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/WindowList.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,90 @@
+from Tkinter import *
+
+class WindowList:
+
+    def __init__(self):
+        self.dict = {}
+        self.callbacks = []
+
+    def add(self, window):
+        window.after_idle(self.call_callbacks)
+        self.dict[str(window)] = window
+
+    def delete(self, window):
+        try:
+            del self.dict[str(window)]
+        except KeyError:
+            # Sometimes, destroy() is called twice
+            pass
+        self.call_callbacks()
+
+    def add_windows_to_menu(self,  menu):
+        list = []
+        for key in self.dict.keys():
+            window = self.dict[key]
+            try:
+                title = window.get_title()
+            except TclError:
+                continue
+            list.append((title, window))
+        list.sort()
+        for title, window in list:
+            menu.add_command(label=title, command=window.wakeup)
+
+    def register_callback(self, callback):
+        self.callbacks.append(callback)
+
+    def unregister_callback(self, callback):
+        try:
+            self.callbacks.remove(callback)
+        except ValueError:
+            pass
+
+    def call_callbacks(self):
+        for callback in self.callbacks:
+            try:
+                callback()
+            except:
+                print "warning: callback failed in WindowList", \
+                      sys.exc_type, ":", sys.exc_value
+
+registry = WindowList()
+
+add_windows_to_menu = registry.add_windows_to_menu
+register_callback = registry.register_callback
+unregister_callback = registry.unregister_callback
+
+
+class ListedToplevel(Toplevel):
+
+    def __init__(self, master, **kw):
+        Toplevel.__init__(self, master, kw)
+        registry.add(self)
+        self.focused_widget = self
+
+    def destroy(self):
+        registry.delete(self)
+        Toplevel.destroy(self)
+        # If this is Idle's last window then quit the mainloop
+        # (Needed for clean exit on Windows 98)
+        if not registry.dict:
+            self.quit()
+
+    def update_windowlist_registry(self, window):
+        registry.call_callbacks()
+
+    def get_title(self):
+        # Subclass can override
+        return self.wm_title()
+
+    def wakeup(self):
+        try:
+            if self.wm_state() == "iconic":
+                self.wm_withdraw()
+                self.wm_deiconify()
+            self.tkraise()
+            self.focused_widget.focus_set()
+        except TclError:
+            # This can happen when the window menu was torn off.
+            # Simply ignore it.
+            pass

Added: vendor/Python/current/Lib/idlelib/ZoomHeight.py
===================================================================
--- vendor/Python/current/Lib/idlelib/ZoomHeight.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/ZoomHeight.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,50 @@
+# Sample extension: zoom a window to maximum height
+
+import re
+import sys
+import macosxSupport
+
+class ZoomHeight:
+
+    menudefs = [
+        ('windows', [
+            ('_Zoom Height', '<<zoom-height>>'),
+         ])
+    ]
+
+    def __init__(self, editwin):
+        self.editwin = editwin
+
+    def zoom_height_event(self, event):
+        top = self.editwin.top
+        zoom_height(top)
+
+def zoom_height(top):
+    geom = top.wm_geometry()
+    m = re.match(r"(\d+)x(\d+)\+(-?\d+)\+(-?\d+)", geom)
+    if not m:
+        top.bell()
+        return
+    width, height, x, y = map(int, m.groups())
+    newheight = top.winfo_screenheight()
+    if sys.platform == 'win32':
+        newy = 0
+        newheight = newheight - 72
+
+    elif macosxSupport.runningAsOSXApp():
+        # The '88' below is a magic number that avoids placing the bottom
+        # of the window below the panel on my machine. I don't know how
+        # to calculate the correct value for this with tkinter.
+        newy = 22
+        newheight = newheight - newy - 88
+
+    else:
+        #newy = 24
+        newy = 0
+        #newheight = newheight - 96
+        newheight = newheight - 88
+    if height >= newheight:
+        newgeom = ""
+    else:
+        newgeom = "%dx%d+%d+%d" % (width, newheight, x, newy)
+    top.wm_geometry(newgeom)

Added: vendor/Python/current/Lib/idlelib/__init__.py
===================================================================
--- vendor/Python/current/Lib/idlelib/__init__.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/__init__.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1 @@
+# Dummy file to make this a package.

Added: vendor/Python/current/Lib/idlelib/aboutDialog.py
===================================================================
--- vendor/Python/current/Lib/idlelib/aboutDialog.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/aboutDialog.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,163 @@
+"""About Dialog for IDLE
+
+"""
+
+from Tkinter import *
+import string, os
+import textView
+import idlever
+
+class AboutDialog(Toplevel):
+    """Modal about dialog for idle
+
+    """
+    def __init__(self,parent,title):
+        Toplevel.__init__(self, parent)
+        self.configure(borderwidth=5)
+        self.geometry("+%d+%d" % (parent.winfo_rootx()+30,
+                                  parent.winfo_rooty()+30))
+        self.bg = "#707070"
+        self.fg = "#ffffff"
+        self.CreateWidgets()
+        self.resizable(height=FALSE, width=FALSE)
+        self.title(title)
+        self.transient(parent)
+        self.grab_set()
+        self.protocol("WM_DELETE_WINDOW", self.Ok)
+        self.parent = parent
+        self.buttonOk.focus_set()
+        self.bind('<Return>',self.Ok) #dismiss dialog
+        self.bind('<Escape>',self.Ok) #dismiss dialog
+        self.wait_window()
+
+    def CreateWidgets(self):
+        frameMain = Frame(self, borderwidth=2, relief=SUNKEN)
+        frameButtons = Frame(self)
+        frameButtons.pack(side=BOTTOM, fill=X)
+        frameMain.pack(side=TOP, expand=TRUE, fill=BOTH)
+        self.buttonOk = Button(frameButtons, text='Close',
+                               command=self.Ok)
+        self.buttonOk.pack(padx=5, pady=5)
+        #self.picture = Image('photo', data=self.pictureData)
+        frameBg = Frame(frameMain, bg=self.bg)
+        frameBg.pack(expand=TRUE, fill=BOTH)
+        labelTitle = Label(frameBg, text='IDLE', fg=self.fg, bg=self.bg,
+                           font=('courier', 24, 'bold'))
+        labelTitle.grid(row=0, column=0, sticky=W, padx=10, pady=10)
+        #labelPicture = Label(frameBg, text='[picture]')
+        #image=self.picture, bg=self.bg)
+        #labelPicture.grid(row=1, column=1, sticky=W, rowspan=2,
+        #                  padx=0, pady=3)
+        byline = "Python's Integrated DeveLopment Environment" + 5*'\n'
+        labelDesc = Label(frameBg, text=byline, justify=LEFT,
+                          fg=self.fg, bg=self.bg)
+        labelDesc.grid(row=2, column=0, sticky=W, columnspan=3, padx=10, pady=5)
+        labelEmail = Label(frameBg, text='email:  idle-dev at python.org',
+                           justify=LEFT, fg=self.fg, bg=self.bg)
+        labelEmail.grid(row=6, column=0, columnspan=2,
+                        sticky=W, padx=10, pady=0)
+        labelWWW = Label(frameBg, text='www:  http://www.python.org/idle/',
+                         justify=LEFT, fg=self.fg, bg=self.bg)
+        labelWWW.grid(row=7, column=0, columnspan=2, sticky=W, padx=10, pady=0)
+        Frame(frameBg, borderwidth=1, relief=SUNKEN,
+              height=2, bg=self.bg).grid(row=8, column=0, sticky=EW,
+                                         columnspan=3, padx=5, pady=5)
+        labelPythonVer = Label(frameBg, text='Python version:  ' + \
+                               sys.version.split()[0], fg=self.fg, bg=self.bg)
+        labelPythonVer.grid(row=9, column=0, sticky=W, padx=10, pady=0)
+        # handle weird tk version num in windoze python >= 1.6 (?!?)
+        tkVer = repr(TkVersion).split('.')
+        tkVer[len(tkVer)-1] = str('%.3g' % (float('.'+tkVer[len(tkVer)-1])))[2:]
+        if tkVer[len(tkVer)-1] == '':
+            tkVer[len(tkVer)-1] = '0'
+        tkVer = string.join(tkVer,'.')
+        labelTkVer = Label(frameBg, text='Tk version:  '+
+                           tkVer, fg=self.fg, bg=self.bg)
+        labelTkVer.grid(row=9, column=1, sticky=W, padx=2, pady=0)
+        py_button_f = Frame(frameBg, bg=self.bg)
+        py_button_f.grid(row=10, column=0, columnspan=2, sticky=NSEW)
+        buttonLicense = Button(py_button_f, text='License', width=8,
+                               highlightbackground=self.bg,
+                               command=self.ShowLicense)
+        buttonLicense.pack(side=LEFT, padx=10, pady=10)
+        buttonCopyright = Button(py_button_f, text='Copyright', width=8,
+                                 highlightbackground=self.bg,
+                                 command=self.ShowCopyright)
+        buttonCopyright.pack(side=LEFT, padx=10, pady=10)
+        buttonCredits = Button(py_button_f, text='Credits', width=8,
+                               highlightbackground=self.bg,
+                               command=self.ShowPythonCredits)
+        buttonCredits.pack(side=LEFT, padx=10, pady=10)
+        Frame(frameBg, borderwidth=1, relief=SUNKEN,
+              height=2, bg=self.bg).grid(row=11, column=0, sticky=EW,
+                                         columnspan=3, padx=5, pady=5)
+        idle_v = Label(frameBg, text='IDLE version:   ' + idlever.IDLE_VERSION,
+                       fg=self.fg, bg=self.bg)
+        idle_v.grid(row=12, column=0, sticky=W, padx=10, pady=0)
+        idle_button_f = Frame(frameBg, bg=self.bg)
+        idle_button_f.grid(row=13, column=0, columnspan=3, sticky=NSEW)
+        idle_about_b = Button(idle_button_f, text='README', width=8,
+                                highlightbackground=self.bg,
+                                command=self.ShowIDLEAbout)
+        idle_about_b.pack(side=LEFT, padx=10, pady=10)
+        idle_news_b = Button(idle_button_f, text='NEWS', width=8,
+                                highlightbackground=self.bg,
+                                command=self.ShowIDLENEWS)
+        idle_news_b.pack(side=LEFT, padx=10, pady=10)
+        idle_credits_b = Button(idle_button_f, text='Credits', width=8,
+                                highlightbackground=self.bg,
+                                command=self.ShowIDLECredits)
+        idle_credits_b.pack(side=LEFT, padx=10, pady=10)
+
+    def ShowLicense(self):
+        self.display_printer_text(license, 'About - License')
+
+    def ShowCopyright(self):
+        self.display_printer_text(copyright, 'About - Copyright')
+
+    def ShowPythonCredits(self):
+        self.display_printer_text(credits, 'About - Python Credits')
+
+    def ShowIDLECredits(self):
+        self.ViewFile('About - Credits','CREDITS.txt', 'iso-8859-1')
+
+    def ShowIDLEAbout(self):
+        self.ViewFile('About - Readme', 'README.txt')
+
+    def ShowIDLENEWS(self):
+        self.ViewFile('About - NEWS', 'NEWS.txt')
+
+    def display_printer_text(self, printer, title):
+        printer._Printer__setup()
+        data = '\n'.join(printer._Printer__lines)
+        textView.TextViewer(self, title, None, data)
+
+    def ViewFile(self, viewTitle, viewFile, encoding=None):
+        fn = os.path.join(os.path.abspath(os.path.dirname(__file__)), viewFile)
+        if encoding:
+            import codecs
+            try:
+                textFile = codecs.open(fn, 'r')
+            except IOError:
+                import tkMessageBox
+                tkMessageBox.showerror(title='File Load Error',
+                                       message='Unable to load file %r .' % (fn,),
+                                       parent=self)
+                return
+            else:
+                data = textFile.read()
+        else:
+            data = None
+        textView.TextViewer(self, viewTitle, fn, data=data)
+
+    def Ok(self, event=None):
+        self.destroy()
+
+if __name__ == '__main__':
+    # test the dialog
+    root = Tk()
+    def run():
+        import aboutDialog
+        aboutDialog.AboutDialog(root, 'About')
+    Button(root, text='Dialog', command=run).pack()
+    root.mainloop()

Added: vendor/Python/current/Lib/idlelib/config-extensions.def
===================================================================
--- vendor/Python/current/Lib/idlelib/config-extensions.def	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/config-extensions.def	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,88 @@
+# config-extensions.def
+#
+# IDLE reads several config files to determine user preferences.  This
+# file is the default configuration file for IDLE extensions settings.
+#
+# Each extension must have at least one section, named after the extension
+# module. This section must contain an 'enable' item (=1 to enable the
+# extension, =0 to disable it), it may contain 'enable_editor' or 'enable_shell'
+# items, to apply it only to editor/shell windows, and may also contain any
+# other general configuration items for the extension.
+#
+# Each extension must define at least one section named ExtensionName_bindings
+# or ExtensionName_cfgBindings. If present, ExtensionName_bindings defines
+# virtual event bindings for the extension that are not user re-configurable.
+# If present, ExtensionName_cfgBindings defines virtual event bindings for the
+# extension that may be sensibly re-configured.
+#
+# If there are no keybindings for a menus' virtual events, include lines like
+# <<toggle-code-context>>=   (See [CodeContext], below.)
+#
+# Currently it is necessary to manually modify this file to change extension
+# key bindings and default values. To customize, create
+# ~/.idlerc/config-extensions.cfg and append the appropriate customized
+# section(s).  Those sections will override the defaults in this file.
+#
+# Note: If a keybinding is already in use when the extension is
+# loaded, the extension's virtual event's keybinding will be set to ''.
+#
+# See config-keys.def for notes on specifying keys and extend.txt for
+# information on creating IDLE extensions.
+
+[FormatParagraph]
+enable=1
+[FormatParagraph_cfgBindings]
+format-paragraph=<Alt-Key-q>
+
+[AutoExpand]
+enable=1
+[AutoExpand_cfgBindings]
+expand-word=<Alt-Key-slash>
+
+[ZoomHeight]
+enable=1
+[ZoomHeight_cfgBindings]
+zoom-height=<Alt-Key-2>
+
+[ScriptBinding]
+enable=1
+[ScriptBinding_cfgBindings]
+run-module=<Key-F5>
+check-module=<Alt-Key-x>
+
+[CallTips]
+enable=1
+[CallTips_cfgBindings]
+force-open-calltip=<Control-Key-backslash>
+[CallTips_bindings]
+try-open-calltip=<KeyRelease-parenleft>
+refresh-calltip=<KeyRelease-parenright> <KeyRelease-0>
+
+[ParenMatch]
+enable=1
+style= expression
+flash-delay= 500
+bell= 1
+[ParenMatch_cfgBindings]
+flash-paren=<Control-Key-0>
+[ParenMatch_bindings]
+paren-closed=<KeyRelease-parenright> <KeyRelease-bracketright> <KeyRelease-braceright>
+
+[AutoComplete]
+enable=1
+popupwait=2000
+[AutoComplete_cfgBindings]
+force-open-completions=<Control-Key-space>
+[AutoComplete_bindings]
+autocomplete=<Key-Tab>
+try-open-completions=<KeyRelease-period> <KeyRelease-slash> <KeyRelease-backslash>
+
+[CodeContext]
+enable=1
+enable_shell=0
+numlines=3
+visible=0
+bgcolor=LightGray
+fgcolor=Black
+[CodeContext_bindings]
+toggle-code-context=

Added: vendor/Python/current/Lib/idlelib/config-highlight.def
===================================================================
--- vendor/Python/current/Lib/idlelib/config-highlight.def	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/config-highlight.def	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,64 @@
+# IDLE reads several config files to determine user preferences.  This
+# file is the default config file for idle highlight theme settings.
+
+[IDLE Classic]
+normal-foreground= #000000
+normal-background= #ffffff
+keyword-foreground= #ff7700
+keyword-background= #ffffff
+builtin-foreground= #900090
+builtin-background= #ffffff
+comment-foreground= #dd0000
+comment-background= #ffffff
+string-foreground= #00aa00
+string-background= #ffffff
+definition-foreground= #0000ff
+definition-background= #ffffff
+hilite-foreground= #000000
+hilite-background= gray
+break-foreground= black
+break-background= #ffff55
+hit-foreground= #ffffff
+hit-background= #000000
+error-foreground= #000000
+error-background= #ff7777
+#cursor (only foreground can be set, restart IDLE)
+cursor-foreground= black
+#shell window
+stdout-foreground= blue
+stdout-background= #ffffff
+stderr-foreground= red
+stderr-background= #ffffff
+console-foreground= #770000
+console-background= #ffffff
+
+[IDLE New]
+normal-foreground= #000000
+normal-background= #ffffff
+keyword-foreground= #ff7700
+keyword-background= #ffffff
+builtin-foreground= #900090
+builtin-background= #ffffff
+comment-foreground= #dd0000
+comment-background= #ffffff
+string-foreground= #00aa00
+string-background= #ffffff
+definition-foreground= #0000ff
+definition-background= #ffffff
+hilite-foreground= #000000
+hilite-background= gray
+break-foreground= black
+break-background= #ffff55
+hit-foreground= #ffffff
+hit-background= #000000
+error-foreground= #000000
+error-background= #ff7777
+#cursor (only foreground can be set, restart IDLE)
+cursor-foreground= black
+#shell window
+stdout-foreground= blue
+stdout-background= #ffffff
+stderr-foreground= red
+stderr-background= #ffffff
+console-foreground= #770000
+console-background= #ffffff

Added: vendor/Python/current/Lib/idlelib/config-keys.def
===================================================================
--- vendor/Python/current/Lib/idlelib/config-keys.def	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/config-keys.def	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,214 @@
+# IDLE reads several config files to determine user preferences.  This
+# file is the default config file for idle key binding settings.
+# Where multiple keys are specified for an action: if they are separated
+# by a space (eg. action=<key1> <key2>) then the keys are alternatives, if
+# there is no space (eg. action=<key1><key2>) then the keys comprise a
+# single 'emacs style' multi-keystoke binding. The tk event specifier 'Key'
+# is used in all cases, for consistency in auto key conflict checking in the
+# configuration gui.
+
+[IDLE Classic Windows]
+copy=<Control-Key-c> <Control-Key-C>
+cut=<Control-Key-x> <Control-Key-X>
+paste=<Control-Key-v> <Control-Key-V>
+beginning-of-line= <Key-Home>
+center-insert=<Control-Key-l> <Control-Key-L>
+close-all-windows=<Control-Key-q>
+close-window=<Alt-Key-F4> <Meta-Key-F4>
+do-nothing=<Control-Key-F12>
+end-of-file=<Control-Key-d> <Control-Key-D>
+python-docs=<Key-F1>
+python-context-help=<Shift-Key-F1>
+history-next=<Alt-Key-n> <Meta-Key-n>
+history-previous=<Alt-Key-p> <Meta-Key-p>
+interrupt-execution=<Control-Key-c> <Control-Key-C>
+view-restart=<Key-F6>
+restart-shell=<Control-Key-F6>
+open-class-browser=<Alt-Key-c> <Meta-Key-c> <Alt-Key-C>
+open-module=<Alt-Key-m> <Meta-Key-m> <Alt-Key-M>
+open-new-window=<Control-Key-n> <Control-Key-N>
+open-window-from-file=<Control-Key-o> <Control-Key-O>
+plain-newline-and-indent=<Control-Key-j> <Control-Key-J>
+print-window=<Control-Key-p> <Control-Key-P>
+redo=<Control-Shift-Key-Z>
+remove-selection=<Key-Escape>
+save-copy-of-window-as-file=<Alt-Shift-Key-S>
+save-window-as-file=<Control-Shift-Key-S>
+save-window=<Control-Key-s>
+select-all=<Control-Key-a>
+toggle-auto-coloring=<Control-Key-slash>
+undo=<Control-Key-z> <Control-Key-Z>
+find=<Control-Key-f> <Control-Key-F>
+find-again=<Control-Key-g> <Key-F3>
+find-in-files=<Alt-Key-F3> <Meta-Key-F3>
+find-selection=<Control-Key-F3>
+replace=<Control-Key-h> <Control-Key-H>
+goto-line=<Alt-Key-g> <Meta-Key-g>
+smart-backspace=<Key-BackSpace>
+newline-and-indent=<Key-Return> <Key-KP_Enter>
+smart-indent=<Key-Tab>
+indent-region=<Control-Key-bracketright>
+dedent-region=<Control-Key-bracketleft>
+comment-region=<Alt-Key-3> <Meta-Key-3>
+uncomment-region=<Alt-Key-4> <Meta-Key-4>
+tabify-region=<Alt-Key-5> <Meta-Key-5>
+untabify-region=<Alt-Key-6> <Meta-Key-6>
+toggle-tabs=<Alt-Key-t> <Meta-Key-t> <Alt-Key-T>
+change-indentwidth=<Alt-Key-u> <Meta-Key-u> <Alt-Key-U>
+del-word-left=<Control-Key-BackSpace>
+del-word-right=<Control-Key-Delete>
+
+[IDLE Classic Unix]
+copy=<Alt-Key-w> <Meta-Key-w>
+cut=<Control-Key-w>
+paste=<Control-Key-y>
+beginning-of-line=<Control-Key-a> <Key-Home>
+center-insert=<Control-Key-l>
+close-all-windows=<Control-Key-x><Control-Key-c>
+close-window=<Control-Key-x><Control-Key-0>
+do-nothing=<Control-Key-x>
+end-of-file=<Control-Key-d>
+history-next=<Alt-Key-n> <Meta-Key-n>
+history-previous=<Alt-Key-p> <Meta-Key-p>
+interrupt-execution=<Control-Key-c>
+view-restart=<Key-F6>
+restart-shell=<Control-Key-F6>
+open-class-browser=<Control-Key-x><Control-Key-b>
+open-module=<Control-Key-x><Control-Key-m>
+open-new-window=<Control-Key-x><Control-Key-n>
+open-window-from-file=<Control-Key-x><Control-Key-f>
+plain-newline-and-indent=<Control-Key-j>
+print-window=<Control-x><Control-Key-p>
+python-docs=<Control-Key-h>
+python-context-help=<Control-Shift-Key-H>
+redo=<Alt-Key-z> <Meta-Key-z>
+remove-selection=<Key-Escape>
+save-copy-of-window-as-file=<Control-Key-x><Control-Key-y>
+save-window-as-file=<Control-Key-x><Control-Key-w>
+save-window=<Control-Key-x><Control-Key-s>
+select-all=<Alt-Key-a> <Meta-Key-a>
+toggle-auto-coloring=<Control-Key-slash>
+undo=<Control-Key-z>
+find=<Control-Key-u><Control-Key-u><Control-Key-s>
+find-again=<Control-Key-u><Control-Key-s>
+find-in-files=<Alt-Key-s> <Meta-Key-s>
+find-selection=<Control-Key-s>
+replace=<Control-Key-r>
+goto-line=<Alt-Key-g> <Meta-Key-g>
+smart-backspace=<Key-BackSpace>
+newline-and-indent=<Key-Return> <Key-KP_Enter>
+smart-indent=<Key-Tab>
+indent-region=<Control-Key-bracketright>
+dedent-region=<Control-Key-bracketleft>
+comment-region=<Alt-Key-3>
+uncomment-region=<Alt-Key-4>
+tabify-region=<Alt-Key-5>
+untabify-region=<Alt-Key-6>
+toggle-tabs=<Alt-Key-t>
+change-indentwidth=<Alt-Key-u>
+del-word-left=<Alt-Key-BackSpace>
+del-word-right=<Alt-Key-d>
+
+[IDLE Classic Mac]
+copy=<Command-Key-c>
+cut=<Command-Key-x>
+paste=<Command-Key-v>
+beginning-of-line= <Key-Home>
+center-insert=<Control-Key-l>
+close-all-windows=<Command-Key-q>
+close-window=<Command-Key-w>
+do-nothing=<Control-Key-F12>
+end-of-file=<Control-Key-d>
+python-docs=<Key-F1>
+python-context-help=<Shift-Key-F1>
+history-next=<Control-Key-n>
+history-previous=<Control-Key-p>
+interrupt-execution=<Control-Key-c>
+view-restart=<Key-F6>
+restart-shell=<Control-Key-F6>
+open-class-browser=<Command-Key-b>
+open-module=<Command-Key-m>
+open-new-window=<Command-Key-n>
+open-window-from-file=<Command-Key-o>
+plain-newline-and-indent=<Control-Key-j>
+print-window=<Command-Key-p>
+redo=<Shift-Command-Key-Z>
+remove-selection=<Key-Escape>
+save-window-as-file=<Shift-Command-Key-S>
+save-window=<Command-Key-s>
+save-copy-of-window-as-file=<Option-Command-Key-s>
+select-all=<Command-Key-a>
+toggle-auto-coloring=<Control-Key-slash>
+undo=<Command-Key-z>
+find=<Command-Key-f>
+find-again=<Command-Key-g> <Key-F3>
+find-in-files=<Command-Key-F3>
+find-selection=<Shift-Command-Key-F3>
+replace=<Command-Key-r>
+goto-line=<Command-Key-j>
+smart-backspace=<Key-BackSpace>
+newline-and-indent=<Key-Return> <Key-KP_Enter>
+smart-indent=<Key-Tab>
+indent-region=<Command-Key-bracketright>
+dedent-region=<Command-Key-bracketleft>
+comment-region=<Control-Key-3>
+uncomment-region=<Control-Key-4>
+tabify-region=<Control-Key-5>
+untabify-region=<Control-Key-6>
+toggle-tabs=<Control-Key-t>
+change-indentwidth=<Control-Key-u>
+del-word-left=<Control-Key-BackSpace>
+del-word-right=<Control-Key-Delete>
+
+[IDLE Classic OSX]
+toggle-tabs = <Control-Key-t>
+interrupt-execution = <Control-Key-c>
+untabify-region = <Control-Key-6>
+remove-selection = <Key-Escape>
+print-window = <Command-Key-p>
+replace = <Command-Key-r>
+goto-line = <Command-Key-j>
+plain-newline-and-indent = <Control-Key-j>
+history-previous = <Control-Key-p>
+beginning-of-line = <Control-Key-Left>
+end-of-line = <Control-Key-Right>
+comment-region = <Control-Key-3>
+redo = <Shift-Command-Key-Z>
+close-window = <Command-Key-w>
+restart-shell = <Control-Key-F6>
+save-window-as-file = <Command-Key-S>
+close-all-windows = <Command-Key-q>
+view-restart = <Key-F6>
+tabify-region = <Control-Key-5>
+find-again = <Command-Key-g> <Key-F3>
+find = <Command-Key-f>
+toggle-auto-coloring = <Control-Key-slash>
+select-all = <Command-Key-a>
+smart-backspace = <Key-BackSpace>
+change-indentwidth = <Control-Key-u>
+do-nothing = <Control-Key-F12>
+smart-indent = <Key-Tab>
+center-insert = <Control-Key-l>
+history-next = <Control-Key-n>
+del-word-right = <Option-Key-Delete>
+undo = <Command-Key-z>
+save-window = <Command-Key-s>
+uncomment-region = <Control-Key-4>
+cut = <Command-Key-x>
+find-in-files = <Command-Key-F3>
+dedent-region = <Command-Key-bracketleft>
+copy = <Command-Key-c>
+paste = <Command-Key-v>
+indent-region = <Command-Key-bracketright>
+del-word-left = <Option-Key-BackSpace> <Option-Command-Key-BackSpace>
+newline-and-indent = <Key-Return> <Key-KP_Enter>
+end-of-file = <Control-Key-d>
+open-class-browser = <Command-Key-b>
+open-new-window = <Command-Key-n>
+open-module = <Command-Key-m>
+find-selection = <Shift-Command-Key-F3>
+python-context-help = <Shift-Key-F1>
+save-copy-of-window-as-file = <Shift-Command-Key-s>
+open-window-from-file = <Command-Key-o>
+python-docs = <Key-F1>
+

Added: vendor/Python/current/Lib/idlelib/config-main.def
===================================================================
--- vendor/Python/current/Lib/idlelib/config-main.def	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/config-main.def	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,79 @@
+# IDLE reads several config files to determine user preferences.  This
+# file is the default config file for general idle settings.
+#
+# When IDLE starts, it will look in
+# the following two sets of files, in order:
+#
+#     default configuration
+#     ---------------------
+#     config-main.def         the default general config file
+#     config-extensions.def   the default extension config file
+#     config-highlight.def    the default highlighting config file
+#     config-keys.def         the default keybinding config file
+#
+#     user configuration
+#     -------------------
+#     ~/.idlerc/config-main.cfg            the user general config file
+#     ~/.idlerc/config-extensions.cfg      the user extension config file
+#     ~/.idlerc/config-highlight.cfg       the user highlighting config file
+#     ~/.idlerc/config-keys.cfg            the user keybinding config file
+#
+# On Windows2000 and Windows XP the .idlerc directory is at
+#     Documents and Settings\<username>\.idlerc
+#
+# On Windows98 it is at c:\.idlerc
+#
+# Any options the user saves through the config dialog will be saved to
+# the relevant user config file. Reverting any general setting to the
+# default causes that entry to be wiped from the user file and re-read
+# from the default file. User highlighting themes or keybinding sets are
+# retained unless specifically deleted within the config dialog. Choosing
+# one of the default themes or keysets just applies the relevant settings
+# from the default file.
+#
+# Additional help sources are listed in the [HelpFiles] section and must be
+# viewable by a web browser (or the Windows Help viewer in the case of .chm
+# files). These sources will be listed on the Help menu.  The pattern is
+# <sequence_number = menu item;/path/to/help/source>
+# You can't use a semi-colon in a menu item or path.  The path will be platform
+# specific because of path separators, drive specs etc.
+#
+# It is best to use the Configuration GUI to set up additional help sources!
+# Example:
+#1 = My Extra Help Source;/usr/share/doc/foo/index.html
+#2 = Another Help Source;/path/to/another.pdf
+
+[General]
+editor-on-startup= 0
+autosave= 0
+print-command-posix=lpr %s
+print-command-win=start /min notepad /p %s
+delete-exitfunc= 1
+
+[EditorWindow]
+width= 80
+height= 40
+font= courier
+font-size= 10
+font-bold= 0
+encoding= none
+
+[FormatParagraph]
+paragraph=70
+
+[Indent]
+use-spaces= 1
+num-spaces= 4
+
+[Theme]
+default= 1
+name= IDLE Classic
+
+[Keys]
+default= 1
+name= IDLE Classic Windows
+
+[History]
+cyclic=1
+
+[HelpFiles]

Added: vendor/Python/current/Lib/idlelib/configDialog.py
===================================================================
--- vendor/Python/current/Lib/idlelib/configDialog.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/configDialog.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1147 @@
+"""IDLE Configuration Dialog: support user customization of IDLE by GUI
+
+Customize font faces, sizes, and colorization attributes.  Set indentation
+defaults.  Customize keybindings.  Colorization and keybindings can be
+saved as user defined sets.  Select startup options including shell/editor
+and default window size.  Define additional help sources.
+
+Note that tab width in IDLE is currently fixed at eight due to Tk issues.
+Refer to comments in EditorWindow autoindent code for details.
+
+"""
+from Tkinter import *
+import tkMessageBox, tkColorChooser, tkFont
+import string, copy
+
+from configHandler import idleConf
+from dynOptionMenuWidget import DynOptionMenu
+from tabpage import TabPageSet
+from keybindingDialog import GetKeysDialog
+from configSectionNameDialog import GetCfgSectionNameDialog
+from configHelpSourceEdit import GetHelpSourceDialog
+
+class ConfigDialog(Toplevel):
+
+    def __init__(self,parent,title):
+        Toplevel.__init__(self, parent)
+        self.configure(borderwidth=5)
+        self.geometry("+%d+%d" % (parent.winfo_rootx()+20,
+                parent.winfo_rooty()+30))
+        #Theme Elements. Each theme element key is its display name.
+        #The first value of the tuple is the sample area tag name.
+        #The second value is the display name list sort index.
+        self.themeElements={'Normal Text':('normal','00'),
+            'Python Keywords':('keyword','01'),
+            'Python Definitions':('definition','02'),
+            'Python Builtins':('builtin', '03'),
+            'Python Comments':('comment','04'),
+            'Python Strings':('string','05'),
+            'Selected Text':('hilite','06'),
+            'Found Text':('hit','07'),
+            'Cursor':('cursor','08'),
+            'Error Text':('error','09'),
+            'Shell Normal Text':('console','10'),
+            'Shell Stdout Text':('stdout','11'),
+            'Shell Stderr Text':('stderr','12'),
+            }
+        self.ResetChangedItems() #load initial values in changed items dict
+        self.CreateWidgets()
+        self.resizable(height=FALSE,width=FALSE)
+        self.transient(parent)
+        self.grab_set()
+        self.protocol("WM_DELETE_WINDOW", self.Cancel)
+        self.parent = parent
+        self.tabPages.focus_set()
+        #key bindings for this dialog
+        #self.bind('<Escape>',self.Cancel) #dismiss dialog, no save
+        #self.bind('<Alt-a>',self.Apply) #apply changes, save
+        #self.bind('<F1>',self.Help) #context help
+        self.LoadConfigs()
+        self.AttachVarCallbacks() #avoid callbacks during LoadConfigs
+        self.wait_window()
+
+    def CreateWidgets(self):
+        self.tabPages = TabPageSet(self,
+                pageNames=['Fonts/Tabs','Highlighting','Keys','General'])
+        self.tabPages.ChangePage()#activates default (first) page
+        frameActionButtons = Frame(self)
+        #action buttons
+        self.buttonHelp = Button(frameActionButtons,text='Help',
+                command=self.Help,takefocus=FALSE)
+        self.buttonOk = Button(frameActionButtons,text='Ok',
+                command=self.Ok,takefocus=FALSE)
+        self.buttonApply = Button(frameActionButtons,text='Apply',
+                command=self.Apply,takefocus=FALSE)
+        self.buttonCancel = Button(frameActionButtons,text='Cancel',
+                command=self.Cancel,takefocus=FALSE)
+        self.CreatePageFontTab()
+        self.CreatePageHighlight()
+        self.CreatePageKeys()
+        self.CreatePageGeneral()
+        self.buttonHelp.pack(side=RIGHT,padx=5,pady=5)
+        self.buttonOk.pack(side=LEFT,padx=5,pady=5)
+        self.buttonApply.pack(side=LEFT,padx=5,pady=5)
+        self.buttonCancel.pack(side=LEFT,padx=5,pady=5)
+        frameActionButtons.pack(side=BOTTOM)
+        self.tabPages.pack(side=TOP,expand=TRUE,fill=BOTH)
+
+    def CreatePageFontTab(self):
+        #tkVars
+        self.fontSize=StringVar(self)
+        self.fontBold=BooleanVar(self)
+        self.fontName=StringVar(self)
+        self.spaceNum=IntVar(self)
+        self.editFont=tkFont.Font(self,('courier',10,'normal'))
+        ##widget creation
+        #body frame
+        frame=self.tabPages.pages['Fonts/Tabs']['page']
+        #body section frames
+        frameFont=Frame(frame,borderwidth=2,relief=GROOVE)
+        frameIndent=Frame(frame,borderwidth=2,relief=GROOVE)
+        #frameFont
+        labelFontTitle=Label(frameFont,text='Set Base Editor Font')
+        frameFontName=Frame(frameFont)
+        frameFontParam=Frame(frameFont)
+        labelFontNameTitle=Label(frameFontName,justify=LEFT,
+                text='Font :')
+        self.listFontName=Listbox(frameFontName,height=5,takefocus=FALSE,
+                exportselection=FALSE)
+        self.listFontName.bind('<ButtonRelease-1>',self.OnListFontButtonRelease)
+        scrollFont=Scrollbar(frameFontName)
+        scrollFont.config(command=self.listFontName.yview)
+        self.listFontName.config(yscrollcommand=scrollFont.set)
+        labelFontSizeTitle=Label(frameFontParam,text='Size :')
+        self.optMenuFontSize=DynOptionMenu(frameFontParam,self.fontSize,None,
+            command=self.SetFontSample)
+        checkFontBold=Checkbutton(frameFontParam,variable=self.fontBold,
+            onvalue=1,offvalue=0,text='Bold',command=self.SetFontSample)
+        frameFontSample=Frame(frameFont,relief=SOLID,borderwidth=1)
+        self.labelFontSample=Label(frameFontSample,
+                text='AaBbCcDdEe\nFfGgHhIiJjK\n1234567890\n#:+=(){}[]',
+                justify=LEFT,font=self.editFont)
+        #frameIndent
+        frameIndentSize=Frame(frameIndent)
+        labelSpaceNumTitle=Label(frameIndentSize, justify=LEFT,
+                                 text='Python Standard: 4 Spaces!')
+        self.scaleSpaceNum=Scale(frameIndentSize, variable=self.spaceNum,
+                                 label='Indentation Width', orient='horizontal',
+                                 tickinterval=2, from_=2, to=16)
+        #widget packing
+        #body
+        frameFont.pack(side=LEFT,padx=5,pady=10,expand=TRUE,fill=BOTH)
+        frameIndent.pack(side=LEFT,padx=5,pady=10,fill=Y)
+        #frameFont
+        labelFontTitle.pack(side=TOP,anchor=W,padx=5,pady=5)
+        frameFontName.pack(side=TOP,padx=5,pady=5,fill=X)
+        frameFontParam.pack(side=TOP,padx=5,pady=5,fill=X)
+        labelFontNameTitle.pack(side=TOP,anchor=W)
+        self.listFontName.pack(side=LEFT,expand=TRUE,fill=X)
+        scrollFont.pack(side=LEFT,fill=Y)
+        labelFontSizeTitle.pack(side=LEFT,anchor=W)
+        self.optMenuFontSize.pack(side=LEFT,anchor=W)
+        checkFontBold.pack(side=LEFT,anchor=W,padx=20)
+        frameFontSample.pack(side=TOP,padx=5,pady=5,expand=TRUE,fill=BOTH)
+        self.labelFontSample.pack(expand=TRUE,fill=BOTH)
+        #frameIndent
+        frameIndentSize.pack(side=TOP,padx=5,pady=5,fill=BOTH)
+        labelSpaceNumTitle.pack(side=TOP,anchor=W,padx=5)
+        self.scaleSpaceNum.pack(side=TOP,padx=5,fill=X)
+        return frame
+
+    def CreatePageHighlight(self):
+        self.builtinTheme=StringVar(self)
+        self.customTheme=StringVar(self)
+        self.fgHilite=BooleanVar(self)
+        self.colour=StringVar(self)
+        self.fontName=StringVar(self)
+        self.themeIsBuiltin=BooleanVar(self)
+        self.highlightTarget=StringVar(self)
+        ##widget creation
+        #body frame
+        frame=self.tabPages.pages['Highlighting']['page']
+        #body section frames
+        frameCustom=Frame(frame,borderwidth=2,relief=GROOVE)
+        frameTheme=Frame(frame,borderwidth=2,relief=GROOVE)
+        #frameCustom
+        self.textHighlightSample=Text(frameCustom,relief=SOLID,borderwidth=1,
+            font=('courier',12,''),cursor='hand2',width=21,height=10,
+            takefocus=FALSE,highlightthickness=0,wrap=NONE)
+        text=self.textHighlightSample
+        text.bind('<Double-Button-1>',lambda e: 'break')
+        text.bind('<B1-Motion>',lambda e: 'break')
+        textAndTags=(('#you can click here','comment'),('\n','normal'),
+            ('#to choose items','comment'),('\n','normal'),('def','keyword'),
+            (' ','normal'),('func','definition'),('(param):','normal'),
+            ('\n  ','normal'),('"""string"""','string'),('\n  var0 = ','normal'),
+            ("'string'",'string'),('\n  var1 = ','normal'),("'selected'",'hilite'),
+            ('\n  var2 = ','normal'),("'found'",'hit'),
+            ('\n  var3 = ','normal'),('list', 'builtin'), ('(','normal'),
+            ('None', 'builtin'),(')\n\n','normal'),
+            (' error ','error'),(' ','normal'),('cursor |','cursor'),
+            ('\n ','normal'),('shell','console'),(' ','normal'),('stdout','stdout'),
+            (' ','normal'),('stderr','stderr'),('\n','normal'))
+        for txTa in textAndTags:
+            text.insert(END,txTa[0],txTa[1])
+        for element in self.themeElements.keys():
+            text.tag_bind(self.themeElements[element][0],'<ButtonPress-1>',
+                lambda event,elem=element: event.widget.winfo_toplevel()
+                .highlightTarget.set(elem))
+        text.config(state=DISABLED)
+        self.frameColourSet=Frame(frameCustom,relief=SOLID,borderwidth=1)
+        frameFgBg=Frame(frameCustom)
+        labelCustomTitle=Label(frameCustom,text='Set Custom Highlighting')
+        buttonSetColour=Button(self.frameColourSet,text='Choose Colour for :',
+            command=self.GetColour,highlightthickness=0)
+        self.optMenuHighlightTarget=DynOptionMenu(self.frameColourSet,
+            self.highlightTarget,None,highlightthickness=0)#,command=self.SetHighlightTargetBinding
+        self.radioFg=Radiobutton(frameFgBg,variable=self.fgHilite,
+            value=1,text='Foreground',command=self.SetColourSampleBinding)
+        self.radioBg=Radiobutton(frameFgBg,variable=self.fgHilite,
+            value=0,text='Background',command=self.SetColourSampleBinding)
+        self.fgHilite.set(1)
+        buttonSaveCustomTheme=Button(frameCustom,
+            text='Save as New Custom Theme',command=self.SaveAsNewTheme)
+        #frameTheme
+        labelThemeTitle=Label(frameTheme,text='Select a Highlighting Theme')
+        labelTypeTitle=Label(frameTheme,text='Select : ')
+        self.radioThemeBuiltin=Radiobutton(frameTheme,variable=self.themeIsBuiltin,
+            value=1,command=self.SetThemeType,text='a Built-in Theme')
+        self.radioThemeCustom=Radiobutton(frameTheme,variable=self.themeIsBuiltin,
+            value=0,command=self.SetThemeType,text='a Custom Theme')
+        self.optMenuThemeBuiltin=DynOptionMenu(frameTheme,
+            self.builtinTheme,None,command=None)
+        self.optMenuThemeCustom=DynOptionMenu(frameTheme,
+            self.customTheme,None,command=None)
+        self.buttonDeleteCustomTheme=Button(frameTheme,text='Delete Custom Theme',
+                command=self.DeleteCustomTheme)
+        ##widget packing
+        #body
+        frameCustom.pack(side=LEFT,padx=5,pady=10,expand=TRUE,fill=BOTH)
+        frameTheme.pack(side=LEFT,padx=5,pady=10,fill=Y)
+        #frameCustom
+        labelCustomTitle.pack(side=TOP,anchor=W,padx=5,pady=5)
+        self.frameColourSet.pack(side=TOP,padx=5,pady=5,expand=TRUE,fill=X)
+        frameFgBg.pack(side=TOP,padx=5,pady=0)
+        self.textHighlightSample.pack(side=TOP,padx=5,pady=5,expand=TRUE,
+            fill=BOTH)
+        buttonSetColour.pack(side=TOP,expand=TRUE,fill=X,padx=8,pady=4)
+        self.optMenuHighlightTarget.pack(side=TOP,expand=TRUE,fill=X,padx=8,pady=3)
+        self.radioFg.pack(side=LEFT,anchor=E)
+        self.radioBg.pack(side=RIGHT,anchor=W)
+        buttonSaveCustomTheme.pack(side=BOTTOM,fill=X,padx=5,pady=5)
+        #frameTheme
+        labelThemeTitle.pack(side=TOP,anchor=W,padx=5,pady=5)
+        labelTypeTitle.pack(side=TOP,anchor=W,padx=5,pady=5)
+        self.radioThemeBuiltin.pack(side=TOP,anchor=W,padx=5)
+        self.radioThemeCustom.pack(side=TOP,anchor=W,padx=5,pady=2)
+        self.optMenuThemeBuiltin.pack(side=TOP,fill=X,padx=5,pady=5)
+        self.optMenuThemeCustom.pack(side=TOP,fill=X,anchor=W,padx=5,pady=5)
+        self.buttonDeleteCustomTheme.pack(side=TOP,fill=X,padx=5,pady=5)
+        return frame
+
+    def CreatePageKeys(self):
+        #tkVars
+        self.bindingTarget=StringVar(self)
+        self.builtinKeys=StringVar(self)
+        self.customKeys=StringVar(self)
+        self.keysAreBuiltin=BooleanVar(self)
+        self.keyBinding=StringVar(self)
+        ##widget creation
+        #body frame
+        frame=self.tabPages.pages['Keys']['page']
+        #body section frames
+        frameCustom=Frame(frame,borderwidth=2,relief=GROOVE)
+        frameKeySets=Frame(frame,borderwidth=2,relief=GROOVE)
+        #frameCustom
+        frameTarget=Frame(frameCustom)
+        labelCustomTitle=Label(frameCustom,text='Set Custom Key Bindings')
+        labelTargetTitle=Label(frameTarget,text='Action - Key(s)')
+        scrollTargetY=Scrollbar(frameTarget)
+        scrollTargetX=Scrollbar(frameTarget,orient=HORIZONTAL)
+        self.listBindings=Listbox(frameTarget,takefocus=FALSE,
+                exportselection=FALSE)
+        self.listBindings.bind('<ButtonRelease-1>',self.KeyBindingSelected)
+        scrollTargetY.config(command=self.listBindings.yview)
+        scrollTargetX.config(command=self.listBindings.xview)
+        self.listBindings.config(yscrollcommand=scrollTargetY.set)
+        self.listBindings.config(xscrollcommand=scrollTargetX.set)
+        self.buttonNewKeys=Button(frameCustom,text='Get New Keys for Selection',
+            command=self.GetNewKeys,state=DISABLED)
+        buttonSaveCustomKeys=Button(frameCustom,
+                text='Save as New Custom Key Set',command=self.SaveAsNewKeySet)
+        #frameKeySets
+        labelKeysTitle=Label(frameKeySets,text='Select a Key Set')
+        labelTypeTitle=Label(frameKeySets,text='Select : ')
+        self.radioKeysBuiltin=Radiobutton(frameKeySets,variable=self.keysAreBuiltin,
+            value=1,command=self.SetKeysType,text='a Built-in Key Set')
+        self.radioKeysCustom=Radiobutton(frameKeySets,variable=self.keysAreBuiltin,
+            value=0,command=self.SetKeysType,text='a Custom Key Set')
+        self.optMenuKeysBuiltin=DynOptionMenu(frameKeySets,
+            self.builtinKeys,None,command=None)
+        self.optMenuKeysCustom=DynOptionMenu(frameKeySets,
+            self.customKeys,None,command=None)
+        self.buttonDeleteCustomKeys=Button(frameKeySets,text='Delete Custom Key Set',
+                command=self.DeleteCustomKeys)
+        ##widget packing
+        #body
+        frameCustom.pack(side=LEFT,padx=5,pady=5,expand=TRUE,fill=BOTH)
+        frameKeySets.pack(side=LEFT,padx=5,pady=5,fill=Y)
+        #frameCustom
+        labelCustomTitle.pack(side=TOP,anchor=W,padx=5,pady=5)
+        buttonSaveCustomKeys.pack(side=BOTTOM,fill=X,padx=5,pady=5)
+        self.buttonNewKeys.pack(side=BOTTOM,fill=X,padx=5,pady=5)
+        frameTarget.pack(side=LEFT,padx=5,pady=5,expand=TRUE,fill=BOTH)
+        #frame target
+        frameTarget.columnconfigure(0,weight=1)
+        frameTarget.rowconfigure(1,weight=1)
+        labelTargetTitle.grid(row=0,column=0,columnspan=2,sticky=W)
+        self.listBindings.grid(row=1,column=0,sticky=NSEW)
+        scrollTargetY.grid(row=1,column=1,sticky=NS)
+        scrollTargetX.grid(row=2,column=0,sticky=EW)
+        #frameKeySets
+        labelKeysTitle.pack(side=TOP,anchor=W,padx=5,pady=5)
+        labelTypeTitle.pack(side=TOP,anchor=W,padx=5,pady=5)
+        self.radioKeysBuiltin.pack(side=TOP,anchor=W,padx=5)
+        self.radioKeysCustom.pack(side=TOP,anchor=W,padx=5,pady=2)
+        self.optMenuKeysBuiltin.pack(side=TOP,fill=X,padx=5,pady=5)
+        self.optMenuKeysCustom.pack(side=TOP,fill=X,anchor=W,padx=5,pady=5)
+        self.buttonDeleteCustomKeys.pack(side=TOP,fill=X,padx=5,pady=5)
+        return frame
+
+    def CreatePageGeneral(self):
+        #tkVars
+        self.winWidth=StringVar(self)
+        self.winHeight=StringVar(self)
+        self.paraWidth=StringVar(self)
+        self.startupEdit=IntVar(self)
+        self.autoSave=IntVar(self)
+        self.encoding=StringVar(self)
+        self.userHelpBrowser=BooleanVar(self)
+        self.helpBrowser=StringVar(self)
+        #widget creation
+        #body
+        frame=self.tabPages.pages['General']['page']
+        #body section frames
+        frameRun=Frame(frame,borderwidth=2,relief=GROOVE)
+        frameSave=Frame(frame,borderwidth=2,relief=GROOVE)
+        frameWinSize=Frame(frame,borderwidth=2,relief=GROOVE)
+        frameParaSize=Frame(frame,borderwidth=2,relief=GROOVE)
+        frameEncoding=Frame(frame,borderwidth=2,relief=GROOVE)
+        frameHelp=Frame(frame,borderwidth=2,relief=GROOVE)
+        #frameRun
+        labelRunTitle=Label(frameRun,text='Startup Preferences')
+        labelRunChoiceTitle=Label(frameRun,text='At Startup')
+        radioStartupEdit=Radiobutton(frameRun,variable=self.startupEdit,
+            value=1,command=self.SetKeysType,text="Open Edit Window")
+        radioStartupShell=Radiobutton(frameRun,variable=self.startupEdit,
+            value=0,command=self.SetKeysType,text='Open Shell Window')
+        #frameSave
+        labelSaveTitle=Label(frameSave,text='Autosave Preference')
+        labelRunSaveTitle=Label(frameSave,text='At Start of Run (F5)  ')
+        radioSaveAsk=Radiobutton(frameSave,variable=self.autoSave,
+            value=0,command=self.SetKeysType,text="Prompt to Save")
+        radioSaveAuto=Radiobutton(frameSave,variable=self.autoSave,
+            value=1,command=self.SetKeysType,text='No Prompt')
+        #frameWinSize
+        labelWinSizeTitle=Label(frameWinSize,text='Initial Window Size'+
+                '  (in characters)')
+        labelWinWidthTitle=Label(frameWinSize,text='Width')
+        entryWinWidth=Entry(frameWinSize,textvariable=self.winWidth,
+                width=3)
+        labelWinHeightTitle=Label(frameWinSize,text='Height')
+        entryWinHeight=Entry(frameWinSize,textvariable=self.winHeight,
+                width=3)
+        #paragraphFormatWidth
+        labelParaWidthTitle=Label(frameParaSize,text='Paragraph reformat'+
+                ' width (in characters)')
+        entryParaWidth=Entry(frameParaSize,textvariable=self.paraWidth,
+                width=3)
+        #frameEncoding
+        labelEncodingTitle=Label(frameEncoding,text="Default Source Encoding")
+        radioEncLocale=Radiobutton(frameEncoding,variable=self.encoding,
+            value="locale",text="Locale-defined")
+        radioEncUTF8=Radiobutton(frameEncoding,variable=self.encoding,
+            value="utf-8",text="UTF-8")
+        radioEncNone=Radiobutton(frameEncoding,variable=self.encoding,
+            value="none",text="None")
+        #frameHelp
+        frameHelpList=Frame(frameHelp)
+        frameHelpListButtons=Frame(frameHelpList)
+        labelHelpListTitle=Label(frameHelpList,text='Additional Help Sources:')
+        scrollHelpList=Scrollbar(frameHelpList)
+        self.listHelp=Listbox(frameHelpList,height=5,takefocus=FALSE,
+                exportselection=FALSE)
+        scrollHelpList.config(command=self.listHelp.yview)
+        self.listHelp.config(yscrollcommand=scrollHelpList.set)
+        self.listHelp.bind('<ButtonRelease-1>',self.HelpSourceSelected)
+        self.buttonHelpListEdit=Button(frameHelpListButtons,text='Edit',
+                state=DISABLED,width=8,command=self.HelpListItemEdit)
+        self.buttonHelpListAdd=Button(frameHelpListButtons,text='Add',
+                width=8,command=self.HelpListItemAdd)
+        self.buttonHelpListRemove=Button(frameHelpListButtons,text='Remove',
+                state=DISABLED,width=8,command=self.HelpListItemRemove)
+        #widget packing
+        #body
+        frameRun.pack(side=TOP,padx=5,pady=5,fill=X)
+        frameSave.pack(side=TOP,padx=5,pady=5,fill=X)
+        frameWinSize.pack(side=TOP,padx=5,pady=5,fill=X)
+        frameParaSize.pack(side=TOP,padx=5,pady=5,fill=X)
+        frameEncoding.pack(side=TOP,padx=5,pady=5,fill=X)
+        frameHelp.pack(side=TOP,padx=5,pady=5,expand=TRUE,fill=BOTH)
+        #frameRun
+        labelRunTitle.pack(side=TOP,anchor=W,padx=5,pady=5)
+        labelRunChoiceTitle.pack(side=LEFT,anchor=W,padx=5,pady=5)
+        radioStartupShell.pack(side=RIGHT,anchor=W,padx=5,pady=5)
+        radioStartupEdit.pack(side=RIGHT,anchor=W,padx=5,pady=5)
+        #frameSave
+        labelSaveTitle.pack(side=TOP,anchor=W,padx=5,pady=5)
+        labelRunSaveTitle.pack(side=LEFT,anchor=W,padx=5,pady=5)
+        radioSaveAuto.pack(side=RIGHT,anchor=W,padx=5,pady=5)
+        radioSaveAsk.pack(side=RIGHT,anchor=W,padx=5,pady=5)
+        #frameWinSize
+        labelWinSizeTitle.pack(side=LEFT,anchor=W,padx=5,pady=5)
+        entryWinHeight.pack(side=RIGHT,anchor=E,padx=10,pady=5)
+        labelWinHeightTitle.pack(side=RIGHT,anchor=E,pady=5)
+        entryWinWidth.pack(side=RIGHT,anchor=E,padx=10,pady=5)
+        labelWinWidthTitle.pack(side=RIGHT,anchor=E,pady=5)
+        #paragraphFormatWidth
+        labelParaWidthTitle.pack(side=LEFT,anchor=W,padx=5,pady=5)
+        entryParaWidth.pack(side=RIGHT,anchor=E,padx=10,pady=5)
+        #frameEncoding
+        labelEncodingTitle.pack(side=LEFT,anchor=W,padx=5,pady=5)
+        radioEncNone.pack(side=RIGHT,anchor=E,pady=5)
+        radioEncUTF8.pack(side=RIGHT,anchor=E,pady=5)
+        radioEncLocale.pack(side=RIGHT,anchor=E,pady=5)
+        #frameHelp
+        frameHelpListButtons.pack(side=RIGHT,padx=5,pady=5,fill=Y)
+        frameHelpList.pack(side=TOP,padx=5,pady=5,expand=TRUE,fill=BOTH)
+        labelHelpListTitle.pack(side=TOP,anchor=W)
+        scrollHelpList.pack(side=RIGHT,anchor=W,fill=Y)
+        self.listHelp.pack(side=LEFT,anchor=E,expand=TRUE,fill=BOTH)
+        self.buttonHelpListEdit.pack(side=TOP,anchor=W,pady=5)
+        self.buttonHelpListAdd.pack(side=TOP,anchor=W)
+        self.buttonHelpListRemove.pack(side=TOP,anchor=W,pady=5)
+        return frame
+
+    def AttachVarCallbacks(self):
+        self.fontSize.trace_variable('w',self.VarChanged_fontSize)
+        self.fontName.trace_variable('w',self.VarChanged_fontName)
+        self.fontBold.trace_variable('w',self.VarChanged_fontBold)
+        self.spaceNum.trace_variable('w',self.VarChanged_spaceNum)
+        self.colour.trace_variable('w',self.VarChanged_colour)
+        self.builtinTheme.trace_variable('w',self.VarChanged_builtinTheme)
+        self.customTheme.trace_variable('w',self.VarChanged_customTheme)
+        self.themeIsBuiltin.trace_variable('w',self.VarChanged_themeIsBuiltin)
+        self.highlightTarget.trace_variable('w',self.VarChanged_highlightTarget)
+        self.keyBinding.trace_variable('w',self.VarChanged_keyBinding)
+        self.builtinKeys.trace_variable('w',self.VarChanged_builtinKeys)
+        self.customKeys.trace_variable('w',self.VarChanged_customKeys)
+        self.keysAreBuiltin.trace_variable('w',self.VarChanged_keysAreBuiltin)
+        self.winWidth.trace_variable('w',self.VarChanged_winWidth)
+        self.winHeight.trace_variable('w',self.VarChanged_winHeight)
+        self.paraWidth.trace_variable('w',self.VarChanged_paraWidth)
+        self.startupEdit.trace_variable('w',self.VarChanged_startupEdit)
+        self.autoSave.trace_variable('w',self.VarChanged_autoSave)
+        self.encoding.trace_variable('w',self.VarChanged_encoding)
+
+    def VarChanged_fontSize(self,*params):
+        value=self.fontSize.get()
+        self.AddChangedItem('main','EditorWindow','font-size',value)
+
+    def VarChanged_fontName(self,*params):
+        value=self.fontName.get()
+        self.AddChangedItem('main','EditorWindow','font',value)
+
+    def VarChanged_fontBold(self,*params):
+        value=self.fontBold.get()
+        self.AddChangedItem('main','EditorWindow','font-bold',value)
+
+    def VarChanged_spaceNum(self,*params):
+        value=self.spaceNum.get()
+        self.AddChangedItem('main','Indent','num-spaces',value)
+
+    def VarChanged_colour(self,*params):
+        self.OnNewColourSet()
+
+    def VarChanged_builtinTheme(self,*params):
+        value=self.builtinTheme.get()
+        self.AddChangedItem('main','Theme','name',value)
+        self.PaintThemeSample()
+
+    def VarChanged_customTheme(self,*params):
+        value=self.customTheme.get()
+        if value != '- no custom themes -':
+            self.AddChangedItem('main','Theme','name',value)
+            self.PaintThemeSample()
+
+    def VarChanged_themeIsBuiltin(self,*params):
+        value=self.themeIsBuiltin.get()
+        self.AddChangedItem('main','Theme','default',value)
+        if value:
+            self.VarChanged_builtinTheme()
+        else:
+            self.VarChanged_customTheme()
+
+    def VarChanged_highlightTarget(self,*params):
+        self.SetHighlightTarget()
+
+    def VarChanged_keyBinding(self,*params):
+        value=self.keyBinding.get()
+        keySet=self.customKeys.get()
+        event=self.listBindings.get(ANCHOR).split()[0]
+        if idleConf.IsCoreBinding(event):
+            #this is a core keybinding
+            self.AddChangedItem('keys',keySet,event,value)
+        else: #this is an extension key binding
+            extName=idleConf.GetExtnNameForEvent(event)
+            extKeybindSection=extName+'_cfgBindings'
+            self.AddChangedItem('extensions',extKeybindSection,event,value)
+
+    def VarChanged_builtinKeys(self,*params):
+        value=self.builtinKeys.get()
+        self.AddChangedItem('main','Keys','name',value)
+        self.LoadKeysList(value)
+
+    def VarChanged_customKeys(self,*params):
+        value=self.customKeys.get()
+        if value != '- no custom keys -':
+            self.AddChangedItem('main','Keys','name',value)
+            self.LoadKeysList(value)
+
+    def VarChanged_keysAreBuiltin(self,*params):
+        value=self.keysAreBuiltin.get()
+        self.AddChangedItem('main','Keys','default',value)
+        if value:
+            self.VarChanged_builtinKeys()
+        else:
+            self.VarChanged_customKeys()
+
+    def VarChanged_winWidth(self,*params):
+        value=self.winWidth.get()
+        self.AddChangedItem('main','EditorWindow','width',value)
+
+    def VarChanged_winHeight(self,*params):
+        value=self.winHeight.get()
+        self.AddChangedItem('main','EditorWindow','height',value)
+
+    def VarChanged_paraWidth(self,*params):
+        value=self.paraWidth.get()
+        self.AddChangedItem('main','FormatParagraph','paragraph',value)
+
+    def VarChanged_startupEdit(self,*params):
+        value=self.startupEdit.get()
+        self.AddChangedItem('main','General','editor-on-startup',value)
+
+    def VarChanged_autoSave(self,*params):
+        value=self.autoSave.get()
+        self.AddChangedItem('main','General','autosave',value)
+
+    def VarChanged_encoding(self,*params):
+        value=self.encoding.get()
+        self.AddChangedItem('main','EditorWindow','encoding',value)
+
+    def ResetChangedItems(self):
+        #When any config item is changed in this dialog, an entry
+        #should be made in the relevant section (config type) of this
+        #dictionary. The key should be the config file section name and the
+        #value a dictionary, whose key:value pairs are item=value pairs for
+        #that config file section.
+        self.changedItems={'main':{},'highlight':{},'keys':{},'extensions':{}}
+
+    def AddChangedItem(self,type,section,item,value):
+        value=str(value) #make sure we use a string
+        if not self.changedItems[type].has_key(section):
+            self.changedItems[type][section]={}
+        self.changedItems[type][section][item]=value
+
+    def GetDefaultItems(self):
+        dItems={'main':{},'highlight':{},'keys':{},'extensions':{}}
+        for configType in dItems.keys():
+            sections=idleConf.GetSectionList('default',configType)
+            for section in sections:
+                dItems[configType][section]={}
+                options=idleConf.defaultCfg[configType].GetOptionList(section)
+                for option in options:
+                    dItems[configType][section][option]=(
+                            idleConf.defaultCfg[configType].Get(section,option))
+        return dItems
+
+    def SetThemeType(self):
+        if self.themeIsBuiltin.get():
+            self.optMenuThemeBuiltin.config(state=NORMAL)
+            self.optMenuThemeCustom.config(state=DISABLED)
+            self.buttonDeleteCustomTheme.config(state=DISABLED)
+        else:
+            self.optMenuThemeBuiltin.config(state=DISABLED)
+            self.radioThemeCustom.config(state=NORMAL)
+            self.optMenuThemeCustom.config(state=NORMAL)
+            self.buttonDeleteCustomTheme.config(state=NORMAL)
+
+    def SetKeysType(self):
+        if self.keysAreBuiltin.get():
+            self.optMenuKeysBuiltin.config(state=NORMAL)
+            self.optMenuKeysCustom.config(state=DISABLED)
+            self.buttonDeleteCustomKeys.config(state=DISABLED)
+        else:
+            self.optMenuKeysBuiltin.config(state=DISABLED)
+            self.radioKeysCustom.config(state=NORMAL)
+            self.optMenuKeysCustom.config(state=NORMAL)
+            self.buttonDeleteCustomKeys.config(state=NORMAL)
+
+    def GetNewKeys(self):
+        listIndex=self.listBindings.index(ANCHOR)
+        binding=self.listBindings.get(listIndex)
+        bindName=binding.split()[0] #first part, up to first space
+        if self.keysAreBuiltin.get():
+            currentKeySetName=self.builtinKeys.get()
+        else:
+            currentKeySetName=self.customKeys.get()
+        currentBindings=idleConf.GetCurrentKeySet()
+        if currentKeySetName in self.changedItems['keys'].keys(): #unsaved changes
+            keySetChanges=self.changedItems['keys'][currentKeySetName]
+            for event in keySetChanges.keys():
+                currentBindings[event]=keySetChanges[event].split()
+        currentKeySequences=currentBindings.values()
+        newKeys=GetKeysDialog(self,'Get New Keys',bindName,
+                currentKeySequences).result
+        if newKeys: #new keys were specified
+            if self.keysAreBuiltin.get(): #current key set is a built-in
+                message=('Your changes will be saved as a new Custom Key Set. '+
+                        'Enter a name for your new Custom Key Set below.')
+                newKeySet=self.GetNewKeysName(message)
+                if not newKeySet: #user cancelled custom key set creation
+                    self.listBindings.select_set(listIndex)
+                    self.listBindings.select_anchor(listIndex)
+                    return
+                else: #create new custom key set based on previously active key set
+                    self.CreateNewKeySet(newKeySet)
+            self.listBindings.delete(listIndex)
+            self.listBindings.insert(listIndex,bindName+' - '+newKeys)
+            self.listBindings.select_set(listIndex)
+            self.listBindings.select_anchor(listIndex)
+            self.keyBinding.set(newKeys)
+        else:
+            self.listBindings.select_set(listIndex)
+            self.listBindings.select_anchor(listIndex)
+
+    def GetNewKeysName(self,message):
+        usedNames=(idleConf.GetSectionList('user','keys')+
+                idleConf.GetSectionList('default','keys'))
+        newKeySet=GetCfgSectionNameDialog(self,'New Custom Key Set',
+                message,usedNames).result
+        return newKeySet
+
+    def SaveAsNewKeySet(self):
+        newKeysName=self.GetNewKeysName('New Key Set Name:')
+        if newKeysName:
+            self.CreateNewKeySet(newKeysName)
+
+    def KeyBindingSelected(self,event):
+        self.buttonNewKeys.config(state=NORMAL)
+
+    def CreateNewKeySet(self,newKeySetName):
+        #creates new custom key set based on the previously active key set,
+        #and makes the new key set active
+        if self.keysAreBuiltin.get():
+            prevKeySetName=self.builtinKeys.get()
+        else:
+            prevKeySetName=self.customKeys.get()
+        prevKeys=idleConf.GetCoreKeys(prevKeySetName)
+        newKeys={}
+        for event in prevKeys.keys(): #add key set to changed items
+            eventName=event[2:-2] #trim off the angle brackets
+            binding=string.join(prevKeys[event])
+            newKeys[eventName]=binding
+        #handle any unsaved changes to prev key set
+        if prevKeySetName in self.changedItems['keys'].keys():
+            keySetChanges=self.changedItems['keys'][prevKeySetName]
+            for event in keySetChanges.keys():
+                newKeys[event]=keySetChanges[event]
+        #save the new theme
+        self.SaveNewKeySet(newKeySetName,newKeys)
+        #change gui over to the new key set
+        customKeyList=idleConf.GetSectionList('user','keys')
+        customKeyList.sort()
+        self.optMenuKeysCustom.SetMenu(customKeyList,newKeySetName)
+        self.keysAreBuiltin.set(0)
+        self.SetKeysType()
+
+    def LoadKeysList(self,keySetName):
+        reselect=0
+        newKeySet=0
+        if self.listBindings.curselection():
+            reselect=1
+            listIndex=self.listBindings.index(ANCHOR)
+        keySet=idleConf.GetKeySet(keySetName)
+        bindNames=keySet.keys()
+        bindNames.sort()
+        self.listBindings.delete(0,END)
+        for bindName in bindNames:
+            key=string.join(keySet[bindName]) #make key(s) into a string
+            bindName=bindName[2:-2] #trim off the angle brackets
+            if keySetName in self.changedItems['keys'].keys():
+                #handle any unsaved changes to this key set
+                if bindName in self.changedItems['keys'][keySetName].keys():
+                    key=self.changedItems['keys'][keySetName][bindName]
+            self.listBindings.insert(END, bindName+' - '+key)
+        if reselect:
+            self.listBindings.see(listIndex)
+            self.listBindings.select_set(listIndex)
+            self.listBindings.select_anchor(listIndex)
+
+    def DeleteCustomKeys(self):
+        keySetName=self.customKeys.get()
+        if not tkMessageBox.askyesno('Delete Key Set','Are you sure you wish '+
+                                     'to delete the key set %r ?' % (keySetName),
+                                     parent=self):
+            return
+        #remove key set from config
+        idleConf.userCfg['keys'].remove_section(keySetName)
+        if self.changedItems['keys'].has_key(keySetName):
+            del(self.changedItems['keys'][keySetName])
+        #write changes
+        idleConf.userCfg['keys'].Save()
+        #reload user key set list
+        itemList=idleConf.GetSectionList('user','keys')
+        itemList.sort()
+        if not itemList:
+            self.radioKeysCustom.config(state=DISABLED)
+            self.optMenuKeysCustom.SetMenu(itemList,'- no custom keys -')
+        else:
+            self.optMenuKeysCustom.SetMenu(itemList,itemList[0])
+        #revert to default key set
+        self.keysAreBuiltin.set(idleConf.defaultCfg['main'].Get('Keys','default'))
+        self.builtinKeys.set(idleConf.defaultCfg['main'].Get('Keys','name'))
+        #user can't back out of these changes, they must be applied now
+        self.Apply()
+        self.SetKeysType()
+
+    def DeleteCustomTheme(self):
+        themeName=self.customTheme.get()
+        if not tkMessageBox.askyesno('Delete Theme','Are you sure you wish '+
+                                     'to delete the theme %r ?' % (themeName,),
+                                     parent=self):
+            return
+        #remove theme from config
+        idleConf.userCfg['highlight'].remove_section(themeName)
+        if self.changedItems['highlight'].has_key(themeName):
+            del(self.changedItems['highlight'][themeName])
+        #write changes
+        idleConf.userCfg['highlight'].Save()
+        #reload user theme list
+        itemList=idleConf.GetSectionList('user','highlight')
+        itemList.sort()
+        if not itemList:
+            self.radioThemeCustom.config(state=DISABLED)
+            self.optMenuThemeCustom.SetMenu(itemList,'- no custom themes -')
+        else:
+            self.optMenuThemeCustom.SetMenu(itemList,itemList[0])
+        #revert to default theme
+        self.themeIsBuiltin.set(idleConf.defaultCfg['main'].Get('Theme','default'))
+        self.builtinTheme.set(idleConf.defaultCfg['main'].Get('Theme','name'))
+        #user can't back out of these changes, they must be applied now
+        self.Apply()
+        self.SetThemeType()
+
+    def GetColour(self):
+        target=self.highlightTarget.get()
+        prevColour=self.frameColourSet.cget('bg')
+        rgbTuplet, colourString = tkColorChooser.askcolor(parent=self,
+            title='Pick new colour for : '+target,initialcolor=prevColour)
+        if colourString and (colourString!=prevColour):
+            #user didn't cancel, and they chose a new colour
+            if self.themeIsBuiltin.get(): #current theme is a built-in
+                message=('Your changes will be saved as a new Custom Theme. '+
+                        'Enter a name for your new Custom Theme below.')
+                newTheme=self.GetNewThemeName(message)
+                if not newTheme: #user cancelled custom theme creation
+                    return
+                else: #create new custom theme based on previously active theme
+                    self.CreateNewTheme(newTheme)
+                    self.colour.set(colourString)
+            else: #current theme is user defined
+                self.colour.set(colourString)
+
+    def OnNewColourSet(self):
+        newColour=self.colour.get()
+        self.frameColourSet.config(bg=newColour)#set sample
+        if self.fgHilite.get(): plane='foreground'
+        else: plane='background'
+        sampleElement=self.themeElements[self.highlightTarget.get()][0]
+        self.textHighlightSample.tag_config(sampleElement, **{plane:newColour})
+        theme=self.customTheme.get()
+        themeElement=sampleElement+'-'+plane
+        self.AddChangedItem('highlight',theme,themeElement,newColour)
+
+    def GetNewThemeName(self,message):
+        usedNames=(idleConf.GetSectionList('user','highlight')+
+                idleConf.GetSectionList('default','highlight'))
+        newTheme=GetCfgSectionNameDialog(self,'New Custom Theme',
+                message,usedNames).result
+        return newTheme
+
+    def SaveAsNewTheme(self):
+        newThemeName=self.GetNewThemeName('New Theme Name:')
+        if newThemeName:
+            self.CreateNewTheme(newThemeName)
+
+    def CreateNewTheme(self,newThemeName):
+        #creates new custom theme based on the previously active theme,
+        #and makes the new theme active
+        if self.themeIsBuiltin.get():
+            themeType='default'
+            themeName=self.builtinTheme.get()
+        else:
+            themeType='user'
+            themeName=self.customTheme.get()
+        newTheme=idleConf.GetThemeDict(themeType,themeName)
+        #apply any of the old theme's unsaved changes to the new theme
+        if themeName in self.changedItems['highlight'].keys():
+            themeChanges=self.changedItems['highlight'][themeName]
+            for element in themeChanges.keys():
+                newTheme[element]=themeChanges[element]
+        #save the new theme
+        self.SaveNewTheme(newThemeName,newTheme)
+        #change gui over to the new theme
+        customThemeList=idleConf.GetSectionList('user','highlight')
+        customThemeList.sort()
+        self.optMenuThemeCustom.SetMenu(customThemeList,newThemeName)
+        self.themeIsBuiltin.set(0)
+        self.SetThemeType()
+
+    def OnListFontButtonRelease(self,event):
+        font = self.listFontName.get(ANCHOR)
+        self.fontName.set(font.lower())
+        self.SetFontSample()
+
+    def SetFontSample(self,event=None):
+        fontName=self.fontName.get()
+        if self.fontBold.get():
+            fontWeight=tkFont.BOLD
+        else:
+            fontWeight=tkFont.NORMAL
+        self.editFont.config(size=self.fontSize.get(),
+                weight=fontWeight,family=fontName)
+
+    def SetHighlightTarget(self):
+        if self.highlightTarget.get()=='Cursor': #bg not possible
+            self.radioFg.config(state=DISABLED)
+            self.radioBg.config(state=DISABLED)
+            self.fgHilite.set(1)
+        else: #both fg and bg can be set
+            self.radioFg.config(state=NORMAL)
+            self.radioBg.config(state=NORMAL)
+            self.fgHilite.set(1)
+        self.SetColourSample()
+
+    def SetColourSampleBinding(self,*args):
+        self.SetColourSample()
+
+    def SetColourSample(self):
+        #set the colour smaple area
+        tag=self.themeElements[self.highlightTarget.get()][0]
+        if self.fgHilite.get(): plane='foreground'
+        else: plane='background'
+        colour=self.textHighlightSample.tag_cget(tag,plane)
+        self.frameColourSet.config(bg=colour)
+
+    def PaintThemeSample(self):
+        if self.themeIsBuiltin.get(): #a default theme
+            theme=self.builtinTheme.get()
+        else: #a user theme
+            theme=self.customTheme.get()
+        for elementTitle in self.themeElements.keys():
+            element=self.themeElements[elementTitle][0]
+            colours=idleConf.GetHighlight(theme,element)
+            if element=='cursor': #cursor sample needs special painting
+                colours['background']=idleConf.GetHighlight(theme,
+                        'normal', fgBg='bg')
+            #handle any unsaved changes to this theme
+            if theme in self.changedItems['highlight'].keys():
+                themeDict=self.changedItems['highlight'][theme]
+                if themeDict.has_key(element+'-foreground'):
+                    colours['foreground']=themeDict[element+'-foreground']
+                if themeDict.has_key(element+'-background'):
+                    colours['background']=themeDict[element+'-background']
+            self.textHighlightSample.tag_config(element, **colours)
+        self.SetColourSample()
+
+    def HelpSourceSelected(self,event):
+        self.SetHelpListButtonStates()
+
+    def SetHelpListButtonStates(self):
+        if self.listHelp.size()<1: #no entries in list
+            self.buttonHelpListEdit.config(state=DISABLED)
+            self.buttonHelpListRemove.config(state=DISABLED)
+        else: #there are some entries
+            if self.listHelp.curselection(): #there currently is a selection
+                self.buttonHelpListEdit.config(state=NORMAL)
+                self.buttonHelpListRemove.config(state=NORMAL)
+            else:  #there currently is not a selection
+                self.buttonHelpListEdit.config(state=DISABLED)
+                self.buttonHelpListRemove.config(state=DISABLED)
+
+    def HelpListItemAdd(self):
+        helpSource=GetHelpSourceDialog(self,'New Help Source').result
+        if helpSource:
+            self.userHelpList.append( (helpSource[0],helpSource[1]) )
+            self.listHelp.insert(END,helpSource[0])
+            self.UpdateUserHelpChangedItems()
+        self.SetHelpListButtonStates()
+
+    def HelpListItemEdit(self):
+        itemIndex=self.listHelp.index(ANCHOR)
+        helpSource=self.userHelpList[itemIndex]
+        newHelpSource=GetHelpSourceDialog(self,'Edit Help Source',
+                menuItem=helpSource[0],filePath=helpSource[1]).result
+        if (not newHelpSource) or (newHelpSource==helpSource):
+            return #no changes
+        self.userHelpList[itemIndex]=newHelpSource
+        self.listHelp.delete(itemIndex)
+        self.listHelp.insert(itemIndex,newHelpSource[0])
+        self.UpdateUserHelpChangedItems()
+        self.SetHelpListButtonStates()
+
+    def HelpListItemRemove(self):
+        itemIndex=self.listHelp.index(ANCHOR)
+        del(self.userHelpList[itemIndex])
+        self.listHelp.delete(itemIndex)
+        self.UpdateUserHelpChangedItems()
+        self.SetHelpListButtonStates()
+
+    def UpdateUserHelpChangedItems(self):
+        "Clear and rebuild the HelpFiles section in self.changedItems"
+        self.changedItems['main']['HelpFiles'] = {}
+        for num in range(1,len(self.userHelpList)+1):
+            self.AddChangedItem('main','HelpFiles',str(num),
+                    string.join(self.userHelpList[num-1][:2],';'))
+
+    def LoadFontCfg(self):
+        ##base editor font selection list
+        fonts=list(tkFont.families(self))
+        fonts.sort()
+        for font in fonts:
+            self.listFontName.insert(END,font)
+        configuredFont=idleConf.GetOption('main','EditorWindow','font',
+                default='courier')
+        lc_configuredFont = configuredFont.lower()
+        self.fontName.set(lc_configuredFont)
+        lc_fonts = [s.lower() for s in fonts]
+        if lc_configuredFont in lc_fonts:
+            currentFontIndex = lc_fonts.index(lc_configuredFont)
+            self.listFontName.see(currentFontIndex)
+            self.listFontName.select_set(currentFontIndex)
+            self.listFontName.select_anchor(currentFontIndex)
+        ##font size dropdown
+        fontSize=idleConf.GetOption('main','EditorWindow','font-size',
+                default='10')
+        self.optMenuFontSize.SetMenu(('7','8','9','10','11','12','13','14',
+                '16','18','20','22'),fontSize )
+        ##fontWeight
+        self.fontBold.set(idleConf.GetOption('main','EditorWindow',
+                'font-bold',default=0,type='bool'))
+        ##font sample
+        self.SetFontSample()
+
+    def LoadTabCfg(self):
+        ##indent sizes
+        spaceNum=idleConf.GetOption('main','Indent','num-spaces',
+                default=4,type='int')
+        self.spaceNum.set(spaceNum)
+
+    def LoadThemeCfg(self):
+        ##current theme type radiobutton
+        self.themeIsBuiltin.set(idleConf.GetOption('main','Theme','default',
+            type='bool',default=1))
+        ##currently set theme
+        currentOption=idleConf.CurrentTheme()
+        ##load available theme option menus
+        if self.themeIsBuiltin.get(): #default theme selected
+            itemList=idleConf.GetSectionList('default','highlight')
+            itemList.sort()
+            self.optMenuThemeBuiltin.SetMenu(itemList,currentOption)
+            itemList=idleConf.GetSectionList('user','highlight')
+            itemList.sort()
+            if not itemList:
+                self.radioThemeCustom.config(state=DISABLED)
+                self.customTheme.set('- no custom themes -')
+            else:
+                self.optMenuThemeCustom.SetMenu(itemList,itemList[0])
+        else: #user theme selected
+            itemList=idleConf.GetSectionList('user','highlight')
+            itemList.sort()
+            self.optMenuThemeCustom.SetMenu(itemList,currentOption)
+            itemList=idleConf.GetSectionList('default','highlight')
+            itemList.sort()
+            self.optMenuThemeBuiltin.SetMenu(itemList,itemList[0])
+        self.SetThemeType()
+        ##load theme element option menu
+        themeNames=self.themeElements.keys()
+        themeNames.sort(self.__ThemeNameIndexCompare)
+        self.optMenuHighlightTarget.SetMenu(themeNames,themeNames[0])
+        self.PaintThemeSample()
+        self.SetHighlightTarget()
+
+    def __ThemeNameIndexCompare(self,a,b):
+        if self.themeElements[a][1]<self.themeElements[b][1]: return -1
+        elif self.themeElements[a][1]==self.themeElements[b][1]: return 0
+        else: return 1
+
+    def LoadKeyCfg(self):
+        ##current keys type radiobutton
+        self.keysAreBuiltin.set(idleConf.GetOption('main','Keys','default',
+            type='bool',default=1))
+        ##currently set keys
+        currentOption=idleConf.CurrentKeys()
+        ##load available keyset option menus
+        if self.keysAreBuiltin.get(): #default theme selected
+            itemList=idleConf.GetSectionList('default','keys')
+            itemList.sort()
+            self.optMenuKeysBuiltin.SetMenu(itemList,currentOption)
+            itemList=idleConf.GetSectionList('user','keys')
+            itemList.sort()
+            if not itemList:
+                self.radioKeysCustom.config(state=DISABLED)
+                self.customKeys.set('- no custom keys -')
+            else:
+                self.optMenuKeysCustom.SetMenu(itemList,itemList[0])
+        else: #user key set selected
+            itemList=idleConf.GetSectionList('user','keys')
+            itemList.sort()
+            self.optMenuKeysCustom.SetMenu(itemList,currentOption)
+            itemList=idleConf.GetSectionList('default','keys')
+            itemList.sort()
+            self.optMenuKeysBuiltin.SetMenu(itemList,itemList[0])
+        self.SetKeysType()
+        ##load keyset element list
+        keySetName=idleConf.CurrentKeys()
+        self.LoadKeysList(keySetName)
+
+    def LoadGeneralCfg(self):
+        #startup state
+        self.startupEdit.set(idleConf.GetOption('main','General',
+                'editor-on-startup',default=1,type='bool'))
+        #autosave state
+        self.autoSave.set(idleConf.GetOption('main', 'General', 'autosave',
+                                             default=0, type='bool'))
+        #initial window size
+        self.winWidth.set(idleConf.GetOption('main','EditorWindow','width'))
+        self.winHeight.set(idleConf.GetOption('main','EditorWindow','height'))
+        #initial paragraph reformat size
+        self.paraWidth.set(idleConf.GetOption('main','FormatParagraph','paragraph'))
+        # default source encoding
+        self.encoding.set(idleConf.GetOption('main', 'EditorWindow',
+                                             'encoding', default='none'))
+        # additional help sources
+        self.userHelpList = idleConf.GetAllExtraHelpSourcesList()
+        for helpItem in self.userHelpList:
+            self.listHelp.insert(END,helpItem[0])
+        self.SetHelpListButtonStates()
+
+    def LoadConfigs(self):
+        """
+        load configuration from default and user config files and populate
+        the widgets on the config dialog pages.
+        """
+        ### fonts / tabs page
+        self.LoadFontCfg()
+        self.LoadTabCfg()
+        ### highlighting page
+        self.LoadThemeCfg()
+        ### keys page
+        self.LoadKeyCfg()
+        ### general page
+        self.LoadGeneralCfg()
+
+    def SaveNewKeySet(self,keySetName,keySet):
+        """
+        save a newly created core key set.
+        keySetName - string, the name of the new key set
+        keySet - dictionary containing the new key set
+        """
+        if not idleConf.userCfg['keys'].has_section(keySetName):
+            idleConf.userCfg['keys'].add_section(keySetName)
+        for event in keySet.keys():
+            value=keySet[event]
+            idleConf.userCfg['keys'].SetOption(keySetName,event,value)
+
+    def SaveNewTheme(self,themeName,theme):
+        """
+        save a newly created theme.
+        themeName - string, the name of the new theme
+        theme - dictionary containing the new theme
+        """
+        if not idleConf.userCfg['highlight'].has_section(themeName):
+            idleConf.userCfg['highlight'].add_section(themeName)
+        for element in theme.keys():
+            value=theme[element]
+            idleConf.userCfg['highlight'].SetOption(themeName,element,value)
+
+    def SetUserValue(self,configType,section,item,value):
+        if idleConf.defaultCfg[configType].has_option(section,item):
+            if idleConf.defaultCfg[configType].Get(section,item)==value:
+                #the setting equals a default setting, remove it from user cfg
+                return idleConf.userCfg[configType].RemoveOption(section,item)
+        #if we got here set the option
+        return idleConf.userCfg[configType].SetOption(section,item,value)
+
+    def SaveAllChangedConfigs(self):
+        "Save configuration changes to the user config file."
+        idleConf.userCfg['main'].Save()
+        for configType in self.changedItems.keys():
+            cfgTypeHasChanges = False
+            for section in self.changedItems[configType].keys():
+                if section == 'HelpFiles':
+                    #this section gets completely replaced
+                    idleConf.userCfg['main'].remove_section('HelpFiles')
+                    cfgTypeHasChanges = True
+                for item in self.changedItems[configType][section].keys():
+                    value = self.changedItems[configType][section][item]
+                    if self.SetUserValue(configType,section,item,value):
+                        cfgTypeHasChanges = True
+            if cfgTypeHasChanges:
+                idleConf.userCfg[configType].Save()
+        for configType in ['keys', 'highlight']:
+            # save these even if unchanged!
+            idleConf.userCfg[configType].Save()
+        self.ResetChangedItems() #clear the changed items dict
+
+    def DeactivateCurrentConfig(self):
+        #Before a config is saved, some cleanup of current
+        #config must be done - remove the previous keybindings
+        winInstances=self.parent.instance_dict.keys()
+        for instance in winInstances:
+            instance.RemoveKeybindings()
+
+    def ActivateConfigChanges(self):
+        "Dynamically apply configuration changes"
+        winInstances=self.parent.instance_dict.keys()
+        for instance in winInstances:
+            instance.ResetColorizer()
+            instance.ResetFont()
+            instance.set_notabs_indentwidth()
+            instance.ApplyKeybindings()
+            instance.reset_help_menu_entries()
+
+    def Cancel(self):
+        self.destroy()
+
+    def Ok(self):
+        self.Apply()
+        self.destroy()
+
+    def Apply(self):
+        self.DeactivateCurrentConfig()
+        self.SaveAllChangedConfigs()
+        self.ActivateConfigChanges()
+
+    def Help(self):
+        pass
+
+if __name__ == '__main__':
+    #test the dialog
+    root=Tk()
+    Button(root,text='Dialog',
+            command=lambda:ConfigDialog(root,'Settings')).pack()
+    root.instance_dict={}
+    root.mainloop()

Added: vendor/Python/current/Lib/idlelib/configHandler.py
===================================================================
--- vendor/Python/current/Lib/idlelib/configHandler.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/configHandler.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,696 @@
+"""Provides access to stored IDLE configuration information.
+
+Refer to the comments at the beginning of config-main.def for a description of
+the available configuration files and the design implemented to update user
+configuration information.  In particular, user configuration choices which
+duplicate the defaults will be removed from the user's configuration files,
+and if a file becomes empty, it will be deleted.
+
+The contents of the user files may be altered using the Options/Configure IDLE
+menu to access the configuration GUI (configDialog.py), or manually.
+
+Throughout this module there is an emphasis on returning useable defaults
+when a problem occurs in returning a requested configuration value back to
+idle. This is to allow IDLE to continue to function in spite of errors in
+the retrieval of config information. When a default is returned instead of
+a requested config value, a message is printed to stderr to aid in
+configuration problem notification and resolution.
+
+"""
+import os
+import sys
+import string
+import macosxSupport
+from ConfigParser import ConfigParser, NoOptionError, NoSectionError
+
+class InvalidConfigType(Exception): pass
+class InvalidConfigSet(Exception): pass
+class InvalidFgBg(Exception): pass
+class InvalidTheme(Exception): pass
+
+class IdleConfParser(ConfigParser):
+    """
+    A ConfigParser specialised for idle configuration file handling
+    """
+    def __init__(self, cfgFile, cfgDefaults=None):
+        """
+        cfgFile - string, fully specified configuration file name
+        """
+        self.file=cfgFile
+        ConfigParser.__init__(self,defaults=cfgDefaults)
+
+    def Get(self, section, option, type=None, default=None):
+        """
+        Get an option value for given section/option or return default.
+        If type is specified, return as type.
+        """
+        if type=='bool':
+            getVal=self.getboolean
+        elif type=='int':
+            getVal=self.getint
+        else:
+            getVal=self.get
+        if self.has_option(section,option):
+            #return getVal(section, option, raw, vars, default)
+            return getVal(section, option)
+        else:
+            return default
+
+    def GetOptionList(self,section):
+        """
+        Get an option list for given section
+        """
+        if self.has_section(section):
+            return self.options(section)
+        else:  #return a default value
+            return []
+
+    def Load(self):
+        """
+        Load the configuration file from disk
+        """
+        self.read(self.file)
+
+class IdleUserConfParser(IdleConfParser):
+    """
+    IdleConfigParser specialised for user configuration handling.
+    """
+
+    def AddSection(self,section):
+        """
+        if section doesn't exist, add it
+        """
+        if not self.has_section(section):
+            self.add_section(section)
+
+    def RemoveEmptySections(self):
+        """
+        remove any sections that have no options
+        """
+        for section in self.sections():
+            if not self.GetOptionList(section):
+                self.remove_section(section)
+
+    def IsEmpty(self):
+        """
+        Remove empty sections and then return 1 if parser has no sections
+        left, else return 0.
+        """
+        self.RemoveEmptySections()
+        if self.sections():
+            return 0
+        else:
+            return 1
+
+    def RemoveOption(self,section,option):
+        """
+        If section/option exists, remove it.
+        Returns 1 if option was removed, 0 otherwise.
+        """
+        if self.has_section(section):
+            return self.remove_option(section,option)
+
+    def SetOption(self,section,option,value):
+        """
+        Sets option to value, adding section if required.
+        Returns 1 if option was added or changed, otherwise 0.
+        """
+        if self.has_option(section,option):
+            if self.get(section,option)==value:
+                return 0
+            else:
+                self.set(section,option,value)
+                return 1
+        else:
+            if not self.has_section(section):
+                self.add_section(section)
+            self.set(section,option,value)
+            return 1
+
+    def RemoveFile(self):
+        """
+        Removes the user config file from disk if it exists.
+        """
+        if os.path.exists(self.file):
+            os.remove(self.file)
+
+    def Save(self):
+        """Update user configuration file.
+
+        Remove empty sections. If resulting config isn't empty, write the file
+        to disk. If config is empty, remove the file from disk if it exists.
+
+        """
+        if not self.IsEmpty():
+            cfgFile=open(self.file,'w')
+            self.write(cfgFile)
+        else:
+            self.RemoveFile()
+
+class IdleConf:
+    """
+    holds config parsers for all idle config files:
+    default config files
+        (idle install dir)/config-main.def
+        (idle install dir)/config-extensions.def
+        (idle install dir)/config-highlight.def
+        (idle install dir)/config-keys.def
+    user config  files
+        (user home dir)/.idlerc/config-main.cfg
+        (user home dir)/.idlerc/config-extensions.cfg
+        (user home dir)/.idlerc/config-highlight.cfg
+        (user home dir)/.idlerc/config-keys.cfg
+    """
+    def __init__(self):
+        self.defaultCfg={}
+        self.userCfg={}
+        self.cfg={}
+        self.CreateConfigHandlers()
+        self.LoadCfgFiles()
+        #self.LoadCfg()
+
+    def CreateConfigHandlers(self):
+        """
+        set up a dictionary of config parsers for default and user
+        configurations respectively
+        """
+        #build idle install path
+        if __name__ != '__main__': # we were imported
+            idleDir=os.path.dirname(__file__)
+        else: # we were exec'ed (for testing only)
+            idleDir=os.path.abspath(sys.path[0])
+        userDir=self.GetUserCfgDir()
+        configTypes=('main','extensions','highlight','keys')
+        defCfgFiles={}
+        usrCfgFiles={}
+        for cfgType in configTypes: #build config file names
+            defCfgFiles[cfgType]=os.path.join(idleDir,'config-'+cfgType+'.def')
+            usrCfgFiles[cfgType]=os.path.join(userDir,'config-'+cfgType+'.cfg')
+        for cfgType in configTypes: #create config parsers
+            self.defaultCfg[cfgType]=IdleConfParser(defCfgFiles[cfgType])
+            self.userCfg[cfgType]=IdleUserConfParser(usrCfgFiles[cfgType])
+
+    def GetUserCfgDir(self):
+        """
+        Creates (if required) and returns a filesystem directory for storing
+        user config files.
+
+        """
+        cfgDir = '.idlerc'
+        userDir = os.path.expanduser('~')
+        if userDir != '~': # expanduser() found user home dir
+            if not os.path.exists(userDir):
+                warn = ('\n Warning: os.path.expanduser("~") points to\n '+
+                        userDir+',\n but the path does not exist.\n')
+                sys.stderr.write(warn)
+                userDir = '~'
+        if userDir == "~": # still no path to home!
+            # traditionally IDLE has defaulted to os.getcwd(), is this adequate?
+            userDir = os.getcwd()
+        userDir = os.path.join(userDir, cfgDir)
+        if not os.path.exists(userDir):
+            try:
+                os.mkdir(userDir)
+            except (OSError, IOError):
+                warn = ('\n Warning: unable to create user config directory\n'+
+                        userDir+'\n Check path and permissions.\n Exiting!\n\n')
+                sys.stderr.write(warn)
+                raise SystemExit
+        return userDir
+
+    def GetOption(self, configType, section, option, default=None, type=None,
+                  warn_on_default=True):
+        """
+        Get an option value for given config type and given general
+        configuration section/option or return a default. If type is specified,
+        return as type. Firstly the user configuration is checked, with a
+        fallback to the default configuration, and a final 'catch all'
+        fallback to a useable passed-in default if the option isn't present in
+        either the user or the default configuration.
+        configType must be one of ('main','extensions','highlight','keys')
+        If a default is returned, and warn_on_default is True, a warning is
+        printed to stderr.
+
+        """
+        if self.userCfg[configType].has_option(section,option):
+            return self.userCfg[configType].Get(section, option, type=type)
+        elif self.defaultCfg[configType].has_option(section,option):
+            return self.defaultCfg[configType].Get(section, option, type=type)
+        else: #returning default, print warning
+            if warn_on_default:
+                warning = ('\n Warning: configHandler.py - IdleConf.GetOption -\n'
+                           ' problem retrieving configration option %r\n'
+                           ' from section %r.\n'
+                           ' returning default value: %r\n' %
+                           (option, section, default))
+                sys.stderr.write(warning)
+            return default
+
+    def SetOption(self, configType, section, option, value):
+        """In user's config file, set section's option to value.
+
+        """
+        self.userCfg[configType].SetOption(section, option, value)
+
+    def GetSectionList(self, configSet, configType):
+        """
+        Get a list of sections from either the user or default config for
+        the given config type.
+        configSet must be either 'user' or 'default'
+        configType must be one of ('main','extensions','highlight','keys')
+        """
+        if not (configType in ('main','extensions','highlight','keys')):
+            raise InvalidConfigType, 'Invalid configType specified'
+        if configSet == 'user':
+            cfgParser=self.userCfg[configType]
+        elif configSet == 'default':
+            cfgParser=self.defaultCfg[configType]
+        else:
+            raise InvalidConfigSet, 'Invalid configSet specified'
+        return cfgParser.sections()
+
+    def GetHighlight(self, theme, element, fgBg=None):
+        """
+        return individual highlighting theme elements.
+        fgBg - string ('fg'or'bg') or None, if None return a dictionary
+        containing fg and bg colours (appropriate for passing to Tkinter in,
+        e.g., a tag_config call), otherwise fg or bg colour only as specified.
+        """
+        if self.defaultCfg['highlight'].has_section(theme):
+            themeDict=self.GetThemeDict('default',theme)
+        else:
+            themeDict=self.GetThemeDict('user',theme)
+        fore=themeDict[element+'-foreground']
+        if element=='cursor': #there is no config value for cursor bg
+            back=themeDict['normal-background']
+        else:
+            back=themeDict[element+'-background']
+        highlight={"foreground": fore,"background": back}
+        if not fgBg: #return dict of both colours
+            return highlight
+        else: #return specified colour only
+            if fgBg == 'fg':
+                return highlight["foreground"]
+            if fgBg == 'bg':
+                return highlight["background"]
+            else:
+                raise InvalidFgBg, 'Invalid fgBg specified'
+
+    def GetThemeDict(self,type,themeName):
+        """
+        type - string, 'default' or 'user' theme type
+        themeName - string, theme name
+        Returns a dictionary which holds {option:value} for each element
+        in the specified theme. Values are loaded over a set of ultimate last
+        fallback defaults to guarantee that all theme elements are present in
+        a newly created theme.
+        """
+        if type == 'user':
+            cfgParser=self.userCfg['highlight']
+        elif type == 'default':
+            cfgParser=self.defaultCfg['highlight']
+        else:
+            raise InvalidTheme, 'Invalid theme type specified'
+        #foreground and background values are provded for each theme element
+        #(apart from cursor) even though all these values are not yet used
+        #by idle, to allow for their use in the future. Default values are
+        #generally black and white.
+        theme={ 'normal-foreground':'#000000',
+                'normal-background':'#ffffff',
+                'keyword-foreground':'#000000',
+                'keyword-background':'#ffffff',
+                'builtin-foreground':'#000000',
+                'builtin-background':'#ffffff',
+                'comment-foreground':'#000000',
+                'comment-background':'#ffffff',
+                'string-foreground':'#000000',
+                'string-background':'#ffffff',
+                'definition-foreground':'#000000',
+                'definition-background':'#ffffff',
+                'hilite-foreground':'#000000',
+                'hilite-background':'gray',
+                'break-foreground':'#ffffff',
+                'break-background':'#000000',
+                'hit-foreground':'#ffffff',
+                'hit-background':'#000000',
+                'error-foreground':'#ffffff',
+                'error-background':'#000000',
+                #cursor (only foreground can be set)
+                'cursor-foreground':'#000000',
+                #shell window
+                'stdout-foreground':'#000000',
+                'stdout-background':'#ffffff',
+                'stderr-foreground':'#000000',
+                'stderr-background':'#ffffff',
+                'console-foreground':'#000000',
+                'console-background':'#ffffff' }
+        for element in theme.keys():
+            if not cfgParser.has_option(themeName,element):
+                #we are going to return a default, print warning
+                warning=('\n Warning: configHandler.py - IdleConf.GetThemeDict'
+                           ' -\n problem retrieving theme element %r'
+                           '\n from theme %r.\n'
+                           ' returning default value: %r\n' %
+                           (element, themeName, theme[element]))
+                sys.stderr.write(warning)
+            colour=cfgParser.Get(themeName,element,default=theme[element])
+            theme[element]=colour
+        return theme
+
+    def CurrentTheme(self):
+        """
+        Returns the name of the currently active theme
+        """
+        return self.GetOption('main','Theme','name',default='')
+
+    def CurrentKeys(self):
+        """
+        Returns the name of the currently active key set
+        """
+        return self.GetOption('main','Keys','name',default='')
+
+    def GetExtensions(self, active_only=True, editor_only=False, shell_only=False):
+        """
+        Gets a list of all idle extensions declared in the config files.
+        active_only - boolean, if true only return active (enabled) extensions
+        """
+        extns=self.RemoveKeyBindNames(
+                self.GetSectionList('default','extensions'))
+        userExtns=self.RemoveKeyBindNames(
+                self.GetSectionList('user','extensions'))
+        for extn in userExtns:
+            if extn not in extns: #user has added own extension
+                extns.append(extn)
+        if active_only:
+            activeExtns=[]
+            for extn in extns:
+                if self.GetOption('extensions', extn, 'enable', default=True,
+                                  type='bool'):
+                    #the extension is enabled
+                    if editor_only or shell_only:
+                        if editor_only:
+                            option = "enable_editor"
+                        else:
+                            option = "enable_shell"
+                        if self.GetOption('extensions', extn,option,
+                                          default=True, type='bool',
+                                          warn_on_default=False):
+                            activeExtns.append(extn)
+                    else:
+                        activeExtns.append(extn)
+            return activeExtns
+        else:
+            return extns
+
+    def RemoveKeyBindNames(self,extnNameList):
+        #get rid of keybinding section names
+        names=extnNameList
+        kbNameIndicies=[]
+        for name in names:
+            if name.endswith(('_bindings', '_cfgBindings')):
+                kbNameIndicies.append(names.index(name))
+        kbNameIndicies.sort()
+        kbNameIndicies.reverse()
+        for index in kbNameIndicies: #delete each keybinding section name
+            del(names[index])
+        return names
+
+    def GetExtnNameForEvent(self,virtualEvent):
+        """
+        Returns the name of the extension that virtualEvent is bound in, or
+        None if not bound in any extension.
+        virtualEvent - string, name of the virtual event to test for, without
+                       the enclosing '<< >>'
+        """
+        extName=None
+        vEvent='<<'+virtualEvent+'>>'
+        for extn in self.GetExtensions(active_only=0):
+            for event in self.GetExtensionKeys(extn).keys():
+                if event == vEvent:
+                    extName=extn
+        return extName
+
+    def GetExtensionKeys(self,extensionName):
+        """
+        returns a dictionary of the configurable keybindings for a particular
+        extension,as they exist in the dictionary returned by GetCurrentKeySet;
+        that is, where previously used bindings are disabled.
+        """
+        keysName=extensionName+'_cfgBindings'
+        activeKeys=self.GetCurrentKeySet()
+        extKeys={}
+        if self.defaultCfg['extensions'].has_section(keysName):
+            eventNames=self.defaultCfg['extensions'].GetOptionList(keysName)
+            for eventName in eventNames:
+                event='<<'+eventName+'>>'
+                binding=activeKeys[event]
+                extKeys[event]=binding
+        return extKeys
+
+    def __GetRawExtensionKeys(self,extensionName):
+        """
+        returns a dictionary of the configurable keybindings for a particular
+        extension, as defined in the configuration files, or an empty dictionary
+        if no bindings are found
+        """
+        keysName=extensionName+'_cfgBindings'
+        extKeys={}
+        if self.defaultCfg['extensions'].has_section(keysName):
+            eventNames=self.defaultCfg['extensions'].GetOptionList(keysName)
+            for eventName in eventNames:
+                binding=self.GetOption('extensions',keysName,
+                        eventName,default='').split()
+                event='<<'+eventName+'>>'
+                extKeys[event]=binding
+        return extKeys
+
+    def GetExtensionBindings(self,extensionName):
+        """
+        Returns a dictionary of all the event bindings for a particular
+        extension. The configurable keybindings are returned as they exist in
+        the dictionary returned by GetCurrentKeySet; that is, where re-used
+        keybindings are disabled.
+        """
+        bindsName=extensionName+'_bindings'
+        extBinds=self.GetExtensionKeys(extensionName)
+        #add the non-configurable bindings
+        if self.defaultCfg['extensions'].has_section(bindsName):
+            eventNames=self.defaultCfg['extensions'].GetOptionList(bindsName)
+            for eventName in eventNames:
+                binding=self.GetOption('extensions',bindsName,
+                        eventName,default='').split()
+                event='<<'+eventName+'>>'
+                extBinds[event]=binding
+
+        return extBinds
+
+    def GetKeyBinding(self, keySetName, eventStr):
+        """
+        returns the keybinding for a specific event.
+        keySetName - string, name of key binding set
+        eventStr - string, the virtual event we want the binding for,
+                   represented as a string, eg. '<<event>>'
+        """
+        eventName=eventStr[2:-2] #trim off the angle brackets
+        binding=self.GetOption('keys',keySetName,eventName,default='').split()
+        return binding
+
+    def GetCurrentKeySet(self):
+        result = self.GetKeySet(self.CurrentKeys())
+
+        if macosxSupport.runningAsOSXApp():
+            # We're using AquaTk, replace all keybingings that use the
+            # Alt key by ones that use the Option key because the former
+            # don't work reliably.
+            for k, v in result.items():
+                v2 = [ x.replace('<Alt-', '<Option-') for x in v ]
+                if v != v2:
+                    result[k] = v2
+
+        return result
+
+    def GetKeySet(self,keySetName):
+        """
+        Returns a dictionary of: all requested core keybindings, plus the
+        keybindings for all currently active extensions. If a binding defined
+        in an extension is already in use, that binding is disabled.
+        """
+        keySet=self.GetCoreKeys(keySetName)
+        activeExtns=self.GetExtensions(active_only=1)
+        for extn in activeExtns:
+            extKeys=self.__GetRawExtensionKeys(extn)
+            if extKeys: #the extension defines keybindings
+                for event in extKeys.keys():
+                    if extKeys[event] in keySet.values():
+                        #the binding is already in use
+                        extKeys[event]='' #disable this binding
+                    keySet[event]=extKeys[event] #add binding
+        return keySet
+
+    def IsCoreBinding(self,virtualEvent):
+        """
+        returns true if the virtual event is bound in the core idle keybindings.
+        virtualEvent - string, name of the virtual event to test for, without
+                       the enclosing '<< >>'
+        """
+        return ('<<'+virtualEvent+'>>') in self.GetCoreKeys().keys()
+
+    def GetCoreKeys(self, keySetName=None):
+        """
+        returns the requested set of core keybindings, with fallbacks if
+        required.
+        Keybindings loaded from the config file(s) are loaded _over_ these
+        defaults, so if there is a problem getting any core binding there will
+        be an 'ultimate last resort fallback' to the CUA-ish bindings
+        defined here.
+        """
+        keyBindings={
+            '<<copy>>': ['<Control-c>', '<Control-C>'],
+            '<<cut>>': ['<Control-x>', '<Control-X>'],
+            '<<paste>>': ['<Control-v>', '<Control-V>'],
+            '<<beginning-of-line>>': ['<Control-a>', '<Home>'],
+            '<<center-insert>>': ['<Control-l>'],
+            '<<close-all-windows>>': ['<Control-q>'],
+            '<<close-window>>': ['<Alt-F4>'],
+            '<<do-nothing>>': ['<Control-x>'],
+            '<<end-of-file>>': ['<Control-d>'],
+            '<<python-docs>>': ['<F1>'],
+            '<<python-context-help>>': ['<Shift-F1>'],
+            '<<history-next>>': ['<Alt-n>'],
+            '<<history-previous>>': ['<Alt-p>'],
+            '<<interrupt-execution>>': ['<Control-c>'],
+            '<<view-restart>>': ['<F6>'],
+            '<<restart-shell>>': ['<Control-F6>'],
+            '<<open-class-browser>>': ['<Alt-c>'],
+            '<<open-module>>': ['<Alt-m>'],
+            '<<open-new-window>>': ['<Control-n>'],
+            '<<open-window-from-file>>': ['<Control-o>'],
+            '<<plain-newline-and-indent>>': ['<Control-j>'],
+            '<<print-window>>': ['<Control-p>'],
+            '<<redo>>': ['<Control-y>'],
+            '<<remove-selection>>': ['<Escape>'],
+            '<<save-copy-of-window-as-file>>': ['<Alt-Shift-S>'],
+            '<<save-window-as-file>>': ['<Alt-s>'],
+            '<<save-window>>': ['<Control-s>'],
+            '<<select-all>>': ['<Alt-a>'],
+            '<<toggle-auto-coloring>>': ['<Control-slash>'],
+            '<<undo>>': ['<Control-z>'],
+            '<<find-again>>': ['<Control-g>', '<F3>'],
+            '<<find-in-files>>': ['<Alt-F3>'],
+            '<<find-selection>>': ['<Control-F3>'],
+            '<<find>>': ['<Control-f>'],
+            '<<replace>>': ['<Control-h>'],
+            '<<goto-line>>': ['<Alt-g>'],
+            '<<smart-backspace>>': ['<Key-BackSpace>'],
+            '<<newline-and-indent>>': ['<Key-Return> <Key-KP_Enter>'],
+            '<<smart-indent>>': ['<Key-Tab>'],
+            '<<indent-region>>': ['<Control-Key-bracketright>'],
+            '<<dedent-region>>': ['<Control-Key-bracketleft>'],
+            '<<comment-region>>': ['<Alt-Key-3>'],
+            '<<uncomment-region>>': ['<Alt-Key-4>'],
+            '<<tabify-region>>': ['<Alt-Key-5>'],
+            '<<untabify-region>>': ['<Alt-Key-6>'],
+            '<<toggle-tabs>>': ['<Alt-Key-t>'],
+            '<<change-indentwidth>>': ['<Alt-Key-u>'],
+            '<<del-word-left>>': ['<Control-Key-BackSpace>'],
+            '<<del-word-right>>': ['<Control-Key-Delete>']
+            }
+        if keySetName:
+            for event in keyBindings.keys():
+                binding=self.GetKeyBinding(keySetName,event)
+                if binding:
+                    keyBindings[event]=binding
+                else: #we are going to return a default, print warning
+                    warning=('\n Warning: configHandler.py - IdleConf.GetCoreKeys'
+                               ' -\n problem retrieving key binding for event %r'
+                               '\n from key set %r.\n'
+                               ' returning default value: %r\n' %
+                               (event, keySetName, keyBindings[event]))
+                    sys.stderr.write(warning)
+        return keyBindings
+
+    def GetExtraHelpSourceList(self,configSet):
+        """Fetch list of extra help sources from a given configSet.
+
+        Valid configSets are 'user' or 'default'.  Return a list of tuples of
+        the form (menu_item , path_to_help_file , option), or return the empty
+        list.  'option' is the sequence number of the help resource.  'option'
+        values determine the position of the menu items on the Help menu,
+        therefore the returned list must be sorted by 'option'.
+
+        """
+        helpSources=[]
+        if configSet=='user':
+            cfgParser=self.userCfg['main']
+        elif configSet=='default':
+            cfgParser=self.defaultCfg['main']
+        else:
+            raise InvalidConfigSet, 'Invalid configSet specified'
+        options=cfgParser.GetOptionList('HelpFiles')
+        for option in options:
+            value=cfgParser.Get('HelpFiles',option,default=';')
+            if value.find(';')==-1: #malformed config entry with no ';'
+                menuItem='' #make these empty
+                helpPath='' #so value won't be added to list
+            else: #config entry contains ';' as expected
+                value=string.split(value,';')
+                menuItem=value[0].strip()
+                helpPath=value[1].strip()
+            if menuItem and helpPath: #neither are empty strings
+                helpSources.append( (menuItem,helpPath,option) )
+        helpSources.sort(self.__helpsort)
+        return helpSources
+
+    def __helpsort(self, h1, h2):
+        if int(h1[2]) < int(h2[2]):
+            return -1
+        elif int(h1[2]) > int(h2[2]):
+            return 1
+        else:
+            return 0
+
+    def GetAllExtraHelpSourcesList(self):
+        """
+        Returns a list of tuples containing the details of all additional help
+        sources configured, or an empty list if there are none. Tuples are of
+        the format returned by GetExtraHelpSourceList.
+        """
+        allHelpSources=( self.GetExtraHelpSourceList('default')+
+                self.GetExtraHelpSourceList('user') )
+        return allHelpSources
+
+    def LoadCfgFiles(self):
+        """
+        load all configuration files.
+        """
+        for key in self.defaultCfg.keys():
+            self.defaultCfg[key].Load()
+            self.userCfg[key].Load() #same keys
+
+    def SaveUserCfgFiles(self):
+        """
+        write all loaded user configuration files back to disk
+        """
+        for key in self.userCfg.keys():
+            self.userCfg[key].Save()
+
+idleConf=IdleConf()
+
+### module test
+if __name__ == '__main__':
+    def dumpCfg(cfg):
+        print '\n',cfg,'\n'
+        for key in cfg.keys():
+            sections=cfg[key].sections()
+            print key
+            print sections
+            for section in sections:
+                options=cfg[key].options(section)
+                print section
+                print options
+                for option in options:
+                    print option, '=', cfg[key].Get(section,option)
+    dumpCfg(idleConf.defaultCfg)
+    dumpCfg(idleConf.userCfg)
+    print idleConf.userCfg['main'].Get('Theme','name')
+    #print idleConf.userCfg['highlight'].GetDefHighlight('Foo','normal')

Added: vendor/Python/current/Lib/idlelib/configHelpSourceEdit.py
===================================================================
--- vendor/Python/current/Lib/idlelib/configHelpSourceEdit.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/configHelpSourceEdit.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,169 @@
+"Dialog to specify or edit the parameters for a user configured help source."
+
+import os
+import sys
+
+from Tkinter import *
+import tkMessageBox
+import tkFileDialog
+
+class GetHelpSourceDialog(Toplevel):
+    def __init__(self, parent, title, menuItem='', filePath=''):
+        """Get menu entry and url/ local file location for Additional Help
+
+        User selects a name for the Help resource and provides a web url
+        or a local file as its source.  The user can enter a url or browse
+        for the file.
+
+        """
+        Toplevel.__init__(self, parent)
+        self.configure(borderwidth=5)
+        self.resizable(height=FALSE, width=FALSE)
+        self.title(title)
+        self.transient(parent)
+        self.grab_set()
+        self.protocol("WM_DELETE_WINDOW", self.Cancel)
+        self.parent = parent
+        self.result = None
+        self.CreateWidgets()
+        self.menu.set(menuItem)
+        self.path.set(filePath)
+        self.withdraw() #hide while setting geometry
+        #needs to be done here so that the winfo_reqwidth is valid
+        self.update_idletasks()
+        #centre dialog over parent:
+        self.geometry("+%d+%d" %
+                      ((parent.winfo_rootx() + ((parent.winfo_width()/2)
+                                                -(self.winfo_reqwidth()/2)),
+                        parent.winfo_rooty() + ((parent.winfo_height()/2)
+                                                -(self.winfo_reqheight()/2)))))
+        self.deiconify() #geometry set, unhide
+        self.bind('<Return>', self.Ok)
+        self.wait_window()
+
+    def CreateWidgets(self):
+        self.menu = StringVar(self)
+        self.path = StringVar(self)
+        self.fontSize = StringVar(self)
+        self.frameMain = Frame(self, borderwidth=2, relief=GROOVE)
+        self.frameMain.pack(side=TOP, expand=TRUE, fill=BOTH)
+        labelMenu = Label(self.frameMain, anchor=W, justify=LEFT,
+                          text='Menu Item:')
+        self.entryMenu = Entry(self.frameMain, textvariable=self.menu,
+                               width=30)
+        self.entryMenu.focus_set()
+        labelPath = Label(self.frameMain, anchor=W, justify=LEFT,
+                          text='Help File Path: Enter URL or browse for file')
+        self.entryPath = Entry(self.frameMain, textvariable=self.path,
+                               width=40)
+        self.entryMenu.focus_set()
+        labelMenu.pack(anchor=W, padx=5, pady=3)
+        self.entryMenu.pack(anchor=W, padx=5, pady=3)
+        labelPath.pack(anchor=W, padx=5, pady=3)
+        self.entryPath.pack(anchor=W, padx=5, pady=3)
+        browseButton = Button(self.frameMain, text='Browse', width=8,
+                              command=self.browseFile)
+        browseButton.pack(pady=3)
+        frameButtons = Frame(self)
+        frameButtons.pack(side=BOTTOM, fill=X)
+        self.buttonOk = Button(frameButtons, text='OK',
+                               width=8, default=ACTIVE,  command=self.Ok)
+        self.buttonOk.grid(row=0, column=0, padx=5,pady=5)
+        self.buttonCancel = Button(frameButtons, text='Cancel',
+                                   width=8, command=self.Cancel)
+        self.buttonCancel.grid(row=0, column=1, padx=5, pady=5)
+
+    def browseFile(self):
+        filetypes = [
+            ("HTML Files", "*.htm *.html", "TEXT"),
+            ("PDF Files", "*.pdf", "TEXT"),
+            ("Windows Help Files", "*.chm"),
+            ("Text Files", "*.txt", "TEXT"),
+            ("All Files", "*")]
+        path = self.path.get()
+        if path:
+            dir, base = os.path.split(path)
+        else:
+            base = None
+            if sys.platform[:3] == 'win':
+                dir = os.path.join(os.path.dirname(sys.executable), 'Doc')
+                if not os.path.isdir(dir):
+                    dir = os.getcwd()
+            else:
+                dir = os.getcwd()
+        opendialog = tkFileDialog.Open(parent=self, filetypes=filetypes)
+        file = opendialog.show(initialdir=dir, initialfile=base)
+        if file:
+            self.path.set(file)
+
+    def MenuOk(self):
+        "Simple validity check for a sensible menu item name"
+        menuOk = True
+        menu = self.menu.get()
+        menu.strip()
+        if not menu:
+            tkMessageBox.showerror(title='Menu Item Error',
+                                   message='No menu item specified',
+                                   parent=self)
+            self.entryMenu.focus_set()
+            menuOk = False
+        elif len(menu) > 30:
+            tkMessageBox.showerror(title='Menu Item Error',
+                                   message='Menu item too long:'
+                                           '\nLimit 30 characters.',
+                                   parent=self)
+            self.entryMenu.focus_set()
+            menuOk = False
+        return menuOk
+
+    def PathOk(self):
+        "Simple validity check for menu file path"
+        pathOk = True
+        path = self.path.get()
+        path.strip()
+        if not path: #no path specified
+            tkMessageBox.showerror(title='File Path Error',
+                                   message='No help file path specified.',
+                                   parent=self)
+            self.entryPath.focus_set()
+            pathOk = False
+        elif path.startswith(('www.', 'http')):
+            pass
+        else:
+            if path[:5] == 'file:':
+                path = path[5:]
+            if not os.path.exists(path):
+                tkMessageBox.showerror(title='File Path Error',
+                                       message='Help file path does not exist.',
+                                       parent=self)
+                self.entryPath.focus_set()
+                pathOk = False
+        return pathOk
+
+    def Ok(self, event=None):
+        if self.MenuOk() and self.PathOk():
+            self.result = (self.menu.get().strip(),
+                           self.path.get().strip())
+            if sys.platform == 'darwin':
+                path = self.result[1]
+                if path.startswith(('www', 'file:', 'http:')):
+                    pass
+                else:
+                    # Mac Safari insists on using the URI form for local files
+                    self.result = list(self.result)
+                    self.result[1] = "file://" + path
+            self.destroy()
+
+    def Cancel(self, event=None):
+        self.result = None
+        self.destroy()
+
+if __name__ == '__main__':
+    #test the dialog
+    root = Tk()
+    def run():
+        keySeq = ''
+        dlg = GetHelpSourceDialog(root, 'Get Help Source')
+        print dlg.result
+    Button(root,text='Dialog', command=run).pack()
+    root.mainloop()

Added: vendor/Python/current/Lib/idlelib/configSectionNameDialog.py
===================================================================
--- vendor/Python/current/Lib/idlelib/configSectionNameDialog.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/configSectionNameDialog.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,97 @@
+"""
+Dialog that allows user to specify a new config file section name.
+Used to get new highlight theme and keybinding set names.
+"""
+from Tkinter import *
+import tkMessageBox
+
+class GetCfgSectionNameDialog(Toplevel):
+    def __init__(self,parent,title,message,usedNames):
+        """
+        message - string, informational message to display
+        usedNames - list, list of names already in use for validity check
+        """
+        Toplevel.__init__(self, parent)
+        self.configure(borderwidth=5)
+        self.resizable(height=FALSE,width=FALSE)
+        self.title(title)
+        self.transient(parent)
+        self.grab_set()
+        self.protocol("WM_DELETE_WINDOW", self.Cancel)
+        self.parent = parent
+        self.message=message
+        self.usedNames=usedNames
+        self.result=''
+        self.CreateWidgets()
+        self.withdraw() #hide while setting geometry
+        self.update_idletasks()
+        #needs to be done here so that the winfo_reqwidth is valid
+        self.messageInfo.config(width=self.frameMain.winfo_reqwidth())
+        self.geometry("+%d+%d" %
+            ((parent.winfo_rootx()+((parent.winfo_width()/2)
+                -(self.winfo_reqwidth()/2)),
+              parent.winfo_rooty()+((parent.winfo_height()/2)
+                -(self.winfo_reqheight()/2)) )) ) #centre dialog over parent
+        self.deiconify() #geometry set, unhide
+        self.wait_window()
+
+    def CreateWidgets(self):
+        self.name=StringVar(self)
+        self.fontSize=StringVar(self)
+        self.frameMain = Frame(self,borderwidth=2,relief=SUNKEN)
+        self.frameMain.pack(side=TOP,expand=TRUE,fill=BOTH)
+        self.messageInfo=Message(self.frameMain,anchor=W,justify=LEFT,padx=5,pady=5,
+                text=self.message)#,aspect=200)
+        entryName=Entry(self.frameMain,textvariable=self.name,width=30)
+        entryName.focus_set()
+        self.messageInfo.pack(padx=5,pady=5)#,expand=TRUE,fill=BOTH)
+        entryName.pack(padx=5,pady=5)
+        frameButtons=Frame(self)
+        frameButtons.pack(side=BOTTOM,fill=X)
+        self.buttonOk = Button(frameButtons,text='Ok',
+                width=8,command=self.Ok)
+        self.buttonOk.grid(row=0,column=0,padx=5,pady=5)
+        self.buttonCancel = Button(frameButtons,text='Cancel',
+                width=8,command=self.Cancel)
+        self.buttonCancel.grid(row=0,column=1,padx=5,pady=5)
+
+    def NameOk(self):
+        #simple validity check for a sensible
+        #ConfigParser file section name
+        nameOk=1
+        name=self.name.get()
+        name.strip()
+        if not name: #no name specified
+            tkMessageBox.showerror(title='Name Error',
+                    message='No name specified.', parent=self)
+            nameOk=0
+        elif len(name)>30: #name too long
+            tkMessageBox.showerror(title='Name Error',
+                    message='Name too long. It should be no more than '+
+                    '30 characters.', parent=self)
+            nameOk=0
+        elif name in self.usedNames:
+            tkMessageBox.showerror(title='Name Error',
+                    message='This name is already in use.', parent=self)
+            nameOk=0
+        return nameOk
+
+    def Ok(self, event=None):
+        if self.NameOk():
+            self.result=self.name.get().strip()
+            self.destroy()
+
+    def Cancel(self, event=None):
+        self.result=''
+        self.destroy()
+
+if __name__ == '__main__':
+    #test the dialog
+    root=Tk()
+    def run():
+        keySeq=''
+        dlg=GetCfgSectionNameDialog(root,'Get Name',
+                'The information here should need to be word wrapped. Test.')
+        print dlg.result
+    Button(root,text='Dialog',command=run).pack()
+    root.mainloop()

Added: vendor/Python/current/Lib/idlelib/dynOptionMenuWidget.py
===================================================================
--- vendor/Python/current/Lib/idlelib/dynOptionMenuWidget.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/dynOptionMenuWidget.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,35 @@
+"""
+OptionMenu widget modified to allow dynamic menu reconfiguration
+and setting of highlightthickness
+"""
+from Tkinter import OptionMenu
+from Tkinter import _setit
+import copy
+
+class DynOptionMenu(OptionMenu):
+    """
+    unlike OptionMenu, our kwargs can include highlightthickness
+    """
+    def __init__(self, master, variable, value, *values, **kwargs):
+        #get a copy of kwargs before OptionMenu.__init__ munges them
+        kwargsCopy=copy.copy(kwargs)
+        if 'highlightthickness' in kwargs.keys():
+            del(kwargs['highlightthickness'])
+        OptionMenu.__init__(self, master, variable, value, *values, **kwargs)
+        self.config(highlightthickness=kwargsCopy.get('highlightthickness'))
+        #self.menu=self['menu']
+        self.variable=variable
+        self.command=kwargs.get('command')
+
+    def SetMenu(self,valueList,value=None):
+        """
+        clear and reload the menu with a new set of options.
+        valueList - list of new options
+        value - initial value to set the optionmenu's menubutton to
+        """
+        self['menu'].delete(0,'end')
+        for item in valueList:
+            self['menu'].add_command(label=item,
+                    command=_setit(self.variable,item,self.command))
+        if value:
+            self.variable.set(value)

Added: vendor/Python/current/Lib/idlelib/extend.txt
===================================================================
--- vendor/Python/current/Lib/idlelib/extend.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/extend.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,83 @@
+Writing an IDLE extension
+=========================
+
+An IDLE extension can define new key bindings and menu entries for IDLE
+edit windows.  There is a simple mechanism to load extensions when IDLE
+starts up and to attach them to each edit window. (It is also possible
+to make other changes to IDLE, but this must be done by editing the IDLE
+source code.)
+
+The list of extensions loaded at startup time is configured by editing
+the file config-extensions.def.  See below for details.
+
+An IDLE extension is defined by a class.  Methods of the class define
+actions that are invoked by event bindings or menu entries. Class (or
+instance) variables define the bindings and menu additions; these are
+automatically applied by IDLE when the extension is linked to an edit
+window.
+
+An IDLE extension class is instantiated with a single argument,
+`editwin', an EditorWindow instance. The extension cannot assume much
+about this argument, but it is guarateed to have the following instance
+variables:
+
+    text	a Text instance (a widget)
+    io		an IOBinding instance (more about this later)
+    flist	the FileList instance (shared by all edit windows)
+
+(There are a few more, but they are rarely useful.)
+
+The extension class must not directly bind Window Manager (e.g. X) events.
+Rather, it must define one or more virtual events, e.g. <<zoom-height>>, and
+corresponding methods, e.g. zoom_height_event().  The virtual events will be
+bound to the corresponding methods, and Window Manager events can then be bound
+to the virtual events. (This indirection is done so that the key bindings can
+easily be changed, and so that other sources of virtual events can exist, such
+as menu entries.)
+
+An extension can define menu entries.  This is done with a class or instance
+variable named menudefs; it should be a list of pairs, where each pair is a
+menu name (lowercase) and a list of menu entries. Each menu entry is either
+None (to insert a separator entry) or a pair of strings (menu_label,
+virtual_event).  Here, menu_label is the label of the menu entry, and
+virtual_event is the virtual event to be generated when the entry is selected.
+An underscore in the menu label is removed; the character following the
+underscore is displayed underlined, to indicate the shortcut character (for
+Windows).
+
+At the moment, extensions cannot define whole new menus; they must define
+entries in existing menus.  Some menus are not present on some windows; such
+entry definitions are then ignored, but key bindings are still applied.  (This
+should probably be refined in the future.)
+
+Extensions are not required to define menu entries for all the events they
+implement.  (They are also not required to create keybindings, but in that
+case there must be empty bindings in cofig-extensions.def)
+
+Here is a complete example example:
+
+class ZoomHeight:
+
+    menudefs = [
+        ('edit', [
+            None, # Separator
+            ('_Zoom Height', '<<zoom-height>>'),
+         ])
+    ]
+
+    def __init__(self, editwin):
+        self.editwin = editwin
+
+    def zoom_height_event(self, event):
+        "...Do what you want here..."
+
+The final piece of the puzzle is the file "config-extensions.def", which is
+used to to configure the loading of extensions and to establish key (or, more
+generally, event) bindings to the virtual events defined in the extensions.
+
+See the comments at the top of config-extensions.def for information.  It's
+currently necessary to manually modify that file to change IDLE's extension
+loading or extension key bindings.
+
+For further information on binding refer to the Tkinter Resources web page at
+python.org and to the Tk Command "bind" man page.

Added: vendor/Python/current/Lib/idlelib/help.txt
===================================================================
--- vendor/Python/current/Lib/idlelib/help.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/help.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,213 @@
+[See the end of this file for ** TIPS ** on using IDLE !!]
+
+Click on the dotted line at the top of a menu to "tear it off": a
+separate window containing the menu is created.
+
+File Menu:
+
+	New Window       -- Create a new editing window
+	Open...          -- Open an existing file
+	Recent Files...  -- Open a list of recent files
+	Open Module...   -- Open an existing module (searches sys.path)
+	Class Browser    -- Show classes and methods in current file
+	Path Browser     -- Show sys.path directories, modules, classes
+                            and methods
+	---
+	Save             -- Save current window to the associated file (unsaved
+		            windows have a * before and after the window title)
+
+	Save As...       -- Save current window to new file, which becomes
+		            the associated file
+	Save Copy As...  -- Save current window to different file
+		            without changing the associated file
+	---
+	Print Window     -- Print the current window
+	---
+	Close            -- Close current window (asks to save if unsaved)
+	Exit             -- Close all windows, quit (asks to save if unsaved)
+
+Edit Menu:
+
+	Undo             -- Undo last change to current window
+                            (A maximum of 1000 changes may be undone)
+	Redo             -- Redo last undone change to current window
+	---
+	Cut              -- Copy a selection into system-wide clipboard,
+                            then delete the selection
+	Copy             -- Copy selection into system-wide clipboard
+	Paste            -- Insert system-wide clipboard into window
+	Select All       -- Select the entire contents of the edit buffer
+	---
+	Find...          -- Open a search dialog box with many options
+	Find Again       -- Repeat last search
+	Find Selection   -- Search for the string in the selection
+	Find in Files... -- Open a search dialog box for searching files
+	Replace...       -- Open a search-and-replace dialog box
+	Go to Line       -- Ask for a line number and show that line
+	Expand Word      -- Expand the word you have typed to match another
+		            word in the same buffer; repeat to get a
+                            different expansion
+
+Format Menu (only in Edit window):
+
+	Indent Region       -- Shift selected lines right 4 spaces
+	Dedent Region       -- Shift selected lines left 4 spaces
+	Comment Out Region  -- Insert ## in front of selected lines
+	Uncomment Region    -- Remove leading # or ## from selected lines
+	Tabify Region       -- Turns *leading* stretches of spaces into tabs
+		(Note: We recommend using 4 space blocks to indent Python code.)
+	Untabify Region     -- Turn *all* tabs into the right number of spaces
+	New Indent Width... -- Open dialog to change indent width
+	Format Paragraph    -- Reformat the current blank-line-separated
+                               paragraph
+
+Run Menu (only in Edit window):
+
+	Python Shell -- Open or wake up the Python shell window
+	---
+	Check Module -- Run a syntax check on the module
+	Run Module   -- Execute the current file in the __main__ namespace
+
+Shell Menu (only in Shell window):
+
+	View Last Restart -- Scroll the shell window to the last restart
+	Restart Shell     -- Restart the interpreter with a fresh environment
+
+Debug Menu (only in Shell window):
+
+	Go to File/Line   -- look around the insert point for a filename
+		             and linenumber, open the file, and show the line
+	Debugger (toggle) -- Run commands in the shell under the debugger
+	Stack Viewer      -- Show the stack traceback of the last exception
+	Auto-open Stack Viewer (toggle) -- Open stack viewer on traceback
+
+Options Menu:
+
+	Configure IDLE -- Open a configuration dialog.  Fonts, indentation,
+                          keybindings, and color themes may be altered.
+                          Startup Preferences may be set, and Additional Help
+                          Souces can be specified.
+	---
+	Code Context --	  Open a pane at the top of the edit window which
+			  shows the block context of the section of code
+			  which is scrolling off the top or the window.
+
+Windows Menu:
+
+	Zoom Height -- toggles the window between configured size
+	and maximum height.
+	---
+	The rest of this menu lists the names of all open windows;
+	select one to bring it to the foreground (deiconifying it if
+	necessary).
+
+Help Menu:
+
+	About IDLE  -- Version, copyright, license, credits
+	IDLE Readme -- Background discussion and change details
+	---
+	IDLE Help   -- Display this file
+	Python Docs -- Access local Python documentation, if
+		       installed.  Otherwise, access www.python.org.
+	---
+	(Additional Help Sources may be added here)
+
+
+** TIPS **
+==========
+
+Additional Help Sources:
+
+	Windows users can Google on zopeshelf.chm to access Zope help files in
+	the Windows help format.  The Additional Help Sources feature of the
+	configuration GUI supports .chm, along with any other filetypes
+	supported by your browser.  Supply a Menu Item title, and enter the
+	location in the Help File Path slot of the New Help Source dialog.  Use
+	http:// and/or www. to identify external URLs, or download the file and
+	browse for its path on your machine using the Browse button.
+
+	All users can access the extensive sources of help, including
+	tutorials, available at www.python.org/doc.  Selected URLs can be added
+	or removed from the Help menu at any time using Configure IDLE.
+
+Basic editing and navigation:
+
+	Backspace deletes char to the left; DEL deletes char to the right.
+	Control-backspace deletes word left, Control-DEL deletes word right.
+	Arrow keys and Page Up/Down move around.
+	Control-left/right Arrow moves by words in a strange but useful way.
+	Home/End go to begin/end of line.
+	Control-Home/End go to begin/end of file.
+	Some useful Emacs bindings (Control-a, Control-e, Control-k, etc.)
+		are inherited from Tcl/Tk.
+	Standard Windows bindings may work on that platform.
+	Keybindings are selected in the Settings Dialog, look there.
+
+Automatic indentation:
+
+	After a block-opening statement, the next line is indented by 4 spaces
+	(in the Python Shell window by one tab).  After certain keywords
+	(break, return etc.) the next line is dedented.  In leading
+	indentation, Backspace deletes up to 4 spaces if they are there.  Tab
+	inserts spaces (in the Python Shell window one tab), number depends on
+	Indent Width.  (N.B. Currently tabs are restricted to four spaces due
+	to Tcl/Tk issues.)
+
+        See also the indent/dedent region commands in the edit menu.
+
+Python Shell window:
+
+	Control-c interrupts executing command.
+	Control-d sends end-of-file; closes window if typed at >>> prompt
+		(this is Control-z on Windows).
+
+    Command history:
+
+	Alt-p retrieves previous command matching what you have typed.
+	Alt-n retrieves next.
+	      (These are Control-p, Control-n on the Mac)      
+	Return while cursor is on a previous command retrieves that command.
+	Expand word is also useful to reduce typing.
+
+    Syntax colors:
+
+	The coloring is applied in a background "thread", so you may
+	occasionally see uncolorized text.  To change the color
+	scheme, use the Configure IDLE / Highlighting dialog.
+
+    Python default syntax colors:
+
+	Keywords	orange
+	Builtins	royal purple
+	Strings		green
+	Comments	red
+	Definitions	blue
+
+    Shell default colors:
+
+	Console output	brown
+	stdout		blue
+	stderr		red
+	stdin		black
+
+Other preferences:
+
+	The font preferences, keybinding, and startup preferences can
+	be changed using the Settings dialog.
+
+Command line usage:
+	
+	Enter idle -h at the command prompt to get a usage message.
+
+Running without a subprocess:
+
+	If IDLE is started with the -n command line switch it will run in a
+	single process and will not create the subprocess which runs the RPC
+	Python execution server.  This can be useful if Python cannot create
+	the subprocess or the RPC socket interface on your platform.  However,
+	in this mode user code is not isolated from IDLE itself.  Also, the
+	environment is not restarted when Run/Run Module (F5) is selected.  If
+	your code has been modified, you must reload() the affected modules and
+	re-import any specific items (e.g. from foo import baz) if the changes
+	are to take effect.  For these reasons, it is preferable to run IDLE
+	with the default subprocess if at all possible.

Added: vendor/Python/current/Lib/idlelib/idle.bat
===================================================================
--- vendor/Python/current/Lib/idlelib/idle.bat	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/idle.bat	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,3 @@
+ at echo off
+rem Working IDLE bat for Windows - uses start instead of absolute pathname
+start idle.pyw %1 %2 %3 %4 %5 %6 %7 %8 %9


Property changes on: vendor/Python/current/Lib/idlelib/idle.bat
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/idlelib/idle.py
===================================================================
--- vendor/Python/current/Lib/idlelib/idle.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/idle.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,21 @@
+try:
+    import idlelib.PyShell
+except ImportError:
+    # IDLE is not installed, but maybe PyShell is on sys.path:
+    try:
+        import PyShell
+    except ImportError:
+        raise
+    else:
+        import os
+        idledir = os.path.dirname(os.path.abspath(PyShell.__file__))
+        if idledir != os.getcwd():
+            # We're not in the IDLE directory, help the subprocess find run.py
+            pypath = os.environ.get('PYTHONPATH', '')
+            if pypath:
+                os.environ['PYTHONPATH'] = pypath + ':' + idledir
+            else:
+                os.environ['PYTHONPATH'] = idledir
+        PyShell.main()
+else:
+    idlelib.PyShell.main()

Added: vendor/Python/current/Lib/idlelib/idle.pyw
===================================================================
--- vendor/Python/current/Lib/idlelib/idle.pyw	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/idle.pyw	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,21 @@
+try:
+    import idlelib.PyShell
+except ImportError:
+    # IDLE is not installed, but maybe PyShell is on sys.path:
+    try:
+        import PyShell
+    except ImportError:
+        raise
+    else:
+        import os
+        idledir = os.path.dirname(os.path.abspath(PyShell.__file__))
+        if idledir != os.getcwd():
+            # We're not in the IDLE directory, help the subprocess find run.py
+            pypath = os.environ.get('PYTHONPATH', '')
+            if pypath:
+                os.environ['PYTHONPATH'] = pypath + ':' + idledir
+            else:
+                os.environ['PYTHONPATH'] = idledir
+        PyShell.main()
+else:
+    idlelib.PyShell.main()

Added: vendor/Python/current/Lib/idlelib/idlever.py
===================================================================
--- vendor/Python/current/Lib/idlelib/idlever.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/idlever.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1 @@
+IDLE_VERSION = "1.2.1"

Added: vendor/Python/current/Lib/idlelib/keybindingDialog.py
===================================================================
--- vendor/Python/current/Lib/idlelib/keybindingDialog.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/keybindingDialog.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,268 @@
+"""
+Dialog for building Tkinter accelerator key bindings
+"""
+from Tkinter import *
+import tkMessageBox
+import string, os
+
+class GetKeysDialog(Toplevel):
+    def __init__(self,parent,title,action,currentKeySequences):
+        """
+        action - string, the name of the virtual event these keys will be
+                 mapped to
+        currentKeys - list, a list of all key sequence lists currently mapped
+                 to virtual events, for overlap checking
+        """
+        Toplevel.__init__(self, parent)
+        self.configure(borderwidth=5)
+        self.resizable(height=FALSE,width=FALSE)
+        self.title(title)
+        self.transient(parent)
+        self.grab_set()
+        self.protocol("WM_DELETE_WINDOW", self.Cancel)
+        self.parent = parent
+        self.action=action
+        self.currentKeySequences=currentKeySequences
+        self.result=''
+        self.keyString=StringVar(self)
+        self.keyString.set('')
+        self.SetModifiersForPlatform() # set self.modifiers, self.modifier_label
+        self.modifier_vars = []
+        for modifier in self.modifiers:
+            variable = StringVar(self)
+            variable.set('')
+            self.modifier_vars.append(variable)
+        self.advanced = False
+        self.CreateWidgets()
+        self.LoadFinalKeyList()
+        self.withdraw() #hide while setting geometry
+        self.update_idletasks()
+        self.geometry("+%d+%d" %
+            ((parent.winfo_rootx()+((parent.winfo_width()/2)
+                -(self.winfo_reqwidth()/2)),
+              parent.winfo_rooty()+((parent.winfo_height()/2)
+                -(self.winfo_reqheight()/2)) )) ) #centre dialog over parent
+        self.deiconify() #geometry set, unhide
+        self.wait_window()
+
+    def CreateWidgets(self):
+        frameMain = Frame(self,borderwidth=2,relief=SUNKEN)
+        frameMain.pack(side=TOP,expand=TRUE,fill=BOTH)
+        frameButtons=Frame(self)
+        frameButtons.pack(side=BOTTOM,fill=X)
+        self.buttonOK = Button(frameButtons,text='OK',
+                width=8,command=self.OK)
+        self.buttonOK.grid(row=0,column=0,padx=5,pady=5)
+        self.buttonCancel = Button(frameButtons,text='Cancel',
+                width=8,command=self.Cancel)
+        self.buttonCancel.grid(row=0,column=1,padx=5,pady=5)
+        self.frameKeySeqBasic = Frame(frameMain)
+        self.frameKeySeqAdvanced = Frame(frameMain)
+        self.frameControlsBasic = Frame(frameMain)
+        self.frameHelpAdvanced = Frame(frameMain)
+        self.frameKeySeqAdvanced.grid(row=0,column=0,sticky=NSEW,padx=5,pady=5)
+        self.frameKeySeqBasic.grid(row=0,column=0,sticky=NSEW,padx=5,pady=5)
+        self.frameKeySeqBasic.lift()
+        self.frameHelpAdvanced.grid(row=1,column=0,sticky=NSEW,padx=5)
+        self.frameControlsBasic.grid(row=1,column=0,sticky=NSEW,padx=5)
+        self.frameControlsBasic.lift()
+        self.buttonLevel = Button(frameMain,command=self.ToggleLevel,
+                text='Advanced Key Binding Entry >>')
+        self.buttonLevel.grid(row=2,column=0,stick=EW,padx=5,pady=5)
+        labelTitleBasic = Label(self.frameKeySeqBasic,
+                text="New keys for  '"+self.action+"' :")
+        labelTitleBasic.pack(anchor=W)
+        labelKeysBasic = Label(self.frameKeySeqBasic,justify=LEFT,
+                textvariable=self.keyString,relief=GROOVE,borderwidth=2)
+        labelKeysBasic.pack(ipadx=5,ipady=5,fill=X)
+        self.modifier_checkbuttons = {}
+        column = 0
+        for modifier, variable in zip(self.modifiers, self.modifier_vars):
+            label = self.modifier_label.get(modifier, modifier)
+            check=Checkbutton(self.frameControlsBasic,
+                command=self.BuildKeyString,
+                text=label,variable=variable,onvalue=modifier,offvalue='')
+            check.grid(row=0,column=column,padx=2,sticky=W)
+            self.modifier_checkbuttons[modifier] = check
+            column += 1
+        labelFnAdvice=Label(self.frameControlsBasic,justify=LEFT,
+                            text=\
+                            "Select the desired modifier keys\n"+
+                            "above, and the final key from the\n"+
+                            "list on the right.\n\n" +
+                            "Use upper case Symbols when using\n" +
+                            "the Shift modifier.  (Letters will be\n" +
+                            "converted automatically.)")
+        labelFnAdvice.grid(row=1,column=0,columnspan=4,padx=2,sticky=W)
+        self.listKeysFinal=Listbox(self.frameControlsBasic,width=15,height=10,
+                selectmode=SINGLE)
+        self.listKeysFinal.bind('<ButtonRelease-1>',self.FinalKeySelected)
+        self.listKeysFinal.grid(row=0,column=4,rowspan=4,sticky=NS)
+        scrollKeysFinal=Scrollbar(self.frameControlsBasic,orient=VERTICAL,
+                command=self.listKeysFinal.yview)
+        self.listKeysFinal.config(yscrollcommand=scrollKeysFinal.set)
+        scrollKeysFinal.grid(row=0,column=5,rowspan=4,sticky=NS)
+        self.buttonClear=Button(self.frameControlsBasic,
+                text='Clear Keys',command=self.ClearKeySeq)
+        self.buttonClear.grid(row=2,column=0,columnspan=4)
+        labelTitleAdvanced = Label(self.frameKeySeqAdvanced,justify=LEFT,
+                text="Enter new binding(s) for  '"+self.action+"' :\n"+
+                "(These bindings will not be checked for validity!)")
+        labelTitleAdvanced.pack(anchor=W)
+        self.entryKeysAdvanced=Entry(self.frameKeySeqAdvanced,
+                textvariable=self.keyString)
+        self.entryKeysAdvanced.pack(fill=X)
+        labelHelpAdvanced=Label(self.frameHelpAdvanced,justify=LEFT,
+            text="Key bindings are specified using Tkinter keysyms as\n"+
+                 "in these samples: <Control-f>, <Shift-F2>, <F12>,\n"
+                 "<Control-space>, <Meta-less>, <Control-Alt-Shift-X>.\n"
+                 "Upper case is used when the Shift modifier is present!\n\n" +
+                 "'Emacs style' multi-keystroke bindings are specified as\n" +
+                 "follows: <Control-x><Control-y>, where the first key\n" +
+                 "is the 'do-nothing' keybinding.\n\n" +
+                 "Multiple separate bindings for one action should be\n"+
+                 "separated by a space, eg., <Alt-v> <Meta-v>." )
+        labelHelpAdvanced.grid(row=0,column=0,sticky=NSEW)
+
+    def SetModifiersForPlatform(self):
+        """Determine list of names of key modifiers for this platform.
+
+        The names are used to build Tk bindings -- it doesn't matter if the
+        keyboard has these keys, it matters if Tk understands them. The
+        order is also important: key binding equality depends on it, so
+        config-keys.def must use the same ordering.
+        """
+        import sys
+        if sys.platform == 'darwin' and sys.argv[0].count('.app'):
+            self.modifiers = ['Shift', 'Control', 'Option', 'Command']
+        else:
+            self.modifiers = ['Control', 'Alt', 'Shift']
+        self.modifier_label = {'Control': 'Ctrl'} # short name
+
+    def ToggleLevel(self):
+        if  self.buttonLevel.cget('text')[:8]=='Advanced':
+            self.ClearKeySeq()
+            self.buttonLevel.config(text='<< Basic Key Binding Entry')
+            self.frameKeySeqAdvanced.lift()
+            self.frameHelpAdvanced.lift()
+            self.entryKeysAdvanced.focus_set()
+            self.advanced = True
+        else:
+            self.ClearKeySeq()
+            self.buttonLevel.config(text='Advanced Key Binding Entry >>')
+            self.frameKeySeqBasic.lift()
+            self.frameControlsBasic.lift()
+            self.advanced = False
+
+    def FinalKeySelected(self,event):
+        self.BuildKeyString()
+
+    def BuildKeyString(self):
+        keyList = modifiers = self.GetModifiers()
+        finalKey = self.listKeysFinal.get(ANCHOR)
+        if finalKey:
+            finalKey = self.TranslateKey(finalKey, modifiers)
+            keyList.append(finalKey)
+        self.keyString.set('<' + string.join(keyList,'-') + '>')
+
+    def GetModifiers(self):
+        modList = [variable.get() for variable in self.modifier_vars]
+        return filter(None, modList)
+
+    def ClearKeySeq(self):
+        self.listKeysFinal.select_clear(0,END)
+        self.listKeysFinal.yview(MOVETO, '0.0')
+        for variable in self.modifier_vars:
+            variable.set('')
+        self.keyString.set('')
+
+    def LoadFinalKeyList(self):
+        #these tuples are also available for use in validity checks
+        self.functionKeys=('F1','F2','F2','F4','F5','F6','F7','F8','F9',
+                'F10','F11','F12')
+        self.alphanumKeys=tuple(string.ascii_lowercase+string.digits)
+        self.punctuationKeys=tuple('~!@#%^&*()_-+={}[]|;:,.<>/?')
+        self.whitespaceKeys=('Tab','Space','Return')
+        self.editKeys=('BackSpace','Delete','Insert')
+        self.moveKeys=('Home','End','Page Up','Page Down','Left Arrow',
+                'Right Arrow','Up Arrow','Down Arrow')
+        #make a tuple of most of the useful common 'final' keys
+        keys=(self.alphanumKeys+self.punctuationKeys+self.functionKeys+
+                self.whitespaceKeys+self.editKeys+self.moveKeys)
+        self.listKeysFinal.insert(END, *keys)
+
+    def TranslateKey(self, key, modifiers):
+        "Translate from keycap symbol to the Tkinter keysym"
+        translateDict = {'Space':'space',
+                '~':'asciitilde','!':'exclam','@':'at','#':'numbersign',
+                '%':'percent','^':'asciicircum','&':'ampersand','*':'asterisk',
+                '(':'parenleft',')':'parenright','_':'underscore','-':'minus',
+                '+':'plus','=':'equal','{':'braceleft','}':'braceright',
+                '[':'bracketleft',']':'bracketright','|':'bar',';':'semicolon',
+                ':':'colon',',':'comma','.':'period','<':'less','>':'greater',
+                '/':'slash','?':'question','Page Up':'Prior','Page Down':'Next',
+                'Left Arrow':'Left','Right Arrow':'Right','Up Arrow':'Up',
+                'Down Arrow': 'Down', 'Tab':'Tab'}
+        if key in translateDict.keys():
+            key = translateDict[key]
+        if 'Shift' in modifiers and key in string.ascii_lowercase:
+            key = key.upper()
+        key = 'Key-' + key
+        return key
+
+    def OK(self, event=None):
+        if self.advanced or self.KeysOK():  # doesn't check advanced string yet
+            self.result=self.keyString.get()
+            self.destroy()
+
+    def Cancel(self, event=None):
+        self.result=''
+        self.destroy()
+
+    def KeysOK(self):
+        '''Validity check on user's 'basic' keybinding selection.
+
+        Doesn't check the string produced by the advanced dialog because
+        'modifiers' isn't set.
+
+        '''
+        keys = self.keyString.get()
+        keys.strip()
+        finalKey = self.listKeysFinal.get(ANCHOR)
+        modifiers = self.GetModifiers()
+        # create a key sequence list for overlap check:
+        keySequence = keys.split()
+        keysOK = False
+        title = 'Key Sequence Error'
+        if not keys:
+            tkMessageBox.showerror(title=title, parent=self,
+                                   message='No keys specified.')
+        elif not keys.endswith('>'):
+            tkMessageBox.showerror(title=title, parent=self,
+                                   message='Missing the final Key')
+        elif (not modifiers
+              and finalKey not in self.functionKeys + self.moveKeys):
+            tkMessageBox.showerror(title=title, parent=self,
+                                   message='No modifier key(s) specified.')
+        elif (modifiers == ['Shift']) \
+                 and (finalKey not in
+                      self.functionKeys + self.moveKeys + ('Tab', 'Space')):
+            msg = 'The shift modifier by itself may not be used with'\
+                  ' this key symbol.'
+            tkMessageBox.showerror(title=title, parent=self, message=msg)
+        elif keySequence in self.currentKeySequences:
+            msg = 'This key combination is already in use.'
+            tkMessageBox.showerror(title=title, parent=self, message=msg)
+        else:
+            keysOK = True
+        return keysOK
+
+if __name__ == '__main__':
+    #test the dialog
+    root=Tk()
+    def run():
+        keySeq=''
+        dlg=GetKeysDialog(root,'Get Keys','find-again',[])
+        print dlg.result
+    Button(root,text='Dialog',command=run).pack()
+    root.mainloop()

Added: vendor/Python/current/Lib/idlelib/macosxSupport.py
===================================================================
--- vendor/Python/current/Lib/idlelib/macosxSupport.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/macosxSupport.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,112 @@
+"""
+A number of function that enhance IDLE on MacOSX when it used as a normal
+GUI application (as opposed to an X11 application).
+"""
+import sys
+
+def runningAsOSXApp():
+    """ Returns True iff running from the IDLE.app bundle on OSX """
+    return (sys.platform == 'darwin' and 'IDLE.app' in sys.argv[0])
+
+def addOpenEventSupport(root, flist):
+    """
+    This ensures that the application will respont to open AppleEvents, which
+    makes is feaseable to use IDLE as the default application for python files.
+    """
+    def doOpenFile(*args):
+        for fn in args:
+            flist.open(fn)
+
+    # The command below is a hook in aquatk that is called whenever the app
+    # receives a file open event. The callback can have multiple arguments,
+    # one for every file that should be opened.
+    root.createcommand("::tk::mac::OpenDocument", doOpenFile)
+
+def hideTkConsole(root):
+    root.tk.call('console', 'hide')
+
+def overrideRootMenu(root, flist):
+    """
+    Replace the Tk root menu by something that's more appropriate for
+    IDLE.
+    """
+    # The menu that is attached to the Tk root (".") is also used by AquaTk for
+    # all windows that don't specify a menu of their own. The default menubar
+    # contains a number of menus, none of which are appropriate for IDLE. The
+    # Most annoying of those is an 'About Tck/Tk...' menu in the application
+    # menu.
+    #
+    # This function replaces the default menubar by a mostly empty one, it
+    # should only contain the correct application menu and the window menu.
+    #
+    # Due to a (mis-)feature of TkAqua the user will also see an empty Help
+    # menu.
+    from Tkinter import Menu, Text, Text
+    from EditorWindow import prepstr, get_accelerator
+    import Bindings
+    import WindowList
+    from MultiCall import MultiCallCreator
+
+    menubar = Menu(root)
+    root.configure(menu=menubar)
+    menudict = {}
+
+    menudict['windows'] = menu = Menu(menubar, name='windows')
+    menubar.add_cascade(label='Window', menu=menu, underline=0)
+
+    def postwindowsmenu(menu=menu):
+        end = menu.index('end')
+        if end is None:
+            end = -1
+
+        if end > 0:
+            menu.delete(0, end)
+        WindowList.add_windows_to_menu(menu)
+    WindowList.register_callback(postwindowsmenu)
+
+    menudict['application'] = menu = Menu(menubar, name='apple')
+    menubar.add_cascade(label='IDLE', menu=menu)
+
+    def about_dialog(event=None):
+        import aboutDialog
+        aboutDialog.AboutDialog(root, 'About IDLE')
+
+    def config_dialog(event=None):
+        import configDialog
+        configDialog.ConfigDialog(root, 'Settings')
+
+    root.bind('<<about-idle>>', about_dialog)
+    root.bind('<<open-config-dialog>>', config_dialog)
+    if flist:
+        root.bind('<<close-all-windows>>', flist.close_all_callback)
+
+    for mname, entrylist in Bindings.menudefs:
+        menu = menudict.get(mname)
+        if not menu:
+            continue
+        for entry in entrylist:
+            if not entry:
+                menu.add_separator()
+            else:
+                label, eventname = entry
+                underline, label = prepstr(label)
+                accelerator = get_accelerator(Bindings.default_keydefs,
+                        eventname)
+                def command(text=root, eventname=eventname):
+                    text.event_generate(eventname)
+                menu.add_command(label=label, underline=underline,
+                        command=command, accelerator=accelerator)
+
+
+
+
+
+def setupApp(root, flist):
+    """
+    Perform setup for the OSX application bundle.
+    """
+    if not runningAsOSXApp(): return
+
+    hideTkConsole(root)
+    overrideRootMenu(root, flist)
+    addOpenEventSupport(root, flist)

Added: vendor/Python/current/Lib/idlelib/rpc.py
===================================================================
--- vendor/Python/current/Lib/idlelib/rpc.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/rpc.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,602 @@
+"""RPC Implemention, originally written for the Python Idle IDE
+
+For security reasons, GvR requested that Idle's Python execution server process
+connect to the Idle process, which listens for the connection.  Since Idle has
+has only one client per server, this was not a limitation.
+
+   +---------------------------------+ +-------------+
+   | SocketServer.BaseRequestHandler | | SocketIO    |
+   +---------------------------------+ +-------------+
+                   ^                   | register()  |
+                   |                   | unregister()|
+                   |                   +-------------+
+                   |                      ^  ^
+                   |                      |  |
+                   | + -------------------+  |
+                   | |                       |
+   +-------------------------+        +-----------------+
+   | RPCHandler              |        | RPCClient       |
+   | [attribute of RPCServer]|        |                 |
+   +-------------------------+        +-----------------+
+
+The RPCServer handler class is expected to provide register/unregister methods.
+RPCHandler inherits the mix-in class SocketIO, which provides these methods.
+
+See the Idle run.main() docstring for further information on how this was
+accomplished in Idle.
+
+"""
+
+import sys
+import os
+import socket
+import select
+import SocketServer
+import struct
+import cPickle as pickle
+import threading
+import Queue
+import traceback
+import copy_reg
+import types
+import marshal
+
+
+def unpickle_code(ms):
+    co = marshal.loads(ms)
+    assert isinstance(co, types.CodeType)
+    return co
+
+def pickle_code(co):
+    assert isinstance(co, types.CodeType)
+    ms = marshal.dumps(co)
+    return unpickle_code, (ms,)
+
+# XXX KBK 24Aug02 function pickling capability not used in Idle
+#  def unpickle_function(ms):
+#      return ms
+
+#  def pickle_function(fn):
+#      assert isinstance(fn, type.FunctionType)
+#      return repr(fn)
+
+copy_reg.pickle(types.CodeType, pickle_code, unpickle_code)
+# copy_reg.pickle(types.FunctionType, pickle_function, unpickle_function)
+
+BUFSIZE = 8*1024
+LOCALHOST = '127.0.0.1'
+
+class RPCServer(SocketServer.TCPServer):
+
+    def __init__(self, addr, handlerclass=None):
+        if handlerclass is None:
+            handlerclass = RPCHandler
+        SocketServer.TCPServer.__init__(self, addr, handlerclass)
+
+    def server_bind(self):
+        "Override TCPServer method, no bind() phase for connecting entity"
+        pass
+
+    def server_activate(self):
+        """Override TCPServer method, connect() instead of listen()
+
+        Due to the reversed connection, self.server_address is actually the
+        address of the Idle Client to which we are connecting.
+
+        """
+        self.socket.connect(self.server_address)
+
+    def get_request(self):
+        "Override TCPServer method, return already connected socket"
+        return self.socket, self.server_address
+
+    def handle_error(self, request, client_address):
+        """Override TCPServer method
+
+        Error message goes to __stderr__.  No error message if exiting
+        normally or socket raised EOF.  Other exceptions not handled in
+        server code will cause os._exit.
+
+        """
+        try:
+            raise
+        except SystemExit:
+            raise
+        except:
+            erf = sys.__stderr__
+            print>>erf, '\n' + '-'*40
+            print>>erf, 'Unhandled server exception!'
+            print>>erf, 'Thread: %s' % threading.currentThread().getName()
+            print>>erf, 'Client Address: ', client_address
+            print>>erf, 'Request: ', repr(request)
+            traceback.print_exc(file=erf)
+            print>>erf, '\n*** Unrecoverable, server exiting!'
+            print>>erf, '-'*40
+            os._exit(0)
+
+#----------------- end class RPCServer --------------------
+
+objecttable = {}
+request_queue = Queue.Queue(0)
+response_queue = Queue.Queue(0)
+
+
+class SocketIO(object):
+
+    nextseq = 0
+
+    def __init__(self, sock, objtable=None, debugging=None):
+        self.sockthread = threading.currentThread()
+        if debugging is not None:
+            self.debugging = debugging
+        self.sock = sock
+        if objtable is None:
+            objtable = objecttable
+        self.objtable = objtable
+        self.responses = {}
+        self.cvars = {}
+
+    def close(self):
+        sock = self.sock
+        self.sock = None
+        if sock is not None:
+            sock.close()
+
+    def exithook(self):
+        "override for specific exit action"
+        os._exit()
+
+    def debug(self, *args):
+        if not self.debugging:
+            return
+        s = self.location + " " + str(threading.currentThread().getName())
+        for a in args:
+            s = s + " " + str(a)
+        print>>sys.__stderr__, s
+
+    def register(self, oid, object):
+        self.objtable[oid] = object
+
+    def unregister(self, oid):
+        try:
+            del self.objtable[oid]
+        except KeyError:
+            pass
+
+    def localcall(self, seq, request):
+        self.debug("localcall:", request)
+        try:
+            how, (oid, methodname, args, kwargs) = request
+        except TypeError:
+            return ("ERROR", "Bad request format")
+        if not self.objtable.has_key(oid):
+            return ("ERROR", "Unknown object id: %r" % (oid,))
+        obj = self.objtable[oid]
+        if methodname == "__methods__":
+            methods = {}
+            _getmethods(obj, methods)
+            return ("OK", methods)
+        if methodname == "__attributes__":
+            attributes = {}
+            _getattributes(obj, attributes)
+            return ("OK", attributes)
+        if not hasattr(obj, methodname):
+            return ("ERROR", "Unsupported method name: %r" % (methodname,))
+        method = getattr(obj, methodname)
+        try:
+            if how == 'CALL':
+                ret = method(*args, **kwargs)
+                if isinstance(ret, RemoteObject):
+                    ret = remoteref(ret)
+                return ("OK", ret)
+            elif how == 'QUEUE':
+                request_queue.put((seq, (method, args, kwargs)))
+                return("QUEUED", None)
+            else:
+                return ("ERROR", "Unsupported message type: %s" % how)
+        except SystemExit:
+            raise
+        except socket.error:
+            raise
+        except:
+            msg = "*** Internal Error: rpc.py:SocketIO.localcall()\n\n"\
+                  " Object: %s \n Method: %s \n Args: %s\n"
+            print>>sys.__stderr__, msg % (oid, method, args)
+            traceback.print_exc(file=sys.__stderr__)
+            return ("EXCEPTION", None)
+
+    def remotecall(self, oid, methodname, args, kwargs):
+        self.debug("remotecall:asynccall: ", oid, methodname)
+        seq = self.asynccall(oid, methodname, args, kwargs)
+        return self.asyncreturn(seq)
+
+    def remotequeue(self, oid, methodname, args, kwargs):
+        self.debug("remotequeue:asyncqueue: ", oid, methodname)
+        seq = self.asyncqueue(oid, methodname, args, kwargs)
+        return self.asyncreturn(seq)
+
+    def asynccall(self, oid, methodname, args, kwargs):
+        request = ("CALL", (oid, methodname, args, kwargs))
+        seq = self.newseq()
+        if threading.currentThread() != self.sockthread:
+            cvar = threading.Condition()
+            self.cvars[seq] = cvar
+        self.debug(("asynccall:%d:" % seq), oid, methodname, args, kwargs)
+        self.putmessage((seq, request))
+        return seq
+
+    def asyncqueue(self, oid, methodname, args, kwargs):
+        request = ("QUEUE", (oid, methodname, args, kwargs))
+        seq = self.newseq()
+        if threading.currentThread() != self.sockthread:
+            cvar = threading.Condition()
+            self.cvars[seq] = cvar
+        self.debug(("asyncqueue:%d:" % seq), oid, methodname, args, kwargs)
+        self.putmessage((seq, request))
+        return seq
+
+    def asyncreturn(self, seq):
+        self.debug("asyncreturn:%d:call getresponse(): " % seq)
+        response = self.getresponse(seq, wait=0.05)
+        self.debug(("asyncreturn:%d:response: " % seq), response)
+        return self.decoderesponse(response)
+
+    def decoderesponse(self, response):
+        how, what = response
+        if how == "OK":
+            return what
+        if how == "QUEUED":
+            return None
+        if how == "EXCEPTION":
+            self.debug("decoderesponse: EXCEPTION")
+            return None
+        if how == "EOF":
+            self.debug("decoderesponse: EOF")
+            self.decode_interrupthook()
+            return None
+        if how == "ERROR":
+            self.debug("decoderesponse: Internal ERROR:", what)
+            raise RuntimeError, what
+        raise SystemError, (how, what)
+
+    def decode_interrupthook(self):
+        ""
+        raise EOFError
+
+    def mainloop(self):
+        """Listen on socket until I/O not ready or EOF
+
+        pollresponse() will loop looking for seq number None, which
+        never comes, and exit on EOFError.
+
+        """
+        try:
+            self.getresponse(myseq=None, wait=0.05)
+        except EOFError:
+            self.debug("mainloop:return")
+            return
+
+    def getresponse(self, myseq, wait):
+        response = self._getresponse(myseq, wait)
+        if response is not None:
+            how, what = response
+            if how == "OK":
+                response = how, self._proxify(what)
+        return response
+
+    def _proxify(self, obj):
+        if isinstance(obj, RemoteProxy):
+            return RPCProxy(self, obj.oid)
+        if isinstance(obj, types.ListType):
+            return map(self._proxify, obj)
+        # XXX Check for other types -- not currently needed
+        return obj
+
+    def _getresponse(self, myseq, wait):
+        self.debug("_getresponse:myseq:", myseq)
+        if threading.currentThread() is self.sockthread:
+            # this thread does all reading of requests or responses
+            while 1:
+                response = self.pollresponse(myseq, wait)
+                if response is not None:
+                    return response
+        else:
+            # wait for notification from socket handling thread
+            cvar = self.cvars[myseq]
+            cvar.acquire()
+            while not self.responses.has_key(myseq):
+                cvar.wait()
+            response = self.responses[myseq]
+            self.debug("_getresponse:%s: thread woke up: response: %s" %
+                       (myseq, response))
+            del self.responses[myseq]
+            del self.cvars[myseq]
+            cvar.release()
+            return response
+
+    def newseq(self):
+        self.nextseq = seq = self.nextseq + 2
+        return seq
+
+    def putmessage(self, message):
+        self.debug("putmessage:%d:" % message[0])
+        try:
+            s = pickle.dumps(message)
+        except pickle.PicklingError:
+            print >>sys.__stderr__, "Cannot pickle:", repr(message)
+            raise
+        s = struct.pack("<i", len(s)) + s
+        while len(s) > 0:
+            try:
+                r, w, x = select.select([], [self.sock], [])
+                n = self.sock.send(s[:BUFSIZE])
+            except (AttributeError, TypeError):
+                raise IOError, "socket no longer exists"
+            except socket.error:
+                raise
+            else:
+                s = s[n:]
+
+    buffer = ""
+    bufneed = 4
+    bufstate = 0 # meaning: 0 => reading count; 1 => reading data
+
+    def pollpacket(self, wait):
+        self._stage0()
+        if len(self.buffer) < self.bufneed:
+            r, w, x = select.select([self.sock.fileno()], [], [], wait)
+            if len(r) == 0:
+                return None
+            try:
+                s = self.sock.recv(BUFSIZE)
+            except socket.error:
+                raise EOFError
+            if len(s) == 0:
+                raise EOFError
+            self.buffer += s
+            self._stage0()
+        return self._stage1()
+
+    def _stage0(self):
+        if self.bufstate == 0 and len(self.buffer) >= 4:
+            s = self.buffer[:4]
+            self.buffer = self.buffer[4:]
+            self.bufneed = struct.unpack("<i", s)[0]
+            self.bufstate = 1
+
+    def _stage1(self):
+        if self.bufstate == 1 and len(self.buffer) >= self.bufneed:
+            packet = self.buffer[:self.bufneed]
+            self.buffer = self.buffer[self.bufneed:]
+            self.bufneed = 4
+            self.bufstate = 0
+            return packet
+
+    def pollmessage(self, wait):
+        packet = self.pollpacket(wait)
+        if packet is None:
+            return None
+        try:
+            message = pickle.loads(packet)
+        except pickle.UnpicklingError:
+            print >>sys.__stderr__, "-----------------------"
+            print >>sys.__stderr__, "cannot unpickle packet:", repr(packet)
+            traceback.print_stack(file=sys.__stderr__)
+            print >>sys.__stderr__, "-----------------------"
+            raise
+        return message
+
+    def pollresponse(self, myseq, wait):
+        """Handle messages received on the socket.
+
+        Some messages received may be asynchronous 'call' or 'queue' requests,
+        and some may be responses for other threads.
+
+        'call' requests are passed to self.localcall() with the expectation of
+        immediate execution, during which time the socket is not serviced.
+
+        'queue' requests are used for tasks (which may block or hang) to be
+        processed in a different thread.  These requests are fed into
+        request_queue by self.localcall().  Responses to queued requests are
+        taken from response_queue and sent across the link with the associated
+        sequence numbers.  Messages in the queues are (sequence_number,
+        request/response) tuples and code using this module removing messages
+        from the request_queue is responsible for returning the correct
+        sequence number in the response_queue.
+
+        pollresponse() will loop until a response message with the myseq
+        sequence number is received, and will save other responses in
+        self.responses and notify the owning thread.
+
+        """
+        while 1:
+            # send queued response if there is one available
+            try:
+                qmsg = response_queue.get(0)
+            except Queue.Empty:
+                pass
+            else:
+                seq, response = qmsg
+                message = (seq, ('OK', response))
+                self.putmessage(message)
+            # poll for message on link
+            try:
+                message = self.pollmessage(wait)
+                if message is None:  # socket not ready
+                    return None
+            except EOFError:
+                self.handle_EOF()
+                return None
+            except AttributeError:
+                return None
+            seq, resq = message
+            how = resq[0]
+            self.debug("pollresponse:%d:myseq:%s" % (seq, myseq))
+            # process or queue a request
+            if how in ("CALL", "QUEUE"):
+                self.debug("pollresponse:%d:localcall:call:" % seq)
+                response = self.localcall(seq, resq)
+                self.debug("pollresponse:%d:localcall:response:%s"
+                           % (seq, response))
+                if how == "CALL":
+                    self.putmessage((seq, response))
+                elif how == "QUEUE":
+                    # don't acknowledge the 'queue' request!
+                    pass
+                continue
+            # return if completed message transaction
+            elif seq == myseq:
+                return resq
+            # must be a response for a different thread:
+            else:
+                cv = self.cvars.get(seq, None)
+                # response involving unknown sequence number is discarded,
+                # probably intended for prior incarnation of server
+                if cv is not None:
+                    cv.acquire()
+                    self.responses[seq] = resq
+                    cv.notify()
+                    cv.release()
+                continue
+
+    def handle_EOF(self):
+        "action taken upon link being closed by peer"
+        self.EOFhook()
+        self.debug("handle_EOF")
+        for key in self.cvars:
+            cv = self.cvars[key]
+            cv.acquire()
+            self.responses[key] = ('EOF', None)
+            cv.notify()
+            cv.release()
+        # call our (possibly overridden) exit function
+        self.exithook()
+
+    def EOFhook(self):
+        "Classes using rpc client/server can override to augment EOF action"
+        pass
+
+#----------------- end class SocketIO --------------------
+
+class RemoteObject(object):
+    # Token mix-in class
+    pass
+
+def remoteref(obj):
+    oid = id(obj)
+    objecttable[oid] = obj
+    return RemoteProxy(oid)
+
+class RemoteProxy(object):
+
+    def __init__(self, oid):
+        self.oid = oid
+
+class RPCHandler(SocketServer.BaseRequestHandler, SocketIO):
+
+    debugging = False
+    location = "#S"  # Server
+
+    def __init__(self, sock, addr, svr):
+        svr.current_handler = self ## cgt xxx
+        SocketIO.__init__(self, sock)
+        SocketServer.BaseRequestHandler.__init__(self, sock, addr, svr)
+
+    def handle(self):
+        "handle() method required by SocketServer"
+        self.mainloop()
+
+    def get_remote_proxy(self, oid):
+        return RPCProxy(self, oid)
+
+class RPCClient(SocketIO):
+
+    debugging = False
+    location = "#C"  # Client
+
+    nextseq = 1 # Requests coming from the client are odd numbered
+
+    def __init__(self, address, family=socket.AF_INET, type=socket.SOCK_STREAM):
+        self.listening_sock = socket.socket(family, type)
+        self.listening_sock.setsockopt(socket.SOL_SOCKET,
+                                       socket.SO_REUSEADDR, 1)
+        self.listening_sock.bind(address)
+        self.listening_sock.listen(1)
+
+    def accept(self):
+        working_sock, address = self.listening_sock.accept()
+        if self.debugging:
+            print>>sys.__stderr__, "****** Connection request from ", address
+        if address[0] == LOCALHOST:
+            SocketIO.__init__(self, working_sock)
+        else:
+            print>>sys.__stderr__, "** Invalid host: ", address
+            raise socket.error
+
+    def get_remote_proxy(self, oid):
+        return RPCProxy(self, oid)
+
+class RPCProxy(object):
+
+    __methods = None
+    __attributes = None
+
+    def __init__(self, sockio, oid):
+        self.sockio = sockio
+        self.oid = oid
+
+    def __getattr__(self, name):
+        if self.__methods is None:
+            self.__getmethods()
+        if self.__methods.get(name):
+            return MethodProxy(self.sockio, self.oid, name)
+        if self.__attributes is None:
+            self.__getattributes()
+        if self.__attributes.has_key(name):
+            value = self.sockio.remotecall(self.oid, '__getattribute__',
+                                           (name,), {})
+            return value
+        else:
+            raise AttributeError, name
+
+    def __getattributes(self):
+        self.__attributes = self.sockio.remotecall(self.oid,
+                                                "__attributes__", (), {})
+
+    def __getmethods(self):
+        self.__methods = self.sockio.remotecall(self.oid,
+                                                "__methods__", (), {})
+
+def _getmethods(obj, methods):
+    # Helper to get a list of methods from an object
+    # Adds names to dictionary argument 'methods'
+    for name in dir(obj):
+        attr = getattr(obj, name)
+        if callable(attr):
+            methods[name] = 1
+    if type(obj) == types.InstanceType:
+        _getmethods(obj.__class__, methods)
+    if type(obj) == types.ClassType:
+        for super in obj.__bases__:
+            _getmethods(super, methods)
+
+def _getattributes(obj, attributes):
+    for name in dir(obj):
+        attr = getattr(obj, name)
+        if not callable(attr):
+            attributes[name] = 1
+
+class MethodProxy(object):
+
+    def __init__(self, sockio, oid, name):
+        self.sockio = sockio
+        self.oid = oid
+        self.name = name
+
+    def __call__(self, *args, **kwargs):
+        value = self.sockio.remotecall(self.oid, self.name, args, kwargs)
+        return value
+
+
+# XXX KBK 09Sep03  We need a proper unit test for this module.  Previously
+#                  existing test code was removed at Rev 1.27.

Added: vendor/Python/current/Lib/idlelib/run.py
===================================================================
--- vendor/Python/current/Lib/idlelib/run.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/run.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,327 @@
+import sys
+import os
+import linecache
+import time
+import socket
+import traceback
+import thread
+import threading
+import Queue
+
+import CallTips
+import AutoComplete
+
+import RemoteDebugger
+import RemoteObjectBrowser
+import StackViewer
+import rpc
+
+import __main__
+
+LOCALHOST = '127.0.0.1'
+
+try:
+    import warnings
+except ImportError:
+    pass
+else:
+    def idle_formatwarning_subproc(message, category, filename, lineno):
+        """Format warnings the IDLE way"""
+        s = "\nWarning (from warnings module):\n"
+        s += '  File \"%s\", line %s\n' % (filename, lineno)
+        line = linecache.getline(filename, lineno).strip()
+        if line:
+            s += "    %s\n" % line
+        s += "%s: %s\n" % (category.__name__, message)
+        return s
+    warnings.formatwarning = idle_formatwarning_subproc
+
+# Thread shared globals: Establish a queue between a subthread (which handles
+# the socket) and the main thread (which runs user code), plus global
+# completion and exit flags:
+
+exit_now = False
+quitting = False
+
+def main(del_exitfunc=False):
+    """Start the Python execution server in a subprocess
+
+    In the Python subprocess, RPCServer is instantiated with handlerclass
+    MyHandler, which inherits register/unregister methods from RPCHandler via
+    the mix-in class SocketIO.
+
+    When the RPCServer 'server' is instantiated, the TCPServer initialization
+    creates an instance of run.MyHandler and calls its handle() method.
+    handle() instantiates a run.Executive object, passing it a reference to the
+    MyHandler object.  That reference is saved as attribute rpchandler of the
+    Executive instance.  The Executive methods have access to the reference and
+    can pass it on to entities that they command
+    (e.g. RemoteDebugger.Debugger.start_debugger()).  The latter, in turn, can
+    call MyHandler(SocketIO) register/unregister methods via the reference to
+    register and unregister themselves.
+
+    """
+    global exit_now
+    global quitting
+    global no_exitfunc
+    no_exitfunc = del_exitfunc
+    port = 8833
+    #time.sleep(15) # test subprocess not responding
+    if sys.argv[1:]:
+        port = int(sys.argv[1])
+    sys.argv[:] = [""]
+    sockthread = threading.Thread(target=manage_socket,
+                                  name='SockThread',
+                                  args=((LOCALHOST, port),))
+    sockthread.setDaemon(True)
+    sockthread.start()
+    while 1:
+        try:
+            if exit_now:
+                try:
+                    exit()
+                except KeyboardInterrupt:
+                    # exiting but got an extra KBI? Try again!
+                    continue
+            try:
+                seq, request = rpc.request_queue.get(block=True, timeout=0.05)
+            except Queue.Empty:
+                continue
+            method, args, kwargs = request
+            ret = method(*args, **kwargs)
+            rpc.response_queue.put((seq, ret))
+        except KeyboardInterrupt:
+            if quitting:
+                exit_now = True
+            continue
+        except SystemExit:
+            raise
+        except:
+            type, value, tb = sys.exc_info()
+            try:
+                print_exception()
+                rpc.response_queue.put((seq, None))
+            except:
+                # Link didn't work, print same exception to __stderr__
+                traceback.print_exception(type, value, tb, file=sys.__stderr__)
+                exit()
+            else:
+                continue
+
+def manage_socket(address):
+    for i in range(3):
+        time.sleep(i)
+        try:
+            server = MyRPCServer(address, MyHandler)
+            break
+        except socket.error, err:
+            print>>sys.__stderr__,"IDLE Subprocess: socket error: "\
+                                        + err[1] + ", retrying...."
+    else:
+        print>>sys.__stderr__, "IDLE Subprocess: Connection to "\
+                               "IDLE GUI failed, exiting."
+        show_socket_error(err, address)
+        global exit_now
+        exit_now = True
+        return
+    server.handle_request() # A single request only
+
+def show_socket_error(err, address):
+    import Tkinter
+    import tkMessageBox
+    root = Tkinter.Tk()
+    root.withdraw()
+    if err[0] == 61: # connection refused
+        msg = "IDLE's subprocess can't connect to %s:%d.  This may be due "\
+              "to your personal firewall configuration.  It is safe to "\
+              "allow this internal connection because no data is visible on "\
+              "external ports." % address
+        tkMessageBox.showerror("IDLE Subprocess Error", msg, parent=root)
+    else:
+        tkMessageBox.showerror("IDLE Subprocess Error", "Socket Error: %s" % err[1])
+    root.destroy()
+
+def print_exception():
+    import linecache
+    linecache.checkcache()
+    flush_stdout()
+    efile = sys.stderr
+    typ, val, tb = excinfo = sys.exc_info()
+    sys.last_type, sys.last_value, sys.last_traceback = excinfo
+    tbe = traceback.extract_tb(tb)
+    print>>efile, '\nTraceback (most recent call last):'
+    exclude = ("run.py", "rpc.py", "threading.py", "Queue.py",
+               "RemoteDebugger.py", "bdb.py")
+    cleanup_traceback(tbe, exclude)
+    traceback.print_list(tbe, file=efile)
+    lines = traceback.format_exception_only(typ, val)
+    for line in lines:
+        print>>efile, line,
+
+def cleanup_traceback(tb, exclude):
+    "Remove excluded traces from beginning/end of tb; get cached lines"
+    orig_tb = tb[:]
+    while tb:
+        for rpcfile in exclude:
+            if tb[0][0].count(rpcfile):
+                break    # found an exclude, break for: and delete tb[0]
+        else:
+            break        # no excludes, have left RPC code, break while:
+        del tb[0]
+    while tb:
+        for rpcfile in exclude:
+            if tb[-1][0].count(rpcfile):
+                break
+        else:
+            break
+        del tb[-1]
+    if len(tb) == 0:
+        # exception was in IDLE internals, don't prune!
+        tb[:] = orig_tb[:]
+        print>>sys.stderr, "** IDLE Internal Exception: "
+    rpchandler = rpc.objecttable['exec'].rpchandler
+    for i in range(len(tb)):
+        fn, ln, nm, line = tb[i]
+        if nm == '?':
+            nm = "-toplevel-"
+        if not line and fn.startswith("<pyshell#"):
+            line = rpchandler.remotecall('linecache', 'getline',
+                                              (fn, ln), {})
+        tb[i] = fn, ln, nm, line
+
+def flush_stdout():
+    try:
+        if sys.stdout.softspace:
+            sys.stdout.softspace = 0
+            sys.stdout.write("\n")
+    except (AttributeError, EOFError):
+        pass
+
+def exit():
+    """Exit subprocess, possibly after first deleting sys.exitfunc
+
+    If config-main.cfg/.def 'General' 'delete-exitfunc' is True, then any
+    sys.exitfunc will be removed before exiting.  (VPython support)
+
+    """
+    if no_exitfunc:
+        del sys.exitfunc
+    sys.exit(0)
+
+class MyRPCServer(rpc.RPCServer):
+
+    def handle_error(self, request, client_address):
+        """Override RPCServer method for IDLE
+
+        Interrupt the MainThread and exit server if link is dropped.
+
+        """
+        global quitting
+        try:
+            raise
+        except SystemExit:
+            raise
+        except EOFError:
+            global exit_now
+            exit_now = True
+            thread.interrupt_main()
+        except:
+            erf = sys.__stderr__
+            print>>erf, '\n' + '-'*40
+            print>>erf, 'Unhandled server exception!'
+            print>>erf, 'Thread: %s' % threading.currentThread().getName()
+            print>>erf, 'Client Address: ', client_address
+            print>>erf, 'Request: ', repr(request)
+            traceback.print_exc(file=erf)
+            print>>erf, '\n*** Unrecoverable, server exiting!'
+            print>>erf, '-'*40
+            quitting = True
+            thread.interrupt_main()
+
+
+class MyHandler(rpc.RPCHandler):
+
+    def handle(self):
+        """Override base method"""
+        executive = Executive(self)
+        self.register("exec", executive)
+        sys.stdin = self.console = self.get_remote_proxy("stdin")
+        sys.stdout = self.get_remote_proxy("stdout")
+        sys.stderr = self.get_remote_proxy("stderr")
+        import IOBinding
+        sys.stdin.encoding = sys.stdout.encoding = \
+                             sys.stderr.encoding = IOBinding.encoding
+        self.interp = self.get_remote_proxy("interp")
+        rpc.RPCHandler.getresponse(self, myseq=None, wait=0.05)
+
+    def exithook(self):
+        "override SocketIO method - wait for MainThread to shut us down"
+        time.sleep(10)
+
+    def EOFhook(self):
+        "Override SocketIO method - terminate wait on callback and exit thread"
+        global quitting
+        quitting = True
+        thread.interrupt_main()
+
+    def decode_interrupthook(self):
+        "interrupt awakened thread"
+        global quitting
+        quitting = True
+        thread.interrupt_main()
+
+
+class Executive(object):
+
+    def __init__(self, rpchandler):
+        self.rpchandler = rpchandler
+        self.locals = __main__.__dict__
+        self.calltip = CallTips.CallTips()
+        self.autocomplete = AutoComplete.AutoComplete()
+
+    def runcode(self, code):
+        try:
+            self.usr_exc_info = None
+            exec code in self.locals
+        except:
+            self.usr_exc_info = sys.exc_info()
+            if quitting:
+                exit()
+            # even print a user code SystemExit exception, continue
+            print_exception()
+            jit = self.rpchandler.console.getvar("<<toggle-jit-stack-viewer>>")
+            if jit:
+                self.rpchandler.interp.open_remote_stack_viewer()
+        else:
+            flush_stdout()
+
+    def interrupt_the_server(self):
+        thread.interrupt_main()
+
+    def start_the_debugger(self, gui_adap_oid):
+        return RemoteDebugger.start_debugger(self.rpchandler, gui_adap_oid)
+
+    def stop_the_debugger(self, idb_adap_oid):
+        "Unregister the Idb Adapter.  Link objects and Idb then subject to GC"
+        self.rpchandler.unregister(idb_adap_oid)
+
+    def get_the_calltip(self, name):
+        return self.calltip.fetch_tip(name)
+
+    def get_the_completion_list(self, what, mode):
+        return self.autocomplete.fetch_completions(what, mode)
+
+    def stackviewer(self, flist_oid=None):
+        if self.usr_exc_info:
+            typ, val, tb = self.usr_exc_info
+        else:
+            return None
+        flist = None
+        if flist_oid is not None:
+            flist = self.rpchandler.get_remote_proxy(flist_oid)
+        while tb and tb.tb_frame.f_globals["__name__"] in ["rpc", "run"]:
+            tb = tb.tb_next
+        sys.last_type = typ
+        sys.last_value = val
+        item = StackViewer.StackTreeItem(flist, tb)
+        return RemoteObjectBrowser.remote_object_tree_item(item)

Added: vendor/Python/current/Lib/idlelib/tabpage.py
===================================================================
--- vendor/Python/current/Lib/idlelib/tabpage.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/tabpage.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,113 @@
+"""
+a couple of classes for implementing partial tabbed-page like behaviour
+"""
+
+from Tkinter import *
+
+class InvalidTabPage(Exception): pass
+class AlreadyExists(Exception): pass
+
+class PageTab(Frame):
+    """
+    a 'page tab' like framed button
+    """
+    def __init__(self,parent):
+        Frame.__init__(self, parent,borderwidth=2,relief=RIDGE)
+        self.button=Radiobutton(self,padx=5,pady=5,takefocus=FALSE,
+                indicatoron=FALSE,highlightthickness=0,
+                borderwidth=0,selectcolor=self.cget('bg'))
+        self.button.pack()
+
+class TabPageSet(Frame):
+    """
+    a set of 'pages' with TabButtons for controlling their display
+    """
+    def __init__(self,parent,pageNames=[],**kw):
+        """
+        pageNames - a list of strings, each string will be the dictionary key
+        to a page's data, and the name displayed on the page's tab. Should be
+        specified in desired page order. The first page will be the default
+        and first active page.
+        """
+        Frame.__init__(self, parent, kw)
+        self.grid_location(0,0)
+        self.columnconfigure(0,weight=1)
+        self.rowconfigure(1,weight=1)
+        self.tabBar=Frame(self)
+        self.tabBar.grid(row=0,column=0,sticky=EW)
+        self.activePage=StringVar(self)
+        self.defaultPage=''
+        self.pages={}
+        for name in pageNames:
+            self.AddPage(name)
+
+    def ChangePage(self,pageName=None):
+        if pageName:
+            if pageName in self.pages.keys():
+                self.activePage.set(pageName)
+            else:
+                raise InvalidTabPage, 'Invalid TabPage Name'
+        ## pop up the active 'tab' only
+        for page in self.pages.keys():
+            self.pages[page]['tab'].config(relief=RIDGE)
+        self.pages[self.GetActivePage()]['tab'].config(relief=RAISED)
+        ## switch page
+        self.pages[self.GetActivePage()]['page'].lift()
+
+    def GetActivePage(self):
+        return self.activePage.get()
+
+    def AddPage(self,pageName):
+        if pageName in self.pages.keys():
+            raise AlreadyExists, 'TabPage Name Already Exists'
+        self.pages[pageName]={'tab':PageTab(self.tabBar),
+                'page':Frame(self,borderwidth=2,relief=RAISED)}
+        self.pages[pageName]['tab'].button.config(text=pageName,
+                command=self.ChangePage,variable=self.activePage,
+                value=pageName)
+        self.pages[pageName]['tab'].pack(side=LEFT)
+        self.pages[pageName]['page'].grid(row=1,column=0,sticky=NSEW)
+        if len(self.pages)==1: # adding first page
+            self.defaultPage=pageName
+            self.activePage.set(self.defaultPage)
+            self.ChangePage()
+
+    def RemovePage(self,pageName):
+        if not pageName in self.pages.keys():
+            raise InvalidTabPage, 'Invalid TabPage Name'
+        self.pages[pageName]['tab'].pack_forget()
+        self.pages[pageName]['page'].grid_forget()
+        self.pages[pageName]['tab'].destroy()
+        self.pages[pageName]['page'].destroy()
+        del(self.pages[pageName])
+        # handle removing last remaining, or default, or active page
+        if not self.pages: # removed last remaining page
+            self.defaultPage=''
+            return
+        if pageName==self.defaultPage: # set a new default page
+            self.defaultPage=\
+                self.tabBar.winfo_children()[0].button.cget('text')
+        if pageName==self.GetActivePage(): # set a new active page
+            self.activePage.set(self.defaultPage)
+        self.ChangePage()
+
+if __name__ == '__main__':
+    #test dialog
+    root=Tk()
+    tabPage=TabPageSet(root,pageNames=['Foobar','Baz'])
+    tabPage.pack(expand=TRUE,fill=BOTH)
+    Label(tabPage.pages['Foobar']['page'],text='Foo',pady=20).pack()
+    Label(tabPage.pages['Foobar']['page'],text='Bar',pady=20).pack()
+    Label(tabPage.pages['Baz']['page'],text='Baz').pack()
+    entryPgName=Entry(root)
+    buttonAdd=Button(root,text='Add Page',
+            command=lambda:tabPage.AddPage(entryPgName.get()))
+    buttonRemove=Button(root,text='Remove Page',
+            command=lambda:tabPage.RemovePage(entryPgName.get()))
+    labelPgName=Label(root,text='name of page to add/remove:')
+    buttonAdd.pack(padx=5,pady=5)
+    buttonRemove.pack(padx=5,pady=5)
+    labelPgName.pack(padx=5)
+    entryPgName.pack(padx=5)
+    tabPage.ChangePage()
+    root.mainloop()

Added: vendor/Python/current/Lib/idlelib/testcode.py
===================================================================
--- vendor/Python/current/Lib/idlelib/testcode.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/testcode.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,31 @@
+import string
+
+def f():
+    a = 0
+    b = 1
+    c = 2
+    d = 3
+    e = 4
+    g()
+
+def g():
+    h()
+
+def h():
+    i()
+
+def i():
+    j()
+
+def j():
+    k()
+
+def k():
+    l()
+
+l = lambda: test()
+
+def test():
+    string.capwords(1)
+
+f()

Added: vendor/Python/current/Lib/idlelib/textView.py
===================================================================
--- vendor/Python/current/Lib/idlelib/textView.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/idlelib/textView.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,78 @@
+"""Simple text browser for IDLE
+
+"""
+
+from Tkinter import *
+import tkMessageBox
+
+class TextViewer(Toplevel):
+    """
+    simple text viewer dialog for idle
+    """
+    def __init__(self, parent, title, fileName, data=None):
+        """If data exists, load it into viewer, otherwise try to load file.
+
+        fileName - string, should be an absoulute filename
+        """
+        Toplevel.__init__(self, parent)
+        self.configure(borderwidth=5)
+        self.geometry("=%dx%d+%d+%d" % (625, 500,
+                                        parent.winfo_rootx() + 10,
+                                        parent.winfo_rooty() + 10))
+        #elguavas - config placeholders til config stuff completed
+        self.bg = '#ffffff'
+        self.fg = '#000000'
+
+        self.CreateWidgets()
+        self.title(title)
+        self.transient(parent)
+        self.grab_set()
+        self.protocol("WM_DELETE_WINDOW", self.Ok)
+        self.parent = parent
+        self.textView.focus_set()
+        #key bindings for this dialog
+        self.bind('<Return>',self.Ok) #dismiss dialog
+        self.bind('<Escape>',self.Ok) #dismiss dialog
+        if data:
+            self.textView.insert(0.0, data)
+        else:
+            self.LoadTextFile(fileName)
+        self.textView.config(state=DISABLED)
+        self.wait_window()
+
+    def LoadTextFile(self, fileName):
+        textFile = None
+        try:
+            textFile = open(fileName, 'r')
+        except IOError:
+            tkMessageBox.showerror(title='File Load Error',
+                    message='Unable to load file %r .' % (fileName,))
+        else:
+            self.textView.insert(0.0,textFile.read())
+
+    def CreateWidgets(self):
+        frameText = Frame(self, relief=SUNKEN, height=700)
+        frameButtons = Frame(self)
+        self.buttonOk = Button(frameButtons, text='Close',
+                               command=self.Ok, takefocus=FALSE)
+        self.scrollbarView = Scrollbar(frameText, orient=VERTICAL,
+                                       takefocus=FALSE, highlightthickness=0)
+        self.textView = Text(frameText, wrap=WORD, highlightthickness=0,
+                             fg=self.fg, bg=self.bg)
+        self.scrollbarView.config(command=self.textView.yview)
+        self.textView.config(yscrollcommand=self.scrollbarView.set)
+        self.buttonOk.pack()
+        self.scrollbarView.pack(side=RIGHT,fill=Y)
+        self.textView.pack(side=LEFT,expand=TRUE,fill=BOTH)
+        frameButtons.pack(side=BOTTOM,fill=X)
+        frameText.pack(side=TOP,expand=TRUE,fill=BOTH)
+
+    def Ok(self, event=None):
+        self.destroy()
+
+if __name__ == '__main__':
+    #test the dialog
+    root=Tk()
+    Button(root,text='View',
+            command=lambda:TextViewer(root,'Text','./textView.py')).pack()
+    root.mainloop()

Added: vendor/Python/current/Lib/ihooks.py
===================================================================
--- vendor/Python/current/Lib/ihooks.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ihooks.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,520 @@
+"""Import hook support.
+
+Consistent use of this module will make it possible to change the
+different mechanisms involved in loading modules independently.
+
+While the built-in module imp exports interfaces to the built-in
+module searching and loading algorithm, and it is possible to replace
+the built-in function __import__ in order to change the semantics of
+the import statement, until now it has been difficult to combine the
+effect of different __import__ hacks, like loading modules from URLs
+by rimport.py, or restricted execution by rexec.py.
+
+This module defines three new concepts:
+
+1) A "file system hooks" class provides an interface to a filesystem.
+
+One hooks class is defined (Hooks), which uses the interface provided
+by standard modules os and os.path.  It should be used as the base
+class for other hooks classes.
+
+2) A "module loader" class provides an interface to search for a
+module in a search path and to load it.  It defines a method which
+searches for a module in a single directory; by overriding this method
+one can redefine the details of the search.  If the directory is None,
+built-in and frozen modules are searched instead.
+
+Two module loader class are defined, both implementing the search
+strategy used by the built-in __import__ function: ModuleLoader uses
+the imp module's find_module interface, while HookableModuleLoader
+uses a file system hooks class to interact with the file system.  Both
+use the imp module's load_* interfaces to actually load the module.
+
+3) A "module importer" class provides an interface to import a
+module, as well as interfaces to reload and unload a module.  It also
+provides interfaces to install and uninstall itself instead of the
+default __import__ and reload (and unload) functions.
+
+One module importer class is defined (ModuleImporter), which uses a
+module loader instance passed in (by default HookableModuleLoader is
+instantiated).
+
+The classes defined here should be used as base classes for extended
+functionality along those lines.
+
+If a module importer class supports dotted names, its import_module()
+must return a different value depending on whether it is called on
+behalf of a "from ... import ..." statement or not.  (This is caused
+by the way the __import__ hook is used by the Python interpreter.)  It
+would also do wise to install a different version of reload().
+
+"""
+
+
+import __builtin__
+import imp
+import os
+import sys
+
+__all__ = ["BasicModuleLoader","Hooks","ModuleLoader","FancyModuleLoader",
+           "BasicModuleImporter","ModuleImporter","install","uninstall"]
+
+VERBOSE = 0
+
+
+from imp import C_EXTENSION, PY_SOURCE, PY_COMPILED
+from imp import C_BUILTIN, PY_FROZEN, PKG_DIRECTORY
+BUILTIN_MODULE = C_BUILTIN
+FROZEN_MODULE = PY_FROZEN
+
+
+class _Verbose:
+
+    def __init__(self, verbose = VERBOSE):
+        self.verbose = verbose
+
+    def get_verbose(self):
+        return self.verbose
+
+    def set_verbose(self, verbose):
+        self.verbose = verbose
+
+    # XXX The following is an experimental interface
+
+    def note(self, *args):
+        if self.verbose:
+            self.message(*args)
+
+    def message(self, format, *args):
+        if args:
+            print format%args
+        else:
+            print format
+
+
+class BasicModuleLoader(_Verbose):
+
+    """Basic module loader.
+
+    This provides the same functionality as built-in import.  It
+    doesn't deal with checking sys.modules -- all it provides is
+    find_module() and a load_module(), as well as find_module_in_dir()
+    which searches just one directory, and can be overridden by a
+    derived class to change the module search algorithm when the basic
+    dependency on sys.path is unchanged.
+
+    The interface is a little more convenient than imp's:
+    find_module(name, [path]) returns None or 'stuff', and
+    load_module(name, stuff) loads the module.
+
+    """
+
+    def find_module(self, name, path = None):
+        if path is None:
+            path = [None] + self.default_path()
+        for dir in path:
+            stuff = self.find_module_in_dir(name, dir)
+            if stuff: return stuff
+        return None
+
+    def default_path(self):
+        return sys.path
+
+    def find_module_in_dir(self, name, dir):
+        if dir is None:
+            return self.find_builtin_module(name)
+        else:
+            try:
+                return imp.find_module(name, [dir])
+            except ImportError:
+                return None
+
+    def find_builtin_module(self, name):
+        # XXX frozen packages?
+        if imp.is_builtin(name):
+            return None, '', ('', '', BUILTIN_MODULE)
+        if imp.is_frozen(name):
+            return None, '', ('', '', FROZEN_MODULE)
+        return None
+
+    def load_module(self, name, stuff):
+        file, filename, info = stuff
+        try:
+            return imp.load_module(name, file, filename, info)
+        finally:
+            if file: file.close()
+
+
+class Hooks(_Verbose):
+
+    """Hooks into the filesystem and interpreter.
+
+    By deriving a subclass you can redefine your filesystem interface,
+    e.g. to merge it with the URL space.
+
+    This base class behaves just like the native filesystem.
+
+    """
+
+    # imp interface
+    def get_suffixes(self): return imp.get_suffixes()
+    def new_module(self, name): return imp.new_module(name)
+    def is_builtin(self, name): return imp.is_builtin(name)
+    def init_builtin(self, name): return imp.init_builtin(name)
+    def is_frozen(self, name): return imp.is_frozen(name)
+    def init_frozen(self, name): return imp.init_frozen(name)
+    def get_frozen_object(self, name): return imp.get_frozen_object(name)
+    def load_source(self, name, filename, file=None):
+        return imp.load_source(name, filename, file)
+    def load_compiled(self, name, filename, file=None):
+        return imp.load_compiled(name, filename, file)
+    def load_dynamic(self, name, filename, file=None):
+        return imp.load_dynamic(name, filename, file)
+    def load_package(self, name, filename, file=None):
+        return imp.load_module(name, file, filename, ("", "", PKG_DIRECTORY))
+
+    def add_module(self, name):
+        d = self.modules_dict()
+        if name in d: return d[name]
+        d[name] = m = self.new_module(name)
+        return m
+
+    # sys interface
+    def modules_dict(self): return sys.modules
+    def default_path(self): return sys.path
+
+    def path_split(self, x): return os.path.split(x)
+    def path_join(self, x, y): return os.path.join(x, y)
+    def path_isabs(self, x): return os.path.isabs(x)
+    # etc.
+
+    def path_exists(self, x): return os.path.exists(x)
+    def path_isdir(self, x): return os.path.isdir(x)
+    def path_isfile(self, x): return os.path.isfile(x)
+    def path_islink(self, x): return os.path.islink(x)
+    # etc.
+
+    def openfile(self, *x): return open(*x)
+    openfile_error = IOError
+    def listdir(self, x): return os.listdir(x)
+    listdir_error = os.error
+    # etc.
+
+
+class ModuleLoader(BasicModuleLoader):
+
+    """Default module loader; uses file system hooks.
+
+    By defining suitable hooks, you might be able to load modules from
+    other sources than the file system, e.g. from compressed or
+    encrypted files, tar files or (if you're brave!) URLs.
+
+    """
+
+    def __init__(self, hooks = None, verbose = VERBOSE):
+        BasicModuleLoader.__init__(self, verbose)
+        self.hooks = hooks or Hooks(verbose)
+
+    def default_path(self):
+        return self.hooks.default_path()
+
+    def modules_dict(self):
+        return self.hooks.modules_dict()
+
+    def get_hooks(self):
+        return self.hooks
+
+    def set_hooks(self, hooks):
+        self.hooks = hooks
+
+    def find_builtin_module(self, name):
+        # XXX frozen packages?
+        if self.hooks.is_builtin(name):
+            return None, '', ('', '', BUILTIN_MODULE)
+        if self.hooks.is_frozen(name):
+            return None, '', ('', '', FROZEN_MODULE)
+        return None
+
+    def find_module_in_dir(self, name, dir, allow_packages=1):
+        if dir is None:
+            return self.find_builtin_module(name)
+        if allow_packages:
+            fullname = self.hooks.path_join(dir, name)
+            if self.hooks.path_isdir(fullname):
+                stuff = self.find_module_in_dir("__init__", fullname, 0)
+                if stuff:
+                    file = stuff[0]
+                    if file: file.close()
+                    return None, fullname, ('', '', PKG_DIRECTORY)
+        for info in self.hooks.get_suffixes():
+            suff, mode, type = info
+            fullname = self.hooks.path_join(dir, name+suff)
+            try:
+                fp = self.hooks.openfile(fullname, mode)
+                return fp, fullname, info
+            except self.hooks.openfile_error:
+                pass
+        return None
+
+    def load_module(self, name, stuff):
+        file, filename, info = stuff
+        (suff, mode, type) = info
+        try:
+            if type == BUILTIN_MODULE:
+                return self.hooks.init_builtin(name)
+            if type == FROZEN_MODULE:
+                return self.hooks.init_frozen(name)
+            if type == C_EXTENSION:
+                m = self.hooks.load_dynamic(name, filename, file)
+            elif type == PY_SOURCE:
+                m = self.hooks.load_source(name, filename, file)
+            elif type == PY_COMPILED:
+                m = self.hooks.load_compiled(name, filename, file)
+            elif type == PKG_DIRECTORY:
+                m = self.hooks.load_package(name, filename, file)
+            else:
+                raise ImportError, "Unrecognized module type (%r) for %s" % \
+                      (type, name)
+        finally:
+            if file: file.close()
+        m.__file__ = filename
+        return m
+
+
+class FancyModuleLoader(ModuleLoader):
+
+    """Fancy module loader -- parses and execs the code itself."""
+
+    def load_module(self, name, stuff):
+        file, filename, (suff, mode, type) = stuff
+        realfilename = filename
+        path = None
+
+        if type == PKG_DIRECTORY:
+            initstuff = self.find_module_in_dir("__init__", filename, 0)
+            if not initstuff:
+                raise ImportError, "No __init__ module in package %s" % name
+            initfile, initfilename, initinfo = initstuff
+            initsuff, initmode, inittype = initinfo
+            if inittype not in (PY_COMPILED, PY_SOURCE):
+                if initfile: initfile.close()
+                raise ImportError, \
+                    "Bad type (%r) for __init__ module in package %s" % (
+                    inittype, name)
+            path = [filename]
+            file = initfile
+            realfilename = initfilename
+            type = inittype
+
+        if type == FROZEN_MODULE:
+            code = self.hooks.get_frozen_object(name)
+        elif type == PY_COMPILED:
+            import marshal
+            file.seek(8)
+            code = marshal.load(file)
+        elif type == PY_SOURCE:
+            data = file.read()
+            code = compile(data, realfilename, 'exec')
+        else:
+            return ModuleLoader.load_module(self, name, stuff)
+
+        m = self.hooks.add_module(name)
+        if path:
+            m.__path__ = path
+        m.__file__ = filename
+        try:
+            exec code in m.__dict__
+        except:
+            d = self.hooks.modules_dict()
+            if name in d:
+                del d[name]
+            raise
+        return m
+
+
+class BasicModuleImporter(_Verbose):
+
+    """Basic module importer; uses module loader.
+
+    This provides basic import facilities but no package imports.
+
+    """
+
+    def __init__(self, loader = None, verbose = VERBOSE):
+        _Verbose.__init__(self, verbose)
+        self.loader = loader or ModuleLoader(None, verbose)
+        self.modules = self.loader.modules_dict()
+
+    def get_loader(self):
+        return self.loader
+
+    def set_loader(self, loader):
+        self.loader = loader
+
+    def get_hooks(self):
+        return self.loader.get_hooks()
+
+    def set_hooks(self, hooks):
+        return self.loader.set_hooks(hooks)
+
+    def import_module(self, name, globals={}, locals={}, fromlist=[]):
+        name = str(name)
+        if name in self.modules:
+            return self.modules[name] # Fast path
+        stuff = self.loader.find_module(name)
+        if not stuff:
+            raise ImportError, "No module named %s" % name
+        return self.loader.load_module(name, stuff)
+
+    def reload(self, module, path = None):
+        name = str(module.__name__)
+        stuff = self.loader.find_module(name, path)
+        if not stuff:
+            raise ImportError, "Module %s not found for reload" % name
+        return self.loader.load_module(name, stuff)
+
+    def unload(self, module):
+        del self.modules[str(module.__name__)]
+        # XXX Should this try to clear the module's namespace?
+
+    def install(self):
+        self.save_import_module = __builtin__.__import__
+        self.save_reload = __builtin__.reload
+        if not hasattr(__builtin__, 'unload'):
+            __builtin__.unload = None
+        self.save_unload = __builtin__.unload
+        __builtin__.__import__ = self.import_module
+        __builtin__.reload = self.reload
+        __builtin__.unload = self.unload
+
+    def uninstall(self):
+        __builtin__.__import__ = self.save_import_module
+        __builtin__.reload = self.save_reload
+        __builtin__.unload = self.save_unload
+        if not __builtin__.unload:
+            del __builtin__.unload
+
+
+class ModuleImporter(BasicModuleImporter):
+
+    """A module importer that supports packages."""
+
+    def import_module(self, name, globals=None, locals=None, fromlist=None):
+        parent = self.determine_parent(globals)
+        q, tail = self.find_head_package(parent, str(name))
+        m = self.load_tail(q, tail)
+        if not fromlist:
+            return q
+        if hasattr(m, "__path__"):
+            self.ensure_fromlist(m, fromlist)
+        return m
+
+    def determine_parent(self, globals):
+        if not globals or not "__name__" in globals:
+            return None
+        pname = globals['__name__']
+        if "__path__" in globals:
+            parent = self.modules[pname]
+            assert globals is parent.__dict__
+            return parent
+        if '.' in pname:
+            i = pname.rfind('.')
+            pname = pname[:i]
+            parent = self.modules[pname]
+            assert parent.__name__ == pname
+            return parent
+        return None
+
+    def find_head_package(self, parent, name):
+        if '.' in name:
+            i = name.find('.')
+            head = name[:i]
+            tail = name[i+1:]
+        else:
+            head = name
+            tail = ""
+        if parent:
+            qname = "%s.%s" % (parent.__name__, head)
+        else:
+            qname = head
+        q = self.import_it(head, qname, parent)
+        if q: return q, tail
+        if parent:
+            qname = head
+            parent = None
+            q = self.import_it(head, qname, parent)
+            if q: return q, tail
+        raise ImportError, "No module named " + qname
+
+    def load_tail(self, q, tail):
+        m = q
+        while tail:
+            i = tail.find('.')
+            if i < 0: i = len(tail)
+            head, tail = tail[:i], tail[i+1:]
+            mname = "%s.%s" % (m.__name__, head)
+            m = self.import_it(head, mname, m)
+            if not m:
+                raise ImportError, "No module named " + mname
+        return m
+
+    def ensure_fromlist(self, m, fromlist, recursive=0):
+        for sub in fromlist:
+            if sub == "*":
+                if not recursive:
+                    try:
+                        all = m.__all__
+                    except AttributeError:
+                        pass
+                    else:
+                        self.ensure_fromlist(m, all, 1)
+                continue
+            if sub != "*" and not hasattr(m, sub):
+                subname = "%s.%s" % (m.__name__, sub)
+                submod = self.import_it(sub, subname, m)
+                if not submod:
+                    raise ImportError, "No module named " + subname
+
+    def import_it(self, partname, fqname, parent, force_load=0):
+        if not partname:
+            raise ValueError, "Empty module name"
+        if not force_load:
+            try:
+                return self.modules[fqname]
+            except KeyError:
+                pass
+        try:
+            path = parent and parent.__path__
+        except AttributeError:
+            return None
+        partname = str(partname)
+        stuff = self.loader.find_module(partname, path)
+        if not stuff:
+            return None
+        fqname = str(fqname)
+        m = self.loader.load_module(fqname, stuff)
+        if parent:
+            setattr(parent, partname, m)
+        return m
+
+    def reload(self, module):
+        name = str(module.__name__)
+        if '.' not in name:
+            return self.import_it(name, name, None, force_load=1)
+        i = name.rfind('.')
+        pname = name[:i]
+        parent = self.modules[pname]
+        return self.import_it(name[i+1:], name, parent, force_load=1)
+
+
+default_importer = None
+current_importer = None
+
+def install(importer = None):
+    global current_importer
+    current_importer = importer or default_importer or ModuleImporter()
+    current_importer.install()
+
+def uninstall():
+    global current_importer
+    current_importer.uninstall()

Added: vendor/Python/current/Lib/imaplib.py
===================================================================
--- vendor/Python/current/Lib/imaplib.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/imaplib.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1499 @@
+"""IMAP4 client.
+
+Based on RFC 2060.
+
+Public class:           IMAP4
+Public variable:        Debug
+Public functions:       Internaldate2tuple
+                        Int2AP
+                        ParseFlags
+                        Time2Internaldate
+"""
+
+# Author: Piers Lauder <piers at cs.su.oz.au> December 1997.
+#
+# Authentication code contributed by Donn Cave <donn at u.washington.edu> June 1998.
+# String method conversion by ESR, February 2001.
+# GET/SETACL contributed by Anthony Baxter <anthony at interlink.com.au> April 2001.
+# IMAP4_SSL contributed by Tino Lange <Tino.Lange at isg.de> March 2002.
+# GET/SETQUOTA contributed by Andreas Zeidler <az at kreativkombinat.de> June 2002.
+# PROXYAUTH contributed by Rick Holbert <holbert.13 at osu.edu> November 2002.
+# GET/SETANNOTATION contributed by Tomas Lindroos <skitta at abo.fi> June 2005.
+
+__version__ = "2.58"
+
+import binascii, os, random, re, socket, sys, time
+
+__all__ = ["IMAP4", "IMAP4_SSL", "IMAP4_stream", "Internaldate2tuple",
+           "Int2AP", "ParseFlags", "Time2Internaldate"]
+
+#       Globals
+
+CRLF = '\r\n'
+Debug = 0
+IMAP4_PORT = 143
+IMAP4_SSL_PORT = 993
+AllowedVersions = ('IMAP4REV1', 'IMAP4')        # Most recent first
+
+#       Commands
+
+Commands = {
+        # name            valid states
+        'APPEND':       ('AUTH', 'SELECTED'),
+        'AUTHENTICATE': ('NONAUTH',),
+        'CAPABILITY':   ('NONAUTH', 'AUTH', 'SELECTED', 'LOGOUT'),
+        'CHECK':        ('SELECTED',),
+        'CLOSE':        ('SELECTED',),
+        'COPY':         ('SELECTED',),
+        'CREATE':       ('AUTH', 'SELECTED'),
+        'DELETE':       ('AUTH', 'SELECTED'),
+        'DELETEACL':    ('AUTH', 'SELECTED'),
+        'EXAMINE':      ('AUTH', 'SELECTED'),
+        'EXPUNGE':      ('SELECTED',),
+        'FETCH':        ('SELECTED',),
+        'GETACL':       ('AUTH', 'SELECTED'),
+        'GETANNOTATION':('AUTH', 'SELECTED'),
+        'GETQUOTA':     ('AUTH', 'SELECTED'),
+        'GETQUOTAROOT': ('AUTH', 'SELECTED'),
+        'MYRIGHTS':     ('AUTH', 'SELECTED'),
+        'LIST':         ('AUTH', 'SELECTED'),
+        'LOGIN':        ('NONAUTH',),
+        'LOGOUT':       ('NONAUTH', 'AUTH', 'SELECTED', 'LOGOUT'),
+        'LSUB':         ('AUTH', 'SELECTED'),
+        'NAMESPACE':    ('AUTH', 'SELECTED'),
+        'NOOP':         ('NONAUTH', 'AUTH', 'SELECTED', 'LOGOUT'),
+        'PARTIAL':      ('SELECTED',),                                  # NB: obsolete
+        'PROXYAUTH':    ('AUTH',),
+        'RENAME':       ('AUTH', 'SELECTED'),
+        'SEARCH':       ('SELECTED',),
+        'SELECT':       ('AUTH', 'SELECTED'),
+        'SETACL':       ('AUTH', 'SELECTED'),
+        'SETANNOTATION':('AUTH', 'SELECTED'),
+        'SETQUOTA':     ('AUTH', 'SELECTED'),
+        'SORT':         ('SELECTED',),
+        'STATUS':       ('AUTH', 'SELECTED'),
+        'STORE':        ('SELECTED',),
+        'SUBSCRIBE':    ('AUTH', 'SELECTED'),
+        'THREAD':       ('SELECTED',),
+        'UID':          ('SELECTED',),
+        'UNSUBSCRIBE':  ('AUTH', 'SELECTED'),
+        }
+
+#       Patterns to match server responses
+
+Continuation = re.compile(r'\+( (?P<data>.*))?')
+Flags = re.compile(r'.*FLAGS \((?P<flags>[^\)]*)\)')
+InternalDate = re.compile(r'.*INTERNALDATE "'
+        r'(?P<day>[ 0123][0-9])-(?P<mon>[A-Z][a-z][a-z])-(?P<year>[0-9][0-9][0-9][0-9])'
+        r' (?P<hour>[0-9][0-9]):(?P<min>[0-9][0-9]):(?P<sec>[0-9][0-9])'
+        r' (?P<zonen>[-+])(?P<zoneh>[0-9][0-9])(?P<zonem>[0-9][0-9])'
+        r'"')
+Literal = re.compile(r'.*{(?P<size>\d+)}$')
+MapCRLF = re.compile(r'\r\n|\r|\n')
+Response_code = re.compile(r'\[(?P<type>[A-Z-]+)( (?P<data>[^\]]*))?\]')
+Untagged_response = re.compile(r'\* (?P<type>[A-Z-]+)( (?P<data>.*))?')
+Untagged_status = re.compile(r'\* (?P<data>\d+) (?P<type>[A-Z-]+)( (?P<data2>.*))?')
+
+
+
+class IMAP4:
+
+    """IMAP4 client class.
+
+    Instantiate with: IMAP4([host[, port]])
+
+            host - host's name (default: localhost);
+            port - port number (default: standard IMAP4 port).
+
+    All IMAP4rev1 commands are supported by methods of the same
+    name (in lower-case).
+
+    All arguments to commands are converted to strings, except for
+    AUTHENTICATE, and the last argument to APPEND which is passed as
+    an IMAP4 literal.  If necessary (the string contains any
+    non-printing characters or white-space and isn't enclosed with
+    either parentheses or double quotes) each string is quoted.
+    However, the 'password' argument to the LOGIN command is always
+    quoted.  If you want to avoid having an argument string quoted
+    (eg: the 'flags' argument to STORE) then enclose the string in
+    parentheses (eg: "(\Deleted)").
+
+    Each command returns a tuple: (type, [data, ...]) where 'type'
+    is usually 'OK' or 'NO', and 'data' is either the text from the
+    tagged response, or untagged results from command. Each 'data'
+    is either a string, or a tuple. If a tuple, then the first part
+    is the header of the response, and the second part contains
+    the data (ie: 'literal' value).
+
+    Errors raise the exception class <instance>.error("<reason>").
+    IMAP4 server errors raise <instance>.abort("<reason>"),
+    which is a sub-class of 'error'. Mailbox status changes
+    from READ-WRITE to READ-ONLY raise the exception class
+    <instance>.readonly("<reason>"), which is a sub-class of 'abort'.
+
+    "error" exceptions imply a program error.
+    "abort" exceptions imply the connection should be reset, and
+            the command re-tried.
+    "readonly" exceptions imply the command should be re-tried.
+
+    Note: to use this module, you must read the RFCs pertaining to the
+    IMAP4 protocol, as the semantics of the arguments to each IMAP4
+    command are left to the invoker, not to mention the results. Also,
+    most IMAP servers implement a sub-set of the commands available here.
+    """
+
+    class error(Exception): pass    # Logical errors - debug required
+    class abort(error): pass        # Service errors - close and retry
+    class readonly(abort): pass     # Mailbox status changed to READ-ONLY
+
+    mustquote = re.compile(r"[^\w!#$%&'*+,.:;<=>?^`|~-]")
+
+    def __init__(self, host = '', port = IMAP4_PORT):
+        self.debug = Debug
+        self.state = 'LOGOUT'
+        self.literal = None             # A literal argument to a command
+        self.tagged_commands = {}       # Tagged commands awaiting response
+        self.untagged_responses = {}    # {typ: [data, ...], ...}
+        self.continuation_response = '' # Last continuation response
+        self.is_readonly = False        # READ-ONLY desired state
+        self.tagnum = 0
+
+        # Open socket to server.
+
+        self.open(host, port)
+
+        # Create unique tag for this session,
+        # and compile tagged response matcher.
+
+        self.tagpre = Int2AP(random.randint(4096, 65535))
+        self.tagre = re.compile(r'(?P<tag>'
+                        + self.tagpre
+                        + r'\d+) (?P<type>[A-Z]+) (?P<data>.*)')
+
+        # Get server welcome message,
+        # request and store CAPABILITY response.
+
+        if __debug__:
+            self._cmd_log_len = 10
+            self._cmd_log_idx = 0
+            self._cmd_log = {}           # Last `_cmd_log_len' interactions
+            if self.debug >= 1:
+                self._mesg('imaplib version %s' % __version__)
+                self._mesg('new IMAP4 connection, tag=%s' % self.tagpre)
+
+        self.welcome = self._get_response()
+        if 'PREAUTH' in self.untagged_responses:
+            self.state = 'AUTH'
+        elif 'OK' in self.untagged_responses:
+            self.state = 'NONAUTH'
+        else:
+            raise self.error(self.welcome)
+
+        typ, dat = self.capability()
+        if dat == [None]:
+            raise self.error('no CAPABILITY response from server')
+        self.capabilities = tuple(dat[-1].upper().split())
+
+        if __debug__:
+            if self.debug >= 3:
+                self._mesg('CAPABILITIES: %r' % (self.capabilities,))
+
+        for version in AllowedVersions:
+            if not version in self.capabilities:
+                continue
+            self.PROTOCOL_VERSION = version
+            return
+
+        raise self.error('server not IMAP4 compliant')
+
+
+    def __getattr__(self, attr):
+        #       Allow UPPERCASE variants of IMAP4 command methods.
+        if attr in Commands:
+            return getattr(self, attr.lower())
+        raise AttributeError("Unknown IMAP4 command: '%s'" % attr)
+
+
+
+    #       Overridable methods
+
+
+    def open(self, host = '', port = IMAP4_PORT):
+        """Setup connection to remote server on "host:port"
+            (default: localhost:standard IMAP4 port).
+        This connection will be used by the routines:
+            read, readline, send, shutdown.
+        """
+        self.host = host
+        self.port = port
+        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        self.sock.connect((host, port))
+        self.file = self.sock.makefile('rb')
+
+
+    def read(self, size):
+        """Read 'size' bytes from remote."""
+        return self.file.read(size)
+
+
+    def readline(self):
+        """Read line from remote."""
+        return self.file.readline()
+
+
+    def send(self, data):
+        """Send data to remote."""
+        self.sock.sendall(data)
+
+
+    def shutdown(self):
+        """Close I/O established in "open"."""
+        self.file.close()
+        self.sock.close()
+
+
+    def socket(self):
+        """Return socket instance used to connect to IMAP4 server.
+
+        socket = <instance>.socket()
+        """
+        return self.sock
+
+
+
+    #       Utility methods
+
+
+    def recent(self):
+        """Return most recent 'RECENT' responses if any exist,
+        else prompt server for an update using the 'NOOP' command.
+
+        (typ, [data]) = <instance>.recent()
+
+        'data' is None if no new messages,
+        else list of RECENT responses, most recent last.
+        """
+        name = 'RECENT'
+        typ, dat = self._untagged_response('OK', [None], name)
+        if dat[-1]:
+            return typ, dat
+        typ, dat = self.noop()  # Prod server for response
+        return self._untagged_response(typ, dat, name)
+
+
+    def response(self, code):
+        """Return data for response 'code' if received, or None.
+
+        Old value for response 'code' is cleared.
+
+        (code, [data]) = <instance>.response(code)
+        """
+        return self._untagged_response(code, [None], code.upper())
+
+
+
+    #       IMAP4 commands
+
+
+    def append(self, mailbox, flags, date_time, message):
+        """Append message to named mailbox.
+
+        (typ, [data]) = <instance>.append(mailbox, flags, date_time, message)
+
+                All args except `message' can be None.
+        """
+        name = 'APPEND'
+        if not mailbox:
+            mailbox = 'INBOX'
+        if flags:
+            if (flags[0],flags[-1]) != ('(',')'):
+                flags = '(%s)' % flags
+        else:
+            flags = None
+        if date_time:
+            date_time = Time2Internaldate(date_time)
+        else:
+            date_time = None
+        self.literal = MapCRLF.sub(CRLF, message)
+        return self._simple_command(name, mailbox, flags, date_time)
+
+
+    def authenticate(self, mechanism, authobject):
+        """Authenticate command - requires response processing.
+
+        'mechanism' specifies which authentication mechanism is to
+        be used - it must appear in <instance>.capabilities in the
+        form AUTH=<mechanism>.
+
+        'authobject' must be a callable object:
+
+                data = authobject(response)
+
+        It will be called to process server continuation responses.
+        It should return data that will be encoded and sent to server.
+        It should return None if the client abort response '*' should
+        be sent instead.
+        """
+        mech = mechanism.upper()
+        # XXX: shouldn't this code be removed, not commented out?
+        #cap = 'AUTH=%s' % mech
+        #if not cap in self.capabilities:       # Let the server decide!
+        #    raise self.error("Server doesn't allow %s authentication." % mech)
+        self.literal = _Authenticator(authobject).process
+        typ, dat = self._simple_command('AUTHENTICATE', mech)
+        if typ != 'OK':
+            raise self.error(dat[-1])
+        self.state = 'AUTH'
+        return typ, dat
+
+
+    def capability(self):
+        """(typ, [data]) = <instance>.capability()
+        Fetch capabilities list from server."""
+
+        name = 'CAPABILITY'
+        typ, dat = self._simple_command(name)
+        return self._untagged_response(typ, dat, name)
+
+
+    def check(self):
+        """Checkpoint mailbox on server.
+
+        (typ, [data]) = <instance>.check()
+        """
+        return self._simple_command('CHECK')
+
+
+    def close(self):
+        """Close currently selected mailbox.
+
+        Deleted messages are removed from writable mailbox.
+        This is the recommended command before 'LOGOUT'.
+
+        (typ, [data]) = <instance>.close()
+        """
+        try:
+            typ, dat = self._simple_command('CLOSE')
+        finally:
+            self.state = 'AUTH'
+        return typ, dat
+
+
+    def copy(self, message_set, new_mailbox):
+        """Copy 'message_set' messages onto end of 'new_mailbox'.
+
+        (typ, [data]) = <instance>.copy(message_set, new_mailbox)
+        """
+        return self._simple_command('COPY', message_set, new_mailbox)
+
+
+    def create(self, mailbox):
+        """Create new mailbox.
+
+        (typ, [data]) = <instance>.create(mailbox)
+        """
+        return self._simple_command('CREATE', mailbox)
+
+
+    def delete(self, mailbox):
+        """Delete old mailbox.
+
+        (typ, [data]) = <instance>.delete(mailbox)
+        """
+        return self._simple_command('DELETE', mailbox)
+
+    def deleteacl(self, mailbox, who):
+        """Delete the ACLs (remove any rights) set for who on mailbox.
+
+        (typ, [data]) = <instance>.deleteacl(mailbox, who)
+        """
+        return self._simple_command('DELETEACL', mailbox, who)
+
+    def expunge(self):
+        """Permanently remove deleted items from selected mailbox.
+
+        Generates 'EXPUNGE' response for each deleted message.
+
+        (typ, [data]) = <instance>.expunge()
+
+        'data' is list of 'EXPUNGE'd message numbers in order received.
+        """
+        name = 'EXPUNGE'
+        typ, dat = self._simple_command(name)
+        return self._untagged_response(typ, dat, name)
+
+
+    def fetch(self, message_set, message_parts):
+        """Fetch (parts of) messages.
+
+        (typ, [data, ...]) = <instance>.fetch(message_set, message_parts)
+
+        'message_parts' should be a string of selected parts
+        enclosed in parentheses, eg: "(UID BODY[TEXT])".
+
+        'data' are tuples of message part envelope and data.
+        """
+        name = 'FETCH'
+        typ, dat = self._simple_command(name, message_set, message_parts)
+        return self._untagged_response(typ, dat, name)
+
+
+    def getacl(self, mailbox):
+        """Get the ACLs for a mailbox.
+
+        (typ, [data]) = <instance>.getacl(mailbox)
+        """
+        typ, dat = self._simple_command('GETACL', mailbox)
+        return self._untagged_response(typ, dat, 'ACL')
+
+
+    def getannotation(self, mailbox, entry, attribute):
+        """(typ, [data]) = <instance>.getannotation(mailbox, entry, attribute)
+        Retrieve ANNOTATIONs."""
+
+        typ, dat = self._simple_command('GETANNOTATION', mailbox, entry, attribute)
+        return self._untagged_response(typ, dat, 'ANNOTATION')
+
+
+    def getquota(self, root):
+        """Get the quota root's resource usage and limits.
+
+        Part of the IMAP4 QUOTA extension defined in rfc2087.
+
+        (typ, [data]) = <instance>.getquota(root)
+        """
+        typ, dat = self._simple_command('GETQUOTA', root)
+        return self._untagged_response(typ, dat, 'QUOTA')
+
+
+    def getquotaroot(self, mailbox):
+        """Get the list of quota roots for the named mailbox.
+
+        (typ, [[QUOTAROOT responses...], [QUOTA responses]]) = <instance>.getquotaroot(mailbox)
+        """
+        typ, dat = self._simple_command('GETQUOTAROOT', mailbox)
+        typ, quota = self._untagged_response(typ, dat, 'QUOTA')
+        typ, quotaroot = self._untagged_response(typ, dat, 'QUOTAROOT')
+        return typ, [quotaroot, quota]
+
+
+    def list(self, directory='""', pattern='*'):
+        """List mailbox names in directory matching pattern.
+
+        (typ, [data]) = <instance>.list(directory='""', pattern='*')
+
+        'data' is list of LIST responses.
+        """
+        name = 'LIST'
+        typ, dat = self._simple_command(name, directory, pattern)
+        return self._untagged_response(typ, dat, name)
+
+
+    def login(self, user, password):
+        """Identify client using plaintext password.
+
+        (typ, [data]) = <instance>.login(user, password)
+
+        NB: 'password' will be quoted.
+        """
+        typ, dat = self._simple_command('LOGIN', user, self._quote(password))
+        if typ != 'OK':
+            raise self.error(dat[-1])
+        self.state = 'AUTH'
+        return typ, dat
+
+
+    def login_cram_md5(self, user, password):
+        """ Force use of CRAM-MD5 authentication.
+
+        (typ, [data]) = <instance>.login_cram_md5(user, password)
+        """
+        self.user, self.password = user, password
+        return self.authenticate('CRAM-MD5', self._CRAM_MD5_AUTH)
+
+
+    def _CRAM_MD5_AUTH(self, challenge):
+        """ Authobject to use with CRAM-MD5 authentication. """
+        import hmac
+        return self.user + " " + hmac.HMAC(self.password, challenge).hexdigest()
+
+
+    def logout(self):
+        """Shutdown connection to server.
+
+        (typ, [data]) = <instance>.logout()
+
+        Returns server 'BYE' response.
+        """
+        self.state = 'LOGOUT'
+        try: typ, dat = self._simple_command('LOGOUT')
+        except: typ, dat = 'NO', ['%s: %s' % sys.exc_info()[:2]]
+        self.shutdown()
+        if 'BYE' in self.untagged_responses:
+            return 'BYE', self.untagged_responses['BYE']
+        return typ, dat
+
+
+    def lsub(self, directory='""', pattern='*'):
+        """List 'subscribed' mailbox names in directory matching pattern.
+
+        (typ, [data, ...]) = <instance>.lsub(directory='""', pattern='*')
+
+        'data' are tuples of message part envelope and data.
+        """
+        name = 'LSUB'
+        typ, dat = self._simple_command(name, directory, pattern)
+        return self._untagged_response(typ, dat, name)
+
+    def myrights(self, mailbox):
+        """Show my ACLs for a mailbox (i.e. the rights that I have on mailbox).
+
+        (typ, [data]) = <instance>.myrights(mailbox)
+        """
+        typ,dat = self._simple_command('MYRIGHTS', mailbox)
+        return self._untagged_response(typ, dat, 'MYRIGHTS')
+
+    def namespace(self):
+        """ Returns IMAP namespaces ala rfc2342
+
+        (typ, [data, ...]) = <instance>.namespace()
+        """
+        name = 'NAMESPACE'
+        typ, dat = self._simple_command(name)
+        return self._untagged_response(typ, dat, name)
+
+
+    def noop(self):
+        """Send NOOP command.
+
+        (typ, [data]) = <instance>.noop()
+        """
+        if __debug__:
+            if self.debug >= 3:
+                self._dump_ur(self.untagged_responses)
+        return self._simple_command('NOOP')
+
+
+    def partial(self, message_num, message_part, start, length):
+        """Fetch truncated part of a message.
+
+        (typ, [data, ...]) = <instance>.partial(message_num, message_part, start, length)
+
+        'data' is tuple of message part envelope and data.
+        """
+        name = 'PARTIAL'
+        typ, dat = self._simple_command(name, message_num, message_part, start, length)
+        return self._untagged_response(typ, dat, 'FETCH')
+
+
+    def proxyauth(self, user):
+        """Assume authentication as "user".
+
+        Allows an authorised administrator to proxy into any user's
+        mailbox.
+
+        (typ, [data]) = <instance>.proxyauth(user)
+        """
+
+        name = 'PROXYAUTH'
+        return self._simple_command('PROXYAUTH', user)
+
+
+    def rename(self, oldmailbox, newmailbox):
+        """Rename old mailbox name to new.
+
+        (typ, [data]) = <instance>.rename(oldmailbox, newmailbox)
+        """
+        return self._simple_command('RENAME', oldmailbox, newmailbox)
+
+
+    def search(self, charset, *criteria):
+        """Search mailbox for matching messages.
+
+        (typ, [data]) = <instance>.search(charset, criterion, ...)
+
+        'data' is space separated list of matching message numbers.
+        """
+        name = 'SEARCH'
+        if charset:
+            typ, dat = self._simple_command(name, 'CHARSET', charset, *criteria)
+        else:
+            typ, dat = self._simple_command(name, *criteria)
+        return self._untagged_response(typ, dat, name)
+
+
+    def select(self, mailbox='INBOX', readonly=False):
+        """Select a mailbox.
+
+        Flush all untagged responses.
+
+        (typ, [data]) = <instance>.select(mailbox='INBOX', readonly=False)
+
+        'data' is count of messages in mailbox ('EXISTS' response).
+
+        Mandated responses are ('FLAGS', 'EXISTS', 'RECENT', 'UIDVALIDITY'), so
+        other responses should be obtained via <instance>.response('FLAGS') etc.
+        """
+        self.untagged_responses = {}    # Flush old responses.
+        self.is_readonly = readonly
+        if readonly:
+            name = 'EXAMINE'
+        else:
+            name = 'SELECT'
+        typ, dat = self._simple_command(name, mailbox)
+        if typ != 'OK':
+            self.state = 'AUTH'     # Might have been 'SELECTED'
+            return typ, dat
+        self.state = 'SELECTED'
+        if 'READ-ONLY' in self.untagged_responses \
+                and not readonly:
+            if __debug__:
+                if self.debug >= 1:
+                    self._dump_ur(self.untagged_responses)
+            raise self.readonly('%s is not writable' % mailbox)
+        return typ, self.untagged_responses.get('EXISTS', [None])
+
+
+    def setacl(self, mailbox, who, what):
+        """Set a mailbox acl.
+
+        (typ, [data]) = <instance>.setacl(mailbox, who, what)
+        """
+        return self._simple_command('SETACL', mailbox, who, what)
+
+
+    def setannotation(self, *args):
+        """(typ, [data]) = <instance>.setannotation(mailbox[, entry, attribute]+)
+        Set ANNOTATIONs."""
+
+        typ, dat = self._simple_command('SETANNOTATION', *args)
+        return self._untagged_response(typ, dat, 'ANNOTATION')
+
+
+    def setquota(self, root, limits):
+        """Set the quota root's resource limits.
+
+        (typ, [data]) = <instance>.setquota(root, limits)
+        """
+        typ, dat = self._simple_command('SETQUOTA', root, limits)
+        return self._untagged_response(typ, dat, 'QUOTA')
+
+
+    def sort(self, sort_criteria, charset, *search_criteria):
+        """IMAP4rev1 extension SORT command.
+
+        (typ, [data]) = <instance>.sort(sort_criteria, charset, search_criteria, ...)
+        """
+        name = 'SORT'
+        #if not name in self.capabilities:      # Let the server decide!
+        #       raise self.error('unimplemented extension command: %s' % name)
+        if (sort_criteria[0],sort_criteria[-1]) != ('(',')'):
+            sort_criteria = '(%s)' % sort_criteria
+        typ, dat = self._simple_command(name, sort_criteria, charset, *search_criteria)
+        return self._untagged_response(typ, dat, name)
+
+
+    def status(self, mailbox, names):
+        """Request named status conditions for mailbox.
+
+        (typ, [data]) = <instance>.status(mailbox, names)
+        """
+        name = 'STATUS'
+        #if self.PROTOCOL_VERSION == 'IMAP4':   # Let the server decide!
+        #    raise self.error('%s unimplemented in IMAP4 (obtain IMAP4rev1 server, or re-code)' % name)
+        typ, dat = self._simple_command(name, mailbox, names)
+        return self._untagged_response(typ, dat, name)
+
+
+    def store(self, message_set, command, flags):
+        """Alters flag dispositions for messages in mailbox.
+
+        (typ, [data]) = <instance>.store(message_set, command, flags)
+        """
+        if (flags[0],flags[-1]) != ('(',')'):
+            flags = '(%s)' % flags  # Avoid quoting the flags
+        typ, dat = self._simple_command('STORE', message_set, command, flags)
+        return self._untagged_response(typ, dat, 'FETCH')
+
+
+    def subscribe(self, mailbox):
+        """Subscribe to new mailbox.
+
+        (typ, [data]) = <instance>.subscribe(mailbox)
+        """
+        return self._simple_command('SUBSCRIBE', mailbox)
+
+
+    def thread(self, threading_algorithm, charset, *search_criteria):
+        """IMAPrev1 extension THREAD command.
+
+        (type, [data]) = <instance>.thread(threading_alogrithm, charset, search_criteria, ...)
+        """
+        name = 'THREAD'
+        typ, dat = self._simple_command(name, threading_algorithm, charset, *search_criteria)
+        return self._untagged_response(typ, dat, name)
+
+
+    def uid(self, command, *args):
+        """Execute "command arg ..." with messages identified by UID,
+                rather than message number.
+
+        (typ, [data]) = <instance>.uid(command, arg1, arg2, ...)
+
+        Returns response appropriate to 'command'.
+        """
+        command = command.upper()
+        if not command in Commands:
+            raise self.error("Unknown IMAP4 UID command: %s" % command)
+        if self.state not in Commands[command]:
+            raise self.error('command %s illegal in state %s'
+                                    % (command, self.state))
+        name = 'UID'
+        typ, dat = self._simple_command(name, command, *args)
+        if command in ('SEARCH', 'SORT'):
+            name = command
+        else:
+            name = 'FETCH'
+        return self._untagged_response(typ, dat, name)
+
+
+    def unsubscribe(self, mailbox):
+        """Unsubscribe from old mailbox.
+
+        (typ, [data]) = <instance>.unsubscribe(mailbox)
+        """
+        return self._simple_command('UNSUBSCRIBE', mailbox)
+
+
+    def xatom(self, name, *args):
+        """Allow simple extension commands
+                notified by server in CAPABILITY response.
+
+        Assumes command is legal in current state.
+
+        (typ, [data]) = <instance>.xatom(name, arg, ...)
+
+        Returns response appropriate to extension command `name'.
+        """
+        name = name.upper()
+        #if not name in self.capabilities:      # Let the server decide!
+        #    raise self.error('unknown extension command: %s' % name)
+        if not name in Commands:
+            Commands[name] = (self.state,)
+        return self._simple_command(name, *args)
+
+
+
+    #       Private methods
+
+
+    def _append_untagged(self, typ, dat):
+
+        if dat is None: dat = ''
+        ur = self.untagged_responses
+        if __debug__:
+            if self.debug >= 5:
+                self._mesg('untagged_responses[%s] %s += ["%s"]' %
+                        (typ, len(ur.get(typ,'')), dat))
+        if typ in ur:
+            ur[typ].append(dat)
+        else:
+            ur[typ] = [dat]
+
+
+    def _check_bye(self):
+        bye = self.untagged_responses.get('BYE')
+        if bye:
+            raise self.abort(bye[-1])
+
+
+    def _command(self, name, *args):
+
+        if self.state not in Commands[name]:
+            self.literal = None
+            raise self.error(
+            'command %s illegal in state %s' % (name, self.state))
+
+        for typ in ('OK', 'NO', 'BAD'):
+            if typ in self.untagged_responses:
+                del self.untagged_responses[typ]
+
+        if 'READ-ONLY' in self.untagged_responses \
+        and not self.is_readonly:
+            raise self.readonly('mailbox status changed to READ-ONLY')
+
+        tag = self._new_tag()
+        data = '%s %s' % (tag, name)
+        for arg in args:
+            if arg is None: continue
+            data = '%s %s' % (data, self._checkquote(arg))
+
+        literal = self.literal
+        if literal is not None:
+            self.literal = None
+            if type(literal) is type(self._command):
+                literator = literal
+            else:
+                literator = None
+                data = '%s {%s}' % (data, len(literal))
+
+        if __debug__:
+            if self.debug >= 4:
+                self._mesg('> %s' % data)
+            else:
+                self._log('> %s' % data)
+
+        try:
+            self.send('%s%s' % (data, CRLF))
+        except (socket.error, OSError), val:
+            raise self.abort('socket error: %s' % val)
+
+        if literal is None:
+            return tag
+
+        while 1:
+            # Wait for continuation response
+
+            while self._get_response():
+                if self.tagged_commands[tag]:   # BAD/NO?
+                    return tag
+
+            # Send literal
+
+            if literator:
+                literal = literator(self.continuation_response)
+
+            if __debug__:
+                if self.debug >= 4:
+                    self._mesg('write literal size %s' % len(literal))
+
+            try:
+                self.send(literal)
+                self.send(CRLF)
+            except (socket.error, OSError), val:
+                raise self.abort('socket error: %s' % val)
+
+            if not literator:
+                break
+
+        return tag
+
+
+    def _command_complete(self, name, tag):
+        self._check_bye()
+        try:
+            typ, data = self._get_tagged_response(tag)
+        except self.abort, val:
+            raise self.abort('command: %s => %s' % (name, val))
+        except self.error, val:
+            raise self.error('command: %s => %s' % (name, val))
+        self._check_bye()
+        if typ == 'BAD':
+            raise self.error('%s command error: %s %s' % (name, typ, data))
+        return typ, data
+
+
+    def _get_response(self):
+
+        # Read response and store.
+        #
+        # Returns None for continuation responses,
+        # otherwise first response line received.
+
+        resp = self._get_line()
+
+        # Command completion response?
+
+        if self._match(self.tagre, resp):
+            tag = self.mo.group('tag')
+            if not tag in self.tagged_commands:
+                raise self.abort('unexpected tagged response: %s' % resp)
+
+            typ = self.mo.group('type')
+            dat = self.mo.group('data')
+            self.tagged_commands[tag] = (typ, [dat])
+        else:
+            dat2 = None
+
+            # '*' (untagged) responses?
+
+            if not self._match(Untagged_response, resp):
+                if self._match(Untagged_status, resp):
+                    dat2 = self.mo.group('data2')
+
+            if self.mo is None:
+                # Only other possibility is '+' (continuation) response...
+
+                if self._match(Continuation, resp):
+                    self.continuation_response = self.mo.group('data')
+                    return None     # NB: indicates continuation
+
+                raise self.abort("unexpected response: '%s'" % resp)
+
+            typ = self.mo.group('type')
+            dat = self.mo.group('data')
+            if dat is None: dat = ''        # Null untagged response
+            if dat2: dat = dat + ' ' + dat2
+
+            # Is there a literal to come?
+
+            while self._match(Literal, dat):
+
+                # Read literal direct from connection.
+
+                size = int(self.mo.group('size'))
+                if __debug__:
+                    if self.debug >= 4:
+                        self._mesg('read literal size %s' % size)
+                data = self.read(size)
+
+                # Store response with literal as tuple
+
+                self._append_untagged(typ, (dat, data))
+
+                # Read trailer - possibly containing another literal
+
+                dat = self._get_line()
+
+            self._append_untagged(typ, dat)
+
+        # Bracketed response information?
+
+        if typ in ('OK', 'NO', 'BAD') and self._match(Response_code, dat):
+            self._append_untagged(self.mo.group('type'), self.mo.group('data'))
+
+        if __debug__:
+            if self.debug >= 1 and typ in ('NO', 'BAD', 'BYE'):
+                self._mesg('%s response: %s' % (typ, dat))
+
+        return resp
+
+
+    def _get_tagged_response(self, tag):
+
+        while 1:
+            result = self.tagged_commands[tag]
+            if result is not None:
+                del self.tagged_commands[tag]
+                return result
+
+            # Some have reported "unexpected response" exceptions.
+            # Note that ignoring them here causes loops.
+            # Instead, send me details of the unexpected response and
+            # I'll update the code in `_get_response()'.
+
+            try:
+                self._get_response()
+            except self.abort, val:
+                if __debug__:
+                    if self.debug >= 1:
+                        self.print_log()
+                raise
+
+
+    def _get_line(self):
+
+        line = self.readline()
+        if not line:
+            raise self.abort('socket error: EOF')
+
+        # Protocol mandates all lines terminated by CRLF
+
+        line = line[:-2]
+        if __debug__:
+            if self.debug >= 4:
+                self._mesg('< %s' % line)
+            else:
+                self._log('< %s' % line)
+        return line
+
+
+    def _match(self, cre, s):
+
+        # Run compiled regular expression match method on 's'.
+        # Save result, return success.
+
+        self.mo = cre.match(s)
+        if __debug__:
+            if self.mo is not None and self.debug >= 5:
+                self._mesg("\tmatched r'%s' => %r" % (cre.pattern, self.mo.groups()))
+        return self.mo is not None
+
+
+    def _new_tag(self):
+
+        tag = '%s%s' % (self.tagpre, self.tagnum)
+        self.tagnum = self.tagnum + 1
+        self.tagged_commands[tag] = None
+        return tag
+
+
+    def _checkquote(self, arg):
+
+        # Must quote command args if non-alphanumeric chars present,
+        # and not already quoted.
+
+        if type(arg) is not type(''):
+            return arg
+        if len(arg) >= 2 and (arg[0],arg[-1]) in (('(',')'),('"','"')):
+            return arg
+        if arg and self.mustquote.search(arg) is None:
+            return arg
+        return self._quote(arg)
+
+
+    def _quote(self, arg):
+
+        arg = arg.replace('\\', '\\\\')
+        arg = arg.replace('"', '\\"')
+
+        return '"%s"' % arg
+
+
+    def _simple_command(self, name, *args):
+
+        return self._command_complete(name, self._command(name, *args))
+
+
+    def _untagged_response(self, typ, dat, name):
+
+        if typ == 'NO':
+            return typ, dat
+        if not name in self.untagged_responses:
+            return typ, [None]
+        data = self.untagged_responses.pop(name)
+        if __debug__:
+            if self.debug >= 5:
+                self._mesg('untagged_responses[%s] => %s' % (name, data))
+        return typ, data
+
+
+    if __debug__:
+
+        def _mesg(self, s, secs=None):
+            if secs is None:
+                secs = time.time()
+            tm = time.strftime('%M:%S', time.localtime(secs))
+            sys.stderr.write('  %s.%02d %s\n' % (tm, (secs*100)%100, s))
+            sys.stderr.flush()
+
+        def _dump_ur(self, dict):
+            # Dump untagged responses (in `dict').
+            l = dict.items()
+            if not l: return
+            t = '\n\t\t'
+            l = map(lambda x:'%s: "%s"' % (x[0], x[1][0] and '" "'.join(x[1]) or ''), l)
+            self._mesg('untagged responses dump:%s%s' % (t, t.join(l)))
+
+        def _log(self, line):
+            # Keep log of last `_cmd_log_len' interactions for debugging.
+            self._cmd_log[self._cmd_log_idx] = (line, time.time())
+            self._cmd_log_idx += 1
+            if self._cmd_log_idx >= self._cmd_log_len:
+                self._cmd_log_idx = 0
+
+        def print_log(self):
+            self._mesg('last %d IMAP4 interactions:' % len(self._cmd_log))
+            i, n = self._cmd_log_idx, self._cmd_log_len
+            while n:
+                try:
+                    self._mesg(*self._cmd_log[i])
+                except:
+                    pass
+                i += 1
+                if i >= self._cmd_log_len:
+                    i = 0
+                n -= 1
+
+
+
+class IMAP4_SSL(IMAP4):
+
+    """IMAP4 client class over SSL connection
+
+    Instantiate with: IMAP4_SSL([host[, port[, keyfile[, certfile]]]])
+
+            host - host's name (default: localhost);
+            port - port number (default: standard IMAP4 SSL port).
+            keyfile - PEM formatted file that contains your private key (default: None);
+            certfile - PEM formatted certificate chain file (default: None);
+
+    for more documentation see the docstring of the parent class IMAP4.
+    """
+
+
+    def __init__(self, host = '', port = IMAP4_SSL_PORT, keyfile = None, certfile = None):
+        self.keyfile = keyfile
+        self.certfile = certfile
+        IMAP4.__init__(self, host, port)
+
+
+    def open(self, host = '', port = IMAP4_SSL_PORT):
+        """Setup connection to remote server on "host:port".
+            (default: localhost:standard IMAP4 SSL port).
+        This connection will be used by the routines:
+            read, readline, send, shutdown.
+        """
+        self.host = host
+        self.port = port
+        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        self.sock.connect((host, port))
+        self.sslobj = socket.ssl(self.sock, self.keyfile, self.certfile)
+
+
+    def read(self, size):
+        """Read 'size' bytes from remote."""
+        # sslobj.read() sometimes returns < size bytes
+        chunks = []
+        read = 0
+        while read < size:
+            data = self.sslobj.read(size-read)
+            read += len(data)
+            chunks.append(data)
+
+        return ''.join(chunks)
+
+
+    def readline(self):
+        """Read line from remote."""
+        # NB: socket.ssl needs a "readline" method, or perhaps a "makefile" method.
+        line = []
+        while 1:
+            char = self.sslobj.read(1)
+            line.append(char)
+            if char == "\n": return ''.join(line)
+
+
+    def send(self, data):
+        """Send data to remote."""
+        # NB: socket.ssl needs a "sendall" method to match socket objects.
+        bytes = len(data)
+        while bytes > 0:
+            sent = self.sslobj.write(data)
+            if sent == bytes:
+                break    # avoid copy
+            data = data[sent:]
+            bytes = bytes - sent
+
+
+    def shutdown(self):
+        """Close I/O established in "open"."""
+        self.sock.close()
+
+
+    def socket(self):
+        """Return socket instance used to connect to IMAP4 server.
+
+        socket = <instance>.socket()
+        """
+        return self.sock
+
+
+    def ssl(self):
+        """Return SSLObject instance used to communicate with the IMAP4 server.
+
+        ssl = <instance>.socket.ssl()
+        """
+        return self.sslobj
+
+
+
+class IMAP4_stream(IMAP4):
+
+    """IMAP4 client class over a stream
+
+    Instantiate with: IMAP4_stream(command)
+
+            where "command" is a string that can be passed to os.popen2()
+
+    for more documentation see the docstring of the parent class IMAP4.
+    """
+
+
+    def __init__(self, command):
+        self.command = command
+        IMAP4.__init__(self)
+
+
+    def open(self, host = None, port = None):
+        """Setup a stream connection.
+        This connection will be used by the routines:
+            read, readline, send, shutdown.
+        """
+        self.host = None        # For compatibility with parent class
+        self.port = None
+        self.sock = None
+        self.file = None
+        self.writefile, self.readfile = os.popen2(self.command)
+
+
+    def read(self, size):
+        """Read 'size' bytes from remote."""
+        return self.readfile.read(size)
+
+
+    def readline(self):
+        """Read line from remote."""
+        return self.readfile.readline()
+
+
+    def send(self, data):
+        """Send data to remote."""
+        self.writefile.write(data)
+        self.writefile.flush()
+
+
+    def shutdown(self):
+        """Close I/O established in "open"."""
+        self.readfile.close()
+        self.writefile.close()
+
+
+
+class _Authenticator:
+
+    """Private class to provide en/decoding
+            for base64-based authentication conversation.
+    """
+
+    def __init__(self, mechinst):
+        self.mech = mechinst    # Callable object to provide/process data
+
+    def process(self, data):
+        ret = self.mech(self.decode(data))
+        if ret is None:
+            return '*'      # Abort conversation
+        return self.encode(ret)
+
+    def encode(self, inp):
+        #
+        #  Invoke binascii.b2a_base64 iteratively with
+        #  short even length buffers, strip the trailing
+        #  line feed from the result and append.  "Even"
+        #  means a number that factors to both 6 and 8,
+        #  so when it gets to the end of the 8-bit input
+        #  there's no partial 6-bit output.
+        #
+        oup = ''
+        while inp:
+            if len(inp) > 48:
+                t = inp[:48]
+                inp = inp[48:]
+            else:
+                t = inp
+                inp = ''
+            e = binascii.b2a_base64(t)
+            if e:
+                oup = oup + e[:-1]
+        return oup
+
+    def decode(self, inp):
+        if not inp:
+            return ''
+        return binascii.a2b_base64(inp)
+
+
+
+Mon2num = {'Jan': 1, 'Feb': 2, 'Mar': 3, 'Apr': 4, 'May': 5, 'Jun': 6,
+        'Jul': 7, 'Aug': 8, 'Sep': 9, 'Oct': 10, 'Nov': 11, 'Dec': 12}
+
+def Internaldate2tuple(resp):
+    """Convert IMAP4 INTERNALDATE to UT.
+
+    Returns Python time module tuple.
+    """
+
+    mo = InternalDate.match(resp)
+    if not mo:
+        return None
+
+    mon = Mon2num[mo.group('mon')]
+    zonen = mo.group('zonen')
+
+    day = int(mo.group('day'))
+    year = int(mo.group('year'))
+    hour = int(mo.group('hour'))
+    min = int(mo.group('min'))
+    sec = int(mo.group('sec'))
+    zoneh = int(mo.group('zoneh'))
+    zonem = int(mo.group('zonem'))
+
+    # INTERNALDATE timezone must be subtracted to get UT
+
+    zone = (zoneh*60 + zonem)*60
+    if zonen == '-':
+        zone = -zone
+
+    tt = (year, mon, day, hour, min, sec, -1, -1, -1)
+
+    utc = time.mktime(tt)
+
+    # Following is necessary because the time module has no 'mkgmtime'.
+    # 'mktime' assumes arg in local timezone, so adds timezone/altzone.
+
+    lt = time.localtime(utc)
+    if time.daylight and lt[-1]:
+        zone = zone + time.altzone
+    else:
+        zone = zone + time.timezone
+
+    return time.localtime(utc - zone)
+
+
+
+def Int2AP(num):
+
+    """Convert integer to A-P string representation."""
+
+    val = ''; AP = 'ABCDEFGHIJKLMNOP'
+    num = int(abs(num))
+    while num:
+        num, mod = divmod(num, 16)
+        val = AP[mod] + val
+    return val
+
+
+
+def ParseFlags(resp):
+
+    """Convert IMAP4 flags response to python tuple."""
+
+    mo = Flags.match(resp)
+    if not mo:
+        return ()
+
+    return tuple(mo.group('flags').split())
+
+
+def Time2Internaldate(date_time):
+
+    """Convert 'date_time' to IMAP4 INTERNALDATE representation.
+
+    Return string in form: '"DD-Mmm-YYYY HH:MM:SS +HHMM"'
+    """
+
+    if isinstance(date_time, (int, float)):
+        tt = time.localtime(date_time)
+    elif isinstance(date_time, (tuple, time.struct_time)):
+        tt = date_time
+    elif isinstance(date_time, str) and (date_time[0],date_time[-1]) == ('"','"'):
+        return date_time        # Assume in correct format
+    else:
+        raise ValueError("date_time not of a known type")
+
+    dt = time.strftime("%d-%b-%Y %H:%M:%S", tt)
+    if dt[0] == '0':
+        dt = ' ' + dt[1:]
+    if time.daylight and tt[-1]:
+        zone = -time.altzone
+    else:
+        zone = -time.timezone
+    return '"' + dt + " %+03d%02d" % divmod(zone//60, 60) + '"'
+
+
+
+if __name__ == '__main__':
+
+    # To test: invoke either as 'python imaplib.py [IMAP4_server_hostname]'
+    # or 'python imaplib.py -s "rsh IMAP4_server_hostname exec /etc/rimapd"'
+    # to test the IMAP4_stream class
+
+    import getopt, getpass
+
+    try:
+        optlist, args = getopt.getopt(sys.argv[1:], 'd:s:')
+    except getopt.error, val:
+        optlist, args = (), ()
+
+    stream_command = None
+    for opt,val in optlist:
+        if opt == '-d':
+            Debug = int(val)
+        elif opt == '-s':
+            stream_command = val
+            if not args: args = (stream_command,)
+
+    if not args: args = ('',)
+
+    host = args[0]
+
+    USER = getpass.getuser()
+    PASSWD = getpass.getpass("IMAP password for %s on %s: " % (USER, host or "localhost"))
+
+    test_mesg = 'From: %(user)s at localhost%(lf)sSubject: IMAP4 test%(lf)s%(lf)sdata...%(lf)s' % {'user':USER, 'lf':'\n'}
+    test_seq1 = (
+    ('login', (USER, PASSWD)),
+    ('create', ('/tmp/xxx 1',)),
+    ('rename', ('/tmp/xxx 1', '/tmp/yyy')),
+    ('CREATE', ('/tmp/yyz 2',)),
+    ('append', ('/tmp/yyz 2', None, None, test_mesg)),
+    ('list', ('/tmp', 'yy*')),
+    ('select', ('/tmp/yyz 2',)),
+    ('search', (None, 'SUBJECT', 'test')),
+    ('fetch', ('1', '(FLAGS INTERNALDATE RFC822)')),
+    ('store', ('1', 'FLAGS', '(\Deleted)')),
+    ('namespace', ()),
+    ('expunge', ()),
+    ('recent', ()),
+    ('close', ()),
+    )
+
+    test_seq2 = (
+    ('select', ()),
+    ('response',('UIDVALIDITY',)),
+    ('uid', ('SEARCH', 'ALL')),
+    ('response', ('EXISTS',)),
+    ('append', (None, None, None, test_mesg)),
+    ('recent', ()),
+    ('logout', ()),
+    )
+
+    def run(cmd, args):
+        M._mesg('%s %s' % (cmd, args))
+        typ, dat = getattr(M, cmd)(*args)
+        M._mesg('%s => %s %s' % (cmd, typ, dat))
+        if typ == 'NO': raise dat[0]
+        return dat
+
+    try:
+        if stream_command:
+            M = IMAP4_stream(stream_command)
+        else:
+            M = IMAP4(host)
+        if M.state == 'AUTH':
+            test_seq1 = test_seq1[1:]   # Login not needed
+        M._mesg('PROTOCOL_VERSION = %s' % M.PROTOCOL_VERSION)
+        M._mesg('CAPABILITIES = %r' % (M.capabilities,))
+
+        for cmd,args in test_seq1:
+            run(cmd, args)
+
+        for ml in run('list', ('/tmp/', 'yy%')):
+            mo = re.match(r'.*"([^"]+)"$', ml)
+            if mo: path = mo.group(1)
+            else: path = ml.split()[-1]
+            run('delete', (path,))
+
+        for cmd,args in test_seq2:
+            dat = run(cmd, args)
+
+            if (cmd,args) != ('uid', ('SEARCH', 'ALL')):
+                continue
+
+            uid = dat[-1].split()
+            if not uid: continue
+            run('uid', ('FETCH', '%s' % uid[-1],
+                    '(FLAGS INTERNALDATE RFC822.SIZE RFC822.HEADER RFC822.TEXT)'))
+
+        print '\nAll tests OK.'
+
+    except:
+        print '\nTests failed.'
+
+        if not Debug:
+            print '''
+If you would like to see debugging output,
+try: %s -d5
+''' % sys.argv[0]
+
+        raise

Added: vendor/Python/current/Lib/imghdr.py
===================================================================
--- vendor/Python/current/Lib/imghdr.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/imghdr.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,161 @@
+"""Recognize image file formats based on their first few bytes."""
+
+__all__ = ["what"]
+
+#-------------------------#
+# Recognize image headers #
+#-------------------------#
+
+def what(file, h=None):
+    if h is None:
+        if type(file) == type(''):
+            f = open(file, 'rb')
+            h = f.read(32)
+        else:
+            location = file.tell()
+            h = file.read(32)
+            file.seek(location)
+            f = None
+    else:
+        f = None
+    try:
+        for tf in tests:
+            res = tf(h, f)
+            if res:
+                return res
+    finally:
+        if f: f.close()
+    return None
+
+
+#---------------------------------#
+# Subroutines per image file type #
+#---------------------------------#
+
+tests = []
+
+def test_rgb(h, f):
+    """SGI image library"""
+    if h[:2] == '\001\332':
+        return 'rgb'
+
+tests.append(test_rgb)
+
+def test_gif(h, f):
+    """GIF ('87 and '89 variants)"""
+    if h[:6] in ('GIF87a', 'GIF89a'):
+        return 'gif'
+
+tests.append(test_gif)
+
+def test_pbm(h, f):
+    """PBM (portable bitmap)"""
+    if len(h) >= 3 and \
+        h[0] == 'P' and h[1] in '14' and h[2] in ' \t\n\r':
+        return 'pbm'
+
+tests.append(test_pbm)
+
+def test_pgm(h, f):
+    """PGM (portable graymap)"""
+    if len(h) >= 3 and \
+        h[0] == 'P' and h[1] in '25' and h[2] in ' \t\n\r':
+        return 'pgm'
+
+tests.append(test_pgm)
+
+def test_ppm(h, f):
+    """PPM (portable pixmap)"""
+    if len(h) >= 3 and \
+        h[0] == 'P' and h[1] in '36' and h[2] in ' \t\n\r':
+        return 'ppm'
+
+tests.append(test_ppm)
+
+def test_tiff(h, f):
+    """TIFF (can be in Motorola or Intel byte order)"""
+    if h[:2] in ('MM', 'II'):
+        return 'tiff'
+
+tests.append(test_tiff)
+
+def test_rast(h, f):
+    """Sun raster file"""
+    if h[:4] == '\x59\xA6\x6A\x95':
+        return 'rast'
+
+tests.append(test_rast)
+
+def test_xbm(h, f):
+    """X bitmap (X10 or X11)"""
+    s = '#define '
+    if h[:len(s)] == s:
+        return 'xbm'
+
+tests.append(test_xbm)
+
+def test_jpeg(h, f):
+    """JPEG data in JFIF format"""
+    if h[6:10] == 'JFIF':
+        return 'jpeg'
+
+tests.append(test_jpeg)
+
+def test_exif(h, f):
+    """JPEG data in Exif format"""
+    if h[6:10] == 'Exif':
+        return 'jpeg'
+
+tests.append(test_exif)
+
+def test_bmp(h, f):
+    if h[:2] == 'BM':
+        return 'bmp'
+
+tests.append(test_bmp)
+
+def test_png(h, f):
+    if h[:8] == "\211PNG\r\n\032\n":
+        return 'png'
+
+tests.append(test_png)
+
+#--------------------#
+# Small test program #
+#--------------------#
+
+def test():
+    import sys
+    recursive = 0
+    if sys.argv[1:] and sys.argv[1] == '-r':
+        del sys.argv[1:2]
+        recursive = 1
+    try:
+        if sys.argv[1:]:
+            testall(sys.argv[1:], recursive, 1)
+        else:
+            testall(['.'], recursive, 1)
+    except KeyboardInterrupt:
+        sys.stderr.write('\n[Interrupted]\n')
+        sys.exit(1)
+
+def testall(list, recursive, toplevel):
+    import sys
+    import os
+    for filename in list:
+        if os.path.isdir(filename):
+            print filename + '/:',
+            if recursive or toplevel:
+                print 'recursing down:'
+                import glob
+                names = glob.glob(os.path.join(filename, '*'))
+                testall(names, recursive, 0)
+            else:
+                print '*** directory (use -r) ***'
+        else:
+            print filename + ':',
+            sys.stdout.flush()
+            try:
+                print what(filename)
+            except IOError:
+                print '*** not found ***'

Added: vendor/Python/current/Lib/imputil.py
===================================================================
--- vendor/Python/current/Lib/imputil.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/imputil.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,731 @@
+"""
+Import utilities
+
+Exported classes:
+    ImportManager   Manage the import process
+
+    Importer        Base class for replacing standard import functions
+    BuiltinImporter Emulate the import mechanism for builtin and frozen modules
+
+    DynLoadSuffixImporter
+"""
+
+# note: avoid importing non-builtin modules
+import imp                      ### not available in JPython?
+import sys
+import __builtin__
+
+# for the DirectoryImporter
+import struct
+import marshal
+
+__all__ = ["ImportManager","Importer","BuiltinImporter"]
+
+_StringType = type('')
+_ModuleType = type(sys)         ### doesn't work in JPython...
+
+class ImportManager:
+    "Manage the import process."
+
+    def install(self, namespace=vars(__builtin__)):
+        "Install this ImportManager into the specified namespace."
+
+        if isinstance(namespace, _ModuleType):
+            namespace = vars(namespace)
+
+        # Note: we have no notion of "chaining"
+
+        # Record the previous import hook, then install our own.
+        self.previous_importer = namespace['__import__']
+        self.namespace = namespace
+        namespace['__import__'] = self._import_hook
+
+        ### fix this
+        #namespace['reload'] = self._reload_hook
+
+    def uninstall(self):
+        "Restore the previous import mechanism."
+        self.namespace['__import__'] = self.previous_importer
+
+    def add_suffix(self, suffix, importFunc):
+        assert callable(importFunc)
+        self.fs_imp.add_suffix(suffix, importFunc)
+
+    ######################################################################
+    #
+    # PRIVATE METHODS
+    #
+
+    clsFilesystemImporter = None
+
+    def __init__(self, fs_imp=None):
+        # we're definitely going to be importing something in the future,
+        # so let's just load the OS-related facilities.
+        if not _os_stat:
+            _os_bootstrap()
+
+        # This is the Importer that we use for grabbing stuff from the
+        # filesystem. It defines one more method (import_from_dir) for our use.
+        if fs_imp is None:
+            cls = self.clsFilesystemImporter or _FilesystemImporter
+            fs_imp = cls()
+        self.fs_imp = fs_imp
+
+        # Initialize the set of suffixes that we recognize and import.
+        # The default will import dynamic-load modules first, followed by
+        # .py files (or a .py file's cached bytecode)
+        for desc in imp.get_suffixes():
+            if desc[2] == imp.C_EXTENSION:
+                self.add_suffix(desc[0],
+                                DynLoadSuffixImporter(desc).import_file)
+        self.add_suffix('.py', py_suffix_importer)
+
+    def _import_hook(self, fqname, globals=None, locals=None, fromlist=None):
+        """Python calls this hook to locate and import a module."""
+
+        parts = fqname.split('.')
+
+        # determine the context of this import
+        parent = self._determine_import_context(globals)
+
+        # if there is a parent, then its importer should manage this import
+        if parent:
+            module = parent.__importer__._do_import(parent, parts, fromlist)
+            if module:
+                return module
+
+        # has the top module already been imported?
+        try:
+            top_module = sys.modules[parts[0]]
+        except KeyError:
+
+            # look for the topmost module
+            top_module = self._import_top_module(parts[0])
+            if not top_module:
+                # the topmost module wasn't found at all.
+                raise ImportError, 'No module named ' + fqname
+
+        # fast-path simple imports
+        if len(parts) == 1:
+            if not fromlist:
+                return top_module
+
+            if not top_module.__dict__.get('__ispkg__'):
+                # __ispkg__ isn't defined (the module was not imported by us),
+                # or it is zero.
+                #
+                # In the former case, there is no way that we could import
+                # sub-modules that occur in the fromlist (but we can't raise an
+                # error because it may just be names) because we don't know how
+                # to deal with packages that were imported by other systems.
+                #
+                # In the latter case (__ispkg__ == 0), there can't be any sub-
+                # modules present, so we can just return.
+                #
+                # In both cases, since len(parts) == 1, the top_module is also
+                # the "bottom" which is the defined return when a fromlist
+                # exists.
+                return top_module
+
+        importer = top_module.__dict__.get('__importer__')
+        if importer:
+            return importer._finish_import(top_module, parts[1:], fromlist)
+
+        # Grrr, some people "import os.path" or do "from os.path import ..."
+        if len(parts) == 2 and hasattr(top_module, parts[1]):
+            if fromlist:
+                return getattr(top_module, parts[1])
+            else:
+                return top_module
+
+        # If the importer does not exist, then we have to bail. A missing
+        # importer means that something else imported the module, and we have
+        # no knowledge of how to get sub-modules out of the thing.
+        raise ImportError, 'No module named ' + fqname
+
+    def _determine_import_context(self, globals):
+        """Returns the context in which a module should be imported.
+
+        The context could be a loaded (package) module and the imported module
+        will be looked for within that package. The context could also be None,
+        meaning there is no context -- the module should be looked for as a
+        "top-level" module.
+        """
+
+        if not globals or not globals.get('__importer__'):
+            # globals does not refer to one of our modules or packages. That
+            # implies there is no relative import context (as far as we are
+            # concerned), and it should just pick it off the standard path.
+            return None
+
+        # The globals refer to a module or package of ours. It will define
+        # the context of the new import. Get the module/package fqname.
+        parent_fqname = globals['__name__']
+
+        # if a package is performing the import, then return itself (imports
+        # refer to pkg contents)
+        if globals['__ispkg__']:
+            parent = sys.modules[parent_fqname]
+            assert globals is parent.__dict__
+            return parent
+
+        i = parent_fqname.rfind('.')
+
+        # a module outside of a package has no particular import context
+        if i == -1:
+            return None
+
+        # if a module in a package is performing the import, then return the
+        # package (imports refer to siblings)
+        parent_fqname = parent_fqname[:i]
+        parent = sys.modules[parent_fqname]
+        assert parent.__name__ == parent_fqname
+        return parent
+
+    def _import_top_module(self, name):
+        # scan sys.path looking for a location in the filesystem that contains
+        # the module, or an Importer object that can import the module.
+        for item in sys.path:
+            if isinstance(item, _StringType):
+                module = self.fs_imp.import_from_dir(item, name)
+            else:
+                module = item.import_top(name)
+            if module:
+                return module
+        return None
+
+    def _reload_hook(self, module):
+        "Python calls this hook to reload a module."
+
+        # reloading of a module may or may not be possible (depending on the
+        # importer), but at least we can validate that it's ours to reload
+        importer = module.__dict__.get('__importer__')
+        if not importer:
+            ### oops. now what...
+            pass
+
+        # okay. it is using the imputil system, and we must delegate it, but
+        # we don't know what to do (yet)
+        ### we should blast the module dict and do another get_code(). need to
+        ### flesh this out and add proper docco...
+        raise SystemError, "reload not yet implemented"
+
+
+class Importer:
+    "Base class for replacing standard import functions."
+
+    def import_top(self, name):
+        "Import a top-level module."
+        return self._import_one(None, name, name)
+
+    ######################################################################
+    #
+    # PRIVATE METHODS
+    #
+    def _finish_import(self, top, parts, fromlist):
+        # if "a.b.c" was provided, then load the ".b.c" portion down from
+        # below the top-level module.
+        bottom = self._load_tail(top, parts)
+
+        # if the form is "import a.b.c", then return "a"
+        if not fromlist:
+            # no fromlist: return the top of the import tree
+            return top
+
+        # the top module was imported by self.
+        #
+        # this means that the bottom module was also imported by self (just
+        # now, or in the past and we fetched it from sys.modules).
+        #
+        # since we imported/handled the bottom module, this means that we can
+        # also handle its fromlist (and reliably use __ispkg__).
+
+        # if the bottom node is a package, then (potentially) import some
+        # modules.
+        #
+        # note: if it is not a package, then "fromlist" refers to names in
+        #       the bottom module rather than modules.
+        # note: for a mix of names and modules in the fromlist, we will
+        #       import all modules and insert those into the namespace of
+        #       the package module. Python will pick up all fromlist names
+        #       from the bottom (package) module; some will be modules that
+        #       we imported and stored in the namespace, others are expected
+        #       to be present already.
+        if bottom.__ispkg__:
+            self._import_fromlist(bottom, fromlist)
+
+        # if the form is "from a.b import c, d" then return "b"
+        return bottom
+
+    def _import_one(self, parent, modname, fqname):
+        "Import a single module."
+
+        # has the module already been imported?
+        try:
+            return sys.modules[fqname]
+        except KeyError:
+            pass
+
+        # load the module's code, or fetch the module itself
+        result = self.get_code(parent, modname, fqname)
+        if result is None:
+            return None
+
+        module = self._process_result(result, fqname)
+
+        # insert the module into its parent
+        if parent:
+            setattr(parent, modname, module)
+        return module
+
+    def _process_result(self, (ispkg, code, values), fqname):
+        # did get_code() return an actual module? (rather than a code object)
+        is_module = isinstance(code, _ModuleType)
+
+        # use the returned module, or create a new one to exec code into
+        if is_module:
+            module = code
+        else:
+            module = imp.new_module(fqname)
+
+        ### record packages a bit differently??
+        module.__importer__ = self
+        module.__ispkg__ = ispkg
+
+        # insert additional values into the module (before executing the code)
+        module.__dict__.update(values)
+
+        # the module is almost ready... make it visible
+        sys.modules[fqname] = module
+
+        # execute the code within the module's namespace
+        if not is_module:
+            try:
+                exec code in module.__dict__
+            except:
+                if fqname in sys.modules:
+                    del sys.modules[fqname]
+                raise
+
+        # fetch from sys.modules instead of returning module directly.
+        # also make module's __name__ agree with fqname, in case
+        # the "exec code in module.__dict__" played games on us.
+        module = sys.modules[fqname]
+        module.__name__ = fqname
+        return module
+
+    def _load_tail(self, m, parts):
+        """Import the rest of the modules, down from the top-level module.
+
+        Returns the last module in the dotted list of modules.
+        """
+        for part in parts:
+            fqname = "%s.%s" % (m.__name__, part)
+            m = self._import_one(m, part, fqname)
+            if not m:
+                raise ImportError, "No module named " + fqname
+        return m
+
+    def _import_fromlist(self, package, fromlist):
+        'Import any sub-modules in the "from" list.'
+
+        # if '*' is present in the fromlist, then look for the '__all__'
+        # variable to find additional items (modules) to import.
+        if '*' in fromlist:
+            fromlist = list(fromlist) + \
+                       list(package.__dict__.get('__all__', []))
+
+        for sub in fromlist:
+            # if the name is already present, then don't try to import it (it
+            # might not be a module!).
+            if sub != '*' and not hasattr(package, sub):
+                subname = "%s.%s" % (package.__name__, sub)
+                submod = self._import_one(package, sub, subname)
+                if not submod:
+                    raise ImportError, "cannot import name " + subname
+
+    def _do_import(self, parent, parts, fromlist):
+        """Attempt to import the module relative to parent.
+
+        This method is used when the import context specifies that <self>
+        imported the parent module.
+        """
+        top_name = parts[0]
+        top_fqname = parent.__name__ + '.' + top_name
+        top_module = self._import_one(parent, top_name, top_fqname)
+        if not top_module:
+            # this importer and parent could not find the module (relatively)
+            return None
+
+        return self._finish_import(top_module, parts[1:], fromlist)
+
+    ######################################################################
+    #
+    # METHODS TO OVERRIDE
+    #
+    def get_code(self, parent, modname, fqname):
+        """Find and retrieve the code for the given module.
+
+        parent specifies a parent module to define a context for importing. It
+        may be None, indicating no particular context for the search.
+
+        modname specifies a single module (not dotted) within the parent.
+
+        fqname specifies the fully-qualified module name. This is a
+        (potentially) dotted name from the "root" of the module namespace
+        down to the modname.
+        If there is no parent, then modname==fqname.
+
+        This method should return None, or a 3-tuple.
+
+        * If the module was not found, then None should be returned.
+
+        * The first item of the 2- or 3-tuple should be the integer 0 or 1,
+            specifying whether the module that was found is a package or not.
+
+        * The second item is the code object for the module (it will be
+            executed within the new module's namespace). This item can also
+            be a fully-loaded module object (e.g. loaded from a shared lib).
+
+        * The third item is a dictionary of name/value pairs that will be
+            inserted into new module before the code object is executed. This
+            is provided in case the module's code expects certain values (such
+            as where the module was found). When the second item is a module
+            object, then these names/values will be inserted *after* the module
+            has been loaded/initialized.
+        """
+        raise RuntimeError, "get_code not implemented"
+
+
+######################################################################
+#
+# Some handy stuff for the Importers
+#
+
+# byte-compiled file suffix character
+_suffix_char = __debug__ and 'c' or 'o'
+
+# byte-compiled file suffix
+_suffix = '.py' + _suffix_char
+
+def _compile(pathname, timestamp):
+    """Compile (and cache) a Python source file.
+
+    The file specified by <pathname> is compiled to a code object and
+    returned.
+
+    Presuming the appropriate privileges exist, the bytecodes will be
+    saved back to the filesystem for future imports. The source file's
+    modification timestamp must be provided as a Long value.
+    """
+    codestring = open(pathname, 'rU').read()
+    if codestring and codestring[-1] != '\n':
+        codestring = codestring + '\n'
+    code = __builtin__.compile(codestring, pathname, 'exec')
+
+    # try to cache the compiled code
+    try:
+        f = open(pathname + _suffix_char, 'wb')
+    except IOError:
+        pass
+    else:
+        f.write('\0\0\0\0')
+        f.write(struct.pack('<I', timestamp))
+        marshal.dump(code, f)
+        f.flush()
+        f.seek(0, 0)
+        f.write(imp.get_magic())
+        f.close()
+
+    return code
+
+_os_stat = _os_path_join = None
+def _os_bootstrap():
+    "Set up 'os' module replacement functions for use during import bootstrap."
+
+    names = sys.builtin_module_names
+
+    join = None
+    if 'posix' in names:
+        sep = '/'
+        from posix import stat
+    elif 'nt' in names:
+        sep = '\\'
+        from nt import stat
+    elif 'dos' in names:
+        sep = '\\'
+        from dos import stat
+    elif 'os2' in names:
+        sep = '\\'
+        from os2 import stat
+    elif 'mac' in names:
+        from mac import stat
+        def join(a, b):
+            if a == '':
+                return b
+            if ':' not in a:
+                a = ':' + a
+            if a[-1:] != ':':
+                a = a + ':'
+            return a + b
+    else:
+        raise ImportError, 'no os specific module found'
+
+    if join is None:
+        def join(a, b, sep=sep):
+            if a == '':
+                return b
+            lastchar = a[-1:]
+            if lastchar == '/' or lastchar == sep:
+                return a + b
+            return a + sep + b
+
+    global _os_stat
+    _os_stat = stat
+
+    global _os_path_join
+    _os_path_join = join
+
+def _os_path_isdir(pathname):
+    "Local replacement for os.path.isdir()."
+    try:
+        s = _os_stat(pathname)
+    except OSError:
+        return None
+    return (s.st_mode & 0170000) == 0040000
+
+def _timestamp(pathname):
+    "Return the file modification time as a Long."
+    try:
+        s = _os_stat(pathname)
+    except OSError:
+        return None
+    return long(s.st_mtime)
+
+
+######################################################################
+#
+# Emulate the import mechanism for builtin and frozen modules
+#
+class BuiltinImporter(Importer):
+    def get_code(self, parent, modname, fqname):
+        if parent:
+            # these modules definitely do not occur within a package context
+            return None
+
+        # look for the module
+        if imp.is_builtin(modname):
+            type = imp.C_BUILTIN
+        elif imp.is_frozen(modname):
+            type = imp.PY_FROZEN
+        else:
+            # not found
+            return None
+
+        # got it. now load and return it.
+        module = imp.load_module(modname, None, modname, ('', '', type))
+        return 0, module, { }
+
+
+######################################################################
+#
+# Internal importer used for importing from the filesystem
+#
+class _FilesystemImporter(Importer):
+    def __init__(self):
+        self.suffixes = [ ]
+
+    def add_suffix(self, suffix, importFunc):
+        assert callable(importFunc)
+        self.suffixes.append((suffix, importFunc))
+
+    def import_from_dir(self, dir, fqname):
+        result = self._import_pathname(_os_path_join(dir, fqname), fqname)
+        if result:
+            return self._process_result(result, fqname)
+        return None
+
+    def get_code(self, parent, modname, fqname):
+        # This importer is never used with an empty parent. Its existence is
+        # private to the ImportManager. The ImportManager uses the
+        # import_from_dir() method to import top-level modules/packages.
+        # This method is only used when we look for a module within a package.
+        assert parent
+
+        for submodule_path in parent.__path__:
+            code = self._import_pathname(_os_path_join(submodule_path, modname), fqname)
+            if code is not None:
+                return code
+        return self._import_pathname(_os_path_join(parent.__pkgdir__, modname),
+                                     fqname)
+
+    def _import_pathname(self, pathname, fqname):
+        if _os_path_isdir(pathname):
+            result = self._import_pathname(_os_path_join(pathname, '__init__'),
+                                           fqname)
+            if result:
+                values = result[2]
+                values['__pkgdir__'] = pathname
+                values['__path__'] = [ pathname ]
+                return 1, result[1], values
+            return None
+
+        for suffix, importFunc in self.suffixes:
+            filename = pathname + suffix
+            try:
+                finfo = _os_stat(filename)
+            except OSError:
+                pass
+            else:
+                return importFunc(filename, finfo, fqname)
+        return None
+
+######################################################################
+#
+# SUFFIX-BASED IMPORTERS
+#
+
+def py_suffix_importer(filename, finfo, fqname):
+    file = filename[:-3] + _suffix
+    t_py = long(finfo[8])
+    t_pyc = _timestamp(file)
+
+    code = None
+    if t_pyc is not None and t_pyc >= t_py:
+        f = open(file, 'rb')
+        if f.read(4) == imp.get_magic():
+            t = struct.unpack('<I', f.read(4))[0]
+            if t == t_py:
+                code = marshal.load(f)
+        f.close()
+    if code is None:
+        file = filename
+        code = _compile(file, t_py)
+
+    return 0, code, { '__file__' : file }
+
+class DynLoadSuffixImporter:
+    def __init__(self, desc):
+        self.desc = desc
+
+    def import_file(self, filename, finfo, fqname):
+        fp = open(filename, self.desc[1])
+        module = imp.load_module(fqname, fp, filename, self.desc)
+        module.__file__ = filename
+        return 0, module, { }
+
+
+######################################################################
+
+def _print_importers():
+    items = sys.modules.items()
+    items.sort()
+    for name, module in items:
+        if module:
+            print name, module.__dict__.get('__importer__', '-- no importer')
+        else:
+            print name, '-- non-existent module'
+
+def _test_revamp():
+    ImportManager().install()
+    sys.path.insert(0, BuiltinImporter())
+
+######################################################################
+
+#
+# TODO
+#
+# from Finn Bock:
+#   type(sys) is not a module in JPython. what to use instead?
+#   imp.C_EXTENSION is not in JPython. same for get_suffixes and new_module
+#
+#   given foo.py of:
+#      import sys
+#      sys.modules['foo'] = sys
+#
+#   ---- standard import mechanism
+#   >>> import foo
+#   >>> foo
+#   <module 'sys' (built-in)>
+#
+#   ---- revamped import mechanism
+#   >>> import imputil
+#   >>> imputil._test_revamp()
+#   >>> import foo
+#   >>> foo
+#   <module 'foo' from 'foo.py'>
+#
+#
+# from MAL:
+#   should BuiltinImporter exist in sys.path or hard-wired in ImportManager?
+#   need __path__ processing
+#   performance
+#   move chaining to a subclass [gjs: it's been nuked]
+#   deinstall should be possible
+#   query mechanism needed: is a specific Importer installed?
+#   py/pyc/pyo piping hooks to filter/process these files
+#   wish list:
+#     distutils importer hooked to list of standard Internet repositories
+#     module->file location mapper to speed FS-based imports
+#     relative imports
+#     keep chaining so that it can play nice with other import hooks
+#
+# from Gordon:
+#   push MAL's mapper into sys.path[0] as a cache (hard-coded for apps)
+#
+# from Guido:
+#   need to change sys.* references for rexec environs
+#   need hook for MAL's walk-me-up import strategy, or Tim's absolute strategy
+#   watch out for sys.modules[...] is None
+#   flag to force absolute imports? (speeds _determine_import_context and
+#       checking for a relative module)
+#   insert names of archives into sys.path  (see quote below)
+#   note: reload does NOT blast module dict
+#   shift import mechanisms and policies around; provide for hooks, overrides
+#       (see quote below)
+#   add get_source stuff
+#   get_topcode and get_subcode
+#   CRLF handling in _compile
+#   race condition in _compile
+#   refactoring of os.py to deal with _os_bootstrap problem
+#   any special handling to do for importing a module with a SyntaxError?
+#       (e.g. clean up the traceback)
+#   implement "domain" for path-type functionality using pkg namespace
+#       (rather than FS-names like __path__)
+#   don't use the word "private"... maybe "internal"
+#
+#
+# Guido's comments on sys.path caching:
+#
+# We could cache this in a dictionary: the ImportManager can have a
+# cache dict mapping pathnames to importer objects, and a separate
+# method for coming up with an importer given a pathname that's not yet
+# in the cache.  The method should do a stat and/or look at the
+# extension to decide which importer class to use; you can register new
+# importer classes by registering a suffix or a Boolean function, plus a
+# class.  If you register a new importer class, the cache is zapped.
+# The cache is independent from sys.path (but maintained per
+# ImportManager instance) so that rearrangements of sys.path do the
+# right thing.  If a path is dropped from sys.path the corresponding
+# cache entry is simply no longer used.
+#
+# My/Guido's comments on factoring ImportManager and Importer:
+#
+# > However, we still have a tension occurring here:
+# >
+# > 1) implementing policy in ImportManager assists in single-point policy
+# >    changes for app/rexec situations
+# > 2) implementing policy in Importer assists in package-private policy
+# >    changes for normal, operating conditions
+# >
+# > I'll see if I can sort out a way to do this. Maybe the Importer class will
+# > implement the methods (which can be overridden to change policy) by
+# > delegating to ImportManager.
+#
+# Maybe also think about what kind of policies an Importer would be
+# likely to want to change.  I have a feeling that a lot of the code
+# there is actually not so much policy but a *necessity* to get things
+# working given the calling conventions for the __import__ hook: whether
+# to return the head or tail of a dotted name, or when to do the "finish
+# fromlist" stuff.
+#

Added: vendor/Python/current/Lib/inspect.py
===================================================================
--- vendor/Python/current/Lib/inspect.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/inspect.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,889 @@
+# -*- coding: iso-8859-1 -*-
+"""Get useful information from live Python objects.
+
+This module encapsulates the interface provided by the internal special
+attributes (func_*, co_*, im_*, tb_*, etc.) in a friendlier fashion.
+It also provides some help for examining source code and class layout.
+
+Here are some of the useful functions provided by this module:
+
+    ismodule(), isclass(), ismethod(), isfunction(), istraceback(),
+        isframe(), iscode(), isbuiltin(), isroutine() - check object types
+    getmembers() - get members of an object that satisfy a given condition
+
+    getfile(), getsourcefile(), getsource() - find an object's source code
+    getdoc(), getcomments() - get documentation on an object
+    getmodule() - determine the module that an object came from
+    getclasstree() - arrange classes so as to represent their hierarchy
+
+    getargspec(), getargvalues() - get info about function arguments
+    formatargspec(), formatargvalues() - format an argument spec
+    getouterframes(), getinnerframes() - get info about frames
+    currentframe() - get the current stack frame
+    stack(), trace() - get info about frames on the stack or in a traceback
+"""
+
+# This module is in the public domain.  No warranties.
+
+__author__ = 'Ka-Ping Yee <ping at lfw.org>'
+__date__ = '1 Jan 2001'
+
+import sys, os, types, string, re, dis, imp, tokenize, linecache
+from operator import attrgetter
+
+# ----------------------------------------------------------- type-checking
+def ismodule(object):
+    """Return true if the object is a module.
+
+    Module objects provide these attributes:
+        __doc__         documentation string
+        __file__        filename (missing for built-in modules)"""
+    return isinstance(object, types.ModuleType)
+
+def isclass(object):
+    """Return true if the object is a class.
+
+    Class objects provide these attributes:
+        __doc__         documentation string
+        __module__      name of module in which this class was defined"""
+    return isinstance(object, types.ClassType) or hasattr(object, '__bases__')
+
+def ismethod(object):
+    """Return true if the object is an instance method.
+
+    Instance method objects provide these attributes:
+        __doc__         documentation string
+        __name__        name with which this method was defined
+        im_class        class object in which this method belongs
+        im_func         function object containing implementation of method
+        im_self         instance to which this method is bound, or None"""
+    return isinstance(object, types.MethodType)
+
+def ismethoddescriptor(object):
+    """Return true if the object is a method descriptor.
+
+    But not if ismethod() or isclass() or isfunction() are true.
+
+    This is new in Python 2.2, and, for example, is true of int.__add__.
+    An object passing this test has a __get__ attribute but not a __set__
+    attribute, but beyond that the set of attributes varies.  __name__ is
+    usually sensible, and __doc__ often is.
+
+    Methods implemented via descriptors that also pass one of the other
+    tests return false from the ismethoddescriptor() test, simply because
+    the other tests promise more -- you can, e.g., count on having the
+    im_func attribute (etc) when an object passes ismethod()."""
+    return (hasattr(object, "__get__")
+            and not hasattr(object, "__set__") # else it's a data descriptor
+            and not ismethod(object)           # mutual exclusion
+            and not isfunction(object)
+            and not isclass(object))
+
+def isdatadescriptor(object):
+    """Return true if the object is a data descriptor.
+
+    Data descriptors have both a __get__ and a __set__ attribute.  Examples are
+    properties (defined in Python) and getsets and members (defined in C).
+    Typically, data descriptors will also have __name__ and __doc__ attributes
+    (properties, getsets, and members have both of these attributes), but this
+    is not guaranteed."""
+    return (hasattr(object, "__set__") and hasattr(object, "__get__"))
+
+if hasattr(types, 'MemberDescriptorType'):
+    # CPython and equivalent
+    def ismemberdescriptor(object):
+        """Return true if the object is a member descriptor.
+
+        Member descriptors are specialized descriptors defined in extension
+        modules."""
+        return isinstance(object, types.MemberDescriptorType)
+else:
+    # Other implementations
+    def ismemberdescriptor(object):
+        """Return true if the object is a member descriptor.
+
+        Member descriptors are specialized descriptors defined in extension
+        modules."""
+        return False
+
+if hasattr(types, 'GetSetDescriptorType'):
+    # CPython and equivalent
+    def isgetsetdescriptor(object):
+        """Return true if the object is a getset descriptor.
+
+        getset descriptors are specialized descriptors defined in extension
+        modules."""
+        return isinstance(object, types.GetSetDescriptorType)
+else:
+    # Other implementations
+    def isgetsetdescriptor(object):
+        """Return true if the object is a getset descriptor.
+
+        getset descriptors are specialized descriptors defined in extension
+        modules."""
+        return False
+
+def isfunction(object):
+    """Return true if the object is a user-defined function.
+
+    Function objects provide these attributes:
+        __doc__         documentation string
+        __name__        name with which this function was defined
+        func_code       code object containing compiled function bytecode
+        func_defaults   tuple of any default values for arguments
+        func_doc        (same as __doc__)
+        func_globals    global namespace in which this function was defined
+        func_name       (same as __name__)"""
+    return isinstance(object, types.FunctionType)
+
+def istraceback(object):
+    """Return true if the object is a traceback.
+
+    Traceback objects provide these attributes:
+        tb_frame        frame object at this level
+        tb_lasti        index of last attempted instruction in bytecode
+        tb_lineno       current line number in Python source code
+        tb_next         next inner traceback object (called by this level)"""
+    return isinstance(object, types.TracebackType)
+
+def isframe(object):
+    """Return true if the object is a frame object.
+
+    Frame objects provide these attributes:
+        f_back          next outer frame object (this frame's caller)
+        f_builtins      built-in namespace seen by this frame
+        f_code          code object being executed in this frame
+        f_exc_traceback traceback if raised in this frame, or None
+        f_exc_type      exception type if raised in this frame, or None
+        f_exc_value     exception value if raised in this frame, or None
+        f_globals       global namespace seen by this frame
+        f_lasti         index of last attempted instruction in bytecode
+        f_lineno        current line number in Python source code
+        f_locals        local namespace seen by this frame
+        f_restricted    0 or 1 if frame is in restricted execution mode
+        f_trace         tracing function for this frame, or None"""
+    return isinstance(object, types.FrameType)
+
+def iscode(object):
+    """Return true if the object is a code object.
+
+    Code objects provide these attributes:
+        co_argcount     number of arguments (not including * or ** args)
+        co_code         string of raw compiled bytecode
+        co_consts       tuple of constants used in the bytecode
+        co_filename     name of file in which this code object was created
+        co_firstlineno  number of first line in Python source code
+        co_flags        bitmap: 1=optimized | 2=newlocals | 4=*arg | 8=**arg
+        co_lnotab       encoded mapping of line numbers to bytecode indices
+        co_name         name with which this code object was defined
+        co_names        tuple of names of local variables
+        co_nlocals      number of local variables
+        co_stacksize    virtual machine stack space required
+        co_varnames     tuple of names of arguments and local variables"""
+    return isinstance(object, types.CodeType)
+
+def isbuiltin(object):
+    """Return true if the object is a built-in function or method.
+
+    Built-in functions and methods provide these attributes:
+        __doc__         documentation string
+        __name__        original name of this function or method
+        __self__        instance to which a method is bound, or None"""
+    return isinstance(object, types.BuiltinFunctionType)
+
+def isroutine(object):
+    """Return true if the object is any kind of function or method."""
+    return (isbuiltin(object)
+            or isfunction(object)
+            or ismethod(object)
+            or ismethoddescriptor(object))
+
+def getmembers(object, predicate=None):
+    """Return all members of an object as (name, value) pairs sorted by name.
+    Optionally, only return members that satisfy a given predicate."""
+    results = []
+    for key in dir(object):
+        value = getattr(object, key)
+        if not predicate or predicate(value):
+            results.append((key, value))
+    results.sort()
+    return results
+
+def classify_class_attrs(cls):
+    """Return list of attribute-descriptor tuples.
+
+    For each name in dir(cls), the return list contains a 4-tuple
+    with these elements:
+
+        0. The name (a string).
+
+        1. The kind of attribute this is, one of these strings:
+               'class method'    created via classmethod()
+               'static method'   created via staticmethod()
+               'property'        created via property()
+               'method'          any other flavor of method
+               'data'            not a method
+
+        2. The class which defined this attribute (a class).
+
+        3. The object as obtained directly from the defining class's
+           __dict__, not via getattr.  This is especially important for
+           data attributes:  C.data is just a data object, but
+           C.__dict__['data'] may be a data descriptor with additional
+           info, like a __doc__ string.
+    """
+
+    mro = getmro(cls)
+    names = dir(cls)
+    result = []
+    for name in names:
+        # Get the object associated with the name.
+        # Getting an obj from the __dict__ sometimes reveals more than
+        # using getattr.  Static and class methods are dramatic examples.
+        if name in cls.__dict__:
+            obj = cls.__dict__[name]
+        else:
+            obj = getattr(cls, name)
+
+        # Figure out where it was defined.
+        homecls = getattr(obj, "__objclass__", None)
+        if homecls is None:
+            # search the dicts.
+            for base in mro:
+                if name in base.__dict__:
+                    homecls = base
+                    break
+
+        # Get the object again, in order to get it from the defining
+        # __dict__ instead of via getattr (if possible).
+        if homecls is not None and name in homecls.__dict__:
+            obj = homecls.__dict__[name]
+
+        # Also get the object via getattr.
+        obj_via_getattr = getattr(cls, name)
+
+        # Classify the object.
+        if isinstance(obj, staticmethod):
+            kind = "static method"
+        elif isinstance(obj, classmethod):
+            kind = "class method"
+        elif isinstance(obj, property):
+            kind = "property"
+        elif (ismethod(obj_via_getattr) or
+              ismethoddescriptor(obj_via_getattr)):
+            kind = "method"
+        else:
+            kind = "data"
+
+        result.append((name, kind, homecls, obj))
+
+    return result
+
+# ----------------------------------------------------------- class helpers
+def _searchbases(cls, accum):
+    # Simulate the "classic class" search order.
+    if cls in accum:
+        return
+    accum.append(cls)
+    for base in cls.__bases__:
+        _searchbases(base, accum)
+
+def getmro(cls):
+    "Return tuple of base classes (including cls) in method resolution order."
+    if hasattr(cls, "__mro__"):
+        return cls.__mro__
+    else:
+        result = []
+        _searchbases(cls, result)
+        return tuple(result)
+
+# -------------------------------------------------- source code extraction
+def indentsize(line):
+    """Return the indent size, in spaces, at the start of a line of text."""
+    expline = string.expandtabs(line)
+    return len(expline) - len(string.lstrip(expline))
+
+def getdoc(object):
+    """Get the documentation string for an object.
+
+    All tabs are expanded to spaces.  To clean up docstrings that are
+    indented to line up with blocks of code, any whitespace than can be
+    uniformly removed from the second line onwards is removed."""
+    try:
+        doc = object.__doc__
+    except AttributeError:
+        return None
+    if not isinstance(doc, types.StringTypes):
+        return None
+    try:
+        lines = string.split(string.expandtabs(doc), '\n')
+    except UnicodeError:
+        return None
+    else:
+        # Find minimum indentation of any non-blank lines after first line.
+        margin = sys.maxint
+        for line in lines[1:]:
+            content = len(string.lstrip(line))
+            if content:
+                indent = len(line) - content
+                margin = min(margin, indent)
+        # Remove indentation.
+        if lines:
+            lines[0] = lines[0].lstrip()
+        if margin < sys.maxint:
+            for i in range(1, len(lines)): lines[i] = lines[i][margin:]
+        # Remove any trailing or leading blank lines.
+        while lines and not lines[-1]:
+            lines.pop()
+        while lines and not lines[0]:
+            lines.pop(0)
+        return string.join(lines, '\n')
+
+def getfile(object):
+    """Work out which source or compiled file an object was defined in."""
+    if ismodule(object):
+        if hasattr(object, '__file__'):
+            return object.__file__
+        raise TypeError('arg is a built-in module')
+    if isclass(object):
+        object = sys.modules.get(object.__module__)
+        if hasattr(object, '__file__'):
+            return object.__file__
+        raise TypeError('arg is a built-in class')
+    if ismethod(object):
+        object = object.im_func
+    if isfunction(object):
+        object = object.func_code
+    if istraceback(object):
+        object = object.tb_frame
+    if isframe(object):
+        object = object.f_code
+    if iscode(object):
+        return object.co_filename
+    raise TypeError('arg is not a module, class, method, '
+                    'function, traceback, frame, or code object')
+
+def getmoduleinfo(path):
+    """Get the module name, suffix, mode, and module type for a given file."""
+    filename = os.path.basename(path)
+    suffixes = map(lambda (suffix, mode, mtype):
+                   (-len(suffix), suffix, mode, mtype), imp.get_suffixes())
+    suffixes.sort() # try longest suffixes first, in case they overlap
+    for neglen, suffix, mode, mtype in suffixes:
+        if filename[neglen:] == suffix:
+            return filename[:neglen], suffix, mode, mtype
+
+def getmodulename(path):
+    """Return the module name for a given file, or None."""
+    info = getmoduleinfo(path)
+    if info: return info[0]
+
+def getsourcefile(object):
+    """Return the Python source file an object was defined in, if it exists."""
+    filename = getfile(object)
+    if string.lower(filename[-4:]) in ('.pyc', '.pyo'):
+        filename = filename[:-4] + '.py'
+    for suffix, mode, kind in imp.get_suffixes():
+        if 'b' in mode and string.lower(filename[-len(suffix):]) == suffix:
+            # Looks like a binary file.  We want to only return a text file.
+            return None
+    if os.path.exists(filename):
+        return filename
+    # only return a non-existent filename if the module has a PEP 302 loader
+    if hasattr(getmodule(object, filename), '__loader__'):
+        return filename
+
+def getabsfile(object, _filename=None):
+    """Return an absolute path to the source or compiled file for an object.
+
+    The idea is for each object to have a unique origin, so this routine
+    normalizes the result as much as possible."""
+    if _filename is None:
+        _filename = getsourcefile(object) or getfile(object)
+    return os.path.normcase(os.path.abspath(_filename))
+
+modulesbyfile = {}
+_filesbymodname = {}
+
+def getmodule(object, _filename=None):
+    """Return the module an object was defined in, or None if not found."""
+    if ismodule(object):
+        return object
+    if hasattr(object, '__module__'):
+        return sys.modules.get(object.__module__)
+    # Try the filename to modulename cache
+    if _filename is not None and _filename in modulesbyfile:
+        return sys.modules.get(modulesbyfile[_filename])
+    # Try the cache again with the absolute file name
+    try:
+        file = getabsfile(object, _filename)
+    except TypeError:
+        return None
+    if file in modulesbyfile:
+        return sys.modules.get(modulesbyfile[file])
+    # Update the filename to module name cache and check yet again
+    # Copy sys.modules in order to cope with changes while iterating
+    for modname, module in sys.modules.items():
+        if ismodule(module) and hasattr(module, '__file__'):
+            f = module.__file__
+            if f == _filesbymodname.get(modname, None):
+                # Have already mapped this module, so skip it
+                continue
+            _filesbymodname[modname] = f
+            f = getabsfile(module)
+            # Always map to the name the module knows itself by
+            modulesbyfile[f] = modulesbyfile[
+                os.path.realpath(f)] = module.__name__
+    if file in modulesbyfile:
+        return sys.modules.get(modulesbyfile[file])
+    # Check the main module
+    main = sys.modules['__main__']
+    if not hasattr(object, '__name__'):
+        return None
+    if hasattr(main, object.__name__):
+        mainobject = getattr(main, object.__name__)
+        if mainobject is object:
+            return main
+    # Check builtins
+    builtin = sys.modules['__builtin__']
+    if hasattr(builtin, object.__name__):
+        builtinobject = getattr(builtin, object.__name__)
+        if builtinobject is object:
+            return builtin
+
+def findsource(object):
+    """Return the entire source file and starting line number for an object.
+
+    The argument may be a module, class, method, function, traceback, frame,
+    or code object.  The source code is returned as a list of all the lines
+    in the file and the line number indexes a line in that list.  An IOError
+    is raised if the source code cannot be retrieved."""
+    file = getsourcefile(object) or getfile(object)
+    module = getmodule(object, file)
+    if module:
+        lines = linecache.getlines(file, module.__dict__)
+    else:
+        lines = linecache.getlines(file)
+    if not lines:
+        raise IOError('could not get source code')
+
+    if ismodule(object):
+        return lines, 0
+
+    if isclass(object):
+        name = object.__name__
+        pat = re.compile(r'^(\s*)class\s*' + name + r'\b')
+        # make some effort to find the best matching class definition:
+        # use the one with the least indentation, which is the one
+        # that's most probably not inside a function definition.
+        candidates = []
+        for i in range(len(lines)):
+            match = pat.match(lines[i])
+            if match:
+                # if it's at toplevel, it's already the best one
+                if lines[i][0] == 'c':
+                    return lines, i
+                # else add whitespace to candidate list
+                candidates.append((match.group(1), i))
+        if candidates:
+            # this will sort by whitespace, and by line number,
+            # less whitespace first
+            candidates.sort()
+            return lines, candidates[0][1]
+        else:
+            raise IOError('could not find class definition')
+
+    if ismethod(object):
+        object = object.im_func
+    if isfunction(object):
+        object = object.func_code
+    if istraceback(object):
+        object = object.tb_frame
+    if isframe(object):
+        object = object.f_code
+    if iscode(object):
+        if not hasattr(object, 'co_firstlineno'):
+            raise IOError('could not find function definition')
+        lnum = object.co_firstlineno - 1
+        pat = re.compile(r'^(\s*def\s)|(.*(?<!\w)lambda(:|\s))|^(\s*@)')
+        while lnum > 0:
+            if pat.match(lines[lnum]): break
+            lnum = lnum - 1
+        return lines, lnum
+    raise IOError('could not find code object')
+
+def getcomments(object):
+    """Get lines of comments immediately preceding an object's source code.
+
+    Returns None when source can't be found.
+    """
+    try:
+        lines, lnum = findsource(object)
+    except (IOError, TypeError):
+        return None
+
+    if ismodule(object):
+        # Look for a comment block at the top of the file.
+        start = 0
+        if lines and lines[0][:2] == '#!': start = 1
+        while start < len(lines) and string.strip(lines[start]) in ('', '#'):
+            start = start + 1
+        if start < len(lines) and lines[start][:1] == '#':
+            comments = []
+            end = start
+            while end < len(lines) and lines[end][:1] == '#':
+                comments.append(string.expandtabs(lines[end]))
+                end = end + 1
+            return string.join(comments, '')
+
+    # Look for a preceding block of comments at the same indentation.
+    elif lnum > 0:
+        indent = indentsize(lines[lnum])
+        end = lnum - 1
+        if end >= 0 and string.lstrip(lines[end])[:1] == '#' and \
+            indentsize(lines[end]) == indent:
+            comments = [string.lstrip(string.expandtabs(lines[end]))]
+            if end > 0:
+                end = end - 1
+                comment = string.lstrip(string.expandtabs(lines[end]))
+                while comment[:1] == '#' and indentsize(lines[end]) == indent:
+                    comments[:0] = [comment]
+                    end = end - 1
+                    if end < 0: break
+                    comment = string.lstrip(string.expandtabs(lines[end]))
+            while comments and string.strip(comments[0]) == '#':
+                comments[:1] = []
+            while comments and string.strip(comments[-1]) == '#':
+                comments[-1:] = []
+            return string.join(comments, '')
+
+class EndOfBlock(Exception): pass
+
+class BlockFinder:
+    """Provide a tokeneater() method to detect the end of a code block."""
+    def __init__(self):
+        self.indent = 0
+        self.islambda = False
+        self.started = False
+        self.passline = False
+        self.last = 1
+
+    def tokeneater(self, type, token, (srow, scol), (erow, ecol), line):
+        if not self.started:
+            # look for the first "def", "class" or "lambda"
+            if token in ("def", "class", "lambda"):
+                if token == "lambda":
+                    self.islambda = True
+                self.started = True
+            self.passline = True    # skip to the end of the line
+        elif type == tokenize.NEWLINE:
+            self.passline = False   # stop skipping when a NEWLINE is seen
+            self.last = srow
+            if self.islambda:       # lambdas always end at the first NEWLINE
+                raise EndOfBlock
+        elif self.passline:
+            pass
+        elif type == tokenize.INDENT:
+            self.indent = self.indent + 1
+            self.passline = True
+        elif type == tokenize.DEDENT:
+            self.indent = self.indent - 1
+            # the end of matching indent/dedent pairs end a block
+            # (note that this only works for "def"/"class" blocks,
+            #  not e.g. for "if: else:" or "try: finally:" blocks)
+            if self.indent <= 0:
+                raise EndOfBlock
+        elif self.indent == 0 and type not in (tokenize.COMMENT, tokenize.NL):
+            # any other token on the same indentation level end the previous
+            # block as well, except the pseudo-tokens COMMENT and NL.
+            raise EndOfBlock
+
+def getblock(lines):
+    """Extract the block of code at the top of the given list of lines."""
+    blockfinder = BlockFinder()
+    try:
+        tokenize.tokenize(iter(lines).next, blockfinder.tokeneater)
+    except (EndOfBlock, IndentationError):
+        pass
+    return lines[:blockfinder.last]
+
+def getsourcelines(object):
+    """Return a list of source lines and starting line number for an object.
+
+    The argument may be a module, class, method, function, traceback, frame,
+    or code object.  The source code is returned as a list of the lines
+    corresponding to the object and the line number indicates where in the
+    original source file the first line of code was found.  An IOError is
+    raised if the source code cannot be retrieved."""
+    lines, lnum = findsource(object)
+
+    if ismodule(object): return lines, 0
+    else: return getblock(lines[lnum:]), lnum + 1
+
+def getsource(object):
+    """Return the text of the source code for an object.
+
+    The argument may be a module, class, method, function, traceback, frame,
+    or code object.  The source code is returned as a single string.  An
+    IOError is raised if the source code cannot be retrieved."""
+    lines, lnum = getsourcelines(object)
+    return string.join(lines, '')
+
+# --------------------------------------------------- class tree extraction
+def walktree(classes, children, parent):
+    """Recursive helper function for getclasstree()."""
+    results = []
+    classes.sort(key=attrgetter('__module__', '__name__'))
+    for c in classes:
+        results.append((c, c.__bases__))
+        if c in children:
+            results.append(walktree(children[c], children, c))
+    return results
+
+def getclasstree(classes, unique=0):
+    """Arrange the given list of classes into a hierarchy of nested lists.
+
+    Where a nested list appears, it contains classes derived from the class
+    whose entry immediately precedes the list.  Each entry is a 2-tuple
+    containing a class and a tuple of its base classes.  If the 'unique'
+    argument is true, exactly one entry appears in the returned structure
+    for each class in the given list.  Otherwise, classes using multiple
+    inheritance and their descendants will appear multiple times."""
+    children = {}
+    roots = []
+    for c in classes:
+        if c.__bases__:
+            for parent in c.__bases__:
+                if not parent in children:
+                    children[parent] = []
+                children[parent].append(c)
+                if unique and parent in classes: break
+        elif c not in roots:
+            roots.append(c)
+    for parent in children:
+        if parent not in classes:
+            roots.append(parent)
+    return walktree(roots, children, None)
+
+# ------------------------------------------------ argument list extraction
+# These constants are from Python's compile.h.
+CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS = 1, 2, 4, 8
+
+def getargs(co):
+    """Get information about the arguments accepted by a code object.
+
+    Three things are returned: (args, varargs, varkw), where 'args' is
+    a list of argument names (possibly containing nested lists), and
+    'varargs' and 'varkw' are the names of the * and ** arguments or None."""
+
+    if not iscode(co):
+        raise TypeError('arg is not a code object')
+
+    code = co.co_code
+    nargs = co.co_argcount
+    names = co.co_varnames
+    args = list(names[:nargs])
+    step = 0
+
+    # The following acrobatics are for anonymous (tuple) arguments.
+    for i in range(nargs):
+        if args[i][:1] in ('', '.'):
+            stack, remain, count = [], [], []
+            while step < len(code):
+                op = ord(code[step])
+                step = step + 1
+                if op >= dis.HAVE_ARGUMENT:
+                    opname = dis.opname[op]
+                    value = ord(code[step]) + ord(code[step+1])*256
+                    step = step + 2
+                    if opname in ('UNPACK_TUPLE', 'UNPACK_SEQUENCE'):
+                        remain.append(value)
+                        count.append(value)
+                    elif opname == 'STORE_FAST':
+                        stack.append(names[value])
+
+                        # Special case for sublists of length 1: def foo((bar))
+                        # doesn't generate the UNPACK_TUPLE bytecode, so if
+                        # `remain` is empty here, we have such a sublist.
+                        if not remain:
+                            stack[0] = [stack[0]]
+                            break
+                        else:
+                            remain[-1] = remain[-1] - 1
+                            while remain[-1] == 0:
+                                remain.pop()
+                                size = count.pop()
+                                stack[-size:] = [stack[-size:]]
+                                if not remain: break
+                                remain[-1] = remain[-1] - 1
+                            if not remain: break
+            args[i] = stack[0]
+
+    varargs = None
+    if co.co_flags & CO_VARARGS:
+        varargs = co.co_varnames[nargs]
+        nargs = nargs + 1
+    varkw = None
+    if co.co_flags & CO_VARKEYWORDS:
+        varkw = co.co_varnames[nargs]
+    return args, varargs, varkw
+
+def getargspec(func):
+    """Get the names and default values of a function's arguments.
+
+    A tuple of four things is returned: (args, varargs, varkw, defaults).
+    'args' is a list of the argument names (it may contain nested lists).
+    'varargs' and 'varkw' are the names of the * and ** arguments or None.
+    'defaults' is an n-tuple of the default values of the last n arguments.
+    """
+
+    if ismethod(func):
+        func = func.im_func
+    if not isfunction(func):
+        raise TypeError('arg is not a Python function')
+    args, varargs, varkw = getargs(func.func_code)
+    return args, varargs, varkw, func.func_defaults
+
+def getargvalues(frame):
+    """Get information about arguments passed into a particular frame.
+
+    A tuple of four things is returned: (args, varargs, varkw, locals).
+    'args' is a list of the argument names (it may contain nested lists).
+    'varargs' and 'varkw' are the names of the * and ** arguments or None.
+    'locals' is the locals dictionary of the given frame."""
+    args, varargs, varkw = getargs(frame.f_code)
+    return args, varargs, varkw, frame.f_locals
+
+def joinseq(seq):
+    if len(seq) == 1:
+        return '(' + seq[0] + ',)'
+    else:
+        return '(' + string.join(seq, ', ') + ')'
+
+def strseq(object, convert, join=joinseq):
+    """Recursively walk a sequence, stringifying each element."""
+    if type(object) in (list, tuple):
+        return join(map(lambda o, c=convert, j=join: strseq(o, c, j), object))
+    else:
+        return convert(object)
+
+def formatargspec(args, varargs=None, varkw=None, defaults=None,
+                  formatarg=str,
+                  formatvarargs=lambda name: '*' + name,
+                  formatvarkw=lambda name: '**' + name,
+                  formatvalue=lambda value: '=' + repr(value),
+                  join=joinseq):
+    """Format an argument spec from the 4 values returned by getargspec.
+
+    The first four arguments are (args, varargs, varkw, defaults).  The
+    other four arguments are the corresponding optional formatting functions
+    that are called to turn names and values into strings.  The ninth
+    argument is an optional function to format the sequence of arguments."""
+    specs = []
+    if defaults:
+        firstdefault = len(args) - len(defaults)
+    for i in range(len(args)):
+        spec = strseq(args[i], formatarg, join)
+        if defaults and i >= firstdefault:
+            spec = spec + formatvalue(defaults[i - firstdefault])
+        specs.append(spec)
+    if varargs is not None:
+        specs.append(formatvarargs(varargs))
+    if varkw is not None:
+        specs.append(formatvarkw(varkw))
+    return '(' + string.join(specs, ', ') + ')'
+
+def formatargvalues(args, varargs, varkw, locals,
+                    formatarg=str,
+                    formatvarargs=lambda name: '*' + name,
+                    formatvarkw=lambda name: '**' + name,
+                    formatvalue=lambda value: '=' + repr(value),
+                    join=joinseq):
+    """Format an argument spec from the 4 values returned by getargvalues.
+
+    The first four arguments are (args, varargs, varkw, locals).  The
+    next four arguments are the corresponding optional formatting functions
+    that are called to turn names and values into strings.  The ninth
+    argument is an optional function to format the sequence of arguments."""
+    def convert(name, locals=locals,
+                formatarg=formatarg, formatvalue=formatvalue):
+        return formatarg(name) + formatvalue(locals[name])
+    specs = []
+    for i in range(len(args)):
+        specs.append(strseq(args[i], convert, join))
+    if varargs:
+        specs.append(formatvarargs(varargs) + formatvalue(locals[varargs]))
+    if varkw:
+        specs.append(formatvarkw(varkw) + formatvalue(locals[varkw]))
+    return '(' + string.join(specs, ', ') + ')'
+
+# -------------------------------------------------- stack frame extraction
+def getframeinfo(frame, context=1):
+    """Get information about a frame or traceback object.
+
+    A tuple of five things is returned: the filename, the line number of
+    the current line, the function name, a list of lines of context from
+    the source code, and the index of the current line within that list.
+    The optional second argument specifies the number of lines of context
+    to return, which are centered around the current line."""
+    if istraceback(frame):
+        lineno = frame.tb_lineno
+        frame = frame.tb_frame
+    else:
+        lineno = frame.f_lineno
+    if not isframe(frame):
+        raise TypeError('arg is not a frame or traceback object')
+
+    filename = getsourcefile(frame) or getfile(frame)
+    if context > 0:
+        start = lineno - 1 - context//2
+        try:
+            lines, lnum = findsource(frame)
+        except IOError:
+            lines = index = None
+        else:
+            start = max(start, 1)
+            start = max(0, min(start, len(lines) - context))
+            lines = lines[start:start+context]
+            index = lineno - 1 - start
+    else:
+        lines = index = None
+
+    return (filename, lineno, frame.f_code.co_name, lines, index)
+
+def getlineno(frame):
+    """Get the line number from a frame object, allowing for optimization."""
+    # FrameType.f_lineno is now a descriptor that grovels co_lnotab
+    return frame.f_lineno
+
+def getouterframes(frame, context=1):
+    """Get a list of records for a frame and all higher (calling) frames.
+
+    Each record contains a frame object, filename, line number, function
+    name, a list of lines of context, and index within the context."""
+    framelist = []
+    while frame:
+        framelist.append((frame,) + getframeinfo(frame, context))
+        frame = frame.f_back
+    return framelist
+
+def getinnerframes(tb, context=1):
+    """Get a list of records for a traceback's frame and all lower frames.
+
+    Each record contains a frame object, filename, line number, function
+    name, a list of lines of context, and index within the context."""
+    framelist = []
+    while tb:
+        framelist.append((tb.tb_frame,) + getframeinfo(tb, context))
+        tb = tb.tb_next
+    return framelist
+
+currentframe = sys._getframe
+
+def stack(context=1):
+    """Return a list of records for the stack above the caller's frame."""
+    return getouterframes(sys._getframe(1), context)
+
+def trace(context=1):
+    """Return a list of records for the stack below the current exception."""
+    return getinnerframes(sys.exc_info()[2], context)

Added: vendor/Python/current/Lib/keyword.py
===================================================================
--- vendor/Python/current/Lib/keyword.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/keyword.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,95 @@
+#! /usr/bin/env python
+
+"""Keywords (from "graminit.c")
+
+This file is automatically generated; please don't muck it up!
+
+To update the symbols in this file, 'cd' to the top directory of
+the python source tree after building the interpreter and run:
+
+    python Lib/keyword.py
+"""
+
+__all__ = ["iskeyword", "kwlist"]
+
+kwlist = [
+#--start keywords--
+        'and',
+        'as',
+        'assert',
+        'break',
+        'class',
+        'continue',
+        'def',
+        'del',
+        'elif',
+        'else',
+        'except',
+        'exec',
+        'finally',
+        'for',
+        'from',
+        'global',
+        'if',
+        'import',
+        'in',
+        'is',
+        'lambda',
+        'not',
+        'or',
+        'pass',
+        'print',
+        'raise',
+        'return',
+        'try',
+        'while',
+        'with',
+        'yield',
+#--end keywords--
+        ]
+
+iskeyword = frozenset(kwlist).__contains__
+
+def main():
+    import sys, re
+
+    args = sys.argv[1:]
+    iptfile = args and args[0] or "Python/graminit.c"
+    if len(args) > 1: optfile = args[1]
+    else: optfile = "Lib/keyword.py"
+
+    # scan the source file for keywords
+    fp = open(iptfile)
+    strprog = re.compile('"([^"]+)"')
+    lines = []
+    while 1:
+        line = fp.readline()
+        if not line: break
+        if '{1, "' in line:
+            match = strprog.search(line)
+            if match:
+                lines.append("        '" + match.group(1) + "',\n")
+    fp.close()
+    lines.sort()
+
+    # load the output skeleton from the target
+    fp = open(optfile)
+    format = fp.readlines()
+    fp.close()
+
+    # insert the lines of keywords
+    try:
+        start = format.index("#--start keywords--\n") + 1
+        end = format.index("#--end keywords--\n")
+        format[start:end] = lines
+    except ValueError:
+        sys.stderr.write("target does not contain format markers\n")
+        sys.exit(1)
+
+    # write the output file
+    fp = open(optfile, 'w')
+    fp.write(''.join(format))
+    fp.close()
+
+if __name__ == "__main__":
+    main()


Property changes on: vendor/Python/current/Lib/keyword.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/lib-tk/Canvas.py
===================================================================
--- vendor/Python/current/Lib/lib-tk/Canvas.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/lib-tk/Canvas.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,190 @@
+# This module exports classes for the various canvas item types
+
+# NOTE: This module was an experiment and is now obsolete.
+# It's best to use the Tkinter.Canvas class directly.
+
+from Tkinter import Canvas, _cnfmerge, _flatten
+
+
+class CanvasItem:
+    def __init__(self, canvas, itemType, *args, **kw):
+        self.canvas = canvas
+        self.id = canvas._create(itemType, args, kw)
+        if not hasattr(canvas, 'items'):
+            canvas.items = {}
+        canvas.items[self.id] = self
+    def __str__(self):
+        return str(self.id)
+    def __repr__(self):
+        return '<%s, id=%d>' % (self.__class__.__name__, self.id)
+    def delete(self):
+        del self.canvas.items[self.id]
+        self.canvas.delete(self.id)
+    def __getitem__(self, key):
+        v = self.canvas.tk.split(self.canvas.tk.call(
+                self.canvas._w, 'itemconfigure',
+                self.id, '-' + key))
+        return v[4]
+    cget = __getitem__
+    def __setitem__(self, key, value):
+        self.canvas.itemconfig(self.id, {key: value})
+    def keys(self):
+        if not hasattr(self, '_keys'):
+            self._keys = map(lambda x, tk=self.canvas.tk:
+                             tk.splitlist(x)[0][1:],
+                             self.canvas.tk.splitlist(
+                                     self.canvas._do(
+                                             'itemconfigure',
+                                             (self.id,))))
+        return self._keys
+    def has_key(self, key):
+        return key in self.keys()
+    def __contains__(self, key):
+        return key in self.keys()
+    def addtag(self, tag, option='withtag'):
+        self.canvas.addtag(tag, option, self.id)
+    def bbox(self):
+        x1, y1, x2, y2 = self.canvas.bbox(self.id)
+        return (x1, y1), (x2, y2)
+    def bind(self, sequence=None, command=None, add=None):
+        return self.canvas.tag_bind(self.id, sequence, command, add)
+    def unbind(self, sequence, funcid=None):
+        self.canvas.tag_unbind(self.id, sequence, funcid)
+    def config(self, cnf={}, **kw):
+        return self.canvas.itemconfig(self.id, _cnfmerge((cnf, kw)))
+    def coords(self, pts = ()):
+        flat = ()
+        for x, y in pts: flat = flat + (x, y)
+        return self.canvas.coords(self.id, *flat)
+    def dchars(self, first, last=None):
+        self.canvas.dchars(self.id, first, last)
+    def dtag(self, ttd):
+        self.canvas.dtag(self.id, ttd)
+    def focus(self):
+        self.canvas.focus(self.id)
+    def gettags(self):
+        return self.canvas.gettags(self.id)
+    def icursor(self, index):
+        self.canvas.icursor(self.id, index)
+    def index(self, index):
+        return self.canvas.index(self.id, index)
+    def insert(self, beforethis, string):
+        self.canvas.insert(self.id, beforethis, string)
+    def lower(self, belowthis=None):
+        self.canvas.tag_lower(self.id, belowthis)
+    def move(self, xamount, yamount):
+        self.canvas.move(self.id, xamount, yamount)
+    def tkraise(self, abovethis=None):
+        self.canvas.tag_raise(self.id, abovethis)
+    raise_ = tkraise # BW compat
+    def scale(self, xorigin, yorigin, xscale, yscale):
+        self.canvas.scale(self.id, xorigin, yorigin, xscale, yscale)
+    def type(self):
+        return self.canvas.type(self.id)
+
+class Arc(CanvasItem):
+    def __init__(self, canvas, *args, **kw):
+        CanvasItem.__init__(self, canvas, 'arc', *args, **kw)
+
+class Bitmap(CanvasItem):
+    def __init__(self, canvas, *args, **kw):
+        CanvasItem.__init__(self, canvas, 'bitmap', *args, **kw)
+
+class ImageItem(CanvasItem):
+    def __init__(self, canvas, *args, **kw):
+        CanvasItem.__init__(self, canvas, 'image', *args, **kw)
+
+class Line(CanvasItem):
+    def __init__(self, canvas, *args, **kw):
+        CanvasItem.__init__(self, canvas, 'line', *args, **kw)
+
+class Oval(CanvasItem):
+    def __init__(self, canvas, *args, **kw):
+        CanvasItem.__init__(self, canvas, 'oval', *args, **kw)
+
+class Polygon(CanvasItem):
+    def __init__(self, canvas, *args, **kw):
+        CanvasItem.__init__(self, canvas, 'polygon', *args, **kw)
+
+class Rectangle(CanvasItem):
+    def __init__(self, canvas, *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):
+        CanvasItem.__init__(self, canvas, 'text', *args, **kw)
+
+class Window(CanvasItem):
+    def __init__(self, canvas, *args, **kw):
+        CanvasItem.__init__(self, canvas, 'window', *args, **kw)
+
+class Group:
+    def __init__(self, canvas, tag=None):
+        if not tag:
+            tag = 'Group%d' % id(self)
+        self.tag = self.id = tag
+        self.canvas = canvas
+        self.canvas.dtag(self.tag)
+    def str(self):
+        return self.tag
+    __str__ = str
+    def _do(self, cmd, *args):
+        return self.canvas._do(cmd, (self.tag,) + _flatten(args))
+    def addtag_above(self, tagOrId):
+        self._do('addtag', 'above', tagOrId)
+    def addtag_all(self):
+        self._do('addtag', 'all')
+    def addtag_below(self, tagOrId):
+        self._do('addtag', 'below', tagOrId)
+    def addtag_closest(self, x, y, halo=None, start=None):
+        self._do('addtag', 'closest', x, y, halo, start)
+    def addtag_enclosed(self, x1, y1, x2, y2):
+        self._do('addtag', 'enclosed', x1, y1, x2, y2)
+    def addtag_overlapping(self, x1, y1, x2, y2):
+        self._do('addtag', 'overlapping', x1, y1, x2, y2)
+    def addtag_withtag(self, tagOrId):
+        self._do('addtag', 'withtag', tagOrId)
+    def bbox(self):
+        return self.canvas._getints(self._do('bbox'))
+    def bind(self, sequence=None, command=None, add=None):
+        return self.canvas.tag_bind(self.id, sequence, command, add)
+    def unbind(self, sequence, funcid=None):
+        self.canvas.tag_unbind(self.id, sequence, funcid)
+    def coords(self, *pts):
+        return self._do('coords', pts)
+    def dchars(self, first, last=None):
+        self._do('dchars', first, last)
+    def delete(self):
+        self._do('delete')
+    def dtag(self, tagToDelete=None):
+        self._do('dtag', tagToDelete)
+    def focus(self):
+        self._do('focus')
+    def gettags(self):
+        return self.canvas.tk.splitlist(self._do('gettags', self.tag))
+    def icursor(self, index):
+        return self._do('icursor', index)
+    def index(self, index):
+        return self.canvas.tk.getint(self._do('index', index))
+    def insert(self, beforeThis, string):
+        self._do('insert', beforeThis, string)
+    def config(self, cnf={}, **kw):
+        return self.canvas.itemconfigure(self.tag, _cnfmerge((cnf,kw)))
+    def lower(self, belowThis=None):
+        self._do('lower', belowThis)
+    def move(self, xAmount, yAmount):
+        self._do('move', xAmount, yAmount)
+    def tkraise(self, aboveThis=None):
+        self._do('raise', aboveThis)
+    lift = tkraise
+    def scale(self, xOrigin, yOrigin, xScale, yScale):
+        self._do('scale', xOrigin, yOrigin, xScale, yScale)
+    def select_adjust(self, index):
+        self.canvas._do('select', ('adjust', self.tag, index))
+    def select_from(self, index):
+        self.canvas._do('select', ('from', self.tag, index))
+    def select_to(self, index):
+        self.canvas._do('select', ('to', self.tag, index))
+    def type(self):
+        return self._do('type')

Added: vendor/Python/current/Lib/lib-tk/Dialog.py
===================================================================
--- vendor/Python/current/Lib/lib-tk/Dialog.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/lib-tk/Dialog.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,49 @@
+# Dialog.py -- Tkinter interface to the tk_dialog script.
+
+from Tkinter import *
+from Tkinter import _cnfmerge
+
+if TkVersion <= 3.6:
+    DIALOG_ICON = 'warning'
+else:
+    DIALOG_ICON = 'questhead'
+
+
+class Dialog(Widget):
+    def __init__(self, master=None, cnf={}, **kw):
+        cnf = _cnfmerge((cnf, kw))
+        self.widgetName = '__dialog__'
+        Widget._setup(self, master, cnf)
+        self.num = self.tk.getint(
+                self.tk.call(
+                      'tk_dialog', self._w,
+                      cnf['title'], cnf['text'],
+                      cnf['bitmap'], cnf['default'],
+                      *cnf['strings']))
+        try: Widget.destroy(self)
+        except TclError: pass
+    def destroy(self): pass
+
+def _test():
+    d = Dialog(None, {'title': 'File Modified',
+                      'text':
+                      'File "Python.h" has been modified'
+                      ' since the last time it was saved.'
+                      ' Do you want to save it before'
+                      ' exiting the application.',
+                      'bitmap': DIALOG_ICON,
+                      'default': 0,
+                      'strings': ('Save File',
+                                  'Discard Changes',
+                                  'Return to Editor')})
+    print d.num
+
+
+if __name__ == '__main__':
+    t = Button(None, {'text': 'Test',
+                      'command': _test,
+                      Pack: {}})
+    q = Button(None, {'text': 'Quit',
+                      'command': t.quit,
+                      Pack: {}})
+    t.mainloop()

Added: vendor/Python/current/Lib/lib-tk/FileDialog.py
===================================================================
--- vendor/Python/current/Lib/lib-tk/FileDialog.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/lib-tk/FileDialog.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,274 @@
+"""File selection dialog classes.
+
+Classes:
+
+- FileDialog
+- LoadFileDialog
+- SaveFileDialog
+
+"""
+
+from Tkinter import *
+from Dialog import Dialog
+
+import os
+import fnmatch
+
+
+dialogstates = {}
+
+
+class FileDialog:
+
+    """Standard file selection dialog -- no checks on selected file.
+
+    Usage:
+
+        d = FileDialog(master)
+        fname = d.go(dir_or_file, pattern, default, key)
+        if fname is None: ...canceled...
+        else: ...open file...
+
+    All arguments to go() are optional.
+
+    The 'key' argument specifies a key in the global dictionary
+    'dialogstates', which keeps track of the values for the directory
+    and pattern arguments, overriding the values passed in (it does
+    not keep track of the default argument!).  If no key is specified,
+    the dialog keeps no memory of previous state.  Note that memory is
+    kept even when the dialog is canceled.  (All this emulates the
+    behavior of the Macintosh file selection dialogs.)
+
+    """
+
+    title = "File Selection Dialog"
+
+    def __init__(self, master, title=None):
+        if title is None: title = self.title
+        self.master = master
+        self.directory = None
+
+        self.top = Toplevel(master)
+        self.top.title(title)
+        self.top.iconname(title)
+
+        self.botframe = Frame(self.top)
+        self.botframe.pack(side=BOTTOM, fill=X)
+
+        self.selection = Entry(self.top)
+        self.selection.pack(side=BOTTOM, fill=X)
+        self.selection.bind('<Return>', self.ok_event)
+
+        self.filter = Entry(self.top)
+        self.filter.pack(side=TOP, fill=X)
+        self.filter.bind('<Return>', self.filter_command)
+
+        self.midframe = Frame(self.top)
+        self.midframe.pack(expand=YES, fill=BOTH)
+
+        self.filesbar = Scrollbar(self.midframe)
+        self.filesbar.pack(side=RIGHT, fill=Y)
+        self.files = Listbox(self.midframe, exportselection=0,
+                             yscrollcommand=(self.filesbar, 'set'))
+        self.files.pack(side=RIGHT, expand=YES, fill=BOTH)
+        btags = self.files.bindtags()
+        self.files.bindtags(btags[1:] + btags[:1])
+        self.files.bind('<ButtonRelease-1>', self.files_select_event)
+        self.files.bind('<Double-ButtonRelease-1>', self.files_double_event)
+        self.filesbar.config(command=(self.files, 'yview'))
+
+        self.dirsbar = Scrollbar(self.midframe)
+        self.dirsbar.pack(side=LEFT, fill=Y)
+        self.dirs = Listbox(self.midframe, exportselection=0,
+                            yscrollcommand=(self.dirsbar, 'set'))
+        self.dirs.pack(side=LEFT, expand=YES, fill=BOTH)
+        self.dirsbar.config(command=(self.dirs, 'yview'))
+        btags = self.dirs.bindtags()
+        self.dirs.bindtags(btags[1:] + btags[:1])
+        self.dirs.bind('<ButtonRelease-1>', self.dirs_select_event)
+        self.dirs.bind('<Double-ButtonRelease-1>', self.dirs_double_event)
+
+        self.ok_button = Button(self.botframe,
+                                 text="OK",
+                                 command=self.ok_command)
+        self.ok_button.pack(side=LEFT)
+        self.filter_button = Button(self.botframe,
+                                    text="Filter",
+                                    command=self.filter_command)
+        self.filter_button.pack(side=LEFT, expand=YES)
+        self.cancel_button = Button(self.botframe,
+                                    text="Cancel",
+                                    command=self.cancel_command)
+        self.cancel_button.pack(side=RIGHT)
+
+        self.top.protocol('WM_DELETE_WINDOW', self.cancel_command)
+        # XXX Are the following okay for a general audience?
+        self.top.bind('<Alt-w>', self.cancel_command)
+        self.top.bind('<Alt-W>', self.cancel_command)
+
+    def go(self, dir_or_file=os.curdir, pattern="*", default="", key=None):
+        if key and dialogstates.has_key(key):
+            self.directory, pattern = dialogstates[key]
+        else:
+            dir_or_file = os.path.expanduser(dir_or_file)
+            if os.path.isdir(dir_or_file):
+                self.directory = dir_or_file
+            else:
+                self.directory, default = os.path.split(dir_or_file)
+        self.set_filter(self.directory, pattern)
+        self.set_selection(default)
+        self.filter_command()
+        self.selection.focus_set()
+        self.top.wait_visibility() # window needs to be visible for the grab
+        self.top.grab_set()
+        self.how = None
+        self.master.mainloop()          # Exited by self.quit(how)
+        if key:
+            directory, pattern = self.get_filter()
+            if self.how:
+                directory = os.path.dirname(self.how)
+            dialogstates[key] = directory, pattern
+        self.top.destroy()
+        return self.how
+
+    def quit(self, how=None):
+        self.how = how
+        self.master.quit()              # Exit mainloop()
+
+    def dirs_double_event(self, event):
+        self.filter_command()
+
+    def dirs_select_event(self, event):
+        dir, pat = self.get_filter()
+        subdir = self.dirs.get('active')
+        dir = os.path.normpath(os.path.join(self.directory, subdir))
+        self.set_filter(dir, pat)
+
+    def files_double_event(self, event):
+        self.ok_command()
+
+    def files_select_event(self, event):
+        file = self.files.get('active')
+        self.set_selection(file)
+
+    def ok_event(self, event):
+        self.ok_command()
+
+    def ok_command(self):
+        self.quit(self.get_selection())
+
+    def filter_command(self, event=None):
+        dir, pat = self.get_filter()
+        try:
+            names = os.listdir(dir)
+        except os.error:
+            self.master.bell()
+            return
+        self.directory = dir
+        self.set_filter(dir, pat)
+        names.sort()
+        subdirs = [os.pardir]
+        matchingfiles = []
+        for name in names:
+            fullname = os.path.join(dir, name)
+            if os.path.isdir(fullname):
+                subdirs.append(name)
+            elif fnmatch.fnmatch(name, pat):
+                matchingfiles.append(name)
+        self.dirs.delete(0, END)
+        for name in subdirs:
+            self.dirs.insert(END, name)
+        self.files.delete(0, END)
+        for name in matchingfiles:
+            self.files.insert(END, name)
+        head, tail = os.path.split(self.get_selection())
+        if tail == os.curdir: tail = ''
+        self.set_selection(tail)
+
+    def get_filter(self):
+        filter = self.filter.get()
+        filter = os.path.expanduser(filter)
+        if filter[-1:] == os.sep or os.path.isdir(filter):
+            filter = os.path.join(filter, "*")
+        return os.path.split(filter)
+
+    def get_selection(self):
+        file = self.selection.get()
+        file = os.path.expanduser(file)
+        return file
+
+    def cancel_command(self, event=None):
+        self.quit()
+
+    def set_filter(self, dir, pat):
+        if not os.path.isabs(dir):
+            try:
+                pwd = os.getcwd()
+            except os.error:
+                pwd = None
+            if pwd:
+                dir = os.path.join(pwd, dir)
+                dir = os.path.normpath(dir)
+        self.filter.delete(0, END)
+        self.filter.insert(END, os.path.join(dir or os.curdir, pat or "*"))
+
+    def set_selection(self, file):
+        self.selection.delete(0, END)
+        self.selection.insert(END, os.path.join(self.directory, file))
+
+
+class LoadFileDialog(FileDialog):
+
+    """File selection dialog which checks that the file exists."""
+
+    title = "Load File Selection Dialog"
+
+    def ok_command(self):
+        file = self.get_selection()
+        if not os.path.isfile(file):
+            self.master.bell()
+        else:
+            self.quit(file)
+
+
+class SaveFileDialog(FileDialog):
+
+    """File selection dialog which checks that the file may be created."""
+
+    title = "Save File Selection Dialog"
+
+    def ok_command(self):
+        file = self.get_selection()
+        if os.path.exists(file):
+            if os.path.isdir(file):
+                self.master.bell()
+                return
+            d = Dialog(self.top,
+                       title="Overwrite Existing File Question",
+                       text="Overwrite existing file %r?" % (file,),
+                       bitmap='questhead',
+                       default=1,
+                       strings=("Yes", "Cancel"))
+            if d.num != 0:
+                return
+        else:
+            head, tail = os.path.split(file)
+            if not os.path.isdir(head):
+                self.master.bell()
+                return
+        self.quit(file)
+
+
+def test():
+    """Simple test program."""
+    root = Tk()
+    root.withdraw()
+    fd = LoadFileDialog(root)
+    loadfile = fd.go(key="test")
+    fd = SaveFileDialog(root)
+    savefile = fd.go(key="test")
+    print loadfile, savefile
+
+
+if __name__ == '__main__':
+    test()

Added: vendor/Python/current/Lib/lib-tk/FixTk.py
===================================================================
--- vendor/Python/current/Lib/lib-tk/FixTk.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/lib-tk/FixTk.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,37 @@
+import sys, os
+
+# Delay import _tkinter until we have set TCL_LIBRARY,
+# so that Tcl_FindExecutable has a chance to locate its
+# encoding directory.
+
+# Unfortunately, we cannot know the TCL_LIBRARY directory
+# if we don't know the tcl version, which we cannot find out
+# without import Tcl. Fortunately, Tcl will itself look in
+# <TCL_LIBRARY>\..\tcl<TCL_VERSION>, so anything close to
+# the real Tcl library will do.
+
+prefix = os.path.join(sys.prefix,"tcl")
+# if this does not exist, no further search is needed
+if os.path.exists(prefix):
+    if not os.environ.has_key("TCL_LIBRARY"):
+        for name in os.listdir(prefix):
+            if name.startswith("tcl"):
+                tcldir = os.path.join(prefix,name)
+                if os.path.isdir(tcldir):
+                    os.environ["TCL_LIBRARY"] = tcldir
+    # Compute TK_LIBRARY, knowing that it has the same version
+    # as Tcl
+    import _tkinter
+    ver = str(_tkinter.TCL_VERSION)
+    if not os.environ.has_key("TK_LIBRARY"):
+        v = os.path.join(prefix, 'tk'+ver)
+        if os.path.exists(os.path.join(v, "tclIndex")):
+            os.environ['TK_LIBRARY'] = v
+    # We don't know the Tix version, so we must search the entire
+    # directory
+    if not os.environ.has_key("TIX_LIBRARY"):
+        for name in os.listdir(prefix):
+            if name.startswith("tix"):
+                tixdir = os.path.join(prefix,name)
+                if os.path.isdir(tixdir):
+                    os.environ["TIX_LIBRARY"] = tixdir

Added: vendor/Python/current/Lib/lib-tk/ScrolledText.py
===================================================================
--- vendor/Python/current/Lib/lib-tk/ScrolledText.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/lib-tk/ScrolledText.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,43 @@
+# A ScrolledText widget feels like a text widget but also has a
+# vertical scroll bar on its right.  (Later, options may be added to
+# add a horizontal bar as well, to make the bars disappear
+# automatically when not needed, to move them to the other side of the
+# window, etc.)
+#
+# Configuration options are passed to the Text widget.
+# A Frame widget is inserted between the master and the text, to hold
+# the Scrollbar widget.
+# Most methods calls are inherited from the Text widget; Pack methods
+# are redirected to the Frame widget however.
+
+from Tkinter import *
+from Tkinter import _cnfmerge
+
+class ScrolledText(Text):
+    def __init__(self, master=None, cnf=None, **kw):
+        if cnf is None:
+            cnf = {}
+        if kw:
+            cnf = _cnfmerge((cnf, kw))
+        fcnf = {}
+        for k in cnf.keys():
+            if type(k) == ClassType or k == 'name':
+                fcnf[k] = cnf[k]
+                del cnf[k]
+        self.frame = Frame(master, **fcnf)
+        self.vbar = Scrollbar(self.frame, name='vbar')
+        self.vbar.pack(side=RIGHT, fill=Y)
+        cnf['name'] = 'text'
+        Text.__init__(self, self.frame, **cnf)
+        self.pack(side=LEFT, fill=BOTH, expand=1)
+        self['yscrollcommand'] = self.vbar.set
+        self.vbar['command'] = self.yview
+
+        # Copy geometry methods of self.frame -- hack!
+        methods = Pack.__dict__.keys()
+        methods = methods + Grid.__dict__.keys()
+        methods = methods + Place.__dict__.keys()
+
+        for m in methods:
+            if m[0] != '_' and m != 'config' and m != 'configure':
+                setattr(self, m, getattr(self.frame, m))

Added: vendor/Python/current/Lib/lib-tk/SimpleDialog.py
===================================================================
--- vendor/Python/current/Lib/lib-tk/SimpleDialog.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/lib-tk/SimpleDialog.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,112 @@
+"""A simple but flexible modal dialog box."""
+
+
+from Tkinter import *
+
+
+class SimpleDialog:
+
+    def __init__(self, master,
+                 text='', buttons=[], default=None, cancel=None,
+                 title=None, class_=None):
+        if class_:
+            self.root = Toplevel(master, class_=class_)
+        else:
+            self.root = Toplevel(master)
+        if title:
+            self.root.title(title)
+            self.root.iconname(title)
+        self.message = Message(self.root, text=text, aspect=400)
+        self.message.pack(expand=1, fill=BOTH)
+        self.frame = Frame(self.root)
+        self.frame.pack()
+        self.num = default
+        self.cancel = cancel
+        self.default = default
+        self.root.bind('<Return>', self.return_event)
+        for num in range(len(buttons)):
+            s = buttons[num]
+            b = Button(self.frame, text=s,
+                       command=(lambda self=self, num=num: self.done(num)))
+            if num == default:
+                b.config(relief=RIDGE, borderwidth=8)
+            b.pack(side=LEFT, fill=BOTH, expand=1)
+        self.root.protocol('WM_DELETE_WINDOW', self.wm_delete_window)
+        self._set_transient(master)
+
+    def _set_transient(self, master, relx=0.5, rely=0.3):
+        widget = self.root
+        widget.withdraw() # Remain invisible while we figure out the geometry
+        widget.transient(master)
+        widget.update_idletasks() # Actualize geometry information
+        if master.winfo_ismapped():
+            m_width = master.winfo_width()
+            m_height = master.winfo_height()
+            m_x = master.winfo_rootx()
+            m_y = master.winfo_rooty()
+        else:
+            m_width = master.winfo_screenwidth()
+            m_height = master.winfo_screenheight()
+            m_x = m_y = 0
+        w_width = widget.winfo_reqwidth()
+        w_height = widget.winfo_reqheight()
+        x = m_x + (m_width - w_width) * relx
+        y = m_y + (m_height - w_height) * rely
+        if x+w_width > master.winfo_screenwidth():
+            x = master.winfo_screenwidth() - w_width
+        elif x < 0:
+            x = 0
+        if y+w_height > master.winfo_screenheight():
+            y = master.winfo_screenheight() - w_height
+        elif y < 0:
+            y = 0
+        widget.geometry("+%d+%d" % (x, y))
+        widget.deiconify() # Become visible at the desired location
+
+    def go(self):
+        self.root.wait_visibility()
+        self.root.grab_set()
+        self.root.mainloop()
+        self.root.destroy()
+        return self.num
+
+    def return_event(self, event):
+        if self.default is None:
+            self.root.bell()
+        else:
+            self.done(self.default)
+
+    def wm_delete_window(self):
+        if self.cancel is None:
+            self.root.bell()
+        else:
+            self.done(self.cancel)
+
+    def done(self, num):
+        self.num = num
+        self.root.quit()
+
+
+if __name__ == '__main__':
+
+    def test():
+        root = Tk()
+        def doit(root=root):
+            d = SimpleDialog(root,
+                         text="This is a test dialog.  "
+                              "Would this have been an actual dialog, "
+                              "the buttons below would have been glowing "
+                              "in soft pink light.\n"
+                              "Do you believe this?",
+                         buttons=["Yes", "No", "Cancel"],
+                         default=0,
+                         cancel=2,
+                         title="Test Dialog")
+            print d.go()
+        t = Button(root, text='Test', command=doit)
+        t.pack()
+        q = Button(root, text='Quit', command=t.quit)
+        q.pack()
+        t.mainloop()
+
+    test()

Added: vendor/Python/current/Lib/lib-tk/Tix.py
===================================================================
--- vendor/Python/current/Lib/lib-tk/Tix.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/lib-tk/Tix.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1891 @@
+# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
+#
+# $Id: Tix.py 52785 2006-11-18 18:42:22Z martin.v.loewis $
+#
+# Tix.py -- Tix widget wrappers.
+#
+#       For Tix, see http://tix.sourceforge.net
+#
+#       - Sudhir Shenoy (sshenoy at gol.com), Dec. 1995.
+#         based on an idea of Jean-Marc Lugrin (lugrin at ms.com)
+#
+# NOTE: In order to minimize changes to Tkinter.py, some of the code here
+#       (TixWidget.__init__) has been taken from Tkinter (Widget.__init__)
+#       and will break if there are major changes in Tkinter.
+#
+# The Tix widgets are represented by a class hierarchy in python with proper
+# inheritance of base classes.
+#
+# As a result after creating a 'w = StdButtonBox', I can write
+#              w.ok['text'] = 'Who Cares'
+#    or              w.ok['bg'] = w['bg']
+# or even       w.ok.invoke()
+# etc.
+#
+# Compare the demo tixwidgets.py to the original Tcl program and you will
+# appreciate the advantages.
+#
+
+from Tkinter import *
+from Tkinter import _flatten, _cnfmerge, _default_root
+
+# WARNING - TkVersion is a limited precision floating point number
+if TkVersion < 3.999:
+    raise ImportError, "This version of Tix.py requires Tk 4.0 or higher"
+
+import _tkinter # If this fails your Python may not be configured for Tk
+
+# Some more constants (for consistency with Tkinter)
+WINDOW = 'window'
+TEXT = 'text'
+STATUS = 'status'
+IMMEDIATE = 'immediate'
+IMAGE = 'image'
+IMAGETEXT = 'imagetext'
+BALLOON = 'balloon'
+AUTO = 'auto'
+ACROSSTOP = 'acrosstop'
+
+# Some constants used by Tkinter dooneevent()
+TCL_DONT_WAIT     = 1 << 1
+TCL_WINDOW_EVENTS = 1 << 2
+TCL_FILE_EVENTS   = 1 << 3
+TCL_TIMER_EVENTS  = 1 << 4
+TCL_IDLE_EVENTS   = 1 << 5
+TCL_ALL_EVENTS    = 0
+
+# BEWARE - this is implemented by copying some code from the Widget class
+#          in Tkinter (to override Widget initialization) and is therefore
+#          liable to break.
+import Tkinter, os
+
+# Could probably add this to Tkinter.Misc
+class tixCommand:
+    """The tix commands provide access to miscellaneous  elements
+    of  Tix's  internal state and the Tix application context.
+    Most of the information manipulated by these  commands pertains
+    to  the  application  as a whole, or to a screen or
+    display, rather than to a particular window.
+
+    This is a mixin class, assumed to be mixed to Tkinter.Tk
+    that supports the self.tk.call method.
+    """
+
+    def tix_addbitmapdir(self, directory):
+        """Tix maintains a list of directories under which
+        the  tix_getimage  and tix_getbitmap commands will
+        search for image files. The standard bitmap  directory
+        is $TIX_LIBRARY/bitmaps. The addbitmapdir command
+        adds directory into this list. By  using  this
+        command, the  image  files  of an applications can
+        also be located using the tix_getimage or tix_getbitmap
+        command.
+        """
+        return self.tk.call('tix', 'addbitmapdir', directory)
+
+    def tix_cget(self, option):
+        """Returns  the  current  value  of the configuration
+        option given by option. Option may be  any  of  the
+        options described in the CONFIGURATION OPTIONS section.
+        """
+        return self.tk.call('tix', 'cget', option)
+
+    def tix_configure(self, cnf=None, **kw):
+        """Query or modify the configuration options of the Tix application
+        context. If no option is specified, returns a dictionary all of the
+        available options.  If option is specified with no value, then the
+        command returns a list describing the one named option (this list
+        will be identical to the corresponding sublist of the value
+        returned if no option is specified).  If one or more option-value
+        pairs are specified, then the command modifies the given option(s)
+        to have the given value(s); in this case the command returns an
+        empty string. Option may be any of the configuration options.
+        """
+        # Copied from Tkinter.py
+        if kw:
+            cnf = _cnfmerge((cnf, kw))
+        elif cnf:
+            cnf = _cnfmerge(cnf)
+        if cnf is None:
+            cnf = {}
+            for x in self.tk.split(self.tk.call('tix', 'configure')):
+                cnf[x[0][1:]] = (x[0][1:],) + x[1:]
+            return cnf
+        if isinstance(cnf, StringType):
+            x = self.tk.split(self.tk.call('tix', 'configure', '-'+cnf))
+            return (x[0][1:],) + x[1:]
+        return self.tk.call(('tix', 'configure') + self._options(cnf))
+
+    def tix_filedialog(self, dlgclass=None):
+        """Returns the file selection dialog that may be shared among
+        different calls from this application.  This command will create a
+        file selection dialog widget when it is called the first time. This
+        dialog will be returned by all subsequent calls to tix_filedialog.
+        An optional dlgclass parameter can be passed to specified what type
+        of file selection dialog widget is desired. Possible options are
+        tix FileSelectDialog or tixExFileSelectDialog.
+        """
+        if dlgclass is not None:
+            return self.tk.call('tix', 'filedialog', dlgclass)
+        else:
+            return self.tk.call('tix', 'filedialog')
+
+    def tix_getbitmap(self, name):
+        """Locates a bitmap file of the name name.xpm or name in one of the
+        bitmap directories (see the tix_addbitmapdir command above).  By
+        using tix_getbitmap, you can avoid hard coding the pathnames of the
+        bitmap files in your application. When successful, it returns the
+        complete pathname of the bitmap file, prefixed with the character
+        '@'.  The returned value can be used to configure the -bitmap
+        option of the TK and Tix widgets.
+        """
+        return self.tk.call('tix', 'getbitmap', name)
+
+    def tix_getimage(self, name):
+        """Locates an image file of the name name.xpm, name.xbm or name.ppm
+        in one of the bitmap directories (see the addbitmapdir command
+        above). If more than one file with the same name (but different
+        extensions) exist, then the image type is chosen according to the
+        depth of the X display: xbm images are chosen on monochrome
+        displays and color images are chosen on color displays. By using
+        tix_ getimage, you can advoid hard coding the pathnames of the
+        image files in your application. When successful, this command
+        returns the name of the newly created image, which can be used to
+        configure the -image option of the Tk and Tix widgets.
+        """
+        return self.tk.call('tix', 'getimage', name)
+
+    def tix_option_get(self, name):
+        """Gets  the options  manitained  by  the  Tix
+        scheme mechanism. Available options include:
+
+            active_bg       active_fg      bg
+            bold_font       dark1_bg       dark1_fg
+            dark2_bg        dark2_fg       disabled_fg
+            fg              fixed_font     font
+            inactive_bg     inactive_fg    input1_bg
+            input2_bg       italic_font    light1_bg
+            light1_fg       light2_bg      light2_fg
+            menu_font       output1_bg     output2_bg
+            select_bg       select_fg      selector
+            """
+        # could use self.tk.globalgetvar('tixOption', name)
+        return self.tk.call('tix', 'option', 'get', name)
+
+    def tix_resetoptions(self, newScheme, newFontSet, newScmPrio=None):
+        """Resets the scheme and fontset of the Tix application to
+        newScheme and newFontSet, respectively.  This affects only those
+        widgets created after this call. Therefore, it is best to call the
+        resetoptions command before the creation of any widgets in a Tix
+        application.
+
+        The optional parameter newScmPrio can be given to reset the
+        priority level of the Tk options set by the Tix schemes.
+
+        Because of the way Tk handles the X option database, after Tix has
+        been has imported and inited, it is not possible to reset the color
+        schemes and font sets using the tix config command.  Instead, the
+        tix_resetoptions command must be used.
+        """
+        if newScmPrio is not None:
+            return self.tk.call('tix', 'resetoptions', newScheme, newFontSet, newScmPrio)
+        else:
+            return self.tk.call('tix', 'resetoptions', newScheme, newFontSet)
+
+class Tk(Tkinter.Tk, tixCommand):
+    """Toplevel widget of Tix which represents mostly the main window
+    of an application. It has an associated Tcl interpreter."""
+    def __init__(self, screenName=None, baseName=None, className='Tix'):
+        Tkinter.Tk.__init__(self, screenName, baseName, className)
+        tixlib = os.environ.get('TIX_LIBRARY')
+        self.tk.eval('global auto_path; lappend auto_path [file dir [info nameof]]')
+        if tixlib is not None:
+            self.tk.eval('global auto_path; lappend auto_path {%s}' % tixlib)
+            self.tk.eval('global tcl_pkgPath; lappend tcl_pkgPath {%s}' % tixlib)
+        # Load Tix - this should work dynamically or statically
+        # If it's static, tcl/tix8.1/pkgIndex.tcl should have
+        #               'load {} Tix'
+        # If it's dynamic under Unix, tcl/tix8.1/pkgIndex.tcl should have
+        #               'load libtix8.1.8.3.so Tix'
+        self.tk.eval('package require Tix')
+
+    def destroy(self):
+        # For safety, remove an delete_window binding before destroy
+        self.protocol("WM_DELETE_WINDOW", "")
+        Tkinter.Tk.destroy(self)
+
+# The Tix 'tixForm' geometry manager
+class Form:
+    """The Tix Form geometry manager
+
+    Widgets can be arranged by specifying attachments to other widgets.
+    See Tix documentation for complete details"""
+
+    def config(self, cnf={}, **kw):
+        self.tk.call('tixForm', self._w, *self._options(cnf, kw))
+
+    form = config
+
+    def __setitem__(self, key, value):
+        Form.form(self, {key: value})
+
+    def check(self):
+        return self.tk.call('tixForm', 'check', self._w)
+
+    def forget(self):
+        self.tk.call('tixForm', 'forget', self._w)
+
+    def grid(self, xsize=0, ysize=0):
+        if (not xsize) and (not ysize):
+            x = self.tk.call('tixForm', 'grid', self._w)
+            y = self.tk.splitlist(x)
+            z = ()
+            for x in y:
+                z = z + (self.tk.getint(x),)
+            return z
+        return self.tk.call('tixForm', 'grid', self._w, xsize, ysize)
+
+    def info(self, option=None):
+        if not option:
+            return self.tk.call('tixForm', 'info', self._w)
+        if option[0] != '-':
+            option = '-' + option
+        return self.tk.call('tixForm', 'info', self._w, option)
+
+    def slaves(self):
+        return map(self._nametowidget,
+                   self.tk.splitlist(
+                       self.tk.call(
+                       'tixForm', 'slaves', self._w)))
+
+
+
+Tkinter.Widget.__bases__ = Tkinter.Widget.__bases__ + (Form,)
+
+class TixWidget(Tkinter.Widget):
+    """A TixWidget class is used to package all (or most) Tix widgets.
+
+    Widget initialization is extended in two ways:
+       1) It is possible to give a list of options which must be part of
+       the creation command (so called Tix 'static' options). These cannot be
+       given as a 'config' command later.
+       2) It is possible to give the name of an existing TK widget. These are
+       child widgets created automatically by a Tix mega-widget. The Tk call
+       to create these widgets is therefore bypassed in TixWidget.__init__
+
+    Both options are for use by subclasses only.
+    """
+    def __init__ (self, master=None, widgetName=None,
+                static_options=None, cnf={}, kw={}):
+        # Merge keywords and dictionary arguments
+        if kw:
+            cnf = _cnfmerge((cnf, kw))
+        else:
+            cnf = _cnfmerge(cnf)
+
+        # Move static options into extra. static_options must be
+        # a list of keywords (or None).
+        extra=()
+
+        # 'options' is always a static option
+        if static_options:
+            static_options.append('options')
+        else:
+            static_options = ['options']
+
+        for k,v in cnf.items()[:]:
+            if k in static_options:
+                extra = extra + ('-' + k, v)
+                del cnf[k]
+
+        self.widgetName = widgetName
+        Widget._setup(self, master, cnf)
+
+        # If widgetName is None, this is a dummy creation call where the
+        # corresponding Tk widget has already been created by Tix
+        if widgetName:
+            self.tk.call(widgetName, self._w, *extra)
+
+        # Non-static options - to be done via a 'config' command
+        if cnf:
+            Widget.config(self, cnf)
+
+        # Dictionary to hold subwidget names for easier access. We can't
+        # use the children list because the public Tix names may not be the
+        # same as the pathname component
+        self.subwidget_list = {}
+
+    # We set up an attribute access function so that it is possible to
+    # do w.ok['text'] = 'Hello' rather than w.subwidget('ok')['text'] = 'Hello'
+    # when w is a StdButtonBox.
+    # We can even do w.ok.invoke() because w.ok is subclassed from the
+    # Button class if you go through the proper constructors
+    def __getattr__(self, name):
+        if self.subwidget_list.has_key(name):
+            return self.subwidget_list[name]
+        raise AttributeError, name
+
+    def set_silent(self, value):
+        """Set a variable without calling its action routine"""
+        self.tk.call('tixSetSilent', self._w, value)
+
+    def subwidget(self, name):
+        """Return the named subwidget (which must have been created by
+        the sub-class)."""
+        n = self._subwidget_name(name)
+        if not n:
+            raise TclError, "Subwidget " + name + " not child of " + self._name
+        # Remove header of name and leading dot
+        n = n[len(self._w)+1:]
+        return self._nametowidget(n)
+
+    def subwidgets_all(self):
+        """Return all subwidgets."""
+        names = self._subwidget_names()
+        if not names:
+            return []
+        retlist = []
+        for name in names:
+            name = name[len(self._w)+1:]
+            try:
+                retlist.append(self._nametowidget(name))
+            except:
+                # some of the widgets are unknown e.g. border in LabelFrame
+                pass
+        return retlist
+
+    def _subwidget_name(self,name):
+        """Get a subwidget name (returns a String, not a Widget !)"""
+        try:
+            return self.tk.call(self._w, 'subwidget', name)
+        except TclError:
+            return None
+
+    def _subwidget_names(self):
+        """Return the name of all subwidgets."""
+        try:
+            x = self.tk.call(self._w, 'subwidgets', '-all')
+            return self.tk.split(x)
+        except TclError:
+            return None
+
+    def config_all(self, option, value):
+        """Set configuration options for all subwidgets (and self)."""
+        if option == '':
+            return
+        elif not isinstance(option, StringType):
+            option = repr(option)
+        if not isinstance(value, StringType):
+            value = repr(value)
+        names = self._subwidget_names()
+        for name in names:
+            self.tk.call(name, 'configure', '-' + option, value)
+    # These are missing from Tkinter
+    def image_create(self, imgtype, cnf={}, master=None, **kw):
+        if not master:
+            master = Tkinter._default_root
+            if not master:
+                raise RuntimeError, 'Too early to create image'
+        if kw and cnf: cnf = _cnfmerge((cnf, kw))
+        elif kw: cnf = kw
+        options = ()
+        for k, v in cnf.items():
+            if callable(v):
+                v = self._register(v)
+            options = options + ('-'+k, v)
+        return master.tk.call(('image', 'create', imgtype,) + options)
+    def image_delete(self, imgname):
+        try:
+            self.tk.call('image', 'delete', imgname)
+        except TclError:
+            # May happen if the root was destroyed
+            pass
+
+# Subwidgets are child widgets created automatically by mega-widgets.
+# In python, we have to create these subwidgets manually to mirror their
+# existence in Tk/Tix.
+class TixSubWidget(TixWidget):
+    """Subwidget class.
+
+    This is used to mirror child widgets automatically created
+    by Tix/Tk as part of a mega-widget in Python (which is not informed
+    of this)"""
+
+    def __init__(self, master, name,
+               destroy_physically=1, check_intermediate=1):
+        if check_intermediate:
+            path = master._subwidget_name(name)
+            try:
+                path = path[len(master._w)+1:]
+                plist = path.split('.')
+            except:
+                plist = []
+
+        if not check_intermediate:
+            # immediate descendant
+            TixWidget.__init__(self, master, None, None, {'name' : name})
+        else:
+            # Ensure that the intermediate widgets exist
+            parent = master
+            for i in range(len(plist) - 1):
+                n = '.'.join(plist[:i+1])
+                try:
+                    w = master._nametowidget(n)
+                    parent = w
+                except KeyError:
+                    # Create the intermediate widget
+                    parent = TixSubWidget(parent, plist[i],
+                                          destroy_physically=0,
+                                          check_intermediate=0)
+            # The Tk widget name is in plist, not in name
+            if plist:
+                name = plist[-1]
+            TixWidget.__init__(self, parent, None, None, {'name' : name})
+        self.destroy_physically = destroy_physically
+
+    def destroy(self):
+        # For some widgets e.g., a NoteBook, when we call destructors,
+        # we must be careful not to destroy the frame widget since this
+        # also destroys the parent NoteBook thus leading to an exception
+        # in Tkinter when it finally calls Tcl to destroy the NoteBook
+        for c in self.children.values(): c.destroy()
+        if self.master.children.has_key(self._name):
+            del self.master.children[self._name]
+        if self.master.subwidget_list.has_key(self._name):
+            del self.master.subwidget_list[self._name]
+        if self.destroy_physically:
+            # This is bypassed only for a few widgets
+            self.tk.call('destroy', self._w)
+
+
+# Useful func. to split Tcl lists and return as a dict. From Tkinter.py
+def _lst2dict(lst):
+    dict = {}
+    for x in lst:
+        dict[x[0][1:]] = (x[0][1:],) + x[1:]
+    return dict
+
+# Useful class to create a display style - later shared by many items.
+# Contributed by Steffen Kremser
+class DisplayStyle:
+    """DisplayStyle - handle configuration options shared by
+    (multiple) Display Items"""
+
+    def __init__(self, itemtype, cnf={}, **kw):
+        master = _default_root              # global from Tkinter
+        if not master and cnf.has_key('refwindow'): master=cnf['refwindow']
+        elif not master and kw.has_key('refwindow'):  master= kw['refwindow']
+        elif not master: raise RuntimeError, "Too early to create display style: no root window"
+        self.tk = master.tk
+        self.stylename = self.tk.call('tixDisplayStyle', itemtype,
+                            *self._options(cnf,kw) )
+
+    def __str__(self):
+        return self.stylename
+
+    def _options(self, cnf, kw):
+        if kw and cnf:
+            cnf = _cnfmerge((cnf, kw))
+        elif kw:
+            cnf = kw
+        opts = ()
+        for k, v in cnf.items():
+            opts = opts + ('-'+k, v)
+        return opts
+
+    def delete(self):
+        self.tk.call(self.stylename, 'delete')
+
+    def __setitem__(self,key,value):
+        self.tk.call(self.stylename, 'configure', '-%s'%key, value)
+
+    def config(self, cnf={}, **kw):
+        return _lst2dict(
+            self.tk.split(
+            self.tk.call(
+                  self.stylename, 'configure', *self._options(cnf,kw))))
+
+    def __getitem__(self,key):
+        return self.tk.call(self.stylename, 'cget', '-%s'%key)
+
+
+######################################################
+### The Tix Widget classes - in alphabetical order ###
+######################################################
+
+class Balloon(TixWidget):
+    """Balloon help widget.
+
+    Subwidget       Class
+    ---------       -----
+    label           Label
+    message         Message"""
+
+    # FIXME: It should inherit -superclass tixShell
+    def __init__(self, master=None, cnf={}, **kw):
+        # static seem to be -installcolormap -initwait -statusbar -cursor
+        static = ['options', 'installcolormap', 'initwait', 'statusbar',
+                  'cursor']
+        TixWidget.__init__(self, master, 'tixBalloon', static, cnf, kw)
+        self.subwidget_list['label'] = _dummyLabel(self, 'label',
+                                                   destroy_physically=0)
+        self.subwidget_list['message'] = _dummyLabel(self, 'message',
+                                                     destroy_physically=0)
+
+    def bind_widget(self, widget, cnf={}, **kw):
+        """Bind balloon widget to another.
+        One balloon widget may be bound to several widgets at the same time"""
+        self.tk.call(self._w, 'bind', widget._w, *self._options(cnf, kw))
+
+    def unbind_widget(self, widget):
+        self.tk.call(self._w, 'unbind', widget._w)
+
+class ButtonBox(TixWidget):
+    """ButtonBox - A container for pushbuttons.
+    Subwidgets are the buttons added with the add method.
+    """
+    def __init__(self, master=None, cnf={}, **kw):
+        TixWidget.__init__(self, master, 'tixButtonBox',
+                           ['orientation', 'options'], cnf, kw)
+
+    def add(self, name, cnf={}, **kw):
+        """Add a button with given name to box."""
+
+        btn = self.tk.call(self._w, 'add', name, *self._options(cnf, kw))
+        self.subwidget_list[name] = _dummyButton(self, name)
+        return btn
+
+    def invoke(self, name):
+        if self.subwidget_list.has_key(name):
+            self.tk.call(self._w, 'invoke', name)
+
+class ComboBox(TixWidget):
+    """ComboBox - an Entry field with a dropdown menu. The user can select a
+    choice by either typing in the entry subwdget or selecting from the
+    listbox subwidget.
+
+    Subwidget       Class
+    ---------       -----
+    entry       Entry
+    arrow       Button
+    slistbox    ScrolledListBox
+    tick        Button
+    cross       Button : present if created with the fancy option"""
+
+    # FIXME: It should inherit -superclass tixLabelWidget
+    def __init__ (self, master=None, cnf={}, **kw):
+        TixWidget.__init__(self, master, 'tixComboBox',
+                           ['editable', 'dropdown', 'fancy', 'options'],
+                           cnf, kw)
+        self.subwidget_list['label'] = _dummyLabel(self, 'label')
+        self.subwidget_list['entry'] = _dummyEntry(self, 'entry')
+        self.subwidget_list['arrow'] = _dummyButton(self, 'arrow')
+        self.subwidget_list['slistbox'] = _dummyScrolledListBox(self,
+                                                                'slistbox')
+        try:
+            self.subwidget_list['tick'] = _dummyButton(self, 'tick')
+            self.subwidget_list['cross'] = _dummyButton(self, 'cross')
+        except TypeError:
+            # unavailable when -fancy not specified
+            pass
+
+    # align
+
+    def add_history(self, str):
+        self.tk.call(self._w, 'addhistory', str)
+
+    def append_history(self, str):
+        self.tk.call(self._w, 'appendhistory', str)
+
+    def insert(self, index, str):
+        self.tk.call(self._w, 'insert', index, str)
+
+    def pick(self, index):
+        self.tk.call(self._w, 'pick', index)
+
+class Control(TixWidget):
+    """Control - An entry field with value change arrows.  The user can
+    adjust the value by pressing the two arrow buttons or by entering
+    the value directly into the entry. The new value will be checked
+    against the user-defined upper and lower limits.
+
+    Subwidget       Class
+    ---------       -----
+    incr       Button
+    decr       Button
+    entry       Entry
+    label       Label"""
+
+    # FIXME: It should inherit -superclass tixLabelWidget
+    def __init__ (self, master=None, cnf={}, **kw):
+        TixWidget.__init__(self, master, 'tixControl', ['options'], cnf, kw)
+        self.subwidget_list['incr'] = _dummyButton(self, 'incr')
+        self.subwidget_list['decr'] = _dummyButton(self, 'decr')
+        self.subwidget_list['label'] = _dummyLabel(self, 'label')
+        self.subwidget_list['entry'] = _dummyEntry(self, 'entry')
+
+    def decrement(self):
+        self.tk.call(self._w, 'decr')
+
+    def increment(self):
+        self.tk.call(self._w, 'incr')
+
+    def invoke(self):
+        self.tk.call(self._w, 'invoke')
+
+    def update(self):
+        self.tk.call(self._w, 'update')
+
+class DirList(TixWidget):
+    """DirList - displays a list view of a directory, its previous
+    directories and its sub-directories. The user can choose one of
+    the directories displayed in the list or change to another directory.
+
+    Subwidget       Class
+    ---------       -----
+    hlist       HList
+    hsb              Scrollbar
+    vsb              Scrollbar"""
+
+    # FIXME: It should inherit -superclass tixScrolledHList
+    def __init__(self, master, cnf={}, **kw):
+        TixWidget.__init__(self, master, 'tixDirList', ['options'], cnf, kw)
+        self.subwidget_list['hlist'] = _dummyHList(self, 'hlist')
+        self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb')
+        self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb')
+
+    def chdir(self, dir):
+        self.tk.call(self._w, 'chdir', dir)
+
+class DirTree(TixWidget):
+    """DirTree - Directory Listing in a hierarchical view.
+    Displays a tree view of a directory, its previous directories and its
+    sub-directories. The user can choose one of the directories displayed
+    in the list or change to another directory.
+
+    Subwidget       Class
+    ---------       -----
+    hlist           HList
+    hsb             Scrollbar
+    vsb             Scrollbar"""
+
+    # FIXME: It should inherit -superclass tixScrolledHList
+    def __init__(self, master, cnf={}, **kw):
+        TixWidget.__init__(self, master, 'tixDirTree', ['options'], cnf, kw)
+        self.subwidget_list['hlist'] = _dummyHList(self, 'hlist')
+        self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb')
+        self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb')
+
+    def chdir(self, dir):
+        self.tk.call(self._w, 'chdir', dir)
+
+class DirSelectBox(TixWidget):
+    """DirSelectBox - Motif style file select box.
+    It is generally used for
+    the user to choose a file. FileSelectBox stores the files mostly
+    recently selected into a ComboBox widget so that they can be quickly
+    selected again.
+
+    Subwidget       Class
+    ---------       -----
+    selection       ComboBox
+    filter          ComboBox
+    dirlist         ScrolledListBox
+    filelist        ScrolledListBox"""
+
+    def __init__(self, master, cnf={}, **kw):
+        TixWidget.__init__(self, master, 'tixDirSelectBox', ['options'], cnf, kw)
+        self.subwidget_list['dirlist'] = _dummyDirList(self, 'dirlist')
+        self.subwidget_list['dircbx'] = _dummyFileComboBox(self, 'dircbx')
+
+class ExFileSelectBox(TixWidget):
+    """ExFileSelectBox - MS Windows style file select box.
+    It provides an convenient method for the user to select files.
+
+    Subwidget       Class
+    ---------       -----
+    cancel       Button
+    ok              Button
+    hidden       Checkbutton
+    types       ComboBox
+    dir              ComboBox
+    file       ComboBox
+    dirlist       ScrolledListBox
+    filelist       ScrolledListBox"""
+
+    def __init__(self, master, cnf={}, **kw):
+        TixWidget.__init__(self, master, 'tixExFileSelectBox', ['options'], cnf, kw)
+        self.subwidget_list['cancel'] = _dummyButton(self, 'cancel')
+        self.subwidget_list['ok'] = _dummyButton(self, 'ok')
+        self.subwidget_list['hidden'] = _dummyCheckbutton(self, 'hidden')
+        self.subwidget_list['types'] = _dummyComboBox(self, 'types')
+        self.subwidget_list['dir'] = _dummyComboBox(self, 'dir')
+        self.subwidget_list['dirlist'] = _dummyDirList(self, 'dirlist')
+        self.subwidget_list['file'] = _dummyComboBox(self, 'file')
+        self.subwidget_list['filelist'] = _dummyScrolledListBox(self, 'filelist')
+
+    def filter(self):
+        self.tk.call(self._w, 'filter')
+
+    def invoke(self):
+        self.tk.call(self._w, 'invoke')
+
+
+# Should inherit from a Dialog class
+class DirSelectDialog(TixWidget):
+    """The DirSelectDialog widget presents the directories in the file
+    system in a dialog window. The user can use this dialog window to
+    navigate through the file system to select the desired directory.
+
+    Subwidgets       Class
+    ----------       -----
+    dirbox       DirSelectDialog"""
+
+    # FIXME: It should inherit -superclass tixDialogShell
+    def __init__(self, master, cnf={}, **kw):
+        TixWidget.__init__(self, master, 'tixDirSelectDialog',
+                           ['options'], cnf, kw)
+        self.subwidget_list['dirbox'] = _dummyDirSelectBox(self, 'dirbox')
+        # cancel and ok buttons are missing
+
+    def popup(self):
+        self.tk.call(self._w, 'popup')
+
+    def popdown(self):
+        self.tk.call(self._w, 'popdown')
+
+
+# Should inherit from a Dialog class
+class ExFileSelectDialog(TixWidget):
+    """ExFileSelectDialog - MS Windows style file select dialog.
+    It provides an convenient method for the user to select files.
+
+    Subwidgets       Class
+    ----------       -----
+    fsbox       ExFileSelectBox"""
+
+    # FIXME: It should inherit -superclass tixDialogShell
+    def __init__(self, master, cnf={}, **kw):
+        TixWidget.__init__(self, master, 'tixExFileSelectDialog',
+                           ['options'], cnf, kw)
+        self.subwidget_list['fsbox'] = _dummyExFileSelectBox(self, 'fsbox')
+
+    def popup(self):
+        self.tk.call(self._w, 'popup')
+
+    def popdown(self):
+        self.tk.call(self._w, 'popdown')
+
+class FileSelectBox(TixWidget):
+    """ExFileSelectBox - Motif style file select box.
+    It is generally used for
+    the user to choose a file. FileSelectBox stores the files mostly
+    recently selected into a ComboBox widget so that they can be quickly
+    selected again.
+
+    Subwidget       Class
+    ---------       -----
+    selection       ComboBox
+    filter          ComboBox
+    dirlist         ScrolledListBox
+    filelist        ScrolledListBox"""
+
+    def __init__(self, master, cnf={}, **kw):
+        TixWidget.__init__(self, master, 'tixFileSelectBox', ['options'], cnf, kw)
+        self.subwidget_list['dirlist'] = _dummyScrolledListBox(self, 'dirlist')
+        self.subwidget_list['filelist'] = _dummyScrolledListBox(self, 'filelist')
+        self.subwidget_list['filter'] = _dummyComboBox(self, 'filter')
+        self.subwidget_list['selection'] = _dummyComboBox(self, 'selection')
+
+    def apply_filter(self):              # name of subwidget is same as command
+        self.tk.call(self._w, 'filter')
+
+    def invoke(self):
+        self.tk.call(self._w, 'invoke')
+
+# Should inherit from a Dialog class
+class FileSelectDialog(TixWidget):
+    """FileSelectDialog - Motif style file select dialog.
+
+    Subwidgets       Class
+    ----------       -----
+    btns       StdButtonBox
+    fsbox       FileSelectBox"""
+
+    # FIXME: It should inherit -superclass tixStdDialogShell
+    def __init__(self, master, cnf={}, **kw):
+        TixWidget.__init__(self, master, 'tixFileSelectDialog',
+                           ['options'], cnf, kw)
+        self.subwidget_list['btns'] = _dummyStdButtonBox(self, 'btns')
+        self.subwidget_list['fsbox'] = _dummyFileSelectBox(self, 'fsbox')
+
+    def popup(self):
+        self.tk.call(self._w, 'popup')
+
+    def popdown(self):
+        self.tk.call(self._w, 'popdown')
+
+class FileEntry(TixWidget):
+    """FileEntry - Entry field with button that invokes a FileSelectDialog.
+    The user can type in the filename manually. Alternatively, the user can
+    press the button widget that sits next to the entry, which will bring
+    up a file selection dialog.
+
+    Subwidgets       Class
+    ----------       -----
+    button       Button
+    entry       Entry"""
+
+    # FIXME: It should inherit -superclass tixLabelWidget
+    def __init__(self, master, cnf={}, **kw):
+        TixWidget.__init__(self, master, 'tixFileEntry',
+                           ['dialogtype', 'options'], cnf, kw)
+        self.subwidget_list['button'] = _dummyButton(self, 'button')
+        self.subwidget_list['entry'] = _dummyEntry(self, 'entry')
+
+    def invoke(self):
+        self.tk.call(self._w, 'invoke')
+
+    def file_dialog(self):
+        # FIXME: return python object
+        pass
+
+class HList(TixWidget):
+    """HList - Hierarchy display  widget can be used to display any data
+    that have a hierarchical structure, for example, file system directory
+    trees. The list entries are indented and connected by branch lines
+    according to their places in the hierachy.
+
+    Subwidgets - None"""
+
+    def __init__ (self,master=None,cnf={}, **kw):
+        TixWidget.__init__(self, master, 'tixHList',
+                           ['columns', 'options'], cnf, kw)
+
+    def add(self, entry, cnf={}, **kw):
+        return self.tk.call(self._w, 'add', entry, *self._options(cnf, kw))
+
+    def add_child(self, parent=None, cnf={}, **kw):
+        if not parent:
+            parent = ''
+        return self.tk.call(
+                     self._w, 'addchild', parent, *self._options(cnf, kw))
+
+    def anchor_set(self, entry):
+        self.tk.call(self._w, 'anchor', 'set', entry)
+
+    def anchor_clear(self):
+        self.tk.call(self._w, 'anchor', 'clear')
+
+    def column_width(self, col=0, width=None, chars=None):
+        if not chars:
+            return self.tk.call(self._w, 'column', 'width', col, width)
+        else:
+            return self.tk.call(self._w, 'column', 'width', col,
+                                '-char', chars)
+
+    def delete_all(self):
+        self.tk.call(self._w, 'delete', 'all')
+
+    def delete_entry(self, entry):
+        self.tk.call(self._w, 'delete', 'entry', entry)
+
+    def delete_offsprings(self, entry):
+        self.tk.call(self._w, 'delete', 'offsprings', entry)
+
+    def delete_siblings(self, entry):
+        self.tk.call(self._w, 'delete', 'siblings', entry)
+
+    def dragsite_set(self, index):
+        self.tk.call(self._w, 'dragsite', 'set', index)
+
+    def dragsite_clear(self):
+        self.tk.call(self._w, 'dragsite', 'clear')
+
+    def dropsite_set(self, index):
+        self.tk.call(self._w, 'dropsite', 'set', index)
+
+    def dropsite_clear(self):
+        self.tk.call(self._w, 'dropsite', 'clear')
+
+    def header_create(self, col, cnf={}, **kw):
+        self.tk.call(self._w, 'header', 'create', col, *self._options(cnf, kw))
+
+    def header_configure(self, col, cnf={}, **kw):
+        if cnf is None:
+            return _lst2dict(
+                self.tk.split(
+                self.tk.call(self._w, 'header', 'configure', col)))
+        self.tk.call(self._w, 'header', 'configure', col,
+                     *self._options(cnf, kw))
+
+    def header_cget(self,  col, opt):
+        return self.tk.call(self._w, 'header', 'cget', col, opt)
+
+    def header_exists(self,  col):
+        return self.tk.call(self._w, 'header', 'exists', col)
+
+    def header_delete(self, col):
+        self.tk.call(self._w, 'header', 'delete', col)
+
+    def header_size(self, col):
+        return self.tk.call(self._w, 'header', 'size', col)
+
+    def hide_entry(self, entry):
+        self.tk.call(self._w, 'hide', 'entry', entry)
+
+    def indicator_create(self, entry, cnf={}, **kw):
+        self.tk.call(
+              self._w, 'indicator', 'create', entry, *self._options(cnf, kw))
+
+    def indicator_configure(self, entry, cnf={}, **kw):
+        if cnf is None:
+            return _lst2dict(
+                self.tk.split(
+                self.tk.call(self._w, 'indicator', 'configure', entry)))
+        self.tk.call(
+              self._w, 'indicator', 'configure', entry, *self._options(cnf, kw))
+
+    def indicator_cget(self,  entry, opt):
+        return self.tk.call(self._w, 'indicator', 'cget', entry, opt)
+
+    def indicator_exists(self,  entry):
+        return self.tk.call (self._w, 'indicator', 'exists', entry)
+
+    def indicator_delete(self, entry):
+        self.tk.call(self._w, 'indicator', 'delete', entry)
+
+    def indicator_size(self, entry):
+        return self.tk.call(self._w, 'indicator', 'size', entry)
+
+    def info_anchor(self):
+        return self.tk.call(self._w, 'info', 'anchor')
+
+    def info_children(self, entry=None):
+        c = self.tk.call(self._w, 'info', 'children', entry)
+        return self.tk.splitlist(c)
+
+    def info_data(self, entry):
+        return self.tk.call(self._w, 'info', 'data', entry)
+
+    def info_exists(self, entry):
+        return self.tk.call(self._w, 'info', 'exists', entry)
+
+    def info_hidden(self, entry):
+        return self.tk.call(self._w, 'info', 'hidden', entry)
+
+    def info_next(self, entry):
+        return self.tk.call(self._w, 'info', 'next', entry)
+
+    def info_parent(self, entry):
+        return self.tk.call(self._w, 'info', 'parent', entry)
+
+    def info_prev(self, entry):
+        return self.tk.call(self._w, 'info', 'prev', entry)
+
+    def info_selection(self):
+        c = self.tk.call(self._w, 'info', 'selection')
+        return self.tk.splitlist(c)
+
+    def item_cget(self, entry, col, opt):
+        return self.tk.call(self._w, 'item', 'cget', entry, col, opt)
+
+    def item_configure(self, entry, col, cnf={}, **kw):
+        if cnf is None:
+            return _lst2dict(
+                self.tk.split(
+                self.tk.call(self._w, 'item', 'configure', entry, col)))
+        self.tk.call(self._w, 'item', 'configure', entry, col,
+              *self._options(cnf, kw))
+
+    def item_create(self, entry, col, cnf={}, **kw):
+        self.tk.call(
+              self._w, 'item', 'create', entry, col, *self._options(cnf, kw))
+
+    def item_exists(self, entry, col):
+        return self.tk.call(self._w, 'item', 'exists', entry, col)
+
+    def item_delete(self, entry, col):
+        self.tk.call(self._w, 'item', 'delete', entry, col)
+
+    def entrycget(self, entry, opt):
+        return self.tk.call(self._w, 'entrycget', entry, opt)
+
+    def entryconfigure(self, entry, cnf={}, **kw):
+        if cnf is None:
+            return _lst2dict(
+                self.tk.split(
+                self.tk.call(self._w, 'entryconfigure', entry)))
+        self.tk.call(self._w, 'entryconfigure', entry,
+              *self._options(cnf, kw))
+
+    def nearest(self, y):
+        return self.tk.call(self._w, 'nearest', y)
+
+    def see(self, entry):
+        self.tk.call(self._w, 'see', entry)
+
+    def selection_clear(self, cnf={}, **kw):
+        self.tk.call(self._w, 'selection', 'clear', *self._options(cnf, kw))
+
+    def selection_includes(self, entry):
+        return self.tk.call(self._w, 'selection', 'includes', entry)
+
+    def selection_set(self, first, last=None):
+        self.tk.call(self._w, 'selection', 'set', first, last)
+
+    def show_entry(self, entry):
+        return self.tk.call(self._w, 'show', 'entry', entry)
+
+    def xview(self, *args):
+        self.tk.call(self._w, 'xview', *args)
+
+    def yview(self, *args):
+        self.tk.call(self._w, 'yview', *args)
+
+class InputOnly(TixWidget):
+    """InputOnly - Invisible widget. Unix only.
+
+    Subwidgets - None"""
+
+    def __init__ (self,master=None,cnf={}, **kw):
+        TixWidget.__init__(self, master, 'tixInputOnly', None, cnf, kw)
+
+class LabelEntry(TixWidget):
+    """LabelEntry - Entry field with label. Packages an entry widget
+    and a label into one mega widget. It can beused be used to simplify
+    the creation of ``entry-form'' type of interface.
+
+    Subwidgets       Class
+    ----------       -----
+    label       Label
+    entry       Entry"""
+
+    def __init__ (self,master=None,cnf={}, **kw):
+        TixWidget.__init__(self, master, 'tixLabelEntry',
+                           ['labelside','options'], cnf, kw)
+        self.subwidget_list['label'] = _dummyLabel(self, 'label')
+        self.subwidget_list['entry'] = _dummyEntry(self, 'entry')
+
+class LabelFrame(TixWidget):
+    """LabelFrame - Labelled Frame container. Packages a frame widget
+    and a label into one mega widget. To create widgets inside a
+    LabelFrame widget, one creates the new widgets relative to the
+    frame subwidget and manage them inside the frame subwidget.
+
+    Subwidgets       Class
+    ----------       -----
+    label       Label
+    frame       Frame"""
+
+    def __init__ (self,master=None,cnf={}, **kw):
+        TixWidget.__init__(self, master, 'tixLabelFrame',
+                           ['labelside','options'], cnf, kw)
+        self.subwidget_list['label'] = _dummyLabel(self, 'label')
+        self.subwidget_list['frame'] = _dummyFrame(self, 'frame')
+
+
+class ListNoteBook(TixWidget):
+    """A ListNoteBook widget is very similar to the TixNoteBook widget:
+    it can be used to display many windows in a limited space using a
+    notebook metaphor. The notebook is divided into a stack of pages
+    (windows). At one time only one of these pages can be shown.
+    The user can navigate through these pages by
+    choosing the name of the desired page in the hlist subwidget."""
+
+    def __init__(self, master, cnf={}, **kw):
+        TixWidget.__init__(self, master, 'tixListNoteBook', ['options'], cnf, kw)
+        # Is this necessary? It's not an exposed subwidget in Tix.
+        self.subwidget_list['pane'] = _dummyPanedWindow(self, 'pane',
+                                                        destroy_physically=0)
+        self.subwidget_list['hlist'] = _dummyHList(self, 'hlist')
+        self.subwidget_list['shlist'] = _dummyScrolledHList(self, 'shlist')
+
+    def add(self, name, cnf={}, **kw):
+        self.tk.call(self._w, 'add', name, *self._options(cnf, kw))
+        self.subwidget_list[name] = TixSubWidget(self, name)
+        return self.subwidget_list[name]
+
+    def page(self, name):
+        return self.subwidget(name)
+
+    def pages(self):
+        # Can't call subwidgets_all directly because we don't want .nbframe
+        names = self.tk.split(self.tk.call(self._w, 'pages'))
+        ret = []
+        for x in names:
+            ret.append(self.subwidget(x))
+        return ret
+
+    def raise_page(self, name):              # raise is a python keyword
+        self.tk.call(self._w, 'raise', name)
+
+class Meter(TixWidget):
+    """The Meter widget can be used to show the progress of a background
+    job which may take a long time to execute.
+    """
+
+    def __init__(self, master=None, cnf={}, **kw):
+        TixWidget.__init__(self, master, 'tixMeter',
+                           ['options'], cnf, kw)
+
+class NoteBook(TixWidget):
+    """NoteBook - Multi-page container widget (tabbed notebook metaphor).
+
+    Subwidgets       Class
+    ----------       -----
+    nbframe       NoteBookFrame
+    <pages>       page widgets added dynamically with the add method"""
+
+    def __init__ (self,master=None,cnf={}, **kw):
+        TixWidget.__init__(self,master,'tixNoteBook', ['options'], cnf, kw)
+        self.subwidget_list['nbframe'] = TixSubWidget(self, 'nbframe',
+                                                      destroy_physically=0)
+
+    def add(self, name, cnf={}, **kw):
+        self.tk.call(self._w, 'add', name, *self._options(cnf, kw))
+        self.subwidget_list[name] = TixSubWidget(self, name)
+        return self.subwidget_list[name]
+
+    def delete(self, name):
+        self.tk.call(self._w, 'delete', name)
+        self.subwidget_list[name].destroy()
+        del self.subwidget_list[name]
+
+    def page(self, name):
+        return self.subwidget(name)
+
+    def pages(self):
+        # Can't call subwidgets_all directly because we don't want .nbframe
+        names = self.tk.split(self.tk.call(self._w, 'pages'))
+        ret = []
+        for x in names:
+            ret.append(self.subwidget(x))
+        return ret
+
+    def raise_page(self, name):              # raise is a python keyword
+        self.tk.call(self._w, 'raise', name)
+
+    def raised(self):
+        return self.tk.call(self._w, 'raised')
+
+class NoteBookFrame(TixWidget):
+    # FIXME: This is dangerous to expose to be called on its own.
+    pass
+
+class OptionMenu(TixWidget):
+    """OptionMenu - creates a menu button of options.
+
+    Subwidget       Class
+    ---------       -----
+    menubutton      Menubutton
+    menu            Menu"""
+
+    def __init__(self, master, cnf={}, **kw):
+        TixWidget.__init__(self, master, 'tixOptionMenu', ['options'], cnf, kw)
+        self.subwidget_list['menubutton'] = _dummyMenubutton(self, 'menubutton')
+        self.subwidget_list['menu'] = _dummyMenu(self, 'menu')
+
+    def add_command(self, name, cnf={}, **kw):
+        self.tk.call(self._w, 'add', 'command', name, *self._options(cnf, kw))
+
+    def add_separator(self, name, cnf={}, **kw):
+        self.tk.call(self._w, 'add', 'separator', name, *self._options(cnf, kw))
+
+    def delete(self, name):
+        self.tk.call(self._w, 'delete', name)
+
+    def disable(self, name):
+        self.tk.call(self._w, 'disable', name)
+
+    def enable(self, name):
+        self.tk.call(self._w, 'enable', name)
+
+class PanedWindow(TixWidget):
+    """PanedWindow - Multi-pane container widget
+    allows the user to interactively manipulate the sizes of several
+    panes. The panes can be arranged either vertically or horizontally.The
+    user changes the sizes of the panes by dragging the resize handle
+    between two panes.
+
+    Subwidgets       Class
+    ----------       -----
+    <panes>       g/p widgets added dynamically with the add method."""
+
+    def __init__(self, master, cnf={}, **kw):
+        TixWidget.__init__(self, master, 'tixPanedWindow', ['orientation', 'options'], cnf, kw)
+
+    # add delete forget panecget paneconfigure panes setsize
+    def add(self, name, cnf={}, **kw):
+        self.tk.call(self._w, 'add', name, *self._options(cnf, kw))
+        self.subwidget_list[name] = TixSubWidget(self, name,
+                                                 check_intermediate=0)
+        return self.subwidget_list[name]
+
+    def delete(self, name):
+        self.tk.call(self._w, 'delete', name)
+        self.subwidget_list[name].destroy()
+        del self.subwidget_list[name]
+
+    def forget(self, name):
+        self.tk.call(self._w, 'forget', name)
+
+    def panecget(self,  entry, opt):
+        return self.tk.call(self._w, 'panecget', entry, opt)
+
+    def paneconfigure(self, entry, cnf={}, **kw):
+        if cnf is None:
+            return _lst2dict(
+                self.tk.split(
+                self.tk.call(self._w, 'paneconfigure', entry)))
+        self.tk.call(self._w, 'paneconfigure', entry, *self._options(cnf, kw))
+
+    def panes(self):
+        names = self.tk.call(self._w, 'panes')
+        ret = []
+        for x in names:
+            ret.append(self.subwidget(x))
+        return ret
+
+class PopupMenu(TixWidget):
+    """PopupMenu widget can be used as a replacement of the tk_popup command.
+    The advantage of the Tix PopupMenu widget is it requires less application
+    code to manipulate.
+
+
+    Subwidgets       Class
+    ----------       -----
+    menubutton       Menubutton
+    menu       Menu"""
+
+    # FIXME: It should inherit -superclass tixShell
+    def __init__(self, master, cnf={}, **kw):
+        TixWidget.__init__(self, master, 'tixPopupMenu', ['options'], cnf, kw)
+        self.subwidget_list['menubutton'] = _dummyMenubutton(self, 'menubutton')
+        self.subwidget_list['menu'] = _dummyMenu(self, 'menu')
+
+    def bind_widget(self, widget):
+        self.tk.call(self._w, 'bind', widget._w)
+
+    def unbind_widget(self, widget):
+        self.tk.call(self._w, 'unbind', widget._w)
+
+    def post_widget(self, widget, x, y):
+        self.tk.call(self._w, 'post', widget._w, x, y)
+
+class ResizeHandle(TixWidget):
+    """Internal widget to draw resize handles on Scrolled widgets."""
+    def __init__(self, master, cnf={}, **kw):
+        # There seems to be a Tix bug rejecting the configure method
+        # Let's try making the flags -static
+        flags = ['options', 'command', 'cursorfg', 'cursorbg',
+                 'handlesize', 'hintcolor', 'hintwidth',
+                 'x', 'y']
+        # In fact, x y height width are configurable
+        TixWidget.__init__(self, master, 'tixResizeHandle',
+                           flags, cnf, kw)
+
+    def attach_widget(self, widget):
+        self.tk.call(self._w, 'attachwidget', widget._w)
+
+    def detach_widget(self, widget):
+        self.tk.call(self._w, 'detachwidget', widget._w)
+
+    def hide(self, widget):
+        self.tk.call(self._w, 'hide', widget._w)
+
+    def show(self, widget):
+        self.tk.call(self._w, 'show', widget._w)
+
+class ScrolledHList(TixWidget):
+    """ScrolledHList - HList with automatic scrollbars."""
+
+    # FIXME: It should inherit -superclass tixScrolledWidget
+    def __init__(self, master, cnf={}, **kw):
+        TixWidget.__init__(self, master, 'tixScrolledHList', ['options'],
+                           cnf, kw)
+        self.subwidget_list['hlist'] = _dummyHList(self, 'hlist')
+        self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb')
+        self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb')
+
+class ScrolledListBox(TixWidget):
+    """ScrolledListBox - Listbox with automatic scrollbars."""
+
+    # FIXME: It should inherit -superclass tixScrolledWidget
+    def __init__(self, master, cnf={}, **kw):
+        TixWidget.__init__(self, master, 'tixScrolledListBox', ['options'], cnf, kw)
+        self.subwidget_list['listbox'] = _dummyListbox(self, 'listbox')
+        self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb')
+        self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb')
+
+class ScrolledText(TixWidget):
+    """ScrolledText - Text with automatic scrollbars."""
+
+    # FIXME: It should inherit -superclass tixScrolledWidget
+    def __init__(self, master, cnf={}, **kw):
+        TixWidget.__init__(self, master, 'tixScrolledText', ['options'], cnf, kw)
+        self.subwidget_list['text'] = _dummyText(self, 'text')
+        self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb')
+        self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb')
+
+class ScrolledTList(TixWidget):
+    """ScrolledTList - TList with automatic scrollbars."""
+
+    # FIXME: It should inherit -superclass tixScrolledWidget
+    def __init__(self, master, cnf={}, **kw):
+        TixWidget.__init__(self, master, 'tixScrolledTList', ['options'],
+                           cnf, kw)
+        self.subwidget_list['tlist'] = _dummyTList(self, 'tlist')
+        self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb')
+        self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb')
+
+class ScrolledWindow(TixWidget):
+    """ScrolledWindow - Window with automatic scrollbars."""
+
+    # FIXME: It should inherit -superclass tixScrolledWidget
+    def __init__(self, master, cnf={}, **kw):
+        TixWidget.__init__(self, master, 'tixScrolledWindow', ['options'], cnf, kw)
+        self.subwidget_list['window'] = _dummyFrame(self, 'window')
+        self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb')
+        self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb')
+
+class Select(TixWidget):
+    """Select - Container of button subwidgets. It can be used to provide
+    radio-box or check-box style of selection options for the user.
+
+    Subwidgets are buttons added dynamically using the add method."""
+
+    # FIXME: It should inherit -superclass tixLabelWidget
+    def __init__(self, master, cnf={}, **kw):
+        TixWidget.__init__(self, master, 'tixSelect',
+                           ['allowzero', 'radio', 'orientation', 'labelside',
+                            'options'],
+                           cnf, kw)
+        self.subwidget_list['label'] = _dummyLabel(self, 'label')
+
+    def add(self, name, cnf={}, **kw):
+        self.tk.call(self._w, 'add', name, *self._options(cnf, kw))
+        self.subwidget_list[name] = _dummyButton(self, name)
+        return self.subwidget_list[name]
+
+    def invoke(self, name):
+        self.tk.call(self._w, 'invoke', name)
+
+class Shell(TixWidget):
+    """Toplevel window.
+
+    Subwidgets - None"""
+
+    def __init__ (self,master=None,cnf={}, **kw):
+        TixWidget.__init__(self, master, 'tixShell', ['options', 'title'], cnf, kw)
+
+class DialogShell(TixWidget):
+    """Toplevel window, with popup popdown and center methods.
+    It tells the window manager that it is a dialog window and should be
+    treated specially. The exact treatment depends on the treatment of
+    the window manager.
+
+    Subwidgets - None"""
+
+    # FIXME: It should inherit from  Shell
+    def __init__ (self,master=None,cnf={}, **kw):
+        TixWidget.__init__(self, master,
+                           'tixDialogShell',
+                           ['options', 'title', 'mapped',
+                            'minheight', 'minwidth',
+                            'parent', 'transient'], cnf, kw)
+
+    def popdown(self):
+        self.tk.call(self._w, 'popdown')
+
+    def popup(self):
+        self.tk.call(self._w, 'popup')
+
+    def center(self):
+        self.tk.call(self._w, 'center')
+
+class StdButtonBox(TixWidget):
+    """StdButtonBox - Standard Button Box (OK, Apply, Cancel and Help) """
+
+    def __init__(self, master=None, cnf={}, **kw):
+        TixWidget.__init__(self, master, 'tixStdButtonBox',
+                           ['orientation', 'options'], cnf, kw)
+        self.subwidget_list['ok'] = _dummyButton(self, 'ok')
+        self.subwidget_list['apply'] = _dummyButton(self, 'apply')
+        self.subwidget_list['cancel'] = _dummyButton(self, 'cancel')
+        self.subwidget_list['help'] = _dummyButton(self, 'help')
+
+    def invoke(self, name):
+        if self.subwidget_list.has_key(name):
+            self.tk.call(self._w, 'invoke', name)
+
+class TList(TixWidget):
+    """TList - Hierarchy display widget which can be
+    used to display data in a tabular format. The list entries of a TList
+    widget are similar to the entries in the Tk listbox widget. The main
+    differences are (1) the TList widget can display the list entries in a
+    two dimensional format and (2) you can use graphical images as well as
+    multiple colors and fonts for the list entries.
+
+    Subwidgets - None"""
+
+    def __init__ (self,master=None,cnf={}, **kw):
+        TixWidget.__init__(self, master, 'tixTList', ['options'], cnf, kw)
+
+    def active_set(self, index):
+        self.tk.call(self._w, 'active', 'set', index)
+
+    def active_clear(self):
+        self.tk.call(self._w, 'active', 'clear')
+
+    def anchor_set(self, index):
+        self.tk.call(self._w, 'anchor', 'set', index)
+
+    def anchor_clear(self):
+        self.tk.call(self._w, 'anchor', 'clear')
+
+    def delete(self, from_, to=None):
+        self.tk.call(self._w, 'delete', from_, to)
+
+    def dragsite_set(self, index):
+        self.tk.call(self._w, 'dragsite', 'set', index)
+
+    def dragsite_clear(self):
+        self.tk.call(self._w, 'dragsite', 'clear')
+
+    def dropsite_set(self, index):
+        self.tk.call(self._w, 'dropsite', 'set', index)
+
+    def dropsite_clear(self):
+        self.tk.call(self._w, 'dropsite', 'clear')
+
+    def insert(self, index, cnf={}, **kw):
+        self.tk.call(self._w, 'insert', index, *self._options(cnf, kw))
+
+    def info_active(self):
+        return self.tk.call(self._w, 'info', 'active')
+
+    def info_anchor(self):
+        return self.tk.call(self._w, 'info', 'anchor')
+
+    def info_down(self, index):
+        return self.tk.call(self._w, 'info', 'down', index)
+
+    def info_left(self, index):
+        return self.tk.call(self._w, 'info', 'left', index)
+
+    def info_right(self, index):
+        return self.tk.call(self._w, 'info', 'right', index)
+
+    def info_selection(self):
+        c = self.tk.call(self._w, 'info', 'selection')
+        return self.tk.splitlist(c)
+
+    def info_size(self):
+        return self.tk.call(self._w, 'info', 'size')
+
+    def info_up(self, index):
+        return self.tk.call(self._w, 'info', 'up', index)
+
+    def nearest(self, x, y):
+        return self.tk.call(self._w, 'nearest', x, y)
+
+    def see(self, index):
+        self.tk.call(self._w, 'see', index)
+
+    def selection_clear(self, cnf={}, **kw):
+        self.tk.call(self._w, 'selection', 'clear', *self._options(cnf, kw))
+
+    def selection_includes(self, index):
+        return self.tk.call(self._w, 'selection', 'includes', index)
+
+    def selection_set(self, first, last=None):
+        self.tk.call(self._w, 'selection', 'set', first, last)
+
+    def xview(self, *args):
+        self.tk.call(self._w, 'xview', *args)
+
+    def yview(self, *args):
+        self.tk.call(self._w, 'yview', *args)
+
+class Tree(TixWidget):
+    """Tree - The tixTree widget can be used to display hierachical
+    data in a tree form. The user can adjust
+    the view of the tree by opening or closing parts of the tree."""
+
+    # FIXME: It should inherit -superclass tixScrolledWidget
+    def __init__(self, master=None, cnf={}, **kw):
+        TixWidget.__init__(self, master, 'tixTree',
+                           ['options'], cnf, kw)
+        self.subwidget_list['hlist'] = _dummyHList(self, 'hlist')
+        self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb')
+        self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb')
+
+    def autosetmode(self):
+        '''This command calls the setmode method for all the entries in this
+     Tree widget: if an entry has no child entries, its mode is set to
+     none. Otherwise, if the entry has any hidden child entries, its mode is
+     set to open; otherwise its mode is set to close.'''
+        self.tk.call(self._w, 'autosetmode')
+
+    def close(self, entrypath):
+        '''Close the entry given by entryPath if its mode is close.'''
+        self.tk.call(self._w, 'close', entrypath)
+
+    def getmode(self, entrypath):
+        '''Returns the current mode of the entry given by entryPath.'''
+        return self.tk.call(self._w, 'getmode', entrypath)
+
+    def open(self, entrypath):
+        '''Open the entry given by entryPath if its mode is open.'''
+        self.tk.call(self._w, 'open', entrypath)
+
+    def setmode(self, entrypath, mode='none'):
+        '''This command is used to indicate whether the entry given by
+     entryPath has children entries and whether the children are visible. mode
+     must be one of open, close or none. If mode is set to open, a (+)
+     indicator is drawn next the the entry. If mode is set to close, a (-)
+     indicator is drawn next the the entry. If mode is set to none, no
+     indicators will be drawn for this entry. The default mode is none. The
+     open mode indicates the entry has hidden children and this entry can be
+     opened by the user. The close mode indicates that all the children of the
+     entry are now visible and the entry can be closed by the user.'''
+        self.tk.call(self._w, 'setmode', entrypath, mode)
+
+
+# Could try subclassing Tree for CheckList - would need another arg to init
+class CheckList(TixWidget):
+    """The CheckList widget
+    displays a list of items to be selected by the user. CheckList acts
+    similarly to the Tk checkbutton or radiobutton widgets, except it is
+    capable of handling many more items than checkbuttons or radiobuttons.
+    """
+    # FIXME: It should inherit -superclass tixTree
+    def __init__(self, master=None, cnf={}, **kw):
+        TixWidget.__init__(self, master, 'tixCheckList',
+                           ['options'], cnf, kw)
+        self.subwidget_list['hlist'] = _dummyHList(self, 'hlist')
+        self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb')
+        self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb')
+
+    def autosetmode(self):
+        '''This command calls the setmode method for all the entries in this
+     Tree widget: if an entry has no child entries, its mode is set to
+     none. Otherwise, if the entry has any hidden child entries, its mode is
+     set to open; otherwise its mode is set to close.'''
+        self.tk.call(self._w, 'autosetmode')
+
+    def close(self, entrypath):
+        '''Close the entry given by entryPath if its mode is close.'''
+        self.tk.call(self._w, 'close', entrypath)
+
+    def getmode(self, entrypath):
+        '''Returns the current mode of the entry given by entryPath.'''
+        return self.tk.call(self._w, 'getmode', entrypath)
+
+    def open(self, entrypath):
+        '''Open the entry given by entryPath if its mode is open.'''
+        self.tk.call(self._w, 'open', entrypath)
+
+    def getselection(self, mode='on'):
+        '''Returns a list of items whose status matches status. If status is
+     not specified, the list of items in the "on" status will be returned.
+     Mode can be on, off, default'''
+        c = self.tk.split(self.tk.call(self._w, 'getselection', mode))
+        return self.tk.splitlist(c)
+
+    def getstatus(self, entrypath):
+        '''Returns the current status of entryPath.'''
+        return self.tk.call(self._w, 'getstatus', entrypath)
+
+    def setstatus(self, entrypath, mode='on'):
+        '''Sets the status of entryPath to be status. A bitmap will be
+     displayed next to the entry its status is on, off or default.'''
+        self.tk.call(self._w, 'setstatus', entrypath, mode)
+
+
+###########################################################################
+### The subclassing below is used to instantiate the subwidgets in each ###
+### mega widget. This allows us to access their methods directly.       ###
+###########################################################################
+
+class _dummyButton(Button, TixSubWidget):
+    def __init__(self, master, name, destroy_physically=1):
+        TixSubWidget.__init__(self, master, name, destroy_physically)
+
+class _dummyCheckbutton(Checkbutton, TixSubWidget):
+    def __init__(self, master, name, destroy_physically=1):
+        TixSubWidget.__init__(self, master, name, destroy_physically)
+
+class _dummyEntry(Entry, TixSubWidget):
+    def __init__(self, master, name, destroy_physically=1):
+        TixSubWidget.__init__(self, master, name, destroy_physically)
+
+class _dummyFrame(Frame, TixSubWidget):
+    def __init__(self, master, name, destroy_physically=1):
+        TixSubWidget.__init__(self, master, name, destroy_physically)
+
+class _dummyLabel(Label, TixSubWidget):
+    def __init__(self, master, name, destroy_physically=1):
+        TixSubWidget.__init__(self, master, name, destroy_physically)
+
+class _dummyListbox(Listbox, TixSubWidget):
+    def __init__(self, master, name, destroy_physically=1):
+        TixSubWidget.__init__(self, master, name, destroy_physically)
+
+class _dummyMenu(Menu, TixSubWidget):
+    def __init__(self, master, name, destroy_physically=1):
+        TixSubWidget.__init__(self, master, name, destroy_physically)
+
+class _dummyMenubutton(Menubutton, TixSubWidget):
+    def __init__(self, master, name, destroy_physically=1):
+        TixSubWidget.__init__(self, master, name, destroy_physically)
+
+class _dummyScrollbar(Scrollbar, TixSubWidget):
+    def __init__(self, master, name, destroy_physically=1):
+        TixSubWidget.__init__(self, master, name, destroy_physically)
+
+class _dummyText(Text, TixSubWidget):
+    def __init__(self, master, name, destroy_physically=1):
+        TixSubWidget.__init__(self, master, name, destroy_physically)
+
+class _dummyScrolledListBox(ScrolledListBox, TixSubWidget):
+    def __init__(self, master, name, destroy_physically=1):
+        TixSubWidget.__init__(self, master, name, destroy_physically)
+        self.subwidget_list['listbox'] = _dummyListbox(self, 'listbox')
+        self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb')
+        self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb')
+
+class _dummyHList(HList, TixSubWidget):
+    def __init__(self, master, name, destroy_physically=1):
+        TixSubWidget.__init__(self, master, name, destroy_physically)
+
+class _dummyScrolledHList(ScrolledHList, TixSubWidget):
+    def __init__(self, master, name, destroy_physically=1):
+        TixSubWidget.__init__(self, master, name, destroy_physically)
+        self.subwidget_list['hlist'] = _dummyHList(self, 'hlist')
+        self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb')
+        self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb')
+
+class _dummyTList(TList, TixSubWidget):
+    def __init__(self, master, name, destroy_physically=1):
+        TixSubWidget.__init__(self, master, name, destroy_physically)
+
+class _dummyComboBox(ComboBox, TixSubWidget):
+    def __init__(self, master, name, destroy_physically=1):
+        TixSubWidget.__init__(self, master, name, ['fancy',destroy_physically])
+        self.subwidget_list['label'] = _dummyLabel(self, 'label')
+        self.subwidget_list['entry'] = _dummyEntry(self, 'entry')
+        self.subwidget_list['arrow'] = _dummyButton(self, 'arrow')
+
+        self.subwidget_list['slistbox'] = _dummyScrolledListBox(self,
+                                                                'slistbox')
+        try:
+            self.subwidget_list['tick'] = _dummyButton(self, 'tick')
+            #cross Button : present if created with the fancy option
+            self.subwidget_list['cross'] = _dummyButton(self, 'cross')
+        except TypeError:
+            # unavailable when -fancy not specified
+            pass
+
+class _dummyDirList(DirList, TixSubWidget):
+    def __init__(self, master, name, destroy_physically=1):
+        TixSubWidget.__init__(self, master, name, destroy_physically)
+        self.subwidget_list['hlist'] = _dummyHList(self, 'hlist')
+        self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb')
+        self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb')
+
+class _dummyDirSelectBox(DirSelectBox, TixSubWidget):
+    def __init__(self, master, name, destroy_physically=1):
+        TixSubWidget.__init__(self, master, name, destroy_physically)
+        self.subwidget_list['dirlist'] = _dummyDirList(self, 'dirlist')
+        self.subwidget_list['dircbx'] = _dummyFileComboBox(self, 'dircbx')
+
+class _dummyExFileSelectBox(ExFileSelectBox, TixSubWidget):
+    def __init__(self, master, name, destroy_physically=1):
+        TixSubWidget.__init__(self, master, name, destroy_physically)
+        self.subwidget_list['cancel'] = _dummyButton(self, 'cancel')
+        self.subwidget_list['ok'] = _dummyButton(self, 'ok')
+        self.subwidget_list['hidden'] = _dummyCheckbutton(self, 'hidden')
+        self.subwidget_list['types'] = _dummyComboBox(self, 'types')
+        self.subwidget_list['dir'] = _dummyComboBox(self, 'dir')
+        self.subwidget_list['dirlist'] = _dummyScrolledListBox(self, 'dirlist')
+        self.subwidget_list['file'] = _dummyComboBox(self, 'file')
+        self.subwidget_list['filelist'] = _dummyScrolledListBox(self, 'filelist')
+
+class _dummyFileSelectBox(FileSelectBox, TixSubWidget):
+    def __init__(self, master, name, destroy_physically=1):
+        TixSubWidget.__init__(self, master, name, destroy_physically)
+        self.subwidget_list['dirlist'] = _dummyScrolledListBox(self, 'dirlist')
+        self.subwidget_list['filelist'] = _dummyScrolledListBox(self, 'filelist')
+        self.subwidget_list['filter'] = _dummyComboBox(self, 'filter')
+        self.subwidget_list['selection'] = _dummyComboBox(self, 'selection')
+
+class _dummyFileComboBox(ComboBox, TixSubWidget):
+    def __init__(self, master, name, destroy_physically=1):
+        TixSubWidget.__init__(self, master, name, destroy_physically)
+        self.subwidget_list['dircbx'] = _dummyComboBox(self, 'dircbx')
+
+class _dummyStdButtonBox(StdButtonBox, TixSubWidget):
+    def __init__(self, master, name, destroy_physically=1):
+        TixSubWidget.__init__(self, master, name, destroy_physically)
+        self.subwidget_list['ok'] = _dummyButton(self, 'ok')
+        self.subwidget_list['apply'] = _dummyButton(self, 'apply')
+        self.subwidget_list['cancel'] = _dummyButton(self, 'cancel')
+        self.subwidget_list['help'] = _dummyButton(self, 'help')
+
+class _dummyNoteBookFrame(NoteBookFrame, TixSubWidget):
+    def __init__(self, master, name, destroy_physically=0):
+        TixSubWidget.__init__(self, master, name, destroy_physically)
+
+class _dummyPanedWindow(PanedWindow, TixSubWidget):
+    def __init__(self, master, name, destroy_physically=1):
+        TixSubWidget.__init__(self, master, name, destroy_physically)
+
+########################
+### Utility Routines ###
+########################
+
+#mike Should tixDestroy be exposed as a wrapper? - but not for widgets.
+
+def OptionName(widget):
+    '''Returns the qualified path name for the widget. Normally used to set
+    default options for subwidgets. See tixwidgets.py'''
+    return widget.tk.call('tixOptionName', widget._w)
+
+# Called with a dictionary argument of the form
+# {'*.c':'C source files', '*.txt':'Text Files', '*':'All files'}
+# returns a string which can be used to configure the fsbox file types
+# in an ExFileSelectBox. i.e.,
+# '{{*} {* - All files}} {{*.c} {*.c - C source files}} {{*.txt} {*.txt - Text Files}}'
+def FileTypeList(dict):
+    s = ''
+    for type in dict.keys():
+        s = s + '{{' + type + '} {' + type + ' - ' + dict[type] + '}} '
+    return s
+
+# Still to be done:
+# tixIconView
+class CObjView(TixWidget):
+    """This file implements the Canvas Object View widget. This is a base
+    class of IconView. It implements automatic placement/adjustment of the
+    scrollbars according to the canvas objects inside the canvas subwidget.
+    The scrollbars are adjusted so that the canvas is just large enough
+    to see all the objects.
+    """
+    # FIXME: It should inherit -superclass tixScrolledWidget
+    pass
+
+
+class Grid(TixWidget):
+    '''The Tix Grid command creates a new window  and makes it into a
+    tixGrid widget. Additional options, may be specified on the command
+    line or in the option database to configure aspects such as its cursor
+    and relief.
+
+    A Grid widget displays its contents in a two dimensional grid of cells.
+    Each cell may contain one Tix display item, which may be in text,
+    graphics or other formats. See the DisplayStyle class for more information
+    about Tix display items. Individual cells, or groups of cells, can be
+    formatted with a wide range of attributes, such as its color, relief and
+    border.
+
+    Subwidgets - None'''
+    # valid specific resources as of Tk 8.4
+    # editdonecmd, editnotifycmd, floatingcols, floatingrows, formatcmd,
+    # highlightbackground, highlightcolor, leftmargin, itemtype, selectmode,
+    # selectunit, topmargin,
+    def __init__(self, master=None, cnf={}, **kw):
+        static= []
+        self.cnf= cnf
+        TixWidget.__init__(self, master, 'tixGrid', static, cnf, kw)
+
+    # valid options as of Tk 8.4
+    # anchor, bdtype, cget, configure, delete, dragsite, dropsite, entrycget, edit
+    # entryconfigure, format, geometryinfo, info, index, move, nearest, selection
+    # set, size, unset, xview, yview
+    # def anchor option ?args ...?
+    def anchor_get(self):
+        "Get the (x,y) coordinate of the current anchor cell"
+        return self._getints(self.tk.call(self, 'anchor', 'get'))
+
+    # def bdtype
+    # def delete dim from ?to?
+    def delete_row(self, from_, to=None):
+        """Delete rows between from_ and to inclusive.
+        If to is not provided,  delete only row at from_"""
+        if to is None:
+            self.tk.call(self, 'delete', 'row', from_)
+        else:
+            self.tk.call(self, 'delete', 'row', from_, to)
+    def delete_column(self, from_, to=None):
+        """Delete columns between from_ and to inclusive.
+        If to is not provided,  delete only column at from_"""
+        if to is None:
+            self.tk.call(self, 'delete', 'column', from_)
+        else:
+            self.tk.call(self, 'delete', 'column', from_, to)
+    # def edit apply
+    # def edit set x y
+
+    def entrycget(self, x, y, option):
+        "Get the option value for cell at (x,y)"
+        return self.tk.call(self, 'entrycget', x, y, option)
+
+    def entryconfigure(self, x, y, **kw):
+        return self.tk.call(self, 'entryconfigure', x, y, *self._options(None, kw))
+    # def format
+    # def index
+
+    def info_exists(self, x, y):
+        "Return True if display item exists at (x,y)"
+        return bool(int(self.tk.call(self, 'info', 'exists', x, y)))
+
+    def info_bbox(self, x, y):
+        # This seems to always return '', at least for 'text' displayitems
+        return self.tk.call(self, 'info', 'bbox', x, y)
+
+    def nearest(self, x, y):
+        "Return coordinate of cell nearest pixel coordinate (x,y)"
+        return self._getints(self.tk.call(self, 'nearest', x, y))
+
+    # def selection adjust
+    # def selection clear
+    # def selection includes
+    # def selection set
+    # def selection toggle
+    # def move dim from to offset
+
+    def set(self, x, y, itemtype=None, **kw):
+        args= self._options(self.cnf, kw)
+        if itemtype is not None:
+            args= ('-itemtype', itemtype) + args
+        self.tk.call(self, 'set', x, y, *args)
+
+    # def size dim index ?option value ...?
+    # def unset x y
+
+    def xview(self):
+        return self._getdoubles(self.tk.call(self, 'xview'))
+    def xview_moveto(self, fraction):
+        self.tk.call(self,'xview', 'moveto', fraction)
+    def xview_scroll(self, count, what="units"):
+        "Scroll right (count>0) or left <count> of units|pages"
+        self.tk.call(self, 'xview', 'scroll', count, what)
+
+    def yview(self):
+        return self._getdoubles(self.tk.call(self, 'yview'))
+    def yview_moveto(self, fraction):
+        self.tk.call(self,'ysview', 'moveto', fraction)
+    def yview_scroll(self, count, what="units"):
+        "Scroll down (count>0) or up <count> of units|pages"
+        self.tk.call(self, 'yview', 'scroll', count, what)
+
+class ScrolledGrid(Grid):
+    '''Scrolled Grid widgets'''
+
+    # FIXME: It should inherit -superclass tixScrolledWidget
+    def __init__(self, master=None, cnf={}, **kw):
+        static= []
+        self.cnf= cnf
+        TixWidget.__init__(self, master, 'tixScrolledGrid', static, cnf, kw)


Property changes on: vendor/Python/current/Lib/lib-tk/Tix.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/lib-tk/Tkconstants.py
===================================================================
--- vendor/Python/current/Lib/lib-tk/Tkconstants.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/lib-tk/Tkconstants.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,110 @@
+# Symbolic constants for Tk
+
+# Booleans
+NO=FALSE=OFF=0
+YES=TRUE=ON=1
+
+# -anchor and -sticky
+N='n'
+S='s'
+W='w'
+E='e'
+NW='nw'
+SW='sw'
+NE='ne'
+SE='se'
+NS='ns'
+EW='ew'
+NSEW='nsew'
+CENTER='center'
+
+# -fill
+NONE='none'
+X='x'
+Y='y'
+BOTH='both'
+
+# -side
+LEFT='left'
+TOP='top'
+RIGHT='right'
+BOTTOM='bottom'
+
+# -relief
+RAISED='raised'
+SUNKEN='sunken'
+FLAT='flat'
+RIDGE='ridge'
+GROOVE='groove'
+SOLID = 'solid'
+
+# -orient
+HORIZONTAL='horizontal'
+VERTICAL='vertical'
+
+# -tabs
+NUMERIC='numeric'
+
+# -wrap
+CHAR='char'
+WORD='word'
+
+# -align
+BASELINE='baseline'
+
+# -bordermode
+INSIDE='inside'
+OUTSIDE='outside'
+
+# Special tags, marks and insert positions
+SEL='sel'
+SEL_FIRST='sel.first'
+SEL_LAST='sel.last'
+END='end'
+INSERT='insert'
+CURRENT='current'
+ANCHOR='anchor'
+ALL='all' # e.g. Canvas.delete(ALL)
+
+# Text widget and button states
+NORMAL='normal'
+DISABLED='disabled'
+ACTIVE='active'
+# Canvas state
+HIDDEN='hidden'
+
+# Menu item types
+CASCADE='cascade'
+CHECKBUTTON='checkbutton'
+COMMAND='command'
+RADIOBUTTON='radiobutton'
+SEPARATOR='separator'
+
+# Selection modes for list boxes
+SINGLE='single'
+BROWSE='browse'
+MULTIPLE='multiple'
+EXTENDED='extended'
+
+# Activestyle for list boxes
+# NONE='none' is also valid
+DOTBOX='dotbox'
+UNDERLINE='underline'
+
+# Various canvas styles
+PIESLICE='pieslice'
+CHORD='chord'
+ARC='arc'
+FIRST='first'
+LAST='last'
+BUTT='butt'
+PROJECTING='projecting'
+ROUND='round'
+BEVEL='bevel'
+MITER='miter'
+
+# Arguments to xview/yview
+MOVETO='moveto'
+SCROLL='scroll'
+UNITS='units'
+PAGES='pages'

Added: vendor/Python/current/Lib/lib-tk/Tkdnd.py
===================================================================
--- vendor/Python/current/Lib/lib-tk/Tkdnd.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/lib-tk/Tkdnd.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,321 @@
+"""Drag-and-drop support for Tkinter.
+
+This is very preliminary.  I currently only support dnd *within* one
+application, between different windows (or within the same window).
+
+I an trying to make this as generic as possible -- not dependent on
+the use of a particular widget or icon type, etc.  I also hope that
+this will work with Pmw.
+
+To enable an object to be dragged, you must create an event binding
+for it that starts the drag-and-drop process. Typically, you should
+bind <ButtonPress> to a callback function that you write. The function
+should call Tkdnd.dnd_start(source, event), where 'source' is the
+object to be dragged, and 'event' is the event that invoked the call
+(the argument to your callback function).  Even though this is a class
+instantiation, the returned instance should not be stored -- it will
+be kept alive automatically for the duration of the drag-and-drop.
+
+When a drag-and-drop is already in process for the Tk interpreter, the
+call is *ignored*; this normally averts starting multiple simultaneous
+dnd processes, e.g. because different button callbacks all
+dnd_start().
+
+The object is *not* necessarily a widget -- it can be any
+application-specific object that is meaningful to potential
+drag-and-drop targets.
+
+Potential drag-and-drop targets are discovered as follows.  Whenever
+the mouse moves, and at the start and end of a drag-and-drop move, the
+Tk widget directly under the mouse is inspected.  This is the target
+widget (not to be confused with the target object, yet to be
+determined).  If there is no target widget, there is no dnd target
+object.  If there is a target widget, and it has an attribute
+dnd_accept, this should be a function (or any callable object).  The
+function is called as dnd_accept(source, event), where 'source' is the
+object being dragged (the object passed to dnd_start() above), and
+'event' is the most recent event object (generally a <Motion> event;
+it can also be <ButtonPress> or <ButtonRelease>).  If the dnd_accept()
+function returns something other than None, this is the new dnd target
+object.  If dnd_accept() returns None, or if the target widget has no
+dnd_accept attribute, the target widget's parent is considered as the
+target widget, and the search for a target object is repeated from
+there.  If necessary, the search is repeated all the way up to the
+root widget.  If none of the target widgets can produce a target
+object, there is no target object (the target object is None).
+
+The target object thus produced, if any, is called the new target
+object.  It is compared with the old target object (or None, if there
+was no old target widget).  There are several cases ('source' is the
+source object, and 'event' is the most recent event object):
+
+- Both the old and new target objects are None.  Nothing happens.
+
+- The old and new target objects are the same object.  Its method
+dnd_motion(source, event) is called.
+
+- The old target object was None, and the new target object is not
+None.  The new target object's method dnd_enter(source, event) is
+called.
+
+- The new target object is None, and the old target object is not
+None.  The old target object's method dnd_leave(source, event) is
+called.
+
+- The old and new target objects differ and neither is None.  The old
+target object's method dnd_leave(source, event), and then the new
+target object's method dnd_enter(source, event) is called.
+
+Once this is done, the new target object replaces the old one, and the
+Tk mainloop proceeds.  The return value of the methods mentioned above
+is ignored; if they raise an exception, the normal exception handling
+mechanisms take over.
+
+The drag-and-drop processes can end in two ways: a final target object
+is selected, or no final target object is selected.  When a final
+target object is selected, it will always have been notified of the
+potential drop by a call to its dnd_enter() method, as described
+above, and possibly one or more calls to its dnd_motion() method; its
+dnd_leave() method has not been called since the last call to
+dnd_enter().  The target is notified of the drop by a call to its
+method dnd_commit(source, event).
+
+If no final target object is selected, and there was an old target
+object, its dnd_leave(source, event) method is called to complete the
+dnd sequence.
+
+Finally, the source object is notified that the drag-and-drop process
+is over, by a call to source.dnd_end(target, event), specifying either
+the selected target object, or None if no target object was selected.
+The source object can use this to implement the commit action; this is
+sometimes simpler than to do it in the target's dnd_commit().  The
+target's dnd_commit() method could then simply be aliased to
+dnd_leave().
+
+At any time during a dnd sequence, the application can cancel the
+sequence by calling the cancel() method on the object returned by
+dnd_start().  This will call dnd_leave() if a target is currently
+active; it will never call dnd_commit().
+
+"""
+
+
+import Tkinter
+
+
+# The factory function
+
+def dnd_start(source, event):
+    h = DndHandler(source, event)
+    if h.root:
+        return h
+    else:
+        return None
+
+
+# The class that does the work
+
+class DndHandler:
+
+    root = None
+
+    def __init__(self, source, event):
+        if event.num > 5:
+            return
+        root = event.widget._root()
+        try:
+            root.__dnd
+            return # Don't start recursive dnd
+        except AttributeError:
+            root.__dnd = self
+            self.root = root
+        self.source = source
+        self.target = None
+        self.initial_button = button = event.num
+        self.initial_widget = widget = event.widget
+        self.release_pattern = "<B%d-ButtonRelease-%d>" % (button, button)
+        self.save_cursor = widget['cursor'] or ""
+        widget.bind(self.release_pattern, self.on_release)
+        widget.bind("<Motion>", self.on_motion)
+        widget['cursor'] = "hand2"
+
+    def __del__(self):
+        root = self.root
+        self.root = None
+        if root:
+            try:
+                del root.__dnd
+            except AttributeError:
+                pass
+
+    def on_motion(self, event):
+        x, y = event.x_root, event.y_root
+        target_widget = self.initial_widget.winfo_containing(x, y)
+        source = self.source
+        new_target = None
+        while target_widget:
+            try:
+                attr = target_widget.dnd_accept
+            except AttributeError:
+                pass
+            else:
+                new_target = attr(source, event)
+                if new_target:
+                    break
+            target_widget = target_widget.master
+        old_target = self.target
+        if old_target is new_target:
+            if old_target:
+                old_target.dnd_motion(source, event)
+        else:
+            if old_target:
+                self.target = None
+                old_target.dnd_leave(source, event)
+            if new_target:
+                new_target.dnd_enter(source, event)
+                self.target = new_target
+
+    def on_release(self, event):
+        self.finish(event, 1)
+
+    def cancel(self, event=None):
+        self.finish(event, 0)
+
+    def finish(self, event, commit=0):
+        target = self.target
+        source = self.source
+        widget = self.initial_widget
+        root = self.root
+        try:
+            del root.__dnd
+            self.initial_widget.unbind(self.release_pattern)
+            self.initial_widget.unbind("<Motion>")
+            widget['cursor'] = self.save_cursor
+            self.target = self.source = self.initial_widget = self.root = None
+            if target:
+                if commit:
+                    target.dnd_commit(source, event)
+                else:
+                    target.dnd_leave(source, event)
+        finally:
+            source.dnd_end(target, event)
+
+
+
+# ----------------------------------------------------------------------
+# The rest is here for testing and demonstration purposes only!
+
+class Icon:
+
+    def __init__(self, name):
+        self.name = name
+        self.canvas = self.label = self.id = None
+
+    def attach(self, canvas, x=10, y=10):
+        if canvas is self.canvas:
+            self.canvas.coords(self.id, x, y)
+            return
+        if self.canvas:
+            self.detach()
+        if not canvas:
+            return
+        label = Tkinter.Label(canvas, text=self.name,
+                              borderwidth=2, relief="raised")
+        id = canvas.create_window(x, y, window=label, anchor="nw")
+        self.canvas = canvas
+        self.label = label
+        self.id = id
+        label.bind("<ButtonPress>", self.press)
+
+    def detach(self):
+        canvas = self.canvas
+        if not canvas:
+            return
+        id = self.id
+        label = self.label
+        self.canvas = self.label = self.id = None
+        canvas.delete(id)
+        label.destroy()
+
+    def press(self, event):
+        if dnd_start(self, event):
+            # where the pointer is relative to the label widget:
+            self.x_off = event.x
+            self.y_off = event.y
+            # where the widget is relative to the canvas:
+            self.x_orig, self.y_orig = self.canvas.coords(self.id)
+
+    def move(self, event):
+        x, y = self.where(self.canvas, event)
+        self.canvas.coords(self.id, x, y)
+
+    def putback(self):
+        self.canvas.coords(self.id, self.x_orig, self.y_orig)
+
+    def where(self, canvas, event):
+        # where the corner of the canvas is relative to the screen:
+        x_org = canvas.winfo_rootx()
+        y_org = canvas.winfo_rooty()
+        # where the pointer is relative to the canvas widget:
+        x = event.x_root - x_org
+        y = event.y_root - y_org
+        # compensate for initial pointer offset
+        return x - self.x_off, y - self.y_off
+
+    def dnd_end(self, target, event):
+        pass
+
+class Tester:
+
+    def __init__(self, root):
+        self.top = Tkinter.Toplevel(root)
+        self.canvas = Tkinter.Canvas(self.top, width=100, height=100)
+        self.canvas.pack(fill="both", expand=1)
+        self.canvas.dnd_accept = self.dnd_accept
+
+    def dnd_accept(self, source, event):
+        return self
+
+    def dnd_enter(self, source, event):
+        self.canvas.focus_set() # Show highlight border
+        x, y = source.where(self.canvas, event)
+        x1, y1, x2, y2 = source.canvas.bbox(source.id)
+        dx, dy = x2-x1, y2-y1
+        self.dndid = self.canvas.create_rectangle(x, y, x+dx, y+dy)
+        self.dnd_motion(source, event)
+
+    def dnd_motion(self, source, event):
+        x, y = source.where(self.canvas, event)
+        x1, y1, x2, y2 = self.canvas.bbox(self.dndid)
+        self.canvas.move(self.dndid, x-x1, y-y1)
+
+    def dnd_leave(self, source, event):
+        self.top.focus_set() # Hide highlight border
+        self.canvas.delete(self.dndid)
+        self.dndid = None
+
+    def dnd_commit(self, source, event):
+        self.dnd_leave(source, event)
+        x, y = source.where(self.canvas, event)
+        source.attach(self.canvas, x, y)
+
+def test():
+    root = Tkinter.Tk()
+    root.geometry("+1+1")
+    Tkinter.Button(command=root.quit, text="Quit").pack()
+    t1 = Tester(root)
+    t1.top.geometry("+1+60")
+    t2 = Tester(root)
+    t2.top.geometry("+120+60")
+    t3 = Tester(root)
+    t3.top.geometry("+240+60")
+    i1 = Icon("ICON1")
+    i2 = Icon("ICON2")
+    i3 = Icon("ICON3")
+    i1.attach(t1.canvas)
+    i2.attach(t2.canvas)
+    i3.attach(t3.canvas)
+    root.mainloop()
+
+if __name__ == '__main__':
+    test()

Added: vendor/Python/current/Lib/lib-tk/Tkinter.py
===================================================================
--- vendor/Python/current/Lib/lib-tk/Tkinter.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/lib-tk/Tkinter.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,3759 @@
+"""Wrapper functions for Tcl/Tk.
+
+Tkinter provides classes which allow the display, positioning and
+control of widgets. Toplevel widgets are Tk and Toplevel. Other
+widgets are Frame, Label, Entry, Text, Canvas, Button, Radiobutton,
+Checkbutton, Scale, Listbox, Scrollbar, OptionMenu, Spinbox
+LabelFrame and PanedWindow.
+
+Properties of the widgets are specified with keyword arguments.
+Keyword arguments have the same name as the corresponding resource
+under Tk.
+
+Widgets are positioned with one of the geometry managers Place, Pack
+or Grid. These managers can be called with methods place, pack, grid
+available in every Widget.
+
+Actions are bound to events by resources (e.g. keyword argument
+command) or with the method bind.
+
+Example (Hello, World):
+import Tkinter
+from Tkconstants import *
+tk = Tkinter.Tk()
+frame = Tkinter.Frame(tk, relief=RIDGE, borderwidth=2)
+frame.pack(fill=BOTH,expand=1)
+label = Tkinter.Label(frame, text="Hello, World")
+label.pack(fill=X, expand=1)
+button = Tkinter.Button(frame,text="Exit",command=tk.destroy)
+button.pack(side=BOTTOM)
+tk.mainloop()
+"""
+
+__version__ = "$Revision: 50704 $"
+
+import sys
+if sys.platform == "win32":
+    import FixTk # Attempt to configure Tcl/Tk without requiring PATH
+import _tkinter # If this fails your Python may not be configured for Tk
+tkinter = _tkinter # b/w compat for export
+TclError = _tkinter.TclError
+from types import *
+from Tkconstants import *
+try:
+    import MacOS; _MacOS = MacOS; del MacOS
+except ImportError:
+    _MacOS = None
+
+wantobjects = 1
+
+TkVersion = float(_tkinter.TK_VERSION)
+TclVersion = float(_tkinter.TCL_VERSION)
+
+READABLE = _tkinter.READABLE
+WRITABLE = _tkinter.WRITABLE
+EXCEPTION = _tkinter.EXCEPTION
+
+# These are not always defined, e.g. not on Win32 with Tk 8.0 :-(
+try: _tkinter.createfilehandler
+except AttributeError: _tkinter.createfilehandler = None
+try: _tkinter.deletefilehandler
+except AttributeError: _tkinter.deletefilehandler = None
+
+
+def _flatten(tuple):
+    """Internal function."""
+    res = ()
+    for item in tuple:
+        if type(item) in (TupleType, ListType):
+            res = res + _flatten(item)
+        elif item is not None:
+            res = res + (item,)
+    return res
+
+try: _flatten = _tkinter._flatten
+except AttributeError: pass
+
+def _cnfmerge(cnfs):
+    """Internal function."""
+    if type(cnfs) is DictionaryType:
+        return cnfs
+    elif type(cnfs) in (NoneType, StringType):
+        return cnfs
+    else:
+        cnf = {}
+        for c in _flatten(cnfs):
+            try:
+                cnf.update(c)
+            except (AttributeError, TypeError), msg:
+                print "_cnfmerge: fallback due to:", msg
+                for k, v in c.items():
+                    cnf[k] = v
+        return cnf
+
+try: _cnfmerge = _tkinter._cnfmerge
+except AttributeError: pass
+
+class Event:
+    """Container for the properties of an event.
+
+    Instances of this type are generated if one of the following events occurs:
+
+    KeyPress, KeyRelease - for keyboard events
+    ButtonPress, ButtonRelease, Motion, Enter, Leave, MouseWheel - for mouse events
+    Visibility, Unmap, Map, Expose, FocusIn, FocusOut, Circulate,
+    Colormap, Gravity, Reparent, Property, Destroy, Activate,
+    Deactivate - for window events.
+
+    If a callback function for one of these events is registered
+    using bind, bind_all, bind_class, or tag_bind, the callback is
+    called with an Event as first argument. It will have the
+    following attributes (in braces are the event types for which
+    the attribute is valid):
+
+        serial - serial number of event
+    num - mouse button pressed (ButtonPress, ButtonRelease)
+    focus - whether the window has the focus (Enter, Leave)
+    height - height of the exposed window (Configure, Expose)
+    width - width of the exposed window (Configure, Expose)
+    keycode - keycode of the pressed key (KeyPress, KeyRelease)
+    state - state of the event as a number (ButtonPress, ButtonRelease,
+                            Enter, KeyPress, KeyRelease,
+                            Leave, Motion)
+    state - state as a string (Visibility)
+    time - when the event occurred
+    x - x-position of the mouse
+    y - y-position of the mouse
+    x_root - x-position of the mouse on the screen
+             (ButtonPress, ButtonRelease, KeyPress, KeyRelease, Motion)
+    y_root - y-position of the mouse on the screen
+             (ButtonPress, ButtonRelease, KeyPress, KeyRelease, Motion)
+    char - pressed character (KeyPress, KeyRelease)
+    send_event - see X/Windows documentation
+    keysym - keysym of the event as a string (KeyPress, KeyRelease)
+    keysym_num - keysym of the event as a number (KeyPress, KeyRelease)
+    type - type of the event as a number
+    widget - widget in which the event occurred
+    delta - delta of wheel movement (MouseWheel)
+    """
+    pass
+
+_support_default_root = 1
+_default_root = None
+
+def NoDefaultRoot():
+    """Inhibit setting of default root window.
+
+    Call this function to inhibit that the first instance of
+    Tk is used for windows without an explicit parent window.
+    """
+    global _support_default_root
+    _support_default_root = 0
+    global _default_root
+    _default_root = None
+    del _default_root
+
+def _tkerror(err):
+    """Internal function."""
+    pass
+
+def _exit(code='0'):
+    """Internal function. Calling it will throw the exception SystemExit."""
+    raise SystemExit, code
+
+_varnum = 0
+class Variable:
+    """Class to define value holders for e.g. buttons.
+
+    Subclasses StringVar, IntVar, DoubleVar, BooleanVar are specializations
+    that constrain the type of the value returned from get()."""
+    _default = ""
+    def __init__(self, master=None, value=None, name=None):
+        """Construct a variable
+
+        MASTER can be given as master widget.
+        VALUE is an optional value (defaults to "")
+        NAME is an optional Tcl name (defaults to PY_VARnum).
+
+        If NAME matches an existing variable and VALUE is omitted
+        then the existing value is retained.
+        """
+        global _varnum
+        if not master:
+            master = _default_root
+        self._master = master
+        self._tk = master.tk
+        if name:
+            self._name = name
+        else:
+            self._name = 'PY_VAR' + repr(_varnum)
+            _varnum += 1
+        if value != None:
+            self.set(value)
+        elif not self._tk.call("info", "exists", self._name):
+            self.set(self._default)
+    def __del__(self):
+        """Unset the variable in Tcl."""
+        self._tk.globalunsetvar(self._name)
+    def __str__(self):
+        """Return the name of the variable in Tcl."""
+        return self._name
+    def set(self, value):
+        """Set the variable to VALUE."""
+        return self._tk.globalsetvar(self._name, value)
+    def get(self):
+        """Return value of variable."""
+        return self._tk.globalgetvar(self._name)
+    def trace_variable(self, mode, callback):
+        """Define a trace callback for the variable.
+
+        MODE is one of "r", "w", "u" for read, write, undefine.
+        CALLBACK must be a function which is called when
+        the variable is read, written or undefined.
+
+        Return the name of the callback.
+        """
+        cbname = self._master._register(callback)
+        self._tk.call("trace", "variable", self._name, mode, cbname)
+        return cbname
+    trace = trace_variable
+    def trace_vdelete(self, mode, cbname):
+        """Delete the trace callback for a variable.
+
+        MODE is one of "r", "w", "u" for read, write, undefine.
+        CBNAME is the name of the callback returned from trace_variable or trace.
+        """
+        self._tk.call("trace", "vdelete", self._name, mode, cbname)
+        self._master.deletecommand(cbname)
+    def trace_vinfo(self):
+        """Return all trace callback information."""
+        return map(self._tk.split, self._tk.splitlist(
+            self._tk.call("trace", "vinfo", self._name)))
+    def __eq__(self, other):
+        """Comparison for equality (==).
+
+        Note: if the Variable's master matters to behavior
+        also compare self._master == other._master
+        """
+        return self.__class__.__name__ == other.__class__.__name__ \
+            and self._name == other._name
+
+class StringVar(Variable):
+    """Value holder for strings variables."""
+    _default = ""
+    def __init__(self, master=None, value=None, name=None):
+        """Construct a string variable.
+
+        MASTER can be given as master widget.
+        VALUE is an optional value (defaults to "")
+        NAME is an optional Tcl name (defaults to PY_VARnum).
+
+        If NAME matches an existing variable and VALUE is omitted
+        then the existing value is retained.
+        """
+        Variable.__init__(self, master, value, name)
+
+    def get(self):
+        """Return value of variable as string."""
+        value = self._tk.globalgetvar(self._name)
+        if isinstance(value, basestring):
+            return value
+        return str(value)
+
+class IntVar(Variable):
+    """Value holder for integer variables."""
+    _default = 0
+    def __init__(self, master=None, value=None, name=None):
+        """Construct an integer variable.
+
+        MASTER can be given as master widget.
+        VALUE is an optional value (defaults to 0)
+        NAME is an optional Tcl name (defaults to PY_VARnum).
+
+        If NAME matches an existing variable and VALUE is omitted
+        then the existing value is retained.
+        """
+        Variable.__init__(self, master, value, name)
+
+    def set(self, value):
+        """Set the variable to value, converting booleans to integers."""
+        if isinstance(value, bool):
+            value = int(value)
+        return Variable.set(self, value)
+
+    def get(self):
+        """Return the value of the variable as an integer."""
+        return getint(self._tk.globalgetvar(self._name))
+
+class DoubleVar(Variable):
+    """Value holder for float variables."""
+    _default = 0.0
+    def __init__(self, master=None, value=None, name=None):
+        """Construct a float variable.
+
+        MASTER can be given as master widget.
+        VALUE is an optional value (defaults to 0.0)
+        NAME is an optional Tcl name (defaults to PY_VARnum).
+
+        If NAME matches an existing variable and VALUE is omitted
+        then the existing value is retained.
+        """
+        Variable.__init__(self, master, value, name)
+
+    def get(self):
+        """Return the value of the variable as a float."""
+        return getdouble(self._tk.globalgetvar(self._name))
+
+class BooleanVar(Variable):
+    """Value holder for boolean variables."""
+    _default = False
+    def __init__(self, master=None, value=None, name=None):
+        """Construct a boolean variable.
+
+        MASTER can be given as master widget.
+        VALUE is an optional value (defaults to False)
+        NAME is an optional Tcl name (defaults to PY_VARnum).
+
+        If NAME matches an existing variable and VALUE is omitted
+        then the existing value is retained.
+        """
+        Variable.__init__(self, master, value, name)
+
+    def get(self):
+        """Return the value of the variable as a bool."""
+        return self._tk.getboolean(self._tk.globalgetvar(self._name))
+
+def mainloop(n=0):
+    """Run the main loop of Tcl."""
+    _default_root.tk.mainloop(n)
+
+getint = int
+
+getdouble = float
+
+def getboolean(s):
+    """Convert true and false to integer values 1 and 0."""
+    return _default_root.tk.getboolean(s)
+
+# Methods defined on both toplevel and interior widgets
+class Misc:
+    """Internal class.
+
+    Base class which defines methods common for interior widgets."""
+
+    # XXX font command?
+    _tclCommands = None
+    def destroy(self):
+        """Internal function.
+
+        Delete all Tcl commands created for
+        this widget in the Tcl interpreter."""
+        if self._tclCommands is not None:
+            for name in self._tclCommands:
+                #print '- Tkinter: deleted command', name
+                self.tk.deletecommand(name)
+            self._tclCommands = None
+    def deletecommand(self, name):
+        """Internal function.
+
+        Delete the Tcl command provided in NAME."""
+        #print '- Tkinter: deleted command', name
+        self.tk.deletecommand(name)
+        try:
+            self._tclCommands.remove(name)
+        except ValueError:
+            pass
+    def tk_strictMotif(self, boolean=None):
+        """Set Tcl internal variable, whether the look and feel
+        should adhere to Motif.
+
+        A parameter of 1 means adhere to Motif (e.g. no color
+        change if mouse passes over slider).
+        Returns the set value."""
+        return self.tk.getboolean(self.tk.call(
+            'set', 'tk_strictMotif', boolean))
+    def tk_bisque(self):
+        """Change the color scheme to light brown as used in Tk 3.6 and before."""
+        self.tk.call('tk_bisque')
+    def tk_setPalette(self, *args, **kw):
+        """Set a new color scheme for all widget elements.
+
+        A single color as argument will cause that all colors of Tk
+        widget elements are derived from this.
+        Alternatively several keyword parameters and its associated
+        colors can be given. The following keywords are valid:
+        activeBackground, foreground, selectColor,
+        activeForeground, highlightBackground, selectBackground,
+        background, highlightColor, selectForeground,
+        disabledForeground, insertBackground, troughColor."""
+        self.tk.call(('tk_setPalette',)
+              + _flatten(args) + _flatten(kw.items()))
+    def tk_menuBar(self, *args):
+        """Do not use. Needed in Tk 3.6 and earlier."""
+        pass # obsolete since Tk 4.0
+    def wait_variable(self, name='PY_VAR'):
+        """Wait until the variable is modified.
+
+        A parameter of type IntVar, StringVar, DoubleVar or
+        BooleanVar must be given."""
+        self.tk.call('tkwait', 'variable', name)
+    waitvar = wait_variable # XXX b/w compat
+    def wait_window(self, window=None):
+        """Wait until a WIDGET is destroyed.
+
+        If no parameter is given self is used."""
+        if window is None:
+            window = self
+        self.tk.call('tkwait', 'window', window._w)
+    def wait_visibility(self, window=None):
+        """Wait until the visibility of a WIDGET changes
+        (e.g. it appears).
+
+        If no parameter is given self is used."""
+        if window is None:
+            window = self
+        self.tk.call('tkwait', 'visibility', window._w)
+    def setvar(self, name='PY_VAR', value='1'):
+        """Set Tcl variable NAME to VALUE."""
+        self.tk.setvar(name, value)
+    def getvar(self, name='PY_VAR'):
+        """Return value of Tcl variable NAME."""
+        return self.tk.getvar(name)
+    getint = int
+    getdouble = float
+    def getboolean(self, s):
+        """Return a boolean value for Tcl boolean values true and false given as parameter."""
+        return self.tk.getboolean(s)
+    def focus_set(self):
+        """Direct input focus to this widget.
+
+        If the application currently does not have the focus
+        this widget will get the focus if the application gets
+        the focus through the window manager."""
+        self.tk.call('focus', self._w)
+    focus = focus_set # XXX b/w compat?
+    def focus_force(self):
+        """Direct input focus to this widget even if the
+        application does not have the focus. Use with
+        caution!"""
+        self.tk.call('focus', '-force', self._w)
+    def focus_get(self):
+        """Return the widget which has currently the focus in the
+        application.
+
+        Use focus_displayof to allow working with several
+        displays. Return None if application does not have
+        the focus."""
+        name = self.tk.call('focus')
+        if name == 'none' or not name: return None
+        return self._nametowidget(name)
+    def focus_displayof(self):
+        """Return the widget which has currently the focus on the
+        display where this widget is located.
+
+        Return None if the application does not have the focus."""
+        name = self.tk.call('focus', '-displayof', self._w)
+        if name == 'none' or not name: return None
+        return self._nametowidget(name)
+    def focus_lastfor(self):
+        """Return the widget which would have the focus if top level
+        for this widget gets the focus from the window manager."""
+        name = self.tk.call('focus', '-lastfor', self._w)
+        if name == 'none' or not name: return None
+        return self._nametowidget(name)
+    def tk_focusFollowsMouse(self):
+        """The widget under mouse will get automatically focus. Can not
+        be disabled easily."""
+        self.tk.call('tk_focusFollowsMouse')
+    def tk_focusNext(self):
+        """Return the next widget in the focus order which follows
+        widget which has currently the focus.
+
+        The focus order first goes to the next child, then to
+        the children of the child recursively and then to the
+        next sibling which is higher in the stacking order.  A
+        widget is omitted if it has the takefocus resource set
+        to 0."""
+        name = self.tk.call('tk_focusNext', self._w)
+        if not name: return None
+        return self._nametowidget(name)
+    def tk_focusPrev(self):
+        """Return previous widget in the focus order. See tk_focusNext for details."""
+        name = self.tk.call('tk_focusPrev', self._w)
+        if not name: return None
+        return self._nametowidget(name)
+    def after(self, ms, func=None, *args):
+        """Call function once after given time.
+
+        MS specifies the time in milliseconds. FUNC gives the
+        function which shall be called. Additional parameters
+        are given as parameters to the function call.  Return
+        identifier to cancel scheduling with after_cancel."""
+        if not func:
+            # I'd rather use time.sleep(ms*0.001)
+            self.tk.call('after', ms)
+        else:
+            def callit():
+                try:
+                    func(*args)
+                finally:
+                    try:
+                        self.deletecommand(name)
+                    except TclError:
+                        pass
+            name = self._register(callit)
+            return self.tk.call('after', ms, name)
+    def after_idle(self, func, *args):
+        """Call FUNC once if the Tcl main loop has no event to
+        process.
+
+        Return an identifier to cancel the scheduling with
+        after_cancel."""
+        return self.after('idle', func, *args)
+    def after_cancel(self, id):
+        """Cancel scheduling of function identified with ID.
+
+        Identifier returned by after or after_idle must be
+        given as first parameter."""
+        try:
+            data = self.tk.call('after', 'info', id)
+            # In Tk 8.3, splitlist returns: (script, type)
+            # In Tk 8.4, splitlist may return (script, type) or (script,)
+            script = self.tk.splitlist(data)[0]
+            self.deletecommand(script)
+        except TclError:
+            pass
+        self.tk.call('after', 'cancel', id)
+    def bell(self, displayof=0):
+        """Ring a display's bell."""
+        self.tk.call(('bell',) + self._displayof(displayof))
+
+    # Clipboard handling:
+    def clipboard_get(self, **kw):
+        """Retrieve data from the clipboard on window's display.
+
+        The window keyword defaults to the root window of the Tkinter
+        application.
+
+        The type keyword specifies the form in which the data is
+        to be returned and should be an atom name such as STRING
+        or FILE_NAME.  Type defaults to STRING.
+
+        This command is equivalent to:
+
+        selection_get(CLIPBOARD)
+        """
+        return self.tk.call(('clipboard', 'get') + self._options(kw))
+
+    def clipboard_clear(self, **kw):
+        """Clear the data in the Tk clipboard.
+
+        A widget specified for the optional displayof keyword
+        argument specifies the target display."""
+        if not kw.has_key('displayof'): kw['displayof'] = self._w
+        self.tk.call(('clipboard', 'clear') + self._options(kw))
+    def clipboard_append(self, string, **kw):
+        """Append STRING to the Tk clipboard.
+
+        A widget specified at the optional displayof keyword
+        argument specifies the target display. The clipboard
+        can be retrieved with selection_get."""
+        if not kw.has_key('displayof'): kw['displayof'] = self._w
+        self.tk.call(('clipboard', 'append') + self._options(kw)
+              + ('--', string))
+    # XXX grab current w/o window argument
+    def grab_current(self):
+        """Return widget which has currently the grab in this application
+        or None."""
+        name = self.tk.call('grab', 'current', self._w)
+        if not name: return None
+        return self._nametowidget(name)
+    def grab_release(self):
+        """Release grab for this widget if currently set."""
+        self.tk.call('grab', 'release', self._w)
+    def grab_set(self):
+        """Set grab for this widget.
+
+        A grab directs all events to this and descendant
+        widgets in the application."""
+        self.tk.call('grab', 'set', self._w)
+    def grab_set_global(self):
+        """Set global grab for this widget.
+
+        A global grab directs all events to this and
+        descendant widgets on the display. Use with caution -
+        other applications do not get events anymore."""
+        self.tk.call('grab', 'set', '-global', self._w)
+    def grab_status(self):
+        """Return None, "local" or "global" if this widget has
+        no, a local or a global grab."""
+        status = self.tk.call('grab', 'status', self._w)
+        if status == 'none': status = None
+        return status
+    def lower(self, belowThis=None):
+        """Lower this widget in the stacking order."""
+        self.tk.call('lower', self._w, belowThis)
+    def option_add(self, pattern, value, priority = None):
+        """Set a VALUE (second parameter) for an option
+        PATTERN (first parameter).
+
+        An optional third parameter gives the numeric priority
+        (defaults to 80)."""
+        self.tk.call('option', 'add', pattern, value, priority)
+    def option_clear(self):
+        """Clear the option database.
+
+        It will be reloaded if option_add is called."""
+        self.tk.call('option', 'clear')
+    def option_get(self, name, className):
+        """Return the value for an option NAME for this widget
+        with CLASSNAME.
+
+        Values with higher priority override lower values."""
+        return self.tk.call('option', 'get', self._w, name, className)
+    def option_readfile(self, fileName, priority = None):
+        """Read file FILENAME into the option database.
+
+        An optional second parameter gives the numeric
+        priority."""
+        self.tk.call('option', 'readfile', fileName, priority)
+    def selection_clear(self, **kw):
+        """Clear the current X selection."""
+        if not kw.has_key('displayof'): kw['displayof'] = self._w
+        self.tk.call(('selection', 'clear') + self._options(kw))
+    def selection_get(self, **kw):
+        """Return the contents of the current X selection.
+
+        A keyword parameter selection specifies the name of
+        the selection and defaults to PRIMARY.  A keyword
+        parameter displayof specifies a widget on the display
+        to use."""
+        if not kw.has_key('displayof'): kw['displayof'] = self._w
+        return self.tk.call(('selection', 'get') + self._options(kw))
+    def selection_handle(self, command, **kw):
+        """Specify a function COMMAND to call if the X
+        selection owned by this widget is queried by another
+        application.
+
+        This function must return the contents of the
+        selection. The function will be called with the
+        arguments OFFSET and LENGTH which allows the chunking
+        of very long selections. The following keyword
+        parameters can be provided:
+        selection - name of the selection (default PRIMARY),
+        type - type of the selection (e.g. STRING, FILE_NAME)."""
+        name = self._register(command)
+        self.tk.call(('selection', 'handle') + self._options(kw)
+              + (self._w, name))
+    def selection_own(self, **kw):
+        """Become owner of X selection.
+
+        A keyword parameter selection specifies the name of
+        the selection (default PRIMARY)."""
+        self.tk.call(('selection', 'own') +
+                 self._options(kw) + (self._w,))
+    def selection_own_get(self, **kw):
+        """Return owner of X selection.
+
+        The following keyword parameter can
+        be provided:
+        selection - name of the selection (default PRIMARY),
+        type - type of the selection (e.g. STRING, FILE_NAME)."""
+        if not kw.has_key('displayof'): kw['displayof'] = self._w
+        name = self.tk.call(('selection', 'own') + self._options(kw))
+        if not name: return None
+        return self._nametowidget(name)
+    def send(self, interp, cmd, *args):
+        """Send Tcl command CMD to different interpreter INTERP to be executed."""
+        return self.tk.call(('send', interp, cmd) + args)
+    def lower(self, belowThis=None):
+        """Lower this widget in the stacking order."""
+        self.tk.call('lower', self._w, belowThis)
+    def tkraise(self, aboveThis=None):
+        """Raise this widget in the stacking order."""
+        self.tk.call('raise', self._w, aboveThis)
+    lift = tkraise
+    def colormodel(self, value=None):
+        """Useless. Not implemented in Tk."""
+        return self.tk.call('tk', 'colormodel', self._w, value)
+    def winfo_atom(self, name, displayof=0):
+        """Return integer which represents atom NAME."""
+        args = ('winfo', 'atom') + self._displayof(displayof) + (name,)
+        return getint(self.tk.call(args))
+    def winfo_atomname(self, id, displayof=0):
+        """Return name of atom with identifier ID."""
+        args = ('winfo', 'atomname') \
+               + self._displayof(displayof) + (id,)
+        return self.tk.call(args)
+    def winfo_cells(self):
+        """Return number of cells in the colormap for this widget."""
+        return getint(
+            self.tk.call('winfo', 'cells', self._w))
+    def winfo_children(self):
+        """Return a list of all widgets which are children of this widget."""
+        result = []
+        for child in self.tk.splitlist(
+            self.tk.call('winfo', 'children', self._w)):
+            try:
+                # Tcl sometimes returns extra windows, e.g. for
+                # menus; those need to be skipped
+                result.append(self._nametowidget(child))
+            except KeyError:
+                pass
+        return result
+
+    def winfo_class(self):
+        """Return window class name of this widget."""
+        return self.tk.call('winfo', 'class', self._w)
+    def winfo_colormapfull(self):
+        """Return true if at the last color request the colormap was full."""
+        return self.tk.getboolean(
+            self.tk.call('winfo', 'colormapfull', self._w))
+    def winfo_containing(self, rootX, rootY, displayof=0):
+        """Return the widget which is at the root coordinates ROOTX, ROOTY."""
+        args = ('winfo', 'containing') \
+               + self._displayof(displayof) + (rootX, rootY)
+        name = self.tk.call(args)
+        if not name: return None
+        return self._nametowidget(name)
+    def winfo_depth(self):
+        """Return the number of bits per pixel."""
+        return getint(self.tk.call('winfo', 'depth', self._w))
+    def winfo_exists(self):
+        """Return true if this widget exists."""
+        return getint(
+            self.tk.call('winfo', 'exists', self._w))
+    def winfo_fpixels(self, number):
+        """Return the number of pixels for the given distance NUMBER
+        (e.g. "3c") as float."""
+        return getdouble(self.tk.call(
+            'winfo', 'fpixels', self._w, number))
+    def winfo_geometry(self):
+        """Return geometry string for this widget in the form "widthxheight+X+Y"."""
+        return self.tk.call('winfo', 'geometry', self._w)
+    def winfo_height(self):
+        """Return height of this widget."""
+        return getint(
+            self.tk.call('winfo', 'height', self._w))
+    def winfo_id(self):
+        """Return identifier ID for this widget."""
+        return self.tk.getint(
+            self.tk.call('winfo', 'id', self._w))
+    def winfo_interps(self, displayof=0):
+        """Return the name of all Tcl interpreters for this display."""
+        args = ('winfo', 'interps') + self._displayof(displayof)
+        return self.tk.splitlist(self.tk.call(args))
+    def winfo_ismapped(self):
+        """Return true if this widget is mapped."""
+        return getint(
+            self.tk.call('winfo', 'ismapped', self._w))
+    def winfo_manager(self):
+        """Return the window mananger name for this widget."""
+        return self.tk.call('winfo', 'manager', self._w)
+    def winfo_name(self):
+        """Return the name of this widget."""
+        return self.tk.call('winfo', 'name', self._w)
+    def winfo_parent(self):
+        """Return the name of the parent of this widget."""
+        return self.tk.call('winfo', 'parent', self._w)
+    def winfo_pathname(self, id, displayof=0):
+        """Return the pathname of the widget given by ID."""
+        args = ('winfo', 'pathname') \
+               + self._displayof(displayof) + (id,)
+        return self.tk.call(args)
+    def winfo_pixels(self, number):
+        """Rounded integer value of winfo_fpixels."""
+        return getint(
+            self.tk.call('winfo', 'pixels', self._w, number))
+    def winfo_pointerx(self):
+        """Return the x coordinate of the pointer on the root window."""
+        return getint(
+            self.tk.call('winfo', 'pointerx', self._w))
+    def winfo_pointerxy(self):
+        """Return a tuple of x and y coordinates of the pointer on the root window."""
+        return self._getints(
+            self.tk.call('winfo', 'pointerxy', self._w))
+    def winfo_pointery(self):
+        """Return the y coordinate of the pointer on the root window."""
+        return getint(
+            self.tk.call('winfo', 'pointery', self._w))
+    def winfo_reqheight(self):
+        """Return requested height of this widget."""
+        return getint(
+            self.tk.call('winfo', 'reqheight', self._w))
+    def winfo_reqwidth(self):
+        """Return requested width of this widget."""
+        return getint(
+            self.tk.call('winfo', 'reqwidth', self._w))
+    def winfo_rgb(self, color):
+        """Return tuple of decimal values for red, green, blue for
+        COLOR in this widget."""
+        return self._getints(
+            self.tk.call('winfo', 'rgb', self._w, color))
+    def winfo_rootx(self):
+        """Return x coordinate of upper left corner of this widget on the
+        root window."""
+        return getint(
+            self.tk.call('winfo', 'rootx', self._w))
+    def winfo_rooty(self):
+        """Return y coordinate of upper left corner of this widget on the
+        root window."""
+        return getint(
+            self.tk.call('winfo', 'rooty', self._w))
+    def winfo_screen(self):
+        """Return the screen name of this widget."""
+        return self.tk.call('winfo', 'screen', self._w)
+    def winfo_screencells(self):
+        """Return the number of the cells in the colormap of the screen
+        of this widget."""
+        return getint(
+            self.tk.call('winfo', 'screencells', self._w))
+    def winfo_screendepth(self):
+        """Return the number of bits per pixel of the root window of the
+        screen of this widget."""
+        return getint(
+            self.tk.call('winfo', 'screendepth', self._w))
+    def winfo_screenheight(self):
+        """Return the number of pixels of the height of the screen of this widget
+        in pixel."""
+        return getint(
+            self.tk.call('winfo', 'screenheight', self._w))
+    def winfo_screenmmheight(self):
+        """Return the number of pixels of the height of the screen of
+        this widget in mm."""
+        return getint(
+            self.tk.call('winfo', 'screenmmheight', self._w))
+    def winfo_screenmmwidth(self):
+        """Return the number of pixels of the width of the screen of
+        this widget in mm."""
+        return getint(
+            self.tk.call('winfo', 'screenmmwidth', self._w))
+    def winfo_screenvisual(self):
+        """Return one of the strings directcolor, grayscale, pseudocolor,
+        staticcolor, staticgray, or truecolor for the default
+        colormodel of this screen."""
+        return self.tk.call('winfo', 'screenvisual', self._w)
+    def winfo_screenwidth(self):
+        """Return the number of pixels of the width of the screen of
+        this widget in pixel."""
+        return getint(
+            self.tk.call('winfo', 'screenwidth', self._w))
+    def winfo_server(self):
+        """Return information of the X-Server of the screen of this widget in
+        the form "XmajorRminor vendor vendorVersion"."""
+        return self.tk.call('winfo', 'server', self._w)
+    def winfo_toplevel(self):
+        """Return the toplevel widget of this widget."""
+        return self._nametowidget(self.tk.call(
+            'winfo', 'toplevel', self._w))
+    def winfo_viewable(self):
+        """Return true if the widget and all its higher ancestors are mapped."""
+        return getint(
+            self.tk.call('winfo', 'viewable', self._w))
+    def winfo_visual(self):
+        """Return one of the strings directcolor, grayscale, pseudocolor,
+        staticcolor, staticgray, or truecolor for the
+        colormodel of this widget."""
+        return self.tk.call('winfo', 'visual', self._w)
+    def winfo_visualid(self):
+        """Return the X identifier for the visual for this widget."""
+        return self.tk.call('winfo', 'visualid', self._w)
+    def winfo_visualsavailable(self, includeids=0):
+        """Return a list of all visuals available for the screen
+        of this widget.
+
+        Each item in the list consists of a visual name (see winfo_visual), a
+        depth and if INCLUDEIDS=1 is given also the X identifier."""
+        data = self.tk.split(
+            self.tk.call('winfo', 'visualsavailable', self._w,
+                     includeids and 'includeids' or None))
+        if type(data) is StringType:
+            data = [self.tk.split(data)]
+        return map(self.__winfo_parseitem, data)
+    def __winfo_parseitem(self, t):
+        """Internal function."""
+        return t[:1] + tuple(map(self.__winfo_getint, t[1:]))
+    def __winfo_getint(self, x):
+        """Internal function."""
+        return int(x, 0)
+    def winfo_vrootheight(self):
+        """Return the height of the virtual root window associated with this
+        widget in pixels. If there is no virtual root window return the
+        height of the screen."""
+        return getint(
+            self.tk.call('winfo', 'vrootheight', self._w))
+    def winfo_vrootwidth(self):
+        """Return the width of the virtual root window associated with this
+        widget in pixel. If there is no virtual root window return the
+        width of the screen."""
+        return getint(
+            self.tk.call('winfo', 'vrootwidth', self._w))
+    def winfo_vrootx(self):
+        """Return the x offset of the virtual root relative to the root
+        window of the screen of this widget."""
+        return getint(
+            self.tk.call('winfo', 'vrootx', self._w))
+    def winfo_vrooty(self):
+        """Return the y offset of the virtual root relative to the root
+        window of the screen of this widget."""
+        return getint(
+            self.tk.call('winfo', 'vrooty', self._w))
+    def winfo_width(self):
+        """Return the width of this widget."""
+        return getint(
+            self.tk.call('winfo', 'width', self._w))
+    def winfo_x(self):
+        """Return the x coordinate of the upper left corner of this widget
+        in the parent."""
+        return getint(
+            self.tk.call('winfo', 'x', self._w))
+    def winfo_y(self):
+        """Return the y coordinate of the upper left corner of this widget
+        in the parent."""
+        return getint(
+            self.tk.call('winfo', 'y', self._w))
+    def update(self):
+        """Enter event loop until all pending events have been processed by Tcl."""
+        self.tk.call('update')
+    def update_idletasks(self):
+        """Enter event loop until all idle callbacks have been called. This
+        will update the display of windows but not process events caused by
+        the user."""
+        self.tk.call('update', 'idletasks')
+    def bindtags(self, tagList=None):
+        """Set or get the list of bindtags for this widget.
+
+        With no argument return the list of all bindtags associated with
+        this widget. With a list of strings as argument the bindtags are
+        set to this list. The bindtags determine in which order events are
+        processed (see bind)."""
+        if tagList is None:
+            return self.tk.splitlist(
+                self.tk.call('bindtags', self._w))
+        else:
+            self.tk.call('bindtags', self._w, tagList)
+    def _bind(self, what, sequence, func, add, needcleanup=1):
+        """Internal function."""
+        if type(func) is StringType:
+            self.tk.call(what + (sequence, func))
+        elif func:
+            funcid = self._register(func, self._substitute,
+                        needcleanup)
+            cmd = ('%sif {"[%s %s]" == "break"} break\n'
+                   %
+                   (add and '+' or '',
+                funcid, self._subst_format_str))
+            self.tk.call(what + (sequence, cmd))
+            return funcid
+        elif sequence:
+            return self.tk.call(what + (sequence,))
+        else:
+            return self.tk.splitlist(self.tk.call(what))
+    def bind(self, sequence=None, func=None, add=None):
+        """Bind to this widget at event SEQUENCE a call to function FUNC.
+
+        SEQUENCE is a string of concatenated event
+        patterns. An event pattern is of the form
+        <MODIFIER-MODIFIER-TYPE-DETAIL> where MODIFIER is one
+        of Control, Mod2, M2, Shift, Mod3, M3, Lock, Mod4, M4,
+        Button1, B1, Mod5, M5 Button2, B2, Meta, M, Button3,
+        B3, Alt, Button4, B4, Double, Button5, B5 Triple,
+        Mod1, M1. TYPE is one of Activate, Enter, Map,
+        ButtonPress, Button, Expose, Motion, ButtonRelease
+        FocusIn, MouseWheel, Circulate, FocusOut, Property,
+        Colormap, Gravity Reparent, Configure, KeyPress, Key,
+        Unmap, Deactivate, KeyRelease Visibility, Destroy,
+        Leave and DETAIL is the button number for ButtonPress,
+        ButtonRelease and DETAIL is the Keysym for KeyPress and
+        KeyRelease. Examples are
+        <Control-Button-1> for pressing Control and mouse button 1 or
+        <Alt-A> for pressing A and the Alt key (KeyPress can be omitted).
+        An event pattern can also be a virtual event of the form
+        <<AString>> where AString can be arbitrary. This
+        event can be generated by event_generate.
+        If events are concatenated they must appear shortly
+        after each other.
+
+        FUNC will be called if the event sequence occurs with an
+        instance of Event as argument. If the return value of FUNC is
+        "break" no further bound function is invoked.
+
+        An additional boolean parameter ADD specifies whether FUNC will
+        be called additionally to the other bound function or whether
+        it will replace the previous function.
+
+        Bind will return an identifier to allow deletion of the bound function with
+        unbind without memory leak.
+
+        If FUNC or SEQUENCE is omitted the bound function or list
+        of bound events are returned."""
+
+        return self._bind(('bind', self._w), sequence, func, add)
+    def unbind(self, sequence, funcid=None):
+        """Unbind for this widget for event SEQUENCE  the
+        function identified with FUNCID."""
+        self.tk.call('bind', self._w, sequence, '')
+        if funcid:
+            self.deletecommand(funcid)
+    def bind_all(self, sequence=None, func=None, add=None):
+        """Bind to all widgets at an event SEQUENCE a call to function FUNC.
+        An additional boolean parameter ADD specifies whether FUNC will
+        be called additionally to the other bound function or whether
+        it will replace the previous function. See bind for the return value."""
+        return self._bind(('bind', 'all'), sequence, func, add, 0)
+    def unbind_all(self, sequence):
+        """Unbind for all widgets for event SEQUENCE all functions."""
+        self.tk.call('bind', 'all' , sequence, '')
+    def bind_class(self, className, sequence=None, func=None, add=None):
+
+        """Bind to widgets with bindtag CLASSNAME at event
+        SEQUENCE a call of function FUNC. An additional
+        boolean parameter ADD specifies whether FUNC will be
+        called additionally to the other bound function or
+        whether it will replace the previous function. See bind for
+        the return value."""
+
+        return self._bind(('bind', className), sequence, func, add, 0)
+    def unbind_class(self, className, sequence):
+        """Unbind for a all widgets with bindtag CLASSNAME for event SEQUENCE
+        all functions."""
+        self.tk.call('bind', className , sequence, '')
+    def mainloop(self, n=0):
+        """Call the mainloop of Tk."""
+        self.tk.mainloop(n)
+    def quit(self):
+        """Quit the Tcl interpreter. All widgets will be destroyed."""
+        self.tk.quit()
+    def _getints(self, string):
+        """Internal function."""
+        if string:
+            return tuple(map(getint, self.tk.splitlist(string)))
+    def _getdoubles(self, string):
+        """Internal function."""
+        if string:
+            return tuple(map(getdouble, self.tk.splitlist(string)))
+    def _getboolean(self, string):
+        """Internal function."""
+        if string:
+            return self.tk.getboolean(string)
+    def _displayof(self, displayof):
+        """Internal function."""
+        if displayof:
+            return ('-displayof', displayof)
+        if displayof is None:
+            return ('-displayof', self._w)
+        return ()
+    def _options(self, cnf, kw = None):
+        """Internal function."""
+        if kw:
+            cnf = _cnfmerge((cnf, kw))
+        else:
+            cnf = _cnfmerge(cnf)
+        res = ()
+        for k, v in cnf.items():
+            if v is not None:
+                if k[-1] == '_': k = k[:-1]
+                if callable(v):
+                    v = self._register(v)
+                res = res + ('-'+k, v)
+        return res
+    def nametowidget(self, name):
+        """Return the Tkinter instance of a widget identified by
+        its Tcl name NAME."""
+        w = self
+        if name[0] == '.':
+            w = w._root()
+            name = name[1:]
+        while name:
+            i = name.find('.')
+            if i >= 0:
+                name, tail = name[:i], name[i+1:]
+            else:
+                tail = ''
+            w = w.children[name]
+            name = tail
+        return w
+    _nametowidget = nametowidget
+    def _register(self, func, subst=None, needcleanup=1):
+        """Return a newly created Tcl function. If this
+        function is called, the Python function FUNC will
+        be executed. An optional function SUBST can
+        be given which will be executed before FUNC."""
+        f = CallWrapper(func, subst, self).__call__
+        name = repr(id(f))
+        try:
+            func = func.im_func
+        except AttributeError:
+            pass
+        try:
+            name = name + func.__name__
+        except AttributeError:
+            pass
+        self.tk.createcommand(name, f)
+        if needcleanup:
+            if self._tclCommands is None:
+                self._tclCommands = []
+            self._tclCommands.append(name)
+        #print '+ Tkinter created command', name
+        return name
+    register = _register
+    def _root(self):
+        """Internal function."""
+        w = self
+        while w.master: w = w.master
+        return w
+    _subst_format = ('%#', '%b', '%f', '%h', '%k',
+             '%s', '%t', '%w', '%x', '%y',
+             '%A', '%E', '%K', '%N', '%W', '%T', '%X', '%Y', '%D')
+    _subst_format_str = " ".join(_subst_format)
+    def _substitute(self, *args):
+        """Internal function."""
+        if len(args) != len(self._subst_format): return args
+        getboolean = self.tk.getboolean
+
+        getint = int
+        def getint_event(s):
+            """Tk changed behavior in 8.4.2, returning "??" rather more often."""
+            try:
+                return int(s)
+            except ValueError:
+                return s
+
+        nsign, b, f, h, k, s, t, w, x, y, A, E, K, N, W, T, X, Y, D = args
+        # Missing: (a, c, d, m, o, v, B, R)
+        e = Event()
+        # serial field: valid vor all events
+        # number of button: ButtonPress and ButtonRelease events only
+        # height field: Configure, ConfigureRequest, Create,
+        # ResizeRequest, and Expose events only
+        # keycode field: KeyPress and KeyRelease events only
+        # time field: "valid for events that contain a time field"
+        # width field: Configure, ConfigureRequest, Create, ResizeRequest,
+        # and Expose events only
+        # x field: "valid for events that contain a x field"
+        # y field: "valid for events that contain a y field"
+        # keysym as decimal: KeyPress and KeyRelease events only
+        # x_root, y_root fields: ButtonPress, ButtonRelease, KeyPress,
+        # KeyRelease,and Motion events
+        e.serial = getint(nsign)
+        e.num = getint_event(b)
+        try: e.focus = getboolean(f)
+        except TclError: pass
+        e.height = getint_event(h)
+        e.keycode = getint_event(k)
+        e.state = getint_event(s)
+        e.time = getint_event(t)
+        e.width = getint_event(w)
+        e.x = getint_event(x)
+        e.y = getint_event(y)
+        e.char = A
+        try: e.send_event = getboolean(E)
+        except TclError: pass
+        e.keysym = K
+        e.keysym_num = getint_event(N)
+        e.type = T
+        try:
+            e.widget = self._nametowidget(W)
+        except KeyError:
+            e.widget = W
+        e.x_root = getint_event(X)
+        e.y_root = getint_event(Y)
+        try:
+            e.delta = getint(D)
+        except ValueError:
+            e.delta = 0
+        return (e,)
+    def _report_exception(self):
+        """Internal function."""
+        import sys
+        exc, val, tb = sys.exc_type, sys.exc_value, sys.exc_traceback
+        root = self._root()
+        root.report_callback_exception(exc, val, tb)
+    def _configure(self, cmd, cnf, kw):
+        """Internal function."""
+        if kw:
+            cnf = _cnfmerge((cnf, kw))
+        elif cnf:
+            cnf = _cnfmerge(cnf)
+        if cnf is None:
+            cnf = {}
+            for x in self.tk.split(
+                    self.tk.call(_flatten((self._w, cmd)))):
+                cnf[x[0][1:]] = (x[0][1:],) + x[1:]
+            return cnf
+        if type(cnf) is StringType:
+            x = self.tk.split(
+                    self.tk.call(_flatten((self._w, cmd, '-'+cnf))))
+            return (x[0][1:],) + x[1:]
+        self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
+    # These used to be defined in Widget:
+    def configure(self, cnf=None, **kw):
+        """Configure resources of a widget.
+
+        The values for resources are specified as keyword
+        arguments. To get an overview about
+        the allowed keyword arguments call the method keys.
+        """
+        return self._configure('configure', cnf, kw)
+    config = configure
+    def cget(self, key):
+        """Return the resource value for a KEY given as string."""
+        return self.tk.call(self._w, 'cget', '-' + key)
+    __getitem__ = cget
+    def __setitem__(self, key, value):
+        self.configure({key: value})
+    def keys(self):
+        """Return a list of all resource names of this widget."""
+        return map(lambda x: x[0][1:],
+               self.tk.split(self.tk.call(self._w, 'configure')))
+    def __str__(self):
+        """Return the window path name of this widget."""
+        return self._w
+    # Pack methods that apply to the master
+    _noarg_ = ['_noarg_']
+    def pack_propagate(self, flag=_noarg_):
+        """Set or get the status for propagation of geometry information.
+
+        A boolean argument specifies whether the geometry information
+        of the slaves will determine the size of this widget. If no argument
+        is given the current setting will be returned.
+        """
+        if flag is Misc._noarg_:
+            return self._getboolean(self.tk.call(
+                'pack', 'propagate', self._w))
+        else:
+            self.tk.call('pack', 'propagate', self._w, flag)
+    propagate = pack_propagate
+    def pack_slaves(self):
+        """Return a list of all slaves of this widget
+        in its packing order."""
+        return map(self._nametowidget,
+               self.tk.splitlist(
+                   self.tk.call('pack', 'slaves', self._w)))
+    slaves = pack_slaves
+    # Place method that applies to the master
+    def place_slaves(self):
+        """Return a list of all slaves of this widget
+        in its packing order."""
+        return map(self._nametowidget,
+               self.tk.splitlist(
+                   self.tk.call(
+                       'place', 'slaves', self._w)))
+    # Grid methods that apply to the master
+    def grid_bbox(self, column=None, row=None, col2=None, row2=None):
+        """Return a tuple of integer coordinates for the bounding
+        box of this widget controlled by the geometry manager grid.
+
+        If COLUMN, ROW is given the bounding box applies from
+        the cell with row and column 0 to the specified
+        cell. If COL2 and ROW2 are given the bounding box
+        starts at that cell.
+
+        The returned integers specify the offset of the upper left
+        corner in the master widget and the width and height.
+        """
+        args = ('grid', 'bbox', self._w)
+        if column is not None and row is not None:
+            args = args + (column, row)
+        if col2 is not None and row2 is not None:
+            args = args + (col2, row2)
+        return self._getints(self.tk.call(*args)) or None
+
+    bbox = grid_bbox
+    def _grid_configure(self, command, index, cnf, kw):
+        """Internal function."""
+        if type(cnf) is StringType and not kw:
+            if cnf[-1:] == '_':
+                cnf = cnf[:-1]
+            if cnf[:1] != '-':
+                cnf = '-'+cnf
+            options = (cnf,)
+        else:
+            options = self._options(cnf, kw)
+        if not options:
+            res = self.tk.call('grid',
+                       command, self._w, index)
+            words = self.tk.splitlist(res)
+            dict = {}
+            for i in range(0, len(words), 2):
+                key = words[i][1:]
+                value = words[i+1]
+                if not value:
+                    value = None
+                elif '.' in value:
+                    value = getdouble(value)
+                else:
+                    value = getint(value)
+                dict[key] = value
+            return dict
+        res = self.tk.call(
+                  ('grid', command, self._w, index)
+                  + options)
+        if len(options) == 1:
+            if not res: return None
+            # In Tk 7.5, -width can be a float
+            if '.' in res: return getdouble(res)
+            return getint(res)
+    def grid_columnconfigure(self, index, cnf={}, **kw):
+        """Configure column INDEX of a grid.
+
+        Valid resources are minsize (minimum size of the column),
+        weight (how much does additional space propagate to this column)
+        and pad (how much space to let additionally)."""
+        return self._grid_configure('columnconfigure', index, cnf, kw)
+    columnconfigure = grid_columnconfigure
+    def grid_location(self, x, y):
+        """Return a tuple of column and row which identify the cell
+        at which the pixel at position X and Y inside the master
+        widget is located."""
+        return self._getints(
+            self.tk.call(
+                'grid', 'location', self._w, x, y)) or None
+    def grid_propagate(self, flag=_noarg_):
+        """Set or get the status for propagation of geometry information.
+
+        A boolean argument specifies whether the geometry information
+        of the slaves will determine the size of this widget. If no argument
+        is given, the current setting will be returned.
+        """
+        if flag is Misc._noarg_:
+            return self._getboolean(self.tk.call(
+                'grid', 'propagate', self._w))
+        else:
+            self.tk.call('grid', 'propagate', self._w, flag)
+    def grid_rowconfigure(self, index, cnf={}, **kw):
+        """Configure row INDEX of a grid.
+
+        Valid resources are minsize (minimum size of the row),
+        weight (how much does additional space propagate to this row)
+        and pad (how much space to let additionally)."""
+        return self._grid_configure('rowconfigure', index, cnf, kw)
+    rowconfigure = grid_rowconfigure
+    def grid_size(self):
+        """Return a tuple of the number of column and rows in the grid."""
+        return self._getints(
+            self.tk.call('grid', 'size', self._w)) or None
+    size = grid_size
+    def grid_slaves(self, row=None, column=None):
+        """Return a list of all slaves of this widget
+        in its packing order."""
+        args = ()
+        if row is not None:
+            args = args + ('-row', row)
+        if column is not None:
+            args = args + ('-column', column)
+        return map(self._nametowidget,
+               self.tk.splitlist(self.tk.call(
+                   ('grid', 'slaves', self._w) + args)))
+
+    # Support for the "event" command, new in Tk 4.2.
+    # By Case Roole.
+
+    def event_add(self, virtual, *sequences):
+        """Bind a virtual event VIRTUAL (of the form <<Name>>)
+        to an event SEQUENCE such that the virtual event is triggered
+        whenever SEQUENCE occurs."""
+        args = ('event', 'add', virtual) + sequences
+        self.tk.call(args)
+
+    def event_delete(self, virtual, *sequences):
+        """Unbind a virtual event VIRTUAL from SEQUENCE."""
+        args = ('event', 'delete', virtual) + sequences
+        self.tk.call(args)
+
+    def event_generate(self, sequence, **kw):
+        """Generate an event SEQUENCE. Additional
+        keyword arguments specify parameter of the event
+        (e.g. x, y, rootx, rooty)."""
+        args = ('event', 'generate', self._w, sequence)
+        for k, v in kw.items():
+            args = args + ('-%s' % k, str(v))
+        self.tk.call(args)
+
+    def event_info(self, virtual=None):
+        """Return a list of all virtual events or the information
+        about the SEQUENCE bound to the virtual event VIRTUAL."""
+        return self.tk.splitlist(
+            self.tk.call('event', 'info', virtual))
+
+    # Image related commands
+
+    def image_names(self):
+        """Return a list of all existing image names."""
+        return self.tk.call('image', 'names')
+
+    def image_types(self):
+        """Return a list of all available image types (e.g. phote bitmap)."""
+        return self.tk.call('image', 'types')
+
+
+class CallWrapper:
+    """Internal class. Stores function to call when some user
+    defined Tcl function is called e.g. after an event occurred."""
+    def __init__(self, func, subst, widget):
+        """Store FUNC, SUBST and WIDGET as members."""
+        self.func = func
+        self.subst = subst
+        self.widget = widget
+    def __call__(self, *args):
+        """Apply first function SUBST to arguments, than FUNC."""
+        try:
+            if self.subst:
+                args = self.subst(*args)
+            return self.func(*args)
+        except SystemExit, msg:
+            raise SystemExit, msg
+        except:
+            self.widget._report_exception()
+
+
+class Wm:
+    """Provides functions for the communication with the window manager."""
+
+    def wm_aspect(self,
+              minNumer=None, minDenom=None,
+              maxNumer=None, maxDenom=None):
+        """Instruct the window manager to set the aspect ratio (width/height)
+        of this widget to be between MINNUMER/MINDENOM and MAXNUMER/MAXDENOM. Return a tuple
+        of the actual values if no argument is given."""
+        return self._getints(
+            self.tk.call('wm', 'aspect', self._w,
+                     minNumer, minDenom,
+                     maxNumer, maxDenom))
+    aspect = wm_aspect
+
+    def wm_attributes(self, *args):
+        """This subcommand returns or sets platform specific attributes
+
+        The first form returns a list of the platform specific flags and
+        their values. The second form returns the value for the specific
+        option. The third form sets one or more of the values. The values
+        are as follows:
+
+        On Windows, -disabled gets or sets whether the window is in a
+        disabled state. -toolwindow gets or sets the style of the window
+        to toolwindow (as defined in the MSDN). -topmost gets or sets
+        whether this is a topmost window (displays above all other
+        windows).
+
+        On Macintosh, XXXXX
+
+        On Unix, there are currently no special attribute values.
+        """
+        args = ('wm', 'attributes', self._w) + args
+        return self.tk.call(args)
+    attributes=wm_attributes
+
+    def wm_client(self, name=None):
+        """Store NAME in WM_CLIENT_MACHINE property of this widget. Return
+        current value."""
+        return self.tk.call('wm', 'client', self._w, name)
+    client = wm_client
+    def wm_colormapwindows(self, *wlist):
+        """Store list of window names (WLIST) into WM_COLORMAPWINDOWS property
+        of this widget. This list contains windows whose colormaps differ from their
+        parents. Return current list of widgets if WLIST is empty."""
+        if len(wlist) > 1:
+            wlist = (wlist,) # Tk needs a list of windows here
+        args = ('wm', 'colormapwindows', self._w) + wlist
+        return map(self._nametowidget, self.tk.call(args))
+    colormapwindows = wm_colormapwindows
+    def wm_command(self, value=None):
+        """Store VALUE in WM_COMMAND property. It is the command
+        which shall be used to invoke the application. Return current
+        command if VALUE is None."""
+        return self.tk.call('wm', 'command', self._w, value)
+    command = wm_command
+    def wm_deiconify(self):
+        """Deiconify this widget. If it was never mapped it will not be mapped.
+        On Windows it will raise this widget and give it the focus."""
+        return self.tk.call('wm', 'deiconify', self._w)
+    deiconify = wm_deiconify
+    def wm_focusmodel(self, model=None):
+        """Set focus model to MODEL. "active" means that this widget will claim
+        the focus itself, "passive" means that the window manager shall give
+        the focus. Return current focus model if MODEL is None."""
+        return self.tk.call('wm', 'focusmodel', self._w, model)
+    focusmodel = wm_focusmodel
+    def wm_frame(self):
+        """Return identifier for decorative frame of this widget if present."""
+        return self.tk.call('wm', 'frame', self._w)
+    frame = wm_frame
+    def wm_geometry(self, newGeometry=None):
+        """Set geometry to NEWGEOMETRY of the form =widthxheight+x+y. Return
+        current value if None is given."""
+        return self.tk.call('wm', 'geometry', self._w, newGeometry)
+    geometry = wm_geometry
+    def wm_grid(self,
+         baseWidth=None, baseHeight=None,
+         widthInc=None, heightInc=None):
+        """Instruct the window manager that this widget shall only be
+        resized on grid boundaries. WIDTHINC and HEIGHTINC are the width and
+        height of a grid unit in pixels. BASEWIDTH and BASEHEIGHT are the
+        number of grid units requested in Tk_GeometryRequest."""
+        return self._getints(self.tk.call(
+            'wm', 'grid', self._w,
+            baseWidth, baseHeight, widthInc, heightInc))
+    grid = wm_grid
+    def wm_group(self, pathName=None):
+        """Set the group leader widgets for related widgets to PATHNAME. Return
+        the group leader of this widget if None is given."""
+        return self.tk.call('wm', 'group', self._w, pathName)
+    group = wm_group
+    def wm_iconbitmap(self, bitmap=None, default=None):
+        """Set bitmap for the iconified widget to BITMAP. Return
+        the bitmap if None is given.
+
+        Under Windows, the DEFAULT parameter can be used to set the icon
+        for the widget and any descendents that don't have an icon set
+        explicitly.  DEFAULT can be the relative path to a .ico file
+        (example: root.iconbitmap(default='myicon.ico') ).  See Tk
+        documentation for more information."""
+        if default:
+            return self.tk.call('wm', 'iconbitmap', self._w, '-default', default)
+        else:
+            return self.tk.call('wm', 'iconbitmap', self._w, bitmap)
+    iconbitmap = wm_iconbitmap
+    def wm_iconify(self):
+        """Display widget as icon."""
+        return self.tk.call('wm', 'iconify', self._w)
+    iconify = wm_iconify
+    def wm_iconmask(self, bitmap=None):
+        """Set mask for the icon bitmap of this widget. Return the
+        mask if None is given."""
+        return self.tk.call('wm', 'iconmask', self._w, bitmap)
+    iconmask = wm_iconmask
+    def wm_iconname(self, newName=None):
+        """Set the name of the icon for this widget. Return the name if
+        None is given."""
+        return self.tk.call('wm', 'iconname', self._w, newName)
+    iconname = wm_iconname
+    def wm_iconposition(self, x=None, y=None):
+        """Set the position of the icon of this widget to X and Y. Return
+        a tuple of the current values of X and X if None is given."""
+        return self._getints(self.tk.call(
+            'wm', 'iconposition', self._w, x, y))
+    iconposition = wm_iconposition
+    def wm_iconwindow(self, pathName=None):
+        """Set widget PATHNAME to be displayed instead of icon. Return the current
+        value if None is given."""
+        return self.tk.call('wm', 'iconwindow', self._w, pathName)
+    iconwindow = wm_iconwindow
+    def wm_maxsize(self, width=None, height=None):
+        """Set max WIDTH and HEIGHT for this widget. If the window is gridded
+        the values are given in grid units. Return the current values if None
+        is given."""
+        return self._getints(self.tk.call(
+            'wm', 'maxsize', self._w, width, height))
+    maxsize = wm_maxsize
+    def wm_minsize(self, width=None, height=None):
+        """Set min WIDTH and HEIGHT for this widget. If the window is gridded
+        the values are given in grid units. Return the current values if None
+        is given."""
+        return self._getints(self.tk.call(
+            'wm', 'minsize', self._w, width, height))
+    minsize = wm_minsize
+    def wm_overrideredirect(self, boolean=None):
+        """Instruct the window manager to ignore this widget
+        if BOOLEAN is given with 1. Return the current value if None
+        is given."""
+        return self._getboolean(self.tk.call(
+            'wm', 'overrideredirect', self._w, boolean))
+    overrideredirect = wm_overrideredirect
+    def wm_positionfrom(self, who=None):
+        """Instruct the window manager that the position of this widget shall
+        be defined by the user if WHO is "user", and by its own policy if WHO is
+        "program"."""
+        return self.tk.call('wm', 'positionfrom', self._w, who)
+    positionfrom = wm_positionfrom
+    def wm_protocol(self, name=None, func=None):
+        """Bind function FUNC to command NAME for this widget.
+        Return the function bound to NAME if None is given. NAME could be
+        e.g. "WM_SAVE_YOURSELF" or "WM_DELETE_WINDOW"."""
+        if callable(func):
+            command = self._register(func)
+        else:
+            command = func
+        return self.tk.call(
+            'wm', 'protocol', self._w, name, command)
+    protocol = wm_protocol
+    def wm_resizable(self, width=None, height=None):
+        """Instruct the window manager whether this width can be resized
+        in WIDTH or HEIGHT. Both values are boolean values."""
+        return self.tk.call('wm', 'resizable', self._w, width, height)
+    resizable = wm_resizable
+    def wm_sizefrom(self, who=None):
+        """Instruct the window manager that the size of this widget shall
+        be defined by the user if WHO is "user", and by its own policy if WHO is
+        "program"."""
+        return self.tk.call('wm', 'sizefrom', self._w, who)
+    sizefrom = wm_sizefrom
+    def wm_state(self, newstate=None):
+        """Query or set the state of this widget as one of normal, icon,
+        iconic (see wm_iconwindow), withdrawn, or zoomed (Windows only)."""
+        return self.tk.call('wm', 'state', self._w, newstate)
+    state = wm_state
+    def wm_title(self, string=None):
+        """Set the title of this widget."""
+        return self.tk.call('wm', 'title', self._w, string)
+    title = wm_title
+    def wm_transient(self, master=None):
+        """Instruct the window manager that this widget is transient
+        with regard to widget MASTER."""
+        return self.tk.call('wm', 'transient', self._w, master)
+    transient = wm_transient
+    def wm_withdraw(self):
+        """Withdraw this widget from the screen such that it is unmapped
+        and forgotten by the window manager. Re-draw it with wm_deiconify."""
+        return self.tk.call('wm', 'withdraw', self._w)
+    withdraw = wm_withdraw
+
+
+class Tk(Misc, Wm):
+    """Toplevel widget of Tk which represents mostly the main window
+    of an appliation. It has an associated Tcl interpreter."""
+    _w = '.'
+    def __init__(self, screenName=None, baseName=None, className='Tk',
+                 useTk=1, sync=0, use=None):
+        """Return a new Toplevel widget on screen SCREENNAME. A new Tcl interpreter will
+        be created. BASENAME will be used for the identification of the profile file (see
+        readprofile).
+        It is constructed from sys.argv[0] without extensions if None is given. CLASSNAME
+        is the name of the widget class."""
+        self.master = None
+        self.children = {}
+        self._tkloaded = 0
+        # to avoid recursions in the getattr code in case of failure, we
+        # ensure that self.tk is always _something_.
+        self.tk = None
+        if baseName is None:
+            import sys, os
+            baseName = os.path.basename(sys.argv[0])
+            baseName, ext = os.path.splitext(baseName)
+            if ext not in ('.py', '.pyc', '.pyo'):
+                baseName = baseName + ext
+        interactive = 0
+        self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)
+        if useTk:
+            self._loadtk()
+        self.readprofile(baseName, className)
+    def loadtk(self):
+        if not self._tkloaded:
+            self.tk.loadtk()
+            self._loadtk()
+    def _loadtk(self):
+        self._tkloaded = 1
+        global _default_root
+        if _MacOS and hasattr(_MacOS, 'SchedParams'):
+            # Disable event scanning except for Command-Period
+            _MacOS.SchedParams(1, 0)
+            # Work around nasty MacTk bug
+            # XXX Is this one still needed?
+            self.update()
+        # Version sanity checks
+        tk_version = self.tk.getvar('tk_version')
+        if tk_version != _tkinter.TK_VERSION:
+            raise RuntimeError, \
+            "tk.h version (%s) doesn't match libtk.a version (%s)" \
+            % (_tkinter.TK_VERSION, tk_version)
+        # Under unknown circumstances, tcl_version gets coerced to float
+        tcl_version = str(self.tk.getvar('tcl_version'))
+        if tcl_version != _tkinter.TCL_VERSION:
+            raise RuntimeError, \
+            "tcl.h version (%s) doesn't match libtcl.a version (%s)" \
+            % (_tkinter.TCL_VERSION, tcl_version)
+        if TkVersion < 4.0:
+            raise RuntimeError, \
+            "Tk 4.0 or higher is required; found Tk %s" \
+            % str(TkVersion)
+        # Create and register the tkerror and exit commands
+        # We need to inline parts of _register here, _ register
+        # would register differently-named commands.
+        if self._tclCommands is None:
+            self._tclCommands = []
+        self.tk.createcommand('tkerror', _tkerror)
+        self.tk.createcommand('exit', _exit)
+        self._tclCommands.append('tkerror')
+        self._tclCommands.append('exit')
+        if _support_default_root and not _default_root:
+            _default_root = self
+        self.protocol("WM_DELETE_WINDOW", self.destroy)
+    def destroy(self):
+        """Destroy this and all descendants widgets. This will
+        end the application of this Tcl interpreter."""
+        for c in self.children.values(): c.destroy()
+        self.tk.call('destroy', self._w)
+        Misc.destroy(self)
+        global _default_root
+        if _support_default_root and _default_root is self:
+            _default_root = None
+    def readprofile(self, baseName, className):
+        """Internal function. It reads BASENAME.tcl and CLASSNAME.tcl into
+        the Tcl Interpreter and calls execfile on BASENAME.py and CLASSNAME.py if
+        such a file exists in the home directory."""
+        import os
+        if os.environ.has_key('HOME'): home = os.environ['HOME']
+        else: home = os.curdir
+        class_tcl = os.path.join(home, '.%s.tcl' % className)
+        class_py = os.path.join(home, '.%s.py' % className)
+        base_tcl = os.path.join(home, '.%s.tcl' % baseName)
+        base_py = os.path.join(home, '.%s.py' % baseName)
+        dir = {'self': self}
+        exec 'from Tkinter import *' in dir
+        if os.path.isfile(class_tcl):
+            self.tk.call('source', class_tcl)
+        if os.path.isfile(class_py):
+            execfile(class_py, dir)
+        if os.path.isfile(base_tcl):
+            self.tk.call('source', base_tcl)
+        if os.path.isfile(base_py):
+            execfile(base_py, dir)
+    def report_callback_exception(self, exc, val, tb):
+        """Internal function. It reports exception on sys.stderr."""
+        import traceback, sys
+        sys.stderr.write("Exception in Tkinter callback\n")
+        sys.last_type = exc
+        sys.last_value = val
+        sys.last_traceback = tb
+        traceback.print_exception(exc, val, tb)
+    def __getattr__(self, attr):
+        "Delegate attribute access to the interpreter object"
+        return getattr(self.tk, attr)
+
+# Ideally, the classes Pack, Place and Grid disappear, the
+# pack/place/grid methods are defined on the Widget class, and
+# everybody uses w.pack_whatever(...) instead of Pack.whatever(w,
+# ...), with pack(), place() and grid() being short for
+# pack_configure(), place_configure() and grid_columnconfigure(), and
+# forget() being short for pack_forget().  As a practical matter, I'm
+# afraid that there is too much code out there that may be using the
+# Pack, Place or Grid class, so I leave them intact -- but only as
+# backwards compatibility features.  Also note that those methods that
+# take a master as argument (e.g. pack_propagate) have been moved to
+# the Misc class (which now incorporates all methods common between
+# toplevel and interior widgets).  Again, for compatibility, these are
+# copied into the Pack, Place or Grid class.
+
+
+def Tcl(screenName=None, baseName=None, className='Tk', useTk=0):
+    return Tk(screenName, baseName, className, useTk)
+
+class Pack:
+    """Geometry manager Pack.
+
+    Base class to use the methods pack_* in every widget."""
+    def pack_configure(self, cnf={}, **kw):
+        """Pack a widget in the parent widget. Use as options:
+        after=widget - pack it after you have packed widget
+        anchor=NSEW (or subset) - position widget according to
+                                  given direction
+                before=widget - pack it before you will pack widget
+        expand=bool - expand widget if parent size grows
+        fill=NONE or X or Y or BOTH - fill widget if widget grows
+        in=master - use master to contain this widget
+        ipadx=amount - add internal padding in x direction
+        ipady=amount - add internal padding in y direction
+        padx=amount - add padding in x direction
+        pady=amount - add padding in y direction
+        side=TOP or BOTTOM or LEFT or RIGHT -  where to add this widget.
+        """
+        self.tk.call(
+              ('pack', 'configure', self._w)
+              + self._options(cnf, kw))
+    pack = configure = config = pack_configure
+    def pack_forget(self):
+        """Unmap this widget and do not use it for the packing order."""
+        self.tk.call('pack', 'forget', self._w)
+    forget = pack_forget
+    def pack_info(self):
+        """Return information about the packing options
+        for this widget."""
+        words = self.tk.splitlist(
+            self.tk.call('pack', 'info', self._w))
+        dict = {}
+        for i in range(0, len(words), 2):
+            key = words[i][1:]
+            value = words[i+1]
+            if value[:1] == '.':
+                value = self._nametowidget(value)
+            dict[key] = value
+        return dict
+    info = pack_info
+    propagate = pack_propagate = Misc.pack_propagate
+    slaves = pack_slaves = Misc.pack_slaves
+
+class Place:
+    """Geometry manager Place.
+
+    Base class to use the methods place_* in every widget."""
+    def place_configure(self, cnf={}, **kw):
+        """Place a widget in the parent widget. Use as options:
+        in=master - master relative to which the widget is placed.
+        x=amount - locate anchor of this widget at position x of master
+        y=amount - locate anchor of this widget at position y of master
+        relx=amount - locate anchor of this widget between 0.0 and 1.0
+                      relative to width of master (1.0 is right edge)
+            rely=amount - locate anchor of this widget between 0.0 and 1.0
+                      relative to height of master (1.0 is bottom edge)
+            anchor=NSEW (or subset) - position anchor according to given direction
+        width=amount - width of this widget in pixel
+        height=amount - height of this widget in pixel
+        relwidth=amount - width of this widget between 0.0 and 1.0
+                          relative to width of master (1.0 is the same width
+                  as the master)
+            relheight=amount - height of this widget between 0.0 and 1.0
+                           relative to height of master (1.0 is the same
+                   height as the master)
+            bordermode="inside" or "outside" - whether to take border width of master widget
+                                               into account
+            """
+        for k in ['in_']:
+            if kw.has_key(k):
+                kw[k[:-1]] = kw[k]
+                del kw[k]
+        self.tk.call(
+              ('place', 'configure', self._w)
+              + self._options(cnf, kw))
+    place = configure = config = place_configure
+    def place_forget(self):
+        """Unmap this widget."""
+        self.tk.call('place', 'forget', self._w)
+    forget = place_forget
+    def place_info(self):
+        """Return information about the placing options
+        for this widget."""
+        words = self.tk.splitlist(
+            self.tk.call('place', 'info', self._w))
+        dict = {}
+        for i in range(0, len(words), 2):
+            key = words[i][1:]
+            value = words[i+1]
+            if value[:1] == '.':
+                value = self._nametowidget(value)
+            dict[key] = value
+        return dict
+    info = place_info
+    slaves = place_slaves = Misc.place_slaves
+
+class Grid:
+    """Geometry manager Grid.
+
+    Base class to use the methods grid_* in every widget."""
+    # Thanks to Masazumi Yoshikawa (yosikawa at isi.edu)
+    def grid_configure(self, cnf={}, **kw):
+        """Position a widget in the parent widget in a grid. Use as options:
+        column=number - use cell identified with given column (starting with 0)
+        columnspan=number - this widget will span several columns
+        in=master - use master to contain this widget
+        ipadx=amount - add internal padding in x direction
+        ipady=amount - add internal padding in y direction
+        padx=amount - add padding in x direction
+        pady=amount - add padding in y direction
+        row=number - use cell identified with given row (starting with 0)
+        rowspan=number - this widget will span several rows
+        sticky=NSEW - if cell is larger on which sides will this
+                      widget stick to the cell boundary
+        """
+        self.tk.call(
+              ('grid', 'configure', self._w)
+              + self._options(cnf, kw))
+    grid = configure = config = grid_configure
+    bbox = grid_bbox = Misc.grid_bbox
+    columnconfigure = grid_columnconfigure = Misc.grid_columnconfigure
+    def grid_forget(self):
+        """Unmap this widget."""
+        self.tk.call('grid', 'forget', self._w)
+    forget = grid_forget
+    def grid_remove(self):
+        """Unmap this widget but remember the grid options."""
+        self.tk.call('grid', 'remove', self._w)
+    def grid_info(self):
+        """Return information about the options
+        for positioning this widget in a grid."""
+        words = self.tk.splitlist(
+            self.tk.call('grid', 'info', self._w))
+        dict = {}
+        for i in range(0, len(words), 2):
+            key = words[i][1:]
+            value = words[i+1]
+            if value[:1] == '.':
+                value = self._nametowidget(value)
+            dict[key] = value
+        return dict
+    info = grid_info
+    location = grid_location = Misc.grid_location
+    propagate = grid_propagate = Misc.grid_propagate
+    rowconfigure = grid_rowconfigure = Misc.grid_rowconfigure
+    size = grid_size = Misc.grid_size
+    slaves = grid_slaves = Misc.grid_slaves
+
+class BaseWidget(Misc):
+    """Internal class."""
+    def _setup(self, master, cnf):
+        """Internal function. Sets up information about children."""
+        if _support_default_root:
+            global _default_root
+            if not master:
+                if not _default_root:
+                    _default_root = Tk()
+                master = _default_root
+        self.master = master
+        self.tk = master.tk
+        name = None
+        if cnf.has_key('name'):
+            name = cnf['name']
+            del cnf['name']
+        if not name:
+            name = repr(id(self))
+        self._name = name
+        if master._w=='.':
+            self._w = '.' + name
+        else:
+            self._w = master._w + '.' + name
+        self.children = {}
+        if self.master.children.has_key(self._name):
+            self.master.children[self._name].destroy()
+        self.master.children[self._name] = self
+    def __init__(self, master, widgetName, cnf={}, kw={}, extra=()):
+        """Construct a widget with the parent widget MASTER, a name WIDGETNAME
+        and appropriate options."""
+        if kw:
+            cnf = _cnfmerge((cnf, kw))
+        self.widgetName = widgetName
+        BaseWidget._setup(self, master, cnf)
+        classes = []
+        for k in cnf.keys():
+            if type(k) is ClassType:
+                classes.append((k, cnf[k]))
+                del cnf[k]
+        self.tk.call(
+            (widgetName, self._w) + extra + self._options(cnf))
+        for k, v in classes:
+            k.configure(self, v)
+    def destroy(self):
+        """Destroy this and all descendants widgets."""
+        for c in self.children.values(): c.destroy()
+        self.tk.call('destroy', self._w)
+        if self.master.children.has_key(self._name):
+            del self.master.children[self._name]
+        Misc.destroy(self)
+    def _do(self, name, args=()):
+        # XXX Obsolete -- better use self.tk.call directly!
+        return self.tk.call((self._w, name) + args)
+
+class Widget(BaseWidget, Pack, Place, Grid):
+    """Internal class.
+
+    Base class for a widget which can be positioned with the geometry managers
+    Pack, Place or Grid."""
+    pass
+
+class Toplevel(BaseWidget, Wm):
+    """Toplevel widget, e.g. for dialogs."""
+    def __init__(self, master=None, cnf={}, **kw):
+        """Construct a toplevel widget with the parent MASTER.
+
+        Valid resource names: background, bd, bg, borderwidth, class,
+        colormap, container, cursor, height, highlightbackground,
+        highlightcolor, highlightthickness, menu, relief, screen, takefocus,
+        use, visual, width."""
+        if kw:
+            cnf = _cnfmerge((cnf, kw))
+        extra = ()
+        for wmkey in ['screen', 'class_', 'class', 'visual',
+                  'colormap']:
+            if cnf.has_key(wmkey):
+                val = cnf[wmkey]
+                # TBD: a hack needed because some keys
+                # are not valid as keyword arguments
+                if wmkey[-1] == '_': opt = '-'+wmkey[:-1]
+                else: opt = '-'+wmkey
+                extra = extra + (opt, val)
+                del cnf[wmkey]
+        BaseWidget.__init__(self, master, 'toplevel', cnf, {}, extra)
+        root = self._root()
+        self.iconname(root.iconname())
+        self.title(root.title())
+        self.protocol("WM_DELETE_WINDOW", self.destroy)
+
+class Button(Widget):
+    """Button widget."""
+    def __init__(self, master=None, cnf={}, **kw):
+        """Construct a button widget with the parent MASTER.
+
+        STANDARD OPTIONS
+
+            activebackground, activeforeground, anchor,
+            background, bitmap, borderwidth, cursor,
+            disabledforeground, font, foreground
+            highlightbackground, highlightcolor,
+            highlightthickness, image, justify,
+            padx, pady, relief, repeatdelay,
+            repeatinterval, takefocus, text,
+            textvariable, underline, wraplength
+
+        WIDGET-SPECIFIC OPTIONS
+
+            command, compound, default, height,
+            overrelief, state, width
+        """
+        Widget.__init__(self, master, 'button', cnf, kw)
+
+    def tkButtonEnter(self, *dummy):
+        self.tk.call('tkButtonEnter', self._w)
+
+    def tkButtonLeave(self, *dummy):
+        self.tk.call('tkButtonLeave', self._w)
+
+    def tkButtonDown(self, *dummy):
+        self.tk.call('tkButtonDown', self._w)
+
+    def tkButtonUp(self, *dummy):
+        self.tk.call('tkButtonUp', self._w)
+
+    def tkButtonInvoke(self, *dummy):
+        self.tk.call('tkButtonInvoke', self._w)
+
+    def flash(self):
+        """Flash the button.
+
+        This is accomplished by redisplaying
+        the button several times, alternating between active and
+        normal colors. At the end of the flash the button is left
+        in the same normal/active state as when the command was
+        invoked. This command is ignored if the button's state is
+        disabled.
+        """
+        self.tk.call(self._w, 'flash')
+
+    def invoke(self):
+        """Invoke the command associated with the button.
+
+        The return value is the return value from the command,
+        or an empty string if there is no command associated with
+        the button. This command is ignored if the button's state
+        is disabled.
+        """
+        return self.tk.call(self._w, 'invoke')
+
+# Indices:
+# XXX I don't like these -- take them away
+def AtEnd():
+    return 'end'
+def AtInsert(*args):
+    s = 'insert'
+    for a in args:
+        if a: s = s + (' ' + a)
+    return s
+def AtSelFirst():
+    return 'sel.first'
+def AtSelLast():
+    return 'sel.last'
+def At(x, y=None):
+    if y is None:
+        return '@%r' % (x,)
+    else:
+        return '@%r,%r' % (x, y)
+
+class Canvas(Widget):
+    """Canvas widget to display graphical elements like lines or text."""
+    def __init__(self, master=None, cnf={}, **kw):
+        """Construct a canvas widget with the parent MASTER.
+
+        Valid resource names: background, bd, bg, borderwidth, closeenough,
+        confine, cursor, height, highlightbackground, highlightcolor,
+        highlightthickness, insertbackground, insertborderwidth,
+        insertofftime, insertontime, insertwidth, offset, relief,
+        scrollregion, selectbackground, selectborderwidth, selectforeground,
+        state, takefocus, width, xscrollcommand, xscrollincrement,
+        yscrollcommand, yscrollincrement."""
+        Widget.__init__(self, master, 'canvas', cnf, kw)
+    def addtag(self, *args):
+        """Internal function."""
+        self.tk.call((self._w, 'addtag') + args)
+    def addtag_above(self, newtag, tagOrId):
+        """Add tag NEWTAG to all items above TAGORID."""
+        self.addtag(newtag, 'above', tagOrId)
+    def addtag_all(self, newtag):
+        """Add tag NEWTAG to all items."""
+        self.addtag(newtag, 'all')
+    def addtag_below(self, newtag, tagOrId):
+        """Add tag NEWTAG to all items below TAGORID."""
+        self.addtag(newtag, 'below', tagOrId)
+    def addtag_closest(self, newtag, x, y, halo=None, start=None):
+        """Add tag NEWTAG to item which is closest to pixel at X, Y.
+        If several match take the top-most.
+        All items closer than HALO are considered overlapping (all are
+        closests). If START is specified the next below this tag is taken."""
+        self.addtag(newtag, 'closest', x, y, halo, start)
+    def addtag_enclosed(self, newtag, x1, y1, x2, y2):
+        """Add tag NEWTAG to all items in the rectangle defined
+        by X1,Y1,X2,Y2."""
+        self.addtag(newtag, 'enclosed', x1, y1, x2, y2)
+    def addtag_overlapping(self, newtag, x1, y1, x2, y2):
+        """Add tag NEWTAG to all items which overlap the rectangle
+        defined by X1,Y1,X2,Y2."""
+        self.addtag(newtag, 'overlapping', x1, y1, x2, y2)
+    def addtag_withtag(self, newtag, tagOrId):
+        """Add tag NEWTAG to all items with TAGORID."""
+        self.addtag(newtag, 'withtag', tagOrId)
+    def bbox(self, *args):
+        """Return a tuple of X1,Y1,X2,Y2 coordinates for a rectangle
+        which encloses all items with tags specified as arguments."""
+        return self._getints(
+            self.tk.call((self._w, 'bbox') + args)) or None
+    def tag_unbind(self, tagOrId, sequence, funcid=None):
+        """Unbind for all items with TAGORID for event SEQUENCE  the
+        function identified with FUNCID."""
+        self.tk.call(self._w, 'bind', tagOrId, sequence, '')
+        if funcid:
+            self.deletecommand(funcid)
+    def tag_bind(self, tagOrId, sequence=None, func=None, add=None):
+        """Bind to all items with TAGORID at event SEQUENCE a call to function FUNC.
+
+        An additional boolean parameter ADD specifies whether FUNC will be
+        called additionally to the other bound function or whether it will
+        replace the previous function. See bind for the return value."""
+        return self._bind((self._w, 'bind', tagOrId),
+                  sequence, func, add)
+    def canvasx(self, screenx, gridspacing=None):
+        """Return the canvas x coordinate of pixel position SCREENX rounded
+        to nearest multiple of GRIDSPACING units."""
+        return getdouble(self.tk.call(
+            self._w, 'canvasx', screenx, gridspacing))
+    def canvasy(self, screeny, gridspacing=None):
+        """Return the canvas y coordinate of pixel position SCREENY rounded
+        to nearest multiple of GRIDSPACING units."""
+        return getdouble(self.tk.call(
+            self._w, 'canvasy', screeny, gridspacing))
+    def coords(self, *args):
+        """Return a list of coordinates for the item given in ARGS."""
+        # XXX Should use _flatten on args
+        return map(getdouble,
+                           self.tk.splitlist(
+                   self.tk.call((self._w, 'coords') + args)))
+    def _create(self, itemType, args, kw): # Args: (val, val, ..., cnf={})
+        """Internal function."""
+        args = _flatten(args)
+        cnf = args[-1]
+        if type(cnf) in (DictionaryType, TupleType):
+            args = args[:-1]
+        else:
+            cnf = {}
+        return getint(self.tk.call(
+            self._w, 'create', itemType,
+            *(args + self._options(cnf, kw))))
+    def create_arc(self, *args, **kw):
+        """Create arc shaped region with coordinates x1,y1,x2,y2."""
+        return self._create('arc', args, kw)
+    def create_bitmap(self, *args, **kw):
+        """Create bitmap with coordinates x1,y1."""
+        return self._create('bitmap', args, kw)
+    def create_image(self, *args, **kw):
+        """Create image item with coordinates x1,y1."""
+        return self._create('image', args, kw)
+    def create_line(self, *args, **kw):
+        """Create line with coordinates x1,y1,...,xn,yn."""
+        return self._create('line', args, kw)
+    def create_oval(self, *args, **kw):
+        """Create oval with coordinates x1,y1,x2,y2."""
+        return self._create('oval', args, kw)
+    def create_polygon(self, *args, **kw):
+        """Create polygon with coordinates x1,y1,...,xn,yn."""
+        return self._create('polygon', args, kw)
+    def create_rectangle(self, *args, **kw):
+        """Create rectangle with coordinates x1,y1,x2,y2."""
+        return self._create('rectangle', args, kw)
+    def create_text(self, *args, **kw):
+        """Create text with coordinates x1,y1."""
+        return self._create('text', args, kw)
+    def create_window(self, *args, **kw):
+        """Create window with coordinates x1,y1,x2,y2."""
+        return self._create('window', args, kw)
+    def dchars(self, *args):
+        """Delete characters of text items identified by tag or id in ARGS (possibly
+        several times) from FIRST to LAST character (including)."""
+        self.tk.call((self._w, 'dchars') + args)
+    def delete(self, *args):
+        """Delete items identified by all tag or ids contained in ARGS."""
+        self.tk.call((self._w, 'delete') + args)
+    def dtag(self, *args):
+        """Delete tag or id given as last arguments in ARGS from items
+        identified by first argument in ARGS."""
+        self.tk.call((self._w, 'dtag') + args)
+    def find(self, *args):
+        """Internal function."""
+        return self._getints(
+            self.tk.call((self._w, 'find') + args)) or ()
+    def find_above(self, tagOrId):
+        """Return items above TAGORID."""
+        return self.find('above', tagOrId)
+    def find_all(self):
+        """Return all items."""
+        return self.find('all')
+    def find_below(self, tagOrId):
+        """Return all items below TAGORID."""
+        return self.find('below', tagOrId)
+    def find_closest(self, x, y, halo=None, start=None):
+        """Return item which is closest to pixel at X, Y.
+        If several match take the top-most.
+        All items closer than HALO are considered overlapping (all are
+        closests). If START is specified the next below this tag is taken."""
+        return self.find('closest', x, y, halo, start)
+    def find_enclosed(self, x1, y1, x2, y2):
+        """Return all items in rectangle defined
+        by X1,Y1,X2,Y2."""
+        return self.find('enclosed', x1, y1, x2, y2)
+    def find_overlapping(self, x1, y1, x2, y2):
+        """Return all items which overlap the rectangle
+        defined by X1,Y1,X2,Y2."""
+        return self.find('overlapping', x1, y1, x2, y2)
+    def find_withtag(self, tagOrId):
+        """Return all items with TAGORID."""
+        return self.find('withtag', tagOrId)
+    def focus(self, *args):
+        """Set focus to the first item specified in ARGS."""
+        return self.tk.call((self._w, 'focus') + args)
+    def gettags(self, *args):
+        """Return tags associated with the first item specified in ARGS."""
+        return self.tk.splitlist(
+            self.tk.call((self._w, 'gettags') + args))
+    def icursor(self, *args):
+        """Set cursor at position POS in the item identified by TAGORID.
+        In ARGS TAGORID must be first."""
+        self.tk.call((self._w, 'icursor') + args)
+    def index(self, *args):
+        """Return position of cursor as integer in item specified in ARGS."""
+        return getint(self.tk.call((self._w, 'index') + args))
+    def insert(self, *args):
+        """Insert TEXT in item TAGORID at position POS. ARGS must
+        be TAGORID POS TEXT."""
+        self.tk.call((self._w, 'insert') + args)
+    def itemcget(self, tagOrId, option):
+        """Return the resource value for an OPTION for item TAGORID."""
+        return self.tk.call(
+            (self._w, 'itemcget') + (tagOrId, '-'+option))
+    def itemconfigure(self, tagOrId, cnf=None, **kw):
+        """Configure resources of an item TAGORID.
+
+        The values for resources are specified as keyword
+        arguments. To get an overview about
+        the allowed keyword arguments call the method without arguments.
+        """
+        return self._configure(('itemconfigure', tagOrId), cnf, kw)
+    itemconfig = itemconfigure
+    # lower, tkraise/lift hide Misc.lower, Misc.tkraise/lift,
+    # so the preferred name for them is tag_lower, tag_raise
+    # (similar to tag_bind, and similar to the Text widget);
+    # unfortunately can't delete the old ones yet (maybe in 1.6)
+    def tag_lower(self, *args):
+        """Lower an item TAGORID given in ARGS
+        (optional below another item)."""
+        self.tk.call((self._w, 'lower') + args)
+    lower = tag_lower
+    def move(self, *args):
+        """Move an item TAGORID given in ARGS."""
+        self.tk.call((self._w, 'move') + args)
+    def postscript(self, cnf={}, **kw):
+        """Print the contents of the canvas to a postscript
+        file. Valid options: colormap, colormode, file, fontmap,
+        height, pageanchor, pageheight, pagewidth, pagex, pagey,
+        rotate, witdh, x, y."""
+        return self.tk.call((self._w, 'postscript') +
+                    self._options(cnf, kw))
+    def tag_raise(self, *args):
+        """Raise an item TAGORID given in ARGS
+        (optional above another item)."""
+        self.tk.call((self._w, 'raise') + args)
+    lift = tkraise = tag_raise
+    def scale(self, *args):
+        """Scale item TAGORID with XORIGIN, YORIGIN, XSCALE, YSCALE."""
+        self.tk.call((self._w, 'scale') + args)
+    def scan_mark(self, x, y):
+        """Remember the current X, Y coordinates."""
+        self.tk.call(self._w, 'scan', 'mark', x, y)
+    def scan_dragto(self, x, y, gain=10):
+        """Adjust the view of the canvas to GAIN times the
+        difference between X and Y and the coordinates given in
+        scan_mark."""
+        self.tk.call(self._w, 'scan', 'dragto', x, y, gain)
+    def select_adjust(self, tagOrId, index):
+        """Adjust the end of the selection near the cursor of an item TAGORID to index."""
+        self.tk.call(self._w, 'select', 'adjust', tagOrId, index)
+    def select_clear(self):
+        """Clear the selection if it is in this widget."""
+        self.tk.call(self._w, 'select', 'clear')
+    def select_from(self, tagOrId, index):
+        """Set the fixed end of a selection in item TAGORID to INDEX."""
+        self.tk.call(self._w, 'select', 'from', tagOrId, index)
+    def select_item(self):
+        """Return the item which has the selection."""
+        return self.tk.call(self._w, 'select', 'item') or None
+    def select_to(self, tagOrId, index):
+        """Set the variable end of a selection in item TAGORID to INDEX."""
+        self.tk.call(self._w, 'select', 'to', tagOrId, index)
+    def type(self, tagOrId):
+        """Return the type of the item TAGORID."""
+        return self.tk.call(self._w, 'type', tagOrId) or None
+    def xview(self, *args):
+        """Query and change horizontal position of the view."""
+        if not args:
+            return self._getdoubles(self.tk.call(self._w, 'xview'))
+        self.tk.call((self._w, 'xview') + args)
+    def xview_moveto(self, fraction):
+        """Adjusts the view in the window so that FRACTION of the
+        total width of the canvas is off-screen to the left."""
+        self.tk.call(self._w, 'xview', 'moveto', fraction)
+    def xview_scroll(self, number, what):
+        """Shift the x-view according to NUMBER which is measured in "units" or "pages" (WHAT)."""
+        self.tk.call(self._w, 'xview', 'scroll', number, what)
+    def yview(self, *args):
+        """Query and change vertical position of the view."""
+        if not args:
+            return self._getdoubles(self.tk.call(self._w, 'yview'))
+        self.tk.call((self._w, 'yview') + args)
+    def yview_moveto(self, fraction):
+        """Adjusts the view in the window so that FRACTION of the
+        total height of the canvas is off-screen to the top."""
+        self.tk.call(self._w, 'yview', 'moveto', fraction)
+    def yview_scroll(self, number, what):
+        """Shift the y-view according to NUMBER which is measured in "units" or "pages" (WHAT)."""
+        self.tk.call(self._w, 'yview', 'scroll', number, what)
+
+class Checkbutton(Widget):
+    """Checkbutton widget which is either in on- or off-state."""
+    def __init__(self, master=None, cnf={}, **kw):
+        """Construct a checkbutton widget with the parent MASTER.
+
+        Valid resource names: activebackground, activeforeground, anchor,
+        background, bd, bg, bitmap, borderwidth, command, cursor,
+        disabledforeground, fg, font, foreground, height,
+        highlightbackground, highlightcolor, highlightthickness, image,
+        indicatoron, justify, offvalue, onvalue, padx, pady, relief,
+        selectcolor, selectimage, state, takefocus, text, textvariable,
+        underline, variable, width, wraplength."""
+        Widget.__init__(self, master, 'checkbutton', cnf, kw)
+    def deselect(self):
+        """Put the button in off-state."""
+        self.tk.call(self._w, 'deselect')
+    def flash(self):
+        """Flash the button."""
+        self.tk.call(self._w, 'flash')
+    def invoke(self):
+        """Toggle the button and invoke a command if given as resource."""
+        return self.tk.call(self._w, 'invoke')
+    def select(self):
+        """Put the button in on-state."""
+        self.tk.call(self._w, 'select')
+    def toggle(self):
+        """Toggle the button."""
+        self.tk.call(self._w, 'toggle')
+
+class Entry(Widget):
+    """Entry widget which allows to display simple text."""
+    def __init__(self, master=None, cnf={}, **kw):
+        """Construct an entry widget with the parent MASTER.
+
+        Valid resource names: background, bd, bg, borderwidth, cursor,
+        exportselection, fg, font, foreground, highlightbackground,
+        highlightcolor, highlightthickness, insertbackground,
+        insertborderwidth, insertofftime, insertontime, insertwidth,
+        invalidcommand, invcmd, justify, relief, selectbackground,
+        selectborderwidth, selectforeground, show, state, takefocus,
+        textvariable, validate, validatecommand, vcmd, width,
+        xscrollcommand."""
+        Widget.__init__(self, master, 'entry', cnf, kw)
+    def delete(self, first, last=None):
+        """Delete text from FIRST to LAST (not included)."""
+        self.tk.call(self._w, 'delete', first, last)
+    def get(self):
+        """Return the text."""
+        return self.tk.call(self._w, 'get')
+    def icursor(self, index):
+        """Insert cursor at INDEX."""
+        self.tk.call(self._w, 'icursor', index)
+    def index(self, index):
+        """Return position of cursor."""
+        return getint(self.tk.call(
+            self._w, 'index', index))
+    def insert(self, index, string):
+        """Insert STRING at INDEX."""
+        self.tk.call(self._w, 'insert', index, string)
+    def scan_mark(self, x):
+        """Remember the current X, Y coordinates."""
+        self.tk.call(self._w, 'scan', 'mark', x)
+    def scan_dragto(self, x):
+        """Adjust the view of the canvas to 10 times the
+        difference between X and Y and the coordinates given in
+        scan_mark."""
+        self.tk.call(self._w, 'scan', 'dragto', x)
+    def selection_adjust(self, index):
+        """Adjust the end of the selection near the cursor to INDEX."""
+        self.tk.call(self._w, 'selection', 'adjust', index)
+    select_adjust = selection_adjust
+    def selection_clear(self):
+        """Clear the selection if it is in this widget."""
+        self.tk.call(self._w, 'selection', 'clear')
+    select_clear = selection_clear
+    def selection_from(self, index):
+        """Set the fixed end of a selection to INDEX."""
+        self.tk.call(self._w, 'selection', 'from', index)
+    select_from = selection_from
+    def selection_present(self):
+        """Return whether the widget has the selection."""
+        return self.tk.getboolean(
+            self.tk.call(self._w, 'selection', 'present'))
+    select_present = selection_present
+    def selection_range(self, start, end):
+        """Set the selection from START to END (not included)."""
+        self.tk.call(self._w, 'selection', 'range', start, end)
+    select_range = selection_range
+    def selection_to(self, index):
+        """Set the variable end of a selection to INDEX."""
+        self.tk.call(self._w, 'selection', 'to', index)
+    select_to = selection_to
+    def xview(self, index):
+        """Query and change horizontal position of the view."""
+        self.tk.call(self._w, 'xview', index)
+    def xview_moveto(self, fraction):
+        """Adjust the view in the window so that FRACTION of the
+        total width of the entry is off-screen to the left."""
+        self.tk.call(self._w, 'xview', 'moveto', fraction)
+    def xview_scroll(self, number, what):
+        """Shift the x-view according to NUMBER which is measured in "units" or "pages" (WHAT)."""
+        self.tk.call(self._w, 'xview', 'scroll', number, what)
+
+class Frame(Widget):
+    """Frame widget which may contain other widgets and can have a 3D border."""
+    def __init__(self, master=None, cnf={}, **kw):
+        """Construct a frame widget with the parent MASTER.
+
+        Valid resource names: background, bd, bg, borderwidth, class,
+        colormap, container, cursor, height, highlightbackground,
+        highlightcolor, highlightthickness, relief, takefocus, visual, width."""
+        cnf = _cnfmerge((cnf, kw))
+        extra = ()
+        if cnf.has_key('class_'):
+            extra = ('-class', cnf['class_'])
+            del cnf['class_']
+        elif cnf.has_key('class'):
+            extra = ('-class', cnf['class'])
+            del cnf['class']
+        Widget.__init__(self, master, 'frame', cnf, {}, extra)
+
+class Label(Widget):
+    """Label widget which can display text and bitmaps."""
+    def __init__(self, master=None, cnf={}, **kw):
+        """Construct a label widget with the parent MASTER.
+
+        STANDARD OPTIONS
+
+            activebackground, activeforeground, anchor,
+            background, bitmap, borderwidth, cursor,
+            disabledforeground, font, foreground,
+            highlightbackground, highlightcolor,
+            highlightthickness, image, justify,
+            padx, pady, relief, takefocus, text,
+            textvariable, underline, wraplength
+
+        WIDGET-SPECIFIC OPTIONS
+
+            height, state, width
+
+        """
+        Widget.__init__(self, master, 'label', cnf, kw)
+
+class Listbox(Widget):
+    """Listbox widget which can display a list of strings."""
+    def __init__(self, master=None, cnf={}, **kw):
+        """Construct a listbox widget with the parent MASTER.
+
+        Valid resource names: background, bd, bg, borderwidth, cursor,
+        exportselection, fg, font, foreground, height, highlightbackground,
+        highlightcolor, highlightthickness, relief, selectbackground,
+        selectborderwidth, selectforeground, selectmode, setgrid, takefocus,
+        width, xscrollcommand, yscrollcommand, listvariable."""
+        Widget.__init__(self, master, 'listbox', cnf, kw)
+    def activate(self, index):
+        """Activate item identified by INDEX."""
+        self.tk.call(self._w, 'activate', index)
+    def bbox(self, *args):
+        """Return a tuple of X1,Y1,X2,Y2 coordinates for a rectangle
+        which encloses the item identified by index in ARGS."""
+        return self._getints(
+            self.tk.call((self._w, 'bbox') + args)) or None
+    def curselection(self):
+        """Return list of indices of currently selected item."""
+        # XXX Ought to apply self._getints()...
+        return self.tk.splitlist(self.tk.call(
+            self._w, 'curselection'))
+    def delete(self, first, last=None):
+        """Delete items from FIRST to LAST (not included)."""
+        self.tk.call(self._w, 'delete', first, last)
+    def get(self, first, last=None):
+        """Get list of items from FIRST to LAST (not included)."""
+        if last:
+            return self.tk.splitlist(self.tk.call(
+                self._w, 'get', first, last))
+        else:
+            return self.tk.call(self._w, 'get', first)
+    def index(self, index):
+        """Return index of item identified with INDEX."""
+        i = self.tk.call(self._w, 'index', index)
+        if i == 'none': return None
+        return getint(i)
+    def insert(self, index, *elements):
+        """Insert ELEMENTS at INDEX."""
+        self.tk.call((self._w, 'insert', index) + elements)
+    def nearest(self, y):
+        """Get index of item which is nearest to y coordinate Y."""
+        return getint(self.tk.call(
+            self._w, 'nearest', y))
+    def scan_mark(self, x, y):
+        """Remember the current X, Y coordinates."""
+        self.tk.call(self._w, 'scan', 'mark', x, y)
+    def scan_dragto(self, x, y):
+        """Adjust the view of the listbox to 10 times the
+        difference between X and Y and the coordinates given in
+        scan_mark."""
+        self.tk.call(self._w, 'scan', 'dragto', x, y)
+    def see(self, index):
+        """Scroll such that INDEX is visible."""
+        self.tk.call(self._w, 'see', index)
+    def selection_anchor(self, index):
+        """Set the fixed end oft the selection to INDEX."""
+        self.tk.call(self._w, 'selection', 'anchor', index)
+    select_anchor = selection_anchor
+    def selection_clear(self, first, last=None):
+        """Clear the selection from FIRST to LAST (not included)."""
+        self.tk.call(self._w,
+                 'selection', 'clear', first, last)
+    select_clear = selection_clear
+    def selection_includes(self, index):
+        """Return 1 if INDEX is part of the selection."""
+        return self.tk.getboolean(self.tk.call(
+            self._w, 'selection', 'includes', index))
+    select_includes = selection_includes
+    def selection_set(self, first, last=None):
+        """Set the selection from FIRST to LAST (not included) without
+        changing the currently selected elements."""
+        self.tk.call(self._w, 'selection', 'set', first, last)
+    select_set = selection_set
+    def size(self):
+        """Return the number of elements in the listbox."""
+        return getint(self.tk.call(self._w, 'size'))
+    def xview(self, *what):
+        """Query and change horizontal position of the view."""
+        if not what:
+            return self._getdoubles(self.tk.call(self._w, 'xview'))
+        self.tk.call((self._w, 'xview') + what)
+    def xview_moveto(self, fraction):
+        """Adjust the view in the window so that FRACTION of the
+        total width of the entry is off-screen to the left."""
+        self.tk.call(self._w, 'xview', 'moveto', fraction)
+    def xview_scroll(self, number, what):
+        """Shift the x-view according to NUMBER which is measured in "units" or "pages" (WHAT)."""
+        self.tk.call(self._w, 'xview', 'scroll', number, what)
+    def yview(self, *what):
+        """Query and change vertical position of the view."""
+        if not what:
+            return self._getdoubles(self.tk.call(self._w, 'yview'))
+        self.tk.call((self._w, 'yview') + what)
+    def yview_moveto(self, fraction):
+        """Adjust the view in the window so that FRACTION of the
+        total width of the entry is off-screen to the top."""
+        self.tk.call(self._w, 'yview', 'moveto', fraction)
+    def yview_scroll(self, number, what):
+        """Shift the y-view according to NUMBER which is measured in "units" or "pages" (WHAT)."""
+        self.tk.call(self._w, 'yview', 'scroll', number, what)
+    def itemcget(self, index, option):
+        """Return the resource value for an ITEM and an OPTION."""
+        return self.tk.call(
+            (self._w, 'itemcget') + (index, '-'+option))
+    def itemconfigure(self, index, cnf=None, **kw):
+        """Configure resources of an ITEM.
+
+        The values for resources are specified as keyword arguments.
+        To get an overview about the allowed keyword arguments
+        call the method without arguments.
+        Valid resource names: background, bg, foreground, fg,
+        selectbackground, selectforeground."""
+        return self._configure(('itemconfigure', index), cnf, kw)
+    itemconfig = itemconfigure
+
+class Menu(Widget):
+    """Menu widget which allows to display menu bars, pull-down menus and pop-up menus."""
+    def __init__(self, master=None, cnf={}, **kw):
+        """Construct menu widget with the parent MASTER.
+
+        Valid resource names: activebackground, activeborderwidth,
+        activeforeground, background, bd, bg, borderwidth, cursor,
+        disabledforeground, fg, font, foreground, postcommand, relief,
+        selectcolor, takefocus, tearoff, tearoffcommand, title, type."""
+        Widget.__init__(self, master, 'menu', cnf, kw)
+    def tk_bindForTraversal(self):
+        pass # obsolete since Tk 4.0
+    def tk_mbPost(self):
+        self.tk.call('tk_mbPost', self._w)
+    def tk_mbUnpost(self):
+        self.tk.call('tk_mbUnpost')
+    def tk_traverseToMenu(self, char):
+        self.tk.call('tk_traverseToMenu', self._w, char)
+    def tk_traverseWithinMenu(self, char):
+        self.tk.call('tk_traverseWithinMenu', self._w, char)
+    def tk_getMenuButtons(self):
+        return self.tk.call('tk_getMenuButtons', self._w)
+    def tk_nextMenu(self, count):
+        self.tk.call('tk_nextMenu', count)
+    def tk_nextMenuEntry(self, count):
+        self.tk.call('tk_nextMenuEntry', count)
+    def tk_invokeMenu(self):
+        self.tk.call('tk_invokeMenu', self._w)
+    def tk_firstMenu(self):
+        self.tk.call('tk_firstMenu', self._w)
+    def tk_mbButtonDown(self):
+        self.tk.call('tk_mbButtonDown', self._w)
+    def tk_popup(self, x, y, entry=""):
+        """Post the menu at position X,Y with entry ENTRY."""
+        self.tk.call('tk_popup', self._w, x, y, entry)
+    def activate(self, index):
+        """Activate entry at INDEX."""
+        self.tk.call(self._w, 'activate', index)
+    def add(self, itemType, cnf={}, **kw):
+        """Internal function."""
+        self.tk.call((self._w, 'add', itemType) +
+                 self._options(cnf, kw))
+    def add_cascade(self, cnf={}, **kw):
+        """Add hierarchical menu item."""
+        self.add('cascade', cnf or kw)
+    def add_checkbutton(self, cnf={}, **kw):
+        """Add checkbutton menu item."""
+        self.add('checkbutton', cnf or kw)
+    def add_command(self, cnf={}, **kw):
+        """Add command menu item."""
+        self.add('command', cnf or kw)
+    def add_radiobutton(self, cnf={}, **kw):
+        """Addd radio menu item."""
+        self.add('radiobutton', cnf or kw)
+    def add_separator(self, cnf={}, **kw):
+        """Add separator."""
+        self.add('separator', cnf or kw)
+    def insert(self, index, itemType, cnf={}, **kw):
+        """Internal function."""
+        self.tk.call((self._w, 'insert', index, itemType) +
+                 self._options(cnf, kw))
+    def insert_cascade(self, index, cnf={}, **kw):
+        """Add hierarchical menu item at INDEX."""
+        self.insert(index, 'cascade', cnf or kw)
+    def insert_checkbutton(self, index, cnf={}, **kw):
+        """Add checkbutton menu item at INDEX."""
+        self.insert(index, 'checkbutton', cnf or kw)
+    def insert_command(self, index, cnf={}, **kw):
+        """Add command menu item at INDEX."""
+        self.insert(index, 'command', cnf or kw)
+    def insert_radiobutton(self, index, cnf={}, **kw):
+        """Addd radio menu item at INDEX."""
+        self.insert(index, 'radiobutton', cnf or kw)
+    def insert_separator(self, index, cnf={}, **kw):
+        """Add separator at INDEX."""
+        self.insert(index, 'separator', cnf or kw)
+    def delete(self, index1, index2=None):
+        """Delete menu items between INDEX1 and INDEX2 (not included)."""
+        self.tk.call(self._w, 'delete', index1, index2)
+    def entrycget(self, index, option):
+        """Return the resource value of an menu item for OPTION at INDEX."""
+        return self.tk.call(self._w, 'entrycget', index, '-' + option)
+    def entryconfigure(self, index, cnf=None, **kw):
+        """Configure a menu item at INDEX."""
+        return self._configure(('entryconfigure', index), cnf, kw)
+    entryconfig = entryconfigure
+    def index(self, index):
+        """Return the index of a menu item identified by INDEX."""
+        i = self.tk.call(self._w, 'index', index)
+        if i == 'none': return None
+        return getint(i)
+    def invoke(self, index):
+        """Invoke a menu item identified by INDEX and execute
+        the associated command."""
+        return self.tk.call(self._w, 'invoke', index)
+    def post(self, x, y):
+        """Display a menu at position X,Y."""
+        self.tk.call(self._w, 'post', x, y)
+    def type(self, index):
+        """Return the type of the menu item at INDEX."""
+        return self.tk.call(self._w, 'type', index)
+    def unpost(self):
+        """Unmap a menu."""
+        self.tk.call(self._w, 'unpost')
+    def yposition(self, index):
+        """Return the y-position of the topmost pixel of the menu item at INDEX."""
+        return getint(self.tk.call(
+            self._w, 'yposition', index))
+
+class Menubutton(Widget):
+    """Menubutton widget, obsolete since Tk8.0."""
+    def __init__(self, master=None, cnf={}, **kw):
+        Widget.__init__(self, master, 'menubutton', cnf, kw)
+
+class Message(Widget):
+    """Message widget to display multiline text. Obsolete since Label does it too."""
+    def __init__(self, master=None, cnf={}, **kw):
+        Widget.__init__(self, master, 'message', cnf, kw)
+
+class Radiobutton(Widget):
+    """Radiobutton widget which shows only one of several buttons in on-state."""
+    def __init__(self, master=None, cnf={}, **kw):
+        """Construct a radiobutton widget with the parent MASTER.
+
+        Valid resource names: activebackground, activeforeground, anchor,
+        background, bd, bg, bitmap, borderwidth, command, cursor,
+        disabledforeground, fg, font, foreground, height,
+        highlightbackground, highlightcolor, highlightthickness, image,
+        indicatoron, justify, padx, pady, relief, selectcolor, selectimage,
+        state, takefocus, text, textvariable, underline, value, variable,
+        width, wraplength."""
+        Widget.__init__(self, master, 'radiobutton', cnf, kw)
+    def deselect(self):
+        """Put the button in off-state."""
+
+        self.tk.call(self._w, 'deselect')
+    def flash(self):
+        """Flash the button."""
+        self.tk.call(self._w, 'flash')
+    def invoke(self):
+        """Toggle the button and invoke a command if given as resource."""
+        return self.tk.call(self._w, 'invoke')
+    def select(self):
+        """Put the button in on-state."""
+        self.tk.call(self._w, 'select')
+
+class Scale(Widget):
+    """Scale widget which can display a numerical scale."""
+    def __init__(self, master=None, cnf={}, **kw):
+        """Construct a scale widget with the parent MASTER.
+
+        Valid resource names: activebackground, background, bigincrement, bd,
+        bg, borderwidth, command, cursor, digits, fg, font, foreground, from,
+        highlightbackground, highlightcolor, highlightthickness, label,
+        length, orient, relief, repeatdelay, repeatinterval, resolution,
+        showvalue, sliderlength, sliderrelief, state, takefocus,
+        tickinterval, to, troughcolor, variable, width."""
+        Widget.__init__(self, master, 'scale', cnf, kw)
+    def get(self):
+        """Get the current value as integer or float."""
+        value = self.tk.call(self._w, 'get')
+        try:
+            return getint(value)
+        except ValueError:
+            return getdouble(value)
+    def set(self, value):
+        """Set the value to VALUE."""
+        self.tk.call(self._w, 'set', value)
+    def coords(self, value=None):
+        """Return a tuple (X,Y) of the point along the centerline of the
+        trough that corresponds to VALUE or the current value if None is
+        given."""
+
+        return self._getints(self.tk.call(self._w, 'coords', value))
+    def identify(self, x, y):
+        """Return where the point X,Y lies. Valid return values are "slider",
+        "though1" and "though2"."""
+        return self.tk.call(self._w, 'identify', x, y)
+
+class Scrollbar(Widget):
+    """Scrollbar widget which displays a slider at a certain position."""
+    def __init__(self, master=None, cnf={}, **kw):
+        """Construct a scrollbar widget with the parent MASTER.
+
+        Valid resource names: activebackground, activerelief,
+        background, bd, bg, borderwidth, command, cursor,
+        elementborderwidth, highlightbackground,
+        highlightcolor, highlightthickness, jump, orient,
+        relief, repeatdelay, repeatinterval, takefocus,
+        troughcolor, width."""
+        Widget.__init__(self, master, 'scrollbar', cnf, kw)
+    def activate(self, index):
+        """Display the element at INDEX with activebackground and activerelief.
+        INDEX can be "arrow1","slider" or "arrow2"."""
+        self.tk.call(self._w, 'activate', index)
+    def delta(self, deltax, deltay):
+        """Return the fractional change of the scrollbar setting if it
+        would be moved by DELTAX or DELTAY pixels."""
+        return getdouble(
+            self.tk.call(self._w, 'delta', deltax, deltay))
+    def fraction(self, x, y):
+        """Return the fractional value which corresponds to a slider
+        position of X,Y."""
+        return getdouble(self.tk.call(self._w, 'fraction', x, y))
+    def identify(self, x, y):
+        """Return the element under position X,Y as one of
+        "arrow1","slider","arrow2" or ""."""
+        return self.tk.call(self._w, 'identify', x, y)
+    def get(self):
+        """Return the current fractional values (upper and lower end)
+        of the slider position."""
+        return self._getdoubles(self.tk.call(self._w, 'get'))
+    def set(self, *args):
+        """Set the fractional values of the slider position (upper and
+        lower ends as value between 0 and 1)."""
+        self.tk.call((self._w, 'set') + args)
+
+
+
+class Text(Widget):
+    """Text widget which can display text in various forms."""
+    def __init__(self, master=None, cnf={}, **kw):
+        """Construct a text widget with the parent MASTER.
+
+        STANDARD OPTIONS
+
+            background, borderwidth, cursor,
+            exportselection, font, foreground,
+            highlightbackground, highlightcolor,
+            highlightthickness, insertbackground,
+            insertborderwidth, insertofftime,
+            insertontime, insertwidth, padx, pady,
+            relief, selectbackground,
+            selectborderwidth, selectforeground,
+            setgrid, takefocus,
+            xscrollcommand, yscrollcommand,
+
+        WIDGET-SPECIFIC OPTIONS
+
+            autoseparators, height, maxundo,
+            spacing1, spacing2, spacing3,
+            state, tabs, undo, width, wrap,
+
+        """
+        Widget.__init__(self, master, 'text', cnf, kw)
+    def bbox(self, *args):
+        """Return a tuple of (x,y,width,height) which gives the bounding
+        box of the visible part of the character at the index in ARGS."""
+        return self._getints(
+            self.tk.call((self._w, 'bbox') + args)) or None
+    def tk_textSelectTo(self, index):
+        self.tk.call('tk_textSelectTo', self._w, index)
+    def tk_textBackspace(self):
+        self.tk.call('tk_textBackspace', self._w)
+    def tk_textIndexCloser(self, a, b, c):
+        self.tk.call('tk_textIndexCloser', self._w, a, b, c)
+    def tk_textResetAnchor(self, index):
+        self.tk.call('tk_textResetAnchor', self._w, index)
+    def compare(self, index1, op, index2):
+        """Return whether between index INDEX1 and index INDEX2 the
+        relation OP is satisfied. OP is one of <, <=, ==, >=, >, or !=."""
+        return self.tk.getboolean(self.tk.call(
+            self._w, 'compare', index1, op, index2))
+    def debug(self, boolean=None):
+        """Turn on the internal consistency checks of the B-Tree inside the text
+        widget according to BOOLEAN."""
+        return self.tk.getboolean(self.tk.call(
+            self._w, 'debug', boolean))
+    def delete(self, index1, index2=None):
+        """Delete the characters between INDEX1 and INDEX2 (not included)."""
+        self.tk.call(self._w, 'delete', index1, index2)
+    def dlineinfo(self, index):
+        """Return tuple (x,y,width,height,baseline) giving the bounding box
+        and baseline position of the visible part of the line containing
+        the character at INDEX."""
+        return self._getints(self.tk.call(self._w, 'dlineinfo', index))
+    def dump(self, index1, index2=None, command=None, **kw):
+        """Return the contents of the widget between index1 and index2.
+
+        The type of contents returned in filtered based on the keyword
+        parameters; if 'all', 'image', 'mark', 'tag', 'text', or 'window' are
+        given and true, then the corresponding items are returned. The result
+        is a list of triples of the form (key, value, index). If none of the
+        keywords are true then 'all' is used by default.
+
+        If the 'command' argument is given, it is called once for each element
+        of the list of triples, with the values of each triple serving as the
+        arguments to the function. In this case the list is not returned."""
+        args = []
+        func_name = None
+        result = None
+        if not command:
+            # Never call the dump command without the -command flag, since the
+            # output could involve Tcl quoting and would be a pain to parse
+            # right. Instead just set the command to build a list of triples
+            # as if we had done the parsing.
+            result = []
+            def append_triple(key, value, index, result=result):
+                result.append((key, value, index))
+            command = append_triple
+        try:
+            if not isinstance(command, str):
+                func_name = command = self._register(command)
+            args += ["-command", command]
+            for key in kw:
+                if kw[key]: args.append("-" + key)
+            args.append(index1)
+            if index2:
+                args.append(index2)
+            self.tk.call(self._w, "dump", *args)
+            return result
+        finally:
+            if func_name:
+                self.deletecommand(func_name)
+
+    ## new in tk8.4
+    def edit(self, *args):
+        """Internal method
+
+        This method controls the undo mechanism and
+        the modified flag. The exact behavior of the
+        command depends on the option argument that
+        follows the edit argument. The following forms
+        of the command are currently supported:
+
+        edit_modified, edit_redo, edit_reset, edit_separator
+        and edit_undo
+
+        """
+        return self._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
+        modified flag of the widget to arg.
+        """
+        return self.edit("modified", arg)
+
+    def edit_redo(self):
+        """Redo the last undone edit
+
+        When the undo option is true, reapplies the last
+        undone edits provided no other edits were done since
+        then. Generates an error when the redo stack is empty.
+        Does nothing when the undo option is false.
+        """
+        return self.edit("redo")
+
+    def edit_reset(self):
+        """Clears the undo and redo stacks
+        """
+        return self.edit("reset")
+
+    def edit_separator(self):
+        """Inserts a separator (boundary) on the undo stack.
+
+        Does nothing when the undo option is false
+        """
+        return self.edit("separator")
+
+    def edit_undo(self):
+        """Undoes the last edit action
+
+        If the undo option is true. An edit action is defined
+        as all the insert and delete commands that are recorded
+        on the undo stack in between two separators. Generates
+        an error when the undo stack is empty. Does nothing
+        when the undo option is false
+        """
+        return self.edit("undo")
+
+    def get(self, index1, index2=None):
+        """Return the text from INDEX1 to INDEX2 (not included)."""
+        return self.tk.call(self._w, 'get', index1, index2)
+    # (Image commands are new in 8.0)
+    def image_cget(self, index, option):
+        """Return the value of OPTION of an embedded image at INDEX."""
+        if option[:1] != "-":
+            option = "-" + option
+        if option[-1:] == "_":
+            option = option[:-1]
+        return self.tk.call(self._w, "image", "cget", index, option)
+    def image_configure(self, index, cnf=None, **kw):
+        """Configure an embedded image at INDEX."""
+        return self._configure(('image', 'configure', index), cnf, kw)
+    def image_create(self, index, cnf={}, **kw):
+        """Create an embedded image at INDEX."""
+        return self.tk.call(
+                 self._w, "image", "create", index,
+                 *self._options(cnf, kw))
+    def image_names(self):
+        """Return all names of embedded images in this widget."""
+        return self.tk.call(self._w, "image", "names")
+    def index(self, index):
+        """Return the index in the form line.char for INDEX."""
+        return self.tk.call(self._w, 'index', index)
+    def insert(self, index, chars, *args):
+        """Insert CHARS before the characters at INDEX. An additional
+        tag can be given in ARGS. Additional CHARS and tags can follow in ARGS."""
+        self.tk.call((self._w, 'insert', index, chars) + args)
+    def mark_gravity(self, markName, direction=None):
+        """Change the gravity of a mark MARKNAME to DIRECTION (LEFT or RIGHT).
+        Return the current value if None is given for DIRECTION."""
+        return self.tk.call(
+            (self._w, 'mark', 'gravity', markName, direction))
+    def mark_names(self):
+        """Return all mark names."""
+        return self.tk.splitlist(self.tk.call(
+            self._w, 'mark', 'names'))
+    def mark_set(self, markName, index):
+        """Set mark MARKNAME before the character at INDEX."""
+        self.tk.call(self._w, 'mark', 'set', markName, index)
+    def mark_unset(self, *markNames):
+        """Delete all marks in MARKNAMES."""
+        self.tk.call((self._w, 'mark', 'unset') + markNames)
+    def mark_next(self, index):
+        """Return the name of the next mark after INDEX."""
+        return self.tk.call(self._w, 'mark', 'next', index) or None
+    def mark_previous(self, index):
+        """Return the name of the previous mark before INDEX."""
+        return self.tk.call(self._w, 'mark', 'previous', index) or None
+    def scan_mark(self, x, y):
+        """Remember the current X, Y coordinates."""
+        self.tk.call(self._w, 'scan', 'mark', x, y)
+    def scan_dragto(self, x, y):
+        """Adjust the view of the text to 10 times the
+        difference between X and Y and the coordinates given in
+        scan_mark."""
+        self.tk.call(self._w, 'scan', 'dragto', x, y)
+    def search(self, pattern, index, stopindex=None,
+           forwards=None, backwards=None, exact=None,
+           regexp=None, nocase=None, count=None):
+        """Search PATTERN beginning from INDEX until STOPINDEX.
+        Return the index of the first character of a match or an empty string."""
+        args = [self._w, 'search']
+        if forwards: args.append('-forwards')
+        if backwards: args.append('-backwards')
+        if exact: args.append('-exact')
+        if regexp: args.append('-regexp')
+        if nocase: args.append('-nocase')
+        if count: args.append('-count'); args.append(count)
+        if pattern[0] == '-': args.append('--')
+        args.append(pattern)
+        args.append(index)
+        if stopindex: args.append(stopindex)
+        return self.tk.call(tuple(args))
+    def see(self, index):
+        """Scroll such that the character at INDEX is visible."""
+        self.tk.call(self._w, 'see', index)
+    def tag_add(self, tagName, index1, *args):
+        """Add tag TAGNAME to all characters between INDEX1 and index2 in ARGS.
+        Additional pairs of indices may follow in ARGS."""
+        self.tk.call(
+            (self._w, 'tag', 'add', tagName, index1) + args)
+    def tag_unbind(self, tagName, sequence, funcid=None):
+        """Unbind for all characters with TAGNAME for event SEQUENCE  the
+        function identified with FUNCID."""
+        self.tk.call(self._w, 'tag', 'bind', tagName, sequence, '')
+        if funcid:
+            self.deletecommand(funcid)
+    def tag_bind(self, tagName, sequence, func, add=None):
+        """Bind to all characters with TAGNAME at event SEQUENCE a call to function FUNC.
+
+        An additional boolean parameter ADD specifies whether FUNC will be
+        called additionally to the other bound function or whether it will
+        replace the previous function. See bind for the return value."""
+        return self._bind((self._w, 'tag', 'bind', tagName),
+                  sequence, func, add)
+    def tag_cget(self, tagName, option):
+        """Return the value of OPTION for tag TAGNAME."""
+        if option[:1] != '-':
+            option = '-' + option
+        if option[-1:] == '_':
+            option = option[:-1]
+        return self.tk.call(self._w, 'tag', 'cget', tagName, option)
+    def tag_configure(self, tagName, cnf=None, **kw):
+        """Configure a tag TAGNAME."""
+        return self._configure(('tag', 'configure', tagName), cnf, kw)
+    tag_config = tag_configure
+    def tag_delete(self, *tagNames):
+        """Delete all tags in TAGNAMES."""
+        self.tk.call((self._w, 'tag', 'delete') + tagNames)
+    def tag_lower(self, tagName, belowThis=None):
+        """Change the priority of tag TAGNAME such that it is lower
+        than the priority of BELOWTHIS."""
+        self.tk.call(self._w, 'tag', 'lower', tagName, belowThis)
+    def tag_names(self, index=None):
+        """Return a list of all tag names."""
+        return self.tk.splitlist(
+            self.tk.call(self._w, 'tag', 'names', index))
+    def tag_nextrange(self, tagName, index1, index2=None):
+        """Return a list of start and end index for the first sequence of
+        characters between INDEX1 and INDEX2 which all have tag TAGNAME.
+        The text is searched forward from INDEX1."""
+        return self.tk.splitlist(self.tk.call(
+            self._w, 'tag', 'nextrange', tagName, index1, index2))
+    def tag_prevrange(self, tagName, index1, index2=None):
+        """Return a list of start and end index for the first sequence of
+        characters between INDEX1 and INDEX2 which all have tag TAGNAME.
+        The text is searched backwards from INDEX1."""
+        return self.tk.splitlist(self.tk.call(
+            self._w, 'tag', 'prevrange', tagName, index1, index2))
+    def tag_raise(self, tagName, aboveThis=None):
+        """Change the priority of tag TAGNAME such that it is higher
+        than the priority of ABOVETHIS."""
+        self.tk.call(
+            self._w, 'tag', 'raise', tagName, aboveThis)
+    def tag_ranges(self, tagName):
+        """Return a list of ranges of text which have tag TAGNAME."""
+        return self.tk.splitlist(self.tk.call(
+            self._w, 'tag', 'ranges', tagName))
+    def tag_remove(self, tagName, index1, index2=None):
+        """Remove tag TAGNAME from all characters between INDEX1 and INDEX2."""
+        self.tk.call(
+            self._w, 'tag', 'remove', tagName, index1, index2)
+    def window_cget(self, index, option):
+        """Return the value of OPTION of an embedded window at INDEX."""
+        if option[:1] != '-':
+            option = '-' + option
+        if option[-1:] == '_':
+            option = option[:-1]
+        return self.tk.call(self._w, 'window', 'cget', index, option)
+    def window_configure(self, index, cnf=None, **kw):
+        """Configure an embedded window at INDEX."""
+        return self._configure(('window', 'configure', index), cnf, kw)
+    window_config = window_configure
+    def window_create(self, index, cnf={}, **kw):
+        """Create a window at INDEX."""
+        self.tk.call(
+              (self._w, 'window', 'create', index)
+              + self._options(cnf, kw))
+    def window_names(self):
+        """Return all names of embedded windows in this widget."""
+        return self.tk.splitlist(
+            self.tk.call(self._w, 'window', 'names'))
+    def xview(self, *what):
+        """Query and change horizontal position of the view."""
+        if not what:
+            return self._getdoubles(self.tk.call(self._w, 'xview'))
+        self.tk.call((self._w, 'xview') + what)
+    def xview_moveto(self, fraction):
+        """Adjusts the view in the window so that FRACTION of the
+        total width of the canvas is off-screen to the left."""
+        self.tk.call(self._w, 'xview', 'moveto', fraction)
+    def xview_scroll(self, number, what):
+        """Shift the x-view according to NUMBER which is measured
+        in "units" or "pages" (WHAT)."""
+        self.tk.call(self._w, 'xview', 'scroll', number, what)
+    def yview(self, *what):
+        """Query and change vertical position of the view."""
+        if not what:
+            return self._getdoubles(self.tk.call(self._w, 'yview'))
+        self.tk.call((self._w, 'yview') + what)
+    def yview_moveto(self, fraction):
+        """Adjusts the view in the window so that FRACTION of the
+        total height of the canvas is off-screen to the top."""
+        self.tk.call(self._w, 'yview', 'moveto', fraction)
+    def yview_scroll(self, number, what):
+        """Shift the y-view according to NUMBER which is measured
+        in "units" or "pages" (WHAT)."""
+        self.tk.call(self._w, 'yview', 'scroll', number, what)
+    def yview_pickplace(self, *what):
+        """Obsolete function, use see."""
+        self.tk.call((self._w, 'yview', '-pickplace') + what)
+
+
+class _setit:
+    """Internal class. It wraps the command in the widget OptionMenu."""
+    def __init__(self, var, value, callback=None):
+        self.__value = value
+        self.__var = var
+        self.__callback = callback
+    def __call__(self, *args):
+        self.__var.set(self.__value)
+        if self.__callback:
+            self.__callback(self.__value, *args)
+
+class OptionMenu(Menubutton):
+    """OptionMenu which allows the user to select a value from a menu."""
+    def __init__(self, master, variable, value, *values, **kwargs):
+        """Construct an optionmenu widget with the parent MASTER, with
+        the resource textvariable set to VARIABLE, the initially selected
+        value VALUE, the other menu values VALUES and an additional
+        keyword argument command."""
+        kw = {"borderwidth": 2, "textvariable": variable,
+              "indicatoron": 1, "relief": RAISED, "anchor": "c",
+              "highlightthickness": 2}
+        Widget.__init__(self, master, "menubutton", kw)
+        self.widgetName = 'tk_optionMenu'
+        menu = self.__menu = Menu(self, name="menu", tearoff=0)
+        self.menuname = menu._w
+        # 'command' is the only supported keyword
+        callback = kwargs.get('command')
+        if kwargs.has_key('command'):
+            del kwargs['command']
+        if kwargs:
+            raise TclError, 'unknown option -'+kwargs.keys()[0]
+        menu.add_command(label=value,
+                 command=_setit(variable, value, callback))
+        for v in values:
+            menu.add_command(label=v,
+                     command=_setit(variable, v, callback))
+        self["menu"] = menu
+
+    def __getitem__(self, name):
+        if name == 'menu':
+            return self.__menu
+        return Widget.__getitem__(self, name)
+
+    def destroy(self):
+        """Destroy this widget and the associated menu."""
+        Menubutton.destroy(self)
+        self.__menu = None
+
+class Image:
+    """Base class for images."""
+    _last_id = 0
+    def __init__(self, imgtype, name=None, cnf={}, master=None, **kw):
+        self.name = None
+        if not master:
+            master = _default_root
+            if not master:
+                raise RuntimeError, 'Too early to create image'
+        self.tk = master.tk
+        if not name:
+            Image._last_id += 1
+            name = "pyimage%r" % (Image._last_id,) # tk itself would use image<x>
+            # The following is needed for systems where id(x)
+            # can return a negative number, such as Linux/m68k:
+            if name[0] == '-': name = '_' + name[1:]
+        if kw and cnf: cnf = _cnfmerge((cnf, kw))
+        elif kw: cnf = kw
+        options = ()
+        for k, v in cnf.items():
+            if callable(v):
+                v = self._register(v)
+            options = options + ('-'+k, v)
+        self.tk.call(('image', 'create', imgtype, name,) + options)
+        self.name = name
+    def __str__(self): return self.name
+    def __del__(self):
+        if self.name:
+            try:
+                self.tk.call('image', 'delete', self.name)
+            except TclError:
+                # May happen if the root was destroyed
+                pass
+    def __setitem__(self, key, value):
+        self.tk.call(self.name, 'configure', '-'+key, value)
+    def __getitem__(self, key):
+        return self.tk.call(self.name, 'configure', '-'+key)
+    def configure(self, **kw):
+        """Configure the image."""
+        res = ()
+        for k, v in _cnfmerge(kw).items():
+            if v is not None:
+                if k[-1] == '_': k = k[:-1]
+                if callable(v):
+                    v = self._register(v)
+                res = res + ('-'+k, v)
+        self.tk.call((self.name, 'config') + res)
+    config = configure
+    def height(self):
+        """Return the height of the image."""
+        return getint(
+            self.tk.call('image', 'height', self.name))
+    def type(self):
+        """Return the type of the imgage, e.g. "photo" or "bitmap"."""
+        return self.tk.call('image', 'type', self.name)
+    def width(self):
+        """Return the width of the image."""
+        return getint(
+            self.tk.call('image', 'width', self.name))
+
+class PhotoImage(Image):
+    """Widget which can display colored images in GIF, PPM/PGM format."""
+    def __init__(self, name=None, cnf={}, master=None, **kw):
+        """Create an image with NAME.
+
+        Valid resource names: data, format, file, gamma, height, palette,
+        width."""
+        Image.__init__(self, 'photo', name, cnf, master, **kw)
+    def blank(self):
+        """Display a transparent image."""
+        self.tk.call(self.name, 'blank')
+    def cget(self, option):
+        """Return the value of OPTION."""
+        return self.tk.call(self.name, 'cget', '-' + option)
+    # XXX config
+    def __getitem__(self, key):
+        return self.tk.call(self.name, 'cget', '-' + key)
+    # XXX copy -from, -to, ...?
+    def copy(self):
+        """Return a new PhotoImage with the same image as this widget."""
+        destImage = PhotoImage()
+        self.tk.call(destImage, 'copy', self.name)
+        return destImage
+    def zoom(self,x,y=''):
+        """Return a new PhotoImage with the same image as this widget
+        but zoom it with X and Y."""
+        destImage = PhotoImage()
+        if y=='': y=x
+        self.tk.call(destImage, 'copy', self.name, '-zoom',x,y)
+        return destImage
+    def subsample(self,x,y=''):
+        """Return a new PhotoImage based on the same image as this widget
+        but use only every Xth or Yth pixel."""
+        destImage = PhotoImage()
+        if y=='': y=x
+        self.tk.call(destImage, 'copy', self.name, '-subsample',x,y)
+        return destImage
+    def get(self, x, y):
+        """Return the color (red, green, blue) of the pixel at X,Y."""
+        return self.tk.call(self.name, 'get', x, y)
+    def put(self, data, to=None):
+        """Put row formated colors to image starting from
+        position TO, e.g. image.put("{red green} {blue yellow}", to=(4,6))"""
+        args = (self.name, 'put', data)
+        if to:
+            if to[0] == '-to':
+                to = to[1:]
+            args = args + ('-to',) + tuple(to)
+        self.tk.call(args)
+    # XXX read
+    def write(self, filename, format=None, from_coords=None):
+        """Write image to file FILENAME in FORMAT starting from
+        position FROM_COORDS."""
+        args = (self.name, 'write', filename)
+        if format:
+            args = args + ('-format', format)
+        if from_coords:
+            args = args + ('-from',) + tuple(from_coords)
+        self.tk.call(args)
+
+class BitmapImage(Image):
+    """Widget which can display a bitmap."""
+    def __init__(self, name=None, cnf={}, master=None, **kw):
+        """Create a bitmap with NAME.
+
+        Valid resource names: background, data, file, foreground, maskdata, maskfile."""
+        Image.__init__(self, 'bitmap', name, cnf, master, **kw)
+
+def image_names(): return _default_root.tk.call('image', 'names')
+def image_types(): return _default_root.tk.call('image', 'types')
+
+
+class Spinbox(Widget):
+    """spinbox widget."""
+    def __init__(self, master=None, cnf={}, **kw):
+        """Construct a spinbox widget with the parent MASTER.
+
+        STANDARD OPTIONS
+
+            activebackground, background, borderwidth,
+            cursor, exportselection, font, foreground,
+            highlightbackground, highlightcolor,
+            highlightthickness, insertbackground,
+            insertborderwidth, insertofftime,
+            insertontime, insertwidth, justify, relief,
+            repeatdelay, repeatinterval,
+            selectbackground, selectborderwidth
+            selectforeground, takefocus, textvariable
+            xscrollcommand.
+
+        WIDGET-SPECIFIC OPTIONS
+
+            buttonbackground, buttoncursor,
+            buttondownrelief, buttonuprelief,
+            command, disabledbackground,
+            disabledforeground, format, from,
+            invalidcommand, increment,
+            readonlybackground, state, to,
+            validate, validatecommand values,
+            width, wrap,
+        """
+        Widget.__init__(self, master, 'spinbox', cnf, kw)
+
+    def bbox(self, index):
+        """Return a tuple of X1,Y1,X2,Y2 coordinates for a
+        rectangle which encloses the character given by index.
+
+        The first two elements of the list give the x and y
+        coordinates of the upper-left corner of the screen
+        area covered by the character (in pixels relative
+        to the widget) and the last two elements give the
+        width and height of the character, in pixels. The
+        bounding box may refer to a region outside the
+        visible area of the window.
+        """
+        return self.tk.call(self._w, 'bbox', index)
+
+    def delete(self, first, last=None):
+        """Delete one or more elements of the spinbox.
+
+        First is the index of the first character to delete,
+        and last is the index of the character just after
+        the last one to delete. If last isn't specified it
+        defaults to first+1, i.e. a single character is
+        deleted.  This command returns an empty string.
+        """
+        return self.tk.call(self._w, 'delete', first, last)
+
+    def get(self):
+        """Returns the spinbox's string"""
+        return self.tk.call(self._w, 'get')
+
+    def icursor(self, index):
+        """Alter the position of the insertion cursor.
+
+        The insertion cursor will be displayed just before
+        the character given by index. Returns an empty string
+        """
+        return self.tk.call(self._w, 'icursor', index)
+
+    def identify(self, x, y):
+        """Returns the name of the widget at position x, y
+
+        Return value is one of: none, buttondown, buttonup, entry
+        """
+        return self.tk.call(self._w, 'identify', x, y)
+
+    def index(self, index):
+        """Returns the numerical index corresponding to index
+        """
+        return self.tk.call(self._w, 'index', index)
+
+    def insert(self, index, s):
+        """Insert string s at index
+
+         Returns an empty string.
+        """
+        return self.tk.call(self._w, 'insert', index, s)
+
+    def invoke(self, element):
+        """Causes the specified element to be invoked
+
+        The element could be buttondown or buttonup
+        triggering the action associated with it.
+        """
+        return self.tk.call(self._w, 'invoke', element)
+
+    def scan(self, *args):
+        """Internal function."""
+        return self._getints(
+            self.tk.call((self._w, 'scan') + args)) or ()
+
+    def scan_mark(self, x):
+        """Records x and the current view in the spinbox window;
+
+        used in conjunction with later scan dragto commands.
+        Typically this command is associated with a mouse button
+        press in the widget. It returns an empty string.
+        """
+        return self.scan("mark", x)
+
+    def scan_dragto(self, x):
+        """Compute the difference between the given x argument
+        and the x argument to the last scan mark command
+
+        It then adjusts the view left or right by 10 times the
+        difference in x-coordinates. This command is typically
+        associated with mouse motion events in the widget, to
+        produce the effect of dragging the spinbox at high speed
+        through the window. The return value is an empty string.
+        """
+        return self.scan("dragto", x)
+
+    def selection(self, *args):
+        """Internal function."""
+        return self._getints(
+            self.tk.call((self._w, 'selection') + args)) or ()
+
+    def selection_adjust(self, index):
+        """Locate the end of the selection nearest to the character
+        given by index,
+
+        Then adjust that end of the selection to be at index
+        (i.e including but not going beyond index). The other
+        end of the selection is made the anchor point for future
+        select to commands. If the selection isn't currently in
+        the spinbox, then a new selection is created to include
+        the characters between index and the most recent selection
+        anchor point, inclusive. Returns an empty string.
+        """
+        return self.selection("adjust", index)
+
+    def selection_clear(self):
+        """Clear the selection
+
+        If the selection isn't in this widget then the
+        command has no effect. Returns an empty string.
+        """
+        return self.selection("clear")
+
+    def selection_element(self, element=None):
+        """Sets or gets the currently selected element.
+
+        If a spinbutton element is specified, it will be
+        displayed depressed
+        """
+        return self.selection("element", element)
+
+###########################################################################
+
+class LabelFrame(Widget):
+    """labelframe widget."""
+    def __init__(self, master=None, cnf={}, **kw):
+        """Construct a labelframe widget with the parent MASTER.
+
+        STANDARD OPTIONS
+
+            borderwidth, cursor, font, foreground,
+            highlightbackground, highlightcolor,
+            highlightthickness, padx, pady, relief,
+            takefocus, text
+
+        WIDGET-SPECIFIC OPTIONS
+
+            background, class, colormap, container,
+            height, labelanchor, labelwidget,
+            visual, width
+        """
+        Widget.__init__(self, master, 'labelframe', cnf, kw)
+
+########################################################################
+
+class PanedWindow(Widget):
+    """panedwindow widget."""
+    def __init__(self, master=None, cnf={}, **kw):
+        """Construct a panedwindow widget with the parent MASTER.
+
+        STANDARD OPTIONS
+
+            background, borderwidth, cursor, height,
+            orient, relief, width
+
+        WIDGET-SPECIFIC OPTIONS
+
+            handlepad, handlesize, opaqueresize,
+            sashcursor, sashpad, sashrelief,
+            sashwidth, showhandle,
+        """
+        Widget.__init__(self, master, 'panedwindow', cnf, kw)
+
+    def add(self, child, **kw):
+        """Add a child widget to the panedwindow in a new pane.
+
+        The child argument is the name of the child widget
+        followed by pairs of arguments that specify how to
+        manage the windows. Options may have any of the values
+        accepted by the configure subcommand.
+        """
+        self.tk.call((self._w, 'add', child) + self._options(kw))
+
+    def remove(self, child):
+        """Remove the pane containing child from the panedwindow
+
+        All geometry management options for child will be forgotten.
+        """
+        self.tk.call(self._w, 'forget', child)
+    forget=remove
+
+    def identify(self, x, y):
+        """Identify the panedwindow component at point x, y
+
+        If the point is over a sash or a sash handle, the result
+        is a two element list containing the index of the sash or
+        handle, and a word indicating whether it is over a sash
+        or a handle, such as {0 sash} or {2 handle}. If the point
+        is over any other part of the panedwindow, the result is
+        an empty list.
+        """
+        return self.tk.call(self._w, 'identify', x, y)
+
+    def proxy(self, *args):
+        """Internal function."""
+        return self._getints(
+            self.tk.call((self._w, 'proxy') + args)) or ()
+
+    def proxy_coord(self):
+        """Return the x and y pair of the most recent proxy location
+        """
+        return self.proxy("coord")
+
+    def proxy_forget(self):
+        """Remove the proxy from the display.
+        """
+        return self.proxy("forget")
+
+    def proxy_place(self, x, y):
+        """Place the proxy at the given x and y coordinates.
+        """
+        return self.proxy("place", x, y)
+
+    def sash(self, *args):
+        """Internal function."""
+        return self._getints(
+            self.tk.call((self._w, 'sash') + args)) or ()
+
+    def sash_coord(self, index):
+        """Return the current x and y pair for the sash given by index.
+
+        Index must be an integer between 0 and 1 less than the
+        number of panes in the panedwindow. The coordinates given are
+        those of the top left corner of the region containing the sash.
+        pathName sash dragto index x y This command computes the
+        difference between the given coordinates and the coordinates
+        given to the last sash coord command for the given sash. It then
+        moves that sash the computed difference. The return value is the
+        empty string.
+        """
+        return self.sash("coord", index)
+
+    def sash_mark(self, index):
+        """Records x and y for the sash given by index;
+
+        Used in conjunction with later dragto commands to move the sash.
+        """
+        return self.sash("mark", index)
+
+    def sash_place(self, index, x, y):
+        """Place the sash given by index at the given coordinates
+        """
+        return self.sash("place", index, x, y)
+
+    def panecget(self, child, option):
+        """Query a management option for window.
+
+        Option may be any value allowed by the paneconfigure subcommand
+        """
+        return self.tk.call(
+            (self._w, 'panecget') + (child, '-'+option))
+
+    def paneconfigure(self, tagOrId, cnf=None, **kw):
+        """Query or modify the management options for window.
+
+        If no option is specified, returns a list describing all
+        of the available options for pathName.  If option is
+        specified with no value, then the command returns a list
+        describing the one named option (this list will be identical
+        to the corresponding sublist of the value returned if no
+        option is specified). If one or more option-value pairs are
+        specified, then the command modifies the given widget
+        option(s) to have the given value(s); in this case the
+        command returns an empty string. The following options
+        are supported:
+
+        after window
+            Insert the window after the window specified. window
+            should be the name of a window already managed by pathName.
+        before window
+            Insert the window before the window specified. window
+            should be the name of a window already managed by pathName.
+        height size
+            Specify a height for the window. The height will be the
+            outer dimension of the window including its border, if
+            any. If size is an empty string, or if -height is not
+            specified, then the height requested internally by the
+            window will be used initially; the height may later be
+            adjusted by the movement of sashes in the panedwindow.
+            Size may be any value accepted by Tk_GetPixels.
+        minsize n
+            Specifies that the size of the window cannot be made
+            less than n. This constraint only affects the size of
+            the widget in the paned dimension -- the x dimension
+            for horizontal panedwindows, the y dimension for
+            vertical panedwindows. May be any value accepted by
+            Tk_GetPixels.
+        padx n
+            Specifies a non-negative value indicating how much
+            extra space to leave on each side of the window in
+            the X-direction. The value may have any of the forms
+            accepted by Tk_GetPixels.
+        pady n
+            Specifies a non-negative value indicating how much
+            extra space to leave on each side of the window in
+            the Y-direction. The value may have any of the forms
+            accepted by Tk_GetPixels.
+        sticky style
+            If a window's pane is larger than the requested
+            dimensions of the window, this option may be used
+            to position (or stretch) the window within its pane.
+            Style is a string that contains zero or more of the
+            characters n, s, e or w. The string can optionally
+            contains spaces or commas, but they are ignored. Each
+            letter refers to a side (north, south, east, or west)
+            that the window will "stick" to. If both n and s
+            (or e and w) are specified, the window will be
+            stretched to fill the entire height (or width) of
+            its cavity.
+        width size
+            Specify a width for the window. The width will be
+            the outer dimension of the window including its
+            border, if any. If size is an empty string, or
+            if -width is not specified, then the width requested
+            internally by the window will be used initially; the
+            width may later be adjusted by the movement of sashes
+            in the panedwindow. Size may be any value accepted by
+            Tk_GetPixels.
+
+        """
+        if cnf is None and not kw:
+            cnf = {}
+            for x in self.tk.split(
+                self.tk.call(self._w,
+                         'paneconfigure', tagOrId)):
+                cnf[x[0][1:]] = (x[0][1:],) + x[1:]
+            return cnf
+        if type(cnf) == StringType and not kw:
+            x = self.tk.split(self.tk.call(
+                self._w, 'paneconfigure', tagOrId, '-'+cnf))
+            return (x[0][1:],) + x[1:]
+        self.tk.call((self._w, 'paneconfigure', tagOrId) +
+                 self._options(cnf, kw))
+    paneconfig = paneconfigure
+
+    def panes(self):
+        """Returns an ordered list of the child panes."""
+        return self.tk.call(self._w, 'panes')
+
+######################################################################
+# Extensions:
+
+class Studbutton(Button):
+    def __init__(self, master=None, cnf={}, **kw):
+        Widget.__init__(self, master, 'studbutton', cnf, kw)
+        self.bind('<Any-Enter>',       self.tkButtonEnter)
+        self.bind('<Any-Leave>',       self.tkButtonLeave)
+        self.bind('<1>',               self.tkButtonDown)
+        self.bind('<ButtonRelease-1>', self.tkButtonUp)
+
+class Tributton(Button):
+    def __init__(self, master=None, cnf={}, **kw):
+        Widget.__init__(self, master, 'tributton', cnf, kw)
+        self.bind('<Any-Enter>',       self.tkButtonEnter)
+        self.bind('<Any-Leave>',       self.tkButtonLeave)
+        self.bind('<1>',               self.tkButtonDown)
+        self.bind('<ButtonRelease-1>', self.tkButtonUp)
+        self['fg']               = self['bg']
+        self['activebackground'] = self['bg']
+
+######################################################################
+# Test:
+
+def _test():
+    root = Tk()
+    text = "This is Tcl/Tk version %s" % TclVersion
+    if TclVersion >= 8.1:
+        try:
+            text = text + unicode("\nThis should be a cedilla: \347",
+                                  "iso-8859-1")
+        except NameError:
+            pass # no unicode support
+    label = Label(root, text=text)
+    label.pack()
+    test = Button(root, text="Click me!",
+              command=lambda root=root: root.test.configure(
+                  text="[%s]" % root.test['text']))
+    test.pack()
+    root.test = test
+    quit = Button(root, text="QUIT", command=root.destroy)
+    quit.pack()
+    # The following three commands are needed so the window pops
+    # up on top on Windows...
+    root.iconify()
+    root.update()
+    root.deiconify()
+    root.mainloop()
+
+if __name__ == '__main__':
+    _test()

Added: vendor/Python/current/Lib/lib-tk/tkColorChooser.py
===================================================================
--- vendor/Python/current/Lib/lib-tk/tkColorChooser.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/lib-tk/tkColorChooser.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,70 @@
+# tk common colour chooser dialogue
+#
+# this module provides an interface to the native color dialogue
+# available in Tk 4.2 and newer.
+#
+# written by Fredrik Lundh, May 1997
+#
+# fixed initialcolor handling in August 1998
+#
+
+#
+# options (all have default values):
+#
+# - initialcolor: colour to mark as selected when dialog is displayed
+#   (given as an RGB triplet or a Tk color string)
+#
+# - parent: which window to place the dialog on top of
+#
+# - title: dialog title
+#
+
+from tkCommonDialog import Dialog
+
+
+#
+# color chooser class
+
+class Chooser(Dialog):
+    "Ask for a color"
+
+    command = "tk_chooseColor"
+
+    def _fixoptions(self):
+        try:
+            # make sure initialcolor is a tk color string
+            color = self.options["initialcolor"]
+            if type(color) == type(()):
+                # assume an RGB triplet
+                self.options["initialcolor"] = "#%02x%02x%02x" % color
+        except KeyError:
+            pass
+
+    def _fixresult(self, widget, result):
+        # to simplify application code, the color chooser returns
+        # an RGB tuple together with the Tk color string
+        if not result:
+            return None, None # canceled
+        r, g, b = widget.winfo_rgb(result)
+        return (r/256, g/256, b/256), result
+
+
+#
+# convenience stuff
+
+def askcolor(color = None, **options):
+    "Ask for a color"
+
+    if color:
+        options = options.copy()
+        options["initialcolor"] = color
+
+    return Chooser(**options).show()
+
+
+# --------------------------------------------------------------------
+# test stuff
+
+if __name__ == "__main__":
+
+    print "color", askcolor()

Added: vendor/Python/current/Lib/lib-tk/tkCommonDialog.py
===================================================================
--- vendor/Python/current/Lib/lib-tk/tkCommonDialog.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/lib-tk/tkCommonDialog.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,60 @@
+# base class for tk common dialogues
+#
+# this module provides a base class for accessing the common
+# dialogues available in Tk 4.2 and newer.  use tkFileDialog,
+# tkColorChooser, and tkMessageBox to access the individual
+# dialogs.
+#
+# written by Fredrik Lundh, May 1997
+#
+
+from Tkinter import *
+
+class Dialog:
+
+    command  = None
+
+    def __init__(self, master=None, **options):
+
+        # FIXME: should this be placed on the module level instead?
+        if TkVersion < 4.2:
+            raise TclError, "this module requires Tk 4.2 or newer"
+
+        self.master  = master
+        self.options = options
+        if not master and options.get('parent'):
+            self.master = options['parent']
+
+    def _fixoptions(self):
+        pass # hook
+
+    def _fixresult(self, widget, result):
+        return result # hook
+
+    def show(self, **options):
+
+        # update instance options
+        for k, v in options.items():
+            self.options[k] = v
+
+        self._fixoptions()
+
+        # we need a dummy widget to properly process the options
+        # (at least as long as we use Tkinter 1.63)
+        w = Frame(self.master)
+
+        try:
+
+            s = w.tk.call(self.command, *w._options(self.options))
+
+            s = self._fixresult(w, s)
+
+        finally:
+
+            try:
+                # get rid of the widget
+                w.destroy()
+            except:
+                pass
+
+        return s

Added: vendor/Python/current/Lib/lib-tk/tkFileDialog.py
===================================================================
--- vendor/Python/current/Lib/lib-tk/tkFileDialog.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/lib-tk/tkFileDialog.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,215 @@
+#
+# Instant Python
+# $Id: tkFileDialog.py 36560 2004-07-18 06:16:08Z tim_one $
+#
+# tk common file dialogues
+#
+# this module provides interfaces to the native file dialogues
+# available in Tk 4.2 and newer, and the directory dialogue available
+# in Tk 8.3 and newer.
+#
+# written by Fredrik Lundh, May 1997.
+#
+
+#
+# options (all have default values):
+#
+# - defaultextension: added to filename if not explicitly given
+#
+# - filetypes: sequence of (label, pattern) tuples.  the same pattern
+#   may occur with several patterns.  use "*" as pattern to indicate
+#   all files.
+#
+# - initialdir: initial directory.  preserved by dialog instance.
+#
+# - initialfile: initial file (ignored by the open dialog).  preserved
+#   by dialog instance.
+#
+# - parent: which window to place the dialog on top of
+#
+# - title: dialog title
+#
+# - multiple: if true user may select more than one file
+#
+# options for the directory chooser:
+#
+# - initialdir, parent, title: see above
+#
+# - mustexist: if true, user must pick an existing directory
+#
+#
+
+
+from tkCommonDialog import Dialog
+
+class _Dialog(Dialog):
+
+    def _fixoptions(self):
+        try:
+            # make sure "filetypes" is a tuple
+            self.options["filetypes"] = tuple(self.options["filetypes"])
+        except KeyError:
+            pass
+
+    def _fixresult(self, widget, result):
+        if result:
+            # keep directory and filename until next time
+            import os
+            # convert Tcl path objects to strings
+            try:
+                result = result.string
+            except AttributeError:
+                # it already is a string
+                pass
+            path, file = os.path.split(result)
+            self.options["initialdir"] = path
+            self.options["initialfile"] = file
+        self.filename = result # compatibility
+        return result
+
+
+#
+# file dialogs
+
+class Open(_Dialog):
+    "Ask for a filename to open"
+
+    command = "tk_getOpenFile"
+
+    def _fixresult(self, widget, result):
+        if isinstance(result, tuple):
+            # multiple results:
+            result = tuple([getattr(r, "string", r) for r in result])
+            if result:
+                import os
+                path, file = os.path.split(result[0])
+                self.options["initialdir"] = path
+                # don't set initialfile or filename, as we have multiple of these
+            return result
+        if not widget.tk.wantobjects() and "multiple" in self.options:
+            # Need to split result explicitly
+            return self._fixresult(widget, widget.tk.splitlist(result))
+        return _Dialog._fixresult(self, widget, result)
+
+class SaveAs(_Dialog):
+    "Ask for a filename to save as"
+
+    command = "tk_getSaveFile"
+
+
+# the directory dialog has its own _fix routines.
+class Directory(Dialog):
+    "Ask for a directory"
+
+    command = "tk_chooseDirectory"
+
+    def _fixresult(self, widget, result):
+        if result:
+            # convert Tcl path objects to strings
+            try:
+                result = result.string
+            except AttributeError:
+                # it already is a string
+                pass
+            # keep directory until next time
+            self.options["initialdir"] = result
+        self.directory = result # compatibility
+        return result
+
+#
+# convenience stuff
+
+def askopenfilename(**options):
+    "Ask for a filename to open"
+
+    return Open(**options).show()
+
+def asksaveasfilename(**options):
+    "Ask for a filename to save as"
+
+    return SaveAs(**options).show()
+
+def askopenfilenames(**options):
+    """Ask for multiple filenames to open
+
+    Returns a list of filenames or empty list if
+    cancel button selected
+    """
+    options["multiple"]=1
+    return Open(**options).show()
+
+# FIXME: are the following  perhaps a bit too convenient?
+
+def askopenfile(mode = "r", **options):
+    "Ask for a filename to open, and returned the opened file"
+
+    filename = Open(**options).show()
+    if filename:
+        return open(filename, mode)
+    return None
+
+def askopenfiles(mode = "r", **options):
+    """Ask for multiple filenames and return the open file
+    objects
+
+    returns a list of open file objects or an empty list if
+    cancel selected
+    """
+
+    files = askopenfilenames(**options)
+    if files:
+        ofiles=[]
+        for filename in files:
+            ofiles.append(open(filename, mode))
+        files=ofiles
+    return files
+
+
+def asksaveasfile(mode = "w", **options):
+    "Ask for a filename to save as, and returned the opened file"
+
+    filename = SaveAs(**options).show()
+    if filename:
+        return open(filename, mode)
+    return None
+
+def askdirectory (**options):
+    "Ask for a directory, and return the file name"
+    return Directory(**options).show()
+
+# --------------------------------------------------------------------
+# test stuff
+
+if __name__ == "__main__":
+    # Since the file name may contain non-ASCII characters, we need
+    # to find an encoding that likely supports the file name, and
+    # displays correctly on the terminal.
+
+    # Start off with UTF-8
+    enc = "utf-8"
+    import sys
+
+    # See whether CODESET is defined
+    try:
+        import locale
+        locale.setlocale(locale.LC_ALL,'')
+        enc = locale.nl_langinfo(locale.CODESET)
+    except (ImportError, AttributeError):
+        pass
+
+    # dialog for openening files
+
+    openfilename=askopenfilename(filetypes=[("all files", "*")])
+    try:
+        fp=open(openfilename,"r")
+        fp.close()
+    except:
+        print "Could not open File: "
+        print sys.exc_info()[1]
+
+    print "open", openfilename.encode(enc)
+
+    # dialog for saving files
+
+    saveasfilename=asksaveasfilename()
+    print "saveas", saveasfilename.encode(enc)

Added: vendor/Python/current/Lib/lib-tk/tkFont.py
===================================================================
--- vendor/Python/current/Lib/lib-tk/tkFont.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/lib-tk/tkFont.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,216 @@
+# Tkinter font wrapper
+#
+# written by Fredrik Lundh, February 1998
+#
+# FIXME: should add 'displayof' option where relevant (actual, families,
+#        measure, and metrics)
+#
+
+__version__ = "0.9"
+
+import Tkinter
+
+# weight/slant
+NORMAL = "normal"
+ROMAN = "roman"
+BOLD   = "bold"
+ITALIC = "italic"
+
+def nametofont(name):
+    """Given the name of a tk named font, returns a Font representation.
+    """
+    return Font(name=name, exists=True)
+
+class Font:
+
+    """Represents a named font.
+
+    Constructor options are:
+
+    font -- font specifier (name, system font, or (family, size, style)-tuple)
+    name -- name to use for this font configuration (defaults to a unique name)
+    exists -- does a named font by this name already exist?
+       Creates a new named font if False, points to the existing font if True.
+       Raises _tkinter.TclError if the assertion is false.
+
+       the following are ignored if font is specified:
+
+    family -- font 'family', e.g. Courier, Times, Helvetica
+    size -- font size in points
+    weight -- font thickness: NORMAL, BOLD
+    slant -- font slant: ROMAN, ITALIC
+    underline -- font underlining: false (0), true (1)
+    overstrike -- font strikeout: false (0), true (1)
+
+    """
+
+    def _set(self, kw):
+        options = []
+        for k, v in kw.items():
+            options.append("-"+k)
+            options.append(str(v))
+        return tuple(options)
+
+    def _get(self, args):
+        options = []
+        for k in args:
+            options.append("-"+k)
+        return tuple(options)
+
+    def _mkdict(self, args):
+        options = {}
+        for i in range(0, len(args), 2):
+            options[args[i][1:]] = args[i+1]
+        return options
+
+    def __init__(self, root=None, font=None, name=None, exists=False, **options):
+        if not root:
+            root = Tkinter._default_root
+        if font:
+            # get actual settings corresponding to the given font
+            font = root.tk.splitlist(root.tk.call("font", "actual", font))
+        else:
+            font = self._set(options)
+        if not name:
+            name = "font" + str(id(self))
+        self.name = name
+
+        if exists:
+            self.delete_font = False
+            # confirm font exists
+            if self.name not in root.tk.call("font", "names"):
+                raise Tkinter._tkinter.TclError, "named font %s does not already exist" % (self.name,)
+            # if font config info supplied, apply it
+            if font:
+                root.tk.call("font", "configure", self.name, *font)
+        else:
+            # create new font (raises TclError if the font exists)
+            root.tk.call("font", "create", self.name, *font)
+            self.delete_font = True
+        # backlinks!
+        self._root  = root
+        self._split = root.tk.splitlist
+        self._call  = root.tk.call
+
+    def __str__(self):
+        return self.name
+
+    def __eq__(self, other):
+        return self.name == other.name and isinstance(other, Font)
+
+    def __getitem__(self, key):
+        return self.cget(key)
+
+    def __setitem__(self, key, value):
+        self.configure(**{key: value})
+
+    def __del__(self):
+        try:
+            if self.delete_font:
+                self._call("font", "delete", self.name)
+        except (KeyboardInterrupt, SystemExit):
+            raise
+        except Exception:
+            pass
+
+    def copy(self):
+        "Return a distinct copy of the current font"
+        return Font(self._root, **self.actual())
+
+    def actual(self, option=None):
+        "Return actual font attributes"
+        if option:
+            return self._call("font", "actual", self.name, "-"+option)
+        else:
+            return self._mkdict(
+                self._split(self._call("font", "actual", self.name))
+                )
+
+    def cget(self, option):
+        "Get font attribute"
+        return self._call("font", "config", self.name, "-"+option)
+
+    def config(self, **options):
+        "Modify font attributes"
+        if options:
+            self._call("font", "config", self.name,
+                  *self._set(options))
+        else:
+            return self._mkdict(
+                self._split(self._call("font", "config", self.name))
+                )
+
+    configure = config
+
+    def measure(self, text):
+        "Return text width"
+        return int(self._call("font", "measure", self.name, text))
+
+    def metrics(self, *options):
+        """Return font metrics.
+
+        For best performance, create a dummy widget
+        using this font before calling this method."""
+
+        if options:
+            return int(
+                self._call("font", "metrics", self.name, self._get(options))
+                )
+        else:
+            res = self._split(self._call("font", "metrics", self.name))
+            options = {}
+            for i in range(0, len(res), 2):
+                options[res[i][1:]] = int(res[i+1])
+            return options
+
+def families(root=None):
+    "Get font families (as a tuple)"
+    if not root:
+        root = Tkinter._default_root
+    return root.tk.splitlist(root.tk.call("font", "families"))
+
+def names(root=None):
+    "Get names of defined fonts (as a tuple)"
+    if not root:
+        root = Tkinter._default_root
+    return root.tk.splitlist(root.tk.call("font", "names"))
+
+# --------------------------------------------------------------------
+# test stuff
+
+if __name__ == "__main__":
+
+    root = Tkinter.Tk()
+
+    # create a font
+    f = Font(family="times", size=30, weight=NORMAL)
+
+    print f.actual()
+    print f.actual("family")
+    print f.actual("weight")
+
+    print f.config()
+    print f.cget("family")
+    print f.cget("weight")
+
+    print names()
+
+    print f.measure("hello"), f.metrics("linespace")
+
+    print f.metrics()
+
+    f = Font(font=("Courier", 20, "bold"))
+    print f.measure("hello"), f.metrics("linespace")
+
+    w = Tkinter.Label(root, text="Hello, world", font=f)
+    w.pack()
+
+    w = Tkinter.Button(root, text="Quit!", command=root.destroy)
+    w.pack()
+
+    fb = Font(font=w["font"]).copy()
+    fb.config(weight=BOLD)
+
+    w.config(font=fb)
+
+    Tkinter.mainloop()

Added: vendor/Python/current/Lib/lib-tk/tkMessageBox.py
===================================================================
--- vendor/Python/current/Lib/lib-tk/tkMessageBox.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/lib-tk/tkMessageBox.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,122 @@
+# tk common message boxes
+#
+# this module provides an interface to the native message boxes
+# available in Tk 4.2 and newer.
+#
+# written by Fredrik Lundh, May 1997
+#
+
+#
+# options (all have default values):
+#
+# - default: which button to make default (one of the reply codes)
+#
+# - icon: which icon to display (see below)
+#
+# - message: the message to display
+#
+# - parent: which window to place the dialog on top of
+#
+# - title: dialog title
+#
+# - type: dialog type; that is, which buttons to display (see below)
+#
+
+from tkCommonDialog import Dialog
+
+#
+# constants
+
+# icons
+ERROR = "error"
+INFO = "info"
+QUESTION = "question"
+WARNING = "warning"
+
+# types
+ABORTRETRYIGNORE = "abortretryignore"
+OK = "ok"
+OKCANCEL = "okcancel"
+RETRYCANCEL = "retrycancel"
+YESNO = "yesno"
+YESNOCANCEL = "yesnocancel"
+
+# replies
+ABORT = "abort"
+RETRY = "retry"
+IGNORE = "ignore"
+OK = "ok"
+CANCEL = "cancel"
+YES = "yes"
+NO = "no"
+
+
+#
+# message dialog class
+
+class Message(Dialog):
+    "A message box"
+
+    command  = "tk_messageBox"
+
+
+#
+# convenience stuff
+
+# Rename _icon and _type options to allow overriding them in options
+def _show(title=None, message=None, _icon=None, _type=None, **options):
+    if _icon and "icon" not in options:    options["icon"] = _icon
+    if _type and "type" not in options:    options["type"] = _type
+    if title:   options["title"] = title
+    if message: options["message"] = message
+    res = Message(**options).show()
+    # In some Tcl installations, Tcl converts yes/no into a boolean
+    if isinstance(res, bool):
+        if res: return YES
+        return NO
+    return res
+
+def showinfo(title=None, message=None, **options):
+    "Show an info message"
+    return _show(title, message, INFO, OK, **options)
+
+def showwarning(title=None, message=None, **options):
+    "Show a warning message"
+    return _show(title, message, WARNING, OK, **options)
+
+def showerror(title=None, message=None, **options):
+    "Show an error message"
+    return _show(title, message, ERROR, OK, **options)
+
+def askquestion(title=None, message=None, **options):
+    "Ask a question"
+    return _show(title, message, QUESTION, YESNO, **options)
+
+def askokcancel(title=None, message=None, **options):
+    "Ask if operation should proceed; return true if the answer is ok"
+    s = _show(title, message, QUESTION, OKCANCEL, **options)
+    return s == OK
+
+def askyesno(title=None, message=None, **options):
+    "Ask a question; return true if the answer is yes"
+    s = _show(title, message, QUESTION, YESNO, **options)
+    return s == YES
+
+def askretrycancel(title=None, message=None, **options):
+    "Ask if operation should be retried; return true if the answer is yes"
+    s = _show(title, message, WARNING, RETRYCANCEL, **options)
+    return s == RETRY
+
+
+# --------------------------------------------------------------------
+# test stuff
+
+if __name__ == "__main__":
+
+    print "info", showinfo("Spam", "Egg Information")
+    print "warning", showwarning("Spam", "Egg Warning")
+    print "error", showerror("Spam", "Egg Alert")
+    print "question", askquestion("Spam", "Question?")
+    print "proceed", askokcancel("Spam", "Proceed?")
+    print "yes/no", askyesno("Spam", "Got it?")
+    print "try again", askretrycancel("Spam", "Try again?")

Added: vendor/Python/current/Lib/lib-tk/tkSimpleDialog.py
===================================================================
--- vendor/Python/current/Lib/lib-tk/tkSimpleDialog.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/lib-tk/tkSimpleDialog.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,320 @@
+#
+# An Introduction to Tkinter
+# tkSimpleDialog.py
+#
+# Copyright (c) 1997 by Fredrik Lundh
+#
+# fredrik at pythonware.com
+# http://www.pythonware.com
+#
+
+# --------------------------------------------------------------------
+# dialog base class
+
+'''Dialog boxes
+
+This module handles dialog boxes. It contains the following
+public symbols:
+
+Dialog -- a base class for dialogs
+
+askinteger -- get an integer from the user
+
+askfloat -- get a float from the user
+
+askstring -- get a string from the user
+'''
+
+from Tkinter import *
+import os
+
+class Dialog(Toplevel):
+
+    '''Class to open dialogs.
+
+    This class is intended as a base class for custom dialogs
+    '''
+
+    def __init__(self, parent, title = None):
+
+        '''Initialize a dialog.
+
+        Arguments:
+
+            parent -- a parent window (the application window)
+
+            title -- the dialog title
+        '''
+        Toplevel.__init__(self, parent)
+
+        # If the master is not viewable, don't
+        # make the child transient, or else it
+        # would be opened withdrawn
+        if parent.winfo_viewable():  
+            self.transient(parent)
+ 
+        if title:
+            self.title(title)
+
+        self.parent = parent
+
+        self.result = None
+
+        body = Frame(self)
+        self.initial_focus = self.body(body)
+        body.pack(padx=5, pady=5)
+
+        self.buttonbox()
+
+        self.wait_visibility() # window needs to be visible for the grab
+        self.grab_set()
+
+        if not self.initial_focus:
+            self.initial_focus = self
+
+        self.protocol("WM_DELETE_WINDOW", self.cancel)
+
+        if self.parent is not None:
+            self.geometry("+%d+%d" % (parent.winfo_rootx()+50,
+                                      parent.winfo_rooty()+50))
+
+        self.initial_focus.focus_set()
+
+        self.wait_window(self)
+
+    def destroy(self):
+        '''Destroy the window'''
+        self.initial_focus = None
+        Toplevel.destroy(self)
+
+    #
+    # construction hooks
+
+    def body(self, master):
+        '''create dialog body.
+
+        return widget that should have initial focus.
+        This method should be overridden, and is called
+        by the __init__ method.
+        '''
+        pass
+
+    def buttonbox(self):
+        '''add standard button box.
+
+        override if you do not want the standard buttons
+        '''
+
+        box = Frame(self)
+
+        w = Button(box, text="OK", width=10, command=self.ok, default=ACTIVE)
+        w.pack(side=LEFT, padx=5, pady=5)
+        w = Button(box, text="Cancel", width=10, command=self.cancel)
+        w.pack(side=LEFT, padx=5, pady=5)
+
+        self.bind("<Return>", self.ok)
+        self.bind("<Escape>", self.cancel)
+
+        box.pack()
+
+    #
+    # standard button semantics
+
+    def ok(self, event=None):
+
+        if not self.validate():
+            self.initial_focus.focus_set() # put focus back
+            return
+
+        self.withdraw()
+        self.update_idletasks()
+
+        try:
+            self.apply()
+        finally:
+            self.cancel()
+
+    def cancel(self, event=None):
+
+        # put focus back to the parent window
+        if self.parent is not None:
+            self.parent.focus_set()
+        self.destroy()
+
+    #
+    # command hooks
+
+    def validate(self):
+        '''validate the data
+
+        This method is called automatically to validate the data before the
+        dialog is destroyed. By default, it always validates OK.
+        '''
+
+        return 1 # override
+
+    def apply(self):
+        '''process the data
+
+        This method is called automatically to process the data, *after*
+        the dialog is destroyed. By default, it does nothing.
+        '''
+
+        pass # override
+
+
+# --------------------------------------------------------------------
+# convenience dialogues
+
+class _QueryDialog(Dialog):
+
+    def __init__(self, title, prompt,
+                 initialvalue=None,
+                 minvalue = None, maxvalue = None,
+                 parent = None):
+
+        if not parent:
+            import Tkinter
+            parent = Tkinter._default_root
+
+        self.prompt   = prompt
+        self.minvalue = minvalue
+        self.maxvalue = maxvalue
+
+        self.initialvalue = initialvalue
+
+        Dialog.__init__(self, parent, title)
+
+    def destroy(self):
+        self.entry = None
+        Dialog.destroy(self)
+
+    def body(self, master):
+
+        w = Label(master, text=self.prompt, justify=LEFT)
+        w.grid(row=0, padx=5, sticky=W)
+
+        self.entry = Entry(master, name="entry")
+        self.entry.grid(row=1, padx=5, sticky=W+E)
+
+        if self.initialvalue:
+            self.entry.insert(0, self.initialvalue)
+            self.entry.select_range(0, END)
+
+        return self.entry
+
+    def validate(self):
+
+        import tkMessageBox
+
+        try:
+            result = self.getresult()
+        except ValueError:
+            tkMessageBox.showwarning(
+                "Illegal value",
+                self.errormessage + "\nPlease try again",
+                parent = self
+            )
+            return 0
+
+        if self.minvalue is not None and result < self.minvalue:
+            tkMessageBox.showwarning(
+                "Too small",
+                "The allowed minimum value is %s. "
+                "Please try again." % self.minvalue,
+                parent = self
+            )
+            return 0
+
+        if self.maxvalue is not None and result > self.maxvalue:
+            tkMessageBox.showwarning(
+                "Too large",
+                "The allowed maximum value is %s. "
+                "Please try again." % self.maxvalue,
+                parent = self
+            )
+            return 0
+
+        self.result = result
+
+        return 1
+
+
+class _QueryInteger(_QueryDialog):
+    errormessage = "Not an integer."
+    def getresult(self):
+        return int(self.entry.get())
+
+def askinteger(title, prompt, **kw):
+    '''get an integer from the user
+
+    Arguments:
+
+        title -- the dialog title
+        prompt -- the label text
+        **kw -- see SimpleDialog class
+
+    Return value is an integer
+    '''
+    d = _QueryInteger(title, prompt, **kw)
+    return d.result
+
+class _QueryFloat(_QueryDialog):
+    errormessage = "Not a floating point value."
+    def getresult(self):
+        return float(self.entry.get())
+
+def askfloat(title, prompt, **kw):
+    '''get a float from the user
+
+    Arguments:
+
+        title -- the dialog title
+        prompt -- the label text
+        **kw -- see SimpleDialog class
+
+    Return value is a float
+    '''
+    d = _QueryFloat(title, prompt, **kw)
+    return d.result
+
+class _QueryString(_QueryDialog):
+    def __init__(self, *args, **kw):
+        if kw.has_key("show"):
+            self.__show = kw["show"]
+            del kw["show"]
+        else:
+            self.__show = None
+        _QueryDialog.__init__(self, *args, **kw)
+
+    def body(self, master):
+        entry = _QueryDialog.body(self, master)
+        if self.__show is not None:
+            entry.configure(show=self.__show)
+        return entry
+
+    def getresult(self):
+        return self.entry.get()
+
+def askstring(title, prompt, **kw):
+    '''get a string from the user
+
+    Arguments:
+
+        title -- the dialog title
+        prompt -- the label text
+        **kw -- see SimpleDialog class
+
+    Return value is a string
+    '''
+    d = _QueryString(title, prompt, **kw)
+    return d.result
+
+if __name__ == "__main__":
+
+    root = Tk()
+    root.update()
+
+    print askinteger("Spam", "Egg count", initialvalue=12*12)
+    print askfloat("Spam", "Egg weight\n(in tons)", minvalue=1, maxvalue=100)
+    print askstring("Spam", "Egg label")

Added: vendor/Python/current/Lib/lib-tk/turtle.py
===================================================================
--- vendor/Python/current/Lib/lib-tk/turtle.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/lib-tk/turtle.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,956 @@
+# LogoMation-like turtle graphics
+
+"""
+Turtle graphics is a popular way for introducing programming to
+kids. It was part of the original Logo programming language developed
+by Wally Feurzeig and Seymour Papert in 1966.
+
+Imagine a robotic turtle starting at (0, 0) in the x-y plane. Give it
+the command turtle.forward(15), and it moves (on-screen!) 15 pixels in
+the direction it is facing, drawing a line as it moves. Give it the
+command turtle.left(25), and it rotates in-place 25 degrees clockwise.
+
+By combining together these and similar commands, intricate shapes and
+pictures can easily be drawn.
+"""
+
+from math import * # Also for export
+import Tkinter
+
+speeds = ['fastest', 'fast', 'normal', 'slow', 'slowest']
+
+class Error(Exception):
+    pass
+
+class RawPen:
+
+    def __init__(self, canvas):
+        self._canvas = canvas
+        self._items = []
+        self._tracing = 1
+        self._arrow = 0
+        self._delay = 10     # default delay for drawing
+        self._angle = 0.0
+        self.degrees()
+        self.reset()
+
+    def degrees(self, fullcircle=360.0):
+        """ Set angle measurement units to degrees.
+
+        Example:
+        >>> turtle.degrees()
+        """
+        # Don't try to change _angle if it is 0, because
+        # _fullcircle might not be set, yet
+        if self._angle:
+            self._angle = (self._angle / self._fullcircle) * fullcircle
+        self._fullcircle = fullcircle
+        self._invradian = pi / (fullcircle * 0.5)
+
+    def radians(self):
+        """ Set the angle measurement units to radians.
+
+        Example:
+        >>> turtle.radians()
+        """
+        self.degrees(2.0*pi)
+
+    def reset(self):
+        """ Clear the screen, re-center the pen, and set variables to
+        the default values.
+
+        Example:
+        >>> turtle.position()
+        [0.0, -22.0]
+        >>> turtle.heading()
+        100.0
+        >>> turtle.reset()
+        >>> turtle.position()
+        [0.0, 0.0]
+        >>> turtle.heading()
+        0.0
+        """
+        canvas = self._canvas
+        self._canvas.update()
+        width = canvas.winfo_width()
+        height = canvas.winfo_height()
+        if width <= 1:
+            width = canvas['width']
+        if height <= 1:
+            height = canvas['height']
+        self._origin = float(width)/2.0, float(height)/2.0
+        self._position = self._origin
+        self._angle = 0.0
+        self._drawing = 1
+        self._width = 1
+        self._color = "black"
+        self._filling = 0
+        self._path = []
+        self.clear()
+        canvas._root().tkraise()
+
+    def clear(self):
+        """ Clear the screen. The turtle does not move.
+
+        Example:
+        >>> turtle.clear()
+        """
+        self.fill(0)
+        canvas = self._canvas
+        items = self._items
+        self._items = []
+        for item in items:
+            canvas.delete(item)
+        self._delete_turtle()
+        self._draw_turtle()
+
+    def tracer(self, flag):
+        """ Set tracing on if flag is True, and off if it is False.
+        Tracing means line are drawn more slowly, with an
+        animation of an arrow along the line.
+
+        Example:
+        >>> turtle.tracer(False)   # turns off Tracer
+        """
+        self._tracing = flag
+        if not self._tracing:
+            self._delete_turtle()
+        self._draw_turtle()
+
+    def forward(self, distance):
+        """ Go forward distance steps.
+
+        Example:
+        >>> turtle.position()
+        [0.0, 0.0]
+        >>> turtle.forward(25)
+        >>> turtle.position()
+        [25.0, 0.0]
+        >>> turtle.forward(-75)
+        >>> turtle.position()
+        [-50.0, 0.0]
+        """
+        x0, y0 = start = self._position
+        x1 = x0 + distance * cos(self._angle*self._invradian)
+        y1 = y0 - distance * sin(self._angle*self._invradian)
+        self._goto(x1, y1)
+
+    def backward(self, distance):
+        """ Go backwards distance steps.
+
+        The turtle's heading does not change.
+
+        Example:
+        >>> turtle.position()
+        [0.0, 0.0]
+        >>> turtle.backward(30)
+        >>> turtle.position()
+        [-30.0, 0.0]
+        """
+        self.forward(-distance)
+
+    def left(self, angle):
+        """ Turn left angle units (units are by default degrees,
+        but can be set via the degrees() and radians() functions.)
+
+        When viewed from above, the turning happens in-place around
+        its front tip.
+
+        Example:
+        >>> turtle.heading()
+        22
+        >>> turtle.left(45)
+        >>> turtle.heading()
+        67.0
+        """
+        self._angle = (self._angle + angle) % self._fullcircle
+        self._draw_turtle()
+
+    def right(self, angle):
+        """ Turn right angle units (units are by default degrees,
+        but can be set via the degrees() and radians() functions.)
+
+        When viewed from above, the turning happens in-place around
+        its front tip.
+
+        Example:
+        >>> turtle.heading()
+        22
+        >>> turtle.right(45)
+        >>> turtle.heading()
+        337.0
+        """
+        self.left(-angle)
+
+    def up(self):
+        """ Pull the pen up -- no drawing when moving.
+
+        Example:
+        >>> turtle.up()
+        """
+        self._drawing = 0
+
+    def down(self):
+        """ Put the pen down -- draw when moving.
+
+        Example:
+        >>> turtle.down()
+        """
+        self._drawing = 1
+
+    def width(self, width):
+        """ Set the line to thickness to width.
+
+        Example:
+        >>> turtle.width(10)
+        """
+        self._width = float(width)
+
+    def color(self, *args):
+        """ Set the pen color.
+
+        Three input formats are allowed:
+
+            color(s)
+            s is a Tk specification string, such as "red" or "yellow"
+
+            color((r, g, b))
+            *a tuple* of r, g, and b, which represent, an RGB color,
+            and each of r, g, and b are in the range [0..1]
+
+            color(r, g, b)
+            r, g, and b represent an RGB color, and each of r, g, and b
+            are in the range [0..1]
+
+        Example:
+
+        >>> turtle.color('brown')
+        >>> tup = (0.2, 0.8, 0.55)
+        >>> turtle.color(tup)
+        >>> turtle.color(0, .5, 0)
+        """
+        if not args:
+            raise Error, "no color arguments"
+        if len(args) == 1:
+            color = args[0]
+            if type(color) == type(""):
+                # Test the color first
+                try:
+                    id = self._canvas.create_line(0, 0, 0, 0, fill=color)
+                except Tkinter.TclError:
+                    raise Error, "bad color string: %r" % (color,)
+                self._set_color(color)
+                return
+            try:
+                r, g, b = color
+            except:
+                raise Error, "bad color sequence: %r" % (color,)
+        else:
+            try:
+                r, g, b = args
+            except:
+                raise Error, "bad color arguments: %r" % (args,)
+        assert 0 <= r <= 1
+        assert 0 <= g <= 1
+        assert 0 <= b <= 1
+        x = 255.0
+        y = 0.5
+        self._set_color("#%02x%02x%02x" % (int(r*x+y), int(g*x+y), int(b*x+y)))
+
+    def _set_color(self,color):
+        self._color = color
+        self._draw_turtle()
+
+    def write(self, text, move=False):
+        """ Write text at the current pen position.
+
+        If move is true, the pen is moved to the bottom-right corner
+        of the text. By default, move is False.
+
+        Example:
+        >>> turtle.write('The race is on!')
+        >>> turtle.write('Home = (0, 0)', True)
+        """
+        x, y  = self._position
+        x = x-1 # correction -- calibrated for Windows
+        item = self._canvas.create_text(x, y,
+                                        text=str(text), anchor="sw",
+                                        fill=self._color)
+        self._items.append(item)
+        if move:
+            x0, y0, x1, y1 = self._canvas.bbox(item)
+            self._goto(x1, y1)
+        self._draw_turtle()
+
+    def fill(self, flag):
+        """ Call fill(1) before drawing the shape you
+         want to fill, and fill(0) when done.
+
+        Example:
+        >>> turtle.fill(1)
+        >>> turtle.forward(100)
+        >>> turtle.left(90)
+        >>> turtle.forward(100)
+        >>> turtle.left(90)
+        >>> turtle.forward(100)
+        >>> turtle.left(90)
+        >>> turtle.forward(100)
+        >>> turtle.fill(0)
+        """
+        if self._filling:
+            path = tuple(self._path)
+            smooth = self._filling < 0
+            if len(path) > 2:
+                item = self._canvas._create('polygon', path,
+                                            {'fill': self._color,
+                                             'smooth': smooth})
+                self._items.append(item)
+        self._path = []
+        self._filling = flag
+        if flag:
+            self._path.append(self._position)
+
+    def begin_fill(self):
+        """ Called just before drawing a shape to be filled.
+            Must eventually be followed by a corresponding end_fill() call.
+            Otherwise it will be ignored.
+
+        Example:
+        >>> turtle.begin_fill()
+        >>> turtle.forward(100)
+        >>> turtle.left(90)
+        >>> turtle.forward(100)
+        >>> turtle.left(90)
+        >>> turtle.forward(100)
+        >>> turtle.left(90)
+        >>> turtle.forward(100)
+        >>> turtle.end_fill()
+        """
+        self._path = [self._position]
+        self._filling = 1
+
+    def end_fill(self):
+        """ Called after drawing a shape to be filled.
+
+        Example:
+        >>> turtle.begin_fill()
+        >>> turtle.forward(100)
+        >>> turtle.left(90)
+        >>> turtle.forward(100)
+        >>> turtle.left(90)
+        >>> turtle.forward(100)
+        >>> turtle.left(90)
+        >>> turtle.forward(100)
+        >>> turtle.end_fill()
+        """
+        self.fill(0)
+
+    def circle(self, radius, extent = None):
+        """ Draw a circle with given radius.
+        The center is radius units left of the turtle; extent
+        determines which part of the circle is drawn. If not given,
+        the entire circle is drawn.
+
+        If extent is not a full circle, one endpoint of the arc is the
+        current pen position. The arc is drawn in a counter clockwise
+        direction if radius is positive, otherwise in a clockwise
+        direction. In the process, the direction of the turtle is
+        changed by the amount of the extent.
+
+        >>> turtle.circle(50)
+        >>> turtle.circle(120, 180)  # half a circle
+        """
+        if extent is None:
+            extent = self._fullcircle
+        frac = abs(extent)/self._fullcircle
+        steps = 1+int(min(11+abs(radius)/6.0, 59.0)*frac)
+        w = 1.0 * extent / steps
+        w2 = 0.5 * w
+        l = 2.0 * radius * sin(w2*self._invradian)
+        if radius < 0:
+            l, w, w2 = -l, -w, -w2
+        self.left(w2)
+        for i in range(steps):
+            self.forward(l)
+            self.left(w)
+        self.right(w2)
+
+    def heading(self):
+        """ Return the turtle's current heading.
+
+        Example:
+        >>> turtle.heading()
+        67.0
+        """
+        return self._angle
+
+    def setheading(self, angle):
+        """ Set the turtle facing the given angle.
+
+        Here are some common directions in degrees:
+
+           0 - east
+          90 - north
+         180 - west
+         270 - south
+
+        Example:
+        >>> turtle.setheading(90)
+        >>> turtle.heading()
+        90
+        >>> turtle.setheading(128)
+        >>> turtle.heading()
+        128
+        """
+        self._angle = angle
+        self._draw_turtle()
+
+    def window_width(self):
+        """ Returns the width of the turtle window.
+
+        Example:
+        >>> turtle.window_width()
+        640
+        """
+        width = self._canvas.winfo_width()
+        if width <= 1:  # the window isn't managed by a geometry manager
+            width = self._canvas['width']
+        return width
+
+    def window_height(self):
+        """ Return the height of the turtle window.
+
+        Example:
+        >>> turtle.window_height()
+        768
+        """
+        height = self._canvas.winfo_height()
+        if height <= 1: # the window isn't managed by a geometry manager
+            height = self._canvas['height']
+        return height
+
+    def position(self):
+        """ Return the current (x, y) location of the turtle.
+
+        Example:
+        >>> turtle.position()
+        [0.0, 240.0]
+        """
+        x0, y0 = self._origin
+        x1, y1 = self._position
+        return [x1-x0, -y1+y0]
+
+    def setx(self, xpos):
+        """ Set the turtle's x coordinate to be xpos.
+
+        Example:
+        >>> turtle.position()
+        [10.0, 240.0]
+        >>> turtle.setx(10)
+        >>> turtle.position()
+        [10.0, 240.0]
+        """
+        x0, y0 = self._origin
+        x1, y1 = self._position
+        self._goto(x0+xpos, y1)
+
+    def sety(self, ypos):
+        """ Set the turtle's y coordinate to be ypos.
+
+        Example:
+        >>> turtle.position()
+        [0.0, 0.0]
+        >>> turtle.sety(-22)
+        >>> turtle.position()
+        [0.0, -22.0]
+        """
+        x0, y0 = self._origin
+        x1, y1 = self._position
+        self._goto(x1, y0-ypos)
+
+    def towards(self, *args):
+        """Returs the angle, which corresponds to the line
+        from turtle-position to point (x,y).
+
+        Argument can be two coordinates or one pair of coordinates
+        or a RawPen/Pen instance.
+
+        Example:
+        >>> turtle.position()
+        [10.0, 10.0]
+        >>> turtle.towards(0,0)
+        225.0
+        """
+        if len(args) == 2:
+            x, y = args
+        else:
+            arg = args[0]
+            if isinstance(arg, RawPen):
+                x, y = arg.position()
+            else:
+                x, y = arg
+        x0, y0 = self.position()
+        dx = x - x0
+        dy = y - y0
+        return (atan2(dy,dx) / self._invradian) % self._fullcircle
+
+    def goto(self, *args):
+        """ Go to the given point.
+
+        If the pen is down, then a line will be drawn. The turtle's
+        orientation does not change.
+
+        Two input formats are accepted:
+
+           goto(x, y)
+           go to point (x, y)
+
+           goto((x, y))
+           go to point (x, y)
+
+        Example:
+        >>> turtle.position()
+        [0.0, 0.0]
+        >>> turtle.goto(50, -45)
+        >>> turtle.position()
+        [50.0, -45.0]
+        """
+        if len(args) == 1:
+            try:
+                x, y = args[0]
+            except:
+                raise Error, "bad point argument: %r" % (args[0],)
+        else:
+            try:
+                x, y = args
+            except:
+                raise Error, "bad coordinates: %r" % (args[0],)
+        x0, y0 = self._origin
+        self._goto(x0+x, y0-y)
+
+    def _goto(self, x1, y1):
+        x0, y0 = self._position
+        self._position = map(float, (x1, y1))
+        if self._filling:
+            self._path.append(self._position)
+        if self._drawing:
+            if self._tracing:
+                dx = float(x1 - x0)
+                dy = float(y1 - y0)
+                distance = hypot(dx, dy)
+                nhops = int(distance)
+                item = self._canvas.create_line(x0, y0, x0, y0,
+                                                width=self._width,
+                                                capstyle="round",
+                                                fill=self._color)
+                try:
+                    for i in range(1, 1+nhops):
+                        x, y = x0 + dx*i/nhops, y0 + dy*i/nhops
+                        self._canvas.coords(item, x0, y0, x, y)
+                        self._draw_turtle((x,y))
+                        self._canvas.update()
+                        self._canvas.after(self._delay)
+                    # in case nhops==0
+                    self._canvas.coords(item, x0, y0, x1, y1)
+                    self._canvas.itemconfigure(item, arrow="none")
+                except Tkinter.TclError:
+                    # Probably the window was closed!
+                    return
+            else:
+                item = self._canvas.create_line(x0, y0, x1, y1,
+                                                width=self._width,
+                                                capstyle="round",
+                                                fill=self._color)
+            self._items.append(item)
+        self._draw_turtle()
+
+    def speed(self, speed):
+        """ Set the turtle's speed.
+
+        speed must one of these five strings:
+
+            'fastest' is a 0 ms delay
+            'fast' is a 5 ms delay
+            'normal' is a 10 ms delay
+            'slow' is a 15 ms delay
+            'slowest' is a 20 ms delay
+
+         Example:
+         >>> turtle.speed('slow')
+        """
+        try:
+            speed = speed.strip().lower()
+            self._delay = speeds.index(speed) * 5
+        except:
+            raise ValueError("%r is not a valid speed. speed must be "
+                             "one of %s" % (speed, speeds))
+
+
+    def delay(self, delay):
+        """ Set the drawing delay in milliseconds.
+
+        This is intended to allow finer control of the drawing speed
+        than the speed() method
+
+        Example:
+        >>> turtle.delay(15)
+        """
+        if int(delay) < 0:
+            raise ValueError("delay must be greater than or equal to 0")
+        self._delay = int(delay)
+
+    def _draw_turtle(self, position=[]):
+        if not self._tracing:
+            self._canvas.update()
+            return
+        if position == []:
+            position = self._position
+        x,y = position
+        distance = 8
+        dx = distance * cos(self._angle*self._invradian)
+        dy = distance * sin(self._angle*self._invradian)
+        self._delete_turtle()
+        self._arrow = self._canvas.create_line(x-dx,y+dy,x,y,
+                                          width=self._width,
+                                          arrow="last",
+                                          capstyle="round",
+                                          fill=self._color)
+        self._canvas.update()
+
+    def _delete_turtle(self):
+        if self._arrow != 0:
+            self._canvas.delete(self._arrow)
+            self._arrow = 0
+
+
+_root = None
+_canvas = None
+_pen = None
+_width = 0.50                  # 50% of window width
+_height = 0.75                 # 75% of window height
+_startx = None
+_starty = None
+_title = "Turtle Graphics"     # default title
+
+class Pen(RawPen):
+
+    def __init__(self):
+        global _root, _canvas
+        if _root is None:
+            _root = Tkinter.Tk()
+            _root.wm_protocol("WM_DELETE_WINDOW", self._destroy)
+            _root.title(_title)
+
+        if _canvas is None:
+            # XXX Should have scroll bars
+            _canvas = Tkinter.Canvas(_root, background="white")
+            _canvas.pack(expand=1, fill="both")
+
+            setup(width=_width, height= _height, startx=_startx, starty=_starty)
+
+        RawPen.__init__(self, _canvas)
+
+    def _destroy(self):
+        global _root, _canvas, _pen
+        root = self._canvas._root()
+        if root is _root:
+            _pen = None
+            _root = None
+            _canvas = None
+        root.destroy()
+
+def _getpen():
+    global _pen
+    if not _pen:
+        _pen = Pen()
+    return _pen
+
+class Turtle(Pen):
+    pass
+
+"""For documentation of the following functions see
+   the RawPen methods with the same names
+"""
+
+def degrees(): _getpen().degrees()
+def radians(): _getpen().radians()
+def reset(): _getpen().reset()
+def clear(): _getpen().clear()
+def tracer(flag): _getpen().tracer(flag)
+def forward(distance): _getpen().forward(distance)
+def backward(distance): _getpen().backward(distance)
+def left(angle): _getpen().left(angle)
+def right(angle): _getpen().right(angle)
+def up(): _getpen().up()
+def down(): _getpen().down()
+def width(width): _getpen().width(width)
+def color(*args): _getpen().color(*args)
+def write(arg, move=0): _getpen().write(arg, move)
+def fill(flag): _getpen().fill(flag)
+def begin_fill(): _getpen().begin_fill()
+def end_fill(): _getpen().end_fill()
+def circle(radius, extent=None): _getpen().circle(radius, extent)
+def goto(*args): _getpen().goto(*args)
+def heading(): return _getpen().heading()
+def setheading(angle): _getpen().setheading(angle)
+def position(): return _getpen().position()
+def window_width(): return _getpen().window_width()
+def window_height(): return _getpen().window_height()
+def setx(xpos): _getpen().setx(xpos)
+def sety(ypos): _getpen().sety(ypos)
+def towards(*args): return _getpen().towards(*args)
+
+def done(): _root.mainloop()
+def delay(delay): return _getpen().delay(delay)
+def speed(speed): return _getpen().speed(speed)
+
+for methodname in dir(RawPen):
+    """ copies RawPen docstrings to module functions of same name """
+    if not methodname.startswith("_"):
+        eval(methodname).__doc__ = RawPen.__dict__[methodname].__doc__
+
+
+def setup(**geometry):
+    """ Sets the size and position of the main window.
+
+    Keywords are width, height, startx and starty:
+
+    width: either a size in pixels or a fraction of the screen.
+      Default is 50% of screen.
+    height: either the height in pixels or a fraction of the screen.
+      Default is 75% of screen.
+
+    Setting either width or height to None before drawing will force
+      use of default geometry as in older versions of turtle.py
+
+    startx: starting position in pixels from the left edge of the screen.
+      Default is to center window. Setting startx to None is the default
+      and centers window horizontally on screen.
+
+    starty: starting position in pixels from the top edge of the screen.
+      Default is to center window. Setting starty to None is the default
+      and centers window vertically on screen.
+
+    Examples:
+    >>> setup (width=200, height=200, startx=0, starty=0)
+
+    sets window to 200x200 pixels, in upper left of screen
+
+    >>> setup(width=.75, height=0.5, startx=None, starty=None)
+
+    sets window to 75% of screen by 50% of screen and centers
+
+    >>> setup(width=None)
+
+    forces use of default geometry as in older versions of turtle.py
+    """
+
+    global _width, _height, _startx, _starty
+
+    width = geometry.get('width',_width)
+    if width >= 0 or width == None:
+        _width = width
+    else:
+        raise ValueError, "width can not be less than 0"
+
+    height = geometry.get('height',_height)
+    if height >= 0 or height == None:
+        _height = height
+    else:
+        raise ValueError, "height can not be less than 0"
+
+    startx = geometry.get('startx', _startx)
+    if startx >= 0 or startx == None:
+        _startx = _startx
+    else:
+        raise ValueError, "startx can not be less than 0"
+
+    starty = geometry.get('starty', _starty)
+    if starty >= 0 or starty == None:
+        _starty = starty
+    else:
+        raise ValueError, "startx can not be less than 0"
+
+
+    if _root and _width and _height:
+        if 0 < _width <= 1:
+            _width = _root.winfo_screenwidth() * +width
+        if 0 < _height <= 1:
+            _height = _root.winfo_screenheight() * _height
+
+        # center window on screen
+        if _startx is None:
+            _startx = (_root.winfo_screenwidth() - _width) / 2
+
+        if _starty is None:
+            _starty = (_root.winfo_screenheight() - _height) / 2
+
+        _root.geometry("%dx%d+%d+%d" % (_width, _height, _startx, _starty))
+
+def title(title):
+    """Set the window title.
+
+    By default this is set to 'Turtle Graphics'
+
+    Example:
+    >>> title("My Window")
+    """
+
+    global _title
+    _title = title
+
+def demo():
+    reset()
+    tracer(1)
+    up()
+    backward(100)
+    down()
+    # draw 3 squares; the last filled
+    width(3)
+    for i in range(3):
+        if i == 2:
+            fill(1)
+        for j in range(4):
+            forward(20)
+            left(90)
+        if i == 2:
+            color("maroon")
+            fill(0)
+        up()
+        forward(30)
+        down()
+    width(1)
+    color("black")
+    # move out of the way
+    tracer(0)
+    up()
+    right(90)
+    forward(100)
+    right(90)
+    forward(100)
+    right(180)
+    down()
+    # some text
+    write("startstart", 1)
+    write("start", 1)
+    color("red")
+    # staircase
+    for i in range(5):
+        forward(20)
+        left(90)
+        forward(20)
+        right(90)
+    # filled staircase
+    fill(1)
+    for i in range(5):
+        forward(20)
+        left(90)
+        forward(20)
+        right(90)
+    fill(0)
+    tracer(1)
+    # more text
+    write("end")
+
+def demo2():
+    # exercises some new and improved features
+    speed('fast')
+    width(3)
+
+    # draw a segmented half-circle
+    setheading(towards(0,0))
+    x,y = position()
+    r = (x**2+y**2)**.5/2.0
+    right(90)
+    pendown = True
+    for i in range(18):
+        if pendown:
+            up()
+            pendown = False
+        else:
+            down()
+            pendown = True
+        circle(r,10)
+    sleep(2)
+
+    reset()
+    left(90)
+
+    # draw a series of triangles
+    l = 10
+    color("green")
+    width(3)
+    left(180)
+    sp = 5
+    for i in range(-2,16):
+        if i > 0:
+            color(1.0-0.05*i,0,0.05*i)
+            fill(1)
+            color("green")
+        for j in range(3):
+            forward(l)
+            left(120)
+        l += 10
+        left(15)
+        if sp > 0:
+            sp = sp-1
+            speed(speeds[sp])
+    color(0.25,0,0.75)
+    fill(0)
+
+    # draw and fill a concave shape
+    left(120)
+    up()
+    forward(70)
+    right(30)
+    down()
+    color("red")
+    speed("fastest")
+    fill(1)
+    for i in range(4):
+        circle(50,90)
+        right(90)
+        forward(30)
+        right(90)
+    color("yellow")
+    fill(0)
+    left(90)
+    up()
+    forward(30)
+    down();
+
+    color("red")
+
+    # create a second turtle and make the original pursue and catch it
+    turtle=Turtle()
+    turtle.reset()
+    turtle.left(90)
+    turtle.speed('normal')
+    turtle.up()
+    turtle.goto(280,40)
+    turtle.left(24)
+    turtle.down()
+    turtle.speed('fast')
+    turtle.color("blue")
+    turtle.width(2)
+    speed('fastest')
+
+    # turn default turtle towards new turtle object
+    setheading(towards(turtle))
+    while ( abs(position()[0]-turtle.position()[0])>4 or
+            abs(position()[1]-turtle.position()[1])>4):
+        turtle.forward(3.5)
+        turtle.left(0.6)
+        # turn default turtle towards new turtle object
+        setheading(towards(turtle))
+        forward(4)
+    write("CAUGHT! ", move=True)
+
+
+
+if __name__ == '__main__':
+    from time import sleep
+    demo()
+    sleep(3)
+    demo2()
+    done()

Added: vendor/Python/current/Lib/linecache.py
===================================================================
--- vendor/Python/current/Lib/linecache.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/linecache.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,136 @@
+"""Cache lines from files.
+
+This is intended to read lines from modules imported -- hence if a filename
+is not found, it will look down the module search path for a file by
+that name.
+"""
+
+import sys
+import os
+
+__all__ = ["getline", "clearcache", "checkcache"]
+
+def getline(filename, lineno, module_globals=None):
+    lines = getlines(filename, module_globals)
+    if 1 <= lineno <= len(lines):
+        return lines[lineno-1]
+    else:
+        return ''
+
+
+# The cache
+
+cache = {} # The cache
+
+
+def clearcache():
+    """Clear the cache entirely."""
+
+    global cache
+    cache = {}
+
+
+def getlines(filename, module_globals=None):
+    """Get the lines for a file from the cache.
+    Update the cache if it doesn't contain an entry for this file already."""
+
+    if filename in cache:
+        return cache[filename][2]
+    else:
+        return updatecache(filename, module_globals)
+
+
+def checkcache(filename=None):
+    """Discard cache entries that are out of date.
+    (This is not checked upon each call!)"""
+
+    if filename is None:
+        filenames = cache.keys()
+    else:
+        if filename in cache:
+            filenames = [filename]
+        else:
+            return
+
+    for filename in filenames:
+        size, mtime, lines, fullname = cache[filename]
+        if mtime is None:
+            continue   # no-op for files loaded via a __loader__
+        try:
+            stat = os.stat(fullname)
+        except os.error:
+            del cache[filename]
+            continue
+        if size != stat.st_size or mtime != stat.st_mtime:
+            del cache[filename]
+
+
+def updatecache(filename, module_globals=None):
+    """Update a cache entry and return its list of lines.
+    If something's wrong, print a message, discard the cache entry,
+    and return an empty list."""
+
+    if filename in cache:
+        del cache[filename]
+    if not filename or filename[0] + filename[-1] == '<>':
+        return []
+
+    fullname = filename
+    try:
+        stat = os.stat(fullname)
+    except os.error, msg:
+        basename = os.path.split(filename)[1]
+
+        # Try for a __loader__, if available
+        if module_globals and '__loader__' in module_globals:
+            name = module_globals.get('__name__')
+            loader = module_globals['__loader__']
+            get_source = getattr(loader, 'get_source', None)
+
+            if name and get_source:
+                if basename.startswith(name.split('.')[-1]+'.'):
+                    try:
+                        data = get_source(name)
+                    except (ImportError, IOError):
+                        pass
+                    else:
+                        if data is None:
+                            # No luck, the PEP302 loader cannot find the source
+                            # for this module.
+                            return []
+                        cache[filename] = (
+                            len(data), None,
+                            [line+'\n' for line in data.splitlines()], fullname
+                        )
+                        return cache[filename][2]
+
+        # Try looking through the module search path.
+
+        for dirname in sys.path:
+            # When using imputil, sys.path may contain things other than
+            # strings; ignore them when it happens.
+            try:
+                fullname = os.path.join(dirname, basename)
+            except (TypeError, AttributeError):
+                # Not sufficiently string-like to do anything useful with.
+                pass
+            else:
+                try:
+                    stat = os.stat(fullname)
+                    break
+                except os.error:
+                    pass
+        else:
+            # No luck
+##          print '*** Cannot stat', filename, ':', msg
+            return []
+    try:
+        fp = open(fullname, 'rU')
+        lines = fp.readlines()
+        fp.close()
+    except IOError, msg:
+##      print '*** Cannot open', fullname, ':', msg
+        return []
+    size, mtime = stat.st_size, stat.st_mtime
+    cache[filename] = size, mtime, lines, fullname
+    return lines

Added: vendor/Python/current/Lib/locale.py
===================================================================
--- vendor/Python/current/Lib/locale.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/locale.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1562 @@
+""" Locale support.
+
+    The module provides low-level access to the C lib's locale APIs
+    and adds high level number formatting APIs as well as a locale
+    aliasing engine to complement these.
+
+    The aliasing engine includes support for many commonly used locale
+    names and maps them to values suitable for passing to the C lib's
+    setlocale() function. It also includes default encodings for all
+    supported locale names.
+
+"""
+
+import sys, encodings, encodings.aliases
+
+# Try importing the _locale module.
+#
+# If this fails, fall back on a basic 'C' locale emulation.
+
+# Yuck:  LC_MESSAGES is non-standard:  can't tell whether it exists before
+# trying the import.  So __all__ is also fiddled at the end of the file.
+__all__ = ["setlocale","Error","localeconv","strcoll","strxfrm",
+           "format","str","atof","atoi","LC_CTYPE","LC_COLLATE",
+           "LC_TIME","LC_MONETARY","LC_NUMERIC", "LC_ALL","CHAR_MAX"]
+
+try:
+
+    from _locale import *
+
+except ImportError:
+
+    # Locale emulation
+
+    CHAR_MAX = 127
+    LC_ALL = 6
+    LC_COLLATE = 3
+    LC_CTYPE = 0
+    LC_MESSAGES = 5
+    LC_MONETARY = 4
+    LC_NUMERIC = 1
+    LC_TIME = 2
+    Error = ValueError
+
+    def localeconv():
+        """ localeconv() -> dict.
+            Returns numeric and monetary locale-specific parameters.
+        """
+        # 'C' locale default values
+        return {'grouping': [127],
+                'currency_symbol': '',
+                'n_sign_posn': 127,
+                'p_cs_precedes': 127,
+                'n_cs_precedes': 127,
+                'mon_grouping': [],
+                'n_sep_by_space': 127,
+                'decimal_point': '.',
+                'negative_sign': '',
+                'positive_sign': '',
+                'p_sep_by_space': 127,
+                'int_curr_symbol': '',
+                'p_sign_posn': 127,
+                'thousands_sep': '',
+                'mon_thousands_sep': '',
+                'frac_digits': 127,
+                'mon_decimal_point': '',
+                'int_frac_digits': 127}
+
+    def setlocale(category, value=None):
+        """ setlocale(integer,string=None) -> string.
+            Activates/queries locale processing.
+        """
+        if value not in (None, '', 'C'):
+            raise Error, '_locale emulation only supports "C" locale'
+        return 'C'
+
+    def strcoll(a,b):
+        """ strcoll(string,string) -> int.
+            Compares two strings according to the locale.
+        """
+        return cmp(a,b)
+
+    def strxfrm(s):
+        """ strxfrm(string) -> string.
+            Returns a string that behaves for cmp locale-aware.
+        """
+        return s
+
+### Number formatting APIs
+
+# Author: Martin von Loewis
+# improved by Georg Brandl
+
+#perform the grouping from right to left
+def _group(s, monetary=False):
+    conv = localeconv()
+    thousands_sep = conv[monetary and 'mon_thousands_sep' or 'thousands_sep']
+    grouping = conv[monetary and 'mon_grouping' or 'grouping']
+    if not grouping:
+        return (s, 0)
+    result = ""
+    seps = 0
+    spaces = ""
+    if s[-1] == ' ':
+        sp = s.find(' ')
+        spaces = s[sp:]
+        s = s[:sp]
+    while s and grouping:
+        # if grouping is -1, we are done
+        if grouping[0] == CHAR_MAX:
+            break
+        # 0: re-use last group ad infinitum
+        elif grouping[0] != 0:
+            #process last group
+            group = grouping[0]
+            grouping = grouping[1:]
+        if result:
+            result = s[-group:] + thousands_sep + result
+            seps += 1
+        else:
+            result = s[-group:]
+        s = s[:-group]
+        if s and s[-1] not in "0123456789":
+            # the leading string is only spaces and signs
+            return s + result + spaces, seps
+    if not result:
+        return s + spaces, seps
+    if s:
+        result = s + thousands_sep + result
+        seps += 1
+    return result + spaces, seps
+
+def format(percent, value, grouping=False, monetary=False, *additional):
+    """Returns the locale-aware substitution of a %? specifier
+    (percent).
+
+    additional is for format strings which contain one or more
+    '*' modifiers."""
+    # this is only for one-percent-specifier strings and this should be checked
+    if percent[0] != '%':
+        raise ValueError("format() must be given exactly one %char "
+                         "format specifier")
+    if additional:
+        formatted = percent % ((value,) + additional)
+    else:
+        formatted = percent % value
+    # floats and decimal ints need special action!
+    if percent[-1] in 'eEfFgG':
+        seps = 0
+        parts = formatted.split('.')
+        if grouping:
+            parts[0], seps = _group(parts[0], monetary=monetary)
+        decimal_point = localeconv()[monetary and 'mon_decimal_point'
+                                              or 'decimal_point']
+        formatted = decimal_point.join(parts)
+        while seps:
+            sp = formatted.find(' ')
+            if sp == -1: break
+            formatted = formatted[:sp] + formatted[sp+1:]
+            seps -= 1
+    elif percent[-1] in 'diu':
+        if grouping:
+            formatted = _group(formatted, monetary=monetary)[0]
+    return formatted
+
+import re, operator
+_percent_re = re.compile(r'%(?:\((?P<key>.*?)\))?'
+                         r'(?P<modifiers>[-#0-9 +*.hlL]*?)[eEfFgGdiouxXcrs%]')
+
+def format_string(f, val, grouping=False):
+    """Formats a string in the same way that the % formatting would use,
+    but takes the current locale into account.
+    Grouping is applied if the third parameter is true."""
+    percents = list(_percent_re.finditer(f))
+    new_f = _percent_re.sub('%s', f)
+
+    if isinstance(val, tuple):
+        new_val = list(val)
+        i = 0
+        for perc in percents:
+            starcount = perc.group('modifiers').count('*')
+            new_val[i] = format(perc.group(), new_val[i], grouping, False, *new_val[i+1:i+1+starcount])
+            del new_val[i+1:i+1+starcount]
+            i += (1 + starcount)
+        val = tuple(new_val)
+    elif operator.isMappingType(val):
+        for perc in percents:
+            key = perc.group("key")
+            val[key] = format(perc.group(), val[key], grouping)
+    else:
+        # val is a single value
+        val = format(percents[0].group(), val, grouping)
+
+    return new_f % val
+
+def currency(val, symbol=True, grouping=False, international=False):
+    """Formats val according to the currency settings
+    in the current locale."""
+    conv = localeconv()
+
+    # check for illegal values
+    digits = conv[international and 'int_frac_digits' or 'frac_digits']
+    if digits == 127:
+        raise ValueError("Currency formatting is not possible using "
+                         "the 'C' locale.")
+
+    s = format('%%.%if' % digits, abs(val), grouping, monetary=True)
+    # '<' and '>' are markers if the sign must be inserted between symbol and value
+    s = '<' + s + '>'
+
+    if symbol:
+        smb = conv[international and 'int_curr_symbol' or 'currency_symbol']
+        precedes = conv[val<0 and 'n_cs_precedes' or 'p_cs_precedes']
+        separated = conv[val<0 and 'n_sep_by_space' or 'p_sep_by_space']
+
+        if precedes:
+            s = smb + (separated and ' ' or '') + s
+        else:
+            s = s + (separated and ' ' or '') + smb
+
+    sign_pos = conv[val<0 and 'n_sign_posn' or 'p_sign_posn']
+    sign = conv[val<0 and 'negative_sign' or 'positive_sign']
+
+    if sign_pos == 0:
+        s = '(' + s + ')'
+    elif sign_pos == 1:
+        s = sign + s
+    elif sign_pos == 2:
+        s = s + sign
+    elif sign_pos == 3:
+        s = s.replace('<', sign)
+    elif sign_pos == 4:
+        s = s.replace('>', sign)
+    else:
+        # the default if nothing specified;
+        # this should be the most fitting sign position
+        s = sign + s
+
+    return s.replace('<', '').replace('>', '')
+
+def str(val):
+    """Convert float to integer, taking the locale into account."""
+    return format("%.12g", val)
+
+def atof(string, func=float):
+    "Parses a string as a float according to the locale settings."
+    #First, get rid of the grouping
+    ts = localeconv()['thousands_sep']
+    if ts:
+        string = string.replace(ts, '')
+    #next, replace the decimal point with a dot
+    dd = localeconv()['decimal_point']
+    if dd:
+        string = string.replace(dd, '.')
+    #finally, parse the string
+    return func(string)
+
+def atoi(str):
+    "Converts a string to an integer according to the locale settings."
+    return atof(str, int)
+
+def _test():
+    setlocale(LC_ALL, "")
+    #do grouping
+    s1 = format("%d", 123456789,1)
+    print s1, "is", atoi(s1)
+    #standard formatting
+    s1 = str(3.14)
+    print s1, "is", atof(s1)
+
+### Locale name aliasing engine
+
+# Author: Marc-Andre Lemburg, mal at lemburg.com
+# Various tweaks by Fredrik Lundh <fredrik at pythonware.com>
+
+# store away the low-level version of setlocale (it's
+# overridden below)
+_setlocale = setlocale
+
+def normalize(localename):
+
+    """ Returns a normalized locale code for the given locale
+        name.
+
+        The returned locale code is formatted for use with
+        setlocale().
+
+        If normalization fails, the original name is returned
+        unchanged.
+
+        If the given encoding is not known, the function defaults to
+        the default encoding for the locale code just like setlocale()
+        does.
+
+    """
+    # Normalize the locale name and extract the encoding
+    fullname = localename.lower()
+    if ':' in fullname:
+        # ':' is sometimes used as encoding delimiter.
+        fullname = fullname.replace(':', '.')
+    if '.' in fullname:
+        langname, encoding = fullname.split('.')[:2]
+        fullname = langname + '.' + encoding
+    else:
+        langname = fullname
+        encoding = ''
+
+    # First lookup: fullname (possibly with encoding)
+    norm_encoding = encoding.replace('-', '')
+    norm_encoding = norm_encoding.replace('_', '')
+    lookup_name = langname + '.' + encoding
+    code = locale_alias.get(lookup_name, None)
+    if code is not None:
+        return code
+    #print 'first lookup failed'
+
+    # Second try: langname (without encoding)
+    code = locale_alias.get(langname, None)
+    if code is not None:
+        #print 'langname lookup succeeded'
+        if '.' in code:
+            langname, defenc = code.split('.')
+        else:
+            langname = code
+            defenc = ''
+        if encoding:
+            # Convert the encoding to a C lib compatible encoding string
+            norm_encoding = encodings.normalize_encoding(encoding)
+            #print 'norm encoding: %r' % norm_encoding
+            norm_encoding = encodings.aliases.aliases.get(norm_encoding,
+                                                          norm_encoding)
+            #print 'aliased encoding: %r' % norm_encoding
+            encoding = locale_encoding_alias.get(norm_encoding,
+                                                 norm_encoding)
+        else:
+            encoding = defenc
+        #print 'found encoding %r' % encoding
+        if encoding:
+            return langname + '.' + encoding
+        else:
+            return langname
+
+    else:
+        return localename
+
+def _parse_localename(localename):
+
+    """ Parses the locale code for localename and returns the
+        result as tuple (language code, encoding).
+
+        The localename is normalized and passed through the locale
+        alias engine. A ValueError is raised in case the locale name
+        cannot be parsed.
+
+        The language code corresponds to RFC 1766.  code and encoding
+        can be None in case the values cannot be determined or are
+        unknown to this implementation.
+
+    """
+    code = normalize(localename)
+    if '@' in code:
+        # Deal with locale modifiers
+        code, modifier = code.split('@')
+        if modifier == 'euro' and '.' not in code:
+            # Assume Latin-9 for @euro locales. This is bogus,
+            # since some systems may use other encodings for these
+            # locales. Also, we ignore other modifiers.
+            return code, 'iso-8859-15'
+
+    if '.' in code:
+        return tuple(code.split('.')[:2])
+    elif code == 'C':
+        return None, None
+    raise ValueError, 'unknown locale: %s' % localename
+
+def _build_localename(localetuple):
+
+    """ Builds a locale code from the given tuple (language code,
+        encoding).
+
+        No aliasing or normalizing takes place.
+
+    """
+    language, encoding = localetuple
+    if language is None:
+        language = 'C'
+    if encoding is None:
+        return language
+    else:
+        return language + '.' + encoding
+
+def getdefaultlocale(envvars=('LC_ALL', 'LC_CTYPE', 'LANG', 'LANGUAGE')):
+
+    """ Tries to determine the default locale settings and returns
+        them as tuple (language code, encoding).
+
+        According to POSIX, a program which has not called
+        setlocale(LC_ALL, "") runs using the portable 'C' locale.
+        Calling setlocale(LC_ALL, "") lets it use the default locale as
+        defined by the LANG variable. Since we don't want to interfere
+        with the current locale setting we thus emulate the behavior
+        in the way described above.
+
+        To maintain compatibility with other platforms, not only the
+        LANG variable is tested, but a list of variables given as
+        envvars parameter. The first found to be defined will be
+        used. envvars defaults to the search path used in GNU gettext;
+        it must always contain the variable name 'LANG'.
+
+        Except for the code 'C', the language code corresponds to RFC
+        1766.  code and encoding can be None in case the values cannot
+        be determined.
+
+    """
+
+    try:
+        # check if it's supported by the _locale module
+        import _locale
+        code, encoding = _locale._getdefaultlocale()
+    except (ImportError, AttributeError):
+        pass
+    else:
+        # make sure the code/encoding values are valid
+        if sys.platform == "win32" and code and code[:2] == "0x":
+            # map windows language identifier to language name
+            code = windows_locale.get(int(code, 0))
+        # ...add other platform-specific processing here, if
+        # necessary...
+        return code, encoding
+
+    # fall back on POSIX behaviour
+    import os
+    lookup = os.environ.get
+    for variable in envvars:
+        localename = lookup(variable,None)
+        if localename:
+            if variable == 'LANGUAGE':
+                localename = localename.split(':')[0]
+            break
+    else:
+        localename = 'C'
+    return _parse_localename(localename)
+
+
+def getlocale(category=LC_CTYPE):
+
+    """ Returns the current setting for the given locale category as
+        tuple (language code, encoding).
+
+        category may be one of the LC_* value except LC_ALL. It
+        defaults to LC_CTYPE.
+
+        Except for the code 'C', the language code corresponds to RFC
+        1766.  code and encoding can be None in case the values cannot
+        be determined.
+
+    """
+    localename = _setlocale(category)
+    if category == LC_ALL and ';' in localename:
+        raise TypeError, 'category LC_ALL is not supported'
+    return _parse_localename(localename)
+
+def setlocale(category, locale=None):
+
+    """ Set the locale for the given category.  The locale can be
+        a string, a locale tuple (language code, encoding), or None.
+
+        Locale tuples are converted to strings the locale aliasing
+        engine.  Locale strings are passed directly to the C lib.
+
+        category may be given as one of the LC_* values.
+
+    """
+    if locale and type(locale) is not type(""):
+        # convert to string
+        locale = normalize(_build_localename(locale))
+    return _setlocale(category, locale)
+
+def resetlocale(category=LC_ALL):
+
+    """ Sets the locale for category to the default setting.
+
+        The default setting is determined by calling
+        getdefaultlocale(). category defaults to LC_ALL.
+
+    """
+    _setlocale(category, _build_localename(getdefaultlocale()))
+
+if sys.platform in ('win32', 'darwin', 'mac'):
+    # On Win32, this will return the ANSI code page
+    # On the Mac, it should return the system encoding;
+    # it might return "ascii" instead
+    def getpreferredencoding(do_setlocale = True):
+        """Return the charset that the user is likely using."""
+        import _locale
+        return _locale._getdefaultlocale()[1]
+else:
+    # On Unix, if CODESET is available, use that.
+    try:
+        CODESET
+    except NameError:
+        # Fall back to parsing environment variables :-(
+        def getpreferredencoding(do_setlocale = True):
+            """Return the charset that the user is likely using,
+            by looking at environment variables."""
+            return getdefaultlocale()[1]
+    else:
+        def getpreferredencoding(do_setlocale = True):
+            """Return the charset that the user is likely using,
+            according to the system configuration."""
+            if do_setlocale:
+                oldloc = setlocale(LC_CTYPE)
+                setlocale(LC_CTYPE, "")
+                result = nl_langinfo(CODESET)
+                setlocale(LC_CTYPE, oldloc)
+                return result
+            else:
+                return nl_langinfo(CODESET)
+
+
+### Database
+#
+# The following data was extracted from the locale.alias file which
+# comes with X11 and then hand edited removing the explicit encoding
+# definitions and adding some more aliases. The file is usually
+# available as /usr/lib/X11/locale/locale.alias.
+#
+
+#
+# The local_encoding_alias table maps lowercase encoding alias names
+# to C locale encoding names (case-sensitive). Note that normalize()
+# first looks up the encoding in the encodings.aliases dictionary and
+# then applies this mapping to find the correct C lib name for the
+# encoding.
+#
+locale_encoding_alias = {
+
+    # Mappings for non-standard encoding names used in locale names
+    '437':                          'C',
+    'c':                            'C',
+    'en':                           'ISO8859-1',
+    'jis':                          'JIS7',
+    'jis7':                         'JIS7',
+    'ajec':                         'eucJP',
+
+    # Mappings from Python codec names to C lib encoding names
+    'ascii':                        'ISO8859-1',
+    'latin_1':                      'ISO8859-1',
+    'iso8859_1':                    'ISO8859-1',
+    'iso8859_10':                   'ISO8859-10',
+    'iso8859_11':                   'ISO8859-11',
+    'iso8859_13':                   'ISO8859-13',
+    'iso8859_14':                   'ISO8859-14',
+    'iso8859_15':                   'ISO8859-15',
+    'iso8859_2':                    'ISO8859-2',
+    'iso8859_3':                    'ISO8859-3',
+    'iso8859_4':                    'ISO8859-4',
+    'iso8859_5':                    'ISO8859-5',
+    'iso8859_6':                    'ISO8859-6',
+    'iso8859_7':                    'ISO8859-7',
+    'iso8859_8':                    'ISO8859-8',
+    'iso8859_9':                    'ISO8859-9',
+    'iso2022_jp':                   'JIS7',
+    'shift_jis':                    'SJIS',
+    'tactis':                       'TACTIS',
+    'euc_jp':                       'eucJP',
+    'euc_kr':                       'eucKR',
+    'utf_8':                        'UTF8',
+    'koi8_r':                       'KOI8-R',
+    'koi8_u':                       'KOI8-U',
+    # XXX This list is still incomplete. If you know more
+    # mappings, please file a bug report. Thanks.
+}
+
+#
+# The locale_alias table maps lowercase alias names to C locale names
+# (case-sensitive). Encodings are always separated from the locale
+# name using a dot ('.'); they should only be given in case the
+# language name is needed to interpret the given encoding alias
+# correctly (CJK codes often have this need).
+#
+# Note that the normalize() function which uses this tables
+# removes '_' and '-' characters from the encoding part of the
+# locale name before doing the lookup. This saves a lot of
+# space in the table.
+#
+# MAL 2004-12-10:
+# Updated alias mapping to most recent locale.alias file
+# from X.org distribution using makelocalealias.py.
+#
+# These are the differences compared to the old mapping (Python 2.4
+# and older):
+#
+#    updated 'bg' -> 'bg_BG.ISO8859-5' to 'bg_BG.CP1251'
+#    updated 'bg_bg' -> 'bg_BG.ISO8859-5' to 'bg_BG.CP1251'
+#    updated 'bulgarian' -> 'bg_BG.ISO8859-5' to 'bg_BG.CP1251'
+#    updated 'cz' -> 'cz_CZ.ISO8859-2' to 'cs_CZ.ISO8859-2'
+#    updated 'cz_cz' -> 'cz_CZ.ISO8859-2' to 'cs_CZ.ISO8859-2'
+#    updated 'czech' -> 'cs_CS.ISO8859-2' to 'cs_CZ.ISO8859-2'
+#    updated 'dutch' -> 'nl_BE.ISO8859-1' to 'nl_NL.ISO8859-1'
+#    updated 'et' -> 'et_EE.ISO8859-4' to 'et_EE.ISO8859-15'
+#    updated 'et_ee' -> 'et_EE.ISO8859-4' to 'et_EE.ISO8859-15'
+#    updated 'fi' -> 'fi_FI.ISO8859-1' to 'fi_FI.ISO8859-15'
+#    updated 'fi_fi' -> 'fi_FI.ISO8859-1' to 'fi_FI.ISO8859-15'
+#    updated 'iw' -> 'iw_IL.ISO8859-8' to 'he_IL.ISO8859-8'
+#    updated 'iw_il' -> 'iw_IL.ISO8859-8' to 'he_IL.ISO8859-8'
+#    updated 'japanese' -> 'ja_JP.SJIS' to 'ja_JP.eucJP'
+#    updated 'lt' -> 'lt_LT.ISO8859-4' to 'lt_LT.ISO8859-13'
+#    updated 'lv' -> 'lv_LV.ISO8859-4' to 'lv_LV.ISO8859-13'
+#    updated 'sl' -> 'sl_CS.ISO8859-2' to 'sl_SI.ISO8859-2'
+#    updated 'slovene' -> 'sl_CS.ISO8859-2' to 'sl_SI.ISO8859-2'
+#    updated 'th_th' -> 'th_TH.TACTIS' to 'th_TH.ISO8859-11'
+#    updated 'zh_cn' -> 'zh_CN.eucCN' to 'zh_CN.gb2312'
+#    updated 'zh_cn.big5' -> 'zh_TW.eucTW' to 'zh_TW.big5'
+#    updated 'zh_tw' -> 'zh_TW.eucTW' to 'zh_TW.big5'
+#
+locale_alias = {
+    'a3':                                   'a3_AZ.KOI8-C',
+    'a3_az':                                'a3_AZ.KOI8-C',
+    'a3_az.koi8c':                          'a3_AZ.KOI8-C',
+    'af':                                   'af_ZA.ISO8859-1',
+    'af_za':                                'af_ZA.ISO8859-1',
+    'af_za.iso88591':                       'af_ZA.ISO8859-1',
+    'am':                                   'am_ET.UTF-8',
+    'american':                             'en_US.ISO8859-1',
+    'american.iso88591':                    'en_US.ISO8859-1',
+    'ar':                                   'ar_AA.ISO8859-6',
+    'ar_aa':                                'ar_AA.ISO8859-6',
+    'ar_aa.iso88596':                       'ar_AA.ISO8859-6',
+    'ar_ae':                                'ar_AE.ISO8859-6',
+    'ar_bh':                                'ar_BH.ISO8859-6',
+    'ar_dz':                                'ar_DZ.ISO8859-6',
+    'ar_eg':                                'ar_EG.ISO8859-6',
+    'ar_eg.iso88596':                       'ar_EG.ISO8859-6',
+    'ar_iq':                                'ar_IQ.ISO8859-6',
+    'ar_jo':                                'ar_JO.ISO8859-6',
+    'ar_kw':                                'ar_KW.ISO8859-6',
+    'ar_lb':                                'ar_LB.ISO8859-6',
+    'ar_ly':                                'ar_LY.ISO8859-6',
+    'ar_ma':                                'ar_MA.ISO8859-6',
+    'ar_om':                                'ar_OM.ISO8859-6',
+    'ar_qa':                                'ar_QA.ISO8859-6',
+    'ar_sa':                                'ar_SA.ISO8859-6',
+    'ar_sa.iso88596':                       'ar_SA.ISO8859-6',
+    'ar_sd':                                'ar_SD.ISO8859-6',
+    'ar_sy':                                'ar_SY.ISO8859-6',
+    'ar_tn':                                'ar_TN.ISO8859-6',
+    'ar_ye':                                'ar_YE.ISO8859-6',
+    'arabic':                               'ar_AA.ISO8859-6',
+    'arabic.iso88596':                      'ar_AA.ISO8859-6',
+    'az':                                   'az_AZ.ISO8859-9E',
+    'az_az':                                'az_AZ.ISO8859-9E',
+    'az_az.iso88599e':                      'az_AZ.ISO8859-9E',
+    'be':                                   'be_BY.CP1251',
+    'be_by':                                'be_BY.CP1251',
+    'be_by.cp1251':                         'be_BY.CP1251',
+    'be_by.microsoftcp1251':                'be_BY.CP1251',
+    'bg':                                   'bg_BG.CP1251',
+    'bg_bg':                                'bg_BG.CP1251',
+    'bg_bg.cp1251':                         'bg_BG.CP1251',
+    'bg_bg.iso88595':                       'bg_BG.ISO8859-5',
+    'bg_bg.koi8r':                          'bg_BG.KOI8-R',
+    'bg_bg.microsoftcp1251':                'bg_BG.CP1251',
+    'bokmal':                               'nb_NO.ISO8859-1',
+    'bokm\xe5l':                            'nb_NO.ISO8859-1',
+    'br':                                   'br_FR.ISO8859-1',
+    'br_fr':                                'br_FR.ISO8859-1',
+    'br_fr.iso88591':                       'br_FR.ISO8859-1',
+    'br_fr.iso885914':                      'br_FR.ISO8859-14',
+    'br_fr.iso885915':                      'br_FR.ISO8859-15',
+    'br_fr at euro':                           'br_FR.ISO8859-15',
+    'bulgarian':                            'bg_BG.CP1251',
+    'c':                                    'C',
+    'c-french':                             'fr_CA.ISO8859-1',
+    'c-french.iso88591':                    'fr_CA.ISO8859-1',
+    'c.en':                                 'C',
+    'c.iso88591':                           'en_US.ISO8859-1',
+    'c_c':                                  'C',
+    'c_c.c':                                'C',
+    'ca':                                   'ca_ES.ISO8859-1',
+    'ca_es':                                'ca_ES.ISO8859-1',
+    'ca_es.iso88591':                       'ca_ES.ISO8859-1',
+    'ca_es.iso885915':                      'ca_ES.ISO8859-15',
+    'ca_es at euro':                           'ca_ES.ISO8859-15',
+    'catalan':                              'ca_ES.ISO8859-1',
+    'cextend':                              'en_US.ISO8859-1',
+    'cextend.en':                           'en_US.ISO8859-1',
+    'chinese-s':                            'zh_CN.eucCN',
+    'chinese-t':                            'zh_TW.eucTW',
+    'croatian':                             'hr_HR.ISO8859-2',
+    'cs':                                   'cs_CZ.ISO8859-2',
+    'cs_cs':                                'cs_CZ.ISO8859-2',
+    'cs_cs.iso88592':                       'cs_CZ.ISO8859-2',
+    'cs_cz':                                'cs_CZ.ISO8859-2',
+    'cs_cz.iso88592':                       'cs_CZ.ISO8859-2',
+    'cy':                                   'cy_GB.ISO8859-1',
+    'cy_gb':                                'cy_GB.ISO8859-1',
+    'cy_gb.iso88591':                       'cy_GB.ISO8859-1',
+    'cy_gb.iso885914':                      'cy_GB.ISO8859-14',
+    'cy_gb.iso885915':                      'cy_GB.ISO8859-15',
+    'cy_gb at euro':                           'cy_GB.ISO8859-15',
+    'cz':                                   'cs_CZ.ISO8859-2',
+    'cz_cz':                                'cs_CZ.ISO8859-2',
+    'czech':                                'cs_CZ.ISO8859-2',
+    'da':                                   'da_DK.ISO8859-1',
+    'da_dk':                                'da_DK.ISO8859-1',
+    'da_dk.88591':                          'da_DK.ISO8859-1',
+    'da_dk.885915':                         'da_DK.ISO8859-15',
+    'da_dk.iso88591':                       'da_DK.ISO8859-1',
+    'da_dk.iso885915':                      'da_DK.ISO8859-15',
+    'da_dk at euro':                           'da_DK.ISO8859-15',
+    'danish':                               'da_DK.ISO8859-1',
+    'danish.iso88591':                      'da_DK.ISO8859-1',
+    'dansk':                                'da_DK.ISO8859-1',
+    'de':                                   'de_DE.ISO8859-1',
+    'de_at':                                'de_AT.ISO8859-1',
+    'de_at.iso88591':                       'de_AT.ISO8859-1',
+    'de_at.iso885915':                      'de_AT.ISO8859-15',
+    'de_at at euro':                           'de_AT.ISO8859-15',
+    'de_be':                                'de_BE.ISO8859-1',
+    'de_be.iso88591':                       'de_BE.ISO8859-1',
+    'de_be.iso885915':                      'de_BE.ISO8859-15',
+    'de_be at euro':                           'de_BE.ISO8859-15',
+    'de_ch':                                'de_CH.ISO8859-1',
+    'de_ch.iso88591':                       'de_CH.ISO8859-1',
+    'de_ch.iso885915':                      'de_CH.ISO8859-15',
+    'de_ch at euro':                           'de_CH.ISO8859-15',
+    'de_de':                                'de_DE.ISO8859-1',
+    'de_de.88591':                          'de_DE.ISO8859-1',
+    'de_de.885915':                         'de_DE.ISO8859-15',
+    'de_de.885915 at euro':                    'de_DE.ISO8859-15',
+    'de_de.iso88591':                       'de_DE.ISO8859-1',
+    'de_de.iso885915':                      'de_DE.ISO8859-15',
+    'de_de at euro':                           'de_DE.ISO8859-15',
+    'de_lu':                                'de_LU.ISO8859-1',
+    'de_lu.iso88591':                       'de_LU.ISO8859-1',
+    'de_lu.iso885915':                      'de_LU.ISO8859-15',
+    'de_lu at euro':                           'de_LU.ISO8859-15',
+    'deutsch':                              'de_DE.ISO8859-1',
+    'dutch':                                'nl_NL.ISO8859-1',
+    'dutch.iso88591':                       'nl_BE.ISO8859-1',
+    'ee':                                   'ee_EE.ISO8859-4',
+    'ee_ee':                                'ee_EE.ISO8859-4',
+    'ee_ee.iso88594':                       'ee_EE.ISO8859-4',
+    'eesti':                                'et_EE.ISO8859-1',
+    'el':                                   'el_GR.ISO8859-7',
+    'el_gr':                                'el_GR.ISO8859-7',
+    'el_gr.iso88597':                       'el_GR.ISO8859-7',
+    'el_gr at euro':                           'el_GR.ISO8859-15',
+    'en':                                   'en_US.ISO8859-1',
+    'en.iso88591':                          'en_US.ISO8859-1',
+    'en_au':                                'en_AU.ISO8859-1',
+    'en_au.iso88591':                       'en_AU.ISO8859-1',
+    'en_be':                                'en_BE.ISO8859-1',
+    'en_be at euro':                           'en_BE.ISO8859-15',
+    'en_bw':                                'en_BW.ISO8859-1',
+    'en_ca':                                'en_CA.ISO8859-1',
+    'en_ca.iso88591':                       'en_CA.ISO8859-1',
+    'en_gb':                                'en_GB.ISO8859-1',
+    'en_gb.88591':                          'en_GB.ISO8859-1',
+    'en_gb.iso88591':                       'en_GB.ISO8859-1',
+    'en_gb.iso885915':                      'en_GB.ISO8859-15',
+    'en_gb at euro':                           'en_GB.ISO8859-15',
+    'en_hk':                                'en_HK.ISO8859-1',
+    'en_ie':                                'en_IE.ISO8859-1',
+    'en_ie.iso88591':                       'en_IE.ISO8859-1',
+    'en_ie.iso885915':                      'en_IE.ISO8859-15',
+    'en_ie at euro':                           'en_IE.ISO8859-15',
+    'en_in':                                'en_IN.ISO8859-1',
+    'en_nz':                                'en_NZ.ISO8859-1',
+    'en_nz.iso88591':                       'en_NZ.ISO8859-1',
+    'en_ph':                                'en_PH.ISO8859-1',
+    'en_sg':                                'en_SG.ISO8859-1',
+    'en_uk':                                'en_GB.ISO8859-1',
+    'en_us':                                'en_US.ISO8859-1',
+    'en_us.88591':                          'en_US.ISO8859-1',
+    'en_us.885915':                         'en_US.ISO8859-15',
+    'en_us.iso88591':                       'en_US.ISO8859-1',
+    'en_us.iso885915':                      'en_US.ISO8859-15',
+    'en_us.iso885915 at euro':                 'en_US.ISO8859-15',
+    'en_us at euro':                           'en_US.ISO8859-15',
+    'en_us at euro@euro':                      'en_US.ISO8859-15',
+    'en_za':                                'en_ZA.ISO8859-1',
+    'en_za.88591':                          'en_ZA.ISO8859-1',
+    'en_za.iso88591':                       'en_ZA.ISO8859-1',
+    'en_za.iso885915':                      'en_ZA.ISO8859-15',
+    'en_za at euro':                           'en_ZA.ISO8859-15',
+    'en_zw':                                'en_ZW.ISO8859-1',
+    'eng_gb':                               'en_GB.ISO8859-1',
+    'eng_gb.8859':                          'en_GB.ISO8859-1',
+    'english':                              'en_EN.ISO8859-1',
+    'english.iso88591':                     'en_EN.ISO8859-1',
+    'english_uk':                           'en_GB.ISO8859-1',
+    'english_uk.8859':                      'en_GB.ISO8859-1',
+    'english_united-states':                'en_US.ISO8859-1',
+    'english_united-states.437':            'C',
+    'english_us':                           'en_US.ISO8859-1',
+    'english_us.8859':                      'en_US.ISO8859-1',
+    'english_us.ascii':                     'en_US.ISO8859-1',
+    'eo':                                   'eo_XX.ISO8859-3',
+    'eo_eo':                                'eo_EO.ISO8859-3',
+    'eo_eo.iso88593':                       'eo_EO.ISO8859-3',
+    'eo_xx':                                'eo_XX.ISO8859-3',
+    'eo_xx.iso88593':                       'eo_XX.ISO8859-3',
+    'es':                                   'es_ES.ISO8859-1',
+    'es_ar':                                'es_AR.ISO8859-1',
+    'es_ar.iso88591':                       'es_AR.ISO8859-1',
+    'es_bo':                                'es_BO.ISO8859-1',
+    'es_bo.iso88591':                       'es_BO.ISO8859-1',
+    'es_cl':                                'es_CL.ISO8859-1',
+    'es_cl.iso88591':                       'es_CL.ISO8859-1',
+    'es_co':                                'es_CO.ISO8859-1',
+    'es_co.iso88591':                       'es_CO.ISO8859-1',
+    'es_cr':                                'es_CR.ISO8859-1',
+    'es_cr.iso88591':                       'es_CR.ISO8859-1',
+    'es_do':                                'es_DO.ISO8859-1',
+    'es_do.iso88591':                       'es_DO.ISO8859-1',
+    'es_ec':                                'es_EC.ISO8859-1',
+    'es_ec.iso88591':                       'es_EC.ISO8859-1',
+    'es_es':                                'es_ES.ISO8859-1',
+    'es_es.88591':                          'es_ES.ISO8859-1',
+    'es_es.iso88591':                       'es_ES.ISO8859-1',
+    'es_es.iso885915':                      'es_ES.ISO8859-15',
+    'es_es at euro':                           'es_ES.ISO8859-15',
+    'es_gt':                                'es_GT.ISO8859-1',
+    'es_gt.iso88591':                       'es_GT.ISO8859-1',
+    'es_hn':                                'es_HN.ISO8859-1',
+    'es_hn.iso88591':                       'es_HN.ISO8859-1',
+    'es_mx':                                'es_MX.ISO8859-1',
+    'es_mx.iso88591':                       'es_MX.ISO8859-1',
+    'es_ni':                                'es_NI.ISO8859-1',
+    'es_ni.iso88591':                       'es_NI.ISO8859-1',
+    'es_pa':                                'es_PA.ISO8859-1',
+    'es_pa.iso88591':                       'es_PA.ISO8859-1',
+    'es_pa.iso885915':                      'es_PA.ISO8859-15',
+    'es_pa at euro':                           'es_PA.ISO8859-15',
+    'es_pe':                                'es_PE.ISO8859-1',
+    'es_pe.iso88591':                       'es_PE.ISO8859-1',
+    'es_pe.iso885915':                      'es_PE.ISO8859-15',
+    'es_pe at euro':                           'es_PE.ISO8859-15',
+    'es_pr':                                'es_PR.ISO8859-1',
+    'es_pr.iso88591':                       'es_PR.ISO8859-1',
+    'es_py':                                'es_PY.ISO8859-1',
+    'es_py.iso88591':                       'es_PY.ISO8859-1',
+    'es_py.iso885915':                      'es_PY.ISO8859-15',
+    'es_py at euro':                           'es_PY.ISO8859-15',
+    'es_sv':                                'es_SV.ISO8859-1',
+    'es_sv.iso88591':                       'es_SV.ISO8859-1',
+    'es_sv.iso885915':                      'es_SV.ISO8859-15',
+    'es_sv at euro':                           'es_SV.ISO8859-15',
+    'es_us':                                'es_US.ISO8859-1',
+    'es_uy':                                'es_UY.ISO8859-1',
+    'es_uy.iso88591':                       'es_UY.ISO8859-1',
+    'es_uy.iso885915':                      'es_UY.ISO8859-15',
+    'es_uy at euro':                           'es_UY.ISO8859-15',
+    'es_ve':                                'es_VE.ISO8859-1',
+    'es_ve.iso88591':                       'es_VE.ISO8859-1',
+    'es_ve.iso885915':                      'es_VE.ISO8859-15',
+    'es_ve at euro':                           'es_VE.ISO8859-15',
+    'estonian':                             'et_EE.ISO8859-1',
+    'et':                                   'et_EE.ISO8859-15',
+    'et_ee':                                'et_EE.ISO8859-15',
+    'et_ee.iso88591':                       'et_EE.ISO8859-1',
+    'et_ee.iso885913':                      'et_EE.ISO8859-13',
+    'et_ee.iso885915':                      'et_EE.ISO8859-15',
+    'et_ee.iso88594':                       'et_EE.ISO8859-4',
+    'et_ee at euro':                           'et_EE.ISO8859-15',
+    'eu':                                   'eu_ES.ISO8859-1',
+    'eu_es':                                'eu_ES.ISO8859-1',
+    'eu_es.iso88591':                       'eu_ES.ISO8859-1',
+    'eu_es.iso885915':                      'eu_ES.ISO8859-15',
+    'eu_es at euro':                           'eu_ES.ISO8859-15',
+    'fa':                                   'fa_IR.UTF-8',
+    'fa_ir':                                'fa_IR.UTF-8',
+    'fa_ir.isiri3342':                      'fa_IR.ISIRI-3342',
+    'fi':                                   'fi_FI.ISO8859-15',
+    'fi_fi':                                'fi_FI.ISO8859-15',
+    'fi_fi.88591':                          'fi_FI.ISO8859-1',
+    'fi_fi.iso88591':                       'fi_FI.ISO8859-1',
+    'fi_fi.iso885915':                      'fi_FI.ISO8859-15',
+    'fi_fi.utf8 at euro':                      'fi_FI.UTF-8',
+    'fi_fi at euro':                           'fi_FI.ISO8859-15',
+    'finnish':                              'fi_FI.ISO8859-1',
+    'finnish.iso88591':                     'fi_FI.ISO8859-1',
+    'fo':                                   'fo_FO.ISO8859-1',
+    'fo_fo':                                'fo_FO.ISO8859-1',
+    'fo_fo.iso88591':                       'fo_FO.ISO8859-1',
+    'fo_fo.iso885915':                      'fo_FO.ISO8859-15',
+    'fo_fo at euro':                           'fo_FO.ISO8859-15',
+    'fr':                                   'fr_FR.ISO8859-1',
+    'fr_be':                                'fr_BE.ISO8859-1',
+    'fr_be.88591':                          'fr_BE.ISO8859-1',
+    'fr_be.iso88591':                       'fr_BE.ISO8859-1',
+    'fr_be.iso885915':                      'fr_BE.ISO8859-15',
+    'fr_be at euro':                           'fr_BE.ISO8859-15',
+    'fr_ca':                                'fr_CA.ISO8859-1',
+    'fr_ca.88591':                          'fr_CA.ISO8859-1',
+    'fr_ca.iso88591':                       'fr_CA.ISO8859-1',
+    'fr_ca.iso885915':                      'fr_CA.ISO8859-15',
+    'fr_ca at euro':                           'fr_CA.ISO8859-15',
+    'fr_ch':                                'fr_CH.ISO8859-1',
+    'fr_ch.88591':                          'fr_CH.ISO8859-1',
+    'fr_ch.iso88591':                       'fr_CH.ISO8859-1',
+    'fr_ch.iso885915':                      'fr_CH.ISO8859-15',
+    'fr_ch at euro':                           'fr_CH.ISO8859-15',
+    'fr_fr':                                'fr_FR.ISO8859-1',
+    'fr_fr.88591':                          'fr_FR.ISO8859-1',
+    'fr_fr.iso88591':                       'fr_FR.ISO8859-1',
+    'fr_fr.iso885915':                      'fr_FR.ISO8859-15',
+    'fr_fr at euro':                           'fr_FR.ISO8859-15',
+    'fr_lu':                                'fr_LU.ISO8859-1',
+    'fr_lu.88591':                          'fr_LU.ISO8859-1',
+    'fr_lu.iso88591':                       'fr_LU.ISO8859-1',
+    'fr_lu.iso885915':                      'fr_LU.ISO8859-15',
+    'fr_lu at euro':                           'fr_LU.ISO8859-15',
+    'fran\xe7ais':                          'fr_FR.ISO8859-1',
+    'fre_fr':                               'fr_FR.ISO8859-1',
+    'fre_fr.8859':                          'fr_FR.ISO8859-1',
+    'french':                               'fr_FR.ISO8859-1',
+    'french.iso88591':                      'fr_CH.ISO8859-1',
+    'french_france':                        'fr_FR.ISO8859-1',
+    'french_france.8859':                   'fr_FR.ISO8859-1',
+    'ga':                                   'ga_IE.ISO8859-1',
+    'ga_ie':                                'ga_IE.ISO8859-1',
+    'ga_ie.iso88591':                       'ga_IE.ISO8859-1',
+    'ga_ie.iso885914':                      'ga_IE.ISO8859-14',
+    'ga_ie.iso885915':                      'ga_IE.ISO8859-15',
+    'ga_ie at euro':                           'ga_IE.ISO8859-15',
+    'galego':                               'gl_ES.ISO8859-1',
+    'galician':                             'gl_ES.ISO8859-1',
+    'gd':                                   'gd_GB.ISO8859-1',
+    'gd_gb':                                'gd_GB.ISO8859-1',
+    'gd_gb.iso88591':                       'gd_GB.ISO8859-1',
+    'gd_gb.iso885914':                      'gd_GB.ISO8859-14',
+    'gd_gb.iso885915':                      'gd_GB.ISO8859-15',
+    'gd_gb at euro':                           'gd_GB.ISO8859-15',
+    'ger_de':                               'de_DE.ISO8859-1',
+    'ger_de.8859':                          'de_DE.ISO8859-1',
+    'german':                               'de_DE.ISO8859-1',
+    'german.iso88591':                      'de_CH.ISO8859-1',
+    'german_germany':                       'de_DE.ISO8859-1',
+    'german_germany.8859':                  'de_DE.ISO8859-1',
+    'gl':                                   'gl_ES.ISO8859-1',
+    'gl_es':                                'gl_ES.ISO8859-1',
+    'gl_es.iso88591':                       'gl_ES.ISO8859-1',
+    'gl_es.iso885915':                      'gl_ES.ISO8859-15',
+    'gl_es at euro':                           'gl_ES.ISO8859-15',
+    'greek':                                'el_GR.ISO8859-7',
+    'greek.iso88597':                       'el_GR.ISO8859-7',
+    'gv':                                   'gv_GB.ISO8859-1',
+    'gv_gb':                                'gv_GB.ISO8859-1',
+    'gv_gb.iso88591':                       'gv_GB.ISO8859-1',
+    'gv_gb.iso885914':                      'gv_GB.ISO8859-14',
+    'gv_gb.iso885915':                      'gv_GB.ISO8859-15',
+    'gv_gb at euro':                           'gv_GB.ISO8859-15',
+    'he':                                   'he_IL.ISO8859-8',
+    'he_il':                                'he_IL.ISO8859-8',
+    'he_il.cp1255':                         'he_IL.CP1255',
+    'he_il.iso88598':                       'he_IL.ISO8859-8',
+    'he_il.microsoftcp1255':                'he_IL.CP1255',
+    'hebrew':                               'iw_IL.ISO8859-8',
+    'hebrew.iso88598':                      'iw_IL.ISO8859-8',
+    'hi':                                   'hi_IN.ISCII-DEV',
+    'hi_in':                                'hi_IN.ISCII-DEV',
+    'hi_in.isciidev':                       'hi_IN.ISCII-DEV',
+    'hr':                                   'hr_HR.ISO8859-2',
+    'hr_hr':                                'hr_HR.ISO8859-2',
+    'hr_hr.iso88592':                       'hr_HR.ISO8859-2',
+    'hrvatski':                             'hr_HR.ISO8859-2',
+    'hu':                                   'hu_HU.ISO8859-2',
+    'hu_hu':                                'hu_HU.ISO8859-2',
+    'hu_hu.iso88592':                       'hu_HU.ISO8859-2',
+    'hungarian':                            'hu_HU.ISO8859-2',
+    'icelandic':                            'is_IS.ISO8859-1',
+    'icelandic.iso88591':                   'is_IS.ISO8859-1',
+    'id':                                   'id_ID.ISO8859-1',
+    'id_id':                                'id_ID.ISO8859-1',
+    'in':                                   'id_ID.ISO8859-1',
+    'in_id':                                'id_ID.ISO8859-1',
+    'is':                                   'is_IS.ISO8859-1',
+    'is_is':                                'is_IS.ISO8859-1',
+    'is_is.iso88591':                       'is_IS.ISO8859-1',
+    'is_is.iso885915':                      'is_IS.ISO8859-15',
+    'is_is at euro':                           'is_IS.ISO8859-15',
+    'iso-8859-1':                           'en_US.ISO8859-1',
+    'iso-8859-15':                          'en_US.ISO8859-15',
+    'iso8859-1':                            'en_US.ISO8859-1',
+    'iso8859-15':                           'en_US.ISO8859-15',
+    'iso_8859_1':                           'en_US.ISO8859-1',
+    'iso_8859_15':                          'en_US.ISO8859-15',
+    'it':                                   'it_IT.ISO8859-1',
+    'it_ch':                                'it_CH.ISO8859-1',
+    'it_ch.iso88591':                       'it_CH.ISO8859-1',
+    'it_ch.iso885915':                      'it_CH.ISO8859-15',
+    'it_ch at euro':                           'it_CH.ISO8859-15',
+    'it_it':                                'it_IT.ISO8859-1',
+    'it_it.88591':                          'it_IT.ISO8859-1',
+    'it_it.iso88591':                       'it_IT.ISO8859-1',
+    'it_it.iso885915':                      'it_IT.ISO8859-15',
+    'it_it at euro':                           'it_IT.ISO8859-15',
+    'italian':                              'it_IT.ISO8859-1',
+    'italian.iso88591':                     'it_IT.ISO8859-1',
+    'iu':                                   'iu_CA.NUNACOM-8',
+    'iu_ca':                                'iu_CA.NUNACOM-8',
+    'iu_ca.nunacom8':                       'iu_CA.NUNACOM-8',
+    'iw':                                   'he_IL.ISO8859-8',
+    'iw_il':                                'he_IL.ISO8859-8',
+    'iw_il.iso88598':                       'he_IL.ISO8859-8',
+    'ja':                                   'ja_JP.eucJP',
+    'ja.jis':                               'ja_JP.JIS7',
+    'ja.sjis':                              'ja_JP.SJIS',
+    'ja_jp':                                'ja_JP.eucJP',
+    'ja_jp.ajec':                           'ja_JP.eucJP',
+    'ja_jp.euc':                            'ja_JP.eucJP',
+    'ja_jp.eucjp':                          'ja_JP.eucJP',
+    'ja_jp.iso-2022-jp':                    'ja_JP.JIS7',
+    'ja_jp.iso2022jp':                      'ja_JP.JIS7',
+    'ja_jp.jis':                            'ja_JP.JIS7',
+    'ja_jp.jis7':                           'ja_JP.JIS7',
+    'ja_jp.mscode':                         'ja_JP.SJIS',
+    'ja_jp.sjis':                           'ja_JP.SJIS',
+    'ja_jp.ujis':                           'ja_JP.eucJP',
+    'japan':                                'ja_JP.eucJP',
+    'japanese':                             'ja_JP.eucJP',
+    'japanese-euc':                         'ja_JP.eucJP',
+    'japanese.euc':                         'ja_JP.eucJP',
+    'japanese.sjis':                        'ja_JP.SJIS',
+    'jp_jp':                                'ja_JP.eucJP',
+    'ka':                                   'ka_GE.GEORGIAN-ACADEMY',
+    'ka_ge':                                'ka_GE.GEORGIAN-ACADEMY',
+    'ka_ge.georgianacademy':                'ka_GE.GEORGIAN-ACADEMY',
+    'ka_ge.georgianps':                     'ka_GE.GEORGIAN-PS',
+    'ka_ge.georgianrs':                     'ka_GE.GEORGIAN-ACADEMY',
+    'kl':                                   'kl_GL.ISO8859-1',
+    'kl_gl':                                'kl_GL.ISO8859-1',
+    'kl_gl.iso88591':                       'kl_GL.ISO8859-1',
+    'kl_gl.iso885915':                      'kl_GL.ISO8859-15',
+    'kl_gl at euro':                           'kl_GL.ISO8859-15',
+    'ko':                                   'ko_KR.eucKR',
+    'ko_kr':                                'ko_KR.eucKR',
+    'ko_kr.euc':                            'ko_KR.eucKR',
+    'ko_kr.euckr':                          'ko_KR.eucKR',
+    'korean':                               'ko_KR.eucKR',
+    'korean.euc':                           'ko_KR.eucKR',
+    'kw':                                   'kw_GB.ISO8859-1',
+    'kw_gb':                                'kw_GB.ISO8859-1',
+    'kw_gb.iso88591':                       'kw_GB.ISO8859-1',
+    'kw_gb.iso885914':                      'kw_GB.ISO8859-14',
+    'kw_gb.iso885915':                      'kw_GB.ISO8859-15',
+    'kw_gb at euro':                           'kw_GB.ISO8859-15',
+    'lithuanian':                           'lt_LT.ISO8859-13',
+    'lo':                                   'lo_LA.MULELAO-1',
+    'lo_la':                                'lo_LA.MULELAO-1',
+    'lo_la.cp1133':                         'lo_LA.IBM-CP1133',
+    'lo_la.ibmcp1133':                      'lo_LA.IBM-CP1133',
+    'lo_la.mulelao1':                       'lo_LA.MULELAO-1',
+    'lt':                                   'lt_LT.ISO8859-13',
+    'lt_lt':                                'lt_LT.ISO8859-13',
+    'lt_lt.iso885913':                      'lt_LT.ISO8859-13',
+    'lt_lt.iso88594':                       'lt_LT.ISO8859-4',
+    'lv':                                   'lv_LV.ISO8859-13',
+    'lv_lv':                                'lv_LV.ISO8859-13',
+    'lv_lv.iso885913':                      'lv_LV.ISO8859-13',
+    'lv_lv.iso88594':                       'lv_LV.ISO8859-4',
+    'mi':                                   'mi_NZ.ISO8859-1',
+    'mi_nz':                                'mi_NZ.ISO8859-1',
+    'mi_nz.iso88591':                       'mi_NZ.ISO8859-1',
+    'mk':                                   'mk_MK.ISO8859-5',
+    'mk_mk':                                'mk_MK.ISO8859-5',
+    'mk_mk.cp1251':                         'mk_MK.CP1251',
+    'mk_mk.iso88595':                       'mk_MK.ISO8859-5',
+    'mk_mk.microsoftcp1251':                'mk_MK.CP1251',
+    'ms':                                   'ms_MY.ISO8859-1',
+    'ms_my':                                'ms_MY.ISO8859-1',
+    'ms_my.iso88591':                       'ms_MY.ISO8859-1',
+    'mt':                                   'mt_MT.ISO8859-3',
+    'mt_mt':                                'mt_MT.ISO8859-3',
+    'mt_mt.iso88593':                       'mt_MT.ISO8859-3',
+    'nb':                                   'nb_NO.ISO8859-1',
+    'nb_no':                                'nb_NO.ISO8859-1',
+    'nb_no.88591':                          'nb_NO.ISO8859-1',
+    'nb_no.iso88591':                       'nb_NO.ISO8859-1',
+    'nb_no.iso885915':                      'nb_NO.ISO8859-15',
+    'nb_no at euro':                           'nb_NO.ISO8859-15',
+    'nl':                                   'nl_NL.ISO8859-1',
+    'nl_be':                                'nl_BE.ISO8859-1',
+    'nl_be.88591':                          'nl_BE.ISO8859-1',
+    'nl_be.iso88591':                       'nl_BE.ISO8859-1',
+    'nl_be.iso885915':                      'nl_BE.ISO8859-15',
+    'nl_be at euro':                           'nl_BE.ISO8859-15',
+    'nl_nl':                                'nl_NL.ISO8859-1',
+    'nl_nl.88591':                          'nl_NL.ISO8859-1',
+    'nl_nl.iso88591':                       'nl_NL.ISO8859-1',
+    'nl_nl.iso885915':                      'nl_NL.ISO8859-15',
+    'nl_nl at euro':                           'nl_NL.ISO8859-15',
+    'nn':                                   'nn_NO.ISO8859-1',
+    'nn_no':                                'nn_NO.ISO8859-1',
+    'nn_no.88591':                          'nn_NO.ISO8859-1',
+    'nn_no.iso88591':                       'nn_NO.ISO8859-1',
+    'nn_no.iso885915':                      'nn_NO.ISO8859-15',
+    'nn_no at euro':                           'nn_NO.ISO8859-15',
+    'no':                                   'no_NO.ISO8859-1',
+    'no at nynorsk':                           'ny_NO.ISO8859-1',
+    'no_no':                                'no_NO.ISO8859-1',
+    'no_no.88591':                          'no_NO.ISO8859-1',
+    'no_no.iso88591':                       'no_NO.ISO8859-1',
+    'no_no.iso885915':                      'no_NO.ISO8859-15',
+    'no_no at euro':                           'no_NO.ISO8859-15',
+    'norwegian':                            'no_NO.ISO8859-1',
+    'norwegian.iso88591':                   'no_NO.ISO8859-1',
+    'ny':                                   'ny_NO.ISO8859-1',
+    'ny_no':                                'ny_NO.ISO8859-1',
+    'ny_no.88591':                          'ny_NO.ISO8859-1',
+    'ny_no.iso88591':                       'ny_NO.ISO8859-1',
+    'ny_no.iso885915':                      'ny_NO.ISO8859-15',
+    'ny_no at euro':                           'ny_NO.ISO8859-15',
+    'nynorsk':                              'nn_NO.ISO8859-1',
+    'oc':                                   'oc_FR.ISO8859-1',
+    'oc_fr':                                'oc_FR.ISO8859-1',
+    'oc_fr.iso88591':                       'oc_FR.ISO8859-1',
+    'oc_fr.iso885915':                      'oc_FR.ISO8859-15',
+    'oc_fr at euro':                           'oc_FR.ISO8859-15',
+    'pd':                                   'pd_US.ISO8859-1',
+    'pd_de':                                'pd_DE.ISO8859-1',
+    'pd_de.iso88591':                       'pd_DE.ISO8859-1',
+    'pd_de.iso885915':                      'pd_DE.ISO8859-15',
+    'pd_de at euro':                           'pd_DE.ISO8859-15',
+    'pd_us':                                'pd_US.ISO8859-1',
+    'pd_us.iso88591':                       'pd_US.ISO8859-1',
+    'pd_us.iso885915':                      'pd_US.ISO8859-15',
+    'pd_us at euro':                           'pd_US.ISO8859-15',
+    'ph':                                   'ph_PH.ISO8859-1',
+    'ph_ph':                                'ph_PH.ISO8859-1',
+    'ph_ph.iso88591':                       'ph_PH.ISO8859-1',
+    'pl':                                   'pl_PL.ISO8859-2',
+    'pl_pl':                                'pl_PL.ISO8859-2',
+    'pl_pl.iso88592':                       'pl_PL.ISO8859-2',
+    'polish':                               'pl_PL.ISO8859-2',
+    'portuguese':                           'pt_PT.ISO8859-1',
+    'portuguese.iso88591':                  'pt_PT.ISO8859-1',
+    'portuguese_brazil':                    'pt_BR.ISO8859-1',
+    'portuguese_brazil.8859':               'pt_BR.ISO8859-1',
+    'posix':                                'C',
+    'posix-utf2':                           'C',
+    'pp':                                   'pp_AN.ISO8859-1',
+    'pp_an':                                'pp_AN.ISO8859-1',
+    'pp_an.iso88591':                       'pp_AN.ISO8859-1',
+    'pt':                                   'pt_PT.ISO8859-1',
+    'pt_br':                                'pt_BR.ISO8859-1',
+    'pt_br.88591':                          'pt_BR.ISO8859-1',
+    'pt_br.iso88591':                       'pt_BR.ISO8859-1',
+    'pt_br.iso885915':                      'pt_BR.ISO8859-15',
+    'pt_br at euro':                           'pt_BR.ISO8859-15',
+    'pt_pt':                                'pt_PT.ISO8859-1',
+    'pt_pt.88591':                          'pt_PT.ISO8859-1',
+    'pt_pt.iso88591':                       'pt_PT.ISO8859-1',
+    'pt_pt.iso885915':                      'pt_PT.ISO8859-15',
+    'pt_pt.utf8 at euro':                      'pt_PT.UTF-8',
+    'pt_pt at euro':                           'pt_PT.ISO8859-15',
+    'ro':                                   'ro_RO.ISO8859-2',
+    'ro_ro':                                'ro_RO.ISO8859-2',
+    'ro_ro.iso88592':                       'ro_RO.ISO8859-2',
+    'romanian':                             'ro_RO.ISO8859-2',
+    'ru':                                   'ru_RU.ISO8859-5',
+    'ru_ru':                                'ru_RU.ISO8859-5',
+    'ru_ru.cp1251':                         'ru_RU.CP1251',
+    'ru_ru.iso88595':                       'ru_RU.ISO8859-5',
+    'ru_ru.koi8r':                          'ru_RU.KOI8-R',
+    'ru_ru.microsoftcp1251':                'ru_RU.CP1251',
+    'ru_ua':                                'ru_UA.KOI8-U',
+    'ru_ua.cp1251':                         'ru_UA.CP1251',
+    'ru_ua.koi8u':                          'ru_UA.KOI8-U',
+    'ru_ua.microsoftcp1251':                'ru_UA.CP1251',
+    'rumanian':                             'ro_RO.ISO8859-2',
+    'russian':                              'ru_RU.ISO8859-5',
+    'se_no':                                'se_NO.UTF-8',
+    'serbocroatian':                        'sh_YU.ISO8859-2',
+    'sh':                                   'sh_YU.ISO8859-2',
+    'sh_hr':                                'sh_HR.ISO8859-2',
+    'sh_hr.iso88592':                       'sh_HR.ISO8859-2',
+    'sh_sp':                                'sh_YU.ISO8859-2',
+    'sh_yu':                                'sh_YU.ISO8859-2',
+    'sk':                                   'sk_SK.ISO8859-2',
+    'sk_sk':                                'sk_SK.ISO8859-2',
+    'sk_sk.iso88592':                       'sk_SK.ISO8859-2',
+    'sl':                                   'sl_SI.ISO8859-2',
+    'sl_cs':                                'sl_CS.ISO8859-2',
+    'sl_si':                                'sl_SI.ISO8859-2',
+    'sl_si.iso88592':                       'sl_SI.ISO8859-2',
+    'slovak':                               'sk_SK.ISO8859-2',
+    'slovene':                              'sl_SI.ISO8859-2',
+    'slovenian':                            'sl_SI.ISO8859-2',
+    'sp':                                   'sp_YU.ISO8859-5',
+    'sp_yu':                                'sp_YU.ISO8859-5',
+    'spanish':                              'es_ES.ISO8859-1',
+    'spanish.iso88591':                     'es_ES.ISO8859-1',
+    'spanish_spain':                        'es_ES.ISO8859-1',
+    'spanish_spain.8859':                   'es_ES.ISO8859-1',
+    'sq':                                   'sq_AL.ISO8859-2',
+    'sq_al':                                'sq_AL.ISO8859-2',
+    'sq_al.iso88592':                       'sq_AL.ISO8859-2',
+    'sr':                                   'sr_YU.ISO8859-5',
+    'sr at cyrillic':                          'sr_YU.ISO8859-5',
+    'sr_sp':                                'sr_SP.ISO8859-2',
+    'sr_yu':                                'sr_YU.ISO8859-5',
+    'sr_yu.cp1251 at cyrillic':                'sr_YU.CP1251',
+    'sr_yu.iso88592':                       'sr_YU.ISO8859-2',
+    'sr_yu.iso88595':                       'sr_YU.ISO8859-5',
+    'sr_yu.iso88595 at cyrillic':              'sr_YU.ISO8859-5',
+    'sr_yu.microsoftcp1251 at cyrillic':       'sr_YU.CP1251',
+    'sr_yu.utf8 at cyrillic':                  'sr_YU.UTF-8',
+    'sr_yu at cyrillic':                       'sr_YU.ISO8859-5',
+    'sv':                                   'sv_SE.ISO8859-1',
+    'sv_fi':                                'sv_FI.ISO8859-1',
+    'sv_fi.iso88591':                       'sv_FI.ISO8859-1',
+    'sv_fi.iso885915':                      'sv_FI.ISO8859-15',
+    'sv_fi at euro':                           'sv_FI.ISO8859-15',
+    'sv_se':                                'sv_SE.ISO8859-1',
+    'sv_se.88591':                          'sv_SE.ISO8859-1',
+    'sv_se.iso88591':                       'sv_SE.ISO8859-1',
+    'sv_se.iso885915':                      'sv_SE.ISO8859-15',
+    'sv_se at euro':                           'sv_SE.ISO8859-15',
+    'swedish':                              'sv_SE.ISO8859-1',
+    'swedish.iso88591':                     'sv_SE.ISO8859-1',
+    'ta':                                   'ta_IN.TSCII-0',
+    'ta_in':                                'ta_IN.TSCII-0',
+    'ta_in.tscii':                          'ta_IN.TSCII-0',
+    'ta_in.tscii0':                         'ta_IN.TSCII-0',
+    'tg':                                   'tg_TJ.KOI8-C',
+    'tg_tj':                                'tg_TJ.KOI8-C',
+    'tg_tj.koi8c':                          'tg_TJ.KOI8-C',
+    'th':                                   'th_TH.ISO8859-11',
+    'th_th':                                'th_TH.ISO8859-11',
+    'th_th.iso885911':                      'th_TH.ISO8859-11',
+    'th_th.tactis':                         'th_TH.TIS620',
+    'th_th.tis620':                         'th_TH.TIS620',
+    'thai':                                 'th_TH.ISO8859-11',
+    'tl':                                   'tl_PH.ISO8859-1',
+    'tl_ph':                                'tl_PH.ISO8859-1',
+    'tl_ph.iso88591':                       'tl_PH.ISO8859-1',
+    'tr':                                   'tr_TR.ISO8859-9',
+    'tr_tr':                                'tr_TR.ISO8859-9',
+    'tr_tr.iso88599':                       'tr_TR.ISO8859-9',
+    'tt':                                   'tt_RU.TATAR-CYR',
+    'tt_ru':                                'tt_RU.TATAR-CYR',
+    'tt_ru.koi8c':                          'tt_RU.KOI8-C',
+    'tt_ru.tatarcyr':                       'tt_RU.TATAR-CYR',
+    'turkish':                              'tr_TR.ISO8859-9',
+    'turkish.iso88599':                     'tr_TR.ISO8859-9',
+    'uk':                                   'uk_UA.KOI8-U',
+    'uk_ua':                                'uk_UA.KOI8-U',
+    'uk_ua.cp1251':                         'uk_UA.CP1251',
+    'uk_ua.iso88595':                       'uk_UA.ISO8859-5',
+    'uk_ua.koi8u':                          'uk_UA.KOI8-U',
+    'uk_ua.microsoftcp1251':                'uk_UA.CP1251',
+    'univ':                                 'en_US.utf',
+    'universal':                            'en_US.utf',
+    'universal.utf8 at ucs4':                  'en_US.UTF-8',
+    'ur':                                   'ur_PK.CP1256',
+    'ur_pk':                                'ur_PK.CP1256',
+    'ur_pk.cp1256':                         'ur_PK.CP1256',
+    'ur_pk.microsoftcp1256':                'ur_PK.CP1256',
+    'uz':                                   'uz_UZ.UTF-8',
+    'uz_uz':                                'uz_UZ.UTF-8',
+    'vi':                                   'vi_VN.TCVN',
+    'vi_vn':                                'vi_VN.TCVN',
+    'vi_vn.tcvn':                           'vi_VN.TCVN',
+    'vi_vn.tcvn5712':                       'vi_VN.TCVN',
+    'vi_vn.viscii':                         'vi_VN.VISCII',
+    'vi_vn.viscii111':                      'vi_VN.VISCII',
+    'wa':                                   'wa_BE.ISO8859-1',
+    'wa_be':                                'wa_BE.ISO8859-1',
+    'wa_be.iso88591':                       'wa_BE.ISO8859-1',
+    'wa_be.iso885915':                      'wa_BE.ISO8859-15',
+    'wa_be at euro':                           'wa_BE.ISO8859-15',
+    'yi':                                   'yi_US.CP1255',
+    'yi_us':                                'yi_US.CP1255',
+    'yi_us.cp1255':                         'yi_US.CP1255',
+    'yi_us.microsoftcp1255':                'yi_US.CP1255',
+    'zh':                                   'zh_CN.eucCN',
+    'zh_cn':                                'zh_CN.gb2312',
+    'zh_cn.big5':                           'zh_TW.big5',
+    'zh_cn.euc':                            'zh_CN.eucCN',
+    'zh_cn.gb18030':                        'zh_CN.gb18030',
+    'zh_cn.gb2312':                         'zh_CN.gb2312',
+    'zh_cn.gbk':                            'zh_CN.gbk',
+    'zh_hk':                                'zh_HK.big5hkscs',
+    'zh_hk.big5':                           'zh_HK.big5',
+    'zh_hk.big5hkscs':                      'zh_HK.big5hkscs',
+    'zh_tw':                                'zh_TW.big5',
+    'zh_tw.big5':                           'zh_TW.big5',
+    'zh_tw.euc':                            'zh_TW.eucTW',
+}
+
+#
+# This maps Windows language identifiers to locale strings.
+#
+# This list has been updated from
+# http://msdn.microsoft.com/library/default.asp?url=/library/en-us/intl/nls_238z.asp
+# to include every locale up to Windows XP.
+#
+# NOTE: this mapping is incomplete.  If your language is missing, please
+# submit a bug report to Python bug manager, which you can find via:
+#     http://www.python.org/dev/
+# Make sure you include the missing language identifier and the suggested
+# locale code.
+#
+
+windows_locale = {
+    0x0436: "af_ZA", # Afrikaans
+    0x041c: "sq_AL", # Albanian
+    0x0401: "ar_SA", # Arabic - Saudi Arabia
+    0x0801: "ar_IQ", # Arabic - Iraq
+    0x0c01: "ar_EG", # Arabic - Egypt
+    0x1001: "ar_LY", # Arabic - Libya
+    0x1401: "ar_DZ", # Arabic - Algeria
+    0x1801: "ar_MA", # Arabic - Morocco
+    0x1c01: "ar_TN", # Arabic - Tunisia
+    0x2001: "ar_OM", # Arabic - Oman
+    0x2401: "ar_YE", # Arabic - Yemen
+    0x2801: "ar_SY", # Arabic - Syria
+    0x2c01: "ar_JO", # Arabic - Jordan
+    0x3001: "ar_LB", # Arabic - Lebanon
+    0x3401: "ar_KW", # Arabic - Kuwait
+    0x3801: "ar_AE", # Arabic - United Arab Emirates
+    0x3c01: "ar_BH", # Arabic - Bahrain
+    0x4001: "ar_QA", # Arabic - Qatar
+    0x042b: "hy_AM", # Armenian
+    0x042c: "az_AZ", # Azeri Latin
+    0x082c: "az_AZ", # Azeri - Cyrillic
+    0x042d: "eu_ES", # Basque
+    0x0423: "be_BY", # Belarusian
+    0x0445: "bn_IN", # Begali
+    0x201a: "bs_BA", # Bosnian
+    0x141a: "bs_BA", # Bosnian - Cyrillic
+    0x047e: "br_FR", # Breton - France
+    0x0402: "bg_BG", # Bulgarian
+    0x0403: "ca_ES", # Catalan
+    0x0004: "zh_CHS",# Chinese - Simplified
+    0x0404: "zh_TW", # Chinese - Taiwan
+    0x0804: "zh_CN", # Chinese - PRC
+    0x0c04: "zh_HK", # Chinese - Hong Kong S.A.R.
+    0x1004: "zh_SG", # Chinese - Singapore
+    0x1404: "zh_MO", # Chinese - Macao S.A.R.
+    0x7c04: "zh_CHT",# Chinese - Traditional
+    0x041a: "hr_HR", # Croatian
+    0x101a: "hr_BA", # Croatian - Bosnia
+    0x0405: "cs_CZ", # Czech
+    0x0406: "da_DK", # Danish
+    0x048c: "gbz_AF",# Dari - Afghanistan
+    0x0465: "div_MV",# Divehi - Maldives
+    0x0413: "nl_NL", # Dutch - The Netherlands
+    0x0813: "nl_BE", # Dutch - Belgium
+    0x0409: "en_US", # English - United States
+    0x0809: "en_GB", # English - United Kingdom
+    0x0c09: "en_AU", # English - Australia
+    0x1009: "en_CA", # English - Canada
+    0x1409: "en_NZ", # English - New Zealand
+    0x1809: "en_IE", # English - Ireland
+    0x1c09: "en_ZA", # English - South Africa
+    0x2009: "en_JA", # English - Jamaica
+    0x2409: "en_CB", # English - Carribbean
+    0x2809: "en_BZ", # English - Belize
+    0x2c09: "en_TT", # English - Trinidad
+    0x3009: "en_ZW", # English - Zimbabwe
+    0x3409: "en_PH", # English - Phillippines
+    0x0425: "et_EE", # Estonian
+    0x0438: "fo_FO", # Faroese
+    0x0464: "fil_PH",# Filipino
+    0x040b: "fi_FI", # Finnish
+    0x040c: "fr_FR", # French - France
+    0x080c: "fr_BE", # French - Belgium
+    0x0c0c: "fr_CA", # French - Canada
+    0x100c: "fr_CH", # French - Switzerland
+    0x140c: "fr_LU", # French - Luxembourg
+    0x180c: "fr_MC", # French - Monaco
+    0x0462: "fy_NL", # Frisian - Netherlands
+    0x0456: "gl_ES", # Galician
+    0x0437: "ka_GE", # Georgian
+    0x0407: "de_DE", # German - Germany
+    0x0807: "de_CH", # German - Switzerland
+    0x0c07: "de_AT", # German - Austria
+    0x1007: "de_LU", # German - Luxembourg
+    0x1407: "de_LI", # German - Liechtenstein
+    0x0408: "el_GR", # Greek
+    0x0447: "gu_IN", # Gujarati
+    0x040d: "he_IL", # Hebrew
+    0x0439: "hi_IN", # Hindi
+    0x040e: "hu_HU", # Hungarian
+    0x040f: "is_IS", # Icelandic
+    0x0421: "id_ID", # Indonesian
+    0x045d: "iu_CA", # Inuktitut
+    0x085d: "iu_CA", # Inuktitut - Latin
+    0x083c: "ga_IE", # Irish - Ireland
+    0x0434: "xh_ZA", # Xhosa - South Africa
+    0x0435: "zu_ZA", # Zulu
+    0x0410: "it_IT", # Italian - Italy
+    0x0810: "it_CH", # Italian - Switzerland
+    0x0411: "ja_JP", # Japanese
+    0x044b: "kn_IN", # Kannada - India
+    0x043f: "kk_KZ", # Kazakh
+    0x0457: "kok_IN",# Konkani
+    0x0412: "ko_KR", # Korean
+    0x0440: "ky_KG", # Kyrgyz
+    0x0426: "lv_LV", # Latvian
+    0x0427: "lt_LT", # Lithuanian
+    0x046e: "lb_LU", # Luxembourgish
+    0x042f: "mk_MK", # FYRO Macedonian
+    0x043e: "ms_MY", # Malay - Malaysia
+    0x083e: "ms_BN", # Malay - Brunei
+    0x044c: "ml_IN", # Malayalam - India
+    0x043a: "mt_MT", # Maltese
+    0x0481: "mi_NZ", # Maori
+    0x047a: "arn_CL",# Mapudungun
+    0x044e: "mr_IN", # Marathi
+    0x047c: "moh_CA",# Mohawk - Canada
+    0x0450: "mn_MN", # Mongolian
+    0x0461: "ne_NP", # Nepali
+    0x0414: "nb_NO", # Norwegian - Bokmal
+    0x0814: "nn_NO", # Norwegian - Nynorsk
+    0x0482: "oc_FR", # Occitan - France
+    0x0448: "or_IN", # Oriya - India
+    0x0463: "ps_AF", # Pashto - Afghanistan
+    0x0429: "fa_IR", # Persian
+    0x0415: "pl_PL", # Polish
+    0x0416: "pt_BR", # Portuguese - Brazil
+    0x0816: "pt_PT", # Portuguese - Portugal
+    0x0446: "pa_IN", # Punjabi
+    0x046b: "quz_BO",# Quechua (Bolivia)
+    0x086b: "quz_EC",# Quechua (Ecuador)
+    0x0c6b: "quz_PE",# Quechua (Peru)
+    0x0418: "ro_RO", # Romanian - Romania
+    0x0417: "rm_CH", # Raeto-Romanese
+    0x0419: "ru_RU", # Russian
+    0x243b: "smn_FI",# Sami Finland
+    0x103b: "smj_NO",# Sami Norway
+    0x143b: "smj_SE",# Sami Sweden
+    0x043b: "se_NO", # Sami Northern Norway
+    0x083b: "se_SE", # Sami Northern Sweden
+    0x0c3b: "se_FI", # Sami Northern Finland
+    0x203b: "sms_FI",# Sami Skolt
+    0x183b: "sma_NO",# Sami Southern Norway
+    0x1c3b: "sma_SE",# Sami Southern Sweden
+    0x044f: "sa_IN", # Sanskrit
+    0x0c1a: "sr_SP", # Serbian - Cyrillic
+    0x1c1a: "sr_BA", # Serbian - Bosnia Cyrillic
+    0x081a: "sr_SP", # Serbian - Latin
+    0x181a: "sr_BA", # Serbian - Bosnia Latin
+    0x046c: "ns_ZA", # Northern Sotho
+    0x0432: "tn_ZA", # Setswana - Southern Africa
+    0x041b: "sk_SK", # Slovak
+    0x0424: "sl_SI", # Slovenian
+    0x040a: "es_ES", # Spanish - Spain
+    0x080a: "es_MX", # Spanish - Mexico
+    0x0c0a: "es_ES", # Spanish - Spain (Modern)
+    0x100a: "es_GT", # Spanish - Guatemala
+    0x140a: "es_CR", # Spanish - Costa Rica
+    0x180a: "es_PA", # Spanish - Panama
+    0x1c0a: "es_DO", # Spanish - Dominican Republic
+    0x200a: "es_VE", # Spanish - Venezuela
+    0x240a: "es_CO", # Spanish - Colombia
+    0x280a: "es_PE", # Spanish - Peru
+    0x2c0a: "es_AR", # Spanish - Argentina
+    0x300a: "es_EC", # Spanish - Ecuador
+    0x340a: "es_CL", # Spanish - Chile
+    0x380a: "es_UR", # Spanish - Uruguay
+    0x3c0a: "es_PY", # Spanish - Paraguay
+    0x400a: "es_BO", # Spanish - Bolivia
+    0x440a: "es_SV", # Spanish - El Salvador
+    0x480a: "es_HN", # Spanish - Honduras
+    0x4c0a: "es_NI", # Spanish - Nicaragua
+    0x500a: "es_PR", # Spanish - Puerto Rico
+    0x0441: "sw_KE", # Swahili
+    0x041d: "sv_SE", # Swedish - Sweden
+    0x081d: "sv_FI", # Swedish - Finland
+    0x045a: "syr_SY",# Syriac
+    0x0449: "ta_IN", # Tamil
+    0x0444: "tt_RU", # Tatar
+    0x044a: "te_IN", # Telugu
+    0x041e: "th_TH", # Thai
+    0x041f: "tr_TR", # Turkish
+    0x0422: "uk_UA", # Ukrainian
+    0x0420: "ur_PK", # Urdu
+    0x0820: "ur_IN", # Urdu - India
+    0x0443: "uz_UZ", # Uzbek - Latin
+    0x0843: "uz_UZ", # Uzbek - Cyrillic
+    0x042a: "vi_VN", # Vietnamese
+    0x0452: "cy_GB", # Welsh
+}
+
+def _print_locale():
+
+    """ Test function.
+    """
+    categories = {}
+    def _init_categories(categories=categories):
+        for k,v in globals().items():
+            if k[:3] == 'LC_':
+                categories[k] = v
+    _init_categories()
+    del categories['LC_ALL']
+
+    print 'Locale defaults as determined by getdefaultlocale():'
+    print '-'*72
+    lang, enc = getdefaultlocale()
+    print 'Language: ', lang or '(undefined)'
+    print 'Encoding: ', enc or '(undefined)'
+    print
+
+    print 'Locale settings on startup:'
+    print '-'*72
+    for name,category in categories.items():
+        print name, '...'
+        lang, enc = getlocale(category)
+        print '   Language: ', lang or '(undefined)'
+        print '   Encoding: ', enc or '(undefined)'
+        print
+
+    print
+    print 'Locale settings after calling resetlocale():'
+    print '-'*72
+    resetlocale()
+    for name,category in categories.items():
+        print name, '...'
+        lang, enc = getlocale(category)
+        print '   Language: ', lang or '(undefined)'
+        print '   Encoding: ', enc or '(undefined)'
+        print
+
+    try:
+        setlocale(LC_ALL, "")
+    except:
+        print 'NOTE:'
+        print 'setlocale(LC_ALL, "") does not support the default locale'
+        print 'given in the OS environment variables.'
+    else:
+        print
+        print 'Locale settings after calling setlocale(LC_ALL, ""):'
+        print '-'*72
+        for name,category in categories.items():
+            print name, '...'
+            lang, enc = getlocale(category)
+            print '   Language: ', lang or '(undefined)'
+            print '   Encoding: ', enc or '(undefined)'
+            print
+
+###
+
+try:
+    LC_MESSAGES
+except NameError:
+    pass
+else:
+    __all__.append("LC_MESSAGES")
+
+if __name__=='__main__':
+    print 'Locale aliasing:'
+    print
+    _print_locale()
+    print
+    print 'Number formatting:'
+    print
+    _test()

Added: vendor/Python/current/Lib/logging/__init__.py
===================================================================
--- vendor/Python/current/Lib/logging/__init__.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/logging/__init__.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1372 @@
+# Copyright 2001-2007 by Vinay Sajip. All Rights Reserved.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose and without fee is hereby granted,
+# provided that the above copyright notice appear in all copies and that
+# both that copyright notice and this permission notice appear in
+# supporting documentation, and that the name of Vinay Sajip
+# not be used in advertising or publicity pertaining to distribution
+# of the software without specific, written prior permission.
+# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+"""
+Logging package for Python. Based on PEP 282 and comments thereto in
+comp.lang.python, and influenced by Apache's log4j system.
+
+Should work under Python versions >= 1.5.2, except that source line
+information is not available unless 'sys._getframe()' is.
+
+Copyright (C) 2001-2007 Vinay Sajip. All Rights Reserved.
+
+To use, simply 'import logging' and log away!
+"""
+
+import sys, os, types, time, string, cStringIO, traceback
+
+try:
+    import codecs
+except ImportError:
+    codecs = None
+
+try:
+    import thread
+    import threading
+except ImportError:
+    thread = None
+
+__author__  = "Vinay Sajip <vinay_sajip at red-dove.com>"
+__status__  = "production"
+__version__ = "0.5.0.2"
+__date__    = "16 February 2007"
+
+#---------------------------------------------------------------------------
+#   Miscellaneous module data
+#---------------------------------------------------------------------------
+
+#
+# _srcfile is used when walking the stack to check when we've got the first
+# caller stack frame.
+#
+if hasattr(sys, 'frozen'): #support for py2exe
+    _srcfile = "logging%s__init__%s" % (os.sep, __file__[-4:])
+elif string.lower(__file__[-4:]) in ['.pyc', '.pyo']:
+    _srcfile = __file__[:-4] + '.py'
+else:
+    _srcfile = __file__
+_srcfile = os.path.normcase(_srcfile)
+
+# next bit filched from 1.5.2's inspect.py
+def currentframe():
+    """Return the frame object for the caller's stack frame."""
+    try:
+        raise Exception
+    except:
+        return sys.exc_traceback.tb_frame.f_back
+
+if hasattr(sys, '_getframe'): currentframe = lambda: sys._getframe(3)
+# done filching
+
+# _srcfile is only used in conjunction with sys._getframe().
+# To provide compatibility with older versions of Python, set _srcfile
+# to None if _getframe() is not available; this value will prevent
+# findCaller() from being called.
+#if not hasattr(sys, "_getframe"):
+#    _srcfile = None
+
+#
+#_startTime is used as the base when calculating the relative time of events
+#
+_startTime = time.time()
+
+#
+#raiseExceptions is used to see if exceptions during handling should be
+#propagated
+#
+raiseExceptions = 1
+
+#
+# If you don't want threading information in the log, set this to zero
+#
+logThreads = 1
+
+#
+# If you don't want process information in the log, set this to zero
+#
+logProcesses = 1
+
+#---------------------------------------------------------------------------
+#   Level related stuff
+#---------------------------------------------------------------------------
+#
+# Default levels and level names, these can be replaced with any positive set
+# of values having corresponding names. There is a pseudo-level, NOTSET, which
+# is only really there as a lower limit for user-defined levels. Handlers and
+# loggers are initialized with NOTSET so that they will log all messages, even
+# at user-defined levels.
+#
+
+CRITICAL = 50
+FATAL = CRITICAL
+ERROR = 40
+WARNING = 30
+WARN = WARNING
+INFO = 20
+DEBUG = 10
+NOTSET = 0
+
+_levelNames = {
+    CRITICAL : 'CRITICAL',
+    ERROR : 'ERROR',
+    WARNING : 'WARNING',
+    INFO : 'INFO',
+    DEBUG : 'DEBUG',
+    NOTSET : 'NOTSET',
+    'CRITICAL' : CRITICAL,
+    'ERROR' : ERROR,
+    'WARN' : WARNING,
+    'WARNING' : WARNING,
+    'INFO' : INFO,
+    'DEBUG' : DEBUG,
+    'NOTSET' : NOTSET,
+}
+
+def getLevelName(level):
+    """
+    Return the textual representation of logging level 'level'.
+
+    If the level is one of the predefined levels (CRITICAL, ERROR, WARNING,
+    INFO, DEBUG) then you get the corresponding string. If you have
+    associated levels with names using addLevelName then the name you have
+    associated with 'level' is returned.
+
+    If a numeric value corresponding to one of the defined levels is passed
+    in, the corresponding string representation is returned.
+
+    Otherwise, the string "Level %s" % level is returned.
+    """
+    return _levelNames.get(level, ("Level %s" % level))
+
+def addLevelName(level, levelName):
+    """
+    Associate 'levelName' with 'level'.
+
+    This is used when converting levels to text during message formatting.
+    """
+    _acquireLock()
+    try:    #unlikely to cause an exception, but you never know...
+        _levelNames[level] = levelName
+        _levelNames[levelName] = level
+    finally:
+        _releaseLock()
+
+#---------------------------------------------------------------------------
+#   Thread-related stuff
+#---------------------------------------------------------------------------
+
+#
+#_lock is used to serialize access to shared data structures in this module.
+#This needs to be an RLock because fileConfig() creates Handlers and so
+#might arbitrary user threads. Since Handler.__init__() updates the shared
+#dictionary _handlers, it needs to acquire the lock. But if configuring,
+#the lock would already have been acquired - so we need an RLock.
+#The same argument applies to Loggers and Manager.loggerDict.
+#
+_lock = None
+
+def _acquireLock():
+    """
+    Acquire the module-level lock for serializing access to shared data.
+
+    This should be released with _releaseLock().
+    """
+    global _lock
+    if (not _lock) and thread:
+        _lock = threading.RLock()
+    if _lock:
+        _lock.acquire()
+
+def _releaseLock():
+    """
+    Release the module-level lock acquired by calling _acquireLock().
+    """
+    if _lock:
+        _lock.release()
+
+#---------------------------------------------------------------------------
+#   The logging record
+#---------------------------------------------------------------------------
+
+class LogRecord:
+    """
+    A LogRecord instance represents an event being logged.
+
+    LogRecord instances are created every time something is logged. They
+    contain all the information pertinent to the event being logged. The
+    main information passed in is in msg and args, which are combined
+    using str(msg) % args to create the message field of the record. The
+    record also includes information such as when the record was created,
+    the source line where the logging call was made, and any exception
+    information to be logged.
+    """
+    def __init__(self, name, level, pathname, lineno,
+                 msg, args, exc_info, func=None):
+        """
+        Initialize a logging record with interesting information.
+        """
+        ct = time.time()
+        self.name = name
+        self.msg = msg
+        #
+        # The following statement allows passing of a dictionary as a sole
+        # argument, so that you can do something like
+        #  logging.debug("a %(a)d b %(b)s", {'a':1, 'b':2})
+        # Suggested by Stefan Behnel.
+        # Note that without the test for args[0], we get a problem because
+        # during formatting, we test to see if the arg is present using
+        # 'if self.args:'. If the event being logged is e.g. 'Value is %d'
+        # and if the passed arg fails 'if self.args:' then no formatting
+        # is done. For example, logger.warn('Value is %d', 0) would log
+        # 'Value is %d' instead of 'Value is 0'.
+        # For the use case of passing a dictionary, this should not be a
+        # problem.
+        if args and (len(args) == 1) and args[0] and (type(args[0]) == types.DictType):
+            args = args[0]
+        self.args = args
+        self.levelname = getLevelName(level)
+        self.levelno = level
+        self.pathname = pathname
+        try:
+            self.filename = os.path.basename(pathname)
+            self.module = os.path.splitext(self.filename)[0]
+        except:
+            self.filename = pathname
+            self.module = "Unknown module"
+        self.exc_info = exc_info
+        self.exc_text = None      # used to cache the traceback text
+        self.lineno = lineno
+        self.funcName = func
+        self.created = ct
+        self.msecs = (ct - long(ct)) * 1000
+        self.relativeCreated = (self.created - _startTime) * 1000
+        if logThreads and thread:
+            self.thread = thread.get_ident()
+            self.threadName = threading.currentThread().getName()
+        else:
+            self.thread = None
+            self.threadName = None
+        if logProcesses and hasattr(os, 'getpid'):
+            self.process = os.getpid()
+        else:
+            self.process = None
+
+    def __str__(self):
+        return '<LogRecord: %s, %s, %s, %s, "%s">'%(self.name, self.levelno,
+            self.pathname, self.lineno, self.msg)
+
+    def getMessage(self):
+        """
+        Return the message for this LogRecord.
+
+        Return the message for this LogRecord after merging any user-supplied
+        arguments with the message.
+        """
+        if not hasattr(types, "UnicodeType"): #if no unicode support...
+            msg = str(self.msg)
+        else:
+            msg = self.msg
+            if type(msg) not in (types.UnicodeType, types.StringType):
+                try:
+                    msg = str(self.msg)
+                except UnicodeError:
+                    msg = self.msg      #Defer encoding till later
+        if self.args:
+            msg = msg % self.args
+        return msg
+
+def makeLogRecord(dict):
+    """
+    Make a LogRecord whose attributes are defined by the specified dictionary,
+    This function is useful for converting a logging event received over
+    a socket connection (which is sent as a dictionary) into a LogRecord
+    instance.
+    """
+    rv = LogRecord(None, None, "", 0, "", (), None, None)
+    rv.__dict__.update(dict)
+    return rv
+
+#---------------------------------------------------------------------------
+#   Formatter classes and functions
+#---------------------------------------------------------------------------
+
+class Formatter:
+    """
+    Formatter instances are used to convert a LogRecord to text.
+
+    Formatters need to know how a LogRecord is constructed. They are
+    responsible for converting a LogRecord to (usually) a string which can
+    be interpreted by either a human or an external system. The base Formatter
+    allows a formatting string to be specified. If none is supplied, the
+    default value of "%s(message)\\n" is used.
+
+    The Formatter can be initialized with a format string which makes use of
+    knowledge of the LogRecord attributes - e.g. the default value mentioned
+    above makes use of the fact that the user's message and arguments are pre-
+    formatted into a LogRecord's message attribute. Currently, the useful
+    attributes in a LogRecord are described by:
+
+    %(name)s            Name of the logger (logging channel)
+    %(levelno)s         Numeric logging level for the message (DEBUG, INFO,
+                        WARNING, ERROR, CRITICAL)
+    %(levelname)s       Text logging level for the message ("DEBUG", "INFO",
+                        "WARNING", "ERROR", "CRITICAL")
+    %(pathname)s        Full pathname of the source file where the logging
+                        call was issued (if available)
+    %(filename)s        Filename portion of pathname
+    %(module)s          Module (name portion of filename)
+    %(lineno)d          Source line number where the logging call was issued
+                        (if available)
+    %(funcName)s        Function name
+    %(created)f         Time when the LogRecord was created (time.time()
+                        return value)
+    %(asctime)s         Textual time when the LogRecord was created
+    %(msecs)d           Millisecond portion of the creation time
+    %(relativeCreated)d Time in milliseconds when the LogRecord was created,
+                        relative to the time the logging module was loaded
+                        (typically at application startup time)
+    %(thread)d          Thread ID (if available)
+    %(threadName)s      Thread name (if available)
+    %(process)d         Process ID (if available)
+    %(message)s         The result of record.getMessage(), computed just as
+                        the record is emitted
+    """
+
+    converter = time.localtime
+
+    def __init__(self, fmt=None, datefmt=None):
+        """
+        Initialize the formatter with specified format strings.
+
+        Initialize the formatter either with the specified format string, or a
+        default as described above. Allow for specialized date formatting with
+        the optional datefmt argument (if omitted, you get the ISO8601 format).
+        """
+        if fmt:
+            self._fmt = fmt
+        else:
+            self._fmt = "%(message)s"
+        self.datefmt = datefmt
+
+    def formatTime(self, record, datefmt=None):
+        """
+        Return the creation time of the specified LogRecord as formatted text.
+
+        This method should be called from format() by a formatter which
+        wants to make use of a formatted time. This method can be overridden
+        in formatters to provide for any specific requirement, but the
+        basic behaviour is as follows: if datefmt (a string) is specified,
+        it is used with time.strftime() to format the creation time of the
+        record. Otherwise, the ISO8601 format is used. The resulting
+        string is returned. This function uses a user-configurable function
+        to convert the creation time to a tuple. By default, time.localtime()
+        is used; to change this for a particular formatter instance, set the
+        'converter' attribute to a function with the same signature as
+        time.localtime() or time.gmtime(). To change it for all formatters,
+        for example if you want all logging times to be shown in GMT,
+        set the 'converter' attribute in the Formatter class.
+        """
+        ct = self.converter(record.created)
+        if datefmt:
+            s = time.strftime(datefmt, ct)
+        else:
+            t = time.strftime("%Y-%m-%d %H:%M:%S", ct)
+            s = "%s,%03d" % (t, record.msecs)
+        return s
+
+    def formatException(self, ei):
+        """
+        Format and return the specified exception information as a string.
+
+        This default implementation just uses
+        traceback.print_exception()
+        """
+        sio = cStringIO.StringIO()
+        traceback.print_exception(ei[0], ei[1], ei[2], None, sio)
+        s = sio.getvalue()
+        sio.close()
+        if s[-1] == "\n":
+            s = s[:-1]
+        return s
+
+    def format(self, record):
+        """
+        Format the specified record as text.
+
+        The record's attribute dictionary is used as the operand to a
+        string formatting operation which yields the returned string.
+        Before formatting the dictionary, a couple of preparatory steps
+        are carried out. The message attribute of the record is computed
+        using LogRecord.getMessage(). If the formatting string contains
+        "%(asctime)", formatTime() is called to format the event time.
+        If there is exception information, it is formatted using
+        formatException() and appended to the message.
+        """
+        record.message = record.getMessage()
+        if string.find(self._fmt,"%(asctime)") >= 0:
+            record.asctime = self.formatTime(record, self.datefmt)
+        s = self._fmt % record.__dict__
+        if record.exc_info:
+            # Cache the traceback text to avoid converting it multiple times
+            # (it's constant anyway)
+            if not record.exc_text:
+                record.exc_text = self.formatException(record.exc_info)
+        if record.exc_text:
+            if s[-1] != "\n":
+                s = s + "\n"
+            s = s + record.exc_text
+        return s
+
+#
+#   The default formatter to use when no other is specified
+#
+_defaultFormatter = Formatter()
+
+class BufferingFormatter:
+    """
+    A formatter suitable for formatting a number of records.
+    """
+    def __init__(self, linefmt=None):
+        """
+        Optionally specify a formatter which will be used to format each
+        individual record.
+        """
+        if linefmt:
+            self.linefmt = linefmt
+        else:
+            self.linefmt = _defaultFormatter
+
+    def formatHeader(self, records):
+        """
+        Return the header string for the specified records.
+        """
+        return ""
+
+    def formatFooter(self, records):
+        """
+        Return the footer string for the specified records.
+        """
+        return ""
+
+    def format(self, records):
+        """
+        Format the specified records and return the result as a string.
+        """
+        rv = ""
+        if len(records) > 0:
+            rv = rv + self.formatHeader(records)
+            for record in records:
+                rv = rv + self.linefmt.format(record)
+            rv = rv + self.formatFooter(records)
+        return rv
+
+#---------------------------------------------------------------------------
+#   Filter classes and functions
+#---------------------------------------------------------------------------
+
+class Filter:
+    """
+    Filter instances are used to perform arbitrary filtering of LogRecords.
+
+    Loggers and Handlers can optionally use Filter instances to filter
+    records as desired. The base filter class only allows events which are
+    below a certain point in the logger hierarchy. For example, a filter
+    initialized with "A.B" will allow events logged by loggers "A.B",
+    "A.B.C", "A.B.C.D", "A.B.D" etc. but not "A.BB", "B.A.B" etc. If
+    initialized with the empty string, all events are passed.
+    """
+    def __init__(self, name=''):
+        """
+        Initialize a filter.
+
+        Initialize with the name of the logger which, together with its
+        children, will have its events allowed through the filter. If no
+        name is specified, allow every event.
+        """
+        self.name = name
+        self.nlen = len(name)
+
+    def filter(self, record):
+        """
+        Determine if the specified record is to be logged.
+
+        Is the specified record to be logged? Returns 0 for no, nonzero for
+        yes. If deemed appropriate, the record may be modified in-place.
+        """
+        if self.nlen == 0:
+            return 1
+        elif self.name == record.name:
+            return 1
+        elif string.find(record.name, self.name, 0, self.nlen) != 0:
+            return 0
+        return (record.name[self.nlen] == ".")
+
+class Filterer:
+    """
+    A base class for loggers and handlers which allows them to share
+    common code.
+    """
+    def __init__(self):
+        """
+        Initialize the list of filters to be an empty list.
+        """
+        self.filters = []
+
+    def addFilter(self, filter):
+        """
+        Add the specified filter to this handler.
+        """
+        if not (filter in self.filters):
+            self.filters.append(filter)
+
+    def removeFilter(self, filter):
+        """
+        Remove the specified filter from this handler.
+        """
+        if filter in self.filters:
+            self.filters.remove(filter)
+
+    def filter(self, record):
+        """
+        Determine if a record is loggable by consulting all the filters.
+
+        The default is to allow the record to be logged; any filter can veto
+        this and the record is then dropped. Returns a zero value if a record
+        is to be dropped, else non-zero.
+        """
+        rv = 1
+        for f in self.filters:
+            if not f.filter(record):
+                rv = 0
+                break
+        return rv
+
+#---------------------------------------------------------------------------
+#   Handler classes and functions
+#---------------------------------------------------------------------------
+
+_handlers = {}  #repository of handlers (for flushing when shutdown called)
+_handlerList = [] # added to allow handlers to be removed in reverse of order initialized
+
+class Handler(Filterer):
+    """
+    Handler instances dispatch logging events to specific destinations.
+
+    The base handler class. Acts as a placeholder which defines the Handler
+    interface. Handlers can optionally use Formatter instances to format
+    records as desired. By default, no formatter is specified; in this case,
+    the 'raw' message as determined by record.message is logged.
+    """
+    def __init__(self, level=NOTSET):
+        """
+        Initializes the instance - basically setting the formatter to None
+        and the filter list to empty.
+        """
+        Filterer.__init__(self)
+        self.level = level
+        self.formatter = None
+        #get the module data lock, as we're updating a shared structure.
+        _acquireLock()
+        try:    #unlikely to raise an exception, but you never know...
+            _handlers[self] = 1
+            _handlerList.insert(0, self)
+        finally:
+            _releaseLock()
+        self.createLock()
+
+    def createLock(self):
+        """
+        Acquire a thread lock for serializing access to the underlying I/O.
+        """
+        if thread:
+            self.lock = threading.RLock()
+        else:
+            self.lock = None
+
+    def acquire(self):
+        """
+        Acquire the I/O thread lock.
+        """
+        if self.lock:
+            self.lock.acquire()
+
+    def release(self):
+        """
+        Release the I/O thread lock.
+        """
+        if self.lock:
+            self.lock.release()
+
+    def setLevel(self, level):
+        """
+        Set the logging level of this handler.
+        """
+        self.level = level
+
+    def format(self, record):
+        """
+        Format the specified record.
+
+        If a formatter is set, use it. Otherwise, use the default formatter
+        for the module.
+        """
+        if self.formatter:
+            fmt = self.formatter
+        else:
+            fmt = _defaultFormatter
+        return fmt.format(record)
+
+    def emit(self, record):
+        """
+        Do whatever it takes to actually log the specified logging record.
+
+        This version is intended to be implemented by subclasses and so
+        raises a NotImplementedError.
+        """
+        raise NotImplementedError, 'emit must be implemented '\
+                                    'by Handler subclasses'
+
+    def handle(self, record):
+        """
+        Conditionally emit the specified logging record.
+
+        Emission depends on filters which may have been added to the handler.
+        Wrap the actual emission of the record with acquisition/release of
+        the I/O thread lock. Returns whether the filter passed the record for
+        emission.
+        """
+        rv = self.filter(record)
+        if rv:
+            self.acquire()
+            try:
+                self.emit(record)
+            finally:
+                self.release()
+        return rv
+
+    def setFormatter(self, fmt):
+        """
+        Set the formatter for this handler.
+        """
+        self.formatter = fmt
+
+    def flush(self):
+        """
+        Ensure all logging output has been flushed.
+
+        This version does nothing and is intended to be implemented by
+        subclasses.
+        """
+        pass
+
+    def close(self):
+        """
+        Tidy up any resources used by the handler.
+
+        This version does removes the handler from an internal list
+        of handlers which is closed when shutdown() is called. Subclasses
+        should ensure that this gets called from overridden close()
+        methods.
+        """
+        #get the module data lock, as we're updating a shared structure.
+        _acquireLock()
+        try:    #unlikely to raise an exception, but you never know...
+            del _handlers[self]
+            _handlerList.remove(self)
+        finally:
+            _releaseLock()
+
+    def handleError(self, record):
+        """
+        Handle errors which occur during an emit() call.
+
+        This method should be called from handlers when an exception is
+        encountered during an emit() call. If raiseExceptions is false,
+        exceptions get silently ignored. This is what is mostly wanted
+        for a logging system - most users will not care about errors in
+        the logging system, they are more interested in application errors.
+        You could, however, replace this with a custom handler if you wish.
+        The record which was being processed is passed in to this method.
+        """
+        if raiseExceptions:
+            ei = sys.exc_info()
+            traceback.print_exception(ei[0], ei[1], ei[2], None, sys.stderr)
+            del ei
+
+class StreamHandler(Handler):
+    """
+    A handler class which writes logging records, appropriately formatted,
+    to a stream. Note that this class does not close the stream, as
+    sys.stdout or sys.stderr may be used.
+    """
+    def __init__(self, strm=None):
+        """
+        Initialize the handler.
+
+        If strm is not specified, sys.stderr is used.
+        """
+        Handler.__init__(self)
+        if strm is None:
+            strm = sys.stderr
+        self.stream = strm
+        self.formatter = None
+
+    def flush(self):
+        """
+        Flushes the stream.
+        """
+        self.stream.flush()
+
+    def emit(self, record):
+        """
+        Emit a record.
+
+        If a formatter is specified, it is used to format the record.
+        The record is then written to the stream with a trailing newline
+        [N.B. this may be removed depending on feedback]. If exception
+        information is present, it is formatted using
+        traceback.print_exception and appended to the stream.
+        """
+        try:
+            msg = self.format(record)
+            fs = "%s\n"
+            if not hasattr(types, "UnicodeType"): #if no unicode support...
+                self.stream.write(fs % msg)
+            else:
+                try:
+                    self.stream.write(fs % msg)
+                except UnicodeError:
+                    self.stream.write(fs % msg.encode("UTF-8"))
+            self.flush()
+        except (KeyboardInterrupt, SystemExit):
+            raise
+        except:
+            self.handleError(record)
+
+class FileHandler(StreamHandler):
+    """
+    A handler class which writes formatted logging records to disk files.
+    """
+    def __init__(self, filename, mode='a', encoding=None):
+        """
+        Open the specified file and use it as the stream for logging.
+        """
+        if codecs is None:
+            encoding = None
+        if encoding is None:
+            stream = open(filename, mode)
+        else:
+            stream = codecs.open(filename, mode, encoding)
+        StreamHandler.__init__(self, stream)
+        #keep the absolute path, otherwise derived classes which use this
+        #may come a cropper when the current directory changes
+        self.baseFilename = os.path.abspath(filename)
+        self.mode = mode
+
+    def close(self):
+        """
+        Closes the stream.
+        """
+        self.flush()
+        self.stream.close()
+        StreamHandler.close(self)
+
+#---------------------------------------------------------------------------
+#   Manager classes and functions
+#---------------------------------------------------------------------------
+
+class PlaceHolder:
+    """
+    PlaceHolder instances are used in the Manager logger hierarchy to take
+    the place of nodes for which no loggers have been defined. This class is
+    intended for internal use only and not as part of the public API.
+    """
+    def __init__(self, alogger):
+        """
+        Initialize with the specified logger being a child of this placeholder.
+        """
+        #self.loggers = [alogger]
+        self.loggerMap = { alogger : None }
+
+    def append(self, alogger):
+        """
+        Add the specified logger as a child of this placeholder.
+        """
+        #if alogger not in self.loggers:
+        if not self.loggerMap.has_key(alogger):
+            #self.loggers.append(alogger)
+            self.loggerMap[alogger] = None
+
+#
+#   Determine which class to use when instantiating loggers.
+#
+_loggerClass = None
+
+def setLoggerClass(klass):
+    """
+    Set the class to be used when instantiating a logger. The class should
+    define __init__() such that only a name argument is required, and the
+    __init__() should call Logger.__init__()
+    """
+    if klass != Logger:
+        if not issubclass(klass, Logger):
+            raise TypeError, "logger not derived from logging.Logger: " + \
+                            klass.__name__
+    global _loggerClass
+    _loggerClass = klass
+
+def getLoggerClass():
+    """
+    Return the class to be used when instantiating a logger.
+    """
+
+    return _loggerClass
+
+class Manager:
+    """
+    There is [under normal circumstances] just one Manager instance, which
+    holds the hierarchy of loggers.
+    """
+    def __init__(self, rootnode):
+        """
+        Initialize the manager with the root node of the logger hierarchy.
+        """
+        self.root = rootnode
+        self.disable = 0
+        self.emittedNoHandlerWarning = 0
+        self.loggerDict = {}
+
+    def getLogger(self, name):
+        """
+        Get a logger with the specified name (channel name), creating it
+        if it doesn't yet exist. This name is a dot-separated hierarchical
+        name, such as "a", "a.b", "a.b.c" or similar.
+
+        If a PlaceHolder existed for the specified name [i.e. the logger
+        didn't exist but a child of it did], replace it with the created
+        logger and fix up the parent/child references which pointed to the
+        placeholder to now point to the logger.
+        """
+        rv = None
+        _acquireLock()
+        try:
+            if self.loggerDict.has_key(name):
+                rv = self.loggerDict[name]
+                if isinstance(rv, PlaceHolder):
+                    ph = rv
+                    rv = _loggerClass(name)
+                    rv.manager = self
+                    self.loggerDict[name] = rv
+                    self._fixupChildren(ph, rv)
+                    self._fixupParents(rv)
+            else:
+                rv = _loggerClass(name)
+                rv.manager = self
+                self.loggerDict[name] = rv
+                self._fixupParents(rv)
+        finally:
+            _releaseLock()
+        return rv
+
+    def _fixupParents(self, alogger):
+        """
+        Ensure that there are either loggers or placeholders all the way
+        from the specified logger to the root of the logger hierarchy.
+        """
+        name = alogger.name
+        i = string.rfind(name, ".")
+        rv = None
+        while (i > 0) and not rv:
+            substr = name[:i]
+            if not self.loggerDict.has_key(substr):
+                self.loggerDict[substr] = PlaceHolder(alogger)
+            else:
+                obj = self.loggerDict[substr]
+                if isinstance(obj, Logger):
+                    rv = obj
+                else:
+                    assert isinstance(obj, PlaceHolder)
+                    obj.append(alogger)
+            i = string.rfind(name, ".", 0, i - 1)
+        if not rv:
+            rv = self.root
+        alogger.parent = rv
+
+    def _fixupChildren(self, ph, alogger):
+        """
+        Ensure that children of the placeholder ph are connected to the
+        specified logger.
+        """
+        name = alogger.name
+        namelen = len(name)
+        for c in ph.loggerMap.keys():
+            #The if means ... if not c.parent.name.startswith(nm)
+            #if string.find(c.parent.name, nm) <> 0:
+            if c.parent.name[:namelen] != name:
+                alogger.parent = c.parent
+                c.parent = alogger
+
+#---------------------------------------------------------------------------
+#   Logger classes and functions
+#---------------------------------------------------------------------------
+
+class Logger(Filterer):
+    """
+    Instances of the Logger class represent a single logging channel. A
+    "logging channel" indicates an area of an application. Exactly how an
+    "area" is defined is up to the application developer. Since an
+    application can have any number of areas, logging channels are identified
+    by a unique string. Application areas can be nested (e.g. an area
+    of "input processing" might include sub-areas "read CSV files", "read
+    XLS files" and "read Gnumeric files"). To cater for this natural nesting,
+    channel names are organized into a namespace hierarchy where levels are
+    separated by periods, much like the Java or Python package namespace. So
+    in the instance given above, channel names might be "input" for the upper
+    level, and "input.csv", "input.xls" and "input.gnu" for the sub-levels.
+    There is no arbitrary limit to the depth of nesting.
+    """
+    def __init__(self, name, level=NOTSET):
+        """
+        Initialize the logger with a name and an optional level.
+        """
+        Filterer.__init__(self)
+        self.name = name
+        self.level = level
+        self.parent = None
+        self.propagate = 1
+        self.handlers = []
+        self.disabled = 0
+
+    def setLevel(self, level):
+        """
+        Set the logging level of this logger.
+        """
+        self.level = level
+
+    def debug(self, msg, *args, **kwargs):
+        """
+        Log 'msg % args' with severity 'DEBUG'.
+
+        To pass exception information, use the keyword argument exc_info with
+        a true value, e.g.
+
+        logger.debug("Houston, we have a %s", "thorny problem", exc_info=1)
+        """
+        if self.manager.disable >= DEBUG:
+            return
+        if DEBUG >= self.getEffectiveLevel():
+            apply(self._log, (DEBUG, msg, args), kwargs)
+
+    def info(self, msg, *args, **kwargs):
+        """
+        Log 'msg % args' with severity 'INFO'.
+
+        To pass exception information, use the keyword argument exc_info with
+        a true value, e.g.
+
+        logger.info("Houston, we have a %s", "interesting problem", exc_info=1)
+        """
+        if self.manager.disable >= INFO:
+            return
+        if INFO >= self.getEffectiveLevel():
+            apply(self._log, (INFO, msg, args), kwargs)
+
+    def warning(self, msg, *args, **kwargs):
+        """
+        Log 'msg % args' with severity 'WARNING'.
+
+        To pass exception information, use the keyword argument exc_info with
+        a true value, e.g.
+
+        logger.warning("Houston, we have a %s", "bit of a problem", exc_info=1)
+        """
+        if self.manager.disable >= WARNING:
+            return
+        if self.isEnabledFor(WARNING):
+            apply(self._log, (WARNING, msg, args), kwargs)
+
+    warn = warning
+
+    def error(self, msg, *args, **kwargs):
+        """
+        Log 'msg % args' with severity 'ERROR'.
+
+        To pass exception information, use the keyword argument exc_info with
+        a true value, e.g.
+
+        logger.error("Houston, we have a %s", "major problem", exc_info=1)
+        """
+        if self.manager.disable >= ERROR:
+            return
+        if self.isEnabledFor(ERROR):
+            apply(self._log, (ERROR, msg, args), kwargs)
+
+    def exception(self, msg, *args):
+        """
+        Convenience method for logging an ERROR with exception information.
+        """
+        apply(self.error, (msg,) + args, {'exc_info': 1})
+
+    def critical(self, msg, *args, **kwargs):
+        """
+        Log 'msg % args' with severity 'CRITICAL'.
+
+        To pass exception information, use the keyword argument exc_info with
+        a true value, e.g.
+
+        logger.critical("Houston, we have a %s", "major disaster", exc_info=1)
+        """
+        if self.manager.disable >= CRITICAL:
+            return
+        if CRITICAL >= self.getEffectiveLevel():
+            apply(self._log, (CRITICAL, msg, args), kwargs)
+
+    fatal = critical
+
+    def log(self, level, msg, *args, **kwargs):
+        """
+        Log 'msg % args' with the integer severity 'level'.
+
+        To pass exception information, use the keyword argument exc_info with
+        a true value, e.g.
+
+        logger.log(level, "We have a %s", "mysterious problem", exc_info=1)
+        """
+        if type(level) != types.IntType:
+            if raiseExceptions:
+                raise TypeError, "level must be an integer"
+            else:
+                return
+        if self.manager.disable >= level:
+            return
+        if self.isEnabledFor(level):
+            apply(self._log, (level, msg, args), kwargs)
+
+    def findCaller(self):
+        """
+        Find the stack frame of the caller so that we can note the source
+        file name, line number and function name.
+        """
+        f = currentframe().f_back
+        rv = "(unknown file)", 0, "(unknown function)"
+        while hasattr(f, "f_code"):
+            co = f.f_code
+            filename = os.path.normcase(co.co_filename)
+            if filename == _srcfile:
+                f = f.f_back
+                continue
+            rv = (filename, f.f_lineno, co.co_name)
+            break
+        return rv
+
+    def makeRecord(self, name, level, fn, lno, msg, args, exc_info, func=None, extra=None):
+        """
+        A factory method which can be overridden in subclasses to create
+        specialized LogRecords.
+        """
+        rv = LogRecord(name, level, fn, lno, msg, args, exc_info, func)
+        if extra:
+            for key in extra:
+                if (key in ["message", "asctime"]) or (key in rv.__dict__):
+                    raise KeyError("Attempt to overwrite %r in LogRecord" % key)
+                rv.__dict__[key] = extra[key]
+        return rv
+
+    def _log(self, level, msg, args, exc_info=None, extra=None):
+        """
+        Low-level logging routine which creates a LogRecord and then calls
+        all the handlers of this logger to handle the record.
+        """
+        if _srcfile:
+            fn, lno, func = self.findCaller()
+        else:
+            fn, lno, func = "(unknown file)", 0, "(unknown function)"
+        if exc_info:
+            if type(exc_info) != types.TupleType:
+                exc_info = sys.exc_info()
+        record = self.makeRecord(self.name, level, fn, lno, msg, args, exc_info, func, extra)
+        self.handle(record)
+
+    def handle(self, record):
+        """
+        Call the handlers for the specified record.
+
+        This method is used for unpickled records received from a socket, as
+        well as those created locally. Logger-level filtering is applied.
+        """
+        if (not self.disabled) and self.filter(record):
+            self.callHandlers(record)
+
+    def addHandler(self, hdlr):
+        """
+        Add the specified handler to this logger.
+        """
+        if not (hdlr in self.handlers):
+            self.handlers.append(hdlr)
+
+    def removeHandler(self, hdlr):
+        """
+        Remove the specified handler from this logger.
+        """
+        if hdlr in self.handlers:
+            #hdlr.close()
+            hdlr.acquire()
+            try:
+                self.handlers.remove(hdlr)
+            finally:
+                hdlr.release()
+
+    def callHandlers(self, record):
+        """
+        Pass a record to all relevant handlers.
+
+        Loop through all handlers for this logger and its parents in the
+        logger hierarchy. If no handler was found, output a one-off error
+        message to sys.stderr. Stop searching up the hierarchy whenever a
+        logger with the "propagate" attribute set to zero is found - that
+        will be the last logger whose handlers are called.
+        """
+        c = self
+        found = 0
+        while c:
+            for hdlr in c.handlers:
+                found = found + 1
+                if record.levelno >= hdlr.level:
+                    hdlr.handle(record)
+            if not c.propagate:
+                c = None    #break out
+            else:
+                c = c.parent
+        if (found == 0) and raiseExceptions and not self.manager.emittedNoHandlerWarning:
+            sys.stderr.write("No handlers could be found for logger"
+                             " \"%s\"\n" % self.name)
+            self.manager.emittedNoHandlerWarning = 1
+
+    def getEffectiveLevel(self):
+        """
+        Get the effective level for this logger.
+
+        Loop through this logger and its parents in the logger hierarchy,
+        looking for a non-zero logging level. Return the first one found.
+        """
+        logger = self
+        while logger:
+            if logger.level:
+                return logger.level
+            logger = logger.parent
+        return NOTSET
+
+    def isEnabledFor(self, level):
+        """
+        Is this logger enabled for level 'level'?
+        """
+        if self.manager.disable >= level:
+            return 0
+        return level >= self.getEffectiveLevel()
+
+class RootLogger(Logger):
+    """
+    A root logger is not that different to any other logger, except that
+    it must have a logging level and there is only one instance of it in
+    the hierarchy.
+    """
+    def __init__(self, level):
+        """
+        Initialize the logger with the name "root".
+        """
+        Logger.__init__(self, "root", level)
+
+_loggerClass = Logger
+
+root = RootLogger(WARNING)
+Logger.root = root
+Logger.manager = Manager(Logger.root)
+
+#---------------------------------------------------------------------------
+# Configuration classes and functions
+#---------------------------------------------------------------------------
+
+BASIC_FORMAT = "%(levelname)s:%(name)s:%(message)s"
+
+def basicConfig(**kwargs):
+    """
+    Do basic configuration for the logging system.
+
+    This function does nothing if the root logger already has handlers
+    configured. It is a convenience method intended for use by simple scripts
+    to do one-shot configuration of the logging package.
+
+    The default behaviour is to create a StreamHandler which writes to
+    sys.stderr, set a formatter using the BASIC_FORMAT format string, and
+    add the handler to the root logger.
+
+    A number of optional keyword arguments may be specified, which can alter
+    the default behaviour.
+
+    filename  Specifies that a FileHandler be created, using the specified
+              filename, rather than a StreamHandler.
+    filemode  Specifies the mode to open the file, if filename is specified
+              (if filemode is unspecified, it defaults to 'a').
+    format    Use the specified format string for the handler.
+    datefmt   Use the specified date/time format.
+    level     Set the root logger level to the specified level.
+    stream    Use the specified stream to initialize the StreamHandler. Note
+              that this argument is incompatible with 'filename' - if both
+              are present, 'stream' is ignored.
+
+    Note that you could specify a stream created using open(filename, mode)
+    rather than passing the filename and mode in. However, it should be
+    remembered that StreamHandler does not close its stream (since it may be
+    using sys.stdout or sys.stderr), whereas FileHandler closes its stream
+    when the handler is closed.
+    """
+    if len(root.handlers) == 0:
+        filename = kwargs.get("filename")
+        if filename:
+            mode = kwargs.get("filemode", 'a')
+            hdlr = FileHandler(filename, mode)
+        else:
+            stream = kwargs.get("stream")
+            hdlr = StreamHandler(stream)
+        fs = kwargs.get("format", BASIC_FORMAT)
+        dfs = kwargs.get("datefmt", None)
+        fmt = Formatter(fs, dfs)
+        hdlr.setFormatter(fmt)
+        root.addHandler(hdlr)
+        level = kwargs.get("level")
+        if level:
+            root.setLevel(level)
+
+#---------------------------------------------------------------------------
+# Utility functions at module level.
+# Basically delegate everything to the root logger.
+#---------------------------------------------------------------------------
+
+def getLogger(name=None):
+    """
+    Return a logger with the specified name, creating it if necessary.
+
+    If no name is specified, return the root logger.
+    """
+    if name:
+        return Logger.manager.getLogger(name)
+    else:
+        return root
+
+#def getRootLogger():
+#    """
+#    Return the root logger.
+#
+#    Note that getLogger('') now does the same thing, so this function is
+#    deprecated and may disappear in the future.
+#    """
+#    return root
+
+def critical(msg, *args, **kwargs):
+    """
+    Log a message with severity 'CRITICAL' on the root logger.
+    """
+    if len(root.handlers) == 0:
+        basicConfig()
+    apply(root.critical, (msg,)+args, kwargs)
+
+fatal = critical
+
+def error(msg, *args, **kwargs):
+    """
+    Log a message with severity 'ERROR' on the root logger.
+    """
+    if len(root.handlers) == 0:
+        basicConfig()
+    apply(root.error, (msg,)+args, kwargs)
+
+def exception(msg, *args):
+    """
+    Log a message with severity 'ERROR' on the root logger,
+    with exception information.
+    """
+    apply(error, (msg,)+args, {'exc_info': 1})
+
+def warning(msg, *args, **kwargs):
+    """
+    Log a message with severity 'WARNING' on the root logger.
+    """
+    if len(root.handlers) == 0:
+        basicConfig()
+    apply(root.warning, (msg,)+args, kwargs)
+
+warn = warning
+
+def info(msg, *args, **kwargs):
+    """
+    Log a message with severity 'INFO' on the root logger.
+    """
+    if len(root.handlers) == 0:
+        basicConfig()
+    apply(root.info, (msg,)+args, kwargs)
+
+def debug(msg, *args, **kwargs):
+    """
+    Log a message with severity 'DEBUG' on the root logger.
+    """
+    if len(root.handlers) == 0:
+        basicConfig()
+    apply(root.debug, (msg,)+args, kwargs)
+
+def log(level, msg, *args, **kwargs):
+    """
+    Log 'msg % args' with the integer severity 'level' on the root logger.
+    """
+    if len(root.handlers) == 0:
+        basicConfig()
+    apply(root.log, (level, msg)+args, kwargs)
+
+def disable(level):
+    """
+    Disable all logging calls less severe than 'level'.
+    """
+    root.manager.disable = level
+
+def shutdown(handlerList=_handlerList):
+    """
+    Perform any cleanup actions in the logging system (e.g. flushing
+    buffers).
+
+    Should be called at application exit.
+    """
+    for h in handlerList[:]:
+        #errors might occur, for example, if files are locked
+        #we just ignore them if raiseExceptions is not set
+        try:
+            h.flush()
+            h.close()
+        except:
+            if raiseExceptions:
+                raise
+            #else, swallow
+
+#Let's try and shutdown automatically on application exit...
+try:
+    import atexit
+    atexit.register(shutdown)
+except ImportError: # for Python versions < 2.0
+    def exithook(status, old_exit=sys.exit):
+        try:
+            shutdown()
+        finally:
+            old_exit(status)
+
+    sys.exit = exithook

Added: vendor/Python/current/Lib/logging/config.py
===================================================================
--- vendor/Python/current/Lib/logging/config.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/logging/config.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,348 @@
+# Copyright 2001-2005 by Vinay Sajip. All Rights Reserved.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose and without fee is hereby granted,
+# provided that the above copyright notice appear in all copies and that
+# both that copyright notice and this permission notice appear in
+# supporting documentation, and that the name of Vinay Sajip
+# not be used in advertising or publicity pertaining to distribution
+# of the software without specific, written prior permission.
+# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+"""
+Configuration functions for the logging package for Python. The core package
+is based on PEP 282 and comments thereto in comp.lang.python, and influenced
+by Apache's log4j system.
+
+Should work under Python versions >= 1.5.2, except that source line
+information is not available unless 'sys._getframe()' is.
+
+Copyright (C) 2001-2004 Vinay Sajip. All Rights Reserved.
+
+To use, simply 'import logging' and log away!
+"""
+
+import sys, logging, logging.handlers, string, socket, struct, os, traceback, types
+
+try:
+    import thread
+    import threading
+except ImportError:
+    thread = None
+
+from SocketServer import ThreadingTCPServer, StreamRequestHandler
+
+
+DEFAULT_LOGGING_CONFIG_PORT = 9030
+
+if sys.platform == "win32":
+    RESET_ERROR = 10054   #WSAECONNRESET
+else:
+    RESET_ERROR = 104     #ECONNRESET
+
+#
+#   The following code implements a socket listener for on-the-fly
+#   reconfiguration of logging.
+#
+#   _listener holds the server object doing the listening
+_listener = None
+
+def fileConfig(fname, defaults=None):
+    """
+    Read the logging configuration from a ConfigParser-format file.
+
+    This can be called several times from an application, allowing an end user
+    the ability to select from various pre-canned configurations (if the
+    developer provides a mechanism to present the choices and load the chosen
+    configuration).
+    In versions of ConfigParser which have the readfp method [typically
+    shipped in 2.x versions of Python], you can pass in a file-like object
+    rather than a filename, in which case the file-like object will be read
+    using readfp.
+    """
+    import ConfigParser
+
+    cp = ConfigParser.ConfigParser(defaults)
+    if hasattr(cp, 'readfp') and hasattr(fname, 'readline'):
+        cp.readfp(fname)
+    else:
+        cp.read(fname)
+
+    formatters = _create_formatters(cp)
+
+    # critical section
+    logging._acquireLock()
+    try:
+        logging._handlers.clear()
+        del logging._handlerList[:]
+        # Handlers add themselves to logging._handlers
+        handlers = _install_handlers(cp, formatters)
+        _install_loggers(cp, handlers)
+    finally:
+        logging._releaseLock()
+
+
+def _resolve(name):
+    """Resolve a dotted name to a global object."""
+    name = string.split(name, '.')
+    used = name.pop(0)
+    found = __import__(used)
+    for n in name:
+        used = used + '.' + n
+        try:
+            found = getattr(found, n)
+        except AttributeError:
+            __import__(used)
+            found = getattr(found, n)
+    return found
+
+
+def _create_formatters(cp):
+    """Create and return formatters"""
+    flist = cp.get("formatters", "keys")
+    if not len(flist):
+        return {}
+    flist = string.split(flist, ",")
+    formatters = {}
+    for form in flist:
+        sectname = "formatter_%s" % string.strip(form)
+        opts = cp.options(sectname)
+        if "format" in opts:
+            fs = cp.get(sectname, "format", 1)
+        else:
+            fs = None
+        if "datefmt" in opts:
+            dfs = cp.get(sectname, "datefmt", 1)
+        else:
+            dfs = None
+        c = logging.Formatter
+        if "class" in opts:
+            class_name = cp.get(sectname, "class")
+            if class_name:
+                c = _resolve(class_name)
+        f = c(fs, dfs)
+        formatters[form] = f
+    return formatters
+
+
+def _install_handlers(cp, formatters):
+    """Install and return handlers"""
+    hlist = cp.get("handlers", "keys")
+    if not len(hlist):
+        return {}
+    hlist = string.split(hlist, ",")
+    handlers = {}
+    fixups = [] #for inter-handler references
+    for hand in hlist:
+        sectname = "handler_%s" % string.strip(hand)
+        klass = cp.get(sectname, "class")
+        opts = cp.options(sectname)
+        if "formatter" in opts:
+            fmt = cp.get(sectname, "formatter")
+        else:
+            fmt = ""
+        klass = eval(klass, vars(logging))
+        args = cp.get(sectname, "args")
+        args = eval(args, vars(logging))
+        h = apply(klass, args)
+        if "level" in opts:
+            level = cp.get(sectname, "level")
+            h.setLevel(logging._levelNames[level])
+        if len(fmt):
+            h.setFormatter(formatters[fmt])
+        #temporary hack for FileHandler and MemoryHandler.
+        if klass == logging.handlers.MemoryHandler:
+            if "target" in opts:
+                target = cp.get(sectname,"target")
+            else:
+                target = ""
+            if len(target): #the target handler may not be loaded yet, so keep for later...
+                fixups.append((h, target))
+        handlers[hand] = h
+    #now all handlers are loaded, fixup inter-handler references...
+    for h, t in fixups:
+        h.setTarget(handlers[t])
+    return handlers
+
+
+def _install_loggers(cp, handlers):
+    """Create and install loggers"""
+
+    # configure the root first
+    llist = cp.get("loggers", "keys")
+    llist = string.split(llist, ",")
+    llist = map(lambda x: string.strip(x), llist)
+    llist.remove("root")
+    sectname = "logger_root"
+    root = logging.root
+    log = root
+    opts = cp.options(sectname)
+    if "level" in opts:
+        level = cp.get(sectname, "level")
+        log.setLevel(logging._levelNames[level])
+    for h in root.handlers[:]:
+        root.removeHandler(h)
+    hlist = cp.get(sectname, "handlers")
+    if len(hlist):
+        hlist = string.split(hlist, ",")
+        for hand in hlist:
+            log.addHandler(handlers[string.strip(hand)])
+
+    #and now the others...
+    #we don't want to lose the existing loggers,
+    #since other threads may have pointers to them.
+    #existing is set to contain all existing loggers,
+    #and as we go through the new configuration we
+    #remove any which are configured. At the end,
+    #what's left in existing is the set of loggers
+    #which were in the previous configuration but
+    #which are not in the new configuration.
+    existing = root.manager.loggerDict.keys()
+    #now set up the new ones...
+    for log in llist:
+        sectname = "logger_%s" % log
+        qn = cp.get(sectname, "qualname")
+        opts = cp.options(sectname)
+        if "propagate" in opts:
+            propagate = cp.getint(sectname, "propagate")
+        else:
+            propagate = 1
+        logger = logging.getLogger(qn)
+        if qn in existing:
+            existing.remove(qn)
+        if "level" in opts:
+            level = cp.get(sectname, "level")
+            logger.setLevel(logging._levelNames[level])
+        for h in logger.handlers[:]:
+            logger.removeHandler(h)
+        logger.propagate = propagate
+        logger.disabled = 0
+        hlist = cp.get(sectname, "handlers")
+        if len(hlist):
+            hlist = string.split(hlist, ",")
+            for hand in hlist:
+                logger.addHandler(handlers[string.strip(hand)])
+
+    #Disable any old loggers. There's no point deleting
+    #them as other threads may continue to hold references
+    #and by disabling them, you stop them doing any logging.
+    for log in existing:
+        root.manager.loggerDict[log].disabled = 1
+
+
+def listen(port=DEFAULT_LOGGING_CONFIG_PORT):
+    """
+    Start up a socket server on the specified port, and listen for new
+    configurations.
+
+    These will be sent as a file suitable for processing by fileConfig().
+    Returns a Thread object on which you can call start() to start the server,
+    and which you can join() when appropriate. To stop the server, call
+    stopListening().
+    """
+    if not thread:
+        raise NotImplementedError, "listen() needs threading to work"
+
+    class ConfigStreamHandler(StreamRequestHandler):
+        """
+        Handler for a logging configuration request.
+
+        It expects a completely new logging configuration and uses fileConfig
+        to install it.
+        """
+        def handle(self):
+            """
+            Handle a request.
+
+            Each request is expected to be a 4-byte length, packed using
+            struct.pack(">L", n), followed by the config file.
+            Uses fileConfig() to do the grunt work.
+            """
+            import tempfile
+            try:
+                conn = self.connection
+                chunk = conn.recv(4)
+                if len(chunk) == 4:
+                    slen = struct.unpack(">L", chunk)[0]
+                    chunk = self.connection.recv(slen)
+                    while len(chunk) < slen:
+                        chunk = chunk + conn.recv(slen - len(chunk))
+                    #Apply new configuration. We'd like to be able to
+                    #create a StringIO and pass that in, but unfortunately
+                    #1.5.2 ConfigParser does not support reading file
+                    #objects, only actual files. So we create a temporary
+                    #file and remove it later.
+                    file = tempfile.mktemp(".ini")
+                    f = open(file, "w")
+                    f.write(chunk)
+                    f.close()
+                    try:
+                        fileConfig(file)
+                    except (KeyboardInterrupt, SystemExit):
+                        raise
+                    except:
+                        traceback.print_exc()
+                    os.remove(file)
+            except socket.error, e:
+                if type(e.args) != types.TupleType:
+                    raise
+                else:
+                    errcode = e.args[0]
+                    if errcode != RESET_ERROR:
+                        raise
+
+    class ConfigSocketReceiver(ThreadingTCPServer):
+        """
+        A simple TCP socket-based logging config receiver.
+        """
+
+        allow_reuse_address = 1
+
+        def __init__(self, host='localhost', port=DEFAULT_LOGGING_CONFIG_PORT,
+                     handler=None):
+            ThreadingTCPServer.__init__(self, (host, port), handler)
+            logging._acquireLock()
+            self.abort = 0
+            logging._releaseLock()
+            self.timeout = 1
+
+        def serve_until_stopped(self):
+            import select
+            abort = 0
+            while not abort:
+                rd, wr, ex = select.select([self.socket.fileno()],
+                                           [], [],
+                                           self.timeout)
+                if rd:
+                    self.handle_request()
+                logging._acquireLock()
+                abort = self.abort
+                logging._releaseLock()
+
+    def serve(rcvr, hdlr, port):
+        server = rcvr(port=port, handler=hdlr)
+        global _listener
+        logging._acquireLock()
+        _listener = server
+        logging._releaseLock()
+        server.serve_until_stopped()
+
+    return threading.Thread(target=serve,
+                            args=(ConfigSocketReceiver,
+                                  ConfigStreamHandler, port))
+
+def stopListening():
+    """
+    Stop the listening server which was created with a call to listen().
+    """
+    global _listener
+    if _listener:
+        logging._acquireLock()
+        _listener.abort = 1
+        _listener = None
+        logging._releaseLock()

Added: vendor/Python/current/Lib/logging/handlers.py
===================================================================
--- vendor/Python/current/Lib/logging/handlers.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/logging/handlers.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1019 @@
+# Copyright 2001-2005 by Vinay Sajip. All Rights Reserved.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose and without fee is hereby granted,
+# provided that the above copyright notice appear in all copies and that
+# both that copyright notice and this permission notice appear in
+# supporting documentation, and that the name of Vinay Sajip
+# not be used in advertising or publicity pertaining to distribution
+# of the software without specific, written prior permission.
+# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+"""
+Additional handlers for the logging package for Python. The core package is
+based on PEP 282 and comments thereto in comp.lang.python, and influenced by
+Apache's log4j system.
+
+Should work under Python versions >= 1.5.2, except that source line
+information is not available unless 'sys._getframe()' is.
+
+Copyright (C) 2001-2004 Vinay Sajip. All Rights Reserved.
+
+To use, simply 'import logging' and log away!
+"""
+
+import sys, logging, socket, types, os, string, cPickle, struct, time, glob
+
+try:
+    import codecs
+except ImportError:
+    codecs = None
+
+#
+# Some constants...
+#
+
+DEFAULT_TCP_LOGGING_PORT    = 9020
+DEFAULT_UDP_LOGGING_PORT    = 9021
+DEFAULT_HTTP_LOGGING_PORT   = 9022
+DEFAULT_SOAP_LOGGING_PORT   = 9023
+SYSLOG_UDP_PORT             = 514
+
+_MIDNIGHT = 24 * 60 * 60  # number of seconds in a day
+
+class BaseRotatingHandler(logging.FileHandler):
+    """
+    Base class for handlers that rotate log files at a certain point.
+    Not meant to be instantiated directly.  Instead, use RotatingFileHandler
+    or TimedRotatingFileHandler.
+    """
+    def __init__(self, filename, mode, encoding=None):
+        """
+        Use the specified filename for streamed logging
+        """
+        if codecs is None:
+            encoding = None
+        logging.FileHandler.__init__(self, filename, mode, encoding)
+        self.mode = mode
+        self.encoding = encoding
+
+    def emit(self, record):
+        """
+        Emit a record.
+
+        Output the record to the file, catering for rollover as described
+        in doRollover().
+        """
+        try:
+            if self.shouldRollover(record):
+                self.doRollover()
+            logging.FileHandler.emit(self, record)
+        except (KeyboardInterrupt, SystemExit):
+            raise
+        except:
+            self.handleError(record)
+
+class RotatingFileHandler(BaseRotatingHandler):
+    """
+    Handler for logging to a set of files, which switches from one file
+    to the next when the current file reaches a certain size.
+    """
+    def __init__(self, filename, mode='a', maxBytes=0, backupCount=0, encoding=None):
+        """
+        Open the specified file and use it as the stream for logging.
+
+        By default, the file grows indefinitely. You can specify particular
+        values of maxBytes and backupCount to allow the file to rollover at
+        a predetermined size.
+
+        Rollover occurs whenever the current log file is nearly maxBytes in
+        length. If backupCount is >= 1, the system will successively create
+        new files with the same pathname as the base file, but with extensions
+        ".1", ".2" etc. appended to it. For example, with a backupCount of 5
+        and a base file name of "app.log", you would get "app.log",
+        "app.log.1", "app.log.2", ... through to "app.log.5". The file being
+        written to is always "app.log" - when it gets filled up, it is closed
+        and renamed to "app.log.1", and if files "app.log.1", "app.log.2" etc.
+        exist, then they are renamed to "app.log.2", "app.log.3" etc.
+        respectively.
+
+        If maxBytes is zero, rollover never occurs.
+        """
+        if maxBytes > 0:
+            mode = 'a' # doesn't make sense otherwise!
+        BaseRotatingHandler.__init__(self, filename, mode, encoding)
+        self.maxBytes = maxBytes
+        self.backupCount = backupCount
+
+    def doRollover(self):
+        """
+        Do a rollover, as described in __init__().
+        """
+
+        self.stream.close()
+        if self.backupCount > 0:
+            for i in range(self.backupCount - 1, 0, -1):
+                sfn = "%s.%d" % (self.baseFilename, i)
+                dfn = "%s.%d" % (self.baseFilename, i + 1)
+                if os.path.exists(sfn):
+                    #print "%s -> %s" % (sfn, dfn)
+                    if os.path.exists(dfn):
+                        os.remove(dfn)
+                    os.rename(sfn, dfn)
+            dfn = self.baseFilename + ".1"
+            if os.path.exists(dfn):
+                os.remove(dfn)
+            os.rename(self.baseFilename, dfn)
+            #print "%s -> %s" % (self.baseFilename, dfn)
+        if self.encoding:
+            self.stream = codecs.open(self.baseFilename, 'w', self.encoding)
+        else:
+            self.stream = open(self.baseFilename, 'w')
+
+    def shouldRollover(self, record):
+        """
+        Determine if rollover should occur.
+
+        Basically, see if the supplied record would cause the file to exceed
+        the size limit we have.
+        """
+        if self.maxBytes > 0:                   # are we rolling over?
+            msg = "%s\n" % self.format(record)
+            self.stream.seek(0, 2)  #due to non-posix-compliant Windows feature
+            if self.stream.tell() + len(msg) >= self.maxBytes:
+                return 1
+        return 0
+
+class TimedRotatingFileHandler(BaseRotatingHandler):
+    """
+    Handler for logging to a file, rotating the log file at certain timed
+    intervals.
+
+    If backupCount is > 0, when rollover is done, no more than backupCount
+    files are kept - the oldest ones are deleted.
+    """
+    def __init__(self, filename, when='h', interval=1, backupCount=0, encoding=None):
+        BaseRotatingHandler.__init__(self, filename, 'a', encoding)
+        self.when = string.upper(when)
+        self.backupCount = backupCount
+        # Calculate the real rollover interval, which is just the number of
+        # seconds between rollovers.  Also set the filename suffix used when
+        # a rollover occurs.  Current 'when' events supported:
+        # S - Seconds
+        # M - Minutes
+        # H - Hours
+        # D - Days
+        # midnight - roll over at midnight
+        # W{0-6} - roll over on a certain day; 0 - Monday
+        #
+        # Case of the 'when' specifier is not important; lower or upper case
+        # will work.
+        currentTime = int(time.time())
+        if self.when == 'S':
+            self.interval = 1 # one second
+            self.suffix = "%Y-%m-%d_%H-%M-%S"
+        elif self.when == 'M':
+            self.interval = 60 # one minute
+            self.suffix = "%Y-%m-%d_%H-%M"
+        elif self.when == 'H':
+            self.interval = 60 * 60 # one hour
+            self.suffix = "%Y-%m-%d_%H"
+        elif self.when == 'D' or self.when == 'MIDNIGHT':
+            self.interval = 60 * 60 * 24 # one day
+            self.suffix = "%Y-%m-%d"
+        elif self.when.startswith('W'):
+            self.interval = 60 * 60 * 24 * 7 # one week
+            if len(self.when) != 2:
+                raise ValueError("You must specify a day for weekly rollover from 0 to 6 (0 is Monday): %s" % self.when)
+            if self.when[1] < '0' or self.when[1] > '6':
+                raise ValueError("Invalid day specified for weekly rollover: %s" % self.when)
+            self.dayOfWeek = int(self.when[1])
+            self.suffix = "%Y-%m-%d"
+        else:
+            raise ValueError("Invalid rollover interval specified: %s" % self.when)
+
+        self.interval = self.interval * interval # multiply by units requested
+        self.rolloverAt = currentTime + self.interval
+
+        # If we are rolling over at midnight or weekly, then the interval is already known.
+        # What we need to figure out is WHEN the next interval is.  In other words,
+        # if you are rolling over at midnight, then your base interval is 1 day,
+        # but you want to start that one day clock at midnight, not now.  So, we
+        # have to fudge the rolloverAt value in order to trigger the first rollover
+        # at the right time.  After that, the regular interval will take care of
+        # the rest.  Note that this code doesn't care about leap seconds. :)
+        if self.when == 'MIDNIGHT' or self.when.startswith('W'):
+            # This could be done with less code, but I wanted it to be clear
+            t = time.localtime(currentTime)
+            currentHour = t[3]
+            currentMinute = t[4]
+            currentSecond = t[5]
+            # r is the number of seconds left between now and midnight
+            r = _MIDNIGHT - ((currentHour * 60 + currentMinute) * 60 +
+                    currentSecond)
+            self.rolloverAt = currentTime + r
+            # If we are rolling over on a certain day, add in the number of days until
+            # the next rollover, but offset by 1 since we just calculated the time
+            # until the next day starts.  There are three cases:
+            # Case 1) The day to rollover is today; in this case, do nothing
+            # Case 2) The day to rollover is further in the interval (i.e., today is
+            #         day 2 (Wednesday) and rollover is on day 6 (Sunday).  Days to
+            #         next rollover is simply 6 - 2 - 1, or 3.
+            # Case 3) The day to rollover is behind us in the interval (i.e., today
+            #         is day 5 (Saturday) and rollover is on day 3 (Thursday).
+            #         Days to rollover is 6 - 5 + 3, or 4.  In this case, it's the
+            #         number of days left in the current week (1) plus the number
+            #         of days in the next week until the rollover day (3).
+            if when.startswith('W'):
+                day = t[6] # 0 is Monday
+                if day > self.dayOfWeek:
+                    daysToWait = (day - self.dayOfWeek) - 1
+                    self.rolloverAt = self.rolloverAt + (daysToWait * (60 * 60 * 24))
+                if day < self.dayOfWeek:
+                    daysToWait = (6 - self.dayOfWeek) + day
+                    self.rolloverAt = self.rolloverAt + (daysToWait * (60 * 60 * 24))
+
+        #print "Will rollover at %d, %d seconds from now" % (self.rolloverAt, self.rolloverAt - currentTime)
+
+    def shouldRollover(self, record):
+        """
+        Determine if rollover should occur
+
+        record is not used, as we are just comparing times, but it is needed so
+        the method siguratures are the same
+        """
+        t = int(time.time())
+        if t >= self.rolloverAt:
+            return 1
+        #print "No need to rollover: %d, %d" % (t, self.rolloverAt)
+        return 0
+
+    def doRollover(self):
+        """
+        do a rollover; in this case, a date/time stamp is appended to the filename
+        when the rollover happens.  However, you want the file to be named for the
+        start of the interval, not the current time.  If there is a backup count,
+        then we have to get a list of matching filenames, sort them and remove
+        the one with the oldest suffix.
+        """
+        self.stream.close()
+        # get the time that this sequence started at and make it a TimeTuple
+        t = self.rolloverAt - self.interval
+        timeTuple = time.localtime(t)
+        dfn = self.baseFilename + "." + time.strftime(self.suffix, timeTuple)
+        if os.path.exists(dfn):
+            os.remove(dfn)
+        os.rename(self.baseFilename, dfn)
+        if self.backupCount > 0:
+            # find the oldest log file and delete it
+            s = glob.glob(self.baseFilename + ".20*")
+            if len(s) > self.backupCount:
+                s.sort()
+                os.remove(s[0])
+        #print "%s -> %s" % (self.baseFilename, dfn)
+        if self.encoding:
+            self.stream = codecs.open(self.baseFilename, 'w', self.encoding)
+        else:
+            self.stream = open(self.baseFilename, 'w')
+        self.rolloverAt = self.rolloverAt + self.interval
+
+class SocketHandler(logging.Handler):
+    """
+    A handler class which writes logging records, in pickle format, to
+    a streaming socket. The socket is kept open across logging calls.
+    If the peer resets it, an attempt is made to reconnect on the next call.
+    The pickle which is sent is that of the LogRecord's attribute dictionary
+    (__dict__), so that the receiver does not need to have the logging module
+    installed in order to process the logging event.
+
+    To unpickle the record at the receiving end into a LogRecord, use the
+    makeLogRecord function.
+    """
+
+    def __init__(self, host, port):
+        """
+        Initializes the handler with a specific host address and port.
+
+        The attribute 'closeOnError' is set to 1 - which means that if
+        a socket error occurs, the socket is silently closed and then
+        reopened on the next logging call.
+        """
+        logging.Handler.__init__(self)
+        self.host = host
+        self.port = port
+        self.sock = None
+        self.closeOnError = 0
+        self.retryTime = None
+        #
+        # Exponential backoff parameters.
+        #
+        self.retryStart = 1.0
+        self.retryMax = 30.0
+        self.retryFactor = 2.0
+
+    def makeSocket(self):
+        """
+        A factory method which allows subclasses to define the precise
+        type of socket they want.
+        """
+        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        s.connect((self.host, self.port))
+        return s
+
+    def createSocket(self):
+        """
+        Try to create a socket, using an exponential backoff with
+        a max retry time. Thanks to Robert Olson for the original patch
+        (SF #815911) which has been slightly refactored.
+        """
+        now = time.time()
+        # Either retryTime is None, in which case this
+        # is the first time back after a disconnect, or
+        # we've waited long enough.
+        if self.retryTime is None:
+            attempt = 1
+        else:
+            attempt = (now >= self.retryTime)
+        if attempt:
+            try:
+                self.sock = self.makeSocket()
+                self.retryTime = None # next time, no delay before trying
+            except:
+                #Creation failed, so set the retry time and return.
+                if self.retryTime is None:
+                    self.retryPeriod = self.retryStart
+                else:
+                    self.retryPeriod = self.retryPeriod * self.retryFactor
+                    if self.retryPeriod > self.retryMax:
+                        self.retryPeriod = self.retryMax
+                self.retryTime = now + self.retryPeriod
+
+    def send(self, s):
+        """
+        Send a pickled string to the socket.
+
+        This function allows for partial sends which can happen when the
+        network is busy.
+        """
+        if self.sock is None:
+            self.createSocket()
+        #self.sock can be None either because we haven't reached the retry
+        #time yet, or because we have reached the retry time and retried,
+        #but are still unable to connect.
+        if self.sock:
+            try:
+                if hasattr(self.sock, "sendall"):
+                    self.sock.sendall(s)
+                else:
+                    sentsofar = 0
+                    left = len(s)
+                    while left > 0:
+                        sent = self.sock.send(s[sentsofar:])
+                        sentsofar = sentsofar + sent
+                        left = left - sent
+            except socket.error:
+                self.sock.close()
+                self.sock = None  # so we can call createSocket next time
+
+    def makePickle(self, record):
+        """
+        Pickles the record in binary format with a length prefix, and
+        returns it ready for transmission across the socket.
+        """
+        ei = record.exc_info
+        if ei:
+            dummy = self.format(record) # just to get traceback text into record.exc_text
+            record.exc_info = None  # to avoid Unpickleable error
+        s = cPickle.dumps(record.__dict__, 1)
+        if ei:
+            record.exc_info = ei  # for next handler
+        slen = struct.pack(">L", len(s))
+        return slen + s
+
+    def handleError(self, record):
+        """
+        Handle an error during logging.
+
+        An error has occurred during logging. Most likely cause -
+        connection lost. Close the socket so that we can retry on the
+        next event.
+        """
+        if self.closeOnError and self.sock:
+            self.sock.close()
+            self.sock = None        #try to reconnect next time
+        else:
+            logging.Handler.handleError(self, record)
+
+    def emit(self, record):
+        """
+        Emit a record.
+
+        Pickles the record and writes it to the socket in binary format.
+        If there is an error with the socket, silently drop the packet.
+        If there was a problem with the socket, re-establishes the
+        socket.
+        """
+        try:
+            s = self.makePickle(record)
+            self.send(s)
+        except (KeyboardInterrupt, SystemExit):
+            raise
+        except:
+            self.handleError(record)
+
+    def close(self):
+        """
+        Closes the socket.
+        """
+        if self.sock:
+            self.sock.close()
+            self.sock = None
+        logging.Handler.close(self)
+
+class DatagramHandler(SocketHandler):
+    """
+    A handler class which writes logging records, in pickle format, to
+    a datagram socket.  The pickle which is sent is that of the LogRecord's
+    attribute dictionary (__dict__), so that the receiver does not need to
+    have the logging module installed in order to process the logging event.
+
+    To unpickle the record at the receiving end into a LogRecord, use the
+    makeLogRecord function.
+
+    """
+    def __init__(self, host, port):
+        """
+        Initializes the handler with a specific host address and port.
+        """
+        SocketHandler.__init__(self, host, port)
+        self.closeOnError = 0
+
+    def makeSocket(self):
+        """
+        The factory method of SocketHandler is here overridden to create
+        a UDP socket (SOCK_DGRAM).
+        """
+        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+        return s
+
+    def send(self, s):
+        """
+        Send a pickled string to a socket.
+
+        This function no longer allows for partial sends which can happen
+        when the network is busy - UDP does not guarantee delivery and
+        can deliver packets out of sequence.
+        """
+        if self.sock is None:
+            self.createSocket()
+        self.sock.sendto(s, (self.host, self.port))
+
+class SysLogHandler(logging.Handler):
+    """
+    A handler class which sends formatted logging records to a syslog
+    server. Based on Sam Rushing's syslog module:
+    http://www.nightmare.com/squirl/python-ext/misc/syslog.py
+    Contributed by Nicolas Untz (after which minor refactoring changes
+    have been made).
+    """
+
+    # from <linux/sys/syslog.h>:
+    # ======================================================================
+    # priorities/facilities are encoded into a single 32-bit quantity, where
+    # the bottom 3 bits are the priority (0-7) and the top 28 bits are the
+    # facility (0-big number). Both the priorities and the facilities map
+    # roughly one-to-one to strings in the syslogd(8) source code.  This
+    # mapping is included in this file.
+    #
+    # priorities (these are ordered)
+
+    LOG_EMERG     = 0       #  system is unusable
+    LOG_ALERT     = 1       #  action must be taken immediately
+    LOG_CRIT      = 2       #  critical conditions
+    LOG_ERR       = 3       #  error conditions
+    LOG_WARNING   = 4       #  warning conditions
+    LOG_NOTICE    = 5       #  normal but significant condition
+    LOG_INFO      = 6       #  informational
+    LOG_DEBUG     = 7       #  debug-level messages
+
+    #  facility codes
+    LOG_KERN      = 0       #  kernel messages
+    LOG_USER      = 1       #  random user-level messages
+    LOG_MAIL      = 2       #  mail system
+    LOG_DAEMON    = 3       #  system daemons
+    LOG_AUTH      = 4       #  security/authorization messages
+    LOG_SYSLOG    = 5       #  messages generated internally by syslogd
+    LOG_LPR       = 6       #  line printer subsystem
+    LOG_NEWS      = 7       #  network news subsystem
+    LOG_UUCP      = 8       #  UUCP subsystem
+    LOG_CRON      = 9       #  clock daemon
+    LOG_AUTHPRIV  = 10  #  security/authorization messages (private)
+
+    #  other codes through 15 reserved for system use
+    LOG_LOCAL0    = 16      #  reserved for local use
+    LOG_LOCAL1    = 17      #  reserved for local use
+    LOG_LOCAL2    = 18      #  reserved for local use
+    LOG_LOCAL3    = 19      #  reserved for local use
+    LOG_LOCAL4    = 20      #  reserved for local use
+    LOG_LOCAL5    = 21      #  reserved for local use
+    LOG_LOCAL6    = 22      #  reserved for local use
+    LOG_LOCAL7    = 23      #  reserved for local use
+
+    priority_names = {
+        "alert":    LOG_ALERT,
+        "crit":     LOG_CRIT,
+        "critical": LOG_CRIT,
+        "debug":    LOG_DEBUG,
+        "emerg":    LOG_EMERG,
+        "err":      LOG_ERR,
+        "error":    LOG_ERR,        #  DEPRECATED
+        "info":     LOG_INFO,
+        "notice":   LOG_NOTICE,
+        "panic":    LOG_EMERG,      #  DEPRECATED
+        "warn":     LOG_WARNING,    #  DEPRECATED
+        "warning":  LOG_WARNING,
+        }
+
+    facility_names = {
+        "auth":     LOG_AUTH,
+        "authpriv": LOG_AUTHPRIV,
+        "cron":     LOG_CRON,
+        "daemon":   LOG_DAEMON,
+        "kern":     LOG_KERN,
+        "lpr":      LOG_LPR,
+        "mail":     LOG_MAIL,
+        "news":     LOG_NEWS,
+        "security": LOG_AUTH,       #  DEPRECATED
+        "syslog":   LOG_SYSLOG,
+        "user":     LOG_USER,
+        "uucp":     LOG_UUCP,
+        "local0":   LOG_LOCAL0,
+        "local1":   LOG_LOCAL1,
+        "local2":   LOG_LOCAL2,
+        "local3":   LOG_LOCAL3,
+        "local4":   LOG_LOCAL4,
+        "local5":   LOG_LOCAL5,
+        "local6":   LOG_LOCAL6,
+        "local7":   LOG_LOCAL7,
+        }
+
+    #The map below appears to be trivially lowercasing the key. However,
+    #there's more to it than meets the eye - in some locales, lowercasing
+    #gives unexpected results. See SF #1524081: in the Turkish locale,
+    #"INFO".lower() != "info"
+    priority_map = {
+        "DEBUG" : "debug",
+        "INFO" : "info",
+        "WARNING" : "warning",
+        "ERROR" : "error",
+        "CRITICAL" : "critical"
+    }
+
+    def __init__(self, address=('localhost', SYSLOG_UDP_PORT), facility=LOG_USER):
+        """
+        Initialize a handler.
+
+        If address is specified as a string, UNIX socket is used.
+        If facility is not specified, LOG_USER is used.
+        """
+        logging.Handler.__init__(self)
+
+        self.address = address
+        self.facility = facility
+        if type(address) == types.StringType:
+            self.unixsocket = 1
+            self._connect_unixsocket(address)
+        else:
+            self.unixsocket = 0
+            self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+
+        self.formatter = None
+
+    def _connect_unixsocket(self, address):
+        self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
+        # syslog may require either DGRAM or STREAM sockets
+        try:
+            self.socket.connect(address)
+        except socket.error:
+            self.socket.close()
+            self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+            self.socket.connect(address)
+
+    # curious: when talking to the unix-domain '/dev/log' socket, a
+    #   zero-terminator seems to be required.  this string is placed
+    #   into a class variable so that it can be overridden if
+    #   necessary.
+    log_format_string = '<%d>%s\000'
+
+    def encodePriority(self, facility, priority):
+        """
+        Encode the facility and priority. You can pass in strings or
+        integers - if strings are passed, the facility_names and
+        priority_names mapping dictionaries are used to convert them to
+        integers.
+        """
+        if type(facility) == types.StringType:
+            facility = self.facility_names[facility]
+        if type(priority) == types.StringType:
+            priority = self.priority_names[priority]
+        return (facility << 3) | priority
+
+    def close (self):
+        """
+        Closes the socket.
+        """
+        if self.unixsocket:
+            self.socket.close()
+        logging.Handler.close(self)
+
+    def mapPriority(self, levelName):
+        """
+        Map a logging level name to a key in the priority_names map.
+        This is useful in two scenarios: when custom levels are being
+        used, and in the case where you can't do a straightforward
+        mapping by lowercasing the logging level name because of locale-
+        specific issues (see SF #1524081).
+        """
+        return self.priority_map.get(levelName, "warning")
+
+    def emit(self, record):
+        """
+        Emit a record.
+
+        The record is formatted, and then sent to the syslog server. If
+        exception information is present, it is NOT sent to the server.
+        """
+        msg = self.format(record)
+        """
+        We need to convert record level to lowercase, maybe this will
+        change in the future.
+        """
+        msg = self.log_format_string % (
+            self.encodePriority(self.facility,
+                                self.mapPriority(record.levelname)),
+                                msg)
+        try:
+            if self.unixsocket:
+                try:
+                    self.socket.send(msg)
+                except socket.error:
+                    self._connect_unixsocket(self.address)
+                    self.socket.send(msg)
+            else:
+                self.socket.sendto(msg, self.address)
+        except (KeyboardInterrupt, SystemExit):
+            raise
+        except:
+            self.handleError(record)
+
+class SMTPHandler(logging.Handler):
+    """
+    A handler class which sends an SMTP email for each logging event.
+    """
+    def __init__(self, mailhost, fromaddr, toaddrs, subject):
+        """
+        Initialize the handler.
+
+        Initialize the instance with the from and to addresses and subject
+        line of the email. To specify a non-standard SMTP port, use the
+        (host, port) tuple format for the mailhost argument.
+        """
+        logging.Handler.__init__(self)
+        if type(mailhost) == types.TupleType:
+            host, port = mailhost
+            self.mailhost = host
+            self.mailport = port
+        else:
+            self.mailhost = mailhost
+            self.mailport = None
+        self.fromaddr = fromaddr
+        if type(toaddrs) == types.StringType:
+            toaddrs = [toaddrs]
+        self.toaddrs = toaddrs
+        self.subject = subject
+
+    def getSubject(self, record):
+        """
+        Determine the subject for the email.
+
+        If you want to specify a subject line which is record-dependent,
+        override this method.
+        """
+        return self.subject
+
+    weekdayname = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
+
+    monthname = [None,
+                 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
+                 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
+
+    def date_time(self):
+        """
+        Return the current date and time formatted for a MIME header.
+        Needed for Python 1.5.2 (no email package available)
+        """
+        year, month, day, hh, mm, ss, wd, y, z = time.gmtime(time.time())
+        s = "%s, %02d %3s %4d %02d:%02d:%02d GMT" % (
+                self.weekdayname[wd],
+                day, self.monthname[month], year,
+                hh, mm, ss)
+        return s
+
+    def emit(self, record):
+        """
+        Emit a record.
+
+        Format the record and send it to the specified addressees.
+        """
+        try:
+            import smtplib
+            try:
+                from email.Utils import formatdate
+            except:
+                formatdate = self.date_time
+            port = self.mailport
+            if not port:
+                port = smtplib.SMTP_PORT
+            smtp = smtplib.SMTP(self.mailhost, port)
+            msg = self.format(record)
+            msg = "From: %s\r\nTo: %s\r\nSubject: %s\r\nDate: %s\r\n\r\n%s" % (
+                            self.fromaddr,
+                            string.join(self.toaddrs, ","),
+                            self.getSubject(record),
+                            formatdate(), msg)
+            smtp.sendmail(self.fromaddr, self.toaddrs, msg)
+            smtp.quit()
+        except (KeyboardInterrupt, SystemExit):
+            raise
+        except:
+            self.handleError(record)
+
+class NTEventLogHandler(logging.Handler):
+    """
+    A handler class which sends events to the NT Event Log. Adds a
+    registry entry for the specified application name. If no dllname is
+    provided, win32service.pyd (which contains some basic message
+    placeholders) is used. Note that use of these placeholders will make
+    your event logs big, as the entire message source is held in the log.
+    If you want slimmer logs, you have to pass in the name of your own DLL
+    which contains the message definitions you want to use in the event log.
+    """
+    def __init__(self, appname, dllname=None, logtype="Application"):
+        logging.Handler.__init__(self)
+        try:
+            import win32evtlogutil, win32evtlog
+            self.appname = appname
+            self._welu = win32evtlogutil
+            if not dllname:
+                dllname = os.path.split(self._welu.__file__)
+                dllname = os.path.split(dllname[0])
+                dllname = os.path.join(dllname[0], r'win32service.pyd')
+            self.dllname = dllname
+            self.logtype = logtype
+            self._welu.AddSourceToRegistry(appname, dllname, logtype)
+            self.deftype = win32evtlog.EVENTLOG_ERROR_TYPE
+            self.typemap = {
+                logging.DEBUG   : win32evtlog.EVENTLOG_INFORMATION_TYPE,
+                logging.INFO    : win32evtlog.EVENTLOG_INFORMATION_TYPE,
+                logging.WARNING : win32evtlog.EVENTLOG_WARNING_TYPE,
+                logging.ERROR   : win32evtlog.EVENTLOG_ERROR_TYPE,
+                logging.CRITICAL: win32evtlog.EVENTLOG_ERROR_TYPE,
+         }
+        except ImportError:
+            print "The Python Win32 extensions for NT (service, event "\
+                        "logging) appear not to be available."
+            self._welu = None
+
+    def getMessageID(self, record):
+        """
+        Return the message ID for the event record. If you are using your
+        own messages, you could do this by having the msg passed to the
+        logger being an ID rather than a formatting string. Then, in here,
+        you could use a dictionary lookup to get the message ID. This
+        version returns 1, which is the base message ID in win32service.pyd.
+        """
+        return 1
+
+    def getEventCategory(self, record):
+        """
+        Return the event category for the record.
+
+        Override this if you want to specify your own categories. This version
+        returns 0.
+        """
+        return 0
+
+    def getEventType(self, record):
+        """
+        Return the event type for the record.
+
+        Override this if you want to specify your own types. This version does
+        a mapping using the handler's typemap attribute, which is set up in
+        __init__() to a dictionary which contains mappings for DEBUG, INFO,
+        WARNING, ERROR and CRITICAL. If you are using your own levels you will
+        either need to override this method or place a suitable dictionary in
+        the handler's typemap attribute.
+        """
+        return self.typemap.get(record.levelno, self.deftype)
+
+    def emit(self, record):
+        """
+        Emit a record.
+
+        Determine the message ID, event category and event type. Then
+        log the message in the NT event log.
+        """
+        if self._welu:
+            try:
+                id = self.getMessageID(record)
+                cat = self.getEventCategory(record)
+                type = self.getEventType(record)
+                msg = self.format(record)
+                self._welu.ReportEvent(self.appname, id, cat, type, [msg])
+            except (KeyboardInterrupt, SystemExit):
+                raise
+            except:
+                self.handleError(record)
+
+    def close(self):
+        """
+        Clean up this handler.
+
+        You can remove the application name from the registry as a
+        source of event log entries. However, if you do this, you will
+        not be able to see the events as you intended in the Event Log
+        Viewer - it needs to be able to access the registry to get the
+        DLL name.
+        """
+        #self._welu.RemoveSourceFromRegistry(self.appname, self.logtype)
+        logging.Handler.close(self)
+
+class HTTPHandler(logging.Handler):
+    """
+    A class which sends records to a Web server, using either GET or
+    POST semantics.
+    """
+    def __init__(self, host, url, method="GET"):
+        """
+        Initialize the instance with the host, the request URL, and the method
+        ("GET" or "POST")
+        """
+        logging.Handler.__init__(self)
+        method = string.upper(method)
+        if method not in ["GET", "POST"]:
+            raise ValueError, "method must be GET or POST"
+        self.host = host
+        self.url = url
+        self.method = method
+
+    def mapLogRecord(self, record):
+        """
+        Default implementation of mapping the log record into a dict
+        that is sent as the CGI data. Overwrite in your class.
+        Contributed by Franz  Glasner.
+        """
+        return record.__dict__
+
+    def emit(self, record):
+        """
+        Emit a record.
+
+        Send the record to the Web server as an URL-encoded dictionary
+        """
+        try:
+            import httplib, urllib
+            host = self.host
+            h = httplib.HTTP(host)
+            url = self.url
+            data = urllib.urlencode(self.mapLogRecord(record))
+            if self.method == "GET":
+                if (string.find(url, '?') >= 0):
+                    sep = '&'
+                else:
+                    sep = '?'
+                url = url + "%c%s" % (sep, data)
+            h.putrequest(self.method, url)
+            # support multiple hosts on one IP address...
+            # need to strip optional :port from host, if present
+            i = string.find(host, ":")
+            if i >= 0:
+                host = host[:i]
+            h.putheader("Host", host)
+            if self.method == "POST":
+                h.putheader("Content-type",
+                            "application/x-www-form-urlencoded")
+                h.putheader("Content-length", str(len(data)))
+            h.endheaders()
+            if self.method == "POST":
+                h.send(data)
+            h.getreply()    #can't do anything with the result
+        except (KeyboardInterrupt, SystemExit):
+            raise
+        except:
+            self.handleError(record)
+
+class BufferingHandler(logging.Handler):
+    """
+  A handler class which buffers logging records in memory. Whenever each
+  record is added to the buffer, a check is made to see if the buffer should
+  be flushed. If it should, then flush() is expected to do what's needed.
+    """
+    def __init__(self, capacity):
+        """
+        Initialize the handler with the buffer size.
+        """
+        logging.Handler.__init__(self)
+        self.capacity = capacity
+        self.buffer = []
+
+    def shouldFlush(self, record):
+        """
+        Should the handler flush its buffer?
+
+        Returns true if the buffer is up to capacity. This method can be
+        overridden to implement custom flushing strategies.
+        """
+        return (len(self.buffer) >= self.capacity)
+
+    def emit(self, record):
+        """
+        Emit a record.
+
+        Append the record. If shouldFlush() tells us to, call flush() to process
+        the buffer.
+        """
+        self.buffer.append(record)
+        if self.shouldFlush(record):
+            self.flush()
+
+    def flush(self):
+        """
+        Override to implement custom flushing behaviour.
+
+        This version just zaps the buffer to empty.
+        """
+        self.buffer = []
+
+    def close(self):
+        """
+        Close the handler.
+
+        This version just flushes and chains to the parent class' close().
+        """
+        self.flush()
+        logging.Handler.close(self)
+
+class MemoryHandler(BufferingHandler):
+    """
+    A handler class which buffers logging records in memory, periodically
+    flushing them to a target handler. Flushing occurs whenever the buffer
+    is full, or when an event of a certain severity or greater is seen.
+    """
+    def __init__(self, capacity, flushLevel=logging.ERROR, target=None):
+        """
+        Initialize the handler with the buffer size, the level at which
+        flushing should occur and an optional target.
+
+        Note that without a target being set either here or via setTarget(),
+        a MemoryHandler is no use to anyone!
+        """
+        BufferingHandler.__init__(self, capacity)
+        self.flushLevel = flushLevel
+        self.target = target
+
+    def shouldFlush(self, record):
+        """
+        Check for buffer full or a record at the flushLevel or higher.
+        """
+        return (len(self.buffer) >= self.capacity) or \
+                (record.levelno >= self.flushLevel)
+
+    def setTarget(self, target):
+        """
+        Set the target handler for this handler.
+        """
+        self.target = target
+
+    def flush(self):
+        """
+        For a MemoryHandler, flushing means just sending the buffered
+        records to the target, if there is one. Override if you want
+        different behaviour.
+        """
+        if self.target:
+            for record in self.buffer:
+                self.target.handle(record)
+            self.buffer = []
+
+    def close(self):
+        """
+        Flush, set the target to None and lose the buffer.
+        """
+        self.flush()
+        self.target = None
+        BufferingHandler.close(self)

Added: vendor/Python/current/Lib/macpath.py
===================================================================
--- vendor/Python/current/Lib/macpath.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/macpath.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,275 @@
+"""Pathname and path-related operations for the Macintosh."""
+
+import os
+from stat import *
+
+__all__ = ["normcase","isabs","join","splitdrive","split","splitext",
+           "basename","dirname","commonprefix","getsize","getmtime",
+           "getatime","getctime", "islink","exists","lexists","isdir","isfile",
+           "walk","expanduser","expandvars","normpath","abspath",
+           "curdir","pardir","sep","pathsep","defpath","altsep","extsep",
+           "devnull","realpath","supports_unicode_filenames"]
+
+# strings representing various path-related bits and pieces
+curdir = ':'
+pardir = '::'
+extsep = '.'
+sep = ':'
+pathsep = '\n'
+defpath = ':'
+altsep = None
+devnull = 'Dev:Null'
+
+# Normalize the case of a pathname.  Dummy in Posix, but <s>.lower() here.
+
+def normcase(path):
+    return path.lower()
+
+
+def isabs(s):
+    """Return true if a path is absolute.
+    On the Mac, relative paths begin with a colon,
+    but as a special case, paths with no colons at all are also relative.
+    Anything else is absolute (the string up to the first colon is the
+    volume name)."""
+
+    return ':' in s and s[0] != ':'
+
+
+def join(s, *p):
+    path = s
+    for t in p:
+        if (not s) or isabs(t):
+            path = t
+            continue
+        if t[:1] == ':':
+            t = t[1:]
+        if ':' not in path:
+            path = ':' + path
+        if path[-1:] != ':':
+            path = path + ':'
+        path = path + t
+    return path
+
+
+def split(s):
+    """Split a pathname into two parts: the directory leading up to the final
+    bit, and the basename (the filename, without colons, in that directory).
+    The result (s, t) is such that join(s, t) yields the original argument."""
+
+    if ':' not in s: return '', s
+    colon = 0
+    for i in range(len(s)):
+        if s[i] == ':': colon = i + 1
+    path, file = s[:colon-1], s[colon:]
+    if path and not ':' in path:
+        path = path + ':'
+    return path, file
+
+
+def splitext(p):
+    """Split a path into root and extension.
+    The extension is everything starting at the last dot in the last
+    pathname component; the root is everything before that.
+    It is always true that root + ext == p."""
+
+    i = p.rfind('.')
+    if i<=p.rfind(':'):
+        return p, ''
+    else:
+        return p[:i], p[i:]
+
+
+def splitdrive(p):
+    """Split a pathname into a drive specification and the rest of the
+    path.  Useful on DOS/Windows/NT; on the Mac, the drive is always
+    empty (don't use the volume name -- it doesn't have the same
+    syntactic and semantic oddities as DOS drive letters, such as there
+    being a separate current directory per drive)."""
+
+    return '', p
+
+
+# Short interfaces to split()
+
+def dirname(s): return split(s)[0]
+def basename(s): return split(s)[1]
+
+def ismount(s):
+    if not isabs(s):
+        return False
+    components = split(s)
+    return len(components) == 2 and components[1] == ''
+
+def isdir(s):
+    """Return true if the pathname refers to an existing directory."""
+
+    try:
+        st = os.stat(s)
+    except os.error:
+        return 0
+    return S_ISDIR(st.st_mode)
+
+
+# Get size, mtime, atime of files.
+
+def getsize(filename):
+    """Return the size of a file, reported by os.stat()."""
+    return os.stat(filename).st_size
+
+def getmtime(filename):
+    """Return the last modification time of a file, reported by os.stat()."""
+    return os.stat(filename).st_mtime
+
+def getatime(filename):
+    """Return the last access time of a file, reported by os.stat()."""
+    return os.stat(filename).st_atime
+
+
+def islink(s):
+    """Return true if the pathname refers to a symbolic link."""
+
+    try:
+        import Carbon.File
+        return Carbon.File.ResolveAliasFile(s, 0)[2]
+    except:
+        return False
+
+
+def isfile(s):
+    """Return true if the pathname refers to an existing regular file."""
+
+    try:
+        st = os.stat(s)
+    except os.error:
+        return False
+    return S_ISREG(st.st_mode)
+
+def getctime(filename):
+    """Return the creation time of a file, reported by os.stat()."""
+    return os.stat(filename).st_ctime
+
+def exists(s):
+    """Test whether a path exists.  Returns False for broken symbolic links"""
+
+    try:
+        st = os.stat(s)
+    except os.error:
+        return False
+    return True
+
+# Is `stat`/`lstat` a meaningful difference on the Mac?  This is safe in any
+# case.
+
+def lexists(path):
+    """Test whether a path exists.  Returns True for broken symbolic links"""
+
+    try:
+        st = os.lstat(path)
+    except os.error:
+        return False
+    return True
+
+# Return the longest prefix of all list elements.
+
+def commonprefix(m):
+    "Given a list of pathnames, returns the longest common leading component"
+    if not m: return ''
+    s1 = min(m)
+    s2 = max(m)
+    n = min(len(s1), len(s2))
+    for i in xrange(n):
+        if s1[i] != s2[i]:
+            return s1[:i]
+    return s1[:n]
+
+
+def expandvars(path):
+    """Dummy to retain interface-compatibility with other operating systems."""
+    return path
+
+
+def expanduser(path):
+    """Dummy to retain interface-compatibility with other operating systems."""
+    return path
+
+class norm_error(Exception):
+    """Path cannot be normalized"""
+
+def normpath(s):
+    """Normalize a pathname.  Will return the same result for
+    equivalent paths."""
+
+    if ":" not in s:
+        return ":"+s
+
+    comps = s.split(":")
+    i = 1
+    while i < len(comps)-1:
+        if comps[i] == "" and comps[i-1] != "":
+            if i > 1:
+                del comps[i-1:i+1]
+                i = i - 1
+            else:
+                # best way to handle this is to raise an exception
+                raise norm_error, 'Cannot use :: immediately after volume name'
+        else:
+            i = i + 1
+
+    s = ":".join(comps)
+
+    # remove trailing ":" except for ":" and "Volume:"
+    if s[-1] == ":" and len(comps) > 2 and s != ":"*len(s):
+        s = s[:-1]
+    return s
+
+
+def walk(top, func, arg):
+    """Directory tree walk with callback function.
+
+    For each directory in the directory tree rooted at top (including top
+    itself, but excluding '.' and '..'), call func(arg, dirname, fnames).
+    dirname is the name of the directory, and fnames a list of the names of
+    the files and subdirectories in dirname (excluding '.' and '..').  func
+    may modify the fnames list in-place (e.g. via del or slice assignment),
+    and walk will only recurse into the subdirectories whose names remain in
+    fnames; this can be used to implement a filter, or to impose a specific
+    order of visiting.  No semantics are defined for, or required of, arg,
+    beyond that arg is always passed to func.  It can be used, e.g., to pass
+    a filename pattern, or a mutable object designed to accumulate
+    statistics.  Passing None for arg is common."""
+
+    try:
+        names = os.listdir(top)
+    except os.error:
+        return
+    func(arg, top, names)
+    for name in names:
+        name = join(top, name)
+        if isdir(name) and not islink(name):
+            walk(name, func, arg)
+
+
+def abspath(path):
+    """Return an absolute path."""
+    if not isabs(path):
+        path = join(os.getcwd(), path)
+    return normpath(path)
+
+# realpath is a no-op on systems without islink support
+def realpath(path):
+    path = abspath(path)
+    try:
+        import Carbon.File
+    except ImportError:
+        return path
+    if not path:
+        return path
+    components = path.split(':')
+    path = components[0] + ':'
+    for c in components[1:]:
+        path = join(path, c)
+        path = Carbon.File.FSResolveAliasFile(path, 1)[0].as_pathname()
+    return path
+
+supports_unicode_filenames = False

Added: vendor/Python/current/Lib/macurl2path.py
===================================================================
--- vendor/Python/current/Lib/macurl2path.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/macurl2path.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,97 @@
+"""Macintosh-specific module for conversion between pathnames and URLs.
+
+Do not import directly; use urllib instead."""
+
+import urllib
+import os
+
+__all__ = ["url2pathname","pathname2url"]
+
+def url2pathname(pathname):
+    """OS-specific conversion from a relative URL of the 'file' scheme
+    to a file system path; not recommended for general use."""
+    #
+    # XXXX The .. handling should be fixed...
+    #
+    tp = urllib.splittype(pathname)[0]
+    if tp and tp != 'file':
+        raise RuntimeError, 'Cannot convert non-local URL to pathname'
+    # Turn starting /// into /, an empty hostname means current host
+    if pathname[:3] == '///':
+        pathname = pathname[2:]
+    elif pathname[:2] == '//':
+        raise RuntimeError, 'Cannot convert non-local URL to pathname'
+    components = pathname.split('/')
+    # Remove . and embedded ..
+    i = 0
+    while i < len(components):
+        if components[i] == '.':
+            del components[i]
+        elif components[i] == '..' and i > 0 and \
+                                  components[i-1] not in ('', '..'):
+            del components[i-1:i+1]
+            i = i-1
+        elif components[i] == '' and i > 0 and components[i-1] != '':
+            del components[i]
+        else:
+            i = i+1
+    if not components[0]:
+        # Absolute unix path, don't start with colon
+        rv = ':'.join(components[1:])
+    else:
+        # relative unix path, start with colon. First replace
+        # leading .. by empty strings (giving ::file)
+        i = 0
+        while i < len(components) and components[i] == '..':
+            components[i] = ''
+            i = i + 1
+        rv = ':' + ':'.join(components)
+    # and finally unquote slashes and other funny characters
+    return urllib.unquote(rv)
+
+def pathname2url(pathname):
+    """OS-specific conversion from a file system path to a relative URL
+    of the 'file' scheme; not recommended for general use."""
+    if '/' in pathname:
+        raise RuntimeError, "Cannot convert pathname containing slashes"
+    components = pathname.split(':')
+    # Remove empty first and/or last component
+    if components[0] == '':
+        del components[0]
+    if components[-1] == '':
+        del components[-1]
+    # Replace empty string ('::') by .. (will result in '/../' later)
+    for i in range(len(components)):
+        if components[i] == '':
+            components[i] = '..'
+    # Truncate names longer than 31 bytes
+    components = map(_pncomp2url, components)
+
+    if os.path.isabs(pathname):
+        return '/' + '/'.join(components)
+    else:
+        return '/'.join(components)
+
+def _pncomp2url(component):
+    component = urllib.quote(component[:31], safe='')  # We want to quote slashes
+    return component
+
+def test():
+    for url in ["index.html",
+                "bar/index.html",
+                "/foo/bar/index.html",
+                "/foo/bar/",
+                "/"]:
+        print '%r -> %r' % (url, url2pathname(url))
+    for path in ["drive:",
+                 "drive:dir:",
+                 "drive:dir:file",
+                 "drive:file",
+                 "file",
+                 ":file",
+                 ":dir:",
+                 ":dir:file"]:
+        print '%r -> %r' % (path, pathname2url(path))
+
+if __name__ == '__main__':
+    test()

Added: vendor/Python/current/Lib/mailbox.py
===================================================================
--- vendor/Python/current/Lib/mailbox.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/mailbox.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2090 @@
+#! /usr/bin/env python
+
+"""Read/write support for Maildir, mbox, MH, Babyl, and MMDF mailboxes."""
+
+# Notes for authors of new mailbox subclasses:
+#
+# Remember to fsync() changes to disk before closing a modified file
+# or returning from a flush() method.  See functions _sync_flush() and
+# _sync_close().
+
+import sys
+import os
+import time
+import calendar
+import socket
+import errno
+import copy
+import email
+import email.Message
+import email.Generator
+import rfc822
+import StringIO
+try:
+    if sys.platform == 'os2emx':
+        # OS/2 EMX fcntl() not adequate
+        raise ImportError
+    import fcntl
+except ImportError:
+    fcntl = None
+
+__all__ = [ 'Mailbox', 'Maildir', 'mbox', 'MH', 'Babyl', 'MMDF',
+            'Message', 'MaildirMessage', 'mboxMessage', 'MHMessage',
+            'BabylMessage', 'MMDFMessage', 'UnixMailbox',
+            'PortableUnixMailbox', 'MmdfMailbox', 'MHMailbox', 'BabylMailbox' ]
+
+class Mailbox:
+    """A group of messages in a particular place."""
+
+    def __init__(self, path, factory=None, create=True):
+        """Initialize a Mailbox instance."""
+        self._path = os.path.abspath(os.path.expanduser(path))
+        self._factory = factory
+
+    def add(self, message):
+        """Add message and return assigned key."""
+        raise NotImplementedError('Method must be implemented by subclass')
+
+    def remove(self, key):
+        """Remove the keyed message; raise KeyError if it doesn't exist."""
+        raise NotImplementedError('Method must be implemented by subclass')
+
+    def __delitem__(self, key):
+        self.remove(key)
+
+    def discard(self, key):
+        """If the keyed message exists, remove it."""
+        try:
+            self.remove(key)
+        except KeyError:
+            pass
+
+    def __setitem__(self, key, message):
+        """Replace the keyed message; raise KeyError if it doesn't exist."""
+        raise NotImplementedError('Method must be implemented by subclass')
+
+    def get(self, key, default=None):
+        """Return the keyed message, or default if it doesn't exist."""
+        try:
+            return self.__getitem__(key)
+        except KeyError:
+            return default
+
+    def __getitem__(self, key):
+        """Return the keyed message; raise KeyError if it doesn't exist."""
+        if not self._factory:
+            return self.get_message(key)
+        else:
+            return self._factory(self.get_file(key))
+
+    def get_message(self, key):
+        """Return a Message representation or raise a KeyError."""
+        raise NotImplementedError('Method must be implemented by subclass')
+
+    def get_string(self, key):
+        """Return a string representation or raise a KeyError."""
+        raise NotImplementedError('Method must be implemented by subclass')
+
+    def get_file(self, key):
+        """Return a file-like representation or raise a KeyError."""
+        raise NotImplementedError('Method must be implemented by subclass')
+
+    def iterkeys(self):
+        """Return an iterator over keys."""
+        raise NotImplementedError('Method must be implemented by subclass')
+
+    def keys(self):
+        """Return a list of keys."""
+        return list(self.iterkeys())
+
+    def itervalues(self):
+        """Return an iterator over all messages."""
+        for key in self.iterkeys():
+            try:
+                value = self[key]
+            except KeyError:
+                continue
+            yield value
+
+    def __iter__(self):
+        return self.itervalues()
+
+    def values(self):
+        """Return a list of messages. Memory intensive."""
+        return list(self.itervalues())
+
+    def iteritems(self):
+        """Return an iterator over (key, message) tuples."""
+        for key in self.iterkeys():
+            try:
+                value = self[key]
+            except KeyError:
+                continue
+            yield (key, value)
+
+    def items(self):
+        """Return a list of (key, message) tuples. Memory intensive."""
+        return list(self.iteritems())
+
+    def has_key(self, key):
+        """Return True if the keyed message exists, False otherwise."""
+        raise NotImplementedError('Method must be implemented by subclass')
+
+    def __contains__(self, key):
+        return self.has_key(key)
+
+    def __len__(self):
+        """Return a count of messages in the mailbox."""
+        raise NotImplementedError('Method must be implemented by subclass')
+
+    def clear(self):
+        """Delete all messages."""
+        for key in self.iterkeys():
+            self.discard(key)
+
+    def pop(self, key, default=None):
+        """Delete the keyed message and return it, or default."""
+        try:
+            result = self[key]
+        except KeyError:
+            return default
+        self.discard(key)
+        return result
+
+    def popitem(self):
+        """Delete an arbitrary (key, message) pair and return it."""
+        for key in self.iterkeys():
+            return (key, self.pop(key))     # This is only run once.
+        else:
+            raise KeyError('No messages in mailbox')
+
+    def update(self, arg=None):
+        """Change the messages that correspond to certain keys."""
+        if hasattr(arg, 'iteritems'):
+            source = arg.iteritems()
+        elif hasattr(arg, 'items'):
+            source = arg.items()
+        else:
+            source = arg
+        bad_key = False
+        for key, message in source:
+            try:
+                self[key] = message
+            except KeyError:
+                bad_key = True
+        if bad_key:
+            raise KeyError('No message with key(s)')
+
+    def flush(self):
+        """Write any pending changes to the disk."""
+        raise NotImplementedError('Method must be implemented by subclass')
+
+    def lock(self):
+        """Lock the mailbox."""
+        raise NotImplementedError('Method must be implemented by subclass')
+
+    def unlock(self):
+        """Unlock the mailbox if it is locked."""
+        raise NotImplementedError('Method must be implemented by subclass')
+
+    def close(self):
+        """Flush and close the mailbox."""
+        raise NotImplementedError('Method must be implemented by subclass')
+
+    def _dump_message(self, message, target, mangle_from_=False):
+        # Most files are opened in binary mode to allow predictable seeking.
+        # To get native line endings on disk, the user-friendly \n line endings
+        # used in strings and by email.Message are translated here.
+        """Dump message contents to target file."""
+        if isinstance(message, email.Message.Message):
+            buffer = StringIO.StringIO()
+            gen = email.Generator.Generator(buffer, mangle_from_, 0)
+            gen.flatten(message)
+            buffer.seek(0)
+            target.write(buffer.read().replace('\n', os.linesep))
+        elif isinstance(message, str):
+            if mangle_from_:
+                message = message.replace('\nFrom ', '\n>From ')
+            message = message.replace('\n', os.linesep)
+            target.write(message)
+        elif hasattr(message, 'read'):
+            while True:
+                line = message.readline()
+                if line == '':
+                    break
+                if mangle_from_ and line.startswith('From '):
+                    line = '>From ' + line[5:]
+                line = line.replace('\n', os.linesep)
+                target.write(line)
+        else:
+            raise TypeError('Invalid message type: %s' % type(message))
+
+
+class Maildir(Mailbox):
+    """A qmail-style Maildir mailbox."""
+
+    colon = ':'
+
+    def __init__(self, dirname, factory=rfc822.Message, create=True):
+        """Initialize a Maildir instance."""
+        Mailbox.__init__(self, dirname, factory, create)
+        if not os.path.exists(self._path):
+            if create:
+                os.mkdir(self._path, 0700)
+                os.mkdir(os.path.join(self._path, 'tmp'), 0700)
+                os.mkdir(os.path.join(self._path, 'new'), 0700)
+                os.mkdir(os.path.join(self._path, 'cur'), 0700)
+            else:
+                raise NoSuchMailboxError(self._path)
+        self._toc = {}
+
+    def add(self, message):
+        """Add message and return assigned key."""
+        tmp_file = self._create_tmp()
+        try:
+            self._dump_message(message, tmp_file)
+        finally:
+            _sync_close(tmp_file)
+        if isinstance(message, MaildirMessage):
+            subdir = message.get_subdir()
+            suffix = self.colon + message.get_info()
+            if suffix == self.colon:
+                suffix = ''
+        else:
+            subdir = 'new'
+            suffix = ''
+        uniq = os.path.basename(tmp_file.name).split(self.colon)[0]
+        dest = os.path.join(self._path, subdir, uniq + suffix)
+        try:
+            if hasattr(os, 'link'):
+                os.link(tmp_file.name, dest)
+                os.remove(tmp_file.name)
+            else:
+                os.rename(tmp_file.name, dest)
+        except OSError, e:
+            os.remove(tmp_file.name)
+            if e.errno == errno.EEXIST:
+                raise ExternalClashError('Name clash with existing message: %s'
+                                         % dest)
+            else:
+                raise
+        if isinstance(message, MaildirMessage):
+            os.utime(dest, (os.path.getatime(dest), message.get_date()))
+        return uniq
+
+    def remove(self, key):
+        """Remove the keyed message; raise KeyError if it doesn't exist."""
+        os.remove(os.path.join(self._path, self._lookup(key)))
+
+    def discard(self, key):
+        """If the keyed message exists, remove it."""
+        # This overrides an inapplicable implementation in the superclass.
+        try:
+            self.remove(key)
+        except KeyError:
+            pass
+        except OSError, e:
+            if e.errno != errno.ENOENT:
+                raise
+
+    def __setitem__(self, key, message):
+        """Replace the keyed message; raise KeyError if it doesn't exist."""
+        old_subpath = self._lookup(key)
+        temp_key = self.add(message)
+        temp_subpath = self._lookup(temp_key)
+        if isinstance(message, MaildirMessage):
+            # temp's subdir and suffix were specified by message.
+            dominant_subpath = temp_subpath
+        else:
+            # temp's subdir and suffix were defaults from add().
+            dominant_subpath = old_subpath
+        subdir = os.path.dirname(dominant_subpath)
+        if self.colon in dominant_subpath:
+            suffix = self.colon + dominant_subpath.split(self.colon)[-1]
+        else:
+            suffix = ''
+        self.discard(key)
+        new_path = os.path.join(self._path, subdir, key + suffix)
+        os.rename(os.path.join(self._path, temp_subpath), new_path)
+        if isinstance(message, MaildirMessage):
+            os.utime(new_path, (os.path.getatime(new_path),
+                                message.get_date()))
+
+    def get_message(self, key):
+        """Return a Message representation or raise a KeyError."""
+        subpath = self._lookup(key)
+        f = open(os.path.join(self._path, subpath), 'r')
+        try:
+            msg = MaildirMessage(f)
+        finally:
+            f.close()
+        subdir, name = os.path.split(subpath)
+        msg.set_subdir(subdir)
+        if self.colon in name:
+            msg.set_info(name.split(self.colon)[-1])
+        msg.set_date(os.path.getmtime(os.path.join(self._path, subpath)))
+        return msg
+
+    def get_string(self, key):
+        """Return a string representation or raise a KeyError."""
+        f = open(os.path.join(self._path, self._lookup(key)), 'r')
+        try:
+            return f.read()
+        finally:
+            f.close()
+
+    def get_file(self, key):
+        """Return a file-like representation or raise a KeyError."""
+        f = open(os.path.join(self._path, self._lookup(key)), 'rb')
+        return _ProxyFile(f)
+
+    def iterkeys(self):
+        """Return an iterator over keys."""
+        self._refresh()
+        for key in self._toc:
+            try:
+                self._lookup(key)
+            except KeyError:
+                continue
+            yield key
+
+    def has_key(self, key):
+        """Return True if the keyed message exists, False otherwise."""
+        self._refresh()
+        return key in self._toc
+
+    def __len__(self):
+        """Return a count of messages in the mailbox."""
+        self._refresh()
+        return len(self._toc)
+
+    def flush(self):
+        """Write any pending changes to disk."""
+        return  # Maildir changes are always written immediately.
+
+    def lock(self):
+        """Lock the mailbox."""
+        return
+
+    def unlock(self):
+        """Unlock the mailbox if it is locked."""
+        return
+
+    def close(self):
+        """Flush and close the mailbox."""
+        return
+
+    def list_folders(self):
+        """Return a list of folder names."""
+        result = []
+        for entry in os.listdir(self._path):
+            if len(entry) > 1 and entry[0] == '.' and \
+               os.path.isdir(os.path.join(self._path, entry)):
+                result.append(entry[1:])
+        return result
+
+    def get_folder(self, folder):
+        """Return a Maildir instance for the named folder."""
+        return Maildir(os.path.join(self._path, '.' + folder),
+                       factory=self._factory,
+                       create=False)
+
+    def add_folder(self, folder):
+        """Create a folder and return a Maildir instance representing it."""
+        path = os.path.join(self._path, '.' + folder)
+        result = Maildir(path, factory=self._factory)
+        maildirfolder_path = os.path.join(path, 'maildirfolder')
+        if not os.path.exists(maildirfolder_path):
+            os.close(os.open(maildirfolder_path, os.O_CREAT | os.O_WRONLY))
+        return result
+
+    def remove_folder(self, folder):
+        """Delete the named folder, which must be empty."""
+        path = os.path.join(self._path, '.' + folder)
+        for entry in os.listdir(os.path.join(path, 'new')) + \
+                     os.listdir(os.path.join(path, 'cur')):
+            if len(entry) < 1 or entry[0] != '.':
+                raise NotEmptyError('Folder contains message(s): %s' % folder)
+        for entry in os.listdir(path):
+            if entry != 'new' and entry != 'cur' and entry != 'tmp' and \
+               os.path.isdir(os.path.join(path, entry)):
+                raise NotEmptyError("Folder contains subdirectory '%s': %s" %
+                                    (folder, entry))
+        for root, dirs, files in os.walk(path, topdown=False):
+            for entry in files:
+                os.remove(os.path.join(root, entry))
+            for entry in dirs:
+                os.rmdir(os.path.join(root, entry))
+        os.rmdir(path)
+
+    def clean(self):
+        """Delete old files in "tmp"."""
+        now = time.time()
+        for entry in os.listdir(os.path.join(self._path, 'tmp')):
+            path = os.path.join(self._path, 'tmp', entry)
+            if now - os.path.getatime(path) > 129600:   # 60 * 60 * 36
+                os.remove(path)
+
+    _count = 1  # This is used to generate unique file names.
+
+    def _create_tmp(self):
+        """Create a file in the tmp subdirectory and open and return it."""
+        now = time.time()
+        hostname = socket.gethostname()
+        if '/' in hostname:
+            hostname = hostname.replace('/', r'\057')
+        if ':' in hostname:
+            hostname = hostname.replace(':', r'\072')
+        uniq = "%s.M%sP%sQ%s.%s" % (int(now), int(now % 1 * 1e6), os.getpid(),
+                                    Maildir._count, hostname)
+        path = os.path.join(self._path, 'tmp', uniq)
+        try:
+            os.stat(path)
+        except OSError, e:
+            if e.errno == errno.ENOENT:
+                Maildir._count += 1
+                try:
+                    return _create_carefully(path)
+                except OSError, e:
+                    if e.errno != errno.EEXIST:
+                        raise
+            else:
+                raise
+
+        # Fall through to here if stat succeeded or open raised EEXIST.
+        raise ExternalClashError('Name clash prevented file creation: %s' %
+                                 path)
+
+    def _refresh(self):
+        """Update table of contents mapping."""
+        self._toc = {}
+        for subdir in ('new', 'cur'):
+            for entry in os.listdir(os.path.join(self._path, subdir)):
+                uniq = entry.split(self.colon)[0]
+                self._toc[uniq] = os.path.join(subdir, entry)
+
+    def _lookup(self, key):
+        """Use TOC to return subpath for given key, or raise a KeyError."""
+        try:
+            if os.path.exists(os.path.join(self._path, self._toc[key])):
+                return self._toc[key]
+        except KeyError:
+            pass
+        self._refresh()
+        try:
+            return self._toc[key]
+        except KeyError:
+            raise KeyError('No message with key: %s' % key)
+
+    # This method is for backward compatibility only.
+    def next(self):
+        """Return the next message in a one-time iteration."""
+        if not hasattr(self, '_onetime_keys'):
+            self._onetime_keys = self.iterkeys()
+        while True:
+            try:
+                return self[self._onetime_keys.next()]
+            except StopIteration:
+                return None
+            except KeyError:
+                continue
+
+
+class _singlefileMailbox(Mailbox):
+    """A single-file mailbox."""
+
+    def __init__(self, path, factory=None, create=True):
+        """Initialize a single-file mailbox."""
+        Mailbox.__init__(self, path, factory, create)
+        try:
+            f = open(self._path, 'rb+')
+        except IOError, e:
+            if e.errno == errno.ENOENT:
+                if create:
+                    f = open(self._path, 'wb+')
+                else:
+                    raise NoSuchMailboxError(self._path)
+            elif e.errno == errno.EACCES:
+                f = open(self._path, 'rb')
+            else:
+                raise
+        self._file = f
+        self._toc = None
+        self._next_key = 0
+        self._pending = False   # No changes require rewriting the file.
+        self._locked = False
+
+    def add(self, message):
+        """Add message and return assigned key."""
+        self._lookup()
+        self._toc[self._next_key] = self._append_message(message)
+        self._next_key += 1
+        self._pending = True
+        return self._next_key - 1
+
+    def remove(self, key):
+        """Remove the keyed message; raise KeyError if it doesn't exist."""
+        self._lookup(key)
+        del self._toc[key]
+        self._pending = True
+
+    def __setitem__(self, key, message):
+        """Replace the keyed message; raise KeyError if it doesn't exist."""
+        self._lookup(key)
+        self._toc[key] = self._append_message(message)
+        self._pending = True
+
+    def iterkeys(self):
+        """Return an iterator over keys."""
+        self._lookup()
+        for key in self._toc.keys():
+            yield key
+
+    def has_key(self, key):
+        """Return True if the keyed message exists, False otherwise."""
+        self._lookup()
+        return key in self._toc
+
+    def __len__(self):
+        """Return a count of messages in the mailbox."""
+        self._lookup()
+        return len(self._toc)
+
+    def lock(self):
+        """Lock the mailbox."""
+        if not self._locked:
+            _lock_file(self._file)
+            self._locked = True
+
+    def unlock(self):
+        """Unlock the mailbox if it is locked."""
+        if self._locked:
+            _unlock_file(self._file)
+            self._locked = False
+
+    def flush(self):
+        """Write any pending changes to disk."""
+        if not self._pending:
+            return
+        self._lookup()
+        new_file = _create_temporary(self._path)
+        try:
+            new_toc = {}
+            self._pre_mailbox_hook(new_file)
+            for key in sorted(self._toc.keys()):
+                start, stop = self._toc[key]
+                self._file.seek(start)
+                self._pre_message_hook(new_file)
+                new_start = new_file.tell()
+                while True:
+                    buffer = self._file.read(min(4096,
+                                                 stop - self._file.tell()))
+                    if buffer == '':
+                        break
+                    new_file.write(buffer)
+                new_toc[key] = (new_start, new_file.tell())
+                self._post_message_hook(new_file)
+        except:
+            new_file.close()
+            os.remove(new_file.name)
+            raise
+        _sync_close(new_file)
+        # self._file is about to get replaced, so no need to sync.
+        self._file.close()
+        try:
+            os.rename(new_file.name, self._path)
+        except OSError, e:
+            if e.errno == errno.EEXIST or \
+              (os.name == 'os2' and e.errno == errno.EACCES):
+                os.remove(self._path)
+                os.rename(new_file.name, self._path)
+            else:
+                raise
+        self._file = open(self._path, 'rb+')
+        self._toc = new_toc
+        self._pending = False
+        if self._locked:
+            _lock_file(self._file, dotlock=False)
+
+    def _pre_mailbox_hook(self, f):
+        """Called before writing the mailbox to file f."""
+        return
+
+    def _pre_message_hook(self, f):
+        """Called before writing each message to file f."""
+        return
+
+    def _post_message_hook(self, f):
+        """Called after writing each message to file f."""
+        return
+
+    def close(self):
+        """Flush and close the mailbox."""
+        self.flush()
+        if self._locked:
+            self.unlock()
+        self._file.close()  # Sync has been done by self.flush() above.
+
+    def _lookup(self, key=None):
+        """Return (start, stop) or raise KeyError."""
+        if self._toc is None:
+            self._generate_toc()
+        if key is not None:
+            try:
+                return self._toc[key]
+            except KeyError:
+                raise KeyError('No message with key: %s' % key)
+
+    def _append_message(self, message):
+        """Append message to mailbox and return (start, stop) offsets."""
+        self._file.seek(0, 2)
+        self._pre_message_hook(self._file)
+        offsets = self._install_message(message)
+        self._post_message_hook(self._file)
+        self._file.flush()
+        return offsets
+
+
+
+class _mboxMMDF(_singlefileMailbox):
+    """An mbox or MMDF mailbox."""
+
+    _mangle_from_ = True
+
+    def get_message(self, key):
+        """Return a Message representation or raise a KeyError."""
+        start, stop = self._lookup(key)
+        self._file.seek(start)
+        from_line = self._file.readline().replace(os.linesep, '')
+        string = self._file.read(stop - self._file.tell())
+        msg = self._message_factory(string.replace(os.linesep, '\n'))
+        msg.set_from(from_line[5:])
+        return msg
+
+    def get_string(self, key, from_=False):
+        """Return a string representation or raise a KeyError."""
+        start, stop = self._lookup(key)
+        self._file.seek(start)
+        if not from_:
+            self._file.readline()
+        string = self._file.read(stop - self._file.tell())
+        return string.replace(os.linesep, '\n')
+
+    def get_file(self, key, from_=False):
+        """Return a file-like representation or raise a KeyError."""
+        start, stop = self._lookup(key)
+        self._file.seek(start)
+        if not from_:
+            self._file.readline()
+        return _PartialFile(self._file, self._file.tell(), stop)
+
+    def _install_message(self, message):
+        """Format a message and blindly write to self._file."""
+        from_line = None
+        if isinstance(message, str) and message.startswith('From '):
+            newline = message.find('\n')
+            if newline != -1:
+                from_line = message[:newline]
+                message = message[newline + 1:]
+            else:
+                from_line = message
+                message = ''
+        elif isinstance(message, _mboxMMDFMessage):
+            from_line = 'From ' + message.get_from()
+        elif isinstance(message, email.Message.Message):
+            from_line = message.get_unixfrom()  # May be None.
+        if from_line is None:
+            from_line = 'From MAILER-DAEMON %s' % time.asctime(time.gmtime())
+        start = self._file.tell()
+        self._file.write(from_line + os.linesep)
+        self._dump_message(message, self._file, self._mangle_from_)
+        stop = self._file.tell()
+        return (start, stop)
+
+
+class mbox(_mboxMMDF):
+    """A classic mbox mailbox."""
+
+    _mangle_from_ = True
+
+    def __init__(self, path, factory=None, create=True):
+        """Initialize an mbox mailbox."""
+        self._message_factory = mboxMessage
+        _mboxMMDF.__init__(self, path, factory, create)
+
+    def _pre_message_hook(self, f):
+        """Called before writing each message to file f."""
+        if f.tell() != 0:
+            f.write(os.linesep)
+
+    def _generate_toc(self):
+        """Generate key-to-(start, stop) table of contents."""
+        starts, stops = [], []
+        self._file.seek(0)
+        while True:
+            line_pos = self._file.tell()
+            line = self._file.readline()
+            if line.startswith('From '):
+                if len(stops) < len(starts):
+                    stops.append(line_pos - len(os.linesep))
+                starts.append(line_pos)
+            elif line == '':
+                stops.append(line_pos)
+                break
+        self._toc = dict(enumerate(zip(starts, stops)))
+        self._next_key = len(self._toc)
+
+
+class MMDF(_mboxMMDF):
+    """An MMDF mailbox."""
+
+    def __init__(self, path, factory=None, create=True):
+        """Initialize an MMDF mailbox."""
+        self._message_factory = MMDFMessage
+        _mboxMMDF.__init__(self, path, factory, create)
+
+    def _pre_message_hook(self, f):
+        """Called before writing each message to file f."""
+        f.write('\001\001\001\001' + os.linesep)
+
+    def _post_message_hook(self, f):
+        """Called after writing each message to file f."""
+        f.write(os.linesep + '\001\001\001\001' + os.linesep)
+
+    def _generate_toc(self):
+        """Generate key-to-(start, stop) table of contents."""
+        starts, stops = [], []
+        self._file.seek(0)
+        next_pos = 0
+        while True:
+            line_pos = next_pos
+            line = self._file.readline()
+            next_pos = self._file.tell()
+            if line.startswith('\001\001\001\001' + os.linesep):
+                starts.append(next_pos)
+                while True:
+                    line_pos = next_pos
+                    line = self._file.readline()
+                    next_pos = self._file.tell()
+                    if line == '\001\001\001\001' + os.linesep:
+                        stops.append(line_pos - len(os.linesep))
+                        break
+                    elif line == '':
+                        stops.append(line_pos)
+                        break
+            elif line == '':
+                break
+        self._toc = dict(enumerate(zip(starts, stops)))
+        self._next_key = len(self._toc)
+
+
+class MH(Mailbox):
+    """An MH mailbox."""
+
+    def __init__(self, path, factory=None, create=True):
+        """Initialize an MH instance."""
+        Mailbox.__init__(self, path, factory, create)
+        if not os.path.exists(self._path):
+            if create:
+                os.mkdir(self._path, 0700)
+                os.close(os.open(os.path.join(self._path, '.mh_sequences'),
+                                 os.O_CREAT | os.O_EXCL | os.O_WRONLY, 0600))
+            else:
+                raise NoSuchMailboxError(self._path)
+        self._locked = False
+
+    def add(self, message):
+        """Add message and return assigned key."""
+        keys = self.keys()
+        if len(keys) == 0:
+            new_key = 1
+        else:
+            new_key = max(keys) + 1
+        new_path = os.path.join(self._path, str(new_key))
+        f = _create_carefully(new_path)
+        try:
+            if self._locked:
+                _lock_file(f)
+            try:
+                self._dump_message(message, f)
+                if isinstance(message, MHMessage):
+                    self._dump_sequences(message, new_key)
+            finally:
+                if self._locked:
+                    _unlock_file(f)
+        finally:
+            _sync_close(f)
+        return new_key
+
+    def remove(self, key):
+        """Remove the keyed message; raise KeyError if it doesn't exist."""
+        path = os.path.join(self._path, str(key))
+        try:
+            f = open(path, 'rb+')
+        except IOError, e:
+            if e.errno == errno.ENOENT:
+                raise KeyError('No message with key: %s' % key)
+            else:
+                raise
+        try:
+            if self._locked:
+                _lock_file(f)
+            try:
+                f.close()
+                os.remove(os.path.join(self._path, str(key)))
+            finally:
+                if self._locked:
+                    _unlock_file(f)
+        finally:
+            f.close()
+
+    def __setitem__(self, key, message):
+        """Replace the keyed message; raise KeyError if it doesn't exist."""
+        path = os.path.join(self._path, str(key))
+        try:
+            f = open(path, 'rb+')
+        except IOError, e:
+            if e.errno == errno.ENOENT:
+                raise KeyError('No message with key: %s' % key)
+            else:
+                raise
+        try:
+            if self._locked:
+                _lock_file(f)
+            try:
+                os.close(os.open(path, os.O_WRONLY | os.O_TRUNC))
+                self._dump_message(message, f)
+                if isinstance(message, MHMessage):
+                    self._dump_sequences(message, key)
+            finally:
+                if self._locked:
+                    _unlock_file(f)
+        finally:
+            _sync_close(f)
+
+    def get_message(self, key):
+        """Return a Message representation or raise a KeyError."""
+        try:
+            if self._locked:
+                f = open(os.path.join(self._path, str(key)), 'r+')
+            else:
+                f = open(os.path.join(self._path, str(key)), 'r')
+        except IOError, e:
+            if e.errno == errno.ENOENT:
+                raise KeyError('No message with key: %s' % key)
+            else:
+                raise
+        try:
+            if self._locked:
+                _lock_file(f)
+            try:
+                msg = MHMessage(f)
+            finally:
+                if self._locked:
+                    _unlock_file(f)
+        finally:
+            f.close()
+        for name, key_list in self.get_sequences():
+            if key in key_list:
+                msg.add_sequence(name)
+        return msg
+
+    def get_string(self, key):
+        """Return a string representation or raise a KeyError."""
+        try:
+            if self._locked:
+                f = open(os.path.join(self._path, str(key)), 'r+')
+            else:
+                f = open(os.path.join(self._path, str(key)), 'r')
+        except IOError, e:
+            if e.errno == errno.ENOENT:
+                raise KeyError('No message with key: %s' % key)
+            else:
+                raise
+        try:
+            if self._locked:
+                _lock_file(f)
+            try:
+                return f.read()
+            finally:
+                if self._locked:
+                    _unlock_file(f)
+        finally:
+            f.close()
+
+    def get_file(self, key):
+        """Return a file-like representation or raise a KeyError."""
+        try:
+            f = open(os.path.join(self._path, str(key)), 'rb')
+        except IOError, e:
+            if e.errno == errno.ENOENT:
+                raise KeyError('No message with key: %s' % key)
+            else:
+                raise
+        return _ProxyFile(f)
+
+    def iterkeys(self):
+        """Return an iterator over keys."""
+        return iter(sorted(int(entry) for entry in os.listdir(self._path)
+                                      if entry.isdigit()))
+
+    def has_key(self, key):
+        """Return True if the keyed message exists, False otherwise."""
+        return os.path.exists(os.path.join(self._path, str(key)))
+
+    def __len__(self):
+        """Return a count of messages in the mailbox."""
+        return len(list(self.iterkeys()))
+
+    def lock(self):
+        """Lock the mailbox."""
+        if not self._locked:
+            self._file = open(os.path.join(self._path, '.mh_sequences'), 'rb+')
+            _lock_file(self._file)
+            self._locked = True
+
+    def unlock(self):
+        """Unlock the mailbox if it is locked."""
+        if self._locked:
+            _unlock_file(self._file)
+            _sync_close(self._file)
+            del self._file
+            self._locked = False
+
+    def flush(self):
+        """Write any pending changes to the disk."""
+        return
+
+    def close(self):
+        """Flush and close the mailbox."""
+        if self._locked:
+            self.unlock()
+
+    def list_folders(self):
+        """Return a list of folder names."""
+        result = []
+        for entry in os.listdir(self._path):
+            if os.path.isdir(os.path.join(self._path, entry)):
+                result.append(entry)
+        return result
+
+    def get_folder(self, folder):
+        """Return an MH instance for the named folder."""
+        return MH(os.path.join(self._path, folder),
+                  factory=self._factory, create=False)
+
+    def add_folder(self, folder):
+        """Create a folder and return an MH instance representing it."""
+        return MH(os.path.join(self._path, folder),
+                  factory=self._factory)
+
+    def remove_folder(self, folder):
+        """Delete the named folder, which must be empty."""
+        path = os.path.join(self._path, folder)
+        entries = os.listdir(path)
+        if entries == ['.mh_sequences']:
+            os.remove(os.path.join(path, '.mh_sequences'))
+        elif entries == []:
+            pass
+        else:
+            raise NotEmptyError('Folder not empty: %s' % self._path)
+        os.rmdir(path)
+
+    def get_sequences(self):
+        """Return a name-to-key-list dictionary to define each sequence."""
+        results = {}
+        f = open(os.path.join(self._path, '.mh_sequences'), 'r')
+        try:
+            all_keys = set(self.keys())
+            for line in f:
+                try:
+                    name, contents = line.split(':')
+                    keys = set()
+                    for spec in contents.split():
+                        if spec.isdigit():
+                            keys.add(int(spec))
+                        else:
+                            start, stop = (int(x) for x in spec.split('-'))
+                            keys.update(range(start, stop + 1))
+                    results[name] = [key for key in sorted(keys) \
+                                         if key in all_keys]
+                    if len(results[name]) == 0:
+                        del results[name]
+                except ValueError:
+                    raise FormatError('Invalid sequence specification: %s' %
+                                      line.rstrip())
+        finally:
+            f.close()
+        return results
+
+    def set_sequences(self, sequences):
+        """Set sequences using the given name-to-key-list dictionary."""
+        f = open(os.path.join(self._path, '.mh_sequences'), 'r+')
+        try:
+            os.close(os.open(f.name, os.O_WRONLY | os.O_TRUNC))
+            for name, keys in sequences.iteritems():
+                if len(keys) == 0:
+                    continue
+                f.write('%s:' % name)
+                prev = None
+                completing = False
+                for key in sorted(set(keys)):
+                    if key - 1 == prev:
+                        if not completing:
+                            completing = True
+                            f.write('-')
+                    elif completing:
+                        completing = False
+                        f.write('%s %s' % (prev, key))
+                    else:
+                        f.write(' %s' % key)
+                    prev = key
+                if completing:
+                    f.write(str(prev) + '\n')
+                else:
+                    f.write('\n')
+        finally:
+            _sync_close(f)
+
+    def pack(self):
+        """Re-name messages to eliminate numbering gaps. Invalidates keys."""
+        sequences = self.get_sequences()
+        prev = 0
+        changes = []
+        for key in self.iterkeys():
+            if key - 1 != prev:
+                changes.append((key, prev + 1))
+                if hasattr(os, 'link'):
+                    os.link(os.path.join(self._path, str(key)),
+                            os.path.join(self._path, str(prev + 1)))
+                    os.unlink(os.path.join(self._path, str(key)))
+                else:
+                    os.rename(os.path.join(self._path, str(key)),
+                              os.path.join(self._path, str(prev + 1)))
+            prev += 1
+        self._next_key = prev + 1
+        if len(changes) == 0:
+            return
+        for name, key_list in sequences.items():
+            for old, new in changes:
+                if old in key_list:
+                    key_list[key_list.index(old)] = new
+        self.set_sequences(sequences)
+
+    def _dump_sequences(self, message, key):
+        """Inspect a new MHMessage and update sequences appropriately."""
+        pending_sequences = message.get_sequences()
+        all_sequences = self.get_sequences()
+        for name, key_list in all_sequences.iteritems():
+            if name in pending_sequences:
+                key_list.append(key)
+            elif key in key_list:
+                del key_list[key_list.index(key)]
+        for sequence in pending_sequences:
+            if sequence not in all_sequences:
+                all_sequences[sequence] = [key]
+        self.set_sequences(all_sequences)
+
+
+class Babyl(_singlefileMailbox):
+    """An Rmail-style Babyl mailbox."""
+
+    _special_labels = frozenset(('unseen', 'deleted', 'filed', 'answered',
+                                 'forwarded', 'edited', 'resent'))
+
+    def __init__(self, path, factory=None, create=True):
+        """Initialize a Babyl mailbox."""
+        _singlefileMailbox.__init__(self, path, factory, create)
+        self._labels = {}
+
+    def add(self, message):
+        """Add message and return assigned key."""
+        key = _singlefileMailbox.add(self, message)
+        if isinstance(message, BabylMessage):
+            self._labels[key] = message.get_labels()
+        return key
+
+    def remove(self, key):
+        """Remove the keyed message; raise KeyError if it doesn't exist."""
+        _singlefileMailbox.remove(self, key)
+        if key in self._labels:
+            del self._labels[key]
+
+    def __setitem__(self, key, message):
+        """Replace the keyed message; raise KeyError if it doesn't exist."""
+        _singlefileMailbox.__setitem__(self, key, message)
+        if isinstance(message, BabylMessage):
+            self._labels[key] = message.get_labels()
+
+    def get_message(self, key):
+        """Return a Message representation or raise a KeyError."""
+        start, stop = self._lookup(key)
+        self._file.seek(start)
+        self._file.readline()   # Skip '1,' line specifying labels.
+        original_headers = StringIO.StringIO()
+        while True:
+            line = self._file.readline()
+            if line == '*** EOOH ***' + os.linesep or line == '':
+                break
+            original_headers.write(line.replace(os.linesep, '\n'))
+        visible_headers = StringIO.StringIO()
+        while True:
+            line = self._file.readline()
+            if line == os.linesep or line == '':
+                break
+            visible_headers.write(line.replace(os.linesep, '\n'))
+        body = self._file.read(stop - self._file.tell()).replace(os.linesep,
+                                                                 '\n')
+        msg = BabylMessage(original_headers.getvalue() + body)
+        msg.set_visible(visible_headers.getvalue())
+        if key in self._labels:
+            msg.set_labels(self._labels[key])
+        return msg
+
+    def get_string(self, key):
+        """Return a string representation or raise a KeyError."""
+        start, stop = self._lookup(key)
+        self._file.seek(start)
+        self._file.readline()   # Skip '1,' line specifying labels.
+        original_headers = StringIO.StringIO()
+        while True:
+            line = self._file.readline()
+            if line == '*** EOOH ***' + os.linesep or line == '':
+                break
+            original_headers.write(line.replace(os.linesep, '\n'))
+        while True:
+            line = self._file.readline()
+            if line == os.linesep or line == '':
+                break
+        return original_headers.getvalue() + \
+               self._file.read(stop - self._file.tell()).replace(os.linesep,
+                                                                 '\n')
+
+    def get_file(self, key):
+        """Return a file-like representation or raise a KeyError."""
+        return StringIO.StringIO(self.get_string(key).replace('\n',
+                                                              os.linesep))
+
+    def get_labels(self):
+        """Return a list of user-defined labels in the mailbox."""
+        self._lookup()
+        labels = set()
+        for label_list in self._labels.values():
+            labels.update(label_list)
+        labels.difference_update(self._special_labels)
+        return list(labels)
+
+    def _generate_toc(self):
+        """Generate key-to-(start, stop) table of contents."""
+        starts, stops = [], []
+        self._file.seek(0)
+        next_pos = 0
+        label_lists = []
+        while True:
+            line_pos = next_pos
+            line = self._file.readline()
+            next_pos = self._file.tell()
+            if line == '\037\014' + os.linesep:
+                if len(stops) < len(starts):
+                    stops.append(line_pos - len(os.linesep))
+                starts.append(next_pos)
+                labels = [label.strip() for label
+                                        in self._file.readline()[1:].split(',')
+                                        if label.strip() != '']
+                label_lists.append(labels)
+            elif line == '\037' or line == '\037' + os.linesep:
+                if len(stops) < len(starts):
+                    stops.append(line_pos - len(os.linesep))
+            elif line == '':
+                stops.append(line_pos - len(os.linesep))
+                break
+        self._toc = dict(enumerate(zip(starts, stops)))
+        self._labels = dict(enumerate(label_lists))
+        self._next_key = len(self._toc)
+
+    def _pre_mailbox_hook(self, f):
+        """Called before writing the mailbox to file f."""
+        f.write('BABYL OPTIONS:%sVersion: 5%sLabels:%s%s\037' %
+                (os.linesep, os.linesep, ','.join(self.get_labels()),
+                 os.linesep))
+
+    def _pre_message_hook(self, f):
+        """Called before writing each message to file f."""
+        f.write('\014' + os.linesep)
+
+    def _post_message_hook(self, f):
+        """Called after writing each message to file f."""
+        f.write(os.linesep + '\037')
+
+    def _install_message(self, message):
+        """Write message contents and return (start, stop)."""
+        start = self._file.tell()
+        if isinstance(message, BabylMessage):
+            special_labels = []
+            labels = []
+            for label in message.get_labels():
+                if label in self._special_labels:
+                    special_labels.append(label)
+                else:
+                    labels.append(label)
+            self._file.write('1')
+            for label in special_labels:
+                self._file.write(', ' + label)
+            self._file.write(',,')
+            for label in labels:
+                self._file.write(' ' + label + ',')
+            self._file.write(os.linesep)
+        else:
+            self._file.write('1,,' + os.linesep)
+        if isinstance(message, email.Message.Message):
+            orig_buffer = StringIO.StringIO()
+            orig_generator = email.Generator.Generator(orig_buffer, False, 0)
+            orig_generator.flatten(message)
+            orig_buffer.seek(0)
+            while True:
+                line = orig_buffer.readline()
+                self._file.write(line.replace('\n', os.linesep))
+                if line == '\n' or line == '':
+                    break
+            self._file.write('*** EOOH ***' + os.linesep)
+            if isinstance(message, BabylMessage):
+                vis_buffer = StringIO.StringIO()
+                vis_generator = email.Generator.Generator(vis_buffer, False, 0)
+                vis_generator.flatten(message.get_visible())
+                while True:
+                    line = vis_buffer.readline()
+                    self._file.write(line.replace('\n', os.linesep))
+                    if line == '\n' or line == '':
+                        break
+            else:
+                orig_buffer.seek(0)
+                while True:
+                    line = orig_buffer.readline()
+                    self._file.write(line.replace('\n', os.linesep))
+                    if line == '\n' or line == '':
+                        break
+            while True:
+                buffer = orig_buffer.read(4096) # Buffer size is arbitrary.
+                if buffer == '':
+                    break
+                self._file.write(buffer.replace('\n', os.linesep))
+        elif isinstance(message, str):
+            body_start = message.find('\n\n') + 2
+            if body_start - 2 != -1:
+                self._file.write(message[:body_start].replace('\n',
+                                                              os.linesep))
+                self._file.write('*** EOOH ***' + os.linesep)
+                self._file.write(message[:body_start].replace('\n',
+                                                              os.linesep))
+                self._file.write(message[body_start:].replace('\n',
+                                                              os.linesep))
+            else:
+                self._file.write('*** EOOH ***' + os.linesep + os.linesep)
+                self._file.write(message.replace('\n', os.linesep))
+        elif hasattr(message, 'readline'):
+            original_pos = message.tell()
+            first_pass = True
+            while True:
+                line = message.readline()
+                self._file.write(line.replace('\n', os.linesep))
+                if line == '\n' or line == '':
+                    self._file.write('*** EOOH ***' + os.linesep)
+                    if first_pass:
+                        first_pass = False
+                        message.seek(original_pos)
+                    else:
+                        break
+            while True:
+                buffer = message.read(4096)     # Buffer size is arbitrary.
+                if buffer == '':
+                    break
+                self._file.write(buffer.replace('\n', os.linesep))
+        else:
+            raise TypeError('Invalid message type: %s' % type(message))
+        stop = self._file.tell()
+        return (start, stop)
+
+
+class Message(email.Message.Message):
+    """Message with mailbox-format-specific properties."""
+
+    def __init__(self, message=None):
+        """Initialize a Message instance."""
+        if isinstance(message, email.Message.Message):
+            self._become_message(copy.deepcopy(message))
+            if isinstance(message, Message):
+                message._explain_to(self)
+        elif isinstance(message, str):
+            self._become_message(email.message_from_string(message))
+        elif hasattr(message, "read"):
+            self._become_message(email.message_from_file(message))
+        elif message is None:
+            email.Message.Message.__init__(self)
+        else:
+            raise TypeError('Invalid message type: %s' % type(message))
+
+    def _become_message(self, message):
+        """Assume the non-format-specific state of message."""
+        for name in ('_headers', '_unixfrom', '_payload', '_charset',
+                     'preamble', 'epilogue', 'defects', '_default_type'):
+            self.__dict__[name] = message.__dict__[name]
+
+    def _explain_to(self, message):
+        """Copy format-specific state to message insofar as possible."""
+        if isinstance(message, Message):
+            return  # There's nothing format-specific to explain.
+        else:
+            raise TypeError('Cannot convert to specified type')
+
+
+class MaildirMessage(Message):
+    """Message with Maildir-specific properties."""
+
+    def __init__(self, message=None):
+        """Initialize a MaildirMessage instance."""
+        self._subdir = 'new'
+        self._info = ''
+        self._date = time.time()
+        Message.__init__(self, message)
+
+    def get_subdir(self):
+        """Return 'new' or 'cur'."""
+        return self._subdir
+
+    def set_subdir(self, subdir):
+        """Set subdir to 'new' or 'cur'."""
+        if subdir == 'new' or subdir == 'cur':
+            self._subdir = subdir
+        else:
+            raise ValueError("subdir must be 'new' or 'cur': %s" % subdir)
+
+    def get_flags(self):
+        """Return as a string the flags that are set."""
+        if self._info.startswith('2,'):
+            return self._info[2:]
+        else:
+            return ''
+
+    def set_flags(self, flags):
+        """Set the given flags and unset all others."""
+        self._info = '2,' + ''.join(sorted(flags))
+
+    def add_flag(self, flag):
+        """Set the given flag(s) without changing others."""
+        self.set_flags(''.join(set(self.get_flags()) | set(flag)))
+
+    def remove_flag(self, flag):
+        """Unset the given string flag(s) without changing others."""
+        if self.get_flags() != '':
+            self.set_flags(''.join(set(self.get_flags()) - set(flag)))
+
+    def get_date(self):
+        """Return delivery date of message, in seconds since the epoch."""
+        return self._date
+
+    def set_date(self, date):
+        """Set delivery date of message, in seconds since the epoch."""
+        try:
+            self._date = float(date)
+        except ValueError:
+            raise TypeError("can't convert to float: %s" % date)
+
+    def get_info(self):
+        """Get the message's "info" as a string."""
+        return self._info
+
+    def set_info(self, info):
+        """Set the message's "info" string."""
+        if isinstance(info, str):
+            self._info = info
+        else:
+            raise TypeError('info must be a string: %s' % type(info))
+
+    def _explain_to(self, message):
+        """Copy Maildir-specific state to message insofar as possible."""
+        if isinstance(message, MaildirMessage):
+            message.set_flags(self.get_flags())
+            message.set_subdir(self.get_subdir())
+            message.set_date(self.get_date())
+        elif isinstance(message, _mboxMMDFMessage):
+            flags = set(self.get_flags())
+            if 'S' in flags:
+                message.add_flag('R')
+            if self.get_subdir() == 'cur':
+                message.add_flag('O')
+            if 'T' in flags:
+                message.add_flag('D')
+            if 'F' in flags:
+                message.add_flag('F')
+            if 'R' in flags:
+                message.add_flag('A')
+            message.set_from('MAILER-DAEMON', time.gmtime(self.get_date()))
+        elif isinstance(message, MHMessage):
+            flags = set(self.get_flags())
+            if 'S' not in flags:
+                message.add_sequence('unseen')
+            if 'R' in flags:
+                message.add_sequence('replied')
+            if 'F' in flags:
+                message.add_sequence('flagged')
+        elif isinstance(message, BabylMessage):
+            flags = set(self.get_flags())
+            if 'S' not in flags:
+                message.add_label('unseen')
+            if 'T' in flags:
+                message.add_label('deleted')
+            if 'R' in flags:
+                message.add_label('answered')
+            if 'P' in flags:
+                message.add_label('forwarded')
+        elif isinstance(message, Message):
+            pass
+        else:
+            raise TypeError('Cannot convert to specified type: %s' %
+                            type(message))
+
+
+class _mboxMMDFMessage(Message):
+    """Message with mbox- or MMDF-specific properties."""
+
+    def __init__(self, message=None):
+        """Initialize an mboxMMDFMessage instance."""
+        self.set_from('MAILER-DAEMON', True)
+        if isinstance(message, email.Message.Message):
+            unixfrom = message.get_unixfrom()
+            if unixfrom is not None and unixfrom.startswith('From '):
+                self.set_from(unixfrom[5:])
+        Message.__init__(self, message)
+
+    def get_from(self):
+        """Return contents of "From " line."""
+        return self._from
+
+    def set_from(self, from_, time_=None):
+        """Set "From " line, formatting and appending time_ if specified."""
+        if time_ is not None:
+            if time_ is True:
+                time_ = time.gmtime()
+            from_ += ' ' + time.asctime(time_)
+        self._from = from_
+
+    def get_flags(self):
+        """Return as a string the flags that are set."""
+        return self.get('Status', '') + self.get('X-Status', '')
+
+    def set_flags(self, flags):
+        """Set the given flags and unset all others."""
+        flags = set(flags)
+        status_flags, xstatus_flags = '', ''
+        for flag in ('R', 'O'):
+            if flag in flags:
+                status_flags += flag
+                flags.remove(flag)
+        for flag in ('D', 'F', 'A'):
+            if flag in flags:
+                xstatus_flags += flag
+                flags.remove(flag)
+        xstatus_flags += ''.join(sorted(flags))
+        try:
+            self.replace_header('Status', status_flags)
+        except KeyError:
+            self.add_header('Status', status_flags)
+        try:
+            self.replace_header('X-Status', xstatus_flags)
+        except KeyError:
+            self.add_header('X-Status', xstatus_flags)
+
+    def add_flag(self, flag):
+        """Set the given flag(s) without changing others."""
+        self.set_flags(''.join(set(self.get_flags()) | set(flag)))
+
+    def remove_flag(self, flag):
+        """Unset the given string flag(s) without changing others."""
+        if 'Status' in self or 'X-Status' in self:
+            self.set_flags(''.join(set(self.get_flags()) - set(flag)))
+
+    def _explain_to(self, message):
+        """Copy mbox- or MMDF-specific state to message insofar as possible."""
+        if isinstance(message, MaildirMessage):
+            flags = set(self.get_flags())
+            if 'O' in flags:
+                message.set_subdir('cur')
+            if 'F' in flags:
+                message.add_flag('F')
+            if 'A' in flags:
+                message.add_flag('R')
+            if 'R' in flags:
+                message.add_flag('S')
+            if 'D' in flags:
+                message.add_flag('T')
+            del message['status']
+            del message['x-status']
+            maybe_date = ' '.join(self.get_from().split()[-5:])
+            try:
+                message.set_date(calendar.timegm(time.strptime(maybe_date,
+                                                      '%a %b %d %H:%M:%S %Y')))
+            except (ValueError, OverflowError):
+                pass
+        elif isinstance(message, _mboxMMDFMessage):
+            message.set_flags(self.get_flags())
+            message.set_from(self.get_from())
+        elif isinstance(message, MHMessage):
+            flags = set(self.get_flags())
+            if 'R' not in flags:
+                message.add_sequence('unseen')
+            if 'A' in flags:
+                message.add_sequence('replied')
+            if 'F' in flags:
+                message.add_sequence('flagged')
+            del message['status']
+            del message['x-status']
+        elif isinstance(message, BabylMessage):
+            flags = set(self.get_flags())
+            if 'R' not in flags:
+                message.add_label('unseen')
+            if 'D' in flags:
+                message.add_label('deleted')
+            if 'A' in flags:
+                message.add_label('answered')
+            del message['status']
+            del message['x-status']
+        elif isinstance(message, Message):
+            pass
+        else:
+            raise TypeError('Cannot convert to specified type: %s' %
+                            type(message))
+
+
+class mboxMessage(_mboxMMDFMessage):
+    """Message with mbox-specific properties."""
+
+
+class MHMessage(Message):
+    """Message with MH-specific properties."""
+
+    def __init__(self, message=None):
+        """Initialize an MHMessage instance."""
+        self._sequences = []
+        Message.__init__(self, message)
+
+    def get_sequences(self):
+        """Return a list of sequences that include the message."""
+        return self._sequences[:]
+
+    def set_sequences(self, sequences):
+        """Set the list of sequences that include the message."""
+        self._sequences = list(sequences)
+
+    def add_sequence(self, sequence):
+        """Add sequence to list of sequences including the message."""
+        if isinstance(sequence, str):
+            if not sequence in self._sequences:
+                self._sequences.append(sequence)
+        else:
+            raise TypeError('sequence must be a string: %s' % type(sequence))
+
+    def remove_sequence(self, sequence):
+        """Remove sequence from the list of sequences including the message."""
+        try:
+            self._sequences.remove(sequence)
+        except ValueError:
+            pass
+
+    def _explain_to(self, message):
+        """Copy MH-specific state to message insofar as possible."""
+        if isinstance(message, MaildirMessage):
+            sequences = set(self.get_sequences())
+            if 'unseen' in sequences:
+                message.set_subdir('cur')
+            else:
+                message.set_subdir('cur')
+                message.add_flag('S')
+            if 'flagged' in sequences:
+                message.add_flag('F')
+            if 'replied' in sequences:
+                message.add_flag('R')
+        elif isinstance(message, _mboxMMDFMessage):
+            sequences = set(self.get_sequences())
+            if 'unseen' not in sequences:
+                message.add_flag('RO')
+            else:
+                message.add_flag('O')
+            if 'flagged' in sequences:
+                message.add_flag('F')
+            if 'replied' in sequences:
+                message.add_flag('A')
+        elif isinstance(message, MHMessage):
+            for sequence in self.get_sequences():
+                message.add_sequence(sequence)
+        elif isinstance(message, BabylMessage):
+            sequences = set(self.get_sequences())
+            if 'unseen' in sequences:
+                message.add_label('unseen')
+            if 'replied' in sequences:
+                message.add_label('answered')
+        elif isinstance(message, Message):
+            pass
+        else:
+            raise TypeError('Cannot convert to specified type: %s' %
+                            type(message))
+
+
+class BabylMessage(Message):
+    """Message with Babyl-specific properties."""
+
+    def __init__(self, message=None):
+        """Initialize an BabylMessage instance."""
+        self._labels = []
+        self._visible = Message()
+        Message.__init__(self, message)
+
+    def get_labels(self):
+        """Return a list of labels on the message."""
+        return self._labels[:]
+
+    def set_labels(self, labels):
+        """Set the list of labels on the message."""
+        self._labels = list(labels)
+
+    def add_label(self, label):
+        """Add label to list of labels on the message."""
+        if isinstance(label, str):
+            if label not in self._labels:
+                self._labels.append(label)
+        else:
+            raise TypeError('label must be a string: %s' % type(label))
+
+    def remove_label(self, label):
+        """Remove label from the list of labels on the message."""
+        try:
+            self._labels.remove(label)
+        except ValueError:
+            pass
+
+    def get_visible(self):
+        """Return a Message representation of visible headers."""
+        return Message(self._visible)
+
+    def set_visible(self, visible):
+        """Set the Message representation of visible headers."""
+        self._visible = Message(visible)
+
+    def update_visible(self):
+        """Update and/or sensibly generate a set of visible headers."""
+        for header in self._visible.keys():
+            if header in self:
+                self._visible.replace_header(header, self[header])
+            else:
+                del self._visible[header]
+        for header in ('Date', 'From', 'Reply-To', 'To', 'CC', 'Subject'):
+            if header in self and header not in self._visible:
+                self._visible[header] = self[header]
+
+    def _explain_to(self, message):
+        """Copy Babyl-specific state to message insofar as possible."""
+        if isinstance(message, MaildirMessage):
+            labels = set(self.get_labels())
+            if 'unseen' in labels:
+                message.set_subdir('cur')
+            else:
+                message.set_subdir('cur')
+                message.add_flag('S')
+            if 'forwarded' in labels or 'resent' in labels:
+                message.add_flag('P')
+            if 'answered' in labels:
+                message.add_flag('R')
+            if 'deleted' in labels:
+                message.add_flag('T')
+        elif isinstance(message, _mboxMMDFMessage):
+            labels = set(self.get_labels())
+            if 'unseen' not in labels:
+                message.add_flag('RO')
+            else:
+                message.add_flag('O')
+            if 'deleted' in labels:
+                message.add_flag('D')
+            if 'answered' in labels:
+                message.add_flag('A')
+        elif isinstance(message, MHMessage):
+            labels = set(self.get_labels())
+            if 'unseen' in labels:
+                message.add_sequence('unseen')
+            if 'answered' in labels:
+                message.add_sequence('replied')
+        elif isinstance(message, BabylMessage):
+            message.set_visible(self.get_visible())
+            for label in self.get_labels():
+                message.add_label(label)
+        elif isinstance(message, Message):
+            pass
+        else:
+            raise TypeError('Cannot convert to specified type: %s' %
+                            type(message))
+
+
+class MMDFMessage(_mboxMMDFMessage):
+    """Message with MMDF-specific properties."""
+
+
+class _ProxyFile:
+    """A read-only wrapper of a file."""
+
+    def __init__(self, f, pos=None):
+        """Initialize a _ProxyFile."""
+        self._file = f
+        if pos is None:
+            self._pos = f.tell()
+        else:
+            self._pos = pos
+
+    def read(self, size=None):
+        """Read bytes."""
+        return self._read(size, self._file.read)
+
+    def readline(self, size=None):
+        """Read a line."""
+        return self._read(size, self._file.readline)
+
+    def readlines(self, sizehint=None):
+        """Read multiple lines."""
+        result = []
+        for line in self:
+            result.append(line)
+            if sizehint is not None:
+                sizehint -= len(line)
+                if sizehint <= 0:
+                    break
+        return result
+
+    def __iter__(self):
+        """Iterate over lines."""
+        return iter(self.readline, "")
+
+    def tell(self):
+        """Return the position."""
+        return self._pos
+
+    def seek(self, offset, whence=0):
+        """Change position."""
+        if whence == 1:
+            self._file.seek(self._pos)
+        self._file.seek(offset, whence)
+        self._pos = self._file.tell()
+
+    def close(self):
+        """Close the file."""
+        del self._file
+
+    def _read(self, size, read_method):
+        """Read size bytes using read_method."""
+        if size is None:
+            size = -1
+        self._file.seek(self._pos)
+        result = read_method(size)
+        self._pos = self._file.tell()
+        return result
+
+
+class _PartialFile(_ProxyFile):
+    """A read-only wrapper of part of a file."""
+
+    def __init__(self, f, start=None, stop=None):
+        """Initialize a _PartialFile."""
+        _ProxyFile.__init__(self, f, start)
+        self._start = start
+        self._stop = stop
+
+    def tell(self):
+        """Return the position with respect to start."""
+        return _ProxyFile.tell(self) - self._start
+
+    def seek(self, offset, whence=0):
+        """Change position, possibly with respect to start or stop."""
+        if whence == 0:
+            self._pos = self._start
+            whence = 1
+        elif whence == 2:
+            self._pos = self._stop
+            whence = 1
+        _ProxyFile.seek(self, offset, whence)
+
+    def _read(self, size, read_method):
+        """Read size bytes using read_method, honoring start and stop."""
+        remaining = self._stop - self._pos
+        if remaining <= 0:
+            return ''
+        if size is None or size < 0 or size > remaining:
+            size = remaining
+        return _ProxyFile._read(self, size, read_method)
+
+
+def _lock_file(f, dotlock=True):
+    """Lock file f using lockf and dot locking."""
+    dotlock_done = False
+    try:
+        if fcntl:
+            try:
+                fcntl.lockf(f, fcntl.LOCK_EX | fcntl.LOCK_NB)
+            except IOError, e:
+                if e.errno in (errno.EAGAIN, errno.EACCES):
+                    raise ExternalClashError('lockf: lock unavailable: %s' %
+                                             f.name)
+                else:
+                    raise
+        if dotlock:
+            try:
+                pre_lock = _create_temporary(f.name + '.lock')
+                pre_lock.close()
+            except IOError, e:
+                if e.errno == errno.EACCES:
+                    return  # Without write access, just skip dotlocking.
+                else:
+                    raise
+            try:
+                if hasattr(os, 'link'):
+                    os.link(pre_lock.name, f.name + '.lock')
+                    dotlock_done = True
+                    os.unlink(pre_lock.name)
+                else:
+                    os.rename(pre_lock.name, f.name + '.lock')
+                    dotlock_done = True
+            except OSError, e:
+                if e.errno == errno.EEXIST or \
+                  (os.name == 'os2' and e.errno == errno.EACCES):
+                    os.remove(pre_lock.name)
+                    raise ExternalClashError('dot lock unavailable: %s' %
+                                             f.name)
+                else:
+                    raise
+    except:
+        if fcntl:
+            fcntl.lockf(f, fcntl.LOCK_UN)
+        if dotlock_done:
+            os.remove(f.name + '.lock')
+        raise
+
+def _unlock_file(f):
+    """Unlock file f using lockf and dot locking."""
+    if fcntl:
+        fcntl.lockf(f, fcntl.LOCK_UN)
+    if os.path.exists(f.name + '.lock'):
+        os.remove(f.name + '.lock')
+
+def _create_carefully(path):
+    """Create a file if it doesn't exist and open for reading and writing."""
+    fd = os.open(path, os.O_CREAT | os.O_EXCL | os.O_RDWR)
+    try:
+        return open(path, 'rb+')
+    finally:
+        os.close(fd)
+
+def _create_temporary(path):
+    """Create a temp file based on path and open for reading and writing."""
+    return _create_carefully('%s.%s.%s.%s' % (path, int(time.time()),
+                                              socket.gethostname(),
+                                              os.getpid()))
+
+def _sync_flush(f):
+    """Ensure changes to file f are physically on disk."""
+    f.flush()
+    if hasattr(os, 'fsync'):
+        os.fsync(f.fileno())
+
+def _sync_close(f):
+    """Close file f, ensuring all changes are physically on disk."""
+    _sync_flush(f)
+    f.close()
+
+## Start: classes from the original module (for backward compatibility).
+
+# Note that the Maildir class, whose name is unchanged, itself offers a next()
+# method for backward compatibility.
+
+class _Mailbox:
+
+    def __init__(self, fp, factory=rfc822.Message):
+        self.fp = fp
+        self.seekp = 0
+        self.factory = factory
+
+    def __iter__(self):
+        return iter(self.next, None)
+
+    def next(self):
+        while 1:
+            self.fp.seek(self.seekp)
+            try:
+                self._search_start()
+            except EOFError:
+                self.seekp = self.fp.tell()
+                return None
+            start = self.fp.tell()
+            self._search_end()
+            self.seekp = stop = self.fp.tell()
+            if start != stop:
+                break
+        return self.factory(_PartialFile(self.fp, start, stop))
+
+# Recommended to use PortableUnixMailbox instead!
+class UnixMailbox(_Mailbox):
+
+    def _search_start(self):
+        while 1:
+            pos = self.fp.tell()
+            line = self.fp.readline()
+            if not line:
+                raise EOFError
+            if line[:5] == 'From ' and self._isrealfromline(line):
+                self.fp.seek(pos)
+                return
+
+    def _search_end(self):
+        self.fp.readline()      # Throw away header line
+        while 1:
+            pos = self.fp.tell()
+            line = self.fp.readline()
+            if not line:
+                return
+            if line[:5] == 'From ' and self._isrealfromline(line):
+                self.fp.seek(pos)
+                return
+
+    # An overridable mechanism to test for From-line-ness.  You can either
+    # specify a different regular expression or define a whole new
+    # _isrealfromline() method.  Note that this only gets called for lines
+    # starting with the 5 characters "From ".
+    #
+    # BAW: According to
+    #http://home.netscape.com/eng/mozilla/2.0/relnotes/demo/content-length.html
+    # the only portable, reliable way to find message delimiters in a BSD (i.e
+    # Unix mailbox) style folder is to search for "\n\nFrom .*\n", or at the
+    # beginning of the file, "^From .*\n".  While _fromlinepattern below seems
+    # like a good idea, in practice, there are too many variations for more
+    # strict parsing of the line to be completely accurate.
+    #
+    # _strict_isrealfromline() is the old version which tries to do stricter
+    # parsing of the From_ line.  _portable_isrealfromline() simply returns
+    # true, since it's never called if the line doesn't already start with
+    # "From ".
+    #
+    # This algorithm, and the way it interacts with _search_start() and
+    # _search_end() may not be completely correct, because it doesn't check
+    # that the two characters preceding "From " are \n\n or the beginning of
+    # the file.  Fixing this would require a more extensive rewrite than is
+    # necessary.  For convenience, we've added a PortableUnixMailbox class
+    # which does no checking of the format of the 'From' line.
+
+    _fromlinepattern = (r"From \s*[^\s]+\s+\w\w\w\s+\w\w\w\s+\d?\d\s+"
+                        r"\d?\d:\d\d(:\d\d)?(\s+[^\s]+)?\s+\d\d\d\d\s*"
+                        r"[^\s]*\s*"
+                        "$")
+    _regexp = None
+
+    def _strict_isrealfromline(self, line):
+        if not self._regexp:
+            import re
+            self._regexp = re.compile(self._fromlinepattern)
+        return self._regexp.match(line)
+
+    def _portable_isrealfromline(self, line):
+        return True
+
+    _isrealfromline = _strict_isrealfromline
+
+
+class PortableUnixMailbox(UnixMailbox):
+    _isrealfromline = UnixMailbox._portable_isrealfromline
+
+
+class MmdfMailbox(_Mailbox):
+
+    def _search_start(self):
+        while 1:
+            line = self.fp.readline()
+            if not line:
+                raise EOFError
+            if line[:5] == '\001\001\001\001\n':
+                return
+
+    def _search_end(self):
+        while 1:
+            pos = self.fp.tell()
+            line = self.fp.readline()
+            if not line:
+                return
+            if line == '\001\001\001\001\n':
+                self.fp.seek(pos)
+                return
+
+
+class MHMailbox:
+
+    def __init__(self, dirname, factory=rfc822.Message):
+        import re
+        pat = re.compile('^[1-9][0-9]*$')
+        self.dirname = dirname
+        # the three following lines could be combined into:
+        # list = map(long, filter(pat.match, os.listdir(self.dirname)))
+        list = os.listdir(self.dirname)
+        list = filter(pat.match, list)
+        list = map(long, list)
+        list.sort()
+        # This only works in Python 1.6 or later;
+        # before that str() added 'L':
+        self.boxes = map(str, list)
+        self.boxes.reverse()
+        self.factory = factory
+
+    def __iter__(self):
+        return iter(self.next, None)
+
+    def next(self):
+        if not self.boxes:
+            return None
+        fn = self.boxes.pop()
+        fp = open(os.path.join(self.dirname, fn))
+        msg = self.factory(fp)
+        try:
+            msg._mh_msgno = fn
+        except (AttributeError, TypeError):
+            pass
+        return msg
+
+
+class BabylMailbox(_Mailbox):
+
+    def _search_start(self):
+        while 1:
+            line = self.fp.readline()
+            if not line:
+                raise EOFError
+            if line == '*** EOOH ***\n':
+                return
+
+    def _search_end(self):
+        while 1:
+            pos = self.fp.tell()
+            line = self.fp.readline()
+            if not line:
+                return
+            if line == '\037\014\n' or line == '\037':
+                self.fp.seek(pos)
+                return
+
+## End: classes from the original module (for backward compatibility).
+
+
+class Error(Exception):
+    """Raised for module-specific errors."""
+
+class NoSuchMailboxError(Error):
+    """The specified mailbox does not exist and won't be created."""
+
+class NotEmptyError(Error):
+    """The specified mailbox is not empty and deletion was requested."""
+
+class ExternalClashError(Error):
+    """Another process caused an action to fail."""
+
+class FormatError(Error):
+    """A file appears to have an invalid format."""


Property changes on: vendor/Python/current/Lib/mailbox.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/mailcap.py
===================================================================
--- vendor/Python/current/Lib/mailcap.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/mailcap.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,255 @@
+"""Mailcap file handling.  See RFC 1524."""
+
+import os
+
+__all__ = ["getcaps","findmatch"]
+
+# Part 1: top-level interface.
+
+def getcaps():
+    """Return a dictionary containing the mailcap database.
+
+    The dictionary maps a MIME type (in all lowercase, e.g. 'text/plain')
+    to a list of dictionaries corresponding to mailcap entries.  The list
+    collects all the entries for that MIME type from all available mailcap
+    files.  Each dictionary contains key-value pairs for that MIME type,
+    where the viewing command is stored with the key "view".
+
+    """
+    caps = {}
+    for mailcap in listmailcapfiles():
+        try:
+            fp = open(mailcap, 'r')
+        except IOError:
+            continue
+        morecaps = readmailcapfile(fp)
+        fp.close()
+        for key, value in morecaps.iteritems():
+            if not key in caps:
+                caps[key] = value
+            else:
+                caps[key] = caps[key] + value
+    return caps
+
+def listmailcapfiles():
+    """Return a list of all mailcap files found on the system."""
+    # XXX Actually, this is Unix-specific
+    if 'MAILCAPS' in os.environ:
+        str = os.environ['MAILCAPS']
+        mailcaps = str.split(':')
+    else:
+        if 'HOME' in os.environ:
+            home = os.environ['HOME']
+        else:
+            # Don't bother with getpwuid()
+            home = '.' # Last resort
+        mailcaps = [home + '/.mailcap', '/etc/mailcap',
+                '/usr/etc/mailcap', '/usr/local/etc/mailcap']
+    return mailcaps
+
+
+# Part 2: the parser.
+
+def readmailcapfile(fp):
+    """Read a mailcap file and return a dictionary keyed by MIME type.
+
+    Each MIME type is mapped to an entry consisting of a list of
+    dictionaries; the list will contain more than one such dictionary
+    if a given MIME type appears more than once in the mailcap file.
+    Each dictionary contains key-value pairs for that MIME type, where
+    the viewing command is stored with the key "view".
+    """
+    caps = {}
+    while 1:
+        line = fp.readline()
+        if not line: break
+        # Ignore comments and blank lines
+        if line[0] == '#' or line.strip() == '':
+            continue
+        nextline = line
+        # Join continuation lines
+        while nextline[-2:] == '\\\n':
+            nextline = fp.readline()
+            if not nextline: nextline = '\n'
+            line = line[:-2] + nextline
+        # Parse the line
+        key, fields = parseline(line)
+        if not (key and fields):
+            continue
+        # Normalize the key
+        types = key.split('/')
+        for j in range(len(types)):
+            types[j] = types[j].strip()
+        key = '/'.join(types).lower()
+        # Update the database
+        if key in caps:
+            caps[key].append(fields)
+        else:
+            caps[key] = [fields]
+    return caps
+
+def parseline(line):
+    """Parse one entry in a mailcap file and return a dictionary.
+
+    The viewing command is stored as the value with the key "view",
+    and the rest of the fields produce key-value pairs in the dict.
+    """
+    fields = []
+    i, n = 0, len(line)
+    while i < n:
+        field, i = parsefield(line, i, n)
+        fields.append(field)
+        i = i+1 # Skip semicolon
+    if len(fields) < 2:
+        return None, None
+    key, view, rest = fields[0], fields[1], fields[2:]
+    fields = {'view': view}
+    for field in rest:
+        i = field.find('=')
+        if i < 0:
+            fkey = field
+            fvalue = ""
+        else:
+            fkey = field[:i].strip()
+            fvalue = field[i+1:].strip()
+        if fkey in fields:
+            # Ignore it
+            pass
+        else:
+            fields[fkey] = fvalue
+    return key, fields
+
+def parsefield(line, i, n):
+    """Separate one key-value pair in a mailcap entry."""
+    start = i
+    while i < n:
+        c = line[i]
+        if c == ';':
+            break
+        elif c == '\\':
+            i = i+2
+        else:
+            i = i+1
+    return line[start:i].strip(), i
+
+
+# Part 3: using the database.
+
+def findmatch(caps, MIMEtype, key='view', filename="/dev/null", plist=[]):
+    """Find a match for a mailcap entry.
+
+    Return a tuple containing the command line, and the mailcap entry
+    used; (None, None) if no match is found.  This may invoke the
+    'test' command of several matching entries before deciding which
+    entry to use.
+
+    """
+    entries = lookup(caps, MIMEtype, key)
+    # XXX This code should somehow check for the needsterminal flag.
+    for e in entries:
+        if 'test' in e:
+            test = subst(e['test'], filename, plist)
+            if test and os.system(test) != 0:
+                continue
+        command = subst(e[key], MIMEtype, filename, plist)
+        return command, e
+    return None, None
+
+def lookup(caps, MIMEtype, key=None):
+    entries = []
+    if MIMEtype in caps:
+        entries = entries + caps[MIMEtype]
+    MIMEtypes = MIMEtype.split('/')
+    MIMEtype = MIMEtypes[0] + '/*'
+    if MIMEtype in caps:
+        entries = entries + caps[MIMEtype]
+    if key is not None:
+        entries = filter(lambda e, key=key: key in e, entries)
+    return entries
+
+def subst(field, MIMEtype, filename, plist=[]):
+    # XXX Actually, this is Unix-specific
+    res = ''
+    i, n = 0, len(field)
+    while i < n:
+        c = field[i]; i = i+1
+        if c != '%':
+            if c == '\\':
+                c = field[i:i+1]; i = i+1
+            res = res + c
+        else:
+            c = field[i]; i = i+1
+            if c == '%':
+                res = res + c
+            elif c == 's':
+                res = res + filename
+            elif c == 't':
+                res = res + MIMEtype
+            elif c == '{':
+                start = i
+                while i < n and field[i] != '}':
+                    i = i+1
+                name = field[start:i]
+                i = i+1
+                res = res + findparam(name, plist)
+            # XXX To do:
+            # %n == number of parts if type is multipart/*
+            # %F == list of alternating type and filename for parts
+            else:
+                res = res + '%' + c
+    return res
+
+def findparam(name, plist):
+    name = name.lower() + '='
+    n = len(name)
+    for p in plist:
+        if p[:n].lower() == name:
+            return p[n:]
+    return ''
+
+
+# Part 4: test program.
+
+def test():
+    import sys
+    caps = getcaps()
+    if not sys.argv[1:]:
+        show(caps)
+        return
+    for i in range(1, len(sys.argv), 2):
+        args = sys.argv[i:i+2]
+        if len(args) < 2:
+            print "usage: mailcap [MIMEtype file] ..."
+            return
+        MIMEtype = args[0]
+        file = args[1]
+        command, e = findmatch(caps, MIMEtype, 'view', file)
+        if not command:
+            print "No viewer found for", type
+        else:
+            print "Executing:", command
+            sts = os.system(command)
+            if sts:
+                print "Exit status:", sts
+
+def show(caps):
+    print "Mailcap files:"
+    for fn in listmailcapfiles(): print "\t" + fn
+    print
+    if not caps: caps = getcaps()
+    print "Mailcap entries:"
+    print
+    ckeys = caps.keys()
+    ckeys.sort()
+    for type in ckeys:
+        print type
+        entries = caps[type]
+        for e in entries:
+            keys = e.keys()
+            keys.sort()
+            for k in keys:
+                print "  %-15s" % k, e[k]
+            print
+
+if __name__ == '__main__':
+    test()

Added: vendor/Python/current/Lib/markupbase.py
===================================================================
--- vendor/Python/current/Lib/markupbase.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/markupbase.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,392 @@
+"""Shared support for scanning document type declarations in HTML and XHTML.
+
+This module is used as a foundation for the HTMLParser and sgmllib
+modules (indirectly, for htmllib as well).  It has no documented
+public API and should not be used directly.
+
+"""
+
+import re
+
+_declname_match = re.compile(r'[a-zA-Z][-_.a-zA-Z0-9]*\s*').match
+_declstringlit_match = re.compile(r'(\'[^\']*\'|"[^"]*")\s*').match
+_commentclose = re.compile(r'--\s*>')
+_markedsectionclose = re.compile(r']\s*]\s*>')
+
+# An analysis of the MS-Word extensions is available at
+# http://www.planetpublish.com/xmlarena/xap/Thursday/WordtoXML.pdf
+
+_msmarkedsectionclose = re.compile(r']\s*>')
+
+del re
+
+
+class ParserBase:
+    """Parser base class which provides some common support methods used
+    by the SGML/HTML and XHTML parsers."""
+
+    def __init__(self):
+        if self.__class__ is ParserBase:
+            raise RuntimeError(
+                "markupbase.ParserBase must be subclassed")
+
+    def error(self, message):
+        raise NotImplementedError(
+            "subclasses of ParserBase must override error()")
+
+    def reset(self):
+        self.lineno = 1
+        self.offset = 0
+
+    def getpos(self):
+        """Return current line number and offset."""
+        return self.lineno, self.offset
+
+    # Internal -- update line number and offset.  This should be
+    # called for each piece of data exactly once, in order -- in other
+    # words the concatenation of all the input strings to this
+    # function should be exactly the entire input.
+    def updatepos(self, i, j):
+        if i >= j:
+            return j
+        rawdata = self.rawdata
+        nlines = rawdata.count("\n", i, j)
+        if nlines:
+            self.lineno = self.lineno + nlines
+            pos = rawdata.rindex("\n", i, j) # Should not fail
+            self.offset = j-(pos+1)
+        else:
+            self.offset = self.offset + j-i
+        return j
+
+    _decl_otherchars = ''
+
+    # Internal -- parse declaration (for use by subclasses).
+    def parse_declaration(self, i):
+        # This is some sort of declaration; in "HTML as
+        # deployed," this should only be the document type
+        # declaration ("<!DOCTYPE html...>").
+        # ISO 8879:1986, however, has more complex
+        # declaration syntax for elements in <!...>, including:
+        # --comment--
+        # [marked section]
+        # name in the following list: ENTITY, DOCTYPE, ELEMENT,
+        # ATTLIST, NOTATION, SHORTREF, USEMAP,
+        # LINKTYPE, LINK, IDLINK, USELINK, SYSTEM
+        rawdata = self.rawdata
+        j = i + 2
+        assert rawdata[i:j] == "<!", "unexpected call to parse_declaration"
+        if rawdata[j:j+1] == ">":
+            # the empty comment <!>
+            return j + 1
+        if rawdata[j:j+1] in ("-", ""):
+            # Start of comment followed by buffer boundary,
+            # or just a buffer boundary.
+            return -1
+        # A simple, practical version could look like: ((name|stringlit) S*) + '>'
+        n = len(rawdata)
+        if rawdata[j:j+2] == '--': #comment
+            # Locate --.*-- as the body of the comment
+            return self.parse_comment(i)
+        elif rawdata[j] == '[': #marked section
+            # Locate [statusWord [...arbitrary SGML...]] as the body of the marked section
+            # Where statusWord is one of TEMP, CDATA, IGNORE, INCLUDE, RCDATA
+            # Note that this is extended by Microsoft Office "Save as Web" function
+            # to include [if...] and [endif].
+            return self.parse_marked_section(i)
+        else: #all other declaration elements
+            decltype, j = self._scan_name(j, i)
+        if j < 0:
+            return j
+        if decltype == "doctype":
+            self._decl_otherchars = ''
+        while j < n:
+            c = rawdata[j]
+            if c == ">":
+                # end of declaration syntax
+                data = rawdata[i+2:j]
+                if decltype == "doctype":
+                    self.handle_decl(data)
+                else:
+                    self.unknown_decl(data)
+                return j + 1
+            if c in "\"'":
+                m = _declstringlit_match(rawdata, j)
+                if not m:
+                    return -1 # incomplete
+                j = m.end()
+            elif c in "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ":
+                name, j = self._scan_name(j, i)
+            elif c in self._decl_otherchars:
+                j = j + 1
+            elif c == "[":
+                # this could be handled in a separate doctype parser
+                if decltype == "doctype":
+                    j = self._parse_doctype_subset(j + 1, i)
+                elif decltype in ("attlist", "linktype", "link", "element"):
+                    # must tolerate []'d groups in a content model in an element declaration
+                    # also in data attribute specifications of attlist declaration
+                    # also link type declaration subsets in linktype declarations
+                    # also link attribute specification lists in link declarations
+                    self.error("unsupported '[' char in %s declaration" % decltype)
+                else:
+                    self.error("unexpected '[' char in declaration")
+            else:
+                self.error(
+                    "unexpected %r char in declaration" % rawdata[j])
+            if j < 0:
+                return j
+        return -1 # incomplete
+
+    # Internal -- parse a marked section
+    # Override this to handle MS-word extension syntax <![if word]>content<![endif]>
+    def parse_marked_section(self, i, report=1):
+        rawdata= self.rawdata
+        assert rawdata[i:i+3] == '<![', "unexpected call to parse_marked_section()"
+        sectName, j = self._scan_name( i+3, i )
+        if j < 0:
+            return j
+        if sectName in ("temp", "cdata", "ignore", "include", "rcdata"):
+            # look for standard ]]> ending
+            match= _markedsectionclose.search(rawdata, i+3)
+        elif sectName in ("if", "else", "endif"):
+            # look for MS Office ]> ending
+            match= _msmarkedsectionclose.search(rawdata, i+3)
+        else:
+            self.error('unknown status keyword %r in marked section' % rawdata[i+3:j])
+        if not match:
+            return -1
+        if report:
+            j = match.start(0)
+            self.unknown_decl(rawdata[i+3: j])
+        return match.end(0)
+
+    # Internal -- parse comment, return length or -1 if not terminated
+    def parse_comment(self, i, report=1):
+        rawdata = self.rawdata
+        if rawdata[i:i+4] != '<!--':
+            self.error('unexpected call to parse_comment()')
+        match = _commentclose.search(rawdata, i+4)
+        if not match:
+            return -1
+        if report:
+            j = match.start(0)
+            self.handle_comment(rawdata[i+4: j])
+        return match.end(0)
+
+    # Internal -- scan past the internal subset in a <!DOCTYPE declaration,
+    # returning the index just past any whitespace following the trailing ']'.
+    def _parse_doctype_subset(self, i, declstartpos):
+        rawdata = self.rawdata
+        n = len(rawdata)
+        j = i
+        while j < n:
+            c = rawdata[j]
+            if c == "<":
+                s = rawdata[j:j+2]
+                if s == "<":
+                    # end of buffer; incomplete
+                    return -1
+                if s != "<!":
+                    self.updatepos(declstartpos, j + 1)
+                    self.error("unexpected char in internal subset (in %r)" % s)
+                if (j + 2) == n:
+                    # end of buffer; incomplete
+                    return -1
+                if (j + 4) > n:
+                    # end of buffer; incomplete
+                    return -1
+                if rawdata[j:j+4] == "<!--":
+                    j = self.parse_comment(j, report=0)
+                    if j < 0:
+                        return j
+                    continue
+                name, j = self._scan_name(j + 2, declstartpos)
+                if j == -1:
+                    return -1
+                if name not in ("attlist", "element", "entity", "notation"):
+                    self.updatepos(declstartpos, j + 2)
+                    self.error(
+                        "unknown declaration %r in internal subset" % name)
+                # handle the individual names
+                meth = getattr(self, "_parse_doctype_" + name)
+                j = meth(j, declstartpos)
+                if j < 0:
+                    return j
+            elif c == "%":
+                # parameter entity reference
+                if (j + 1) == n:
+                    # end of buffer; incomplete
+                    return -1
+                s, j = self._scan_name(j + 1, declstartpos)
+                if j < 0:
+                    return j
+                if rawdata[j] == ";":
+                    j = j + 1
+            elif c == "]":
+                j = j + 1
+                while j < n and rawdata[j].isspace():
+                    j = j + 1
+                if j < n:
+                    if rawdata[j] == ">":
+                        return j
+                    self.updatepos(declstartpos, j)
+                    self.error("unexpected char after internal subset")
+                else:
+                    return -1
+            elif c.isspace():
+                j = j + 1
+            else:
+                self.updatepos(declstartpos, j)
+                self.error("unexpected char %r in internal subset" % c)
+        # end of buffer reached
+        return -1
+
+    # Internal -- scan past <!ELEMENT declarations
+    def _parse_doctype_element(self, i, declstartpos):
+        name, j = self._scan_name(i, declstartpos)
+        if j == -1:
+            return -1
+        # style content model; just skip until '>'
+        rawdata = self.rawdata
+        if '>' in rawdata[j:]:
+            return rawdata.find(">", j) + 1
+        return -1
+
+    # Internal -- scan past <!ATTLIST declarations
+    def _parse_doctype_attlist(self, i, declstartpos):
+        rawdata = self.rawdata
+        name, j = self._scan_name(i, declstartpos)
+        c = rawdata[j:j+1]
+        if c == "":
+            return -1
+        if c == ">":
+            return j + 1
+        while 1:
+            # scan a series of attribute descriptions; simplified:
+            #   name type [value] [#constraint]
+            name, j = self._scan_name(j, declstartpos)
+            if j < 0:
+                return j
+            c = rawdata[j:j+1]
+            if c == "":
+                return -1
+            if c == "(":
+                # an enumerated type; look for ')'
+                if ")" in rawdata[j:]:
+                    j = rawdata.find(")", j) + 1
+                else:
+                    return -1
+                while rawdata[j:j+1].isspace():
+                    j = j + 1
+                if not rawdata[j:]:
+                    # end of buffer, incomplete
+                    return -1
+            else:
+                name, j = self._scan_name(j, declstartpos)
+            c = rawdata[j:j+1]
+            if not c:
+                return -1
+            if c in "'\"":
+                m = _declstringlit_match(rawdata, j)
+                if m:
+                    j = m.end()
+                else:
+                    return -1
+                c = rawdata[j:j+1]
+                if not c:
+                    return -1
+            if c == "#":
+                if rawdata[j:] == "#":
+                    # end of buffer
+                    return -1
+                name, j = self._scan_name(j + 1, declstartpos)
+                if j < 0:
+                    return j
+                c = rawdata[j:j+1]
+                if not c:
+                    return -1
+            if c == '>':
+                # all done
+                return j + 1
+
+    # Internal -- scan past <!NOTATION declarations
+    def _parse_doctype_notation(self, i, declstartpos):
+        name, j = self._scan_name(i, declstartpos)
+        if j < 0:
+            return j
+        rawdata = self.rawdata
+        while 1:
+            c = rawdata[j:j+1]
+            if not c:
+                # end of buffer; incomplete
+                return -1
+            if c == '>':
+                return j + 1
+            if c in "'\"":
+                m = _declstringlit_match(rawdata, j)
+                if not m:
+                    return -1
+                j = m.end()
+            else:
+                name, j = self._scan_name(j, declstartpos)
+                if j < 0:
+                    return j
+
+    # Internal -- scan past <!ENTITY declarations
+    def _parse_doctype_entity(self, i, declstartpos):
+        rawdata = self.rawdata
+        if rawdata[i:i+1] == "%":
+            j = i + 1
+            while 1:
+                c = rawdata[j:j+1]
+                if not c:
+                    return -1
+                if c.isspace():
+                    j = j + 1
+                else:
+                    break
+        else:
+            j = i
+        name, j = self._scan_name(j, declstartpos)
+        if j < 0:
+            return j
+        while 1:
+            c = self.rawdata[j:j+1]
+            if not c:
+                return -1
+            if c in "'\"":
+                m = _declstringlit_match(rawdata, j)
+                if m:
+                    j = m.end()
+                else:
+                    return -1    # incomplete
+            elif c == ">":
+                return j + 1
+            else:
+                name, j = self._scan_name(j, declstartpos)
+                if j < 0:
+                    return j
+
+    # Internal -- scan a name token and the new position and the token, or
+    # return -1 if we've reached the end of the buffer.
+    def _scan_name(self, i, declstartpos):
+        rawdata = self.rawdata
+        n = len(rawdata)
+        if i == n:
+            return None, -1
+        m = _declname_match(rawdata, i)
+        if m:
+            s = m.group()
+            name = s.strip()
+            if (i + len(s)) == n:
+                return None, -1  # end of buffer
+            return name.lower(), m.end()
+        else:
+            self.updatepos(declstartpos, i)
+            self.error("expected name token at %r"
+                       % rawdata[declstartpos:declstartpos+20])
+
+    # To be overridden -- handlers for unknown objects
+    def unknown_decl(self, data):
+        pass

Added: vendor/Python/current/Lib/md5.py
===================================================================
--- vendor/Python/current/Lib/md5.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/md5.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,10 @@
+# $Id: md5.py 39316 2005-08-21 18:45:59Z greg $
+#
+#  Copyright (C) 2005   Gregory P. Smith (greg at electricrain.com)
+#  Licensed to PSF under a Contributor Agreement.
+
+from hashlib import md5
+new = md5
+
+blocksize = 1        # legacy value (wrong in any useful sense)
+digest_size = 16

Added: vendor/Python/current/Lib/mhlib.py
===================================================================
--- vendor/Python/current/Lib/mhlib.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/mhlib.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1001 @@
+"""MH interface -- purely object-oriented (well, almost)
+
+Executive summary:
+
+import mhlib
+
+mh = mhlib.MH()         # use default mailbox directory and profile
+mh = mhlib.MH(mailbox)  # override mailbox location (default from profile)
+mh = mhlib.MH(mailbox, profile) # override mailbox and profile
+
+mh.error(format, ...)   # print error message -- can be overridden
+s = mh.getprofile(key)  # profile entry (None if not set)
+path = mh.getpath()     # mailbox pathname
+name = mh.getcontext()  # name of current folder
+mh.setcontext(name)     # set name of current folder
+
+list = mh.listfolders() # names of top-level folders
+list = mh.listallfolders() # names of all folders, including subfolders
+list = mh.listsubfolders(name) # direct subfolders of given folder
+list = mh.listallsubfolders(name) # all subfolders of given folder
+
+mh.makefolder(name)     # create new folder
+mh.deletefolder(name)   # delete folder -- must have no subfolders
+
+f = mh.openfolder(name) # new open folder object
+
+f.error(format, ...)    # same as mh.error(format, ...)
+path = f.getfullname()  # folder's full pathname
+path = f.getsequencesfilename() # full pathname of folder's sequences file
+path = f.getmessagefilename(n)  # full pathname of message n in folder
+
+list = f.listmessages() # list of messages in folder (as numbers)
+n = f.getcurrent()      # get current message
+f.setcurrent(n)         # set current message
+list = f.parsesequence(seq)     # parse msgs syntax into list of messages
+n = f.getlast()         # get last message (0 if no messagse)
+f.setlast(n)            # set last message (internal use only)
+
+dict = f.getsequences() # dictionary of sequences in folder {name: list}
+f.putsequences(dict)    # write sequences back to folder
+
+f.createmessage(n, fp)  # add message from file f as number n
+f.removemessages(list)  # remove messages in list from folder
+f.refilemessages(list, tofolder) # move messages in list to other folder
+f.movemessage(n, tofolder, ton)  # move one message to a given destination
+f.copymessage(n, tofolder, ton)  # copy one message to a given destination
+
+m = f.openmessage(n)    # new open message object (costs a file descriptor)
+m is a derived class of mimetools.Message(rfc822.Message), with:
+s = m.getheadertext()   # text of message's headers
+s = m.getheadertext(pred) # text of message's headers, filtered by pred
+s = m.getbodytext()     # text of message's body, decoded
+s = m.getbodytext(0)    # text of message's body, not decoded
+"""
+
+# XXX To do, functionality:
+# - annotate messages
+# - send messages
+#
+# XXX To do, organization:
+# - move IntSet to separate file
+# - move most Message functionality to module mimetools
+
+
+# Customizable defaults
+
+MH_PROFILE = '~/.mh_profile'
+PATH = '~/Mail'
+MH_SEQUENCES = '.mh_sequences'
+FOLDER_PROTECT = 0700
+
+
+# Imported modules
+
+import os
+import sys
+import re
+import mimetools
+import multifile
+import shutil
+from bisect import bisect
+
+__all__ = ["MH","Error","Folder","Message"]
+
+# Exported constants
+
+class Error(Exception):
+    pass
+
+
+class MH:
+    """Class representing a particular collection of folders.
+    Optional constructor arguments are the pathname for the directory
+    containing the collection, and the MH profile to use.
+    If either is omitted or empty a default is used; the default
+    directory is taken from the MH profile if it is specified there."""
+
+    def __init__(self, path = None, profile = None):
+        """Constructor."""
+        if profile is None: profile = MH_PROFILE
+        self.profile = os.path.expanduser(profile)
+        if path is None: path = self.getprofile('Path')
+        if not path: path = PATH
+        if not os.path.isabs(path) and path[0] != '~':
+            path = os.path.join('~', path)
+        path = os.path.expanduser(path)
+        if not os.path.isdir(path): raise Error, 'MH() path not found'
+        self.path = path
+
+    def __repr__(self):
+        """String representation."""
+        return 'MH(%r, %r)' % (self.path, self.profile)
+
+    def error(self, msg, *args):
+        """Routine to print an error.  May be overridden by a derived class."""
+        sys.stderr.write('MH error: %s\n' % (msg % args))
+
+    def getprofile(self, key):
+        """Return a profile entry, None if not found."""
+        return pickline(self.profile, key)
+
+    def getpath(self):
+        """Return the path (the name of the collection's directory)."""
+        return self.path
+
+    def getcontext(self):
+        """Return the name of the current folder."""
+        context = pickline(os.path.join(self.getpath(), 'context'),
+                  'Current-Folder')
+        if not context: context = 'inbox'
+        return context
+
+    def setcontext(self, context):
+        """Set the name of the current folder."""
+        fn = os.path.join(self.getpath(), 'context')
+        f = open(fn, "w")
+        f.write("Current-Folder: %s\n" % context)
+        f.close()
+
+    def listfolders(self):
+        """Return the names of the top-level folders."""
+        folders = []
+        path = self.getpath()
+        for name in os.listdir(path):
+            fullname = os.path.join(path, name)
+            if os.path.isdir(fullname):
+                folders.append(name)
+        folders.sort()
+        return folders
+
+    def listsubfolders(self, name):
+        """Return the names of the subfolders in a given folder
+        (prefixed with the given folder name)."""
+        fullname = os.path.join(self.path, name)
+        # Get the link count so we can avoid listing folders
+        # that have no subfolders.
+        nlinks = os.stat(fullname).st_nlink
+        if nlinks <= 2:
+            return []
+        subfolders = []
+        subnames = os.listdir(fullname)
+        for subname in subnames:
+            fullsubname = os.path.join(fullname, subname)
+            if os.path.isdir(fullsubname):
+                name_subname = os.path.join(name, subname)
+                subfolders.append(name_subname)
+                # Stop looking for subfolders when
+                # we've seen them all
+                nlinks = nlinks - 1
+                if nlinks <= 2:
+                    break
+        subfolders.sort()
+        return subfolders
+
+    def listallfolders(self):
+        """Return the names of all folders and subfolders, recursively."""
+        return self.listallsubfolders('')
+
+    def listallsubfolders(self, name):
+        """Return the names of subfolders in a given folder, recursively."""
+        fullname = os.path.join(self.path, name)
+        # Get the link count so we can avoid listing folders
+        # that have no subfolders.
+        nlinks = os.stat(fullname).st_nlink
+        if nlinks <= 2:
+            return []
+        subfolders = []
+        subnames = os.listdir(fullname)
+        for subname in subnames:
+            if subname[0] == ',' or isnumeric(subname): continue
+            fullsubname = os.path.join(fullname, subname)
+            if os.path.isdir(fullsubname):
+                name_subname = os.path.join(name, subname)
+                subfolders.append(name_subname)
+                if not os.path.islink(fullsubname):
+                    subsubfolders = self.listallsubfolders(
+                              name_subname)
+                    subfolders = subfolders + subsubfolders
+                # Stop looking for subfolders when
+                # we've seen them all
+                nlinks = nlinks - 1
+                if nlinks <= 2:
+                    break
+        subfolders.sort()
+        return subfolders
+
+    def openfolder(self, name):
+        """Return a new Folder object for the named folder."""
+        return Folder(self, name)
+
+    def makefolder(self, name):
+        """Create a new folder (or raise os.error if it cannot be created)."""
+        protect = pickline(self.profile, 'Folder-Protect')
+        if protect and isnumeric(protect):
+            mode = int(protect, 8)
+        else:
+            mode = FOLDER_PROTECT
+        os.mkdir(os.path.join(self.getpath(), name), mode)
+
+    def deletefolder(self, name):
+        """Delete a folder.  This removes files in the folder but not
+        subdirectories.  Raise os.error if deleting the folder itself fails."""
+        fullname = os.path.join(self.getpath(), name)
+        for subname in os.listdir(fullname):
+            fullsubname = os.path.join(fullname, subname)
+            try:
+                os.unlink(fullsubname)
+            except os.error:
+                self.error('%s not deleted, continuing...' %
+                          fullsubname)
+        os.rmdir(fullname)
+
+
+numericprog = re.compile('^[1-9][0-9]*$')
+def isnumeric(str):
+    return numericprog.match(str) is not None
+
+class Folder:
+    """Class representing a particular folder."""
+
+    def __init__(self, mh, name):
+        """Constructor."""
+        self.mh = mh
+        self.name = name
+        if not os.path.isdir(self.getfullname()):
+            raise Error, 'no folder %s' % name
+
+    def __repr__(self):
+        """String representation."""
+        return 'Folder(%r, %r)' % (self.mh, self.name)
+
+    def error(self, *args):
+        """Error message handler."""
+        self.mh.error(*args)
+
+    def getfullname(self):
+        """Return the full pathname of the folder."""
+        return os.path.join(self.mh.path, self.name)
+
+    def getsequencesfilename(self):
+        """Return the full pathname of the folder's sequences file."""
+        return os.path.join(self.getfullname(), MH_SEQUENCES)
+
+    def getmessagefilename(self, n):
+        """Return the full pathname of a message in the folder."""
+        return os.path.join(self.getfullname(), str(n))
+
+    def listsubfolders(self):
+        """Return list of direct subfolders."""
+        return self.mh.listsubfolders(self.name)
+
+    def listallsubfolders(self):
+        """Return list of all subfolders."""
+        return self.mh.listallsubfolders(self.name)
+
+    def listmessages(self):
+        """Return the list of messages currently present in the folder.
+        As a side effect, set self.last to the last message (or 0)."""
+        messages = []
+        match = numericprog.match
+        append = messages.append
+        for name in os.listdir(self.getfullname()):
+            if match(name):
+                append(name)
+        messages = map(int, messages)
+        messages.sort()
+        if messages:
+            self.last = messages[-1]
+        else:
+            self.last = 0
+        return messages
+
+    def getsequences(self):
+        """Return the set of sequences for the folder."""
+        sequences = {}
+        fullname = self.getsequencesfilename()
+        try:
+            f = open(fullname, 'r')
+        except IOError:
+            return sequences
+        while 1:
+            line = f.readline()
+            if not line: break
+            fields = line.split(':')
+            if len(fields) != 2:
+                self.error('bad sequence in %s: %s' %
+                          (fullname, line.strip()))
+            key = fields[0].strip()
+            value = IntSet(fields[1].strip(), ' ').tolist()
+            sequences[key] = value
+        return sequences
+
+    def putsequences(self, sequences):
+        """Write the set of sequences back to the folder."""
+        fullname = self.getsequencesfilename()
+        f = None
+        for key, seq in sequences.iteritems():
+            s = IntSet('', ' ')
+            s.fromlist(seq)
+            if not f: f = open(fullname, 'w')
+            f.write('%s: %s\n' % (key, s.tostring()))
+        if not f:
+            try:
+                os.unlink(fullname)
+            except os.error:
+                pass
+        else:
+            f.close()
+
+    def getcurrent(self):
+        """Return the current message.  Raise Error when there is none."""
+        seqs = self.getsequences()
+        try:
+            return max(seqs['cur'])
+        except (ValueError, KeyError):
+            raise Error, "no cur message"
+
+    def setcurrent(self, n):
+        """Set the current message."""
+        updateline(self.getsequencesfilename(), 'cur', str(n), 0)
+
+    def parsesequence(self, seq):
+        """Parse an MH sequence specification into a message list.
+        Attempt to mimic mh-sequence(5) as close as possible.
+        Also attempt to mimic observed behavior regarding which
+        conditions cause which error messages."""
+        # XXX Still not complete (see mh-format(5)).
+        # Missing are:
+        # - 'prev', 'next' as count
+        # - Sequence-Negation option
+        all = self.listmessages()
+        # Observed behavior: test for empty folder is done first
+        if not all:
+            raise Error, "no messages in %s" % self.name
+        # Common case first: all is frequently the default
+        if seq == 'all':
+            return all
+        # Test for X:Y before X-Y because 'seq:-n' matches both
+        i = seq.find(':')
+        if i >= 0:
+            head, dir, tail = seq[:i], '', seq[i+1:]
+            if tail[:1] in '-+':
+                dir, tail = tail[:1], tail[1:]
+            if not isnumeric(tail):
+                raise Error, "bad message list %s" % seq
+            try:
+                count = int(tail)
+            except (ValueError, OverflowError):
+                # Can't use sys.maxint because of i+count below
+                count = len(all)
+            try:
+                anchor = self._parseindex(head, all)
+            except Error, msg:
+                seqs = self.getsequences()
+                if not head in seqs:
+                    if not msg:
+                        msg = "bad message list %s" % seq
+                    raise Error, msg, sys.exc_info()[2]
+                msgs = seqs[head]
+                if not msgs:
+                    raise Error, "sequence %s empty" % head
+                if dir == '-':
+                    return msgs[-count:]
+                else:
+                    return msgs[:count]
+            else:
+                if not dir:
+                    if head in ('prev', 'last'):
+                        dir = '-'
+                if dir == '-':
+                    i = bisect(all, anchor)
+                    return all[max(0, i-count):i]
+                else:
+                    i = bisect(all, anchor-1)
+                    return all[i:i+count]
+        # Test for X-Y next
+        i = seq.find('-')
+        if i >= 0:
+            begin = self._parseindex(seq[:i], all)
+            end = self._parseindex(seq[i+1:], all)
+            i = bisect(all, begin-1)
+            j = bisect(all, end)
+            r = all[i:j]
+            if not r:
+                raise Error, "bad message list %s" % seq
+            return r
+        # Neither X:Y nor X-Y; must be a number or a (pseudo-)sequence
+        try:
+            n = self._parseindex(seq, all)
+        except Error, msg:
+            seqs = self.getsequences()
+            if not seq in seqs:
+                if not msg:
+                    msg = "bad message list %s" % seq
+                raise Error, msg
+            return seqs[seq]
+        else:
+            if n not in all:
+                if isnumeric(seq):
+                    raise Error, "message %d doesn't exist" % n
+                else:
+                    raise Error, "no %s message" % seq
+            else:
+                return [n]
+
+    def _parseindex(self, seq, all):
+        """Internal: parse a message number (or cur, first, etc.)."""
+        if isnumeric(seq):
+            try:
+                return int(seq)
+            except (OverflowError, ValueError):
+                return sys.maxint
+        if seq in ('cur', '.'):
+            return self.getcurrent()
+        if seq == 'first':
+            return all[0]
+        if seq == 'last':
+            return all[-1]
+        if seq == 'next':
+            n = self.getcurrent()
+            i = bisect(all, n)
+            try:
+                return all[i]
+            except IndexError:
+                raise Error, "no next message"
+        if seq == 'prev':
+            n = self.getcurrent()
+            i = bisect(all, n-1)
+            if i == 0:
+                raise Error, "no prev message"
+            try:
+                return all[i-1]
+            except IndexError:
+                raise Error, "no prev message"
+        raise Error, None
+
+    def openmessage(self, n):
+        """Open a message -- returns a Message object."""
+        return Message(self, n)
+
+    def removemessages(self, list):
+        """Remove one or more messages -- may raise os.error."""
+        errors = []
+        deleted = []
+        for n in list:
+            path = self.getmessagefilename(n)
+            commapath = self.getmessagefilename(',' + str(n))
+            try:
+                os.unlink(commapath)
+            except os.error:
+                pass
+            try:
+                os.rename(path, commapath)
+            except os.error, msg:
+                errors.append(msg)
+            else:
+                deleted.append(n)
+        if deleted:
+            self.removefromallsequences(deleted)
+        if errors:
+            if len(errors) == 1:
+                raise os.error, errors[0]
+            else:
+                raise os.error, ('multiple errors:', errors)
+
+    def refilemessages(self, list, tofolder, keepsequences=0):
+        """Refile one or more messages -- may raise os.error.
+        'tofolder' is an open folder object."""
+        errors = []
+        refiled = {}
+        for n in list:
+            ton = tofolder.getlast() + 1
+            path = self.getmessagefilename(n)
+            topath = tofolder.getmessagefilename(ton)
+            try:
+                os.rename(path, topath)
+            except os.error:
+                # Try copying
+                try:
+                    shutil.copy2(path, topath)
+                    os.unlink(path)
+                except (IOError, os.error), msg:
+                    errors.append(msg)
+                    try:
+                        os.unlink(topath)
+                    except os.error:
+                        pass
+                    continue
+            tofolder.setlast(ton)
+            refiled[n] = ton
+        if refiled:
+            if keepsequences:
+                tofolder._copysequences(self, refiled.items())
+            self.removefromallsequences(refiled.keys())
+        if errors:
+            if len(errors) == 1:
+                raise os.error, errors[0]
+            else:
+                raise os.error, ('multiple errors:', errors)
+
+    def _copysequences(self, fromfolder, refileditems):
+        """Helper for refilemessages() to copy sequences."""
+        fromsequences = fromfolder.getsequences()
+        tosequences = self.getsequences()
+        changed = 0
+        for name, seq in fromsequences.items():
+            try:
+                toseq = tosequences[name]
+                new = 0
+            except KeyError:
+                toseq = []
+                new = 1
+            for fromn, ton in refileditems:
+                if fromn in seq:
+                    toseq.append(ton)
+                    changed = 1
+            if new and toseq:
+                tosequences[name] = toseq
+        if changed:
+            self.putsequences(tosequences)
+
+    def movemessage(self, n, tofolder, ton):
+        """Move one message over a specific destination message,
+        which may or may not already exist."""
+        path = self.getmessagefilename(n)
+        # Open it to check that it exists
+        f = open(path)
+        f.close()
+        del f
+        topath = tofolder.getmessagefilename(ton)
+        backuptopath = tofolder.getmessagefilename(',%d' % ton)
+        try:
+            os.rename(topath, backuptopath)
+        except os.error:
+            pass
+        try:
+            os.rename(path, topath)
+        except os.error:
+            # Try copying
+            ok = 0
+            try:
+                tofolder.setlast(None)
+                shutil.copy2(path, topath)
+                ok = 1
+            finally:
+                if not ok:
+                    try:
+                        os.unlink(topath)
+                    except os.error:
+                        pass
+            os.unlink(path)
+        self.removefromallsequences([n])
+
+    def copymessage(self, n, tofolder, ton):
+        """Copy one message over a specific destination message,
+        which may or may not already exist."""
+        path = self.getmessagefilename(n)
+        # Open it to check that it exists
+        f = open(path)
+        f.close()
+        del f
+        topath = tofolder.getmessagefilename(ton)
+        backuptopath = tofolder.getmessagefilename(',%d' % ton)
+        try:
+            os.rename(topath, backuptopath)
+        except os.error:
+            pass
+        ok = 0
+        try:
+            tofolder.setlast(None)
+            shutil.copy2(path, topath)
+            ok = 1
+        finally:
+            if not ok:
+                try:
+                    os.unlink(topath)
+                except os.error:
+                    pass
+
+    def createmessage(self, n, txt):
+        """Create a message, with text from the open file txt."""
+        path = self.getmessagefilename(n)
+        backuppath = self.getmessagefilename(',%d' % n)
+        try:
+            os.rename(path, backuppath)
+        except os.error:
+            pass
+        ok = 0
+        BUFSIZE = 16*1024
+        try:
+            f = open(path, "w")
+            while 1:
+                buf = txt.read(BUFSIZE)
+                if not buf:
+                    break
+                f.write(buf)
+            f.close()
+            ok = 1
+        finally:
+            if not ok:
+                try:
+                    os.unlink(path)
+                except os.error:
+                    pass
+
+    def removefromallsequences(self, list):
+        """Remove one or more messages from all sequences (including last)
+        -- but not from 'cur'!!!"""
+        if hasattr(self, 'last') and self.last in list:
+            del self.last
+        sequences = self.getsequences()
+        changed = 0
+        for name, seq in sequences.items():
+            if name == 'cur':
+                continue
+            for n in list:
+                if n in seq:
+                    seq.remove(n)
+                    changed = 1
+                    if not seq:
+                        del sequences[name]
+        if changed:
+            self.putsequences(sequences)
+
+    def getlast(self):
+        """Return the last message number."""
+        if not hasattr(self, 'last'):
+            self.listmessages() # Set self.last
+        return self.last
+
+    def setlast(self, last):
+        """Set the last message number."""
+        if last is None:
+            if hasattr(self, 'last'):
+                del self.last
+        else:
+            self.last = last
+
+class Message(mimetools.Message):
+
+    def __init__(self, f, n, fp = None):
+        """Constructor."""
+        self.folder = f
+        self.number = n
+        if fp is None:
+            path = f.getmessagefilename(n)
+            fp = open(path, 'r')
+        mimetools.Message.__init__(self, fp)
+
+    def __repr__(self):
+        """String representation."""
+        return 'Message(%s, %s)' % (repr(self.folder), self.number)
+
+    def getheadertext(self, pred = None):
+        """Return the message's header text as a string.  If an
+        argument is specified, it is used as a filter predicate to
+        decide which headers to return (its argument is the header
+        name converted to lower case)."""
+        if pred is None:
+            return ''.join(self.headers)
+        headers = []
+        hit = 0
+        for line in self.headers:
+            if not line[0].isspace():
+                i = line.find(':')
+                if i > 0:
+                    hit = pred(line[:i].lower())
+            if hit: headers.append(line)
+        return ''.join(headers)
+
+    def getbodytext(self, decode = 1):
+        """Return the message's body text as string.  This undoes a
+        Content-Transfer-Encoding, but does not interpret other MIME
+        features (e.g. multipart messages).  To suppress decoding,
+        pass 0 as an argument."""
+        self.fp.seek(self.startofbody)
+        encoding = self.getencoding()
+        if not decode or encoding in ('', '7bit', '8bit', 'binary'):
+            return self.fp.read()
+        try:
+            from cStringIO import StringIO
+        except ImportError:
+            from StringIO import StringIO
+        output = StringIO()
+        mimetools.decode(self.fp, output, encoding)
+        return output.getvalue()
+
+    def getbodyparts(self):
+        """Only for multipart messages: return the message's body as a
+        list of SubMessage objects.  Each submessage object behaves
+        (almost) as a Message object."""
+        if self.getmaintype() != 'multipart':
+            raise Error, 'Content-Type is not multipart/*'
+        bdry = self.getparam('boundary')
+        if not bdry:
+            raise Error, 'multipart/* without boundary param'
+        self.fp.seek(self.startofbody)
+        mf = multifile.MultiFile(self.fp)
+        mf.push(bdry)
+        parts = []
+        while mf.next():
+            n = "%s.%r" % (self.number, 1 + len(parts))
+            part = SubMessage(self.folder, n, mf)
+            parts.append(part)
+        mf.pop()
+        return parts
+
+    def getbody(self):
+        """Return body, either a string or a list of messages."""
+        if self.getmaintype() == 'multipart':
+            return self.getbodyparts()
+        else:
+            return self.getbodytext()
+
+
+class SubMessage(Message):
+
+    def __init__(self, f, n, fp):
+        """Constructor."""
+        Message.__init__(self, f, n, fp)
+        if self.getmaintype() == 'multipart':
+            self.body = Message.getbodyparts(self)
+        else:
+            self.body = Message.getbodytext(self)
+        self.bodyencoded = Message.getbodytext(self, decode=0)
+            # XXX If this is big, should remember file pointers
+
+    def __repr__(self):
+        """String representation."""
+        f, n, fp = self.folder, self.number, self.fp
+        return 'SubMessage(%s, %s, %s)' % (f, n, fp)
+
+    def getbodytext(self, decode = 1):
+        if not decode:
+            return self.bodyencoded
+        if type(self.body) == type(''):
+            return self.body
+
+    def getbodyparts(self):
+        if type(self.body) == type([]):
+            return self.body
+
+    def getbody(self):
+        return self.body
+
+
+class IntSet:
+    """Class implementing sets of integers.
+
+    This is an efficient representation for sets consisting of several
+    continuous ranges, e.g. 1-100,200-400,402-1000 is represented
+    internally as a list of three pairs: [(1,100), (200,400),
+    (402,1000)].  The internal representation is always kept normalized.
+
+    The constructor has up to three arguments:
+    - the string used to initialize the set (default ''),
+    - the separator between ranges (default ',')
+    - the separator between begin and end of a range (default '-')
+    The separators must be strings (not regexprs) and should be different.
+
+    The tostring() function yields a string that can be passed to another
+    IntSet constructor; __repr__() is a valid IntSet constructor itself.
+    """
+
+    # XXX The default begin/end separator means that negative numbers are
+    #     not supported very well.
+    #
+    # XXX There are currently no operations to remove set elements.
+
+    def __init__(self, data = None, sep = ',', rng = '-'):
+        self.pairs = []
+        self.sep = sep
+        self.rng = rng
+        if data: self.fromstring(data)
+
+    def reset(self):
+        self.pairs = []
+
+    def __cmp__(self, other):
+        return cmp(self.pairs, other.pairs)
+
+    def __hash__(self):
+        return hash(self.pairs)
+
+    def __repr__(self):
+        return 'IntSet(%r, %r, %r)' % (self.tostring(), self.sep, self.rng)
+
+    def normalize(self):
+        self.pairs.sort()
+        i = 1
+        while i < len(self.pairs):
+            alo, ahi = self.pairs[i-1]
+            blo, bhi = self.pairs[i]
+            if ahi >= blo-1:
+                self.pairs[i-1:i+1] = [(alo, max(ahi, bhi))]
+            else:
+                i = i+1
+
+    def tostring(self):
+        s = ''
+        for lo, hi in self.pairs:
+            if lo == hi: t = repr(lo)
+            else: t = repr(lo) + self.rng + repr(hi)
+            if s: s = s + (self.sep + t)
+            else: s = t
+        return s
+
+    def tolist(self):
+        l = []
+        for lo, hi in self.pairs:
+            m = range(lo, hi+1)
+            l = l + m
+        return l
+
+    def fromlist(self, list):
+        for i in list:
+            self.append(i)
+
+    def clone(self):
+        new = IntSet()
+        new.pairs = self.pairs[:]
+        return new
+
+    def min(self):
+        return self.pairs[0][0]
+
+    def max(self):
+        return self.pairs[-1][-1]
+
+    def contains(self, x):
+        for lo, hi in self.pairs:
+            if lo <= x <= hi: return True
+        return False
+
+    def append(self, x):
+        for i in range(len(self.pairs)):
+            lo, hi = self.pairs[i]
+            if x < lo: # Need to insert before
+                if x+1 == lo:
+                    self.pairs[i] = (x, hi)
+                else:
+                    self.pairs.insert(i, (x, x))
+                if i > 0 and x-1 == self.pairs[i-1][1]:
+                    # Merge with previous
+                    self.pairs[i-1:i+1] = [
+                            (self.pairs[i-1][0],
+                             self.pairs[i][1])
+                          ]
+                return
+            if x <= hi: # Already in set
+                return
+        i = len(self.pairs) - 1
+        if i >= 0:
+            lo, hi = self.pairs[i]
+            if x-1 == hi:
+                self.pairs[i] = lo, x
+                return
+        self.pairs.append((x, x))
+
+    def addpair(self, xlo, xhi):
+        if xlo > xhi: return
+        self.pairs.append((xlo, xhi))
+        self.normalize()
+
+    def fromstring(self, data):
+        new = []
+        for part in data.split(self.sep):
+            list = []
+            for subp in part.split(self.rng):
+                s = subp.strip()
+                list.append(int(s))
+            if len(list) == 1:
+                new.append((list[0], list[0]))
+            elif len(list) == 2 and list[0] <= list[1]:
+                new.append((list[0], list[1]))
+            else:
+                raise ValueError, 'bad data passed to IntSet'
+        self.pairs = self.pairs + new
+        self.normalize()
+
+
+# Subroutines to read/write entries in .mh_profile and .mh_sequences
+
+def pickline(file, key, casefold = 1):
+    try:
+        f = open(file, 'r')
+    except IOError:
+        return None
+    pat = re.escape(key) + ':'
+    prog = re.compile(pat, casefold and re.IGNORECASE)
+    while 1:
+        line = f.readline()
+        if not line: break
+        if prog.match(line):
+            text = line[len(key)+1:]
+            while 1:
+                line = f.readline()
+                if not line or not line[0].isspace():
+                    break
+                text = text + line
+            return text.strip()
+    return None
+
+def updateline(file, key, value, casefold = 1):
+    try:
+        f = open(file, 'r')
+        lines = f.readlines()
+        f.close()
+    except IOError:
+        lines = []
+    pat = re.escape(key) + ':(.*)\n'
+    prog = re.compile(pat, casefold and re.IGNORECASE)
+    if value is None:
+        newline = None
+    else:
+        newline = '%s: %s\n' % (key, value)
+    for i in range(len(lines)):
+        line = lines[i]
+        if prog.match(line):
+            if newline is None:
+                del lines[i]
+            else:
+                lines[i] = newline
+            break
+    else:
+        if newline is not None:
+            lines.append(newline)
+    tempfile = file + "~"
+    f = open(tempfile, 'w')
+    for line in lines:
+        f.write(line)
+    f.close()
+    os.rename(tempfile, file)
+
+
+# Test program
+
+def test():
+    global mh, f
+    os.system('rm -rf $HOME/Mail/@test')
+    mh = MH()
+    def do(s): print s; print eval(s)
+    do('mh.listfolders()')
+    do('mh.listallfolders()')
+    testfolders = ['@test', '@test/test1', '@test/test2',
+                   '@test/test1/test11', '@test/test1/test12',
+                   '@test/test1/test11/test111']
+    for t in testfolders: do('mh.makefolder(%r)' % (t,))
+    do('mh.listsubfolders(\'@test\')')
+    do('mh.listallsubfolders(\'@test\')')
+    f = mh.openfolder('@test')
+    do('f.listsubfolders()')
+    do('f.listallsubfolders()')
+    do('f.getsequences()')
+    seqs = f.getsequences()
+    seqs['foo'] = IntSet('1-10 12-20', ' ').tolist()
+    print seqs
+    f.putsequences(seqs)
+    do('f.getsequences()')
+    for t in reversed(testfolders): do('mh.deletefolder(%r)' % (t,))
+    do('mh.getcontext()')
+    context = mh.getcontext()
+    f = mh.openfolder(context)
+    do('f.getcurrent()')
+    for seq in ('first', 'last', 'cur', '.', 'prev', 'next',
+                'first:3', 'last:3', 'cur:3', 'cur:-3',
+                'prev:3', 'next:3',
+                '1:3', '1:-3', '100:3', '100:-3', '10000:3', '10000:-3',
+                'all'):
+        try:
+            do('f.parsesequence(%r)' % (seq,))
+        except Error, msg:
+            print "Error:", msg
+        stuff = os.popen("pick %r 2>/dev/null" % (seq,)).read()
+        list = map(int, stuff.split())
+        print list, "<-- pick"
+    do('f.listmessages()')
+
+
+if __name__ == '__main__':
+    test()

Added: vendor/Python/current/Lib/mimetools.py
===================================================================
--- vendor/Python/current/Lib/mimetools.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/mimetools.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,241 @@
+"""Various tools used by MIME-reading or MIME-writing programs."""
+
+
+import os
+import rfc822
+import tempfile
+
+__all__ = ["Message","choose_boundary","encode","decode","copyliteral",
+           "copybinary"]
+
+class Message(rfc822.Message):
+    """A derived class of rfc822.Message that knows about MIME headers and
+    contains some hooks for decoding encoded and multipart messages."""
+
+    def __init__(self, fp, seekable = 1):
+        rfc822.Message.__init__(self, fp, seekable)
+        self.encodingheader = \
+                self.getheader('content-transfer-encoding')
+        self.typeheader = \
+                self.getheader('content-type')
+        self.parsetype()
+        self.parseplist()
+
+    def parsetype(self):
+        str = self.typeheader
+        if str is None:
+            str = 'text/plain'
+        if ';' in str:
+            i = str.index(';')
+            self.plisttext = str[i:]
+            str = str[:i]
+        else:
+            self.plisttext = ''
+        fields = str.split('/')
+        for i in range(len(fields)):
+            fields[i] = fields[i].strip().lower()
+        self.type = '/'.join(fields)
+        self.maintype = fields[0]
+        self.subtype = '/'.join(fields[1:])
+
+    def parseplist(self):
+        str = self.plisttext
+        self.plist = []
+        while str[:1] == ';':
+            str = str[1:]
+            if ';' in str:
+                # XXX Should parse quotes!
+                end = str.index(';')
+            else:
+                end = len(str)
+            f = str[:end]
+            if '=' in f:
+                i = f.index('=')
+                f = f[:i].strip().lower() + \
+                        '=' + f[i+1:].strip()
+            self.plist.append(f.strip())
+            str = str[end:]
+
+    def getplist(self):
+        return self.plist
+
+    def getparam(self, name):
+        name = name.lower() + '='
+        n = len(name)
+        for p in self.plist:
+            if p[:n] == name:
+                return rfc822.unquote(p[n:])
+        return None
+
+    def getparamnames(self):
+        result = []
+        for p in self.plist:
+            i = p.find('=')
+            if i >= 0:
+                result.append(p[:i].lower())
+        return result
+
+    def getencoding(self):
+        if self.encodingheader is None:
+            return '7bit'
+        return self.encodingheader.lower()
+
+    def gettype(self):
+        return self.type
+
+    def getmaintype(self):
+        return self.maintype
+
+    def getsubtype(self):
+        return self.subtype
+
+
+
+
+# Utility functions
+# -----------------
+
+try:
+    import thread
+except ImportError:
+    import dummy_thread as thread
+_counter_lock = thread.allocate_lock()
+del thread
+
+_counter = 0
+def _get_next_counter():
+    global _counter
+    _counter_lock.acquire()
+    _counter += 1
+    result = _counter
+    _counter_lock.release()
+    return result
+
+_prefix = None
+
+def choose_boundary():
+    """Return a string usable as a multipart boundary.
+
+    The string chosen is unique within a single program run, and
+    incorporates the user id (if available), process id (if available),
+    and current time.  So it's very unlikely the returned string appears
+    in message text, but there's no guarantee.
+
+    The boundary contains dots so you have to quote it in the header."""
+
+    global _prefix
+    import time
+    if _prefix is None:
+        import socket
+        try:
+            hostid = socket.gethostbyname(socket.gethostname())
+        except socket.gaierror:
+            hostid = '127.0.0.1'
+        try:
+            uid = repr(os.getuid())
+        except AttributeError:
+            uid = '1'
+        try:
+            pid = repr(os.getpid())
+        except AttributeError:
+            pid = '1'
+        _prefix = hostid + '.' + uid + '.' + pid
+    return "%s.%.3f.%d" % (_prefix, time.time(), _get_next_counter())
+
+
+# Subroutines for decoding some common content-transfer-types
+
+def decode(input, output, encoding):
+    """Decode common content-transfer-encodings (base64, quopri, uuencode)."""
+    if encoding == 'base64':
+        import base64
+        return base64.decode(input, output)
+    if encoding == 'quoted-printable':
+        import quopri
+        return quopri.decode(input, output)
+    if encoding in ('uuencode', 'x-uuencode', 'uue', 'x-uue'):
+        import uu
+        return uu.decode(input, output)
+    if encoding in ('7bit', '8bit'):
+        return output.write(input.read())
+    if encoding in decodetab:
+        pipethrough(input, decodetab[encoding], output)
+    else:
+        raise ValueError, \
+              'unknown Content-Transfer-Encoding: %s' % encoding
+
+def encode(input, output, encoding):
+    """Encode common content-transfer-encodings (base64, quopri, uuencode)."""
+    if encoding == 'base64':
+        import base64
+        return base64.encode(input, output)
+    if encoding == 'quoted-printable':
+        import quopri
+        return quopri.encode(input, output, 0)
+    if encoding in ('uuencode', 'x-uuencode', 'uue', 'x-uue'):
+        import uu
+        return uu.encode(input, output)
+    if encoding in ('7bit', '8bit'):
+        return output.write(input.read())
+    if encoding in encodetab:
+        pipethrough(input, encodetab[encoding], output)
+    else:
+        raise ValueError, \
+              'unknown Content-Transfer-Encoding: %s' % encoding
+
+# The following is no longer used for standard encodings
+
+# XXX This requires that uudecode and mmencode are in $PATH
+
+uudecode_pipe = '''(
+TEMP=/tmp/@uu.$$
+sed "s%^begin [0-7][0-7]* .*%begin 600 $TEMP%" | uudecode
+cat $TEMP
+rm $TEMP
+)'''
+
+decodetab = {
+        'uuencode':             uudecode_pipe,
+        'x-uuencode':           uudecode_pipe,
+        'uue':                  uudecode_pipe,
+        'x-uue':                uudecode_pipe,
+        'quoted-printable':     'mmencode -u -q',
+        'base64':               'mmencode -u -b',
+}
+
+encodetab = {
+        'x-uuencode':           'uuencode tempfile',
+        'uuencode':             'uuencode tempfile',
+        'x-uue':                'uuencode tempfile',
+        'uue':                  'uuencode tempfile',
+        'quoted-printable':     'mmencode -q',
+        'base64':               'mmencode -b',
+}
+
+def pipeto(input, command):
+    pipe = os.popen(command, 'w')
+    copyliteral(input, pipe)
+    pipe.close()
+
+def pipethrough(input, command, output):
+    (fd, tempname) = tempfile.mkstemp()
+    temp = os.fdopen(fd, 'w')
+    copyliteral(input, temp)
+    temp.close()
+    pipe = os.popen(command + ' <' + tempname, 'r')
+    copybinary(pipe, output)
+    pipe.close()
+    os.unlink(tempname)
+
+def copyliteral(input, output):
+    while 1:
+        line = input.readline()
+        if not line: break
+        output.write(line)
+
+def copybinary(input, output):
+    BUFSIZE = 8192
+    while 1:
+        line = input.read(BUFSIZE)
+        if not line: break
+        output.write(line)

Added: vendor/Python/current/Lib/mimetypes.py
===================================================================
--- vendor/Python/current/Lib/mimetypes.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/mimetypes.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,533 @@
+"""Guess the MIME type of a file.
+
+This module defines two useful functions:
+
+guess_type(url, strict=1) -- guess the MIME type and encoding of a URL.
+
+guess_extension(type, strict=1) -- guess the extension for a given MIME type.
+
+It also contains the following, for tuning the behavior:
+
+Data:
+
+knownfiles -- list of files to parse
+inited -- flag set when init() has been called
+suffix_map -- dictionary mapping suffixes to suffixes
+encodings_map -- dictionary mapping suffixes to encodings
+types_map -- dictionary mapping suffixes to types
+
+Functions:
+
+init([files]) -- parse a list of files, default knownfiles
+read_mime_types(file) -- parse one file, return a dictionary or None
+"""
+
+import os
+import posixpath
+import urllib
+
+__all__ = [
+    "guess_type","guess_extension","guess_all_extensions",
+    "add_type","read_mime_types","init"
+]
+
+knownfiles = [
+    "/etc/mime.types",
+    "/etc/httpd/mime.types",                    # Mac OS X
+    "/etc/httpd/conf/mime.types",               # Apache
+    "/etc/apache/mime.types",                   # Apache 1
+    "/etc/apache2/mime.types",                  # Apache 2
+    "/usr/local/etc/httpd/conf/mime.types",
+    "/usr/local/lib/netscape/mime.types",
+    "/usr/local/etc/httpd/conf/mime.types",     # Apache 1.2
+    "/usr/local/etc/mime.types",                # Apache 1.3
+    ]
+
+inited = False
+
+
+class MimeTypes:
+    """MIME-types datastore.
+
+    This datastore can handle information from mime.types-style files
+    and supports basic determination of MIME type from a filename or
+    URL, and can guess a reasonable extension given a MIME type.
+    """
+
+    def __init__(self, filenames=(), strict=True):
+        if not inited:
+            init()
+        self.encodings_map = encodings_map.copy()
+        self.suffix_map = suffix_map.copy()
+        self.types_map = ({}, {}) # dict for (non-strict, strict)
+        self.types_map_inv = ({}, {})
+        for (ext, type) in types_map.items():
+            self.add_type(type, ext, True)
+        for (ext, type) in common_types.items():
+            self.add_type(type, ext, False)
+        for name in filenames:
+            self.read(name, strict)
+
+    def add_type(self, type, ext, strict=True):
+        """Add a mapping between a type and an extension.
+
+        When the extension is already known, the new
+        type will replace the old one. When the type
+        is already known the extension will be added
+        to the list of known extensions.
+
+        If strict is true, information will be added to
+        list of standard types, else to the list of non-standard
+        types.
+        """
+        self.types_map[strict][ext] = type
+        exts = self.types_map_inv[strict].setdefault(type, [])
+        if ext not in exts:
+            exts.append(ext)
+
+    def guess_type(self, url, strict=True):
+        """Guess the type of a file based on its URL.
+
+        Return value is a tuple (type, encoding) where type is None if
+        the type can't be guessed (no or unknown suffix) or a string
+        of the form type/subtype, usable for a MIME Content-type
+        header; and encoding is None for no encoding or the name of
+        the program used to encode (e.g. compress or gzip).  The
+        mappings are table driven.  Encoding suffixes are case
+        sensitive; type suffixes are first tried case sensitive, then
+        case insensitive.
+
+        The suffixes .tgz, .taz and .tz (case sensitive!) are all
+        mapped to '.tar.gz'.  (This is table-driven too, using the
+        dictionary suffix_map.)
+
+        Optional `strict' argument when False adds a bunch of commonly found,
+        but non-standard types.
+        """
+        scheme, url = urllib.splittype(url)
+        if scheme == 'data':
+            # syntax of data URLs:
+            # dataurl   := "data:" [ mediatype ] [ ";base64" ] "," data
+            # mediatype := [ type "/" subtype ] *( ";" parameter )
+            # data      := *urlchar
+            # parameter := attribute "=" value
+            # type/subtype defaults to "text/plain"
+            comma = url.find(',')
+            if comma < 0:
+                # bad data URL
+                return None, None
+            semi = url.find(';', 0, comma)
+            if semi >= 0:
+                type = url[:semi]
+            else:
+                type = url[:comma]
+            if '=' in type or '/' not in type:
+                type = 'text/plain'
+            return type, None           # never compressed, so encoding is None
+        base, ext = posixpath.splitext(url)
+        while ext in self.suffix_map:
+            base, ext = posixpath.splitext(base + self.suffix_map[ext])
+        if ext in self.encodings_map:
+            encoding = self.encodings_map[ext]
+            base, ext = posixpath.splitext(base)
+        else:
+            encoding = None
+        types_map = self.types_map[True]
+        if ext in types_map:
+            return types_map[ext], encoding
+        elif ext.lower() in types_map:
+            return types_map[ext.lower()], encoding
+        elif strict:
+            return None, encoding
+        types_map = self.types_map[False]
+        if ext in types_map:
+            return types_map[ext], encoding
+        elif ext.lower() in types_map:
+            return types_map[ext.lower()], encoding
+        else:
+            return None, encoding
+
+    def guess_all_extensions(self, type, strict=True):
+        """Guess the extensions for a file based on its MIME type.
+
+        Return value is a list of strings giving the possible filename
+        extensions, including the leading dot ('.').  The extension is not
+        guaranteed to have been associated with any particular data stream,
+        but would be mapped to the MIME type `type' by guess_type().
+
+        Optional `strict' argument when false adds a bunch of commonly found,
+        but non-standard types.
+        """
+        type = type.lower()
+        extensions = self.types_map_inv[True].get(type, [])
+        if not strict:
+            for ext in self.types_map_inv[False].get(type, []):
+                if ext not in extensions:
+                    extensions.append(ext)
+        return extensions
+
+    def guess_extension(self, type, strict=True):
+        """Guess the extension for a file based on its MIME type.
+
+        Return value is a string giving a filename extension,
+        including the leading dot ('.').  The extension is not
+        guaranteed to have been associated with any particular data
+        stream, but would be mapped to the MIME type `type' by
+        guess_type().  If no extension can be guessed for `type', None
+        is returned.
+
+        Optional `strict' argument when false adds a bunch of commonly found,
+        but non-standard types.
+        """
+        extensions = self.guess_all_extensions(type, strict)
+        if not extensions:
+            return None
+        return extensions[0]
+
+    def read(self, filename, strict=True):
+        """
+        Read a single mime.types-format file, specified by pathname.
+
+        If strict is true, information will be added to
+        list of standard types, else to the list of non-standard
+        types.
+        """
+        fp = open(filename)
+        self.readfp(fp, strict)
+        fp.close()
+
+    def readfp(self, fp, strict=True):
+        """
+        Read a single mime.types-format file.
+
+        If strict is true, information will be added to
+        list of standard types, else to the list of non-standard
+        types.
+        """
+        while 1:
+            line = fp.readline()
+            if not line:
+                break
+            words = line.split()
+            for i in range(len(words)):
+                if words[i][0] == '#':
+                    del words[i:]
+                    break
+            if not words:
+                continue
+            type, suffixes = words[0], words[1:]
+            for suff in suffixes:
+                self.add_type(type, '.' + suff, strict)
+
+def guess_type(url, strict=True):
+    """Guess the type of a file based on its URL.
+
+    Return value is a tuple (type, encoding) where type is None if the
+    type can't be guessed (no or unknown suffix) or a string of the
+    form type/subtype, usable for a MIME Content-type header; and
+    encoding is None for no encoding or the name of the program used
+    to encode (e.g. compress or gzip).  The mappings are table
+    driven.  Encoding suffixes are case sensitive; type suffixes are
+    first tried case sensitive, then case insensitive.
+
+    The suffixes .tgz, .taz and .tz (case sensitive!) are all mapped
+    to ".tar.gz".  (This is table-driven too, using the dictionary
+    suffix_map).
+
+    Optional `strict' argument when false adds a bunch of commonly found, but
+    non-standard types.
+    """
+    init()
+    return guess_type(url, strict)
+
+
+def guess_all_extensions(type, strict=True):
+    """Guess the extensions for a file based on its MIME type.
+
+    Return value is a list of strings giving the possible filename
+    extensions, including the leading dot ('.').  The extension is not
+    guaranteed to have been associated with any particular data
+    stream, but would be mapped to the MIME type `type' by
+    guess_type().  If no extension can be guessed for `type', None
+    is returned.
+
+    Optional `strict' argument when false adds a bunch of commonly found,
+    but non-standard types.
+    """
+    init()
+    return guess_all_extensions(type, strict)
+
+def guess_extension(type, strict=True):
+    """Guess the extension for a file based on its MIME type.
+
+    Return value is a string giving a filename extension, including the
+    leading dot ('.').  The extension is not guaranteed to have been
+    associated with any particular data stream, but would be mapped to the
+    MIME type `type' by guess_type().  If no extension can be guessed for
+    `type', None is returned.
+
+    Optional `strict' argument when false adds a bunch of commonly found,
+    but non-standard types.
+    """
+    init()
+    return guess_extension(type, strict)
+
+def add_type(type, ext, strict=True):
+    """Add a mapping between a type and an extension.
+
+    When the extension is already known, the new
+    type will replace the old one. When the type
+    is already known the extension will be added
+    to the list of known extensions.
+
+    If strict is true, information will be added to
+    list of standard types, else to the list of non-standard
+    types.
+    """
+    init()
+    return add_type(type, ext, strict)
+
+
+def init(files=None):
+    global guess_all_extensions, guess_extension, guess_type
+    global suffix_map, types_map, encodings_map, common_types
+    global add_type, inited
+    inited = True
+    db = MimeTypes()
+    if files is None:
+        files = knownfiles
+    for file in files:
+        if os.path.isfile(file):
+            db.readfp(open(file))
+    encodings_map = db.encodings_map
+    suffix_map = db.suffix_map
+    types_map = db.types_map[True]
+    guess_all_extensions = db.guess_all_extensions
+    guess_extension = db.guess_extension
+    guess_type = db.guess_type
+    add_type = db.add_type
+    common_types = db.types_map[False]
+
+
+def read_mime_types(file):
+    try:
+        f = open(file)
+    except IOError:
+        return None
+    db = MimeTypes()
+    db.readfp(f, True)
+    return db.types_map[True]
+
+
+def _default_mime_types():
+    global suffix_map
+    global encodings_map
+    global types_map
+    global common_types
+
+    suffix_map = {
+        '.tgz': '.tar.gz',
+        '.taz': '.tar.gz',
+        '.tz': '.tar.gz',
+        }
+
+    encodings_map = {
+        '.gz': 'gzip',
+        '.Z': 'compress',
+        }
+
+    # Before adding new types, make sure they are either registered with IANA,
+    # at http://www.isi.edu/in-notes/iana/assignments/media-types
+    # or extensions, i.e. using the x- prefix
+
+    # If you add to these, please keep them sorted!
+    types_map = {
+        '.a'      : 'application/octet-stream',
+        '.ai'     : 'application/postscript',
+        '.aif'    : 'audio/x-aiff',
+        '.aifc'   : 'audio/x-aiff',
+        '.aiff'   : 'audio/x-aiff',
+        '.au'     : 'audio/basic',
+        '.avi'    : 'video/x-msvideo',
+        '.bat'    : 'text/plain',
+        '.bcpio'  : 'application/x-bcpio',
+        '.bin'    : 'application/octet-stream',
+        '.bmp'    : 'image/x-ms-bmp',
+        '.c'      : 'text/plain',
+        # Duplicates :(
+        '.cdf'    : 'application/x-cdf',
+        '.cdf'    : 'application/x-netcdf',
+        '.cpio'   : 'application/x-cpio',
+        '.csh'    : 'application/x-csh',
+        '.css'    : 'text/css',
+        '.dll'    : 'application/octet-stream',
+        '.doc'    : 'application/msword',
+        '.dot'    : 'application/msword',
+        '.dvi'    : 'application/x-dvi',
+        '.eml'    : 'message/rfc822',
+        '.eps'    : 'application/postscript',
+        '.etx'    : 'text/x-setext',
+        '.exe'    : 'application/octet-stream',
+        '.gif'    : 'image/gif',
+        '.gtar'   : 'application/x-gtar',
+        '.h'      : 'text/plain',
+        '.hdf'    : 'application/x-hdf',
+        '.htm'    : 'text/html',
+        '.html'   : 'text/html',
+        '.ief'    : 'image/ief',
+        '.jpe'    : 'image/jpeg',
+        '.jpeg'   : 'image/jpeg',
+        '.jpg'    : 'image/jpeg',
+        '.js'     : 'application/x-javascript',
+        '.ksh'    : 'text/plain',
+        '.latex'  : 'application/x-latex',
+        '.m1v'    : 'video/mpeg',
+        '.man'    : 'application/x-troff-man',
+        '.me'     : 'application/x-troff-me',
+        '.mht'    : 'message/rfc822',
+        '.mhtml'  : 'message/rfc822',
+        '.mif'    : 'application/x-mif',
+        '.mov'    : 'video/quicktime',
+        '.movie'  : 'video/x-sgi-movie',
+        '.mp2'    : 'audio/mpeg',
+        '.mp3'    : 'audio/mpeg',
+        '.mpa'    : 'video/mpeg',
+        '.mpe'    : 'video/mpeg',
+        '.mpeg'   : 'video/mpeg',
+        '.mpg'    : 'video/mpeg',
+        '.ms'     : 'application/x-troff-ms',
+        '.nc'     : 'application/x-netcdf',
+        '.nws'    : 'message/rfc822',
+        '.o'      : 'application/octet-stream',
+        '.obj'    : 'application/octet-stream',
+        '.oda'    : 'application/oda',
+        '.p12'    : 'application/x-pkcs12',
+        '.p7c'    : 'application/pkcs7-mime',
+        '.pbm'    : 'image/x-portable-bitmap',
+        '.pdf'    : 'application/pdf',
+        '.pfx'    : 'application/x-pkcs12',
+        '.pgm'    : 'image/x-portable-graymap',
+        '.pl'     : 'text/plain',
+        '.png'    : 'image/png',
+        '.pnm'    : 'image/x-portable-anymap',
+        '.pot'    : 'application/vnd.ms-powerpoint',
+        '.ppa'    : 'application/vnd.ms-powerpoint',
+        '.ppm'    : 'image/x-portable-pixmap',
+        '.pps'    : 'application/vnd.ms-powerpoint',
+        '.ppt'    : 'application/vnd.ms-powerpoint',
+        '.ps'     : 'application/postscript',
+        '.pwz'    : 'application/vnd.ms-powerpoint',
+        '.py'     : 'text/x-python',
+        '.pyc'    : 'application/x-python-code',
+        '.pyo'    : 'application/x-python-code',
+        '.qt'     : 'video/quicktime',
+        '.ra'     : 'audio/x-pn-realaudio',
+        '.ram'    : 'application/x-pn-realaudio',
+        '.ras'    : 'image/x-cmu-raster',
+        '.rdf'    : 'application/xml',
+        '.rgb'    : 'image/x-rgb',
+        '.roff'   : 'application/x-troff',
+        '.rtx'    : 'text/richtext',
+        '.sgm'    : 'text/x-sgml',
+        '.sgml'   : 'text/x-sgml',
+        '.sh'     : 'application/x-sh',
+        '.shar'   : 'application/x-shar',
+        '.snd'    : 'audio/basic',
+        '.so'     : 'application/octet-stream',
+        '.src'    : 'application/x-wais-source',
+        '.sv4cpio': 'application/x-sv4cpio',
+        '.sv4crc' : 'application/x-sv4crc',
+        '.swf'    : 'application/x-shockwave-flash',
+        '.t'      : 'application/x-troff',
+        '.tar'    : 'application/x-tar',
+        '.tcl'    : 'application/x-tcl',
+        '.tex'    : 'application/x-tex',
+        '.texi'   : 'application/x-texinfo',
+        '.texinfo': 'application/x-texinfo',
+        '.tif'    : 'image/tiff',
+        '.tiff'   : 'image/tiff',
+        '.tr'     : 'application/x-troff',
+        '.tsv'    : 'text/tab-separated-values',
+        '.txt'    : 'text/plain',
+        '.ustar'  : 'application/x-ustar',
+        '.vcf'    : 'text/x-vcard',
+        '.wav'    : 'audio/x-wav',
+        '.wiz'    : 'application/msword',
+        '.wsdl'   : 'application/xml',
+        '.xbm'    : 'image/x-xbitmap',
+        '.xlb'    : 'application/vnd.ms-excel',
+        # Duplicates :(
+        '.xls'    : 'application/excel',
+        '.xls'    : 'application/vnd.ms-excel',
+        '.xml'    : 'text/xml',
+        '.xpdl'   : 'application/xml',
+        '.xpm'    : 'image/x-xpixmap',
+        '.xsl'    : 'application/xml',
+        '.xwd'    : 'image/x-xwindowdump',
+        '.zip'    : 'application/zip',
+        }
+
+    # These are non-standard types, commonly found in the wild.  They will
+    # only match if strict=0 flag is given to the API methods.
+
+    # Please sort these too
+    common_types = {
+        '.jpg' : 'image/jpg',
+        '.mid' : 'audio/midi',
+        '.midi': 'audio/midi',
+        '.pct' : 'image/pict',
+        '.pic' : 'image/pict',
+        '.pict': 'image/pict',
+        '.rtf' : 'application/rtf',
+        '.xul' : 'text/xul'
+        }
+
+
+_default_mime_types()
+
+
+if __name__ == '__main__':
+    import sys
+    import getopt
+
+    USAGE = """\
+Usage: mimetypes.py [options] type
+
+Options:
+    --help / -h       -- print this message and exit
+    --lenient / -l    -- additionally search of some common, but non-standard
+                         types.
+    --extension / -e  -- guess extension instead of type
+
+More than one type argument may be given.
+"""
+
+    def usage(code, msg=''):
+        print USAGE
+        if msg: print msg
+        sys.exit(code)
+
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], 'hle',
+                                   ['help', 'lenient', 'extension'])
+    except getopt.error, msg:
+        usage(1, msg)
+
+    strict = 1
+    extension = 0
+    for opt, arg in opts:
+        if opt in ('-h', '--help'):
+            usage(0)
+        elif opt in ('-l', '--lenient'):
+            strict = 0
+        elif opt in ('-e', '--extension'):
+            extension = 1
+    for gtype in args:
+        if extension:
+            guess = guess_extension(gtype, strict)
+            if not guess: print "I don't know anything about type", gtype
+            else: print guess
+        else:
+            guess, encoding = guess_type(gtype, strict)
+            if not guess: print "I don't know anything about type", gtype
+            else: print 'type:', guess, 'encoding:', encoding

Added: vendor/Python/current/Lib/mimify.py
===================================================================
--- vendor/Python/current/Lib/mimify.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/mimify.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,464 @@
+#! /usr/bin/env python
+
+"""Mimification and unmimification of mail messages.
+
+Decode quoted-printable parts of a mail message or encode using
+quoted-printable.
+
+Usage:
+        mimify(input, output)
+        unmimify(input, output, decode_base64 = 0)
+to encode and decode respectively.  Input and output may be the name
+of a file or an open file object.  Only a readline() method is used
+on the input file, only a write() method is used on the output file.
+When using file names, the input and output file names may be the
+same.
+
+Interactive usage:
+        mimify.py -e [infile [outfile]]
+        mimify.py -d [infile [outfile]]
+to encode and decode respectively.  Infile defaults to standard
+input and outfile to standard output.
+"""
+
+# Configure
+MAXLEN = 200    # if lines longer than this, encode as quoted-printable
+CHARSET = 'ISO-8859-1'  # default charset for non-US-ASCII mail
+QUOTE = '> '            # string replies are quoted with
+# End configure
+
+import re
+
+__all__ = ["mimify","unmimify","mime_encode_header","mime_decode_header"]
+
+qp = re.compile('^content-transfer-encoding:\\s*quoted-printable', re.I)
+base64_re = re.compile('^content-transfer-encoding:\\s*base64', re.I)
+mp = re.compile('^content-type:.*multipart/.*boundary="?([^;"\n]*)', re.I|re.S)
+chrset = re.compile('^(content-type:.*charset=")(us-ascii|iso-8859-[0-9]+)(".*)', re.I|re.S)
+he = re.compile('^-*\n')
+mime_code = re.compile('=([0-9a-f][0-9a-f])', re.I)
+mime_head = re.compile('=\\?iso-8859-1\\?q\\?([^? \t\n]+)\\?=', re.I)
+repl = re.compile('^subject:\\s+re: ', re.I)
+
+class File:
+    """A simple fake file object that knows about limited read-ahead and
+    boundaries.  The only supported method is readline()."""
+
+    def __init__(self, file, boundary):
+        self.file = file
+        self.boundary = boundary
+        self.peek = None
+
+    def readline(self):
+        if self.peek is not None:
+            return ''
+        line = self.file.readline()
+        if not line:
+            return line
+        if self.boundary:
+            if line == self.boundary + '\n':
+                self.peek = line
+                return ''
+            if line == self.boundary + '--\n':
+                self.peek = line
+                return ''
+        return line
+
+class HeaderFile:
+    def __init__(self, file):
+        self.file = file
+        self.peek = None
+
+    def readline(self):
+        if self.peek is not None:
+            line = self.peek
+            self.peek = None
+        else:
+            line = self.file.readline()
+        if not line:
+            return line
+        if he.match(line):
+            return line
+        while 1:
+            self.peek = self.file.readline()
+            if len(self.peek) == 0 or \
+               (self.peek[0] != ' ' and self.peek[0] != '\t'):
+                return line
+            line = line + self.peek
+            self.peek = None
+
+def mime_decode(line):
+    """Decode a single line of quoted-printable text to 8bit."""
+    newline = ''
+    pos = 0
+    while 1:
+        res = mime_code.search(line, pos)
+        if res is None:
+            break
+        newline = newline + line[pos:res.start(0)] + \
+                  chr(int(res.group(1), 16))
+        pos = res.end(0)
+    return newline + line[pos:]
+
+def mime_decode_header(line):
+    """Decode a header line to 8bit."""
+    newline = ''
+    pos = 0
+    while 1:
+        res = mime_head.search(line, pos)
+        if res is None:
+            break
+        match = res.group(1)
+        # convert underscores to spaces (before =XX conversion!)
+        match = ' '.join(match.split('_'))
+        newline = newline + line[pos:res.start(0)] + mime_decode(match)
+        pos = res.end(0)
+    return newline + line[pos:]
+
+def unmimify_part(ifile, ofile, decode_base64 = 0):
+    """Convert a quoted-printable part of a MIME mail message to 8bit."""
+    multipart = None
+    quoted_printable = 0
+    is_base64 = 0
+    is_repl = 0
+    if ifile.boundary and ifile.boundary[:2] == QUOTE:
+        prefix = QUOTE
+    else:
+        prefix = ''
+
+    # read header
+    hfile = HeaderFile(ifile)
+    while 1:
+        line = hfile.readline()
+        if not line:
+            return
+        if prefix and line[:len(prefix)] == prefix:
+            line = line[len(prefix):]
+            pref = prefix
+        else:
+            pref = ''
+        line = mime_decode_header(line)
+        if qp.match(line):
+            quoted_printable = 1
+            continue        # skip this header
+        if decode_base64 and base64_re.match(line):
+            is_base64 = 1
+            continue
+        ofile.write(pref + line)
+        if not prefix and repl.match(line):
+            # we're dealing with a reply message
+            is_repl = 1
+        mp_res = mp.match(line)
+        if mp_res:
+            multipart = '--' + mp_res.group(1)
+        if he.match(line):
+            break
+    if is_repl and (quoted_printable or multipart):
+        is_repl = 0
+
+    # read body
+    while 1:
+        line = ifile.readline()
+        if not line:
+            return
+        line = re.sub(mime_head, '\\1', line)
+        if prefix and line[:len(prefix)] == prefix:
+            line = line[len(prefix):]
+            pref = prefix
+        else:
+            pref = ''
+##              if is_repl and len(line) >= 4 and line[:4] == QUOTE+'--' and line[-3:] != '--\n':
+##                      multipart = line[:-1]
+        while multipart:
+            if line == multipart + '--\n':
+                ofile.write(pref + line)
+                multipart = None
+                line = None
+                break
+            if line == multipart + '\n':
+                ofile.write(pref + line)
+                nifile = File(ifile, multipart)
+                unmimify_part(nifile, ofile, decode_base64)
+                line = nifile.peek
+                if not line:
+                    # premature end of file
+                    break
+                continue
+            # not a boundary between parts
+            break
+        if line and quoted_printable:
+            while line[-2:] == '=\n':
+                line = line[:-2]
+                newline = ifile.readline()
+                if newline[:len(QUOTE)] == QUOTE:
+                    newline = newline[len(QUOTE):]
+                line = line + newline
+            line = mime_decode(line)
+        if line and is_base64 and not pref:
+            import base64
+            line = base64.decodestring(line)
+        if line:
+            ofile.write(pref + line)
+
+def unmimify(infile, outfile, decode_base64 = 0):
+    """Convert quoted-printable parts of a MIME mail message to 8bit."""
+    if type(infile) == type(''):
+        ifile = open(infile)
+        if type(outfile) == type('') and infile == outfile:
+            import os
+            d, f = os.path.split(infile)
+            os.rename(infile, os.path.join(d, ',' + f))
+    else:
+        ifile = infile
+    if type(outfile) == type(''):
+        ofile = open(outfile, 'w')
+    else:
+        ofile = outfile
+    nifile = File(ifile, None)
+    unmimify_part(nifile, ofile, decode_base64)
+    ofile.flush()
+
+mime_char = re.compile('[=\177-\377]') # quote these chars in body
+mime_header_char = re.compile('[=?\177-\377]') # quote these in header
+
+def mime_encode(line, header):
+    """Code a single line as quoted-printable.
+    If header is set, quote some extra characters."""
+    if header:
+        reg = mime_header_char
+    else:
+        reg = mime_char
+    newline = ''
+    pos = 0
+    if len(line) >= 5 and line[:5] == 'From ':
+        # quote 'From ' at the start of a line for stupid mailers
+        newline = ('=%02x' % ord('F')).upper()
+        pos = 1
+    while 1:
+        res = reg.search(line, pos)
+        if res is None:
+            break
+        newline = newline + line[pos:res.start(0)] + \
+                  ('=%02x' % ord(res.group(0))).upper()
+        pos = res.end(0)
+    line = newline + line[pos:]
+
+    newline = ''
+    while len(line) >= 75:
+        i = 73
+        while line[i] == '=' or line[i-1] == '=':
+            i = i - 1
+        i = i + 1
+        newline = newline + line[:i] + '=\n'
+        line = line[i:]
+    return newline + line
+
+mime_header = re.compile('([ \t(]|^)([-a-zA-Z0-9_+]*[\177-\377][-a-zA-Z0-9_+\177-\377]*)(?=[ \t)]|\n)')
+
+def mime_encode_header(line):
+    """Code a single header line as quoted-printable."""
+    newline = ''
+    pos = 0
+    while 1:
+        res = mime_header.search(line, pos)
+        if res is None:
+            break
+        newline = '%s%s%s=?%s?Q?%s?=' % \
+                  (newline, line[pos:res.start(0)], res.group(1),
+                   CHARSET, mime_encode(res.group(2), 1))
+        pos = res.end(0)
+    return newline + line[pos:]
+
+mv = re.compile('^mime-version:', re.I)
+cte = re.compile('^content-transfer-encoding:', re.I)
+iso_char = re.compile('[\177-\377]')
+
+def mimify_part(ifile, ofile, is_mime):
+    """Convert an 8bit part of a MIME mail message to quoted-printable."""
+    has_cte = is_qp = is_base64 = 0
+    multipart = None
+    must_quote_body = must_quote_header = has_iso_chars = 0
+
+    header = []
+    header_end = ''
+    message = []
+    message_end = ''
+    # read header
+    hfile = HeaderFile(ifile)
+    while 1:
+        line = hfile.readline()
+        if not line:
+            break
+        if not must_quote_header and iso_char.search(line):
+            must_quote_header = 1
+        if mv.match(line):
+            is_mime = 1
+        if cte.match(line):
+            has_cte = 1
+            if qp.match(line):
+                is_qp = 1
+            elif base64_re.match(line):
+                is_base64 = 1
+        mp_res = mp.match(line)
+        if mp_res:
+            multipart = '--' + mp_res.group(1)
+        if he.match(line):
+            header_end = line
+            break
+        header.append(line)
+
+    # read body
+    while 1:
+        line = ifile.readline()
+        if not line:
+            break
+        if multipart:
+            if line == multipart + '--\n':
+                message_end = line
+                break
+            if line == multipart + '\n':
+                message_end = line
+                break
+        if is_base64:
+            message.append(line)
+            continue
+        if is_qp:
+            while line[-2:] == '=\n':
+                line = line[:-2]
+                newline = ifile.readline()
+                if newline[:len(QUOTE)] == QUOTE:
+                    newline = newline[len(QUOTE):]
+                line = line + newline
+            line = mime_decode(line)
+        message.append(line)
+        if not has_iso_chars:
+            if iso_char.search(line):
+                has_iso_chars = must_quote_body = 1
+        if not must_quote_body:
+            if len(line) > MAXLEN:
+                must_quote_body = 1
+
+    # convert and output header and body
+    for line in header:
+        if must_quote_header:
+            line = mime_encode_header(line)
+        chrset_res = chrset.match(line)
+        if chrset_res:
+            if has_iso_chars:
+                # change us-ascii into iso-8859-1
+                if chrset_res.group(2).lower() == 'us-ascii':
+                    line = '%s%s%s' % (chrset_res.group(1),
+                                       CHARSET,
+                                       chrset_res.group(3))
+            else:
+                # change iso-8859-* into us-ascii
+                line = '%sus-ascii%s' % chrset_res.group(1, 3)
+        if has_cte and cte.match(line):
+            line = 'Content-Transfer-Encoding: '
+            if is_base64:
+                line = line + 'base64\n'
+            elif must_quote_body:
+                line = line + 'quoted-printable\n'
+            else:
+                line = line + '7bit\n'
+        ofile.write(line)
+    if (must_quote_header or must_quote_body) and not is_mime:
+        ofile.write('Mime-Version: 1.0\n')
+        ofile.write('Content-Type: text/plain; ')
+        if has_iso_chars:
+            ofile.write('charset="%s"\n' % CHARSET)
+        else:
+            ofile.write('charset="us-ascii"\n')
+    if must_quote_body and not has_cte:
+        ofile.write('Content-Transfer-Encoding: quoted-printable\n')
+    ofile.write(header_end)
+
+    for line in message:
+        if must_quote_body:
+            line = mime_encode(line, 0)
+        ofile.write(line)
+    ofile.write(message_end)
+
+    line = message_end
+    while multipart:
+        if line == multipart + '--\n':
+            # read bit after the end of the last part
+            while 1:
+                line = ifile.readline()
+                if not line:
+                    return
+                if must_quote_body:
+                    line = mime_encode(line, 0)
+                ofile.write(line)
+        if line == multipart + '\n':
+            nifile = File(ifile, multipart)
+            mimify_part(nifile, ofile, 1)
+            line = nifile.peek
+            if not line:
+                # premature end of file
+                break
+            ofile.write(line)
+            continue
+        # unexpectedly no multipart separator--copy rest of file
+        while 1:
+            line = ifile.readline()
+            if not line:
+                return
+            if must_quote_body:
+                line = mime_encode(line, 0)
+            ofile.write(line)
+
+def mimify(infile, outfile):
+    """Convert 8bit parts of a MIME mail message to quoted-printable."""
+    if type(infile) == type(''):
+        ifile = open(infile)
+        if type(outfile) == type('') and infile == outfile:
+            import os
+            d, f = os.path.split(infile)
+            os.rename(infile, os.path.join(d, ',' + f))
+    else:
+        ifile = infile
+    if type(outfile) == type(''):
+        ofile = open(outfile, 'w')
+    else:
+        ofile = outfile
+    nifile = File(ifile, None)
+    mimify_part(nifile, ofile, 0)
+    ofile.flush()
+
+import sys
+if __name__ == '__main__' or (len(sys.argv) > 0 and sys.argv[0] == 'mimify'):
+    import getopt
+    usage = 'Usage: mimify [-l len] -[ed] [infile [outfile]]'
+
+    decode_base64 = 0
+    opts, args = getopt.getopt(sys.argv[1:], 'l:edb')
+    if len(args) not in (0, 1, 2):
+        print usage
+        sys.exit(1)
+    if (('-e', '') in opts) == (('-d', '') in opts) or \
+       ((('-b', '') in opts) and (('-d', '') not in opts)):
+        print usage
+        sys.exit(1)
+    for o, a in opts:
+        if o == '-e':
+            encode = mimify
+        elif o == '-d':
+            encode = unmimify
+        elif o == '-l':
+            try:
+                MAXLEN = int(a)
+            except (ValueError, OverflowError):
+                print usage
+                sys.exit(1)
+        elif o == '-b':
+            decode_base64 = 1
+    if len(args) == 0:
+        encode_args = (sys.stdin, sys.stdout)
+    elif len(args) == 1:
+        encode_args = (args[0], sys.stdout)
+    else:
+        encode_args = (args[0], args[1])
+    if decode_base64:
+        encode_args = encode_args + (decode_base64,)
+    encode(*encode_args)


Property changes on: vendor/Python/current/Lib/mimify.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/modulefinder.py
===================================================================
--- vendor/Python/current/Lib/modulefinder.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/modulefinder.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,595 @@
+"""Find modules used by a script, using introspection."""
+
+# This module should be kept compatible with Python 2.2, see PEP 291.
+
+import dis
+import imp
+import marshal
+import os
+import sys
+import new
+
+if hasattr(sys.__stdout__, "newlines"):
+    READ_MODE = "U"  # universal line endings
+else:
+    # remain compatible with Python  < 2.3
+    READ_MODE = "r"
+
+LOAD_CONST = dis.opname.index('LOAD_CONST')
+IMPORT_NAME = dis.opname.index('IMPORT_NAME')
+STORE_NAME = dis.opname.index('STORE_NAME')
+STORE_GLOBAL = dis.opname.index('STORE_GLOBAL')
+STORE_OPS = [STORE_NAME, STORE_GLOBAL]
+
+# Modulefinder does a good job at simulating Python's, but it can not
+# handle __path__ modifications packages make at runtime.  Therefore there
+# is a mechanism whereby you can register extra paths in this map for a
+# package, and it will be honored.
+
+# Note this is a mapping is lists of paths.
+packagePathMap = {}
+
+# A Public interface
+def AddPackagePath(packagename, path):
+    paths = packagePathMap.get(packagename, [])
+    paths.append(path)
+    packagePathMap[packagename] = paths
+
+replacePackageMap = {}
+
+# This ReplacePackage mechanism allows modulefinder to work around the
+# way the _xmlplus package injects itself under the name "xml" into
+# sys.modules at runtime by calling ReplacePackage("_xmlplus", "xml")
+# before running ModuleFinder.
+
+def ReplacePackage(oldname, newname):
+    replacePackageMap[oldname] = newname
+
+
+class Module:
+
+    def __init__(self, name, file=None, path=None):
+        self.__name__ = name
+        self.__file__ = file
+        self.__path__ = path
+        self.__code__ = None
+        # The set of global names that are assigned to in the module.
+        # This includes those names imported through starimports of
+        # Python modules.
+        self.globalnames = {}
+        # The set of starimports this module did that could not be
+        # resolved, ie. a starimport from a non-Python module.
+        self.starimports = {}
+
+    def __repr__(self):
+        s = "Module(%r" % (self.__name__,)
+        if self.__file__ is not None:
+            s = s + ", %r" % (self.__file__,)
+        if self.__path__ is not None:
+            s = s + ", %r" % (self.__path__,)
+        s = s + ")"
+        return s
+
+class ModuleFinder:
+
+    def __init__(self, path=None, debug=0, excludes=[], replace_paths=[]):
+        if path is None:
+            path = sys.path
+        self.path = path
+        self.modules = {}
+        self.badmodules = {}
+        self.debug = debug
+        self.indent = 0
+        self.excludes = excludes
+        self.replace_paths = replace_paths
+        self.processed_paths = []   # Used in debugging only
+
+    def msg(self, level, str, *args):
+        if level <= self.debug:
+            for i in range(self.indent):
+                print "   ",
+            print str,
+            for arg in args:
+                print repr(arg),
+            print
+
+    def msgin(self, *args):
+        level = args[0]
+        if level <= self.debug:
+            self.indent = self.indent + 1
+            self.msg(*args)
+
+    def msgout(self, *args):
+        level = args[0]
+        if level <= self.debug:
+            self.indent = self.indent - 1
+            self.msg(*args)
+
+    def run_script(self, pathname):
+        self.msg(2, "run_script", pathname)
+        fp = open(pathname, READ_MODE)
+        stuff = ("", "r", imp.PY_SOURCE)
+        self.load_module('__main__', fp, pathname, stuff)
+
+    def load_file(self, pathname):
+        dir, name = os.path.split(pathname)
+        name, ext = os.path.splitext(name)
+        fp = open(pathname, READ_MODE)
+        stuff = (ext, "r", imp.PY_SOURCE)
+        self.load_module(name, fp, pathname, stuff)
+
+    def import_hook(self, name, caller=None, fromlist=None):
+        self.msg(3, "import_hook", name, caller, fromlist)
+        parent = self.determine_parent(caller)
+        q, tail = self.find_head_package(parent, name)
+        m = self.load_tail(q, tail)
+        if not fromlist:
+            return q
+        if m.__path__:
+            self.ensure_fromlist(m, fromlist)
+        return None
+
+    def determine_parent(self, caller):
+        self.msgin(4, "determine_parent", caller)
+        if not caller:
+            self.msgout(4, "determine_parent -> None")
+            return None
+        pname = caller.__name__
+        if caller.__path__:
+            parent = self.modules[pname]
+            assert caller is parent
+            self.msgout(4, "determine_parent ->", parent)
+            return parent
+        if '.' in pname:
+            i = pname.rfind('.')
+            pname = pname[:i]
+            parent = self.modules[pname]
+            assert parent.__name__ == pname
+            self.msgout(4, "determine_parent ->", parent)
+            return parent
+        self.msgout(4, "determine_parent -> None")
+        return None
+
+    def find_head_package(self, parent, name):
+        self.msgin(4, "find_head_package", parent, name)
+        if '.' in name:
+            i = name.find('.')
+            head = name[:i]
+            tail = name[i+1:]
+        else:
+            head = name
+            tail = ""
+        if parent:
+            qname = "%s.%s" % (parent.__name__, head)
+        else:
+            qname = head
+        q = self.import_module(head, qname, parent)
+        if q:
+            self.msgout(4, "find_head_package ->", (q, tail))
+            return q, tail
+        if parent:
+            qname = head
+            parent = None
+            q = self.import_module(head, qname, parent)
+            if q:
+                self.msgout(4, "find_head_package ->", (q, tail))
+                return q, tail
+        self.msgout(4, "raise ImportError: No module named", qname)
+        raise ImportError, "No module named " + qname
+
+    def load_tail(self, q, tail):
+        self.msgin(4, "load_tail", q, tail)
+        m = q
+        while tail:
+            i = tail.find('.')
+            if i < 0: i = len(tail)
+            head, tail = tail[:i], tail[i+1:]
+            mname = "%s.%s" % (m.__name__, head)
+            m = self.import_module(head, mname, m)
+            if not m:
+                self.msgout(4, "raise ImportError: No module named", mname)
+                raise ImportError, "No module named " + mname
+        self.msgout(4, "load_tail ->", m)
+        return m
+
+    def ensure_fromlist(self, m, fromlist, recursive=0):
+        self.msg(4, "ensure_fromlist", m, fromlist, recursive)
+        for sub in fromlist:
+            if sub == "*":
+                if not recursive:
+                    all = self.find_all_submodules(m)
+                    if all:
+                        self.ensure_fromlist(m, all, 1)
+            elif not hasattr(m, sub):
+                subname = "%s.%s" % (m.__name__, sub)
+                submod = self.import_module(sub, subname, m)
+                if not submod:
+                    raise ImportError, "No module named " + subname
+
+    def find_all_submodules(self, m):
+        if not m.__path__:
+            return
+        modules = {}
+        # 'suffixes' used to be a list hardcoded to [".py", ".pyc", ".pyo"].
+        # But we must also collect Python extension modules - although
+        # we cannot separate normal dlls from Python extensions.
+        suffixes = []
+        for triple in imp.get_suffixes():
+            suffixes.append(triple[0])
+        for dir in m.__path__:
+            try:
+                names = os.listdir(dir)
+            except os.error:
+                self.msg(2, "can't list directory", dir)
+                continue
+            for name in names:
+                mod = None
+                for suff in suffixes:
+                    n = len(suff)
+                    if name[-n:] == suff:
+                        mod = name[:-n]
+                        break
+                if mod and mod != "__init__":
+                    modules[mod] = mod
+        return modules.keys()
+
+    def import_module(self, partname, fqname, parent):
+        self.msgin(3, "import_module", partname, fqname, parent)
+        try:
+            m = self.modules[fqname]
+        except KeyError:
+            pass
+        else:
+            self.msgout(3, "import_module ->", m)
+            return m
+        if self.badmodules.has_key(fqname):
+            self.msgout(3, "import_module -> None")
+            return None
+        if parent and parent.__path__ is None:
+            self.msgout(3, "import_module -> None")
+            return None
+        try:
+            fp, pathname, stuff = self.find_module(partname,
+                                                   parent and parent.__path__, parent)
+        except ImportError:
+            self.msgout(3, "import_module ->", None)
+            return None
+        try:
+            m = self.load_module(fqname, fp, pathname, stuff)
+        finally:
+            if fp: fp.close()
+        if parent:
+            setattr(parent, partname, m)
+        self.msgout(3, "import_module ->", m)
+        return m
+
+    def load_module(self, fqname, fp, pathname, (suffix, mode, type)):
+        self.msgin(2, "load_module", fqname, fp and "fp", pathname)
+        if type == imp.PKG_DIRECTORY:
+            m = self.load_package(fqname, pathname)
+            self.msgout(2, "load_module ->", m)
+            return m
+        if type == imp.PY_SOURCE:
+            co = compile(fp.read()+'\n', pathname, 'exec')
+        elif type == imp.PY_COMPILED:
+            if fp.read(4) != imp.get_magic():
+                self.msgout(2, "raise ImportError: Bad magic number", pathname)
+                raise ImportError, "Bad magic number in %s" % pathname
+            fp.read(4)
+            co = marshal.load(fp)
+        else:
+            co = None
+        m = self.add_module(fqname)
+        m.__file__ = pathname
+        if co:
+            if self.replace_paths:
+                co = self.replace_paths_in_code(co)
+            m.__code__ = co
+            self.scan_code(co, m)
+        self.msgout(2, "load_module ->", m)
+        return m
+
+    def _add_badmodule(self, name, caller):
+        if name not in self.badmodules:
+            self.badmodules[name] = {}
+        self.badmodules[name][caller.__name__] = 1
+
+    def _safe_import_hook(self, name, caller, fromlist):
+        # wrapper for self.import_hook() that won't raise ImportError
+        if name in self.badmodules:
+            self._add_badmodule(name, caller)
+            return
+        try:
+            self.import_hook(name, caller)
+        except ImportError, msg:
+            self.msg(2, "ImportError:", str(msg))
+            self._add_badmodule(name, caller)
+        else:
+            if fromlist:
+                for sub in fromlist:
+                    if sub in self.badmodules:
+                        self._add_badmodule(sub, caller)
+                        continue
+                    try:
+                        self.import_hook(name, caller, [sub])
+                    except ImportError, msg:
+                        self.msg(2, "ImportError:", str(msg))
+                        fullname = name + "." + sub
+                        self._add_badmodule(fullname, caller)
+
+    def scan_code(self, co, m):
+        code = co.co_code
+        n = len(code)
+        i = 0
+        fromlist = None
+        while i < n:
+            c = code[i]
+            i = i+1
+            op = ord(c)
+            if op >= dis.HAVE_ARGUMENT:
+                oparg = ord(code[i]) + ord(code[i+1])*256
+                i = i+2
+            if op == LOAD_CONST:
+                # An IMPORT_NAME is always preceded by a LOAD_CONST, it's
+                # a tuple of "from" names, or None for a regular import.
+                # The tuple may contain "*" for "from <mod> import *"
+                fromlist = co.co_consts[oparg]
+            elif op == IMPORT_NAME:
+                assert fromlist is None or type(fromlist) is tuple
+                name = co.co_names[oparg]
+                have_star = 0
+                if fromlist is not None:
+                    if "*" in fromlist:
+                        have_star = 1
+                    fromlist = [f for f in fromlist if f != "*"]
+                self._safe_import_hook(name, m, fromlist)
+                if have_star:
+                    # We've encountered an "import *". If it is a Python module,
+                    # the code has already been parsed and we can suck out the
+                    # global names.
+                    mm = None
+                    if m.__path__:
+                        # At this point we don't know whether 'name' is a
+                        # submodule of 'm' or a global module. Let's just try
+                        # the full name first.
+                        mm = self.modules.get(m.__name__ + "." + name)
+                    if mm is None:
+                        mm = self.modules.get(name)
+                    if mm is not None:
+                        m.globalnames.update(mm.globalnames)
+                        m.starimports.update(mm.starimports)
+                        if mm.__code__ is None:
+                            m.starimports[name] = 1
+                    else:
+                        m.starimports[name] = 1
+            elif op in STORE_OPS:
+                # keep track of all global names that are assigned to
+                name = co.co_names[oparg]
+                m.globalnames[name] = 1
+        for c in co.co_consts:
+            if isinstance(c, type(co)):
+                self.scan_code(c, m)
+
+    def load_package(self, fqname, pathname):
+        self.msgin(2, "load_package", fqname, pathname)
+        newname = replacePackageMap.get(fqname)
+        if newname:
+            fqname = newname
+        m = self.add_module(fqname)
+        m.__file__ = pathname
+        m.__path__ = [pathname]
+
+        # As per comment at top of file, simulate runtime __path__ additions.
+        m.__path__ = m.__path__ + packagePathMap.get(fqname, [])
+
+        fp, buf, stuff = self.find_module("__init__", m.__path__)
+        self.load_module(fqname, fp, buf, stuff)
+        self.msgout(2, "load_package ->", m)
+        return m
+
+    def add_module(self, fqname):
+        if self.modules.has_key(fqname):
+            return self.modules[fqname]
+        self.modules[fqname] = m = Module(fqname)
+        return m
+
+    def find_module(self, name, path, parent=None):
+        if parent is not None:
+            # assert path is not None
+            fullname = parent.__name__+'.'+name
+        else:
+            fullname = name
+        if fullname in self.excludes:
+            self.msgout(3, "find_module -> Excluded", fullname)
+            raise ImportError, name
+
+        if path is None:
+            if name in sys.builtin_module_names:
+                return (None, None, ("", "", imp.C_BUILTIN))
+
+            path = self.path
+        return imp.find_module(name, path)
+
+    def report(self):
+        """Print a report to stdout, listing the found modules with their
+        paths, as well as modules that are missing, or seem to be missing.
+        """
+        print
+        print "  %-25s %s" % ("Name", "File")
+        print "  %-25s %s" % ("----", "----")
+        # Print modules found
+        keys = self.modules.keys()
+        keys.sort()
+        for key in keys:
+            m = self.modules[key]
+            if m.__path__:
+                print "P",
+            else:
+                print "m",
+            print "%-25s" % key, m.__file__ or ""
+
+        # Print missing modules
+        missing, maybe = self.any_missing_maybe()
+        if missing:
+            print
+            print "Missing modules:"
+            for name in missing:
+                mods = self.badmodules[name].keys()
+                mods.sort()
+                print "?", name, "imported from", ', '.join(mods)
+        # Print modules that may be missing, but then again, maybe not...
+        if maybe:
+            print
+            print "Submodules thay appear to be missing, but could also be",
+            print "global names in the parent package:"
+            for name in maybe:
+                mods = self.badmodules[name].keys()
+                mods.sort()
+                print "?", name, "imported from", ', '.join(mods)
+
+    def any_missing(self):
+        """Return a list of modules that appear to be missing. Use
+        any_missing_maybe() if you want to know which modules are
+        certain to be missing, and which *may* be missing.
+        """
+        missing, maybe = self.any_missing_maybe()
+        return missing + maybe
+
+    def any_missing_maybe(self):
+        """Return two lists, one with modules that are certainly missing
+        and one with modules that *may* be missing. The latter names could
+        either be submodules *or* just global names in the package.
+
+        The reason it can't always be determined is that it's impossible to
+        tell which names are imported when "from module import *" is done
+        with an extension module, short of actually importing it.
+        """
+        missing = []
+        maybe = []
+        for name in self.badmodules:
+            if name in self.excludes:
+                continue
+            i = name.rfind(".")
+            if i < 0:
+                missing.append(name)
+                continue
+            subname = name[i+1:]
+            pkgname = name[:i]
+            pkg = self.modules.get(pkgname)
+            if pkg is not None:
+                if pkgname in self.badmodules[name]:
+                    # The package tried to import this module itself and
+                    # failed. It's definitely missing.
+                    missing.append(name)
+                elif subname in pkg.globalnames:
+                    # It's a global in the package: definitely not missing.
+                    pass
+                elif pkg.starimports:
+                    # It could be missing, but the package did an "import *"
+                    # from a non-Python module, so we simply can't be sure.
+                    maybe.append(name)
+                else:
+                    # It's not a global in the package, the package didn't
+                    # do funny star imports, it's very likely to be missing.
+                    # The symbol could be inserted into the package from the
+                    # outside, but since that's not good style we simply list
+                    # it missing.
+                    missing.append(name)
+            else:
+                missing.append(name)
+        missing.sort()
+        maybe.sort()
+        return missing, maybe
+
+    def replace_paths_in_code(self, co):
+        new_filename = original_filename = os.path.normpath(co.co_filename)
+        for f, r in self.replace_paths:
+            if original_filename.startswith(f):
+                new_filename = r + original_filename[len(f):]
+                break
+
+        if self.debug and original_filename not in self.processed_paths:
+            if new_filename != original_filename:
+                self.msgout(2, "co_filename %r changed to %r" \
+                                    % (original_filename,new_filename,))
+            else:
+                self.msgout(2, "co_filename %r remains unchanged" \
+                                    % (original_filename,))
+            self.processed_paths.append(original_filename)
+
+        consts = list(co.co_consts)
+        for i in range(len(consts)):
+            if isinstance(consts[i], type(co)):
+                consts[i] = self.replace_paths_in_code(consts[i])
+
+        return new.code(co.co_argcount, co.co_nlocals, co.co_stacksize,
+                         co.co_flags, co.co_code, tuple(consts), co.co_names,
+                         co.co_varnames, new_filename, co.co_name,
+                         co.co_firstlineno, co.co_lnotab,
+                         co.co_freevars, co.co_cellvars)
+
+
+def test():
+    # Parse command line
+    import getopt
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], "dmp:qx:")
+    except getopt.error, msg:
+        print msg
+        return
+
+    # Process options
+    debug = 1
+    domods = 0
+    addpath = []
+    exclude = []
+    for o, a in opts:
+        if o == '-d':
+            debug = debug + 1
+        if o == '-m':
+            domods = 1
+        if o == '-p':
+            addpath = addpath + a.split(os.pathsep)
+        if o == '-q':
+            debug = 0
+        if o == '-x':
+            exclude.append(a)
+
+    # Provide default arguments
+    if not args:
+        script = "hello.py"
+    else:
+        script = args[0]
+
+    # Set the path based on sys.path and the script directory
+    path = sys.path[:]
+    path[0] = os.path.dirname(script)
+    path = addpath + path
+    if debug > 1:
+        print "path:"
+        for item in path:
+            print "   ", repr(item)
+
+    # Create the module finder and turn its crank
+    mf = ModuleFinder(path, debug, exclude)
+    for arg in args[1:]:
+        if arg == '-m':
+            domods = 1
+            continue
+        if domods:
+            if arg[-2:] == '.*':
+                mf.import_hook(arg[:-2], None, ["*"])
+            else:
+                mf.import_hook(arg)
+        else:
+            mf.load_file(arg)
+    mf.run_script(script)
+    mf.report()
+    return mf  # for -i debugging
+
+
+if __name__ == '__main__':
+    try:
+        mf = test()
+    except KeyboardInterrupt:
+        print "\n[interrupt]"

Added: vendor/Python/current/Lib/msilib/__init__.py
===================================================================
--- vendor/Python/current/Lib/msilib/__init__.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/msilib/__init__.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,463 @@
+# -*- coding: iso-8859-1 -*-
+# Copyright (C) 2005 Martin v. Löwis
+# Licensed to PSF under a Contributor Agreement.
+from _msi import *
+import sets, os, string, re
+
+Win64=0
+
+# Partially taken from Wine
+datasizemask=      0x00ff
+type_valid=        0x0100
+type_localizable=  0x0200
+
+typemask=          0x0c00
+type_long=         0x0000
+type_short=        0x0400
+type_string=       0x0c00
+type_binary=       0x0800
+
+type_nullable=     0x1000
+type_key=          0x2000
+# XXX temporary, localizable?
+knownbits = datasizemask | type_valid | type_localizable | \
+            typemask | type_nullable | type_key
+
+class Table:
+    def __init__(self, name):
+        self.name = name
+        self.fields = []
+
+    def add_field(self, index, name, type):
+        self.fields.append((index,name,type))
+
+    def sql(self):
+        fields = []
+        keys = []
+        self.fields.sort()
+        fields = [None]*len(self.fields)
+        for index, name, type in self.fields:
+            index -= 1
+            unk = type & ~knownbits
+            if unk:
+                print "%s.%s unknown bits %x" % (self.name, name, unk)
+            size = type & datasizemask
+            dtype = type & typemask
+            if dtype == type_string:
+                if size:
+                    tname="CHAR(%d)" % size
+                else:
+                    tname="CHAR"
+            elif dtype == type_short:
+                assert size==2
+                tname = "SHORT"
+            elif dtype == type_long:
+                assert size==4
+                tname="LONG"
+            elif dtype == type_binary:
+                assert size==0
+                tname="OBJECT"
+            else:
+                tname="unknown"
+                print "%s.%sunknown integer type %d" % (self.name, name, size)
+            if type & type_nullable:
+                flags = ""
+            else:
+                flags = " NOT NULL"
+            if type & type_localizable:
+                flags += " LOCALIZABLE"
+            fields[index] = "`%s` %s%s" % (name, tname, flags)
+            if type & type_key:
+                keys.append("`%s`" % name)
+        fields = ", ".join(fields)
+        keys = ", ".join(keys)
+        return "CREATE TABLE %s (%s PRIMARY KEY %s)" % (self.name, fields, keys)
+
+    def create(self, db):
+        v = db.OpenView(self.sql())
+        v.Execute(None)
+        v.Close()
+
+class _Unspecified:pass
+def change_sequence(seq, action, seqno=_Unspecified, cond = _Unspecified):
+    "Change the sequence number of an action in a sequence list"
+    for i in range(len(seq)):
+        if seq[i][0] == action:
+            if cond is _Unspecified:
+                cond = seq[i][1]
+            if seqno is _Unspecified:
+                seqno = seq[i][2]
+            seq[i] = (action, cond, seqno)
+            return
+    raise ValueError, "Action not found in sequence"
+
+def add_data(db, table, values):
+    v = db.OpenView("SELECT * FROM `%s`" % table)
+    count = v.GetColumnInfo(MSICOLINFO_NAMES).GetFieldCount()
+    r = CreateRecord(count)
+    for value in values:
+        assert len(value) == count, value
+        for i in range(count):
+            field = value[i]
+            if isinstance(field, (int, long)):
+                r.SetInteger(i+1,field)
+            elif isinstance(field, basestring):
+                r.SetString(i+1,field)
+            elif field is None:
+                pass
+            elif isinstance(field, Binary):
+                r.SetStream(i+1, field.name)
+            else:
+                raise TypeError, "Unsupported type %s" % field.__class__.__name__
+        try:
+            v.Modify(MSIMODIFY_INSERT, r)
+        except Exception, e:
+            raise MSIError("Could not insert "+repr(values)+" into "+table)
+
+        r.ClearData()
+    v.Close()
+
+
+def add_stream(db, name, path):
+    v = db.OpenView("INSERT INTO _Streams (Name, Data) VALUES ('%s', ?)" % name)
+    r = CreateRecord(1)
+    r.SetStream(1, path)
+    v.Execute(r)
+    v.Close()
+
+def init_database(name, schema,
+                  ProductName, ProductCode, ProductVersion,
+                  Manufacturer):
+    try:
+        os.unlink(name)
+    except OSError:
+        pass
+    ProductCode = ProductCode.upper()
+    # Create the database
+    db = OpenDatabase(name, MSIDBOPEN_CREATE)
+    # Create the tables
+    for t in schema.tables:
+        t.create(db)
+    # Fill the validation table
+    add_data(db, "_Validation", schema._Validation_records)
+    # Initialize the summary information, allowing atmost 20 properties
+    si = db.GetSummaryInformation(20)
+    si.SetProperty(PID_TITLE, "Installation Database")
+    si.SetProperty(PID_SUBJECT, ProductName)
+    si.SetProperty(PID_AUTHOR, Manufacturer)
+    if Win64:
+        si.SetProperty(PID_TEMPLATE, "Intel64;1033")
+    else:
+        si.SetProperty(PID_TEMPLATE, "Intel;1033")
+    si.SetProperty(PID_REVNUMBER, gen_uuid())
+    si.SetProperty(PID_WORDCOUNT, 2) # long file names, compressed, original media
+    si.SetProperty(PID_PAGECOUNT, 200)
+    si.SetProperty(PID_APPNAME, "Python MSI Library")
+    # XXX more properties
+    si.Persist()
+    add_data(db, "Property", [
+        ("ProductName", ProductName),
+        ("ProductCode", ProductCode),
+        ("ProductVersion", ProductVersion),
+        ("Manufacturer", Manufacturer),
+        ("ProductLanguage", "1033")])
+    db.Commit()
+    return db
+
+def add_tables(db, module):
+    for table in module.tables:
+        add_data(db, table, getattr(module, table))
+
+def make_id(str):
+    #str = str.replace(".", "_") # colons are allowed
+    str = str.replace(" ", "_")
+    str = str.replace("-", "_")
+    if str[0] in string.digits:
+        str = "_"+str
+    assert re.match("^[A-Za-z_][A-Za-z0-9_.]*$", str), "FILE"+str
+    return str
+
+def gen_uuid():
+    return "{"+UuidCreate().upper()+"}"
+
+class CAB:
+    def __init__(self, name):
+        self.name = name
+        self.files = []
+        self.filenames = sets.Set()
+        self.index = 0
+
+    def gen_id(self, file):
+        logical = _logical = make_id(file)
+        pos = 1
+        while logical in self.filenames:
+            logical = "%s.%d" % (_logical, pos)
+            pos += 1
+        self.filenames.add(logical)
+        return logical
+
+    def append(self, full, file, logical):
+        if os.path.isdir(full):
+            return
+        if not logical:
+            logical = self.gen_id(file)
+        self.index += 1
+        self.files.append((full, logical))
+        return self.index, logical
+
+    def commit(self, db):
+        from tempfile import mktemp
+        filename = mktemp()
+        FCICreate(filename, self.files)
+        add_data(db, "Media",
+                [(1, self.index, None, "#"+self.name, None, None)])
+        add_stream(db, self.name, filename)
+        os.unlink(filename)
+        db.Commit()
+
+_directories = sets.Set()
+class Directory:
+    def __init__(self, db, cab, basedir, physical, _logical, default, componentflags=None):
+        """Create a new directory in the Directory table. There is a current component
+        at each point in time for the directory, which is either explicitly created
+        through start_component, or implicitly when files are added for the first
+        time. Files are added into the current component, and into the cab file.
+        To create a directory, a base directory object needs to be specified (can be
+        None), the path to the physical directory, and a logical directory name.
+        Default specifies the DefaultDir slot in the directory table. componentflags
+        specifies the default flags that new components get."""
+        index = 1
+        _logical = make_id(_logical)
+        logical = _logical
+        while logical in _directories:
+            logical = "%s%d" % (_logical, index)
+            index += 1
+        _directories.add(logical)
+        self.db = db
+        self.cab = cab
+        self.basedir = basedir
+        self.physical = physical
+        self.logical = logical
+        self.component = None
+        self.short_names = sets.Set()
+        self.ids = sets.Set()
+        self.keyfiles = {}
+        self.componentflags = componentflags
+        if basedir:
+            self.absolute = os.path.join(basedir.absolute, physical)
+            blogical = basedir.logical
+        else:
+            self.absolute = physical
+            blogical = None
+        add_data(db, "Directory", [(logical, blogical, default)])
+
+    def start_component(self, component = None, feature = None, flags = None, keyfile = None, uuid=None):
+        """Add an entry to the Component table, and make this component the current for this
+        directory. If no component name is given, the directory name is used. If no feature
+        is given, the current feature is used. If no flags are given, the directory's default
+        flags are used. If no keyfile is given, the KeyPath is left null in the Component
+        table."""
+        if flags is None:
+            flags = self.componentflags
+        if uuid is None:
+            uuid = gen_uuid()
+        else:
+            uuid = uuid.upper()
+        if component is None:
+            component = self.logical
+        self.component = component
+        if Win64:
+            flags |= 256
+        if keyfile:
+            keyid = self.cab.gen_id(self.absolute, keyfile)
+            self.keyfiles[keyfile] = keyid
+        else:
+            keyid = None
+        add_data(self.db, "Component",
+                        [(component, uuid, self.logical, flags, None, keyid)])
+        if feature is None:
+            feature = current_feature
+        add_data(self.db, "FeatureComponents",
+                        [(feature.id, component)])
+
+    def make_short(self, file):
+        parts = file.split(".")
+        if len(parts)>1:
+            suffix = parts[-1].upper()
+        else:
+            suffix = None
+        prefix = parts[0].upper()
+        if len(prefix) <= 8 and (not suffix or len(suffix)<=3):
+            if suffix:
+                file = prefix+"."+suffix
+            else:
+                file = prefix
+            assert file not in self.short_names
+        else:
+            prefix = prefix[:6]
+            if suffix:
+                suffix = suffix[:3]
+            pos = 1
+            while 1:
+                if suffix:
+                    file = "%s~%d.%s" % (prefix, pos, suffix)
+                else:
+                    file = "%s~%d" % (prefix, pos)
+                if file not in self.short_names: break
+                pos += 1
+                assert pos < 10000
+                if pos in (10, 100, 1000):
+                    prefix = prefix[:-1]
+        self.short_names.add(file)
+        assert not re.search(r'[\?|><:/*"+,;=\[\]]', file) # restrictions on short names
+        return file
+
+    def add_file(self, file, src=None, version=None, language=None):
+        """Add a file to the current component of the directory, starting a new one
+        one if there is no current component. By default, the file name in the source
+        and the file table will be identical. If the src file is specified, it is
+        interpreted relative to the current directory. Optionally, a version and a
+        language can be specified for the entry in the File table."""
+        if not self.component:
+            self.start_component(self.logical, current_feature, 0)
+        if not src:
+            # Allow relative paths for file if src is not specified
+            src = file
+            file = os.path.basename(file)
+        absolute = os.path.join(self.absolute, src)
+        assert not re.search(r'[\?|><:/*]"', file) # restrictions on long names
+        if self.keyfiles.has_key(file):
+            logical = self.keyfiles[file]
+        else:
+            logical = None
+        sequence, logical = self.cab.append(absolute, file, logical)
+        assert logical not in self.ids
+        self.ids.add(logical)
+        short = self.make_short(file)
+        full = "%s|%s" % (short, file)
+        filesize = os.stat(absolute).st_size
+        # constants.msidbFileAttributesVital
+        # Compressed omitted, since it is the database default
+        # could add r/o, system, hidden
+        attributes = 512
+        add_data(self.db, "File",
+                        [(logical, self.component, full, filesize, version,
+                         language, attributes, sequence)])
+        #if not version:
+        #    # Add hash if the file is not versioned
+        #    filehash = FileHash(absolute, 0)
+        #    add_data(self.db, "MsiFileHash",
+        #             [(logical, 0, filehash.IntegerData(1),
+        #               filehash.IntegerData(2), filehash.IntegerData(3),
+        #               filehash.IntegerData(4))])
+        # Automatically remove .pyc/.pyo files on uninstall (2)
+        # XXX: adding so many RemoveFile entries makes installer unbelievably
+        # slow. So instead, we have to use wildcard remove entries
+        if file.endswith(".py"):
+            add_data(self.db, "RemoveFile",
+                      [(logical+"c", self.component, "%sC|%sc" % (short, file),
+                        self.logical, 2),
+                       (logical+"o", self.component, "%sO|%so" % (short, file),
+                        self.logical, 2)])
+        return logical
+
+    def glob(self, pattern, exclude = None):
+        """Add a list of files to the current component as specified in the
+        glob pattern. Individual files can be excluded in the exclude list."""
+        files = glob.glob1(self.absolute, pattern)
+        for f in files:
+            if exclude and f in exclude: continue
+            self.add_file(f)
+        return files
+
+    def remove_pyc(self):
+        "Remove .pyc/.pyo files on uninstall"
+        add_data(self.db, "RemoveFile",
+                 [(self.component+"c", self.component, "*.pyc", self.logical, 2),
+                  (self.component+"o", self.component, "*.pyo", self.logical, 2)])
+
+class Binary:
+    def __init__(self, fname):
+        self.name = fname
+    def __repr__(self):
+        return 'msilib.Binary(os.path.join(dirname,"%s"))' % self.name
+
+class Feature:
+    def __init__(self, db, id, title, desc, display, level = 1,
+                 parent=None, directory = None, attributes=0):
+        self.id = id
+        if parent:
+            parent = parent.id
+        add_data(db, "Feature",
+                        [(id, parent, title, desc, display,
+                          level, directory, attributes)])
+    def set_current(self):
+        global current_feature
+        current_feature = self
+
+class Control:
+    def __init__(self, dlg, name):
+        self.dlg = dlg
+        self.name = name
+
+    def event(self, event, argument, condition = "1", ordering = None):
+        add_data(self.dlg.db, "ControlEvent",
+                 [(self.dlg.name, self.name, event, argument,
+                   condition, ordering)])
+
+    def mapping(self, event, attribute):
+        add_data(self.dlg.db, "EventMapping",
+                 [(self.dlg.name, self.name, event, attribute)])
+
+    def condition(self, action, condition):
+        add_data(self.dlg.db, "ControlCondition",
+                 [(self.dlg.name, self.name, action, condition)])
+
+class RadioButtonGroup(Control):
+    def __init__(self, dlg, name, property):
+        self.dlg = dlg
+        self.name = name
+        self.property = property
+        self.index = 1
+
+    def add(self, name, x, y, w, h, text, value = None):
+        if value is None:
+            value = name
+        add_data(self.dlg.db, "RadioButton",
+                 [(self.property, self.index, value,
+                   x, y, w, h, text, None)])
+        self.index += 1
+
+class Dialog:
+    def __init__(self, db, name, x, y, w, h, attr, title, first, default, cancel):
+        self.db = db
+        self.name = name
+        self.x, self.y, self.w, self.h = x,y,w,h
+        add_data(db, "Dialog", [(name, x,y,w,h,attr,title,first,default,cancel)])
+
+    def control(self, name, type, x, y, w, h, attr, prop, text, next, help):
+        add_data(self.db, "Control",
+                 [(self.name, name, type, x, y, w, h, attr, prop, text, next, help)])
+        return Control(self, name)
+
+    def text(self, name, x, y, w, h, attr, text):
+        return self.control(name, "Text", x, y, w, h, attr, None,
+                     text, None, None)
+
+    def bitmap(self, name, x, y, w, h, text):
+        return self.control(name, "Bitmap", x, y, w, h, 1, None, text, None, None)
+
+    def line(self, name, x, y, w, h):
+        return self.control(name, "Line", x, y, w, h, 1, None, None, None, None)
+
+    def pushbutton(self, name, x, y, w, h, attr, text, next):
+        return self.control(name, "PushButton", x, y, w, h, attr, None, text, next, None)
+
+    def radiogroup(self, name, x, y, w, h, attr, prop, text, next):
+        add_data(self.db, "Control",
+                 [(self.name, name, "RadioButtonGroup",
+                   x, y, w, h, attr, prop, text, next, None)])
+        return RadioButtonGroup(self, name, prop)
+
+    def checkbox(self, name, x, y, w, h, attr, prop, text, next):
+        return self.control(name, "CheckBox", x, y, w, h, attr, prop, text, next, None)

Added: vendor/Python/current/Lib/msilib/schema.py
===================================================================
--- vendor/Python/current/Lib/msilib/schema.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/msilib/schema.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1007 @@
+from . import Table
+
+_Validation = Table('_Validation')
+_Validation.add_field(1,'Table',11552)
+_Validation.add_field(2,'Column',11552)
+_Validation.add_field(3,'Nullable',3332)
+_Validation.add_field(4,'MinValue',4356)
+_Validation.add_field(5,'MaxValue',4356)
+_Validation.add_field(6,'KeyTable',7679)
+_Validation.add_field(7,'KeyColumn',5378)
+_Validation.add_field(8,'Category',7456)
+_Validation.add_field(9,'Set',7679)
+_Validation.add_field(10,'Description',7679)
+
+ActionText = Table('ActionText')
+ActionText.add_field(1,'Action',11592)
+ActionText.add_field(2,'Description',7936)
+ActionText.add_field(3,'Template',7936)
+
+AdminExecuteSequence = Table('AdminExecuteSequence')
+AdminExecuteSequence.add_field(1,'Action',11592)
+AdminExecuteSequence.add_field(2,'Condition',7679)
+AdminExecuteSequence.add_field(3,'Sequence',5378)
+
+Condition = Table('Condition')
+Condition.add_field(1,'Feature_',11558)
+Condition.add_field(2,'Level',9474)
+Condition.add_field(3,'Condition',7679)
+
+AdminUISequence = Table('AdminUISequence')
+AdminUISequence.add_field(1,'Action',11592)
+AdminUISequence.add_field(2,'Condition',7679)
+AdminUISequence.add_field(3,'Sequence',5378)
+
+AdvtExecuteSequence = Table('AdvtExecuteSequence')
+AdvtExecuteSequence.add_field(1,'Action',11592)
+AdvtExecuteSequence.add_field(2,'Condition',7679)
+AdvtExecuteSequence.add_field(3,'Sequence',5378)
+
+AdvtUISequence = Table('AdvtUISequence')
+AdvtUISequence.add_field(1,'Action',11592)
+AdvtUISequence.add_field(2,'Condition',7679)
+AdvtUISequence.add_field(3,'Sequence',5378)
+
+AppId = Table('AppId')
+AppId.add_field(1,'AppId',11558)
+AppId.add_field(2,'RemoteServerName',7679)
+AppId.add_field(3,'LocalService',7679)
+AppId.add_field(4,'ServiceParameters',7679)
+AppId.add_field(5,'DllSurrogate',7679)
+AppId.add_field(6,'ActivateAtStorage',5378)
+AppId.add_field(7,'RunAsInteractiveUser',5378)
+
+AppSearch = Table('AppSearch')
+AppSearch.add_field(1,'Property',11592)
+AppSearch.add_field(2,'Signature_',11592)
+
+Property = Table('Property')
+Property.add_field(1,'Property',11592)
+Property.add_field(2,'Value',3840)
+
+BBControl = Table('BBControl')
+BBControl.add_field(1,'Billboard_',11570)
+BBControl.add_field(2,'BBControl',11570)
+BBControl.add_field(3,'Type',3378)
+BBControl.add_field(4,'X',1282)
+BBControl.add_field(5,'Y',1282)
+BBControl.add_field(6,'Width',1282)
+BBControl.add_field(7,'Height',1282)
+BBControl.add_field(8,'Attributes',4356)
+BBControl.add_field(9,'Text',7986)
+
+Billboard = Table('Billboard')
+Billboard.add_field(1,'Billboard',11570)
+Billboard.add_field(2,'Feature_',3366)
+Billboard.add_field(3,'Action',7474)
+Billboard.add_field(4,'Ordering',5378)
+
+Feature = Table('Feature')
+Feature.add_field(1,'Feature',11558)
+Feature.add_field(2,'Feature_Parent',7462)
+Feature.add_field(3,'Title',8000)
+Feature.add_field(4,'Description',8191)
+Feature.add_field(5,'Display',5378)
+Feature.add_field(6,'Level',1282)
+Feature.add_field(7,'Directory_',7496)
+Feature.add_field(8,'Attributes',1282)
+
+Binary = Table('Binary')
+Binary.add_field(1,'Name',11592)
+Binary.add_field(2,'Data',2304)
+
+BindImage = Table('BindImage')
+BindImage.add_field(1,'File_',11592)
+BindImage.add_field(2,'Path',7679)
+
+File = Table('File')
+File.add_field(1,'File',11592)
+File.add_field(2,'Component_',3400)
+File.add_field(3,'FileName',4095)
+File.add_field(4,'FileSize',260)
+File.add_field(5,'Version',7496)
+File.add_field(6,'Language',7444)
+File.add_field(7,'Attributes',5378)
+File.add_field(8,'Sequence',1282)
+
+CCPSearch = Table('CCPSearch')
+CCPSearch.add_field(1,'Signature_',11592)
+
+CheckBox = Table('CheckBox')
+CheckBox.add_field(1,'Property',11592)
+CheckBox.add_field(2,'Value',7488)
+
+Class = Table('Class')
+Class.add_field(1,'CLSID',11558)
+Class.add_field(2,'Context',11552)
+Class.add_field(3,'Component_',11592)
+Class.add_field(4,'ProgId_Default',7679)
+Class.add_field(5,'Description',8191)
+Class.add_field(6,'AppId_',7462)
+Class.add_field(7,'FileTypeMask',7679)
+Class.add_field(8,'Icon_',7496)
+Class.add_field(9,'IconIndex',5378)
+Class.add_field(10,'DefInprocHandler',7456)
+Class.add_field(11,'Argument',7679)
+Class.add_field(12,'Feature_',3366)
+Class.add_field(13,'Attributes',5378)
+
+Component = Table('Component')
+Component.add_field(1,'Component',11592)
+Component.add_field(2,'ComponentId',7462)
+Component.add_field(3,'Directory_',3400)
+Component.add_field(4,'Attributes',1282)
+Component.add_field(5,'Condition',7679)
+Component.add_field(6,'KeyPath',7496)
+
+Icon = Table('Icon')
+Icon.add_field(1,'Name',11592)
+Icon.add_field(2,'Data',2304)
+
+ProgId = Table('ProgId')
+ProgId.add_field(1,'ProgId',11775)
+ProgId.add_field(2,'ProgId_Parent',7679)
+ProgId.add_field(3,'Class_',7462)
+ProgId.add_field(4,'Description',8191)
+ProgId.add_field(5,'Icon_',7496)
+ProgId.add_field(6,'IconIndex',5378)
+
+ComboBox = Table('ComboBox')
+ComboBox.add_field(1,'Property',11592)
+ComboBox.add_field(2,'Order',9474)
+ComboBox.add_field(3,'Value',3392)
+ComboBox.add_field(4,'Text',8000)
+
+CompLocator = Table('CompLocator')
+CompLocator.add_field(1,'Signature_',11592)
+CompLocator.add_field(2,'ComponentId',3366)
+CompLocator.add_field(3,'Type',5378)
+
+Complus = Table('Complus')
+Complus.add_field(1,'Component_',11592)
+Complus.add_field(2,'ExpType',13570)
+
+Directory = Table('Directory')
+Directory.add_field(1,'Directory',11592)
+Directory.add_field(2,'Directory_Parent',7496)
+Directory.add_field(3,'DefaultDir',4095)
+
+Control = Table('Control')
+Control.add_field(1,'Dialog_',11592)
+Control.add_field(2,'Control',11570)
+Control.add_field(3,'Type',3348)
+Control.add_field(4,'X',1282)
+Control.add_field(5,'Y',1282)
+Control.add_field(6,'Width',1282)
+Control.add_field(7,'Height',1282)
+Control.add_field(8,'Attributes',4356)
+Control.add_field(9,'Property',7474)
+Control.add_field(10,'Text',7936)
+Control.add_field(11,'Control_Next',7474)
+Control.add_field(12,'Help',7986)
+
+Dialog = Table('Dialog')
+Dialog.add_field(1,'Dialog',11592)
+Dialog.add_field(2,'HCentering',1282)
+Dialog.add_field(3,'VCentering',1282)
+Dialog.add_field(4,'Width',1282)
+Dialog.add_field(5,'Height',1282)
+Dialog.add_field(6,'Attributes',4356)
+Dialog.add_field(7,'Title',8064)
+Dialog.add_field(8,'Control_First',3378)
+Dialog.add_field(9,'Control_Default',7474)
+Dialog.add_field(10,'Control_Cancel',7474)
+
+ControlCondition = Table('ControlCondition')
+ControlCondition.add_field(1,'Dialog_',11592)
+ControlCondition.add_field(2,'Control_',11570)
+ControlCondition.add_field(3,'Action',11570)
+ControlCondition.add_field(4,'Condition',11775)
+
+ControlEvent = Table('ControlEvent')
+ControlEvent.add_field(1,'Dialog_',11592)
+ControlEvent.add_field(2,'Control_',11570)
+ControlEvent.add_field(3,'Event',11570)
+ControlEvent.add_field(4,'Argument',11775)
+ControlEvent.add_field(5,'Condition',15871)
+ControlEvent.add_field(6,'Ordering',5378)
+
+CreateFolder = Table('CreateFolder')
+CreateFolder.add_field(1,'Directory_',11592)
+CreateFolder.add_field(2,'Component_',11592)
+
+CustomAction = Table('CustomAction')
+CustomAction.add_field(1,'Action',11592)
+CustomAction.add_field(2,'Type',1282)
+CustomAction.add_field(3,'Source',7496)
+CustomAction.add_field(4,'Target',7679)
+
+DrLocator = Table('DrLocator')
+DrLocator.add_field(1,'Signature_',11592)
+DrLocator.add_field(2,'Parent',15688)
+DrLocator.add_field(3,'Path',15871)
+DrLocator.add_field(4,'Depth',5378)
+
+DuplicateFile = Table('DuplicateFile')
+DuplicateFile.add_field(1,'FileKey',11592)
+DuplicateFile.add_field(2,'Component_',3400)
+DuplicateFile.add_field(3,'File_',3400)
+DuplicateFile.add_field(4,'DestName',8191)
+DuplicateFile.add_field(5,'DestFolder',7496)
+
+Environment = Table('Environment')
+Environment.add_field(1,'Environment',11592)
+Environment.add_field(2,'Name',4095)
+Environment.add_field(3,'Value',8191)
+Environment.add_field(4,'Component_',3400)
+
+Error = Table('Error')
+Error.add_field(1,'Error',9474)
+Error.add_field(2,'Message',7936)
+
+EventMapping = Table('EventMapping')
+EventMapping.add_field(1,'Dialog_',11592)
+EventMapping.add_field(2,'Control_',11570)
+EventMapping.add_field(3,'Event',11570)
+EventMapping.add_field(4,'Attribute',3378)
+
+Extension = Table('Extension')
+Extension.add_field(1,'Extension',11775)
+Extension.add_field(2,'Component_',11592)
+Extension.add_field(3,'ProgId_',7679)
+Extension.add_field(4,'MIME_',7488)
+Extension.add_field(5,'Feature_',3366)
+
+MIME = Table('MIME')
+MIME.add_field(1,'ContentType',11584)
+MIME.add_field(2,'Extension_',3583)
+MIME.add_field(3,'CLSID',7462)
+
+FeatureComponents = Table('FeatureComponents')
+FeatureComponents.add_field(1,'Feature_',11558)
+FeatureComponents.add_field(2,'Component_',11592)
+
+FileSFPCatalog = Table('FileSFPCatalog')
+FileSFPCatalog.add_field(1,'File_',11592)
+FileSFPCatalog.add_field(2,'SFPCatalog_',11775)
+
+SFPCatalog = Table('SFPCatalog')
+SFPCatalog.add_field(1,'SFPCatalog',11775)
+SFPCatalog.add_field(2,'Catalog',2304)
+SFPCatalog.add_field(3,'Dependency',7424)
+
+Font = Table('Font')
+Font.add_field(1,'File_',11592)
+Font.add_field(2,'FontTitle',7552)
+
+IniFile = Table('IniFile')
+IniFile.add_field(1,'IniFile',11592)
+IniFile.add_field(2,'FileName',4095)
+IniFile.add_field(3,'DirProperty',7496)
+IniFile.add_field(4,'Section',3936)
+IniFile.add_field(5,'Key',3968)
+IniFile.add_field(6,'Value',4095)
+IniFile.add_field(7,'Action',1282)
+IniFile.add_field(8,'Component_',3400)
+
+IniLocator = Table('IniLocator')
+IniLocator.add_field(1,'Signature_',11592)
+IniLocator.add_field(2,'FileName',3583)
+IniLocator.add_field(3,'Section',3424)
+IniLocator.add_field(4,'Key',3456)
+IniLocator.add_field(5,'Field',5378)
+IniLocator.add_field(6,'Type',5378)
+
+InstallExecuteSequence = Table('InstallExecuteSequence')
+InstallExecuteSequence.add_field(1,'Action',11592)
+InstallExecuteSequence.add_field(2,'Condition',7679)
+InstallExecuteSequence.add_field(3,'Sequence',5378)
+
+InstallUISequence = Table('InstallUISequence')
+InstallUISequence.add_field(1,'Action',11592)
+InstallUISequence.add_field(2,'Condition',7679)
+InstallUISequence.add_field(3,'Sequence',5378)
+
+IsolatedComponent = Table('IsolatedComponent')
+IsolatedComponent.add_field(1,'Component_Shared',11592)
+IsolatedComponent.add_field(2,'Component_Application',11592)
+
+LaunchCondition = Table('LaunchCondition')
+LaunchCondition.add_field(1,'Condition',11775)
+LaunchCondition.add_field(2,'Description',4095)
+
+ListBox = Table('ListBox')
+ListBox.add_field(1,'Property',11592)
+ListBox.add_field(2,'Order',9474)
+ListBox.add_field(3,'Value',3392)
+ListBox.add_field(4,'Text',8000)
+
+ListView = Table('ListView')
+ListView.add_field(1,'Property',11592)
+ListView.add_field(2,'Order',9474)
+ListView.add_field(3,'Value',3392)
+ListView.add_field(4,'Text',8000)
+ListView.add_field(5,'Binary_',7496)
+
+LockPermissions = Table('LockPermissions')
+LockPermissions.add_field(1,'LockObject',11592)
+LockPermissions.add_field(2,'Table',11552)
+LockPermissions.add_field(3,'Domain',15871)
+LockPermissions.add_field(4,'User',11775)
+LockPermissions.add_field(5,'Permission',4356)
+
+Media = Table('Media')
+Media.add_field(1,'DiskId',9474)
+Media.add_field(2,'LastSequence',1282)
+Media.add_field(3,'DiskPrompt',8000)
+Media.add_field(4,'Cabinet',7679)
+Media.add_field(5,'VolumeLabel',7456)
+Media.add_field(6,'Source',7496)
+
+MoveFile = Table('MoveFile')
+MoveFile.add_field(1,'FileKey',11592)
+MoveFile.add_field(2,'Component_',3400)
+MoveFile.add_field(3,'SourceName',8191)
+MoveFile.add_field(4,'DestName',8191)
+MoveFile.add_field(5,'SourceFolder',7496)
+MoveFile.add_field(6,'DestFolder',3400)
+MoveFile.add_field(7,'Options',1282)
+
+MsiAssembly = Table('MsiAssembly')
+MsiAssembly.add_field(1,'Component_',11592)
+MsiAssembly.add_field(2,'Feature_',3366)
+MsiAssembly.add_field(3,'File_Manifest',7496)
+MsiAssembly.add_field(4,'File_Application',7496)
+MsiAssembly.add_field(5,'Attributes',5378)
+
+MsiAssemblyName = Table('MsiAssemblyName')
+MsiAssemblyName.add_field(1,'Component_',11592)
+MsiAssemblyName.add_field(2,'Name',11775)
+MsiAssemblyName.add_field(3,'Value',3583)
+
+MsiDigitalCertificate = Table('MsiDigitalCertificate')
+MsiDigitalCertificate.add_field(1,'DigitalCertificate',11592)
+MsiDigitalCertificate.add_field(2,'CertData',2304)
+
+MsiDigitalSignature = Table('MsiDigitalSignature')
+MsiDigitalSignature.add_field(1,'Table',11552)
+MsiDigitalSignature.add_field(2,'SignObject',11592)
+MsiDigitalSignature.add_field(3,'DigitalCertificate_',3400)
+MsiDigitalSignature.add_field(4,'Hash',6400)
+
+MsiFileHash = Table('MsiFileHash')
+MsiFileHash.add_field(1,'File_',11592)
+MsiFileHash.add_field(2,'Options',1282)
+MsiFileHash.add_field(3,'HashPart1',260)
+MsiFileHash.add_field(4,'HashPart2',260)
+MsiFileHash.add_field(5,'HashPart3',260)
+MsiFileHash.add_field(6,'HashPart4',260)
+
+MsiPatchHeaders = Table('MsiPatchHeaders')
+MsiPatchHeaders.add_field(1,'StreamRef',11558)
+MsiPatchHeaders.add_field(2,'Header',2304)
+
+ODBCAttribute = Table('ODBCAttribute')
+ODBCAttribute.add_field(1,'Driver_',11592)
+ODBCAttribute.add_field(2,'Attribute',11560)
+ODBCAttribute.add_field(3,'Value',8191)
+
+ODBCDriver = Table('ODBCDriver')
+ODBCDriver.add_field(1,'Driver',11592)
+ODBCDriver.add_field(2,'Component_',3400)
+ODBCDriver.add_field(3,'Description',3583)
+ODBCDriver.add_field(4,'File_',3400)
+ODBCDriver.add_field(5,'File_Setup',7496)
+
+ODBCDataSource = Table('ODBCDataSource')
+ODBCDataSource.add_field(1,'DataSource',11592)
+ODBCDataSource.add_field(2,'Component_',3400)
+ODBCDataSource.add_field(3,'Description',3583)
+ODBCDataSource.add_field(4,'DriverDescription',3583)
+ODBCDataSource.add_field(5,'Registration',1282)
+
+ODBCSourceAttribute = Table('ODBCSourceAttribute')
+ODBCSourceAttribute.add_field(1,'DataSource_',11592)
+ODBCSourceAttribute.add_field(2,'Attribute',11552)
+ODBCSourceAttribute.add_field(3,'Value',8191)
+
+ODBCTranslator = Table('ODBCTranslator')
+ODBCTranslator.add_field(1,'Translator',11592)
+ODBCTranslator.add_field(2,'Component_',3400)
+ODBCTranslator.add_field(3,'Description',3583)
+ODBCTranslator.add_field(4,'File_',3400)
+ODBCTranslator.add_field(5,'File_Setup',7496)
+
+Patch = Table('Patch')
+Patch.add_field(1,'File_',11592)
+Patch.add_field(2,'Sequence',9474)
+Patch.add_field(3,'PatchSize',260)
+Patch.add_field(4,'Attributes',1282)
+Patch.add_field(5,'Header',6400)
+Patch.add_field(6,'StreamRef_',7462)
+
+PatchPackage = Table('PatchPackage')
+PatchPackage.add_field(1,'PatchId',11558)
+PatchPackage.add_field(2,'Media_',1282)
+
+PublishComponent = Table('PublishComponent')
+PublishComponent.add_field(1,'ComponentId',11558)
+PublishComponent.add_field(2,'Qualifier',11775)
+PublishComponent.add_field(3,'Component_',11592)
+PublishComponent.add_field(4,'AppData',8191)
+PublishComponent.add_field(5,'Feature_',3366)
+
+RadioButton = Table('RadioButton')
+RadioButton.add_field(1,'Property',11592)
+RadioButton.add_field(2,'Order',9474)
+RadioButton.add_field(3,'Value',3392)
+RadioButton.add_field(4,'X',1282)
+RadioButton.add_field(5,'Y',1282)
+RadioButton.add_field(6,'Width',1282)
+RadioButton.add_field(7,'Height',1282)
+RadioButton.add_field(8,'Text',8000)
+RadioButton.add_field(9,'Help',7986)
+
+Registry = Table('Registry')
+Registry.add_field(1,'Registry',11592)
+Registry.add_field(2,'Root',1282)
+Registry.add_field(3,'Key',4095)
+Registry.add_field(4,'Name',8191)
+Registry.add_field(5,'Value',7936)
+Registry.add_field(6,'Component_',3400)
+
+RegLocator = Table('RegLocator')
+RegLocator.add_field(1,'Signature_',11592)
+RegLocator.add_field(2,'Root',1282)
+RegLocator.add_field(3,'Key',3583)
+RegLocator.add_field(4,'Name',7679)
+RegLocator.add_field(5,'Type',5378)
+
+RemoveFile = Table('RemoveFile')
+RemoveFile.add_field(1,'FileKey',11592)
+RemoveFile.add_field(2,'Component_',3400)
+RemoveFile.add_field(3,'FileName',8191)
+RemoveFile.add_field(4,'DirProperty',3400)
+RemoveFile.add_field(5,'InstallMode',1282)
+
+RemoveIniFile = Table('RemoveIniFile')
+RemoveIniFile.add_field(1,'RemoveIniFile',11592)
+RemoveIniFile.add_field(2,'FileName',4095)
+RemoveIniFile.add_field(3,'DirProperty',7496)
+RemoveIniFile.add_field(4,'Section',3936)
+RemoveIniFile.add_field(5,'Key',3968)
+RemoveIniFile.add_field(6,'Value',8191)
+RemoveIniFile.add_field(7,'Action',1282)
+RemoveIniFile.add_field(8,'Component_',3400)
+
+RemoveRegistry = Table('RemoveRegistry')
+RemoveRegistry.add_field(1,'RemoveRegistry',11592)
+RemoveRegistry.add_field(2,'Root',1282)
+RemoveRegistry.add_field(3,'Key',4095)
+RemoveRegistry.add_field(4,'Name',8191)
+RemoveRegistry.add_field(5,'Component_',3400)
+
+ReserveCost = Table('ReserveCost')
+ReserveCost.add_field(1,'ReserveKey',11592)
+ReserveCost.add_field(2,'Component_',3400)
+ReserveCost.add_field(3,'ReserveFolder',7496)
+ReserveCost.add_field(4,'ReserveLocal',260)
+ReserveCost.add_field(5,'ReserveSource',260)
+
+SelfReg = Table('SelfReg')
+SelfReg.add_field(1,'File_',11592)
+SelfReg.add_field(2,'Cost',5378)
+
+ServiceControl = Table('ServiceControl')
+ServiceControl.add_field(1,'ServiceControl',11592)
+ServiceControl.add_field(2,'Name',4095)
+ServiceControl.add_field(3,'Event',1282)
+ServiceControl.add_field(4,'Arguments',8191)
+ServiceControl.add_field(5,'Wait',5378)
+ServiceControl.add_field(6,'Component_',3400)
+
+ServiceInstall = Table('ServiceInstall')
+ServiceInstall.add_field(1,'ServiceInstall',11592)
+ServiceInstall.add_field(2,'Name',3583)
+ServiceInstall.add_field(3,'DisplayName',8191)
+ServiceInstall.add_field(4,'ServiceType',260)
+ServiceInstall.add_field(5,'StartType',260)
+ServiceInstall.add_field(6,'ErrorControl',260)
+ServiceInstall.add_field(7,'LoadOrderGroup',7679)
+ServiceInstall.add_field(8,'Dependencies',7679)
+ServiceInstall.add_field(9,'StartName',7679)
+ServiceInstall.add_field(10,'Password',7679)
+ServiceInstall.add_field(11,'Arguments',7679)
+ServiceInstall.add_field(12,'Component_',3400)
+ServiceInstall.add_field(13,'Description',8191)
+
+Shortcut = Table('Shortcut')
+Shortcut.add_field(1,'Shortcut',11592)
+Shortcut.add_field(2,'Directory_',3400)
+Shortcut.add_field(3,'Name',3968)
+Shortcut.add_field(4,'Component_',3400)
+Shortcut.add_field(5,'Target',3400)
+Shortcut.add_field(6,'Arguments',7679)
+Shortcut.add_field(7,'Description',8191)
+Shortcut.add_field(8,'Hotkey',5378)
+Shortcut.add_field(9,'Icon_',7496)
+Shortcut.add_field(10,'IconIndex',5378)
+Shortcut.add_field(11,'ShowCmd',5378)
+Shortcut.add_field(12,'WkDir',7496)
+
+Signature = Table('Signature')
+Signature.add_field(1,'Signature',11592)
+Signature.add_field(2,'FileName',3583)
+Signature.add_field(3,'MinVersion',7444)
+Signature.add_field(4,'MaxVersion',7444)
+Signature.add_field(5,'MinSize',4356)
+Signature.add_field(6,'MaxSize',4356)
+Signature.add_field(7,'MinDate',4356)
+Signature.add_field(8,'MaxDate',4356)
+Signature.add_field(9,'Languages',7679)
+
+TextStyle = Table('TextStyle')
+TextStyle.add_field(1,'TextStyle',11592)
+TextStyle.add_field(2,'FaceName',3360)
+TextStyle.add_field(3,'Size',1282)
+TextStyle.add_field(4,'Color',4356)
+TextStyle.add_field(5,'StyleBits',5378)
+
+TypeLib = Table('TypeLib')
+TypeLib.add_field(1,'LibID',11558)
+TypeLib.add_field(2,'Language',9474)
+TypeLib.add_field(3,'Component_',11592)
+TypeLib.add_field(4,'Version',4356)
+TypeLib.add_field(5,'Description',8064)
+TypeLib.add_field(6,'Directory_',7496)
+TypeLib.add_field(7,'Feature_',3366)
+TypeLib.add_field(8,'Cost',4356)
+
+UIText = Table('UIText')
+UIText.add_field(1,'Key',11592)
+UIText.add_field(2,'Text',8191)
+
+Upgrade = Table('Upgrade')
+Upgrade.add_field(1,'UpgradeCode',11558)
+Upgrade.add_field(2,'VersionMin',15636)
+Upgrade.add_field(3,'VersionMax',15636)
+Upgrade.add_field(4,'Language',15871)
+Upgrade.add_field(5,'Attributes',8452)
+Upgrade.add_field(6,'Remove',7679)
+Upgrade.add_field(7,'ActionProperty',3400)
+
+Verb = Table('Verb')
+Verb.add_field(1,'Extension_',11775)
+Verb.add_field(2,'Verb',11552)
+Verb.add_field(3,'Sequence',5378)
+Verb.add_field(4,'Command',8191)
+Verb.add_field(5,'Argument',8191)
+
+tables=[_Validation, ActionText, AdminExecuteSequence, Condition, AdminUISequence, AdvtExecuteSequence, AdvtUISequence, AppId, AppSearch, Property, BBControl, Billboard, Feature, Binary, BindImage, File, CCPSearch, CheckBox, Class, Component, Icon, ProgId, ComboBox, CompLocator, Complus, Directory, Control, Dialog, ControlCondition, ControlEvent, CreateFolder, CustomAction, DrLocator, DuplicateFile, Environment, Error, EventMapping, Extension, MIME, FeatureComponents, FileSFPCatalog, SFPCatalog, Font, IniFile, IniLocator, InstallExecuteSequence, InstallUISequence, IsolatedComponent, LaunchCondition, ListBox, ListView, LockPermissions, Media, MoveFile, MsiAssembly, MsiAssemblyName, MsiDigitalCertificate, MsiDigitalSignature, MsiFileHash, MsiPatchHeaders, ODBCAttribute, ODBCDriver, ODBCDataSource, ODBCSourceAttribute, ODBCTranslator, Patch, PatchPackage, PublishComponent, RadioButton, Registry, RegLocator, RemoveFile, RemoveIniFile, RemoveRegistry, ReserveCost, SelfReg, ServiceControl, ServiceInstall, Shortcut, Signature, TextStyle, TypeLib, UIText, Upgrade, Verb]
+
+_Validation_records = [
+(u'_Validation',u'Table',u'N',None, None, None, None, u'Identifier',None, u'Name of table',),
+(u'_Validation',u'Column',u'N',None, None, None, None, u'Identifier',None, u'Name of column',),
+(u'_Validation',u'Description',u'Y',None, None, None, None, u'Text',None, u'Description of column',),
+(u'_Validation',u'Set',u'Y',None, None, None, None, u'Text',None, u'Set of values that are permitted',),
+(u'_Validation',u'Category',u'Y',None, None, None, None, None, u'Text;Formatted;Template;Condition;Guid;Path;Version;Language;Identifier;Binary;UpperCase;LowerCase;Filename;Paths;AnyPath;WildCardFilename;RegPath;KeyFormatted;CustomSource;Property;Cabinet;Shortcut;URL',u'String category',),
+(u'_Validation',u'KeyColumn',u'Y',1,32,None, None, None, None, u'Column to which foreign key connects',),
+(u'_Validation',u'KeyTable',u'Y',None, None, None, None, u'Identifier',None, u'For foreign key, Name of table to which data must link',),
+(u'_Validation',u'MaxValue',u'Y',-2147483647,2147483647,None, None, None, None, u'Maximum value allowed',),
+(u'_Validation',u'MinValue',u'Y',-2147483647,2147483647,None, None, None, None, u'Minimum value allowed',),
+(u'_Validation',u'Nullable',u'N',None, None, None, None, None, u'Y;N;@',u'Whether the column is nullable',),
+(u'ActionText',u'Description',u'Y',None, None, None, None, u'Text',None, u'Localized description displayed in progress dialog and log when action is executing.',),
+(u'ActionText',u'Action',u'N',None, None, None, None, u'Identifier',None, u'Name of action to be described.',),
+(u'ActionText',u'Template',u'Y',None, None, None, None, u'Template',None, u'Optional localized format template used to format action data records for display during action execution.',),
+(u'AdminExecuteSequence',u'Action',u'N',None, None, None, None, u'Identifier',None, u'Name of action to invoke, either in the engine or the handler DLL.',),
+(u'AdminExecuteSequence',u'Condition',u'Y',None, None, None, None, u'Condition',None, u'Optional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData.',),
+(u'AdminExecuteSequence',u'Sequence',u'Y',-4,32767,None, None, None, None, u'Number that determines the sort order in which the actions are to be executed.  Leave blank to suppress action.',),
+(u'Condition',u'Condition',u'Y',None, None, None, None, u'Condition',None, u'Expression evaluated to determine if Level in the Feature table is to change.',),
+(u'Condition',u'Feature_',u'N',None, None, u'Feature',1,u'Identifier',None, u'Reference to a Feature entry in Feature table.',),
+(u'Condition',u'Level',u'N',0,32767,None, None, None, None, u'New selection Level to set in Feature table if Condition evaluates to TRUE.',),
+(u'AdminUISequence',u'Action',u'N',None, None, None, None, u'Identifier',None, u'Name of action to invoke, either in the engine or the handler DLL.',),
+(u'AdminUISequence',u'Condition',u'Y',None, None, None, None, u'Condition',None, u'Optional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData.',),
+(u'AdminUISequence',u'Sequence',u'Y',-4,32767,None, None, None, None, u'Number that determines the sort order in which the actions are to be executed.  Leave blank to suppress action.',),
+(u'AdvtExecuteSequence',u'Action',u'N',None, None, None, None, u'Identifier',None, u'Name of action to invoke, either in the engine or the handler DLL.',),
+(u'AdvtExecuteSequence',u'Condition',u'Y',None, None, None, None, u'Condition',None, u'Optional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData.',),
+(u'AdvtExecuteSequence',u'Sequence',u'Y',-4,32767,None, None, None, None, u'Number that determines the sort order in which the actions are to be executed.  Leave blank to suppress action.',),
+(u'AdvtUISequence',u'Action',u'N',None, None, None, None, u'Identifier',None, u'Name of action to invoke, either in the engine or the handler DLL.',),
+(u'AdvtUISequence',u'Condition',u'Y',None, None, None, None, u'Condition',None, u'Optional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData.',),
+(u'AdvtUISequence',u'Sequence',u'Y',-4,32767,None, None, None, None, u'Number that determines the sort order in which the actions are to be executed.  Leave blank to suppress action.',),
+(u'AppId',u'AppId',u'N',None, None, None, None, u'Guid',None, None, ),
+(u'AppId',u'ActivateAtStorage',u'Y',0,1,None, None, None, None, None, ),
+(u'AppId',u'DllSurrogate',u'Y',None, None, None, None, u'Text',None, None, ),
+(u'AppId',u'LocalService',u'Y',None, None, None, None, u'Text',None, None, ),
+(u'AppId',u'RemoteServerName',u'Y',None, None, None, None, u'Formatted',None, None, ),
+(u'AppId',u'RunAsInteractiveUser',u'Y',0,1,None, None, None, None, None, ),
+(u'AppId',u'ServiceParameters',u'Y',None, None, None, None, u'Text',None, None, ),
+(u'AppSearch',u'Property',u'N',None, None, None, None, u'Identifier',None, u'The property associated with a Signature',),
+(u'AppSearch',u'Signature_',u'N',None, None, u'Signature;RegLocator;IniLocator;DrLocator;CompLocator',1,u'Identifier',None, u'The Signature_ represents a unique file signature and is also the foreign key in the Signature,  RegLocator, IniLocator, CompLocator and the DrLocator tables.',),
+(u'Property',u'Property',u'N',None, None, None, None, u'Identifier',None, u'Name of property, uppercase if settable by launcher or loader.',),
+(u'Property',u'Value',u'N',None, None, None, None, u'Text',None, u'String value for property.  Never null or empty.',),
+(u'BBControl',u'Type',u'N',None, None, None, None, u'Identifier',None, u'The type of the control.',),
+(u'BBControl',u'Y',u'N',0,32767,None, None, None, None, u'Vertical coordinate of the upper left corner of the bounding rectangle of the control.',),
+(u'BBControl',u'Text',u'Y',None, None, None, None, u'Text',None, u'A string used to set the initial text contained within a control (if appropriate).',),
+(u'BBControl',u'BBControl',u'N',None, None, None, None, u'Identifier',None, u'Name of the control. This name must be unique within a billboard, but can repeat on different billboard.',),
+(u'BBControl',u'Attributes',u'Y',0,2147483647,None, None, None, None, u'A 32-bit word that specifies the attribute flags to be applied to this control.',),
+(u'BBControl',u'Billboard_',u'N',None, None, u'Billboard',1,u'Identifier',None, u'External key to the Billboard table, name of the billboard.',),
+(u'BBControl',u'Height',u'N',0,32767,None, None, None, None, u'Height of the bounding rectangle of the control.',),
+(u'BBControl',u'Width',u'N',0,32767,None, None, None, None, u'Width of the bounding rectangle of the control.',),
+(u'BBControl',u'X',u'N',0,32767,None, None, None, None, u'Horizontal coordinate of the upper left corner of the bounding rectangle of the control.',),
+(u'Billboard',u'Action',u'Y',None, None, None, None, u'Identifier',None, u'The name of an action. The billboard is displayed during the progress messages received from this action.',),
+(u'Billboard',u'Billboard',u'N',None, None, None, None, u'Identifier',None, u'Name of the billboard.',),
+(u'Billboard',u'Feature_',u'N',None, None, u'Feature',1,u'Identifier',None, u'An external key to the Feature Table. The billboard is shown only if this feature is being installed.',),
+(u'Billboard',u'Ordering',u'Y',0,32767,None, None, None, None, u'A positive integer. If there is more than one billboard corresponding to an action they will be shown in the order defined by this column.',),
+(u'Feature',u'Description',u'Y',None, None, None, None, u'Text',None, u'Longer descriptive text describing a visible feature item.',),
+(u'Feature',u'Attributes',u'N',None, None, None, None, None, u'0;1;2;4;5;6;8;9;10;16;17;18;20;21;22;24;25;26;32;33;34;36;37;38;48;49;50;52;53;54',u'Feature attributes',),
+(u'Feature',u'Feature',u'N',None, None, None, None, u'Identifier',None, u'Primary key used to identify a particular feature record.',),
+(u'Feature',u'Directory_',u'Y',None, None, u'Directory',1,u'UpperCase',None, u'The name of the Directory that can be configured by the UI. A non-null value will enable the browse button.',),
+(u'Feature',u'Level',u'N',0,32767,None, None, None, None, u'The install level at which record will be initially selected. An install level of 0 will disable an item and prevent its display.',),
+(u'Feature',u'Title',u'Y',None, None, None, None, u'Text',None, u'Short text identifying a visible feature item.',),
+(u'Feature',u'Display',u'Y',0,32767,None, None, None, None, u'Numeric sort order, used to force a specific display ordering.',),
+(u'Feature',u'Feature_Parent',u'Y',None, None, u'Feature',1,u'Identifier',None, u'Optional key of a parent record in the same table. If the parent is not selected, then the record will not be installed. Null indicates a root item.',),
+(u'Binary',u'Name',u'N',None, None, None, None, u'Identifier',None, u'Unique key identifying the binary data.',),
+(u'Binary',u'Data',u'N',None, None, None, None, u'Binary',None, u'The unformatted binary data.',),
+(u'BindImage',u'File_',u'N',None, None, u'File',1,u'Identifier',None, u'The index into the File table. This must be an executable file.',),
+(u'BindImage',u'Path',u'Y',None, None, None, None, u'Paths',None, u'A list of ;  delimited paths that represent the paths to be searched for the import DLLS. The list is usually a list of properties each enclosed within square brackets [] .',),
+(u'File',u'Sequence',u'N',1,32767,None, None, None, None, u'Sequence with respect to the media images; order must track cabinet order.',),
+(u'File',u'Attributes',u'Y',0,32767,None, None, None, None, u'Integer containing bit flags representing file attributes (with the decimal value of each bit position in parentheses)',),
+(u'File',u'File',u'N',None, None, None, None, u'Identifier',None, u'Primary key, non-localized token, must match identifier in cabinet.  For uncompressed files, this field is ignored.',),
+(u'File',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key referencing Component that controls the file.',),
+(u'File',u'FileName',u'N',None, None, None, None, u'Filename',None, u'File name used for installation, may be localized.  This may contain a "short name|long name" pair.',),
+(u'File',u'FileSize',u'N',0,2147483647,None, None, None, None, u'Size of file in bytes (long integer).',),
+(u'File',u'Language',u'Y',None, None, None, None, u'Language',None, u'List of decimal language Ids, comma-separated if more than one.',),
+(u'File',u'Version',u'Y',None, None, u'File',1,u'Version',None, u'Version string for versioned files;  Blank for unversioned files.',),
+(u'CCPSearch',u'Signature_',u'N',None, None, u'Signature;RegLocator;IniLocator;DrLocator;CompLocator',1,u'Identifier',None, u'The Signature_ represents a unique file signature and is also the foreign key in the Signature,  RegLocator, IniLocator, CompLocator and the DrLocator tables.',),
+(u'CheckBox',u'Property',u'N',None, None, None, None, u'Identifier',None, u'A named property to be tied to the item.',),
+(u'CheckBox',u'Value',u'Y',None, None, None, None, u'Formatted',None, u'The value string associated with the item.',),
+(u'Class',u'Description',u'Y',None, None, None, None, u'Text',None, u'Localized description for the Class.',),
+(u'Class',u'Attributes',u'Y',None, 32767,None, None, None, None, u'Class registration attributes.',),
+(u'Class',u'Feature_',u'N',None, None, u'Feature',1,u'Identifier',None, u'Required foreign key into the Feature Table, specifying the feature to validate or install in order for the CLSID factory to be operational.',),
+(u'Class',u'AppId_',u'Y',None, None, u'AppId',1,u'Guid',None, u'Optional AppID containing DCOM information for associated application (string GUID).',),
+(u'Class',u'Argument',u'Y',None, None, None, None, u'Formatted',None, u'optional argument for LocalServers.',),
+(u'Class',u'CLSID',u'N',None, None, None, None, u'Guid',None, u'The CLSID of an OLE factory.',),
+(u'Class',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Required foreign key into the Component Table, specifying the component for which to return a path when called through LocateComponent.',),
+(u'Class',u'Context',u'N',None, None, None, None, u'Identifier',None, u'The numeric server context for this server. CLSCTX_xxxx',),
+(u'Class',u'DefInprocHandler',u'Y',None, None, None, None, u'Filename',u'1;2;3',u'Optional default inproc handler.  Only optionally provided if Context=CLSCTX_LOCAL_SERVER.  Typically "ole32.dll" or "mapi32.dll"',),
+(u'Class',u'FileTypeMask',u'Y',None, None, None, None, u'Text',None, u'Optional string containing information for the HKCRthis CLSID) key. If multiple patterns exist, they must be delimited by a semicolon, and numeric subkeys will be generated: 0,1,2...',),
+(u'Class',u'Icon_',u'Y',None, None, u'Icon',1,u'Identifier',None, u'Optional foreign key into the Icon Table, specifying the icon file associated with this CLSID. Will be written under the DefaultIcon key.',),
+(u'Class',u'IconIndex',u'Y',-32767,32767,None, None, None, None, u'Optional icon index.',),
+(u'Class',u'ProgId_Default',u'Y',None, None, u'ProgId',1,u'Text',None, u'Optional ProgId associated with this CLSID.',),
+(u'Component',u'Condition',u'Y',None, None, None, None, u'Condition',None, u"A conditional statement that will disable this component if the specified condition evaluates to the 'True' state. If a component is disabled, it will not be installed, regardless of the 'Action' state associated with the component.",),
+(u'Component',u'Attributes',u'N',None, None, None, None, None, None, u'Remote execution option, one of irsEnum',),
+(u'Component',u'Component',u'N',None, None, None, None, u'Identifier',None, u'Primary key used to identify a particular component record.',),
+(u'Component',u'ComponentId',u'Y',None, None, None, None, u'Guid',None, u'A string GUID unique to this component, version, and language.',),
+(u'Component',u'Directory_',u'N',None, None, u'Directory',1,u'Identifier',None, u'Required key of a Directory table record. This is actually a property name whose value contains the actual path, set either by the AppSearch action or with the default setting obtained from the Directory table.',),
+(u'Component',u'KeyPath',u'Y',None, None, u'File;Registry;ODBCDataSource',1,u'Identifier',None, u'Either the primary key into the File table, Registry table, or ODBCDataSource table. This extract path is stored when the component is installed, and is used to detect the presence of the component and to return the path to it.',),
+(u'Icon',u'Name',u'N',None, None, None, None, u'Identifier',None, u'Primary key. Name of the icon file.',),
+(u'Icon',u'Data',u'N',None, None, None, None, u'Binary',None, u'Binary stream. The binary icon data in PE (.DLL or .EXE) or icon (.ICO) format.',),
+(u'ProgId',u'Description',u'Y',None, None, None, None, u'Text',None, u'Localized description for the Program identifier.',),
+(u'ProgId',u'Icon_',u'Y',None, None, u'Icon',1,u'Identifier',None, u'Optional foreign key into the Icon Table, specifying the icon file associated with this ProgId. Will be written under the DefaultIcon key.',),
+(u'ProgId',u'IconIndex',u'Y',-32767,32767,None, None, None, None, u'Optional icon index.',),
+(u'ProgId',u'ProgId',u'N',None, None, None, None, u'Text',None, u'The Program Identifier. Primary key.',),
+(u'ProgId',u'Class_',u'Y',None, None, u'Class',1,u'Guid',None, u'The CLSID of an OLE factory corresponding to the ProgId.',),
+(u'ProgId',u'ProgId_Parent',u'Y',None, None, u'ProgId',1,u'Text',None, u'The Parent Program Identifier. If specified, the ProgId column becomes a version independent prog id.',),
+(u'ComboBox',u'Text',u'Y',None, None, None, None, u'Formatted',None, u'The visible text to be assigned to the item. Optional. If this entry or the entire column is missing, the text is the same as the value.',),
+(u'ComboBox',u'Property',u'N',None, None, None, None, u'Identifier',None, u'A named property to be tied to this item. All the items tied to the same property become part of the same combobox.',),
+(u'ComboBox',u'Value',u'N',None, None, None, None, u'Formatted',None, u'The value string associated with this item. Selecting the line will set the associated property to this value.',),
+(u'ComboBox',u'Order',u'N',1,32767,None, None, None, None, u'A positive integer used to determine the ordering of the items within one list.\tThe integers do not have to be consecutive.',),
+(u'CompLocator',u'Type',u'Y',0,1,None, None, None, None, u'A boolean value that determines if the registry value is a filename or a directory location.',),
+(u'CompLocator',u'Signature_',u'N',None, None, None, None, u'Identifier',None, u'The table key. The Signature_ represents a unique file signature and is also the foreign key in the Signature table.',),
+(u'CompLocator',u'ComponentId',u'N',None, None, None, None, u'Guid',None, u'A string GUID unique to this component, version, and language.',),
+(u'Complus',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key referencing Component that controls the ComPlus component.',),
+(u'Complus',u'ExpType',u'Y',0,32767,None, None, None, None, u'ComPlus component attributes.',),
+(u'Directory',u'Directory',u'N',None, None, None, None, u'Identifier',None, u'Unique identifier for directory entry, primary key. If a property by this name is defined, it contains the full path to the directory.',),
+(u'Directory',u'DefaultDir',u'N',None, None, None, None, u'DefaultDir',None, u"The default sub-path under parent's path.",),
+(u'Directory',u'Directory_Parent',u'Y',None, None, u'Directory',1,u'Identifier',None, u'Reference to the entry in this table specifying the default parent directory. A record parented to itself or with a Null parent represents a root of the install tree.',),
+(u'Control',u'Type',u'N',None, None, None, None, u'Identifier',None, u'The type of the control.',),
+(u'Control',u'Y',u'N',0,32767,None, None, None, None, u'Vertical coordinate of the upper left corner of the bounding rectangle of the control.',),
+(u'Control',u'Text',u'Y',None, None, None, None, u'Formatted',None, u'A string used to set the initial text contained within a control (if appropriate).',),
+(u'Control',u'Property',u'Y',None, None, None, None, u'Identifier',None, u'The name of a defined property to be linked to this control. ',),
+(u'Control',u'Attributes',u'Y',0,2147483647,None, None, None, None, u'A 32-bit word that specifies the attribute flags to be applied to this control.',),
+(u'Control',u'Height',u'N',0,32767,None, None, None, None, u'Height of the bounding rectangle of the control.',),
+(u'Control',u'Width',u'N',0,32767,None, None, None, None, u'Width of the bounding rectangle of the control.',),
+(u'Control',u'X',u'N',0,32767,None, None, None, None, u'Horizontal coordinate of the upper left corner of the bounding rectangle of the control.',),
+(u'Control',u'Control',u'N',None, None, None, None, u'Identifier',None, u'Name of the control. This name must be unique within a dialog, but can repeat on different dialogs. ',),
+(u'Control',u'Control_Next',u'Y',None, None, u'Control',2,u'Identifier',None, u'The name of an other control on the same dialog. This link defines the tab order of the controls. The links have to form one or more cycles!',),
+(u'Control',u'Dialog_',u'N',None, None, u'Dialog',1,u'Identifier',None, u'External key to the Dialog table, name of the dialog.',),
+(u'Control',u'Help',u'Y',None, None, None, None, u'Text',None, u'The help strings used with the button. The text is optional. ',),
+(u'Dialog',u'Attributes',u'Y',0,2147483647,None, None, None, None, u'A 32-bit word that specifies the attribute flags to be applied to this dialog.',),
+(u'Dialog',u'Height',u'N',0,32767,None, None, None, None, u'Height of the bounding rectangle of the dialog.',),
+(u'Dialog',u'Width',u'N',0,32767,None, None, None, None, u'Width of the bounding rectangle of the dialog.',),
+(u'Dialog',u'Dialog',u'N',None, None, None, None, u'Identifier',None, u'Name of the dialog.',),
+(u'Dialog',u'Control_Cancel',u'Y',None, None, u'Control',2,u'Identifier',None, u'Defines the cancel control. Hitting escape or clicking on the close icon on the dialog is equivalent to pushing this button.',),
+(u'Dialog',u'Control_Default',u'Y',None, None, u'Control',2,u'Identifier',None, u'Defines the default control. Hitting return is equivalent to pushing this button.',),
+(u'Dialog',u'Control_First',u'N',None, None, u'Control',2,u'Identifier',None, u'Defines the control that has the focus when the dialog is created.',),
+(u'Dialog',u'HCentering',u'N',0,100,None, None, None, None, u'Horizontal position of the dialog on a 0-100 scale. 0 means left end, 100 means right end of the screen, 50 center.',),
+(u'Dialog',u'Title',u'Y',None, None, None, None, u'Formatted',None, u"A text string specifying the title to be displayed in the title bar of the dialog's window.",),
+(u'Dialog',u'VCentering',u'N',0,100,None, None, None, None, u'Vertical position of the dialog on a 0-100 scale. 0 means top end, 100 means bottom end of the screen, 50 center.',),
+(u'ControlCondition',u'Action',u'N',None, None, None, None, None, u'Default;Disable;Enable;Hide;Show',u'The desired action to be taken on the specified control.',),
+(u'ControlCondition',u'Condition',u'N',None, None, None, None, u'Condition',None, u'A standard conditional statement that specifies under which conditions the action should be triggered.',),
+(u'ControlCondition',u'Dialog_',u'N',None, None, u'Dialog',1,u'Identifier',None, u'A foreign key to the Dialog table, name of the dialog.',),
+(u'ControlCondition',u'Control_',u'N',None, None, u'Control',2,u'Identifier',None, u'A foreign key to the Control table, name of the control.',),
+(u'ControlEvent',u'Condition',u'Y',None, None, None, None, u'Condition',None, u'A standard conditional statement that specifies under which conditions an event should be triggered.',),
+(u'ControlEvent',u'Ordering',u'Y',0,2147483647,None, None, None, None, u'An integer used to order several events tied to the same control. Can be left blank.',),
+(u'ControlEvent',u'Argument',u'N',None, None, None, None, u'Formatted',None, u'A value to be used as a modifier when triggering a particular event.',),
+(u'ControlEvent',u'Dialog_',u'N',None, None, u'Dialog',1,u'Identifier',None, u'A foreign key to the Dialog table, name of the dialog.',),
+(u'ControlEvent',u'Control_',u'N',None, None, u'Control',2,u'Identifier',None, u'A foreign key to the Control table, name of the control',),
+(u'ControlEvent',u'Event',u'N',None, None, None, None, u'Formatted',None, u'An identifier that specifies the type of the event that should take place when the user interacts with control specified by the first two entries.',),
+(u'CreateFolder',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key into the Component table.',),
+(u'CreateFolder',u'Directory_',u'N',None, None, u'Directory',1,u'Identifier',None, u'Primary key, could be foreign key into the Directory table.',),
+(u'CustomAction',u'Type',u'N',1,16383,None, None, None, None, u'The numeric custom action type, consisting of source location, code type, entry, option flags.',),
+(u'CustomAction',u'Action',u'N',None, None, None, None, u'Identifier',None, u'Primary key, name of action, normally appears in sequence table unless private use.',),
+(u'CustomAction',u'Source',u'Y',None, None, None, None, u'CustomSource',None, u'The table reference of the source of the code.',),
+(u'CustomAction',u'Target',u'Y',None, None, None, None, u'Formatted',None, u'Excecution parameter, depends on the type of custom action',),
+(u'DrLocator',u'Signature_',u'N',None, None, None, None, u'Identifier',None, u'The Signature_ represents a unique file signature and is also the foreign key in the Signature table.',),
+(u'DrLocator',u'Path',u'Y',None, None, None, None, u'AnyPath',None, u'The path on the user system. This is a either a subpath below the value of the Parent or a full path. The path may contain properties enclosed within [ ] that will be expanded.',),
+(u'DrLocator',u'Depth',u'Y',0,32767,None, None, None, None, u'The depth below the path to which the Signature_ is recursively searched. If absent, the depth is assumed to be 0.',),
+(u'DrLocator',u'Parent',u'Y',None, None, None, None, u'Identifier',None, u'The parent file signature. It is also a foreign key in the Signature table. If null and the Path column does not expand to a full path, then all the fixed drives of the user system are searched using the Path.',),
+(u'DuplicateFile',u'File_',u'N',None, None, u'File',1,u'Identifier',None, u'Foreign key referencing the source file to be duplicated.',),
+(u'DuplicateFile',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key referencing Component that controls the duplicate file.',),
+(u'DuplicateFile',u'DestFolder',u'Y',None, None, None, None, u'Identifier',None, u'Name of a property whose value is assumed to resolve to the full pathname to a destination folder.',),
+(u'DuplicateFile',u'DestName',u'Y',None, None, None, None, u'Filename',None, u'Filename to be given to the duplicate file.',),
+(u'DuplicateFile',u'FileKey',u'N',None, None, None, None, u'Identifier',None, u'Primary key used to identify a particular file entry',),
+(u'Environment',u'Name',u'N',None, None, None, None, u'Text',None, u'The name of the environmental value.',),
+(u'Environment',u'Value',u'Y',None, None, None, None, u'Formatted',None, u'The value to set in the environmental settings.',),
+(u'Environment',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key into the Component table referencing component that controls the installing of the environmental value.',),
+(u'Environment',u'Environment',u'N',None, None, None, None, u'Identifier',None, u'Unique identifier for the environmental variable setting',),
+(u'Error',u'Error',u'N',0,32767,None, None, None, None, u'Integer error number, obtained from header file IError(...) macros.',),
+(u'Error',u'Message',u'Y',None, None, None, None, u'Template',None, u'Error formatting template, obtained from user ed. or localizers.',),
+(u'EventMapping',u'Dialog_',u'N',None, None, u'Dialog',1,u'Identifier',None, u'A foreign key to the Dialog table, name of the Dialog.',),
+(u'EventMapping',u'Control_',u'N',None, None, u'Control',2,u'Identifier',None, u'A foreign key to the Control table, name of the control.',),
+(u'EventMapping',u'Event',u'N',None, None, None, None, u'Identifier',None, u'An identifier that specifies the type of the event that the control subscribes to.',),
+(u'EventMapping',u'Attribute',u'N',None, None, None, None, u'Identifier',None, u'The name of the control attribute, that is set when this event is received.',),
+(u'Extension',u'Feature_',u'N',None, None, u'Feature',1,u'Identifier',None, u'Required foreign key into the Feature Table, specifying the feature to validate or install in order for the CLSID factory to be operational.',),
+(u'Extension',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Required foreign key into the Component Table, specifying the component for which to return a path when called through LocateComponent.',),
+(u'Extension',u'Extension',u'N',None, None, None, None, u'Text',None, u'The extension associated with the table row.',),
+(u'Extension',u'MIME_',u'Y',None, None, u'MIME',1,u'Text',None, u'Optional Context identifier, typically "type/format" associated with the extension',),
+(u'Extension',u'ProgId_',u'Y',None, None, u'ProgId',1,u'Text',None, u'Optional ProgId associated with this extension.',),
+(u'MIME',u'CLSID',u'Y',None, None, None, None, u'Guid',None, u'Optional associated CLSID.',),
+(u'MIME',u'ContentType',u'N',None, None, None, None, u'Text',None, u'Primary key. Context identifier, typically "type/format".',),
+(u'MIME',u'Extension_',u'N',None, None, u'Extension',1,u'Text',None, u'Optional associated extension (without dot)',),
+(u'FeatureComponents',u'Feature_',u'N',None, None, u'Feature',1,u'Identifier',None, u'Foreign key into Feature table.',),
+(u'FeatureComponents',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key into Component table.',),
+(u'FileSFPCatalog',u'File_',u'N',None, None, u'File',1,u'Identifier',None, u'File associated with the catalog',),
+(u'FileSFPCatalog',u'SFPCatalog_',u'N',None, None, u'SFPCatalog',1,u'Filename',None, u'Catalog associated with the file',),
+(u'SFPCatalog',u'SFPCatalog',u'N',None, None, None, None, u'Filename',None, u'File name for the catalog.',),
+(u'SFPCatalog',u'Catalog',u'N',None, None, None, None, u'Binary',None, u'SFP Catalog',),
+(u'SFPCatalog',u'Dependency',u'Y',None, None, None, None, u'Formatted',None, u'Parent catalog - only used by SFP',),
+(u'Font',u'File_',u'N',None, None, u'File',1,u'Identifier',None, u'Primary key, foreign key into File table referencing font file.',),
+(u'Font',u'FontTitle',u'Y',None, None, None, None, u'Text',None, u'Font name.',),
+(u'IniFile',u'Action',u'N',None, None, None, None, None, u'0;1;3',u'The type of modification to be made, one of iifEnum',),
+(u'IniFile',u'Value',u'N',None, None, None, None, u'Formatted',None, u'The value to be written.',),
+(u'IniFile',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key into the Component table referencing component that controls the installing of the .INI value.',),
+(u'IniFile',u'FileName',u'N',None, None, None, None, u'Filename',None, u'The .INI file name in which to write the information',),
+(u'IniFile',u'IniFile',u'N',None, None, None, None, u'Identifier',None, u'Primary key, non-localized token.',),
+(u'IniFile',u'DirProperty',u'Y',None, None, None, None, u'Identifier',None, u'Foreign key into the Directory table denoting the directory where the .INI file is.',),
+(u'IniFile',u'Key',u'N',None, None, None, None, u'Formatted',None, u'The .INI file key below Section.',),
+(u'IniFile',u'Section',u'N',None, None, None, None, u'Formatted',None, u'The .INI file Section.',),
+(u'IniLocator',u'Type',u'Y',0,2,None, None, None, None, u'An integer value that determines if the .INI value read is a filename or a directory location or to be used as is w/o interpretation.',),
+(u'IniLocator',u'Signature_',u'N',None, None, None, None, u'Identifier',None, u'The table key. The Signature_ represents a unique file signature and is also the foreign key in the Signature table.',),
+(u'IniLocator',u'FileName',u'N',None, None, None, None, u'Filename',None, u'The .INI file name.',),
+(u'IniLocator',u'Key',u'N',None, None, None, None, u'Text',None, u'Key value (followed by an equals sign in INI file).',),
+(u'IniLocator',u'Section',u'N',None, None, None, None, u'Text',None, u'Section name within in file (within square brackets in INI file).',),
+(u'IniLocator',u'Field',u'Y',0,32767,None, None, None, None, u'The field in the .INI line. If Field is null or 0 the entire line is read.',),
+(u'InstallExecuteSequence',u'Action',u'N',None, None, None, None, u'Identifier',None, u'Name of action to invoke, either in the engine or the handler DLL.',),
+(u'InstallExecuteSequence',u'Condition',u'Y',None, None, None, None, u'Condition',None, u'Optional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData.',),
+(u'InstallExecuteSequence',u'Sequence',u'Y',-4,32767,None, None, None, None, u'Number that determines the sort order in which the actions are to be executed.  Leave blank to suppress action.',),
+(u'InstallUISequence',u'Action',u'N',None, None, None, None, u'Identifier',None, u'Name of action to invoke, either in the engine or the handler DLL.',),
+(u'InstallUISequence',u'Condition',u'Y',None, None, None, None, u'Condition',None, u'Optional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData.',),
+(u'InstallUISequence',u'Sequence',u'Y',-4,32767,None, None, None, None, u'Number that determines the sort order in which the actions are to be executed.  Leave blank to suppress action.',),
+(u'IsolatedComponent',u'Component_Application',u'N',None, None, u'Component',1,u'Identifier',None, u'Key to Component table item for application',),
+(u'IsolatedComponent',u'Component_Shared',u'N',None, None, u'Component',1,u'Identifier',None, u'Key to Component table item to be isolated',),
+(u'LaunchCondition',u'Description',u'N',None, None, None, None, u'Formatted',None, u'Localizable text to display when condition fails and install must abort.',),
+(u'LaunchCondition',u'Condition',u'N',None, None, None, None, u'Condition',None, u'Expression which must evaluate to TRUE in order for install to commence.',),
+(u'ListBox',u'Text',u'Y',None, None, None, None, u'Text',None, u'The visible text to be assigned to the item. Optional. If this entry or the entire column is missing, the text is the same as the value.',),
+(u'ListBox',u'Property',u'N',None, None, None, None, u'Identifier',None, u'A named property to be tied to this item. All the items tied to the same property become part of the same listbox.',),
+(u'ListBox',u'Value',u'N',None, None, None, None, u'Formatted',None, u'The value string associated with this item. Selecting the line will set the associated property to this value.',),
+(u'ListBox',u'Order',u'N',1,32767,None, None, None, None, u'A positive integer used to determine the ordering of the items within one list..The integers do not have to be consecutive.',),
+(u'ListView',u'Text',u'Y',None, None, None, None, u'Text',None, u'The visible text to be assigned to the item. Optional. If this entry or the entire column is missing, the text is the same as the value.',),
+(u'ListView',u'Property',u'N',None, None, None, None, u'Identifier',None, u'A named property to be tied to this item. All the items tied to the same property become part of the same listview.',),
+(u'ListView',u'Value',u'N',None, None, None, None, u'Identifier',None, u'The value string associated with this item. Selecting the line will set the associated property to this value.',),
+(u'ListView',u'Order',u'N',1,32767,None, None, None, None, u'A positive integer used to determine the ordering of the items within one list..The integers do not have to be consecutive.',),
+(u'ListView',u'Binary_',u'Y',None, None, u'Binary',1,u'Identifier',None, u'The name of the icon to be displayed with the icon. The binary information is looked up from the Binary Table.',),
+(u'LockPermissions',u'Table',u'N',None, None, None, None, u'Identifier',u'Directory;File;Registry',u'Reference to another table name',),
+(u'LockPermissions',u'Domain',u'Y',None, None, None, None, u'Formatted',None, u'Domain name for user whose permissions are being set. (usually a property)',),
+(u'LockPermissions',u'LockObject',u'N',None, None, None, None, u'Identifier',None, u'Foreign key into Registry or File table',),
+(u'LockPermissions',u'Permission',u'Y',-2147483647,2147483647,None, None, None, None, u'Permission Access mask.  Full Control = 268435456 (GENERIC_ALL = 0x10000000)',),
+(u'LockPermissions',u'User',u'N',None, None, None, None, u'Formatted',None, u'User for permissions to be set.  (usually a property)',),
+(u'Media',u'Source',u'Y',None, None, None, None, u'Property',None, u'The property defining the location of the cabinet file.',),
+(u'Media',u'Cabinet',u'Y',None, None, None, None, u'Cabinet',None, u'If some or all of the files stored on the media are compressed in a cabinet, the name of that cabinet.',),
+(u'Media',u'DiskId',u'N',1,32767,None, None, None, None, u'Primary key, integer to determine sort order for table.',),
+(u'Media',u'DiskPrompt',u'Y',None, None, None, None, u'Text',None, u'Disk name: the visible text actually printed on the disk.  This will be used to prompt the user when this disk needs to be inserted.',),
+(u'Media',u'LastSequence',u'N',0,32767,None, None, None, None, u'File sequence number for the last file for this media.',),
+(u'Media',u'VolumeLabel',u'Y',None, None, None, None, u'Text',None, u'The label attributed to the volume.',),
+(u'ModuleComponents',u'Component',u'N',None, None, u'Component',1,u'Identifier',None, u'Component contained in the module.',),
+(u'ModuleComponents',u'Language',u'N',None, None, u'ModuleSignature',2,None, None, u'Default language ID for module (may be changed by transform).',),
+(u'ModuleComponents',u'ModuleID',u'N',None, None, u'ModuleSignature',1,u'Identifier',None, u'Module containing the component.',),
+(u'ModuleSignature',u'Language',u'N',None, None, None, None, None, None, u'Default decimal language of module.',),
+(u'ModuleSignature',u'Version',u'N',None, None, None, None, u'Version',None, u'Version of the module.',),
+(u'ModuleSignature',u'ModuleID',u'N',None, None, None, None, u'Identifier',None, u'Module identifier (String.GUID).',),
+(u'ModuleDependency',u'ModuleID',u'N',None, None, u'ModuleSignature',1,u'Identifier',None, u'Module requiring the dependency.',),
+(u'ModuleDependency',u'ModuleLanguage',u'N',None, None, u'ModuleSignature',2,None, None, u'Language of module requiring the dependency.',),
+(u'ModuleDependency',u'RequiredID',u'N',None, None, None, None, None, None, u'String.GUID of required module.',),
+(u'ModuleDependency',u'RequiredLanguage',u'N',None, None, None, None, None, None, u'LanguageID of the required module.',),
+(u'ModuleDependency',u'RequiredVersion',u'Y',None, None, None, None, u'Version',None, u'Version of the required version.',),
+(u'ModuleExclusion',u'ModuleID',u'N',None, None, u'ModuleSignature',1,u'Identifier',None, u'String.GUID of module with exclusion requirement.',),
+(u'ModuleExclusion',u'ModuleLanguage',u'N',None, None, u'ModuleSignature',2,None, None, u'LanguageID of module with exclusion requirement.',),
+(u'ModuleExclusion',u'ExcludedID',u'N',None, None, None, None, None, None, u'String.GUID of excluded module.',),
+(u'ModuleExclusion',u'ExcludedLanguage',u'N',None, None, None, None, None, None, u'Language of excluded module.',),
+(u'ModuleExclusion',u'ExcludedMaxVersion',u'Y',None, None, None, None, u'Version',None, u'Maximum version of excluded module.',),
+(u'ModuleExclusion',u'ExcludedMinVersion',u'Y',None, None, None, None, u'Version',None, u'Minimum version of excluded module.',),
+(u'MoveFile',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'If this component is not "selected" for installation or removal, no action will be taken on the associated MoveFile entry',),
+(u'MoveFile',u'DestFolder',u'N',None, None, None, None, u'Identifier',None, u'Name of a property whose value is assumed to resolve to the full path to the destination directory',),
+(u'MoveFile',u'DestName',u'Y',None, None, None, None, u'Filename',None, u'Name to be given to the original file after it is moved or copied.  If blank, the destination file will be given the same name as the source file',),
+(u'MoveFile',u'FileKey',u'N',None, None, None, None, u'Identifier',None, u'Primary key that uniquely identifies a particular MoveFile record',),
+(u'MoveFile',u'Options',u'N',0,1,None, None, None, None, u'Integer value specifying the MoveFile operating mode, one of imfoEnum',),
+(u'MoveFile',u'SourceFolder',u'Y',None, None, None, None, u'Identifier',None, u'Name of a property whose value is assumed to resolve to the full path to the source directory',),
+(u'MoveFile',u'SourceName',u'Y',None, None, None, None, u'Text',None, u"Name of the source file(s) to be moved or copied.  Can contain the '*' or '?' wildcards.",),
+(u'MsiAssembly',u'Attributes',u'Y',None, None, None, None, None, None, u'Assembly attributes',),
+(u'MsiAssembly',u'Feature_',u'N',None, None, u'Feature',1,u'Identifier',None, u'Foreign key into Feature table.',),
+(u'MsiAssembly',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key into Component table.',),
+(u'MsiAssembly',u'File_Application',u'Y',None, None, u'File',1,u'Identifier',None, u'Foreign key into File table, denoting the application context for private assemblies. Null for global assemblies.',),
+(u'MsiAssembly',u'File_Manifest',u'Y',None, None, u'File',1,u'Identifier',None, u'Foreign key into the File table denoting the manifest file for the assembly.',),
+(u'MsiAssemblyName',u'Name',u'N',None, None, None, None, u'Text',None, u'The name part of the name-value pairs for the assembly name.',),
+(u'MsiAssemblyName',u'Value',u'N',None, None, None, None, u'Text',None, u'The value part of the name-value pairs for the assembly name.',),
+(u'MsiAssemblyName',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key into Component table.',),
+(u'MsiDigitalCertificate',u'CertData',u'N',None, None, None, None, u'Binary',None, u'A certificate context blob for a signer certificate',),
+(u'MsiDigitalCertificate',u'DigitalCertificate',u'N',None, None, None, None, u'Identifier',None, u'A unique identifier for the row',),
+(u'MsiDigitalSignature',u'Table',u'N',None, None, None, None, None, u'Media',u'Reference to another table name (only Media table is supported)',),
+(u'MsiDigitalSignature',u'DigitalCertificate_',u'N',None, None, u'MsiDigitalCertificate',1,u'Identifier',None, u'Foreign key to MsiDigitalCertificate table identifying the signer certificate',),
+(u'MsiDigitalSignature',u'Hash',u'Y',None, None, None, None, u'Binary',None, u'The encoded hash blob from the digital signature',),
+(u'MsiDigitalSignature',u'SignObject',u'N',None, None, None, None, u'Text',None, u'Foreign key to Media table',),
+(u'MsiFileHash',u'File_',u'N',None, None, u'File',1,u'Identifier',None, u'Primary key, foreign key into File table referencing file with this hash',),
+(u'MsiFileHash',u'Options',u'N',0,32767,None, None, None, None, u'Various options and attributes for this hash.',),
+(u'MsiFileHash',u'HashPart1',u'N',None, None, None, None, None, None, u'Size of file in bytes (long integer).',),
+(u'MsiFileHash',u'HashPart2',u'N',None, None, None, None, None, None, u'Size of file in bytes (long integer).',),
+(u'MsiFileHash',u'HashPart3',u'N',None, None, None, None, None, None, u'Size of file in bytes (long integer).',),
+(u'MsiFileHash',u'HashPart4',u'N',None, None, None, None, None, None, u'Size of file in bytes (long integer).',),
+(u'MsiPatchHeaders',u'StreamRef',u'N',None, None, None, None, u'Identifier',None, u'Primary key. A unique identifier for the row.',),
+(u'MsiPatchHeaders',u'Header',u'N',None, None, None, None, u'Binary',None, u'Binary stream. The patch header, used for patch validation.',),
+(u'ODBCAttribute',u'Value',u'Y',None, None, None, None, u'Text',None, u'Value for ODBC driver attribute',),
+(u'ODBCAttribute',u'Attribute',u'N',None, None, None, None, u'Text',None, u'Name of ODBC driver attribute',),
+(u'ODBCAttribute',u'Driver_',u'N',None, None, u'ODBCDriver',1,u'Identifier',None, u'Reference to ODBC driver in ODBCDriver table',),
+(u'ODBCDriver',u'Description',u'N',None, None, None, None, u'Text',None, u'Text used as registered name for driver, non-localized',),
+(u'ODBCDriver',u'File_',u'N',None, None, u'File',1,u'Identifier',None, u'Reference to key driver file',),
+(u'ODBCDriver',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Reference to associated component',),
+(u'ODBCDriver',u'Driver',u'N',None, None, None, None, u'Identifier',None, u'Primary key, non-localized.internal token for driver',),
+(u'ODBCDriver',u'File_Setup',u'Y',None, None, u'File',1,u'Identifier',None, u'Optional reference to key driver setup DLL',),
+(u'ODBCDataSource',u'Description',u'N',None, None, None, None, u'Text',None, u'Text used as registered name for data source',),
+(u'ODBCDataSource',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Reference to associated component',),
+(u'ODBCDataSource',u'DataSource',u'N',None, None, None, None, u'Identifier',None, u'Primary key, non-localized.internal token for data source',),
+(u'ODBCDataSource',u'DriverDescription',u'N',None, None, None, None, u'Text',None, u'Reference to driver description, may be existing driver',),
+(u'ODBCDataSource',u'Registration',u'N',0,1,None, None, None, None, u'Registration option: 0=machine, 1=user, others t.b.d.',),
+(u'ODBCSourceAttribute',u'Value',u'Y',None, None, None, None, u'Text',None, u'Value for ODBC data source attribute',),
+(u'ODBCSourceAttribute',u'Attribute',u'N',None, None, None, None, u'Text',None, u'Name of ODBC data source attribute',),
+(u'ODBCSourceAttribute',u'DataSource_',u'N',None, None, u'ODBCDataSource',1,u'Identifier',None, u'Reference to ODBC data source in ODBCDataSource table',),
+(u'ODBCTranslator',u'Description',u'N',None, None, None, None, u'Text',None, u'Text used as registered name for translator',),
+(u'ODBCTranslator',u'File_',u'N',None, None, u'File',1,u'Identifier',None, u'Reference to key translator file',),
+(u'ODBCTranslator',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Reference to associated component',),
+(u'ODBCTranslator',u'File_Setup',u'Y',None, None, u'File',1,u'Identifier',None, u'Optional reference to key translator setup DLL',),
+(u'ODBCTranslator',u'Translator',u'N',None, None, None, None, u'Identifier',None, u'Primary key, non-localized.internal token for translator',),
+(u'Patch',u'Sequence',u'N',0,32767,None, None, None, None, u'Primary key, sequence with respect to the media images; order must track cabinet order.',),
+(u'Patch',u'Attributes',u'N',0,32767,None, None, None, None, u'Integer containing bit flags representing patch attributes',),
+(u'Patch',u'File_',u'N',None, None, None, None, u'Identifier',None, u'Primary key, non-localized token, foreign key to File table, must match identifier in cabinet.',),
+(u'Patch',u'Header',u'Y',None, None, None, None, u'Binary',None, u'Binary stream. The patch header, used for patch validation.',),
+(u'Patch',u'PatchSize',u'N',0,2147483647,None, None, None, None, u'Size of patch in bytes (long integer).',),
+(u'Patch',u'StreamRef_',u'Y',None, None, None, None, u'Identifier',None, u'Identifier. Foreign key to the StreamRef column of the MsiPatchHeaders table.',),
+(u'PatchPackage',u'Media_',u'N',0,32767,None, None, None, None, u'Foreign key to DiskId column of Media table. Indicates the disk containing the patch package.',),
+(u'PatchPackage',u'PatchId',u'N',None, None, None, None, u'Guid',None, u'A unique string GUID representing this patch.',),
+(u'PublishComponent',u'Feature_',u'N',None, None, u'Feature',1,u'Identifier',None, u'Foreign key into the Feature table.',),
+(u'PublishComponent',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key into the Component table.',),
+(u'PublishComponent',u'ComponentId',u'N',None, None, None, None, u'Guid',None, u'A string GUID that represents the component id that will be requested by the alien product.',),
+(u'PublishComponent',u'AppData',u'Y',None, None, None, None, u'Text',None, u'This is localisable Application specific data that can be associated with a Qualified Component.',),
+(u'PublishComponent',u'Qualifier',u'N',None, None, None, None, u'Text',None, u'This is defined only when the ComponentId column is an Qualified Component Id. This is the Qualifier for ProvideComponentIndirect.',),
+(u'RadioButton',u'Y',u'N',0,32767,None, None, None, None, u'The vertical coordinate of the upper left corner of the bounding rectangle of the radio button.',),
+(u'RadioButton',u'Text',u'Y',None, None, None, None, u'Text',None, u'The visible title to be assigned to the radio button.',),
+(u'RadioButton',u'Property',u'N',None, None, None, None, u'Identifier',None, u'A named property to be tied to this radio button. All the buttons tied to the same property become part of the same group.',),
+(u'RadioButton',u'Height',u'N',0,32767,None, None, None, None, u'The height of the button.',),
+(u'RadioButton',u'Width',u'N',0,32767,None, None, None, None, u'The width of the button.',),
+(u'RadioButton',u'X',u'N',0,32767,None, None, None, None, u'The horizontal coordinate of the upper left corner of the bounding rectangle of the radio button.',),
+(u'RadioButton',u'Value',u'N',None, None, None, None, u'Formatted',None, u'The value string associated with this button. Selecting the button will set the associated property to this value.',),
+(u'RadioButton',u'Order',u'N',1,32767,None, None, None, None, u'A positive integer used to determine the ordering of the items within one list..The integers do not have to be consecutive.',),
+(u'RadioButton',u'Help',u'Y',None, None, None, None, u'Text',None, u'The help strings used with the button. The text is optional.',),
+(u'Registry',u'Name',u'Y',None, None, None, None, u'Formatted',None, u'The registry value name.',),
+(u'Registry',u'Value',u'Y',None, None, None, None, u'Formatted',None, u'The registry value.',),
+(u'Registry',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key into the Component table referencing component that controls the installing of the registry value.',),
+(u'Registry',u'Key',u'N',None, None, None, None, u'RegPath',None, u'The key for the registry value.',),
+(u'Registry',u'Registry',u'N',None, None, None, None, u'Identifier',None, u'Primary key, non-localized token.',),
+(u'Registry',u'Root',u'N',-1,3,None, None, None, None, u'The predefined root key for the registry value, one of rrkEnum.',),
+(u'RegLocator',u'Name',u'Y',None, None, None, None, u'Formatted',None, u'The registry value name.',),
+(u'RegLocator',u'Type',u'Y',0,18,None, None, None, None, u'An integer value that determines if the registry value is a filename or a directory location or to be used as is w/o interpretation.',),
+(u'RegLocator',u'Signature_',u'N',None, None, None, None, u'Identifier',None, u'The table key. The Signature_ represents a unique file signature and is also the foreign key in the Signature table. If the type is 0, the registry values refers a directory, and _Signature is not a foreign key.',),
+(u'RegLocator',u'Key',u'N',None, None, None, None, u'RegPath',None, u'The key for the registry value.',),
+(u'RegLocator',u'Root',u'N',0,3,None, None, None, None, u'The predefined root key for the registry value, one of rrkEnum.',),
+(u'RemoveFile',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key referencing Component that controls the file to be removed.',),
+(u'RemoveFile',u'FileKey',u'N',None, None, None, None, u'Identifier',None, u'Primary key used to identify a particular file entry',),
+(u'RemoveFile',u'FileName',u'Y',None, None, None, None, u'WildCardFilename',None, u'Name of the file to be removed.',),
+(u'RemoveFile',u'DirProperty',u'N',None, None, None, None, u'Identifier',None, u'Name of a property whose value is assumed to resolve to the full pathname to the folder of the file to be removed.',),
+(u'RemoveFile',u'InstallMode',u'N',None, None, None, None, None, u'1;2;3',u'Installation option, one of iimEnum.',),
+(u'RemoveIniFile',u'Action',u'N',None, None, None, None, None, u'2;4',u'The type of modification to be made, one of iifEnum.',),
+(u'RemoveIniFile',u'Value',u'Y',None, None, None, None, u'Formatted',None, u'The value to be deleted. The value is required when Action is iifIniRemoveTag',),
+(u'RemoveIniFile',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key into the Component table referencing component that controls the deletion of the .INI value.',),
+(u'RemoveIniFile',u'FileName',u'N',None, None, None, None, u'Filename',None, u'The .INI file name in which to delete the information',),
+(u'RemoveIniFile',u'DirProperty',u'Y',None, None, None, None, u'Identifier',None, u'Foreign key into the Directory table denoting the directory where the .INI file is.',),
+(u'RemoveIniFile',u'Key',u'N',None, None, None, None, u'Formatted',None, u'The .INI file key below Section.',),
+(u'RemoveIniFile',u'Section',u'N',None, None, None, None, u'Formatted',None, u'The .INI file Section.',),
+(u'RemoveIniFile',u'RemoveIniFile',u'N',None, None, None, None, u'Identifier',None, u'Primary key, non-localized token.',),
+(u'RemoveRegistry',u'Name',u'Y',None, None, None, None, u'Formatted',None, u'The registry value name.',),
+(u'RemoveRegistry',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key into the Component table referencing component that controls the deletion of the registry value.',),
+(u'RemoveRegistry',u'Key',u'N',None, None, None, None, u'RegPath',None, u'The key for the registry value.',),
+(u'RemoveRegistry',u'Root',u'N',-1,3,None, None, None, None, u'The predefined root key for the registry value, one of rrkEnum',),
+(u'RemoveRegistry',u'RemoveRegistry',u'N',None, None, None, None, u'Identifier',None, u'Primary key, non-localized token.',),
+(u'ReserveCost',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Reserve a specified amount of space if this component is to be installed.',),
+(u'ReserveCost',u'ReserveFolder',u'Y',None, None, None, None, u'Identifier',None, u'Name of a property whose value is assumed to resolve to the full path to the destination directory',),
+(u'ReserveCost',u'ReserveKey',u'N',None, None, None, None, u'Identifier',None, u'Primary key that uniquely identifies a particular ReserveCost record',),
+(u'ReserveCost',u'ReserveLocal',u'N',0,2147483647,None, None, None, None, u'Disk space to reserve if linked component is installed locally.',),
+(u'ReserveCost',u'ReserveSource',u'N',0,2147483647,None, None, None, None, u'Disk space to reserve if linked component is installed to run from the source location.',),
+(u'SelfReg',u'File_',u'N',None, None, u'File',1,u'Identifier',None, u'Foreign key into the File table denoting the module that needs to be registered.',),
+(u'SelfReg',u'Cost',u'Y',0,32767,None, None, None, None, u'The cost of registering the module.',),
+(u'ServiceControl',u'Name',u'N',None, None, None, None, u'Formatted',None, u'Name of a service. /, \\, comma and space are invalid',),
+(u'ServiceControl',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Required foreign key into the Component Table that controls the startup of the service',),
+(u'ServiceControl',u'Event',u'N',0,187,None, None, None, None, u'Bit field:  Install:  0x1 = Start, 0x2 = Stop, 0x8 = Delete, Uninstall: 0x10 = Start, 0x20 = Stop, 0x80 = Delete',),
+(u'ServiceControl',u'ServiceControl',u'N',None, None, None, None, u'Identifier',None, u'Primary key, non-localized token.',),
+(u'ServiceControl',u'Arguments',u'Y',None, None, None, None, u'Formatted',None, u'Arguments for the service.  Separate by [~].',),
+(u'ServiceControl',u'Wait',u'Y',0,1,None, None, None, None, u'Boolean for whether to wait for the service to fully start',),
+(u'ServiceInstall',u'Name',u'N',None, None, None, None, u'Formatted',None, u'Internal Name of the Service',),
+(u'ServiceInstall',u'Description',u'Y',None, None, None, None, u'Text',None, u'Description of service.',),
+(u'ServiceInstall',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Required foreign key into the Component Table that controls the startup of the service',),
+(u'ServiceInstall',u'Arguments',u'Y',None, None, None, None, u'Formatted',None, u'Arguments to include in every start of the service, passed to WinMain',),
+(u'ServiceInstall',u'ServiceInstall',u'N',None, None, None, None, u'Identifier',None, u'Primary key, non-localized token.',),
+(u'ServiceInstall',u'Dependencies',u'Y',None, None, None, None, u'Formatted',None, u'Other services this depends on to start.  Separate by [~], and end with [~][~]',),
+(u'ServiceInstall',u'DisplayName',u'Y',None, None, None, None, u'Formatted',None, u'External Name of the Service',),
+(u'ServiceInstall',u'ErrorControl',u'N',-2147483647,2147483647,None, None, None, None, u'Severity of error if service fails to start',),
+(u'ServiceInstall',u'LoadOrderGroup',u'Y',None, None, None, None, u'Formatted',None, u'LoadOrderGroup',),
+(u'ServiceInstall',u'Password',u'Y',None, None, None, None, u'Formatted',None, u'password to run service with.  (with StartName)',),
+(u'ServiceInstall',u'ServiceType',u'N',-2147483647,2147483647,None, None, None, None, u'Type of the service',),
+(u'ServiceInstall',u'StartName',u'Y',None, None, None, None, u'Formatted',None, u'User or object name to run service as',),
+(u'ServiceInstall',u'StartType',u'N',0,4,None, None, None, None, u'Type of the service',),
+(u'Shortcut',u'Name',u'N',None, None, None, None, u'Filename',None, u'The name of the shortcut to be created.',),
+(u'Shortcut',u'Description',u'Y',None, None, None, None, u'Text',None, u'The description for the shortcut.',),
+(u'Shortcut',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key into the Component table denoting the component whose selection gates the the shortcut creation/deletion.',),
+(u'Shortcut',u'Icon_',u'Y',None, None, u'Icon',1,u'Identifier',None, u'Foreign key into the File table denoting the external icon file for the shortcut.',),
+(u'Shortcut',u'IconIndex',u'Y',-32767,32767,None, None, None, None, u'The icon index for the shortcut.',),
+(u'Shortcut',u'Directory_',u'N',None, None, u'Directory',1,u'Identifier',None, u'Foreign key into the Directory table denoting the directory where the shortcut file is created.',),
+(u'Shortcut',u'Target',u'N',None, None, None, None, u'Shortcut',None, u'The shortcut target. This is usually a property that is expanded to a file or a folder that the shortcut points to.',),
+(u'Shortcut',u'Arguments',u'Y',None, None, None, None, u'Formatted',None, u'The command-line arguments for the shortcut.',),
+(u'Shortcut',u'Shortcut',u'N',None, None, None, None, u'Identifier',None, u'Primary key, non-localized token.',),
+(u'Shortcut',u'Hotkey',u'Y',0,32767,None, None, None, None, u'The hotkey for the shortcut. It has the virtual-key code for the key in the low-order byte, and the modifier flags in the high-order byte. ',),
+(u'Shortcut',u'ShowCmd',u'Y',None, None, None, None, None, u'1;3;7',u'The show command for the application window.The following values may be used.',),
+(u'Shortcut',u'WkDir',u'Y',None, None, None, None, u'Identifier',None, u'Name of property defining location of working directory.',),
+(u'Signature',u'FileName',u'N',None, None, None, None, u'Filename',None, u'The name of the file. This may contain a "short name|long name" pair.',),
+(u'Signature',u'Signature',u'N',None, None, None, None, u'Identifier',None, u'The table key. The Signature represents a unique file signature.',),
+(u'Signature',u'Languages',u'Y',None, None, None, None, u'Language',None, u'The languages supported by the file.',),
+(u'Signature',u'MaxDate',u'Y',0,2147483647,None, None, None, None, u'The maximum creation date of the file.',),
+(u'Signature',u'MaxSize',u'Y',0,2147483647,None, None, None, None, u'The maximum size of the file. ',),
+(u'Signature',u'MaxVersion',u'Y',None, None, None, None, u'Text',None, u'The maximum version of the file.',),
+(u'Signature',u'MinDate',u'Y',0,2147483647,None, None, None, None, u'The minimum creation date of the file.',),
+(u'Signature',u'MinSize',u'Y',0,2147483647,None, None, None, None, u'The minimum size of the file.',),
+(u'Signature',u'MinVersion',u'Y',None, None, None, None, u'Text',None, u'The minimum version of the file.',),
+(u'TextStyle',u'TextStyle',u'N',None, None, None, None, u'Identifier',None, u'Name of the style. The primary key of this table. This name is embedded in the texts to indicate a style change.',),
+(u'TextStyle',u'Color',u'Y',0,16777215,None, None, None, None, u'A long integer indicating the color of the string in the RGB format (Red, Green, Blue each 0-255, RGB = R + 256*G + 256^2*B).',),
+(u'TextStyle',u'FaceName',u'N',None, None, None, None, u'Text',None, u'A string indicating the name of the font used. Required. The string must be at most 31 characters long.',),
+(u'TextStyle',u'Size',u'N',0,32767,None, None, None, None, u'The size of the font used. This size is given in our units (1/12 of the system font height). Assuming that the system font is set to 12 point size, this is equivalent to the point size.',),
+(u'TextStyle',u'StyleBits',u'Y',0,15,None, None, None, None, u'A combination of style bits.',),
+(u'TypeLib',u'Description',u'Y',None, None, None, None, u'Text',None, None, ),
+(u'TypeLib',u'Feature_',u'N',None, None, u'Feature',1,u'Identifier',None, u'Required foreign key into the Feature Table, specifying the feature to validate or install in order for the type library to be operational.',),
+(u'TypeLib',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Required foreign key into the Component Table, specifying the component for which to return a path when called through LocateComponent.',),
+(u'TypeLib',u'Directory_',u'Y',None, None, u'Directory',1,u'Identifier',None, u'Optional. The foreign key into the Directory table denoting the path to the help file for the type library.',),
+(u'TypeLib',u'Language',u'N',0,32767,None, None, None, None, u'The language of the library.',),
+(u'TypeLib',u'Version',u'Y',0,16777215,None, None, None, None, u'The version of the library. The minor version is in the lower 8 bits of the integer. The major version is in the next 16 bits. ',),
+(u'TypeLib',u'Cost',u'Y',0,2147483647,None, None, None, None, u'The cost associated with the registration of the typelib. This column is currently optional.',),
+(u'TypeLib',u'LibID',u'N',None, None, None, None, u'Guid',None, u'The GUID that represents the library.',),
+(u'UIText',u'Text',u'Y',None, None, None, None, u'Text',None, u'The localized version of the string.',),
+(u'UIText',u'Key',u'N',None, None, None, None, u'Identifier',None, u'A unique key that identifies the particular string.',),
+(u'Upgrade',u'Attributes',u'N',0,2147483647,None, None, None, None, u'The attributes of this product set.',),
+(u'Upgrade',u'Language',u'Y',None, None, None, None, u'Language',None, u'A comma-separated list of languages for either products in this set or products not in this set.',),
+(u'Upgrade',u'ActionProperty',u'N',None, None, None, None, u'UpperCase',None, u'The property to set when a product in this set is found.',),
+(u'Upgrade',u'Remove',u'Y',None, None, None, None, u'Formatted',None, u'The list of features to remove when uninstalling a product from this set.  The default is "ALL".',),
+(u'Upgrade',u'UpgradeCode',u'N',None, None, None, None, u'Guid',None, u'The UpgradeCode GUID belonging to the products in this set.',),
+(u'Upgrade',u'VersionMax',u'Y',None, None, None, None, u'Text',None, u'The maximum ProductVersion of the products in this set.  The set may or may not include products with this particular version.',),
+(u'Upgrade',u'VersionMin',u'Y',None, None, None, None, u'Text',None, u'The minimum ProductVersion of the products in this set.  The set may or may not include products with this particular version.',),
+(u'Verb',u'Sequence',u'Y',0,32767,None, None, None, None, u'Order within the verbs for a particular extension. Also used simply to specify the default verb.',),
+(u'Verb',u'Argument',u'Y',None, None, None, None, u'Formatted',None, u'Optional value for the command arguments.',),
+(u'Verb',u'Extension_',u'N',None, None, u'Extension',1,u'Text',None, u'The extension associated with the table row.',),
+(u'Verb',u'Verb',u'N',None, None, None, None, u'Text',None, u'The verb for the command.',),
+(u'Verb',u'Command',u'Y',None, None, None, None, u'Formatted',None, u'The command text.',),
+]

Added: vendor/Python/current/Lib/msilib/sequence.py
===================================================================
--- vendor/Python/current/Lib/msilib/sequence.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/msilib/sequence.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,126 @@
+AdminExecuteSequence = [
+(u'InstallInitialize', None, 1500),
+(u'InstallFinalize', None, 6600),
+(u'InstallFiles', None, 4000),
+(u'InstallAdminPackage', None, 3900),
+(u'FileCost', None, 900),
+(u'CostInitialize', None, 800),
+(u'CostFinalize', None, 1000),
+(u'InstallValidate', None, 1400),
+]
+
+AdminUISequence = [
+(u'FileCost', None, 900),
+(u'CostInitialize', None, 800),
+(u'CostFinalize', None, 1000),
+(u'ExecuteAction', None, 1300),
+(u'ExitDialog', None, -1),
+(u'FatalError', None, -3),
+(u'UserExit', None, -2),
+]
+
+AdvtExecuteSequence = [
+(u'InstallInitialize', None, 1500),
+(u'InstallFinalize', None, 6600),
+(u'CostInitialize', None, 800),
+(u'CostFinalize', None, 1000),
+(u'InstallValidate', None, 1400),
+(u'CreateShortcuts', None, 4500),
+(u'MsiPublishAssemblies', None, 6250),
+(u'PublishComponents', None, 6200),
+(u'PublishFeatures', None, 6300),
+(u'PublishProduct', None, 6400),
+(u'RegisterClassInfo', None, 4600),
+(u'RegisterExtensionInfo', None, 4700),
+(u'RegisterMIMEInfo', None, 4900),
+(u'RegisterProgIdInfo', None, 4800),
+]
+
+InstallExecuteSequence = [
+(u'InstallInitialize', None, 1500),
+(u'InstallFinalize', None, 6600),
+(u'InstallFiles', None, 4000),
+(u'FileCost', None, 900),
+(u'CostInitialize', None, 800),
+(u'CostFinalize', None, 1000),
+(u'InstallValidate', None, 1400),
+(u'CreateShortcuts', None, 4500),
+(u'MsiPublishAssemblies', None, 6250),
+(u'PublishComponents', None, 6200),
+(u'PublishFeatures', None, 6300),
+(u'PublishProduct', None, 6400),
+(u'RegisterClassInfo', None, 4600),
+(u'RegisterExtensionInfo', None, 4700),
+(u'RegisterMIMEInfo', None, 4900),
+(u'RegisterProgIdInfo', None, 4800),
+(u'AllocateRegistrySpace', u'NOT Installed', 1550),
+(u'AppSearch', None, 400),
+(u'BindImage', None, 4300),
+(u'CCPSearch', u'NOT Installed', 500),
+(u'CreateFolders', None, 3700),
+(u'DeleteServices', u'VersionNT', 2000),
+(u'DuplicateFiles', None, 4210),
+(u'FindRelatedProducts', None, 200),
+(u'InstallODBC', None, 5400),
+(u'InstallServices', u'VersionNT', 5800),
+(u'IsolateComponents', None, 950),
+(u'LaunchConditions', None, 100),
+(u'MigrateFeatureStates', None, 1200),
+(u'MoveFiles', None, 3800),
+(u'PatchFiles', None, 4090),
+(u'ProcessComponents', None, 1600),
+(u'RegisterComPlus', None, 5700),
+(u'RegisterFonts', None, 5300),
+(u'RegisterProduct', None, 6100),
+(u'RegisterTypeLibraries', None, 5500),
+(u'RegisterUser', None, 6000),
+(u'RemoveDuplicateFiles', None, 3400),
+(u'RemoveEnvironmentStrings', None, 3300),
+(u'RemoveExistingProducts', None, 6700),
+(u'RemoveFiles', None, 3500),
+(u'RemoveFolders', None, 3600),
+(u'RemoveIniValues', None, 3100),
+(u'RemoveODBC', None, 2400),
+(u'RemoveRegistryValues', None, 2600),
+(u'RemoveShortcuts', None, 3200),
+(u'RMCCPSearch', u'NOT Installed', 600),
+(u'SelfRegModules', None, 5600),
+(u'SelfUnregModules', None, 2200),
+(u'SetODBCFolders', None, 1100),
+(u'StartServices', u'VersionNT', 5900),
+(u'StopServices', u'VersionNT', 1900),
+(u'MsiUnpublishAssemblies', None, 1750),
+(u'UnpublishComponents', None, 1700),
+(u'UnpublishFeatures', None, 1800),
+(u'UnregisterClassInfo', None, 2700),
+(u'UnregisterComPlus', None, 2100),
+(u'UnregisterExtensionInfo', None, 2800),
+(u'UnregisterFonts', None, 2500),
+(u'UnregisterMIMEInfo', None, 3000),
+(u'UnregisterProgIdInfo', None, 2900),
+(u'UnregisterTypeLibraries', None, 2300),
+(u'ValidateProductID', None, 700),
+(u'WriteEnvironmentStrings', None, 5200),
+(u'WriteIniValues', None, 5100),
+(u'WriteRegistryValues', None, 5000),
+]
+
+InstallUISequence = [
+(u'FileCost', None, 900),
+(u'CostInitialize', None, 800),
+(u'CostFinalize', None, 1000),
+(u'ExecuteAction', None, 1300),
+(u'ExitDialog', None, -1),
+(u'FatalError', None, -3),
+(u'UserExit', None, -2),
+(u'AppSearch', None, 400),
+(u'CCPSearch', u'NOT Installed', 500),
+(u'FindRelatedProducts', None, 200),
+(u'IsolateComponents', None, 950),
+(u'LaunchConditions', None, 100),
+(u'MigrateFeatureStates', None, 1200),
+(u'RMCCPSearch', u'NOT Installed', 600),
+(u'ValidateProductID', None, 700),
+]
+
+tables=['AdminExecuteSequence', 'AdminUISequence', 'AdvtExecuteSequence', 'InstallExecuteSequence', 'InstallUISequence']

Added: vendor/Python/current/Lib/msilib/text.py
===================================================================
--- vendor/Python/current/Lib/msilib/text.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/msilib/text.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,129 @@
+import msilib,os;dirname=os.path.dirname(__file__)
+
+ActionText = [
+(u'InstallValidate', u'Validating install', None),
+(u'InstallFiles', u'Copying new files', u'File: [1],  Directory: [9],  Size: [6]'),
+(u'InstallAdminPackage', u'Copying network install files', u'File: [1], Directory: [9], Size: [6]'),
+(u'FileCost', u'Computing space requirements', None),
+(u'CostInitialize', u'Computing space requirements', None),
+(u'CostFinalize', u'Computing space requirements', None),
+(u'CreateShortcuts', u'Creating shortcuts', u'Shortcut: [1]'),
+(u'PublishComponents', u'Publishing Qualified Components', u'Component ID: [1], Qualifier: [2]'),
+(u'PublishFeatures', u'Publishing Product Features', u'Feature: [1]'),
+(u'PublishProduct', u'Publishing product information', None),
+(u'RegisterClassInfo', u'Registering Class servers', u'Class Id: [1]'),
+(u'RegisterExtensionInfo', u'Registering extension servers', u'Extension: [1]'),
+(u'RegisterMIMEInfo', u'Registering MIME info', u'MIME Content Type: [1], Extension: [2]'),
+(u'RegisterProgIdInfo', u'Registering program identifiers', u'ProgId: [1]'),
+(u'AllocateRegistrySpace', u'Allocating registry space', u'Free space: [1]'),
+(u'AppSearch', u'Searching for installed applications', u'Property: [1], Signature: [2]'),
+(u'BindImage', u'Binding executables', u'File: [1]'),
+(u'CCPSearch', u'Searching for qualifying products', None),
+(u'CreateFolders', u'Creating folders', u'Folder: [1]'),
+(u'DeleteServices', u'Deleting services', u'Service: [1]'),
+(u'DuplicateFiles', u'Creating duplicate files', u'File: [1],  Directory: [9],  Size: [6]'),
+(u'FindRelatedProducts', u'Searching for related applications', u'Found application: [1]'),
+(u'InstallODBC', u'Installing ODBC components', None),
+(u'InstallServices', u'Installing new services', u'Service: [2]'),
+(u'LaunchConditions', u'Evaluating launch conditions', None),
+(u'MigrateFeatureStates', u'Migrating feature states from related applications', u'Application: [1]'),
+(u'MoveFiles', u'Moving files', u'File: [1],  Directory: [9],  Size: [6]'),
+(u'PatchFiles', u'Patching files', u'File: [1],  Directory: [2],  Size: [3]'),
+(u'ProcessComponents', u'Updating component registration', None),
+(u'RegisterComPlus', u'Registering COM+ Applications and Components', u'AppId: [1]{{, AppType: [2], Users: [3], RSN: [4]}}'),
+(u'RegisterFonts', u'Registering fonts', u'Font: [1]'),
+(u'RegisterProduct', u'Registering product', u'[1]'),
+(u'RegisterTypeLibraries', u'Registering type libraries', u'LibID: [1]'),
+(u'RegisterUser', u'Registering user', u'[1]'),
+(u'RemoveDuplicateFiles', u'Removing duplicated files', u'File: [1], Directory: [9]'),
+(u'RemoveEnvironmentStrings', u'Updating environment strings', u'Name: [1], Value: [2], Action [3]'),
+(u'RemoveExistingProducts', u'Removing applications', u'Application: [1], Command line: [2]'),
+(u'RemoveFiles', u'Removing files', u'File: [1], Directory: [9]'),
+(u'RemoveFolders', u'Removing folders', u'Folder: [1]'),
+(u'RemoveIniValues', u'Removing INI files entries', u'File: [1],  Section: [2],  Key: [3], Value: [4]'),
+(u'RemoveODBC', u'Removing ODBC components', None),
+(u'RemoveRegistryValues', u'Removing system registry values', u'Key: [1], Name: [2]'),
+(u'RemoveShortcuts', u'Removing shortcuts', u'Shortcut: [1]'),
+(u'RMCCPSearch', u'Searching for qualifying products', None),
+(u'SelfRegModules', u'Registering modules', u'File: [1], Folder: [2]'),
+(u'SelfUnregModules', u'Unregistering modules', u'File: [1], Folder: [2]'),
+(u'SetODBCFolders', u'Initializing ODBC directories', None),
+(u'StartServices', u'Starting services', u'Service: [1]'),
+(u'StopServices', u'Stopping services', u'Service: [1]'),
+(u'UnpublishComponents', u'Unpublishing Qualified Components', u'Component ID: [1], Qualifier: [2]'),
+(u'UnpublishFeatures', u'Unpublishing Product Features', u'Feature: [1]'),
+(u'UnregisterClassInfo', u'Unregister Class servers', u'Class Id: [1]'),
+(u'UnregisterComPlus', u'Unregistering COM+ Applications and Components', u'AppId: [1]{{, AppType: [2]}}'),
+(u'UnregisterExtensionInfo', u'Unregistering extension servers', u'Extension: [1]'),
+(u'UnregisterFonts', u'Unregistering fonts', u'Font: [1]'),
+(u'UnregisterMIMEInfo', u'Unregistering MIME info', u'MIME Content Type: [1], Extension: [2]'),
+(u'UnregisterProgIdInfo', u'Unregistering program identifiers', u'ProgId: [1]'),
+(u'UnregisterTypeLibraries', u'Unregistering type libraries', u'LibID: [1]'),
+(u'WriteEnvironmentStrings', u'Updating environment strings', u'Name: [1], Value: [2], Action [3]'),
+(u'WriteIniValues', u'Writing INI files values', u'File: [1],  Section: [2],  Key: [3], Value: [4]'),
+(u'WriteRegistryValues', u'Writing system registry values', u'Key: [1], Name: [2], Value: [3]'),
+(u'Advertise', u'Advertising application', None),
+(u'GenerateScript', u'Generating script operations for action:', u'[1]'),
+(u'InstallSFPCatalogFile', u'Installing system catalog', u'File: [1],  Dependencies: [2]'),
+(u'MsiPublishAssemblies', u'Publishing assembly information', u'Application Context:[1], Assembly Name:[2]'),
+(u'MsiUnpublishAssemblies', u'Unpublishing assembly information', u'Application Context:[1], Assembly Name:[2]'),
+(u'Rollback', u'Rolling back action:', u'[1]'),
+(u'RollbackCleanup', u'Removing backup files', u'File: [1]'),
+(u'UnmoveFiles', u'Removing moved files', u'File: [1], Directory: [9]'),
+(u'UnpublishProduct', u'Unpublishing product information', None),
+]
+
+UIText = [
+(u'AbsentPath', None),
+(u'bytes', u'bytes'),
+(u'GB', u'GB'),
+(u'KB', u'KB'),
+(u'MB', u'MB'),
+(u'MenuAbsent', u'Entire feature will be unavailable'),
+(u'MenuAdvertise', u'Feature will be installed when required'),
+(u'MenuAllCD', u'Entire feature will be installed to run from CD'),
+(u'MenuAllLocal', u'Entire feature will be installed on local hard drive'),
+(u'MenuAllNetwork', u'Entire feature will be installed to run from network'),
+(u'MenuCD', u'Will be installed to run from CD'),
+(u'MenuLocal', u'Will be installed on local hard drive'),
+(u'MenuNetwork', u'Will be installed to run from network'),
+(u'ScriptInProgress', u'Gathering required information...'),
+(u'SelAbsentAbsent', u'This feature will remain uninstalled'),
+(u'SelAbsentAdvertise', u'This feature will be set to be installed when required'),
+(u'SelAbsentCD', u'This feature will be installed to run from CD'),
+(u'SelAbsentLocal', u'This feature will be installed on the local hard drive'),
+(u'SelAbsentNetwork', u'This feature will be installed to run from the network'),
+(u'SelAdvertiseAbsent', u'This feature will become unavailable'),
+(u'SelAdvertiseAdvertise', u'Will be installed when required'),
+(u'SelAdvertiseCD', u'This feature will be available to run from CD'),
+(u'SelAdvertiseLocal', u'This feature will be installed on your local hard drive'),
+(u'SelAdvertiseNetwork', u'This feature will be available to run from the network'),
+(u'SelCDAbsent', u"This feature will be uninstalled completely, you won't be able to run it from CD"),
+(u'SelCDAdvertise', u'This feature will change from run from CD state to set to be installed when required'),
+(u'SelCDCD', u'This feature will remain to be run from CD'),
+(u'SelCDLocal', u'This feature will change from run from CD state to be installed on the local hard drive'),
+(u'SelChildCostNeg', u'This feature frees up [1] on your hard drive.'),
+(u'SelChildCostPos', u'This feature requires [1] on your hard drive.'),
+(u'SelCostPending', u'Compiling cost for this feature...'),
+(u'SelLocalAbsent', u'This feature will be completely removed'),
+(u'SelLocalAdvertise', u'This feature will be removed from your local hard drive, but will be set to be installed when required'),
+(u'SelLocalCD', u'This feature will be removed from your local hard drive, but will be still available to run from CD'),
+(u'SelLocalLocal', u'This feature will remain on you local hard drive'),
+(u'SelLocalNetwork', u'This feature will be removed from your local hard drive, but will be still available to run from the network'),
+(u'SelNetworkAbsent', u"This feature will be uninstalled completely, you won't be able to run it from the network"),
+(u'SelNetworkAdvertise', u'This feature will change from run from network state to set to be installed when required'),
+(u'SelNetworkLocal', u'This feature will change from run from network state to be installed on the local hard drive'),
+(u'SelNetworkNetwork', u'This feature will remain to be run from the network'),
+(u'SelParentCostNegNeg', u'This feature frees up [1] on your hard drive. It has [2] of [3] subfeatures selected. The subfeatures free up [4] on your hard drive.'),
+(u'SelParentCostNegPos', u'This feature frees up [1] on your hard drive. It has [2] of [3] subfeatures selected. The subfeatures require [4] on your hard drive.'),
+(u'SelParentCostPosNeg', u'This feature requires [1] on your hard drive. It has [2] of [3] subfeatures selected. The subfeatures free up [4] on your hard drive.'),
+(u'SelParentCostPosPos', u'This feature requires [1] on your hard drive. It has [2] of [3] subfeatures selected. The subfeatures require [4] on your hard drive.'),
+(u'TimeRemaining', u'Time remaining: {[1] minutes }{[2] seconds}'),
+(u'VolumeCostAvailable', u'Available'),
+(u'VolumeCostDifference', u'Difference'),
+(u'VolumeCostRequired', u'Required'),
+(u'VolumeCostSize', u'Disk Size'),
+(u'VolumeCostVolume', u'Volume'),
+]
+
+tables=['ActionText', 'UIText']

Added: vendor/Python/current/Lib/multifile.py
===================================================================
--- vendor/Python/current/Lib/multifile.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/multifile.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,158 @@
+"""A readline()-style interface to the parts of a multipart message.
+
+The MultiFile class makes each part of a multipart message "feel" like
+an ordinary file, as long as you use fp.readline().  Allows recursive
+use, for nested multipart messages.  Probably best used together
+with module mimetools.
+
+Suggested use:
+
+real_fp = open(...)
+fp = MultiFile(real_fp)
+
+"read some lines from fp"
+fp.push(separator)
+while 1:
+        "read lines from fp until it returns an empty string" (A)
+        if not fp.next(): break
+fp.pop()
+"read remaining lines from fp until it returns an empty string"
+
+The latter sequence may be used recursively at (A).
+It is also allowed to use multiple push()...pop() sequences.
+
+If seekable is given as 0, the class code will not do the bookkeeping
+it normally attempts in order to make seeks relative to the beginning of the
+current file part.  This may be useful when using MultiFile with a non-
+seekable stream object.
+"""
+
+__all__ = ["MultiFile","Error"]
+
+class Error(Exception):
+    pass
+
+class MultiFile:
+
+    seekable = 0
+
+    def __init__(self, fp, seekable=1):
+        self.fp = fp
+        self.stack = []
+        self.level = 0
+        self.last = 0
+        if seekable:
+            self.seekable = 1
+            self.start = self.fp.tell()
+            self.posstack = []
+
+    def tell(self):
+        if self.level > 0:
+            return self.lastpos
+        return self.fp.tell() - self.start
+
+    def seek(self, pos, whence=0):
+        here = self.tell()
+        if whence:
+            if whence == 1:
+                pos = pos + here
+            elif whence == 2:
+                if self.level > 0:
+                    pos = pos + self.lastpos
+                else:
+                    raise Error, "can't use whence=2 yet"
+        if not 0 <= pos <= here or \
+                        self.level > 0 and pos > self.lastpos:
+            raise Error, 'bad MultiFile.seek() call'
+        self.fp.seek(pos + self.start)
+        self.level = 0
+        self.last = 0
+
+    def readline(self):
+        if self.level > 0:
+            return ''
+        line = self.fp.readline()
+        # Real EOF?
+        if not line:
+            self.level = len(self.stack)
+            self.last = (self.level > 0)
+            if self.last:
+                raise Error, 'sudden EOF in MultiFile.readline()'
+            return ''
+        assert self.level == 0
+        # Fast check to see if this is just data
+        if self.is_data(line):
+            return line
+        else:
+            # Ignore trailing whitespace on marker lines
+            marker = line.rstrip()
+        # No?  OK, try to match a boundary.
+        # Return the line (unstripped) if we don't.
+        for i, sep in enumerate(reversed(self.stack)):
+            if marker == self.section_divider(sep):
+                self.last = 0
+                break
+            elif marker == self.end_marker(sep):
+                self.last = 1
+                break
+        else:
+            return line
+        # We only get here if we see a section divider or EOM line
+        if self.seekable:
+            self.lastpos = self.tell() - len(line)
+        self.level = i+1
+        if self.level > 1:
+            raise Error,'Missing endmarker in MultiFile.readline()'
+        return ''
+
+    def readlines(self):
+        list = []
+        while 1:
+            line = self.readline()
+            if not line: break
+            list.append(line)
+        return list
+
+    def read(self): # Note: no size argument -- read until EOF only!
+        return ''.join(self.readlines())
+
+    def next(self):
+        while self.readline(): pass
+        if self.level > 1 or self.last:
+            return 0
+        self.level = 0
+        self.last = 0
+        if self.seekable:
+            self.start = self.fp.tell()
+        return 1
+
+    def push(self, sep):
+        if self.level > 0:
+            raise Error, 'bad MultiFile.push() call'
+        self.stack.append(sep)
+        if self.seekable:
+            self.posstack.append(self.start)
+            self.start = self.fp.tell()
+
+    def pop(self):
+        if self.stack == []:
+            raise Error, 'bad MultiFile.pop() call'
+        if self.level <= 1:
+            self.last = 0
+        else:
+            abslastpos = self.lastpos + self.start
+        self.level = max(0, self.level - 1)
+        self.stack.pop()
+        if self.seekable:
+            self.start = self.posstack.pop()
+            if self.level > 0:
+                self.lastpos = abslastpos - self.start
+
+    def is_data(self, line):
+        return line[:2] != '--'
+
+    def section_divider(self, str):
+        return "--" + str
+
+    def end_marker(self, str):
+        return "--" + str + "--"

Added: vendor/Python/current/Lib/mutex.py
===================================================================
--- vendor/Python/current/Lib/mutex.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/mutex.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,52 @@
+"""Mutual exclusion -- for use with module sched
+
+A mutex has two pieces of state -- a 'locked' bit and a queue.
+When the mutex is not locked, the queue is empty.
+Otherwise, the queue contains 0 or more (function, argument) pairs
+representing functions (or methods) waiting to acquire the lock.
+When the mutex is unlocked while the queue is not empty,
+the first queue entry is removed and its function(argument) pair called,
+implying it now has the lock.
+
+Of course, no multi-threading is implied -- hence the funny interface
+for lock, where a function is called once the lock is aquired.
+"""
+
+from collections import deque
+
+class mutex:
+    def __init__(self):
+        """Create a new mutex -- initially unlocked."""
+        self.locked = 0
+        self.queue = deque()
+
+    def test(self):
+        """Test the locked bit of the mutex."""
+        return self.locked
+
+    def testandset(self):
+        """Atomic test-and-set -- grab the lock if it is not set,
+        return True if it succeeded."""
+        if not self.locked:
+            self.locked = 1
+            return True
+        else:
+            return False
+
+    def lock(self, function, argument):
+        """Lock a mutex, call the function with supplied argument
+        when it is acquired.  If the mutex is already locked, place
+        function and argument in the queue."""
+        if self.testandset():
+            function(argument)
+        else:
+            self.queue.append((function, argument))
+
+    def unlock(self):
+        """Unlock a mutex.  If the queue is not empty, call the next
+        function with its argument."""
+        if self.queue:
+            function, argument = self.queue.popleft()
+            function(argument)
+        else:
+            self.locked = 0

Added: vendor/Python/current/Lib/netrc.py
===================================================================
--- vendor/Python/current/Lib/netrc.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/netrc.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,111 @@
+"""An object-oriented interface to .netrc files."""
+
+# Module and documentation by Eric S. Raymond, 21 Dec 1998
+
+import os, shlex
+
+__all__ = ["netrc", "NetrcParseError"]
+
+
+class NetrcParseError(Exception):
+    """Exception raised on syntax errors in the .netrc file."""
+    def __init__(self, msg, filename=None, lineno=None):
+        self.filename = filename
+        self.lineno = lineno
+        self.msg = msg
+        Exception.__init__(self, msg)
+
+    def __str__(self):
+        return "%s (%s, line %s)" % (self.msg, self.filename, self.lineno)
+
+
+class netrc:
+    def __init__(self, file=None):
+        if file is None:
+            try:
+                file = os.path.join(os.environ['HOME'], ".netrc")
+            except KeyError:
+                raise IOError("Could not find .netrc: $HOME is not set")
+        fp = open(file)
+        self.hosts = {}
+        self.macros = {}
+        lexer = shlex.shlex(fp)
+        lexer.wordchars += r"""!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~"""
+        while 1:
+            # Look for a machine, default, or macdef top-level keyword
+            toplevel = tt = lexer.get_token()
+            if not tt:
+                break
+            elif tt == 'machine':
+                entryname = lexer.get_token()
+            elif tt == 'default':
+                entryname = 'default'
+            elif tt == 'macdef':                # Just skip to end of macdefs
+                entryname = lexer.get_token()
+                self.macros[entryname] = []
+                lexer.whitespace = ' \t'
+                while 1:
+                    line = lexer.instream.readline()
+                    if not line or line == '\012':
+                        lexer.whitespace = ' \t\r\n'
+                        break
+                    self.macros[entryname].append(line)
+                continue
+            else:
+                raise NetrcParseError(
+                    "bad toplevel token %r" % tt, file, lexer.lineno)
+
+            # We're looking at start of an entry for a named machine or default.
+            login = ''
+            account = password = None
+            self.hosts[entryname] = {}
+            while 1:
+                tt = lexer.get_token()
+                if (tt=='' or tt == 'machine' or
+                    tt == 'default' or tt =='macdef'):
+                    if password:
+                        self.hosts[entryname] = (login, account, password)
+                        lexer.push_token(tt)
+                        break
+                    else:
+                        raise NetrcParseError(
+                            "malformed %s entry %s terminated by %s"
+                            % (toplevel, entryname, repr(tt)),
+                            file, lexer.lineno)
+                elif tt == 'login' or tt == 'user':
+                    login = lexer.get_token()
+                elif tt == 'account':
+                    account = lexer.get_token()
+                elif tt == 'password':
+                    password = lexer.get_token()
+                else:
+                    raise NetrcParseError("bad follower token %r" % tt,
+                                          file, lexer.lineno)
+
+    def authenticators(self, host):
+        """Return a (user, account, password) tuple for given host."""
+        if host in self.hosts:
+            return self.hosts[host]
+        elif 'default' in self.hosts:
+            return self.hosts['default']
+        else:
+            return None
+
+    def __repr__(self):
+        """Dump the class data in the format of a .netrc file."""
+        rep = ""
+        for host in self.hosts.keys():
+            attrs = self.hosts[host]
+            rep = rep + "machine "+ host + "\n\tlogin " + repr(attrs[0]) + "\n"
+            if attrs[1]:
+                rep = rep + "account " + repr(attrs[1])
+            rep = rep + "\tpassword " + repr(attrs[2]) + "\n"
+        for macro in self.macros.keys():
+            rep = rep + "macdef " + macro + "\n"
+            for line in self.macros[macro]:
+                rep = rep + line
+            rep = rep + "\n"
+        return rep
+
+if __name__ == '__main__':
+    print netrc()

Added: vendor/Python/current/Lib/new.py
===================================================================
--- vendor/Python/current/Lib/new.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/new.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,17 @@
+"""Create new objects of various types.  Deprecated.
+
+This module is no longer required except for backward compatibility.
+Objects of most types can now be created by calling the type object.
+"""
+
+from types import ClassType as classobj
+from types import FunctionType as function
+from types import InstanceType as instance
+from types import MethodType as instancemethod
+from types import ModuleType as module
+
+# CodeType is not accessible in restricted execution mode
+try:
+    from types import CodeType as code
+except ImportError:
+    pass

Added: vendor/Python/current/Lib/nntplib.py
===================================================================
--- vendor/Python/current/Lib/nntplib.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/nntplib.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,628 @@
+"""An NNTP client class based on RFC 977: Network News Transfer Protocol.
+
+Example:
+
+>>> from nntplib import NNTP
+>>> s = NNTP('news')
+>>> resp, count, first, last, name = s.group('comp.lang.python')
+>>> print 'Group', name, 'has', count, 'articles, range', first, 'to', last
+Group comp.lang.python has 51 articles, range 5770 to 5821
+>>> resp, subs = s.xhdr('subject', first + '-' + last)
+>>> resp = s.quit()
+>>>
+
+Here 'resp' is the server response line.
+Error responses are turned into exceptions.
+
+To post an article from a file:
+>>> f = open(filename, 'r') # file containing article, including header
+>>> resp = s.post(f)
+>>>
+
+For descriptions of all methods, read the comments in the code below.
+Note that all arguments and return values representing article numbers
+are strings, not numbers, since they are rarely used for calculations.
+"""
+
+# RFC 977 by Brian Kantor and Phil Lapsley.
+# xover, xgtitle, xpath, date methods by Kevan Heydon
+
+
+# Imports
+import re
+import socket
+
+__all__ = ["NNTP","NNTPReplyError","NNTPTemporaryError",
+           "NNTPPermanentError","NNTPProtocolError","NNTPDataError",
+           "error_reply","error_temp","error_perm","error_proto",
+           "error_data",]
+
+# Exceptions raised when an error or invalid response is received
+class NNTPError(Exception):
+    """Base class for all nntplib exceptions"""
+    def __init__(self, *args):
+        Exception.__init__(self, *args)
+        try:
+            self.response = args[0]
+        except IndexError:
+            self.response = 'No response given'
+
+class NNTPReplyError(NNTPError):
+    """Unexpected [123]xx reply"""
+    pass
+
+class NNTPTemporaryError(NNTPError):
+    """4xx errors"""
+    pass
+
+class NNTPPermanentError(NNTPError):
+    """5xx errors"""
+    pass
+
+class NNTPProtocolError(NNTPError):
+    """Response does not begin with [1-5]"""
+    pass
+
+class NNTPDataError(NNTPError):
+    """Error in response data"""
+    pass
+
+# for backwards compatibility
+error_reply = NNTPReplyError
+error_temp = NNTPTemporaryError
+error_perm = NNTPPermanentError
+error_proto = NNTPProtocolError
+error_data = NNTPDataError
+
+
+
+# Standard port used by NNTP servers
+NNTP_PORT = 119
+
+
+# Response numbers that are followed by additional text (e.g. article)
+LONGRESP = ['100', '215', '220', '221', '222', '224', '230', '231', '282']
+
+
+# Line terminators (we always output CRLF, but accept any of CRLF, CR, LF)
+CRLF = '\r\n'
+
+
+
+# The class itself
+class NNTP:
+    def __init__(self, host, port=NNTP_PORT, user=None, password=None,
+                 readermode=None, usenetrc=True):
+        """Initialize an instance.  Arguments:
+        - host: hostname to connect to
+        - port: port to connect to (default the standard NNTP port)
+        - user: username to authenticate with
+        - password: password to use with username
+        - readermode: if true, send 'mode reader' command after
+                      connecting.
+
+        readermode is sometimes necessary if you are connecting to an
+        NNTP server on the local machine and intend to call
+        reader-specific comamnds, such as `group'.  If you get
+        unexpected NNTPPermanentErrors, you might need to set
+        readermode.
+        """
+        self.host = host
+        self.port = port
+        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        self.sock.connect((self.host, self.port))
+        self.file = self.sock.makefile('rb')
+        self.debugging = 0
+        self.welcome = self.getresp()
+
+        # 'mode reader' is sometimes necessary to enable 'reader' mode.
+        # However, the order in which 'mode reader' and 'authinfo' need to
+        # arrive differs between some NNTP servers. Try to send
+        # 'mode reader', and if it fails with an authorization failed
+        # error, try again after sending authinfo.
+        readermode_afterauth = 0
+        if readermode:
+            try:
+                self.welcome = self.shortcmd('mode reader')
+            except NNTPPermanentError:
+                # error 500, probably 'not implemented'
+                pass
+            except NNTPTemporaryError, e:
+                if user and e.response[:3] == '480':
+                    # Need authorization before 'mode reader'
+                    readermode_afterauth = 1
+                else:
+                    raise
+        # If no login/password was specified, try to get them from ~/.netrc
+        # Presume that if .netc has an entry, NNRP authentication is required.
+        try:
+            if usenetrc and not user:
+                import netrc
+                credentials = netrc.netrc()
+                auth = credentials.authenticators(host)
+                if auth:
+                    user = auth[0]
+                    password = auth[2]
+        except IOError:
+            pass
+        # Perform NNRP authentication if needed.
+        if user:
+            resp = self.shortcmd('authinfo user '+user)
+            if resp[:3] == '381':
+                if not password:
+                    raise NNTPReplyError(resp)
+                else:
+                    resp = self.shortcmd(
+                            'authinfo pass '+password)
+                    if resp[:3] != '281':
+                        raise NNTPPermanentError(resp)
+            if readermode_afterauth:
+                try:
+                    self.welcome = self.shortcmd('mode reader')
+                except NNTPPermanentError:
+                    # error 500, probably 'not implemented'
+                    pass
+
+
+    # Get the welcome message from the server
+    # (this is read and squirreled away by __init__()).
+    # If the response code is 200, posting is allowed;
+    # if it 201, posting is not allowed
+
+    def getwelcome(self):
+        """Get the welcome message from the server
+        (this is read and squirreled away by __init__()).
+        If the response code is 200, posting is allowed;
+        if it 201, posting is not allowed."""
+
+        if self.debugging: print '*welcome*', repr(self.welcome)
+        return self.welcome
+
+    def set_debuglevel(self, level):
+        """Set the debugging level.  Argument 'level' means:
+        0: no debugging output (default)
+        1: print commands and responses but not body text etc.
+        2: also print raw lines read and sent before stripping CR/LF"""
+
+        self.debugging = level
+    debug = set_debuglevel
+
+    def putline(self, line):
+        """Internal: send one line to the server, appending CRLF."""
+        line = line + CRLF
+        if self.debugging > 1: print '*put*', repr(line)
+        self.sock.sendall(line)
+
+    def putcmd(self, line):
+        """Internal: send one command to the server (through putline())."""
+        if self.debugging: print '*cmd*', repr(line)
+        self.putline(line)
+
+    def getline(self):
+        """Internal: return one line from the server, stripping CRLF.
+        Raise EOFError if the connection is closed."""
+        line = self.file.readline()
+        if self.debugging > 1:
+            print '*get*', repr(line)
+        if not line: raise EOFError
+        if line[-2:] == CRLF: line = line[:-2]
+        elif line[-1:] in CRLF: line = line[:-1]
+        return line
+
+    def getresp(self):
+        """Internal: get a response from the server.
+        Raise various errors if the response indicates an error."""
+        resp = self.getline()
+        if self.debugging: print '*resp*', repr(resp)
+        c = resp[:1]
+        if c == '4':
+            raise NNTPTemporaryError(resp)
+        if c == '5':
+            raise NNTPPermanentError(resp)
+        if c not in '123':
+            raise NNTPProtocolError(resp)
+        return resp
+
+    def getlongresp(self, file=None):
+        """Internal: get a response plus following text from the server.
+        Raise various errors if the response indicates an error."""
+
+        openedFile = None
+        try:
+            # If a string was passed then open a file with that name
+            if isinstance(file, str):
+                openedFile = file = open(file, "w")
+
+            resp = self.getresp()
+            if resp[:3] not in LONGRESP:
+                raise NNTPReplyError(resp)
+            list = []
+            while 1:
+                line = self.getline()
+                if line == '.':
+                    break
+                if line[:2] == '..':
+                    line = line[1:]
+                if file:
+                    file.write(line + "\n")
+                else:
+                    list.append(line)
+        finally:
+            # If this method created the file, then it must close it
+            if openedFile:
+                openedFile.close()
+
+        return resp, list
+
+    def shortcmd(self, line):
+        """Internal: send a command and get the response."""
+        self.putcmd(line)
+        return self.getresp()
+
+    def longcmd(self, line, file=None):
+        """Internal: send a command and get the response plus following text."""
+        self.putcmd(line)
+        return self.getlongresp(file)
+
+    def newgroups(self, date, time, file=None):
+        """Process a NEWGROUPS command.  Arguments:
+        - date: string 'yymmdd' indicating the date
+        - time: string 'hhmmss' indicating the time
+        Return:
+        - resp: server response if successful
+        - list: list of newsgroup names"""
+
+        return self.longcmd('NEWGROUPS ' + date + ' ' + time, file)
+
+    def newnews(self, group, date, time, file=None):
+        """Process a NEWNEWS command.  Arguments:
+        - group: group name or '*'
+        - date: string 'yymmdd' indicating the date
+        - time: string 'hhmmss' indicating the time
+        Return:
+        - resp: server response if successful
+        - list: list of message ids"""
+
+        cmd = 'NEWNEWS ' + group + ' ' + date + ' ' + time
+        return self.longcmd(cmd, file)
+
+    def list(self, file=None):
+        """Process a LIST command.  Return:
+        - resp: server response if successful
+        - list: list of (group, last, first, flag) (strings)"""
+
+        resp, list = self.longcmd('LIST', file)
+        for i in range(len(list)):
+            # Parse lines into "group last first flag"
+            list[i] = tuple(list[i].split())
+        return resp, list
+
+    def description(self, group):
+
+        """Get a description for a single group.  If more than one
+        group matches ('group' is a pattern), return the first.  If no
+        group matches, return an empty string.
+
+        This elides the response code from the server, since it can
+        only be '215' or '285' (for xgtitle) anyway.  If the response
+        code is needed, use the 'descriptions' method.
+
+        NOTE: This neither checks for a wildcard in 'group' nor does
+        it check whether the group actually exists."""
+
+        resp, lines = self.descriptions(group)
+        if len(lines) == 0:
+            return ""
+        else:
+            return lines[0][1]
+
+    def descriptions(self, group_pattern):
+        """Get descriptions for a range of groups."""
+        line_pat = re.compile("^(?P<group>[^ \t]+)[ \t]+(.*)$")
+        # Try the more std (acc. to RFC2980) LIST NEWSGROUPS first
+        resp, raw_lines = self.longcmd('LIST NEWSGROUPS ' + group_pattern)
+        if resp[:3] != "215":
+            # Now the deprecated XGTITLE.  This either raises an error
+            # or succeeds with the same output structure as LIST
+            # NEWSGROUPS.
+            resp, raw_lines = self.longcmd('XGTITLE ' + group_pattern)
+        lines = []
+        for raw_line in raw_lines:
+            match = line_pat.search(raw_line.strip())
+            if match:
+                lines.append(match.group(1, 2))
+        return resp, lines
+
+    def group(self, name):
+        """Process a GROUP command.  Argument:
+        - group: the group name
+        Returns:
+        - resp: server response if successful
+        - count: number of articles (string)
+        - first: first article number (string)
+        - last: last article number (string)
+        - name: the group name"""
+
+        resp = self.shortcmd('GROUP ' + name)
+        if resp[:3] != '211':
+            raise NNTPReplyError(resp)
+        words = resp.split()
+        count = first = last = 0
+        n = len(words)
+        if n > 1:
+            count = words[1]
+            if n > 2:
+                first = words[2]
+                if n > 3:
+                    last = words[3]
+                    if n > 4:
+                        name = words[4].lower()
+        return resp, count, first, last, name
+
+    def help(self, file=None):
+        """Process a HELP command.  Returns:
+        - resp: server response if successful
+        - list: list of strings"""
+
+        return self.longcmd('HELP',file)
+
+    def statparse(self, resp):
+        """Internal: parse the response of a STAT, NEXT or LAST command."""
+        if resp[:2] != '22':
+            raise NNTPReplyError(resp)
+        words = resp.split()
+        nr = 0
+        id = ''
+        n = len(words)
+        if n > 1:
+            nr = words[1]
+            if n > 2:
+                id = words[2]
+        return resp, nr, id
+
+    def statcmd(self, line):
+        """Internal: process a STAT, NEXT or LAST command."""
+        resp = self.shortcmd(line)
+        return self.statparse(resp)
+
+    def stat(self, id):
+        """Process a STAT command.  Argument:
+        - id: article number or message id
+        Returns:
+        - resp: server response if successful
+        - nr:   the article number
+        - id:   the message id"""
+
+        return self.statcmd('STAT ' + id)
+
+    def next(self):
+        """Process a NEXT command.  No arguments.  Return as for STAT."""
+        return self.statcmd('NEXT')
+
+    def last(self):
+        """Process a LAST command.  No arguments.  Return as for STAT."""
+        return self.statcmd('LAST')
+
+    def artcmd(self, line, file=None):
+        """Internal: process a HEAD, BODY or ARTICLE command."""
+        resp, list = self.longcmd(line, file)
+        resp, nr, id = self.statparse(resp)
+        return resp, nr, id, list
+
+    def head(self, id):
+        """Process a HEAD command.  Argument:
+        - id: article number or message id
+        Returns:
+        - resp: server response if successful
+        - nr: article number
+        - id: message id
+        - list: the lines of the article's header"""
+
+        return self.artcmd('HEAD ' + id)
+
+    def body(self, id, file=None):
+        """Process a BODY command.  Argument:
+        - id: article number or message id
+        - file: Filename string or file object to store the article in
+        Returns:
+        - resp: server response if successful
+        - nr: article number
+        - id: message id
+        - list: the lines of the article's body or an empty list
+                if file was used"""
+
+        return self.artcmd('BODY ' + id, file)
+
+    def article(self, id):
+        """Process an ARTICLE command.  Argument:
+        - id: article number or message id
+        Returns:
+        - resp: server response if successful
+        - nr: article number
+        - id: message id
+        - list: the lines of the article"""
+
+        return self.artcmd('ARTICLE ' + id)
+
+    def slave(self):
+        """Process a SLAVE command.  Returns:
+        - resp: server response if successful"""
+
+        return self.shortcmd('SLAVE')
+
+    def xhdr(self, hdr, str, file=None):
+        """Process an XHDR command (optional server extension).  Arguments:
+        - hdr: the header type (e.g. 'subject')
+        - str: an article nr, a message id, or a range nr1-nr2
+        Returns:
+        - resp: server response if successful
+        - list: list of (nr, value) strings"""
+
+        pat = re.compile('^([0-9]+) ?(.*)\n?')
+        resp, lines = self.longcmd('XHDR ' + hdr + ' ' + str, file)
+        for i in range(len(lines)):
+            line = lines[i]
+            m = pat.match(line)
+            if m:
+                lines[i] = m.group(1, 2)
+        return resp, lines
+
+    def xover(self, start, end, file=None):
+        """Process an XOVER command (optional server extension) Arguments:
+        - start: start of range
+        - end: end of range
+        Returns:
+        - resp: server response if successful
+        - list: list of (art-nr, subject, poster, date,
+                         id, references, size, lines)"""
+
+        resp, lines = self.longcmd('XOVER ' + start + '-' + end, file)
+        xover_lines = []
+        for line in lines:
+            elem = line.split("\t")
+            try:
+                xover_lines.append((elem[0],
+                                    elem[1],
+                                    elem[2],
+                                    elem[3],
+                                    elem[4],
+                                    elem[5].split(),
+                                    elem[6],
+                                    elem[7]))
+            except IndexError:
+                raise NNTPDataError(line)
+        return resp,xover_lines
+
+    def xgtitle(self, group, file=None):
+        """Process an XGTITLE command (optional server extension) Arguments:
+        - group: group name wildcard (i.e. news.*)
+        Returns:
+        - resp: server response if successful
+        - list: list of (name,title) strings"""
+
+        line_pat = re.compile("^([^ \t]+)[ \t]+(.*)$")
+        resp, raw_lines = self.longcmd('XGTITLE ' + group, file)
+        lines = []
+        for raw_line in raw_lines:
+            match = line_pat.search(raw_line.strip())
+            if match:
+                lines.append(match.group(1, 2))
+        return resp, lines
+
+    def xpath(self,id):
+        """Process an XPATH command (optional server extension) Arguments:
+        - id: Message id of article
+        Returns:
+        resp: server response if successful
+        path: directory path to article"""
+
+        resp = self.shortcmd("XPATH " + id)
+        if resp[:3] != '223':
+            raise NNTPReplyError(resp)
+        try:
+            [resp_num, path] = resp.split()
+        except ValueError:
+            raise NNTPReplyError(resp)
+        else:
+            return resp, path
+
+    def date (self):
+        """Process the DATE command. Arguments:
+        None
+        Returns:
+        resp: server response if successful
+        date: Date suitable for newnews/newgroups commands etc.
+        time: Time suitable for newnews/newgroups commands etc."""
+
+        resp = self.shortcmd("DATE")
+        if resp[:3] != '111':
+            raise NNTPReplyError(resp)
+        elem = resp.split()
+        if len(elem) != 2:
+            raise NNTPDataError(resp)
+        date = elem[1][2:8]
+        time = elem[1][-6:]
+        if len(date) != 6 or len(time) != 6:
+            raise NNTPDataError(resp)
+        return resp, date, time
+
+
+    def post(self, f):
+        """Process a POST command.  Arguments:
+        - f: file containing the article
+        Returns:
+        - resp: server response if successful"""
+
+        resp = self.shortcmd('POST')
+        # Raises error_??? if posting is not allowed
+        if resp[0] != '3':
+            raise NNTPReplyError(resp)
+        while 1:
+            line = f.readline()
+            if not line:
+                break
+            if line[-1] == '\n':
+                line = line[:-1]
+            if line[:1] == '.':
+                line = '.' + line
+            self.putline(line)
+        self.putline('.')
+        return self.getresp()
+
+    def ihave(self, id, f):
+        """Process an IHAVE command.  Arguments:
+        - id: message-id of the article
+        - f:  file containing the article
+        Returns:
+        - resp: server response if successful
+        Note that if the server refuses the article an exception is raised."""
+
+        resp = self.shortcmd('IHAVE ' + id)
+        # Raises error_??? if the server already has it
+        if resp[0] != '3':
+            raise NNTPReplyError(resp)
+        while 1:
+            line = f.readline()
+            if not line:
+                break
+            if line[-1] == '\n':
+                line = line[:-1]
+            if line[:1] == '.':
+                line = '.' + line
+            self.putline(line)
+        self.putline('.')
+        return self.getresp()
+
+    def quit(self):
+        """Process a QUIT command and close the socket.  Returns:
+        - resp: server response if successful"""
+
+        resp = self.shortcmd('QUIT')
+        self.file.close()
+        self.sock.close()
+        del self.file, self.sock
+        return resp
+
+
+# Test retrieval when run as a script.
+# Assumption: if there's a local news server, it's called 'news'.
+# Assumption: if user queries a remote news server, it's named
+# in the environment variable NNTPSERVER (used by slrn and kin)
+# and we want readermode off.
+if __name__ == '__main__':
+    import os
+    newshost = 'news' and os.environ["NNTPSERVER"]
+    if newshost.find('.') == -1:
+        mode = 'readermode'
+    else:
+        mode = None
+    s = NNTP(newshost, readermode=mode)
+    resp, count, first, last, name = s.group('comp.lang.python')
+    print resp
+    print 'Group', name, 'has', count, 'articles, range', first, 'to', last
+    resp, subs = s.xhdr('subject', first + '-' + last)
+    print resp
+    for item in subs:
+        print "%7s %s" % item
+    resp = s.quit()
+    print resp

Added: vendor/Python/current/Lib/ntpath.py
===================================================================
--- vendor/Python/current/Lib/ntpath.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/ntpath.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,511 @@
+# Module 'ntpath' -- common operations on WinNT/Win95 pathnames
+"""Common pathname manipulations, WindowsNT/95 version.
+
+Instead of importing this module directly, import os and refer to this
+module as os.path.
+"""
+
+import os
+import stat
+import sys
+
+__all__ = ["normcase","isabs","join","splitdrive","split","splitext",
+           "basename","dirname","commonprefix","getsize","getmtime",
+           "getatime","getctime", "islink","exists","lexists","isdir","isfile",
+           "ismount","walk","expanduser","expandvars","normpath","abspath",
+           "splitunc","curdir","pardir","sep","pathsep","defpath","altsep",
+           "extsep","devnull","realpath","supports_unicode_filenames"]
+
+# strings representing various path-related bits and pieces
+curdir = '.'
+pardir = '..'
+extsep = '.'
+sep = '\\'
+pathsep = ';'
+altsep = '/'
+defpath = '.;C:\\bin'
+if 'ce' in sys.builtin_module_names:
+    defpath = '\\Windows'
+elif 'os2' in sys.builtin_module_names:
+    # OS/2 w/ VACPP
+    altsep = '/'
+devnull = 'nul'
+
+# Normalize the case of a pathname and map slashes to backslashes.
+# Other normalizations (such as optimizing '../' away) are not done
+# (this is done by normpath).
+
+def normcase(s):
+    """Normalize case of pathname.
+
+    Makes all characters lowercase and all slashes into backslashes."""
+    return s.replace("/", "\\").lower()
+
+
+# Return whether a path is absolute.
+# Trivial in Posix, harder on the Mac or MS-DOS.
+# For DOS it is absolute if it starts with a slash or backslash (current
+# volume), or if a pathname after the volume letter and colon / UNC resource
+# starts with a slash or backslash.
+
+def isabs(s):
+    """Test whether a path is absolute"""
+    s = splitdrive(s)[1]
+    return s != '' and s[:1] in '/\\'
+
+
+# Join two (or more) paths.
+
+def join(a, *p):
+    """Join two or more pathname components, inserting "\\" as needed"""
+    path = a
+    for b in p:
+        b_wins = 0  # set to 1 iff b makes path irrelevant
+        if path == "":
+            b_wins = 1
+
+        elif isabs(b):
+            # This probably wipes out path so far.  However, it's more
+            # complicated if path begins with a drive letter:
+            #     1. join('c:', '/a') == 'c:/a'
+            #     2. join('c:/', '/a') == 'c:/a'
+            # But
+            #     3. join('c:/a', '/b') == '/b'
+            #     4. join('c:', 'd:/') = 'd:/'
+            #     5. join('c:/', 'd:/') = 'd:/'
+            if path[1:2] != ":" or b[1:2] == ":":
+                # Path doesn't start with a drive letter, or cases 4 and 5.
+                b_wins = 1
+
+            # Else path has a drive letter, and b doesn't but is absolute.
+            elif len(path) > 3 or (len(path) == 3 and
+                                   path[-1] not in "/\\"):
+                # case 3
+                b_wins = 1
+
+        if b_wins:
+            path = b
+        else:
+            # Join, and ensure there's a separator.
+            assert len(path) > 0
+            if path[-1] in "/\\":
+                if b and b[0] in "/\\":
+                    path += b[1:]
+                else:
+                    path += b
+            elif path[-1] == ":":
+                path += b
+            elif b:
+                if b[0] in "/\\":
+                    path += b
+                else:
+                    path += "\\" + b
+            else:
+                # path is not empty and does not end with a backslash,
+                # but b is empty; since, e.g., split('a/') produces
+                # ('a', ''), it's best if join() adds a backslash in
+                # this case.
+                path += '\\'
+
+    return path
+
+
+# Split a path in a drive specification (a drive letter followed by a
+# colon) and the path specification.
+# It is always true that drivespec + pathspec == p
+def splitdrive(p):
+    """Split a pathname into drive and path specifiers. Returns a 2-tuple
+"(drive,path)";  either part may be empty"""
+    if p[1:2] == ':':
+        return p[0:2], p[2:]
+    return '', p
+
+
+# Parse UNC paths
+def splitunc(p):
+    """Split a pathname into UNC mount point and relative path specifiers.
+
+    Return a 2-tuple (unc, rest); either part may be empty.
+    If unc is not empty, it has the form '//host/mount' (or similar
+    using backslashes).  unc+rest is always the input path.
+    Paths containing drive letters never have an UNC part.
+    """
+    if p[1:2] == ':':
+        return '', p # Drive letter present
+    firstTwo = p[0:2]
+    if firstTwo == '//' or firstTwo == '\\\\':
+        # is a UNC path:
+        # vvvvvvvvvvvvvvvvvvvv equivalent to drive letter
+        # \\machine\mountpoint\directories...
+        #           directory ^^^^^^^^^^^^^^^
+        normp = normcase(p)
+        index = normp.find('\\', 2)
+        if index == -1:
+            ##raise RuntimeError, 'illegal UNC path: "' + p + '"'
+            return ("", p)
+        index = normp.find('\\', index + 1)
+        if index == -1:
+            index = len(p)
+        return p[:index], p[index:]
+    return '', p
+
+
+# Split a path in head (everything up to the last '/') and tail (the
+# rest).  After the trailing '/' is stripped, the invariant
+# join(head, tail) == p holds.
+# The resulting head won't end in '/' unless it is the root.
+
+def split(p):
+    """Split a pathname.
+
+    Return tuple (head, tail) where tail is everything after the final slash.
+    Either part may be empty."""
+
+    d, p = splitdrive(p)
+    # set i to index beyond p's last slash
+    i = len(p)
+    while i and p[i-1] not in '/\\':
+        i = i - 1
+    head, tail = p[:i], p[i:]  # now tail has no slashes
+    # remove trailing slashes from head, unless it's all slashes
+    head2 = head
+    while head2 and head2[-1] in '/\\':
+        head2 = head2[:-1]
+    head = head2 or head
+    return d + head, tail
+
+
+# Split a path in root and extension.
+# The extension is everything starting at the last dot in the last
+# pathname component; the root is everything before that.
+# It is always true that root + ext == p.
+
+def splitext(p):
+    """Split the extension from a pathname.
+
+    Extension is everything from the last dot to the end.
+    Return (root, ext), either part may be empty."""
+
+    i = p.rfind('.')
+    if i<=max(p.rfind('/'), p.rfind('\\')):
+        return p, ''
+    else:
+        return p[:i], p[i:]
+
+
+# Return the tail (basename) part of a path.
+
+def basename(p):
+    """Returns the final component of a pathname"""
+    return split(p)[1]
+
+
+# Return the head (dirname) part of a path.
+
+def dirname(p):
+    """Returns the directory component of a pathname"""
+    return split(p)[0]
+
+
+# Return the longest prefix of all list elements.
+
+def commonprefix(m):
+    "Given a list of pathnames, returns the longest common leading component"
+    if not m: return ''
+    s1 = min(m)
+    s2 = max(m)
+    n = min(len(s1), len(s2))
+    for i in xrange(n):
+        if s1[i] != s2[i]:
+            return s1[:i]
+    return s1[:n]
+
+
+# Get size, mtime, atime of files.
+
+def getsize(filename):
+    """Return the size of a file, reported by os.stat()"""
+    return os.stat(filename).st_size
+
+def getmtime(filename):
+    """Return the last modification time of a file, reported by os.stat()"""
+    return os.stat(filename).st_mtime
+
+def getatime(filename):
+    """Return the last access time of a file, reported by os.stat()"""
+    return os.stat(filename).st_atime
+
+def getctime(filename):
+    """Return the creation time of a file, reported by os.stat()."""
+    return os.stat(filename).st_ctime
+
+# Is a path a symbolic link?
+# This will always return false on systems where posix.lstat doesn't exist.
+
+def islink(path):
+    """Test for symbolic link.  On WindowsNT/95 always returns false"""
+    return False
+
+
+# Does a path exist?
+
+def exists(path):
+    """Test whether a path exists"""
+    try:
+        st = os.stat(path)
+    except os.error:
+        return False
+    return True
+
+lexists = exists
+
+
+# Is a path a dos directory?
+# This follows symbolic links, so both islink() and isdir() can be true
+# for the same path.
+
+def isdir(path):
+    """Test whether a path is a directory"""
+    try:
+        st = os.stat(path)
+    except os.error:
+        return False
+    return stat.S_ISDIR(st.st_mode)
+
+
+# Is a path a regular file?
+# This follows symbolic links, so both islink() and isdir() can be true
+# for the same path.
+
+def isfile(path):
+    """Test whether a path is a regular file"""
+    try:
+        st = os.stat(path)
+    except os.error:
+        return False
+    return stat.S_ISREG(st.st_mode)
+
+
+# Is a path a mount point?  Either a root (with or without drive letter)
+# or an UNC path with at most a / or \ after the mount point.
+
+def ismount(path):
+    """Test whether a path is a mount point (defined as root of drive)"""
+    unc, rest = splitunc(path)
+    if unc:
+        return rest in ("", "/", "\\")
+    p = splitdrive(path)[1]
+    return len(p) == 1 and p[0] in '/\\'
+
+
+# Directory tree walk.
+# For each directory under top (including top itself, but excluding
+# '.' and '..'), func(arg, dirname, filenames) is called, where
+# dirname is the name of the directory and filenames is the list
+# of files (and subdirectories etc.) in the directory.
+# The func may modify the filenames list, to implement a filter,
+# or to impose a different order of visiting.
+
+def walk(top, func, arg):
+    """Directory tree walk with callback function.
+
+    For each directory in the directory tree rooted at top (including top
+    itself, but excluding '.' and '..'), call func(arg, dirname, fnames).
+    dirname is the name of the directory, and fnames a list of the names of
+    the files and subdirectories in dirname (excluding '.' and '..').  func
+    may modify the fnames list in-place (e.g. via del or slice assignment),
+    and walk will only recurse into the subdirectories whose names remain in
+    fnames; this can be used to implement a filter, or to impose a specific
+    order of visiting.  No semantics are defined for, or required of, arg,
+    beyond that arg is always passed to func.  It can be used, e.g., to pass
+    a filename pattern, or a mutable object designed to accumulate
+    statistics.  Passing None for arg is common."""
+
+    try:
+        names = os.listdir(top)
+    except os.error:
+        return
+    func(arg, top, names)
+    exceptions = ('.', '..')
+    for name in names:
+        if name not in exceptions:
+            name = join(top, name)
+            if isdir(name):
+                walk(name, func, arg)
+
+
+# Expand paths beginning with '~' or '~user'.
+# '~' means $HOME; '~user' means that user's home directory.
+# If the path doesn't begin with '~', or if the user or $HOME is unknown,
+# the path is returned unchanged (leaving error reporting to whatever
+# function is called with the expanded path as argument).
+# See also module 'glob' for expansion of *, ? and [...] in pathnames.
+# (A function should also be defined to do full *sh-style environment
+# variable expansion.)
+
+def expanduser(path):
+    """Expand ~ and ~user constructs.
+
+    If user or $HOME is unknown, do nothing."""
+    if path[:1] != '~':
+        return path
+    i, n = 1, len(path)
+    while i < n and path[i] not in '/\\':
+        i = i + 1
+    if i == 1:
+        if 'HOME' in os.environ:
+            userhome = os.environ['HOME']
+        elif not 'HOMEPATH' in os.environ:
+            return path
+        else:
+            try:
+                drive = os.environ['HOMEDRIVE']
+            except KeyError:
+                drive = ''
+            userhome = join(drive, os.environ['HOMEPATH'])
+    else:
+        return path
+    return userhome + path[i:]
+
+
+# Expand paths containing shell variable substitutions.
+# The following rules apply:
+#       - no expansion within single quotes
+#       - no escape character, except for '$$' which is translated into '$'
+#       - ${varname} is accepted.
+#       - varnames can be made out of letters, digits and the character '_'
+# XXX With COMMAND.COM you can use any characters in a variable name,
+# XXX except '^|<>='.
+
+def expandvars(path):
+    """Expand shell variables of form $var and ${var}.
+
+    Unknown variables are left unchanged."""
+    if '$' not in path:
+        return path
+    import string
+    varchars = string.ascii_letters + string.digits + '_-'
+    res = ''
+    index = 0
+    pathlen = len(path)
+    while index < pathlen:
+        c = path[index]
+        if c == '\'':   # no expansion within single quotes
+            path = path[index + 1:]
+            pathlen = len(path)
+            try:
+                index = path.index('\'')
+                res = res + '\'' + path[:index + 1]
+            except ValueError:
+                res = res + path
+                index = pathlen - 1
+        elif c == '$':  # variable or '$$'
+            if path[index + 1:index + 2] == '$':
+                res = res + c
+                index = index + 1
+            elif path[index + 1:index + 2] == '{':
+                path = path[index+2:]
+                pathlen = len(path)
+                try:
+                    index = path.index('}')
+                    var = path[:index]
+                    if var in os.environ:
+                        res = res + os.environ[var]
+                except ValueError:
+                    res = res + path
+                    index = pathlen - 1
+            else:
+                var = ''
+                index = index + 1
+                c = path[index:index + 1]
+                while c != '' and c in varchars:
+                    var = var + c
+                    index = index + 1
+                    c = path[index:index + 1]
+                if var in os.environ:
+                    res = res + os.environ[var]
+                if c != '':
+                    res = res + c
+        else:
+            res = res + c
+        index = index + 1
+    return res
+
+
+# Normalize a path, e.g. A//B, A/./B and A/foo/../B all become A\B.
+# Previously, this function also truncated pathnames to 8+3 format,
+# but as this module is called "ntpath", that's obviously wrong!
+
+def normpath(path):
+    """Normalize path, eliminating double slashes, etc."""
+    path = path.replace("/", "\\")
+    prefix, path = splitdrive(path)
+    # We need to be careful here. If the prefix is empty, and the path starts
+    # with a backslash, it could either be an absolute path on the current
+    # drive (\dir1\dir2\file) or a UNC filename (\\server\mount\dir1\file). It
+    # is therefore imperative NOT to collapse multiple backslashes blindly in
+    # that case.
+    # The code below preserves multiple backslashes when there is no drive
+    # letter. This means that the invalid filename \\\a\b is preserved
+    # unchanged, where a\\\b is normalised to a\b. It's not clear that there
+    # is any better behaviour for such edge cases.
+    if prefix == '':
+        # No drive letter - preserve initial backslashes
+        while path[:1] == "\\":
+            prefix = prefix + "\\"
+            path = path[1:]
+    else:
+        # We have a drive letter - collapse initial backslashes
+        if path.startswith("\\"):
+            prefix = prefix + "\\"
+            path = path.lstrip("\\")
+    comps = path.split("\\")
+    i = 0
+    while i < len(comps):
+        if comps[i] in ('.', ''):
+            del comps[i]
+        elif comps[i] == '..':
+            if i > 0 and comps[i-1] != '..':
+                del comps[i-1:i+1]
+                i -= 1
+            elif i == 0 and prefix.endswith("\\"):
+                del comps[i]
+            else:
+                i += 1
+        else:
+            i += 1
+    # If the path is now empty, substitute '.'
+    if not prefix and not comps:
+        comps.append('.')
+    return prefix + "\\".join(comps)
+
+
+# Return an absolute path.
+try:
+    from nt import _getfullpathname
+
+except ImportError: # not running on Windows - mock up something sensible
+    def abspath(path):
+        """Return the absolute version of a path."""
+        if not isabs(path):
+            path = join(os.getcwd(), path)
+        return normpath(path)
+
+else:  # use native Windows method on Windows
+    def abspath(path):
+        """Return the absolute version of a path."""
+
+        if path: # Empty path must return current working directory.
+            try:
+                path = _getfullpathname(path)
+            except WindowsError:
+                pass # Bad path - return unchanged.
+        else:
+            path = os.getcwd()
+        return normpath(path)
+
+# realpath is a no-op on systems without islink support
+realpath = abspath
+# Win9x family and earlier have no Unicode filename support.
+supports_unicode_filenames = (hasattr(sys, "getwindowsversion") and
+                              sys.getwindowsversion()[3] >= 2)

Added: vendor/Python/current/Lib/nturl2path.py
===================================================================
--- vendor/Python/current/Lib/nturl2path.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/nturl2path.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,63 @@
+"""Convert a NT pathname to a file URL and vice versa."""
+
+def url2pathname(url):
+    """OS-specific conversion from a relative URL of the 'file' scheme
+    to a file system path; not recommended for general use."""
+    # e.g.
+    # ///C|/foo/bar/spam.foo
+    # becomes
+    # C:\foo\bar\spam.foo
+    import string, urllib
+    # Windows itself uses ":" even in URLs.
+    url = url.replace(':', '|')
+    if not '|' in url:
+        # No drive specifier, just convert slashes
+        if url[:4] == '////':
+            # path is something like ////host/path/on/remote/host
+            # convert this to \\host\path\on\remote\host
+            # (notice halving of slashes at the start of the path)
+            url = url[2:]
+        components = url.split('/')
+        # make sure not to convert quoted slashes :-)
+        return urllib.unquote('\\'.join(components))
+    comp = url.split('|')
+    if len(comp) != 2 or comp[0][-1] not in string.ascii_letters:
+        error = 'Bad URL: ' + url
+        raise IOError, error
+    drive = comp[0][-1].upper()
+    components = comp[1].split('/')
+    path = drive + ':'
+    for  comp in components:
+        if comp:
+            path = path + '\\' + urllib.unquote(comp)
+    return path
+
+def pathname2url(p):
+    """OS-specific conversion from a file system path to a relative URL
+    of the 'file' scheme; not recommended for general use."""
+    # e.g.
+    # C:\foo\bar\spam.foo
+    # becomes
+    # ///C|/foo/bar/spam.foo
+    import urllib
+    if not ':' in p:
+        # No drive specifier, just convert slashes and quote the name
+        if p[:2] == '\\\\':
+        # path is something like \\host\path\on\remote\host
+        # convert this to ////host/path/on/remote/host
+        # (notice doubling of slashes at the start of the path)
+            p = '\\\\' + p
+        components = p.split('\\')
+        return urllib.quote('/'.join(components))
+    comp = p.split(':')
+    if len(comp) != 2 or len(comp[0]) > 1:
+        error = 'Bad path: ' + p
+        raise IOError, error
+
+    drive = urllib.quote(comp[0].upper())
+    components = comp[1].split('\\')
+    path = '///' + drive + '|'
+    for comp in components:
+        if comp:
+            path = path + '/' + urllib.quote(comp)
+    return path

Added: vendor/Python/current/Lib/opcode.py
===================================================================
--- vendor/Python/current/Lib/opcode.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/opcode.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,185 @@
+
+"""
+opcode module - potentially shared between dis and other modules which
+operate on bytecodes (e.g. peephole optimizers).
+"""
+
+__all__ = ["cmp_op", "hasconst", "hasname", "hasjrel", "hasjabs",
+           "haslocal", "hascompare", "hasfree", "opname", "opmap",
+           "HAVE_ARGUMENT", "EXTENDED_ARG"]
+
+cmp_op = ('<', '<=', '==', '!=', '>', '>=', 'in', 'not in', 'is',
+        'is not', 'exception match', 'BAD')
+
+hasconst = []
+hasname = []
+hasjrel = []
+hasjabs = []
+haslocal = []
+hascompare = []
+hasfree = []
+
+opmap = {}
+opname = [''] * 256
+for op in range(256): opname[op] = '<%r>' % (op,)
+del op
+
+def def_op(name, op):
+    opname[op] = name
+    opmap[name] = op
+
+def name_op(name, op):
+    def_op(name, op)
+    hasname.append(op)
+
+def jrel_op(name, op):
+    def_op(name, op)
+    hasjrel.append(op)
+
+def jabs_op(name, op):
+    def_op(name, op)
+    hasjabs.append(op)
+
+# Instruction opcodes for compiled code
+# Blank lines correspond to available opcodes
+
+def_op('STOP_CODE', 0)
+def_op('POP_TOP', 1)
+def_op('ROT_TWO', 2)
+def_op('ROT_THREE', 3)
+def_op('DUP_TOP', 4)
+def_op('ROT_FOUR', 5)
+
+def_op('NOP', 9)
+def_op('UNARY_POSITIVE', 10)
+def_op('UNARY_NEGATIVE', 11)
+def_op('UNARY_NOT', 12)
+def_op('UNARY_CONVERT', 13)
+
+def_op('UNARY_INVERT', 15)
+
+def_op('LIST_APPEND', 18)
+def_op('BINARY_POWER', 19)
+def_op('BINARY_MULTIPLY', 20)
+def_op('BINARY_DIVIDE', 21)
+def_op('BINARY_MODULO', 22)
+def_op('BINARY_ADD', 23)
+def_op('BINARY_SUBTRACT', 24)
+def_op('BINARY_SUBSCR', 25)
+def_op('BINARY_FLOOR_DIVIDE', 26)
+def_op('BINARY_TRUE_DIVIDE', 27)
+def_op('INPLACE_FLOOR_DIVIDE', 28)
+def_op('INPLACE_TRUE_DIVIDE', 29)
+def_op('SLICE+0', 30)
+def_op('SLICE+1', 31)
+def_op('SLICE+2', 32)
+def_op('SLICE+3', 33)
+
+def_op('STORE_SLICE+0', 40)
+def_op('STORE_SLICE+1', 41)
+def_op('STORE_SLICE+2', 42)
+def_op('STORE_SLICE+3', 43)
+
+def_op('DELETE_SLICE+0', 50)
+def_op('DELETE_SLICE+1', 51)
+def_op('DELETE_SLICE+2', 52)
+def_op('DELETE_SLICE+3', 53)
+
+def_op('INPLACE_ADD', 55)
+def_op('INPLACE_SUBTRACT', 56)
+def_op('INPLACE_MULTIPLY', 57)
+def_op('INPLACE_DIVIDE', 58)
+def_op('INPLACE_MODULO', 59)
+def_op('STORE_SUBSCR', 60)
+def_op('DELETE_SUBSCR', 61)
+def_op('BINARY_LSHIFT', 62)
+def_op('BINARY_RSHIFT', 63)
+def_op('BINARY_AND', 64)
+def_op('BINARY_XOR', 65)
+def_op('BINARY_OR', 66)
+def_op('INPLACE_POWER', 67)
+def_op('GET_ITER', 68)
+
+def_op('PRINT_EXPR', 70)
+def_op('PRINT_ITEM', 71)
+def_op('PRINT_NEWLINE', 72)
+def_op('PRINT_ITEM_TO', 73)
+def_op('PRINT_NEWLINE_TO', 74)
+def_op('INPLACE_LSHIFT', 75)
+def_op('INPLACE_RSHIFT', 76)
+def_op('INPLACE_AND', 77)
+def_op('INPLACE_XOR', 78)
+def_op('INPLACE_OR', 79)
+def_op('BREAK_LOOP', 80)
+def_op('WITH_CLEANUP', 81)
+def_op('LOAD_LOCALS', 82)
+def_op('RETURN_VALUE', 83)
+def_op('IMPORT_STAR', 84)
+def_op('EXEC_STMT', 85)
+def_op('YIELD_VALUE', 86)
+def_op('POP_BLOCK', 87)
+def_op('END_FINALLY', 88)
+def_op('BUILD_CLASS', 89)
+
+HAVE_ARGUMENT = 90              # Opcodes from here have an argument:
+
+name_op('STORE_NAME', 90)       # Index in name list
+name_op('DELETE_NAME', 91)      # ""
+def_op('UNPACK_SEQUENCE', 92)   # Number of tuple items
+jrel_op('FOR_ITER', 93)
+
+name_op('STORE_ATTR', 95)       # Index in name list
+name_op('DELETE_ATTR', 96)      # ""
+name_op('STORE_GLOBAL', 97)     # ""
+name_op('DELETE_GLOBAL', 98)    # ""
+def_op('DUP_TOPX', 99)          # number of items to duplicate
+def_op('LOAD_CONST', 100)       # Index in const list
+hasconst.append(100)
+name_op('LOAD_NAME', 101)       # Index in name list
+def_op('BUILD_TUPLE', 102)      # Number of tuple items
+def_op('BUILD_LIST', 103)       # Number of list items
+def_op('BUILD_MAP', 104)        # Always zero for now
+name_op('LOAD_ATTR', 105)       # Index in name list
+def_op('COMPARE_OP', 106)       # Comparison operator
+hascompare.append(106)
+name_op('IMPORT_NAME', 107)     # Index in name list
+name_op('IMPORT_FROM', 108)     # Index in name list
+
+jrel_op('JUMP_FORWARD', 110)    # Number of bytes to skip
+jrel_op('JUMP_IF_FALSE', 111)   # ""
+jrel_op('JUMP_IF_TRUE', 112)    # ""
+jabs_op('JUMP_ABSOLUTE', 113)   # Target byte offset from beginning of code
+
+name_op('LOAD_GLOBAL', 116)     # Index in name list
+
+jabs_op('CONTINUE_LOOP', 119)   # Target address
+jrel_op('SETUP_LOOP', 120)      # Distance to target address
+jrel_op('SETUP_EXCEPT', 121)    # ""
+jrel_op('SETUP_FINALLY', 122)   # ""
+
+def_op('LOAD_FAST', 124)        # Local variable number
+haslocal.append(124)
+def_op('STORE_FAST', 125)       # Local variable number
+haslocal.append(125)
+def_op('DELETE_FAST', 126)      # Local variable number
+haslocal.append(126)
+
+def_op('RAISE_VARARGS', 130)    # Number of raise arguments (1, 2, or 3)
+def_op('CALL_FUNCTION', 131)    # #args + (#kwargs << 8)
+def_op('MAKE_FUNCTION', 132)    # Number of args with default values
+def_op('BUILD_SLICE', 133)      # Number of items
+def_op('MAKE_CLOSURE', 134)
+def_op('LOAD_CLOSURE', 135)
+hasfree.append(135)
+def_op('LOAD_DEREF', 136)
+hasfree.append(136)
+def_op('STORE_DEREF', 137)
+hasfree.append(137)
+
+def_op('CALL_FUNCTION_VAR', 140)     # #args + (#kwargs << 8)
+def_op('CALL_FUNCTION_KW', 141)      # #args + (#kwargs << 8)
+def_op('CALL_FUNCTION_VAR_KW', 142)  # #args + (#kwargs << 8)
+def_op('EXTENDED_ARG', 143)
+EXTENDED_ARG = 143
+
+del def_op, name_op, jrel_op, jabs_op

Added: vendor/Python/current/Lib/optparse.py
===================================================================
--- vendor/Python/current/Lib/optparse.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/optparse.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1682 @@
+"""optparse - a powerful, extensible, and easy-to-use option parser.
+
+By Greg Ward <gward at python.net>
+
+Originally distributed as Optik; see http://optik.sourceforge.net/ .
+
+If you have problems with this module, please do not file bugs,
+patches, or feature requests with Python; instead, use Optik's
+SourceForge project page:
+  http://sourceforge.net/projects/optik
+
+For support, use the optik-users at lists.sourceforge.net mailing list
+(http://lists.sourceforge.net/lists/listinfo/optik-users).
+"""
+
+# Python developers: please do not make changes to this file, since
+# it is automatically generated from the Optik source code.
+
+__version__ = "1.5.3"
+
+__all__ = ['Option',
+           'SUPPRESS_HELP',
+           'SUPPRESS_USAGE',
+           'Values',
+           'OptionContainer',
+           'OptionGroup',
+           'OptionParser',
+           'HelpFormatter',
+           'IndentedHelpFormatter',
+           'TitledHelpFormatter',
+           'OptParseError',
+           'OptionError',
+           'OptionConflictError',
+           'OptionValueError',
+           'BadOptionError']
+
+__copyright__ = """
+Copyright (c) 2001-2006 Gregory P. Ward.  All rights reserved.
+Copyright (c) 2002-2006 Python Software Foundation.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+  * Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+
+  * Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+
+  * Neither the name of the author nor the names of its
+    contributors may be used to endorse or promote products derived from
+    this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+"""
+
+import sys, os
+import types
+import textwrap
+
+def _repr(self):
+    return "<%s at 0x%x: %s>" % (self.__class__.__name__, id(self), self)
+
+
+# This file was generated from:
+#   Id: option_parser.py 527 2006-07-23 15:21:30Z greg
+#   Id: option.py 522 2006-06-11 16:22:03Z gward
+#   Id: help.py 527 2006-07-23 15:21:30Z greg
+#   Id: errors.py 509 2006-04-20 00:58:24Z gward
+
+try:
+    from gettext import gettext
+except ImportError:
+    def gettext(message):
+        return message
+_ = gettext
+
+
+class OptParseError (Exception):
+    def __init__(self, msg):
+        self.msg = msg
+
+    def __str__(self):
+        return self.msg
+
+
+class OptionError (OptParseError):
+    """
+    Raised if an Option instance is created with invalid or
+    inconsistent arguments.
+    """
+
+    def __init__(self, msg, option):
+        self.msg = msg
+        self.option_id = str(option)
+
+    def __str__(self):
+        if self.option_id:
+            return "option %s: %s" % (self.option_id, self.msg)
+        else:
+            return self.msg
+
+class OptionConflictError (OptionError):
+    """
+    Raised if conflicting options are added to an OptionParser.
+    """
+
+class OptionValueError (OptParseError):
+    """
+    Raised if an invalid option value is encountered on the command
+    line.
+    """
+
+class BadOptionError (OptParseError):
+    """
+    Raised if an invalid option is seen on the command line.
+    """
+    def __init__(self, opt_str):
+        self.opt_str = opt_str
+
+    def __str__(self):
+        return _("no such option: %s") % self.opt_str
+
+class AmbiguousOptionError (BadOptionError):
+    """
+    Raised if an ambiguous option is seen on the command line.
+    """
+    def __init__(self, opt_str, possibilities):
+        BadOptionError.__init__(self, opt_str)
+        self.possibilities = possibilities
+
+    def __str__(self):
+        return (_("ambiguous option: %s (%s?)")
+                % (self.opt_str, ", ".join(self.possibilities)))
+
+
+class HelpFormatter:
+
+    """
+    Abstract base class for formatting option help.  OptionParser
+    instances should use one of the HelpFormatter subclasses for
+    formatting help; by default IndentedHelpFormatter is used.
+
+    Instance attributes:
+      parser : OptionParser
+        the controlling OptionParser instance
+      indent_increment : int
+        the number of columns to indent per nesting level
+      max_help_position : int
+        the maximum starting column for option help text
+      help_position : int
+        the calculated starting column for option help text;
+        initially the same as the maximum
+      width : int
+        total number of columns for output (pass None to constructor for
+        this value to be taken from the $COLUMNS environment variable)
+      level : int
+        current indentation level
+      current_indent : int
+        current indentation level (in columns)
+      help_width : int
+        number of columns available for option help text (calculated)
+      default_tag : str
+        text to replace with each option's default value, "%default"
+        by default.  Set to false value to disable default value expansion.
+      option_strings : { Option : str }
+        maps Option instances to the snippet of help text explaining
+        the syntax of that option, e.g. "-h, --help" or
+        "-fFILE, --file=FILE"
+      _short_opt_fmt : str
+        format string controlling how short options with values are
+        printed in help text.  Must be either "%s%s" ("-fFILE") or
+        "%s %s" ("-f FILE"), because those are the two syntaxes that
+        Optik supports.
+      _long_opt_fmt : str
+        similar but for long options; must be either "%s %s" ("--file FILE")
+        or "%s=%s" ("--file=FILE").
+    """
+
+    NO_DEFAULT_VALUE = "none"
+
+    def __init__(self,
+                 indent_increment,
+                 max_help_position,
+                 width,
+                 short_first):
+        self.parser = None
+        self.indent_increment = indent_increment
+        self.help_position = self.max_help_position = max_help_position
+        if width is None:
+            try:
+                width = int(os.environ['COLUMNS'])
+            except (KeyError, ValueError):
+                width = 80
+            width -= 2
+        self.width = width
+        self.current_indent = 0
+        self.level = 0
+        self.help_width = None          # computed later
+        self.short_first = short_first
+        self.default_tag = "%default"
+        self.option_strings = {}
+        self._short_opt_fmt = "%s %s"
+        self._long_opt_fmt = "%s=%s"
+
+    def set_parser(self, parser):
+        self.parser = parser
+
+    def set_short_opt_delimiter(self, delim):
+        if delim not in ("", " "):
+            raise ValueError(
+                "invalid metavar delimiter for short options: %r" % delim)
+        self._short_opt_fmt = "%s" + delim + "%s"
+
+    def set_long_opt_delimiter(self, delim):
+        if delim not in ("=", " "):
+            raise ValueError(
+                "invalid metavar delimiter for long options: %r" % delim)
+        self._long_opt_fmt = "%s" + delim + "%s"
+
+    def indent(self):
+        self.current_indent += self.indent_increment
+        self.level += 1
+
+    def dedent(self):
+        self.current_indent -= self.indent_increment
+        assert self.current_indent >= 0, "Indent decreased below 0."
+        self.level -= 1
+
+    def format_usage(self, usage):
+        raise NotImplementedError, "subclasses must implement"
+
+    def format_heading(self, heading):
+        raise NotImplementedError, "subclasses must implement"
+
+    def _format_text(self, text):
+        """
+        Format a paragraph of free-form text for inclusion in the
+        help output at the current indentation level.
+        """
+        text_width = self.width - self.current_indent
+        indent = " "*self.current_indent
+        return textwrap.fill(text,
+                             text_width,
+                             initial_indent=indent,
+                             subsequent_indent=indent)
+
+    def format_description(self, description):
+        if description:
+            return self._format_text(description) + "\n"
+        else:
+            return ""
+
+    def format_epilog(self, epilog):
+        if epilog:
+            return "\n" + self._format_text(epilog) + "\n"
+        else:
+            return ""
+
+
+    def expand_default(self, option):
+        if self.parser is None or not self.default_tag:
+            return option.help
+
+        default_value = self.parser.defaults.get(option.dest)
+        if default_value is NO_DEFAULT or default_value is None:
+            default_value = self.NO_DEFAULT_VALUE
+
+        return option.help.replace(self.default_tag, str(default_value))
+
+    def format_option(self, option):
+        # The help for each option consists of two parts:
+        #   * the opt strings and metavars
+        #     eg. ("-x", or "-fFILENAME, --file=FILENAME")
+        #   * the user-supplied help string
+        #     eg. ("turn on expert mode", "read data from FILENAME")
+        #
+        # If possible, we write both of these on the same line:
+        #   -x      turn on expert mode
+        #
+        # But if the opt string list is too long, we put the help
+        # string on a second line, indented to the same column it would
+        # start in if it fit on the first line.
+        #   -fFILENAME, --file=FILENAME
+        #           read data from FILENAME
+        result = []
+        opts = self.option_strings[option]
+        opt_width = self.help_position - self.current_indent - 2
+        if len(opts) > opt_width:
+            opts = "%*s%s\n" % (self.current_indent, "", opts)
+            indent_first = self.help_position
+        else:                       # start help on same line as opts
+            opts = "%*s%-*s  " % (self.current_indent, "", opt_width, opts)
+            indent_first = 0
+        result.append(opts)
+        if option.help:
+            help_text = self.expand_default(option)
+            help_lines = textwrap.wrap(help_text, self.help_width)
+            result.append("%*s%s\n" % (indent_first, "", help_lines[0]))
+            result.extend(["%*s%s\n" % (self.help_position, "", line)
+                           for line in help_lines[1:]])
+        elif opts[-1] != "\n":
+            result.append("\n")
+        return "".join(result)
+
+    def store_option_strings(self, parser):
+        self.indent()
+        max_len = 0
+        for opt in parser.option_list:
+            strings = self.format_option_strings(opt)
+            self.option_strings[opt] = strings
+            max_len = max(max_len, len(strings) + self.current_indent)
+        self.indent()
+        for group in parser.option_groups:
+            for opt in group.option_list:
+                strings = self.format_option_strings(opt)
+                self.option_strings[opt] = strings
+                max_len = max(max_len, len(strings) + self.current_indent)
+        self.dedent()
+        self.dedent()
+        self.help_position = min(max_len + 2, self.max_help_position)
+        self.help_width = self.width - self.help_position
+
+    def format_option_strings(self, option):
+        """Return a comma-separated list of option strings & metavariables."""
+        if option.takes_value():
+            metavar = option.metavar or option.dest.upper()
+            short_opts = [self._short_opt_fmt % (sopt, metavar)
+                          for sopt in option._short_opts]
+            long_opts = [self._long_opt_fmt % (lopt, metavar)
+                         for lopt in option._long_opts]
+        else:
+            short_opts = option._short_opts
+            long_opts = option._long_opts
+
+        if self.short_first:
+            opts = short_opts + long_opts
+        else:
+            opts = long_opts + short_opts
+
+        return ", ".join(opts)
+
+class IndentedHelpFormatter (HelpFormatter):
+    """Format help with indented section bodies.
+    """
+
+    def __init__(self,
+                 indent_increment=2,
+                 max_help_position=24,
+                 width=None,
+                 short_first=1):
+        HelpFormatter.__init__(
+            self, indent_increment, max_help_position, width, short_first)
+
+    def format_usage(self, usage):
+        return _("Usage: %s\n") % usage
+
+    def format_heading(self, heading):
+        return "%*s%s:\n" % (self.current_indent, "", heading)
+
+
+class TitledHelpFormatter (HelpFormatter):
+    """Format help with underlined section headers.
+    """
+
+    def __init__(self,
+                 indent_increment=0,
+                 max_help_position=24,
+                 width=None,
+                 short_first=0):
+        HelpFormatter.__init__ (
+            self, indent_increment, max_help_position, width, short_first)
+
+    def format_usage(self, usage):
+        return "%s  %s\n" % (self.format_heading(_("Usage")), usage)
+
+    def format_heading(self, heading):
+        return "%s\n%s\n" % (heading, "=-"[self.level] * len(heading))
+
+
+def _parse_num(val, type):
+    if val[:2].lower() == "0x":         # hexadecimal
+        radix = 16
+    elif val[:2].lower() == "0b":       # binary
+        radix = 2
+        val = val[2:] or "0"            # have to remove "0b" prefix
+    elif val[:1] == "0":                # octal
+        radix = 8
+    else:                               # decimal
+        radix = 10
+
+    return type(val, radix)
+
+def _parse_int(val):
+    return _parse_num(val, int)
+
+def _parse_long(val):
+    return _parse_num(val, long)
+
+_builtin_cvt = { "int" : (_parse_int, _("integer")),
+                 "long" : (_parse_long, _("long integer")),
+                 "float" : (float, _("floating-point")),
+                 "complex" : (complex, _("complex")) }
+
+def check_builtin(option, opt, value):
+    (cvt, what) = _builtin_cvt[option.type]
+    try:
+        return cvt(value)
+    except ValueError:
+        raise OptionValueError(
+            _("option %s: invalid %s value: %r") % (opt, what, value))
+
+def check_choice(option, opt, value):
+    if value in option.choices:
+        return value
+    else:
+        choices = ", ".join(map(repr, option.choices))
+        raise OptionValueError(
+            _("option %s: invalid choice: %r (choose from %s)")
+            % (opt, value, choices))
+
+# Not supplying a default is different from a default of None,
+# so we need an explicit "not supplied" value.
+NO_DEFAULT = ("NO", "DEFAULT")
+
+
+class Option:
+    """
+    Instance attributes:
+      _short_opts : [string]
+      _long_opts : [string]
+
+      action : string
+      type : string
+      dest : string
+      default : any
+      nargs : int
+      const : any
+      choices : [string]
+      callback : function
+      callback_args : (any*)
+      callback_kwargs : { string : any }
+      help : string
+      metavar : string
+    """
+
+    # The list of instance attributes that may be set through
+    # keyword args to the constructor.
+    ATTRS = ['action',
+             'type',
+             'dest',
+             'default',
+             'nargs',
+             'const',
+             'choices',
+             'callback',
+             'callback_args',
+             'callback_kwargs',
+             'help',
+             'metavar']
+
+    # The set of actions allowed by option parsers.  Explicitly listed
+    # here so the constructor can validate its arguments.
+    ACTIONS = ("store",
+               "store_const",
+               "store_true",
+               "store_false",
+               "append",
+               "append_const",
+               "count",
+               "callback",
+               "help",
+               "version")
+
+    # The set of actions that involve storing a value somewhere;
+    # also listed just for constructor argument validation.  (If
+    # the action is one of these, there must be a destination.)
+    STORE_ACTIONS = ("store",
+                     "store_const",
+                     "store_true",
+                     "store_false",
+                     "append",
+                     "append_const",
+                     "count")
+
+    # The set of actions for which it makes sense to supply a value
+    # type, ie. which may consume an argument from the command line.
+    TYPED_ACTIONS = ("store",
+                     "append",
+                     "callback")
+
+    # The set of actions which *require* a value type, ie. that
+    # always consume an argument from the command line.
+    ALWAYS_TYPED_ACTIONS = ("store",
+                            "append")
+
+    # The set of actions which take a 'const' attribute.
+    CONST_ACTIONS = ("store_const",
+                     "append_const")
+
+    # The set of known types for option parsers.  Again, listed here for
+    # constructor argument validation.
+    TYPES = ("string", "int", "long", "float", "complex", "choice")
+
+    # Dictionary of argument checking functions, which convert and
+    # validate option arguments according to the option type.
+    #
+    # Signature of checking functions is:
+    #   check(option : Option, opt : string, value : string) -> any
+    # where
+    #   option is the Option instance calling the checker
+    #   opt is the actual option seen on the command-line
+    #     (eg. "-a", "--file")
+    #   value is the option argument seen on the command-line
+    #
+    # The return value should be in the appropriate Python type
+    # for option.type -- eg. an integer if option.type == "int".
+    #
+    # If no checker is defined for a type, arguments will be
+    # unchecked and remain strings.
+    TYPE_CHECKER = { "int"    : check_builtin,
+                     "long"   : check_builtin,
+                     "float"  : check_builtin,
+                     "complex": check_builtin,
+                     "choice" : check_choice,
+                   }
+
+
+    # CHECK_METHODS is a list of unbound method objects; they are called
+    # by the constructor, in order, after all attributes are
+    # initialized.  The list is created and filled in later, after all
+    # the methods are actually defined.  (I just put it here because I
+    # like to define and document all class attributes in the same
+    # place.)  Subclasses that add another _check_*() method should
+    # define their own CHECK_METHODS list that adds their check method
+    # to those from this class.
+    CHECK_METHODS = None
+
+
+    # -- Constructor/initialization methods ----------------------------
+
+    def __init__(self, *opts, **attrs):
+        # Set _short_opts, _long_opts attrs from 'opts' tuple.
+        # Have to be set now, in case no option strings are supplied.
+        self._short_opts = []
+        self._long_opts = []
+        opts = self._check_opt_strings(opts)
+        self._set_opt_strings(opts)
+
+        # Set all other attrs (action, type, etc.) from 'attrs' dict
+        self._set_attrs(attrs)
+
+        # Check all the attributes we just set.  There are lots of
+        # complicated interdependencies, but luckily they can be farmed
+        # out to the _check_*() methods listed in CHECK_METHODS -- which
+        # could be handy for subclasses!  The one thing these all share
+        # is that they raise OptionError if they discover a problem.
+        for checker in self.CHECK_METHODS:
+            checker(self)
+
+    def _check_opt_strings(self, opts):
+        # Filter out None because early versions of Optik had exactly
+        # one short option and one long option, either of which
+        # could be None.
+        opts = filter(None, opts)
+        if not opts:
+            raise TypeError("at least one option string must be supplied")
+        return opts
+
+    def _set_opt_strings(self, opts):
+        for opt in opts:
+            if len(opt) < 2:
+                raise OptionError(
+                    "invalid option string %r: "
+                    "must be at least two characters long" % opt, self)
+            elif len(opt) == 2:
+                if not (opt[0] == "-" and opt[1] != "-"):
+                    raise OptionError(
+                        "invalid short option string %r: "
+                        "must be of the form -x, (x any non-dash char)" % opt,
+                        self)
+                self._short_opts.append(opt)
+            else:
+                if not (opt[0:2] == "--" and opt[2] != "-"):
+                    raise OptionError(
+                        "invalid long option string %r: "
+                        "must start with --, followed by non-dash" % opt,
+                        self)
+                self._long_opts.append(opt)
+
+    def _set_attrs(self, attrs):
+        for attr in self.ATTRS:
+            if attrs.has_key(attr):
+                setattr(self, attr, attrs[attr])
+                del attrs[attr]
+            else:
+                if attr == 'default':
+                    setattr(self, attr, NO_DEFAULT)
+                else:
+                    setattr(self, attr, None)
+        if attrs:
+            attrs = attrs.keys()
+            attrs.sort()
+            raise OptionError(
+                "invalid keyword arguments: %s" % ", ".join(attrs),
+                self)
+
+
+    # -- Constructor validation methods --------------------------------
+
+    def _check_action(self):
+        if self.action is None:
+            self.action = "store"
+        elif self.action not in self.ACTIONS:
+            raise OptionError("invalid action: %r" % self.action, self)
+
+    def _check_type(self):
+        if self.type is None:
+            if self.action in self.ALWAYS_TYPED_ACTIONS:
+                if self.choices is not None:
+                    # The "choices" attribute implies "choice" type.
+                    self.type = "choice"
+                else:
+                    # No type given?  "string" is the most sensible default.
+                    self.type = "string"
+        else:
+            # Allow type objects or builtin type conversion functions
+            # (int, str, etc.) as an alternative to their names.  (The
+            # complicated check of __builtin__ is only necessary for
+            # Python 2.1 and earlier, and is short-circuited by the
+            # first check on modern Pythons.)
+            import __builtin__
+            if ( type(self.type) is types.TypeType or
+                 (hasattr(self.type, "__name__") and
+                  getattr(__builtin__, self.type.__name__, None) is self.type) ):
+                self.type = self.type.__name__
+
+            if self.type == "str":
+                self.type = "string"
+
+            if self.type not in self.TYPES:
+                raise OptionError("invalid option type: %r" % self.type, self)
+            if self.action not in self.TYPED_ACTIONS:
+                raise OptionError(
+                    "must not supply a type for action %r" % self.action, self)
+
+    def _check_choice(self):
+        if self.type == "choice":
+            if self.choices is None:
+                raise OptionError(
+                    "must supply a list of choices for type 'choice'", self)
+            elif type(self.choices) not in (types.TupleType, types.ListType):
+                raise OptionError(
+                    "choices must be a list of strings ('%s' supplied)"
+                    % str(type(self.choices)).split("'")[1], self)
+        elif self.choices is not None:
+            raise OptionError(
+                "must not supply choices for type %r" % self.type, self)
+
+    def _check_dest(self):
+        # No destination given, and we need one for this action.  The
+        # self.type check is for callbacks that take a value.
+        takes_value = (self.action in self.STORE_ACTIONS or
+                       self.type is not None)
+        if self.dest is None and takes_value:
+
+            # Glean a destination from the first long option string,
+            # or from the first short option string if no long options.
+            if self._long_opts:
+                # eg. "--foo-bar" -> "foo_bar"
+                self.dest = self._long_opts[0][2:].replace('-', '_')
+            else:
+                self.dest = self._short_opts[0][1]
+
+    def _check_const(self):
+        if self.action not in self.CONST_ACTIONS and self.const is not None:
+            raise OptionError(
+                "'const' must not be supplied for action %r" % self.action,
+                self)
+
+    def _check_nargs(self):
+        if self.action in self.TYPED_ACTIONS:
+            if self.nargs is None:
+                self.nargs = 1
+        elif self.nargs is not None:
+            raise OptionError(
+                "'nargs' must not be supplied for action %r" % self.action,
+                self)
+
+    def _check_callback(self):
+        if self.action == "callback":
+            if not callable(self.callback):
+                raise OptionError(
+                    "callback not callable: %r" % self.callback, self)
+            if (self.callback_args is not None and
+                type(self.callback_args) is not types.TupleType):
+                raise OptionError(
+                    "callback_args, if supplied, must be a tuple: not %r"
+                    % self.callback_args, self)
+            if (self.callback_kwargs is not None and
+                type(self.callback_kwargs) is not types.DictType):
+                raise OptionError(
+                    "callback_kwargs, if supplied, must be a dict: not %r"
+                    % self.callback_kwargs, self)
+        else:
+            if self.callback is not None:
+                raise OptionError(
+                    "callback supplied (%r) for non-callback option"
+                    % self.callback, self)
+            if self.callback_args is not None:
+                raise OptionError(
+                    "callback_args supplied for non-callback option", self)
+            if self.callback_kwargs is not None:
+                raise OptionError(
+                    "callback_kwargs supplied for non-callback option", self)
+
+
+    CHECK_METHODS = [_check_action,
+                     _check_type,
+                     _check_choice,
+                     _check_dest,
+                     _check_const,
+                     _check_nargs,
+                     _check_callback]
+
+
+    # -- Miscellaneous methods -----------------------------------------
+
+    def __str__(self):
+        return "/".join(self._short_opts + self._long_opts)
+
+    __repr__ = _repr
+
+    def takes_value(self):
+        return self.type is not None
+
+    def get_opt_string(self):
+        if self._long_opts:
+            return self._long_opts[0]
+        else:
+            return self._short_opts[0]
+
+
+    # -- Processing methods --------------------------------------------
+
+    def check_value(self, opt, value):
+        checker = self.TYPE_CHECKER.get(self.type)
+        if checker is None:
+            return value
+        else:
+            return checker(self, opt, value)
+
+    def convert_value(self, opt, value):
+        if value is not None:
+            if self.nargs == 1:
+                return self.check_value(opt, value)
+            else:
+                return tuple([self.check_value(opt, v) for v in value])
+
+    def process(self, opt, value, values, parser):
+
+        # First, convert the value(s) to the right type.  Howl if any
+        # value(s) are bogus.
+        value = self.convert_value(opt, value)
+
+        # And then take whatever action is expected of us.
+        # This is a separate method to make life easier for
+        # subclasses to add new actions.
+        return self.take_action(
+            self.action, self.dest, opt, value, values, parser)
+
+    def take_action(self, action, dest, opt, value, values, parser):
+        if action == "store":
+            setattr(values, dest, value)
+        elif action == "store_const":
+            setattr(values, dest, self.const)
+        elif action == "store_true":
+            setattr(values, dest, True)
+        elif action == "store_false":
+            setattr(values, dest, False)
+        elif action == "append":
+            values.ensure_value(dest, []).append(value)
+        elif action == "append_const":
+            values.ensure_value(dest, []).append(self.const)
+        elif action == "count":
+            setattr(values, dest, values.ensure_value(dest, 0) + 1)
+        elif action == "callback":
+            args = self.callback_args or ()
+            kwargs = self.callback_kwargs or {}
+            self.callback(self, opt, value, parser, *args, **kwargs)
+        elif action == "help":
+            parser.print_help()
+            parser.exit()
+        elif action == "version":
+            parser.print_version()
+            parser.exit()
+        else:
+            raise RuntimeError, "unknown action %r" % self.action
+
+        return 1
+
+# class Option
+
+
+SUPPRESS_HELP = "SUPPRESS"+"HELP"
+SUPPRESS_USAGE = "SUPPRESS"+"USAGE"
+
+# For compatibility with Python 2.2
+try:
+    True, False
+except NameError:
+    (True, False) = (1, 0)
+
+def isbasestring(x):
+    return isinstance(x, types.StringType) or isinstance(x, types.UnicodeType)
+
+class Values:
+
+    def __init__(self, defaults=None):
+        if defaults:
+            for (attr, val) in defaults.items():
+                setattr(self, attr, val)
+
+    def __str__(self):
+        return str(self.__dict__)
+
+    __repr__ = _repr
+
+    def __cmp__(self, other):
+        if isinstance(other, Values):
+            return cmp(self.__dict__, other.__dict__)
+        elif isinstance(other, types.DictType):
+            return cmp(self.__dict__, other)
+        else:
+            return -1
+
+    def _update_careful(self, dict):
+        """
+        Update the option values from an arbitrary dictionary, but only
+        use keys from dict that already have a corresponding attribute
+        in self.  Any keys in dict without a corresponding attribute
+        are silently ignored.
+        """
+        for attr in dir(self):
+            if dict.has_key(attr):
+                dval = dict[attr]
+                if dval is not None:
+                    setattr(self, attr, dval)
+
+    def _update_loose(self, dict):
+        """
+        Update the option values from an arbitrary dictionary,
+        using all keys from the dictionary regardless of whether
+        they have a corresponding attribute in self or not.
+        """
+        self.__dict__.update(dict)
+
+    def _update(self, dict, mode):
+        if mode == "careful":
+            self._update_careful(dict)
+        elif mode == "loose":
+            self._update_loose(dict)
+        else:
+            raise ValueError, "invalid update mode: %r" % mode
+
+    def read_module(self, modname, mode="careful"):
+        __import__(modname)
+        mod = sys.modules[modname]
+        self._update(vars(mod), mode)
+
+    def read_file(self, filename, mode="careful"):
+        vars = {}
+        execfile(filename, vars)
+        self._update(vars, mode)
+
+    def ensure_value(self, attr, value):
+        if not hasattr(self, attr) or getattr(self, attr) is None:
+            setattr(self, attr, value)
+        return getattr(self, attr)
+
+
+class OptionContainer:
+
+    """
+    Abstract base class.
+
+    Class attributes:
+      standard_option_list : [Option]
+        list of standard options that will be accepted by all instances
+        of this parser class (intended to be overridden by subclasses).
+
+    Instance attributes:
+      option_list : [Option]
+        the list of Option objects contained by this OptionContainer
+      _short_opt : { string : Option }
+        dictionary mapping short option strings, eg. "-f" or "-X",
+        to the Option instances that implement them.  If an Option
+        has multiple short option strings, it will appears in this
+        dictionary multiple times. [1]
+      _long_opt : { string : Option }
+        dictionary mapping long option strings, eg. "--file" or
+        "--exclude", to the Option instances that implement them.
+        Again, a given Option can occur multiple times in this
+        dictionary. [1]
+      defaults : { string : any }
+        dictionary mapping option destination names to default
+        values for each destination [1]
+
+    [1] These mappings are common to (shared by) all components of the
+        controlling OptionParser, where they are initially created.
+
+    """
+
+    def __init__(self, option_class, conflict_handler, description):
+        # Initialize the option list and related data structures.
+        # This method must be provided by subclasses, and it must
+        # initialize at least the following instance attributes:
+        # option_list, _short_opt, _long_opt, defaults.
+        self._create_option_list()
+
+        self.option_class = option_class
+        self.set_conflict_handler(conflict_handler)
+        self.set_description(description)
+
+    def _create_option_mappings(self):
+        # For use by OptionParser constructor -- create the master
+        # option mappings used by this OptionParser and all
+        # OptionGroups that it owns.
+        self._short_opt = {}            # single letter -> Option instance
+        self._long_opt = {}             # long option -> Option instance
+        self.defaults = {}              # maps option dest -> default value
+
+
+    def _share_option_mappings(self, parser):
+        # For use by OptionGroup constructor -- use shared option
+        # mappings from the OptionParser that owns this OptionGroup.
+        self._short_opt = parser._short_opt
+        self._long_opt = parser._long_opt
+        self.defaults = parser.defaults
+
+    def set_conflict_handler(self, handler):
+        if handler not in ("error", "resolve"):
+            raise ValueError, "invalid conflict_resolution value %r" % handler
+        self.conflict_handler = handler
+
+    def set_description(self, description):
+        self.description = description
+
+    def get_description(self):
+        return self.description
+
+
+    def destroy(self):
+        """see OptionParser.destroy()."""
+        del self._short_opt
+        del self._long_opt
+        del self.defaults
+
+
+    # -- Option-adding methods -----------------------------------------
+
+    def _check_conflict(self, option):
+        conflict_opts = []
+        for opt in option._short_opts:
+            if self._short_opt.has_key(opt):
+                conflict_opts.append((opt, self._short_opt[opt]))
+        for opt in option._long_opts:
+            if self._long_opt.has_key(opt):
+                conflict_opts.append((opt, self._long_opt[opt]))
+
+        if conflict_opts:
+            handler = self.conflict_handler
+            if handler == "error":
+                raise OptionConflictError(
+                    "conflicting option string(s): %s"
+                    % ", ".join([co[0] for co in conflict_opts]),
+                    option)
+            elif handler == "resolve":
+                for (opt, c_option) in conflict_opts:
+                    if opt.startswith("--"):
+                        c_option._long_opts.remove(opt)
+                        del self._long_opt[opt]
+                    else:
+                        c_option._short_opts.remove(opt)
+                        del self._short_opt[opt]
+                    if not (c_option._short_opts or c_option._long_opts):
+                        c_option.container.option_list.remove(c_option)
+
+    def add_option(self, *args, **kwargs):
+        """add_option(Option)
+           add_option(opt_str, ..., kwarg=val, ...)
+        """
+        if type(args[0]) is types.StringType:
+            option = self.option_class(*args, **kwargs)
+        elif len(args) == 1 and not kwargs:
+            option = args[0]
+            if not isinstance(option, Option):
+                raise TypeError, "not an Option instance: %r" % option
+        else:
+            raise TypeError, "invalid arguments"
+
+        self._check_conflict(option)
+
+        self.option_list.append(option)
+        option.container = self
+        for opt in option._short_opts:
+            self._short_opt[opt] = option
+        for opt in option._long_opts:
+            self._long_opt[opt] = option
+
+        if option.dest is not None:     # option has a dest, we need a default
+            if option.default is not NO_DEFAULT:
+                self.defaults[option.dest] = option.default
+            elif not self.defaults.has_key(option.dest):
+                self.defaults[option.dest] = None
+
+        return option
+
+    def add_options(self, option_list):
+        for option in option_list:
+            self.add_option(option)
+
+    # -- Option query/removal methods ----------------------------------
+
+    def get_option(self, opt_str):
+        return (self._short_opt.get(opt_str) or
+                self._long_opt.get(opt_str))
+
+    def has_option(self, opt_str):
+        return (self._short_opt.has_key(opt_str) or
+                self._long_opt.has_key(opt_str))
+
+    def remove_option(self, opt_str):
+        option = self._short_opt.get(opt_str)
+        if option is None:
+            option = self._long_opt.get(opt_str)
+        if option is None:
+            raise ValueError("no such option %r" % opt_str)
+
+        for opt in option._short_opts:
+            del self._short_opt[opt]
+        for opt in option._long_opts:
+            del self._long_opt[opt]
+        option.container.option_list.remove(option)
+
+
+    # -- Help-formatting methods ---------------------------------------
+
+    def format_option_help(self, formatter):
+        if not self.option_list:
+            return ""
+        result = []
+        for option in self.option_list:
+            if not option.help is SUPPRESS_HELP:
+                result.append(formatter.format_option(option))
+        return "".join(result)
+
+    def format_description(self, formatter):
+        return formatter.format_description(self.get_description())
+
+    def format_help(self, formatter):
+        result = []
+        if self.description:
+            result.append(self.format_description(formatter))
+        if self.option_list:
+            result.append(self.format_option_help(formatter))
+        return "\n".join(result)
+
+
+class OptionGroup (OptionContainer):
+
+    def __init__(self, parser, title, description=None):
+        self.parser = parser
+        OptionContainer.__init__(
+            self, parser.option_class, parser.conflict_handler, description)
+        self.title = title
+
+    def _create_option_list(self):
+        self.option_list = []
+        self._share_option_mappings(self.parser)
+
+    def set_title(self, title):
+        self.title = title
+
+    def destroy(self):
+        """see OptionParser.destroy()."""
+        OptionContainer.destroy(self)
+        del self.option_list
+
+    # -- Help-formatting methods ---------------------------------------
+
+    def format_help(self, formatter):
+        result = formatter.format_heading(self.title)
+        formatter.indent()
+        result += OptionContainer.format_help(self, formatter)
+        formatter.dedent()
+        return result
+
+
+class OptionParser (OptionContainer):
+
+    """
+    Class attributes:
+      standard_option_list : [Option]
+        list of standard options that will be accepted by all instances
+        of this parser class (intended to be overridden by subclasses).
+
+    Instance attributes:
+      usage : string
+        a usage string for your program.  Before it is displayed
+        to the user, "%prog" will be expanded to the name of
+        your program (self.prog or os.path.basename(sys.argv[0])).
+      prog : string
+        the name of the current program (to override
+        os.path.basename(sys.argv[0])).
+      epilog : string
+        paragraph of help text to print after option help
+
+      option_groups : [OptionGroup]
+        list of option groups in this parser (option groups are
+        irrelevant for parsing the command-line, but very useful
+        for generating help)
+
+      allow_interspersed_args : bool = true
+        if true, positional arguments may be interspersed with options.
+        Assuming -a and -b each take a single argument, the command-line
+          -ablah foo bar -bboo baz
+        will be interpreted the same as
+          -ablah -bboo -- foo bar baz
+        If this flag were false, that command line would be interpreted as
+          -ablah -- foo bar -bboo baz
+        -- ie. we stop processing options as soon as we see the first
+        non-option argument.  (This is the tradition followed by
+        Python's getopt module, Perl's Getopt::Std, and other argument-
+        parsing libraries, but it is generally annoying to users.)
+
+      process_default_values : bool = true
+        if true, option default values are processed similarly to option
+        values from the command line: that is, they are passed to the
+        type-checking function for the option's type (as long as the
+        default value is a string).  (This really only matters if you
+        have defined custom types; see SF bug #955889.)  Set it to false
+        to restore the behaviour of Optik 1.4.1 and earlier.
+
+      rargs : [string]
+        the argument list currently being parsed.  Only set when
+        parse_args() is active, and continually trimmed down as
+        we consume arguments.  Mainly there for the benefit of
+        callback options.
+      largs : [string]
+        the list of leftover arguments that we have skipped while
+        parsing options.  If allow_interspersed_args is false, this
+        list is always empty.
+      values : Values
+        the set of option values currently being accumulated.  Only
+        set when parse_args() is active.  Also mainly for callbacks.
+
+    Because of the 'rargs', 'largs', and 'values' attributes,
+    OptionParser is not thread-safe.  If, for some perverse reason, you
+    need to parse command-line arguments simultaneously in different
+    threads, use different OptionParser instances.
+
+    """
+
+    standard_option_list = []
+
+    def __init__(self,
+                 usage=None,
+                 option_list=None,
+                 option_class=Option,
+                 version=None,
+                 conflict_handler="error",
+                 description=None,
+                 formatter=None,
+                 add_help_option=True,
+                 prog=None,
+                 epilog=None):
+        OptionContainer.__init__(
+            self, option_class, conflict_handler, description)
+        self.set_usage(usage)
+        self.prog = prog
+        self.version = version
+        self.allow_interspersed_args = True
+        self.process_default_values = True
+        if formatter is None:
+            formatter = IndentedHelpFormatter()
+        self.formatter = formatter
+        self.formatter.set_parser(self)
+        self.epilog = epilog
+
+        # Populate the option list; initial sources are the
+        # standard_option_list class attribute, the 'option_list'
+        # argument, and (if applicable) the _add_version_option() and
+        # _add_help_option() methods.
+        self._populate_option_list(option_list,
+                                   add_help=add_help_option)
+
+        self._init_parsing_state()
+
+
+    def destroy(self):
+        """
+        Declare that you are done with this OptionParser.  This cleans up
+        reference cycles so the OptionParser (and all objects referenced by
+        it) can be garbage-collected promptly.  After calling destroy(), the
+        OptionParser is unusable.
+        """
+        OptionContainer.destroy(self)
+        for group in self.option_groups:
+            group.destroy()
+        del self.option_list
+        del self.option_groups
+        del self.formatter
+
+
+    # -- Private methods -----------------------------------------------
+    # (used by our or OptionContainer's constructor)
+
+    def _create_option_list(self):
+        self.option_list = []
+        self.option_groups = []
+        self._create_option_mappings()
+
+    def _add_help_option(self):
+        self.add_option("-h", "--help",
+                        action="help",
+                        help=_("show this help message and exit"))
+
+    def _add_version_option(self):
+        self.add_option("--version",
+                        action="version",
+                        help=_("show program's version number and exit"))
+
+    def _populate_option_list(self, option_list, add_help=True):
+        if self.standard_option_list:
+            self.add_options(self.standard_option_list)
+        if option_list:
+            self.add_options(option_list)
+        if self.version:
+            self._add_version_option()
+        if add_help:
+            self._add_help_option()
+
+    def _init_parsing_state(self):
+        # These are set in parse_args() for the convenience of callbacks.
+        self.rargs = None
+        self.largs = None
+        self.values = None
+
+
+    # -- Simple modifier methods ---------------------------------------
+
+    def set_usage(self, usage):
+        if usage is None:
+            self.usage = _("%prog [options]")
+        elif usage is SUPPRESS_USAGE:
+            self.usage = None
+        # For backwards compatibility with Optik 1.3 and earlier.
+        elif usage.lower().startswith("usage: "):
+            self.usage = usage[7:]
+        else:
+            self.usage = usage
+
+    def enable_interspersed_args(self):
+        self.allow_interspersed_args = True
+
+    def disable_interspersed_args(self):
+        self.allow_interspersed_args = False
+
+    def set_process_default_values(self, process):
+        self.process_default_values = process
+
+    def set_default(self, dest, value):
+        self.defaults[dest] = value
+
+    def set_defaults(self, **kwargs):
+        self.defaults.update(kwargs)
+
+    def _get_all_options(self):
+        options = self.option_list[:]
+        for group in self.option_groups:
+            options.extend(group.option_list)
+        return options
+
+    def get_default_values(self):
+        if not self.process_default_values:
+            # Old, pre-Optik 1.5 behaviour.
+            return Values(self.defaults)
+
+        defaults = self.defaults.copy()
+        for option in self._get_all_options():
+            default = defaults.get(option.dest)
+            if isbasestring(default):
+                opt_str = option.get_opt_string()
+                defaults[option.dest] = option.check_value(opt_str, default)
+
+        return Values(defaults)
+
+
+    # -- OptionGroup methods -------------------------------------------
+
+    def add_option_group(self, *args, **kwargs):
+        # XXX lots of overlap with OptionContainer.add_option()
+        if type(args[0]) is types.StringType:
+            group = OptionGroup(self, *args, **kwargs)
+        elif len(args) == 1 and not kwargs:
+            group = args[0]
+            if not isinstance(group, OptionGroup):
+                raise TypeError, "not an OptionGroup instance: %r" % group
+            if group.parser is not self:
+                raise ValueError, "invalid OptionGroup (wrong parser)"
+        else:
+            raise TypeError, "invalid arguments"
+
+        self.option_groups.append(group)
+        return group
+
+    def get_option_group(self, opt_str):
+        option = (self._short_opt.get(opt_str) or
+                  self._long_opt.get(opt_str))
+        if option and option.container is not self:
+            return option.container
+        return None
+
+
+    # -- Option-parsing methods ----------------------------------------
+
+    def _get_args(self, args):
+        if args is None:
+            return sys.argv[1:]
+        else:
+            return args[:]              # don't modify caller's list
+
+    def parse_args(self, args=None, values=None):
+        """
+        parse_args(args : [string] = sys.argv[1:],
+                   values : Values = None)
+        -> (values : Values, args : [string])
+
+        Parse the command-line options found in 'args' (default:
+        sys.argv[1:]).  Any errors result in a call to 'error()', which
+        by default prints the usage message to stderr and calls
+        sys.exit() with an error message.  On success returns a pair
+        (values, args) where 'values' is an Values instance (with all
+        your option values) and 'args' is the list of arguments left
+        over after parsing options.
+        """
+        rargs = self._get_args(args)
+        if values is None:
+            values = self.get_default_values()
+
+        # Store the halves of the argument list as attributes for the
+        # convenience of callbacks:
+        #   rargs
+        #     the rest of the command-line (the "r" stands for
+        #     "remaining" or "right-hand")
+        #   largs
+        #     the leftover arguments -- ie. what's left after removing
+        #     options and their arguments (the "l" stands for "leftover"
+        #     or "left-hand")
+        self.rargs = rargs
+        self.largs = largs = []
+        self.values = values
+
+        try:
+            stop = self._process_args(largs, rargs, values)
+        except (BadOptionError, OptionValueError), err:
+            self.error(str(err))
+
+        args = largs + rargs
+        return self.check_values(values, args)
+
+    def check_values(self, values, args):
+        """
+        check_values(values : Values, args : [string])
+        -> (values : Values, args : [string])
+
+        Check that the supplied option values and leftover arguments are
+        valid.  Returns the option values and leftover arguments
+        (possibly adjusted, possibly completely new -- whatever you
+        like).  Default implementation just returns the passed-in
+        values; subclasses may override as desired.
+        """
+        return (values, args)
+
+    def _process_args(self, largs, rargs, values):
+        """_process_args(largs : [string],
+                         rargs : [string],
+                         values : Values)
+
+        Process command-line arguments and populate 'values', consuming
+        options and arguments from 'rargs'.  If 'allow_interspersed_args' is
+        false, stop at the first non-option argument.  If true, accumulate any
+        interspersed non-option arguments in 'largs'.
+        """
+        while rargs:
+            arg = rargs[0]
+            # We handle bare "--" explicitly, and bare "-" is handled by the
+            # standard arg handler since the short arg case ensures that the
+            # len of the opt string is greater than 1.
+            if arg == "--":
+                del rargs[0]
+                return
+            elif arg[0:2] == "--":
+                # process a single long option (possibly with value(s))
+                self._process_long_opt(rargs, values)
+            elif arg[:1] == "-" and len(arg) > 1:
+                # process a cluster of short options (possibly with
+                # value(s) for the last one only)
+                self._process_short_opts(rargs, values)
+            elif self.allow_interspersed_args:
+                largs.append(arg)
+                del rargs[0]
+            else:
+                return                  # stop now, leave this arg in rargs
+
+        # Say this is the original argument list:
+        # [arg0, arg1, ..., arg(i-1), arg(i), arg(i+1), ..., arg(N-1)]
+        #                            ^
+        # (we are about to process arg(i)).
+        #
+        # Then rargs is [arg(i), ..., arg(N-1)] and largs is a *subset* of
+        # [arg0, ..., arg(i-1)] (any options and their arguments will have
+        # been removed from largs).
+        #
+        # The while loop will usually consume 1 or more arguments per pass.
+        # If it consumes 1 (eg. arg is an option that takes no arguments),
+        # then after _process_arg() is done the situation is:
+        #
+        #   largs = subset of [arg0, ..., arg(i)]
+        #   rargs = [arg(i+1), ..., arg(N-1)]
+        #
+        # If allow_interspersed_args is false, largs will always be
+        # *empty* -- still a subset of [arg0, ..., arg(i-1)], but
+        # not a very interesting subset!
+
+    def _match_long_opt(self, opt):
+        """_match_long_opt(opt : string) -> string
+
+        Determine which long option string 'opt' matches, ie. which one
+        it is an unambiguous abbrevation for.  Raises BadOptionError if
+        'opt' doesn't unambiguously match any long option string.
+        """
+        return _match_abbrev(opt, self._long_opt)
+
+    def _process_long_opt(self, rargs, values):
+        arg = rargs.pop(0)
+
+        # Value explicitly attached to arg?  Pretend it's the next
+        # argument.
+        if "=" in arg:
+            (opt, next_arg) = arg.split("=", 1)
+            rargs.insert(0, next_arg)
+            had_explicit_value = True
+        else:
+            opt = arg
+            had_explicit_value = False
+
+        opt = self._match_long_opt(opt)
+        option = self._long_opt[opt]
+        if option.takes_value():
+            nargs = option.nargs
+            if len(rargs) < nargs:
+                if nargs == 1:
+                    self.error(_("%s option requires an argument") % opt)
+                else:
+                    self.error(_("%s option requires %d arguments")
+                               % (opt, nargs))
+            elif nargs == 1:
+                value = rargs.pop(0)
+            else:
+                value = tuple(rargs[0:nargs])
+                del rargs[0:nargs]
+
+        elif had_explicit_value:
+            self.error(_("%s option does not take a value") % opt)
+
+        else:
+            value = None
+
+        option.process(opt, value, values, self)
+
+    def _process_short_opts(self, rargs, values):
+        arg = rargs.pop(0)
+        stop = False
+        i = 1
+        for ch in arg[1:]:
+            opt = "-" + ch
+            option = self._short_opt.get(opt)
+            i += 1                      # we have consumed a character
+
+            if not option:
+                raise BadOptionError(opt)
+            if option.takes_value():
+                # Any characters left in arg?  Pretend they're the
+                # next arg, and stop consuming characters of arg.
+                if i < len(arg):
+                    rargs.insert(0, arg[i:])
+                    stop = True
+
+                nargs = option.nargs
+                if len(rargs) < nargs:
+                    if nargs == 1:
+                        self.error(_("%s option requires an argument") % opt)
+                    else:
+                        self.error(_("%s option requires %d arguments")
+                                   % (opt, nargs))
+                elif nargs == 1:
+                    value = rargs.pop(0)
+                else:
+                    value = tuple(rargs[0:nargs])
+                    del rargs[0:nargs]
+
+            else:                       # option doesn't take a value
+                value = None
+
+            option.process(opt, value, values, self)
+
+            if stop:
+                break
+
+
+    # -- Feedback methods ----------------------------------------------
+
+    def get_prog_name(self):
+        if self.prog is None:
+            return os.path.basename(sys.argv[0])
+        else:
+            return self.prog
+
+    def expand_prog_name(self, s):
+        return s.replace("%prog", self.get_prog_name())
+
+    def get_description(self):
+        return self.expand_prog_name(self.description)
+
+    def exit(self, status=0, msg=None):
+        if msg:
+            sys.stderr.write(msg)
+        sys.exit(status)
+
+    def error(self, msg):
+        """error(msg : string)
+
+        Print a usage message incorporating 'msg' to stderr and exit.
+        If you override this in a subclass, it should not return -- it
+        should either exit or raise an exception.
+        """
+        self.print_usage(sys.stderr)
+        self.exit(2, "%s: error: %s\n" % (self.get_prog_name(), msg))
+
+    def get_usage(self):
+        if self.usage:
+            return self.formatter.format_usage(
+                self.expand_prog_name(self.usage))
+        else:
+            return ""
+
+    def print_usage(self, file=None):
+        """print_usage(file : file = stdout)
+
+        Print the usage message for the current program (self.usage) to
+        'file' (default stdout).  Any occurence of the string "%prog" in
+        self.usage is replaced with the name of the current program
+        (basename of sys.argv[0]).  Does nothing if self.usage is empty
+        or not defined.
+        """
+        if self.usage:
+            print >>file, self.get_usage()
+
+    def get_version(self):
+        if self.version:
+            return self.expand_prog_name(self.version)
+        else:
+            return ""
+
+    def print_version(self, file=None):
+        """print_version(file : file = stdout)
+
+        Print the version message for this program (self.version) to
+        'file' (default stdout).  As with print_usage(), any occurence
+        of "%prog" in self.version is replaced by the current program's
+        name.  Does nothing if self.version is empty or undefined.
+        """
+        if self.version:
+            print >>file, self.get_version()
+
+    def format_option_help(self, formatter=None):
+        if formatter is None:
+            formatter = self.formatter
+        formatter.store_option_strings(self)
+        result = []
+        result.append(formatter.format_heading(_("Options")))
+        formatter.indent()
+        if self.option_list:
+            result.append(OptionContainer.format_option_help(self, formatter))
+            result.append("\n")
+        for group in self.option_groups:
+            result.append(group.format_help(formatter))
+            result.append("\n")
+        formatter.dedent()
+        # Drop the last "\n", or the header if no options or option groups:
+        return "".join(result[:-1])
+
+    def format_epilog(self, formatter):
+        return formatter.format_epilog(self.epilog)
+
+    def format_help(self, formatter=None):
+        if formatter is None:
+            formatter = self.formatter
+        result = []
+        if self.usage:
+            result.append(self.get_usage() + "\n")
+        if self.description:
+            result.append(self.format_description(formatter) + "\n")
+        result.append(self.format_option_help(formatter))
+        result.append(self.format_epilog(formatter))
+        return "".join(result)
+
+    # used by test suite
+    def _get_encoding(self, file):
+        encoding = getattr(file, "encoding", None)
+        if not encoding:
+            encoding = sys.getdefaultencoding()
+        return encoding
+
+    def print_help(self, file=None):
+        """print_help(file : file = stdout)
+
+        Print an extended help message, listing all options and any
+        help text provided with them, to 'file' (default stdout).
+        """
+        if file is None:
+            file = sys.stdout
+        encoding = self._get_encoding(file)
+        file.write(self.format_help().encode(encoding, "replace"))
+
+# class OptionParser
+
+
+def _match_abbrev(s, wordmap):
+    """_match_abbrev(s : string, wordmap : {string : Option}) -> string
+
+    Return the string key in 'wordmap' for which 's' is an unambiguous
+    abbreviation.  If 's' is found to be ambiguous or doesn't match any of
+    'words', raise BadOptionError.
+    """
+    # Is there an exact match?
+    if wordmap.has_key(s):
+        return s
+    else:
+        # Isolate all words with s as a prefix.
+        possibilities = [word for word in wordmap.keys()
+                         if word.startswith(s)]
+        # No exact match, so there had better be just one possibility.
+        if len(possibilities) == 1:
+            return possibilities[0]
+        elif not possibilities:
+            raise BadOptionError(s)
+        else:
+            # More than one possible completion: ambiguous prefix.
+            possibilities.sort()
+            raise AmbiguousOptionError(s, possibilities)
+
+
+# Some day, there might be many Option classes.  As of Optik 1.3, the
+# preferred way to instantiate Options is indirectly, via make_option(),
+# which will become a factory function when there are many Option
+# classes.
+make_option = Option

Added: vendor/Python/current/Lib/os.py
===================================================================
--- vendor/Python/current/Lib/os.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/os.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,738 @@
+r"""OS routines for Mac, NT, or Posix depending on what system we're on.
+
+This exports:
+  - all functions from posix, nt, os2, mac, or ce, e.g. unlink, stat, etc.
+  - os.path is one of the modules posixpath, ntpath, or macpath
+  - os.name is 'posix', 'nt', 'os2', 'mac', 'ce' or 'riscos'
+  - os.curdir is a string representing the current directory ('.' or ':')
+  - os.pardir is a string representing the parent directory ('..' or '::')
+  - os.sep is the (or a most common) pathname separator ('/' or ':' or '\\')
+  - os.extsep is the extension separator ('.' or '/')
+  - os.altsep is the alternate pathname separator (None or '/')
+  - os.pathsep is the component separator used in $PATH etc
+  - os.linesep is the line separator in text files ('\r' or '\n' or '\r\n')
+  - os.defpath is the default search path for executables
+  - os.devnull is the file path of the null device ('/dev/null', etc.)
+
+Programs that import and use 'os' stand a better chance of being
+portable between different platforms.  Of course, they must then
+only use functions that are defined by all platforms (e.g., unlink
+and opendir), and leave all pathname manipulation to os.path
+(e.g., split and join).
+"""
+
+#'
+
+import sys
+
+_names = sys.builtin_module_names
+
+# Note:  more names are added to __all__ later.
+__all__ = ["altsep", "curdir", "pardir", "sep", "pathsep", "linesep",
+           "defpath", "name", "path", "devnull",
+           "SEEK_SET", "SEEK_CUR", "SEEK_END"]
+
+def _get_exports_list(module):
+    try:
+        return list(module.__all__)
+    except AttributeError:
+        return [n for n in dir(module) if n[0] != '_']
+
+if 'posix' in _names:
+    name = 'posix'
+    linesep = '\n'
+    from posix import *
+    try:
+        from posix import _exit
+    except ImportError:
+        pass
+    import posixpath as path
+
+    import posix
+    __all__.extend(_get_exports_list(posix))
+    del posix
+
+elif 'nt' in _names:
+    name = 'nt'
+    linesep = '\r\n'
+    from nt import *
+    try:
+        from nt import _exit
+    except ImportError:
+        pass
+    import ntpath as path
+
+    import nt
+    __all__.extend(_get_exports_list(nt))
+    del nt
+
+elif 'os2' in _names:
+    name = 'os2'
+    linesep = '\r\n'
+    from os2 import *
+    try:
+        from os2 import _exit
+    except ImportError:
+        pass
+    if sys.version.find('EMX GCC') == -1:
+        import ntpath as path
+    else:
+        import os2emxpath as path
+        from _emx_link import link
+
+    import os2
+    __all__.extend(_get_exports_list(os2))
+    del os2
+
+elif 'mac' in _names:
+    name = 'mac'
+    linesep = '\r'
+    from mac import *
+    try:
+        from mac import _exit
+    except ImportError:
+        pass
+    import macpath as path
+
+    import mac
+    __all__.extend(_get_exports_list(mac))
+    del mac
+
+elif 'ce' in _names:
+    name = 'ce'
+    linesep = '\r\n'
+    from ce import *
+    try:
+        from ce import _exit
+    except ImportError:
+        pass
+    # We can use the standard Windows path.
+    import ntpath as path
+
+    import ce
+    __all__.extend(_get_exports_list(ce))
+    del ce
+
+elif 'riscos' in _names:
+    name = 'riscos'
+    linesep = '\n'
+    from riscos import *
+    try:
+        from riscos import _exit
+    except ImportError:
+        pass
+    import riscospath as path
+
+    import riscos
+    __all__.extend(_get_exports_list(riscos))
+    del riscos
+
+else:
+    raise ImportError, 'no os specific module found'
+
+sys.modules['os.path'] = path
+from os.path import (curdir, pardir, sep, pathsep, defpath, extsep, altsep,
+    devnull)
+
+del _names
+
+# Python uses fixed values for the SEEK_ constants; they are mapped
+# to native constants if necessary in posixmodule.c
+SEEK_SET = 0
+SEEK_CUR = 1
+SEEK_END = 2
+
+#'
+
+# Super directory utilities.
+# (Inspired by Eric Raymond; the doc strings are mostly his)
+
+def makedirs(name, mode=0777):
+    """makedirs(path [, mode=0777])
+
+    Super-mkdir; create a leaf directory and all intermediate ones.
+    Works like mkdir, except that any intermediate path segment (not
+    just the rightmost) will be created if it does not exist.  This is
+    recursive.
+
+    """
+    from errno import EEXIST
+    head, tail = path.split(name)
+    if not tail:
+        head, tail = path.split(head)
+    if head and tail and not path.exists(head):
+        try:
+            makedirs(head, mode)
+        except OSError, e:
+            # be happy if someone already created the path
+            if e.errno != EEXIST:
+                raise
+        if tail == curdir:           # xxx/newdir/. exists if xxx/newdir exists
+            return
+    mkdir(name, mode)
+
+def removedirs(name):
+    """removedirs(path)
+
+    Super-rmdir; remove a leaf directory and all empty intermediate
+    ones.  Works like rmdir except that, if the leaf directory is
+    successfully removed, directories corresponding to rightmost path
+    segments will be pruned away until either the whole path is
+    consumed or an error occurs.  Errors during this latter phase are
+    ignored -- they generally mean that a directory was not empty.
+
+    """
+    rmdir(name)
+    head, tail = path.split(name)
+    if not tail:
+        head, tail = path.split(head)
+    while head and tail:
+        try:
+            rmdir(head)
+        except error:
+            break
+        head, tail = path.split(head)
+
+def renames(old, new):
+    """renames(old, new)
+
+    Super-rename; create directories as necessary and delete any left
+    empty.  Works like rename, except creation of any intermediate
+    directories needed to make the new pathname good is attempted
+    first.  After the rename, directories corresponding to rightmost
+    path segments of the old name will be pruned way until either the
+    whole path is consumed or a nonempty directory is found.
+
+    Note: this function can fail with the new directory structure made
+    if you lack permissions needed to unlink the leaf directory or
+    file.
+
+    """
+    head, tail = path.split(new)
+    if head and tail and not path.exists(head):
+        makedirs(head)
+    rename(old, new)
+    head, tail = path.split(old)
+    if head and tail:
+        try:
+            removedirs(head)
+        except error:
+            pass
+
+__all__.extend(["makedirs", "removedirs", "renames"])
+
+def walk(top, topdown=True, onerror=None):
+    """Directory tree generator.
+
+    For each directory in the directory tree rooted at top (including top
+    itself, but excluding '.' and '..'), yields a 3-tuple
+
+        dirpath, dirnames, filenames
+
+    dirpath is a string, the path to the directory.  dirnames is a list of
+    the names of the subdirectories in dirpath (excluding '.' and '..').
+    filenames is a list of the names of the non-directory files in dirpath.
+    Note that the names in the lists are just names, with no path components.
+    To get a full path (which begins with top) to a file or directory in
+    dirpath, do os.path.join(dirpath, name).
+
+    If optional arg 'topdown' is true or not specified, the triple for a
+    directory is generated before the triples for any of its subdirectories
+    (directories are generated top down).  If topdown is false, the triple
+    for a directory is generated after the triples for all of its
+    subdirectories (directories are generated bottom up).
+
+    When topdown is true, the caller can modify the dirnames list in-place
+    (e.g., via del or slice assignment), and walk will only recurse into the
+    subdirectories whose names remain in dirnames; this can be used to prune
+    the search, or to impose a specific order of visiting.  Modifying
+    dirnames when topdown is false is ineffective, since the directories in
+    dirnames have already been generated by the time dirnames itself is
+    generated.
+
+    By default errors from the os.listdir() call are ignored.  If
+    optional arg 'onerror' is specified, it should be a function; it
+    will be called with one argument, an os.error instance.  It can
+    report the error to continue with the walk, or raise the exception
+    to abort the walk.  Note that the filename is available as the
+    filename attribute of the exception object.
+
+    Caution:  if you pass a relative pathname for top, don't change the
+    current working directory between resumptions of walk.  walk never
+    changes the current directory, and assumes that the client doesn't
+    either.
+
+    Example:
+
+    from os.path import join, getsize
+    for root, dirs, files in walk('python/Lib/email'):
+        print root, "consumes",
+        print sum([getsize(join(root, name)) for name in files]),
+        print "bytes in", len(files), "non-directory files"
+        if 'CVS' in dirs:
+            dirs.remove('CVS')  # don't visit CVS directories
+    """
+
+    from os.path import join, isdir, islink
+
+    # We may not have read permission for top, in which case we can't
+    # get a list of the files the directory contains.  os.path.walk
+    # always suppressed the exception then, rather than blow up for a
+    # minor reason when (say) a thousand readable directories are still
+    # left to visit.  That logic is copied here.
+    try:
+        # Note that listdir and error are globals in this module due
+        # to earlier import-*.
+        names = listdir(top)
+    except error, err:
+        if onerror is not None:
+            onerror(err)
+        return
+
+    dirs, nondirs = [], []
+    for name in names:
+        if isdir(join(top, name)):
+            dirs.append(name)
+        else:
+            nondirs.append(name)
+
+    if topdown:
+        yield top, dirs, nondirs
+    for name in dirs:
+        path = join(top, name)
+        if not islink(path):
+            for x in walk(path, topdown, onerror):
+                yield x
+    if not topdown:
+        yield top, dirs, nondirs
+
+__all__.append("walk")
+
+# Make sure os.environ exists, at least
+try:
+    environ
+except NameError:
+    environ = {}
+
+def execl(file, *args):
+    """execl(file, *args)
+
+    Execute the executable file with argument list args, replacing the
+    current process. """
+    execv(file, args)
+
+def execle(file, *args):
+    """execle(file, *args, env)
+
+    Execute the executable file with argument list args and
+    environment env, replacing the current process. """
+    env = args[-1]
+    execve(file, args[:-1], env)
+
+def execlp(file, *args):
+    """execlp(file, *args)
+
+    Execute the executable file (which is searched for along $PATH)
+    with argument list args, replacing the current process. """
+    execvp(file, args)
+
+def execlpe(file, *args):
+    """execlpe(file, *args, env)
+
+    Execute the executable file (which is searched for along $PATH)
+    with argument list args and environment env, replacing the current
+    process. """
+    env = args[-1]
+    execvpe(file, args[:-1], env)
+
+def execvp(file, args):
+    """execp(file, args)
+
+    Execute the executable file (which is searched for along $PATH)
+    with argument list args, replacing the current process.
+    args may be a list or tuple of strings. """
+    _execvpe(file, args)
+
+def execvpe(file, args, env):
+    """execvpe(file, args, env)
+
+    Execute the executable file (which is searched for along $PATH)
+    with argument list args and environment env , replacing the
+    current process.
+    args may be a list or tuple of strings. """
+    _execvpe(file, args, env)
+
+__all__.extend(["execl","execle","execlp","execlpe","execvp","execvpe"])
+
+def _execvpe(file, args, env=None):
+    from errno import ENOENT, ENOTDIR
+
+    if env is not None:
+        func = execve
+        argrest = (args, env)
+    else:
+        func = execv
+        argrest = (args,)
+        env = environ
+
+    head, tail = path.split(file)
+    if head:
+        func(file, *argrest)
+        return
+    if 'PATH' in env:
+        envpath = env['PATH']
+    else:
+        envpath = defpath
+    PATH = envpath.split(pathsep)
+    saved_exc = None
+    saved_tb = None
+    for dir in PATH:
+        fullname = path.join(dir, file)
+        try:
+            func(fullname, *argrest)
+        except error, e:
+            tb = sys.exc_info()[2]
+            if (e.errno != ENOENT and e.errno != ENOTDIR
+                and saved_exc is None):
+                saved_exc = e
+                saved_tb = tb
+    if saved_exc:
+        raise error, saved_exc, saved_tb
+    raise error, e, tb
+
+# Change environ to automatically call putenv() if it exists
+try:
+    # This will fail if there's no putenv
+    putenv
+except NameError:
+    pass
+else:
+    import UserDict
+
+    # Fake unsetenv() for Windows
+    # not sure about os2 here but
+    # I'm guessing they are the same.
+
+    if name in ('os2', 'nt'):
+        def unsetenv(key):
+            putenv(key, "")
+
+    if name == "riscos":
+        # On RISC OS, all env access goes through getenv and putenv
+        from riscosenviron import _Environ
+    elif name in ('os2', 'nt'):  # Where Env Var Names Must Be UPPERCASE
+        # But we store them as upper case
+        class _Environ(UserDict.IterableUserDict):
+            def __init__(self, environ):
+                UserDict.UserDict.__init__(self)
+                data = self.data
+                for k, v in environ.items():
+                    data[k.upper()] = v
+            def __setitem__(self, key, item):
+                putenv(key, item)
+                self.data[key.upper()] = item
+            def __getitem__(self, key):
+                return self.data[key.upper()]
+            try:
+                unsetenv
+            except NameError:
+                def __delitem__(self, key):
+                    del self.data[key.upper()]
+            else:
+                def __delitem__(self, key):
+                    unsetenv(key)
+                    del self.data[key.upper()]
+            def has_key(self, key):
+                return key.upper() in self.data
+            def __contains__(self, key):
+                return key.upper() in self.data
+            def get(self, key, failobj=None):
+                return self.data.get(key.upper(), failobj)
+            def update(self, dict=None, **kwargs):
+                if dict:
+                    try:
+                        keys = dict.keys()
+                    except AttributeError:
+                        # List of (key, value)
+                        for k, v in dict:
+                            self[k] = v
+                    else:
+                        # got keys
+                        # cannot use items(), since mappings
+                        # may not have them.
+                        for k in keys:
+                            self[k] = dict[k]
+                if kwargs:
+                    self.update(kwargs)
+            def copy(self):
+                return dict(self)
+
+    else:  # Where Env Var Names Can Be Mixed Case
+        class _Environ(UserDict.IterableUserDict):
+            def __init__(self, environ):
+                UserDict.UserDict.__init__(self)
+                self.data = environ
+            def __setitem__(self, key, item):
+                putenv(key, item)
+                self.data[key] = item
+            def update(self,  dict=None, **kwargs):
+                if dict:
+                    try:
+                        keys = dict.keys()
+                    except AttributeError:
+                        # List of (key, value)
+                        for k, v in dict:
+                            self[k] = v
+                    else:
+                        # got keys
+                        # cannot use items(), since mappings
+                        # may not have them.
+                        for k in keys:
+                            self[k] = dict[k]
+                if kwargs:
+                    self.update(kwargs)
+            try:
+                unsetenv
+            except NameError:
+                pass
+            else:
+                def __delitem__(self, key):
+                    unsetenv(key)
+                    del self.data[key]
+            def copy(self):
+                return dict(self)
+
+
+    environ = _Environ(environ)
+
+def getenv(key, default=None):
+    """Get an environment variable, return None if it doesn't exist.
+    The optional second argument can specify an alternate default."""
+    return environ.get(key, default)
+__all__.append("getenv")
+
+def _exists(name):
+    try:
+        eval(name)
+        return True
+    except NameError:
+        return False
+
+# Supply spawn*() (probably only for Unix)
+if _exists("fork") and not _exists("spawnv") and _exists("execv"):
+
+    P_WAIT = 0
+    P_NOWAIT = P_NOWAITO = 1
+
+    # XXX Should we support P_DETACH?  I suppose it could fork()**2
+    # and close the std I/O streams.  Also, P_OVERLAY is the same
+    # as execv*()?
+
+    def _spawnvef(mode, file, args, env, func):
+        # Internal helper; func is the exec*() function to use
+        pid = fork()
+        if not pid:
+            # Child
+            try:
+                if env is None:
+                    func(file, args)
+                else:
+                    func(file, args, env)
+            except:
+                _exit(127)
+        else:
+            # Parent
+            if mode == P_NOWAIT:
+                return pid # Caller is responsible for waiting!
+            while 1:
+                wpid, sts = waitpid(pid, 0)
+                if WIFSTOPPED(sts):
+                    continue
+                elif WIFSIGNALED(sts):
+                    return -WTERMSIG(sts)
+                elif WIFEXITED(sts):
+                    return WEXITSTATUS(sts)
+                else:
+                    raise error, "Not stopped, signaled or exited???"
+
+    def spawnv(mode, file, args):
+        """spawnv(mode, file, args) -> integer
+
+Execute file with arguments from args in a subprocess.
+If mode == P_NOWAIT return the pid of the process.
+If mode == P_WAIT return the process's exit code if it exits normally;
+otherwise return -SIG, where SIG is the signal that killed it. """
+        return _spawnvef(mode, file, args, None, execv)
+
+    def spawnve(mode, file, args, env):
+        """spawnve(mode, file, args, env) -> integer
+
+Execute file with arguments from args in a subprocess with the
+specified environment.
+If mode == P_NOWAIT return the pid of the process.
+If mode == P_WAIT return the process's exit code if it exits normally;
+otherwise return -SIG, where SIG is the signal that killed it. """
+        return _spawnvef(mode, file, args, env, execve)
+
+    # Note: spawnvp[e] is't currently supported on Windows
+
+    def spawnvp(mode, file, args):
+        """spawnvp(mode, file, args) -> integer
+
+Execute file (which is looked for along $PATH) with arguments from
+args in a subprocess.
+If mode == P_NOWAIT return the pid of the process.
+If mode == P_WAIT return the process's exit code if it exits normally;
+otherwise return -SIG, where SIG is the signal that killed it. """
+        return _spawnvef(mode, file, args, None, execvp)
+
+    def spawnvpe(mode, file, args, env):
+        """spawnvpe(mode, file, args, env) -> integer
+
+Execute file (which is looked for along $PATH) with arguments from
+args in a subprocess with the supplied environment.
+If mode == P_NOWAIT return the pid of the process.
+If mode == P_WAIT return the process's exit code if it exits normally;
+otherwise return -SIG, where SIG is the signal that killed it. """
+        return _spawnvef(mode, file, args, env, execvpe)
+
+if _exists("spawnv"):
+    # These aren't supplied by the basic Windows code
+    # but can be easily implemented in Python
+
+    def spawnl(mode, file, *args):
+        """spawnl(mode, file, *args) -> integer
+
+Execute file with arguments from args in a subprocess.
+If mode == P_NOWAIT return the pid of the process.
+If mode == P_WAIT return the process's exit code if it exits normally;
+otherwise return -SIG, where SIG is the signal that killed it. """
+        return spawnv(mode, file, args)
+
+    def spawnle(mode, file, *args):
+        """spawnle(mode, file, *args, env) -> integer
+
+Execute file with arguments from args in a subprocess with the
+supplied environment.
+If mode == P_NOWAIT return the pid of the process.
+If mode == P_WAIT return the process's exit code if it exits normally;
+otherwise return -SIG, where SIG is the signal that killed it. """
+        env = args[-1]
+        return spawnve(mode, file, args[:-1], env)
+
+
+    __all__.extend(["spawnv", "spawnve", "spawnl", "spawnle",])
+
+
+if _exists("spawnvp"):
+    # At the moment, Windows doesn't implement spawnvp[e],
+    # so it won't have spawnlp[e] either.
+    def spawnlp(mode, file, *args):
+        """spawnlp(mode, file, *args) -> integer
+
+Execute file (which is looked for along $PATH) with arguments from
+args in a subprocess with the supplied environment.
+If mode == P_NOWAIT return the pid of the process.
+If mode == P_WAIT return the process's exit code if it exits normally;
+otherwise return -SIG, where SIG is the signal that killed it. """
+        return spawnvp(mode, file, args)
+
+    def spawnlpe(mode, file, *args):
+        """spawnlpe(mode, file, *args, env) -> integer
+
+Execute file (which is looked for along $PATH) with arguments from
+args in a subprocess with the supplied environment.
+If mode == P_NOWAIT return the pid of the process.
+If mode == P_WAIT return the process's exit code if it exits normally;
+otherwise return -SIG, where SIG is the signal that killed it. """
+        env = args[-1]
+        return spawnvpe(mode, file, args[:-1], env)
+
+
+    __all__.extend(["spawnvp", "spawnvpe", "spawnlp", "spawnlpe",])
+
+
+# Supply popen2 etc. (for Unix)
+if _exists("fork"):
+    if not _exists("popen2"):
+        def popen2(cmd, mode="t", bufsize=-1):
+            """Execute the shell command 'cmd' in a sub-process.  On UNIX, 'cmd'
+            may be a sequence, in which case arguments will be passed directly to
+            the program without shell intervention (as with os.spawnv()).  If 'cmd'
+            is a string it will be passed to the shell (as with os.system()). If
+            'bufsize' is specified, it sets the buffer size for the I/O pipes.  The
+            file objects (child_stdin, child_stdout) are returned."""
+            import popen2
+            stdout, stdin = popen2.popen2(cmd, bufsize)
+            return stdin, stdout
+        __all__.append("popen2")
+
+    if not _exists("popen3"):
+        def popen3(cmd, mode="t", bufsize=-1):
+            """Execute the shell command 'cmd' in a sub-process.  On UNIX, 'cmd'
+            may be a sequence, in which case arguments will be passed directly to
+            the program without shell intervention (as with os.spawnv()).  If 'cmd'
+            is a string it will be passed to the shell (as with os.system()). If
+            'bufsize' is specified, it sets the buffer size for the I/O pipes.  The
+            file objects (child_stdin, child_stdout, child_stderr) are returned."""
+            import popen2
+            stdout, stdin, stderr = popen2.popen3(cmd, bufsize)
+            return stdin, stdout, stderr
+        __all__.append("popen3")
+
+    if not _exists("popen4"):
+        def popen4(cmd, mode="t", bufsize=-1):
+            """Execute the shell command 'cmd' in a sub-process.  On UNIX, 'cmd'
+            may be a sequence, in which case arguments will be passed directly to
+            the program without shell intervention (as with os.spawnv()).  If 'cmd'
+            is a string it will be passed to the shell (as with os.system()). If
+            'bufsize' is specified, it sets the buffer size for the I/O pipes.  The
+            file objects (child_stdin, child_stdout_stderr) are returned."""
+            import popen2
+            stdout, stdin = popen2.popen4(cmd, bufsize)
+            return stdin, stdout
+        __all__.append("popen4")
+
+import copy_reg as _copy_reg
+
+def _make_stat_result(tup, dict):
+    return stat_result(tup, dict)
+
+def _pickle_stat_result(sr):
+    (type, args) = sr.__reduce__()
+    return (_make_stat_result, args)
+
+try:
+    _copy_reg.pickle(stat_result, _pickle_stat_result, _make_stat_result)
+except NameError: # stat_result may not exist
+    pass
+
+def _make_statvfs_result(tup, dict):
+    return statvfs_result(tup, dict)
+
+def _pickle_statvfs_result(sr):
+    (type, args) = sr.__reduce__()
+    return (_make_statvfs_result, args)
+
+try:
+    _copy_reg.pickle(statvfs_result, _pickle_statvfs_result,
+                     _make_statvfs_result)
+except NameError: # statvfs_result may not exist
+    pass
+
+if not _exists("urandom"):
+    def urandom(n):
+        """urandom(n) -> str
+
+        Return a string of n random bytes suitable for cryptographic use.
+
+        """
+        try:
+            _urandomfd = open("/dev/urandom", O_RDONLY)
+        except (OSError, IOError):
+            raise NotImplementedError("/dev/urandom (or equivalent) not found")
+        bytes = ""
+        while len(bytes) < n:
+            bytes += read(_urandomfd, n - len(bytes))
+        close(_urandomfd)
+        return bytes

Added: vendor/Python/current/Lib/os2emxpath.py
===================================================================
--- vendor/Python/current/Lib/os2emxpath.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/os2emxpath.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,423 @@
+# Module 'os2emxpath' -- common operations on OS/2 pathnames
+"""Common pathname manipulations, OS/2 EMX version.
+
+Instead of importing this module directly, import os and refer to this
+module as os.path.
+"""
+
+import os
+import stat
+
+__all__ = ["normcase","isabs","join","splitdrive","split","splitext",
+           "basename","dirname","commonprefix","getsize","getmtime",
+           "getatime","getctime", "islink","exists","lexists","isdir","isfile",
+           "ismount","walk","expanduser","expandvars","normpath","abspath",
+           "splitunc","curdir","pardir","sep","pathsep","defpath","altsep",
+           "extsep","devnull","realpath","supports_unicode_filenames"]
+
+# strings representing various path-related bits and pieces
+curdir = '.'
+pardir = '..'
+extsep = '.'
+sep = '/'
+altsep = '\\'
+pathsep = ';'
+defpath = '.;C:\\bin'
+devnull = 'nul'
+
+# Normalize the case of a pathname and map slashes to backslashes.
+# Other normalizations (such as optimizing '../' away) are not done
+# (this is done by normpath).
+
+def normcase(s):
+    """Normalize case of pathname.
+
+    Makes all characters lowercase and all altseps into seps."""
+    return s.replace('\\', '/').lower()
+
+
+# Return whether a path is absolute.
+# Trivial in Posix, harder on the Mac or MS-DOS.
+# For DOS it is absolute if it starts with a slash or backslash (current
+# volume), or if a pathname after the volume letter and colon / UNC resource
+# starts with a slash or backslash.
+
+def isabs(s):
+    """Test whether a path is absolute"""
+    s = splitdrive(s)[1]
+    return s != '' and s[:1] in '/\\'
+
+
+# Join two (or more) paths.
+
+def join(a, *p):
+    """Join two or more pathname components, inserting sep as needed"""
+    path = a
+    for b in p:
+        if isabs(b):
+            path = b
+        elif path == '' or path[-1:] in '/\\:':
+            path = path + b
+        else:
+            path = path + '/' + b
+    return path
+
+
+# Split a path in a drive specification (a drive letter followed by a
+# colon) and the path specification.
+# It is always true that drivespec + pathspec == p
+def splitdrive(p):
+    """Split a pathname into drive and path specifiers. Returns a 2-tuple
+"(drive,path)";  either part may be empty"""
+    if p[1:2] == ':':
+        return p[0:2], p[2:]
+    return '', p
+
+
+# Parse UNC paths
+def splitunc(p):
+    """Split a pathname into UNC mount point and relative path specifiers.
+
+    Return a 2-tuple (unc, rest); either part may be empty.
+    If unc is not empty, it has the form '//host/mount' (or similar
+    using backslashes).  unc+rest is always the input path.
+    Paths containing drive letters never have an UNC part.
+    """
+    if p[1:2] == ':':
+        return '', p # Drive letter present
+    firstTwo = p[0:2]
+    if firstTwo == '/' * 2 or firstTwo == '\\' * 2:
+        # is a UNC path:
+        # vvvvvvvvvvvvvvvvvvvv equivalent to drive letter
+        # \\machine\mountpoint\directories...
+        #           directory ^^^^^^^^^^^^^^^
+        normp = normcase(p)
+        index = normp.find('/', 2)
+        if index == -1:
+            ##raise RuntimeError, 'illegal UNC path: "' + p + '"'
+            return ("", p)
+        index = normp.find('/', index + 1)
+        if index == -1:
+            index = len(p)
+        return p[:index], p[index:]
+    return '', p
+
+
+# Split a path in head (everything up to the last '/') and tail (the
+# rest).  After the trailing '/' is stripped, the invariant
+# join(head, tail) == p holds.
+# The resulting head won't end in '/' unless it is the root.
+
+def split(p):
+    """Split a pathname.
+
+    Return tuple (head, tail) where tail is everything after the final slash.
+    Either part may be empty."""
+
+    d, p = splitdrive(p)
+    # set i to index beyond p's last slash
+    i = len(p)
+    while i and p[i-1] not in '/\\':
+        i = i - 1
+    head, tail = p[:i], p[i:]  # now tail has no slashes
+    # remove trailing slashes from head, unless it's all slashes
+    head2 = head
+    while head2 and head2[-1] in '/\\':
+        head2 = head2[:-1]
+    head = head2 or head
+    return d + head, tail
+
+
+# Split a path in root and extension.
+# The extension is everything starting at the last dot in the last
+# pathname component; the root is everything before that.
+# It is always true that root + ext == p.
+
+def splitext(p):
+    """Split the extension from a pathname.
+
+    Extension is everything from the last dot to the end.
+    Return (root, ext), either part may be empty."""
+    root, ext = '', ''
+    for c in p:
+        if c in ['/','\\']:
+            root, ext = root + ext + c, ''
+        elif c == '.':
+            if ext:
+                root, ext = root + ext, c
+            else:
+                ext = c
+        elif ext:
+            ext = ext + c
+        else:
+            root = root + c
+    return root, ext
+
+
+# Return the tail (basename) part of a path.
+
+def basename(p):
+    """Returns the final component of a pathname"""
+    return split(p)[1]
+
+
+# Return the head (dirname) part of a path.
+
+def dirname(p):
+    """Returns the directory component of a pathname"""
+    return split(p)[0]
+
+
+# Return the longest prefix of all list elements.
+
+def commonprefix(m):
+    "Given a list of pathnames, returns the longest common leading component"
+    if not m: return ''
+    s1 = min(m)
+    s2 = max(m)
+    n = min(len(s1), len(s2))
+    for i in xrange(n):
+        if s1[i] != s2[i]:
+            return s1[:i]
+    return s1[:n]
+
+
+# Get size, mtime, atime of files.
+
+def getsize(filename):
+    """Return the size of a file, reported by os.stat()"""
+    return os.stat(filename).st_size
+
+def getmtime(filename):
+    """Return the last modification time of a file, reported by os.stat()"""
+    return os.stat(filename).st_mtime
+
+def getatime(filename):
+    """Return the last access time of a file, reported by os.stat()"""
+    return os.stat(filename).st_atime
+
+def getctime(filename):
+    """Return the creation time of a file, reported by os.stat()."""
+    return os.stat(filename).st_ctime
+
+# Is a path a symbolic link?
+# This will always return false on systems where posix.lstat doesn't exist.
+
+def islink(path):
+    """Test for symbolic link.  On OS/2 always returns false"""
+    return False
+
+
+# Does a path exist?
+# This is false for dangling symbolic links.
+
+def exists(path):
+    """Test whether a path exists"""
+    try:
+        st = os.stat(path)
+    except os.error:
+        return False
+    return True
+
+lexists = exists
+
+
+# Is a path a directory?
+
+def isdir(path):
+    """Test whether a path is a directory"""
+    try:
+        st = os.stat(path)
+    except os.error:
+        return False
+    return stat.S_ISDIR(st.st_mode)
+
+
+# Is a path a regular file?
+# This follows symbolic links, so both islink() and isdir() can be true
+# for the same path.
+
+def isfile(path):
+    """Test whether a path is a regular file"""
+    try:
+        st = os.stat(path)
+    except os.error:
+        return False
+    return stat.S_ISREG(st.st_mode)
+
+
+# Is a path a mount point?  Either a root (with or without drive letter)
+# or an UNC path with at most a / or \ after the mount point.
+
+def ismount(path):
+    """Test whether a path is a mount point (defined as root of drive)"""
+    unc, rest = splitunc(path)
+    if unc:
+        return rest in ("", "/", "\\")
+    p = splitdrive(path)[1]
+    return len(p) == 1 and p[0] in '/\\'
+
+
+# Directory tree walk.
+# For each directory under top (including top itself, but excluding
+# '.' and '..'), func(arg, dirname, filenames) is called, where
+# dirname is the name of the directory and filenames is the list
+# of files (and subdirectories etc.) in the directory.
+# The func may modify the filenames list, to implement a filter,
+# or to impose a different order of visiting.
+
+def walk(top, func, arg):
+    """Directory tree walk whth callback function.
+
+    walk(top, func, arg) calls func(arg, d, files) for each directory d
+    in the tree rooted at top (including top itself); files is a list
+    of all the files and subdirs in directory d."""
+    try:
+        names = os.listdir(top)
+    except os.error:
+        return
+    func(arg, top, names)
+    exceptions = ('.', '..')
+    for name in names:
+        if name not in exceptions:
+            name = join(top, name)
+            if isdir(name):
+                walk(name, func, arg)
+
+
+# Expand paths beginning with '~' or '~user'.
+# '~' means $HOME; '~user' means that user's home directory.
+# If the path doesn't begin with '~', or if the user or $HOME is unknown,
+# the path is returned unchanged (leaving error reporting to whatever
+# function is called with the expanded path as argument).
+# See also module 'glob' for expansion of *, ? and [...] in pathnames.
+# (A function should also be defined to do full *sh-style environment
+# variable expansion.)
+
+def expanduser(path):
+    """Expand ~ and ~user constructs.
+
+    If user or $HOME is unknown, do nothing."""
+    if path[:1] != '~':
+        return path
+    i, n = 1, len(path)
+    while i < n and path[i] not in '/\\':
+        i = i + 1
+    if i == 1:
+        if 'HOME' in os.environ:
+            userhome = os.environ['HOME']
+        elif not 'HOMEPATH' in os.environ:
+            return path
+        else:
+            try:
+                drive = os.environ['HOMEDRIVE']
+            except KeyError:
+                drive = ''
+            userhome = join(drive, os.environ['HOMEPATH'])
+    else:
+        return path
+    return userhome + path[i:]
+
+
+# Expand paths containing shell variable substitutions.
+# The following rules apply:
+#       - no expansion within single quotes
+#       - no escape character, except for '$$' which is translated into '$'
+#       - ${varname} is accepted.
+#       - varnames can be made out of letters, digits and the character '_'
+# XXX With COMMAND.COM you can use any characters in a variable name,
+# XXX except '^|<>='.
+
+def expandvars(path):
+    """Expand shell variables of form $var and ${var}.
+
+    Unknown variables are left unchanged."""
+    if '$' not in path:
+        return path
+    import string
+    varchars = string.letters + string.digits + '_-'
+    res = ''
+    index = 0
+    pathlen = len(path)
+    while index < pathlen:
+        c = path[index]
+        if c == '\'':   # no expansion within single quotes
+            path = path[index + 1:]
+            pathlen = len(path)
+            try:
+                index = path.index('\'')
+                res = res + '\'' + path[:index + 1]
+            except ValueError:
+                res = res + path
+                index = pathlen - 1
+        elif c == '$':  # variable or '$$'
+            if path[index + 1:index + 2] == '$':
+                res = res + c
+                index = index + 1
+            elif path[index + 1:index + 2] == '{':
+                path = path[index+2:]
+                pathlen = len(path)
+                try:
+                    index = path.index('}')
+                    var = path[:index]
+                    if var in os.environ:
+                        res = res + os.environ[var]
+                except ValueError:
+                    res = res + path
+                    index = pathlen - 1
+            else:
+                var = ''
+                index = index + 1
+                c = path[index:index + 1]
+                while c != '' and c in varchars:
+                    var = var + c
+                    index = index + 1
+                    c = path[index:index + 1]
+                if var in os.environ:
+                    res = res + os.environ[var]
+                if c != '':
+                    res = res + c
+        else:
+            res = res + c
+        index = index + 1
+    return res
+
+
+# Normalize a path, e.g. A//B, A/./B and A/foo/../B all become A/B.
+
+def normpath(path):
+    """Normalize path, eliminating double slashes, etc."""
+    path = path.replace('\\', '/')
+    prefix, path = splitdrive(path)
+    while path[:1] == '/':
+        prefix = prefix + '/'
+        path = path[1:]
+    comps = path.split('/')
+    i = 0
+    while i < len(comps):
+        if comps[i] == '.':
+            del comps[i]
+        elif comps[i] == '..' and i > 0 and comps[i-1] not in ('', '..'):
+            del comps[i-1:i+1]
+            i = i - 1
+        elif comps[i] == '' and i > 0 and comps[i-1] != '':
+            del comps[i]
+        else:
+            i = i + 1
+    # If the path is now empty, substitute '.'
+    if not prefix and not comps:
+        comps.append('.')
+    return prefix + '/'.join(comps)
+
+
+# Return an absolute path.
+def abspath(path):
+    """Return the absolute version of a path"""
+    if not isabs(path):
+        path = join(os.getcwd(), path)
+    return normpath(path)
+
+# realpath is a no-op on systems without islink support
+realpath = abspath
+
+supports_unicode_filenames = False

Added: vendor/Python/current/Lib/pdb.doc
===================================================================
--- vendor/Python/current/Lib/pdb.doc	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/pdb.doc	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,192 @@
+The Python Debugger Pdb
+=======================
+
+To use the debugger in its simplest form:
+
+        >>> import pdb
+        >>> pdb.run('<a statement>')
+
+The debugger's prompt is '(Pdb) '.  This will stop in the first
+function call in <a statement>.
+
+Alternatively, if a statement terminated with an unhandled exception,
+you can use pdb's post-mortem facility to inspect the contents of the
+traceback:
+
+        >>> <a statement>
+        <exception traceback>
+        >>> import pdb
+        >>> pdb.pm()
+
+The commands recognized by the debugger are listed in the next
+section.  Most can be abbreviated as indicated; e.g., h(elp) means
+that 'help' can be typed as 'h' or 'help' (but not as 'he' or 'hel',
+nor as 'H' or 'Help' or 'HELP').  Optional arguments are enclosed in
+square brackets.
+
+A blank line repeats the previous command literally, except for
+'list', where it lists the next 11 lines.
+
+Commands that the debugger doesn't recognize are assumed to be Python
+statements and are executed in the context of the program being
+debugged.  Python statements can also be prefixed with an exclamation
+point ('!').  This is a powerful way to inspect the program being
+debugged; it is even possible to change variables.  When an exception
+occurs in such a statement, the exception name is printed but the
+debugger's state is not changed.
+
+The debugger supports aliases, which can save typing.  And aliases can
+have parameters (see the alias help entry) which allows one a certain
+level of adaptability to the context under examination.
+
+Multiple commands may be entered on a single line, separated by the
+pair ';;'.  No intelligence is applied to separating the commands; the
+input is split at the first ';;', even if it is in the middle of a
+quoted string.
+
+If a file ".pdbrc" exists in your home directory or in the current
+directory, it is read in and executed as if it had been typed at the
+debugger prompt.  This is particularly useful for aliases.  If both
+files exist, the one in the home directory is read first and aliases
+defined there can be overriden by the local file.
+
+Aside from aliases, the debugger is not directly programmable; but it
+is implemented as a class from which you can derive your own debugger
+class, which you can make as fancy as you like.
+
+
+Debugger commands
+=================
+
+h(elp)
+        Without argument, print the list of available commands.  With
+        a command name as argument, print help about that command
+        (this is currently not implemented).
+
+w(here)
+        Print a stack trace, with the most recent frame at the bottom.
+        An arrow indicates the "current frame", which determines the
+        context of most commands.
+
+d(own)
+        Move the current frame one level down in the stack trace
+        (to a newer frame).
+
+u(p)
+        Move the current frame one level up in the stack trace
+        (to an older frame).
+
+b(reak) [ ([filename:]lineno | function) [, condition] ]
+        With a filename:line number argument, set a break there.  If
+        filename is omitted, use the current file.  With a function
+        name, set a break at the first executable line of that
+        function.  Without argument, list all breaks.  Each breakpoint
+        is assigned a number to which all the other breakpoint
+        commands refer.
+
+        The condition argument, if present, is a string which must
+        evaluate to true in order for the breakpoint to be honored.
+
+tbreak [ ([filename:]lineno | function) [, condition] ]
+        Temporary breakpoint, which is removed automatically when it
+        is first hit.  The arguments are the same as break.
+
+cl(ear) [bpnumber [bpnumber ...] ]
+        With a space separated list of breakpoint numbers, clear those
+        breakpoints.  Without argument, clear all breaks (but first
+        ask confirmation).
+
+disable bpnumber [bpnumber ...]
+        Disables the breakpoints given as a space separated list of
+        breakpoint numbers.  Disabling a breakpoint means it cannot
+        cause the program to stop execution, but unlike clearing a
+        breakpoint, it remains in the list of breakpoints and can be
+        (re-)enabled.
+
+enable bpnumber [bpnumber ...]
+        Enables the breakpoints specified.
+
+ignore bpnumber count
+        Sets the ignore count for the given breakpoint number.  If
+        count is omitted, the ignore count is set to 0.  A breakpoint
+        becomes active when the ignore count is zero.  When non-zero,
+        the count is decremented each time the breakpoint is reached
+        and the breakpoint is not disabled and any associated
+        condition evaluates to true.
+
+condition bpnumber condition
+        condition is an expression which must evaluate to true before
+        the breakpoint is honored.  If condition is absent, any
+        existing condition is removed; i.e., the breakpoint is made
+        unconditional.
+
+s(tep)
+        Execute the current line, stop at the first possible occasion
+        (either in a function that is called or in the current function).
+
+n(ext)
+        Continue execution until the next line in the current function
+        is reached or it returns.
+
+r(eturn)
+        Continue execution until the current function returns.
+
+c(ont(inue))
+        Continue execution, only stop when a breakpoint is encountered.
+
+l(ist) [first [,last]]
+        List source code for the current file.
+        Without arguments, list 11 lines around the current line
+        or continue the previous listing.
+        With one argument, list 11 lines starting at that line.
+        With two arguments, list the given range;
+        if the second argument is less than the first, it is a count.
+
+a(rgs)
+        Print the argument list of the current function.
+
+p expression
+        Print the value of the expression.
+
+(!) statement
+        Execute the (one-line) statement in the context of the current
+        stack frame.  The exclamation point can be omitted unless the
+        first word of the statement resembles a debugger command.  To
+        assign to a global variable you must always prefix the command
+        with a 'global' command, e.g.:
+        (Pdb) global list_options; list_options = ['-l']
+        (Pdb)
+
+
+whatis arg
+         Prints the type of the argument.
+
+alias [name [command]]
+        Creates an alias called 'name' that executes 'command'.  The
+        command must *not* be enclosed in quotes.  Replaceable
+        parameters can be indicated by %1, %2, and so on, while %* is
+        replaced by all the parameters.  If no command is given, the
+        current alias for name is shown. If no name is given, all
+        aliases are listed.
+
+        Aliases may be nested and can contain anything that can be
+        legally typed at the pdb prompt.  Note!  You *can* override
+        internal pdb commands with aliases!  Those internal commands
+        are then hidden until the alias is removed.  Aliasing is
+        recursively applied to the first word of the command line; all
+        other words in the line are left alone.
+
+        As an example, here are two useful aliases (especially when
+        placed in the .pdbrc file):
+
+        #Print instance variables (usage "pi classInst")
+        alias pi for k in %1.__dict__.keys(): print "%1.",k,"=",%1.__dict__[k]
+        #Print instance variables in self
+        alias ps pi self
+                
+unalias name
+        Deletes the specified alias.
+
+q(uit)
+        Quit from the debugger.
+        The program being executed is aborted.

Added: vendor/Python/current/Lib/pdb.py
===================================================================
--- vendor/Python/current/Lib/pdb.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/pdb.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1234 @@
+#! /usr/bin/env python
+
+"""A Python debugger."""
+
+# (See pdb.doc for documentation.)
+
+import sys
+import linecache
+import cmd
+import bdb
+from repr import Repr
+import os
+import re
+import pprint
+import traceback
+# Create a custom safe Repr instance and increase its maxstring.
+# The default of 30 truncates error messages too easily.
+_repr = Repr()
+_repr.maxstring = 200
+_saferepr = _repr.repr
+
+__all__ = ["run", "pm", "Pdb", "runeval", "runctx", "runcall", "set_trace",
+           "post_mortem", "help"]
+
+def find_function(funcname, filename):
+    cre = re.compile(r'def\s+%s\s*[(]' % funcname)
+    try:
+        fp = open(filename)
+    except IOError:
+        return None
+    # consumer of this info expects the first line to be 1
+    lineno = 1
+    answer = None
+    while 1:
+        line = fp.readline()
+        if line == '':
+            break
+        if cre.match(line):
+            answer = funcname, filename, lineno
+            break
+        lineno = lineno + 1
+    fp.close()
+    return answer
+
+
+# Interaction prompt line will separate file and call info from code
+# text using value of line_prefix string.  A newline and arrow may
+# be to your liking.  You can set it once pdb is imported using the
+# command "pdb.line_prefix = '\n% '".
+# line_prefix = ': '    # Use this to get the old situation back
+line_prefix = '\n-> '   # Probably a better default
+
+class Pdb(bdb.Bdb, cmd.Cmd):
+
+    def __init__(self, completekey='tab', stdin=None, stdout=None):
+        bdb.Bdb.__init__(self)
+        cmd.Cmd.__init__(self, completekey, stdin, stdout)
+        if stdout:
+            self.use_rawinput = 0
+        self.prompt = '(Pdb) '
+        self.aliases = {}
+        self.mainpyfile = ''
+        self._wait_for_mainpyfile = 0
+        # Try to load readline if it exists
+        try:
+            import readline
+        except ImportError:
+            pass
+
+        # Read $HOME/.pdbrc and ./.pdbrc
+        self.rcLines = []
+        if 'HOME' in os.environ:
+            envHome = os.environ['HOME']
+            try:
+                rcFile = open(os.path.join(envHome, ".pdbrc"))
+            except IOError:
+                pass
+            else:
+                for line in rcFile.readlines():
+                    self.rcLines.append(line)
+                rcFile.close()
+        try:
+            rcFile = open(".pdbrc")
+        except IOError:
+            pass
+        else:
+            for line in rcFile.readlines():
+                self.rcLines.append(line)
+            rcFile.close()
+
+        self.commands = {} # associates a command list to breakpoint numbers
+        self.commands_doprompt = {} # for each bp num, tells if the prompt must be disp. after execing the cmd list
+        self.commands_silent = {} # for each bp num, tells if the stack trace must be disp. after execing the cmd list
+        self.commands_defining = False # True while in the process of defining a command list
+        self.commands_bnum = None # The breakpoint number for which we are defining a list
+
+    def reset(self):
+        bdb.Bdb.reset(self)
+        self.forget()
+
+    def forget(self):
+        self.lineno = None
+        self.stack = []
+        self.curindex = 0
+        self.curframe = None
+
+    def setup(self, f, t):
+        self.forget()
+        self.stack, self.curindex = self.get_stack(f, t)
+        self.curframe = self.stack[self.curindex][0]
+        self.execRcLines()
+
+    # Can be executed earlier than 'setup' if desired
+    def execRcLines(self):
+        if self.rcLines:
+            # Make local copy because of recursion
+            rcLines = self.rcLines
+            # executed only once
+            self.rcLines = []
+            for line in rcLines:
+                line = line[:-1]
+                if len(line) > 0 and line[0] != '#':
+                    self.onecmd(line)
+
+    # Override Bdb methods
+
+    def user_call(self, frame, argument_list):
+        """This method is called when there is the remote possibility
+        that we ever need to stop in this function."""
+        if self._wait_for_mainpyfile:
+            return
+        if self.stop_here(frame):
+            print >>self.stdout, '--Call--'
+            self.interaction(frame, None)
+
+    def user_line(self, frame):
+        """This function is called when we stop or break at this line."""
+        if self._wait_for_mainpyfile:
+            if (self.mainpyfile != self.canonic(frame.f_code.co_filename)
+                or frame.f_lineno<= 0):
+                return
+            self._wait_for_mainpyfile = 0
+        if self.bp_commands(frame):
+            self.interaction(frame, None)
+
+    def bp_commands(self,frame):
+        """ Call every command that was set for the current active breakpoint (if there is one)
+        Returns True if the normal interaction function must be called, False otherwise """
+        #self.currentbp is set in bdb.py in bdb.break_here if a breakpoint was hit
+        if getattr(self,"currentbp",False) and self.currentbp in self.commands:
+            currentbp = self.currentbp
+            self.currentbp = 0
+            lastcmd_back = self.lastcmd
+            self.setup(frame, None)
+            for line in self.commands[currentbp]:
+                self.onecmd(line)
+            self.lastcmd = lastcmd_back
+            if not self.commands_silent[currentbp]:
+                self.print_stack_entry(self.stack[self.curindex])
+            if self.commands_doprompt[currentbp]:
+                self.cmdloop()
+            self.forget()
+            return
+        return 1
+
+    def user_return(self, frame, return_value):
+        """This function is called when a return trap is set here."""
+        frame.f_locals['__return__'] = return_value
+        print >>self.stdout, '--Return--'
+        self.interaction(frame, None)
+
+    def user_exception(self, frame, (exc_type, exc_value, exc_traceback)):
+        """This function is called if an exception occurs,
+        but only if we are to stop at or just below this level."""
+        frame.f_locals['__exception__'] = exc_type, exc_value
+        if type(exc_type) == type(''):
+            exc_type_name = exc_type
+        else: exc_type_name = exc_type.__name__
+        print >>self.stdout, exc_type_name + ':', _saferepr(exc_value)
+        self.interaction(frame, exc_traceback)
+
+    # General interaction function
+
+    def interaction(self, frame, traceback):
+        self.setup(frame, traceback)
+        self.print_stack_entry(self.stack[self.curindex])
+        self.cmdloop()
+        self.forget()
+
+    def default(self, line):
+        if line[:1] == '!': line = line[1:]
+        locals = self.curframe.f_locals
+        globals = self.curframe.f_globals
+        try:
+            code = compile(line + '\n', '<stdin>', 'single')
+            exec code in globals, locals
+        except:
+            t, v = sys.exc_info()[:2]
+            if type(t) == type(''):
+                exc_type_name = t
+            else: exc_type_name = t.__name__
+            print >>self.stdout, '***', exc_type_name + ':', v
+
+    def precmd(self, line):
+        """Handle alias expansion and ';;' separator."""
+        if not line.strip():
+            return line
+        args = line.split()
+        while args[0] in self.aliases:
+            line = self.aliases[args[0]]
+            ii = 1
+            for tmpArg in args[1:]:
+                line = line.replace("%" + str(ii),
+                                      tmpArg)
+                ii = ii + 1
+            line = line.replace("%*", ' '.join(args[1:]))
+            args = line.split()
+        # split into ';;' separated commands
+        # unless it's an alias command
+        if args[0] != 'alias':
+            marker = line.find(';;')
+            if marker >= 0:
+                # queue up everything after marker
+                next = line[marker+2:].lstrip()
+                self.cmdqueue.append(next)
+                line = line[:marker].rstrip()
+        return line
+
+    def onecmd(self, line):
+        """Interpret the argument as though it had been typed in response
+        to the prompt.
+
+        Checks whether this line is typed at the normal prompt or in
+        a breakpoint command list definition.
+        """
+        if not self.commands_defining:
+            return cmd.Cmd.onecmd(self, line)
+        else:
+            return self.handle_command_def(line)
+
+    def handle_command_def(self,line):
+        """ Handles one command line during command list definition. """
+        cmd, arg, line = self.parseline(line)
+        if cmd == 'silent':
+            self.commands_silent[self.commands_bnum] = True
+            return # continue to handle other cmd def in the cmd list
+        elif cmd == 'end':
+            self.cmdqueue = []
+            return 1 # end of cmd list
+        cmdlist = self.commands[self.commands_bnum]
+        if (arg):
+            cmdlist.append(cmd+' '+arg)
+        else:
+            cmdlist.append(cmd)
+        # Determine if we must stop
+        try:
+            func = getattr(self, 'do_' + cmd)
+        except AttributeError:
+            func = self.default
+        if func.func_name in self.commands_resuming : # one of the resuming commands.
+            self.commands_doprompt[self.commands_bnum] = False
+            self.cmdqueue = []
+            return 1
+        return
+
+    # Command definitions, called by cmdloop()
+    # The argument is the remaining string on the command line
+    # Return true to exit from the command loop
+
+    do_h = cmd.Cmd.do_help
+
+    def do_commands(self, arg):
+        """Defines a list of commands associated to a breakpoint
+        Those commands will be executed whenever the breakpoint causes the program to stop execution."""
+        if not arg:
+            bnum = len(bdb.Breakpoint.bpbynumber)-1
+        else:
+            try:
+                bnum = int(arg)
+            except:
+                print >>self.stdout, "Usage : commands [bnum]\n        ...\n        end"
+                return
+        self.commands_bnum = bnum
+        self.commands[bnum] = []
+        self.commands_doprompt[bnum] = True
+        self.commands_silent[bnum] = False
+        prompt_back = self.prompt
+        self.prompt = '(com) '
+        self.commands_defining = True
+        self.cmdloop()
+        self.commands_defining = False
+        self.prompt = prompt_back
+
+    def do_break(self, arg, temporary = 0):
+        # break [ ([filename:]lineno | function) [, "condition"] ]
+        if not arg:
+            if self.breaks:  # There's at least one
+                print >>self.stdout, "Num Type         Disp Enb   Where"
+                for bp in bdb.Breakpoint.bpbynumber:
+                    if bp:
+                        bp.bpprint(self.stdout)
+            return
+        # parse arguments; comma has lowest precedence
+        # and cannot occur in filename
+        filename = None
+        lineno = None
+        cond = None
+        comma = arg.find(',')
+        if comma > 0:
+            # parse stuff after comma: "condition"
+            cond = arg[comma+1:].lstrip()
+            arg = arg[:comma].rstrip()
+        # parse stuff before comma: [filename:]lineno | function
+        colon = arg.rfind(':')
+        funcname = None
+        if colon >= 0:
+            filename = arg[:colon].rstrip()
+            f = self.lookupmodule(filename)
+            if not f:
+                print >>self.stdout, '*** ', repr(filename),
+                print >>self.stdout, 'not found from sys.path'
+                return
+            else:
+                filename = f
+            arg = arg[colon+1:].lstrip()
+            try:
+                lineno = int(arg)
+            except ValueError, msg:
+                print >>self.stdout, '*** Bad lineno:', arg
+                return
+        else:
+            # no colon; can be lineno or function
+            try:
+                lineno = int(arg)
+            except ValueError:
+                try:
+                    func = eval(arg,
+                                self.curframe.f_globals,
+                                self.curframe.f_locals)
+                except:
+                    func = arg
+                try:
+                    if hasattr(func, 'im_func'):
+                        func = func.im_func
+                    code = func.func_code
+                    #use co_name to identify the bkpt (function names
+                    #could be aliased, but co_name is invariant)
+                    funcname = code.co_name
+                    lineno = code.co_firstlineno
+                    filename = code.co_filename
+                except:
+                    # last thing to try
+                    (ok, filename, ln) = self.lineinfo(arg)
+                    if not ok:
+                        print >>self.stdout, '*** The specified object',
+                        print >>self.stdout, repr(arg),
+                        print >>self.stdout, 'is not a function'
+                        print >>self.stdout, 'or was not found along sys.path.'
+                        return
+                    funcname = ok # ok contains a function name
+                    lineno = int(ln)
+        if not filename:
+            filename = self.defaultFile()
+        # Check for reasonable breakpoint
+        line = self.checkline(filename, lineno)
+        if line:
+            # now set the break point
+            err = self.set_break(filename, line, temporary, cond, funcname)
+            if err: print >>self.stdout, '***', err
+            else:
+                bp = self.get_breaks(filename, line)[-1]
+                print >>self.stdout, "Breakpoint %d at %s:%d" % (bp.number,
+                                                                 bp.file,
+                                                                 bp.line)
+
+    # To be overridden in derived debuggers
+    def defaultFile(self):
+        """Produce a reasonable default."""
+        filename = self.curframe.f_code.co_filename
+        if filename == '<string>' and self.mainpyfile:
+            filename = self.mainpyfile
+        return filename
+
+    do_b = do_break
+
+    def do_tbreak(self, arg):
+        self.do_break(arg, 1)
+
+    def lineinfo(self, identifier):
+        failed = (None, None, None)
+        # Input is identifier, may be in single quotes
+        idstring = identifier.split("'")
+        if len(idstring) == 1:
+            # not in single quotes
+            id = idstring[0].strip()
+        elif len(idstring) == 3:
+            # quoted
+            id = idstring[1].strip()
+        else:
+            return failed
+        if id == '': return failed
+        parts = id.split('.')
+        # Protection for derived debuggers
+        if parts[0] == 'self':
+            del parts[0]
+            if len(parts) == 0:
+                return failed
+        # Best first guess at file to look at
+        fname = self.defaultFile()
+        if len(parts) == 1:
+            item = parts[0]
+        else:
+            # More than one part.
+            # First is module, second is method/class
+            f = self.lookupmodule(parts[0])
+            if f:
+                fname = f
+            item = parts[1]
+        answer = find_function(item, fname)
+        return answer or failed
+
+    def checkline(self, filename, lineno):
+        """Check whether specified line seems to be executable.
+
+        Return `lineno` if it is, 0 if not (e.g. a docstring, comment, blank
+        line or EOF). Warning: testing is not comprehensive.
+        """
+        line = linecache.getline(filename, lineno)
+        if not line:
+            print >>self.stdout, 'End of file'
+            return 0
+        line = line.strip()
+        # Don't allow setting breakpoint at a blank line
+        if (not line or (line[0] == '#') or
+             (line[:3] == '"""') or line[:3] == "'''"):
+            print >>self.stdout, '*** Blank or comment'
+            return 0
+        return lineno
+
+    def do_enable(self, arg):
+        args = arg.split()
+        for i in args:
+            try:
+                i = int(i)
+            except ValueError:
+                print >>self.stdout, 'Breakpoint index %r is not a number' % i
+                continue
+
+            if not (0 <= i < len(bdb.Breakpoint.bpbynumber)):
+                print >>self.stdout, 'No breakpoint numbered', i
+                continue
+
+            bp = bdb.Breakpoint.bpbynumber[i]
+            if bp:
+                bp.enable()
+
+    def do_disable(self, arg):
+        args = arg.split()
+        for i in args:
+            try:
+                i = int(i)
+            except ValueError:
+                print >>self.stdout, 'Breakpoint index %r is not a number' % i
+                continue
+
+            if not (0 <= i < len(bdb.Breakpoint.bpbynumber)):
+                print >>self.stdout, 'No breakpoint numbered', i
+                continue
+
+            bp = bdb.Breakpoint.bpbynumber[i]
+            if bp:
+                bp.disable()
+
+    def do_condition(self, arg):
+        # arg is breakpoint number and condition
+        args = arg.split(' ', 1)
+        try:
+            bpnum = int(args[0].strip())
+        except ValueError:
+            # something went wrong
+            print >>self.stdout, \
+                'Breakpoint index %r is not a number' % args[0]
+            return
+        try:
+            cond = args[1]
+        except:
+            cond = None
+        try:
+            bp = bdb.Breakpoint.bpbynumber[bpnum]
+        except IndexError:
+            print >>self.stdout, 'Breakpoint index %r is not valid' % args[0]
+            return
+        if bp:
+            bp.cond = cond
+            if not cond:
+                print >>self.stdout, 'Breakpoint', bpnum,
+                print >>self.stdout, 'is now unconditional.'
+
+    def do_ignore(self,arg):
+        """arg is bp number followed by ignore count."""
+        args = arg.split()
+        try:
+            bpnum = int(args[0].strip())
+        except ValueError:
+            # something went wrong
+            print >>self.stdout, \
+                'Breakpoint index %r is not a number' % args[0]
+            return
+        try:
+            count = int(args[1].strip())
+        except:
+            count = 0
+        try:
+            bp = bdb.Breakpoint.bpbynumber[bpnum]
+        except IndexError:
+            print >>self.stdout, 'Breakpoint index %r is not valid' % args[0]
+            return
+        if bp:
+            bp.ignore = count
+            if count > 0:
+                reply = 'Will ignore next '
+                if count > 1:
+                    reply = reply + '%d crossings' % count
+                else:
+                    reply = reply + '1 crossing'
+                print >>self.stdout, reply + ' of breakpoint %d.' % bpnum
+            else:
+                print >>self.stdout, 'Will stop next time breakpoint',
+                print >>self.stdout, bpnum, 'is reached.'
+
+    def do_clear(self, arg):
+        """Three possibilities, tried in this order:
+        clear -> clear all breaks, ask for confirmation
+        clear file:lineno -> clear all breaks at file:lineno
+        clear bpno bpno ... -> clear breakpoints by number"""
+        if not arg:
+            try:
+                reply = raw_input('Clear all breaks? ')
+            except EOFError:
+                reply = 'no'
+            reply = reply.strip().lower()
+            if reply in ('y', 'yes'):
+                self.clear_all_breaks()
+            return
+        if ':' in arg:
+            # Make sure it works for "clear C:\foo\bar.py:12"
+            i = arg.rfind(':')
+            filename = arg[:i]
+            arg = arg[i+1:]
+            try:
+                lineno = int(arg)
+            except ValueError:
+                err = "Invalid line number (%s)" % arg
+            else:
+                err = self.clear_break(filename, lineno)
+            if err: print >>self.stdout, '***', err
+            return
+        numberlist = arg.split()
+        for i in numberlist:
+            try:
+                i = int(i)
+            except ValueError:
+                print >>self.stdout, 'Breakpoint index %r is not a number' % i
+                continue
+
+            if not (0 <= i < len(bdb.Breakpoint.bpbynumber)):
+                print >>self.stdout, 'No breakpoint numbered', i
+                continue
+            err = self.clear_bpbynumber(i)
+            if err:
+                print >>self.stdout, '***', err
+            else:
+                print >>self.stdout, 'Deleted breakpoint', i
+    do_cl = do_clear # 'c' is already an abbreviation for 'continue'
+
+    def do_where(self, arg):
+        self.print_stack_trace()
+    do_w = do_where
+    do_bt = do_where
+
+    def do_up(self, arg):
+        if self.curindex == 0:
+            print >>self.stdout, '*** Oldest frame'
+        else:
+            self.curindex = self.curindex - 1
+            self.curframe = self.stack[self.curindex][0]
+            self.print_stack_entry(self.stack[self.curindex])
+            self.lineno = None
+    do_u = do_up
+
+    def do_down(self, arg):
+        if self.curindex + 1 == len(self.stack):
+            print >>self.stdout, '*** Newest frame'
+        else:
+            self.curindex = self.curindex + 1
+            self.curframe = self.stack[self.curindex][0]
+            self.print_stack_entry(self.stack[self.curindex])
+            self.lineno = None
+    do_d = do_down
+
+    def do_step(self, arg):
+        self.set_step()
+        return 1
+    do_s = do_step
+
+    def do_next(self, arg):
+        self.set_next(self.curframe)
+        return 1
+    do_n = do_next
+
+    def do_return(self, arg):
+        self.set_return(self.curframe)
+        return 1
+    do_r = do_return
+
+    def do_continue(self, arg):
+        self.set_continue()
+        return 1
+    do_c = do_cont = do_continue
+
+    def do_jump(self, arg):
+        if self.curindex + 1 != len(self.stack):
+            print >>self.stdout, "*** You can only jump within the bottom frame"
+            return
+        try:
+            arg = int(arg)
+        except ValueError:
+            print >>self.stdout, "*** The 'jump' command requires a line number."
+        else:
+            try:
+                # Do the jump, fix up our copy of the stack, and display the
+                # new position
+                self.curframe.f_lineno = arg
+                self.stack[self.curindex] = self.stack[self.curindex][0], arg
+                self.print_stack_entry(self.stack[self.curindex])
+            except ValueError, e:
+                print >>self.stdout, '*** Jump failed:', e
+    do_j = do_jump
+
+    def do_debug(self, arg):
+        sys.settrace(None)
+        globals = self.curframe.f_globals
+        locals = self.curframe.f_locals
+        p = Pdb()
+        p.prompt = "(%s) " % self.prompt.strip()
+        print >>self.stdout, "ENTERING RECURSIVE DEBUGGER"
+        sys.call_tracing(p.run, (arg, globals, locals))
+        print >>self.stdout, "LEAVING RECURSIVE DEBUGGER"
+        sys.settrace(self.trace_dispatch)
+        self.lastcmd = p.lastcmd
+
+    def do_quit(self, arg):
+        self._user_requested_quit = 1
+        self.set_quit()
+        return 1
+
+    do_q = do_quit
+    do_exit = do_quit
+
+    def do_EOF(self, arg):
+        print >>self.stdout
+        self._user_requested_quit = 1
+        self.set_quit()
+        return 1
+
+    def do_args(self, arg):
+        f = self.curframe
+        co = f.f_code
+        dict = f.f_locals
+        n = co.co_argcount
+        if co.co_flags & 4: n = n+1
+        if co.co_flags & 8: n = n+1
+        for i in range(n):
+            name = co.co_varnames[i]
+            print >>self.stdout, name, '=',
+            if name in dict: print >>self.stdout, dict[name]
+            else: print >>self.stdout, "*** undefined ***"
+    do_a = do_args
+
+    def do_retval(self, arg):
+        if '__return__' in self.curframe.f_locals:
+            print >>self.stdout, self.curframe.f_locals['__return__']
+        else:
+            print >>self.stdout, '*** Not yet returned!'
+    do_rv = do_retval
+
+    def _getval(self, arg):
+        try:
+            return eval(arg, self.curframe.f_globals,
+                        self.curframe.f_locals)
+        except:
+            t, v = sys.exc_info()[:2]
+            if isinstance(t, str):
+                exc_type_name = t
+            else: exc_type_name = t.__name__
+            print >>self.stdout, '***', exc_type_name + ':', repr(v)
+            raise
+
+    def do_p(self, arg):
+        try:
+            print >>self.stdout, repr(self._getval(arg))
+        except:
+            pass
+
+    def do_pp(self, arg):
+        try:
+            pprint.pprint(self._getval(arg), self.stdout)
+        except:
+            pass
+
+    def do_list(self, arg):
+        self.lastcmd = 'list'
+        last = None
+        if arg:
+            try:
+                x = eval(arg, {}, {})
+                if type(x) == type(()):
+                    first, last = x
+                    first = int(first)
+                    last = int(last)
+                    if last < first:
+                        # Assume it's a count
+                        last = first + last
+                else:
+                    first = max(1, int(x) - 5)
+            except:
+                print >>self.stdout, '*** Error in argument:', repr(arg)
+                return
+        elif self.lineno is None:
+            first = max(1, self.curframe.f_lineno - 5)
+        else:
+            first = self.lineno + 1
+        if last is None:
+            last = first + 10
+        filename = self.curframe.f_code.co_filename
+        breaklist = self.get_file_breaks(filename)
+        try:
+            for lineno in range(first, last+1):
+                line = linecache.getline(filename, lineno)
+                if not line:
+                    print >>self.stdout, '[EOF]'
+                    break
+                else:
+                    s = repr(lineno).rjust(3)
+                    if len(s) < 4: s = s + ' '
+                    if lineno in breaklist: s = s + 'B'
+                    else: s = s + ' '
+                    if lineno == self.curframe.f_lineno:
+                        s = s + '->'
+                    print >>self.stdout, s + '\t' + line,
+                    self.lineno = lineno
+        except KeyboardInterrupt:
+            pass
+    do_l = do_list
+
+    def do_whatis(self, arg):
+        try:
+            value = eval(arg, self.curframe.f_globals,
+                            self.curframe.f_locals)
+        except:
+            t, v = sys.exc_info()[:2]
+            if type(t) == type(''):
+                exc_type_name = t
+            else: exc_type_name = t.__name__
+            print >>self.stdout, '***', exc_type_name + ':', repr(v)
+            return
+        code = None
+        # Is it a function?
+        try: code = value.func_code
+        except: pass
+        if code:
+            print >>self.stdout, 'Function', code.co_name
+            return
+        # Is it an instance method?
+        try: code = value.im_func.func_code
+        except: pass
+        if code:
+            print >>self.stdout, 'Method', code.co_name
+            return
+        # None of the above...
+        print >>self.stdout, type(value)
+
+    def do_alias(self, arg):
+        args = arg.split()
+        if len(args) == 0:
+            keys = self.aliases.keys()
+            keys.sort()
+            for alias in keys:
+                print >>self.stdout, "%s = %s" % (alias, self.aliases[alias])
+            return
+        if args[0] in self.aliases and len(args) == 1:
+            print >>self.stdout, "%s = %s" % (args[0], self.aliases[args[0]])
+        else:
+            self.aliases[args[0]] = ' '.join(args[1:])
+
+    def do_unalias(self, arg):
+        args = arg.split()
+        if len(args) == 0: return
+        if args[0] in self.aliases:
+            del self.aliases[args[0]]
+
+    #list of all the commands making the program resume execution.
+    commands_resuming = ['do_continue', 'do_step', 'do_next', 'do_return',
+                         'do_quit', 'do_jump']
+
+    # Print a traceback starting at the top stack frame.
+    # The most recently entered frame is printed last;
+    # this is different from dbx and gdb, but consistent with
+    # the Python interpreter's stack trace.
+    # It is also consistent with the up/down commands (which are
+    # compatible with dbx and gdb: up moves towards 'main()'
+    # and down moves towards the most recent stack frame).
+
+    def print_stack_trace(self):
+        try:
+            for frame_lineno in self.stack:
+                self.print_stack_entry(frame_lineno)
+        except KeyboardInterrupt:
+            pass
+
+    def print_stack_entry(self, frame_lineno, prompt_prefix=line_prefix):
+        frame, lineno = frame_lineno
+        if frame is self.curframe:
+            print >>self.stdout, '>',
+        else:
+            print >>self.stdout, ' ',
+        print >>self.stdout, self.format_stack_entry(frame_lineno,
+                                                     prompt_prefix)
+
+
+    # Help methods (derived from pdb.doc)
+
+    def help_help(self):
+        self.help_h()
+
+    def help_h(self):
+        print >>self.stdout, """h(elp)
+Without argument, print the list of available commands.
+With a command name as argument, print help about that command
+"help pdb" pipes the full documentation file to the $PAGER
+"help exec" gives help on the ! command"""
+
+    def help_where(self):
+        self.help_w()
+
+    def help_w(self):
+        print >>self.stdout, """w(here)
+Print a stack trace, with the most recent frame at the bottom.
+An arrow indicates the "current frame", which determines the
+context of most commands.  'bt' is an alias for this command."""
+
+    help_bt = help_w
+
+    def help_down(self):
+        self.help_d()
+
+    def help_d(self):
+        print >>self.stdout, """d(own)
+Move the current frame one level down in the stack trace
+(to a newer frame)."""
+
+    def help_up(self):
+        self.help_u()
+
+    def help_u(self):
+        print >>self.stdout, """u(p)
+Move the current frame one level up in the stack trace
+(to an older frame)."""
+
+    def help_break(self):
+        self.help_b()
+
+    def help_b(self):
+        print >>self.stdout, """b(reak) ([file:]lineno | function) [, condition]
+With a line number argument, set a break there in the current
+file.  With a function name, set a break at first executable line
+of that function.  Without argument, list all breaks.  If a second
+argument is present, it is a string specifying an expression
+which must evaluate to true before the breakpoint is honored.
+
+The line number may be prefixed with a filename and a colon,
+to specify a breakpoint in another file (probably one that
+hasn't been loaded yet).  The file is searched for on sys.path;
+the .py suffix may be omitted."""
+
+    def help_clear(self):
+        self.help_cl()
+
+    def help_cl(self):
+        print >>self.stdout, "cl(ear) filename:lineno"
+        print >>self.stdout, """cl(ear) [bpnumber [bpnumber...]]
+With a space separated list of breakpoint numbers, clear
+those breakpoints.  Without argument, clear all breaks (but
+first ask confirmation).  With a filename:lineno argument,
+clear all breaks at that line in that file.
+
+Note that the argument is different from previous versions of
+the debugger (in python distributions 1.5.1 and before) where
+a linenumber was used instead of either filename:lineno or
+breakpoint numbers."""
+
+    def help_tbreak(self):
+        print >>self.stdout, """tbreak  same arguments as break, but breakpoint is
+removed when first hit."""
+
+    def help_enable(self):
+        print >>self.stdout, """enable bpnumber [bpnumber ...]
+Enables the breakpoints given as a space separated list of
+bp numbers."""
+
+    def help_disable(self):
+        print >>self.stdout, """disable bpnumber [bpnumber ...]
+Disables the breakpoints given as a space separated list of
+bp numbers."""
+
+    def help_ignore(self):
+        print >>self.stdout, """ignore bpnumber count
+Sets the ignore count for the given breakpoint number.  A breakpoint
+becomes active when the ignore count is zero.  When non-zero, the
+count is decremented each time the breakpoint is reached and the
+breakpoint is not disabled and any associated condition evaluates
+to true."""
+
+    def help_condition(self):
+        print >>self.stdout, """condition bpnumber str_condition
+str_condition is a string specifying an expression which
+must evaluate to true before the breakpoint is honored.
+If str_condition is absent, any existing condition is removed;
+i.e., the breakpoint is made unconditional."""
+
+    def help_step(self):
+        self.help_s()
+
+    def help_s(self):
+        print >>self.stdout, """s(tep)
+Execute the current line, stop at the first possible occasion
+(either in a function that is called or in the current function)."""
+
+    def help_next(self):
+        self.help_n()
+
+    def help_n(self):
+        print >>self.stdout, """n(ext)
+Continue execution until the next line in the current function
+is reached or it returns."""
+
+    def help_return(self):
+        self.help_r()
+
+    def help_r(self):
+        print >>self.stdout, """r(eturn)
+Continue execution until the current function returns."""
+
+    def help_continue(self):
+        self.help_c()
+
+    def help_cont(self):
+        self.help_c()
+
+    def help_c(self):
+        print >>self.stdout, """c(ont(inue))
+Continue execution, only stop when a breakpoint is encountered."""
+
+    def help_jump(self):
+        self.help_j()
+
+    def help_j(self):
+        print >>self.stdout, """j(ump) lineno
+Set the next line that will be executed."""
+
+    def help_debug(self):
+        print >>self.stdout, """debug code
+Enter a recursive debugger that steps through the code argument
+(which is an arbitrary expression or statement to be executed
+in the current environment)."""
+
+    def help_list(self):
+        self.help_l()
+
+    def help_l(self):
+        print >>self.stdout, """l(ist) [first [,last]]
+List source code for the current file.
+Without arguments, list 11 lines around the current line
+or continue the previous listing.
+With one argument, list 11 lines starting at that line.
+With two arguments, list the given range;
+if the second argument is less than the first, it is a count."""
+
+    def help_args(self):
+        self.help_a()
+
+    def help_a(self):
+        print >>self.stdout, """a(rgs)
+Print the arguments of the current function."""
+
+    def help_p(self):
+        print >>self.stdout, """p expression
+Print the value of the expression."""
+
+    def help_pp(self):
+        print >>self.stdout, """pp expression
+Pretty-print the value of the expression."""
+
+    def help_exec(self):
+        print >>self.stdout, """(!) statement
+Execute the (one-line) statement in the context of
+the current stack frame.
+The exclamation point can be omitted unless the first word
+of the statement resembles a debugger command.
+To assign to a global variable you must always prefix the
+command with a 'global' command, e.g.:
+(Pdb) global list_options; list_options = ['-l']
+(Pdb)"""
+
+    def help_quit(self):
+        self.help_q()
+
+    def help_q(self):
+        print >>self.stdout, """q(uit) or exit - Quit from the debugger.
+The program being executed is aborted."""
+
+    help_exit = help_q
+
+    def help_whatis(self):
+        print >>self.stdout, """whatis arg
+Prints the type of the argument."""
+
+    def help_EOF(self):
+        print >>self.stdout, """EOF
+Handles the receipt of EOF as a command."""
+
+    def help_alias(self):
+        print >>self.stdout, """alias [name [command [parameter parameter ...] ]]
+Creates an alias called 'name' the executes 'command'.  The command
+must *not* be enclosed in quotes.  Replaceable parameters are
+indicated by %1, %2, and so on, while %* is replaced by all the
+parameters.  If no command is given, the current alias for name
+is shown. If no name is given, all aliases are listed.
+
+Aliases may be nested and can contain anything that can be
+legally typed at the pdb prompt.  Note!  You *can* override
+internal pdb commands with aliases!  Those internal commands
+are then hidden until the alias is removed.  Aliasing is recursively
+applied to the first word of the command line; all other words
+in the line are left alone.
+
+Some useful aliases (especially when placed in the .pdbrc file) are:
+
+#Print instance variables (usage "pi classInst")
+alias pi for k in %1.__dict__.keys(): print "%1.",k,"=",%1.__dict__[k]
+
+#Print instance variables in self
+alias ps pi self
+"""
+
+    def help_unalias(self):
+        print >>self.stdout, """unalias name
+Deletes the specified alias."""
+
+    def help_commands(self):
+        print >>self.stdout, """commands [bpnumber]
+(com) ...
+(com) end
+(Pdb)
+
+Specify a list of commands for breakpoint number bpnumber.  The
+commands themselves appear on the following lines.  Type a line
+containing just 'end' to terminate the commands.
+
+To remove all commands from a breakpoint, type commands and
+follow it immediately with  end; that is, give no commands.
+
+With no bpnumber argument, commands refers to the last
+breakpoint set.
+
+You can use breakpoint commands to start your program up again.
+Simply use the continue command, or step, or any other
+command that resumes execution.
+
+Specifying any command resuming execution (currently continue,
+step, next, return, jump, quit and their abbreviations) terminates
+the command list (as if that command was immediately followed by end).
+This is because any time you resume execution
+(even with a simple next or step), you may encounter
+another breakpoint--which could have its own command list, leading to
+ambiguities about which list to execute.
+
+   If you use the 'silent' command in the command list, the
+usual message about stopping at a breakpoint is not printed.  This may
+be desirable for breakpoints that are to print a specific message and
+then continue.  If none of the other commands print anything, you
+see no sign that the breakpoint was reached.
+"""
+
+    def help_pdb(self):
+        help()
+
+    def lookupmodule(self, filename):
+        """Helper function for break/clear parsing -- may be overridden.
+
+        lookupmodule() translates (possibly incomplete) file or module name
+        into an absolute file name.
+        """
+        if os.path.isabs(filename) and  os.path.exists(filename):
+            return filename
+        f = os.path.join(sys.path[0], filename)
+        if  os.path.exists(f) and self.canonic(f) == self.mainpyfile:
+            return f
+        root, ext = os.path.splitext(filename)
+        if ext == '':
+            filename = filename + '.py'
+        if os.path.isabs(filename):
+            return filename
+        for dirname in sys.path:
+            while os.path.islink(dirname):
+                dirname = os.readlink(dirname)
+            fullname = os.path.join(dirname, filename)
+            if os.path.exists(fullname):
+                return fullname
+        return None
+
+    def _runscript(self, filename):
+        # Start with fresh empty copy of globals and locals and tell the script
+        # that it's being run as __main__ to avoid scripts being able to access
+        # the pdb.py namespace.
+        globals_ = {"__name__" : "__main__"}
+        locals_ = globals_
+
+        # When bdb sets tracing, a number of call and line events happens
+        # BEFORE debugger even reaches user's code (and the exact sequence of
+        # events depends on python version). So we take special measures to
+        # avoid stopping before we reach the main script (see user_line and
+        # user_call for details).
+        self._wait_for_mainpyfile = 1
+        self.mainpyfile = self.canonic(filename)
+        self._user_requested_quit = 0
+        statement = 'execfile( "%s")' % filename
+        self.run(statement, globals=globals_, locals=locals_)
+
+# Simplified interface
+
+def run(statement, globals=None, locals=None):
+    Pdb().run(statement, globals, locals)
+
+def runeval(expression, globals=None, locals=None):
+    return Pdb().runeval(expression, globals, locals)
+
+def runctx(statement, globals, locals):
+    # B/W compatibility
+    run(statement, globals, locals)
+
+def runcall(*args, **kwds):
+    return Pdb().runcall(*args, **kwds)
+
+def set_trace():
+    Pdb().set_trace(sys._getframe().f_back)
+
+# Post-Mortem interface
+
+def post_mortem(t):
+    p = Pdb()
+    p.reset()
+    while t.tb_next is not None:
+        t = t.tb_next
+    p.interaction(t.tb_frame, t)
+
+def pm():
+    post_mortem(sys.last_traceback)
+
+
+# Main program for testing
+
+TESTCMD = 'import x; x.main()'
+
+def test():
+    run(TESTCMD)
+
+# print help
+def help():
+    for dirname in sys.path:
+        fullname = os.path.join(dirname, 'pdb.doc')
+        if os.path.exists(fullname):
+            sts = os.system('${PAGER-more} '+fullname)
+            if sts: print '*** Pager exit status:', sts
+            break
+    else:
+        print 'Sorry, can\'t find the help file "pdb.doc"',
+        print 'along the Python search path'
+
+def main():
+    if not sys.argv[1:]:
+        print "usage: pdb.py scriptfile [arg] ..."
+        sys.exit(2)
+
+    mainpyfile =  sys.argv[1]     # Get script filename
+    if not os.path.exists(mainpyfile):
+        print 'Error:', mainpyfile, 'does not exist'
+        sys.exit(1)
+
+    del sys.argv[0]         # Hide "pdb.py" from argument list
+
+    # Replace pdb's dir with script's dir in front of module search path.
+    sys.path[0] = os.path.dirname(mainpyfile)
+
+    # Note on saving/restoring sys.argv: it's a good idea when sys.argv was
+    # modified by the script being debugged. It's a bad idea when it was
+    # changed by the user from the command line. The best approach would be to
+    # have a "restart" command which would allow explicit specification of
+    # command line arguments.
+    pdb = Pdb()
+    while 1:
+        try:
+            pdb._runscript(mainpyfile)
+            if pdb._user_requested_quit:
+                break
+            print "The program finished and will be restarted"
+        except SystemExit:
+            # In most cases SystemExit does not warrant a post-mortem session.
+            print "The program exited via sys.exit(). Exit status: ",
+            print sys.exc_info()[1]
+        except:
+            traceback.print_exc()
+            print "Uncaught exception. Entering post mortem debugging"
+            print "Running 'cont' or 'step' will restart the program"
+            t = sys.exc_info()[2]
+            while t.tb_next is not None:
+                t = t.tb_next
+            pdb.interaction(t.tb_frame,t)
+            print "Post mortem debugger finished. The "+mainpyfile+" will be restarted"
+
+
+# When invoked as main program, invoke the debugger on a script
+if __name__=='__main__':
+    main()


Property changes on: vendor/Python/current/Lib/pdb.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/pickle.py
===================================================================
--- vendor/Python/current/Lib/pickle.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/pickle.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1383 @@
+"""Create portable serialized representations of Python objects.
+
+See module cPickle for a (much) faster implementation.
+See module copy_reg for a mechanism for registering custom picklers.
+See module pickletools source for extensive comments.
+
+Classes:
+
+    Pickler
+    Unpickler
+
+Functions:
+
+    dump(object, file)
+    dumps(object) -> string
+    load(file) -> object
+    loads(string) -> object
+
+Misc variables:
+
+    __version__
+    format_version
+    compatible_formats
+
+"""
+
+__version__ = "$Revision: 38432 $"       # Code version
+
+from types import *
+from copy_reg import dispatch_table
+from copy_reg import _extension_registry, _inverted_registry, _extension_cache
+import marshal
+import sys
+import struct
+import re
+
+__all__ = ["PickleError", "PicklingError", "UnpicklingError", "Pickler",
+           "Unpickler", "dump", "dumps", "load", "loads"]
+
+# These are purely informational; no code uses these.
+format_version = "2.0"                  # File format version we write
+compatible_formats = ["1.0",            # Original protocol 0
+                      "1.1",            # Protocol 0 with INST added
+                      "1.2",            # Original protocol 1
+                      "1.3",            # Protocol 1 with BINFLOAT added
+                      "2.0",            # Protocol 2
+                      ]                 # Old format versions we can read
+
+# Keep in synch with cPickle.  This is the highest protocol number we
+# know how to read.
+HIGHEST_PROTOCOL = 2
+
+# Why use struct.pack() for pickling but marshal.loads() for
+# unpickling?  struct.pack() is 40% faster than marshal.dumps(), but
+# marshal.loads() is twice as fast as struct.unpack()!
+mloads = marshal.loads
+
+class PickleError(Exception):
+    """A common base class for the other pickling exceptions."""
+    pass
+
+class PicklingError(PickleError):
+    """This exception is raised when an unpicklable object is passed to the
+    dump() method.
+
+    """
+    pass
+
+class UnpicklingError(PickleError):
+    """This exception is raised when there is a problem unpickling an object,
+    such as a security violation.
+
+    Note that other exceptions may also be raised during unpickling, including
+    (but not necessarily limited to) AttributeError, EOFError, ImportError,
+    and IndexError.
+
+    """
+    pass
+
+# An instance of _Stop is raised by Unpickler.load_stop() in response to
+# the STOP opcode, passing the object that is the result of unpickling.
+class _Stop(Exception):
+    def __init__(self, value):
+        self.value = value
+
+# Jython has PyStringMap; it's a dict subclass with string keys
+try:
+    from org.python.core import PyStringMap
+except ImportError:
+    PyStringMap = None
+
+# UnicodeType may or may not be exported (normally imported from types)
+try:
+    UnicodeType
+except NameError:
+    UnicodeType = None
+
+# Pickle opcodes.  See pickletools.py for extensive docs.  The listing
+# here is in kind-of alphabetical order of 1-character pickle code.
+# pickletools groups them by purpose.
+
+MARK            = '('   # push special markobject on stack
+STOP            = '.'   # every pickle ends with STOP
+POP             = '0'   # discard topmost stack item
+POP_MARK        = '1'   # discard stack top through topmost markobject
+DUP             = '2'   # duplicate top stack item
+FLOAT           = 'F'   # push float object; decimal string argument
+INT             = 'I'   # push integer or bool; decimal string argument
+BININT          = 'J'   # push four-byte signed int
+BININT1         = 'K'   # push 1-byte unsigned int
+LONG            = 'L'   # push long; decimal string argument
+BININT2         = 'M'   # push 2-byte unsigned int
+NONE            = 'N'   # push None
+PERSID          = 'P'   # push persistent object; id is taken from string arg
+BINPERSID       = 'Q'   #  "       "         "  ;  "  "   "     "  stack
+REDUCE          = 'R'   # apply callable to argtuple, both on stack
+STRING          = 'S'   # push string; NL-terminated string argument
+BINSTRING       = 'T'   # push string; counted binary string argument
+SHORT_BINSTRING = 'U'   #  "     "   ;    "      "       "      " < 256 bytes
+UNICODE         = 'V'   # push Unicode string; raw-unicode-escaped'd argument
+BINUNICODE      = 'X'   #   "     "       "  ; counted UTF-8 string argument
+APPEND          = 'a'   # append stack top to list below it
+BUILD           = 'b'   # call __setstate__ or __dict__.update()
+GLOBAL          = 'c'   # push self.find_class(modname, name); 2 string args
+DICT            = 'd'   # build a dict from stack items
+EMPTY_DICT      = '}'   # push empty dict
+APPENDS         = 'e'   # extend list on stack by topmost stack slice
+GET             = 'g'   # push item from memo on stack; index is string arg
+BINGET          = 'h'   #   "    "    "    "   "   "  ;   "    " 1-byte arg
+INST            = 'i'   # build & push class instance
+LONG_BINGET     = 'j'   # push item from memo on stack; index is 4-byte arg
+LIST            = 'l'   # build list from topmost stack items
+EMPTY_LIST      = ']'   # push empty list
+OBJ             = 'o'   # build & push class instance
+PUT             = 'p'   # store stack top in memo; index is string arg
+BINPUT          = 'q'   #   "     "    "   "   " ;   "    " 1-byte arg
+LONG_BINPUT     = 'r'   #   "     "    "   "   " ;   "    " 4-byte arg
+SETITEM         = 's'   # add key+value pair to dict
+TUPLE           = 't'   # build tuple from topmost stack items
+EMPTY_TUPLE     = ')'   # push empty tuple
+SETITEMS        = 'u'   # modify dict by adding topmost key+value pairs
+BINFLOAT        = 'G'   # push float; arg is 8-byte float encoding
+
+TRUE            = 'I01\n'  # not an opcode; see INT docs in pickletools.py
+FALSE           = 'I00\n'  # not an opcode; see INT docs in pickletools.py
+
+# Protocol 2
+
+PROTO           = '\x80'  # identify pickle protocol
+NEWOBJ          = '\x81'  # build object by applying cls.__new__ to argtuple
+EXT1            = '\x82'  # push object from extension registry; 1-byte index
+EXT2            = '\x83'  # ditto, but 2-byte index
+EXT4            = '\x84'  # ditto, but 4-byte index
+TUPLE1          = '\x85'  # build 1-tuple from stack top
+TUPLE2          = '\x86'  # build 2-tuple from two topmost stack items
+TUPLE3          = '\x87'  # build 3-tuple from three topmost stack items
+NEWTRUE         = '\x88'  # push True
+NEWFALSE        = '\x89'  # push False
+LONG1           = '\x8a'  # push long from < 256 bytes
+LONG4           = '\x8b'  # push really big long
+
+_tuplesize2code = [EMPTY_TUPLE, TUPLE1, TUPLE2, TUPLE3]
+
+
+__all__.extend([x for x in dir() if re.match("[A-Z][A-Z0-9_]+$",x)])
+del x
+
+
+# Pickling machinery
+
+class Pickler:
+
+    def __init__(self, file, protocol=None):
+        """This takes a file-like object for writing a pickle data stream.
+
+        The optional protocol argument tells the pickler to use the
+        given protocol; supported protocols are 0, 1, 2.  The default
+        protocol is 0, to be backwards compatible.  (Protocol 0 is the
+        only protocol that can be written to a file opened in text
+        mode and read back successfully.  When using a protocol higher
+        than 0, make sure the file is opened in binary mode, both when
+        pickling and unpickling.)
+
+        Protocol 1 is more efficient than protocol 0; protocol 2 is
+        more efficient than protocol 1.
+
+        Specifying a negative protocol version selects the highest
+        protocol version supported.  The higher the protocol used, the
+        more recent the version of Python needed to read the pickle
+        produced.
+
+        The file parameter must have a write() method that accepts a single
+        string argument.  It can thus be an open file object, a StringIO
+        object, or any other custom object that meets this interface.
+
+        """
+        if protocol is None:
+            protocol = 0
+        if protocol < 0:
+            protocol = HIGHEST_PROTOCOL
+        elif not 0 <= protocol <= HIGHEST_PROTOCOL:
+            raise ValueError("pickle protocol must be <= %d" % HIGHEST_PROTOCOL)
+        self.write = file.write
+        self.memo = {}
+        self.proto = int(protocol)
+        self.bin = protocol >= 1
+        self.fast = 0
+
+    def clear_memo(self):
+        """Clears the pickler's "memo".
+
+        The memo is the data structure that remembers which objects the
+        pickler has already seen, so that shared or recursive objects are
+        pickled by reference and not by value.  This method is useful when
+        re-using picklers.
+
+        """
+        self.memo.clear()
+
+    def dump(self, obj):
+        """Write a pickled representation of obj to the open file."""
+        if self.proto >= 2:
+            self.write(PROTO + chr(self.proto))
+        self.save(obj)
+        self.write(STOP)
+
+    def memoize(self, obj):
+        """Store an object in the memo."""
+
+        # The Pickler memo is a dictionary mapping object ids to 2-tuples
+        # that contain the Unpickler memo key and the object being memoized.
+        # The memo key is written to the pickle and will become
+        # the key in the Unpickler's memo.  The object is stored in the
+        # Pickler memo so that transient objects are kept alive during
+        # pickling.
+
+        # The use of the Unpickler memo length as the memo key is just a
+        # convention.  The only requirement is that the memo values be unique.
+        # But there appears no advantage to any other scheme, and this
+        # scheme allows the Unpickler memo to be implemented as a plain (but
+        # growable) array, indexed by memo key.
+        if self.fast:
+            return
+        assert id(obj) not in self.memo
+        memo_len = len(self.memo)
+        self.write(self.put(memo_len))
+        self.memo[id(obj)] = memo_len, obj
+
+    # Return a PUT (BINPUT, LONG_BINPUT) opcode string, with argument i.
+    def put(self, i, pack=struct.pack):
+        if self.bin:
+            if i < 256:
+                return BINPUT + chr(i)
+            else:
+                return LONG_BINPUT + pack("<i", i)
+
+        return PUT + repr(i) + '\n'
+
+    # Return a GET (BINGET, LONG_BINGET) opcode string, with argument i.
+    def get(self, i, pack=struct.pack):
+        if self.bin:
+            if i < 256:
+                return BINGET + chr(i)
+            else:
+                return LONG_BINGET + pack("<i", i)
+
+        return GET + repr(i) + '\n'
+
+    def save(self, obj):
+        # Check for persistent id (defined by a subclass)
+        pid = self.persistent_id(obj)
+        if pid:
+            self.save_pers(pid)
+            return
+
+        # Check the memo
+        x = self.memo.get(id(obj))
+        if x:
+            self.write(self.get(x[0]))
+            return
+
+        # Check the type dispatch table
+        t = type(obj)
+        f = self.dispatch.get(t)
+        if f:
+            f(self, obj) # Call unbound method with explicit self
+            return
+
+        # Check for a class with a custom metaclass; treat as regular class
+        try:
+            issc = issubclass(t, TypeType)
+        except TypeError: # t is not a class (old Boost; see SF #502085)
+            issc = 0
+        if issc:
+            self.save_global(obj)
+            return
+
+        # Check copy_reg.dispatch_table
+        reduce = dispatch_table.get(t)
+        if reduce:
+            rv = reduce(obj)
+        else:
+            # Check for a __reduce_ex__ method, fall back to __reduce__
+            reduce = getattr(obj, "__reduce_ex__", None)
+            if reduce:
+                rv = reduce(self.proto)
+            else:
+                reduce = getattr(obj, "__reduce__", None)
+                if reduce:
+                    rv = reduce()
+                else:
+                    raise PicklingError("Can't pickle %r object: %r" %
+                                        (t.__name__, obj))
+
+        # Check for string returned by reduce(), meaning "save as global"
+        if type(rv) is StringType:
+            self.save_global(obj, rv)
+            return
+
+        # Assert that reduce() returned a tuple
+        if type(rv) is not TupleType:
+            raise PicklingError("%s must return string or tuple" % reduce)
+
+        # Assert that it returned an appropriately sized tuple
+        l = len(rv)
+        if not (2 <= l <= 5):
+            raise PicklingError("Tuple returned by %s must have "
+                                "two to five elements" % reduce)
+
+        # Save the reduce() output and finally memoize the object
+        self.save_reduce(obj=obj, *rv)
+
+    def persistent_id(self, obj):
+        # This exists so a subclass can override it
+        return None
+
+    def save_pers(self, pid):
+        # Save a persistent id reference
+        if self.bin:
+            self.save(pid)
+            self.write(BINPERSID)
+        else:
+            self.write(PERSID + str(pid) + '\n')
+
+    def save_reduce(self, func, args, state=None,
+                    listitems=None, dictitems=None, obj=None):
+        # This API is called by some subclasses
+
+        # Assert that args is a tuple or None
+        if not isinstance(args, TupleType):
+            raise PicklingError("args from reduce() should be a tuple")
+
+        # Assert that func is callable
+        if not callable(func):
+            raise PicklingError("func from reduce should be callable")
+
+        save = self.save
+        write = self.write
+
+        # Protocol 2 special case: if func's name is __newobj__, use NEWOBJ
+        if self.proto >= 2 and getattr(func, "__name__", "") == "__newobj__":
+            # A __reduce__ implementation can direct protocol 2 to
+            # use the more efficient NEWOBJ opcode, while still
+            # allowing protocol 0 and 1 to work normally.  For this to
+            # work, the function returned by __reduce__ should be
+            # called __newobj__, and its first argument should be a
+            # new-style class.  The implementation for __newobj__
+            # should be as follows, although pickle has no way to
+            # verify this:
+            #
+            # def __newobj__(cls, *args):
+            #     return cls.__new__(cls, *args)
+            #
+            # Protocols 0 and 1 will pickle a reference to __newobj__,
+            # while protocol 2 (and above) will pickle a reference to
+            # cls, the remaining args tuple, and the NEWOBJ code,
+            # which calls cls.__new__(cls, *args) at unpickling time
+            # (see load_newobj below).  If __reduce__ returns a
+            # three-tuple, the state from the third tuple item will be
+            # pickled regardless of the protocol, calling __setstate__
+            # at unpickling time (see load_build below).
+            #
+            # Note that no standard __newobj__ implementation exists;
+            # you have to provide your own.  This is to enforce
+            # compatibility with Python 2.2 (pickles written using
+            # protocol 0 or 1 in Python 2.3 should be unpicklable by
+            # Python 2.2).
+            cls = args[0]
+            if not hasattr(cls, "__new__"):
+                raise PicklingError(
+                    "args[0] from __newobj__ args has no __new__")
+            if obj is not None and cls is not obj.__class__:
+                raise PicklingError(
+                    "args[0] from __newobj__ args has the wrong class")
+            args = args[1:]
+            save(cls)
+            save(args)
+            write(NEWOBJ)
+        else:
+            save(func)
+            save(args)
+            write(REDUCE)
+
+        if obj is not None:
+            self.memoize(obj)
+
+        # More new special cases (that work with older protocols as
+        # well): when __reduce__ returns a tuple with 4 or 5 items,
+        # the 4th and 5th item should be iterators that provide list
+        # items and dict items (as (key, value) tuples), or None.
+
+        if listitems is not None:
+            self._batch_appends(listitems)
+
+        if dictitems is not None:
+            self._batch_setitems(dictitems)
+
+        if state is not None:
+            save(state)
+            write(BUILD)
+
+    # Methods below this point are dispatched through the dispatch table
+
+    dispatch = {}
+
+    def save_none(self, obj):
+        self.write(NONE)
+    dispatch[NoneType] = save_none
+
+    def save_bool(self, obj):
+        if self.proto >= 2:
+            self.write(obj and NEWTRUE or NEWFALSE)
+        else:
+            self.write(obj and TRUE or FALSE)
+    dispatch[bool] = save_bool
+
+    def save_int(self, obj, pack=struct.pack):
+        if self.bin:
+            # If the int is small enough to fit in a signed 4-byte 2's-comp
+            # format, we can store it more efficiently than the general
+            # case.
+            # First one- and two-byte unsigned ints:
+            if obj >= 0:
+                if obj <= 0xff:
+                    self.write(BININT1 + chr(obj))
+                    return
+                if obj <= 0xffff:
+                    self.write("%c%c%c" % (BININT2, obj&0xff, obj>>8))
+                    return
+            # Next check for 4-byte signed ints:
+            high_bits = obj >> 31  # note that Python shift sign-extends
+            if high_bits == 0 or high_bits == -1:
+                # All high bits are copies of bit 2**31, so the value
+                # fits in a 4-byte signed int.
+                self.write(BININT + pack("<i", obj))
+                return
+        # Text pickle, or int too big to fit in signed 4-byte format.
+        self.write(INT + repr(obj) + '\n')
+    dispatch[IntType] = save_int
+
+    def save_long(self, obj, pack=struct.pack):
+        if self.proto >= 2:
+            bytes = encode_long(obj)
+            n = len(bytes)
+            if n < 256:
+                self.write(LONG1 + chr(n) + bytes)
+            else:
+                self.write(LONG4 + pack("<i", n) + bytes)
+            return
+        self.write(LONG + repr(obj) + '\n')
+    dispatch[LongType] = save_long
+
+    def save_float(self, obj, pack=struct.pack):
+        if self.bin:
+            self.write(BINFLOAT + pack('>d', obj))
+        else:
+            self.write(FLOAT + repr(obj) + '\n')
+    dispatch[FloatType] = save_float
+
+    def save_string(self, obj, pack=struct.pack):
+        if self.bin:
+            n = len(obj)
+            if n < 256:
+                self.write(SHORT_BINSTRING + chr(n) + obj)
+            else:
+                self.write(BINSTRING + pack("<i", n) + obj)
+        else:
+            self.write(STRING + repr(obj) + '\n')
+        self.memoize(obj)
+    dispatch[StringType] = save_string
+
+    def save_unicode(self, obj, pack=struct.pack):
+        if self.bin:
+            encoding = obj.encode('utf-8')
+            n = len(encoding)
+            self.write(BINUNICODE + pack("<i", n) + encoding)
+        else:
+            obj = obj.replace("\\", "\\u005c")
+            obj = obj.replace("\n", "\\u000a")
+            self.write(UNICODE + obj.encode('raw-unicode-escape') + '\n')
+        self.memoize(obj)
+    dispatch[UnicodeType] = save_unicode
+
+    if StringType == UnicodeType:
+        # This is true for Jython
+        def save_string(self, obj, pack=struct.pack):
+            unicode = obj.isunicode()
+
+            if self.bin:
+                if unicode:
+                    obj = obj.encode("utf-8")
+                l = len(obj)
+                if l < 256 and not unicode:
+                    self.write(SHORT_BINSTRING + chr(l) + obj)
+                else:
+                    s = pack("<i", l)
+                    if unicode:
+                        self.write(BINUNICODE + s + obj)
+                    else:
+                        self.write(BINSTRING + s + obj)
+            else:
+                if unicode:
+                    obj = obj.replace("\\", "\\u005c")
+                    obj = obj.replace("\n", "\\u000a")
+                    obj = obj.encode('raw-unicode-escape')
+                    self.write(UNICODE + obj + '\n')
+                else:
+                    self.write(STRING + repr(obj) + '\n')
+            self.memoize(obj)
+        dispatch[StringType] = save_string
+
+    def save_tuple(self, obj):
+        write = self.write
+        proto = self.proto
+
+        n = len(obj)
+        if n == 0:
+            if proto:
+                write(EMPTY_TUPLE)
+            else:
+                write(MARK + TUPLE)
+            return
+
+        save = self.save
+        memo = self.memo
+        if n <= 3 and proto >= 2:
+            for element in obj:
+                save(element)
+            # Subtle.  Same as in the big comment below.
+            if id(obj) in memo:
+                get = self.get(memo[id(obj)][0])
+                write(POP * n + get)
+            else:
+                write(_tuplesize2code[n])
+                self.memoize(obj)
+            return
+
+        # proto 0 or proto 1 and tuple isn't empty, or proto > 1 and tuple
+        # has more than 3 elements.
+        write(MARK)
+        for element in obj:
+            save(element)
+
+        if id(obj) in memo:
+            # Subtle.  d was not in memo when we entered save_tuple(), so
+            # the process of saving the tuple's elements must have saved
+            # the tuple itself:  the tuple is recursive.  The proper action
+            # now is to throw away everything we put on the stack, and
+            # simply GET the tuple (it's already constructed).  This check
+            # could have been done in the "for element" loop instead, but
+            # recursive tuples are a rare thing.
+            get = self.get(memo[id(obj)][0])
+            if proto:
+                write(POP_MARK + get)
+            else:   # proto 0 -- POP_MARK not available
+                write(POP * (n+1) + get)
+            return
+
+        # No recursion.
+        self.write(TUPLE)
+        self.memoize(obj)
+
+    dispatch[TupleType] = save_tuple
+
+    # save_empty_tuple() isn't used by anything in Python 2.3.  However, I
+    # found a Pickler subclass in Zope3 that calls it, so it's not harmless
+    # to remove it.
+    def save_empty_tuple(self, obj):
+        self.write(EMPTY_TUPLE)
+
+    def save_list(self, obj):
+        write = self.write
+
+        if self.bin:
+            write(EMPTY_LIST)
+        else:   # proto 0 -- can't use EMPTY_LIST
+            write(MARK + LIST)
+
+        self.memoize(obj)
+        self._batch_appends(iter(obj))
+
+    dispatch[ListType] = save_list
+
+    # Keep in synch with cPickle's BATCHSIZE.  Nothing will break if it gets
+    # out of synch, though.
+    _BATCHSIZE = 1000
+
+    def _batch_appends(self, items):
+        # Helper to batch up APPENDS sequences
+        save = self.save
+        write = self.write
+
+        if not self.bin:
+            for x in items:
+                save(x)
+                write(APPEND)
+            return
+
+        r = xrange(self._BATCHSIZE)
+        while items is not None:
+            tmp = []
+            for i in r:
+                try:
+                    x = items.next()
+                    tmp.append(x)
+                except StopIteration:
+                    items = None
+                    break
+            n = len(tmp)
+            if n > 1:
+                write(MARK)
+                for x in tmp:
+                    save(x)
+                write(APPENDS)
+            elif n:
+                save(tmp[0])
+                write(APPEND)
+            # else tmp is empty, and we're done
+
+    def save_dict(self, obj):
+        write = self.write
+
+        if self.bin:
+            write(EMPTY_DICT)
+        else:   # proto 0 -- can't use EMPTY_DICT
+            write(MARK + DICT)
+
+        self.memoize(obj)
+        self._batch_setitems(obj.iteritems())
+
+    dispatch[DictionaryType] = save_dict
+    if not PyStringMap is None:
+        dispatch[PyStringMap] = save_dict
+
+    def _batch_setitems(self, items):
+        # Helper to batch up SETITEMS sequences; proto >= 1 only
+        save = self.save
+        write = self.write
+
+        if not self.bin:
+            for k, v in items:
+                save(k)
+                save(v)
+                write(SETITEM)
+            return
+
+        r = xrange(self._BATCHSIZE)
+        while items is not None:
+            tmp = []
+            for i in r:
+                try:
+                    tmp.append(items.next())
+                except StopIteration:
+                    items = None
+                    break
+            n = len(tmp)
+            if n > 1:
+                write(MARK)
+                for k, v in tmp:
+                    save(k)
+                    save(v)
+                write(SETITEMS)
+            elif n:
+                k, v = tmp[0]
+                save(k)
+                save(v)
+                write(SETITEM)
+            # else tmp is empty, and we're done
+
+    def save_inst(self, obj):
+        cls = obj.__class__
+
+        memo  = self.memo
+        write = self.write
+        save  = self.save
+
+        if hasattr(obj, '__getinitargs__'):
+            args = obj.__getinitargs__()
+            len(args) # XXX Assert it's a sequence
+            _keep_alive(args, memo)
+        else:
+            args = ()
+
+        write(MARK)
+
+        if self.bin:
+            save(cls)
+            for arg in args:
+                save(arg)
+            write(OBJ)
+        else:
+            for arg in args:
+                save(arg)
+            write(INST + cls.__module__ + '\n' + cls.__name__ + '\n')
+
+        self.memoize(obj)
+
+        try:
+            getstate = obj.__getstate__
+        except AttributeError:
+            stuff = obj.__dict__
+        else:
+            stuff = getstate()
+            _keep_alive(stuff, memo)
+        save(stuff)
+        write(BUILD)
+
+    dispatch[InstanceType] = save_inst
+
+    def save_global(self, obj, name=None, pack=struct.pack):
+        write = self.write
+        memo = self.memo
+
+        if name is None:
+            name = obj.__name__
+
+        module = getattr(obj, "__module__", None)
+        if module is None:
+            module = whichmodule(obj, name)
+
+        try:
+            __import__(module)
+            mod = sys.modules[module]
+            klass = getattr(mod, name)
+        except (ImportError, KeyError, AttributeError):
+            raise PicklingError(
+                "Can't pickle %r: it's not found as %s.%s" %
+                (obj, module, name))
+        else:
+            if klass is not obj:
+                raise PicklingError(
+                    "Can't pickle %r: it's not the same object as %s.%s" %
+                    (obj, module, name))
+
+        if self.proto >= 2:
+            code = _extension_registry.get((module, name))
+            if code:
+                assert code > 0
+                if code <= 0xff:
+                    write(EXT1 + chr(code))
+                elif code <= 0xffff:
+                    write("%c%c%c" % (EXT2, code&0xff, code>>8))
+                else:
+                    write(EXT4 + pack("<i", code))
+                return
+
+        write(GLOBAL + module + '\n' + name + '\n')
+        self.memoize(obj)
+
+    dispatch[ClassType] = save_global
+    dispatch[FunctionType] = save_global
+    dispatch[BuiltinFunctionType] = save_global
+    dispatch[TypeType] = save_global
+
+# Pickling helpers
+
+def _keep_alive(x, memo):
+    """Keeps a reference to the object x in the memo.
+
+    Because we remember objects by their id, we have
+    to assure that possibly temporary objects are kept
+    alive by referencing them.
+    We store a reference at the id of the memo, which should
+    normally not be used unless someone tries to deepcopy
+    the memo itself...
+    """
+    try:
+        memo[id(memo)].append(x)
+    except KeyError:
+        # aha, this is the first one :-)
+        memo[id(memo)]=[x]
+
+
+# A cache for whichmodule(), mapping a function object to the name of
+# the module in which the function was found.
+
+classmap = {} # called classmap for backwards compatibility
+
+def whichmodule(func, funcname):
+    """Figure out the module in which a function occurs.
+
+    Search sys.modules for the module.
+    Cache in classmap.
+    Return a module name.
+    If the function cannot be found, return "__main__".
+    """
+    # Python functions should always get an __module__ from their globals.
+    mod = getattr(func, "__module__", None)
+    if mod is not None:
+        return mod
+    if func in classmap:
+        return classmap[func]
+
+    for name, module in sys.modules.items():
+        if module is None:
+            continue # skip dummy package entries
+        if name != '__main__' and getattr(module, funcname, None) is func:
+            break
+    else:
+        name = '__main__'
+    classmap[func] = name
+    return name
+
+
+# Unpickling machinery
+
+class Unpickler:
+
+    def __init__(self, file):
+        """This takes a file-like object for reading a pickle data stream.
+
+        The protocol version of the pickle is detected automatically, so no
+        proto argument is needed.
+
+        The file-like object must have two methods, a read() method that
+        takes an integer argument, and a readline() method that requires no
+        arguments.  Both methods should return a string.  Thus file-like
+        object can be a file object opened for reading, a StringIO object,
+        or any other custom object that meets this interface.
+        """
+        self.readline = file.readline
+        self.read = file.read
+        self.memo = {}
+
+    def load(self):
+        """Read a pickled object representation from the open file.
+
+        Return the reconstituted object hierarchy specified in the file.
+        """
+        self.mark = object() # any new unique object
+        self.stack = []
+        self.append = self.stack.append
+        read = self.read
+        dispatch = self.dispatch
+        try:
+            while 1:
+                key = read(1)
+                dispatch[key](self)
+        except _Stop, stopinst:
+            return stopinst.value
+
+    # Return largest index k such that self.stack[k] is self.mark.
+    # If the stack doesn't contain a mark, eventually raises IndexError.
+    # This could be sped by maintaining another stack, of indices at which
+    # the mark appears.  For that matter, the latter stack would suffice,
+    # and we wouldn't need to push mark objects on self.stack at all.
+    # Doing so is probably a good thing, though, since if the pickle is
+    # corrupt (or hostile) we may get a clue from finding self.mark embedded
+    # in unpickled objects.
+    def marker(self):
+        stack = self.stack
+        mark = self.mark
+        k = len(stack)-1
+        while stack[k] is not mark: k = k-1
+        return k
+
+    dispatch = {}
+
+    def load_eof(self):
+        raise EOFError
+    dispatch[''] = load_eof
+
+    def load_proto(self):
+        proto = ord(self.read(1))
+        if not 0 <= proto <= 2:
+            raise ValueError, "unsupported pickle protocol: %d" % proto
+    dispatch[PROTO] = load_proto
+
+    def load_persid(self):
+        pid = self.readline()[:-1]
+        self.append(self.persistent_load(pid))
+    dispatch[PERSID] = load_persid
+
+    def load_binpersid(self):
+        pid = self.stack.pop()
+        self.append(self.persistent_load(pid))
+    dispatch[BINPERSID] = load_binpersid
+
+    def load_none(self):
+        self.append(None)
+    dispatch[NONE] = load_none
+
+    def load_false(self):
+        self.append(False)
+    dispatch[NEWFALSE] = load_false
+
+    def load_true(self):
+        self.append(True)
+    dispatch[NEWTRUE] = load_true
+
+    def load_int(self):
+        data = self.readline()
+        if data == FALSE[1:]:
+            val = False
+        elif data == TRUE[1:]:
+            val = True
+        else:
+            try:
+                val = int(data)
+            except ValueError:
+                val = long(data)
+        self.append(val)
+    dispatch[INT] = load_int
+
+    def load_binint(self):
+        self.append(mloads('i' + self.read(4)))
+    dispatch[BININT] = load_binint
+
+    def load_binint1(self):
+        self.append(ord(self.read(1)))
+    dispatch[BININT1] = load_binint1
+
+    def load_binint2(self):
+        self.append(mloads('i' + self.read(2) + '\000\000'))
+    dispatch[BININT2] = load_binint2
+
+    def load_long(self):
+        self.append(long(self.readline()[:-1], 0))
+    dispatch[LONG] = load_long
+
+    def load_long1(self):
+        n = ord(self.read(1))
+        bytes = self.read(n)
+        self.append(decode_long(bytes))
+    dispatch[LONG1] = load_long1
+
+    def load_long4(self):
+        n = mloads('i' + self.read(4))
+        bytes = self.read(n)
+        self.append(decode_long(bytes))
+    dispatch[LONG4] = load_long4
+
+    def load_float(self):
+        self.append(float(self.readline()[:-1]))
+    dispatch[FLOAT] = load_float
+
+    def load_binfloat(self, unpack=struct.unpack):
+        self.append(unpack('>d', self.read(8))[0])
+    dispatch[BINFLOAT] = load_binfloat
+
+    def load_string(self):
+        rep = self.readline()[:-1]
+        for q in "\"'": # double or single quote
+            if rep.startswith(q):
+                if not rep.endswith(q):
+                    raise ValueError, "insecure string pickle"
+                rep = rep[len(q):-len(q)]
+                break
+        else:
+            raise ValueError, "insecure string pickle"
+        self.append(rep.decode("string-escape"))
+    dispatch[STRING] = load_string
+
+    def load_binstring(self):
+        len = mloads('i' + self.read(4))
+        self.append(self.read(len))
+    dispatch[BINSTRING] = load_binstring
+
+    def load_unicode(self):
+        self.append(unicode(self.readline()[:-1],'raw-unicode-escape'))
+    dispatch[UNICODE] = load_unicode
+
+    def load_binunicode(self):
+        len = mloads('i' + self.read(4))
+        self.append(unicode(self.read(len),'utf-8'))
+    dispatch[BINUNICODE] = load_binunicode
+
+    def load_short_binstring(self):
+        len = ord(self.read(1))
+        self.append(self.read(len))
+    dispatch[SHORT_BINSTRING] = load_short_binstring
+
+    def load_tuple(self):
+        k = self.marker()
+        self.stack[k:] = [tuple(self.stack[k+1:])]
+    dispatch[TUPLE] = load_tuple
+
+    def load_empty_tuple(self):
+        self.stack.append(())
+    dispatch[EMPTY_TUPLE] = load_empty_tuple
+
+    def load_tuple1(self):
+        self.stack[-1] = (self.stack[-1],)
+    dispatch[TUPLE1] = load_tuple1
+
+    def load_tuple2(self):
+        self.stack[-2:] = [(self.stack[-2], self.stack[-1])]
+    dispatch[TUPLE2] = load_tuple2
+
+    def load_tuple3(self):
+        self.stack[-3:] = [(self.stack[-3], self.stack[-2], self.stack[-1])]
+    dispatch[TUPLE3] = load_tuple3
+
+    def load_empty_list(self):
+        self.stack.append([])
+    dispatch[EMPTY_LIST] = load_empty_list
+
+    def load_empty_dictionary(self):
+        self.stack.append({})
+    dispatch[EMPTY_DICT] = load_empty_dictionary
+
+    def load_list(self):
+        k = self.marker()
+        self.stack[k:] = [self.stack[k+1:]]
+    dispatch[LIST] = load_list
+
+    def load_dict(self):
+        k = self.marker()
+        d = {}
+        items = self.stack[k+1:]
+        for i in range(0, len(items), 2):
+            key = items[i]
+            value = items[i+1]
+            d[key] = value
+        self.stack[k:] = [d]
+    dispatch[DICT] = load_dict
+
+    # INST and OBJ differ only in how they get a class object.  It's not
+    # only sensible to do the rest in a common routine, the two routines
+    # previously diverged and grew different bugs.
+    # klass is the class to instantiate, and k points to the topmost mark
+    # object, following which are the arguments for klass.__init__.
+    def _instantiate(self, klass, k):
+        args = tuple(self.stack[k+1:])
+        del self.stack[k:]
+        instantiated = 0
+        if (not args and
+                type(klass) is ClassType and
+                not hasattr(klass, "__getinitargs__")):
+            try:
+                value = _EmptyClass()
+                value.__class__ = klass
+                instantiated = 1
+            except RuntimeError:
+                # In restricted execution, assignment to inst.__class__ is
+                # prohibited
+                pass
+        if not instantiated:
+            try:
+                value = klass(*args)
+            except TypeError, err:
+                raise TypeError, "in constructor for %s: %s" % (
+                    klass.__name__, str(err)), sys.exc_info()[2]
+        self.append(value)
+
+    def load_inst(self):
+        module = self.readline()[:-1]
+        name = self.readline()[:-1]
+        klass = self.find_class(module, name)
+        self._instantiate(klass, self.marker())
+    dispatch[INST] = load_inst
+
+    def load_obj(self):
+        # Stack is ... markobject classobject arg1 arg2 ...
+        k = self.marker()
+        klass = self.stack.pop(k+1)
+        self._instantiate(klass, k)
+    dispatch[OBJ] = load_obj
+
+    def load_newobj(self):
+        args = self.stack.pop()
+        cls = self.stack[-1]
+        obj = cls.__new__(cls, *args)
+        self.stack[-1] = obj
+    dispatch[NEWOBJ] = load_newobj
+
+    def load_global(self):
+        module = self.readline()[:-1]
+        name = self.readline()[:-1]
+        klass = self.find_class(module, name)
+        self.append(klass)
+    dispatch[GLOBAL] = load_global
+
+    def load_ext1(self):
+        code = ord(self.read(1))
+        self.get_extension(code)
+    dispatch[EXT1] = load_ext1
+
+    def load_ext2(self):
+        code = mloads('i' + self.read(2) + '\000\000')
+        self.get_extension(code)
+    dispatch[EXT2] = load_ext2
+
+    def load_ext4(self):
+        code = mloads('i' + self.read(4))
+        self.get_extension(code)
+    dispatch[EXT4] = load_ext4
+
+    def get_extension(self, code):
+        nil = []
+        obj = _extension_cache.get(code, nil)
+        if obj is not nil:
+            self.append(obj)
+            return
+        key = _inverted_registry.get(code)
+        if not key:
+            raise ValueError("unregistered extension code %d" % code)
+        obj = self.find_class(*key)
+        _extension_cache[code] = obj
+        self.append(obj)
+
+    def find_class(self, module, name):
+        # Subclasses may override this
+        __import__(module)
+        mod = sys.modules[module]
+        klass = getattr(mod, name)
+        return klass
+
+    def load_reduce(self):
+        stack = self.stack
+        args = stack.pop()
+        func = stack[-1]
+        value = func(*args)
+        stack[-1] = value
+    dispatch[REDUCE] = load_reduce
+
+    def load_pop(self):
+        del self.stack[-1]
+    dispatch[POP] = load_pop
+
+    def load_pop_mark(self):
+        k = self.marker()
+        del self.stack[k:]
+    dispatch[POP_MARK] = load_pop_mark
+
+    def load_dup(self):
+        self.append(self.stack[-1])
+    dispatch[DUP] = load_dup
+
+    def load_get(self):
+        self.append(self.memo[self.readline()[:-1]])
+    dispatch[GET] = load_get
+
+    def load_binget(self):
+        i = ord(self.read(1))
+        self.append(self.memo[repr(i)])
+    dispatch[BINGET] = load_binget
+
+    def load_long_binget(self):
+        i = mloads('i' + self.read(4))
+        self.append(self.memo[repr(i)])
+    dispatch[LONG_BINGET] = load_long_binget
+
+    def load_put(self):
+        self.memo[self.readline()[:-1]] = self.stack[-1]
+    dispatch[PUT] = load_put
+
+    def load_binput(self):
+        i = ord(self.read(1))
+        self.memo[repr(i)] = self.stack[-1]
+    dispatch[BINPUT] = load_binput
+
+    def load_long_binput(self):
+        i = mloads('i' + self.read(4))
+        self.memo[repr(i)] = self.stack[-1]
+    dispatch[LONG_BINPUT] = load_long_binput
+
+    def load_append(self):
+        stack = self.stack
+        value = stack.pop()
+        list = stack[-1]
+        list.append(value)
+    dispatch[APPEND] = load_append
+
+    def load_appends(self):
+        stack = self.stack
+        mark = self.marker()
+        list = stack[mark - 1]
+        list.extend(stack[mark + 1:])
+        del stack[mark:]
+    dispatch[APPENDS] = load_appends
+
+    def load_setitem(self):
+        stack = self.stack
+        value = stack.pop()
+        key = stack.pop()
+        dict = stack[-1]
+        dict[key] = value
+    dispatch[SETITEM] = load_setitem
+
+    def load_setitems(self):
+        stack = self.stack
+        mark = self.marker()
+        dict = stack[mark - 1]
+        for i in range(mark + 1, len(stack), 2):
+            dict[stack[i]] = stack[i + 1]
+
+        del stack[mark:]
+    dispatch[SETITEMS] = load_setitems
+
+    def load_build(self):
+        stack = self.stack
+        state = stack.pop()
+        inst = stack[-1]
+        setstate = getattr(inst, "__setstate__", None)
+        if setstate:
+            setstate(state)
+            return
+        slotstate = None
+        if isinstance(state, tuple) and len(state) == 2:
+            state, slotstate = state
+        if state:
+            try:
+                inst.__dict__.update(state)
+            except RuntimeError:
+                # XXX In restricted execution, the instance's __dict__
+                # is not accessible.  Use the old way of unpickling
+                # the instance variables.  This is a semantic
+                # difference when unpickling in restricted
+                # vs. unrestricted modes.
+                # Note, however, that cPickle has never tried to do the
+                # .update() business, and always uses
+                #     PyObject_SetItem(inst.__dict__, key, value) in a
+                # loop over state.items().
+                for k, v in state.items():
+                    setattr(inst, k, v)
+        if slotstate:
+            for k, v in slotstate.items():
+                setattr(inst, k, v)
+    dispatch[BUILD] = load_build
+
+    def load_mark(self):
+        self.append(self.mark)
+    dispatch[MARK] = load_mark
+
+    def load_stop(self):
+        value = self.stack.pop()
+        raise _Stop(value)
+    dispatch[STOP] = load_stop
+
+# Helper class for load_inst/load_obj
+
+class _EmptyClass:
+    pass
+
+# Encode/decode longs in linear time.
+
+import binascii as _binascii
+
+def encode_long(x):
+    r"""Encode a long to a two's complement little-endian binary string.
+    Note that 0L is a special case, returning an empty string, to save a
+    byte in the LONG1 pickling context.
+
+    >>> encode_long(0L)
+    ''
+    >>> encode_long(255L)
+    '\xff\x00'
+    >>> encode_long(32767L)
+    '\xff\x7f'
+    >>> encode_long(-256L)
+    '\x00\xff'
+    >>> encode_long(-32768L)
+    '\x00\x80'
+    >>> encode_long(-128L)
+    '\x80'
+    >>> encode_long(127L)
+    '\x7f'
+    >>>
+    """
+
+    if x == 0:
+        return ''
+    if x > 0:
+        ashex = hex(x)
+        assert ashex.startswith("0x")
+        njunkchars = 2 + ashex.endswith('L')
+        nibbles = len(ashex) - njunkchars
+        if nibbles & 1:
+            # need an even # of nibbles for unhexlify
+            ashex = "0x0" + ashex[2:]
+        elif int(ashex[2], 16) >= 8:
+            # "looks negative", so need a byte of sign bits
+            ashex = "0x00" + ashex[2:]
+    else:
+        # Build the 256's-complement:  (1L << nbytes) + x.  The trick is
+        # to find the number of bytes in linear time (although that should
+        # really be a constant-time task).
+        ashex = hex(-x)
+        assert ashex.startswith("0x")
+        njunkchars = 2 + ashex.endswith('L')
+        nibbles = len(ashex) - njunkchars
+        if nibbles & 1:
+            # Extend to a full byte.
+            nibbles += 1
+        nbits = nibbles * 4
+        x += 1L << nbits
+        assert x > 0
+        ashex = hex(x)
+        njunkchars = 2 + ashex.endswith('L')
+        newnibbles = len(ashex) - njunkchars
+        if newnibbles < nibbles:
+            ashex = "0x" + "0" * (nibbles - newnibbles) + ashex[2:]
+        if int(ashex[2], 16) < 8:
+            # "looks positive", so need a byte of sign bits
+            ashex = "0xff" + ashex[2:]
+
+    if ashex.endswith('L'):
+        ashex = ashex[2:-1]
+    else:
+        ashex = ashex[2:]
+    assert len(ashex) & 1 == 0, (x, ashex)
+    binary = _binascii.unhexlify(ashex)
+    return binary[::-1]
+
+def decode_long(data):
+    r"""Decode a long from a two's complement little-endian binary string.
+
+    >>> decode_long('')
+    0L
+    >>> decode_long("\xff\x00")
+    255L
+    >>> decode_long("\xff\x7f")
+    32767L
+    >>> decode_long("\x00\xff")
+    -256L
+    >>> decode_long("\x00\x80")
+    -32768L
+    >>> decode_long("\x80")
+    -128L
+    >>> decode_long("\x7f")
+    127L
+    """
+
+    nbytes = len(data)
+    if nbytes == 0:
+        return 0L
+    ashex = _binascii.hexlify(data[::-1])
+    n = long(ashex, 16) # quadratic time before Python 2.3; linear now
+    if data[-1] >= '\x80':
+        n -= 1L << (nbytes * 8)
+    return n
+
+# Shorthands
+
+try:
+    from cStringIO import StringIO
+except ImportError:
+    from StringIO import StringIO
+
+def dump(obj, file, protocol=None):
+    Pickler(file, protocol).dump(obj)
+
+def dumps(obj, protocol=None):
+    file = StringIO()
+    Pickler(file, protocol).dump(obj)
+    return file.getvalue()
+
+def load(file):
+    return Unpickler(file).load()
+
+def loads(str):
+    file = StringIO(str)
+    return Unpickler(file).load()
+
+# Doctest
+
+def _test():
+    import doctest
+    return doctest.testmod()
+
+if __name__ == "__main__":
+    _test()

Added: vendor/Python/current/Lib/pickletools.py
===================================================================
--- vendor/Python/current/Lib/pickletools.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/pickletools.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2246 @@
+'''"Executable documentation" for the pickle module.
+
+Extensive comments about the pickle protocols and pickle-machine opcodes
+can be found here.  Some functions meant for external use:
+
+genops(pickle)
+   Generate all the opcodes in a pickle, as (opcode, arg, position) triples.
+
+dis(pickle, out=None, memo=None, indentlevel=4)
+   Print a symbolic disassembly of a pickle.
+'''
+
+__all__ = ['dis',
+           'genops',
+          ]
+
+# Other ideas:
+#
+# - A pickle verifier:  read a pickle and check it exhaustively for
+#   well-formedness.  dis() does a lot of this already.
+#
+# - A protocol identifier:  examine a pickle and return its protocol number
+#   (== the highest .proto attr value among all the opcodes in the pickle).
+#   dis() already prints this info at the end.
+#
+# - A pickle optimizer:  for example, tuple-building code is sometimes more
+#   elaborate than necessary, catering for the possibility that the tuple
+#   is recursive.  Or lots of times a PUT is generated that's never accessed
+#   by a later GET.
+
+
+"""
+"A pickle" is a program for a virtual pickle machine (PM, but more accurately
+called an unpickling machine).  It's a sequence of opcodes, interpreted by the
+PM, building an arbitrarily complex Python object.
+
+For the most part, the PM is very simple:  there are no looping, testing, or
+conditional instructions, no arithmetic and no function calls.  Opcodes are
+executed once each, from first to last, until a STOP opcode is reached.
+
+The PM has two data areas, "the stack" and "the memo".
+
+Many opcodes push Python objects onto the stack; e.g., INT pushes a Python
+integer object on the stack, whose value is gotten from a decimal string
+literal immediately following the INT opcode in the pickle bytestream.  Other
+opcodes take Python objects off the stack.  The result of unpickling is
+whatever object is left on the stack when the final STOP opcode is executed.
+
+The memo is simply an array of objects, or it can be implemented as a dict
+mapping little integers to objects.  The memo serves as the PM's "long term
+memory", and the little integers indexing the memo are akin to variable
+names.  Some opcodes pop a stack object into the memo at a given index,
+and others push a memo object at a given index onto the stack again.
+
+At heart, that's all the PM has.  Subtleties arise for these reasons:
+
++ Object identity.  Objects can be arbitrarily complex, and subobjects
+  may be shared (for example, the list [a, a] refers to the same object a
+  twice).  It can be vital that unpickling recreate an isomorphic object
+  graph, faithfully reproducing sharing.
+
++ Recursive objects.  For example, after "L = []; L.append(L)", L is a
+  list, and L[0] is the same list.  This is related to the object identity
+  point, and some sequences of pickle opcodes are subtle in order to
+  get the right result in all cases.
+
++ Things pickle doesn't know everything about.  Examples of things pickle
+  does know everything about are Python's builtin scalar and container
+  types, like ints and tuples.  They generally have opcodes dedicated to
+  them.  For things like module references and instances of user-defined
+  classes, pickle's knowledge is limited.  Historically, many enhancements
+  have been made to the pickle protocol in order to do a better (faster,
+  and/or more compact) job on those.
+
++ Backward compatibility and micro-optimization.  As explained below,
+  pickle opcodes never go away, not even when better ways to do a thing
+  get invented.  The repertoire of the PM just keeps growing over time.
+  For example, protocol 0 had two opcodes for building Python integers (INT
+  and LONG), protocol 1 added three more for more-efficient pickling of short
+  integers, and protocol 2 added two more for more-efficient pickling of
+  long integers (before protocol 2, the only ways to pickle a Python long
+  took time quadratic in the number of digits, for both pickling and
+  unpickling).  "Opcode bloat" isn't so much a subtlety as a source of
+  wearying complication.
+
+
+Pickle protocols:
+
+For compatibility, the meaning of a pickle opcode never changes.  Instead new
+pickle opcodes get added, and each version's unpickler can handle all the
+pickle opcodes in all protocol versions to date.  So old pickles continue to
+be readable forever.  The pickler can generally be told to restrict itself to
+the subset of opcodes available under previous protocol versions too, so that
+users can create pickles under the current version readable by older
+versions.  However, a pickle does not contain its version number embedded
+within it.  If an older unpickler tries to read a pickle using a later
+protocol, the result is most likely an exception due to seeing an unknown (in
+the older unpickler) opcode.
+
+The original pickle used what's now called "protocol 0", and what was called
+"text mode" before Python 2.3.  The entire pickle bytestream is made up of
+printable 7-bit ASCII characters, plus the newline character, in protocol 0.
+That's why it was called text mode.  Protocol 0 is small and elegant, but
+sometimes painfully inefficient.
+
+The second major set of additions is now called "protocol 1", and was called
+"binary mode" before Python 2.3.  This added many opcodes with arguments
+consisting of arbitrary bytes, including NUL bytes and unprintable "high bit"
+bytes.  Binary mode pickles can be substantially smaller than equivalent
+text mode pickles, and sometimes faster too; e.g., BININT represents a 4-byte
+int as 4 bytes following the opcode, which is cheaper to unpickle than the
+(perhaps) 11-character decimal string attached to INT.  Protocol 1 also added
+a number of opcodes that operate on many stack elements at once (like APPENDS
+and SETITEMS), and "shortcut" opcodes (like EMPTY_DICT and EMPTY_TUPLE).
+
+The third major set of additions came in Python 2.3, and is called "protocol
+2".  This added:
+
+- A better way to pickle instances of new-style classes (NEWOBJ).
+
+- A way for a pickle to identify its protocol (PROTO).
+
+- Time- and space- efficient pickling of long ints (LONG{1,4}).
+
+- Shortcuts for small tuples (TUPLE{1,2,3}}.
+
+- Dedicated opcodes for bools (NEWTRUE, NEWFALSE).
+
+- The "extension registry", a vector of popular objects that can be pushed
+  efficiently by index (EXT{1,2,4}).  This is akin to the memo and GET, but
+  the registry contents are predefined (there's nothing akin to the memo's
+  PUT).
+
+Another independent change with Python 2.3 is the abandonment of any
+pretense that it might be safe to load pickles received from untrusted
+parties -- no sufficient security analysis has been done to guarantee
+this and there isn't a use case that warrants the expense of such an
+analysis.
+
+To this end, all tests for __safe_for_unpickling__ or for
+copy_reg.safe_constructors are removed from the unpickling code.
+References to these variables in the descriptions below are to be seen
+as describing unpickling in Python 2.2 and before.
+"""
+
+# Meta-rule:  Descriptions are stored in instances of descriptor objects,
+# with plain constructors.  No meta-language is defined from which
+# descriptors could be constructed.  If you want, e.g., XML, write a little
+# program to generate XML from the objects.
+
+##############################################################################
+# Some pickle opcodes have an argument, following the opcode in the
+# bytestream.  An argument is of a specific type, described by an instance
+# of ArgumentDescriptor.  These are not to be confused with arguments taken
+# off the stack -- ArgumentDescriptor applies only to arguments embedded in
+# the opcode stream, immediately following an opcode.
+
+# Represents the number of bytes consumed by an argument delimited by the
+# next newline character.
+UP_TO_NEWLINE = -1
+
+# Represents the number of bytes consumed by a two-argument opcode where
+# the first argument gives the number of bytes in the second argument.
+TAKEN_FROM_ARGUMENT1 = -2   # num bytes is 1-byte unsigned int
+TAKEN_FROM_ARGUMENT4 = -3   # num bytes is 4-byte signed little-endian int
+
+class ArgumentDescriptor(object):
+    __slots__ = (
+        # name of descriptor record, also a module global name; a string
+        'name',
+
+        # length of argument, in bytes; an int; UP_TO_NEWLINE and
+        # TAKEN_FROM_ARGUMENT{1,4} are negative values for variable-length
+        # cases
+        'n',
+
+        # a function taking a file-like object, reading this kind of argument
+        # from the object at the current position, advancing the current
+        # position by n bytes, and returning the value of the argument
+        'reader',
+
+        # human-readable docs for this arg descriptor; a string
+        'doc',
+    )
+
+    def __init__(self, name, n, reader, doc):
+        assert isinstance(name, str)
+        self.name = name
+
+        assert isinstance(n, int) and (n >= 0 or
+                                       n in (UP_TO_NEWLINE,
+                                             TAKEN_FROM_ARGUMENT1,
+                                             TAKEN_FROM_ARGUMENT4))
+        self.n = n
+
+        self.reader = reader
+
+        assert isinstance(doc, str)
+        self.doc = doc
+
+from struct import unpack as _unpack
+
+def read_uint1(f):
+    r"""
+    >>> import StringIO
+    >>> read_uint1(StringIO.StringIO('\xff'))
+    255
+    """
+
+    data = f.read(1)
+    if data:
+        return ord(data)
+    raise ValueError("not enough data in stream to read uint1")
+
+uint1 = ArgumentDescriptor(
+            name='uint1',
+            n=1,
+            reader=read_uint1,
+            doc="One-byte unsigned integer.")
+
+
+def read_uint2(f):
+    r"""
+    >>> import StringIO
+    >>> read_uint2(StringIO.StringIO('\xff\x00'))
+    255
+    >>> read_uint2(StringIO.StringIO('\xff\xff'))
+    65535
+    """
+
+    data = f.read(2)
+    if len(data) == 2:
+        return _unpack("<H", data)[0]
+    raise ValueError("not enough data in stream to read uint2")
+
+uint2 = ArgumentDescriptor(
+            name='uint2',
+            n=2,
+            reader=read_uint2,
+            doc="Two-byte unsigned integer, little-endian.")
+
+
+def read_int4(f):
+    r"""
+    >>> import StringIO
+    >>> read_int4(StringIO.StringIO('\xff\x00\x00\x00'))
+    255
+    >>> read_int4(StringIO.StringIO('\x00\x00\x00\x80')) == -(2**31)
+    True
+    """
+
+    data = f.read(4)
+    if len(data) == 4:
+        return _unpack("<i", data)[0]
+    raise ValueError("not enough data in stream to read int4")
+
+int4 = ArgumentDescriptor(
+           name='int4',
+           n=4,
+           reader=read_int4,
+           doc="Four-byte signed integer, little-endian, 2's complement.")
+
+
+def read_stringnl(f, decode=True, stripquotes=True):
+    r"""
+    >>> import StringIO
+    >>> read_stringnl(StringIO.StringIO("'abcd'\nefg\n"))
+    'abcd'
+
+    >>> read_stringnl(StringIO.StringIO("\n"))
+    Traceback (most recent call last):
+    ...
+    ValueError: no string quotes around ''
+
+    >>> read_stringnl(StringIO.StringIO("\n"), stripquotes=False)
+    ''
+
+    >>> read_stringnl(StringIO.StringIO("''\n"))
+    ''
+
+    >>> read_stringnl(StringIO.StringIO('"abcd"'))
+    Traceback (most recent call last):
+    ...
+    ValueError: no newline found when trying to read stringnl
+
+    Embedded escapes are undone in the result.
+    >>> read_stringnl(StringIO.StringIO(r"'a\n\\b\x00c\td'" + "\n'e'"))
+    'a\n\\b\x00c\td'
+    """
+
+    data = f.readline()
+    if not data.endswith('\n'):
+        raise ValueError("no newline found when trying to read stringnl")
+    data = data[:-1]    # lose the newline
+
+    if stripquotes:
+        for q in "'\"":
+            if data.startswith(q):
+                if not data.endswith(q):
+                    raise ValueError("strinq quote %r not found at both "
+                                     "ends of %r" % (q, data))
+                data = data[1:-1]
+                break
+        else:
+            raise ValueError("no string quotes around %r" % data)
+
+    # I'm not sure when 'string_escape' was added to the std codecs; it's
+    # crazy not to use it if it's there.
+    if decode:
+        data = data.decode('string_escape')
+    return data
+
+stringnl = ArgumentDescriptor(
+               name='stringnl',
+               n=UP_TO_NEWLINE,
+               reader=read_stringnl,
+               doc="""A newline-terminated string.
+
+                   This is a repr-style string, with embedded escapes, and
+                   bracketing quotes.
+                   """)
+
+def read_stringnl_noescape(f):
+    return read_stringnl(f, decode=False, stripquotes=False)
+
+stringnl_noescape = ArgumentDescriptor(
+                        name='stringnl_noescape',
+                        n=UP_TO_NEWLINE,
+                        reader=read_stringnl_noescape,
+                        doc="""A newline-terminated string.
+
+                        This is a str-style string, without embedded escapes,
+                        or bracketing quotes.  It should consist solely of
+                        printable ASCII characters.
+                        """)
+
+def read_stringnl_noescape_pair(f):
+    r"""
+    >>> import StringIO
+    >>> read_stringnl_noescape_pair(StringIO.StringIO("Queue\nEmpty\njunk"))
+    'Queue Empty'
+    """
+
+    return "%s %s" % (read_stringnl_noescape(f), read_stringnl_noescape(f))
+
+stringnl_noescape_pair = ArgumentDescriptor(
+                             name='stringnl_noescape_pair',
+                             n=UP_TO_NEWLINE,
+                             reader=read_stringnl_noescape_pair,
+                             doc="""A pair of newline-terminated strings.
+
+                             These are str-style strings, without embedded
+                             escapes, or bracketing quotes.  They should
+                             consist solely of printable ASCII characters.
+                             The pair is returned as a single string, with
+                             a single blank separating the two strings.
+                             """)
+
+def read_string4(f):
+    r"""
+    >>> import StringIO
+    >>> read_string4(StringIO.StringIO("\x00\x00\x00\x00abc"))
+    ''
+    >>> read_string4(StringIO.StringIO("\x03\x00\x00\x00abcdef"))
+    'abc'
+    >>> read_string4(StringIO.StringIO("\x00\x00\x00\x03abcdef"))
+    Traceback (most recent call last):
+    ...
+    ValueError: expected 50331648 bytes in a string4, but only 6 remain
+    """
+
+    n = read_int4(f)
+    if n < 0:
+        raise ValueError("string4 byte count < 0: %d" % n)
+    data = f.read(n)
+    if len(data) == n:
+        return data
+    raise ValueError("expected %d bytes in a string4, but only %d remain" %
+                     (n, len(data)))
+
+string4 = ArgumentDescriptor(
+              name="string4",
+              n=TAKEN_FROM_ARGUMENT4,
+              reader=read_string4,
+              doc="""A counted string.
+
+              The first argument is a 4-byte little-endian signed int giving
+              the number of bytes in the string, and the second argument is
+              that many bytes.
+              """)
+
+
+def read_string1(f):
+    r"""
+    >>> import StringIO
+    >>> read_string1(StringIO.StringIO("\x00"))
+    ''
+    >>> read_string1(StringIO.StringIO("\x03abcdef"))
+    'abc'
+    """
+
+    n = read_uint1(f)
+    assert n >= 0
+    data = f.read(n)
+    if len(data) == n:
+        return data
+    raise ValueError("expected %d bytes in a string1, but only %d remain" %
+                     (n, len(data)))
+
+string1 = ArgumentDescriptor(
+              name="string1",
+              n=TAKEN_FROM_ARGUMENT1,
+              reader=read_string1,
+              doc="""A counted string.
+
+              The first argument is a 1-byte unsigned int giving the number
+              of bytes in the string, and the second argument is that many
+              bytes.
+              """)
+
+
+def read_unicodestringnl(f):
+    r"""
+    >>> import StringIO
+    >>> read_unicodestringnl(StringIO.StringIO("abc\uabcd\njunk"))
+    u'abc\uabcd'
+    """
+
+    data = f.readline()
+    if not data.endswith('\n'):
+        raise ValueError("no newline found when trying to read "
+                         "unicodestringnl")
+    data = data[:-1]    # lose the newline
+    return unicode(data, 'raw-unicode-escape')
+
+unicodestringnl = ArgumentDescriptor(
+                      name='unicodestringnl',
+                      n=UP_TO_NEWLINE,
+                      reader=read_unicodestringnl,
+                      doc="""A newline-terminated Unicode string.
+
+                      This is raw-unicode-escape encoded, so consists of
+                      printable ASCII characters, and may contain embedded
+                      escape sequences.
+                      """)
+
+def read_unicodestring4(f):
+    r"""
+    >>> import StringIO
+    >>> s = u'abcd\uabcd'
+    >>> enc = s.encode('utf-8')
+    >>> enc
+    'abcd\xea\xaf\x8d'
+    >>> n = chr(len(enc)) + chr(0) * 3  # little-endian 4-byte length
+    >>> t = read_unicodestring4(StringIO.StringIO(n + enc + 'junk'))
+    >>> s == t
+    True
+
+    >>> read_unicodestring4(StringIO.StringIO(n + enc[:-1]))
+    Traceback (most recent call last):
+    ...
+    ValueError: expected 7 bytes in a unicodestring4, but only 6 remain
+    """
+
+    n = read_int4(f)
+    if n < 0:
+        raise ValueError("unicodestring4 byte count < 0: %d" % n)
+    data = f.read(n)
+    if len(data) == n:
+        return unicode(data, 'utf-8')
+    raise ValueError("expected %d bytes in a unicodestring4, but only %d "
+                     "remain" % (n, len(data)))
+
+unicodestring4 = ArgumentDescriptor(
+                    name="unicodestring4",
+                    n=TAKEN_FROM_ARGUMENT4,
+                    reader=read_unicodestring4,
+                    doc="""A counted Unicode string.
+
+                    The first argument is a 4-byte little-endian signed int
+                    giving the number of bytes in the string, and the second
+                    argument-- the UTF-8 encoding of the Unicode string --
+                    contains that many bytes.
+                    """)
+
+
+def read_decimalnl_short(f):
+    r"""
+    >>> import StringIO
+    >>> read_decimalnl_short(StringIO.StringIO("1234\n56"))
+    1234
+
+    >>> read_decimalnl_short(StringIO.StringIO("1234L\n56"))
+    Traceback (most recent call last):
+    ...
+    ValueError: trailing 'L' not allowed in '1234L'
+    """
+
+    s = read_stringnl(f, decode=False, stripquotes=False)
+    if s.endswith("L"):
+        raise ValueError("trailing 'L' not allowed in %r" % s)
+
+    # It's not necessarily true that the result fits in a Python short int:
+    # the pickle may have been written on a 64-bit box.  There's also a hack
+    # for True and False here.
+    if s == "00":
+        return False
+    elif s == "01":
+        return True
+
+    try:
+        return int(s)
+    except OverflowError:
+        return long(s)
+
+def read_decimalnl_long(f):
+    r"""
+    >>> import StringIO
+
+    >>> read_decimalnl_long(StringIO.StringIO("1234\n56"))
+    Traceback (most recent call last):
+    ...
+    ValueError: trailing 'L' required in '1234'
+
+    Someday the trailing 'L' will probably go away from this output.
+
+    >>> read_decimalnl_long(StringIO.StringIO("1234L\n56"))
+    1234L
+
+    >>> read_decimalnl_long(StringIO.StringIO("123456789012345678901234L\n6"))
+    123456789012345678901234L
+    """
+
+    s = read_stringnl(f, decode=False, stripquotes=False)
+    if not s.endswith("L"):
+        raise ValueError("trailing 'L' required in %r" % s)
+    return long(s)
+
+
+decimalnl_short = ArgumentDescriptor(
+                      name='decimalnl_short',
+                      n=UP_TO_NEWLINE,
+                      reader=read_decimalnl_short,
+                      doc="""A newline-terminated decimal integer literal.
+
+                          This never has a trailing 'L', and the integer fit
+                          in a short Python int on the box where the pickle
+                          was written -- but there's no guarantee it will fit
+                          in a short Python int on the box where the pickle
+                          is read.
+                          """)
+
+decimalnl_long = ArgumentDescriptor(
+                     name='decimalnl_long',
+                     n=UP_TO_NEWLINE,
+                     reader=read_decimalnl_long,
+                     doc="""A newline-terminated decimal integer literal.
+
+                         This has a trailing 'L', and can represent integers
+                         of any size.
+                         """)
+
+
+def read_floatnl(f):
+    r"""
+    >>> import StringIO
+    >>> read_floatnl(StringIO.StringIO("-1.25\n6"))
+    -1.25
+    """
+    s = read_stringnl(f, decode=False, stripquotes=False)
+    return float(s)
+
+floatnl = ArgumentDescriptor(
+              name='floatnl',
+              n=UP_TO_NEWLINE,
+              reader=read_floatnl,
+              doc="""A newline-terminated decimal floating literal.
+
+              In general this requires 17 significant digits for roundtrip
+              identity, and pickling then unpickling infinities, NaNs, and
+              minus zero doesn't work across boxes, or on some boxes even
+              on itself (e.g., Windows can't read the strings it produces
+              for infinities or NaNs).
+              """)
+
+def read_float8(f):
+    r"""
+    >>> import StringIO, struct
+    >>> raw = struct.pack(">d", -1.25)
+    >>> raw
+    '\xbf\xf4\x00\x00\x00\x00\x00\x00'
+    >>> read_float8(StringIO.StringIO(raw + "\n"))
+    -1.25
+    """
+
+    data = f.read(8)
+    if len(data) == 8:
+        return _unpack(">d", data)[0]
+    raise ValueError("not enough data in stream to read float8")
+
+
+float8 = ArgumentDescriptor(
+             name='float8',
+             n=8,
+             reader=read_float8,
+             doc="""An 8-byte binary representation of a float, big-endian.
+
+             The format is unique to Python, and shared with the struct
+             module (format string '>d') "in theory" (the struct and cPickle
+             implementations don't share the code -- they should).  It's
+             strongly related to the IEEE-754 double format, and, in normal
+             cases, is in fact identical to the big-endian 754 double format.
+             On other boxes the dynamic range is limited to that of a 754
+             double, and "add a half and chop" rounding is used to reduce
+             the precision to 53 bits.  However, even on a 754 box,
+             infinities, NaNs, and minus zero may not be handled correctly
+             (may not survive roundtrip pickling intact).
+             """)
+
+# Protocol 2 formats
+
+from pickle import decode_long
+
+def read_long1(f):
+    r"""
+    >>> import StringIO
+    >>> read_long1(StringIO.StringIO("\x00"))
+    0L
+    >>> read_long1(StringIO.StringIO("\x02\xff\x00"))
+    255L
+    >>> read_long1(StringIO.StringIO("\x02\xff\x7f"))
+    32767L
+    >>> read_long1(StringIO.StringIO("\x02\x00\xff"))
+    -256L
+    >>> read_long1(StringIO.StringIO("\x02\x00\x80"))
+    -32768L
+    """
+
+    n = read_uint1(f)
+    data = f.read(n)
+    if len(data) != n:
+        raise ValueError("not enough data in stream to read long1")
+    return decode_long(data)
+
+long1 = ArgumentDescriptor(
+    name="long1",
+    n=TAKEN_FROM_ARGUMENT1,
+    reader=read_long1,
+    doc="""A binary long, little-endian, using 1-byte size.
+
+    This first reads one byte as an unsigned size, then reads that
+    many bytes and interprets them as a little-endian 2's-complement long.
+    If the size is 0, that's taken as a shortcut for the long 0L.
+    """)
+
+def read_long4(f):
+    r"""
+    >>> import StringIO
+    >>> read_long4(StringIO.StringIO("\x02\x00\x00\x00\xff\x00"))
+    255L
+    >>> read_long4(StringIO.StringIO("\x02\x00\x00\x00\xff\x7f"))
+    32767L
+    >>> read_long4(StringIO.StringIO("\x02\x00\x00\x00\x00\xff"))
+    -256L
+    >>> read_long4(StringIO.StringIO("\x02\x00\x00\x00\x00\x80"))
+    -32768L
+    >>> read_long1(StringIO.StringIO("\x00\x00\x00\x00"))
+    0L
+    """
+
+    n = read_int4(f)
+    if n < 0:
+        raise ValueError("long4 byte count < 0: %d" % n)
+    data = f.read(n)
+    if len(data) != n:
+        raise ValueError("not enough data in stream to read long4")
+    return decode_long(data)
+
+long4 = ArgumentDescriptor(
+    name="long4",
+    n=TAKEN_FROM_ARGUMENT4,
+    reader=read_long4,
+    doc="""A binary representation of a long, little-endian.
+
+    This first reads four bytes as a signed size (but requires the
+    size to be >= 0), then reads that many bytes and interprets them
+    as a little-endian 2's-complement long.  If the size is 0, that's taken
+    as a shortcut for the long 0L, although LONG1 should really be used
+    then instead (and in any case where # of bytes < 256).
+    """)
+
+
+##############################################################################
+# Object descriptors.  The stack used by the pickle machine holds objects,
+# and in the stack_before and stack_after attributes of OpcodeInfo
+# descriptors we need names to describe the various types of objects that can
+# appear on the stack.
+
+class StackObject(object):
+    __slots__ = (
+        # name of descriptor record, for info only
+        'name',
+
+        # type of object, or tuple of type objects (meaning the object can
+        # be of any type in the tuple)
+        'obtype',
+
+        # human-readable docs for this kind of stack object; a string
+        'doc',
+    )
+
+    def __init__(self, name, obtype, doc):
+        assert isinstance(name, str)
+        self.name = name
+
+        assert isinstance(obtype, type) or isinstance(obtype, tuple)
+        if isinstance(obtype, tuple):
+            for contained in obtype:
+                assert isinstance(contained, type)
+        self.obtype = obtype
+
+        assert isinstance(doc, str)
+        self.doc = doc
+
+    def __repr__(self):
+        return self.name
+
+
+pyint = StackObject(
+            name='int',
+            obtype=int,
+            doc="A short (as opposed to long) Python integer object.")
+
+pylong = StackObject(
+             name='long',
+             obtype=long,
+             doc="A long (as opposed to short) Python integer object.")
+
+pyinteger_or_bool = StackObject(
+                        name='int_or_bool',
+                        obtype=(int, long, bool),
+                        doc="A Python integer object (short or long), or "
+                            "a Python bool.")
+
+pybool = StackObject(
+             name='bool',
+             obtype=(bool,),
+             doc="A Python bool object.")
+
+pyfloat = StackObject(
+              name='float',
+              obtype=float,
+              doc="A Python float object.")
+
+pystring = StackObject(
+               name='str',
+               obtype=str,
+               doc="A Python string object.")
+
+pyunicode = StackObject(
+                name='unicode',
+                obtype=unicode,
+                doc="A Python Unicode string object.")
+
+pynone = StackObject(
+             name="None",
+             obtype=type(None),
+             doc="The Python None object.")
+
+pytuple = StackObject(
+              name="tuple",
+              obtype=tuple,
+              doc="A Python tuple object.")
+
+pylist = StackObject(
+             name="list",
+             obtype=list,
+             doc="A Python list object.")
+
+pydict = StackObject(
+             name="dict",
+             obtype=dict,
+             doc="A Python dict object.")
+
+anyobject = StackObject(
+                name='any',
+                obtype=object,
+                doc="Any kind of object whatsoever.")
+
+markobject = StackObject(
+                 name="mark",
+                 obtype=StackObject,
+                 doc="""'The mark' is a unique object.
+
+                 Opcodes that operate on a variable number of objects
+                 generally don't embed the count of objects in the opcode,
+                 or pull it off the stack.  Instead the MARK opcode is used
+                 to push a special marker object on the stack, and then
+                 some other opcodes grab all the objects from the top of
+                 the stack down to (but not including) the topmost marker
+                 object.
+                 """)
+
+stackslice = StackObject(
+                 name="stackslice",
+                 obtype=StackObject,
+                 doc="""An object representing a contiguous slice of the stack.
+
+                 This is used in conjuction with markobject, to represent all
+                 of the stack following the topmost markobject.  For example,
+                 the POP_MARK opcode changes the stack from
+
+                     [..., markobject, stackslice]
+                 to
+                     [...]
+
+                 No matter how many object are on the stack after the topmost
+                 markobject, POP_MARK gets rid of all of them (including the
+                 topmost markobject too).
+                 """)
+
+##############################################################################
+# Descriptors for pickle opcodes.
+
+class OpcodeInfo(object):
+
+    __slots__ = (
+        # symbolic name of opcode; a string
+        'name',
+
+        # the code used in a bytestream to represent the opcode; a
+        # one-character string
+        'code',
+
+        # If the opcode has an argument embedded in the byte string, an
+        # instance of ArgumentDescriptor specifying its type.  Note that
+        # arg.reader(s) can be used to read and decode the argument from
+        # the bytestream s, and arg.doc documents the format of the raw
+        # argument bytes.  If the opcode doesn't have an argument embedded
+        # in the bytestream, arg should be None.
+        'arg',
+
+        # what the stack looks like before this opcode runs; a list
+        'stack_before',
+
+        # what the stack looks like after this opcode runs; a list
+        'stack_after',
+
+        # the protocol number in which this opcode was introduced; an int
+        'proto',
+
+        # human-readable docs for this opcode; a string
+        'doc',
+    )
+
+    def __init__(self, name, code, arg,
+                 stack_before, stack_after, proto, doc):
+        assert isinstance(name, str)
+        self.name = name
+
+        assert isinstance(code, str)
+        assert len(code) == 1
+        self.code = code
+
+        assert arg is None or isinstance(arg, ArgumentDescriptor)
+        self.arg = arg
+
+        assert isinstance(stack_before, list)
+        for x in stack_before:
+            assert isinstance(x, StackObject)
+        self.stack_before = stack_before
+
+        assert isinstance(stack_after, list)
+        for x in stack_after:
+            assert isinstance(x, StackObject)
+        self.stack_after = stack_after
+
+        assert isinstance(proto, int) and 0 <= proto <= 2
+        self.proto = proto
+
+        assert isinstance(doc, str)
+        self.doc = doc
+
+I = OpcodeInfo
+opcodes = [
+
+    # Ways to spell integers.
+
+    I(name='INT',
+      code='I',
+      arg=decimalnl_short,
+      stack_before=[],
+      stack_after=[pyinteger_or_bool],
+      proto=0,
+      doc="""Push an integer or bool.
+
+      The argument is a newline-terminated decimal literal string.
+
+      The intent may have been that this always fit in a short Python int,
+      but INT can be generated in pickles written on a 64-bit box that
+      require a Python long on a 32-bit box.  The difference between this
+      and LONG then is that INT skips a trailing 'L', and produces a short
+      int whenever possible.
+
+      Another difference is due to that, when bool was introduced as a
+      distinct type in 2.3, builtin names True and False were also added to
+      2.2.2, mapping to ints 1 and 0.  For compatibility in both directions,
+      True gets pickled as INT + "I01\\n", and False as INT + "I00\\n".
+      Leading zeroes are never produced for a genuine integer.  The 2.3
+      (and later) unpicklers special-case these and return bool instead;
+      earlier unpicklers ignore the leading "0" and return the int.
+      """),
+
+    I(name='BININT',
+      code='J',
+      arg=int4,
+      stack_before=[],
+      stack_after=[pyint],
+      proto=1,
+      doc="""Push a four-byte signed integer.
+
+      This handles the full range of Python (short) integers on a 32-bit
+      box, directly as binary bytes (1 for the opcode and 4 for the integer).
+      If the integer is non-negative and fits in 1 or 2 bytes, pickling via
+      BININT1 or BININT2 saves space.
+      """),
+
+    I(name='BININT1',
+      code='K',
+      arg=uint1,
+      stack_before=[],
+      stack_after=[pyint],
+      proto=1,
+      doc="""Push a one-byte unsigned integer.
+
+      This is a space optimization for pickling very small non-negative ints,
+      in range(256).
+      """),
+
+    I(name='BININT2',
+      code='M',
+      arg=uint2,
+      stack_before=[],
+      stack_after=[pyint],
+      proto=1,
+      doc="""Push a two-byte unsigned integer.
+
+      This is a space optimization for pickling small positive ints, in
+      range(256, 2**16).  Integers in range(256) can also be pickled via
+      BININT2, but BININT1 instead saves a byte.
+      """),
+
+    I(name='LONG',
+      code='L',
+      arg=decimalnl_long,
+      stack_before=[],
+      stack_after=[pylong],
+      proto=0,
+      doc="""Push a long integer.
+
+      The same as INT, except that the literal ends with 'L', and always
+      unpickles to a Python long.  There doesn't seem a real purpose to the
+      trailing 'L'.
+
+      Note that LONG takes time quadratic in the number of digits when
+      unpickling (this is simply due to the nature of decimal->binary
+      conversion).  Proto 2 added linear-time (in C; still quadratic-time
+      in Python) LONG1 and LONG4 opcodes.
+      """),
+
+    I(name="LONG1",
+      code='\x8a',
+      arg=long1,
+      stack_before=[],
+      stack_after=[pylong],
+      proto=2,
+      doc="""Long integer using one-byte length.
+
+      A more efficient encoding of a Python long; the long1 encoding
+      says it all."""),
+
+    I(name="LONG4",
+      code='\x8b',
+      arg=long4,
+      stack_before=[],
+      stack_after=[pylong],
+      proto=2,
+      doc="""Long integer using found-byte length.
+
+      A more efficient encoding of a Python long; the long4 encoding
+      says it all."""),
+
+    # Ways to spell strings (8-bit, not Unicode).
+
+    I(name='STRING',
+      code='S',
+      arg=stringnl,
+      stack_before=[],
+      stack_after=[pystring],
+      proto=0,
+      doc="""Push a Python string object.
+
+      The argument is a repr-style string, with bracketing quote characters,
+      and perhaps embedded escapes.  The argument extends until the next
+      newline character.
+      """),
+
+    I(name='BINSTRING',
+      code='T',
+      arg=string4,
+      stack_before=[],
+      stack_after=[pystring],
+      proto=1,
+      doc="""Push a Python string object.
+
+      There are two arguments:  the first is a 4-byte little-endian signed int
+      giving the number of bytes in the string, and the second is that many
+      bytes, which are taken literally as the string content.
+      """),
+
+    I(name='SHORT_BINSTRING',
+      code='U',
+      arg=string1,
+      stack_before=[],
+      stack_after=[pystring],
+      proto=1,
+      doc="""Push a Python string object.
+
+      There are two arguments:  the first is a 1-byte unsigned int giving
+      the number of bytes in the string, and the second is that many bytes,
+      which are taken literally as the string content.
+      """),
+
+    # Ways to spell None.
+
+    I(name='NONE',
+      code='N',
+      arg=None,
+      stack_before=[],
+      stack_after=[pynone],
+      proto=0,
+      doc="Push None on the stack."),
+
+    # Ways to spell bools, starting with proto 2.  See INT for how this was
+    # done before proto 2.
+
+    I(name='NEWTRUE',
+      code='\x88',
+      arg=None,
+      stack_before=[],
+      stack_after=[pybool],
+      proto=2,
+      doc="""True.
+
+      Push True onto the stack."""),
+
+    I(name='NEWFALSE',
+      code='\x89',
+      arg=None,
+      stack_before=[],
+      stack_after=[pybool],
+      proto=2,
+      doc="""True.
+
+      Push False onto the stack."""),
+
+    # Ways to spell Unicode strings.
+
+    I(name='UNICODE',
+      code='V',
+      arg=unicodestringnl,
+      stack_before=[],
+      stack_after=[pyunicode],
+      proto=0,  # this may be pure-text, but it's a later addition
+      doc="""Push a Python Unicode string object.
+
+      The argument is a raw-unicode-escape encoding of a Unicode string,
+      and so may contain embedded escape sequences.  The argument extends
+      until the next newline character.
+      """),
+
+    I(name='BINUNICODE',
+      code='X',
+      arg=unicodestring4,
+      stack_before=[],
+      stack_after=[pyunicode],
+      proto=1,
+      doc="""Push a Python Unicode string object.
+
+      There are two arguments:  the first is a 4-byte little-endian signed int
+      giving the number of bytes in the string.  The second is that many
+      bytes, and is the UTF-8 encoding of the Unicode string.
+      """),
+
+    # Ways to spell floats.
+
+    I(name='FLOAT',
+      code='F',
+      arg=floatnl,
+      stack_before=[],
+      stack_after=[pyfloat],
+      proto=0,
+      doc="""Newline-terminated decimal float literal.
+
+      The argument is repr(a_float), and in general requires 17 significant
+      digits for roundtrip conversion to be an identity (this is so for
+      IEEE-754 double precision values, which is what Python float maps to
+      on most boxes).
+
+      In general, FLOAT cannot be used to transport infinities, NaNs, or
+      minus zero across boxes (or even on a single box, if the platform C
+      library can't read the strings it produces for such things -- Windows
+      is like that), but may do less damage than BINFLOAT on boxes with
+      greater precision or dynamic range than IEEE-754 double.
+      """),
+
+    I(name='BINFLOAT',
+      code='G',
+      arg=float8,
+      stack_before=[],
+      stack_after=[pyfloat],
+      proto=1,
+      doc="""Float stored in binary form, with 8 bytes of data.
+
+      This generally requires less than half the space of FLOAT encoding.
+      In general, BINFLOAT cannot be used to transport infinities, NaNs, or
+      minus zero, raises an exception if the exponent exceeds the range of
+      an IEEE-754 double, and retains no more than 53 bits of precision (if
+      there are more than that, "add a half and chop" rounding is used to
+      cut it back to 53 significant bits).
+      """),
+
+    # Ways to build lists.
+
+    I(name='EMPTY_LIST',
+      code=']',
+      arg=None,
+      stack_before=[],
+      stack_after=[pylist],
+      proto=1,
+      doc="Push an empty list."),
+
+    I(name='APPEND',
+      code='a',
+      arg=None,
+      stack_before=[pylist, anyobject],
+      stack_after=[pylist],
+      proto=0,
+      doc="""Append an object to a list.
+
+      Stack before:  ... pylist anyobject
+      Stack after:   ... pylist+[anyobject]
+
+      although pylist is really extended in-place.
+      """),
+
+    I(name='APPENDS',
+      code='e',
+      arg=None,
+      stack_before=[pylist, markobject, stackslice],
+      stack_after=[pylist],
+      proto=1,
+      doc="""Extend a list by a slice of stack objects.
+
+      Stack before:  ... pylist markobject stackslice
+      Stack after:   ... pylist+stackslice
+
+      although pylist is really extended in-place.
+      """),
+
+    I(name='LIST',
+      code='l',
+      arg=None,
+      stack_before=[markobject, stackslice],
+      stack_after=[pylist],
+      proto=0,
+      doc="""Build a list out of the topmost stack slice, after markobject.
+
+      All the stack entries following the topmost markobject are placed into
+      a single Python list, which single list object replaces all of the
+      stack from the topmost markobject onward.  For example,
+
+      Stack before: ... markobject 1 2 3 'abc'
+      Stack after:  ... [1, 2, 3, 'abc']
+      """),
+
+    # Ways to build tuples.
+
+    I(name='EMPTY_TUPLE',
+      code=')',
+      arg=None,
+      stack_before=[],
+      stack_after=[pytuple],
+      proto=1,
+      doc="Push an empty tuple."),
+
+    I(name='TUPLE',
+      code='t',
+      arg=None,
+      stack_before=[markobject, stackslice],
+      stack_after=[pytuple],
+      proto=0,
+      doc="""Build a tuple out of the topmost stack slice, after markobject.
+
+      All the stack entries following the topmost markobject are placed into
+      a single Python tuple, which single tuple object replaces all of the
+      stack from the topmost markobject onward.  For example,
+
+      Stack before: ... markobject 1 2 3 'abc'
+      Stack after:  ... (1, 2, 3, 'abc')
+      """),
+
+    I(name='TUPLE1',
+      code='\x85',
+      arg=None,
+      stack_before=[anyobject],
+      stack_after=[pytuple],
+      proto=2,
+      doc="""One-tuple.
+
+      This code pops one value off the stack and pushes a tuple of
+      length 1 whose one item is that value back onto it.  IOW:
+
+          stack[-1] = tuple(stack[-1:])
+      """),
+
+    I(name='TUPLE2',
+      code='\x86',
+      arg=None,
+      stack_before=[anyobject, anyobject],
+      stack_after=[pytuple],
+      proto=2,
+      doc="""One-tuple.
+
+      This code pops two values off the stack and pushes a tuple
+      of length 2 whose items are those values back onto it.  IOW:
+
+          stack[-2:] = [tuple(stack[-2:])]
+      """),
+
+    I(name='TUPLE3',
+      code='\x87',
+      arg=None,
+      stack_before=[anyobject, anyobject, anyobject],
+      stack_after=[pytuple],
+      proto=2,
+      doc="""One-tuple.
+
+      This code pops three values off the stack and pushes a tuple
+      of length 3 whose items are those values back onto it.  IOW:
+
+          stack[-3:] = [tuple(stack[-3:])]
+      """),
+
+    # Ways to build dicts.
+
+    I(name='EMPTY_DICT',
+      code='}',
+      arg=None,
+      stack_before=[],
+      stack_after=[pydict],
+      proto=1,
+      doc="Push an empty dict."),
+
+    I(name='DICT',
+      code='d',
+      arg=None,
+      stack_before=[markobject, stackslice],
+      stack_after=[pydict],
+      proto=0,
+      doc="""Build a dict out of the topmost stack slice, after markobject.
+
+      All the stack entries following the topmost markobject are placed into
+      a single Python dict, which single dict object replaces all of the
+      stack from the topmost markobject onward.  The stack slice alternates
+      key, value, key, value, ....  For example,
+
+      Stack before: ... markobject 1 2 3 'abc'
+      Stack after:  ... {1: 2, 3: 'abc'}
+      """),
+
+    I(name='SETITEM',
+      code='s',
+      arg=None,
+      stack_before=[pydict, anyobject, anyobject],
+      stack_after=[pydict],
+      proto=0,
+      doc="""Add a key+value pair to an existing dict.
+
+      Stack before:  ... pydict key value
+      Stack after:   ... pydict
+
+      where pydict has been modified via pydict[key] = value.
+      """),
+
+    I(name='SETITEMS',
+      code='u',
+      arg=None,
+      stack_before=[pydict, markobject, stackslice],
+      stack_after=[pydict],
+      proto=1,
+      doc="""Add an arbitrary number of key+value pairs to an existing dict.
+
+      The slice of the stack following the topmost markobject is taken as
+      an alternating sequence of keys and values, added to the dict
+      immediately under the topmost markobject.  Everything at and after the
+      topmost markobject is popped, leaving the mutated dict at the top
+      of the stack.
+
+      Stack before:  ... pydict markobject key_1 value_1 ... key_n value_n
+      Stack after:   ... pydict
+
+      where pydict has been modified via pydict[key_i] = value_i for i in
+      1, 2, ..., n, and in that order.
+      """),
+
+    # Stack manipulation.
+
+    I(name='POP',
+      code='0',
+      arg=None,
+      stack_before=[anyobject],
+      stack_after=[],
+      proto=0,
+      doc="Discard the top stack item, shrinking the stack by one item."),
+
+    I(name='DUP',
+      code='2',
+      arg=None,
+      stack_before=[anyobject],
+      stack_after=[anyobject, anyobject],
+      proto=0,
+      doc="Push the top stack item onto the stack again, duplicating it."),
+
+    I(name='MARK',
+      code='(',
+      arg=None,
+      stack_before=[],
+      stack_after=[markobject],
+      proto=0,
+      doc="""Push markobject onto the stack.
+
+      markobject is a unique object, used by other opcodes to identify a
+      region of the stack containing a variable number of objects for them
+      to work on.  See markobject.doc for more detail.
+      """),
+
+    I(name='POP_MARK',
+      code='1',
+      arg=None,
+      stack_before=[markobject, stackslice],
+      stack_after=[],
+      proto=0,
+      doc="""Pop all the stack objects at and above the topmost markobject.
+
+      When an opcode using a variable number of stack objects is done,
+      POP_MARK is used to remove those objects, and to remove the markobject
+      that delimited their starting position on the stack.
+      """),
+
+    # Memo manipulation.  There are really only two operations (get and put),
+    # each in all-text, "short binary", and "long binary" flavors.
+
+    I(name='GET',
+      code='g',
+      arg=decimalnl_short,
+      stack_before=[],
+      stack_after=[anyobject],
+      proto=0,
+      doc="""Read an object from the memo and push it on the stack.
+
+      The index of the memo object to push is given by the newline-teriminated
+      decimal string following.  BINGET and LONG_BINGET are space-optimized
+      versions.
+      """),
+
+    I(name='BINGET',
+      code='h',
+      arg=uint1,
+      stack_before=[],
+      stack_after=[anyobject],
+      proto=1,
+      doc="""Read an object from the memo and push it on the stack.
+
+      The index of the memo object to push is given by the 1-byte unsigned
+      integer following.
+      """),
+
+    I(name='LONG_BINGET',
+      code='j',
+      arg=int4,
+      stack_before=[],
+      stack_after=[anyobject],
+      proto=1,
+      doc="""Read an object from the memo and push it on the stack.
+
+      The index of the memo object to push is given by the 4-byte signed
+      little-endian integer following.
+      """),
+
+    I(name='PUT',
+      code='p',
+      arg=decimalnl_short,
+      stack_before=[],
+      stack_after=[],
+      proto=0,
+      doc="""Store the stack top into the memo.  The stack is not popped.
+
+      The index of the memo location to write into is given by the newline-
+      terminated decimal string following.  BINPUT and LONG_BINPUT are
+      space-optimized versions.
+      """),
+
+    I(name='BINPUT',
+      code='q',
+      arg=uint1,
+      stack_before=[],
+      stack_after=[],
+      proto=1,
+      doc="""Store the stack top into the memo.  The stack is not popped.
+
+      The index of the memo location to write into is given by the 1-byte
+      unsigned integer following.
+      """),
+
+    I(name='LONG_BINPUT',
+      code='r',
+      arg=int4,
+      stack_before=[],
+      stack_after=[],
+      proto=1,
+      doc="""Store the stack top into the memo.  The stack is not popped.
+
+      The index of the memo location to write into is given by the 4-byte
+      signed little-endian integer following.
+      """),
+
+    # Access the extension registry (predefined objects).  Akin to the GET
+    # family.
+
+    I(name='EXT1',
+      code='\x82',
+      arg=uint1,
+      stack_before=[],
+      stack_after=[anyobject],
+      proto=2,
+      doc="""Extension code.
+
+      This code and the similar EXT2 and EXT4 allow using a registry
+      of popular objects that are pickled by name, typically classes.
+      It is envisioned that through a global negotiation and
+      registration process, third parties can set up a mapping between
+      ints and object names.
+
+      In order to guarantee pickle interchangeability, the extension
+      code registry ought to be global, although a range of codes may
+      be reserved for private use.
+
+      EXT1 has a 1-byte integer argument.  This is used to index into the
+      extension registry, and the object at that index is pushed on the stack.
+      """),
+
+    I(name='EXT2',
+      code='\x83',
+      arg=uint2,
+      stack_before=[],
+      stack_after=[anyobject],
+      proto=2,
+      doc="""Extension code.
+
+      See EXT1.  EXT2 has a two-byte integer argument.
+      """),
+
+    I(name='EXT4',
+      code='\x84',
+      arg=int4,
+      stack_before=[],
+      stack_after=[anyobject],
+      proto=2,
+      doc="""Extension code.
+
+      See EXT1.  EXT4 has a four-byte integer argument.
+      """),
+
+    # Push a class object, or module function, on the stack, via its module
+    # and name.
+
+    I(name='GLOBAL',
+      code='c',
+      arg=stringnl_noescape_pair,
+      stack_before=[],
+      stack_after=[anyobject],
+      proto=0,
+      doc="""Push a global object (module.attr) on the stack.
+
+      Two newline-terminated strings follow the GLOBAL opcode.  The first is
+      taken as a module name, and the second as a class name.  The class
+      object module.class is pushed on the stack.  More accurately, the
+      object returned by self.find_class(module, class) is pushed on the
+      stack, so unpickling subclasses can override this form of lookup.
+      """),
+
+    # Ways to build objects of classes pickle doesn't know about directly
+    # (user-defined classes).  I despair of documenting this accurately
+    # and comprehensibly -- you really have to read the pickle code to
+    # find all the special cases.
+
+    I(name='REDUCE',
+      code='R',
+      arg=None,
+      stack_before=[anyobject, anyobject],
+      stack_after=[anyobject],
+      proto=0,
+      doc="""Push an object built from a callable and an argument tuple.
+
+      The opcode is named to remind of the __reduce__() method.
+
+      Stack before: ... callable pytuple
+      Stack after:  ... callable(*pytuple)
+
+      The callable and the argument tuple are the first two items returned
+      by a __reduce__ method.  Applying the callable to the argtuple is
+      supposed to reproduce the original object, or at least get it started.
+      If the __reduce__ method returns a 3-tuple, the last component is an
+      argument to be passed to the object's __setstate__, and then the REDUCE
+      opcode is followed by code to create setstate's argument, and then a
+      BUILD opcode to apply  __setstate__ to that argument.
+
+      If type(callable) is not ClassType, REDUCE complains unless the
+      callable has been registered with the copy_reg module's
+      safe_constructors dict, or the callable has a magic
+      '__safe_for_unpickling__' attribute with a true value.  I'm not sure
+      why it does this, but I've sure seen this complaint often enough when
+      I didn't want to <wink>.
+      """),
+
+    I(name='BUILD',
+      code='b',
+      arg=None,
+      stack_before=[anyobject, anyobject],
+      stack_after=[anyobject],
+      proto=0,
+      doc="""Finish building an object, via __setstate__ or dict update.
+
+      Stack before: ... anyobject argument
+      Stack after:  ... anyobject
+
+      where anyobject may have been mutated, as follows:
+
+      If the object has a __setstate__ method,
+
+          anyobject.__setstate__(argument)
+
+      is called.
+
+      Else the argument must be a dict, the object must have a __dict__, and
+      the object is updated via
+
+          anyobject.__dict__.update(argument)
+
+      This may raise RuntimeError in restricted execution mode (which
+      disallows access to __dict__ directly); in that case, the object
+      is updated instead via
+
+          for k, v in argument.items():
+              anyobject[k] = v
+      """),
+
+    I(name='INST',
+      code='i',
+      arg=stringnl_noescape_pair,
+      stack_before=[markobject, stackslice],
+      stack_after=[anyobject],
+      proto=0,
+      doc="""Build a class instance.
+
+      This is the protocol 0 version of protocol 1's OBJ opcode.
+      INST is followed by two newline-terminated strings, giving a
+      module and class name, just as for the GLOBAL opcode (and see
+      GLOBAL for more details about that).  self.find_class(module, name)
+      is used to get a class object.
+
+      In addition, all the objects on the stack following the topmost
+      markobject are gathered into a tuple and popped (along with the
+      topmost markobject), just as for the TUPLE opcode.
+
+      Now it gets complicated.  If all of these are true:
+
+        + The argtuple is empty (markobject was at the top of the stack
+          at the start).
+
+        + It's an old-style class object (the type of the class object is
+          ClassType).
+
+        + The class object does not have a __getinitargs__ attribute.
+
+      then we want to create an old-style class instance without invoking
+      its __init__() method (pickle has waffled on this over the years; not
+      calling __init__() is current wisdom).  In this case, an instance of
+      an old-style dummy class is created, and then we try to rebind its
+      __class__ attribute to the desired class object.  If this succeeds,
+      the new instance object is pushed on the stack, and we're done.  In
+      restricted execution mode it can fail (assignment to __class__ is
+      disallowed), and I'm not really sure what happens then -- it looks
+      like the code ends up calling the class object's __init__ anyway,
+      via falling into the next case.
+
+      Else (the argtuple is not empty, it's not an old-style class object,
+      or the class object does have a __getinitargs__ attribute), the code
+      first insists that the class object have a __safe_for_unpickling__
+      attribute.  Unlike as for the __safe_for_unpickling__ check in REDUCE,
+      it doesn't matter whether this attribute has a true or false value, it
+      only matters whether it exists (XXX this is a bug; cPickle
+      requires the attribute to be true).  If __safe_for_unpickling__
+      doesn't exist, UnpicklingError is raised.
+
+      Else (the class object does have a __safe_for_unpickling__ attr),
+      the class object obtained from INST's arguments is applied to the
+      argtuple obtained from the stack, and the resulting instance object
+      is pushed on the stack.
+
+      NOTE:  checks for __safe_for_unpickling__ went away in Python 2.3.
+      """),
+
+    I(name='OBJ',
+      code='o',
+      arg=None,
+      stack_before=[markobject, anyobject, stackslice],
+      stack_after=[anyobject],
+      proto=1,
+      doc="""Build a class instance.
+
+      This is the protocol 1 version of protocol 0's INST opcode, and is
+      very much like it.  The major difference is that the class object
+      is taken off the stack, allowing it to be retrieved from the memo
+      repeatedly if several instances of the same class are created.  This
+      can be much more efficient (in both time and space) than repeatedly
+      embedding the module and class names in INST opcodes.
+
+      Unlike INST, OBJ takes no arguments from the opcode stream.  Instead
+      the class object is taken off the stack, immediately above the
+      topmost markobject:
+
+      Stack before: ... markobject classobject stackslice
+      Stack after:  ... new_instance_object
+
+      As for INST, the remainder of the stack above the markobject is
+      gathered into an argument tuple, and then the logic seems identical,
+      except that no __safe_for_unpickling__ check is done (XXX this is
+      a bug; cPickle does test __safe_for_unpickling__).  See INST for
+      the gory details.
+
+      NOTE:  In Python 2.3, INST and OBJ are identical except for how they
+      get the class object.  That was always the intent; the implementations
+      had diverged for accidental reasons.
+      """),
+
+    I(name='NEWOBJ',
+      code='\x81',
+      arg=None,
+      stack_before=[anyobject, anyobject],
+      stack_after=[anyobject],
+      proto=2,
+      doc="""Build an object instance.
+
+      The stack before should be thought of as containing a class
+      object followed by an argument tuple (the tuple being the stack
+      top).  Call these cls and args.  They are popped off the stack,
+      and the value returned by cls.__new__(cls, *args) is pushed back
+      onto the stack.
+      """),
+
+    # Machine control.
+
+    I(name='PROTO',
+      code='\x80',
+      arg=uint1,
+      stack_before=[],
+      stack_after=[],
+      proto=2,
+      doc="""Protocol version indicator.
+
+      For protocol 2 and above, a pickle must start with this opcode.
+      The argument is the protocol version, an int in range(2, 256).
+      """),
+
+    I(name='STOP',
+      code='.',
+      arg=None,
+      stack_before=[anyobject],
+      stack_after=[],
+      proto=0,
+      doc="""Stop the unpickling machine.
+
+      Every pickle ends with this opcode.  The object at the top of the stack
+      is popped, and that's the result of unpickling.  The stack should be
+      empty then.
+      """),
+
+    # Ways to deal with persistent IDs.
+
+    I(name='PERSID',
+      code='P',
+      arg=stringnl_noescape,
+      stack_before=[],
+      stack_after=[anyobject],
+      proto=0,
+      doc="""Push an object identified by a persistent ID.
+
+      The pickle module doesn't define what a persistent ID means.  PERSID's
+      argument is a newline-terminated str-style (no embedded escapes, no
+      bracketing quote characters) string, which *is* "the persistent ID".
+      The unpickler passes this string to self.persistent_load().  Whatever
+      object that returns is pushed on the stack.  There is no implementation
+      of persistent_load() in Python's unpickler:  it must be supplied by an
+      unpickler subclass.
+      """),
+
+    I(name='BINPERSID',
+      code='Q',
+      arg=None,
+      stack_before=[anyobject],
+      stack_after=[anyobject],
+      proto=1,
+      doc="""Push an object identified by a persistent ID.
+
+      Like PERSID, except the persistent ID is popped off the stack (instead
+      of being a string embedded in the opcode bytestream).  The persistent
+      ID is passed to self.persistent_load(), and whatever object that
+      returns is pushed on the stack.  See PERSID for more detail.
+      """),
+]
+del I
+
+# Verify uniqueness of .name and .code members.
+name2i = {}
+code2i = {}
+
+for i, d in enumerate(opcodes):
+    if d.name in name2i:
+        raise ValueError("repeated name %r at indices %d and %d" %
+                         (d.name, name2i[d.name], i))
+    if d.code in code2i:
+        raise ValueError("repeated code %r at indices %d and %d" %
+                         (d.code, code2i[d.code], i))
+
+    name2i[d.name] = i
+    code2i[d.code] = i
+
+del name2i, code2i, i, d
+
+##############################################################################
+# Build a code2op dict, mapping opcode characters to OpcodeInfo records.
+# Also ensure we've got the same stuff as pickle.py, although the
+# introspection here is dicey.
+
+code2op = {}
+for d in opcodes:
+    code2op[d.code] = d
+del d
+
+def assure_pickle_consistency(verbose=False):
+    import pickle, re
+
+    copy = code2op.copy()
+    for name in pickle.__all__:
+        if not re.match("[A-Z][A-Z0-9_]+$", name):
+            if verbose:
+                print "skipping %r: it doesn't look like an opcode name" % name
+            continue
+        picklecode = getattr(pickle, name)
+        if not isinstance(picklecode, str) or len(picklecode) != 1:
+            if verbose:
+                print ("skipping %r: value %r doesn't look like a pickle "
+                       "code" % (name, picklecode))
+            continue
+        if picklecode in copy:
+            if verbose:
+                print "checking name %r w/ code %r for consistency" % (
+                      name, picklecode)
+            d = copy[picklecode]
+            if d.name != name:
+                raise ValueError("for pickle code %r, pickle.py uses name %r "
+                                 "but we're using name %r" % (picklecode,
+                                                              name,
+                                                              d.name))
+            # Forget this one.  Any left over in copy at the end are a problem
+            # of a different kind.
+            del copy[picklecode]
+        else:
+            raise ValueError("pickle.py appears to have a pickle opcode with "
+                             "name %r and code %r, but we don't" %
+                             (name, picklecode))
+    if copy:
+        msg = ["we appear to have pickle opcodes that pickle.py doesn't have:"]
+        for code, d in copy.items():
+            msg.append("    name %r with code %r" % (d.name, code))
+        raise ValueError("\n".join(msg))
+
+assure_pickle_consistency()
+del assure_pickle_consistency
+
+##############################################################################
+# A pickle opcode generator.
+
+def genops(pickle):
+    """Generate all the opcodes in a pickle.
+
+    'pickle' is a file-like object, or string, containing the pickle.
+
+    Each opcode in the pickle is generated, from the current pickle position,
+    stopping after a STOP opcode is delivered.  A triple is generated for
+    each opcode:
+
+        opcode, arg, pos
+
+    opcode is an OpcodeInfo record, describing the current opcode.
+
+    If the opcode has an argument embedded in the pickle, arg is its decoded
+    value, as a Python object.  If the opcode doesn't have an argument, arg
+    is None.
+
+    If the pickle has a tell() method, pos was the value of pickle.tell()
+    before reading the current opcode.  If the pickle is a string object,
+    it's wrapped in a StringIO object, and the latter's tell() result is
+    used.  Else (the pickle doesn't have a tell(), and it's not obvious how
+    to query its current position) pos is None.
+    """
+
+    import cStringIO as StringIO
+
+    if isinstance(pickle, str):
+        pickle = StringIO.StringIO(pickle)
+
+    if hasattr(pickle, "tell"):
+        getpos = pickle.tell
+    else:
+        getpos = lambda: None
+
+    while True:
+        pos = getpos()
+        code = pickle.read(1)
+        opcode = code2op.get(code)
+        if opcode is None:
+            if code == "":
+                raise ValueError("pickle exhausted before seeing STOP")
+            else:
+                raise ValueError("at position %s, opcode %r unknown" % (
+                                 pos is None and "<unknown>" or pos,
+                                 code))
+        if opcode.arg is None:
+            arg = None
+        else:
+            arg = opcode.arg.reader(pickle)
+        yield opcode, arg, pos
+        if code == '.':
+            assert opcode.name == 'STOP'
+            break
+
+##############################################################################
+# A symbolic pickle disassembler.
+
+def dis(pickle, out=None, memo=None, indentlevel=4):
+    """Produce a symbolic disassembly of a pickle.
+
+    'pickle' is a file-like object, or string, containing a (at least one)
+    pickle.  The pickle is disassembled from the current position, through
+    the first STOP opcode encountered.
+
+    Optional arg 'out' is a file-like object to which the disassembly is
+    printed.  It defaults to sys.stdout.
+
+    Optional arg 'memo' is a Python dict, used as the pickle's memo.  It
+    may be mutated by dis(), if the pickle contains PUT or BINPUT opcodes.
+    Passing the same memo object to another dis() call then allows disassembly
+    to proceed across multiple pickles that were all created by the same
+    pickler with the same memo.  Ordinarily you don't need to worry about this.
+
+    Optional arg indentlevel is the number of blanks by which to indent
+    a new MARK level.  It defaults to 4.
+
+    In addition to printing the disassembly, some sanity checks are made:
+
+    + All embedded opcode arguments "make sense".
+
+    + Explicit and implicit pop operations have enough items on the stack.
+
+    + When an opcode implicitly refers to a markobject, a markobject is
+      actually on the stack.
+
+    + A memo entry isn't referenced before it's defined.
+
+    + The markobject isn't stored in the memo.
+
+    + A memo entry isn't redefined.
+    """
+
+    # Most of the hair here is for sanity checks, but most of it is needed
+    # anyway to detect when a protocol 0 POP takes a MARK off the stack
+    # (which in turn is needed to indent MARK blocks correctly).
+
+    stack = []          # crude emulation of unpickler stack
+    if memo is None:
+        memo = {}       # crude emulation of unpicker memo
+    maxproto = -1       # max protocol number seen
+    markstack = []      # bytecode positions of MARK opcodes
+    indentchunk = ' ' * indentlevel
+    errormsg = None
+    for opcode, arg, pos in genops(pickle):
+        if pos is not None:
+            print >> out, "%5d:" % pos,
+
+        line = "%-4s %s%s" % (repr(opcode.code)[1:-1],
+                              indentchunk * len(markstack),
+                              opcode.name)
+
+        maxproto = max(maxproto, opcode.proto)
+        before = opcode.stack_before    # don't mutate
+        after = opcode.stack_after      # don't mutate
+        numtopop = len(before)
+
+        # See whether a MARK should be popped.
+        markmsg = None
+        if markobject in before or (opcode.name == "POP" and
+                                    stack and
+                                    stack[-1] is markobject):
+            assert markobject not in after
+            if __debug__:
+                if markobject in before:
+                    assert before[-1] is stackslice
+            if markstack:
+                markpos = markstack.pop()
+                if markpos is None:
+                    markmsg = "(MARK at unknown opcode offset)"
+                else:
+                    markmsg = "(MARK at %d)" % markpos
+                # Pop everything at and after the topmost markobject.
+                while stack[-1] is not markobject:
+                    stack.pop()
+                stack.pop()
+                # Stop later code from popping too much.
+                try:
+                    numtopop = before.index(markobject)
+                except ValueError:
+                    assert opcode.name == "POP"
+                    numtopop = 0
+            else:
+                errormsg = markmsg = "no MARK exists on stack"
+
+        # Check for correct memo usage.
+        if opcode.name in ("PUT", "BINPUT", "LONG_BINPUT"):
+            assert arg is not None
+            if arg in memo:
+                errormsg = "memo key %r already defined" % arg
+            elif not stack:
+                errormsg = "stack is empty -- can't store into memo"
+            elif stack[-1] is markobject:
+                errormsg = "can't store markobject in the memo"
+            else:
+                memo[arg] = stack[-1]
+
+        elif opcode.name in ("GET", "BINGET", "LONG_BINGET"):
+            if arg in memo:
+                assert len(after) == 1
+                after = [memo[arg]]     # for better stack emulation
+            else:
+                errormsg = "memo key %r has never been stored into" % arg
+
+        if arg is not None or markmsg:
+            # make a mild effort to align arguments
+            line += ' ' * (10 - len(opcode.name))
+            if arg is not None:
+                line += ' ' + repr(arg)
+            if markmsg:
+                line += ' ' + markmsg
+        print >> out, line
+
+        if errormsg:
+            # Note that we delayed complaining until the offending opcode
+            # was printed.
+            raise ValueError(errormsg)
+
+        # Emulate the stack effects.
+        if len(stack) < numtopop:
+            raise ValueError("tries to pop %d items from stack with "
+                             "only %d items" % (numtopop, len(stack)))
+        if numtopop:
+            del stack[-numtopop:]
+        if markobject in after:
+            assert markobject not in before
+            markstack.append(pos)
+
+        stack.extend(after)
+
+    print >> out, "highest protocol among opcodes =", maxproto
+    if stack:
+        raise ValueError("stack not empty after STOP: %r" % stack)
+
+# For use in the doctest, simply as an example of a class to pickle.
+class _Example:
+    def __init__(self, value):
+        self.value = value
+
+_dis_test = r"""
+>>> import pickle
+>>> x = [1, 2, (3, 4), {'abc': u"def"}]
+>>> pkl = pickle.dumps(x, 0)
+>>> dis(pkl)
+    0: (    MARK
+    1: l        LIST       (MARK at 0)
+    2: p    PUT        0
+    5: I    INT        1
+    8: a    APPEND
+    9: I    INT        2
+   12: a    APPEND
+   13: (    MARK
+   14: I        INT        3
+   17: I        INT        4
+   20: t        TUPLE      (MARK at 13)
+   21: p    PUT        1
+   24: a    APPEND
+   25: (    MARK
+   26: d        DICT       (MARK at 25)
+   27: p    PUT        2
+   30: S    STRING     'abc'
+   37: p    PUT        3
+   40: V    UNICODE    u'def'
+   45: p    PUT        4
+   48: s    SETITEM
+   49: a    APPEND
+   50: .    STOP
+highest protocol among opcodes = 0
+
+Try again with a "binary" pickle.
+
+>>> pkl = pickle.dumps(x, 1)
+>>> dis(pkl)
+    0: ]    EMPTY_LIST
+    1: q    BINPUT     0
+    3: (    MARK
+    4: K        BININT1    1
+    6: K        BININT1    2
+    8: (        MARK
+    9: K            BININT1    3
+   11: K            BININT1    4
+   13: t            TUPLE      (MARK at 8)
+   14: q        BINPUT     1
+   16: }        EMPTY_DICT
+   17: q        BINPUT     2
+   19: U        SHORT_BINSTRING 'abc'
+   24: q        BINPUT     3
+   26: X        BINUNICODE u'def'
+   34: q        BINPUT     4
+   36: s        SETITEM
+   37: e        APPENDS    (MARK at 3)
+   38: .    STOP
+highest protocol among opcodes = 1
+
+Exercise the INST/OBJ/BUILD family.
+
+>>> import random
+>>> dis(pickle.dumps(random.random, 0))
+    0: c    GLOBAL     'random random'
+   15: p    PUT        0
+   18: .    STOP
+highest protocol among opcodes = 0
+
+>>> from pickletools import _Example
+>>> x = [_Example(42)] * 2
+>>> dis(pickle.dumps(x, 0))
+    0: (    MARK
+    1: l        LIST       (MARK at 0)
+    2: p    PUT        0
+    5: (    MARK
+    6: i        INST       'pickletools _Example' (MARK at 5)
+   28: p    PUT        1
+   31: (    MARK
+   32: d        DICT       (MARK at 31)
+   33: p    PUT        2
+   36: S    STRING     'value'
+   45: p    PUT        3
+   48: I    INT        42
+   52: s    SETITEM
+   53: b    BUILD
+   54: a    APPEND
+   55: g    GET        1
+   58: a    APPEND
+   59: .    STOP
+highest protocol among opcodes = 0
+
+>>> dis(pickle.dumps(x, 1))
+    0: ]    EMPTY_LIST
+    1: q    BINPUT     0
+    3: (    MARK
+    4: (        MARK
+    5: c            GLOBAL     'pickletools _Example'
+   27: q            BINPUT     1
+   29: o            OBJ        (MARK at 4)
+   30: q        BINPUT     2
+   32: }        EMPTY_DICT
+   33: q        BINPUT     3
+   35: U        SHORT_BINSTRING 'value'
+   42: q        BINPUT     4
+   44: K        BININT1    42
+   46: s        SETITEM
+   47: b        BUILD
+   48: h        BINGET     2
+   50: e        APPENDS    (MARK at 3)
+   51: .    STOP
+highest protocol among opcodes = 1
+
+Try "the canonical" recursive-object test.
+
+>>> L = []
+>>> T = L,
+>>> L.append(T)
+>>> L[0] is T
+True
+>>> T[0] is L
+True
+>>> L[0][0] is L
+True
+>>> T[0][0] is T
+True
+>>> dis(pickle.dumps(L, 0))
+    0: (    MARK
+    1: l        LIST       (MARK at 0)
+    2: p    PUT        0
+    5: (    MARK
+    6: g        GET        0
+    9: t        TUPLE      (MARK at 5)
+   10: p    PUT        1
+   13: a    APPEND
+   14: .    STOP
+highest protocol among opcodes = 0
+
+>>> dis(pickle.dumps(L, 1))
+    0: ]    EMPTY_LIST
+    1: q    BINPUT     0
+    3: (    MARK
+    4: h        BINGET     0
+    6: t        TUPLE      (MARK at 3)
+    7: q    BINPUT     1
+    9: a    APPEND
+   10: .    STOP
+highest protocol among opcodes = 1
+
+Note that, in the protocol 0 pickle of the recursive tuple, the disassembler
+has to emulate the stack in order to realize that the POP opcode at 16 gets
+rid of the MARK at 0.
+
+>>> dis(pickle.dumps(T, 0))
+    0: (    MARK
+    1: (        MARK
+    2: l            LIST       (MARK at 1)
+    3: p        PUT        0
+    6: (        MARK
+    7: g            GET        0
+   10: t            TUPLE      (MARK at 6)
+   11: p        PUT        1
+   14: a        APPEND
+   15: 0        POP
+   16: 0        POP        (MARK at 0)
+   17: g    GET        1
+   20: .    STOP
+highest protocol among opcodes = 0
+
+>>> dis(pickle.dumps(T, 1))
+    0: (    MARK
+    1: ]        EMPTY_LIST
+    2: q        BINPUT     0
+    4: (        MARK
+    5: h            BINGET     0
+    7: t            TUPLE      (MARK at 4)
+    8: q        BINPUT     1
+   10: a        APPEND
+   11: 1        POP_MARK   (MARK at 0)
+   12: h    BINGET     1
+   14: .    STOP
+highest protocol among opcodes = 1
+
+Try protocol 2.
+
+>>> dis(pickle.dumps(L, 2))
+    0: \x80 PROTO      2
+    2: ]    EMPTY_LIST
+    3: q    BINPUT     0
+    5: h    BINGET     0
+    7: \x85 TUPLE1
+    8: q    BINPUT     1
+   10: a    APPEND
+   11: .    STOP
+highest protocol among opcodes = 2
+
+>>> dis(pickle.dumps(T, 2))
+    0: \x80 PROTO      2
+    2: ]    EMPTY_LIST
+    3: q    BINPUT     0
+    5: h    BINGET     0
+    7: \x85 TUPLE1
+    8: q    BINPUT     1
+   10: a    APPEND
+   11: 0    POP
+   12: h    BINGET     1
+   14: .    STOP
+highest protocol among opcodes = 2
+"""
+
+_memo_test = r"""
+>>> import pickle
+>>> from StringIO import StringIO
+>>> f = StringIO()
+>>> p = pickle.Pickler(f, 2)
+>>> x = [1, 2, 3]
+>>> p.dump(x)
+>>> p.dump(x)
+>>> f.seek(0)
+>>> memo = {}
+>>> dis(f, memo=memo)
+    0: \x80 PROTO      2
+    2: ]    EMPTY_LIST
+    3: q    BINPUT     0
+    5: (    MARK
+    6: K        BININT1    1
+    8: K        BININT1    2
+   10: K        BININT1    3
+   12: e        APPENDS    (MARK at 5)
+   13: .    STOP
+highest protocol among opcodes = 2
+>>> dis(f, memo=memo)
+   14: \x80 PROTO      2
+   16: h    BINGET     0
+   18: .    STOP
+highest protocol among opcodes = 2
+"""
+
+__test__ = {'disassembler_test': _dis_test,
+            'disassembler_memo_test': _memo_test,
+           }
+
+def _test():
+    import doctest
+    return doctest.testmod()
+
+if __name__ == "__main__":
+    _test()

Added: vendor/Python/current/Lib/pipes.py
===================================================================
--- vendor/Python/current/Lib/pipes.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/pipes.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,298 @@
+"""Conversion pipeline templates.
+
+The problem:
+------------
+
+Suppose you have some data that you want to convert to another format,
+such as from GIF image format to PPM image format.  Maybe the
+conversion involves several steps (e.g. piping it through compress or
+uuencode).  Some of the conversion steps may require that their input
+is a disk file, others may be able to read standard input; similar for
+their output.  The input to the entire conversion may also be read
+from a disk file or from an open file, and similar for its output.
+
+The module lets you construct a pipeline template by sticking one or
+more conversion steps together.  It will take care of creating and
+removing temporary files if they are necessary to hold intermediate
+data.  You can then use the template to do conversions from many
+different sources to many different destinations.  The temporary
+file names used are different each time the template is used.
+
+The templates are objects so you can create templates for many
+different conversion steps and store them in a dictionary, for
+instance.
+
+
+Directions:
+-----------
+
+To create a template:
+    t = Template()
+
+To add a conversion step to a template:
+   t.append(command, kind)
+where kind is a string of two characters: the first is '-' if the
+command reads its standard input or 'f' if it requires a file; the
+second likewise for the output. The command must be valid /bin/sh
+syntax.  If input or output files are required, they are passed as
+$IN and $OUT; otherwise, it must be  possible to use the command in
+a pipeline.
+
+To add a conversion step at the beginning:
+   t.prepend(command, kind)
+
+To convert a file to another file using a template:
+  sts = t.copy(infile, outfile)
+If infile or outfile are the empty string, standard input is read or
+standard output is written, respectively.  The return value is the
+exit status of the conversion pipeline.
+
+To open a file for reading or writing through a conversion pipeline:
+   fp = t.open(file, mode)
+where mode is 'r' to read the file, or 'w' to write it -- just like
+for the built-in function open() or for os.popen().
+
+To create a new template object initialized to a given one:
+   t2 = t.clone()
+
+For an example, see the function test() at the end of the file.
+"""                                     # '
+
+
+import re
+
+import os
+import tempfile
+import string
+
+__all__ = ["Template"]
+
+# Conversion step kinds
+
+FILEIN_FILEOUT = 'ff'                   # Must read & write real files
+STDIN_FILEOUT  = '-f'                   # Must write a real file
+FILEIN_STDOUT  = 'f-'                   # Must read a real file
+STDIN_STDOUT   = '--'                   # Normal pipeline element
+SOURCE         = '.-'                   # Must be first, writes stdout
+SINK           = '-.'                   # Must be last, reads stdin
+
+stepkinds = [FILEIN_FILEOUT, STDIN_FILEOUT, FILEIN_STDOUT, STDIN_STDOUT, \
+             SOURCE, SINK]
+
+
+class Template:
+    """Class representing a pipeline template."""
+
+    def __init__(self):
+        """Template() returns a fresh pipeline template."""
+        self.debugging = 0
+        self.reset()
+
+    def __repr__(self):
+        """t.__repr__() implements repr(t)."""
+        return '<Template instance, steps=%r>' % (self.steps,)
+
+    def reset(self):
+        """t.reset() restores a pipeline template to its initial state."""
+        self.steps = []
+
+    def clone(self):
+        """t.clone() returns a new pipeline template with identical
+        initial state as the current one."""
+        t = Template()
+        t.steps = self.steps[:]
+        t.debugging = self.debugging
+        return t
+
+    def debug(self, flag):
+        """t.debug(flag) turns debugging on or off."""
+        self.debugging = flag
+
+    def append(self, cmd, kind):
+        """t.append(cmd, kind) adds a new step at the end."""
+        if type(cmd) is not type(''):
+            raise TypeError, \
+                  'Template.append: cmd must be a string'
+        if kind not in stepkinds:
+            raise ValueError, \
+                  'Template.append: bad kind %r' % (kind,)
+        if kind == SOURCE:
+            raise ValueError, \
+                  'Template.append: SOURCE can only be prepended'
+        if self.steps and self.steps[-1][1] == SINK:
+            raise ValueError, \
+                  'Template.append: already ends with SINK'
+        if kind[0] == 'f' and not re.search(r'\$IN\b', cmd):
+            raise ValueError, \
+                  'Template.append: missing $IN in cmd'
+        if kind[1] == 'f' and not re.search(r'\$OUT\b', cmd):
+            raise ValueError, \
+                  'Template.append: missing $OUT in cmd'
+        self.steps.append((cmd, kind))
+
+    def prepend(self, cmd, kind):
+        """t.prepend(cmd, kind) adds a new step at the front."""
+        if type(cmd) is not type(''):
+            raise TypeError, \
+                  'Template.prepend: cmd must be a string'
+        if kind not in stepkinds:
+            raise ValueError, \
+                  'Template.prepend: bad kind %r' % (kind,)
+        if kind == SINK:
+            raise ValueError, \
+                  'Template.prepend: SINK can only be appended'
+        if self.steps and self.steps[0][1] == SOURCE:
+            raise ValueError, \
+                  'Template.prepend: already begins with SOURCE'
+        if kind[0] == 'f' and not re.search(r'\$IN\b', cmd):
+            raise ValueError, \
+                  'Template.prepend: missing $IN in cmd'
+        if kind[1] == 'f' and not re.search(r'\$OUT\b', cmd):
+            raise ValueError, \
+                  'Template.prepend: missing $OUT in cmd'
+        self.steps.insert(0, (cmd, kind))
+
+    def open(self, file, rw):
+        """t.open(file, rw) returns a pipe or file object open for
+        reading or writing; the file is the other end of the pipeline."""
+        if rw == 'r':
+            return self.open_r(file)
+        if rw == 'w':
+            return self.open_w(file)
+        raise ValueError, \
+              'Template.open: rw must be \'r\' or \'w\', not %r' % (rw,)
+
+    def open_r(self, file):
+        """t.open_r(file) and t.open_w(file) implement
+        t.open(file, 'r') and t.open(file, 'w') respectively."""
+        if not self.steps:
+            return open(file, 'r')
+        if self.steps[-1][1] == SINK:
+            raise ValueError, \
+                  'Template.open_r: pipeline ends width SINK'
+        cmd = self.makepipeline(file, '')
+        return os.popen(cmd, 'r')
+
+    def open_w(self, file):
+        if not self.steps:
+            return open(file, 'w')
+        if self.steps[0][1] == SOURCE:
+            raise ValueError, \
+                  'Template.open_w: pipeline begins with SOURCE'
+        cmd = self.makepipeline('', file)
+        return os.popen(cmd, 'w')
+
+    def copy(self, infile, outfile):
+        return os.system(self.makepipeline(infile, outfile))
+
+    def makepipeline(self, infile, outfile):
+        cmd = makepipeline(infile, self.steps, outfile)
+        if self.debugging:
+            print cmd
+            cmd = 'set -x; ' + cmd
+        return cmd
+
+
+def makepipeline(infile, steps, outfile):
+    # Build a list with for each command:
+    # [input filename or '', command string, kind, output filename or '']
+
+    list = []
+    for cmd, kind in steps:
+        list.append(['', cmd, kind, ''])
+    #
+    # Make sure there is at least one step
+    #
+    if not list:
+        list.append(['', 'cat', '--', ''])
+    #
+    # Take care of the input and output ends
+    #
+    [cmd, kind] = list[0][1:3]
+    if kind[0] == 'f' and not infile:
+        list.insert(0, ['', 'cat', '--', ''])
+    list[0][0] = infile
+    #
+    [cmd, kind] = list[-1][1:3]
+    if kind[1] == 'f' and not outfile:
+        list.append(['', 'cat', '--', ''])
+    list[-1][-1] = outfile
+    #
+    # Invent temporary files to connect stages that need files
+    #
+    garbage = []
+    for i in range(1, len(list)):
+        lkind = list[i-1][2]
+        rkind = list[i][2]
+        if lkind[1] == 'f' or rkind[0] == 'f':
+            (fd, temp) = tempfile.mkstemp()
+            os.close(fd)
+            garbage.append(temp)
+            list[i-1][-1] = list[i][0] = temp
+    #
+    for item in list:
+        [inf, cmd, kind, outf] = item
+        if kind[1] == 'f':
+            cmd = 'OUT=' + quote(outf) + '; ' + cmd
+        if kind[0] == 'f':
+            cmd = 'IN=' + quote(inf) + '; ' + cmd
+        if kind[0] == '-' and inf:
+            cmd = cmd + ' <' + quote(inf)
+        if kind[1] == '-' and outf:
+            cmd = cmd + ' >' + quote(outf)
+        item[1] = cmd
+    #
+    cmdlist = list[0][1]
+    for item in list[1:]:
+        [cmd, kind] = item[1:3]
+        if item[0] == '':
+            if 'f' in kind:
+                cmd = '{ ' + cmd + '; }'
+            cmdlist = cmdlist + ' |\n' + cmd
+        else:
+            cmdlist = cmdlist + '\n' + cmd
+    #
+    if garbage:
+        rmcmd = 'rm -f'
+        for file in garbage:
+            rmcmd = rmcmd + ' ' + quote(file)
+        trapcmd = 'trap ' + quote(rmcmd + '; exit') + ' 1 2 3 13 14 15'
+        cmdlist = trapcmd + '\n' + cmdlist + '\n' + rmcmd
+    #
+    return cmdlist
+
+
+# Reliably quote a string as a single argument for /bin/sh
+
+_safechars = string.ascii_letters + string.digits + '!@%_-+=:,./' # Safe unquoted
+_funnychars = '"`$\\'                           # Unsafe inside "double quotes"
+
+def quote(file):
+    for c in file:
+        if c not in _safechars:
+            break
+    else:
+        return file
+    if '\'' not in file:
+        return '\'' + file + '\''
+    res = ''
+    for c in file:
+        if c in _funnychars:
+            c = '\\' + c
+        res = res + c
+    return '"' + res + '"'
+
+
+# Small test program and example
+
+def test():
+    print 'Testing...'
+    t = Template()
+    t.append('togif $IN $OUT', 'ff')
+    t.append('giftoppm', '--')
+    t.append('ppmtogif >$OUT', '-f')
+    t.append('fromgif $IN $OUT', 'ff')
+    t.debug(1)
+    FILE = '/usr/local/images/rgb/rogues/guido.rgb'
+    t.copy(FILE, '@temp')
+    print 'Done.'

Added: vendor/Python/current/Lib/pkgutil.py
===================================================================
--- vendor/Python/current/Lib/pkgutil.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/pkgutil.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,546 @@
+"""Utilities to support packages."""
+
+# NOTE: This module must remain compatible with Python 2.3, as it is shared
+# by setuptools for distribution with Python 2.3 and up.
+
+import os
+import sys
+import imp
+import os.path
+from types import ModuleType
+
+__all__ = [
+    'get_importer', 'iter_importers', 'get_loader', 'find_loader',
+    'walk_packages', 'iter_modules',
+    'ImpImporter', 'ImpLoader', 'read_code', 'extend_path',
+]
+
+def read_code(stream):
+    # This helper is needed in order for the PEP 302 emulation to
+    # correctly handle compiled files
+    import marshal
+
+    magic = stream.read(4)
+    if magic != imp.get_magic():
+        return None
+
+    stream.read(4) # Skip timestamp
+    return marshal.load(stream)
+
+
+def simplegeneric(func):
+    """Make a trivial single-dispatch generic function"""
+    registry = {}
+    def wrapper(*args, **kw):
+        ob = args[0]
+        try:
+            cls = ob.__class__
+        except AttributeError:
+            cls = type(ob)
+        try:
+            mro = cls.__mro__
+        except AttributeError:
+            try:
+                class cls(cls, object):
+                    pass
+                mro = cls.__mro__[1:]
+            except TypeError:
+                mro = object,   # must be an ExtensionClass or some such  :(
+        for t in mro:
+            if t in registry:
+                return registry[t](*args, **kw)
+        else:
+            return func(*args, **kw)
+    try:
+        wrapper.__name__ = func.__name__
+    except (TypeError, AttributeError):
+        pass    # Python 2.3 doesn't allow functions to be renamed
+
+    def register(typ, func=None):
+        if func is None:
+            return lambda f: register(typ, f)
+        registry[typ] = func
+        return func
+
+    wrapper.__dict__ = func.__dict__
+    wrapper.__doc__ = func.__doc__
+    wrapper.register = register
+    return wrapper
+
+
+def walk_packages(path=None, prefix='', onerror=None):
+    """Yields (module_loader, name, ispkg) for all modules recursively
+    on path, or, if path is None, all accessible modules.
+
+    'path' should be either None or a list of paths to look for
+    modules in.
+
+    'prefix' is a string to output on the front of every module name
+    on output.
+
+    Note that this function must import all *packages* (NOT all
+    modules!) on the given path, in order to access the __path__
+    attribute to find submodules.
+
+    'onerror' is a function which gets called with one argument (the
+    name of the package which was being imported) if any exception
+    occurs while trying to import a package.  If no onerror function is
+    supplied, ImportErrors are caught and ignored, while all other
+    exceptions are propagated, terminating the search.
+
+    Examples:
+
+    # list all modules python can access
+    walk_packages()
+
+    # list all submodules of ctypes
+    walk_packages(ctypes.__path__, ctypes.__name__+'.')
+    """
+
+    def seen(p, m={}):
+        if p in m:
+            return True
+        m[p] = True
+
+    for importer, name, ispkg in iter_modules(path, prefix):
+        yield importer, name, ispkg
+
+        if ispkg:
+            try:
+                __import__(name)
+            except ImportError:
+                if onerror is not None:
+                    onerror(name)
+            except Exception:
+                if onerror is not None:
+                    onerror(name)
+                else:
+                    raise
+            else:
+                path = getattr(sys.modules[name], '__path__', None) or []
+
+                # don't traverse path items we've seen before
+                path = [p for p in path if not seen(p)]
+
+                for item in walk_packages(path, name+'.', onerror):
+                    yield item
+
+
+def iter_modules(path=None, prefix=''):
+    """Yields (module_loader, name, ispkg) for all submodules on path,
+    or, if path is None, all top-level modules on sys.path.
+
+    'path' should be either None or a list of paths to look for
+    modules in.
+
+    'prefix' is a string to output on the front of every module name
+    on output.
+    """
+
+    if path is None:
+        importers = iter_importers()
+    else:
+        importers = map(get_importer, path)
+
+    yielded = {}
+    for i in importers:
+        for name, ispkg in iter_importer_modules(i, prefix):
+            if name not in yielded:
+                yielded[name] = 1
+                yield i, name, ispkg
+
+
+#@simplegeneric
+def iter_importer_modules(importer, prefix=''):
+    if not hasattr(importer, 'iter_modules'):
+        return []
+    return importer.iter_modules(prefix)
+
+iter_importer_modules = simplegeneric(iter_importer_modules)
+
+
+class ImpImporter:
+    """PEP 302 Importer that wraps Python's "classic" import algorithm
+
+    ImpImporter(dirname) produces a PEP 302 importer that searches that
+    directory.  ImpImporter(None) produces a PEP 302 importer that searches
+    the current sys.path, plus any modules that are frozen or built-in.
+
+    Note that ImpImporter does not currently support being used by placement
+    on sys.meta_path.
+    """
+
+    def __init__(self, path=None):
+        self.path = path
+
+    def find_module(self, fullname, path=None):
+        # Note: we ignore 'path' argument since it is only used via meta_path
+        subname = fullname.split(".")[-1]
+        if subname != fullname and self.path is None:
+            return None
+        if self.path is None:
+            path = None
+        else:
+            path = [os.path.realpath(self.path)]
+        try:
+            file, filename, etc = imp.find_module(subname, path)
+        except ImportError:
+            return None
+        return ImpLoader(fullname, file, filename, etc)
+
+    def iter_modules(self, prefix=''):
+        if self.path is None or not os.path.isdir(self.path):
+            return
+
+        yielded = {}
+        import inspect
+
+        filenames = os.listdir(self.path)
+        filenames.sort()  # handle packages before same-named modules
+
+        for fn in filenames:
+            modname = inspect.getmodulename(fn)
+            if modname=='__init__' or modname in yielded:
+                continue
+
+            path = os.path.join(self.path, fn)
+            ispkg = False
+
+            if not modname and os.path.isdir(path) and '.' not in fn:
+                modname = fn
+                for fn in os.listdir(path):
+                    subname = inspect.getmodulename(fn)
+                    if subname=='__init__':
+                        ispkg = True
+                        break
+                else:
+                    continue    # not a package
+
+            if modname and '.' not in modname:
+                yielded[modname] = 1
+                yield prefix + modname, ispkg
+
+
+class ImpLoader:
+    """PEP 302 Loader that wraps Python's "classic" import algorithm
+    """
+    code = source = None
+
+    def __init__(self, fullname, file, filename, etc):
+        self.file = file
+        self.filename = filename
+        self.fullname = fullname
+        self.etc = etc
+
+    def load_module(self, fullname):
+        self._reopen()
+        try:
+            mod = imp.load_module(fullname, self.file, self.filename, self.etc)
+        finally:
+            if self.file:
+                self.file.close()
+        # Note: we don't set __loader__ because we want the module to look
+        # normal; i.e. this is just a wrapper for standard import machinery
+        return mod
+
+    def get_data(self, pathname):
+        return open(pathname, "rb").read()
+
+    def _reopen(self):
+        if self.file and self.file.closed:
+            mod_type = self.etc[2]
+            if mod_type==imp.PY_SOURCE:
+                self.file = open(self.filename, 'rU')
+            elif mod_type in (imp.PY_COMPILED, imp.C_EXTENSION):
+                self.file = open(self.filename, 'rb')
+
+    def _fix_name(self, fullname):
+        if fullname is None:
+            fullname = self.fullname
+        elif fullname != self.fullname:
+            raise ImportError("Loader for module %s cannot handle "
+                              "module %s" % (self.fullname, fullname))
+        return fullname
+
+    def is_package(self, fullname):
+        fullname = self._fix_name(fullname)
+        return self.etc[2]==imp.PKG_DIRECTORY
+
+    def get_code(self, fullname=None):
+        fullname = self._fix_name(fullname)
+        if self.code is None:
+            mod_type = self.etc[2]
+            if mod_type==imp.PY_SOURCE:
+                source = self.get_source(fullname)
+                self.code = compile(source, self.filename, 'exec')
+            elif mod_type==imp.PY_COMPILED:
+                self._reopen()
+                try:
+                    self.code = read_code(self.file)
+                finally:
+                    self.file.close()
+            elif mod_type==imp.PKG_DIRECTORY:
+                self.code = self._get_delegate().get_code()
+        return self.code
+
+    def get_source(self, fullname=None):
+        fullname = self._fix_name(fullname)
+        if self.source is None:
+            mod_type = self.etc[2]
+            if mod_type==imp.PY_SOURCE:
+                self._reopen()
+                try:
+                    self.source = self.file.read()
+                finally:
+                    self.file.close()
+            elif mod_type==imp.PY_COMPILED:
+                if os.path.exists(self.filename[:-1]):
+                    f = open(self.filename[:-1], 'rU')
+                    self.source = f.read()
+                    f.close()
+            elif mod_type==imp.PKG_DIRECTORY:
+                self.source = self._get_delegate().get_source()
+        return self.source
+
+
+    def _get_delegate(self):
+        return ImpImporter(self.filename).find_module('__init__')
+
+    def get_filename(self, fullname=None):
+        fullname = self._fix_name(fullname)
+        mod_type = self.etc[2]
+        if self.etc[2]==imp.PKG_DIRECTORY:
+            return self._get_delegate().get_filename()
+        elif self.etc[2] in (imp.PY_SOURCE, imp.PY_COMPILED, imp.C_EXTENSION):
+            return self.filename
+        return None
+
+
+try:
+    import zipimport
+    from zipimport import zipimporter
+
+    def iter_zipimport_modules(importer, prefix=''):
+        dirlist = zipimport._zip_directory_cache[importer.archive].keys()
+        dirlist.sort()
+        _prefix = importer.prefix
+        plen = len(_prefix)
+        yielded = {}
+        import inspect
+        for fn in dirlist:
+            if not fn.startswith(_prefix):
+                continue
+
+            fn = fn[plen:].split(os.sep)
+
+            if len(fn)==2 and fn[1].startswith('__init__.py'):
+                if fn[0] not in yielded:
+                    yielded[fn[0]] = 1
+                    yield fn[0], True
+
+            if len(fn)!=1:
+                continue
+
+            modname = inspect.getmodulename(fn[0])
+            if modname=='__init__':
+                continue
+
+            if modname and '.' not in modname and modname not in yielded:
+                yielded[modname] = 1
+                yield prefix + modname, False
+
+    iter_importer_modules.register(zipimporter, iter_zipimport_modules)
+
+except ImportError:
+    pass
+
+
+def get_importer(path_item):
+    """Retrieve a PEP 302 importer for the given path item
+
+    The returned importer is cached in sys.path_importer_cache
+    if it was newly created by a path hook.
+
+    If there is no importer, a wrapper around the basic import
+    machinery is returned. This wrapper is never inserted into
+    the importer cache (None is inserted instead).
+
+    The cache (or part of it) can be cleared manually if a
+    rescan of sys.path_hooks is necessary.
+    """
+    try:
+        importer = sys.path_importer_cache[path_item]
+    except KeyError:
+        for path_hook in sys.path_hooks:
+            try:
+                importer = path_hook(path_item)
+                break
+            except ImportError:
+                pass
+        else:
+            importer = None
+        sys.path_importer_cache.setdefault(path_item, importer)
+
+    if importer is None:
+        try:
+            importer = ImpImporter(path_item)
+        except ImportError:
+            importer = None
+    return importer
+
+
+def iter_importers(fullname=""):
+    """Yield PEP 302 importers for the given module name
+
+    If fullname contains a '.', the importers will be for the package
+    containing fullname, otherwise they will be importers for sys.meta_path,
+    sys.path, and Python's "classic" import machinery, in that order.  If
+    the named module is in a package, that package is imported as a side
+    effect of invoking this function.
+
+    Non PEP 302 mechanisms (e.g. the Windows registry) used by the
+    standard import machinery to find files in alternative locations
+    are partially supported, but are searched AFTER sys.path. Normally,
+    these locations are searched BEFORE sys.path, preventing sys.path
+    entries from shadowing them.
+
+    For this to cause a visible difference in behaviour, there must
+    be a module or package name that is accessible via both sys.path
+    and one of the non PEP 302 file system mechanisms. In this case,
+    the emulation will find the former version, while the builtin
+    import mechanism will find the latter.
+
+    Items of the following types can be affected by this discrepancy:
+        imp.C_EXTENSION, imp.PY_SOURCE, imp.PY_COMPILED, imp.PKG_DIRECTORY
+    """
+    if fullname.startswith('.'):
+        raise ImportError("Relative module names not supported")
+    if '.' in fullname:
+        # Get the containing package's __path__
+        pkg = '.'.join(fullname.split('.')[:-1])
+        if pkg not in sys.modules:
+            __import__(pkg)
+        path = getattr(sys.modules[pkg], '__path__', None) or []
+    else:
+        for importer in sys.meta_path:
+            yield importer
+        path = sys.path
+    for item in path:
+        yield get_importer(item)
+    if '.' not in fullname:
+        yield ImpImporter()
+
+def get_loader(module_or_name):
+    """Get a PEP 302 "loader" object for module_or_name
+
+    If the module or package is accessible via the normal import
+    mechanism, a wrapper around the relevant part of that machinery
+    is returned.  Returns None if the module cannot be found or imported.
+    If the named module is not already imported, its containing package
+    (if any) is imported, in order to establish the package __path__.
+
+    This function uses iter_importers(), and is thus subject to the same
+    limitations regarding platform-specific special import locations such
+    as the Windows registry.
+    """
+    if module_or_name in sys.modules:
+        module_or_name = sys.modules[module_or_name]
+    if isinstance(module_or_name, ModuleType):
+        module = module_or_name
+        loader = getattr(module, '__loader__', None)
+        if loader is not None:
+            return loader
+        fullname = module.__name__
+    else:
+        fullname = module_or_name
+    return find_loader(fullname)
+
+def find_loader(fullname):
+    """Find a PEP 302 "loader" object for fullname
+
+    If fullname contains dots, path must be the containing package's __path__.
+    Returns None if the module cannot be found or imported. This function uses
+    iter_importers(), and is thus subject to the same limitations regarding
+    platform-specific special import locations such as the Windows registry.
+    """
+    for importer in iter_importers(fullname):
+        loader = importer.find_module(fullname)
+        if loader is not None:
+            return loader
+
+    return None
+
+
+def extend_path(path, name):
+    """Extend a package's path.
+
+    Intended use is to place the following code in a package's __init__.py:
+
+        from pkgutil import extend_path
+        __path__ = extend_path(__path__, __name__)
+
+    This will add to the package's __path__ all subdirectories of
+    directories on sys.path named after the package.  This is useful
+    if one wants to distribute different parts of a single logical
+    package as multiple directories.
+
+    It also looks for *.pkg files beginning where * matches the name
+    argument.  This feature is similar to *.pth files (see site.py),
+    except that it doesn't special-case lines starting with 'import'.
+    A *.pkg file is trusted at face value: apart from checking for
+    duplicates, all entries found in a *.pkg file are added to the
+    path, regardless of whether they are exist the filesystem.  (This
+    is a feature.)
+
+    If the input path is not a list (as is the case for frozen
+    packages) it is returned unchanged.  The input path is not
+    modified; an extended copy is returned.  Items are only appended
+    to the copy at the end.
+
+    It is assumed that sys.path is a sequence.  Items of sys.path that
+    are not (unicode or 8-bit) strings referring to existing
+    directories are ignored.  Unicode items of sys.path that cause
+    errors when used as filenames may cause this function to raise an
+    exception (in line with os.path.isdir() behavior).
+    """
+
+    if not isinstance(path, list):
+        # This could happen e.g. when this is called from inside a
+        # frozen package.  Return the path unchanged in that case.
+        return path
+
+    pname = os.path.join(*name.split('.')) # Reconstitute as relative path
+    # Just in case os.extsep != '.'
+    sname = os.extsep.join(name.split('.'))
+    sname_pkg = sname + os.extsep + "pkg"
+    init_py = "__init__" + os.extsep + "py"
+
+    path = path[:] # Start with a copy of the existing path
+
+    for dir in sys.path:
+        if not isinstance(dir, basestring) or not os.path.isdir(dir):
+            continue
+        subdir = os.path.join(dir, pname)
+        # XXX This may still add duplicate entries to path on
+        # case-insensitive filesystems
+        initfile = os.path.join(subdir, init_py)
+        if subdir not in path and os.path.isfile(initfile):
+            path.append(subdir)
+        # XXX Is this the right thing for subpackages like zope.app?
+        # It looks for a file named "zope.app.pkg"
+        pkgfile = os.path.join(dir, sname_pkg)
+        if os.path.isfile(pkgfile):
+            try:
+                f = open(pkgfile)
+            except IOError, msg:
+                sys.stderr.write("Can't open %s: %s\n" %
+                                 (pkgfile, msg))
+            else:
+                for line in f:
+                    line = line.rstrip('\n')
+                    if not line or line.startswith('#'):
+                        continue
+                    path.append(line) # Don't check for existence!
+                f.close()
+
+    return path

Added: vendor/Python/current/Lib/plat-aix3/IN.py
===================================================================
--- vendor/Python/current/Lib/plat-aix3/IN.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-aix3/IN.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,126 @@
+# Generated by h2py from /usr/include/netinet/in.h
+
+# Included from net/nh.h
+
+# Included from sys/machine.h
+LITTLE_ENDIAN = 1234
+BIG_ENDIAN = 4321
+PDP_ENDIAN = 3412
+BYTE_ORDER = BIG_ENDIAN
+DEFAULT_GPR = 0xDEADBEEF
+MSR_EE = 0x8000
+MSR_PR = 0x4000
+MSR_FP = 0x2000
+MSR_ME = 0x1000
+MSR_FE = 0x0800
+MSR_FE0 = 0x0800
+MSR_SE = 0x0400
+MSR_BE = 0x0200
+MSR_IE = 0x0100
+MSR_FE1 = 0x0100
+MSR_AL = 0x0080
+MSR_IP = 0x0040
+MSR_IR = 0x0020
+MSR_DR = 0x0010
+MSR_PM = 0x0004
+DEFAULT_MSR = (MSR_EE | MSR_ME | MSR_AL | MSR_IR | MSR_DR)
+DEFAULT_USER_MSR = (DEFAULT_MSR | MSR_PR)
+CR_LT = 0x80000000
+CR_GT = 0x40000000
+CR_EQ = 0x20000000
+CR_SO = 0x10000000
+CR_FX = 0x08000000
+CR_FEX = 0x04000000
+CR_VX = 0x02000000
+CR_OX = 0x01000000
+XER_SO = 0x80000000
+XER_OV = 0x40000000
+XER_CA = 0x20000000
+def XER_COMP_BYTE(xer): return ((xer >> 8) & 0x000000FF)
+
+def XER_LENGTH(xer): return (xer & 0x0000007F)
+
+DSISR_IO = 0x80000000
+DSISR_PFT = 0x40000000
+DSISR_LOCK = 0x20000000
+DSISR_FPIO = 0x10000000
+DSISR_PROT = 0x08000000
+DSISR_LOOP = 0x04000000
+DSISR_DRST = 0x04000000
+DSISR_ST = 0x02000000
+DSISR_SEGB = 0x01000000
+DSISR_DABR = 0x00400000
+DSISR_EAR = 0x00100000
+SRR_IS_PFT = 0x40000000
+SRR_IS_ISPEC = 0x20000000
+SRR_IS_IIO = 0x10000000
+SRR_IS_PROT = 0x08000000
+SRR_IS_LOOP = 0x04000000
+SRR_PR_FPEN = 0x00100000
+SRR_PR_INVAL = 0x00080000
+SRR_PR_PRIV = 0x00040000
+SRR_PR_TRAP = 0x00020000
+SRR_PR_IMPRE = 0x00010000
+def ntohl(x): return (x)
+
+def ntohs(x): return (x)
+
+def htonl(x): return (x)
+
+def htons(x): return (x)
+
+IPPROTO_IP = 0
+IPPROTO_ICMP = 1
+IPPROTO_GGP = 3
+IPPROTO_TCP = 6
+IPPROTO_EGP = 8
+IPPROTO_PUP = 12
+IPPROTO_UDP = 17
+IPPROTO_IDP = 22
+IPPROTO_TP = 29
+IPPROTO_LOCAL = 63
+IPPROTO_EON = 80
+IPPROTO_BIP = 0x53
+IPPROTO_RAW = 255
+IPPROTO_MAX = 256
+IPPORT_RESERVED = 1024
+IPPORT_USERRESERVED = 5000
+IPPORT_TIMESERVER = 37
+def IN_CLASSA(i): return (((long)(i) & 0x80000000) == 0)
+
+IN_CLASSA_NET = 0xff000000
+IN_CLASSA_NSHIFT = 24
+IN_CLASSA_HOST = 0x00ffffff
+IN_CLASSA_MAX = 128
+def IN_CLASSB(i): return (((long)(i) & 0xc0000000) == 0x80000000)
+
+IN_CLASSB_NET = 0xffff0000
+IN_CLASSB_NSHIFT = 16
+IN_CLASSB_HOST = 0x0000ffff
+IN_CLASSB_MAX = 65536
+def IN_CLASSC(i): return (((long)(i) & 0xe0000000) == 0xc0000000)
+
+IN_CLASSC_NET = 0xffffff00
+IN_CLASSC_NSHIFT = 8
+IN_CLASSC_HOST = 0x000000ff
+def IN_CLASSD(i): return (((long)(i) & 0xf0000000) == 0xe0000000)
+
+def IN_MULTICAST(i): return IN_CLASSD(i)
+
+def IN_EXPERIMENTAL(i): return (((long)(i) & 0xe0000000) == 0xe0000000)
+
+def IN_BADCLASS(i): return (((long)(i) & 0xf0000000) == 0xf0000000)
+
+INADDR_ANY = 0x00000000
+INADDR_LOOPBACK = 0x7f000001
+INADDR_BROADCAST = 0xffffffff
+INADDR_NONE = 0xffffffff
+IN_LOOPBACKNET = 127
+IP_OPTIONS = 1
+IP_HDRINCL = 2
+IP_TOS = 3
+IP_TTL = 4
+IP_RECVOPTS = 5
+IP_RECVRETOPTS = 6
+IP_RECVDSTADDR = 7
+IP_RETOPTS = 8

Added: vendor/Python/current/Lib/plat-aix3/regen
===================================================================
--- vendor/Python/current/Lib/plat-aix3/regen	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-aix3/regen	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,8 @@
+#! /bin/sh
+case `uname -sv` in
+'AIX 3'*)  ;;
+*)      echo Probably not on an AIX 3 system 1>&2
+        exit 1;;
+esac
+set -v
+h2py.py -i '(u_long)' /usr/include/netinet/in.h


Property changes on: vendor/Python/current/Lib/plat-aix3/regen
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/plat-aix4/IN.py
===================================================================
--- vendor/Python/current/Lib/plat-aix4/IN.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-aix4/IN.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,165 @@
+# Generated by h2py from /usr/include/netinet/in.h
+
+# Included from net/nh.h
+
+# Included from sys/machine.h
+LITTLE_ENDIAN = 1234
+BIG_ENDIAN = 4321
+PDP_ENDIAN = 3412
+BYTE_ORDER = BIG_ENDIAN
+DEFAULT_GPR = 0xDEADBEEF
+MSR_EE = 0x8000
+MSR_PR = 0x4000
+MSR_FP = 0x2000
+MSR_ME = 0x1000
+MSR_FE = 0x0800
+MSR_FE0 = 0x0800
+MSR_SE = 0x0400
+MSR_BE = 0x0200
+MSR_IE = 0x0100
+MSR_FE1 = 0x0100
+MSR_AL = 0x0080
+MSR_IP = 0x0040
+MSR_IR = 0x0020
+MSR_DR = 0x0010
+MSR_PM = 0x0004
+DEFAULT_MSR = (MSR_EE | MSR_ME | MSR_AL | MSR_IR | MSR_DR)
+DEFAULT_USER_MSR = (DEFAULT_MSR | MSR_PR)
+CR_LT = 0x80000000
+CR_GT = 0x40000000
+CR_EQ = 0x20000000
+CR_SO = 0x10000000
+CR_FX = 0x08000000
+CR_FEX = 0x04000000
+CR_VX = 0x02000000
+CR_OX = 0x01000000
+XER_SO = 0x80000000
+XER_OV = 0x40000000
+XER_CA = 0x20000000
+def XER_COMP_BYTE(xer): return ((xer >> 8) & 0x000000FF)
+
+def XER_LENGTH(xer): return (xer & 0x0000007F)
+
+DSISR_IO = 0x80000000
+DSISR_PFT = 0x40000000
+DSISR_LOCK = 0x20000000
+DSISR_FPIO = 0x10000000
+DSISR_PROT = 0x08000000
+DSISR_LOOP = 0x04000000
+DSISR_DRST = 0x04000000
+DSISR_ST = 0x02000000
+DSISR_SEGB = 0x01000000
+DSISR_DABR = 0x00400000
+DSISR_EAR = 0x00100000
+SRR_IS_PFT = 0x40000000
+SRR_IS_ISPEC = 0x20000000
+SRR_IS_IIO = 0x10000000
+SRR_IS_GUARD = 0x10000000
+SRR_IS_PROT = 0x08000000
+SRR_IS_LOOP = 0x04000000
+SRR_PR_FPEN = 0x00100000
+SRR_PR_INVAL = 0x00080000
+SRR_PR_PRIV = 0x00040000
+SRR_PR_TRAP = 0x00020000
+SRR_PR_IMPRE = 0x00010000
+def BUID_7F_SRVAL(raddr): return (0x87F00000 | (((uint)(raddr)) >> 28))
+
+BT_256M = 0x1FFC
+BT_128M = 0x0FFC
+BT_64M = 0x07FC
+BT_32M = 0x03FC
+BT_16M = 0x01FC
+BT_8M = 0x00FC
+BT_4M = 0x007C
+BT_2M = 0x003C
+BT_1M = 0x001C
+BT_512K = 0x000C
+BT_256K = 0x0004
+BT_128K = 0x0000
+BT_NOACCESS = 0x0
+BT_RDONLY = 0x1
+BT_WRITE = 0x2
+BT_VS = 0x2
+BT_VP = 0x1
+def BAT_ESEG(dbatu): return (((uint)(dbatu) >> 28))
+
+MIN_BAT_SIZE = 0x00020000
+MAX_BAT_SIZE = 0x10000000
+def ntohl(x): return (x)
+
+def ntohs(x): return (x)
+
+def htonl(x): return (x)
+
+def htons(x): return (x)
+
+IPPROTO_IP = 0
+IPPROTO_ICMP = 1
+IPPROTO_IGMP = 2
+IPPROTO_GGP = 3
+IPPROTO_TCP = 6
+IPPROTO_EGP = 8
+IPPROTO_PUP = 12
+IPPROTO_UDP = 17
+IPPROTO_IDP = 22
+IPPROTO_TP = 29
+IPPROTO_LOCAL = 63
+IPPROTO_EON = 80
+IPPROTO_BIP = 0x53
+IPPROTO_RAW = 255
+IPPROTO_MAX = 256
+IPPORT_RESERVED = 1024
+IPPORT_USERRESERVED = 5000
+IPPORT_TIMESERVER = 37
+def IN_CLASSA(i): return (((long)(i) & 0x80000000) == 0)
+
+IN_CLASSA_NET = 0xff000000
+IN_CLASSA_NSHIFT = 24
+IN_CLASSA_HOST = 0x00ffffff
+IN_CLASSA_MAX = 128
+def IN_CLASSB(i): return (((long)(i) & 0xc0000000) == 0x80000000)
+
+IN_CLASSB_NET = 0xffff0000
+IN_CLASSB_NSHIFT = 16
+IN_CLASSB_HOST = 0x0000ffff
+IN_CLASSB_MAX = 65536
+def IN_CLASSC(i): return (((long)(i) & 0xe0000000) == 0xc0000000)
+
+IN_CLASSC_NET = 0xffffff00
+IN_CLASSC_NSHIFT = 8
+IN_CLASSC_HOST = 0x000000ff
+def IN_CLASSD(i): return (((long)(i) & 0xf0000000) == 0xe0000000)
+
+def IN_MULTICAST(i): return IN_CLASSD(i)
+
+IN_CLASSD_NET = 0xf0000000
+IN_CLASSD_NSHIFT = 28
+IN_CLASSD_HOST = 0x0fffffff
+INADDR_UNSPEC_GROUP = 0xe0000000
+INADDR_ALLHOSTS_GROUP = 0xe0000001
+INADDR_MAX_LOCAL_GROUP = 0xe00000ff
+def IN_EXPERIMENTAL(i): return (((long)(i) & 0xe0000000) == 0xe0000000)
+
+def IN_BADCLASS(i): return (((long)(i) & 0xf0000000) == 0xf0000000)
+
+INADDR_ANY = 0x00000000
+INADDR_BROADCAST = 0xffffffff
+INADDR_LOOPBACK = 0x7f000001
+INADDR_NONE = 0xffffffff
+IN_LOOPBACKNET = 127
+IP_OPTIONS = 1
+IP_HDRINCL = 2
+IP_TOS = 3
+IP_TTL = 4
+IP_RECVOPTS = 5
+IP_RECVRETOPTS = 6
+IP_RECVDSTADDR = 7
+IP_RETOPTS = 8
+IP_MULTICAST_IF = 9
+IP_MULTICAST_TTL = 10
+IP_MULTICAST_LOOP = 11
+IP_ADD_MEMBERSHIP = 12
+IP_DROP_MEMBERSHIP = 13
+IP_DEFAULT_MULTICAST_TTL = 1
+IP_DEFAULT_MULTICAST_LOOP = 1
+IP_MAX_MEMBERSHIPS = 20

Added: vendor/Python/current/Lib/plat-aix4/regen
===================================================================
--- vendor/Python/current/Lib/plat-aix4/regen	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-aix4/regen	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,8 @@
+#! /bin/sh
+case `uname -sv` in
+'AIX 4'*)  ;;
+*)      echo Probably not on an AIX 4 system 1>&2
+        exit 1;;
+esac
+set -v
+h2py.py -i '(u_long)' /usr/include/netinet/in.h


Property changes on: vendor/Python/current/Lib/plat-aix4/regen
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/plat-atheos/IN.py
===================================================================
--- vendor/Python/current/Lib/plat-atheos/IN.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-atheos/IN.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,944 @@
+# Generated by h2py from /include/netinet/in.h
+_NETINET_IN_H = 1
+
+# Included from features.h
+_FEATURES_H = 1
+__USE_ANSI = 1
+__FAVOR_BSD = 1
+_ISOC9X_SOURCE = 1
+_POSIX_SOURCE = 1
+_POSIX_C_SOURCE = 199506L
+_XOPEN_SOURCE = 500
+_XOPEN_SOURCE_EXTENDED = 1
+_LARGEFILE64_SOURCE = 1
+_BSD_SOURCE = 1
+_SVID_SOURCE = 1
+_BSD_SOURCE = 1
+_SVID_SOURCE = 1
+__USE_ISOC9X = 1
+_POSIX_SOURCE = 1
+_POSIX_C_SOURCE = 2
+_POSIX_C_SOURCE = 199506L
+__USE_POSIX = 1
+__USE_POSIX2 = 1
+__USE_POSIX199309 = 1
+__USE_POSIX199506 = 1
+__USE_XOPEN = 1
+__USE_XOPEN_EXTENDED = 1
+__USE_UNIX98 = 1
+_LARGEFILE_SOURCE = 1
+__USE_XOPEN_EXTENDED = 1
+__USE_LARGEFILE = 1
+__USE_LARGEFILE64 = 1
+__USE_FILE_OFFSET64 = 1
+__USE_MISC = 1
+__USE_BSD = 1
+__USE_SVID = 1
+__USE_GNU = 1
+__USE_REENTRANT = 1
+__STDC_IEC_559__ = 1
+__STDC_IEC_559_COMPLEX__ = 1
+__GNU_LIBRARY__ = 6
+__GLIBC__ = 2
+__GLIBC_MINOR__ = 1
+
+# Included from sys/cdefs.h
+_SYS_CDEFS_H = 1
+def __PMT(args): return args
+
+def __P(args): return args
+
+def __PMT(args): return args
+
+def __P(args): return ()
+
+def __PMT(args): return ()
+
+def __STRING(x): return #x
+
+def __STRING(x): return "x"
+
+def __ASMNAME(cname): return __ASMNAME2 (__USER_LABEL_PREFIX__, cname)
+
+def __attribute__(xyz): return
+
+__USE_EXTERN_INLINES = 1
+
+# Included from gnu/stubs.h
+
+# Included from limits.h
+_LIBC_LIMITS_H_ = 1
+
+# Included from bits/posix1_lim.h
+_BITS_POSIX1_LIM_H = 1
+_POSIX_AIO_LISTIO_MAX = 2
+_POSIX_AIO_MAX = 1
+_POSIX_ARG_MAX = 4096
+_POSIX_CHILD_MAX = 6
+_POSIX_DELAYTIMER_MAX = 32
+_POSIX_LINK_MAX = 8
+_POSIX_MAX_CANON = 255
+_POSIX_MAX_INPUT = 255
+_POSIX_MQ_OPEN_MAX = 8
+_POSIX_MQ_PRIO_MAX = 32
+_POSIX_NGROUPS_MAX = 0
+_POSIX_OPEN_MAX = 16
+_POSIX_FD_SETSIZE = _POSIX_OPEN_MAX
+_POSIX_NAME_MAX = 14
+_POSIX_PATH_MAX = 255
+_POSIX_PIPE_BUF = 512
+_POSIX_RTSIG_MAX = 8
+_POSIX_SEM_NSEMS_MAX = 256
+_POSIX_SEM_VALUE_MAX = 32767
+_POSIX_SIGQUEUE_MAX = 32
+_POSIX_SSIZE_MAX = 32767
+_POSIX_STREAM_MAX = 8
+_POSIX_TZNAME_MAX = 3
+_POSIX_QLIMIT = 1
+_POSIX_HIWAT = _POSIX_PIPE_BUF
+_POSIX_UIO_MAXIOV = 16
+_POSIX_TTY_NAME_MAX = 9
+_POSIX_TIMER_MAX = 32
+_POSIX_LOGIN_NAME_MAX = 9
+_POSIX_CLOCKRES_MIN = 20000000
+
+# Included from bits/local_lim.h
+
+# Included from posix/limits.h
+CHAR_BIT = 8
+CHAR_MAX = 127
+CHAR_MIN = (-128)
+INT_MAX = 2147483647
+INT_MIN = (-2147483647-1)
+LONG_MAX = 2147483647L
+LONG_MIN = (-2147483647L-1L)
+SCHAR_MAX = 127
+SCHAR_MIN = (-128)
+SHRT_MAX = 32767
+SHRT_MIN = (-32768)
+UCHAR_MAX = 255
+USHRT_MAX = 65535
+_POSIX_ARG_MAX = 131072
+_POSIX_CHILD_MAX = 4096
+_POSIX_LINK_MAX = 1
+_POSIX_MAX_CANON = 126
+_POSIX_MAX_INPUT = 126
+_POSIX_NAME_MAX = 256
+_POSIX_NGROUPS_MAX = 32
+_POSIX_OPEN_MAX = 256
+_POSIX_PATH_MAX = 255
+_POSIX_PIPE_BUF = 512
+_POSIX_SSIZE_MAX = 2147483647
+_POSIX_STREAM_MAX = 256
+_POSIX_TZNAME_MAX = 5
+NGROUPS_MAX = 32
+ARG_MAX = 131072
+CHILD_MAX = 4096
+OPEN_MAX = 256
+LINK_MAX = 1
+MAX_CANON = 126
+MAX_INPUT = 126
+NAME_MAX = 255
+PATH_MAX = 4096
+PIPE_BUF = 4096
+SSIZE_MAX = 2147483647
+MAXSYMLINKS = 16
+AIO_PRIO_DELTA_MAX = 20
+SSIZE_MAX = INT_MAX
+NGROUPS_MAX = _POSIX_NGROUPS_MAX
+
+# Included from bits/posix2_lim.h
+_BITS_POSIX2_LIM_H = 1
+_POSIX2_BC_BASE_MAX = 99
+_POSIX2_BC_DIM_MAX = 2048
+_POSIX2_BC_SCALE_MAX = 99
+_POSIX2_BC_STRING_MAX = 1000
+_POSIX2_COLL_WEIGHTS_MAX = 255
+_POSIX2_EQUIV_CLASS_MAX = 255
+_POSIX2_EXPR_NEST_MAX = 32
+_POSIX2_LINE_MAX = 2048
+_POSIX2_RE_DUP_MAX = 255
+_POSIX2_CHARCLASS_NAME_MAX = 2048
+BC_BASE_MAX = _POSIX2_BC_BASE_MAX
+BC_DIM_MAX = _POSIX2_BC_DIM_MAX
+BC_SCALE_MAX = _POSIX2_BC_SCALE_MAX
+BC_STRING_MAX = _POSIX2_BC_STRING_MAX
+COLL_WEIGHTS_MAX = _POSIX2_COLL_WEIGHTS_MAX
+EQUIV_CLASS_MAX = _POSIX2_EQUIV_CLASS_MAX
+EXPR_NEST_MAX = _POSIX2_EXPR_NEST_MAX
+LINE_MAX = _POSIX2_LINE_MAX
+RE_DUP_MAX = _POSIX2_RE_DUP_MAX
+CHARCLASS_NAME_MAX = _POSIX2_CHARCLASS_NAME_MAX
+
+# Included from bits/xopen_lim.h
+_XOPEN_LIM_H = 1
+
+# Included from bits/stdio_lim.h
+L_tmpnam = 20
+TMP_MAX = 238328
+FILENAME_MAX = 4096
+L_ctermid = 9
+L_cuserid = 9
+FOPEN_MAX = 256
+STREAM_MAX = FOPEN_MAX
+TZNAME_MAX = _POSIX_TZNAME_MAX
+_XOPEN_IOV_MAX = _POSIX_UIO_MAXIOV
+NL_ARGMAX = _POSIX_ARG_MAX
+NL_LANGMAX = _POSIX2_LINE_MAX
+NL_MSGMAX = INT_MAX
+NL_NMAX = INT_MAX
+NL_SETMAX = INT_MAX
+NL_TEXTMAX = INT_MAX
+NZERO = 20
+MB_LEN_MAX = 6
+_LIMITS_H = 1
+CHAR_BIT = 8
+SCHAR_MIN = (-128)
+SCHAR_MAX = 127
+UCHAR_MAX = 255
+CHAR_MIN = 0
+CHAR_MAX = UCHAR_MAX
+CHAR_MIN = SCHAR_MIN
+CHAR_MAX = SCHAR_MAX
+SHRT_MIN = (-32768)
+SHRT_MAX = 32767
+USHRT_MAX = 65535
+INT_MIN = (-INT_MAX - 1)
+INT_MAX = 2147483647
+UINT_MAX = 4294967295
+LONG_MAX = 9223372036854775807L
+LONG_MAX = 2147483647L
+LONG_MIN = (-LONG_MAX - 1L)
+ULONG_MAX = 4294967295L
+
+# Included from stdint.h
+_STDINT_H = 1
+
+# Included from bits/wordsize.h
+__WORDSIZE = 32
+def __INT64_C(c): return c ## L
+
+def __UINT64_C(c): return c ## UL
+
+def __INT64_C(c): return c ## LL
+
+def __UINT64_C(c): return c ## ULL
+
+INT8_MIN = (-128)
+INT16_MIN = (-32767-1)
+INT32_MIN = (-2147483647-1)
+INT64_MIN = (-__INT64_C(9223372036854775807)-1)
+INT8_MAX = (127)
+INT16_MAX = (32767)
+INT32_MAX = (2147483647)
+INT64_MAX = (__INT64_C(9223372036854775807))
+UINT64_MAX = (__UINT64_C(18446744073709551615))
+INT_LEAST8_MIN = (-128)
+INT_LEAST16_MIN = (-32767-1)
+INT_LEAST32_MIN = (-2147483647-1)
+INT_LEAST64_MIN = (-__INT64_C(9223372036854775807)-1)
+INT_LEAST8_MAX = (127)
+INT_LEAST16_MAX = (32767)
+INT_LEAST32_MAX = (2147483647)
+INT_LEAST64_MAX = (__INT64_C(9223372036854775807))
+UINT_LEAST64_MAX = (__UINT64_C(18446744073709551615))
+INT_FAST8_MIN = (-128)
+INT_FAST16_MIN = (-9223372036854775807L-1)
+INT_FAST32_MIN = (-9223372036854775807L-1)
+INT_FAST16_MIN = (-2147483647-1)
+INT_FAST32_MIN = (-2147483647-1)
+INT_FAST64_MIN = (-__INT64_C(9223372036854775807)-1)
+INT_FAST8_MAX = (127)
+INT_FAST16_MAX = (9223372036854775807L)
+INT_FAST32_MAX = (9223372036854775807L)
+INT_FAST16_MAX = (2147483647)
+INT_FAST32_MAX = (2147483647)
+INT_FAST64_MAX = (__INT64_C(9223372036854775807))
+UINT_FAST64_MAX = (__UINT64_C(18446744073709551615))
+INTPTR_MIN = (-9223372036854775807L-1)
+INTPTR_MAX = (9223372036854775807L)
+INTPTR_MIN = (-2147483647-1)
+INTPTR_MAX = (2147483647)
+INTMAX_MIN = (-__INT64_C(9223372036854775807)-1)
+INTMAX_MAX = (__INT64_C(9223372036854775807))
+UINTMAX_MAX = (__UINT64_C(18446744073709551615))
+PTRDIFF_MIN = (-9223372036854775807L-1)
+PTRDIFF_MAX = (9223372036854775807L)
+PTRDIFF_MIN = (-2147483647-1)
+PTRDIFF_MAX = (2147483647)
+SIG_ATOMIC_MIN = (-2147483647-1)
+SIG_ATOMIC_MAX = (2147483647)
+WCHAR_MIN = (-2147483647-1)
+WCHAR_MAX = (2147483647)
+WINT_MIN = (0)
+def INT8_C(c): return c
+
+def INT16_C(c): return c
+
+def INT32_C(c): return c
+
+def INT64_C(c): return c ## L
+
+def INT64_C(c): return c ## LL
+
+def UINT8_C(c): return c ## U
+
+def UINT16_C(c): return c ## U
+
+def UINT32_C(c): return c ## U
+
+def UINT64_C(c): return c ## UL
+
+def UINT64_C(c): return c ## ULL
+
+def INTMAX_C(c): return c ## L
+
+def UINTMAX_C(c): return c ## UL
+
+def INTMAX_C(c): return c ## LL
+
+def UINTMAX_C(c): return c ## ULL
+
+
+# Included from sys/types.h
+_SYS_TYPES_H = 1
+
+# Included from bits/types.h
+_BITS_TYPES_H = 1
+__FD_SETSIZE = 1024
+def __FDELT(d): return ((d) / __NFDBITS)
+
+
+# Included from bits/pthreadtypes.h
+
+# Included from time.h
+_TIME_H = 1
+
+# Included from bits/time.h
+
+# Included from posix/time.h
+
+# Included from posix/types.h
+MAXHOSTNAMELEN = 64
+FD_SETSIZE = 1024
+CLOCKS_PER_SEC = 1000000
+_BITS_TIME_H = 1
+CLOCKS_PER_SEC = 1000000
+CLK_TCK = 100
+_STRUCT_TIMEVAL = 1
+CLK_TCK = CLOCKS_PER_SEC
+__clock_t_defined = 1
+__time_t_defined = 1
+__timespec_defined = 1
+def __isleap(year): return \
+
+__BIT_TYPES_DEFINED__ = 1
+
+# Included from endian.h
+_ENDIAN_H = 1
+__LITTLE_ENDIAN = 1234
+__BIG_ENDIAN = 4321
+__PDP_ENDIAN = 3412
+
+# Included from bits/endian.h
+__BYTE_ORDER = __LITTLE_ENDIAN
+__FLOAT_WORD_ORDER = __BYTE_ORDER
+LITTLE_ENDIAN = __LITTLE_ENDIAN
+BIG_ENDIAN = __BIG_ENDIAN
+PDP_ENDIAN = __PDP_ENDIAN
+BYTE_ORDER = __BYTE_ORDER
+
+# Included from sys/select.h
+_SYS_SELECT_H = 1
+
+# Included from bits/select.h
+def __FD_ZERO(fdsp): return \
+
+def __FD_ZERO(set): return \
+
+
+# Included from bits/sigset.h
+_SIGSET_H_types = 1
+_SIGSET_H_fns = 1
+def __sigmask(sig): return \
+
+def __sigemptyset(set): return \
+
+def __sigfillset(set): return \
+
+def __sigisemptyset(set): return \
+
+FD_SETSIZE = __FD_SETSIZE
+def FD_ZERO(fdsetp): return __FD_ZERO (fdsetp)
+
+
+# Included from sys/sysmacros.h
+_SYS_SYSMACROS_H = 1
+def major(dev): return ( ((  (dev) >> 8) & 0xff))
+
+def minor(dev): return ( ((dev) & 0xff))
+
+
+# Included from bits/socket.h
+PF_UNSPEC = 0
+PF_LOCAL = 1
+PF_UNIX = PF_LOCAL
+PF_FILE = PF_LOCAL
+PF_INET = 2
+PF_AX25 = 3
+PF_IPX = 4
+PF_APPLETALK = 5
+PF_NETROM = 6
+PF_BRIDGE = 7
+PF_ATMPVC = 8
+PF_X25 = 9
+PF_INET6 = 10
+PF_ROSE = 11
+PF_DECnet = 12
+PF_NETBEUI = 13
+PF_SECURITY = 14
+PF_KEY = 15
+PF_NETLINK = 16
+PF_ROUTE = PF_NETLINK
+PF_PACKET = 17
+PF_ASH = 18
+PF_ECONET = 19
+PF_ATMSVC = 20
+PF_SNA = 22
+PF_IRDA = 23
+PF_MAX = 32
+AF_UNSPEC = PF_UNSPEC
+AF_LOCAL = PF_LOCAL
+AF_UNIX = PF_UNIX
+AF_FILE = PF_FILE
+AF_INET = PF_INET
+AF_AX25 = PF_AX25
+AF_IPX = PF_IPX
+AF_APPLETALK = PF_APPLETALK
+AF_NETROM = PF_NETROM
+AF_BRIDGE = PF_BRIDGE
+AF_ATMPVC = PF_ATMPVC
+AF_X25 = PF_X25
+AF_INET6 = PF_INET6
+AF_ROSE = PF_ROSE
+AF_DECnet = PF_DECnet
+AF_NETBEUI = PF_NETBEUI
+AF_SECURITY = PF_SECURITY
+AF_KEY = PF_KEY
+AF_NETLINK = PF_NETLINK
+AF_ROUTE = PF_ROUTE
+AF_PACKET = PF_PACKET
+AF_ASH = PF_ASH
+AF_ECONET = PF_ECONET
+AF_ATMSVC = PF_ATMSVC
+AF_SNA = PF_SNA
+AF_IRDA = PF_IRDA
+AF_MAX = PF_MAX
+SOL_RAW = 255
+SOL_DECNET = 261
+SOL_X25 = 262
+SOL_PACKET = 263
+SOL_ATM = 264
+SOL_AAL = 265
+SOL_IRDA = 266
+SOMAXCONN = 128
+
+# Included from bits/sockaddr.h
+_BITS_SOCKADDR_H = 1
+def __SOCKADDR_COMMON(sa_prefix): return \
+
+_SS_SIZE = 128
+def CMSG_FIRSTHDR(mhdr): return \
+
+
+# Included from atheos/socket.h
+
+# Included from atheos/types.h
+OS_NAME_LENGTH = 64
+TRUE = 1
+FALSE = 0
+
+# Included from atheos/filesystem.h
+
+# Included from atheos/atomic.h
+
+# Included from atheos/typedefs.h
+
+# Included from atheos/fs_attribs.h
+
+# Included from atheos/kernel.h
+
+# Included from atheos/kdebug.h
+
+# Included from atheos/threads.h
+TF_DEADLOCK = 0x0001
+DB_PACKET_SIZE = 128
+DB_PORT_COUNT = 16
+DBP_PRINTK = 0
+DBP_DEBUGGER = 2
+
+# Included from atheos/stdlib.h
+
+# Included from atheos/string.h
+def COMMON(x): return \
+
+def COMMON(x): return \
+
+
+# Included from atheos/schedule.h
+
+# Included from atheos/timer.h
+
+# Included from posix/resource.h
+RUSAGE_SELF = 0
+RUSAGE_CHILDREN = -1
+RLIMIT_CPU = 0
+RLIMIT_FSIZE = 1
+RLIMIT_DATA = 2
+RLIMIT_STACK = 3
+RLIMIT_CORE = 4
+RLIMIT_RSS = 5
+RLIMIT_MEMLOCK = 6
+RLIMIT_NPROC = 7
+RLIMIT_NOFILE = 8
+RLIMIT_AS = 9
+RLIM_NLIMITS = 10
+
+# Included from atheos/v86.h
+
+# Included from atheos/areas.h
+MEMF_REAL = 0x00000002
+MEMF_USER = 0x00000004
+MEMF_BUFFER = 0x00000008
+MEMF_KERNEL = 0x00000010
+MEMF_OKTOFAILHACK = 0x00000020
+MEMF_PRI_MASK = 0x000000ff
+MEMF_NOBLOCK = 0x00000100
+MEMF_CLEAR = 0x00010000
+MEMF_LOCKED = 0x10000000
+PAGE_SHIFT = 12
+PGDIR_SHIFT = 22
+def PAGE_ALIGN(addr): return (((addr)+PAGE_SIZE-1)&PAGE_MASK)
+
+AREA_NO_LOCK = 0
+AREA_LAZY_LOCK = 1
+AREA_FULL_LOCK = 2
+AREA_CONTIGUOUS = 3
+AREA_READ = 0x00000001
+AREA_WRITE = 0x00000002
+AREA_EXEC = 0x00000004
+AREA_FULL_ACCESS = (AREA_READ | AREA_WRITE | AREA_EXEC)
+AREA_KERNEL = 0x00000008
+AREA_UNMAP_PHYS = 0x00000010
+AREA_ANY_ADDRESS = 0x00000000
+AREA_EXACT_ADDRESS = 0x00000100
+AREA_BASE_ADDRESS = 0x00000200
+AREA_CLONE_ADDRESS = 0x00000300
+AREA_ADDR_SPEC_MASK = 0x00000f00
+AREA_TOP_DOWN = 0x00001000
+AREA_REMAPPED = 0x0020
+AREA_SHARED = 0x0040
+AREA_GROWSDOWN = 0x0080
+AREA_FIRST_KERNEL_ADDRESS = 0x00100000
+AREA_LAST_KERNEL_ADDRESS = 0x7fffffff
+AREA_FIRST_USER_ADDRESS = 0x80000000
+AREA_LAST_USER_ADDRESS = 0xffffffff
+MAX_CPU_COUNT = 16
+def kfree(p): return kassertw( __kfree(p) == 0 )
+
+
+# Included from posix/dirent.h
+MAXNAMLEN = NAME_MAX
+MAXNAMLEN = 255
+
+# Included from dirent.h
+_DIRENT_H = 1
+
+# Included from bits/dirent.h
+def _D_ALLOC_NAMLEN(d): return (_D_EXACT_NAMLEN (d) + 1)
+
+def IFTODT(mode): return (((mode) & 0170000) >> 12)
+
+def DTTOIF(dirtype): return ((dirtype) << 12)
+
+def dirfd(dirp): return _DIR_dirfd (dirp)
+
+MAXNAMLEN = NAME_MAX
+MAXNAMLEN = 255
+
+# Included from posix/stat.h
+S_IFMT = 00170000
+S_IFSOCK = 0140000
+S_IFLNK = 0120000
+S_IFREG = 0100000
+S_IFBLK = 0060000
+S_IFDIR = 0040000
+S_IFCHR = 0020000
+S_IFIFO = 0010000
+S_ISUID = 0004000
+S_ISGID = 0002000
+S_ISVTX = 0001000
+def S_ISLNK(m): return (((m) & S_IFMT) == S_IFLNK)
+
+def S_ISREG(m): return (((m) & S_IFMT) == S_IFREG)
+
+def S_ISDIR(m): return (((m) & S_IFMT) == S_IFDIR)
+
+def S_ISCHR(m): return (((m) & S_IFMT) == S_IFCHR)
+
+def S_ISBLK(m): return (((m) & S_IFMT) == S_IFBLK)
+
+def S_ISFIFO(m): return (((m) & S_IFMT) == S_IFIFO)
+
+def S_ISSOCK(m): return (((m) & S_IFMT) == S_IFSOCK)
+
+S_IRWXU = 00700
+S_IRUSR = 00400
+S_IWUSR = 00200
+S_IXUSR = 00100
+S_IRWXG = 00070
+S_IRGRP = 00040
+S_IWGRP = 00020
+S_IXGRP = 00010
+S_IRWXO = 00007
+S_IROTH = 00004
+S_IWOTH = 00002
+S_IXOTH = 00001
+S_IRWXUGO = (S_IRWXU|S_IRWXG|S_IRWXO)
+S_IALLUGO = (S_ISUID|S_ISGID|S_ISVTX|S_IRWXUGO)
+S_IRUGO = (S_IRUSR|S_IRGRP|S_IROTH)
+S_IWUGO = (S_IWUSR|S_IWGRP|S_IWOTH)
+S_IXUGO = (S_IXUSR|S_IXGRP|S_IXOTH)
+_STAT_VER_KERNEL = 0
+
+# Included from posix/fcntl.h
+O_ACCMODE = 0003
+O_RWMASK = O_ACCMODE
+O_RDONLY = 00
+O_WRONLY = 01
+O_RDWR = 02
+O_CREAT = 0100
+O_EXCL = 0200
+O_NOCTTY = 0400
+O_TRUNC = 01000
+O_APPEND = 02000
+O_NONBLOCK = 04000
+O_NDELAY = O_NONBLOCK
+O_SYNC = 010000
+O_FSYNC = O_SYNC
+O_ASYNC = 020000
+FASYNC = O_ASYNC
+O_DIRECTORY = 040000
+O_NOTRAVERSE = 0100000
+O_NOFOLLOW = O_NOTRAVERSE
+F_DUPFD = 0
+F_GETFD = 1
+F_SETFD = 2
+F_GETFL = 3
+F_SETFL = 4
+F_GETLK = 5
+F_SETLK = 6
+F_SETLKW = 7
+F_SETOWN = 8
+F_GETOWN = 9
+F_SETSIG = 10
+F_GETSIG = 11
+F_COPYFD = 12
+FD_CLOEXEC = 1
+F_RDLCK = 0
+F_WRLCK = 1
+F_UNLCK = 2
+F_EXLCK = 4
+F_SHLCK = 8
+LOCK_SH = 1
+LOCK_EX = 2
+LOCK_NB = 4
+LOCK_UN = 8
+
+# Included from posix/uio.h
+UIO_FASTIOV = 8
+UIO_MAXIOV = 1024
+MNTF_READONLY = 0x0001
+FS_IS_READONLY = 0x00000001
+FS_IS_REMOVABLE = 0x00000002
+FS_IS_PERSISTENT = 0x00000004
+FS_IS_SHARED = 0x00000008
+FS_IS_BLOCKBASED = 0x00000010
+FS_CAN_MOUNT = 0x00000020
+FS_HAS_MIME = 0x00010000
+FS_HAS_ATTR = 0x00020000
+FS_HAS_QUERY = 0x00040000
+FSINFO_VERSION = 1
+WSTAT_MODE = 0x0001
+WSTAT_UID = 0x0002
+WSTAT_GID = 0x0004
+WSTAT_SIZE = 0x0008
+WSTAT_ATIME = 0x0010
+WSTAT_MTIME = 0x0020
+WSTAT_CTIME = 0x0040
+WFSSTAT_NAME = 0x0001
+FSDRIVER_API_VERSION = 1
+
+# Included from net/nettypes.h
+IP_ADR_LEN = 4
+INADDR_ANY = 0x00000000
+INADDR_BROADCAST = 0xffffffff
+INADDR_LOOPBACK = 0x7f000001
+def CMSG_ALIGN(len): return ( ((len)+sizeof(long)-1) & ~(sizeof(long)-1) )
+
+PROT_SOCK = 1024
+SHUTDOWN_MASK = 3
+RCV_SHUTDOWN = 1
+SEND_SHUTDOWN = 2
+SOCK_STREAM = 1
+SOCK_DGRAM = 2
+SOCK_RAW = 3
+SOCK_RDM = 4
+SOCK_SEQPACKET = 5
+SOCK_PACKET = 10
+PF_UNSPEC = 0
+PF_LOCAL = 1
+PF_UNIX = PF_LOCAL
+PF_FILE = PF_LOCAL
+PF_INET = 2
+PF_AX25 = 3
+PF_IPX = 4
+PF_APPLETALK = 5
+PF_NETROM = 6
+PF_BRIDGE = 7
+PF_ATMPVC = 8
+PF_X25 = 9
+PF_INET6 = 10
+PF_ROSE = 11
+PF_DECnet = 12
+PF_NETBEUI = 13
+PF_SECURITY = 14
+PF_KEY = 15
+PF_NETLINK = 16
+PF_ROUTE = PF_NETLINK
+PF_PACKET = 17
+PF_ASH = 18
+PF_ECONET = 19
+PF_ATMSVC = 20
+PF_SNA = 22
+PF_IRDA = 23
+PF_MAX = 32
+AF_UNSPEC = PF_UNSPEC
+AF_LOCAL = PF_LOCAL
+AF_UNIX = PF_UNIX
+AF_FILE = PF_FILE
+AF_INET = PF_INET
+AF_AX25 = PF_AX25
+AF_IPX = PF_IPX
+AF_APPLETALK = PF_APPLETALK
+AF_NETROM = PF_NETROM
+AF_BRIDGE = PF_BRIDGE
+AF_ATMPVC = PF_ATMPVC
+AF_X25 = PF_X25
+AF_INET6 = PF_INET6
+AF_ROSE = PF_ROSE
+AF_DECnet = PF_DECnet
+AF_NETBEUI = PF_NETBEUI
+AF_SECURITY = PF_SECURITY
+AF_KEY = PF_KEY
+AF_NETLINK = PF_NETLINK
+AF_ROUTE = PF_ROUTE
+AF_PACKET = PF_PACKET
+AF_ASH = PF_ASH
+AF_ECONET = PF_ECONET
+AF_ATMSVC = PF_ATMSVC
+AF_SNA = PF_SNA
+AF_IRDA = PF_IRDA
+AF_MAX = PF_MAX
+PF_UNIX = 1
+AF_UNIX = PF_UNIX
+PF_INET = 2
+AF_INET = PF_INET
+SOMAXCONN = 128
+MSG_OOB = 1
+MSG_PEEK = 2
+MSG_DONTROUTE = 4
+MSG_PROXY = 16
+SOL_SOCKET = 1
+SO_DEBUG = 1
+SO_REUSEADDR = 2
+SO_TYPE = 3
+SO_ERROR = 4
+SO_DONTROUTE = 5
+SO_BROADCAST = 6
+SO_SNDBUF = 7
+SO_RCVBUF = 8
+SO_KEEPALIVE = 9
+SO_OOBINLINE = 10
+SO_NO_CHECK = 11
+SO_PRIORITY = 12
+SO_LINGER = 13
+SO_BSDCOMPAT = 14
+SOL_IP = 0
+SOL_IPX = 256
+SOL_AX25 = 257
+SOL_ATALK = 258
+SOL_NETROM = 259
+SOL_TCP = 6
+SOL_UDP = 17
+IP_TOS = 1
+IPTOS_LOWDELAY = 0x10
+IPTOS_THROUGHPUT = 0x08
+IPTOS_RELIABILITY = 0x04
+IPTOS_MINCOST = 0x02
+IP_TTL = 2
+IP_HDRINCL = 3
+IP_OPTIONS = 4
+IP_MULTICAST_IF = 32
+IP_MULTICAST_TTL = 33
+IP_MULTICAST_LOOP = 34
+IP_ADD_MEMBERSHIP = 35
+IP_DROP_MEMBERSHIP = 36
+TCP_NODELAY = 0x01
+TCP_MAXSEG = 0x02
+def IN_CLASSA(a): return (((  (a)) & 0x80000000) == 0)
+
+IN_CLASSA_NET = 0xff000000
+IN_CLASSA_NSHIFT = 24
+IN_CLASSA_HOST = (0xffffffff & ~IN_CLASSA_NET)
+IN_CLASSA_MAX = 128
+def IN_CLASSB(a): return (((  (a)) & 0xc0000000) == 0x80000000)
+
+IN_CLASSB_NET = 0xffff0000
+IN_CLASSB_NSHIFT = 16
+IN_CLASSB_HOST = (0xffffffff & ~IN_CLASSB_NET)
+IN_CLASSB_MAX = 65536
+def IN_CLASSC(a): return (((  (a)) & 0xe0000000) == 0xc0000000)
+
+IN_CLASSC_NET = 0xffffff00
+IN_CLASSC_NSHIFT = 8
+IN_CLASSC_HOST = (0xffffffff & ~IN_CLASSC_NET)
+def IN_CLASSD(a): return (((  (a)) & 0xf0000000) == 0xe0000000)
+
+def IN_MULTICAST(a): return IN_CLASSD(a)
+
+def IN_EXPERIMENTAL(a): return (((  (a)) & 0xe0000000) == 0xe0000000)
+
+def IN_BADCLASS(a): return (((  (a)) & 0xf0000000) == 0xf0000000)
+
+INADDR_ANY = (  0x00000000)
+INADDR_BROADCAST = (  0xffffffff)
+INADDR_NONE = (  0xffffffff)
+IN_LOOPBACKNET = 127
+INADDR_LOOPBACK = (  0x7f000001)
+INADDR_UNSPEC_GROUP = (  0xe0000000)
+INADDR_ALLHOSTS_GROUP = (  0xe0000001)
+INADDR_ALLRTRS_GROUP = (  0xe0000002)
+INADDR_MAX_LOCAL_GROUP = (  0xe00000ff)
+INET_ADDRSTRLEN = 16
+INET6_ADDRSTRLEN = 46
+
+# Included from bits/in.h
+IP_TOS = 1
+IP_TTL = 2
+IP_HDRINCL = 3
+IP_OPTIONS = 4
+IP_ROUTER_ALERT = 5
+IP_RECVOPTS = 6
+IP_RETOPTS = 7
+IP_PKTINFO = 8
+IP_PKTOPTIONS = 9
+IP_PMTUDISC = 10
+IP_MTU_DISCOVER = 10
+IP_RECVERR = 11
+IP_RECVTTL = 12
+IP_RECVTOS = 13
+IP_MULTICAST_IF = 32
+IP_MULTICAST_TTL = 33
+IP_MULTICAST_LOOP = 34
+IP_ADD_MEMBERSHIP = 35
+IP_DROP_MEMBERSHIP = 36
+IP_RECVRETOPTS = IP_RETOPTS
+IP_PMTUDISC_DONT = 0
+IP_PMTUDISC_WANT = 1
+IP_PMTUDISC_DO = 2
+SOL_IP = 0
+SOL_SOCKET = 1
+IP_DEFAULT_MULTICAST_TTL = 1
+IP_DEFAULT_MULTICAST_LOOP = 1
+IP_MAX_MEMBERSHIPS = 20
+IPV6_ADDRFORM = 1
+IPV6_PKTINFO = 2
+IPV6_HOPOPTS = 3
+IPV6_DSTOPTS = 4
+IPV6_RXSRCRT = 5
+IPV6_PKTOPTIONS = 6
+IPV6_CHECKSUM = 7
+IPV6_HOPLIMIT = 8
+IPV6_NEXTHOP = 9
+IPV6_AUTHHDR = 10
+IPV6_UNICAST_HOPS = 16
+IPV6_MULTICAST_IF = 17
+IPV6_MULTICAST_HOPS = 18
+IPV6_MULTICAST_LOOP = 19
+IPV6_ADD_MEMBERSHIP = 20
+IPV6_DROP_MEMBERSHIP = 21
+IPV6_ROUTER_ALERT = 22
+SCM_SRCRT = IPV6_RXSRCRT
+IPV6_RXHOPOPTS = IPV6_HOPOPTS
+IPV6_RXDSTOPTS = IPV6_DSTOPTS
+IPV6_PMTUDISC_DONT = 0
+IPV6_PMTUDISC_WANT = 1
+IPV6_PMTUDISC_DO = 2
+SOL_IPV6 = 41
+SOL_ICMPV6 = 58
+
+# Included from bits/byteswap.h
+def __bswap_constant_16(x): return \
+
+def __bswap_16(x): return \
+
+def __bswap_16(x): return __bswap_constant_16 (x)
+
+def __bswap_constant_32(x): return \
+
+def __bswap_32(x): return \
+
+def __bswap_32(x): return \
+
+def __bswap_32(x): return __bswap_constant_32 (x)
+
+def __bswap_64(x): return \
+
+def ntohl(x): return (x)
+
+def ntohs(x): return (x)
+
+def htonl(x): return (x)
+
+def htons(x): return (x)
+
+def ntohl(x): return __bswap_32 (x)
+
+def ntohs(x): return __bswap_16 (x)
+
+def htonl(x): return __bswap_32 (x)
+
+def htons(x): return __bswap_16 (x)
+
+def IN6_IS_ADDR_UNSPECIFIED(a): return \
+
+def IN6_IS_ADDR_LOOPBACK(a): return \
+
+def IN6_IS_ADDR_LINKLOCAL(a): return \
+
+def IN6_IS_ADDR_SITELOCAL(a): return \
+
+def IN6_IS_ADDR_V4MAPPED(a): return \
+
+def IN6_IS_ADDR_V4COMPAT(a): return \
+
+def IN6_IS_ADDR_MC_NODELOCAL(a): return \
+
+def IN6_IS_ADDR_MC_LINKLOCAL(a): return \
+
+def IN6_IS_ADDR_MC_SITELOCAL(a): return \
+
+def IN6_IS_ADDR_MC_ORGLOCAL(a): return \
+
+def IN6_IS_ADDR_MC_GLOBAL(a): return

Added: vendor/Python/current/Lib/plat-atheos/TYPES.py
===================================================================
--- vendor/Python/current/Lib/plat-atheos/TYPES.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-atheos/TYPES.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,142 @@
+# Generated by h2py from /include/sys/types.h
+_SYS_TYPES_H = 1
+
+# Included from features.h
+_FEATURES_H = 1
+__USE_ANSI = 1
+__FAVOR_BSD = 1
+_ISOC9X_SOURCE = 1
+_POSIX_SOURCE = 1
+_POSIX_C_SOURCE = 199506L
+_XOPEN_SOURCE = 500
+_XOPEN_SOURCE_EXTENDED = 1
+_LARGEFILE64_SOURCE = 1
+_BSD_SOURCE = 1
+_SVID_SOURCE = 1
+_BSD_SOURCE = 1
+_SVID_SOURCE = 1
+__USE_ISOC9X = 1
+_POSIX_SOURCE = 1
+_POSIX_C_SOURCE = 2
+_POSIX_C_SOURCE = 199506L
+__USE_POSIX = 1
+__USE_POSIX2 = 1
+__USE_POSIX199309 = 1
+__USE_POSIX199506 = 1
+__USE_XOPEN = 1
+__USE_XOPEN_EXTENDED = 1
+__USE_UNIX98 = 1
+_LARGEFILE_SOURCE = 1
+__USE_XOPEN_EXTENDED = 1
+__USE_LARGEFILE = 1
+__USE_LARGEFILE64 = 1
+__USE_FILE_OFFSET64 = 1
+__USE_MISC = 1
+__USE_BSD = 1
+__USE_SVID = 1
+__USE_GNU = 1
+__USE_REENTRANT = 1
+__STDC_IEC_559__ = 1
+__STDC_IEC_559_COMPLEX__ = 1
+__GNU_LIBRARY__ = 6
+__GLIBC__ = 2
+__GLIBC_MINOR__ = 1
+
+# Included from sys/cdefs.h
+_SYS_CDEFS_H = 1
+def __PMT(args): return args
+
+def __P(args): return args
+
+def __PMT(args): return args
+
+def __P(args): return ()
+
+def __PMT(args): return ()
+
+def __STRING(x): return #x
+
+def __STRING(x): return "x"
+
+def __ASMNAME(cname): return __ASMNAME2 (__USER_LABEL_PREFIX__, cname)
+
+def __attribute__(xyz): return
+
+__USE_EXTERN_INLINES = 1
+
+# Included from gnu/stubs.h
+
+# Included from bits/types.h
+_BITS_TYPES_H = 1
+__FD_SETSIZE = 1024
+def __FDELT(d): return ((d) / __NFDBITS)
+
+
+# Included from bits/pthreadtypes.h
+
+# Included from time.h
+_TIME_H = 1
+
+# Included from bits/time.h
+
+# Included from posix/time.h
+
+# Included from posix/types.h
+MAXHOSTNAMELEN = 64
+FD_SETSIZE = 1024
+CLOCKS_PER_SEC = 1000000
+_BITS_TIME_H = 1
+CLOCKS_PER_SEC = 1000000
+CLK_TCK = 100
+_STRUCT_TIMEVAL = 1
+CLK_TCK = CLOCKS_PER_SEC
+__clock_t_defined = 1
+__time_t_defined = 1
+__timespec_defined = 1
+def __isleap(year): return \
+
+__BIT_TYPES_DEFINED__ = 1
+
+# Included from endian.h
+_ENDIAN_H = 1
+__LITTLE_ENDIAN = 1234
+__BIG_ENDIAN = 4321
+__PDP_ENDIAN = 3412
+
+# Included from bits/endian.h
+__BYTE_ORDER = __LITTLE_ENDIAN
+__FLOAT_WORD_ORDER = __BYTE_ORDER
+LITTLE_ENDIAN = __LITTLE_ENDIAN
+BIG_ENDIAN = __BIG_ENDIAN
+PDP_ENDIAN = __PDP_ENDIAN
+BYTE_ORDER = __BYTE_ORDER
+
+# Included from sys/select.h
+_SYS_SELECT_H = 1
+
+# Included from bits/select.h
+def __FD_ZERO(fdsp): return \
+
+def __FD_ZERO(set): return \
+
+
+# Included from bits/sigset.h
+_SIGSET_H_types = 1
+_SIGSET_H_fns = 1
+def __sigmask(sig): return \
+
+def __sigemptyset(set): return \
+
+def __sigfillset(set): return \
+
+def __sigisemptyset(set): return \
+
+FD_SETSIZE = __FD_SETSIZE
+def FD_ZERO(fdsetp): return __FD_ZERO (fdsetp)
+
+
+# Included from sys/sysmacros.h
+_SYS_SYSMACROS_H = 1
+def major(dev): return ( ((  (dev) >> 8) & 0xff))
+
+def minor(dev): return ( ((dev) & 0xff))

Added: vendor/Python/current/Lib/plat-atheos/regen
===================================================================
--- vendor/Python/current/Lib/plat-atheos/regen	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-atheos/regen	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,3 @@
+#! /bin/sh
+set -v
+python$EXE ../../Tools/scripts/h2py.py -i '\(u_long\)' -i '\(uint32_t\)' -i '\(int\)' -i '\(unsigned int\)' /include/netinet/in.h /include/sys/types.h

Added: vendor/Python/current/Lib/plat-beos5/IN.py
===================================================================
--- vendor/Python/current/Lib/plat-beos5/IN.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-beos5/IN.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,327 @@
+# Generated by h2py from /boot/develop/headers/be/net/netinet/in.h
+
+# Included from socket.h
+
+# Included from BeBuild.h
+B_BEOS_VERSION_4 = 0x0400
+B_BEOS_VERSION_4_5 = 0x0450
+B_BEOS_VERSION_5 = 0x0500
+B_BEOS_VERSION = B_BEOS_VERSION_5
+B_BEOS_VERSION_MAUI = B_BEOS_VERSION_5
+_PR2_COMPATIBLE_ = 1
+_PR3_COMPATIBLE_ = 1
+_R4_COMPATIBLE_ = 1
+_R4_5_COMPATIBLE_ = 1
+_PR2_COMPATIBLE_ = 0
+_PR3_COMPATIBLE_ = 0
+_R4_COMPATIBLE_ = 1
+_R4_5_COMPATIBLE_ = 1
+def _UNUSED(x): return x
+
+
+# Included from sys/types.h
+
+# Included from time.h
+
+# Included from be_setup.h
+def __std(ref): return ref
+
+__be_os = 2
+__dest_os = __be_os
+__MSL__ = 0x4011
+__GLIBC__ = -2
+__GLIBC_MINOR__ = 1
+
+# Included from null.h
+NULL = (0)
+NULL = 0L
+
+# Included from size_t.h
+
+# Included from stddef.h
+
+# Included from wchar_t.h
+CLOCKS_PER_SEC = 1000
+CLK_TCK = CLOCKS_PER_SEC
+MAX_TIMESTR = 70
+
+# Included from sys/time.h
+
+# Included from ByteOrder.h
+
+# Included from endian.h
+__LITTLE_ENDIAN = 1234
+LITTLE_ENDIAN = __LITTLE_ENDIAN
+__BYTE_ORDER = __LITTLE_ENDIAN
+BYTE_ORDER = __BYTE_ORDER
+__BIG_ENDIAN = 0
+BIG_ENDIAN = 0
+__BIG_ENDIAN = 4321
+BIG_ENDIAN = __BIG_ENDIAN
+__BYTE_ORDER = __BIG_ENDIAN
+BYTE_ORDER = __BYTE_ORDER
+__LITTLE_ENDIAN = 0
+LITTLE_ENDIAN = 0
+__PDP_ENDIAN = 3412
+PDP_ENDIAN = __PDP_ENDIAN
+
+# Included from SupportDefs.h
+
+# Included from Errors.h
+
+# Included from limits.h
+
+# Included from float.h
+FLT_ROUNDS = 1
+FLT_RADIX = 2
+FLT_MANT_DIG = 24
+FLT_DIG = 6
+FLT_MIN_EXP = (-125)
+FLT_MIN_10_EXP = (-37)
+FLT_MAX_EXP = 128
+FLT_MAX_10_EXP = 38
+DBL_MANT_DIG = 53
+DBL_DIG = 15
+DBL_MIN_EXP = (-1021)
+DBL_MIN_10_EXP = (-308)
+DBL_MAX_EXP = 1024
+DBL_MAX_10_EXP = 308
+LDBL_MANT_DIG = DBL_MANT_DIG
+LDBL_DIG = DBL_DIG
+LDBL_MIN_EXP = DBL_MIN_EXP
+LDBL_MIN_10_EXP = DBL_MIN_10_EXP
+LDBL_MAX_EXP = DBL_MAX_EXP
+LDBL_MAX_10_EXP = DBL_MAX_10_EXP
+CHAR_BIT = (8)
+SCHAR_MIN = (-127-1)
+SCHAR_MAX = (127)
+CHAR_MIN = SCHAR_MIN
+CHAR_MAX = SCHAR_MAX
+MB_LEN_MAX = (1)
+SHRT_MIN = (-32767-1)
+SHRT_MAX = (32767)
+LONG_MIN = (-2147483647L-1)
+LONG_MAX = (2147483647L)
+INT_MIN = LONG_MIN
+INT_MAX = LONG_MAX
+ARG_MAX = (32768)
+ATEXIT_MAX = (32)
+CHILD_MAX = (1024)
+IOV_MAX = (256)
+FILESIZEBITS = (64)
+LINK_MAX = (1)
+LOGIN_NAME_MAX = (32)
+MAX_CANON = (255)
+MAX_INPUT = (255)
+NAME_MAX = (256)
+NGROUPS_MAX = (32)
+OPEN_MAX = (128)
+PATH_MAX = (1024)
+PIPE_MAX = (512)
+SSIZE_MAX = (2147483647L)
+TTY_NAME_MAX = (256)
+TZNAME_MAX = (32)
+SYMLINKS_MAX = (16)
+_POSIX_ARG_MAX = (32768)
+_POSIX_CHILD_MAX = (1024)
+_POSIX_LINK_MAX = (1)
+_POSIX_LOGIN_NAME_MAX = (9)
+_POSIX_MAX_CANON = (255)
+_POSIX_MAX_INPUT = (255)
+_POSIX_NAME_MAX = (255)
+_POSIX_NGROUPS_MAX = (0)
+_POSIX_OPEN_MAX = (128)
+_POSIX_PATH_MAX = (1024)
+_POSIX_PIPE_BUF = (512)
+_POSIX_SSIZE_MAX = (2147483647L)
+_POSIX_STREAM_MAX = (8)
+_POSIX_TTY_NAME_MAX = (256)
+_POSIX_TZNAME_MAX = (3)
+B_GENERAL_ERROR_BASE = LONG_MIN
+B_OS_ERROR_BASE = B_GENERAL_ERROR_BASE + 0x1000
+B_APP_ERROR_BASE = B_GENERAL_ERROR_BASE + 0x2000
+B_INTERFACE_ERROR_BASE = B_GENERAL_ERROR_BASE + 0x3000
+B_MEDIA_ERROR_BASE = B_GENERAL_ERROR_BASE + 0x4000
+B_TRANSLATION_ERROR_BASE = B_GENERAL_ERROR_BASE + 0x4800
+B_MIDI_ERROR_BASE = B_GENERAL_ERROR_BASE + 0x5000
+B_STORAGE_ERROR_BASE = B_GENERAL_ERROR_BASE + 0x6000
+B_POSIX_ERROR_BASE = B_GENERAL_ERROR_BASE + 0x7000
+B_MAIL_ERROR_BASE = B_GENERAL_ERROR_BASE + 0x8000
+B_PRINT_ERROR_BASE = B_GENERAL_ERROR_BASE + 0x9000
+B_DEVICE_ERROR_BASE = B_GENERAL_ERROR_BASE + 0xa000
+B_ERRORS_END = (B_GENERAL_ERROR_BASE + 0xffff)
+E2BIG = (B_POSIX_ERROR_BASE + 1)
+ECHILD = (B_POSIX_ERROR_BASE + 2)
+EDEADLK = (B_POSIX_ERROR_BASE + 3)
+EFBIG = (B_POSIX_ERROR_BASE + 4)
+EMLINK = (B_POSIX_ERROR_BASE + 5)
+ENFILE = (B_POSIX_ERROR_BASE + 6)
+ENODEV = (B_POSIX_ERROR_BASE + 7)
+ENOLCK = (B_POSIX_ERROR_BASE + 8)
+ENOSYS = (B_POSIX_ERROR_BASE + 9)
+ENOTTY = (B_POSIX_ERROR_BASE + 10)
+ENXIO = (B_POSIX_ERROR_BASE + 11)
+ESPIPE = (B_POSIX_ERROR_BASE + 12)
+ESRCH = (B_POSIX_ERROR_BASE + 13)
+EFPOS = (B_POSIX_ERROR_BASE + 14)
+ESIGPARM = (B_POSIX_ERROR_BASE + 15)
+EDOM = (B_POSIX_ERROR_BASE + 16)
+ERANGE = (B_POSIX_ERROR_BASE + 17)
+EPROTOTYPE = (B_POSIX_ERROR_BASE + 18)
+EPROTONOSUPPORT = (B_POSIX_ERROR_BASE + 19)
+EPFNOSUPPORT = (B_POSIX_ERROR_BASE + 20)
+EAFNOSUPPORT = (B_POSIX_ERROR_BASE + 21)
+EADDRINUSE = (B_POSIX_ERROR_BASE + 22)
+EADDRNOTAVAIL = (B_POSIX_ERROR_BASE + 23)
+ENETDOWN = (B_POSIX_ERROR_BASE + 24)
+ENETUNREACH = (B_POSIX_ERROR_BASE + 25)
+ENETRESET = (B_POSIX_ERROR_BASE + 26)
+ECONNABORTED = (B_POSIX_ERROR_BASE + 27)
+ECONNRESET = (B_POSIX_ERROR_BASE + 28)
+EISCONN = (B_POSIX_ERROR_BASE + 29)
+ENOTCONN = (B_POSIX_ERROR_BASE + 30)
+ESHUTDOWN = (B_POSIX_ERROR_BASE + 31)
+ECONNREFUSED = (B_POSIX_ERROR_BASE + 32)
+EHOSTUNREACH = (B_POSIX_ERROR_BASE + 33)
+ENOPROTOOPT = (B_POSIX_ERROR_BASE + 34)
+ENOBUFS = (B_POSIX_ERROR_BASE + 35)
+EINPROGRESS = (B_POSIX_ERROR_BASE + 36)
+EALREADY = (B_POSIX_ERROR_BASE + 37)
+EILSEQ = (B_POSIX_ERROR_BASE + 38)
+ENOMSG = (B_POSIX_ERROR_BASE + 39)
+ESTALE = (B_POSIX_ERROR_BASE + 40)
+EOVERFLOW = (B_POSIX_ERROR_BASE + 41)
+EMSGSIZE = (B_POSIX_ERROR_BASE + 42)
+EOPNOTSUPP = (B_POSIX_ERROR_BASE + 43)
+ENOTSOCK = (B_POSIX_ERROR_BASE + 44)
+false = 0
+true = 1
+NULL = (0)
+FALSE = 0
+TRUE = 1
+
+# Included from TypeConstants.h
+B_HOST_IS_LENDIAN = 1
+B_HOST_IS_BENDIAN = 0
+def B_HOST_TO_LENDIAN_DOUBLE(arg): return (double)(arg)
+
+def B_HOST_TO_LENDIAN_FLOAT(arg): return (float)(arg)
+
+def B_HOST_TO_LENDIAN_INT64(arg): return (uint64)(arg)
+
+def B_HOST_TO_LENDIAN_INT32(arg): return (uint32)(arg)
+
+def B_HOST_TO_LENDIAN_INT16(arg): return (uint16)(arg)
+
+def B_HOST_TO_BENDIAN_DOUBLE(arg): return __swap_double(arg)
+
+def B_HOST_TO_BENDIAN_FLOAT(arg): return __swap_float(arg)
+
+def B_HOST_TO_BENDIAN_INT64(arg): return __swap_int64(arg)
+
+def B_HOST_TO_BENDIAN_INT32(arg): return __swap_int32(arg)
+
+def B_HOST_TO_BENDIAN_INT16(arg): return __swap_int16(arg)
+
+def B_LENDIAN_TO_HOST_DOUBLE(arg): return (double)(arg)
+
+def B_LENDIAN_TO_HOST_FLOAT(arg): return (float)(arg)
+
+def B_LENDIAN_TO_HOST_INT64(arg): return (uint64)(arg)
+
+def B_LENDIAN_TO_HOST_INT32(arg): return (uint32)(arg)
+
+def B_LENDIAN_TO_HOST_INT16(arg): return (uint16)(arg)
+
+def B_BENDIAN_TO_HOST_DOUBLE(arg): return __swap_double(arg)
+
+def B_BENDIAN_TO_HOST_FLOAT(arg): return __swap_float(arg)
+
+def B_BENDIAN_TO_HOST_INT64(arg): return __swap_int64(arg)
+
+def B_BENDIAN_TO_HOST_INT32(arg): return __swap_int32(arg)
+
+def B_BENDIAN_TO_HOST_INT16(arg): return __swap_int16(arg)
+
+B_HOST_IS_LENDIAN = 0
+B_HOST_IS_BENDIAN = 1
+def B_HOST_TO_LENDIAN_DOUBLE(arg): return __swap_double(arg)
+
+def B_HOST_TO_LENDIAN_FLOAT(arg): return __swap_float(arg)
+
+def B_HOST_TO_LENDIAN_INT64(arg): return __swap_int64(arg)
+
+def B_HOST_TO_LENDIAN_INT32(arg): return __swap_int32(arg)
+
+def B_HOST_TO_LENDIAN_INT16(arg): return __swap_int16(arg)
+
+def B_HOST_TO_BENDIAN_DOUBLE(arg): return (double)(arg)
+
+def B_HOST_TO_BENDIAN_FLOAT(arg): return (float)(arg)
+
+def B_HOST_TO_BENDIAN_INT64(arg): return (uint64)(arg)
+
+def B_HOST_TO_BENDIAN_INT32(arg): return (uint32)(arg)
+
+def B_HOST_TO_BENDIAN_INT16(arg): return (uint16)(arg)
+
+def B_LENDIAN_TO_HOST_DOUBLE(arg): return __swap_double(arg)
+
+def B_LENDIAN_TO_HOST_FLOAT(arg): return __swap_float(arg)
+
+def B_LENDIAN_TO_HOST_INT64(arg): return __swap_int64(arg)
+
+def B_LENDIAN_TO_HOST_INT32(arg): return __swap_int32(arg)
+
+def B_LENDIAN_TO_HOST_INT16(arg): return __swap_int16(arg)
+
+def B_BENDIAN_TO_HOST_DOUBLE(arg): return (double)(arg)
+
+def B_BENDIAN_TO_HOST_FLOAT(arg): return (float)(arg)
+
+def B_BENDIAN_TO_HOST_INT64(arg): return (uint64)(arg)
+
+def B_BENDIAN_TO_HOST_INT32(arg): return (uint32)(arg)
+
+def B_BENDIAN_TO_HOST_INT16(arg): return (uint16)(arg)
+
+def B_SWAP_DOUBLE(arg): return __swap_double(arg)
+
+def B_SWAP_FLOAT(arg): return __swap_float(arg)
+
+def B_SWAP_INT64(arg): return __swap_int64(arg)
+
+def B_SWAP_INT32(arg): return __swap_int32(arg)
+
+def B_SWAP_INT16(arg): return __swap_int16(arg)
+
+def htonl(x): return B_HOST_TO_BENDIAN_INT32(x)
+
+def ntohl(x): return B_BENDIAN_TO_HOST_INT32(x)
+
+def htons(x): return B_HOST_TO_BENDIAN_INT16(x)
+
+def ntohs(x): return B_BENDIAN_TO_HOST_INT16(x)
+
+AF_INET = 1
+INADDR_ANY = 0x00000000
+INADDR_BROADCAST = 0xffffffff
+INADDR_LOOPBACK = 0x7f000001
+SOL_SOCKET = 1
+SO_DEBUG = 1
+SO_REUSEADDR = 2
+SO_NONBLOCK = 3
+SO_REUSEPORT = 4
+MSG_OOB = 0x1
+SOCK_DGRAM = 1
+SOCK_STREAM = 2
+IPPROTO_UDP = 1
+IPPROTO_TCP = 2
+IPPROTO_ICMP = 3
+B_UDP_MAX_SIZE = (65536 - 1024)
+FD_SETSIZE = 256
+FDSETSIZE = FD_SETSIZE
+NFDBITS = 32
+def _FDMSKNO(fd): return ((fd) / NFDBITS)
+
+def _FDBITNO(fd): return ((fd) % NFDBITS)

Added: vendor/Python/current/Lib/plat-beos5/regen
===================================================================
--- vendor/Python/current/Lib/plat-beos5/regen	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-beos5/regen	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,7 @@
+#! /bin/sh
+
+H2PY=../../Tools/scripts/h2py.py
+HEADERS=/boot/develop/headers
+
+set -v
+python $H2PY -i '(u_long)' $HEADERS/be/net/netinet/in.h


Property changes on: vendor/Python/current/Lib/plat-beos5/regen
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/plat-darwin/IN.py
===================================================================
--- vendor/Python/current/Lib/plat-darwin/IN.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-darwin/IN.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,357 @@
+# Generated by h2py from /usr/include/netinet/in.h
+
+# Included from sys/appleapiopts.h
+IPPROTO_IP = 0
+IPPROTO_HOPOPTS = 0
+IPPROTO_ICMP = 1
+IPPROTO_IGMP = 2
+IPPROTO_GGP = 3
+IPPROTO_IPV4 = 4
+IPPROTO_IPIP = IPPROTO_IPV4
+IPPROTO_TCP = 6
+IPPROTO_ST = 7
+IPPROTO_EGP = 8
+IPPROTO_PIGP = 9
+IPPROTO_RCCMON = 10
+IPPROTO_NVPII = 11
+IPPROTO_PUP = 12
+IPPROTO_ARGUS = 13
+IPPROTO_EMCON = 14
+IPPROTO_XNET = 15
+IPPROTO_CHAOS = 16
+IPPROTO_UDP = 17
+IPPROTO_MUX = 18
+IPPROTO_MEAS = 19
+IPPROTO_HMP = 20
+IPPROTO_PRM = 21
+IPPROTO_IDP = 22
+IPPROTO_TRUNK1 = 23
+IPPROTO_TRUNK2 = 24
+IPPROTO_LEAF1 = 25
+IPPROTO_LEAF2 = 26
+IPPROTO_RDP = 27
+IPPROTO_IRTP = 28
+IPPROTO_TP = 29
+IPPROTO_BLT = 30
+IPPROTO_NSP = 31
+IPPROTO_INP = 32
+IPPROTO_SEP = 33
+IPPROTO_3PC = 34
+IPPROTO_IDPR = 35
+IPPROTO_XTP = 36
+IPPROTO_DDP = 37
+IPPROTO_CMTP = 38
+IPPROTO_TPXX = 39
+IPPROTO_IL = 40
+IPPROTO_IPV6 = 41
+IPPROTO_SDRP = 42
+IPPROTO_ROUTING = 43
+IPPROTO_FRAGMENT = 44
+IPPROTO_IDRP = 45
+IPPROTO_RSVP = 46
+IPPROTO_GRE = 47
+IPPROTO_MHRP = 48
+IPPROTO_BHA = 49
+IPPROTO_ESP = 50
+IPPROTO_AH = 51
+IPPROTO_INLSP = 52
+IPPROTO_SWIPE = 53
+IPPROTO_NHRP = 54
+IPPROTO_ICMPV6 = 58
+IPPROTO_NONE = 59
+IPPROTO_DSTOPTS = 60
+IPPROTO_AHIP = 61
+IPPROTO_CFTP = 62
+IPPROTO_HELLO = 63
+IPPROTO_SATEXPAK = 64
+IPPROTO_KRYPTOLAN = 65
+IPPROTO_RVD = 66
+IPPROTO_IPPC = 67
+IPPROTO_ADFS = 68
+IPPROTO_SATMON = 69
+IPPROTO_VISA = 70
+IPPROTO_IPCV = 71
+IPPROTO_CPNX = 72
+IPPROTO_CPHB = 73
+IPPROTO_WSN = 74
+IPPROTO_PVP = 75
+IPPROTO_BRSATMON = 76
+IPPROTO_ND = 77
+IPPROTO_WBMON = 78
+IPPROTO_WBEXPAK = 79
+IPPROTO_EON = 80
+IPPROTO_VMTP = 81
+IPPROTO_SVMTP = 82
+IPPROTO_VINES = 83
+IPPROTO_TTP = 84
+IPPROTO_IGP = 85
+IPPROTO_DGP = 86
+IPPROTO_TCF = 87
+IPPROTO_IGRP = 88
+IPPROTO_OSPFIGP = 89
+IPPROTO_SRPC = 90
+IPPROTO_LARP = 91
+IPPROTO_MTP = 92
+IPPROTO_AX25 = 93
+IPPROTO_IPEIP = 94
+IPPROTO_MICP = 95
+IPPROTO_SCCSP = 96
+IPPROTO_ETHERIP = 97
+IPPROTO_ENCAP = 98
+IPPROTO_APES = 99
+IPPROTO_GMTP = 100
+IPPROTO_IPCOMP = 108
+IPPROTO_PIM = 103
+IPPROTO_PGM = 113
+IPPROTO_DIVERT = 254
+IPPROTO_RAW = 255
+IPPROTO_MAX = 256
+IPPROTO_DONE = 257
+IPPORT_RESERVED = 1024
+IPPORT_USERRESERVED = 5000
+IPPORT_HIFIRSTAUTO = 49152
+IPPORT_HILASTAUTO = 65535
+IPPORT_RESERVEDSTART = 600
+def IN_CLASSA(i): return (((u_int32_t)(i) & 0x80000000) == 0)
+
+IN_CLASSA_NET = 0xff000000
+IN_CLASSA_NSHIFT = 24
+IN_CLASSA_HOST = 0x00ffffff
+IN_CLASSA_MAX = 128
+def IN_CLASSB(i): return (((u_int32_t)(i) & 0xc0000000) == 0x80000000)
+
+IN_CLASSB_NET = 0xffff0000
+IN_CLASSB_NSHIFT = 16
+IN_CLASSB_HOST = 0x0000ffff
+IN_CLASSB_MAX = 65536
+def IN_CLASSC(i): return (((u_int32_t)(i) & 0xe0000000) == 0xc0000000)
+
+IN_CLASSC_NET = 0xffffff00
+IN_CLASSC_NSHIFT = 8
+IN_CLASSC_HOST = 0x000000ff
+def IN_CLASSD(i): return (((u_int32_t)(i) & 0xf0000000) == 0xe0000000)
+
+IN_CLASSD_NET = 0xf0000000
+IN_CLASSD_NSHIFT = 28
+IN_CLASSD_HOST = 0x0fffffff
+def IN_MULTICAST(i): return IN_CLASSD(i)
+
+def IN_EXPERIMENTAL(i): return (((u_int32_t)(i) & 0xf0000000) == 0xf0000000)
+
+def IN_BADCLASS(i): return (((u_int32_t)(i) & 0xf0000000) == 0xf0000000)
+
+INADDR_NONE = 0xffffffff
+def IN_LINKLOCAL(i): return (((u_int32_t)(i) & IN_CLASSB_NET) == IN_LINKLOCALNETNUM)
+
+IN_LOOPBACKNET = 127
+INET_ADDRSTRLEN = 16
+IP_OPTIONS = 1
+IP_HDRINCL = 2
+IP_TOS = 3
+IP_TTL = 4
+IP_RECVOPTS = 5
+IP_RECVRETOPTS = 6
+IP_RECVDSTADDR = 7
+IP_RETOPTS = 8
+IP_MULTICAST_IF = 9
+IP_MULTICAST_TTL = 10
+IP_MULTICAST_LOOP = 11
+IP_ADD_MEMBERSHIP = 12
+IP_DROP_MEMBERSHIP = 13
+IP_MULTICAST_VIF = 14
+IP_RSVP_ON = 15
+IP_RSVP_OFF = 16
+IP_RSVP_VIF_ON = 17
+IP_RSVP_VIF_OFF = 18
+IP_PORTRANGE = 19
+IP_RECVIF = 20
+IP_IPSEC_POLICY = 21
+IP_FAITH = 22
+IP_STRIPHDR = 23
+IP_FW_ADD = 40
+IP_FW_DEL = 41
+IP_FW_FLUSH = 42
+IP_FW_ZERO = 43
+IP_FW_GET = 44
+IP_FW_RESETLOG = 45
+IP_OLD_FW_ADD = 50
+IP_OLD_FW_DEL = 51
+IP_OLD_FW_FLUSH = 52
+IP_OLD_FW_ZERO = 53
+IP_OLD_FW_GET = 54
+IP_NAT__XXX = 55
+IP_OLD_FW_RESETLOG = 56
+IP_DUMMYNET_CONFIGURE = 60
+IP_DUMMYNET_DEL = 61
+IP_DUMMYNET_FLUSH = 62
+IP_DUMMYNET_GET = 64
+IP_DEFAULT_MULTICAST_TTL = 1
+IP_DEFAULT_MULTICAST_LOOP = 1
+IP_MAX_MEMBERSHIPS = 20
+IP_PORTRANGE_DEFAULT = 0
+IP_PORTRANGE_HIGH = 1
+IP_PORTRANGE_LOW = 2
+IPPROTO_MAXID = (IPPROTO_AH + 1)
+IPCTL_FORWARDING = 1
+IPCTL_SENDREDIRECTS = 2
+IPCTL_DEFTTL = 3
+IPCTL_DEFMTU = 4
+IPCTL_RTEXPIRE = 5
+IPCTL_RTMINEXPIRE = 6
+IPCTL_RTMAXCACHE = 7
+IPCTL_SOURCEROUTE = 8
+IPCTL_DIRECTEDBROADCAST = 9
+IPCTL_INTRQMAXLEN = 10
+IPCTL_INTRQDROPS = 11
+IPCTL_STATS = 12
+IPCTL_ACCEPTSOURCEROUTE = 13
+IPCTL_FASTFORWARDING = 14
+IPCTL_KEEPFAITH = 15
+IPCTL_GIF_TTL = 16
+IPCTL_MAXID = 17
+
+# Included from netinet6/in6.h
+__KAME_VERSION = "20010528/apple-darwin"
+IPV6PORT_RESERVED = 1024
+IPV6PORT_ANONMIN = 49152
+IPV6PORT_ANONMAX = 65535
+IPV6PORT_RESERVEDMIN = 600
+IPV6PORT_RESERVEDMAX = (IPV6PORT_RESERVED-1)
+INET6_ADDRSTRLEN = 46
+IPV6_ADDR_INT32_ONE = 1
+IPV6_ADDR_INT32_TWO = 2
+IPV6_ADDR_INT32_MNL = 0xff010000
+IPV6_ADDR_INT32_MLL = 0xff020000
+IPV6_ADDR_INT32_SMP = 0x0000ffff
+IPV6_ADDR_INT16_ULL = 0xfe80
+IPV6_ADDR_INT16_USL = 0xfec0
+IPV6_ADDR_INT16_MLL = 0xff02
+IPV6_ADDR_INT32_ONE = 0x01000000
+IPV6_ADDR_INT32_TWO = 0x02000000
+IPV6_ADDR_INT32_MNL = 0x000001ff
+IPV6_ADDR_INT32_MLL = 0x000002ff
+IPV6_ADDR_INT32_SMP = 0xffff0000
+IPV6_ADDR_INT16_ULL = 0x80fe
+IPV6_ADDR_INT16_USL = 0xc0fe
+IPV6_ADDR_INT16_MLL = 0x02ff
+def IN6_IS_ADDR_UNSPECIFIED(a): return \
+
+def IN6_IS_ADDR_LOOPBACK(a): return \
+
+def IN6_IS_ADDR_V4COMPAT(a): return \
+
+def IN6_IS_ADDR_V4MAPPED(a): return \
+
+IPV6_ADDR_SCOPE_NODELOCAL = 0x01
+IPV6_ADDR_SCOPE_LINKLOCAL = 0x02
+IPV6_ADDR_SCOPE_SITELOCAL = 0x05
+IPV6_ADDR_SCOPE_ORGLOCAL = 0x08
+IPV6_ADDR_SCOPE_GLOBAL = 0x0e
+__IPV6_ADDR_SCOPE_NODELOCAL = 0x01
+__IPV6_ADDR_SCOPE_LINKLOCAL = 0x02
+__IPV6_ADDR_SCOPE_SITELOCAL = 0x05
+__IPV6_ADDR_SCOPE_ORGLOCAL = 0x08
+__IPV6_ADDR_SCOPE_GLOBAL = 0x0e
+def IN6_IS_ADDR_LINKLOCAL(a): return \
+
+def IN6_IS_ADDR_SITELOCAL(a): return \
+
+def IN6_IS_ADDR_MC_NODELOCAL(a): return \
+
+def IN6_IS_ADDR_MC_LINKLOCAL(a): return \
+
+def IN6_IS_ADDR_MC_SITELOCAL(a): return \
+
+def IN6_IS_ADDR_MC_ORGLOCAL(a): return \
+
+def IN6_IS_ADDR_MC_GLOBAL(a): return \
+
+def IN6_IS_ADDR_MC_NODELOCAL(a): return \
+
+def IN6_IS_ADDR_MC_LINKLOCAL(a): return \
+
+def IN6_IS_ADDR_MC_SITELOCAL(a): return \
+
+def IN6_IS_ADDR_MC_ORGLOCAL(a): return \
+
+def IN6_IS_ADDR_MC_GLOBAL(a): return \
+
+def IN6_IS_SCOPE_LINKLOCAL(a): return \
+
+def IFA6_IS_DEPRECATED(a): return \
+
+def IFA6_IS_INVALID(a): return \
+
+IPV6_OPTIONS = 1
+IPV6_RECVOPTS = 5
+IPV6_RECVRETOPTS = 6
+IPV6_RECVDSTADDR = 7
+IPV6_RETOPTS = 8
+IPV6_SOCKOPT_RESERVED1 = 3
+IPV6_UNICAST_HOPS = 4
+IPV6_MULTICAST_IF = 9
+IPV6_MULTICAST_HOPS = 10
+IPV6_MULTICAST_LOOP = 11
+IPV6_JOIN_GROUP = 12
+IPV6_LEAVE_GROUP = 13
+IPV6_PORTRANGE = 14
+ICMP6_FILTER = 18
+IPV6_PKTINFO = 19
+IPV6_HOPLIMIT = 20
+IPV6_NEXTHOP = 21
+IPV6_HOPOPTS = 22
+IPV6_DSTOPTS = 23
+IPV6_RTHDR = 24
+IPV6_PKTOPTIONS = 25
+IPV6_CHECKSUM = 26
+IPV6_V6ONLY = 27
+IPV6_BINDV6ONLY = IPV6_V6ONLY
+IPV6_IPSEC_POLICY = 28
+IPV6_FAITH = 29
+IPV6_FW_ADD = 30
+IPV6_FW_DEL = 31
+IPV6_FW_FLUSH = 32
+IPV6_FW_ZERO = 33
+IPV6_FW_GET = 34
+IPV6_RTHDR_LOOSE = 0
+IPV6_RTHDR_STRICT = 1
+IPV6_RTHDR_TYPE_0 = 0
+IPV6_DEFAULT_MULTICAST_HOPS = 1
+IPV6_DEFAULT_MULTICAST_LOOP = 1
+IPV6_PORTRANGE_DEFAULT = 0
+IPV6_PORTRANGE_HIGH = 1
+IPV6_PORTRANGE_LOW = 2
+IPV6PROTO_MAXID = (IPPROTO_PIM + 1)
+IPV6CTL_FORWARDING = 1
+IPV6CTL_SENDREDIRECTS = 2
+IPV6CTL_DEFHLIM = 3
+IPV6CTL_DEFMTU = 4
+IPV6CTL_FORWSRCRT = 5
+IPV6CTL_STATS = 6
+IPV6CTL_MRTSTATS = 7
+IPV6CTL_MRTPROTO = 8
+IPV6CTL_MAXFRAGPACKETS = 9
+IPV6CTL_SOURCECHECK = 10
+IPV6CTL_SOURCECHECK_LOGINT = 11
+IPV6CTL_ACCEPT_RTADV = 12
+IPV6CTL_KEEPFAITH = 13
+IPV6CTL_LOG_INTERVAL = 14
+IPV6CTL_HDRNESTLIMIT = 15
+IPV6CTL_DAD_COUNT = 16
+IPV6CTL_AUTO_FLOWLABEL = 17
+IPV6CTL_DEFMCASTHLIM = 18
+IPV6CTL_GIF_HLIM = 19
+IPV6CTL_KAME_VERSION = 20
+IPV6CTL_USE_DEPRECATED = 21
+IPV6CTL_RR_PRUNE = 22
+IPV6CTL_MAPPED_ADDR = 23
+IPV6CTL_V6ONLY = 24
+IPV6CTL_RTEXPIRE = 25
+IPV6CTL_RTMINEXPIRE = 26
+IPV6CTL_RTMAXCACHE = 27
+IPV6CTL_USETEMPADDR = 32
+IPV6CTL_TEMPPLTIME = 33
+IPV6CTL_TEMPVLTIME = 34
+IPV6CTL_AUTO_LINKLOCAL = 35
+IPV6CTL_RIP6STATS = 36
+IPV6CTL_MAXID = 37

Added: vendor/Python/current/Lib/plat-darwin/regen
===================================================================
--- vendor/Python/current/Lib/plat-darwin/regen	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-darwin/regen	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,3 @@
+#! /bin/sh
+set -v
+python$EXE ../../Tools/scripts/h2py.py -i '(u_long)' /usr/include/netinet/in.h


Property changes on: vendor/Python/current/Lib/plat-darwin/regen
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/plat-freebsd2/IN.py
===================================================================
--- vendor/Python/current/Lib/plat-freebsd2/IN.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-freebsd2/IN.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,187 @@
+# Generated by h2py from /usr/include/netinet/in.h
+IPPROTO_IP = 0
+IPPROTO_ICMP = 1
+IPPROTO_IGMP = 2
+IPPROTO_GGP = 3
+IPPROTO_IPIP = 4
+IPPROTO_TCP = 6
+IPPROTO_ST = 7
+IPPROTO_EGP = 8
+IPPROTO_PIGP = 9
+IPPROTO_RCCMON = 10
+IPPROTO_NVPII = 11
+IPPROTO_PUP = 12
+IPPROTO_ARGUS = 13
+IPPROTO_EMCON = 14
+IPPROTO_XNET = 15
+IPPROTO_CHAOS = 16
+IPPROTO_UDP = 17
+IPPROTO_MUX = 18
+IPPROTO_MEAS = 19
+IPPROTO_HMP = 20
+IPPROTO_PRM = 21
+IPPROTO_IDP = 22
+IPPROTO_TRUNK1 = 23
+IPPROTO_TRUNK2 = 24
+IPPROTO_LEAF1 = 25
+IPPROTO_LEAF2 = 26
+IPPROTO_RDP = 27
+IPPROTO_IRTP = 28
+IPPROTO_TP = 29
+IPPROTO_BLT = 30
+IPPROTO_NSP = 31
+IPPROTO_INP = 32
+IPPROTO_SEP = 33
+IPPROTO_3PC = 34
+IPPROTO_IDPR = 35
+IPPROTO_XTP = 36
+IPPROTO_DDP = 37
+IPPROTO_CMTP = 38
+IPPROTO_TPXX = 39
+IPPROTO_IL = 40
+IPPROTO_SIP = 41
+IPPROTO_SDRP = 42
+IPPROTO_SIPSR = 43
+IPPROTO_SIPFRAG = 44
+IPPROTO_IDRP = 45
+IPPROTO_RSVP = 46
+IPPROTO_GRE = 47
+IPPROTO_MHRP = 48
+IPPROTO_BHA = 49
+IPPROTO_ESP = 50
+IPPROTO_AH = 51
+IPPROTO_INLSP = 52
+IPPROTO_SWIPE = 53
+IPPROTO_NHRP = 54
+IPPROTO_AHIP = 61
+IPPROTO_CFTP = 62
+IPPROTO_HELLO = 63
+IPPROTO_SATEXPAK = 64
+IPPROTO_KRYPTOLAN = 65
+IPPROTO_RVD = 66
+IPPROTO_IPPC = 67
+IPPROTO_ADFS = 68
+IPPROTO_SATMON = 69
+IPPROTO_VISA = 70
+IPPROTO_IPCV = 71
+IPPROTO_CPNX = 72
+IPPROTO_CPHB = 73
+IPPROTO_WSN = 74
+IPPROTO_PVP = 75
+IPPROTO_BRSATMON = 76
+IPPROTO_ND = 77
+IPPROTO_WBMON = 78
+IPPROTO_WBEXPAK = 79
+IPPROTO_EON = 80
+IPPROTO_VMTP = 81
+IPPROTO_SVMTP = 82
+IPPROTO_VINES = 83
+IPPROTO_TTP = 84
+IPPROTO_IGP = 85
+IPPROTO_DGP = 86
+IPPROTO_TCF = 87
+IPPROTO_IGRP = 88
+IPPROTO_OSPFIGP = 89
+IPPROTO_SRPC = 90
+IPPROTO_LARP = 91
+IPPROTO_MTP = 92
+IPPROTO_AX25 = 93
+IPPROTO_IPEIP = 94
+IPPROTO_MICP = 95
+IPPROTO_SCCSP = 96
+IPPROTO_ETHERIP = 97
+IPPROTO_ENCAP = 98
+IPPROTO_APES = 99
+IPPROTO_GMTP = 100
+IPPROTO_DIVERT = 254
+IPPROTO_RAW = 255
+IPPROTO_MAX = 256
+IPPORT_RESERVED = 1024
+IPPORT_USERRESERVED = 5000
+IPPORT_HIFIRSTAUTO = 40000
+IPPORT_HILASTAUTO = 44999
+IPPORT_RESERVEDSTART = 600
+def IN_CLASSA(i): return (((long)(i) & 0x80000000) == 0)
+
+IN_CLASSA_NET = 0xff000000
+IN_CLASSA_NSHIFT = 24
+IN_CLASSA_HOST = 0x00ffffff
+IN_CLASSA_MAX = 128
+def IN_CLASSB(i): return (((long)(i) & 0xc0000000) == 0x80000000)
+
+IN_CLASSB_NET = 0xffff0000
+IN_CLASSB_NSHIFT = 16
+IN_CLASSB_HOST = 0x0000ffff
+IN_CLASSB_MAX = 65536
+def IN_CLASSC(i): return (((long)(i) & 0xe0000000) == 0xc0000000)
+
+IN_CLASSC_NET = 0xffffff00
+IN_CLASSC_NSHIFT = 8
+IN_CLASSC_HOST = 0x000000ff
+def IN_CLASSD(i): return (((long)(i) & 0xf0000000) == 0xe0000000)
+
+IN_CLASSD_NET = 0xf0000000
+IN_CLASSD_NSHIFT = 28
+IN_CLASSD_HOST = 0x0fffffff
+def IN_MULTICAST(i): return IN_CLASSD(i)
+
+def IN_EXPERIMENTAL(i): return (((long)(i) & 0xf0000000) == 0xf0000000)
+
+def IN_BADCLASS(i): return (((long)(i) & 0xf0000000) == 0xf0000000)
+
+INADDR_ANY = 0x00000000
+INADDR_BROADCAST = 0xffffffff
+INADDR_NONE = 0xffffffff
+INADDR_UNSPEC_GROUP = 0xe0000000
+INADDR_ALLHOSTS_GROUP = 0xe0000001
+INADDR_ALLRTRS_GROUP = 0xe0000002
+INADDR_MAX_LOCAL_GROUP = 0xe00000ff
+IN_LOOPBACKNET = 127
+IP_OPTIONS = 1
+IP_HDRINCL = 2
+IP_TOS = 3
+IP_TTL = 4
+IP_RECVOPTS = 5
+IP_RECVRETOPTS = 6
+IP_RECVDSTADDR = 7
+IP_RETOPTS = 8
+IP_MULTICAST_IF = 9
+IP_MULTICAST_TTL = 10
+IP_MULTICAST_LOOP = 11
+IP_ADD_MEMBERSHIP = 12
+IP_DROP_MEMBERSHIP = 13
+IP_MULTICAST_VIF = 14
+IP_RSVP_ON = 15
+IP_RSVP_OFF = 16
+IP_RSVP_VIF_ON = 17
+IP_RSVP_VIF_OFF = 18
+IP_PORTRANGE = 19
+IP_RECVIF = 20
+IP_FW_ADD = 50
+IP_FW_DEL = 51
+IP_FW_FLUSH = 52
+IP_FW_ZERO = 53
+IP_FW_GET = 54
+IP_NAT = 55
+IP_DEFAULT_MULTICAST_TTL = 1
+IP_DEFAULT_MULTICAST_LOOP = 1
+IP_MAX_MEMBERSHIPS = 20
+IP_PORTRANGE_DEFAULT = 0
+IP_PORTRANGE_HIGH = 1
+IP_PORTRANGE_LOW = 2
+IPPROTO_MAXID = (IPPROTO_IDP + 1)
+IPCTL_FORWARDING = 1
+IPCTL_SENDREDIRECTS = 2
+IPCTL_DEFTTL = 3
+IPCTL_DEFMTU = 4
+IPCTL_RTEXPIRE = 5
+IPCTL_RTMINEXPIRE = 6
+IPCTL_RTMAXCACHE = 7
+IPCTL_SOURCEROUTE = 8
+IPCTL_DIRECTEDBROADCAST = 9
+IPCTL_INTRQMAXLEN = 10
+IPCTL_INTRQDROPS = 11
+IPCTL_ACCEPTSOURCEROUTE = 13
+IPCTL_MAXID = 13
+IP_NAT_IN = 0x00000001
+IP_NAT_OUT = 0x00000002

Added: vendor/Python/current/Lib/plat-freebsd2/regen
===================================================================
--- vendor/Python/current/Lib/plat-freebsd2/regen	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-freebsd2/regen	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,3 @@
+#! /bin/sh
+set -v
+h2py -i '(u_long)' /usr/include/netinet/in.h


Property changes on: vendor/Python/current/Lib/plat-freebsd2/regen
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/plat-freebsd3/IN.py
===================================================================
--- vendor/Python/current/Lib/plat-freebsd3/IN.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-freebsd3/IN.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,189 @@
+# Generated by h2py from /usr/include/netinet/in.h
+IPPROTO_IP = 0
+IPPROTO_ICMP = 1
+IPPROTO_IGMP = 2
+IPPROTO_GGP = 3
+IPPROTO_IPIP = 4
+IPPROTO_TCP = 6
+IPPROTO_ST = 7
+IPPROTO_EGP = 8
+IPPROTO_PIGP = 9
+IPPROTO_RCCMON = 10
+IPPROTO_NVPII = 11
+IPPROTO_PUP = 12
+IPPROTO_ARGUS = 13
+IPPROTO_EMCON = 14
+IPPROTO_XNET = 15
+IPPROTO_CHAOS = 16
+IPPROTO_UDP = 17
+IPPROTO_MUX = 18
+IPPROTO_MEAS = 19
+IPPROTO_HMP = 20
+IPPROTO_PRM = 21
+IPPROTO_IDP = 22
+IPPROTO_TRUNK1 = 23
+IPPROTO_TRUNK2 = 24
+IPPROTO_LEAF1 = 25
+IPPROTO_LEAF2 = 26
+IPPROTO_RDP = 27
+IPPROTO_IRTP = 28
+IPPROTO_TP = 29
+IPPROTO_BLT = 30
+IPPROTO_NSP = 31
+IPPROTO_INP = 32
+IPPROTO_SEP = 33
+IPPROTO_3PC = 34
+IPPROTO_IDPR = 35
+IPPROTO_XTP = 36
+IPPROTO_DDP = 37
+IPPROTO_CMTP = 38
+IPPROTO_TPXX = 39
+IPPROTO_IL = 40
+IPPROTO_SIP = 41
+IPPROTO_SDRP = 42
+IPPROTO_SIPSR = 43
+IPPROTO_SIPFRAG = 44
+IPPROTO_IDRP = 45
+IPPROTO_RSVP = 46
+IPPROTO_GRE = 47
+IPPROTO_MHRP = 48
+IPPROTO_BHA = 49
+IPPROTO_ESP = 50
+IPPROTO_AH = 51
+IPPROTO_INLSP = 52
+IPPROTO_SWIPE = 53
+IPPROTO_NHRP = 54
+IPPROTO_AHIP = 61
+IPPROTO_CFTP = 62
+IPPROTO_HELLO = 63
+IPPROTO_SATEXPAK = 64
+IPPROTO_KRYPTOLAN = 65
+IPPROTO_RVD = 66
+IPPROTO_IPPC = 67
+IPPROTO_ADFS = 68
+IPPROTO_SATMON = 69
+IPPROTO_VISA = 70
+IPPROTO_IPCV = 71
+IPPROTO_CPNX = 72
+IPPROTO_CPHB = 73
+IPPROTO_WSN = 74
+IPPROTO_PVP = 75
+IPPROTO_BRSATMON = 76
+IPPROTO_ND = 77
+IPPROTO_WBMON = 78
+IPPROTO_WBEXPAK = 79
+IPPROTO_EON = 80
+IPPROTO_VMTP = 81
+IPPROTO_SVMTP = 82
+IPPROTO_VINES = 83
+IPPROTO_TTP = 84
+IPPROTO_IGP = 85
+IPPROTO_DGP = 86
+IPPROTO_TCF = 87
+IPPROTO_IGRP = 88
+IPPROTO_OSPFIGP = 89
+IPPROTO_SRPC = 90
+IPPROTO_LARP = 91
+IPPROTO_MTP = 92
+IPPROTO_AX25 = 93
+IPPROTO_IPEIP = 94
+IPPROTO_MICP = 95
+IPPROTO_SCCSP = 96
+IPPROTO_ETHERIP = 97
+IPPROTO_ENCAP = 98
+IPPROTO_APES = 99
+IPPROTO_GMTP = 100
+IPPROTO_DIVERT = 254
+IPPROTO_RAW = 255
+IPPROTO_MAX = 256
+IPPORT_RESERVED = 1024
+IPPORT_USERRESERVED = 5000
+IPPORT_HIFIRSTAUTO = 49152
+IPPORT_HILASTAUTO = 65535
+IPPORT_RESERVEDSTART = 600
+def IN_CLASSA(i): return (((long)(i) & 0x80000000) == 0)
+
+IN_CLASSA_NET = 0xff000000
+IN_CLASSA_NSHIFT = 24
+IN_CLASSA_HOST = 0x00ffffff
+IN_CLASSA_MAX = 128
+def IN_CLASSB(i): return (((long)(i) & 0xc0000000) == 0x80000000)
+
+IN_CLASSB_NET = 0xffff0000
+IN_CLASSB_NSHIFT = 16
+IN_CLASSB_HOST = 0x0000ffff
+IN_CLASSB_MAX = 65536
+def IN_CLASSC(i): return (((long)(i) & 0xe0000000) == 0xc0000000)
+
+IN_CLASSC_NET = 0xffffff00
+IN_CLASSC_NSHIFT = 8
+IN_CLASSC_HOST = 0x000000ff
+def IN_CLASSD(i): return (((long)(i) & 0xf0000000) == 0xe0000000)
+
+IN_CLASSD_NET = 0xf0000000
+IN_CLASSD_NSHIFT = 28
+IN_CLASSD_HOST = 0x0fffffff
+def IN_MULTICAST(i): return IN_CLASSD(i)
+
+def IN_EXPERIMENTAL(i): return (((long)(i) & 0xf0000000) == 0xf0000000)
+
+def IN_BADCLASS(i): return (((long)(i) & 0xf0000000) == 0xf0000000)
+
+INADDR_ANY = 0x00000000
+INADDR_LOOPBACK = 0x7f000001
+INADDR_BROADCAST = 0xffffffff
+INADDR_NONE = 0xffffffff
+INADDR_UNSPEC_GROUP = 0xe0000000
+INADDR_ALLHOSTS_GROUP = 0xe0000001
+INADDR_ALLRTRS_GROUP = 0xe0000002
+INADDR_MAX_LOCAL_GROUP = 0xe00000ff
+IN_LOOPBACKNET = 127
+IP_OPTIONS = 1
+IP_HDRINCL = 2
+IP_TOS = 3
+IP_TTL = 4
+IP_RECVOPTS = 5
+IP_RECVRETOPTS = 6
+IP_RECVDSTADDR = 7
+IP_RETOPTS = 8
+IP_MULTICAST_IF = 9
+IP_MULTICAST_TTL = 10
+IP_MULTICAST_LOOP = 11
+IP_ADD_MEMBERSHIP = 12
+IP_DROP_MEMBERSHIP = 13
+IP_MULTICAST_VIF = 14
+IP_RSVP_ON = 15
+IP_RSVP_OFF = 16
+IP_RSVP_VIF_ON = 17
+IP_RSVP_VIF_OFF = 18
+IP_PORTRANGE = 19
+IP_RECVIF = 20
+IP_FW_ADD = 50
+IP_FW_DEL = 51
+IP_FW_FLUSH = 52
+IP_FW_ZERO = 53
+IP_FW_GET = 54
+IP_NAT = 55
+IP_DEFAULT_MULTICAST_TTL = 1
+IP_DEFAULT_MULTICAST_LOOP = 1
+IP_MAX_MEMBERSHIPS = 20
+IP_PORTRANGE_DEFAULT = 0
+IP_PORTRANGE_HIGH = 1
+IP_PORTRANGE_LOW = 2
+IPPROTO_MAXID = (IPPROTO_IDP + 1)
+IPCTL_FORWARDING = 1
+IPCTL_SENDREDIRECTS = 2
+IPCTL_DEFTTL = 3
+IPCTL_DEFMTU = 4
+IPCTL_RTEXPIRE = 5
+IPCTL_RTMINEXPIRE = 6
+IPCTL_RTMAXCACHE = 7
+IPCTL_SOURCEROUTE = 8
+IPCTL_DIRECTEDBROADCAST = 9
+IPCTL_INTRQMAXLEN = 10
+IPCTL_INTRQDROPS = 11
+IPCTL_STATS = 12
+IPCTL_ACCEPTSOURCEROUTE = 13
+IPCTL_MAXID = 14
+IP_NAT_IN = 0x00000001
+IP_NAT_OUT = 0x00000002

Added: vendor/Python/current/Lib/plat-freebsd3/regen
===================================================================
--- vendor/Python/current/Lib/plat-freebsd3/regen	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-freebsd3/regen	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,4 @@
+#! /bin/sh
+set -v
+h2py -i '(u_long)' /usr/include/netinet/in.h
+


Property changes on: vendor/Python/current/Lib/plat-freebsd3/regen
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/plat-freebsd4/IN.py
===================================================================
--- vendor/Python/current/Lib/plat-freebsd4/IN.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-freebsd4/IN.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,355 @@
+# Generated by h2py from /usr/include/netinet/in.h
+IPPROTO_IP = 0
+IPPROTO_HOPOPTS = 0
+IPPROTO_ICMP = 1
+IPPROTO_IGMP = 2
+IPPROTO_GGP = 3
+IPPROTO_IPV4 = 4
+IPPROTO_IPIP = IPPROTO_IPV4
+IPPROTO_TCP = 6
+IPPROTO_ST = 7
+IPPROTO_EGP = 8
+IPPROTO_PIGP = 9
+IPPROTO_RCCMON = 10
+IPPROTO_NVPII = 11
+IPPROTO_PUP = 12
+IPPROTO_ARGUS = 13
+IPPROTO_EMCON = 14
+IPPROTO_XNET = 15
+IPPROTO_CHAOS = 16
+IPPROTO_UDP = 17
+IPPROTO_MUX = 18
+IPPROTO_MEAS = 19
+IPPROTO_HMP = 20
+IPPROTO_PRM = 21
+IPPROTO_IDP = 22
+IPPROTO_TRUNK1 = 23
+IPPROTO_TRUNK2 = 24
+IPPROTO_LEAF1 = 25
+IPPROTO_LEAF2 = 26
+IPPROTO_RDP = 27
+IPPROTO_IRTP = 28
+IPPROTO_TP = 29
+IPPROTO_BLT = 30
+IPPROTO_NSP = 31
+IPPROTO_INP = 32
+IPPROTO_SEP = 33
+IPPROTO_3PC = 34
+IPPROTO_IDPR = 35
+IPPROTO_XTP = 36
+IPPROTO_DDP = 37
+IPPROTO_CMTP = 38
+IPPROTO_TPXX = 39
+IPPROTO_IL = 40
+IPPROTO_IPV6 = 41
+IPPROTO_SDRP = 42
+IPPROTO_ROUTING = 43
+IPPROTO_FRAGMENT = 44
+IPPROTO_IDRP = 45
+IPPROTO_RSVP = 46
+IPPROTO_GRE = 47
+IPPROTO_MHRP = 48
+IPPROTO_BHA = 49
+IPPROTO_ESP = 50
+IPPROTO_AH = 51
+IPPROTO_INLSP = 52
+IPPROTO_SWIPE = 53
+IPPROTO_NHRP = 54
+IPPROTO_ICMPV6 = 58
+IPPROTO_NONE = 59
+IPPROTO_DSTOPTS = 60
+IPPROTO_AHIP = 61
+IPPROTO_CFTP = 62
+IPPROTO_HELLO = 63
+IPPROTO_SATEXPAK = 64
+IPPROTO_KRYPTOLAN = 65
+IPPROTO_RVD = 66
+IPPROTO_IPPC = 67
+IPPROTO_ADFS = 68
+IPPROTO_SATMON = 69
+IPPROTO_VISA = 70
+IPPROTO_IPCV = 71
+IPPROTO_CPNX = 72
+IPPROTO_CPHB = 73
+IPPROTO_WSN = 74
+IPPROTO_PVP = 75
+IPPROTO_BRSATMON = 76
+IPPROTO_ND = 77
+IPPROTO_WBMON = 78
+IPPROTO_WBEXPAK = 79
+IPPROTO_EON = 80
+IPPROTO_VMTP = 81
+IPPROTO_SVMTP = 82
+IPPROTO_VINES = 83
+IPPROTO_TTP = 84
+IPPROTO_IGP = 85
+IPPROTO_DGP = 86
+IPPROTO_TCF = 87
+IPPROTO_IGRP = 88
+IPPROTO_OSPFIGP = 89
+IPPROTO_SRPC = 90
+IPPROTO_LARP = 91
+IPPROTO_MTP = 92
+IPPROTO_AX25 = 93
+IPPROTO_IPEIP = 94
+IPPROTO_MICP = 95
+IPPROTO_SCCSP = 96
+IPPROTO_ETHERIP = 97
+IPPROTO_ENCAP = 98
+IPPROTO_APES = 99
+IPPROTO_GMTP = 100
+IPPROTO_IPCOMP = 108
+IPPROTO_PIM = 103
+IPPROTO_PGM = 113
+IPPROTO_DIVERT = 254
+IPPROTO_RAW = 255
+IPPROTO_MAX = 256
+IPPROTO_DONE = 257
+IPPORT_RESERVED = 1024
+IPPORT_USERRESERVED = 5000
+IPPORT_HIFIRSTAUTO = 49152
+IPPORT_HILASTAUTO = 65535
+IPPORT_RESERVEDSTART = 600
+def IN_CLASSA(i): return (((u_int32_t)(i) & 0x80000000) == 0)
+
+IN_CLASSA_NET = 0xff000000
+IN_CLASSA_NSHIFT = 24
+IN_CLASSA_HOST = 0x00ffffff
+IN_CLASSA_MAX = 128
+def IN_CLASSB(i): return (((u_int32_t)(i) & 0xc0000000) == 0x80000000)
+
+IN_CLASSB_NET = 0xffff0000
+IN_CLASSB_NSHIFT = 16
+IN_CLASSB_HOST = 0x0000ffff
+IN_CLASSB_MAX = 65536
+def IN_CLASSC(i): return (((u_int32_t)(i) & 0xe0000000) == 0xc0000000)
+
+IN_CLASSC_NET = 0xffffff00
+IN_CLASSC_NSHIFT = 8
+IN_CLASSC_HOST = 0x000000ff
+def IN_CLASSD(i): return (((u_int32_t)(i) & 0xf0000000) == 0xe0000000)
+
+IN_CLASSD_NET = 0xf0000000
+IN_CLASSD_NSHIFT = 28
+IN_CLASSD_HOST = 0x0fffffff
+def IN_MULTICAST(i): return IN_CLASSD(i)
+
+def IN_EXPERIMENTAL(i): return (((u_int32_t)(i) & 0xf0000000) == 0xf0000000)
+
+def IN_BADCLASS(i): return (((u_int32_t)(i) & 0xf0000000) == 0xf0000000)
+
+INADDR_NONE = 0xffffffff
+IN_LOOPBACKNET = 127
+INET_ADDRSTRLEN = 16
+IP_OPTIONS = 1
+IP_HDRINCL = 2
+IP_TOS = 3
+IP_TTL = 4
+IP_RECVOPTS = 5
+IP_RECVRETOPTS = 6
+IP_RECVDSTADDR = 7
+IP_RETOPTS = 8
+IP_MULTICAST_IF = 9
+IP_MULTICAST_TTL = 10
+IP_MULTICAST_LOOP = 11
+IP_ADD_MEMBERSHIP = 12
+IP_DROP_MEMBERSHIP = 13
+IP_MULTICAST_VIF = 14
+IP_RSVP_ON = 15
+IP_RSVP_OFF = 16
+IP_RSVP_VIF_ON = 17
+IP_RSVP_VIF_OFF = 18
+IP_PORTRANGE = 19
+IP_RECVIF = 20
+IP_IPSEC_POLICY = 21
+IP_FAITH = 22
+IP_FW_ADD = 50
+IP_FW_DEL = 51
+IP_FW_FLUSH = 52
+IP_FW_ZERO = 53
+IP_FW_GET = 54
+IP_FW_RESETLOG = 55
+IP_DUMMYNET_CONFIGURE = 60
+IP_DUMMYNET_DEL = 61
+IP_DUMMYNET_FLUSH = 62
+IP_DUMMYNET_GET = 64
+IP_DEFAULT_MULTICAST_TTL = 1
+IP_DEFAULT_MULTICAST_LOOP = 1
+IP_MAX_MEMBERSHIPS = 20
+IP_PORTRANGE_DEFAULT = 0
+IP_PORTRANGE_HIGH = 1
+IP_PORTRANGE_LOW = 2
+IPPROTO_MAXID = (IPPROTO_AH + 1)
+IPCTL_FORWARDING = 1
+IPCTL_SENDREDIRECTS = 2
+IPCTL_DEFTTL = 3
+IPCTL_DEFMTU = 4
+IPCTL_RTEXPIRE = 5
+IPCTL_RTMINEXPIRE = 6
+IPCTL_RTMAXCACHE = 7
+IPCTL_SOURCEROUTE = 8
+IPCTL_DIRECTEDBROADCAST = 9
+IPCTL_INTRQMAXLEN = 10
+IPCTL_INTRQDROPS = 11
+IPCTL_STATS = 12
+IPCTL_ACCEPTSOURCEROUTE = 13
+IPCTL_FASTFORWARDING = 14
+IPCTL_KEEPFAITH = 15
+IPCTL_GIF_TTL = 16
+IPCTL_MAXID = 17
+
+# Included from netinet6/in6.h
+
+# Included from sys/queue.h
+def SLIST_HEAD_INITIALIZER(head): return \
+
+def SLIST_ENTRY(type): return \
+
+def STAILQ_HEAD_INITIALIZER(head): return \
+
+def STAILQ_ENTRY(type): return \
+
+def LIST_HEAD_INITIALIZER(head): return \
+
+def LIST_ENTRY(type): return \
+
+def TAILQ_HEAD_INITIALIZER(head): return \
+
+def TAILQ_ENTRY(type): return \
+
+def CIRCLEQ_ENTRY(type): return \
+
+__KAME_VERSION = "20000701/FreeBSD-current"
+IPV6PORT_RESERVED = 1024
+IPV6PORT_ANONMIN = 49152
+IPV6PORT_ANONMAX = 65535
+IPV6PORT_RESERVEDMIN = 600
+IPV6PORT_RESERVEDMAX = (IPV6PORT_RESERVED-1)
+INET6_ADDRSTRLEN = 46
+IPV6_ADDR_INT32_ONE = 1
+IPV6_ADDR_INT32_TWO = 2
+IPV6_ADDR_INT32_MNL = 0xff010000
+IPV6_ADDR_INT32_MLL = 0xff020000
+IPV6_ADDR_INT32_SMP = 0x0000ffff
+IPV6_ADDR_INT16_ULL = 0xfe80
+IPV6_ADDR_INT16_USL = 0xfec0
+IPV6_ADDR_INT16_MLL = 0xff02
+IPV6_ADDR_INT32_ONE = 0x01000000
+IPV6_ADDR_INT32_TWO = 0x02000000
+IPV6_ADDR_INT32_MNL = 0x000001ff
+IPV6_ADDR_INT32_MLL = 0x000002ff
+IPV6_ADDR_INT32_SMP = 0xffff0000
+IPV6_ADDR_INT16_ULL = 0x80fe
+IPV6_ADDR_INT16_USL = 0xc0fe
+IPV6_ADDR_INT16_MLL = 0x02ff
+def IN6_IS_ADDR_UNSPECIFIED(a): return \
+
+def IN6_IS_ADDR_LOOPBACK(a): return \
+
+def IN6_IS_ADDR_V4COMPAT(a): return \
+
+def IN6_IS_ADDR_V4MAPPED(a): return \
+
+IPV6_ADDR_SCOPE_NODELOCAL = 0x01
+IPV6_ADDR_SCOPE_LINKLOCAL = 0x02
+IPV6_ADDR_SCOPE_SITELOCAL = 0x05
+IPV6_ADDR_SCOPE_ORGLOCAL = 0x08
+IPV6_ADDR_SCOPE_GLOBAL = 0x0e
+__IPV6_ADDR_SCOPE_NODELOCAL = 0x01
+__IPV6_ADDR_SCOPE_LINKLOCAL = 0x02
+__IPV6_ADDR_SCOPE_SITELOCAL = 0x05
+__IPV6_ADDR_SCOPE_ORGLOCAL = 0x08
+__IPV6_ADDR_SCOPE_GLOBAL = 0x0e
+def IN6_IS_ADDR_LINKLOCAL(a): return \
+
+def IN6_IS_ADDR_SITELOCAL(a): return \
+
+def IN6_IS_ADDR_MC_NODELOCAL(a): return \
+
+def IN6_IS_ADDR_MC_LINKLOCAL(a): return \
+
+def IN6_IS_ADDR_MC_SITELOCAL(a): return \
+
+def IN6_IS_ADDR_MC_ORGLOCAL(a): return \
+
+def IN6_IS_ADDR_MC_GLOBAL(a): return \
+
+def IN6_IS_ADDR_MC_NODELOCAL(a): return \
+
+def IN6_IS_ADDR_MC_LINKLOCAL(a): return \
+
+def IN6_IS_ADDR_MC_SITELOCAL(a): return \
+
+def IN6_IS_ADDR_MC_ORGLOCAL(a): return \
+
+def IN6_IS_ADDR_MC_GLOBAL(a): return \
+
+def IN6_IS_SCOPE_LINKLOCAL(a): return \
+
+IPV6_OPTIONS = 1
+IPV6_RECVOPTS = 5
+IPV6_RECVRETOPTS = 6
+IPV6_RECVDSTADDR = 7
+IPV6_RETOPTS = 8
+IPV6_SOCKOPT_RESERVED1 = 3
+IPV6_UNICAST_HOPS = 4
+IPV6_MULTICAST_IF = 9
+IPV6_MULTICAST_HOPS = 10
+IPV6_MULTICAST_LOOP = 11
+IPV6_JOIN_GROUP = 12
+IPV6_LEAVE_GROUP = 13
+IPV6_PORTRANGE = 14
+ICMP6_FILTER = 18
+IPV6_PKTINFO = 19
+IPV6_HOPLIMIT = 20
+IPV6_NEXTHOP = 21
+IPV6_HOPOPTS = 22
+IPV6_DSTOPTS = 23
+IPV6_RTHDR = 24
+IPV6_PKTOPTIONS = 25
+IPV6_CHECKSUM = 26
+IPV6_BINDV6ONLY = 27
+IPV6_IPSEC_POLICY = 28
+IPV6_FAITH = 29
+IPV6_FW_ADD = 30
+IPV6_FW_DEL = 31
+IPV6_FW_FLUSH = 32
+IPV6_FW_ZERO = 33
+IPV6_FW_GET = 34
+IPV6_RTHDR_LOOSE = 0
+IPV6_RTHDR_STRICT = 1
+IPV6_RTHDR_TYPE_0 = 0
+IPV6_DEFAULT_MULTICAST_HOPS = 1
+IPV6_DEFAULT_MULTICAST_LOOP = 1
+IPV6_PORTRANGE_DEFAULT = 0
+IPV6_PORTRANGE_HIGH = 1
+IPV6_PORTRANGE_LOW = 2
+IPV6PROTO_MAXID = (IPPROTO_PIM + 1)
+IPV6CTL_FORWARDING = 1
+IPV6CTL_SENDREDIRECTS = 2
+IPV6CTL_DEFHLIM = 3
+IPV6CTL_DEFMTU = 4
+IPV6CTL_FORWSRCRT = 5
+IPV6CTL_STATS = 6
+IPV6CTL_MRTSTATS = 7
+IPV6CTL_MRTPROTO = 8
+IPV6CTL_MAXFRAGPACKETS = 9
+IPV6CTL_SOURCECHECK = 10
+IPV6CTL_SOURCECHECK_LOGINT = 11
+IPV6CTL_ACCEPT_RTADV = 12
+IPV6CTL_KEEPFAITH = 13
+IPV6CTL_LOG_INTERVAL = 14
+IPV6CTL_HDRNESTLIMIT = 15
+IPV6CTL_DAD_COUNT = 16
+IPV6CTL_AUTO_FLOWLABEL = 17
+IPV6CTL_DEFMCASTHLIM = 18
+IPV6CTL_GIF_HLIM = 19
+IPV6CTL_KAME_VERSION = 20
+IPV6CTL_USE_DEPRECATED = 21
+IPV6CTL_RR_PRUNE = 22
+IPV6CTL_MAPPED_ADDR = 23
+IPV6CTL_BINDV6ONLY = 24
+IPV6CTL_RTEXPIRE = 25
+IPV6CTL_RTMINEXPIRE = 26
+IPV6CTL_RTMAXCACHE = 27
+IPV6CTL_MAXID = 28

Added: vendor/Python/current/Lib/plat-freebsd4/regen
===================================================================
--- vendor/Python/current/Lib/plat-freebsd4/regen	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-freebsd4/regen	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,3 @@
+#! /bin/sh
+set -v
+python ../../Tools/scripts/h2py.py -i '(u_long)' /usr/include/netinet/in.h

Added: vendor/Python/current/Lib/plat-freebsd5/IN.py
===================================================================
--- vendor/Python/current/Lib/plat-freebsd5/IN.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-freebsd5/IN.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,355 @@
+# Generated by h2py from /usr/include/netinet/in.h
+IPPROTO_IP = 0
+IPPROTO_HOPOPTS = 0
+IPPROTO_ICMP = 1
+IPPROTO_IGMP = 2
+IPPROTO_GGP = 3
+IPPROTO_IPV4 = 4
+IPPROTO_IPIP = IPPROTO_IPV4
+IPPROTO_TCP = 6
+IPPROTO_ST = 7
+IPPROTO_EGP = 8
+IPPROTO_PIGP = 9
+IPPROTO_RCCMON = 10
+IPPROTO_NVPII = 11
+IPPROTO_PUP = 12
+IPPROTO_ARGUS = 13
+IPPROTO_EMCON = 14
+IPPROTO_XNET = 15
+IPPROTO_CHAOS = 16
+IPPROTO_UDP = 17
+IPPROTO_MUX = 18
+IPPROTO_MEAS = 19
+IPPROTO_HMP = 20
+IPPROTO_PRM = 21
+IPPROTO_IDP = 22
+IPPROTO_TRUNK1 = 23
+IPPROTO_TRUNK2 = 24
+IPPROTO_LEAF1 = 25
+IPPROTO_LEAF2 = 26
+IPPROTO_RDP = 27
+IPPROTO_IRTP = 28
+IPPROTO_TP = 29
+IPPROTO_BLT = 30
+IPPROTO_NSP = 31
+IPPROTO_INP = 32
+IPPROTO_SEP = 33
+IPPROTO_3PC = 34
+IPPROTO_IDPR = 35
+IPPROTO_XTP = 36
+IPPROTO_DDP = 37
+IPPROTO_CMTP = 38
+IPPROTO_TPXX = 39
+IPPROTO_IL = 40
+IPPROTO_IPV6 = 41
+IPPROTO_SDRP = 42
+IPPROTO_ROUTING = 43
+IPPROTO_FRAGMENT = 44
+IPPROTO_IDRP = 45
+IPPROTO_RSVP = 46
+IPPROTO_GRE = 47
+IPPROTO_MHRP = 48
+IPPROTO_BHA = 49
+IPPROTO_ESP = 50
+IPPROTO_AH = 51
+IPPROTO_INLSP = 52
+IPPROTO_SWIPE = 53
+IPPROTO_NHRP = 54
+IPPROTO_ICMPV6 = 58
+IPPROTO_NONE = 59
+IPPROTO_DSTOPTS = 60
+IPPROTO_AHIP = 61
+IPPROTO_CFTP = 62
+IPPROTO_HELLO = 63
+IPPROTO_SATEXPAK = 64
+IPPROTO_KRYPTOLAN = 65
+IPPROTO_RVD = 66
+IPPROTO_IPPC = 67
+IPPROTO_ADFS = 68
+IPPROTO_SATMON = 69
+IPPROTO_VISA = 70
+IPPROTO_IPCV = 71
+IPPROTO_CPNX = 72
+IPPROTO_CPHB = 73
+IPPROTO_WSN = 74
+IPPROTO_PVP = 75
+IPPROTO_BRSATMON = 76
+IPPROTO_ND = 77
+IPPROTO_WBMON = 78
+IPPROTO_WBEXPAK = 79
+IPPROTO_EON = 80
+IPPROTO_VMTP = 81
+IPPROTO_SVMTP = 82
+IPPROTO_VINES = 83
+IPPROTO_TTP = 84
+IPPROTO_IGP = 85
+IPPROTO_DGP = 86
+IPPROTO_TCF = 87
+IPPROTO_IGRP = 88
+IPPROTO_OSPFIGP = 89
+IPPROTO_SRPC = 90
+IPPROTO_LARP = 91
+IPPROTO_MTP = 92
+IPPROTO_AX25 = 93
+IPPROTO_IPEIP = 94
+IPPROTO_MICP = 95
+IPPROTO_SCCSP = 96
+IPPROTO_ETHERIP = 97
+IPPROTO_ENCAP = 98
+IPPROTO_APES = 99
+IPPROTO_GMTP = 100
+IPPROTO_IPCOMP = 108
+IPPROTO_PIM = 103
+IPPROTO_PGM = 113
+IPPROTO_DIVERT = 254
+IPPROTO_RAW = 255
+IPPROTO_MAX = 256
+IPPROTO_DONE = 257
+IPPORT_RESERVED = 1024
+IPPORT_USERRESERVED = 5000
+IPPORT_HIFIRSTAUTO = 49152
+IPPORT_HILASTAUTO = 65535
+IPPORT_RESERVEDSTART = 600
+def IN_CLASSA(i): return (((u_int32_t)(i) & 0x80000000) == 0)
+
+IN_CLASSA_NET = 0xff000000
+IN_CLASSA_NSHIFT = 24
+IN_CLASSA_HOST = 0x00ffffff
+IN_CLASSA_MAX = 128
+def IN_CLASSB(i): return (((u_int32_t)(i) & 0xc0000000) == 0x80000000)
+
+IN_CLASSB_NET = 0xffff0000
+IN_CLASSB_NSHIFT = 16
+IN_CLASSB_HOST = 0x0000ffff
+IN_CLASSB_MAX = 65536
+def IN_CLASSC(i): return (((u_int32_t)(i) & 0xe0000000) == 0xc0000000)
+
+IN_CLASSC_NET = 0xffffff00
+IN_CLASSC_NSHIFT = 8
+IN_CLASSC_HOST = 0x000000ff
+def IN_CLASSD(i): return (((u_int32_t)(i) & 0xf0000000) == 0xe0000000)
+
+IN_CLASSD_NET = 0xf0000000
+IN_CLASSD_NSHIFT = 28
+IN_CLASSD_HOST = 0x0fffffff
+def IN_MULTICAST(i): return IN_CLASSD(i)
+
+def IN_EXPERIMENTAL(i): return (((u_int32_t)(i) & 0xf0000000) == 0xf0000000)
+
+def IN_BADCLASS(i): return (((u_int32_t)(i) & 0xf0000000) == 0xf0000000)
+
+INADDR_NONE = 0xffffffff
+IN_LOOPBACKNET = 127
+INET_ADDRSTRLEN = 16
+IP_OPTIONS = 1
+IP_HDRINCL = 2
+IP_TOS = 3
+IP_TTL = 4
+IP_RECVOPTS = 5
+IP_RECVRETOPTS = 6
+IP_RECVDSTADDR = 7
+IP_RETOPTS = 8
+IP_MULTICAST_IF = 9
+IP_MULTICAST_TTL = 10
+IP_MULTICAST_LOOP = 11
+IP_ADD_MEMBERSHIP = 12
+IP_DROP_MEMBERSHIP = 13
+IP_MULTICAST_VIF = 14
+IP_RSVP_ON = 15
+IP_RSVP_OFF = 16
+IP_RSVP_VIF_ON = 17
+IP_RSVP_VIF_OFF = 18
+IP_PORTRANGE = 19
+IP_RECVIF = 20
+IP_IPSEC_POLICY = 21
+IP_FAITH = 22
+IP_FW_ADD = 50
+IP_FW_DEL = 51
+IP_FW_FLUSH = 52
+IP_FW_ZERO = 53
+IP_FW_GET = 54
+IP_FW_RESETLOG = 55
+IP_DUMMYNET_CONFIGURE = 60
+IP_DUMMYNET_DEL = 61
+IP_DUMMYNET_FLUSH = 62
+IP_DUMMYNET_GET = 64
+IP_DEFAULT_MULTICAST_TTL = 1
+IP_DEFAULT_MULTICAST_LOOP = 1
+IP_MAX_MEMBERSHIPS = 20
+IP_PORTRANGE_DEFAULT = 0
+IP_PORTRANGE_HIGH = 1
+IP_PORTRANGE_LOW = 2
+IPPROTO_MAXID = (IPPROTO_AH + 1)
+IPCTL_FORWARDING = 1
+IPCTL_SENDREDIRECTS = 2
+IPCTL_DEFTTL = 3
+IPCTL_DEFMTU = 4
+IPCTL_RTEXPIRE = 5
+IPCTL_RTMINEXPIRE = 6
+IPCTL_RTMAXCACHE = 7
+IPCTL_SOURCEROUTE = 8
+IPCTL_DIRECTEDBROADCAST = 9
+IPCTL_INTRQMAXLEN = 10
+IPCTL_INTRQDROPS = 11
+IPCTL_STATS = 12
+IPCTL_ACCEPTSOURCEROUTE = 13
+IPCTL_FASTFORWARDING = 14
+IPCTL_KEEPFAITH = 15
+IPCTL_GIF_TTL = 16
+IPCTL_MAXID = 17
+
+# Included from netinet6/in6.h
+
+# Included from sys/queue.h
+def SLIST_HEAD_INITIALIZER(head): return \
+
+def SLIST_ENTRY(type): return \
+
+def STAILQ_HEAD_INITIALIZER(head): return \
+
+def STAILQ_ENTRY(type): return \
+
+def LIST_HEAD_INITIALIZER(head): return \
+
+def LIST_ENTRY(type): return \
+
+def TAILQ_HEAD_INITIALIZER(head): return \
+
+def TAILQ_ENTRY(type): return \
+
+def CIRCLEQ_ENTRY(type): return \
+
+__KAME_VERSION = "20000701/FreeBSD-current"
+IPV6PORT_RESERVED = 1024
+IPV6PORT_ANONMIN = 49152
+IPV6PORT_ANONMAX = 65535
+IPV6PORT_RESERVEDMIN = 600
+IPV6PORT_RESERVEDMAX = (IPV6PORT_RESERVED-1)
+INET6_ADDRSTRLEN = 46
+IPV6_ADDR_INT32_ONE = 1
+IPV6_ADDR_INT32_TWO = 2
+IPV6_ADDR_INT32_MNL = 0xff010000
+IPV6_ADDR_INT32_MLL = 0xff020000
+IPV6_ADDR_INT32_SMP = 0x0000ffff
+IPV6_ADDR_INT16_ULL = 0xfe80
+IPV6_ADDR_INT16_USL = 0xfec0
+IPV6_ADDR_INT16_MLL = 0xff02
+IPV6_ADDR_INT32_ONE = 0x01000000
+IPV6_ADDR_INT32_TWO = 0x02000000
+IPV6_ADDR_INT32_MNL = 0x000001ff
+IPV6_ADDR_INT32_MLL = 0x000002ff
+IPV6_ADDR_INT32_SMP = 0xffff0000
+IPV6_ADDR_INT16_ULL = 0x80fe
+IPV6_ADDR_INT16_USL = 0xc0fe
+IPV6_ADDR_INT16_MLL = 0x02ff
+def IN6_IS_ADDR_UNSPECIFIED(a): return \
+
+def IN6_IS_ADDR_LOOPBACK(a): return \
+
+def IN6_IS_ADDR_V4COMPAT(a): return \
+
+def IN6_IS_ADDR_V4MAPPED(a): return \
+
+IPV6_ADDR_SCOPE_NODELOCAL = 0x01
+IPV6_ADDR_SCOPE_LINKLOCAL = 0x02
+IPV6_ADDR_SCOPE_SITELOCAL = 0x05
+IPV6_ADDR_SCOPE_ORGLOCAL = 0x08
+IPV6_ADDR_SCOPE_GLOBAL = 0x0e
+__IPV6_ADDR_SCOPE_NODELOCAL = 0x01
+__IPV6_ADDR_SCOPE_LINKLOCAL = 0x02
+__IPV6_ADDR_SCOPE_SITELOCAL = 0x05
+__IPV6_ADDR_SCOPE_ORGLOCAL = 0x08
+__IPV6_ADDR_SCOPE_GLOBAL = 0x0e
+def IN6_IS_ADDR_LINKLOCAL(a): return \
+
+def IN6_IS_ADDR_SITELOCAL(a): return \
+
+def IN6_IS_ADDR_MC_NODELOCAL(a): return \
+
+def IN6_IS_ADDR_MC_LINKLOCAL(a): return \
+
+def IN6_IS_ADDR_MC_SITELOCAL(a): return \
+
+def IN6_IS_ADDR_MC_ORGLOCAL(a): return \
+
+def IN6_IS_ADDR_MC_GLOBAL(a): return \
+
+def IN6_IS_ADDR_MC_NODELOCAL(a): return \
+
+def IN6_IS_ADDR_MC_LINKLOCAL(a): return \
+
+def IN6_IS_ADDR_MC_SITELOCAL(a): return \
+
+def IN6_IS_ADDR_MC_ORGLOCAL(a): return \
+
+def IN6_IS_ADDR_MC_GLOBAL(a): return \
+
+def IN6_IS_SCOPE_LINKLOCAL(a): return \
+
+IPV6_OPTIONS = 1
+IPV6_RECVOPTS = 5
+IPV6_RECVRETOPTS = 6
+IPV6_RECVDSTADDR = 7
+IPV6_RETOPTS = 8
+IPV6_SOCKOPT_RESERVED1 = 3
+IPV6_UNICAST_HOPS = 4
+IPV6_MULTICAST_IF = 9
+IPV6_MULTICAST_HOPS = 10
+IPV6_MULTICAST_LOOP = 11
+IPV6_JOIN_GROUP = 12
+IPV6_LEAVE_GROUP = 13
+IPV6_PORTRANGE = 14
+ICMP6_FILTER = 18
+IPV6_PKTINFO = 19
+IPV6_HOPLIMIT = 20
+IPV6_NEXTHOP = 21
+IPV6_HOPOPTS = 22
+IPV6_DSTOPTS = 23
+IPV6_RTHDR = 24
+IPV6_PKTOPTIONS = 25
+IPV6_CHECKSUM = 26
+IPV6_BINDV6ONLY = 27
+IPV6_IPSEC_POLICY = 28
+IPV6_FAITH = 29
+IPV6_FW_ADD = 30
+IPV6_FW_DEL = 31
+IPV6_FW_FLUSH = 32
+IPV6_FW_ZERO = 33
+IPV6_FW_GET = 34
+IPV6_RTHDR_LOOSE = 0
+IPV6_RTHDR_STRICT = 1
+IPV6_RTHDR_TYPE_0 = 0
+IPV6_DEFAULT_MULTICAST_HOPS = 1
+IPV6_DEFAULT_MULTICAST_LOOP = 1
+IPV6_PORTRANGE_DEFAULT = 0
+IPV6_PORTRANGE_HIGH = 1
+IPV6_PORTRANGE_LOW = 2
+IPV6PROTO_MAXID = (IPPROTO_PIM + 1)
+IPV6CTL_FORWARDING = 1
+IPV6CTL_SENDREDIRECTS = 2
+IPV6CTL_DEFHLIM = 3
+IPV6CTL_DEFMTU = 4
+IPV6CTL_FORWSRCRT = 5
+IPV6CTL_STATS = 6
+IPV6CTL_MRTSTATS = 7
+IPV6CTL_MRTPROTO = 8
+IPV6CTL_MAXFRAGPACKETS = 9
+IPV6CTL_SOURCECHECK = 10
+IPV6CTL_SOURCECHECK_LOGINT = 11
+IPV6CTL_ACCEPT_RTADV = 12
+IPV6CTL_KEEPFAITH = 13
+IPV6CTL_LOG_INTERVAL = 14
+IPV6CTL_HDRNESTLIMIT = 15
+IPV6CTL_DAD_COUNT = 16
+IPV6CTL_AUTO_FLOWLABEL = 17
+IPV6CTL_DEFMCASTHLIM = 18
+IPV6CTL_GIF_HLIM = 19
+IPV6CTL_KAME_VERSION = 20
+IPV6CTL_USE_DEPRECATED = 21
+IPV6CTL_RR_PRUNE = 22
+IPV6CTL_MAPPED_ADDR = 23
+IPV6CTL_BINDV6ONLY = 24
+IPV6CTL_RTEXPIRE = 25
+IPV6CTL_RTMINEXPIRE = 26
+IPV6CTL_RTMAXCACHE = 27
+IPV6CTL_MAXID = 28

Added: vendor/Python/current/Lib/plat-freebsd5/regen
===================================================================
--- vendor/Python/current/Lib/plat-freebsd5/regen	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-freebsd5/regen	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,3 @@
+#! /bin/sh
+set -v
+python ../../Tools/scripts/h2py.py -i '(u_long)' /usr/include/netinet/in.h

Added: vendor/Python/current/Lib/plat-freebsd6/IN.py
===================================================================
--- vendor/Python/current/Lib/plat-freebsd6/IN.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-freebsd6/IN.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,515 @@
+# Generated by h2py from /usr/include/netinet/in.h
+
+# Included from sys/cdefs.h
+def __P(protos): return protos
+
+def __STRING(x): return #x
+
+def __XSTRING(x): return __STRING(x)
+
+def __P(protos): return ()
+
+def __STRING(x): return "x"
+
+def __aligned(x): return __attribute__((__aligned__(x)))
+
+def __section(x): return __attribute__((__section__(x)))
+
+def __aligned(x): return __attribute__((__aligned__(x)))
+
+def __section(x): return __attribute__((__section__(x)))
+
+def __nonnull(x): return __attribute__((__nonnull__(x)))
+
+def __predict_true(exp): return __builtin_expect((exp), 1)
+
+def __predict_false(exp): return __builtin_expect((exp), 0)
+
+def __predict_true(exp): return (exp)
+
+def __predict_false(exp): return (exp)
+
+def __FBSDID(s): return __IDSTRING(__CONCAT(__rcsid_,__LINE__),s)
+
+def __RCSID(s): return __IDSTRING(__CONCAT(__rcsid_,__LINE__),s)
+
+def __RCSID_SOURCE(s): return __IDSTRING(__CONCAT(__rcsid_source_,__LINE__),s)
+
+def __SCCSID(s): return __IDSTRING(__CONCAT(__sccsid_,__LINE__),s)
+
+def __COPYRIGHT(s): return __IDSTRING(__CONCAT(__copyright_,__LINE__),s)
+
+_POSIX_C_SOURCE = 199009
+_POSIX_C_SOURCE = 199209
+__XSI_VISIBLE = 600
+_POSIX_C_SOURCE = 200112
+__XSI_VISIBLE = 500
+_POSIX_C_SOURCE = 199506
+_POSIX_C_SOURCE = 198808
+__POSIX_VISIBLE = 200112
+__ISO_C_VISIBLE = 1999
+__POSIX_VISIBLE = 199506
+__ISO_C_VISIBLE = 1990
+__POSIX_VISIBLE = 199309
+__ISO_C_VISIBLE = 1990
+__POSIX_VISIBLE = 199209
+__ISO_C_VISIBLE = 1990
+__POSIX_VISIBLE = 199009
+__ISO_C_VISIBLE = 1990
+__POSIX_VISIBLE = 198808
+__ISO_C_VISIBLE = 0
+__POSIX_VISIBLE = 0
+__XSI_VISIBLE = 0
+__BSD_VISIBLE = 0
+__ISO_C_VISIBLE = 1990
+__POSIX_VISIBLE = 0
+__XSI_VISIBLE = 0
+__BSD_VISIBLE = 0
+__ISO_C_VISIBLE = 1999
+__POSIX_VISIBLE = 200112
+__XSI_VISIBLE = 600
+__BSD_VISIBLE = 1
+__ISO_C_VISIBLE = 1999
+
+# Included from sys/_types.h
+
+# Included from machine/_types.h
+
+# Included from machine/endian.h
+_QUAD_HIGHWORD = 1
+_QUAD_LOWWORD = 0
+_LITTLE_ENDIAN = 1234
+_BIG_ENDIAN = 4321
+_PDP_ENDIAN = 3412
+_BYTE_ORDER = _LITTLE_ENDIAN
+LITTLE_ENDIAN = _LITTLE_ENDIAN
+BIG_ENDIAN = _BIG_ENDIAN
+PDP_ENDIAN = _PDP_ENDIAN
+BYTE_ORDER = _BYTE_ORDER
+__INTEL_COMPILER_with_FreeBSD_endian = 1
+__INTEL_COMPILER_with_FreeBSD_endian = 1
+def __word_swap_int_var(x): return \
+
+def __word_swap_int_const(x): return \
+
+def __word_swap_int(x): return __word_swap_int_var(x)
+
+def __byte_swap_int_var(x): return \
+
+def __byte_swap_int_var(x): return \
+
+def __byte_swap_int_const(x): return \
+
+def __byte_swap_int(x): return __byte_swap_int_var(x)
+
+def __byte_swap_word_var(x): return \
+
+def __byte_swap_word_const(x): return \
+
+def __byte_swap_word(x): return __byte_swap_word_var(x)
+
+def __htonl(x): return __bswap32(x)
+
+def __htons(x): return __bswap16(x)
+
+def __ntohl(x): return __bswap32(x)
+
+def __ntohs(x): return __bswap16(x)
+
+IPPROTO_IP = 0
+IPPROTO_ICMP = 1
+IPPROTO_TCP = 6
+IPPROTO_UDP = 17
+def htonl(x): return __htonl(x)
+
+def htons(x): return __htons(x)
+
+def ntohl(x): return __ntohl(x)
+
+def ntohs(x): return __ntohs(x)
+
+IPPROTO_RAW = 255
+INET_ADDRSTRLEN = 16
+IPPROTO_HOPOPTS = 0
+IPPROTO_IGMP = 2
+IPPROTO_GGP = 3
+IPPROTO_IPV4 = 4
+IPPROTO_IPIP = IPPROTO_IPV4
+IPPROTO_ST = 7
+IPPROTO_EGP = 8
+IPPROTO_PIGP = 9
+IPPROTO_RCCMON = 10
+IPPROTO_NVPII = 11
+IPPROTO_PUP = 12
+IPPROTO_ARGUS = 13
+IPPROTO_EMCON = 14
+IPPROTO_XNET = 15
+IPPROTO_CHAOS = 16
+IPPROTO_MUX = 18
+IPPROTO_MEAS = 19
+IPPROTO_HMP = 20
+IPPROTO_PRM = 21
+IPPROTO_IDP = 22
+IPPROTO_TRUNK1 = 23
+IPPROTO_TRUNK2 = 24
+IPPROTO_LEAF1 = 25
+IPPROTO_LEAF2 = 26
+IPPROTO_RDP = 27
+IPPROTO_IRTP = 28
+IPPROTO_TP = 29
+IPPROTO_BLT = 30
+IPPROTO_NSP = 31
+IPPROTO_INP = 32
+IPPROTO_SEP = 33
+IPPROTO_3PC = 34
+IPPROTO_IDPR = 35
+IPPROTO_XTP = 36
+IPPROTO_DDP = 37
+IPPROTO_CMTP = 38
+IPPROTO_TPXX = 39
+IPPROTO_IL = 40
+IPPROTO_IPV6 = 41
+IPPROTO_SDRP = 42
+IPPROTO_ROUTING = 43
+IPPROTO_FRAGMENT = 44
+IPPROTO_IDRP = 45
+IPPROTO_RSVP = 46
+IPPROTO_GRE = 47
+IPPROTO_MHRP = 48
+IPPROTO_BHA = 49
+IPPROTO_ESP = 50
+IPPROTO_AH = 51
+IPPROTO_INLSP = 52
+IPPROTO_SWIPE = 53
+IPPROTO_NHRP = 54
+IPPROTO_MOBILE = 55
+IPPROTO_TLSP = 56
+IPPROTO_SKIP = 57
+IPPROTO_ICMPV6 = 58
+IPPROTO_NONE = 59
+IPPROTO_DSTOPTS = 60
+IPPROTO_AHIP = 61
+IPPROTO_CFTP = 62
+IPPROTO_HELLO = 63
+IPPROTO_SATEXPAK = 64
+IPPROTO_KRYPTOLAN = 65
+IPPROTO_RVD = 66
+IPPROTO_IPPC = 67
+IPPROTO_ADFS = 68
+IPPROTO_SATMON = 69
+IPPROTO_VISA = 70
+IPPROTO_IPCV = 71
+IPPROTO_CPNX = 72
+IPPROTO_CPHB = 73
+IPPROTO_WSN = 74
+IPPROTO_PVP = 75
+IPPROTO_BRSATMON = 76
+IPPROTO_ND = 77
+IPPROTO_WBMON = 78
+IPPROTO_WBEXPAK = 79
+IPPROTO_EON = 80
+IPPROTO_VMTP = 81
+IPPROTO_SVMTP = 82
+IPPROTO_VINES = 83
+IPPROTO_TTP = 84
+IPPROTO_IGP = 85
+IPPROTO_DGP = 86
+IPPROTO_TCF = 87
+IPPROTO_IGRP = 88
+IPPROTO_OSPFIGP = 89
+IPPROTO_SRPC = 90
+IPPROTO_LARP = 91
+IPPROTO_MTP = 92
+IPPROTO_AX25 = 93
+IPPROTO_IPEIP = 94
+IPPROTO_MICP = 95
+IPPROTO_SCCSP = 96
+IPPROTO_ETHERIP = 97
+IPPROTO_ENCAP = 98
+IPPROTO_APES = 99
+IPPROTO_GMTP = 100
+IPPROTO_IPCOMP = 108
+IPPROTO_PIM = 103
+IPPROTO_PGM = 113
+IPPROTO_PFSYNC = 240
+IPPROTO_OLD_DIVERT = 254
+IPPROTO_MAX = 256
+IPPROTO_DONE = 257
+IPPROTO_DIVERT = 258
+IPPORT_RESERVED = 1024
+IPPORT_HIFIRSTAUTO = 49152
+IPPORT_HILASTAUTO = 65535
+IPPORT_RESERVEDSTART = 600
+IPPORT_MAX = 65535
+def IN_CLASSA(i): return (((u_int32_t)(i) & (-2147483648)) == 0)
+
+IN_CLASSA_NET = (-16777216)
+IN_CLASSA_NSHIFT = 24
+IN_CLASSA_HOST = 0x00ffffff
+IN_CLASSA_MAX = 128
+def IN_CLASSB(i): return (((u_int32_t)(i) & (-1073741824)) == (-2147483648))
+
+IN_CLASSB_NET = (-65536)
+IN_CLASSB_NSHIFT = 16
+IN_CLASSB_HOST = 0x0000ffff
+IN_CLASSB_MAX = 65536
+def IN_CLASSC(i): return (((u_int32_t)(i) & (-536870912)) == (-1073741824))
+
+IN_CLASSC_NET = (-256)
+IN_CLASSC_NSHIFT = 8
+IN_CLASSC_HOST = 0x000000ff
+def IN_CLASSD(i): return (((u_int32_t)(i) & (-268435456)) == (-536870912))
+
+IN_CLASSD_NET = (-268435456)
+IN_CLASSD_NSHIFT = 28
+IN_CLASSD_HOST = 0x0fffffff
+def IN_MULTICAST(i): return IN_CLASSD(i)
+
+def IN_EXPERIMENTAL(i): return (((u_int32_t)(i) & (-268435456)) == (-268435456))
+
+def IN_BADCLASS(i): return (((u_int32_t)(i) & (-268435456)) == (-268435456))
+
+INADDR_NONE = (-1)
+IN_LOOPBACKNET = 127
+IP_OPTIONS = 1
+IP_HDRINCL = 2
+IP_TOS = 3
+IP_TTL = 4
+IP_RECVOPTS = 5
+IP_RECVRETOPTS = 6
+IP_RECVDSTADDR = 7
+IP_SENDSRCADDR = IP_RECVDSTADDR
+IP_RETOPTS = 8
+IP_MULTICAST_IF = 9
+IP_MULTICAST_TTL = 10
+IP_MULTICAST_LOOP = 11
+IP_ADD_MEMBERSHIP = 12
+IP_DROP_MEMBERSHIP = 13
+IP_MULTICAST_VIF = 14
+IP_RSVP_ON = 15
+IP_RSVP_OFF = 16
+IP_RSVP_VIF_ON = 17
+IP_RSVP_VIF_OFF = 18
+IP_PORTRANGE = 19
+IP_RECVIF = 20
+IP_IPSEC_POLICY = 21
+IP_FAITH = 22
+IP_ONESBCAST = 23
+IP_FW_TABLE_ADD = 40
+IP_FW_TABLE_DEL = 41
+IP_FW_TABLE_FLUSH = 42
+IP_FW_TABLE_GETSIZE = 43
+IP_FW_TABLE_LIST = 44
+IP_FW_ADD = 50
+IP_FW_DEL = 51
+IP_FW_FLUSH = 52
+IP_FW_ZERO = 53
+IP_FW_GET = 54
+IP_FW_RESETLOG = 55
+IP_DUMMYNET_CONFIGURE = 60
+IP_DUMMYNET_DEL = 61
+IP_DUMMYNET_FLUSH = 62
+IP_DUMMYNET_GET = 64
+IP_RECVTTL = 65
+IP_DEFAULT_MULTICAST_TTL = 1
+IP_DEFAULT_MULTICAST_LOOP = 1
+IP_MAX_MEMBERSHIPS = 20
+IP_PORTRANGE_DEFAULT = 0
+IP_PORTRANGE_HIGH = 1
+IP_PORTRANGE_LOW = 2
+IPPROTO_MAXID = (IPPROTO_AH + 1)
+IPCTL_FORWARDING = 1
+IPCTL_SENDREDIRECTS = 2
+IPCTL_DEFTTL = 3
+IPCTL_DEFMTU = 4
+IPCTL_RTEXPIRE = 5
+IPCTL_RTMINEXPIRE = 6
+IPCTL_RTMAXCACHE = 7
+IPCTL_SOURCEROUTE = 8
+IPCTL_DIRECTEDBROADCAST = 9
+IPCTL_INTRQMAXLEN = 10
+IPCTL_INTRQDROPS = 11
+IPCTL_STATS = 12
+IPCTL_ACCEPTSOURCEROUTE = 13
+IPCTL_FASTFORWARDING = 14
+IPCTL_KEEPFAITH = 15
+IPCTL_GIF_TTL = 16
+IPCTL_MAXID = 17
+def in_nullhost(x): return ((x).s_addr == INADDR_ANY)
+
+
+# Included from netinet6/in6.h
+__KAME_VERSION = "20010528/FreeBSD"
+IPV6PORT_RESERVED = 1024
+IPV6PORT_ANONMIN = 49152
+IPV6PORT_ANONMAX = 65535
+IPV6PORT_RESERVEDMIN = 600
+IPV6PORT_RESERVEDMAX = (IPV6PORT_RESERVED-1)
+INET6_ADDRSTRLEN = 46
+IPV6_ADDR_INT32_ONE = 1
+IPV6_ADDR_INT32_TWO = 2
+IPV6_ADDR_INT32_MNL = (-16711680)
+IPV6_ADDR_INT32_MLL = (-16646144)
+IPV6_ADDR_INT32_SMP = 0x0000ffff
+IPV6_ADDR_INT16_ULL = 0xfe80
+IPV6_ADDR_INT16_USL = 0xfec0
+IPV6_ADDR_INT16_MLL = 0xff02
+IPV6_ADDR_INT32_ONE = 0x01000000
+IPV6_ADDR_INT32_TWO = 0x02000000
+IPV6_ADDR_INT32_MNL = 0x000001ff
+IPV6_ADDR_INT32_MLL = 0x000002ff
+IPV6_ADDR_INT32_SMP = (-65536)
+IPV6_ADDR_INT16_ULL = 0x80fe
+IPV6_ADDR_INT16_USL = 0xc0fe
+IPV6_ADDR_INT16_MLL = 0x02ff
+def IN6_IS_ADDR_UNSPECIFIED(a): return \
+
+def IN6_IS_ADDR_LOOPBACK(a): return \
+
+def IN6_IS_ADDR_V4COMPAT(a): return \
+
+def IN6_IS_ADDR_V4MAPPED(a): return \
+
+IPV6_ADDR_SCOPE_NODELOCAL = 0x01
+IPV6_ADDR_SCOPE_INTFACELOCAL = 0x01
+IPV6_ADDR_SCOPE_LINKLOCAL = 0x02
+IPV6_ADDR_SCOPE_SITELOCAL = 0x05
+IPV6_ADDR_SCOPE_ORGLOCAL = 0x08
+IPV6_ADDR_SCOPE_GLOBAL = 0x0e
+__IPV6_ADDR_SCOPE_NODELOCAL = 0x01
+__IPV6_ADDR_SCOPE_INTFACELOCAL = 0x01
+__IPV6_ADDR_SCOPE_LINKLOCAL = 0x02
+__IPV6_ADDR_SCOPE_SITELOCAL = 0x05
+__IPV6_ADDR_SCOPE_ORGLOCAL = 0x08
+__IPV6_ADDR_SCOPE_GLOBAL = 0x0e
+def IN6_IS_ADDR_LINKLOCAL(a): return \
+
+def IN6_IS_ADDR_SITELOCAL(a): return \
+
+def IN6_IS_ADDR_MC_NODELOCAL(a): return \
+
+def IN6_IS_ADDR_MC_INTFACELOCAL(a): return \
+
+def IN6_IS_ADDR_MC_LINKLOCAL(a): return \
+
+def IN6_IS_ADDR_MC_SITELOCAL(a): return \
+
+def IN6_IS_ADDR_MC_ORGLOCAL(a): return \
+
+def IN6_IS_ADDR_MC_GLOBAL(a): return \
+
+def IN6_IS_ADDR_MC_NODELOCAL(a): return \
+
+def IN6_IS_ADDR_MC_LINKLOCAL(a): return \
+
+def IN6_IS_ADDR_MC_SITELOCAL(a): return \
+
+def IN6_IS_ADDR_MC_ORGLOCAL(a): return \
+
+def IN6_IS_ADDR_MC_GLOBAL(a): return \
+
+def IN6_IS_SCOPE_LINKLOCAL(a): return \
+
+def IFA6_IS_DEPRECATED(a): return \
+
+def IFA6_IS_INVALID(a): return \
+
+IPV6_OPTIONS = 1
+IPV6_RECVOPTS = 5
+IPV6_RECVRETOPTS = 6
+IPV6_RECVDSTADDR = 7
+IPV6_RETOPTS = 8
+IPV6_SOCKOPT_RESERVED1 = 3
+IPV6_UNICAST_HOPS = 4
+IPV6_MULTICAST_IF = 9
+IPV6_MULTICAST_HOPS = 10
+IPV6_MULTICAST_LOOP = 11
+IPV6_JOIN_GROUP = 12
+IPV6_LEAVE_GROUP = 13
+IPV6_PORTRANGE = 14
+ICMP6_FILTER = 18
+IPV6_2292PKTINFO = 19
+IPV6_2292HOPLIMIT = 20
+IPV6_2292NEXTHOP = 21
+IPV6_2292HOPOPTS = 22
+IPV6_2292DSTOPTS = 23
+IPV6_2292RTHDR = 24
+IPV6_2292PKTOPTIONS = 25
+IPV6_CHECKSUM = 26
+IPV6_V6ONLY = 27
+IPV6_BINDV6ONLY = IPV6_V6ONLY
+IPV6_IPSEC_POLICY = 28
+IPV6_FAITH = 29
+IPV6_FW_ADD = 30
+IPV6_FW_DEL = 31
+IPV6_FW_FLUSH = 32
+IPV6_FW_ZERO = 33
+IPV6_FW_GET = 34
+IPV6_RTHDRDSTOPTS = 35
+IPV6_RECVPKTINFO = 36
+IPV6_RECVHOPLIMIT = 37
+IPV6_RECVRTHDR = 38
+IPV6_RECVHOPOPTS = 39
+IPV6_RECVDSTOPTS = 40
+IPV6_RECVRTHDRDSTOPTS = 41
+IPV6_USE_MIN_MTU = 42
+IPV6_RECVPATHMTU = 43
+IPV6_PATHMTU = 44
+IPV6_REACHCONF = 45
+IPV6_PKTINFO = 46
+IPV6_HOPLIMIT = 47
+IPV6_NEXTHOP = 48
+IPV6_HOPOPTS = 49
+IPV6_DSTOPTS = 50
+IPV6_RTHDR = 51
+IPV6_PKTOPTIONS = 52
+IPV6_RECVTCLASS = 57
+IPV6_AUTOFLOWLABEL = 59
+IPV6_TCLASS = 61
+IPV6_DONTFRAG = 62
+IPV6_PREFER_TEMPADDR = 63
+IPV6_RTHDR_LOOSE = 0
+IPV6_RTHDR_STRICT = 1
+IPV6_RTHDR_TYPE_0 = 0
+IPV6_DEFAULT_MULTICAST_HOPS = 1
+IPV6_DEFAULT_MULTICAST_LOOP = 1
+IPV6_PORTRANGE_DEFAULT = 0
+IPV6_PORTRANGE_HIGH = 1
+IPV6_PORTRANGE_LOW = 2
+IPV6PROTO_MAXID = (IPPROTO_PIM + 1)
+IPV6CTL_FORWARDING = 1
+IPV6CTL_SENDREDIRECTS = 2
+IPV6CTL_DEFHLIM = 3
+IPV6CTL_DEFMTU = 4
+IPV6CTL_FORWSRCRT = 5
+IPV6CTL_STATS = 6
+IPV6CTL_MRTSTATS = 7
+IPV6CTL_MRTPROTO = 8
+IPV6CTL_MAXFRAGPACKETS = 9
+IPV6CTL_SOURCECHECK = 10
+IPV6CTL_SOURCECHECK_LOGINT = 11
+IPV6CTL_ACCEPT_RTADV = 12
+IPV6CTL_KEEPFAITH = 13
+IPV6CTL_LOG_INTERVAL = 14
+IPV6CTL_HDRNESTLIMIT = 15
+IPV6CTL_DAD_COUNT = 16
+IPV6CTL_AUTO_FLOWLABEL = 17
+IPV6CTL_DEFMCASTHLIM = 18
+IPV6CTL_GIF_HLIM = 19
+IPV6CTL_KAME_VERSION = 20
+IPV6CTL_USE_DEPRECATED = 21
+IPV6CTL_RR_PRUNE = 22
+IPV6CTL_MAPPED_ADDR = 23
+IPV6CTL_V6ONLY = 24
+IPV6CTL_RTEXPIRE = 25
+IPV6CTL_RTMINEXPIRE = 26
+IPV6CTL_RTMAXCACHE = 27
+IPV6CTL_USETEMPADDR = 32
+IPV6CTL_TEMPPLTIME = 33
+IPV6CTL_TEMPVLTIME = 34
+IPV6CTL_AUTO_LINKLOCAL = 35
+IPV6CTL_RIP6STATS = 36
+IPV6CTL_PREFER_TEMPADDR = 37
+IPV6CTL_ADDRCTLPOLICY = 38
+IPV6CTL_MAXFRAGS = 41
+IPV6CTL_MAXID = 42

Added: vendor/Python/current/Lib/plat-freebsd6/regen
===================================================================
--- vendor/Python/current/Lib/plat-freebsd6/regen	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-freebsd6/regen	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,3 @@
+#! /bin/sh
+set -v
+python ../../Tools/scripts/h2py.py -i '(u_long)' /usr/include/netinet/in.h

Added: vendor/Python/current/Lib/plat-freebsd7/IN.py
===================================================================
--- vendor/Python/current/Lib/plat-freebsd7/IN.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-freebsd7/IN.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,535 @@
+# Generated by h2py from /usr/include/netinet/in.h
+
+# Included from sys/cdefs.h
+__GNUCLIKE_ASM = 3
+__GNUCLIKE_ASM = 2
+__GNUCLIKE___TYPEOF = 1
+__GNUCLIKE___OFFSETOF = 1
+__GNUCLIKE___SECTION = 1
+__GNUCLIKE_ATTRIBUTE_MODE_DI = 1
+__GNUCLIKE_CTOR_SECTION_HANDLING = 1
+__GNUCLIKE_BUILTIN_CONSTANT_P = 1
+__GNUCLIKE_BUILTIN_VARARGS = 1
+__GNUCLIKE_BUILTIN_VAALIST = 1
+__GNUC_VA_LIST_COMPATIBILITY = 1
+__GNUCLIKE_BUILTIN_STDARG = 1
+__GNUCLIKE_BUILTIN_NEXT_ARG = 1
+__GNUCLIKE_BUILTIN_MEMCPY = 1
+__CC_SUPPORTS_INLINE = 1
+__CC_SUPPORTS___INLINE = 1
+__CC_SUPPORTS___INLINE__ = 1
+__CC_SUPPORTS___FUNC__ = 1
+__CC_SUPPORTS_WARNING = 1
+__CC_SUPPORTS_VARADIC_XXX = 1
+__CC_SUPPORTS_DYNAMIC_ARRAY_INIT = 1
+__CC_INT_IS_32BIT = 1
+def __P(protos): return protos
+
+def __STRING(x): return #x
+
+def __XSTRING(x): return __STRING(x)
+
+def __P(protos): return ()
+
+def __STRING(x): return "x"
+
+def __aligned(x): return __attribute__((__aligned__(x)))
+
+def __section(x): return __attribute__((__section__(x)))
+
+def __aligned(x): return __attribute__((__aligned__(x)))
+
+def __section(x): return __attribute__((__section__(x)))
+
+def __nonnull(x): return __attribute__((__nonnull__(x)))
+
+def __predict_true(exp): return __builtin_expect((exp), 1)
+
+def __predict_false(exp): return __builtin_expect((exp), 0)
+
+def __predict_true(exp): return (exp)
+
+def __predict_false(exp): return (exp)
+
+def __FBSDID(s): return __IDSTRING(__CONCAT(__rcsid_,__LINE__),s)
+
+def __RCSID(s): return __IDSTRING(__CONCAT(__rcsid_,__LINE__),s)
+
+def __RCSID_SOURCE(s): return __IDSTRING(__CONCAT(__rcsid_source_,__LINE__),s)
+
+def __SCCSID(s): return __IDSTRING(__CONCAT(__sccsid_,__LINE__),s)
+
+def __COPYRIGHT(s): return __IDSTRING(__CONCAT(__copyright_,__LINE__),s)
+
+_POSIX_C_SOURCE = 199009
+_POSIX_C_SOURCE = 199209
+__XSI_VISIBLE = 600
+_POSIX_C_SOURCE = 200112
+__XSI_VISIBLE = 500
+_POSIX_C_SOURCE = 199506
+_POSIX_C_SOURCE = 198808
+__POSIX_VISIBLE = 200112
+__ISO_C_VISIBLE = 1999
+__POSIX_VISIBLE = 199506
+__ISO_C_VISIBLE = 1990
+__POSIX_VISIBLE = 199309
+__ISO_C_VISIBLE = 1990
+__POSIX_VISIBLE = 199209
+__ISO_C_VISIBLE = 1990
+__POSIX_VISIBLE = 199009
+__ISO_C_VISIBLE = 1990
+__POSIX_VISIBLE = 198808
+__ISO_C_VISIBLE = 0
+__POSIX_VISIBLE = 0
+__XSI_VISIBLE = 0
+__BSD_VISIBLE = 0
+__ISO_C_VISIBLE = 1990
+__POSIX_VISIBLE = 0
+__XSI_VISIBLE = 0
+__BSD_VISIBLE = 0
+__ISO_C_VISIBLE = 1999
+__POSIX_VISIBLE = 200112
+__XSI_VISIBLE = 600
+__BSD_VISIBLE = 1
+__ISO_C_VISIBLE = 1999
+
+# Included from sys/_types.h
+
+# Included from machine/_types.h
+
+# Included from machine/endian.h
+_QUAD_HIGHWORD = 1
+_QUAD_LOWWORD = 0
+_LITTLE_ENDIAN = 1234
+_BIG_ENDIAN = 4321
+_PDP_ENDIAN = 3412
+_BYTE_ORDER = _LITTLE_ENDIAN
+LITTLE_ENDIAN = _LITTLE_ENDIAN
+BIG_ENDIAN = _BIG_ENDIAN
+PDP_ENDIAN = _PDP_ENDIAN
+BYTE_ORDER = _BYTE_ORDER
+def __word_swap_int_var(x): return \
+
+def __word_swap_int_const(x): return \
+
+def __word_swap_int(x): return __word_swap_int_var(x)
+
+def __byte_swap_int_var(x): return \
+
+def __byte_swap_int_const(x): return \
+
+def __byte_swap_int(x): return __byte_swap_int_var(x)
+
+def __byte_swap_word_var(x): return \
+
+def __byte_swap_word_const(x): return \
+
+def __byte_swap_word(x): return __byte_swap_word_var(x)
+
+def __htonl(x): return __bswap32(x)
+
+def __htons(x): return __bswap16(x)
+
+def __ntohl(x): return __bswap32(x)
+
+def __ntohs(x): return __bswap16(x)
+
+IPPROTO_IP = 0
+IPPROTO_ICMP = 1
+IPPROTO_TCP = 6
+IPPROTO_UDP = 17
+def htonl(x): return __htonl(x)
+
+def htons(x): return __htons(x)
+
+def ntohl(x): return __ntohl(x)
+
+def ntohs(x): return __ntohs(x)
+
+IPPROTO_RAW = 255
+INET_ADDRSTRLEN = 16
+IPPROTO_HOPOPTS = 0
+IPPROTO_IGMP = 2
+IPPROTO_GGP = 3
+IPPROTO_IPV4 = 4
+IPPROTO_IPIP = IPPROTO_IPV4
+IPPROTO_ST = 7
+IPPROTO_EGP = 8
+IPPROTO_PIGP = 9
+IPPROTO_RCCMON = 10
+IPPROTO_NVPII = 11
+IPPROTO_PUP = 12
+IPPROTO_ARGUS = 13
+IPPROTO_EMCON = 14
+IPPROTO_XNET = 15
+IPPROTO_CHAOS = 16
+IPPROTO_MUX = 18
+IPPROTO_MEAS = 19
+IPPROTO_HMP = 20
+IPPROTO_PRM = 21
+IPPROTO_IDP = 22
+IPPROTO_TRUNK1 = 23
+IPPROTO_TRUNK2 = 24
+IPPROTO_LEAF1 = 25
+IPPROTO_LEAF2 = 26
+IPPROTO_RDP = 27
+IPPROTO_IRTP = 28
+IPPROTO_TP = 29
+IPPROTO_BLT = 30
+IPPROTO_NSP = 31
+IPPROTO_INP = 32
+IPPROTO_SEP = 33
+IPPROTO_3PC = 34
+IPPROTO_IDPR = 35
+IPPROTO_XTP = 36
+IPPROTO_DDP = 37
+IPPROTO_CMTP = 38
+IPPROTO_TPXX = 39
+IPPROTO_IL = 40
+IPPROTO_IPV6 = 41
+IPPROTO_SDRP = 42
+IPPROTO_ROUTING = 43
+IPPROTO_FRAGMENT = 44
+IPPROTO_IDRP = 45
+IPPROTO_RSVP = 46
+IPPROTO_GRE = 47
+IPPROTO_MHRP = 48
+IPPROTO_BHA = 49
+IPPROTO_ESP = 50
+IPPROTO_AH = 51
+IPPROTO_INLSP = 52
+IPPROTO_SWIPE = 53
+IPPROTO_NHRP = 54
+IPPROTO_MOBILE = 55
+IPPROTO_TLSP = 56
+IPPROTO_SKIP = 57
+IPPROTO_ICMPV6 = 58
+IPPROTO_NONE = 59
+IPPROTO_DSTOPTS = 60
+IPPROTO_AHIP = 61
+IPPROTO_CFTP = 62
+IPPROTO_HELLO = 63
+IPPROTO_SATEXPAK = 64
+IPPROTO_KRYPTOLAN = 65
+IPPROTO_RVD = 66
+IPPROTO_IPPC = 67
+IPPROTO_ADFS = 68
+IPPROTO_SATMON = 69
+IPPROTO_VISA = 70
+IPPROTO_IPCV = 71
+IPPROTO_CPNX = 72
+IPPROTO_CPHB = 73
+IPPROTO_WSN = 74
+IPPROTO_PVP = 75
+IPPROTO_BRSATMON = 76
+IPPROTO_ND = 77
+IPPROTO_WBMON = 78
+IPPROTO_WBEXPAK = 79
+IPPROTO_EON = 80
+IPPROTO_VMTP = 81
+IPPROTO_SVMTP = 82
+IPPROTO_VINES = 83
+IPPROTO_TTP = 84
+IPPROTO_IGP = 85
+IPPROTO_DGP = 86
+IPPROTO_TCF = 87
+IPPROTO_IGRP = 88
+IPPROTO_OSPFIGP = 89
+IPPROTO_SRPC = 90
+IPPROTO_LARP = 91
+IPPROTO_MTP = 92
+IPPROTO_AX25 = 93
+IPPROTO_IPEIP = 94
+IPPROTO_MICP = 95
+IPPROTO_SCCSP = 96
+IPPROTO_ETHERIP = 97
+IPPROTO_ENCAP = 98
+IPPROTO_APES = 99
+IPPROTO_GMTP = 100
+IPPROTO_IPCOMP = 108
+IPPROTO_PIM = 103
+IPPROTO_CARP = 112
+IPPROTO_PGM = 113
+IPPROTO_PFSYNC = 240
+IPPROTO_OLD_DIVERT = 254
+IPPROTO_MAX = 256
+IPPROTO_DONE = 257
+IPPROTO_DIVERT = 258
+IPPROTO_SPACER = 32767
+IPPORT_RESERVED = 1024
+IPPORT_HIFIRSTAUTO = 49152
+IPPORT_HILASTAUTO = 65535
+IPPORT_RESERVEDSTART = 600
+IPPORT_MAX = 65535
+def IN_CLASSA(i): return (((u_int32_t)(i) & (-2147483648)) == 0)
+
+IN_CLASSA_NET = (-16777216)
+IN_CLASSA_NSHIFT = 24
+IN_CLASSA_HOST = 0x00ffffff
+IN_CLASSA_MAX = 128
+def IN_CLASSB(i): return (((u_int32_t)(i) & (-1073741824)) == (-2147483648))
+
+IN_CLASSB_NET = (-65536)
+IN_CLASSB_NSHIFT = 16
+IN_CLASSB_HOST = 0x0000ffff
+IN_CLASSB_MAX = 65536
+def IN_CLASSC(i): return (((u_int32_t)(i) & (-536870912)) == (-1073741824))
+
+IN_CLASSC_NET = (-256)
+IN_CLASSC_NSHIFT = 8
+IN_CLASSC_HOST = 0x000000ff
+def IN_CLASSD(i): return (((u_int32_t)(i) & (-268435456)) == (-536870912))
+
+IN_CLASSD_NET = (-268435456)
+IN_CLASSD_NSHIFT = 28
+IN_CLASSD_HOST = 0x0fffffff
+def IN_MULTICAST(i): return IN_CLASSD(i)
+
+def IN_EXPERIMENTAL(i): return (((u_int32_t)(i) & (-268435456)) == (-268435456))
+
+def IN_BADCLASS(i): return (((u_int32_t)(i) & (-268435456)) == (-268435456))
+
+INADDR_NONE = (-1)
+IN_LOOPBACKNET = 127
+IP_OPTIONS = 1
+IP_HDRINCL = 2
+IP_TOS = 3
+IP_TTL = 4
+IP_RECVOPTS = 5
+IP_RECVRETOPTS = 6
+IP_RECVDSTADDR = 7
+IP_SENDSRCADDR = IP_RECVDSTADDR
+IP_RETOPTS = 8
+IP_MULTICAST_IF = 9
+IP_MULTICAST_TTL = 10
+IP_MULTICAST_LOOP = 11
+IP_ADD_MEMBERSHIP = 12
+IP_DROP_MEMBERSHIP = 13
+IP_MULTICAST_VIF = 14
+IP_RSVP_ON = 15
+IP_RSVP_OFF = 16
+IP_RSVP_VIF_ON = 17
+IP_RSVP_VIF_OFF = 18
+IP_PORTRANGE = 19
+IP_RECVIF = 20
+IP_IPSEC_POLICY = 21
+IP_FAITH = 22
+IP_ONESBCAST = 23
+IP_FW_TABLE_ADD = 40
+IP_FW_TABLE_DEL = 41
+IP_FW_TABLE_FLUSH = 42
+IP_FW_TABLE_GETSIZE = 43
+IP_FW_TABLE_LIST = 44
+IP_FW_ADD = 50
+IP_FW_DEL = 51
+IP_FW_FLUSH = 52
+IP_FW_ZERO = 53
+IP_FW_GET = 54
+IP_FW_RESETLOG = 55
+IP_DUMMYNET_CONFIGURE = 60
+IP_DUMMYNET_DEL = 61
+IP_DUMMYNET_FLUSH = 62
+IP_DUMMYNET_GET = 64
+IP_RECVTTL = 65
+IP_DEFAULT_MULTICAST_TTL = 1
+IP_DEFAULT_MULTICAST_LOOP = 1
+IP_MAX_MEMBERSHIPS = 20
+IP_PORTRANGE_DEFAULT = 0
+IP_PORTRANGE_HIGH = 1
+IP_PORTRANGE_LOW = 2
+IPPROTO_MAXID = (IPPROTO_AH + 1)
+IPCTL_FORWARDING = 1
+IPCTL_SENDREDIRECTS = 2
+IPCTL_DEFTTL = 3
+IPCTL_DEFMTU = 4
+IPCTL_RTEXPIRE = 5
+IPCTL_RTMINEXPIRE = 6
+IPCTL_RTMAXCACHE = 7
+IPCTL_SOURCEROUTE = 8
+IPCTL_DIRECTEDBROADCAST = 9
+IPCTL_INTRQMAXLEN = 10
+IPCTL_INTRQDROPS = 11
+IPCTL_STATS = 12
+IPCTL_ACCEPTSOURCEROUTE = 13
+IPCTL_FASTFORWARDING = 14
+IPCTL_KEEPFAITH = 15
+IPCTL_GIF_TTL = 16
+IPCTL_MAXID = 17
+def in_nullhost(x): return ((x).s_addr == INADDR_ANY)
+
+
+# Included from netinet6/in6.h
+__KAME_VERSION = "20010528/FreeBSD"
+IPV6PORT_RESERVED = 1024
+IPV6PORT_ANONMIN = 49152
+IPV6PORT_ANONMAX = 65535
+IPV6PORT_RESERVEDMIN = 600
+IPV6PORT_RESERVEDMAX = (IPV6PORT_RESERVED-1)
+INET6_ADDRSTRLEN = 46
+IPV6_ADDR_INT32_ONE = 1
+IPV6_ADDR_INT32_TWO = 2
+IPV6_ADDR_INT32_MNL = (-16711680)
+IPV6_ADDR_INT32_MLL = (-16646144)
+IPV6_ADDR_INT32_SMP = 0x0000ffff
+IPV6_ADDR_INT16_ULL = 0xfe80
+IPV6_ADDR_INT16_USL = 0xfec0
+IPV6_ADDR_INT16_MLL = 0xff02
+IPV6_ADDR_INT32_ONE = 0x01000000
+IPV6_ADDR_INT32_TWO = 0x02000000
+IPV6_ADDR_INT32_MNL = 0x000001ff
+IPV6_ADDR_INT32_MLL = 0x000002ff
+IPV6_ADDR_INT32_SMP = (-65536)
+IPV6_ADDR_INT16_ULL = 0x80fe
+IPV6_ADDR_INT16_USL = 0xc0fe
+IPV6_ADDR_INT16_MLL = 0x02ff
+def IN6_IS_ADDR_UNSPECIFIED(a): return \
+
+def IN6_IS_ADDR_LOOPBACK(a): return \
+
+def IN6_IS_ADDR_V4COMPAT(a): return \
+
+def IN6_IS_ADDR_V4MAPPED(a): return \
+
+IPV6_ADDR_SCOPE_NODELOCAL = 0x01
+IPV6_ADDR_SCOPE_INTFACELOCAL = 0x01
+IPV6_ADDR_SCOPE_LINKLOCAL = 0x02
+IPV6_ADDR_SCOPE_SITELOCAL = 0x05
+IPV6_ADDR_SCOPE_ORGLOCAL = 0x08
+IPV6_ADDR_SCOPE_GLOBAL = 0x0e
+__IPV6_ADDR_SCOPE_NODELOCAL = 0x01
+__IPV6_ADDR_SCOPE_INTFACELOCAL = 0x01
+__IPV6_ADDR_SCOPE_LINKLOCAL = 0x02
+__IPV6_ADDR_SCOPE_SITELOCAL = 0x05
+__IPV6_ADDR_SCOPE_ORGLOCAL = 0x08
+__IPV6_ADDR_SCOPE_GLOBAL = 0x0e
+def IN6_IS_ADDR_LINKLOCAL(a): return \
+
+def IN6_IS_ADDR_SITELOCAL(a): return \
+
+def IN6_IS_ADDR_MC_NODELOCAL(a): return \
+
+def IN6_IS_ADDR_MC_INTFACELOCAL(a): return \
+
+def IN6_IS_ADDR_MC_LINKLOCAL(a): return \
+
+def IN6_IS_ADDR_MC_SITELOCAL(a): return \
+
+def IN6_IS_ADDR_MC_ORGLOCAL(a): return \
+
+def IN6_IS_ADDR_MC_GLOBAL(a): return \
+
+def IN6_IS_ADDR_MC_NODELOCAL(a): return \
+
+def IN6_IS_ADDR_MC_LINKLOCAL(a): return \
+
+def IN6_IS_ADDR_MC_SITELOCAL(a): return \
+
+def IN6_IS_ADDR_MC_ORGLOCAL(a): return \
+
+def IN6_IS_ADDR_MC_GLOBAL(a): return \
+
+def IN6_IS_SCOPE_LINKLOCAL(a): return \
+
+def IFA6_IS_DEPRECATED(a): return \
+
+def IFA6_IS_INVALID(a): return \
+
+IPV6_OPTIONS = 1
+IPV6_RECVOPTS = 5
+IPV6_RECVRETOPTS = 6
+IPV6_RECVDSTADDR = 7
+IPV6_RETOPTS = 8
+IPV6_SOCKOPT_RESERVED1 = 3
+IPV6_UNICAST_HOPS = 4
+IPV6_MULTICAST_IF = 9
+IPV6_MULTICAST_HOPS = 10
+IPV6_MULTICAST_LOOP = 11
+IPV6_JOIN_GROUP = 12
+IPV6_LEAVE_GROUP = 13
+IPV6_PORTRANGE = 14
+ICMP6_FILTER = 18
+IPV6_2292PKTINFO = 19
+IPV6_2292HOPLIMIT = 20
+IPV6_2292NEXTHOP = 21
+IPV6_2292HOPOPTS = 22
+IPV6_2292DSTOPTS = 23
+IPV6_2292RTHDR = 24
+IPV6_2292PKTOPTIONS = 25
+IPV6_CHECKSUM = 26
+IPV6_V6ONLY = 27
+IPV6_BINDV6ONLY = IPV6_V6ONLY
+IPV6_IPSEC_POLICY = 28
+IPV6_FAITH = 29
+IPV6_FW_ADD = 30
+IPV6_FW_DEL = 31
+IPV6_FW_FLUSH = 32
+IPV6_FW_ZERO = 33
+IPV6_FW_GET = 34
+IPV6_RTHDRDSTOPTS = 35
+IPV6_RECVPKTINFO = 36
+IPV6_RECVHOPLIMIT = 37
+IPV6_RECVRTHDR = 38
+IPV6_RECVHOPOPTS = 39
+IPV6_RECVDSTOPTS = 40
+IPV6_RECVRTHDRDSTOPTS = 41
+IPV6_USE_MIN_MTU = 42
+IPV6_RECVPATHMTU = 43
+IPV6_PATHMTU = 44
+IPV6_REACHCONF = 45
+IPV6_PKTINFO = 46
+IPV6_HOPLIMIT = 47
+IPV6_NEXTHOP = 48
+IPV6_HOPOPTS = 49
+IPV6_DSTOPTS = 50
+IPV6_RTHDR = 51
+IPV6_PKTOPTIONS = 52
+IPV6_RECVTCLASS = 57
+IPV6_AUTOFLOWLABEL = 59
+IPV6_TCLASS = 61
+IPV6_DONTFRAG = 62
+IPV6_PREFER_TEMPADDR = 63
+IPV6_RTHDR_LOOSE = 0
+IPV6_RTHDR_STRICT = 1
+IPV6_RTHDR_TYPE_0 = 0
+IPV6_DEFAULT_MULTICAST_HOPS = 1
+IPV6_DEFAULT_MULTICAST_LOOP = 1
+IPV6_PORTRANGE_DEFAULT = 0
+IPV6_PORTRANGE_HIGH = 1
+IPV6_PORTRANGE_LOW = 2
+IPV6PROTO_MAXID = (IPPROTO_PIM + 1)
+IPV6CTL_FORWARDING = 1
+IPV6CTL_SENDREDIRECTS = 2
+IPV6CTL_DEFHLIM = 3
+IPV6CTL_DEFMTU = 4
+IPV6CTL_FORWSRCRT = 5
+IPV6CTL_STATS = 6
+IPV6CTL_MRTSTATS = 7
+IPV6CTL_MRTPROTO = 8
+IPV6CTL_MAXFRAGPACKETS = 9
+IPV6CTL_SOURCECHECK = 10
+IPV6CTL_SOURCECHECK_LOGINT = 11
+IPV6CTL_ACCEPT_RTADV = 12
+IPV6CTL_KEEPFAITH = 13
+IPV6CTL_LOG_INTERVAL = 14
+IPV6CTL_HDRNESTLIMIT = 15
+IPV6CTL_DAD_COUNT = 16
+IPV6CTL_AUTO_FLOWLABEL = 17
+IPV6CTL_DEFMCASTHLIM = 18
+IPV6CTL_GIF_HLIM = 19
+IPV6CTL_KAME_VERSION = 20
+IPV6CTL_USE_DEPRECATED = 21
+IPV6CTL_RR_PRUNE = 22
+IPV6CTL_MAPPED_ADDR = 23
+IPV6CTL_V6ONLY = 24
+IPV6CTL_RTEXPIRE = 25
+IPV6CTL_RTMINEXPIRE = 26
+IPV6CTL_RTMAXCACHE = 27
+IPV6CTL_USETEMPADDR = 32
+IPV6CTL_TEMPPLTIME = 33
+IPV6CTL_TEMPVLTIME = 34
+IPV6CTL_AUTO_LINKLOCAL = 35
+IPV6CTL_RIP6STATS = 36
+IPV6CTL_PREFER_TEMPADDR = 37
+IPV6CTL_ADDRCTLPOLICY = 38
+IPV6CTL_MAXFRAGS = 41
+IPV6CTL_MAXID = 42

Added: vendor/Python/current/Lib/plat-freebsd7/regen
===================================================================
--- vendor/Python/current/Lib/plat-freebsd7/regen	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-freebsd7/regen	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,3 @@
+#! /bin/sh
+set -v
+python ../../Tools/scripts/h2py.py -i '(u_long)' /usr/include/netinet/in.h

Added: vendor/Python/current/Lib/plat-generic/regen
===================================================================
--- vendor/Python/current/Lib/plat-generic/regen	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-generic/regen	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,3 @@
+#! /bin/sh
+set -v
+python$EXE ../../Tools/scripts/h2py.py -i '(u_long)' /usr/include/netinet/in.h


Property changes on: vendor/Python/current/Lib/plat-generic/regen
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/plat-irix5/AL.py
===================================================================
--- vendor/Python/current/Lib/plat-irix5/AL.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix5/AL.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,61 @@
+RATE_48000      = 48000
+RATE_44100      = 44100
+RATE_32000      = 32000
+RATE_22050      = 22050
+RATE_16000      = 16000
+RATE_11025      = 11025
+RATE_8000       = 8000
+
+SAMPFMT_TWOSCOMP= 1
+SAMPFMT_FLOAT   = 32
+SAMPFMT_DOUBLE  = 64
+
+SAMPLE_8        = 1
+SAMPLE_16       = 2
+        # SAMPLE_24 is the low 24 bits of a long, sign extended to 32 bits
+SAMPLE_24       = 4
+
+MONO            = 1
+STEREO          = 2
+QUADRO          = 4                     # 4CHANNEL is not a legal Python name
+
+INPUT_LINE      = 0
+INPUT_MIC       = 1
+INPUT_DIGITAL   = 2
+
+MONITOR_OFF     = 0
+MONITOR_ON      = 1
+
+ERROR_NUMBER            = 0
+ERROR_TYPE              = 1
+ERROR_LOCATION_LSP      = 2
+ERROR_LOCATION_MSP      = 3
+ERROR_LENGTH            = 4
+
+ERROR_INPUT_UNDERFLOW   = 0
+ERROR_OUTPUT_OVERFLOW   = 1
+
+# These seem to be not supported anymore:
+##HOLD, RELEASE                 = 0, 1
+##ATTAIL, ATHEAD, ATMARK, ATTIME        = 0, 1, 2, 3
+
+DEFAULT_DEVICE  = 1
+
+INPUT_SOURCE            = 0
+LEFT_INPUT_ATTEN        = 1
+RIGHT_INPUT_ATTEN       = 2
+INPUT_RATE              = 3
+OUTPUT_RATE             = 4
+LEFT_SPEAKER_GAIN       = 5
+RIGHT_SPEAKER_GAIN      = 6
+INPUT_COUNT             = 7
+OUTPUT_COUNT            = 8
+UNUSED_COUNT            = 9
+SYNC_INPUT_TO_AES       = 10
+SYNC_OUTPUT_TO_AES      = 11
+MONITOR_CTL             = 12
+LEFT_MONITOR_ATTEN      = 13
+RIGHT_MONITOR_ATTEN     = 14
+
+ENUM_VALUE      = 0     # only certain values are valid
+RANGE_VALUE     = 1     # any value in range is valid


Property changes on: vendor/Python/current/Lib/plat-irix5/AL.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/plat-irix5/CD.py
===================================================================
--- vendor/Python/current/Lib/plat-irix5/CD.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix5/CD.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,34 @@
+ERROR           = 0
+NODISC          = 1
+READY           = 2
+PLAYING         = 3
+PAUSED          = 4
+STILL           = 5
+
+AUDIO           = 0
+PNUM            = 1
+INDEX           = 2
+PTIME           = 3
+ATIME           = 4
+CATALOG         = 5
+IDENT           = 6
+CONTROL         = 7
+
+CDDA_DATASIZE   = 2352
+
+##CDDA_SUBCODESIZE      = (sizeof(struct subcodeQ))
+##CDDA_BLOCKSIZE        = (sizeof(struct cdframe))
+##CDDA_NUMSAMPLES       = (CDDA_DATASIZE/2)
+##
+##CDQ_PREEMP_MASK       = 0xd
+##CDQ_COPY_MASK = 0xb
+##CDQ_DDATA_MASK        = 0xd
+##CDQ_BROADCAST_MASK    = 0x8
+##CDQ_PREEMPHASIS       = 0x1
+##CDQ_COPY_PERMITTED    = 0x2
+##CDQ_DIGITAL_DATA      = 0x4
+##CDQ_BROADCAST_USE     = 0x8
+##
+##CDQ_MODE1     = 0x1
+##CDQ_MODE2     = 0x2
+##CDQ_MODE3     = 0x3


Property changes on: vendor/Python/current/Lib/plat-irix5/CD.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/plat-irix5/CL.py
===================================================================
--- vendor/Python/current/Lib/plat-irix5/CL.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix5/CL.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,24 @@
+# Backward compatible module CL.
+# All relevant symbols are now defined in the module cl.
+try:
+    from cl import *
+except ImportError:
+    from CL_old import *
+else:
+    del CompressImage
+    del DecompressImage
+    del GetAlgorithmName
+    del OpenCompressor
+    del OpenDecompressor
+    del QueryAlgorithms
+    del QueryMaxHeaderSize
+    del QueryScheme
+    del QuerySchemeFromName
+    del SetDefault
+    del SetMax
+    del SetMin
+    try:
+        del cvt_type
+    except NameError:
+        pass
+    del error


Property changes on: vendor/Python/current/Lib/plat-irix5/CL.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/plat-irix5/CL_old.py
===================================================================
--- vendor/Python/current/Lib/plat-irix5/CL_old.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix5/CL_old.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,236 @@
+#
+# cl.h - Compression Library typedefs and prototypes
+#
+#   01/07/92    Cleanup by Brian Knittel
+#   02/18/92    Original Version by Brian Knittel
+#
+
+#
+# originalFormat parameter values
+#
+MAX_NUMBER_OF_ORIGINAL_FORMATS = 32
+
+# Audio
+MONO = 0
+STEREO_INTERLEAVED = 1
+
+# Video
+# YUV is defined to be the same thing as YCrCb (luma and two chroma components).
+# 422 is appended to YUV (or YCrCb) if the chroma is sub-sampled by 2
+#       horizontally, packed as U Y1 V Y2 (byte order).
+# 422HC is appended to YUV (or YCrCb) if the chroma is sub-sampled by 2
+#       vertically in addition to horizontally, and is packed the same as
+#       422 except that U & V are not valid on the second line.
+#
+RGB = 0
+RGBX = 1
+RGBA = 2
+RGB332 = 3
+
+GRAYSCALE = 4
+Y = 4
+YUV = 5
+YCbCr = 5
+YUV422 = 6                              # 4:2:2 sampling
+YCbCr422 = 6                            # 4:2:2 sampling
+YUV422HC = 7                            # 4:1:1 sampling
+YCbCr422HC = 7                          # 4:1:1 sampling
+YUV422DC = 7                            # 4:1:1 sampling
+YCbCr422DC = 7                          # 4:1:1 sampling
+
+BEST_FIT = -1
+
+def BytesPerSample(s):
+    if s in (MONO, YUV):
+        return 2
+    elif s == STEREO_INTERLEAVED:
+        return 4
+    else:
+        return 0
+
+def BytesPerPixel(f):
+    if f in (RGB, YUV):
+        return 3
+    elif f in (RGBX, RGBA):
+        return 4
+    elif f in (RGB332, GRAYSCALE):
+        return 1
+    else:
+        return 2
+
+def AudioFormatName(f):
+    if f == MONO:
+        return 'MONO'
+    elif f == STEREO_INTERLEAVED:
+        return 'STEREO_INTERLEAVED'
+    else:
+        return 'Not a valid format'
+
+def VideoFormatName(f):
+    if f == RGB:
+        return 'RGB'
+    elif f == RGBX:
+        return 'RGBX'
+    elif f == RGBA:
+        return 'RGBA'
+    elif f == RGB332:
+        return 'RGB332'
+    elif f == GRAYSCALE:
+        return 'GRAYSCALE'
+    elif f == YUV:
+        return 'YUV'
+    elif f == YUV422:
+        return 'YUV422'
+    elif f == YUV422DC:
+        return 'YUV422DC'
+    else:
+        return 'Not a valid format'
+
+MAX_NUMBER_OF_AUDIO_ALGORITHMS = 32
+MAX_NUMBER_OF_VIDEO_ALGORITHMS = 32
+
+#
+# Algorithm types
+#
+AUDIO = 0
+VIDEO = 1
+
+def AlgorithmNumber(scheme):
+    return scheme & 0x7fff
+def AlgorithmType(scheme):
+    return (scheme >> 15) & 1
+def Algorithm(type, n):
+    return n | ((type & 1) << 15)
+
+#
+# "compressionScheme" argument values
+#
+UNKNOWN_SCHEME = -1
+
+UNCOMPRESSED_AUDIO = Algorithm(AUDIO, 0)
+G711_ULAW = Algorithm(AUDIO, 1)
+ULAW = Algorithm(AUDIO, 1)
+G711_ALAW = Algorithm(AUDIO, 2)
+ALAW = Algorithm(AUDIO, 2)
+AWARE_MPEG_AUDIO = Algorithm(AUDIO, 3)
+AWARE_MULTIRATE = Algorithm(AUDIO, 4)
+
+UNCOMPRESSED = Algorithm(VIDEO, 0)
+UNCOMPRESSED_VIDEO = Algorithm(VIDEO, 0)
+RLE = Algorithm(VIDEO, 1)
+JPEG = Algorithm(VIDEO, 2)
+MPEG_VIDEO = Algorithm(VIDEO, 3)
+MVC1 = Algorithm(VIDEO, 4)
+RTR = Algorithm(VIDEO, 5)
+RTR1 = Algorithm(VIDEO, 5)
+
+#
+# Parameters
+#
+MAX_NUMBER_OF_PARAMS = 256
+# Default Parameters
+IMAGE_WIDTH = 0
+IMAGE_HEIGHT = 1
+ORIGINAL_FORMAT = 2
+INTERNAL_FORMAT = 3
+COMPONENTS = 4
+BITS_PER_COMPONENT = 5
+FRAME_RATE = 6
+COMPRESSION_RATIO = 7
+EXACT_COMPRESSION_RATIO = 8
+FRAME_BUFFER_SIZE = 9
+COMPRESSED_BUFFER_SIZE = 10
+BLOCK_SIZE = 11
+PREROLL = 12
+FRAME_TYPE = 13
+ALGORITHM_ID = 14
+ALGORITHM_VERSION = 15
+ORIENTATION = 16
+NUMBER_OF_FRAMES = 17
+SPEED = 18
+LAST_FRAME_INDEX = 19
+NUMBER_OF_PARAMS = 20
+
+# JPEG Specific Parameters
+QUALITY_FACTOR = NUMBER_OF_PARAMS + 0
+
+# MPEG Specific Parameters
+END_OF_SEQUENCE = NUMBER_OF_PARAMS + 0
+
+# RTR Specific Parameters
+QUALITY_LEVEL = NUMBER_OF_PARAMS + 0
+ZOOM_X = NUMBER_OF_PARAMS + 1
+ZOOM_Y = NUMBER_OF_PARAMS + 2
+
+#
+# Parameter value types
+#
+ENUM_VALUE = 0                          # only certain constant values are valid
+RANGE_VALUE = 1                         # any value in a given range is valid
+FLOATING_ENUM_VALUE = 2                 # only certain constant floating point values are valid
+FLOATING_RANGE_VALUE = 3                # any value in a given floating point range is valid
+
+#
+# Algorithm Functionality
+#
+DECOMPRESSOR = 1
+COMPRESSOR = 2
+CODEC = 3
+
+#
+# Buffer types
+#
+NONE = 0
+FRAME = 1
+DATA = 2
+
+#
+# Frame types
+#
+NONE = 0
+KEYFRAME = 1
+INTRA = 1
+PREDICTED = 2
+BIDIRECTIONAL = 3
+
+#
+# Orientations
+#
+TOP_DOWN = 0
+BOTTOM_UP = 1
+
+#
+# SGI Proprietary Algorithm Header Start Code
+#
+HEADER_START_CODE = 0xc1C0DEC
+
+#
+# error codes
+#
+
+BAD_NO_BUFFERSPACE =  -2                # no space for internal buffers
+BAD_PVBUFFER =  -3                      # param/val buffer doesn't make sense
+BAD_BUFFERLENGTH_NEG =  -4              # negative buffer length
+BAD_BUFFERLENGTH_ODD =  -5              # odd length parameter/value buffer
+BAD_PARAM =  -6                         # invalid parameter
+BAD_COMPRESSION_SCHEME =  -7            # compression scheme parameter invalid
+BAD_COMPRESSOR_HANDLE =  -8             # compression handle parameter invalid
+BAD_COMPRESSOR_HANDLE_POINTER = -9      # compression handle pointer invalid
+BAD_BUFFER_HANDLE = -10                 # buffer handle invalid
+BAD_BUFFER_QUERY_SIZE = -11             # buffer query size too large
+JPEG_ERROR = -12                        # error from libjpeg
+BAD_FRAME_SIZE = -13                    # frame size invalid
+PARAM_OUT_OF_RANGE = -14                # parameter out of range
+ADDED_ALGORITHM_ERROR = -15             # added algorithm had a unique error
+BAD_ALGORITHM_TYPE = -16                # bad algorithm type
+BAD_ALGORITHM_NAME = -17                # bad algorithm name
+BAD_BUFFERING = -18                     # bad buffering calls
+BUFFER_NOT_CREATED = -19                # buffer not created
+BAD_BUFFER_EXISTS = -20                 # buffer already created
+BAD_INTERNAL_FORMAT = -21               # invalid internal format
+BAD_BUFFER_POINTER = -22                # invalid buffer pointer
+FRAME_BUFFER_SIZE_ZERO = -23            # frame buffer has zero size
+BAD_STREAM_HEADER = -24                 # invalid stream header
+
+BAD_LICENSE = -25                       # netls license not valid
+AWARE_ERROR = -26                       # error from libawcmp


Property changes on: vendor/Python/current/Lib/plat-irix5/CL_old.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/plat-irix5/DEVICE.py
===================================================================
--- vendor/Python/current/Lib/plat-irix5/DEVICE.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix5/DEVICE.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,400 @@
+NULLDEV = 0
+BUTOFFSET = 1
+VALOFFSET = 256
+PSEUDOFFSET = 512
+BUT2OFFSET = 3840
+TIMOFFSET = 515
+XKBDOFFSET = 143
+BUTCOUNT = 255
+VALCOUNT = 256
+TIMCOUNT = 4
+XKBDCOUNT = 28
+USERBUTOFFSET = 4096
+USERVALOFFSET = 12288
+USERPSEUDOFFSET = 16384
+BUT0 = 1
+BUT1 = 2
+BUT2 = 3
+BUT3 = 4
+BUT4 = 5
+BUT5 = 6
+BUT6 = 7
+BUT7 = 8
+BUT8 = 9
+BUT9 = 10
+BUT10 = 11
+BUT11 = 12
+BUT12 = 13
+BUT13 = 14
+BUT14 = 15
+BUT15 = 16
+BUT16 = 17
+BUT17 = 18
+BUT18 = 19
+BUT19 = 20
+BUT20 = 21
+BUT21 = 22
+BUT22 = 23
+BUT23 = 24
+BUT24 = 25
+BUT25 = 26
+BUT26 = 27
+BUT27 = 28
+BUT28 = 29
+BUT29 = 30
+BUT30 = 31
+BUT31 = 32
+BUT32 = 33
+BUT33 = 34
+BUT34 = 35
+BUT35 = 36
+BUT36 = 37
+BUT37 = 38
+BUT38 = 39
+BUT39 = 40
+BUT40 = 41
+BUT41 = 42
+BUT42 = 43
+BUT43 = 44
+BUT44 = 45
+BUT45 = 46
+BUT46 = 47
+BUT47 = 48
+BUT48 = 49
+BUT49 = 50
+BUT50 = 51
+BUT51 = 52
+BUT52 = 53
+BUT53 = 54
+BUT54 = 55
+BUT55 = 56
+BUT56 = 57
+BUT57 = 58
+BUT58 = 59
+BUT59 = 60
+BUT60 = 61
+BUT61 = 62
+BUT62 = 63
+BUT63 = 64
+BUT64 = 65
+BUT65 = 66
+BUT66 = 67
+BUT67 = 68
+BUT68 = 69
+BUT69 = 70
+BUT70 = 71
+BUT71 = 72
+BUT72 = 73
+BUT73 = 74
+BUT74 = 75
+BUT75 = 76
+BUT76 = 77
+BUT77 = 78
+BUT78 = 79
+BUT79 = 80
+BUT80 = 81
+BUT81 = 82
+BUT82 = 83
+MAXKBDBUT = 83
+BUT100 = 101
+BUT101 = 102
+BUT102 = 103
+BUT103 = 104
+BUT104 = 105
+BUT105 = 106
+BUT106 = 107
+BUT107 = 108
+BUT108 = 109
+BUT109 = 110
+BUT110 = 111
+BUT111 = 112
+BUT112 = 113
+BUT113 = 114
+BUT114 = 115
+BUT115 = 116
+BUT116 = 117
+BUT117 = 118
+BUT118 = 119
+BUT119 = 120
+BUT120 = 121
+BUT121 = 122
+BUT122 = 123
+BUT123 = 124
+BUT124 = 125
+BUT125 = 126
+BUT126 = 127
+BUT127 = 128
+BUT128 = 129
+BUT129 = 130
+BUT130 = 131
+BUT131 = 132
+BUT132 = 133
+BUT133 = 134
+BUT134 = 135
+BUT135 = 136
+BUT136 = 137
+BUT137 = 138
+BUT138 = 139
+BUT139 = 140
+BUT140 = 141
+BUT141 = 142
+BUT142 = 143
+BUT143 = 144
+BUT144 = 145
+BUT145 = 146
+BUT146 = 147
+BUT147 = 148
+BUT148 = 149
+BUT149 = 150
+BUT150 = 151
+BUT151 = 152
+BUT152 = 153
+BUT153 = 154
+BUT154 = 155
+BUT155 = 156
+BUT156 = 157
+BUT157 = 158
+BUT158 = 159
+BUT159 = 160
+BUT160 = 161
+BUT161 = 162
+BUT162 = 163
+BUT163 = 164
+BUT164 = 165
+BUT165 = 166
+BUT166 = 167
+BUT167 = 168
+BUT168 = 169
+BUT181 = 182
+BUT182 = 183
+BUT183 = 184
+BUT184 = 185
+BUT185 = 186
+BUT186 = 187
+BUT187 = 188
+BUT188 = 189
+BUT189 = 190
+MOUSE1 = 101
+MOUSE2 = 102
+MOUSE3 = 103
+LEFTMOUSE = 103
+MIDDLEMOUSE = 102
+RIGHTMOUSE = 101
+LPENBUT = 104
+BPAD0 = 105
+BPAD1 = 106
+BPAD2 = 107
+BPAD3 = 108
+LPENVALID = 109
+SWBASE = 111
+SW0 = 111
+SW1 = 112
+SW2 = 113
+SW3 = 114
+SW4 = 115
+SW5 = 116
+SW6 = 117
+SW7 = 118
+SW8 = 119
+SW9 = 120
+SW10 = 121
+SW11 = 122
+SW12 = 123
+SW13 = 124
+SW14 = 125
+SW15 = 126
+SW16 = 127
+SW17 = 128
+SW18 = 129
+SW19 = 130
+SW20 = 131
+SW21 = 132
+SW22 = 133
+SW23 = 134
+SW24 = 135
+SW25 = 136
+SW26 = 137
+SW27 = 138
+SW28 = 139
+SW29 = 140
+SW30 = 141
+SW31 = 142
+SBBASE = 182
+SBPICK = 182
+SBBUT1 = 183
+SBBUT2 = 184
+SBBUT3 = 185
+SBBUT4 = 186
+SBBUT5 = 187
+SBBUT6 = 188
+SBBUT7 = 189
+SBBUT8 = 190
+AKEY = 11
+BKEY = 36
+CKEY = 28
+DKEY = 18
+EKEY = 17
+FKEY = 19
+GKEY = 26
+HKEY = 27
+IKEY = 40
+JKEY = 34
+KKEY = 35
+LKEY = 42
+MKEY = 44
+NKEY = 37
+OKEY = 41
+PKEY = 48
+QKEY = 10
+RKEY = 24
+SKEY = 12
+TKEY = 25
+UKEY = 33
+VKEY = 29
+WKEY = 16
+XKEY = 21
+YKEY = 32
+ZKEY = 20
+ZEROKEY = 46
+ONEKEY = 8
+TWOKEY = 14
+THREEKEY = 15
+FOURKEY = 22
+FIVEKEY = 23
+SIXKEY = 30
+SEVENKEY = 31
+EIGHTKEY = 38
+NINEKEY = 39
+BREAKKEY = 1
+SETUPKEY = 2
+CTRLKEY = 3
+LEFTCTRLKEY = CTRLKEY
+CAPSLOCKKEY = 4
+RIGHTSHIFTKEY = 5
+LEFTSHIFTKEY = 6
+NOSCRLKEY = 13
+ESCKEY = 7
+TABKEY = 9
+RETKEY = 51
+SPACEKEY = 83
+LINEFEEDKEY = 60
+BACKSPACEKEY = 61
+DELKEY = 62
+SEMICOLONKEY = 43
+PERIODKEY = 52
+COMMAKEY = 45
+QUOTEKEY = 50
+ACCENTGRAVEKEY = 55
+MINUSKEY = 47
+VIRGULEKEY = 53
+BACKSLASHKEY = 57
+EQUALKEY = 54
+LEFTBRACKETKEY = 49
+RIGHTBRACKETKEY = 56
+LEFTARROWKEY = 73
+DOWNARROWKEY = 74
+RIGHTARROWKEY = 80
+UPARROWKEY = 81
+PAD0 = 59
+PAD1 = 58
+PAD2 = 64
+PAD3 = 65
+PAD4 = 63
+PAD5 = 69
+PAD6 = 70
+PAD7 = 67
+PAD8 = 68
+PAD9 = 75
+PADPF1 = 72
+PADPF2 = 71
+PADPF3 = 79
+PADPF4 = 78
+PADPERIOD = 66
+PADMINUS = 76
+PADCOMMA = 77
+PADENTER = 82
+LEFTALTKEY = 143
+RIGHTALTKEY = 144
+RIGHTCTRLKEY = 145
+F1KEY = 146
+F2KEY = 147
+F3KEY = 148
+F4KEY = 149
+F5KEY = 150
+F6KEY = 151
+F7KEY = 152
+F8KEY = 153
+F9KEY = 154
+F10KEY = 155
+F11KEY = 156
+F12KEY = 157
+PRINTSCREENKEY = 158
+SCROLLLOCKKEY = 159
+PAUSEKEY = 160
+INSERTKEY = 161
+HOMEKEY = 162
+PAGEUPKEY = 163
+ENDKEY = 164
+PAGEDOWNKEY = 165
+NUMLOCKKEY = 166
+PADVIRGULEKEY = 167
+PADASTERKEY = 168
+PADPLUSKEY = 169
+SGIRESERVED = 256
+DIAL0 = 257
+DIAL1 = 258
+DIAL2 = 259
+DIAL3 = 260
+DIAL4 = 261
+DIAL5 = 262
+DIAL6 = 263
+DIAL7 = 264
+DIAL8 = 265
+MOUSEX = 266
+MOUSEY = 267
+LPENX = 268
+LPENY = 269
+BPADX = 270
+BPADY = 271
+CURSORX = 272
+CURSORY = 273
+GHOSTX = 274
+GHOSTY = 275
+SBTX = 276
+SBTY = 277
+SBTZ = 278
+SBRX = 279
+SBRY = 280
+SBRZ = 281
+SBPERIOD = 282
+TIMER0 = 515
+TIMER1 = 516
+TIMER2 = 517
+TIMER3 = 518
+KEYBD = 513
+RAWKEYBD = 514
+VALMARK = 523
+REDRAW = 528
+INPUTCHANGE = 534
+QFULL = 535
+QREADERROR = 538
+WINFREEZE = 539
+WINTHAW = 540
+REDRAWICONIC = 541
+WINQUIT = 542
+DEPTHCHANGE = 543
+WINSHUT = 546
+DRAWOVERLAY = 547
+VIDEO = 548
+MENUBUTTON = RIGHTMOUSE
+WINCLOSE = 537
+KEYBDFNAMES = 544
+KEYBDFSTRINGS = 545
+MAXSGIDEVICE = 20000
+GERROR = 524
+WMSEND = 529
+WMREPLY = 530
+WMGFCLOSE = 531
+WMTXCLOSE = 532
+MODECHANGE = 533
+PIECECHANGE = 536


Property changes on: vendor/Python/current/Lib/plat-irix5/DEVICE.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/plat-irix5/ERRNO.py
===================================================================
--- vendor/Python/current/Lib/plat-irix5/ERRNO.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix5/ERRNO.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,147 @@
+# Generated by h2py from /usr/include/errno.h
+
+# Included from sys/errno.h
+__KBASE = 1000
+__IRIXBASE = 1000
+EPERM = 1
+ENOENT = 2
+ESRCH = 3
+EINTR = 4
+EIO = 5
+ENXIO = 6
+E2BIG = 7
+ENOEXEC = 8
+EBADF = 9
+ECHILD = 10
+EAGAIN = 11
+ENOMEM = 12
+EACCES = 13
+EFAULT = 14
+ENOTBLK = 15
+EBUSY = 16
+EEXIST = 17
+EXDEV = 18
+ENODEV = 19
+ENOTDIR = 20
+EISDIR = 21
+EINVAL = 22
+ENFILE = 23
+EMFILE = 24
+ENOTTY = 25
+ETXTBSY = 26
+EFBIG = 27
+ENOSPC = 28
+ESPIPE = 29
+EROFS = 30
+EMLINK = 31
+EPIPE = 32
+EDOM = 33
+ERANGE = 34
+ENOMSG = 35
+EIDRM = 36
+ECHRNG = 37
+EL2NSYNC = 38
+EL3HLT = 39
+EL3RST = 40
+ELNRNG = 41
+EUNATCH = 42
+ENOCSI = 43
+EL2HLT = 44
+EDEADLK = 45
+ENOLCK = 46
+EBADE = 50
+EBADR = 51
+EXFULL = 52
+ENOANO = 53
+EBADRQC = 54
+EBADSLT = 55
+EDEADLOCK = 56
+EBFONT = 57
+ENOSTR = 60
+ENODATA = 61
+ETIME = 62
+ENOSR = 63
+ENONET = 64
+ENOPKG = 65
+EREMOTE = 66
+ENOLINK = 67
+EADV = 68
+ESRMNT = 69
+ECOMM = 70
+EPROTO = 71
+EMULTIHOP = 74
+EBADMSG = 77
+ENAMETOOLONG = 78
+EOVERFLOW = 79
+ENOTUNIQ = 80
+EBADFD = 81
+EREMCHG = 82
+ELIBACC = 83
+ELIBBAD = 84
+ELIBSCN = 85
+ELIBMAX = 86
+ELIBEXEC = 87
+EILSEQ = 88
+ENOSYS = 89
+ELOOP = 90
+ERESTART = 91
+ESTRPIPE = 92
+ENOTEMPTY = 93
+EUSERS = 94
+ENOTSOCK = 95
+EDESTADDRREQ = 96
+EMSGSIZE = 97
+EPROTOTYPE = 98
+ENOPROTOOPT = 99
+EPROTONOSUPPORT = 120
+ESOCKTNOSUPPORT = 121
+EOPNOTSUPP = 122
+EPFNOSUPPORT = 123
+EAFNOSUPPORT = 124
+EADDRINUSE = 125
+EADDRNOTAVAIL = 126
+ENETDOWN = 127
+ENETUNREACH = 128
+ENETRESET = 129
+ECONNABORTED = 130
+ECONNRESET = 131
+ENOBUFS = 132
+EISCONN = 133
+ENOTCONN = 134
+ESHUTDOWN = 143
+ETOOMANYREFS = 144
+ETIMEDOUT = 145
+ECONNREFUSED = 146
+EHOSTDOWN = 147
+EHOSTUNREACH = 148
+EWOULDBLOCK = __KBASE+101
+EWOULDBLOCK = EAGAIN
+EALREADY = 149
+EINPROGRESS = 150
+ESTALE = 151
+EIORESID = 500
+EUCLEAN = 135
+ENOTNAM = 137
+ENAVAIL = 138
+EISNAM = 139
+EREMOTEIO = 140
+EINIT = 141
+EREMDEV = 142
+ECANCELED = 158
+ECANCELED = 1000
+EDQUOT = 1133
+ENFSREMOTE = 1135
+ETCP_EBASE = 100
+ETCP_ELIMIT = 129
+ENAMI_EBASE = 129
+ENAMI_ELIMIT = 131
+ENFS_EBASE = 131
+ENFS_ELIMIT = 135
+ELASTERRNO = 135
+TCP_EBASE = ETCP_EBASE
+TCP_ELIMIT = ETCP_ELIMIT
+NAMI_EBASE = ENAMI_EBASE
+NAMI_ELIMIT = ENAMI_ELIMIT
+NFS_EBASE = ENFS_EBASE
+NFS_ELIMIT = ENFS_ELIMIT
+LASTERRNO = ELASTERRNO


Property changes on: vendor/Python/current/Lib/plat-irix5/ERRNO.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/plat-irix5/FILE.py
===================================================================
--- vendor/Python/current/Lib/plat-irix5/FILE.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix5/FILE.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,239 @@
+# Generated by h2py from /usr/include/sys/file.h
+
+# Included from sys/types.h
+
+# Included from sgidefs.h
+_MIPS_ISA_MIPS1 = 1
+_MIPS_ISA_MIPS2 = 2
+_MIPS_ISA_MIPS3 = 3
+_MIPS_ISA_MIPS4 = 4
+_MIPS_SIM_ABI32 = 1
+_MIPS_SIM_NABI32 = 2
+_MIPS_SIM_ABI64 = 3
+P_MYID = (-1)
+P_MYHOSTID = (-1)
+
+# Included from sys/bsd_types.h
+
+# Included from sys/mkdev.h
+ONBITSMAJOR = 7
+ONBITSMINOR = 8
+OMAXMAJ = 0x7f
+OMAXMIN = 0xff
+NBITSMAJOR = 14
+NBITSMINOR = 18
+MAXMAJ = 0x1ff
+MAXMIN = 0x3ffff
+OLDDEV = 0
+NEWDEV = 1
+MKDEV_VER = NEWDEV
+def major(dev): return __major(MKDEV_VER, dev)
+
+def minor(dev): return __minor(MKDEV_VER, dev)
+
+
+# Included from sys/select.h
+FD_SETSIZE = 1024
+NBBY = 8
+
+# Included from sys/sema.h
+HP_NOPOLICY = 0
+HP_ADDOFF = 1
+HP_MULOFF = 2
+SEMA_NAMSZ = 8
+SEMA_NOHIST = 0x1
+SEMA_LIFO = 0x2
+SEMA_MUTEX = 0x4
+SEMA_METER = 0x8
+SEMAOP_PSEMA = 1
+SEMAOP_VSEMA = 2
+SEMAOP_CPSEMA = 3
+SEMAOP_CVSEMA = 4
+SEMAOP_WSEMA = 5
+SEMAOP_UNSEMA = 6
+SEMAOP_INIT = 7
+SEMAOP_FREE = 8
+SSOP_PHIT = 1
+SSOP_PSLP = 2
+SSOP_PWAKE = 6
+SSOP_PRESIG = 7
+SSOP_POSTSIG = 8
+SSOP_VNOWAKE = 3
+SSOP_VWAKE = 4
+SSOP_CPHIT = 1
+SSOP_CPMISS = 5
+SSOP_CVNOWAKE = 3
+SSOP_CVWAKE = 4
+SSOP_WMISS = 5
+SSOP_WWAKE = 4
+SSOP_RMV = 9
+TZERO = 10
+SEMA_NOP = 0
+SEMA_WAKE = 1
+SEMA_VSEMA = 2
+SEMA_SPINOP = 3
+MR_ACCESS = 0x1
+MR_UPDATE = 0x2
+def cv_signal(cv): return cvsema(cv);
+
+def cv_destroy(cv): return freesema(cv)
+
+def mutex_enter(m): return psema(m, PZERO | PNOSTOP)
+
+def mutex_exit(m): return vsema(m)
+
+def mutex_destroy(m): return freesema(m)
+
+def MUTEX_HELD(m): return (ownsema(m))
+
+def MUTEX_HELD(m): return (1)
+
+RW_READER = MR_ACCESS
+RW_WRITER = MR_UPDATE
+def rw_exit(r): return mrunlock(r)
+
+def rw_tryupgrade(r): return cmrpromote(r)
+
+def rw_downgrade(r): return mrdemote(r)
+
+def rw_destroy(r): return mrfree(r)
+
+def RW_WRITE_HELD(r): return ismrlocked(r, MR_UPDATE)
+
+def RW_READ_HELD(r): return ismrlocked(r, MR_ACCESS)
+
+
+# Included from sys/splock.h
+SPLOCKNAMSIZ = 8
+SPLOCK_NONE = 0
+SPLOCK_SOFT = 1
+SPLOCK_HARD = 2
+OWNER_NONE = -1
+MAP_LOCKID = 0
+SPLOCK_MAX = (96*1024)
+SPLOCK_MAX = 32768
+MIN_POOL_SIZE = 256
+MAX_POOL_SIZE = 16384
+DEF_SEMA_POOL = 8192
+DEF_VNODE_POOL = 1024
+DEF_FILE_POOL = 1024
+def ownlock(x): return 1
+
+def splock(x): return 1
+
+def io_splock(x): return 1
+
+def apvsema(x): return vsema(x)
+
+def apcpsema(x): return cpsema(x)
+
+def apcvsema(x): return cvsema(x)
+
+def mp_mrunlock(a): return mrunlock(a)
+
+def apvsema(x): return 0
+
+def apcpsema(x): return 1
+
+def apcvsema(x): return 0
+
+def mp_mrunlock(a): return 0
+
+
+# Included from sys/fcntl.h
+FNDELAY = 0x04
+FAPPEND = 0x08
+FSYNC = 0x10
+FNONBLOCK = 0x80
+FASYNC = 0x1000
+FNONBLK = FNONBLOCK
+FDIRECT = 0x8000
+FCREAT = 0x0100
+FTRUNC = 0x0200
+FEXCL = 0x0400
+FNOCTTY = 0x0800
+O_RDONLY = 0
+O_WRONLY = 1
+O_RDWR = 2
+O_NDELAY = 0x04
+O_APPEND = 0x08
+O_SYNC = 0x10
+O_NONBLOCK = 0x80
+O_DIRECT = 0x8000
+O_CREAT = 0x100
+O_TRUNC = 0x200
+O_EXCL = 0x400
+O_NOCTTY = 0x800
+F_DUPFD = 0
+F_GETFD = 1
+F_SETFD = 2
+F_GETFL = 3
+F_SETFL = 4
+F_GETLK = 14
+F_SETLK = 6
+F_SETLKW = 7
+F_CHKFL = 8
+F_ALLOCSP = 10
+F_FREESP = 11
+F_SETBSDLK = 12
+F_SETBSDLKW = 13
+F_DIOINFO = 30
+F_FSGETXATTR = 31
+F_FSSETXATTR = 32
+F_GETLK64 = 33
+F_SETLK64 = 34
+F_SETLKW64 = 35
+F_ALLOCSP64 = 36
+F_FREESP64 = 37
+F_GETBMAP = 38
+F_FSSETDM = 39
+F_RSETLK = 20
+F_RGETLK = 21
+F_RSETLKW = 22
+F_GETOWN = 23
+F_SETOWN = 24
+F_O_GETLK = 5
+F_O_GETOWN = 10
+F_O_SETOWN = 11
+F_RDLCK = 01
+F_WRLCK = 02
+F_UNLCK = 03
+O_ACCMODE = 3
+FD_CLOEXEC = 1
+FD_NODUP_FORK = 4
+FMASK = 0x90FF
+FOPEN = 0xFFFFFFFF
+FREAD = 0x01
+FWRITE = 0x02
+FNDELAY = 0x04
+FAPPEND = 0x08
+FSYNC = 0x10
+FNONBLOCK = 0x80
+FASYNC = 0x1000
+FNONBLK = FNONBLOCK
+FDIRECT = 0x8000
+FCREAT = 0x0100
+FTRUNC = 0x0200
+FEXCL = 0x0400
+FNOCTTY = 0x0800
+IRIX4_FASYNC = 0x40
+FMARK = 0x4000
+FDEFER = 0x2000
+FINPROGRESS = 0x0400
+FINVIS = 0x0100
+FNMFS = 0x2000
+FCLOSEXEC = 001
+FDSHD = 0x0001
+FDNOMARK = 0x0002
+FDIGNPROGRESS = 0x0004
+LOCK_SH = 1
+LOCK_EX = 2
+LOCK_NB = 4
+LOCK_UN = 8
+F_OK = 0
+X_OK = 1
+W_OK = 2
+R_OK = 4
+L_SET = 0
+L_INCR = 1
+L_XTND = 2


Property changes on: vendor/Python/current/Lib/plat-irix5/FILE.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/plat-irix5/FL.py
===================================================================
--- vendor/Python/current/Lib/plat-irix5/FL.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix5/FL.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,289 @@
+# Constants used by the FORMS library (module fl).
+# This corresponds to "forms.h".
+# Recommended use: import FL; ... FL.NORMAL_BOX ... etc.
+# Alternate use: from FL import *; ... NORMAL_BOX ... etc.
+
+_v20 = 1
+_v21 = 1
+##import fl
+##try:
+##      _v20 = (fl.get_rgbmode is not None)
+##except:
+##      _v20 = 0
+##del fl
+
+NULL = 0
+FALSE = 0
+TRUE = 1
+
+EVENT = -1
+
+LABEL_SIZE = 64
+if _v20:
+    SHORTCUT_SIZE = 32
+PLACE_FREE = 0
+PLACE_SIZE = 1
+PLACE_ASPECT = 2
+PLACE_MOUSE = 3
+PLACE_CENTER = 4
+PLACE_POSITION = 5
+FL_PLACE_FULLSCREEN = 6
+FIND_INPUT = 0
+FIND_AUTOMATIC = 1
+FIND_MOUSE = 2
+BEGIN_GROUP = 10000
+END_GROUP = 20000
+ALIGN_TOP = 0
+ALIGN_BOTTOM = 1
+ALIGN_LEFT = 2
+ALIGN_RIGHT = 3
+ALIGN_CENTER = 4
+NO_BOX = 0
+UP_BOX = 1
+DOWN_BOX = 2
+FLAT_BOX = 3
+BORDER_BOX = 4
+SHADOW_BOX = 5
+FRAME_BOX = 6
+ROUNDED_BOX = 7
+RFLAT_BOX = 8
+RSHADOW_BOX = 9
+TOP_BOUND_COL = 51
+LEFT_BOUND_COL = 55
+BOT_BOUND_COL = 40
+RIGHT_BOUND_COL = 35
+COL1 = 47
+MCOL = 49
+LCOL = 0
+BOUND_WIDTH = 3.0
+DRAW = 0
+PUSH = 1
+RELEASE = 2
+ENTER = 3
+LEAVE = 4
+MOUSE = 5
+FOCUS = 6
+UNFOCUS = 7
+KEYBOARD = 8
+STEP = 9
+MOVE = 10
+FONT_NAME = 'Helvetica'
+FONT_BOLDNAME = 'Helvetica-Bold'
+FONT_ITALICNAME = 'Helvetica-Oblique'
+FONT_FIXEDNAME = 'Courier'
+FONT_ICONNAME = 'Icon'
+SMALL_FONT = 8.0
+NORMAL_FONT = 11.0
+LARGE_FONT = 20.0
+NORMAL_STYLE = 0
+BOLD_STYLE = 1
+ITALIC_STYLE = 2
+FIXED_STYLE = 3
+ENGRAVED_STYLE = 4
+ICON_STYLE = 5
+BITMAP = 3
+NORMAL_BITMAP = 0
+BITMAP_BOXTYPE = NO_BOX
+BITMAP_COL1 = 0
+BITMAP_COL2 = COL1
+BITMAP_LCOL = LCOL
+BITMAP_ALIGN = ALIGN_BOTTOM
+BITMAP_MAXSIZE = 128*128
+BITMAP_BW = BOUND_WIDTH
+BOX = 1
+BOX_BOXTYPE = UP_BOX
+BOX_COL1 = COL1
+BOX_LCOL = LCOL
+BOX_ALIGN = ALIGN_CENTER
+BOX_BW = BOUND_WIDTH
+BROWSER = 71
+NORMAL_BROWSER = 0
+SELECT_BROWSER = 1
+HOLD_BROWSER = 2
+MULTI_BROWSER = 3
+BROWSER_BOXTYPE = DOWN_BOX
+BROWSER_COL1 = COL1
+BROWSER_COL2 = 3
+BROWSER_LCOL = LCOL
+BROWSER_ALIGN = ALIGN_BOTTOM
+BROWSER_SLCOL = COL1
+BROWSER_BW = BOUND_WIDTH
+BROWSER_LINELENGTH = 128
+BROWSER_MAXLINE = 512
+BUTTON = 11
+NORMAL_BUTTON = 0
+PUSH_BUTTON = 1
+RADIO_BUTTON = 2
+HIDDEN_BUTTON = 3
+TOUCH_BUTTON = 4
+INOUT_BUTTON = 5
+RETURN_BUTTON = 6
+if _v20:
+    HIDDEN_RET_BUTTON = 7
+BUTTON_BOXTYPE = UP_BOX
+BUTTON_COL1 = COL1
+BUTTON_COL2 = COL1
+BUTTON_LCOL = LCOL
+BUTTON_ALIGN = ALIGN_CENTER
+BUTTON_MCOL1 = MCOL
+BUTTON_MCOL2 = MCOL
+BUTTON_BW = BOUND_WIDTH
+if _v20:
+    CHART = 4
+    BAR_CHART = 0
+    HORBAR_CHART = 1
+    LINE_CHART = 2
+    FILLED_CHART = 3
+    SPIKE_CHART = 4
+    PIE_CHART = 5
+    SPECIALPIE_CHART = 6
+    CHART_BOXTYPE = BORDER_BOX
+    CHART_COL1 = COL1
+    CHART_LCOL = LCOL
+    CHART_ALIGN = ALIGN_BOTTOM
+    CHART_BW = BOUND_WIDTH
+    CHART_MAX = 128
+CHOICE = 42
+NORMAL_CHOICE = 0
+CHOICE_BOXTYPE = DOWN_BOX
+CHOICE_COL1 = COL1
+CHOICE_COL2 = LCOL
+CHOICE_LCOL = LCOL
+CHOICE_ALIGN = ALIGN_LEFT
+CHOICE_BW = BOUND_WIDTH
+CHOICE_MCOL = MCOL
+CHOICE_MAXITEMS = 128
+CHOICE_MAXSTR = 64
+CLOCK = 61
+SQUARE_CLOCK = 0
+ROUND_CLOCK = 1
+CLOCK_BOXTYPE = UP_BOX
+CLOCK_COL1 = 37
+CLOCK_COL2 = 42
+CLOCK_LCOL = LCOL
+CLOCK_ALIGN = ALIGN_BOTTOM
+CLOCK_TOPCOL = COL1
+CLOCK_BW = BOUND_WIDTH
+COUNTER = 25
+NORMAL_COUNTER = 0
+SIMPLE_COUNTER = 1
+COUNTER_BOXTYPE = UP_BOX
+COUNTER_COL1 = COL1
+COUNTER_COL2 = 4
+COUNTER_LCOL = LCOL
+COUNTER_ALIGN = ALIGN_BOTTOM
+if _v20:
+    COUNTER_BW = BOUND_WIDTH
+else:
+    DEFAULT = 51
+    RETURN_DEFAULT = 0
+    ALWAYS_DEFAULT = 1
+DIAL = 22
+NORMAL_DIAL = 0
+LINE_DIAL = 1
+DIAL_BOXTYPE = NO_BOX
+DIAL_COL1 = COL1
+DIAL_COL2 = 37
+DIAL_LCOL = LCOL
+DIAL_ALIGN = ALIGN_BOTTOM
+DIAL_TOPCOL = COL1
+DIAL_BW = BOUND_WIDTH
+FREE = 101
+NORMAL_FREE = 1
+SLEEPING_FREE = 2
+INPUT_FREE = 3
+CONTINUOUS_FREE = 4
+ALL_FREE = 5
+INPUT = 31
+NORMAL_INPUT = 0
+if _v20:
+    FLOAT_INPUT = 1
+    INT_INPUT = 2
+    HIDDEN_INPUT = 3
+    if _v21:
+        MULTILINE_INPUT = 4
+        SECRET_INPUT = 5
+else:
+    ALWAYS_INPUT = 1
+INPUT_BOXTYPE = DOWN_BOX
+INPUT_COL1 = 13
+INPUT_COL2 = 5
+INPUT_LCOL = LCOL
+INPUT_ALIGN = ALIGN_LEFT
+INPUT_TCOL = LCOL
+INPUT_CCOL = 4
+INPUT_BW = BOUND_WIDTH
+INPUT_MAX = 128
+LIGHTBUTTON = 12
+LIGHTBUTTON_BOXTYPE = UP_BOX
+LIGHTBUTTON_COL1 = 39
+LIGHTBUTTON_COL2 = 3
+LIGHTBUTTON_LCOL = LCOL
+LIGHTBUTTON_ALIGN = ALIGN_CENTER
+LIGHTBUTTON_TOPCOL = COL1
+LIGHTBUTTON_MCOL = MCOL
+LIGHTBUTTON_BW1 = BOUND_WIDTH
+LIGHTBUTTON_BW2 = BOUND_WIDTH/2.0
+LIGHTBUTTON_MINSIZE = 12.0
+MENU = 41
+TOUCH_MENU = 0
+PUSH_MENU = 1
+MENU_BOXTYPE = BORDER_BOX
+MENU_COL1 = 55
+MENU_COL2 = 37
+MENU_LCOL = LCOL
+MENU_ALIGN = ALIGN_CENTER
+MENU_BW = BOUND_WIDTH
+MENU_MAX = 300
+POSITIONER = 23
+NORMAL_POSITIONER = 0
+POSITIONER_BOXTYPE = DOWN_BOX
+POSITIONER_COL1 = COL1
+POSITIONER_COL2 = 1
+POSITIONER_LCOL = LCOL
+POSITIONER_ALIGN = ALIGN_BOTTOM
+POSITIONER_BW = BOUND_WIDTH
+ROUNDBUTTON = 13
+ROUNDBUTTON_BOXTYPE = NO_BOX
+ROUNDBUTTON_COL1 = 7
+ROUNDBUTTON_COL2 = 3
+ROUNDBUTTON_LCOL = LCOL
+ROUNDBUTTON_ALIGN = ALIGN_CENTER
+ROUNDBUTTON_TOPCOL = COL1
+ROUNDBUTTON_MCOL = MCOL
+ROUNDBUTTON_BW = BOUND_WIDTH
+SLIDER = 21
+VALSLIDER = 24
+VERT_SLIDER = 0
+HOR_SLIDER = 1
+VERT_FILL_SLIDER = 2
+HOR_FILL_SLIDER = 3
+VERT_NICE_SLIDER = 4
+HOR_NICE_SLIDER = 5
+SLIDER_BOXTYPE = DOWN_BOX
+SLIDER_COL1 = COL1
+SLIDER_COL2 = COL1
+SLIDER_LCOL = LCOL
+SLIDER_ALIGN = ALIGN_BOTTOM
+SLIDER_BW1 = BOUND_WIDTH
+SLIDER_BW2 = BOUND_WIDTH*0.75
+SLIDER_FINE = 0.05
+SLIDER_WIDTH = 0.08
+TEXT = 2
+NORMAL_TEXT = 0
+TEXT_BOXTYPE = NO_BOX
+TEXT_COL1 = COL1
+TEXT_LCOL = LCOL
+TEXT_ALIGN = ALIGN_LEFT
+TEXT_BW = BOUND_WIDTH
+TIMER = 62
+NORMAL_TIMER = 0
+VALUE_TIMER = 1
+HIDDEN_TIMER = 2
+TIMER_BOXTYPE = DOWN_BOX
+TIMER_COL1 = COL1
+TIMER_COL2 = 1
+TIMER_LCOL = LCOL
+TIMER_ALIGN = ALIGN_CENTER
+TIMER_BW = BOUND_WIDTH
+TIMER_BLINKRATE = 0.2


Property changes on: vendor/Python/current/Lib/plat-irix5/FL.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/plat-irix5/GET.py
===================================================================
--- vendor/Python/current/Lib/plat-irix5/GET.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix5/GET.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,59 @@
+# Symbols from <gl/get.h>
+
+BCKBUFFER = 0x1
+FRNTBUFFER = 0x2
+DRAWZBUFFER = 0x4
+DMRGB = 0
+DMSINGLE = 1
+DMDOUBLE = 2
+DMRGBDOUBLE = 5
+HZ30 = 0
+HZ60 = 1
+NTSC = 2
+HDTV = 3
+VGA = 4
+IRIS3K = 5
+PR60 = 6
+PAL = 9
+HZ30_SG = 11
+A343 = 14
+STR_RECT = 15
+VOF0 = 16
+VOF1 = 17
+VOF2 = 18
+VOF3 = 19
+SGI0 = 20
+SGI1 = 21
+SGI2 = 22
+HZ72 = 23
+GL_VIDEO_REG = 0x00800000
+GLV_GENLOCK = 0x00000001
+GLV_UNBLANK = 0x00000002
+GLV_SRED = 0x00000004
+GLV_SGREEN = 0x00000008
+GLV_SBLUE = 0x00000010
+GLV_SALPHA = 0x00000020
+GLV_TTLGENLOCK = 0x00000080
+GLV_TTLSYNC = GLV_TTLGENLOCK
+GLV_GREENGENLOCK = 0x0000100
+LEFTPLANE = 0x0001
+RIGHTPLANE = 0x0002
+BOTTOMPLANE = 0x0004
+TOPPLANE = 0x0008
+NEARPLANE = 0x0010
+FARPLANE = 0x0020
+## GETDEF = __GL_GET_H__
+NOBUFFER = 0x0
+BOTHBUFFERS = 0x3
+DMINTENSITYSINGLE = 3
+DMINTENSITYDOUBLE = 4
+MONSPECIAL = 0x20
+HZ50 = 3
+MONA = 5
+MONB = 6
+MONC = 7
+MOND = 8
+MON_ALL = 12
+MON_GEN_ALL = 13
+CMAPMULTI = 0
+CMAPONE = 1


Property changes on: vendor/Python/current/Lib/plat-irix5/GET.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/plat-irix5/GL.py
===================================================================
--- vendor/Python/current/Lib/plat-irix5/GL.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix5/GL.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,393 @@
+NULL = 0
+FALSE = 0
+TRUE = 1
+ATTRIBSTACKDEPTH = 10
+VPSTACKDEPTH = 8
+MATRIXSTACKDEPTH = 32
+NAMESTACKDEPTH = 1025
+STARTTAG = -2
+ENDTAG = -3
+BLACK = 0
+RED = 1
+GREEN = 2
+YELLOW = 3
+BLUE = 4
+MAGENTA = 5
+CYAN = 6
+WHITE = 7
+PUP_CLEAR = 0
+PUP_COLOR = 1
+PUP_BLACK = 2
+PUP_WHITE = 3
+NORMALDRAW = 0x010
+PUPDRAW = 0x020
+OVERDRAW = 0x040
+UNDERDRAW = 0x080
+CURSORDRAW = 0x100
+DUALDRAW = 0x200
+PATTERN_16 = 16
+PATTERN_32 = 32
+PATTERN_64 = 64
+PATTERN_16_SIZE = 16
+PATTERN_32_SIZE = 64
+PATTERN_64_SIZE = 256
+SRC_AUTO = 0
+SRC_FRONT = 1
+SRC_BACK = 2
+SRC_ZBUFFER = 3
+SRC_PUP = 4
+SRC_OVER = 5
+SRC_UNDER = 6
+SRC_FRAMEGRABBER = 7
+BF_ZERO = 0
+BF_ONE = 1
+BF_DC = 2
+BF_SC = 2
+BF_MDC = 3
+BF_MSC = 3
+BF_SA = 4
+BF_MSA = 5
+BF_DA = 6
+BF_MDA = 7
+BF_MIN_SA_MDA = 8
+AF_NEVER = 0
+AF_LESS = 1
+AF_EQUAL = 2
+AF_LEQUAL = 3
+AF_GREATER = 4
+AF_NOTEQUAL = 5
+AF_GEQUAL = 6
+AF_ALWAYS = 7
+ZF_NEVER = 0
+ZF_LESS = 1
+ZF_EQUAL = 2
+ZF_LEQUAL = 3
+ZF_GREATER = 4
+ZF_NOTEQUAL = 5
+ZF_GEQUAL = 6
+ZF_ALWAYS = 7
+ZSRC_DEPTH = 0
+ZSRC_COLOR = 1
+SMP_OFF = 0x0
+SMP_ON = 0x1
+SMP_SMOOTHER = 0x2
+SML_OFF = 0x0
+SML_ON = 0x1
+SML_SMOOTHER = 0x2
+SML_END_CORRECT = 0x4
+PYSM_OFF = 0
+PYSM_ON = 1
+PYSM_SHRINK = 2
+DT_OFF = 0
+DT_ON = 1
+PUP_NONE = 0
+PUP_GREY = 0x1
+PUP_BOX = 0x2
+PUP_CHECK = 0x4
+GLC_OLDPOLYGON = 0
+GLC_ZRANGEMAP = 1
+GLC_MQUEUERATE = 2
+GLC_SOFTATTACH = 3
+GLC_MANAGEBG = 4
+GLC_SLOWMAPCOLORS = 5
+GLC_INPUTCHANGEBUG = 6
+GLC_NOBORDERBUG = 7
+GLC_SET_VSYNC = 8
+GLC_GET_VSYNC = 9
+GLC_VSYNC_SLEEP = 10
+GLC_COMPATRATE = 15
+C16X1 = 0
+C16X2 = 1
+C32X1 = 2
+C32X2 = 3
+CCROSS = 4
+FLAT = 0
+GOURAUD = 1
+LO_ZERO = 0x0
+LO_AND = 0x1
+LO_ANDR = 0x2
+LO_SRC = 0x3
+LO_ANDI = 0x4
+LO_DST = 0x5
+LO_XOR = 0x6
+LO_OR = 0x7
+LO_NOR = 0x8
+LO_XNOR = 0x9
+LO_NDST = 0xa
+LO_ORR = 0xb
+LO_NSRC = 0xc
+LO_ORI = 0xd
+LO_NAND = 0xe
+LO_ONE = 0xf
+INFOCUSSCRN = -2
+ST_KEEP = 0
+ST_ZERO = 1
+ST_REPLACE = 2
+ST_INCR = 3
+ST_DECR = 4
+ST_INVERT = 5
+SF_NEVER = 0
+SF_LESS = 1
+SF_EQUAL = 2
+SF_LEQUAL = 3
+SF_GREATER = 4
+SF_NOTEQUAL = 5
+SF_GEQUAL = 6
+SF_ALWAYS = 7
+SS_OFF = 0
+SS_DEPTH = 1
+PYM_FILL = 1
+PYM_POINT = 2
+PYM_LINE = 3
+PYM_HOLLOW = 4
+PYM_LINE_FAST = 5
+FG_OFF = 0
+FG_ON = 1
+FG_DEFINE = 2
+FG_VTX_EXP = 2
+FG_VTX_LIN = 3
+FG_PIX_EXP = 4
+FG_PIX_LIN = 5
+FG_VTX_EXP2 = 6
+FG_PIX_EXP2 = 7
+PM_SHIFT = 0
+PM_EXPAND = 1
+PM_C0 = 2
+PM_C1 = 3
+PM_ADD24 = 4
+PM_SIZE = 5
+PM_OFFSET = 6
+PM_STRIDE = 7
+PM_TTOB = 8
+PM_RTOL = 9
+PM_ZDATA = 10
+PM_WARP = 11
+PM_RDX = 12
+PM_RDY = 13
+PM_CDX = 14
+PM_CDY = 15
+PM_XSTART = 16
+PM_YSTART = 17
+PM_VO1 = 1000
+NAUTO = 0
+NNORMALIZE = 1
+AC_CLEAR = 0
+AC_ACCUMULATE = 1
+AC_CLEAR_ACCUMULATE = 2
+AC_RETURN = 3
+AC_MULT = 4
+AC_ADD = 5
+CP_OFF = 0
+CP_ON = 1
+CP_DEFINE = 2
+SB_RESET = 0
+SB_TRACK = 1
+SB_HOLD = 2
+RD_FREEZE = 0x00000001
+RD_ALPHAONE = 0x00000002
+RD_IGNORE_UNDERLAY = 0x00000004
+RD_IGNORE_OVERLAY = 0x00000008
+RD_IGNORE_PUP = 0x00000010
+RD_OFFSCREEN = 0x00000020
+GD_XPMAX = 0
+GD_YPMAX = 1
+GD_XMMAX = 2
+GD_YMMAX = 3
+GD_ZMIN = 4
+GD_ZMAX = 5
+GD_BITS_NORM_SNG_RED = 6
+GD_BITS_NORM_SNG_GREEN = 7
+GD_BITS_NORM_SNG_BLUE = 8
+GD_BITS_NORM_DBL_RED = 9
+GD_BITS_NORM_DBL_GREEN = 10
+GD_BITS_NORM_DBL_BLUE = 11
+GD_BITS_NORM_SNG_CMODE = 12
+GD_BITS_NORM_DBL_CMODE = 13
+GD_BITS_NORM_SNG_MMAP = 14
+GD_BITS_NORM_DBL_MMAP = 15
+GD_BITS_NORM_ZBUFFER = 16
+GD_BITS_OVER_SNG_CMODE = 17
+GD_BITS_UNDR_SNG_CMODE = 18
+GD_BITS_PUP_SNG_CMODE = 19
+GD_BITS_NORM_SNG_ALPHA = 21
+GD_BITS_NORM_DBL_ALPHA = 22
+GD_BITS_CURSOR = 23
+GD_OVERUNDER_SHARED = 24
+GD_BLEND = 25
+GD_CIFRACT = 26
+GD_CROSSHAIR_CINDEX = 27
+GD_DITHER = 28
+GD_LINESMOOTH_CMODE = 30
+GD_LINESMOOTH_RGB = 31
+GD_LOGICOP = 33
+GD_NSCRNS = 35
+GD_NURBS_ORDER = 36
+GD_NBLINKS = 37
+GD_NVERTEX_POLY = 39
+GD_PATSIZE_64 = 40
+GD_PNTSMOOTH_CMODE = 41
+GD_PNTSMOOTH_RGB = 42
+GD_PUP_TO_OVERUNDER = 43
+GD_READSOURCE = 44
+GD_READSOURCE_ZBUFFER = 48
+GD_STEREO = 50
+GD_SUBPIXEL_LINE = 51
+GD_SUBPIXEL_PNT = 52
+GD_SUBPIXEL_POLY = 53
+GD_TRIMCURVE_ORDER = 54
+GD_WSYS = 55
+GD_ZDRAW_GEOM = 57
+GD_ZDRAW_PIXELS = 58
+GD_SCRNTYPE = 61
+GD_TEXTPORT = 62
+GD_NMMAPS = 63
+GD_FRAMEGRABBER = 64
+GD_TIMERHZ = 66
+GD_DBBOX = 67
+GD_AFUNCTION = 68
+GD_ALPHA_OVERUNDER = 69
+GD_BITS_ACBUF = 70
+GD_BITS_ACBUF_HW = 71
+GD_BITS_STENCIL = 72
+GD_CLIPPLANES = 73
+GD_FOGVERTEX = 74
+GD_LIGHTING_TWOSIDE = 76
+GD_POLYMODE = 77
+GD_POLYSMOOTH = 78
+GD_SCRBOX = 79
+GD_TEXTURE = 80
+GD_FOGPIXEL = 81
+GD_TEXTURE_PERSP = 82
+GD_MUXPIPES = 83
+GD_NOLIMIT = -2
+GD_WSYS_NONE = 0
+GD_WSYS_4S = 1
+GD_SCRNTYPE_WM = 0
+GD_SCRNTYPE_NOWM = 1
+N_PIXEL_TOLERANCE = 1
+N_CULLING = 2
+N_DISPLAY = 3
+N_ERRORCHECKING = 4
+N_SUBDIVISIONS = 5
+N_S_STEPS = 6
+N_T_STEPS = 7
+N_TILES = 8
+N_TMP1 = 9
+N_TMP2 = 10
+N_TMP3 = 11
+N_TMP4 = 12
+N_TMP5 = 13
+N_TMP6 = 14
+N_FILL = 1.0
+N_OUTLINE_POLY = 2.0
+N_OUTLINE_PATCH = 5.0
+N_ISOLINE_S = 12.0
+N_ST = 0x8
+N_STW = 0xd
+N_XYZ = 0x4c
+N_XYZW = 0x51
+N_TEX = 0x88
+N_TEXW = 0x8d
+N_RGBA = 0xd0
+N_RGBAW = 0xd5
+N_P2D = 0x8
+N_P2DR = 0xd
+N_V3D = 0x4c
+N_V3DR = 0x51
+N_T2D = 0x88
+N_T2DR = 0x8d
+N_C4D = 0xd0
+N_C4DR = 0xd5
+LMNULL = 0.0
+MSINGLE = 0
+MPROJECTION = 1
+MVIEWING = 2
+MTEXTURE = 3
+MAXLIGHTS = 8
+MAXRESTRICTIONS = 4
+DEFMATERIAL = 0
+EMISSION = 1
+AMBIENT = 2
+DIFFUSE = 3
+SPECULAR = 4
+SHININESS = 5
+COLORINDEXES = 6
+ALPHA = 7
+DEFLIGHT = 100
+LCOLOR = 101
+POSITION = 102
+SPOTDIRECTION = 103
+SPOTLIGHT = 104
+DEFLMODEL = 200
+LOCALVIEWER = 201
+ATTENUATION = 202
+ATTENUATION2 = 203
+TWOSIDE = 204
+MATERIAL = 1000
+BACKMATERIAL = 1001
+LIGHT0 = 1100
+LIGHT1 = 1101
+LIGHT2 = 1102
+LIGHT3 = 1103
+LIGHT4 = 1104
+LIGHT5 = 1105
+LIGHT6 = 1106
+LIGHT7 = 1107
+LMODEL = 1200
+LMC_COLOR = 0
+LMC_EMISSION = 1
+LMC_AMBIENT = 2
+LMC_DIFFUSE = 3
+LMC_SPECULAR = 4
+LMC_AD = 5
+LMC_NULL = 6
+TX_MINFILTER = 0x100
+TX_MAGFILTER = 0x200
+TX_WRAP = 0x300
+TX_WRAP_S = 0x310
+TX_WRAP_T = 0x320
+TX_TILE = 0x400
+TX_BORDER = 0x500
+TX_NULL = 0x000
+TX_POINT = 0x110
+TX_BILINEAR = 0x220
+TX_MIPMAP = 0x120
+TX_MIPMAP_POINT = 0x121
+TX_MIPMAP_LINEAR = 0x122
+TX_MIPMAP_BILINEAR = 0x123
+TX_MIPMAP_TRILINEAR = 0x124
+TX_REPEAT = 0x301
+TX_CLAMP = 0x302
+TX_SELECT = 0x303
+TX_TEXTURE_0 = 0
+TV_MODULATE = 0x101
+TV_BLEND = 0x102
+TV_DECAL = 0x103
+TV_COLOR = 0x200
+TV_NULL = 0x000
+TV_ENV0 = 0
+TX_S = 0
+TX_T = 1
+TG_OFF = 0
+TG_ON = 1
+TG_CONTOUR = 2
+TG_LINEAR = 3
+TG_SPHEREMAP = 4
+TG_REFRACTMAP = 5
+DGLSINK = 0
+DGLLOCAL = 1
+DGLTSOCKET = 2
+DGL4DDN = 3
+PUP_CURSOR = PUP_COLOR
+FATAL = 1
+WARNING = 2
+ASK_CONT = 3
+ASK_RESTART = 4
+XMAXSCREEN = 1279
+YMAXSCREEN = 1023
+XMAXMEDIUM = 1023
+YMAXMEDIUM = 767
+XMAX170 = 645
+YMAX170 = 484
+XMAXPAL = 779
+YMAXPAL = 574


Property changes on: vendor/Python/current/Lib/plat-irix5/GL.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/plat-irix5/GLWS.py
===================================================================
--- vendor/Python/current/Lib/plat-irix5/GLWS.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix5/GLWS.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,12 @@
+NOERROR = 0
+NOCONTEXT = -1
+NODISPLAY = -2
+NOWINDOW = -3
+NOGRAPHICS = -4
+NOTTOP = -5
+NOVISUAL = -6
+BUFSIZE = -7
+BADWINDOW = -8
+ALREADYBOUND = -100
+BINDFAILED = -101
+SETFAILED = -102


Property changes on: vendor/Python/current/Lib/plat-irix5/GLWS.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/plat-irix5/IN.py
===================================================================
--- vendor/Python/current/Lib/plat-irix5/IN.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix5/IN.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,141 @@
+# Generated by h2py from /usr/include/netinet/in.h
+
+# Included from sys/endian.h
+LITTLE_ENDIAN = 1234
+BIG_ENDIAN = 4321
+PDP_ENDIAN = 3412
+BYTE_ORDER = BIG_ENDIAN
+BYTE_ORDER = LITTLE_ENDIAN
+def ntohl(x): return (x)
+
+def ntohs(x): return (x)
+
+def htonl(x): return (x)
+
+def htons(x): return (x)
+
+def htonl(x): return ntohl(x)
+
+def htons(x): return ntohs(x)
+
+
+# Included from sys/bsd_types.h
+
+# Included from sys/mkdev.h
+ONBITSMAJOR = 7
+ONBITSMINOR = 8
+OMAXMAJ = 0x7f
+OMAXMIN = 0xff
+NBITSMAJOR = 14
+NBITSMINOR = 18
+MAXMAJ = 0x1ff
+MAXMIN = 0x3ffff
+OLDDEV = 0
+NEWDEV = 1
+MKDEV_VER = NEWDEV
+def major(dev): return __major(MKDEV_VER, dev)
+
+def minor(dev): return __minor(MKDEV_VER, dev)
+
+
+# Included from sys/select.h
+FD_SETSIZE = 1024
+NBBY = 8
+IPPROTO_IP = 0
+IPPROTO_ICMP = 1
+IPPROTO_IGMP = 2
+IPPROTO_GGP = 3
+IPPROTO_ENCAP = 4
+IPPROTO_TCP = 6
+IPPROTO_EGP = 8
+IPPROTO_PUP = 12
+IPPROTO_UDP = 17
+IPPROTO_IDP = 22
+IPPROTO_TP = 29
+IPPROTO_XTP = 36
+IPPROTO_HELLO = 63
+IPPROTO_ND = 77
+IPPROTO_EON = 80
+IPPROTO_RAW = 255
+IPPROTO_MAX = 256
+IPPORT_RESERVED = 1024
+IPPORT_USERRESERVED = 5000
+IPPORT_MAXPORT = 65535
+def IN_CLASSA(i): return (((long)(i) & 0x80000000) == 0)
+
+IN_CLASSA_NET = 0xff000000
+IN_CLASSA_NSHIFT = 24
+IN_CLASSA_HOST = 0x00ffffff
+IN_CLASSA_MAX = 128
+def IN_CLASSB(i): return (((long)(i) & 0xc0000000) == 0x80000000)
+
+IN_CLASSB_NET = 0xffff0000
+IN_CLASSB_NSHIFT = 16
+IN_CLASSB_HOST = 0x0000ffff
+IN_CLASSB_MAX = 65536
+def IN_CLASSC(i): return (((long)(i) & 0xe0000000) == 0xc0000000)
+
+IN_CLASSC_NET = 0xffffff00
+IN_CLASSC_NSHIFT = 8
+IN_CLASSC_HOST = 0x000000ff
+def IN_CLASSD(i): return (((long)(i) & 0xf0000000) == 0xe0000000)
+
+IN_CLASSD_NET = 0xf0000000
+IN_CLASSD_NSHIFT = 28
+IN_CLASSD_HOST = 0x0fffffff
+def IN_MULTICAST(i): return IN_CLASSD(i)
+
+def IN_EXPERIMENTAL(i): return (((long)(i) & 0xf0000000) == 0xf0000000)
+
+def IN_BADCLASS(i): return (((long)(i) & 0xf0000000) == 0xf0000000)
+
+INADDR_ANY = 0x00000000
+INADDR_BROADCAST = 0xffffffff
+INADDR_LOOPBACK = 0x7F000001
+INADDR_UNSPEC_GROUP = 0xe0000000
+INADDR_ALLHOSTS_GROUP = 0xe0000001
+INADDR_MAX_LOCAL_GROUP = 0xe00000ff
+INADDR_NONE = 0xffffffff
+IN_LOOPBACKNET = 127
+IP_OPTIONS = 1
+IP_MULTICAST_IF = 2
+IP_MULTICAST_TTL = 3
+IP_MULTICAST_LOOP = 4
+IP_ADD_MEMBERSHIP = 5
+IP_DROP_MEMBERSHIP = 6
+IP_HDRINCL = 7
+IP_TOS = 8
+IP_TTL = 9
+IP_RECVOPTS = 10
+IP_RECVRETOPTS = 11
+IP_RECVDSTADDR = 12
+IP_RETOPTS = 13
+IP_OPTIONS = 1
+IP_HDRINCL = 2
+IP_TOS = 3
+IP_TTL = 4
+IP_RECVOPTS = 5
+IP_RECVRETOPTS = 6
+IP_RECVDSTADDR = 7
+IP_RETOPTS = 8
+IP_MULTICAST_IF = 20
+IP_MULTICAST_TTL = 21
+IP_MULTICAST_LOOP = 22
+IP_ADD_MEMBERSHIP = 23
+IP_DROP_MEMBERSHIP = 24
+IRIX4_IP_OPTIONS = 1
+IRIX4_IP_MULTICAST_IF = 2
+IRIX4_IP_MULTICAST_TTL = 3
+IRIX4_IP_MULTICAST_LOOP = 4
+IRIX4_IP_ADD_MEMBERSHIP = 5
+IRIX4_IP_DROP_MEMBERSHIP = 6
+IRIX4_IP_HDRINCL = 7
+IRIX4_IP_TOS = 8
+IRIX4_IP_TTL = 9
+IRIX4_IP_RECVOPTS = 10
+IRIX4_IP_RECVRETOPTS = 11
+IRIX4_IP_RECVDSTADDR = 12
+IRIX4_IP_RETOPTS = 13
+IP_DEFAULT_MULTICAST_TTL = 1
+IP_DEFAULT_MULTICAST_LOOP = 1
+IP_MAX_MEMBERSHIPS = 20


Property changes on: vendor/Python/current/Lib/plat-irix5/IN.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/plat-irix5/IOCTL.py
===================================================================
--- vendor/Python/current/Lib/plat-irix5/IOCTL.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix5/IOCTL.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,233 @@
+# These lines were mostly generated by h2py.py (see demo/scripts)
+# from <sys/ioctl.h>, <sys/termio.h> and <termios.h> on Irix 4.0.2
+# with some manual changes to cope with imperfections in h2py.py.
+# The applicability on other systems is not clear; especially non-SYSV
+# systems may have a totally different set of ioctls.
+
+IOCTYPE = 0xff00
+LIOC = (ord('l')<<8)
+LIOCGETP = (LIOC|1)
+LIOCSETP = (LIOC|2)
+LIOCGETS = (LIOC|5)
+LIOCSETS = (LIOC|6)
+DIOC = (ord('d')<<8)
+DIOCGETC = (DIOC|1)
+DIOCGETB = (DIOC|2)
+DIOCSETE = (DIOC|3)
+IOCPARM_MASK = 0x7f
+IOC_VOID = 0x20000000
+IOC_OUT = 0x40000000
+IOC_IN = 0x80000000
+IOC_INOUT = (IOC_IN|IOC_OUT)
+int = 'i'
+short = 'h'
+long = 'l'
+def sizeof(t): import struct; return struct.calcsize(t)
+def _IO(x,y): return (IOC_VOID|((x)<<8)|y)
+def _IOR(x,y,t): return (IOC_OUT|((sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|y)
+def _IOW(x,y,t): return (IOC_IN|((sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|y)
+# this should be _IORW, but stdio got there first
+def _IOWR(x,y,t): return (IOC_INOUT|((sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|y)
+FIONREAD = _IOR(ord('f'), 127, int)
+FIONBIO = _IOW(ord('f'), 126, int)
+FIOASYNC = _IOW(ord('f'), 125, int)
+FIOSETOWN = _IOW(ord('f'), 124, int)
+FIOGETOWN = _IOR(ord('f'), 123, int)
+NCC = 8
+NCC_PAD = 7
+NCC_EXT = 16
+NCCS = (NCC+NCC_PAD+NCC_EXT)
+VINTR = 0
+VQUIT = 1
+VERASE = 2
+VKILL = 3
+VEOF = 4
+VEOL = 5
+VEOL2 = 6
+VMIN = VEOF
+VTIME = VEOL
+VSWTCH = 7
+VLNEXT = (NCC+NCC_PAD+0)
+VWERASE = (NCC+NCC_PAD+1)
+VRPRNT = (NCC+NCC_PAD+2)
+VFLUSHO = (NCC+NCC_PAD+3)
+VSTOP = (NCC+NCC_PAD+4)
+VSTART = (NCC+NCC_PAD+5)
+CNUL = '\0'
+CDEL = '\377'
+CESC = '\\'
+CINTR = '\177'
+CQUIT = '\34'
+CBRK = '\377'
+def CTRL(c): return ord(c) & 0x0f
+CERASE = CTRL('H')
+CKILL = CTRL('U')
+CEOF = CTRL('d')
+CEOT = CEOF
+CSTART = CTRL('q')
+CSTOP = CTRL('s')
+CSWTCH = CTRL('z')
+CSUSP = CSWTCH
+CNSWTCH = 0
+CLNEXT = CTRL('v')
+CWERASE = CTRL('w')
+CFLUSHO = CTRL('o')
+CFLUSH = CFLUSHO
+CRPRNT = CTRL('r')
+CDSUSP = CTRL('y')
+IGNBRK = 0000001
+BRKINT = 0000002
+IGNPAR = 0000004
+PARMRK = 0000010
+INPCK = 0000020
+ISTRIP = 0000040
+INLCR = 0000100
+IGNCR = 0000200
+ICRNL = 0000400
+IUCLC = 0001000
+IXON = 0002000
+IXANY = 0004000
+IXOFF = 0010000
+IBLKMD = 0020000
+OPOST = 0000001
+OLCUC = 0000002
+ONLCR = 0000004
+OCRNL = 0000010
+ONOCR = 0000020
+ONLRET = 0000040
+OFILL = 0000100
+OFDEL = 0000200
+NLDLY = 0000400
+NL0 = 0
+NL1 = 0000400
+CRDLY = 0003000
+CR0 = 0
+CR1 = 0001000
+CR2 = 0002000
+CR3 = 0003000
+TABDLY = 0014000
+TAB0 = 0
+TAB1 = 0004000
+TAB2 = 0010000
+TAB3 = 0014000
+BSDLY = 0020000
+BS0 = 0
+BS1 = 0020000
+VTDLY = 0040000
+VT0 = 0
+VT1 = 0040000
+FFDLY = 0100000
+FF0 = 0
+FF1 = 0100000
+CBAUD = 0000017
+B0 = 0
+B50 = 0000001
+B75 = 0000002
+B110 = 0000003
+B134 = 0000004
+B150 = 0000005
+B200 = 0000006
+B300 = 0000007
+B600 = 0000010
+B1200 = 0000011
+B1800 = 0000012
+B2400 = 0000013
+B4800 = 0000014
+B9600 = 0000015
+B19200 = 0000016
+EXTA = 0000016
+B38400 = 0000017
+EXTB = 0000017
+CSIZE = 0000060
+CS5 = 0
+CS6 = 0000020
+CS7 = 0000040
+CS8 = 0000060
+CSTOPB = 0000100
+CREAD = 0000200
+PARENB = 0000400
+PARODD = 0001000
+HUPCL = 0002000
+CLOCAL = 0004000
+LOBLK = 0040000
+ISIG = 0000001
+ICANON = 0000002
+XCASE = 0000004
+ECHO = 0000010
+ECHOE = 0000020
+ECHOK = 0000040
+ECHONL = 0000100
+NOFLSH = 0000200
+IIEXTEN = 0000400
+ITOSTOP = 0001000
+SSPEED = B9600
+IOCTYPE = 0xff00
+TIOC = (ord('T')<<8)
+oTCGETA = (TIOC|1)
+oTCSETA = (TIOC|2)
+oTCSETAW = (TIOC|3)
+oTCSETAF = (TIOC|4)
+TCSBRK = (TIOC|5)
+TCXONC = (TIOC|6)
+TCFLSH = (TIOC|7)
+TCGETA = (TIOC|8)
+TCSETA = (TIOC|9)
+TCSETAW = (TIOC|10)
+TCSETAF = (TIOC|11)
+TIOCFLUSH = (TIOC|12)
+TCDSET = (TIOC|32)
+TCBLKMD = (TIOC|33)
+TIOCPKT = (TIOC|112)
+TIOCPKT_DATA = 0x00
+TIOCPKT_FLUSHREAD = 0x01
+TIOCPKT_FLUSHWRITE = 0x02
+TIOCPKT_NOSTOP = 0x10
+TIOCPKT_DOSTOP = 0x20
+TIOCNOTTY = (TIOC|113)
+TIOCSTI = (TIOC|114)
+TIOCSPGRP = _IOW(ord('t'), 118, int)
+TIOCGPGRP = _IOR(ord('t'), 119, int)
+TIOCCONS = _IOW(ord('t'), 120, int)
+struct_winsize = 'hhhh'
+TIOCGWINSZ = _IOR(ord('t'), 104, struct_winsize)
+TIOCSWINSZ = _IOW(ord('t'), 103, struct_winsize)
+TFIOC = (ord('F')<<8)
+oFIONREAD = (TFIOC|127)
+LDIOC = (ord('D')<<8)
+LDOPEN = (LDIOC|0)
+LDCLOSE = (LDIOC|1)
+LDCHG = (LDIOC|2)
+LDGETT = (LDIOC|8)
+LDSETT = (LDIOC|9)
+TERM_NONE = 0
+TERM_TEC = 1
+TERM_V61 = 2
+TERM_V10 = 3
+TERM_TEX = 4
+TERM_D40 = 5
+TERM_H45 = 6
+TERM_D42 = 7
+TM_NONE = 0000
+TM_SNL = 0001
+TM_ANL = 0002
+TM_LCF = 0004
+TM_CECHO = 0010
+TM_CINVIS = 0020
+TM_SET = 0200
+LDISC0 = 0
+LDISC1 = 1
+NTTYDISC = LDISC1
+VSUSP = VSWTCH
+TCSANOW = 0
+TCSADRAIN = 1
+TCSAFLUSH = 2
+TCIFLUSH = 0
+TCOFLUSH = 1
+TCIOFLUSH = 2
+TCOOFF = 0
+TCOON = 1
+TCIOFF = 2
+TCION = 3
+TO_STOP = LOBLK
+IEXTEN = IIEXTEN
+TOSTOP = ITOSTOP


Property changes on: vendor/Python/current/Lib/plat-irix5/IOCTL.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/plat-irix5/SV.py
===================================================================
--- vendor/Python/current/Lib/plat-irix5/SV.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix5/SV.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,120 @@
+NTSC_XMAX = 640
+NTSC_YMAX = 480
+PAL_XMAX = 768
+PAL_YMAX = 576
+BLANKING_BUFFER_SIZE = 2
+
+MAX_SOURCES = 2
+
+# mode parameter for Bind calls
+IN_OFF = 0                              # No Video
+IN_OVER = 1                             # Video over graphics
+IN_UNDER = 2                            # Video under graphics
+IN_REPLACE = 3                          # Video replaces entire win
+
+# mode parameters for LoadMap calls.  Specifies buffer, always 256 entries
+INPUT_COLORMAP = 0                      # tuples of 8-bit RGB
+CHROMA_KEY_MAP = 1                      # tuples of 8-bit RGB
+COLOR_SPACE_MAP = 2                     # tuples of 8-bit RGB
+GAMMA_MAP = 3                           # tuples of 24-bit red values
+
+# mode parameters for UseExclusive calls
+INPUT = 0
+OUTPUT = 1
+IN_OUT = 2
+
+# Format constants for the capture routines
+RGB8_FRAMES = 0                         # noninterleaved 8 bit 3:2:3 RBG fields
+RGB32_FRAMES = 1                        # 32-bit 8:8:8 RGB frames
+YUV411_FRAMES = 2                       # interleaved, 8:2:2 YUV format
+YUV411_FRAMES_AND_BLANKING_BUFFER = 3
+
+#
+# sv.SetParam is passed variable length argument lists,
+# consisting of <name, value> pairs.   The following
+# constants identify argument names.
+#
+_NAME_BASE = 1000
+SOURCE = (_NAME_BASE + 0)
+SOURCE1 = 0
+SOURCE2 = 1
+SOURCE3 = 2
+COLOR = (_NAME_BASE + 1)
+DEFAULT_COLOR = 0
+USER_COLOR = 1
+MONO = 2
+OUTPUTMODE = (_NAME_BASE + 2)
+LIVE_OUTPUT = 0
+STILL24_OUT = 1
+FREEZE = (_NAME_BASE + 3)
+DITHER = (_NAME_BASE + 4)
+OUTPUT_FILTER = (_NAME_BASE + 5)
+HUE = (_NAME_BASE + 6)
+GENLOCK = (_NAME_BASE + 7)
+GENLOCK_OFF = 0
+GENLOCK_ON = 1
+GENLOCK_HOUSE = 2
+BROADCAST = (_NAME_BASE + 8)
+NTSC = 0
+PAL = 1
+VIDEO_MODE = (_NAME_BASE + 9)
+COMP = 0
+SVIDEO = 1
+INPUT_BYPASS = (_NAME_BASE + 10)
+FIELDDROP = (_NAME_BASE + 11)
+SLAVE = (_NAME_BASE + 12)
+APERTURE_FACTOR = (_NAME_BASE + 13)
+AFACTOR_0 = 0
+AFACTOR_QTR = 1
+AFACTOR_HLF = 2
+AFACTOR_ONE = 3
+CORING = (_NAME_BASE + 14)
+COR_OFF = 0
+COR_1LSB = 1
+COR_2LSB = 2
+COR_3LSB = 3
+APERTURE_BANDPASS = (_NAME_BASE + 15)
+ABAND_F0 = 0
+ABAND_F1 = 1
+ABAND_F2 = 2
+ABAND_F3 = 3
+PREFILTER = (_NAME_BASE + 16)
+CHROMA_TRAP = (_NAME_BASE + 17)
+CK_THRESHOLD = (_NAME_BASE + 18)
+PAL_SENSITIVITY = (_NAME_BASE + 19)
+GAIN_CONTROL = (_NAME_BASE + 20)
+GAIN_SLOW = 0
+GAIN_MEDIUM = 1
+GAIN_FAST = 2
+GAIN_FROZEN = 3
+AUTO_CKILL = (_NAME_BASE + 21)
+VTR_MODE = (_NAME_BASE + 22)
+VTR_INPUT = 0
+CAMERA_INPUT = 1
+LUMA_DELAY = (_NAME_BASE + 23)
+VNOISE = (_NAME_BASE + 24)
+VNOISE_NORMAL = 0
+VNOISE_SEARCH = 1
+VNOISE_AUTO = 2
+VNOISE_BYPASS = 3
+CHCV_PAL = (_NAME_BASE + 25)
+CHCV_NTSC = (_NAME_BASE + 26)
+CCIR_LEVELS = (_NAME_BASE + 27)
+STD_CHROMA = (_NAME_BASE + 28)
+DENC_VTBYPASS = (_NAME_BASE + 29)
+FAST_TIMECONSTANT = (_NAME_BASE + 30)
+GENLOCK_DELAY = (_NAME_BASE + 31)
+PHASE_SYNC = (_NAME_BASE + 32)
+VIDEO_OUTPUT = (_NAME_BASE + 33)
+CHROMA_PHASEOUT = (_NAME_BASE + 34)
+CHROMA_CENTER = (_NAME_BASE + 35)
+YUV_TO_RGB_INVERT = (_NAME_BASE + 36)
+SOURCE1_BROADCAST = (_NAME_BASE + 37)
+SOURCE1_MODE = (_NAME_BASE + 38)
+SOURCE2_BROADCAST = (_NAME_BASE + 39)
+SOURCE2_MODE = (_NAME_BASE + 40)
+SOURCE3_BROADCAST = (_NAME_BASE + 41)
+SOURCE3_MODE = (_NAME_BASE + 42)
+SIGNAL_STD = (_NAME_BASE + 43)
+NOSIGNAL = 2
+SIGNAL_COLOR = (_NAME_BASE + 44)


Property changes on: vendor/Python/current/Lib/plat-irix5/SV.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/plat-irix5/WAIT.py
===================================================================
--- vendor/Python/current/Lib/plat-irix5/WAIT.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix5/WAIT.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,14 @@
+# Generated by h2py from /usr/include/sys/wait.h
+_WSTOPPED = 0177
+WNOHANG = 0100
+WEXITED = 0001
+WTRAPPED = 0002
+WSTOPPED = 0004
+WCONTINUED = 0010
+WNOWAIT = 0200
+WOPTMASK = (WEXITED|WTRAPPED|WSTOPPED|WCONTINUED|WNOHANG|WNOWAIT)
+WSTOPFLG = 0177
+WCONTFLG = 0177777
+WCOREFLAG = 0200
+WSIGMASK = 0177
+WUNTRACED = 0004


Property changes on: vendor/Python/current/Lib/plat-irix5/WAIT.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/plat-irix5/cddb.py
===================================================================
--- vendor/Python/current/Lib/plat-irix5/cddb.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix5/cddb.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,204 @@
+# This file implements a class which forms an interface to the .cddb
+# directory that is maintained by SGI's cdman program.
+#
+# Usage is as follows:
+#
+# import readcd
+# r = readcd.Readcd()
+# c = Cddb(r.gettrackinfo())
+#
+# Now you can use c.artist, c.title and c.track[trackno] (where trackno
+# starts at 1).  When the CD is not recognized, all values will be the empty
+# string.
+# It is also possible to set the above mentioned variables to new values.
+# You can then use c.write() to write out the changed values to the
+# .cdplayerrc file.
+
+import string, posix, os
+
+_cddbrc = '.cddb'
+_DB_ID_NTRACKS = 5
+_dbid_map = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ at _=+abcdefghijklmnopqrstuvwxyz'
+def _dbid(v):
+    if v >= len(_dbid_map):
+        return string.zfill(v, 2)
+    else:
+        return _dbid_map[v]
+
+def tochash(toc):
+    if type(toc) == type(''):
+        tracklist = []
+        for i in range(2, len(toc), 4):
+            tracklist.append((None,
+                      (int(toc[i:i+2]),
+                       int(toc[i+2:i+4]))))
+    else:
+        tracklist = toc
+    ntracks = len(tracklist)
+    hash = _dbid((ntracks >> 4) & 0xF) + _dbid(ntracks & 0xF)
+    if ntracks <= _DB_ID_NTRACKS:
+        nidtracks = ntracks
+    else:
+        nidtracks = _DB_ID_NTRACKS - 1
+        min = 0
+        sec = 0
+        for track in tracklist:
+            start, length = track
+            min = min + length[0]
+            sec = sec + length[1]
+        min = min + sec / 60
+        sec = sec % 60
+        hash = hash + _dbid(min) + _dbid(sec)
+    for i in range(nidtracks):
+        start, length = tracklist[i]
+        hash = hash + _dbid(length[0]) + _dbid(length[1])
+    return hash
+
+class Cddb:
+    def __init__(self, tracklist):
+        if os.environ.has_key('CDDB_PATH'):
+            path = os.environ['CDDB_PATH']
+            cddb_path = path.split(',')
+        else:
+            home = os.environ['HOME']
+            cddb_path = [home + '/' + _cddbrc]
+
+        self._get_id(tracklist)
+
+        for dir in cddb_path:
+            file = dir + '/' + self.id + '.rdb'
+            try:
+                f = open(file, 'r')
+                self.file = file
+                break
+            except IOError:
+                pass
+        ntracks = int(self.id[:2], 16)
+        self.artist = ''
+        self.title = ''
+        self.track = [None] + [''] * ntracks
+        self.trackartist = [None] + [''] * ntracks
+        self.notes = []
+        if not hasattr(self, 'file'):
+            return
+        import re
+        reg = re.compile(r'^([^.]*)\.([^:]*):[\t ]+(.*)')
+        while 1:
+            line = f.readline()
+            if not line:
+                break
+            match = reg.match(line)
+            if not match:
+                print 'syntax error in ' + file
+                continue
+            name1, name2, value = match.group(1, 2, 3)
+            if name1 == 'album':
+                if name2 == 'artist':
+                    self.artist = value
+                elif name2 == 'title':
+                    self.title = value
+                elif name2 == 'toc':
+                    if not self.toc:
+                        self.toc = value
+                    if self.toc != value:
+                        print 'toc\'s don\'t match'
+                elif name2 == 'notes':
+                    self.notes.append(value)
+            elif name1[:5] == 'track':
+                try:
+                    trackno = int(name1[5:])
+                except strings.atoi_error:
+                    print 'syntax error in ' + file
+                    continue
+                if trackno > ntracks:
+                    print 'track number %r in file %r out of range' % (trackno, file)
+                    continue
+                if name2 == 'title':
+                    self.track[trackno] = value
+                elif name2 == 'artist':
+                    self.trackartist[trackno] = value
+        f.close()
+        for i in range(2, len(self.track)):
+            track = self.track[i]
+            # if track title starts with `,', use initial part
+            # of previous track's title
+            if track and track[0] == ',':
+                try:
+                    off = self.track[i - 1].index(',')
+                except ValueError:
+                    pass
+                else:
+                    self.track[i] = self.track[i-1][:off] \
+                                    + track
+
+    def _get_id(self, tracklist):
+        # fill in self.id and self.toc.
+        # if the argument is a string ending in .rdb, the part
+        # upto the suffix is taken as the id.
+        if type(tracklist) == type(''):
+            if tracklist[-4:] == '.rdb':
+                self.id = tracklist[:-4]
+                self.toc = ''
+                return
+            t = []
+            for i in range(2, len(tracklist), 4):
+                t.append((None, \
+                          (int(tracklist[i:i+2]), \
+                           int(tracklist[i+2:i+4]))))
+            tracklist = t
+        ntracks = len(tracklist)
+        self.id = _dbid((ntracks >> 4) & 0xF) + _dbid(ntracks & 0xF)
+        if ntracks <= _DB_ID_NTRACKS:
+            nidtracks = ntracks
+        else:
+            nidtracks = _DB_ID_NTRACKS - 1
+            min = 0
+            sec = 0
+            for track in tracklist:
+                start, length = track
+                min = min + length[0]
+                sec = sec + length[1]
+            min = min + sec / 60
+            sec = sec % 60
+            self.id = self.id + _dbid(min) + _dbid(sec)
+        for i in range(nidtracks):
+            start, length = tracklist[i]
+            self.id = self.id + _dbid(length[0]) + _dbid(length[1])
+        self.toc = string.zfill(ntracks, 2)
+        for track in tracklist:
+            start, length = track
+            self.toc = self.toc + string.zfill(length[0], 2) + \
+                      string.zfill(length[1], 2)
+
+    def write(self):
+        import posixpath
+        if os.environ.has_key('CDDB_WRITE_DIR'):
+            dir = os.environ['CDDB_WRITE_DIR']
+        else:
+            dir = os.environ['HOME'] + '/' + _cddbrc
+        file = dir + '/' + self.id + '.rdb'
+        if posixpath.exists(file):
+            # make backup copy
+            posix.rename(file, file + '~')
+        f = open(file, 'w')
+        f.write('album.title:\t' + self.title + '\n')
+        f.write('album.artist:\t' + self.artist + '\n')
+        f.write('album.toc:\t' + self.toc + '\n')
+        for note in self.notes:
+            f.write('album.notes:\t' + note + '\n')
+        prevpref = None
+        for i in range(1, len(self.track)):
+            if self.trackartist[i]:
+                f.write('track%r.artist:\t%s\n' % (i, self.trackartist[i]))
+            track = self.track[i]
+            try:
+                off = track.index(',')
+            except ValuError:
+                prevpref = None
+            else:
+                if prevpref and track[:off] == prevpref:
+                    track = track[off:]
+                else:
+                    prevpref = track[:off]
+            f.write('track%r.title:\t%s\n' % (i, track))
+        f.close()


Property changes on: vendor/Python/current/Lib/plat-irix5/cddb.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/plat-irix5/cdplayer.py
===================================================================
--- vendor/Python/current/Lib/plat-irix5/cdplayer.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix5/cdplayer.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,88 @@
+# This file implements a class which forms an interface to the .cdplayerrc
+# file that is maintained by SGI's cdplayer program.
+#
+# Usage is as follows:
+#
+# import readcd
+# r = readcd.Readcd()
+# c = Cdplayer(r.gettrackinfo())
+#
+# Now you can use c.artist, c.title and c.track[trackno] (where trackno
+# starts at 1).  When the CD is not recognized, all values will be the empty
+# string.
+# It is also possible to set the above mentioned variables to new values.
+# You can then use c.write() to write out the changed values to the
+# .cdplayerrc file.
+
+cdplayerrc = '.cdplayerrc'
+
+class Cdplayer:
+    def __init__(self, tracklist):
+        import string
+        self.artist = ''
+        self.title = ''
+        if type(tracklist) == type(''):
+            t = []
+            for i in range(2, len(tracklist), 4):
+                t.append((None, \
+                          (string.atoi(tracklist[i:i+2]), \
+                           string.atoi(tracklist[i+2:i+4]))))
+            tracklist = t
+        self.track = [None] + [''] * len(tracklist)
+        self.id = 'd' + string.zfill(len(tracklist), 2)
+        for track in tracklist:
+            start, length = track
+            self.id = self.id + string.zfill(length[0], 2) + \
+                      string.zfill(length[1], 2)
+        try:
+            import posix
+            f = open(posix.environ['HOME'] + '/' + cdplayerrc, 'r')
+        except IOError:
+            return
+        import re
+        reg = re.compile(r'^([^:]*):\t(.*)')
+        s = self.id + '.'
+        l = len(s)
+        while 1:
+            line = f.readline()
+            if line == '':
+                break
+            if line[:l] == s:
+                line = line[l:]
+                match = reg.match(line)
+                if not match:
+                    print 'syntax error in ~/' + cdplayerrc
+                    continue
+                name, value = match.group(1, 2)
+                if name == 'title':
+                    self.title = value
+                elif name == 'artist':
+                    self.artist = value
+                elif name[:5] == 'track':
+                    trackno = string.atoi(name[6:])
+                    self.track[trackno] = value
+        f.close()
+
+    def write(self):
+        import posix
+        filename = posix.environ['HOME'] + '/' + cdplayerrc
+        try:
+            old = open(filename, 'r')
+        except IOError:
+            old = open('/dev/null', 'r')
+        new = open(filename + '.new', 'w')
+        s = self.id + '.'
+        l = len(s)
+        while 1:
+            line = old.readline()
+            if line == '':
+                break
+            if line[:l] != s:
+                new.write(line)
+        new.write(self.id + '.title:\t' + self.title + '\n')
+        new.write(self.id + '.artist:\t' + self.artist + '\n')
+        for i in range(1, len(self.track)):
+            new.write('%s.track.%r:\t%s\n' % (self.id, i, self.track[i]))
+        old.close()
+        new.close()
+        posix.rename(filename + '.new', filename)


Property changes on: vendor/Python/current/Lib/plat-irix5/cdplayer.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/plat-irix5/flp.doc
===================================================================
--- vendor/Python/current/Lib/plat-irix5/flp.doc	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix5/flp.doc	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,117 @@
+.SH
+Module flp
+.LP
+The flp module loads fl-forms from fd files, as generated
+by fdesign. The module is designed to be flexible enough to allow
+almost anything to be done with the loaded form.
+.LP
+Loadform defines 
+two types of functions: functions to parse fd files and functions to
+create the forms from the templates returned by the parse functions.
+There are fairly low-level create functions that create single objects,
+and convenience routines that create complete forms, including callbacks,
+etc.
+.LP
+The exception flp.error is raised whenever an error occurs while parsing a forms
+definition file or creating a form.
+.SH 2
+Parsing functions
+.LP
+There are two parsing functions, parse_form() and parse_forms(). They
+take the following form:
+.LP
+.ft C
+ftuple = parse_form(filename, formname)
+.br
+ftdict = parse_forms(filename)
+.IP
+Parse_form parses a single form, and returns a tuple (ftmp, otmplist).
+Ftmp is a template for a form, otmplist is a list of templates for
+objects. See below for a description of these templates.
+.IP
+Parse_forms parses all forms in an fd file. It returns a dictionary of
+(ftmp, otmplist) tuples, indexed by formname.
+.IP
+Filename is the name of the forms definition file to inspect. The functions
+appends '.fd' if needed, and use 'sys.path' to locate the file.
+.IP
+formname is the name of the form to load. This argument is mandatory,
+even if the file only contains one form.
+.LP
+The form template and object template are structures that contain all
+the information read from the fd file, in 'natural' form. A form
+template record contains the following fields:
+.IP
+.nf
+"Name", the name of the form;
+"Width", the width of the form;
+"Height", the height of the form; and
+"Numberofobjects", the number of objects in the form.
+.LP
+An object template contains the following fields:
+.IP
+.nf
+"Class", the class of object (eg. FL.BUTTON);
+"Type", the sub-class (eg. FL.NORMALBUTTON);
+"Box", a list with four members: [x, y, width, height];
+"Boxtype", the type of box (eg. FL.DOWNBOX);
+"Colors", a list with the two object colors;
+"Alignment", the label alignment (eg. FL.ALIGNLEFT); 
+"Style", the label style (eg. FL.BOLDSTYLE);
+"Lcol", the label color;
+"Label", a string containing the label;
+"Name", a string containing the name of the object;
+"Callback", a string containing the callback routine name; and
+"Argument", a string containing the callback routine extra argument.
+.SH
+Low-level create routines.
+.LP
+The three low-level creation routines are called as follows:
+.LP
+.ft C
+form = create_form(form_template)
+.IP
+Create an fl form from a form template. Returns the form created.
+.LP
+.ft C
+obj = create_object(form, obj_template)
+.IP
+Create an object in an fl form. Return the new object.
+An error is raised if the object has a callback routine.
+.SH
+High-level create routines.
+.LP
+The 'standard' way to handle forms in python is to define a class
+that contains the form and all the objects (insofar as they are named),
+and that defines all the callback functions, and use an instance of
+this class to handle the form interaction.
+Flp contains three routines that simplify handling this paradigm:
+.LP
+.ft C
+create_full_form(instance, ftuple)
+.IP
+This routine takes an instance of your form-handling class and an
+ftuple (as returned by the parsing routines) as parameters. It inserts
+the form into the instance, defines all object names and arranges that
+the callback methods are called. All the names inserted into the
+instance are the same as the names used for the objects, etc. in the
+fd file.
+.LP
+.ft C
+merge_full_form(instance, form, ftuple)
+.IP
+This function does the same as create_full_form, only it does not create
+the form itself nor the 'background box' that fdesign automatically
+adds to each form. This is useful if your class inherits a superclass
+that already defines a skeleton form (with 'OK' and 'Cancel' buttons,
+for instance), and you want to merge the new form into that existing
+form. The 'form' parameter is the form to which the new objects are
+added.
+.LP
+If you use the paradigm sketched here but need slightly more control
+over object creation there is a routine that creates a single object
+and inserts its name (and arranges for the callback routine to be
+called):
+.LP
+.ft C
+create_object_instance(instance, form, obj_template)


Property changes on: vendor/Python/current/Lib/plat-irix5/flp.doc
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/plat-irix5/flp.py
===================================================================
--- vendor/Python/current/Lib/plat-irix5/flp.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix5/flp.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,451 @@
+#
+# flp - Module to load fl forms from fd files
+#
+# Jack Jansen, December 1991
+#
+import string
+import os
+import sys
+import FL
+
+SPLITLINE = '--------------------'
+FORMLINE = '=============== FORM ==============='
+ENDLINE = '=============================='
+
+class error(Exception):
+    pass
+
+##################################################################
+#    Part 1 - The parsing routines                               #
+##################################################################
+
+#
+# Externally visible function. Load form.
+#
+def parse_form(filename, formname):
+    forms = checkcache(filename)
+    if forms is None:
+        forms = parse_forms(filename)
+    if forms.has_key(formname):
+        return forms[formname]
+    else:
+        raise error, 'No such form in fd file'
+
+#
+# Externally visible function. Load all forms.
+#
+def parse_forms(filename):
+    forms = checkcache(filename)
+    if forms is not None: return forms
+    fp = _open_formfile(filename)
+    nforms = _parse_fd_header(fp)
+    forms = {}
+    for i in range(nforms):
+        form = _parse_fd_form(fp, None)
+        forms[form[0].Name] = form
+    writecache(filename, forms)
+    return forms
+
+#
+# Internal: see if a cached version of the file exists
+#
+MAGIC = '.fdc'
+_internal_cache = {}                    # Used by frozen scripts only
+def checkcache(filename):
+    if _internal_cache.has_key(filename):
+        altforms = _internal_cache[filename]
+        return _unpack_cache(altforms)
+    import marshal
+    fp, filename = _open_formfile2(filename)
+    fp.close()
+    cachename = filename + 'c'
+    try:
+        fp = open(cachename, 'r')
+    except IOError:
+        #print 'flp: no cache file', cachename
+        return None
+    try:
+        if fp.read(4) != MAGIC:
+            print 'flp: bad magic word in cache file', cachename
+            return None
+        cache_mtime = rdlong(fp)
+        file_mtime = getmtime(filename)
+        if cache_mtime != file_mtime:
+            #print 'flp: outdated cache file', cachename
+            return None
+        #print 'flp: valid cache file', cachename
+        altforms = marshal.load(fp)
+        return _unpack_cache(altforms)
+    finally:
+        fp.close()
+
+def _unpack_cache(altforms):
+    forms = {}
+    for name in altforms.keys():
+        altobj, altlist = altforms[name]
+        obj = _newobj()
+        obj.make(altobj)
+        list = []
+        for altobj in altlist:
+            nobj = _newobj()
+            nobj.make(altobj)
+            list.append(nobj)
+        forms[name] = obj, list
+    return forms
+
+def rdlong(fp):
+    s = fp.read(4)
+    if len(s) != 4: return None
+    a, b, c, d = s[0], s[1], s[2], s[3]
+    return ord(a)<<24 | ord(b)<<16 | ord(c)<<8 | ord(d)
+
+def wrlong(fp, x):
+    a, b, c, d = (x>>24)&0xff, (x>>16)&0xff, (x>>8)&0xff, x&0xff
+    fp.write(chr(a) + chr(b) + chr(c) + chr(d))
+
+def getmtime(filename):
+    import os
+    from stat import ST_MTIME
+    try:
+        return os.stat(filename)[ST_MTIME]
+    except os.error:
+        return None
+
+#
+# Internal: write cached version of the form (parsing is too slow!)
+#
+def writecache(filename, forms):
+    import marshal
+    fp, filename = _open_formfile2(filename)
+    fp.close()
+    cachename = filename + 'c'
+    try:
+        fp = open(cachename, 'w')
+    except IOError:
+        print 'flp: can\'t create cache file', cachename
+        return # Never mind
+    fp.write('\0\0\0\0') # Seek back and write MAGIC when done
+    wrlong(fp, getmtime(filename))
+    altforms = _pack_cache(forms)
+    marshal.dump(altforms, fp)
+    fp.seek(0)
+    fp.write(MAGIC)
+    fp.close()
+    #print 'flp: wrote cache file', cachename
+
+#
+# External: print some statements that set up the internal cache.
+# This is for use with the "freeze" script.  You should call
+# flp.freeze(filename) for all forms used by the script, and collect
+# the output on a file in a module file named "frozenforms.py".  Then
+# in the main program of the script import frozenforms.
+# (Don't forget to take this out when using the unfrozen version of
+# the script!)
+#
+def freeze(filename):
+    forms = parse_forms(filename)
+    altforms = _pack_cache(forms)
+    print 'import flp'
+    print 'flp._internal_cache[', repr(filename), '] =', altforms
+
+#
+# Internal: create the data structure to be placed in the cache
+#
+def _pack_cache(forms):
+    altforms = {}
+    for name in forms.keys():
+        obj, list = forms[name]
+        altobj = obj.__dict__
+        altlist = []
+        for obj in list: altlist.append(obj.__dict__)
+        altforms[name] = altobj, altlist
+    return altforms
+
+#
+# Internal: Locate form file (using PYTHONPATH) and open file
+#
+def _open_formfile(filename):
+    return _open_formfile2(filename)[0]
+
+def _open_formfile2(filename):
+    if filename[-3:] != '.fd':
+        filename = filename + '.fd'
+    if filename[0] == '/':
+        try:
+            fp = open(filename,'r')
+        except IOError:
+            fp = None
+    else:
+        for pc in sys.path:
+            pn = os.path.join(pc, filename)
+            try:
+                fp = open(pn, 'r')
+                filename = pn
+                break
+            except IOError:
+                fp = None
+    if fp is None:
+        raise error, 'Cannot find forms file ' + filename
+    return fp, filename
+
+#
+# Internal: parse the fd file header, return number of forms
+#
+def _parse_fd_header(file):
+    # First read the magic header line
+    datum = _parse_1_line(file)
+    if datum != ('Magic', 12321):
+        raise error, 'Not a forms definition file'
+    # Now skip until we know number of forms
+    while 1:
+        datum = _parse_1_line(file)
+        if type(datum) == type(()) and datum[0] == 'Numberofforms':
+            break
+    return datum[1]
+#
+# Internal: parse fd form, or skip if name doesn't match.
+# the special value None means 'always parse it'.
+#
+def _parse_fd_form(file, name):
+    datum = _parse_1_line(file)
+    if datum != FORMLINE:
+        raise error, 'Missing === FORM === line'
+    form = _parse_object(file)
+    if form.Name == name or name is None:
+        objs = []
+        for j in range(form.Numberofobjects):
+            obj = _parse_object(file)
+            objs.append(obj)
+        return (form, objs)
+    else:
+        for j in range(form.Numberofobjects):
+            _skip_object(file)
+    return None
+
+#
+# Internal class: a convenient place to store object info fields
+#
+class _newobj:
+    def add(self, name, value):
+        self.__dict__[name] = value
+    def make(self, dict):
+        for name in dict.keys():
+            self.add(name, dict[name])
+
+#
+# Internal parsing routines.
+#
+def _parse_string(str):
+    if '\\' in str:
+        s = '\'' + str + '\''
+        try:
+            return eval(s)
+        except:
+            pass
+    return str
+
+def _parse_num(str):
+    return eval(str)
+
+def _parse_numlist(str):
+    slist = string.split(str)
+    nlist = []
+    for i in slist:
+        nlist.append(_parse_num(i))
+    return nlist
+
+# This dictionary maps item names to parsing routines.
+# If no routine is given '_parse_num' is default.
+_parse_func = { \
+        'Name':         _parse_string, \
+        'Box':          _parse_numlist, \
+        'Colors':       _parse_numlist, \
+        'Label':        _parse_string, \
+        'Name':         _parse_string, \
+        'Callback':     _parse_string, \
+        'Argument':     _parse_string }
+
+# This function parses a line, and returns either
+# a string or a tuple (name,value)
+
+import re
+prog = re.compile('^([^:]*): *(.*)')
+
+def _parse_line(line):
+    match = prog.match(line)
+    if not match:
+        return line
+    name, value = match.group(1, 2)
+    if name[0] == 'N':
+        name = string.join(string.split(name),'')
+        name = string.lower(name)
+    name = string.capitalize(name)
+    try:
+        pf = _parse_func[name]
+    except KeyError:
+        pf = _parse_num
+    value = pf(value)
+    return (name, value)
+
+def _readline(file):
+    line = file.readline()
+    if not line:
+        raise EOFError
+    return line[:-1]
+
+def _parse_1_line(file):
+    line = _readline(file)
+    while line == '':
+        line = _readline(file)
+    return _parse_line(line)
+
+def _skip_object(file):
+    line = ''
+    while not line in (SPLITLINE, FORMLINE, ENDLINE):
+        pos = file.tell()
+        line = _readline(file)
+    if line == FORMLINE:
+        file.seek(pos)
+
+def _parse_object(file):
+    obj = _newobj()
+    while 1:
+        pos = file.tell()
+        datum = _parse_1_line(file)
+        if datum in (SPLITLINE, FORMLINE, ENDLINE):
+            if datum == FORMLINE:
+                file.seek(pos)
+            return obj
+        if type(datum) is not type(()) or len(datum) != 2:
+            raise error, 'Parse error, illegal line in object: '+datum
+        obj.add(datum[0], datum[1])
+
+#################################################################
+#   Part 2 - High-level object/form creation routines            #
+#################################################################
+
+#
+# External - Create a form an link to an instance variable.
+#
+def create_full_form(inst, (fdata, odatalist)):
+    form = create_form(fdata)
+    exec 'inst.'+fdata.Name+' = form\n'
+    for odata in odatalist:
+        create_object_instance(inst, form, odata)
+
+#
+# External - Merge a form into an existing form in an instance
+# variable.
+#
+def merge_full_form(inst, form, (fdata, odatalist)):
+    exec 'inst.'+fdata.Name+' = form\n'
+    if odatalist[0].Class != FL.BOX:
+        raise error, 'merge_full_form() expects FL.BOX as first obj'
+    for odata in odatalist[1:]:
+        create_object_instance(inst, form, odata)
+
+
+#################################################################
+#   Part 3 - Low-level object/form creation routines            #
+#################################################################
+
+#
+# External Create_form - Create form from parameters
+#
+def create_form(fdata):
+    import fl
+    return fl.make_form(FL.NO_BOX, fdata.Width, fdata.Height)
+
+#
+# External create_object - Create an object. Make sure there are
+# no callbacks. Returns the object created.
+#
+def create_object(form, odata):
+    obj = _create_object(form, odata)
+    if odata.Callback:
+        raise error, 'Creating free object with callback'
+    return obj
+#
+# External create_object_instance - Create object in an instance.
+#
+def create_object_instance(inst, form, odata):
+    obj = _create_object(form, odata)
+    if odata.Callback:
+        cbfunc = eval('inst.'+odata.Callback)
+        obj.set_call_back(cbfunc, odata.Argument)
+    if odata.Name:
+        exec 'inst.' + odata.Name + ' = obj\n'
+#
+# Internal _create_object: Create the object and fill options
+#
+def _create_object(form, odata):
+    crfunc = _select_crfunc(form, odata.Class)
+    obj = crfunc(odata.Type, odata.Box[0], odata.Box[1], odata.Box[2], \
+            odata.Box[3], odata.Label)
+    if not odata.Class in (FL.BEGIN_GROUP, FL.END_GROUP):
+        obj.boxtype = odata.Boxtype
+        obj.col1 = odata.Colors[0]
+        obj.col2 = odata.Colors[1]
+        obj.align = odata.Alignment
+        obj.lstyle = odata.Style
+        obj.lsize = odata.Size
+        obj.lcol = odata.Lcol
+    return obj
+#
+# Internal crfunc: helper function that returns correct create function
+#
+def _select_crfunc(fm, cl):
+    if cl == FL.BEGIN_GROUP: return fm.bgn_group
+    elif cl == FL.END_GROUP: return fm.end_group
+    elif cl == FL.BITMAP: return fm.add_bitmap
+    elif cl == FL.BOX: return fm.add_box
+    elif cl == FL.BROWSER: return fm.add_browser
+    elif cl == FL.BUTTON: return fm.add_button
+    elif cl == FL.CHART: return fm.add_chart
+    elif cl == FL.CHOICE: return fm.add_choice
+    elif cl == FL.CLOCK: return fm.add_clock
+    elif cl == FL.COUNTER: return fm.add_counter
+    elif cl == FL.DIAL: return fm.add_dial
+    elif cl == FL.FREE: return fm.add_free
+    elif cl == FL.INPUT: return fm.add_input
+    elif cl == FL.LIGHTBUTTON: return fm.add_lightbutton
+    elif cl == FL.MENU: return fm.add_menu
+    elif cl == FL.POSITIONER: return fm.add_positioner
+    elif cl == FL.ROUNDBUTTON: return fm.add_roundbutton
+    elif cl == FL.SLIDER: return fm.add_slider
+    elif cl == FL.VALSLIDER: return fm.add_valslider
+    elif cl == FL.TEXT: return fm.add_text
+    elif cl == FL.TIMER: return fm.add_timer
+    else:
+        raise error, 'Unknown object type: %r' % (cl,)
+
+
+def test():
+    import time
+    t0 = time.time()
+    if len(sys.argv) == 2:
+        forms = parse_forms(sys.argv[1])
+        t1 = time.time()
+        print 'parse time:', 0.001*(t1-t0), 'sec.'
+        keys = forms.keys()
+        keys.sort()
+        for i in keys:
+            _printform(forms[i])
+    elif len(sys.argv) == 3:
+        form = parse_form(sys.argv[1], sys.argv[2])
+        t1 = time.time()
+        print 'parse time:', round(t1-t0, 3), 'sec.'
+        _printform(form)
+    else:
+        print 'Usage: test fdfile [form]'
+
+def _printform(form):
+    f = form[0]
+    objs = form[1]
+    print 'Form ', f.Name, ', size: ', f.Width, f.Height, ' Nobj ', f.Numberofobjects
+    for i in objs:
+        print '  Obj ', i.Name, ' type ', i.Class, i.Type
+        print '    Box ', i.Box, ' btype ', i.Boxtype
+        print '    Label ', i.Label, ' size/style/col/align ', i.Size,i.Style, i.Lcol, i.Alignment
+        print '    cols ', i.Colors
+        print '    cback ', i.Callback, i.Argument


Property changes on: vendor/Python/current/Lib/plat-irix5/flp.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/plat-irix5/jpeg.py
===================================================================
--- vendor/Python/current/Lib/plat-irix5/jpeg.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix5/jpeg.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,111 @@
+# Implement 'jpeg' interface using SGI's compression library
+
+# XXX Options 'smooth' and 'optimize' are ignored.
+
+# XXX It appears that compressing grayscale images doesn't work right;
+# XXX the resulting file causes weirdness.
+
+class error(Exception):
+    pass
+
+options = {'quality': 75, 'optimize': 0, 'smooth': 0, 'forcegray': 0}
+
+comp = None
+decomp = None
+
+def compress(imgdata, width, height, bytesperpixel):
+    global comp
+    import cl
+    if comp is None: comp = cl.OpenCompressor(cl.JPEG)
+    if bytesperpixel == 1:
+        format = cl.GRAYSCALE
+    elif bytesperpixel == 4:
+        format = cl.RGBX
+    if options['forcegray']:
+        iformat = cl.GRAYSCALE
+    else:
+        iformat = cl.YUV
+    # XXX How to support 'optimize'?
+    params = [cl.IMAGE_WIDTH, width, cl.IMAGE_HEIGHT, height, \
+              cl.ORIGINAL_FORMAT, format, \
+              cl.ORIENTATION, cl.BOTTOM_UP, \
+              cl.QUALITY_FACTOR, options['quality'], \
+              cl.INTERNAL_FORMAT, iformat, \
+             ]
+    comp.SetParams(params)
+    jpegdata = comp.Compress(1, imgdata)
+    return jpegdata
+
+def decompress(jpegdata):
+    global decomp
+    import cl
+    if decomp is None: decomp = cl.OpenDecompressor(cl.JPEG)
+    headersize = decomp.ReadHeader(jpegdata)
+    params = [cl.IMAGE_WIDTH, 0, cl.IMAGE_HEIGHT, 0, cl.INTERNAL_FORMAT, 0]
+    decomp.GetParams(params)
+    width, height, format = params[1], params[3], params[5]
+    if format == cl.GRAYSCALE or options['forcegray']:
+        format = cl.GRAYSCALE
+        bytesperpixel = 1
+    else:
+        format = cl.RGBX
+        bytesperpixel = 4
+    # XXX How to support 'smooth'?
+    params = [cl.ORIGINAL_FORMAT, format, \
+              cl.ORIENTATION, cl.BOTTOM_UP, \
+              cl.FRAME_BUFFER_SIZE, width*height*bytesperpixel]
+    decomp.SetParams(params)
+    imgdata = decomp.Decompress(1, jpegdata)
+    return imgdata, width, height, bytesperpixel
+
+def setoption(name, value):
+    if type(value) is not type(0):
+        raise TypeError, 'jpeg.setoption: numeric options only'
+    if name == 'forcegrey':
+        name = 'forcegray'
+    if not options.has_key(name):
+        raise KeyError, 'jpeg.setoption: unknown option name'
+    options[name] = int(value)
+
+def test():
+    import sys
+    if sys.argv[1:2] == ['-g']:
+        del sys.argv[1]
+        setoption('forcegray', 1)
+    if not sys.argv[1:]:
+        sys.argv.append('/usr/local/images/data/jpg/asterix.jpg')
+    for file in sys.argv[1:]:
+        show(file)
+
+def show(file):
+    import gl, GL, DEVICE
+    jpegdata = open(file, 'r').read()
+    imgdata, width, height, bytesperpixel = decompress(jpegdata)
+    gl.foreground()
+    gl.prefsize(width, height)
+    win = gl.winopen(file)
+    if bytesperpixel == 1:
+        gl.cmode()
+        gl.pixmode(GL.PM_SIZE, 8)
+        gl.gconfig()
+        for i in range(256):
+            gl.mapcolor(i, i, i, i)
+    else:
+        gl.RGBmode()
+        gl.pixmode(GL.PM_SIZE, 32)
+        gl.gconfig()
+    gl.qdevice(DEVICE.REDRAW)
+    gl.qdevice(DEVICE.ESCKEY)
+    gl.qdevice(DEVICE.WINQUIT)
+    gl.qdevice(DEVICE.WINSHUT)
+    gl.lrectwrite(0, 0, width-1, height-1, imgdata)
+    while 1:
+        dev, val = gl.qread()
+        if dev in (DEVICE.ESCKEY, DEVICE.WINSHUT, DEVICE.WINQUIT):
+            break
+        if dev == DEVICE.REDRAW:
+            gl.lrectwrite(0, 0, width-1, height-1, imgdata)
+    gl.winclose(win)
+    # Now test the compression and write the result to a fixed filename
+    newjpegdata = compress(imgdata, width, height, bytesperpixel)
+    open('/tmp/j.jpg', 'w').write(newjpegdata)


Property changes on: vendor/Python/current/Lib/plat-irix5/jpeg.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/plat-irix5/panel.py
===================================================================
--- vendor/Python/current/Lib/plat-irix5/panel.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix5/panel.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,281 @@
+# Module 'panel'
+#
+# Support for the Panel library.
+# Uses built-in module 'pnl'.
+# Applications should use 'panel.function' instead of 'pnl.function';
+# most 'pnl' functions are transparently exported by 'panel',
+# but dopanel() is overridden and you have to use this version
+# if you want to use callbacks.
+
+
+import pnl
+
+
+debug = 0
+
+
+# Test if an object is a list.
+#
+def is_list(x):
+    return type(x) == type([])
+
+
+# Reverse a list.
+#
+def reverse(list):
+    res = []
+    for item in list:
+        res.insert(0, item)
+    return res
+
+
+# Get an attribute of a list, which may itself be another list.
+# Don't use 'prop' for name.
+#
+def getattrlist(list, name):
+    for item in list:
+        if item and is_list(item) and item[0] == name:
+            return item[1:]
+    return []
+
+
+# Get a property of a list, which may itself be another list.
+#
+def getproplist(list, name):
+    for item in list:
+        if item and is_list(item) and item[0] == 'prop':
+            if len(item) > 1 and item[1] == name:
+                return item[2:]
+    return []
+
+
+# Test if an actuator description contains the property 'end-of-group'
+#
+def is_endgroup(list):
+    x = getproplist(list, 'end-of-group')
+    return (x and x[0] == '#t')
+
+
+# Neatly display an actuator definition given as S-expression
+# the prefix string is printed before each line.
+#
+def show_actuator(prefix, a):
+    for item in a:
+        if not is_list(item):
+            print prefix, item
+        elif item and item[0] == 'al':
+            print prefix, 'Subactuator list:'
+            for a in item[1:]:
+                show_actuator(prefix + '    ', a)
+        elif len(item) == 2:
+            print prefix, item[0], '=>', item[1]
+        elif len(item) == 3 and item[0] == 'prop':
+            print prefix, 'Prop', item[1], '=>',
+            print item[2]
+        else:
+            print prefix, '?', item
+
+
+# Neatly display a panel.
+#
+def show_panel(prefix, p):
+    for item in p:
+        if not is_list(item):
+            print prefix, item
+        elif item and item[0] == 'al':
+            print prefix, 'Actuator list:'
+            for a in item[1:]:
+                show_actuator(prefix + '    ', a)
+        elif len(item) == 2:
+            print prefix, item[0], '=>', item[1]
+        elif len(item) == 3 and item[0] == 'prop':
+            print prefix, 'Prop', item[1], '=>',
+            print item[2]
+        else:
+            print prefix, '?', item
+
+
+# Exception raised by build_actuator or build_panel.
+#
+panel_error = 'panel error'
+
+
+# Dummy callback used to initialize the callbacks.
+#
+def dummy_callback(arg):
+    pass
+
+
+# Assign attributes to members of the target.
+# Attribute names in exclist are ignored.
+# The member name is the attribute name prefixed with the prefix.
+#
+def assign_members(target, attrlist, exclist, prefix):
+    for item in attrlist:
+        if is_list(item) and len(item) == 2 and item[0] not in exclist:
+            name, value = item[0], item[1]
+            ok = 1
+            if value[0] in '-0123456789':
+                value = eval(value)
+            elif value[0] == '"':
+                value = value[1:-1]
+            elif value == 'move-then-resize':
+                # Strange default set by Panel Editor...
+                ok = 0
+            else:
+                print 'unknown value', value, 'for', name
+                ok = 0
+            if ok:
+                lhs = 'target.' + prefix + name
+                stmt = lhs + '=' + repr(value)
+                if debug: print 'exec', stmt
+                try:
+                    exec stmt + '\n'
+                except KeyboardInterrupt: # Don't catch this!
+                    raise KeyboardInterrupt
+                except:
+                    print 'assign failed:', stmt
+
+
+# Build a real actuator from an actuator description.
+# Return a pair (actuator, name).
+#
+def build_actuator(descr):
+    namelist = getattrlist(descr, 'name')
+    if namelist:
+        # Assume it is a string
+        actuatorname = namelist[0][1:-1]
+    else:
+        actuatorname = ''
+    type = descr[0]
+    if type[:4] == 'pnl_': type = type[4:]
+    act = pnl.mkact(type)
+    act.downfunc = act.activefunc = act.upfunc = dummy_callback
+    #
+    assign_members(act, descr[1:], ['al', 'data', 'name'], '')
+    #
+    # Treat actuator-specific data
+    #
+    datalist = getattrlist(descr, 'data')
+    prefix = ''
+    if type[-4:] == 'puck':
+        prefix = 'puck_'
+    elif type == 'mouse':
+        prefix = 'mouse_'
+    assign_members(act, datalist, [], prefix)
+    #
+    return act, actuatorname
+
+
+# Build all sub-actuators and add them to the super-actuator.
+# The super-actuator must already have been added to the panel.
+# Sub-actuators with defined names are added as members to the panel
+# so they can be referenced as p.name.
+#
+# Note: I have no idea how panel.endgroup() works when applied
+# to a sub-actuator.
+#
+def build_subactuators(panel, super_act, al):
+    #
+    # This is nearly the same loop as below in build_panel(),
+    # except a call is made to addsubact() instead of addact().
+    #
+    for a in al:
+        act, name = build_actuator(a)
+        act.addsubact(super_act)
+        if name:
+            stmt = 'panel.' + name + ' = act'
+            if debug: print 'exec', stmt
+            exec stmt + '\n'
+        if is_endgroup(a):
+            panel.endgroup()
+        sub_al = getattrlist(a, 'al')
+        if sub_al:
+            build_subactuators(panel, act, sub_al)
+    #
+    # Fix the actuator to which whe just added subactuators.
+    # This can't hurt (I hope) and is needed for the scroll actuator.
+    #
+    super_act.fixact()
+
+
+# Build a real panel from a panel definition.
+# Return a panel object p, where for each named actuator a, p.name is a
+# reference to a.
+#
+def build_panel(descr):
+    #
+    # Sanity check
+    #
+    if (not descr) or descr[0] != 'panel':
+        raise panel_error, 'panel description must start with "panel"'
+    #
+    if debug: show_panel('', descr)
+    #
+    # Create an empty panel
+    #
+    panel = pnl.mkpanel()
+    #
+    # Assign panel attributes
+    #
+    assign_members(panel, descr[1:], ['al'], '')
+    #
+    # Look for actuator list
+    #
+    al = getattrlist(descr, 'al')
+    #
+    # The order in which actuators are created is important
+    # because of the endgroup() operator.
+    # Unfortunately the Panel Editor outputs the actuator list
+    # in reverse order, so we reverse it here.
+    #
+    al = reverse(al)
+    #
+    for a in al:
+        act, name = build_actuator(a)
+        act.addact(panel)
+        if name:
+            stmt = 'panel.' + name + ' = act'
+            exec stmt + '\n'
+        if is_endgroup(a):
+            panel.endgroup()
+        sub_al = getattrlist(a, 'al')
+        if sub_al:
+            build_subactuators(panel, act, sub_al)
+    #
+    return panel
+
+
+# Wrapper around pnl.dopanel() which calls call-back functions.
+#
+def my_dopanel():
+    # Extract only the first 4 elements to allow for future expansion
+    a, down, active, up = pnl.dopanel()[:4]
+    if down:
+        down.downfunc(down)
+    if active:
+        active.activefunc(active)
+    if up:
+        up.upfunc(up)
+    return a
+
+
+# Create one or more panels from a description file (S-expressions)
+# generated by the Panel Editor.
+#
+def defpanellist(file):
+    import panelparser
+    descrlist = panelparser.parse_file(open(file, 'r'))
+    panellist = []
+    for descr in descrlist:
+        panellist.append(build_panel(descr))
+    return panellist
+
+
+# Import everything from built-in method pnl, so the user can always
+# use panel.foo() instead of pnl.foo().
+# This gives *no* performance penalty once this module is imported.
+#
+from pnl import *                       # for export
+
+dopanel = my_dopanel                    # override pnl.dopanel


Property changes on: vendor/Python/current/Lib/plat-irix5/panel.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/plat-irix5/panelparser.py
===================================================================
--- vendor/Python/current/Lib/plat-irix5/panelparser.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix5/panelparser.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,128 @@
+# Module 'parser'
+#
+# Parse S-expressions output by the Panel Editor
+# (which is written in Scheme so it can't help writing S-expressions).
+#
+# See notes at end of file.
+
+
+whitespace = ' \t\n'
+operators = '()\''
+separators = operators + whitespace + ';' + '"'
+
+
+# Tokenize a string.
+# Return a list of tokens (strings).
+#
+def tokenize_string(s):
+    tokens = []
+    while s:
+        c = s[:1]
+        if c in whitespace:
+            s = s[1:]
+        elif c == ';':
+            s = ''
+        elif c == '"':
+            n = len(s)
+            i = 1
+            while i < n:
+                c = s[i]
+                i = i+1
+                if c == '"': break
+                if c == '\\': i = i+1
+            tokens.append(s[:i])
+            s = s[i:]
+        elif c in operators:
+            tokens.append(c)
+            s = s[1:]
+        else:
+            n = len(s)
+            i = 1
+            while i < n:
+                if s[i] in separators: break
+                i = i+1
+            tokens.append(s[:i])
+            s = s[i:]
+    return tokens
+
+
+# Tokenize a whole file (given as file object, not as file name).
+# Return a list of tokens (strings).
+#
+def tokenize_file(fp):
+    tokens = []
+    while 1:
+        line = fp.readline()
+        if not line: break
+        tokens = tokens + tokenize_string(line)
+    return tokens
+
+
+# Exception raised by parse_exr.
+#
+syntax_error = 'syntax error'
+
+
+# Parse an S-expression.
+# Input is a list of tokens as returned by tokenize_*().
+# Return a pair (expr, tokens)
+# where expr is a list representing the s-expression,
+# and tokens contains the remaining tokens.
+# May raise syntax_error.
+#
+def parse_expr(tokens):
+    if (not tokens) or tokens[0] != '(':
+        raise syntax_error, 'expected "("'
+    tokens = tokens[1:]
+    expr = []
+    while 1:
+        if not tokens:
+            raise syntax_error, 'missing ")"'
+        if tokens[0] == ')':
+            return expr, tokens[1:]
+        elif tokens[0] == '(':
+            subexpr, tokens = parse_expr(tokens)
+            expr.append(subexpr)
+        else:
+            expr.append(tokens[0])
+            tokens = tokens[1:]
+
+
+# Parse a file (given as file object, not as file name).
+# Return a list of parsed S-expressions found at the top level.
+#
+def parse_file(fp):
+    tokens = tokenize_file(fp)
+    exprlist = []
+    while tokens:
+        expr, tokens = parse_expr(tokens)
+        exprlist.append(expr)
+    return exprlist
+
+
+# EXAMPLE:
+#
+# The input
+#       '(hip (hop hur-ray))'
+#
+# passed to tokenize_string() returns the token list
+#       ['(', 'hip', '(', 'hop', 'hur-ray', ')', ')']
+#
+# When this is passed to parse_expr() it returns the expression
+#       ['hip', ['hop', 'hur-ray']]
+# plus an empty token list (because there are no tokens left.
+#
+# When a file containing the example is passed to parse_file() it returns
+# a list whose only element is the output of parse_expr() above:
+#       [['hip', ['hop', 'hur-ray']]]
+
+
+# TOKENIZING:
+#
+# Comments start with semicolon (;) and continue till the end of the line.
+#
+# Tokens are separated by whitespace, except the following characters
+# always form a separate token (outside strings):
+#       ( ) '
+# Strings are enclosed in double quotes (") and backslash (\) is used
+# as escape character in strings.


Property changes on: vendor/Python/current/Lib/plat-irix5/panelparser.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/plat-irix5/readcd.doc
===================================================================
--- vendor/Python/current/Lib/plat-irix5/readcd.doc	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix5/readcd.doc	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,104 @@
+Interface to CD-ROM player.
+
+This module implements an interface to the built-in cd module.  The
+intention is to provide a more user-friendly interface than the
+built-in module.
+
+The module defines a class Readcd with several methods.  The
+initialization of the class will try to open the CD player.  This
+means that initialization will fail if the CD player is already in
+use.  A RuntimeError will be raised by the cd module in that case.
+
+The way to work with this module is as follows.  The user specifies
+the parts of the CD that are to be read and he specifies callback
+functions which are to be called by the system.  At some point he can
+tell the system to play.  The specified parts of the CD will then be
+read and the callbacks will be called.
+
+Initialization.
+===============
+
+r = readcd.Readcd([cd-player [, mode]])
+
+The optional arguments are the name of the CD device and the mode.
+When "mode" is not specified, it defaults to 'r' (which is the only
+possible value); when "cd-player" also isn't specified, it defaults
+to "None" which indicates the default CD player.
+
+Methods.
+========
+
+eject() -- Eject the CD from the player.
+
+reset() -- Reset the list of data stretches to be played.
+
+appendtrack(track) -- Append the specified track to the list of music
+stretches.
+
+appendstretch(first, last) -- Append the stretch from "first" to "last"
+to the list of music stretches.  Both "first" and "last" can be in one
+of four forms.  "None": for "first", the beginning of the CD, for
+"last" the end of the CD; a single integer: a track number--playing
+starts at the beginning of the track or ends at the end of the
+specified track; a three-tuple: the absolute time from the start of
+the CD in minutes, seconds, frames; a four-tuple: track number and
+relative time within the track in minutes, seconds, frames.
+
+settracks(tracklist) -- The argument is a list of integers.  The list
+of stretches is set to argument list.  The old list is discarded.
+
+setcallback(type, func, arg) -- Set a callback function for "type".
+The function will be called as func(arg, type, data) where "arg" is
+the third argument of setcallback, "type" is the type of callback,
+"data" is type-dependent data.  See the CDsetcallback(3) manual page
+for more information.  The possible "type" arguments are defined in
+the CD module.
+
+removecallback(type) -- Remove the callback for "type".
+
+gettrackinfo([tracklist]) -- Return a list of tuples.  Each tuple
+consists of start and length information of a track.  The start and
+length information consist of three-tuples with minutes, seconds and
+frames.  The optional tracklist argument gives a list of interesting
+track numbers.  If no tracklist is specified, information about all
+tracks is returned.
+
+getstatus() -- Return the status information of the CD.
+
+play() -- Play the preprogrammed stretches of music from the CD.  When
+nothing was programmed, the whole CD is played.
+
+Specifying stretches.
+=====================
+
+There are three methods available to specify a stretch of music to be
+played.  The easiest way is to use "settracklist(tracklist)" with which
+a list of tracks can be specified.  "settracklist(tracklist)" is
+equivalent to the sequence
+	reset()
+	for track in tracklist:
+		appendtrack(track)
+
+The next method is "appendtrack(track)" with which a whole track can be
+added to the list of music to be played.  "appendtrack(track)" is
+equivalent to "appendstretch(track, track)".
+
+The most complete method is "appendstretch(first, last)".  Using this
+method, it is possible to specify any stretch of music.
+
+When two consecutive tracks are played, it is possible to choose
+whether the pause that may be between the tracks is played as well or
+whether the pause should be skipped.  When the end of a stretch is
+specified using a track number and the next stretch starts at the
+beginning of the following track and that was also specified using the
+track number (that is, both were specified as integers, not as tuples),
+the pause is played.  When either value was specified using absolute
+time or track-relative time (that is, as three-tuple or as
+four-tuple), the pause will not be played.
+
+Errors.
+=======
+
+When an error occurs, an exception will be raised.  Depending on where
+the error occurs, the exception may either be "readcd.Error" or
+"RuntimeError".


Property changes on: vendor/Python/current/Lib/plat-irix5/readcd.doc
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/plat-irix5/readcd.py
===================================================================
--- vendor/Python/current/Lib/plat-irix5/readcd.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix5/readcd.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,244 @@
+# Class interface to the CD module.
+
+import cd, CD
+
+class Error(Exception):
+    pass
+class _Stop(Exception):
+    pass
+
+def _doatime(self, cb_type, data):
+    if ((data[0] * 60) + data[1]) * 75 + data[2] > self.end:
+##              print 'done with list entry', repr(self.listindex)
+        raise _Stop
+    func, arg = self.callbacks[cb_type]
+    if func:
+        func(arg, cb_type, data)
+
+def _dopnum(self, cb_type, data):
+    if data > self.end:
+##              print 'done with list entry', repr(self.listindex)
+        raise _Stop
+    func, arg = self.callbacks[cb_type]
+    if func:
+        func(arg, cb_type, data)
+
+class Readcd:
+    def __init__(self, *arg):
+        if len(arg) == 0:
+            self.player = cd.open()
+        elif len(arg) == 1:
+            self.player = cd.open(arg[0])
+        elif len(arg) == 2:
+            self.player = cd.open(arg[0], arg[1])
+        else:
+            raise Error, 'bad __init__ call'
+        self.list = []
+        self.callbacks = [(None, None)] * 8
+        self.parser = cd.createparser()
+        self.playing = 0
+        self.end = 0
+        self.status = None
+        self.trackinfo = None
+
+    def eject(self):
+        self.player.eject()
+        self.list = []
+        self.end = 0
+        self.listindex = 0
+        self.status = None
+        self.trackinfo = None
+        if self.playing:
+##                      print 'stop playing from eject'
+            raise _Stop
+
+    def pmsf2msf(self, track, min, sec, frame):
+        if not self.status:
+            self.cachestatus()
+        if track < self.status[5] or track > self.status[6]:
+            raise Error, 'track number out of range'
+        if not self.trackinfo:
+            self.cacheinfo()
+        start, total = self.trackinfo[track]
+        start = ((start[0] * 60) + start[1]) * 75 + start[2]
+        total = ((total[0] * 60) + total[1]) * 75 + total[2]
+        block = ((min * 60) + sec) * 75 + frame
+        if block > total:
+            raise Error, 'out of range'
+        block = start + block
+        min, block = divmod(block, 75*60)
+        sec, frame = divmod(block, 75)
+        return min, sec, frame
+
+    def reset(self):
+        self.list = []
+
+    def appendtrack(self, track):
+        self.appendstretch(track, track)
+
+    def appendstretch(self, start, end):
+        if not self.status:
+            self.cachestatus()
+        if not start:
+            start = 1
+        if not end:
+            end = self.status[6]
+        if type(end) == type(0):
+            if end < self.status[5] or end > self.status[6]:
+                raise Error, 'range error'
+        else:
+            l = len(end)
+            if l == 4:
+                prog, min, sec, frame = end
+                if prog < self.status[5] or prog > self.status[6]:
+                    raise Error, 'range error'
+                end = self.pmsf2msf(prog, min, sec, frame)
+            elif l != 3:
+                raise Error, 'syntax error'
+        if type(start) == type(0):
+            if start < self.status[5] or start > self.status[6]:
+                raise Error, 'range error'
+            if len(self.list) > 0:
+                s, e = self.list[-1]
+                if type(e) == type(0):
+                    if start == e+1:
+                        start = s
+                        del self.list[-1]
+        else:
+            l = len(start)
+            if l == 4:
+                prog, min, sec, frame = start
+                if prog < self.status[5] or prog > self.status[6]:
+                    raise Error, 'range error'
+                start = self.pmsf2msf(prog, min, sec, frame)
+            elif l != 3:
+                raise Error, 'syntax error'
+        self.list.append((start, end))
+
+    def settracks(self, list):
+        self.list = []
+        for track in list:
+            self.appendtrack(track)
+
+    def setcallback(self, cb_type, func, arg):
+        if cb_type < 0 or cb_type >= 8:
+            raise Error, 'type out of range'
+        self.callbacks[cb_type] = (func, arg)
+        if self.playing:
+            start, end = self.list[self.listindex]
+            if type(end) == type(0):
+                if cb_type != CD.PNUM:
+                    self.parser.setcallback(cb_type, func, arg)
+            else:
+                if cb_type != CD.ATIME:
+                    self.parser.setcallback(cb_type, func, arg)
+
+    def removecallback(self, cb_type):
+        if cb_type < 0 or cb_type >= 8:
+            raise Error, 'type out of range'
+        self.callbacks[cb_type] = (None, None)
+        if self.playing:
+            start, end = self.list[self.listindex]
+            if type(end) == type(0):
+                if cb_type != CD.PNUM:
+                    self.parser.removecallback(cb_type)
+            else:
+                if cb_type != CD.ATIME:
+                    self.parser.removecallback(cb_type)
+
+    def gettrackinfo(self, *arg):
+        if not self.status:
+            self.cachestatus()
+        if not self.trackinfo:
+            self.cacheinfo()
+        if len(arg) == 0:
+            return self.trackinfo[self.status[5]:self.status[6]+1]
+        result = []
+        for i in arg:
+            if i < self.status[5] or i > self.status[6]:
+                raise Error, 'range error'
+            result.append(self.trackinfo[i])
+        return result
+
+    def cacheinfo(self):
+        if not self.status:
+            self.cachestatus()
+        self.trackinfo = []
+        for i in range(self.status[5]):
+            self.trackinfo.append(None)
+        for i in range(self.status[5], self.status[6]+1):
+            self.trackinfo.append(self.player.gettrackinfo(i))
+
+    def cachestatus(self):
+        self.status = self.player.getstatus()
+        if self.status[0] == CD.NODISC:
+            self.status = None
+            raise Error, 'no disc in player'
+
+    def getstatus(self):
+        return self.player.getstatus()
+
+    def play(self):
+        if not self.status:
+            self.cachestatus()
+        size = self.player.bestreadsize()
+        self.listindex = 0
+        self.playing = 0
+        for i in range(8):
+            func, arg = self.callbacks[i]
+            if func:
+                self.parser.setcallback(i, func, arg)
+            else:
+                self.parser.removecallback(i)
+        if len(self.list) == 0:
+            for i in range(self.status[5], self.status[6]+1):
+                self.appendtrack(i)
+        try:
+            while 1:
+                if not self.playing:
+                    if self.listindex >= len(self.list):
+                        return
+                    start, end = self.list[self.listindex]
+                    if type(start) == type(0):
+                        dummy = self.player.seektrack(
+                                start)
+                    else:
+                        min, sec, frame = start
+                        dummy = self.player.seek(
+                                min, sec, frame)
+                    if type(end) == type(0):
+                        self.parser.setcallback(
+                                CD.PNUM, _dopnum, self)
+                        self.end = end
+                        func, arg = \
+                              self.callbacks[CD.ATIME]
+                        if func:
+                            self.parser.setcallback(CD.ATIME, func, arg)
+                        else:
+                            self.parser.removecallback(CD.ATIME)
+                    else:
+                        min, sec, frame = end
+                        self.parser.setcallback(
+                                CD.ATIME, _doatime,
+                                self)
+                        self.end = (min * 60 + sec) * \
+                                   75 + frame
+                        func, arg = \
+                              self.callbacks[CD.PNUM]
+                        if func:
+                            self.parser.setcallback(CD.PNUM, func, arg)
+                        else:
+                            self.parser.removecallback(CD.PNUM)
+                    self.playing = 1
+                data = self.player.readda(size)
+                if data == '':
+                    self.playing = 0
+                    self.listindex = self.listindex + 1
+                    continue
+                try:
+                    self.parser.parseframe(data)
+                except _Stop:
+                    self.playing = 0
+                    self.listindex = self.listindex + 1
+        finally:
+            self.playing = 0


Property changes on: vendor/Python/current/Lib/plat-irix5/readcd.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/plat-irix5/regen
===================================================================
--- vendor/Python/current/Lib/plat-irix5/regen	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix5/regen	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,10 @@
+#! /bin/sh
+case `uname -sr` in
+'IRIX '[45].*)	;;
+*)	echo Probably not on an IRIX system 1>&2
+	exit 1;;
+esac
+set -v
+h2py /usr/include/sys/file.h
+h2py -i '(u_long)' /usr/include/netinet/in.h
+h2py /usr/include/errno.h


Property changes on: vendor/Python/current/Lib/plat-irix5/regen
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/plat-irix5/torgb.py
===================================================================
--- vendor/Python/current/Lib/plat-irix5/torgb.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix5/torgb.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,99 @@
+# Convert "arbitrary" image files to rgb files (SGI's image format).
+# Input may be compressed.
+# The uncompressed file type may be PBM, PGM, PPM, GIF, TIFF, or Sun raster.
+# An exception is raised if the file is not of a recognized type.
+# Returned filename is either the input filename or a temporary filename;
+# in the latter case the caller must ensure that it is removed.
+# Other temporary files used are removed by the function.
+
+import os
+import tempfile
+import pipes
+import imghdr
+
+table = {}
+
+t = pipes.Template()
+t.append('fromppm $IN $OUT', 'ff')
+table['ppm'] = t
+
+t = pipes.Template()
+t.append('(PATH=$PATH:/ufs/guido/bin/sgi; exec pnmtoppm)', '--')
+t.append('fromppm $IN $OUT', 'ff')
+table['pnm'] = t
+table['pgm'] = t
+table['pbm'] = t
+
+t = pipes.Template()
+t.append('fromgif $IN $OUT', 'ff')
+table['gif'] = t
+
+t = pipes.Template()
+t.append('tifftopnm', '--')
+t.append('(PATH=$PATH:/ufs/guido/bin/sgi; exec pnmtoppm)', '--')
+t.append('fromppm $IN $OUT', 'ff')
+table['tiff'] = t
+
+t = pipes.Template()
+t.append('rasttopnm', '--')
+t.append('(PATH=$PATH:/ufs/guido/bin/sgi; exec pnmtoppm)', '--')
+t.append('fromppm $IN $OUT', 'ff')
+table['rast'] = t
+
+t = pipes.Template()
+t.append('djpeg', '--')
+t.append('(PATH=$PATH:/ufs/guido/bin/sgi; exec pnmtoppm)', '--')
+t.append('fromppm $IN $OUT', 'ff')
+table['jpeg'] = t
+
+uncompress = pipes.Template()
+uncompress.append('uncompress', '--')
+
+
+class error(Exception):
+    pass
+
+def torgb(filename):
+    temps = []
+    ret = None
+    try:
+        ret = _torgb(filename, temps)
+    finally:
+        for temp in temps[:]:
+            if temp != ret:
+                try:
+                    os.unlink(temp)
+                except os.error:
+                    pass
+                temps.remove(temp)
+    return ret
+
+def _torgb(filename, temps):
+    if filename[-2:] == '.Z':
+        (fd, fname) = tempfile.mkstemp()
+        os.close(fd)
+        temps.append(fname)
+        sts = uncompress.copy(filename, fname)
+        if sts:
+            raise error, filename + ': uncompress failed'
+    else:
+        fname = filename
+    try:
+        ftype = imghdr.what(fname)
+    except IOError, msg:
+        if type(msg) == type(()) and len(msg) == 2 and \
+                type(msg[0]) == type(0) and type(msg[1]) == type(''):
+            msg = msg[1]
+        if type(msg) is not type(''):
+            msg = repr(msg)
+        raise error, filename + ': ' + msg
+    if ftype == 'rgb':
+        return fname
+    if ftype is None or not table.has_key(ftype):
+        raise error, '%s: unsupported image file type %r' % (filename, ftype)
+    (fd, temp) = tempfile.mkstemp()
+    os.close(fd)
+    sts = table[ftype].copy(fname, temp)
+    if sts:
+        raise error, filename + ': conversion to rgb failed'
+    return temp


Property changes on: vendor/Python/current/Lib/plat-irix5/torgb.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/plat-irix6/AL.py
===================================================================
--- vendor/Python/current/Lib/plat-irix6/AL.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix6/AL.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,61 @@
+RATE_48000      = 48000
+RATE_44100      = 44100
+RATE_32000      = 32000
+RATE_22050      = 22050
+RATE_16000      = 16000
+RATE_11025      = 11025
+RATE_8000       = 8000
+
+SAMPFMT_TWOSCOMP= 1
+SAMPFMT_FLOAT   = 32
+SAMPFMT_DOUBLE  = 64
+
+SAMPLE_8        = 1
+SAMPLE_16       = 2
+        # SAMPLE_24 is the low 24 bits of a long, sign extended to 32 bits
+SAMPLE_24       = 4
+
+MONO            = 1
+STEREO          = 2
+QUADRO          = 4                     # 4CHANNEL is not a legal Python name
+
+INPUT_LINE      = 0
+INPUT_MIC       = 1
+INPUT_DIGITAL   = 2
+
+MONITOR_OFF     = 0
+MONITOR_ON      = 1
+
+ERROR_NUMBER            = 0
+ERROR_TYPE              = 1
+ERROR_LOCATION_LSP      = 2
+ERROR_LOCATION_MSP      = 3
+ERROR_LENGTH            = 4
+
+ERROR_INPUT_UNDERFLOW   = 0
+ERROR_OUTPUT_OVERFLOW   = 1
+
+# These seem to be not supported anymore:
+##HOLD, RELEASE                 = 0, 1
+##ATTAIL, ATHEAD, ATMARK, ATTIME        = 0, 1, 2, 3
+
+DEFAULT_DEVICE  = 1
+
+INPUT_SOURCE            = 0
+LEFT_INPUT_ATTEN        = 1
+RIGHT_INPUT_ATTEN       = 2
+INPUT_RATE              = 3
+OUTPUT_RATE             = 4
+LEFT_SPEAKER_GAIN       = 5
+RIGHT_SPEAKER_GAIN      = 6
+INPUT_COUNT             = 7
+OUTPUT_COUNT            = 8
+UNUSED_COUNT            = 9
+SYNC_INPUT_TO_AES       = 10
+SYNC_OUTPUT_TO_AES      = 11
+MONITOR_CTL             = 12
+LEFT_MONITOR_ATTEN      = 13
+RIGHT_MONITOR_ATTEN     = 14
+
+ENUM_VALUE      = 0     # only certain values are valid
+RANGE_VALUE     = 1     # any value in range is valid

Added: vendor/Python/current/Lib/plat-irix6/CD.py
===================================================================
--- vendor/Python/current/Lib/plat-irix6/CD.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix6/CD.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,34 @@
+ERROR           = 0
+NODISC          = 1
+READY           = 2
+PLAYING         = 3
+PAUSED          = 4
+STILL           = 5
+
+AUDIO           = 0
+PNUM            = 1
+INDEX           = 2
+PTIME           = 3
+ATIME           = 4
+CATALOG         = 5
+IDENT           = 6
+CONTROL         = 7
+
+CDDA_DATASIZE   = 2352
+
+##CDDA_SUBCODESIZE      = (sizeof(struct subcodeQ))
+##CDDA_BLOCKSIZE        = (sizeof(struct cdframe))
+##CDDA_NUMSAMPLES       = (CDDA_DATASIZE/2)
+##
+##CDQ_PREEMP_MASK       = 0xd
+##CDQ_COPY_MASK = 0xb
+##CDQ_DDATA_MASK        = 0xd
+##CDQ_BROADCAST_MASK    = 0x8
+##CDQ_PREEMPHASIS       = 0x1
+##CDQ_COPY_PERMITTED    = 0x2
+##CDQ_DIGITAL_DATA      = 0x4
+##CDQ_BROADCAST_USE     = 0x8
+##
+##CDQ_MODE1     = 0x1
+##CDQ_MODE2     = 0x2
+##CDQ_MODE3     = 0x3

Added: vendor/Python/current/Lib/plat-irix6/CL.py
===================================================================
--- vendor/Python/current/Lib/plat-irix6/CL.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix6/CL.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,24 @@
+# Backward compatible module CL.
+# All relevant symbols are now defined in the module cl.
+try:
+    from cl import *
+except ImportError:
+    from CL_old import *
+else:
+    del CompressImage
+    del DecompressImage
+    del GetAlgorithmName
+    del OpenCompressor
+    del OpenDecompressor
+    del QueryAlgorithms
+    del QueryMaxHeaderSize
+    del QueryScheme
+    del QuerySchemeFromName
+    del SetDefault
+    del SetMax
+    del SetMin
+    try:
+        del cvt_type
+    except NameError:
+        pass
+    del error

Added: vendor/Python/current/Lib/plat-irix6/DEVICE.py
===================================================================
--- vendor/Python/current/Lib/plat-irix6/DEVICE.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix6/DEVICE.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,400 @@
+NULLDEV = 0
+BUTOFFSET = 1
+VALOFFSET = 256
+PSEUDOFFSET = 512
+BUT2OFFSET = 3840
+TIMOFFSET = 515
+XKBDOFFSET = 143
+BUTCOUNT = 255
+VALCOUNT = 256
+TIMCOUNT = 4
+XKBDCOUNT = 28
+USERBUTOFFSET = 4096
+USERVALOFFSET = 12288
+USERPSEUDOFFSET = 16384
+BUT0 = 1
+BUT1 = 2
+BUT2 = 3
+BUT3 = 4
+BUT4 = 5
+BUT5 = 6
+BUT6 = 7
+BUT7 = 8
+BUT8 = 9
+BUT9 = 10
+BUT10 = 11
+BUT11 = 12
+BUT12 = 13
+BUT13 = 14
+BUT14 = 15
+BUT15 = 16
+BUT16 = 17
+BUT17 = 18
+BUT18 = 19
+BUT19 = 20
+BUT20 = 21
+BUT21 = 22
+BUT22 = 23
+BUT23 = 24
+BUT24 = 25
+BUT25 = 26
+BUT26 = 27
+BUT27 = 28
+BUT28 = 29
+BUT29 = 30
+BUT30 = 31
+BUT31 = 32
+BUT32 = 33
+BUT33 = 34
+BUT34 = 35
+BUT35 = 36
+BUT36 = 37
+BUT37 = 38
+BUT38 = 39
+BUT39 = 40
+BUT40 = 41
+BUT41 = 42
+BUT42 = 43
+BUT43 = 44
+BUT44 = 45
+BUT45 = 46
+BUT46 = 47
+BUT47 = 48
+BUT48 = 49
+BUT49 = 50
+BUT50 = 51
+BUT51 = 52
+BUT52 = 53
+BUT53 = 54
+BUT54 = 55
+BUT55 = 56
+BUT56 = 57
+BUT57 = 58
+BUT58 = 59
+BUT59 = 60
+BUT60 = 61
+BUT61 = 62
+BUT62 = 63
+BUT63 = 64
+BUT64 = 65
+BUT65 = 66
+BUT66 = 67
+BUT67 = 68
+BUT68 = 69
+BUT69 = 70
+BUT70 = 71
+BUT71 = 72
+BUT72 = 73
+BUT73 = 74
+BUT74 = 75
+BUT75 = 76
+BUT76 = 77
+BUT77 = 78
+BUT78 = 79
+BUT79 = 80
+BUT80 = 81
+BUT81 = 82
+BUT82 = 83
+MAXKBDBUT = 83
+BUT100 = 101
+BUT101 = 102
+BUT102 = 103
+BUT103 = 104
+BUT104 = 105
+BUT105 = 106
+BUT106 = 107
+BUT107 = 108
+BUT108 = 109
+BUT109 = 110
+BUT110 = 111
+BUT111 = 112
+BUT112 = 113
+BUT113 = 114
+BUT114 = 115
+BUT115 = 116
+BUT116 = 117
+BUT117 = 118
+BUT118 = 119
+BUT119 = 120
+BUT120 = 121
+BUT121 = 122
+BUT122 = 123
+BUT123 = 124
+BUT124 = 125
+BUT125 = 126
+BUT126 = 127
+BUT127 = 128
+BUT128 = 129
+BUT129 = 130
+BUT130 = 131
+BUT131 = 132
+BUT132 = 133
+BUT133 = 134
+BUT134 = 135
+BUT135 = 136
+BUT136 = 137
+BUT137 = 138
+BUT138 = 139
+BUT139 = 140
+BUT140 = 141
+BUT141 = 142
+BUT142 = 143
+BUT143 = 144
+BUT144 = 145
+BUT145 = 146
+BUT146 = 147
+BUT147 = 148
+BUT148 = 149
+BUT149 = 150
+BUT150 = 151
+BUT151 = 152
+BUT152 = 153
+BUT153 = 154
+BUT154 = 155
+BUT155 = 156
+BUT156 = 157
+BUT157 = 158
+BUT158 = 159
+BUT159 = 160
+BUT160 = 161
+BUT161 = 162
+BUT162 = 163
+BUT163 = 164
+BUT164 = 165
+BUT165 = 166
+BUT166 = 167
+BUT167 = 168
+BUT168 = 169
+BUT181 = 182
+BUT182 = 183
+BUT183 = 184
+BUT184 = 185
+BUT185 = 186
+BUT186 = 187
+BUT187 = 188
+BUT188 = 189
+BUT189 = 190
+MOUSE1 = 101
+MOUSE2 = 102
+MOUSE3 = 103
+LEFTMOUSE = 103
+MIDDLEMOUSE = 102
+RIGHTMOUSE = 101
+LPENBUT = 104
+BPAD0 = 105
+BPAD1 = 106
+BPAD2 = 107
+BPAD3 = 108
+LPENVALID = 109
+SWBASE = 111
+SW0 = 111
+SW1 = 112
+SW2 = 113
+SW3 = 114
+SW4 = 115
+SW5 = 116
+SW6 = 117
+SW7 = 118
+SW8 = 119
+SW9 = 120
+SW10 = 121
+SW11 = 122
+SW12 = 123
+SW13 = 124
+SW14 = 125
+SW15 = 126
+SW16 = 127
+SW17 = 128
+SW18 = 129
+SW19 = 130
+SW20 = 131
+SW21 = 132
+SW22 = 133
+SW23 = 134
+SW24 = 135
+SW25 = 136
+SW26 = 137
+SW27 = 138
+SW28 = 139
+SW29 = 140
+SW30 = 141
+SW31 = 142
+SBBASE = 182
+SBPICK = 182
+SBBUT1 = 183
+SBBUT2 = 184
+SBBUT3 = 185
+SBBUT4 = 186
+SBBUT5 = 187
+SBBUT6 = 188
+SBBUT7 = 189
+SBBUT8 = 190
+AKEY = 11
+BKEY = 36
+CKEY = 28
+DKEY = 18
+EKEY = 17
+FKEY = 19
+GKEY = 26
+HKEY = 27
+IKEY = 40
+JKEY = 34
+KKEY = 35
+LKEY = 42
+MKEY = 44
+NKEY = 37
+OKEY = 41
+PKEY = 48
+QKEY = 10
+RKEY = 24
+SKEY = 12
+TKEY = 25
+UKEY = 33
+VKEY = 29
+WKEY = 16
+XKEY = 21
+YKEY = 32
+ZKEY = 20
+ZEROKEY = 46
+ONEKEY = 8
+TWOKEY = 14
+THREEKEY = 15
+FOURKEY = 22
+FIVEKEY = 23
+SIXKEY = 30
+SEVENKEY = 31
+EIGHTKEY = 38
+NINEKEY = 39
+BREAKKEY = 1
+SETUPKEY = 2
+CTRLKEY = 3
+LEFTCTRLKEY = CTRLKEY
+CAPSLOCKKEY = 4
+RIGHTSHIFTKEY = 5
+LEFTSHIFTKEY = 6
+NOSCRLKEY = 13
+ESCKEY = 7
+TABKEY = 9
+RETKEY = 51
+SPACEKEY = 83
+LINEFEEDKEY = 60
+BACKSPACEKEY = 61
+DELKEY = 62
+SEMICOLONKEY = 43
+PERIODKEY = 52
+COMMAKEY = 45
+QUOTEKEY = 50
+ACCENTGRAVEKEY = 55
+MINUSKEY = 47
+VIRGULEKEY = 53
+BACKSLASHKEY = 57
+EQUALKEY = 54
+LEFTBRACKETKEY = 49
+RIGHTBRACKETKEY = 56
+LEFTARROWKEY = 73
+DOWNARROWKEY = 74
+RIGHTARROWKEY = 80
+UPARROWKEY = 81
+PAD0 = 59
+PAD1 = 58
+PAD2 = 64
+PAD3 = 65
+PAD4 = 63
+PAD5 = 69
+PAD6 = 70
+PAD7 = 67
+PAD8 = 68
+PAD9 = 75
+PADPF1 = 72
+PADPF2 = 71
+PADPF3 = 79
+PADPF4 = 78
+PADPERIOD = 66
+PADMINUS = 76
+PADCOMMA = 77
+PADENTER = 82
+LEFTALTKEY = 143
+RIGHTALTKEY = 144
+RIGHTCTRLKEY = 145
+F1KEY = 146
+F2KEY = 147
+F3KEY = 148
+F4KEY = 149
+F5KEY = 150
+F6KEY = 151
+F7KEY = 152
+F8KEY = 153
+F9KEY = 154
+F10KEY = 155
+F11KEY = 156
+F12KEY = 157
+PRINTSCREENKEY = 158
+SCROLLLOCKKEY = 159
+PAUSEKEY = 160
+INSERTKEY = 161
+HOMEKEY = 162
+PAGEUPKEY = 163
+ENDKEY = 164
+PAGEDOWNKEY = 165
+NUMLOCKKEY = 166
+PADVIRGULEKEY = 167
+PADASTERKEY = 168
+PADPLUSKEY = 169
+SGIRESERVED = 256
+DIAL0 = 257
+DIAL1 = 258
+DIAL2 = 259
+DIAL3 = 260
+DIAL4 = 261
+DIAL5 = 262
+DIAL6 = 263
+DIAL7 = 264
+DIAL8 = 265
+MOUSEX = 266
+MOUSEY = 267
+LPENX = 268
+LPENY = 269
+BPADX = 270
+BPADY = 271
+CURSORX = 272
+CURSORY = 273
+GHOSTX = 274
+GHOSTY = 275
+SBTX = 276
+SBTY = 277
+SBTZ = 278
+SBRX = 279
+SBRY = 280
+SBRZ = 281
+SBPERIOD = 282
+TIMER0 = 515
+TIMER1 = 516
+TIMER2 = 517
+TIMER3 = 518
+KEYBD = 513
+RAWKEYBD = 514
+VALMARK = 523
+REDRAW = 528
+INPUTCHANGE = 534
+QFULL = 535
+QREADERROR = 538
+WINFREEZE = 539
+WINTHAW = 540
+REDRAWICONIC = 541
+WINQUIT = 542
+DEPTHCHANGE = 543
+WINSHUT = 546
+DRAWOVERLAY = 547
+VIDEO = 548
+MENUBUTTON = RIGHTMOUSE
+WINCLOSE = 537
+KEYBDFNAMES = 544
+KEYBDFSTRINGS = 545
+MAXSGIDEVICE = 20000
+GERROR = 524
+WMSEND = 529
+WMREPLY = 530
+WMGFCLOSE = 531
+WMTXCLOSE = 532
+MODECHANGE = 533
+PIECECHANGE = 536

Added: vendor/Python/current/Lib/plat-irix6/ERRNO.py
===================================================================
--- vendor/Python/current/Lib/plat-irix6/ERRNO.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix6/ERRNO.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,180 @@
+# Generated by h2py from /usr/include/errno.h
+
+# Included from sys/errno.h
+
+# Included from standards.h
+__KBASE = 1000
+__IRIXBASE = 1000
+__FTNBASE = 4000
+__FTNLAST = 5999
+EPERM = 1
+ENOENT = 2
+ESRCH = 3
+EINTR = 4
+EIO = 5
+ENXIO = 6
+E2BIG = 7
+ENOEXEC = 8
+EBADF = 9
+ECHILD = 10
+EAGAIN = 11
+ENOMEM = 12
+EACCES = 13
+EFAULT = 14
+ENOTBLK = 15
+EBUSY = 16
+EEXIST = 17
+EXDEV = 18
+ENODEV = 19
+ENOTDIR = 20
+EISDIR = 21
+EINVAL = 22
+ENFILE = 23
+EMFILE = 24
+ENOTTY = 25
+ETXTBSY = 26
+EFBIG = 27
+ENOSPC = 28
+ESPIPE = 29
+EROFS = 30
+EMLINK = 31
+EPIPE = 32
+EDOM = 33
+ERANGE = 34
+ENOMSG = 35
+EIDRM = 36
+ECHRNG = 37
+EL2NSYNC = 38
+EL3HLT = 39
+EL3RST = 40
+ELNRNG = 41
+EUNATCH = 42
+ENOCSI = 43
+EL2HLT = 44
+EDEADLK = 45
+ENOLCK = 46
+ECKPT = 47
+EBADE = 50
+EBADR = 51
+EXFULL = 52
+ENOANO = 53
+EBADRQC = 54
+EBADSLT = 55
+EDEADLOCK = 56
+EBFONT = 57
+ENOSTR = 60
+ENODATA = 61
+ETIME = 62
+ENOSR = 63
+ENONET = 64
+ENOPKG = 65
+EREMOTE = 66
+ENOLINK = 67
+EADV = 68
+ESRMNT = 69
+ECOMM = 70
+EPROTO = 71
+EMULTIHOP = 74
+EBADMSG = 77
+ENAMETOOLONG = 78
+EOVERFLOW = 79
+ENOTUNIQ = 80
+EBADFD = 81
+EREMCHG = 82
+ELIBACC = 83
+ELIBBAD = 84
+ELIBSCN = 85
+ELIBMAX = 86
+ELIBEXEC = 87
+EILSEQ = 88
+ENOSYS = 89
+ELOOP = 90
+ERESTART = 91
+ESTRPIPE = 92
+ENOTEMPTY = 93
+EUSERS = 94
+ENOTSOCK = 95
+EDESTADDRREQ = 96
+EMSGSIZE = 97
+EPROTOTYPE = 98
+ENOPROTOOPT = 99
+EPROTONOSUPPORT = 120
+ESOCKTNOSUPPORT = 121
+EOPNOTSUPP = 122
+EPFNOSUPPORT = 123
+EAFNOSUPPORT = 124
+EADDRINUSE = 125
+EADDRNOTAVAIL = 126
+ENETDOWN = 127
+ENETUNREACH = 128
+ENETRESET = 129
+ECONNABORTED = 130
+ECONNRESET = 131
+ENOBUFS = 132
+EISCONN = 133
+ENOTCONN = 134
+ESHUTDOWN = 143
+ETOOMANYREFS = 144
+ETIMEDOUT = 145
+ECONNREFUSED = 146
+EHOSTDOWN = 147
+EHOSTUNREACH = 148
+LASTERRNO = ENOTCONN
+EWOULDBLOCK = __KBASE+101
+EWOULDBLOCK = EAGAIN
+EALREADY = 149
+EINPROGRESS = 150
+ESTALE = 151
+EIORESID = 500
+EUCLEAN = 135
+ENOTNAM = 137
+ENAVAIL = 138
+EISNAM = 139
+EREMOTEIO = 140
+EINIT = 141
+EREMDEV = 142
+ECANCELED = 158
+ENOLIMFILE = 1001
+EPROCLIM = 1002
+EDISJOINT = 1003
+ENOLOGIN = 1004
+ELOGINLIM = 1005
+EGROUPLOOP = 1006
+ENOATTACH = 1007
+ENOTSUP = 1008
+ENOATTR = 1009
+EFSCORRUPTED = 1010
+EDIRCORRUPTED = 1010
+EWRONGFS = 1011
+EDQUOT = 1133
+ENFSREMOTE = 1135
+ECONTROLLER = 1300
+ENOTCONTROLLER = 1301
+EENQUEUED = 1302
+ENOTENQUEUED = 1303
+EJOINED = 1304
+ENOTJOINED = 1305
+ENOPROC = 1306
+EMUSTRUN = 1307
+ENOTSTOPPED = 1308
+ECLOCKCPU = 1309
+EINVALSTATE = 1310
+ENOEXIST = 1311
+EENDOFMINOR = 1312
+EBUFSIZE = 1313
+EEMPTY = 1314
+ENOINTRGROUP = 1315
+EINVALMODE = 1316
+ECANTEXTENT = 1317
+EINVALTIME = 1318
+EDESTROYED = 1319
+EBDHDL = 1400
+EDELAY = 1401
+ENOBWD = 1402
+EBADRSPEC = 1403
+EBADTSPEC = 1404
+EBADFILT = 1405
+EMIGRATED = 1500
+EMIGRATING = 1501
+ECELLDOWN = 1502
+EMEMRETRY = 1600

Added: vendor/Python/current/Lib/plat-irix6/FILE.py
===================================================================
--- vendor/Python/current/Lib/plat-irix6/FILE.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix6/FILE.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,674 @@
+# Generated by h2py from /usr/include/sys/file.h
+
+# Included from standards.h
+
+# Included from sys/types.h
+
+# Included from sgidefs.h
+_MIPS_ISA_MIPS1 = 1
+_MIPS_ISA_MIPS2 = 2
+_MIPS_ISA_MIPS3 = 3
+_MIPS_ISA_MIPS4 = 4
+_MIPS_SIM_ABI32 = 1
+_MIPS_SIM_NABI32 = 2
+_MIPS_SIM_ABI64 = 3
+
+# Included from sys/pthread.h
+P_MYID = (-1)
+P_MYHOSTID = (-1)
+
+# Included from sys/bsd_types.h
+
+# Included from sys/mkdev.h
+ONBITSMAJOR = 7
+ONBITSMINOR = 8
+OMAXMAJ = 0x7f
+OMAXMIN = 0xff
+NBITSMAJOR = 14
+NBITSMINOR = 18
+MAXMAJ = 0x1ff
+MAXMIN = 0x3ffff
+OLDDEV = 0
+NEWDEV = 1
+MKDEV_VER = NEWDEV
+def IS_STRING_SPEC_DEV(x): return ((dev_t)(x)==__makedev(MKDEV_VER, 0, 0))
+
+def major(dev): return __major(MKDEV_VER, dev)
+
+def minor(dev): return __minor(MKDEV_VER, dev)
+
+
+# Included from sys/select.h
+FD_SETSIZE = 1024
+__NBBY = 8
+
+# Included from string.h
+NULL = 0L
+NBBY = 8
+
+# Included from sys/cpumask.h
+MAXCPU = 128
+def CPUMASK_INDEX(bit): return ((bit) >> 6)
+
+def CPUMASK_SHFT(bit): return ((bit) & 0x3f)
+
+def CPUMASK_IS_ZERO(p): return ((p) == 0)
+
+def CPUMASK_IS_NONZERO(p): return ((p) != 0)
+
+
+# Included from sys/nodemask.h
+def CNODEMASK_IS_ZERO(p): return ((p) == 0)
+
+def CNODEMASK_IS_NONZERO(p): return ((p) != 0)
+
+
+# Included from sys/sema.h
+
+# Included from sys/timespec.h
+
+# Included from sys/param.h
+
+# Included from sys/signal.h
+SIGHUP = 1
+SIGINT = 2
+SIGQUIT = 3
+SIGILL = 4
+SIGTRAP = 5
+SIGIOT = 6
+SIGABRT = 6
+SIGEMT = 7
+SIGFPE = 8
+SIGKILL = 9
+SIGBUS = 10
+SIGSEGV = 11
+SIGSYS = 12
+SIGPIPE = 13
+SIGALRM = 14
+SIGTERM = 15
+SIGUSR1 = 16
+SIGUSR2 = 17
+SIGCLD = 18
+SIGCHLD = 18
+SIGPWR = 19
+SIGWINCH = 20
+SIGURG = 21
+SIGPOLL = 22
+SIGIO = 22
+SIGSTOP = 23
+SIGTSTP = 24
+SIGCONT = 25
+SIGTTIN = 26
+SIGTTOU = 27
+SIGVTALRM = 28
+SIGPROF = 29
+SIGXCPU = 30
+SIGXFSZ = 31
+SIGK32 = 32
+SIGCKPT = 33
+SIGRESTART = 34
+SIGUME = 35
+SIGPTINTR = 47
+SIGPTRESCHED = 48
+SIGRTMIN = 49
+SIGRTMAX = 64
+__sigargs = int
+
+# Included from sys/sigevent.h
+SIGEV_NONE = 128
+SIGEV_SIGNAL = 129
+SIGEV_CALLBACK = 130
+SIGEV_THREAD = 131
+
+# Included from sys/siginfo.h
+SI_MAXSZ = 128
+SI_USER = 0
+SI_KILL = SI_USER
+SI_QUEUE = -1
+SI_ASYNCIO = -2
+SI_TIMER = -3
+SI_MESGQ = -4
+ILL_ILLOPC = 1
+ILL_ILLOPN = 2
+ILL_ILLADR = 3
+ILL_ILLTRP = 4
+ILL_PRVOPC = 5
+ILL_PRVREG = 6
+ILL_COPROC = 7
+ILL_BADSTK = 8
+NSIGILL = 8
+FPE_INTDIV = 1
+FPE_INTOVF = 2
+FPE_FLTDIV = 3
+FPE_FLTOVF = 4
+FPE_FLTUND = 5
+FPE_FLTRES = 6
+FPE_FLTINV = 7
+FPE_FLTSUB = 8
+NSIGFPE = 8
+SEGV_MAPERR = 1
+SEGV_ACCERR = 2
+NSIGSEGV = 2
+BUS_ADRALN = 1
+BUS_ADRERR = 2
+BUS_OBJERR = 3
+NSIGBUS = 3
+TRAP_BRKPT = 1
+TRAP_TRACE = 2
+NSIGTRAP = 2
+CLD_EXITED = 1
+CLD_KILLED = 2
+CLD_DUMPED = 3
+CLD_TRAPPED = 4
+CLD_STOPPED = 5
+CLD_CONTINUED = 6
+NSIGCLD = 6
+POLL_IN = 1
+POLL_OUT = 2
+POLL_MSG = 3
+POLL_ERR = 4
+POLL_PRI = 5
+POLL_HUP = 6
+NSIGPOLL = 6
+UME_ECCERR = 1
+NSIGUME = 1
+SIG_NOP = 0
+SIG_BLOCK = 1
+SIG_UNBLOCK = 2
+SIG_SETMASK = 3
+SIG_SETMASK32 = 256
+SA_ONSTACK = 0x00000001
+SA_RESETHAND = 0x00000002
+SA_RESTART = 0x00000004
+SA_SIGINFO = 0x00000008
+SA_NODEFER = 0x00000010
+SA_NOCLDWAIT = 0x00010000
+SA_NOCLDSTOP = 0x00020000
+_SA_BSDCALL = 0x10000000
+MINSIGSTKSZ = 512
+SIGSTKSZ = 8192
+SS_ONSTACK = 0x00000001
+SS_DISABLE = 0x00000002
+
+# Included from sys/ucontext.h
+NGREG = 36
+NGREG = 37
+GETCONTEXT = 0
+SETCONTEXT = 1
+UC_SIGMASK = 001
+UC_STACK = 002
+UC_CPU = 004
+UC_MAU = 010
+UC_MCONTEXT = (UC_CPU|UC_MAU)
+UC_ALL = (UC_SIGMASK|UC_STACK|UC_MCONTEXT)
+CTX_R0 = 0
+CTX_AT = 1
+CTX_V0 = 2
+CTX_V1 = 3
+CTX_A0 = 4
+CTX_A1 = 5
+CTX_A2 = 6
+CTX_A3 = 7
+CTX_T0 = 8
+CTX_T1 = 9
+CTX_T2 = 10
+CTX_T3 = 11
+CTX_T4 = 12
+CTX_T5 = 13
+CTX_T6 = 14
+CTX_T7 = 15
+CTX_A4 = 8
+CTX_A5 = 9
+CTX_A6 = 10
+CTX_A7 = 11
+CTX_T0 = 12
+CTX_T1 = 13
+CTX_T2 = 14
+CTX_T3 = 15
+CTX_S0 = 16
+CTX_S1 = 17
+CTX_S2 = 18
+CTX_S3 = 19
+CTX_S4 = 20
+CTX_S5 = 21
+CTX_S6 = 22
+CTX_S7 = 23
+CTX_T8 = 24
+CTX_T9 = 25
+CTX_K0 = 26
+CTX_K1 = 27
+CTX_GP = 28
+CTX_SP = 29
+CTX_S8 = 30
+CTX_RA = 31
+CTX_MDLO = 32
+CTX_MDHI = 33
+CTX_CAUSE = 34
+CTX_EPC = 35
+CTX_SR = 36
+CXT_R0 = CTX_R0
+CXT_AT = CTX_AT
+CXT_V0 = CTX_V0
+CXT_V1 = CTX_V1
+CXT_A0 = CTX_A0
+CXT_A1 = CTX_A1
+CXT_A2 = CTX_A2
+CXT_A3 = CTX_A3
+CXT_T0 = CTX_T0
+CXT_T1 = CTX_T1
+CXT_T2 = CTX_T2
+CXT_T3 = CTX_T3
+CXT_T4 = CTX_T4
+CXT_T5 = CTX_T5
+CXT_T6 = CTX_T6
+CXT_T7 = CTX_T7
+CXT_S0 = CTX_S0
+CXT_S1 = CTX_S1
+CXT_S2 = CTX_S2
+CXT_S3 = CTX_S3
+CXT_S4 = CTX_S4
+CXT_S5 = CTX_S5
+CXT_S6 = CTX_S6
+CXT_S7 = CTX_S7
+CXT_T8 = CTX_T8
+CXT_T9 = CTX_T9
+CXT_K0 = CTX_K0
+CXT_K1 = CTX_K1
+CXT_GP = CTX_GP
+CXT_SP = CTX_SP
+CXT_S8 = CTX_S8
+CXT_RA = CTX_RA
+CXT_MDLO = CTX_MDLO
+CXT_MDHI = CTX_MDHI
+CXT_CAUSE = CTX_CAUSE
+CXT_EPC = CTX_EPC
+CXT_SR = CTX_SR
+CTX_FV0 = 0
+CTX_FV1 = 2
+CTX_FA0 = 12
+CTX_FA1 = 13
+CTX_FA2 = 14
+CTX_FA3 = 15
+CTX_FA4 = 16
+CTX_FA5 = 17
+CTX_FA6 = 18
+CTX_FA7 = 19
+CTX_FT0 = 4
+CTX_FT1 = 5
+CTX_FT2 = 6
+CTX_FT3 = 7
+CTX_FT4 = 8
+CTX_FT5 = 9
+CTX_FT6 = 10
+CTX_FT7 = 11
+CTX_FT8 = 20
+CTX_FT9 = 21
+CTX_FT10 = 22
+CTX_FT11 = 23
+CTX_FT12 = 1
+CTX_FT13 = 3
+CTX_FS0 = 24
+CTX_FS1 = 25
+CTX_FS2 = 26
+CTX_FS3 = 27
+CTX_FS4 = 28
+CTX_FS5 = 29
+CTX_FS6 = 30
+CTX_FS7 = 31
+CTX_FT8 = 21
+CTX_FT9 = 23
+CTX_FT10 = 25
+CTX_FT11 = 27
+CTX_FT12 = 29
+CTX_FT13 = 31
+CTX_FT14 = 1
+CTX_FT15 = 3
+CTX_FS0 = 20
+CTX_FS1 = 22
+CTX_FS2 = 24
+CTX_FS3 = 26
+CTX_FS4 = 28
+CTX_FS5 = 30
+SV_ONSTACK = 0x0001
+SV_INTERRUPT = 0x0002
+NUMBSDSIGS = (32)
+def sigmask(sig): return (1L << ((sig)-1))
+
+def sigmask(sig): return (1L << ((sig)-1))
+
+SIG_ERR = (-1)
+SIG_IGN = (1)
+SIG_HOLD = (2)
+SIG_DFL = (0)
+NSIG = 65
+MAXSIG = (NSIG-1)
+NUMSIGS = (NSIG-1)
+BRK_USERBP = 0
+BRK_KERNELBP = 1
+BRK_ABORT = 2
+BRK_BD_TAKEN = 3
+BRK_BD_NOTTAKEN = 4
+BRK_SSTEPBP = 5
+BRK_OVERFLOW = 6
+BRK_DIVZERO = 7
+BRK_RANGE = 8
+BRK_PSEUDO_OP_BIT = 0x80
+BRK_PSEUDO_OP_MAX = 0x3
+BRK_CACHE_SYNC = 0x80
+BRK_MULOVF = 1023
+_POSIX_VERSION = 199506L
+_POSIX_VERSION = 199506
+_POSIX_VDISABLE = 0
+MAX_INPUT = 512
+MAX_CANON = 256
+UID_NOBODY = 60001
+GID_NOBODY = UID_NOBODY
+UID_NOACCESS = 60002
+MAXPID = 0x7ffffff0
+MAXUID = 0x7fffffff
+MAXLINK = 30000
+SSIZE = 1
+SINCR = 1
+KSTKSIZE = 1
+EXTKSTKSIZE = 1
+KSTKIDX = 0
+KSTEIDX = 1
+EXTKSTKSIZE = 0
+KSTKIDX = 0
+CANBSIZ = 256
+HZ = 100
+TICK = 10000000
+NOFILE = 20
+NGROUPS_UMIN = 0
+NGROUPS_UMAX = 32
+NGROUPS = 16
+PMASK = 0177
+PCATCH = 0400
+PLTWAIT = 01000
+PRECALC = 01000
+PSWP = 0
+PINOD = 10
+PSNDD = PINOD
+PRIBIO = 20
+PZERO = 25
+PMEM = 0
+NZERO = 20
+PPIPE = 26
+PVFS = 27
+PWAIT = 30
+PSLEP = 39
+PUSER = 60
+PBATCH_CRITICAL = -1
+PTIME_SHARE = -2
+PTIME_SHARE_OVER = -3
+PBATCH = -4
+PWEIGHTLESS = -5
+IO_NBPC = 4096
+IO_BPCSHIFT = 12
+MIN_NBPC = 4096
+MIN_BPCSHIFT = 12
+MIN_CPSSHIFT = 10
+BPCSHIFT = 12
+CPSSHIFT = 10
+BPCSHIFT = 14
+CPSSHIFT = 12
+CPSSHIFT = 11
+BPSSHIFT = (BPCSHIFT+CPSSHIFT)
+NULL = 0L
+CMASK = 022
+NODEV = (-1)
+NOPAGE = (-1)
+NBPSCTR = 512
+SCTRSHFT = 9
+def BASEPRI(psw): return (((psw) & SR_IMASK) == SR_IMASK0)
+
+def BASEPRI(psw): return (((psw) & SR_IMASK) == SR_IMASK)
+
+def USERMODE(psw): return (((psw) & SR_KSU_MSK) == SR_KSU_USR)
+
+MAXPATHLEN = 1024
+MAXSYMLINKS = 30
+MAXNAMELEN = 256
+PIPE_BUF = 10240
+PIPE_MAX = 10240
+NBBY = 8
+BBSHIFT = 9
+BBSIZE = (1<<BBSHIFT)
+BBMASK = (BBSIZE-1)
+def BBTOB(bbs): return ((bbs) << BBSHIFT)
+
+def OFFTOBB(bytes): return (((__uint64_t)(bytes) + BBSIZE - 1) >> BBSHIFT)
+
+def OFFTOBBT(bytes): return ((off_t)(bytes) >> BBSHIFT)
+
+def BBTOOFF(bbs): return ((off_t)(bbs) << BBSHIFT)
+
+SEEKLIMIT32 = 0x7fffffff
+MAXBSIZE = 8192
+DEV_BSIZE = BBSIZE
+DEV_BSHIFT = BBSHIFT
+def btodb(bytes): return   \
+
+def dbtob(db): return   \
+
+BLKDEV_IOSHIFT = BPCSHIFT
+BLKDEV_IOSIZE = (1<<BLKDEV_IOSHIFT)
+def BLKDEV_OFF(off): return ((off) & (BLKDEV_IOSIZE - 1))
+
+def BLKDEV_LBN(off): return ((off) >> BLKDEV_IOSHIFT)
+
+def BLKDEV_LTOP(bn): return ((bn) * BLKDEV_BB)
+
+MAXHOSTNAMELEN = 256
+def DELAY(n): return us_delay(n)
+
+def DELAYBUS(n): return us_delaybus(n)
+
+TIMEPOKE_NOW = -100L
+MUTEX_DEFAULT = 0x0
+METER_NAMSZ = 16
+METER_NO_SEQ = -1
+def mutex_spinlock(l): return splhi()
+
+def mutex_spintrylock(l): return splhi()
+
+def spinlock_initialized(l): return 1
+
+SV_FIFO = 0x0
+SV_LIFO = 0x2
+SV_PRIO = 0x4
+SV_KEYED = 0x6
+SV_DEFAULT = SV_FIFO
+SEMA_NOHIST = 0x0001
+SEMA_LOCK = 0x0004
+NSCHEDCLASS = (-(PWEIGHTLESS)+1)
+MR_ACCESS = 1
+MR_UPDATE = 2
+MRLOCK_BARRIER = 0x1
+MRLOCK_BEHAVIOR = 0x2
+MRLOCK_DBLTRIPPABLE = 0x4
+MRLOCK_ALLOW_EQUAL_PRI = 0x8
+MRLOCK_DEFAULT = MRLOCK_BARRIER
+def mraccess(mrp): return mraccessf(mrp, 0)
+
+def mrupdate(mrp): return mrupdatef(mrp, 0)
+
+def mp_mutex_unlock(m): return mutex_unlock(m)
+
+def mp_mutex_trylock(m): return mutex_trylock(m)
+
+def mp_mutex_spinlock(m): return mutex_spinlock(m)
+
+
+# Included from sys/mon.h
+MON_LOCKED = 0x01
+MON_WAITING = 0x02
+MON_TIMEOUT = 0x04
+MON_DOSRV = 0x08
+MON_RUN = 0x10
+MR_READER_BUCKETS = 13
+def initlock(l): return spinlock_init(l,0)
+
+def ownlock(x): return 1
+
+def mutex_enter(m): return mutex_lock(m, PZERO)
+
+def mutex_tryenter(m): return mutex_trylock(m)
+
+def mutex_exit(m): return mutex_unlock(m)
+
+def cv_signal(cv): return sv_signal(cv)
+
+def cv_broadcast(cv): return sv_broadcast(cv)
+
+def cv_destroy(cv): return sv_destroy(cv)
+
+RW_READER = MR_ACCESS
+RW_WRITER = MR_UPDATE
+def rw_exit(r): return mrunlock(r)
+
+def rw_tryupgrade(r): return mrtrypromote(r)
+
+def rw_downgrade(r): return mrdemote(r)
+
+def rw_destroy(r): return mrfree(r)
+
+def RW_WRITE_HELD(r): return ismrlocked(r, MR_UPDATE)
+
+def RW_READ_HELD(r): return ismrlocked(r, MR_ACCESS)
+
+MS_FREE = 0
+MS_UPD = 1
+MS_ACC = 2
+MS_WAITERS = 4
+
+# Included from sys/fcntl.h
+FNDELAY = 0x04
+FAPPEND = 0x08
+FSYNC = 0x10
+FDSYNC = 0x20
+FRSYNC = 0x40
+FNONBLOCK = 0x80
+FASYNC = 0x1000
+FLARGEFILE = 0x2000
+FNONBLK = FNONBLOCK
+FDIRECT = 0x8000
+FBULK = 0x10000
+FDIRENT64 = 0x8000
+FCREAT = 0x0100
+FTRUNC = 0x0200
+FEXCL = 0x0400
+FNOCTTY = 0x0800
+O_RDONLY = 0
+O_WRONLY = 1
+O_RDWR = 2
+O_NDELAY = 0x04
+O_APPEND = 0x08
+O_SYNC = 0x10
+O_DSYNC = 0x20
+O_RSYNC = 0x40
+O_NONBLOCK = 0x80
+O_LARGEFILE = 0x2000
+O_DIRECT = 0x8000
+O_BULK = 0x10000
+O_CREAT = 0x100
+O_TRUNC = 0x200
+O_EXCL = 0x400
+O_NOCTTY = 0x800
+F_DUPFD = 0
+F_GETFD = 1
+F_SETFD = 2
+F_GETFL = 3
+F_SETFL = 4
+F_SETLK = 6
+F_SETLKW = 7
+F_CHKFL = 8
+F_ALLOCSP = 10
+F_FREESP = 11
+F_SETBSDLK = 12
+F_SETBSDLKW = 13
+F_GETLK = 14
+F_CHKLK = 15
+F_CHKLKW = 16
+F_CLNLK = 17
+F_RSETLK = 20
+F_RGETLK = 21
+F_RSETLKW = 22
+F_GETOWN = 23
+F_SETOWN = 24
+F_DIOINFO = 30
+F_FSGETXATTR = 31
+F_FSSETXATTR = 32
+F_GETLK64 = 33
+F_SETLK64 = 34
+F_SETLKW64 = 35
+F_ALLOCSP64 = 36
+F_FREESP64 = 37
+F_GETBMAP = 38
+F_FSSETDM = 39
+F_RESVSP = 40
+F_UNRESVSP = 41
+F_RESVSP64 = 42
+F_UNRESVSP64 = 43
+F_GETBMAPA = 44
+F_FSGETXATTRA = 45
+F_SETBIOSIZE = 46
+F_GETBIOSIZE = 47
+F_GETOPS = 50
+F_DMAPI = 51
+F_FSYNC = 52
+F_FSYNC64 = 53
+F_GETBDSATTR = 54
+F_SETBDSATTR = 55
+F_GETBMAPX = 56
+F_SETPRIO = 57
+F_GETPRIO = 58
+F_RDLCK = 01
+F_WRLCK = 02
+F_UNLCK = 03
+O_ACCMODE = 3
+FD_CLOEXEC = 1
+FD_NODUP_FORK = 4
+BMV_IF_ATTRFORK = 0x1
+BMV_IF_NO_DMAPI_READ = 0x2
+BMV_IF_PREALLOC = 0x4
+BMV_IF_VALID = (BMV_IF_ATTRFORK|BMV_IF_NO_DMAPI_READ|BMV_IF_PREALLOC)
+BMV_OF_PREALLOC = 0x1
+BMV_IF_EXTENDED = 0x40000000
+FMASK = 0x190FF
+FOPEN = 0xFFFFFFFF
+FREAD = 0x01
+FWRITE = 0x02
+FNDELAY = 0x04
+FAPPEND = 0x08
+FSYNC = 0x10
+FDSYNC = 0x20
+FRSYNC = 0x40
+FNONBLOCK = 0x80
+FASYNC = 0x1000
+FNONBLK = FNONBLOCK
+FLARGEFILE = 0x2000
+FDIRECT = 0x8000
+FBULK = 0x10000
+FCREAT = 0x0100
+FTRUNC = 0x0200
+FEXCL = 0x0400
+FNOCTTY = 0x0800
+FINVIS = 0x0100
+FSOCKET = 0x0200
+FINPROGRESS = 0x0400
+FPRIORITY = 0x0800
+FPRIO = 0x4000
+FDIRENT64 = 0x8000
+FCLOSEXEC = 0x01
+LOCK_SH = 1
+LOCK_EX = 2
+LOCK_NB = 4
+LOCK_UN = 8
+L_SET = 0
+L_INCR = 1
+L_XTND = 2
+F_OK = 0
+X_OK = 1
+W_OK = 2
+R_OK = 4

Added: vendor/Python/current/Lib/plat-irix6/FL.py
===================================================================
--- vendor/Python/current/Lib/plat-irix6/FL.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix6/FL.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,289 @@
+# Constants used by the FORMS library (module fl).
+# This corresponds to "forms.h".
+# Recommended use: import FL; ... FL.NORMAL_BOX ... etc.
+# Alternate use: from FL import *; ... NORMAL_BOX ... etc.
+
+_v20 = 1
+_v21 = 1
+##import fl
+##try:
+##      _v20 = (fl.get_rgbmode is not None)
+##except:
+##      _v20 = 0
+##del fl
+
+NULL = 0
+FALSE = 0
+TRUE = 1
+
+EVENT = -1
+
+LABEL_SIZE = 64
+if _v20:
+    SHORTCUT_SIZE = 32
+PLACE_FREE = 0
+PLACE_SIZE = 1
+PLACE_ASPECT = 2
+PLACE_MOUSE = 3
+PLACE_CENTER = 4
+PLACE_POSITION = 5
+FL_PLACE_FULLSCREEN = 6
+FIND_INPUT = 0
+FIND_AUTOMATIC = 1
+FIND_MOUSE = 2
+BEGIN_GROUP = 10000
+END_GROUP = 20000
+ALIGN_TOP = 0
+ALIGN_BOTTOM = 1
+ALIGN_LEFT = 2
+ALIGN_RIGHT = 3
+ALIGN_CENTER = 4
+NO_BOX = 0
+UP_BOX = 1
+DOWN_BOX = 2
+FLAT_BOX = 3
+BORDER_BOX = 4
+SHADOW_BOX = 5
+FRAME_BOX = 6
+ROUNDED_BOX = 7
+RFLAT_BOX = 8
+RSHADOW_BOX = 9
+TOP_BOUND_COL = 51
+LEFT_BOUND_COL = 55
+BOT_BOUND_COL = 40
+RIGHT_BOUND_COL = 35
+COL1 = 47
+MCOL = 49
+LCOL = 0
+BOUND_WIDTH = 3.0
+DRAW = 0
+PUSH = 1
+RELEASE = 2
+ENTER = 3
+LEAVE = 4
+MOUSE = 5
+FOCUS = 6
+UNFOCUS = 7
+KEYBOARD = 8
+STEP = 9
+MOVE = 10
+FONT_NAME = 'Helvetica'
+FONT_BOLDNAME = 'Helvetica-Bold'
+FONT_ITALICNAME = 'Helvetica-Oblique'
+FONT_FIXEDNAME = 'Courier'
+FONT_ICONNAME = 'Icon'
+SMALL_FONT = 8.0
+NORMAL_FONT = 11.0
+LARGE_FONT = 20.0
+NORMAL_STYLE = 0
+BOLD_STYLE = 1
+ITALIC_STYLE = 2
+FIXED_STYLE = 3
+ENGRAVED_STYLE = 4
+ICON_STYLE = 5
+BITMAP = 3
+NORMAL_BITMAP = 0
+BITMAP_BOXTYPE = NO_BOX
+BITMAP_COL1 = 0
+BITMAP_COL2 = COL1
+BITMAP_LCOL = LCOL
+BITMAP_ALIGN = ALIGN_BOTTOM
+BITMAP_MAXSIZE = 128*128
+BITMAP_BW = BOUND_WIDTH
+BOX = 1
+BOX_BOXTYPE = UP_BOX
+BOX_COL1 = COL1
+BOX_LCOL = LCOL
+BOX_ALIGN = ALIGN_CENTER
+BOX_BW = BOUND_WIDTH
+BROWSER = 71
+NORMAL_BROWSER = 0
+SELECT_BROWSER = 1
+HOLD_BROWSER = 2
+MULTI_BROWSER = 3
+BROWSER_BOXTYPE = DOWN_BOX
+BROWSER_COL1 = COL1
+BROWSER_COL2 = 3
+BROWSER_LCOL = LCOL
+BROWSER_ALIGN = ALIGN_BOTTOM
+BROWSER_SLCOL = COL1
+BROWSER_BW = BOUND_WIDTH
+BROWSER_LINELENGTH = 128
+BROWSER_MAXLINE = 512
+BUTTON = 11
+NORMAL_BUTTON = 0
+PUSH_BUTTON = 1
+RADIO_BUTTON = 2
+HIDDEN_BUTTON = 3
+TOUCH_BUTTON = 4
+INOUT_BUTTON = 5
+RETURN_BUTTON = 6
+if _v20:
+    HIDDEN_RET_BUTTON = 7
+BUTTON_BOXTYPE = UP_BOX
+BUTTON_COL1 = COL1
+BUTTON_COL2 = COL1
+BUTTON_LCOL = LCOL
+BUTTON_ALIGN = ALIGN_CENTER
+BUTTON_MCOL1 = MCOL
+BUTTON_MCOL2 = MCOL
+BUTTON_BW = BOUND_WIDTH
+if _v20:
+    CHART = 4
+    BAR_CHART = 0
+    HORBAR_CHART = 1
+    LINE_CHART = 2
+    FILLED_CHART = 3
+    SPIKE_CHART = 4
+    PIE_CHART = 5
+    SPECIALPIE_CHART = 6
+    CHART_BOXTYPE = BORDER_BOX
+    CHART_COL1 = COL1
+    CHART_LCOL = LCOL
+    CHART_ALIGN = ALIGN_BOTTOM
+    CHART_BW = BOUND_WIDTH
+    CHART_MAX = 128
+CHOICE = 42
+NORMAL_CHOICE = 0
+CHOICE_BOXTYPE = DOWN_BOX
+CHOICE_COL1 = COL1
+CHOICE_COL2 = LCOL
+CHOICE_LCOL = LCOL
+CHOICE_ALIGN = ALIGN_LEFT
+CHOICE_BW = BOUND_WIDTH
+CHOICE_MCOL = MCOL
+CHOICE_MAXITEMS = 128
+CHOICE_MAXSTR = 64
+CLOCK = 61
+SQUARE_CLOCK = 0
+ROUND_CLOCK = 1
+CLOCK_BOXTYPE = UP_BOX
+CLOCK_COL1 = 37
+CLOCK_COL2 = 42
+CLOCK_LCOL = LCOL
+CLOCK_ALIGN = ALIGN_BOTTOM
+CLOCK_TOPCOL = COL1
+CLOCK_BW = BOUND_WIDTH
+COUNTER = 25
+NORMAL_COUNTER = 0
+SIMPLE_COUNTER = 1
+COUNTER_BOXTYPE = UP_BOX
+COUNTER_COL1 = COL1
+COUNTER_COL2 = 4
+COUNTER_LCOL = LCOL
+COUNTER_ALIGN = ALIGN_BOTTOM
+if _v20:
+    COUNTER_BW = BOUND_WIDTH
+else:
+    DEFAULT = 51
+    RETURN_DEFAULT = 0
+    ALWAYS_DEFAULT = 1
+DIAL = 22
+NORMAL_DIAL = 0
+LINE_DIAL = 1
+DIAL_BOXTYPE = NO_BOX
+DIAL_COL1 = COL1
+DIAL_COL2 = 37
+DIAL_LCOL = LCOL
+DIAL_ALIGN = ALIGN_BOTTOM
+DIAL_TOPCOL = COL1
+DIAL_BW = BOUND_WIDTH
+FREE = 101
+NORMAL_FREE = 1
+SLEEPING_FREE = 2
+INPUT_FREE = 3
+CONTINUOUS_FREE = 4
+ALL_FREE = 5
+INPUT = 31
+NORMAL_INPUT = 0
+if _v20:
+    FLOAT_INPUT = 1
+    INT_INPUT = 2
+    HIDDEN_INPUT = 3
+    if _v21:
+        MULTILINE_INPUT = 4
+        SECRET_INPUT = 5
+else:
+    ALWAYS_INPUT = 1
+INPUT_BOXTYPE = DOWN_BOX
+INPUT_COL1 = 13
+INPUT_COL2 = 5
+INPUT_LCOL = LCOL
+INPUT_ALIGN = ALIGN_LEFT
+INPUT_TCOL = LCOL
+INPUT_CCOL = 4
+INPUT_BW = BOUND_WIDTH
+INPUT_MAX = 128
+LIGHTBUTTON = 12
+LIGHTBUTTON_BOXTYPE = UP_BOX
+LIGHTBUTTON_COL1 = 39
+LIGHTBUTTON_COL2 = 3
+LIGHTBUTTON_LCOL = LCOL
+LIGHTBUTTON_ALIGN = ALIGN_CENTER
+LIGHTBUTTON_TOPCOL = COL1
+LIGHTBUTTON_MCOL = MCOL
+LIGHTBUTTON_BW1 = BOUND_WIDTH
+LIGHTBUTTON_BW2 = BOUND_WIDTH/2.0
+LIGHTBUTTON_MINSIZE = 12.0
+MENU = 41
+TOUCH_MENU = 0
+PUSH_MENU = 1
+MENU_BOXTYPE = BORDER_BOX
+MENU_COL1 = 55
+MENU_COL2 = 37
+MENU_LCOL = LCOL
+MENU_ALIGN = ALIGN_CENTER
+MENU_BW = BOUND_WIDTH
+MENU_MAX = 300
+POSITIONER = 23
+NORMAL_POSITIONER = 0
+POSITIONER_BOXTYPE = DOWN_BOX
+POSITIONER_COL1 = COL1
+POSITIONER_COL2 = 1
+POSITIONER_LCOL = LCOL
+POSITIONER_ALIGN = ALIGN_BOTTOM
+POSITIONER_BW = BOUND_WIDTH
+ROUNDBUTTON = 13
+ROUNDBUTTON_BOXTYPE = NO_BOX
+ROUNDBUTTON_COL1 = 7
+ROUNDBUTTON_COL2 = 3
+ROUNDBUTTON_LCOL = LCOL
+ROUNDBUTTON_ALIGN = ALIGN_CENTER
+ROUNDBUTTON_TOPCOL = COL1
+ROUNDBUTTON_MCOL = MCOL
+ROUNDBUTTON_BW = BOUND_WIDTH
+SLIDER = 21
+VALSLIDER = 24
+VERT_SLIDER = 0
+HOR_SLIDER = 1
+VERT_FILL_SLIDER = 2
+HOR_FILL_SLIDER = 3
+VERT_NICE_SLIDER = 4
+HOR_NICE_SLIDER = 5
+SLIDER_BOXTYPE = DOWN_BOX
+SLIDER_COL1 = COL1
+SLIDER_COL2 = COL1
+SLIDER_LCOL = LCOL
+SLIDER_ALIGN = ALIGN_BOTTOM
+SLIDER_BW1 = BOUND_WIDTH
+SLIDER_BW2 = BOUND_WIDTH*0.75
+SLIDER_FINE = 0.05
+SLIDER_WIDTH = 0.08
+TEXT = 2
+NORMAL_TEXT = 0
+TEXT_BOXTYPE = NO_BOX
+TEXT_COL1 = COL1
+TEXT_LCOL = LCOL
+TEXT_ALIGN = ALIGN_LEFT
+TEXT_BW = BOUND_WIDTH
+TIMER = 62
+NORMAL_TIMER = 0
+VALUE_TIMER = 1
+HIDDEN_TIMER = 2
+TIMER_BOXTYPE = DOWN_BOX
+TIMER_COL1 = COL1
+TIMER_COL2 = 1
+TIMER_LCOL = LCOL
+TIMER_ALIGN = ALIGN_CENTER
+TIMER_BW = BOUND_WIDTH
+TIMER_BLINKRATE = 0.2

Added: vendor/Python/current/Lib/plat-irix6/GET.py
===================================================================
--- vendor/Python/current/Lib/plat-irix6/GET.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix6/GET.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,59 @@
+# Symbols from <gl/get.h>
+
+BCKBUFFER = 0x1
+FRNTBUFFER = 0x2
+DRAWZBUFFER = 0x4
+DMRGB = 0
+DMSINGLE = 1
+DMDOUBLE = 2
+DMRGBDOUBLE = 5
+HZ30 = 0
+HZ60 = 1
+NTSC = 2
+HDTV = 3
+VGA = 4
+IRIS3K = 5
+PR60 = 6
+PAL = 9
+HZ30_SG = 11
+A343 = 14
+STR_RECT = 15
+VOF0 = 16
+VOF1 = 17
+VOF2 = 18
+VOF3 = 19
+SGI0 = 20
+SGI1 = 21
+SGI2 = 22
+HZ72 = 23
+GL_VIDEO_REG = 0x00800000
+GLV_GENLOCK = 0x00000001
+GLV_UNBLANK = 0x00000002
+GLV_SRED = 0x00000004
+GLV_SGREEN = 0x00000008
+GLV_SBLUE = 0x00000010
+GLV_SALPHA = 0x00000020
+GLV_TTLGENLOCK = 0x00000080
+GLV_TTLSYNC = GLV_TTLGENLOCK
+GLV_GREENGENLOCK = 0x0000100
+LEFTPLANE = 0x0001
+RIGHTPLANE = 0x0002
+BOTTOMPLANE = 0x0004
+TOPPLANE = 0x0008
+NEARPLANE = 0x0010
+FARPLANE = 0x0020
+## GETDEF = __GL_GET_H__
+NOBUFFER = 0x0
+BOTHBUFFERS = 0x3
+DMINTENSITYSINGLE = 3
+DMINTENSITYDOUBLE = 4
+MONSPECIAL = 0x20
+HZ50 = 3
+MONA = 5
+MONB = 6
+MONC = 7
+MOND = 8
+MON_ALL = 12
+MON_GEN_ALL = 13
+CMAPMULTI = 0
+CMAPONE = 1

Added: vendor/Python/current/Lib/plat-irix6/GL.py
===================================================================
--- vendor/Python/current/Lib/plat-irix6/GL.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix6/GL.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,393 @@
+NULL = 0
+FALSE = 0
+TRUE = 1
+ATTRIBSTACKDEPTH = 10
+VPSTACKDEPTH = 8
+MATRIXSTACKDEPTH = 32
+NAMESTACKDEPTH = 1025
+STARTTAG = -2
+ENDTAG = -3
+BLACK = 0
+RED = 1
+GREEN = 2
+YELLOW = 3
+BLUE = 4
+MAGENTA = 5
+CYAN = 6
+WHITE = 7
+PUP_CLEAR = 0
+PUP_COLOR = 1
+PUP_BLACK = 2
+PUP_WHITE = 3
+NORMALDRAW = 0x010
+PUPDRAW = 0x020
+OVERDRAW = 0x040
+UNDERDRAW = 0x080
+CURSORDRAW = 0x100
+DUALDRAW = 0x200
+PATTERN_16 = 16
+PATTERN_32 = 32
+PATTERN_64 = 64
+PATTERN_16_SIZE = 16
+PATTERN_32_SIZE = 64
+PATTERN_64_SIZE = 256
+SRC_AUTO = 0
+SRC_FRONT = 1
+SRC_BACK = 2
+SRC_ZBUFFER = 3
+SRC_PUP = 4
+SRC_OVER = 5
+SRC_UNDER = 6
+SRC_FRAMEGRABBER = 7
+BF_ZERO = 0
+BF_ONE = 1
+BF_DC = 2
+BF_SC = 2
+BF_MDC = 3
+BF_MSC = 3
+BF_SA = 4
+BF_MSA = 5
+BF_DA = 6
+BF_MDA = 7
+BF_MIN_SA_MDA = 8
+AF_NEVER = 0
+AF_LESS = 1
+AF_EQUAL = 2
+AF_LEQUAL = 3
+AF_GREATER = 4
+AF_NOTEQUAL = 5
+AF_GEQUAL = 6
+AF_ALWAYS = 7
+ZF_NEVER = 0
+ZF_LESS = 1
+ZF_EQUAL = 2
+ZF_LEQUAL = 3
+ZF_GREATER = 4
+ZF_NOTEQUAL = 5
+ZF_GEQUAL = 6
+ZF_ALWAYS = 7
+ZSRC_DEPTH = 0
+ZSRC_COLOR = 1
+SMP_OFF = 0x0
+SMP_ON = 0x1
+SMP_SMOOTHER = 0x2
+SML_OFF = 0x0
+SML_ON = 0x1
+SML_SMOOTHER = 0x2
+SML_END_CORRECT = 0x4
+PYSM_OFF = 0
+PYSM_ON = 1
+PYSM_SHRINK = 2
+DT_OFF = 0
+DT_ON = 1
+PUP_NONE = 0
+PUP_GREY = 0x1
+PUP_BOX = 0x2
+PUP_CHECK = 0x4
+GLC_OLDPOLYGON = 0
+GLC_ZRANGEMAP = 1
+GLC_MQUEUERATE = 2
+GLC_SOFTATTACH = 3
+GLC_MANAGEBG = 4
+GLC_SLOWMAPCOLORS = 5
+GLC_INPUTCHANGEBUG = 6
+GLC_NOBORDERBUG = 7
+GLC_SET_VSYNC = 8
+GLC_GET_VSYNC = 9
+GLC_VSYNC_SLEEP = 10
+GLC_COMPATRATE = 15
+C16X1 = 0
+C16X2 = 1
+C32X1 = 2
+C32X2 = 3
+CCROSS = 4
+FLAT = 0
+GOURAUD = 1
+LO_ZERO = 0x0
+LO_AND = 0x1
+LO_ANDR = 0x2
+LO_SRC = 0x3
+LO_ANDI = 0x4
+LO_DST = 0x5
+LO_XOR = 0x6
+LO_OR = 0x7
+LO_NOR = 0x8
+LO_XNOR = 0x9
+LO_NDST = 0xa
+LO_ORR = 0xb
+LO_NSRC = 0xc
+LO_ORI = 0xd
+LO_NAND = 0xe
+LO_ONE = 0xf
+INFOCUSSCRN = -2
+ST_KEEP = 0
+ST_ZERO = 1
+ST_REPLACE = 2
+ST_INCR = 3
+ST_DECR = 4
+ST_INVERT = 5
+SF_NEVER = 0
+SF_LESS = 1
+SF_EQUAL = 2
+SF_LEQUAL = 3
+SF_GREATER = 4
+SF_NOTEQUAL = 5
+SF_GEQUAL = 6
+SF_ALWAYS = 7
+SS_OFF = 0
+SS_DEPTH = 1
+PYM_FILL = 1
+PYM_POINT = 2
+PYM_LINE = 3
+PYM_HOLLOW = 4
+PYM_LINE_FAST = 5
+FG_OFF = 0
+FG_ON = 1
+FG_DEFINE = 2
+FG_VTX_EXP = 2
+FG_VTX_LIN = 3
+FG_PIX_EXP = 4
+FG_PIX_LIN = 5
+FG_VTX_EXP2 = 6
+FG_PIX_EXP2 = 7
+PM_SHIFT = 0
+PM_EXPAND = 1
+PM_C0 = 2
+PM_C1 = 3
+PM_ADD24 = 4
+PM_SIZE = 5
+PM_OFFSET = 6
+PM_STRIDE = 7
+PM_TTOB = 8
+PM_RTOL = 9
+PM_ZDATA = 10
+PM_WARP = 11
+PM_RDX = 12
+PM_RDY = 13
+PM_CDX = 14
+PM_CDY = 15
+PM_XSTART = 16
+PM_YSTART = 17
+PM_VO1 = 1000
+NAUTO = 0
+NNORMALIZE = 1
+AC_CLEAR = 0
+AC_ACCUMULATE = 1
+AC_CLEAR_ACCUMULATE = 2
+AC_RETURN = 3
+AC_MULT = 4
+AC_ADD = 5
+CP_OFF = 0
+CP_ON = 1
+CP_DEFINE = 2
+SB_RESET = 0
+SB_TRACK = 1
+SB_HOLD = 2
+RD_FREEZE = 0x00000001
+RD_ALPHAONE = 0x00000002
+RD_IGNORE_UNDERLAY = 0x00000004
+RD_IGNORE_OVERLAY = 0x00000008
+RD_IGNORE_PUP = 0x00000010
+RD_OFFSCREEN = 0x00000020
+GD_XPMAX = 0
+GD_YPMAX = 1
+GD_XMMAX = 2
+GD_YMMAX = 3
+GD_ZMIN = 4
+GD_ZMAX = 5
+GD_BITS_NORM_SNG_RED = 6
+GD_BITS_NORM_SNG_GREEN = 7
+GD_BITS_NORM_SNG_BLUE = 8
+GD_BITS_NORM_DBL_RED = 9
+GD_BITS_NORM_DBL_GREEN = 10
+GD_BITS_NORM_DBL_BLUE = 11
+GD_BITS_NORM_SNG_CMODE = 12
+GD_BITS_NORM_DBL_CMODE = 13
+GD_BITS_NORM_SNG_MMAP = 14
+GD_BITS_NORM_DBL_MMAP = 15
+GD_BITS_NORM_ZBUFFER = 16
+GD_BITS_OVER_SNG_CMODE = 17
+GD_BITS_UNDR_SNG_CMODE = 18
+GD_BITS_PUP_SNG_CMODE = 19
+GD_BITS_NORM_SNG_ALPHA = 21
+GD_BITS_NORM_DBL_ALPHA = 22
+GD_BITS_CURSOR = 23
+GD_OVERUNDER_SHARED = 24
+GD_BLEND = 25
+GD_CIFRACT = 26
+GD_CROSSHAIR_CINDEX = 27
+GD_DITHER = 28
+GD_LINESMOOTH_CMODE = 30
+GD_LINESMOOTH_RGB = 31
+GD_LOGICOP = 33
+GD_NSCRNS = 35
+GD_NURBS_ORDER = 36
+GD_NBLINKS = 37
+GD_NVERTEX_POLY = 39
+GD_PATSIZE_64 = 40
+GD_PNTSMOOTH_CMODE = 41
+GD_PNTSMOOTH_RGB = 42
+GD_PUP_TO_OVERUNDER = 43
+GD_READSOURCE = 44
+GD_READSOURCE_ZBUFFER = 48
+GD_STEREO = 50
+GD_SUBPIXEL_LINE = 51
+GD_SUBPIXEL_PNT = 52
+GD_SUBPIXEL_POLY = 53
+GD_TRIMCURVE_ORDER = 54
+GD_WSYS = 55
+GD_ZDRAW_GEOM = 57
+GD_ZDRAW_PIXELS = 58
+GD_SCRNTYPE = 61
+GD_TEXTPORT = 62
+GD_NMMAPS = 63
+GD_FRAMEGRABBER = 64
+GD_TIMERHZ = 66
+GD_DBBOX = 67
+GD_AFUNCTION = 68
+GD_ALPHA_OVERUNDER = 69
+GD_BITS_ACBUF = 70
+GD_BITS_ACBUF_HW = 71
+GD_BITS_STENCIL = 72
+GD_CLIPPLANES = 73
+GD_FOGVERTEX = 74
+GD_LIGHTING_TWOSIDE = 76
+GD_POLYMODE = 77
+GD_POLYSMOOTH = 78
+GD_SCRBOX = 79
+GD_TEXTURE = 80
+GD_FOGPIXEL = 81
+GD_TEXTURE_PERSP = 82
+GD_MUXPIPES = 83
+GD_NOLIMIT = -2
+GD_WSYS_NONE = 0
+GD_WSYS_4S = 1
+GD_SCRNTYPE_WM = 0
+GD_SCRNTYPE_NOWM = 1
+N_PIXEL_TOLERANCE = 1
+N_CULLING = 2
+N_DISPLAY = 3
+N_ERRORCHECKING = 4
+N_SUBDIVISIONS = 5
+N_S_STEPS = 6
+N_T_STEPS = 7
+N_TILES = 8
+N_TMP1 = 9
+N_TMP2 = 10
+N_TMP3 = 11
+N_TMP4 = 12
+N_TMP5 = 13
+N_TMP6 = 14
+N_FILL = 1.0
+N_OUTLINE_POLY = 2.0
+N_OUTLINE_PATCH = 5.0
+N_ISOLINE_S = 12.0
+N_ST = 0x8
+N_STW = 0xd
+N_XYZ = 0x4c
+N_XYZW = 0x51
+N_TEX = 0x88
+N_TEXW = 0x8d
+N_RGBA = 0xd0
+N_RGBAW = 0xd5
+N_P2D = 0x8
+N_P2DR = 0xd
+N_V3D = 0x4c
+N_V3DR = 0x51
+N_T2D = 0x88
+N_T2DR = 0x8d
+N_C4D = 0xd0
+N_C4DR = 0xd5
+LMNULL = 0.0
+MSINGLE = 0
+MPROJECTION = 1
+MVIEWING = 2
+MTEXTURE = 3
+MAXLIGHTS = 8
+MAXRESTRICTIONS = 4
+DEFMATERIAL = 0
+EMISSION = 1
+AMBIENT = 2
+DIFFUSE = 3
+SPECULAR = 4
+SHININESS = 5
+COLORINDEXES = 6
+ALPHA = 7
+DEFLIGHT = 100
+LCOLOR = 101
+POSITION = 102
+SPOTDIRECTION = 103
+SPOTLIGHT = 104
+DEFLMODEL = 200
+LOCALVIEWER = 201
+ATTENUATION = 202
+ATTENUATION2 = 203
+TWOSIDE = 204
+MATERIAL = 1000
+BACKMATERIAL = 1001
+LIGHT0 = 1100
+LIGHT1 = 1101
+LIGHT2 = 1102
+LIGHT3 = 1103
+LIGHT4 = 1104
+LIGHT5 = 1105
+LIGHT6 = 1106
+LIGHT7 = 1107
+LMODEL = 1200
+LMC_COLOR = 0
+LMC_EMISSION = 1
+LMC_AMBIENT = 2
+LMC_DIFFUSE = 3
+LMC_SPECULAR = 4
+LMC_AD = 5
+LMC_NULL = 6
+TX_MINFILTER = 0x100
+TX_MAGFILTER = 0x200
+TX_WRAP = 0x300
+TX_WRAP_S = 0x310
+TX_WRAP_T = 0x320
+TX_TILE = 0x400
+TX_BORDER = 0x500
+TX_NULL = 0x000
+TX_POINT = 0x110
+TX_BILINEAR = 0x220
+TX_MIPMAP = 0x120
+TX_MIPMAP_POINT = 0x121
+TX_MIPMAP_LINEAR = 0x122
+TX_MIPMAP_BILINEAR = 0x123
+TX_MIPMAP_TRILINEAR = 0x124
+TX_REPEAT = 0x301
+TX_CLAMP = 0x302
+TX_SELECT = 0x303
+TX_TEXTURE_0 = 0
+TV_MODULATE = 0x101
+TV_BLEND = 0x102
+TV_DECAL = 0x103
+TV_COLOR = 0x200
+TV_NULL = 0x000
+TV_ENV0 = 0
+TX_S = 0
+TX_T = 1
+TG_OFF = 0
+TG_ON = 1
+TG_CONTOUR = 2
+TG_LINEAR = 3
+TG_SPHEREMAP = 4
+TG_REFRACTMAP = 5
+DGLSINK = 0
+DGLLOCAL = 1
+DGLTSOCKET = 2
+DGL4DDN = 3
+PUP_CURSOR = PUP_COLOR
+FATAL = 1
+WARNING = 2
+ASK_CONT = 3
+ASK_RESTART = 4
+XMAXSCREEN = 1279
+YMAXSCREEN = 1023
+XMAXMEDIUM = 1023
+YMAXMEDIUM = 767
+XMAX170 = 645
+YMAX170 = 484
+XMAXPAL = 779
+YMAXPAL = 574

Added: vendor/Python/current/Lib/plat-irix6/GLWS.py
===================================================================
--- vendor/Python/current/Lib/plat-irix6/GLWS.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix6/GLWS.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,12 @@
+NOERROR = 0
+NOCONTEXT = -1
+NODISPLAY = -2
+NOWINDOW = -3
+NOGRAPHICS = -4
+NOTTOP = -5
+NOVISUAL = -6
+BUFSIZE = -7
+BADWINDOW = -8
+ALREADYBOUND = -100
+BINDFAILED = -101
+SETFAILED = -102

Added: vendor/Python/current/Lib/plat-irix6/IN.py
===================================================================
--- vendor/Python/current/Lib/plat-irix6/IN.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix6/IN.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,385 @@
+# Generated by h2py from /usr/include/netinet/in.h
+
+# Included from standards.h
+
+# Included from sgidefs.h
+_MIPS_ISA_MIPS1 = 1
+_MIPS_ISA_MIPS2 = 2
+_MIPS_ISA_MIPS3 = 3
+_MIPS_ISA_MIPS4 = 4
+_MIPS_SIM_ABI32 = 1
+_MIPS_SIM_NABI32 = 2
+_MIPS_SIM_ABI64 = 3
+
+# Included from sys/bsd_types.h
+
+# Included from sys/mkdev.h
+ONBITSMAJOR = 7
+ONBITSMINOR = 8
+OMAXMAJ = 0x7f
+OMAXMIN = 0xff
+NBITSMAJOR = 14
+NBITSMINOR = 18
+MAXMAJ = 0x1ff
+MAXMIN = 0x3ffff
+OLDDEV = 0
+NEWDEV = 1
+MKDEV_VER = NEWDEV
+def IS_STRING_SPEC_DEV(x): return ((dev_t)(x)==__makedev(MKDEV_VER, 0, 0))
+
+def major(dev): return __major(MKDEV_VER, dev)
+
+def minor(dev): return __minor(MKDEV_VER, dev)
+
+
+# Included from sys/select.h
+FD_SETSIZE = 1024
+__NBBY = 8
+
+# Included from string.h
+NULL = 0L
+NBBY = 8
+
+# Included from sys/endian.h
+LITTLE_ENDIAN = 1234
+BIG_ENDIAN = 4321
+PDP_ENDIAN = 3412
+_LITTLE_ENDIAN = 1234
+_BIG_ENDIAN = 4321
+_PDP_ENDIAN = 3412
+_BYTE_ORDER = _BIG_ENDIAN
+_BYTE_ORDER = _LITTLE_ENDIAN
+def ntohl(x): return (x)
+
+def ntohs(x): return (x)
+
+def htonl(x): return (x)
+
+def htons(x): return (x)
+
+def htonl(x): return ntohl(x)
+
+def htons(x): return ntohs(x)
+
+
+# Included from sys/types.h
+
+# Included from sys/pthread.h
+P_MYID = (-1)
+P_MYHOSTID = (-1)
+
+# Included from sys/cpumask.h
+MAXCPU = 128
+def CPUMASK_INDEX(bit): return ((bit) >> 6)
+
+def CPUMASK_SHFT(bit): return ((bit) & 0x3f)
+
+def CPUMASK_IS_ZERO(p): return ((p) == 0)
+
+def CPUMASK_IS_NONZERO(p): return ((p) != 0)
+
+
+# Included from sys/nodemask.h
+def CNODEMASK_IS_ZERO(p): return ((p) == 0)
+
+def CNODEMASK_IS_NONZERO(p): return ((p) != 0)
+
+IPPROTO_IP = 0
+IPPROTO_HOPOPTS = 0
+IPPROTO_ICMP = 1
+IPPROTO_IGMP = 2
+IPPROTO_GGP = 3
+IPPROTO_IPIP = 4
+IPPROTO_ENCAP = IPPROTO_IPIP
+IPPROTO_ST = 5
+IPPROTO_TCP = 6
+IPPROTO_UCL = 7
+IPPROTO_EGP = 8
+IPPROTO_IGP = 9
+IPPROTO_BBN_RCC_MON = 10
+IPPROTO_NVP_II = 11
+IPPROTO_PUP = 12
+IPPROTO_ARGUS = 13
+IPPROTO_EMCON = 14
+IPPROTO_XNET = 15
+IPPROTO_CHAOS = 16
+IPPROTO_UDP = 17
+IPPROTO_MUX = 18
+IPPROTO_DCN_MEAS = 19
+IPPROTO_HMP = 20
+IPPROTO_PRM = 21
+IPPROTO_IDP = 22
+IPPROTO_TRUNK_1 = 23
+IPPROTO_TRUNK_2 = 24
+IPPROTO_LEAF_1 = 25
+IPPROTO_LEAF_2 = 26
+IPPROTO_RDP = 27
+IPPROTO_IRTP = 28
+IPPROTO_TP = 29
+IPPROTO_NETBLT = 30
+IPPROTO_MFE_NSP = 31
+IPPROTO_MERIT_INP = 32
+IPPROTO_SEP = 33
+IPPROTO_3PC = 34
+IPPROTO_IDPR = 35
+IPPROTO_XTP = 36
+IPPROTO_DDP = 37
+IPPROTO_IDPR_CMTP = 38
+IPPROTO_TPPP = 39
+IPPROTO_IL = 40
+IPPROTO_IPV6 = 41
+IPPROTO_ROUTING = 43
+IPPROTO_FRAGMENT = 44
+IPPROTO_RSVP = 46
+IPPROTO_ESP = 50
+IPPROTO_AH = 51
+IPPROTO_ICMPV6 = 58
+IPPROTO_NONE = 59
+IPPROTO_DSTOPTS = 60
+IPPROTO_CFTP = 62
+IPPROTO_HELLO = 63
+IPPROTO_SAT_EXPAK = 64
+IPPROTO_KRYPTOLAN = 65
+IPPROTO_RVD = 66
+IPPROTO_IPPC = 67
+IPPROTO_SAT_MON = 69
+IPPROTO_VISA = 70
+IPPROTO_IPCV = 71
+IPPROTO_CPNX = 72
+IPPROTO_CPHB = 73
+IPPROTO_WSN = 74
+IPPROTO_PVP = 75
+IPPROTO_BR_SAT_MON = 76
+IPPROTO_ND = 77
+IPPROTO_WB_MON = 78
+IPPROTO_WB_EXPAK = 79
+IPPROTO_EON = 80
+IPPROTO_VMTP = 81
+IPPROTO_SECURE_VMTP = 82
+IPPROTO_VINES = 83
+IPPROTO_TTP = 84
+IPPROTO_NSFNET_IGP = 85
+IPPROTO_DGP = 86
+IPPROTO_TCF = 87
+IPPROTO_IGRP = 88
+IPPROTO_OSPF = 89
+IPPROTO_SPRITE_RPC = 90
+IPPROTO_LARP = 91
+IPPROTO_MTP = 92
+IPPROTO_AX25 = 93
+IPPROTO_SWIPE = 94
+IPPROTO_MICP = 95
+IPPROTO_AES_SP3_D = 96
+IPPROTO_ETHERIP = 97
+IPPROTO_ENCAPHDR = 98
+IPPROTO_RAW = 255
+IPPROTO_MAX = 256
+IPPROTO_STP = 257
+IPPORT_RESERVED = 1024
+IPPORT_MAXPORT = 65535
+INET_ADDRSTRLEN = 16
+INET6_ADDRSTRLEN = 46
+def IN_CLASSA(i): return (((__int32_t)(i) & 0x80000000) == 0)
+
+IN_CLASSA_NET = 0xff000000
+IN_CLASSA_NSHIFT = 24
+IN_CLASSA_HOST = 0x00ffffff
+IN_CLASSA_MAX = 128
+def IN_CLASSB(i): return (((__int32_t)(i) & 0xc0000000) == 0x80000000)
+
+IN_CLASSB_NET = 0xffff0000
+IN_CLASSB_NSHIFT = 16
+IN_CLASSB_HOST = 0x0000ffff
+IN_CLASSB_MAX = 65536
+def IN_CLASSC(i): return (((__int32_t)(i) & 0xe0000000) == 0xc0000000)
+
+IN_CLASSC_NET = 0xffffff00
+IN_CLASSC_NSHIFT = 8
+IN_CLASSC_HOST = 0x000000ff
+def IN_CLASSD(i): return (((__int32_t)(i) & 0xf0000000) == 0xe0000000)
+
+IN_CLASSD_NET = 0xf0000000
+IN_CLASSD_NSHIFT = 28
+IN_CLASSD_HOST = 0x0fffffff
+def IN_MULTICAST(i): return IN_CLASSD(i)
+
+def IN_EXPERIMENTAL(i): return (((__int32_t)(i) & 0xf0000000) == 0xf0000000)
+
+def IN_BADCLASS(i): return (((__int32_t)(i) & 0xf0000000) == 0xf0000000)
+
+INADDR_NONE = 0xffffffff
+IN_LOOPBACKNET = 127
+IPNGVERSION = 6
+IPV6_FLOWINFO_FLOWLABEL = 0x00ffffff
+IPV6_FLOWINFO_PRIORITY = 0x0f000000
+IPV6_FLOWINFO_PRIFLOW = 0x0fffffff
+IPV6_FLOWINFO_SRFLAG = 0x10000000
+IPV6_FLOWINFO_VERSION = 0xf0000000
+IPV6_PRIORITY_UNCHARACTERIZED = 0x00000000
+IPV6_PRIORITY_FILLER = 0x01000000
+IPV6_PRIORITY_UNATTENDED = 0x02000000
+IPV6_PRIORITY_RESERVED1 = 0x03000000
+IPV6_PRIORITY_BULK = 0x04000000
+IPV6_PRIORITY_RESERVED2 = 0x05000000
+IPV6_PRIORITY_INTERACTIVE = 0x06000000
+IPV6_PRIORITY_CONTROL = 0x07000000
+IPV6_PRIORITY_8 = 0x08000000
+IPV6_PRIORITY_9 = 0x09000000
+IPV6_PRIORITY_10 = 0x0a000000
+IPV6_PRIORITY_11 = 0x0b000000
+IPV6_PRIORITY_12 = 0x0c000000
+IPV6_PRIORITY_13 = 0x0d000000
+IPV6_PRIORITY_14 = 0x0e000000
+IPV6_PRIORITY_15 = 0x0f000000
+IPV6_SRFLAG_STRICT = 0x10000000
+IPV6_SRFLAG_LOOSE = 0x00000000
+IPV6_VERSION = 0x60000000
+IPV6_FLOWINFO_FLOWLABEL = 0xffffff00
+IPV6_FLOWINFO_PRIORITY = 0x0000000f
+IPV6_FLOWINFO_PRIFLOW = 0xffffff0f
+IPV6_FLOWINFO_SRFLAG = 0x00000010
+IPV6_FLOWINFO_VERSION = 0x000000f0
+IPV6_PRIORITY_UNCHARACTERIZED = 0x00000000
+IPV6_PRIORITY_FILLER = 0x00000001
+IPV6_PRIORITY_UNATTENDED = 0x00000002
+IPV6_PRIORITY_RESERVED1 = 0x00000003
+IPV6_PRIORITY_BULK = 0x00000004
+IPV6_PRIORITY_RESERVED2 = 0x00000005
+IPV6_PRIORITY_INTERACTIVE = 0x00000006
+IPV6_PRIORITY_CONTROL = 0x00000007
+IPV6_PRIORITY_8 = 0x00000008
+IPV6_PRIORITY_9 = 0x00000009
+IPV6_PRIORITY_10 = 0x0000000a
+IPV6_PRIORITY_11 = 0x0000000b
+IPV6_PRIORITY_12 = 0x0000000c
+IPV6_PRIORITY_13 = 0x0000000d
+IPV6_PRIORITY_14 = 0x0000000e
+IPV6_PRIORITY_15 = 0x0000000f
+IPV6_SRFLAG_STRICT = 0x00000010
+IPV6_SRFLAG_LOOSE = 0x00000000
+IPV6_VERSION = 0x00000060
+def IPV6_GET_FLOWLABEL(x): return (ntohl(x) & 0x00ffffff)
+
+def IPV6_GET_PRIORITY(x): return ((ntohl(x) >> 24) & 0xf)
+
+def IPV6_GET_VERSION(x): return ((ntohl(x) >> 28) & 0xf)
+
+def IPV6_SET_FLOWLABEL(x): return (htonl(x) & IPV6_FLOWINFO_FLOWLABEL)
+
+def IPV6_SET_PRIORITY(x): return (htonl((x & 0xf) << 24))
+
+def CLR_ADDR6(a): return \
+
+def IS_ANYSOCKADDR(a): return \
+
+def IS_ANYADDR6(a): return \
+
+def IS_COMPATSOCKADDR(a): return \
+
+def IS_COMPATADDR6(a): return \
+
+def IS_LOOPSOCKADDR(a): return \
+
+def IS_LOOPADDR6(a): return \
+
+def IS_IPV4SOCKADDR(a): return \
+
+def IS_IPV4ADDR6(a): return \
+
+def IS_LOOPSOCKADDR(a): return \
+
+def IS_LOOPADDR6(a): return \
+
+def IS_IPV4SOCKADDR(a): return \
+
+def IS_IPV4ADDR6(a): return \
+
+def IS_LOCALADDR6(a): return ((a).s6_addr8[0] == 0xfe)
+
+def IS_LINKLADDR6(a): return \
+
+def IS_SITELADDR6(a): return \
+
+def IS_MULTIADDR6(a): return ((a).s6_addr8[0] == 0xff)
+
+def MADDR6_FLAGS(a): return ((a).s6_addr8[1] >> 4)
+
+MADDR6_FLG_WK = 0
+MADDR6_FLG_TS = 1
+def MADDR6_SCOPE(a): return ((a).s6_addr8[1] & 0x0f)
+
+MADDR6_SCP_NODE = 0x1
+MADDR6_SCP_LINK = 0x2
+MADDR6_SCP_SITE = 0x5
+MADDR6_SCP_ORG = 0x8
+MADDR6_SCP_GLO = 0xe
+MADDR6_ALLNODES = 1
+MADDR6_ALLROUTERS = 2
+MADDR6_ALLHOSTS = 3
+def IN6_IS_ADDR_UNSPECIFIED(p): return IS_ANYADDR6(*p)
+
+def IN6_IS_ADDR_LOOPBACK(p): return IS_LOOPADDR6(*p)
+
+def IN6_IS_ADDR_MULTICAST(p): return IS_MULTIADDR6(*p)
+
+def IN6_IS_ADDR_LINKLOCAL(p): return IS_LINKLADDR6(*p)
+
+def IN6_IS_ADDR_SITELOCAL(p): return IS_SITELADDR6(*p)
+
+def IN6_IS_ADDR_V4MAPPED(p): return IS_IPV4ADDR6(*p)
+
+def IN6_IS_ADDR_V4COMPAT(p): return IS_COMPATADDR6(*p)
+
+def IN6_IS_ADDR_MC_NODELOCAL(p): return \
+
+def IN6_IS_ADDR_MC_LINKLOCAL(p): return \
+
+def IN6_IS_ADDR_MC_SITELOCAL(p): return \
+
+def IN6_IS_ADDR_MC_ORGLOCAL(p): return \
+
+def IN6_IS_ADDR_MC_GLOBAL(p): return \
+
+IP_OPTIONS = 1
+IP_HDRINCL = 2
+IP_TOS = 3
+IP_TTL = 4
+IP_RECVOPTS = 5
+IP_RECVRETOPTS = 6
+IP_RECVDSTADDR = 7
+IP_RETOPTS = 8
+IP_MULTICAST_IF = 20
+IP_MULTICAST_TTL = 21
+IP_MULTICAST_LOOP = 22
+IP_ADD_MEMBERSHIP = 23
+IP_DROP_MEMBERSHIP = 24
+IP_MULTICAST_VIF = 25
+IP_RSVP_VIF_ON = 26
+IP_RSVP_VIF_OFF = 27
+IP_RSVP_ON = 28
+IP_SENDSRCADDR = 36
+IPV6_UNICAST_HOPS = IP_TTL
+IPV6_MULTICAST_IF = IP_MULTICAST_IF
+IPV6_MULTICAST_HOPS = IP_MULTICAST_TTL
+IPV6_MULTICAST_LOOP = IP_MULTICAST_LOOP
+IPV6_ADD_MEMBERSHIP = IP_ADD_MEMBERSHIP
+IPV6_DROP_MEMBERSHIP = IP_DROP_MEMBERSHIP
+IPV6_SENDIF = 40
+IPV6_NOPROBE = 42
+IPV6_RECVPKTINFO = 43
+IPV6_PKTINFO = 44
+IP_RECVTTL = 45
+IPV6_RECVHOPS = IP_RECVTTL
+IPV6_CHECKSUM = 46
+ICMP6_FILTER = 47
+IPV6_HOPLIMIT = 48
+IPV6_HOPOPTS = 49
+IPV6_DSTOPTS = 50
+IPV6_RTHDR = 51
+IPV6_PKTOPTIONS = 52
+IPV6_NEXTHOP = 53
+IP_DEFAULT_MULTICAST_TTL = 1
+IP_DEFAULT_MULTICAST_LOOP = 1
+IPV6_RTHDR_LOOSE = 0
+IPV6_RTHDR_STRICT = 1
+IPV6_RTHDR_TYPE_0 = 0

Added: vendor/Python/current/Lib/plat-irix6/IOCTL.py
===================================================================
--- vendor/Python/current/Lib/plat-irix6/IOCTL.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix6/IOCTL.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,233 @@
+# These lines were mostly generated by h2py.py (see demo/scripts)
+# from <sys/ioctl.h>, <sys/termio.h> and <termios.h> on Irix 4.0.2
+# with some manual changes to cope with imperfections in h2py.py.
+# The applicability on other systems is not clear; especially non-SYSV
+# systems may have a totally different set of ioctls.
+
+IOCTYPE = 0xff00
+LIOC = (ord('l')<<8)
+LIOCGETP = (LIOC|1)
+LIOCSETP = (LIOC|2)
+LIOCGETS = (LIOC|5)
+LIOCSETS = (LIOC|6)
+DIOC = (ord('d')<<8)
+DIOCGETC = (DIOC|1)
+DIOCGETB = (DIOC|2)
+DIOCSETE = (DIOC|3)
+IOCPARM_MASK = 0x7f
+IOC_VOID = 0x20000000
+IOC_OUT = 0x40000000
+IOC_IN = 0x80000000
+IOC_INOUT = (IOC_IN|IOC_OUT)
+int = 'i'
+short = 'h'
+long = 'l'
+def sizeof(t): import struct; return struct.calcsize(t)
+def _IO(x,y): return (IOC_VOID|((x)<<8)|y)
+def _IOR(x,y,t): return (IOC_OUT|((sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|y)
+def _IOW(x,y,t): return (IOC_IN|((sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|y)
+# this should be _IORW, but stdio got there first
+def _IOWR(x,y,t): return (IOC_INOUT|((sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|y)
+FIONREAD = _IOR(ord('f'), 127, int)
+FIONBIO = _IOW(ord('f'), 126, int)
+FIOASYNC = _IOW(ord('f'), 125, int)
+FIOSETOWN = _IOW(ord('f'), 124, int)
+FIOGETOWN = _IOR(ord('f'), 123, int)
+NCC = 8
+NCC_PAD = 7
+NCC_EXT = 16
+NCCS = (NCC+NCC_PAD+NCC_EXT)
+VINTR = 0
+VQUIT = 1
+VERASE = 2
+VKILL = 3
+VEOF = 4
+VEOL = 5
+VEOL2 = 6
+VMIN = VEOF
+VTIME = VEOL
+VSWTCH = 7
+VLNEXT = (NCC+NCC_PAD+0)
+VWERASE = (NCC+NCC_PAD+1)
+VRPRNT = (NCC+NCC_PAD+2)
+VFLUSHO = (NCC+NCC_PAD+3)
+VSTOP = (NCC+NCC_PAD+4)
+VSTART = (NCC+NCC_PAD+5)
+CNUL = '\0'
+CDEL = '\377'
+CESC = '\\'
+CINTR = '\177'
+CQUIT = '\34'
+CBRK = '\377'
+def CTRL(c): return ord(c) & 0x0f
+CERASE = CTRL('H')
+CKILL = CTRL('U')
+CEOF = CTRL('d')
+CEOT = CEOF
+CSTART = CTRL('q')
+CSTOP = CTRL('s')
+CSWTCH = CTRL('z')
+CSUSP = CSWTCH
+CNSWTCH = 0
+CLNEXT = CTRL('v')
+CWERASE = CTRL('w')
+CFLUSHO = CTRL('o')
+CFLUSH = CFLUSHO
+CRPRNT = CTRL('r')
+CDSUSP = CTRL('y')
+IGNBRK = 0000001
+BRKINT = 0000002
+IGNPAR = 0000004
+PARMRK = 0000010
+INPCK = 0000020
+ISTRIP = 0000040
+INLCR = 0000100
+IGNCR = 0000200
+ICRNL = 0000400
+IUCLC = 0001000
+IXON = 0002000
+IXANY = 0004000
+IXOFF = 0010000
+IBLKMD = 0020000
+OPOST = 0000001
+OLCUC = 0000002
+ONLCR = 0000004
+OCRNL = 0000010
+ONOCR = 0000020
+ONLRET = 0000040
+OFILL = 0000100
+OFDEL = 0000200
+NLDLY = 0000400
+NL0 = 0
+NL1 = 0000400
+CRDLY = 0003000
+CR0 = 0
+CR1 = 0001000
+CR2 = 0002000
+CR3 = 0003000
+TABDLY = 0014000
+TAB0 = 0
+TAB1 = 0004000
+TAB2 = 0010000
+TAB3 = 0014000
+BSDLY = 0020000
+BS0 = 0
+BS1 = 0020000
+VTDLY = 0040000
+VT0 = 0
+VT1 = 0040000
+FFDLY = 0100000
+FF0 = 0
+FF1 = 0100000
+CBAUD = 0000017
+B0 = 0
+B50 = 0000001
+B75 = 0000002
+B110 = 0000003
+B134 = 0000004
+B150 = 0000005
+B200 = 0000006
+B300 = 0000007
+B600 = 0000010
+B1200 = 0000011
+B1800 = 0000012
+B2400 = 0000013
+B4800 = 0000014
+B9600 = 0000015
+B19200 = 0000016
+EXTA = 0000016
+B38400 = 0000017
+EXTB = 0000017
+CSIZE = 0000060
+CS5 = 0
+CS6 = 0000020
+CS7 = 0000040
+CS8 = 0000060
+CSTOPB = 0000100
+CREAD = 0000200
+PARENB = 0000400
+PARODD = 0001000
+HUPCL = 0002000
+CLOCAL = 0004000
+LOBLK = 0040000
+ISIG = 0000001
+ICANON = 0000002
+XCASE = 0000004
+ECHO = 0000010
+ECHOE = 0000020
+ECHOK = 0000040
+ECHONL = 0000100
+NOFLSH = 0000200
+IIEXTEN = 0000400
+ITOSTOP = 0001000
+SSPEED = B9600
+IOCTYPE = 0xff00
+TIOC = (ord('T')<<8)
+oTCGETA = (TIOC|1)
+oTCSETA = (TIOC|2)
+oTCSETAW = (TIOC|3)
+oTCSETAF = (TIOC|4)
+TCSBRK = (TIOC|5)
+TCXONC = (TIOC|6)
+TCFLSH = (TIOC|7)
+TCGETA = (TIOC|8)
+TCSETA = (TIOC|9)
+TCSETAW = (TIOC|10)
+TCSETAF = (TIOC|11)
+TIOCFLUSH = (TIOC|12)
+TCDSET = (TIOC|32)
+TCBLKMD = (TIOC|33)
+TIOCPKT = (TIOC|112)
+TIOCPKT_DATA = 0x00
+TIOCPKT_FLUSHREAD = 0x01
+TIOCPKT_FLUSHWRITE = 0x02
+TIOCPKT_NOSTOP = 0x10
+TIOCPKT_DOSTOP = 0x20
+TIOCNOTTY = (TIOC|113)
+TIOCSTI = (TIOC|114)
+TIOCSPGRP = _IOW(ord('t'), 118, int)
+TIOCGPGRP = _IOR(ord('t'), 119, int)
+TIOCCONS = _IOW(ord('t'), 120, int)
+struct_winsize = 'hhhh'
+TIOCGWINSZ = _IOR(ord('t'), 104, struct_winsize)
+TIOCSWINSZ = _IOW(ord('t'), 103, struct_winsize)
+TFIOC = (ord('F')<<8)
+oFIONREAD = (TFIOC|127)
+LDIOC = (ord('D')<<8)
+LDOPEN = (LDIOC|0)
+LDCLOSE = (LDIOC|1)
+LDCHG = (LDIOC|2)
+LDGETT = (LDIOC|8)
+LDSETT = (LDIOC|9)
+TERM_NONE = 0
+TERM_TEC = 1
+TERM_V61 = 2
+TERM_V10 = 3
+TERM_TEX = 4
+TERM_D40 = 5
+TERM_H45 = 6
+TERM_D42 = 7
+TM_NONE = 0000
+TM_SNL = 0001
+TM_ANL = 0002
+TM_LCF = 0004
+TM_CECHO = 0010
+TM_CINVIS = 0020
+TM_SET = 0200
+LDISC0 = 0
+LDISC1 = 1
+NTTYDISC = LDISC1
+VSUSP = VSWTCH
+TCSANOW = 0
+TCSADRAIN = 1
+TCSAFLUSH = 2
+TCIFLUSH = 0
+TCOFLUSH = 1
+TCIOFLUSH = 2
+TCOOFF = 0
+TCOON = 1
+TCIOFF = 2
+TCION = 3
+TO_STOP = LOBLK
+IEXTEN = IIEXTEN
+TOSTOP = ITOSTOP

Added: vendor/Python/current/Lib/plat-irix6/SV.py
===================================================================
--- vendor/Python/current/Lib/plat-irix6/SV.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix6/SV.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,120 @@
+NTSC_XMAX = 640
+NTSC_YMAX = 480
+PAL_XMAX = 768
+PAL_YMAX = 576
+BLANKING_BUFFER_SIZE = 2
+
+MAX_SOURCES = 2
+
+# mode parameter for Bind calls
+IN_OFF = 0                              # No Video
+IN_OVER = 1                             # Video over graphics
+IN_UNDER = 2                            # Video under graphics
+IN_REPLACE = 3                          # Video replaces entire win
+
+# mode parameters for LoadMap calls.  Specifies buffer, always 256 entries
+INPUT_COLORMAP = 0                      # tuples of 8-bit RGB
+CHROMA_KEY_MAP = 1                      # tuples of 8-bit RGB
+COLOR_SPACE_MAP = 2                     # tuples of 8-bit RGB
+GAMMA_MAP = 3                           # tuples of 24-bit red values
+
+# mode parameters for UseExclusive calls
+INPUT = 0
+OUTPUT = 1
+IN_OUT = 2
+
+# Format constants for the capture routines
+RGB8_FRAMES = 0                         # noninterleaved 8 bit 3:2:3 RBG fields
+RGB32_FRAMES = 1                        # 32-bit 8:8:8 RGB frames
+YUV411_FRAMES = 2                       # interleaved, 8:2:2 YUV format
+YUV411_FRAMES_AND_BLANKING_BUFFER = 3
+
+#
+# sv.SetParam is passed variable length argument lists,
+# consisting of <name, value> pairs.   The following
+# constants identify argument names.
+#
+_NAME_BASE = 1000
+SOURCE = (_NAME_BASE + 0)
+SOURCE1 = 0
+SOURCE2 = 1
+SOURCE3 = 2
+COLOR = (_NAME_BASE + 1)
+DEFAULT_COLOR = 0
+USER_COLOR = 1
+MONO = 2
+OUTPUTMODE = (_NAME_BASE + 2)
+LIVE_OUTPUT = 0
+STILL24_OUT = 1
+FREEZE = (_NAME_BASE + 3)
+DITHER = (_NAME_BASE + 4)
+OUTPUT_FILTER = (_NAME_BASE + 5)
+HUE = (_NAME_BASE + 6)
+GENLOCK = (_NAME_BASE + 7)
+GENLOCK_OFF = 0
+GENLOCK_ON = 1
+GENLOCK_HOUSE = 2
+BROADCAST = (_NAME_BASE + 8)
+NTSC = 0
+PAL = 1
+VIDEO_MODE = (_NAME_BASE + 9)
+COMP = 0
+SVIDEO = 1
+INPUT_BYPASS = (_NAME_BASE + 10)
+FIELDDROP = (_NAME_BASE + 11)
+SLAVE = (_NAME_BASE + 12)
+APERTURE_FACTOR = (_NAME_BASE + 13)
+AFACTOR_0 = 0
+AFACTOR_QTR = 1
+AFACTOR_HLF = 2
+AFACTOR_ONE = 3
+CORING = (_NAME_BASE + 14)
+COR_OFF = 0
+COR_1LSB = 1
+COR_2LSB = 2
+COR_3LSB = 3
+APERTURE_BANDPASS = (_NAME_BASE + 15)
+ABAND_F0 = 0
+ABAND_F1 = 1
+ABAND_F2 = 2
+ABAND_F3 = 3
+PREFILTER = (_NAME_BASE + 16)
+CHROMA_TRAP = (_NAME_BASE + 17)
+CK_THRESHOLD = (_NAME_BASE + 18)
+PAL_SENSITIVITY = (_NAME_BASE + 19)
+GAIN_CONTROL = (_NAME_BASE + 20)
+GAIN_SLOW = 0
+GAIN_MEDIUM = 1
+GAIN_FAST = 2
+GAIN_FROZEN = 3
+AUTO_CKILL = (_NAME_BASE + 21)
+VTR_MODE = (_NAME_BASE + 22)
+VTR_INPUT = 0
+CAMERA_INPUT = 1
+LUMA_DELAY = (_NAME_BASE + 23)
+VNOISE = (_NAME_BASE + 24)
+VNOISE_NORMAL = 0
+VNOISE_SEARCH = 1
+VNOISE_AUTO = 2
+VNOISE_BYPASS = 3
+CHCV_PAL = (_NAME_BASE + 25)
+CHCV_NTSC = (_NAME_BASE + 26)
+CCIR_LEVELS = (_NAME_BASE + 27)
+STD_CHROMA = (_NAME_BASE + 28)
+DENC_VTBYPASS = (_NAME_BASE + 29)
+FAST_TIMECONSTANT = (_NAME_BASE + 30)
+GENLOCK_DELAY = (_NAME_BASE + 31)
+PHASE_SYNC = (_NAME_BASE + 32)
+VIDEO_OUTPUT = (_NAME_BASE + 33)
+CHROMA_PHASEOUT = (_NAME_BASE + 34)
+CHROMA_CENTER = (_NAME_BASE + 35)
+YUV_TO_RGB_INVERT = (_NAME_BASE + 36)
+SOURCE1_BROADCAST = (_NAME_BASE + 37)
+SOURCE1_MODE = (_NAME_BASE + 38)
+SOURCE2_BROADCAST = (_NAME_BASE + 39)
+SOURCE2_MODE = (_NAME_BASE + 40)
+SOURCE3_BROADCAST = (_NAME_BASE + 41)
+SOURCE3_MODE = (_NAME_BASE + 42)
+SIGNAL_STD = (_NAME_BASE + 43)
+NOSIGNAL = 2
+SIGNAL_COLOR = (_NAME_BASE + 44)

Added: vendor/Python/current/Lib/plat-irix6/WAIT.py
===================================================================
--- vendor/Python/current/Lib/plat-irix6/WAIT.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix6/WAIT.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,335 @@
+# Generated by h2py from /usr/include/sys/wait.h
+
+# Included from standards.h
+def _W_INT(i): return (i)
+
+WUNTRACED = 0004
+WNOHANG = 0100
+_WSTOPPED = 0177
+def WIFEXITED(stat): return ((_W_INT(stat)&0377)==0)
+
+def WEXITSTATUS(stat): return ((_W_INT(stat)>>8)&0377)
+
+def WTERMSIG(stat): return (_W_INT(stat)&0177)
+
+def WSTOPSIG(stat): return ((_W_INT(stat)>>8)&0377)
+
+WEXITED = 0001
+WTRAPPED = 0002
+WSTOPPED = 0004
+WCONTINUED = 0010
+WNOWAIT = 0200
+WOPTMASK = (WEXITED|WTRAPPED|WSTOPPED|WCONTINUED|WNOHANG|WNOWAIT)
+WSTOPFLG = 0177
+WCONTFLG = 0177777
+WCOREFLAG = 0200
+WSIGMASK = 0177
+def WWORD(stat): return (_W_INT(stat)&0177777)
+
+def WIFCONTINUED(stat): return (WWORD(stat)==WCONTFLG)
+
+def WCOREDUMP(stat): return (_W_INT(stat) & WCOREFLAG)
+
+
+# Included from sys/types.h
+
+# Included from sgidefs.h
+_MIPS_ISA_MIPS1 = 1
+_MIPS_ISA_MIPS2 = 2
+_MIPS_ISA_MIPS3 = 3
+_MIPS_ISA_MIPS4 = 4
+_MIPS_SIM_ABI32 = 1
+_MIPS_SIM_NABI32 = 2
+_MIPS_SIM_ABI64 = 3
+P_MYID = (-1)
+P_MYHOSTID = (-1)
+
+# Included from sys/bsd_types.h
+
+# Included from sys/mkdev.h
+ONBITSMAJOR = 7
+ONBITSMINOR = 8
+OMAXMAJ = 0x7f
+OMAXMIN = 0xff
+NBITSMAJOR = 14
+NBITSMINOR = 18
+MAXMAJ = 0x1ff
+MAXMIN = 0x3ffff
+OLDDEV = 0
+NEWDEV = 1
+MKDEV_VER = NEWDEV
+def major(dev): return __major(MKDEV_VER, dev)
+
+def minor(dev): return __minor(MKDEV_VER, dev)
+
+
+# Included from sys/select.h
+FD_SETSIZE = 1024
+__NBBY = 8
+
+# Included from string.h
+NULL = 0L
+NBBY = 8
+
+# Included from sys/procset.h
+P_INITPID = 1
+P_INITUID = 0
+P_INITPGID = 0
+
+# Included from sys/signal.h
+SIGHUP = 1
+SIGINT = 2
+SIGQUIT = 3
+SIGILL = 4
+SIGTRAP = 5
+SIGIOT = 6
+SIGABRT = 6
+SIGEMT = 7
+SIGFPE = 8
+SIGKILL = 9
+SIGBUS = 10
+SIGSEGV = 11
+SIGSYS = 12
+SIGPIPE = 13
+SIGALRM = 14
+SIGTERM = 15
+SIGUSR1 = 16
+SIGUSR2 = 17
+SIGCLD = 18
+SIGCHLD = 18
+SIGPWR = 19
+SIGWINCH = 20
+SIGURG = 21
+SIGPOLL = 22
+SIGIO = 22
+SIGSTOP = 23
+SIGTSTP = 24
+SIGCONT = 25
+SIGTTIN = 26
+SIGTTOU = 27
+SIGVTALRM = 28
+SIGPROF = 29
+SIGXCPU = 30
+SIGXFSZ = 31
+SIG32 = 32
+SIGCKPT = 33
+SIGRTMIN = 49
+SIGRTMAX = 64
+SIGPTINTR = 47
+SIGPTRESCHED = 48
+__sigargs = int
+SIGEV_NONE = 128
+SIGEV_SIGNAL = 129
+SIGEV_CALLBACK = 130
+
+# Included from sys/siginfo.h
+ILL_ILLOPC = 1
+ILL_ILLOPN = 2
+ILL_ILLADR = 3
+ILL_ILLTRP = 4
+ILL_PRVOPC = 5
+ILL_PRVREG = 6
+ILL_COPROC = 7
+ILL_BADSTK = 8
+NSIGILL = 8
+FPE_INTDIV = 1
+FPE_INTOVF = 2
+FPE_FLTDIV = 3
+FPE_FLTOVF = 4
+FPE_FLTUND = 5
+FPE_FLTRES = 6
+FPE_FLTINV = 7
+FPE_FLTSUB = 8
+NSIGFPE = 8
+SEGV_MAPERR = 1
+SEGV_ACCERR = 2
+NSIGSEGV = 2
+BUS_ADRALN = 1
+BUS_ADRERR = 2
+BUS_OBJERR = 3
+NSIGBUS = 3
+TRAP_BRKPT = 1
+TRAP_TRACE = 2
+NSIGTRAP = 2
+CLD_EXITED = 1
+CLD_KILLED = 2
+CLD_DUMPED = 3
+CLD_TRAPPED = 4
+CLD_STOPPED = 5
+CLD_CONTINUED = 6
+NSIGCLD = 6
+POLL_IN = 1
+POLL_OUT = 2
+POLL_MSG = 3
+POLL_ERR = 4
+POLL_PRI = 5
+POLL_HUP = 6
+NSIGPOLL = 6
+SI_MAXSZ = 128
+SI_USER = 0
+SI_KILL = SI_USER
+SI_QUEUE = -1
+SI_ASYNCIO = -2
+SI_TIMER = -3
+SI_MESGQ = -4
+SIG_NOP = 0
+SIG_BLOCK = 1
+SIG_UNBLOCK = 2
+SIG_SETMASK = 3
+SIG_SETMASK32 = 256
+SA_ONSTACK = 0x00000001
+SA_RESETHAND = 0x00000002
+SA_RESTART = 0x00000004
+SA_SIGINFO = 0x00000008
+SA_NODEFER = 0x00000010
+SA_NOCLDWAIT = 0x00010000
+SA_NOCLDSTOP = 0x00020000
+_SA_BSDCALL = 0x10000000
+MINSIGSTKSZ = 512
+SIGSTKSZ = 8192
+SS_ONSTACK = 0x00000001
+SS_DISABLE = 0x00000002
+
+# Included from sys/ucontext.h
+NGREG = 36
+NGREG = 37
+GETCONTEXT = 0
+SETCONTEXT = 1
+UC_SIGMASK = 001
+UC_STACK = 002
+UC_CPU = 004
+UC_MAU = 010
+UC_MCONTEXT = (UC_CPU|UC_MAU)
+UC_ALL = (UC_SIGMASK|UC_STACK|UC_MCONTEXT)
+CTX_R0 = 0
+CTX_AT = 1
+CTX_V0 = 2
+CTX_V1 = 3
+CTX_A0 = 4
+CTX_A1 = 5
+CTX_A2 = 6
+CTX_A3 = 7
+CTX_T0 = 8
+CTX_T1 = 9
+CTX_T2 = 10
+CTX_T3 = 11
+CTX_T4 = 12
+CTX_T5 = 13
+CTX_T6 = 14
+CTX_T7 = 15
+CTX_A4 = 8
+CTX_A5 = 9
+CTX_A6 = 10
+CTX_A7 = 11
+CTX_T0 = 12
+CTX_T1 = 13
+CTX_T2 = 14
+CTX_T3 = 15
+CTX_S0 = 16
+CTX_S1 = 17
+CTX_S2 = 18
+CTX_S3 = 19
+CTX_S4 = 20
+CTX_S5 = 21
+CTX_S6 = 22
+CTX_S7 = 23
+CTX_T8 = 24
+CTX_T9 = 25
+CTX_K0 = 26
+CTX_K1 = 27
+CTX_GP = 28
+CTX_SP = 29
+CTX_S8 = 30
+CTX_RA = 31
+CTX_MDLO = 32
+CTX_MDHI = 33
+CTX_CAUSE = 34
+CTX_EPC = 35
+CTX_SR = 36
+CXT_R0 = CTX_R0
+CXT_AT = CTX_AT
+CXT_V0 = CTX_V0
+CXT_V1 = CTX_V1
+CXT_A0 = CTX_A0
+CXT_A1 = CTX_A1
+CXT_A2 = CTX_A2
+CXT_A3 = CTX_A3
+CXT_T0 = CTX_T0
+CXT_T1 = CTX_T1
+CXT_T2 = CTX_T2
+CXT_T3 = CTX_T3
+CXT_T4 = CTX_T4
+CXT_T5 = CTX_T5
+CXT_T6 = CTX_T6
+CXT_T7 = CTX_T7
+CXT_S0 = CTX_S0
+CXT_S1 = CTX_S1
+CXT_S2 = CTX_S2
+CXT_S3 = CTX_S3
+CXT_S4 = CTX_S4
+CXT_S5 = CTX_S5
+CXT_S6 = CTX_S6
+CXT_S7 = CTX_S7
+CXT_T8 = CTX_T8
+CXT_T9 = CTX_T9
+CXT_K0 = CTX_K0
+CXT_K1 = CTX_K1
+CXT_GP = CTX_GP
+CXT_SP = CTX_SP
+CXT_S8 = CTX_S8
+CXT_RA = CTX_RA
+CXT_MDLO = CTX_MDLO
+CXT_MDHI = CTX_MDHI
+CXT_CAUSE = CTX_CAUSE
+CXT_EPC = CTX_EPC
+CXT_SR = CTX_SR
+SV_ONSTACK = 0x0001
+SV_INTERRUPT = 0x0002
+NUMBSDSIGS = (32)
+def sigmask(sig): return (1L << ((sig)-1))
+
+def sigmask(sig): return (1L << ((sig)-1))
+
+SIG_ERR = (-1)
+SIG_IGN = (1)
+SIG_HOLD = (2)
+SIG_DFL = (0)
+NSIG = 65
+MAXSIG = (NSIG-1)
+NUMSIGS = (NSIG-1)
+BRK_USERBP = 0
+BRK_KERNELBP = 1
+BRK_ABORT = 2
+BRK_BD_TAKEN = 3
+BRK_BD_NOTTAKEN = 4
+BRK_SSTEPBP = 5
+BRK_OVERFLOW = 6
+BRK_DIVZERO = 7
+BRK_RANGE = 8
+BRK_PSEUDO_OP_BIT = 0x80
+BRK_PSEUDO_OP_MAX = 0x3
+BRK_CACHE_SYNC = 0x80
+BRK_SWASH_FLUSH = 0x81
+BRK_SWASH_SWTCH = 0x82
+BRK_MULOVF = 1023
+
+# Included from sys/resource.h
+PRIO_MIN = -20
+PRIO_MAX = 20
+PRIO_PROCESS = 0
+PRIO_PGRP = 1
+PRIO_USER = 2
+RUSAGE_SELF = 0
+RUSAGE_CHILDREN = -1
+RLIMIT_CPU = 0
+RLIMIT_FSIZE = 1
+RLIMIT_DATA = 2
+RLIMIT_STACK = 3
+RLIMIT_CORE = 4
+RLIMIT_NOFILE = 5
+RLIMIT_VMEM = 6
+RLIMIT_RSS = 7
+RLIMIT_AS = RLIMIT_VMEM
+RLIM_NLIMITS = 8
+RLIM32_INFINITY = 0x7fffffff
+RLIM_INFINITY = 0x7fffffff

Added: vendor/Python/current/Lib/plat-irix6/cddb.py
===================================================================
--- vendor/Python/current/Lib/plat-irix6/cddb.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix6/cddb.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,204 @@
+# This file implements a class which forms an interface to the .cddb
+# directory that is maintained by SGI's cdman program.
+#
+# Usage is as follows:
+#
+# import readcd
+# r = readcd.Readcd()
+# c = Cddb(r.gettrackinfo())
+#
+# Now you can use c.artist, c.title and c.track[trackno] (where trackno
+# starts at 1).  When the CD is not recognized, all values will be the empty
+# string.
+# It is also possible to set the above mentioned variables to new values.
+# You can then use c.write() to write out the changed values to the
+# .cdplayerrc file.
+
+import string, posix, os
+
+_cddbrc = '.cddb'
+_DB_ID_NTRACKS = 5
+_dbid_map = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ at _=+abcdefghijklmnopqrstuvwxyz'
+def _dbid(v):
+    if v >= len(_dbid_map):
+        return string.zfill(v, 2)
+    else:
+        return _dbid_map[v]
+
+def tochash(toc):
+    if type(toc) == type(''):
+        tracklist = []
+        for i in range(2, len(toc), 4):
+            tracklist.append((None,
+                      (int(toc[i:i+2]),
+                       int(toc[i+2:i+4]))))
+    else:
+        tracklist = toc
+    ntracks = len(tracklist)
+    hash = _dbid((ntracks >> 4) & 0xF) + _dbid(ntracks & 0xF)
+    if ntracks <= _DB_ID_NTRACKS:
+        nidtracks = ntracks
+    else:
+        nidtracks = _DB_ID_NTRACKS - 1
+        min = 0
+        sec = 0
+        for track in tracklist:
+            start, length = track
+            min = min + length[0]
+            sec = sec + length[1]
+        min = min + sec / 60
+        sec = sec % 60
+        hash = hash + _dbid(min) + _dbid(sec)
+    for i in range(nidtracks):
+        start, length = tracklist[i]
+        hash = hash + _dbid(length[0]) + _dbid(length[1])
+    return hash
+
+class Cddb:
+    def __init__(self, tracklist):
+        if os.environ.has_key('CDDB_PATH'):
+            path = os.environ['CDDB_PATH']
+            cddb_path = path.split(',')
+        else:
+            home = os.environ['HOME']
+            cddb_path = [home + '/' + _cddbrc]
+
+        self._get_id(tracklist)
+
+        for dir in cddb_path:
+            file = dir + '/' + self.id + '.rdb'
+            try:
+                f = open(file, 'r')
+                self.file = file
+                break
+            except IOError:
+                pass
+        ntracks = int(self.id[:2], 16)
+        self.artist = ''
+        self.title = ''
+        self.track = [None] + [''] * ntracks
+        self.trackartist = [None] + [''] * ntracks
+        self.notes = []
+        if not hasattr(self, 'file'):
+            return
+        import re
+        reg = re.compile(r'^([^.]*)\.([^:]*):[\t ]+(.*)')
+        while 1:
+            line = f.readline()
+            if not line:
+                break
+            match = reg.match(line)
+            if not match:
+                print 'syntax error in ' + file
+                continue
+            name1, name2, value = match.group(1, 2, 3)
+            if name1 == 'album':
+                if name2 == 'artist':
+                    self.artist = value
+                elif name2 == 'title':
+                    self.title = value
+                elif name2 == 'toc':
+                    if not self.toc:
+                        self.toc = value
+                    if self.toc != value:
+                        print 'toc\'s don\'t match'
+                elif name2 == 'notes':
+                    self.notes.append(value)
+            elif name1[:5] == 'track':
+                try:
+                    trackno = int(name1[5:])
+                except ValueError:
+                    print 'syntax error in ' + file
+                    continue
+                if trackno > ntracks:
+                    print 'track number %r in file %s out of range' % (trackno, file)
+                    continue
+                if name2 == 'title':
+                    self.track[trackno] = value
+                elif name2 == 'artist':
+                    self.trackartist[trackno] = value
+        f.close()
+        for i in range(2, len(self.track)):
+            track = self.track[i]
+            # if track title starts with `,', use initial part
+            # of previous track's title
+            if track and track[0] == ',':
+                try:
+                    off = self.track[i - 1].index(',')
+                except ValueError:
+                    pass
+                else:
+                    self.track[i] = self.track[i-1][:off] \
+                                    + track
+
+    def _get_id(self, tracklist):
+        # fill in self.id and self.toc.
+        # if the argument is a string ending in .rdb, the part
+        # upto the suffix is taken as the id.
+        if type(tracklist) == type(''):
+            if tracklist[-4:] == '.rdb':
+                self.id = tracklist[:-4]
+                self.toc = ''
+                return
+            t = []
+            for i in range(2, len(tracklist), 4):
+                t.append((None, \
+                          (int(tracklist[i:i+2]), \
+                           int(tracklist[i+2:i+4]))))
+            tracklist = t
+        ntracks = len(tracklist)
+        self.id = _dbid((ntracks >> 4) & 0xF) + _dbid(ntracks & 0xF)
+        if ntracks <= _DB_ID_NTRACKS:
+            nidtracks = ntracks
+        else:
+            nidtracks = _DB_ID_NTRACKS - 1
+            min = 0
+            sec = 0
+            for track in tracklist:
+                start, length = track
+                min = min + length[0]
+                sec = sec + length[1]
+            min = min + sec / 60
+            sec = sec % 60
+            self.id = self.id + _dbid(min) + _dbid(sec)
+        for i in range(nidtracks):
+            start, length = tracklist[i]
+            self.id = self.id + _dbid(length[0]) + _dbid(length[1])
+        self.toc = string.zfill(ntracks, 2)
+        for track in tracklist:
+            start, length = track
+            self.toc = self.toc + string.zfill(length[0], 2) + \
+                      string.zfill(length[1], 2)
+
+    def write(self):
+        import posixpath
+        if os.environ.has_key('CDDB_WRITE_DIR'):
+            dir = os.environ['CDDB_WRITE_DIR']
+        else:
+            dir = os.environ['HOME'] + '/' + _cddbrc
+        file = dir + '/' + self.id + '.rdb'
+        if posixpath.exists(file):
+            # make backup copy
+            posix.rename(file, file + '~')
+        f = open(file, 'w')
+        f.write('album.title:\t' + self.title + '\n')
+        f.write('album.artist:\t' + self.artist + '\n')
+        f.write('album.toc:\t' + self.toc + '\n')
+        for note in self.notes:
+            f.write('album.notes:\t' + note + '\n')
+        prevpref = None
+        for i in range(1, len(self.track)):
+            if self.trackartist[i]:
+                f.write('track%r.artist:\t%s\n' % (i, self.trackartist[i]))
+            track = self.track[i]
+            try:
+                off = track.index(',')
+            except ValueError:
+                prevpref = None
+            else:
+                if prevpref and track[:off] == prevpref:
+                    track = track[off:]
+                else:
+                    prevpref = track[:off]
+            f.write('track%r.title:\t%s\n' % (i, track))
+        f.close()

Added: vendor/Python/current/Lib/plat-irix6/cdplayer.py
===================================================================
--- vendor/Python/current/Lib/plat-irix6/cdplayer.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix6/cdplayer.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,88 @@
+# This file implements a class which forms an interface to the .cdplayerrc
+# file that is maintained by SGI's cdplayer program.
+#
+# Usage is as follows:
+#
+# import readcd
+# r = readcd.Readcd()
+# c = Cdplayer(r.gettrackinfo())
+#
+# Now you can use c.artist, c.title and c.track[trackno] (where trackno
+# starts at 1).  When the CD is not recognized, all values will be the empty
+# string.
+# It is also possible to set the above mentioned variables to new values.
+# You can then use c.write() to write out the changed values to the
+# .cdplayerrc file.
+
+cdplayerrc = '.cdplayerrc'
+
+class Cdplayer:
+    def __init__(self, tracklist):
+        import string
+        self.artist = ''
+        self.title = ''
+        if type(tracklist) == type(''):
+            t = []
+            for i in range(2, len(tracklist), 4):
+                t.append((None, \
+                          (int(tracklist[i:i+2]), \
+                           int(tracklist[i+2:i+4]))))
+            tracklist = t
+        self.track = [None] + [''] * len(tracklist)
+        self.id = 'd' + string.zfill(len(tracklist), 2)
+        for track in tracklist:
+            start, length = track
+            self.id = self.id + string.zfill(length[0], 2) + \
+                      string.zfill(length[1], 2)
+        try:
+            import posix
+            f = open(posix.environ['HOME'] + '/' + cdplayerrc, 'r')
+        except IOError:
+            return
+        import re
+        reg = re.compile(r'^([^:]*):\t(.*)')
+        s = self.id + '.'
+        l = len(s)
+        while 1:
+            line = f.readline()
+            if line == '':
+                break
+            if line[:l] == s:
+                line = line[l:]
+                match = reg.match(line)
+                if not match:
+                    print 'syntax error in ~/' + cdplayerrc
+                    continue
+                name, value = match.group(1, 2)
+                if name == 'title':
+                    self.title = value
+                elif name == 'artist':
+                    self.artist = value
+                elif name[:5] == 'track':
+                    trackno = int(name[6:])
+                    self.track[trackno] = value
+        f.close()
+
+    def write(self):
+        import posix
+        filename = posix.environ['HOME'] + '/' + cdplayerrc
+        try:
+            old = open(filename, 'r')
+        except IOError:
+            old = open('/dev/null', 'r')
+        new = open(filename + '.new', 'w')
+        s = self.id + '.'
+        l = len(s)
+        while 1:
+            line = old.readline()
+            if line == '':
+                break
+            if line[:l] != s:
+                new.write(line)
+        new.write(self.id + '.title:\t' + self.title + '\n')
+        new.write(self.id + '.artist:\t' + self.artist + '\n')
+        for i in range(1, len(self.track)):
+            new.write('%s.track.%r:\t%s\n' % (i, track))
+        old.close()
+        new.close()
+        posix.rename(filename + '.new', filename)

Added: vendor/Python/current/Lib/plat-irix6/flp.doc
===================================================================
--- vendor/Python/current/Lib/plat-irix6/flp.doc	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix6/flp.doc	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,117 @@
+.SH
+Module flp
+.LP
+The flp module loads fl-forms from fd files, as generated
+by fdesign. The module is designed to be flexible enough to allow
+almost anything to be done with the loaded form.
+.LP
+Loadform defines 
+two types of functions: functions to parse fd files and functions to
+create the forms from the templates returned by the parse functions.
+There are fairly low-level create functions that create single objects,
+and convenience routines that create complete forms, including callbacks,
+etc.
+.LP
+The exception flp.error is raised whenever an error occurs while parsing a forms
+definition file or creating a form.
+.SH 2
+Parsing functions
+.LP
+There are two parsing functions, parse_form() and parse_forms(). They
+take the following form:
+.LP
+.ft C
+ftuple = parse_form(filename, formname)
+.br
+ftdict = parse_forms(filename)
+.IP
+Parse_form parses a single form, and returns a tuple (ftmp, otmplist).
+Ftmp is a template for a form, otmplist is a list of templates for
+objects. See below for a description of these templates.
+.IP
+Parse_forms parses all forms in an fd file. It returns a dictionary of
+(ftmp, otmplist) tuples, indexed by formname.
+.IP
+Filename is the name of the forms definition file to inspect. The functions
+appends '.fd' if needed, and use 'sys.path' to locate the file.
+.IP
+formname is the name of the form to load. This argument is mandatory,
+even if the file only contains one form.
+.LP
+The form template and object template are structures that contain all
+the information read from the fd file, in 'natural' form. A form
+template record contains the following fields:
+.IP
+.nf
+"Name", the name of the form;
+"Width", the width of the form;
+"Height", the height of the form; and
+"Numberofobjects", the number of objects in the form.
+.LP
+An object template contains the following fields:
+.IP
+.nf
+"Class", the class of object (eg. FL.BUTTON);
+"Type", the sub-class (eg. FL.NORMALBUTTON);
+"Box", a list with four members: [x, y, width, height];
+"Boxtype", the type of box (eg. FL.DOWNBOX);
+"Colors", a list with the two object colors;
+"Alignment", the label alignment (eg. FL.ALIGNLEFT); 
+"Style", the label style (eg. FL.BOLDSTYLE);
+"Lcol", the label color;
+"Label", a string containing the label;
+"Name", a string containing the name of the object;
+"Callback", a string containing the callback routine name; and
+"Argument", a string containing the callback routine extra argument.
+.SH
+Low-level create routines.
+.LP
+The three low-level creation routines are called as follows:
+.LP
+.ft C
+form = create_form(form_template)
+.IP
+Create an fl form from a form template. Returns the form created.
+.LP
+.ft C
+obj = create_object(form, obj_template)
+.IP
+Create an object in an fl form. Return the new object.
+An error is raised if the object has a callback routine.
+.SH
+High-level create routines.
+.LP
+The 'standard' way to handle forms in python is to define a class
+that contains the form and all the objects (insofar as they are named),
+and that defines all the callback functions, and use an instance of
+this class to handle the form interaction.
+Flp contains three routines that simplify handling this paradigm:
+.LP
+.ft C
+create_full_form(instance, ftuple)
+.IP
+This routine takes an instance of your form-handling class and an
+ftuple (as returned by the parsing routines) as parameters. It inserts
+the form into the instance, defines all object names and arranges that
+the callback methods are called. All the names inserted into the
+instance are the same as the names used for the objects, etc. in the
+fd file.
+.LP
+.ft C
+merge_full_form(instance, form, ftuple)
+.IP
+This function does the same as create_full_form, only it does not create
+the form itself nor the 'background box' that fdesign automatically
+adds to each form. This is useful if your class inherits a superclass
+that already defines a skeleton form (with 'OK' and 'Cancel' buttons,
+for instance), and you want to merge the new form into that existing
+form. The 'form' parameter is the form to which the new objects are
+added.
+.LP
+If you use the paradigm sketched here but need slightly more control
+over object creation there is a routine that creates a single object
+and inserts its name (and arranges for the callback routine to be
+called):
+.LP
+.ft C
+create_object_instance(instance, form, obj_template)

Added: vendor/Python/current/Lib/plat-irix6/flp.py
===================================================================
--- vendor/Python/current/Lib/plat-irix6/flp.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix6/flp.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,450 @@
+#
+# flp - Module to load fl forms from fd files
+#
+# Jack Jansen, December 1991
+#
+import os
+import sys
+import FL
+
+SPLITLINE = '--------------------'
+FORMLINE = '=============== FORM ==============='
+ENDLINE = '=============================='
+
+class error(Exception):
+    pass
+
+##################################################################
+#    Part 1 - The parsing routines                               #
+##################################################################
+
+#
+# Externally visible function. Load form.
+#
+def parse_form(filename, formname):
+    forms = checkcache(filename)
+    if forms is None:
+        forms = parse_forms(filename)
+    if forms.has_key(formname):
+        return forms[formname]
+    else:
+        raise error, 'No such form in fd file'
+
+#
+# Externally visible function. Load all forms.
+#
+def parse_forms(filename):
+    forms = checkcache(filename)
+    if forms is not None: return forms
+    fp = _open_formfile(filename)
+    nforms = _parse_fd_header(fp)
+    forms = {}
+    for i in range(nforms):
+        form = _parse_fd_form(fp, None)
+        forms[form[0].Name] = form
+    writecache(filename, forms)
+    return forms
+
+#
+# Internal: see if a cached version of the file exists
+#
+MAGIC = '.fdc'
+_internal_cache = {}                    # Used by frozen scripts only
+def checkcache(filename):
+    if _internal_cache.has_key(filename):
+        altforms = _internal_cache[filename]
+        return _unpack_cache(altforms)
+    import marshal
+    fp, filename = _open_formfile2(filename)
+    fp.close()
+    cachename = filename + 'c'
+    try:
+        fp = open(cachename, 'r')
+    except IOError:
+        #print 'flp: no cache file', cachename
+        return None
+    try:
+        if fp.read(4) != MAGIC:
+            print 'flp: bad magic word in cache file', cachename
+            return None
+        cache_mtime = rdlong(fp)
+        file_mtime = getmtime(filename)
+        if cache_mtime != file_mtime:
+            #print 'flp: outdated cache file', cachename
+            return None
+        #print 'flp: valid cache file', cachename
+        altforms = marshal.load(fp)
+        return _unpack_cache(altforms)
+    finally:
+        fp.close()
+
+def _unpack_cache(altforms):
+    forms = {}
+    for name in altforms.keys():
+        altobj, altlist = altforms[name]
+        obj = _newobj()
+        obj.make(altobj)
+        list = []
+        for altobj in altlist:
+            nobj = _newobj()
+            nobj.make(altobj)
+            list.append(nobj)
+        forms[name] = obj, list
+    return forms
+
+def rdlong(fp):
+    s = fp.read(4)
+    if len(s) != 4: return None
+    a, b, c, d = s[0], s[1], s[2], s[3]
+    return ord(a)<<24 | ord(b)<<16 | ord(c)<<8 | ord(d)
+
+def wrlong(fp, x):
+    a, b, c, d = (x>>24)&0xff, (x>>16)&0xff, (x>>8)&0xff, x&0xff
+    fp.write(chr(a) + chr(b) + chr(c) + chr(d))
+
+def getmtime(filename):
+    import os
+    from stat import ST_MTIME
+    try:
+        return os.stat(filename)[ST_MTIME]
+    except os.error:
+        return None
+
+#
+# Internal: write cached version of the form (parsing is too slow!)
+#
+def writecache(filename, forms):
+    import marshal
+    fp, filename = _open_formfile2(filename)
+    fp.close()
+    cachename = filename + 'c'
+    try:
+        fp = open(cachename, 'w')
+    except IOError:
+        print 'flp: can\'t create cache file', cachename
+        return # Never mind
+    fp.write('\0\0\0\0') # Seek back and write MAGIC when done
+    wrlong(fp, getmtime(filename))
+    altforms = _pack_cache(forms)
+    marshal.dump(altforms, fp)
+    fp.seek(0)
+    fp.write(MAGIC)
+    fp.close()
+    #print 'flp: wrote cache file', cachename
+
+#
+# External: print some statements that set up the internal cache.
+# This is for use with the "freeze" script.  You should call
+# flp.freeze(filename) for all forms used by the script, and collect
+# the output on a file in a module file named "frozenforms.py".  Then
+# in the main program of the script import frozenforms.
+# (Don't forget to take this out when using the unfrozen version of
+# the script!)
+#
+def freeze(filename):
+    forms = parse_forms(filename)
+    altforms = _pack_cache(forms)
+    print 'import flp'
+    print 'flp._internal_cache[', repr(filename), '] =', altforms
+
+#
+# Internal: create the data structure to be placed in the cache
+#
+def _pack_cache(forms):
+    altforms = {}
+    for name in forms.keys():
+        obj, list = forms[name]
+        altobj = obj.__dict__
+        altlist = []
+        for obj in list: altlist.append(obj.__dict__)
+        altforms[name] = altobj, altlist
+    return altforms
+
+#
+# Internal: Locate form file (using PYTHONPATH) and open file
+#
+def _open_formfile(filename):
+    return _open_formfile2(filename)[0]
+
+def _open_formfile2(filename):
+    if filename[-3:] != '.fd':
+        filename = filename + '.fd'
+    if filename[0] == '/':
+        try:
+            fp = open(filename,'r')
+        except IOError:
+            fp = None
+    else:
+        for pc in sys.path:
+            pn = os.path.join(pc, filename)
+            try:
+                fp = open(pn, 'r')
+                filename = pn
+                break
+            except IOError:
+                fp = None
+    if fp is None:
+        raise error, 'Cannot find forms file ' + filename
+    return fp, filename
+
+#
+# Internal: parse the fd file header, return number of forms
+#
+def _parse_fd_header(file):
+    # First read the magic header line
+    datum = _parse_1_line(file)
+    if datum != ('Magic', 12321):
+        raise error, 'Not a forms definition file'
+    # Now skip until we know number of forms
+    while 1:
+        datum = _parse_1_line(file)
+        if type(datum) == type(()) and datum[0] == 'Numberofforms':
+            break
+    return datum[1]
+#
+# Internal: parse fd form, or skip if name doesn't match.
+# the special value None means 'always parse it'.
+#
+def _parse_fd_form(file, name):
+    datum = _parse_1_line(file)
+    if datum != FORMLINE:
+        raise error, 'Missing === FORM === line'
+    form = _parse_object(file)
+    if form.Name == name or name is None:
+        objs = []
+        for j in range(form.Numberofobjects):
+            obj = _parse_object(file)
+            objs.append(obj)
+        return (form, objs)
+    else:
+        for j in range(form.Numberofobjects):
+            _skip_object(file)
+    return None
+
+#
+# Internal class: a convenient place to store object info fields
+#
+class _newobj:
+    def add(self, name, value):
+        self.__dict__[name] = value
+    def make(self, dict):
+        for name in dict.keys():
+            self.add(name, dict[name])
+
+#
+# Internal parsing routines.
+#
+def _parse_string(str):
+    if '\\' in str:
+        s = '\'' + str + '\''
+        try:
+            return eval(s)
+        except:
+            pass
+    return str
+
+def _parse_num(str):
+    return eval(str)
+
+def _parse_numlist(str):
+    slist = str.split()
+    nlist = []
+    for i in slist:
+        nlist.append(_parse_num(i))
+    return nlist
+
+# This dictionary maps item names to parsing routines.
+# If no routine is given '_parse_num' is default.
+_parse_func = { \
+        'Name':         _parse_string, \
+        'Box':          _parse_numlist, \
+        'Colors':       _parse_numlist, \
+        'Label':        _parse_string, \
+        'Name':         _parse_string, \
+        'Callback':     _parse_string, \
+        'Argument':     _parse_string }
+
+# This function parses a line, and returns either
+# a string or a tuple (name,value)
+
+import re
+prog = re.compile('^([^:]*): *(.*)')
+
+def _parse_line(line):
+    match = prog.match(line)
+    if not match:
+        return line
+    name, value = match.group(1, 2)
+    if name[0] == 'N':
+        name = ''.join(name.split())
+        name = name.lower()
+    name = name.capitalize()
+    try:
+        pf = _parse_func[name]
+    except KeyError:
+        pf = _parse_num
+    value = pf(value)
+    return (name, value)
+
+def _readline(file):
+    line = file.readline()
+    if not line:
+        raise EOFError
+    return line[:-1]
+
+def _parse_1_line(file):
+    line = _readline(file)
+    while line == '':
+        line = _readline(file)
+    return _parse_line(line)
+
+def _skip_object(file):
+    line = ''
+    while not line in (SPLITLINE, FORMLINE, ENDLINE):
+        pos = file.tell()
+        line = _readline(file)
+    if line == FORMLINE:
+        file.seek(pos)
+
+def _parse_object(file):
+    obj = _newobj()
+    while 1:
+        pos = file.tell()
+        datum = _parse_1_line(file)
+        if datum in (SPLITLINE, FORMLINE, ENDLINE):
+            if datum == FORMLINE:
+                file.seek(pos)
+            return obj
+        if type(datum) is not type(()) or len(datum) != 2:
+            raise error, 'Parse error, illegal line in object: '+datum
+        obj.add(datum[0], datum[1])
+
+#################################################################
+#   Part 2 - High-level object/form creation routines            #
+#################################################################
+
+#
+# External - Create a form an link to an instance variable.
+#
+def create_full_form(inst, (fdata, odatalist)):
+    form = create_form(fdata)
+    exec 'inst.'+fdata.Name+' = form\n'
+    for odata in odatalist:
+        create_object_instance(inst, form, odata)
+
+#
+# External - Merge a form into an existing form in an instance
+# variable.
+#
+def merge_full_form(inst, form, (fdata, odatalist)):
+    exec 'inst.'+fdata.Name+' = form\n'
+    if odatalist[0].Class != FL.BOX:
+        raise error, 'merge_full_form() expects FL.BOX as first obj'
+    for odata in odatalist[1:]:
+        create_object_instance(inst, form, odata)
+
+
+#################################################################
+#   Part 3 - Low-level object/form creation routines            #
+#################################################################
+
+#
+# External Create_form - Create form from parameters
+#
+def create_form(fdata):
+    import fl
+    return fl.make_form(FL.NO_BOX, fdata.Width, fdata.Height)
+
+#
+# External create_object - Create an object. Make sure there are
+# no callbacks. Returns the object created.
+#
+def create_object(form, odata):
+    obj = _create_object(form, odata)
+    if odata.Callback:
+        raise error, 'Creating free object with callback'
+    return obj
+#
+# External create_object_instance - Create object in an instance.
+#
+def create_object_instance(inst, form, odata):
+    obj = _create_object(form, odata)
+    if odata.Callback:
+        cbfunc = eval('inst.'+odata.Callback)
+        obj.set_call_back(cbfunc, odata.Argument)
+    if odata.Name:
+        exec 'inst.' + odata.Name + ' = obj\n'
+#
+# Internal _create_object: Create the object and fill options
+#
+def _create_object(form, odata):
+    crfunc = _select_crfunc(form, odata.Class)
+    obj = crfunc(odata.Type, odata.Box[0], odata.Box[1], odata.Box[2], \
+            odata.Box[3], odata.Label)
+    if not odata.Class in (FL.BEGIN_GROUP, FL.END_GROUP):
+        obj.boxtype = odata.Boxtype
+        obj.col1 = odata.Colors[0]
+        obj.col2 = odata.Colors[1]
+        obj.align = odata.Alignment
+        obj.lstyle = odata.Style
+        obj.lsize = odata.Size
+        obj.lcol = odata.Lcol
+    return obj
+#
+# Internal crfunc: helper function that returns correct create function
+#
+def _select_crfunc(fm, cl):
+    if cl == FL.BEGIN_GROUP: return fm.bgn_group
+    elif cl == FL.END_GROUP: return fm.end_group
+    elif cl == FL.BITMAP: return fm.add_bitmap
+    elif cl == FL.BOX: return fm.add_box
+    elif cl == FL.BROWSER: return fm.add_browser
+    elif cl == FL.BUTTON: return fm.add_button
+    elif cl == FL.CHART: return fm.add_chart
+    elif cl == FL.CHOICE: return fm.add_choice
+    elif cl == FL.CLOCK: return fm.add_clock
+    elif cl == FL.COUNTER: return fm.add_counter
+    elif cl == FL.DIAL: return fm.add_dial
+    elif cl == FL.FREE: return fm.add_free
+    elif cl == FL.INPUT: return fm.add_input
+    elif cl == FL.LIGHTBUTTON: return fm.add_lightbutton
+    elif cl == FL.MENU: return fm.add_menu
+    elif cl == FL.POSITIONER: return fm.add_positioner
+    elif cl == FL.ROUNDBUTTON: return fm.add_roundbutton
+    elif cl == FL.SLIDER: return fm.add_slider
+    elif cl == FL.VALSLIDER: return fm.add_valslider
+    elif cl == FL.TEXT: return fm.add_text
+    elif cl == FL.TIMER: return fm.add_timer
+    else:
+        raise error, 'Unknown object type: %r' % (cl,)
+
+
+def test():
+    import time
+    t0 = time.time()
+    if len(sys.argv) == 2:
+        forms = parse_forms(sys.argv[1])
+        t1 = time.time()
+        print 'parse time:', 0.001*(t1-t0), 'sec.'
+        keys = forms.keys()
+        keys.sort()
+        for i in keys:
+            _printform(forms[i])
+    elif len(sys.argv) == 3:
+        form = parse_form(sys.argv[1], sys.argv[2])
+        t1 = time.time()
+        print 'parse time:', round(t1-t0, 3), 'sec.'
+        _printform(form)
+    else:
+        print 'Usage: test fdfile [form]'
+
+def _printform(form):
+    f = form[0]
+    objs = form[1]
+    print 'Form ', f.Name, ', size: ', f.Width, f.Height, ' Nobj ', f.Numberofobjects
+    for i in objs:
+        print '  Obj ', i.Name, ' type ', i.Class, i.Type
+        print '    Box ', i.Box, ' btype ', i.Boxtype
+        print '    Label ', i.Label, ' size/style/col/align ', i.Size,i.Style, i.Lcol, i.Alignment
+        print '    cols ', i.Colors
+        print '    cback ', i.Callback, i.Argument

Added: vendor/Python/current/Lib/plat-irix6/jpeg.py
===================================================================
--- vendor/Python/current/Lib/plat-irix6/jpeg.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix6/jpeg.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,111 @@
+# Implement 'jpeg' interface using SGI's compression library
+
+# XXX Options 'smooth' and 'optimize' are ignored.
+
+# XXX It appears that compressing grayscale images doesn't work right;
+# XXX the resulting file causes weirdness.
+
+class error(Exception):
+    pass
+
+options = {'quality': 75, 'optimize': 0, 'smooth': 0, 'forcegray': 0}
+
+comp = None
+decomp = None
+
+def compress(imgdata, width, height, bytesperpixel):
+    global comp
+    import cl
+    if comp is None: comp = cl.OpenCompressor(cl.JPEG)
+    if bytesperpixel == 1:
+        format = cl.GRAYSCALE
+    elif bytesperpixel == 4:
+        format = cl.RGBX
+    if options['forcegray']:
+        iformat = cl.GRAYSCALE
+    else:
+        iformat = cl.YUV
+    # XXX How to support 'optimize'?
+    params = [cl.IMAGE_WIDTH, width, cl.IMAGE_HEIGHT, height,
+              cl.ORIGINAL_FORMAT, format,
+              cl.ORIENTATION, cl.BOTTOM_UP,
+              cl.QUALITY_FACTOR, options['quality'],
+              cl.INTERNAL_FORMAT, iformat,
+             ]
+    comp.SetParams(params)
+    jpegdata = comp.Compress(1, imgdata)
+    return jpegdata
+
+def decompress(jpegdata):
+    global decomp
+    import cl
+    if decomp is None: decomp = cl.OpenDecompressor(cl.JPEG)
+    headersize = decomp.ReadHeader(jpegdata)
+    params = [cl.IMAGE_WIDTH, 0, cl.IMAGE_HEIGHT, 0, cl.INTERNAL_FORMAT, 0]
+    decomp.GetParams(params)
+    width, height, format = params[1], params[3], params[5]
+    if format == cl.GRAYSCALE or options['forcegray']:
+        format = cl.GRAYSCALE
+        bytesperpixel = 1
+    else:
+        format = cl.RGBX
+        bytesperpixel = 4
+    # XXX How to support 'smooth'?
+    params = [cl.ORIGINAL_FORMAT, format,
+              cl.ORIENTATION, cl.BOTTOM_UP,
+              cl.FRAME_BUFFER_SIZE, width*height*bytesperpixel]
+    decomp.SetParams(params)
+    imgdata = decomp.Decompress(1, jpegdata)
+    return imgdata, width, height, bytesperpixel
+
+def setoption(name, value):
+    if type(value) is not type(0):
+        raise TypeError, 'jpeg.setoption: numeric options only'
+    if name == 'forcegrey':
+        name = 'forcegray'
+    if not options.has_key(name):
+        raise KeyError, 'jpeg.setoption: unknown option name'
+    options[name] = int(value)
+
+def test():
+    import sys
+    if sys.argv[1:2] == ['-g']:
+        del sys.argv[1]
+        setoption('forcegray', 1)
+    if not sys.argv[1:]:
+        sys.argv.append('/usr/local/images/data/jpg/asterix.jpg')
+    for file in sys.argv[1:]:
+        show(file)
+
+def show(file):
+    import gl, GL, DEVICE
+    jpegdata = open(file, 'r').read()
+    imgdata, width, height, bytesperpixel = decompress(jpegdata)
+    gl.foreground()
+    gl.prefsize(width, height)
+    win = gl.winopen(file)
+    if bytesperpixel == 1:
+        gl.cmode()
+        gl.pixmode(GL.PM_SIZE, 8)
+        gl.gconfig()
+        for i in range(256):
+            gl.mapcolor(i, i, i, i)
+    else:
+        gl.RGBmode()
+        gl.pixmode(GL.PM_SIZE, 32)
+        gl.gconfig()
+    gl.qdevice(DEVICE.REDRAW)
+    gl.qdevice(DEVICE.ESCKEY)
+    gl.qdevice(DEVICE.WINQUIT)
+    gl.qdevice(DEVICE.WINSHUT)
+    gl.lrectwrite(0, 0, width-1, height-1, imgdata)
+    while 1:
+        dev, val = gl.qread()
+        if dev in (DEVICE.ESCKEY, DEVICE.WINSHUT, DEVICE.WINQUIT):
+            break
+        if dev == DEVICE.REDRAW:
+            gl.lrectwrite(0, 0, width-1, height-1, imgdata)
+    gl.winclose(win)
+    # Now test the compression and write the result to a fixed filename
+    newjpegdata = compress(imgdata, width, height, bytesperpixel)
+    open('/tmp/j.jpg', 'w').write(newjpegdata)

Added: vendor/Python/current/Lib/plat-irix6/panel.py
===================================================================
--- vendor/Python/current/Lib/plat-irix6/panel.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix6/panel.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,281 @@
+# Module 'panel'
+#
+# Support for the Panel library.
+# Uses built-in module 'pnl'.
+# Applications should use 'panel.function' instead of 'pnl.function';
+# most 'pnl' functions are transparently exported by 'panel',
+# but dopanel() is overridden and you have to use this version
+# if you want to use callbacks.
+
+
+import pnl
+
+
+debug = 0
+
+
+# Test if an object is a list.
+#
+def is_list(x):
+    return type(x) == type([])
+
+
+# Reverse a list.
+#
+def reverse(list):
+    res = []
+    for item in list:
+        res.insert(0, item)
+    return res
+
+
+# Get an attribute of a list, which may itself be another list.
+# Don't use 'prop' for name.
+#
+def getattrlist(list, name):
+    for item in list:
+        if item and is_list(item) and item[0] == name:
+            return item[1:]
+    return []
+
+
+# Get a property of a list, which may itself be another list.
+#
+def getproplist(list, name):
+    for item in list:
+        if item and is_list(item) and item[0] == 'prop':
+            if len(item) > 1 and item[1] == name:
+                return item[2:]
+    return []
+
+
+# Test if an actuator description contains the property 'end-of-group'
+#
+def is_endgroup(list):
+    x = getproplist(list, 'end-of-group')
+    return (x and x[0] == '#t')
+
+
+# Neatly display an actuator definition given as S-expression
+# the prefix string is printed before each line.
+#
+def show_actuator(prefix, a):
+    for item in a:
+        if not is_list(item):
+            print prefix, item
+        elif item and item[0] == 'al':
+            print prefix, 'Subactuator list:'
+            for a in item[1:]:
+                show_actuator(prefix + '    ', a)
+        elif len(item) == 2:
+            print prefix, item[0], '=>', item[1]
+        elif len(item) == 3 and item[0] == 'prop':
+            print prefix, 'Prop', item[1], '=>',
+            print item[2]
+        else:
+            print prefix, '?', item
+
+
+# Neatly display a panel.
+#
+def show_panel(prefix, p):
+    for item in p:
+        if not is_list(item):
+            print prefix, item
+        elif item and item[0] == 'al':
+            print prefix, 'Actuator list:'
+            for a in item[1:]:
+                show_actuator(prefix + '    ', a)
+        elif len(item) == 2:
+            print prefix, item[0], '=>', item[1]
+        elif len(item) == 3 and item[0] == 'prop':
+            print prefix, 'Prop', item[1], '=>',
+            print item[2]
+        else:
+            print prefix, '?', item
+
+
+# Exception raised by build_actuator or build_panel.
+#
+panel_error = 'panel error'
+
+
+# Dummy callback used to initialize the callbacks.
+#
+def dummy_callback(arg):
+    pass
+
+
+# Assign attributes to members of the target.
+# Attribute names in exclist are ignored.
+# The member name is the attribute name prefixed with the prefix.
+#
+def assign_members(target, attrlist, exclist, prefix):
+    for item in attrlist:
+        if is_list(item) and len(item) == 2 and item[0] not in exclist:
+            name, value = item[0], item[1]
+            ok = 1
+            if value[0] in '-0123456789':
+                value = eval(value)
+            elif value[0] == '"':
+                value = value[1:-1]
+            elif value == 'move-then-resize':
+                # Strange default set by Panel Editor...
+                ok = 0
+            else:
+                print 'unknown value', value, 'for', name
+                ok = 0
+            if ok:
+                lhs = 'target.' + prefix + name
+                stmt = lhs + '=' + repr(value)
+                if debug: print 'exec', stmt
+                try:
+                    exec stmt + '\n'
+                except KeyboardInterrupt: # Don't catch this!
+                    raise KeyboardInterrupt
+                except:
+                    print 'assign failed:', stmt
+
+
+# Build a real actuator from an actuator description.
+# Return a pair (actuator, name).
+#
+def build_actuator(descr):
+    namelist = getattrlist(descr, 'name')
+    if namelist:
+        # Assume it is a string
+        actuatorname = namelist[0][1:-1]
+    else:
+        actuatorname = ''
+    type = descr[0]
+    if type[:4] == 'pnl_': type = type[4:]
+    act = pnl.mkact(type)
+    act.downfunc = act.activefunc = act.upfunc = dummy_callback
+    #
+    assign_members(act, descr[1:], ['al', 'data', 'name'], '')
+    #
+    # Treat actuator-specific data
+    #
+    datalist = getattrlist(descr, 'data')
+    prefix = ''
+    if type[-4:] == 'puck':
+        prefix = 'puck_'
+    elif type == 'mouse':
+        prefix = 'mouse_'
+    assign_members(act, datalist, [], prefix)
+    #
+    return act, actuatorname
+
+
+# Build all sub-actuators and add them to the super-actuator.
+# The super-actuator must already have been added to the panel.
+# Sub-actuators with defined names are added as members to the panel
+# so they can be referenced as p.name.
+#
+# Note: I have no idea how panel.endgroup() works when applied
+# to a sub-actuator.
+#
+def build_subactuators(panel, super_act, al):
+    #
+    # This is nearly the same loop as below in build_panel(),
+    # except a call is made to addsubact() instead of addact().
+    #
+    for a in al:
+        act, name = build_actuator(a)
+        act.addsubact(super_act)
+        if name:
+            stmt = 'panel.' + name + ' = act'
+            if debug: print 'exec', stmt
+            exec stmt + '\n'
+        if is_endgroup(a):
+            panel.endgroup()
+        sub_al = getattrlist(a, 'al')
+        if sub_al:
+            build_subactuators(panel, act, sub_al)
+    #
+    # Fix the actuator to which whe just added subactuators.
+    # This can't hurt (I hope) and is needed for the scroll actuator.
+    #
+    super_act.fixact()
+
+
+# Build a real panel from a panel definition.
+# Return a panel object p, where for each named actuator a, p.name is a
+# reference to a.
+#
+def build_panel(descr):
+    #
+    # Sanity check
+    #
+    if (not descr) or descr[0] != 'panel':
+        raise panel_error, 'panel description must start with "panel"'
+    #
+    if debug: show_panel('', descr)
+    #
+    # Create an empty panel
+    #
+    panel = pnl.mkpanel()
+    #
+    # Assign panel attributes
+    #
+    assign_members(panel, descr[1:], ['al'], '')
+    #
+    # Look for actuator list
+    #
+    al = getattrlist(descr, 'al')
+    #
+    # The order in which actuators are created is important
+    # because of the endgroup() operator.
+    # Unfortunately the Panel Editor outputs the actuator list
+    # in reverse order, so we reverse it here.
+    #
+    al = reverse(al)
+    #
+    for a in al:
+        act, name = build_actuator(a)
+        act.addact(panel)
+        if name:
+            stmt = 'panel.' + name + ' = act'
+            exec stmt + '\n'
+        if is_endgroup(a):
+            panel.endgroup()
+        sub_al = getattrlist(a, 'al')
+        if sub_al:
+            build_subactuators(panel, act, sub_al)
+    #
+    return panel
+
+
+# Wrapper around pnl.dopanel() which calls call-back functions.
+#
+def my_dopanel():
+    # Extract only the first 4 elements to allow for future expansion
+    a, down, active, up = pnl.dopanel()[:4]
+    if down:
+        down.downfunc(down)
+    if active:
+        active.activefunc(active)
+    if up:
+        up.upfunc(up)
+    return a
+
+
+# Create one or more panels from a description file (S-expressions)
+# generated by the Panel Editor.
+#
+def defpanellist(file):
+    import panelparser
+    descrlist = panelparser.parse_file(open(file, 'r'))
+    panellist = []
+    for descr in descrlist:
+        panellist.append(build_panel(descr))
+    return panellist
+
+
+# Import everything from built-in method pnl, so the user can always
+# use panel.foo() instead of pnl.foo().
+# This gives *no* performance penalty once this module is imported.
+#
+from pnl import *                       # for export
+
+dopanel = my_dopanel                    # override pnl.dopanel

Added: vendor/Python/current/Lib/plat-irix6/panelparser.py
===================================================================
--- vendor/Python/current/Lib/plat-irix6/panelparser.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix6/panelparser.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,128 @@
+# Module 'parser'
+#
+# Parse S-expressions output by the Panel Editor
+# (which is written in Scheme so it can't help writing S-expressions).
+#
+# See notes at end of file.
+
+
+whitespace = ' \t\n'
+operators = '()\''
+separators = operators + whitespace + ';' + '"'
+
+
+# Tokenize a string.
+# Return a list of tokens (strings).
+#
+def tokenize_string(s):
+    tokens = []
+    while s:
+        c = s[:1]
+        if c in whitespace:
+            s = s[1:]
+        elif c == ';':
+            s = ''
+        elif c == '"':
+            n = len(s)
+            i = 1
+            while i < n:
+                c = s[i]
+                i = i+1
+                if c == '"': break
+                if c == '\\': i = i+1
+            tokens.append(s[:i])
+            s = s[i:]
+        elif c in operators:
+            tokens.append(c)
+            s = s[1:]
+        else:
+            n = len(s)
+            i = 1
+            while i < n:
+                if s[i] in separators: break
+                i = i+1
+            tokens.append(s[:i])
+            s = s[i:]
+    return tokens
+
+
+# Tokenize a whole file (given as file object, not as file name).
+# Return a list of tokens (strings).
+#
+def tokenize_file(fp):
+    tokens = []
+    while 1:
+        line = fp.readline()
+        if not line: break
+        tokens = tokens + tokenize_string(line)
+    return tokens
+
+
+# Exception raised by parse_exr.
+#
+syntax_error = 'syntax error'
+
+
+# Parse an S-expression.
+# Input is a list of tokens as returned by tokenize_*().
+# Return a pair (expr, tokens)
+# where expr is a list representing the s-expression,
+# and tokens contains the remaining tokens.
+# May raise syntax_error.
+#
+def parse_expr(tokens):
+    if (not tokens) or tokens[0] != '(':
+        raise syntax_error, 'expected "("'
+    tokens = tokens[1:]
+    expr = []
+    while 1:
+        if not tokens:
+            raise syntax_error, 'missing ")"'
+        if tokens[0] == ')':
+            return expr, tokens[1:]
+        elif tokens[0] == '(':
+            subexpr, tokens = parse_expr(tokens)
+            expr.append(subexpr)
+        else:
+            expr.append(tokens[0])
+            tokens = tokens[1:]
+
+
+# Parse a file (given as file object, not as file name).
+# Return a list of parsed S-expressions found at the top level.
+#
+def parse_file(fp):
+    tokens = tokenize_file(fp)
+    exprlist = []
+    while tokens:
+        expr, tokens = parse_expr(tokens)
+        exprlist.append(expr)
+    return exprlist
+
+
+# EXAMPLE:
+#
+# The input
+#       '(hip (hop hur-ray))'
+#
+# passed to tokenize_string() returns the token list
+#       ['(', 'hip', '(', 'hop', 'hur-ray', ')', ')']
+#
+# When this is passed to parse_expr() it returns the expression
+#       ['hip', ['hop', 'hur-ray']]
+# plus an empty token list (because there are no tokens left.
+#
+# When a file containing the example is passed to parse_file() it returns
+# a list whose only element is the output of parse_expr() above:
+#       [['hip', ['hop', 'hur-ray']]]
+
+
+# TOKENIZING:
+#
+# Comments start with semicolon (;) and continue till the end of the line.
+#
+# Tokens are separated by whitespace, except the following characters
+# always form a separate token (outside strings):
+#       ( ) '
+# Strings are enclosed in double quotes (") and backslash (\) is used
+# as escape character in strings.

Added: vendor/Python/current/Lib/plat-irix6/readcd.doc
===================================================================
--- vendor/Python/current/Lib/plat-irix6/readcd.doc	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix6/readcd.doc	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,104 @@
+Interface to CD-ROM player.
+
+This module implements an interface to the built-in cd module.  The
+intention is to provide a more user-friendly interface than the
+built-in module.
+
+The module defines a class Readcd with several methods.  The
+initialization of the class will try to open the CD player.  This
+means that initialization will fail if the CD player is already in
+use.  A RuntimeError will be raised by the cd module in that case.
+
+The way to work with this module is as follows.  The user specifies
+the parts of the CD that are to be read and he specifies callback
+functions which are to be called by the system.  At some point he can
+tell the system to play.  The specified parts of the CD will then be
+read and the callbacks will be called.
+
+Initialization.
+===============
+
+r = readcd.Readcd([cd-player [, mode]])
+
+The optional arguments are the name of the CD device and the mode.
+When "mode" is not specified, it defaults to 'r' (which is the only
+possible value); when "cd-player" also isn't specified, it defaults
+to "None" which indicates the default CD player.
+
+Methods.
+========
+
+eject() -- Eject the CD from the player.
+
+reset() -- Reset the list of data stretches to be played.
+
+appendtrack(track) -- Append the specified track to the list of music
+stretches.
+
+appendstretch(first, last) -- Append the stretch from "first" to "last"
+to the list of music stretches.  Both "first" and "last" can be in one
+of four forms.  "None": for "first", the beginning of the CD, for
+"last" the end of the CD; a single integer: a track number--playing
+starts at the beginning of the track or ends at the end of the
+specified track; a three-tuple: the absolute time from the start of
+the CD in minutes, seconds, frames; a four-tuple: track number and
+relative time within the track in minutes, seconds, frames.
+
+settracks(tracklist) -- The argument is a list of integers.  The list
+of stretches is set to argument list.  The old list is discarded.
+
+setcallback(type, func, arg) -- Set a callback function for "type".
+The function will be called as func(arg, type, data) where "arg" is
+the third argument of setcallback, "type" is the type of callback,
+"data" is type-dependent data.  See the CDsetcallback(3) manual page
+for more information.  The possible "type" arguments are defined in
+the CD module.
+
+removecallback(type) -- Remove the callback for "type".
+
+gettrackinfo([tracklist]) -- Return a list of tuples.  Each tuple
+consists of start and length information of a track.  The start and
+length information consist of three-tuples with minutes, seconds and
+frames.  The optional tracklist argument gives a list of interesting
+track numbers.  If no tracklist is specified, information about all
+tracks is returned.
+
+getstatus() -- Return the status information of the CD.
+
+play() -- Play the preprogrammed stretches of music from the CD.  When
+nothing was programmed, the whole CD is played.
+
+Specifying stretches.
+=====================
+
+There are three methods available to specify a stretch of music to be
+played.  The easiest way is to use "settracklist(tracklist)" with which
+a list of tracks can be specified.  "settracklist(tracklist)" is
+equivalent to the sequence
+	reset()
+	for track in tracklist:
+		appendtrack(track)
+
+The next method is "appendtrack(track)" with which a whole track can be
+added to the list of music to be played.  "appendtrack(track)" is
+equivalent to "appendstretch(track, track)".
+
+The most complete method is "appendstretch(first, last)".  Using this
+method, it is possible to specify any stretch of music.
+
+When two consecutive tracks are played, it is possible to choose
+whether the pause that may be between the tracks is played as well or
+whether the pause should be skipped.  When the end of a stretch is
+specified using a track number and the next stretch starts at the
+beginning of the following track and that was also specified using the
+track number (that is, both were specified as integers, not as tuples),
+the pause is played.  When either value was specified using absolute
+time or track-relative time (that is, as three-tuple or as
+four-tuple), the pause will not be played.
+
+Errors.
+=======
+
+When an error occurs, an exception will be raised.  Depending on where
+the error occurs, the exception may either be "readcd.Error" or
+"RuntimeError".

Added: vendor/Python/current/Lib/plat-irix6/readcd.py
===================================================================
--- vendor/Python/current/Lib/plat-irix6/readcd.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix6/readcd.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,244 @@
+# Class interface to the CD module.
+
+import cd, CD
+
+class Error(Exception):
+    pass
+class _Stop(Exception):
+    pass
+
+def _doatime(self, cb_type, data):
+    if ((data[0] * 60) + data[1]) * 75 + data[2] > self.end:
+##              print 'done with list entry', repr(self.listindex)
+        raise _Stop
+    func, arg = self.callbacks[cb_type]
+    if func:
+        func(arg, cb_type, data)
+
+def _dopnum(self, cb_type, data):
+    if data > self.end:
+##              print 'done with list entry', repr(self.listindex)
+        raise _Stop
+    func, arg = self.callbacks[cb_type]
+    if func:
+        func(arg, cb_type, data)
+
+class Readcd:
+    def __init__(self, *arg):
+        if len(arg) == 0:
+            self.player = cd.open()
+        elif len(arg) == 1:
+            self.player = cd.open(arg[0])
+        elif len(arg) == 2:
+            self.player = cd.open(arg[0], arg[1])
+        else:
+            raise Error, 'bad __init__ call'
+        self.list = []
+        self.callbacks = [(None, None)] * 8
+        self.parser = cd.createparser()
+        self.playing = 0
+        self.end = 0
+        self.status = None
+        self.trackinfo = None
+
+    def eject(self):
+        self.player.eject()
+        self.list = []
+        self.end = 0
+        self.listindex = 0
+        self.status = None
+        self.trackinfo = None
+        if self.playing:
+##                      print 'stop playing from eject'
+            raise _Stop
+
+    def pmsf2msf(self, track, min, sec, frame):
+        if not self.status:
+            self.cachestatus()
+        if track < self.status[5] or track > self.status[6]:
+            raise Error, 'track number out of range'
+        if not self.trackinfo:
+            self.cacheinfo()
+        start, total = self.trackinfo[track]
+        start = ((start[0] * 60) + start[1]) * 75 + start[2]
+        total = ((total[0] * 60) + total[1]) * 75 + total[2]
+        block = ((min * 60) + sec) * 75 + frame
+        if block > total:
+            raise Error, 'out of range'
+        block = start + block
+        min, block = divmod(block, 75*60)
+        sec, frame = divmod(block, 75)
+        return min, sec, frame
+
+    def reset(self):
+        self.list = []
+
+    def appendtrack(self, track):
+        self.appendstretch(track, track)
+
+    def appendstretch(self, start, end):
+        if not self.status:
+            self.cachestatus()
+        if not start:
+            start = 1
+        if not end:
+            end = self.status[6]
+        if type(end) == type(0):
+            if end < self.status[5] or end > self.status[6]:
+                raise Error, 'range error'
+        else:
+            l = len(end)
+            if l == 4:
+                prog, min, sec, frame = end
+                if prog < self.status[5] or prog > self.status[6]:
+                    raise Error, 'range error'
+                end = self.pmsf2msf(prog, min, sec, frame)
+            elif l != 3:
+                raise Error, 'syntax error'
+        if type(start) == type(0):
+            if start < self.status[5] or start > self.status[6]:
+                raise Error, 'range error'
+            if len(self.list) > 0:
+                s, e = self.list[-1]
+                if type(e) == type(0):
+                    if start == e+1:
+                        start = s
+                        del self.list[-1]
+        else:
+            l = len(start)
+            if l == 4:
+                prog, min, sec, frame = start
+                if prog < self.status[5] or prog > self.status[6]:
+                    raise Error, 'range error'
+                start = self.pmsf2msf(prog, min, sec, frame)
+            elif l != 3:
+                raise Error, 'syntax error'
+        self.list.append((start, end))
+
+    def settracks(self, list):
+        self.list = []
+        for track in list:
+            self.appendtrack(track)
+
+    def setcallback(self, cb_type, func, arg):
+        if cb_type < 0 or cb_type >= 8:
+            raise Error, 'type out of range'
+        self.callbacks[cb_type] = (func, arg)
+        if self.playing:
+            start, end = self.list[self.listindex]
+            if type(end) == type(0):
+                if cb_type != CD.PNUM:
+                    self.parser.setcallback(cb_type, func, arg)
+            else:
+                if cb_type != CD.ATIME:
+                    self.parser.setcallback(cb_type, func, arg)
+
+    def removecallback(self, cb_type):
+        if cb_type < 0 or cb_type >= 8:
+            raise Error, 'type out of range'
+        self.callbacks[cb_type] = (None, None)
+        if self.playing:
+            start, end = self.list[self.listindex]
+            if type(end) == type(0):
+                if cb_type != CD.PNUM:
+                    self.parser.removecallback(cb_type)
+            else:
+                if cb_type != CD.ATIME:
+                    self.parser.removecallback(cb_type)
+
+    def gettrackinfo(self, *arg):
+        if not self.status:
+            self.cachestatus()
+        if not self.trackinfo:
+            self.cacheinfo()
+        if len(arg) == 0:
+            return self.trackinfo[self.status[5]:self.status[6]+1]
+        result = []
+        for i in arg:
+            if i < self.status[5] or i > self.status[6]:
+                raise Error, 'range error'
+            result.append(self.trackinfo[i])
+        return result
+
+    def cacheinfo(self):
+        if not self.status:
+            self.cachestatus()
+        self.trackinfo = []
+        for i in range(self.status[5]):
+            self.trackinfo.append(None)
+        for i in range(self.status[5], self.status[6]+1):
+            self.trackinfo.append(self.player.gettrackinfo(i))
+
+    def cachestatus(self):
+        self.status = self.player.getstatus()
+        if self.status[0] == CD.NODISC:
+            self.status = None
+            raise Error, 'no disc in player'
+
+    def getstatus(self):
+        return self.player.getstatus()
+
+    def play(self):
+        if not self.status:
+            self.cachestatus()
+        size = self.player.bestreadsize()
+        self.listindex = 0
+        self.playing = 0
+        for i in range(8):
+            func, arg = self.callbacks[i]
+            if func:
+                self.parser.setcallback(i, func, arg)
+            else:
+                self.parser.removecallback(i)
+        if len(self.list) == 0:
+            for i in range(self.status[5], self.status[6]+1):
+                self.appendtrack(i)
+        try:
+            while 1:
+                if not self.playing:
+                    if self.listindex >= len(self.list):
+                        return
+                    start, end = self.list[self.listindex]
+                    if type(start) == type(0):
+                        dummy = self.player.seektrack(
+                                start)
+                    else:
+                        min, sec, frame = start
+                        dummy = self.player.seek(
+                                min, sec, frame)
+                    if type(end) == type(0):
+                        self.parser.setcallback(
+                                CD.PNUM, _dopnum, self)
+                        self.end = end
+                        func, arg = \
+                              self.callbacks[CD.ATIME]
+                        if func:
+                            self.parser.setcallback(CD.ATIME, func, arg)
+                        else:
+                            self.parser.removecallback(CD.ATIME)
+                    else:
+                        min, sec, frame = end
+                        self.parser.setcallback(
+                                CD.ATIME, _doatime,
+                                self)
+                        self.end = (min * 60 + sec) * \
+                                   75 + frame
+                        func, arg = \
+                              self.callbacks[CD.PNUM]
+                        if func:
+                            self.parser.setcallback(CD.PNUM, func, arg)
+                        else:
+                            self.parser.removecallback(CD.PNUM)
+                    self.playing = 1
+                data = self.player.readda(size)
+                if data == '':
+                    self.playing = 0
+                    self.listindex = self.listindex + 1
+                    continue
+                try:
+                    self.parser.parseframe(data)
+                except _Stop:
+                    self.playing = 0
+                    self.listindex = self.listindex + 1
+        finally:
+            self.playing = 0

Added: vendor/Python/current/Lib/plat-irix6/regen
===================================================================
--- vendor/Python/current/Lib/plat-irix6/regen	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix6/regen	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,11 @@
+#! /bin/sh
+case `uname -sr` in
+'IRIX '[456].*)	;;
+'IRIX64 '[456].*)	;;
+*)	echo Probably not on an IRIX system 1>&2
+	exit 1;;
+esac
+set -v
+h2py /usr/include/sys/file.h
+h2py -i '(u_long)' /usr/include/netinet/in.h
+h2py /usr/include/errno.h


Property changes on: vendor/Python/current/Lib/plat-irix6/regen
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/plat-irix6/torgb.py
===================================================================
--- vendor/Python/current/Lib/plat-irix6/torgb.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-irix6/torgb.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,99 @@
+# Convert "arbitrary" image files to rgb files (SGI's image format).
+# Input may be compressed.
+# The uncompressed file type may be PBM, PGM, PPM, GIF, TIFF, or Sun raster.
+# An exception is raised if the file is not of a recognized type.
+# Returned filename is either the input filename or a temporary filename;
+# in the latter case the caller must ensure that it is removed.
+# Other temporary files used are removed by the function.
+
+import os
+import tempfile
+import pipes
+import imghdr
+
+table = {}
+
+t = pipes.Template()
+t.append('fromppm $IN $OUT', 'ff')
+table['ppm'] = t
+
+t = pipes.Template()
+t.append('(PATH=$PATH:/ufs/guido/bin/sgi; exec pnmtoppm)', '--')
+t.append('fromppm $IN $OUT', 'ff')
+table['pnm'] = t
+table['pgm'] = t
+table['pbm'] = t
+
+t = pipes.Template()
+t.append('fromgif $IN $OUT', 'ff')
+table['gif'] = t
+
+t = pipes.Template()
+t.append('tifftopnm', '--')
+t.append('(PATH=$PATH:/ufs/guido/bin/sgi; exec pnmtoppm)', '--')
+t.append('fromppm $IN $OUT', 'ff')
+table['tiff'] = t
+
+t = pipes.Template()
+t.append('rasttopnm', '--')
+t.append('(PATH=$PATH:/ufs/guido/bin/sgi; exec pnmtoppm)', '--')
+t.append('fromppm $IN $OUT', 'ff')
+table['rast'] = t
+
+t = pipes.Template()
+t.append('djpeg', '--')
+t.append('(PATH=$PATH:/ufs/guido/bin/sgi; exec pnmtoppm)', '--')
+t.append('fromppm $IN $OUT', 'ff')
+table['jpeg'] = t
+
+uncompress = pipes.Template()
+uncompress.append('uncompress', '--')
+
+
+class error(Exception):
+    pass
+
+def torgb(filename):
+    temps = []
+    ret = None
+    try:
+        ret = _torgb(filename, temps)
+    finally:
+        for temp in temps[:]:
+            if temp != ret:
+                try:
+                    os.unlink(temp)
+                except os.error:
+                    pass
+                temps.remove(temp)
+    return ret
+
+def _torgb(filename, temps):
+    if filename[-2:] == '.Z':
+        (fd, fname) = tempfile.mkstemp()
+        os.close(fd)
+        temps.append(fname)
+        sts = uncompress.copy(filename, fname)
+        if sts:
+            raise error, filename + ': uncompress failed'
+    else:
+        fname = filename
+    try:
+        ftype = imghdr.what(fname)
+    except IOError, msg:
+        if type(msg) == type(()) and len(msg) == 2 and \
+                type(msg[0]) == type(0) and type(msg[1]) == type(''):
+            msg = msg[1]
+        if type(msg) is not type(''):
+            msg = repr(msg)
+        raise error, filename + ': ' + msg
+    if ftype == 'rgb':
+        return fname
+    if ftype is None or not table.has_key(ftype):
+        raise error, '%s: unsupported image file type %r' % (filename, ftype)
+    (fd, temp) = tempfile.mkstemp()
+    os.close(fd)
+    sts = table[ftype].copy(fname, temp)
+    if sts:
+        raise error, filename + ': conversion to rgb failed'
+    return temp

Added: vendor/Python/current/Lib/plat-linux2/CDROM.py
===================================================================
--- vendor/Python/current/Lib/plat-linux2/CDROM.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-linux2/CDROM.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,207 @@
+# Generated by h2py from /usr/include/linux/cdrom.h
+
+CDROMPAUSE = 0x5301
+CDROMRESUME = 0x5302
+CDROMPLAYMSF = 0x5303
+CDROMPLAYTRKIND = 0x5304
+CDROMREADTOCHDR = 0x5305
+CDROMREADTOCENTRY = 0x5306
+CDROMSTOP = 0x5307
+CDROMSTART = 0x5308
+CDROMEJECT = 0x5309
+CDROMVOLCTRL = 0x530a
+CDROMSUBCHNL = 0x530b
+CDROMREADMODE2 = 0x530c
+CDROMREADMODE1 = 0x530d
+CDROMREADAUDIO = 0x530e
+CDROMEJECT_SW = 0x530f
+CDROMMULTISESSION = 0x5310
+CDROM_GET_MCN = 0x5311
+CDROM_GET_UPC = CDROM_GET_MCN
+CDROMRESET = 0x5312
+CDROMVOLREAD = 0x5313
+CDROMREADRAW = 0x5314
+CDROMREADCOOKED = 0x5315
+CDROMSEEK = 0x5316
+CDROMPLAYBLK = 0x5317
+CDROMREADALL = 0x5318
+CDROMGETSPINDOWN = 0x531d
+CDROMSETSPINDOWN = 0x531e
+CDROMCLOSETRAY = 0x5319
+CDROM_SET_OPTIONS = 0x5320
+CDROM_CLEAR_OPTIONS = 0x5321
+CDROM_SELECT_SPEED = 0x5322
+CDROM_SELECT_DISC = 0x5323
+CDROM_MEDIA_CHANGED = 0x5325
+CDROM_DRIVE_STATUS = 0x5326
+CDROM_DISC_STATUS = 0x5327
+CDROM_CHANGER_NSLOTS = 0x5328
+CDROM_LOCKDOOR = 0x5329
+CDROM_DEBUG = 0x5330
+CDROM_GET_CAPABILITY = 0x5331
+CDROMAUDIOBUFSIZ = 0x5382
+DVD_READ_STRUCT = 0x5390
+DVD_WRITE_STRUCT = 0x5391
+DVD_AUTH = 0x5392
+CDROM_SEND_PACKET = 0x5393
+CDROM_NEXT_WRITABLE = 0x5394
+CDROM_LAST_WRITTEN = 0x5395
+CDROM_PACKET_SIZE = 12
+CGC_DATA_UNKNOWN = 0
+CGC_DATA_WRITE = 1
+CGC_DATA_READ = 2
+CGC_DATA_NONE = 3
+CD_MINS = 74
+CD_SECS = 60
+CD_FRAMES = 75
+CD_SYNC_SIZE = 12
+CD_MSF_OFFSET = 150
+CD_CHUNK_SIZE = 24
+CD_NUM_OF_CHUNKS = 98
+CD_FRAMESIZE_SUB = 96
+CD_HEAD_SIZE = 4
+CD_SUBHEAD_SIZE = 8
+CD_EDC_SIZE = 4
+CD_ZERO_SIZE = 8
+CD_ECC_SIZE = 276
+CD_FRAMESIZE = 2048
+CD_FRAMESIZE_RAW = 2352
+CD_FRAMESIZE_RAWER = 2646
+CD_FRAMESIZE_RAW1 = (CD_FRAMESIZE_RAW-CD_SYNC_SIZE)
+CD_FRAMESIZE_RAW0 = (CD_FRAMESIZE_RAW-CD_SYNC_SIZE-CD_HEAD_SIZE)
+CD_XA_HEAD = (CD_HEAD_SIZE+CD_SUBHEAD_SIZE)
+CD_XA_TAIL = (CD_EDC_SIZE+CD_ECC_SIZE)
+CD_XA_SYNC_HEAD = (CD_SYNC_SIZE+CD_XA_HEAD)
+CDROM_LBA = 0x01
+CDROM_MSF = 0x02
+CDROM_DATA_TRACK = 0x04
+CDROM_LEADOUT = 0xAA
+CDROM_AUDIO_INVALID = 0x00
+CDROM_AUDIO_PLAY = 0x11
+CDROM_AUDIO_PAUSED = 0x12
+CDROM_AUDIO_COMPLETED = 0x13
+CDROM_AUDIO_ERROR = 0x14
+CDROM_AUDIO_NO_STATUS = 0x15
+CDC_CLOSE_TRAY = 0x1
+CDC_OPEN_TRAY = 0x2
+CDC_LOCK = 0x4
+CDC_SELECT_SPEED = 0x8
+CDC_SELECT_DISC = 0x10
+CDC_MULTI_SESSION = 0x20
+CDC_MCN = 0x40
+CDC_MEDIA_CHANGED = 0x80
+CDC_PLAY_AUDIO = 0x100
+CDC_RESET = 0x200
+CDC_IOCTLS = 0x400
+CDC_DRIVE_STATUS = 0x800
+CDC_GENERIC_PACKET = 0x1000
+CDC_CD_R = 0x2000
+CDC_CD_RW = 0x4000
+CDC_DVD = 0x8000
+CDC_DVD_R = 0x10000
+CDC_DVD_RAM = 0x20000
+CDS_NO_INFO = 0
+CDS_NO_DISC = 1
+CDS_TRAY_OPEN = 2
+CDS_DRIVE_NOT_READY = 3
+CDS_DISC_OK = 4
+CDS_AUDIO = 100
+CDS_DATA_1 = 101
+CDS_DATA_2 = 102
+CDS_XA_2_1 = 103
+CDS_XA_2_2 = 104
+CDS_MIXED = 105
+CDO_AUTO_CLOSE = 0x1
+CDO_AUTO_EJECT = 0x2
+CDO_USE_FFLAGS = 0x4
+CDO_LOCK = 0x8
+CDO_CHECK_TYPE = 0x10
+CD_PART_MAX = 64
+CD_PART_MASK = (CD_PART_MAX - 1)
+GPCMD_BLANK = 0xa1
+GPCMD_CLOSE_TRACK = 0x5b
+GPCMD_FLUSH_CACHE = 0x35
+GPCMD_FORMAT_UNIT = 0x04
+GPCMD_GET_CONFIGURATION = 0x46
+GPCMD_GET_EVENT_STATUS_NOTIFICATION = 0x4a
+GPCMD_GET_PERFORMANCE = 0xac
+GPCMD_INQUIRY = 0x12
+GPCMD_LOAD_UNLOAD = 0xa6
+GPCMD_MECHANISM_STATUS = 0xbd
+GPCMD_MODE_SELECT_10 = 0x55
+GPCMD_MODE_SENSE_10 = 0x5a
+GPCMD_PAUSE_RESUME = 0x4b
+GPCMD_PLAY_AUDIO_10 = 0x45
+GPCMD_PLAY_AUDIO_MSF = 0x47
+GPCMD_PLAY_AUDIO_TI = 0x48
+GPCMD_PLAY_CD = 0xbc
+GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL = 0x1e
+GPCMD_READ_10 = 0x28
+GPCMD_READ_12 = 0xa8
+GPCMD_READ_CDVD_CAPACITY = 0x25
+GPCMD_READ_CD = 0xbe
+GPCMD_READ_CD_MSF = 0xb9
+GPCMD_READ_DISC_INFO = 0x51
+GPCMD_READ_DVD_STRUCTURE = 0xad
+GPCMD_READ_FORMAT_CAPACITIES = 0x23
+GPCMD_READ_HEADER = 0x44
+GPCMD_READ_TRACK_RZONE_INFO = 0x52
+GPCMD_READ_SUBCHANNEL = 0x42
+GPCMD_READ_TOC_PMA_ATIP = 0x43
+GPCMD_REPAIR_RZONE_TRACK = 0x58
+GPCMD_REPORT_KEY = 0xa4
+GPCMD_REQUEST_SENSE = 0x03
+GPCMD_RESERVE_RZONE_TRACK = 0x53
+GPCMD_SCAN = 0xba
+GPCMD_SEEK = 0x2b
+GPCMD_SEND_DVD_STRUCTURE = 0xad
+GPCMD_SEND_EVENT = 0xa2
+GPCMD_SEND_KEY = 0xa3
+GPCMD_SEND_OPC = 0x54
+GPCMD_SET_READ_AHEAD = 0xa7
+GPCMD_SET_STREAMING = 0xb6
+GPCMD_START_STOP_UNIT = 0x1b
+GPCMD_STOP_PLAY_SCAN = 0x4e
+GPCMD_TEST_UNIT_READY = 0x00
+GPCMD_VERIFY_10 = 0x2f
+GPCMD_WRITE_10 = 0x2a
+GPCMD_WRITE_AND_VERIFY_10 = 0x2e
+GPCMD_SET_SPEED = 0xbb
+GPCMD_PLAYAUDIO_TI = 0x48
+GPCMD_GET_MEDIA_STATUS = 0xda
+GPMODE_R_W_ERROR_PAGE = 0x01
+GPMODE_WRITE_PARMS_PAGE = 0x05
+GPMODE_AUDIO_CTL_PAGE = 0x0e
+GPMODE_POWER_PAGE = 0x1a
+GPMODE_FAULT_FAIL_PAGE = 0x1c
+GPMODE_TO_PROTECT_PAGE = 0x1d
+GPMODE_CAPABILITIES_PAGE = 0x2a
+GPMODE_ALL_PAGES = 0x3f
+GPMODE_CDROM_PAGE = 0x0d
+DVD_STRUCT_PHYSICAL = 0x00
+DVD_STRUCT_COPYRIGHT = 0x01
+DVD_STRUCT_DISCKEY = 0x02
+DVD_STRUCT_BCA = 0x03
+DVD_STRUCT_MANUFACT = 0x04
+DVD_LAYERS = 4
+DVD_LU_SEND_AGID = 0
+DVD_HOST_SEND_CHALLENGE = 1
+DVD_LU_SEND_KEY1 = 2
+DVD_LU_SEND_CHALLENGE = 3
+DVD_HOST_SEND_KEY2 = 4
+DVD_AUTH_ESTABLISHED = 5
+DVD_AUTH_FAILURE = 6
+DVD_LU_SEND_TITLE_KEY = 7
+DVD_LU_SEND_ASF = 8
+DVD_INVALIDATE_AGID = 9
+DVD_LU_SEND_RPC_STATE = 10
+DVD_HOST_SEND_RPC_STATE = 11
+DVD_CPM_NO_COPYRIGHT = 0
+DVD_CPM_COPYRIGHTED = 1
+DVD_CP_SEC_NONE = 0
+DVD_CP_SEC_EXIST = 1
+DVD_CGMS_UNRESTRICTED = 0
+DVD_CGMS_SINGLE = 2
+DVD_CGMS_RESTRICTED = 3
+
+CDROM_MAX_SLOTS = 256

Added: vendor/Python/current/Lib/plat-linux2/DLFCN.py
===================================================================
--- vendor/Python/current/Lib/plat-linux2/DLFCN.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-linux2/DLFCN.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,83 @@
+# Generated by h2py from /usr/include/dlfcn.h
+_DLFCN_H = 1
+
+# Included from features.h
+_FEATURES_H = 1
+__USE_ANSI = 1
+__FAVOR_BSD = 1
+_ISOC99_SOURCE = 1
+_POSIX_SOURCE = 1
+_POSIX_C_SOURCE = 199506L
+_XOPEN_SOURCE = 600
+_XOPEN_SOURCE_EXTENDED = 1
+_LARGEFILE64_SOURCE = 1
+_BSD_SOURCE = 1
+_SVID_SOURCE = 1
+_BSD_SOURCE = 1
+_SVID_SOURCE = 1
+__USE_ISOC99 = 1
+_POSIX_SOURCE = 1
+_POSIX_C_SOURCE = 2
+_POSIX_C_SOURCE = 199506L
+__USE_POSIX = 1
+__USE_POSIX2 = 1
+__USE_POSIX199309 = 1
+__USE_POSIX199506 = 1
+__USE_XOPEN = 1
+__USE_XOPEN_EXTENDED = 1
+__USE_UNIX98 = 1
+_LARGEFILE_SOURCE = 1
+__USE_XOPEN2K = 1
+__USE_ISOC99 = 1
+__USE_XOPEN_EXTENDED = 1
+__USE_LARGEFILE = 1
+__USE_LARGEFILE64 = 1
+__USE_FILE_OFFSET64 = 1
+__USE_MISC = 1
+__USE_BSD = 1
+__USE_SVID = 1
+__USE_GNU = 1
+__USE_REENTRANT = 1
+__STDC_IEC_559__ = 1
+__STDC_IEC_559_COMPLEX__ = 1
+__STDC_ISO_10646__ = 200009L
+__GNU_LIBRARY__ = 6
+__GLIBC__ = 2
+__GLIBC_MINOR__ = 2
+
+# Included from sys/cdefs.h
+_SYS_CDEFS_H = 1
+def __PMT(args): return args
+
+def __P(args): return args
+
+def __PMT(args): return args
+
+def __STRING(x): return #x
+
+__flexarr = []
+__flexarr = [0]
+__flexarr = []
+__flexarr = [1]
+def __ASMNAME(cname): return __ASMNAME2 (__USER_LABEL_PREFIX__, cname)
+
+def __attribute__(xyz): return
+
+def __attribute_format_arg__(x): return __attribute__ ((__format_arg__ (x)))
+
+def __attribute_format_arg__(x): return
+
+__USE_LARGEFILE = 1
+__USE_LARGEFILE64 = 1
+__USE_EXTERN_INLINES = 1
+
+# Included from gnu/stubs.h
+
+# Included from bits/dlfcn.h
+RTLD_LAZY = 0x00001
+RTLD_NOW = 0x00002
+RTLD_BINDING_MASK = 0x3
+RTLD_NOLOAD = 0x00004
+RTLD_GLOBAL = 0x00100
+RTLD_LOCAL = 0
+RTLD_NODELETE = 0x01000

Added: vendor/Python/current/Lib/plat-linux2/IN.py
===================================================================
--- vendor/Python/current/Lib/plat-linux2/IN.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-linux2/IN.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,615 @@
+# Generated by h2py from /usr/include/netinet/in.h
+_NETINET_IN_H = 1
+
+# Included from features.h
+_FEATURES_H = 1
+__USE_ANSI = 1
+__FAVOR_BSD = 1
+_ISOC99_SOURCE = 1
+_POSIX_SOURCE = 1
+_POSIX_C_SOURCE = 199506L
+_XOPEN_SOURCE = 600
+_XOPEN_SOURCE_EXTENDED = 1
+_LARGEFILE64_SOURCE = 1
+_BSD_SOURCE = 1
+_SVID_SOURCE = 1
+_BSD_SOURCE = 1
+_SVID_SOURCE = 1
+__USE_ISOC99 = 1
+_POSIX_SOURCE = 1
+_POSIX_C_SOURCE = 2
+_POSIX_C_SOURCE = 199506L
+__USE_POSIX = 1
+__USE_POSIX2 = 1
+__USE_POSIX199309 = 1
+__USE_POSIX199506 = 1
+__USE_XOPEN = 1
+__USE_XOPEN_EXTENDED = 1
+__USE_UNIX98 = 1
+_LARGEFILE_SOURCE = 1
+__USE_XOPEN2K = 1
+__USE_ISOC99 = 1
+__USE_XOPEN_EXTENDED = 1
+__USE_LARGEFILE = 1
+__USE_LARGEFILE64 = 1
+__USE_FILE_OFFSET64 = 1
+__USE_MISC = 1
+__USE_BSD = 1
+__USE_SVID = 1
+__USE_GNU = 1
+__USE_REENTRANT = 1
+__STDC_IEC_559__ = 1
+__STDC_IEC_559_COMPLEX__ = 1
+__STDC_ISO_10646__ = 200009L
+__GNU_LIBRARY__ = 6
+__GLIBC__ = 2
+__GLIBC_MINOR__ = 2
+
+# Included from sys/cdefs.h
+_SYS_CDEFS_H = 1
+def __PMT(args): return args
+
+def __P(args): return args
+
+def __PMT(args): return args
+
+def __STRING(x): return #x
+
+__flexarr = []
+__flexarr = [0]
+__flexarr = []
+__flexarr = [1]
+def __ASMNAME(cname): return __ASMNAME2 (__USER_LABEL_PREFIX__, cname)
+
+def __attribute__(xyz): return
+
+def __attribute_format_arg__(x): return __attribute__ ((__format_arg__ (x)))
+
+def __attribute_format_arg__(x): return
+
+__USE_LARGEFILE = 1
+__USE_LARGEFILE64 = 1
+__USE_EXTERN_INLINES = 1
+
+# Included from gnu/stubs.h
+
+# Included from stdint.h
+_STDINT_H = 1
+
+# Included from bits/wchar.h
+_BITS_WCHAR_H = 1
+__WCHAR_MIN = (-2147483647l - 1l)
+__WCHAR_MAX = (2147483647l)
+
+# Included from bits/wordsize.h
+__WORDSIZE = 32
+def __INT64_C(c): return c ## L
+
+def __UINT64_C(c): return c ## UL
+
+def __INT64_C(c): return c ## LL
+
+def __UINT64_C(c): return c ## ULL
+
+INT8_MIN = (-128)
+INT16_MIN = (-32767-1)
+INT32_MIN = (-2147483647-1)
+INT64_MIN = (-__INT64_C(9223372036854775807)-1)
+INT8_MAX = (127)
+INT16_MAX = (32767)
+INT32_MAX = (2147483647)
+INT64_MAX = (__INT64_C(9223372036854775807))
+UINT8_MAX = (255)
+UINT16_MAX = (65535)
+UINT64_MAX = (__UINT64_C(18446744073709551615))
+INT_LEAST8_MIN = (-128)
+INT_LEAST16_MIN = (-32767-1)
+INT_LEAST32_MIN = (-2147483647-1)
+INT_LEAST64_MIN = (-__INT64_C(9223372036854775807)-1)
+INT_LEAST8_MAX = (127)
+INT_LEAST16_MAX = (32767)
+INT_LEAST32_MAX = (2147483647)
+INT_LEAST64_MAX = (__INT64_C(9223372036854775807))
+UINT_LEAST8_MAX = (255)
+UINT_LEAST16_MAX = (65535)
+UINT_LEAST64_MAX = (__UINT64_C(18446744073709551615))
+INT_FAST8_MIN = (-128)
+INT_FAST16_MIN = (-9223372036854775807L-1)
+INT_FAST32_MIN = (-9223372036854775807L-1)
+INT_FAST16_MIN = (-2147483647-1)
+INT_FAST32_MIN = (-2147483647-1)
+INT_FAST64_MIN = (-__INT64_C(9223372036854775807)-1)
+INT_FAST8_MAX = (127)
+INT_FAST16_MAX = (9223372036854775807L)
+INT_FAST32_MAX = (9223372036854775807L)
+INT_FAST16_MAX = (2147483647)
+INT_FAST32_MAX = (2147483647)
+INT_FAST64_MAX = (__INT64_C(9223372036854775807))
+UINT_FAST8_MAX = (255)
+UINT_FAST64_MAX = (__UINT64_C(18446744073709551615))
+INTPTR_MIN = (-9223372036854775807L-1)
+INTPTR_MAX = (9223372036854775807L)
+INTPTR_MIN = (-2147483647-1)
+INTPTR_MAX = (2147483647)
+INTMAX_MIN = (-__INT64_C(9223372036854775807)-1)
+INTMAX_MAX = (__INT64_C(9223372036854775807))
+UINTMAX_MAX = (__UINT64_C(18446744073709551615))
+PTRDIFF_MIN = (-9223372036854775807L-1)
+PTRDIFF_MAX = (9223372036854775807L)
+PTRDIFF_MIN = (-2147483647-1)
+PTRDIFF_MAX = (2147483647)
+SIG_ATOMIC_MIN = (-2147483647-1)
+SIG_ATOMIC_MAX = (2147483647)
+WCHAR_MIN = __WCHAR_MIN
+WCHAR_MAX = __WCHAR_MAX
+def INT8_C(c): return c
+
+def INT16_C(c): return c
+
+def INT32_C(c): return c
+
+def INT64_C(c): return c ## L
+
+def INT64_C(c): return c ## LL
+
+def UINT8_C(c): return c ## U
+
+def UINT16_C(c): return c ## U
+
+def UINT32_C(c): return c ## U
+
+def UINT64_C(c): return c ## UL
+
+def UINT64_C(c): return c ## ULL
+
+def INTMAX_C(c): return c ## L
+
+def UINTMAX_C(c): return c ## UL
+
+def INTMAX_C(c): return c ## LL
+
+def UINTMAX_C(c): return c ## ULL
+
+
+# Included from bits/types.h
+_BITS_TYPES_H = 1
+__FD_SETSIZE = 1024
+
+# Included from bits/pthreadtypes.h
+_BITS_PTHREADTYPES_H = 1
+
+# Included from bits/sched.h
+SCHED_OTHER = 0
+SCHED_FIFO = 1
+SCHED_RR = 2
+CSIGNAL = 0x000000ff
+CLONE_VM = 0x00000100
+CLONE_FS = 0x00000200
+CLONE_FILES = 0x00000400
+CLONE_SIGHAND = 0x00000800
+CLONE_PID = 0x00001000
+CLONE_PTRACE = 0x00002000
+CLONE_VFORK = 0x00004000
+__defined_schedparam = 1
+def IN_CLASSA(a): return ((((in_addr_t)(a)) & (-2147483648)) == 0)
+
+IN_CLASSA_NET = (-16777216)
+IN_CLASSA_NSHIFT = 24
+IN_CLASSA_HOST = ((-1) & ~IN_CLASSA_NET)
+IN_CLASSA_MAX = 128
+def IN_CLASSB(a): return ((((in_addr_t)(a)) & (-1073741824)) == (-2147483648))
+
+IN_CLASSB_NET = (-65536)
+IN_CLASSB_NSHIFT = 16
+IN_CLASSB_HOST = ((-1) & ~IN_CLASSB_NET)
+IN_CLASSB_MAX = 65536
+def IN_CLASSC(a): return ((((in_addr_t)(a)) & (-536870912)) == (-1073741824))
+
+IN_CLASSC_NET = (-256)
+IN_CLASSC_NSHIFT = 8
+IN_CLASSC_HOST = ((-1) & ~IN_CLASSC_NET)
+def IN_CLASSD(a): return ((((in_addr_t)(a)) & (-268435456)) == (-536870912))
+
+def IN_MULTICAST(a): return IN_CLASSD(a)
+
+def IN_EXPERIMENTAL(a): return ((((in_addr_t)(a)) & (-536870912)) == (-536870912))
+
+def IN_BADCLASS(a): return ((((in_addr_t)(a)) & (-268435456)) == (-268435456))
+
+IN_LOOPBACKNET = 127
+INET_ADDRSTRLEN = 16
+INET6_ADDRSTRLEN = 46
+
+# Included from bits/socket.h
+
+# Included from limits.h
+_LIBC_LIMITS_H_ = 1
+MB_LEN_MAX = 16
+_LIMITS_H = 1
+CHAR_BIT = 8
+SCHAR_MIN = (-128)
+SCHAR_MAX = 127
+UCHAR_MAX = 255
+CHAR_MIN = 0
+CHAR_MAX = UCHAR_MAX
+CHAR_MIN = SCHAR_MIN
+CHAR_MAX = SCHAR_MAX
+SHRT_MIN = (-32768)
+SHRT_MAX = 32767
+USHRT_MAX = 65535
+INT_MAX = 2147483647
+LONG_MAX = 9223372036854775807L
+LONG_MAX = 2147483647L
+LONG_MIN = (-LONG_MAX - 1L)
+
+# Included from bits/posix1_lim.h
+_BITS_POSIX1_LIM_H = 1
+_POSIX_AIO_LISTIO_MAX = 2
+_POSIX_AIO_MAX = 1
+_POSIX_ARG_MAX = 4096
+_POSIX_CHILD_MAX = 6
+_POSIX_DELAYTIMER_MAX = 32
+_POSIX_LINK_MAX = 8
+_POSIX_MAX_CANON = 255
+_POSIX_MAX_INPUT = 255
+_POSIX_MQ_OPEN_MAX = 8
+_POSIX_MQ_PRIO_MAX = 32
+_POSIX_NGROUPS_MAX = 0
+_POSIX_OPEN_MAX = 16
+_POSIX_FD_SETSIZE = _POSIX_OPEN_MAX
+_POSIX_NAME_MAX = 14
+_POSIX_PATH_MAX = 256
+_POSIX_PIPE_BUF = 512
+_POSIX_RTSIG_MAX = 8
+_POSIX_SEM_NSEMS_MAX = 256
+_POSIX_SEM_VALUE_MAX = 32767
+_POSIX_SIGQUEUE_MAX = 32
+_POSIX_SSIZE_MAX = 32767
+_POSIX_STREAM_MAX = 8
+_POSIX_TZNAME_MAX = 6
+_POSIX_QLIMIT = 1
+_POSIX_HIWAT = _POSIX_PIPE_BUF
+_POSIX_UIO_MAXIOV = 16
+_POSIX_TTY_NAME_MAX = 9
+_POSIX_TIMER_MAX = 32
+_POSIX_LOGIN_NAME_MAX = 9
+_POSIX_CLOCKRES_MIN = 20000000
+
+# Included from bits/local_lim.h
+
+# Included from linux/limits.h
+NR_OPEN = 1024
+NGROUPS_MAX = 32
+ARG_MAX = 131072
+CHILD_MAX = 999
+OPEN_MAX = 256
+LINK_MAX = 127
+MAX_CANON = 255
+MAX_INPUT = 255
+NAME_MAX = 255
+PATH_MAX = 4096
+PIPE_BUF = 4096
+RTSIG_MAX = 32
+_POSIX_THREAD_KEYS_MAX = 128
+PTHREAD_KEYS_MAX = 1024
+_POSIX_THREAD_DESTRUCTOR_ITERATIONS = 4
+PTHREAD_DESTRUCTOR_ITERATIONS = _POSIX_THREAD_DESTRUCTOR_ITERATIONS
+_POSIX_THREAD_THREADS_MAX = 64
+PTHREAD_THREADS_MAX = 1024
+AIO_PRIO_DELTA_MAX = 20
+PTHREAD_STACK_MIN = 16384
+TIMER_MAX = 256
+SSIZE_MAX = LONG_MAX
+NGROUPS_MAX = _POSIX_NGROUPS_MAX
+
+# Included from bits/posix2_lim.h
+_BITS_POSIX2_LIM_H = 1
+_POSIX2_BC_BASE_MAX = 99
+_POSIX2_BC_DIM_MAX = 2048
+_POSIX2_BC_SCALE_MAX = 99
+_POSIX2_BC_STRING_MAX = 1000
+_POSIX2_COLL_WEIGHTS_MAX = 2
+_POSIX2_EXPR_NEST_MAX = 32
+_POSIX2_LINE_MAX = 2048
+_POSIX2_RE_DUP_MAX = 255
+_POSIX2_CHARCLASS_NAME_MAX = 14
+BC_BASE_MAX = _POSIX2_BC_BASE_MAX
+BC_DIM_MAX = _POSIX2_BC_DIM_MAX
+BC_SCALE_MAX = _POSIX2_BC_SCALE_MAX
+BC_STRING_MAX = _POSIX2_BC_STRING_MAX
+COLL_WEIGHTS_MAX = 255
+EXPR_NEST_MAX = _POSIX2_EXPR_NEST_MAX
+LINE_MAX = _POSIX2_LINE_MAX
+CHARCLASS_NAME_MAX = 2048
+RE_DUP_MAX = (0x7fff)
+
+# Included from bits/xopen_lim.h
+_XOPEN_LIM_H = 1
+
+# Included from bits/stdio_lim.h
+L_tmpnam = 20
+TMP_MAX = 238328
+FILENAME_MAX = 4096
+L_ctermid = 9
+L_cuserid = 9
+FOPEN_MAX = 16
+IOV_MAX = 1024
+_XOPEN_IOV_MAX = _POSIX_UIO_MAXIOV
+NL_ARGMAX = _POSIX_ARG_MAX
+NL_LANGMAX = _POSIX2_LINE_MAX
+NL_MSGMAX = INT_MAX
+NL_NMAX = INT_MAX
+NL_SETMAX = INT_MAX
+NL_TEXTMAX = INT_MAX
+NZERO = 20
+WORD_BIT = 16
+WORD_BIT = 32
+WORD_BIT = 64
+WORD_BIT = 16
+WORD_BIT = 32
+WORD_BIT = 64
+WORD_BIT = 32
+LONG_BIT = 32
+LONG_BIT = 64
+LONG_BIT = 32
+LONG_BIT = 64
+LONG_BIT = 64
+LONG_BIT = 32
+from TYPES import *
+PF_UNSPEC = 0
+PF_LOCAL = 1
+PF_UNIX = PF_LOCAL
+PF_FILE = PF_LOCAL
+PF_INET = 2
+PF_AX25 = 3
+PF_IPX = 4
+PF_APPLETALK = 5
+PF_NETROM = 6
+PF_BRIDGE = 7
+PF_ATMPVC = 8
+PF_X25 = 9
+PF_INET6 = 10
+PF_ROSE = 11
+PF_DECnet = 12
+PF_NETBEUI = 13
+PF_SECURITY = 14
+PF_KEY = 15
+PF_NETLINK = 16
+PF_ROUTE = PF_NETLINK
+PF_PACKET = 17
+PF_ASH = 18
+PF_ECONET = 19
+PF_ATMSVC = 20
+PF_SNA = 22
+PF_IRDA = 23
+PF_PPPOX = 24
+PF_WANPIPE = 25
+PF_BLUETOOTH = 31
+PF_MAX = 32
+AF_UNSPEC = PF_UNSPEC
+AF_LOCAL = PF_LOCAL
+AF_UNIX = PF_UNIX
+AF_FILE = PF_FILE
+AF_INET = PF_INET
+AF_AX25 = PF_AX25
+AF_IPX = PF_IPX
+AF_APPLETALK = PF_APPLETALK
+AF_NETROM = PF_NETROM
+AF_BRIDGE = PF_BRIDGE
+AF_ATMPVC = PF_ATMPVC
+AF_X25 = PF_X25
+AF_INET6 = PF_INET6
+AF_ROSE = PF_ROSE
+AF_DECnet = PF_DECnet
+AF_NETBEUI = PF_NETBEUI
+AF_SECURITY = PF_SECURITY
+AF_KEY = PF_KEY
+AF_NETLINK = PF_NETLINK
+AF_ROUTE = PF_ROUTE
+AF_PACKET = PF_PACKET
+AF_ASH = PF_ASH
+AF_ECONET = PF_ECONET
+AF_ATMSVC = PF_ATMSVC
+AF_SNA = PF_SNA
+AF_IRDA = PF_IRDA
+AF_PPPOX = PF_PPPOX
+AF_WANPIPE = PF_WANPIPE
+AF_BLUETOOTH = PF_BLUETOOTH
+AF_MAX = PF_MAX
+SOL_RAW = 255
+SOL_DECNET = 261
+SOL_X25 = 262
+SOL_PACKET = 263
+SOL_ATM = 264
+SOL_AAL = 265
+SOL_IRDA = 266
+SOMAXCONN = 128
+
+# Included from bits/sockaddr.h
+_BITS_SOCKADDR_H = 1
+def __SOCKADDR_COMMON(sa_prefix): return \
+
+_SS_SIZE = 128
+def CMSG_FIRSTHDR(mhdr): return \
+
+
+# Included from asm/socket.h
+
+# Included from asm/sockios.h
+FIOSETOWN = 0x8901
+SIOCSPGRP = 0x8902
+FIOGETOWN = 0x8903
+SIOCGPGRP = 0x8904
+SIOCATMARK = 0x8905
+SIOCGSTAMP = 0x8906
+SOL_SOCKET = 1
+SO_DEBUG = 1
+SO_REUSEADDR = 2
+SO_TYPE = 3
+SO_ERROR = 4
+SO_DONTROUTE = 5
+SO_BROADCAST = 6
+SO_SNDBUF = 7
+SO_RCVBUF = 8
+SO_KEEPALIVE = 9
+SO_OOBINLINE = 10
+SO_NO_CHECK = 11
+SO_PRIORITY = 12
+SO_LINGER = 13
+SO_BSDCOMPAT = 14
+SO_PASSCRED = 16
+SO_PEERCRED = 17
+SO_RCVLOWAT = 18
+SO_SNDLOWAT = 19
+SO_RCVTIMEO = 20
+SO_SNDTIMEO = 21
+SO_SECURITY_AUTHENTICATION = 22
+SO_SECURITY_ENCRYPTION_TRANSPORT = 23
+SO_SECURITY_ENCRYPTION_NETWORK = 24
+SO_BINDTODEVICE = 25
+SO_ATTACH_FILTER = 26
+SO_DETACH_FILTER = 27
+SO_PEERNAME = 28
+SO_TIMESTAMP = 29
+SCM_TIMESTAMP = SO_TIMESTAMP
+SO_ACCEPTCONN = 30
+SOCK_STREAM = 1
+SOCK_DGRAM = 2
+SOCK_RAW = 3
+SOCK_RDM = 4
+SOCK_SEQPACKET = 5
+SOCK_PACKET = 10
+SOCK_MAX = (SOCK_PACKET+1)
+
+# Included from bits/in.h
+IP_TOS = 1
+IP_TTL = 2
+IP_HDRINCL = 3
+IP_OPTIONS = 4
+IP_ROUTER_ALERT = 5
+IP_RECVOPTS = 6
+IP_RETOPTS = 7
+IP_PKTINFO = 8
+IP_PKTOPTIONS = 9
+IP_PMTUDISC = 10
+IP_MTU_DISCOVER = 10
+IP_RECVERR = 11
+IP_RECVTTL = 12
+IP_RECVTOS = 13
+IP_MULTICAST_IF = 32
+IP_MULTICAST_TTL = 33
+IP_MULTICAST_LOOP = 34
+IP_ADD_MEMBERSHIP = 35
+IP_DROP_MEMBERSHIP = 36
+IP_RECVRETOPTS = IP_RETOPTS
+IP_PMTUDISC_DONT = 0
+IP_PMTUDISC_WANT = 1
+IP_PMTUDISC_DO = 2
+SOL_IP = 0
+IP_DEFAULT_MULTICAST_TTL = 1
+IP_DEFAULT_MULTICAST_LOOP = 1
+IP_MAX_MEMBERSHIPS = 20
+IPV6_ADDRFORM = 1
+IPV6_PKTINFO = 2
+IPV6_HOPOPTS = 3
+IPV6_DSTOPTS = 4
+IPV6_RTHDR = 5
+IPV6_PKTOPTIONS = 6
+IPV6_CHECKSUM = 7
+IPV6_HOPLIMIT = 8
+IPV6_NEXTHOP = 9
+IPV6_AUTHHDR = 10
+IPV6_UNICAST_HOPS = 16
+IPV6_MULTICAST_IF = 17
+IPV6_MULTICAST_HOPS = 18
+IPV6_MULTICAST_LOOP = 19
+IPV6_JOIN_GROUP = 20
+IPV6_LEAVE_GROUP = 21
+IPV6_ROUTER_ALERT = 22
+IPV6_MTU_DISCOVER = 23
+IPV6_MTU = 24
+IPV6_RECVERR = 25
+IPV6_RXHOPOPTS = IPV6_HOPOPTS
+IPV6_RXDSTOPTS = IPV6_DSTOPTS
+IPV6_ADD_MEMBERSHIP = IPV6_JOIN_GROUP
+IPV6_DROP_MEMBERSHIP = IPV6_LEAVE_GROUP
+IPV6_PMTUDISC_DONT = 0
+IPV6_PMTUDISC_WANT = 1
+IPV6_PMTUDISC_DO = 2
+SOL_IPV6 = 41
+SOL_ICMPV6 = 58
+IPV6_RTHDR_LOOSE = 0
+IPV6_RTHDR_STRICT = 1
+IPV6_RTHDR_TYPE_0 = 0
+
+# Included from endian.h
+_ENDIAN_H = 1
+__LITTLE_ENDIAN = 1234
+__BIG_ENDIAN = 4321
+__PDP_ENDIAN = 3412
+
+# Included from bits/endian.h
+__BYTE_ORDER = __LITTLE_ENDIAN
+__FLOAT_WORD_ORDER = __BYTE_ORDER
+LITTLE_ENDIAN = __LITTLE_ENDIAN
+BIG_ENDIAN = __BIG_ENDIAN
+PDP_ENDIAN = __PDP_ENDIAN
+BYTE_ORDER = __BYTE_ORDER
+
+# Included from bits/byteswap.h
+_BITS_BYTESWAP_H = 1
+def __bswap_constant_16(x): return \
+
+def __bswap_16(x): return \
+
+def __bswap_16(x): return __bswap_constant_16 (x)
+
+def __bswap_constant_32(x): return \
+
+def __bswap_32(x): return \
+
+def __bswap_32(x): return \
+
+def __bswap_32(x): return __bswap_constant_32 (x)
+
+def __bswap_constant_64(x): return \
+
+def __bswap_64(x): return \
+
+def ntohl(x): return (x)
+
+def ntohs(x): return (x)
+
+def htonl(x): return (x)
+
+def htons(x): return (x)
+
+def ntohl(x): return __bswap_32 (x)
+
+def ntohs(x): return __bswap_16 (x)
+
+def htonl(x): return __bswap_32 (x)
+
+def htons(x): return __bswap_16 (x)
+
+def IN6_IS_ADDR_UNSPECIFIED(a): return \
+
+def IN6_IS_ADDR_LOOPBACK(a): return \
+
+def IN6_IS_ADDR_LINKLOCAL(a): return \
+
+def IN6_IS_ADDR_SITELOCAL(a): return \
+
+def IN6_IS_ADDR_V4MAPPED(a): return \
+
+def IN6_IS_ADDR_V4COMPAT(a): return \
+
+def IN6_IS_ADDR_MC_NODELOCAL(a): return \
+
+def IN6_IS_ADDR_MC_LINKLOCAL(a): return \
+
+def IN6_IS_ADDR_MC_SITELOCAL(a): return \
+
+def IN6_IS_ADDR_MC_ORGLOCAL(a): return \
+
+def IN6_IS_ADDR_MC_GLOBAL(a): return

Added: vendor/Python/current/Lib/plat-linux2/TYPES.py
===================================================================
--- vendor/Python/current/Lib/plat-linux2/TYPES.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-linux2/TYPES.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,170 @@
+# Generated by h2py from /usr/include/sys/types.h
+_SYS_TYPES_H = 1
+
+# Included from features.h
+_FEATURES_H = 1
+__USE_ANSI = 1
+__FAVOR_BSD = 1
+_ISOC99_SOURCE = 1
+_POSIX_SOURCE = 1
+_POSIX_C_SOURCE = 199506L
+_XOPEN_SOURCE = 600
+_XOPEN_SOURCE_EXTENDED = 1
+_LARGEFILE64_SOURCE = 1
+_BSD_SOURCE = 1
+_SVID_SOURCE = 1
+_BSD_SOURCE = 1
+_SVID_SOURCE = 1
+__USE_ISOC99 = 1
+_POSIX_SOURCE = 1
+_POSIX_C_SOURCE = 2
+_POSIX_C_SOURCE = 199506L
+__USE_POSIX = 1
+__USE_POSIX2 = 1
+__USE_POSIX199309 = 1
+__USE_POSIX199506 = 1
+__USE_XOPEN = 1
+__USE_XOPEN_EXTENDED = 1
+__USE_UNIX98 = 1
+_LARGEFILE_SOURCE = 1
+__USE_XOPEN2K = 1
+__USE_ISOC99 = 1
+__USE_XOPEN_EXTENDED = 1
+__USE_LARGEFILE = 1
+__USE_LARGEFILE64 = 1
+__USE_FILE_OFFSET64 = 1
+__USE_MISC = 1
+__USE_BSD = 1
+__USE_SVID = 1
+__USE_GNU = 1
+__USE_REENTRANT = 1
+__STDC_IEC_559__ = 1
+__STDC_IEC_559_COMPLEX__ = 1
+__STDC_ISO_10646__ = 200009L
+__GNU_LIBRARY__ = 6
+__GLIBC__ = 2
+__GLIBC_MINOR__ = 2
+
+# Included from sys/cdefs.h
+_SYS_CDEFS_H = 1
+def __PMT(args): return args
+
+def __P(args): return args
+
+def __PMT(args): return args
+
+def __STRING(x): return #x
+
+__flexarr = []
+__flexarr = [0]
+__flexarr = []
+__flexarr = [1]
+def __ASMNAME(cname): return __ASMNAME2 (__USER_LABEL_PREFIX__, cname)
+
+def __attribute__(xyz): return
+
+def __attribute_format_arg__(x): return __attribute__ ((__format_arg__ (x)))
+
+def __attribute_format_arg__(x): return
+
+__USE_LARGEFILE = 1
+__USE_LARGEFILE64 = 1
+__USE_EXTERN_INLINES = 1
+
+# Included from gnu/stubs.h
+
+# Included from bits/types.h
+_BITS_TYPES_H = 1
+__FD_SETSIZE = 1024
+
+# Included from bits/pthreadtypes.h
+_BITS_PTHREADTYPES_H = 1
+
+# Included from bits/sched.h
+SCHED_OTHER = 0
+SCHED_FIFO = 1
+SCHED_RR = 2
+CSIGNAL = 0x000000ff
+CLONE_VM = 0x00000100
+CLONE_FS = 0x00000200
+CLONE_FILES = 0x00000400
+CLONE_SIGHAND = 0x00000800
+CLONE_PID = 0x00001000
+CLONE_PTRACE = 0x00002000
+CLONE_VFORK = 0x00004000
+__defined_schedparam = 1
+
+# Included from time.h
+_TIME_H = 1
+
+# Included from bits/time.h
+_BITS_TIME_H = 1
+CLOCKS_PER_SEC = 1000000l
+CLOCK_REALTIME = 0
+CLOCK_PROCESS_CPUTIME_ID = 2
+CLOCK_THREAD_CPUTIME_ID = 3
+TIMER_ABSTIME = 1
+_STRUCT_TIMEVAL = 1
+CLK_TCK = CLOCKS_PER_SEC
+__clock_t_defined = 1
+__time_t_defined = 1
+__clockid_t_defined = 1
+__timer_t_defined = 1
+__timespec_defined = 1
+def __isleap(year): return \
+
+__BIT_TYPES_DEFINED__ = 1
+
+# Included from endian.h
+_ENDIAN_H = 1
+__LITTLE_ENDIAN = 1234
+__BIG_ENDIAN = 4321
+__PDP_ENDIAN = 3412
+
+# Included from bits/endian.h
+__BYTE_ORDER = __LITTLE_ENDIAN
+__FLOAT_WORD_ORDER = __BYTE_ORDER
+LITTLE_ENDIAN = __LITTLE_ENDIAN
+BIG_ENDIAN = __BIG_ENDIAN
+PDP_ENDIAN = __PDP_ENDIAN
+BYTE_ORDER = __BYTE_ORDER
+
+# Included from sys/select.h
+_SYS_SELECT_H = 1
+
+# Included from bits/select.h
+def __FD_ZERO(fdsp): return \
+
+def __FD_ZERO(set): return \
+
+
+# Included from bits/sigset.h
+_SIGSET_H_types = 1
+_SIGSET_H_fns = 1
+def __sigmask(sig): return \
+
+def __sigemptyset(set): return \
+
+def __sigfillset(set): return \
+
+def __sigisemptyset(set): return \
+
+def __FDELT(d): return ((d) / __NFDBITS)
+
+FD_SETSIZE = __FD_SETSIZE
+def FD_ZERO(fdsetp): return __FD_ZERO (fdsetp)
+
+
+# Included from sys/sysmacros.h
+_SYS_SYSMACROS_H = 1
+def major(dev): return ((int)(((dev) >> 8) & 0xff))
+
+def minor(dev): return ((int)((dev) & 0xff))
+
+def major(dev): return (((dev).__val[1] >> 8) & 0xff)
+
+def minor(dev): return ((dev).__val[1] & 0xff)
+
+def major(dev): return (((dev).__val[0] >> 8) & 0xff)
+
+def minor(dev): return ((dev).__val[0] & 0xff)

Added: vendor/Python/current/Lib/plat-linux2/regen
===================================================================
--- vendor/Python/current/Lib/plat-linux2/regen	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-linux2/regen	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,8 @@
+#! /bin/sh
+case `uname` in
+Linux*)	;;
+*)	echo Probably not on a Linux system 1>&2
+	exit 1;;
+esac
+set -v
+h2py -i '(u_long)' /usr/include/sys/types.h /usr/include/netinet/in.h /usr/include/dlfcn.h


Property changes on: vendor/Python/current/Lib/plat-linux2/regen
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/plat-mac/Audio_mac.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Audio_mac.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Audio_mac.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,121 @@
+QSIZE = 100000
+error='Audio_mac.error'
+
+class Play_Audio_mac:
+
+    def __init__(self, qsize=QSIZE):
+        self._chan = None
+        self._qsize = qsize
+        self._outrate = 22254
+        self._sampwidth = 1
+        self._nchannels = 1
+        self._gc = []
+        self._usercallback = None
+
+    def __del__(self):
+        self.stop()
+        self._usercallback = None
+
+    def wait(self):
+        import time
+        while self.getfilled():
+            time.sleep(0.1)
+        self._chan = None
+        self._gc = []
+
+    def stop(self, quietNow = 1):
+        ##chan = self._chan
+        self._chan = None
+        ##chan.SndDisposeChannel(1)
+        self._gc = []
+
+    def setoutrate(self, outrate):
+        self._outrate = outrate
+
+    def setsampwidth(self, sampwidth):
+        self._sampwidth = sampwidth
+
+    def setnchannels(self, nchannels):
+        self._nchannels = nchannels
+
+    def writeframes(self, data):
+        import time
+        from Carbon.Sound import bufferCmd, callBackCmd, extSH
+        import struct
+        import MacOS
+        if not self._chan:
+            from Carbon import Snd
+            self._chan = Snd.SndNewChannel(5, 0, self._callback)
+        nframes = len(data) / self._nchannels / self._sampwidth
+        if len(data) != nframes * self._nchannels * self._sampwidth:
+            raise error, 'data is not a whole number of frames'
+        while self._gc and \
+              self.getfilled() + nframes > \
+                self._qsize / self._nchannels / self._sampwidth:
+            time.sleep(0.1)
+        if self._sampwidth == 1:
+            import audioop
+            data = audioop.add(data, '\x80'*len(data), 1)
+        h1 = struct.pack('llHhllbbl',
+            id(data)+MacOS.string_id_to_buffer,
+            self._nchannels,
+            self._outrate, 0,
+            0,
+            0,
+            extSH,
+            60,
+            nframes)
+        h2 = 22*'\0'
+        h3 = struct.pack('hhlll',
+            self._sampwidth*8,
+            0,
+            0,
+            0,
+            0)
+        header = h1+h2+h3
+        self._gc.append((header, data))
+        self._chan.SndDoCommand((bufferCmd, 0, header), 0)
+        self._chan.SndDoCommand((callBackCmd, 0, 0), 0)
+
+    def _callback(self, *args):
+        del self._gc[0]
+        if self._usercallback:
+            self._usercallback()
+
+    def setcallback(self, callback):
+        self._usercallback = callback
+
+    def getfilled(self):
+        filled = 0
+        for header, data in self._gc:
+            filled = filled + len(data)
+        return filled / self._nchannels / self._sampwidth
+
+    def getfillable(self):
+        return (self._qsize / self._nchannels / self._sampwidth) - self.getfilled()
+
+    def ulaw2lin(self, data):
+        import audioop
+        return audioop.ulaw2lin(data, 2)
+
+def test():
+    import aifc
+    import EasyDialogs
+    fn = EasyDialogs.AskFileForOpen(message="Select an AIFF soundfile", typeList=("AIFF",))
+    if not fn: return
+    af = aifc.open(fn, 'r')
+    print af.getparams()
+    p = Play_Audio_mac()
+    p.setoutrate(af.getframerate())
+    p.setsampwidth(af.getsampwidth())
+    p.setnchannels(af.getnchannels())
+    BUFSIZ = 10000
+    while 1:
+        data = af.readframes(BUFSIZ)
+        if not data: break
+        p.writeframes(data)
+        print 'wrote', len(data), 'space', p.getfillable()
+    p.wait()
+
+if __name__ == '__main__':
+    test()

Added: vendor/Python/current/Lib/plat-mac/Carbon/AE.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/AE.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/AE.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1 @@
+from _AE import *

Added: vendor/Python/current/Lib/plat-mac/Carbon/AH.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/AH.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/AH.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1 @@
+from _AH import *

Added: vendor/Python/current/Lib/plat-mac/Carbon/Alias.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/Alias.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/Alias.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1 @@
+from _Alias import *

Added: vendor/Python/current/Lib/plat-mac/Carbon/Aliases.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/Aliases.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/Aliases.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,18 @@
+# Generated from 'Aliases.h'
+
+def FOUR_CHAR_CODE(x): return x
+true = True
+false = False
+rAliasType = FOUR_CHAR_CODE('alis')
+kARMMountVol = 0x00000001
+kARMNoUI = 0x00000002
+kARMMultVols = 0x00000008
+kARMSearch = 0x00000100
+kARMSearchMore = 0x00000200
+kARMSearchRelFirst = 0x00000400
+asiZoneName = -3
+asiServerName = -2
+asiVolumeName = -1
+asiAliasName = 0
+asiParentName = 1
+kResolveAliasFileNoUI = 0x00000001

Added: vendor/Python/current/Lib/plat-mac/Carbon/App.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/App.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/App.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1 @@
+from _App import *

Added: vendor/Python/current/Lib/plat-mac/Carbon/Appearance.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/Appearance.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/Appearance.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,648 @@
+# Generated from 'Appearance.h'
+
+def FOUR_CHAR_CODE(x): return x
+kAppearanceEventClass = FOUR_CHAR_CODE('appr')
+kAEAppearanceChanged = FOUR_CHAR_CODE('thme')
+kAESystemFontChanged = FOUR_CHAR_CODE('sysf')
+kAESmallSystemFontChanged = FOUR_CHAR_CODE('ssfn')
+kAEViewsFontChanged = FOUR_CHAR_CODE('vfnt')
+kThemeDataFileType = FOUR_CHAR_CODE('thme')
+kThemePlatinumFileType = FOUR_CHAR_CODE('pltn')
+kThemeCustomThemesFileType = FOUR_CHAR_CODE('scen')
+kThemeSoundTrackFileType = FOUR_CHAR_CODE('tsnd')
+kThemeBrushDialogBackgroundActive = 1
+kThemeBrushDialogBackgroundInactive = 2
+kThemeBrushAlertBackgroundActive = 3
+kThemeBrushAlertBackgroundInactive = 4
+kThemeBrushModelessDialogBackgroundActive = 5
+kThemeBrushModelessDialogBackgroundInactive = 6
+kThemeBrushUtilityWindowBackgroundActive = 7
+kThemeBrushUtilityWindowBackgroundInactive = 8
+kThemeBrushListViewSortColumnBackground = 9
+kThemeBrushListViewBackground = 10
+kThemeBrushIconLabelBackground = 11
+kThemeBrushListViewSeparator = 12
+kThemeBrushChasingArrows = 13
+kThemeBrushDragHilite = 14
+kThemeBrushDocumentWindowBackground = 15
+kThemeBrushFinderWindowBackground = 16
+kThemeBrushScrollBarDelimiterActive = 17
+kThemeBrushScrollBarDelimiterInactive = 18
+kThemeBrushFocusHighlight = 19
+kThemeBrushPopupArrowActive = 20
+kThemeBrushPopupArrowPressed = 21
+kThemeBrushPopupArrowInactive = 22
+kThemeBrushAppleGuideCoachmark = 23
+kThemeBrushIconLabelBackgroundSelected = 24
+kThemeBrushStaticAreaFill = 25
+kThemeBrushActiveAreaFill = 26
+kThemeBrushButtonFrameActive = 27
+kThemeBrushButtonFrameInactive = 28
+kThemeBrushButtonFaceActive = 29
+kThemeBrushButtonFaceInactive = 30
+kThemeBrushButtonFacePressed = 31
+kThemeBrushButtonActiveDarkShadow = 32
+kThemeBrushButtonActiveDarkHighlight = 33
+kThemeBrushButtonActiveLightShadow = 34
+kThemeBrushButtonActiveLightHighlight = 35
+kThemeBrushButtonInactiveDarkShadow = 36
+kThemeBrushButtonInactiveDarkHighlight = 37
+kThemeBrushButtonInactiveLightShadow = 38
+kThemeBrushButtonInactiveLightHighlight = 39
+kThemeBrushButtonPressedDarkShadow = 40
+kThemeBrushButtonPressedDarkHighlight = 41
+kThemeBrushButtonPressedLightShadow = 42
+kThemeBrushButtonPressedLightHighlight = 43
+kThemeBrushBevelActiveLight = 44
+kThemeBrushBevelActiveDark = 45
+kThemeBrushBevelInactiveLight = 46
+kThemeBrushBevelInactiveDark = 47
+kThemeBrushNotificationWindowBackground = 48
+kThemeBrushMovableModalBackground = 49
+kThemeBrushSheetBackgroundOpaque = 50
+kThemeBrushDrawerBackground = 51
+kThemeBrushToolbarBackground = 52
+kThemeBrushSheetBackgroundTransparent = 53
+kThemeBrushMenuBackground = 54
+kThemeBrushMenuBackgroundSelected = 55
+kThemeBrushSheetBackground = kThemeBrushSheetBackgroundOpaque
+kThemeBrushBlack = -1
+kThemeBrushWhite = -2
+kThemeBrushPrimaryHighlightColor = -3
+kThemeBrushSecondaryHighlightColor = -4
+kThemeTextColorDialogActive = 1
+kThemeTextColorDialogInactive = 2
+kThemeTextColorAlertActive = 3
+kThemeTextColorAlertInactive = 4
+kThemeTextColorModelessDialogActive = 5
+kThemeTextColorModelessDialogInactive = 6
+kThemeTextColorWindowHeaderActive = 7
+kThemeTextColorWindowHeaderInactive = 8
+kThemeTextColorPlacardActive = 9
+kThemeTextColorPlacardInactive = 10
+kThemeTextColorPlacardPressed = 11
+kThemeTextColorPushButtonActive = 12
+kThemeTextColorPushButtonInactive = 13
+kThemeTextColorPushButtonPressed = 14
+kThemeTextColorBevelButtonActive = 15
+kThemeTextColorBevelButtonInactive = 16
+kThemeTextColorBevelButtonPressed = 17
+kThemeTextColorPopupButtonActive = 18
+kThemeTextColorPopupButtonInactive = 19
+kThemeTextColorPopupButtonPressed = 20
+kThemeTextColorIconLabel = 21
+kThemeTextColorListView = 22
+kThemeTextColorDocumentWindowTitleActive = 23
+kThemeTextColorDocumentWindowTitleInactive = 24
+kThemeTextColorMovableModalWindowTitleActive = 25
+kThemeTextColorMovableModalWindowTitleInactive = 26
+kThemeTextColorUtilityWindowTitleActive = 27
+kThemeTextColorUtilityWindowTitleInactive = 28
+kThemeTextColorPopupWindowTitleActive = 29
+kThemeTextColorPopupWindowTitleInactive = 30
+kThemeTextColorRootMenuActive = 31
+kThemeTextColorRootMenuSelected = 32
+kThemeTextColorRootMenuDisabled = 33
+kThemeTextColorMenuItemActive = 34
+kThemeTextColorMenuItemSelected = 35
+kThemeTextColorMenuItemDisabled = 36
+kThemeTextColorPopupLabelActive = 37
+kThemeTextColorPopupLabelInactive = 38
+kThemeTextColorTabFrontActive = 39
+kThemeTextColorTabNonFrontActive = 40
+kThemeTextColorTabNonFrontPressed = 41
+kThemeTextColorTabFrontInactive = 42
+kThemeTextColorTabNonFrontInactive = 43
+kThemeTextColorIconLabelSelected = 44
+kThemeTextColorBevelButtonStickyActive = 45
+kThemeTextColorBevelButtonStickyInactive = 46
+kThemeTextColorNotification = 47
+kThemeTextColorBlack = -1
+kThemeTextColorWhite = -2
+kThemeStateInactive = 0
+kThemeStateActive = 1
+kThemeStatePressed = 2
+kThemeStateRollover = 6
+kThemeStateUnavailable = 7
+kThemeStateUnavailableInactive = 8
+kThemeStateDisabled = 0
+kThemeStatePressedUp = 2
+kThemeStatePressedDown = 3
+kThemeArrowCursor = 0
+kThemeCopyArrowCursor = 1
+kThemeAliasArrowCursor = 2
+kThemeContextualMenuArrowCursor = 3
+kThemeIBeamCursor = 4
+kThemeCrossCursor = 5
+kThemePlusCursor = 6
+kThemeWatchCursor = 7
+kThemeClosedHandCursor = 8
+kThemeOpenHandCursor = 9
+kThemePointingHandCursor = 10
+kThemeCountingUpHandCursor = 11
+kThemeCountingDownHandCursor = 12
+kThemeCountingUpAndDownHandCursor = 13
+kThemeSpinningCursor = 14
+kThemeResizeLeftCursor = 15
+kThemeResizeRightCursor = 16
+kThemeResizeLeftRightCursor = 17
+kThemeMenuBarNormal = 0
+kThemeMenuBarSelected = 1
+kThemeMenuSquareMenuBar = (1 << 0)
+kThemeMenuActive = 0
+kThemeMenuSelected = 1
+kThemeMenuDisabled = 3
+kThemeMenuTypePullDown = 0
+kThemeMenuTypePopUp = 1
+kThemeMenuTypeHierarchical = 2
+kThemeMenuTypeInactive = 0x0100
+kThemeMenuItemPlain = 0
+kThemeMenuItemHierarchical = 1
+kThemeMenuItemScrollUpArrow = 2
+kThemeMenuItemScrollDownArrow = 3
+kThemeMenuItemAtTop = 0x0100
+kThemeMenuItemAtBottom = 0x0200
+kThemeMenuItemHierBackground = 0x0400
+kThemeMenuItemPopUpBackground = 0x0800
+kThemeMenuItemHasIcon = 0x8000
+kThemeMenuItemNoBackground = 0x4000
+kThemeBackgroundTabPane = 1
+kThemeBackgroundPlacard = 2
+kThemeBackgroundWindowHeader = 3
+kThemeBackgroundListViewWindowHeader = 4
+kThemeBackgroundSecondaryGroupBox = 5
+kThemeNameTag = FOUR_CHAR_CODE('name')
+kThemeVariantNameTag = FOUR_CHAR_CODE('varn')
+kThemeVariantBaseTintTag = FOUR_CHAR_CODE('tint')
+kThemeHighlightColorTag = FOUR_CHAR_CODE('hcol')
+kThemeScrollBarArrowStyleTag = FOUR_CHAR_CODE('sbar')
+kThemeScrollBarThumbStyleTag = FOUR_CHAR_CODE('sbth')
+kThemeSoundsEnabledTag = FOUR_CHAR_CODE('snds')
+kThemeDblClickCollapseTag = FOUR_CHAR_CODE('coll')
+kThemeAppearanceFileNameTag = FOUR_CHAR_CODE('thme')
+kThemeSystemFontTag = FOUR_CHAR_CODE('lgsf')
+kThemeSmallSystemFontTag = FOUR_CHAR_CODE('smsf')
+kThemeViewsFontTag = FOUR_CHAR_CODE('vfnt')
+kThemeViewsFontSizeTag = FOUR_CHAR_CODE('vfsz')
+kThemeDesktopPatternNameTag = FOUR_CHAR_CODE('patn')
+kThemeDesktopPatternTag = FOUR_CHAR_CODE('patt')
+kThemeDesktopPictureNameTag = FOUR_CHAR_CODE('dpnm')
+kThemeDesktopPictureAliasTag = FOUR_CHAR_CODE('dpal')
+kThemeDesktopPictureAlignmentTag = FOUR_CHAR_CODE('dpan')
+kThemeHighlightColorNameTag = FOUR_CHAR_CODE('hcnm')
+kThemeExamplePictureIDTag = FOUR_CHAR_CODE('epic')
+kThemeSoundTrackNameTag = FOUR_CHAR_CODE('sndt')
+kThemeSoundMaskTag = FOUR_CHAR_CODE('smsk')
+kThemeUserDefinedTag = FOUR_CHAR_CODE('user')
+kThemeSmoothFontEnabledTag = FOUR_CHAR_CODE('smoo')
+kThemeSmoothFontMinSizeTag = FOUR_CHAR_CODE('smos')
+kTiledOnScreen = 1
+kCenterOnScreen = 2
+kFitToScreen = 3
+kFillScreen = 4
+kUseBestGuess = 5
+kThemeCheckBoxClassicX = 0
+kThemeCheckBoxCheckMark = 1
+kThemeScrollBarArrowsSingle = 0
+kThemeScrollBarArrowsLowerRight = 1
+kThemeScrollBarThumbNormal = 0
+kThemeScrollBarThumbProportional = 1
+kThemeSystemFont = 0
+kThemeSmallSystemFont = 1
+kThemeSmallEmphasizedSystemFont = 2
+kThemeViewsFont = 3
+kThemeEmphasizedSystemFont = 4
+kThemeApplicationFont = 5
+kThemeLabelFont = 6
+kThemeMenuTitleFont = 100
+kThemeMenuItemFont = 101
+kThemeMenuItemMarkFont = 102
+kThemeMenuItemCmdKeyFont = 103
+kThemeWindowTitleFont = 104
+kThemePushButtonFont = 105
+kThemeUtilityWindowTitleFont = 106
+kThemeAlertHeaderFont = 107
+kThemeCurrentPortFont = 200
+kThemeTabNonFront = 0
+kThemeTabNonFrontPressed = 1
+kThemeTabNonFrontInactive = 2
+kThemeTabFront = 3
+kThemeTabFrontInactive = 4
+kThemeTabNonFrontUnavailable = 5
+kThemeTabFrontUnavailable = 6
+kThemeTabNorth = 0
+kThemeTabSouth = 1
+kThemeTabEast = 2
+kThemeTabWest = 3
+kThemeSmallTabHeight = 16
+kThemeLargeTabHeight = 21
+kThemeTabPaneOverlap = 3
+kThemeSmallTabHeightMax = 19
+kThemeLargeTabHeightMax = 24
+kThemeMediumScrollBar = 0
+kThemeSmallScrollBar = 1
+kThemeMediumSlider = 2
+kThemeMediumProgressBar = 3
+kThemeMediumIndeterminateBar = 4
+kThemeRelevanceBar = 5
+kThemeSmallSlider = 6
+kThemeLargeProgressBar = 7
+kThemeLargeIndeterminateBar = 8
+kThemeTrackActive = 0
+kThemeTrackDisabled = 1
+kThemeTrackNothingToScroll = 2
+kThemeTrackInactive = 3
+kThemeLeftOutsideArrowPressed = 0x01
+kThemeLeftInsideArrowPressed = 0x02
+kThemeLeftTrackPressed = 0x04
+kThemeThumbPressed = 0x08
+kThemeRightTrackPressed = 0x10
+kThemeRightInsideArrowPressed = 0x20
+kThemeRightOutsideArrowPressed = 0x40
+kThemeTopOutsideArrowPressed = kThemeLeftOutsideArrowPressed
+kThemeTopInsideArrowPressed = kThemeLeftInsideArrowPressed
+kThemeTopTrackPressed = kThemeLeftTrackPressed
+kThemeBottomTrackPressed = kThemeRightTrackPressed
+kThemeBottomInsideArrowPressed = kThemeRightInsideArrowPressed
+kThemeBottomOutsideArrowPressed = kThemeRightOutsideArrowPressed
+kThemeThumbPlain = 0
+kThemeThumbUpward = 1
+kThemeThumbDownward = 2
+kThemeTrackHorizontal = (1 << 0)
+kThemeTrackRightToLeft = (1 << 1)
+kThemeTrackShowThumb = (1 << 2)
+kThemeTrackThumbRgnIsNotGhost = (1 << 3)
+kThemeTrackNoScrollBarArrows = (1 << 4)
+kThemeWindowHasGrow = (1 << 0)
+kThemeWindowHasHorizontalZoom = (1 << 3)
+kThemeWindowHasVerticalZoom = (1 << 4)
+kThemeWindowHasFullZoom = kThemeWindowHasHorizontalZoom + kThemeWindowHasVerticalZoom
+kThemeWindowHasCloseBox = (1 << 5)
+kThemeWindowHasCollapseBox = (1 << 6)
+kThemeWindowHasTitleText = (1 << 7)
+kThemeWindowIsCollapsed = (1 << 8)
+kThemeWindowHasDirty = (1 << 9)
+kThemeDocumentWindow = 0
+kThemeDialogWindow = 1
+kThemeMovableDialogWindow = 2
+kThemeAlertWindow = 3
+kThemeMovableAlertWindow = 4
+kThemePlainDialogWindow = 5
+kThemeShadowDialogWindow = 6
+kThemePopupWindow = 7
+kThemeUtilityWindow = 8
+kThemeUtilitySideWindow = 9
+kThemeSheetWindow = 10
+kThemeDrawerWindow = 11
+kThemeWidgetCloseBox = 0
+kThemeWidgetZoomBox = 1
+kThemeWidgetCollapseBox = 2
+kThemeWidgetDirtyCloseBox = 6
+kThemeArrowLeft = 0
+kThemeArrowDown = 1
+kThemeArrowRight = 2
+kThemeArrowUp = 3
+kThemeArrow3pt = 0
+kThemeArrow5pt = 1
+kThemeArrow7pt = 2
+kThemeArrow9pt = 3
+kThemeGrowLeft = (1 << 0)
+kThemeGrowRight = (1 << 1)
+kThemeGrowUp = (1 << 2)
+kThemeGrowDown = (1 << 3)
+kThemePushButton = 0
+kThemeCheckBox = 1
+kThemeRadioButton = 2
+kThemeBevelButton = 3
+kThemeArrowButton = 4
+kThemePopupButton = 5
+kThemeDisclosureButton = 6
+kThemeIncDecButton = 7
+kThemeSmallBevelButton = 8
+kThemeMediumBevelButton = 3
+kThemeLargeBevelButton = 9
+kThemeListHeaderButton = 10
+kThemeRoundButton = 11
+kThemeLargeRoundButton = 12
+kThemeSmallCheckBox = 13
+kThemeSmallRadioButton = 14
+kThemeRoundedBevelButton = 15
+kThemeNormalCheckBox = kThemeCheckBox
+kThemeNormalRadioButton = kThemeRadioButton
+kThemeButtonOff = 0
+kThemeButtonOn = 1
+kThemeButtonMixed = 2
+kThemeDisclosureRight = 0
+kThemeDisclosureDown = 1
+kThemeDisclosureLeft = 2
+kThemeAdornmentNone = 0
+kThemeAdornmentDefault = (1 << 0)
+kThemeAdornmentFocus = (1 << 2)
+kThemeAdornmentRightToLeft = (1 << 4)
+kThemeAdornmentDrawIndicatorOnly = (1 << 5)
+kThemeAdornmentHeaderButtonLeftNeighborSelected = (1 << 6)
+kThemeAdornmentHeaderButtonRightNeighborSelected = (1 << 7)
+kThemeAdornmentHeaderButtonSortUp = (1 << 8)
+kThemeAdornmentHeaderMenuButton = (1 << 9)
+kThemeAdornmentHeaderButtonNoShadow = (1 << 10)
+kThemeAdornmentHeaderButtonShadowOnly = (1 << 11)
+kThemeAdornmentNoShadow = kThemeAdornmentHeaderButtonNoShadow
+kThemeAdornmentShadowOnly = kThemeAdornmentHeaderButtonShadowOnly
+kThemeAdornmentArrowLeftArrow = (1 << 6)
+kThemeAdornmentArrowDownArrow = (1 << 7)
+kThemeAdornmentArrowDoubleArrow = (1 << 8)
+kThemeAdornmentArrowUpArrow = (1 << 9)
+kThemeNoSounds = 0
+kThemeWindowSoundsMask = (1 << 0)
+kThemeMenuSoundsMask = (1 << 1)
+kThemeControlSoundsMask = (1 << 2)
+kThemeFinderSoundsMask = (1 << 3)
+kThemeDragSoundNone = 0
+kThemeDragSoundMoveWindow = FOUR_CHAR_CODE('wmov')
+kThemeDragSoundGrowWindow = FOUR_CHAR_CODE('wgro')
+kThemeDragSoundMoveUtilWindow = FOUR_CHAR_CODE('umov')
+kThemeDragSoundGrowUtilWindow = FOUR_CHAR_CODE('ugro')
+kThemeDragSoundMoveDialog = FOUR_CHAR_CODE('dmov')
+kThemeDragSoundMoveAlert = FOUR_CHAR_CODE('amov')
+kThemeDragSoundMoveIcon = FOUR_CHAR_CODE('imov')
+kThemeDragSoundSliderThumb = FOUR_CHAR_CODE('slth')
+kThemeDragSoundSliderGhost = FOUR_CHAR_CODE('slgh')
+kThemeDragSoundScrollBarThumb = FOUR_CHAR_CODE('sbth')
+kThemeDragSoundScrollBarGhost = FOUR_CHAR_CODE('sbgh')
+kThemeDragSoundScrollBarArrowDecreasing = FOUR_CHAR_CODE('sbad')
+kThemeDragSoundScrollBarArrowIncreasing = FOUR_CHAR_CODE('sbai')
+kThemeDragSoundDragging = FOUR_CHAR_CODE('drag')
+kThemeSoundNone = 0
+kThemeSoundMenuOpen = FOUR_CHAR_CODE('mnuo')
+kThemeSoundMenuClose = FOUR_CHAR_CODE('mnuc')
+kThemeSoundMenuItemHilite = FOUR_CHAR_CODE('mnui')
+kThemeSoundMenuItemRelease = FOUR_CHAR_CODE('mnus')
+kThemeSoundWindowClosePress = FOUR_CHAR_CODE('wclp')
+kThemeSoundWindowCloseEnter = FOUR_CHAR_CODE('wcle')
+kThemeSoundWindowCloseExit = FOUR_CHAR_CODE('wclx')
+kThemeSoundWindowCloseRelease = FOUR_CHAR_CODE('wclr')
+kThemeSoundWindowZoomPress = FOUR_CHAR_CODE('wzmp')
+kThemeSoundWindowZoomEnter = FOUR_CHAR_CODE('wzme')
+kThemeSoundWindowZoomExit = FOUR_CHAR_CODE('wzmx')
+kThemeSoundWindowZoomRelease = FOUR_CHAR_CODE('wzmr')
+kThemeSoundWindowCollapsePress = FOUR_CHAR_CODE('wcop')
+kThemeSoundWindowCollapseEnter = FOUR_CHAR_CODE('wcoe')
+kThemeSoundWindowCollapseExit = FOUR_CHAR_CODE('wcox')
+kThemeSoundWindowCollapseRelease = FOUR_CHAR_CODE('wcor')
+kThemeSoundWindowDragBoundary = FOUR_CHAR_CODE('wdbd')
+kThemeSoundUtilWinClosePress = FOUR_CHAR_CODE('uclp')
+kThemeSoundUtilWinCloseEnter = FOUR_CHAR_CODE('ucle')
+kThemeSoundUtilWinCloseExit = FOUR_CHAR_CODE('uclx')
+kThemeSoundUtilWinCloseRelease = FOUR_CHAR_CODE('uclr')
+kThemeSoundUtilWinZoomPress = FOUR_CHAR_CODE('uzmp')
+kThemeSoundUtilWinZoomEnter = FOUR_CHAR_CODE('uzme')
+kThemeSoundUtilWinZoomExit = FOUR_CHAR_CODE('uzmx')
+kThemeSoundUtilWinZoomRelease = FOUR_CHAR_CODE('uzmr')
+kThemeSoundUtilWinCollapsePress = FOUR_CHAR_CODE('ucop')
+kThemeSoundUtilWinCollapseEnter = FOUR_CHAR_CODE('ucoe')
+kThemeSoundUtilWinCollapseExit = FOUR_CHAR_CODE('ucox')
+kThemeSoundUtilWinCollapseRelease = FOUR_CHAR_CODE('ucor')
+kThemeSoundUtilWinDragBoundary = FOUR_CHAR_CODE('udbd')
+kThemeSoundWindowOpen = FOUR_CHAR_CODE('wopn')
+kThemeSoundWindowClose = FOUR_CHAR_CODE('wcls')
+kThemeSoundWindowZoomIn = FOUR_CHAR_CODE('wzmi')
+kThemeSoundWindowZoomOut = FOUR_CHAR_CODE('wzmo')
+kThemeSoundWindowCollapseUp = FOUR_CHAR_CODE('wcol')
+kThemeSoundWindowCollapseDown = FOUR_CHAR_CODE('wexp')
+kThemeSoundWindowActivate = FOUR_CHAR_CODE('wact')
+kThemeSoundUtilWindowOpen = FOUR_CHAR_CODE('uopn')
+kThemeSoundUtilWindowClose = FOUR_CHAR_CODE('ucls')
+kThemeSoundUtilWindowZoomIn = FOUR_CHAR_CODE('uzmi')
+kThemeSoundUtilWindowZoomOut = FOUR_CHAR_CODE('uzmo')
+kThemeSoundUtilWindowCollapseUp = FOUR_CHAR_CODE('ucol')
+kThemeSoundUtilWindowCollapseDown = FOUR_CHAR_CODE('uexp')
+kThemeSoundUtilWindowActivate = FOUR_CHAR_CODE('uact')
+kThemeSoundDialogOpen = FOUR_CHAR_CODE('dopn')
+kThemeSoundDialogClose = FOUR_CHAR_CODE('dlgc')
+kThemeSoundAlertOpen = FOUR_CHAR_CODE('aopn')
+kThemeSoundAlertClose = FOUR_CHAR_CODE('altc')
+kThemeSoundPopupWindowOpen = FOUR_CHAR_CODE('pwop')
+kThemeSoundPopupWindowClose = FOUR_CHAR_CODE('pwcl')
+kThemeSoundButtonPress = FOUR_CHAR_CODE('btnp')
+kThemeSoundButtonEnter = FOUR_CHAR_CODE('btne')
+kThemeSoundButtonExit = FOUR_CHAR_CODE('btnx')
+kThemeSoundButtonRelease = FOUR_CHAR_CODE('btnr')
+kThemeSoundDefaultButtonPress = FOUR_CHAR_CODE('dbtp')
+kThemeSoundDefaultButtonEnter = FOUR_CHAR_CODE('dbte')
+kThemeSoundDefaultButtonExit = FOUR_CHAR_CODE('dbtx')
+kThemeSoundDefaultButtonRelease = FOUR_CHAR_CODE('dbtr')
+kThemeSoundCancelButtonPress = FOUR_CHAR_CODE('cbtp')
+kThemeSoundCancelButtonEnter = FOUR_CHAR_CODE('cbte')
+kThemeSoundCancelButtonExit = FOUR_CHAR_CODE('cbtx')
+kThemeSoundCancelButtonRelease = FOUR_CHAR_CODE('cbtr')
+kThemeSoundCheckboxPress = FOUR_CHAR_CODE('chkp')
+kThemeSoundCheckboxEnter = FOUR_CHAR_CODE('chke')
+kThemeSoundCheckboxExit = FOUR_CHAR_CODE('chkx')
+kThemeSoundCheckboxRelease = FOUR_CHAR_CODE('chkr')
+kThemeSoundRadioPress = FOUR_CHAR_CODE('radp')
+kThemeSoundRadioEnter = FOUR_CHAR_CODE('rade')
+kThemeSoundRadioExit = FOUR_CHAR_CODE('radx')
+kThemeSoundRadioRelease = FOUR_CHAR_CODE('radr')
+kThemeSoundScrollArrowPress = FOUR_CHAR_CODE('sbap')
+kThemeSoundScrollArrowEnter = FOUR_CHAR_CODE('sbae')
+kThemeSoundScrollArrowExit = FOUR_CHAR_CODE('sbax')
+kThemeSoundScrollArrowRelease = FOUR_CHAR_CODE('sbar')
+kThemeSoundScrollEndOfTrack = FOUR_CHAR_CODE('sbte')
+kThemeSoundScrollTrackPress = FOUR_CHAR_CODE('sbtp')
+kThemeSoundSliderEndOfTrack = FOUR_CHAR_CODE('slte')
+kThemeSoundSliderTrackPress = FOUR_CHAR_CODE('sltp')
+kThemeSoundBalloonOpen = FOUR_CHAR_CODE('blno')
+kThemeSoundBalloonClose = FOUR_CHAR_CODE('blnc')
+kThemeSoundBevelPress = FOUR_CHAR_CODE('bevp')
+kThemeSoundBevelEnter = FOUR_CHAR_CODE('beve')
+kThemeSoundBevelExit = FOUR_CHAR_CODE('bevx')
+kThemeSoundBevelRelease = FOUR_CHAR_CODE('bevr')
+kThemeSoundLittleArrowUpPress = FOUR_CHAR_CODE('laup')
+kThemeSoundLittleArrowDnPress = FOUR_CHAR_CODE('ladp')
+kThemeSoundLittleArrowEnter = FOUR_CHAR_CODE('lare')
+kThemeSoundLittleArrowExit = FOUR_CHAR_CODE('larx')
+kThemeSoundLittleArrowUpRelease = FOUR_CHAR_CODE('laur')
+kThemeSoundLittleArrowDnRelease = FOUR_CHAR_CODE('ladr')
+kThemeSoundPopupPress = FOUR_CHAR_CODE('popp')
+kThemeSoundPopupEnter = FOUR_CHAR_CODE('pope')
+kThemeSoundPopupExit = FOUR_CHAR_CODE('popx')
+kThemeSoundPopupRelease = FOUR_CHAR_CODE('popr')
+kThemeSoundDisclosurePress = FOUR_CHAR_CODE('dscp')
+kThemeSoundDisclosureEnter = FOUR_CHAR_CODE('dsce')
+kThemeSoundDisclosureExit = FOUR_CHAR_CODE('dscx')
+kThemeSoundDisclosureRelease = FOUR_CHAR_CODE('dscr')
+kThemeSoundTabPressed = FOUR_CHAR_CODE('tabp')
+kThemeSoundTabEnter = FOUR_CHAR_CODE('tabe')
+kThemeSoundTabExit = FOUR_CHAR_CODE('tabx')
+kThemeSoundTabRelease = FOUR_CHAR_CODE('tabr')
+kThemeSoundDragTargetHilite = FOUR_CHAR_CODE('dthi')
+kThemeSoundDragTargetUnhilite = FOUR_CHAR_CODE('dtuh')
+kThemeSoundDragTargetDrop = FOUR_CHAR_CODE('dtdr')
+kThemeSoundEmptyTrash = FOUR_CHAR_CODE('ftrs')
+kThemeSoundSelectItem = FOUR_CHAR_CODE('fsel')
+kThemeSoundNewItem = FOUR_CHAR_CODE('fnew')
+kThemeSoundReceiveDrop = FOUR_CHAR_CODE('fdrp')
+kThemeSoundCopyDone = FOUR_CHAR_CODE('fcpd')
+kThemeSoundResolveAlias = FOUR_CHAR_CODE('fral')
+kThemeSoundLaunchApp = FOUR_CHAR_CODE('flap')
+kThemeSoundDiskInsert = FOUR_CHAR_CODE('dski')
+kThemeSoundDiskEject = FOUR_CHAR_CODE('dske')
+kThemeSoundFinderDragOnIcon = FOUR_CHAR_CODE('fdon')
+kThemeSoundFinderDragOffIcon = FOUR_CHAR_CODE('fdof')
+kThemePopupTabNormalPosition = 0
+kThemePopupTabCenterOnWindow = 1
+kThemePopupTabCenterOnOffset = 2
+kThemeMetricScrollBarWidth = 0
+kThemeMetricSmallScrollBarWidth = 1
+kThemeMetricCheckBoxHeight = 2
+kThemeMetricRadioButtonHeight = 3
+kThemeMetricEditTextWhitespace = 4
+kThemeMetricEditTextFrameOutset = 5
+kThemeMetricListBoxFrameOutset = 6
+kThemeMetricFocusRectOutset = 7
+kThemeMetricImageWellThickness = 8
+kThemeMetricScrollBarOverlap = 9
+kThemeMetricLargeTabHeight = 10
+kThemeMetricLargeTabCapsWidth = 11
+kThemeMetricTabFrameOverlap = 12
+kThemeMetricTabIndentOrStyle = 13
+kThemeMetricTabOverlap = 14
+kThemeMetricSmallTabHeight = 15
+kThemeMetricSmallTabCapsWidth = 16
+kThemeMetricDisclosureButtonHeight = 17
+kThemeMetricRoundButtonSize = 18
+kThemeMetricPushButtonHeight = 19
+kThemeMetricListHeaderHeight = 20
+kThemeMetricSmallCheckBoxHeight = 21
+kThemeMetricDisclosureButtonWidth = 22
+kThemeMetricSmallDisclosureButtonHeight = 23
+kThemeMetricSmallDisclosureButtonWidth = 24
+kThemeMetricDisclosureTriangleHeight = 25
+kThemeMetricDisclosureTriangleWidth = 26
+kThemeMetricLittleArrowsHeight = 27
+kThemeMetricLittleArrowsWidth = 28
+kThemeMetricPaneSplitterHeight = 29
+kThemeMetricPopupButtonHeight = 30
+kThemeMetricSmallPopupButtonHeight = 31
+kThemeMetricLargeProgressBarThickness = 32
+kThemeMetricPullDownHeight = 33
+kThemeMetricSmallPullDownHeight = 34
+kThemeMetricSmallPushButtonHeight = 35
+kThemeMetricSmallRadioButtonHeight = 36
+kThemeMetricRelevanceIndicatorHeight = 37
+kThemeMetricResizeControlHeight = 38
+kThemeMetricSmallResizeControlHeight = 39
+kThemeMetricLargeRoundButtonSize = 40
+kThemeMetricHSliderHeight = 41
+kThemeMetricHSliderTickHeight = 42
+kThemeMetricSmallHSliderHeight = 43
+kThemeMetricSmallHSliderTickHeight = 44
+kThemeMetricVSliderWidth = 45
+kThemeMetricVSliderTickWidth = 46
+kThemeMetricSmallVSliderWidth = 47
+kThemeMetricSmallVSliderTickWidth = 48
+kThemeMetricTitleBarControlsHeight = 49
+kThemeMetricCheckBoxWidth = 50
+kThemeMetricSmallCheckBoxWidth = 51
+kThemeMetricRadioButtonWidth = 52
+kThemeMetricSmallRadioButtonWidth = 53
+kThemeMetricSmallHSliderMinThumbWidth = 54
+kThemeMetricSmallVSliderMinThumbHeight = 55
+kThemeMetricSmallHSliderTickOffset = 56
+kThemeMetricSmallVSliderTickOffset = 57
+kThemeMetricNormalProgressBarThickness = 58
+kThemeMetricProgressBarShadowOutset = 59
+kThemeMetricSmallProgressBarShadowOutset = 60
+kThemeMetricPrimaryGroupBoxContentInset = 61
+kThemeMetricSecondaryGroupBoxContentInset = 62
+kThemeMetricMenuMarkColumnWidth = 63
+kThemeMetricMenuExcludedMarkColumnWidth = 64
+kThemeMetricMenuMarkIndent = 65
+kThemeMetricMenuTextLeadingEdgeMargin = 66
+kThemeMetricMenuTextTrailingEdgeMargin = 67
+kThemeMetricMenuIndentWidth = 68
+kThemeMetricMenuIconTrailingEdgeMargin = 69
+# appearanceBadBrushIndexErr = themeInvalidBrushErr
+# appearanceProcessRegisteredErr = themeProcessRegisteredErr
+# appearanceProcessNotRegisteredErr = themeProcessNotRegisteredErr
+# appearanceBadTextColorIndexErr = themeBadTextColorErr
+# appearanceThemeHasNoAccents = themeHasNoAccentsErr
+# appearanceBadCursorIndexErr = themeBadCursorIndexErr
+kThemeActiveDialogBackgroundBrush = kThemeBrushDialogBackgroundActive
+kThemeInactiveDialogBackgroundBrush = kThemeBrushDialogBackgroundInactive
+kThemeActiveAlertBackgroundBrush = kThemeBrushAlertBackgroundActive
+kThemeInactiveAlertBackgroundBrush = kThemeBrushAlertBackgroundInactive
+kThemeActiveModelessDialogBackgroundBrush = kThemeBrushModelessDialogBackgroundActive
+kThemeInactiveModelessDialogBackgroundBrush = kThemeBrushModelessDialogBackgroundInactive
+kThemeActiveUtilityWindowBackgroundBrush = kThemeBrushUtilityWindowBackgroundActive
+kThemeInactiveUtilityWindowBackgroundBrush = kThemeBrushUtilityWindowBackgroundInactive
+kThemeListViewSortColumnBackgroundBrush = kThemeBrushListViewSortColumnBackground
+kThemeListViewBackgroundBrush = kThemeBrushListViewBackground
+kThemeIconLabelBackgroundBrush = kThemeBrushIconLabelBackground
+kThemeListViewSeparatorBrush = kThemeBrushListViewSeparator
+kThemeChasingArrowsBrush = kThemeBrushChasingArrows
+kThemeDragHiliteBrush = kThemeBrushDragHilite
+kThemeDocumentWindowBackgroundBrush = kThemeBrushDocumentWindowBackground
+kThemeFinderWindowBackgroundBrush = kThemeBrushFinderWindowBackground
+kThemeActiveScrollBarDelimiterBrush = kThemeBrushScrollBarDelimiterActive
+kThemeInactiveScrollBarDelimiterBrush = kThemeBrushScrollBarDelimiterInactive
+kThemeFocusHighlightBrush = kThemeBrushFocusHighlight
+kThemeActivePopupArrowBrush = kThemeBrushPopupArrowActive
+kThemePressedPopupArrowBrush = kThemeBrushPopupArrowPressed
+kThemeInactivePopupArrowBrush = kThemeBrushPopupArrowInactive
+kThemeAppleGuideCoachmarkBrush = kThemeBrushAppleGuideCoachmark
+kThemeActiveDialogTextColor = kThemeTextColorDialogActive
+kThemeInactiveDialogTextColor = kThemeTextColorDialogInactive
+kThemeActiveAlertTextColor = kThemeTextColorAlertActive
+kThemeInactiveAlertTextColor = kThemeTextColorAlertInactive
+kThemeActiveModelessDialogTextColor = kThemeTextColorModelessDialogActive
+kThemeInactiveModelessDialogTextColor = kThemeTextColorModelessDialogInactive
+kThemeActiveWindowHeaderTextColor = kThemeTextColorWindowHeaderActive
+kThemeInactiveWindowHeaderTextColor = kThemeTextColorWindowHeaderInactive
+kThemeActivePlacardTextColor = kThemeTextColorPlacardActive
+kThemeInactivePlacardTextColor = kThemeTextColorPlacardInactive
+kThemePressedPlacardTextColor = kThemeTextColorPlacardPressed
+kThemeActivePushButtonTextColor = kThemeTextColorPushButtonActive
+kThemeInactivePushButtonTextColor = kThemeTextColorPushButtonInactive
+kThemePressedPushButtonTextColor = kThemeTextColorPushButtonPressed
+kThemeActiveBevelButtonTextColor = kThemeTextColorBevelButtonActive
+kThemeInactiveBevelButtonTextColor = kThemeTextColorBevelButtonInactive
+kThemePressedBevelButtonTextColor = kThemeTextColorBevelButtonPressed
+kThemeActivePopupButtonTextColor = kThemeTextColorPopupButtonActive
+kThemeInactivePopupButtonTextColor = kThemeTextColorPopupButtonInactive
+kThemePressedPopupButtonTextColor = kThemeTextColorPopupButtonPressed
+kThemeIconLabelTextColor = kThemeTextColorIconLabel
+kThemeListViewTextColor = kThemeTextColorListView
+kThemeActiveDocumentWindowTitleTextColor = kThemeTextColorDocumentWindowTitleActive
+kThemeInactiveDocumentWindowTitleTextColor = kThemeTextColorDocumentWindowTitleInactive
+kThemeActiveMovableModalWindowTitleTextColor = kThemeTextColorMovableModalWindowTitleActive
+kThemeInactiveMovableModalWindowTitleTextColor = kThemeTextColorMovableModalWindowTitleInactive
+kThemeActiveUtilityWindowTitleTextColor = kThemeTextColorUtilityWindowTitleActive
+kThemeInactiveUtilityWindowTitleTextColor = kThemeTextColorUtilityWindowTitleInactive
+kThemeActivePopupWindowTitleColor = kThemeTextColorPopupWindowTitleActive
+kThemeInactivePopupWindowTitleColor = kThemeTextColorPopupWindowTitleInactive
+kThemeActiveRootMenuTextColor = kThemeTextColorRootMenuActive
+kThemeSelectedRootMenuTextColor = kThemeTextColorRootMenuSelected
+kThemeDisabledRootMenuTextColor = kThemeTextColorRootMenuDisabled
+kThemeActiveMenuItemTextColor = kThemeTextColorMenuItemActive
+kThemeSelectedMenuItemTextColor = kThemeTextColorMenuItemSelected
+kThemeDisabledMenuItemTextColor = kThemeTextColorMenuItemDisabled
+kThemeActivePopupLabelTextColor = kThemeTextColorPopupLabelActive
+kThemeInactivePopupLabelTextColor = kThemeTextColorPopupLabelInactive
+kAEThemeSwitch = kAEAppearanceChanged
+kThemeNoAdornment = kThemeAdornmentNone
+kThemeDefaultAdornment = kThemeAdornmentDefault
+kThemeFocusAdornment = kThemeAdornmentFocus
+kThemeRightToLeftAdornment = kThemeAdornmentRightToLeft
+kThemeDrawIndicatorOnly = kThemeAdornmentDrawIndicatorOnly
+kThemeBrushPassiveAreaFill = kThemeBrushStaticAreaFill
+kThemeMetricCheckBoxGlyphHeight = kThemeMetricCheckBoxHeight
+kThemeMetricRadioButtonGlyphHeight = kThemeMetricRadioButtonHeight
+kThemeMetricDisclosureButtonSize = kThemeMetricDisclosureButtonHeight
+kThemeMetricBestListHeaderHeight = kThemeMetricListHeaderHeight
+kThemeMetricSmallProgressBarThickness = kThemeMetricNormalProgressBarThickness
+kThemeMetricProgressBarThickness = kThemeMetricLargeProgressBarThickness
+kThemeScrollBar = kThemeMediumScrollBar
+kThemeSlider = kThemeMediumSlider
+kThemeProgressBar = kThemeMediumProgressBar
+kThemeIndeterminateBar = kThemeMediumIndeterminateBar

Added: vendor/Python/current/Lib/plat-mac/Carbon/AppleEvents.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/AppleEvents.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/AppleEvents.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,960 @@
+# Generated from 'AEDataModel.h'
+
+def FOUR_CHAR_CODE(x): return x
+typeBoolean = FOUR_CHAR_CODE('bool')
+typeChar = FOUR_CHAR_CODE('TEXT')
+typeSInt16 = FOUR_CHAR_CODE('shor')
+typeSInt32 = FOUR_CHAR_CODE('long')
+typeUInt32 = FOUR_CHAR_CODE('magn')
+typeSInt64 = FOUR_CHAR_CODE('comp')
+typeIEEE32BitFloatingPoint = FOUR_CHAR_CODE('sing')
+typeIEEE64BitFloatingPoint = FOUR_CHAR_CODE('doub')
+type128BitFloatingPoint = FOUR_CHAR_CODE('ldbl')
+typeDecimalStruct = FOUR_CHAR_CODE('decm')
+typeSMInt = typeSInt16
+typeShortInteger = typeSInt16
+typeInteger = typeSInt32
+typeLongInteger = typeSInt32
+typeMagnitude = typeUInt32
+typeComp = typeSInt64
+typeSMFloat = typeIEEE32BitFloatingPoint
+typeShortFloat = typeIEEE32BitFloatingPoint
+typeFloat = typeIEEE64BitFloatingPoint
+typeLongFloat = typeIEEE64BitFloatingPoint
+typeExtended = FOUR_CHAR_CODE('exte')
+typeAEList = FOUR_CHAR_CODE('list')
+typeAERecord = FOUR_CHAR_CODE('reco')
+typeAppleEvent = FOUR_CHAR_CODE('aevt')
+typeEventRecord = FOUR_CHAR_CODE('evrc')
+typeTrue = FOUR_CHAR_CODE('true')
+typeFalse = FOUR_CHAR_CODE('fals')
+typeAlias = FOUR_CHAR_CODE('alis')
+typeEnumerated = FOUR_CHAR_CODE('enum')
+typeType = FOUR_CHAR_CODE('type')
+typeAppParameters = FOUR_CHAR_CODE('appa')
+typeProperty = FOUR_CHAR_CODE('prop')
+typeFSS = FOUR_CHAR_CODE('fss ')
+typeFSRef = FOUR_CHAR_CODE('fsrf')
+typeFileURL = FOUR_CHAR_CODE('furl')
+typeKeyword = FOUR_CHAR_CODE('keyw')
+typeSectionH = FOUR_CHAR_CODE('sect')
+typeWildCard = FOUR_CHAR_CODE('****')
+typeApplSignature = FOUR_CHAR_CODE('sign')
+typeQDRectangle = FOUR_CHAR_CODE('qdrt')
+typeFixed = FOUR_CHAR_CODE('fixd')
+typeProcessSerialNumber = FOUR_CHAR_CODE('psn ')
+typeApplicationURL = FOUR_CHAR_CODE('aprl')
+typeNull = FOUR_CHAR_CODE('null')
+typeSessionID = FOUR_CHAR_CODE('ssid')
+typeTargetID = FOUR_CHAR_CODE('targ')
+typeDispatcherID = FOUR_CHAR_CODE('dspt')
+keyTransactionIDAttr = FOUR_CHAR_CODE('tran')
+keyReturnIDAttr = FOUR_CHAR_CODE('rtid')
+keyEventClassAttr = FOUR_CHAR_CODE('evcl')
+keyEventIDAttr = FOUR_CHAR_CODE('evid')
+keyAddressAttr = FOUR_CHAR_CODE('addr')
+keyOptionalKeywordAttr = FOUR_CHAR_CODE('optk')
+keyTimeoutAttr = FOUR_CHAR_CODE('timo')
+keyInteractLevelAttr = FOUR_CHAR_CODE('inte')
+keyEventSourceAttr = FOUR_CHAR_CODE('esrc')
+keyMissedKeywordAttr = FOUR_CHAR_CODE('miss')
+keyOriginalAddressAttr = FOUR_CHAR_CODE('from')
+keyAcceptTimeoutAttr = FOUR_CHAR_CODE('actm')
+kAEDescListFactorNone = 0
+kAEDescListFactorType = 4
+kAEDescListFactorTypeAndSize = 8
+kAutoGenerateReturnID = -1
+kAnyTransactionID = 0
+kAEDataArray = 0
+kAEPackedArray = 1
+kAEDescArray = 3
+kAEKeyDescArray = 4
+kAEHandleArray = 2
+kAENormalPriority = 0x00000000
+kAEHighPriority = 0x00000001
+kAENoReply = 0x00000001
+kAEQueueReply = 0x00000002
+kAEWaitReply = 0x00000003
+kAEDontReconnect = 0x00000080
+kAEWantReceipt = 0x00000200
+kAENeverInteract = 0x00000010
+kAECanInteract = 0x00000020
+kAEAlwaysInteract = 0x00000030
+kAECanSwitchLayer = 0x00000040
+kAEDontRecord = 0x00001000
+kAEDontExecute = 0x00002000
+kAEProcessNonReplyEvents = 0x00008000
+kAEDefaultTimeout = -1
+kNoTimeOut = -2
+kAEInteractWithSelf = 0
+kAEInteractWithLocal = 1
+kAEInteractWithAll = 2
+kAEDoNotIgnoreHandler = 0x00000000
+kAEIgnoreAppPhacHandler = 0x00000001
+kAEIgnoreAppEventHandler = 0x00000002
+kAEIgnoreSysPhacHandler = 0x00000004
+kAEIgnoreSysEventHandler = 0x00000008
+kAEIngoreBuiltInEventHandler = 0x00000010
+# kAEDontDisposeOnResume = (long)0x80000000
+kAENoDispatch = 0
+# kAEUseStandardDispatch = (long)0xFFFFFFFF
+keyDirectObject = FOUR_CHAR_CODE('----')
+keyErrorNumber = FOUR_CHAR_CODE('errn')
+keyErrorString = FOUR_CHAR_CODE('errs')
+keyProcessSerialNumber = FOUR_CHAR_CODE('psn ')
+keyPreDispatch = FOUR_CHAR_CODE('phac')
+keySelectProc = FOUR_CHAR_CODE('selh')
+keyAERecorderCount = FOUR_CHAR_CODE('recr')
+keyAEVersion = FOUR_CHAR_CODE('vers')
+kCoreEventClass = FOUR_CHAR_CODE('aevt')
+kAEOpenApplication = FOUR_CHAR_CODE('oapp')
+kAEOpenDocuments = FOUR_CHAR_CODE('odoc')
+kAEPrintDocuments = FOUR_CHAR_CODE('pdoc')
+kAEQuitApplication = FOUR_CHAR_CODE('quit')
+kAEAnswer = FOUR_CHAR_CODE('ansr')
+kAEApplicationDied = FOUR_CHAR_CODE('obit')
+kAEShowPreferences = FOUR_CHAR_CODE('pref')
+kAEStartRecording = FOUR_CHAR_CODE('reca')
+kAEStopRecording = FOUR_CHAR_CODE('recc')
+kAENotifyStartRecording = FOUR_CHAR_CODE('rec1')
+kAENotifyStopRecording = FOUR_CHAR_CODE('rec0')
+kAENotifyRecording = FOUR_CHAR_CODE('recr')
+kAEUnknownSource = 0
+kAEDirectCall = 1
+kAESameProcess = 2
+kAELocalProcess = 3
+kAERemoteProcess = 4
+cAEList = FOUR_CHAR_CODE('list')
+cApplication = FOUR_CHAR_CODE('capp')
+cArc = FOUR_CHAR_CODE('carc')
+cBoolean = FOUR_CHAR_CODE('bool')
+cCell = FOUR_CHAR_CODE('ccel')
+cChar = FOUR_CHAR_CODE('cha ')
+cColorTable = FOUR_CHAR_CODE('clrt')
+cColumn = FOUR_CHAR_CODE('ccol')
+cDocument = FOUR_CHAR_CODE('docu')
+cDrawingArea = FOUR_CHAR_CODE('cdrw')
+cEnumeration = FOUR_CHAR_CODE('enum')
+cFile = FOUR_CHAR_CODE('file')
+cFixed = FOUR_CHAR_CODE('fixd')
+cFixedPoint = FOUR_CHAR_CODE('fpnt')
+cFixedRectangle = FOUR_CHAR_CODE('frct')
+cGraphicLine = FOUR_CHAR_CODE('glin')
+cGraphicObject = FOUR_CHAR_CODE('cgob')
+cGraphicShape = FOUR_CHAR_CODE('cgsh')
+cGraphicText = FOUR_CHAR_CODE('cgtx')
+cGroupedGraphic = FOUR_CHAR_CODE('cpic')
+cInsertionLoc = FOUR_CHAR_CODE('insl')
+cInsertionPoint = FOUR_CHAR_CODE('cins')
+cIntlText = FOUR_CHAR_CODE('itxt')
+cIntlWritingCode = FOUR_CHAR_CODE('intl')
+cItem = FOUR_CHAR_CODE('citm')
+cLine = FOUR_CHAR_CODE('clin')
+cLongDateTime = FOUR_CHAR_CODE('ldt ')
+cLongFixed = FOUR_CHAR_CODE('lfxd')
+cLongFixedPoint = FOUR_CHAR_CODE('lfpt')
+cLongFixedRectangle = FOUR_CHAR_CODE('lfrc')
+cLongInteger = FOUR_CHAR_CODE('long')
+cLongPoint = FOUR_CHAR_CODE('lpnt')
+cLongRectangle = FOUR_CHAR_CODE('lrct')
+cMachineLoc = FOUR_CHAR_CODE('mLoc')
+cMenu = FOUR_CHAR_CODE('cmnu')
+cMenuItem = FOUR_CHAR_CODE('cmen')
+cObject = FOUR_CHAR_CODE('cobj')
+cObjectSpecifier = FOUR_CHAR_CODE('obj ')
+cOpenableObject = FOUR_CHAR_CODE('coob')
+cOval = FOUR_CHAR_CODE('covl')
+cParagraph = FOUR_CHAR_CODE('cpar')
+cPICT = FOUR_CHAR_CODE('PICT')
+cPixel = FOUR_CHAR_CODE('cpxl')
+cPixelMap = FOUR_CHAR_CODE('cpix')
+cPolygon = FOUR_CHAR_CODE('cpgn')
+cProperty = FOUR_CHAR_CODE('prop')
+cQDPoint = FOUR_CHAR_CODE('QDpt')
+cQDRectangle = FOUR_CHAR_CODE('qdrt')
+cRectangle = FOUR_CHAR_CODE('crec')
+cRGBColor = FOUR_CHAR_CODE('cRGB')
+cRotation = FOUR_CHAR_CODE('trot')
+cRoundedRectangle = FOUR_CHAR_CODE('crrc')
+cRow = FOUR_CHAR_CODE('crow')
+cSelection = FOUR_CHAR_CODE('csel')
+cShortInteger = FOUR_CHAR_CODE('shor')
+cTable = FOUR_CHAR_CODE('ctbl')
+cText = FOUR_CHAR_CODE('ctxt')
+cTextFlow = FOUR_CHAR_CODE('cflo')
+cTextStyles = FOUR_CHAR_CODE('tsty')
+cType = FOUR_CHAR_CODE('type')
+cVersion = FOUR_CHAR_CODE('vers')
+cWindow = FOUR_CHAR_CODE('cwin')
+cWord = FOUR_CHAR_CODE('cwor')
+enumArrows = FOUR_CHAR_CODE('arro')
+enumJustification = FOUR_CHAR_CODE('just')
+enumKeyForm = FOUR_CHAR_CODE('kfrm')
+enumPosition = FOUR_CHAR_CODE('posi')
+enumProtection = FOUR_CHAR_CODE('prtn')
+enumQuality = FOUR_CHAR_CODE('qual')
+enumSaveOptions = FOUR_CHAR_CODE('savo')
+enumStyle = FOUR_CHAR_CODE('styl')
+enumTransferMode = FOUR_CHAR_CODE('tran')
+formUniqueID = FOUR_CHAR_CODE('ID  ')
+kAEAbout = FOUR_CHAR_CODE('abou')
+kAEAfter = FOUR_CHAR_CODE('afte')
+kAEAliasSelection = FOUR_CHAR_CODE('sali')
+kAEAllCaps = FOUR_CHAR_CODE('alcp')
+kAEArrowAtEnd = FOUR_CHAR_CODE('aren')
+kAEArrowAtStart = FOUR_CHAR_CODE('arst')
+kAEArrowBothEnds = FOUR_CHAR_CODE('arbo')
+kAEAsk = FOUR_CHAR_CODE('ask ')
+kAEBefore = FOUR_CHAR_CODE('befo')
+kAEBeginning = FOUR_CHAR_CODE('bgng')
+kAEBeginsWith = FOUR_CHAR_CODE('bgwt')
+kAEBeginTransaction = FOUR_CHAR_CODE('begi')
+kAEBold = FOUR_CHAR_CODE('bold')
+kAECaseSensEquals = FOUR_CHAR_CODE('cseq')
+kAECentered = FOUR_CHAR_CODE('cent')
+kAEChangeView = FOUR_CHAR_CODE('view')
+kAEClone = FOUR_CHAR_CODE('clon')
+kAEClose = FOUR_CHAR_CODE('clos')
+kAECondensed = FOUR_CHAR_CODE('cond')
+kAEContains = FOUR_CHAR_CODE('cont')
+kAECopy = FOUR_CHAR_CODE('copy')
+kAECoreSuite = FOUR_CHAR_CODE('core')
+kAECountElements = FOUR_CHAR_CODE('cnte')
+kAECreateElement = FOUR_CHAR_CODE('crel')
+kAECreatePublisher = FOUR_CHAR_CODE('cpub')
+kAECut = FOUR_CHAR_CODE('cut ')
+kAEDelete = FOUR_CHAR_CODE('delo')
+kAEDoObjectsExist = FOUR_CHAR_CODE('doex')
+kAEDoScript = FOUR_CHAR_CODE('dosc')
+kAEDrag = FOUR_CHAR_CODE('drag')
+kAEDuplicateSelection = FOUR_CHAR_CODE('sdup')
+kAEEditGraphic = FOUR_CHAR_CODE('edit')
+kAEEmptyTrash = FOUR_CHAR_CODE('empt')
+kAEEnd = FOUR_CHAR_CODE('end ')
+kAEEndsWith = FOUR_CHAR_CODE('ends')
+kAEEndTransaction = FOUR_CHAR_CODE('endt')
+kAEEquals = FOUR_CHAR_CODE('=   ')
+kAEExpanded = FOUR_CHAR_CODE('pexp')
+kAEFast = FOUR_CHAR_CODE('fast')
+kAEFinderEvents = FOUR_CHAR_CODE('FNDR')
+kAEFormulaProtect = FOUR_CHAR_CODE('fpro')
+kAEFullyJustified = FOUR_CHAR_CODE('full')
+kAEGetClassInfo = FOUR_CHAR_CODE('qobj')
+kAEGetData = FOUR_CHAR_CODE('getd')
+kAEGetDataSize = FOUR_CHAR_CODE('dsiz')
+kAEGetEventInfo = FOUR_CHAR_CODE('gtei')
+kAEGetInfoSelection = FOUR_CHAR_CODE('sinf')
+kAEGetPrivilegeSelection = FOUR_CHAR_CODE('sprv')
+kAEGetSuiteInfo = FOUR_CHAR_CODE('gtsi')
+kAEGreaterThan = FOUR_CHAR_CODE('>   ')
+kAEGreaterThanEquals = FOUR_CHAR_CODE('>=  ')
+kAEGrow = FOUR_CHAR_CODE('grow')
+kAEHidden = FOUR_CHAR_CODE('hidn')
+kAEHiQuality = FOUR_CHAR_CODE('hiqu')
+kAEImageGraphic = FOUR_CHAR_CODE('imgr')
+kAEIsUniform = FOUR_CHAR_CODE('isun')
+kAEItalic = FOUR_CHAR_CODE('ital')
+kAELeftJustified = FOUR_CHAR_CODE('left')
+kAELessThan = FOUR_CHAR_CODE('<   ')
+kAELessThanEquals = FOUR_CHAR_CODE('<=  ')
+kAELowercase = FOUR_CHAR_CODE('lowc')
+kAEMakeObjectsVisible = FOUR_CHAR_CODE('mvis')
+kAEMiscStandards = FOUR_CHAR_CODE('misc')
+kAEModifiable = FOUR_CHAR_CODE('modf')
+kAEMove = FOUR_CHAR_CODE('move')
+kAENo = FOUR_CHAR_CODE('no  ')
+kAENoArrow = FOUR_CHAR_CODE('arno')
+kAENonmodifiable = FOUR_CHAR_CODE('nmod')
+kAEOpen = FOUR_CHAR_CODE('odoc')
+kAEOpenSelection = FOUR_CHAR_CODE('sope')
+kAEOutline = FOUR_CHAR_CODE('outl')
+kAEPageSetup = FOUR_CHAR_CODE('pgsu')
+kAEPaste = FOUR_CHAR_CODE('past')
+kAEPlain = FOUR_CHAR_CODE('plan')
+kAEPrint = FOUR_CHAR_CODE('pdoc')
+kAEPrintSelection = FOUR_CHAR_CODE('spri')
+kAEPrintWindow = FOUR_CHAR_CODE('pwin')
+kAEPutAwaySelection = FOUR_CHAR_CODE('sput')
+kAEQDAddOver = FOUR_CHAR_CODE('addo')
+kAEQDAddPin = FOUR_CHAR_CODE('addp')
+kAEQDAdMax = FOUR_CHAR_CODE('admx')
+kAEQDAdMin = FOUR_CHAR_CODE('admn')
+kAEQDBic = FOUR_CHAR_CODE('bic ')
+kAEQDBlend = FOUR_CHAR_CODE('blnd')
+kAEQDCopy = FOUR_CHAR_CODE('cpy ')
+kAEQDNotBic = FOUR_CHAR_CODE('nbic')
+kAEQDNotCopy = FOUR_CHAR_CODE('ncpy')
+kAEQDNotOr = FOUR_CHAR_CODE('ntor')
+kAEQDNotXor = FOUR_CHAR_CODE('nxor')
+kAEQDOr = FOUR_CHAR_CODE('or  ')
+kAEQDSubOver = FOUR_CHAR_CODE('subo')
+kAEQDSubPin = FOUR_CHAR_CODE('subp')
+kAEQDSupplementalSuite = FOUR_CHAR_CODE('qdsp')
+kAEQDXor = FOUR_CHAR_CODE('xor ')
+kAEQuickdrawSuite = FOUR_CHAR_CODE('qdrw')
+kAEQuitAll = FOUR_CHAR_CODE('quia')
+kAERedo = FOUR_CHAR_CODE('redo')
+kAERegular = FOUR_CHAR_CODE('regl')
+kAEReopenApplication = FOUR_CHAR_CODE('rapp')
+kAEReplace = FOUR_CHAR_CODE('rplc')
+kAERequiredSuite = FOUR_CHAR_CODE('reqd')
+kAERestart = FOUR_CHAR_CODE('rest')
+kAERevealSelection = FOUR_CHAR_CODE('srev')
+kAERevert = FOUR_CHAR_CODE('rvrt')
+kAERightJustified = FOUR_CHAR_CODE('rght')
+kAESave = FOUR_CHAR_CODE('save')
+kAESelect = FOUR_CHAR_CODE('slct')
+kAESetData = FOUR_CHAR_CODE('setd')
+kAESetPosition = FOUR_CHAR_CODE('posn')
+kAEShadow = FOUR_CHAR_CODE('shad')
+kAEShowClipboard = FOUR_CHAR_CODE('shcl')
+kAEShutDown = FOUR_CHAR_CODE('shut')
+kAESleep = FOUR_CHAR_CODE('slep')
+kAESmallCaps = FOUR_CHAR_CODE('smcp')
+kAESpecialClassProperties = FOUR_CHAR_CODE('c@#!')
+kAEStrikethrough = FOUR_CHAR_CODE('strk')
+kAESubscript = FOUR_CHAR_CODE('sbsc')
+kAESuperscript = FOUR_CHAR_CODE('spsc')
+kAETableSuite = FOUR_CHAR_CODE('tbls')
+kAETextSuite = FOUR_CHAR_CODE('TEXT')
+kAETransactionTerminated = FOUR_CHAR_CODE('ttrm')
+kAEUnderline = FOUR_CHAR_CODE('undl')
+kAEUndo = FOUR_CHAR_CODE('undo')
+kAEWholeWordEquals = FOUR_CHAR_CODE('wweq')
+kAEYes = FOUR_CHAR_CODE('yes ')
+kAEZoom = FOUR_CHAR_CODE('zoom')
+kAEMouseClass = FOUR_CHAR_CODE('mous')
+kAEDown = FOUR_CHAR_CODE('down')
+kAEUp = FOUR_CHAR_CODE('up  ')
+kAEMoved = FOUR_CHAR_CODE('move')
+kAEStoppedMoving = FOUR_CHAR_CODE('stop')
+kAEWindowClass = FOUR_CHAR_CODE('wind')
+kAEUpdate = FOUR_CHAR_CODE('updt')
+kAEActivate = FOUR_CHAR_CODE('actv')
+kAEDeactivate = FOUR_CHAR_CODE('dact')
+kAECommandClass = FOUR_CHAR_CODE('cmnd')
+kAEKeyClass = FOUR_CHAR_CODE('keyc')
+kAERawKey = FOUR_CHAR_CODE('rkey')
+kAEVirtualKey = FOUR_CHAR_CODE('keyc')
+kAENavigationKey = FOUR_CHAR_CODE('nave')
+kAEAutoDown = FOUR_CHAR_CODE('auto')
+kAEApplicationClass = FOUR_CHAR_CODE('appl')
+kAESuspend = FOUR_CHAR_CODE('susp')
+kAEResume = FOUR_CHAR_CODE('rsme')
+kAEDiskEvent = FOUR_CHAR_CODE('disk')
+kAENullEvent = FOUR_CHAR_CODE('null')
+kAEWakeUpEvent = FOUR_CHAR_CODE('wake')
+kAEScrapEvent = FOUR_CHAR_CODE('scrp')
+kAEHighLevel = FOUR_CHAR_CODE('high')
+keyAEAngle = FOUR_CHAR_CODE('kang')
+keyAEArcAngle = FOUR_CHAR_CODE('parc')
+keyAEBaseAddr = FOUR_CHAR_CODE('badd')
+keyAEBestType = FOUR_CHAR_CODE('pbst')
+keyAEBgndColor = FOUR_CHAR_CODE('kbcl')
+keyAEBgndPattern = FOUR_CHAR_CODE('kbpt')
+keyAEBounds = FOUR_CHAR_CODE('pbnd')
+keyAECellList = FOUR_CHAR_CODE('kclt')
+keyAEClassID = FOUR_CHAR_CODE('clID')
+keyAEColor = FOUR_CHAR_CODE('colr')
+keyAEColorTable = FOUR_CHAR_CODE('cltb')
+keyAECurveHeight = FOUR_CHAR_CODE('kchd')
+keyAECurveWidth = FOUR_CHAR_CODE('kcwd')
+keyAEDashStyle = FOUR_CHAR_CODE('pdst')
+keyAEData = FOUR_CHAR_CODE('data')
+keyAEDefaultType = FOUR_CHAR_CODE('deft')
+keyAEDefinitionRect = FOUR_CHAR_CODE('pdrt')
+keyAEDescType = FOUR_CHAR_CODE('dstp')
+keyAEDestination = FOUR_CHAR_CODE('dest')
+keyAEDoAntiAlias = FOUR_CHAR_CODE('anta')
+keyAEDoDithered = FOUR_CHAR_CODE('gdit')
+keyAEDoRotate = FOUR_CHAR_CODE('kdrt')
+keyAEDoScale = FOUR_CHAR_CODE('ksca')
+keyAEDoTranslate = FOUR_CHAR_CODE('ktra')
+keyAEEditionFileLoc = FOUR_CHAR_CODE('eloc')
+keyAEElements = FOUR_CHAR_CODE('elms')
+keyAEEndPoint = FOUR_CHAR_CODE('pend')
+keyAEEventClass = FOUR_CHAR_CODE('evcl')
+keyAEEventID = FOUR_CHAR_CODE('evti')
+keyAEFile = FOUR_CHAR_CODE('kfil')
+keyAEFileType = FOUR_CHAR_CODE('fltp')
+keyAEFillColor = FOUR_CHAR_CODE('flcl')
+keyAEFillPattern = FOUR_CHAR_CODE('flpt')
+keyAEFlipHorizontal = FOUR_CHAR_CODE('kfho')
+keyAEFlipVertical = FOUR_CHAR_CODE('kfvt')
+keyAEFont = FOUR_CHAR_CODE('font')
+keyAEFormula = FOUR_CHAR_CODE('pfor')
+keyAEGraphicObjects = FOUR_CHAR_CODE('gobs')
+keyAEID = FOUR_CHAR_CODE('ID  ')
+keyAEImageQuality = FOUR_CHAR_CODE('gqua')
+keyAEInsertHere = FOUR_CHAR_CODE('insh')
+keyAEKeyForms = FOUR_CHAR_CODE('keyf')
+keyAEKeyword = FOUR_CHAR_CODE('kywd')
+keyAELevel = FOUR_CHAR_CODE('levl')
+keyAELineArrow = FOUR_CHAR_CODE('arro')
+keyAEName = FOUR_CHAR_CODE('pnam')
+keyAENewElementLoc = FOUR_CHAR_CODE('pnel')
+keyAEObject = FOUR_CHAR_CODE('kobj')
+keyAEObjectClass = FOUR_CHAR_CODE('kocl')
+keyAEOffStyles = FOUR_CHAR_CODE('ofst')
+keyAEOnStyles = FOUR_CHAR_CODE('onst')
+keyAEParameters = FOUR_CHAR_CODE('prms')
+keyAEParamFlags = FOUR_CHAR_CODE('pmfg')
+keyAEPenColor = FOUR_CHAR_CODE('ppcl')
+keyAEPenPattern = FOUR_CHAR_CODE('pppa')
+keyAEPenWidth = FOUR_CHAR_CODE('ppwd')
+keyAEPixelDepth = FOUR_CHAR_CODE('pdpt')
+keyAEPixMapMinus = FOUR_CHAR_CODE('kpmm')
+keyAEPMTable = FOUR_CHAR_CODE('kpmt')
+keyAEPointList = FOUR_CHAR_CODE('ptlt')
+keyAEPointSize = FOUR_CHAR_CODE('ptsz')
+keyAEPosition = FOUR_CHAR_CODE('kpos')
+keyAEPropData = FOUR_CHAR_CODE('prdt')
+keyAEProperties = FOUR_CHAR_CODE('qpro')
+keyAEProperty = FOUR_CHAR_CODE('kprp')
+keyAEPropFlags = FOUR_CHAR_CODE('prfg')
+keyAEPropID = FOUR_CHAR_CODE('prop')
+keyAEProtection = FOUR_CHAR_CODE('ppro')
+keyAERenderAs = FOUR_CHAR_CODE('kren')
+keyAERequestedType = FOUR_CHAR_CODE('rtyp')
+keyAEResult = FOUR_CHAR_CODE('----')
+keyAEResultInfo = FOUR_CHAR_CODE('rsin')
+keyAERotation = FOUR_CHAR_CODE('prot')
+keyAERotPoint = FOUR_CHAR_CODE('krtp')
+keyAERowList = FOUR_CHAR_CODE('krls')
+keyAESaveOptions = FOUR_CHAR_CODE('savo')
+keyAEScale = FOUR_CHAR_CODE('pscl')
+keyAEScriptTag = FOUR_CHAR_CODE('psct')
+keyAEShowWhere = FOUR_CHAR_CODE('show')
+keyAEStartAngle = FOUR_CHAR_CODE('pang')
+keyAEStartPoint = FOUR_CHAR_CODE('pstp')
+keyAEStyles = FOUR_CHAR_CODE('ksty')
+keyAESuiteID = FOUR_CHAR_CODE('suit')
+keyAEText = FOUR_CHAR_CODE('ktxt')
+keyAETextColor = FOUR_CHAR_CODE('ptxc')
+keyAETextFont = FOUR_CHAR_CODE('ptxf')
+keyAETextPointSize = FOUR_CHAR_CODE('ptps')
+keyAETextStyles = FOUR_CHAR_CODE('txst')
+keyAETextLineHeight = FOUR_CHAR_CODE('ktlh')
+keyAETextLineAscent = FOUR_CHAR_CODE('ktas')
+keyAETheText = FOUR_CHAR_CODE('thtx')
+keyAETransferMode = FOUR_CHAR_CODE('pptm')
+keyAETranslation = FOUR_CHAR_CODE('ptrs')
+keyAETryAsStructGraf = FOUR_CHAR_CODE('toog')
+keyAEUniformStyles = FOUR_CHAR_CODE('ustl')
+keyAEUpdateOn = FOUR_CHAR_CODE('pupd')
+keyAEUserTerm = FOUR_CHAR_CODE('utrm')
+keyAEWindow = FOUR_CHAR_CODE('wndw')
+keyAEWritingCode = FOUR_CHAR_CODE('wrcd')
+keyMiscellaneous = FOUR_CHAR_CODE('fmsc')
+keySelection = FOUR_CHAR_CODE('fsel')
+keyWindow = FOUR_CHAR_CODE('kwnd')
+keyWhen = FOUR_CHAR_CODE('when')
+keyWhere = FOUR_CHAR_CODE('wher')
+keyModifiers = FOUR_CHAR_CODE('mods')
+keyKey = FOUR_CHAR_CODE('key ')
+keyKeyCode = FOUR_CHAR_CODE('code')
+keyKeyboard = FOUR_CHAR_CODE('keyb')
+keyDriveNumber = FOUR_CHAR_CODE('drv#')
+keyErrorCode = FOUR_CHAR_CODE('err#')
+keyHighLevelClass = FOUR_CHAR_CODE('hcls')
+keyHighLevelID = FOUR_CHAR_CODE('hid ')
+pArcAngle = FOUR_CHAR_CODE('parc')
+pBackgroundColor = FOUR_CHAR_CODE('pbcl')
+pBackgroundPattern = FOUR_CHAR_CODE('pbpt')
+pBestType = FOUR_CHAR_CODE('pbst')
+pBounds = FOUR_CHAR_CODE('pbnd')
+pClass = FOUR_CHAR_CODE('pcls')
+pClipboard = FOUR_CHAR_CODE('pcli')
+pColor = FOUR_CHAR_CODE('colr')
+pColorTable = FOUR_CHAR_CODE('cltb')
+pContents = FOUR_CHAR_CODE('pcnt')
+pCornerCurveHeight = FOUR_CHAR_CODE('pchd')
+pCornerCurveWidth = FOUR_CHAR_CODE('pcwd')
+pDashStyle = FOUR_CHAR_CODE('pdst')
+pDefaultType = FOUR_CHAR_CODE('deft')
+pDefinitionRect = FOUR_CHAR_CODE('pdrt')
+pEnabled = FOUR_CHAR_CODE('enbl')
+pEndPoint = FOUR_CHAR_CODE('pend')
+pFillColor = FOUR_CHAR_CODE('flcl')
+pFillPattern = FOUR_CHAR_CODE('flpt')
+pFont = FOUR_CHAR_CODE('font')
+pFormula = FOUR_CHAR_CODE('pfor')
+pGraphicObjects = FOUR_CHAR_CODE('gobs')
+pHasCloseBox = FOUR_CHAR_CODE('hclb')
+pHasTitleBar = FOUR_CHAR_CODE('ptit')
+pID = FOUR_CHAR_CODE('ID  ')
+pIndex = FOUR_CHAR_CODE('pidx')
+pInsertionLoc = FOUR_CHAR_CODE('pins')
+pIsFloating = FOUR_CHAR_CODE('isfl')
+pIsFrontProcess = FOUR_CHAR_CODE('pisf')
+pIsModal = FOUR_CHAR_CODE('pmod')
+pIsModified = FOUR_CHAR_CODE('imod')
+pIsResizable = FOUR_CHAR_CODE('prsz')
+pIsStationeryPad = FOUR_CHAR_CODE('pspd')
+pIsZoomable = FOUR_CHAR_CODE('iszm')
+pIsZoomed = FOUR_CHAR_CODE('pzum')
+pItemNumber = FOUR_CHAR_CODE('itmn')
+pJustification = FOUR_CHAR_CODE('pjst')
+pLineArrow = FOUR_CHAR_CODE('arro')
+pMenuID = FOUR_CHAR_CODE('mnid')
+pName = FOUR_CHAR_CODE('pnam')
+pNewElementLoc = FOUR_CHAR_CODE('pnel')
+pPenColor = FOUR_CHAR_CODE('ppcl')
+pPenPattern = FOUR_CHAR_CODE('pppa')
+pPenWidth = FOUR_CHAR_CODE('ppwd')
+pPixelDepth = FOUR_CHAR_CODE('pdpt')
+pPointList = FOUR_CHAR_CODE('ptlt')
+pPointSize = FOUR_CHAR_CODE('ptsz')
+pProtection = FOUR_CHAR_CODE('ppro')
+pRotation = FOUR_CHAR_CODE('prot')
+pScale = FOUR_CHAR_CODE('pscl')
+pScript = FOUR_CHAR_CODE('scpt')
+pScriptTag = FOUR_CHAR_CODE('psct')
+pSelected = FOUR_CHAR_CODE('selc')
+pSelection = FOUR_CHAR_CODE('sele')
+pStartAngle = FOUR_CHAR_CODE('pang')
+pStartPoint = FOUR_CHAR_CODE('pstp')
+pTextColor = FOUR_CHAR_CODE('ptxc')
+pTextFont = FOUR_CHAR_CODE('ptxf')
+pTextItemDelimiters = FOUR_CHAR_CODE('txdl')
+pTextPointSize = FOUR_CHAR_CODE('ptps')
+pTextStyles = FOUR_CHAR_CODE('txst')
+pTransferMode = FOUR_CHAR_CODE('pptm')
+pTranslation = FOUR_CHAR_CODE('ptrs')
+pUniformStyles = FOUR_CHAR_CODE('ustl')
+pUpdateOn = FOUR_CHAR_CODE('pupd')
+pUserSelection = FOUR_CHAR_CODE('pusl')
+pVersion = FOUR_CHAR_CODE('vers')
+pVisible = FOUR_CHAR_CODE('pvis')
+typeAEText = FOUR_CHAR_CODE('tTXT')
+typeArc = FOUR_CHAR_CODE('carc')
+typeBest = FOUR_CHAR_CODE('best')
+typeCell = FOUR_CHAR_CODE('ccel')
+typeClassInfo = FOUR_CHAR_CODE('gcli')
+typeColorTable = FOUR_CHAR_CODE('clrt')
+typeColumn = FOUR_CHAR_CODE('ccol')
+typeDashStyle = FOUR_CHAR_CODE('tdas')
+typeData = FOUR_CHAR_CODE('tdta')
+typeDrawingArea = FOUR_CHAR_CODE('cdrw')
+typeElemInfo = FOUR_CHAR_CODE('elin')
+typeEnumeration = FOUR_CHAR_CODE('enum')
+typeEPS = FOUR_CHAR_CODE('EPS ')
+typeEventInfo = FOUR_CHAR_CODE('evin')
+typeFinderWindow = FOUR_CHAR_CODE('fwin')
+typeFixedPoint = FOUR_CHAR_CODE('fpnt')
+typeFixedRectangle = FOUR_CHAR_CODE('frct')
+typeGraphicLine = FOUR_CHAR_CODE('glin')
+typeGraphicText = FOUR_CHAR_CODE('cgtx')
+typeGroupedGraphic = FOUR_CHAR_CODE('cpic')
+typeInsertionLoc = FOUR_CHAR_CODE('insl')
+typeIntlText = FOUR_CHAR_CODE('itxt')
+typeIntlWritingCode = FOUR_CHAR_CODE('intl')
+typeLongDateTime = FOUR_CHAR_CODE('ldt ')
+typeLongFixed = FOUR_CHAR_CODE('lfxd')
+typeLongFixedPoint = FOUR_CHAR_CODE('lfpt')
+typeLongFixedRectangle = FOUR_CHAR_CODE('lfrc')
+typeLongPoint = FOUR_CHAR_CODE('lpnt')
+typeLongRectangle = FOUR_CHAR_CODE('lrct')
+typeMachineLoc = FOUR_CHAR_CODE('mLoc')
+typeOval = FOUR_CHAR_CODE('covl')
+typeParamInfo = FOUR_CHAR_CODE('pmin')
+typePict = FOUR_CHAR_CODE('PICT')
+typePixelMap = FOUR_CHAR_CODE('cpix')
+typePixMapMinus = FOUR_CHAR_CODE('tpmm')
+typePolygon = FOUR_CHAR_CODE('cpgn')
+typePropInfo = FOUR_CHAR_CODE('pinf')
+typePtr = FOUR_CHAR_CODE('ptr ')
+typeQDPoint = FOUR_CHAR_CODE('QDpt')
+typeQDRegion = FOUR_CHAR_CODE('Qrgn')
+typeRectangle = FOUR_CHAR_CODE('crec')
+typeRGB16 = FOUR_CHAR_CODE('tr16')
+typeRGB96 = FOUR_CHAR_CODE('tr96')
+typeRGBColor = FOUR_CHAR_CODE('cRGB')
+typeRotation = FOUR_CHAR_CODE('trot')
+typeRoundedRectangle = FOUR_CHAR_CODE('crrc')
+typeRow = FOUR_CHAR_CODE('crow')
+typeScrapStyles = FOUR_CHAR_CODE('styl')
+typeScript = FOUR_CHAR_CODE('scpt')
+typeStyledText = FOUR_CHAR_CODE('STXT')
+typeSuiteInfo = FOUR_CHAR_CODE('suin')
+typeTable = FOUR_CHAR_CODE('ctbl')
+typeTextStyles = FOUR_CHAR_CODE('tsty')
+typeTIFF = FOUR_CHAR_CODE('TIFF')
+typeVersion = FOUR_CHAR_CODE('vers')
+kAEMenuClass = FOUR_CHAR_CODE('menu')
+kAEMenuSelect = FOUR_CHAR_CODE('mhit')
+kAEMouseDown = FOUR_CHAR_CODE('mdwn')
+kAEMouseDownInBack = FOUR_CHAR_CODE('mdbk')
+kAEKeyDown = FOUR_CHAR_CODE('kdwn')
+kAEResized = FOUR_CHAR_CODE('rsiz')
+kAEPromise = FOUR_CHAR_CODE('prom')
+keyMenuID = FOUR_CHAR_CODE('mid ')
+keyMenuItem = FOUR_CHAR_CODE('mitm')
+keyCloseAllWindows = FOUR_CHAR_CODE('caw ')
+keyOriginalBounds = FOUR_CHAR_CODE('obnd')
+keyNewBounds = FOUR_CHAR_CODE('nbnd')
+keyLocalWhere = FOUR_CHAR_CODE('lwhr')
+typeHIMenu = FOUR_CHAR_CODE('mobj')
+typeHIWindow = FOUR_CHAR_CODE('wobj')
+kBySmallIcon = 0
+kByIconView = 1
+kByNameView = 2
+kByDateView = 3
+kBySizeView = 4
+kByKindView = 5
+kByCommentView = 6
+kByLabelView = 7
+kByVersionView = 8
+kAEInfo = 11
+kAEMain = 0
+kAESharing = 13
+kAEZoomIn = 7
+kAEZoomOut = 8
+kTextServiceClass = FOUR_CHAR_CODE('tsvc')
+kUpdateActiveInputArea = FOUR_CHAR_CODE('updt')
+kShowHideInputWindow = FOUR_CHAR_CODE('shiw')
+kPos2Offset = FOUR_CHAR_CODE('p2st')
+kOffset2Pos = FOUR_CHAR_CODE('st2p')
+kUnicodeNotFromInputMethod = FOUR_CHAR_CODE('unim')
+kGetSelectedText = FOUR_CHAR_CODE('gtxt')
+keyAETSMDocumentRefcon = FOUR_CHAR_CODE('refc')
+keyAEServerInstance = FOUR_CHAR_CODE('srvi')
+keyAETheData = FOUR_CHAR_CODE('kdat')
+keyAEFixLength = FOUR_CHAR_CODE('fixl')
+keyAEUpdateRange = FOUR_CHAR_CODE('udng')
+keyAECurrentPoint = FOUR_CHAR_CODE('cpos')
+keyAEBufferSize = FOUR_CHAR_CODE('buff')
+keyAEMoveView = FOUR_CHAR_CODE('mvvw')
+keyAENextBody = FOUR_CHAR_CODE('nxbd')
+keyAETSMScriptTag = FOUR_CHAR_CODE('sclg')
+keyAETSMTextFont = FOUR_CHAR_CODE('ktxf')
+keyAETSMTextFMFont = FOUR_CHAR_CODE('ktxm')
+keyAETSMTextPointSize = FOUR_CHAR_CODE('ktps')
+keyAETSMEventRecord = FOUR_CHAR_CODE('tevt')
+keyAETSMEventRef = FOUR_CHAR_CODE('tevr')
+keyAETextServiceEncoding = FOUR_CHAR_CODE('tsen')
+keyAETextServiceMacEncoding = FOUR_CHAR_CODE('tmen')
+typeTextRange = FOUR_CHAR_CODE('txrn')
+typeComponentInstance = FOUR_CHAR_CODE('cmpi')
+typeOffsetArray = FOUR_CHAR_CODE('ofay')
+typeTextRangeArray = FOUR_CHAR_CODE('tray')
+typeLowLevelEventRecord = FOUR_CHAR_CODE('evtr')
+typeEventRef = FOUR_CHAR_CODE('evrf')
+typeText = typeChar
+kTSMOutsideOfBody = 1
+kTSMInsideOfBody = 2
+kTSMInsideOfActiveInputArea = 3
+kNextBody = 1
+kPreviousBody = 2
+kCaretPosition = 1
+kRawText = 2
+kSelectedRawText = 3
+kConvertedText = 4
+kSelectedConvertedText = 5
+kBlockFillText = 6
+kOutlineText = 7
+kSelectedText = 8
+keyAEHiliteRange = FOUR_CHAR_CODE('hrng')
+keyAEPinRange = FOUR_CHAR_CODE('pnrg')
+keyAEClauseOffsets = FOUR_CHAR_CODE('clau')
+keyAEOffset = FOUR_CHAR_CODE('ofst')
+keyAEPoint = FOUR_CHAR_CODE('gpos')
+keyAELeftSide = FOUR_CHAR_CODE('klef')
+keyAERegionClass = FOUR_CHAR_CODE('rgnc')
+keyAEDragging = FOUR_CHAR_CODE('bool')
+keyAELeadingEdge = keyAELeftSide
+typeUnicodeText = FOUR_CHAR_CODE('utxt')
+typeStyledUnicodeText = FOUR_CHAR_CODE('sutx')
+typeEncodedString = FOUR_CHAR_CODE('encs')
+typeCString = FOUR_CHAR_CODE('cstr')
+typePString = FOUR_CHAR_CODE('pstr')
+typeMeters = FOUR_CHAR_CODE('metr')
+typeInches = FOUR_CHAR_CODE('inch')
+typeFeet = FOUR_CHAR_CODE('feet')
+typeYards = FOUR_CHAR_CODE('yard')
+typeMiles = FOUR_CHAR_CODE('mile')
+typeKilometers = FOUR_CHAR_CODE('kmtr')
+typeCentimeters = FOUR_CHAR_CODE('cmtr')
+typeSquareMeters = FOUR_CHAR_CODE('sqrm')
+typeSquareFeet = FOUR_CHAR_CODE('sqft')
+typeSquareYards = FOUR_CHAR_CODE('sqyd')
+typeSquareMiles = FOUR_CHAR_CODE('sqmi')
+typeSquareKilometers = FOUR_CHAR_CODE('sqkm')
+typeLiters = FOUR_CHAR_CODE('litr')
+typeQuarts = FOUR_CHAR_CODE('qrts')
+typeGallons = FOUR_CHAR_CODE('galn')
+typeCubicMeters = FOUR_CHAR_CODE('cmet')
+typeCubicFeet = FOUR_CHAR_CODE('cfet')
+typeCubicInches = FOUR_CHAR_CODE('cuin')
+typeCubicCentimeter = FOUR_CHAR_CODE('ccmt')
+typeCubicYards = FOUR_CHAR_CODE('cyrd')
+typeKilograms = FOUR_CHAR_CODE('kgrm')
+typeGrams = FOUR_CHAR_CODE('gram')
+typeOunces = FOUR_CHAR_CODE('ozs ')
+typePounds = FOUR_CHAR_CODE('lbs ')
+typeDegreesC = FOUR_CHAR_CODE('degc')
+typeDegreesF = FOUR_CHAR_CODE('degf')
+typeDegreesK = FOUR_CHAR_CODE('degk')
+kFAServerApp = FOUR_CHAR_CODE('ssrv')
+kDoFolderActionEvent = FOUR_CHAR_CODE('fola')
+kFolderActionCode = FOUR_CHAR_CODE('actn')
+kFolderOpenedEvent = FOUR_CHAR_CODE('fopn')
+kFolderClosedEvent = FOUR_CHAR_CODE('fclo')
+kFolderWindowMovedEvent = FOUR_CHAR_CODE('fsiz')
+kFolderItemsAddedEvent = FOUR_CHAR_CODE('fget')
+kFolderItemsRemovedEvent = FOUR_CHAR_CODE('flos')
+kItemList = FOUR_CHAR_CODE('flst')
+kNewSizeParameter = FOUR_CHAR_CODE('fnsz')
+kFASuiteCode = FOUR_CHAR_CODE('faco')
+kFAAttachCommand = FOUR_CHAR_CODE('atfa')
+kFARemoveCommand = FOUR_CHAR_CODE('rmfa')
+kFAEditCommand = FOUR_CHAR_CODE('edfa')
+kFAFileParam = FOUR_CHAR_CODE('faal')
+kFAIndexParam = FOUR_CHAR_CODE('indx')
+kAEInternetSuite = FOUR_CHAR_CODE('gurl')
+kAEISWebStarSuite = FOUR_CHAR_CODE('WWW\xbd')
+kAEISGetURL = FOUR_CHAR_CODE('gurl')
+KAEISHandleCGI = FOUR_CHAR_CODE('sdoc')
+cURL = FOUR_CHAR_CODE('url ')
+cInternetAddress = FOUR_CHAR_CODE('IPAD')
+cHTML = FOUR_CHAR_CODE('html')
+cFTPItem = FOUR_CHAR_CODE('ftp ')
+kAEISHTTPSearchArgs = FOUR_CHAR_CODE('kfor')
+kAEISPostArgs = FOUR_CHAR_CODE('post')
+kAEISMethod = FOUR_CHAR_CODE('meth')
+kAEISClientAddress = FOUR_CHAR_CODE('addr')
+kAEISUserName = FOUR_CHAR_CODE('user')
+kAEISPassword = FOUR_CHAR_CODE('pass')
+kAEISFromUser = FOUR_CHAR_CODE('frmu')
+kAEISServerName = FOUR_CHAR_CODE('svnm')
+kAEISServerPort = FOUR_CHAR_CODE('svpt')
+kAEISScriptName = FOUR_CHAR_CODE('scnm')
+kAEISContentType = FOUR_CHAR_CODE('ctyp')
+kAEISReferrer = FOUR_CHAR_CODE('refr')
+kAEISUserAgent = FOUR_CHAR_CODE('Agnt')
+kAEISAction = FOUR_CHAR_CODE('Kact')
+kAEISActionPath = FOUR_CHAR_CODE('Kapt')
+kAEISClientIP = FOUR_CHAR_CODE('Kcip')
+kAEISFullRequest = FOUR_CHAR_CODE('Kfrq')
+pScheme = FOUR_CHAR_CODE('pusc')
+pHost = FOUR_CHAR_CODE('HOST')
+pPath = FOUR_CHAR_CODE('FTPc')
+pUserName = FOUR_CHAR_CODE('RAun')
+pUserPassword = FOUR_CHAR_CODE('RApw')
+pDNSForm = FOUR_CHAR_CODE('pDNS')
+pURL = FOUR_CHAR_CODE('pURL')
+pTextEncoding = FOUR_CHAR_CODE('ptxe')
+pFTPKind = FOUR_CHAR_CODE('kind')
+eScheme = FOUR_CHAR_CODE('esch')
+eurlHTTP = FOUR_CHAR_CODE('http')
+eurlHTTPS = FOUR_CHAR_CODE('htps')
+eurlFTP = FOUR_CHAR_CODE('ftp ')
+eurlMail = FOUR_CHAR_CODE('mail')
+eurlFile = FOUR_CHAR_CODE('file')
+eurlGopher = FOUR_CHAR_CODE('gphr')
+eurlTelnet = FOUR_CHAR_CODE('tlnt')
+eurlNews = FOUR_CHAR_CODE('news')
+eurlSNews = FOUR_CHAR_CODE('snws')
+eurlNNTP = FOUR_CHAR_CODE('nntp')
+eurlMessage = FOUR_CHAR_CODE('mess')
+eurlMailbox = FOUR_CHAR_CODE('mbox')
+eurlMulti = FOUR_CHAR_CODE('mult')
+eurlLaunch = FOUR_CHAR_CODE('laun')
+eurlAFP = FOUR_CHAR_CODE('afp ')
+eurlAT = FOUR_CHAR_CODE('at  ')
+eurlEPPC = FOUR_CHAR_CODE('eppc')
+eurlRTSP = FOUR_CHAR_CODE('rtsp')
+eurlIMAP = FOUR_CHAR_CODE('imap')
+eurlNFS = FOUR_CHAR_CODE('unfs')
+eurlPOP = FOUR_CHAR_CODE('upop')
+eurlLDAP = FOUR_CHAR_CODE('uldp')
+eurlUnknown = FOUR_CHAR_CODE('url?')
+kConnSuite = FOUR_CHAR_CODE('macc')
+cDevSpec = FOUR_CHAR_CODE('cdev')
+cAddressSpec = FOUR_CHAR_CODE('cadr')
+cADBAddress = FOUR_CHAR_CODE('cadb')
+cAppleTalkAddress = FOUR_CHAR_CODE('cat ')
+cBusAddress = FOUR_CHAR_CODE('cbus')
+cEthernetAddress = FOUR_CHAR_CODE('cen ')
+cFireWireAddress = FOUR_CHAR_CODE('cfw ')
+cIPAddress = FOUR_CHAR_CODE('cip ')
+cLocalTalkAddress = FOUR_CHAR_CODE('clt ')
+cSCSIAddress = FOUR_CHAR_CODE('cscs')
+cTokenRingAddress = FOUR_CHAR_CODE('ctok')
+cUSBAddress = FOUR_CHAR_CODE('cusb')
+pDeviceType = FOUR_CHAR_CODE('pdvt')
+pDeviceAddress = FOUR_CHAR_CODE('pdva')
+pConduit = FOUR_CHAR_CODE('pcon')
+pProtocol = FOUR_CHAR_CODE('pprt')
+pATMachine = FOUR_CHAR_CODE('patm')
+pATZone = FOUR_CHAR_CODE('patz')
+pATType = FOUR_CHAR_CODE('patt')
+pDottedDecimal = FOUR_CHAR_CODE('pipd')
+pDNS = FOUR_CHAR_CODE('pdns')
+pPort = FOUR_CHAR_CODE('ppor')
+pNetwork = FOUR_CHAR_CODE('pnet')
+pNode = FOUR_CHAR_CODE('pnod')
+pSocket = FOUR_CHAR_CODE('psoc')
+pSCSIBus = FOUR_CHAR_CODE('pscb')
+pSCSILUN = FOUR_CHAR_CODE('pslu')
+eDeviceType = FOUR_CHAR_CODE('edvt')
+eAddressSpec = FOUR_CHAR_CODE('eads')
+eConduit = FOUR_CHAR_CODE('econ')
+eProtocol = FOUR_CHAR_CODE('epro')
+eADB = FOUR_CHAR_CODE('eadb')
+eAnalogAudio = FOUR_CHAR_CODE('epau')
+eAppleTalk = FOUR_CHAR_CODE('epat')
+eAudioLineIn = FOUR_CHAR_CODE('ecai')
+eAudioLineOut = FOUR_CHAR_CODE('ecal')
+eAudioOut = FOUR_CHAR_CODE('ecao')
+eBus = FOUR_CHAR_CODE('ebus')
+eCDROM = FOUR_CHAR_CODE('ecd ')
+eCommSlot = FOUR_CHAR_CODE('eccm')
+eDigitalAudio = FOUR_CHAR_CODE('epda')
+eDisplay = FOUR_CHAR_CODE('edds')
+eDVD = FOUR_CHAR_CODE('edvd')
+eEthernet = FOUR_CHAR_CODE('ecen')
+eFireWire = FOUR_CHAR_CODE('ecfw')
+eFloppy = FOUR_CHAR_CODE('efd ')
+eHD = FOUR_CHAR_CODE('ehd ')
+eInfrared = FOUR_CHAR_CODE('ecir')
+eIP = FOUR_CHAR_CODE('epip')
+eIrDA = FOUR_CHAR_CODE('epir')
+eIRTalk = FOUR_CHAR_CODE('epit')
+eKeyboard = FOUR_CHAR_CODE('ekbd')
+eLCD = FOUR_CHAR_CODE('edlc')
+eLocalTalk = FOUR_CHAR_CODE('eclt')
+eMacIP = FOUR_CHAR_CODE('epmi')
+eMacVideo = FOUR_CHAR_CODE('epmv')
+eMicrophone = FOUR_CHAR_CODE('ecmi')
+eModemPort = FOUR_CHAR_CODE('ecmp')
+eModemPrinterPort = FOUR_CHAR_CODE('empp')
+eModem = FOUR_CHAR_CODE('edmm')
+eMonitorOut = FOUR_CHAR_CODE('ecmn')
+eMouse = FOUR_CHAR_CODE('emou')
+eNuBusCard = FOUR_CHAR_CODE('ednb')
+eNuBus = FOUR_CHAR_CODE('enub')
+ePCcard = FOUR_CHAR_CODE('ecpc')
+ePCIbus = FOUR_CHAR_CODE('ecpi')
+ePCIcard = FOUR_CHAR_CODE('edpi')
+ePDSslot = FOUR_CHAR_CODE('ecpd')
+ePDScard = FOUR_CHAR_CODE('epds')
+ePointingDevice = FOUR_CHAR_CODE('edpd')
+ePostScript = FOUR_CHAR_CODE('epps')
+ePPP = FOUR_CHAR_CODE('eppp')
+ePrinterPort = FOUR_CHAR_CODE('ecpp')
+ePrinter = FOUR_CHAR_CODE('edpr')
+eSvideo = FOUR_CHAR_CODE('epsv')
+eSCSI = FOUR_CHAR_CODE('ecsc')
+eSerial = FOUR_CHAR_CODE('epsr')
+eSpeakers = FOUR_CHAR_CODE('edsp')
+eStorageDevice = FOUR_CHAR_CODE('edst')
+eSVGA = FOUR_CHAR_CODE('epsg')
+eTokenRing = FOUR_CHAR_CODE('etok')
+eTrackball = FOUR_CHAR_CODE('etrk')
+eTrackpad = FOUR_CHAR_CODE('edtp')
+eUSB = FOUR_CHAR_CODE('ecus')
+eVideoIn = FOUR_CHAR_CODE('ecvi')
+eVideoMonitor = FOUR_CHAR_CODE('edvm')
+eVideoOut = FOUR_CHAR_CODE('ecvo')
+cKeystroke = FOUR_CHAR_CODE('kprs')
+pKeystrokeKey = FOUR_CHAR_CODE('kMsg')
+pModifiers = FOUR_CHAR_CODE('kMod')
+pKeyKind = FOUR_CHAR_CODE('kknd')
+eModifiers = FOUR_CHAR_CODE('eMds')
+eOptionDown = FOUR_CHAR_CODE('Kopt')
+eCommandDown = FOUR_CHAR_CODE('Kcmd')
+eControlDown = FOUR_CHAR_CODE('Kctl')
+eShiftDown = FOUR_CHAR_CODE('Ksft')
+eCapsLockDown = FOUR_CHAR_CODE('Kclk')
+eKeyKind = FOUR_CHAR_CODE('ekst')
+eEscapeKey = 0x6B733500
+eDeleteKey = 0x6B733300
+eTabKey = 0x6B733000
+eReturnKey = 0x6B732400
+eClearKey = 0x6B734700
+eEnterKey = 0x6B734C00
+eUpArrowKey = 0x6B737E00
+eDownArrowKey = 0x6B737D00
+eLeftArrowKey = 0x6B737B00
+eRightArrowKey = 0x6B737C00
+eHelpKey = 0x6B737200
+eHomeKey = 0x6B737300
+ePageUpKey = 0x6B737400
+ePageDownKey = 0x6B737900
+eForwardDelKey = 0x6B737500
+eEndKey = 0x6B737700
+eF1Key = 0x6B737A00
+eF2Key = 0x6B737800
+eF3Key = 0x6B736300
+eF4Key = 0x6B737600
+eF5Key = 0x6B736000
+eF6Key = 0x6B736100
+eF7Key = 0x6B736200
+eF8Key = 0x6B736400
+eF9Key = 0x6B736500
+eF10Key = 0x6B736D00
+eF11Key = 0x6B736700
+eF12Key = 0x6B736F00
+eF13Key = 0x6B736900
+eF14Key = 0x6B736B00
+eF15Key = 0x6B737100
+kAEAND = FOUR_CHAR_CODE('AND ')
+kAEOR = FOUR_CHAR_CODE('OR  ')
+kAENOT = FOUR_CHAR_CODE('NOT ')
+kAEFirst = FOUR_CHAR_CODE('firs')
+kAELast = FOUR_CHAR_CODE('last')
+kAEMiddle = FOUR_CHAR_CODE('midd')
+kAEAny = FOUR_CHAR_CODE('any ')
+kAEAll = FOUR_CHAR_CODE('all ')
+kAENext = FOUR_CHAR_CODE('next')
+kAEPrevious = FOUR_CHAR_CODE('prev')
+keyAECompOperator = FOUR_CHAR_CODE('relo')
+keyAELogicalTerms = FOUR_CHAR_CODE('term')
+keyAELogicalOperator = FOUR_CHAR_CODE('logc')
+keyAEObject1 = FOUR_CHAR_CODE('obj1')
+keyAEObject2 = FOUR_CHAR_CODE('obj2')
+keyAEDesiredClass = FOUR_CHAR_CODE('want')
+keyAEContainer = FOUR_CHAR_CODE('from')
+keyAEKeyForm = FOUR_CHAR_CODE('form')
+keyAEKeyData = FOUR_CHAR_CODE('seld')
+keyAERangeStart = FOUR_CHAR_CODE('star')
+keyAERangeStop = FOUR_CHAR_CODE('stop')
+keyDisposeTokenProc = FOUR_CHAR_CODE('xtok')
+keyAECompareProc = FOUR_CHAR_CODE('cmpr')
+keyAECountProc = FOUR_CHAR_CODE('cont')
+keyAEMarkTokenProc = FOUR_CHAR_CODE('mkid')
+keyAEMarkProc = FOUR_CHAR_CODE('mark')
+keyAEAdjustMarksProc = FOUR_CHAR_CODE('adjm')
+keyAEGetErrDescProc = FOUR_CHAR_CODE('indc')
+formAbsolutePosition = FOUR_CHAR_CODE('indx')
+formRelativePosition = FOUR_CHAR_CODE('rele')
+formTest = FOUR_CHAR_CODE('test')
+formRange = FOUR_CHAR_CODE('rang')
+formPropertyID = FOUR_CHAR_CODE('prop')
+formName = FOUR_CHAR_CODE('name')
+typeObjectSpecifier = FOUR_CHAR_CODE('obj ')
+typeObjectBeingExamined = FOUR_CHAR_CODE('exmn')
+typeCurrentContainer = FOUR_CHAR_CODE('ccnt')
+typeToken = FOUR_CHAR_CODE('toke')
+typeRelativeDescriptor = FOUR_CHAR_CODE('rel ')
+typeAbsoluteOrdinal = FOUR_CHAR_CODE('abso')
+typeIndexDescriptor = FOUR_CHAR_CODE('inde')
+typeRangeDescriptor = FOUR_CHAR_CODE('rang')
+typeLogicalDescriptor = FOUR_CHAR_CODE('logi')
+typeCompDescriptor = FOUR_CHAR_CODE('cmpd')
+typeOSLTokenList = FOUR_CHAR_CODE('ostl')
+kAEIDoMinimum = 0x0000
+kAEIDoWhose = 0x0001
+kAEIDoMarking = 0x0004
+kAEPassSubDescs = 0x0008
+kAEResolveNestedLists = 0x0010
+kAEHandleSimpleRanges = 0x0020
+kAEUseRelativeIterators = 0x0040
+typeWhoseDescriptor = FOUR_CHAR_CODE('whos')
+formWhose = FOUR_CHAR_CODE('whos')
+typeWhoseRange = FOUR_CHAR_CODE('wrng')
+keyAEWhoseRangeStart = FOUR_CHAR_CODE('wstr')
+keyAEWhoseRangeStop = FOUR_CHAR_CODE('wstp')
+keyAEIndex = FOUR_CHAR_CODE('kidx')
+keyAETest = FOUR_CHAR_CODE('ktst')

Added: vendor/Python/current/Lib/plat-mac/Carbon/AppleHelp.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/AppleHelp.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/AppleHelp.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,6 @@
+# Generated from 'AppleHelp.h'
+
+kAHInternalErr = -10790
+kAHInternetConfigPrefErr = -10791
+kAHTOCTypeUser = 0
+kAHTOCTypeDeveloper = 1

Added: vendor/Python/current/Lib/plat-mac/Carbon/CF.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/CF.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/CF.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1 @@
+from _CF import *

Added: vendor/Python/current/Lib/plat-mac/Carbon/CG.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/CG.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/CG.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1 @@
+from _CG import *


Property changes on: vendor/Python/current/Lib/plat-mac/Carbon/CG.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/plat-mac/Carbon/CarbonEvents.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/CarbonEvents.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/CarbonEvents.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,451 @@
+# Generated from 'CarbonEvents.h'
+
+def FOUR_CHAR_CODE(x): return x
+def FOUR_CHAR_CODE(x): return x
+false = 0
+true = 1
+keyAEEventClass = FOUR_CHAR_CODE('evcl')
+keyAEEventID = FOUR_CHAR_CODE('evti')
+eventAlreadyPostedErr = -9860
+eventTargetBusyErr = -9861
+eventClassInvalidErr = -9862
+eventClassIncorrectErr = -9864
+eventHandlerAlreadyInstalledErr = -9866
+eventInternalErr = -9868
+eventKindIncorrectErr = -9869
+eventParameterNotFoundErr = -9870
+eventNotHandledErr = -9874
+eventLoopTimedOutErr = -9875
+eventLoopQuitErr = -9876
+eventNotInQueueErr = -9877
+eventHotKeyExistsErr = -9878
+eventHotKeyInvalidErr = -9879
+kEventPriorityLow = 0
+kEventPriorityStandard = 1
+kEventPriorityHigh = 2
+kEventLeaveInQueue = false
+kEventRemoveFromQueue = true
+kTrackMouseLocationOptionDontConsumeMouseUp = (1 << 0)
+kMouseTrackingMouseDown = 1
+kMouseTrackingMouseUp = 2
+kMouseTrackingMouseExited = 3
+kMouseTrackingMouseEntered = 4
+kMouseTrackingMouseDragged = 5
+kMouseTrackingKeyModifiersChanged = 6
+kMouseTrackingUserCancelled = 7
+kMouseTrackingTimedOut = 8
+kMouseTrackingMouseMoved = 9
+kEventAttributeNone = 0
+kEventAttributeUserEvent = (1 << 0)
+kEventClassMouse = FOUR_CHAR_CODE('mous')
+kEventClassKeyboard = FOUR_CHAR_CODE('keyb')
+kEventClassTextInput = FOUR_CHAR_CODE('text')
+kEventClassApplication = FOUR_CHAR_CODE('appl')
+kEventClassAppleEvent = FOUR_CHAR_CODE('eppc')
+kEventClassMenu = FOUR_CHAR_CODE('menu')
+kEventClassWindow = FOUR_CHAR_CODE('wind')
+kEventClassControl = FOUR_CHAR_CODE('cntl')
+kEventClassCommand = FOUR_CHAR_CODE('cmds')
+kEventClassTablet = FOUR_CHAR_CODE('tblt')
+kEventClassVolume = FOUR_CHAR_CODE('vol ')
+kEventClassAppearance = FOUR_CHAR_CODE('appm')
+kEventClassService = FOUR_CHAR_CODE('serv')
+kEventMouseDown = 1
+kEventMouseUp = 2
+kEventMouseMoved = 5
+kEventMouseDragged = 6
+kEventMouseWheelMoved = 10
+kEventMouseButtonPrimary = 1
+kEventMouseButtonSecondary = 2
+kEventMouseButtonTertiary = 3
+kEventMouseWheelAxisX = 0
+kEventMouseWheelAxisY = 1
+kEventTextInputUpdateActiveInputArea = 1
+kEventTextInputUnicodeForKeyEvent = 2
+kEventTextInputOffsetToPos = 3
+kEventTextInputPosToOffset = 4
+kEventTextInputShowHideBottomWindow = 5
+kEventTextInputGetSelectedText = 6
+kEventRawKeyDown = 1
+kEventRawKeyRepeat = 2
+kEventRawKeyUp = 3
+kEventRawKeyModifiersChanged = 4
+kEventHotKeyPressed = 5
+kEventHotKeyReleased = 6
+kEventKeyModifierNumLockBit = 16
+kEventKeyModifierFnBit = 17
+kEventKeyModifierNumLockMask = 1L << kEventKeyModifierNumLockBit
+kEventKeyModifierFnMask = 1L << kEventKeyModifierFnBit
+kEventAppActivated = 1
+kEventAppDeactivated = 2
+kEventAppQuit = 3
+kEventAppLaunchNotification = 4
+kEventAppLaunched = 5
+kEventAppTerminated = 6
+kEventAppFrontSwitched = 7
+kEventAppGetDockTileMenu = 20
+kEventAppleEvent = 1
+kEventWindowUpdate = 1
+kEventWindowDrawContent = 2
+kEventWindowActivated = 5
+kEventWindowDeactivated = 6
+kEventWindowGetClickActivation = 7
+kEventWindowShowing = 22
+kEventWindowHiding = 23
+kEventWindowShown = 24
+kEventWindowHidden = 25
+kEventWindowCollapsing = 86
+kEventWindowCollapsed = 67
+kEventWindowExpanding = 87
+kEventWindowExpanded = 70
+kEventWindowZoomed = 76
+kEventWindowBoundsChanging = 26
+kEventWindowBoundsChanged = 27
+kEventWindowResizeStarted = 28
+kEventWindowResizeCompleted = 29
+kEventWindowDragStarted = 30
+kEventWindowDragCompleted = 31
+kEventWindowClosed = 73
+kWindowBoundsChangeUserDrag = (1 << 0)
+kWindowBoundsChangeUserResize = (1 << 1)
+kWindowBoundsChangeSizeChanged = (1 << 2)
+kWindowBoundsChangeOriginChanged = (1 << 3)
+kWindowBoundsChangeZoom = (1 << 4)
+kEventWindowClickDragRgn = 32
+kEventWindowClickResizeRgn = 33
+kEventWindowClickCollapseRgn = 34
+kEventWindowClickCloseRgn = 35
+kEventWindowClickZoomRgn = 36
+kEventWindowClickContentRgn = 37
+kEventWindowClickProxyIconRgn = 38
+kEventWindowClickToolbarButtonRgn = 41
+kEventWindowClickStructureRgn = 42
+kEventWindowCursorChange = 40
+kEventWindowCollapse = 66
+kEventWindowCollapseAll = 68
+kEventWindowExpand = 69
+kEventWindowExpandAll = 71
+kEventWindowClose = 72
+kEventWindowCloseAll = 74
+kEventWindowZoom = 75
+kEventWindowZoomAll = 77
+kEventWindowContextualMenuSelect = 78
+kEventWindowPathSelect = 79
+kEventWindowGetIdealSize = 80
+kEventWindowGetMinimumSize = 81
+kEventWindowGetMaximumSize = 82
+kEventWindowConstrain = 83
+kEventWindowHandleContentClick = 85
+kEventWindowProxyBeginDrag = 128
+kEventWindowProxyEndDrag = 129
+kEventWindowToolbarSwitchMode = 150
+kDockChangedUser = 1
+kDockChangedOrientation = 2
+kDockChangedAutohide = 3
+kDockChangedDisplay = 4
+kDockChangedItems = 5
+kDockChangedUnknown = 6
+kEventWindowFocusAcquired = 200
+kEventWindowFocusRelinquish = 201
+kEventWindowDrawFrame = 1000
+kEventWindowDrawPart = 1001
+kEventWindowGetRegion = 1002
+kEventWindowHitTest = 1003
+kEventWindowInit = 1004
+kEventWindowDispose = 1005
+kEventWindowDragHilite = 1006
+kEventWindowModified = 1007
+kEventWindowSetupProxyDragImage = 1008
+kEventWindowStateChanged = 1009
+kEventWindowMeasureTitle = 1010
+kEventWindowDrawGrowBox = 1011
+kEventWindowGetGrowImageRegion = 1012
+kEventWindowPaint = 1013
+kEventMenuBeginTracking = 1
+kEventMenuEndTracking = 2
+kEventMenuChangeTrackingMode = 3
+kEventMenuOpening = 4
+kEventMenuClosed = 5
+kEventMenuTargetItem = 6
+kEventMenuMatchKey = 7
+kEventMenuEnableItems = 8
+kEventMenuPopulate = 9
+kEventMenuMeasureItemWidth = 100
+kEventMenuMeasureItemHeight = 101
+kEventMenuDrawItem = 102
+kEventMenuDrawItemContent = 103
+kEventMenuDispose = 1001
+kMenuContextMenuBar = 1 << 0
+kMenuContextPullDown = 1 << 8
+kMenuContextPopUp = 1 << 9
+kMenuContextSubmenu = 1 << 10
+kMenuContextMenuBarTracking = 1 << 16
+kMenuContextPopUpTracking = 1 << 17
+kMenuContextKeyMatching = 1 << 18
+kMenuContextMenuEnabling = 1 << 19
+kMenuContextCommandIDSearch = 1 << 20
+kEventProcessCommand = 1
+kEventCommandProcess = 1
+kEventCommandUpdateStatus = 2
+kHICommandOK = FOUR_CHAR_CODE('ok  ')
+kHICommandCancel = FOUR_CHAR_CODE('not!')
+kHICommandQuit = FOUR_CHAR_CODE('quit')
+kHICommandUndo = FOUR_CHAR_CODE('undo')
+kHICommandRedo = FOUR_CHAR_CODE('redo')
+kHICommandCut = FOUR_CHAR_CODE('cut ')
+kHICommandCopy = FOUR_CHAR_CODE('copy')
+kHICommandPaste = FOUR_CHAR_CODE('past')
+kHICommandClear = FOUR_CHAR_CODE('clea')
+kHICommandSelectAll = FOUR_CHAR_CODE('sall')
+kHICommandHide = FOUR_CHAR_CODE('hide')
+kHICommandHideOthers = FOUR_CHAR_CODE('hido')
+kHICommandShowAll = FOUR_CHAR_CODE('shal')
+kHICommandPreferences = FOUR_CHAR_CODE('pref')
+kHICommandZoomWindow = FOUR_CHAR_CODE('zoom')
+kHICommandMinimizeWindow = FOUR_CHAR_CODE('mini')
+kHICommandMinimizeAll = FOUR_CHAR_CODE('mina')
+kHICommandMaximizeWindow = FOUR_CHAR_CODE('maxi')
+kHICommandMaximizeAll = FOUR_CHAR_CODE('maxa')
+kHICommandArrangeInFront = FOUR_CHAR_CODE('frnt')
+kHICommandBringAllToFront = FOUR_CHAR_CODE('bfrt')
+kHICommandWindowListSeparator = FOUR_CHAR_CODE('wldv')
+kHICommandWindowListTerminator = FOUR_CHAR_CODE('wlst')
+kHICommandSelectWindow = FOUR_CHAR_CODE('swin')
+kHICommandAbout = FOUR_CHAR_CODE('abou')
+kHICommandNew = FOUR_CHAR_CODE('new ')
+kHICommandOpen = FOUR_CHAR_CODE('open')
+kHICommandClose = FOUR_CHAR_CODE('clos')
+kHICommandSave = FOUR_CHAR_CODE('save')
+kHICommandSaveAs = FOUR_CHAR_CODE('svas')
+kHICommandRevert = FOUR_CHAR_CODE('rvrt')
+kHICommandPrint = FOUR_CHAR_CODE('prnt')
+kHICommandPageSetup = FOUR_CHAR_CODE('page')
+kHICommandAppHelp = FOUR_CHAR_CODE('ahlp')
+kHICommandFromMenu = (1L << 0)
+kHICommandFromControl = (1L << 1)
+kHICommandFromWindow = (1L << 2)
+kEventControlInitialize = 1000
+kEventControlDispose = 1001
+kEventControlGetOptimalBounds = 1003
+kEventControlDefInitialize = kEventControlInitialize
+kEventControlDefDispose = kEventControlDispose
+kEventControlHit = 1
+kEventControlSimulateHit = 2
+kEventControlHitTest = 3
+kEventControlDraw = 4
+kEventControlApplyBackground = 5
+kEventControlApplyTextColor = 6
+kEventControlSetFocusPart = 7
+kEventControlGetFocusPart = 8
+kEventControlActivate = 9
+kEventControlDeactivate = 10
+kEventControlSetCursor = 11
+kEventControlContextualMenuClick = 12
+kEventControlClick = 13
+kEventControlTrack = 51
+kEventControlGetScrollToHereStartPoint = 52
+kEventControlGetIndicatorDragConstraint = 53
+kEventControlIndicatorMoved = 54
+kEventControlGhostingFinished = 55
+kEventControlGetActionProcPart = 56
+kEventControlGetPartRegion = 101
+kEventControlGetPartBounds = 102
+kEventControlSetData = 103
+kEventControlGetData = 104
+kEventControlValueFieldChanged = 151
+kEventControlAddedSubControl = 152
+kEventControlRemovingSubControl = 153
+kEventControlBoundsChanged = 154
+kEventControlOwningWindowChanged = 159
+kEventControlArbitraryMessage = 201
+kControlBoundsChangeSizeChanged = (1 << 2)
+kControlBoundsChangePositionChanged = (1 << 3)
+kEventTabletPoint = 1
+kEventTabletProximity = 2
+kEventTabletPointer = 1
+kEventVolumeMounted = 1
+kEventVolumeUnmounted = 2
+typeFSVolumeRefNum = FOUR_CHAR_CODE('voln')
+kEventAppearanceScrollBarVariantChanged = 1
+kEventServiceCopy = 1
+kEventServicePaste = 2
+kEventServiceGetTypes = 3
+kEventServicePerform = 4
+kEventParamDirectObject = FOUR_CHAR_CODE('----')
+kEventParamPostTarget = FOUR_CHAR_CODE('ptrg')
+typeEventTargetRef = FOUR_CHAR_CODE('etrg')
+kEventParamWindowRef = FOUR_CHAR_CODE('wind')
+kEventParamGrafPort = FOUR_CHAR_CODE('graf')
+kEventParamDragRef = FOUR_CHAR_CODE('drag')
+kEventParamMenuRef = FOUR_CHAR_CODE('menu')
+kEventParamEventRef = FOUR_CHAR_CODE('evnt')
+kEventParamControlRef = FOUR_CHAR_CODE('ctrl')
+kEventParamRgnHandle = FOUR_CHAR_CODE('rgnh')
+kEventParamEnabled = FOUR_CHAR_CODE('enab')
+kEventParamDimensions = FOUR_CHAR_CODE('dims')
+kEventParamAvailableBounds = FOUR_CHAR_CODE('avlb')
+kEventParamAEEventID = keyAEEventID
+kEventParamAEEventClass = keyAEEventClass
+kEventParamCGContextRef = FOUR_CHAR_CODE('cntx')
+kEventParamDeviceDepth = FOUR_CHAR_CODE('devd')
+kEventParamDeviceColor = FOUR_CHAR_CODE('devc')
+typeWindowRef = FOUR_CHAR_CODE('wind')
+typeGrafPtr = FOUR_CHAR_CODE('graf')
+typeGWorldPtr = FOUR_CHAR_CODE('gwld')
+typeDragRef = FOUR_CHAR_CODE('drag')
+typeMenuRef = FOUR_CHAR_CODE('menu')
+typeControlRef = FOUR_CHAR_CODE('ctrl')
+typeCollection = FOUR_CHAR_CODE('cltn')
+typeQDRgnHandle = FOUR_CHAR_CODE('rgnh')
+typeOSStatus = FOUR_CHAR_CODE('osst')
+typeCFStringRef = FOUR_CHAR_CODE('cfst')
+typeCFIndex = FOUR_CHAR_CODE('cfix')
+typeCFTypeRef = FOUR_CHAR_CODE('cfty')
+typeCGContextRef = FOUR_CHAR_CODE('cntx')
+typeHIPoint = FOUR_CHAR_CODE('hipt')
+typeHISize = FOUR_CHAR_CODE('hisz')
+typeHIRect = FOUR_CHAR_CODE('hirc')
+kEventParamMouseLocation = FOUR_CHAR_CODE('mloc')
+kEventParamMouseButton = FOUR_CHAR_CODE('mbtn')
+kEventParamClickCount = FOUR_CHAR_CODE('ccnt')
+kEventParamMouseWheelAxis = FOUR_CHAR_CODE('mwax')
+kEventParamMouseWheelDelta = FOUR_CHAR_CODE('mwdl')
+kEventParamMouseDelta = FOUR_CHAR_CODE('mdta')
+kEventParamMouseChord = FOUR_CHAR_CODE('chor')
+kEventParamTabletEventType = FOUR_CHAR_CODE('tblt')
+typeMouseButton = FOUR_CHAR_CODE('mbtn')
+typeMouseWheelAxis = FOUR_CHAR_CODE('mwax')
+kEventParamKeyCode = FOUR_CHAR_CODE('kcod')
+kEventParamKeyMacCharCodes = FOUR_CHAR_CODE('kchr')
+kEventParamKeyModifiers = FOUR_CHAR_CODE('kmod')
+kEventParamKeyUnicodes = FOUR_CHAR_CODE('kuni')
+kEventParamKeyboardType = FOUR_CHAR_CODE('kbdt')
+typeEventHotKeyID = FOUR_CHAR_CODE('hkid')
+kEventParamTextInputSendRefCon = FOUR_CHAR_CODE('tsrc')
+kEventParamTextInputSendComponentInstance = FOUR_CHAR_CODE('tsci')
+kEventParamTextInputSendSLRec = FOUR_CHAR_CODE('tssl')
+kEventParamTextInputReplySLRec = FOUR_CHAR_CODE('trsl')
+kEventParamTextInputSendText = FOUR_CHAR_CODE('tstx')
+kEventParamTextInputReplyText = FOUR_CHAR_CODE('trtx')
+kEventParamTextInputSendUpdateRng = FOUR_CHAR_CODE('tsup')
+kEventParamTextInputSendHiliteRng = FOUR_CHAR_CODE('tshi')
+kEventParamTextInputSendClauseRng = FOUR_CHAR_CODE('tscl')
+kEventParamTextInputSendPinRng = FOUR_CHAR_CODE('tspn')
+kEventParamTextInputSendFixLen = FOUR_CHAR_CODE('tsfx')
+kEventParamTextInputSendLeadingEdge = FOUR_CHAR_CODE('tsle')
+kEventParamTextInputReplyLeadingEdge = FOUR_CHAR_CODE('trle')
+kEventParamTextInputSendTextOffset = FOUR_CHAR_CODE('tsto')
+kEventParamTextInputReplyTextOffset = FOUR_CHAR_CODE('trto')
+kEventParamTextInputReplyRegionClass = FOUR_CHAR_CODE('trrg')
+kEventParamTextInputSendCurrentPoint = FOUR_CHAR_CODE('tscp')
+kEventParamTextInputSendDraggingMode = FOUR_CHAR_CODE('tsdm')
+kEventParamTextInputReplyPoint = FOUR_CHAR_CODE('trpt')
+kEventParamTextInputReplyFont = FOUR_CHAR_CODE('trft')
+kEventParamTextInputReplyFMFont = FOUR_CHAR_CODE('trfm')
+kEventParamTextInputReplyPointSize = FOUR_CHAR_CODE('trpz')
+kEventParamTextInputReplyLineHeight = FOUR_CHAR_CODE('trlh')
+kEventParamTextInputReplyLineAscent = FOUR_CHAR_CODE('trla')
+kEventParamTextInputReplyTextAngle = FOUR_CHAR_CODE('trta')
+kEventParamTextInputSendShowHide = FOUR_CHAR_CODE('tssh')
+kEventParamTextInputReplyShowHide = FOUR_CHAR_CODE('trsh')
+kEventParamTextInputSendKeyboardEvent = FOUR_CHAR_CODE('tske')
+kEventParamTextInputSendTextServiceEncoding = FOUR_CHAR_CODE('tsse')
+kEventParamTextInputSendTextServiceMacEncoding = FOUR_CHAR_CODE('tssm')
+kEventParamHICommand = FOUR_CHAR_CODE('hcmd')
+typeHICommand = FOUR_CHAR_CODE('hcmd')
+kEventParamWindowFeatures = FOUR_CHAR_CODE('wftr')
+kEventParamWindowDefPart = FOUR_CHAR_CODE('wdpc')
+kEventParamCurrentBounds = FOUR_CHAR_CODE('crct')
+kEventParamOriginalBounds = FOUR_CHAR_CODE('orct')
+kEventParamPreviousBounds = FOUR_CHAR_CODE('prct')
+kEventParamClickActivation = FOUR_CHAR_CODE('clac')
+kEventParamWindowRegionCode = FOUR_CHAR_CODE('wshp')
+kEventParamWindowDragHiliteFlag = FOUR_CHAR_CODE('wdhf')
+kEventParamWindowModifiedFlag = FOUR_CHAR_CODE('wmff')
+kEventParamWindowProxyGWorldPtr = FOUR_CHAR_CODE('wpgw')
+kEventParamWindowProxyImageRgn = FOUR_CHAR_CODE('wpir')
+kEventParamWindowProxyOutlineRgn = FOUR_CHAR_CODE('wpor')
+kEventParamWindowStateChangedFlags = FOUR_CHAR_CODE('wscf')
+kEventParamWindowTitleFullWidth = FOUR_CHAR_CODE('wtfw')
+kEventParamWindowTitleTextWidth = FOUR_CHAR_CODE('wttw')
+kEventParamWindowGrowRect = FOUR_CHAR_CODE('grct')
+kEventParamAttributes = FOUR_CHAR_CODE('attr')
+kEventParamDockChangedReason = FOUR_CHAR_CODE('dcrs')
+kEventParamPreviousDockRect = FOUR_CHAR_CODE('pdrc')
+kEventParamCurrentDockRect = FOUR_CHAR_CODE('cdrc')
+typeWindowRegionCode = FOUR_CHAR_CODE('wshp')
+typeWindowDefPartCode = FOUR_CHAR_CODE('wdpt')
+typeClickActivationResult = FOUR_CHAR_CODE('clac')
+kEventParamControlPart = FOUR_CHAR_CODE('cprt')
+kEventParamInitCollection = FOUR_CHAR_CODE('icol')
+kEventParamControlMessage = FOUR_CHAR_CODE('cmsg')
+kEventParamControlParam = FOUR_CHAR_CODE('cprm')
+kEventParamControlResult = FOUR_CHAR_CODE('crsl')
+kEventParamControlRegion = FOUR_CHAR_CODE('crgn')
+kEventParamControlAction = FOUR_CHAR_CODE('caup')
+kEventParamControlIndicatorDragConstraint = FOUR_CHAR_CODE('cidc')
+kEventParamControlIndicatorRegion = FOUR_CHAR_CODE('cirn')
+kEventParamControlIsGhosting = FOUR_CHAR_CODE('cgst')
+kEventParamControlIndicatorOffset = FOUR_CHAR_CODE('ciof')
+kEventParamControlClickActivationResult = FOUR_CHAR_CODE('ccar')
+kEventParamControlSubControl = FOUR_CHAR_CODE('csub')
+kEventParamControlOptimalBounds = FOUR_CHAR_CODE('cobn')
+kEventParamControlOptimalBaselineOffset = FOUR_CHAR_CODE('cobo')
+kEventParamControlDataTag = FOUR_CHAR_CODE('cdtg')
+kEventParamControlDataBuffer = FOUR_CHAR_CODE('cdbf')
+kEventParamControlDataBufferSize = FOUR_CHAR_CODE('cdbs')
+kEventParamControlDrawDepth = FOUR_CHAR_CODE('cddp')
+kEventParamControlDrawInColor = FOUR_CHAR_CODE('cdic')
+kEventParamControlFeatures = FOUR_CHAR_CODE('cftr')
+kEventParamControlPartBounds = FOUR_CHAR_CODE('cpbd')
+kEventParamControlOriginalOwningWindow = FOUR_CHAR_CODE('coow')
+kEventParamControlCurrentOwningWindow = FOUR_CHAR_CODE('ccow')
+typeControlActionUPP = FOUR_CHAR_CODE('caup')
+typeIndicatorDragConstraint = FOUR_CHAR_CODE('cidc')
+typeControlPartCode = FOUR_CHAR_CODE('cprt')
+kEventParamCurrentMenuTrackingMode = FOUR_CHAR_CODE('cmtm')
+kEventParamNewMenuTrackingMode = FOUR_CHAR_CODE('nmtm')
+kEventParamMenuFirstOpen = FOUR_CHAR_CODE('1sto')
+kEventParamMenuItemIndex = FOUR_CHAR_CODE('item')
+kEventParamMenuCommand = FOUR_CHAR_CODE('mcmd')
+kEventParamEnableMenuForKeyEvent = FOUR_CHAR_CODE('fork')
+kEventParamMenuEventOptions = FOUR_CHAR_CODE('meop')
+kEventParamMenuContext = FOUR_CHAR_CODE('mctx')
+kEventParamMenuItemBounds = FOUR_CHAR_CODE('mitb')
+kEventParamMenuMarkBounds = FOUR_CHAR_CODE('mmkb')
+kEventParamMenuIconBounds = FOUR_CHAR_CODE('micb')
+kEventParamMenuTextBounds = FOUR_CHAR_CODE('mtxb')
+kEventParamMenuTextBaseline = FOUR_CHAR_CODE('mtbl')
+kEventParamMenuCommandKeyBounds = FOUR_CHAR_CODE('mcmb')
+kEventParamMenuVirtualTop = FOUR_CHAR_CODE('mvrt')
+kEventParamMenuVirtualBottom = FOUR_CHAR_CODE('mvrb')
+kEventParamMenuDrawState = FOUR_CHAR_CODE('mdrs')
+kEventParamMenuItemType = FOUR_CHAR_CODE('mitp')
+kEventParamMenuItemWidth = FOUR_CHAR_CODE('mitw')
+kEventParamMenuItemHeight = FOUR_CHAR_CODE('mith')
+typeMenuItemIndex = FOUR_CHAR_CODE('midx')
+typeMenuCommand = FOUR_CHAR_CODE('mcmd')
+typeMenuTrackingMode = FOUR_CHAR_CODE('mtmd')
+typeMenuEventOptions = FOUR_CHAR_CODE('meop')
+typeThemeMenuState = FOUR_CHAR_CODE('tmns')
+typeThemeMenuItemType = FOUR_CHAR_CODE('tmit')
+kEventParamProcessID = FOUR_CHAR_CODE('psn ')
+kEventParamLaunchRefCon = FOUR_CHAR_CODE('lref')
+kEventParamLaunchErr = FOUR_CHAR_CODE('err ')
+kEventParamTabletPointRec = FOUR_CHAR_CODE('tbrc')
+kEventParamTabletProximityRec = FOUR_CHAR_CODE('tbpx')
+typeTabletPointRec = FOUR_CHAR_CODE('tbrc')
+typeTabletProximityRec = FOUR_CHAR_CODE('tbpx')
+kEventParamTabletPointerRec = FOUR_CHAR_CODE('tbrc')
+typeTabletPointerRec = FOUR_CHAR_CODE('tbrc')
+kEventParamNewScrollBarVariant = FOUR_CHAR_CODE('nsbv')
+kEventParamScrapRef = FOUR_CHAR_CODE('scrp')
+kEventParamServiceCopyTypes = FOUR_CHAR_CODE('svsd')
+kEventParamServicePasteTypes = FOUR_CHAR_CODE('svpt')
+kEventParamServiceMessageName = FOUR_CHAR_CODE('svmg')
+kEventParamServiceUserData = FOUR_CHAR_CODE('svud')
+typeScrapRef = FOUR_CHAR_CODE('scrp')
+typeCFMutableArrayRef = FOUR_CHAR_CODE('cfma')
+# sHandler = NewEventHandlerUPP( x )
+kMouseTrackingMousePressed = kMouseTrackingMouseDown
+kMouseTrackingMouseReleased = kMouseTrackingMouseUp


Property changes on: vendor/Python/current/Lib/plat-mac/Carbon/CarbonEvents.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/plat-mac/Carbon/CarbonEvt.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/CarbonEvt.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/CarbonEvt.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1 @@
+from _CarbonEvt import *


Property changes on: vendor/Python/current/Lib/plat-mac/Carbon/CarbonEvt.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/plat-mac/Carbon/Cm.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/Cm.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/Cm.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1 @@
+from _Cm import *

Added: vendor/Python/current/Lib/plat-mac/Carbon/Components.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/Components.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/Components.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,62 @@
+# Generated from 'Components.h'
+
+def FOUR_CHAR_CODE(x): return x
+kAppleManufacturer = FOUR_CHAR_CODE('appl')
+kComponentResourceType = FOUR_CHAR_CODE('thng')
+kComponentAliasResourceType = FOUR_CHAR_CODE('thga')
+kAnyComponentType = 0
+kAnyComponentSubType = 0
+kAnyComponentManufacturer = 0
+kAnyComponentFlagsMask = 0
+cmpIsMissing = 1L << 29
+cmpWantsRegisterMessage = 1L << 31
+kComponentOpenSelect = -1
+kComponentCloseSelect = -2
+kComponentCanDoSelect = -3
+kComponentVersionSelect = -4
+kComponentRegisterSelect = -5
+kComponentTargetSelect = -6
+kComponentUnregisterSelect = -7
+kComponentGetMPWorkFunctionSelect = -8
+kComponentExecuteWiredActionSelect = -9
+kComponentGetPublicResourceSelect = -10
+componentDoAutoVersion = (1 << 0)
+componentWantsUnregister = (1 << 1)
+componentAutoVersionIncludeFlags = (1 << 2)
+componentHasMultiplePlatforms = (1 << 3)
+componentLoadResident = (1 << 4)
+defaultComponentIdentical = 0
+defaultComponentAnyFlags = 1
+defaultComponentAnyManufacturer = 2
+defaultComponentAnySubType = 4
+defaultComponentAnyFlagsAnyManufacturer = (defaultComponentAnyFlags + defaultComponentAnyManufacturer)
+defaultComponentAnyFlagsAnyManufacturerAnySubType = (defaultComponentAnyFlags + defaultComponentAnyManufacturer + defaultComponentAnySubType)
+registerComponentGlobal = 1
+registerComponentNoDuplicates = 2
+registerComponentAfterExisting = 4
+registerComponentAliasesOnly = 8
+platform68k = 1
+platformPowerPC = 2
+platformInterpreted = 3
+platformWin32 = 4
+platformPowerPCNativeEntryPoint = 5
+mpWorkFlagDoWork = (1 << 0)
+mpWorkFlagDoCompletion = (1 << 1)
+mpWorkFlagCopyWorkBlock = (1 << 2)
+mpWorkFlagDontBlock = (1 << 3)
+mpWorkFlagGetProcessorCount = (1 << 4)
+mpWorkFlagGetIsRunning = (1 << 6)
+cmpAliasNoFlags = 0
+cmpAliasOnlyThisFile = 1
+uppComponentFunctionImplementedProcInfo = 0x000002F0
+uppGetComponentVersionProcInfo = 0x000000F0
+uppComponentSetTargetProcInfo = 0x000003F0
+uppCallComponentOpenProcInfo = 0x000003F0
+uppCallComponentCloseProcInfo = 0x000003F0
+uppCallComponentCanDoProcInfo = 0x000002F0
+uppCallComponentVersionProcInfo = 0x000000F0
+uppCallComponentRegisterProcInfo = 0x000000F0
+uppCallComponentTargetProcInfo = 0x000003F0
+uppCallComponentUnregisterProcInfo = 0x000000F0
+uppCallComponentGetMPWorkFunctionProcInfo = 0x00000FF0
+uppCallComponentGetPublicResourceProcInfo = 0x00003BF0

Added: vendor/Python/current/Lib/plat-mac/Carbon/ControlAccessor.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/ControlAccessor.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/ControlAccessor.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,56 @@
+# Accessor functions for control properties
+
+from Controls import *
+import struct
+
+# These needn't go through this module, but are here for completeness
+def SetControlData_Handle(control, part, selector, data):
+    control.SetControlData_Handle(part, selector, data)
+
+def GetControlData_Handle(control, part, selector):
+    return control.GetControlData_Handle(part, selector)
+
+_accessdict = {
+    kControlPopupButtonMenuHandleTag: (SetControlData_Handle, GetControlData_Handle),
+}
+
+_codingdict = {
+    kControlPushButtonDefaultTag : ("b", None, None),
+
+    kControlEditTextTextTag: (None, None, None),
+    kControlEditTextPasswordTag: (None, None, None),
+
+    kControlPopupButtonMenuIDTag: ("h", None, None),
+
+    kControlListBoxDoubleClickTag: ("b", None, None),
+}
+
+def SetControlData(control, part, selector, data):
+    if _accessdict.has_key(selector):
+        setfunc, getfunc = _accessdict[selector]
+        setfunc(control, part, selector, data)
+        return
+    if not _codingdict.has_key(selector):
+        raise KeyError, ('Unknown control selector', selector)
+    structfmt, coder, decoder = _codingdict[selector]
+    if coder:
+        data = coder(data)
+    if structfmt:
+        data = struct.pack(structfmt, data)
+    control.SetControlData(part, selector, data)
+
+def GetControlData(control, part, selector):
+    if _accessdict.has_key(selector):
+        setfunc, getfunc = _accessdict[selector]
+        return getfunc(control, part, selector, data)
+    if not _codingdict.has_key(selector):
+        raise KeyError, ('Unknown control selector', selector)
+    structfmt, coder, decoder = _codingdict[selector]
+    data = control.GetControlData(part, selector)
+    if structfmt:
+        data = struct.unpack(structfmt, data)
+    if decoder:
+        data = decoder(data)
+    if type(data) == type(()) and len(data) == 1:
+        data = data[0]
+    return data

Added: vendor/Python/current/Lib/plat-mac/Carbon/Controls.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/Controls.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/Controls.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,668 @@
+# Generated from 'Controls.h'
+
+def FOUR_CHAR_CODE(x): return x
+from Carbon.TextEdit import *
+from Carbon.QuickDraw import *
+from Carbon.Dragconst import *
+from Carbon.CarbonEvents import *
+from Carbon.Appearance import *
+kDataBrowserItemAnyState = -1
+kControlBevelButtonCenterPopupGlyphTag = -1
+kDataBrowserClientPropertyFlagsMask = 0xFF000000
+
+kControlDefProcType = FOUR_CHAR_CODE('CDEF')
+kControlTemplateResourceType = FOUR_CHAR_CODE('CNTL')
+kControlColorTableResourceType = FOUR_CHAR_CODE('cctb')
+kControlDefProcResourceType = FOUR_CHAR_CODE('CDEF')
+controlNotifyNothing = FOUR_CHAR_CODE('nada')
+controlNotifyClick = FOUR_CHAR_CODE('clik')
+controlNotifyFocus = FOUR_CHAR_CODE('focu')
+controlNotifyKey = FOUR_CHAR_CODE('key ')
+kControlCanAutoInvalidate = 1L << 0
+staticTextProc = 256
+editTextProc = 272
+iconProc = 288
+userItemProc = 304
+pictItemProc = 320
+cFrameColor = 0
+cBodyColor = 1
+cTextColor = 2
+cThumbColor = 3
+kNumberCtlCTabEntries = 4
+kControlNoVariant = 0
+kControlUsesOwningWindowsFontVariant = 1 << 3
+kControlNoPart = 0
+kControlIndicatorPart = 129
+kControlDisabledPart = 254
+kControlInactivePart = 255
+kControlEntireControl = 0
+kControlStructureMetaPart = -1
+kControlContentMetaPart = -2
+kControlFocusNoPart = 0
+kControlFocusNextPart = -1
+kControlFocusPrevPart = -2
+kControlCollectionTagBounds = FOUR_CHAR_CODE('boun')
+kControlCollectionTagValue = FOUR_CHAR_CODE('valu')
+kControlCollectionTagMinimum = FOUR_CHAR_CODE('min ')
+kControlCollectionTagMaximum = FOUR_CHAR_CODE('max ')
+kControlCollectionTagViewSize = FOUR_CHAR_CODE('view')
+kControlCollectionTagVisibility = FOUR_CHAR_CODE('visi')
+kControlCollectionTagRefCon = FOUR_CHAR_CODE('refc')
+kControlCollectionTagTitle = FOUR_CHAR_CODE('titl')
+kControlCollectionTagUnicodeTitle = FOUR_CHAR_CODE('uttl')
+kControlCollectionTagIDSignature = FOUR_CHAR_CODE('idsi')
+kControlCollectionTagIDID = FOUR_CHAR_CODE('idid')
+kControlCollectionTagCommand = FOUR_CHAR_CODE('cmd ')
+kControlCollectionTagVarCode = FOUR_CHAR_CODE('varc')
+kControlContentTextOnly = 0
+kControlNoContent = 0
+kControlContentIconSuiteRes = 1
+kControlContentCIconRes = 2
+kControlContentPictRes = 3
+kControlContentICONRes = 4
+kControlContentIconSuiteHandle = 129
+kControlContentCIconHandle = 130
+kControlContentPictHandle = 131
+kControlContentIconRef = 132
+kControlContentICON = 133
+kControlKeyScriptBehaviorAllowAnyScript = FOUR_CHAR_CODE('any ')
+kControlKeyScriptBehaviorPrefersRoman = FOUR_CHAR_CODE('prmn')
+kControlKeyScriptBehaviorRequiresRoman = FOUR_CHAR_CODE('rrmn')
+kControlFontBigSystemFont = -1
+kControlFontSmallSystemFont = -2
+kControlFontSmallBoldSystemFont = -3
+kControlFontViewSystemFont = -4
+kControlUseFontMask = 0x0001
+kControlUseFaceMask = 0x0002
+kControlUseSizeMask = 0x0004
+kControlUseForeColorMask = 0x0008
+kControlUseBackColorMask = 0x0010
+kControlUseModeMask = 0x0020
+kControlUseJustMask = 0x0040
+kControlUseAllMask = 0x00FF
+kControlAddFontSizeMask = 0x0100
+kControlAddToMetaFontMask = 0x0200
+kControlUseThemeFontIDMask = 0x0080
+kDoNotActivateAndIgnoreClick = 0
+kDoNotActivateAndHandleClick = 1
+kActivateAndIgnoreClick = 2
+kActivateAndHandleClick = 3
+kControlFontStyleTag = FOUR_CHAR_CODE('font')
+kControlKeyFilterTag = FOUR_CHAR_CODE('fltr')
+kControlKindTag = FOUR_CHAR_CODE('kind')
+kControlSizeTag = FOUR_CHAR_CODE('size')
+kControlSupportsGhosting = 1 << 0
+kControlSupportsEmbedding = 1 << 1
+kControlSupportsFocus = 1 << 2
+kControlWantsIdle = 1 << 3
+kControlWantsActivate = 1 << 4
+kControlHandlesTracking = 1 << 5
+kControlSupportsDataAccess = 1 << 6
+kControlHasSpecialBackground = 1 << 7
+kControlGetsFocusOnClick = 1 << 8
+kControlSupportsCalcBestRect = 1 << 9
+kControlSupportsLiveFeedback = 1 << 10
+kControlHasRadioBehavior = 1 << 11
+kControlSupportsDragAndDrop = 1 << 12
+kControlAutoToggles = 1 << 14
+kControlSupportsGetRegion = 1 << 17
+kControlSupportsFlattening = 1 << 19
+kControlSupportsSetCursor = 1 << 20
+kControlSupportsContextualMenus = 1 << 21
+kControlSupportsClickActivation = 1 << 22
+kControlIdlesWithTimer = 1 << 23
+drawCntl = 0
+testCntl = 1
+calcCRgns = 2
+initCntl = 3
+dispCntl = 4
+posCntl = 5
+thumbCntl = 6
+dragCntl = 7
+autoTrack = 8
+calcCntlRgn = 10
+calcThumbRgn = 11
+drawThumbOutline = 12
+kControlMsgDrawGhost = 13
+kControlMsgCalcBestRect = 14
+kControlMsgHandleTracking = 15
+kControlMsgFocus = 16
+kControlMsgKeyDown = 17
+kControlMsgIdle = 18
+kControlMsgGetFeatures = 19
+kControlMsgSetData = 20
+kControlMsgGetData = 21
+kControlMsgActivate = 22
+kControlMsgSetUpBackground = 23
+kControlMsgCalcValueFromPos = 26
+kControlMsgTestNewMsgSupport = 27
+kControlMsgSubValueChanged = 25
+kControlMsgSubControlAdded = 28
+kControlMsgSubControlRemoved = 29
+kControlMsgApplyTextColor = 30
+kControlMsgGetRegion = 31
+kControlMsgFlatten = 32
+kControlMsgSetCursor = 33
+kControlMsgDragEnter = 38
+kControlMsgDragLeave = 39
+kControlMsgDragWithin = 40
+kControlMsgDragReceive = 41
+kControlMsgDisplayDebugInfo = 46
+kControlMsgContextualMenuClick = 47
+kControlMsgGetClickActivation = 48
+kControlSizeNormal = 0
+kControlSizeSmall = 1
+kControlSizeLarge = 2
+kControlSizeAuto = 0xFFFF
+kDrawControlEntireControl = 0
+kDrawControlIndicatorOnly = 129
+kDragControlEntireControl = 0
+kDragControlIndicator = 1
+kControlSupportsNewMessages = FOUR_CHAR_CODE(' ok ')
+kControlKeyFilterBlockKey = 0
+kControlKeyFilterPassKey = 1
+noConstraint = kNoConstraint
+hAxisOnly = 1
+vAxisOnly = 2
+kControlDefProcPtr = 0
+kControlDefObjectClass = 1
+kControlKindSignatureApple = FOUR_CHAR_CODE('appl')
+kControlPropertyPersistent = 0x00000001
+kDragTrackingEnterControl = 2
+kDragTrackingInControl = 3
+kDragTrackingLeaveControl = 4
+useWFont = kControlUsesOwningWindowsFontVariant
+inThumb = kControlIndicatorPart
+kNoHiliteControlPart = kControlNoPart
+kInIndicatorControlPart = kControlIndicatorPart
+kReservedControlPart = kControlDisabledPart
+kControlInactiveControlPart = kControlInactivePart
+kControlTabListResType = FOUR_CHAR_CODE('tab#')
+kControlListDescResType = FOUR_CHAR_CODE('ldes')
+kControlCheckBoxUncheckedValue = 0
+kControlCheckBoxCheckedValue = 1
+kControlCheckBoxMixedValue = 2
+kControlRadioButtonUncheckedValue = 0
+kControlRadioButtonCheckedValue = 1
+kControlRadioButtonMixedValue = 2
+popupFixedWidth = 1 << 0
+popupVariableWidth = 1 << 1
+popupUseAddResMenu = 1 << 2
+popupUseWFont = 1 << 3
+popupTitleBold = 1 << 8
+popupTitleItalic = 1 << 9
+popupTitleUnderline = 1 << 10
+popupTitleOutline = 1 << 11
+popupTitleShadow = 1 << 12
+popupTitleCondense = 1 << 13
+popupTitleExtend = 1 << 14
+popupTitleNoStyle = 1 << 15
+popupTitleLeftJust = 0x00000000
+popupTitleCenterJust = 0x00000001
+popupTitleRightJust = 0x000000FF
+pushButProc = 0
+checkBoxProc = 1
+radioButProc = 2
+scrollBarProc = 16
+popupMenuProc = 1008
+kControlLabelPart = 1
+kControlMenuPart = 2
+kControlTrianglePart = 4
+kControlEditTextPart = 5
+kControlPicturePart = 6
+kControlIconPart = 7
+kControlClockPart = 8
+kControlListBoxPart = 24
+kControlListBoxDoubleClickPart = 25
+kControlImageWellPart = 26
+kControlRadioGroupPart = 27
+kControlButtonPart = 10
+kControlCheckBoxPart = 11
+kControlRadioButtonPart = 11
+kControlUpButtonPart = 20
+kControlDownButtonPart = 21
+kControlPageUpPart = 22
+kControlPageDownPart = 23
+kControlClockHourDayPart = 9
+kControlClockMinuteMonthPart = 10
+kControlClockSecondYearPart = 11
+kControlClockAMPMPart = 12
+kControlDataBrowserPart = 24
+kControlDataBrowserDraggedPart = 25
+kControlBevelButtonSmallBevelProc = 32
+kControlBevelButtonNormalBevelProc = 33
+kControlBevelButtonLargeBevelProc = 34
+kControlBevelButtonSmallBevelVariant = 0
+kControlBevelButtonNormalBevelVariant = (1 << 0)
+kControlBevelButtonLargeBevelVariant = (1 << 1)
+kControlBevelButtonMenuOnRightVariant = (1 << 2)
+kControlBevelButtonSmallBevel = 0
+kControlBevelButtonNormalBevel = 1
+kControlBevelButtonLargeBevel = 2
+kControlBehaviorPushbutton = 0
+kControlBehaviorToggles = 0x0100
+kControlBehaviorSticky = 0x0200
+kControlBehaviorSingleValueMenu = 0
+kControlBehaviorMultiValueMenu = 0x4000
+kControlBehaviorOffsetContents = 0x8000
+kControlBehaviorCommandMenu = 0x2000
+kControlBevelButtonMenuOnBottom = 0
+kControlBevelButtonMenuOnRight = (1 << 2)
+kControlKindBevelButton = FOUR_CHAR_CODE('bevl')
+kControlBevelButtonAlignSysDirection = -1
+kControlBevelButtonAlignCenter = 0
+kControlBevelButtonAlignLeft = 1
+kControlBevelButtonAlignRight = 2
+kControlBevelButtonAlignTop = 3
+kControlBevelButtonAlignBottom = 4
+kControlBevelButtonAlignTopLeft = 5
+kControlBevelButtonAlignBottomLeft = 6
+kControlBevelButtonAlignTopRight = 7
+kControlBevelButtonAlignBottomRight = 8
+kControlBevelButtonAlignTextSysDirection = teFlushDefault
+kControlBevelButtonAlignTextCenter = teCenter
+kControlBevelButtonAlignTextFlushRight = teFlushRight
+kControlBevelButtonAlignTextFlushLeft = teFlushLeft
+kControlBevelButtonPlaceSysDirection = -1
+kControlBevelButtonPlaceNormally = 0
+kControlBevelButtonPlaceToRightOfGraphic = 1
+kControlBevelButtonPlaceToLeftOfGraphic = 2
+kControlBevelButtonPlaceBelowGraphic = 3
+kControlBevelButtonPlaceAboveGraphic = 4
+kControlBevelButtonContentTag = FOUR_CHAR_CODE('cont')
+kControlBevelButtonTransformTag = FOUR_CHAR_CODE('tran')
+kControlBevelButtonTextAlignTag = FOUR_CHAR_CODE('tali')
+kControlBevelButtonTextOffsetTag = FOUR_CHAR_CODE('toff')
+kControlBevelButtonGraphicAlignTag = FOUR_CHAR_CODE('gali')
+kControlBevelButtonGraphicOffsetTag = FOUR_CHAR_CODE('goff')
+kControlBevelButtonTextPlaceTag = FOUR_CHAR_CODE('tplc')
+kControlBevelButtonMenuValueTag = FOUR_CHAR_CODE('mval')
+kControlBevelButtonMenuHandleTag = FOUR_CHAR_CODE('mhnd')
+kControlBevelButtonMenuRefTag = FOUR_CHAR_CODE('mhnd')
+# kControlBevelButtonCenterPopupGlyphTag = FOUR_CHAR_CODE('pglc')
+kControlBevelButtonLastMenuTag = FOUR_CHAR_CODE('lmnu')
+kControlBevelButtonMenuDelayTag = FOUR_CHAR_CODE('mdly')
+kControlBevelButtonScaleIconTag = FOUR_CHAR_CODE('scal')
+kControlBevelButtonOwnedMenuRefTag = FOUR_CHAR_CODE('omrf')
+kControlBevelButtonKindTag = FOUR_CHAR_CODE('bebk')
+kControlSliderProc = 48
+kControlSliderLiveFeedback = (1 << 0)
+kControlSliderHasTickMarks = (1 << 1)
+kControlSliderReverseDirection = (1 << 2)
+kControlSliderNonDirectional = (1 << 3)
+kControlSliderPointsDownOrRight = 0
+kControlSliderPointsUpOrLeft = 1
+kControlSliderDoesNotPoint = 2
+kControlKindSlider = FOUR_CHAR_CODE('sldr')
+kControlTriangleProc = 64
+kControlTriangleLeftFacingProc = 65
+kControlTriangleAutoToggleProc = 66
+kControlTriangleLeftFacingAutoToggleProc = 67
+kControlDisclosureTrianglePointDefault = 0
+kControlDisclosureTrianglePointRight = 1
+kControlDisclosureTrianglePointLeft = 2
+kControlKindDisclosureTriangle = FOUR_CHAR_CODE('dist')
+kControlTriangleLastValueTag = FOUR_CHAR_CODE('last')
+kControlProgressBarProc = 80
+kControlRelevanceBarProc = 81
+kControlKindProgressBar = FOUR_CHAR_CODE('prgb')
+kControlKindRelevanceBar = FOUR_CHAR_CODE('relb')
+kControlProgressBarIndeterminateTag = FOUR_CHAR_CODE('inde')
+kControlProgressBarAnimatingTag = FOUR_CHAR_CODE('anim')
+kControlLittleArrowsProc = 96
+kControlKindLittleArrows = FOUR_CHAR_CODE('larr')
+kControlChasingArrowsProc = 112
+kControlKindChasingArrows = FOUR_CHAR_CODE('carr')
+kControlChasingArrowsAnimatingTag = FOUR_CHAR_CODE('anim')
+kControlTabLargeProc = 128
+kControlTabSmallProc = 129
+kControlTabLargeNorthProc = 128
+kControlTabSmallNorthProc = 129
+kControlTabLargeSouthProc = 130
+kControlTabSmallSouthProc = 131
+kControlTabLargeEastProc = 132
+kControlTabSmallEastProc = 133
+kControlTabLargeWestProc = 134
+kControlTabSmallWestProc = 135
+kControlTabDirectionNorth = 0
+kControlTabDirectionSouth = 1
+kControlTabDirectionEast = 2
+kControlTabDirectionWest = 3
+kControlTabSizeLarge = kControlSizeNormal
+kControlTabSizeSmall = kControlSizeSmall
+kControlKindTabs = FOUR_CHAR_CODE('tabs')
+kControlTabContentRectTag = FOUR_CHAR_CODE('rect')
+kControlTabEnabledFlagTag = FOUR_CHAR_CODE('enab')
+kControlTabFontStyleTag = kControlFontStyleTag
+kControlTabInfoTag = FOUR_CHAR_CODE('tabi')
+kControlTabImageContentTag = FOUR_CHAR_CODE('cont')
+kControlTabInfoVersionZero = 0
+kControlTabInfoVersionOne = 1
+kControlSeparatorLineProc = 144
+kControlKindSeparator = FOUR_CHAR_CODE('sepa')
+kControlGroupBoxTextTitleProc = 160
+kControlGroupBoxCheckBoxProc = 161
+kControlGroupBoxPopupButtonProc = 162
+kControlGroupBoxSecondaryTextTitleProc = 164
+kControlGroupBoxSecondaryCheckBoxProc = 165
+kControlGroupBoxSecondaryPopupButtonProc = 166
+kControlKindGroupBox = FOUR_CHAR_CODE('grpb')
+kControlKindCheckGroupBox = FOUR_CHAR_CODE('cgrp')
+kControlKindPopupGroupBox = FOUR_CHAR_CODE('pgrp')
+kControlGroupBoxMenuHandleTag = FOUR_CHAR_CODE('mhan')
+kControlGroupBoxMenuRefTag = FOUR_CHAR_CODE('mhan')
+kControlGroupBoxFontStyleTag = kControlFontStyleTag
+kControlGroupBoxTitleRectTag = FOUR_CHAR_CODE('trec')
+kControlImageWellProc = 176
+kControlKindImageWell = FOUR_CHAR_CODE('well')
+kControlImageWellContentTag = FOUR_CHAR_CODE('cont')
+kControlImageWellTransformTag = FOUR_CHAR_CODE('tran')
+kControlImageWellIsDragDestinationTag = FOUR_CHAR_CODE('drag')
+kControlPopupArrowEastProc = 192
+kControlPopupArrowWestProc = 193
+kControlPopupArrowNorthProc = 194
+kControlPopupArrowSouthProc = 195
+kControlPopupArrowSmallEastProc = 196
+kControlPopupArrowSmallWestProc = 197
+kControlPopupArrowSmallNorthProc = 198
+kControlPopupArrowSmallSouthProc = 199
+kControlPopupArrowOrientationEast = 0
+kControlPopupArrowOrientationWest = 1
+kControlPopupArrowOrientationNorth = 2
+kControlPopupArrowOrientationSouth = 3
+kControlPopupArrowSizeNormal = 0
+kControlPopupArrowSizeSmall = 1
+kControlKindPopupArrow = FOUR_CHAR_CODE('parr')
+kControlPlacardProc = 224
+kControlKindPlacard = FOUR_CHAR_CODE('plac')
+kControlClockTimeProc = 240
+kControlClockTimeSecondsProc = 241
+kControlClockDateProc = 242
+kControlClockMonthYearProc = 243
+kControlClockTypeHourMinute = 0
+kControlClockTypeHourMinuteSecond = 1
+kControlClockTypeMonthDayYear = 2
+kControlClockTypeMonthYear = 3
+kControlClockFlagStandard = 0
+kControlClockNoFlags = 0
+kControlClockFlagDisplayOnly = 1
+kControlClockIsDisplayOnly = 1
+kControlClockFlagLive = 2
+kControlClockIsLive = 2
+kControlKindClock = FOUR_CHAR_CODE('clck')
+kControlClockLongDateTag = FOUR_CHAR_CODE('date')
+kControlClockFontStyleTag = kControlFontStyleTag
+kControlClockAnimatingTag = FOUR_CHAR_CODE('anim')
+kControlUserPaneProc = 256
+kControlKindUserPane = FOUR_CHAR_CODE('upan')
+kControlUserItemDrawProcTag = FOUR_CHAR_CODE('uidp')
+kControlUserPaneDrawProcTag = FOUR_CHAR_CODE('draw')
+kControlUserPaneHitTestProcTag = FOUR_CHAR_CODE('hitt')
+kControlUserPaneTrackingProcTag = FOUR_CHAR_CODE('trak')
+kControlUserPaneIdleProcTag = FOUR_CHAR_CODE('idle')
+kControlUserPaneKeyDownProcTag = FOUR_CHAR_CODE('keyd')
+kControlUserPaneActivateProcTag = FOUR_CHAR_CODE('acti')
+kControlUserPaneFocusProcTag = FOUR_CHAR_CODE('foci')
+kControlUserPaneBackgroundProcTag = FOUR_CHAR_CODE('back')
+kControlEditTextProc = 272
+kControlEditTextPasswordProc = 274
+kControlEditTextInlineInputProc = 276
+kControlKindEditText = FOUR_CHAR_CODE('etxt')
+kControlEditTextStyleTag = kControlFontStyleTag
+kControlEditTextTextTag = FOUR_CHAR_CODE('text')
+kControlEditTextTEHandleTag = FOUR_CHAR_CODE('than')
+kControlEditTextKeyFilterTag = kControlKeyFilterTag
+kControlEditTextSelectionTag = FOUR_CHAR_CODE('sele')
+kControlEditTextPasswordTag = FOUR_CHAR_CODE('pass')
+kControlEditTextKeyScriptBehaviorTag = FOUR_CHAR_CODE('kscr')
+kControlEditTextLockedTag = FOUR_CHAR_CODE('lock')
+kControlEditTextFixedTextTag = FOUR_CHAR_CODE('ftxt')
+kControlEditTextValidationProcTag = FOUR_CHAR_CODE('vali')
+kControlEditTextInlinePreUpdateProcTag = FOUR_CHAR_CODE('prup')
+kControlEditTextInlinePostUpdateProcTag = FOUR_CHAR_CODE('poup')
+kControlEditTextCFStringTag = FOUR_CHAR_CODE('cfst')
+kControlEditTextPasswordCFStringTag = FOUR_CHAR_CODE('pwcf')
+kControlStaticTextProc = 288
+kControlKindStaticText = FOUR_CHAR_CODE('stxt')
+kControlStaticTextStyleTag = kControlFontStyleTag
+kControlStaticTextTextTag = FOUR_CHAR_CODE('text')
+kControlStaticTextTextHeightTag = FOUR_CHAR_CODE('thei')
+kControlStaticTextTruncTag = FOUR_CHAR_CODE('trun')
+kControlStaticTextCFStringTag = FOUR_CHAR_CODE('cfst')
+kControlPictureProc = 304
+kControlPictureNoTrackProc = 305
+kControlKindPicture = FOUR_CHAR_CODE('pict')
+kControlPictureHandleTag = FOUR_CHAR_CODE('pich')
+kControlIconProc = 320
+kControlIconNoTrackProc = 321
+kControlIconSuiteProc = 322
+kControlIconSuiteNoTrackProc = 323
+kControlIconRefProc = 324
+kControlIconRefNoTrackProc = 325
+kControlKindIcon = FOUR_CHAR_CODE('icon')
+kControlIconTransformTag = FOUR_CHAR_CODE('trfm')
+kControlIconAlignmentTag = FOUR_CHAR_CODE('algn')
+kControlIconResourceIDTag = FOUR_CHAR_CODE('ires')
+kControlIconContentTag = FOUR_CHAR_CODE('cont')
+kControlWindowHeaderProc = 336
+kControlWindowListViewHeaderProc = 337
+kControlKindWindowHeader = FOUR_CHAR_CODE('whed')
+kControlListBoxProc = 352
+kControlListBoxAutoSizeProc = 353
+kControlKindListBox = FOUR_CHAR_CODE('lbox')
+kControlListBoxListHandleTag = FOUR_CHAR_CODE('lhan')
+kControlListBoxKeyFilterTag = kControlKeyFilterTag
+kControlListBoxFontStyleTag = kControlFontStyleTag
+kControlListBoxDoubleClickTag = FOUR_CHAR_CODE('dblc')
+kControlListBoxLDEFTag = FOUR_CHAR_CODE('ldef')
+kControlPushButtonProc = 368
+kControlCheckBoxProc = 369
+kControlRadioButtonProc = 370
+kControlPushButLeftIconProc = 374
+kControlPushButRightIconProc = 375
+kControlCheckBoxAutoToggleProc = 371
+kControlRadioButtonAutoToggleProc = 372
+kControlPushButtonIconOnLeft = 6
+kControlPushButtonIconOnRight = 7
+kControlKindPushButton = FOUR_CHAR_CODE('push')
+kControlKindPushIconButton = FOUR_CHAR_CODE('picn')
+kControlKindRadioButton = FOUR_CHAR_CODE('rdio')
+kControlKindCheckBox = FOUR_CHAR_CODE('cbox')
+kControlPushButtonDefaultTag = FOUR_CHAR_CODE('dflt')
+kControlPushButtonCancelTag = FOUR_CHAR_CODE('cncl')
+kControlScrollBarProc = 384
+kControlScrollBarLiveProc = 386
+kControlKindScrollBar = FOUR_CHAR_CODE('sbar')
+kControlScrollBarShowsArrowsTag = FOUR_CHAR_CODE('arro')
+kControlPopupButtonProc = 400
+kControlPopupFixedWidthVariant = 1 << 0
+kControlPopupVariableWidthVariant = 1 << 1
+kControlPopupUseAddResMenuVariant = 1 << 2
+kControlPopupUseWFontVariant = kControlUsesOwningWindowsFontVariant
+kControlKindPopupButton = FOUR_CHAR_CODE('popb')
+kControlPopupButtonMenuHandleTag = FOUR_CHAR_CODE('mhan')
+kControlPopupButtonMenuRefTag = FOUR_CHAR_CODE('mhan')
+kControlPopupButtonMenuIDTag = FOUR_CHAR_CODE('mnid')
+kControlPopupButtonExtraHeightTag = FOUR_CHAR_CODE('exht')
+kControlPopupButtonOwnedMenuRefTag = FOUR_CHAR_CODE('omrf')
+kControlPopupButtonCheckCurrentTag = FOUR_CHAR_CODE('chck')
+kControlRadioGroupProc = 416
+kControlKindRadioGroup = FOUR_CHAR_CODE('rgrp')
+kControlScrollTextBoxProc = 432
+kControlScrollTextBoxAutoScrollProc = 433
+kControlKindScrollingTextBox = FOUR_CHAR_CODE('stbx')
+kControlScrollTextBoxDelayBeforeAutoScrollTag = FOUR_CHAR_CODE('stdl')
+kControlScrollTextBoxDelayBetweenAutoScrollTag = FOUR_CHAR_CODE('scdl')
+kControlScrollTextBoxAutoScrollAmountTag = FOUR_CHAR_CODE('samt')
+kControlScrollTextBoxContentsTag = FOUR_CHAR_CODE('tres')
+kControlScrollTextBoxAnimatingTag = FOUR_CHAR_CODE('anim')
+kControlKindDisclosureButton = FOUR_CHAR_CODE('disb')
+kControlDisclosureButtonClosed = 0
+kControlDisclosureButtonDisclosed = 1
+kControlRoundButtonNormalSize = kControlSizeNormal
+kControlRoundButtonLargeSize = kControlSizeLarge
+kControlRoundButtonContentTag = FOUR_CHAR_CODE('cont')
+kControlRoundButtonSizeTag = kControlSizeTag
+kControlKindRoundButton = FOUR_CHAR_CODE('rndb')
+kControlKindDataBrowser = FOUR_CHAR_CODE('datb')
+errDataBrowserNotConfigured = -4970
+errDataBrowserItemNotFound = -4971
+errDataBrowserItemNotAdded = -4975
+errDataBrowserPropertyNotFound = -4972
+errDataBrowserInvalidPropertyPart = -4973
+errDataBrowserInvalidPropertyData = -4974
+errDataBrowserPropertyNotSupported = -4979
+kControlDataBrowserIncludesFrameAndFocusTag = FOUR_CHAR_CODE('brdr')
+kControlDataBrowserKeyFilterTag = kControlEditTextKeyFilterTag
+kControlDataBrowserEditTextKeyFilterTag = kControlDataBrowserKeyFilterTag
+kControlDataBrowserEditTextValidationProcTag = kControlEditTextValidationProcTag
+kDataBrowserNoView = 0x3F3F3F3F
+kDataBrowserListView = FOUR_CHAR_CODE('lstv')
+kDataBrowserColumnView = FOUR_CHAR_CODE('clmv')
+kDataBrowserDragSelect = 1 << 0
+kDataBrowserSelectOnlyOne = 1 << 1
+kDataBrowserResetSelection = 1 << 2
+kDataBrowserCmdTogglesSelection = 1 << 3
+kDataBrowserNoDisjointSelection = 1 << 4
+kDataBrowserAlwaysExtendSelection = 1 << 5
+kDataBrowserNeverEmptySelectionSet = 1 << 6
+kDataBrowserOrderUndefined = 0
+kDataBrowserOrderIncreasing = 1
+kDataBrowserOrderDecreasing = 2
+kDataBrowserNoItem = 0L
+kDataBrowserItemNoState = 0
+# kDataBrowserItemAnyState = (unsigned long)(-1)
+kDataBrowserItemIsSelected = 1 << 0
+kDataBrowserContainerIsOpen = 1 << 1
+kDataBrowserItemIsDragTarget = 1 << 2
+kDataBrowserRevealOnly = 0
+kDataBrowserRevealAndCenterInView = 1 << 0
+kDataBrowserRevealWithoutSelecting = 1 << 1
+kDataBrowserItemsAdd = 0
+kDataBrowserItemsAssign = 1
+kDataBrowserItemsToggle = 2
+kDataBrowserItemsRemove = 3
+kDataBrowserSelectionAnchorUp = 0
+kDataBrowserSelectionAnchorDown = 1
+kDataBrowserSelectionAnchorLeft = 2
+kDataBrowserSelectionAnchorRight = 3
+kDataBrowserEditMsgUndo = kHICommandUndo
+kDataBrowserEditMsgRedo = kHICommandRedo
+kDataBrowserEditMsgCut = kHICommandCut
+kDataBrowserEditMsgCopy = kHICommandCopy
+kDataBrowserEditMsgPaste = kHICommandPaste
+kDataBrowserEditMsgClear = kHICommandClear
+kDataBrowserEditMsgSelectAll = kHICommandSelectAll
+kDataBrowserItemAdded = 1
+kDataBrowserItemRemoved = 2
+kDataBrowserEditStarted = 3
+kDataBrowserEditStopped = 4
+kDataBrowserItemSelected = 5
+kDataBrowserItemDeselected = 6
+kDataBrowserItemDoubleClicked = 7
+kDataBrowserContainerOpened = 8
+kDataBrowserContainerClosing = 9
+kDataBrowserContainerClosed = 10
+kDataBrowserContainerSorting = 11
+kDataBrowserContainerSorted = 12
+kDataBrowserUserToggledContainer = 16
+kDataBrowserTargetChanged = 15
+kDataBrowserUserStateChanged = 13
+kDataBrowserSelectionSetChanged = 14
+kDataBrowserItemNoProperty = 0L
+kDataBrowserItemIsActiveProperty = 1L
+kDataBrowserItemIsSelectableProperty = 2L
+kDataBrowserItemIsEditableProperty = 3L
+kDataBrowserItemIsContainerProperty = 4L
+kDataBrowserContainerIsOpenableProperty = 5L
+kDataBrowserContainerIsClosableProperty = 6L
+kDataBrowserContainerIsSortableProperty = 7L
+kDataBrowserItemSelfIdentityProperty = 8L
+kDataBrowserContainerAliasIDProperty = 9L
+kDataBrowserColumnViewPreviewProperty = 10L
+kDataBrowserItemParentContainerProperty = 11L
+kDataBrowserCustomType = 0x3F3F3F3F
+kDataBrowserIconType = FOUR_CHAR_CODE('icnr')
+kDataBrowserTextType = FOUR_CHAR_CODE('text')
+kDataBrowserDateTimeType = FOUR_CHAR_CODE('date')
+kDataBrowserSliderType = FOUR_CHAR_CODE('sldr')
+kDataBrowserCheckboxType = FOUR_CHAR_CODE('chbx')
+kDataBrowserProgressBarType = FOUR_CHAR_CODE('prog')
+kDataBrowserRelevanceRankType = FOUR_CHAR_CODE('rank')
+kDataBrowserPopupMenuType = FOUR_CHAR_CODE('menu')
+kDataBrowserIconAndTextType = FOUR_CHAR_CODE('ticn')
+kDataBrowserPropertyEnclosingPart = 0L
+kDataBrowserPropertyContentPart = FOUR_CHAR_CODE('----')
+kDataBrowserPropertyDisclosurePart = FOUR_CHAR_CODE('disc')
+kDataBrowserPropertyTextPart = kDataBrowserTextType
+kDataBrowserPropertyIconPart = kDataBrowserIconType
+kDataBrowserPropertySliderPart = kDataBrowserSliderType
+kDataBrowserPropertyCheckboxPart = kDataBrowserCheckboxType
+kDataBrowserPropertyProgressBarPart = kDataBrowserProgressBarType
+kDataBrowserPropertyRelevanceRankPart = kDataBrowserRelevanceRankType
+kDataBrowserUniversalPropertyFlagsMask = 0xFF
+kDataBrowserPropertyIsMutable = 1 << 0
+kDataBrowserDefaultPropertyFlags = 0 << 0
+kDataBrowserUniversalPropertyFlags = kDataBrowserUniversalPropertyFlagsMask
+kDataBrowserPropertyIsEditable = kDataBrowserPropertyIsMutable
+kDataBrowserPropertyFlagsOffset = 8
+kDataBrowserPropertyFlagsMask = 0xFF << kDataBrowserPropertyFlagsOffset
+kDataBrowserCheckboxTriState = 1 << kDataBrowserPropertyFlagsOffset
+kDataBrowserDateTimeRelative = 1 << (kDataBrowserPropertyFlagsOffset)
+kDataBrowserDateTimeDateOnly = 1 << (kDataBrowserPropertyFlagsOffset + 1)
+kDataBrowserDateTimeTimeOnly = 1 << (kDataBrowserPropertyFlagsOffset + 2)
+kDataBrowserDateTimeSecondsToo = 1 << (kDataBrowserPropertyFlagsOffset + 3)
+kDataBrowserSliderPlainThumb = kThemeThumbPlain << kDataBrowserPropertyFlagsOffset
+kDataBrowserSliderUpwardThumb = kThemeThumbUpward << kDataBrowserPropertyFlagsOffset
+kDataBrowserSliderDownwardThumb = kThemeThumbDownward << kDataBrowserPropertyFlagsOffset
+kDataBrowserDoNotTruncateText = 3 << kDataBrowserPropertyFlagsOffset
+kDataBrowserTruncateTextAtEnd = 2 << kDataBrowserPropertyFlagsOffset
+kDataBrowserTruncateTextMiddle = 0 << kDataBrowserPropertyFlagsOffset
+kDataBrowserTruncateTextAtStart = 1 << kDataBrowserPropertyFlagsOffset
+kDataBrowserPropertyModificationFlags = kDataBrowserPropertyFlagsMask
+kDataBrowserRelativeDateTime = kDataBrowserDateTimeRelative
+kDataBrowserViewSpecificFlagsOffset = 16
+kDataBrowserViewSpecificFlagsMask = 0xFF << kDataBrowserViewSpecificFlagsOffset
+kDataBrowserViewSpecificPropertyFlags = kDataBrowserViewSpecificFlagsMask
+kDataBrowserClientPropertyFlagsOffset = 24
+# kDataBrowserClientPropertyFlagsMask = (unsigned long)(0xFF << kDataBrowserClientPropertyFlagsOffset)
+kDataBrowserLatestCallbacks = 0
+kDataBrowserContentHit = 1
+kDataBrowserNothingHit = 0
+kDataBrowserStopTracking = -1
+kDataBrowserLatestCustomCallbacks = 0
+kDataBrowserTableViewMinimalHilite = 0
+kDataBrowserTableViewFillHilite = 1
+kDataBrowserTableViewSelectionColumn = 1 << kDataBrowserViewSpecificFlagsOffset
+kDataBrowserTableViewLastColumn = -1
+kDataBrowserListViewMovableColumn = 1 << (kDataBrowserViewSpecificFlagsOffset + 1)
+kDataBrowserListViewSortableColumn = 1 << (kDataBrowserViewSpecificFlagsOffset + 2)
+kDataBrowserListViewSelectionColumn = kDataBrowserTableViewSelectionColumn
+kDataBrowserListViewDefaultColumnFlags = kDataBrowserListViewMovableColumn + kDataBrowserListViewSortableColumn
+kDataBrowserListViewLatestHeaderDesc = 0
+kDataBrowserListViewAppendColumn = kDataBrowserTableViewLastColumn
+kControlEditUnicodeTextPostUpdateProcTag = FOUR_CHAR_CODE('upup')
+kControlEditUnicodeTextProc = 912
+kControlEditUnicodeTextPasswordProc = 914
+kControlKindEditUnicodeText = FOUR_CHAR_CODE('eutx')
+kControlCheckboxUncheckedValue = kControlCheckBoxUncheckedValue
+kControlCheckboxCheckedValue = kControlCheckBoxCheckedValue
+kControlCheckboxMixedValue = kControlCheckBoxMixedValue
+inLabel = kControlLabelPart
+inMenu = kControlMenuPart
+inTriangle = kControlTrianglePart
+inButton = kControlButtonPart
+inCheckBox = kControlCheckBoxPart
+inUpButton = kControlUpButtonPart
+inDownButton = kControlDownButtonPart
+inPageUp = kControlPageUpPart
+inPageDown = kControlPageDownPart
+kInLabelControlPart = kControlLabelPart
+kInMenuControlPart = kControlMenuPart
+kInTriangleControlPart = kControlTrianglePart
+kInButtonControlPart = kControlButtonPart
+kInCheckBoxControlPart = kControlCheckBoxPart
+kInUpButtonControlPart = kControlUpButtonPart
+kInDownButtonControlPart = kControlDownButtonPart
+kInPageUpControlPart = kControlPageUpPart
+kInPageDownControlPart = kControlPageDownPart

Added: vendor/Python/current/Lib/plat-mac/Carbon/CoreFoundation.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/CoreFoundation.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/CoreFoundation.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,28 @@
+# Generated from 'CFBase.h'
+
+def FOUR_CHAR_CODE(x): return x
+kCFCompareLessThan = -1
+kCFCompareEqualTo = 0
+kCFCompareGreaterThan = 1
+kCFNotFound = -1
+kCFPropertyListImmutable = 0
+kCFPropertyListMutableContainers = 1
+kCFPropertyListMutableContainersAndLeaves = 2
+# kCFStringEncodingInvalidId = (long)0xFFFFFFFF
+kCFStringEncodingMacRoman = 0
+kCFStringEncodingWindowsLatin1 = 0x0500
+kCFStringEncodingISOLatin1 = 0x0201
+kCFStringEncodingNextStepLatin = 0x0B01
+kCFStringEncodingASCII = 0x0600
+kCFStringEncodingUnicode = 0x0100
+kCFStringEncodingUTF8 = 0x08000100
+kCFStringEncodingNonLossyASCII = 0x0BFF
+kCFCompareCaseInsensitive = 1
+kCFCompareBackwards = 4
+kCFCompareAnchored = 8
+kCFCompareNonliteral = 16
+kCFCompareLocalized = 32
+kCFCompareNumerically = 64
+kCFURLPOSIXPathStyle = 0
+kCFURLHFSPathStyle = 1
+kCFURLWindowsPathStyle = 2

Added: vendor/Python/current/Lib/plat-mac/Carbon/CoreGraphics.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/CoreGraphics.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/CoreGraphics.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,28 @@
+# Generated from 'CGContext.h'
+
+def FOUR_CHAR_CODE(x): return x
+kCGLineJoinMiter = 0
+kCGLineJoinRound = 1
+kCGLineJoinBevel = 2
+kCGLineCapButt = 0
+kCGLineCapRound = 1
+kCGLineCapSquare = 2
+kCGPathFill = 0
+kCGPathEOFill = 1
+kCGPathStroke = 2
+kCGPathFillStroke = 3
+kCGPathEOFillStroke = 4
+kCGTextFill = 0
+kCGTextStroke = 1
+kCGTextFillStroke = 2
+kCGTextInvisible = 3
+kCGTextFillClip = 4
+kCGTextStrokeClip = 5
+kCGTextFillStrokeClip = 6
+kCGTextClip = 7
+kCGEncodingFontSpecific = 0
+kCGEncodingMacRoman = 1
+kCGInterpolationDefault = 0
+kCGInterpolationNone = 1
+kCGInterpolationLow = 2
+kCGInterpolationHigh = 3


Property changes on: vendor/Python/current/Lib/plat-mac/Carbon/CoreGraphics.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/plat-mac/Carbon/Ctl.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/Ctl.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/Ctl.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1 @@
+from _Ctl import *

Added: vendor/Python/current/Lib/plat-mac/Carbon/Dialogs.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/Dialogs.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/Dialogs.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,79 @@
+# Generated from 'Dialogs.h'
+
+def FOUR_CHAR_CODE(x): return x
+kControlDialogItem = 4
+kButtonDialogItem = kControlDialogItem | 0
+kCheckBoxDialogItem = kControlDialogItem | 1
+kRadioButtonDialogItem = kControlDialogItem | 2
+kResourceControlDialogItem = kControlDialogItem | 3
+kStaticTextDialogItem = 8
+kEditTextDialogItem = 16
+kIconDialogItem = 32
+kPictureDialogItem = 64
+kUserDialogItem = 0
+kHelpDialogItem = 1
+kItemDisableBit = 128
+ctrlItem = 4
+btnCtrl = 0
+chkCtrl = 1
+radCtrl = 2
+resCtrl = 3
+statText = 8
+editText = 16
+iconItem = 32
+picItem = 64
+userItem = 0
+itemDisable = 128
+kStdOkItemIndex = 1
+kStdCancelItemIndex = 2
+ok = kStdOkItemIndex
+cancel = kStdCancelItemIndex
+kStopIcon = 0
+kNoteIcon = 1
+kCautionIcon = 2
+stopIcon = kStopIcon
+noteIcon = kNoteIcon
+cautionIcon = kCautionIcon
+kOkItemIndex = 1
+kCancelItemIndex = 2
+overlayDITL = 0
+appendDITLRight = 1
+appendDITLBottom = 2
+kAlertStopAlert = 0
+kAlertNoteAlert = 1
+kAlertCautionAlert = 2
+kAlertPlainAlert = 3
+kAlertDefaultOKText = -1
+kAlertDefaultCancelText = -1
+kAlertDefaultOtherText = -1
+kAlertStdAlertOKButton = 1
+kAlertStdAlertCancelButton = 2
+kAlertStdAlertOtherButton = 3
+kAlertStdAlertHelpButton = 4
+kDialogFlagsUseThemeBackground = (1 << 0)
+kDialogFlagsUseControlHierarchy = (1 << 1)
+kDialogFlagsHandleMovableModal = (1 << 2)
+kDialogFlagsUseThemeControls = (1 << 3)
+kAlertFlagsUseThemeBackground = (1 << 0)
+kAlertFlagsUseControlHierarchy = (1 << 1)
+kAlertFlagsAlertIsMovable = (1 << 2)
+kAlertFlagsUseThemeControls = (1 << 3)
+kDialogFontNoFontStyle = 0
+kDialogFontUseFontMask = 0x0001
+kDialogFontUseFaceMask = 0x0002
+kDialogFontUseSizeMask = 0x0004
+kDialogFontUseForeColorMask = 0x0008
+kDialogFontUseBackColorMask = 0x0010
+kDialogFontUseModeMask = 0x0020
+kDialogFontUseJustMask = 0x0040
+kDialogFontUseAllMask = 0x00FF
+kDialogFontAddFontSizeMask = 0x0100
+kDialogFontUseFontNameMask = 0x0200
+kDialogFontAddToMetaFontMask = 0x0400
+kDialogFontUseThemeFontIDMask = 0x0080
+kHICommandOther = FOUR_CHAR_CODE('othr')
+kStdCFStringAlertVersionOne = 1
+kStdAlertDoNotDisposeSheet = 1 << 0
+kStdAlertDoNotAnimateOnDefault = 1 << 1
+kStdAlertDoNotAnimateOnCancel = 1 << 2
+kStdAlertDoNotAnimateOnOther = 1 << 3

Added: vendor/Python/current/Lib/plat-mac/Carbon/Dlg.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/Dlg.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/Dlg.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1 @@
+from _Dlg import *

Added: vendor/Python/current/Lib/plat-mac/Carbon/Drag.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/Drag.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/Drag.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1 @@
+from _Drag import *

Added: vendor/Python/current/Lib/plat-mac/Carbon/Dragconst.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/Dragconst.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/Dragconst.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,86 @@
+# Generated from 'Drag.h'
+
+def FOUR_CHAR_CODE(x): return x
+from Carbon.TextEdit import *
+from Carbon.QuickDraw import *
+fkDragActionAll = -1
+
+
+kDragHasLeftSenderWindow        = (1 << 0)
+kDragInsideSenderApplication = (1 << 1)
+kDragInsideSenderWindow         = (1 << 2)
+kDragRegionAndImage                     = (1 << 4)
+flavorSenderOnly                        = (1 << 0)
+flavorSenderTranslated          = (1 << 1)
+flavorNotSaved                          = (1 << 2)
+flavorSystemTranslated          = (1 << 8)
+kDragHasLeftSenderWindow = (1L << 0)
+kDragInsideSenderApplication = (1L << 1)
+kDragInsideSenderWindow = (1L << 2)
+kDragBehaviorNone = 0
+kDragBehaviorZoomBackAnimation = (1L << 0)
+kDragRegionAndImage = (1L << 4)
+kDragStandardTranslucency = 0L
+kDragDarkTranslucency = 1L
+kDragDarkerTranslucency = 2L
+kDragOpaqueTranslucency = 3L
+kDragRegionBegin = 1
+kDragRegionDraw = 2
+kDragRegionHide = 3
+kDragRegionIdle = 4
+kDragRegionEnd = 5
+kZoomNoAcceleration = 0
+kZoomAccelerate = 1
+kZoomDecelerate = 2
+flavorSenderOnly = (1 << 0)
+flavorSenderTranslated = (1 << 1)
+flavorNotSaved = (1 << 2)
+flavorSystemTranslated = (1 << 8)
+flavorDataPromised = (1 << 9)
+kDragFlavorTypeHFS = FOUR_CHAR_CODE('hfs ')
+kDragFlavorTypePromiseHFS = FOUR_CHAR_CODE('phfs')
+flavorTypeHFS = kDragFlavorTypeHFS
+flavorTypePromiseHFS = kDragFlavorTypePromiseHFS
+kDragPromisedFlavorFindFile = FOUR_CHAR_CODE('rWm1')
+kDragPromisedFlavor = FOUR_CHAR_CODE('fssP')
+kDragPseudoCreatorVolumeOrDirectory = FOUR_CHAR_CODE('MACS')
+kDragPseudoFileTypeVolume = FOUR_CHAR_CODE('disk')
+kDragPseudoFileTypeDirectory = FOUR_CHAR_CODE('fold')
+flavorTypeDirectory = FOUR_CHAR_CODE('diry')
+kFlavorTypeClippingName = FOUR_CHAR_CODE('clnm')
+kFlavorTypeClippingFilename = FOUR_CHAR_CODE('clfn')
+kFlavorTypeDragToTrashOnly = FOUR_CHAR_CODE('fdtt')
+kFlavorTypeFinderNoTrackingBehavior = FOUR_CHAR_CODE('fntb')
+kDragTrackingEnterHandler = 1
+kDragTrackingEnterWindow = 2
+kDragTrackingInWindow = 3
+kDragTrackingLeaveWindow = 4
+kDragTrackingLeaveHandler = 5
+kDragActionNothing = 0L
+kDragActionCopy = 1L
+kDragActionAlias = (1L << 1)
+kDragActionGeneric = (1L << 2)
+kDragActionPrivate = (1L << 3)
+kDragActionMove = (1L << 4)
+kDragActionDelete = (1L << 5)
+# kDragActionAll = (long)0xFFFFFFFF
+dragHasLeftSenderWindow = kDragHasLeftSenderWindow
+dragInsideSenderApplication = kDragInsideSenderApplication
+dragInsideSenderWindow = kDragInsideSenderWindow
+dragTrackingEnterHandler = kDragTrackingEnterHandler
+dragTrackingEnterWindow = kDragTrackingEnterWindow
+dragTrackingInWindow = kDragTrackingInWindow
+dragTrackingLeaveWindow = kDragTrackingLeaveWindow
+dragTrackingLeaveHandler = kDragTrackingLeaveHandler
+dragRegionBegin = kDragRegionBegin
+dragRegionDraw = kDragRegionDraw
+dragRegionHide = kDragRegionHide
+dragRegionIdle = kDragRegionIdle
+dragRegionEnd = kDragRegionEnd
+zoomNoAcceleration = kZoomNoAcceleration
+zoomAccelerate = kZoomAccelerate
+zoomDecelerate = kZoomDecelerate
+kDragStandardImage = kDragStandardTranslucency
+kDragDarkImage = kDragDarkTranslucency
+kDragDarkerImage = kDragDarkerTranslucency
+kDragOpaqueImage = kDragOpaqueTranslucency

Added: vendor/Python/current/Lib/plat-mac/Carbon/Events.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/Events.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/Events.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,102 @@
+# Generated from 'Events.h'
+
+nullEvent = 0
+mouseDown = 1
+mouseUp = 2
+keyDown = 3
+keyUp = 4
+autoKey = 5
+updateEvt = 6
+diskEvt = 7
+activateEvt = 8
+osEvt = 15
+kHighLevelEvent = 23
+mDownMask = 1 << mouseDown
+mUpMask = 1 << mouseUp
+keyDownMask = 1 << keyDown
+keyUpMask = 1 << keyUp
+autoKeyMask = 1 << autoKey
+updateMask = 1 << updateEvt
+diskMask = 1 << diskEvt
+activMask = 1 << activateEvt
+highLevelEventMask = 0x0400
+osMask = 1 << osEvt
+everyEvent = 0xFFFF
+charCodeMask = 0x000000FF
+keyCodeMask = 0x0000FF00
+adbAddrMask = 0x00FF0000
+# osEvtMessageMask = (unsigned long)0xFF000000
+mouseMovedMessage = 0x00FA
+suspendResumeMessage = 0x0001
+resumeFlag = 1
+convertClipboardFlag = 2
+activeFlagBit = 0
+btnStateBit = 7
+cmdKeyBit = 8
+shiftKeyBit = 9
+alphaLockBit = 10
+optionKeyBit = 11
+controlKeyBit = 12
+rightShiftKeyBit = 13
+rightOptionKeyBit = 14
+rightControlKeyBit = 15
+activeFlag = 1 << activeFlagBit
+btnState = 1 << btnStateBit
+cmdKey = 1 << cmdKeyBit
+shiftKey = 1 << shiftKeyBit
+alphaLock = 1 << alphaLockBit
+optionKey = 1 << optionKeyBit
+controlKey = 1 << controlKeyBit
+rightShiftKey = 1 << rightShiftKeyBit
+rightOptionKey = 1 << rightOptionKeyBit
+rightControlKey = 1 << rightControlKeyBit
+kNullCharCode = 0
+kHomeCharCode = 1
+kEnterCharCode = 3
+kEndCharCode = 4
+kHelpCharCode = 5
+kBellCharCode = 7
+kBackspaceCharCode = 8
+kTabCharCode = 9
+kLineFeedCharCode = 10
+kVerticalTabCharCode = 11
+kPageUpCharCode = 11
+kFormFeedCharCode = 12
+kPageDownCharCode = 12
+kReturnCharCode = 13
+kFunctionKeyCharCode = 16
+kCommandCharCode = 17
+kCheckCharCode = 18
+kDiamondCharCode = 19
+kAppleLogoCharCode = 20
+kEscapeCharCode = 27
+kClearCharCode = 27
+kLeftArrowCharCode = 28
+kRightArrowCharCode = 29
+kUpArrowCharCode = 30
+kDownArrowCharCode = 31
+kSpaceCharCode = 32
+kDeleteCharCode = 127
+kBulletCharCode = 165
+kNonBreakingSpaceCharCode = 202
+kShiftUnicode = 0x21E7
+kControlUnicode = 0x2303
+kOptionUnicode = 0x2325
+kCommandUnicode = 0x2318
+kPencilUnicode = 0x270E
+kCheckUnicode = 0x2713
+kDiamondUnicode = 0x25C6
+kBulletUnicode = 0x2022
+kAppleLogoUnicode = 0xF8FF
+networkEvt = 10
+driverEvt = 11
+app1Evt = 12
+app2Evt = 13
+app3Evt = 14
+app4Evt = 15
+networkMask = 0x0400
+driverMask = 0x0800
+app1Mask = 0x1000
+app2Mask = 0x2000
+app3Mask = 0x4000
+app4Mask = 0x8000

Added: vendor/Python/current/Lib/plat-mac/Carbon/Evt.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/Evt.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/Evt.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1 @@
+from _Evt import *

Added: vendor/Python/current/Lib/plat-mac/Carbon/File.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/File.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/File.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1 @@
+from _File import *

Added: vendor/Python/current/Lib/plat-mac/Carbon/Files.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/Files.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/Files.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,426 @@
+# Generated from 'Files.h'
+
+def FOUR_CHAR_CODE(x): return x
+true = True
+false = False
+fsCurPerm = 0x00
+fsRdPerm = 0x01
+fsWrPerm = 0x02
+fsRdWrPerm = 0x03
+fsRdWrShPerm = 0x04
+fsRdDenyPerm = 0x10
+fsWrDenyPerm = 0x20
+fsRtParID = 1
+fsRtDirID = 2
+fsAtMark = 0
+fsFromStart = 1
+fsFromLEOF = 2
+fsFromMark = 3
+pleaseCacheBit = 4
+pleaseCacheMask = 0x0010
+noCacheBit = 5
+noCacheMask = 0x0020
+rdVerifyBit = 6
+rdVerifyMask = 0x0040
+rdVerify = 64
+forceReadBit = 6
+forceReadMask = 0x0040
+newLineBit = 7
+newLineMask = 0x0080
+newLineCharMask = 0xFF00
+fsSBPartialName = 1
+fsSBFullName = 2
+fsSBFlAttrib = 4
+fsSBFlFndrInfo = 8
+fsSBFlLgLen = 32
+fsSBFlPyLen = 64
+fsSBFlRLgLen = 128
+fsSBFlRPyLen = 256
+fsSBFlCrDat = 512
+fsSBFlMdDat = 1024
+fsSBFlBkDat = 2048
+fsSBFlXFndrInfo = 4096
+fsSBFlParID = 8192
+fsSBNegate = 16384
+fsSBDrUsrWds = 8
+fsSBDrNmFls = 16
+fsSBDrCrDat = 512
+fsSBDrMdDat = 1024
+fsSBDrBkDat = 2048
+fsSBDrFndrInfo = 4096
+fsSBDrParID = 8192
+fsSBPartialNameBit = 0
+fsSBFullNameBit = 1
+fsSBFlAttribBit = 2
+fsSBFlFndrInfoBit = 3
+fsSBFlLgLenBit = 5
+fsSBFlPyLenBit = 6
+fsSBFlRLgLenBit = 7
+fsSBFlRPyLenBit = 8
+fsSBFlCrDatBit = 9
+fsSBFlMdDatBit = 10
+fsSBFlBkDatBit = 11
+fsSBFlXFndrInfoBit = 12
+fsSBFlParIDBit = 13
+fsSBNegateBit = 14
+fsSBDrUsrWdsBit = 3
+fsSBDrNmFlsBit = 4
+fsSBDrCrDatBit = 9
+fsSBDrMdDatBit = 10
+fsSBDrBkDatBit = 11
+fsSBDrFndrInfoBit = 12
+fsSBDrParIDBit = 13
+bLimitFCBs = 31
+bLocalWList = 30
+bNoMiniFndr = 29
+bNoVNEdit = 28
+bNoLclSync = 27
+bTrshOffLine = 26
+bNoSwitchTo = 25
+bDontShareIt = 21
+bNoDeskItems = 20
+bNoBootBlks = 19
+bAccessCntl = 18
+bNoSysDir = 17
+bHasExtFSVol = 16
+bHasOpenDeny = 15
+bHasCopyFile = 14
+bHasMoveRename = 13
+bHasDesktopMgr = 12
+bHasShortName = 11
+bHasFolderLock = 10
+bHasPersonalAccessPrivileges = 9
+bHasUserGroupList = 8
+bHasCatSearch = 7
+bHasFileIDs = 6
+bHasBTreeMgr = 5
+bHasBlankAccessPrivileges = 4
+bSupportsAsyncRequests = 3
+bSupportsTrashVolumeCache = 2
+bIsEjectable = 0
+bSupportsHFSPlusAPIs = 1
+bSupportsFSCatalogSearch = 2
+bSupportsFSExchangeObjects = 3
+bSupports2TBFiles = 4
+bSupportsLongNames = 5
+bSupportsMultiScriptNames = 6
+bSupportsNamedForks = 7
+bSupportsSubtreeIterators = 8
+bL2PCanMapFileBlocks = 9
+bParentModDateChanges = 10
+bAncestorModDateChanges = 11
+bSupportsSymbolicLinks = 13
+bIsAutoMounted = 14
+bAllowCDiDataHandler = 17
+kLargeIcon = 1
+kLarge4BitIcon = 2
+kLarge8BitIcon = 3
+kSmallIcon = 4
+kSmall4BitIcon = 5
+kSmall8BitIcon = 6
+kicnsIconFamily = 239
+kLargeIconSize = 256
+kLarge4BitIconSize = 512
+kLarge8BitIconSize = 1024
+kSmallIconSize = 64
+kSmall4BitIconSize = 128
+kSmall8BitIconSize = 256
+kWidePosOffsetBit = 8
+kUseWidePositioning = (1 << kWidePosOffsetBit)
+kMaximumBlocksIn4GB = 0x007FFFFF
+fsUnixPriv = 1
+kNoUserAuthentication = 1
+kPassword = 2
+kEncryptPassword = 3
+kTwoWayEncryptPassword = 6
+kOwnerID2Name = 1
+kGroupID2Name = 2
+kOwnerName2ID = 3
+kGroupName2ID = 4
+kReturnNextUser = 1
+kReturnNextGroup = 2
+kReturnNextUG = 3
+kVCBFlagsIdleFlushBit = 3
+kVCBFlagsIdleFlushMask = 0x0008
+kVCBFlagsHFSPlusAPIsBit = 4
+kVCBFlagsHFSPlusAPIsMask = 0x0010
+kVCBFlagsHardwareGoneBit = 5
+kVCBFlagsHardwareGoneMask = 0x0020
+kVCBFlagsVolumeDirtyBit = 15
+kVCBFlagsVolumeDirtyMask = 0x8000
+kioVAtrbDefaultVolumeBit = 5
+kioVAtrbDefaultVolumeMask = 0x0020
+kioVAtrbFilesOpenBit = 6
+kioVAtrbFilesOpenMask = 0x0040
+kioVAtrbHardwareLockedBit = 7
+kioVAtrbHardwareLockedMask = 0x0080
+kioVAtrbSoftwareLockedBit = 15
+kioVAtrbSoftwareLockedMask = 0x8000
+kioFlAttribLockedBit = 0
+kioFlAttribLockedMask = 0x01
+kioFlAttribResOpenBit = 2
+kioFlAttribResOpenMask = 0x04
+kioFlAttribDataOpenBit = 3
+kioFlAttribDataOpenMask = 0x08
+kioFlAttribDirBit = 4
+kioFlAttribDirMask = 0x10
+ioDirFlg = 4
+ioDirMask = 0x10
+kioFlAttribCopyProtBit = 6
+kioFlAttribCopyProtMask = 0x40
+kioFlAttribFileOpenBit = 7
+kioFlAttribFileOpenMask = 0x80
+kioFlAttribInSharedBit = 2
+kioFlAttribInSharedMask = 0x04
+kioFlAttribMountedBit = 3
+kioFlAttribMountedMask = 0x08
+kioFlAttribSharePointBit = 5
+kioFlAttribSharePointMask = 0x20
+kioFCBWriteBit = 8
+kioFCBWriteMask = 0x0100
+kioFCBResourceBit = 9
+kioFCBResourceMask = 0x0200
+kioFCBWriteLockedBit = 10
+kioFCBWriteLockedMask = 0x0400
+kioFCBLargeFileBit = 11
+kioFCBLargeFileMask = 0x0800
+kioFCBSharedWriteBit = 12
+kioFCBSharedWriteMask = 0x1000
+kioFCBFileLockedBit = 13
+kioFCBFileLockedMask = 0x2000
+kioFCBOwnClumpBit = 14
+kioFCBOwnClumpMask = 0x4000
+kioFCBModifiedBit = 15
+kioFCBModifiedMask = 0x8000
+kioACUserNoSeeFolderBit = 0
+kioACUserNoSeeFolderMask = 0x01
+kioACUserNoSeeFilesBit = 1
+kioACUserNoSeeFilesMask = 0x02
+kioACUserNoMakeChangesBit = 2
+kioACUserNoMakeChangesMask = 0x04
+kioACUserNotOwnerBit = 7
+kioACUserNotOwnerMask = 0x80
+kioACAccessOwnerBit = 31
+# kioACAccessOwnerMask = (long)0x80000000
+kioACAccessBlankAccessBit = 28
+kioACAccessBlankAccessMask = 0x10000000
+kioACAccessUserWriteBit = 26
+kioACAccessUserWriteMask = 0x04000000
+kioACAccessUserReadBit = 25
+kioACAccessUserReadMask = 0x02000000
+kioACAccessUserSearchBit = 24
+kioACAccessUserSearchMask = 0x01000000
+kioACAccessEveryoneWriteBit = 18
+kioACAccessEveryoneWriteMask = 0x00040000
+kioACAccessEveryoneReadBit = 17
+kioACAccessEveryoneReadMask = 0x00020000
+kioACAccessEveryoneSearchBit = 16
+kioACAccessEveryoneSearchMask = 0x00010000
+kioACAccessGroupWriteBit = 10
+kioACAccessGroupWriteMask = 0x00000400
+kioACAccessGroupReadBit = 9
+kioACAccessGroupReadMask = 0x00000200
+kioACAccessGroupSearchBit = 8
+kioACAccessGroupSearchMask = 0x00000100
+kioACAccessOwnerWriteBit = 2
+kioACAccessOwnerWriteMask = 0x00000004
+kioACAccessOwnerReadBit = 1
+kioACAccessOwnerReadMask = 0x00000002
+kioACAccessOwnerSearchBit = 0
+kioACAccessOwnerSearchMask = 0x00000001
+kfullPrivileges = 0x00070007
+kownerPrivileges = 0x00000007
+knoUser = 0
+kadministratorUser = 1
+knoGroup = 0
+AppleShareMediaType = FOUR_CHAR_CODE('afpm')
+volMountNoLoginMsgFlagBit = 0
+volMountNoLoginMsgFlagMask = 0x0001
+volMountExtendedFlagsBit = 7
+volMountExtendedFlagsMask = 0x0080
+volMountInteractBit = 15
+volMountInteractMask = 0x8000
+volMountChangedBit = 14
+volMountChangedMask = 0x4000
+volMountFSReservedMask = 0x00FF
+volMountSysReservedMask = 0xFF00
+kAFPExtendedFlagsAlternateAddressMask = 1
+kAFPTagTypeIP = 0x01
+kAFPTagTypeIPPort = 0x02
+kAFPTagTypeDDP = 0x03
+kAFPTagTypeDNS = 0x04
+kAFPTagLengthIP = 0x06
+kAFPTagLengthIPPort = 0x08
+kAFPTagLengthDDP = 0x06
+kFSInvalidVolumeRefNum = 0
+kFSCatInfoNone = 0x00000000
+kFSCatInfoTextEncoding = 0x00000001
+kFSCatInfoNodeFlags = 0x00000002
+kFSCatInfoVolume = 0x00000004
+kFSCatInfoParentDirID = 0x00000008
+kFSCatInfoNodeID = 0x00000010
+kFSCatInfoCreateDate = 0x00000020
+kFSCatInfoContentMod = 0x00000040
+kFSCatInfoAttrMod = 0x00000080
+kFSCatInfoAccessDate = 0x00000100
+kFSCatInfoBackupDate = 0x00000200
+kFSCatInfoPermissions = 0x00000400
+kFSCatInfoFinderInfo = 0x00000800
+kFSCatInfoFinderXInfo = 0x00001000
+kFSCatInfoValence = 0x00002000
+kFSCatInfoDataSizes = 0x00004000
+kFSCatInfoRsrcSizes = 0x00008000
+kFSCatInfoSharingFlags = 0x00010000
+kFSCatInfoUserPrivs = 0x00020000
+kFSCatInfoUserAccess = 0x00080000
+kFSCatInfoAllDates = 0x000003E0
+kFSCatInfoGettableInfo = 0x0003FFFF
+kFSCatInfoSettableInfo = 0x00001FE3
+# kFSCatInfoReserved = (long)0xFFFC0000
+kFSNodeLockedBit = 0
+kFSNodeLockedMask = 0x0001
+kFSNodeResOpenBit = 2
+kFSNodeResOpenMask = 0x0004
+kFSNodeDataOpenBit = 3
+kFSNodeDataOpenMask = 0x0008
+kFSNodeIsDirectoryBit = 4
+kFSNodeIsDirectoryMask = 0x0010
+kFSNodeCopyProtectBit = 6
+kFSNodeCopyProtectMask = 0x0040
+kFSNodeForkOpenBit = 7
+kFSNodeForkOpenMask = 0x0080
+kFSNodeInSharedBit = 2
+kFSNodeInSharedMask = 0x0004
+kFSNodeIsMountedBit = 3
+kFSNodeIsMountedMask = 0x0008
+kFSNodeIsSharePointBit = 5
+kFSNodeIsSharePointMask = 0x0020
+kFSIterateFlat = 0
+kFSIterateSubtree = 1
+kFSIterateDelete = 2
+# kFSIterateReserved = (long)0xFFFFFFFC
+fsSBNodeID = 0x00008000
+fsSBAttributeModDate = 0x00010000
+fsSBAccessDate = 0x00020000
+fsSBPermissions = 0x00040000
+fsSBNodeIDBit = 15
+fsSBAttributeModDateBit = 16
+fsSBAccessDateBit = 17
+fsSBPermissionsBit = 18
+kFSAllocDefaultFlags = 0x0000
+kFSAllocAllOrNothingMask = 0x0001
+kFSAllocContiguousMask = 0x0002
+kFSAllocNoRoundUpMask = 0x0004
+kFSAllocReservedMask = 0xFFF8
+kFSVolInfoNone = 0x0000
+kFSVolInfoCreateDate = 0x0001
+kFSVolInfoModDate = 0x0002
+kFSVolInfoBackupDate = 0x0004
+kFSVolInfoCheckedDate = 0x0008
+kFSVolInfoFileCount = 0x0010
+kFSVolInfoDirCount = 0x0020
+kFSVolInfoSizes = 0x0040
+kFSVolInfoBlocks = 0x0080
+kFSVolInfoNextAlloc = 0x0100
+kFSVolInfoRsrcClump = 0x0200
+kFSVolInfoDataClump = 0x0400
+kFSVolInfoNextID = 0x0800
+kFSVolInfoFinderInfo = 0x1000
+kFSVolInfoFlags = 0x2000
+kFSVolInfoFSInfo = 0x4000
+kFSVolInfoDriveInfo = 0x8000
+kFSVolInfoGettableInfo = 0xFFFF
+kFSVolInfoSettableInfo = 0x3004
+kFSVolFlagDefaultVolumeBit = 5
+kFSVolFlagDefaultVolumeMask = 0x0020
+kFSVolFlagFilesOpenBit = 6
+kFSVolFlagFilesOpenMask = 0x0040
+kFSVolFlagHardwareLockedBit = 7
+kFSVolFlagHardwareLockedMask = 0x0080
+kFSVolFlagSoftwareLockedBit = 15
+kFSVolFlagSoftwareLockedMask = 0x8000
+kFNDirectoryModifiedMessage = 1
+kFNNoImplicitAllSubscription = (1 << 0)
+rAliasType = FOUR_CHAR_CODE('alis')
+kARMMountVol = 0x00000001
+kARMNoUI = 0x00000002
+kARMMultVols = 0x00000008
+kARMSearch = 0x00000100
+kARMSearchMore = 0x00000200
+kARMSearchRelFirst = 0x00000400
+asiZoneName = -3
+asiServerName = -2
+asiVolumeName = -1
+asiAliasName = 0
+asiParentName = 1
+kResolveAliasFileNoUI = 0x00000001
+kClippingCreator = FOUR_CHAR_CODE('drag')
+kClippingPictureType = FOUR_CHAR_CODE('clpp')
+kClippingTextType = FOUR_CHAR_CODE('clpt')
+kClippingSoundType = FOUR_CHAR_CODE('clps')
+kClippingUnknownType = FOUR_CHAR_CODE('clpu')
+kInternetLocationCreator = FOUR_CHAR_CODE('drag')
+kInternetLocationHTTP = FOUR_CHAR_CODE('ilht')
+kInternetLocationFTP = FOUR_CHAR_CODE('ilft')
+kInternetLocationFile = FOUR_CHAR_CODE('ilfi')
+kInternetLocationMail = FOUR_CHAR_CODE('ilma')
+kInternetLocationNNTP = FOUR_CHAR_CODE('ilnw')
+kInternetLocationAFP = FOUR_CHAR_CODE('ilaf')
+kInternetLocationAppleTalk = FOUR_CHAR_CODE('ilat')
+kInternetLocationNSL = FOUR_CHAR_CODE('ilns')
+kInternetLocationGeneric = FOUR_CHAR_CODE('ilge')
+kCustomIconResource = -16455
+kCustomBadgeResourceType = FOUR_CHAR_CODE('badg')
+kCustomBadgeResourceID = kCustomIconResource
+kCustomBadgeResourceVersion = 0
+# kSystemFolderType = 'macs'.
+kRoutingResourceType = FOUR_CHAR_CODE('rout')
+kRoutingResourceID = 0
+kContainerFolderAliasType = FOUR_CHAR_CODE('fdrp')
+kContainerTrashAliasType = FOUR_CHAR_CODE('trsh')
+kContainerHardDiskAliasType = FOUR_CHAR_CODE('hdsk')
+kContainerFloppyAliasType = FOUR_CHAR_CODE('flpy')
+kContainerServerAliasType = FOUR_CHAR_CODE('srvr')
+kApplicationAliasType = FOUR_CHAR_CODE('adrp')
+kContainerAliasType = FOUR_CHAR_CODE('drop')
+kDesktopPrinterAliasType = FOUR_CHAR_CODE('dtpa')
+kContainerCDROMAliasType = FOUR_CHAR_CODE('cddr')
+kApplicationCPAliasType = FOUR_CHAR_CODE('acdp')
+kApplicationDAAliasType = FOUR_CHAR_CODE('addp')
+kPackageAliasType = FOUR_CHAR_CODE('fpka')
+kAppPackageAliasType = FOUR_CHAR_CODE('fapa')
+kSystemFolderAliasType = FOUR_CHAR_CODE('fasy')
+kAppleMenuFolderAliasType = FOUR_CHAR_CODE('faam')
+kStartupFolderAliasType = FOUR_CHAR_CODE('fast')
+kPrintMonitorDocsFolderAliasType = FOUR_CHAR_CODE('fapn')
+kPreferencesFolderAliasType = FOUR_CHAR_CODE('fapf')
+kControlPanelFolderAliasType = FOUR_CHAR_CODE('fact')
+kExtensionFolderAliasType = FOUR_CHAR_CODE('faex')
+kExportedFolderAliasType = FOUR_CHAR_CODE('faet')
+kDropFolderAliasType = FOUR_CHAR_CODE('fadr')
+kSharedFolderAliasType = FOUR_CHAR_CODE('fash')
+kMountedFolderAliasType = FOUR_CHAR_CODE('famn')
+kIsOnDesk = 0x0001
+kColor = 0x000E
+kIsShared = 0x0040
+kHasNoINITs = 0x0080
+kHasBeenInited = 0x0100
+kHasCustomIcon = 0x0400
+kIsStationery = 0x0800
+kNameLocked = 0x1000
+kHasBundle = 0x2000
+kIsInvisible = 0x4000
+kIsAlias = 0x8000
+fOnDesk = kIsOnDesk
+fHasBundle = kHasBundle
+fInvisible = kIsInvisible
+fTrash = -3
+fDesktop = -2
+fDisk = 0
+kIsStationary = kIsStationery
+kExtendedFlagsAreInvalid = 0x8000
+kExtendedFlagHasCustomBadge = 0x0100
+kExtendedFlagHasRoutingInfo = 0x0004
+kFirstMagicBusyFiletype = FOUR_CHAR_CODE('bzy ')
+kLastMagicBusyFiletype = FOUR_CHAR_CODE('bzy?')
+kMagicBusyCreationDate = 0x4F3AFDB0

Added: vendor/Python/current/Lib/plat-mac/Carbon/Fm.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/Fm.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/Fm.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1 @@
+from _Fm import *

Added: vendor/Python/current/Lib/plat-mac/Carbon/Folder.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/Folder.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/Folder.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1 @@
+from _Folder import *

Added: vendor/Python/current/Lib/plat-mac/Carbon/Folders.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/Folders.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/Folders.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,190 @@
+# Generated from 'Folders.h'
+
+def FOUR_CHAR_CODE(x): return x
+true = True
+false = False
+kOnSystemDisk = -32768L
+kOnAppropriateDisk = -32767
+kSystemDomain = -32766
+kLocalDomain = -32765
+kNetworkDomain = -32764
+kUserDomain = -32763
+kClassicDomain = -32762
+kCreateFolder = true
+kDontCreateFolder = false
+kSystemFolderType = FOUR_CHAR_CODE('macs')
+kDesktopFolderType = FOUR_CHAR_CODE('desk')
+kSystemDesktopFolderType = FOUR_CHAR_CODE('sdsk')
+kTrashFolderType = FOUR_CHAR_CODE('trsh')
+kSystemTrashFolderType = FOUR_CHAR_CODE('strs')
+kWhereToEmptyTrashFolderType = FOUR_CHAR_CODE('empt')
+kPrintMonitorDocsFolderType = FOUR_CHAR_CODE('prnt')
+kStartupFolderType = FOUR_CHAR_CODE('strt')
+kShutdownFolderType = FOUR_CHAR_CODE('shdf')
+kAppleMenuFolderType = FOUR_CHAR_CODE('amnu')
+kControlPanelFolderType = FOUR_CHAR_CODE('ctrl')
+kSystemControlPanelFolderType = FOUR_CHAR_CODE('sctl')
+kExtensionFolderType = FOUR_CHAR_CODE('extn')
+kFontsFolderType = FOUR_CHAR_CODE('font')
+kPreferencesFolderType = FOUR_CHAR_CODE('pref')
+kSystemPreferencesFolderType = FOUR_CHAR_CODE('sprf')
+kTemporaryFolderType = FOUR_CHAR_CODE('temp')
+kExtensionDisabledFolderType = FOUR_CHAR_CODE('extD')
+kControlPanelDisabledFolderType = FOUR_CHAR_CODE('ctrD')
+kSystemExtensionDisabledFolderType = FOUR_CHAR_CODE('macD')
+kStartupItemsDisabledFolderType = FOUR_CHAR_CODE('strD')
+kShutdownItemsDisabledFolderType = FOUR_CHAR_CODE('shdD')
+kApplicationsFolderType = FOUR_CHAR_CODE('apps')
+kDocumentsFolderType = FOUR_CHAR_CODE('docs')
+kVolumeRootFolderType = FOUR_CHAR_CODE('root')
+kChewableItemsFolderType = FOUR_CHAR_CODE('flnt')
+kApplicationSupportFolderType = FOUR_CHAR_CODE('asup')
+kTextEncodingsFolderType = FOUR_CHAR_CODE('\xc4tex')
+kStationeryFolderType = FOUR_CHAR_CODE('odst')
+kOpenDocFolderType = FOUR_CHAR_CODE('odod')
+kOpenDocShellPlugInsFolderType = FOUR_CHAR_CODE('odsp')
+kEditorsFolderType = FOUR_CHAR_CODE('oded')
+kOpenDocEditorsFolderType = FOUR_CHAR_CODE('\xc4odf')
+kOpenDocLibrariesFolderType = FOUR_CHAR_CODE('odlb')
+kGenEditorsFolderType = FOUR_CHAR_CODE('\xc4edi')
+kHelpFolderType = FOUR_CHAR_CODE('\xc4hlp')
+kInternetPlugInFolderType = FOUR_CHAR_CODE('\xc4net')
+kModemScriptsFolderType = FOUR_CHAR_CODE('\xc4mod')
+kPrinterDescriptionFolderType = FOUR_CHAR_CODE('ppdf')
+kPrinterDriverFolderType = FOUR_CHAR_CODE('\xc4prd')
+kScriptingAdditionsFolderType = FOUR_CHAR_CODE('\xc4scr')
+kSharedLibrariesFolderType = FOUR_CHAR_CODE('\xc4lib')
+kVoicesFolderType = FOUR_CHAR_CODE('fvoc')
+kControlStripModulesFolderType = FOUR_CHAR_CODE('sdev')
+kAssistantsFolderType = FOUR_CHAR_CODE('ast\xc4')
+kUtilitiesFolderType = FOUR_CHAR_CODE('uti\xc4')
+kAppleExtrasFolderType = FOUR_CHAR_CODE('aex\xc4')
+kContextualMenuItemsFolderType = FOUR_CHAR_CODE('cmnu')
+kMacOSReadMesFolderType = FOUR_CHAR_CODE('mor\xc4')
+kALMModulesFolderType = FOUR_CHAR_CODE('walk')
+kALMPreferencesFolderType = FOUR_CHAR_CODE('trip')
+kALMLocationsFolderType = FOUR_CHAR_CODE('fall')
+kColorSyncProfilesFolderType = FOUR_CHAR_CODE('prof')
+kThemesFolderType = FOUR_CHAR_CODE('thme')
+kFavoritesFolderType = FOUR_CHAR_CODE('favs')
+kInternetFolderType = FOUR_CHAR_CODE('int\xc4')
+kAppearanceFolderType = FOUR_CHAR_CODE('appr')
+kSoundSetsFolderType = FOUR_CHAR_CODE('snds')
+kDesktopPicturesFolderType = FOUR_CHAR_CODE('dtp\xc4')
+kInternetSearchSitesFolderType = FOUR_CHAR_CODE('issf')
+kFindSupportFolderType = FOUR_CHAR_CODE('fnds')
+kFindByContentFolderType = FOUR_CHAR_CODE('fbcf')
+kInstallerLogsFolderType = FOUR_CHAR_CODE('ilgf')
+kScriptsFolderType = FOUR_CHAR_CODE('scr\xc4')
+kFolderActionsFolderType = FOUR_CHAR_CODE('fasf')
+kLauncherItemsFolderType = FOUR_CHAR_CODE('laun')
+kRecentApplicationsFolderType = FOUR_CHAR_CODE('rapp')
+kRecentDocumentsFolderType = FOUR_CHAR_CODE('rdoc')
+kRecentServersFolderType = FOUR_CHAR_CODE('rsvr')
+kSpeakableItemsFolderType = FOUR_CHAR_CODE('spki')
+kKeychainFolderType = FOUR_CHAR_CODE('kchn')
+kQuickTimeExtensionsFolderType = FOUR_CHAR_CODE('qtex')
+kDisplayExtensionsFolderType = FOUR_CHAR_CODE('dspl')
+kMultiprocessingFolderType = FOUR_CHAR_CODE('mpxf')
+kPrintingPlugInsFolderType = FOUR_CHAR_CODE('pplg')
+kDomainTopLevelFolderType = FOUR_CHAR_CODE('dtop')
+kDomainLibraryFolderType = FOUR_CHAR_CODE('dlib')
+kColorSyncFolderType = FOUR_CHAR_CODE('sync')
+kColorSyncCMMFolderType = FOUR_CHAR_CODE('ccmm')
+kColorSyncScriptingFolderType = FOUR_CHAR_CODE('cscr')
+kPrintersFolderType = FOUR_CHAR_CODE('impr')
+kSpeechFolderType = FOUR_CHAR_CODE('spch')
+kCarbonLibraryFolderType = FOUR_CHAR_CODE('carb')
+kDocumentationFolderType = FOUR_CHAR_CODE('info')
+kDeveloperDocsFolderType = FOUR_CHAR_CODE('ddoc')
+kDeveloperHelpFolderType = FOUR_CHAR_CODE('devh')
+kISSDownloadsFolderType = FOUR_CHAR_CODE('issd')
+kUserSpecificTmpFolderType = FOUR_CHAR_CODE('utmp')
+kCachedDataFolderType = FOUR_CHAR_CODE('cach')
+kFrameworksFolderType = FOUR_CHAR_CODE('fram')
+kPrivateFrameworksFolderType = FOUR_CHAR_CODE('pfrm')
+kClassicDesktopFolderType = FOUR_CHAR_CODE('sdsk')
+kDeveloperFolderType = FOUR_CHAR_CODE('devf')
+kSystemSoundsFolderType = FOUR_CHAR_CODE('ssnd')
+kComponentsFolderType = FOUR_CHAR_CODE('cmpd')
+kQuickTimeComponentsFolderType = FOUR_CHAR_CODE('wcmp')
+kCoreServicesFolderType = FOUR_CHAR_CODE('csrv')
+kPictureDocumentsFolderType = FOUR_CHAR_CODE('pdoc')
+kMovieDocumentsFolderType = FOUR_CHAR_CODE('mdoc')
+kMusicDocumentsFolderType = FOUR_CHAR_CODE('\xb5doc')
+kInternetSitesFolderType = FOUR_CHAR_CODE('site')
+kPublicFolderType = FOUR_CHAR_CODE('pubb')
+kAudioSupportFolderType = FOUR_CHAR_CODE('adio')
+kAudioSoundsFolderType = FOUR_CHAR_CODE('asnd')
+kAudioSoundBanksFolderType = FOUR_CHAR_CODE('bank')
+kAudioAlertSoundsFolderType = FOUR_CHAR_CODE('alrt')
+kAudioPlugInsFolderType = FOUR_CHAR_CODE('aplg')
+kAudioComponentsFolderType = FOUR_CHAR_CODE('acmp')
+kKernelExtensionsFolderType = FOUR_CHAR_CODE('kext')
+kDirectoryServicesFolderType = FOUR_CHAR_CODE('dsrv')
+kDirectoryServicesPlugInsFolderType = FOUR_CHAR_CODE('dplg')
+kInstallerReceiptsFolderType = FOUR_CHAR_CODE('rcpt')
+kFileSystemSupportFolderType = FOUR_CHAR_CODE('fsys')
+kAppleShareSupportFolderType = FOUR_CHAR_CODE('shar')
+kAppleShareAuthenticationFolderType = FOUR_CHAR_CODE('auth')
+kMIDIDriversFolderType = FOUR_CHAR_CODE('midi')
+kLocalesFolderType = FOUR_CHAR_CODE('\xc4loc')
+kFindByContentPluginsFolderType = FOUR_CHAR_CODE('fbcp')
+kUsersFolderType = FOUR_CHAR_CODE('usrs')
+kCurrentUserFolderType = FOUR_CHAR_CODE('cusr')
+kCurrentUserRemoteFolderLocation = FOUR_CHAR_CODE('rusf')
+kCurrentUserRemoteFolderType = FOUR_CHAR_CODE('rusr')
+kSharedUserDataFolderType = FOUR_CHAR_CODE('sdat')
+kVolumeSettingsFolderType = FOUR_CHAR_CODE('vsfd')
+kAppleshareAutomountServerAliasesFolderType = FOUR_CHAR_CODE('srv\xc4')
+kPreMacOS91ApplicationsFolderType = FOUR_CHAR_CODE('\x8cpps')
+kPreMacOS91InstallerLogsFolderType = FOUR_CHAR_CODE('\x94lgf')
+kPreMacOS91AssistantsFolderType = FOUR_CHAR_CODE('\x8cst\xc4')
+kPreMacOS91UtilitiesFolderType = FOUR_CHAR_CODE('\x9fti\xc4')
+kPreMacOS91AppleExtrasFolderType = FOUR_CHAR_CODE('\x8cex\xc4')
+kPreMacOS91MacOSReadMesFolderType = FOUR_CHAR_CODE('\xb5or\xc4')
+kPreMacOS91InternetFolderType = FOUR_CHAR_CODE('\x94nt\xc4')
+kPreMacOS91AutomountedServersFolderType = FOUR_CHAR_CODE('\xa7rv\xc4')
+kPreMacOS91StationeryFolderType = FOUR_CHAR_CODE('\xbfdst')
+kCreateFolderAtBoot = 0x00000002
+kCreateFolderAtBootBit = 1
+kFolderCreatedInvisible = 0x00000004
+kFolderCreatedInvisibleBit = 2
+kFolderCreatedNameLocked = 0x00000008
+kFolderCreatedNameLockedBit = 3
+kFolderCreatedAdminPrivs = 0x00000010
+kFolderCreatedAdminPrivsBit = 4
+kFolderInUserFolder = 0x00000020
+kFolderInUserFolderBit = 5
+kFolderTrackedByAlias = 0x00000040
+kFolderTrackedByAliasBit = 6
+kFolderInRemoteUserFolderIfAvailable = 0x00000080
+kFolderInRemoteUserFolderIfAvailableBit = 7
+kFolderNeverMatchedInIdentifyFolder = 0x00000100
+kFolderNeverMatchedInIdentifyFolderBit = 8
+kFolderMustStayOnSameVolume = 0x00000200
+kFolderMustStayOnSameVolumeBit = 9
+kFolderManagerFolderInMacOS9FolderIfMacOSXIsInstalledMask = 0x00000400
+kFolderManagerFolderInMacOS9FolderIfMacOSXIsInstalledBit = 10
+kFolderInLocalOrRemoteUserFolder = kFolderInUserFolder | kFolderInRemoteUserFolderIfAvailable
+kRelativeFolder = FOUR_CHAR_CODE('relf')
+kSpecialFolder = FOUR_CHAR_CODE('spcf')
+kBlessedFolder = FOUR_CHAR_CODE('blsf')
+kRootFolder = FOUR_CHAR_CODE('rotf')
+kCurrentUserFolderLocation = FOUR_CHAR_CODE('cusf')
+kFindFolderRedirectionFlagUseDistinctUserFoldersBit = 0
+kFindFolderRedirectionFlagUseGivenVRefAndDirIDAsUserFolderBit = 1
+kFindFolderRedirectionFlagsUseGivenVRefNumAndDirIDAsRemoteUserFolderBit = 2
+kFolderManagerUserRedirectionGlobalsCurrentVersion = 1
+kFindFolderExtendedFlagsDoNotFollowAliasesBit = 0
+kFindFolderExtendedFlagsDoNotUseUserFolderBit = 1
+kFindFolderExtendedFlagsUseOtherUserRecord = 0x01000000
+kFolderManagerNotificationMessageUserLogIn = FOUR_CHAR_CODE('log+')
+kFolderManagerNotificationMessagePreUserLogIn = FOUR_CHAR_CODE('logj')
+kFolderManagerNotificationMessageUserLogOut = FOUR_CHAR_CODE('log-')
+kFolderManagerNotificationMessagePostUserLogOut = FOUR_CHAR_CODE('logp')
+kFolderManagerNotificationDiscardCachedData = FOUR_CHAR_CODE('dche')
+kFolderManagerNotificationMessageLoginStartup = FOUR_CHAR_CODE('stup')
+kDoNotRemoveWhenCurrentApplicationQuitsBit = 0
+kDoNotRemoveWheCurrentApplicationQuitsBit = kDoNotRemoveWhenCurrentApplicationQuitsBit
+kStopIfAnyNotificationProcReturnsErrorBit = 31

Added: vendor/Python/current/Lib/plat-mac/Carbon/Fonts.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/Fonts.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/Fonts.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,59 @@
+# Generated from 'Fonts.h'
+
+def FOUR_CHAR_CODE(x): return x
+kNilOptions = 0
+systemFont = 0
+applFont = 1
+kFMDefaultOptions = kNilOptions
+kFMDefaultActivationContext = kFMDefaultOptions
+kFMGlobalActivationContext = 0x00000001
+kFMLocalActivationContext = kFMDefaultActivationContext
+kFMDefaultIterationScope = kFMDefaultOptions
+kFMGlobalIterationScope = 0x00000001
+kFMLocalIterationScope = kFMDefaultIterationScope
+kPlatformDefaultGuiFontID = applFont
+kPlatformDefaultGuiFontID = -1
+commandMark = 17
+checkMark = 18
+diamondMark = 19
+appleMark = 20
+propFont = 36864L
+prpFntH = 36865L
+prpFntW = 36866L
+prpFntHW = 36867L
+fixedFont = 45056L
+fxdFntH = 45057L
+fxdFntW = 45058L
+fxdFntHW = 45059L
+fontWid = 44208L
+kFMUseGlobalScopeOption = 0x00000001
+kFontIDNewYork = 2
+kFontIDGeneva = 3
+kFontIDMonaco = 4
+kFontIDVenice = 5
+kFontIDLondon = 6
+kFontIDAthens = 7
+kFontIDSanFrancisco = 8
+kFontIDToronto = 9
+kFontIDCairo = 11
+kFontIDLosAngeles = 12
+kFontIDTimes = 20
+kFontIDHelvetica = 21
+kFontIDCourier = 22
+kFontIDSymbol = 23
+kFontIDMobile = 24
+newYork = kFontIDNewYork
+geneva = kFontIDGeneva
+monaco = kFontIDMonaco
+venice = kFontIDVenice
+london = kFontIDLondon
+athens = kFontIDAthens
+sanFran = kFontIDSanFrancisco
+toronto = kFontIDToronto
+cairo = kFontIDCairo
+losAngeles = kFontIDLosAngeles
+times = kFontIDTimes
+helvetica = kFontIDHelvetica
+courier = kFontIDCourier
+symbol = kFontIDSymbol
+mobile = kFontIDMobile

Added: vendor/Python/current/Lib/plat-mac/Carbon/Help.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/Help.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/Help.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1 @@
+from _Help import *

Added: vendor/Python/current/Lib/plat-mac/Carbon/IBCarbon.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/IBCarbon.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/IBCarbon.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1 @@
+from _IBCarbon import *

Added: vendor/Python/current/Lib/plat-mac/Carbon/IBCarbonRuntime.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/IBCarbonRuntime.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/IBCarbonRuntime.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,5 @@
+# Generated from 'IBCarbonRuntime.h'
+
+kIBCarbonRuntimeCantFindNibFile = -10960
+kIBCarbonRuntimeObjectNotOfRequestedType = -10961
+kIBCarbonRuntimeCantFindObject = -10962

Added: vendor/Python/current/Lib/plat-mac/Carbon/Icn.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/Icn.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/Icn.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1 @@
+from _Icn import *

Added: vendor/Python/current/Lib/plat-mac/Carbon/Icons.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/Icons.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/Icons.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,381 @@
+# Generated from 'Icons.h'
+
+def FOUR_CHAR_CODE(x): return x
+from Carbon.Files import *
+kGenericDocumentIconResource = -4000
+kGenericStationeryIconResource = -3985
+kGenericEditionFileIconResource = -3989
+kGenericApplicationIconResource = -3996
+kGenericDeskAccessoryIconResource = -3991
+kGenericFolderIconResource = -3999
+kPrivateFolderIconResource = -3994
+kFloppyIconResource = -3998
+kTrashIconResource = -3993
+kGenericRAMDiskIconResource = -3988
+kGenericCDROMIconResource = -3987
+kDesktopIconResource = -3992
+kOpenFolderIconResource = -3997
+kGenericHardDiskIconResource = -3995
+kGenericFileServerIconResource = -3972
+kGenericSuitcaseIconResource = -3970
+kGenericMoverObjectIconResource = -3969
+kGenericPreferencesIconResource = -3971
+kGenericQueryDocumentIconResource = -16506
+kGenericExtensionIconResource = -16415
+kSystemFolderIconResource = -3983
+kHelpIconResource = -20271
+kAppleMenuFolderIconResource = -3982
+genericDocumentIconResource = kGenericDocumentIconResource
+genericStationeryIconResource = kGenericStationeryIconResource
+genericEditionFileIconResource = kGenericEditionFileIconResource
+genericApplicationIconResource = kGenericApplicationIconResource
+genericDeskAccessoryIconResource = kGenericDeskAccessoryIconResource
+genericFolderIconResource = kGenericFolderIconResource
+privateFolderIconResource = kPrivateFolderIconResource
+floppyIconResource = kFloppyIconResource
+trashIconResource = kTrashIconResource
+genericRAMDiskIconResource = kGenericRAMDiskIconResource
+genericCDROMIconResource = kGenericCDROMIconResource
+desktopIconResource = kDesktopIconResource
+openFolderIconResource = kOpenFolderIconResource
+genericHardDiskIconResource = kGenericHardDiskIconResource
+genericFileServerIconResource = kGenericFileServerIconResource
+genericSuitcaseIconResource = kGenericSuitcaseIconResource
+genericMoverObjectIconResource = kGenericMoverObjectIconResource
+genericPreferencesIconResource = kGenericPreferencesIconResource
+genericQueryDocumentIconResource = kGenericQueryDocumentIconResource
+genericExtensionIconResource = kGenericExtensionIconResource
+systemFolderIconResource = kSystemFolderIconResource
+appleMenuFolderIconResource = kAppleMenuFolderIconResource
+kStartupFolderIconResource = -3981
+kOwnedFolderIconResource = -3980
+kDropFolderIconResource = -3979
+kSharedFolderIconResource = -3978
+kMountedFolderIconResource = -3977
+kControlPanelFolderIconResource = -3976
+kPrintMonitorFolderIconResource = -3975
+kPreferencesFolderIconResource = -3974
+kExtensionsFolderIconResource = -3973
+kFontsFolderIconResource = -3968
+kFullTrashIconResource = -3984
+startupFolderIconResource = kStartupFolderIconResource
+ownedFolderIconResource = kOwnedFolderIconResource
+dropFolderIconResource = kDropFolderIconResource
+sharedFolderIconResource = kSharedFolderIconResource
+mountedFolderIconResource = kMountedFolderIconResource
+controlPanelFolderIconResource = kControlPanelFolderIconResource
+printMonitorFolderIconResource = kPrintMonitorFolderIconResource
+preferencesFolderIconResource = kPreferencesFolderIconResource
+extensionsFolderIconResource = kExtensionsFolderIconResource
+fontsFolderIconResource = kFontsFolderIconResource
+fullTrashIconResource = kFullTrashIconResource
+kThumbnail32BitData = FOUR_CHAR_CODE('it32')
+kThumbnail8BitMask = FOUR_CHAR_CODE('t8mk')
+kHuge1BitMask = FOUR_CHAR_CODE('ich#')
+kHuge4BitData = FOUR_CHAR_CODE('ich4')
+kHuge8BitData = FOUR_CHAR_CODE('ich8')
+kHuge32BitData = FOUR_CHAR_CODE('ih32')
+kHuge8BitMask = FOUR_CHAR_CODE('h8mk')
+kLarge1BitMask = FOUR_CHAR_CODE('ICN#')
+kLarge4BitData = FOUR_CHAR_CODE('icl4')
+kLarge8BitData = FOUR_CHAR_CODE('icl8')
+kLarge32BitData = FOUR_CHAR_CODE('il32')
+kLarge8BitMask = FOUR_CHAR_CODE('l8mk')
+kSmall1BitMask = FOUR_CHAR_CODE('ics#')
+kSmall4BitData = FOUR_CHAR_CODE('ics4')
+kSmall8BitData = FOUR_CHAR_CODE('ics8')
+kSmall32BitData = FOUR_CHAR_CODE('is32')
+kSmall8BitMask = FOUR_CHAR_CODE('s8mk')
+kMini1BitMask = FOUR_CHAR_CODE('icm#')
+kMini4BitData = FOUR_CHAR_CODE('icm4')
+kMini8BitData = FOUR_CHAR_CODE('icm8')
+kTileIconVariant = FOUR_CHAR_CODE('tile')
+kRolloverIconVariant = FOUR_CHAR_CODE('over')
+kDropIconVariant = FOUR_CHAR_CODE('drop')
+kOpenIconVariant = FOUR_CHAR_CODE('open')
+kOpenDropIconVariant = FOUR_CHAR_CODE('odrp')
+large1BitMask = kLarge1BitMask
+large4BitData = kLarge4BitData
+large8BitData = kLarge8BitData
+small1BitMask = kSmall1BitMask
+small4BitData = kSmall4BitData
+small8BitData = kSmall8BitData
+mini1BitMask = kMini1BitMask
+mini4BitData = kMini4BitData
+mini8BitData = kMini8BitData
+kAlignNone = 0x00
+kAlignVerticalCenter = 0x01
+kAlignTop = 0x02
+kAlignBottom = 0x03
+kAlignHorizontalCenter = 0x04
+kAlignAbsoluteCenter = kAlignVerticalCenter | kAlignHorizontalCenter
+kAlignCenterTop = kAlignTop | kAlignHorizontalCenter
+kAlignCenterBottom = kAlignBottom | kAlignHorizontalCenter
+kAlignLeft = 0x08
+kAlignCenterLeft = kAlignVerticalCenter | kAlignLeft
+kAlignTopLeft = kAlignTop | kAlignLeft
+kAlignBottomLeft = kAlignBottom | kAlignLeft
+kAlignRight = 0x0C
+kAlignCenterRight = kAlignVerticalCenter | kAlignRight
+kAlignTopRight = kAlignTop | kAlignRight
+kAlignBottomRight = kAlignBottom | kAlignRight
+atNone = kAlignNone
+atVerticalCenter = kAlignVerticalCenter
+atTop = kAlignTop
+atBottom = kAlignBottom
+atHorizontalCenter = kAlignHorizontalCenter
+atAbsoluteCenter = kAlignAbsoluteCenter
+atCenterTop = kAlignCenterTop
+atCenterBottom = kAlignCenterBottom
+atLeft = kAlignLeft
+atCenterLeft = kAlignCenterLeft
+atTopLeft = kAlignTopLeft
+atBottomLeft = kAlignBottomLeft
+atRight = kAlignRight
+atCenterRight = kAlignCenterRight
+atTopRight = kAlignTopRight
+atBottomRight = kAlignBottomRight
+kTransformNone = 0x00
+kTransformDisabled = 0x01
+kTransformOffline = 0x02
+kTransformOpen = 0x03
+kTransformLabel1 = 0x0100
+kTransformLabel2 = 0x0200
+kTransformLabel3 = 0x0300
+kTransformLabel4 = 0x0400
+kTransformLabel5 = 0x0500
+kTransformLabel6 = 0x0600
+kTransformLabel7 = 0x0700
+kTransformSelected = 0x4000
+kTransformSelectedDisabled = kTransformSelected | kTransformDisabled
+kTransformSelectedOffline = kTransformSelected | kTransformOffline
+kTransformSelectedOpen = kTransformSelected | kTransformOpen
+ttNone = kTransformNone
+ttDisabled = kTransformDisabled
+ttOffline = kTransformOffline
+ttOpen = kTransformOpen
+ttLabel1 = kTransformLabel1
+ttLabel2 = kTransformLabel2
+ttLabel3 = kTransformLabel3
+ttLabel4 = kTransformLabel4
+ttLabel5 = kTransformLabel5
+ttLabel6 = kTransformLabel6
+ttLabel7 = kTransformLabel7
+ttSelected = kTransformSelected
+ttSelectedDisabled = kTransformSelectedDisabled
+ttSelectedOffline = kTransformSelectedOffline
+ttSelectedOpen = kTransformSelectedOpen
+kSelectorLarge1Bit = 0x00000001
+kSelectorLarge4Bit = 0x00000002
+kSelectorLarge8Bit = 0x00000004
+kSelectorLarge32Bit = 0x00000008
+kSelectorLarge8BitMask = 0x00000010
+kSelectorSmall1Bit = 0x00000100
+kSelectorSmall4Bit = 0x00000200
+kSelectorSmall8Bit = 0x00000400
+kSelectorSmall32Bit = 0x00000800
+kSelectorSmall8BitMask = 0x00001000
+kSelectorMini1Bit = 0x00010000
+kSelectorMini4Bit = 0x00020000
+kSelectorMini8Bit = 0x00040000
+kSelectorHuge1Bit = 0x01000000
+kSelectorHuge4Bit = 0x02000000
+kSelectorHuge8Bit = 0x04000000
+kSelectorHuge32Bit = 0x08000000
+kSelectorHuge8BitMask = 0x10000000
+kSelectorAllLargeData = 0x000000FF
+kSelectorAllSmallData = 0x0000FF00
+kSelectorAllMiniData = 0x00FF0000
+# kSelectorAllHugeData = (long)0xFF000000
+kSelectorAll1BitData = kSelectorLarge1Bit | kSelectorSmall1Bit | kSelectorMini1Bit | kSelectorHuge1Bit
+kSelectorAll4BitData = kSelectorLarge4Bit | kSelectorSmall4Bit | kSelectorMini4Bit | kSelectorHuge4Bit
+kSelectorAll8BitData = kSelectorLarge8Bit | kSelectorSmall8Bit | kSelectorMini8Bit | kSelectorHuge8Bit
+kSelectorAll32BitData = kSelectorLarge32Bit | kSelectorSmall32Bit | kSelectorHuge32Bit
+# kSelectorAllAvailableData = (long)0xFFFFFFFF
+svLarge1Bit = kSelectorLarge1Bit
+svLarge4Bit = kSelectorLarge4Bit
+svLarge8Bit = kSelectorLarge8Bit
+svSmall1Bit = kSelectorSmall1Bit
+svSmall4Bit = kSelectorSmall4Bit
+svSmall8Bit = kSelectorSmall8Bit
+svMini1Bit = kSelectorMini1Bit
+svMini4Bit = kSelectorMini4Bit
+svMini8Bit = kSelectorMini8Bit
+svAllLargeData = kSelectorAllLargeData
+svAllSmallData = kSelectorAllSmallData
+svAllMiniData = kSelectorAllMiniData
+svAll1BitData = kSelectorAll1BitData
+svAll4BitData = kSelectorAll4BitData
+svAll8BitData = kSelectorAll8BitData
+# svAllAvailableData = kSelectorAllAvailableData
+kSystemIconsCreator = FOUR_CHAR_CODE('macs')
+# err = GetIconRef(kOnSystemDisk
+kClipboardIcon = FOUR_CHAR_CODE('CLIP')
+kClippingUnknownTypeIcon = FOUR_CHAR_CODE('clpu')
+kClippingPictureTypeIcon = FOUR_CHAR_CODE('clpp')
+kClippingTextTypeIcon = FOUR_CHAR_CODE('clpt')
+kClippingSoundTypeIcon = FOUR_CHAR_CODE('clps')
+kDesktopIcon = FOUR_CHAR_CODE('desk')
+kFinderIcon = FOUR_CHAR_CODE('FNDR')
+kFontSuitcaseIcon = FOUR_CHAR_CODE('FFIL')
+kFullTrashIcon = FOUR_CHAR_CODE('ftrh')
+kGenericApplicationIcon = FOUR_CHAR_CODE('APPL')
+kGenericCDROMIcon = FOUR_CHAR_CODE('cddr')
+kGenericControlPanelIcon = FOUR_CHAR_CODE('APPC')
+kGenericControlStripModuleIcon = FOUR_CHAR_CODE('sdev')
+kGenericComponentIcon = FOUR_CHAR_CODE('thng')
+kGenericDeskAccessoryIcon = FOUR_CHAR_CODE('APPD')
+kGenericDocumentIcon = FOUR_CHAR_CODE('docu')
+kGenericEditionFileIcon = FOUR_CHAR_CODE('edtf')
+kGenericExtensionIcon = FOUR_CHAR_CODE('INIT')
+kGenericFileServerIcon = FOUR_CHAR_CODE('srvr')
+kGenericFontIcon = FOUR_CHAR_CODE('ffil')
+kGenericFontScalerIcon = FOUR_CHAR_CODE('sclr')
+kGenericFloppyIcon = FOUR_CHAR_CODE('flpy')
+kGenericHardDiskIcon = FOUR_CHAR_CODE('hdsk')
+kGenericIDiskIcon = FOUR_CHAR_CODE('idsk')
+kGenericRemovableMediaIcon = FOUR_CHAR_CODE('rmov')
+kGenericMoverObjectIcon = FOUR_CHAR_CODE('movr')
+kGenericPCCardIcon = FOUR_CHAR_CODE('pcmc')
+kGenericPreferencesIcon = FOUR_CHAR_CODE('pref')
+kGenericQueryDocumentIcon = FOUR_CHAR_CODE('qery')
+kGenericRAMDiskIcon = FOUR_CHAR_CODE('ramd')
+kGenericSharedLibaryIcon = FOUR_CHAR_CODE('shlb')
+kGenericStationeryIcon = FOUR_CHAR_CODE('sdoc')
+kGenericSuitcaseIcon = FOUR_CHAR_CODE('suit')
+kGenericURLIcon = FOUR_CHAR_CODE('gurl')
+kGenericWORMIcon = FOUR_CHAR_CODE('worm')
+kInternationalResourcesIcon = FOUR_CHAR_CODE('ifil')
+kKeyboardLayoutIcon = FOUR_CHAR_CODE('kfil')
+kSoundFileIcon = FOUR_CHAR_CODE('sfil')
+kSystemSuitcaseIcon = FOUR_CHAR_CODE('zsys')
+kTrashIcon = FOUR_CHAR_CODE('trsh')
+kTrueTypeFontIcon = FOUR_CHAR_CODE('tfil')
+kTrueTypeFlatFontIcon = FOUR_CHAR_CODE('sfnt')
+kTrueTypeMultiFlatFontIcon = FOUR_CHAR_CODE('ttcf')
+kUserIDiskIcon = FOUR_CHAR_CODE('udsk')
+kInternationResourcesIcon = kInternationalResourcesIcon
+kInternetLocationHTTPIcon = FOUR_CHAR_CODE('ilht')
+kInternetLocationFTPIcon = FOUR_CHAR_CODE('ilft')
+kInternetLocationAppleShareIcon = FOUR_CHAR_CODE('ilaf')
+kInternetLocationAppleTalkZoneIcon = FOUR_CHAR_CODE('ilat')
+kInternetLocationFileIcon = FOUR_CHAR_CODE('ilfi')
+kInternetLocationMailIcon = FOUR_CHAR_CODE('ilma')
+kInternetLocationNewsIcon = FOUR_CHAR_CODE('ilnw')
+kInternetLocationNSLNeighborhoodIcon = FOUR_CHAR_CODE('ilns')
+kInternetLocationGenericIcon = FOUR_CHAR_CODE('ilge')
+kGenericFolderIcon = FOUR_CHAR_CODE('fldr')
+kDropFolderIcon = FOUR_CHAR_CODE('dbox')
+kMountedFolderIcon = FOUR_CHAR_CODE('mntd')
+kOpenFolderIcon = FOUR_CHAR_CODE('ofld')
+kOwnedFolderIcon = FOUR_CHAR_CODE('ownd')
+kPrivateFolderIcon = FOUR_CHAR_CODE('prvf')
+kSharedFolderIcon = FOUR_CHAR_CODE('shfl')
+kSharingPrivsNotApplicableIcon = FOUR_CHAR_CODE('shna')
+kSharingPrivsReadOnlyIcon = FOUR_CHAR_CODE('shro')
+kSharingPrivsReadWriteIcon = FOUR_CHAR_CODE('shrw')
+kSharingPrivsUnknownIcon = FOUR_CHAR_CODE('shuk')
+kSharingPrivsWritableIcon = FOUR_CHAR_CODE('writ')
+kUserFolderIcon = FOUR_CHAR_CODE('ufld')
+kWorkgroupFolderIcon = FOUR_CHAR_CODE('wfld')
+kGuestUserIcon = FOUR_CHAR_CODE('gusr')
+kUserIcon = FOUR_CHAR_CODE('user')
+kOwnerIcon = FOUR_CHAR_CODE('susr')
+kGroupIcon = FOUR_CHAR_CODE('grup')
+kAppearanceFolderIcon = FOUR_CHAR_CODE('appr')
+kAppleExtrasFolderIcon = FOUR_CHAR_CODE('aex\xc4')
+kAppleMenuFolderIcon = FOUR_CHAR_CODE('amnu')
+kApplicationsFolderIcon = FOUR_CHAR_CODE('apps')
+kApplicationSupportFolderIcon = FOUR_CHAR_CODE('asup')
+kAssistantsFolderIcon = FOUR_CHAR_CODE('ast\xc4')
+kColorSyncFolderIcon = FOUR_CHAR_CODE('prof')
+kContextualMenuItemsFolderIcon = FOUR_CHAR_CODE('cmnu')
+kControlPanelDisabledFolderIcon = FOUR_CHAR_CODE('ctrD')
+kControlPanelFolderIcon = FOUR_CHAR_CODE('ctrl')
+kControlStripModulesFolderIcon = FOUR_CHAR_CODE('sdv\xc4')
+kDocumentsFolderIcon = FOUR_CHAR_CODE('docs')
+kExtensionsDisabledFolderIcon = FOUR_CHAR_CODE('extD')
+kExtensionsFolderIcon = FOUR_CHAR_CODE('extn')
+kFavoritesFolderIcon = FOUR_CHAR_CODE('favs')
+kFontsFolderIcon = FOUR_CHAR_CODE('font')
+kHelpFolderIcon = FOUR_CHAR_CODE('\xc4hlp')
+kInternetFolderIcon = FOUR_CHAR_CODE('int\xc4')
+kInternetPlugInFolderIcon = FOUR_CHAR_CODE('\xc4net')
+kInternetSearchSitesFolderIcon = FOUR_CHAR_CODE('issf')
+kLocalesFolderIcon = FOUR_CHAR_CODE('\xc4loc')
+kMacOSReadMeFolderIcon = FOUR_CHAR_CODE('mor\xc4')
+kPublicFolderIcon = FOUR_CHAR_CODE('pubf')
+kPreferencesFolderIcon = FOUR_CHAR_CODE('prf\xc4')
+kPrinterDescriptionFolderIcon = FOUR_CHAR_CODE('ppdf')
+kPrinterDriverFolderIcon = FOUR_CHAR_CODE('\xc4prd')
+kPrintMonitorFolderIcon = FOUR_CHAR_CODE('prnt')
+kRecentApplicationsFolderIcon = FOUR_CHAR_CODE('rapp')
+kRecentDocumentsFolderIcon = FOUR_CHAR_CODE('rdoc')
+kRecentServersFolderIcon = FOUR_CHAR_CODE('rsrv')
+kScriptingAdditionsFolderIcon = FOUR_CHAR_CODE('\xc4scr')
+kSharedLibrariesFolderIcon = FOUR_CHAR_CODE('\xc4lib')
+kScriptsFolderIcon = FOUR_CHAR_CODE('scr\xc4')
+kShutdownItemsDisabledFolderIcon = FOUR_CHAR_CODE('shdD')
+kShutdownItemsFolderIcon = FOUR_CHAR_CODE('shdf')
+kSpeakableItemsFolder = FOUR_CHAR_CODE('spki')
+kStartupItemsDisabledFolderIcon = FOUR_CHAR_CODE('strD')
+kStartupItemsFolderIcon = FOUR_CHAR_CODE('strt')
+kSystemExtensionDisabledFolderIcon = FOUR_CHAR_CODE('macD')
+kSystemFolderIcon = FOUR_CHAR_CODE('macs')
+kTextEncodingsFolderIcon = FOUR_CHAR_CODE('\xc4tex')
+kUsersFolderIcon = FOUR_CHAR_CODE('usr\xc4')
+kUtilitiesFolderIcon = FOUR_CHAR_CODE('uti\xc4')
+kVoicesFolderIcon = FOUR_CHAR_CODE('fvoc')
+kSystemFolderXIcon = FOUR_CHAR_CODE('macx')
+kAppleScriptBadgeIcon = FOUR_CHAR_CODE('scrp')
+kLockedBadgeIcon = FOUR_CHAR_CODE('lbdg')
+kMountedBadgeIcon = FOUR_CHAR_CODE('mbdg')
+kSharedBadgeIcon = FOUR_CHAR_CODE('sbdg')
+kAliasBadgeIcon = FOUR_CHAR_CODE('abdg')
+kAlertCautionBadgeIcon = FOUR_CHAR_CODE('cbdg')
+kAlertNoteIcon = FOUR_CHAR_CODE('note')
+kAlertCautionIcon = FOUR_CHAR_CODE('caut')
+kAlertStopIcon = FOUR_CHAR_CODE('stop')
+kAppleTalkIcon = FOUR_CHAR_CODE('atlk')
+kAppleTalkZoneIcon = FOUR_CHAR_CODE('atzn')
+kAFPServerIcon = FOUR_CHAR_CODE('afps')
+kFTPServerIcon = FOUR_CHAR_CODE('ftps')
+kHTTPServerIcon = FOUR_CHAR_CODE('htps')
+kGenericNetworkIcon = FOUR_CHAR_CODE('gnet')
+kIPFileServerIcon = FOUR_CHAR_CODE('isrv')
+kToolbarCustomizeIcon = FOUR_CHAR_CODE('tcus')
+kToolbarDeleteIcon = FOUR_CHAR_CODE('tdel')
+kToolbarFavoritesIcon = FOUR_CHAR_CODE('tfav')
+kToolbarHomeIcon = FOUR_CHAR_CODE('thom')
+kAppleLogoIcon = FOUR_CHAR_CODE('capl')
+kAppleMenuIcon = FOUR_CHAR_CODE('sapl')
+kBackwardArrowIcon = FOUR_CHAR_CODE('baro')
+kFavoriteItemsIcon = FOUR_CHAR_CODE('favr')
+kForwardArrowIcon = FOUR_CHAR_CODE('faro')
+kGridIcon = FOUR_CHAR_CODE('grid')
+kHelpIcon = FOUR_CHAR_CODE('help')
+kKeepArrangedIcon = FOUR_CHAR_CODE('arng')
+kLockedIcon = FOUR_CHAR_CODE('lock')
+kNoFilesIcon = FOUR_CHAR_CODE('nfil')
+kNoFolderIcon = FOUR_CHAR_CODE('nfld')
+kNoWriteIcon = FOUR_CHAR_CODE('nwrt')
+kProtectedApplicationFolderIcon = FOUR_CHAR_CODE('papp')
+kProtectedSystemFolderIcon = FOUR_CHAR_CODE('psys')
+kRecentItemsIcon = FOUR_CHAR_CODE('rcnt')
+kShortcutIcon = FOUR_CHAR_CODE('shrt')
+kSortAscendingIcon = FOUR_CHAR_CODE('asnd')
+kSortDescendingIcon = FOUR_CHAR_CODE('dsnd')
+kUnlockedIcon = FOUR_CHAR_CODE('ulck')
+kConnectToIcon = FOUR_CHAR_CODE('cnct')
+kGenericWindowIcon = FOUR_CHAR_CODE('gwin')
+kQuestionMarkIcon = FOUR_CHAR_CODE('ques')
+kDeleteAliasIcon = FOUR_CHAR_CODE('dali')
+kEjectMediaIcon = FOUR_CHAR_CODE('ejec')
+kBurningIcon = FOUR_CHAR_CODE('burn')
+kRightContainerArrowIcon = FOUR_CHAR_CODE('rcar')
+kIconServicesNormalUsageFlag = 0
+kIconServicesCatalogInfoMask = (kFSCatInfoNodeID | kFSCatInfoParentDirID | kFSCatInfoVolume | kFSCatInfoNodeFlags | kFSCatInfoFinderInfo | kFSCatInfoFinderXInfo | kFSCatInfoUserAccess)
+kPlotIconRefNormalFlags = 0L
+kPlotIconRefNoImage = (1 << 1)
+kPlotIconRefNoMask = (1 << 2)
+kIconFamilyType = FOUR_CHAR_CODE('icns')

Added: vendor/Python/current/Lib/plat-mac/Carbon/Launch.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/Launch.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/Launch.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1 @@
+from _Launch import *

Added: vendor/Python/current/Lib/plat-mac/Carbon/LaunchServices.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/LaunchServices.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/LaunchServices.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,74 @@
+# Generated from 'LaunchServices.h'
+
+def FOUR_CHAR_CODE(x): return x
+from Carbon.Files import *
+kLSRequestAllInfo = -1
+kLSRolesAll = -1
+kLSUnknownType = FOUR_CHAR_CODE('\0\0\0\0')
+kLSUnknownCreator = FOUR_CHAR_CODE('\0\0\0\0')
+kLSInvalidExtensionIndex = -1
+kLSUnknownErr = -10810
+kLSNotAnApplicationErr = -10811
+kLSNotInitializedErr = -10812
+kLSDataUnavailableErr = -10813
+kLSApplicationNotFoundErr = -10814
+kLSUnknownTypeErr = -10815
+kLSDataTooOldErr = -10816
+kLSDataErr = -10817
+kLSLaunchInProgressErr = -10818
+kLSNotRegisteredErr = -10819
+kLSAppDoesNotClaimTypeErr = -10820
+kLSAppDoesNotSupportSchemeWarning = -10821
+kLSServerCommunicationErr = -10822
+kLSCannotSetInfoErr = -10823
+kLSInitializeDefaults = 0x00000001
+kLSMinCatInfoBitmap = (kFSCatInfoNodeFlags | kFSCatInfoParentDirID | kFSCatInfoFinderInfo | kFSCatInfoFinderXInfo)
+# kLSInvalidExtensionIndex = (unsigned long)0xFFFFFFFF
+kLSRequestExtension = 0x00000001
+kLSRequestTypeCreator = 0x00000002
+kLSRequestBasicFlagsOnly = 0x00000004
+kLSRequestAppTypeFlags = 0x00000008
+kLSRequestAllFlags = 0x00000010
+kLSRequestIconAndKind = 0x00000020
+kLSRequestExtensionFlagsOnly = 0x00000040
+# kLSRequestAllInfo = (unsigned long)0xFFFFFFFF
+kLSItemInfoIsPlainFile = 0x00000001
+kLSItemInfoIsPackage = 0x00000002
+kLSItemInfoIsApplication = 0x00000004
+kLSItemInfoIsContainer = 0x00000008
+kLSItemInfoIsAliasFile = 0x00000010
+kLSItemInfoIsSymlink = 0x00000020
+kLSItemInfoIsInvisible = 0x00000040
+kLSItemInfoIsNativeApp = 0x00000080
+kLSItemInfoIsClassicApp = 0x00000100
+kLSItemInfoAppPrefersNative = 0x00000200
+kLSItemInfoAppPrefersClassic = 0x00000400
+kLSItemInfoAppIsScriptable = 0x00000800
+kLSItemInfoIsVolume = 0x00001000
+kLSItemInfoExtensionIsHidden = 0x00100000
+kLSRolesNone = 0x00000001
+kLSRolesViewer = 0x00000002
+kLSRolesEditor = 0x00000004
+# kLSRolesAll = (unsigned long)0xFFFFFFFF
+kLSUnknownKindID = 0
+# kLSUnknownType = 0
+# kLSUnknownCreator = 0
+kLSAcceptDefault = 0x00000001
+kLSAcceptAllowLoginUI = 0x00000002
+kLSLaunchDefaults = 0x00000001
+kLSLaunchAndPrint = 0x00000002
+kLSLaunchReserved2 = 0x00000004
+kLSLaunchReserved3 = 0x00000008
+kLSLaunchReserved4 = 0x00000010
+kLSLaunchReserved5 = 0x00000020
+kLSLaunchReserved6 = 0x00000040
+kLSLaunchInhibitBGOnly = 0x00000080
+kLSLaunchDontAddToRecents = 0x00000100
+kLSLaunchDontSwitch = 0x00000200
+kLSLaunchNoParams = 0x00000800
+kLSLaunchAsync = 0x00010000
+kLSLaunchStartClassic = 0x00020000
+kLSLaunchInClassic = 0x00040000
+kLSLaunchNewInstance = 0x00080000
+kLSLaunchAndHide = 0x00100000
+kLSLaunchAndHideOthers = 0x00200000

Added: vendor/Python/current/Lib/plat-mac/Carbon/List.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/List.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/List.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1 @@
+from _List import *

Added: vendor/Python/current/Lib/plat-mac/Carbon/Lists.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/Lists.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/Lists.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,35 @@
+# Generated from 'Lists.h'
+
+def FOUR_CHAR_CODE(x): return x
+listNotifyNothing = FOUR_CHAR_CODE('nada')
+listNotifyClick = FOUR_CHAR_CODE('clik')
+listNotifyDoubleClick = FOUR_CHAR_CODE('dblc')
+listNotifyPreClick = FOUR_CHAR_CODE('pclk')
+lDrawingModeOffBit = 3
+lDoVAutoscrollBit = 1
+lDoHAutoscrollBit = 0
+lDrawingModeOff = 8
+lDoVAutoscroll = 2
+lDoHAutoscroll = 1
+lOnlyOneBit = 7
+lExtendDragBit = 6
+lNoDisjointBit = 5
+lNoExtendBit = 4
+lNoRectBit = 3
+lUseSenseBit = 2
+lNoNilHiliteBit = 1
+lOnlyOne = -128
+lExtendDrag = 64
+lNoDisjoint = 32
+lNoExtend = 16
+lNoRect = 8
+lUseSense = 4
+lNoNilHilite = 2
+lInitMsg = 0
+lDrawMsg = 1
+lHiliteMsg = 2
+lCloseMsg = 3
+kListDefProcPtr = 0
+kListDefUserProcType = kListDefProcPtr
+kListDefStandardTextType = 1
+kListDefStandardIconType = 2

Added: vendor/Python/current/Lib/plat-mac/Carbon/MacHelp.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/MacHelp.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/MacHelp.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,58 @@
+# Generated from 'MacHelp.h'
+
+def FOUR_CHAR_CODE(x): return x
+kMacHelpVersion = 0x0003
+kHMSupplyContent = 0
+kHMDisposeContent = 1
+kHMNoContent = FOUR_CHAR_CODE('none')
+kHMCFStringContent = FOUR_CHAR_CODE('cfst')
+kHMPascalStrContent = FOUR_CHAR_CODE('pstr')
+kHMStringResContent = FOUR_CHAR_CODE('str#')
+kHMTEHandleContent = FOUR_CHAR_CODE('txth')
+kHMTextResContent = FOUR_CHAR_CODE('text')
+kHMStrResContent = FOUR_CHAR_CODE('str ')
+kHMDefaultSide = 0
+kHMOutsideTopScriptAligned = 1
+kHMOutsideLeftCenterAligned = 2
+kHMOutsideBottomScriptAligned = 3
+kHMOutsideRightCenterAligned = 4
+kHMOutsideTopLeftAligned = 5
+kHMOutsideTopRightAligned = 6
+kHMOutsideLeftTopAligned = 7
+kHMOutsideLeftBottomAligned = 8
+kHMOutsideBottomLeftAligned = 9
+kHMOutsideBottomRightAligned = 10
+kHMOutsideRightTopAligned = 11
+kHMOutsideRightBottomAligned = 12
+kHMOutsideTopCenterAligned = 13
+kHMOutsideBottomCenterAligned = 14
+kHMInsideRightCenterAligned = 15
+kHMInsideLeftCenterAligned = 16
+kHMInsideBottomCenterAligned = 17
+kHMInsideTopCenterAligned = 18
+kHMInsideTopLeftCorner = 19
+kHMInsideTopRightCorner = 20
+kHMInsideBottomLeftCorner = 21
+kHMInsideBottomRightCorner = 22
+kHMAbsoluteCenterAligned = 23
+kHMTopSide = kHMOutsideTopScriptAligned
+kHMLeftSide = kHMOutsideLeftCenterAligned
+kHMBottomSide = kHMOutsideBottomScriptAligned
+kHMRightSide = kHMOutsideRightCenterAligned
+kHMTopLeftCorner = kHMOutsideTopLeftAligned
+kHMTopRightCorner = kHMOutsideTopRightAligned
+kHMLeftTopCorner = kHMOutsideLeftTopAligned
+kHMLeftBottomCorner = kHMOutsideLeftBottomAligned
+kHMBottomLeftCorner = kHMOutsideBottomLeftAligned
+kHMBottomRightCorner = kHMOutsideBottomRightAligned
+kHMRightTopCorner = kHMOutsideRightTopAligned
+kHMRightBottomCorner = kHMOutsideRightBottomAligned
+kHMContentProvided = 0
+kHMContentNotProvided = 1
+kHMContentNotProvidedDontPropagate = 2
+kHMMinimumContentIndex = 0
+kHMMaximumContentIndex = 1
+errHMIllegalContentForMinimumState = -10980
+errHMIllegalContentForMaximumState = -10981
+kHMIllegalContentForMinimumState = errHMIllegalContentForMinimumState
+kHelpTagEventHandlerTag = FOUR_CHAR_CODE('hevt')

Added: vendor/Python/current/Lib/plat-mac/Carbon/MacTextEditor.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/MacTextEditor.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/MacTextEditor.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,226 @@
+# Generated from 'MacTextEditor.h'
+
+
+def FOUR_CHAR_CODE(x): return x
+false = 0
+true = 1
+kTXNClearThisControl = 0xFFFFFFFF
+kTXNClearTheseFontFeatures = 0x80000000
+kTXNDontCareTypeSize = 0xFFFFFFFF
+kTXNDecrementTypeSize = 0x80000000
+kTXNUseCurrentSelection = 0xFFFFFFFF
+kTXNStartOffset = 0
+kTXNEndOffset = 0x7FFFFFFF
+MovieFileType = FOUR_CHAR_CODE('moov')
+kTXNUseEncodingWordRulesMask = 0x80000000
+kTXNFontSizeAttributeSize = 4
+normal = 0
+kTXNWillDefaultToATSUIBit = 0
+kTXNWillDefaultToCarbonEventBit = 1
+kTXNWillDefaultToATSUIMask = 1L << kTXNWillDefaultToATSUIBit
+kTXNWillDefaultToCarbonEventMask = 1L << kTXNWillDefaultToCarbonEventBit
+kTXNWantMoviesBit = 0
+kTXNWantSoundBit = 1
+kTXNWantGraphicsBit = 2
+kTXNAlwaysUseQuickDrawTextBit = 3
+kTXNUseTemporaryMemoryBit = 4
+kTXNWantMoviesMask = 1L << kTXNWantMoviesBit
+kTXNWantSoundMask = 1L << kTXNWantSoundBit
+kTXNWantGraphicsMask = 1L << kTXNWantGraphicsBit
+kTXNAlwaysUseQuickDrawTextMask = 1L << kTXNAlwaysUseQuickDrawTextBit
+kTXNUseTemporaryMemoryMask = 1L << kTXNUseTemporaryMemoryBit
+kTXNDrawGrowIconBit = 0
+kTXNShowWindowBit = 1
+kTXNWantHScrollBarBit = 2
+kTXNWantVScrollBarBit = 3
+kTXNNoTSMEverBit = 4
+kTXNReadOnlyBit = 5
+kTXNNoKeyboardSyncBit = 6
+kTXNNoSelectionBit = 7
+kTXNSaveStylesAsSTYLResourceBit = 8
+kOutputTextInUnicodeEncodingBit = 9
+kTXNDoNotInstallDragProcsBit = 10
+kTXNAlwaysWrapAtViewEdgeBit = 11
+kTXNDontDrawCaretWhenInactiveBit = 12
+kTXNDontDrawSelectionWhenInactiveBit = 13
+kTXNSingleLineOnlyBit = 14
+kTXNDisableDragAndDropBit = 15
+kTXNUseQDforImagingBit = 16
+kTXNDrawGrowIconMask = 1L << kTXNDrawGrowIconBit
+kTXNShowWindowMask = 1L << kTXNShowWindowBit
+kTXNWantHScrollBarMask = 1L << kTXNWantHScrollBarBit
+kTXNWantVScrollBarMask = 1L << kTXNWantVScrollBarBit
+kTXNNoTSMEverMask = 1L << kTXNNoTSMEverBit
+kTXNReadOnlyMask = 1L << kTXNReadOnlyBit
+kTXNNoKeyboardSyncMask = 1L << kTXNNoKeyboardSyncBit
+kTXNNoSelectionMask = 1L << kTXNNoSelectionBit
+kTXNSaveStylesAsSTYLResourceMask = 1L << kTXNSaveStylesAsSTYLResourceBit
+kOutputTextInUnicodeEncodingMask = 1L << kOutputTextInUnicodeEncodingBit
+kTXNDoNotInstallDragProcsMask = 1L << kTXNDoNotInstallDragProcsBit
+kTXNAlwaysWrapAtViewEdgeMask = 1L << kTXNAlwaysWrapAtViewEdgeBit
+kTXNDontDrawCaretWhenInactiveMask = 1L << kTXNDontDrawCaretWhenInactiveBit
+kTXNDontDrawSelectionWhenInactiveMask = 1L << kTXNDontDrawSelectionWhenInactiveBit
+kTXNSingleLineOnlyMask = 1L << kTXNSingleLineOnlyBit
+kTXNDisableDragAndDropMask = 1L << kTXNDisableDragAndDropBit
+kTXNUseQDforImagingMask = 1L << kTXNUseQDforImagingBit
+kTXNSetFlushnessBit = 0
+kTXNSetJustificationBit = 1
+kTXNUseFontFallBackBit = 2
+kTXNRotateTextBit = 3
+kTXNUseVerticalTextBit = 4
+kTXNDontUpdateBoxRectBit = 5
+kTXNDontDrawTextBit = 6
+kTXNUseCGContextRefBit = 7
+kTXNImageWithQDBit = 8
+kTXNDontWrapTextBit = 9
+kTXNSetFlushnessMask = 1L << kTXNSetFlushnessBit
+kTXNSetJustificationMask = 1L << kTXNSetJustificationBit
+kTXNUseFontFallBackMask = 1L << kTXNUseFontFallBackBit
+kTXNRotateTextMask = 1L << kTXNRotateTextBit
+kTXNUseVerticalTextMask = 1L << kTXNUseVerticalTextBit
+kTXNDontUpdateBoxRectMask = 1L << kTXNDontUpdateBoxRectBit
+kTXNDontDrawTextMask = 1L << kTXNDontDrawTextBit
+kTXNUseCGContextRefMask = 1L << kTXNUseCGContextRefBit
+kTXNImageWithQDMask = 1L << kTXNImageWithQDBit
+kTXNDontWrapTextMask = 1L << kTXNDontWrapTextBit
+kTXNFontContinuousBit = 0
+kTXNSizeContinuousBit = 1
+kTXNStyleContinuousBit = 2
+kTXNColorContinuousBit = 3
+kTXNFontContinuousMask = 1L << kTXNFontContinuousBit
+kTXNSizeContinuousMask = 1L << kTXNSizeContinuousBit
+kTXNStyleContinuousMask = 1L << kTXNStyleContinuousBit
+kTXNColorContinuousMask = 1L << kTXNColorContinuousBit
+kTXNIgnoreCaseBit = 0
+kTXNEntireWordBit = 1
+kTXNUseEncodingWordRulesBit = 31
+kTXNIgnoreCaseMask = 1L << kTXNIgnoreCaseBit
+kTXNEntireWordMask = 1L << kTXNEntireWordBit
+# kTXNUseEncodingWordRulesMask = (unsigned long)(1L << kTXNUseEncodingWordRulesBit)
+kTXNTextensionFile = FOUR_CHAR_CODE('txtn')
+kTXNTextFile = FOUR_CHAR_CODE('TEXT')
+kTXNPictureFile = FOUR_CHAR_CODE('PICT')
+kTXNMovieFile = FOUR_CHAR_CODE('MooV')
+kTXNSoundFile = FOUR_CHAR_CODE('sfil')
+kTXNAIFFFile = FOUR_CHAR_CODE('AIFF')
+kTXNUnicodeTextFile = FOUR_CHAR_CODE('utxt')
+kTXNTextEditStyleFrameType = 1
+kTXNPageFrameType = 2
+kTXNMultipleFrameType = 3
+kTXNTextData = FOUR_CHAR_CODE('TEXT')
+kTXNPictureData = FOUR_CHAR_CODE('PICT')
+kTXNMovieData = FOUR_CHAR_CODE('moov')
+kTXNSoundData = FOUR_CHAR_CODE('snd ')
+kTXNUnicodeTextData = FOUR_CHAR_CODE('utxt')
+kTXNLineDirectionTag = FOUR_CHAR_CODE('lndr')
+kTXNJustificationTag = FOUR_CHAR_CODE('just')
+kTXNIOPrivilegesTag = FOUR_CHAR_CODE('iopv')
+kTXNSelectionStateTag = FOUR_CHAR_CODE('slst')
+kTXNInlineStateTag = FOUR_CHAR_CODE('inst')
+kTXNWordWrapStateTag = FOUR_CHAR_CODE('wwrs')
+kTXNKeyboardSyncStateTag = FOUR_CHAR_CODE('kbsy')
+kTXNAutoIndentStateTag = FOUR_CHAR_CODE('auin')
+kTXNTabSettingsTag = FOUR_CHAR_CODE('tabs')
+kTXNRefConTag = FOUR_CHAR_CODE('rfcn')
+kTXNMarginsTag = FOUR_CHAR_CODE('marg')
+kTXNFlattenMoviesTag = FOUR_CHAR_CODE('flat')
+kTXNDoFontSubstitution = FOUR_CHAR_CODE('fSub')
+kTXNNoUserIOTag = FOUR_CHAR_CODE('nuio')
+kTXNUseCarbonEvents = FOUR_CHAR_CODE('cbcb')
+kTXNDrawCaretWhenInactiveTag = FOUR_CHAR_CODE('dcrt')
+kTXNDrawSelectionWhenInactiveTag = FOUR_CHAR_CODE('dsln')
+kTXNDisableDragAndDropTag = FOUR_CHAR_CODE('drag')
+kTXNTypingAction = 0
+kTXNCutAction = 1
+kTXNPasteAction = 2
+kTXNClearAction = 3
+kTXNChangeFontAction = 4
+kTXNChangeFontColorAction = 5
+kTXNChangeFontSizeAction = 6
+kTXNChangeStyleAction = 7
+kTXNAlignLeftAction = 8
+kTXNAlignCenterAction = 9
+kTXNAlignRightAction = 10
+kTXNDropAction = 11
+kTXNMoveAction = 12
+kTXNFontFeatureAction = 13
+kTXNFontVariationAction = 14
+kTXNUndoLastAction = 1024
+# kTXNClearThisControl = (long)0xFFFFFFFF
+# kTXNClearTheseFontFeatures = (long)0x80000000
+kTXNReadWrite = false
+kTXNReadOnly = true
+kTXNSelectionOn = true
+kTXNSelectionOff = false
+kTXNUseInline = false
+kTXNUseBottomline = true
+kTXNAutoWrap = false
+kTXNNoAutoWrap = true
+kTXNSyncKeyboard = false
+kTXNNoSyncKeyboard = true
+kTXNAutoIndentOff = false
+kTXNAutoIndentOn = true
+kTXNDontDrawCaretWhenInactive = false
+kTXNDrawCaretWhenInactive = true
+kTXNDontDrawSelectionWhenInactive = false
+kTXNDrawSelectionWhenInactive = true
+kTXNEnableDragAndDrop = false
+kTXNDisableDragAndDrop = true
+kTXNRightTab = -1
+kTXNLeftTab = 0
+kTXNCenterTab = 1
+kTXNLeftToRight = 0
+kTXNRightToLeft = 1
+kTXNFlushDefault = 0
+kTXNFlushLeft = 1
+kTXNFlushRight = 2
+kTXNCenter = 4
+kTXNFullJust = 8
+kTXNForceFullJust = 16
+kScrollBarsAlwaysActive = true
+kScrollBarsSyncWithFocus = false
+# kTXNDontCareTypeSize = (long)0xFFFFFFFF
+kTXNDontCareTypeStyle = 0xFF
+kTXNIncrementTypeSize = 0x00000001
+# kTXNDecrementTypeSize = (long)0x80000000
+kTXNUseScriptDefaultValue = -1
+kTXNNoFontVariations = 0x7FFF
+# kTXNUseCurrentSelection = (unsigned long)0xFFFFFFFF
+# kTXNStartOffset = 0
+# kTXNEndOffset = 0x7FFFFFFF
+kTXNSingleStylePerTextDocumentResType = FOUR_CHAR_CODE('MPSR')
+kTXNMultipleStylesPerTextDocumentResType = FOUR_CHAR_CODE('styl')
+kTXNShowStart = false
+kTXNShowEnd = true
+kTXNDefaultFontName = 0
+kTXNDefaultFontSize = 0x000C0000
+kTXNDefaultFontStyle = normal
+kTXNQDFontNameAttribute = FOUR_CHAR_CODE('fntn')
+kTXNQDFontFamilyIDAttribute = FOUR_CHAR_CODE('font')
+kTXNQDFontSizeAttribute = FOUR_CHAR_CODE('size')
+kTXNQDFontStyleAttribute = FOUR_CHAR_CODE('face')
+kTXNQDFontColorAttribute = FOUR_CHAR_CODE('klor')
+kTXNTextEncodingAttribute = FOUR_CHAR_CODE('encd')
+kTXNATSUIFontFeaturesAttribute = FOUR_CHAR_CODE('atfe')
+kTXNATSUIFontVariationsAttribute = FOUR_CHAR_CODE('atva')
+# kTXNQDFontNameAttributeSize = sizeof(Str255)
+# kTXNQDFontFamilyIDAttributeSize = sizeof(SInt16)
+# kTXNQDFontSizeAttributeSize = sizeof(SInt16)
+# kTXNQDFontStyleAttributeSize = sizeof(Style)
+# kTXNQDFontColorAttributeSize = sizeof(RGBColor)
+# kTXNTextEncodingAttributeSize = sizeof(TextEncoding)
+# kTXNFontSizeAttributeSize = sizeof(Fixed)
+kTXNSystemDefaultEncoding = 0
+kTXNMacOSEncoding = 1
+kTXNUnicodeEncoding = 2
+kTXNBackgroundTypeRGB = 1
+kTXNTextInputCountBit = 0
+kTXNRunCountBit = 1
+kTXNTextInputCountMask = 1L << kTXNTextInputCountBit
+kTXNRunCountMask = 1L << kTXNRunCountBit
+kTXNAllCountMask = kTXNTextInputCountMask | kTXNRunCountMask
+kTXNNoAppleEventHandlersBit = 0
+kTXNRestartAppleEventHandlersBit = 1
+kTXNNoAppleEventHandlersMask = 1 << kTXNNoAppleEventHandlersBit
+kTXNRestartAppleEventHandlersMask = 1 << kTXNRestartAppleEventHandlersBit
+# status = TXNInitTextension( &defaults

Added: vendor/Python/current/Lib/plat-mac/Carbon/MediaDescr.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/MediaDescr.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/MediaDescr.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,97 @@
+# Parsers/generators for QuickTime media descriptions
+import struct
+
+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 = struct.pack(*list)
+        return rv
+
+# Helper functions
+def _tofixed(float):
+    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))
+
+def _tostr31(str):
+    return chr(len(str)) + str + '\0'*(31-len(str))
+
+def _fromstr31(str31):
+    return str31[1:1+ord(str31[0])]
+
+SampleDescription = _MediaDescriptionCodec(
+        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
+)
+
+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
+)
+
+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',
+)
+
+# XXXX Others, like TextDescription and such, remain to be done.

Added: vendor/Python/current/Lib/plat-mac/Carbon/Menu.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/Menu.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/Menu.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1 @@
+from _Menu import *

Added: vendor/Python/current/Lib/plat-mac/Carbon/Menus.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/Menus.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/Menus.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,169 @@
+# Generated from 'Menus.h'
+
+def FOUR_CHAR_CODE(x): return x
+noMark = 0
+kMenuDrawMsg = 0
+kMenuSizeMsg = 2
+kMenuPopUpMsg = 3
+kMenuCalcItemMsg = 5
+kMenuThemeSavvyMsg = 7
+mDrawMsg = 0
+mSizeMsg = 2
+mPopUpMsg = 3
+mCalcItemMsg = 5
+mChooseMsg = 1
+mDrawItemMsg = 4
+kMenuChooseMsg = 1
+kMenuDrawItemMsg = 4
+kThemeSavvyMenuResponse = 0x7473
+kMenuInitMsg = 8
+kMenuDisposeMsg = 9
+kMenuFindItemMsg = 10
+kMenuHiliteItemMsg = 11
+kMenuDrawItemsMsg = 12
+textMenuProc = 0
+hMenuCmd = 27
+hierMenu = -1
+kInsertHierarchicalMenu = -1
+mctAllItems = -98
+mctLastIDIndic = -99
+kMenuStdMenuProc = 63
+kMenuStdMenuBarProc = 63
+kMenuNoModifiers = 0
+kMenuShiftModifier = (1 << 0)
+kMenuOptionModifier = (1 << 1)
+kMenuControlModifier = (1 << 2)
+kMenuNoCommandModifier = (1 << 3)
+kMenuNoIcon = 0
+kMenuIconType = 1
+kMenuShrinkIconType = 2
+kMenuSmallIconType = 3
+kMenuColorIconType = 4
+kMenuIconSuiteType = 5
+kMenuIconRefType = 6
+kMenuCGImageRefType = 7
+kMenuSystemIconSelectorType = 8
+kMenuIconResourceType = 9
+kMenuNullGlyph = 0x00
+kMenuTabRightGlyph = 0x02
+kMenuTabLeftGlyph = 0x03
+kMenuEnterGlyph = 0x04
+kMenuShiftGlyph = 0x05
+kMenuControlGlyph = 0x06
+kMenuOptionGlyph = 0x07
+kMenuSpaceGlyph = 0x09
+kMenuDeleteRightGlyph = 0x0A
+kMenuReturnGlyph = 0x0B
+kMenuReturnR2LGlyph = 0x0C
+kMenuNonmarkingReturnGlyph = 0x0D
+kMenuPencilGlyph = 0x0F
+kMenuDownwardArrowDashedGlyph = 0x10
+kMenuCommandGlyph = 0x11
+kMenuCheckmarkGlyph = 0x12
+kMenuDiamondGlyph = 0x13
+kMenuAppleLogoFilledGlyph = 0x14
+kMenuParagraphKoreanGlyph = 0x15
+kMenuDeleteLeftGlyph = 0x17
+kMenuLeftArrowDashedGlyph = 0x18
+kMenuUpArrowDashedGlyph = 0x19
+kMenuRightArrowDashedGlyph = 0x1A
+kMenuEscapeGlyph = 0x1B
+kMenuClearGlyph = 0x1C
+kMenuLeftDoubleQuotesJapaneseGlyph = 0x1D
+kMenuRightDoubleQuotesJapaneseGlyph = 0x1E
+kMenuTrademarkJapaneseGlyph = 0x1F
+kMenuBlankGlyph = 0x61
+kMenuPageUpGlyph = 0x62
+kMenuCapsLockGlyph = 0x63
+kMenuLeftArrowGlyph = 0x64
+kMenuRightArrowGlyph = 0x65
+kMenuNorthwestArrowGlyph = 0x66
+kMenuHelpGlyph = 0x67
+kMenuUpArrowGlyph = 0x68
+kMenuSoutheastArrowGlyph = 0x69
+kMenuDownArrowGlyph = 0x6A
+kMenuPageDownGlyph = 0x6B
+kMenuAppleLogoOutlineGlyph = 0x6C
+kMenuContextualMenuGlyph = 0x6D
+kMenuPowerGlyph = 0x6E
+kMenuF1Glyph = 0x6F
+kMenuF2Glyph = 0x70
+kMenuF3Glyph = 0x71
+kMenuF4Glyph = 0x72
+kMenuF5Glyph = 0x73
+kMenuF6Glyph = 0x74
+kMenuF7Glyph = 0x75
+kMenuF8Glyph = 0x76
+kMenuF9Glyph = 0x77
+kMenuF10Glyph = 0x78
+kMenuF11Glyph = 0x79
+kMenuF12Glyph = 0x7A
+kMenuF13Glyph = 0x87
+kMenuF14Glyph = 0x88
+kMenuF15Glyph = 0x89
+kMenuControlISOGlyph = 0x8A
+kMenuAttrExcludesMarkColumn = (1 << 0)
+kMenuAttrAutoDisable = (1 << 2)
+kMenuAttrUsePencilGlyph = (1 << 3)
+kMenuAttrHidden = (1 << 4)
+kMenuItemAttrDisabled = (1 << 0)
+kMenuItemAttrIconDisabled = (1 << 1)
+kMenuItemAttrSubmenuParentChoosable = (1 << 2)
+kMenuItemAttrDynamic = (1 << 3)
+kMenuItemAttrNotPreviousAlternate = (1 << 4)
+kMenuItemAttrHidden = (1 << 5)
+kMenuItemAttrSeparator = (1 << 6)
+kMenuItemAttrSectionHeader = (1 << 7)
+kMenuItemAttrIgnoreMeta = (1 << 8)
+kMenuItemAttrAutoRepeat = (1 << 9)
+kMenuItemAttrUseVirtualKey = (1 << 10)
+kMenuItemAttrCustomDraw = (1 << 11)
+kMenuItemAttrIncludeInCmdKeyMatching = (1 << 12)
+kMenuTrackingModeMouse = 1
+kMenuTrackingModeKeyboard = 2
+kMenuEventIncludeDisabledItems = 0x0001
+kMenuEventQueryOnly = 0x0002
+kMenuEventDontCheckSubmenus = 0x0004
+kMenuItemDataText = (1 << 0)
+kMenuItemDataMark = (1 << 1)
+kMenuItemDataCmdKey = (1 << 2)
+kMenuItemDataCmdKeyGlyph = (1 << 3)
+kMenuItemDataCmdKeyModifiers = (1 << 4)
+kMenuItemDataStyle = (1 << 5)
+kMenuItemDataEnabled = (1 << 6)
+kMenuItemDataIconEnabled = (1 << 7)
+kMenuItemDataIconID = (1 << 8)
+kMenuItemDataIconHandle = (1 << 9)
+kMenuItemDataCommandID = (1 << 10)
+kMenuItemDataTextEncoding = (1 << 11)
+kMenuItemDataSubmenuID = (1 << 12)
+kMenuItemDataSubmenuHandle = (1 << 13)
+kMenuItemDataFontID = (1 << 14)
+kMenuItemDataRefcon = (1 << 15)
+kMenuItemDataAttributes = (1 << 16)
+kMenuItemDataCFString = (1 << 17)
+kMenuItemDataProperties = (1 << 18)
+kMenuItemDataIndent = (1 << 19)
+kMenuItemDataCmdVirtualKey = (1 << 20)
+kMenuItemDataAllDataVersionOne = 0x000FFFFF
+kMenuItemDataAllDataVersionTwo = kMenuItemDataAllDataVersionOne | kMenuItemDataCmdVirtualKey
+kMenuDefProcPtr = 0
+kMenuPropertyPersistent = 0x00000001
+kHierarchicalFontMenuOption = 0x00000001
+gestaltContextualMenuAttr = FOUR_CHAR_CODE('cmnu')
+gestaltContextualMenuUnusedBit = 0
+gestaltContextualMenuTrapAvailable = 1
+gestaltContextualMenuHasAttributeAndModifierKeys = 2
+gestaltContextualMenuHasUnicodeSupport = 3
+kCMHelpItemNoHelp = 0
+kCMHelpItemAppleGuide = 1
+kCMHelpItemOtherHelp = 2
+kCMHelpItemRemoveHelp = 3
+kCMNothingSelected = 0
+kCMMenuItemSelected = 1
+kCMShowHelpSelected = 3
+keyContextualMenuName = FOUR_CHAR_CODE('pnam')
+keyContextualMenuCommandID = FOUR_CHAR_CODE('cmcd')
+keyContextualMenuSubmenu = FOUR_CHAR_CODE('cmsb')
+keyContextualMenuAttributes = FOUR_CHAR_CODE('cmat')
+keyContextualMenuModifiers = FOUR_CHAR_CODE('cmmd')

Added: vendor/Python/current/Lib/plat-mac/Carbon/Mlte.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/Mlte.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/Mlte.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1 @@
+from _Mlte import *

Added: vendor/Python/current/Lib/plat-mac/Carbon/OSA.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/OSA.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/OSA.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1 @@
+from _OSA import *

Added: vendor/Python/current/Lib/plat-mac/Carbon/OSAconst.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/OSAconst.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/OSAconst.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,133 @@
+# Generated from 'OSA.h'
+
+def FOUR_CHAR_CODE(x): return x
+from Carbon.AppleEvents import *
+kAEUseStandardDispatch = -1
+kOSAComponentType = FOUR_CHAR_CODE('osa ')
+kOSAGenericScriptingComponentSubtype = FOUR_CHAR_CODE('scpt')
+kOSAFileType = FOUR_CHAR_CODE('osas')
+kOSASuite = FOUR_CHAR_CODE('ascr')
+kOSARecordedText = FOUR_CHAR_CODE('recd')
+kOSAScriptIsModified = FOUR_CHAR_CODE('modi')
+kOSAScriptIsTypeCompiledScript = FOUR_CHAR_CODE('cscr')
+kOSAScriptIsTypeScriptValue = FOUR_CHAR_CODE('valu')
+kOSAScriptIsTypeScriptContext = FOUR_CHAR_CODE('cntx')
+kOSAScriptBestType = FOUR_CHAR_CODE('best')
+kOSACanGetSource = FOUR_CHAR_CODE('gsrc')
+typeOSADialectInfo = FOUR_CHAR_CODE('difo')
+keyOSADialectName = FOUR_CHAR_CODE('dnam')
+keyOSADialectCode = FOUR_CHAR_CODE('dcod')
+keyOSADialectLangCode = FOUR_CHAR_CODE('dlcd')
+keyOSADialectScriptCode = FOUR_CHAR_CODE('dscd')
+kOSANullScript = 0L
+kOSANullMode = 0
+kOSAModeNull = 0
+kOSASupportsCompiling = 0x0002
+kOSASupportsGetSource = 0x0004
+kOSASupportsAECoercion = 0x0008
+kOSASupportsAESending = 0x0010
+kOSASupportsRecording = 0x0020
+kOSASupportsConvenience = 0x0040
+kOSASupportsDialects = 0x0080
+kOSASupportsEventHandling = 0x0100
+kOSASelectLoad = 0x0001
+kOSASelectStore = 0x0002
+kOSASelectExecute = 0x0003
+kOSASelectDisplay = 0x0004
+kOSASelectScriptError = 0x0005
+kOSASelectDispose = 0x0006
+kOSASelectSetScriptInfo = 0x0007
+kOSASelectGetScriptInfo = 0x0008
+kOSASelectSetActiveProc = 0x0009
+kOSASelectGetActiveProc = 0x000A
+kOSASelectScriptingComponentName = 0x0102
+kOSASelectCompile = 0x0103
+kOSASelectCopyID = 0x0104
+kOSASelectCopyScript = 0x0105
+kOSASelectGetSource = 0x0201
+kOSASelectCoerceFromDesc = 0x0301
+kOSASelectCoerceToDesc = 0x0302
+kOSASelectSetSendProc = 0x0401
+kOSASelectGetSendProc = 0x0402
+kOSASelectSetCreateProc = 0x0403
+kOSASelectGetCreateProc = 0x0404
+kOSASelectSetDefaultTarget = 0x0405
+kOSASelectStartRecording = 0x0501
+kOSASelectStopRecording = 0x0502
+kOSASelectLoadExecute = 0x0601
+kOSASelectCompileExecute = 0x0602
+kOSASelectDoScript = 0x0603
+kOSASelectSetCurrentDialect = 0x0701
+kOSASelectGetCurrentDialect = 0x0702
+kOSASelectAvailableDialects = 0x0703
+kOSASelectGetDialectInfo = 0x0704
+kOSASelectAvailableDialectCodeList = 0x0705
+kOSASelectSetResumeDispatchProc = 0x0801
+kOSASelectGetResumeDispatchProc = 0x0802
+kOSASelectExecuteEvent = 0x0803
+kOSASelectDoEvent = 0x0804
+kOSASelectMakeContext = 0x0805
+kOSADebuggerCreateSession = 0x0901
+kOSADebuggerGetSessionState = 0x0902
+kOSADebuggerSessionStep = 0x0903
+kOSADebuggerDisposeSession = 0x0904
+kOSADebuggerGetStatementRanges = 0x0905
+kOSADebuggerGetBreakpoint = 0x0910
+kOSADebuggerSetBreakpoint = 0x0911
+kOSADebuggerGetDefaultBreakpoint = 0x0912
+kOSADebuggerGetCurrentCallFrame = 0x0906
+kOSADebuggerGetCallFrameState = 0x0907
+kOSADebuggerGetVariable = 0x0908
+kOSADebuggerSetVariable = 0x0909
+kOSADebuggerGetPreviousCallFrame = 0x090A
+kOSADebuggerDisposeCallFrame = 0x090B
+kOSADebuggerCountVariables = 0x090C
+kOSASelectComponentSpecificStart = 0x1001
+kOSAModePreventGetSource = 0x00000001
+kOSAModeNeverInteract = kAENeverInteract
+kOSAModeCanInteract = kAECanInteract
+kOSAModeAlwaysInteract = kAEAlwaysInteract
+kOSAModeDontReconnect = kAEDontReconnect
+kOSAModeCantSwitchLayer = 0x00000040
+kOSAModeDoRecord = 0x00001000
+kOSAModeCompileIntoContext = 0x00000002
+kOSAModeAugmentContext = 0x00000004
+kOSAModeDisplayForHumans = 0x00000008
+kOSAModeDontStoreParent = 0x00010000
+kOSAModeDispatchToDirectObject = 0x00020000
+kOSAModeDontGetDataForArguments = 0x00040000
+kOSAScriptResourceType = kOSAGenericScriptingComponentSubtype
+typeOSAGenericStorage = kOSAScriptResourceType
+kOSAErrorNumber = keyErrorNumber
+kOSAErrorMessage = keyErrorString
+kOSAErrorBriefMessage = FOUR_CHAR_CODE('errb')
+kOSAErrorApp = FOUR_CHAR_CODE('erap')
+kOSAErrorPartialResult = FOUR_CHAR_CODE('ptlr')
+kOSAErrorOffendingObject = FOUR_CHAR_CODE('erob')
+kOSAErrorExpectedType = FOUR_CHAR_CODE('errt')
+kOSAErrorRange = FOUR_CHAR_CODE('erng')
+typeOSAErrorRange = FOUR_CHAR_CODE('erng')
+keyOSASourceStart = FOUR_CHAR_CODE('srcs')
+keyOSASourceEnd = FOUR_CHAR_CODE('srce')
+kOSAUseStandardDispatch = kAEUseStandardDispatch
+kOSANoDispatch = kAENoDispatch
+kOSADontUsePhac = 0x0001
+eNotStarted = 0
+eRunnable = 1
+eRunning = 2
+eStopped = 3
+eTerminated = 4
+eStepOver = 0
+eStepIn = 1
+eStepOut = 2
+eRun = 3
+eLocal = 0
+eGlobal = 1
+eProperties = 2
+keyProgramState = FOUR_CHAR_CODE('dsps')
+typeStatementRange = FOUR_CHAR_CODE('srng')
+keyProcedureName = FOUR_CHAR_CODE('dfnm')
+keyStatementRange = FOUR_CHAR_CODE('dfsr')
+keyLocalsNames = FOUR_CHAR_CODE('dfln')
+keyGlobalsNames = FOUR_CHAR_CODE('dfgn')
+keyParamsNames = FOUR_CHAR_CODE('dfpn')

Added: vendor/Python/current/Lib/plat-mac/Carbon/QDOffscreen.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/QDOffscreen.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/QDOffscreen.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,47 @@
+# Generated from 'QDOffscreen.h'
+
+def FOUR_CHAR_CODE(x): return x
+pixPurgeBit = 0
+noNewDeviceBit = 1
+useTempMemBit = 2
+keepLocalBit = 3
+useDistantHdwrMemBit = 4
+useLocalHdwrMemBit = 5
+pixelsPurgeableBit = 6
+pixelsLockedBit = 7
+mapPixBit = 16
+newDepthBit = 17
+alignPixBit = 18
+newRowBytesBit = 19
+reallocPixBit = 20
+clipPixBit = 28
+stretchPixBit = 29
+ditherPixBit = 30
+gwFlagErrBit = 31
+pixPurge = 1L << pixPurgeBit
+noNewDevice = 1L << noNewDeviceBit
+useTempMem = 1L << useTempMemBit
+keepLocal = 1L << keepLocalBit
+useDistantHdwrMem = 1L << useDistantHdwrMemBit
+useLocalHdwrMem = 1L << useLocalHdwrMemBit
+pixelsPurgeable = 1L << pixelsPurgeableBit
+pixelsLocked = 1L << pixelsLockedBit
+kAllocDirectDrawSurface = 1L << 14
+mapPix = 1L << mapPixBit
+newDepth = 1L << newDepthBit
+alignPix = 1L << alignPixBit
+newRowBytes = 1L << newRowBytesBit
+reallocPix = 1L << reallocPixBit
+clipPix = 1L << clipPixBit
+stretchPix = 1L << stretchPixBit
+ditherPix = 1L << ditherPixBit
+gwFlagErr = 1L << gwFlagErrBit
+deviceIsIndirect = (1L << 0)
+deviceNeedsLock = (1L << 1)
+deviceIsStatic = (1L << 2)
+deviceIsExternalBuffer = (1L << 3)
+deviceIsDDSurface = (1L << 4)
+deviceIsDCISurface = (1L << 5)
+deviceIsGDISurface = (1L << 6)
+deviceIsAScreen = (1L << 7)
+deviceIsOverlaySurface = (1L << 8)

Added: vendor/Python/current/Lib/plat-mac/Carbon/Qd.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/Qd.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/Qd.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1 @@
+from _Qd import *

Added: vendor/Python/current/Lib/plat-mac/Carbon/Qdoffs.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/Qdoffs.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/Qdoffs.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1 @@
+from _Qdoffs import *

Added: vendor/Python/current/Lib/plat-mac/Carbon/Qt.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/Qt.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/Qt.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,5 @@
+from _Qt import *
+try:
+    _ = AddFilePreview
+except:
+    raise ImportError, "Old (2.3) _Qt.so module loaded in stead of new (2.4) _Qt.so"

Added: vendor/Python/current/Lib/plat-mac/Carbon/QuickDraw.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/QuickDraw.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/QuickDraw.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,218 @@
+# Generated from 'QuickDraw.h'
+
+
+def FOUR_CHAR_CODE(x): return x
+normal                                          = 0
+bold                                            = 1
+italic                                          = 2
+underline                                       = 4
+outline                                         = 8
+shadow                                          = 0x10
+condense                                        = 0x20
+extend                                          = 0x40
+invalColReq = -1
+srcCopy = 0
+srcOr = 1
+srcXor = 2
+srcBic = 3
+notSrcCopy = 4
+notSrcOr = 5
+notSrcXor = 6
+notSrcBic = 7
+patCopy = 8
+patOr = 9
+patXor = 10
+patBic = 11
+notPatCopy = 12
+notPatOr = 13
+notPatXor = 14
+notPatBic = 15
+grayishTextOr = 49
+hilitetransfermode = 50
+hilite = 50
+blend = 32
+addPin = 33
+addOver = 34
+subPin = 35
+addMax = 37
+adMax = 37
+subOver = 38
+adMin = 39
+ditherCopy = 64
+transparent = 36
+italicBit = 1
+ulineBit = 2
+outlineBit = 3
+shadowBit = 4
+condenseBit = 5
+extendBit = 6
+normalBit = 0
+inverseBit = 1
+redBit = 4
+greenBit = 3
+blueBit = 2
+cyanBit = 8
+magentaBit = 7
+yellowBit = 6
+blackBit = 5
+blackColor = 33
+whiteColor = 30
+redColor = 205
+greenColor = 341
+blueColor = 409
+cyanColor = 273
+magentaColor = 137
+yellowColor = 69
+picLParen = 0
+picRParen = 1
+clutType = 0
+fixedType = 1
+directType = 2
+gdDevType = 0
+interlacedDevice = 2
+hwMirroredDevice = 4
+roundedDevice = 5
+hasAuxMenuBar = 6
+burstDevice = 7
+ext32Device = 8
+ramInit = 10
+mainScreen = 11
+allInit = 12
+screenDevice = 13
+noDriver = 14
+screenActive = 15
+hiliteBit = 7
+pHiliteBit = 0
+defQDColors = 127
+RGBDirect = 16
+baseAddr32 = 4
+sysPatListID = 0
+iBeamCursor = 1
+crossCursor = 2
+plusCursor = 3
+watchCursor = 4
+kQDGrafVerbFrame = 0
+kQDGrafVerbPaint = 1
+kQDGrafVerbErase = 2
+kQDGrafVerbInvert = 3
+kQDGrafVerbFill = 4
+frame = kQDGrafVerbFrame
+paint = kQDGrafVerbPaint
+erase = kQDGrafVerbErase
+invert = kQDGrafVerbInvert
+fill = kQDGrafVerbFill
+chunky = 0
+chunkyPlanar = 1
+planar = 2
+singleDevicesBit = 0
+dontMatchSeedsBit = 1
+allDevicesBit = 2
+singleDevices = 1 << singleDevicesBit
+dontMatchSeeds = 1 << dontMatchSeedsBit
+allDevices = 1 << allDevicesBit
+kPrinterFontStatus = 0
+kPrinterScalingStatus = 1
+kNoConstraint = 0
+kVerticalConstraint = 1
+kHorizontalConstraint = 2
+k1MonochromePixelFormat = 0x00000001
+k2IndexedPixelFormat = 0x00000002
+k4IndexedPixelFormat = 0x00000004
+k8IndexedPixelFormat = 0x00000008
+k16BE555PixelFormat = 0x00000010
+k24RGBPixelFormat = 0x00000018
+k32ARGBPixelFormat = 0x00000020
+k1IndexedGrayPixelFormat = 0x00000021
+k2IndexedGrayPixelFormat = 0x00000022
+k4IndexedGrayPixelFormat = 0x00000024
+k8IndexedGrayPixelFormat = 0x00000028
+k16LE555PixelFormat = FOUR_CHAR_CODE('L555')
+k16LE5551PixelFormat = FOUR_CHAR_CODE('5551')
+k16BE565PixelFormat = FOUR_CHAR_CODE('B565')
+k16LE565PixelFormat = FOUR_CHAR_CODE('L565')
+k24BGRPixelFormat = FOUR_CHAR_CODE('24BG')
+k32BGRAPixelFormat = FOUR_CHAR_CODE('BGRA')
+k32ABGRPixelFormat = FOUR_CHAR_CODE('ABGR')
+k32RGBAPixelFormat = FOUR_CHAR_CODE('RGBA')
+kYUVSPixelFormat = FOUR_CHAR_CODE('yuvs')
+kYUVUPixelFormat = FOUR_CHAR_CODE('yuvu')
+kYVU9PixelFormat = FOUR_CHAR_CODE('YVU9')
+kYUV411PixelFormat = FOUR_CHAR_CODE('Y411')
+kYVYU422PixelFormat = FOUR_CHAR_CODE('YVYU')
+kUYVY422PixelFormat = FOUR_CHAR_CODE('UYVY')
+kYUV211PixelFormat = FOUR_CHAR_CODE('Y211')
+k2vuyPixelFormat = FOUR_CHAR_CODE('2vuy')
+kCursorImageMajorVersion = 0x0001
+kCursorImageMinorVersion = 0x0000
+kQDParseRegionFromTop = (1 << 0)
+kQDParseRegionFromBottom = (1 << 1)
+kQDParseRegionFromLeft = (1 << 2)
+kQDParseRegionFromRight = (1 << 3)
+kQDParseRegionFromTopLeft = kQDParseRegionFromTop | kQDParseRegionFromLeft
+kQDParseRegionFromBottomRight = kQDParseRegionFromBottom | kQDParseRegionFromRight
+kQDRegionToRectsMsgInit = 1
+kQDRegionToRectsMsgParse = 2
+kQDRegionToRectsMsgTerminate = 3
+colorXorXFer = 52
+noiseXFer = 53
+customXFer = 54
+kXFer1PixelAtATime = 0x00000001
+kXFerConvertPixelToRGB32 = 0x00000002
+kCursorComponentsVersion = 0x00010001
+kCursorComponentType = FOUR_CHAR_CODE('curs')
+cursorDoesAnimate = 1L << 0
+cursorDoesHardware = 1L << 1
+cursorDoesUnreadableScreenBits = 1L << 2
+kRenderCursorInHardware = 1L << 0
+kRenderCursorInSoftware = 1L << 1
+kCursorComponentInit = 0x0001
+kCursorComponentGetInfo = 0x0002
+kCursorComponentSetOutputMode = 0x0003
+kCursorComponentSetData = 0x0004
+kCursorComponentReconfigure = 0x0005
+kCursorComponentDraw = 0x0006
+kCursorComponentErase = 0x0007
+kCursorComponentMove = 0x0008
+kCursorComponentAnimate = 0x0009
+kCursorComponentLastReserved = 0x0050
+# Generated from 'QuickDrawText.h'
+
+
+def FOUR_CHAR_CODE(x): return x
+normal                                          = 0
+bold                                            = 1
+italic                                          = 2
+underline                                       = 4
+outline                                         = 8
+shadow                                          = 0x10
+condense                                        = 0x20
+extend                                          = 0x40
+leftCaret = 0
+rightCaret = -1
+kHilite = 1
+smLeftCaret = 0
+smRightCaret = -1
+smHilite = 1
+onlyStyleRun = 0
+leftStyleRun = 1
+rightStyleRun = 2
+middleStyleRun = 3
+smOnlyStyleRun = 0
+smLeftStyleRun = 1
+smRightStyleRun = 2
+smMiddleStyleRun = 3
+truncEnd = 0
+truncMiddle = 0x4000
+smTruncEnd = 0
+smTruncMiddle = 0x4000
+notTruncated = 0
+truncated = 1
+truncErr = -1
+smNotTruncated = 0
+smTruncated = 1
+smTruncErr = -1
+smBreakWord = 0
+smBreakChar = 1
+smBreakOverflow = 2
+tfAntiAlias = 1 << 0
+tfUnicode = 1 << 1

Added: vendor/Python/current/Lib/plat-mac/Carbon/QuickTime.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/QuickTime.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/QuickTime.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,3468 @@
+# Generated from 'Movies.h'
+
+def FOUR_CHAR_CODE(x): return x
+xmlIdentifierUnrecognized = -1
+kControllerMinimum = -0xf777
+notImplementedMusicOSErr      = -2071
+cantSendToSynthesizerOSErr    = -2072
+cantReceiveFromSynthesizerOSErr = -2073
+illegalVoiceAllocationOSErr   = -2074
+illegalPartOSErr              = -2075
+illegalChannelOSErr           = -2076
+illegalKnobOSErr              = -2077
+illegalKnobValueOSErr         = -2078
+illegalInstrumentOSErr        = -2079
+illegalControllerOSErr        = -2080
+midiManagerAbsentOSErr        = -2081
+synthesizerNotRespondingOSErr = -2082
+synthesizerOSErr              = -2083
+illegalNoteChannelOSErr       = -2084
+noteChannelNotAllocatedOSErr  = -2085
+tunePlayerFullOSErr           = -2086
+tuneParseOSErr                = -2087
+MovieFileType = FOUR_CHAR_CODE('MooV')
+MovieScrapType = FOUR_CHAR_CODE('moov')
+MovieResourceType = FOUR_CHAR_CODE('moov')
+MovieForwardPointerResourceType = FOUR_CHAR_CODE('fore')
+MovieBackwardPointerResourceType = FOUR_CHAR_CODE('back')
+MovieResourceAtomType = FOUR_CHAR_CODE('moov')
+MovieDataAtomType = FOUR_CHAR_CODE('mdat')
+FreeAtomType = FOUR_CHAR_CODE('free')
+SkipAtomType = FOUR_CHAR_CODE('skip')
+WideAtomPlaceholderType = FOUR_CHAR_CODE('wide')
+MediaHandlerType = FOUR_CHAR_CODE('mhlr')
+DataHandlerType = FOUR_CHAR_CODE('dhlr')
+VideoMediaType = FOUR_CHAR_CODE('vide')
+SoundMediaType = FOUR_CHAR_CODE('soun')
+TextMediaType = FOUR_CHAR_CODE('text')
+BaseMediaType = FOUR_CHAR_CODE('gnrc')
+MPEGMediaType = FOUR_CHAR_CODE('MPEG')
+MusicMediaType = FOUR_CHAR_CODE('musi')
+TimeCodeMediaType = FOUR_CHAR_CODE('tmcd')
+SpriteMediaType = FOUR_CHAR_CODE('sprt')
+FlashMediaType = FOUR_CHAR_CODE('flsh')
+MovieMediaType = FOUR_CHAR_CODE('moov')
+TweenMediaType = FOUR_CHAR_CODE('twen')
+ThreeDeeMediaType = FOUR_CHAR_CODE('qd3d')
+SkinMediaType = FOUR_CHAR_CODE('skin')
+HandleDataHandlerSubType = FOUR_CHAR_CODE('hndl')
+PointerDataHandlerSubType = FOUR_CHAR_CODE('ptr ')
+NullDataHandlerSubType = FOUR_CHAR_CODE('null')
+ResourceDataHandlerSubType = FOUR_CHAR_CODE('rsrc')
+URLDataHandlerSubType = FOUR_CHAR_CODE('url ')
+WiredActionHandlerType = FOUR_CHAR_CODE('wire')
+VisualMediaCharacteristic = FOUR_CHAR_CODE('eyes')
+AudioMediaCharacteristic = FOUR_CHAR_CODE('ears')
+kCharacteristicCanSendVideo = FOUR_CHAR_CODE('vsnd')
+kCharacteristicProvidesActions = FOUR_CHAR_CODE('actn')
+kCharacteristicNonLinear = FOUR_CHAR_CODE('nonl')
+kCharacteristicCanStep = FOUR_CHAR_CODE('step')
+kCharacteristicHasNoDuration = FOUR_CHAR_CODE('noti')
+kCharacteristicHasSkinData = FOUR_CHAR_CODE('skin')
+kCharacteristicProvidesKeyFocus = FOUR_CHAR_CODE('keyf')
+kUserDataMovieControllerType = FOUR_CHAR_CODE('ctyp')
+kUserDataName = FOUR_CHAR_CODE('name')
+kUserDataTextAlbum = FOUR_CHAR_CODE('\xa9alb')
+kUserDataTextArtist = FOUR_CHAR_CODE('\xa9ART')
+kUserDataTextAuthor = FOUR_CHAR_CODE('\xa9aut')
+kUserDataTextChapter = FOUR_CHAR_CODE('\xa9chp')
+kUserDataTextComment = FOUR_CHAR_CODE('\xa9cmt')
+kUserDataTextComposer = FOUR_CHAR_CODE('\xa9com')
+kUserDataTextCopyright = FOUR_CHAR_CODE('\xa9cpy')
+kUserDataTextCreationDate = FOUR_CHAR_CODE('\xa9day')
+kUserDataTextDescription = FOUR_CHAR_CODE('\xa9des')
+kUserDataTextDirector = FOUR_CHAR_CODE('\xa9dir')
+kUserDataTextDisclaimer = FOUR_CHAR_CODE('\xa9dis')
+kUserDataTextEncodedBy = FOUR_CHAR_CODE('\xa9enc')
+kUserDataTextFullName = FOUR_CHAR_CODE('\xa9nam')
+kUserDataTextGenre = FOUR_CHAR_CODE('\xa9gen')
+kUserDataTextHostComputer = FOUR_CHAR_CODE('\xa9hst')
+kUserDataTextInformation = FOUR_CHAR_CODE('\xa9inf')
+kUserDataTextKeywords = FOUR_CHAR_CODE('\xa9key')
+kUserDataTextMake = FOUR_CHAR_CODE('\xa9mak')
+kUserDataTextModel = FOUR_CHAR_CODE('\xa9mod')
+kUserDataTextOriginalArtist = FOUR_CHAR_CODE('\xa9ope')
+kUserDataTextOriginalFormat = FOUR_CHAR_CODE('\xa9fmt')
+kUserDataTextOriginalSource = FOUR_CHAR_CODE('\xa9src')
+kUserDataTextPerformers = FOUR_CHAR_CODE('\xa9prf')
+kUserDataTextProducer = FOUR_CHAR_CODE('\xa9prd')
+kUserDataTextProduct = FOUR_CHAR_CODE('\xa9PRD')
+kUserDataTextSoftware = FOUR_CHAR_CODE('\xa9swr')
+kUserDataTextSpecialPlaybackRequirements = FOUR_CHAR_CODE('\xa9req')
+kUserDataTextTrack = FOUR_CHAR_CODE('\xa9trk')
+kUserDataTextWarning = FOUR_CHAR_CODE('\xa9wrn')
+kUserDataTextWriter = FOUR_CHAR_CODE('\xa9wrt')
+kUserDataTextURLLink = FOUR_CHAR_CODE('\xa9url')
+kUserDataTextEditDate1 = FOUR_CHAR_CODE('\xa9ed1')
+kUserDataUnicodeBit = 1L << 7
+DoTheRightThing = 0
+kQTNetworkStatusNoNetwork = -2
+kQTNetworkStatusUncertain = -1
+kQTNetworkStatusNotConnected = 0
+kQTNetworkStatusConnected = 1
+kMusicFlagDontPlay2Soft = 1L << 0
+kMusicFlagDontSlaveToMovie = 1L << 1
+dfDontDisplay = 1 << 0
+dfDontAutoScale = 1 << 1
+dfClipToTextBox = 1 << 2
+dfUseMovieBGColor = 1 << 3
+dfShrinkTextBoxToFit = 1 << 4
+dfScrollIn = 1 << 5
+dfScrollOut = 1 << 6
+dfHorizScroll = 1 << 7
+dfReverseScroll = 1 << 8
+dfContinuousScroll = 1 << 9
+dfFlowHoriz = 1 << 10
+dfContinuousKaraoke = 1 << 11
+dfDropShadow = 1 << 12
+dfAntiAlias = 1 << 13
+dfKeyedText = 1 << 14
+dfInverseHilite = 1 << 15
+dfTextColorHilite = 1 << 16
+searchTextDontGoToFoundTime = 1L << 16
+searchTextDontHiliteFoundText = 1L << 17
+searchTextOneTrackOnly = 1L << 18
+searchTextEnabledTracksOnly = 1L << 19
+kTextTextHandle = 1
+kTextTextPtr = 2
+kTextTEStyle = 3
+kTextSelection = 4
+kTextBackColor = 5
+kTextForeColor = 6
+kTextFace = 7
+kTextFont = 8
+kTextSize = 9
+kTextAlignment = 10
+kTextHilite = 11
+kTextDropShadow = 12
+kTextDisplayFlags = 13
+kTextScroll = 14
+kTextRelativeScroll = 15
+kTextHyperTextFace = 16
+kTextHyperTextColor = 17
+kTextKeyEntry = 18
+kTextMouseDown = 19
+kTextTextBox = 20
+kTextEditState = 21
+kTextLength = 22
+k3DMediaRendererEntry = FOUR_CHAR_CODE('rend')
+k3DMediaRendererName = FOUR_CHAR_CODE('name')
+k3DMediaRendererCode = FOUR_CHAR_CODE('rcod')
+movieProgressOpen = 0
+movieProgressUpdatePercent = 1
+movieProgressClose = 2
+progressOpFlatten = 1
+progressOpInsertTrackSegment = 2
+progressOpInsertMovieSegment = 3
+progressOpPaste = 4
+progressOpAddMovieSelection = 5
+progressOpCopy = 6
+progressOpCut = 7
+progressOpLoadMovieIntoRam = 8
+progressOpLoadTrackIntoRam = 9
+progressOpLoadMediaIntoRam = 10
+progressOpImportMovie = 11
+progressOpExportMovie = 12
+mediaQualityDraft = 0x0000
+mediaQualityNormal = 0x0040
+mediaQualityBetter = 0x0080
+mediaQualityBest = 0x00C0
+kQTEventPayloadIsQTList = 1L << 0
+kActionMovieSetVolume = 1024
+kActionMovieSetRate = 1025
+kActionMovieSetLoopingFlags = 1026
+kActionMovieGoToTime = 1027
+kActionMovieGoToTimeByName = 1028
+kActionMovieGoToBeginning = 1029
+kActionMovieGoToEnd = 1030
+kActionMovieStepForward = 1031
+kActionMovieStepBackward = 1032
+kActionMovieSetSelection = 1033
+kActionMovieSetSelectionByName = 1034
+kActionMoviePlaySelection = 1035
+kActionMovieSetLanguage = 1036
+kActionMovieChanged = 1037
+kActionMovieRestartAtTime = 1038
+kActionMovieGotoNextChapter = 1039
+kActionMovieGotoPreviousChapter = 1040
+kActionMovieGotoFirstChapter = 1041
+kActionMovieGotoLastChapter = 1042
+kActionMovieGotoChapterByIndex = 1043
+kActionMovieSetScale = 1044
+kActionTrackSetVolume = 2048
+kActionTrackSetBalance = 2049
+kActionTrackSetEnabled = 2050
+kActionTrackSetMatrix = 2051
+kActionTrackSetLayer = 2052
+kActionTrackSetClip = 2053
+kActionTrackSetCursor = 2054
+kActionTrackSetGraphicsMode = 2055
+kActionTrackSetIdleFrequency = 2056
+kActionTrackSetBassTreble = 2057
+kActionSpriteSetMatrix = 3072
+kActionSpriteSetImageIndex = 3073
+kActionSpriteSetVisible = 3074
+kActionSpriteSetLayer = 3075
+kActionSpriteSetGraphicsMode = 3076
+kActionSpritePassMouseToCodec = 3078
+kActionSpriteClickOnCodec = 3079
+kActionSpriteTranslate = 3080
+kActionSpriteScale = 3081
+kActionSpriteRotate = 3082
+kActionSpriteStretch = 3083
+kActionSpriteSetCanBeHitTested = 3094
+kActionQTVRSetPanAngle = 4096
+kActionQTVRSetTiltAngle = 4097
+kActionQTVRSetFieldOfView = 4098
+kActionQTVRShowDefaultView = 4099
+kActionQTVRGoToNodeID = 4100
+kActionQTVREnableHotSpot = 4101
+kActionQTVRShowHotSpots = 4102
+kActionQTVRTranslateObject = 4103
+kActionQTVRSetViewState = 4109
+kActionMusicPlayNote = 5120
+kActionMusicSetController = 5121
+kActionCase = 6144
+kActionWhile = 6145
+kActionGoToURL = 6146
+kActionSendQTEventToSprite = 6147
+kActionDebugStr = 6148
+kActionPushCurrentTime = 6149
+kActionPushCurrentTimeWithLabel = 6150
+kActionPopAndGotoTopTime = 6151
+kActionPopAndGotoLabeledTime = 6152
+kActionStatusString = 6153
+kActionSendQTEventToTrackObject = 6154
+kActionAddChannelSubscription = 6155
+kActionRemoveChannelSubscription = 6156
+kActionOpenCustomActionHandler = 6157
+kActionDoScript = 6158
+kActionDoCompressedActions = 6159
+kActionSendAppMessage = 6160
+kActionLoadComponent = 6161
+kActionSetFocus = 6162
+kActionDontPassKeyEvent = 6163
+kActionSetRandomSeed = 6164
+kActionSpriteTrackSetVariable = 7168
+kActionSpriteTrackNewSprite = 7169
+kActionSpriteTrackDisposeSprite = 7170
+kActionSpriteTrackSetVariableToString = 7171
+kActionSpriteTrackConcatVariables = 7172
+kActionSpriteTrackSetVariableToMovieURL = 7173
+kActionSpriteTrackSetVariableToMovieBaseURL = 7174
+kActionSpriteTrackSetAllSpritesHitTestingMode = 7181
+kActionSpriteTrackNewImage = 7182
+kActionSpriteTrackDisposeImage = 7183
+kActionApplicationNumberAndString = 8192
+kActionQD3DNamedObjectTranslateTo = 9216
+kActionQD3DNamedObjectScaleTo = 9217
+kActionQD3DNamedObjectRotateTo = 9218
+kActionFlashTrackSetPan = 10240
+kActionFlashTrackSetZoom = 10241
+kActionFlashTrackSetZoomRect = 10242
+kActionFlashTrackGotoFrameNumber = 10243
+kActionFlashTrackGotoFrameLabel = 10244
+kActionFlashTrackSetFlashVariable = 10245
+kActionFlashTrackDoButtonActions = 10246
+kActionMovieTrackAddChildMovie = 11264
+kActionMovieTrackLoadChildMovie = 11265
+kActionMovieTrackLoadChildMovieWithQTListParams = 11266
+kActionTextTrackPasteText = 12288
+kActionTextTrackSetTextBox = 12291
+kActionTextTrackSetTextStyle = 12292
+kActionTextTrackSetSelection = 12293
+kActionTextTrackSetBackgroundColor = 12294
+kActionTextTrackSetForegroundColor = 12295
+kActionTextTrackSetFace = 12296
+kActionTextTrackSetFont = 12297
+kActionTextTrackSetSize = 12298
+kActionTextTrackSetAlignment = 12299
+kActionTextTrackSetHilite = 12300
+kActionTextTrackSetDropShadow = 12301
+kActionTextTrackSetDisplayFlags = 12302
+kActionTextTrackSetScroll = 12303
+kActionTextTrackRelativeScroll = 12304
+kActionTextTrackFindText = 12305
+kActionTextTrackSetHyperTextFace = 12306
+kActionTextTrackSetHyperTextColor = 12307
+kActionTextTrackKeyEntry = 12308
+kActionTextTrackMouseDown = 12309
+kActionTextTrackSetEditable = 12310
+kActionListAddElement = 13312
+kActionListRemoveElements = 13313
+kActionListSetElementValue = 13314
+kActionListPasteFromXML = 13315
+kActionListSetMatchingFromXML = 13316
+kActionListSetFromURL = 13317
+kActionListExchangeLists = 13318
+kActionListServerQuery = 13319
+kOperandExpression = 1
+kOperandConstant = 2
+kOperandSubscribedToChannel = 3
+kOperandUniqueCustomActionHandlerID = 4
+kOperandCustomActionHandlerIDIsOpen = 5
+kOperandConnectionSpeed = 6
+kOperandGMTDay = 7
+kOperandGMTMonth = 8
+kOperandGMTYear = 9
+kOperandGMTHours = 10
+kOperandGMTMinutes = 11
+kOperandGMTSeconds = 12
+kOperandLocalDay = 13
+kOperandLocalMonth = 14
+kOperandLocalYear = 15
+kOperandLocalHours = 16
+kOperandLocalMinutes = 17
+kOperandLocalSeconds = 18
+kOperandRegisteredForQuickTimePro = 19
+kOperandPlatformRunningOn = 20
+kOperandQuickTimeVersion = 21
+kOperandComponentVersion = 22
+kOperandOriginalHandlerRefcon = 23
+kOperandTicks = 24
+kOperandMaxLoadedTimeInMovie = 25
+kOperandEventParameter = 26
+kOperandFreeMemory = 27
+kOperandNetworkStatus = 28
+kOperandQuickTimeVersionRegistered = 29
+kOperandSystemVersion = 30
+kOperandMovieVolume = 1024
+kOperandMovieRate = 1025
+kOperandMovieIsLooping = 1026
+kOperandMovieLoopIsPalindrome = 1027
+kOperandMovieTime = 1028
+kOperandMovieDuration = 1029
+kOperandMovieTimeScale = 1030
+kOperandMovieWidth = 1031
+kOperandMovieHeight = 1032
+kOperandMovieLoadState = 1033
+kOperandMovieTrackCount = 1034
+kOperandMovieIsActive = 1035
+kOperandMovieName = 1036
+kOperandMovieID = 1037
+kOperandMovieChapterCount = 1038
+kOperandMovieChapterIndex = 1039
+kOperandMovieChapterName = 1040
+kOperandMovieChapterNameByIndex = 1041
+kOperandMovieChapterIndexByName = 1042
+kOperandMovieAnnotation = 1043
+kOperandMovieConnectionFlags = 1044
+kOperandMovieConnectionString = 1045
+kOperandTrackVolume = 2048
+kOperandTrackBalance = 2049
+kOperandTrackEnabled = 2050
+kOperandTrackLayer = 2051
+kOperandTrackWidth = 2052
+kOperandTrackHeight = 2053
+kOperandTrackDuration = 2054
+kOperandTrackName = 2055
+kOperandTrackID = 2056
+kOperandTrackIdleFrequency = 2057
+kOperandTrackBass = 2058
+kOperandTrackTreble = 2059
+kOperandSpriteBoundsLeft = 3072
+kOperandSpriteBoundsTop = 3073
+kOperandSpriteBoundsRight = 3074
+kOperandSpriteBoundsBottom = 3075
+kOperandSpriteImageIndex = 3076
+kOperandSpriteVisible = 3077
+kOperandSpriteLayer = 3078
+kOperandSpriteTrackVariable = 3079
+kOperandSpriteTrackNumSprites = 3080
+kOperandSpriteTrackNumImages = 3081
+kOperandSpriteID = 3082
+kOperandSpriteIndex = 3083
+kOperandSpriteFirstCornerX = 3084
+kOperandSpriteFirstCornerY = 3085
+kOperandSpriteSecondCornerX = 3086
+kOperandSpriteSecondCornerY = 3087
+kOperandSpriteThirdCornerX = 3088
+kOperandSpriteThirdCornerY = 3089
+kOperandSpriteFourthCornerX = 3090
+kOperandSpriteFourthCornerY = 3091
+kOperandSpriteImageRegistrationPointX = 3092
+kOperandSpriteImageRegistrationPointY = 3093
+kOperandSpriteTrackSpriteIDAtPoint = 3094
+kOperandSpriteName = 3095
+kOperandSpriteCanBeHitTested = 3105
+kOperandSpriteTrackAllSpritesHitTestingMode = 3106
+kOperandSpriteTrackImageIDByIndex = 3107
+kOperandSpriteTrackImageIndexByID = 3108
+kOperandQTVRPanAngle = 4096
+kOperandQTVRTiltAngle = 4097
+kOperandQTVRFieldOfView = 4098
+kOperandQTVRNodeID = 4099
+kOperandQTVRHotSpotsVisible = 4100
+kOperandQTVRViewCenterH = 4101
+kOperandQTVRViewCenterV = 4102
+kOperandQTVRViewStateCount = 4103
+kOperandQTVRViewState = 4104
+kOperandMouseLocalHLoc = 5120
+kOperandMouseLocalVLoc = 5121
+kOperandKeyIsDown = 5122
+kOperandRandom = 5123
+kOperandCanHaveFocus = 5124
+kOperandHasFocus = 5125
+kOperandTextTrackEditable = 6144
+kOperandTextTrackCopyText = 6145
+kOperandTextTrackStartSelection = 6146
+kOperandTextTrackEndSelection = 6147
+kOperandTextTrackTextBoxLeft = 6148
+kOperandTextTrackTextBoxTop = 6149
+kOperandTextTrackTextBoxRight = 6150
+kOperandTextTrackTextBoxBottom = 6151
+kOperandTextTrackTextLength = 6152
+kOperandListCountElements = 7168
+kOperandListGetElementPathByIndex = 7169
+kOperandListGetElementValue = 7170
+kOperandListCopyToXML = 7171
+kOperandSin = 8192
+kOperandCos = 8193
+kOperandTan = 8194
+kOperandATan = 8195
+kOperandATan2 = 8196
+kOperandDegreesToRadians = 8197
+kOperandRadiansToDegrees = 8198
+kOperandSquareRoot = 8199
+kOperandExponent = 8200
+kOperandLog = 8201
+kOperandFlashTrackVariable = 9216
+kOperandStringLength = 10240
+kOperandStringCompare = 10241
+kOperandStringSubString = 10242
+kOperandStringConcat = 10243
+kFirstMovieAction = kActionMovieSetVolume
+kLastMovieAction = kActionMovieSetScale
+kFirstTrackAction = kActionTrackSetVolume
+kLastTrackAction = kActionTrackSetBassTreble
+kFirstSpriteAction = kActionSpriteSetMatrix
+kLastSpriteAction = kActionSpriteSetCanBeHitTested
+kFirstQTVRAction = kActionQTVRSetPanAngle
+kLastQTVRAction = kActionQTVRSetViewState
+kFirstMusicAction = kActionMusicPlayNote
+kLastMusicAction = kActionMusicSetController
+kFirstSystemAction = kActionCase
+kLastSystemAction = kActionSetRandomSeed
+kFirstSpriteTrackAction = kActionSpriteTrackSetVariable
+kLastSpriteTrackAction = kActionSpriteTrackDisposeImage
+kFirstApplicationAction = kActionApplicationNumberAndString
+kLastApplicationAction = kActionApplicationNumberAndString
+kFirstQD3DNamedObjectAction = kActionQD3DNamedObjectTranslateTo
+kLastQD3DNamedObjectAction = kActionQD3DNamedObjectRotateTo
+kFirstFlashTrackAction = kActionFlashTrackSetPan
+kLastFlashTrackAction = kActionFlashTrackDoButtonActions
+kFirstMovieTrackAction = kActionMovieTrackAddChildMovie
+kLastMovieTrackAction = kActionMovieTrackLoadChildMovieWithQTListParams
+kFirstTextTrackAction = kActionTextTrackPasteText
+kLastTextTrackAction = kActionTextTrackSetEditable
+kFirstMultiTargetAction = kActionListAddElement
+kLastMultiTargetAction = kActionListServerQuery
+kFirstAction = kFirstMovieAction
+kLastAction = kLastMultiTargetAction
+kTargetMovie = FOUR_CHAR_CODE('moov')
+kTargetMovieName = FOUR_CHAR_CODE('mona')
+kTargetMovieID = FOUR_CHAR_CODE('moid')
+kTargetRootMovie = FOUR_CHAR_CODE('moro')
+kTargetParentMovie = FOUR_CHAR_CODE('mopa')
+kTargetChildMovieTrackName = FOUR_CHAR_CODE('motn')
+kTargetChildMovieTrackID = FOUR_CHAR_CODE('moti')
+kTargetChildMovieTrackIndex = FOUR_CHAR_CODE('motx')
+kTargetChildMovieMovieName = FOUR_CHAR_CODE('momn')
+kTargetChildMovieMovieID = FOUR_CHAR_CODE('momi')
+kTargetTrackName = FOUR_CHAR_CODE('trna')
+kTargetTrackID = FOUR_CHAR_CODE('trid')
+kTargetTrackType = FOUR_CHAR_CODE('trty')
+kTargetTrackIndex = FOUR_CHAR_CODE('trin')
+kTargetSpriteName = FOUR_CHAR_CODE('spna')
+kTargetSpriteID = FOUR_CHAR_CODE('spid')
+kTargetSpriteIndex = FOUR_CHAR_CODE('spin')
+kTargetQD3DNamedObjectName = FOUR_CHAR_CODE('nana')
+kTargetCurrentQTEventParams = FOUR_CHAR_CODE('evpa')
+kQTEventType = FOUR_CHAR_CODE('evnt')
+kAction = FOUR_CHAR_CODE('actn')
+kWhichAction = FOUR_CHAR_CODE('whic')
+kActionParameter = FOUR_CHAR_CODE('parm')
+kActionTarget = FOUR_CHAR_CODE('targ')
+kActionFlags = FOUR_CHAR_CODE('flag')
+kActionParameterMinValue = FOUR_CHAR_CODE('minv')
+kActionParameterMaxValue = FOUR_CHAR_CODE('maxv')
+kActionListAtomType = FOUR_CHAR_CODE('list')
+kExpressionContainerAtomType = FOUR_CHAR_CODE('expr')
+kConditionalAtomType = FOUR_CHAR_CODE('test')
+kOperatorAtomType = FOUR_CHAR_CODE('oper')
+kOperandAtomType = FOUR_CHAR_CODE('oprn')
+kCommentAtomType = FOUR_CHAR_CODE('why ')
+kCustomActionHandler = FOUR_CHAR_CODE('cust')
+kCustomHandlerID = FOUR_CHAR_CODE('id  ')
+kCustomHandlerDesc = FOUR_CHAR_CODE('desc')
+kQTEventRecordAtomType = FOUR_CHAR_CODE('erec')
+kQTEventMouseClick = FOUR_CHAR_CODE('clik')
+kQTEventMouseClickEnd = FOUR_CHAR_CODE('cend')
+kQTEventMouseClickEndTriggerButton = FOUR_CHAR_CODE('trig')
+kQTEventMouseEnter = FOUR_CHAR_CODE('entr')
+kQTEventMouseExit = FOUR_CHAR_CODE('exit')
+kQTEventMouseMoved = FOUR_CHAR_CODE('move')
+kQTEventFrameLoaded = FOUR_CHAR_CODE('fram')
+kQTEventIdle = FOUR_CHAR_CODE('idle')
+kQTEventKey = FOUR_CHAR_CODE('key ')
+kQTEventMovieLoaded = FOUR_CHAR_CODE('load')
+kQTEventRequestToModifyMovie = FOUR_CHAR_CODE('reqm')
+kQTEventListReceived = FOUR_CHAR_CODE('list')
+kQTEventKeyUp = FOUR_CHAR_CODE('keyU')
+kActionFlagActionIsDelta = 1L << 1
+kActionFlagParameterWrapsAround = 1L << 2
+kActionFlagActionIsToggle = 1L << 3
+kStatusStringIsURLLink = 1L << 1
+kStatusStringIsStreamingStatus = 1L << 2
+kStatusHasCodeNumber = 1L << 3
+kStatusIsError = 1L << 4
+kScriptIsUnknownType = 1L << 0
+kScriptIsJavaScript = 1L << 1
+kScriptIsLingoEvent = 1L << 2
+kScriptIsVBEvent = 1L << 3
+kScriptIsProjectorCommand = 1L << 4
+kScriptIsAppleScript = 1L << 5
+kQTRegistrationDialogTimeOutFlag = 1 << 0
+kQTRegistrationDialogShowDialog = 1 << 1
+kQTRegistrationDialogForceDialog = 1 << 2
+kOperatorAdd = FOUR_CHAR_CODE('add ')
+kOperatorSubtract = FOUR_CHAR_CODE('sub ')
+kOperatorMultiply = FOUR_CHAR_CODE('mult')
+kOperatorDivide = FOUR_CHAR_CODE('div ')
+kOperatorOr = FOUR_CHAR_CODE('or  ')
+kOperatorAnd = FOUR_CHAR_CODE('and ')
+kOperatorNot = FOUR_CHAR_CODE('not ')
+kOperatorLessThan = FOUR_CHAR_CODE('<   ')
+kOperatorLessThanEqualTo = FOUR_CHAR_CODE('<=  ')
+kOperatorEqualTo = FOUR_CHAR_CODE('=   ')
+kOperatorNotEqualTo = FOUR_CHAR_CODE('!=  ')
+kOperatorGreaterThan = FOUR_CHAR_CODE('>   ')
+kOperatorGreaterThanEqualTo = FOUR_CHAR_CODE('>=  ')
+kOperatorModulo = FOUR_CHAR_CODE('mod ')
+kOperatorIntegerDivide = FOUR_CHAR_CODE('idiv')
+kOperatorAbsoluteValue = FOUR_CHAR_CODE('abs ')
+kOperatorNegate = FOUR_CHAR_CODE('neg ')
+kPlatformMacintosh = 1
+kPlatformWindows = 2
+kSystemIsWindows9x = 0x00010000
+kSystemIsWindowsNT = 0x00020000
+kMediaPropertyNonLinearAtomType = FOUR_CHAR_CODE('nonl')
+kMediaPropertyHasActions = 105
+loopTimeBase = 1
+palindromeLoopTimeBase = 2
+maintainTimeBaseZero = 4
+triggerTimeFwd = 0x0001
+triggerTimeBwd = 0x0002
+triggerTimeEither = 0x0003
+triggerRateLT = 0x0004
+triggerRateGT = 0x0008
+triggerRateEqual = 0x0010
+triggerRateLTE = triggerRateLT | triggerRateEqual
+triggerRateGTE = triggerRateGT | triggerRateEqual
+triggerRateNotEqual = triggerRateGT | triggerRateEqual | triggerRateLT
+triggerRateChange = 0
+triggerAtStart = 0x0001
+triggerAtStop = 0x0002
+timeBaseBeforeStartTime = 1
+timeBaseAfterStopTime = 2
+callBackAtTime = 1
+callBackAtRate = 2
+callBackAtTimeJump = 3
+callBackAtExtremes = 4
+callBackAtTimeBaseDisposed = 5
+callBackAtInterrupt = 0x8000
+callBackAtDeferredTask = 0x4000
+qtcbNeedsRateChanges = 1
+qtcbNeedsTimeChanges = 2
+qtcbNeedsStartStopChanges = 4
+keepInRam = 1 << 0
+unkeepInRam = 1 << 1
+flushFromRam = 1 << 2
+loadForwardTrackEdits = 1 << 3
+loadBackwardTrackEdits = 1 << 4
+newMovieActive = 1 << 0
+newMovieDontResolveDataRefs = 1 << 1
+newMovieDontAskUnresolvedDataRefs = 1 << 2
+newMovieDontAutoAlternates = 1 << 3
+newMovieDontUpdateForeBackPointers = 1 << 4
+newMovieDontAutoUpdateClock = 1 << 5
+newMovieAsyncOK = 1 << 8
+newMovieIdleImportOK = 1 << 10
+newMovieDontInteractWithUser = 1 << 11
+trackUsageInMovie = 1 << 1
+trackUsageInPreview = 1 << 2
+trackUsageInPoster = 1 << 3
+mediaSampleNotSync = 1 << 0
+mediaSampleShadowSync = 1 << 1
+pasteInParallel = 1 << 0
+showUserSettingsDialog = 1 << 1
+movieToFileOnlyExport = 1 << 2
+movieFileSpecValid = 1 << 3
+nextTimeMediaSample = 1 << 0
+nextTimeMediaEdit = 1 << 1
+nextTimeTrackEdit = 1 << 2
+nextTimeSyncSample = 1 << 3
+nextTimeStep = 1 << 4
+nextTimeEdgeOK = 1 << 14
+nextTimeIgnoreActiveSegment = 1 << 15
+createMovieFileDeleteCurFile = 1L << 31
+createMovieFileDontCreateMovie = 1L << 30
+createMovieFileDontOpenFile = 1L << 29
+createMovieFileDontCreateResFile = 1L << 28
+flattenAddMovieToDataFork = 1L << 0
+flattenActiveTracksOnly = 1L << 2
+flattenDontInterleaveFlatten = 1L << 3
+flattenFSSpecPtrIsDataRefRecordPtr = 1L << 4
+flattenCompressMovieResource = 1L << 5
+flattenForceMovieResourceBeforeMovieData = 1L << 6
+movieInDataForkResID = -1
+mcTopLeftMovie = 1 << 0
+mcScaleMovieToFit = 1 << 1
+mcWithBadge = 1 << 2
+mcNotVisible = 1 << 3
+mcWithFrame = 1 << 4
+movieScrapDontZeroScrap = 1 << 0
+movieScrapOnlyPutMovie = 1 << 1
+dataRefSelfReference = 1 << 0
+dataRefWasNotResolved = 1 << 1
+kMovieAnchorDataRefIsDefault = 1 << 0
+hintsScrubMode = 1 << 0
+hintsLoop = 1 << 1
+hintsDontPurge = 1 << 2
+hintsUseScreenBuffer = 1 << 5
+hintsAllowInterlace = 1 << 6
+hintsUseSoundInterp = 1 << 7
+hintsHighQuality = 1 << 8
+hintsPalindrome = 1 << 9
+hintsInactive = 1 << 11
+hintsOffscreen = 1 << 12
+hintsDontDraw = 1 << 13
+hintsAllowBlacklining = 1 << 14
+hintsDontUseVideoOverlaySurface = 1 << 16
+hintsIgnoreBandwidthRestrictions = 1 << 17
+hintsPlayingEveryFrame = 1 << 18
+hintsAllowDynamicResize = 1 << 19
+hintsSingleField = 1 << 20
+hintsNoRenderingTimeOut = 1 << 21
+hintsFlushVideoInsteadOfDirtying = 1 << 22
+hintsEnableSubPixelPositioning = 1L << 23
+mediaHandlerFlagBaseClient = 1
+movieTrackMediaType = 1 << 0
+movieTrackCharacteristic = 1 << 1
+movieTrackEnabledOnly = 1 << 2
+kMovieControlOptionHideController = (1L << 0)
+kMovieControlOptionLocateTopLeft = (1L << 1)
+kMovieControlOptionEnableEditing = (1L << 2)
+kMovieControlOptionHandleEditingHI = (1L << 3)
+kMovieControlOptionSetKeysEnabled = (1L << 4)
+kMovieControlOptionManuallyIdled = (1L << 5)
+kMovieControlDataMovieController = FOUR_CHAR_CODE('mc  ')
+kMovieControlDataMovie = FOUR_CHAR_CODE('moov')
+kMovieControlDataManualIdling = FOUR_CHAR_CODE('manu')
+movieDrawingCallWhenChanged = 0
+movieDrawingCallAlways = 1
+kQTCloneShareSamples = 1 << 0
+kQTCloneDontCopyEdits = 1 << 1
+kGetMovieImporterValidateToFind = 1L << 0
+kGetMovieImporterAllowNewFile = 1L << 1
+kGetMovieImporterDontConsiderGraphicsImporters = 1L << 2
+kGetMovieImporterDontConsiderFileOnlyImporters = 1L << 6
+kGetMovieImporterAutoImportOnly = 1L << 10
+kQTGetMIMETypeInfoIsQuickTimeMovieType = FOUR_CHAR_CODE('moov')
+kQTGetMIMETypeInfoIsUnhelpfulType = FOUR_CHAR_CODE('dumb')
+kQTCopyUserDataReplace = FOUR_CHAR_CODE('rplc')
+kQTCopyUserDataMerge = FOUR_CHAR_CODE('merg')
+kMovieLoadStateError = -1L
+kMovieLoadStateLoading = 1000
+kMovieLoadStateLoaded = 2000
+kMovieLoadStatePlayable = 10000
+kMovieLoadStatePlaythroughOK = 20000
+kMovieLoadStateComplete = 100000L
+kQTDontUseDataToFindImporter = 1L << 0
+kQTDontLookForMovieImporterIfGraphicsImporterFound = 1L << 1
+kQTAllowOpeningStillImagesAsMovies = 1L << 2
+kQTAllowImportersThatWouldCreateNewFile = 1L << 3
+kQTAllowAggressiveImporters = 1L << 4
+preloadAlways = 1L << 0
+preloadOnlyIfEnabled = 1L << 1
+fullScreenHideCursor = 1L << 0
+fullScreenAllowEvents = 1L << 1
+fullScreenDontChangeMenuBar = 1L << 2
+fullScreenPreflightSize = 1L << 3
+movieExecuteWiredActionDontExecute = 1L << 0
+kRefConNavigationNext = 0
+kRefConNavigationPrevious = 1
+kRefConPropertyCanHaveFocus = 1
+kRefConPropertyHasFocus = 2
+kTrackFocusCanEditFlag = FOUR_CHAR_CODE('kedt')
+kTrackDefaultFocusFlags = FOUR_CHAR_CODE('kfoc')
+kTrackFocusDefaultRefcon = FOUR_CHAR_CODE('kref')
+kTrackFocusOn = 1
+kTrackHandlesTabs = 2
+kFlashTrackPropertyAcceptAllClicks = FOUR_CHAR_CODE('clik')
+kBackgroundSpriteLayerNum = 32767
+kSpritePropertyMatrix = 1
+kSpritePropertyImageDescription = 2
+kSpritePropertyImageDataPtr = 3
+kSpritePropertyVisible = 4
+kSpritePropertyLayer = 5
+kSpritePropertyGraphicsMode = 6
+kSpritePropertyImageDataSize = 7
+kSpritePropertyActionHandlingSpriteID = 8
+kSpritePropertyCanBeHitTested = 9
+kSpritePropertyImageIndex = 100
+kSpriteTrackPropertyBackgroundColor = 101
+kSpriteTrackPropertyOffscreenBitDepth = 102
+kSpriteTrackPropertySampleFormat = 103
+kSpriteTrackPropertyScaleSpritesToScaleWorld = 104
+kSpriteTrackPropertyHasActions = 105
+kSpriteTrackPropertyVisible = 106
+kSpriteTrackPropertyQTIdleEventsFrequency = 107
+kSpriteTrackPropertyAllSpritesHitTestingMode = 108
+kSpriteTrackPropertyPreferredDepthInterpretationMode = 109
+kSpriteImagePropertyRegistrationPoint = 1000
+kSpriteImagePropertyGroupID = 1001
+kSpriteTrackPreferredDepthCompatibilityMode = 0
+kSpriteTrackPreferredDepthModernMode = 1
+kSpriteHitTestUseSpritesOwnPropertiesMode = 0
+kSpriteHitTestTreatAllSpritesAsHitTestableMode = 1
+kSpriteHitTestTreatAllSpritesAsNotHitTestableMode = 2
+kNoQTIdleEvents = -1
+kGetSpriteWorldInvalidRegionAndLeaveIntact = -1L
+kGetSpriteWorldInvalidRegionAndThenSetEmpty = -2L
+kOnlyDrawToSpriteWorld = 1L << 0
+kSpriteWorldPreflight = 1L << 1
+kSpriteWorldDidDraw = 1L << 0
+kSpriteWorldNeedsToDraw = 1L << 1
+kKeyFrameAndSingleOverride = 1L << 1
+kKeyFrameAndAllOverrides = 1L << 2
+kScaleSpritesToScaleWorld = 1L << 1
+kSpriteWorldHighQuality = 1L << 2
+kSpriteWorldDontAutoInvalidate = 1L << 3
+kSpriteWorldInvisible = 1L << 4
+kSpriteWorldDirtyInsteadOfFlush = 1L << 5
+kParentAtomIsContainer = 0
+kTweenRecordNoFlags = 0
+kTweenRecordIsAtInterruptTime = 0x00000001
+kEffectNameAtom = FOUR_CHAR_CODE('name')
+kEffectTypeAtom = FOUR_CHAR_CODE('type')
+kEffectManufacturerAtom = FOUR_CHAR_CODE('manu')
+pdActionConfirmDialog = 1
+pdActionSetAppleMenu = 2
+pdActionSetEditMenu = 3
+pdActionGetDialogValues = 4
+pdActionSetPreviewUserItem = 5
+pdActionSetPreviewPicture = 6
+pdActionSetColorPickerEventProc = 7
+pdActionSetDialogTitle = 8
+pdActionGetSubPanelMenu = 9
+pdActionActivateSubPanel = 10
+pdActionConductStopAlert = 11
+pdActionModelessCallback = 12
+pdActionFetchPreview = 13
+pdActionSetDialogSettings = 14
+pdActionGetDialogSettings = 15
+pdActionGetNextSample = 16
+pdActionGetPreviousSample = 17
+pdActionCompactSample = 18
+pdActionSetEditCallout = 19
+pdActionSetSampleTime = 20
+pdActionDoEditCommand = 21
+pdActionGetSubPanelMenuValue = 22
+pdActionCustomNewControl = 23
+pdActionCustomDisposeControl = 24
+pdActionCustomPositionControl = 25
+pdActionCustomShowHideControl = 26
+pdActionCustomHandleEvent = 27
+pdActionCustomSetFocus = 28
+pdActionCustomSetEditMenu = 29
+pdActionCustomSetPreviewPicture = 30
+pdActionCustomSetEditCallout = 31
+pdActionCustomGetEnableValue = 32
+pdActionCustomSetSampleTime = 33
+pdActionCustomGetValue = 34
+pdActionCustomDoEditCommand = 35
+pdSampleTimeDisplayOptionsNone = 0x00000000
+pdActionFocusOff = 0
+pdActionFocusFirst = 1
+pdActionFocusLast = 2
+pdActionFocusForward = 3
+pdActionFocusBackward = 4
+elOptionsIncludeNoneInList = 0x00000001
+pdOptionsCollectOneValue = 0x00000001
+pdOptionsAllowOptionalInterpolations = 0x00000002
+pdOptionsModalDialogBox = 0x00000004
+pdOptionsEditCurrentEffectOnly = 0x00000008
+pdOptionsHidePreview = 0x00000010
+effectIsRealtime = 0
+kAccessKeyAtomType = FOUR_CHAR_CODE('acky')
+kAccessKeySystemFlag = 1L << 0
+ConnectionSpeedPrefsType = FOUR_CHAR_CODE('cspd')
+BandwidthManagementPrefsType = FOUR_CHAR_CODE('bwmg')
+kQTIdlePriority = 10
+kQTNonRealTimePriority = 20
+kQTRealTimeSharedPriority = 25
+kQTRealTimePriority = 30
+kQTBandwidthNotifyNeedToStop = 1L << 0
+kQTBandwidthNotifyGoodToGo = 1L << 1
+kQTBandwidthChangeRequest = 1L << 2
+kQTBandwidthQueueRequest = 1L << 3
+kQTBandwidthScheduledRequest = 1L << 4
+kQTBandwidthVoluntaryRelease = 1L << 5
+kITextRemoveEverythingBut = 0 << 1
+kITextRemoveLeaveSuggestedAlternate = 1 << 1
+kITextAtomType = FOUR_CHAR_CODE('itxt')
+kITextStringAtomType = FOUR_CHAR_CODE('text')
+kQTParseTextHREFText = FOUR_CHAR_CODE('text')
+kQTParseTextHREFBaseURL = FOUR_CHAR_CODE('burl')
+kQTParseTextHREFClickPoint = FOUR_CHAR_CODE('clik')
+kQTParseTextHREFUseAltDelim = FOUR_CHAR_CODE('altd')
+kQTParseTextHREFDelimiter = FOUR_CHAR_CODE('delm')
+kQTParseTextHREFRecomposeHREF = FOUR_CHAR_CODE('rhrf')
+kQTParseTextHREFURL = FOUR_CHAR_CODE('url ')
+kQTParseTextHREFTarget = FOUR_CHAR_CODE('targ')
+kQTParseTextHREFChapter = FOUR_CHAR_CODE('chap')
+kQTParseTextHREFIsAutoHREF = FOUR_CHAR_CODE('auto')
+kQTParseTextHREFIsServerMap = FOUR_CHAR_CODE('smap')
+kQTParseTextHREFHREF = FOUR_CHAR_CODE('href')
+kQTParseTextHREFEMBEDArgs = FOUR_CHAR_CODE('mbed')
+kTrackReferenceChapterList = FOUR_CHAR_CODE('chap')
+kTrackReferenceTimeCode = FOUR_CHAR_CODE('tmcd')
+kTrackReferenceModifier = FOUR_CHAR_CODE('ssrc')
+kTrackModifierInput = 0x696E
+kTrackModifierType = 0x7479
+kTrackModifierReference = FOUR_CHAR_CODE('ssrc')
+kTrackModifierObjectID = FOUR_CHAR_CODE('obid')
+kTrackModifierInputName = FOUR_CHAR_CODE('name')
+kInputMapSubInputID = FOUR_CHAR_CODE('subi')
+kTrackModifierTypeMatrix = 1
+kTrackModifierTypeClip = 2
+kTrackModifierTypeGraphicsMode = 5
+kTrackModifierTypeVolume = 3
+kTrackModifierTypeBalance = 4
+kTrackModifierTypeImage = FOUR_CHAR_CODE('vide')
+kTrackModifierObjectMatrix = 6
+kTrackModifierObjectGraphicsMode = 7
+kTrackModifierType3d4x4Matrix = 8
+kTrackModifierCameraData = 9
+kTrackModifierSoundLocalizationData = 10
+kTrackModifierObjectImageIndex = 11
+kTrackModifierObjectLayer = 12
+kTrackModifierObjectVisible = 13
+kTrackModifierAngleAspectCamera = 14
+kTrackModifierPanAngle = FOUR_CHAR_CODE('pan ')
+kTrackModifierTiltAngle = FOUR_CHAR_CODE('tilt')
+kTrackModifierVerticalFieldOfViewAngle = FOUR_CHAR_CODE('fov ')
+kTrackModifierObjectQTEventSend = FOUR_CHAR_CODE('evnt')
+kTrackModifierObjectCanBeHitTested = 15
+kTweenTypeShort = 1
+kTweenTypeLong = 2
+kTweenTypeFixed = 3
+kTweenTypePoint = 4
+kTweenTypeQDRect = 5
+kTweenTypeQDRegion = 6
+kTweenTypeMatrix = 7
+kTweenTypeRGBColor = 8
+kTweenTypeGraphicsModeWithRGBColor = 9
+kTweenTypeQTFloatSingle = 10
+kTweenTypeQTFloatDouble = 11
+kTweenTypeFixedPoint = 12
+kTweenType3dScale = FOUR_CHAR_CODE('3sca')
+kTweenType3dTranslate = FOUR_CHAR_CODE('3tra')
+kTweenType3dRotate = FOUR_CHAR_CODE('3rot')
+kTweenType3dRotateAboutPoint = FOUR_CHAR_CODE('3rap')
+kTweenType3dRotateAboutAxis = FOUR_CHAR_CODE('3rax')
+kTweenType3dRotateAboutVector = FOUR_CHAR_CODE('3rvc')
+kTweenType3dQuaternion = FOUR_CHAR_CODE('3qua')
+kTweenType3dMatrix = FOUR_CHAR_CODE('3mat')
+kTweenType3dCameraData = FOUR_CHAR_CODE('3cam')
+kTweenType3dAngleAspectCameraData = FOUR_CHAR_CODE('3caa')
+kTweenType3dSoundLocalizationData = FOUR_CHAR_CODE('3slc')
+kTweenTypePathToMatrixTranslation = FOUR_CHAR_CODE('gxmt')
+kTweenTypePathToMatrixRotation = FOUR_CHAR_CODE('gxpr')
+kTweenTypePathToMatrixTranslationAndRotation = FOUR_CHAR_CODE('gxmr')
+kTweenTypePathToFixedPoint = FOUR_CHAR_CODE('gxfp')
+kTweenTypePathXtoY = FOUR_CHAR_CODE('gxxy')
+kTweenTypePathYtoX = FOUR_CHAR_CODE('gxyx')
+kTweenTypeAtomList = FOUR_CHAR_CODE('atom')
+kTweenTypePolygon = FOUR_CHAR_CODE('poly')
+kTweenTypeMultiMatrix = FOUR_CHAR_CODE('mulm')
+kTweenTypeSpin = FOUR_CHAR_CODE('spin')
+kTweenType3dMatrixNonLinear = FOUR_CHAR_CODE('3nlr')
+kTweenType3dVRObject = FOUR_CHAR_CODE('3vro')
+kTweenEntry = FOUR_CHAR_CODE('twen')
+kTweenData = FOUR_CHAR_CODE('data')
+kTweenType = FOUR_CHAR_CODE('twnt')
+kTweenStartOffset = FOUR_CHAR_CODE('twst')
+kTweenDuration = FOUR_CHAR_CODE('twdu')
+kTweenFlags = FOUR_CHAR_CODE('flag')
+kTweenOutputMin = FOUR_CHAR_CODE('omin')
+kTweenOutputMax = FOUR_CHAR_CODE('omax')
+kTweenSequenceElement = FOUR_CHAR_CODE('seqe')
+kTween3dInitialCondition = FOUR_CHAR_CODE('icnd')
+kTweenInterpolationID = FOUR_CHAR_CODE('intr')
+kTweenRegionData = FOUR_CHAR_CODE('qdrg')
+kTweenPictureData = FOUR_CHAR_CODE('PICT')
+kListElementType = FOUR_CHAR_CODE('type')
+kListElementDataType = FOUR_CHAR_CODE('daty')
+kNameAtom = FOUR_CHAR_CODE('name')
+kInitialRotationAtom = FOUR_CHAR_CODE('inro')
+kNonLinearTweenHeader = FOUR_CHAR_CODE('nlth')
+kTweenReturnDelta = 1L << 0
+kQTRestrictionClassSave = FOUR_CHAR_CODE('save')
+kQTRestrictionSaveDontAddMovieResource = (1L << 0)
+kQTRestrictionSaveDontFlatten = (1L << 1)
+kQTRestrictionSaveDontExport = (1L << 2)
+kQTRestrictionSaveDontExtract = (1L << 3)
+kQTRestrictionClassEdit = FOUR_CHAR_CODE('edit')
+kQTRestrictionEditDontCopy = (1L << 0)
+kQTRestrictionEditDontCut = (1L << 1)
+kQTRestrictionEditDontPaste = (1L << 2)
+kQTRestrictionEditDontClear = (1L << 3)
+kQTRestrictionEditDontModify = (1L << 4)
+kQTRestrictionEditDontExtract = (1L << 5)
+videoFlagDontLeanAhead = 1L << 0
+txtProcDefaultDisplay = 0
+txtProcDontDisplay = 1
+txtProcDoDisplay = 2
+findTextEdgeOK = 1 << 0
+findTextCaseSensitive = 1 << 1
+findTextReverseSearch = 1 << 2
+findTextWrapAround = 1 << 3
+findTextUseOffset = 1 << 4
+dropShadowOffsetType = FOUR_CHAR_CODE('drpo')
+dropShadowTranslucencyType = FOUR_CHAR_CODE('drpt')
+spriteHitTestBounds = 1L << 0
+spriteHitTestImage = 1L << 1
+spriteHitTestInvisibleSprites = 1L << 2
+spriteHitTestIsClick = 1L << 3
+spriteHitTestLocInDisplayCoordinates = 1L << 4
+spriteHitTestTreatAllSpritesAsHitTestable = 1L << 5
+kSpriteAtomType = FOUR_CHAR_CODE('sprt')
+kSpriteImagesContainerAtomType = FOUR_CHAR_CODE('imct')
+kSpriteImageAtomType = FOUR_CHAR_CODE('imag')
+kSpriteImageDataAtomType = FOUR_CHAR_CODE('imda')
+kSpriteImageDataRefAtomType = FOUR_CHAR_CODE('imre')
+kSpriteImageDataRefTypeAtomType = FOUR_CHAR_CODE('imrt')
+kSpriteImageGroupIDAtomType = FOUR_CHAR_CODE('imgr')
+kSpriteImageRegistrationAtomType = FOUR_CHAR_CODE('imrg')
+kSpriteImageDefaultImageIndexAtomType = FOUR_CHAR_CODE('defi')
+kSpriteSharedDataAtomType = FOUR_CHAR_CODE('dflt')
+kSpriteNameAtomType = FOUR_CHAR_CODE('name')
+kSpriteImageNameAtomType = FOUR_CHAR_CODE('name')
+kSpriteUsesImageIDsAtomType = FOUR_CHAR_CODE('uses')
+kSpriteBehaviorsAtomType = FOUR_CHAR_CODE('beha')
+kSpriteImageBehaviorAtomType = FOUR_CHAR_CODE('imag')
+kSpriteCursorBehaviorAtomType = FOUR_CHAR_CODE('crsr')
+kSpriteStatusStringsBehaviorAtomType = FOUR_CHAR_CODE('sstr')
+kSpriteVariablesContainerAtomType = FOUR_CHAR_CODE('vars')
+kSpriteStringVariableAtomType = FOUR_CHAR_CODE('strv')
+kSpriteFloatingPointVariableAtomType = FOUR_CHAR_CODE('flov')
+kMovieMediaDataReference = FOUR_CHAR_CODE('mmdr')
+kMovieMediaDefaultDataReferenceID = FOUR_CHAR_CODE('ddri')
+kMovieMediaSlaveTime = FOUR_CHAR_CODE('slti')
+kMovieMediaSlaveAudio = FOUR_CHAR_CODE('slau')
+kMovieMediaSlaveGraphicsMode = FOUR_CHAR_CODE('slgr')
+kMovieMediaAutoPlay = FOUR_CHAR_CODE('play')
+kMovieMediaLoop = FOUR_CHAR_CODE('loop')
+kMovieMediaUseMIMEType = FOUR_CHAR_CODE('mime')
+kMovieMediaTitle = FOUR_CHAR_CODE('titl')
+kMovieMediaAltText = FOUR_CHAR_CODE('altt')
+kMovieMediaClipBegin = FOUR_CHAR_CODE('clpb')
+kMovieMediaClipDuration = FOUR_CHAR_CODE('clpd')
+kMovieMediaRegionAtom = FOUR_CHAR_CODE('regi')
+kMovieMediaSlaveTrackDuration = FOUR_CHAR_CODE('sltr')
+kMovieMediaEnableFrameStepping = FOUR_CHAR_CODE('enfs')
+kMovieMediaBackgroundColor = FOUR_CHAR_CODE('bkcl')
+kMovieMediaPrerollTime = FOUR_CHAR_CODE('prer')
+kMovieMediaFitNone = 0
+kMovieMediaFitScroll = FOUR_CHAR_CODE('scro')
+kMovieMediaFitClipIfNecessary = FOUR_CHAR_CODE('hidd')
+kMovieMediaFitFill = FOUR_CHAR_CODE('fill')
+kMovieMediaFitMeet = FOUR_CHAR_CODE('meet')
+kMovieMediaFitSlice = FOUR_CHAR_CODE('slic')
+kMovieMediaSpatialAdjustment = FOUR_CHAR_CODE('fit ')
+kMovieMediaRectangleAtom = FOUR_CHAR_CODE('rect')
+kMovieMediaTop = FOUR_CHAR_CODE('top ')
+kMovieMediaLeft = FOUR_CHAR_CODE('left')
+kMovieMediaWidth = FOUR_CHAR_CODE('wd  ')
+kMovieMediaHeight = FOUR_CHAR_CODE('ht  ')
+kMoviePropertyDuration = FOUR_CHAR_CODE('dura')
+kMoviePropertyTimeScale = FOUR_CHAR_CODE('tims')
+kMoviePropertyTime = FOUR_CHAR_CODE('timv')
+kMoviePropertyNaturalBounds = FOUR_CHAR_CODE('natb')
+kMoviePropertyMatrix = FOUR_CHAR_CODE('mtrx')
+kMoviePropertyTrackList = FOUR_CHAR_CODE('tlst')
+kTrackPropertyMediaType = FOUR_CHAR_CODE('mtyp')
+kTrackPropertyInstantiation = FOUR_CHAR_CODE('inst')
+MovieControllerComponentType = FOUR_CHAR_CODE('play')
+kMovieControllerQTVRFlag = 1 << 0
+kMovieControllerDontDisplayToUser = 1 << 1
+mcActionIdle = 1
+mcActionDraw = 2
+mcActionActivate = 3
+mcActionDeactivate = 4
+mcActionMouseDown = 5
+mcActionKey = 6
+mcActionPlay = 8
+mcActionGoToTime = 12
+mcActionSetVolume = 14
+mcActionGetVolume = 15
+mcActionStep = 18
+mcActionSetLooping = 21
+mcActionGetLooping = 22
+mcActionSetLoopIsPalindrome = 23
+mcActionGetLoopIsPalindrome = 24
+mcActionSetGrowBoxBounds = 25
+mcActionControllerSizeChanged = 26
+mcActionSetSelectionBegin = 29
+mcActionSetSelectionDuration = 30
+mcActionSetKeysEnabled = 32
+mcActionGetKeysEnabled = 33
+mcActionSetPlaySelection = 34
+mcActionGetPlaySelection = 35
+mcActionSetUseBadge = 36
+mcActionGetUseBadge = 37
+mcActionSetFlags = 38
+mcActionGetFlags = 39
+mcActionSetPlayEveryFrame = 40
+mcActionGetPlayEveryFrame = 41
+mcActionGetPlayRate = 42
+mcActionShowBalloon = 43
+mcActionBadgeClick = 44
+mcActionMovieClick = 45
+mcActionSuspend = 46
+mcActionResume = 47
+mcActionSetControllerKeysEnabled = 48
+mcActionGetTimeSliderRect = 49
+mcActionMovieEdited = 50
+mcActionGetDragEnabled = 51
+mcActionSetDragEnabled = 52
+mcActionGetSelectionBegin = 53
+mcActionGetSelectionDuration = 54
+mcActionPrerollAndPlay = 55
+mcActionGetCursorSettingEnabled = 56
+mcActionSetCursorSettingEnabled = 57
+mcActionSetColorTable = 58
+mcActionLinkToURL = 59
+mcActionCustomButtonClick = 60
+mcActionForceTimeTableUpdate = 61
+mcActionSetControllerTimeLimits = 62
+mcActionExecuteAllActionsForQTEvent = 63
+mcActionExecuteOneActionForQTEvent = 64
+mcActionAdjustCursor = 65
+mcActionUseTrackForTimeTable = 66
+mcActionClickAndHoldPoint = 67
+mcActionShowMessageString = 68
+mcActionShowStatusString = 69
+mcActionGetExternalMovie = 70
+mcActionGetChapterTime = 71
+mcActionPerformActionList = 72
+mcActionEvaluateExpression = 73
+mcActionFetchParameterAs = 74
+mcActionGetCursorByID = 75
+mcActionGetNextURL = 76
+mcActionMovieChanged = 77
+mcActionDoScript = 78
+mcActionRestartAtTime = 79
+mcActionGetIndChapter = 80
+mcActionLinkToURLExtended = 81
+mcActionSetVolumeStep = 82
+mcActionAutoPlay = 83
+mcActionPauseToBuffer = 84
+mcActionAppMessageReceived = 85
+mcActionEvaluateExpressionWithType = 89
+mcActionGetMovieName = 90
+mcActionGetMovieID = 91
+mcActionGetMovieActive = 92
+mcFlagSuppressMovieFrame = 1 << 0
+mcFlagSuppressStepButtons = 1 << 1
+mcFlagSuppressSpeakerButton = 1 << 2
+mcFlagsUseWindowPalette = 1 << 3
+mcFlagsDontInvalidate = 1 << 4
+mcFlagsUseCustomButton = 1 << 5
+mcPositionDontInvalidate = 1 << 5
+kMCIEEnabledButtonPicture = 1
+kMCIEDisabledButtonPicture = 2
+kMCIEDepressedButtonPicture = 3
+kMCIEEnabledSizeBoxPicture = 4
+kMCIEDisabledSizeBoxPicture = 5
+kMCIEEnabledUnavailableButtonPicture = 6
+kMCIEDisabledUnavailableButtonPicture = 7
+kMCIESoundSlider = 128
+kMCIESoundThumb = 129
+kMCIEColorTable = 256
+kMCIEIsFlatAppearance = 257
+kMCIEDoButtonIconsDropOnDepress = 258
+mcInfoUndoAvailable = 1 << 0
+mcInfoCutAvailable = 1 << 1
+mcInfoCopyAvailable = 1 << 2
+mcInfoPasteAvailable = 1 << 3
+mcInfoClearAvailable = 1 << 4
+mcInfoHasSound = 1 << 5
+mcInfoIsPlaying = 1 << 6
+mcInfoIsLooping = 1 << 7
+mcInfoIsInPalindrome = 1 << 8
+mcInfoEditingEnabled = 1 << 9
+mcInfoMovieIsInteractive = 1 << 10
+mcMenuUndo = 1
+mcMenuCut = 3
+mcMenuCopy = 4
+mcMenuPaste = 5
+mcMenuClear = 6
+kQTAppMessageSoftwareChanged = 1
+kQTAppMessageWindowCloseRequested = 3
+kQTAppMessageExitFullScreenRequested = 4
+kQTAppMessageDisplayChannels = 5
+kQTAppMessageEnterFullScreenRequested = 6
+kFetchAsBooleanPtr = 1
+kFetchAsShortPtr = 2
+kFetchAsLongPtr = 3
+kFetchAsMatrixRecordPtr = 4
+kFetchAsModifierTrackGraphicsModeRecord = 5
+kFetchAsHandle = 6
+kFetchAsStr255 = 7
+kFetchAsFloatPtr = 8
+kFetchAsPointPtr = 9
+kFetchAsNewAtomContainer = 10
+kFetchAsQTEventRecordPtr = 11
+kFetchAsFixedPtr = 12
+kFetchAsSetControllerValuePtr = 13
+kFetchAsRgnHandle = 14
+kFetchAsComponentDescriptionPtr = 15
+kFetchAsCString = 16
+kQTCursorOpenHand = -19183
+kQTCursorClosedHand = -19182
+kQTCursorPointingHand = -19181
+kQTCursorRightArrow = -19180
+kQTCursorLeftArrow = -19179
+kQTCursorDownArrow = -19178
+kQTCursorUpArrow = -19177
+kQTCursorIBeam = -19176
+kControllerUnderstandsIdleManagers = 1 << 0
+kVideoMediaResetStatisticsSelect = 0x0105
+kVideoMediaGetStatisticsSelect = 0x0106
+kVideoMediaGetStallCountSelect = 0x010E
+kVideoMediaSetCodecParameterSelect = 0x010F
+kVideoMediaGetCodecParameterSelect = 0x0110
+kTextMediaSetTextProcSelect = 0x0101
+kTextMediaAddTextSampleSelect = 0x0102
+kTextMediaAddTESampleSelect = 0x0103
+kTextMediaAddHiliteSampleSelect = 0x0104
+kTextMediaDrawRawSelect = 0x0109
+kTextMediaSetTextPropertySelect = 0x010A
+kTextMediaRawSetupSelect = 0x010B
+kTextMediaRawIdleSelect = 0x010C
+kTextMediaGetTextPropertySelect = 0x010D
+kTextMediaFindNextTextSelect = 0x0105
+kTextMediaHiliteTextSampleSelect = 0x0106
+kTextMediaSetTextSampleDataSelect = 0x0107
+kSpriteMediaSetPropertySelect = 0x0101
+kSpriteMediaGetPropertySelect = 0x0102
+kSpriteMediaHitTestSpritesSelect = 0x0103
+kSpriteMediaCountSpritesSelect = 0x0104
+kSpriteMediaCountImagesSelect = 0x0105
+kSpriteMediaGetIndImageDescriptionSelect = 0x0106
+kSpriteMediaGetDisplayedSampleNumberSelect = 0x0107
+kSpriteMediaGetSpriteNameSelect = 0x0108
+kSpriteMediaGetImageNameSelect = 0x0109
+kSpriteMediaSetSpritePropertySelect = 0x010A
+kSpriteMediaGetSpritePropertySelect = 0x010B
+kSpriteMediaHitTestAllSpritesSelect = 0x010C
+kSpriteMediaHitTestOneSpriteSelect = 0x010D
+kSpriteMediaSpriteIndexToIDSelect = 0x010E
+kSpriteMediaSpriteIDToIndexSelect = 0x010F
+kSpriteMediaGetSpriteActionsForQTEventSelect = 0x0110
+kSpriteMediaSetActionVariableSelect = 0x0111
+kSpriteMediaGetActionVariableSelect = 0x0112
+kSpriteMediaGetIndImagePropertySelect = 0x0113
+kSpriteMediaNewSpriteSelect = 0x0114
+kSpriteMediaDisposeSpriteSelect = 0x0115
+kSpriteMediaSetActionVariableToStringSelect = 0x0116
+kSpriteMediaGetActionVariableAsStringSelect = 0x0117
+kSpriteMediaNewImageSelect = 0x011B
+kSpriteMediaDisposeImageSelect = 0x011C
+kSpriteMediaImageIndexToIDSelect = 0x011D
+kSpriteMediaImageIDToIndexSelect = 0x011E
+kFlashMediaSetPanSelect = 0x0101
+kFlashMediaSetZoomSelect = 0x0102
+kFlashMediaSetZoomRectSelect = 0x0103
+kFlashMediaGetRefConBoundsSelect = 0x0104
+kFlashMediaGetRefConIDSelect = 0x0105
+kFlashMediaIDToRefConSelect = 0x0106
+kFlashMediaGetDisplayedFrameNumberSelect = 0x0107
+kFlashMediaFrameNumberToMovieTimeSelect = 0x0108
+kFlashMediaFrameLabelToMovieTimeSelect = 0x0109
+kFlashMediaGetFlashVariableSelect = 0x010A
+kFlashMediaSetFlashVariableSelect = 0x010B
+kFlashMediaDoButtonActionsSelect = 0x010C
+kFlashMediaGetSupportedSwfVersionSelect = 0x010D
+kMovieMediaGetChildDoMCActionCallbackSelect = 0x0102
+kMovieMediaGetDoMCActionCallbackSelect = 0x0103
+kMovieMediaGetCurrentMoviePropertySelect = 0x0104
+kMovieMediaGetCurrentTrackPropertySelect = 0x0105
+kMovieMediaGetChildMovieDataReferenceSelect = 0x0106
+kMovieMediaSetChildMovieDataReferenceSelect = 0x0107
+kMovieMediaLoadChildMovieFromDataReferenceSelect = 0x0108
+kMedia3DGetNamedObjectListSelect = 0x0101
+kMedia3DGetRendererListSelect = 0x0102
+kMedia3DGetCurrentGroupSelect = 0x0103
+kMedia3DTranslateNamedObjectToSelect = 0x0104
+kMedia3DScaleNamedObjectToSelect = 0x0105
+kMedia3DRotateNamedObjectToSelect = 0x0106
+kMedia3DSetCameraDataSelect = 0x0107
+kMedia3DGetCameraDataSelect = 0x0108
+kMedia3DSetCameraAngleAspectSelect = 0x0109
+kMedia3DGetCameraAngleAspectSelect = 0x010A
+kMedia3DSetCameraRangeSelect = 0x010D
+kMedia3DGetCameraRangeSelect = 0x010E
+kMedia3DGetViewObjectSelect = 0x010F
+kMCSetMovieSelect = 0x0002
+kMCGetIndMovieSelect = 0x0005
+kMCRemoveAllMoviesSelect = 0x0006
+kMCRemoveAMovieSelect = 0x0003
+kMCRemoveMovieSelect = 0x0006
+kMCIsPlayerEventSelect = 0x0007
+kMCSetActionFilterSelect = 0x0008
+kMCDoActionSelect = 0x0009
+kMCSetControllerAttachedSelect = 0x000A
+kMCIsControllerAttachedSelect = 0x000B
+kMCSetControllerPortSelect = 0x000C
+kMCGetControllerPortSelect = 0x000D
+kMCSetVisibleSelect = 0x000E
+kMCGetVisibleSelect = 0x000F
+kMCGetControllerBoundsRectSelect = 0x0010
+kMCSetControllerBoundsRectSelect = 0x0011
+kMCGetControllerBoundsRgnSelect = 0x0012
+kMCGetWindowRgnSelect = 0x0013
+kMCMovieChangedSelect = 0x0014
+kMCSetDurationSelect = 0x0015
+kMCGetCurrentTimeSelect = 0x0016
+kMCNewAttachedControllerSelect = 0x0017
+kMCDrawSelect = 0x0018
+kMCActivateSelect = 0x0019
+kMCIdleSelect = 0x001A
+kMCKeySelect = 0x001B
+kMCClickSelect = 0x001C
+kMCEnableEditingSelect = 0x001D
+kMCIsEditingEnabledSelect = 0x001E
+kMCCopySelect = 0x001F
+kMCCutSelect = 0x0020
+kMCPasteSelect = 0x0021
+kMCClearSelect = 0x0022
+kMCUndoSelect = 0x0023
+kMCPositionControllerSelect = 0x0024
+kMCGetControllerInfoSelect = 0x0025
+kMCSetClipSelect = 0x0028
+kMCGetClipSelect = 0x0029
+kMCDrawBadgeSelect = 0x002A
+kMCSetUpEditMenuSelect = 0x002B
+kMCGetMenuStringSelect = 0x002C
+kMCSetActionFilterWithRefConSelect = 0x002D
+kMCPtInControllerSelect = 0x002E
+kMCInvalidateSelect = 0x002F
+kMCAdjustCursorSelect = 0x0030
+kMCGetInterfaceElementSelect = 0x0031
+kMCGetDoActionsProcSelect = 0x0032
+kMCAddMovieSegmentSelect = 0x0033
+kMCTrimMovieSegmentSelect = 0x0034
+kMCSetIdleManagerSelect = 0x0035
+kMCSetControllerCapabilitiesSelect = 0x0036
+kMusicMediaGetIndexedTunePlayerSelect = 0x0101
+kRawCodecType = FOUR_CHAR_CODE('raw ')
+kCinepakCodecType = FOUR_CHAR_CODE('cvid')
+kGraphicsCodecType = FOUR_CHAR_CODE('smc ')
+kAnimationCodecType = FOUR_CHAR_CODE('rle ')
+kVideoCodecType = FOUR_CHAR_CODE('rpza')
+kComponentVideoCodecType = FOUR_CHAR_CODE('yuv2')
+kJPEGCodecType = FOUR_CHAR_CODE('jpeg')
+kMotionJPEGACodecType = FOUR_CHAR_CODE('mjpa')
+kMotionJPEGBCodecType = FOUR_CHAR_CODE('mjpb')
+kSGICodecType = FOUR_CHAR_CODE('.SGI')
+kPlanarRGBCodecType = FOUR_CHAR_CODE('8BPS')
+kMacPaintCodecType = FOUR_CHAR_CODE('PNTG')
+kGIFCodecType = FOUR_CHAR_CODE('gif ')
+kPhotoCDCodecType = FOUR_CHAR_CODE('kpcd')
+kQuickDrawGXCodecType = FOUR_CHAR_CODE('qdgx')
+kAVRJPEGCodecType = FOUR_CHAR_CODE('avr ')
+kOpenDMLJPEGCodecType = FOUR_CHAR_CODE('dmb1')
+kBMPCodecType = FOUR_CHAR_CODE('WRLE')
+kWindowsRawCodecType = FOUR_CHAR_CODE('WRAW')
+kVectorCodecType = FOUR_CHAR_CODE('path')
+kQuickDrawCodecType = FOUR_CHAR_CODE('qdrw')
+kWaterRippleCodecType = FOUR_CHAR_CODE('ripl')
+kFireCodecType = FOUR_CHAR_CODE('fire')
+kCloudCodecType = FOUR_CHAR_CODE('clou')
+kH261CodecType = FOUR_CHAR_CODE('h261')
+kH263CodecType = FOUR_CHAR_CODE('h263')
+kDVCNTSCCodecType = FOUR_CHAR_CODE('dvc ')
+kDVCPALCodecType = FOUR_CHAR_CODE('dvcp')
+kDVCProPALCodecType = FOUR_CHAR_CODE('dvpp')
+kBaseCodecType = FOUR_CHAR_CODE('base')
+kFLCCodecType = FOUR_CHAR_CODE('flic')
+kTargaCodecType = FOUR_CHAR_CODE('tga ')
+kPNGCodecType = FOUR_CHAR_CODE('png ')
+kTIFFCodecType = FOUR_CHAR_CODE('tiff')
+kComponentVideoSigned = FOUR_CHAR_CODE('yuvu')
+kComponentVideoUnsigned = FOUR_CHAR_CODE('yuvs')
+kCMYKCodecType = FOUR_CHAR_CODE('cmyk')
+kMicrosoftVideo1CodecType = FOUR_CHAR_CODE('msvc')
+kSorensonCodecType = FOUR_CHAR_CODE('SVQ1')
+kSorenson3CodecType = FOUR_CHAR_CODE('SVQ3')
+kIndeo4CodecType = FOUR_CHAR_CODE('IV41')
+kMPEG4VisualCodecType = FOUR_CHAR_CODE('mp4v')
+k64ARGBCodecType = FOUR_CHAR_CODE('b64a')
+k48RGBCodecType = FOUR_CHAR_CODE('b48r')
+k32AlphaGrayCodecType = FOUR_CHAR_CODE('b32a')
+k16GrayCodecType = FOUR_CHAR_CODE('b16g')
+kMpegYUV420CodecType = FOUR_CHAR_CODE('myuv')
+kYUV420CodecType = FOUR_CHAR_CODE('y420')
+kSorensonYUV9CodecType = FOUR_CHAR_CODE('syv9')
+k422YpCbCr8CodecType = FOUR_CHAR_CODE('2vuy')
+k444YpCbCr8CodecType = FOUR_CHAR_CODE('v308')
+k4444YpCbCrA8CodecType = FOUR_CHAR_CODE('v408')
+k422YpCbCr16CodecType = FOUR_CHAR_CODE('v216')
+k422YpCbCr10CodecType = FOUR_CHAR_CODE('v210')
+k444YpCbCr10CodecType = FOUR_CHAR_CODE('v410')
+k4444YpCbCrA8RCodecType = FOUR_CHAR_CODE('r408')
+kBlurImageFilterType = FOUR_CHAR_CODE('blur')
+kSharpenImageFilterType = FOUR_CHAR_CODE('shrp')
+kEdgeDetectImageFilterType = FOUR_CHAR_CODE('edge')
+kEmbossImageFilterType = FOUR_CHAR_CODE('embs')
+kConvolveImageFilterType = FOUR_CHAR_CODE('genk')
+kAlphaGainImageFilterType = FOUR_CHAR_CODE('gain')
+kRGBColorBalanceImageFilterType = FOUR_CHAR_CODE('rgbb')
+kHSLColorBalanceImageFilterType = FOUR_CHAR_CODE('hslb')
+kColorSyncImageFilterType = FOUR_CHAR_CODE('sync')
+kFilmNoiseImageFilterType = FOUR_CHAR_CODE('fmns')
+kSolarizeImageFilterType = FOUR_CHAR_CODE('solr')
+kColorTintImageFilterType = FOUR_CHAR_CODE('tint')
+kLensFlareImageFilterType = FOUR_CHAR_CODE('lens')
+kBrightnessContrastImageFilterType = FOUR_CHAR_CODE('brco')
+kAlphaCompositorTransitionType = FOUR_CHAR_CODE('blnd')
+kCrossFadeTransitionType = FOUR_CHAR_CODE('dslv')
+kChannelCompositeEffectType = FOUR_CHAR_CODE('chan')
+kChromaKeyTransitionType = FOUR_CHAR_CODE('ckey')
+kImplodeTransitionType = FOUR_CHAR_CODE('mplo')
+kExplodeTransitionType = FOUR_CHAR_CODE('xplo')
+kGradientTransitionType = FOUR_CHAR_CODE('matt')
+kPushTransitionType = FOUR_CHAR_CODE('push')
+kSlideTransitionType = FOUR_CHAR_CODE('slid')
+kWipeTransitionType = FOUR_CHAR_CODE('smpt')
+kIrisTransitionType = FOUR_CHAR_CODE('smp2')
+kRadialTransitionType = FOUR_CHAR_CODE('smp3')
+kMatrixTransitionType = FOUR_CHAR_CODE('smp4')
+kZoomTransitionType = FOUR_CHAR_CODE('zoom')
+kTravellingMatteEffectType = FOUR_CHAR_CODE('trav')
+kCMYKPixelFormat = FOUR_CHAR_CODE('cmyk')
+k64ARGBPixelFormat = FOUR_CHAR_CODE('b64a')
+k48RGBPixelFormat = FOUR_CHAR_CODE('b48r')
+k32AlphaGrayPixelFormat = FOUR_CHAR_CODE('b32a')
+k16GrayPixelFormat = FOUR_CHAR_CODE('b16g')
+k422YpCbCr8PixelFormat = FOUR_CHAR_CODE('2vuy')
+k4444YpCbCrA8PixelFormat = FOUR_CHAR_CODE('v408')
+k4444YpCbCrA8RPixelFormat = FOUR_CHAR_CODE('r408')
+kYUV420PixelFormat = FOUR_CHAR_CODE('y420')
+codecInfoDoes1 = (1L << 0)
+codecInfoDoes2 = (1L << 1)
+codecInfoDoes4 = (1L << 2)
+codecInfoDoes8 = (1L << 3)
+codecInfoDoes16 = (1L << 4)
+codecInfoDoes32 = (1L << 5)
+codecInfoDoesDither = (1L << 6)
+codecInfoDoesStretch = (1L << 7)
+codecInfoDoesShrink = (1L << 8)
+codecInfoDoesMask = (1L << 9)
+codecInfoDoesTemporal = (1L << 10)
+codecInfoDoesDouble = (1L << 11)
+codecInfoDoesQuad = (1L << 12)
+codecInfoDoesHalf = (1L << 13)
+codecInfoDoesQuarter = (1L << 14)
+codecInfoDoesRotate = (1L << 15)
+codecInfoDoesHorizFlip = (1L << 16)
+codecInfoDoesVertFlip = (1L << 17)
+codecInfoHasEffectParameterList = (1L << 18)
+codecInfoDoesBlend = (1L << 19)
+codecInfoDoesWarp = (1L << 20)
+codecInfoDoesRecompress = (1L << 21)
+codecInfoDoesSpool = (1L << 22)
+codecInfoDoesRateConstrain = (1L << 23)
+codecInfoDepth1 = (1L << 0)
+codecInfoDepth2 = (1L << 1)
+codecInfoDepth4 = (1L << 2)
+codecInfoDepth8 = (1L << 3)
+codecInfoDepth16 = (1L << 4)
+codecInfoDepth32 = (1L << 5)
+codecInfoDepth24 = (1L << 6)
+codecInfoDepth33 = (1L << 7)
+codecInfoDepth34 = (1L << 8)
+codecInfoDepth36 = (1L << 9)
+codecInfoDepth40 = (1L << 10)
+codecInfoStoresClut = (1L << 11)
+codecInfoDoesLossless = (1L << 12)
+codecInfoSequenceSensitive = (1L << 13)
+codecFlagUseImageBuffer = (1L << 0)
+codecFlagUseScreenBuffer = (1L << 1)
+codecFlagUpdatePrevious = (1L << 2)
+codecFlagNoScreenUpdate = (1L << 3)
+codecFlagWasCompressed = (1L << 4)
+codecFlagDontOffscreen = (1L << 5)
+codecFlagUpdatePreviousComp = (1L << 6)
+codecFlagForceKeyFrame = (1L << 7)
+codecFlagOnlyScreenUpdate = (1L << 8)
+codecFlagLiveGrab = (1L << 9)
+codecFlagDiffFrame = (1L << 9)
+codecFlagDontUseNewImageBuffer = (1L << 10)
+codecFlagInterlaceUpdate = (1L << 11)
+codecFlagCatchUpDiff = (1L << 12)
+codecFlagSupportDisable = (1L << 13)
+codecFlagReenable = (1L << 14)
+codecFlagOutUpdateOnNextIdle = (1L << 9)
+codecFlagOutUpdateOnDataSourceChange = (1L << 10)
+codecFlagSequenceSensitive = (1L << 11)
+codecFlagOutUpdateOnTimeChange = (1L << 12)
+codecFlagImageBufferNotSourceImage = (1L << 13)
+codecFlagUsedNewImageBuffer = (1L << 14)
+codecFlagUsedImageBuffer = (1L << 15)
+codecMinimumDataSize = 32768L
+compressorComponentType = FOUR_CHAR_CODE('imco')
+decompressorComponentType = FOUR_CHAR_CODE('imdc')
+codecLosslessQuality = 0x00000400
+codecMaxQuality = 0x000003FF
+codecMinQuality = 0x00000000
+codecLowQuality = 0x00000100
+codecNormalQuality = 0x00000200
+codecHighQuality = 0x00000300
+codecLockBitsShieldCursor = (1 << 0)
+codecCompletionSource = (1 << 0)
+codecCompletionDest = (1 << 1)
+codecCompletionDontUnshield = (1 << 2)
+codecCompletionWentOffscreen = (1 << 3)
+codecCompletionUnlockBits = (1 << 4)
+codecCompletionForceChainFlush = (1 << 5)
+codecCompletionDropped = (1 << 6)
+codecProgressOpen = 0
+codecProgressUpdatePercent = 1
+codecProgressClose = 2
+defaultDither = 0
+forceDither = 1
+suppressDither = 2
+useColorMatching = 4
+callStdBits = 1
+callOldBits = 2
+noDefaultOpcodes = 4
+graphicsModeStraightAlpha = 256
+graphicsModePreWhiteAlpha = 257
+graphicsModePreBlackAlpha = 258
+graphicsModeComposition = 259
+graphicsModeStraightAlphaBlend = 260
+graphicsModePreMulColorAlpha = 261
+evenField1ToEvenFieldOut = 1 << 0
+evenField1ToOddFieldOut = 1 << 1
+oddField1ToEvenFieldOut = 1 << 2
+oddField1ToOddFieldOut = 1 << 3
+evenField2ToEvenFieldOut = 1 << 4
+evenField2ToOddFieldOut = 1 << 5
+oddField2ToEvenFieldOut = 1 << 6
+oddField2ToOddFieldOut = 1 << 7
+icmFrameTimeHasVirtualStartTimeAndDuration = 1 << 0
+codecDSequenceDisableOverlaySurface = (1L << 5)
+codecDSequenceSingleField = (1L << 6)
+codecDSequenceBidirectionalPrediction = (1L << 7)
+codecDSequenceFlushInsteadOfDirtying = (1L << 8)
+codecDSequenceEnableSubPixelPositioning = (1L << 9)
+kICMSequenceTaskWeight = FOUR_CHAR_CODE('twei')
+kICMSequenceTaskName = FOUR_CHAR_CODE('tnam')
+kICMSequenceUserPreferredCodecs = FOUR_CHAR_CODE('punt')
+kImageDescriptionSampleFormat = FOUR_CHAR_CODE('idfm')
+kImageDescriptionClassicAtomFormat = FOUR_CHAR_CODE('atom')
+kImageDescriptionQTAtomFormat = FOUR_CHAR_CODE('qtat')
+kImageDescriptionEffectDataFormat = FOUR_CHAR_CODE('fxat')
+kImageDescriptionPrivateDataFormat = FOUR_CHAR_CODE('priv')
+kImageDescriptionAlternateCodec = FOUR_CHAR_CODE('subs')
+kImageDescriptionColorSpace = FOUR_CHAR_CODE('cspc')
+sfpItemPreviewAreaUser = 11
+sfpItemPreviewStaticText = 12
+sfpItemPreviewDividerUser = 13
+sfpItemCreatePreviewButton = 14
+sfpItemShowPreviewButton = 15
+kICMPixelFormatIsPlanarMask = 0x0F
+kICMPixelFormatIsIndexed = (1L << 4)
+kICMPixelFormatIsSupportedByQD = (1L << 5)
+kICMPixelFormatIsMonochrome = (1L << 6)
+kICMPixelFormatHasAlphaChannel = (1L << 7)
+kICMGetChainUltimateParent = 0
+kICMGetChainParent = 1
+kICMGetChainChild = 2
+kICMGetChainUltimateChild = 3
+kDontUseValidateToFindGraphicsImporter = 1L << 0
+kICMTempThenAppMemory = 1L << 12
+kICMAppThenTempMemory = 1L << 13
+kQTUsePlatformDefaultGammaLevel = 0
+kQTUseSourceGammaLevel = -1L
+kQTCCIR601VideoGammaLevel = 0x00023333
+identityMatrixType = 0x00
+translateMatrixType = 0x01
+scaleMatrixType = 0x02
+scaleTranslateMatrixType = 0x03
+linearMatrixType = 0x04
+linearTranslateMatrixType = 0x05
+perspectiveMatrixType = 0x06
+GraphicsImporterComponentType = FOUR_CHAR_CODE('grip')
+graphicsImporterUsesImageDecompressor = 1L << 23
+quickTimeImageFileImageDescriptionAtom = FOUR_CHAR_CODE('idsc')
+quickTimeImageFileImageDataAtom = FOUR_CHAR_CODE('idat')
+quickTimeImageFileMetaDataAtom = FOUR_CHAR_CODE('meta')
+quickTimeImageFileColorSyncProfileAtom = FOUR_CHAR_CODE('iicc')
+graphicsImporterDrawsAllPixels = 0
+graphicsImporterDoesntDrawAllPixels = 1
+graphicsImporterDontKnowIfDrawAllPixels = 2
+kGraphicsImporterDontDoGammaCorrection = 1L << 0
+kGraphicsImporterTrustResolutionFromFile = 1L << 1
+kGraphicsImporterEnableSubPixelPositioning = 1L << 2
+kGraphicsExportGroup = FOUR_CHAR_CODE('expo')
+kGraphicsExportFileType = FOUR_CHAR_CODE('ftyp')
+kGraphicsExportMIMEType = FOUR_CHAR_CODE('mime')
+kGraphicsExportExtension = FOUR_CHAR_CODE('ext ')
+kGraphicsExportDescription = FOUR_CHAR_CODE('desc')
+kQTPhotoshopLayerMode = FOUR_CHAR_CODE('lmod')
+kQTPhotoshopLayerOpacity = FOUR_CHAR_CODE('lopa')
+kQTPhotoshopLayerClipping = FOUR_CHAR_CODE('lclp')
+kQTPhotoshopLayerFlags = FOUR_CHAR_CODE('lflg')
+kQTPhotoshopLayerName = FOUR_CHAR_CODE('\xa9lnm')
+kQTPhotoshopLayerUnicodeName = FOUR_CHAR_CODE('luni')
+kQTIndexedImageType = FOUR_CHAR_CODE('nth?')
+kQTIndexedImageIsThumbnail = FOUR_CHAR_CODE('n=th')
+kQTIndexedImageIsLayer = FOUR_CHAR_CODE('n=ly')
+kQTIndexedImageIsPage = FOUR_CHAR_CODE('n=pg')
+kQTIndexedImageIsMultiResolution = FOUR_CHAR_CODE('n=rs')
+kQTTIFFUserDataPrefix = 0x74690000
+kQTTIFFExifUserDataPrefix = 0x65780000
+kQTTIFFExifGPSUserDataPrefix = 0x67700000
+kQTAlphaMode = FOUR_CHAR_CODE('almo')
+kQTAlphaModePreMulColor = FOUR_CHAR_CODE('almp')
+kUserDataIPTC = FOUR_CHAR_CODE('iptc')
+kQTTIFFUserDataOrientation = 0x74690112
+kQTTIFFUserDataTransferFunction = 0x7469012D
+kQTTIFFUserDataWhitePoint = 0x7469013E
+kQTTIFFUserDataPrimaryChromaticities = 0x7469013F
+kQTTIFFUserDataTransferRange = 0x74690156
+kQTTIFFUserDataYCbCrPositioning = 0x74690213
+kQTTIFFUserDataReferenceBlackWhite = 0x74690214
+kQTTIFFUserDataModelPixelScale = 0x7469830E
+kQTTIFFUserDataModelTransformation = 0x746985D8
+kQTTIFFUserDataModelTiepoint = 0x74698482
+kQTTIFFUserDataGeoKeyDirectory = 0x746987AF
+kQTTIFFUserDataGeoDoubleParams = 0x746987B0
+kQTTIFFUserDataGeoAsciiParams = 0x746987B1
+kQTTIFFUserDataIntergraphMatrix = 0x74698480
+kQTExifUserDataExifVersion = 0x65789000
+kQTExifUserDataFlashPixVersion = 0x6578A000
+kQTExifUserDataColorSpace = 0x6578A001
+kQTExifUserDataComponentsConfiguration = 0x65789101
+kQTExifUserDataCompressedBitsPerPixel = 0x65789102
+kQTExifUserDataPixelXDimension = 0x6578A002
+kQTExifUserDataPixelYDimension = 0x6578A003
+kQTExifUserDataMakerNote = 0x6578927C
+kQTExifUserDataUserComment = 0x6578928C
+kQTExifUserDataRelatedSoundFile = 0x6578A004
+kQTExifUserDataDateTimeOriginal = 0x65789003
+kQTExifUserDataDateTimeDigitized = 0x65789004
+kQTExifUserDataSubSecTime = 0x65789290
+kQTExifUserDataSubSecTimeOriginal = 0x65789291
+kQTExifUserDataSubSecTimeDigitized = 0x65789292
+kQTExifUserDataExposureTime = 0x6578829A
+kQTExifUserDataFNumber = 0x6578829D
+kQTExifUserDataExposureProgram = 0x65788822
+kQTExifUserDataSpectralSensitivity = 0x65788824
+kQTExifUserDataISOSpeedRatings = 0x65788827
+kQTExifUserDataShutterSpeedValue = 0x65789201
+kQTExifUserDataApertureValue = 0x65789202
+kQTExifUserDataBrightnessValue = 0x65789203
+kQTExifUserDataExposureBiasValue = 0x65789204
+kQTExifUserDataMaxApertureValue = 0x65789205
+kQTExifUserDataSubjectDistance = 0x65789206
+kQTExifUserDataMeteringMode = 0x65789207
+kQTExifUserDataLightSource = 0x65789208
+kQTExifUserDataFlash = 0x65789209
+kQTExifUserDataFocalLength = 0x6578920A
+kQTExifUserDataFlashEnergy = 0x6578A20B
+kQTExifUserDataFocalPlaneXResolution = 0x6578A20E
+kQTExifUserDataFocalPlaneYResolution = 0x6578A20F
+kQTExifUserDataFocalPlaneResolutionUnit = 0x6578A210
+kQTExifUserDataSubjectLocation = 0x6578A214
+kQTExifUserDataExposureIndex = 0x6578A215
+kQTExifUserDataSensingMethod = 0x6578A217
+kQTExifUserDataFileSource = 0x6578A300
+kQTExifUserDataSceneType = 0x6578A301
+kQTExifUserDataGPSVersionID = 0x06770000
+kQTExifUserDataGPSLatitudeRef = 0x06770001
+kQTExifUserDataGPSLatitude = 0x06770002
+kQTExifUserDataGPSLongitudeRef = 0x06770003
+kQTExifUserDataGPSLongitude = 0x06770004
+kQTExifUserDataGPSAltitudeRef = 0x06770005
+kQTExifUserDataGPSAltitude = 0x06770006
+kQTExifUserDataGPSTimeStamp = 0x06770007
+kQTExifUserDataGPSSatellites = 0x06770008
+kQTExifUserDataGPSStatus = 0x06770009
+kQTExifUserDataGPSMeasureMode = 0x0677000A
+kQTExifUserDataGPSDOP = 0x0677000B
+kQTExifUserDataGPSSpeedRef = 0x0677000C
+kQTExifUserDataGPSSpeed = 0x0677000D
+kQTExifUserDataGPSTrackRef = 0x0677000E
+kQTExifUserDataGPSTrack = 0x0677000F
+kQTExifUserDataGPSImgDirectionRef = 0x06770010
+kQTExifUserDataGPSImgDirection = 0x06770011
+kQTExifUserDataGPSMapDatum = 0x06770012
+kQTExifUserDataGPSDestLatitudeRef = 0x06770013
+kQTExifUserDataGPSDestLatitude = 0x06770014
+kQTExifUserDataGPSDestLongitudeRef = 0x06770015
+kQTExifUserDataGPSDestLongitude = 0x06770016
+kQTExifUserDataGPSDestBearingRef = 0x06770017
+kQTExifUserDataGPSDestBearing = 0x06770018
+kQTExifUserDataGPSDestDistanceRef = 0x06770019
+kQTExifUserDataGPSDestDistance = 0x0677001A
+GraphicsExporterComponentType = FOUR_CHAR_CODE('grex')
+kBaseGraphicsExporterSubType = FOUR_CHAR_CODE('base')
+graphicsExporterIsBaseExporter = 1L << 0
+graphicsExporterCanTranscode = 1L << 1
+graphicsExporterUsesImageCompressor = 1L << 2
+kQTResolutionSettings = FOUR_CHAR_CODE('reso')
+kQTTargetDataSize = FOUR_CHAR_CODE('dasz')
+kQTDontRecompress = FOUR_CHAR_CODE('dntr')
+kQTInterlaceStyle = FOUR_CHAR_CODE('ilac')
+kQTColorSyncProfile = FOUR_CHAR_CODE('iccp')
+kQTThumbnailSettings = FOUR_CHAR_CODE('thum')
+kQTEnableExif = FOUR_CHAR_CODE('exif')
+kQTMetaData = FOUR_CHAR_CODE('meta')
+kQTTIFFCompressionMethod = FOUR_CHAR_CODE('tifc')
+kQTTIFFCompression_None = 1
+kQTTIFFCompression_PackBits = 32773L
+kQTTIFFLittleEndian = FOUR_CHAR_CODE('tife')
+kQTPNGFilterPreference = FOUR_CHAR_CODE('pngf')
+kQTPNGFilterBestForColorType = FOUR_CHAR_CODE('bflt')
+kQTPNGFilterNone = 0
+kQTPNGFilterSub = 1
+kQTPNGFilterUp = 2
+kQTPNGFilterAverage = 3
+kQTPNGFilterPaeth = 4
+kQTPNGFilterAdaptivePerRow = FOUR_CHAR_CODE('aflt')
+kQTPNGInterlaceStyle = FOUR_CHAR_CODE('ilac')
+kQTPNGInterlaceNone = 0
+kQTPNGInterlaceAdam7 = 1
+ImageTranscodererComponentType = FOUR_CHAR_CODE('imtc')
+kGraphicsImportSetDataReferenceSelect = 0x0001
+kGraphicsImportGetDataReferenceSelect = 0x0002
+kGraphicsImportSetDataFileSelect = 0x0003
+kGraphicsImportGetDataFileSelect = 0x0004
+kGraphicsImportSetDataHandleSelect = 0x0005
+kGraphicsImportGetDataHandleSelect = 0x0006
+kGraphicsImportGetImageDescriptionSelect = 0x0007
+kGraphicsImportGetDataOffsetAndSizeSelect = 0x0008
+kGraphicsImportReadDataSelect = 0x0009
+kGraphicsImportSetClipSelect = 0x000A
+kGraphicsImportGetClipSelect = 0x000B
+kGraphicsImportSetSourceRectSelect = 0x000C
+kGraphicsImportGetSourceRectSelect = 0x000D
+kGraphicsImportGetNaturalBoundsSelect = 0x000E
+kGraphicsImportDrawSelect = 0x000F
+kGraphicsImportSetGWorldSelect = 0x0010
+kGraphicsImportGetGWorldSelect = 0x0011
+kGraphicsImportSetMatrixSelect = 0x0012
+kGraphicsImportGetMatrixSelect = 0x0013
+kGraphicsImportSetBoundsRectSelect = 0x0014
+kGraphicsImportGetBoundsRectSelect = 0x0015
+kGraphicsImportSaveAsPictureSelect = 0x0016
+kGraphicsImportSetGraphicsModeSelect = 0x0017
+kGraphicsImportGetGraphicsModeSelect = 0x0018
+kGraphicsImportSetQualitySelect = 0x0019
+kGraphicsImportGetQualitySelect = 0x001A
+kGraphicsImportSaveAsQuickTimeImageFileSelect = 0x001B
+kGraphicsImportSetDataReferenceOffsetAndLimitSelect = 0x001C
+kGraphicsImportGetDataReferenceOffsetAndLimitSelect = 0x001D
+kGraphicsImportGetAliasedDataReferenceSelect = 0x001E
+kGraphicsImportValidateSelect = 0x001F
+kGraphicsImportGetMetaDataSelect = 0x0020
+kGraphicsImportGetMIMETypeListSelect = 0x0021
+kGraphicsImportDoesDrawAllPixelsSelect = 0x0022
+kGraphicsImportGetAsPictureSelect = 0x0023
+kGraphicsImportExportImageFileSelect = 0x0024
+kGraphicsImportGetExportImageTypeListSelect = 0x0025
+kGraphicsImportDoExportImageFileDialogSelect = 0x0026
+kGraphicsImportGetExportSettingsAsAtomContainerSelect = 0x0027
+kGraphicsImportSetExportSettingsFromAtomContainerSelect = 0x0028
+kGraphicsImportSetProgressProcSelect = 0x0029
+kGraphicsImportGetProgressProcSelect = 0x002A
+kGraphicsImportGetImageCountSelect = 0x002B
+kGraphicsImportSetImageIndexSelect = 0x002C
+kGraphicsImportGetImageIndexSelect = 0x002D
+kGraphicsImportGetDataOffsetAndSize64Select = 0x002E
+kGraphicsImportReadData64Select = 0x002F
+kGraphicsImportSetDataReferenceOffsetAndLimit64Select = 0x0030
+kGraphicsImportGetDataReferenceOffsetAndLimit64Select = 0x0031
+kGraphicsImportGetDefaultMatrixSelect = 0x0032
+kGraphicsImportGetDefaultClipSelect = 0x0033
+kGraphicsImportGetDefaultGraphicsModeSelect = 0x0034
+kGraphicsImportGetDefaultSourceRectSelect = 0x0035
+kGraphicsImportGetColorSyncProfileSelect = 0x0036
+kGraphicsImportSetDestRectSelect = 0x0037
+kGraphicsImportGetDestRectSelect = 0x0038
+kGraphicsImportSetFlagsSelect = 0x0039
+kGraphicsImportGetFlagsSelect = 0x003A
+kGraphicsImportGetBaseDataOffsetAndSize64Select = 0x003D
+kGraphicsImportSetImageIndexToThumbnailSelect = 0x003E
+kGraphicsExportDoExportSelect = 0x0001
+kGraphicsExportCanTranscodeSelect = 0x0002
+kGraphicsExportDoTranscodeSelect = 0x0003
+kGraphicsExportCanUseCompressorSelect = 0x0004
+kGraphicsExportDoUseCompressorSelect = 0x0005
+kGraphicsExportDoStandaloneExportSelect = 0x0006
+kGraphicsExportGetDefaultFileTypeAndCreatorSelect = 0x0007
+kGraphicsExportGetDefaultFileNameExtensionSelect = 0x0008
+kGraphicsExportGetMIMETypeListSelect = 0x0009
+kGraphicsExportRequestSettingsSelect = 0x000B
+kGraphicsExportSetSettingsFromAtomContainerSelect = 0x000C
+kGraphicsExportGetSettingsAsAtomContainerSelect = 0x000D
+kGraphicsExportGetSettingsAsTextSelect = 0x000E
+kGraphicsExportSetDontRecompressSelect = 0x000F
+kGraphicsExportGetDontRecompressSelect = 0x0010
+kGraphicsExportSetInterlaceStyleSelect = 0x0011
+kGraphicsExportGetInterlaceStyleSelect = 0x0012
+kGraphicsExportSetMetaDataSelect = 0x0013
+kGraphicsExportGetMetaDataSelect = 0x0014
+kGraphicsExportSetTargetDataSizeSelect = 0x0015
+kGraphicsExportGetTargetDataSizeSelect = 0x0016
+kGraphicsExportSetCompressionMethodSelect = 0x0017
+kGraphicsExportGetCompressionMethodSelect = 0x0018
+kGraphicsExportSetCompressionQualitySelect = 0x0019
+kGraphicsExportGetCompressionQualitySelect = 0x001A
+kGraphicsExportSetResolutionSelect = 0x001B
+kGraphicsExportGetResolutionSelect = 0x001C
+kGraphicsExportSetDepthSelect = 0x001D
+kGraphicsExportGetDepthSelect = 0x001E
+kGraphicsExportSetColorSyncProfileSelect = 0x0021
+kGraphicsExportGetColorSyncProfileSelect = 0x0022
+kGraphicsExportSetProgressProcSelect = 0x0023
+kGraphicsExportGetProgressProcSelect = 0x0024
+kGraphicsExportSetInputDataReferenceSelect = 0x0025
+kGraphicsExportGetInputDataReferenceSelect = 0x0026
+kGraphicsExportSetInputFileSelect = 0x0027
+kGraphicsExportGetInputFileSelect = 0x0028
+kGraphicsExportSetInputHandleSelect = 0x0029
+kGraphicsExportGetInputHandleSelect = 0x002A
+kGraphicsExportSetInputPtrSelect = 0x002B
+kGraphicsExportGetInputPtrSelect = 0x002C
+kGraphicsExportSetInputGraphicsImporterSelect = 0x002D
+kGraphicsExportGetInputGraphicsImporterSelect = 0x002E
+kGraphicsExportSetInputPictureSelect = 0x002F
+kGraphicsExportGetInputPictureSelect = 0x0030
+kGraphicsExportSetInputGWorldSelect = 0x0031
+kGraphicsExportGetInputGWorldSelect = 0x0032
+kGraphicsExportSetInputPixmapSelect = 0x0033
+kGraphicsExportGetInputPixmapSelect = 0x0034
+kGraphicsExportSetInputOffsetAndLimitSelect = 0x0035
+kGraphicsExportGetInputOffsetAndLimitSelect = 0x0036
+kGraphicsExportMayExporterReadInputDataSelect = 0x0037
+kGraphicsExportGetInputDataSizeSelect = 0x0038
+kGraphicsExportReadInputDataSelect = 0x0039
+kGraphicsExportGetInputImageDescriptionSelect = 0x003A
+kGraphicsExportGetInputImageDimensionsSelect = 0x003B
+kGraphicsExportGetInputImageDepthSelect = 0x003C
+kGraphicsExportDrawInputImageSelect = 0x003D
+kGraphicsExportSetOutputDataReferenceSelect = 0x003E
+kGraphicsExportGetOutputDataReferenceSelect = 0x003F
+kGraphicsExportSetOutputFileSelect = 0x0040
+kGraphicsExportGetOutputFileSelect = 0x0041
+kGraphicsExportSetOutputHandleSelect = 0x0042
+kGraphicsExportGetOutputHandleSelect = 0x0043
+kGraphicsExportSetOutputOffsetAndMaxSizeSelect = 0x0044
+kGraphicsExportGetOutputOffsetAndMaxSizeSelect = 0x0045
+kGraphicsExportSetOutputFileTypeAndCreatorSelect = 0x0046
+kGraphicsExportGetOutputFileTypeAndCreatorSelect = 0x0047
+kGraphicsExportWriteOutputDataSelect = 0x0048
+kGraphicsExportSetOutputMarkSelect = 0x0049
+kGraphicsExportGetOutputMarkSelect = 0x004A
+kGraphicsExportReadOutputDataSelect = 0x004B
+kGraphicsExportSetThumbnailEnabledSelect = 0x004C
+kGraphicsExportGetThumbnailEnabledSelect = 0x004D
+kGraphicsExportSetExifEnabledSelect = 0x004E
+kGraphicsExportGetExifEnabledSelect = 0x004F
+kImageTranscoderBeginSequenceSelect = 0x0001
+kImageTranscoderConvertSelect = 0x0002
+kImageTranscoderDisposeDataSelect = 0x0003
+kImageTranscoderEndSequenceSelect = 0x0004
+clockComponentType = FOUR_CHAR_CODE('clok')
+systemTickClock = FOUR_CHAR_CODE('tick')
+systemSecondClock = FOUR_CHAR_CODE('seco')
+systemMillisecondClock = FOUR_CHAR_CODE('mill')
+systemMicrosecondClock = FOUR_CHAR_CODE('micr')
+kClockRateIsLinear = 1
+kClockImplementsCallBacks = 2
+kClockCanHandleIntermittentSound = 4
+StandardCompressionType = FOUR_CHAR_CODE('scdi')
+StandardCompressionSubType = FOUR_CHAR_CODE('imag')
+StandardCompressionSubTypeSound = FOUR_CHAR_CODE('soun')
+scListEveryCodec = 1L << 1
+scAllowZeroFrameRate = 1L << 2
+scAllowZeroKeyFrameRate = 1L << 3
+scShowBestDepth = 1L << 4
+scUseMovableModal = 1L << 5
+scDisableFrameRateItem = 1L << 6
+scShowDataRateAsKilobits = 1L << 7
+scPreferCropping = 1 << 0
+scPreferScaling = 1 << 1
+scPreferScalingAndCropping = scPreferScaling | scPreferCropping
+scDontDetermineSettingsFromTestImage = 1 << 2
+scTestImageWidth = 80
+scTestImageHeight = 80
+scOKItem = 1
+scCancelItem = 2
+scCustomItem = 3
+scUserCancelled = 1
+scPositionRect = 2
+scPositionDialog = 3
+scSetTestImagePictHandle = 4
+scSetTestImagePictFile = 5
+scSetTestImagePixMap = 6
+scGetBestDeviceRect = 7
+scRequestImageSettings = 10
+scCompressImage = 11
+scCompressPicture = 12
+scCompressPictureFile = 13
+scRequestSequenceSettings = 14
+scCompressSequenceBegin = 15
+scCompressSequenceFrame = 16
+scCompressSequenceEnd = 17
+scDefaultPictHandleSettings = 18
+scDefaultPictFileSettings = 19
+scDefaultPixMapSettings = 20
+scGetInfo = 21
+scSetInfo = 22
+scNewGWorld = 23
+scSpatialSettingsType = FOUR_CHAR_CODE('sptl')
+scTemporalSettingsType = FOUR_CHAR_CODE('tprl')
+scDataRateSettingsType = FOUR_CHAR_CODE('drat')
+scColorTableType = FOUR_CHAR_CODE('clut')
+scProgressProcType = FOUR_CHAR_CODE('prog')
+scExtendedProcsType = FOUR_CHAR_CODE('xprc')
+scPreferenceFlagsType = FOUR_CHAR_CODE('pref')
+scSettingsStateType = FOUR_CHAR_CODE('ssta')
+scSequenceIDType = FOUR_CHAR_CODE('sequ')
+scWindowPositionType = FOUR_CHAR_CODE('wndw')
+scCodecFlagsType = FOUR_CHAR_CODE('cflg')
+scCodecSettingsType = FOUR_CHAR_CODE('cdec')
+scForceKeyValueType = FOUR_CHAR_CODE('ksim')
+scSoundSampleRateType = FOUR_CHAR_CODE('ssrt')
+scSoundSampleSizeType = FOUR_CHAR_CODE('ssss')
+scSoundChannelCountType = FOUR_CHAR_CODE('sscc')
+scSoundCompressionType = FOUR_CHAR_CODE('ssct')
+scCompressionListType = FOUR_CHAR_CODE('ctyl')
+scCodecManufacturerType = FOUR_CHAR_CODE('cmfr')
+scSoundVBRCompressionOK = FOUR_CHAR_CODE('cvbr')
+scSoundInputSampleRateType = FOUR_CHAR_CODE('ssir')
+scSoundSampleRateChangeOK = FOUR_CHAR_CODE('rcok')
+scAvailableCompressionListType = FOUR_CHAR_CODE('avai')
+scGetCompression = 1
+scShowMotionSettings = 1L << 0
+scSettingsChangedItem = -1
+scCompressFlagIgnoreIdenticalFrames = 1
+kQTSettingsVideo = FOUR_CHAR_CODE('vide')
+kQTSettingsSound = FOUR_CHAR_CODE('soun')
+kQTSettingsComponentVersion = FOUR_CHAR_CODE('vers')
+TweenComponentType = FOUR_CHAR_CODE('twen')
+TCSourceRefNameType = FOUR_CHAR_CODE('name')
+tcDropFrame = 1 << 0
+tc24HourMax = 1 << 1
+tcNegTimesOK = 1 << 2
+tcCounter = 1 << 3
+tctNegFlag = 0x80
+tcdfShowTimeCode = 1 << 0
+MovieImportType = FOUR_CHAR_CODE('eat ')
+MovieExportType = FOUR_CHAR_CODE('spit')
+canMovieImportHandles = 1 << 0
+canMovieImportFiles = 1 << 1
+hasMovieImportUserInterface = 1 << 2
+canMovieExportHandles = 1 << 3
+canMovieExportFiles = 1 << 4
+hasMovieExportUserInterface = 1 << 5
+movieImporterIsXMLBased = 1 << 5
+dontAutoFileMovieImport = 1 << 6
+canMovieExportAuxDataHandle = 1 << 7
+canMovieImportValidateHandles = 1 << 8
+canMovieImportValidateFile = 1 << 9
+dontRegisterWithEasyOpen = 1 << 10
+canMovieImportInPlace = 1 << 11
+movieImportSubTypeIsFileExtension = 1 << 12
+canMovieImportPartial = 1 << 13
+hasMovieImportMIMEList = 1 << 14
+canMovieImportAvoidBlocking = 1 << 15
+canMovieExportFromProcedures = 1 << 15
+canMovieExportValidateMovie = 1L << 16
+movieImportMustGetDestinationMediaType = 1L << 16
+movieExportNeedsResourceFork = 1L << 17
+canMovieImportDataReferences = 1L << 18
+movieExportMustGetSourceMediaType = 1L << 19
+canMovieImportWithIdle = 1L << 20
+canMovieImportValidateDataReferences = 1L << 21
+reservedForUseByGraphicsImporters = 1L << 23
+movieImportCreateTrack = 1
+movieImportInParallel = 2
+movieImportMustUseTrack = 4
+movieImportWithIdle = 16
+movieImportResultUsedMultipleTracks = 8
+movieImportResultNeedIdles = 32
+movieImportResultComplete = 64
+kMovieExportTextOnly = 0
+kMovieExportAbsoluteTime = 1
+kMovieExportRelativeTime = 2
+kMIDIImportSilenceBefore = 1 << 0
+kMIDIImportSilenceAfter = 1 << 1
+kMIDIImport20Playable = 1 << 2
+kMIDIImportWantLyrics = 1 << 3
+kQTMediaConfigResourceType = FOUR_CHAR_CODE('mcfg')
+kQTMediaConfigResourceVersion = 2
+kQTMediaGroupResourceType = FOUR_CHAR_CODE('mgrp')
+kQTMediaGroupResourceVersion = 1
+kQTBrowserInfoResourceType = FOUR_CHAR_CODE('brws')
+kQTBrowserInfoResourceVersion = 1
+kQTMediaMIMEInfoHasChanged = (1L << 1)
+kQTMediaFileInfoHasChanged = (1L << 2)
+kQTMediaConfigCanUseApp = (1L << 18)
+kQTMediaConfigCanUsePlugin = (1L << 19)
+kQTMediaConfigUNUSED = (1L << 20)
+kQTMediaConfigBinaryFile = (1L << 23)
+kQTMediaConfigTextFile = 0
+kQTMediaConfigMacintoshFile = (1L << 24)
+kQTMediaConfigAssociateByDefault = (1L << 27)
+kQTMediaConfigUseAppByDefault = (1L << 28)
+kQTMediaConfigUsePluginByDefault = (1L << 29)
+kQTMediaConfigDefaultsMask = (kQTMediaConfigUseAppByDefault | kQTMediaConfigUsePluginByDefault)
+kQTMediaConfigDefaultsShift = 12
+kQTMediaConfigHasFileHasQTAtoms = (1L << 30)
+kQTMediaConfigStreamGroupID = FOUR_CHAR_CODE('strm')
+kQTMediaConfigInteractiveGroupID = FOUR_CHAR_CODE('intr')
+kQTMediaConfigVideoGroupID = FOUR_CHAR_CODE('eyes')
+kQTMediaConfigAudioGroupID = FOUR_CHAR_CODE('ears')
+kQTMediaConfigMPEGGroupID = FOUR_CHAR_CODE('mpeg')
+kQTMediaConfigMP3GroupID = FOUR_CHAR_CODE('mp3 ')
+kQTMediaConfigImageGroupID = FOUR_CHAR_CODE('ogle')
+kQTMediaConfigMiscGroupID = FOUR_CHAR_CODE('misc')
+kQTMediaInfoNetGroup = FOUR_CHAR_CODE('net ')
+kQTMediaInfoWinGroup = FOUR_CHAR_CODE('win ')
+kQTMediaInfoMacGroup = FOUR_CHAR_CODE('mac ')
+kQTMediaInfoMiscGroup = 0x3F3F3F3F
+kMimeInfoMimeTypeTag = FOUR_CHAR_CODE('mime')
+kMimeInfoFileExtensionTag = FOUR_CHAR_CODE('ext ')
+kMimeInfoDescriptionTag = FOUR_CHAR_CODE('desc')
+kMimeInfoGroupTag = FOUR_CHAR_CODE('grop')
+kMimeInfoDoNotOverrideExistingFileTypeAssociation = FOUR_CHAR_CODE('nofa')
+kQTFileTypeAIFF = FOUR_CHAR_CODE('AIFF')
+kQTFileTypeAIFC = FOUR_CHAR_CODE('AIFC')
+kQTFileTypeDVC = FOUR_CHAR_CODE('dvc!')
+kQTFileTypeMIDI = FOUR_CHAR_CODE('Midi')
+kQTFileTypePicture = FOUR_CHAR_CODE('PICT')
+kQTFileTypeMovie = FOUR_CHAR_CODE('MooV')
+kQTFileTypeText = FOUR_CHAR_CODE('TEXT')
+kQTFileTypeWave = FOUR_CHAR_CODE('WAVE')
+kQTFileTypeSystemSevenSound = FOUR_CHAR_CODE('sfil')
+kQTFileTypeMuLaw = FOUR_CHAR_CODE('ULAW')
+kQTFileTypeAVI = FOUR_CHAR_CODE('VfW ')
+kQTFileTypeSoundDesignerII = FOUR_CHAR_CODE('Sd2f')
+kQTFileTypeAudioCDTrack = FOUR_CHAR_CODE('trak')
+kQTFileTypePICS = FOUR_CHAR_CODE('PICS')
+kQTFileTypeGIF = FOUR_CHAR_CODE('GIFf')
+kQTFileTypePNG = FOUR_CHAR_CODE('PNGf')
+kQTFileTypeTIFF = FOUR_CHAR_CODE('TIFF')
+kQTFileTypePhotoShop = FOUR_CHAR_CODE('8BPS')
+kQTFileTypeSGIImage = FOUR_CHAR_CODE('.SGI')
+kQTFileTypeBMP = FOUR_CHAR_CODE('BMPf')
+kQTFileTypeJPEG = FOUR_CHAR_CODE('JPEG')
+kQTFileTypeJFIF = FOUR_CHAR_CODE('JPEG')
+kQTFileTypeMacPaint = FOUR_CHAR_CODE('PNTG')
+kQTFileTypeTargaImage = FOUR_CHAR_CODE('TPIC')
+kQTFileTypeQuickDrawGXPicture = FOUR_CHAR_CODE('qdgx')
+kQTFileTypeQuickTimeImage = FOUR_CHAR_CODE('qtif')
+kQTFileType3DMF = FOUR_CHAR_CODE('3DMF')
+kQTFileTypeFLC = FOUR_CHAR_CODE('FLC ')
+kQTFileTypeFlash = FOUR_CHAR_CODE('SWFL')
+kQTFileTypeFlashPix = FOUR_CHAR_CODE('FPix')
+kQTFileTypeMP4 = FOUR_CHAR_CODE('mpg4')
+kQTSettingsDVExportNTSC = FOUR_CHAR_CODE('dvcv')
+kQTSettingsDVExportLockedAudio = FOUR_CHAR_CODE('lock')
+kQTSettingsEffect = FOUR_CHAR_CODE('effe')
+kQTSettingsGraphicsFileImportSequence = FOUR_CHAR_CODE('sequ')
+kQTSettingsGraphicsFileImportSequenceEnabled = FOUR_CHAR_CODE('enab')
+kQTSettingsMovieExportEnableVideo = FOUR_CHAR_CODE('envi')
+kQTSettingsMovieExportEnableSound = FOUR_CHAR_CODE('enso')
+kQTSettingsMovieExportSaveOptions = FOUR_CHAR_CODE('save')
+kQTSettingsMovieExportSaveForInternet = FOUR_CHAR_CODE('fast')
+kQTSettingsMovieExportSaveCompressedMovie = FOUR_CHAR_CODE('cmpm')
+kQTSettingsMIDI = FOUR_CHAR_CODE('MIDI')
+kQTSettingsMIDISettingFlags = FOUR_CHAR_CODE('sttg')
+kQTSettingsText = FOUR_CHAR_CODE('text')
+kQTSettingsTextDescription = FOUR_CHAR_CODE('desc')
+kQTSettingsTextSize = FOUR_CHAR_CODE('size')
+kQTSettingsTextSettingFlags = FOUR_CHAR_CODE('sttg')
+kQTSettingsTextTimeFraction = FOUR_CHAR_CODE('timf')
+kQTSettingsTime = FOUR_CHAR_CODE('time')
+kQTSettingsTimeDuration = FOUR_CHAR_CODE('dura')
+kQTSettingsAudioCDTrack = FOUR_CHAR_CODE('trak')
+kQTSettingsAudioCDTrackRateShift = FOUR_CHAR_CODE('rshf')
+kQTSettingsDVExportDVFormat = FOUR_CHAR_CODE('dvcf')
+kQTPresetsListResourceType = FOUR_CHAR_CODE('stg#')
+kQTPresetsPlatformListResourceType = FOUR_CHAR_CODE('stgp')
+kQTPresetInfoIsDivider = 1
+kQTMovieExportSourceInfoResourceType = FOUR_CHAR_CODE('src#')
+kQTMovieExportSourceInfoIsMediaType = 1L << 0
+kQTMovieExportSourceInfoIsMediaCharacteristic = 1L << 1
+kQTMovieExportSourceInfoIsSourceType = 1L << 2
+movieExportUseConfiguredSettings = FOUR_CHAR_CODE('ucfg')
+movieExportWidth = FOUR_CHAR_CODE('wdth')
+movieExportHeight = FOUR_CHAR_CODE('hegt')
+movieExportDuration = FOUR_CHAR_CODE('dura')
+movieExportVideoFilter = FOUR_CHAR_CODE('iflt')
+movieExportTimeScale = FOUR_CHAR_CODE('tmsc')
+kQTBrowserInfoCanUseSystemFolderPlugin = (1L << 0)
+kQTPreFlightOpenComponent = (1L << 1)
+pnotComponentWantsEvents = 1
+pnotComponentNeedsNoCache = 2
+ShowFilePreviewComponentType = FOUR_CHAR_CODE('pnot')
+CreateFilePreviewComponentType = FOUR_CHAR_CODE('pmak')
+DataCompressorComponentType = FOUR_CHAR_CODE('dcom')
+DataDecompressorComponentType = FOUR_CHAR_CODE('ddec')
+AppleDataCompressorSubType = FOUR_CHAR_CODE('adec')
+zlibDataCompressorSubType = FOUR_CHAR_CODE('zlib')
+kDataHCanRead = 1L << 0
+kDataHSpecialRead = 1L << 1
+kDataHSpecialReadFile = 1L << 2
+kDataHCanWrite = 1L << 3
+kDataHSpecialWrite = 1 << 4
+kDataHSpecialWriteFile = 1 << 5
+kDataHCanStreamingWrite = 1 << 6
+kDataHMustCheckDataRef = 1 << 7
+kDataRefExtensionChokeSpeed = FOUR_CHAR_CODE('chok')
+kDataRefExtensionFileName = FOUR_CHAR_CODE('fnam')
+kDataRefExtensionMIMEType = FOUR_CHAR_CODE('mime')
+kDataRefExtensionMacOSFileType = FOUR_CHAR_CODE('ftyp')
+kDataRefExtensionInitializationData = FOUR_CHAR_CODE('data')
+kDataRefExtensionQuickTimeMediaType = FOUR_CHAR_CODE('mtyp')
+kDataHChokeToMovieDataRate = 1 << 0
+kDataHChokeToParam = 1 << 1
+kDataHExtendedSchedule = FOUR_CHAR_CODE('xtnd')
+kDataHInfoFlagNeverStreams = 1 << 0
+kDataHInfoFlagCanUpdateDataRefs = 1 << 1
+kDataHInfoFlagNeedsNetworkBandwidth = 1 << 2
+kDataHFileTypeMacOSFileType = FOUR_CHAR_CODE('ftyp')
+kDataHFileTypeExtension = FOUR_CHAR_CODE('fext')
+kDataHFileTypeMIME = FOUR_CHAR_CODE('mime')
+kDataHCreateFileButDontCreateResFile = (1L << 0)
+kDataHMovieUsageDoAppendMDAT = 1L << 0
+kDataHTempUseSameDirectory = 1L << 0
+kDataHTempUseSameVolume = 1L << 1
+kDataHTempCreateFile = 1L << 2
+kDataHTempOpenFile = 1L << 3
+kDataHGetDataRateInfiniteRate = 0x7FFFFFFF
+kDataHSetTimeHintsSkipBandwidthRequest = 1 << 0
+videoDigitizerComponentType = FOUR_CHAR_CODE('vdig')
+vdigInterfaceRev = 2
+ntscIn = 0
+currentIn = 0
+palIn = 1
+secamIn = 2
+ntscReallyIn = 3
+compositeIn = 0
+sVideoIn = 1
+rgbComponentIn = 2
+rgbComponentSyncIn = 3
+yuvComponentIn = 4
+yuvComponentSyncIn = 5
+tvTunerIn = 6
+sdiIn = 7
+vdPlayThruOff = 0
+vdPlayThruOn = 1
+vdDigitizerBW = 0
+vdDigitizerRGB = 1
+vdBroadcastMode = 0
+vdVTRMode = 1
+vdUseAnyField = 0
+vdUseOddField = 1
+vdUseEvenField = 2
+vdTypeBasic = 0
+vdTypeAlpha = 1
+vdTypeMask = 2
+vdTypeKey = 3
+digiInDoesNTSC = 1L << 0
+digiInDoesPAL = 1L << 1
+digiInDoesSECAM = 1L << 2
+digiInDoesGenLock = 1L << 7
+digiInDoesComposite = 1L << 8
+digiInDoesSVideo = 1L << 9
+digiInDoesComponent = 1L << 10
+digiInVTR_Broadcast = 1L << 11
+digiInDoesColor = 1L << 12
+digiInDoesBW = 1L << 13
+digiInSignalLock = 1L << 31
+digiOutDoes1 = 1L << 0
+digiOutDoes2 = 1L << 1
+digiOutDoes4 = 1L << 2
+digiOutDoes8 = 1L << 3
+digiOutDoes16 = 1L << 4
+digiOutDoes32 = 1L << 5
+digiOutDoesDither = 1L << 6
+digiOutDoesStretch = 1L << 7
+digiOutDoesShrink = 1L << 8
+digiOutDoesMask = 1L << 9
+digiOutDoesDouble = 1L << 11
+digiOutDoesQuad = 1L << 12
+digiOutDoesQuarter = 1L << 13
+digiOutDoesSixteenth = 1L << 14
+digiOutDoesRotate = 1L << 15
+digiOutDoesHorizFlip = 1L << 16
+digiOutDoesVertFlip = 1L << 17
+digiOutDoesSkew = 1L << 18
+digiOutDoesBlend = 1L << 19
+digiOutDoesWarp = 1L << 20
+digiOutDoesHW_DMA = 1L << 21
+digiOutDoesHWPlayThru = 1L << 22
+digiOutDoesILUT = 1L << 23
+digiOutDoesKeyColor = 1L << 24
+digiOutDoesAsyncGrabs = 1L << 25
+digiOutDoesUnreadableScreenBits = 1L << 26
+digiOutDoesCompress = 1L << 27
+digiOutDoesCompressOnly = 1L << 28
+digiOutDoesPlayThruDuringCompress = 1L << 29
+digiOutDoesCompressPartiallyVisible = 1L << 30
+digiOutDoesNotNeedCopyOfCompressData = 1L << 31
+dmaDepth1 = 1
+dmaDepth2 = 2
+dmaDepth4 = 4
+dmaDepth8 = 8
+dmaDepth16 = 16
+dmaDepth32 = 32
+dmaDepth2Gray = 64
+dmaDepth4Gray = 128
+dmaDepth8Gray = 256
+kVDIGControlledFrameRate = -1
+vdDeviceFlagShowInputsAsDevices = (1 << 0)
+vdDeviceFlagHideDevice = (1 << 1)
+vdFlagCaptureStarting = (1 << 0)
+vdFlagCaptureStopping = (1 << 1)
+vdFlagCaptureIsForPreview = (1 << 2)
+vdFlagCaptureIsForRecord = (1 << 3)
+vdFlagCaptureLowLatency = (1 << 4)
+vdFlagCaptureAlwaysUseTimeBase = (1 << 5)
+vdFlagCaptureSetSettingsBegin = (1 << 6)
+vdFlagCaptureSetSettingsEnd = (1 << 7)
+xmlParseComponentType = FOUR_CHAR_CODE('pars')
+xmlParseComponentSubType = FOUR_CHAR_CODE('xml ')
+xmlIdentifierInvalid = 0
+# xmlIdentifierUnrecognized = (long)0xFFFFFFFF
+xmlContentTypeInvalid = 0
+xmlContentTypeElement = 1
+xmlContentTypeCharData = 2
+elementFlagAlwaysSelfContained = 1L << 0
+elementFlagPreserveWhiteSpace = 1L << 1
+xmlParseFlagAllowUppercase = 1L << 0
+xmlParseFlagAllowUnquotedAttributeValues = 1L << 1
+xmlParseFlagEventParseOnly = 1L << 2
+attributeValueKindCharString = 0
+attributeValueKindInteger = 1L << 0
+attributeValueKindPercent = 1L << 1
+attributeValueKindBoolean = 1L << 2
+attributeValueKindOnOff = 1L << 3
+attributeValueKindColor = 1L << 4
+attributeValueKindEnum = 1L << 5
+attributeValueKindCaseSensEnum = 1L << 6
+MAX_ATTRIBUTE_VALUE_KIND = attributeValueKindCaseSensEnum
+nameSpaceIDNone = 0
+element_xml = 1
+attr_src = 1
+SeqGrabComponentType = FOUR_CHAR_CODE('barg')
+SeqGrabChannelType = FOUR_CHAR_CODE('sgch')
+SeqGrabPanelType = FOUR_CHAR_CODE('sgpn')
+SeqGrabCompressionPanelType = FOUR_CHAR_CODE('cmpr')
+SeqGrabSourcePanelType = FOUR_CHAR_CODE('sour')
+seqGrabToDisk = 1
+seqGrabToMemory = 2
+seqGrabDontUseTempMemory = 4
+seqGrabAppendToFile = 8
+seqGrabDontAddMovieResource = 16
+seqGrabDontMakeMovie = 32
+seqGrabPreExtendFile = 64
+seqGrabDataProcIsInterruptSafe = 128
+seqGrabDataProcDoesOverlappingReads = 256
+seqGrabRecord = 1
+seqGrabPreview = 2
+seqGrabPlayDuringRecord = 4
+seqGrabLowLatencyCapture = 8
+seqGrabAlwaysUseTimeBase = 16
+seqGrabHasBounds = 1
+seqGrabHasVolume = 2
+seqGrabHasDiscreteSamples = 4
+seqGrabDoNotBufferizeData = 8
+seqGrabCanMoveWindowWhileRecording = 16
+grabPictOffScreen = 1
+grabPictIgnoreClip = 2
+grabPictCurrentImage = 4
+sgFlagControlledGrab = (1 << 0)
+sgFlagAllowNonRGBPixMaps = (1 << 1)
+sgDeviceInputNameFlagInputUnavailable = (1 << 0)
+sgDeviceNameFlagDeviceUnavailable = (1 << 0)
+sgDeviceNameFlagShowInputsAsDevices = (1 << 1)
+sgDeviceListWithIcons = (1 << 0)
+sgDeviceListDontCheckAvailability = (1 << 1)
+sgDeviceListIncludeInputs = (1 << 2)
+seqGrabWriteAppend = 0
+seqGrabWriteReserve = 1
+seqGrabWriteFill = 2
+seqGrabUnpause = 0
+seqGrabPause = 1
+seqGrabPauseForMenu = 3
+channelFlagDontOpenResFile = 2
+channelFlagHasDependency = 4
+sgPanelFlagForPanel = 1
+seqGrabSettingsPreviewOnly = 1
+channelPlayNormal = 0
+channelPlayFast = 1
+channelPlayHighQuality = 2
+channelPlayAllData = 4
+sgSetSettingsBegin = (1 << 0)
+sgSetSettingsEnd = (1 << 1)
+kSGSmallestDITLSize = -1
+kSGLargestDITLSize = -2
+sgChannelAtom = FOUR_CHAR_CODE('chan')
+sgChannelSettingsAtom = FOUR_CHAR_CODE('ctom')
+sgChannelDescription = FOUR_CHAR_CODE('cdsc')
+sgChannelSettings = FOUR_CHAR_CODE('cset')
+sgDeviceNameType = FOUR_CHAR_CODE('name')
+sgDeviceDisplayNameType = FOUR_CHAR_CODE('dnam')
+sgDeviceUIDType = FOUR_CHAR_CODE('duid')
+sgInputUIDType = FOUR_CHAR_CODE('iuid')
+sgUsageType = FOUR_CHAR_CODE('use ')
+sgPlayFlagsType = FOUR_CHAR_CODE('plyf')
+sgClipType = FOUR_CHAR_CODE('clip')
+sgMatrixType = FOUR_CHAR_CODE('mtrx')
+sgVolumeType = FOUR_CHAR_CODE('volu')
+sgPanelSettingsAtom = FOUR_CHAR_CODE('ptom')
+sgPanelDescription = FOUR_CHAR_CODE('pdsc')
+sgPanelSettings = FOUR_CHAR_CODE('pset')
+sgcSoundCompressionType = FOUR_CHAR_CODE('scmp')
+sgcSoundCodecSettingsType = FOUR_CHAR_CODE('cdec')
+sgcSoundSampleRateType = FOUR_CHAR_CODE('srat')
+sgcSoundChannelCountType = FOUR_CHAR_CODE('schn')
+sgcSoundSampleSizeType = FOUR_CHAR_CODE('ssiz')
+sgcSoundInputType = FOUR_CHAR_CODE('sinp')
+sgcSoundGainType = FOUR_CHAR_CODE('gain')
+sgcVideoHueType = FOUR_CHAR_CODE('hue ')
+sgcVideoSaturationType = FOUR_CHAR_CODE('satr')
+sgcVideoContrastType = FOUR_CHAR_CODE('trst')
+sgcVideoSharpnessType = FOUR_CHAR_CODE('shrp')
+sgcVideoBrigtnessType = FOUR_CHAR_CODE('brit')
+sgcVideoBlackLevelType = FOUR_CHAR_CODE('blkl')
+sgcVideoWhiteLevelType = FOUR_CHAR_CODE('whtl')
+sgcVideoInputType = FOUR_CHAR_CODE('vinp')
+sgcVideoFormatType = FOUR_CHAR_CODE('vstd')
+sgcVideoFilterType = FOUR_CHAR_CODE('vflt')
+sgcVideoRectType = FOUR_CHAR_CODE('vrct')
+sgcVideoDigitizerType = FOUR_CHAR_CODE('vdig')
+QTVideoOutputComponentType = FOUR_CHAR_CODE('vout')
+QTVideoOutputComponentBaseSubType = FOUR_CHAR_CODE('base')
+kQTVideoOutputDontDisplayToUser = 1L << 0
+kQTVODisplayModeItem = FOUR_CHAR_CODE('qdmi')
+kQTVODimensions = FOUR_CHAR_CODE('dimn')
+kQTVOResolution = FOUR_CHAR_CODE('resl')
+kQTVORefreshRate = FOUR_CHAR_CODE('refr')
+kQTVOPixelType = FOUR_CHAR_CODE('pixl')
+kQTVOName = FOUR_CHAR_CODE('name')
+kQTVODecompressors = FOUR_CHAR_CODE('deco')
+kQTVODecompressorType = FOUR_CHAR_CODE('dety')
+kQTVODecompressorContinuous = FOUR_CHAR_CODE('cont')
+kQTVODecompressorComponent = FOUR_CHAR_CODE('cmpt')
+kClockGetTimeSelect = 0x0001
+kClockNewCallBackSelect = 0x0002
+kClockDisposeCallBackSelect = 0x0003
+kClockCallMeWhenSelect = 0x0004
+kClockCancelCallBackSelect = 0x0005
+kClockRateChangedSelect = 0x0006
+kClockTimeChangedSelect = 0x0007
+kClockSetTimeBaseSelect = 0x0008
+kClockStartStopChangedSelect = 0x0009
+kClockGetRateSelect = 0x000A
+kSCGetCompressionExtendedSelect = 0x0001
+kSCPositionRectSelect = 0x0002
+kSCPositionDialogSelect = 0x0003
+kSCSetTestImagePictHandleSelect = 0x0004
+kSCSetTestImagePictFileSelect = 0x0005
+kSCSetTestImagePixMapSelect = 0x0006
+kSCGetBestDeviceRectSelect = 0x0007
+kSCRequestImageSettingsSelect = 0x000A
+kSCCompressImageSelect = 0x000B
+kSCCompressPictureSelect = 0x000C
+kSCCompressPictureFileSelect = 0x000D
+kSCRequestSequenceSettingsSelect = 0x000E
+kSCCompressSequenceBeginSelect = 0x000F
+kSCCompressSequenceFrameSelect = 0x0010
+kSCCompressSequenceEndSelect = 0x0011
+kSCDefaultPictHandleSettingsSelect = 0x0012
+kSCDefaultPictFileSettingsSelect = 0x0013
+kSCDefaultPixMapSettingsSelect = 0x0014
+kSCGetInfoSelect = 0x0015
+kSCSetInfoSelect = 0x0016
+kSCNewGWorldSelect = 0x0017
+kSCSetCompressFlagsSelect = 0x0018
+kSCGetCompressFlagsSelect = 0x0019
+kSCGetSettingsAsTextSelect = 0x001A
+kSCGetSettingsAsAtomContainerSelect = 0x001B
+kSCSetSettingsFromAtomContainerSelect = 0x001C
+kSCCompressSequenceFrameAsyncSelect = 0x001D
+kSCAsyncIdleSelect = 0x001E
+kTweenerInitializeSelect = 0x0001
+kTweenerDoTweenSelect = 0x0002
+kTweenerResetSelect = 0x0003
+kTCGetCurrentTimeCodeSelect = 0x0101
+kTCGetTimeCodeAtTimeSelect = 0x0102
+kTCTimeCodeToStringSelect = 0x0103
+kTCTimeCodeToFrameNumberSelect = 0x0104
+kTCFrameNumberToTimeCodeSelect = 0x0105
+kTCGetSourceRefSelect = 0x0106
+kTCSetSourceRefSelect = 0x0107
+kTCSetTimeCodeFlagsSelect = 0x0108
+kTCGetTimeCodeFlagsSelect = 0x0109
+kTCSetDisplayOptionsSelect = 0x010A
+kTCGetDisplayOptionsSelect = 0x010B
+kMovieImportHandleSelect = 0x0001
+kMovieImportFileSelect = 0x0002
+kMovieImportSetSampleDurationSelect = 0x0003
+kMovieImportSetSampleDescriptionSelect = 0x0004
+kMovieImportSetMediaFileSelect = 0x0005
+kMovieImportSetDimensionsSelect = 0x0006
+kMovieImportSetChunkSizeSelect = 0x0007
+kMovieImportSetProgressProcSelect = 0x0008
+kMovieImportSetAuxiliaryDataSelect = 0x0009
+kMovieImportSetFromScrapSelect = 0x000A
+kMovieImportDoUserDialogSelect = 0x000B
+kMovieImportSetDurationSelect = 0x000C
+kMovieImportGetAuxiliaryDataTypeSelect = 0x000D
+kMovieImportValidateSelect = 0x000E
+kMovieImportGetFileTypeSelect = 0x000F
+kMovieImportDataRefSelect = 0x0010
+kMovieImportGetSampleDescriptionSelect = 0x0011
+kMovieImportGetMIMETypeListSelect = 0x0012
+kMovieImportSetOffsetAndLimitSelect = 0x0013
+kMovieImportGetSettingsAsAtomContainerSelect = 0x0014
+kMovieImportSetSettingsFromAtomContainerSelect = 0x0015
+kMovieImportSetOffsetAndLimit64Select = 0x0016
+kMovieImportIdleSelect = 0x0017
+kMovieImportValidateDataRefSelect = 0x0018
+kMovieImportGetLoadStateSelect = 0x0019
+kMovieImportGetMaxLoadedTimeSelect = 0x001A
+kMovieImportEstimateCompletionTimeSelect = 0x001B
+kMovieImportSetDontBlockSelect = 0x001C
+kMovieImportGetDontBlockSelect = 0x001D
+kMovieImportSetIdleManagerSelect = 0x001E
+kMovieImportSetNewMovieFlagsSelect = 0x001F
+kMovieImportGetDestinationMediaTypeSelect = 0x0020
+kMovieExportToHandleSelect = 0x0080
+kMovieExportToFileSelect = 0x0081
+kMovieExportGetAuxiliaryDataSelect = 0x0083
+kMovieExportSetProgressProcSelect = 0x0084
+kMovieExportSetSampleDescriptionSelect = 0x0085
+kMovieExportDoUserDialogSelect = 0x0086
+kMovieExportGetCreatorTypeSelect = 0x0087
+kMovieExportToDataRefSelect = 0x0088
+kMovieExportFromProceduresToDataRefSelect = 0x0089
+kMovieExportAddDataSourceSelect = 0x008A
+kMovieExportValidateSelect = 0x008B
+kMovieExportGetSettingsAsAtomContainerSelect = 0x008C
+kMovieExportSetSettingsFromAtomContainerSelect = 0x008D
+kMovieExportGetFileNameExtensionSelect = 0x008E
+kMovieExportGetShortFileTypeStringSelect = 0x008F
+kMovieExportGetSourceMediaTypeSelect = 0x0090
+kMovieExportSetGetMoviePropertyProcSelect = 0x0091
+kTextExportGetDisplayDataSelect = 0x0100
+kTextExportGetTimeFractionSelect = 0x0101
+kTextExportSetTimeFractionSelect = 0x0102
+kTextExportGetSettingsSelect = 0x0103
+kTextExportSetSettingsSelect = 0x0104
+kMIDIImportGetSettingsSelect = 0x0100
+kMIDIImportSetSettingsSelect = 0x0101
+kMovieExportNewGetDataAndPropertiesProcsSelect = 0x0100
+kMovieExportDisposeGetDataAndPropertiesProcsSelect = 0x0101
+kGraphicsImageImportSetSequenceEnabledSelect = 0x0100
+kGraphicsImageImportGetSequenceEnabledSelect = 0x0101
+kPreviewShowDataSelect = 0x0001
+kPreviewMakePreviewSelect = 0x0002
+kPreviewMakePreviewReferenceSelect = 0x0003
+kPreviewEventSelect = 0x0004
+kDataCodecDecompressSelect = 0x0001
+kDataCodecGetCompressBufferSizeSelect = 0x0002
+kDataCodecCompressSelect = 0x0003
+kDataCodecBeginInterruptSafeSelect = 0x0004
+kDataCodecEndInterruptSafeSelect = 0x0005
+kDataCodecDecompressPartialSelect = 0x0006
+kDataCodecCompressPartialSelect = 0x0007
+kDataHGetDataSelect = 0x0002
+kDataHPutDataSelect = 0x0003
+kDataHFlushDataSelect = 0x0004
+kDataHOpenForWriteSelect = 0x0005
+kDataHCloseForWriteSelect = 0x0006
+kDataHOpenForReadSelect = 0x0008
+kDataHCloseForReadSelect = 0x0009
+kDataHSetDataRefSelect = 0x000A
+kDataHGetDataRefSelect = 0x000B
+kDataHCompareDataRefSelect = 0x000C
+kDataHTaskSelect = 0x000D
+kDataHScheduleDataSelect = 0x000E
+kDataHFinishDataSelect = 0x000F
+kDataHFlushCacheSelect = 0x0010
+kDataHResolveDataRefSelect = 0x0011
+kDataHGetFileSizeSelect = 0x0012
+kDataHCanUseDataRefSelect = 0x0013
+kDataHGetVolumeListSelect = 0x0014
+kDataHWriteSelect = 0x0015
+kDataHPreextendSelect = 0x0016
+kDataHSetFileSizeSelect = 0x0017
+kDataHGetFreeSpaceSelect = 0x0018
+kDataHCreateFileSelect = 0x0019
+kDataHGetPreferredBlockSizeSelect = 0x001A
+kDataHGetDeviceIndexSelect = 0x001B
+kDataHIsStreamingDataHandlerSelect = 0x001C
+kDataHGetDataInBufferSelect = 0x001D
+kDataHGetScheduleAheadTimeSelect = 0x001E
+kDataHSetCacheSizeLimitSelect = 0x001F
+kDataHGetCacheSizeLimitSelect = 0x0020
+kDataHGetMovieSelect = 0x0021
+kDataHAddMovieSelect = 0x0022
+kDataHUpdateMovieSelect = 0x0023
+kDataHDoesBufferSelect = 0x0024
+kDataHGetFileNameSelect = 0x0025
+kDataHGetAvailableFileSizeSelect = 0x0026
+kDataHGetMacOSFileTypeSelect = 0x0027
+kDataHGetMIMETypeSelect = 0x0028
+kDataHSetDataRefWithAnchorSelect = 0x0029
+kDataHGetDataRefWithAnchorSelect = 0x002A
+kDataHSetMacOSFileTypeSelect = 0x002B
+kDataHSetTimeBaseSelect = 0x002C
+kDataHGetInfoFlagsSelect = 0x002D
+kDataHScheduleData64Select = 0x002E
+kDataHWrite64Select = 0x002F
+kDataHGetFileSize64Select = 0x0030
+kDataHPreextend64Select = 0x0031
+kDataHSetFileSize64Select = 0x0032
+kDataHGetFreeSpace64Select = 0x0033
+kDataHAppend64Select = 0x0034
+kDataHReadAsyncSelect = 0x0035
+kDataHPollReadSelect = 0x0036
+kDataHGetDataAvailabilitySelect = 0x0037
+kDataHGetFileSizeAsyncSelect = 0x003A
+kDataHGetDataRefAsTypeSelect = 0x003B
+kDataHSetDataRefExtensionSelect = 0x003C
+kDataHGetDataRefExtensionSelect = 0x003D
+kDataHGetMovieWithFlagsSelect = 0x003E
+kDataHGetFileTypeOrderingSelect = 0x0040
+kDataHCreateFileWithFlagsSelect = 0x0041
+kDataHGetMIMETypeAsyncSelect = 0x0042
+kDataHGetInfoSelect = 0x0043
+kDataHSetIdleManagerSelect = 0x0044
+kDataHDeleteFileSelect = 0x0045
+kDataHSetMovieUsageFlagsSelect = 0x0046
+kDataHUseTemporaryDataRefSelect = 0x0047
+kDataHGetTemporaryDataRefCapabilitiesSelect = 0x0048
+kDataHRenameFileSelect = 0x0049
+kDataHPlaybackHintsSelect = 0x0103
+kDataHPlaybackHints64Select = 0x010E
+kDataHGetDataRateSelect = 0x0110
+kDataHSetTimeHintsSelect = 0x0111
+kVDGetMaxSrcRectSelect = 0x0001
+kVDGetActiveSrcRectSelect = 0x0002
+kVDSetDigitizerRectSelect = 0x0003
+kVDGetDigitizerRectSelect = 0x0004
+kVDGetVBlankRectSelect = 0x0005
+kVDGetMaskPixMapSelect = 0x0006
+kVDGetPlayThruDestinationSelect = 0x0008
+kVDUseThisCLUTSelect = 0x0009
+kVDSetInputGammaValueSelect = 0x000A
+kVDGetInputGammaValueSelect = 0x000B
+kVDSetBrightnessSelect = 0x000C
+kVDGetBrightnessSelect = 0x000D
+kVDSetContrastSelect = 0x000E
+kVDSetHueSelect = 0x000F
+kVDSetSharpnessSelect = 0x0010
+kVDSetSaturationSelect = 0x0011
+kVDGetContrastSelect = 0x0012
+kVDGetHueSelect = 0x0013
+kVDGetSharpnessSelect = 0x0014
+kVDGetSaturationSelect = 0x0015
+kVDGrabOneFrameSelect = 0x0016
+kVDGetMaxAuxBufferSelect = 0x0017
+kVDGetDigitizerInfoSelect = 0x0019
+kVDGetCurrentFlagsSelect = 0x001A
+kVDSetKeyColorSelect = 0x001B
+kVDGetKeyColorSelect = 0x001C
+kVDAddKeyColorSelect = 0x001D
+kVDGetNextKeyColorSelect = 0x001E
+kVDSetKeyColorRangeSelect = 0x001F
+kVDGetKeyColorRangeSelect = 0x0020
+kVDSetDigitizerUserInterruptSelect = 0x0021
+kVDSetInputColorSpaceModeSelect = 0x0022
+kVDGetInputColorSpaceModeSelect = 0x0023
+kVDSetClipStateSelect = 0x0024
+kVDGetClipStateSelect = 0x0025
+kVDSetClipRgnSelect = 0x0026
+kVDClearClipRgnSelect = 0x0027
+kVDGetCLUTInUseSelect = 0x0028
+kVDSetPLLFilterTypeSelect = 0x0029
+kVDGetPLLFilterTypeSelect = 0x002A
+kVDGetMaskandValueSelect = 0x002B
+kVDSetMasterBlendLevelSelect = 0x002C
+kVDSetPlayThruDestinationSelect = 0x002D
+kVDSetPlayThruOnOffSelect = 0x002E
+kVDSetFieldPreferenceSelect = 0x002F
+kVDGetFieldPreferenceSelect = 0x0030
+kVDPreflightDestinationSelect = 0x0032
+kVDPreflightGlobalRectSelect = 0x0033
+kVDSetPlayThruGlobalRectSelect = 0x0034
+kVDSetInputGammaRecordSelect = 0x0035
+kVDGetInputGammaRecordSelect = 0x0036
+kVDSetBlackLevelValueSelect = 0x0037
+kVDGetBlackLevelValueSelect = 0x0038
+kVDSetWhiteLevelValueSelect = 0x0039
+kVDGetWhiteLevelValueSelect = 0x003A
+kVDGetVideoDefaultsSelect = 0x003B
+kVDGetNumberOfInputsSelect = 0x003C
+kVDGetInputFormatSelect = 0x003D
+kVDSetInputSelect = 0x003E
+kVDGetInputSelect = 0x003F
+kVDSetInputStandardSelect = 0x0040
+kVDSetupBuffersSelect = 0x0041
+kVDGrabOneFrameAsyncSelect = 0x0042
+kVDDoneSelect = 0x0043
+kVDSetCompressionSelect = 0x0044
+kVDCompressOneFrameAsyncSelect = 0x0045
+kVDCompressDoneSelect = 0x0046
+kVDReleaseCompressBufferSelect = 0x0047
+kVDGetImageDescriptionSelect = 0x0048
+kVDResetCompressSequenceSelect = 0x0049
+kVDSetCompressionOnOffSelect = 0x004A
+kVDGetCompressionTypesSelect = 0x004B
+kVDSetTimeBaseSelect = 0x004C
+kVDSetFrameRateSelect = 0x004D
+kVDGetDataRateSelect = 0x004E
+kVDGetSoundInputDriverSelect = 0x004F
+kVDGetDMADepthsSelect = 0x0050
+kVDGetPreferredTimeScaleSelect = 0x0051
+kVDReleaseAsyncBuffersSelect = 0x0052
+kVDSetDataRateSelect = 0x0054
+kVDGetTimeCodeSelect = 0x0055
+kVDUseSafeBuffersSelect = 0x0056
+kVDGetSoundInputSourceSelect = 0x0057
+kVDGetCompressionTimeSelect = 0x0058
+kVDSetPreferredPacketSizeSelect = 0x0059
+kVDSetPreferredImageDimensionsSelect = 0x005A
+kVDGetPreferredImageDimensionsSelect = 0x005B
+kVDGetInputNameSelect = 0x005C
+kVDSetDestinationPortSelect = 0x005D
+kVDGetDeviceNameAndFlagsSelect = 0x005E
+kVDCaptureStateChangingSelect = 0x005F
+kVDGetUniqueIDsSelect = 0x0060
+kVDSelectUniqueIDsSelect = 0x0061
+kXMLParseDataRefSelect = 0x0001
+kXMLParseFileSelect = 0x0002
+kXMLParseDisposeXMLDocSelect = 0x0003
+kXMLParseGetDetailedParseErrorSelect = 0x0004
+kXMLParseAddElementSelect = 0x0005
+kXMLParseAddAttributeSelect = 0x0006
+kXMLParseAddMultipleAttributesSelect = 0x0007
+kXMLParseAddAttributeAndValueSelect = 0x0008
+kXMLParseAddMultipleAttributesAndValuesSelect = 0x0009
+kXMLParseAddAttributeValueKindSelect = 0x000A
+kXMLParseAddNameSpaceSelect = 0x000B
+kXMLParseSetOffsetAndLimitSelect = 0x000C
+kXMLParseSetEventParseRefConSelect = 0x000D
+kXMLParseSetStartDocumentHandlerSelect = 0x000E
+kXMLParseSetEndDocumentHandlerSelect = 0x000F
+kXMLParseSetStartElementHandlerSelect = 0x0010
+kXMLParseSetEndElementHandlerSelect = 0x0011
+kXMLParseSetCharDataHandlerSelect = 0x0012
+kXMLParseSetPreprocessInstructionHandlerSelect = 0x0013
+kXMLParseSetCommentHandlerSelect = 0x0014
+kXMLParseSetCDataHandlerSelect = 0x0015
+kSGInitializeSelect = 0x0001
+kSGSetDataOutputSelect = 0x0002
+kSGGetDataOutputSelect = 0x0003
+kSGSetGWorldSelect = 0x0004
+kSGGetGWorldSelect = 0x0005
+kSGNewChannelSelect = 0x0006
+kSGDisposeChannelSelect = 0x0007
+kSGStartPreviewSelect = 0x0010
+kSGStartRecordSelect = 0x0011
+kSGIdleSelect = 0x0012
+kSGStopSelect = 0x0013
+kSGPauseSelect = 0x0014
+kSGPrepareSelect = 0x0015
+kSGReleaseSelect = 0x0016
+kSGGetMovieSelect = 0x0017
+kSGSetMaximumRecordTimeSelect = 0x0018
+kSGGetMaximumRecordTimeSelect = 0x0019
+kSGGetStorageSpaceRemainingSelect = 0x001A
+kSGGetTimeRemainingSelect = 0x001B
+kSGGrabPictSelect = 0x001C
+kSGGetLastMovieResIDSelect = 0x001D
+kSGSetFlagsSelect = 0x001E
+kSGGetFlagsSelect = 0x001F
+kSGSetDataProcSelect = 0x0020
+kSGNewChannelFromComponentSelect = 0x0021
+kSGDisposeDeviceListSelect = 0x0022
+kSGAppendDeviceListToMenuSelect = 0x0023
+kSGSetSettingsSelect = 0x0024
+kSGGetSettingsSelect = 0x0025
+kSGGetIndChannelSelect = 0x0026
+kSGUpdateSelect = 0x0027
+kSGGetPauseSelect = 0x0028
+kSGSettingsDialogSelect = 0x0029
+kSGGetAlignmentProcSelect = 0x002A
+kSGSetChannelSettingsSelect = 0x002B
+kSGGetChannelSettingsSelect = 0x002C
+kSGGetModeSelect = 0x002D
+kSGSetDataRefSelect = 0x002E
+kSGGetDataRefSelect = 0x002F
+kSGNewOutputSelect = 0x0030
+kSGDisposeOutputSelect = 0x0031
+kSGSetOutputFlagsSelect = 0x0032
+kSGSetChannelOutputSelect = 0x0033
+kSGGetDataOutputStorageSpaceRemainingSelect = 0x0034
+kSGHandleUpdateEventSelect = 0x0035
+kSGSetOutputNextOutputSelect = 0x0036
+kSGGetOutputNextOutputSelect = 0x0037
+kSGSetOutputMaximumOffsetSelect = 0x0038
+kSGGetOutputMaximumOffsetSelect = 0x0039
+kSGGetOutputDataReferenceSelect = 0x003A
+kSGWriteExtendedMovieDataSelect = 0x003B
+kSGGetStorageSpaceRemaining64Select = 0x003C
+kSGGetDataOutputStorageSpaceRemaining64Select = 0x003D
+kSGWriteMovieDataSelect = 0x0100
+kSGAddFrameReferenceSelect = 0x0101
+kSGGetNextFrameReferenceSelect = 0x0102
+kSGGetTimeBaseSelect = 0x0103
+kSGSortDeviceListSelect = 0x0104
+kSGAddMovieDataSelect = 0x0105
+kSGChangedSourceSelect = 0x0106
+kSGAddExtendedFrameReferenceSelect = 0x0107
+kSGGetNextExtendedFrameReferenceSelect = 0x0108
+kSGAddExtendedMovieDataSelect = 0x0109
+kSGAddOutputDataRefToMediaSelect = 0x010A
+kSGSetSettingsSummarySelect = 0x010B
+kSGSetChannelUsageSelect = 0x0080
+kSGGetChannelUsageSelect = 0x0081
+kSGSetChannelBoundsSelect = 0x0082
+kSGGetChannelBoundsSelect = 0x0083
+kSGSetChannelVolumeSelect = 0x0084
+kSGGetChannelVolumeSelect = 0x0085
+kSGGetChannelInfoSelect = 0x0086
+kSGSetChannelPlayFlagsSelect = 0x0087
+kSGGetChannelPlayFlagsSelect = 0x0088
+kSGSetChannelMaxFramesSelect = 0x0089
+kSGGetChannelMaxFramesSelect = 0x008A
+kSGSetChannelRefConSelect = 0x008B
+kSGSetChannelClipSelect = 0x008C
+kSGGetChannelClipSelect = 0x008D
+kSGGetChannelSampleDescriptionSelect = 0x008E
+kSGGetChannelDeviceListSelect = 0x008F
+kSGSetChannelDeviceSelect = 0x0090
+kSGSetChannelMatrixSelect = 0x0091
+kSGGetChannelMatrixSelect = 0x0092
+kSGGetChannelTimeScaleSelect = 0x0093
+kSGChannelPutPictureSelect = 0x0094
+kSGChannelSetRequestedDataRateSelect = 0x0095
+kSGChannelGetRequestedDataRateSelect = 0x0096
+kSGChannelSetDataSourceNameSelect = 0x0097
+kSGChannelGetDataSourceNameSelect = 0x0098
+kSGChannelSetCodecSettingsSelect = 0x0099
+kSGChannelGetCodecSettingsSelect = 0x009A
+kSGGetChannelTimeBaseSelect = 0x009B
+kSGGetChannelRefConSelect = 0x009C
+kSGGetChannelDeviceAndInputNamesSelect = 0x009D
+kSGSetChannelDeviceInputSelect = 0x009E
+kSGSetChannelSettingsStateChangingSelect = 0x009F
+kSGInitChannelSelect = 0x0180
+kSGWriteSamplesSelect = 0x0181
+kSGGetDataRateSelect = 0x0182
+kSGAlignChannelRectSelect = 0x0183
+kSGPanelGetDitlSelect = 0x0200
+kSGPanelGetTitleSelect = 0x0201
+kSGPanelCanRunSelect = 0x0202
+kSGPanelInstallSelect = 0x0203
+kSGPanelEventSelect = 0x0204
+kSGPanelItemSelect = 0x0205
+kSGPanelRemoveSelect = 0x0206
+kSGPanelSetGrabberSelect = 0x0207
+kSGPanelSetResFileSelect = 0x0208
+kSGPanelGetSettingsSelect = 0x0209
+kSGPanelSetSettingsSelect = 0x020A
+kSGPanelValidateInputSelect = 0x020B
+kSGPanelSetEventFilterSelect = 0x020C
+kSGPanelGetDITLForSizeSelect = 0x020D
+kSGGetSrcVideoBoundsSelect = 0x0100
+kSGSetVideoRectSelect = 0x0101
+kSGGetVideoRectSelect = 0x0102
+kSGGetVideoCompressorTypeSelect = 0x0103
+kSGSetVideoCompressorTypeSelect = 0x0104
+kSGSetVideoCompressorSelect = 0x0105
+kSGGetVideoCompressorSelect = 0x0106
+kSGGetVideoDigitizerComponentSelect = 0x0107
+kSGSetVideoDigitizerComponentSelect = 0x0108
+kSGVideoDigitizerChangedSelect = 0x0109
+kSGSetVideoBottlenecksSelect = 0x010A
+kSGGetVideoBottlenecksSelect = 0x010B
+kSGGrabFrameSelect = 0x010C
+kSGGrabFrameCompleteSelect = 0x010D
+kSGDisplayFrameSelect = 0x010E
+kSGCompressFrameSelect = 0x010F
+kSGCompressFrameCompleteSelect = 0x0110
+kSGAddFrameSelect = 0x0111
+kSGTransferFrameForCompressSelect = 0x0112
+kSGSetCompressBufferSelect = 0x0113
+kSGGetCompressBufferSelect = 0x0114
+kSGGetBufferInfoSelect = 0x0115
+kSGSetUseScreenBufferSelect = 0x0116
+kSGGetUseScreenBufferSelect = 0x0117
+kSGGrabCompressCompleteSelect = 0x0118
+kSGDisplayCompressSelect = 0x0119
+kSGSetFrameRateSelect = 0x011A
+kSGGetFrameRateSelect = 0x011B
+kSGSetPreferredPacketSizeSelect = 0x0121
+kSGGetPreferredPacketSizeSelect = 0x0122
+kSGSetUserVideoCompressorListSelect = 0x0123
+kSGGetUserVideoCompressorListSelect = 0x0124
+kSGSetSoundInputDriverSelect = 0x0100
+kSGGetSoundInputDriverSelect = 0x0101
+kSGSoundInputDriverChangedSelect = 0x0102
+kSGSetSoundRecordChunkSizeSelect = 0x0103
+kSGGetSoundRecordChunkSizeSelect = 0x0104
+kSGSetSoundInputRateSelect = 0x0105
+kSGGetSoundInputRateSelect = 0x0106
+kSGSetSoundInputParametersSelect = 0x0107
+kSGGetSoundInputParametersSelect = 0x0108
+kSGSetAdditionalSoundRatesSelect = 0x0109
+kSGGetAdditionalSoundRatesSelect = 0x010A
+kSGSetFontNameSelect = 0x0100
+kSGSetFontSizeSelect = 0x0101
+kSGSetTextForeColorSelect = 0x0102
+kSGSetTextBackColorSelect = 0x0103
+kSGSetJustificationSelect = 0x0104
+kSGGetTextReturnToSpaceValueSelect = 0x0105
+kSGSetTextReturnToSpaceValueSelect = 0x0106
+kSGGetInstrumentSelect = 0x0100
+kSGSetInstrumentSelect = 0x0101
+kQTVideoOutputGetDisplayModeListSelect = 0x0001
+kQTVideoOutputGetCurrentClientNameSelect = 0x0002
+kQTVideoOutputSetClientNameSelect = 0x0003
+kQTVideoOutputGetClientNameSelect = 0x0004
+kQTVideoOutputBeginSelect = 0x0005
+kQTVideoOutputEndSelect = 0x0006
+kQTVideoOutputSetDisplayModeSelect = 0x0007
+kQTVideoOutputGetDisplayModeSelect = 0x0008
+kQTVideoOutputCustomConfigureDisplaySelect = 0x0009
+kQTVideoOutputSaveStateSelect = 0x000A
+kQTVideoOutputRestoreStateSelect = 0x000B
+kQTVideoOutputGetGWorldSelect = 0x000C
+kQTVideoOutputGetGWorldParametersSelect = 0x000D
+kQTVideoOutputGetIndSoundOutputSelect = 0x000E
+kQTVideoOutputGetClockSelect = 0x000F
+kQTVideoOutputSetEchoPortSelect = 0x0010
+kQTVideoOutputGetIndImageDecompressorSelect = 0x0011
+kQTVideoOutputBaseSetEchoPortSelect = 0x0012
+handlerHasSpatial = 1 << 0
+handlerCanClip = 1 << 1
+handlerCanMatte = 1 << 2
+handlerCanTransferMode = 1 << 3
+handlerNeedsBuffer = 1 << 4
+handlerNoIdle = 1 << 5
+handlerNoScheduler = 1 << 6
+handlerWantsTime = 1 << 7
+handlerCGrafPortOnly = 1 << 8
+handlerCanSend = 1 << 9
+handlerCanHandleComplexMatrix = 1 << 10
+handlerWantsDestinationPixels = 1 << 11
+handlerCanSendImageData = 1 << 12
+handlerCanPicSave = 1 << 13
+mMustDraw = 1 << 3
+mAtEnd = 1 << 4
+mPreflightDraw = 1 << 5
+mSyncDrawing = 1 << 6
+mPrecompositeOnly = 1 << 9
+mSoundOnly = 1 << 10
+mDoIdleActionsBeforeDraws = 1 << 11
+mDisableIdleActions = 1 << 12
+mDidDraw = 1 << 0
+mNeedsToDraw = 1 << 2
+mDrawAgain = 1 << 3
+mPartialDraw = 1 << 4
+mWantIdleActions = 1 << 5
+forceUpdateRedraw = 1 << 0
+forceUpdateNewBuffer = 1 << 1
+mHitTestBounds = 1L << 0
+mHitTestImage = 1L << 1
+mHitTestInvisible = 1L << 2
+mHitTestIsClick = 1L << 3
+mOpaque = 1L << 0
+mInvisible = 1L << 1
+kMediaQTIdleFrequencySelector = FOUR_CHAR_CODE('idfq')
+kMediaVideoParamBrightness = 1
+kMediaVideoParamContrast = 2
+kMediaVideoParamHue = 3
+kMediaVideoParamSharpness = 4
+kMediaVideoParamSaturation = 5
+kMediaVideoParamBlackLevel = 6
+kMediaVideoParamWhiteLevel = 7
+kMHInfoEncodedFrameRate = FOUR_CHAR_CODE('orat')
+kEmptyPurgableChunksOverAllowance = 1
+kCallComponentExecuteWiredActionSelect = -9
+kMediaSetChunkManagementFlagsSelect = 0x0415
+kMediaGetChunkManagementFlagsSelect = 0x0416
+kMediaSetPurgeableChunkMemoryAllowanceSelect = 0x0417
+kMediaGetPurgeableChunkMemoryAllowanceSelect = 0x0418
+kMediaEmptyAllPurgeableChunksSelect = 0x0419
+kMediaInitializeSelect = 0x0501
+kMediaSetHandlerCapabilitiesSelect = 0x0502
+kMediaIdleSelect = 0x0503
+kMediaGetMediaInfoSelect = 0x0504
+kMediaPutMediaInfoSelect = 0x0505
+kMediaSetActiveSelect = 0x0506
+kMediaSetRateSelect = 0x0507
+kMediaGGetStatusSelect = 0x0508
+kMediaTrackEditedSelect = 0x0509
+kMediaSetMediaTimeScaleSelect = 0x050A
+kMediaSetMovieTimeScaleSelect = 0x050B
+kMediaSetGWorldSelect = 0x050C
+kMediaSetDimensionsSelect = 0x050D
+kMediaSetClipSelect = 0x050E
+kMediaSetMatrixSelect = 0x050F
+kMediaGetTrackOpaqueSelect = 0x0510
+kMediaSetGraphicsModeSelect = 0x0511
+kMediaGetGraphicsModeSelect = 0x0512
+kMediaGSetVolumeSelect = 0x0513
+kMediaSetSoundBalanceSelect = 0x0514
+kMediaGetSoundBalanceSelect = 0x0515
+kMediaGetNextBoundsChangeSelect = 0x0516
+kMediaGetSrcRgnSelect = 0x0517
+kMediaPrerollSelect = 0x0518
+kMediaSampleDescriptionChangedSelect = 0x0519
+kMediaHasCharacteristicSelect = 0x051A
+kMediaGetOffscreenBufferSizeSelect = 0x051B
+kMediaSetHintsSelect = 0x051C
+kMediaGetNameSelect = 0x051D
+kMediaForceUpdateSelect = 0x051E
+kMediaGetDrawingRgnSelect = 0x051F
+kMediaGSetActiveSegmentSelect = 0x0520
+kMediaInvalidateRegionSelect = 0x0521
+kMediaGetNextStepTimeSelect = 0x0522
+kMediaSetNonPrimarySourceDataSelect = 0x0523
+kMediaChangedNonPrimarySourceSelect = 0x0524
+kMediaTrackReferencesChangedSelect = 0x0525
+kMediaGetSampleDataPointerSelect = 0x0526
+kMediaReleaseSampleDataPointerSelect = 0x0527
+kMediaTrackPropertyAtomChangedSelect = 0x0528
+kMediaSetTrackInputMapReferenceSelect = 0x0529
+kMediaSetVideoParamSelect = 0x052B
+kMediaGetVideoParamSelect = 0x052C
+kMediaCompareSelect = 0x052D
+kMediaGetClockSelect = 0x052E
+kMediaSetSoundOutputComponentSelect = 0x052F
+kMediaGetSoundOutputComponentSelect = 0x0530
+kMediaSetSoundLocalizationDataSelect = 0x0531
+kMediaGetInvalidRegionSelect = 0x053C
+kMediaSampleDescriptionB2NSelect = 0x053E
+kMediaSampleDescriptionN2BSelect = 0x053F
+kMediaQueueNonPrimarySourceDataSelect = 0x0540
+kMediaFlushNonPrimarySourceDataSelect = 0x0541
+kMediaGetURLLinkSelect = 0x0543
+kMediaMakeMediaTimeTableSelect = 0x0545
+kMediaHitTestForTargetRefConSelect = 0x0546
+kMediaHitTestTargetRefConSelect = 0x0547
+kMediaGetActionsForQTEventSelect = 0x0548
+kMediaDisposeTargetRefConSelect = 0x0549
+kMediaTargetRefConsEqualSelect = 0x054A
+kMediaSetActionsCallbackSelect = 0x054B
+kMediaPrePrerollBeginSelect = 0x054C
+kMediaPrePrerollCancelSelect = 0x054D
+kMediaEnterEmptyEditSelect = 0x054F
+kMediaCurrentMediaQueuedDataSelect = 0x0550
+kMediaGetEffectiveVolumeSelect = 0x0551
+kMediaResolveTargetRefConSelect = 0x0552
+kMediaGetSoundLevelMeteringEnabledSelect = 0x0553
+kMediaSetSoundLevelMeteringEnabledSelect = 0x0554
+kMediaGetSoundLevelMeterInfoSelect = 0x0555
+kMediaGetEffectiveSoundBalanceSelect = 0x0556
+kMediaSetScreenLockSelect = 0x0557
+kMediaSetDoMCActionCallbackSelect = 0x0558
+kMediaGetErrorStringSelect = 0x0559
+kMediaGetSoundEqualizerBandsSelect = 0x055A
+kMediaSetSoundEqualizerBandsSelect = 0x055B
+kMediaGetSoundEqualizerBandLevelsSelect = 0x055C
+kMediaDoIdleActionsSelect = 0x055D
+kMediaSetSoundBassAndTrebleSelect = 0x055E
+kMediaGetSoundBassAndTrebleSelect = 0x055F
+kMediaTimeBaseChangedSelect = 0x0560
+kMediaMCIsPlayerEventSelect = 0x0561
+kMediaGetMediaLoadStateSelect = 0x0562
+kMediaVideoOutputChangedSelect = 0x0563
+kMediaEmptySampleCacheSelect = 0x0564
+kMediaGetPublicInfoSelect = 0x0565
+kMediaSetPublicInfoSelect = 0x0566
+kMediaGetUserPreferredCodecsSelect = 0x0567
+kMediaSetUserPreferredCodecsSelect = 0x0568
+kMediaRefConSetPropertySelect = 0x0569
+kMediaRefConGetPropertySelect = 0x056A
+kMediaNavigateTargetRefConSelect = 0x056B
+kMediaGGetIdleManagerSelect = 0x056C
+kMediaGSetIdleManagerSelect = 0x056D
+kaiToneDescType = FOUR_CHAR_CODE('tone')
+kaiNoteRequestInfoType = FOUR_CHAR_CODE('ntrq')
+kaiKnobListType = FOUR_CHAR_CODE('knbl')
+kaiKeyRangeInfoType = FOUR_CHAR_CODE('sinf')
+kaiSampleDescType = FOUR_CHAR_CODE('sdsc')
+kaiSampleInfoType = FOUR_CHAR_CODE('smin')
+kaiSampleDataType = FOUR_CHAR_CODE('sdat')
+kaiSampleDataQUIDType = FOUR_CHAR_CODE('quid')
+kaiInstInfoType = FOUR_CHAR_CODE('iinf')
+kaiPictType = FOUR_CHAR_CODE('pict')
+kaiWriterType = FOUR_CHAR_CODE('\xa9wrt')
+kaiCopyrightType = FOUR_CHAR_CODE('\xa9cpy')
+kaiOtherStrType = FOUR_CHAR_CODE('str ')
+kaiInstrumentRefType = FOUR_CHAR_CODE('iref')
+kaiInstGMQualityType = FOUR_CHAR_CODE('qual')
+kaiLibraryInfoType = FOUR_CHAR_CODE('linf')
+kaiLibraryDescType = FOUR_CHAR_CODE('ldsc')
+kInstKnobMissingUnknown = 0
+kInstKnobMissingDefault = (1 << 0)
+kMusicLoopTypeNormal = 0
+kMusicLoopTypePalindrome = 1
+instSamplePreProcessFlag = 1 << 0
+kQTMIDIComponentType = FOUR_CHAR_CODE('midi')
+kOMSComponentSubType = FOUR_CHAR_CODE('OMS ')
+kFMSComponentSubType = FOUR_CHAR_CODE('FMS ')
+kMIDIManagerComponentSubType = FOUR_CHAR_CODE('mmgr')
+kOSXMIDIComponentSubType = FOUR_CHAR_CODE('osxm')
+kMusicPacketPortLost = 1
+kMusicPacketPortFound = 2
+kMusicPacketTimeGap = 3
+kAppleSysexID = 0x11
+kAppleSysexCmdSampleSize = 0x0001
+kAppleSysexCmdSampleBreak = 0x0002
+kAppleSysexCmdAtomicInstrument = 0x0010
+kAppleSysexCmdDeveloper = 0x7F00
+kSynthesizerConnectionFMS = 1
+kSynthesizerConnectionMMgr = 2
+kSynthesizerConnectionOMS = 4
+kSynthesizerConnectionQT = 8
+kSynthesizerConnectionOSXMIDI = 16
+kSynthesizerConnectionUnavailable = 256
+kMusicComponentType = FOUR_CHAR_CODE('musi')
+kInstrumentComponentType = FOUR_CHAR_CODE('inst')
+kSoftSynthComponentSubType = FOUR_CHAR_CODE('ss  ')
+kGMSynthComponentSubType = FOUR_CHAR_CODE('gm  ')
+kSynthesizerDynamicVoice = 1 << 0
+kSynthesizerUsesMIDIPort = 1 << 1
+kSynthesizerMicrotone = 1 << 2
+kSynthesizerHasSamples = 1 << 3
+kSynthesizerMixedDrums = 1 << 4
+kSynthesizerSoftware = 1 << 5
+kSynthesizerHardware = 1 << 6
+kSynthesizerDynamicChannel = 1 << 7
+kSynthesizerHogsSystemChannel = 1 << 8
+kSynthesizerHasSystemChannel = 1 << 9
+kSynthesizerSlowSetPart = 1 << 10
+kSynthesizerOffline = 1 << 12
+kSynthesizerGM = 1 << 14
+kSynthesizerDLS = 1 << 15
+kSynthesizerSoundLocalization = 1 << 16
+kControllerModulationWheel = 1
+kControllerBreath = 2
+kControllerFoot = 4
+kControllerPortamentoTime = 5
+kControllerVolume = 7
+kControllerBalance = 8
+kControllerPan = 10
+kControllerExpression = 11
+kControllerLever1 = 16
+kControllerLever2 = 17
+kControllerLever3 = 18
+kControllerLever4 = 19
+kControllerLever5 = 80
+kControllerLever6 = 81
+kControllerLever7 = 82
+kControllerLever8 = 83
+kControllerPitchBend = 32
+kControllerAfterTouch = 33
+kControllerPartTranspose = 40
+kControllerTuneTranspose = 41
+kControllerPartVolume = 42
+kControllerTuneVolume = 43
+kControllerSustain = 64
+kControllerPortamento = 65
+kControllerSostenuto = 66
+kControllerSoftPedal = 67
+kControllerReverb = 91
+kControllerTremolo = 92
+kControllerChorus = 93
+kControllerCeleste = 94
+kControllerPhaser = 95
+kControllerEditPart = 113
+kControllerMasterTune = 114
+kControllerMasterTranspose = 114
+kControllerMasterVolume = 115
+kControllerMasterCPULoad = 116
+kControllerMasterPolyphony = 117
+kControllerMasterFeatures = 118
+kQTMSKnobStartID = 0x02000000
+kQTMSKnobVolumeAttackTimeID = 0x02000001
+kQTMSKnobVolumeDecayTimeID = 0x02000002
+kQTMSKnobVolumeSustainLevelID = 0x02000003
+kQTMSKnobVolumeRelease1RateID = 0x02000004
+kQTMSKnobVolumeDecayKeyScalingID = 0x02000005
+kQTMSKnobVolumeReleaseTimeID = 0x02000006
+kQTMSKnobVolumeLFODelayID = 0x02000007
+kQTMSKnobVolumeLFORampTimeID = 0x02000008
+kQTMSKnobVolumeLFOPeriodID = 0x02000009
+kQTMSKnobVolumeLFOShapeID = 0x0200000A
+kQTMSKnobVolumeLFODepthID = 0x0200000B
+kQTMSKnobVolumeOverallID = 0x0200000C
+kQTMSKnobVolumeVelocity127ID = 0x0200000D
+kQTMSKnobVolumeVelocity96ID = 0x0200000E
+kQTMSKnobVolumeVelocity64ID = 0x0200000F
+kQTMSKnobVolumeVelocity32ID = 0x02000010
+kQTMSKnobVolumeVelocity16ID = 0x02000011
+kQTMSKnobPitchTransposeID = 0x02000012
+kQTMSKnobPitchLFODelayID = 0x02000013
+kQTMSKnobPitchLFORampTimeID = 0x02000014
+kQTMSKnobPitchLFOPeriodID = 0x02000015
+kQTMSKnobPitchLFOShapeID = 0x02000016
+kQTMSKnobPitchLFODepthID = 0x02000017
+kQTMSKnobPitchLFOQuantizeID = 0x02000018
+kQTMSKnobStereoDefaultPanID = 0x02000019
+kQTMSKnobStereoPositionKeyScalingID = 0x0200001A
+kQTMSKnobPitchLFOOffsetID = 0x0200001B
+kQTMSKnobExclusionGroupID = 0x0200001C
+kQTMSKnobSustainTimeID = 0x0200001D
+kQTMSKnobSustainInfiniteID = 0x0200001E
+kQTMSKnobVolumeLFOStereoID = 0x0200001F
+kQTMSKnobVelocityLowID = 0x02000020
+kQTMSKnobVelocityHighID = 0x02000021
+kQTMSKnobVelocitySensitivityID = 0x02000022
+kQTMSKnobPitchSensitivityID = 0x02000023
+kQTMSKnobVolumeLFODepthFromWheelID = 0x02000024
+kQTMSKnobPitchLFODepthFromWheelID = 0x02000025
+kQTMSKnobVolumeExpOptionsID = 0x02000026
+kQTMSKnobEnv1AttackTimeID = 0x02000027
+kQTMSKnobEnv1DecayTimeID = 0x02000028
+kQTMSKnobEnv1SustainLevelID = 0x02000029
+kQTMSKnobEnv1SustainTimeID = 0x0200002A
+kQTMSKnobEnv1SustainInfiniteID = 0x0200002B
+kQTMSKnobEnv1ReleaseTimeID = 0x0200002C
+kQTMSKnobEnv1ExpOptionsID = 0x0200002D
+kQTMSKnobEnv2AttackTimeID = 0x0200002E
+kQTMSKnobEnv2DecayTimeID = 0x0200002F
+kQTMSKnobEnv2SustainLevelID = 0x02000030
+kQTMSKnobEnv2SustainTimeID = 0x02000031
+kQTMSKnobEnv2SustainInfiniteID = 0x02000032
+kQTMSKnobEnv2ReleaseTimeID = 0x02000033
+kQTMSKnobEnv2ExpOptionsID = 0x02000034
+kQTMSKnobPitchEnvelopeID = 0x02000035
+kQTMSKnobPitchEnvelopeDepthID = 0x02000036
+kQTMSKnobFilterKeyFollowID = 0x02000037
+kQTMSKnobFilterTransposeID = 0x02000038
+kQTMSKnobFilterQID = 0x02000039
+kQTMSKnobFilterFrequencyEnvelopeID = 0x0200003A
+kQTMSKnobFilterFrequencyEnvelopeDepthID = 0x0200003B
+kQTMSKnobFilterQEnvelopeID = 0x0200003C
+kQTMSKnobFilterQEnvelopeDepthID = 0x0200003D
+kQTMSKnobReverbThresholdID = 0x0200003E
+kQTMSKnobVolumeAttackVelScalingID = 0x0200003F
+kQTMSKnobLastIDPlus1 = 0x02000040
+kControllerMaximum = 0x00007FFF
+# kControllerMinimum = (long)0xFFFF8000
+kVoiceCountDynamic = -1
+kFirstGMInstrument = 0x00000001
+kLastGMInstrument = 0x00000080
+kFirstGSInstrument = 0x00000081
+kLastGSInstrument = 0x00003FFF
+kFirstDrumkit = 0x00004000
+kLastDrumkit = 0x00004080
+kFirstROMInstrument = 0x00008000
+kLastROMInstrument = 0x0000FFFF
+kFirstUserInstrument = 0x00010000
+kLastUserInstrument = 0x0001FFFF
+kInstrumentMatchSynthesizerType = 1
+kInstrumentMatchSynthesizerName = 2
+kInstrumentMatchName = 4
+kInstrumentMatchNumber = 8
+kInstrumentMatchGMNumber = 16
+kInstrumentMatchGSNumber = 32
+kKnobBasic = 8
+kKnobReadOnly = 16
+kKnobInterruptUnsafe = 32
+kKnobKeyrangeOverride = 64
+kKnobGroupStart = 128
+kKnobFixedPoint8 = 1024
+kKnobFixedPoint16 = 2048
+kKnobTypeNumber = 0 << 12
+kKnobTypeGroupName = 1 << 12
+kKnobTypeBoolean = 2 << 12
+kKnobTypeNote = 3 << 12
+kKnobTypePan = 4 << 12
+kKnobTypeInstrument = 5 << 12
+kKnobTypeSetting = 6 << 12
+kKnobTypeMilliseconds = 7 << 12
+kKnobTypePercentage = 8 << 12
+kKnobTypeHertz = 9 << 12
+kKnobTypeButton = 10 << 12
+kUnknownKnobValue = 0x7FFFFFFF
+kDefaultKnobValue = 0x7FFFFFFE
+notImplementedMusicErr = (0x80000000 | (0xFFFF & (notImplementedMusicOSErr)))
+cantSendToSynthesizerErr = (0x80000000 | (0xFFFF & (cantSendToSynthesizerOSErr)))
+cantReceiveFromSynthesizerErr = (0x80000000 | (0xFFFF & (cantReceiveFromSynthesizerOSErr)))
+illegalVoiceAllocationErr = (0x80000000 | (0xFFFF & (illegalVoiceAllocationOSErr)))
+illegalPartErr = (0x80000000 | (0xFFFF & (illegalPartOSErr)))
+illegalChannelErr = (0x80000000 | (0xFFFF & (illegalChannelOSErr)))
+illegalKnobErr = (0x80000000 | (0xFFFF & (illegalKnobOSErr)))
+illegalKnobValueErr = (0x80000000 | (0xFFFF & (illegalKnobValueOSErr)))
+illegalInstrumentErr = (0x80000000 | (0xFFFF & (illegalInstrumentOSErr)))
+illegalControllerErr = (0x80000000 | (0xFFFF & (illegalControllerOSErr)))
+midiManagerAbsentErr = (0x80000000 | (0xFFFF & (midiManagerAbsentOSErr)))
+synthesizerNotRespondingErr = (0x80000000 | (0xFFFF & (synthesizerNotRespondingOSErr)))
+synthesizerErr = (0x80000000 | (0xFFFF & (synthesizerOSErr)))
+illegalNoteChannelErr = (0x80000000 | (0xFFFF & (illegalNoteChannelOSErr)))
+noteChannelNotAllocatedErr = (0x80000000 | (0xFFFF & (noteChannelNotAllocatedOSErr)))
+tunePlayerFullErr = (0x80000000 | (0xFFFF & (tunePlayerFullOSErr)))
+tuneParseErr = (0x80000000 | (0xFFFF & (tuneParseOSErr)))
+kGetAtomicInstNoExpandedSamples = 1 << 0
+kGetAtomicInstNoOriginalSamples = 1 << 1
+kGetAtomicInstNoSamples = kGetAtomicInstNoExpandedSamples | kGetAtomicInstNoOriginalSamples
+kGetAtomicInstNoKnobList = 1 << 2
+kGetAtomicInstNoInstrumentInfo = 1 << 3
+kGetAtomicInstOriginalKnobList = 1 << 4
+kGetAtomicInstAllKnobs = 1 << 5
+kSetAtomicInstKeepOriginalInstrument = 1 << 0
+kSetAtomicInstShareAcrossParts = 1 << 1
+kSetAtomicInstCallerTosses = 1 << 2
+kSetAtomicInstCallerGuarantees = 1 << 3
+kSetAtomicInstInterruptSafe = 1 << 4
+kSetAtomicInstDontPreprocess = 1 << 7
+kInstrumentNamesModifiable = 1
+kInstrumentNamesBoth = 2
+kGenericMusicComponentSubtype = FOUR_CHAR_CODE('gene')
+kGenericMusicKnob = 1
+kGenericMusicInstrumentKnob = 2
+kGenericMusicDrumKnob = 3
+kGenericMusicGlobalController = 4
+kGenericMusicResFirst = 0
+kGenericMusicResMiscStringList = 1
+kGenericMusicResMiscLongList = 2
+kGenericMusicResInstrumentList = 3
+kGenericMusicResDrumList = 4
+kGenericMusicResInstrumentKnobDescriptionList = 5
+kGenericMusicResDrumKnobDescriptionList = 6
+kGenericMusicResKnobDescriptionList = 7
+kGenericMusicResBitsLongList = 8
+kGenericMusicResModifiableInstrumentHW = 9
+kGenericMusicResGMTranslation = 10
+kGenericMusicResROMInstrumentData = 11
+kGenericMusicResAboutPICT = 12
+kGenericMusicResLast = 13
+kGenericMusicMiscLongFirst = 0
+kGenericMusicMiscLongVoiceCount = 1
+kGenericMusicMiscLongPartCount = 2
+kGenericMusicMiscLongModifiableInstrumentCount = 3
+kGenericMusicMiscLongChannelMask = 4
+kGenericMusicMiscLongDrumPartCount = 5
+kGenericMusicMiscLongModifiableDrumCount = 6
+kGenericMusicMiscLongDrumChannelMask = 7
+kGenericMusicMiscLongOutputCount = 8
+kGenericMusicMiscLongLatency = 9
+kGenericMusicMiscLongFlags = 10
+kGenericMusicMiscLongFirstGMHW = 11
+kGenericMusicMiscLongFirstGMDrumHW = 12
+kGenericMusicMiscLongFirstUserHW = 13
+kGenericMusicMiscLongLast = 14
+kMusicGenericRange = 0x0100
+kMusicDerivedRange = 0x0200
+kGenericMusicDoMIDI = 1 << 0
+kGenericMusicBank0 = 1 << 1
+kGenericMusicBank32 = 1 << 2
+kGenericMusicErsatzMIDI = 1 << 3
+kGenericMusicCallKnobs = 1 << 4
+kGenericMusicCallParts = 1 << 5
+kGenericMusicCallInstrument = 1 << 6
+kGenericMusicCallNumber = 1 << 7
+kGenericMusicCallROMInstrument = 1 << 8
+kGenericMusicAllDefaults = 1 << 9
+kGetInstrumentInfoNoBuiltIn = 1 << 0
+kGetInstrumentInfoMidiUserInst = 1 << 1
+kGetInstrumentInfoNoIText = 1 << 2
+kNoteRequestNoGM = 1
+kNoteRequestNoSynthType = 2
+kNoteRequestSynthMustMatch = 4
+kNoteRequestSpecifyMIDIChannel = 0x80
+kPickDontMix = 1
+kPickSameSynth = 2
+kPickUserInsts = 4
+kPickEditAllowEdit = 8
+kPickEditAllowPick = 16
+kPickEditSynthGlobal = 32
+kPickEditControllers = 64
+kNoteAllocatorComponentType = FOUR_CHAR_CODE('nota')
+kNADummyOneSelect = 29
+kNADummyTwoSelect = 30
+kTuneQueueDepth = 8
+kTunePlayerComponentType = FOUR_CHAR_CODE('tune')
+kTuneStartNow = 1
+kTuneDontClipNotes = 2
+kTuneExcludeEdgeNotes = 4
+kTuneQuickStart = 8
+kTuneLoopUntil = 16
+kTunePlayDifference = 32
+kTunePlayConcurrent = 64
+kTuneStartNewMaster = 16384
+kTuneStopFade = 1
+kTuneStopSustain = 2
+kTuneStopInstant = 4
+kTuneStopReleaseChannels = 8
+kTuneMixMute = 1
+kTuneMixSolo = 2
+kRestEventType = 0x00000000
+kNoteEventType = 0x00000001
+kControlEventType = 0x00000002
+kMarkerEventType = 0x00000003
+kUndefined1EventType = 0x00000008
+kXNoteEventType = 0x00000009
+kXControlEventType = 0x0000000A
+kKnobEventType = 0x0000000B
+kUndefined2EventType = 0x0000000C
+kUndefined3EventType = 0x0000000D
+kUndefined4EventType = 0x0000000E
+kGeneralEventType = 0x0000000F
+kXEventLengthBits = 0x00000002
+kGeneralEventLengthBits = 0x00000003
+kEventLen = 1L
+kXEventLen = 2L
+kRestEventLen = kEventLen
+kNoteEventLen = kEventLen
+kControlEventLen = kEventLen
+kMarkerEventLen = kEventLen
+kXNoteEventLen = kXEventLen
+kXControlEventLen = kXEventLen
+kGeneralEventLen = kXEventLen
+kEventLengthFieldPos = 30
+kEventLengthFieldWidth = 2
+kEventTypeFieldPos = 29
+kEventTypeFieldWidth = 3
+kXEventTypeFieldPos = 28
+kXEventTypeFieldWidth = 4
+kEventPartFieldPos = 24
+kEventPartFieldWidth = 5
+kXEventPartFieldPos = 16
+kXEventPartFieldWidth = 12
+kRestEventDurationFieldPos = 0
+kRestEventDurationFieldWidth = 24
+kRestEventDurationMax = ((1L << kRestEventDurationFieldWidth) - 1)
+kNoteEventPitchFieldPos = 18
+kNoteEventPitchFieldWidth = 6
+kNoteEventPitchOffset = 32
+kNoteEventVolumeFieldPos = 11
+kNoteEventVolumeFieldWidth = 7
+kNoteEventVolumeOffset = 0
+kNoteEventDurationFieldPos = 0
+kNoteEventDurationFieldWidth = 11
+kNoteEventDurationMax = ((1L << kNoteEventDurationFieldWidth) - 1)
+kXNoteEventPitchFieldPos = 0
+kXNoteEventPitchFieldWidth = 16
+kXNoteEventDurationFieldPos = 0
+kXNoteEventDurationFieldWidth = 22
+kXNoteEventDurationMax = ((1L << kXNoteEventDurationFieldWidth) - 1)
+kXNoteEventVolumeFieldPos = 22
+kXNoteEventVolumeFieldWidth = 7
+kControlEventControllerFieldPos = 16
+kControlEventControllerFieldWidth = 8
+kControlEventValueFieldPos = 0
+kControlEventValueFieldWidth = 16
+kXControlEventControllerFieldPos = 0
+kXControlEventControllerFieldWidth = 16
+kXControlEventValueFieldPos = 0
+kXControlEventValueFieldWidth = 16
+kKnobEventValueHighFieldPos = 0
+kKnobEventValueHighFieldWidth = 16
+kKnobEventKnobFieldPos = 16
+kKnobEventKnobFieldWidth = 14
+kKnobEventValueLowFieldPos = 0
+kKnobEventValueLowFieldWidth = 16
+kMarkerEventSubtypeFieldPos = 16
+kMarkerEventSubtypeFieldWidth = 8
+kMarkerEventValueFieldPos = 0
+kMarkerEventValueFieldWidth = 16
+kGeneralEventSubtypeFieldPos = 16
+kGeneralEventSubtypeFieldWidth = 14
+kGeneralEventLengthFieldPos = 0
+kGeneralEventLengthFieldWidth = 16
+kEndMarkerValue = 0x00000060
+kEndMarkerValue = 0x60000000
+# _ext = qtma_EXT(*lP
+# ulen = (_ext < 2) ? 1 : 2
+# ulen = (unsigned short)qtma_EXT(*lP
+# ulen = lP[1]
+# _ext = qtma_EXT(*lP
+# ulen = (_ext < 2) ? 1 : 2
+# ulen = (unsigned short)qtma_EXT(*lP
+# ulen = lP[-1]
+# x = (kRestEventType << kEventTypeFieldPos)   \
+# x = EndianU32_NtoB(x) )
+# x = (kNoteEventType << kEventTypeFieldPos)  \
+# x = EndianU32_NtoB(x) )
+# x = (kControlEventType << kEventTypeFieldPos)           \
+# x = EndianU32_NtoB(x) )
+# x = (kMarkerEventType << kEventTypeFieldPos)    \
+# x = EndianU32_NtoB(x) )
+# w1 = (kXNoteEventType << kXEventTypeFieldPos)            \
+# w1 = EndianU32_NtoB(w1)
+# w2 = (kXEventLengthBits << kEventLengthFieldPos)        \
+# w2 = EndianU32_NtoB(w2) )
+# w1 = (kXControlEventType << kXEventTypeFieldPos)             \
+# w1 = EndianU32_NtoB(w1)
+# w2 = (kXEventLengthBits << kEventLengthFieldPos)             \
+# w2 = EndianU32_NtoB(w2) )
+# w1 = (kKnobEventType << kXEventTypeFieldPos)                 \
+# w1 = EndianU32_NtoB(w1)
+# w2 = (kXEventLengthBits << kEventLengthFieldPos)             \
+# w2 = EndianU32_NtoB(w2) )
+# w1 = (kGeneralEventType << kXEventTypeFieldPos)              \
+# w1 = EndianU32_NtoB(w1)
+# w2 = (kGeneralEventLengthBits << kEventLengthFieldPos)          \
+# w2 = EndianU32_NtoB(w2) )
+kGeneralEventNoteRequest = 1
+kGeneralEventPartKey = 4
+kGeneralEventTuneDifference = 5
+kGeneralEventAtomicInstrument = 6
+kGeneralEventKnob = 7
+kGeneralEventMIDIChannel = 8
+kGeneralEventPartChange = 9
+kGeneralEventNoOp = 10
+kGeneralEventUsedNotes = 11
+kGeneralEventPartMix = 12
+kMarkerEventEnd = 0
+kMarkerEventBeat = 1
+kMarkerEventTempo = 2
+kCurrentlyNativeEndian = 1
+kCurrentlyNotNativeEndian = 2
+kQTMIDIGetMIDIPortsSelect = 0x0001
+kQTMIDIUseSendPortSelect = 0x0002
+kQTMIDISendMIDISelect = 0x0003
+kMusicGetDescriptionSelect = 0x0001
+kMusicGetPartSelect = 0x0002
+kMusicSetPartSelect = 0x0003
+kMusicSetPartInstrumentNumberSelect = 0x0004
+kMusicGetPartInstrumentNumberSelect = 0x0005
+kMusicStorePartInstrumentSelect = 0x0006
+kMusicGetPartAtomicInstrumentSelect = 0x0009
+kMusicSetPartAtomicInstrumentSelect = 0x000A
+kMusicGetPartKnobSelect = 0x0010
+kMusicSetPartKnobSelect = 0x0011
+kMusicGetKnobSelect = 0x0012
+kMusicSetKnobSelect = 0x0013
+kMusicGetPartNameSelect = 0x0014
+kMusicSetPartNameSelect = 0x0015
+kMusicFindToneSelect = 0x0016
+kMusicPlayNoteSelect = 0x0017
+kMusicResetPartSelect = 0x0018
+kMusicSetPartControllerSelect = 0x0019
+kMusicGetPartControllerSelect = 0x001A
+kMusicGetMIDIProcSelect = 0x001B
+kMusicSetMIDIProcSelect = 0x001C
+kMusicGetInstrumentNamesSelect = 0x001D
+kMusicGetDrumNamesSelect = 0x001E
+kMusicGetMasterTuneSelect = 0x001F
+kMusicSetMasterTuneSelect = 0x0020
+kMusicGetInstrumentAboutInfoSelect = 0x0022
+kMusicGetDeviceConnectionSelect = 0x0023
+kMusicUseDeviceConnectionSelect = 0x0024
+kMusicGetKnobSettingStringsSelect = 0x0025
+kMusicGetMIDIPortsSelect = 0x0026
+kMusicSendMIDISelect = 0x0027
+kMusicStartOfflineSelect = 0x0029
+kMusicSetOfflineTimeToSelect = 0x002A
+kMusicGetInstrumentKnobDescriptionSelect = 0x002B
+kMusicGetDrumKnobDescriptionSelect = 0x002C
+kMusicGetKnobDescriptionSelect = 0x002D
+kMusicGetInfoTextSelect = 0x002E
+kMusicGetInstrumentInfoSelect = 0x002F
+kMusicTaskSelect = 0x0031
+kMusicSetPartInstrumentNumberInterruptSafeSelect = 0x0032
+kMusicSetPartSoundLocalizationSelect = 0x0033
+kMusicGenericConfigureSelect = 0x0100
+kMusicGenericGetPartSelect = 0x0101
+kMusicGenericGetKnobListSelect = 0x0102
+kMusicGenericSetResourceNumbersSelect = 0x0103
+kMusicDerivedMIDISendSelect = 0x0200
+kMusicDerivedSetKnobSelect = 0x0201
+kMusicDerivedSetPartSelect = 0x0202
+kMusicDerivedSetInstrumentSelect = 0x0203
+kMusicDerivedSetPartInstrumentNumberSelect = 0x0204
+kMusicDerivedSetMIDISelect = 0x0205
+kMusicDerivedStorePartInstrumentSelect = 0x0206
+kMusicDerivedOpenResFileSelect = 0x0207
+kMusicDerivedCloseResFileSelect = 0x0208
+kNARegisterMusicDeviceSelect = 0x0000
+kNAUnregisterMusicDeviceSelect = 0x0001
+kNAGetRegisteredMusicDeviceSelect = 0x0002
+kNASaveMusicConfigurationSelect = 0x0003
+kNANewNoteChannelSelect = 0x0004
+kNADisposeNoteChannelSelect = 0x0005
+kNAGetNoteChannelInfoSelect = 0x0006
+kNAPrerollNoteChannelSelect = 0x0007
+kNAUnrollNoteChannelSelect = 0x0008
+kNASetNoteChannelVolumeSelect = 0x000B
+kNAResetNoteChannelSelect = 0x000C
+kNAPlayNoteSelect = 0x000D
+kNASetControllerSelect = 0x000E
+kNASetKnobSelect = 0x000F
+kNAFindNoteChannelToneSelect = 0x0010
+kNASetInstrumentNumberSelect = 0x0011
+kNAPickInstrumentSelect = 0x0012
+kNAPickArrangementSelect = 0x0013
+kNAStuffToneDescriptionSelect = 0x001B
+kNACopyrightDialogSelect = 0x001C
+kNAGetIndNoteChannelSelect = 0x001F
+kNAGetMIDIPortsSelect = 0x0021
+kNAGetNoteRequestSelect = 0x0022
+kNASendMIDISelect = 0x0023
+kNAPickEditInstrumentSelect = 0x0024
+kNANewNoteChannelFromAtomicInstrumentSelect = 0x0025
+kNASetAtomicInstrumentSelect = 0x0026
+kNAGetKnobSelect = 0x0028
+kNATaskSelect = 0x0029
+kNASetNoteChannelBalanceSelect = 0x002A
+kNASetInstrumentNumberInterruptSafeSelect = 0x002B
+kNASetNoteChannelSoundLocalizationSelect = 0x002C
+kNAGetControllerSelect = 0x002D
+kTuneSetHeaderSelect = 0x0004
+kTuneGetTimeBaseSelect = 0x0005
+kTuneSetTimeScaleSelect = 0x0006
+kTuneGetTimeScaleSelect = 0x0007
+kTuneGetIndexedNoteChannelSelect = 0x0008
+kTuneQueueSelect = 0x000A
+kTuneInstantSelect = 0x000B
+kTuneGetStatusSelect = 0x000C
+kTuneStopSelect = 0x000D
+kTuneSetVolumeSelect = 0x0010
+kTuneGetVolumeSelect = 0x0011
+kTunePrerollSelect = 0x0012
+kTuneUnrollSelect = 0x0013
+kTuneSetNoteChannelsSelect = 0x0014
+kTuneSetPartTransposeSelect = 0x0015
+kTuneGetNoteAllocatorSelect = 0x0017
+kTuneSetSofterSelect = 0x0018
+kTuneTaskSelect = 0x0019
+kTuneSetBalanceSelect = 0x001A
+kTuneSetSoundLocalizationSelect = 0x001B
+kTuneSetHeaderWithSizeSelect = 0x001C
+kTuneSetPartMixSelect = 0x001D
+kTuneGetPartMixSelect = 0x001E

Added: vendor/Python/current/Lib/plat-mac/Carbon/Res.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/Res.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/Res.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,4 @@
+try:
+    from OverrideFrom23._Res import *
+except ImportError:
+    from _Res import *

Added: vendor/Python/current/Lib/plat-mac/Carbon/Resources.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/Resources.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/Resources.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,27 @@
+# Generated from 'Resources.h'
+
+resSysHeap = 64
+resPurgeable = 32
+resLocked = 16
+resProtected = 8
+resPreload = 4
+resChanged = 2
+mapReadOnly = 128
+mapCompact = 64
+mapChanged = 32
+resSysRefBit = 7
+resSysHeapBit = 6
+resPurgeableBit = 5
+resLockedBit = 4
+resProtectedBit = 3
+resPreloadBit = 2
+resChangedBit = 1
+mapReadOnlyBit = 7
+mapCompactBit = 6
+mapChangedBit = 5
+kResFileNotOpened = -1
+kSystemResFile = 0
+kRsrcChainBelowSystemMap = 0
+kRsrcChainBelowApplicationMap = 1
+kRsrcChainAboveApplicationMap = 2
+kRsrcChainAboveAllMaps = 4

Added: vendor/Python/current/Lib/plat-mac/Carbon/Scrap.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/Scrap.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/Scrap.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1 @@
+from _Scrap import *

Added: vendor/Python/current/Lib/plat-mac/Carbon/Snd.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/Snd.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/Snd.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1 @@
+from _Snd import *

Added: vendor/Python/current/Lib/plat-mac/Carbon/Sndihooks.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/Sndihooks.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/Sndihooks.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1 @@
+from _Sndihooks import *

Added: vendor/Python/current/Lib/plat-mac/Carbon/Sound.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/Sound.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/Sound.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,400 @@
+# Generated from 'Sound.h'
+
+def FOUR_CHAR_CODE(x): return x
+soundListRsrc = FOUR_CHAR_CODE('snd ')
+kSimpleBeepID = 1
+# rate48khz = (long)0xBB800000
+# rate44khz = (long)0xAC440000
+rate32khz = 0x7D000000
+rate22050hz = 0x56220000
+rate22khz = 0x56EE8BA3
+rate16khz = 0x3E800000
+rate11khz = 0x2B7745D1
+rate11025hz = 0x2B110000
+rate8khz = 0x1F400000
+sampledSynth = 5
+squareWaveSynth = 1
+waveTableSynth = 3
+MACE3snthID = 11
+MACE6snthID = 13
+kMiddleC = 60
+kNoVolume = 0
+kFullVolume = 0x0100
+stdQLength = 128
+dataOffsetFlag = 0x8000
+kUseOptionalOutputDevice = -1
+notCompressed = 0
+fixedCompression = -1
+variableCompression = -2
+twoToOne = 1
+eightToThree = 2
+threeToOne = 3
+sixToOne = 4
+sixToOnePacketSize = 8
+threeToOnePacketSize = 16
+stateBlockSize = 64
+leftOverBlockSize = 32
+firstSoundFormat = 0x0001
+secondSoundFormat = 0x0002
+dbBufferReady = 0x00000001
+dbLastBuffer = 0x00000004
+sysBeepDisable = 0x0000
+sysBeepEnable = (1 << 0)
+sysBeepSynchronous = (1 << 1)
+unitTypeNoSelection = 0xFFFF
+unitTypeSeconds = 0x0000
+stdSH = 0x00
+extSH = 0xFF
+cmpSH = 0xFE
+nullCmd = 0
+quietCmd = 3
+flushCmd = 4
+reInitCmd = 5
+waitCmd = 10
+pauseCmd = 11
+resumeCmd = 12
+callBackCmd = 13
+syncCmd = 14
+availableCmd = 24
+versionCmd = 25
+volumeCmd = 46
+getVolumeCmd = 47
+clockComponentCmd = 50
+getClockComponentCmd = 51
+scheduledSoundCmd = 52
+linkSoundComponentsCmd = 53
+soundCmd = 80
+bufferCmd = 81
+rateMultiplierCmd = 86
+getRateMultiplierCmd = 87
+initCmd = 1
+freeCmd = 2
+totalLoadCmd = 26
+loadCmd = 27
+freqDurationCmd = 40
+restCmd = 41
+freqCmd = 42
+ampCmd = 43
+timbreCmd = 44
+getAmpCmd = 45
+waveTableCmd = 60
+phaseCmd = 61
+rateCmd = 82
+continueCmd = 83
+doubleBufferCmd = 84
+getRateCmd = 85
+sizeCmd = 90
+convertCmd = 91
+waveInitChannelMask = 0x07
+waveInitChannel0 = 0x04
+waveInitChannel1 = 0x05
+waveInitChannel2 = 0x06
+waveInitChannel3 = 0x07
+initChan0 = waveInitChannel0
+initChan1 = waveInitChannel1
+initChan2 = waveInitChannel2
+initChan3 = waveInitChannel3
+outsideCmpSH = 0
+insideCmpSH = 1
+aceSuccess = 0
+aceMemFull = 1
+aceNilBlock = 2
+aceBadComp = 3
+aceBadEncode = 4
+aceBadDest = 5
+aceBadCmd = 6
+initChanLeft = 0x0002
+initChanRight = 0x0003
+initNoInterp = 0x0004
+initNoDrop = 0x0008
+initMono = 0x0080
+initStereo = 0x00C0
+initMACE3 = 0x0300
+initMACE6 = 0x0400
+initPanMask = 0x0003
+initSRateMask = 0x0030
+initStereoMask = 0x00C0
+initCompMask = 0xFF00
+siActiveChannels = FOUR_CHAR_CODE('chac')
+siActiveLevels = FOUR_CHAR_CODE('lmac')
+siAGCOnOff = FOUR_CHAR_CODE('agc ')
+siAsync = FOUR_CHAR_CODE('asyn')
+siAVDisplayBehavior = FOUR_CHAR_CODE('avdb')
+siChannelAvailable = FOUR_CHAR_CODE('chav')
+siCompressionAvailable = FOUR_CHAR_CODE('cmav')
+siCompressionChannels = FOUR_CHAR_CODE('cpct')
+siCompressionFactor = FOUR_CHAR_CODE('cmfa')
+siCompressionHeader = FOUR_CHAR_CODE('cmhd')
+siCompressionNames = FOUR_CHAR_CODE('cnam')
+siCompressionParams = FOUR_CHAR_CODE('evaw')
+siCompressionSampleRate = FOUR_CHAR_CODE('cprt')
+siCompressionType = FOUR_CHAR_CODE('comp')
+siContinuous = FOUR_CHAR_CODE('cont')
+siDecompressionParams = FOUR_CHAR_CODE('wave')
+siDeviceBufferInfo = FOUR_CHAR_CODE('dbin')
+siDeviceConnected = FOUR_CHAR_CODE('dcon')
+siDeviceIcon = FOUR_CHAR_CODE('icon')
+siDeviceName = FOUR_CHAR_CODE('name')
+siEQSpectrumBands = FOUR_CHAR_CODE('eqsb')
+siEQSpectrumLevels = FOUR_CHAR_CODE('eqlv')
+siEQSpectrumOnOff = FOUR_CHAR_CODE('eqlo')
+siEQSpectrumResolution = FOUR_CHAR_CODE('eqrs')
+siEQToneControlGain = FOUR_CHAR_CODE('eqtg')
+siEQToneControlOnOff = FOUR_CHAR_CODE('eqtc')
+siHardwareBalance = FOUR_CHAR_CODE('hbal')
+siHardwareBalanceSteps = FOUR_CHAR_CODE('hbls')
+siHardwareBass = FOUR_CHAR_CODE('hbas')
+siHardwareBassSteps = FOUR_CHAR_CODE('hbst')
+siHardwareBusy = FOUR_CHAR_CODE('hwbs')
+siHardwareFormat = FOUR_CHAR_CODE('hwfm')
+siHardwareMute = FOUR_CHAR_CODE('hmut')
+siHardwareMuteNoPrefs = FOUR_CHAR_CODE('hmnp')
+siHardwareTreble = FOUR_CHAR_CODE('htrb')
+siHardwareTrebleSteps = FOUR_CHAR_CODE('hwts')
+siHardwareVolume = FOUR_CHAR_CODE('hvol')
+siHardwareVolumeSteps = FOUR_CHAR_CODE('hstp')
+siHeadphoneMute = FOUR_CHAR_CODE('pmut')
+siHeadphoneVolume = FOUR_CHAR_CODE('pvol')
+siHeadphoneVolumeSteps = FOUR_CHAR_CODE('hdst')
+siInputAvailable = FOUR_CHAR_CODE('inav')
+siInputGain = FOUR_CHAR_CODE('gain')
+siInputSource = FOUR_CHAR_CODE('sour')
+siInputSourceNames = FOUR_CHAR_CODE('snam')
+siLevelMeterOnOff = FOUR_CHAR_CODE('lmet')
+siModemGain = FOUR_CHAR_CODE('mgai')
+siMonitorAvailable = FOUR_CHAR_CODE('mnav')
+siMonitorSource = FOUR_CHAR_CODE('mons')
+siNumberChannels = FOUR_CHAR_CODE('chan')
+siOptionsDialog = FOUR_CHAR_CODE('optd')
+siOSTypeInputSource = FOUR_CHAR_CODE('inpt')
+siOSTypeInputAvailable = FOUR_CHAR_CODE('inav')
+siOutputDeviceName = FOUR_CHAR_CODE('onam')
+siPlayThruOnOff = FOUR_CHAR_CODE('plth')
+siPostMixerSoundComponent = FOUR_CHAR_CODE('psmx')
+siPreMixerSoundComponent = FOUR_CHAR_CODE('prmx')
+siQuality = FOUR_CHAR_CODE('qual')
+siRateMultiplier = FOUR_CHAR_CODE('rmul')
+siRecordingQuality = FOUR_CHAR_CODE('qual')
+siSampleRate = FOUR_CHAR_CODE('srat')
+siSampleRateAvailable = FOUR_CHAR_CODE('srav')
+siSampleSize = FOUR_CHAR_CODE('ssiz')
+siSampleSizeAvailable = FOUR_CHAR_CODE('ssav')
+siSetupCDAudio = FOUR_CHAR_CODE('sucd')
+siSetupModemAudio = FOUR_CHAR_CODE('sumd')
+siSlopeAndIntercept = FOUR_CHAR_CODE('flap')
+siSoundClock = FOUR_CHAR_CODE('sclk')
+siUseThisSoundClock = FOUR_CHAR_CODE('sclc')
+siSpeakerMute = FOUR_CHAR_CODE('smut')
+siSpeakerVolume = FOUR_CHAR_CODE('svol')
+siSSpCPULoadLimit = FOUR_CHAR_CODE('3dll')
+siSSpLocalization = FOUR_CHAR_CODE('3dif')
+siSSpSpeakerSetup = FOUR_CHAR_CODE('3dst')
+siStereoInputGain = FOUR_CHAR_CODE('sgai')
+siSubwooferMute = FOUR_CHAR_CODE('bmut')
+siTerminalType = FOUR_CHAR_CODE('ttyp')
+siTwosComplementOnOff = FOUR_CHAR_CODE('twos')
+siVendorProduct = FOUR_CHAR_CODE('vpro')
+siVolume = FOUR_CHAR_CODE('volu')
+siVoxRecordInfo = FOUR_CHAR_CODE('voxr')
+siVoxStopInfo = FOUR_CHAR_CODE('voxs')
+siWideStereo = FOUR_CHAR_CODE('wide')
+siSupportedExtendedFlags = FOUR_CHAR_CODE('exfl')
+siRateConverterRollOffSlope = FOUR_CHAR_CODE('rcdb')
+siOutputLatency = FOUR_CHAR_CODE('olte')
+siCloseDriver = FOUR_CHAR_CODE('clos')
+siInitializeDriver = FOUR_CHAR_CODE('init')
+siPauseRecording = FOUR_CHAR_CODE('paus')
+siUserInterruptProc = FOUR_CHAR_CODE('user')
+# kInvalidSource = (long)0xFFFFFFFF
+kNoSource = FOUR_CHAR_CODE('none')
+kCDSource = FOUR_CHAR_CODE('cd  ')
+kExtMicSource = FOUR_CHAR_CODE('emic')
+kSoundInSource = FOUR_CHAR_CODE('sinj')
+kRCAInSource = FOUR_CHAR_CODE('irca')
+kTVFMTunerSource = FOUR_CHAR_CODE('tvfm')
+kDAVInSource = FOUR_CHAR_CODE('idav')
+kIntMicSource = FOUR_CHAR_CODE('imic')
+kMediaBaySource = FOUR_CHAR_CODE('mbay')
+kModemSource = FOUR_CHAR_CODE('modm')
+kPCCardSource = FOUR_CHAR_CODE('pcm ')
+kZoomVideoSource = FOUR_CHAR_CODE('zvpc')
+kDVDSource = FOUR_CHAR_CODE('dvda')
+kMicrophoneArray = FOUR_CHAR_CODE('mica')
+kNoSoundComponentType = FOUR_CHAR_CODE('****')
+kSoundComponentType = FOUR_CHAR_CODE('sift')
+kSoundComponentPPCType = FOUR_CHAR_CODE('nift')
+kRate8SubType = FOUR_CHAR_CODE('ratb')
+kRate16SubType = FOUR_CHAR_CODE('ratw')
+kConverterSubType = FOUR_CHAR_CODE('conv')
+kSndSourceSubType = FOUR_CHAR_CODE('sour')
+kMixerType = FOUR_CHAR_CODE('mixr')
+kMixer8SubType = FOUR_CHAR_CODE('mixb')
+kMixer16SubType = FOUR_CHAR_CODE('mixw')
+kSoundInputDeviceType = FOUR_CHAR_CODE('sinp')
+kWaveInSubType = FOUR_CHAR_CODE('wavi')
+kWaveInSnifferSubType = FOUR_CHAR_CODE('wisn')
+kSoundOutputDeviceType = FOUR_CHAR_CODE('sdev')
+kClassicSubType = FOUR_CHAR_CODE('clas')
+kASCSubType = FOUR_CHAR_CODE('asc ')
+kDSPSubType = FOUR_CHAR_CODE('dsp ')
+kAwacsSubType = FOUR_CHAR_CODE('awac')
+kGCAwacsSubType = FOUR_CHAR_CODE('awgc')
+kSingerSubType = FOUR_CHAR_CODE('sing')
+kSinger2SubType = FOUR_CHAR_CODE('sng2')
+kWhitSubType = FOUR_CHAR_CODE('whit')
+kSoundBlasterSubType = FOUR_CHAR_CODE('sbls')
+kWaveOutSubType = FOUR_CHAR_CODE('wavo')
+kWaveOutSnifferSubType = FOUR_CHAR_CODE('wosn')
+kDirectSoundSubType = FOUR_CHAR_CODE('dsnd')
+kDirectSoundSnifferSubType = FOUR_CHAR_CODE('dssn')
+kUNIXsdevSubType = FOUR_CHAR_CODE('un1x')
+kUSBSubType = FOUR_CHAR_CODE('usb ')
+kBlueBoxSubType = FOUR_CHAR_CODE('bsnd')
+kSoundCompressor = FOUR_CHAR_CODE('scom')
+kSoundDecompressor = FOUR_CHAR_CODE('sdec')
+kAudioComponentType = FOUR_CHAR_CODE('adio')
+kAwacsPhoneSubType = FOUR_CHAR_CODE('hphn')
+kAudioVisionSpeakerSubType = FOUR_CHAR_CODE('telc')
+kAudioVisionHeadphoneSubType = FOUR_CHAR_CODE('telh')
+kPhilipsFaderSubType = FOUR_CHAR_CODE('tvav')
+kSGSToneSubType = FOUR_CHAR_CODE('sgs0')
+kSoundEffectsType = FOUR_CHAR_CODE('snfx')
+kEqualizerSubType = FOUR_CHAR_CODE('eqal')
+kSSpLocalizationSubType = FOUR_CHAR_CODE('snd3')
+kSoundNotCompressed = FOUR_CHAR_CODE('NONE')
+k8BitOffsetBinaryFormat = FOUR_CHAR_CODE('raw ')
+k16BitBigEndianFormat = FOUR_CHAR_CODE('twos')
+k16BitLittleEndianFormat = FOUR_CHAR_CODE('sowt')
+kFloat32Format = FOUR_CHAR_CODE('fl32')
+kFloat64Format = FOUR_CHAR_CODE('fl64')
+k24BitFormat = FOUR_CHAR_CODE('in24')
+k32BitFormat = FOUR_CHAR_CODE('in32')
+k32BitLittleEndianFormat = FOUR_CHAR_CODE('23ni')
+kMACE3Compression = FOUR_CHAR_CODE('MAC3')
+kMACE6Compression = FOUR_CHAR_CODE('MAC6')
+kCDXA4Compression = FOUR_CHAR_CODE('cdx4')
+kCDXA2Compression = FOUR_CHAR_CODE('cdx2')
+kIMACompression = FOUR_CHAR_CODE('ima4')
+kULawCompression = FOUR_CHAR_CODE('ulaw')
+kALawCompression = FOUR_CHAR_CODE('alaw')
+kMicrosoftADPCMFormat = 0x6D730002
+kDVIIntelIMAFormat = 0x6D730011
+kDVAudioFormat = FOUR_CHAR_CODE('dvca')
+kQDesignCompression = FOUR_CHAR_CODE('QDMC')
+kQDesign2Compression = FOUR_CHAR_CODE('QDM2')
+kQUALCOMMCompression = FOUR_CHAR_CODE('Qclp')
+kOffsetBinary = k8BitOffsetBinaryFormat
+kTwosComplement = k16BitBigEndianFormat
+kLittleEndianFormat = k16BitLittleEndianFormat
+kMPEGLayer3Format = 0x6D730055
+kFullMPEGLay3Format = FOUR_CHAR_CODE('.mp3')
+k16BitNativeEndianFormat = k16BitLittleEndianFormat
+k16BitNonNativeEndianFormat = k16BitBigEndianFormat
+k16BitNativeEndianFormat = k16BitBigEndianFormat
+k16BitNonNativeEndianFormat = k16BitLittleEndianFormat
+k8BitRawIn = (1 << 0)
+k8BitTwosIn = (1 << 1)
+k16BitIn = (1 << 2)
+kStereoIn = (1 << 3)
+k8BitRawOut = (1 << 8)
+k8BitTwosOut = (1 << 9)
+k16BitOut = (1 << 10)
+kStereoOut = (1 << 11)
+kReverse = (1L << 16)
+kRateConvert = (1L << 17)
+kCreateSoundSource = (1L << 18)
+kVMAwareness = (1L << 21)
+kHighQuality = (1L << 22)
+kNonRealTime = (1L << 23)
+kSourcePaused = (1 << 0)
+kPassThrough = (1L << 16)
+kNoSoundComponentChain = (1L << 17)
+kNoMixing = (1 << 0)
+kNoSampleRateConversion = (1 << 1)
+kNoSampleSizeConversion = (1 << 2)
+kNoSampleFormatConversion = (1 << 3)
+kNoChannelConversion = (1 << 4)
+kNoDecompression = (1 << 5)
+kNoVolumeConversion = (1 << 6)
+kNoRealtimeProcessing = (1 << 7)
+kScheduledSource = (1 << 8)
+kNonInterleavedBuffer = (1 << 9)
+kNonPagingMixer = (1 << 10)
+kSoundConverterMixer = (1 << 11)
+kPagingMixer = (1 << 12)
+kVMAwareMixer = (1 << 13)
+kExtendedSoundData = (1 << 14)
+kBestQuality = (1 << 0)
+kInputMask = 0x000000FF
+kOutputMask = 0x0000FF00
+kOutputShift = 8
+kActionMask = 0x00FF0000
+kSoundComponentBits = 0x00FFFFFF
+kAudioFormatAtomType = FOUR_CHAR_CODE('frma')
+kAudioEndianAtomType = FOUR_CHAR_CODE('enda')
+kAudioVBRAtomType = FOUR_CHAR_CODE('vbra')
+kAudioTerminatorAtomType = 0
+kAVDisplayHeadphoneRemove = 0
+kAVDisplayHeadphoneInsert = 1
+kAVDisplayPlainTalkRemove = 2
+kAVDisplayPlainTalkInsert = 3
+audioAllChannels = 0
+audioLeftChannel = 1
+audioRightChannel = 2
+audioUnmuted = 0
+audioMuted = 1
+audioDoesMono = (1L << 0)
+audioDoesStereo = (1L << 1)
+audioDoesIndependentChannels = (1L << 2)
+siCDQuality = FOUR_CHAR_CODE('cd  ')
+siBestQuality = FOUR_CHAR_CODE('best')
+siBetterQuality = FOUR_CHAR_CODE('betr')
+siGoodQuality = FOUR_CHAR_CODE('good')
+siNoneQuality = FOUR_CHAR_CODE('none')
+siDeviceIsConnected = 1
+siDeviceNotConnected = 0
+siDontKnowIfConnected = -1
+siReadPermission = 0
+siWritePermission = 1
+kSoundConverterDidntFillBuffer = (1 << 0)
+kSoundConverterHasLeftOverData = (1 << 1)
+kExtendedSoundSampleCountNotValid = 1L << 0
+kExtendedSoundBufferSizeValid = 1L << 1
+kScheduledSoundDoScheduled = 1 << 0
+kScheduledSoundDoCallBack = 1 << 1
+kScheduledSoundExtendedHdr = 1 << 2
+kSoundComponentInitOutputDeviceSelect = 0x0001
+kSoundComponentSetSourceSelect = 0x0002
+kSoundComponentGetSourceSelect = 0x0003
+kSoundComponentGetSourceDataSelect = 0x0004
+kSoundComponentSetOutputSelect = 0x0005
+kSoundComponentAddSourceSelect = 0x0101
+kSoundComponentRemoveSourceSelect = 0x0102
+kSoundComponentGetInfoSelect = 0x0103
+kSoundComponentSetInfoSelect = 0x0104
+kSoundComponentStartSourceSelect = 0x0105
+kSoundComponentStopSourceSelect = 0x0106
+kSoundComponentPauseSourceSelect = 0x0107
+kSoundComponentPlaySourceBufferSelect = 0x0108
+kAudioGetVolumeSelect = 0x0000
+kAudioSetVolumeSelect = 0x0001
+kAudioGetMuteSelect = 0x0002
+kAudioSetMuteSelect = 0x0003
+kAudioSetToDefaultsSelect = 0x0004
+kAudioGetInfoSelect = 0x0005
+kAudioGetBassSelect = 0x0006
+kAudioSetBassSelect = 0x0007
+kAudioGetTrebleSelect = 0x0008
+kAudioSetTrebleSelect = 0x0009
+kAudioGetOutputDeviceSelect = 0x000A
+kAudioMuteOnEventSelect = 0x0081
+kDelegatedSoundComponentSelectors = 0x0100
+kSndInputReadAsyncSelect = 0x0001
+kSndInputReadSyncSelect = 0x0002
+kSndInputPauseRecordingSelect = 0x0003
+kSndInputResumeRecordingSelect = 0x0004
+kSndInputStopRecordingSelect = 0x0005
+kSndInputGetStatusSelect = 0x0006
+kSndInputGetDeviceInfoSelect = 0x0007
+kSndInputSetDeviceInfoSelect = 0x0008
+kSndInputInitHardwareSelect = 0x0009

Added: vendor/Python/current/Lib/plat-mac/Carbon/TE.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/TE.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/TE.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1 @@
+from _TE import *

Added: vendor/Python/current/Lib/plat-mac/Carbon/TextEdit.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/TextEdit.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/TextEdit.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,57 @@
+# Generated from 'TextEdit.h'
+
+teJustLeft = 0
+teJustCenter = 1
+teJustRight = -1
+teForceLeft = -2
+teFlushDefault = 0
+teCenter = 1
+teFlushRight = -1
+teFlushLeft = -2
+fontBit = 0
+faceBit = 1
+sizeBit = 2
+clrBit = 3
+addSizeBit = 4
+toggleBit = 5
+doFont = 1
+doFace = 2
+doSize = 4
+doColor = 8
+doAll = 15
+addSize = 16
+doToggle = 32
+EOLHook = 0
+DRAWHook = 4
+WIDTHHook = 8
+HITTESTHook = 12
+nWIDTHHook = 24
+TextWidthHook = 28
+intEOLHook = 0
+intDrawHook = 1
+intWidthHook = 2
+intHitTestHook = 3
+intNWidthHook = 6
+intTextWidthHook = 7
+intInlineInputTSMTEPreUpdateHook = 8
+intInlineInputTSMTEPostUpdateHook = 9
+teFAutoScroll = 0
+teFTextBuffering = 1
+teFOutlineHilite = 2
+teFInlineInput = 3
+teFUseWhiteBackground = 4
+teFUseInlineInput = 5
+teFInlineInputAutoScroll = 6
+teFIdleWithEventLoopTimer = 7
+teBitClear = 0
+teBitSet = 1
+teBitTest = -1
+teWordSelect = 4
+teWordDrag = 8
+teFromFind = 12
+teFromRecal = 16
+teFind = 0
+teHighlight = 1
+teDraw = -1
+teCaret = -2
+teFUseTextServices = 4

Added: vendor/Python/current/Lib/plat-mac/Carbon/Win.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/Win.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/Win.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1 @@
+from _Win import *

Added: vendor/Python/current/Lib/plat-mac/Carbon/Windows.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/Windows.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/Windows.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,279 @@
+# Generated from 'MacWindows.h'
+
+def FOUR_CHAR_CODE(x): return x
+false = 0
+true = 1
+kWindowNoConstrainAttribute = 0x80000000
+kAlertWindowClass = 1
+kMovableAlertWindowClass = 2
+kModalWindowClass = 3
+kMovableModalWindowClass = 4
+kFloatingWindowClass = 5
+kDocumentWindowClass = 6
+kUtilityWindowClass = 8
+kHelpWindowClass = 10
+kSheetWindowClass = 11
+kToolbarWindowClass = 12
+kPlainWindowClass = 13
+kOverlayWindowClass = 14
+kSheetAlertWindowClass = 15
+kAltPlainWindowClass = 16
+kDrawerWindowClass = 20
+# kAllWindowClasses = (unsigned long)0xFFFFFFFF
+kWindowNoAttributes = 0L
+kWindowCloseBoxAttribute = (1L << 0)
+kWindowHorizontalZoomAttribute = (1L << 1)
+kWindowVerticalZoomAttribute = (1L << 2)
+kWindowFullZoomAttribute = (kWindowVerticalZoomAttribute | kWindowHorizontalZoomAttribute)
+kWindowCollapseBoxAttribute = (1L << 3)
+kWindowResizableAttribute = (1L << 4)
+kWindowSideTitlebarAttribute = (1L << 5)
+kWindowToolbarButtonAttribute = (1L << 6)
+kWindowNoUpdatesAttribute = (1L << 16)
+kWindowNoActivatesAttribute = (1L << 17)
+kWindowOpaqueForEventsAttribute = (1L << 18)
+kWindowNoShadowAttribute = (1L << 21)
+kWindowHideOnSuspendAttribute = (1L << 24)
+kWindowStandardHandlerAttribute = (1L << 25)
+kWindowHideOnFullScreenAttribute = (1L << 26)
+kWindowInWindowMenuAttribute = (1L << 27)
+kWindowLiveResizeAttribute = (1L << 28)
+# kWindowNoConstrainAttribute = (unsigned long)((1L << 31))
+kWindowStandardDocumentAttributes = (kWindowCloseBoxAttribute | kWindowFullZoomAttribute | kWindowCollapseBoxAttribute | kWindowResizableAttribute)
+kWindowStandardFloatingAttributes = (kWindowCloseBoxAttribute | kWindowCollapseBoxAttribute)
+kWindowDefProcType = FOUR_CHAR_CODE('WDEF')
+kStandardWindowDefinition = 0
+kRoundWindowDefinition = 1
+kFloatingWindowDefinition = 124
+kDocumentWindowVariantCode = 0
+kModalDialogVariantCode = 1
+kPlainDialogVariantCode = 2
+kShadowDialogVariantCode = 3
+kMovableModalDialogVariantCode = 5
+kAlertVariantCode = 7
+kMovableAlertVariantCode = 9
+kSideFloaterVariantCode = 8
+documentProc = 0
+dBoxProc = 1
+plainDBox = 2
+altDBoxProc = 3
+noGrowDocProc = 4
+movableDBoxProc = 5
+zoomDocProc = 8
+zoomNoGrow = 12
+floatProc = 1985
+floatGrowProc = 1987
+floatZoomProc = 1989
+floatZoomGrowProc = 1991
+floatSideProc = 1993
+floatSideGrowProc = 1995
+floatSideZoomProc = 1997
+floatSideZoomGrowProc = 1999
+rDocProc = 16
+kWindowDocumentDefProcResID = 64
+kWindowDialogDefProcResID = 65
+kWindowUtilityDefProcResID = 66
+kWindowUtilitySideTitleDefProcResID = 67
+kWindowSheetDefProcResID = 68
+kWindowSimpleDefProcResID = 69
+kWindowSheetAlertDefProcResID = 70
+kWindowDocumentProc = 1024
+kWindowGrowDocumentProc = 1025
+kWindowVertZoomDocumentProc = 1026
+kWindowVertZoomGrowDocumentProc = 1027
+kWindowHorizZoomDocumentProc = 1028
+kWindowHorizZoomGrowDocumentProc = 1029
+kWindowFullZoomDocumentProc = 1030
+kWindowFullZoomGrowDocumentProc = 1031
+kWindowPlainDialogProc = 1040
+kWindowShadowDialogProc = 1041
+kWindowModalDialogProc = 1042
+kWindowMovableModalDialogProc = 1043
+kWindowAlertProc = 1044
+kWindowMovableAlertProc = 1045
+kWindowMovableModalGrowProc = 1046
+kWindowFloatProc = 1057
+kWindowFloatGrowProc = 1059
+kWindowFloatVertZoomProc = 1061
+kWindowFloatVertZoomGrowProc = 1063
+kWindowFloatHorizZoomProc = 1065
+kWindowFloatHorizZoomGrowProc = 1067
+kWindowFloatFullZoomProc = 1069
+kWindowFloatFullZoomGrowProc = 1071
+kWindowFloatSideProc = 1073
+kWindowFloatSideGrowProc = 1075
+kWindowFloatSideVertZoomProc = 1077
+kWindowFloatSideVertZoomGrowProc = 1079
+kWindowFloatSideHorizZoomProc = 1081
+kWindowFloatSideHorizZoomGrowProc = 1083
+kWindowFloatSideFullZoomProc = 1085
+kWindowFloatSideFullZoomGrowProc = 1087
+kWindowSheetProc = 1088
+kWindowSheetAlertProc = 1120
+kWindowSimpleProc = 1104
+kWindowSimpleFrameProc = 1105
+kWindowNoPosition = 0x0000
+kWindowDefaultPosition = 0x0000
+kWindowCenterMainScreen = 0x280A
+kWindowAlertPositionMainScreen = 0x300A
+kWindowStaggerMainScreen = 0x380A
+kWindowCenterParentWindow = 0xA80A
+kWindowAlertPositionParentWindow = 0xB00A
+kWindowStaggerParentWindow = 0xB80A
+kWindowCenterParentWindowScreen = 0x680A
+kWindowAlertPositionParentWindowScreen = 0x700A
+kWindowStaggerParentWindowScreen = 0x780A
+kWindowCenterOnMainScreen = 1
+kWindowCenterOnParentWindow = 2
+kWindowCenterOnParentWindowScreen = 3
+kWindowCascadeOnMainScreen = 4
+kWindowCascadeOnParentWindow = 5
+kWindowCascadeOnParentWindowScreen = 6
+kWindowCascadeStartAtParentWindowScreen = 10
+kWindowAlertPositionOnMainScreen = 7
+kWindowAlertPositionOnParentWindow = 8
+kWindowAlertPositionOnParentWindowScreen = 9
+kWindowTitleBarRgn = 0
+kWindowTitleTextRgn = 1
+kWindowCloseBoxRgn = 2
+kWindowZoomBoxRgn = 3
+kWindowDragRgn = 5
+kWindowGrowRgn = 6
+kWindowCollapseBoxRgn = 7
+kWindowTitleProxyIconRgn = 8
+kWindowStructureRgn = 32
+kWindowContentRgn = 33
+kWindowUpdateRgn = 34
+kWindowOpaqueRgn = 35
+kWindowGlobalPortRgn = 40
+dialogKind = 2
+userKind = 8
+kDialogWindowKind = 2
+kApplicationWindowKind = 8
+inDesk = 0
+inNoWindow = 0
+inMenuBar = 1
+inSysWindow = 2
+inContent = 3
+inDrag = 4
+inGrow = 5
+inGoAway = 6
+inZoomIn = 7
+inZoomOut = 8
+inCollapseBox = 11
+inProxyIcon = 12
+inToolbarButton = 13
+inStructure = 15
+wNoHit = 0
+wInContent = 1
+wInDrag = 2
+wInGrow = 3
+wInGoAway = 4
+wInZoomIn = 5
+wInZoomOut = 6
+wInCollapseBox = 9
+wInProxyIcon = 10
+wInToolbarButton = 11
+wInStructure = 13
+kWindowMsgDraw = 0
+kWindowMsgHitTest = 1
+kWindowMsgCalculateShape = 2
+kWindowMsgInitialize = 3
+kWindowMsgCleanUp = 4
+kWindowMsgDrawGrowOutline = 5
+kWindowMsgDrawGrowBox = 6
+kWindowMsgGetFeatures = 7
+kWindowMsgGetRegion = 8
+kWindowMsgDragHilite = 9
+kWindowMsgModified = 10
+kWindowMsgDrawInCurrentPort = 11
+kWindowMsgSetupProxyDragImage = 12
+kWindowMsgStateChanged = 13
+kWindowMsgMeasureTitle = 14
+kWindowMsgGetGrowImageRegion = 19
+wDraw = 0
+wHit = 1
+wCalcRgns = 2
+wNew = 3
+wDispose = 4
+wGrow = 5
+wDrawGIcon = 6
+kWindowStateTitleChanged = (1 << 0)
+kWindowCanGrow = (1 << 0)
+kWindowCanZoom = (1 << 1)
+kWindowCanCollapse = (1 << 2)
+kWindowIsModal = (1 << 3)
+kWindowCanGetWindowRegion = (1 << 4)
+kWindowIsAlert = (1 << 5)
+kWindowHasTitleBar = (1 << 6)
+kWindowSupportsDragHilite = (1 << 7)
+kWindowSupportsModifiedBit = (1 << 8)
+kWindowCanDrawInCurrentPort = (1 << 9)
+kWindowCanSetupProxyDragImage = (1 << 10)
+kWindowCanMeasureTitle = (1 << 11)
+kWindowWantsDisposeAtProcessDeath = (1 << 12)
+kWindowSupportsGetGrowImageRegion = (1 << 13)
+kWindowDefSupportsColorGrafPort = 0x40000002
+kWindowIsOpaque = (1 << 14)
+kWindowSupportsSetGrowImageRegion = (1 << 13)
+deskPatID = 16
+wContentColor = 0
+wFrameColor = 1
+wTextColor = 2
+wHiliteColor = 3
+wTitleBarColor = 4
+# kMouseUpOutOfSlop = (long)0x80008000
+kWindowDefinitionVersionOne = 1
+kWindowDefinitionVersionTwo = 2
+kWindowIsCollapsedState = (1 << 0L)
+kStoredWindowSystemTag = FOUR_CHAR_CODE('appl')
+kStoredBasicWindowDescriptionID = FOUR_CHAR_CODE('sbas')
+kStoredWindowPascalTitleID = FOUR_CHAR_CODE('s255')
+kWindowDefProcPtr = 0
+kWindowDefObjectClass = 1
+kWindowDefProcID = 2
+kWindowModalityNone = 0
+kWindowModalitySystemModal = 1
+kWindowModalityAppModal = 2
+kWindowModalityWindowModal = 3
+kWindowGroupAttrSelectAsLayer = 1 << 0
+kWindowGroupAttrMoveTogether = 1 << 1
+kWindowGroupAttrLayerTogether = 1 << 2
+kWindowGroupAttrSharedActivation = 1 << 3
+kWindowGroupAttrHideOnCollapse = 1 << 4
+kWindowActivationScopeNone = 0
+kWindowActivationScopeIndependent = 1
+kWindowActivationScopeAll = 2
+kNextWindowGroup = true
+kPreviousWindowGroup = false
+kWindowGroupContentsReturnWindows = 1 << 0
+kWindowGroupContentsRecurse = 1 << 1
+kWindowGroupContentsVisible = 1 << 2
+kWindowPaintProcOptionsNone = 0
+kScrollWindowNoOptions = 0
+kScrollWindowInvalidate = (1L << 0)
+kScrollWindowEraseToPortBackground = (1L << 1)
+kWindowMenuIncludeRotate = 1 << 0
+kWindowZoomTransitionEffect = 1
+kWindowSheetTransitionEffect = 2
+kWindowSlideTransitionEffect = 3
+kWindowShowTransitionAction = 1
+kWindowHideTransitionAction = 2
+kWindowMoveTransitionAction = 3
+kWindowResizeTransitionAction = 4
+kWindowConstrainMayResize = (1L << 0)
+kWindowConstrainMoveRegardlessOfFit = (1L << 1)
+kWindowConstrainAllowPartial = (1L << 2)
+kWindowConstrainCalcOnly = (1L << 3)
+kWindowConstrainUseTransitionWindow = (1L << 4)
+kWindowConstrainStandardOptions = kWindowConstrainMoveRegardlessOfFit
+kWindowLatentVisibleFloater = 1 << 0
+kWindowLatentVisibleSuspend = 1 << 1
+kWindowLatentVisibleFullScreen = 1 << 2
+kWindowLatentVisibleAppHidden = 1 << 3
+kWindowLatentVisibleCollapsedOwner = 1 << 4
+kWindowLatentVisibleCollapsedGroup = 1 << 5
+kWindowPropertyPersistent = 0x00000001
+kWindowGroupAttrSelectable = kWindowGroupAttrSelectAsLayer
+kWindowGroupAttrPositionFixed = kWindowGroupAttrMoveTogether
+kWindowGroupAttrZOrderFixed = kWindowGroupAttrLayerTogether

Added: vendor/Python/current/Lib/plat-mac/Carbon/__init__.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/Carbon/__init__.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/Carbon/__init__.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,4 @@
+# Filter out warnings about signed/unsigned constants
+import warnings
+warnings.filterwarnings("ignore", "", FutureWarning, ".*Controls")
+warnings.filterwarnings("ignore", "", FutureWarning, ".*MacTextEditor")

Added: vendor/Python/current/Lib/plat-mac/EasyDialogs.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/EasyDialogs.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/EasyDialogs.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,838 @@
+"""Easy to use dialogs.
+
+Message(msg) -- display a message and an OK button.
+AskString(prompt, default) -- ask for a string, display OK and Cancel buttons.
+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
+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.
+
+More documentation in each function.
+This module uses DLOG resources 260 and on.
+Based upon STDWIN dialogs with the same names and functions.
+"""
+
+from Carbon.Dlg import GetNewDialog, SetDialogItemText, GetDialogItemText, ModalDialog
+from Carbon import Qd
+from Carbon import QuickDraw
+from Carbon import Dialogs
+from Carbon import Windows
+from Carbon import Dlg,Win,Evt,Events # sdm7g
+from Carbon import Ctl
+from Carbon import Controls
+from Carbon import Menu
+from Carbon import AE
+import Nav
+import MacOS
+import string
+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',
+    'ProgressBar']
+
+_initialized = 0
+
+def _initialize():
+    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)
+
+def cr2lf(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
+
+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
+
+
+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
+
+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
+
+
+
+
+screenbounds = Qd.GetQDGlobalsScreenBits().bounds
+screenbounds = screenbounds[0]+4, screenbounds[1]+4, \
+    screenbounds[2]-4, screenbounds[3]-4
+
+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 __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 _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
+ARGV_ITEM_CANCEL=2
+ARGV_OPTION_GROUP=3
+ARGV_OPTION_EXPLAIN=4
+ARGV_OPTION_VALUE=5
+ARGV_OPTION_ADD=6
+ARGV_COMMAND_GROUP=7
+ARGV_COMMAND_EXPLAIN=8
+ARGV_COMMAND_ADD=9
+ARGV_ADD_OLDFILE=10
+ARGV_ADD_NEWFILE=11
+ARGV_ADD_FOLDER=12
+ARGV_CMDLINE_GROUP=13
+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)
+##
+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)
+
+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)
+
+
+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 = repr(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
+
+def _dummy_Nav_eventproc(msg, data):
+    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
+
+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)
+
+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"""
+
+
+    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)
+
+
+def test():
+    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] = %r' % (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.")

Added: vendor/Python/current/Lib/plat-mac/FrameWork.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/FrameWork.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/FrameWork.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1123 @@
+"A sort of application framework for the Mac"
+
+DEBUG=0
+
+import MacOS
+import traceback
+
+from Carbon.AE import *
+from Carbon.AppleEvents import *
+from Carbon.Ctl import *
+from Carbon.Controls import *
+from Carbon.Dlg import *
+from Carbon.Dialogs import *
+from Carbon.Evt import *
+from Carbon.Events import *
+from Carbon.Help import *
+from Carbon.Menu import *
+from Carbon.Menus import *
+from Carbon.Qd import *
+from Carbon.QuickDraw import *
+#from Carbon.Res import *
+#from Carbon.Resources import *
+#from Carbon.Snd import *
+#from Carbon.Sound import *
+from Carbon.Win import *
+from Carbon.Windows import *
+import types
+
+import EasyDialogs
+
+try:
+    MyFrontWindow = FrontNonFloatingWindow
+except NameError:
+    MyFrontWindow = FrontWindow
+
+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
+
+
+# Map event 'what' field to strings
+eventname = {}
+eventname[1] = 'mouseDown'
+eventname[2] = 'mouseUp'
+eventname[3] = 'keyDown'
+eventname[4] = 'keyUp'
+eventname[5] = 'autoKey'
+eventname[6] = 'updateEvt'
+eventname[7] = 'diskEvt'
+eventname[8] = 'activateEvt'
+eventname[15] = 'osEvt'
+eventname[23] = 'kHighLevelEvent'
+
+# Map part codes returned by WhichWindow() to strings
+partname = {}
+partname[0] = 'inDesk'
+partname[1] = 'inMenuBar'
+partname[2] = 'inSysWindow'
+partname[3] = 'inContent'
+partname[4] = 'inDrag'
+partname[5] = 'inGrow'
+partname[6] = 'inGoAway'
+partname[7] = 'inZoomIn'
+partname[8] = 'inZoomOut'
+
+#
+# The useable portion of the screen
+#       ## 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
+
+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
+
+_watch = None
+def setwatchcursor():
+    global _watch
+
+    if _watch == None:
+        _watch = GetCursor(4).data
+    SetCursor(_watch)
+
+def setarrowcursor():
+    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 = 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", repr(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 = repr(what)
+        if eventname.has_key(what):
+            nicewhat = eventname[what]
+        print nicewhat,
+        if what == kHighLevelEvent:
+            h, v = where
+            print repr(ostypecode(message)), hex(when), repr(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)
+
+# 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)
+
+    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)
+
+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 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')
+
+class CheckItem(MenuItem):
+    def __init__(self, menu, title, shortcut=None, callback=None):
+        MenuItem.__init__(self, menu, title, shortcut, callback, 'check')
+
+def Separator(menu):
+    menu.addseparator()
+
+def SubMenu(menu, 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)
+
+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
+
+
+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)
+
+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_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 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 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
+
+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
+
+
+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()
+
+
+def test():
+    "Test program"
+    app = TestApp()
+    app.mainloop()
+
+
+if __name__ == '__main__':
+    test()

Added: vendor/Python/current/Lib/plat-mac/MiniAEFrame.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/MiniAEFrame.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/MiniAEFrame.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,198 @@
+"""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.
+"""
+
+import sys
+import traceback
+import MacOS
+from Carbon import AE
+from Carbon.AppleEvents import *
+from Carbon import Evt
+from Carbon.Events import *
+from Carbon import Menu
+from Carbon import Win
+from Carbon.Windows import *
+from Carbon import Qd
+
+import aetools
+import EasyDialogs
+
+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: %r %r" % (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 = _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
+
+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()
+
+    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()

Added: vendor/Python/current/Lib/plat-mac/PixMapWrapper.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/PixMapWrapper.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/PixMapWrapper.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,214 @@
+"""PixMapWrapper - defines the PixMapWrapper class, which wraps an opaque
+QuickDraw PixMap data structure in a handy Python class.  Also provides
+methods to convert to/from pixel data (from, e.g., the img module) or a
+Python Imaging Library Image object.
+
+J. Strout <joe at strout.net>  February 1999"""
+
+from Carbon import Qd
+from Carbon import QuickDraw
+import struct
+import MacOS
+import img
+import imgformat
+
+# PixMap data structure element format (as used with struct)
+_pmElemFormat = {
+    'baseAddr':'l',     # address of pixel data
+    'rowBytes':'H',     # bytes per row, plus 0x8000
+    'bounds':'hhhh',    # coordinates imposed over pixel data
+        'top':'h',
+        'left':'h',
+        'bottom':'h',
+        'right':'h',
+    'pmVersion':'h',    # flags for Color QuickDraw
+    'packType':'h',     # format of compression algorithm
+    'packSize':'l',     # size after compression
+    'hRes':'l',         # horizontal pixels per inch
+    'vRes':'l',         # vertical pixels per inch
+    'pixelType':'h',    # pixel format
+    'pixelSize':'h',    # bits per pixel
+    'cmpCount':'h',     # color components per pixel
+    'cmpSize':'h',      # bits per component
+    'planeBytes':'l',   # offset in bytes to next plane
+    'pmTable':'l',      # handle to color table
+    'pmReserved':'l'    # reserved for future use
+}
+
+# PixMap data structure element offset
+_pmElemOffset = {
+    'baseAddr':0,
+    'rowBytes':4,
+    'bounds':6,
+        'top':6,
+        'left':8,
+        'bottom':10,
+        'right':12,
+    'pmVersion':14,
+    'packType':16,
+    'packSize':18,
+    'hRes':22,
+    'vRes':26,
+    'pixelType':30,
+    'pixelSize':32,
+    'cmpCount':34,
+    'cmpSize':36,
+    'planeBytes':38,
+    'pmTable':42,
+    'pmReserved':46
+}
+
+class PixMapWrapper:
+    """PixMapWrapper -- wraps the QD PixMap object in a Python class,
+    with methods to easily get/set various pixmap fields.  Note: Use the
+    PixMap() method when passing to QD calls."""
+
+    def __init__(self):
+        self.__dict__['data'] = ''
+        self._header = struct.pack("lhhhhhhhlllhhhhlll",
+            id(self.data)+MacOS.string_id_to_buffer,
+            0,                      # rowBytes
+            0, 0, 0, 0,             # bounds
+            0,                      # pmVersion
+            0, 0,                   # packType, packSize
+            72<<16, 72<<16,         # hRes, vRes
+            QuickDraw.RGBDirect,    # pixelType
+            16,                     # pixelSize
+            2, 5,                   # cmpCount, cmpSize,
+            0, 0, 0)                # planeBytes, pmTable, pmReserved
+        self.__dict__['_pm'] = Qd.RawBitMap(self._header)
+
+    def _stuff(self, element, bytes):
+        offset = _pmElemOffset[element]
+        fmt = _pmElemFormat[element]
+        self._header = self._header[:offset] \
+            + struct.pack(fmt, bytes) \
+            + self._header[offset + struct.calcsize(fmt):]
+        self.__dict__['_pm'] = None
+
+    def _unstuff(self, element):
+        offset = _pmElemOffset[element]
+        fmt = _pmElemFormat[element]
+        return struct.unpack(fmt, self._header[offset:offset+struct.calcsize(fmt)])[0]
+
+    def __setattr__(self, attr, val):
+        if attr == 'baseAddr':
+            raise 'UseErr', "don't assign to .baseAddr -- assign to .data instead"
+        elif attr == 'data':
+            self.__dict__['data'] = val
+            self._stuff('baseAddr', id(self.data) + MacOS.string_id_to_buffer)
+        elif attr == 'rowBytes':
+            # high bit is always set for some odd reason
+            self._stuff('rowBytes', val | 0x8000)
+        elif attr == 'bounds':
+            # assume val is in official Left, Top, Right, Bottom order!
+            self._stuff('left',val[0])
+            self._stuff('top',val[1])
+            self._stuff('right',val[2])
+            self._stuff('bottom',val[3])
+        elif attr == 'hRes' or attr == 'vRes':
+            # 16.16 fixed format, so just shift 16 bits
+            self._stuff(attr, int(val) << 16)
+        elif attr in _pmElemFormat.keys():
+            # any other pm attribute -- just stuff
+            self._stuff(attr, val)
+        else:
+            self.__dict__[attr] = val
+
+    def __getattr__(self, attr):
+        if attr == 'rowBytes':
+            # high bit is always set for some odd reason
+            return self._unstuff('rowBytes') & 0x7FFF
+        elif attr == 'bounds':
+            # return bounds in official Left, Top, Right, Bottom order!
+            return ( \
+                self._unstuff('left'),
+                self._unstuff('top'),
+                self._unstuff('right'),
+                self._unstuff('bottom') )
+        elif attr == 'hRes' or attr == 'vRes':
+            # 16.16 fixed format, so just shift 16 bits
+            return self._unstuff(attr) >> 16
+        elif attr in _pmElemFormat.keys():
+            # any other pm attribute -- just unstuff
+            return self._unstuff(attr)
+        else:
+            return self.__dict__[attr]
+
+
+    def PixMap(self):
+        "Return a QuickDraw PixMap corresponding to this data."
+        if not self.__dict__['_pm']:
+            self.__dict__['_pm'] = Qd.RawBitMap(self._header)
+        return self.__dict__['_pm']
+
+    def blit(self, x1=0,y1=0,x2=None,y2=None, port=None):
+        """Draw this pixmap into the given (default current) grafport."""
+        src = self.bounds
+        dest = [x1,y1,x2,y2]
+        if x2 == None:
+            dest[2] = x1 + src[2]-src[0]
+        if y2 == None:
+            dest[3] = y1 + src[3]-src[1]
+        if not port: port = Qd.GetPort()
+        Qd.CopyBits(self.PixMap(), port.GetPortBitMapForCopyBits(), src, tuple(dest),
+                QuickDraw.srcCopy, None)
+
+    def fromstring(self,s,width,height,format=imgformat.macrgb):
+        """Stuff this pixmap with raw pixel data from a string.
+        Supply width, height, and one of the imgformat specifiers."""
+        # we only support 16- and 32-bit mac rgb...
+        # so convert if necessary
+        if format != imgformat.macrgb and format != imgformat.macrgb16:
+            # (LATER!)
+            raise "NotImplementedError", "conversion to macrgb or macrgb16"
+        self.data = s
+        self.bounds = (0,0,width,height)
+        self.cmpCount = 3
+        self.pixelType = QuickDraw.RGBDirect
+        if format == imgformat.macrgb:
+            self.pixelSize = 32
+            self.cmpSize = 8
+        else:
+            self.pixelSize = 16
+            self.cmpSize = 5
+        self.rowBytes = width*self.pixelSize/8
+
+    def tostring(self, format=imgformat.macrgb):
+        """Return raw data as a string in the specified format."""
+        # is the native format requested?  if so, just return data
+        if (format == imgformat.macrgb and self.pixelSize == 32) or \
+           (format == imgformat.macrgb16 and self.pixelsize == 16):
+            return self.data
+        # otherwise, convert to the requested format
+        # (LATER!)
+            raise "NotImplementedError", "data format conversion"
+
+    def fromImage(self,im):
+        """Initialize this PixMap from a PIL Image object."""
+        # We need data in ARGB format; PIL can't currently do that,
+        # but it can do RGBA, which we can use by inserting one null
+        # up frontpm =
+        if im.mode != 'RGBA': im = im.convert('RGBA')
+        data = chr(0) + im.tostring()
+        self.fromstring(data, im.size[0], im.size[1])
+
+    def toImage(self):
+        """Return the contents of this PixMap as a PIL Image object."""
+        import Image
+        # our tostring() method returns data in ARGB format,
+        # whereas Image uses RGBA; a bit of slicing fixes this...
+        data = self.tostring()[1:] + chr(0)
+        bounds = self.bounds
+        return Image.fromstring('RGBA',(bounds[2]-bounds[0],bounds[3]-bounds[1]),data)
+
+def test():
+    import MacOS
+    import EasyDialogs
+    import Image
+    path = EasyDialogs.AskFileForOpen("Image File:")
+    if not path: return
+    pm = PixMapWrapper()
+    pm.fromImage( Image.open(path) )
+    pm.blit(20,20)
+    return pm

Added: vendor/Python/current/Lib/plat-mac/aepack.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/aepack.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/aepack.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,366 @@
+"""Tools for use in AppleEvent clients and servers:
+conversion between AE types and python types
+
+pack(x) converts a Python object to an AEDesc object
+unpack(desc) does the reverse
+coerce(x, wanted_sample) coerces a python object to another python object
+"""
+
+#
+# This code was originally written by Guido, and modified/extended by Jack
+# to include the various types that were missing. The reference used is
+# Apple Event Registry, chapter 9.
+#
+
+import struct
+import string
+import types
+from string import strip
+from types import *
+from Carbon import AE
+from Carbon.AppleEvents import *
+import MacOS
+import Carbon.File
+import StringIO
+import aetypes
+from aetypes import mkenum, ObjectSpecifier
+import os
+
+# These ones seem to be missing from AppleEvents
+# (they're in AERegistry.h)
+
+#typeColorTable = 'clrt'
+#typeDrawingArea = 'cdrw'
+#typePixelMap = 'cpix'
+#typePixelMapMinus = 'tpmm'
+#typeRotation = 'trot'
+#typeTextStyles = 'tsty'
+#typeStyledText = 'STXT'
+#typeAEText = 'tTXT'
+#typeEnumeration = 'enum'
+
+#
+# Some AE types are immedeately coerced into something
+# we like better (and which is equivalent)
+#
+unpacker_coercions = {
+    typeComp : typeFloat,
+    typeColorTable : typeAEList,
+    typeDrawingArea : typeAERecord,
+    typeFixed : typeFloat,
+    typeExtended : typeFloat,
+    typePixelMap : typeAERecord,
+    typeRotation : typeAERecord,
+    typeStyledText : typeAERecord,
+    typeTextStyles : typeAERecord,
+};
+
+#
+# Some python types we need in the packer:
+#
+AEDescType = AE.AEDescType
+FSSType = Carbon.File.FSSpecType
+FSRefType = Carbon.File.FSRefType
+AliasType = Carbon.File.AliasType
+
+def packkey(ae, key, value):
+    if hasattr(key, 'which'):
+        keystr = key.which
+    elif hasattr(key, 'want'):
+        keystr = key.want
+    else:
+        keystr = key
+    ae.AEPutParamDesc(keystr, pack(value))
+
+def pack(x, forcetype = None):
+    """Pack a python object into an AE descriptor"""
+
+    if forcetype:
+        if type(x) is StringType:
+            return AE.AECreateDesc(forcetype, x)
+        else:
+            return pack(x).AECoerceDesc(forcetype)
+
+    if x == None:
+        return AE.AECreateDesc('null', '')
+
+    if isinstance(x, AEDescType):
+        return x
+    if isinstance(x, FSSType):
+        return AE.AECreateDesc('fss ', x.data)
+    if isinstance(x, FSRefType):
+        return AE.AECreateDesc('fsrf', x.data)
+    if isinstance(x, AliasType):
+        return AE.AECreateDesc('alis', x.data)
+    if isinstance(x, IntType):
+        return AE.AECreateDesc('long', struct.pack('l', x))
+    if isinstance(x, FloatType):
+        return AE.AECreateDesc('doub', struct.pack('d', x))
+    if isinstance(x, StringType):
+        return AE.AECreateDesc('TEXT', x)
+    if isinstance(x, UnicodeType):
+        data = x.encode('utf16')
+        if data[:2] == '\xfe\xff':
+            data = data[2:]
+        return AE.AECreateDesc('utxt', data)
+    if isinstance(x, ListType):
+        list = AE.AECreateList('', 0)
+        for item in x:
+            list.AEPutDesc(0, pack(item))
+        return list
+    if isinstance(x, DictionaryType):
+        record = AE.AECreateList('', 1)
+        for key, value in x.items():
+            packkey(record, key, value)
+            #record.AEPutParamDesc(key, pack(value))
+        return record
+    if type(x) == types.ClassType and issubclass(x, ObjectSpecifier):
+        # Note: we are getting a class object here, not an instance
+        return AE.AECreateDesc('type', x.want)
+    if hasattr(x, '__aepack__'):
+        return x.__aepack__()
+    if hasattr(x, 'which'):
+        return AE.AECreateDesc('TEXT', x.which)
+    if hasattr(x, 'want'):
+        return AE.AECreateDesc('TEXT', x.want)
+    return AE.AECreateDesc('TEXT', repr(x)) # Copout
+
+def unpack(desc, formodulename=""):
+    """Unpack an AE descriptor to a python object"""
+    t = desc.type
+
+    if unpacker_coercions.has_key(t):
+        desc = desc.AECoerceDesc(unpacker_coercions[t])
+        t = desc.type # This is a guess by Jack....
+
+    if t == typeAEList:
+        l = []
+        for i in range(desc.AECountItems()):
+            keyword, item = desc.AEGetNthDesc(i+1, '****')
+            l.append(unpack(item, formodulename))
+        return l
+    if t == typeAERecord:
+        d = {}
+        for i in range(desc.AECountItems()):
+            keyword, item = desc.AEGetNthDesc(i+1, '****')
+            d[keyword] = unpack(item, formodulename)
+        return d
+    if t == typeAEText:
+        record = desc.AECoerceDesc('reco')
+        return mkaetext(unpack(record, formodulename))
+    if t == typeAlias:
+        return Carbon.File.Alias(rawdata=desc.data)
+    # typeAppleEvent returned as unknown
+    if t == typeBoolean:
+        return struct.unpack('b', desc.data)[0]
+    if t == typeChar:
+        return desc.data
+    if t == typeUnicodeText:
+        return unicode(desc.data, 'utf16')
+    # typeColorTable coerced to typeAEList
+    # typeComp coerced to extended
+    # typeData returned as unknown
+    # typeDrawingArea coerced to typeAERecord
+    if t == typeEnumeration:
+        return mkenum(desc.data)
+    # typeEPS returned as unknown
+    if t == typeFalse:
+        return 0
+    if t == typeFloat:
+        data = desc.data
+        return struct.unpack('d', data)[0]
+    if t == typeFSS:
+        return Carbon.File.FSSpec(rawdata=desc.data)
+    if t == typeFSRef:
+        return Carbon.File.FSRef(rawdata=desc.data)
+    if t == typeInsertionLoc:
+        record = desc.AECoerceDesc('reco')
+        return mkinsertionloc(unpack(record, formodulename))
+    # typeInteger equal to typeLongInteger
+    if t == typeIntlText:
+        script, language = struct.unpack('hh', desc.data[:4])
+        return aetypes.IntlText(script, language, desc.data[4:])
+    if t == typeIntlWritingCode:
+        script, language = struct.unpack('hh', desc.data)
+        return aetypes.IntlWritingCode(script, language)
+    if t == typeKeyword:
+        return mkkeyword(desc.data)
+    if t == typeLongInteger:
+        return struct.unpack('l', desc.data)[0]
+    if t == typeLongDateTime:
+        a, b = struct.unpack('lL', desc.data)
+        return (long(a) << 32) + b
+    if t == typeNull:
+        return None
+    if t == typeMagnitude:
+        v = struct.unpack('l', desc.data)
+        if v < 0:
+            v = 0x100000000L + v
+        return v
+    if t == typeObjectSpecifier:
+        record = desc.AECoerceDesc('reco')
+        # If we have been told the name of the module we are unpacking aedescs for,
+        # we can attempt to create the right type of python object from that module.
+        if formodulename:
+            return mkobjectfrommodule(unpack(record, formodulename), formodulename)
+        return mkobject(unpack(record, formodulename))
+    # typePict returned as unknown
+    # typePixelMap coerced to typeAERecord
+    # typePixelMapMinus returned as unknown
+    # typeProcessSerialNumber returned as unknown
+    if t == typeQDPoint:
+        v, h = struct.unpack('hh', desc.data)
+        return aetypes.QDPoint(v, h)
+    if t == typeQDRectangle:
+        v0, h0, v1, h1 = struct.unpack('hhhh', desc.data)
+        return aetypes.QDRectangle(v0, h0, v1, h1)
+    if t == typeRGBColor:
+        r, g, b = struct.unpack('hhh', desc.data)
+        return aetypes.RGBColor(r, g, b)
+    # typeRotation coerced to typeAERecord
+    # typeScrapStyles returned as unknown
+    # typeSessionID returned as unknown
+    if t == typeShortFloat:
+        return struct.unpack('f', desc.data)[0]
+    if t == typeShortInteger:
+        return struct.unpack('h', desc.data)[0]
+    # typeSMFloat identical to typeShortFloat
+    # typeSMInt indetical to typeShortInt
+    # typeStyledText coerced to typeAERecord
+    if t == typeTargetID:
+        return mktargetid(desc.data)
+    # typeTextStyles coerced to typeAERecord
+    # typeTIFF returned as unknown
+    if t == typeTrue:
+        return 1
+    if t == typeType:
+        return mktype(desc.data, formodulename)
+    #
+    # The following are special
+    #
+    if t == 'rang':
+        record = desc.AECoerceDesc('reco')
+        return mkrange(unpack(record, formodulename))
+    if t == 'cmpd':
+        record = desc.AECoerceDesc('reco')
+        return mkcomparison(unpack(record, formodulename))
+    if t == 'logi':
+        record = desc.AECoerceDesc('reco')
+        return mklogical(unpack(record, formodulename))
+    return mkunknown(desc.type, desc.data)
+
+def coerce(data, egdata):
+    """Coerce a python object to another type using the AE coercers"""
+    pdata = pack(data)
+    pegdata = pack(egdata)
+    pdata = pdata.AECoerceDesc(pegdata.type)
+    return unpack(pdata)
+
+#
+# Helper routines for unpack
+#
+def mktargetid(data):
+    sessionID = getlong(data[:4])
+    name = mkppcportrec(data[4:4+72])
+    location = mklocationnamerec(data[76:76+36])
+    rcvrName = mkppcportrec(data[112:112+72])
+    return sessionID, name, location, rcvrName
+
+def mkppcportrec(rec):
+    namescript = getword(rec[:2])
+    name = getpstr(rec[2:2+33])
+    portkind = getword(rec[36:38])
+    if portkind == 1:
+        ctor = rec[38:42]
+        type = rec[42:46]
+        identity = (ctor, type)
+    else:
+        identity = getpstr(rec[38:38+33])
+    return namescript, name, portkind, identity
+
+def mklocationnamerec(rec):
+    kind = getword(rec[:2])
+    stuff = rec[2:]
+    if kind == 0: stuff = None
+    if kind == 2: stuff = getpstr(stuff)
+    return kind, stuff
+
+def mkunknown(type, data):
+    return aetypes.Unknown(type, data)
+
+def getpstr(s):
+    return s[1:1+ord(s[0])]
+
+def getlong(s):
+    return (ord(s[0])<<24) | (ord(s[1])<<16) | (ord(s[2])<<8) | ord(s[3])
+
+def getword(s):
+    return (ord(s[0])<<8) | (ord(s[1])<<0)
+
+def mkkeyword(keyword):
+    return aetypes.Keyword(keyword)
+
+def mkrange(dict):
+    return aetypes.Range(dict['star'], dict['stop'])
+
+def mkcomparison(dict):
+    return aetypes.Comparison(dict['obj1'], dict['relo'].enum, dict['obj2'])
+
+def mklogical(dict):
+    return aetypes.Logical(dict['logc'], dict['term'])
+
+def mkstyledtext(dict):
+    return aetypes.StyledText(dict['ksty'], dict['ktxt'])
+
+def mkaetext(dict):
+    return aetypes.AEText(dict[keyAEScriptTag], dict[keyAEStyles], dict[keyAEText])
+
+def mkinsertionloc(dict):
+    return aetypes.InsertionLoc(dict[keyAEObject], dict[keyAEPosition])
+
+def mkobject(dict):
+    want = dict['want'].type
+    form = dict['form'].enum
+    seld = dict['seld']
+    fr   = dict['from']
+    if form in ('name', 'indx', 'rang', 'test'):
+        if want == 'text': return aetypes.Text(seld, fr)
+        if want == 'cha ': return aetypes.Character(seld, fr)
+        if want == 'cwor': return aetypes.Word(seld, fr)
+        if want == 'clin': return aetypes.Line(seld, fr)
+        if want == 'cpar': return aetypes.Paragraph(seld, fr)
+        if want == 'cwin': return aetypes.Window(seld, fr)
+        if want == 'docu': return aetypes.Document(seld, fr)
+        if want == 'file': return aetypes.File(seld, fr)
+        if want == 'cins': return aetypes.InsertionPoint(seld, fr)
+    if want == 'prop' and form == 'prop' and aetypes.IsType(seld):
+        return aetypes.Property(seld.type, fr)
+    return aetypes.ObjectSpecifier(want, form, seld, fr)
+
+# Note by Jack: I'm not 100% sure of the following code. This was
+# provided by Donovan Preston, but I wonder whether the assignment
+# to __class__ is safe. Moreover, shouldn't there be a better
+# initializer for the classes in the suites?
+def mkobjectfrommodule(dict, modulename):
+    if type(dict['want']) == types.ClassType and issubclass(dict['want'], ObjectSpecifier):
+        # The type has already been converted to Python. Convert back:-(
+        classtype = dict['want']
+        dict['want'] = aetypes.mktype(classtype.want)
+    want = dict['want'].type
+    module = __import__(modulename)
+    codenamemapper = module._classdeclarations
+    classtype = codenamemapper.get(want, None)
+    newobj = mkobject(dict)
+    if classtype:
+        assert issubclass(classtype, ObjectSpecifier)
+        newobj.__class__ = classtype
+    return newobj
+
+def mktype(typecode, modulename=None):
+    if modulename:
+        module = __import__(modulename)
+        codenamemapper = module._classdeclarations
+        classtype = codenamemapper.get(typecode, None)
+        if classtype:
+            return classtype
+    return aetypes.mktype(typecode)

Added: vendor/Python/current/Lib/plat-mac/aetools.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/aetools.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/aetools.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,360 @@
+"""Tools for use in AppleEvent clients and servers.
+
+pack(x) converts a Python object to an AEDesc object
+unpack(desc) does the reverse
+
+packevent(event, parameters, attributes) sets params and attrs in an AEAppleEvent record
+unpackevent(event) returns the parameters and attributes from an AEAppleEvent record
+
+Plus...  Lots of classes and routines that help representing AE objects,
+ranges, conditionals, logicals, etc., so you can write, e.g.:
+
+    x = Character(1, Document("foobar"))
+
+and pack(x) will create an AE object reference equivalent to AppleScript's
+
+    character 1 of document "foobar"
+
+Some of the stuff that appears to be exported from this module comes from other
+files: the pack stuff from aepack, the objects from aetypes.
+
+"""
+
+
+from types import *
+from Carbon import AE
+from Carbon import Evt
+from Carbon import AppleEvents
+import MacOS
+import sys
+import time
+
+from aetypes import *
+from aepack import packkey, pack, unpack, coerce, AEDescType
+
+Error = 'aetools.Error'
+
+# Amount of time to wait for program to be launched
+LAUNCH_MAX_WAIT_TIME=10
+
+# Special code to unpack an AppleEvent (which is *not* a disguised record!)
+# Note by Jack: No??!? If I read the docs correctly it *is*....
+
+aekeywords = [
+    'tran',
+    'rtid',
+    'evcl',
+    'evid',
+    'addr',
+    'optk',
+    'timo',
+    'inte', # this attribute is read only - will be set in AESend
+    'esrc', # this attribute is read only
+    'miss', # this attribute is read only
+    'from'  # new in 1.0.1
+]
+
+def missed(ae):
+    try:
+        desc = ae.AEGetAttributeDesc('miss', 'keyw')
+    except AE.Error, msg:
+        return None
+    return desc.data
+
+def unpackevent(ae, formodulename=""):
+    parameters = {}
+    try:
+        dirobj = ae.AEGetParamDesc('----', '****')
+    except AE.Error:
+        pass
+    else:
+        parameters['----'] = unpack(dirobj, formodulename)
+        del dirobj
+    # Workaround for what I feel is a bug in OSX 10.2: 'errn' won't show up in missed...
+    try:
+        dirobj = ae.AEGetParamDesc('errn', '****')
+    except AE.Error:
+        pass
+    else:
+        parameters['errn'] = unpack(dirobj, formodulename)
+        del dirobj
+    while 1:
+        key = missed(ae)
+        if not key: break
+        parameters[key] = unpack(ae.AEGetParamDesc(key, '****'), formodulename)
+    attributes = {}
+    for key in aekeywords:
+        try:
+            desc = ae.AEGetAttributeDesc(key, '****')
+        except (AE.Error, MacOS.Error), msg:
+            if msg[0] != -1701 and msg[0] != -1704:
+                raise
+            continue
+        attributes[key] = unpack(desc, formodulename)
+    return parameters, attributes
+
+def packevent(ae, parameters = {}, attributes = {}):
+    for key, value in parameters.items():
+        packkey(ae, key, value)
+    for key, value in attributes.items():
+        ae.AEPutAttributeDesc(key, pack(value))
+
+#
+# Support routine for automatically generated Suite interfaces
+# These routines are also useable for the reverse function.
+#
+def keysubst(arguments, keydict):
+    """Replace long name keys by their 4-char counterparts, and check"""
+    ok = keydict.values()
+    for k in arguments.keys():
+        if keydict.has_key(k):
+            v = arguments[k]
+            del arguments[k]
+            arguments[keydict[k]] = v
+        elif k != '----' and k not in ok:
+            raise TypeError, 'Unknown keyword argument: %s'%k
+
+def enumsubst(arguments, key, edict):
+    """Substitute a single enum keyword argument, if it occurs"""
+    if not arguments.has_key(key) or edict is None:
+        return
+    v = arguments[key]
+    ok = edict.values()
+    if edict.has_key(v):
+        arguments[key] = Enum(edict[v])
+    elif not v in ok:
+        raise TypeError, 'Unknown enumerator: %s'%v
+
+def decodeerror(arguments):
+    """Create the 'best' argument for a raise MacOS.Error"""
+    errn = arguments['errn']
+    err_a1 = errn
+    if arguments.has_key('errs'):
+        err_a2 = arguments['errs']
+    else:
+        err_a2 = MacOS.GetErrorString(errn)
+    if arguments.has_key('erob'):
+        err_a3 = arguments['erob']
+    else:
+        err_a3 = None
+
+    return (err_a1, err_a2, err_a3)
+
+class TalkTo:
+    """An AE connection to an application"""
+    _signature = None   # Can be overridden by subclasses
+    _moduleName = None  # Can be overridden by subclasses
+    _elemdict = {}      # Can be overridden by subclasses
+    _propdict = {}      # Can be overridden by subclasses
+
+    __eventloop_initialized = 0
+    def __ensure_WMAvailable(klass):
+        if klass.__eventloop_initialized: return 1
+        if not MacOS.WMAvailable(): return 0
+        # Workaround for a but in MacOSX 10.2: we must have an event
+        # loop before we can call AESend.
+        Evt.WaitNextEvent(0,0)
+        return 1
+    __ensure_WMAvailable = classmethod(__ensure_WMAvailable)
+
+    def __init__(self, signature=None, start=0, timeout=0):
+        """Create a communication channel with a particular application.
+
+        Addressing the application is done by specifying either a
+        4-byte signature, an AEDesc or an object that will __aepack__
+        to an AEDesc.
+        """
+        self.target_signature = None
+        if signature is None:
+            signature = self._signature
+        if type(signature) == AEDescType:
+            self.target = signature
+        elif type(signature) == InstanceType and hasattr(signature, '__aepack__'):
+            self.target = signature.__aepack__()
+        elif type(signature) == StringType and len(signature) == 4:
+            self.target = AE.AECreateDesc(AppleEvents.typeApplSignature, signature)
+            self.target_signature = signature
+        else:
+            raise TypeError, "signature should be 4-char string or AEDesc"
+        self.send_flags = AppleEvents.kAEWaitReply
+        self.send_priority = AppleEvents.kAENormalPriority
+        if timeout:
+            self.send_timeout = timeout
+        else:
+            self.send_timeout = AppleEvents.kAEDefaultTimeout
+        if start:
+            self._start()
+
+    def _start(self):
+        """Start the application, if it is not running yet"""
+        try:
+            self.send('ascr', 'noop')
+        except AE.Error:
+            _launch(self.target_signature)
+            for i in range(LAUNCH_MAX_WAIT_TIME):
+                try:
+                    self.send('ascr', 'noop')
+                except AE.Error:
+                    pass
+                else:
+                    break
+                time.sleep(1)
+
+    def start(self):
+        """Deprecated, used _start()"""
+        self._start()
+
+    def newevent(self, code, subcode, parameters = {}, attributes = {}):
+        """Create a complete structure for an apple event"""
+
+        event = AE.AECreateAppleEvent(code, subcode, self.target,
+                  AppleEvents.kAutoGenerateReturnID, AppleEvents.kAnyTransactionID)
+        packevent(event, parameters, attributes)
+        return event
+
+    def sendevent(self, event):
+        """Send a pre-created appleevent, await the reply and unpack it"""
+        if not self.__ensure_WMAvailable():
+            raise RuntimeError, "No window manager access, cannot send AppleEvent"
+        reply = event.AESend(self.send_flags, self.send_priority,
+                                  self.send_timeout)
+        parameters, attributes = unpackevent(reply, self._moduleName)
+        return reply, parameters, attributes
+
+    def send(self, code, subcode, parameters = {}, attributes = {}):
+        """Send an appleevent given code/subcode/pars/attrs and unpack the reply"""
+        return self.sendevent(self.newevent(code, subcode, parameters, attributes))
+
+    #
+    # The following events are somehow "standard" and don't seem to appear in any
+    # suite...
+    #
+    def activate(self):
+        """Send 'activate' command"""
+        self.send('misc', 'actv')
+
+    def _get(self, _object, as=None, _attributes={}):
+        """_get: get data from an object
+        Required argument: the object
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: the data
+        """
+        _code = 'core'
+        _subcode = 'getd'
+
+        _arguments = {'----':_object}
+        if as:
+            _arguments['rtyp'] = mktype(as)
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.has_key('errn'):
+            raise Error, decodeerror(_arguments)
+
+        if _arguments.has_key('----'):
+            return _arguments['----']
+            if as:
+                item.__class__ = as
+            return item
+
+    get = _get
+
+    _argmap_set = {
+        'to' : 'data',
+    }
+
+    def _set(self, _object, _attributes={}, **_arguments):
+        """set: Set an object's data.
+        Required argument: the object for the command
+        Keyword argument to: The new value.
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'core'
+        _subcode = 'setd'
+
+        keysubst(_arguments, self._argmap_set)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise Error, decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    set = _set
+
+    # Magic glue to allow suite-generated classes to function somewhat
+    # like the "application" class in OSA.
+
+    def __getattr__(self, name):
+        if self._elemdict.has_key(name):
+            cls = self._elemdict[name]
+            return DelayedComponentItem(cls, None)
+        if self._propdict.has_key(name):
+            cls = self._propdict[name]
+            return cls()
+        raise AttributeError, name
+
+# Tiny Finder class, for local use only
+
+class _miniFinder(TalkTo):
+    def open(self, _object, _attributes={}, **_arguments):
+        """open: Open the specified object(s)
+        Required argument: list of objects to open
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'aevt'
+        _subcode = 'odoc'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.has_key('errn'):
+            raise Error, decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+#pass
+
+_finder = _miniFinder('MACS')
+
+def _launch(appfile):
+    """Open a file thru the finder. Specify file by name or fsspec"""
+    _finder.open(_application_file(('ID  ', appfile)))
+
+
+class _application_file(ComponentItem):
+    """application file - An application's file on disk"""
+    want = 'appf'
+
+_application_file._propdict = {
+}
+_application_file._elemdict = {
+}
+
+# Test program
+# XXXX Should test more, really...
+
+def test():
+    target = AE.AECreateDesc('sign', 'quil')
+    ae = AE.AECreateAppleEvent('aevt', 'oapp', target, -1, 0)
+    print unpackevent(ae)
+    raw_input(":")
+    ae = AE.AECreateAppleEvent('core', 'getd', target, -1, 0)
+    obj = Character(2, Word(1, Document(1)))
+    print obj
+    print repr(obj)
+    packevent(ae, {'----': obj})
+    params, attrs = unpackevent(ae)
+    print params['----']
+    raw_input(":")
+
+if __name__ == '__main__':
+    test()
+    sys.exit(1)

Added: vendor/Python/current/Lib/plat-mac/aetypes.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/aetypes.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/aetypes.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,568 @@
+"""aetypes - Python objects representing various AE types."""
+
+from Carbon.AppleEvents import *
+import struct
+from types import *
+import string
+
+#
+# convoluted, since there are cyclic dependencies between this file and
+# aetools_convert.
+#
+def pack(*args, **kwargs):
+    from aepack import pack
+    return pack( *args, **kwargs)
+
+def nice(s):
+    """'nice' representation of an object"""
+    if type(s) is StringType: return repr(s)
+    else: return str(s)
+
+class Unknown:
+    """An uninterpreted AE object"""
+
+    def __init__(self, type, data):
+        self.type = type
+        self.data = data
+
+    def __repr__(self):
+        return "Unknown(%r, %r)" % (self.type, self.data)
+
+    def __aepack__(self):
+        return pack(self.data, self.type)
+
+class Enum:
+    """An AE enumeration value"""
+
+    def __init__(self, enum):
+        self.enum = "%-4.4s" % str(enum)
+
+    def __repr__(self):
+        return "Enum(%r)" % (self.enum,)
+
+    def __str__(self):
+        return string.strip(self.enum)
+
+    def __aepack__(self):
+        return pack(self.enum, typeEnumeration)
+
+def IsEnum(x):
+    return isinstance(x, Enum)
+
+def mkenum(enum):
+    if IsEnum(enum): return enum
+    return Enum(enum)
+
+# Jack changed the way this is done
+class InsertionLoc:
+    def __init__(self, of, pos):
+        self.of = of
+        self.pos = pos
+
+    def __repr__(self):
+        return "InsertionLoc(%r, %r)" % (self.of, self.pos)
+
+    def __aepack__(self):
+        rec = {'kobj': self.of, 'kpos': self.pos}
+        return pack(rec, forcetype='insl')
+
+# Convenience functions for dsp:
+def beginning(of):
+    return InsertionLoc(of, Enum('bgng'))
+
+def end(of):
+    return InsertionLoc(of, Enum('end '))
+
+class Boolean:
+    """An AE boolean value"""
+
+    def __init__(self, bool):
+        self.bool = (not not bool)
+
+    def __repr__(self):
+        return "Boolean(%r)" % (self.bool,)
+
+    def __str__(self):
+        if self.bool:
+            return "True"
+        else:
+            return "False"
+
+    def __aepack__(self):
+        return pack(struct.pack('b', self.bool), 'bool')
+
+def IsBoolean(x):
+    return isinstance(x, Boolean)
+
+def mkboolean(bool):
+    if IsBoolean(bool): return bool
+    return Boolean(bool)
+
+class Type:
+    """An AE 4-char typename object"""
+
+    def __init__(self, type):
+        self.type = "%-4.4s" % str(type)
+
+    def __repr__(self):
+        return "Type(%r)" % (self.type,)
+
+    def __str__(self):
+        return string.strip(self.type)
+
+    def __aepack__(self):
+        return pack(self.type, typeType)
+
+def IsType(x):
+    return isinstance(x, Type)
+
+def mktype(type):
+    if IsType(type): return type
+    return Type(type)
+
+
+class Keyword:
+    """An AE 4-char keyword object"""
+
+    def __init__(self, keyword):
+        self.keyword = "%-4.4s" % str(keyword)
+
+    def __repr__(self):
+        return "Keyword(%r)" % `self.keyword`
+
+    def __str__(self):
+        return string.strip(self.keyword)
+
+    def __aepack__(self):
+        return pack(self.keyword, typeKeyword)
+
+def IsKeyword(x):
+    return isinstance(x, Keyword)
+
+class Range:
+    """An AE range object"""
+
+    def __init__(self, start, stop):
+        self.start = start
+        self.stop = stop
+
+    def __repr__(self):
+        return "Range(%r, %r)" % (self.start, self.stop)
+
+    def __str__(self):
+        return "%s thru %s" % (nice(self.start), nice(self.stop))
+
+    def __aepack__(self):
+        return pack({'star': self.start, 'stop': self.stop}, 'rang')
+
+def IsRange(x):
+    return isinstance(x, Range)
+
+class Comparison:
+    """An AE Comparison"""
+
+    def __init__(self, obj1, relo, obj2):
+        self.obj1 = obj1
+        self.relo = "%-4.4s" % str(relo)
+        self.obj2 = obj2
+
+    def __repr__(self):
+        return "Comparison(%r, %r, %r)" % (self.obj1, self.relo, self.obj2)
+
+    def __str__(self):
+        return "%s %s %s" % (nice(self.obj1), string.strip(self.relo), nice(self.obj2))
+
+    def __aepack__(self):
+        return pack({'obj1': self.obj1,
+                 'relo': mkenum(self.relo),
+                 'obj2': self.obj2},
+                'cmpd')
+
+def IsComparison(x):
+    return isinstance(x, Comparison)
+
+class NComparison(Comparison):
+    # The class attribute 'relo' must be set in a subclass
+
+    def __init__(self, obj1, obj2):
+        Comparison.__init__(obj1, self.relo, obj2)
+
+class Ordinal:
+    """An AE Ordinal"""
+
+    def __init__(self, abso):
+#       self.obj1 = obj1
+        self.abso = "%-4.4s" % str(abso)
+
+    def __repr__(self):
+        return "Ordinal(%r)" % (self.abso,)
+
+    def __str__(self):
+        return "%s" % (string.strip(self.abso))
+
+    def __aepack__(self):
+        return pack(self.abso, 'abso')
+
+def IsOrdinal(x):
+    return isinstance(x, Ordinal)
+
+class NOrdinal(Ordinal):
+    # The class attribute 'abso' must be set in a subclass
+
+    def __init__(self):
+        Ordinal.__init__(self, self.abso)
+
+class Logical:
+    """An AE logical expression object"""
+
+    def __init__(self, logc, term):
+        self.logc = "%-4.4s" % str(logc)
+        self.term = term
+
+    def __repr__(self):
+        return "Logical(%r, %r)" % (self.logc, self.term)
+
+    def __str__(self):
+        if type(self.term) == ListType and len(self.term) == 2:
+            return "%s %s %s" % (nice(self.term[0]),
+                                 string.strip(self.logc),
+                                 nice(self.term[1]))
+        else:
+            return "%s(%s)" % (string.strip(self.logc), nice(self.term))
+
+    def __aepack__(self):
+        return pack({'logc': mkenum(self.logc), 'term': self.term}, 'logi')
+
+def IsLogical(x):
+    return isinstance(x, Logical)
+
+class StyledText:
+    """An AE object respresenting text in a certain style"""
+
+    def __init__(self, style, text):
+        self.style = style
+        self.text = text
+
+    def __repr__(self):
+        return "StyledText(%r, %r)" % (self.style, self.text)
+
+    def __str__(self):
+        return self.text
+
+    def __aepack__(self):
+        return pack({'ksty': self.style, 'ktxt': self.text}, 'STXT')
+
+def IsStyledText(x):
+    return isinstance(x, StyledText)
+
+class AEText:
+    """An AE text object with style, script and language specified"""
+
+    def __init__(self, script, style, text):
+        self.script = script
+        self.style = style
+        self.text = text
+
+    def __repr__(self):
+        return "AEText(%r, %r, %r)" % (self.script, self.style, self.text)
+
+    def __str__(self):
+        return self.text
+
+    def __aepack__(self):
+        return pack({keyAEScriptTag: self.script, keyAEStyles: self.style,
+                 keyAEText: self.text}, typeAEText)
+
+def IsAEText(x):
+    return isinstance(x, AEText)
+
+class IntlText:
+    """A text object with script and language specified"""
+
+    def __init__(self, script, language, text):
+        self.script = script
+        self.language = language
+        self.text = text
+
+    def __repr__(self):
+        return "IntlText(%r, %r, %r)" % (self.script, self.language, self.text)
+
+    def __str__(self):
+        return self.text
+
+    def __aepack__(self):
+        return pack(struct.pack('hh', self.script, self.language)+self.text,
+            typeIntlText)
+
+def IsIntlText(x):
+    return isinstance(x, IntlText)
+
+class IntlWritingCode:
+    """An object representing script and language"""
+
+    def __init__(self, script, language):
+        self.script = script
+        self.language = language
+
+    def __repr__(self):
+        return "IntlWritingCode(%r, %r)" % (self.script, self.language)
+
+    def __str__(self):
+        return "script system %d, language %d"%(self.script, self.language)
+
+    def __aepack__(self):
+        return pack(struct.pack('hh', self.script, self.language),
+            typeIntlWritingCode)
+
+def IsIntlWritingCode(x):
+    return isinstance(x, IntlWritingCode)
+
+class QDPoint:
+    """A point"""
+
+    def __init__(self, v, h):
+        self.v = v
+        self.h = h
+
+    def __repr__(self):
+        return "QDPoint(%r, %r)" % (self.v, self.h)
+
+    def __str__(self):
+        return "(%d, %d)"%(self.v, self.h)
+
+    def __aepack__(self):
+        return pack(struct.pack('hh', self.v, self.h),
+            typeQDPoint)
+
+def IsQDPoint(x):
+    return isinstance(x, QDPoint)
+
+class QDRectangle:
+    """A rectangle"""
+
+    def __init__(self, v0, h0, v1, h1):
+        self.v0 = v0
+        self.h0 = h0
+        self.v1 = v1
+        self.h1 = h1
+
+    def __repr__(self):
+        return "QDRectangle(%r, %r, %r, %r)" % (self.v0, self.h0, self.v1, self.h1)
+
+    def __str__(self):
+        return "(%d, %d)-(%d, %d)"%(self.v0, self.h0, self.v1, self.h1)
+
+    def __aepack__(self):
+        return pack(struct.pack('hhhh', self.v0, self.h0, self.v1, self.h1),
+            typeQDRectangle)
+
+def IsQDRectangle(x):
+    return isinstance(x, QDRectangle)
+
+class RGBColor:
+    """An RGB color"""
+
+    def __init__(self, r, g, b):
+        self.r = r
+        self.g = g
+        self.b = b
+
+    def __repr__(self):
+        return "RGBColor(%r, %r, %r)" % (self.r, self.g, self.b)
+
+    def __str__(self):
+        return "0x%x red, 0x%x green, 0x%x blue"% (self.r, self.g, self.b)
+
+    def __aepack__(self):
+        return pack(struct.pack('hhh', self.r, self.g, self.b),
+            typeRGBColor)
+
+def IsRGBColor(x):
+    return isinstance(x, RGBColor)
+
+class ObjectSpecifier:
+
+    """A class for constructing and manipulation AE object specifiers in python.
+
+    An object specifier is actually a record with four fields:
+
+    key type    description
+    --- ----    -----------
+
+    'want'  type    4-char class code of thing we want,
+            e.g. word, paragraph or property
+
+    'form'  enum    how we specify which 'want' thing(s) we want,
+            e.g. by index, by range, by name, or by property specifier
+
+    'seld'  any which thing(s) we want,
+            e.g. its index, its name, or its property specifier
+
+    'from'  object  the object in which it is contained,
+            or null, meaning look for it in the application
+
+    Note that we don't call this class plain "Object", since that name
+    is likely to be used by the application.
+    """
+
+    def __init__(self, want, form, seld, fr = None):
+        self.want = want
+        self.form = form
+        self.seld = seld
+        self.fr = fr
+
+    def __repr__(self):
+        s = "ObjectSpecifier(%r, %r, %r" % (self.want, self.form, self.seld)
+        if self.fr:
+            s = s + ", %r)" % (self.fr,)
+        else:
+            s = s + ")"
+        return s
+
+    def __aepack__(self):
+        return pack({'want': mktype(self.want),
+                 'form': mkenum(self.form),
+                 'seld': self.seld,
+                 'from': self.fr},
+                'obj ')
+
+def IsObjectSpecifier(x):
+    return isinstance(x, ObjectSpecifier)
+
+
+# Backwards compatibility, sigh...
+class Property(ObjectSpecifier):
+
+    def __init__(self, which, fr = None, want='prop'):
+        ObjectSpecifier.__init__(self, want, 'prop', mktype(which), fr)
+
+    def __repr__(self):
+        if self.fr:
+            return "Property(%r, %r)" % (self.seld.type, self.fr)
+        else:
+            return "Property(%r)" % (self.seld.type,)
+
+    def __str__(self):
+        if self.fr:
+            return "Property %s of %s" % (str(self.seld), str(self.fr))
+        else:
+            return "Property %s" % str(self.seld)
+
+
+class NProperty(ObjectSpecifier):
+    # Subclasses *must* self baseclass attributes:
+    # want is the type of this property
+    # which is the property name of this property
+
+    def __init__(self, fr = None):
+        #try:
+        #   dummy = self.want
+        #except:
+        #   self.want = 'prop'
+        self.want = 'prop'
+        ObjectSpecifier.__init__(self, self.want, 'prop',
+                    mktype(self.which), fr)
+
+    def __repr__(self):
+        rv = "Property(%r" % (self.seld.type,)
+        if self.fr:
+            rv = rv + ", fr=%r" % (self.fr,)
+        if self.want != 'prop':
+            rv = rv + ", want=%r" % (self.want,)
+        return rv + ")"
+
+    def __str__(self):
+        if self.fr:
+            return "Property %s of %s" % (str(self.seld), str(self.fr))
+        else:
+            return "Property %s" % str(self.seld)
+
+
+class SelectableItem(ObjectSpecifier):
+
+    def __init__(self, want, seld, fr = None):
+        t = type(seld)
+        if t == StringType:
+            form = 'name'
+        elif IsRange(seld):
+            form = 'rang'
+        elif IsComparison(seld) or IsLogical(seld):
+            form = 'test'
+        elif t == TupleType:
+            # Breakout: specify both form and seld in a tuple
+            # (if you want ID or rele or somesuch)
+            form, seld = seld
+        else:
+            form = 'indx'
+        ObjectSpecifier.__init__(self, want, form, seld, fr)
+
+
+class ComponentItem(SelectableItem):
+    # Derived classes *must* set the *class attribute* 'want' to some constant
+    # Also, dictionaries _propdict and _elemdict must be set to map property
+    # and element names to the correct classes
+
+    _propdict = {}
+    _elemdict = {}
+    def __init__(self, which, fr = None):
+        SelectableItem.__init__(self, self.want, which, fr)
+
+    def __repr__(self):
+        if not self.fr:
+            return "%s(%r)" % (self.__class__.__name__, self.seld)
+        return "%s(%r, %r)" % (self.__class__.__name__, self.seld, self.fr)
+
+    def __str__(self):
+        seld = self.seld
+        if type(seld) == StringType:
+            ss = repr(seld)
+        elif IsRange(seld):
+            start, stop = seld.start, seld.stop
+            if type(start) == InstanceType == type(stop) and \
+               start.__class__ == self.__class__ == stop.__class__:
+                ss = str(start.seld) + " thru " + str(stop.seld)
+            else:
+                ss = str(seld)
+        else:
+            ss = str(seld)
+        s = "%s %s" % (self.__class__.__name__, ss)
+        if self.fr: s = s + " of %s" % str(self.fr)
+        return s
+
+    def __getattr__(self, name):
+        if self._elemdict.has_key(name):
+            cls = self._elemdict[name]
+            return DelayedComponentItem(cls, self)
+        if self._propdict.has_key(name):
+            cls = self._propdict[name]
+            return cls(self)
+        raise AttributeError, name
+
+
+class DelayedComponentItem:
+    def __init__(self, compclass, fr):
+        self.compclass = compclass
+        self.fr = fr
+
+    def __call__(self, which):
+        return self.compclass(which, self.fr)
+
+    def __repr__(self):
+        return "%s(???, %r)" % (self.__class__.__name__, self.fr)
+
+    def __str__(self):
+        return "selector for element %s of %s"%(self.__class__.__name__, str(self.fr))
+
+template = """
+class %s(ComponentItem): want = '%s'
+"""
+
+exec template % ("Text", 'text')
+exec template % ("Character", 'cha ')
+exec template % ("Word", 'cwor')
+exec template % ("Line", 'clin')
+exec template % ("paragraph", 'cpar')
+exec template % ("Window", 'cwin')
+exec template % ("Document", 'docu')
+exec template % ("File", 'file')
+exec template % ("InsertionPoint", 'cins')

Added: vendor/Python/current/Lib/plat-mac/applesingle.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/applesingle.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/applesingle.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,137 @@
+r"""Routines to decode AppleSingle files
+"""
+import struct
+import sys
+try:
+    import MacOS
+    import Carbon.File
+except:
+    class MacOS:
+        def openrf(path, mode):
+            return open(path + '.rsrc', mode)
+        openrf = classmethod(openrf)
+    class Carbon:
+        class File:
+            class FSSpec:
+                pass
+            class FSRef:
+                pass
+            class Alias:
+                pass
+
+# all of the errors in this module are really errors in the input
+# so I think it should test positive against ValueError.
+class Error(ValueError):
+    pass
+
+# File header format: magic, version, unused, number of entries
+AS_HEADER_FORMAT=">LL16sh"
+AS_HEADER_LENGTH=26
+# The flag words for AppleSingle
+AS_MAGIC=0x00051600
+AS_VERSION=0x00020000
+
+# Entry header format: id, offset, length
+AS_ENTRY_FORMAT=">lll"
+AS_ENTRY_LENGTH=12
+
+# The id values
+AS_DATAFORK=1
+AS_RESOURCEFORK=2
+AS_IGNORE=(3,4,5,6,8,9,10,11,12,13,14,15)
+
+class AppleSingle(object):
+    datafork = None
+    resourcefork = None
+
+    def __init__(self, fileobj, verbose=False):
+        header = fileobj.read(AS_HEADER_LENGTH)
+        try:
+            magic, version, ig, nentry = struct.unpack(AS_HEADER_FORMAT, header)
+        except ValueError, arg:
+            raise Error, "Unpack header error: %s" % (arg,)
+        if verbose:
+            print 'Magic:   0x%8.8x' % (magic,)
+            print 'Version: 0x%8.8x' % (version,)
+            print 'Entries: %d' % (nentry,)
+        if magic != AS_MAGIC:
+            raise Error, "Unknown AppleSingle magic number 0x%8.8x" % (magic,)
+        if version != AS_VERSION:
+            raise Error, "Unknown AppleSingle version number 0x%8.8x" % (version,)
+        if nentry <= 0:
+            raise Error, "AppleSingle file contains no forks"
+        headers = [fileobj.read(AS_ENTRY_LENGTH) for i in xrange(nentry)]
+        self.forks = []
+        for hdr in headers:
+            try:
+                restype, offset, length = struct.unpack(AS_ENTRY_FORMAT, hdr)
+            except ValueError, arg:
+                raise Error, "Unpack entry error: %s" % (arg,)
+            if verbose:
+                print "Fork %d, offset %d, length %d" % (restype, offset, length)
+            fileobj.seek(offset)
+            data = fileobj.read(length)
+            if len(data) != length:
+                raise Error, "Short read: expected %d bytes got %d" % (length, len(data))
+            self.forks.append((restype, data))
+            if restype == AS_DATAFORK:
+                self.datafork = data
+            elif restype == AS_RESOURCEFORK:
+                self.resourcefork = data
+
+    def tofile(self, path, resonly=False):
+        outfile = open(path, 'wb')
+        data = False
+        if resonly:
+            if self.resourcefork is None:
+                raise Error, "No resource fork found"
+            fp = open(path, 'wb')
+            fp.write(self.resourcefork)
+            fp.close()
+        elif (self.resourcefork is None and self.datafork is None):
+            raise Error, "No useful forks found"
+        else:
+            if self.datafork is not None:
+                fp = open(path, 'wb')
+                fp.write(self.datafork)
+                fp.close()
+            if self.resourcefork is not None:
+                fp = MacOS.openrf(path, '*wb')
+                fp.write(self.resourcefork)
+                fp.close()
+
+def decode(infile, outpath, resonly=False, verbose=False):
+    """decode(infile, outpath [, resonly=False, verbose=False])
+
+    Creates a decoded file from an AppleSingle encoded file.
+    If resonly is True, then it will create a regular file at
+    outpath containing only the resource fork from infile.
+    Otherwise it will create an AppleDouble file at outpath
+    with the data and resource forks from infile.  On platforms
+    without the MacOS module, it will create inpath and inpath+'.rsrc'
+    with the data and resource forks respectively.
+
+    """
+    if not hasattr(infile, 'read'):
+        if isinstance(infile, Carbon.File.Alias):
+            infile = infile.ResolveAlias()[0]
+        if isinstance(infile, (Carbon.File.FSSpec, Carbon.File.FSRef)):
+            infile = infile.as_pathname()
+        infile = open(infile, 'rb')
+
+    asfile = AppleSingle(infile, verbose=verbose)
+    asfile.tofile(outpath, resonly=resonly)
+
+def _test():
+    if len(sys.argv) < 3 or sys.argv[1] == '-r' and len(sys.argv) != 4:
+        print 'Usage: applesingle.py [-r] applesinglefile decodedfile'
+        sys.exit(1)
+    if sys.argv[1] == '-r':
+        resonly = True
+        del sys.argv[1]
+    else:
+        resonly = False
+    decode(sys.argv[1], sys.argv[2], resonly=resonly)
+
+if __name__ == '__main__':
+    _test()

Added: vendor/Python/current/Lib/plat-mac/appletrawmain.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/appletrawmain.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/appletrawmain.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,63 @@
+# Emulate sys.argv and run __main__.py or __main__.pyc in an environment that
+# is as close to "normal" as possible.
+#
+# This script is put into __rawmain__.pyc for applets that need argv
+# emulation, by BuildApplet and friends.
+#
+import argvemulator
+import os
+import sys
+import marshal
+
+#
+# Make sure we have an argv[0], and make _dir point to the Resources
+# directory.
+#
+if not sys.argv or sys.argv[0][:1] == '-':
+    # Insert our (guessed) name.
+    _dir = os.path.split(sys.executable)[0] # removes "python"
+    _dir = os.path.split(_dir)[0] # Removes "MacOS"
+    _dir = os.path.join(_dir, 'Resources')
+    sys.argv.insert(0, '__rawmain__')
+else:
+    _dir = os.path.split(sys.argv[0])[0]
+#
+# Add the Resources directory to the path. This is where files installed
+# by BuildApplet.py with the --extra option show up, and if those files are
+# modules this sys.path modification is necessary to be able to import them.
+#
+sys.path.insert(0, _dir)
+#
+# Create sys.argv
+#
+argvemulator.ArgvCollector().mainloop()
+#
+# Find the real main program to run
+#
+__file__ = os.path.join(_dir, '__main__.py')
+if os.path.exists(__file__):
+    #
+    # Setup something resembling a normal environment and go.
+    #
+    sys.argv[0] = __file__
+    del argvemulator, os, sys, _dir
+    execfile(__file__)
+else:
+    __file__ = os.path.join(_dir, '__main__.pyc')
+    if os.path.exists(__file__):
+        #
+        # If we have only a .pyc file we read the code object from that
+        #
+        sys.argv[0] = __file__
+        _fp = open(__file__, 'rb')
+        _fp.read(8)
+        __code__ = marshal.load(_fp)
+        #
+        # Again, we create an almost-normal environment (only __code__ is
+        # funny) and go.
+        #
+        del argvemulator, os, sys, marshal, _dir, _fp
+        exec __code__
+    else:
+        sys.stderr.write("%s: neither __main__.py nor __main__.pyc found\n"%sys.argv[0])
+        sys.exit(1)

Added: vendor/Python/current/Lib/plat-mac/appletrunner.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/appletrunner.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/appletrunner.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,17 @@
+#!/usr/bin/env python
+# This file is meant as an executable script for running applets.
+# BuildApplet will use it as the main executable in the .app bundle if
+# we are not running in a framework build.
+
+import os
+import sys
+for name in ["__rawmain__.py", "__rawmain__.pyc", "__main__.py", "__main__.pyc"]:
+    realmain = os.path.join(os.path.dirname(os.path.dirname(sys.argv[0])),
+                      "Resources", name)
+    if os.path.exists(realmain):
+        break
+else:
+    sys.stderr.write("%s: cannot find applet main program\n" % sys.argv[0])
+    sys.exit(1)
+sys.argv.insert(1, realmain)
+os.execve(sys.executable, sys.argv, os.environ)


Property changes on: vendor/Python/current/Lib/plat-mac/appletrunner.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/plat-mac/argvemulator.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/argvemulator.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/argvemulator.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,89 @@
+"""argvemulator - create sys.argv from OSA events. Used by applets that
+want unix-style arguments.
+"""
+
+import sys
+import traceback
+from Carbon import AE
+from Carbon.AppleEvents import *
+from Carbon import Evt
+from Carbon import File
+from Carbon.Events import *
+import aetools
+
+class ArgvCollector:
+
+    """A minimal FrameWork.Application-like class"""
+
+    def __init__(self):
+        self.quitting = 0
+        # Remove the funny -psn_xxx_xxx argument
+        if len(sys.argv) > 1 and sys.argv[1][:4] == '-psn':
+            del sys.argv[1]
+
+        AE.AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, self.__runapp)
+        AE.AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, self.__openfiles)
+
+    def close(self):
+        AE.AERemoveEventHandler(kCoreEventClass, kAEOpenApplication)
+        AE.AERemoveEventHandler(kCoreEventClass, kAEOpenDocuments)
+
+    def mainloop(self, mask = highLevelEventMask, timeout = 1*60):
+        # Note: this is not the right way to run an event loop in OSX or even
+        # "recent" versions of MacOS9. This is however code that has proven
+        # itself.
+        stoptime = Evt.TickCount() + timeout
+        while not self.quitting and Evt.TickCount() < stoptime:
+            self._dooneevent(mask, timeout)
+
+        if not self.quitting:
+            print "argvemulator: timeout waiting for arguments"
+
+        self.close()
+
+    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: %r %r" % (hex(message), hex(h | (v<<16)))
+                print 'AE error: ', err
+                print 'in', msg
+                traceback.print_exc()
+            return
+        else:
+            print "Unhandled event:", event
+
+
+    def _quit(self):
+        self.quitting = 1
+
+    def __runapp(self, requestevent, replyevent):
+        self._quit()
+
+    def __openfiles(self, requestevent, replyevent):
+        try:
+            listdesc = requestevent.AEGetParamDesc(keyDirectObject, typeAEList)
+            for i in range(listdesc.AECountItems()):
+                aliasdesc = listdesc.AEGetNthDesc(i+1, typeAlias)[1]
+                alias = File.Alias(rawdata=aliasdesc.data)
+                fsref = alias.FSResolveAlias(None)[0]
+                pathname = fsref.as_pathname()
+                sys.argv.append(pathname)
+        except  Exception, e:
+            print "argvemulator.py warning: can't unpack an open document event"
+            import traceback
+            traceback.print_exc()
+
+        self._quit()
+
+if __name__ == '__main__':
+    ArgvCollector().mainloop()
+    print "sys.argv=", sys.argv

Added: vendor/Python/current/Lib/plat-mac/bgenlocations.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/bgenlocations.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/bgenlocations.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,55 @@
+#
+# Local customizations for generating the Carbon interface modules.
+# Edit this file to reflect where things should be on your system.
+# Note that pathnames are unix-style for OSX MachoPython/unix-Python,
+# but mac-style for MacPython, whether running on OS9 or OSX.
+#
+
+import sys, os
+
+Error = "bgenlocations.Error"
+#
+# Where bgen is. For unix-Python bgen isn't installed, so you have to refer to
+# the source tree here.
+BGENDIR="/Users/jack/src/python/Tools/bgen/bgen"
+
+#
+# Where to find the Universal Header include files. If you have CodeWarrior
+# installed you can use the Universal Headers from there, otherwise you can
+# download them from the Apple website. Bgen can handle both unix- and mac-style
+# end of lines, so don't worry about that.
+#
+INCLUDEDIR="/Users/jack/src/Universal/Interfaces/CIncludes"
+
+#
+# Where to put the python definitions files. Note that, on unix-Python,
+# if you want to commit your changes to the CVS repository this should refer to
+# your source directory, not your installed directory.
+#
+TOOLBOXDIR="/Users/jack/src/python/Lib/plat-mac/Carbon"
+
+# Creator for C files:
+CREATOR="CWIE"
+
+# The previous definitions can be overriden by creating a module
+# bgenlocationscustomize.py and putting it in site-packages (or anywere else
+# on sys.path, actually)
+try:
+    from bgenlocationscustomize import *
+except ImportError:
+    pass
+
+if not os.path.exists(BGENDIR):
+    raise Error, "Please fix bgenlocations.py, BGENDIR does not exist: %s" % BGENDIR
+if not os.path.exists(INCLUDEDIR):
+    raise Error, "Please fix bgenlocations.py, INCLUDEDIR does not exist: %s" % INCLUDEDIR
+if not os.path.exists(TOOLBOXDIR):
+    raise Error, "Please fix bgenlocations.py, TOOLBOXDIR does not exist: %s" % TOOLBOXDIR
+
+# Sigh, due to the way these are used make sure they end with : or /.
+if BGENDIR[-1] != os.sep:
+    BGENDIR = BGENDIR + os.sep
+if INCLUDEDIR[-1] != os.sep:
+    INCLUDEDIR = INCLUDEDIR + os.sep
+if TOOLBOXDIR[-1] != os.sep:
+    TOOLBOXDIR = TOOLBOXDIR + os.sep

Added: vendor/Python/current/Lib/plat-mac/buildtools.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/buildtools.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/buildtools.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,420 @@
+"""tools for BuildApplet and BuildApplication"""
+
+import sys
+import os
+import string
+import imp
+import marshal
+from Carbon import Res
+import Carbon.Files
+import Carbon.File
+import MacOS
+import macostools
+import macresource
+import EasyDialogs
+import shutil
+
+
+BuildError = "BuildError"
+
+# .pyc file (and 'PYC ' resource magic number)
+MAGIC = imp.get_magic()
+
+# Template file (searched on sys.path)
+TEMPLATE = "PythonInterpreter"
+
+# Specification of our resource
+RESTYPE = 'PYC '
+RESNAME = '__main__'
+
+# A resource with this name sets the "owner" (creator) of the destination
+# It should also have ID=0. Either of these alone is not enough.
+OWNERNAME = "owner resource"
+
+# Default applet creator code
+DEFAULT_APPLET_CREATOR="Pyta"
+
+# OpenResFile mode parameters
+READ = 1
+WRITE = 2
+
+# Parameter for FSOpenResourceFile
+RESOURCE_FORK_NAME=Carbon.File.FSGetResourceForkName()
+
+def findtemplate(template=None):
+    """Locate the applet template along sys.path"""
+    if MacOS.runtimemodel == 'macho':
+        return None
+    if not template:
+        template=TEMPLATE
+    for p in sys.path:
+        file = os.path.join(p, template)
+        try:
+            file, d1, d2 = Carbon.File.FSResolveAliasFile(file, 1)
+            break
+        except (Carbon.File.Error, ValueError):
+            continue
+    else:
+        raise BuildError, "Template %r not found on sys.path" % (template,)
+    file = file.as_pathname()
+    return file
+
+def process(template, filename, destname, copy_codefragment=0,
+        rsrcname=None, others=[], raw=0, progress="default", destroot=""):
+
+    if progress == "default":
+        progress = EasyDialogs.ProgressBar("Processing %s..."%os.path.split(filename)[1], 120)
+        progress.label("Compiling...")
+        progress.inc(0)
+    # check for the script name being longer than 32 chars. This may trigger a bug
+    # on OSX that can destroy your sourcefile.
+    if '#' in os.path.split(filename)[1]:
+        raise BuildError, "BuildApplet could destroy your sourcefile on OSX, please rename: %s" % filename
+    # Read the source and compile it
+    # (there's no point overwriting the destination if it has a syntax error)
+
+    fp = open(filename, 'rU')
+    text = fp.read()
+    fp.close()
+    try:
+        code = compile(text + '\n', filename, "exec")
+    except SyntaxError, arg:
+        raise BuildError, "Syntax error in script %s: %s" % (filename, arg)
+    except EOFError:
+        raise BuildError, "End-of-file in script %s" % (filename,)
+
+    # Set the destination file name. Note that basename
+    # does contain the whole filepath, only a .py is stripped.
+
+    if string.lower(filename[-3:]) == ".py":
+        basename = filename[:-3]
+        if MacOS.runtimemodel != 'macho' and not destname:
+            destname = basename
+    else:
+        basename = filename
+
+    if not destname:
+        if MacOS.runtimemodel == 'macho':
+            destname = basename + '.app'
+        else:
+            destname = basename + '.applet'
+    if not rsrcname:
+        rsrcname = basename + '.rsrc'
+
+    # Try removing the output file. This fails in MachO, but it should
+    # do any harm.
+    try:
+        os.remove(destname)
+    except os.error:
+        pass
+    process_common(template, progress, code, rsrcname, destname, 0,
+        copy_codefragment, raw, others, filename, destroot)
+
+
+def update(template, filename, output):
+    if MacOS.runtimemodel == 'macho':
+        raise BuildError, "No updating yet for MachO applets"
+    if progress:
+        progress = EasyDialogs.ProgressBar("Updating %s..."%os.path.split(filename)[1], 120)
+    else:
+        progress = None
+    if not output:
+        output = filename + ' (updated)'
+
+    # Try removing the output file
+    try:
+        os.remove(output)
+    except os.error:
+        pass
+    process_common(template, progress, None, filename, output, 1, 1)
+
+
+def process_common(template, progress, code, rsrcname, destname, is_update,
+        copy_codefragment, raw=0, others=[], filename=None, destroot=""):
+    if MacOS.runtimemodel == 'macho':
+        return process_common_macho(template, progress, code, rsrcname, destname,
+            is_update, raw, others, filename, destroot)
+    if others:
+        raise BuildError, "Extra files only allowed for MachoPython applets"
+    # Create FSSpecs for the various files
+    template_fsr, d1, d2 = Carbon.File.FSResolveAliasFile(template, 1)
+    template = template_fsr.as_pathname()
+
+    # Copy data (not resources, yet) from the template
+    if progress:
+        progress.label("Copy data fork...")
+        progress.set(10)
+
+    if copy_codefragment:
+        tmpl = open(template, "rb")
+        dest = open(destname, "wb")
+        data = tmpl.read()
+        if data:
+            dest.write(data)
+        dest.close()
+        tmpl.close()
+        del dest
+        del tmpl
+
+    # Open the output resource fork
+
+    if progress:
+        progress.label("Copy resources...")
+        progress.set(20)
+    try:
+        output = Res.FSOpenResourceFile(destname, RESOURCE_FORK_NAME, WRITE)
+    except MacOS.Error:
+        destdir, destfile = os.path.split(destname)
+        Res.FSCreateResourceFile(destdir, unicode(destfile), RESOURCE_FORK_NAME)
+        output = Res.FSOpenResourceFile(destname, RESOURCE_FORK_NAME, WRITE)
+
+    # Copy the resources from the target specific resource template, if any
+    typesfound, ownertype = [], None
+    try:
+        input = Res.FSOpenResourceFile(rsrcname, RESOURCE_FORK_NAME, READ)
+    except (MacOS.Error, ValueError):
+        pass
+        if progress:
+            progress.inc(50)
+    else:
+        if is_update:
+            skip_oldfile = ['cfrg']
+        else:
+            skip_oldfile = []
+        typesfound, ownertype = copyres(input, output, skip_oldfile, 0, progress)
+        Res.CloseResFile(input)
+
+    # Check which resource-types we should not copy from the template
+    skiptypes = []
+    if 'vers' in typesfound: skiptypes.append('vers')
+    if 'SIZE' in typesfound: skiptypes.append('SIZE')
+    if 'BNDL' in typesfound: skiptypes = skiptypes + ['BNDL', 'FREF', 'icl4',
+            'icl8', 'ics4', 'ics8', 'ICN#', 'ics#']
+    if not copy_codefragment:
+        skiptypes.append('cfrg')
+##  skipowner = (ownertype <> None)
+
+    # Copy the resources from the template
+
+    input = Res.FSOpenResourceFile(template, RESOURCE_FORK_NAME, READ)
+    dummy, tmplowner = copyres(input, output, skiptypes, 1, progress)
+
+    Res.CloseResFile(input)
+##  if ownertype == None:
+##      raise BuildError, "No owner resource found in either resource file or template"
+    # Make sure we're manipulating the output resource file now
+
+    Res.UseResFile(output)
+
+    if ownertype == None:
+        # No owner resource in the template. We have skipped the
+        # Python owner resource, so we have to add our own. The relevant
+        # bundle stuff is already included in the interpret/applet template.
+        newres = Res.Resource('\0')
+        newres.AddResource(DEFAULT_APPLET_CREATOR, 0, "Owner resource")
+        ownertype = DEFAULT_APPLET_CREATOR
+
+    if code:
+        # Delete any existing 'PYC ' resource named __main__
+
+        try:
+            res = Res.Get1NamedResource(RESTYPE, RESNAME)
+            res.RemoveResource()
+        except Res.Error:
+            pass
+
+        # Create the raw data for the resource from the code object
+        if progress:
+            progress.label("Write PYC resource...")
+            progress.set(120)
+
+        data = marshal.dumps(code)
+        del code
+        data = (MAGIC + '\0\0\0\0') + data
+
+        # Create the resource and write it
+
+        id = 0
+        while id < 128:
+            id = Res.Unique1ID(RESTYPE)
+        res = Res.Resource(data)
+        res.AddResource(RESTYPE, id, RESNAME)
+        attrs = res.GetResAttrs()
+        attrs = attrs | 0x04    # set preload
+        res.SetResAttrs(attrs)
+        res.WriteResource()
+        res.ReleaseResource()
+
+    # Close the output file
+
+    Res.CloseResFile(output)
+
+    # Now set the creator, type and bundle bit of the destination.
+    # Done with FSSpec's, FSRef FInfo isn't good enough yet (2.3a1+)
+    dest_fss = Carbon.File.FSSpec(destname)
+    dest_finfo = dest_fss.FSpGetFInfo()
+    dest_finfo.Creator = ownertype
+    dest_finfo.Type = 'APPL'
+    dest_finfo.Flags = dest_finfo.Flags | Carbon.Files.kHasBundle | Carbon.Files.kIsShared
+    dest_finfo.Flags = dest_finfo.Flags & ~Carbon.Files.kHasBeenInited
+    dest_fss.FSpSetFInfo(dest_finfo)
+
+    macostools.touched(destname)
+    if progress:
+        progress.label("Done.")
+        progress.inc(0)
+
+def process_common_macho(template, progress, code, rsrcname, destname, is_update,
+        raw=0, others=[], filename=None, destroot=""):
+    # Check that we have a filename
+    if filename is None:
+        raise BuildError, "Need source filename on MacOSX"
+    # First make sure the name ends in ".app"
+    if destname[-4:] != '.app':
+        destname = destname + '.app'
+    # Now deduce the short name
+    destdir, shortname = os.path.split(destname)
+    if shortname[-4:] == '.app':
+        # Strip the .app suffix
+        shortname = shortname[:-4]
+    # And deduce the .plist and .icns names
+    plistname = None
+    icnsname = None
+    if rsrcname and rsrcname[-5:] == '.rsrc':
+        tmp = rsrcname[:-5]
+        plistname = tmp + '.plist'
+        if os.path.exists(plistname):
+            icnsname = tmp + '.icns'
+            if not os.path.exists(icnsname):
+                icnsname = None
+        else:
+            plistname = None
+    if not icnsname:
+        dft_icnsname = os.path.join(sys.prefix, 'Resources/Python.app/Contents/Resources/PythonApplet.icns')
+        if os.path.exists(dft_icnsname):
+            icnsname = dft_icnsname
+    if not os.path.exists(rsrcname):
+        rsrcname = None
+    if progress:
+        progress.label('Creating bundle...')
+    import bundlebuilder
+    builder = bundlebuilder.AppBuilder(verbosity=0)
+    builder.mainprogram = filename
+    builder.builddir = destdir
+    builder.name = shortname
+    builder.destroot = destroot
+    if rsrcname:
+        realrsrcname = macresource.resource_pathname(rsrcname)
+        builder.files.append((realrsrcname,
+            os.path.join('Contents/Resources', os.path.basename(rsrcname))))
+    for o in others:
+        if type(o) == str:
+            builder.resources.append(o)
+        else:
+            builder.files.append(o)
+    if plistname:
+        import plistlib
+        builder.plist = plistlib.Plist.fromFile(plistname)
+    if icnsname:
+        builder.iconfile = icnsname
+    if not raw:
+        builder.argv_emulation = 1
+    builder.setup()
+    builder.build()
+    if progress:
+        progress.label('Done.')
+        progress.inc(0)
+
+##  macostools.touched(dest_fss)
+
+# Copy resources between two resource file descriptors.
+# skip a resource named '__main__' or (if skipowner is set) with ID zero.
+# Also skip resources with a type listed in skiptypes.
+#
+def copyres(input, output, skiptypes, skipowner, progress=None):
+    ctor = None
+    alltypes = []
+    Res.UseResFile(input)
+    ntypes = Res.Count1Types()
+    progress_type_inc = 50/ntypes
+    for itype in range(1, 1+ntypes):
+        type = Res.Get1IndType(itype)
+        if type in skiptypes:
+            continue
+        alltypes.append(type)
+        nresources = Res.Count1Resources(type)
+        progress_cur_inc = progress_type_inc/nresources
+        for ires in range(1, 1+nresources):
+            res = Res.Get1IndResource(type, ires)
+            id, type, name = res.GetResInfo()
+            lcname = string.lower(name)
+
+            if lcname == OWNERNAME and id == 0:
+                if skipowner:
+                    continue # Skip this one
+                else:
+                    ctor = type
+            size = res.size
+            attrs = res.GetResAttrs()
+            if progress:
+                progress.label("Copy %s %d %s"%(type, id, name))
+                progress.inc(progress_cur_inc)
+            res.LoadResource()
+            res.DetachResource()
+            Res.UseResFile(output)
+            try:
+                res2 = Res.Get1Resource(type, id)
+            except MacOS.Error:
+                res2 = None
+            if res2:
+                if progress:
+                    progress.label("Overwrite %s %d %s"%(type, id, name))
+                    progress.inc(0)
+                res2.RemoveResource()
+            res.AddResource(type, id, name)
+            res.WriteResource()
+            attrs = attrs | res.GetResAttrs()
+            res.SetResAttrs(attrs)
+            Res.UseResFile(input)
+    return alltypes, ctor
+
+def copyapptree(srctree, dsttree, exceptlist=[], progress=None):
+    names = []
+    if os.path.exists(dsttree):
+        shutil.rmtree(dsttree)
+    os.mkdir(dsttree)
+    todo = os.listdir(srctree)
+    while todo:
+        this, todo = todo[0], todo[1:]
+        if this in exceptlist:
+            continue
+        thispath = os.path.join(srctree, this)
+        if os.path.isdir(thispath):
+            thiscontent = os.listdir(thispath)
+            for t in thiscontent:
+                todo.append(os.path.join(this, t))
+        names.append(this)
+    for this in names:
+        srcpath = os.path.join(srctree, this)
+        dstpath = os.path.join(dsttree, this)
+        if os.path.isdir(srcpath):
+            os.mkdir(dstpath)
+        elif os.path.islink(srcpath):
+            endpoint = os.readlink(srcpath)
+            os.symlink(endpoint, dstpath)
+        else:
+            if progress:
+                progress.label('Copy '+this)
+                progress.inc(0)
+            shutil.copy2(srcpath, dstpath)
+
+def writepycfile(codeobject, cfile):
+    import marshal
+    fc = open(cfile, 'wb')
+    fc.write('\0\0\0\0') # MAGIC placeholder, written later
+    fc.write('\0\0\0\0') # Timestap placeholder, not needed
+    marshal.dump(codeobject, fc)
+    fc.flush()
+    fc.seek(0, 0)
+    fc.write(MAGIC)
+    fc.close()

Added: vendor/Python/current/Lib/plat-mac/bundlebuilder.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/bundlebuilder.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/bundlebuilder.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,934 @@
+#! /usr/bin/env python
+
+"""\
+bundlebuilder.py -- Tools to assemble MacOS X (application) bundles.
+
+This module contains two classes to build so called "bundles" for
+MacOS X. BundleBuilder is a general tool, AppBuilder is a subclass
+specialized in building application bundles.
+
+[Bundle|App]Builder objects are instantiated with a bunch of keyword
+arguments, and have a build() method that will do all the work. See
+the class doc strings for a description of the constructor arguments.
+
+The module contains a main program that can be used in two ways:
+
+  % python bundlebuilder.py [options] build
+  % python buildapp.py [options] build
+
+Where "buildapp.py" is a user-supplied setup.py-like script following
+this model:
+
+  from bundlebuilder import buildapp
+  buildapp(<lots-of-keyword-args>)
+
+"""
+
+
+__all__ = ["BundleBuilder", "BundleBuilderError", "AppBuilder", "buildapp"]
+
+
+import sys
+import os, errno, shutil
+import imp, marshal
+import re
+from copy import deepcopy
+import getopt
+from plistlib import Plist
+from types import FunctionType as function
+
+class BundleBuilderError(Exception): pass
+
+
+class Defaults:
+
+    """Class attributes that don't start with an underscore and are
+    not functions or classmethods are (deep)copied to self.__dict__.
+    This allows for mutable default values.
+    """
+
+    def __init__(self, **kwargs):
+        defaults = self._getDefaults()
+        defaults.update(kwargs)
+        self.__dict__.update(defaults)
+
+    def _getDefaults(cls):
+        defaults = {}
+        for base in cls.__bases__:
+            if hasattr(base, "_getDefaults"):
+                defaults.update(base._getDefaults())
+        for name, value in cls.__dict__.items():
+            if name[0] != "_" and not isinstance(value,
+                    (function, classmethod)):
+                defaults[name] = deepcopy(value)
+        return defaults
+    _getDefaults = classmethod(_getDefaults)
+
+
+class BundleBuilder(Defaults):
+
+    """BundleBuilder is a barebones class for assembling bundles. It
+    knows nothing about executables or icons, it only copies files
+    and creates the PkgInfo and Info.plist files.
+    """
+
+    # (Note that Defaults.__init__ (deep)copies these values to
+    # instance variables. Mutable defaults are therefore safe.)
+
+    # Name of the bundle, with or without extension.
+    name = None
+
+    # The property list ("plist")
+    plist = Plist(CFBundleDevelopmentRegion = "English",
+                  CFBundleInfoDictionaryVersion = "6.0")
+
+    # The type of the bundle.
+    type = "BNDL"
+    # The creator code of the bundle.
+    creator = None
+
+    # the CFBundleIdentifier (this is used for the preferences file name)
+    bundle_id = None
+
+    # List of files that have to be copied to <bundle>/Contents/Resources.
+    resources = []
+
+    # List of (src, dest) tuples; dest should be a path relative to the bundle
+    # (eg. "Contents/Resources/MyStuff/SomeFile.ext).
+    files = []
+
+    # List of shared libraries (dylibs, Frameworks) to bundle with the app
+    # will be placed in Contents/Frameworks
+    libs = []
+
+    # Directory where the bundle will be assembled.
+    builddir = "build"
+
+    # Make symlinks instead copying files. This is handy during debugging, but
+    # makes the bundle non-distributable.
+    symlink = 0
+
+    # Verbosity level.
+    verbosity = 1
+
+    # Destination root directory
+    destroot = ""
+
+    def setup(self):
+        # XXX rethink self.name munging, this is brittle.
+        self.name, ext = os.path.splitext(self.name)
+        if not ext:
+            ext = ".bundle"
+        bundleextension = ext
+        # misc (derived) attributes
+        self.bundlepath = pathjoin(self.builddir, self.name + bundleextension)
+
+        plist = self.plist
+        plist.CFBundleName = self.name
+        plist.CFBundlePackageType = self.type
+        if self.creator is None:
+            if hasattr(plist, "CFBundleSignature"):
+                self.creator = plist.CFBundleSignature
+            else:
+                self.creator = "????"
+        plist.CFBundleSignature = self.creator
+        if self.bundle_id:
+            plist.CFBundleIdentifier = self.bundle_id
+        elif not hasattr(plist, "CFBundleIdentifier"):
+            plist.CFBundleIdentifier = self.name
+
+    def build(self):
+        """Build the bundle."""
+        builddir = self.builddir
+        if builddir and not os.path.exists(builddir):
+            os.mkdir(builddir)
+        self.message("Building %s" % repr(self.bundlepath), 1)
+        if os.path.exists(self.bundlepath):
+            shutil.rmtree(self.bundlepath)
+        if os.path.exists(self.bundlepath + '~'):
+            shutil.rmtree(self.bundlepath + '~')
+        bp = self.bundlepath
+
+        # Create the app bundle in a temporary location and then
+        # rename the completed bundle. This way the Finder will
+        # never see an incomplete bundle (where it might pick up
+        # and cache the wrong meta data)
+        self.bundlepath = bp + '~'
+        try:
+            os.mkdir(self.bundlepath)
+            self.preProcess()
+            self._copyFiles()
+            self._addMetaFiles()
+            self.postProcess()
+            os.rename(self.bundlepath, bp)
+        finally:
+            self.bundlepath = bp
+        self.message("Done.", 1)
+
+    def preProcess(self):
+        """Hook for subclasses."""
+        pass
+    def postProcess(self):
+        """Hook for subclasses."""
+        pass
+
+    def _addMetaFiles(self):
+        contents = pathjoin(self.bundlepath, "Contents")
+        makedirs(contents)
+        #
+        # Write Contents/PkgInfo
+        assert len(self.type) == len(self.creator) == 4, \
+                "type and creator must be 4-byte strings."
+        pkginfo = pathjoin(contents, "PkgInfo")
+        f = open(pkginfo, "wb")
+        f.write(self.type + self.creator)
+        f.close()
+        #
+        # Write Contents/Info.plist
+        infoplist = pathjoin(contents, "Info.plist")
+        self.plist.write(infoplist)
+
+    def _copyFiles(self):
+        files = self.files[:]
+        for path in self.resources:
+            files.append((path, pathjoin("Contents", "Resources",
+                os.path.basename(path))))
+        for path in self.libs:
+            files.append((path, pathjoin("Contents", "Frameworks",
+                os.path.basename(path))))
+        if self.symlink:
+            self.message("Making symbolic links", 1)
+            msg = "Making symlink from"
+        else:
+            self.message("Copying files", 1)
+            msg = "Copying"
+        files.sort()
+        for src, dst in files:
+            if os.path.isdir(src):
+                self.message("%s %s/ to %s/" % (msg, src, dst), 2)
+            else:
+                self.message("%s %s to %s" % (msg, src, dst), 2)
+            dst = pathjoin(self.bundlepath, dst)
+            if self.symlink:
+                symlink(src, dst, mkdirs=1)
+            else:
+                copy(src, dst, mkdirs=1)
+
+    def message(self, msg, level=0):
+        if level <= self.verbosity:
+            indent = ""
+            if level > 1:
+                indent = (level - 1) * "  "
+            sys.stderr.write(indent + msg + "\n")
+
+    def report(self):
+        # XXX something decent
+        pass
+
+
+if __debug__:
+    PYC_EXT = ".pyc"
+else:
+    PYC_EXT = ".pyo"
+
+MAGIC = imp.get_magic()
+USE_ZIPIMPORT = "zipimport" in sys.builtin_module_names
+
+# For standalone apps, we have our own minimal site.py. We don't need
+# all the cruft of the real site.py.
+SITE_PY = """\
+import sys
+if not %(semi_standalone)s:
+    del sys.path[1:]  # sys.path[0] is Contents/Resources/
+"""
+
+if USE_ZIPIMPORT:
+    ZIP_ARCHIVE = "Modules.zip"
+    SITE_PY += "sys.path.append(sys.path[0] + '/%s')\n" % ZIP_ARCHIVE
+    def getPycData(fullname, code, ispkg):
+        if ispkg:
+            fullname += ".__init__"
+        path = fullname.replace(".", os.sep) + PYC_EXT
+        return path, MAGIC + '\0\0\0\0' + marshal.dumps(code)
+
+#
+# Extension modules can't be in the modules zip archive, so a placeholder
+# is added instead, that loads the extension from a specified location.
+#
+EXT_LOADER = """\
+def __load():
+    import imp, sys, os
+    for p in sys.path:
+        path = os.path.join(p, "%(filename)s")
+        if os.path.exists(path):
+            break
+    else:
+        assert 0, "file not found: %(filename)s"
+    mod = imp.load_dynamic("%(name)s", path)
+
+__load()
+del __load
+"""
+
+MAYMISS_MODULES = ['mac', 'os2', 'nt', 'ntpath', 'dos', 'dospath',
+    'win32api', 'ce', '_winreg', 'nturl2path', 'sitecustomize',
+    'org.python.core', 'riscos', 'riscosenviron', 'riscospath'
+]
+
+STRIP_EXEC = "/usr/bin/strip"
+
+#
+# We're using a stock interpreter to run the app, yet we need
+# a way to pass the Python main program to the interpreter. The
+# bootstrapping script fires up the interpreter with the right
+# arguments. os.execve() is used as OSX doesn't like us to
+# start a real new process. Also, the executable name must match
+# the CFBundleExecutable value in the Info.plist, so we lie
+# deliberately with argv[0]. The actual Python executable is
+# passed in an environment variable so we can "repair"
+# sys.executable later.
+#
+BOOTSTRAP_SCRIPT = """\
+#!%(hashbang)s
+
+import sys, os
+execdir = os.path.dirname(sys.argv[0])
+executable = os.path.join(execdir, "%(executable)s")
+resdir = os.path.join(os.path.dirname(execdir), "Resources")
+libdir = os.path.join(os.path.dirname(execdir), "Frameworks")
+mainprogram = os.path.join(resdir, "%(mainprogram)s")
+
+sys.argv.insert(1, mainprogram)
+if %(standalone)s or %(semi_standalone)s:
+    os.environ["PYTHONPATH"] = resdir
+    if %(standalone)s:
+        os.environ["PYTHONHOME"] = resdir
+else:
+    pypath = os.getenv("PYTHONPATH", "")
+    if pypath:
+        pypath = ":" + pypath
+    os.environ["PYTHONPATH"] = resdir + pypath
+os.environ["PYTHONEXECUTABLE"] = executable
+os.environ["DYLD_LIBRARY_PATH"] = libdir
+os.environ["DYLD_FRAMEWORK_PATH"] = libdir
+os.execve(executable, sys.argv, os.environ)
+"""
+
+
+#
+# Optional wrapper that converts "dropped files" into sys.argv values.
+#
+ARGV_EMULATOR = """\
+import argvemulator, os
+
+argvemulator.ArgvCollector().mainloop()
+execfile(os.path.join(os.path.split(__file__)[0], "%(realmainprogram)s"))
+"""
+
+#
+# When building a standalone app with Python.framework, we need to copy
+# a subset from Python.framework to the bundle. The following list
+# specifies exactly what items we'll copy.
+#
+PYTHONFRAMEWORKGOODIES = [
+    "Python",  # the Python core library
+    "Resources/English.lproj",
+    "Resources/Info.plist",
+    "Resources/version.plist",
+]
+
+def isFramework():
+    return sys.exec_prefix.find("Python.framework") > 0
+
+
+LIB = os.path.join(sys.prefix, "lib", "python" + sys.version[:3])
+SITE_PACKAGES = os.path.join(LIB, "site-packages")
+
+
+class AppBuilder(BundleBuilder):
+
+    # Override type of the bundle.
+    type = "APPL"
+
+    # platform, name of the subfolder of Contents that contains the executable.
+    platform = "MacOS"
+
+    # A Python main program. If this argument is given, the main
+    # executable in the bundle will be a small wrapper that invokes
+    # the main program. (XXX Discuss why.)
+    mainprogram = None
+
+    # The main executable. If a Python main program is specified
+    # the executable will be copied to Resources and be invoked
+    # by the wrapper program mentioned above. Otherwise it will
+    # simply be used as the main executable.
+    executable = None
+
+    # The name of the main nib, for Cocoa apps. *Must* be specified
+    # when building a Cocoa app.
+    nibname = None
+
+    # The name of the icon file to be copied to Resources and used for
+    # the Finder icon.
+    iconfile = None
+
+    # Symlink the executable instead of copying it.
+    symlink_exec = 0
+
+    # If True, build standalone app.
+    standalone = 0
+
+    # If True, build semi-standalone app (only includes third-party modules).
+    semi_standalone = 0
+
+    # If set, use this for #! lines in stead of sys.executable
+    python = None
+
+    # If True, add a real main program that emulates sys.argv before calling
+    # mainprogram
+    argv_emulation = 0
+
+    # The following attributes are only used when building a standalone app.
+
+    # Exclude these modules.
+    excludeModules = []
+
+    # Include these modules.
+    includeModules = []
+
+    # Include these packages.
+    includePackages = []
+
+    # Strip binaries from debug info.
+    strip = 0
+
+    # Found Python modules: [(name, codeobject, ispkg), ...]
+    pymodules = []
+
+    # Modules that modulefinder couldn't find:
+    missingModules = []
+    maybeMissingModules = []
+
+    def setup(self):
+        if ((self.standalone or self.semi_standalone)
+            and self.mainprogram is None):
+            raise BundleBuilderError, ("must specify 'mainprogram' when "
+                    "building a standalone application.")
+        if self.mainprogram is None and self.executable is None:
+            raise BundleBuilderError, ("must specify either or both of "
+                    "'executable' and 'mainprogram'")
+
+        self.execdir = pathjoin("Contents", self.platform)
+
+        if self.name is not None:
+            pass
+        elif self.mainprogram is not None:
+            self.name = os.path.splitext(os.path.basename(self.mainprogram))[0]
+        elif executable is not None:
+            self.name = os.path.splitext(os.path.basename(self.executable))[0]
+        if self.name[-4:] != ".app":
+            self.name += ".app"
+
+        if self.executable is None:
+            if not self.standalone and not isFramework():
+                self.symlink_exec = 1
+            if self.python:
+                self.executable = self.python
+            else:
+                self.executable = sys.executable
+
+        if self.nibname:
+            self.plist.NSMainNibFile = self.nibname
+            if not hasattr(self.plist, "NSPrincipalClass"):
+                self.plist.NSPrincipalClass = "NSApplication"
+
+        if self.standalone and isFramework():
+            self.addPythonFramework()
+
+        BundleBuilder.setup(self)
+
+        self.plist.CFBundleExecutable = self.name
+
+        if self.standalone or self.semi_standalone:
+            self.findDependencies()
+
+    def preProcess(self):
+        resdir = "Contents/Resources"
+        if self.executable is not None:
+            if self.mainprogram is None:
+                execname = self.name
+            else:
+                execname = os.path.basename(self.executable)
+            execpath = pathjoin(self.execdir, execname)
+            if not self.symlink_exec:
+                self.files.append((self.destroot + self.executable, execpath))
+            self.execpath = execpath
+
+        if self.mainprogram is not None:
+            mainprogram = os.path.basename(self.mainprogram)
+            self.files.append((self.mainprogram, pathjoin(resdir, mainprogram)))
+            if self.argv_emulation:
+                # Change the main program, and create the helper main program (which
+                # does argv collection and then calls the real main).
+                # Also update the included modules (if we're creating a standalone
+                # program) and the plist
+                realmainprogram = mainprogram
+                mainprogram = '__argvemulator_' + mainprogram
+                resdirpath = pathjoin(self.bundlepath, resdir)
+                mainprogrampath = pathjoin(resdirpath, mainprogram)
+                makedirs(resdirpath)
+                open(mainprogrampath, "w").write(ARGV_EMULATOR % locals())
+                if self.standalone or self.semi_standalone:
+                    self.includeModules.append("argvemulator")
+                    self.includeModules.append("os")
+                if not self.plist.has_key("CFBundleDocumentTypes"):
+                    self.plist["CFBundleDocumentTypes"] = [
+                        { "CFBundleTypeOSTypes" : [
+                            "****",
+                            "fold",
+                            "disk"],
+                          "CFBundleTypeRole": "Viewer"}]
+            # Write bootstrap script
+            executable = os.path.basename(self.executable)
+            execdir = pathjoin(self.bundlepath, self.execdir)
+            bootstrappath = pathjoin(execdir, self.name)
+            makedirs(execdir)
+            if self.standalone or self.semi_standalone:
+                # XXX we're screwed when the end user has deleted
+                # /usr/bin/python
+                hashbang = "/usr/bin/python"
+            elif self.python:
+                hashbang = self.python
+            else:
+                hashbang = os.path.realpath(sys.executable)
+            standalone = self.standalone
+            semi_standalone = self.semi_standalone
+            open(bootstrappath, "w").write(BOOTSTRAP_SCRIPT % locals())
+            os.chmod(bootstrappath, 0775)
+
+        if self.iconfile is not None:
+            iconbase = os.path.basename(self.iconfile)
+            self.plist.CFBundleIconFile = iconbase
+            self.files.append((self.iconfile, pathjoin(resdir, iconbase)))
+
+    def postProcess(self):
+        if self.standalone or self.semi_standalone:
+            self.addPythonModules()
+        if self.strip and not self.symlink:
+            self.stripBinaries()
+
+        if self.symlink_exec and self.executable:
+            self.message("Symlinking executable %s to %s" % (self.executable,
+                    self.execpath), 2)
+            dst = pathjoin(self.bundlepath, self.execpath)
+            makedirs(os.path.dirname(dst))
+            os.symlink(os.path.abspath(self.executable), dst)
+
+        if self.missingModules or self.maybeMissingModules:
+            self.reportMissing()
+
+    def addPythonFramework(self):
+        # If we're building a standalone app with Python.framework,
+        # include a minimal subset of Python.framework, *unless*
+        # Python.framework was specified manually in self.libs.
+        for lib in self.libs:
+            if os.path.basename(lib) == "Python.framework":
+                # a Python.framework was specified as a library
+                return
+
+        frameworkpath = sys.exec_prefix[:sys.exec_prefix.find(
+            "Python.framework") + len("Python.framework")]
+
+        version = sys.version[:3]
+        frameworkpath = pathjoin(frameworkpath, "Versions", version)
+        destbase = pathjoin("Contents", "Frameworks", "Python.framework",
+                            "Versions", version)
+        for item in PYTHONFRAMEWORKGOODIES:
+            src = pathjoin(frameworkpath, item)
+            dst = pathjoin(destbase, item)
+            self.files.append((src, dst))
+
+    def _getSiteCode(self):
+        return compile(SITE_PY % {"semi_standalone": self.semi_standalone},
+                     "<-bundlebuilder.py->", "exec")
+
+    def addPythonModules(self):
+        self.message("Adding Python modules", 1)
+
+        if USE_ZIPIMPORT:
+            # Create a zip file containing all modules as pyc.
+            import zipfile
+            relpath = pathjoin("Contents", "Resources", ZIP_ARCHIVE)
+            abspath = pathjoin(self.bundlepath, relpath)
+            zf = zipfile.ZipFile(abspath, "w", zipfile.ZIP_DEFLATED)
+            for name, code, ispkg in self.pymodules:
+                self.message("Adding Python module %s" % name, 2)
+                path, pyc = getPycData(name, code, ispkg)
+                zf.writestr(path, pyc)
+            zf.close()
+            # add site.pyc
+            sitepath = pathjoin(self.bundlepath, "Contents", "Resources",
+                    "site" + PYC_EXT)
+            writePyc(self._getSiteCode(), sitepath)
+        else:
+            # Create individual .pyc files.
+            for name, code, ispkg in self.pymodules:
+                if ispkg:
+                    name += ".__init__"
+                path = name.split(".")
+                path = pathjoin("Contents", "Resources", *path) + PYC_EXT
+
+                if ispkg:
+                    self.message("Adding Python package %s" % path, 2)
+                else:
+                    self.message("Adding Python module %s" % path, 2)
+
+                abspath = pathjoin(self.bundlepath, path)
+                makedirs(os.path.dirname(abspath))
+                writePyc(code, abspath)
+
+    def stripBinaries(self):
+        if not os.path.exists(STRIP_EXEC):
+            self.message("Error: can't strip binaries: no strip program at "
+                "%s" % STRIP_EXEC, 0)
+        else:
+            import stat
+            self.message("Stripping binaries", 1)
+            def walk(top):
+                for name in os.listdir(top):
+                    path = pathjoin(top, name)
+                    if os.path.islink(path):
+                        continue
+                    if os.path.isdir(path):
+                        walk(path)
+                    else:
+                        mod = os.stat(path)[stat.ST_MODE]
+                        if not (mod & 0100):
+                            continue
+                        relpath = path[len(self.bundlepath):]
+                        self.message("Stripping %s" % relpath, 2)
+                        inf, outf = os.popen4("%s -S \"%s\"" %
+                                              (STRIP_EXEC, path))
+                        output = outf.read().strip()
+                        if output:
+                            # usually not a real problem, like when we're
+                            # trying to strip a script
+                            self.message("Problem stripping %s:" % relpath, 3)
+                            self.message(output, 3)
+            walk(self.bundlepath)
+
+    def findDependencies(self):
+        self.message("Finding module dependencies", 1)
+        import modulefinder
+        mf = modulefinder.ModuleFinder(excludes=self.excludeModules)
+        if USE_ZIPIMPORT:
+            # zipimport imports zlib, must add it manually
+            mf.import_hook("zlib")
+        # manually add our own site.py
+        site = mf.add_module("site")
+        site.__code__ = self._getSiteCode()
+        mf.scan_code(site.__code__, site)
+
+        # warnings.py gets imported implicitly from C
+        mf.import_hook("warnings")
+
+        includeModules = self.includeModules[:]
+        for name in self.includePackages:
+            includeModules.extend(findPackageContents(name).keys())
+        for name in includeModules:
+            try:
+                mf.import_hook(name)
+            except ImportError:
+                self.missingModules.append(name)
+
+        mf.run_script(self.mainprogram)
+        modules = mf.modules.items()
+        modules.sort()
+        for name, mod in modules:
+            path = mod.__file__
+            if path and self.semi_standalone:
+                # skip the standard library
+                if path.startswith(LIB) and not path.startswith(SITE_PACKAGES):
+                    continue
+            if path and mod.__code__ is None:
+                # C extension
+                filename = os.path.basename(path)
+                pathitems = name.split(".")[:-1] + [filename]
+                dstpath = pathjoin(*pathitems)
+                if USE_ZIPIMPORT:
+                    if name != "zlib":
+                        # neatly pack all extension modules in a subdirectory,
+                        # except zlib, since it's neccesary for bootstrapping.
+                        dstpath = pathjoin("ExtensionModules", dstpath)
+                    # Python modules are stored in a Zip archive, but put
+                    # extensions in Contents/Resources/. Add a tiny "loader"
+                    # program in the Zip archive. Due to Thomas Heller.
+                    source = EXT_LOADER % {"name": name, "filename": dstpath}
+                    code = compile(source, "<dynloader for %s>" % name, "exec")
+                    mod.__code__ = code
+                self.files.append((path, pathjoin("Contents", "Resources", dstpath)))
+            if mod.__code__ is not None:
+                ispkg = mod.__path__ is not None
+                if not USE_ZIPIMPORT or name != "site":
+                    # Our site.py is doing the bootstrapping, so we must
+                    # include a real .pyc file if USE_ZIPIMPORT is True.
+                    self.pymodules.append((name, mod.__code__, ispkg))
+
+        if hasattr(mf, "any_missing_maybe"):
+            missing, maybe = mf.any_missing_maybe()
+        else:
+            missing = mf.any_missing()
+            maybe = []
+        self.missingModules.extend(missing)
+        self.maybeMissingModules.extend(maybe)
+
+    def reportMissing(self):
+        missing = [name for name in self.missingModules
+                if name not in MAYMISS_MODULES]
+        if self.maybeMissingModules:
+            maybe = self.maybeMissingModules
+        else:
+            maybe = [name for name in missing if "." in name]
+            missing = [name for name in missing if "." not in name]
+        missing.sort()
+        maybe.sort()
+        if maybe:
+            self.message("Warning: couldn't find the following submodules:", 1)
+            self.message("    (Note that these could be false alarms -- "
+                         "it's not always", 1)
+            self.message("    possible to distinguish between \"from package "
+                         "import submodule\" ", 1)
+            self.message("    and \"from package import name\")", 1)
+            for name in maybe:
+                self.message("  ? " + name, 1)
+        if missing:
+            self.message("Warning: couldn't find the following modules:", 1)
+            for name in missing:
+                self.message("  ? " + name, 1)
+
+    def report(self):
+        # XXX something decent
+        import pprint
+        pprint.pprint(self.__dict__)
+        if self.standalone or self.semi_standalone:
+            self.reportMissing()
+
+#
+# Utilities.
+#
+
+SUFFIXES = [_suf for _suf, _mode, _tp in imp.get_suffixes()]
+identifierRE = re.compile(r"[_a-zA-z][_a-zA-Z0-9]*$")
+
+def findPackageContents(name, searchpath=None):
+    head = name.split(".")[-1]
+    if identifierRE.match(head) is None:
+        return {}
+    try:
+        fp, path, (ext, mode, tp) = imp.find_module(head, searchpath)
+    except ImportError:
+        return {}
+    modules = {name: None}
+    if tp == imp.PKG_DIRECTORY and path:
+        files = os.listdir(path)
+        for sub in files:
+            sub, ext = os.path.splitext(sub)
+            fullname = name + "." + sub
+            if sub != "__init__" and fullname not in modules:
+                modules.update(findPackageContents(fullname, [path]))
+    return modules
+
+def writePyc(code, path):
+    f = open(path, "wb")
+    f.write(MAGIC)
+    f.write("\0" * 4)  # don't bother about a time stamp
+    marshal.dump(code, f)
+    f.close()
+
+def copy(src, dst, mkdirs=0):
+    """Copy a file or a directory."""
+    if mkdirs:
+        makedirs(os.path.dirname(dst))
+    if os.path.isdir(src):
+        shutil.copytree(src, dst, symlinks=1)
+    else:
+        shutil.copy2(src, dst)
+
+def copytodir(src, dstdir):
+    """Copy a file or a directory to an existing directory."""
+    dst = pathjoin(dstdir, os.path.basename(src))
+    copy(src, dst)
+
+def makedirs(dir):
+    """Make all directories leading up to 'dir' including the leaf
+    directory. Don't moan if any path element already exists."""
+    try:
+        os.makedirs(dir)
+    except OSError, why:
+        if why.errno != errno.EEXIST:
+            raise
+
+def symlink(src, dst, mkdirs=0):
+    """Copy a file or a directory."""
+    if not os.path.exists(src):
+        raise IOError, "No such file or directory: '%s'" % src
+    if mkdirs:
+        makedirs(os.path.dirname(dst))
+    os.symlink(os.path.abspath(src), dst)
+
+def pathjoin(*args):
+    """Safe wrapper for os.path.join: asserts that all but the first
+    argument are relative paths."""
+    for seg in args[1:]:
+        assert seg[0] != "/"
+    return os.path.join(*args)
+
+
+cmdline_doc = """\
+Usage:
+  python bundlebuilder.py [options] command
+  python mybuildscript.py [options] command
+
+Commands:
+  build      build the application
+  report     print a report
+
+Options:
+  -b, --builddir=DIR     the build directory; defaults to "build"
+  -n, --name=NAME        application name
+  -r, --resource=FILE    extra file or folder to be copied to Resources
+  -f, --file=SRC:DST     extra file or folder to be copied into the bundle;
+                         DST must be a path relative to the bundle root
+  -e, --executable=FILE  the executable to be used
+  -m, --mainprogram=FILE the Python main program
+  -a, --argv             add a wrapper main program to create sys.argv
+  -p, --plist=FILE       .plist file (default: generate one)
+      --nib=NAME         main nib name
+  -c, --creator=CCCC     4-char creator code (default: '????')
+      --iconfile=FILE    filename of the icon (an .icns file) to be used
+                         as the Finder icon
+      --bundle-id=ID     the CFBundleIdentifier, in reverse-dns format
+                         (eg. org.python.BuildApplet; this is used for
+                         the preferences file name)
+  -l, --link             symlink files/folder instead of copying them
+      --link-exec        symlink the executable instead of copying it
+      --standalone       build a standalone application, which is fully
+                         independent of a Python installation
+      --semi-standalone  build a standalone application, which depends on
+                         an installed Python, yet includes all third-party
+                         modules.
+      --python=FILE      Python to use in #! line in stead of current Python
+      --lib=FILE         shared library or framework to be copied into
+                         the bundle
+  -x, --exclude=MODULE   exclude module (with --(semi-)standalone)
+  -i, --include=MODULE   include module (with --(semi-)standalone)
+      --package=PACKAGE  include a whole package (with --(semi-)standalone)
+      --strip            strip binaries (remove debug info)
+  -v, --verbose          increase verbosity level
+  -q, --quiet            decrease verbosity level
+  -h, --help             print this message
+"""
+
+def usage(msg=None):
+    if msg:
+        print msg
+    print cmdline_doc
+    sys.exit(1)
+
+def main(builder=None):
+    if builder is None:
+        builder = AppBuilder(verbosity=1)
+
+    shortopts = "b:n:r:f:e:m:c:p:lx:i:hvqa"
+    longopts = ("builddir=", "name=", "resource=", "file=", "executable=",
+        "mainprogram=", "creator=", "nib=", "plist=", "link",
+        "link-exec", "help", "verbose", "quiet", "argv", "standalone",
+        "exclude=", "include=", "package=", "strip", "iconfile=",
+        "lib=", "python=", "semi-standalone", "bundle-id=", "destroot=")
+
+    try:
+        options, args = getopt.getopt(sys.argv[1:], shortopts, longopts)
+    except getopt.error:
+        usage()
+
+    for opt, arg in options:
+        if opt in ('-b', '--builddir'):
+            builder.builddir = arg
+        elif opt in ('-n', '--name'):
+            builder.name = arg
+        elif opt in ('-r', '--resource'):
+            builder.resources.append(os.path.normpath(arg))
+        elif opt in ('-f', '--file'):
+            srcdst = arg.split(':')
+            if len(srcdst) != 2:
+                usage("-f or --file argument must be two paths, "
+                      "separated by a colon")
+            builder.files.append(srcdst)
+        elif opt in ('-e', '--executable'):
+            builder.executable = arg
+        elif opt in ('-m', '--mainprogram'):
+            builder.mainprogram = arg
+        elif opt in ('-a', '--argv'):
+            builder.argv_emulation = 1
+        elif opt in ('-c', '--creator'):
+            builder.creator = arg
+        elif opt == '--bundle-id':
+            builder.bundle_id = arg
+        elif opt == '--iconfile':
+            builder.iconfile = arg
+        elif opt == "--lib":
+            builder.libs.append(os.path.normpath(arg))
+        elif opt == "--nib":
+            builder.nibname = arg
+        elif opt in ('-p', '--plist'):
+            builder.plist = Plist.fromFile(arg)
+        elif opt in ('-l', '--link'):
+            builder.symlink = 1
+        elif opt == '--link-exec':
+            builder.symlink_exec = 1
+        elif opt in ('-h', '--help'):
+            usage()
+        elif opt in ('-v', '--verbose'):
+            builder.verbosity += 1
+        elif opt in ('-q', '--quiet'):
+            builder.verbosity -= 1
+        elif opt == '--standalone':
+            builder.standalone = 1
+        elif opt == '--semi-standalone':
+            builder.semi_standalone = 1
+        elif opt == '--python':
+            builder.python = arg
+        elif opt in ('-x', '--exclude'):
+            builder.excludeModules.append(arg)
+        elif opt in ('-i', '--include'):
+            builder.includeModules.append(arg)
+        elif opt == '--package':
+            builder.includePackages.append(arg)
+        elif opt == '--strip':
+            builder.strip = 1
+        elif opt == '--destroot':
+            builder.destroot = arg
+
+    if len(args) != 1:
+        usage("Must specify one command ('build', 'report' or 'help')")
+    command = args[0]
+
+    if command == "build":
+        builder.setup()
+        builder.build()
+    elif command == "report":
+        builder.setup()
+        builder.report()
+    elif command == "help":
+        usage()
+    else:
+        usage("Unknown command '%s'" % command)
+
+
+def buildapp(**kwargs):
+    builder = AppBuilder(**kwargs)
+    main(builder)
+
+
+if __name__ == "__main__":
+    main()


Property changes on: vendor/Python/current/Lib/plat-mac/bundlebuilder.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/plat-mac/cfmfile.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/cfmfile.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/cfmfile.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,183 @@
+"""codefragments.py -- wrapper to modify code fragments."""
+
+# (c) 1998, Just van Rossum, Letterror
+
+__version__ = "0.8b3"
+__author__ = "jvr"
+
+import Carbon.File
+import struct
+from Carbon import Res
+import os
+import sys
+
+DEBUG = 0
+
+error = "cfm.error"
+
+BUFSIZE = 0x80000
+
+def mergecfmfiles(srclist, dst, architecture = 'fat'):
+    """Merge all files in srclist into a new file dst.
+
+    If architecture is given, only code fragments of that type will be used:
+    "pwpc" for PPC, "m68k" for cfm68k. This does not work for "classic"
+    68k code, since it does not use code fragments to begin with.
+    If architecture is None, all fragments will be used, enabling FAT binaries.
+    """
+
+    srclist = list(srclist)
+    for i in range(len(srclist)):
+        srclist[i] = Carbon.File.pathname(srclist[i])
+    dst = Carbon.File.pathname(dst)
+
+    dstfile = open(dst, "wb")
+    rf = Res.FSpOpenResFile(dst, 3)
+    try:
+        dstcfrg = CfrgResource()
+        for src in srclist:
+            srccfrg = CfrgResource(src)
+            for frag in srccfrg.fragments:
+                if frag.architecture == 'pwpc' and architecture == 'm68k':
+                    continue
+                if frag.architecture == 'm68k' and architecture == 'pwpc':
+                    continue
+                dstcfrg.append(frag)
+
+                frag.copydata(dstfile)
+
+        cfrgres = Res.Resource(dstcfrg.build())
+        Res.UseResFile(rf)
+        cfrgres.AddResource('cfrg', 0, "")
+    finally:
+        dstfile.close()
+        rf = Res.CloseResFile(rf)
+
+
+class CfrgResource:
+
+    def __init__(self, path = None):
+        self.version = 1
+        self.fragments = []
+        self.path = path
+        if path is not None and os.path.exists(path):
+            currentresref = Res.CurResFile()
+            resref = Res.FSpOpenResFile(path, 1)
+            Res.UseResFile(resref)
+            try:
+                try:
+                    data = Res.Get1Resource('cfrg', 0).data
+                except Res.Error:
+                    raise Res.Error, "no 'cfrg' resource found", sys.exc_traceback
+            finally:
+                Res.CloseResFile(resref)
+                Res.UseResFile(currentresref)
+            self.parse(data)
+            if self.version <> 1:
+                raise error, "unknown 'cfrg' resource format"
+
+    def parse(self, data):
+        (res1, res2, self.version,
+            res3, res4, res5, res6,
+            self.memberCount) = struct.unpack("8l", data[:32])
+        data = data[32:]
+        while data:
+            frag = FragmentDescriptor(self.path, data)
+            data = data[frag.memberSize:]
+            self.fragments.append(frag)
+
+    def build(self):
+        self.memberCount = len(self.fragments)
+        data = struct.pack("8l", 0, 0, self.version, 0, 0, 0, 0, self.memberCount)
+        for frag in self.fragments:
+            data = data + frag.build()
+        return data
+
+    def append(self, frag):
+        self.fragments.append(frag)
+
+
+class FragmentDescriptor:
+
+    def __init__(self, path, data = None):
+        self.path = path
+        if data is not None:
+            self.parse(data)
+
+    def parse(self, data):
+        self.architecture = data[:4]
+        (   self.updatelevel,
+            self.currentVersion,
+            self.oldDefVersion,
+            self.stacksize,
+            self.applibdir,
+            self.fragtype,
+            self.where,
+            self.offset,
+            self.length,
+            self.res1, self.res2,
+            self.memberSize,) = struct.unpack("4lhBB4lh", data[4:42])
+        pname = data[42:self.memberSize]
+        self.name = pname[1:1+ord(pname[0])]
+
+    def build(self):
+        data = self.architecture
+        data = data + struct.pack("4lhBB4l",
+                self.updatelevel,
+                self.currentVersion,
+                self.oldDefVersion,
+                self.stacksize,
+                self.applibdir,
+                self.fragtype,
+                self.where,
+                self.offset,
+                self.length,
+                self.res1, self.res2)
+        self.memberSize = len(data) + 2 + 1 + len(self.name)
+        # pad to 4 byte boundaries
+        if self.memberSize % 4:
+            self.memberSize = self.memberSize + 4 - (self.memberSize % 4)
+        data = data + struct.pack("hb", self.memberSize, len(self.name))
+        data = data + self.name
+        data = data + '\000' * (self.memberSize - len(data))
+        return data
+
+    def getfragment(self):
+        if self.where <> 1:
+            raise error, "can't read fragment, unsupported location"
+        f = open(self.path, "rb")
+        f.seek(self.offset)
+        if self.length:
+            frag = f.read(self.length)
+        else:
+            frag = f.read()
+        f.close()
+        return frag
+
+    def copydata(self, outfile):
+        if self.where <> 1:
+            raise error, "can't read fragment, unsupported location"
+        infile = open(self.path, "rb")
+        if self.length == 0:
+            infile.seek(0, 2)
+            self.length = infile.tell()
+
+        # Position input file and record new offset from output file
+        infile.seek(self.offset)
+
+        # pad to 16 byte boundaries
+        offset = outfile.tell()
+        if offset % 16:
+            offset = offset + 16 - (offset % 16)
+        outfile.seek(offset)
+        self.offset = offset
+
+        l = self.length
+        while l:
+            if l > BUFSIZE:
+                outfile.write(infile.read(BUFSIZE))
+                l = l - BUFSIZE
+            else:
+                outfile.write(infile.read(l))
+                l = 0
+        infile.close()

Added: vendor/Python/current/Lib/plat-mac/dialogs.rsrc
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Lib/plat-mac/dialogs.rsrc
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Lib/plat-mac/errors.rsrc
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Lib/plat-mac/errors.rsrc
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Lib/plat-mac/findertools.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/findertools.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/findertools.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,831 @@
+"""Utility routines depending on the finder,
+a combination of code by Jack Jansen and erik at letterror.com.
+
+Most events have been captured from
+Lasso Capture AE and than translated to python code.
+
+IMPORTANT
+Note that the processes() function returns different values
+depending on the OS version it is running on. On MacOS 9
+the Finder returns the process *names* which can then be
+used to find out more about them. On MacOS 8.6 and earlier
+the Finder returns a code which does not seem to work.
+So bottom line: the processes() stuff does not work on < MacOS9
+
+Mostly written by erik at letterror.com
+"""
+import Finder
+from Carbon import AppleEvents
+import aetools
+import MacOS
+import sys
+import Carbon.File
+import Carbon.Folder
+import aetypes
+from types import *
+
+__version__ = '1.1'
+Error = 'findertools.Error'
+
+_finder_talker = None
+
+def _getfinder():
+    """returns basic (recyclable) Finder AE interface object"""
+    global _finder_talker
+    if not _finder_talker:
+        _finder_talker = Finder.Finder()
+    _finder_talker.send_flags = ( _finder_talker.send_flags |
+        AppleEvents.kAECanInteract | AppleEvents.kAECanSwitchLayer)
+    return _finder_talker
+
+def launch(file):
+    """Open a file thru the finder. Specify file by name or fsspec"""
+    finder = _getfinder()
+    fss = Carbon.File.FSSpec(file)
+    return finder.open(fss)
+
+def Print(file):
+    """Print a file thru the finder. Specify file by name or fsspec"""
+    finder = _getfinder()
+    fss = Carbon.File.FSSpec(file)
+    return finder._print(fss)
+
+def copy(src, dstdir):
+    """Copy a file to a folder"""
+    finder = _getfinder()
+    if type(src) == type([]):
+        src_fss = []
+        for s in src:
+            src_fss.append(Carbon.File.FSSpec(s))
+    else:
+        src_fss = Carbon.File.FSSpec(src)
+    dst_fss = Carbon.File.FSSpec(dstdir)
+    return finder.duplicate(src_fss, to=dst_fss)
+
+def move(src, dstdir):
+    """Move a file to a folder"""
+    finder = _getfinder()
+    if type(src) == type([]):
+        src_fss = []
+        for s in src:
+            src_fss.append(Carbon.File.FSSpec(s))
+    else:
+        src_fss = Carbon.File.FSSpec(src)
+    dst_fss = Carbon.File.FSSpec(dstdir)
+    return finder.move(src_fss, to=dst_fss)
+
+def sleep():
+    """Put the mac to sleep"""
+    finder = _getfinder()
+    finder.sleep()
+
+def shutdown():
+    """Shut the mac down"""
+    finder = _getfinder()
+    finder.shut_down()
+
+def restart():
+    """Restart the mac"""
+    finder = _getfinder()
+    finder.restart()
+
+
+#---------------------------------------------------
+#   Additional findertools
+#
+
+def reveal(file):
+    """Reveal a file in the finder. Specify file by name, fsref or fsspec."""
+    finder = _getfinder()
+    fsr = Carbon.File.FSRef(file)
+    file_alias = fsr.FSNewAliasMinimal()
+    return finder.reveal(file_alias)
+
+def select(file):
+    """select a file in the finder. Specify file by name, fsref or fsspec."""
+    finder = _getfinder()
+    fsr = Carbon.File.FSRef(file)
+    file_alias = fsr.FSNewAliasMinimal()
+    return finder.select(file_alias)
+
+def update(file):
+    """Update the display of the specified object(s) to match
+    their on-disk representation. Specify file by name, fsref or fsspec."""
+    finder = _getfinder()
+    fsr = Carbon.File.FSRef(file)
+    file_alias = fsr.FSNewAliasMinimal()
+    return finder.update(file_alias)
+
+
+#---------------------------------------------------
+#   More findertools
+#
+
+def comment(object, comment=None):
+    """comment: get or set the Finder-comment of the item, displayed in the 'Get Info' window."""
+    object = Carbon.File.FSRef(object)
+    object_alias = object.FSNewAliasMonimal()
+    if comment == None:
+        return _getcomment(object_alias)
+    else:
+        return _setcomment(object_alias, comment)
+
+def _setcomment(object_alias, comment):
+    finder = _getfinder()
+    args = {}
+    attrs = {}
+    aeobj_00 = aetypes.ObjectSpecifier(want=aetypes.Type('cobj'), form="alis", seld=object_alias, fr=None)
+    aeobj_01 = aetypes.ObjectSpecifier(want=aetypes.Type('prop'), form="prop", seld=aetypes.Type('comt'), fr=aeobj_00)
+    args['----'] = aeobj_01
+    args["data"] = comment
+    _reply, args, attrs = finder.send("core", "setd", args, attrs)
+    if args.has_key('errn'):
+        raise Error, aetools.decodeerror(args)
+    if args.has_key('----'):
+        return args['----']
+
+def _getcomment(object_alias):
+    finder = _getfinder()
+    args = {}
+    attrs = {}
+    aeobj_00 = aetypes.ObjectSpecifier(want=aetypes.Type('cobj'), form="alis", seld=object_alias, fr=None)
+    aeobj_01 = aetypes.ObjectSpecifier(want=aetypes.Type('prop'), form="prop", seld=aetypes.Type('comt'), fr=aeobj_00)
+    args['----'] = aeobj_01
+    _reply, args, attrs = finder.send("core", "getd", args, attrs)
+    if args.has_key('errn'):
+        raise Error, aetools.decodeerror(args)
+    if args.has_key('----'):
+        return args['----']
+
+
+#---------------------------------------------------
+#   Get information about current processes in the Finder.
+
+def processes():
+    """processes returns a list of all active processes running on this computer and their creators."""
+    finder = _getfinder()
+    args = {}
+    attrs = {}
+    processnames = []
+    processnumbers = []
+    creators = []
+    partitions = []
+    used = []
+    ## get the processnames or else the processnumbers
+    args['----'] = aetypes.ObjectSpecifier(want=aetypes.Type('prcs'), form="indx", seld=aetypes.Unknown('abso', "all "), fr=None)
+    _reply, args, attrs = finder.send('core', 'getd', args, attrs)
+    if args.has_key('errn'):
+        raise Error, aetools.decodeerror(args)
+    p = []
+    if args.has_key('----'):
+        p =  args['----']
+        for proc in p:
+            if hasattr(proc, 'seld'):
+                # it has a real name
+                processnames.append(proc.seld)
+            elif hasattr(proc, 'type'):
+                if proc.type == "psn ":
+                    # it has a process number
+                    processnumbers.append(proc.data)
+    ## get the creators
+    args = {}
+    attrs = {}
+    aeobj_0 = aetypes.ObjectSpecifier(want=aetypes.Type('prcs'), form="indx", seld=aetypes.Unknown('abso', "all "), fr=None)
+    args['----'] =  aetypes.ObjectSpecifier(want=aetypes.Type('prop'), form="prop", seld=aetypes.Type('fcrt'), fr=aeobj_0)
+    _reply, args, attrs = finder.send('core', 'getd', args, attrs)
+    if args.has_key('errn'):
+        raise Error, aetools.decodeerror(_arg)
+    if args.has_key('----'):
+        p =  args['----']
+        creators = p[:]
+    ## concatenate in one dict
+    result = []
+    if len(processnames) > len(processnumbers):
+        data = processnames
+    else:
+        data = processnumbers
+    for i in range(len(creators)):
+        result.append((data[i], creators[i]))
+    return result
+
+class _process:
+    pass
+
+def isactiveprocess(processname):
+    """Check of processname is active. MacOS9"""
+    all = processes()
+    ok = 0
+    for n, c in all:
+        if n == processname:
+            return 1
+    return 0
+
+def processinfo(processname):
+    """Return an object with all process properties as attributes for processname. MacOS9"""
+    p = _process()
+
+    if processname == "Finder":
+        p.partition = None
+        p.used = None
+    else:
+        p.partition = _processproperty(processname, 'appt')
+        p.used = _processproperty(processname, 'pusd')
+    p.visible = _processproperty(processname, 'pvis')       #Is the process' layer visible?
+    p.frontmost = _processproperty(processname, 'pisf') #Is the process the frontmost process?
+    p.file = _processproperty(processname, 'file')          #the file from which the process was launched
+    p.filetype  = _processproperty(processname, 'asty')     #the OSType of the file type of the process
+    p.creatortype = _processproperty(processname, 'fcrt')   #the OSType of the creator of the process (the signature)
+    p.accepthighlevel = _processproperty(processname, 'revt')   #Is the process high-level event aware (accepts open application, open document, print document, and quit)?
+    p.hasscripting = _processproperty(processname, 'hscr')      #Does the process have a scripting terminology, i.e., can it be scripted?
+    return p
+
+def _processproperty(processname, property):
+    """return the partition size and memory used for processname"""
+    finder = _getfinder()
+    args = {}
+    attrs = {}
+    aeobj_00 = aetypes.ObjectSpecifier(want=aetypes.Type('prcs'), form="name", seld=processname, fr=None)
+    aeobj_01 = aetypes.ObjectSpecifier(want=aetypes.Type('prop'), form="prop", seld=aetypes.Type(property), fr=aeobj_00)
+    args['----'] = aeobj_01
+    _reply, args, attrs = finder.send("core", "getd", args, attrs)
+    if args.has_key('errn'):
+        raise Error, aetools.decodeerror(args)
+    if args.has_key('----'):
+        return args['----']
+
+
+#---------------------------------------------------
+#   Mess around with Finder windows.
+
+def openwindow(object):
+    """Open a Finder window for object, Specify object by name or fsspec."""
+    finder = _getfinder()
+    object = Carbon.File.FSRef(object)
+    object_alias = object.FSNewAliasMinimal()
+    args = {}
+    attrs = {}
+    _code = 'aevt'
+    _subcode = 'odoc'
+    aeobj_0 = aetypes.ObjectSpecifier(want=aetypes.Type('cfol'), form="alis", seld=object_alias, fr=None)
+    args['----'] = aeobj_0
+    _reply, args, attrs = finder.send(_code, _subcode, args, attrs)
+    if args.has_key('errn'):
+        raise Error, aetools.decodeerror(args)
+
+def closewindow(object):
+    """Close a Finder window for folder, Specify by path."""
+    finder = _getfinder()
+    object = Carbon.File.FSRef(object)
+    object_alias = object.FSNewAliasMinimal()
+    args = {}
+    attrs = {}
+    _code = 'core'
+    _subcode = 'clos'
+    aeobj_0 = aetypes.ObjectSpecifier(want=aetypes.Type('cfol'), form="alis", seld=object_alias, fr=None)
+    args['----'] = aeobj_0
+    _reply, args, attrs = finder.send(_code, _subcode, args, attrs)
+    if args.has_key('errn'):
+        raise Error, aetools.decodeerror(args)
+
+def location(object, pos=None):
+    """Set the position of a Finder window for folder to pos=(w, h). Specify file by name or fsspec.
+    If pos=None, location will return the current position of the object."""
+    object = Carbon.File.FSRef(object)
+    object_alias = object.FSNewAliasMinimal()
+    if not pos:
+        return _getlocation(object_alias)
+    return _setlocation(object_alias, pos)
+
+def _setlocation(object_alias, (x, y)):
+    """_setlocation: Set the location of the icon for the object."""
+    finder = _getfinder()
+    args = {}
+    attrs = {}
+    aeobj_00 = aetypes.ObjectSpecifier(want=aetypes.Type('cfol'), form="alis", seld=object_alias, fr=None)
+    aeobj_01 = aetypes.ObjectSpecifier(want=aetypes.Type('prop'), form="prop", seld=aetypes.Type('posn'), fr=aeobj_00)
+    args['----'] = aeobj_01
+    args["data"] = [x, y]
+    _reply, args, attrs = finder.send("core", "setd", args, attrs)
+    if args.has_key('errn'):
+        raise Error, aetools.decodeerror(args)
+    return (x,y)
+
+def _getlocation(object_alias):
+    """_getlocation: get the location of the icon for the object."""
+    finder = _getfinder()
+    args = {}
+    attrs = {}
+    aeobj_00 = aetypes.ObjectSpecifier(want=aetypes.Type('cfol'), form="alis", seld=object_alias, fr=None)
+    aeobj_01 = aetypes.ObjectSpecifier(want=aetypes.Type('prop'), form="prop", seld=aetypes.Type('posn'), fr=aeobj_00)
+    args['----'] = aeobj_01
+    _reply, args, attrs = finder.send("core", "getd", args, attrs)
+    if args.has_key('errn'):
+        raise Error, aetools.decodeerror(args)
+    if args.has_key('----'):
+        pos = args['----']
+        return pos.h, pos.v
+
+def label(object, index=None):
+    """label: set or get the label of the item. Specify file by name or fsspec."""
+    object = Carbon.File.FSRef(object)
+    object_alias = object.FSNewAliasMinimal()
+    if index == None:
+        return _getlabel(object_alias)
+    if index < 0 or index > 7:
+        index = 0
+    return _setlabel(object_alias, index)
+
+def _getlabel(object_alias):
+    """label: Get the label for the object."""
+    finder = _getfinder()
+    args = {}
+    attrs = {}
+    aeobj_00 = aetypes.ObjectSpecifier(want=aetypes.Type('cobj'), form="alis", seld=object_alias, fr=None)
+    aeobj_01 = aetypes.ObjectSpecifier(want=aetypes.Type('prop'), form="prop", seld=aetypes.Type('labi'), fr=aeobj_00)
+    args['----'] = aeobj_01
+    _reply, args, attrs = finder.send("core", "getd", args, attrs)
+    if args.has_key('errn'):
+        raise Error, aetools.decodeerror(args)
+    if args.has_key('----'):
+        return args['----']
+
+def _setlabel(object_alias, index):
+    """label: Set the label for the object."""
+    finder = _getfinder()
+    args = {}
+    attrs = {}
+    _code = 'core'
+    _subcode = 'setd'
+    aeobj_0 = aetypes.ObjectSpecifier(want=aetypes.Type('prop'),
+            form="alis", seld=object_alias, fr=None)
+    aeobj_1 = aetypes.ObjectSpecifier(want=aetypes.Type('prop'),
+            form="prop", seld=aetypes.Type('labi'), fr=aeobj_0)
+    args['----'] = aeobj_1
+    args["data"] = index
+    _reply, args, attrs = finder.send(_code, _subcode, args, attrs)
+    if args.has_key('errn'):
+        raise Error, aetools.decodeerror(args)
+    return index
+
+def windowview(folder, view=None):
+    """windowview: Set the view of the window for the folder. Specify file by name or fsspec.
+    0 = by icon (default)
+    1 = by name
+    2 = by button
+    """
+    fsr = Carbon.File.FSRef(folder)
+    folder_alias = fsr.FSNewAliasMinimal()
+    if view == None:
+        return _getwindowview(folder_alias)
+    return _setwindowview(folder_alias, view)
+
+def _setwindowview(folder_alias, view=0):
+    """set the windowview"""
+    attrs = {}
+    args = {}
+    if view == 1:
+        _v = aetypes.Type('pnam')
+    elif view == 2:
+        _v = aetypes.Type('lgbu')
+    else:
+        _v = aetypes.Type('iimg')
+    finder = _getfinder()
+    aeobj_0 = aetypes.ObjectSpecifier(want = aetypes.Type('cfol'),
+            form = 'alis', seld = folder_alias, fr=None)
+    aeobj_1 = aetypes.ObjectSpecifier(want = aetypes.Type('prop'),
+            form = 'prop', seld = aetypes.Type('cwnd'), fr=aeobj_0)
+    aeobj_2 = aetypes.ObjectSpecifier(want = aetypes.Type('prop'),
+            form = 'prop', seld = aetypes.Type('pvew'), fr=aeobj_1)
+    aeobj_3 = aetypes.ObjectSpecifier(want = aetypes.Type('prop'),
+            form = 'prop', seld = _v, fr=None)
+    _code = 'core'
+    _subcode = 'setd'
+    args['----'] = aeobj_2
+    args['data'] = aeobj_3
+    _reply, args, attrs = finder.send(_code, _subcode, args, attrs)
+    if args.has_key('errn'):
+        raise Error, aetools.decodeerror(args)
+    if args.has_key('----'):
+        return args['----']
+
+def _getwindowview(folder_alias):
+    """get the windowview"""
+    attrs = {}
+    args = {}
+    finder = _getfinder()
+    args = {}
+    attrs = {}
+    aeobj_00 = aetypes.ObjectSpecifier(want=aetypes.Type('cfol'), form="alis", seld=folder_alias, fr=None)
+    aeobj_01 = aetypes.ObjectSpecifier(want=aetypes.Type('prop'), form="prop", seld=aetypes.Type('cwnd'), fr=aeobj_00)
+    aeobj_02 = aetypes.ObjectSpecifier(want=aetypes.Type('prop'), form="prop", seld=aetypes.Type('pvew'), fr=aeobj_01)
+    args['----'] = aeobj_02
+    _reply, args, attrs = finder.send("core", "getd", args, attrs)
+    if args.has_key('errn'):
+        raise Error, aetools.decodeerror(args)
+    views = {'iimg':0, 'pnam':1, 'lgbu':2}
+    if args.has_key('----'):
+        return views[args['----'].enum]
+
+def windowsize(folder, size=None):
+    """Set the size of a Finder window for folder to size=(w, h), Specify by path.
+    If size=None, windowsize will return the current size of the window.
+    Specify file by name or fsspec.
+    """
+    fsr = Carbon.File.FSRef(folder)
+    folder_alias = fsr.FSNewAliasMinimal()
+    openwindow(fsr)
+    if not size:
+        return _getwindowsize(folder_alias)
+    return _setwindowsize(folder_alias, size)
+
+def _setwindowsize(folder_alias, (w, h)):
+    """Set the size of a Finder window for folder to (w, h)"""
+    finder = _getfinder()
+    args = {}
+    attrs = {}
+    _code = 'core'
+    _subcode = 'setd'
+    aevar00 = [w, h]
+    aeobj_0 = aetypes.ObjectSpecifier(want=aetypes.Type('cfol'),
+            form="alis", seld=folder_alias, fr=None)
+    aeobj_1 = aetypes.ObjectSpecifier(want=aetypes.Type('prop'),
+            form="prop", seld=aetypes.Type('cwnd'), fr=aeobj_0)
+    aeobj_2 = aetypes.ObjectSpecifier(want=aetypes.Type('prop'),
+            form="prop", seld=aetypes.Type('ptsz'), fr=aeobj_1)
+    args['----'] = aeobj_2
+    args["data"] = aevar00
+    _reply, args, attrs = finder.send(_code, _subcode, args, attrs)
+    if args.has_key('errn'):
+        raise Error, aetools.decodeerror(args)
+    return (w, h)
+
+def _getwindowsize(folder_alias):
+    """Set the size of a Finder window for folder to (w, h)"""
+    finder = _getfinder()
+    args = {}
+    attrs = {}
+    aeobj_0 = aetypes.ObjectSpecifier(want=aetypes.Type('cfol'),
+            form="alis", seld=folder_alias, fr=None)
+    aeobj_1 = aetypes.ObjectSpecifier(want=aetypes.Type('prop'),
+            form="prop", seld=aetypes.Type('cwnd'), fr=aeobj_0)
+    aeobj_2 = aetypes.ObjectSpecifier(want=aetypes.Type('prop'),
+            form="prop", seld=aetypes.Type('posn'), fr=aeobj_1)
+    args['----'] = aeobj_2
+    _reply, args, attrs = finder.send('core', 'getd', args, attrs)
+    if args.has_key('errn'):
+        raise Error, aetools.decodeerror(args)
+    if args.has_key('----'):
+        return args['----']
+
+def windowposition(folder, pos=None):
+    """Set the position of a Finder window for folder to pos=(w, h)."""
+    fsr = Carbon.File.FSRef(folder)
+    folder_alias = fsr.FSNewAliasMinimal()
+    openwindow(fsr)
+    if not pos:
+        return _getwindowposition(folder_alias)
+    if type(pos) == InstanceType:
+        # pos might be a QDPoint object as returned by _getwindowposition
+        pos = (pos.h, pos.v)
+    return _setwindowposition(folder_alias, pos)
+
+def _setwindowposition(folder_alias, (x, y)):
+    """Set the size of a Finder window for folder to (w, h)."""
+    finder = _getfinder()
+    args = {}
+    attrs = {}
+    aeobj_0 = aetypes.ObjectSpecifier(want=aetypes.Type('cfol'),
+            form="alis", seld=folder_alias, fr=None)
+    aeobj_1 = aetypes.ObjectSpecifier(want=aetypes.Type('prop'),
+            form="prop", seld=aetypes.Type('cwnd'), fr=aeobj_0)
+    aeobj_2 = aetypes.ObjectSpecifier(want=aetypes.Type('prop'),
+            form="prop", seld=aetypes.Type('posn'), fr=aeobj_1)
+    args['----'] = aeobj_2
+    args["data"] = [x, y]
+    _reply, args, attrs = finder.send('core', 'setd', args, attrs)
+    if args.has_key('errn'):
+        raise Error, aetools.decodeerror(args)
+    if args.has_key('----'):
+        return args['----']
+
+def _getwindowposition(folder_alias):
+    """Get the size of a Finder window for folder, Specify by path."""
+    finder = _getfinder()
+    args = {}
+    attrs = {}
+    aeobj_0 = aetypes.ObjectSpecifier(want=aetypes.Type('cfol'),
+            form="alis", seld=folder_alias, fr=None)
+    aeobj_1 = aetypes.ObjectSpecifier(want=aetypes.Type('prop'),
+            form="prop", seld=aetypes.Type('cwnd'), fr=aeobj_0)
+    aeobj_2 = aetypes.ObjectSpecifier(want=aetypes.Type('prop'),
+            form="prop", seld=aetypes.Type('ptsz'), fr=aeobj_1)
+    args['----'] = aeobj_2
+    _reply, args, attrs = finder.send('core', 'getd', args, attrs)
+    if args.has_key('errn'):
+        raise Error, aetools.decodeerror(args)
+    if args.has_key('----'):
+        return args['----']
+
+def icon(object, icondata=None):
+    """icon sets the icon of object, if no icondata is given,
+    icon will return an AE object with binary data for the current icon.
+    If left untouched, this data can be used to paste the icon on another file.
+    Development opportunity: get and set the data as PICT."""
+    fsr = Carbon.File.FSRef(object)
+    object_alias = fsr.FSNewAliasMinimal()
+    if icondata == None:
+        return _geticon(object_alias)
+    return _seticon(object_alias, icondata)
+
+def _geticon(object_alias):
+    """get the icondata for object. Binary data of some sort."""
+    finder = _getfinder()
+    args = {}
+    attrs = {}
+    aeobj_00 = aetypes.ObjectSpecifier(want=aetypes.Type('cobj'),
+            form="alis", seld=object_alias, fr=None)
+    aeobj_01 = aetypes.ObjectSpecifier(want=aetypes.Type('prop'),
+            form="prop", seld=aetypes.Type('iimg'), fr=aeobj_00)
+    args['----'] = aeobj_01
+    _reply, args, attrs = finder.send("core", "getd", args, attrs)
+    if args.has_key('errn'):
+        raise Error, aetools.decodeerror(args)
+    if args.has_key('----'):
+        return args['----']
+
+def _seticon(object_alias, icondata):
+    """set the icondata for object, formatted as produced by _geticon()"""
+    finder = _getfinder()
+    args = {}
+    attrs = {}
+    aeobj_00 = aetypes.ObjectSpecifier(want=aetypes.Type('cobj'),
+            form="alis", seld=object_alias, fr=None)
+    aeobj_01 = aetypes.ObjectSpecifier(want=aetypes.Type('prop'),
+            form="prop", seld=aetypes.Type('iimg'), fr=aeobj_00)
+    args['----'] = aeobj_01
+    args["data"] = icondata
+    _reply, args, attrs = finder.send("core", "setd", args, attrs)
+    if args.has_key('errn'):
+        raise Error, aetools.decodeerror(args)
+    if args.has_key('----'):
+        return args['----'].data
+
+
+#---------------------------------------------------
+#   Volumes and servers.
+
+def mountvolume(volume, server=None, username=None, password=None):
+    """mount a volume, local or on a server on AppleTalk.
+    Note: mounting a ASIP server requires a different operation.
+    server is the name of the server where the volume belongs
+    username, password belong to a registered user of the volume."""
+    finder = _getfinder()
+    args = {}
+    attrs = {}
+    if password:
+        args["PASS"] = password
+    if username:
+        args["USER"] = username
+    if server:
+        args["SRVR"] = server
+    args['----'] = volume
+    _reply, args, attrs = finder.send("aevt", "mvol", args, attrs)
+    if args.has_key('errn'):
+        raise Error, aetools.decodeerror(args)
+    if args.has_key('----'):
+        return args['----']
+
+def unmountvolume(volume):
+    """unmount a volume that's on the desktop"""
+    putaway(volume)
+
+def putaway(object):
+    """puth the object away, whereever it came from."""
+    finder = _getfinder()
+    args = {}
+    attrs = {}
+    args['----'] = aetypes.ObjectSpecifier(want=aetypes.Type('cdis'), form="name", seld=object, fr=None)
+    _reply, args, attrs = talker.send("fndr", "ptwy", args, attrs)
+    if args.has_key('errn'):
+        raise Error, aetools.decodeerror(args)
+    if args.has_key('----'):
+        return args['----']
+
+
+#---------------------------------------------------
+#   Miscellaneous functions
+#
+
+def volumelevel(level):
+    """set the audio output level, parameter between 0 (silent) and 7 (full blast)"""
+    finder = _getfinder()
+    args = {}
+    attrs = {}
+    if level < 0:
+        level = 0
+    elif level > 7:
+        level = 7
+    args['----'] = level
+    _reply, args, attrs = finder.send("aevt", "stvl", args, attrs)
+    if args.has_key('errn'):
+        raise Error, aetools.decodeerror(args)
+    if args.has_key('----'):
+        return args['----']
+
+def OSversion():
+    """return the version of the system software"""
+    finder = _getfinder()
+    args = {}
+    attrs = {}
+    aeobj_00 = aetypes.ObjectSpecifier(want=aetypes.Type('prop'), form="prop", seld=aetypes.Type('ver2'), fr=None)
+    args['----'] = aeobj_00
+    _reply, args, attrs = finder.send("core", "getd", args, attrs)
+    if args.has_key('errn'):
+        raise Error, aetools.decodeerror(args)
+    if args.has_key('----'):
+        return args['----']
+
+def filesharing():
+    """return the current status of filesharing and whether it is starting up or not:
+        -1  file sharing is off and not starting up
+        0   file sharing is off and starting up
+        1   file sharing is on"""
+    status = -1
+    finder = _getfinder()
+    # see if it is on
+    args = {}
+    attrs = {}
+    args['----'] = aetypes.ObjectSpecifier(want=aetypes.Type('prop'), form="prop", seld=aetypes.Type('fshr'), fr=None)
+    _reply, args, attrs = finder.send("core", "getd", args, attrs)
+    if args.has_key('errn'):
+        raise Error, aetools.decodeerror(args)
+    if args.has_key('----'):
+        if args['----'] == 0:
+            status = -1
+        else:
+            status = 1
+    # is it starting up perchance?
+    args = {}
+    attrs = {}
+    args['----'] = aetypes.ObjectSpecifier(want=aetypes.Type('prop'), form="prop", seld=aetypes.Type('fsup'), fr=None)
+    _reply, args, attrs = finder.send("core", "getd", args, attrs)
+    if args.has_key('errn'):
+        raise Error, aetools.decodeerror(args)
+    if args.has_key('----'):
+        if args['----'] == 1:
+            status = 0
+    return status
+
+def movetotrash(path):
+    """move the object to the trash"""
+    fss = Carbon.File.FSSpec(path)
+    trashfolder = Carbon.Folder.FSFindFolder(fss.as_tuple()[0], 'trsh', 0)
+    move(path, trashfolder)
+
+def emptytrash():
+    """empty the trash"""
+    finder = _getfinder()
+    args = {}
+    attrs = {}
+    args['----'] = aetypes.ObjectSpecifier(want=aetypes.Type('prop'), form="prop", seld=aetypes.Type('trsh'), fr=None)
+    _reply, args, attrs = finder.send("fndr", "empt", args, attrs)
+    if args.has_key('errn'):
+        raise aetools.Error, aetools.decodeerror(args)
+
+
+def _test():
+    import EasyDialogs
+    print 'Original findertools functionality test...'
+    print 'Testing launch...'
+    pathname = EasyDialogs.AskFileForOpen('File to launch:')
+    if pathname:
+        result = launch(pathname)
+        if result:
+            print 'Result: ', result
+        print 'Press return-',
+        sys.stdin.readline()
+    print 'Testing print...'
+    pathname = EasyDialogs.AskFileForOpen('File to print:')
+    if pathname:
+        result = Print(pathname)
+        if result:
+            print 'Result: ', result
+        print 'Press return-',
+        sys.stdin.readline()
+    print 'Testing copy...'
+    pathname = EasyDialogs.AskFileForOpen('File to copy:')
+    if pathname:
+        destdir = EasyDialogs.AskFolder('Destination:')
+        if destdir:
+            result = copy(pathname, destdir)
+            if result:
+                print 'Result:', result
+            print 'Press return-',
+            sys.stdin.readline()
+    print 'Testing move...'
+    pathname = EasyDialogs.AskFileForOpen('File to move:')
+    if pathname:
+        destdir = EasyDialogs.AskFolder('Destination:')
+        if destdir:
+            result = move(pathname, destdir)
+            if result:
+                print 'Result:', result
+            print 'Press return-',
+            sys.stdin.readline()
+    print 'Testing sleep...'
+    if EasyDialogs.AskYesNoCancel('Sleep?') > 0:
+        result = sleep()
+        if result:
+            print 'Result:', result
+        print 'Press return-',
+        sys.stdin.readline()
+    print 'Testing shutdown...'
+    if EasyDialogs.AskYesNoCancel('Shut down?') > 0:
+        result = shutdown()
+        if result:
+            print 'Result:', result
+        print 'Press return-',
+        sys.stdin.readline()
+    print 'Testing restart...'
+    if EasyDialogs.AskYesNoCancel('Restart?') > 0:
+        result = restart()
+        if result:
+            print 'Result:', result
+        print 'Press return-',
+        sys.stdin.readline()
+
+def _test2():
+    print '\nmorefindertools version %s\nTests coming up...' %__version__
+    import os
+    import random
+
+    # miscellaneous
+    print '\tfilesharing on?',  filesharing()       # is file sharing on, off, starting up?
+    print '\tOS version',       OSversion()     # the version of the system software
+
+    # set the soundvolume in a simple way
+    print '\tSystem beep volume'
+    for i in range(0, 7):
+        volumelevel(i)
+        MacOS.SysBeep()
+
+    # Finder's windows, file location, file attributes
+    open("@findertoolstest", "w")
+    f = "@findertoolstest"
+    reveal(f)               # reveal this file in a Finder window
+    select(f)               # select this file
+
+    base, file = os.path.split(f)
+    closewindow(base)   # close the window this file is in  (opened by reveal)
+    openwindow(base)        # open it again
+    windowview(base, 1) # set the view by list
+
+    label(f, 2)             # set the label of this file to something orange
+    print '\tlabel', label(f)   # get the label of this file
+
+    # the file location only works in a window with icon view!
+    print 'Random locations for an icon'
+    windowview(base, 0)     # set the view by icon
+    windowsize(base, (600, 600))
+    for i in range(50):
+        location(f, (random.randint(10, 590), random.randint(10, 590)))
+
+    windowsize(base, (200, 400))
+    windowview(base, 1)     # set the view by icon
+
+    orgpos = windowposition(base)
+    print 'Animated window location'
+    for i in range(10):
+        pos = (100+i*10, 100+i*10)
+        windowposition(base, pos)
+        print '\twindow position', pos
+    windowposition(base, orgpos)    # park it where it was before
+
+    print 'Put a comment in file', f, ':'
+    print '\t', comment(f)      # print the Finder comment this file has
+    s = 'This is a comment no one reads!'
+    comment(f, s)           # set the Finder comment
+
+def _test3():
+    print 'MacOS9 or better specific functions'
+    # processes
+    pr = processes()        # return a list of tuples with (active_processname, creatorcode)
+    print 'Return a list of current active processes:'
+    for p in pr:
+        print '\t', p
+
+    # get attributes of the first process in the list
+    print 'Attributes of the first process in the list:'
+    pinfo = processinfo(pr[0][0])
+    print '\t', pr[0][0]
+    print '\t\tmemory partition', pinfo.partition       # the memory allocated to this process
+    print '\t\tmemory used', pinfo.used         # the memory actuall used by this process
+    print '\t\tis visible', pinfo.visible           # is the process visible to the user
+    print '\t\tis frontmost', pinfo.frontmost       # is the process the front most one?
+    print '\t\thas scripting', pinfo.hasscripting       # is the process scriptable?
+    print '\t\taccepts high level events',  pinfo.accepthighlevel   # does the process accept high level appleevents?
+
+if __name__ == '__main__':
+    _test()
+    _test2()
+    _test3()

Added: vendor/Python/current/Lib/plat-mac/gensuitemodule.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/gensuitemodule.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/gensuitemodule.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1213 @@
+"""
+gensuitemodule - Generate an AE suite module from an aete/aeut resource
+
+Based on aete.py.
+
+Reading and understanding this code is left as an exercise to the reader.
+"""
+
+import MacOS
+import EasyDialogs
+import os
+import string
+import sys
+import types
+import StringIO
+import keyword
+import macresource
+import aetools
+import distutils.sysconfig
+import OSATerminology
+from Carbon.Res import *
+import Carbon.Folder
+import MacOS
+import getopt
+import plistlib
+
+_MAC_LIB_FOLDER=os.path.dirname(aetools.__file__)
+DEFAULT_STANDARD_PACKAGEFOLDER=os.path.join(_MAC_LIB_FOLDER, 'lib-scriptpackages')
+DEFAULT_USER_PACKAGEFOLDER=distutils.sysconfig.get_python_lib()
+
+def usage():
+    sys.stderr.write("Usage: %s [opts] application-or-resource-file\n" % sys.argv[0])
+    sys.stderr.write("""Options:
+--output pkgdir  Pathname of the output package (short: -o)
+--resource       Parse resource file in stead of launching application (-r)
+--base package   Use another base package in stead of default StdSuites (-b)
+--edit old=new   Edit suite names, use empty new to skip a suite (-e)
+--creator code   Set creator code for package (-c)
+--dump           Dump aete resource to stdout in stead of creating module (-d)
+--verbose        Tell us what happens (-v)
+""")
+    sys.exit(1)
+
+def main():
+    if len(sys.argv) > 1:
+        SHORTOPTS = "rb:o:e:c:dv"
+        LONGOPTS = ("resource", "base=", "output=", "edit=", "creator=", "dump", "verbose")
+        try:
+            opts, args = getopt.getopt(sys.argv[1:], SHORTOPTS, LONGOPTS)
+        except getopt.GetoptError:
+            usage()
+
+        process_func = processfile
+        basepkgname = 'StdSuites'
+        output = None
+        edit_modnames = []
+        creatorsignature = None
+        dump = None
+        verbose = None
+
+        for o, a in opts:
+            if o in ('-r', '--resource'):
+                process_func = processfile_fromresource
+            if o in ('-b', '--base'):
+                basepkgname = a
+            if o in ('-o', '--output'):
+                output = a
+            if o in ('-e', '--edit'):
+                split = a.split('=')
+                if len(split) != 2:
+                    usage()
+                edit_modnames.append(split)
+            if o in ('-c', '--creator'):
+                if len(a) != 4:
+                    sys.stderr.write("creator must be 4-char string\n")
+                    sys.exit(1)
+                creatorsignature = a
+            if o in ('-d', '--dump'):
+                dump = sys.stdout
+            if o in ('-v', '--verbose'):
+                verbose = sys.stderr
+
+
+        if output and len(args) > 1:
+            sys.stderr.write("%s: cannot specify --output with multiple inputs\n" % sys.argv[0])
+            sys.exit(1)
+
+        for filename in args:
+            process_func(filename, output=output, basepkgname=basepkgname,
+                edit_modnames=edit_modnames, creatorsignature=creatorsignature,
+                dump=dump, verbose=verbose)
+    else:
+        main_interactive()
+
+def main_interactive(interact=0, basepkgname='StdSuites'):
+    if interact:
+        # Ask for save-filename for each module
+        edit_modnames = None
+    else:
+        # Use default filenames for each module
+        edit_modnames = []
+    appsfolder = Carbon.Folder.FSFindFolder(-32765, 'apps', 0)
+    filename = EasyDialogs.AskFileForOpen(
+        message='Select scriptable application',
+        dialogOptionFlags=0x1056,       # allow selection of .app bundles
+        defaultLocation=appsfolder)
+    if not filename:
+        return
+    if not is_scriptable(filename):
+        if EasyDialogs.AskYesNoCancel(
+                "Warning: application does not seem scriptable",
+                yes="Continue", default=2, no="") <= 0:
+            return
+    try:
+        processfile(filename, edit_modnames=edit_modnames, basepkgname=basepkgname,
+        verbose=sys.stderr)
+    except MacOS.Error, arg:
+        print "Error getting terminology:", arg
+        print "Retry, manually parsing resources"
+        processfile_fromresource(filename, edit_modnames=edit_modnames,
+            basepkgname=basepkgname, verbose=sys.stderr)
+
+def is_scriptable(application):
+    """Return true if the application is scriptable"""
+    if os.path.isdir(application):
+        plistfile = os.path.join(application, 'Contents', 'Info.plist')
+        if not os.path.exists(plistfile):
+            return False
+        plist = plistlib.Plist.fromFile(plistfile)
+        return plist.get('NSAppleScriptEnabled', False)
+    # If it is a file test for an aete/aeut resource.
+    currf = CurResFile()
+    try:
+        refno = macresource.open_pathname(application)
+    except MacOS.Error:
+        return False
+    UseResFile(refno)
+    n_terminology = Count1Resources('aete') + Count1Resources('aeut') + \
+        Count1Resources('scsz') + Count1Resources('osiz')
+    CloseResFile(refno)
+    UseResFile(currf)
+    return n_terminology > 0
+
+def processfile_fromresource(fullname, output=None, basepkgname=None,
+        edit_modnames=None, creatorsignature=None, dump=None, verbose=None):
+    """Process all resources in a single file"""
+    if not is_scriptable(fullname) and verbose:
+        print >>verbose, "Warning: app does not seem scriptable: %s" % fullname
+    cur = CurResFile()
+    if verbose:
+        print >>verbose, "Processing", fullname
+    rf = macresource.open_pathname(fullname)
+    try:
+        UseResFile(rf)
+        resources = []
+        for i in range(Count1Resources('aete')):
+            res = Get1IndResource('aete', 1+i)
+            resources.append(res)
+        for i in range(Count1Resources('aeut')):
+            res = Get1IndResource('aeut', 1+i)
+            resources.append(res)
+        if verbose:
+            print >>verbose, "\nLISTING aete+aeut RESOURCES IN", repr(fullname)
+        aetelist = []
+        for res in resources:
+            if verbose:
+                print >>verbose, "decoding", res.GetResInfo(), "..."
+            data = res.data
+            aete = decode(data, verbose)
+            aetelist.append((aete, res.GetResInfo()))
+    finally:
+        if rf <> cur:
+            CloseResFile(rf)
+            UseResFile(cur)
+    # switch back (needed for dialogs in Python)
+    UseResFile(cur)
+    if dump:
+        dumpaetelist(aetelist, dump)
+    compileaetelist(aetelist, fullname, output=output,
+        basepkgname=basepkgname, edit_modnames=edit_modnames,
+        creatorsignature=creatorsignature, verbose=verbose)
+
+def processfile(fullname, output=None, basepkgname=None,
+        edit_modnames=None, creatorsignature=None, dump=None,
+        verbose=None):
+    """Ask an application for its terminology and process that"""
+    if not is_scriptable(fullname) and verbose:
+        print >>verbose, "Warning: app does not seem scriptable: %s" % fullname
+    if verbose:
+        print >>verbose, "\nASKING FOR aete DICTIONARY IN", repr(fullname)
+    try:
+        aedescobj, launched = OSATerminology.GetAppTerminology(fullname)
+    except MacOS.Error, arg:
+        if arg[0] in (-1701, -192): # errAEDescNotFound, resNotFound
+            if verbose:
+                print >>verbose, "GetAppTerminology failed with errAEDescNotFound/resNotFound, trying manually"
+            aedata, sig = getappterminology(fullname, verbose=verbose)
+            if not creatorsignature:
+                creatorsignature = sig
+        else:
+            raise
+    else:
+        if launched:
+            if verbose:
+                print >>verbose, "Launched", fullname
+        raw = aetools.unpack(aedescobj)
+        if not raw:
+            if verbose:
+                print >>verbose, 'Unpack returned empty value:', raw
+            return
+        if not raw[0].data:
+            if verbose:
+                print >>verbose, 'Unpack returned value without data:', raw
+            return
+        aedata = raw[0]
+    aete = decode(aedata.data, verbose)
+    if dump:
+        dumpaetelist([aete], dump)
+        return
+    compileaete(aete, None, fullname, output=output, basepkgname=basepkgname,
+        creatorsignature=creatorsignature, edit_modnames=edit_modnames,
+        verbose=verbose)
+
+def getappterminology(fullname, verbose=None):
+    """Get application terminology by sending an AppleEvent"""
+    # First check that we actually can send AppleEvents
+    if not MacOS.WMAvailable():
+        raise RuntimeError, "Cannot send AppleEvents, no access to window manager"
+    # Next, a workaround for a bug in MacOS 10.2: sending events will hang unless
+    # you have created an event loop first.
+    import Carbon.Evt
+    Carbon.Evt.WaitNextEvent(0,0)
+    if os.path.isdir(fullname):
+        # Now get the signature of the application, hoping it is a bundle
+        pkginfo = os.path.join(fullname, 'Contents', 'PkgInfo')
+        if not os.path.exists(pkginfo):
+            raise RuntimeError, "No PkgInfo file found"
+        tp_cr = open(pkginfo, 'rb').read()
+        cr = tp_cr[4:8]
+    else:
+        # Assume it is a file
+        cr, tp = MacOS.GetCreatorAndType(fullname)
+    # Let's talk to it and ask for its AETE
+    talker = aetools.TalkTo(cr)
+    try:
+        talker._start()
+    except (MacOS.Error, aetools.Error), arg:
+        if verbose:
+            print >>verbose, 'Warning: start() failed, continuing anyway:', arg
+    reply = talker.send("ascr", "gdte")
+    #reply2 = talker.send("ascr", "gdut")
+    # Now pick the bits out of the return that we need.
+    return reply[1]['----'], cr
+
+
+def compileaetelist(aetelist, fullname, output=None, basepkgname=None,
+            edit_modnames=None, creatorsignature=None, verbose=None):
+    for aete, resinfo in aetelist:
+        compileaete(aete, resinfo, fullname, output=output,
+            basepkgname=basepkgname, edit_modnames=edit_modnames,
+            creatorsignature=creatorsignature, verbose=verbose)
+
+def dumpaetelist(aetelist, output):
+    import pprint
+    pprint.pprint(aetelist, output)
+
+def decode(data, verbose=None):
+    """Decode a resource into a python data structure"""
+    f = StringIO.StringIO(data)
+    aete = generic(getaete, f)
+    aete = simplify(aete)
+    processed = f.tell()
+    unprocessed = len(f.read())
+    total = f.tell()
+    if unprocessed and verbose:
+        verbose.write("%d processed + %d unprocessed = %d total\n" %
+                         (processed, unprocessed, total))
+    return aete
+
+def simplify(item):
+    """Recursively replace singleton tuples by their constituent item"""
+    if type(item) is types.ListType:
+        return map(simplify, item)
+    elif type(item) == types.TupleType and len(item) == 2:
+        return simplify(item[1])
+    else:
+        return item
+
+
+# Here follows the aete resource decoder.
+# It is presented bottom-up instead of top-down because there are  direct
+# references to the lower-level part-decoders from the high-level part-decoders.
+
+def getbyte(f, *args):
+    c = f.read(1)
+    if not c:
+        raise EOFError, 'in getbyte' + str(args)
+    return ord(c)
+
+def getword(f, *args):
+    getalign(f)
+    s = f.read(2)
+    if len(s) < 2:
+        raise EOFError, 'in getword' + str(args)
+    return (ord(s[0])<<8) | ord(s[1])
+
+def getlong(f, *args):
+    getalign(f)
+    s = f.read(4)
+    if len(s) < 4:
+        raise EOFError, 'in getlong' + str(args)
+    return (ord(s[0])<<24) | (ord(s[1])<<16) | (ord(s[2])<<8) | ord(s[3])
+
+def getostype(f, *args):
+    getalign(f)
+    s = f.read(4)
+    if len(s) < 4:
+        raise EOFError, 'in getostype' + str(args)
+    return s
+
+def getpstr(f, *args):
+    c = f.read(1)
+    if len(c) < 1:
+        raise EOFError, 'in getpstr[1]' + str(args)
+    nbytes = ord(c)
+    if nbytes == 0: return ''
+    s = f.read(nbytes)
+    if len(s) < nbytes:
+        raise EOFError, 'in getpstr[2]' + str(args)
+    return s
+
+def getalign(f):
+    if f.tell() & 1:
+        c = f.read(1)
+        ##if c <> '\0':
+        ##  print align:', repr(c)
+
+def getlist(f, description, getitem):
+    count = getword(f)
+    list = []
+    for i in range(count):
+        list.append(generic(getitem, f))
+        getalign(f)
+    return list
+
+def alt_generic(what, f, *args):
+    print "generic", repr(what), args
+    res = vageneric(what, f, args)
+    print '->', repr(res)
+    return res
+
+def generic(what, f, *args):
+    if type(what) == types.FunctionType:
+        return apply(what, (f,) + args)
+    if type(what) == types.ListType:
+        record = []
+        for thing in what:
+            item = apply(generic, thing[:1] + (f,) + thing[1:])
+            record.append((thing[1], item))
+        return record
+    return "BAD GENERIC ARGS: %r" % (what,)
+
+getdata = [
+    (getostype, "type"),
+    (getpstr, "description"),
+    (getword, "flags")
+    ]
+getargument = [
+    (getpstr, "name"),
+    (getostype, "keyword"),
+    (getdata, "what")
+    ]
+getevent = [
+    (getpstr, "name"),
+    (getpstr, "description"),
+    (getostype, "suite code"),
+    (getostype, "event code"),
+    (getdata, "returns"),
+    (getdata, "accepts"),
+    (getlist, "optional arguments", getargument)
+    ]
+getproperty = [
+    (getpstr, "name"),
+    (getostype, "code"),
+    (getdata, "what")
+    ]
+getelement = [
+    (getostype, "type"),
+    (getlist, "keyform", getostype)
+    ]
+getclass = [
+    (getpstr, "name"),
+    (getostype, "class code"),
+    (getpstr, "description"),
+    (getlist, "properties", getproperty),
+    (getlist, "elements", getelement)
+    ]
+getcomparison = [
+    (getpstr, "operator name"),
+    (getostype, "operator ID"),
+    (getpstr, "operator comment"),
+    ]
+getenumerator = [
+    (getpstr, "enumerator name"),
+    (getostype, "enumerator ID"),
+    (getpstr, "enumerator comment")
+    ]
+getenumeration = [
+    (getostype, "enumeration ID"),
+    (getlist, "enumerator", getenumerator)
+    ]
+getsuite = [
+    (getpstr, "suite name"),
+    (getpstr, "suite description"),
+    (getostype, "suite ID"),
+    (getword, "suite level"),
+    (getword, "suite version"),
+    (getlist, "events", getevent),
+    (getlist, "classes", getclass),
+    (getlist, "comparisons", getcomparison),
+    (getlist, "enumerations", getenumeration)
+    ]
+getaete = [
+    (getword, "major/minor version in BCD"),
+    (getword, "language code"),
+    (getword, "script code"),
+    (getlist, "suites", getsuite)
+    ]
+
+def compileaete(aete, resinfo, fname, output=None, basepkgname=None,
+        edit_modnames=None, creatorsignature=None, verbose=None):
+    """Generate code for a full aete resource. fname passed for doc purposes"""
+    [version, language, script, suites] = aete
+    major, minor = divmod(version, 256)
+    if not creatorsignature:
+        creatorsignature, dummy = MacOS.GetCreatorAndType(fname)
+    packagename = identify(os.path.splitext(os.path.basename(fname))[0])
+    if language:
+        packagename = packagename+'_lang%d'%language
+    if script:
+        packagename = packagename+'_script%d'%script
+    if len(packagename) > 27:
+        packagename = packagename[:27]
+    if output:
+        # XXXX Put this in site-packages if it isn't a full pathname?
+        if not os.path.exists(output):
+            os.mkdir(output)
+        pathname = output
+    else:
+        pathname = EasyDialogs.AskFolder(message='Create and select package folder for %s'%packagename,
+            defaultLocation=DEFAULT_USER_PACKAGEFOLDER)
+        output = pathname
+    if not pathname:
+        return
+    packagename = os.path.split(os.path.normpath(pathname))[1]
+    if not basepkgname:
+        basepkgname = EasyDialogs.AskFolder(message='Package folder for base suite (usually StdSuites)',
+            defaultLocation=DEFAULT_STANDARD_PACKAGEFOLDER)
+    if basepkgname:
+        dirname, basepkgname = os.path.split(os.path.normpath(basepkgname))
+        if dirname and not dirname in sys.path:
+            sys.path.insert(0, dirname)
+        basepackage = __import__(basepkgname)
+    else:
+        basepackage = None
+    suitelist = []
+    allprecompinfo = []
+    allsuites = []
+    for suite in suites:
+        compiler = SuiteCompiler(suite, basepackage, output, edit_modnames, verbose)
+        code, modname, precompinfo = compiler.precompilesuite()
+        if not code:
+            continue
+        allprecompinfo = allprecompinfo + precompinfo
+        suiteinfo = suite, pathname, modname
+        suitelist.append((code, modname))
+        allsuites.append(compiler)
+    for compiler in allsuites:
+        compiler.compilesuite(major, minor, language, script, fname, allprecompinfo)
+    initfilename = os.path.join(output, '__init__.py')
+    fp = open(initfilename, 'w')
+    MacOS.SetCreatorAndType(initfilename, 'Pyth', 'TEXT')
+    fp.write('"""\n')
+    fp.write("Package generated from %s\n"%ascii(fname))
+    if resinfo:
+        fp.write("Resource %s resid %d %s\n"%(ascii(resinfo[1]), resinfo[0], ascii(resinfo[2])))
+    fp.write('"""\n')
+    fp.write('import aetools\n')
+    fp.write('Error = aetools.Error\n')
+    suitelist.sort()
+    for code, modname in suitelist:
+        fp.write("import %s\n" % modname)
+    fp.write("\n\n_code_to_module = {\n")
+    for code, modname in suitelist:
+        fp.write("    '%s' : %s,\n"%(ascii(code), modname))
+    fp.write("}\n\n")
+    fp.write("\n\n_code_to_fullname = {\n")
+    for code, modname in suitelist:
+        fp.write("    '%s' : ('%s.%s', '%s'),\n"%(ascii(code), packagename, modname, modname))
+    fp.write("}\n\n")
+    for code, modname in suitelist:
+        fp.write("from %s import *\n"%modname)
+
+    # Generate property dicts and element dicts for all types declared in this module
+    fp.write("\ndef getbaseclasses(v):\n")
+    fp.write("    if not getattr(v, '_propdict', None):\n")
+    fp.write("        v._propdict = {}\n")
+    fp.write("        v._elemdict = {}\n")
+    fp.write("        for superclassname in getattr(v, '_superclassnames', []):\n")
+    fp.write("            superclass = eval(superclassname)\n")
+    fp.write("            getbaseclasses(superclass)\n")
+    fp.write("            v._propdict.update(getattr(superclass, '_propdict', {}))\n")
+    fp.write("            v._elemdict.update(getattr(superclass, '_elemdict', {}))\n")
+    fp.write("        v._propdict.update(getattr(v, '_privpropdict', {}))\n")
+    fp.write("        v._elemdict.update(getattr(v, '_privelemdict', {}))\n")
+    fp.write("\n")
+    fp.write("import StdSuites\n")
+    allprecompinfo.sort()
+    if allprecompinfo:
+        fp.write("\n#\n# Set property and element dictionaries now that all classes have been defined\n#\n")
+        for codenamemapper in allprecompinfo:
+            for k, v in codenamemapper.getall('class'):
+                fp.write("getbaseclasses(%s)\n" % v)
+
+    # Generate a code-to-name mapper for all of the types (classes) declared in this module
+    application_class = None
+    if allprecompinfo:
+        fp.write("\n#\n# Indices of types declared in this module\n#\n")
+        fp.write("_classdeclarations = {\n")
+        for codenamemapper in allprecompinfo:
+            for k, v in codenamemapper.getall('class'):
+                fp.write("    %r : %s,\n" % (k, v))
+                if k == 'capp':
+                    application_class = v
+        fp.write("}\n")
+
+
+    if suitelist:
+        fp.write("\n\nclass %s(%s_Events"%(packagename, suitelist[0][1]))
+        for code, modname in suitelist[1:]:
+            fp.write(",\n        %s_Events"%modname)
+        fp.write(",\n        aetools.TalkTo):\n")
+        fp.write("    _signature = %r\n\n"%(creatorsignature,))
+        fp.write("    _moduleName = '%s'\n\n"%packagename)
+        if application_class:
+            fp.write("    _elemdict = %s._elemdict\n" % application_class)
+            fp.write("    _propdict = %s._propdict\n" % application_class)
+    fp.close()
+
+class SuiteCompiler:
+    def __init__(self, suite, basepackage, output, edit_modnames, verbose):
+        self.suite = suite
+        self.basepackage = basepackage
+        self.edit_modnames = edit_modnames
+        self.output = output
+        self.verbose = verbose
+
+        # Set by precompilesuite
+        self.pathname = None
+        self.modname = None
+
+        # Set by compilesuite
+        self.fp = None
+        self.basemodule = None
+        self.enumsneeded = {}
+
+    def precompilesuite(self):
+        """Parse a single suite without generating the output. This step is needed
+        so we can resolve recursive references by suites to enums/comps/etc declared
+        in other suites"""
+        [name, desc, code, level, version, events, classes, comps, enums] = self.suite
+
+        modname = identify(name)
+        if len(modname) > 28:
+            modname = modname[:27]
+        if self.edit_modnames is None:
+            self.pathname = EasyDialogs.AskFileForSave(message='Python output file',
+                savedFileName=modname+'.py')
+        else:
+            for old, new in self.edit_modnames:
+                if old == modname:
+                    modname = new
+            if modname:
+                self.pathname = os.path.join(self.output, modname + '.py')
+            else:
+                self.pathname = None
+        if not self.pathname:
+            return None, None, None
+
+        self.modname = os.path.splitext(os.path.split(self.pathname)[1])[0]
+
+        if self.basepackage and self.basepackage._code_to_module.has_key(code):
+            # We are an extension of a baseclass (usually an application extending
+            # Standard_Suite or so). Import everything from our base module
+            basemodule = self.basepackage._code_to_module[code]
+        else:
+            # We are not an extension.
+            basemodule = None
+
+        self.enumsneeded = {}
+        for event in events:
+            self.findenumsinevent(event)
+
+        objc = ObjectCompiler(None, self.modname, basemodule, interact=(self.edit_modnames is None),
+            verbose=self.verbose)
+        for cls in classes:
+            objc.compileclass(cls)
+        for cls in classes:
+            objc.fillclasspropsandelems(cls)
+        for comp in comps:
+            objc.compilecomparison(comp)
+        for enum in enums:
+            objc.compileenumeration(enum)
+
+        for enum in self.enumsneeded.keys():
+            objc.checkforenum(enum)
+
+        objc.dumpindex()
+
+        precompinfo = objc.getprecompinfo(self.modname)
+
+        return code, self.modname, precompinfo
+
+    def compilesuite(self, major, minor, language, script, fname, precompinfo):
+        """Generate code for a single suite"""
+        [name, desc, code, level, version, events, classes, comps, enums] = self.suite
+        # Sort various lists, so re-generated source is easier compared
+        def class_sorter(k1, k2):
+            """Sort classes by code, and make sure main class sorts before synonyms"""
+            # [name, code, desc, properties, elements] = cls
+            if k1[1] < k2[1]: return -1
+            if k1[1] > k2[1]: return 1
+            if not k2[3] or k2[3][0][1] == 'c@#!':
+                # This is a synonym, the other one is better
+                return -1
+            if not k1[3] or k1[3][0][1] == 'c@#!':
+                # This is a synonym, the other one is better
+                return 1
+            return 0
+
+        events.sort()
+        classes.sort(class_sorter)
+        comps.sort()
+        enums.sort()
+
+        self.fp = fp = open(self.pathname, 'w')
+        MacOS.SetCreatorAndType(self.pathname, 'Pyth', 'TEXT')
+
+        fp.write('"""Suite %s: %s\n' % (ascii(name), ascii(desc)))
+        fp.write("Level %d, version %d\n\n" % (level, version))
+        fp.write("Generated from %s\n"%ascii(fname))
+        fp.write("AETE/AEUT resource version %d/%d, language %d, script %d\n" % \
+            (major, minor, language, script))
+        fp.write('"""\n\n')
+
+        fp.write('import aetools\n')
+        fp.write('import MacOS\n\n')
+        fp.write("_code = %r\n\n"% (code,))
+        if self.basepackage and self.basepackage._code_to_module.has_key(code):
+            # We are an extension of a baseclass (usually an application extending
+            # Standard_Suite or so). Import everything from our base module
+            fp.write('from %s import *\n'%self.basepackage._code_to_fullname[code][0])
+            basemodule = self.basepackage._code_to_module[code]
+        elif self.basepackage and self.basepackage._code_to_module.has_key(code.lower()):
+            # This is needed by CodeWarrior and some others.
+            fp.write('from %s import *\n'%self.basepackage._code_to_fullname[code.lower()][0])
+            basemodule = self.basepackage._code_to_module[code.lower()]
+        else:
+            # We are not an extension.
+            basemodule = None
+        self.basemodule = basemodule
+        self.compileclassheader()
+
+        self.enumsneeded = {}
+        if events:
+            for event in events:
+                self.compileevent(event)
+        else:
+            fp.write("    pass\n\n")
+
+        objc = ObjectCompiler(fp, self.modname, basemodule, precompinfo, interact=(self.edit_modnames is None),
+            verbose=self.verbose)
+        for cls in classes:
+            objc.compileclass(cls)
+        for cls in classes:
+            objc.fillclasspropsandelems(cls)
+        for comp in comps:
+            objc.compilecomparison(comp)
+        for enum in enums:
+            objc.compileenumeration(enum)
+
+        for enum in self.enumsneeded.keys():
+            objc.checkforenum(enum)
+
+        objc.dumpindex()
+
+    def compileclassheader(self):
+        """Generate class boilerplate"""
+        classname = '%s_Events'%self.modname
+        if self.basemodule:
+            modshortname = string.split(self.basemodule.__name__, '.')[-1]
+            baseclassname = '%s_Events'%modshortname
+            self.fp.write("class %s(%s):\n\n"%(classname, baseclassname))
+        else:
+            self.fp.write("class %s:\n\n"%classname)
+
+    def compileevent(self, event):
+        """Generate code for a single event"""
+        [name, desc, code, subcode, returns, accepts, arguments] = event
+        fp = self.fp
+        funcname = identify(name)
+        #
+        # generate name->keyword map
+        #
+        if arguments:
+            fp.write("    _argmap_%s = {\n"%funcname)
+            for a in arguments:
+                fp.write("        %r : %r,\n"%(identify(a[0]), a[1]))
+            fp.write("    }\n\n")
+
+        #
+        # Generate function header
+        #
+        has_arg = (not is_null(accepts))
+        opt_arg = (has_arg and is_optional(accepts))
+
+        fp.write("    def %s(self, "%funcname)
+        if has_arg:
+            if not opt_arg:
+                fp.write("_object, ")       # Include direct object, if it has one
+            else:
+                fp.write("_object=None, ")  # Also include if it is optional
+        else:
+            fp.write("_no_object=None, ")   # For argument checking
+        fp.write("_attributes={}, **_arguments):\n")    # include attribute dict and args
+        #
+        # Generate doc string (important, since it may be the only
+        # available documentation, due to our name-remaping)
+        #
+        fp.write('        """%s: %s\n'%(ascii(name), ascii(desc)))
+        if has_arg:
+            fp.write("        Required argument: %s\n"%getdatadoc(accepts))
+        elif opt_arg:
+            fp.write("        Optional argument: %s\n"%getdatadoc(accepts))
+        for arg in arguments:
+            fp.write("        Keyword argument %s: %s\n"%(identify(arg[0]),
+                    getdatadoc(arg[2])))
+        fp.write("        Keyword argument _attributes: AppleEvent attribute dictionary\n")
+        if not is_null(returns):
+            fp.write("        Returns: %s\n"%getdatadoc(returns))
+        fp.write('        """\n')
+        #
+        # Fiddle the args so everything ends up in 'arguments' dictionary
+        #
+        fp.write("        _code = %r\n"% (code,))
+        fp.write("        _subcode = %r\n\n"% (subcode,))
+        #
+        # Do keyword name substitution
+        #
+        if arguments:
+            fp.write("        aetools.keysubst(_arguments, self._argmap_%s)\n"%funcname)
+        else:
+            fp.write("        if _arguments: raise TypeError, 'No optional args expected'\n")
+        #
+        # Stuff required arg (if there is one) into arguments
+        #
+        if has_arg:
+            fp.write("        _arguments['----'] = _object\n")
+        elif opt_arg:
+            fp.write("        if _object:\n")
+            fp.write("            _arguments['----'] = _object\n")
+        else:
+            fp.write("        if _no_object != None: raise TypeError, 'No direct arg expected'\n")
+        fp.write("\n")
+        #
+        # Do enum-name substitution
+        #
+        for a in arguments:
+            if is_enum(a[2]):
+                kname = a[1]
+                ename = a[2][0]
+                if ename <> '****':
+                    fp.write("        aetools.enumsubst(_arguments, %r, _Enum_%s)\n" %
+                        (kname, identify(ename)))
+                    self.enumsneeded[ename] = 1
+        fp.write("\n")
+        #
+        # Do the transaction
+        #
+        fp.write("        _reply, _arguments, _attributes = self.send(_code, _subcode,\n")
+        fp.write("                _arguments, _attributes)\n")
+        #
+        # Error handling
+        #
+        fp.write("        if _arguments.get('errn', 0):\n")
+        fp.write("            raise aetools.Error, aetools.decodeerror(_arguments)\n")
+        fp.write("        # XXXX Optionally decode result\n")
+        #
+        # Decode result
+        #
+        fp.write("        if _arguments.has_key('----'):\n")
+        if is_enum(returns):
+            fp.write("            # XXXX Should do enum remapping here...\n")
+        fp.write("            return _arguments['----']\n")
+        fp.write("\n")
+
+    def findenumsinevent(self, event):
+        """Find all enums for a single event"""
+        [name, desc, code, subcode, returns, accepts, arguments] = event
+        for a in arguments:
+            if is_enum(a[2]):
+                ename = a[2][0]
+                if ename <> '****':
+                    self.enumsneeded[ename] = 1
+
+#
+# This class stores the code<->name translations for a single module. It is used
+# to keep the information while we're compiling the module, but we also keep these objects
+# around so if one suite refers to, say, an enum in another suite we know where to
+# find it. Finally, if we really can't find a code, the user can add modules by
+# hand.
+#
+class CodeNameMapper:
+
+    def __init__(self, interact=1, verbose=None):
+        self.code2name = {
+            "property" : {},
+            "class" : {},
+            "enum" : {},
+            "comparison" : {},
+        }
+        self.name2code =  {
+            "property" : {},
+            "class" : {},
+            "enum" : {},
+            "comparison" : {},
+        }
+        self.modulename = None
+        self.star_imported = 0
+        self.can_interact = interact
+        self.verbose = verbose
+
+    def addnamecode(self, type, name, code):
+        self.name2code[type][name] = code
+        if not self.code2name[type].has_key(code):
+            self.code2name[type][code] = name
+
+    def hasname(self, name):
+        for dict in self.name2code.values():
+            if dict.has_key(name):
+                return True
+        return False
+
+    def hascode(self, type, code):
+        return self.code2name[type].has_key(code)
+
+    def findcodename(self, type, code):
+        if not self.hascode(type, code):
+            return None, None, None
+        name = self.code2name[type][code]
+        if self.modulename and not self.star_imported:
+            qualname = '%s.%s'%(self.modulename, name)
+        else:
+            qualname = name
+        return name, qualname, self.modulename
+
+    def getall(self, type):
+        return self.code2name[type].items()
+
+    def addmodule(self, module, name, star_imported):
+        self.modulename = name
+        self.star_imported = star_imported
+        for code, name in module._propdeclarations.items():
+            self.addnamecode('property', name, code)
+        for code, name in module._classdeclarations.items():
+            self.addnamecode('class', name, code)
+        for code in module._enumdeclarations.keys():
+            self.addnamecode('enum', '_Enum_'+identify(code), code)
+        for code, name in module._compdeclarations.items():
+            self.addnamecode('comparison', name, code)
+
+    def prepareforexport(self, name=None):
+        if not self.modulename:
+            self.modulename = name
+        return self
+
+class ObjectCompiler:
+    def __init__(self, fp, modname, basesuite, othernamemappers=None, interact=1,
+            verbose=None):
+        self.fp = fp
+        self.verbose = verbose
+        self.basesuite = basesuite
+        self.can_interact = interact
+        self.modulename = modname
+        self.namemappers = [CodeNameMapper(self.can_interact, self.verbose)]
+        if othernamemappers:
+            self.othernamemappers = othernamemappers[:]
+        else:
+            self.othernamemappers = []
+        if basesuite:
+            basemapper = CodeNameMapper(self.can_interact, self.verbose)
+            basemapper.addmodule(basesuite, '', 1)
+            self.namemappers.append(basemapper)
+
+    def getprecompinfo(self, modname):
+        list = []
+        for mapper in self.namemappers:
+            emapper = mapper.prepareforexport(modname)
+            if emapper:
+                list.append(emapper)
+        return list
+
+    def findcodename(self, type, code):
+        while 1:
+            # First try: check whether we already know about this code.
+            for mapper in self.namemappers:
+                if mapper.hascode(type, code):
+                    return mapper.findcodename(type, code)
+            # Second try: maybe one of the other modules knows about it.
+            for mapper in self.othernamemappers:
+                if mapper.hascode(type, code):
+                    self.othernamemappers.remove(mapper)
+                    self.namemappers.append(mapper)
+                    if self.fp:
+                        self.fp.write("import %s\n"%mapper.modulename)
+                    break
+            else:
+                # If all this has failed we ask the user for a guess on where it could
+                # be and retry.
+                if self.fp:
+                    m = self.askdefinitionmodule(type, code)
+                else:
+                    m = None
+                if not m: return None, None, None
+                mapper = CodeNameMapper(self.can_interact, self.verbose)
+                mapper.addmodule(m, m.__name__, 0)
+                self.namemappers.append(mapper)
+
+    def hasname(self, name):
+        for mapper in self.othernamemappers:
+            if mapper.hasname(name) and mapper.modulename != self.modulename:
+                if self.verbose:
+                    print >>self.verbose, "Duplicate Python identifier:", name, self.modulename, mapper.modulename
+                return True
+        return False
+
+    def askdefinitionmodule(self, type, code):
+        if not self.can_interact:
+            if self.verbose:
+                print >>self.verbose, "** No definition for %s '%s' found" % (type, code)
+            return None
+        path = EasyDialogs.AskFileForSave(message='Where is %s %s declared?'%(type, code))
+        if not path: return
+        path, file = os.path.split(path)
+        modname = os.path.splitext(file)[0]
+        if not path in sys.path:
+            sys.path.insert(0, path)
+        m = __import__(modname)
+        self.fp.write("import %s\n"%modname)
+        return m
+
+    def compileclass(self, cls):
+        [name, code, desc, properties, elements] = cls
+        pname = identify(name)
+        if self.namemappers[0].hascode('class', code):
+            # plural forms and such
+            othername, dummy, dummy = self.namemappers[0].findcodename('class', code)
+            if self.fp:
+                self.fp.write("\n%s = %s\n"%(pname, othername))
+        else:
+            if self.fp:
+                self.fp.write('\nclass %s(aetools.ComponentItem):\n' % pname)
+                self.fp.write('    """%s - %s """\n' % (ascii(name), ascii(desc)))
+                self.fp.write('    want = %r\n' % (code,))
+        self.namemappers[0].addnamecode('class', pname, code)
+        is_application_class = (code == 'capp')
+        properties.sort()
+        for prop in properties:
+            self.compileproperty(prop, is_application_class)
+        elements.sort()
+        for elem in elements:
+            self.compileelement(elem)
+
+    def compileproperty(self, prop, is_application_class=False):
+        [name, code, what] = prop
+        if code == 'c@#!':
+            # Something silly with plurals. Skip it.
+            return
+        pname = identify(name)
+        if self.namemappers[0].hascode('property', code):
+            # plural forms and such
+            othername, dummy, dummy = self.namemappers[0].findcodename('property', code)
+            if pname == othername:
+                return
+            if self.fp:
+                self.fp.write("\n_Prop_%s = _Prop_%s\n"%(pname, othername))
+        else:
+            if self.fp:
+                self.fp.write("class _Prop_%s(aetools.NProperty):\n" % pname)
+                self.fp.write('    """%s - %s """\n' % (ascii(name), ascii(what[1])))
+                self.fp.write("    which = %r\n" % (code,))
+                self.fp.write("    want = %r\n" % (what[0],))
+        self.namemappers[0].addnamecode('property', pname, code)
+        if is_application_class and self.fp:
+            self.fp.write("%s = _Prop_%s()\n" % (pname, pname))
+
+    def compileelement(self, elem):
+        [code, keyform] = elem
+        if self.fp:
+            self.fp.write("#        element %r as %s\n" % (code, keyform))
+
+    def fillclasspropsandelems(self, cls):
+        [name, code, desc, properties, elements] = cls
+        cname = identify(name)
+        if self.namemappers[0].hascode('class', code) and \
+                self.namemappers[0].findcodename('class', code)[0] != cname:
+            # This is an other name (plural or so) for something else. Skip.
+            if self.fp and (elements or len(properties) > 1 or (len(properties) == 1 and
+                properties[0][1] != 'c@#!')):
+                if self.verbose:
+                    print >>self.verbose, '** Skip multiple %s of %s (code %r)' % (cname, self.namemappers[0].findcodename('class', code)[0], code)
+                raise RuntimeError, "About to skip non-empty class"
+            return
+        plist = []
+        elist = []
+        superclasses = []
+        for prop in properties:
+            [pname, pcode, what] = prop
+            if pcode == "c@#^":
+                superclasses.append(what)
+            if pcode == 'c@#!':
+                continue
+            pname = identify(pname)
+            plist.append(pname)
+
+        superclassnames = []
+        for superclass in superclasses:
+            superId, superDesc, dummy = superclass
+            superclassname, fullyqualifiedname, module = self.findcodename("class", superId)
+            # I don't think this is correct:
+            if superclassname == cname:
+                pass # superclassnames.append(fullyqualifiedname)
+            else:
+                superclassnames.append(superclassname)
+
+        if self.fp:
+            self.fp.write("%s._superclassnames = %r\n"%(cname, superclassnames))
+
+        for elem in elements:
+            [ecode, keyform] = elem
+            if ecode == 'c@#!':
+                continue
+            name, ename, module = self.findcodename('class', ecode)
+            if not name:
+                if self.fp:
+                    self.fp.write("# XXXX %s element %r not found!!\n"%(cname, ecode))
+            else:
+                elist.append((name, ename))
+
+        plist.sort()
+        elist.sort()
+
+        if self.fp:
+            self.fp.write("%s._privpropdict = {\n"%cname)
+            for n in plist:
+                self.fp.write("    '%s' : _Prop_%s,\n"%(n, n))
+            self.fp.write("}\n")
+            self.fp.write("%s._privelemdict = {\n"%cname)
+            for n, fulln in elist:
+                self.fp.write("    '%s' : %s,\n"%(n, fulln))
+            self.fp.write("}\n")
+
+    def compilecomparison(self, comp):
+        [name, code, comment] = comp
+        iname = identify(name)
+        self.namemappers[0].addnamecode('comparison', iname, code)
+        if self.fp:
+            self.fp.write("class %s(aetools.NComparison):\n" % iname)
+            self.fp.write('    """%s - %s """\n' % (ascii(name), ascii(comment)))
+
+    def compileenumeration(self, enum):
+        [code, items] = enum
+        name = "_Enum_%s" % identify(code)
+        if self.fp:
+            self.fp.write("%s = {\n" % name)
+            for item in items:
+                self.compileenumerator(item)
+            self.fp.write("}\n\n")
+        self.namemappers[0].addnamecode('enum', name, code)
+        return code
+
+    def compileenumerator(self, item):
+        [name, code, desc] = item
+        self.fp.write("    %r : %r,\t# %s\n" % (identify(name), code, ascii(desc)))
+
+    def checkforenum(self, enum):
+        """This enum code is used by an event. Make sure it's available"""
+        name, fullname, module = self.findcodename('enum', enum)
+        if not name:
+            if self.fp:
+                self.fp.write("_Enum_%s = None # XXXX enum %s not found!!\n"%(identify(enum), ascii(enum)))
+            return
+        if module:
+            if self.fp:
+                self.fp.write("from %s import %s\n"%(module, name))
+
+    def dumpindex(self):
+        if not self.fp:
+            return
+        self.fp.write("\n#\n# Indices of types declared in this module\n#\n")
+
+        self.fp.write("_classdeclarations = {\n")
+        classlist = self.namemappers[0].getall('class')
+        classlist.sort()
+        for k, v in classlist:
+            self.fp.write("    %r : %s,\n" % (k, v))
+        self.fp.write("}\n")
+
+        self.fp.write("\n_propdeclarations = {\n")
+        proplist = self.namemappers[0].getall('property')
+        proplist.sort()
+        for k, v in proplist:
+            self.fp.write("    %r : _Prop_%s,\n" % (k, v))
+        self.fp.write("}\n")
+
+        self.fp.write("\n_compdeclarations = {\n")
+        complist = self.namemappers[0].getall('comparison')
+        complist.sort()
+        for k, v in complist:
+            self.fp.write("    %r : %s,\n" % (k, v))
+        self.fp.write("}\n")
+
+        self.fp.write("\n_enumdeclarations = {\n")
+        enumlist = self.namemappers[0].getall('enum')
+        enumlist.sort()
+        for k, v in enumlist:
+            self.fp.write("    %r : %s,\n" % (k, v))
+        self.fp.write("}\n")
+
+def compiledata(data):
+    [type, description, flags] = data
+    return "%r -- %r %s" % (type, description, compiledataflags(flags))
+
+def is_null(data):
+    return data[0] == 'null'
+
+def is_optional(data):
+    return (data[2] & 0x8000)
+
+def is_enum(data):
+    return (data[2] & 0x2000)
+
+def getdatadoc(data):
+    [type, descr, flags] = data
+    if descr:
+        return ascii(descr)
+    if type == '****':
+        return 'anything'
+    if type == 'obj ':
+        return 'an AE object reference'
+    return "undocumented, typecode %r"%(type,)
+
+dataflagdict = {15: "optional", 14: "list", 13: "enum", 12: "mutable"}
+def compiledataflags(flags):
+    bits = []
+    for i in range(16):
+        if flags & (1<<i):
+            if i in dataflagdict.keys():
+                bits.append(dataflagdict[i])
+            else:
+                bits.append(repr(i))
+    return '[%s]' % string.join(bits)
+
+def ascii(str):
+    """Return a string with all non-ascii characters hex-encoded"""
+    if type(str) != type(''):
+        return map(ascii, str)
+    rv = ''
+    for c in str:
+        if c in ('\t', '\n', '\r') or ' ' <= c < chr(0x7f):
+            rv = rv + c
+        else:
+            rv = rv + '\\' + 'x%02.2x' % ord(c)
+    return rv
+
+def identify(str):
+    """Turn any string into an identifier:
+    - replace space by _
+    - replace other illegal chars by _xx_ (hex code)
+    - append _ if the result is a python keyword
+    """
+    if not str:
+        return "empty_ae_name_"
+    rv = ''
+    ok = string.ascii_letters + '_'
+    ok2 = ok + string.digits
+    for c in str:
+        if c in ok:
+            rv = rv + c
+        elif c == ' ':
+            rv = rv + '_'
+        else:
+            rv = rv + '_%02.2x_'%ord(c)
+        ok = ok2
+    if keyword.iskeyword(rv):
+        rv = rv + '_'
+    return rv
+
+# Call the main program
+
+if __name__ == '__main__':
+    main()
+    sys.exit(1)

Added: vendor/Python/current/Lib/plat-mac/ic.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/ic.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/ic.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,268 @@
+"""IC wrapper module, based on Internet Config 1.3"""
+
+import icglue
+import string
+import sys
+import os
+from Carbon import Res
+import Carbon.File
+import macostools
+
+error=icglue.error
+
+# From ictypes.h:
+icPrefNotFoundErr = -666        # preference not found (duh!)
+icPermErr = -667                # cannot set preference
+icPrefDataErr = -668            # problem with preference data
+icInternalErr = -669            # hmm, this is not good
+icTruncatedErr = -670           # more data was present than was returned
+icNoMoreWritersErr = -671       # you cannot begin a write session because someone else is already doing it */
+icNothingToOverrideErr = -672   # no component for the override component to capture
+icNoURLErr = -673               # no URL found
+icConfigNotFoundErr = -674      # no configuration was found
+icConfigInappropriateErr = -675 # incorrect manufacturer code
+
+ICattr_no_change = -1
+
+icNoPerm = 0
+icReadOnlyPerm = 1
+icReadWritePerm = 2
+# End of ictypes.h
+
+class ICOpaqueData:
+    """An unparseable IC entry"""
+    def __init__(self, data):
+        self.data = data
+
+    def __repr__(self):
+        return "ICOpaqueData(%r)"%(self.data,)
+
+_ICOpaqueDataType=type(ICOpaqueData(''))
+
+def _decode_default(data, key):
+    if len(data) == 0:
+        return data
+    if ord(data[0]) == len(data)-1:
+        # Assume Pstring
+        return data[1:]
+    return ICOpaqueData(data)
+
+
+def _decode_multistr(data, key):
+    numstr = ord(data[0]) << 8 | ord(data[1])
+    rv = []
+    ptr = 2
+    for i in range(numstr):
+        strlen = ord(data[ptr])
+        str = data[ptr+1:ptr+strlen+1]
+        rv.append(str)
+        ptr = ptr + strlen + 1
+    return rv
+
+def _decode_fontrecord(data, key):
+    size = ord(data[0]) << 8 | ord(data[1])
+    face = ord(data[2])
+    namelen = ord(data[4])
+    return size, face, data[5:5+namelen]
+
+def _decode_boolean(data, key):
+    return ord(data[0])
+
+def _decode_text(data, key):
+    return data
+
+def _decode_charset(data, key):
+    return data[:256], data[256:]
+
+def _decode_appspec(data, key):
+    namelen = ord(data[4])
+    return data[0:4], data[5:5+namelen]
+
+def _code_default(data, key):
+    return chr(len(data)) + data
+
+def _code_multistr(data, key):
+    numstr = len(data)
+    rv = chr((numstr>>8) & 0xff) + chr(numstr & 0xff)
+    for i in data:
+        rv = rv + _code_default(i)
+    return rv
+
+def _code_fontrecord(data, key):
+    size, face, name = data
+    return chr((size>>8) & 0xff) + chr(size & 0xff) + chr(face & 0xff) + \
+        chr(0) + _code_default(name)
+
+def _code_boolean(data, key):
+    print 'XXXX boolean:', repr(data)
+    return chr(data)
+
+def _code_text(data, key):
+    return data
+
+def _code_charset(data, key):
+    return data[0] + data[1]
+
+def _code_appspec(data, key):
+    return data[0] + _code_default(data[1])
+
+_decoder_table = {
+    "ArchieAll" : (_decode_multistr , _code_multistr),
+    "UMichAll" : (_decode_multistr , _code_multistr),
+    "InfoMacAll" : (_decode_multistr , _code_multistr),
+    "ListFont" : (_decode_fontrecord , _code_fontrecord),
+    "ScreenFont" : (_decode_fontrecord , _code_fontrecord),
+    "PrinterFont" : (_decode_fontrecord , _code_fontrecord),
+#   "DownloadFolder" : (_decode_filespec , _code_filespec),
+    "Signature": (_decode_text , _code_text),
+    "Plan" : (_decode_text , _code_text),
+    "MailHeaders" : (_decode_text , _code_text),
+    "NewsHeaders" : (_decode_text , _code_text),
+#   "Mapping"
+    "CharacterSet" : (_decode_charset , _code_charset),
+    "Helper\245" : (_decode_appspec , _code_appspec),
+#   "Services" : (_decode_services, ????),
+    "NewMailFlashIcon" : (_decode_boolean , _code_boolean),
+    "NewMailDialog" : (_decode_boolean , _code_boolean),
+    "NewMailPlaySound" : (_decode_boolean , _code_boolean),
+#   "WebBackgroundColor" : _decode_color,
+    "NoProxyDomains" : (_decode_multistr , _code_multistr),
+    "UseHTTPProxy" : (_decode_boolean , _code_boolean),
+    "UseGopherProxy": (_decode_boolean , _code_boolean),
+    "UseFTPProxy" : (_decode_boolean , _code_boolean),
+    "UsePassiveFTP" : (_decode_boolean , _code_boolean),
+}
+
+def _decode(data, key):
+    if '\245' in key:
+        key2 = key[:string.index(key, '\245')+1]
+    else:
+        key2 = key
+    if _decoder_table.has_key(key2):
+        decoder = _decoder_table[key2][0]
+    else:
+        decoder = _decode_default
+    return decoder(data, key)
+
+def _code(data, key):
+    if type(data) == _ICOpaqueDataType:
+        return data.data
+    if '\245' in key:
+        key2 = key[:string.index(key, '\245')+1]
+    else:
+        key2 = key
+    if _decoder_table.has_key(key2):
+        coder = _decoder_table[key2][1]
+    else:
+        coder = _code_default
+    return coder(data, key)
+
+class IC:
+    def __init__(self, signature='Pyth', ic=None):
+        if ic:
+            self.ic = ic
+        else:
+            self.ic = icglue.ICStart(signature)
+            if hasattr(self.ic, 'ICFindConfigFile'):
+                self.ic.ICFindConfigFile()
+        self.h = Res.Resource('')
+
+    def keys(self):
+        rv = []
+        self.ic.ICBegin(icReadOnlyPerm)
+        num = self.ic.ICCountPref()
+        for i in range(num):
+            rv.append(self.ic.ICGetIndPref(i+1))
+        self.ic.ICEnd()
+        return rv
+
+    def has_key(self, key):
+        return self.__contains__(key)
+
+    def __contains__(self, key):
+        try:
+            dummy = self.ic.ICFindPrefHandle(key, self.h)
+        except icglue.error:
+            return 0
+        return 1
+
+    def __getitem__(self, key):
+        attr = self.ic.ICFindPrefHandle(key, self.h)
+        return _decode(self.h.data, key)
+
+    def __setitem__(self, key, value):
+        value = _code(value, key)
+        self.ic.ICSetPref(key, ICattr_no_change, value)
+
+    def launchurl(self, url, hint=""):
+        # Work around a bug in ICLaunchURL: file:/foo does
+        # not work but file:///foo does.
+        if url[:6] == 'file:/' and url[6] != '/':
+            url = 'file:///' + url[6:]
+        self.ic.ICLaunchURL(hint, url, 0, len(url))
+
+    def parseurl(self, data, start=None, end=None, hint=""):
+        if start == None:
+            selStart = 0
+            selEnd = len(data)
+        else:
+            selStart = selEnd = start
+        if end != None:
+            selEnd = end
+        selStart, selEnd = self.ic.ICParseURL(hint, data, selStart, selEnd, self.h)
+        return self.h.data, selStart, selEnd
+
+    def mapfile(self, file):
+        if type(file) != type(''):
+            file = file.as_tuple()[2]
+        return self.ic.ICMapFilename(file)
+
+    def maptypecreator(self, type, creator, filename=""):
+        return self.ic.ICMapTypeCreator(type, creator, filename)
+
+    def settypecreator(self, file):
+        file = Carbon.File.pathname(file)
+        record = self.mapfile(os.path.split(file)[1])
+        MacOS.SetCreatorAndType(file, record[2], record[1])
+        macostools.touched(fss)
+
+# Convenience routines
+_dft_ic = None
+
+def launchurl(url, hint=""):
+    global _dft_ic
+    if _dft_ic == None: _dft_ic = IC()
+    return _dft_ic.launchurl(url, hint)
+
+def parseurl(data, start=None, end=None, hint=""):
+    global _dft_ic
+    if _dft_ic == None: _dft_ic = IC()
+    return _dft_ic.parseurl(data, start, end, hint)
+
+def mapfile(filename):
+    global _dft_ic
+    if _dft_ic == None: _dft_ic = IC()
+    return _dft_ic.mapfile(filename)
+
+def maptypecreator(type, creator, filename=""):
+    global _dft_ic
+    if _dft_ic == None: _dft_ic = IC()
+    return _dft_ic.maptypecreator(type, creator, filename)
+
+def settypecreator(file):
+    global _dft_ic
+    if _dft_ic == None: _dft_ic = IC()
+    return _dft_ic.settypecreator(file)
+
+def _test():
+    ic = IC()
+    for k in ic.keys():
+        try:
+            v = ic[k]
+        except error:
+            v = '????'
+        print k, '\t', v
+    sys.exit(1)
+
+if __name__ == '__main__':
+    _test()

Added: vendor/Python/current/Lib/plat-mac/icopen.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/icopen.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/icopen.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,66 @@
+"""icopen patch
+
+OVERVIEW
+
+icopen patches MacOS Python to use the Internet Config file mappings to select
+the type and creator for a file.
+
+Version 1 released to the public domain 3 November 1999
+by Oliver Steele (steele at cs.brandeis.edu).
+
+DETAILS
+
+This patch causes files created by Python's open(filename, 'w') command (and
+by functions and scripts that call it) to set the type and creator of the file
+to the type and creator associated with filename's extension (the
+portion of the filename after the last period), according to Internet Config.
+Thus, a script that creates a file foo.html will create one that opens in whatever
+browser you've set to handle *.html files, and so on.
+
+Python IDE uses its own algorithm to select the type and creator for saved
+editor windows, so this patch won't effect their types.
+
+As of System 8.6 at least, Internet Config is built into the system, and the
+file mappings are accessed from the Advanced pane of the Internet control
+panel.  User Mode (in the Edit menu) needs to be set to Advanced in order to
+access this pane.
+
+INSTALLATION
+
+Put this file in your Python path, and create a file named {Python}:sitecustomize.py
+that contains:
+        import icopen
+
+(If {Python}:sitecustomizer.py already exists, just add the 'import' line to it.)
+
+The next time you launch PythonInterpreter or Python IDE, the patch will take
+effect.
+"""
+
+import __builtin__
+
+_builtin_open = globals().get('_builtin_open', __builtin__.open)
+
+def _open_with_typer(*args):
+    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
+
+"""
+open('test.py')
+_open_with_typer('test.py', 'w')
+_open_with_typer('test.txt', 'w')
+_open_with_typer('test.html', 'w')
+_open_with_typer('test.foo', 'w')
+"""

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/CodeWarrior/CodeWarrior_suite.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/CodeWarrior/CodeWarrior_suite.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/CodeWarrior/CodeWarrior_suite.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,682 @@
+"""Suite CodeWarrior suite: Terms for scripting the CodeWarrior IDE
+Level 0, version 0
+
+Generated from /Volumes/Sap/Applications (Mac OS 9)/Metrowerks CodeWarrior 7.0/Metrowerks CodeWarrior/CodeWarrior IDE 4.2.5
+AETE/AEUT resource version 1/0, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'CWIE'
+
+class CodeWarrior_suite_Events:
+
+    _argmap_add = {
+        'new' : 'kocl',
+        'with_data' : 'data',
+        'to_targets' : 'TTGT',
+        'to_group' : 'TGRP',
+    }
+
+    def add(self, _object, _attributes={}, **_arguments):
+        """add: add elements to a project or target
+        Required argument: an AE object reference
+        Keyword argument new: the class of the new element or elements to add
+        Keyword argument with_data: the initial data for the element or elements
+        Keyword argument to_targets: the targets to which the new element or elements will be added
+        Keyword argument to_group: the group to which the new element or elements will be added
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'CWIE'
+        _subcode = 'ADDF'
+
+        aetools.keysubst(_arguments, self._argmap_add)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def build(self, _no_object=None, _attributes={}, **_arguments):
+        """build: build a project or target (equivalent of the Make menu command)
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'CWIE'
+        _subcode = 'MAKE'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def check(self, _object=None, _attributes={}, **_arguments):
+        """check: check the syntax of a file in a project or target
+        Required argument: the file or files to be checked
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'CWIE'
+        _subcode = 'CHEK'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def compile_file(self, _object=None, _attributes={}, **_arguments):
+        """compile file: compile a file in a project or target
+        Required argument: the file or files to be compiled
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'CWIE'
+        _subcode = 'COMP'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def disassemble_file(self, _object=None, _attributes={}, **_arguments):
+        """disassemble file: disassemble a file in a project or target
+        Required argument: the file or files to be disassembled
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'CWIE'
+        _subcode = 'DASM'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_export = {
+        'in_' : 'kfil',
+    }
+
+    def export(self, _no_object=None, _attributes={}, **_arguments):
+        """export: Export the project file as an XML file
+        Keyword argument in_: the XML file in which to export the project
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'CWIE'
+        _subcode = 'EXPT'
+
+        aetools.keysubst(_arguments, self._argmap_export)
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def remove_object_code(self, _no_object=None, _attributes={}, **_arguments):
+        """remove object code: remove object code from a project or target
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'CWIE'
+        _subcode = 'RMOB'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def remove_target_files(self, _object, _attributes={}, **_arguments):
+        """remove target files: remove files from a target
+        Required argument: an AE object reference
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'CWIE'
+        _subcode = 'RMFL'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def run_target(self, _no_object=None, _attributes={}, **_arguments):
+        """run target: run a project or target
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'CWIE'
+        _subcode = 'RUN '
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def touch_file(self, _object=None, _attributes={}, **_arguments):
+        """touch file: touch a file in a project or target for compilation
+        Required argument: the file or files to be touched
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'CWIE'
+        _subcode = 'TOCH'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def update(self, _no_object=None, _attributes={}, **_arguments):
+        """update: bring a project or target up to date
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'CWIE'
+        _subcode = 'UP2D'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+
+class single_class_browser(aetools.ComponentItem):
+    """single class browser - a single class browser """
+    want = '1BRW'
+class _Prop_inherits(aetools.NProperty):
+    """inherits - all properties and elements of the given class are inherited by this class. """
+    which = 'c@#^'
+    want = 'TXTD'
+
+single_class_browsers = single_class_browser
+
+class single_class_hierarchy(aetools.ComponentItem):
+    """single class hierarchy - a single class hierarchy document """
+    want = '1HIR'
+
+single_class_hierarchies = single_class_hierarchy
+
+class class_browser(aetools.ComponentItem):
+    """class browser - a class browser """
+    want = 'BROW'
+
+class_browsers = class_browser
+
+class file_compare_document(aetools.ComponentItem):
+    """file compare document - a file compare document """
+    want = 'COMP'
+
+file_compare_documents = file_compare_document
+
+class catalog_document(aetools.ComponentItem):
+    """catalog document - a browser catalog document """
+    want = 'CTLG'
+
+catalog_documents = catalog_document
+
+class editor_document(aetools.ComponentItem):
+    """editor document - an editor document """
+    want = 'EDIT'
+
+editor_documents = editor_document
+
+class class_hierarchy(aetools.ComponentItem):
+    """class hierarchy - a class hierarchy document """
+    want = 'HIER'
+
+class_hierarchies = class_hierarchy
+
+class project_inspector(aetools.ComponentItem):
+    """project inspector - the project inspector """
+    want = 'INSP'
+
+project_inspectors = project_inspector
+
+class message_document(aetools.ComponentItem):
+    """message document - a message document """
+    want = 'MSSG'
+
+message_documents = message_document
+
+class build_progress_document(aetools.ComponentItem):
+    """build progress document - a build progress document """
+    want = 'PRGS'
+
+build_progress_documents = build_progress_document
+
+class project_document(aetools.ComponentItem):
+    """project document - a project document """
+    want = 'PRJD'
+class _Prop_current_target(aetools.NProperty):
+    """current target - the current target """
+    which = 'CURT'
+    want = 'TRGT'
+#        element 'TRGT' as ['indx', 'name', 'test', 'rang']
+
+project_documents = project_document
+
+class subtarget(aetools.ComponentItem):
+    """subtarget - a target that is prerequisite for another target """
+    want = 'SBTG'
+class _Prop_link_against_output(aetools.NProperty):
+    """link against output - is the output of this subtarget linked into its dependent target? """
+    which = 'LNKO'
+    want = 'bool'
+class _Prop_target(aetools.NProperty):
+    """target - the target that is dependent on this subtarget """
+    which = 'TrgT'
+    want = 'TRGT'
+
+subtargets = subtarget
+
+class target_file(aetools.ComponentItem):
+    """target file - a source or header file in a target """
+    want = 'SRCF'
+class _Prop_code_size(aetools.NProperty):
+    """code size - the size of the code (in bytes) produced by compiling this source file """
+    which = 'CSZE'
+    want = 'long'
+class _Prop_compiled_date(aetools.NProperty):
+    """compiled date - the date and this source file was last compiled """
+    which = 'CMPD'
+    want = 'ldt '
+class _Prop_data_size(aetools.NProperty):
+    """data size - the size of the date (in bytes) produced by compiling this source file """
+    which = 'DSZE'
+    want = 'long'
+class _Prop_debug(aetools.NProperty):
+    """debug - is debugging information generated for this source file? """
+    which = 'DBUG'
+    want = 'bool'
+class _Prop_dependents(aetools.NProperty):
+    """dependents - the source files that need this source file in order to build """
+    which = 'DPND'
+    want = 'list'
+class _Prop_id(aetools.NProperty):
+    """id - the unique ID number of the target file """
+    which = 'ID  '
+    want = 'long'
+class _Prop_init_before(aetools.NProperty):
+    """init before - is the \xd4initialize before\xd5 flag set for this shared library? """
+    which = 'INIT'
+    want = 'bool'
+class _Prop_link_index(aetools.NProperty):
+    """link index - the index of the source file in its target\xd5s link order (-1 if source file is not in link order) """
+    which = 'LIDX'
+    want = 'long'
+class _Prop_linked(aetools.NProperty):
+    """linked - is the source file in the link order of its target? """
+    which = 'LINK'
+    want = 'bool'
+class _Prop_location(aetools.NProperty):
+    """location - the location of the target file on disk """
+    which = 'FILE'
+    want = 'fss '
+class _Prop_merge_output(aetools.NProperty):
+    """merge output - is this shared library merged into another code fragment? """
+    which = 'MRGE'
+    want = 'bool'
+class _Prop_modified_date(aetools.NProperty):
+    """modified date - the date and time this source file was last modified """
+    which = 'MODD'
+    want = 'ldt '
+class _Prop_path(aetools.NProperty):
+    """path - the path of the source file on disk """
+    which = 'Path'
+    want = 'itxt'
+class _Prop_prerequisites(aetools.NProperty):
+    """prerequisites - the source files needed to build this source file """
+    which = 'PRER'
+    want = 'list'
+class _Prop_type(aetools.NProperty):
+    """type - the type of source file """
+    which = 'FTYP'
+    want = 'FTYP'
+class _Prop_weak_link(aetools.NProperty):
+    """weak link - is this shared library linked weakly? """
+    which = 'WEAK'
+    want = 'bool'
+
+target_files = target_file
+
+class symbol_browser(aetools.ComponentItem):
+    """symbol browser - a symbol browser """
+    want = 'SYMB'
+
+symbol_browsers = symbol_browser
+
+class ToolServer_worksheet(aetools.ComponentItem):
+    """ToolServer worksheet - a ToolServer worksheet """
+    want = 'TOOL'
+
+ToolServer_worksheets = ToolServer_worksheet
+
+class target(aetools.ComponentItem):
+    """target - a target in a project """
+    want = 'TRGT'
+class _Prop_name(aetools.NProperty):
+    """name -  """
+    which = 'pnam'
+    want = 'itxt'
+class _Prop_project_document(aetools.NProperty):
+    """project document - the project document that contains this target """
+    which = 'PrjD'
+    want = 'PRJD'
+#        element 'SBTG' as ['indx', 'test', 'rang']
+#        element 'SRCF' as ['indx', 'test', 'rang']
+
+targets = target
+
+class text_document(aetools.ComponentItem):
+    """text document - a document that contains text """
+    want = 'TXTD'
+class _Prop_modified(aetools.NProperty):
+    """modified - Has the document been modified since the last save? """
+    which = 'imod'
+    want = 'bool'
+class _Prop_selection(aetools.NProperty):
+    """selection - the selection visible to the user """
+    which = 'sele'
+    want = 'csel'
+#        element 'cha ' as ['indx', 'rele', 'rang', 'test']
+#        element 'cins' as ['rele']
+#        element 'clin' as ['indx', 'rang', 'rele']
+#        element 'ctxt' as ['rang']
+
+text_documents = text_document
+single_class_browser._superclassnames = ['text_document']
+single_class_browser._privpropdict = {
+    'inherits' : _Prop_inherits,
+}
+single_class_browser._privelemdict = {
+}
+import Standard_Suite
+single_class_hierarchy._superclassnames = ['document']
+single_class_hierarchy._privpropdict = {
+    'inherits' : _Prop_inherits,
+}
+single_class_hierarchy._privelemdict = {
+}
+class_browser._superclassnames = ['text_document']
+class_browser._privpropdict = {
+    'inherits' : _Prop_inherits,
+}
+class_browser._privelemdict = {
+}
+file_compare_document._superclassnames = ['text_document']
+file_compare_document._privpropdict = {
+    'inherits' : _Prop_inherits,
+}
+file_compare_document._privelemdict = {
+}
+catalog_document._superclassnames = ['text_document']
+catalog_document._privpropdict = {
+    'inherits' : _Prop_inherits,
+}
+catalog_document._privelemdict = {
+}
+editor_document._superclassnames = ['text_document']
+editor_document._privpropdict = {
+    'inherits' : _Prop_inherits,
+}
+editor_document._privelemdict = {
+}
+class_hierarchy._superclassnames = ['document']
+class_hierarchy._privpropdict = {
+    'inherits' : _Prop_inherits,
+}
+class_hierarchy._privelemdict = {
+}
+project_inspector._superclassnames = ['document']
+project_inspector._privpropdict = {
+    'inherits' : _Prop_inherits,
+}
+project_inspector._privelemdict = {
+}
+message_document._superclassnames = ['text_document']
+message_document._privpropdict = {
+    'inherits' : _Prop_inherits,
+}
+message_document._privelemdict = {
+}
+build_progress_document._superclassnames = ['document']
+build_progress_document._privpropdict = {
+    'inherits' : _Prop_inherits,
+}
+build_progress_document._privelemdict = {
+}
+project_document._superclassnames = ['document']
+project_document._privpropdict = {
+    'current_target' : _Prop_current_target,
+    'inherits' : _Prop_inherits,
+}
+project_document._privelemdict = {
+    'target' : target,
+}
+subtarget._superclassnames = ['target']
+subtarget._privpropdict = {
+    'inherits' : _Prop_inherits,
+    'link_against_output' : _Prop_link_against_output,
+    'target' : _Prop_target,
+}
+subtarget._privelemdict = {
+}
+target_file._superclassnames = []
+target_file._privpropdict = {
+    'code_size' : _Prop_code_size,
+    'compiled_date' : _Prop_compiled_date,
+    'data_size' : _Prop_data_size,
+    'debug' : _Prop_debug,
+    'dependents' : _Prop_dependents,
+    'id' : _Prop_id,
+    'init_before' : _Prop_init_before,
+    'link_index' : _Prop_link_index,
+    'linked' : _Prop_linked,
+    'location' : _Prop_location,
+    'merge_output' : _Prop_merge_output,
+    'modified_date' : _Prop_modified_date,
+    'path' : _Prop_path,
+    'prerequisites' : _Prop_prerequisites,
+    'type' : _Prop_type,
+    'weak_link' : _Prop_weak_link,
+}
+target_file._privelemdict = {
+}
+symbol_browser._superclassnames = ['text_document']
+symbol_browser._privpropdict = {
+    'inherits' : _Prop_inherits,
+}
+symbol_browser._privelemdict = {
+}
+ToolServer_worksheet._superclassnames = ['text_document']
+ToolServer_worksheet._privpropdict = {
+    'inherits' : _Prop_inherits,
+}
+ToolServer_worksheet._privelemdict = {
+}
+target._superclassnames = []
+target._privpropdict = {
+    'name' : _Prop_name,
+    'project_document' : _Prop_project_document,
+}
+target._privelemdict = {
+    'subtarget' : subtarget,
+    'target_file' : target_file,
+}
+text_document._superclassnames = ['document']
+text_document._privpropdict = {
+    'inherits' : _Prop_inherits,
+    'modified' : _Prop_modified,
+    'selection' : _Prop_selection,
+}
+text_document._privelemdict = {
+    'character' : Standard_Suite.character,
+    'insertion_point' : Standard_Suite.insertion_point,
+    'line' : Standard_Suite.line,
+    'text' : Standard_Suite.text,
+}
+_Enum_DKND = {
+    'project' : 'PRJD', # a project document
+    'editor_document' : 'EDIT', # an editor document
+    'message' : 'MSSG', # a message document
+    'file_compare' : 'COMP',    # a file compare document
+    'catalog_document' : 'CTLG',        # a browser catalog
+    'class_browser' : 'BROW',   # a class browser document
+    'single_class_browser' : '1BRW',    # a single class browser document
+    'symbol_browser' : 'SYMB',  # a symbol browser document
+    'class_hierarchy' : 'HIER', # a class hierarchy document
+    'single_class_hierarchy' : '1HIR',  # a single class hierarchy document
+    'project_inspector' : 'INSP',       # a project inspector
+    'ToolServer_worksheet' : 'TOOL',    # the ToolServer worksheet
+    'build_progress_document' : 'PRGS', # the build progress window
+}
+
+_Enum_FTYP = {
+    'library_file' : 'LIBF',    # a library file
+    'project_file' : 'PRJF',    # a project file
+    'resource_file' : 'RESF',   # a resource file
+    'text_file' : 'TXTF',       # a text file
+    'unknown_file' : 'UNKN',    # unknown file type
+}
+
+_Enum_Inte = {
+    'never_interact' : 'eNvr',  # never allow user interactions
+    'interact_with_self' : 'eInS',      # allow user interaction only when an AppleEvent is sent from within CodeWarrior
+    'interact_with_local' : 'eInL',     # allow user interaction when AppleEvents are sent from applications on the same machine (default)
+    'interact_with_all' : 'eInA',       # allow user interaction from both local and remote AppleEvents
+}
+
+_Enum_PERM = {
+    'read_write' : 'RdWr',      # the file is open with read/write permission
+    'read_only' : 'Read',       # the file is open with read/only permission
+    'checked_out_read_write' : 'CkRW',  # the file is checked out with read/write permission
+    'checked_out_read_only' : 'CkRO',   # the file is checked out with read/only permission
+    'checked_out_read_modify' : 'CkRM', # the file is checked out with read/modify permission
+    'locked' : 'Lock',  # the file is locked on disk
+    'none' : 'LNNO',    # the file is new
+}
+
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+    '1BRW' : single_class_browser,
+    '1HIR' : single_class_hierarchy,
+    'BROW' : class_browser,
+    'COMP' : file_compare_document,
+    'CTLG' : catalog_document,
+    'EDIT' : editor_document,
+    'HIER' : class_hierarchy,
+    'INSP' : project_inspector,
+    'MSSG' : message_document,
+    'PRGS' : build_progress_document,
+    'PRJD' : project_document,
+    'SBTG' : subtarget,
+    'SRCF' : target_file,
+    'SYMB' : symbol_browser,
+    'TOOL' : ToolServer_worksheet,
+    'TRGT' : target,
+    'TXTD' : text_document,
+}
+
+_propdeclarations = {
+    'CMPD' : _Prop_compiled_date,
+    'CSZE' : _Prop_code_size,
+    'CURT' : _Prop_current_target,
+    'DBUG' : _Prop_debug,
+    'DPND' : _Prop_dependents,
+    'DSZE' : _Prop_data_size,
+    'FILE' : _Prop_location,
+    'FTYP' : _Prop_type,
+    'ID  ' : _Prop_id,
+    'INIT' : _Prop_init_before,
+    'LIDX' : _Prop_link_index,
+    'LINK' : _Prop_linked,
+    'LNKO' : _Prop_link_against_output,
+    'MODD' : _Prop_modified_date,
+    'MRGE' : _Prop_merge_output,
+    'PRER' : _Prop_prerequisites,
+    'Path' : _Prop_path,
+    'PrjD' : _Prop_project_document,
+    'TrgT' : _Prop_target,
+    'WEAK' : _Prop_weak_link,
+    'c@#^' : _Prop_inherits,
+    'imod' : _Prop_modified,
+    'pnam' : _Prop_name,
+    'sele' : _Prop_selection,
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+    'DKND' : _Enum_DKND,
+    'FTYP' : _Enum_FTYP,
+    'Inte' : _Enum_Inte,
+    'PERM' : _Enum_PERM,
+}

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/CodeWarrior/Metrowerks_Shell_Suite.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/CodeWarrior/Metrowerks_Shell_Suite.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/CodeWarrior/Metrowerks_Shell_Suite.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2373 @@
+"""Suite Metrowerks Shell Suite: Events supported by the Metrowerks Project Shell
+Level 1, version 1
+
+Generated from /Volumes/Sap/Applications (Mac OS 9)/Metrowerks CodeWarrior 7.0/Metrowerks CodeWarrior/CodeWarrior IDE 4.2.5
+AETE/AEUT resource version 1/0, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'MMPR'
+
+class Metrowerks_Shell_Suite_Events:
+
+    _argmap_Add_Files = {
+        'To_Segment' : 'Segm',
+    }
+
+    def Add_Files(self, _object, _attributes={}, **_arguments):
+        """Add Files: Add the specified file(s) to the current project
+        Required argument: List of files to add
+        Keyword argument To_Segment: Segment number into which to add the file(s)
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: Error code for each file added
+        """
+        _code = 'MMPR'
+        _subcode = 'AddF'
+
+        aetools.keysubst(_arguments, self._argmap_Add_Files)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_Check_Syntax = {
+        'ExternalEditor' : 'Errs',
+    }
+
+    def Check_Syntax(self, _object, _attributes={}, **_arguments):
+        """Check Syntax: Check the syntax of the specified file(s)
+        Required argument: List of files to check the syntax of
+        Keyword argument ExternalEditor: Should the contents of the message window be returned to the caller?
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: Errors for each file whose syntax was checked
+        """
+        _code = 'MMPR'
+        _subcode = 'Chek'
+
+        aetools.keysubst(_arguments, self._argmap_Check_Syntax)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def Close_Project(self, _no_object=None, _attributes={}, **_arguments):
+        """Close Project: Close the current project
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'MMPR'
+        _subcode = 'ClsP'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_Close_Window = {
+        'Saving' : 'savo',
+    }
+
+    def Close_Window(self, _object, _attributes={}, **_arguments):
+        """Close Window: Close the windows showing the specified files
+        Required argument: The files to close
+        Keyword argument Saving: Whether to save changes to each file before closing its window
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'MMPR'
+        _subcode = 'ClsW'
+
+        aetools.keysubst(_arguments, self._argmap_Close_Window)
+        _arguments['----'] = _object
+
+        aetools.enumsubst(_arguments, 'savo', _Enum_savo)
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_Compile = {
+        'ExternalEditor' : 'Errs',
+    }
+
+    def Compile(self, _object, _attributes={}, **_arguments):
+        """Compile: Compile the specified file(s)
+        Required argument: List of files to compile
+        Keyword argument ExternalEditor: Should the contents of the message window be returned to the caller?
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: Errors for each file compiled
+        """
+        _code = 'MMPR'
+        _subcode = 'Comp'
+
+        aetools.keysubst(_arguments, self._argmap_Compile)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_Create_Project = {
+        'from_stationery' : 'Tmpl',
+    }
+
+    def Create_Project(self, _object, _attributes={}, **_arguments):
+        """Create Project: Create a new project file
+        Required argument: New project file specifier
+        Keyword argument from_stationery: undocumented, typecode 'alis'
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'MMPR'
+        _subcode = 'NewP'
+
+        aetools.keysubst(_arguments, self._argmap_Create_Project)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def Get_Definition(self, _object, _attributes={}, **_arguments):
+        """Get Definition: Returns the location(s) of a globally scoped function or data object.
+        Required argument: undocumented, typecode 'TEXT'
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: undocumented, typecode 'FDef'
+        """
+        _code = 'MMPR'
+        _subcode = 'GDef'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def Get_Open_Documents(self, _no_object=None, _attributes={}, **_arguments):
+        """Get Open Documents: Returns the list of open documents
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: The list of documents
+        """
+        _code = 'MMPR'
+        _subcode = 'GDoc'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_Get_Preferences = {
+        'of' : 'PRec',
+        'from_panel' : 'PNam',
+    }
+
+    def Get_Preferences(self, _no_object=None, _attributes={}, **_arguments):
+        """Get Preferences: Get the preferences for the current project
+        Keyword argument of: Names of requested preferences
+        Keyword argument from_panel: Name of the preference panel
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: The requested preferences
+        """
+        _code = 'MMPR'
+        _subcode = 'Gref'
+
+        aetools.keysubst(_arguments, self._argmap_Get_Preferences)
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_Get_Project_File = {
+        'Segment' : 'Segm',
+    }
+
+    def Get_Project_File(self, _object, _attributes={}, **_arguments):
+        """Get Project File: Returns a description of a file in the project window.
+        Required argument: The index of the file within its segment.
+        Keyword argument Segment: The segment containing the file.
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: undocumented, typecode 'SrcF'
+        """
+        _code = 'MMPR'
+        _subcode = 'GFil'
+
+        aetools.keysubst(_arguments, self._argmap_Get_Project_File)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def Get_Project_Specifier(self, _no_object=None, _attributes={}, **_arguments):
+        """Get Project Specifier: Return the File Specifier for the current project
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: File Specifier for the current project
+        """
+        _code = 'MMPR'
+        _subcode = 'GetP'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def Get_Segments(self, _no_object=None, _attributes={}, **_arguments):
+        """Get Segments: Returns a description of each segment in the project.
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: undocumented, typecode 'Seg '
+        """
+        _code = 'MMPR'
+        _subcode = 'GSeg'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def Get_member_function_names(self, _object, _attributes={}, **_arguments):
+        """Get member function names: Returns a list containing the names of all the member functions of a class object
+        Required argument: must be a class object
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: undocumented, typecode 'list'
+        """
+        _code = 'MMPR'
+        _subcode = 'MbFN'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def Get_nonsimple_classes(self, _no_object=None, _attributes={}, **_arguments):
+        """Get nonsimple classes: Returns an alphabetical list of classes with member functions, bases classes, or subclasses
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: undocumented, typecode 'list'
+        """
+        _code = 'MMPR'
+        _subcode = 'NsCl'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def Goto_Function(self, _object, _attributes={}, **_arguments):
+        """Goto Function: Goto Specified Function Name
+        Required argument: undocumented, typecode 'TEXT'
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'MMPR'
+        _subcode = 'GoFn'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def Goto_Line(self, _object, _attributes={}, **_arguments):
+        """Goto Line: Goto Specified Line Number
+        Required argument: The requested source file line number
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'MMPR'
+        _subcode = 'GoLn'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def Is_In_Project(self, _object, _attributes={}, **_arguments):
+        """Is In Project: Whether or not the specified file(s) is in the current project
+        Required argument: List of files to check for project membership
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: Result code for each file
+        """
+        _code = 'MMPR'
+        _subcode = 'FInP'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_Make_Project = {
+        'ExternalEditor' : 'Errs',
+    }
+
+    def Make_Project(self, _no_object=None, _attributes={}, **_arguments):
+        """Make Project: Make the current project
+        Keyword argument ExternalEditor: Should the contents of the message window be returned to the caller?
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: Errors that occurred while making the project
+        """
+        _code = 'MMPR'
+        _subcode = 'Make'
+
+        aetools.keysubst(_arguments, self._argmap_Make_Project)
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def Open_browser(self, _object, _attributes={}, **_arguments):
+        """Open browser: Display a class, member function, or data member object in a single class browser window
+        Required argument: an AE object reference
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'MMPR'
+        _subcode = 'Brow'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_Precompile = {
+        'Saving_As' : 'Targ',
+        'ExternalEditor' : 'Errs',
+    }
+
+    def Precompile(self, _object, _attributes={}, **_arguments):
+        """Precompile: Precompile the specified file to the specified destination file
+        Required argument: File to precompile
+        Keyword argument Saving_As: Destination file for precompiled header
+        Keyword argument ExternalEditor: Should the contents of the message window be returned to the caller?
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: Errors for the precompiled file
+        """
+        _code = 'MMPR'
+        _subcode = 'PreC'
+
+        aetools.keysubst(_arguments, self._argmap_Precompile)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_Preprocess = {
+        'ExternalEditor' : 'Errs',
+    }
+
+    def Preprocess(self, _object, _attributes={}, **_arguments):
+        """Preprocess: Preprocesses the specified file(s)
+        Required argument: undocumented, typecode 'alis'
+        Keyword argument ExternalEditor: undocumented, typecode 'bool'
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: Errors for each preprocessed file
+        """
+        _code = 'MMPR'
+        _subcode = 'PreP'
+
+        aetools.keysubst(_arguments, self._argmap_Preprocess)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def Remove_Binaries(self, _no_object=None, _attributes={}, **_arguments):
+        """Remove Binaries: Remove the binary object code from the current project
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'MMPR'
+        _subcode = 'RemB'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def Remove_Files(self, _object, _attributes={}, **_arguments):
+        """Remove Files: Remove the specified file(s) from the current project
+        Required argument: List of files to remove
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: Error code for each file removed
+        """
+        _code = 'MMPR'
+        _subcode = 'RemF'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def Reset_File_Paths(self, _no_object=None, _attributes={}, **_arguments):
+        """Reset File Paths: Resets access paths for all files belonging to open project.
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'MMPR'
+        _subcode = 'ReFP'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_Run_Project = {
+        'ExternalEditor' : 'Errs',
+        'SourceDebugger' : 'DeBg',
+    }
+
+    def Run_Project(self, _no_object=None, _attributes={}, **_arguments):
+        """Run Project: Run the current project
+        Keyword argument ExternalEditor: Should the contents of the message window be returned to the caller?
+        Keyword argument SourceDebugger: Run the application under the control of the source-level debugger
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: Errors that occurred when running the project
+        """
+        _code = 'MMPR'
+        _subcode = 'RunP'
+
+        aetools.keysubst(_arguments, self._argmap_Run_Project)
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def Save_Error_Window_As(self, _object, _attributes={}, **_arguments):
+        """Save Error Window As: Saves the Errors & Warnings window as a text file
+        Required argument: Destination file for Save Message Window As
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'MMPR'
+        _subcode = 'SvMs'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def Set_Current_Target(self, _object=None, _attributes={}, **_arguments):
+        """Set Current Target: Set the current target of a project
+        Required argument: Name of target
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'MMPR'
+        _subcode = 'STrg'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def Set_Default_Project(self, _object, _attributes={}, **_arguments):
+        """Set Default Project: Set the default project
+        Required argument: Name of project
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'MMPR'
+        _subcode = 'SDfP'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_Set_Modification_Date = {
+        'to' : 'MDat',
+    }
+
+    def Set_Modification_Date(self, _object, _attributes={}, **_arguments):
+        """Set Modification Date: Changes the internal modification date of the specified file(s)
+        Required argument: List of files
+        Keyword argument to: undocumented, typecode 'ldt '
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: Error code for each modified file
+        """
+        _code = 'MMPR'
+        _subcode = 'SMod'
+
+        aetools.keysubst(_arguments, self._argmap_Set_Modification_Date)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_Set_Preferences = {
+        'of_panel' : 'PNam',
+        'to' : 'PRec',
+    }
+
+    def Set_Preferences(self, _no_object=None, _attributes={}, **_arguments):
+        """Set Preferences: Set the preferences for the current project
+        Keyword argument of_panel: Name of the preference panel
+        Keyword argument to: Preferences settings
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'MMPR'
+        _subcode = 'Pref'
+
+        aetools.keysubst(_arguments, self._argmap_Set_Preferences)
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_Set_Project_File = {
+        'to' : 'SrcS',
+    }
+
+    def Set_Project_File(self, _object, _attributes={}, **_arguments):
+        """Set Project File: Changes the settings for a given file in the project.
+        Required argument: The name of the file
+        Keyword argument to: The new settings for the file
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'MMPR'
+        _subcode = 'SFil'
+
+        aetools.keysubst(_arguments, self._argmap_Set_Project_File)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_Set_Segment = {
+        'to' : 'Segm',
+    }
+
+    def Set_Segment(self, _object, _attributes={}, **_arguments):
+        """Set Segment: Changes the name and attributes of a segment.
+        Required argument: The segment to change
+        Keyword argument to: The new name and attributes for the segment.
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'MMPR'
+        _subcode = 'SSeg'
+
+        aetools.keysubst(_arguments, self._argmap_Set_Segment)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def Touch(self, _object, _attributes={}, **_arguments):
+        """Touch: Force recompilation of the specified file(s)
+        Required argument: List of files to compile
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: Error code for each file touched
+        """
+        _code = 'MMPR'
+        _subcode = 'Toch'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_Update_Project = {
+        'ExternalEditor' : 'Errs',
+    }
+
+    def Update_Project(self, _no_object=None, _attributes={}, **_arguments):
+        """Update Project: Update the current project
+        Keyword argument ExternalEditor: Should the contents of the message window be returned to the caller?
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: Errors that occurred while updating the project
+        """
+        _code = 'MMPR'
+        _subcode = 'UpdP'
+
+        aetools.keysubst(_arguments, self._argmap_Update_Project)
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+
+class Browser_Coloring(aetools.ComponentItem):
+    """Browser Coloring - Colors for Browser symbols. """
+    want = 'BRKW'
+class _Prop_Browser_Keywords(aetools.NProperty):
+    """Browser Keywords - Mark Browser symbols with color. """
+    which = 'BW00'
+    want = 'bool'
+class _Prop_Classes_Color(aetools.NProperty):
+    """Classes Color - The color for classes. """
+    which = 'BW01'
+    want = 'cRGB'
+class _Prop_Constants_Color(aetools.NProperty):
+    """Constants Color - The color for constants. """
+    which = 'BW02'
+    want = 'cRGB'
+class _Prop_Enums_Color(aetools.NProperty):
+    """Enums Color - The color for enums. """
+    which = 'BW03'
+    want = 'cRGB'
+class _Prop_Functions_Color(aetools.NProperty):
+    """Functions Color - Set color for functions. """
+    which = 'BW04'
+    want = 'cRGB'
+class _Prop_Globals_Color(aetools.NProperty):
+    """Globals Color - The color for globals """
+    which = 'BW05'
+    want = 'cRGB'
+class _Prop_Macros_Color(aetools.NProperty):
+    """Macros Color - The color for macros. """
+    which = 'BW06'
+    want = 'cRGB'
+class _Prop_Template_Commands_in_Menu(aetools.NProperty):
+    """Template Commands in Menu - Include template commands in context menus """
+    which = 'BW10'
+    want = 'bool'
+class _Prop_Templates_Color(aetools.NProperty):
+    """Templates Color - Set color for templates. """
+    which = 'BW07'
+    want = 'cRGB'
+class _Prop_Typedefs_Color(aetools.NProperty):
+    """Typedefs Color - The color for typedefs. """
+    which = 'BW08'
+    want = 'cRGB'
+
+class Build_Settings(aetools.ComponentItem):
+    """Build Settings - Build Settings preferences. """
+    want = 'BSTG'
+class _Prop_Build_Before_Running(aetools.NProperty):
+    """Build Before Running - Build the target before running. """
+    which = 'BX04'
+    want = 'BXbr'
+class _Prop_Compiler_Thread_Stack_Size(aetools.NProperty):
+    """Compiler Thread Stack Size - Compiler Thread Stack Size """
+    which = 'BX06'
+    want = 'long'
+class _Prop_Completion_Sound(aetools.NProperty):
+    """Completion Sound - Play a sound when finished a Bring Up To Date or Make command. """
+    which = 'BX01'
+    want = 'bool'
+class _Prop_Failure_Sound(aetools.NProperty):
+    """Failure Sound - The sound CodeWarrior plays when it cannot finish a Bring Up To Date or Make command. """
+    which = 'BX03'
+    want = 'TEXT'
+class _Prop_Include_Cache_Size(aetools.NProperty):
+    """Include Cache Size - Include file cache size. """
+    which = 'BX05'
+    want = 'long'
+class _Prop_Save_Before_Building(aetools.NProperty):
+    """Save Before Building - Save open editor files before build operations """
+    which = 'BX07'
+    want = 'bool'
+class _Prop_Success_Sound(aetools.NProperty):
+    """Success Sound - The sound CodeWarrior plays when it successfully finishes a Bring Up To Date or Make command. """
+    which = 'BX02'
+    want = 'TEXT'
+
+class base_class(aetools.ComponentItem):
+    """base class - A base class or super class of a class """
+    want = 'BsCl'
+class _Prop_access(aetools.NProperty):
+    """access -  """
+    which = 'Acce'
+    want = 'Acce'
+class _Prop_class_(aetools.NProperty):
+    """class - The class object corresponding to this base class """
+    which = 'Clas'
+    want = 'obj '
+class _Prop_virtual(aetools.NProperty):
+    """virtual -  """
+    which = 'Virt'
+    want = 'bool'
+
+base_classes = base_class
+
+class Custom_Keywords(aetools.ComponentItem):
+    """Custom Keywords -  """
+    want = 'CUKW'
+class _Prop_Custom_Color_1(aetools.NProperty):
+    """Custom Color 1 - The color for the first set of custom keywords. """
+    which = 'GH05'
+    want = 'cRGB'
+class _Prop_Custom_Color_2(aetools.NProperty):
+    """Custom Color 2 - The color for the second set custom keywords. """
+    which = 'GH06'
+    want = 'cRGB'
+class _Prop_Custom_Color_3(aetools.NProperty):
+    """Custom Color 3 - The color for the third set of custom keywords. """
+    which = 'GH07'
+    want = 'cRGB'
+class _Prop_Custom_Color_4(aetools.NProperty):
+    """Custom Color 4 - The color for the fourth set of custom keywords. """
+    which = 'GH08'
+    want = 'cRGB'
+
+class browser_catalog(aetools.ComponentItem):
+    """browser catalog - The browser symbol catalog for the current project """
+    want = 'Cata'
+#        element 'Clas' as ['indx', 'name']
+
+class class_(aetools.ComponentItem):
+    """class - A class, struct, or record type in the current project. """
+    want = 'Clas'
+class _Prop_all_subclasses(aetools.NProperty):
+    """all subclasses - the classes directly or indirectly derived from this class """
+    which = 'SubA'
+    want = 'Clas'
+class _Prop_declaration_end_offset(aetools.NProperty):
+    """declaration end offset - End of class declaration """
+    which = 'DcEn'
+    want = 'long'
+class _Prop_declaration_file(aetools.NProperty):
+    """declaration file - Source file containing the class declaration """
+    which = 'DcFl'
+    want = 'fss '
+class _Prop_declaration_start_offset(aetools.NProperty):
+    """declaration start offset - Start of class declaration source code """
+    which = 'DcSt'
+    want = 'long'
+class _Prop_language(aetools.NProperty):
+    """language - Implementation language of this class """
+    which = 'Lang'
+    want = 'Lang'
+class _Prop_name(aetools.NProperty):
+    """name -  """
+    which = 'pnam'
+    want = 'TEXT'
+class _Prop_subclasses(aetools.NProperty):
+    """subclasses - the immediate subclasses of this class """
+    which = 'SubC'
+    want = 'Clas'
+#        element 'BsCl' as ['indx']
+#        element 'DtMb' as ['indx', 'name']
+#        element 'MbFn' as ['indx', 'name']
+
+classes = class_
+
+class Debugger_Display(aetools.ComponentItem):
+    """Debugger Display - Debugger Display preferences """
+    want = 'DbDS'
+class _Prop_Default_Array_Size(aetools.NProperty):
+    """Default Array Size - Controls whether CodeWarrior uses its own integrated editor or an external application for editing text files. """
+    which = 'Db08'
+    want = 'shor'
+class _Prop_Show_As_Decimal(aetools.NProperty):
+    """Show As Decimal - Show variable values as decimal by default """
+    which = 'Db10'
+    want = 'bool'
+class _Prop_Show_Locals(aetools.NProperty):
+    """Show Locals - Show locals by default """
+    which = 'Db09'
+    want = 'bool'
+class _Prop_Show_Variable_Types(aetools.NProperty):
+    """Show Variable Types - Show variable types by default. """
+    which = 'Db01'
+    want = 'bool'
+class _Prop_Sort_By_Method(aetools.NProperty):
+    """Sort By Method - Sort functions by method. """
+    which = 'Db02'
+    want = 'bool'
+class _Prop_Threads_in_Window(aetools.NProperty):
+    """Threads in Window - Show threads in separate windows. """
+    which = 'Db04'
+    want = 'bool'
+class _Prop_Use_RTTI(aetools.NProperty):
+    """Use RTTI - Enable RunTime Type Information. """
+    which = 'Db03'
+    want = 'bool'
+class _Prop_Variable_Changed_Hilite(aetools.NProperty):
+    """Variable Changed Hilite - Variable changed hilite color. """
+    which = 'Db07'
+    want = 'cRGB'
+class _Prop_Variable_Hints(aetools.NProperty):
+    """Variable Hints - Show variable hints. """
+    which = 'Db05'
+    want = 'bool'
+class _Prop_Watchpoint_Hilite(aetools.NProperty):
+    """Watchpoint Hilite - Watchpoint hilite color. """
+    which = 'Db06'
+    want = 'cRGB'
+
+class Debugger_Global(aetools.ComponentItem):
+    """Debugger Global - Debugger Global preferences """
+    want = 'DbGL'
+class _Prop_Auto_Target_Libraries(aetools.NProperty):
+    """Auto Target Libraries - Automatically target libraries when debugging """
+    which = 'Dg11'
+    want = 'bool'
+class _Prop_Cache_Edited_Files(aetools.NProperty):
+    """Cache Edited Files - Cache edit files between debug sessions """
+    which = 'Dg12'
+    want = 'bool'
+class _Prop_Confirm_Kill(aetools.NProperty):
+    """Confirm Kill - Confirm the \xd4killing\xd5 of the process. """
+    which = 'Dg04'
+    want = 'bool'
+class _Prop_Dont_Step_in_Runtime(aetools.NProperty):
+    """Dont Step in Runtime - Don\xd5t step into runtime code when debugging. """
+    which = 'Dg07'
+    want = 'bool'
+class _Prop_File_Cache_Duration(aetools.NProperty):
+    """File Cache Duration - Duration to keep files in cache (in days) """
+    which = 'Dg13'
+    want = 'shor'
+class _Prop_Ignore_Mod_Dates(aetools.NProperty):
+    """Ignore Mod Dates - Ignore modification dates of files. """
+    which = 'Dg01'
+    want = 'bool'
+class _Prop_Launch_Apps_on_Open(aetools.NProperty):
+    """Launch Apps on Open - Launch applications on the opening of sym files. """
+    which = 'Dg03'
+    want = 'bool'
+class _Prop_Open_All_Classes(aetools.NProperty):
+    """Open All Classes - Open all Java class files. """
+    which = 'Dg02'
+    want = 'bool'
+class _Prop_Select_Stack_Crawl(aetools.NProperty):
+    """Select Stack Crawl - Select the stack crawl. """
+    which = 'Dg06'
+    want = 'bool'
+class _Prop_Stop_at_Main(aetools.NProperty):
+    """Stop at Main - Stop to debug on the main() function. """
+    which = 'Dg05'
+    want = 'bool'
+
+class Debugger_Target(aetools.ComponentItem):
+    """Debugger Target - Debugger Target preferences """
+    want = 'DbTG'
+class _Prop_Cache_symbolics(aetools.NProperty):
+    """Cache symbolics - Cache symbolics between runs when executable doesn\xd5t change, else release symbolics files after killing process. """
+    which = 'Dt15'
+    want = 'bool'
+class _Prop_Data_Update_Interval(aetools.NProperty):
+    """Data Update Interval - How often to update the data while running (in seconds) """
+    which = 'Dt09'
+    want = 'long'
+class _Prop_Log_System_Messages(aetools.NProperty):
+    """Log System Messages - Log all system messages while debugging. """
+    which = 'Dt02'
+    want = 'bool'
+class _Prop_Relocated_Executable_Path(aetools.NProperty):
+    """Relocated Executable Path - Path to location of relocated libraries, code resources or remote debugging folder """
+    which = 'Dt10'
+    want = 'RlPt'
+class _Prop_Stop_at_temp_breakpoint(aetools.NProperty):
+    """Stop at temp breakpoint - Stop at a temp breakpoint on program launch. Set breakpoint type in Temp Breakpoint Type AppleEvent. """
+    which = 'Dt13'
+    want = 'bool'
+class _Prop_Temp_Breakpoint_Type(aetools.NProperty):
+    """Temp Breakpoint Type - Type of temp breakpoint to set on program launch. """
+    which = 'Dt16'
+    want = 'TmpB'
+class _Prop_Temp_breakpoint_names(aetools.NProperty):
+    """Temp breakpoint names - Comma separated list of names to attempt to stop at on program launch. First symbol to resolve in list is the temp BP that will be set. """
+    which = 'Dt14'
+    want = 'ctxt'
+class _Prop_Update_Data_While_Running(aetools.NProperty):
+    """Update Data While Running - Should pause to update data while running """
+    which = 'Dt08'
+    want = 'bool'
+
+class Debugger_Windowing(aetools.ComponentItem):
+    """Debugger Windowing -  """
+    want = 'DbWN'
+class _Prop_Debugging_Start_Action(aetools.NProperty):
+    """Debugging Start Action - What action to take when debug session starts """
+    which = 'Dw01'
+    want = 'DbSA'
+class _Prop_Do_Nothing_To_Projects(aetools.NProperty):
+    """Do Nothing To Projects - Suppress debugging start action for project windows """
+    which = 'Dw02'
+    want = 'bool'
+
+class data_member(aetools.ComponentItem):
+    """data member - A class data member or field """
+    want = 'DtMb'
+class _Prop_static(aetools.NProperty):
+    """static -  """
+    which = 'Stat'
+    want = 'bool'
+
+data_members = data_member
+
+class Editor(aetools.ComponentItem):
+    """Editor -  """
+    want = 'EDTR'
+class _Prop_Background_Color(aetools.NProperty):
+    """Background Color - Color of the background of editor windows. """
+    which = 'ED13'
+    want = 'cRGB'
+class _Prop_Balance(aetools.NProperty):
+    """Balance - Flash the matching opening bracket when you type a closing bracket. """
+    which = 'ED03'
+    want = 'bool'
+class _Prop_Context_Popup_Delay(aetools.NProperty):
+    """Context Popup Delay - The amount of time, in sixtieths of a second, before the context popup is displayed if you click and hold on a browser symbol. """
+    which = 'ED14'
+    want = 'long'
+class _Prop_Default_Text_File_Format(aetools.NProperty):
+    """Default Text File Format - Default text file format (i.e. which type of line endings to use) """
+    which = 'ED17'
+    want = 'TxtF'
+class _Prop_Dynamic_Scroll(aetools.NProperty):
+    """Dynamic Scroll - Display a window\xd5s contents as you move the scroll box. """
+    which = 'ED02'
+    want = 'bool'
+class _Prop_Flash_Delay(aetools.NProperty):
+    """Flash Delay - The amount of time, in sixtieths of a second, the editor highlights a matching bracket. """
+    which = 'ED01'
+    want = 'long'
+class _Prop_Left_Margin_Line_Select(aetools.NProperty):
+    """Left Margin Line Select - Clicking in the left margin selects lines """
+    which = 'ED16'
+    want = 'bool'
+class _Prop_Main_Text_Color(aetools.NProperty):
+    """Main Text Color - Main, default, color for text. """
+    which = 'ED12'
+    want = 'cRGB'
+class _Prop_Relaxed_C_Popup_Parsing(aetools.NProperty):
+    """Relaxed C Popup Parsing - Relax the function parser for C source files """
+    which = 'ED15'
+    want = 'bool'
+class _Prop_Remember_Font(aetools.NProperty):
+    """Remember Font - Display a source file with its own font settings. """
+    which = 'ED08'
+    want = 'bool'
+class _Prop_Remember_Selection(aetools.NProperty):
+    """Remember Selection - Restore the previous selection in a file when you open it. """
+    which = 'ED09'
+    want = 'bool'
+class _Prop_Remember_Window(aetools.NProperty):
+    """Remember Window - Restore the last size and position for a source file window when you open it. """
+    which = 'ED10'
+    want = 'bool'
+class _Prop_Sort_Function_Popup(aetools.NProperty):
+    """Sort Function Popup -  """
+    which = 'ED06'
+    want = 'bool'
+class _Prop_Use_Drag__26__Drop_Editing(aetools.NProperty):
+    """Use Drag & Drop Editing - Use Drag & Drop text editing. """
+    which = 'ED04'
+    want = 'bool'
+class _Prop_Use_Multiple_Undo(aetools.NProperty):
+    """Use Multiple Undo -  """
+    which = 'ED07'
+    want = 'bool'
+
+class Environment_Variable(aetools.ComponentItem):
+    """Environment Variable - Environment variable for host OS """
+    want = 'EnvV'
+class _Prop_value(aetools.NProperty):
+    """value - Value of the environment variable """
+    which = 'Valu'
+    want = 'TEXT'
+
+class Error_Information(aetools.ComponentItem):
+    """Error Information - Describes a single error or warning from the compiler or the linker. """
+    want = 'ErrM'
+class _Prop_disk_file(aetools.NProperty):
+    """disk file - The file where the error occurred.  May not be returned for certain kinds of errors (eg, link errors). """
+    which = 'file'
+    want = 'fss '
+class _Prop_lineNumber(aetools.NProperty):
+    """lineNumber - The line in the file where the error occurred.  May not be returned for certain kinds of errors (eg, link errors). """
+    which = 'ErrL'
+    want = 'long'
+class _Prop_message(aetools.NProperty):
+    """message - The error or warning message. """
+    which = 'ErrS'
+    want = 'TEXT'
+class _Prop_messageKind(aetools.NProperty):
+    """messageKind - The type of error or warning. """
+    which = 'ErrT'
+    want = 'ErrT'
+
+class Function_Information(aetools.ComponentItem):
+    """Function Information - Describes the location of any function or global data definition within the current project. """
+    want = 'FDef'
+
+class File_Mappings(aetools.ComponentItem):
+    """File Mappings - Mappings of extensions & file types to compilers """
+    want = 'FLMP'
+class _Prop_Mappings(aetools.NProperty):
+    """Mappings -  """
+    which = 'FMps'
+    want = 'FMap'
+
+class File_Mapping(aetools.ComponentItem):
+    """File Mapping -  """
+    want = 'FMap'
+class _Prop_Compiler(aetools.NProperty):
+    """Compiler -  """
+    which = 'TA07'
+    want = 'TEXT'
+class _Prop_Extension(aetools.NProperty):
+    """Extension -  """
+    which = 'TA02'
+    want = 'TEXT'
+class _Prop_File_Type(aetools.NProperty):
+    """File Type -  """
+    which = 'PR04'
+    want = 'TEXT'
+class _Prop_Ignored_by_Make(aetools.NProperty):
+    """Ignored by Make -  """
+    which = 'TA06'
+    want = 'bool'
+class _Prop_Launchable(aetools.NProperty):
+    """Launchable -  """
+    which = 'TA05'
+    want = 'bool'
+class _Prop_Precompiled(aetools.NProperty):
+    """Precompiled -  """
+    which = 'TA03'
+    want = 'bool'
+class _Prop_Resource_File(aetools.NProperty):
+    """Resource File -  """
+    which = 'TA04'
+    want = 'bool'
+
+class Global_Source_Trees(aetools.ComponentItem):
+    """Global Source Trees - Globally-defined source tree roots """
+    want = 'GSTs'
+class _Prop_Source_Trees(aetools.NProperty):
+    """Source Trees - List of source tree roots """
+    which = 'ST01'
+    want = 'SrcT'
+
+class Extras(aetools.ComponentItem):
+    """Extras -  """
+    want = 'GXTR'
+class _Prop_Automatic_Toolbar_Help(aetools.NProperty):
+    """Automatic Toolbar Help - Automatically show balloon help in toolbar after delay """
+    which = 'EX19'
+    want = 'bool'
+class _Prop_External_Reference(aetools.NProperty):
+    """External Reference - Which on-line function reference to use. """
+    which = 'EX08'
+    want = 'RefP'
+class _Prop_Full_Screen_Zoom(aetools.NProperty):
+    """Full Screen Zoom - Zoom windows to the full screen width. """
+    which = 'EX07'
+    want = 'bool'
+class _Prop_Recent_Editor_Count(aetools.NProperty):
+    """Recent Editor Count - Maximum number of editor documents to show in the \xd2Open Recent\xd3 menu """
+    which = 'EX16'
+    want = 'shor'
+class _Prop_Recent_Project_Count(aetools.NProperty):
+    """Recent Project Count - Maximum number of project documents to show in the \xd2Open Recent\xd3 menu """
+    which = 'EX17'
+    want = 'shor'
+class _Prop_Use_Editor_Extensions(aetools.NProperty):
+    """Use Editor Extensions - Controls the use of the Editor Extensions menu """
+    which = 'EX10'
+    want = 'bool'
+class _Prop_Use_External_Editor(aetools.NProperty):
+    """Use External Editor - Controls whether CodeWarrior uses its own integrated editor or an external application for editing text files. """
+    which = 'EX11'
+    want = 'bool'
+class _Prop_Use_Script_Menu(aetools.NProperty):
+    """Use Script Menu - Controls the use of the AppleScript menu """
+    which = 'EX12'
+    want = 'bool'
+class _Prop_Use_ToolServer_Menu(aetools.NProperty):
+    """Use ToolServer Menu - Controls the use of the ToolServer menu """
+    which = 'EX18'
+    want = 'bool'
+
+class Build_Extras(aetools.ComponentItem):
+    """Build Extras -  """
+    want = 'LXTR'
+class _Prop_Browser_Active(aetools.NProperty):
+    """Browser Active - Allow the collection of browser information. """
+    which = 'EX09'
+    want = 'bool'
+class _Prop_Cache_Subproject_Data(aetools.NProperty):
+    """Cache Subproject Data -  """
+    which = 'EX31'
+    want = 'bool'
+class _Prop_Dump_Browser_Info(aetools.NProperty):
+    """Dump Browser Info -  """
+    which = 'EX30'
+    want = 'bool'
+class _Prop_Modification_Date_Caching(aetools.NProperty):
+    """Modification Date Caching -  """
+    which = 'EX04'
+    want = 'bool'
+
+class member_function(aetools.ComponentItem):
+    """member function - A class member function or method. """
+    want = 'MbFn'
+class _Prop_implementation_end_offset(aetools.NProperty):
+    """implementation end offset - end of member function definition """
+    which = 'DfEn'
+    want = 'long'
+class _Prop_implementation_file(aetools.NProperty):
+    """implementation file - Source file containing the member function definition """
+    which = 'DfFl'
+    want = 'fss '
+class _Prop_implementation_start_offset(aetools.NProperty):
+    """implementation start offset - start of member function definition source code """
+    which = 'DfSt'
+    want = 'long'
+
+member_functions = member_function
+
+class Access_Paths(aetools.ComponentItem):
+    """Access Paths - Contains the definitions of a project\xd5s access (search) paths. """
+    want = 'PATH'
+class _Prop_Always_Full_Search(aetools.NProperty):
+    """Always Full Search - To force the compiler to search for system includes like it searches for user includes. """
+    which = 'PA02'
+    want = 'bool'
+class _Prop_Convert_Paths(aetools.NProperty):
+    """Convert Paths - Enables conversion of DOS & Unix-style relative paths when searching for files. """
+    which = 'PA04'
+    want = 'bool'
+class _Prop_Require_Framework_Includes(aetools.NProperty):
+    """Require Framework Includes - Causes the IDE to only look in the framework access paths if a Mac OS X framework style include (i.e. <Carbon/Carbon.h> ) is used. """
+    which = 'PA05'
+    want = 'bool'
+class _Prop_System_Paths(aetools.NProperty):
+    """System Paths - To add an access path for the include files. (Not supported in Pascal) """
+    which = 'PA03'
+    want = 'PInf'
+class _Prop_User_Paths(aetools.NProperty):
+    """User Paths - To add an access path for the source files. """
+    which = 'PA01'
+    want = 'PInf'
+
+class Path_Information(aetools.ComponentItem):
+    """Path Information - Contains all of the parameters that describe an access path. """
+    want = 'PInf'
+class _Prop_format(aetools.NProperty):
+    """format - Format of the a """
+    which = 'Frmt'
+    want = 'PthF'
+class _Prop_framework(aetools.NProperty):
+    """framework - Is the path a Mac OS X framework style path?  (This flag is readable but not writeable from AppleScript.) """
+    which = 'Frmw'
+    want = 'bool'
+class _Prop_host_flags(aetools.NProperty):
+    """host flags - Bit fields enabling the access path for each host OS (1 = Mac OS, 2 = Windows) """
+    which = 'HstF'
+    want = 'long'
+class _Prop_origin(aetools.NProperty):
+    """origin -  """
+    which = 'Orig'
+    want = 'PPrm'
+class _Prop_recursive(aetools.NProperty):
+    """recursive - Will the path be searched recursively?  (Default is true) """
+    which = 'Recu'
+    want = 'bool'
+class _Prop_root(aetools.NProperty):
+    """root - Name of the root of the relative path. Pre-defined values are \xd2Absolute\xd3, \xd2Project\xd3, \xd2CodeWarrior\xd3, and  \xd2System\xd3. Anything else is a user-defined root. """
+    which = 'Root'
+    want = 'TEXT'
+
+class Plugin_Settings(aetools.ComponentItem):
+    """Plugin Settings - Settings for plugin tools """
+    want = 'PSTG'
+class _Prop_Disable_Third_Party_COM_Plugins(aetools.NProperty):
+    """Disable Third Party COM Plugins - Disable COM plugins from third parties """
+    which = 'PX02'
+    want = 'bool'
+class _Prop_Plugin_Diagnostics_Level(aetools.NProperty):
+    """Plugin Diagnostics Level - Plugin Diagnostics Level is for those who are developing plugins for the IDE and need to debug them. """
+    which = 'PX01'
+    want = 'PXdg'
+
+class Runtime_Settings(aetools.ComponentItem):
+    """Runtime Settings - Runtime settings """
+    want = 'RSTG'
+class _Prop_Command_Line_Arguments(aetools.NProperty):
+    """Command Line Arguments - Extra command line args to pass to executable """
+    which = 'RS02'
+    want = 'TEXT'
+class _Prop_Environment_Variables(aetools.NProperty):
+    """Environment Variables - Environment variables to use when running the executable """
+    which = 'RS04'
+    want = 'EnvV'
+class _Prop_Host_Application(aetools.NProperty):
+    """Host Application - Host application for running/debugging libraries and code resources """
+    which = 'RS01'
+    want = 'RlPt'
+class _Prop_Working_Directory(aetools.NProperty):
+    """Working Directory - Working directory to use when running the executable """
+    which = 'RS03'
+    want = 'TEXT'
+
+class Relative_Path(aetools.ComponentItem):
+    """Relative Path - Relative path from some root """
+    want = 'RlPt'
+
+class Shielded_Folder(aetools.ComponentItem):
+    """Shielded Folder -  """
+    want = 'SFit'
+class _Prop_Expression_To_Match(aetools.NProperty):
+    """Expression To Match - Regular expression which describes folders to skip """
+    which = 'SF01'
+    want = 'TEXT'
+class _Prop_Skip_Find_And_Compare_Operations(aetools.NProperty):
+    """Skip Find And Compare Operations - Matching folders will be skipped during find and compare operations """
+    which = 'SF03'
+    want = 'bool'
+class _Prop_Skip_Project_Operations(aetools.NProperty):
+    """Skip Project Operations - Matching folders will be skipped during project operations """
+    which = 'SF02'
+    want = 'bool'
+
+class Shielded_Folders(aetools.ComponentItem):
+    """Shielded Folders - Folders skipped when performing project and find-and-compare operations """
+    want = 'SHFL'
+class _Prop_Shielded_Items(aetools.NProperty):
+    """Shielded Items -  """
+    which = 'SFis'
+    want = 'SFit'
+
+class Syntax_Coloring(aetools.ComponentItem):
+    """Syntax Coloring -  """
+    want = 'SNTX'
+class _Prop_Comment_Color(aetools.NProperty):
+    """Comment Color - The color for comments. """
+    which = 'GH02'
+    want = 'cRGB'
+class _Prop_Keyword_Color(aetools.NProperty):
+    """Keyword Color - The color for language keywords. """
+    which = 'GH03'
+    want = 'cRGB'
+class _Prop_String_Color(aetools.NProperty):
+    """String Color - The color for strings. """
+    which = 'GH04'
+    want = 'cRGB'
+class _Prop_Syntax_Coloring(aetools.NProperty):
+    """Syntax Coloring - Mark keywords and comments with color. """
+    which = 'GH01'
+    want = 'bool'
+
+class Segment(aetools.ComponentItem):
+    """Segment - A segment or group in the project """
+    want = 'Seg '
+class _Prop_filecount(aetools.NProperty):
+    """filecount -  """
+    which = 'NumF'
+    want = 'shor'
+class _Prop_seg_2d_locked(aetools.NProperty):
+    """seg-locked - Is the segment locked ? [68K only] """
+    which = 'PLck'
+    want = 'bool'
+class _Prop_seg_2d_preloaded(aetools.NProperty):
+    """seg-preloaded - Is the segment preloaded ? [68K only] """
+    which = 'Prel'
+    want = 'bool'
+class _Prop_seg_2d_protected(aetools.NProperty):
+    """seg-protected - Is the segment protected ? [68K only] """
+    which = 'Prot'
+    want = 'bool'
+class _Prop_seg_2d_purgeable(aetools.NProperty):
+    """seg-purgeable - Is the segment purgeable ? [68K only] """
+    which = 'Purg'
+    want = 'bool'
+class _Prop_seg_2d_system_heap(aetools.NProperty):
+    """seg-system heap - Is the segment loaded into the system heap ? [68K only] """
+    which = 'SysH'
+    want = 'bool'
+
+class ProjectFile(aetools.ComponentItem):
+    """ProjectFile - A file contained in a project """
+    want = 'SrcF'
+class _Prop_codesize(aetools.NProperty):
+    """codesize - The size of this file\xd5s code. """
+    which = 'CSiz'
+    want = 'long'
+class _Prop_datasize(aetools.NProperty):
+    """datasize - The size of this file\xd5s data. """
+    which = 'DSiz'
+    want = 'long'
+class _Prop_filetype(aetools.NProperty):
+    """filetype - What kind of file is this ? """
+    which = 'SrcT'
+    want = 'SrcT'
+class _Prop_includes(aetools.NProperty):
+    """includes -  """
+    which = 'IncF'
+    want = 'fss '
+class _Prop_initialize_before(aetools.NProperty):
+    """initialize before - Initialize the shared library before the main application. """
+    which = 'Bfor'
+    want = 'bool'
+class _Prop_symbols(aetools.NProperty):
+    """symbols - Are debugging symbols generated for this file ? """
+    which = 'SymG'
+    want = 'bool'
+class _Prop_up_to_date(aetools.NProperty):
+    """up to date - Has the file been compiled since its last modification ? """
+    which = 'UpTD'
+    want = 'bool'
+class _Prop_weak_link(aetools.NProperty):
+    """weak link - Is this file imported weakly into the project ? [PowerPC only] """
+    which = 'Weak'
+    want = 'bool'
+
+class Source_Tree(aetools.ComponentItem):
+    """Source Tree - User-defined source tree root """
+    want = 'SrcT'
+class _Prop_path(aetools.NProperty):
+    """path - path for the user-defined source tree root """
+    which = 'Path'
+    want = 'TEXT'
+class _Prop_path_kind(aetools.NProperty):
+    """path kind - kind of path """
+    which = 'Kind'
+    want = 'STKd'
+
+class Target_Settings(aetools.ComponentItem):
+    """Target Settings - Contains the definitions of a project\xd5s target. """
+    want = 'TARG'
+class _Prop_Linker(aetools.NProperty):
+    """Linker - The name of the current linker. """
+    which = 'TA01'
+    want = 'TEXT'
+class _Prop_Output_Directory_Location(aetools.NProperty):
+    """Output Directory Location - Location of output directory """
+    which = 'TA16'
+    want = 'RlPt'
+class _Prop_Output_Directory_Origin(aetools.NProperty):
+    """Output Directory Origin - Origin of path to output directory. Usage of this property is deprecated. Use the \xd2Output Directory Location\xd3 property instead. """
+    which = 'TA12'
+    want = 'PPrm'
+class _Prop_Output_Directory_Path(aetools.NProperty):
+    """Output Directory Path - Path to output directory. Usage of this property is deprecated. Use the \xd2Output Directory Location\xd3 property instead. """
+    which = 'TA11'
+    want = 'TEXT'
+class _Prop_Post_Linker(aetools.NProperty):
+    """Post Linker -  """
+    which = 'TA09'
+    want = 'TEXT'
+class _Prop_Pre_Linker(aetools.NProperty):
+    """Pre Linker -  """
+    which = 'TA13'
+    want = 'TEXT'
+class _Prop_Target_Name(aetools.NProperty):
+    """Target Name -  """
+    which = 'TA10'
+    want = 'TEXT'
+class _Prop_Use_Relative_Paths(aetools.NProperty):
+    """Use Relative Paths - Save project entries using relative paths """
+    which = 'TA15'
+    want = 'bool'
+
+class Target_Source_Trees(aetools.ComponentItem):
+    """Target Source Trees - Target-specific user-defined source tree roots """
+    want = 'TSTs'
+
+class VCS_Setup(aetools.ComponentItem):
+    """VCS Setup - The version control system preferences. """
+    want = 'VCSs'
+class _Prop_Always_Prompt(aetools.NProperty):
+    """Always Prompt - Always show login dialog """
+    which = 'VC07'
+    want = 'bool'
+class _Prop_Auto_Connect(aetools.NProperty):
+    """Auto Connect - Automatically connect to database when starting. """
+    which = 'VC05'
+    want = 'bool'
+class _Prop_Connection_Method(aetools.NProperty):
+    """Connection Method - Name of Version Control System to use. """
+    which = 'VC02'
+    want = 'TEXT'
+class _Prop_Database_Path(aetools.NProperty):
+    """Database Path - Path to the VCS database. """
+    which = 'VC09'
+    want = 'RlPt'
+class _Prop_Local_Path(aetools.NProperty):
+    """Local Path - Path to the local root """
+    which = 'VC10'
+    want = 'RlPt'
+class _Prop_Mount_Volume(aetools.NProperty):
+    """Mount Volume - Attempt to mount the database volume if it isn't available. """
+    which = 'VC08'
+    want = 'bool'
+class _Prop_Password(aetools.NProperty):
+    """Password - The password for the VCS. """
+    which = 'VC04'
+    want = 'TEXT'
+class _Prop_Store_Password(aetools.NProperty):
+    """Store Password - Store the password. """
+    which = 'VC06'
+    want = 'bool'
+class _Prop_Use_Global_Settings(aetools.NProperty):
+    """Use Global Settings - Use the global VCS settings by default """
+    which = 'VC11'
+    want = 'bool'
+class _Prop_Username(aetools.NProperty):
+    """Username - The user name for the VCS. """
+    which = 'VC03'
+    want = 'TEXT'
+class _Prop_VCS_Active(aetools.NProperty):
+    """VCS Active - Use Version Control """
+    which = 'VC01'
+    want = 'bool'
+
+class Font(aetools.ComponentItem):
+    """Font -  """
+    want = 'mFNT'
+class _Prop_Auto_Indent(aetools.NProperty):
+    """Auto Indent - Indent new lines automatically. """
+    which = 'FN01'
+    want = 'bool'
+class _Prop_Tab_Indents_Selection(aetools.NProperty):
+    """Tab Indents Selection - Tab indents selection when multiple lines are selected """
+    which = 'FN03'
+    want = 'bool'
+class _Prop_Tab_Inserts_Spaces(aetools.NProperty):
+    """Tab Inserts Spaces - Insert spaces instead of tab character """
+    which = 'FN04'
+    want = 'bool'
+class _Prop_Tab_Size(aetools.NProperty):
+    """Tab Size -  """
+    which = 'FN02'
+    want = 'shor'
+class _Prop_Text_Font(aetools.NProperty):
+    """Text Font - The font used in editing windows. """
+    which = 'ptxf'
+    want = 'TEXT'
+class _Prop_Text_Size(aetools.NProperty):
+    """Text Size - The size of the text in an editing window. """
+    which = 'ptps'
+    want = 'shor'
+Browser_Coloring._superclassnames = []
+Browser_Coloring._privpropdict = {
+    'Browser_Keywords' : _Prop_Browser_Keywords,
+    'Classes_Color' : _Prop_Classes_Color,
+    'Constants_Color' : _Prop_Constants_Color,
+    'Enums_Color' : _Prop_Enums_Color,
+    'Functions_Color' : _Prop_Functions_Color,
+    'Globals_Color' : _Prop_Globals_Color,
+    'Macros_Color' : _Prop_Macros_Color,
+    'Template_Commands_in_Menu' : _Prop_Template_Commands_in_Menu,
+    'Templates_Color' : _Prop_Templates_Color,
+    'Typedefs_Color' : _Prop_Typedefs_Color,
+}
+Browser_Coloring._privelemdict = {
+}
+Build_Settings._superclassnames = []
+Build_Settings._privpropdict = {
+    'Build_Before_Running' : _Prop_Build_Before_Running,
+    'Compiler_Thread_Stack_Size' : _Prop_Compiler_Thread_Stack_Size,
+    'Completion_Sound' : _Prop_Completion_Sound,
+    'Failure_Sound' : _Prop_Failure_Sound,
+    'Include_Cache_Size' : _Prop_Include_Cache_Size,
+    'Save_Before_Building' : _Prop_Save_Before_Building,
+    'Success_Sound' : _Prop_Success_Sound,
+}
+Build_Settings._privelemdict = {
+}
+base_class._superclassnames = []
+base_class._privpropdict = {
+    'access' : _Prop_access,
+    'class_' : _Prop_class_,
+    'virtual' : _Prop_virtual,
+}
+base_class._privelemdict = {
+}
+Custom_Keywords._superclassnames = []
+Custom_Keywords._privpropdict = {
+    'Custom_Color_1' : _Prop_Custom_Color_1,
+    'Custom_Color_2' : _Prop_Custom_Color_2,
+    'Custom_Color_3' : _Prop_Custom_Color_3,
+    'Custom_Color_4' : _Prop_Custom_Color_4,
+}
+Custom_Keywords._privelemdict = {
+}
+browser_catalog._superclassnames = []
+browser_catalog._privpropdict = {
+}
+browser_catalog._privelemdict = {
+    'class_' : class_,
+}
+class_._superclassnames = []
+class_._privpropdict = {
+    'all_subclasses' : _Prop_all_subclasses,
+    'declaration_end_offset' : _Prop_declaration_end_offset,
+    'declaration_file' : _Prop_declaration_file,
+    'declaration_start_offset' : _Prop_declaration_start_offset,
+    'language' : _Prop_language,
+    'name' : _Prop_name,
+    'subclasses' : _Prop_subclasses,
+}
+class_._privelemdict = {
+    'base_class' : base_class,
+    'data_member' : data_member,
+    'member_function' : member_function,
+}
+Debugger_Display._superclassnames = []
+Debugger_Display._privpropdict = {
+    'Default_Array_Size' : _Prop_Default_Array_Size,
+    'Show_As_Decimal' : _Prop_Show_As_Decimal,
+    'Show_Locals' : _Prop_Show_Locals,
+    'Show_Variable_Types' : _Prop_Show_Variable_Types,
+    'Sort_By_Method' : _Prop_Sort_By_Method,
+    'Threads_in_Window' : _Prop_Threads_in_Window,
+    'Use_RTTI' : _Prop_Use_RTTI,
+    'Variable_Changed_Hilite' : _Prop_Variable_Changed_Hilite,
+    'Variable_Hints' : _Prop_Variable_Hints,
+    'Watchpoint_Hilite' : _Prop_Watchpoint_Hilite,
+}
+Debugger_Display._privelemdict = {
+}
+Debugger_Global._superclassnames = []
+Debugger_Global._privpropdict = {
+    'Auto_Target_Libraries' : _Prop_Auto_Target_Libraries,
+    'Cache_Edited_Files' : _Prop_Cache_Edited_Files,
+    'Confirm_Kill' : _Prop_Confirm_Kill,
+    'Dont_Step_in_Runtime' : _Prop_Dont_Step_in_Runtime,
+    'File_Cache_Duration' : _Prop_File_Cache_Duration,
+    'Ignore_Mod_Dates' : _Prop_Ignore_Mod_Dates,
+    'Launch_Apps_on_Open' : _Prop_Launch_Apps_on_Open,
+    'Open_All_Classes' : _Prop_Open_All_Classes,
+    'Select_Stack_Crawl' : _Prop_Select_Stack_Crawl,
+    'Stop_at_Main' : _Prop_Stop_at_Main,
+}
+Debugger_Global._privelemdict = {
+}
+Debugger_Target._superclassnames = []
+Debugger_Target._privpropdict = {
+    'Auto_Target_Libraries' : _Prop_Auto_Target_Libraries,
+    'Cache_symbolics' : _Prop_Cache_symbolics,
+    'Data_Update_Interval' : _Prop_Data_Update_Interval,
+    'Log_System_Messages' : _Prop_Log_System_Messages,
+    'Relocated_Executable_Path' : _Prop_Relocated_Executable_Path,
+    'Stop_at_temp_breakpoint' : _Prop_Stop_at_temp_breakpoint,
+    'Temp_Breakpoint_Type' : _Prop_Temp_Breakpoint_Type,
+    'Temp_breakpoint_names' : _Prop_Temp_breakpoint_names,
+    'Update_Data_While_Running' : _Prop_Update_Data_While_Running,
+}
+Debugger_Target._privelemdict = {
+}
+Debugger_Windowing._superclassnames = []
+Debugger_Windowing._privpropdict = {
+    'Debugging_Start_Action' : _Prop_Debugging_Start_Action,
+    'Do_Nothing_To_Projects' : _Prop_Do_Nothing_To_Projects,
+}
+Debugger_Windowing._privelemdict = {
+}
+data_member._superclassnames = []
+data_member._privpropdict = {
+    'access' : _Prop_access,
+    'declaration_end_offset' : _Prop_declaration_end_offset,
+    'declaration_start_offset' : _Prop_declaration_start_offset,
+    'name' : _Prop_name,
+    'static' : _Prop_static,
+}
+data_member._privelemdict = {
+}
+Editor._superclassnames = []
+Editor._privpropdict = {
+    'Background_Color' : _Prop_Background_Color,
+    'Balance' : _Prop_Balance,
+    'Context_Popup_Delay' : _Prop_Context_Popup_Delay,
+    'Default_Text_File_Format' : _Prop_Default_Text_File_Format,
+    'Dynamic_Scroll' : _Prop_Dynamic_Scroll,
+    'Flash_Delay' : _Prop_Flash_Delay,
+    'Left_Margin_Line_Select' : _Prop_Left_Margin_Line_Select,
+    'Main_Text_Color' : _Prop_Main_Text_Color,
+    'Relaxed_C_Popup_Parsing' : _Prop_Relaxed_C_Popup_Parsing,
+    'Remember_Font' : _Prop_Remember_Font,
+    'Remember_Selection' : _Prop_Remember_Selection,
+    'Remember_Window' : _Prop_Remember_Window,
+    'Sort_Function_Popup' : _Prop_Sort_Function_Popup,
+    'Use_Drag__26__Drop_Editing' : _Prop_Use_Drag__26__Drop_Editing,
+    'Use_Multiple_Undo' : _Prop_Use_Multiple_Undo,
+}
+Editor._privelemdict = {
+}
+Environment_Variable._superclassnames = []
+Environment_Variable._privpropdict = {
+    'name' : _Prop_name,
+    'value' : _Prop_value,
+}
+Environment_Variable._privelemdict = {
+}
+Error_Information._superclassnames = []
+Error_Information._privpropdict = {
+    'disk_file' : _Prop_disk_file,
+    'lineNumber' : _Prop_lineNumber,
+    'message' : _Prop_message,
+    'messageKind' : _Prop_messageKind,
+}
+Error_Information._privelemdict = {
+}
+Function_Information._superclassnames = []
+Function_Information._privpropdict = {
+    'disk_file' : _Prop_disk_file,
+    'lineNumber' : _Prop_lineNumber,
+}
+Function_Information._privelemdict = {
+}
+File_Mappings._superclassnames = []
+File_Mappings._privpropdict = {
+    'Mappings' : _Prop_Mappings,
+}
+File_Mappings._privelemdict = {
+}
+File_Mapping._superclassnames = []
+File_Mapping._privpropdict = {
+    'Compiler' : _Prop_Compiler,
+    'Extension' : _Prop_Extension,
+    'File_Type' : _Prop_File_Type,
+    'Ignored_by_Make' : _Prop_Ignored_by_Make,
+    'Launchable' : _Prop_Launchable,
+    'Precompiled' : _Prop_Precompiled,
+    'Resource_File' : _Prop_Resource_File,
+}
+File_Mapping._privelemdict = {
+}
+Global_Source_Trees._superclassnames = []
+Global_Source_Trees._privpropdict = {
+    'Source_Trees' : _Prop_Source_Trees,
+}
+Global_Source_Trees._privelemdict = {
+}
+Extras._superclassnames = []
+Extras._privpropdict = {
+    'Automatic_Toolbar_Help' : _Prop_Automatic_Toolbar_Help,
+    'External_Reference' : _Prop_External_Reference,
+    'Full_Screen_Zoom' : _Prop_Full_Screen_Zoom,
+    'Recent_Editor_Count' : _Prop_Recent_Editor_Count,
+    'Recent_Project_Count' : _Prop_Recent_Project_Count,
+    'Use_Editor_Extensions' : _Prop_Use_Editor_Extensions,
+    'Use_External_Editor' : _Prop_Use_External_Editor,
+    'Use_Script_Menu' : _Prop_Use_Script_Menu,
+    'Use_ToolServer_Menu' : _Prop_Use_ToolServer_Menu,
+}
+Extras._privelemdict = {
+}
+Build_Extras._superclassnames = []
+Build_Extras._privpropdict = {
+    'Browser_Active' : _Prop_Browser_Active,
+    'Cache_Subproject_Data' : _Prop_Cache_Subproject_Data,
+    'Dump_Browser_Info' : _Prop_Dump_Browser_Info,
+    'Modification_Date_Caching' : _Prop_Modification_Date_Caching,
+}
+Build_Extras._privelemdict = {
+}
+member_function._superclassnames = []
+member_function._privpropdict = {
+    'access' : _Prop_access,
+    'declaration_end_offset' : _Prop_declaration_end_offset,
+    'declaration_file' : _Prop_declaration_file,
+    'declaration_start_offset' : _Prop_declaration_start_offset,
+    'implementation_end_offset' : _Prop_implementation_end_offset,
+    'implementation_file' : _Prop_implementation_file,
+    'implementation_start_offset' : _Prop_implementation_start_offset,
+    'name' : _Prop_name,
+    'static' : _Prop_static,
+    'virtual' : _Prop_virtual,
+}
+member_function._privelemdict = {
+}
+Access_Paths._superclassnames = []
+Access_Paths._privpropdict = {
+    'Always_Full_Search' : _Prop_Always_Full_Search,
+    'Convert_Paths' : _Prop_Convert_Paths,
+    'Require_Framework_Includes' : _Prop_Require_Framework_Includes,
+    'System_Paths' : _Prop_System_Paths,
+    'User_Paths' : _Prop_User_Paths,
+}
+Access_Paths._privelemdict = {
+}
+Path_Information._superclassnames = []
+Path_Information._privpropdict = {
+    'format' : _Prop_format,
+    'framework' : _Prop_framework,
+    'host_flags' : _Prop_host_flags,
+    'name' : _Prop_name,
+    'origin' : _Prop_origin,
+    'recursive' : _Prop_recursive,
+    'root' : _Prop_root,
+}
+Path_Information._privelemdict = {
+}
+Plugin_Settings._superclassnames = []
+Plugin_Settings._privpropdict = {
+    'Disable_Third_Party_COM_Plugins' : _Prop_Disable_Third_Party_COM_Plugins,
+    'Plugin_Diagnostics_Level' : _Prop_Plugin_Diagnostics_Level,
+}
+Plugin_Settings._privelemdict = {
+}
+Runtime_Settings._superclassnames = []
+Runtime_Settings._privpropdict = {
+    'Command_Line_Arguments' : _Prop_Command_Line_Arguments,
+    'Environment_Variables' : _Prop_Environment_Variables,
+    'Host_Application' : _Prop_Host_Application,
+    'Working_Directory' : _Prop_Working_Directory,
+}
+Runtime_Settings._privelemdict = {
+}
+Relative_Path._superclassnames = []
+Relative_Path._privpropdict = {
+    'format' : _Prop_format,
+    'name' : _Prop_name,
+    'origin' : _Prop_origin,
+    'root' : _Prop_root,
+}
+Relative_Path._privelemdict = {
+}
+Shielded_Folder._superclassnames = []
+Shielded_Folder._privpropdict = {
+    'Expression_To_Match' : _Prop_Expression_To_Match,
+    'Skip_Find_And_Compare_Operations' : _Prop_Skip_Find_And_Compare_Operations,
+    'Skip_Project_Operations' : _Prop_Skip_Project_Operations,
+}
+Shielded_Folder._privelemdict = {
+}
+Shielded_Folders._superclassnames = []
+Shielded_Folders._privpropdict = {
+    'Shielded_Items' : _Prop_Shielded_Items,
+}
+Shielded_Folders._privelemdict = {
+}
+Syntax_Coloring._superclassnames = []
+Syntax_Coloring._privpropdict = {
+    'Comment_Color' : _Prop_Comment_Color,
+    'Custom_Color_1' : _Prop_Custom_Color_1,
+    'Custom_Color_2' : _Prop_Custom_Color_2,
+    'Custom_Color_3' : _Prop_Custom_Color_3,
+    'Custom_Color_4' : _Prop_Custom_Color_4,
+    'Keyword_Color' : _Prop_Keyword_Color,
+    'String_Color' : _Prop_String_Color,
+    'Syntax_Coloring' : _Prop_Syntax_Coloring,
+}
+Syntax_Coloring._privelemdict = {
+}
+Segment._superclassnames = []
+Segment._privpropdict = {
+    'filecount' : _Prop_filecount,
+    'name' : _Prop_name,
+    'seg_2d_locked' : _Prop_seg_2d_locked,
+    'seg_2d_preloaded' : _Prop_seg_2d_preloaded,
+    'seg_2d_protected' : _Prop_seg_2d_protected,
+    'seg_2d_purgeable' : _Prop_seg_2d_purgeable,
+    'seg_2d_system_heap' : _Prop_seg_2d_system_heap,
+}
+Segment._privelemdict = {
+}
+ProjectFile._superclassnames = []
+ProjectFile._privpropdict = {
+    'codesize' : _Prop_codesize,
+    'datasize' : _Prop_datasize,
+    'disk_file' : _Prop_disk_file,
+    'filetype' : _Prop_filetype,
+    'includes' : _Prop_includes,
+    'initialize_before' : _Prop_initialize_before,
+    'name' : _Prop_name,
+    'symbols' : _Prop_symbols,
+    'up_to_date' : _Prop_up_to_date,
+    'weak_link' : _Prop_weak_link,
+}
+ProjectFile._privelemdict = {
+}
+Source_Tree._superclassnames = []
+Source_Tree._privpropdict = {
+    'format' : _Prop_format,
+    'name' : _Prop_name,
+    'path' : _Prop_path,
+    'path_kind' : _Prop_path_kind,
+}
+Source_Tree._privelemdict = {
+}
+Target_Settings._superclassnames = []
+Target_Settings._privpropdict = {
+    'Linker' : _Prop_Linker,
+    'Output_Directory_Location' : _Prop_Output_Directory_Location,
+    'Output_Directory_Origin' : _Prop_Output_Directory_Origin,
+    'Output_Directory_Path' : _Prop_Output_Directory_Path,
+    'Post_Linker' : _Prop_Post_Linker,
+    'Pre_Linker' : _Prop_Pre_Linker,
+    'Target_Name' : _Prop_Target_Name,
+    'Use_Relative_Paths' : _Prop_Use_Relative_Paths,
+}
+Target_Settings._privelemdict = {
+}
+Target_Source_Trees._superclassnames = []
+Target_Source_Trees._privpropdict = {
+    'Source_Trees' : _Prop_Source_Trees,
+}
+Target_Source_Trees._privelemdict = {
+}
+VCS_Setup._superclassnames = []
+VCS_Setup._privpropdict = {
+    'Always_Prompt' : _Prop_Always_Prompt,
+    'Auto_Connect' : _Prop_Auto_Connect,
+    'Connection_Method' : _Prop_Connection_Method,
+    'Database_Path' : _Prop_Database_Path,
+    'Local_Path' : _Prop_Local_Path,
+    'Mount_Volume' : _Prop_Mount_Volume,
+    'Password' : _Prop_Password,
+    'Store_Password' : _Prop_Store_Password,
+    'Use_Global_Settings' : _Prop_Use_Global_Settings,
+    'Username' : _Prop_Username,
+    'VCS_Active' : _Prop_VCS_Active,
+}
+VCS_Setup._privelemdict = {
+}
+Font._superclassnames = []
+Font._privpropdict = {
+    'Auto_Indent' : _Prop_Auto_Indent,
+    'Tab_Indents_Selection' : _Prop_Tab_Indents_Selection,
+    'Tab_Inserts_Spaces' : _Prop_Tab_Inserts_Spaces,
+    'Tab_Size' : _Prop_Tab_Size,
+    'Text_Font' : _Prop_Text_Font,
+    'Text_Size' : _Prop_Text_Size,
+}
+Font._privelemdict = {
+}
+_Enum_Acce = {
+    'public' : 'Publ',  #
+    'protected' : 'Prot',       #
+    'private' : 'Priv', #
+}
+
+_Enum_BXbr = {
+    'Always_Build' : 'BXb1',    # Always build the target before running.
+    'Ask_Build' : 'BXb2',       # Ask before building the target when running.
+    'Never_Build' : 'BXb3',     # Never before building the target before running.
+}
+
+_Enum_DbSA = {
+    'No_Action' : 'DSA1',       # Don\xd5t do anything to non-debug windows
+    'Hide_Windows' : 'DSA2',    # Hide non-debugging windows
+    'Collapse_Windows' : 'DSA3',        # Collapse non-debugging windows
+    'Close_Windows' : 'DSA4',   # Close non-debugging windows
+}
+
+_Enum_DgBL = {
+    'Always' : 'DgB0',  # Always build before debugging.
+    'Never' : 'DgB1',   # Never build before debugging.
+    'Ask' : 'DgB2',     # Ask about building before debugging.
+}
+
+_Enum_ErrT = {
+    'information' : 'ErIn',     #
+    'compiler_warning' : 'ErCW',        #
+    'compiler_error' : 'ErCE',  #
+    'definition' : 'ErDf',      #
+    'linker_warning' : 'ErLW',  #
+    'linker_error' : 'ErLE',    #
+    'find_result' : 'ErFn',     #
+    'generic_error' : 'ErGn',   #
+}
+
+_Enum_Inte = {
+    'never_interact' : 'eNvr',  # Never allow user interactions
+    'interact_with_self' : 'eInS',      # Allow user interaction only when an AppleEvent is sent from within CodeWarrior
+    'interact_with_local' : 'eInL',     # Allow user interaction when AppleEvents are sent from applications on the same machine (default)
+    'interact_with_all' : 'eInA',       # Allow user interaction from both local and remote AppleEvents
+}
+
+_Enum_Lang = {
+    'C' : 'LC  ',       #
+    'C_2b__2b_' : 'LC++',       #
+    'Pascal' : 'LP  ',  #
+    'Object_Pascal' : 'LP++',   #
+    'Java' : 'LJav',    #
+    'Assembler' : 'LAsm',       #
+    'Unknown' : 'L?  ', #
+}
+
+_Enum_PPrm = {
+    'absolute' : 'Abso',        # An absolute path name, including volume name.
+    'project_relative' : 'PRel',        # A path relative to the current project\xd5s folder.
+    'shell_relative' : 'SRel',  # A path relative to the CodeWarrior\xaa folder.
+    'system_relative' : 'YRel', # A path relative to the system folder
+    'root_relative' : 'RRel',   #
+}
+
+_Enum_PXdg = {
+    'Diagnose_None' : 'PXd1',   # No Plugin Diagnostics.
+    'Diagnose_Errors' : 'PXd2', # Plugin Diagnostics for errors only.
+    'Diagnose_All' : 'PXd3',    # Plugin Diagnostics for everything.
+}
+
+_Enum_PthF = {
+    'Generic_Path' : 'PFGn',    #
+    'MacOS_Path' : 'PFMc',      # MacOS path using colon as separator
+    'Windows_Path' : 'PFWn',    # Windows path using backslash as separator
+    'Unix_Path' : 'PFUx',       # Unix path using slash as separator
+}
+
+_Enum_RefP = {
+    'Think_Reference' : 'DanR', #
+    'QuickView' : 'ALTV',       #
+}
+
+_Enum_STKd = {
+    'Absolute_Path' : 'STK0',   # The \xd2path\xd3 property is an absolute path to the location of the source tree.
+    'Registry_Key' : 'STK1',    # The \xd2path\xd3 property is the name of a registry key that contains the path to the root.
+    'Environment_Variable' : 'STK2',    # The \xd2path\xd3 property is the name of an environment variable that contains the path to the root.
+}
+
+_Enum_SrcT = {
+    'source' : 'FTxt',  # A source file (.c, .cp, .p, etc).
+    'unknown' : 'FUnk', # An unknown file type.
+}
+
+_Enum_TmpB = {
+    'User_Specified' : 'Usrs',  # Use user specified symbols when setting temporary breakpoints on program launch.
+    'Default' : 'Dflt', # Use system default symbols when setting temporary breakpoints on program launch.
+}
+
+_Enum_TxtF = {
+    'MacOS' : 'TxF0',   # MacOS text format
+    'DOS' : 'TxF1',     # DOS text format
+    'Unix' : 'TxF2',    # Unix text format
+}
+
+_Enum_savo = {
+    'yes' : 'yes ',     # Save changes
+    'no' : 'no  ',      # Do not save changes
+    'ask' : 'ask ',     # Ask the user whether to save
+}
+
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+    'BRKW' : Browser_Coloring,
+    'BSTG' : Build_Settings,
+    'BsCl' : base_class,
+    'CUKW' : Custom_Keywords,
+    'Cata' : browser_catalog,
+    'Clas' : class_,
+    'DbDS' : Debugger_Display,
+    'DbGL' : Debugger_Global,
+    'DbTG' : Debugger_Target,
+    'DbWN' : Debugger_Windowing,
+    'DtMb' : data_member,
+    'EDTR' : Editor,
+    'EnvV' : Environment_Variable,
+    'ErrM' : Error_Information,
+    'FDef' : Function_Information,
+    'FLMP' : File_Mappings,
+    'FMap' : File_Mapping,
+    'GSTs' : Global_Source_Trees,
+    'GXTR' : Extras,
+    'LXTR' : Build_Extras,
+    'MbFn' : member_function,
+    'PATH' : Access_Paths,
+    'PInf' : Path_Information,
+    'PSTG' : Plugin_Settings,
+    'RSTG' : Runtime_Settings,
+    'RlPt' : Relative_Path,
+    'SFit' : Shielded_Folder,
+    'SHFL' : Shielded_Folders,
+    'SNTX' : Syntax_Coloring,
+    'Seg ' : Segment,
+    'SrcF' : ProjectFile,
+    'SrcT' : Source_Tree,
+    'TARG' : Target_Settings,
+    'TSTs' : Target_Source_Trees,
+    'VCSs' : VCS_Setup,
+    'mFNT' : Font,
+}
+
+_propdeclarations = {
+    'Acce' : _Prop_access,
+    'BW00' : _Prop_Browser_Keywords,
+    'BW01' : _Prop_Classes_Color,
+    'BW02' : _Prop_Constants_Color,
+    'BW03' : _Prop_Enums_Color,
+    'BW04' : _Prop_Functions_Color,
+    'BW05' : _Prop_Globals_Color,
+    'BW06' : _Prop_Macros_Color,
+    'BW07' : _Prop_Templates_Color,
+    'BW08' : _Prop_Typedefs_Color,
+    'BW10' : _Prop_Template_Commands_in_Menu,
+    'BX01' : _Prop_Completion_Sound,
+    'BX02' : _Prop_Success_Sound,
+    'BX03' : _Prop_Failure_Sound,
+    'BX04' : _Prop_Build_Before_Running,
+    'BX05' : _Prop_Include_Cache_Size,
+    'BX06' : _Prop_Compiler_Thread_Stack_Size,
+    'BX07' : _Prop_Save_Before_Building,
+    'Bfor' : _Prop_initialize_before,
+    'CSiz' : _Prop_codesize,
+    'Clas' : _Prop_class_,
+    'DSiz' : _Prop_datasize,
+    'Db01' : _Prop_Show_Variable_Types,
+    'Db02' : _Prop_Sort_By_Method,
+    'Db03' : _Prop_Use_RTTI,
+    'Db04' : _Prop_Threads_in_Window,
+    'Db05' : _Prop_Variable_Hints,
+    'Db06' : _Prop_Watchpoint_Hilite,
+    'Db07' : _Prop_Variable_Changed_Hilite,
+    'Db08' : _Prop_Default_Array_Size,
+    'Db09' : _Prop_Show_Locals,
+    'Db10' : _Prop_Show_As_Decimal,
+    'DcEn' : _Prop_declaration_end_offset,
+    'DcFl' : _Prop_declaration_file,
+    'DcSt' : _Prop_declaration_start_offset,
+    'DfEn' : _Prop_implementation_end_offset,
+    'DfFl' : _Prop_implementation_file,
+    'DfSt' : _Prop_implementation_start_offset,
+    'Dg01' : _Prop_Ignore_Mod_Dates,
+    'Dg02' : _Prop_Open_All_Classes,
+    'Dg03' : _Prop_Launch_Apps_on_Open,
+    'Dg04' : _Prop_Confirm_Kill,
+    'Dg05' : _Prop_Stop_at_Main,
+    'Dg06' : _Prop_Select_Stack_Crawl,
+    'Dg07' : _Prop_Dont_Step_in_Runtime,
+    'Dg11' : _Prop_Auto_Target_Libraries,
+    'Dg12' : _Prop_Cache_Edited_Files,
+    'Dg13' : _Prop_File_Cache_Duration,
+    'Dt02' : _Prop_Log_System_Messages,
+    'Dt08' : _Prop_Update_Data_While_Running,
+    'Dt09' : _Prop_Data_Update_Interval,
+    'Dt10' : _Prop_Relocated_Executable_Path,
+    'Dt13' : _Prop_Stop_at_temp_breakpoint,
+    'Dt14' : _Prop_Temp_breakpoint_names,
+    'Dt15' : _Prop_Cache_symbolics,
+    'Dt16' : _Prop_Temp_Breakpoint_Type,
+    'Dw01' : _Prop_Debugging_Start_Action,
+    'Dw02' : _Prop_Do_Nothing_To_Projects,
+    'ED01' : _Prop_Flash_Delay,
+    'ED02' : _Prop_Dynamic_Scroll,
+    'ED03' : _Prop_Balance,
+    'ED04' : _Prop_Use_Drag__26__Drop_Editing,
+    'ED06' : _Prop_Sort_Function_Popup,
+    'ED07' : _Prop_Use_Multiple_Undo,
+    'ED08' : _Prop_Remember_Font,
+    'ED09' : _Prop_Remember_Selection,
+    'ED10' : _Prop_Remember_Window,
+    'ED12' : _Prop_Main_Text_Color,
+    'ED13' : _Prop_Background_Color,
+    'ED14' : _Prop_Context_Popup_Delay,
+    'ED15' : _Prop_Relaxed_C_Popup_Parsing,
+    'ED16' : _Prop_Left_Margin_Line_Select,
+    'ED17' : _Prop_Default_Text_File_Format,
+    'EX04' : _Prop_Modification_Date_Caching,
+    'EX07' : _Prop_Full_Screen_Zoom,
+    'EX08' : _Prop_External_Reference,
+    'EX09' : _Prop_Browser_Active,
+    'EX10' : _Prop_Use_Editor_Extensions,
+    'EX11' : _Prop_Use_External_Editor,
+    'EX12' : _Prop_Use_Script_Menu,
+    'EX16' : _Prop_Recent_Editor_Count,
+    'EX17' : _Prop_Recent_Project_Count,
+    'EX18' : _Prop_Use_ToolServer_Menu,
+    'EX19' : _Prop_Automatic_Toolbar_Help,
+    'EX30' : _Prop_Dump_Browser_Info,
+    'EX31' : _Prop_Cache_Subproject_Data,
+    'ErrL' : _Prop_lineNumber,
+    'ErrS' : _Prop_message,
+    'ErrT' : _Prop_messageKind,
+    'FMps' : _Prop_Mappings,
+    'FN01' : _Prop_Auto_Indent,
+    'FN02' : _Prop_Tab_Size,
+    'FN03' : _Prop_Tab_Indents_Selection,
+    'FN04' : _Prop_Tab_Inserts_Spaces,
+    'Frmt' : _Prop_format,
+    'Frmw' : _Prop_framework,
+    'GH01' : _Prop_Syntax_Coloring,
+    'GH02' : _Prop_Comment_Color,
+    'GH03' : _Prop_Keyword_Color,
+    'GH04' : _Prop_String_Color,
+    'GH05' : _Prop_Custom_Color_1,
+    'GH06' : _Prop_Custom_Color_2,
+    'GH07' : _Prop_Custom_Color_3,
+    'GH08' : _Prop_Custom_Color_4,
+    'HstF' : _Prop_host_flags,
+    'IncF' : _Prop_includes,
+    'Kind' : _Prop_path_kind,
+    'Lang' : _Prop_language,
+    'NumF' : _Prop_filecount,
+    'Orig' : _Prop_origin,
+    'PA01' : _Prop_User_Paths,
+    'PA02' : _Prop_Always_Full_Search,
+    'PA03' : _Prop_System_Paths,
+    'PA04' : _Prop_Convert_Paths,
+    'PA05' : _Prop_Require_Framework_Includes,
+    'PLck' : _Prop_seg_2d_locked,
+    'PR04' : _Prop_File_Type,
+    'PX01' : _Prop_Plugin_Diagnostics_Level,
+    'PX02' : _Prop_Disable_Third_Party_COM_Plugins,
+    'Path' : _Prop_path,
+    'Prel' : _Prop_seg_2d_preloaded,
+    'Prot' : _Prop_seg_2d_protected,
+    'Purg' : _Prop_seg_2d_purgeable,
+    'RS01' : _Prop_Host_Application,
+    'RS02' : _Prop_Command_Line_Arguments,
+    'RS03' : _Prop_Working_Directory,
+    'RS04' : _Prop_Environment_Variables,
+    'Recu' : _Prop_recursive,
+    'Root' : _Prop_root,
+    'SF01' : _Prop_Expression_To_Match,
+    'SF02' : _Prop_Skip_Project_Operations,
+    'SF03' : _Prop_Skip_Find_And_Compare_Operations,
+    'SFis' : _Prop_Shielded_Items,
+    'ST01' : _Prop_Source_Trees,
+    'SrcT' : _Prop_filetype,
+    'Stat' : _Prop_static,
+    'SubA' : _Prop_all_subclasses,
+    'SubC' : _Prop_subclasses,
+    'SymG' : _Prop_symbols,
+    'SysH' : _Prop_seg_2d_system_heap,
+    'TA01' : _Prop_Linker,
+    'TA02' : _Prop_Extension,
+    'TA03' : _Prop_Precompiled,
+    'TA04' : _Prop_Resource_File,
+    'TA05' : _Prop_Launchable,
+    'TA06' : _Prop_Ignored_by_Make,
+    'TA07' : _Prop_Compiler,
+    'TA09' : _Prop_Post_Linker,
+    'TA10' : _Prop_Target_Name,
+    'TA11' : _Prop_Output_Directory_Path,
+    'TA12' : _Prop_Output_Directory_Origin,
+    'TA13' : _Prop_Pre_Linker,
+    'TA15' : _Prop_Use_Relative_Paths,
+    'TA16' : _Prop_Output_Directory_Location,
+    'UpTD' : _Prop_up_to_date,
+    'VC01' : _Prop_VCS_Active,
+    'VC02' : _Prop_Connection_Method,
+    'VC03' : _Prop_Username,
+    'VC04' : _Prop_Password,
+    'VC05' : _Prop_Auto_Connect,
+    'VC06' : _Prop_Store_Password,
+    'VC07' : _Prop_Always_Prompt,
+    'VC08' : _Prop_Mount_Volume,
+    'VC09' : _Prop_Database_Path,
+    'VC10' : _Prop_Local_Path,
+    'VC11' : _Prop_Use_Global_Settings,
+    'Valu' : _Prop_value,
+    'Virt' : _Prop_virtual,
+    'Weak' : _Prop_weak_link,
+    'file' : _Prop_disk_file,
+    'pnam' : _Prop_name,
+    'ptps' : _Prop_Text_Size,
+    'ptxf' : _Prop_Text_Font,
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+    'Acce' : _Enum_Acce,
+    'BXbr' : _Enum_BXbr,
+    'DbSA' : _Enum_DbSA,
+    'DgBL' : _Enum_DgBL,
+    'ErrT' : _Enum_ErrT,
+    'Inte' : _Enum_Inte,
+    'Lang' : _Enum_Lang,
+    'PPrm' : _Enum_PPrm,
+    'PXdg' : _Enum_PXdg,
+    'PthF' : _Enum_PthF,
+    'RefP' : _Enum_RefP,
+    'STKd' : _Enum_STKd,
+    'SrcT' : _Enum_SrcT,
+    'TmpB' : _Enum_TmpB,
+    'TxtF' : _Enum_TxtF,
+    'savo' : _Enum_savo,
+}

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/CodeWarrior/Required.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/CodeWarrior/Required.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/CodeWarrior/Required.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,62 @@
+"""Suite Required: Terms that every application should support
+Level 1, version 1
+
+Generated from /Volumes/Sap/Applications (Mac OS 9)/Metrowerks CodeWarrior 7.0/Metrowerks CodeWarrior/CodeWarrior IDE 4.2.5
+AETE/AEUT resource version 1/0, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'reqd'
+
+from StdSuites.Required_Suite import *
+class Required_Events(Required_Suite_Events):
+
+    _argmap_open = {
+        'converting' : 'Conv',
+    }
+
+    def open(self, _object, _attributes={}, **_arguments):
+        """open: Open the specified object(s)
+        Required argument: list of objects to open
+        Keyword argument converting: Whether to convert project to latest version (yes/no; default is ask).
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'aevt'
+        _subcode = 'odoc'
+
+        aetools.keysubst(_arguments, self._argmap_open)
+        _arguments['----'] = _object
+
+        aetools.enumsubst(_arguments, 'Conv', _Enum_Conv)
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+_Enum_Conv = {
+    'yes' : 'yes ',     # Convert the project if necessary on open
+    'no' : 'no  ',      # Do not convert the project if needed on open
+}
+
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+}
+
+_propdeclarations = {
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+    'Conv' : _Enum_Conv,
+}

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/CodeWarrior/Standard_Suite.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/CodeWarrior/Standard_Suite.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/CodeWarrior/Standard_Suite.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,408 @@
+"""Suite Standard Suite: Common terms for most applications
+Level 1, version 1
+
+Generated from /Volumes/Sap/Applications (Mac OS 9)/Metrowerks CodeWarrior 7.0/Metrowerks CodeWarrior/CodeWarrior IDE 4.2.5
+AETE/AEUT resource version 1/0, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'CoRe'
+
+from StdSuites.Standard_Suite import *
+class Standard_Suite_Events(Standard_Suite_Events):
+
+    _argmap_close = {
+        'saving' : 'savo',
+        'saving_in' : 'kfil',
+    }
+
+    def close(self, _object, _attributes={}, **_arguments):
+        """close: close an object
+        Required argument: the object to close
+        Keyword argument saving: specifies whether or not changes should be saved before closing
+        Keyword argument saving_in: the file in which to save the object
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'core'
+        _subcode = 'clos'
+
+        aetools.keysubst(_arguments, self._argmap_close)
+        _arguments['----'] = _object
+
+        aetools.enumsubst(_arguments, 'savo', _Enum_savo)
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_count = {
+        'each' : 'kocl',
+    }
+
+    def count(self, _object, _attributes={}, **_arguments):
+        """count: return the number of elements of a particular class within an object
+        Required argument: the object whose elements are to be counted
+        Keyword argument each: the class of the elements to be counted. Keyword 'each' is optional in AppleScript
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: the number of elements
+        """
+        _code = 'core'
+        _subcode = 'cnte'
+
+        aetools.keysubst(_arguments, self._argmap_count)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_get = {
+        'as' : 'rtyp',
+    }
+
+    def get(self, _object, _attributes={}, **_arguments):
+        """get: get the data for an object
+        Required argument: the object whose data is to be returned
+        Keyword argument as: the desired types for the data, in order of preference
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: The data from the object
+        """
+        _code = 'core'
+        _subcode = 'getd'
+
+        aetools.keysubst(_arguments, self._argmap_get)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_make = {
+        'new' : 'kocl',
+        'as' : 'rtyp',
+        'at' : 'insh',
+        'with_data' : 'data',
+        'with_properties' : 'prdt',
+    }
+
+    def make(self, _no_object=None, _attributes={}, **_arguments):
+        """make: make a new element
+        Keyword argument new: the class of the new element\xd1keyword 'new' is optional in AppleScript
+        Keyword argument as: the desired types for the data, in order of preference
+        Keyword argument at: the location at which to insert the element
+        Keyword argument with_data: the initial data for the element
+        Keyword argument with_properties: the initial values for the properties of the element
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: to the new object(s)
+        """
+        _code = 'core'
+        _subcode = 'crel'
+
+        aetools.keysubst(_arguments, self._argmap_make)
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def select(self, _object=None, _attributes={}, **_arguments):
+        """select: select the specified object
+        Required argument: the object to select
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'misc'
+        _subcode = 'slct'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_set = {
+        'to' : 'data',
+    }
+
+    def set(self, _object, _attributes={}, **_arguments):
+        """set: set an object's data
+        Required argument: the object to change
+        Keyword argument to: the new value
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'core'
+        _subcode = 'setd'
+
+        aetools.keysubst(_arguments, self._argmap_set)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+
+class application(aetools.ComponentItem):
+    """application - an application program """
+    want = 'capp'
+class _Prop_user_interaction(aetools.NProperty):
+    """user interaction - user interaction level """
+    which = 'inte'
+    want = 'Inte'
+user_interaction = _Prop_user_interaction()
+#        element 'cwin' as ['indx', 'name', 'rang']
+#        element 'docu' as ['indx', 'name', 'rang']
+
+class character(aetools.ComponentItem):
+    """character - a character """
+    want = 'cha '
+class _Prop_length(aetools.NProperty):
+    """length - length in characters of this object """
+    which = 'pLen'
+    want = 'long'
+class _Prop_offset(aetools.NProperty):
+    """offset - offset of a text object from the beginning of the document (first char has offset 1) """
+    which = 'pOff'
+    want = 'long'
+
+class insertion_point(aetools.ComponentItem):
+    """insertion point - An insertion location between two objects """
+    want = 'cins'
+
+class line(aetools.ComponentItem):
+    """line - lines of text """
+    want = 'clin'
+class _Prop_index(aetools.NProperty):
+    """index - index of a line object from the beginning of the document (first line has index 1) """
+    which = 'pidx'
+    want = 'long'
+#        element 'cha ' as ['indx', 'rang', 'rele']
+
+lines = line
+
+class selection_2d_object(aetools.ComponentItem):
+    """selection-object - the selection visible to the user """
+    want = 'csel'
+class _Prop_contents(aetools.NProperty):
+    """contents - the contents of the selection """
+    which = 'pcnt'
+    want = 'type'
+#        element 'cha ' as ['indx', 'rele', 'rang', 'test']
+#        element 'clin' as ['indx', 'rang', 'rele']
+#        element 'ctxt' as ['rang']
+
+class text(aetools.ComponentItem):
+    """text - Text """
+    want = 'ctxt'
+#        element 'cha ' as ['indx', 'rele', 'rang']
+#        element 'cins' as ['rele']
+#        element 'clin' as ['indx', 'rang', 'rele']
+#        element 'ctxt' as ['rang']
+
+class window(aetools.ComponentItem):
+    """window - A window """
+    want = 'cwin'
+class _Prop_bounds(aetools.NProperty):
+    """bounds - the boundary rectangle for the window """
+    which = 'pbnd'
+    want = 'qdrt'
+class _Prop_document(aetools.NProperty):
+    """document - the document that owns this window """
+    which = 'docu'
+    want = 'docu'
+class _Prop_name(aetools.NProperty):
+    """name - the title of the window """
+    which = 'pnam'
+    want = 'itxt'
+class _Prop_position(aetools.NProperty):
+    """position - upper left coordinates of window """
+    which = 'ppos'
+    want = 'QDpt'
+class _Prop_visible(aetools.NProperty):
+    """visible - is the window visible? """
+    which = 'pvis'
+    want = 'bool'
+class _Prop_zoomed(aetools.NProperty):
+    """zoomed - Is the window zoomed? """
+    which = 'pzum'
+    want = 'bool'
+
+windows = window
+
+class document(aetools.ComponentItem):
+    """document - a document """
+    want = 'docu'
+class _Prop_file_permissions(aetools.NProperty):
+    """file permissions - the file permissions for the document """
+    which = 'PERM'
+    want = 'PERM'
+class _Prop_kind(aetools.NProperty):
+    """kind - the kind of document """
+    which = 'DKND'
+    want = 'DKND'
+class _Prop_location(aetools.NProperty):
+    """location - the file of the document """
+    which = 'FILE'
+    want = 'fss '
+class _Prop_window(aetools.NProperty):
+    """window - the window of the document. """
+    which = 'cwin'
+    want = 'cwin'
+
+documents = document
+
+class files(aetools.ComponentItem):
+    """files - Every file """
+    want = 'file'
+
+file = files
+application._superclassnames = []
+application._privpropdict = {
+    'user_interaction' : _Prop_user_interaction,
+}
+application._privelemdict = {
+    'document' : document,
+    'window' : window,
+}
+character._superclassnames = []
+character._privpropdict = {
+    'length' : _Prop_length,
+    'offset' : _Prop_offset,
+}
+character._privelemdict = {
+}
+insertion_point._superclassnames = []
+insertion_point._privpropdict = {
+    'length' : _Prop_length,
+    'offset' : _Prop_offset,
+}
+insertion_point._privelemdict = {
+}
+line._superclassnames = []
+line._privpropdict = {
+    'index' : _Prop_index,
+    'length' : _Prop_length,
+    'offset' : _Prop_offset,
+}
+line._privelemdict = {
+    'character' : character,
+}
+selection_2d_object._superclassnames = []
+selection_2d_object._privpropdict = {
+    'contents' : _Prop_contents,
+    'length' : _Prop_length,
+    'offset' : _Prop_offset,
+}
+selection_2d_object._privelemdict = {
+    'character' : character,
+    'line' : line,
+    'text' : text,
+}
+text._superclassnames = []
+text._privpropdict = {
+    'length' : _Prop_length,
+    'offset' : _Prop_offset,
+}
+text._privelemdict = {
+    'character' : character,
+    'insertion_point' : insertion_point,
+    'line' : line,
+    'text' : text,
+}
+window._superclassnames = []
+window._privpropdict = {
+    'bounds' : _Prop_bounds,
+    'document' : _Prop_document,
+    'index' : _Prop_index,
+    'name' : _Prop_name,
+    'position' : _Prop_position,
+    'visible' : _Prop_visible,
+    'zoomed' : _Prop_zoomed,
+}
+window._privelemdict = {
+}
+document._superclassnames = []
+document._privpropdict = {
+    'file_permissions' : _Prop_file_permissions,
+    'index' : _Prop_index,
+    'kind' : _Prop_kind,
+    'location' : _Prop_location,
+    'name' : _Prop_name,
+    'window' : _Prop_window,
+}
+document._privelemdict = {
+}
+files._superclassnames = []
+files._privpropdict = {
+}
+files._privelemdict = {
+}
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+    'capp' : application,
+    'cha ' : character,
+    'cins' : insertion_point,
+    'clin' : line,
+    'csel' : selection_2d_object,
+    'ctxt' : text,
+    'cwin' : window,
+    'docu' : document,
+    'file' : files,
+}
+
+_propdeclarations = {
+    'DKND' : _Prop_kind,
+    'FILE' : _Prop_location,
+    'PERM' : _Prop_file_permissions,
+    'cwin' : _Prop_window,
+    'docu' : _Prop_document,
+    'inte' : _Prop_user_interaction,
+    'pLen' : _Prop_length,
+    'pOff' : _Prop_offset,
+    'pbnd' : _Prop_bounds,
+    'pcnt' : _Prop_contents,
+    'pidx' : _Prop_index,
+    'pnam' : _Prop_name,
+    'ppos' : _Prop_position,
+    'pvis' : _Prop_visible,
+    'pzum' : _Prop_zoomed,
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+}

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/CodeWarrior/__init__.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/CodeWarrior/__init__.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/CodeWarrior/__init__.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,189 @@
+"""
+Package generated from /Volumes/Sap/Applications (Mac OS 9)/Metrowerks CodeWarrior 7.0/Metrowerks CodeWarrior/CodeWarrior IDE 4.2.5
+"""
+import aetools
+Error = aetools.Error
+import CodeWarrior_suite
+import Standard_Suite
+import Metrowerks_Shell_Suite
+import Required
+
+
+_code_to_module = {
+    'CWIE' : CodeWarrior_suite,
+    'CoRe' : Standard_Suite,
+    'MMPR' : Metrowerks_Shell_Suite,
+    'reqd' : Required,
+}
+
+
+
+_code_to_fullname = {
+    'CWIE' : ('CodeWarrior.CodeWarrior_suite', 'CodeWarrior_suite'),
+    'CoRe' : ('CodeWarrior.Standard_Suite', 'Standard_Suite'),
+    'MMPR' : ('CodeWarrior.Metrowerks_Shell_Suite', 'Metrowerks_Shell_Suite'),
+    'reqd' : ('CodeWarrior.Required', 'Required'),
+}
+
+from CodeWarrior_suite import *
+from Standard_Suite import *
+from Metrowerks_Shell_Suite import *
+from Required import *
+
+def getbaseclasses(v):
+    if not getattr(v, '_propdict', None):
+        v._propdict = {}
+        v._elemdict = {}
+        for superclassname in getattr(v, '_superclassnames', []):
+            superclass = eval(superclassname)
+            getbaseclasses(superclass)
+            v._propdict.update(getattr(superclass, '_propdict', {}))
+            v._elemdict.update(getattr(superclass, '_elemdict', {}))
+        v._propdict.update(getattr(v, '_privpropdict', {}))
+        v._elemdict.update(getattr(v, '_privelemdict', {}))
+
+import StdSuites
+
+#
+# Set property and element dictionaries now that all classes have been defined
+#
+getbaseclasses(character)
+getbaseclasses(selection_2d_object)
+getbaseclasses(application)
+getbaseclasses(document)
+getbaseclasses(text)
+getbaseclasses(window)
+getbaseclasses(file)
+getbaseclasses(line)
+getbaseclasses(insertion_point)
+getbaseclasses(single_class_browser)
+getbaseclasses(project_document)
+getbaseclasses(symbol_browser)
+getbaseclasses(editor_document)
+getbaseclasses(file_compare_document)
+getbaseclasses(class_browser)
+getbaseclasses(subtarget)
+getbaseclasses(message_document)
+getbaseclasses(project_inspector)
+getbaseclasses(text_document)
+getbaseclasses(catalog_document)
+getbaseclasses(class_hierarchy)
+getbaseclasses(target)
+getbaseclasses(build_progress_document)
+getbaseclasses(target_file)
+getbaseclasses(ToolServer_worksheet)
+getbaseclasses(single_class_hierarchy)
+getbaseclasses(File_Mapping)
+getbaseclasses(browser_catalog)
+getbaseclasses(Build_Settings)
+getbaseclasses(ProjectFile)
+getbaseclasses(VCS_Setup)
+getbaseclasses(data_member)
+getbaseclasses(Shielded_Folder)
+getbaseclasses(Custom_Keywords)
+getbaseclasses(Path_Information)
+getbaseclasses(Segment)
+getbaseclasses(Source_Tree)
+getbaseclasses(Access_Paths)
+getbaseclasses(Debugger_Windowing)
+getbaseclasses(Relative_Path)
+getbaseclasses(Environment_Variable)
+getbaseclasses(base_class)
+getbaseclasses(Debugger_Display)
+getbaseclasses(Build_Extras)
+getbaseclasses(Error_Information)
+getbaseclasses(Editor)
+getbaseclasses(Shielded_Folders)
+getbaseclasses(Extras)
+getbaseclasses(File_Mappings)
+getbaseclasses(Function_Information)
+getbaseclasses(Debugger_Target)
+getbaseclasses(Syntax_Coloring)
+getbaseclasses(class_)
+getbaseclasses(Global_Source_Trees)
+getbaseclasses(Target_Settings)
+getbaseclasses(Debugger_Global)
+getbaseclasses(member_function)
+getbaseclasses(Runtime_Settings)
+getbaseclasses(Plugin_Settings)
+getbaseclasses(Browser_Coloring)
+getbaseclasses(Font)
+getbaseclasses(Target_Source_Trees)
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+    'cha ' : character,
+    'csel' : selection_2d_object,
+    'capp' : application,
+    'docu' : document,
+    'ctxt' : text,
+    'cwin' : window,
+    'file' : file,
+    'clin' : line,
+    'cins' : insertion_point,
+    '1BRW' : single_class_browser,
+    'PRJD' : project_document,
+    'SYMB' : symbol_browser,
+    'EDIT' : editor_document,
+    'COMP' : file_compare_document,
+    'BROW' : class_browser,
+    'SBTG' : subtarget,
+    'MSSG' : message_document,
+    'INSP' : project_inspector,
+    'TXTD' : text_document,
+    'CTLG' : catalog_document,
+    'HIER' : class_hierarchy,
+    'TRGT' : target,
+    'PRGS' : build_progress_document,
+    'SRCF' : target_file,
+    'TOOL' : ToolServer_worksheet,
+    '1HIR' : single_class_hierarchy,
+    'FMap' : File_Mapping,
+    'Cata' : browser_catalog,
+    'BSTG' : Build_Settings,
+    'SrcF' : ProjectFile,
+    'VCSs' : VCS_Setup,
+    'DtMb' : data_member,
+    'SFit' : Shielded_Folder,
+    'CUKW' : Custom_Keywords,
+    'PInf' : Path_Information,
+    'Seg ' : Segment,
+    'SrcT' : Source_Tree,
+    'PATH' : Access_Paths,
+    'DbWN' : Debugger_Windowing,
+    'RlPt' : Relative_Path,
+    'EnvV' : Environment_Variable,
+    'BsCl' : base_class,
+    'DbDS' : Debugger_Display,
+    'LXTR' : Build_Extras,
+    'ErrM' : Error_Information,
+    'EDTR' : Editor,
+    'SHFL' : Shielded_Folders,
+    'GXTR' : Extras,
+    'FLMP' : File_Mappings,
+    'FDef' : Function_Information,
+    'DbTG' : Debugger_Target,
+    'SNTX' : Syntax_Coloring,
+    'Clas' : class_,
+    'GSTs' : Global_Source_Trees,
+    'TARG' : Target_Settings,
+    'DbGL' : Debugger_Global,
+    'MbFn' : member_function,
+    'RSTG' : Runtime_Settings,
+    'PSTG' : Plugin_Settings,
+    'BRKW' : Browser_Coloring,
+    'mFNT' : Font,
+    'TSTs' : Target_Source_Trees,
+}
+
+
+class CodeWarrior(CodeWarrior_suite_Events,
+        Standard_Suite_Events,
+        Metrowerks_Shell_Suite_Events,
+        Required_Events,
+        aetools.TalkTo):
+    _signature = 'CWIE'
+
+    _moduleName = 'CodeWarrior'

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Explorer/Microsoft_Internet_Explorer.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Explorer/Microsoft_Internet_Explorer.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Explorer/Microsoft_Internet_Explorer.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,96 @@
+"""Suite Microsoft Internet Explorer Suite: Events defined by Internet Explorer
+Level 1, version 1
+
+Generated from /Applications/Internet Explorer.app
+AETE/AEUT resource version 1/0, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'MSIE'
+
+class Microsoft_Internet_Explorer_Events:
+
+    def GetSource(self, _object=None, _attributes={}, **_arguments):
+        """GetSource: Get the HTML source of a browser window
+        Required argument: Window Identifier of window from which to get the source. No value means get the source from the frontmost window.
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: undocumented, typecode 'TEXT'
+        """
+        _code = 'MSIE'
+        _subcode = 'SORC'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def PrintBrowserWindow(self, _object=None, _attributes={}, **_arguments):
+        """PrintBrowserWindow: Print contents of browser window (HTML)
+        Required argument: Window Identifier of the window to print. No value means print the frontmost browser window.
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'misc'
+        _subcode = 'pWND'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_do_script = {
+        'window' : 'WIND',
+    }
+
+    def do_script(self, _object, _attributes={}, **_arguments):
+        """do script: Execute script commands
+        Required argument: JavaScript text to execute
+        Keyword argument window: optional Window Identifier (as supplied by the ListWindows event) specifying context in which to execute the script
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: Return value
+        """
+        _code = 'misc'
+        _subcode = 'dosc'
+
+        aetools.keysubst(_arguments, self._argmap_do_script)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+}
+
+_propdeclarations = {
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+}

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Explorer/Netscape_Suite.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Explorer/Netscape_Suite.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Explorer/Netscape_Suite.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,49 @@
+"""Suite Netscape Suite: Events defined by Netscape
+Level 1, version 1
+
+Generated from /Applications/Internet Explorer.app
+AETE/AEUT resource version 1/0, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'MOSS'
+
+class Netscape_Suite_Events:
+
+    def Open_bookmark(self, _object=None, _attributes={}, **_arguments):
+        """Open bookmark: Opens a bookmark file
+        Required argument: If not available, reloads the current bookmark file
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'MOSS'
+        _subcode = 'book'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+}
+
+_propdeclarations = {
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+}

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Explorer/Required_Suite.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Explorer/Required_Suite.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Explorer/Required_Suite.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,108 @@
+"""Suite Required Suite: Events that every application should support
+Level 1, version 1
+
+Generated from /Applications/Internet Explorer.app
+AETE/AEUT resource version 1/0, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'reqd'
+
+from StdSuites.Required_Suite import *
+class Required_Suite_Events(Required_Suite_Events):
+
+    def open(self, _object, _attributes={}, **_arguments):
+        """open: Open documents
+        Required argument: undocumented, typecode 'alis'
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'aevt'
+        _subcode = 'odoc'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def print_(self, _object, _attributes={}, **_arguments):
+        """print: Print documents
+        Required argument: undocumented, typecode 'alis'
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'aevt'
+        _subcode = 'pdoc'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def quit(self, _no_object=None, _attributes={}, **_arguments):
+        """quit: Quit application
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'aevt'
+        _subcode = 'quit'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def run(self, _no_object=None, _attributes={}, **_arguments):
+        """run:
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'aevt'
+        _subcode = 'oapp'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+}
+
+_propdeclarations = {
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+}

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Explorer/Standard_Suite.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Explorer/Standard_Suite.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Explorer/Standard_Suite.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,72 @@
+"""Suite Standard Suite: Common terms for most applications
+Level 1, version 1
+
+Generated from /Applications/Internet Explorer.app
+AETE/AEUT resource version 1/0, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = '****'
+
+class Standard_Suite_Events:
+
+    _argmap_get = {
+        'as' : 'rtyp',
+    }
+
+    def get(self, _object, _attributes={}, **_arguments):
+        """get:
+        Required argument: an AE object reference
+        Keyword argument as: undocumented, typecode 'type'
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: anything
+        """
+        _code = 'core'
+        _subcode = 'getd'
+
+        aetools.keysubst(_arguments, self._argmap_get)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+
+class application(aetools.ComponentItem):
+    """application - An application program """
+    want = 'capp'
+class _Prop_selected_text(aetools.NProperty):
+    """selected text - the selected text """
+    which = 'stxt'
+    want = 'TEXT'
+selected_text = _Prop_selected_text()
+application._superclassnames = []
+application._privpropdict = {
+    'selected_text' : _Prop_selected_text,
+}
+application._privelemdict = {
+}
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+    'capp' : application,
+}
+
+_propdeclarations = {
+    'stxt' : _Prop_selected_text,
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+}

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Explorer/URL_Suite.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Explorer/URL_Suite.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Explorer/URL_Suite.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,54 @@
+"""Suite URL Suite: Standard suite for Uniform Resource Locators
+Level 1, version 1
+
+Generated from /Applications/Internet Explorer.app
+AETE/AEUT resource version 1/0, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'GURL'
+
+class URL_Suite_Events:
+
+    _argmap_GetURL = {
+        'to' : 'dest',
+    }
+
+    def GetURL(self, _object, _attributes={}, **_arguments):
+        """GetURL: Open the URL (and optionally save it to disk)
+        Required argument: URL to open
+        Keyword argument to: File into which to save resource located at URL.
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'GURL'
+        _subcode = 'GURL'
+
+        aetools.keysubst(_arguments, self._argmap_GetURL)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+}
+
+_propdeclarations = {
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+}

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Explorer/Web_Browser_Suite.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Explorer/Web_Browser_Suite.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Explorer/Web_Browser_Suite.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,226 @@
+"""Suite Web Browser Suite: Class of events supported by Web Browser applications
+Level 1, version 1
+
+Generated from /Applications/Internet Explorer.app
+AETE/AEUT resource version 1/0, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'WWW!'
+
+class Web_Browser_Suite_Events:
+
+    def Activate(self, _object=None, _attributes={}, **_arguments):
+        """Activate: Activate Internet Explorer and optionally select window designated by Window Identifier.
+        Required argument: Window Identifier
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: Window Identifier of window to activate
+        """
+        _code = 'WWW!'
+        _subcode = 'ACTV'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def CloseAllWindows(self, _no_object=None, _attributes={}, **_arguments):
+        """CloseAllWindows: Closes all windows
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: Success
+        """
+        _code = 'WWW!'
+        _subcode = 'CLSA'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_CloseWindow = {
+        'ID' : 'WIND',
+        'Title' : 'TITL',
+    }
+
+    def CloseWindow(self, _no_object=None, _attributes={}, **_arguments):
+        """CloseWindow: Close the window specified by either Window Identifier or Title. If no parameter is specified, close the top window.
+        Keyword argument ID: ID of the window to close. (Can use -1 for top window)
+        Keyword argument Title: Title of the window to close
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: Success
+        """
+        _code = 'WWW!'
+        _subcode = 'CLOS'
+
+        aetools.keysubst(_arguments, self._argmap_CloseWindow)
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def GetWindowInfo(self, _object, _attributes={}, **_arguments):
+        """GetWindowInfo: Returns a window info record (URL/Title) for the specified window.
+        Required argument: Window Identifier of the window
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns:
+        """
+        _code = 'WWW!'
+        _subcode = 'WNFO'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def ListWindows(self, _no_object=None, _attributes={}, **_arguments):
+        """ListWindows: Returns list of Window Identifiers for all open windows.
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: undocumented, typecode 'list'
+        """
+        _code = 'WWW!'
+        _subcode = 'LSTW'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_OpenURL = {
+        'to' : 'INTO',
+        'toWindow' : 'WIND',
+        'Flags' : 'FLGS',
+        'FormData' : 'POST',
+        'MIME_Type' : 'MIME',
+    }
+
+    def OpenURL(self, _object, _attributes={}, **_arguments):
+        """OpenURL: Retrieves URL off the Web.
+        Required argument: Fully-qualified URL
+        Keyword argument to: Target file for saving downloaded data
+        Keyword argument toWindow: Target window for resource at URL (-1 for top window, 0 for new window)
+        Keyword argument Flags: Valid Flags settings are: 1-Ignore the document cache; 2-Ignore the image cache; 4-Operate in background mode.
+        Keyword argument FormData: data to post
+        Keyword argument MIME_Type: MIME type of data being posted
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'WWW!'
+        _subcode = 'OURL'
+
+        aetools.keysubst(_arguments, self._argmap_OpenURL)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_ParseAnchor = {
+        'withURL' : 'RELA',
+    }
+
+    def ParseAnchor(self, _object, _attributes={}, **_arguments):
+        """ParseAnchor: Combines a base URL and a relative URL to produce a fully-qualified URL
+        Required argument: Base URL
+        Keyword argument withURL: Relative URL that is combined with the Base URL (in the direct object) to produce a fully-qualified URL.
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: Fully-qualified URL
+        """
+        _code = 'WWW!'
+        _subcode = 'PRSA'
+
+        aetools.keysubst(_arguments, self._argmap_ParseAnchor)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_ShowFile = {
+        'MIME_Type' : 'MIME',
+        'Window_Identifier' : 'WIND',
+        'URL' : 'URL ',
+    }
+
+    def ShowFile(self, _object, _attributes={}, **_arguments):
+        """ShowFile: FileSpec containing data of specified MIME type to be rendered in window specified by Window Identifier.
+        Required argument: The file
+        Keyword argument MIME_Type: MIME type
+        Keyword argument Window_Identifier: Identifier of the target window for the URL. (Can use -1 for top window)
+        Keyword argument URL: URL that allows this document to be reloaded.
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'WWW!'
+        _subcode = 'SHWF'
+
+        aetools.keysubst(_arguments, self._argmap_ShowFile)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+}
+
+_propdeclarations = {
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+}

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Explorer/__init__.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Explorer/__init__.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Explorer/__init__.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,80 @@
+"""
+Package generated from /Applications/Internet Explorer.app
+"""
+import aetools
+Error = aetools.Error
+import Standard_Suite
+import URL_Suite
+import Netscape_Suite
+import Microsoft_Internet_Explorer
+import Web_Browser_Suite
+import Required_Suite
+
+
+_code_to_module = {
+    '****' : Standard_Suite,
+    'GURL' : URL_Suite,
+    'MOSS' : Netscape_Suite,
+    'MSIE' : Microsoft_Internet_Explorer,
+    'WWW!' : Web_Browser_Suite,
+    'reqd' : Required_Suite,
+}
+
+
+
+_code_to_fullname = {
+    '****' : ('Explorer.Standard_Suite', 'Standard_Suite'),
+    'GURL' : ('Explorer.URL_Suite', 'URL_Suite'),
+    'MOSS' : ('Explorer.Netscape_Suite', 'Netscape_Suite'),
+    'MSIE' : ('Explorer.Microsoft_Internet_Explorer', 'Microsoft_Internet_Explorer'),
+    'WWW!' : ('Explorer.Web_Browser_Suite', 'Web_Browser_Suite'),
+    'reqd' : ('Explorer.Required_Suite', 'Required_Suite'),
+}
+
+from Standard_Suite import *
+from URL_Suite import *
+from Netscape_Suite import *
+from Microsoft_Internet_Explorer import *
+from Web_Browser_Suite import *
+from Required_Suite import *
+
+def getbaseclasses(v):
+    if not getattr(v, '_propdict', None):
+        v._propdict = {}
+        v._elemdict = {}
+        for superclassname in getattr(v, '_superclassnames', []):
+            superclass = eval(superclassname)
+            getbaseclasses(superclass)
+            v._propdict.update(getattr(superclass, '_propdict', {}))
+            v._elemdict.update(getattr(superclass, '_elemdict', {}))
+        v._propdict.update(getattr(v, '_privpropdict', {}))
+        v._elemdict.update(getattr(v, '_privelemdict', {}))
+
+import StdSuites
+
+#
+# Set property and element dictionaries now that all classes have been defined
+#
+getbaseclasses(application)
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+    'capp' : application,
+}
+
+
+class Explorer(Standard_Suite_Events,
+        URL_Suite_Events,
+        Netscape_Suite_Events,
+        Microsoft_Internet_Explorer_Events,
+        Web_Browser_Suite_Events,
+        Required_Suite_Events,
+        aetools.TalkTo):
+    _signature = 'MSIE'
+
+    _moduleName = 'Explorer'
+
+    _elemdict = application._elemdict
+    _propdict = application._propdict

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Finder/Containers_and_folders.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Finder/Containers_and_folders.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Finder/Containers_and_folders.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,279 @@
+"""Suite Containers and folders: Classes that can contain other file system items
+Level 1, version 1
+
+Generated from /System/Library/CoreServices/Finder.app
+AETE/AEUT resource version 0/144, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'fndr'
+
+class Containers_and_folders_Events:
+
+    pass
+
+
+class disk(aetools.ComponentItem):
+    """disk - A disk """
+    want = 'cdis'
+class _Prop__3c_Inheritance_3e_(aetools.NProperty):
+    """<Inheritance> - inherits some of its properties from the container class """
+    which = 'c@#^'
+    want = 'ctnr'
+class _Prop_capacity(aetools.NProperty):
+    """capacity - the total number of bytes (free or used) on the disk """
+    which = 'capa'
+    want = 'comp'
+class _Prop_ejectable(aetools.NProperty):
+    """ejectable - Can the media be ejected (floppies, CD's, and so on)? """
+    which = 'isej'
+    want = 'bool'
+class _Prop_format(aetools.NProperty):
+    """format - the filesystem format of this disk """
+    which = 'dfmt'
+    want = 'edfm'
+class _Prop_free_space(aetools.NProperty):
+    """free space - the number of free bytes left on the disk """
+    which = 'frsp'
+    want = 'comp'
+class _Prop_ignore_privileges(aetools.NProperty):
+    """ignore privileges - Ignore permissions on this disk? """
+    which = 'igpr'
+    want = 'bool'
+class _Prop_local_volume(aetools.NProperty):
+    """local volume - Is the media a local volume (as opposed to a file server)? """
+    which = 'isrv'
+    want = 'bool'
+class _Prop_startup(aetools.NProperty):
+    """startup - Is this disk the boot disk? """
+    which = 'istd'
+    want = 'bool'
+#        element 'alia' as ['indx', 'name']
+#        element 'appf' as ['indx', 'name', 'ID  ']
+#        element 'cfol' as ['indx', 'name', 'ID  ']
+#        element 'clpf' as ['indx', 'name']
+#        element 'cobj' as ['indx', 'name']
+#        element 'ctnr' as ['indx', 'name']
+#        element 'docf' as ['indx', 'name']
+#        element 'file' as ['indx', 'name']
+#        element 'inlf' as ['indx', 'name']
+#        element 'pack' as ['indx', 'name']
+
+disks = disk
+
+class desktop_2d_object(aetools.ComponentItem):
+    """desktop-object - Desktop-object is the class of the \xd2desktop\xd3 object """
+    want = 'cdsk'
+#        element 'alia' as ['indx', 'name']
+#        element 'appf' as ['indx', 'name', 'ID  ']
+#        element 'cdis' as ['indx', 'name']
+#        element 'cfol' as ['indx', 'name', 'ID  ']
+#        element 'clpf' as ['indx', 'name']
+#        element 'cobj' as ['indx', 'name']
+#        element 'ctnr' as ['indx', 'name']
+#        element 'docf' as ['indx', 'name']
+#        element 'file' as ['indx', 'name']
+#        element 'inlf' as ['indx', 'name']
+#        element 'pack' as ['indx', 'name']
+
+class folder(aetools.ComponentItem):
+    """folder - A folder """
+    want = 'cfol'
+#        element 'alia' as ['indx', 'name']
+#        element 'appf' as ['indx', 'name', 'ID  ']
+#        element 'cfol' as ['indx', 'name', 'ID  ']
+#        element 'clpf' as ['indx', 'name']
+#        element 'cobj' as ['indx', 'name']
+#        element 'ctnr' as ['indx', 'name']
+#        element 'docf' as ['indx', 'name']
+#        element 'file' as ['indx', 'name']
+#        element 'inlf' as ['indx', 'name']
+#        element 'pack' as ['indx', 'name']
+
+folders = folder
+
+class container(aetools.ComponentItem):
+    """container - An item that contains other items """
+    want = 'ctnr'
+class _Prop_completely_expanded(aetools.NProperty):
+    """completely expanded - (NOT AVAILABLE YET) Are the container and all of its children opened as outlines? (can only be set for containers viewed as lists) """
+    which = 'pexc'
+    want = 'bool'
+class _Prop_container_window(aetools.NProperty):
+    """container window - the container window for this folder """
+    which = 'cwnd'
+    want = 'obj '
+class _Prop_entire_contents(aetools.NProperty):
+    """entire contents - the entire contents of the container, including the contents of its children """
+    which = 'ects'
+    want = 'obj '
+class _Prop_expandable(aetools.NProperty):
+    """expandable - (NOT AVAILABLE YET) Is the container capable of being expanded as an outline? """
+    which = 'pexa'
+    want = 'bool'
+class _Prop_expanded(aetools.NProperty):
+    """expanded - (NOT AVAILABLE YET) Is the container opened as an outline? (can only be set for containers viewed as lists) """
+    which = 'pexp'
+    want = 'bool'
+#        element 'alia' as ['indx', 'name']
+#        element 'appf' as ['indx', 'name', 'ID  ']
+#        element 'cfol' as ['indx', 'name', 'ID  ']
+#        element 'clpf' as ['indx', 'name']
+#        element 'cobj' as ['indx', 'name']
+#        element 'ctnr' as ['indx', 'name']
+#        element 'docf' as ['indx', 'name']
+#        element 'file' as ['indx', 'name']
+#        element 'inlf' as ['indx', 'name']
+#        element 'pack' as ['indx', 'name']
+
+containers = container
+
+class trash_2d_object(aetools.ComponentItem):
+    """trash-object - Trash-object is the class of the \xd2trash\xd3 object """
+    want = 'ctrs'
+class _Prop_warns_before_emptying(aetools.NProperty):
+    """warns before emptying - Display a dialog when emptying the trash? """
+    which = 'warn'
+    want = 'bool'
+#        element 'alia' as ['indx', 'name']
+#        element 'appf' as ['indx', 'name', 'ID  ']
+#        element 'cfol' as ['indx', 'name', 'ID  ']
+#        element 'clpf' as ['indx', 'name']
+#        element 'cobj' as ['indx', 'name']
+#        element 'ctnr' as ['indx', 'name']
+#        element 'docf' as ['indx', 'name']
+#        element 'file' as ['indx', 'name']
+#        element 'inlf' as ['indx', 'name']
+#        element 'pack' as ['indx', 'name']
+disk._superclassnames = ['container']
+import Files
+import Finder_items
+disk._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+    'capacity' : _Prop_capacity,
+    'ejectable' : _Prop_ejectable,
+    'format' : _Prop_format,
+    'free_space' : _Prop_free_space,
+    'ignore_privileges' : _Prop_ignore_privileges,
+    'local_volume' : _Prop_local_volume,
+    'startup' : _Prop_startup,
+}
+disk._privelemdict = {
+    'alias_file' : Files.alias_file,
+    'application_file' : Files.application_file,
+    'clipping' : Files.clipping,
+    'container' : container,
+    'document_file' : Files.document_file,
+    'file' : Files.file,
+    'folder' : folder,
+    'internet_location_file' : Files.internet_location_file,
+    'item' : Finder_items.item,
+    'package' : Files.package,
+}
+desktop_2d_object._superclassnames = ['container']
+desktop_2d_object._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+}
+desktop_2d_object._privelemdict = {
+    'alias_file' : Files.alias_file,
+    'application_file' : Files.application_file,
+    'clipping' : Files.clipping,
+    'container' : container,
+    'disk' : disk,
+    'document_file' : Files.document_file,
+    'file' : Files.file,
+    'folder' : folder,
+    'internet_location_file' : Files.internet_location_file,
+    'item' : Finder_items.item,
+    'package' : Files.package,
+}
+folder._superclassnames = ['container']
+folder._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+}
+folder._privelemdict = {
+    'alias_file' : Files.alias_file,
+    'application_file' : Files.application_file,
+    'clipping' : Files.clipping,
+    'container' : container,
+    'document_file' : Files.document_file,
+    'file' : Files.file,
+    'folder' : folder,
+    'internet_location_file' : Files.internet_location_file,
+    'item' : Finder_items.item,
+    'package' : Files.package,
+}
+container._superclassnames = ['item']
+container._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+    'completely_expanded' : _Prop_completely_expanded,
+    'container_window' : _Prop_container_window,
+    'entire_contents' : _Prop_entire_contents,
+    'expandable' : _Prop_expandable,
+    'expanded' : _Prop_expanded,
+}
+container._privelemdict = {
+    'alias_file' : Files.alias_file,
+    'application_file' : Files.application_file,
+    'clipping' : Files.clipping,
+    'container' : container,
+    'document_file' : Files.document_file,
+    'file' : Files.file,
+    'folder' : folder,
+    'internet_location_file' : Files.internet_location_file,
+    'item' : Finder_items.item,
+    'package' : Files.package,
+}
+trash_2d_object._superclassnames = ['container']
+trash_2d_object._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+    'warns_before_emptying' : _Prop_warns_before_emptying,
+}
+trash_2d_object._privelemdict = {
+    'alias_file' : Files.alias_file,
+    'application_file' : Files.application_file,
+    'clipping' : Files.clipping,
+    'container' : container,
+    'document_file' : Files.document_file,
+    'file' : Files.file,
+    'folder' : folder,
+    'internet_location_file' : Files.internet_location_file,
+    'item' : Finder_items.item,
+    'package' : Files.package,
+}
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+    'cdis' : disk,
+    'cdsk' : desktop_2d_object,
+    'cfol' : folder,
+    'ctnr' : container,
+    'ctrs' : trash_2d_object,
+}
+
+_propdeclarations = {
+    'c@#^' : _Prop__3c_Inheritance_3e_,
+    'capa' : _Prop_capacity,
+    'cwnd' : _Prop_container_window,
+    'dfmt' : _Prop_format,
+    'ects' : _Prop_entire_contents,
+    'frsp' : _Prop_free_space,
+    'igpr' : _Prop_ignore_privileges,
+    'isej' : _Prop_ejectable,
+    'isrv' : _Prop_local_volume,
+    'istd' : _Prop_startup,
+    'pexa' : _Prop_expandable,
+    'pexc' : _Prop_completely_expanded,
+    'pexp' : _Prop_expanded,
+    'warn' : _Prop_warns_before_emptying,
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+}

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Finder/Enumerations.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Finder/Enumerations.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Finder/Enumerations.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,145 @@
+"""Suite Enumerations: Enumerations for the Finder
+Level 1, version 1
+
+Generated from /System/Library/CoreServices/Finder.app
+AETE/AEUT resource version 0/144, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'tpnm'
+
+from StdSuites.Type_Names_Suite import *
+class Enumerations_Events(Type_Names_Suite_Events):
+
+    pass
+
+_Enum_earr = {
+    'not_arranged' : 'narr',    #
+    'snap_to_grid' : 'grda',    #
+    'arranged_by_name' : 'nama',        #
+    'arranged_by_modification_date' : 'mdta',   #
+    'arranged_by_creation_date' : 'cdta',       #
+    'arranged_by_size' : 'siza',        #
+    'arranged_by_kind' : 'kina',        #
+    'arranged_by_label' : 'laba',       #
+}
+
+_Enum_ecvw = {
+    'icon_view' : 'icnv',       #
+    'list_view' : 'lsvw',       #
+    'column_view' : 'clvw',     #
+}
+
+_Enum_edfm = {
+    'Mac_OS_format' : 'dfhf',   #
+    'Mac_OS_Extended_format' : 'dfh+',  #
+    'UFS_format' : 'dfuf',      #
+    'NFS_format' : 'dfnf',      #
+    'audio_format' : 'dfau',    #
+    'ProDOS_format' : 'dfpr',   #
+    'MS_2d_DOS_format' : 'dfms',        #
+    'ISO_9660_format' : 'df96', #
+    'High_Sierra_format' : 'dfhs',      #
+    'QuickTake_format' : 'dfqt',        #
+    'Apple_Photo_format' : 'dfph',      #
+    'AppleShare_format' : 'dfas',       #
+    'UDF_format' : 'dfud',      #
+    'WebDAV_format' : 'dfwd',   #
+    'FTP_format' : 'dfft',      #
+    'Packet_2d_written_UDF_format' : 'dfpu',    #
+    'unknown_format' : 'df??',  #
+}
+
+_Enum_elsv = {
+    'name_column' : 'elsn',     #
+    'modification_date_column' : 'elsm',        #
+    'creation_date_column' : 'elsc',    #
+    'size_column' : 'elss',     #
+    'kind_column' : 'elsk',     #
+    'label_column' : 'elsl',    #
+    'version_column' : 'elsv',  #
+    'comment_column' : 'elsC',  #
+}
+
+_Enum_ipnl = {
+    'General_Information_panel' : 'gpnl',       #
+    'Sharing_panel' : 'spnl',   #
+    'Memory_panel' : 'mpnl',    #
+    'Preview_panel' : 'vpnl',   #
+    'Application_panel' : 'apnl',       #
+    'Languages_panel' : 'pklg', #
+    'Plugins_panel' : 'pkpg',   #
+    'Name__26__Extension_panel' : 'npnl',       #
+    'Comments_panel' : 'cpnl',  #
+    'Content_Index_panel' : 'cinl',     #
+}
+
+_Enum_isiz = {
+    'mini' : 'miic',    #
+    'small' : 'smic',   #
+    'large' : 'lgic',   #
+}
+
+_Enum_lvic = {
+    'small_icon' : 'smic',      #
+    'large_icon' : 'lgic',      #
+}
+
+_Enum_priv = {
+    'read_only' : 'read',       #
+    'read_write' : 'rdwr',      #
+    'write_only' : 'writ',      #
+    'none' : 'none',    #
+}
+
+_Enum_sodr = {
+    'normal' : 'snrm',  #
+    'reversed' : 'srvs',        #
+}
+
+_Enum_vwby = {
+    'conflicts' : 'cflc',       #
+    'existing_items' : 'exsi',  #
+    'small_icon' : 'smic',      #
+    'icon' : 'iimg',    #
+    'name' : 'pnam',    #
+    'modification_date' : 'asmo',       #
+    'size' : 'ptsz',    #
+    'kind' : 'kind',    #
+    'comment' : 'comt', #
+    'label' : 'labi',   #
+    'version' : 'vers', #
+    'creation_date' : 'ascd',   #
+    'small_button' : 'smbu',    #
+    'large_button' : 'lgbu',    #
+    'grid' : 'grid',    #
+    'all' : 'kyal',     #
+}
+
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+}
+
+_propdeclarations = {
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+    'earr' : _Enum_earr,
+    'ecvw' : _Enum_ecvw,
+    'edfm' : _Enum_edfm,
+    'elsv' : _Enum_elsv,
+    'ipnl' : _Enum_ipnl,
+    'isiz' : _Enum_isiz,
+    'lvic' : _Enum_lvic,
+    'priv' : _Enum_priv,
+    'sodr' : _Enum_sodr,
+    'vwby' : _Enum_vwby,
+}

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Finder/Files.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Finder/Files.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Finder/Files.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,212 @@
+"""Suite Files: Classes representing files
+Level 1, version 1
+
+Generated from /System/Library/CoreServices/Finder.app
+AETE/AEUT resource version 0/144, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'fndr'
+
+class Files_Events:
+
+    pass
+
+
+class alias_file(aetools.ComponentItem):
+    """alias file - An alias file (created with \xd2Make Alias\xd3) """
+    want = 'alia'
+class _Prop__3c_Inheritance_3e_(aetools.NProperty):
+    """<Inheritance> - inherits some of its properties from the file class """
+    which = 'c@#^'
+    want = 'file'
+class _Prop_original_item(aetools.NProperty):
+    """original item - the original item pointed to by the alias """
+    which = 'orig'
+    want = 'obj '
+
+alias_files = alias_file
+
+class application_file(aetools.ComponentItem):
+    """application file - An application's file on disk """
+    want = 'appf'
+class _Prop_accepts_high_level_events(aetools.NProperty):
+    """accepts high level events - Is the application high-level event aware? (OBSOLETE: always returns true) """
+    which = 'isab'
+    want = 'bool'
+class _Prop_has_scripting_terminology(aetools.NProperty):
+    """has scripting terminology - Does the process have a scripting terminology, i.e., can it be scripted? """
+    which = 'hscr'
+    want = 'bool'
+class _Prop_minimum_size(aetools.NProperty):
+    """minimum size - the smallest memory size with which the application can be launched """
+    which = 'mprt'
+    want = 'long'
+class _Prop_opens_in_Classic(aetools.NProperty):
+    """opens in Classic - Should the application launch in the Classic environment? """
+    which = 'Clsc'
+    want = 'bool'
+class _Prop_preferred_size(aetools.NProperty):
+    """preferred size - the memory size with which the application will be launched """
+    which = 'appt'
+    want = 'long'
+class _Prop_suggested_size(aetools.NProperty):
+    """suggested size - the memory size with which the developer recommends the application be launched """
+    which = 'sprt'
+    want = 'long'
+
+application_files = application_file
+
+class clipping(aetools.ComponentItem):
+    """clipping - A clipping """
+    want = 'clpf'
+class _Prop_clipping_window(aetools.NProperty):
+    """clipping window - (NOT AVAILABLE YET) the clipping window for this clipping """
+    which = 'lwnd'
+    want = 'obj '
+
+clippings = clipping
+
+class document_file(aetools.ComponentItem):
+    """document file - A document file """
+    want = 'docf'
+
+document_files = document_file
+
+class file(aetools.ComponentItem):
+    """file - A file """
+    want = 'file'
+class _Prop_creator_type(aetools.NProperty):
+    """creator type - the OSType identifying the application that created the item """
+    which = 'fcrt'
+    want = 'type'
+class _Prop_file_type(aetools.NProperty):
+    """file type - the OSType identifying the type of data contained in the item """
+    which = 'asty'
+    want = 'type'
+class _Prop_product_version(aetools.NProperty):
+    """product version - the version of the product (visible at the top of the \xd2Get Info\xd3 window) """
+    which = 'ver2'
+    want = 'utxt'
+class _Prop_stationery(aetools.NProperty):
+    """stationery - Is the file a stationery pad? """
+    which = 'pspd'
+    want = 'bool'
+class _Prop_version(aetools.NProperty):
+    """version - the version of the file (visible at the bottom of the \xd2Get Info\xd3 window) """
+    which = 'vers'
+    want = 'utxt'
+
+files = file
+
+class internet_location_file(aetools.ComponentItem):
+    """internet location file - An file containing an internet location """
+    want = 'inlf'
+class _Prop_location(aetools.NProperty):
+    """location - the internet location """
+    which = 'iloc'
+    want = 'utxt'
+
+internet_location_files = internet_location_file
+
+class package(aetools.ComponentItem):
+    """package - A package """
+    want = 'pack'
+
+packages = package
+alias_file._superclassnames = ['file']
+alias_file._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+    'original_item' : _Prop_original_item,
+}
+alias_file._privelemdict = {
+}
+application_file._superclassnames = ['file']
+application_file._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+    'accepts_high_level_events' : _Prop_accepts_high_level_events,
+    'has_scripting_terminology' : _Prop_has_scripting_terminology,
+    'minimum_size' : _Prop_minimum_size,
+    'opens_in_Classic' : _Prop_opens_in_Classic,
+    'preferred_size' : _Prop_preferred_size,
+    'suggested_size' : _Prop_suggested_size,
+}
+application_file._privelemdict = {
+}
+clipping._superclassnames = ['file']
+clipping._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+    'clipping_window' : _Prop_clipping_window,
+}
+clipping._privelemdict = {
+}
+document_file._superclassnames = ['file']
+document_file._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+}
+document_file._privelemdict = {
+}
+import Finder_items
+file._superclassnames = ['item']
+file._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+    'creator_type' : _Prop_creator_type,
+    'file_type' : _Prop_file_type,
+    'product_version' : _Prop_product_version,
+    'stationery' : _Prop_stationery,
+    'version' : _Prop_version,
+}
+file._privelemdict = {
+}
+internet_location_file._superclassnames = ['file']
+internet_location_file._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+    'location' : _Prop_location,
+}
+internet_location_file._privelemdict = {
+}
+package._superclassnames = ['item']
+package._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+}
+package._privelemdict = {
+}
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+    'alia' : alias_file,
+    'appf' : application_file,
+    'clpf' : clipping,
+    'docf' : document_file,
+    'file' : file,
+    'inlf' : internet_location_file,
+    'pack' : package,
+}
+
+_propdeclarations = {
+    'Clsc' : _Prop_opens_in_Classic,
+    'appt' : _Prop_preferred_size,
+    'asty' : _Prop_file_type,
+    'c@#^' : _Prop__3c_Inheritance_3e_,
+    'fcrt' : _Prop_creator_type,
+    'hscr' : _Prop_has_scripting_terminology,
+    'iloc' : _Prop_location,
+    'isab' : _Prop_accepts_high_level_events,
+    'lwnd' : _Prop_clipping_window,
+    'mprt' : _Prop_minimum_size,
+    'orig' : _Prop_original_item,
+    'pspd' : _Prop_stationery,
+    'sprt' : _Prop_suggested_size,
+    'ver2' : _Prop_product_version,
+    'vers' : _Prop_version,
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+}

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Finder/Finder_Basics.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Finder/Finder_Basics.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Finder/Finder_Basics.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,207 @@
+"""Suite Finder Basics: Commonly-used Finder commands and object classes
+Level 1, version 1
+
+Generated from /System/Library/CoreServices/Finder.app
+AETE/AEUT resource version 0/144, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'fndr'
+
+class Finder_Basics_Events:
+
+    def copy(self, _no_object=None, _attributes={}, **_arguments):
+        """copy: (NOT AVAILABLE YET) Copy the selected items to the clipboard (the Finder must be the front application)
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'misc'
+        _subcode = 'copy'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_sort = {
+        'by' : 'by  ',
+    }
+
+    def sort(self, _object, _attributes={}, **_arguments):
+        """sort: (NOT AVAILABLE YET) Return the specified object(s) in a sorted list
+        Required argument: a list of finder objects to sort
+        Keyword argument by: the property to sort the items by (name, index, date, etc.)
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: the sorted items in their new order
+        """
+        _code = 'DATA'
+        _subcode = 'SORT'
+
+        aetools.keysubst(_arguments, self._argmap_sort)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+
+class application(aetools.ComponentItem):
+    """application - The Finder """
+    want = 'capp'
+class _Prop_Finder_preferences(aetools.NProperty):
+    """Finder preferences - (NOT AVAILABLE YET) Various preferences that apply to the Finder as a whole """
+    which = 'pfrp'
+    want = 'cprf'
+Finder_preferences = _Prop_Finder_preferences()
+class _Prop_clipboard(aetools.NProperty):
+    """clipboard - (NOT AVAILABLE YET) the Finder\xd5s clipboard window """
+    which = 'pcli'
+    want = 'obj '
+clipboard = _Prop_clipboard()
+class _Prop_desktop(aetools.NProperty):
+    """desktop - the desktop """
+    which = 'desk'
+    want = 'cdsk'
+desktop = _Prop_desktop()
+class _Prop_frontmost(aetools.NProperty):
+    """frontmost - Is the Finder the frontmost process? """
+    which = 'pisf'
+    want = 'bool'
+frontmost = _Prop_frontmost()
+class _Prop_home(aetools.NProperty):
+    """home - the home directory """
+    which = 'home'
+    want = 'cfol'
+home = _Prop_home()
+class _Prop_insertion_location(aetools.NProperty):
+    """insertion location - the container in which a new folder would appear if \xd2New Folder\xd3 was selected """
+    which = 'pins'
+    want = 'obj '
+insertion_location = _Prop_insertion_location()
+class _Prop_name(aetools.NProperty):
+    """name - the Finder\xd5s name """
+    which = 'pnam'
+    want = 'itxt'
+name = _Prop_name()
+class _Prop_product_version(aetools.NProperty):
+    """product version - the version of the System software running on this computer """
+    which = 'ver2'
+    want = 'utxt'
+product_version = _Prop_product_version()
+class _Prop_selection(aetools.NProperty):
+    """selection - the selection in the frontmost Finder window """
+    which = 'sele'
+    want = 'obj '
+selection = _Prop_selection()
+class _Prop_startup_disk(aetools.NProperty):
+    """startup disk - the startup disk """
+    which = 'sdsk'
+    want = 'cdis'
+startup_disk = _Prop_startup_disk()
+class _Prop_trash(aetools.NProperty):
+    """trash - the trash """
+    which = 'trsh'
+    want = 'ctrs'
+trash = _Prop_trash()
+class _Prop_version(aetools.NProperty):
+    """version - the version of the Finder """
+    which = 'vers'
+    want = 'utxt'
+version = _Prop_version()
+class _Prop_visible(aetools.NProperty):
+    """visible - Is the Finder\xd5s layer visible? """
+    which = 'pvis'
+    want = 'bool'
+visible = _Prop_visible()
+#        element 'alia' as ['indx', 'name']
+#        element 'appf' as ['indx', 'name', 'ID  ']
+#        element 'brow' as ['indx', 'ID  ']
+#        element 'cdis' as ['indx', 'name', 'ID  ']
+#        element 'cfol' as ['indx', 'name', 'ID  ']
+#        element 'clpf' as ['indx', 'name']
+#        element 'cobj' as ['indx', 'rele', 'name', 'rang', 'test']
+#        element 'ctnr' as ['indx', 'name']
+#        element 'cwin' as ['indx', 'name']
+#        element 'docf' as ['indx', 'name']
+#        element 'file' as ['indx', 'name']
+#        element 'inlf' as ['indx', 'name']
+#        element 'lwnd' as ['indx', 'name']
+#        element 'pack' as ['indx', 'name']
+application._superclassnames = []
+import Files
+import Window_classes
+import Containers_and_folders
+import Finder_items
+application._privpropdict = {
+    'Finder_preferences' : _Prop_Finder_preferences,
+    'clipboard' : _Prop_clipboard,
+    'desktop' : _Prop_desktop,
+    'frontmost' : _Prop_frontmost,
+    'home' : _Prop_home,
+    'insertion_location' : _Prop_insertion_location,
+    'name' : _Prop_name,
+    'product_version' : _Prop_product_version,
+    'selection' : _Prop_selection,
+    'startup_disk' : _Prop_startup_disk,
+    'trash' : _Prop_trash,
+    'version' : _Prop_version,
+    'visible' : _Prop_visible,
+}
+application._privelemdict = {
+    'Finder_window' : Window_classes.Finder_window,
+    'alias_file' : Files.alias_file,
+    'application_file' : Files.application_file,
+    'clipping' : Files.clipping,
+    'clipping_window' : Window_classes.clipping_window,
+    'container' : Containers_and_folders.container,
+    'disk' : Containers_and_folders.disk,
+    'document_file' : Files.document_file,
+    'file' : Files.file,
+    'folder' : Containers_and_folders.folder,
+    'internet_location_file' : Files.internet_location_file,
+    'item' : Finder_items.item,
+    'package' : Files.package,
+    'window' : Window_classes.window,
+}
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+    'capp' : application,
+}
+
+_propdeclarations = {
+    'desk' : _Prop_desktop,
+    'home' : _Prop_home,
+    'pcli' : _Prop_clipboard,
+    'pfrp' : _Prop_Finder_preferences,
+    'pins' : _Prop_insertion_location,
+    'pisf' : _Prop_frontmost,
+    'pnam' : _Prop_name,
+    'pvis' : _Prop_visible,
+    'sdsk' : _Prop_startup_disk,
+    'sele' : _Prop_selection,
+    'trsh' : _Prop_trash,
+    'ver2' : _Prop_product_version,
+    'vers' : _Prop_version,
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+}

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Finder/Finder_items.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Finder/Finder_items.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Finder/Finder_items.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,355 @@
+"""Suite Finder items: Commands used with file system items, and basic item definition
+Level 1, version 1
+
+Generated from /System/Library/CoreServices/Finder.app
+AETE/AEUT resource version 0/144, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'fndr'
+
+class Finder_items_Events:
+
+    def add_to_favorites(self, _object, _attributes={}, **_arguments):
+        """add to favorites: (NOT AVAILABLE YET) Add the items to the user\xd5s Favorites
+        Required argument: the items to add to the collection of Favorites
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'fndr'
+        _subcode = 'ffav'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_clean_up = {
+        'by' : 'by  ',
+    }
+
+    def clean_up(self, _object, _attributes={}, **_arguments):
+        """clean up: (NOT AVAILABLE YET) Arrange items in window nicely (only applies to open windows in icon view that are not kept arranged)
+        Required argument: the window to clean up
+        Keyword argument by: the order in which to clean up the objects (name, index, date, etc.)
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'fndr'
+        _subcode = 'fclu'
+
+        aetools.keysubst(_arguments, self._argmap_clean_up)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def eject(self, _object=None, _attributes={}, **_arguments):
+        """eject: Eject the specified disk(s)
+        Required argument: the disk(s) to eject
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'fndr'
+        _subcode = 'ejct'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def empty(self, _object=None, _attributes={}, **_arguments):
+        """empty: Empty the trash
+        Required argument: \xd2empty\xd3 and \xd2empty trash\xd3 both do the same thing
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'fndr'
+        _subcode = 'empt'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def erase(self, _object, _attributes={}, **_arguments):
+        """erase: (NOT AVAILABLE) Erase the specified disk(s)
+        Required argument: the items to erase
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'fndr'
+        _subcode = 'fera'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def reveal(self, _object, _attributes={}, **_arguments):
+        """reveal: Bring the specified object(s) into view
+        Required argument: the object to be made visible
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'misc'
+        _subcode = 'mvis'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_update = {
+        'necessity' : 'nec?',
+        'registering_applications' : 'reg?',
+    }
+
+    def update(self, _object, _attributes={}, **_arguments):
+        """update: Update the display of the specified object(s) to match their on-disk representation
+        Required argument: the item to update
+        Keyword argument necessity: only update if necessary (i.e. a finder window is open).  default is false
+        Keyword argument registering_applications: register applications. default is true
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'fndr'
+        _subcode = 'fupd'
+
+        aetools.keysubst(_arguments, self._argmap_update)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+
+class item(aetools.ComponentItem):
+    """item - An item """
+    want = 'cobj'
+class _Prop_bounds(aetools.NProperty):
+    """bounds - the bounding rectangle of the item (can only be set for an item in a window viewed as icons or buttons) """
+    which = 'pbnd'
+    want = 'qdrt'
+class _Prop_comment(aetools.NProperty):
+    """comment - the comment of the item, displayed in the \xd2Get Info\xd3 window """
+    which = 'comt'
+    want = 'utxt'
+class _Prop_container(aetools.NProperty):
+    """container - the container of the item """
+    which = 'ctnr'
+    want = 'obj '
+class _Prop_creation_date(aetools.NProperty):
+    """creation date - the date on which the item was created """
+    which = 'ascd'
+    want = 'ldt '
+class _Prop_description(aetools.NProperty):
+    """description - a description of the item """
+    which = 'dscr'
+    want = 'utxt'
+class _Prop_disk(aetools.NProperty):
+    """disk - the disk on which the item is stored """
+    which = 'cdis'
+    want = 'obj '
+class _Prop_displayed_name(aetools.NProperty):
+    """displayed name - the user-visible name of the item """
+    which = 'dnam'
+    want = 'utxt'
+class _Prop_everyones_privileges(aetools.NProperty):
+    """everyones privileges -  """
+    which = 'gstp'
+    want = 'priv'
+class _Prop_extension_hidden(aetools.NProperty):
+    """extension hidden - Is the item's extension hidden from the user? """
+    which = 'hidx'
+    want = 'bool'
+class _Prop_group(aetools.NProperty):
+    """group - the user or group that has special access to the container """
+    which = 'sgrp'
+    want = 'utxt'
+class _Prop_group_privileges(aetools.NProperty):
+    """group privileges -  """
+    which = 'gppr'
+    want = 'priv'
+class _Prop_icon(aetools.NProperty):
+    """icon - the icon bitmap of the item """
+    which = 'iimg'
+    want = 'ifam'
+class _Prop_index(aetools.NProperty):
+    """index - the index in the front-to-back ordering within its container """
+    which = 'pidx'
+    want = 'long'
+class _Prop_information_window(aetools.NProperty):
+    """information window - the information window for the item """
+    which = 'iwnd'
+    want = 'obj '
+class _Prop_kind(aetools.NProperty):
+    """kind - the kind of the item """
+    which = 'kind'
+    want = 'utxt'
+class _Prop_label_index(aetools.NProperty):
+    """label index - the label of the item """
+    which = 'labi'
+    want = 'long'
+class _Prop_locked(aetools.NProperty):
+    """locked - Is the file locked? """
+    which = 'aslk'
+    want = 'bool'
+class _Prop_modification_date(aetools.NProperty):
+    """modification date - the date on which the item was last modified """
+    which = 'asmo'
+    want = 'ldt '
+class _Prop_name(aetools.NProperty):
+    """name - the name of the item """
+    which = 'pnam'
+    want = 'utxt'
+class _Prop_name_extension(aetools.NProperty):
+    """name extension - the name extension of the item (such as \xd2txt\xd3) """
+    which = 'nmxt'
+    want = 'utxt'
+class _Prop_owner(aetools.NProperty):
+    """owner - the user that owns the container """
+    which = 'sown'
+    want = 'utxt'
+class _Prop_owner_privileges(aetools.NProperty):
+    """owner privileges -  """
+    which = 'ownr'
+    want = 'priv'
+class _Prop_physical_size(aetools.NProperty):
+    """physical size - the actual space used by the item on disk """
+    which = 'phys'
+    want = 'comp'
+class _Prop_position(aetools.NProperty):
+    """position - the position of the item within its parent window (can only be set for an item in a window viewed as icons or buttons) """
+    which = 'posn'
+    want = 'QDpt'
+class _Prop_properties(aetools.NProperty):
+    """properties - every property of an item """
+    which = 'pALL'
+    want = 'reco'
+class _Prop_size(aetools.NProperty):
+    """size - the logical size of the item """
+    which = 'ptsz'
+    want = 'comp'
+class _Prop_url(aetools.NProperty):
+    """url - the url of the item """
+    which = 'pURL'
+    want = 'utxt'
+
+items = item
+item._superclassnames = []
+item._privpropdict = {
+    'bounds' : _Prop_bounds,
+    'comment' : _Prop_comment,
+    'container' : _Prop_container,
+    'creation_date' : _Prop_creation_date,
+    'description' : _Prop_description,
+    'disk' : _Prop_disk,
+    'displayed_name' : _Prop_displayed_name,
+    'everyones_privileges' : _Prop_everyones_privileges,
+    'extension_hidden' : _Prop_extension_hidden,
+    'group' : _Prop_group,
+    'group_privileges' : _Prop_group_privileges,
+    'icon' : _Prop_icon,
+    'index' : _Prop_index,
+    'information_window' : _Prop_information_window,
+    'kind' : _Prop_kind,
+    'label_index' : _Prop_label_index,
+    'locked' : _Prop_locked,
+    'modification_date' : _Prop_modification_date,
+    'name' : _Prop_name,
+    'name_extension' : _Prop_name_extension,
+    'owner' : _Prop_owner,
+    'owner_privileges' : _Prop_owner_privileges,
+    'physical_size' : _Prop_physical_size,
+    'position' : _Prop_position,
+    'properties' : _Prop_properties,
+    'size' : _Prop_size,
+    'url' : _Prop_url,
+}
+item._privelemdict = {
+}
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+    'cobj' : item,
+}
+
+_propdeclarations = {
+    'ascd' : _Prop_creation_date,
+    'aslk' : _Prop_locked,
+    'asmo' : _Prop_modification_date,
+    'cdis' : _Prop_disk,
+    'comt' : _Prop_comment,
+    'ctnr' : _Prop_container,
+    'dnam' : _Prop_displayed_name,
+    'dscr' : _Prop_description,
+    'gppr' : _Prop_group_privileges,
+    'gstp' : _Prop_everyones_privileges,
+    'hidx' : _Prop_extension_hidden,
+    'iimg' : _Prop_icon,
+    'iwnd' : _Prop_information_window,
+    'kind' : _Prop_kind,
+    'labi' : _Prop_label_index,
+    'nmxt' : _Prop_name_extension,
+    'ownr' : _Prop_owner_privileges,
+    'pALL' : _Prop_properties,
+    'pURL' : _Prop_url,
+    'pbnd' : _Prop_bounds,
+    'phys' : _Prop_physical_size,
+    'pidx' : _Prop_index,
+    'pnam' : _Prop_name,
+    'posn' : _Prop_position,
+    'ptsz' : _Prop_size,
+    'sgrp' : _Prop_group,
+    'sown' : _Prop_owner,
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+}

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Finder/Legacy_suite.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Finder/Legacy_suite.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Finder/Legacy_suite.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,224 @@
+"""Suite Legacy suite: Operations formerly handled by the Finder, but now automatically delegated to other applications
+Level 1, version 1
+
+Generated from /System/Library/CoreServices/Finder.app
+AETE/AEUT resource version 0/144, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'fleg'
+
+class Legacy_suite_Events:
+
+    def restart(self, _no_object=None, _attributes={}, **_arguments):
+        """restart: Restart the computer
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'fndr'
+        _subcode = 'rest'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def shut_down(self, _no_object=None, _attributes={}, **_arguments):
+        """shut down: Shut Down the computer
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'fndr'
+        _subcode = 'shut'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def sleep(self, _no_object=None, _attributes={}, **_arguments):
+        """sleep: Put the computer to sleep
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'fndr'
+        _subcode = 'slep'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+
+class application(aetools.ComponentItem):
+    """application - The Finder """
+    want = 'capp'
+class _Prop_desktop_picture(aetools.NProperty):
+    """desktop picture - the desktop picture of the main monitor """
+    which = 'dpic'
+    want = 'file'
+desktop_picture = _Prop_desktop_picture()
+
+class application_process(aetools.ComponentItem):
+    """application process - A process launched from an application file """
+    want = 'pcap'
+class _Prop__3c_Inheritance_3e_(aetools.NProperty):
+    """<Inheritance> - inherits some of its properties from the process class """
+    which = 'c@#^'
+    want = 'prcs'
+class _Prop_application_file(aetools.NProperty):
+    """application file - the application file from which this process was launched """
+    which = 'appf'
+    want = 'appf'
+
+application_processes = application_process
+
+class desk_accessory_process(aetools.ComponentItem):
+    """desk accessory process - A process launched from a desk accessory file """
+    want = 'pcda'
+class _Prop_desk_accessory_file(aetools.NProperty):
+    """desk accessory file - the desk accessory file from which this process was launched """
+    which = 'dafi'
+    want = 'obj '
+
+desk_accessory_processes = desk_accessory_process
+
+class process(aetools.ComponentItem):
+    """process - A process running on this computer """
+    want = 'prcs'
+class _Prop_accepts_high_level_events(aetools.NProperty):
+    """accepts high level events - Is the process high-level event aware (accepts open application, open document, print document, and quit)? """
+    which = 'isab'
+    want = 'bool'
+class _Prop_accepts_remote_events(aetools.NProperty):
+    """accepts remote events - Does the process accept remote events? """
+    which = 'revt'
+    want = 'bool'
+class _Prop_creator_type(aetools.NProperty):
+    """creator type - the OSType of the creator of the process (the signature) """
+    which = 'fcrt'
+    want = 'type'
+class _Prop_file(aetools.NProperty):
+    """file - the file from which the process was launched """
+    which = 'file'
+    want = 'obj '
+class _Prop_file_type(aetools.NProperty):
+    """file type - the OSType of the file type of the process """
+    which = 'asty'
+    want = 'type'
+class _Prop_frontmost(aetools.NProperty):
+    """frontmost - Is the process the frontmost process? """
+    which = 'pisf'
+    want = 'bool'
+class _Prop_has_scripting_terminology(aetools.NProperty):
+    """has scripting terminology - Does the process have a scripting terminology, i.e., can it be scripted? """
+    which = 'hscr'
+    want = 'bool'
+class _Prop_name(aetools.NProperty):
+    """name - the name of the process """
+    which = 'pnam'
+    want = 'itxt'
+class _Prop_partition_space_used(aetools.NProperty):
+    """partition space used - the number of bytes currently used in the process' partition """
+    which = 'pusd'
+    want = 'long'
+class _Prop_total_partition_size(aetools.NProperty):
+    """total partition size - the size of the partition with which the process was launched """
+    which = 'appt'
+    want = 'long'
+class _Prop_visible(aetools.NProperty):
+    """visible - Is the process' layer visible? """
+    which = 'pvis'
+    want = 'bool'
+
+processes = process
+application._superclassnames = []
+application._privpropdict = {
+    'desktop_picture' : _Prop_desktop_picture,
+}
+application._privelemdict = {
+}
+application_process._superclassnames = ['process']
+application_process._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+    'application_file' : _Prop_application_file,
+}
+application_process._privelemdict = {
+}
+desk_accessory_process._superclassnames = ['process']
+desk_accessory_process._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+    'desk_accessory_file' : _Prop_desk_accessory_file,
+}
+desk_accessory_process._privelemdict = {
+}
+process._superclassnames = []
+process._privpropdict = {
+    'accepts_high_level_events' : _Prop_accepts_high_level_events,
+    'accepts_remote_events' : _Prop_accepts_remote_events,
+    'creator_type' : _Prop_creator_type,
+    'file' : _Prop_file,
+    'file_type' : _Prop_file_type,
+    'frontmost' : _Prop_frontmost,
+    'has_scripting_terminology' : _Prop_has_scripting_terminology,
+    'name' : _Prop_name,
+    'partition_space_used' : _Prop_partition_space_used,
+    'total_partition_size' : _Prop_total_partition_size,
+    'visible' : _Prop_visible,
+}
+process._privelemdict = {
+}
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+    'capp' : application,
+    'pcap' : application_process,
+    'pcda' : desk_accessory_process,
+    'prcs' : process,
+}
+
+_propdeclarations = {
+    'appf' : _Prop_application_file,
+    'appt' : _Prop_total_partition_size,
+    'asty' : _Prop_file_type,
+    'c@#^' : _Prop__3c_Inheritance_3e_,
+    'dafi' : _Prop_desk_accessory_file,
+    'dpic' : _Prop_desktop_picture,
+    'fcrt' : _Prop_creator_type,
+    'file' : _Prop_file,
+    'hscr' : _Prop_has_scripting_terminology,
+    'isab' : _Prop_accepts_high_level_events,
+    'pisf' : _Prop_frontmost,
+    'pnam' : _Prop_name,
+    'pusd' : _Prop_partition_space_used,
+    'pvis' : _Prop_visible,
+    'revt' : _Prop_accepts_remote_events,
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+}

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Finder/Standard_Suite.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Finder/Standard_Suite.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Finder/Standard_Suite.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,335 @@
+"""Suite Standard Suite: Common terms that most applications should support
+Level 1, version 1
+
+Generated from /System/Library/CoreServices/Finder.app
+AETE/AEUT resource version 0/144, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'CoRe'
+
+from StdSuites.Standard_Suite import *
+class Standard_Suite_Events(Standard_Suite_Events):
+
+    def close(self, _object, _attributes={}, **_arguments):
+        """close: Close an object
+        Required argument: the object to close
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'core'
+        _subcode = 'clos'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_count = {
+        'each' : 'kocl',
+    }
+
+    def count(self, _object, _attributes={}, **_arguments):
+        """count: Return the number of elements of a particular class within an object
+        Required argument: the object whose elements are to be counted
+        Keyword argument each: the class of the elements to be counted
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: the number of elements
+        """
+        _code = 'core'
+        _subcode = 'cnte'
+
+        aetools.keysubst(_arguments, self._argmap_count)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_data_size = {
+        'as' : 'rtyp',
+    }
+
+    def data_size(self, _object, _attributes={}, **_arguments):
+        """data size: Return the size in bytes of an object
+        Required argument: the object whose data size is to be returned
+        Keyword argument as: the data type for which the size is calculated
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: the size of the object in bytes
+        """
+        _code = 'core'
+        _subcode = 'dsiz'
+
+        aetools.keysubst(_arguments, self._argmap_data_size)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def delete(self, _object, _attributes={}, **_arguments):
+        """delete: Move an item from its container to the trash
+        Required argument: the item to delete
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: to the item that was just deleted
+        """
+        _code = 'core'
+        _subcode = 'delo'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_duplicate = {
+        'to' : 'insh',
+        'replacing' : 'alrp',
+        'routing_suppressed' : 'rout',
+    }
+
+    def duplicate(self, _object, _attributes={}, **_arguments):
+        """duplicate: Duplicate one or more object(s)
+        Required argument: the object(s) to duplicate
+        Keyword argument to: the new location for the object(s)
+        Keyword argument replacing: Specifies whether or not to replace items in the destination that have the same name as items being duplicated
+        Keyword argument routing_suppressed: Specifies whether or not to autoroute items (default is false). Only applies when copying to the system folder.
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: to the duplicated object(s)
+        """
+        _code = 'core'
+        _subcode = 'clon'
+
+        aetools.keysubst(_arguments, self._argmap_duplicate)
+        _arguments['----'] = _object
+
+        aetools.enumsubst(_arguments, 'alrp', _Enum_bool)
+        aetools.enumsubst(_arguments, 'rout', _Enum_bool)
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def exists(self, _object, _attributes={}, **_arguments):
+        """exists: Verify if an object exists
+        Required argument: the object in question
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: true if it exists, false if not
+        """
+        _code = 'core'
+        _subcode = 'doex'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_make = {
+        'new' : 'kocl',
+        'at' : 'insh',
+        'to' : 'to  ',
+        'with_properties' : 'prdt',
+    }
+
+    def make(self, _no_object=None, _attributes={}, **_arguments):
+        """make: Make a new element
+        Keyword argument new: the class of the new element
+        Keyword argument at: the location at which to insert the element
+        Keyword argument to: when creating an alias file, the original item to create an alias to or when creating a file viewer window, the target of the window
+        Keyword argument with_properties: the initial values for the properties of the element
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: to the new object(s)
+        """
+        _code = 'core'
+        _subcode = 'crel'
+
+        aetools.keysubst(_arguments, self._argmap_make)
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_move = {
+        'to' : 'insh',
+        'replacing' : 'alrp',
+        'positioned_at' : 'mvpl',
+        'routing_suppressed' : 'rout',
+    }
+
+    def move(self, _object, _attributes={}, **_arguments):
+        """move: Move object(s) to a new location
+        Required argument: the object(s) to move
+        Keyword argument to: the new location for the object(s)
+        Keyword argument replacing: Specifies whether or not to replace items in the destination that have the same name as items being moved
+        Keyword argument positioned_at: Gives a list (in local window coordinates) of positions for the destination items
+        Keyword argument routing_suppressed: Specifies whether or not to autoroute items (default is false). Only applies when moving to the system folder.
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: to the object(s) after they have been moved
+        """
+        _code = 'core'
+        _subcode = 'move'
+
+        aetools.keysubst(_arguments, self._argmap_move)
+        _arguments['----'] = _object
+
+        aetools.enumsubst(_arguments, 'alrp', _Enum_bool)
+        aetools.enumsubst(_arguments, 'mvpl', _Enum_list)
+        aetools.enumsubst(_arguments, 'rout', _Enum_bool)
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_open = {
+        'using' : 'usin',
+        'with_properties' : 'prdt',
+    }
+
+    def open(self, _object, _attributes={}, **_arguments):
+        """open: Open the specified object(s)
+        Required argument: list of objects to open
+        Keyword argument using: the application file to open the object with
+        Keyword argument with_properties: the initial values for the properties, to be included with the open command sent to the application that opens the direct object
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'aevt'
+        _subcode = 'odoc'
+
+        aetools.keysubst(_arguments, self._argmap_open)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_print_ = {
+        'with_properties' : 'prdt',
+    }
+
+    def print_(self, _object, _attributes={}, **_arguments):
+        """print: Print the specified object(s)
+        Required argument: list of objects to print
+        Keyword argument with_properties: optional properties to be included with the print command sent to the application that prints the direct object
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'aevt'
+        _subcode = 'pdoc'
+
+        aetools.keysubst(_arguments, self._argmap_print_)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def quit(self, _no_object=None, _attributes={}, **_arguments):
+        """quit: Quit the Finder
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'aevt'
+        _subcode = 'quit'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def select(self, _object, _attributes={}, **_arguments):
+        """select: Select the specified object(s)
+        Required argument: the object to select
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'misc'
+        _subcode = 'slct'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+_Enum_list = None # XXXX enum list not found!!
+_Enum_bool = None # XXXX enum bool not found!!
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+}
+
+_propdeclarations = {
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+}

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Finder/Type_Definitions.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Finder/Type_Definitions.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Finder/Type_Definitions.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,346 @@
+"""Suite Type Definitions: Definitions of records used in scripting the Finder
+Level 1, version 1
+
+Generated from /System/Library/CoreServices/Finder.app
+AETE/AEUT resource version 0/144, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'tpdf'
+
+class Type_Definitions_Events:
+
+    pass
+
+
+class alias_list(aetools.ComponentItem):
+    """alias list - A list of aliases.  Use \xd4as alias list\xd5 when a list of aliases is needed (instead of a list of file system item references). """
+    want = 'alst'
+
+class label(aetools.ComponentItem):
+    """label - (NOT AVAILABLE YET) A Finder label (name and color) """
+    want = 'clbl'
+class _Prop_color(aetools.NProperty):
+    """color - the color associated with the label """
+    which = 'colr'
+    want = 'cRGB'
+class _Prop_index(aetools.NProperty):
+    """index - the index in the front-to-back ordering within its container """
+    which = 'pidx'
+    want = 'long'
+class _Prop_name(aetools.NProperty):
+    """name - the name associated with the label """
+    which = 'pnam'
+    want = 'utxt'
+
+class preferences(aetools.ComponentItem):
+    """preferences - (NOT AVAILABLE, SUBJECT TO CHANGE) The Finder Preferences """
+    want = 'cprf'
+class _Prop_button_view_arrangement(aetools.NProperty):
+    """button view arrangement - the method of arrangement of icons in default Finder button view windows """
+    which = 'barr'
+    want = 'earr'
+class _Prop_button_view_icon_size(aetools.NProperty):
+    """button view icon size - the size of icons displayed in Finder button view windows. """
+    which = 'bisz'
+    want = 'long'
+class _Prop_calculates_folder_sizes(aetools.NProperty):
+    """calculates folder sizes - Are folder sizes calculated and displayed in Finder list view windows? """
+    which = 'sfsz'
+    want = 'bool'
+class _Prop_delay_before_springing(aetools.NProperty):
+    """delay before springing - the delay before springing open a container in ticks (1/60th of a second) (12 is shortest delay, 60 is longest delay) """
+    which = 'dela'
+    want = 'shor'
+class _Prop_list_view_icon_size(aetools.NProperty):
+    """list view icon size - the size of icons displayed in Finder list view windows. """
+    which = 'lisz'
+    want = 'long'
+class _Prop_shows_comments(aetools.NProperty):
+    """shows comments - Are comments displayed in default Finder list view windows? """
+    which = 'scom'
+    want = 'bool'
+class _Prop_shows_creation_date(aetools.NProperty):
+    """shows creation date - Are creation dates displayed in default Finder list view windows? """
+    which = 'scda'
+    want = 'bool'
+class _Prop_shows_kind(aetools.NProperty):
+    """shows kind - Are document kinds displayed in default Finder list view windows? """
+    which = 'sknd'
+    want = 'bool'
+class _Prop_shows_label(aetools.NProperty):
+    """shows label - Are labels displayed in default Finder list view windows? """
+    which = 'slbl'
+    want = 'bool'
+class _Prop_shows_modification_date(aetools.NProperty):
+    """shows modification date - Are modification dates displayed in default Finder list view windows? """
+    which = 'sdat'
+    want = 'bool'
+class _Prop_shows_size(aetools.NProperty):
+    """shows size - Are file sizes displayed in default Finder list view windows? """
+    which = 'ssiz'
+    want = 'bool'
+class _Prop_shows_version(aetools.NProperty):
+    """shows version - Are file versions displayed in default Finder list view windows? """
+    which = 'svrs'
+    want = 'bool'
+class _Prop_spatial_view_arrangement(aetools.NProperty):
+    """spatial view arrangement - the method of arrangement of icons in default Finder spatial view windows """
+    which = 'iarr'
+    want = 'earr'
+class _Prop_spatial_view_icon_size(aetools.NProperty):
+    """spatial view icon size - the size of icons displayed in Finder spatial view windows. """
+    which = 'iisz'
+    want = 'long'
+class _Prop_spring_open_folders(aetools.NProperty):
+    """spring open folders - Spring open folders after the specified delay? """
+    which = 'sprg'
+    want = 'bool'
+class _Prop_uses_relative_dates(aetools.NProperty):
+    """uses relative dates - Are relative dates (e.g., today, yesterday) shown  in Finder list view windows? """
+    which = 'urdt'
+    want = 'bool'
+class _Prop_uses_simple_menus(aetools.NProperty):
+    """uses simple menus - Use simplified Finder menus? """
+    which = 'usme'
+    want = 'bool'
+class _Prop_uses_wide_grid(aetools.NProperty):
+    """uses wide grid - Space icons on a wide grid? """
+    which = 'uswg'
+    want = 'bool'
+class _Prop_view_font(aetools.NProperty):
+    """view font - the id of the font used in Finder views. """
+    which = 'vfnt'
+    want = 'long'
+class _Prop_view_font_size(aetools.NProperty):
+    """view font size - the size of the font used in Finder views """
+    which = 'vfsz'
+    want = 'long'
+class _Prop_window(aetools.NProperty):
+    """window - the window that would open if Finder preferences was opened """
+    which = 'cwin'
+    want = 'pwnd'
+#        element 'clbl' as ['indx', 'name']
+
+class icon_view_options(aetools.ComponentItem):
+    """icon view options - the icon view options """
+    want = 'icop'
+
+_Prop_arrangement = _Prop_spatial_view_arrangement
+class _Prop_icon_size(aetools.NProperty):
+    """icon size - the size of icons displayed in the icon view """
+    which = 'lvis'
+    want = 'shor'
+
+class icon_family(aetools.ComponentItem):
+    """icon family - (NOT AVAILABLE YET) A family of icons """
+    want = 'ifam'
+class _Prop_large_32_bit_icon(aetools.NProperty):
+    """large 32 bit icon - the large 32-bit color icon """
+    which = 'il32'
+    want = 'il32'
+class _Prop_large_4_bit_icon(aetools.NProperty):
+    """large 4 bit icon - the large 4-bit color icon """
+    which = 'icl4'
+    want = 'icl4'
+class _Prop_large_8_bit_icon(aetools.NProperty):
+    """large 8 bit icon - the large 8-bit color icon """
+    which = 'icl8'
+    want = 'icl8'
+class _Prop_large_8_bit_mask(aetools.NProperty):
+    """large 8 bit mask - the large 8-bit mask for large 32-bit icons """
+    which = 'l8mk'
+    want = 'l8mk'
+class _Prop_large_monochrome_icon_and_mask(aetools.NProperty):
+    """large monochrome icon and mask - the large black-and-white icon and the mask for large icons """
+    which = 'ICN#'
+    want = 'ICN#'
+class _Prop_small_32_bit_icon(aetools.NProperty):
+    """small 32 bit icon - the small 32-bit color icon """
+    which = 'is32'
+    want = 'is32'
+class _Prop_small_4_bit_icon(aetools.NProperty):
+    """small 4 bit icon - the small 4-bit color icon """
+    which = 'ics4'
+    want = 'ics4'
+class _Prop_small_8_bit_icon(aetools.NProperty):
+    """small 8 bit icon - the small 8-bit color icon """
+    which = 'ics8'
+    want = 'ics8'
+
+_Prop_small_8_bit_mask = _Prop_small_8_bit_icon
+class _Prop_small_monochrome_icon_and_mask(aetools.NProperty):
+    """small monochrome icon and mask - the small black-and-white icon and the mask for small icons """
+    which = 'ics#'
+    want = 'ics#'
+
+class column(aetools.ComponentItem):
+    """column - a column of a list view """
+    want = 'lvcl'
+class _Prop_sort_direction(aetools.NProperty):
+    """sort direction - The direction in which the window is sorted """
+    which = 'sord'
+    want = 'sodr'
+class _Prop_visible(aetools.NProperty):
+    """visible - is this column visible """
+    which = 'pvis'
+    want = 'bool'
+class _Prop_width(aetools.NProperty):
+    """width - the width of this column """
+    which = 'clwd'
+    want = 'shor'
+
+columns = column
+
+class list_view_options(aetools.ComponentItem):
+    """list view options - the list view options """
+    want = 'lvop'
+class _Prop_sort_column(aetools.NProperty):
+    """sort column - the column that the list view is sorted on """
+    which = 'srtc'
+    want = 'lvcl'
+#        element 'lvcl' as ['indx', 'rele', 'rang', 'test']
+alias_list._superclassnames = []
+alias_list._privpropdict = {
+}
+alias_list._privelemdict = {
+}
+label._superclassnames = []
+label._privpropdict = {
+    'color' : _Prop_color,
+    'index' : _Prop_index,
+    'name' : _Prop_name,
+}
+label._privelemdict = {
+}
+preferences._superclassnames = []
+preferences._privpropdict = {
+    'button_view_arrangement' : _Prop_button_view_arrangement,
+    'button_view_icon_size' : _Prop_button_view_icon_size,
+    'calculates_folder_sizes' : _Prop_calculates_folder_sizes,
+    'delay_before_springing' : _Prop_delay_before_springing,
+    'list_view_icon_size' : _Prop_list_view_icon_size,
+    'shows_comments' : _Prop_shows_comments,
+    'shows_creation_date' : _Prop_shows_creation_date,
+    'shows_kind' : _Prop_shows_kind,
+    'shows_label' : _Prop_shows_label,
+    'shows_modification_date' : _Prop_shows_modification_date,
+    'shows_size' : _Prop_shows_size,
+    'shows_version' : _Prop_shows_version,
+    'spatial_view_arrangement' : _Prop_spatial_view_arrangement,
+    'spatial_view_icon_size' : _Prop_spatial_view_icon_size,
+    'spring_open_folders' : _Prop_spring_open_folders,
+    'uses_relative_dates' : _Prop_uses_relative_dates,
+    'uses_simple_menus' : _Prop_uses_simple_menus,
+    'uses_wide_grid' : _Prop_uses_wide_grid,
+    'view_font' : _Prop_view_font,
+    'view_font_size' : _Prop_view_font_size,
+    'window' : _Prop_window,
+}
+preferences._privelemdict = {
+    'label' : label,
+}
+icon_view_options._superclassnames = []
+icon_view_options._privpropdict = {
+    'arrangement' : _Prop_arrangement,
+    'icon_size' : _Prop_icon_size,
+}
+icon_view_options._privelemdict = {
+}
+icon_family._superclassnames = []
+icon_family._privpropdict = {
+    'large_32_bit_icon' : _Prop_large_32_bit_icon,
+    'large_4_bit_icon' : _Prop_large_4_bit_icon,
+    'large_8_bit_icon' : _Prop_large_8_bit_icon,
+    'large_8_bit_mask' : _Prop_large_8_bit_mask,
+    'large_monochrome_icon_and_mask' : _Prop_large_monochrome_icon_and_mask,
+    'small_32_bit_icon' : _Prop_small_32_bit_icon,
+    'small_4_bit_icon' : _Prop_small_4_bit_icon,
+    'small_8_bit_icon' : _Prop_small_8_bit_icon,
+    'small_8_bit_mask' : _Prop_small_8_bit_mask,
+    'small_monochrome_icon_and_mask' : _Prop_small_monochrome_icon_and_mask,
+}
+icon_family._privelemdict = {
+}
+column._superclassnames = []
+column._privpropdict = {
+    'index' : _Prop_index,
+    'name' : _Prop_name,
+    'sort_direction' : _Prop_sort_direction,
+    'visible' : _Prop_visible,
+    'width' : _Prop_width,
+}
+column._privelemdict = {
+}
+list_view_options._superclassnames = []
+list_view_options._privpropdict = {
+    'calculates_folder_sizes' : _Prop_calculates_folder_sizes,
+    'icon_size' : _Prop_icon_size,
+    'sort_column' : _Prop_sort_column,
+    'uses_relative_dates' : _Prop_uses_relative_dates,
+}
+list_view_options._privelemdict = {
+    'column' : column,
+}
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+    'alst' : alias_list,
+    'clbl' : label,
+    'cprf' : preferences,
+    'icop' : icon_view_options,
+    'ifam' : icon_family,
+    'lvcl' : column,
+    'lvop' : list_view_options,
+}
+
+_propdeclarations = {
+    'ICN#' : _Prop_large_monochrome_icon_and_mask,
+    'barr' : _Prop_button_view_arrangement,
+    'bisz' : _Prop_button_view_icon_size,
+    'clwd' : _Prop_width,
+    'colr' : _Prop_color,
+    'cwin' : _Prop_window,
+    'dela' : _Prop_delay_before_springing,
+    'iarr' : _Prop_spatial_view_arrangement,
+    'icl4' : _Prop_large_4_bit_icon,
+    'icl8' : _Prop_large_8_bit_icon,
+    'ics#' : _Prop_small_monochrome_icon_and_mask,
+    'ics4' : _Prop_small_4_bit_icon,
+    'ics8' : _Prop_small_8_bit_icon,
+    'iisz' : _Prop_spatial_view_icon_size,
+    'il32' : _Prop_large_32_bit_icon,
+    'is32' : _Prop_small_32_bit_icon,
+    'l8mk' : _Prop_large_8_bit_mask,
+    'lisz' : _Prop_list_view_icon_size,
+    'lvis' : _Prop_icon_size,
+    'pidx' : _Prop_index,
+    'pnam' : _Prop_name,
+    'pvis' : _Prop_visible,
+    'scda' : _Prop_shows_creation_date,
+    'scom' : _Prop_shows_comments,
+    'sdat' : _Prop_shows_modification_date,
+    'sfsz' : _Prop_calculates_folder_sizes,
+    'sknd' : _Prop_shows_kind,
+    'slbl' : _Prop_shows_label,
+    'sord' : _Prop_sort_direction,
+    'sprg' : _Prop_spring_open_folders,
+    'srtc' : _Prop_sort_column,
+    'ssiz' : _Prop_shows_size,
+    'svrs' : _Prop_shows_version,
+    'urdt' : _Prop_uses_relative_dates,
+    'usme' : _Prop_uses_simple_menus,
+    'uswg' : _Prop_uses_wide_grid,
+    'vfnt' : _Prop_view_font,
+    'vfsz' : _Prop_view_font_size,
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+}

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Finder/Window_classes.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Finder/Window_classes.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Finder/Window_classes.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,229 @@
+"""Suite Window classes: Classes representing windows
+Level 1, version 1
+
+Generated from /System/Library/CoreServices/Finder.app
+AETE/AEUT resource version 0/144, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'fndr'
+
+class Window_classes_Events:
+
+    pass
+
+
+class Finder_window(aetools.ComponentItem):
+    """Finder window - A file viewer window """
+    want = 'brow'
+class _Prop__3c_Inheritance_3e_(aetools.NProperty):
+    """<Inheritance> - inherits some of its properties from the window class """
+    which = 'c@#^'
+    want = 'cwin'
+class _Prop_current_view(aetools.NProperty):
+    """current view - the current view for the container window """
+    which = 'pvew'
+    want = 'ecvw'
+class _Prop_icon_view_options(aetools.NProperty):
+    """icon view options - the icon view options for the container window """
+    which = 'icop'
+    want = 'icop'
+class _Prop_list_view_options(aetools.NProperty):
+    """list view options - the list view options for the container window """
+    which = 'lvop'
+    want = 'lvop'
+class _Prop_target(aetools.NProperty):
+    """target - the container at which this file viewer is targeted """
+    which = 'fvtg'
+    want = 'obj '
+
+Finder_windows = Finder_window
+
+class window(aetools.ComponentItem):
+    """window - A window """
+    want = 'cwin'
+class _Prop_bounds(aetools.NProperty):
+    """bounds - the boundary rectangle for the window """
+    which = 'pbnd'
+    want = 'qdrt'
+class _Prop_closeable(aetools.NProperty):
+    """closeable - Does the window have a close box? """
+    which = 'hclb'
+    want = 'bool'
+class _Prop_collapsed(aetools.NProperty):
+    """collapsed - Is the window collapsed """
+    which = 'wshd'
+    want = 'bool'
+class _Prop_floating(aetools.NProperty):
+    """floating - Does the window have a title bar? """
+    which = 'isfl'
+    want = 'bool'
+class _Prop_id(aetools.NProperty):
+    """id - the unique id for this window """
+    which = 'ID  '
+    want = 'magn'
+class _Prop_index(aetools.NProperty):
+    """index - the number of the window in the front-to-back layer ordering """
+    which = 'pidx'
+    want = 'long'
+class _Prop_modal(aetools.NProperty):
+    """modal - Is the window modal? """
+    which = 'pmod'
+    want = 'bool'
+class _Prop_name(aetools.NProperty):
+    """name - the name of the window """
+    which = 'pnam'
+    want = 'utxt'
+class _Prop_position(aetools.NProperty):
+    """position - the upper left position of the window """
+    which = 'posn'
+    want = 'QDpt'
+class _Prop_properties(aetools.NProperty):
+    """properties - every property of a window """
+    which = 'pALL'
+    want = 'reco'
+class _Prop_resizable(aetools.NProperty):
+    """resizable - Is the window resizable? """
+    which = 'prsz'
+    want = 'bool'
+class _Prop_titled(aetools.NProperty):
+    """titled - Does the window have a title bar? """
+    which = 'ptit'
+    want = 'bool'
+class _Prop_visible(aetools.NProperty):
+    """visible - Is the window visible (always true for open Finder windows)? """
+    which = 'pvis'
+    want = 'bool'
+class _Prop_zoomable(aetools.NProperty):
+    """zoomable - Is the window zoomable? """
+    which = 'iszm'
+    want = 'bool'
+class _Prop_zoomed(aetools.NProperty):
+    """zoomed - Is the window zoomed? """
+    which = 'pzum'
+    want = 'bool'
+class _Prop_zoomed_full_size(aetools.NProperty):
+    """zoomed full size - Is the window zoomed to the full size of the screen? (can only be set, not read) """
+    which = 'zumf'
+    want = 'bool'
+
+windows = window
+
+class information_window(aetools.ComponentItem):
+    """information window - An inspector window (opened by \xd2Show Info\xd3) """
+    want = 'iwnd'
+class _Prop_current_panel(aetools.NProperty):
+    """current panel - the current panel in the information window """
+    which = 'panl'
+    want = 'ipnl'
+class _Prop_item(aetools.NProperty):
+    """item - the item from which this window was opened """
+    which = 'cobj'
+    want = 'obj '
+
+class clipping_window(aetools.ComponentItem):
+    """clipping window - The window containing a clipping """
+    want = 'lwnd'
+
+clipping_windows = clipping_window
+
+class preferences_window(aetools.ComponentItem):
+    """preferences window - (NOT AVAILABLE YET) The Finder Preferences window """
+    want = 'pwnd'
+Finder_window._superclassnames = ['window']
+Finder_window._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+    'current_view' : _Prop_current_view,
+    'icon_view_options' : _Prop_icon_view_options,
+    'list_view_options' : _Prop_list_view_options,
+    'target' : _Prop_target,
+}
+Finder_window._privelemdict = {
+}
+window._superclassnames = []
+window._privpropdict = {
+    'bounds' : _Prop_bounds,
+    'closeable' : _Prop_closeable,
+    'collapsed' : _Prop_collapsed,
+    'floating' : _Prop_floating,
+    'id' : _Prop_id,
+    'index' : _Prop_index,
+    'modal' : _Prop_modal,
+    'name' : _Prop_name,
+    'position' : _Prop_position,
+    'properties' : _Prop_properties,
+    'resizable' : _Prop_resizable,
+    'titled' : _Prop_titled,
+    'visible' : _Prop_visible,
+    'zoomable' : _Prop_zoomable,
+    'zoomed' : _Prop_zoomed,
+    'zoomed_full_size' : _Prop_zoomed_full_size,
+}
+window._privelemdict = {
+}
+information_window._superclassnames = ['window']
+information_window._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+    'current_panel' : _Prop_current_panel,
+    'item' : _Prop_item,
+}
+information_window._privelemdict = {
+}
+clipping_window._superclassnames = ['window']
+clipping_window._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+}
+clipping_window._privelemdict = {
+}
+preferences_window._superclassnames = ['window']
+preferences_window._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+    'current_panel' : _Prop_current_panel,
+}
+preferences_window._privelemdict = {
+}
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+    'brow' : Finder_window,
+    'cwin' : window,
+    'iwnd' : information_window,
+    'lwnd' : clipping_window,
+    'pwnd' : preferences_window,
+}
+
+_propdeclarations = {
+    'ID  ' : _Prop_id,
+    'c@#^' : _Prop__3c_Inheritance_3e_,
+    'cobj' : _Prop_item,
+    'fvtg' : _Prop_target,
+    'hclb' : _Prop_closeable,
+    'icop' : _Prop_icon_view_options,
+    'isfl' : _Prop_floating,
+    'iszm' : _Prop_zoomable,
+    'lvop' : _Prop_list_view_options,
+    'pALL' : _Prop_properties,
+    'panl' : _Prop_current_panel,
+    'pbnd' : _Prop_bounds,
+    'pidx' : _Prop_index,
+    'pmod' : _Prop_modal,
+    'pnam' : _Prop_name,
+    'posn' : _Prop_position,
+    'prsz' : _Prop_resizable,
+    'ptit' : _Prop_titled,
+    'pvew' : _Prop_current_view,
+    'pvis' : _Prop_visible,
+    'pzum' : _Prop_zoomed,
+    'wshd' : _Prop_collapsed,
+    'zumf' : _Prop_zoomed_full_size,
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+}

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Finder/__init__.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Finder/__init__.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Finder/__init__.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,233 @@
+"""
+Package generated from /System/Library/CoreServices/Finder.app
+"""
+import aetools
+Error = aetools.Error
+import Standard_Suite
+import Legacy_suite
+import Containers_and_folders
+import Files
+import Finder_Basics
+import Finder_items
+import Window_classes
+import Type_Definitions
+import Enumerations
+
+
+_code_to_module = {
+    'CoRe' : Standard_Suite,
+    'fleg' : Legacy_suite,
+    'fndr' : Containers_and_folders,
+    'fndr' : Files,
+    'fndr' : Finder_Basics,
+    'fndr' : Finder_items,
+    'fndr' : Window_classes,
+    'tpdf' : Type_Definitions,
+    'tpnm' : Enumerations,
+}
+
+
+
+_code_to_fullname = {
+    'CoRe' : ('Finder.Standard_Suite', 'Standard_Suite'),
+    'fleg' : ('Finder.Legacy_suite', 'Legacy_suite'),
+    'fndr' : ('Finder.Containers_and_folders', 'Containers_and_folders'),
+    'fndr' : ('Finder.Files', 'Files'),
+    'fndr' : ('Finder.Finder_Basics', 'Finder_Basics'),
+    'fndr' : ('Finder.Finder_items', 'Finder_items'),
+    'fndr' : ('Finder.Window_classes', 'Window_classes'),
+    'tpdf' : ('Finder.Type_Definitions', 'Type_Definitions'),
+    'tpnm' : ('Finder.Enumerations', 'Enumerations'),
+}
+
+from Standard_Suite import *
+from Legacy_suite import *
+from Containers_and_folders import *
+from Files import *
+from Finder_Basics import *
+from Finder_items import *
+from Window_classes import *
+from Type_Definitions import *
+from Enumerations import *
+
+def getbaseclasses(v):
+    if not getattr(v, '_propdict', None):
+        v._propdict = {}
+        v._elemdict = {}
+        for superclassname in getattr(v, '_superclassnames', []):
+            superclass = eval(superclassname)
+            getbaseclasses(superclass)
+            v._propdict.update(getattr(superclass, '_propdict', {}))
+            v._elemdict.update(getattr(superclass, '_elemdict', {}))
+        v._propdict.update(getattr(v, '_privpropdict', {}))
+        v._elemdict.update(getattr(v, '_privelemdict', {}))
+
+import StdSuites
+
+#
+# Set property and element dictionaries now that all classes have been defined
+#
+getbaseclasses(StdSuites.Type_Names_Suite.small_integer)
+getbaseclasses(StdSuites.Type_Names_Suite.system_dictionary)
+getbaseclasses(StdSuites.Type_Names_Suite.color_table)
+getbaseclasses(StdSuites.Type_Names_Suite.fixed_point)
+getbaseclasses(StdSuites.Type_Names_Suite.string)
+getbaseclasses(StdSuites.Type_Names_Suite.type_element_info)
+getbaseclasses(StdSuites.Type_Names_Suite.machine_location)
+getbaseclasses(StdSuites.Type_Names_Suite.PostScript_picture)
+getbaseclasses(StdSuites.Type_Names_Suite.type_property_info)
+getbaseclasses(StdSuites.Type_Names_Suite.menu_item)
+getbaseclasses(StdSuites.Type_Names_Suite.scrap_styles)
+getbaseclasses(StdSuites.Type_Names_Suite.fixed_rectangle)
+getbaseclasses(StdSuites.Type_Names_Suite.null)
+getbaseclasses(StdSuites.Type_Names_Suite.type_event_info)
+getbaseclasses(StdSuites.Type_Names_Suite.rotation)
+getbaseclasses(StdSuites.Type_Names_Suite.long_fixed_rectangle)
+getbaseclasses(StdSuites.Type_Names_Suite.long_point)
+getbaseclasses(StdSuites.Type_Names_Suite.target_id)
+getbaseclasses(StdSuites.Type_Names_Suite.type_suite_info)
+getbaseclasses(StdSuites.Type_Names_Suite.type_parameter_info)
+getbaseclasses(StdSuites.Type_Names_Suite.long_fixed_point)
+getbaseclasses(StdSuites.Type_Names_Suite.bounding_rectangle)
+getbaseclasses(StdSuites.Type_Names_Suite.TIFF_picture)
+getbaseclasses(StdSuites.Type_Names_Suite.long_fixed)
+getbaseclasses(StdSuites.Type_Names_Suite.version)
+getbaseclasses(StdSuites.Type_Names_Suite.RGB16_color)
+getbaseclasses(StdSuites.Type_Names_Suite.double_integer)
+getbaseclasses(StdSuites.Type_Names_Suite.location_reference)
+getbaseclasses(StdSuites.Type_Names_Suite.point)
+getbaseclasses(StdSuites.Type_Names_Suite.application_dictionary)
+getbaseclasses(StdSuites.Type_Names_Suite.unsigned_integer)
+getbaseclasses(StdSuites.Type_Names_Suite.menu)
+getbaseclasses(StdSuites.Type_Names_Suite.small_real)
+getbaseclasses(StdSuites.Type_Names_Suite.fixed)
+getbaseclasses(StdSuites.Type_Names_Suite.type_class_info)
+getbaseclasses(StdSuites.Type_Names_Suite.RGB96_color)
+getbaseclasses(StdSuites.Type_Names_Suite.dash_style)
+getbaseclasses(StdSuites.Type_Names_Suite.pixel_map_record)
+getbaseclasses(StdSuites.Type_Names_Suite.extended_real)
+getbaseclasses(StdSuites.Type_Names_Suite.long_rectangle)
+getbaseclasses(process)
+getbaseclasses(application_process)
+getbaseclasses(desk_accessory_process)
+getbaseclasses(application)
+getbaseclasses(trash_2d_object)
+getbaseclasses(desktop_2d_object)
+getbaseclasses(container)
+getbaseclasses(folder)
+getbaseclasses(disk)
+getbaseclasses(application)
+getbaseclasses(alias_file)
+getbaseclasses(package)
+getbaseclasses(file)
+getbaseclasses(application_file)
+getbaseclasses(internet_location_file)
+getbaseclasses(document_file)
+getbaseclasses(clipping)
+getbaseclasses(preferences_window)
+getbaseclasses(Finder_window)
+getbaseclasses(window)
+getbaseclasses(clipping_window)
+getbaseclasses(information_window)
+getbaseclasses(item)
+getbaseclasses(icon_view_options)
+getbaseclasses(preferences)
+getbaseclasses(alias_list)
+getbaseclasses(icon_family)
+getbaseclasses(label)
+getbaseclasses(column)
+getbaseclasses(list_view_options)
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+    'shor' : StdSuites.Type_Names_Suite.small_integer,
+    'aeut' : StdSuites.Type_Names_Suite.system_dictionary,
+    'clrt' : StdSuites.Type_Names_Suite.color_table,
+    'fpnt' : StdSuites.Type_Names_Suite.fixed_point,
+    'TEXT' : StdSuites.Type_Names_Suite.string,
+    'elin' : StdSuites.Type_Names_Suite.type_element_info,
+    'mLoc' : StdSuites.Type_Names_Suite.machine_location,
+    'EPS ' : StdSuites.Type_Names_Suite.PostScript_picture,
+    'pinf' : StdSuites.Type_Names_Suite.type_property_info,
+    'cmen' : StdSuites.Type_Names_Suite.menu_item,
+    'styl' : StdSuites.Type_Names_Suite.scrap_styles,
+    'frct' : StdSuites.Type_Names_Suite.fixed_rectangle,
+    'null' : StdSuites.Type_Names_Suite.null,
+    'evin' : StdSuites.Type_Names_Suite.type_event_info,
+    'trot' : StdSuites.Type_Names_Suite.rotation,
+    'lfrc' : StdSuites.Type_Names_Suite.long_fixed_rectangle,
+    'lpnt' : StdSuites.Type_Names_Suite.long_point,
+    'targ' : StdSuites.Type_Names_Suite.target_id,
+    'suin' : StdSuites.Type_Names_Suite.type_suite_info,
+    'pmin' : StdSuites.Type_Names_Suite.type_parameter_info,
+    'lfpt' : StdSuites.Type_Names_Suite.long_fixed_point,
+    'qdrt' : StdSuites.Type_Names_Suite.bounding_rectangle,
+    'TIFF' : StdSuites.Type_Names_Suite.TIFF_picture,
+    'lfxd' : StdSuites.Type_Names_Suite.long_fixed,
+    'vers' : StdSuites.Type_Names_Suite.version,
+    'tr16' : StdSuites.Type_Names_Suite.RGB16_color,
+    'comp' : StdSuites.Type_Names_Suite.double_integer,
+    'insl' : StdSuites.Type_Names_Suite.location_reference,
+    'QDpt' : StdSuites.Type_Names_Suite.point,
+    'aete' : StdSuites.Type_Names_Suite.application_dictionary,
+    'magn' : StdSuites.Type_Names_Suite.unsigned_integer,
+    'cmnu' : StdSuites.Type_Names_Suite.menu,
+    'sing' : StdSuites.Type_Names_Suite.small_real,
+    'fixd' : StdSuites.Type_Names_Suite.fixed,
+    'gcli' : StdSuites.Type_Names_Suite.type_class_info,
+    'tr96' : StdSuites.Type_Names_Suite.RGB96_color,
+    'tdas' : StdSuites.Type_Names_Suite.dash_style,
+    'tpmm' : StdSuites.Type_Names_Suite.pixel_map_record,
+    'exte' : StdSuites.Type_Names_Suite.extended_real,
+    'lrct' : StdSuites.Type_Names_Suite.long_rectangle,
+    'prcs' : process,
+    'pcap' : application_process,
+    'pcda' : desk_accessory_process,
+    'capp' : application,
+    'ctrs' : trash_2d_object,
+    'cdsk' : desktop_2d_object,
+    'ctnr' : container,
+    'cfol' : folder,
+    'cdis' : disk,
+    'capp' : application,
+    'alia' : alias_file,
+    'pack' : package,
+    'file' : file,
+    'appf' : application_file,
+    'inlf' : internet_location_file,
+    'docf' : document_file,
+    'clpf' : clipping,
+    'pwnd' : preferences_window,
+    'brow' : Finder_window,
+    'cwin' : window,
+    'lwnd' : clipping_window,
+    'iwnd' : information_window,
+    'cobj' : item,
+    'icop' : icon_view_options,
+    'cprf' : preferences,
+    'alst' : alias_list,
+    'ifam' : icon_family,
+    'clbl' : label,
+    'lvcl' : column,
+    'lvop' : list_view_options,
+}
+
+
+class Finder(Standard_Suite_Events,
+        Legacy_suite_Events,
+        Containers_and_folders_Events,
+        Files_Events,
+        Finder_Basics_Events,
+        Finder_items_Events,
+        Window_classes_Events,
+        Type_Definitions_Events,
+        Enumerations_Events,
+        aetools.TalkTo):
+    _signature = 'MACS'
+
+    _moduleName = 'Finder'
+
+    _elemdict = application._elemdict
+    _propdict = application._propdict

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Netscape/Mozilla_suite.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Netscape/Mozilla_suite.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Netscape/Mozilla_suite.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,269 @@
+"""Suite Mozilla suite: Experimental Mozilla suite
+Level 1, version 1
+
+Generated from /Volumes/Sap/Applications (Mac OS 9)/Netscape Communicator\xe2\x84\xa2 Folder/Netscape Communicator\xe2\x84\xa2
+AETE/AEUT resource version 1/0, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'MOSS'
+
+class Mozilla_suite_Events:
+
+    def Get_Import_Data(self, _no_object=None, _attributes={}, **_arguments):
+        """Get Import Data: Returns a structure containing information that is of use to an external module in importing data from an external mail application into Communicator.
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: vRefNum and dirID of profile folder (2+4 bytes), vRefNum and DirID of the local mail folder (2+4 bytes), window type of front window (0 if none, \xd4Brwz\xd5 browser, \xd4Addr\xd5 addressbook, \xd4Mesg\xd5 messenger, etc., 4 bytes)
+        """
+        _code = 'MOSS'
+        _subcode = 'Impt'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def Get_Profile_Name(self, _no_object=None, _attributes={}, **_arguments):
+        """Get Profile Name: Get the current User Profile
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: Name of the current profile, like \xd2Joe Bloggs\xd3. This is the name of the profile folder in the Netscape Users folder.
+        """
+        _code = 'MOSS'
+        _subcode = 'upro'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def Get_workingURL(self, _no_object=None, _attributes={}, **_arguments):
+        """Get workingURL: Get the path to the running application in URL format.  This will allow a script to construct a relative URL
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: Will return text of the from \xd2FILE://foo/applicationname\xd3
+        """
+        _code = 'MOSS'
+        _subcode = 'wurl'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_Go = {
+        'direction' : 'dire',
+    }
+
+    def Go(self, _object, _attributes={}, **_arguments):
+        """Go: navigate a window: back, forward, again(reload), home)
+        Required argument: window
+        Keyword argument direction: undocumented, typecode 'dire'
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'MOSS'
+        _subcode = 'gogo'
+
+        aetools.keysubst(_arguments, self._argmap_Go)
+        _arguments['----'] = _object
+
+        aetools.enumsubst(_arguments, 'dire', _Enum_dire)
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def Handle_command(self, _object, _attributes={}, **_arguments):
+        """Handle command: Handle a command
+        Required argument: The command to handle
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'MOSS'
+        _subcode = 'hcmd'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def Open_Address_Book(self, _no_object=None, _attributes={}, **_arguments):
+        """Open Address Book: Opens the address book
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'MOSS'
+        _subcode = 'addr'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def Open_Component(self, _object, _attributes={}, **_arguments):
+        """Open Component: Open a Communicator component
+        Required argument: The component to open
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'MOSS'
+        _subcode = 'cpnt'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def Open_Profile_Manager(self, _no_object=None, _attributes={}, **_arguments):
+        """Open Profile Manager: Open the user profile manager (obsolete)
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'MOSS'
+        _subcode = 'prfl'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def Open_bookmark(self, _object=None, _attributes={}, **_arguments):
+        """Open bookmark: Reads in a bookmark file
+        Required argument: If not available, reloads the current bookmark file
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'MOSS'
+        _subcode = 'book'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_Read_help_file = {
+        'with_index' : 'idid',
+        'search_text' : 'sear',
+    }
+
+    def Read_help_file(self, _object, _attributes={}, **_arguments):
+        """Read help file: Reads in the help file (file should be in the help file format)
+        Required argument: undocumented, typecode 'alis'
+        Keyword argument with_index: Index to the help file. Defaults to  \xd4DEFAULT\xd5)
+        Keyword argument search_text: Optional text to search for
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'MOSS'
+        _subcode = 'help'
+
+        aetools.keysubst(_arguments, self._argmap_Read_help_file)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+_Enum_comp = {
+    'Navigator' : 'navg',       # The Navigator component
+    'InBox' : 'inbx',   # The InBox component
+    'Newsgroups' : 'colb',      # The Newsgroups component
+    'Composer' : 'cpsr',        # The Page Composer component
+    'Conference' : 'conf',      # The Conference Component
+    'Calendar' : 'cald',        # The Calendar Component
+}
+
+_Enum_dire = {
+    'again' : 'agai',   # Again (reload)
+    'home' : 'home',    # Home
+    'backward' : 'prev',        # Previous page
+    'forward' : 'next', # Next page
+}
+
+_Enum_ncmd = {
+    'Get_new_mail' : '\x00\x00\x04W',   #
+    'Send_queued_messages' : '\x00\x00\x04X',   #
+    'Read_newsgroups' : '\x00\x00\x04\x04',     #
+    'Show_Inbox' : '\x00\x00\x04\x05',  #
+    'Show_Bookmarks_window' : '\x00\x00\x04\x06',       #
+    'Show_History_window' : '\x00\x00\x04\x07', #
+    'Show_Address_Book_window' : '\x00\x00\x04\t',      #
+}
+
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+}
+
+_propdeclarations = {
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+    'comp' : _Enum_comp,
+    'dire' : _Enum_dire,
+    'ncmd' : _Enum_ncmd,
+}

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Netscape/PowerPlant.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Netscape/PowerPlant.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Netscape/PowerPlant.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,86 @@
+"""Suite PowerPlant:
+Level 0, version 0
+
+Generated from /Volumes/Sap/Applications (Mac OS 9)/Netscape Communicator\xe2\x84\xa2 Folder/Netscape Communicator\xe2\x84\xa2
+AETE/AEUT resource version 1/0, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'ppnt'
+
+class PowerPlant_Events:
+
+    _argmap_SwitchTellTarget = {
+        'to' : 'data',
+    }
+
+    def SwitchTellTarget(self, _no_object=None, _attributes={}, **_arguments):
+        """SwitchTellTarget: Makes an object the \xd2focus\xd3 of AppleEvents
+        Keyword argument to: reference to new focus of AppleEvents
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'ppnt'
+        _subcode = 'sttg'
+
+        aetools.keysubst(_arguments, self._argmap_SwitchTellTarget)
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_select = {
+        'data' : 'data',
+    }
+
+    def select(self, _object, _attributes={}, **_arguments):
+        """select: Sets the present selection
+        Required argument: object to select or container of sub-objects to select
+        Keyword argument data: sub-object(s) to select
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'misc'
+        _subcode = 'slct'
+
+        aetools.keysubst(_arguments, self._argmap_select)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+_Enum_dbac = {
+    'DoNothing' : '\x00\x00\x00\x00',   # No debugging action is taken.
+    'PostAlert' : '\x00\x00\x00\x01',   # Post an alert.
+    'LowLevelDebugger' : '\x00\x00\x00\x02',    # Break into the low level debugger (MacsBug).
+    'SourceDebugger' : '\x00\x00\x00\x03',      # Break into the source level debugger (if source debugger is executing).
+}
+
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+}
+
+_propdeclarations = {
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+    'dbac' : _Enum_dbac,
+}

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Netscape/Required_suite.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Netscape/Required_suite.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Netscape/Required_suite.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,108 @@
+"""Suite Required suite:
+Level 0, version 0
+
+Generated from /Volumes/Sap/Applications (Mac OS 9)/Netscape Communicator\xe2\x84\xa2 Folder/Netscape Communicator\xe2\x84\xa2
+AETE/AEUT resource version 1/0, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'reqd'
+
+from StdSuites.Required_Suite import *
+class Required_suite_Events(Required_Suite_Events):
+
+    def open(self, _object, _attributes={}, **_arguments):
+        """open: Open the specified object(s)
+        Required argument: list of objects to open
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'aevt'
+        _subcode = 'odoc'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def print_(self, _object, _attributes={}, **_arguments):
+        """print: Print the specified object(s)
+        Required argument: list of objects to print
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'aevt'
+        _subcode = 'pdoc'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def quit(self, _no_object=None, _attributes={}, **_arguments):
+        """quit: Quit Navigator
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'aevt'
+        _subcode = 'quit'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def run(self, _no_object=None, _attributes={}, **_arguments):
+        """run: Sent to an application when it is double-clicked
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'aevt'
+        _subcode = 'oapp'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+}
+
+_propdeclarations = {
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+}

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Netscape/Standard_Suite.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Netscape/Standard_Suite.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Netscape/Standard_Suite.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,243 @@
+"""Suite Standard Suite: Common terms for most applications
+Level 1, version 1
+
+Generated from /Volumes/Sap/Applications (Mac OS 9)/Netscape Communicator\xe2\x84\xa2 Folder/Netscape Communicator\xe2\x84\xa2
+AETE/AEUT resource version 1/0, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'CoRe'
+
+from StdSuites.Standard_Suite import *
+class Standard_Suite_Events(Standard_Suite_Events):
+
+    def close(self, _object, _attributes={}, **_arguments):
+        """close: Close an object
+        Required argument: the objects to close
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'core'
+        _subcode = 'clos'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def data_size(self, _object, _attributes={}, **_arguments):
+        """data size: Return the size in bytes of an object
+        Required argument: the object whose data size is to be returned
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: the size of the object in bytes
+        """
+        _code = 'core'
+        _subcode = 'dsiz'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def get(self, _object, _attributes={}, **_arguments):
+        """get: Get the data for an object
+        Required argument: the object whose data is to be returned
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: The data from the object
+        """
+        _code = 'core'
+        _subcode = 'getd'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_set = {
+        'to' : 'data',
+    }
+
+    def set(self, _object, _attributes={}, **_arguments):
+        """set: Set an object\xd5s data
+        Required argument: the object to change
+        Keyword argument to: the new value
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'core'
+        _subcode = 'setd'
+
+        aetools.keysubst(_arguments, self._argmap_set)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+
+class application(aetools.ComponentItem):
+    """application - An application program """
+    want = 'capp'
+class _Prop_alert_application(aetools.NProperty):
+    """alert application - Most of the alerts will be sent to this application using yet unspecified AE interface. We need a few alert boxes: alert, confirm and notify. Any ideas on how to design this event? mailto:atotic at netscape.com. I\xd5d like to conform to the standard. """
+    which = 'ALAP'
+    want = 'type'
+alert_application = _Prop_alert_application()
+class _Prop_kiosk_mode(aetools.NProperty):
+    """kiosk mode - Kiosk mode leaves very few menus enabled """
+    which = 'KOSK'
+    want = 'long'
+kiosk_mode = _Prop_kiosk_mode()
+#        element 'cwin' as ['indx', 'name', 'ID  ']
+
+class window(aetools.ComponentItem):
+    """window - A Window """
+    want = 'cwin'
+class _Prop_URL(aetools.NProperty):
+    """URL - Current URL """
+    which = 'curl'
+    want = 'TEXT'
+class _Prop_bounds(aetools.NProperty):
+    """bounds - the boundary rectangle for the window """
+    which = 'pbnd'
+    want = 'qdrt'
+class _Prop_busy(aetools.NProperty):
+    """busy - Is window loading something right now. 2, window is busy and will reject load requests. 1, window is busy, but will interrupt outstanding loads """
+    which = 'busy'
+    want = 'long'
+class _Prop_closeable(aetools.NProperty):
+    """closeable - Does the window have a close box? """
+    which = 'hclb'
+    want = 'bool'
+class _Prop_floating(aetools.NProperty):
+    """floating - Does the window float? """
+    which = 'isfl'
+    want = 'bool'
+class _Prop_index(aetools.NProperty):
+    """index - the number of the window """
+    which = 'pidx'
+    want = 'long'
+class _Prop_modal(aetools.NProperty):
+    """modal - Is the window modal? """
+    which = 'pmod'
+    want = 'bool'
+class _Prop_name(aetools.NProperty):
+    """name - the title of the window """
+    which = 'pnam'
+    want = 'itxt'
+class _Prop_position(aetools.NProperty):
+    """position - upper left coordinates of window """
+    which = 'ppos'
+    want = 'QDpt'
+class _Prop_resizable(aetools.NProperty):
+    """resizable - Is the window resizable? """
+    which = 'prsz'
+    want = 'bool'
+class _Prop_titled(aetools.NProperty):
+    """titled - Does the window have a title bar? """
+    which = 'ptit'
+    want = 'bool'
+class _Prop_unique_ID(aetools.NProperty):
+    """unique ID - Window\xd5s unique ID (a bridge between WWW! suite window id\xd5s and standard AE windows) """
+    which = 'wiid'
+    want = 'long'
+class _Prop_visible(aetools.NProperty):
+    """visible - is the window visible? """
+    which = 'pvis'
+    want = 'bool'
+class _Prop_zoomable(aetools.NProperty):
+    """zoomable - Is the window zoomable? """
+    which = 'iszm'
+    want = 'bool'
+class _Prop_zoomed(aetools.NProperty):
+    """zoomed - Is the window zoomed? """
+    which = 'pzum'
+    want = 'bool'
+application._superclassnames = []
+application._privpropdict = {
+    'alert_application' : _Prop_alert_application,
+    'kiosk_mode' : _Prop_kiosk_mode,
+}
+application._privelemdict = {
+    'window' : window,
+}
+window._superclassnames = []
+window._privpropdict = {
+    'URL' : _Prop_URL,
+    'bounds' : _Prop_bounds,
+    'busy' : _Prop_busy,
+    'closeable' : _Prop_closeable,
+    'floating' : _Prop_floating,
+    'index' : _Prop_index,
+    'modal' : _Prop_modal,
+    'name' : _Prop_name,
+    'position' : _Prop_position,
+    'resizable' : _Prop_resizable,
+    'titled' : _Prop_titled,
+    'unique_ID' : _Prop_unique_ID,
+    'visible' : _Prop_visible,
+    'zoomable' : _Prop_zoomable,
+    'zoomed' : _Prop_zoomed,
+}
+window._privelemdict = {
+}
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+    'capp' : application,
+    'cwin' : window,
+}
+
+_propdeclarations = {
+    'ALAP' : _Prop_alert_application,
+    'KOSK' : _Prop_kiosk_mode,
+    'busy' : _Prop_busy,
+    'curl' : _Prop_URL,
+    'hclb' : _Prop_closeable,
+    'isfl' : _Prop_floating,
+    'iszm' : _Prop_zoomable,
+    'pbnd' : _Prop_bounds,
+    'pidx' : _Prop_index,
+    'pmod' : _Prop_modal,
+    'pnam' : _Prop_name,
+    'ppos' : _Prop_position,
+    'prsz' : _Prop_resizable,
+    'ptit' : _Prop_titled,
+    'pvis' : _Prop_visible,
+    'pzum' : _Prop_zoomed,
+    'wiid' : _Prop_unique_ID,
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+}

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Netscape/Standard_URL_suite.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Netscape/Standard_URL_suite.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Netscape/Standard_URL_suite.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,60 @@
+"""Suite Standard URL suite: Mac URL standard, supported by many apps
+
+
+Level 1, version 1
+
+Generated from /Volumes/Sap/Applications (Mac OS 9)/Netscape Communicator\xe2\x84\xa2 Folder/Netscape Communicator\xe2\x84\xa2
+AETE/AEUT resource version 1/0, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'GURL'
+
+class Standard_URL_suite_Events:
+
+    _argmap_GetURL = {
+        'to' : 'dest',
+        'inside' : 'HWIN',
+        'from_' : 'refe',
+    }
+
+    def GetURL(self, _object, _attributes={}, **_arguments):
+        """GetURL: Loads the URL (optionally to disk)
+        Required argument: The url
+        Keyword argument to: file the URL should be loaded into
+        Keyword argument inside: Window the URL should be loaded to
+        Keyword argument from_: Referrer, to be sent with the HTTP request
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'GURL'
+        _subcode = 'GURL'
+
+        aetools.keysubst(_arguments, self._argmap_GetURL)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+}
+
+_propdeclarations = {
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+}

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Netscape/Text.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Netscape/Text.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Netscape/Text.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,122 @@
+"""Suite Text:
+Level 0, version 0
+
+Generated from /Volumes/Sap/Applications (Mac OS 9)/Netscape Communicator\xe2\x84\xa2 Folder/Netscape Communicator\xe2\x84\xa2
+AETE/AEUT resource version 1/0, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'TEXT'
+
+from StdSuites.Text_Suite import *
+class Text_Events(Text_Suite_Events):
+
+    pass
+
+
+class text(aetools.ComponentItem):
+    """text - independent text view objects """
+    want = 'ctxt'
+class _Prop_beginning(aetools.NProperty):
+    """beginning - Beginning of element """
+    which = 'bgng'
+    want = 'obj '
+class _Prop_end(aetools.NProperty):
+    """end - Ending of element """
+    which = 'end '
+    want = 'obj '
+class _Prop_infront(aetools.NProperty):
+    """infront - Immediately before element """
+    which = 'pBef'
+    want = 'obj '
+class _Prop_justbehind(aetools.NProperty):
+    """justbehind - Immediately after element """
+    which = 'pAft'
+    want = 'obj '
+class _Prop_updateLevel(aetools.NProperty):
+    """updateLevel - updating level.  Can only be incremented or decremented.  Do so only in a try block -- if the level is greater than zero, visual text updating will cease. """
+    which = 'pUpL'
+    want = 'long'
+#        element 'stys' as ['indx', 'name']
+
+class styleset(aetools.ComponentItem):
+    """styleset - A style \xd2set\xd3 that may be used repeatedly in text objects. """
+    want = 'stys'
+class _Prop_color(aetools.NProperty):
+    """color - the color """
+    which = 'colr'
+    want = 'RGB '
+class _Prop_font(aetools.NProperty):
+    """font - font name """
+    which = 'font'
+    want = 'TEXT'
+class _Prop_name(aetools.NProperty):
+    """name - style name """
+    which = 'pnam'
+    want = 'TEXT'
+class _Prop_size(aetools.NProperty):
+    """size - the size in points """
+    which = 'ptsz'
+    want = 'long'
+class _Prop_style(aetools.NProperty):
+    """style - the text styles or face attributes """
+    which = 'txst'
+    want = 'tsty'
+class _Prop_writing_code(aetools.NProperty):
+    """writing code - the script system and language """
+    which = 'psct'
+    want = 'tsty'
+
+stylesets = styleset
+text._superclassnames = []
+text._privpropdict = {
+    'beginning' : _Prop_beginning,
+    'end' : _Prop_end,
+    'infront' : _Prop_infront,
+    'justbehind' : _Prop_justbehind,
+    'updateLevel' : _Prop_updateLevel,
+}
+text._privelemdict = {
+    'styleset' : styleset,
+}
+styleset._superclassnames = []
+styleset._privpropdict = {
+    'color' : _Prop_color,
+    'font' : _Prop_font,
+    'name' : _Prop_name,
+    'size' : _Prop_size,
+    'style' : _Prop_style,
+    'writing_code' : _Prop_writing_code,
+}
+styleset._privelemdict = {
+}
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+    'ctxt' : text,
+    'stys' : styleset,
+}
+
+_propdeclarations = {
+    'bgng' : _Prop_beginning,
+    'colr' : _Prop_color,
+    'end ' : _Prop_end,
+    'font' : _Prop_font,
+    'pAft' : _Prop_justbehind,
+    'pBef' : _Prop_infront,
+    'pUpL' : _Prop_updateLevel,
+    'pnam' : _Prop_name,
+    'psct' : _Prop_writing_code,
+    'ptsz' : _Prop_size,
+    'txst' : _Prop_style,
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+}

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Netscape/WorldWideWeb_suite.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Netscape/WorldWideWeb_suite.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Netscape/WorldWideWeb_suite.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,426 @@
+"""Suite WorldWideWeb suite, as defined in Spyglass spec.:
+Level 1, version 1
+
+Generated from /Volumes/Sap/Applications (Mac OS 9)/Netscape Communicator\xe2\x84\xa2 Folder/Netscape Communicator\xe2\x84\xa2
+AETE/AEUT resource version 1/0, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'WWW!'
+
+class WorldWideWeb_suite_Events:
+
+    _argmap_OpenURL = {
+        'to' : 'INTO',
+        'toWindow' : 'WIND',
+        'flags' : 'FLGS',
+        'post_data' : 'POST',
+        'post_type' : 'MIME',
+        'progressApp' : 'PROG',
+    }
+
+    def OpenURL(self, _object, _attributes={}, **_arguments):
+        """OpenURL: Opens a URL. Allows for more options than GetURL event
+        Required argument: URL
+        Keyword argument to: file destination
+        Keyword argument toWindow: window iD
+        Keyword argument flags: Binary: any combination of 1, 2 and 4 is allowed: 1 and 2 mean force reload the document. 4 is ignored
+        Keyword argument post_data: Form posting data
+        Keyword argument post_type: MIME type of the posting data. Defaults to application/x-www-form-urlencoded
+        Keyword argument progressApp: Application that will display progress
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: ID of the loading window
+        """
+        _code = 'WWW!'
+        _subcode = 'OURL'
+
+        aetools.keysubst(_arguments, self._argmap_OpenURL)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_ShowFile = {
+        'MIME_type' : 'MIME',
+        'Window_ID' : 'WIND',
+        'URL' : 'URL ',
+    }
+
+    def ShowFile(self, _object, _attributes={}, **_arguments):
+        """ShowFile: Similar to OpenDocuments, except that it specifies the parent URL, and MIME type of the file
+        Required argument: File to open
+        Keyword argument MIME_type: MIME type
+        Keyword argument Window_ID: Window to open the file in
+        Keyword argument URL: Use this as a base URL
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: Window ID of the loaded window. 0 means ShowFile failed, FFFFFFF means that data was not appropriate type to display in the browser.
+        """
+        _code = 'WWW!'
+        _subcode = 'SHWF'
+
+        aetools.keysubst(_arguments, self._argmap_ShowFile)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_cancel_progress = {
+        'in_window' : 'WIND',
+    }
+
+    def cancel_progress(self, _object=None, _attributes={}, **_arguments):
+        """cancel progress: Interrupts the download of the document in the given window
+        Required argument: progress ID, obtained from the progress app
+        Keyword argument in_window: window ID of the progress to cancel
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'WWW!'
+        _subcode = 'CNCL'
+
+        aetools.keysubst(_arguments, self._argmap_cancel_progress)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def find_URL(self, _object, _attributes={}, **_arguments):
+        """find URL: If the file was downloaded by Netscape, you can call FindURL to find out the URL used to download the file.
+        Required argument: File spec
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: The URL
+        """
+        _code = 'WWW!'
+        _subcode = 'FURL'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def get_window_info(self, _object=None, _attributes={}, **_arguments):
+        """get window info: Returns the information about the window as a list. Currently the list contains the window title and the URL. You can get the same information using standard Apple Event GetProperty.
+        Required argument: window ID
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: undocumented, typecode 'list'
+        """
+        _code = 'WWW!'
+        _subcode = 'WNFO'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def list_windows(self, _no_object=None, _attributes={}, **_arguments):
+        """list windows: Lists the IDs of all the hypertext windows
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: List of unique IDs of all the hypertext windows
+        """
+        _code = 'WWW!'
+        _subcode = 'LSTW'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_parse_anchor = {
+        'relative_to' : 'RELA',
+    }
+
+    def parse_anchor(self, _object, _attributes={}, **_arguments):
+        """parse anchor: Resolves the relative URL
+        Required argument: Main URL
+        Keyword argument relative_to: Relative URL
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: Parsed  URL
+        """
+        _code = 'WWW!'
+        _subcode = 'PRSA'
+
+        aetools.keysubst(_arguments, self._argmap_parse_anchor)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def register_URL_echo(self, _object=None, _attributes={}, **_arguments):
+        """register URL echo: Registers the \xd2echo\xd3 application. Each download from now on will be echoed to this application.
+        Required argument: Application signature
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'WWW!'
+        _subcode = 'RGUE'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_register_protocol = {
+        'for_protocol' : 'PROT',
+    }
+
+    def register_protocol(self, _object=None, _attributes={}, **_arguments):
+        """register protocol: Registers application as a \xd2handler\xd3 for this protocol with a given prefix. The handler will receive \xd2OpenURL\xd3, or if that fails, \xd2GetURL\xd3 event.
+        Required argument: Application sig
+        Keyword argument for_protocol: protocol prefix: \xd2finger:\xd3, \xd2file\xd3,
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: TRUE if registration has been successful
+        """
+        _code = 'WWW!'
+        _subcode = 'RGPR'
+
+        aetools.keysubst(_arguments, self._argmap_register_protocol)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_register_viewer = {
+        'MIME_type' : 'MIME',
+        'with_file_type' : 'FTYP',
+    }
+
+    def register_viewer(self, _object, _attributes={}, **_arguments):
+        """register viewer: Registers an application as a \xd4special\xd5 viewer for this MIME type. The application will be launched with ViewDoc events
+        Required argument: Application sig
+        Keyword argument MIME_type: MIME type viewer is registering for
+        Keyword argument with_file_type: Mac file type for the downloaded files
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: TRUE if registration has been successful
+        """
+        _code = 'WWW!'
+        _subcode = 'RGVW'
+
+        aetools.keysubst(_arguments, self._argmap_register_viewer)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_register_window_close = {
+        'for_window' : 'WIND',
+    }
+
+    def register_window_close(self, _object=None, _attributes={}, **_arguments):
+        """register window close: Netscape will notify registered application when this window closes
+        Required argument: Application signature
+        Keyword argument for_window: window ID
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: true if successful
+        """
+        _code = 'WWW!'
+        _subcode = 'RGWC'
+
+        aetools.keysubst(_arguments, self._argmap_register_window_close)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def unregister_URL_echo(self, _object, _attributes={}, **_arguments):
+        """unregister URL echo: cancels URL echo
+        Required argument: application signature
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'WWW!'
+        _subcode = 'UNRU'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_unregister_protocol = {
+        'for_protocol' : 'PROT',
+    }
+
+    def unregister_protocol(self, _object=None, _attributes={}, **_arguments):
+        """unregister protocol: reverses the effects of \xd2register protocol\xd3
+        Required argument: Application sig.
+        Keyword argument for_protocol: protocol prefix. If none, unregister for all protocols
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: TRUE if successful
+        """
+        _code = 'WWW!'
+        _subcode = 'UNRP'
+
+        aetools.keysubst(_arguments, self._argmap_unregister_protocol)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_unregister_viewer = {
+        'MIME_type' : 'MIME',
+    }
+
+    def unregister_viewer(self, _object, _attributes={}, **_arguments):
+        """unregister viewer: Revert to the old way of handling this MIME type
+        Required argument: Application sig
+        Keyword argument MIME_type: MIME type to be unregistered
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: TRUE if the event was successful
+        """
+        _code = 'WWW!'
+        _subcode = 'UNRV'
+
+        aetools.keysubst(_arguments, self._argmap_unregister_viewer)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_unregister_window_close = {
+        'for_window' : 'WIND',
+    }
+
+    def unregister_window_close(self, _object=None, _attributes={}, **_arguments):
+        """unregister window close: Undo for register window close
+        Required argument: Application signature
+        Keyword argument for_window: window ID
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: true if successful
+        """
+        _code = 'WWW!'
+        _subcode = 'UNRC'
+
+        aetools.keysubst(_arguments, self._argmap_unregister_window_close)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def webActivate(self, _object=None, _attributes={}, **_arguments):
+        """webActivate: Makes Netscape the frontmost application, and selects a given window. This event is here for suite completeness/ cross-platform compatibility only, you should use standard AppleEvents instead.
+        Required argument: window to bring to front
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'WWW!'
+        _subcode = 'ACTV'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+}
+
+_propdeclarations = {
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+}

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Netscape/__init__.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Netscape/__init__.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Netscape/__init__.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,105 @@
+"""
+Package generated from /Volumes/Sap/Applications (Mac OS 9)/Netscape Communicator\xe2\x84\xa2 Folder/Netscape Communicator\xe2\x84\xa2
+"""
+import aetools
+Error = aetools.Error
+import Standard_Suite
+import Standard_URL_suite
+import Mozilla_suite
+import Text
+import WorldWideWeb_suite
+import PowerPlant
+import Required_suite
+
+
+_code_to_module = {
+    'CoRe' : Standard_Suite,
+    'GURL' : Standard_URL_suite,
+    'MOSS' : Mozilla_suite,
+    'TEXT' : Text,
+    'WWW!' : WorldWideWeb_suite,
+    'ppnt' : PowerPlant,
+    'reqd' : Required_suite,
+}
+
+
+
+_code_to_fullname = {
+    'CoRe' : ('Netscape.Standard_Suite', 'Standard_Suite'),
+    'GURL' : ('Netscape.Standard_URL_suite', 'Standard_URL_suite'),
+    'MOSS' : ('Netscape.Mozilla_suite', 'Mozilla_suite'),
+    'TEXT' : ('Netscape.Text', 'Text'),
+    'WWW!' : ('Netscape.WorldWideWeb_suite', 'WorldWideWeb_suite'),
+    'ppnt' : ('Netscape.PowerPlant', 'PowerPlant'),
+    'reqd' : ('Netscape.Required_suite', 'Required_suite'),
+}
+
+from Standard_Suite import *
+from Standard_URL_suite import *
+from Mozilla_suite import *
+from Text import *
+from WorldWideWeb_suite import *
+from PowerPlant import *
+from Required_suite import *
+
+def getbaseclasses(v):
+    if not getattr(v, '_propdict', None):
+        v._propdict = {}
+        v._elemdict = {}
+        for superclassname in getattr(v, '_superclassnames', []):
+            superclass = eval(superclassname)
+            getbaseclasses(superclass)
+            v._propdict.update(getattr(superclass, '_propdict', {}))
+            v._elemdict.update(getattr(superclass, '_elemdict', {}))
+        v._propdict.update(getattr(v, '_privpropdict', {}))
+        v._elemdict.update(getattr(v, '_privelemdict', {}))
+
+import StdSuites
+
+#
+# Set property and element dictionaries now that all classes have been defined
+#
+getbaseclasses(text)
+getbaseclasses(styleset)
+getbaseclasses(StdSuites.Text_Suite.character)
+getbaseclasses(StdSuites.Text_Suite.text_flow)
+getbaseclasses(StdSuites.Text_Suite.word)
+getbaseclasses(StdSuites.Text_Suite.paragraph)
+getbaseclasses(StdSuites.Text_Suite.text_style_info)
+getbaseclasses(StdSuites.Text_Suite.line)
+getbaseclasses(StdSuites.Text_Suite.text)
+getbaseclasses(window)
+getbaseclasses(application)
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+    'ctxt' : text,
+    'stys' : styleset,
+    'cha ' : StdSuites.Text_Suite.character,
+    'cflo' : StdSuites.Text_Suite.text_flow,
+    'cwor' : StdSuites.Text_Suite.word,
+    'cpar' : StdSuites.Text_Suite.paragraph,
+    'tsty' : StdSuites.Text_Suite.text_style_info,
+    'clin' : StdSuites.Text_Suite.line,
+    'ctxt' : StdSuites.Text_Suite.text,
+    'cwin' : window,
+    'capp' : application,
+}
+
+
+class Netscape(Standard_Suite_Events,
+        Standard_URL_suite_Events,
+        Mozilla_suite_Events,
+        Text_Events,
+        WorldWideWeb_suite_Events,
+        PowerPlant_Events,
+        Required_suite_Events,
+        aetools.TalkTo):
+    _signature = 'MOSS'
+
+    _moduleName = 'Netscape'
+
+    _elemdict = application._elemdict
+    _propdict = application._propdict

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/StdSuites/AppleScript_Suite.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/StdSuites/AppleScript_Suite.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/StdSuites/AppleScript_Suite.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2215 @@
+"""Suite AppleScript Suite: Standard terms for AppleScript
+Level 1, version 1
+
+Generated from /Volumes/Sap/System Folder/Extensions/AppleScript
+AETE/AEUT resource version 1/0, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'ascr'
+
+class AppleScript_Suite_Events:
+
+    def _26_(self, _object, _attributes={}, **_arguments):
+        """&: Concatenation
+        Required argument: an AE object reference
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: anything
+        """
+        _code = 'ascr'
+        _subcode = 'ccat'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def _2a_(self, _object, _attributes={}, **_arguments):
+        """*: Multiplication
+        Required argument: an AE object reference
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: anything
+        """
+        _code = 'ascr'
+        _subcode = '*   '
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def _2b_(self, _object, _attributes={}, **_arguments):
+        """+: Addition
+        Required argument: an AE object reference
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: anything
+        """
+        _code = 'ascr'
+        _subcode = '+   '
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def _2d_(self, _object, _attributes={}, **_arguments):
+        """-: Subtraction
+        Required argument: an AE object reference
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: anything
+        """
+        _code = 'ascr'
+        _subcode = '-   '
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def _3c_(self, _object, _attributes={}, **_arguments):
+        """<: Less than
+        Required argument: an AE object reference
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: anything
+        """
+        _code = 'ascr'
+        _subcode = '<   '
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def _3d_(self, _object, _attributes={}, **_arguments):
+        """=: Equality
+        Required argument: an AE object reference
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: anything
+        """
+        _code = 'ascr'
+        _subcode = '=   '
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def _3e_(self, _object, _attributes={}, **_arguments):
+        """>: Greater than
+        Required argument: an AE object reference
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: anything
+        """
+        _code = 'ascr'
+        _subcode = '>   '
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_Call_a5_subroutine = {
+        'at' : 'at  ',
+        'from_' : 'from',
+        'for_' : 'for ',
+        'to' : 'to  ',
+        'thru' : 'thru',
+        'through' : 'thgh',
+        'by' : 'by  ',
+        'on' : 'on  ',
+        'into' : 'into',
+        'onto' : 'onto',
+        'between' : 'btwn',
+        'against' : 'agst',
+        'out_of' : 'outo',
+        'instead_of' : 'isto',
+        'aside_from' : 'asdf',
+        'around' : 'arnd',
+        'beside' : 'bsid',
+        'beneath' : 'bnth',
+        'under' : 'undr',
+        'over' : 'over',
+        'above' : 'abve',
+        'below' : 'belw',
+        'apart_from' : 'aprt',
+        'about' : 'abou',
+        'since' : 'snce',
+        'given' : 'givn',
+        'with' : 'with',
+        'without' : 'wout',
+    }
+
+    def Call_a5_subroutine(self, _object=None, _attributes={}, **_arguments):
+        """Call\xa5subroutine: A subroutine call
+        Required argument: anything
+        Keyword argument at: a preposition
+        Keyword argument from_: a preposition
+        Keyword argument for_: a preposition
+        Keyword argument to: a preposition
+        Keyword argument thru: a preposition
+        Keyword argument through: a preposition
+        Keyword argument by: a preposition
+        Keyword argument on: a preposition
+        Keyword argument into: a preposition
+        Keyword argument onto: a preposition
+        Keyword argument between: a preposition
+        Keyword argument against: a preposition
+        Keyword argument out_of: a preposition
+        Keyword argument instead_of: a preposition
+        Keyword argument aside_from: a preposition
+        Keyword argument around: a preposition
+        Keyword argument beside: a preposition
+        Keyword argument beneath: a preposition
+        Keyword argument under: a preposition
+        Keyword argument over: a preposition
+        Keyword argument above: a preposition
+        Keyword argument below: a preposition
+        Keyword argument apart_from: a preposition
+        Keyword argument about: a preposition
+        Keyword argument since: a preposition
+        Keyword argument given: parameter:value pairs, comma-separated
+        Keyword argument with: formal parameter set to true if matching actual parameter is provided
+        Keyword argument without: formal parameter set to false if matching actual parmeter is provided
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: anything
+        """
+        _code = 'ascr'
+        _subcode = 'psbr'
+
+        aetools.keysubst(_arguments, self._argmap_Call_a5_subroutine)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def _5e_(self, _object, _attributes={}, **_arguments):
+        """^: Exponentiation
+        Required argument: an AE object reference
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: anything
+        """
+        _code = 'ascr'
+        _subcode = '^   '
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def activate(self, _no_object=None, _attributes={}, **_arguments):
+        """activate: Bring the targeted application program to the front
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'misc'
+        _subcode = 'actv'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def and_(self, _object, _attributes={}, **_arguments):
+        """and: Logical conjunction
+        Required argument: an AE object reference
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: anything
+        """
+        _code = 'ascr'
+        _subcode = 'AND '
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def as(self, _object, _attributes={}, **_arguments):
+        """as: Coercion
+        Required argument: an AE object reference
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: anything
+        """
+        _code = 'ascr'
+        _subcode = 'coer'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def contains(self, _object, _attributes={}, **_arguments):
+        """contains: Containment
+        Required argument: an AE object reference
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: anything
+        """
+        _code = 'ascr'
+        _subcode = 'cont'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def div(self, _object, _attributes={}, **_arguments):
+        """div: Quotient
+        Required argument: an AE object reference
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: anything
+        """
+        _code = 'ascr'
+        _subcode = 'div '
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def end_tell(self, _no_object=None, _attributes={}, **_arguments):
+        """end tell: Record or log an \xd4end tell\xd5 statement
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'ascr'
+        _subcode = 'tend'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def ends_with(self, _object, _attributes={}, **_arguments):
+        """ends with: Ends with
+        Required argument: an AE object reference
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: anything
+        """
+        _code = 'ascr'
+        _subcode = 'ends'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_error = {
+        'number' : 'errn',
+        'partial_result' : 'ptlr',
+        'from_' : 'erob',
+        'to' : 'errt',
+    }
+
+    def error(self, _object=None, _attributes={}, **_arguments):
+        """error: Raise an error
+        Required argument: anything
+        Keyword argument number: an error number
+        Keyword argument partial_result: any partial result occurring before the error
+        Keyword argument from_: the object that caused the error
+        Keyword argument to: the desired class for a failed coercion
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'ascr'
+        _subcode = 'err '
+
+        aetools.keysubst(_arguments, self._argmap_error)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def idle(self, _no_object=None, _attributes={}, **_arguments):
+        """idle: Sent to a script application when it is idle
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: the number of seconds to wait for next idle event
+        """
+        _code = 'misc'
+        _subcode = 'idle'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def launch(self, _no_object=None, _attributes={}, **_arguments):
+        """launch: Start an application for scripting
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'ascr'
+        _subcode = 'noop'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def log(self, _object, _attributes={}, **_arguments):
+        """log: Cause a comment to be logged
+        Required argument: undocumented, typecode 'TEXT'
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'ascr'
+        _subcode = 'cmnt'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def mod(self, _object, _attributes={}, **_arguments):
+        """mod: Remainder
+        Required argument: an AE object reference
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: anything
+        """
+        _code = 'ascr'
+        _subcode = 'mod '
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def negate(self, _object, _attributes={}, **_arguments):
+        """negate: Numeric negation
+        Required argument: an AE object reference
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: anything
+        """
+        _code = 'ascr'
+        _subcode = 'neg '
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def not_(self, _object, _attributes={}, **_arguments):
+        """not: Logical negation
+        Required argument: an AE object reference
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: anything
+        """
+        _code = 'ascr'
+        _subcode = 'NOT '
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def or_(self, _object, _attributes={}, **_arguments):
+        """or: Logical disjunction
+        Required argument: an AE object reference
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: anything
+        """
+        _code = 'ascr'
+        _subcode = 'OR  '
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def start_log(self, _no_object=None, _attributes={}, **_arguments):
+        """start log: Start event logging in the script editor
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'ToyS'
+        _subcode = 'log1'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def starts_with(self, _object, _attributes={}, **_arguments):
+        """starts with: Starts with
+        Required argument: an AE object reference
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: anything
+        """
+        _code = 'ascr'
+        _subcode = 'bgwt'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def stop_log(self, _no_object=None, _attributes={}, **_arguments):
+        """stop log: Stop event logging in the script editor
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'ToyS'
+        _subcode = 'log0'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def tell(self, _no_object=None, _attributes={}, **_arguments):
+        """tell: Record or log a \xd4tell\xd5 statement
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'ascr'
+        _subcode = 'tell'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def _ad_(self, _object, _attributes={}, **_arguments):
+        """\xad: Inequality
+        Required argument: an AE object reference
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: anything
+        """
+        _code = 'ascr'
+        _subcode = '\xad   '
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def _b2_(self, _object, _attributes={}, **_arguments):
+        """\xb2: Less than or equal to
+        Required argument: an AE object reference
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: anything
+        """
+        _code = 'ascr'
+        _subcode = '<=  '
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def _b3_(self, _object, _attributes={}, **_arguments):
+        """\xb3: Greater than or equal to
+        Required argument: an AE object reference
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: anything
+        """
+        _code = 'ascr'
+        _subcode = '>=  '
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def _d6_(self, _object, _attributes={}, **_arguments):
+        """\xd6: Division
+        Required argument: an AE object reference
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: anything
+        """
+        _code = 'ascr'
+        _subcode = '/   '
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+
+class anything(aetools.ComponentItem):
+    """anything - any class or reference """
+    want = '****'
+
+class pictures(aetools.ComponentItem):
+    """pictures -  """
+    want = 'PICT'
+
+picture = pictures
+
+class styled_text(aetools.ComponentItem):
+    """styled text - text with font, size, and style information """
+    want = 'STXT'
+
+styled_text = styled_text
+
+class strings(aetools.ComponentItem):
+    """strings -  """
+    want = 'TEXT'
+
+string = strings
+
+class alias(aetools.ComponentItem):
+    """alias - a file on a disk or server.  The file must exist when you check the syntax of your script. """
+    want = 'alis'
+class _Prop_POSIX_path(aetools.NProperty):
+    """POSIX path - the POSIX path of the file """
+    which = 'psxp'
+    want = 'TEXT'
+
+aliases = alias
+
+class April(aetools.ComponentItem):
+    """April - the month of April """
+    want = 'apr '
+
+class August(aetools.ComponentItem):
+    """August - the month of August """
+    want = 'aug '
+
+class booleans(aetools.ComponentItem):
+    """booleans -  """
+    want = 'bool'
+
+boolean = booleans
+
+class RGB_colors(aetools.ComponentItem):
+    """RGB colors -  """
+    want = 'cRGB'
+
+RGB_color = RGB_colors
+
+class application(aetools.ComponentItem):
+    """application - specifies global properties of AppleScript """
+    want = 'capp'
+class _Prop_AppleScript(aetools.NProperty):
+    """AppleScript - the top-level script object """
+    which = 'ascr'
+    want = 'scpt'
+AppleScript = _Prop_AppleScript()
+class _Prop_days(aetools.NProperty):
+    """days - the number of seconds in a day """
+    which = 'days'
+    want = 'long'
+days = _Prop_days()
+class _Prop_hours(aetools.NProperty):
+    """hours - the number of seconds in an hour """
+    which = 'hour'
+    want = 'long'
+hours = _Prop_hours()
+class _Prop_minutes(aetools.NProperty):
+    """minutes - the number of seconds in a minute """
+    which = 'min '
+    want = 'long'
+minutes = _Prop_minutes()
+class _Prop_pi(aetools.NProperty):
+    """pi - the constant pi """
+    which = 'pi  '
+    want = 'doub'
+pi = _Prop_pi()
+class _Prop_print_depth(aetools.NProperty):
+    """print depth - the maximum depth to print """
+    which = 'prdp'
+    want = 'long'
+print_depth = _Prop_print_depth()
+class _Prop_print_length(aetools.NProperty):
+    """print length - the maximum length to print """
+    which = 'prln'
+    want = 'long'
+print_length = _Prop_print_length()
+class _Prop_result(aetools.NProperty):
+    """result - the last result of evaluation """
+    which = 'rslt'
+    want = '****'
+result = _Prop_result()
+class _Prop_return_(aetools.NProperty):
+    """return - a return character """
+    which = 'ret '
+    want = 'cha '
+return_ = _Prop_return_()
+class _Prop_space(aetools.NProperty):
+    """space - a space character """
+    which = 'spac'
+    want = 'cha '
+space = _Prop_space()
+class _Prop_tab(aetools.NProperty):
+    """tab - a tab character """
+    which = 'tab '
+    want = 'cha '
+tab = _Prop_tab()
+class _Prop_text_item_delimiters(aetools.NProperty):
+    """text item delimiters - the text item delimiters of a string """
+    which = 'txdl'
+    want = 'list'
+text_item_delimiters = _Prop_text_item_delimiters()
+class _Prop_weeks(aetools.NProperty):
+    """weeks - the number of seconds in a week """
+    which = 'week'
+    want = 'long'
+weeks = _Prop_weeks()
+
+applications = application
+
+app = application
+
+class upper_case(aetools.ComponentItem):
+    """upper case - Text with lower case converted to upper case """
+    want = 'case'
+
+class cubic_centimeters(aetools.ComponentItem):
+    """cubic centimeters - a volume measurement in SI cubic centimeters """
+    want = 'ccmt'
+
+cubic_centimetres = cubic_centimeters
+
+class cubic_feet(aetools.ComponentItem):
+    """cubic feet - a volume measurement in Imperial cubic feet """
+    want = 'cfet'
+
+class characters(aetools.ComponentItem):
+    """characters -  """
+    want = 'cha '
+
+character = characters
+
+class writing_code_info(aetools.ComponentItem):
+    """writing code info - script code and language code of text run """
+    want = 'citl'
+class _Prop_language_code(aetools.NProperty):
+    """language code - the language code for the text """
+    which = 'plcd'
+    want = 'shor'
+class _Prop_script_code(aetools.NProperty):
+    """script code - the script code for the text """
+    which = 'pscd'
+    want = 'shor'
+
+writing_code_infos = writing_code_info
+
+class text_items(aetools.ComponentItem):
+    """text items -  """
+    want = 'citm'
+
+text_item = text_items
+
+class cubic_meters(aetools.ComponentItem):
+    """cubic meters - a volume measurement in SI cubic meters """
+    want = 'cmet'
+
+cubic_metres = cubic_meters
+
+class centimeters(aetools.ComponentItem):
+    """centimeters - a distance measurement in SI centimeters """
+    want = 'cmtr'
+
+centimetres = centimeters
+
+class item(aetools.ComponentItem):
+    """item - An item of any type """
+    want = 'cobj'
+class _Prop_id(aetools.NProperty):
+    """id - the unique ID number of this object """
+    which = 'ID  '
+    want = 'long'
+
+items = item
+
+class C_strings(aetools.ComponentItem):
+    """C strings -  """
+    want = 'cstr'
+
+C_string = C_strings
+
+class text(aetools.ComponentItem):
+    """text - text with language and style information """
+    want = 'ctxt'
+
+class cubic_inches(aetools.ComponentItem):
+    """cubic inches - a volume measurement in Imperial cubic inches """
+    want = 'cuin'
+
+class cubic_yards(aetools.ComponentItem):
+    """cubic yards - a distance measurement in Imperial cubic yards """
+    want = 'cyrd'
+
+class December(aetools.ComponentItem):
+    """December - the month of December """
+    want = 'dec '
+
+class degrees_Celsius(aetools.ComponentItem):
+    """degrees Celsius - a temperature measurement in SI degrees Celsius """
+    want = 'degc'
+
+class degrees_Fahrenheit(aetools.ComponentItem):
+    """degrees Fahrenheit - a temperature measurement in degrees Fahrenheit """
+    want = 'degf'
+
+class degrees_Kelvin(aetools.ComponentItem):
+    """degrees Kelvin - a temperature measurement in degrees Kelvin """
+    want = 'degk'
+
+class reals(aetools.ComponentItem):
+    """reals -  """
+    want = 'doub'
+
+real = reals
+
+class encoded_strings(aetools.ComponentItem):
+    """encoded strings -  """
+    want = 'encs'
+
+encoded_string = encoded_strings
+
+class constants(aetools.ComponentItem):
+    """constants -  """
+    want = 'enum'
+
+constant = constants
+
+class events(aetools.ComponentItem):
+    """events -  """
+    want = 'evnt'
+
+event = events
+
+class February(aetools.ComponentItem):
+    """February - the month of February """
+    want = 'feb '
+
+class feet(aetools.ComponentItem):
+    """feet - a distance measurement in Imperial feet """
+    want = 'feet'
+
+class Friday(aetools.ComponentItem):
+    """Friday - Friday """
+    want = 'fri '
+
+class file_specification(aetools.ComponentItem):
+    """file specification - a file specification as used by the operating system """
+    want = 'fss '
+
+file_specifications = file_specification
+
+class gallons(aetools.ComponentItem):
+    """gallons - a volume measurement in Imperial gallons """
+    want = 'galn'
+
+class grams(aetools.ComponentItem):
+    """grams - a mass measurement in SI meters """
+    want = 'gram'
+
+class handlers(aetools.ComponentItem):
+    """handlers -  """
+    want = 'hand'
+
+handler = handlers
+
+class inches(aetools.ComponentItem):
+    """inches - a distance measurement in Imperial inches """
+    want = 'inch'
+
+class international_text(aetools.ComponentItem):
+    """international text - text that begins with a writing code """
+    want = 'itxt'
+
+international_text = international_text
+
+class January(aetools.ComponentItem):
+    """January - the month of January """
+    want = 'jan '
+
+class July(aetools.ComponentItem):
+    """July - the month of July """
+    want = 'jul '
+
+class June(aetools.ComponentItem):
+    """June - the month of June """
+    want = 'jun '
+
+class reference_forms(aetools.ComponentItem):
+    """reference forms -  """
+    want = 'kfrm'
+
+reference_form = reference_forms
+
+class kilograms(aetools.ComponentItem):
+    """kilograms - a mass measurement in SI kilograms """
+    want = 'kgrm'
+
+class kilometers(aetools.ComponentItem):
+    """kilometers - a distance measurement in SI kilometers """
+    want = 'kmtr'
+
+kilometres = kilometers
+
+class keystroke(aetools.ComponentItem):
+    """keystroke - a press of a key combination on a Macintosh keyboard """
+    want = 'kprs'
+class _Prop_key(aetools.NProperty):
+    """key - the character for the key was pressed (ignoring modifiers) """
+    which = 'kMsg'
+    want = 'cha '
+class _Prop_key_kind(aetools.NProperty):
+    """key kind - the kind of key that was pressed """
+    which = 'kknd'
+    want = 'ekst'
+class _Prop_modifiers(aetools.NProperty):
+    """modifiers - the modifier keys pressed in combination """
+    which = 'kMod'
+    want = 'eMds'
+
+keystrokes = keystroke
+
+class pounds(aetools.ComponentItem):
+    """pounds - a weight measurement in SI meters """
+    want = 'lbs '
+
+class date(aetools.ComponentItem):
+    """date - Absolute date and time values """
+    want = 'ldt '
+class _Prop_date_string(aetools.NProperty):
+    """date string - the date portion of a date-time value as text """
+    which = 'dstr'
+    want = 'TEXT'
+class _Prop_day(aetools.NProperty):
+    """day - the day of the month of a date """
+    which = 'day '
+    want = 'long'
+class _Prop_month(aetools.NProperty):
+    """month - the month of a date """
+    which = 'mnth'
+    want = 'mnth'
+class _Prop_time(aetools.NProperty):
+    """time - the time since midnight of a date """
+    which = 'time'
+    want = 'long'
+class _Prop_time_string(aetools.NProperty):
+    """time string - the time portion of a date-time value as text """
+    which = 'tstr'
+    want = 'TEXT'
+class _Prop_weekday(aetools.NProperty):
+    """weekday - the day of a week of a date """
+    which = 'wkdy'
+    want = 'wkdy'
+class _Prop_year(aetools.NProperty):
+    """year - the year of a date """
+    which = 'year'
+    want = 'long'
+
+dates = date
+
+class list(aetools.ComponentItem):
+    """list - An ordered collection of items """
+    want = 'list'
+class _Prop_length(aetools.NProperty):
+    """length - the length of a list """
+    which = 'leng'
+    want = 'long'
+class _Prop_rest(aetools.NProperty):
+    """rest - all items of the list excluding first """
+    which = 'rest'
+    want = 'list'
+class _Prop_reverse(aetools.NProperty):
+    """reverse - the items of the list in reverse order """
+    which = 'rvse'
+    want = 'list'
+
+lists = list
+
+class liters(aetools.ComponentItem):
+    """liters - a volume measurement in SI liters """
+    want = 'litr'
+
+litres = liters
+
+class linked_list(aetools.ComponentItem):
+    """linked list - An ordered collection of items """
+    want = 'llst'
+
+linked_lists = linked_list
+
+class integers(aetools.ComponentItem):
+    """integers -  """
+    want = 'long'
+
+integer = integers
+
+class list_or_record(aetools.ComponentItem):
+    """list or record - a list or record """
+    want = 'lr  '
+
+class list_2c__record_or_text(aetools.ComponentItem):
+    """list, record or text - a list, record or text """
+    want = 'lrs '
+
+class list_or_string(aetools.ComponentItem):
+    """list or string - a list or string """
+    want = 'ls  '
+
+class machines(aetools.ComponentItem):
+    """machines -  """
+    want = 'mach'
+
+machine = machines
+
+class March(aetools.ComponentItem):
+    """March - the month of March """
+    want = 'mar '
+
+class May(aetools.ComponentItem):
+    """May - the month of May """
+    want = 'may '
+
+class meters(aetools.ComponentItem):
+    """meters - a distance measurement in SI meters """
+    want = 'metr'
+
+metres = meters
+
+class miles(aetools.ComponentItem):
+    """miles - a distance measurement in Imperial miles """
+    want = 'mile'
+
+class months(aetools.ComponentItem):
+    """months -  """
+    want = 'mnth'
+
+month = months
+
+class Monday(aetools.ComponentItem):
+    """Monday - Monday """
+    want = 'mon '
+
+class missing_values(aetools.ComponentItem):
+    """missing values -  """
+    want = 'msng'
+
+missing_value = missing_values
+
+class number_or_date(aetools.ComponentItem):
+    """number or date - a number or date """
+    want = 'nd  '
+
+class number_2c__date_or_text(aetools.ComponentItem):
+    """number, date or text - a number, date or text """
+    want = 'nds '
+
+class numbers(aetools.ComponentItem):
+    """numbers -  """
+    want = 'nmbr'
+
+number = numbers
+
+class November(aetools.ComponentItem):
+    """November - the month of November """
+    want = 'nov '
+
+class number_or_string(aetools.ComponentItem):
+    """number or string - a number or string """
+    want = 'ns  '
+
+class references(aetools.ComponentItem):
+    """references -  """
+    want = 'obj '
+
+reference = references
+
+class October(aetools.ComponentItem):
+    """October - the month of October """
+    want = 'oct '
+
+class ounces(aetools.ComponentItem):
+    """ounces - a weight measurement in SI meters """
+    want = 'ozs '
+
+class class_(aetools.ComponentItem):
+    """class - the type of a value """
+    want = 'pcls'
+class _Prop__3c_Inheritance_3e_(aetools.NProperty):
+    """<Inheritance> - inherits some of its properties from this class """
+    which = 'c@#^'
+    want = 'type'
+
+classes = class_
+
+class prepositions(aetools.ComponentItem):
+    """prepositions -  """
+    want = 'prep'
+
+preposition = prepositions
+
+class properties(aetools.ComponentItem):
+    """properties -  """
+    want = 'prop'
+
+property = properties
+
+class writing_code(aetools.ComponentItem):
+    """writing code - codes that identify the language and script system """
+    want = 'psct'
+
+class Pascal_strings(aetools.ComponentItem):
+    """Pascal strings -  """
+    want = 'pstr'
+
+Pascal_string = Pascal_strings
+
+class quarts(aetools.ComponentItem):
+    """quarts - a volume measurement in Imperial quarts """
+    want = 'qrts'
+
+class data(aetools.ComponentItem):
+    """data - an AppleScript raw data object """
+    want = 'rdat'
+
+class records(aetools.ComponentItem):
+    """records -  """
+    want = 'reco'
+
+record = records
+
+class Saturday(aetools.ComponentItem):
+    """Saturday - Saturday """
+    want = 'sat '
+
+class seconds(aetools.ComponentItem):
+    """seconds - more than one second """
+    want = 'scnd'
+
+class script(aetools.ComponentItem):
+    """script - An AppleScript script """
+    want = 'scpt'
+class _Prop_name(aetools.NProperty):
+    """name - the name of the script """
+    which = 'pnam'
+    want = 'TEXT'
+class _Prop_parent(aetools.NProperty):
+    """parent - its parent, i.e. the script that will handle events that this script doesn\xd5t """
+    which = 'pare'
+    want = 'scpt'
+
+scripts = script
+
+class September(aetools.ComponentItem):
+    """September - the month of September """
+    want = 'sep '
+
+class alias_or_string(aetools.ComponentItem):
+    """alias or string - an alias or string """
+    want = 'sf  '
+
+class sounds(aetools.ComponentItem):
+    """sounds -  """
+    want = 'snd '
+
+sound = sounds
+
+class square_feet(aetools.ComponentItem):
+    """square feet - an area measurement in Imperial square feet """
+    want = 'sqft'
+
+class square_kilometers(aetools.ComponentItem):
+    """square kilometers - an area measurement in SI square kilometers """
+    want = 'sqkm'
+
+square_kilometres = square_kilometers
+
+class square_miles(aetools.ComponentItem):
+    """square miles - an area measurement in Imperial square miles """
+    want = 'sqmi'
+
+class square_meters(aetools.ComponentItem):
+    """square meters - an area measurement in SI square meters """
+    want = 'sqrm'
+
+square_metres = square_meters
+
+class square_yards(aetools.ComponentItem):
+    """square yards - an area measurement in Imperial square yards """
+    want = 'sqyd'
+
+class styled_Clipboard_text(aetools.ComponentItem):
+    """styled Clipboard text - clipboard text with font, size, and style information """
+    want = 'styl'
+
+styled_Clipboard_text = styled_Clipboard_text
+
+class Sunday(aetools.ComponentItem):
+    """Sunday - Sunday """
+    want = 'sun '
+
+class styled_Unicode_text(aetools.ComponentItem):
+    """styled Unicode text - styled text in the Unicode format """
+    want = 'sutx'
+
+styled_Unicode_text = styled_Unicode_text
+
+class Thursday(aetools.ComponentItem):
+    """Thursday - Thursday """
+    want = 'thu '
+
+class Tuesday(aetools.ComponentItem):
+    """Tuesday - Tuesday """
+    want = 'tue '
+
+class type_class(aetools.ComponentItem):
+    """type class - the name of a particular class (or any four-character code) """
+    want = 'type'
+
+class empty_ae_name_(aetools.ComponentItem):
+    """ - the undefined value """
+    want = 'undf'
+
+class Unicode_text(aetools.ComponentItem):
+    """Unicode text - text in the Unicode format (cannot be viewed without conversion) """
+    want = 'utxt'
+
+Unicode_text = Unicode_text
+
+class vector(aetools.ComponentItem):
+    """vector - An ordered collection of items """
+    want = 'vect'
+
+vectors = vector
+
+class version(aetools.ComponentItem):
+    """version - a version value """
+    want = 'vers'
+
+class Wednesday(aetools.ComponentItem):
+    """Wednesday - Wednesday """
+    want = 'wed '
+
+class weekdays(aetools.ComponentItem):
+    """weekdays -  """
+    want = 'wkdy'
+
+weekday = weekdays
+
+class yards(aetools.ComponentItem):
+    """yards - a distance measurement in Imperial yards """
+    want = 'yard'
+
+class zones(aetools.ComponentItem):
+    """zones -  """
+    want = 'zone'
+
+zone = zones
+anything._superclassnames = []
+anything._privpropdict = {
+}
+anything._privelemdict = {
+}
+pictures._superclassnames = []
+pictures._privpropdict = {
+}
+pictures._privelemdict = {
+}
+styled_text._superclassnames = []
+styled_text._privpropdict = {
+}
+styled_text._privelemdict = {
+}
+styled_text._superclassnames = []
+styled_text._privpropdict = {
+}
+styled_text._privelemdict = {
+}
+strings._superclassnames = []
+strings._privpropdict = {
+}
+strings._privelemdict = {
+}
+alias._superclassnames = []
+alias._privpropdict = {
+    'POSIX_path' : _Prop_POSIX_path,
+}
+alias._privelemdict = {
+}
+April._superclassnames = []
+April._privpropdict = {
+}
+April._privelemdict = {
+}
+August._superclassnames = []
+August._privpropdict = {
+}
+August._privelemdict = {
+}
+booleans._superclassnames = []
+booleans._privpropdict = {
+}
+booleans._privelemdict = {
+}
+RGB_colors._superclassnames = []
+RGB_colors._privpropdict = {
+}
+RGB_colors._privelemdict = {
+}
+application._superclassnames = []
+application._privpropdict = {
+    'AppleScript' : _Prop_AppleScript,
+    'days' : _Prop_days,
+    'hours' : _Prop_hours,
+    'minutes' : _Prop_minutes,
+    'pi' : _Prop_pi,
+    'print_depth' : _Prop_print_depth,
+    'print_length' : _Prop_print_length,
+    'result' : _Prop_result,
+    'return_' : _Prop_return_,
+    'space' : _Prop_space,
+    'tab' : _Prop_tab,
+    'text_item_delimiters' : _Prop_text_item_delimiters,
+    'weeks' : _Prop_weeks,
+}
+application._privelemdict = {
+}
+upper_case._superclassnames = []
+upper_case._privpropdict = {
+}
+upper_case._privelemdict = {
+}
+cubic_centimeters._superclassnames = []
+cubic_centimeters._privpropdict = {
+}
+cubic_centimeters._privelemdict = {
+}
+cubic_feet._superclassnames = []
+cubic_feet._privpropdict = {
+}
+cubic_feet._privelemdict = {
+}
+characters._superclassnames = []
+characters._privpropdict = {
+}
+characters._privelemdict = {
+}
+writing_code_info._superclassnames = []
+writing_code_info._privpropdict = {
+    'language_code' : _Prop_language_code,
+    'script_code' : _Prop_script_code,
+}
+writing_code_info._privelemdict = {
+}
+text_items._superclassnames = []
+text_items._privpropdict = {
+}
+text_items._privelemdict = {
+}
+cubic_meters._superclassnames = []
+cubic_meters._privpropdict = {
+}
+cubic_meters._privelemdict = {
+}
+centimeters._superclassnames = []
+centimeters._privpropdict = {
+}
+centimeters._privelemdict = {
+}
+item._superclassnames = []
+item._privpropdict = {
+    'id' : _Prop_id,
+}
+item._privelemdict = {
+}
+C_strings._superclassnames = []
+C_strings._privpropdict = {
+}
+C_strings._privelemdict = {
+}
+text._superclassnames = []
+text._privpropdict = {
+}
+text._privelemdict = {
+}
+cubic_inches._superclassnames = []
+cubic_inches._privpropdict = {
+}
+cubic_inches._privelemdict = {
+}
+cubic_yards._superclassnames = []
+cubic_yards._privpropdict = {
+}
+cubic_yards._privelemdict = {
+}
+December._superclassnames = []
+December._privpropdict = {
+}
+December._privelemdict = {
+}
+degrees_Celsius._superclassnames = []
+degrees_Celsius._privpropdict = {
+}
+degrees_Celsius._privelemdict = {
+}
+degrees_Fahrenheit._superclassnames = []
+degrees_Fahrenheit._privpropdict = {
+}
+degrees_Fahrenheit._privelemdict = {
+}
+degrees_Kelvin._superclassnames = []
+degrees_Kelvin._privpropdict = {
+}
+degrees_Kelvin._privelemdict = {
+}
+reals._superclassnames = []
+reals._privpropdict = {
+}
+reals._privelemdict = {
+}
+encoded_strings._superclassnames = []
+encoded_strings._privpropdict = {
+}
+encoded_strings._privelemdict = {
+}
+constants._superclassnames = []
+constants._privpropdict = {
+}
+constants._privelemdict = {
+}
+events._superclassnames = []
+events._privpropdict = {
+}
+events._privelemdict = {
+}
+February._superclassnames = []
+February._privpropdict = {
+}
+February._privelemdict = {
+}
+feet._superclassnames = []
+feet._privpropdict = {
+}
+feet._privelemdict = {
+}
+Friday._superclassnames = []
+Friday._privpropdict = {
+}
+Friday._privelemdict = {
+}
+file_specification._superclassnames = []
+file_specification._privpropdict = {
+    'POSIX_path' : _Prop_POSIX_path,
+}
+file_specification._privelemdict = {
+}
+gallons._superclassnames = []
+gallons._privpropdict = {
+}
+gallons._privelemdict = {
+}
+grams._superclassnames = []
+grams._privpropdict = {
+}
+grams._privelemdict = {
+}
+handlers._superclassnames = []
+handlers._privpropdict = {
+}
+handlers._privelemdict = {
+}
+inches._superclassnames = []
+inches._privpropdict = {
+}
+inches._privelemdict = {
+}
+international_text._superclassnames = []
+international_text._privpropdict = {
+}
+international_text._privelemdict = {
+}
+international_text._superclassnames = []
+international_text._privpropdict = {
+}
+international_text._privelemdict = {
+}
+January._superclassnames = []
+January._privpropdict = {
+}
+January._privelemdict = {
+}
+July._superclassnames = []
+July._privpropdict = {
+}
+July._privelemdict = {
+}
+June._superclassnames = []
+June._privpropdict = {
+}
+June._privelemdict = {
+}
+reference_forms._superclassnames = []
+reference_forms._privpropdict = {
+}
+reference_forms._privelemdict = {
+}
+kilograms._superclassnames = []
+kilograms._privpropdict = {
+}
+kilograms._privelemdict = {
+}
+kilometers._superclassnames = []
+kilometers._privpropdict = {
+}
+kilometers._privelemdict = {
+}
+keystroke._superclassnames = []
+keystroke._privpropdict = {
+    'key' : _Prop_key,
+    'key_kind' : _Prop_key_kind,
+    'modifiers' : _Prop_modifiers,
+}
+keystroke._privelemdict = {
+}
+pounds._superclassnames = []
+pounds._privpropdict = {
+}
+pounds._privelemdict = {
+}
+date._superclassnames = []
+date._privpropdict = {
+    'date_string' : _Prop_date_string,
+    'day' : _Prop_day,
+    'month' : _Prop_month,
+    'time' : _Prop_time,
+    'time_string' : _Prop_time_string,
+    'weekday' : _Prop_weekday,
+    'year' : _Prop_year,
+}
+date._privelemdict = {
+}
+list._superclassnames = []
+list._privpropdict = {
+    'length' : _Prop_length,
+    'rest' : _Prop_rest,
+    'reverse' : _Prop_reverse,
+}
+list._privelemdict = {
+}
+liters._superclassnames = []
+liters._privpropdict = {
+}
+liters._privelemdict = {
+}
+linked_list._superclassnames = []
+linked_list._privpropdict = {
+    'length' : _Prop_length,
+}
+linked_list._privelemdict = {
+}
+integers._superclassnames = []
+integers._privpropdict = {
+}
+integers._privelemdict = {
+}
+list_or_record._superclassnames = []
+list_or_record._privpropdict = {
+}
+list_or_record._privelemdict = {
+}
+list_2c__record_or_text._superclassnames = []
+list_2c__record_or_text._privpropdict = {
+}
+list_2c__record_or_text._privelemdict = {
+}
+list_or_string._superclassnames = []
+list_or_string._privpropdict = {
+}
+list_or_string._privelemdict = {
+}
+machines._superclassnames = []
+machines._privpropdict = {
+}
+machines._privelemdict = {
+}
+March._superclassnames = []
+March._privpropdict = {
+}
+March._privelemdict = {
+}
+May._superclassnames = []
+May._privpropdict = {
+}
+May._privelemdict = {
+}
+meters._superclassnames = []
+meters._privpropdict = {
+}
+meters._privelemdict = {
+}
+miles._superclassnames = []
+miles._privpropdict = {
+}
+miles._privelemdict = {
+}
+months._superclassnames = []
+months._privpropdict = {
+}
+months._privelemdict = {
+}
+Monday._superclassnames = []
+Monday._privpropdict = {
+}
+Monday._privelemdict = {
+}
+missing_values._superclassnames = []
+missing_values._privpropdict = {
+}
+missing_values._privelemdict = {
+}
+number_or_date._superclassnames = []
+number_or_date._privpropdict = {
+}
+number_or_date._privelemdict = {
+}
+number_2c__date_or_text._superclassnames = []
+number_2c__date_or_text._privpropdict = {
+}
+number_2c__date_or_text._privelemdict = {
+}
+numbers._superclassnames = []
+numbers._privpropdict = {
+}
+numbers._privelemdict = {
+}
+November._superclassnames = []
+November._privpropdict = {
+}
+November._privelemdict = {
+}
+number_or_string._superclassnames = []
+number_or_string._privpropdict = {
+}
+number_or_string._privelemdict = {
+}
+references._superclassnames = []
+references._privpropdict = {
+}
+references._privelemdict = {
+}
+October._superclassnames = []
+October._privpropdict = {
+}
+October._privelemdict = {
+}
+ounces._superclassnames = []
+ounces._privpropdict = {
+}
+ounces._privelemdict = {
+}
+class_._superclassnames = ['type_class']
+class_._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+}
+class_._privelemdict = {
+}
+prepositions._superclassnames = []
+prepositions._privpropdict = {
+}
+prepositions._privelemdict = {
+}
+properties._superclassnames = []
+properties._privpropdict = {
+}
+properties._privelemdict = {
+}
+writing_code._superclassnames = []
+writing_code._privpropdict = {
+}
+writing_code._privelemdict = {
+}
+Pascal_strings._superclassnames = []
+Pascal_strings._privpropdict = {
+}
+Pascal_strings._privelemdict = {
+}
+quarts._superclassnames = []
+quarts._privpropdict = {
+}
+quarts._privelemdict = {
+}
+data._superclassnames = []
+data._privpropdict = {
+}
+data._privelemdict = {
+}
+records._superclassnames = []
+records._privpropdict = {
+}
+records._privelemdict = {
+}
+Saturday._superclassnames = []
+Saturday._privpropdict = {
+}
+Saturday._privelemdict = {
+}
+seconds._superclassnames = []
+seconds._privpropdict = {
+}
+seconds._privelemdict = {
+}
+script._superclassnames = []
+script._privpropdict = {
+    'name' : _Prop_name,
+    'parent' : _Prop_parent,
+}
+script._privelemdict = {
+}
+September._superclassnames = []
+September._privpropdict = {
+}
+September._privelemdict = {
+}
+alias_or_string._superclassnames = []
+alias_or_string._privpropdict = {
+}
+alias_or_string._privelemdict = {
+}
+sounds._superclassnames = []
+sounds._privpropdict = {
+}
+sounds._privelemdict = {
+}
+square_feet._superclassnames = []
+square_feet._privpropdict = {
+}
+square_feet._privelemdict = {
+}
+square_kilometers._superclassnames = []
+square_kilometers._privpropdict = {
+}
+square_kilometers._privelemdict = {
+}
+square_miles._superclassnames = []
+square_miles._privpropdict = {
+}
+square_miles._privelemdict = {
+}
+square_meters._superclassnames = []
+square_meters._privpropdict = {
+}
+square_meters._privelemdict = {
+}
+square_yards._superclassnames = []
+square_yards._privpropdict = {
+}
+square_yards._privelemdict = {
+}
+styled_Clipboard_text._superclassnames = []
+styled_Clipboard_text._privpropdict = {
+}
+styled_Clipboard_text._privelemdict = {
+}
+styled_Clipboard_text._superclassnames = []
+styled_Clipboard_text._privpropdict = {
+}
+styled_Clipboard_text._privelemdict = {
+}
+Sunday._superclassnames = []
+Sunday._privpropdict = {
+}
+Sunday._privelemdict = {
+}
+styled_Unicode_text._superclassnames = []
+styled_Unicode_text._privpropdict = {
+}
+styled_Unicode_text._privelemdict = {
+}
+styled_Unicode_text._superclassnames = []
+styled_Unicode_text._privpropdict = {
+}
+styled_Unicode_text._privelemdict = {
+}
+Thursday._superclassnames = []
+Thursday._privpropdict = {
+}
+Thursday._privelemdict = {
+}
+Tuesday._superclassnames = []
+Tuesday._privpropdict = {
+}
+Tuesday._privelemdict = {
+}
+type_class._superclassnames = []
+type_class._privpropdict = {
+}
+type_class._privelemdict = {
+}
+empty_ae_name_._superclassnames = []
+empty_ae_name_._privpropdict = {
+}
+empty_ae_name_._privelemdict = {
+}
+Unicode_text._superclassnames = []
+Unicode_text._privpropdict = {
+}
+Unicode_text._privelemdict = {
+}
+Unicode_text._superclassnames = []
+Unicode_text._privpropdict = {
+}
+Unicode_text._privelemdict = {
+}
+vector._superclassnames = []
+vector._privpropdict = {
+    'length' : _Prop_length,
+}
+vector._privelemdict = {
+}
+version._superclassnames = []
+version._privpropdict = {
+}
+version._privelemdict = {
+}
+Wednesday._superclassnames = []
+Wednesday._privpropdict = {
+}
+Wednesday._privelemdict = {
+}
+weekdays._superclassnames = []
+weekdays._privpropdict = {
+}
+weekdays._privelemdict = {
+}
+yards._superclassnames = []
+yards._privpropdict = {
+}
+yards._privelemdict = {
+}
+zones._superclassnames = []
+zones._privpropdict = {
+}
+zones._privelemdict = {
+}
+_Enum_boov = {
+    'true' : 'true',    # the true boolean value
+    'false' : 'fals',   # the false boolean value
+}
+
+_Enum_cons = {
+    'case' : 'case',    # case
+    'diacriticals' : 'diac',    # diacriticals
+    'white_space' : 'whit',     # white space
+    'hyphens' : 'hyph', # hyphens
+    'expansion' : 'expa',       # expansion
+    'punctuation' : 'punc',     # punctuation
+    'application_responses' : 'rmte',   # remote event replies
+}
+
+_Enum_eMds = {
+    'option_down' : 'Kopt',     #
+    'command_down' : 'Kcmd',    #
+    'control_down' : 'Kctl',    #
+    'shift_down' : 'Ksft',      #
+    'caps_lock_down' : 'Kclk',  #
+}
+
+_Enum_ekst = {
+    'escape_key' : 'ks5\x00',   #
+    'delete_key' : 'ks3\x00',   #
+    'tab_key' : 'ks0\x00',      #
+    'return_key' : 'ks$\x00',   #
+    'clear_key' : 'ksG\x00',    #
+    'enter_key' : 'ksL\x00',    #
+    'up_arrow_key' : 'ks~\x00', #
+    'down_arrow_key' : 'ks}\x00',       #
+    'left_arrow_key' : 'ks{\x00',       #
+    'right_arrow_key' : 'ks|\x00',      #
+    'help_key' : 'ksr\x00',     #
+    'home_key' : 'kss\x00',     #
+    'page_up_key' : 'kst\x00',  #
+    'page_down_key' : 'ksy\x00',        #
+    'forward_del_key' : 'ksu\x00',      #
+    'end_key' : 'ksw\x00',      #
+    'F1_key' : 'ksz\x00',       #
+    'F2_key' : 'ksx\x00',       #
+    'F3_key' : 'ksc\x00',       #
+    'F4_key' : 'ksv\x00',       #
+    'F5_key' : 'ks`\x00',       #
+    'F6_key' : 'ksa\x00',       #
+    'F7_key' : 'ksb\x00',       #
+    'F8_key' : 'ksd\x00',       #
+    'F9_key' : 'kse\x00',       #
+    'F10_key' : 'ksm\x00',      #
+    'F11_key' : 'ksg\x00',      #
+    'F12_key' : 'kso\x00',      #
+    'F13_key' : 'ksi\x00',      #
+    'F14_key' : 'ksk\x00',      #
+    'F15_key' : 'ksq\x00',      #
+}
+
+_Enum_misc = {
+    'current_application' : 'cura',     # the current application
+}
+
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+    '****' : anything,
+    'PICT' : pictures,
+    'STXT' : styled_text,
+    'TEXT' : strings,
+    'alis' : alias,
+    'apr ' : April,
+    'aug ' : August,
+    'bool' : booleans,
+    'cRGB' : RGB_colors,
+    'capp' : application,
+    'case' : upper_case,
+    'ccmt' : cubic_centimeters,
+    'cfet' : cubic_feet,
+    'cha ' : characters,
+    'citl' : writing_code_info,
+    'citm' : text_items,
+    'cmet' : cubic_meters,
+    'cmtr' : centimeters,
+    'cobj' : item,
+    'cstr' : C_strings,
+    'ctxt' : text,
+    'cuin' : cubic_inches,
+    'cyrd' : cubic_yards,
+    'dec ' : December,
+    'degc' : degrees_Celsius,
+    'degf' : degrees_Fahrenheit,
+    'degk' : degrees_Kelvin,
+    'doub' : reals,
+    'encs' : encoded_strings,
+    'enum' : constants,
+    'evnt' : events,
+    'feb ' : February,
+    'feet' : feet,
+    'fri ' : Friday,
+    'fss ' : file_specification,
+    'galn' : gallons,
+    'gram' : grams,
+    'hand' : handlers,
+    'inch' : inches,
+    'itxt' : international_text,
+    'jan ' : January,
+    'jul ' : July,
+    'jun ' : June,
+    'kfrm' : reference_forms,
+    'kgrm' : kilograms,
+    'kmtr' : kilometers,
+    'kprs' : keystroke,
+    'lbs ' : pounds,
+    'ldt ' : date,
+    'list' : list,
+    'litr' : liters,
+    'llst' : linked_list,
+    'long' : integers,
+    'lr  ' : list_or_record,
+    'lrs ' : list_2c__record_or_text,
+    'ls  ' : list_or_string,
+    'mach' : machines,
+    'mar ' : March,
+    'may ' : May,
+    'metr' : meters,
+    'mile' : miles,
+    'mnth' : months,
+    'mon ' : Monday,
+    'msng' : missing_values,
+    'nd  ' : number_or_date,
+    'nds ' : number_2c__date_or_text,
+    'nmbr' : numbers,
+    'nov ' : November,
+    'ns  ' : number_or_string,
+    'obj ' : references,
+    'oct ' : October,
+    'ozs ' : ounces,
+    'pcls' : class_,
+    'prep' : prepositions,
+    'prop' : properties,
+    'psct' : writing_code,
+    'pstr' : Pascal_strings,
+    'qrts' : quarts,
+    'rdat' : data,
+    'reco' : records,
+    'sat ' : Saturday,
+    'scnd' : seconds,
+    'scpt' : script,
+    'sep ' : September,
+    'sf  ' : alias_or_string,
+    'snd ' : sounds,
+    'sqft' : square_feet,
+    'sqkm' : square_kilometers,
+    'sqmi' : square_miles,
+    'sqrm' : square_meters,
+    'sqyd' : square_yards,
+    'styl' : styled_Clipboard_text,
+    'sun ' : Sunday,
+    'sutx' : styled_Unicode_text,
+    'thu ' : Thursday,
+    'tue ' : Tuesday,
+    'type' : type_class,
+    'undf' : empty_ae_name_,
+    'utxt' : Unicode_text,
+    'vect' : vector,
+    'vers' : version,
+    'wed ' : Wednesday,
+    'wkdy' : weekdays,
+    'yard' : yards,
+    'zone' : zones,
+}
+
+_propdeclarations = {
+    'ID  ' : _Prop_id,
+    'ascr' : _Prop_AppleScript,
+    'c@#^' : _Prop__3c_Inheritance_3e_,
+    'day ' : _Prop_day,
+    'days' : _Prop_days,
+    'dstr' : _Prop_date_string,
+    'hour' : _Prop_hours,
+    'kMod' : _Prop_modifiers,
+    'kMsg' : _Prop_key,
+    'kknd' : _Prop_key_kind,
+    'leng' : _Prop_length,
+    'min ' : _Prop_minutes,
+    'mnth' : _Prop_month,
+    'pare' : _Prop_parent,
+    'pi  ' : _Prop_pi,
+    'plcd' : _Prop_language_code,
+    'pnam' : _Prop_name,
+    'prdp' : _Prop_print_depth,
+    'prln' : _Prop_print_length,
+    'pscd' : _Prop_script_code,
+    'psxp' : _Prop_POSIX_path,
+    'rest' : _Prop_rest,
+    'ret ' : _Prop_return_,
+    'rslt' : _Prop_result,
+    'rvse' : _Prop_reverse,
+    'spac' : _Prop_space,
+    'tab ' : _Prop_tab,
+    'time' : _Prop_time,
+    'tstr' : _Prop_time_string,
+    'txdl' : _Prop_text_item_delimiters,
+    'week' : _Prop_weeks,
+    'wkdy' : _Prop_weekday,
+    'year' : _Prop_year,
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+    'boov' : _Enum_boov,
+    'cons' : _Enum_cons,
+    'eMds' : _Enum_eMds,
+    'ekst' : _Enum_ekst,
+    'misc' : _Enum_misc,
+}

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/StdSuites/Macintosh_Connectivity_Clas.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/StdSuites/Macintosh_Connectivity_Clas.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/StdSuites/Macintosh_Connectivity_Clas.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,373 @@
+"""Suite Macintosh Connectivity Classes: Classes relating to Apple Macintosh personal computer connectivity
+Level 1, version 1
+
+Generated from /Volumes/Sap/System Folder/Extensions/AppleScript
+AETE/AEUT resource version 1/0, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'macc'
+
+class Macintosh_Connectivity_Clas_Events:
+
+    pass
+
+
+class ADB_address(aetools.ComponentItem):
+    """ADB address - Addresses a device connected via Apple Desktop Bus """
+    want = 'cadb'
+class _Prop__3c_inheritance_3e_(aetools.NProperty):
+    """<inheritance> - inherits some of its properties from this class """
+    which = 'c@#^'
+    want = 'cadr'
+class _Prop_ID(aetools.NProperty):
+    """ID - the Apple Desktop Bus device ID """
+    which = 'ID  '
+    want = 'shor'
+
+ADB_addresses = ADB_address
+
+class address_specification(aetools.ComponentItem):
+    """address specification - Unique designation of a device or service connected to this computer """
+    want = 'cadr'
+class _Prop_conduit(aetools.NProperty):
+    """conduit - How the addressee is physically connected """
+    which = 'pcon'
+    want = 'econ'
+class _Prop_properties(aetools.NProperty):
+    """properties - property that allows getting and setting of multiple properties """
+    which = 'pALL'
+    want = 'reco'
+class _Prop_protocol(aetools.NProperty):
+    """protocol - How to talk to this addressee """
+    which = 'pprt'
+    want = 'epro'
+
+address_specifications = address_specification
+
+class AppleTalk_address(aetools.ComponentItem):
+    """AppleTalk address - Addresses a device or service connected via the AppleTalk protocol """
+    want = 'cat '
+class _Prop_AppleTalk_machine(aetools.NProperty):
+    """AppleTalk machine - the machine name part of the address """
+    which = 'patm'
+    want = 'TEXT'
+class _Prop_AppleTalk_type(aetools.NProperty):
+    """AppleTalk type - the type part of the AppleTalk address """
+    which = 'patt'
+    want = 'TEXT'
+class _Prop_AppleTalk_zone(aetools.NProperty):
+    """AppleTalk zone - the zone part of the address """
+    which = 'patz'
+    want = 'TEXT'
+
+AppleTalk_addresses = AppleTalk_address
+
+class bus_slot(aetools.ComponentItem):
+    """bus slot - Addresses a PC, PCI, or NuBus card """
+    want = 'cbus'
+
+bus_slots = bus_slot
+
+class device_specification(aetools.ComponentItem):
+    """device specification - A device connected to a computer """
+    want = 'cdev'
+class _Prop_device_address(aetools.NProperty):
+    """device address - the address of the device """
+    which = 'pdva'
+    want = 'cadr'
+class _Prop_device_type(aetools.NProperty):
+    """device type - the kind of device """
+    which = 'pdvt'
+    want = 'edvt'
+
+device_specifications = device_specification
+
+class Ethernet_address(aetools.ComponentItem):
+    """Ethernet address - Addresses a device by its Ethernet address """
+    want = 'cen '
+
+Ethernet_addresses = Ethernet_address
+
+class FireWire_address(aetools.ComponentItem):
+    """FireWire address - Addresses a device on the FireWire bus """
+    want = 'cfw '
+
+FireWire_addresses = FireWire_address
+
+class IP_address(aetools.ComponentItem):
+    """IP address - Addresses a device or service via the Internet Protocol (IP) """
+    want = 'cip '
+class _Prop_DNS_form(aetools.NProperty):
+    """DNS form - the address in the form "apple.com" """
+    which = 'pdns'
+    want = 'TEXT'
+class _Prop_port(aetools.NProperty):
+    """port - the port number of the service or client being addressed """
+    which = 'ppor'
+    want = 'TEXT'
+
+IP_addresses = IP_address
+
+class LocalTalk_address(aetools.ComponentItem):
+    """LocalTalk address - Addresses a device by its LocalTalk address """
+    want = 'clt '
+class _Prop_network(aetools.NProperty):
+    """network - the LocalTalk network number """
+    which = 'pnet'
+    want = 'shor'
+class _Prop_node(aetools.NProperty):
+    """node - the LocalTalk node number """
+    which = 'pnod'
+    want = 'shor'
+class _Prop_socket(aetools.NProperty):
+    """socket - the LocalTalk socket number """
+    which = 'psoc'
+    want = 'shor'
+
+LocalTalk_addresses = LocalTalk_address
+
+class SCSI_address(aetools.ComponentItem):
+    """SCSI address - Addresses a SCSI device """
+    want = 'cscs'
+class _Prop_LUN(aetools.NProperty):
+    """LUN - the SCSI logical unit number """
+    which = 'pslu'
+    want = 'shor'
+class _Prop_SCSI_bus(aetools.NProperty):
+    """SCSI bus - the SCSI bus number """
+    which = 'pscb'
+    want = 'shor'
+
+SCSI_addresses = SCSI_address
+
+class Token_Ring_address(aetools.ComponentItem):
+    """Token Ring address - Addresses a device or service via the Token Ring protocol """
+    want = 'ctok'
+
+Token_Ring_addresses = Token_Ring_address
+
+class USB_address(aetools.ComponentItem):
+    """USB address - Addresses a device on the Universal Serial Bus """
+    want = 'cusb'
+class _Prop_name(aetools.NProperty):
+    """name - the USB device name """
+    which = 'pnam'
+    want = 'TEXT'
+
+USB_Addresses = USB_address
+ADB_address._superclassnames = ['address_specification']
+ADB_address._privpropdict = {
+    'ID' : _Prop_ID,
+    '_3c_inheritance_3e_' : _Prop__3c_inheritance_3e_,
+}
+ADB_address._privelemdict = {
+}
+address_specification._superclassnames = []
+address_specification._privpropdict = {
+    'conduit' : _Prop_conduit,
+    'properties' : _Prop_properties,
+    'protocol' : _Prop_protocol,
+}
+address_specification._privelemdict = {
+}
+AppleTalk_address._superclassnames = ['address_specification']
+AppleTalk_address._privpropdict = {
+    'AppleTalk_machine' : _Prop_AppleTalk_machine,
+    'AppleTalk_type' : _Prop_AppleTalk_type,
+    'AppleTalk_zone' : _Prop_AppleTalk_zone,
+    '_3c_inheritance_3e_' : _Prop__3c_inheritance_3e_,
+}
+AppleTalk_address._privelemdict = {
+}
+bus_slot._superclassnames = ['address_specification']
+bus_slot._privpropdict = {
+    'ID' : _Prop_ID,
+    '_3c_inheritance_3e_' : _Prop__3c_inheritance_3e_,
+}
+bus_slot._privelemdict = {
+}
+device_specification._superclassnames = []
+device_specification._privpropdict = {
+    'device_address' : _Prop_device_address,
+    'device_type' : _Prop_device_type,
+    'properties' : _Prop_properties,
+}
+device_specification._privelemdict = {
+}
+Ethernet_address._superclassnames = ['address_specification']
+Ethernet_address._privpropdict = {
+    'ID' : _Prop_ID,
+    '_3c_inheritance_3e_' : _Prop__3c_inheritance_3e_,
+}
+Ethernet_address._privelemdict = {
+}
+FireWire_address._superclassnames = ['address_specification']
+FireWire_address._privpropdict = {
+    'ID' : _Prop_ID,
+    '_3c_inheritance_3e_' : _Prop__3c_inheritance_3e_,
+}
+FireWire_address._privelemdict = {
+}
+IP_address._superclassnames = ['address_specification']
+IP_address._privpropdict = {
+    'DNS_form' : _Prop_DNS_form,
+    'ID' : _Prop_ID,
+    '_3c_inheritance_3e_' : _Prop__3c_inheritance_3e_,
+    'port' : _Prop_port,
+}
+IP_address._privelemdict = {
+}
+LocalTalk_address._superclassnames = ['address_specification']
+LocalTalk_address._privpropdict = {
+    '_3c_inheritance_3e_' : _Prop__3c_inheritance_3e_,
+    'network' : _Prop_network,
+    'node' : _Prop_node,
+    'socket' : _Prop_socket,
+}
+LocalTalk_address._privelemdict = {
+}
+SCSI_address._superclassnames = ['address_specification']
+SCSI_address._privpropdict = {
+    'ID' : _Prop_ID,
+    'LUN' : _Prop_LUN,
+    'SCSI_bus' : _Prop_SCSI_bus,
+    '_3c_inheritance_3e_' : _Prop__3c_inheritance_3e_,
+}
+SCSI_address._privelemdict = {
+}
+Token_Ring_address._superclassnames = ['address_specification']
+Token_Ring_address._privpropdict = {
+    'ID' : _Prop_ID,
+    '_3c_inheritance_3e_' : _Prop__3c_inheritance_3e_,
+}
+Token_Ring_address._privelemdict = {
+}
+USB_address._superclassnames = ['address_specification']
+USB_address._privpropdict = {
+    '_3c_inheritance_3e_' : _Prop__3c_inheritance_3e_,
+    'name' : _Prop_name,
+}
+USB_address._privelemdict = {
+}
+_Enum_econ = {
+    'ADB' : 'eadb',     #
+    'printer_port' : 'ecpp',    #
+    'modem_port' : 'ecmp',      #
+    'modem_printer_port' : 'empp',      #
+    'LocalTalk' : 'eclt',       #
+    'Ethernet' : 'ecen',        #
+    'Token_Ring' : 'etok',      #
+    'SCSI' : 'ecsc',    #
+    'USB' : 'ecus',     #
+    'FireWire' : 'ecfw',        #
+    'infrared' : 'ecir',        #
+    'PC_card' : 'ecpc', #
+    'PCI_bus' : 'ecpi', #
+    'NuBus' : 'enub',   #
+    'PDS_slot' : 'ecpd',        #
+    'Comm_slot' : 'eccm',       #
+    'monitor_out' : 'ecmn',     #
+    'video_out' : 'ecvo',       #
+    'video_in' : 'ecvi',        #
+    'audio_out' : 'ecao',       #
+    'audio_line_in' : 'ecai',   #
+    'audio_line_out' : 'ecal',  #
+    'microphone' : 'ecmi',      #
+}
+
+_Enum_edvt = {
+    'hard_disk_drive' : 'ehd ', #
+    'floppy_disk_drive' : 'efd ',       #
+    'CD_ROM_drive' : 'ecd ',    #
+    'DVD_drive' : 'edvd',       #
+    'storage_device' : 'edst',  #
+    'keyboard' : 'ekbd',        #
+    'mouse' : 'emou',   #
+    'trackball' : 'etrk',       #
+    'trackpad' : 'edtp',        #
+    'pointing_device' : 'edpd', #
+    'video_monitor' : 'edvm',   #
+    'LCD_display' : 'edlc',     #
+    'display' : 'edds', #
+    'modem' : 'edmm',   #
+    'PC_card' : 'ecpc', #
+    'PCI_card' : 'edpi',        #
+    'NuBus_card' : 'ednb',      #
+    'printer' : 'edpr', #
+    'speakers' : 'edsp',        #
+    'microphone' : 'ecmi',      #
+}
+
+_Enum_epro = {
+    'serial' : 'epsr',  #
+    'AppleTalk' : 'epat',       #
+    'IP' : 'epip',      #
+    'SCSI' : 'ecsc',    #
+    'ADB' : 'eadb',     #
+    'FireWire' : 'ecfw',        #
+    'IrDA' : 'epir',    #
+    'IRTalk' : 'epit',  #
+    'USB' : 'ecus',     #
+    'PC_card' : 'ecpc', #
+    'PCI_bus' : 'ecpi', #
+    'NuBus' : 'enub',   #
+    'bus' : 'ebus',     #
+    'Macintosh_video' : 'epmv', #
+    'SVGA' : 'epsg',    #
+    'S_video' : 'epsv', #
+    'analog_audio' : 'epau',    #
+    'digital_audio' : 'epda',   #
+    'PostScript' : 'epps',      #
+}
+
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+    'cadb' : ADB_address,
+    'cadr' : address_specification,
+    'cat ' : AppleTalk_address,
+    'cbus' : bus_slot,
+    'cdev' : device_specification,
+    'cen ' : Ethernet_address,
+    'cfw ' : FireWire_address,
+    'cip ' : IP_address,
+    'clt ' : LocalTalk_address,
+    'cscs' : SCSI_address,
+    'ctok' : Token_Ring_address,
+    'cusb' : USB_address,
+}
+
+_propdeclarations = {
+    'ID  ' : _Prop_ID,
+    'c@#^' : _Prop__3c_inheritance_3e_,
+    'pALL' : _Prop_properties,
+    'patm' : _Prop_AppleTalk_machine,
+    'patt' : _Prop_AppleTalk_type,
+    'patz' : _Prop_AppleTalk_zone,
+    'pcon' : _Prop_conduit,
+    'pdns' : _Prop_DNS_form,
+    'pdva' : _Prop_device_address,
+    'pdvt' : _Prop_device_type,
+    'pnam' : _Prop_name,
+    'pnet' : _Prop_network,
+    'pnod' : _Prop_node,
+    'ppor' : _Prop_port,
+    'pprt' : _Prop_protocol,
+    'pscb' : _Prop_SCSI_bus,
+    'pslu' : _Prop_LUN,
+    'psoc' : _Prop_socket,
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+    'econ' : _Enum_econ,
+    'edvt' : _Enum_edvt,
+    'epro' : _Enum_epro,
+}

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/StdSuites/QuickDraw_Graphics_Suite.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/StdSuites/QuickDraw_Graphics_Suite.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/StdSuites/QuickDraw_Graphics_Suite.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,417 @@
+"""Suite QuickDraw Graphics Suite: A set of basic classes for graphics
+Level 1, version 1
+
+Generated from /Volumes/Sap/System Folder/Extensions/AppleScript
+AETE/AEUT resource version 1/0, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'qdrw'
+
+class QuickDraw_Graphics_Suite_Events:
+
+    pass
+
+
+class arc(aetools.ComponentItem):
+    """arc - An arc """
+    want = 'carc'
+class _Prop_arc_angle(aetools.NProperty):
+    """arc angle - the angle of the arc in degrees """
+    which = 'parc'
+    want = 'fixd'
+class _Prop_bounds(aetools.NProperty):
+    """bounds - the smallest rectangle that contains the entire arc """
+    which = 'pbnd'
+    want = 'qdrt'
+class _Prop_definition_rect(aetools.NProperty):
+    """definition rect - the rectangle that contains the circle or oval used to define the arc """
+    which = 'pdrt'
+    want = 'qdrt'
+class _Prop_fill_color(aetools.NProperty):
+    """fill color - the fill color """
+    which = 'flcl'
+    want = 'cRGB'
+class _Prop_fill_pattern(aetools.NProperty):
+    """fill pattern - the fill pattern """
+    which = 'flpt'
+    want = 'cpix'
+class _Prop_pen_color(aetools.NProperty):
+    """pen color - the pen color """
+    which = 'ppcl'
+    want = 'cRGB'
+class _Prop_pen_pattern(aetools.NProperty):
+    """pen pattern - the pen pattern """
+    which = 'pppa'
+    want = 'cpix'
+class _Prop_pen_width(aetools.NProperty):
+    """pen width - the pen width """
+    which = 'ppwd'
+    want = 'shor'
+class _Prop_start_angle(aetools.NProperty):
+    """start angle - the angle that defines the start of the arc, in degrees """
+    which = 'pang'
+    want = 'fixd'
+class _Prop_transfer_mode(aetools.NProperty):
+    """transfer mode - the transfer mode """
+    which = 'pptm'
+    want = 'tran'
+
+arcs = arc
+
+class drawing_area(aetools.ComponentItem):
+    """drawing area - Container for graphics and supporting information """
+    want = 'cdrw'
+class _Prop_background_color(aetools.NProperty):
+    """background color - the color used to fill in unoccupied areas """
+    which = 'pbcl'
+    want = 'cRGB'
+class _Prop_background_pattern(aetools.NProperty):
+    """background pattern - the pattern used to fill in unoccupied areas """
+    which = 'pbpt'
+    want = 'cpix'
+class _Prop_color_table(aetools.NProperty):
+    """color table - the color table """
+    which = 'cltb'
+    want = 'clrt'
+class _Prop_default_font(aetools.NProperty):
+    """default font - the name of the default font for text objects """
+    which = 'ptxf'
+    want = 'itxt'
+class _Prop_default_location(aetools.NProperty):
+    """default location - the default location of each new graphic object """
+    which = 'pnel'
+    want = 'QDpt'
+class _Prop_default_size(aetools.NProperty):
+    """default size - the default size for text objects """
+    which = 'ptps'
+    want = 'fixd'
+class _Prop_name(aetools.NProperty):
+    """name - the name """
+    which = 'pnam'
+    want = 'itxt'
+class _Prop_ordering(aetools.NProperty):
+    """ordering - the ordered list of graphic objects in the drawing area """
+    which = 'gobs'
+    want = 'obj '
+class _Prop_pixel_depth(aetools.NProperty):
+    """pixel depth - the number of bits per pixel """
+    which = 'pdpt'
+    want = 'shor'
+class _Prop_style(aetools.NProperty):
+    """style - the default text style for text objects """
+    which = 'txst'
+    want = 'tsty'
+class _Prop_text_color(aetools.NProperty):
+    """text color - the default color for text objects """
+    which = 'ptxc'
+    want = 'cRGB'
+class _Prop_update_on_change(aetools.NProperty):
+    """update on change - Redraw after each change? """
+    which = 'pupd'
+    want = 'bool'
+class _Prop_writing_code(aetools.NProperty):
+    """writing code - the script system and language of text objects in the drawing area """
+    which = 'psct'
+    want = 'intl'
+
+drawing_areas = drawing_area
+
+class graphic_objects(aetools.ComponentItem):
+    """graphic objects -  """
+    want = 'cgob'
+
+graphic_object = graphic_objects
+
+class graphic_shapes(aetools.ComponentItem):
+    """graphic shapes -  """
+    want = 'cgsh'
+
+graphic_shape = graphic_shapes
+
+class graphic_text(aetools.ComponentItem):
+    """graphic text - A series of characters within a drawing area """
+    want = 'cgtx'
+class _Prop_color(aetools.NProperty):
+    """color - the color of the first character """
+    which = 'colr'
+    want = 'cRGB'
+class _Prop_font(aetools.NProperty):
+    """font - the name of the font of the first character """
+    which = 'font'
+    want = 'ctxt'
+class _Prop_size(aetools.NProperty):
+    """size - the size in points of the first character """
+    which = 'ptsz'
+    want = 'fixd'
+class _Prop_uniform_styles(aetools.NProperty):
+    """uniform styles - the text styles that are uniform throughout the text """
+    which = 'ustl'
+    want = 'tsty'
+
+class ovals(aetools.ComponentItem):
+    """ovals -  """
+    want = 'covl'
+
+oval = ovals
+
+class polygon(aetools.ComponentItem):
+    """polygon - A polygon """
+    want = 'cpgn'
+class _Prop_point_list(aetools.NProperty):
+    """point list - the list of points that define the polygon """
+    which = 'ptlt'
+    want = 'QDpt'
+
+polygons = polygon
+
+class graphic_groups(aetools.ComponentItem):
+    """graphic groups -  """
+    want = 'cpic'
+
+graphic_group = graphic_groups
+
+class pixel_maps(aetools.ComponentItem):
+    """pixel maps -  """
+    want = 'cpix'
+
+pixel_map = pixel_maps
+
+class pixel(aetools.ComponentItem):
+    """pixel - A pixel """
+    want = 'cpxl'
+
+pixels = pixel
+
+class rectangles(aetools.ComponentItem):
+    """rectangles -  """
+    want = 'crec'
+
+rectangle = rectangles
+
+class rounded_rectangle(aetools.ComponentItem):
+    """rounded rectangle - A rounded rectangle """
+    want = 'crrc'
+class _Prop_corner_curve_height(aetools.NProperty):
+    """corner curve height - the height of the oval used to define the shape of the rounded corners """
+    which = 'pchd'
+    want = 'shor'
+class _Prop_corner_curve_width(aetools.NProperty):
+    """corner curve width - the width of the oval used to define the shape of the rounded corners """
+    which = 'pcwd'
+    want = 'shor'
+
+rounded_rectangles = rounded_rectangle
+
+class graphic_line(aetools.ComponentItem):
+    """graphic line - A graphic line """
+    want = 'glin'
+class _Prop_arrow_style(aetools.NProperty):
+    """arrow style - the arrow style """
+    which = 'arro'
+    want = 'arro'
+class _Prop_dash_style(aetools.NProperty):
+    """dash style - the dash style """
+    which = 'pdst'
+    want = 'tdas'
+class _Prop_end_point(aetools.NProperty):
+    """end point - the ending point of the line """
+    which = 'pend'
+    want = 'QDpt'
+class _Prop_start_point(aetools.NProperty):
+    """start point - the starting point of the line """
+    which = 'pstp'
+    want = 'QDpt'
+
+graphic_lines = graphic_line
+arc._superclassnames = []
+arc._privpropdict = {
+    'arc_angle' : _Prop_arc_angle,
+    'bounds' : _Prop_bounds,
+    'definition_rect' : _Prop_definition_rect,
+    'fill_color' : _Prop_fill_color,
+    'fill_pattern' : _Prop_fill_pattern,
+    'pen_color' : _Prop_pen_color,
+    'pen_pattern' : _Prop_pen_pattern,
+    'pen_width' : _Prop_pen_width,
+    'start_angle' : _Prop_start_angle,
+    'transfer_mode' : _Prop_transfer_mode,
+}
+arc._privelemdict = {
+}
+drawing_area._superclassnames = []
+drawing_area._privpropdict = {
+    'background_color' : _Prop_background_color,
+    'background_pattern' : _Prop_background_pattern,
+    'color_table' : _Prop_color_table,
+    'default_font' : _Prop_default_font,
+    'default_location' : _Prop_default_location,
+    'default_size' : _Prop_default_size,
+    'name' : _Prop_name,
+    'ordering' : _Prop_ordering,
+    'pixel_depth' : _Prop_pixel_depth,
+    'style' : _Prop_style,
+    'text_color' : _Prop_text_color,
+    'update_on_change' : _Prop_update_on_change,
+    'writing_code' : _Prop_writing_code,
+}
+drawing_area._privelemdict = {
+}
+graphic_objects._superclassnames = []
+graphic_objects._privpropdict = {
+}
+graphic_objects._privelemdict = {
+}
+graphic_shapes._superclassnames = []
+graphic_shapes._privpropdict = {
+}
+graphic_shapes._privelemdict = {
+}
+graphic_text._superclassnames = []
+graphic_text._privpropdict = {
+    'color' : _Prop_color,
+    'font' : _Prop_font,
+    'size' : _Prop_size,
+    'uniform_styles' : _Prop_uniform_styles,
+}
+graphic_text._privelemdict = {
+}
+ovals._superclassnames = []
+ovals._privpropdict = {
+}
+ovals._privelemdict = {
+}
+polygon._superclassnames = []
+polygon._privpropdict = {
+    'point_list' : _Prop_point_list,
+}
+polygon._privelemdict = {
+}
+graphic_groups._superclassnames = []
+graphic_groups._privpropdict = {
+}
+graphic_groups._privelemdict = {
+}
+pixel_maps._superclassnames = []
+pixel_maps._privpropdict = {
+}
+pixel_maps._privelemdict = {
+}
+pixel._superclassnames = []
+pixel._privpropdict = {
+    'color' : _Prop_color,
+}
+pixel._privelemdict = {
+}
+rectangles._superclassnames = []
+rectangles._privpropdict = {
+}
+rectangles._privelemdict = {
+}
+rounded_rectangle._superclassnames = []
+rounded_rectangle._privpropdict = {
+    'corner_curve_height' : _Prop_corner_curve_height,
+    'corner_curve_width' : _Prop_corner_curve_width,
+}
+rounded_rectangle._privelemdict = {
+}
+graphic_line._superclassnames = []
+graphic_line._privpropdict = {
+    'arrow_style' : _Prop_arrow_style,
+    'dash_style' : _Prop_dash_style,
+    'end_point' : _Prop_end_point,
+    'start_point' : _Prop_start_point,
+}
+graphic_line._privelemdict = {
+}
+_Enum_arro = {
+    'no_arrow' : 'arno',        # No arrow on line
+    'arrow_at_start' : 'arst',  # Arrow at start of line
+    'arrow_at_end' : 'aren',    # Arrow at end of line
+    'arrow_at_both_ends' : 'arbo',      # Arrow at both the start and the end of the line
+}
+
+_Enum_tran = {
+    'copy_pixels' : 'cpy ',     #
+    'not_copy_pixels' : 'ncpy', #
+    'or_pixels' : 'or  ',       #
+    'not_or_pixels' : 'ntor',   #
+    'bic_pixels' : 'bic ',      #
+    'not_bic_pixels' : 'nbic',  #
+    'xor_pixels' : 'xor ',      #
+    'not_xor_pixels' : 'nxor',  #
+    'add_over_pixels' : 'addo', #
+    'add_pin_pixels' : 'addp',  #
+    'sub_over_pixels' : 'subo', #
+    'sub_pin_pixels' : 'subp',  #
+    'ad_max_pixels' : 'admx',   #
+    'ad_min_pixels' : 'admn',   #
+    'blend_pixels' : 'blnd',    #
+}
+
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+    'carc' : arc,
+    'cdrw' : drawing_area,
+    'cgob' : graphic_objects,
+    'cgsh' : graphic_shapes,
+    'cgtx' : graphic_text,
+    'covl' : ovals,
+    'cpgn' : polygon,
+    'cpic' : graphic_groups,
+    'cpix' : pixel_maps,
+    'cpxl' : pixel,
+    'crec' : rectangles,
+    'crrc' : rounded_rectangle,
+    'glin' : graphic_line,
+}
+
+_propdeclarations = {
+    'arro' : _Prop_arrow_style,
+    'cltb' : _Prop_color_table,
+    'colr' : _Prop_color,
+    'flcl' : _Prop_fill_color,
+    'flpt' : _Prop_fill_pattern,
+    'font' : _Prop_font,
+    'gobs' : _Prop_ordering,
+    'pang' : _Prop_start_angle,
+    'parc' : _Prop_arc_angle,
+    'pbcl' : _Prop_background_color,
+    'pbnd' : _Prop_bounds,
+    'pbpt' : _Prop_background_pattern,
+    'pchd' : _Prop_corner_curve_height,
+    'pcwd' : _Prop_corner_curve_width,
+    'pdpt' : _Prop_pixel_depth,
+    'pdrt' : _Prop_definition_rect,
+    'pdst' : _Prop_dash_style,
+    'pend' : _Prop_end_point,
+    'pnam' : _Prop_name,
+    'pnel' : _Prop_default_location,
+    'ppcl' : _Prop_pen_color,
+    'pppa' : _Prop_pen_pattern,
+    'pptm' : _Prop_transfer_mode,
+    'ppwd' : _Prop_pen_width,
+    'psct' : _Prop_writing_code,
+    'pstp' : _Prop_start_point,
+    'ptlt' : _Prop_point_list,
+    'ptps' : _Prop_default_size,
+    'ptsz' : _Prop_size,
+    'ptxc' : _Prop_text_color,
+    'ptxf' : _Prop_default_font,
+    'pupd' : _Prop_update_on_change,
+    'txst' : _Prop_style,
+    'ustl' : _Prop_uniform_styles,
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+    'arro' : _Enum_arro,
+    'tran' : _Enum_tran,
+}

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/StdSuites/QuickDraw_Graphics_Suppleme.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/StdSuites/QuickDraw_Graphics_Suppleme.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/StdSuites/QuickDraw_Graphics_Suppleme.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,73 @@
+"""Suite QuickDraw Graphics Supplemental Suite: Defines transformations of graphic objects
+Level 1, version 1
+
+Generated from /Volumes/Sap/System Folder/Extensions/AppleScript
+AETE/AEUT resource version 1/0, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'qdsp'
+
+class QuickDraw_Graphics_Suppleme_Events:
+
+    pass
+
+
+class drawing_area(aetools.ComponentItem):
+    """drawing area - Container for graphics and supporting information """
+    want = 'cdrw'
+class _Prop_rotation(aetools.NProperty):
+    """rotation - the default rotation for objects in the drawing area """
+    which = 'prot'
+    want = 'trot'
+class _Prop_scale(aetools.NProperty):
+    """scale - the default scaling for objects in the drawing area """
+    which = 'pscl'
+    want = 'fixd'
+class _Prop_translation(aetools.NProperty):
+    """translation - the default repositioning for objects in the drawing area """
+    which = 'ptrs'
+    want = 'QDpt'
+
+drawing_areas = drawing_area
+
+class graphic_groups(aetools.ComponentItem):
+    """graphic groups -  """
+    want = 'cpic'
+
+graphic_group = graphic_groups
+drawing_area._superclassnames = []
+drawing_area._privpropdict = {
+    'rotation' : _Prop_rotation,
+    'scale' : _Prop_scale,
+    'translation' : _Prop_translation,
+}
+drawing_area._privelemdict = {
+}
+graphic_groups._superclassnames = []
+graphic_groups._privpropdict = {
+}
+graphic_groups._privelemdict = {
+}
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+    'cdrw' : drawing_area,
+    'cpic' : graphic_groups,
+}
+
+_propdeclarations = {
+    'prot' : _Prop_rotation,
+    'pscl' : _Prop_scale,
+    'ptrs' : _Prop_translation,
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+}

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/StdSuites/Required_Suite.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/StdSuites/Required_Suite.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/StdSuites/Required_Suite.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,32 @@
+"""Suite Required Suite: Every application supports open, print, run, and quit
+Level 1, version 1
+
+Generated from /Volumes/Sap/System Folder/Extensions/AppleScript
+AETE/AEUT resource version 1/0, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'reqd'
+
+from _builtinSuites.builtin_Suite import *
+class Required_Suite_Events(builtin_Suite_Events):
+
+    pass
+
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+}
+
+_propdeclarations = {
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+}

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/StdSuites/Standard_Suite.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/StdSuites/Standard_Suite.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/StdSuites/Standard_Suite.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,738 @@
+"""Suite Standard Suite: Common terms for most applications
+Level 1, version 1
+
+Generated from /Volumes/Sap/System Folder/Extensions/AppleScript
+AETE/AEUT resource version 1/0, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'core'
+
+from _builtinSuites.builtin_Suite import *
+class Standard_Suite_Events(builtin_Suite_Events):
+
+    _argmap_class_info = {
+        'in_' : 'wrcd',
+    }
+
+    def class_info(self, _object=None, _attributes={}, **_arguments):
+        """class info: (optional) Get information about an object class
+        Required argument: the object class about which information is requested
+        Keyword argument in_: the human language and script system in which to return information
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: a record containing the object\xd5s properties and elements
+        """
+        _code = 'core'
+        _subcode = 'qobj'
+
+        aetools.keysubst(_arguments, self._argmap_class_info)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_close = {
+        'saving' : 'savo',
+        'saving_in' : 'kfil',
+    }
+
+    def close(self, _object, _attributes={}, **_arguments):
+        """close: Close an object
+        Required argument: the object to close
+        Keyword argument saving: specifies whether changes should be saved before closing
+        Keyword argument saving_in: the file or alias in which to save the object
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'core'
+        _subcode = 'clos'
+
+        aetools.keysubst(_arguments, self._argmap_close)
+        _arguments['----'] = _object
+
+        aetools.enumsubst(_arguments, 'savo', _Enum_savo)
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_count = {
+        'each' : 'kocl',
+    }
+
+    def count(self, _object, _attributes={}, **_arguments):
+        """count: Return the number of elements of an object
+        Required argument: the object whose elements are to be counted
+        Keyword argument each: if specified, restricts counting to objects of this class
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: the number of elements
+        """
+        _code = 'core'
+        _subcode = 'cnte'
+
+        aetools.keysubst(_arguments, self._argmap_count)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_data_size = {
+        'as' : 'rtyp',
+    }
+
+    def data_size(self, _object, _attributes={}, **_arguments):
+        """data size: (optional) Return the size in bytes of an object
+        Required argument: the object whose data size is to be returned
+        Keyword argument as: the data type for which the size is calculated
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: the size of the object in bytes
+        """
+        _code = 'core'
+        _subcode = 'dsiz'
+
+        aetools.keysubst(_arguments, self._argmap_data_size)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def delete(self, _object, _attributes={}, **_arguments):
+        """delete: Delete an object from its container. Note this does not work on script variables, only on elements of application classes.
+        Required argument: the element to delete
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'core'
+        _subcode = 'delo'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_duplicate = {
+        'to' : 'insh',
+        'with_properties' : 'prdt',
+    }
+
+    def duplicate(self, _object, _attributes={}, **_arguments):
+        """duplicate: Duplicate one or more objects
+        Required argument: the object(s) to duplicate
+        Keyword argument to: the new location for the object(s)
+        Keyword argument with_properties: the initial values for properties of the new object that are to be different from the original
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: to the duplicated object(s)
+        """
+        _code = 'core'
+        _subcode = 'clon'
+
+        aetools.keysubst(_arguments, self._argmap_duplicate)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_event_info = {
+        'in_' : 'wrcd',
+    }
+
+    def event_info(self, _object, _attributes={}, **_arguments):
+        """event info: (optional) Get information about the Apple events in a suite
+        Required argument: the event class of the Apple events for which to return information
+        Keyword argument in_: the human language and script system in which to return information
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: a record containing the events and their parameters
+        """
+        _code = 'core'
+        _subcode = 'gtei'
+
+        aetools.keysubst(_arguments, self._argmap_event_info)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def exists(self, _object, _attributes={}, **_arguments):
+        """exists: Verify if an object exists
+        Required argument: the object in question
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: true if it exists, false if not
+        """
+        _code = 'core'
+        _subcode = 'doex'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def handleBreakpoint(self, _object, _attributes={}, **_arguments):
+        """handleBreakpoint: return true to stop at a breakpoint
+        Required argument: the call frame of the breakpoint
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: true to stop, false if not
+        """
+        _code = 'core'
+        _subcode = 'brak'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_make = {
+        'new' : 'kocl',
+        'at' : 'insh',
+        'with_data' : 'data',
+        'with_properties' : 'prdt',
+    }
+
+    def make(self, _no_object=None, _attributes={}, **_arguments):
+        """make: Make a new element
+        Keyword argument new: the class of the new element
+        Keyword argument at: the location at which to insert the element
+        Keyword argument with_data: the initial data for the element
+        Keyword argument with_properties: the initial values for the properties of the element
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: to the new object(s)
+        """
+        _code = 'core'
+        _subcode = 'crel'
+
+        aetools.keysubst(_arguments, self._argmap_make)
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_move = {
+        'to' : 'insh',
+    }
+
+    def move(self, _object, _attributes={}, **_arguments):
+        """move: Move object(s) to a new location
+        Required argument: the object(s) to move
+        Keyword argument to: the new location for the object(s)
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: to the object(s) after they have been moved
+        """
+        _code = 'core'
+        _subcode = 'move'
+
+        aetools.keysubst(_arguments, self._argmap_move)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def open(self, _object, _attributes={}, **_arguments):
+        """open: Open the specified object(s)
+        Required argument: list of objects to open
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'aevt'
+        _subcode = 'odoc'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def print_(self, _object, _attributes={}, **_arguments):
+        """print: Print the specified object(s)
+        Required argument: list of objects to print
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'aevt'
+        _subcode = 'pdoc'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_quit = {
+        'saving' : 'savo',
+    }
+
+    def quit(self, _no_object=None, _attributes={}, **_arguments):
+        """quit: Quit an application
+        Keyword argument saving: specifies whether to save currently open documents
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'aevt'
+        _subcode = 'quit'
+
+        aetools.keysubst(_arguments, self._argmap_quit)
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+        aetools.enumsubst(_arguments, 'savo', _Enum_savo)
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def reopen(self, _no_object=None, _attributes={}, **_arguments):
+        """reopen: Reactivate a running application.  Some applications will open a new untitled window if no window is open.
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'aevt'
+        _subcode = 'rapp'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def run(self, _no_object=None, _attributes={}, **_arguments):
+        """run: Run an application.  Most applications will open an empty, untitled window.
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'aevt'
+        _subcode = 'oapp'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_save = {
+        'in_' : 'kfil',
+        'as' : 'fltp',
+    }
+
+    def save(self, _object, _attributes={}, **_arguments):
+        """save: Save an object
+        Required argument: the object to save, usually a document or window
+        Keyword argument in_: the file or alias in which to save the object
+        Keyword argument as: the file type of the document in which to save the data
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'core'
+        _subcode = 'save'
+
+        aetools.keysubst(_arguments, self._argmap_save)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def select(self, _object, _attributes={}, **_arguments):
+        """select: Make a selection
+        Required argument: the object to select
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'misc'
+        _subcode = 'slct'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_suite_info = {
+        'in_' : 'wrcd',
+    }
+
+    def suite_info(self, _object, _attributes={}, **_arguments):
+        """suite info: (optional) Get information about event suite(s)
+        Required argument: the suite for which to return information
+        Keyword argument in_: the human language and script system in which to return information
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: a record containing the suites and their versions
+        """
+        _code = 'core'
+        _subcode = 'gtsi'
+
+        aetools.keysubst(_arguments, self._argmap_suite_info)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+
+class alias(aetools.ComponentItem):
+    """alias - a file on a disk or server.  The file must exist when you check the syntax of your script. """
+    want = 'alis'
+class _Prop_POSIX_path(aetools.NProperty):
+    """POSIX path - the POSIX path of the file """
+    which = 'psxp'
+    want = 'TEXT'
+
+aliases = alias
+
+class application(aetools.ComponentItem):
+    """application - An application program """
+    want = 'capp'
+class _Prop_clipboard(aetools.NProperty):
+    """clipboard - the contents of the clipboard for this application """
+    which = 'pcli'
+    want = '****'
+clipboard = _Prop_clipboard()
+class _Prop_frontmost(aetools.NProperty):
+    """frontmost - Is this the frontmost application? """
+    which = 'pisf'
+    want = 'bool'
+frontmost = _Prop_frontmost()
+class _Prop_name(aetools.NProperty):
+    """name - the name of the application """
+    which = 'pnam'
+    want = 'itxt'
+name = _Prop_name()
+class _Prop_selection(aetools.NProperty):
+    """selection - the selection visible to the user.  Use the \xd4select\xd5 command to set a new selection; use \xd4contents of selection\xd5 to get or change information in the document. """
+    which = 'sele'
+    want = 'csel'
+selection = _Prop_selection()
+class _Prop_version(aetools.NProperty):
+    """version - the version of the application """
+    which = 'vers'
+    want = 'vers'
+version = _Prop_version()
+
+applications = application
+
+class insertion_points(aetools.ComponentItem):
+    """insertion points -  """
+    want = 'cins'
+
+insertion_point = insertion_points
+
+class selection_2d_object(aetools.ComponentItem):
+    """selection-object - A way to refer to the state of the current of the selection.  Use the \xd4select\xd5 command to make a new selection. """
+    want = 'csel'
+class _Prop_contents(aetools.NProperty):
+    """contents - the information currently selected.  Use \xd4contents of selection\xd5 to get or change information in a document. """
+    which = 'pcnt'
+    want = '****'
+
+class window(aetools.ComponentItem):
+    """window - A window """
+    want = 'cwin'
+class _Prop_bounds(aetools.NProperty):
+    """bounds - the boundary rectangle for the window """
+    which = 'pbnd'
+    want = 'qdrt'
+class _Prop_closeable(aetools.NProperty):
+    """closeable - Does the window have a close box? """
+    which = 'hclb'
+    want = 'bool'
+class _Prop_floating(aetools.NProperty):
+    """floating - Does the window float? """
+    which = 'isfl'
+    want = 'bool'
+class _Prop_index(aetools.NProperty):
+    """index - the number of the window """
+    which = 'pidx'
+    want = 'long'
+class _Prop_modal(aetools.NProperty):
+    """modal - Is the window modal? """
+    which = 'pmod'
+    want = 'bool'
+class _Prop_resizable(aetools.NProperty):
+    """resizable - Is the window resizable? """
+    which = 'prsz'
+    want = 'bool'
+class _Prop_titled(aetools.NProperty):
+    """titled - Does the window have a title bar? """
+    which = 'ptit'
+    want = 'bool'
+class _Prop_visible(aetools.NProperty):
+    """visible - Is the window visible? """
+    which = 'pvis'
+    want = 'bool'
+class _Prop_zoomable(aetools.NProperty):
+    """zoomable - Is the window zoomable? """
+    which = 'iszm'
+    want = 'bool'
+class _Prop_zoomed(aetools.NProperty):
+    """zoomed - Is the window zoomed? """
+    which = 'pzum'
+    want = 'bool'
+
+windows = window
+
+class document(aetools.ComponentItem):
+    """document - A document of a scriptable application """
+    want = 'docu'
+class _Prop_modified(aetools.NProperty):
+    """modified - Has the document been modified since the last save? """
+    which = 'imod'
+    want = 'bool'
+
+documents = document
+
+class file(aetools.ComponentItem):
+    """file - a file on a disk or server """
+    want = 'file'
+
+files = file
+alias._superclassnames = []
+alias._privpropdict = {
+    'POSIX_path' : _Prop_POSIX_path,
+}
+alias._privelemdict = {
+}
+application._superclassnames = []
+application._privpropdict = {
+    'clipboard' : _Prop_clipboard,
+    'frontmost' : _Prop_frontmost,
+    'name' : _Prop_name,
+    'selection' : _Prop_selection,
+    'version' : _Prop_version,
+}
+application._privelemdict = {
+}
+insertion_points._superclassnames = []
+insertion_points._privpropdict = {
+}
+insertion_points._privelemdict = {
+}
+selection_2d_object._superclassnames = []
+selection_2d_object._privpropdict = {
+    'contents' : _Prop_contents,
+}
+selection_2d_object._privelemdict = {
+}
+window._superclassnames = []
+window._privpropdict = {
+    'bounds' : _Prop_bounds,
+    'closeable' : _Prop_closeable,
+    'floating' : _Prop_floating,
+    'index' : _Prop_index,
+    'modal' : _Prop_modal,
+    'resizable' : _Prop_resizable,
+    'titled' : _Prop_titled,
+    'visible' : _Prop_visible,
+    'zoomable' : _Prop_zoomable,
+    'zoomed' : _Prop_zoomed,
+}
+window._privelemdict = {
+}
+document._superclassnames = []
+document._privpropdict = {
+    'modified' : _Prop_modified,
+}
+document._privelemdict = {
+}
+file._superclassnames = []
+file._privpropdict = {
+    'POSIX_path' : _Prop_POSIX_path,
+}
+file._privelemdict = {
+}
+class _3c_(aetools.NComparison):
+    """< - Less than """
+class _3d_(aetools.NComparison):
+    """= - Equal """
+class _3e_(aetools.NComparison):
+    """> - Greater than """
+class contains(aetools.NComparison):
+    """contains - Contains """
+class ends_with(aetools.NComparison):
+    """ends with - Ends with """
+class starts_with(aetools.NComparison):
+    """starts with - Starts with """
+class _b2_(aetools.NComparison):
+    """\xb2 - Less than or equal to """
+class _b3_(aetools.NComparison):
+    """\xb3 - Greater than or equal to """
+_Enum_kfrm = {
+    'index' : 'indx',   # keyform designating indexed access
+    'named' : 'name',   # keyform designating named access
+    'id' : 'ID  ',      # keyform designating access by unique identifier
+}
+
+_Enum_savo = {
+    'yes' : 'yes ',     # Save objects now
+    'no' : 'no  ',      # Do not save objects
+    'ask' : 'ask ',     # Ask the user whether to save
+}
+
+_Enum_styl = {
+    'plain' : 'plan',   # Plain
+    'bold' : 'bold',    # Bold
+    'italic' : 'ital',  # Italic
+    'outline' : 'outl', # Outline
+    'shadow' : 'shad',  # Shadow
+    'underline' : 'undl',       # Underline
+    'superscript' : 'spsc',     # Superscript
+    'subscript' : 'sbsc',       # Subscript
+    'strikethrough' : 'strk',   # Strikethrough
+    'small_caps' : 'smcp',      # Small caps
+    'all_caps' : 'alcp',        # All capital letters
+    'all_lowercase' : 'lowc',   # Lowercase
+    'condensed' : 'cond',       # Condensed
+    'expanded' : 'pexp',        # Expanded
+    'hidden' : 'hidn',  # Hidden
+}
+
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+    'alis' : alias,
+    'capp' : application,
+    'cins' : insertion_points,
+    'csel' : selection_2d_object,
+    'cwin' : window,
+    'docu' : document,
+    'file' : file,
+}
+
+_propdeclarations = {
+    'hclb' : _Prop_closeable,
+    'imod' : _Prop_modified,
+    'isfl' : _Prop_floating,
+    'iszm' : _Prop_zoomable,
+    'pbnd' : _Prop_bounds,
+    'pcli' : _Prop_clipboard,
+    'pcnt' : _Prop_contents,
+    'pidx' : _Prop_index,
+    'pisf' : _Prop_frontmost,
+    'pmod' : _Prop_modal,
+    'pnam' : _Prop_name,
+    'prsz' : _Prop_resizable,
+    'psxp' : _Prop_POSIX_path,
+    'ptit' : _Prop_titled,
+    'pvis' : _Prop_visible,
+    'pzum' : _Prop_zoomed,
+    'sele' : _Prop_selection,
+    'vers' : _Prop_version,
+}
+
+_compdeclarations = {
+    '<   ' : _3c_,
+    '<=  ' : _b2_,
+    '=   ' : _3d_,
+    '>   ' : _3e_,
+    '>=  ' : _b3_,
+    'bgwt' : starts_with,
+    'cont' : contains,
+    'ends' : ends_with,
+}
+
+_enumdeclarations = {
+    'kfrm' : _Enum_kfrm,
+    'savo' : _Enum_savo,
+    'styl' : _Enum_styl,
+}

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/StdSuites/Table_Suite.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/StdSuites/Table_Suite.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/StdSuites/Table_Suite.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,104 @@
+"""Suite Table Suite: Classes for manipulating tables
+Level 1, version 1
+
+Generated from /Volumes/Sap/System Folder/Extensions/AppleScript
+AETE/AEUT resource version 1/0, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'tbls'
+
+class Table_Suite_Events:
+
+    pass
+
+
+class cell(aetools.ComponentItem):
+    """cell - A cell """
+    want = 'ccel'
+class _Prop_formula(aetools.NProperty):
+    """formula - the formula of the cell """
+    which = 'pfor'
+    want = 'ctxt'
+class _Prop_protection(aetools.NProperty):
+    """protection - Indicates whether value or formula in the cell can be changed """
+    which = 'ppro'
+    want = 'prtn'
+
+cells = cell
+
+class column(aetools.ComponentItem):
+    """column - A column """
+    want = 'ccol'
+class _Prop_name(aetools.NProperty):
+    """name - the name of the column """
+    which = 'pnam'
+    want = 'itxt'
+
+columns = column
+
+class rows(aetools.ComponentItem):
+    """rows -  """
+    want = 'crow'
+
+row = rows
+
+class tables(aetools.ComponentItem):
+    """tables -  """
+    want = 'ctbl'
+
+table = tables
+cell._superclassnames = []
+cell._privpropdict = {
+    'formula' : _Prop_formula,
+    'protection' : _Prop_protection,
+}
+cell._privelemdict = {
+}
+column._superclassnames = []
+column._privpropdict = {
+    'name' : _Prop_name,
+}
+column._privelemdict = {
+}
+rows._superclassnames = []
+rows._privpropdict = {
+}
+rows._privelemdict = {
+}
+tables._superclassnames = []
+tables._privpropdict = {
+}
+tables._privelemdict = {
+}
+_Enum_prtn = {
+    'read_only' : 'nmod',       # Can\xd5t change values or formulas
+    'formulas_protected' : 'fpro',      # Can changes values but not formulas
+    'read_2f_write' : 'modf',   # Can change values and formulas
+}
+
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+    'ccel' : cell,
+    'ccol' : column,
+    'crow' : rows,
+    'ctbl' : tables,
+}
+
+_propdeclarations = {
+    'pfor' : _Prop_formula,
+    'pnam' : _Prop_name,
+    'ppro' : _Prop_protection,
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+    'prtn' : _Enum_prtn,
+}

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/StdSuites/Text_Suite.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/StdSuites/Text_Suite.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/StdSuites/Text_Suite.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,224 @@
+"""Suite Text Suite: A set of basic classes for text processing
+Level 1, version 1
+
+Generated from /Volumes/Sap/System Folder/Extensions/AppleScript
+AETE/AEUT resource version 1/0, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'TEXT'
+
+class Text_Suite_Events:
+
+    pass
+
+
+class text_flow(aetools.ComponentItem):
+    """text flow - A contiguous block of text.  Page layout applications call this a \xd4story.\xd5 """
+    want = 'cflo'
+class _Prop__3c_inheritance_3e_(aetools.NProperty):
+    """<inheritance> - inherits some of its properties from this class """
+    which = 'c@#^'
+    want = 'ctxt'
+class _Prop_name(aetools.NProperty):
+    """name - the name """
+    which = 'pnam'
+    want = 'itxt'
+
+text_flows = text_flow
+
+class character(aetools.ComponentItem):
+    """character - A character """
+    want = 'cha '
+
+class line(aetools.ComponentItem):
+    """line - A line of text """
+    want = 'clin'
+class _Prop_justification(aetools.NProperty):
+    """justification - the justification of the text """
+    which = 'pjst'
+    want = 'just'
+
+lines = line
+
+class paragraph(aetools.ComponentItem):
+    """paragraph - A paragraph """
+    want = 'cpar'
+
+paragraphs = paragraph
+
+class text(aetools.ComponentItem):
+    """text - Text """
+    want = 'ctxt'
+class _Prop_color(aetools.NProperty):
+    """color - the color of the first character """
+    which = 'colr'
+    want = 'cRGB'
+class _Prop_font(aetools.NProperty):
+    """font - the name of the font of the first character """
+    which = 'font'
+    want = 'ctxt'
+class _Prop_quoted_form(aetools.NProperty):
+    """quoted form - the text in quoted form """
+    which = 'strq'
+    want = 'ctxt'
+class _Prop_size(aetools.NProperty):
+    """size - the size in points of the first character """
+    which = 'ptsz'
+    want = 'fixd'
+class _Prop_style(aetools.NProperty):
+    """style - the text style of the first character of the first character """
+    which = 'txst'
+    want = 'tsty'
+class _Prop_uniform_styles(aetools.NProperty):
+    """uniform styles - the text styles that are uniform throughout the text """
+    which = 'ustl'
+    want = 'tsty'
+class _Prop_writing_code(aetools.NProperty):
+    """writing code - the script system and language """
+    which = 'psct'
+    want = 'intl'
+#        element 'cha ' as ['indx']
+#        element 'clin' as ['indx']
+#        element 'cpar' as ['indx']
+#        element 'ctxt' as ['indx']
+#        element 'cwor' as ['indx']
+
+class word(aetools.ComponentItem):
+    """word - A word """
+    want = 'cwor'
+
+words = word
+
+class text_style_info(aetools.ComponentItem):
+    """text style info - On and Off styles of text run """
+    want = 'tsty'
+class _Prop_off_styles(aetools.NProperty):
+    """off styles - the styles that are off for the text """
+    which = 'ofst'
+    want = 'styl'
+class _Prop_on_styles(aetools.NProperty):
+    """on styles - the styles that are on for the text """
+    which = 'onst'
+    want = 'styl'
+
+text_style_infos = text_style_info
+text_flow._superclassnames = ['text']
+text_flow._privpropdict = {
+    '_3c_inheritance_3e_' : _Prop__3c_inheritance_3e_,
+    'name' : _Prop_name,
+}
+text_flow._privelemdict = {
+}
+character._superclassnames = ['text']
+character._privpropdict = {
+    '_3c_inheritance_3e_' : _Prop__3c_inheritance_3e_,
+}
+character._privelemdict = {
+}
+line._superclassnames = ['text']
+line._privpropdict = {
+    '_3c_inheritance_3e_' : _Prop__3c_inheritance_3e_,
+    'justification' : _Prop_justification,
+}
+line._privelemdict = {
+}
+paragraph._superclassnames = ['text']
+paragraph._privpropdict = {
+    '_3c_inheritance_3e_' : _Prop__3c_inheritance_3e_,
+}
+paragraph._privelemdict = {
+}
+text._superclassnames = []
+text._privpropdict = {
+    'color' : _Prop_color,
+    'font' : _Prop_font,
+    'quoted_form' : _Prop_quoted_form,
+    'size' : _Prop_size,
+    'style' : _Prop_style,
+    'uniform_styles' : _Prop_uniform_styles,
+    'writing_code' : _Prop_writing_code,
+}
+text._privelemdict = {
+    'character' : character,
+    'line' : line,
+    'paragraph' : paragraph,
+    'text' : text,
+    'word' : word,
+}
+word._superclassnames = ['text']
+word._privpropdict = {
+    '_3c_inheritance_3e_' : _Prop__3c_inheritance_3e_,
+}
+word._privelemdict = {
+}
+text_style_info._superclassnames = []
+text_style_info._privpropdict = {
+    'off_styles' : _Prop_off_styles,
+    'on_styles' : _Prop_on_styles,
+}
+text_style_info._privelemdict = {
+}
+_Enum_just = {
+    'left' : 'left',    # Align with left margin
+    'right' : 'rght',   # Align with right margin
+    'center' : 'cent',  # Align with center
+    'full' : 'full',    # Align with both left and right margins
+}
+
+_Enum_styl = {
+    'plain' : 'plan',   # Plain
+    'bold' : 'bold',    # Bold
+    'italic' : 'ital',  # Italic
+    'outline' : 'outl', # Outline
+    'shadow' : 'shad',  # Shadow
+    'underline' : 'undl',       # Underline
+    'superscript' : 'spsc',     # Superscript
+    'subscript' : 'sbsc',       # Subscript
+    'strikethrough' : 'strk',   # Strikethrough
+    'small_caps' : 'smcp',      # Small caps
+    'all_caps' : 'alcp',        # All capital letters
+    'all_lowercase' : 'lowc',   # Lowercase
+    'condensed' : 'cond',       # Condensed
+    'expanded' : 'pexp',        # Expanded
+    'hidden' : 'hidn',  # Hidden
+}
+
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+    'cflo' : text_flow,
+    'cha ' : character,
+    'clin' : line,
+    'cpar' : paragraph,
+    'ctxt' : text,
+    'cwor' : word,
+    'tsty' : text_style_info,
+}
+
+_propdeclarations = {
+    'c@#^' : _Prop__3c_inheritance_3e_,
+    'colr' : _Prop_color,
+    'font' : _Prop_font,
+    'ofst' : _Prop_off_styles,
+    'onst' : _Prop_on_styles,
+    'pjst' : _Prop_justification,
+    'pnam' : _Prop_name,
+    'psct' : _Prop_writing_code,
+    'ptsz' : _Prop_size,
+    'strq' : _Prop_quoted_form,
+    'txst' : _Prop_style,
+    'ustl' : _Prop_uniform_styles,
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+    'just' : _Enum_just,
+    'styl' : _Enum_styl,
+}

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/StdSuites/Type_Names_Suite.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/StdSuites/Type_Names_Suite.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/StdSuites/Type_Names_Suite.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,435 @@
+"""Suite Type Names Suite: Terminology for Registry data types
+Level 1, version 1
+
+Generated from /Volumes/Sap/System Folder/Extensions/AppleScript
+AETE/AEUT resource version 1/0, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'tpnm'
+
+class Type_Names_Suite_Events:
+
+    pass
+
+
+class PostScript_picture(aetools.ComponentItem):
+    """PostScript picture -  """
+    want = 'EPS '
+
+class point(aetools.ComponentItem):
+    """point - point coordinates """
+    want = 'QDpt'
+
+class string(aetools.ComponentItem):
+    """string - a string of characters """
+    want = 'TEXT'
+
+plain_text = string
+
+plain_text = string
+
+class TIFF_picture(aetools.ComponentItem):
+    """TIFF picture -  """
+    want = 'TIFF'
+
+class application_dictionary(aetools.ComponentItem):
+    """application dictionary -  """
+    want = 'aete'
+
+class system_dictionary(aetools.ComponentItem):
+    """system dictionary -  """
+    want = 'aeut'
+
+class color_table(aetools.ComponentItem):
+    """color table -  """
+    want = 'clrt'
+
+class menu_item(aetools.ComponentItem):
+    """menu item -  """
+    want = 'cmen'
+
+class menu(aetools.ComponentItem):
+    """menu -  """
+    want = 'cmnu'
+
+class double_integer(aetools.ComponentItem):
+    """double integer -  """
+    want = 'comp'
+
+class type_element_info(aetools.ComponentItem):
+    """type element info -  """
+    want = 'elin'
+
+class type_event_info(aetools.ComponentItem):
+    """type event info - information about an event """
+    want = 'evin'
+
+class extended_real(aetools.ComponentItem):
+    """extended real -  """
+    want = 'exte'
+
+class fixed(aetools.ComponentItem):
+    """fixed - a real number """
+    want = 'fixd'
+
+class fixed_point(aetools.ComponentItem):
+    """fixed point -  """
+    want = 'fpnt'
+
+class fixed_rectangle(aetools.ComponentItem):
+    """fixed rectangle -  """
+    want = 'frct'
+
+class type_class_info(aetools.ComponentItem):
+    """type class info - information about properties and elements of a class """
+    want = 'gcli'
+
+class location_reference(aetools.ComponentItem):
+    """location reference -  """
+    want = 'insl'
+
+class long_fixed_point(aetools.ComponentItem):
+    """long fixed point -  """
+    want = 'lfpt'
+
+class long_fixed_rectangle(aetools.ComponentItem):
+    """long fixed rectangle -  """
+    want = 'lfrc'
+
+class long_fixed(aetools.ComponentItem):
+    """long fixed -  """
+    want = 'lfxd'
+
+class long_point(aetools.ComponentItem):
+    """long point -  """
+    want = 'lpnt'
+
+class long_rectangle(aetools.ComponentItem):
+    """long rectangle -  """
+    want = 'lrct'
+
+class machine_location(aetools.ComponentItem):
+    """machine location -  """
+    want = 'mLoc'
+
+class unsigned_integer(aetools.ComponentItem):
+    """unsigned integer -  """
+    want = 'magn'
+
+class null(aetools.ComponentItem):
+    """null -  """
+    want = 'null'
+
+class type_property_info(aetools.ComponentItem):
+    """type property info -  """
+    want = 'pinf'
+
+class type_parameter_info(aetools.ComponentItem):
+    """type parameter info -  """
+    want = 'pmin'
+
+class bounding_rectangle(aetools.ComponentItem):
+    """bounding rectangle - bounding rectangle """
+    want = 'qdrt'
+
+class small_integer(aetools.ComponentItem):
+    """small integer -  """
+    want = 'shor'
+
+class small_real(aetools.ComponentItem):
+    """small real -  """
+    want = 'sing'
+
+class scrap_styles(aetools.ComponentItem):
+    """scrap styles -  """
+    want = 'styl'
+
+class type_suite_info(aetools.ComponentItem):
+    """type suite info -  """
+    want = 'suin'
+
+class target_id(aetools.ComponentItem):
+    """target id -  """
+    want = 'targ'
+
+class dash_style(aetools.ComponentItem):
+    """dash style -  """
+    want = 'tdas'
+
+class pixel_map_record(aetools.ComponentItem):
+    """pixel map record -  """
+    want = 'tpmm'
+
+class RGB16_color(aetools.ComponentItem):
+    """RGB16 color -  """
+    want = 'tr16'
+
+class RGB96_color(aetools.ComponentItem):
+    """RGB96 color -  """
+    want = 'tr96'
+
+class rotation(aetools.ComponentItem):
+    """rotation -  """
+    want = 'trot'
+
+class version(aetools.ComponentItem):
+    """version -  """
+    want = 'vers'
+PostScript_picture._superclassnames = []
+PostScript_picture._privpropdict = {
+}
+PostScript_picture._privelemdict = {
+}
+point._superclassnames = []
+point._privpropdict = {
+}
+point._privelemdict = {
+}
+string._superclassnames = []
+string._privpropdict = {
+}
+string._privelemdict = {
+}
+TIFF_picture._superclassnames = []
+TIFF_picture._privpropdict = {
+}
+TIFF_picture._privelemdict = {
+}
+application_dictionary._superclassnames = []
+application_dictionary._privpropdict = {
+}
+application_dictionary._privelemdict = {
+}
+system_dictionary._superclassnames = []
+system_dictionary._privpropdict = {
+}
+system_dictionary._privelemdict = {
+}
+color_table._superclassnames = []
+color_table._privpropdict = {
+}
+color_table._privelemdict = {
+}
+menu_item._superclassnames = []
+menu_item._privpropdict = {
+}
+menu_item._privelemdict = {
+}
+menu._superclassnames = []
+menu._privpropdict = {
+}
+menu._privelemdict = {
+}
+double_integer._superclassnames = []
+double_integer._privpropdict = {
+}
+double_integer._privelemdict = {
+}
+type_element_info._superclassnames = []
+type_element_info._privpropdict = {
+}
+type_element_info._privelemdict = {
+}
+type_event_info._superclassnames = []
+type_event_info._privpropdict = {
+}
+type_event_info._privelemdict = {
+}
+extended_real._superclassnames = []
+extended_real._privpropdict = {
+}
+extended_real._privelemdict = {
+}
+fixed._superclassnames = []
+fixed._privpropdict = {
+}
+fixed._privelemdict = {
+}
+fixed_point._superclassnames = []
+fixed_point._privpropdict = {
+}
+fixed_point._privelemdict = {
+}
+fixed_rectangle._superclassnames = []
+fixed_rectangle._privpropdict = {
+}
+fixed_rectangle._privelemdict = {
+}
+type_class_info._superclassnames = []
+type_class_info._privpropdict = {
+}
+type_class_info._privelemdict = {
+}
+location_reference._superclassnames = []
+location_reference._privpropdict = {
+}
+location_reference._privelemdict = {
+}
+long_fixed_point._superclassnames = []
+long_fixed_point._privpropdict = {
+}
+long_fixed_point._privelemdict = {
+}
+long_fixed_rectangle._superclassnames = []
+long_fixed_rectangle._privpropdict = {
+}
+long_fixed_rectangle._privelemdict = {
+}
+long_fixed._superclassnames = []
+long_fixed._privpropdict = {
+}
+long_fixed._privelemdict = {
+}
+long_point._superclassnames = []
+long_point._privpropdict = {
+}
+long_point._privelemdict = {
+}
+long_rectangle._superclassnames = []
+long_rectangle._privpropdict = {
+}
+long_rectangle._privelemdict = {
+}
+machine_location._superclassnames = []
+machine_location._privpropdict = {
+}
+machine_location._privelemdict = {
+}
+unsigned_integer._superclassnames = []
+unsigned_integer._privpropdict = {
+}
+unsigned_integer._privelemdict = {
+}
+null._superclassnames = []
+null._privpropdict = {
+}
+null._privelemdict = {
+}
+type_property_info._superclassnames = []
+type_property_info._privpropdict = {
+}
+type_property_info._privelemdict = {
+}
+type_parameter_info._superclassnames = []
+type_parameter_info._privpropdict = {
+}
+type_parameter_info._privelemdict = {
+}
+bounding_rectangle._superclassnames = []
+bounding_rectangle._privpropdict = {
+}
+bounding_rectangle._privelemdict = {
+}
+small_integer._superclassnames = []
+small_integer._privpropdict = {
+}
+small_integer._privelemdict = {
+}
+small_real._superclassnames = []
+small_real._privpropdict = {
+}
+small_real._privelemdict = {
+}
+scrap_styles._superclassnames = []
+scrap_styles._privpropdict = {
+}
+scrap_styles._privelemdict = {
+}
+type_suite_info._superclassnames = []
+type_suite_info._privpropdict = {
+}
+type_suite_info._privelemdict = {
+}
+target_id._superclassnames = []
+target_id._privpropdict = {
+}
+target_id._privelemdict = {
+}
+dash_style._superclassnames = []
+dash_style._privpropdict = {
+}
+dash_style._privelemdict = {
+}
+pixel_map_record._superclassnames = []
+pixel_map_record._privpropdict = {
+}
+pixel_map_record._privelemdict = {
+}
+RGB16_color._superclassnames = []
+RGB16_color._privpropdict = {
+}
+RGB16_color._privelemdict = {
+}
+RGB96_color._superclassnames = []
+RGB96_color._privpropdict = {
+}
+RGB96_color._privelemdict = {
+}
+rotation._superclassnames = []
+rotation._privpropdict = {
+}
+rotation._privelemdict = {
+}
+version._superclassnames = []
+version._privpropdict = {
+}
+version._privelemdict = {
+}
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+    'EPS ' : PostScript_picture,
+    'QDpt' : point,
+    'TEXT' : string,
+    'TIFF' : TIFF_picture,
+    'aete' : application_dictionary,
+    'aeut' : system_dictionary,
+    'clrt' : color_table,
+    'cmen' : menu_item,
+    'cmnu' : menu,
+    'comp' : double_integer,
+    'elin' : type_element_info,
+    'evin' : type_event_info,
+    'exte' : extended_real,
+    'fixd' : fixed,
+    'fpnt' : fixed_point,
+    'frct' : fixed_rectangle,
+    'gcli' : type_class_info,
+    'insl' : location_reference,
+    'lfpt' : long_fixed_point,
+    'lfrc' : long_fixed_rectangle,
+    'lfxd' : long_fixed,
+    'lpnt' : long_point,
+    'lrct' : long_rectangle,
+    'mLoc' : machine_location,
+    'magn' : unsigned_integer,
+    'null' : null,
+    'pinf' : type_property_info,
+    'pmin' : type_parameter_info,
+    'qdrt' : bounding_rectangle,
+    'shor' : small_integer,
+    'sing' : small_real,
+    'styl' : scrap_styles,
+    'suin' : type_suite_info,
+    'targ' : target_id,
+    'tdas' : dash_style,
+    'tpmm' : pixel_map_record,
+    'tr16' : RGB16_color,
+    'tr96' : RGB96_color,
+    'trot' : rotation,
+    'vers' : version,
+}
+
+_propdeclarations = {
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+}

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/StdSuites/__init__.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/StdSuites/__init__.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/StdSuites/__init__.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,471 @@
+"""
+Package generated from /Volumes/Sap/System Folder/Extensions/AppleScript
+Resource aeut resid 0 Standard Event Suites for English
+"""
+import aetools
+Error = aetools.Error
+import Text_Suite
+import AppleScript_Suite
+import Standard_Suite
+import Macintosh_Connectivity_Clas
+import QuickDraw_Graphics_Suite
+import QuickDraw_Graphics_Suppleme
+import Required_Suite
+import Table_Suite
+import Type_Names_Suite
+
+
+_code_to_module = {
+    'TEXT' : Text_Suite,
+    'ascr' : AppleScript_Suite,
+    'core' : Standard_Suite,
+    'macc' : Macintosh_Connectivity_Clas,
+    'qdrw' : QuickDraw_Graphics_Suite,
+    'qdsp' : QuickDraw_Graphics_Suppleme,
+    'reqd' : Required_Suite,
+    'tbls' : Table_Suite,
+    'tpnm' : Type_Names_Suite,
+}
+
+
+
+_code_to_fullname = {
+    'TEXT' : ('StdSuites.Text_Suite', 'Text_Suite'),
+    'ascr' : ('StdSuites.AppleScript_Suite', 'AppleScript_Suite'),
+    'core' : ('StdSuites.Standard_Suite', 'Standard_Suite'),
+    'macc' : ('StdSuites.Macintosh_Connectivity_Clas', 'Macintosh_Connectivity_Clas'),
+    'qdrw' : ('StdSuites.QuickDraw_Graphics_Suite', 'QuickDraw_Graphics_Suite'),
+    'qdsp' : ('StdSuites.QuickDraw_Graphics_Suppleme', 'QuickDraw_Graphics_Suppleme'),
+    'reqd' : ('StdSuites.Required_Suite', 'Required_Suite'),
+    'tbls' : ('StdSuites.Table_Suite', 'Table_Suite'),
+    'tpnm' : ('StdSuites.Type_Names_Suite', 'Type_Names_Suite'),
+}
+
+from Text_Suite import *
+from AppleScript_Suite import *
+from Standard_Suite import *
+from Macintosh_Connectivity_Clas import *
+from QuickDraw_Graphics_Suite import *
+from QuickDraw_Graphics_Suppleme import *
+from Required_Suite import *
+from Table_Suite import *
+from Type_Names_Suite import *
+
+def getbaseclasses(v):
+    if not getattr(v, '_propdict', None):
+        v._propdict = {}
+        v._elemdict = {}
+        for superclassname in getattr(v, '_superclassnames', []):
+            superclass = eval(superclassname)
+            getbaseclasses(superclass)
+            v._propdict.update(getattr(superclass, '_propdict', {}))
+            v._elemdict.update(getattr(superclass, '_elemdict', {}))
+        v._propdict.update(getattr(v, '_privpropdict', {}))
+        v._elemdict.update(getattr(v, '_privelemdict', {}))
+
+import StdSuites
+
+#
+# Set property and element dictionaries now that all classes have been defined
+#
+getbaseclasses(graphic_group)
+getbaseclasses(oval)
+getbaseclasses(graphic_text)
+getbaseclasses(graphic_shape)
+getbaseclasses(drawing_area)
+getbaseclasses(graphic_line)
+getbaseclasses(polygon)
+getbaseclasses(pixel)
+getbaseclasses(rounded_rectangle)
+getbaseclasses(graphic_object)
+getbaseclasses(arc)
+getbaseclasses(pixel_map)
+getbaseclasses(rectangle)
+getbaseclasses(selection_2d_object)
+getbaseclasses(application)
+getbaseclasses(document)
+getbaseclasses(window)
+getbaseclasses(file)
+getbaseclasses(alias)
+getbaseclasses(insertion_point)
+getbaseclasses(character)
+getbaseclasses(paragraph)
+getbaseclasses(word)
+getbaseclasses(text_flow)
+getbaseclasses(text_style_info)
+getbaseclasses(line)
+getbaseclasses(text)
+getbaseclasses(AppleTalk_address)
+getbaseclasses(address_specification)
+getbaseclasses(Token_Ring_address)
+getbaseclasses(FireWire_address)
+getbaseclasses(bus_slot)
+getbaseclasses(SCSI_address)
+getbaseclasses(ADB_address)
+getbaseclasses(USB_address)
+getbaseclasses(device_specification)
+getbaseclasses(LocalTalk_address)
+getbaseclasses(IP_address)
+getbaseclasses(Ethernet_address)
+getbaseclasses(graphic_group)
+getbaseclasses(drawing_area)
+getbaseclasses(cell)
+getbaseclasses(column)
+getbaseclasses(table)
+getbaseclasses(row)
+getbaseclasses(small_integer)
+getbaseclasses(system_dictionary)
+getbaseclasses(color_table)
+getbaseclasses(fixed_point)
+getbaseclasses(plain_text)
+getbaseclasses(type_element_info)
+getbaseclasses(machine_location)
+getbaseclasses(PostScript_picture)
+getbaseclasses(type_suite_info)
+getbaseclasses(menu_item)
+getbaseclasses(pixel_map_record)
+getbaseclasses(small_real)
+getbaseclasses(null)
+getbaseclasses(rotation)
+getbaseclasses(fixed)
+getbaseclasses(long_point)
+getbaseclasses(target_id)
+getbaseclasses(type_property_info)
+getbaseclasses(type_parameter_info)
+getbaseclasses(long_fixed_point)
+getbaseclasses(bounding_rectangle)
+getbaseclasses(TIFF_picture)
+getbaseclasses(long_fixed)
+getbaseclasses(location_reference)
+getbaseclasses(version)
+getbaseclasses(RGB16_color)
+getbaseclasses(double_integer)
+getbaseclasses(type_event_info)
+getbaseclasses(point)
+getbaseclasses(application_dictionary)
+getbaseclasses(unsigned_integer)
+getbaseclasses(menu)
+getbaseclasses(fixed_rectangle)
+getbaseclasses(long_fixed_rectangle)
+getbaseclasses(type_class_info)
+getbaseclasses(RGB96_color)
+getbaseclasses(dash_style)
+getbaseclasses(scrap_styles)
+getbaseclasses(extended_real)
+getbaseclasses(long_rectangle)
+getbaseclasses(May)
+getbaseclasses(string)
+getbaseclasses(miles)
+getbaseclasses(number_or_date)
+getbaseclasses(October)
+getbaseclasses(event)
+getbaseclasses(Pascal_string)
+getbaseclasses(zone)
+getbaseclasses(picture)
+getbaseclasses(list_or_string)
+getbaseclasses(number)
+getbaseclasses(Tuesday)
+getbaseclasses(version)
+getbaseclasses(December)
+getbaseclasses(square_kilometres)
+getbaseclasses(reference)
+getbaseclasses(vector)
+getbaseclasses(weekday)
+getbaseclasses(Sunday)
+getbaseclasses(international_text)
+getbaseclasses(seconds)
+getbaseclasses(RGB_color)
+getbaseclasses(kilometres)
+getbaseclasses(styled_Unicode_text)
+getbaseclasses(missing_value)
+getbaseclasses(metres)
+getbaseclasses(number_or_string)
+getbaseclasses(list)
+getbaseclasses(linked_list)
+getbaseclasses(real)
+getbaseclasses(encoded_string)
+getbaseclasses(list_or_record)
+getbaseclasses(Monday)
+getbaseclasses(September)
+getbaseclasses(anything)
+getbaseclasses(property)
+getbaseclasses(reference_form)
+getbaseclasses(item)
+getbaseclasses(grams)
+getbaseclasses(record)
+getbaseclasses(empty_ae_name_)
+getbaseclasses(constant)
+getbaseclasses(square_miles)
+getbaseclasses(data)
+getbaseclasses(Unicode_text)
+getbaseclasses(yards)
+getbaseclasses(cubic_yards)
+getbaseclasses(pounds)
+getbaseclasses(cubic_centimetres)
+getbaseclasses(text)
+getbaseclasses(July)
+getbaseclasses(cubic_metres)
+getbaseclasses(styled_text)
+getbaseclasses(number_2c__date_or_text)
+getbaseclasses(feet)
+getbaseclasses(February)
+getbaseclasses(degrees_Celsius)
+getbaseclasses(keystroke)
+getbaseclasses(integer)
+getbaseclasses(degrees_Fahrenheit)
+getbaseclasses(list_2c__record_or_text)
+getbaseclasses(date)
+getbaseclasses(degrees_Kelvin)
+getbaseclasses(centimetres)
+getbaseclasses(writing_code)
+getbaseclasses(alias_or_string)
+getbaseclasses(writing_code_info)
+getbaseclasses(text_item)
+getbaseclasses(machine)
+getbaseclasses(type_class)
+getbaseclasses(preposition)
+getbaseclasses(Wednesday)
+getbaseclasses(upper_case)
+getbaseclasses(March)
+getbaseclasses(square_feet)
+getbaseclasses(November)
+getbaseclasses(quarts)
+getbaseclasses(alias)
+getbaseclasses(January)
+getbaseclasses(month)
+getbaseclasses(June)
+getbaseclasses(August)
+getbaseclasses(styled_Clipboard_text)
+getbaseclasses(gallons)
+getbaseclasses(cubic_inches)
+getbaseclasses(Friday)
+getbaseclasses(sound)
+getbaseclasses(class_)
+getbaseclasses(kilograms)
+getbaseclasses(script)
+getbaseclasses(litres)
+getbaseclasses(boolean)
+getbaseclasses(square_metres)
+getbaseclasses(inches)
+getbaseclasses(character)
+getbaseclasses(April)
+getbaseclasses(ounces)
+getbaseclasses(app)
+getbaseclasses(handler)
+getbaseclasses(C_string)
+getbaseclasses(Thursday)
+getbaseclasses(square_yards)
+getbaseclasses(cubic_feet)
+getbaseclasses(Saturday)
+getbaseclasses(file_specification)
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+    'cpic' : graphic_group,
+    'covl' : oval,
+    'cgtx' : graphic_text,
+    'cgsh' : graphic_shape,
+    'cdrw' : drawing_area,
+    'glin' : graphic_line,
+    'cpgn' : polygon,
+    'cpxl' : pixel,
+    'crrc' : rounded_rectangle,
+    'cgob' : graphic_object,
+    'carc' : arc,
+    'cpix' : pixel_map,
+    'crec' : rectangle,
+    'csel' : selection_2d_object,
+    'capp' : application,
+    'docu' : document,
+    'cwin' : window,
+    'file' : file,
+    'alis' : alias,
+    'cins' : insertion_point,
+    'cha ' : character,
+    'cpar' : paragraph,
+    'cwor' : word,
+    'cflo' : text_flow,
+    'tsty' : text_style_info,
+    'clin' : line,
+    'ctxt' : text,
+    'cat ' : AppleTalk_address,
+    'cadr' : address_specification,
+    'ctok' : Token_Ring_address,
+    'cfw ' : FireWire_address,
+    'cbus' : bus_slot,
+    'cscs' : SCSI_address,
+    'cadb' : ADB_address,
+    'cusb' : USB_address,
+    'cdev' : device_specification,
+    'clt ' : LocalTalk_address,
+    'cip ' : IP_address,
+    'cen ' : Ethernet_address,
+    'cpic' : graphic_group,
+    'cdrw' : drawing_area,
+    'ccel' : cell,
+    'ccol' : column,
+    'ctbl' : table,
+    'crow' : row,
+    'shor' : small_integer,
+    'aeut' : system_dictionary,
+    'clrt' : color_table,
+    'fpnt' : fixed_point,
+    'TEXT' : plain_text,
+    'elin' : type_element_info,
+    'mLoc' : machine_location,
+    'EPS ' : PostScript_picture,
+    'suin' : type_suite_info,
+    'cmen' : menu_item,
+    'tpmm' : pixel_map_record,
+    'sing' : small_real,
+    'null' : null,
+    'trot' : rotation,
+    'fixd' : fixed,
+    'lpnt' : long_point,
+    'targ' : target_id,
+    'pinf' : type_property_info,
+    'pmin' : type_parameter_info,
+    'lfpt' : long_fixed_point,
+    'qdrt' : bounding_rectangle,
+    'TIFF' : TIFF_picture,
+    'lfxd' : long_fixed,
+    'insl' : location_reference,
+    'vers' : version,
+    'tr16' : RGB16_color,
+    'comp' : double_integer,
+    'evin' : type_event_info,
+    'QDpt' : point,
+    'aete' : application_dictionary,
+    'magn' : unsigned_integer,
+    'cmnu' : menu,
+    'frct' : fixed_rectangle,
+    'lfrc' : long_fixed_rectangle,
+    'gcli' : type_class_info,
+    'tr96' : RGB96_color,
+    'tdas' : dash_style,
+    'styl' : scrap_styles,
+    'exte' : extended_real,
+    'lrct' : long_rectangle,
+    'may ' : May,
+    'TEXT' : string,
+    'mile' : miles,
+    'nd  ' : number_or_date,
+    'oct ' : October,
+    'evnt' : event,
+    'pstr' : Pascal_string,
+    'zone' : zone,
+    'PICT' : picture,
+    'ls  ' : list_or_string,
+    'nmbr' : number,
+    'tue ' : Tuesday,
+    'vers' : version,
+    'dec ' : December,
+    'sqkm' : square_kilometres,
+    'obj ' : reference,
+    'vect' : vector,
+    'wkdy' : weekday,
+    'sun ' : Sunday,
+    'itxt' : international_text,
+    'scnd' : seconds,
+    'cRGB' : RGB_color,
+    'kmtr' : kilometres,
+    'sutx' : styled_Unicode_text,
+    'msng' : missing_value,
+    'metr' : metres,
+    'ns  ' : number_or_string,
+    'list' : list,
+    'llst' : linked_list,
+    'doub' : real,
+    'encs' : encoded_string,
+    'lr  ' : list_or_record,
+    'mon ' : Monday,
+    'sep ' : September,
+    '****' : anything,
+    'prop' : property,
+    'kfrm' : reference_form,
+    'cobj' : item,
+    'gram' : grams,
+    'reco' : record,
+    'undf' : empty_ae_name_,
+    'enum' : constant,
+    'sqmi' : square_miles,
+    'rdat' : data,
+    'utxt' : Unicode_text,
+    'yard' : yards,
+    'cyrd' : cubic_yards,
+    'lbs ' : pounds,
+    'ccmt' : cubic_centimetres,
+    'ctxt' : text,
+    'jul ' : July,
+    'cmet' : cubic_metres,
+    'STXT' : styled_text,
+    'nds ' : number_2c__date_or_text,
+    'feet' : feet,
+    'feb ' : February,
+    'degc' : degrees_Celsius,
+    'kprs' : keystroke,
+    'long' : integer,
+    'degf' : degrees_Fahrenheit,
+    'lrs ' : list_2c__record_or_text,
+    'ldt ' : date,
+    'degk' : degrees_Kelvin,
+    'cmtr' : centimetres,
+    'psct' : writing_code,
+    'sf  ' : alias_or_string,
+    'citl' : writing_code_info,
+    'citm' : text_item,
+    'mach' : machine,
+    'type' : type_class,
+    'prep' : preposition,
+    'wed ' : Wednesday,
+    'case' : upper_case,
+    'mar ' : March,
+    'sqft' : square_feet,
+    'nov ' : November,
+    'qrts' : quarts,
+    'alis' : alias,
+    'jan ' : January,
+    'mnth' : month,
+    'jun ' : June,
+    'aug ' : August,
+    'styl' : styled_Clipboard_text,
+    'galn' : gallons,
+    'cuin' : cubic_inches,
+    'fri ' : Friday,
+    'snd ' : sound,
+    'pcls' : class_,
+    'kgrm' : kilograms,
+    'scpt' : script,
+    'litr' : litres,
+    'bool' : boolean,
+    'sqrm' : square_metres,
+    'inch' : inches,
+    'cha ' : character,
+    'apr ' : April,
+    'ozs ' : ounces,
+    'capp' : app,
+    'hand' : handler,
+    'cstr' : C_string,
+    'thu ' : Thursday,
+    'sqyd' : square_yards,
+    'cfet' : cubic_feet,
+    'sat ' : Saturday,
+    'fss ' : file_specification,
+}
+
+
+class StdSuites(Text_Suite_Events,
+        AppleScript_Suite_Events,
+        Standard_Suite_Events,
+        Macintosh_Connectivity_Clas_Events,
+        QuickDraw_Graphics_Suite_Events,
+        QuickDraw_Graphics_Suppleme_Events,
+        Required_Suite_Events,
+        Table_Suite_Events,
+        Type_Names_Suite_Events,
+        aetools.TalkTo):
+    _signature = 'ascr'
+
+    _moduleName = 'StdSuites'

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/SystemEvents/Disk_Folder_File_Suite.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/SystemEvents/Disk_Folder_File_Suite.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/SystemEvents/Disk_Folder_File_Suite.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,381 @@
+"""Suite Disk-Folder-File Suite: Terms and Events for controlling Disks, Folders, and Files
+Level 1, version 1
+
+Generated from /System/Library/CoreServices/System Events.app
+AETE/AEUT resource version 1/0, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'cdis'
+
+class Disk_Folder_File_Suite_Events:
+
+    _argmap_move = {
+        'to' : 'insh',
+    }
+
+    def move(self, _object, _attributes={}, **_arguments):
+        """move: Move disk item(s) to a new location.
+        Required argument: the object for the command
+        Keyword argument to: The new location for the disk item(s).
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: the reply for the command
+        """
+        _code = 'core'
+        _subcode = 'move'
+
+        aetools.keysubst(_arguments, self._argmap_move)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+
+class application(aetools.ComponentItem):
+    """application - The Disk-Folder-File Suite host program """
+    want = 'capp'
+class _Prop__3c_Inheritance_3e_(aetools.NProperty):
+    """<Inheritance> - All of the properties of the superclass. """
+    which = 'c@#^'
+    want = 'capp'
+_3c_Inheritance_3e_ = _Prop__3c_Inheritance_3e_()
+class _Prop_folder_actions_enabled(aetools.NProperty):
+    """folder actions enabled - Are Folder Actions currently being processed? """
+    which = 'faen'
+    want = 'bool'
+folder_actions_enabled = _Prop_folder_actions_enabled()
+class _Prop_properties(aetools.NProperty):
+    """properties - every property of the Disk-Folder-File Suite host program """
+    which = 'pALL'
+    want = '****'
+properties = _Prop_properties()
+#        element 'cdis' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'cfol' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'cobj' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'cwin' as ['name', 'indx', 'rele', 'rang', 'test', 'ID  ']
+#        element 'docu' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'file' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'foac' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'logi' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'pcap' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'pcda' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'prcs' as ['name', 'indx', 'rele', 'rang', 'test']
+
+applications = application
+
+class disk(aetools.ComponentItem):
+    """disk - A disk in the file system """
+    want = 'cdis'
+class _Prop_POSIX_path(aetools.NProperty):
+    """POSIX path - the POSIX file system path of the disk """
+    which = 'posx'
+    want = 'utxt'
+class _Prop_capacity(aetools.NProperty):
+    """capacity - the total number of bytes (free or used) on the disk """
+    which = 'capa'
+    want = 'magn'
+class _Prop_ejectable(aetools.NProperty):
+    """ejectable - Can the media be ejected (floppies, CD's, and so on)? """
+    which = 'isej'
+    want = 'bool'
+class _Prop_format(aetools.NProperty):
+    """format - the file system format of this disk """
+    which = 'dfmt'
+    want = 'edfm'
+class _Prop_free_space(aetools.NProperty):
+    """free space - the number of free bytes left on the disk """
+    which = 'frsp'
+    want = 'magn'
+class _Prop_ignore_privileges(aetools.NProperty):
+    """ignore privileges - Ignore permissions on this disk? """
+    which = 'igpr'
+    want = 'bool'
+class _Prop_local_volume(aetools.NProperty):
+    """local volume - Is the media a local volume (as opposed to a file server? """
+    which = 'isrv'
+    want = 'bool'
+class _Prop_name(aetools.NProperty):
+    """name - the name of the disk """
+    which = 'pnam'
+    want = 'utxt'
+class _Prop_path(aetools.NProperty):
+    """path - the file system path of the disk """
+    which = 'ppth'
+    want = 'utxt'
+class _Prop_startup(aetools.NProperty):
+    """startup - Is this disk the boot disk? """
+    which = 'istd'
+    want = 'bool'
+class _Prop_volume(aetools.NProperty):
+    """volume - the volume on which the folder resides """
+    which = 'volu'
+    want = 'utxt'
+#        element 'cfol' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'cobj' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'file' as ['name', 'indx', 'rele', 'rang', 'test']
+
+disks = disk
+
+class folder(aetools.ComponentItem):
+    """folder - A folder in the file system """
+    want = 'cfol'
+#        element 'cfol' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'cfol' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'cobj' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'cobj' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'file' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'file' as ['name', 'indx', 'rele', 'rang', 'test']
+
+folders = folder
+
+class item(aetools.ComponentItem):
+    """item - An item in the file system """
+    want = 'cobj'
+class _Prop_busy_status(aetools.NProperty):
+    """busy status - Is the item busy? """
+    which = 'busy'
+    want = 'bool'
+class _Prop_creation_date(aetools.NProperty):
+    """creation date - the date on which the item was created """
+    which = 'ascd'
+    want = '****'
+class _Prop_modification_date(aetools.NProperty):
+    """modification date - the date on which the item was last modified """
+    which = 'asmo'
+    want = '****'
+class _Prop_name_extension(aetools.NProperty):
+    """name extension - the extension portion of the name """
+    which = 'extn'
+    want = 'utxt'
+class _Prop_package_folder(aetools.NProperty):
+    """package folder - Is the item a package? """
+    which = 'pkgf'
+    want = 'bool'
+class _Prop_url(aetools.NProperty):
+    """url - the url of the item """
+    which = 'url '
+    want = 'utxt'
+class _Prop_visible(aetools.NProperty):
+    """visible - Is the item visible? """
+    which = 'visi'
+    want = 'bool'
+#        element 'cfol' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'cobj' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'file' as ['name', 'indx', 'rele', 'rang', 'test']
+
+items = item
+
+class file(aetools.ComponentItem):
+    """file - A file in the file system """
+    want = 'file'
+class _Prop_creator_type(aetools.NProperty):
+    """creator type - the OSType identifying the application that created the item """
+    which = 'fcrt'
+    want = 'utxt'
+class _Prop_file_type(aetools.NProperty):
+    """file type - the OSType identifying the type of data contained in the item """
+    which = 'asty'
+    want = 'utxt'
+class _Prop_physical_size(aetools.NProperty):
+    """physical size - the actual space used by the file on disk """
+    which = 'phys'
+    want = 'magn'
+class _Prop_product_version(aetools.NProperty):
+    """product version - the version of the product (visible at the top of the ?et Info?window) """
+    which = 'ver2'
+    want = 'utxt'
+class _Prop_size(aetools.NProperty):
+    """size - the logical size of the file """
+    which = 'ptsz'
+    want = 'magn'
+class _Prop_stationery(aetools.NProperty):
+    """stationery - Is the file a stationery pad? """
+    which = 'pspd'
+    want = 'bool'
+class _Prop_version(aetools.NProperty):
+    """version - the version of the file (visible at the bottom of the ?et Info?window) """
+    which = 'vers'
+    want = 'utxt'
+#        element 'cfol' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'cobj' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'file' as ['name', 'indx', 'rele', 'rang', 'test']
+
+files = file
+application._superclassnames = []
+import Standard_Suite
+import Folder_Actions_Suite
+import Login_Items_Suite
+import Processes_Suite
+application._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+    'folder_actions_enabled' : _Prop_folder_actions_enabled,
+    'properties' : _Prop_properties,
+}
+application._privelemdict = {
+    'application_process' : Processes_Suite.application_process,
+    'desk_accessory_process' : Processes_Suite.desk_accessory_process,
+    'disk' : disk,
+    'document' : Standard_Suite.document,
+    'file' : file,
+    'folder' : folder,
+    'folder_action' : Folder_Actions_Suite.folder_action,
+    'item' : item,
+    'login_item' : Login_Items_Suite.login_item,
+    'process' : Processes_Suite.process,
+    'window' : Standard_Suite.window,
+}
+disk._superclassnames = ['item']
+disk._privpropdict = {
+    'POSIX_path' : _Prop_POSIX_path,
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+    'capacity' : _Prop_capacity,
+    'ejectable' : _Prop_ejectable,
+    'format' : _Prop_format,
+    'free_space' : _Prop_free_space,
+    'ignore_privileges' : _Prop_ignore_privileges,
+    'local_volume' : _Prop_local_volume,
+    'name' : _Prop_name,
+    'path' : _Prop_path,
+    'properties' : _Prop_properties,
+    'startup' : _Prop_startup,
+    'volume' : _Prop_volume,
+}
+disk._privelemdict = {
+    'file' : file,
+    'folder' : folder,
+    'item' : item,
+}
+folder._superclassnames = ['item']
+folder._privpropdict = {
+    'POSIX_path' : _Prop_POSIX_path,
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+    'name' : _Prop_name,
+    'path' : _Prop_path,
+    'properties' : _Prop_properties,
+    'volume' : _Prop_volume,
+}
+folder._privelemdict = {
+    'file' : file,
+    'file' : file,
+    'folder' : folder,
+    'folder' : folder,
+    'item' : item,
+    'item' : item,
+}
+item._superclassnames = []
+item._privpropdict = {
+    'POSIX_path' : _Prop_POSIX_path,
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+    'busy_status' : _Prop_busy_status,
+    'creation_date' : _Prop_creation_date,
+    'modification_date' : _Prop_modification_date,
+    'name' : _Prop_name,
+    'name_extension' : _Prop_name_extension,
+    'package_folder' : _Prop_package_folder,
+    'path' : _Prop_path,
+    'properties' : _Prop_properties,
+    'url' : _Prop_url,
+    'visible' : _Prop_visible,
+    'volume' : _Prop_volume,
+}
+item._privelemdict = {
+    'file' : file,
+    'folder' : folder,
+    'item' : item,
+}
+file._superclassnames = ['item']
+file._privpropdict = {
+    'POSIX_path' : _Prop_POSIX_path,
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+    'creator_type' : _Prop_creator_type,
+    'file_type' : _Prop_file_type,
+    'name' : _Prop_name,
+    'path' : _Prop_path,
+    'physical_size' : _Prop_physical_size,
+    'product_version' : _Prop_product_version,
+    'properties' : _Prop_properties,
+    'size' : _Prop_size,
+    'stationery' : _Prop_stationery,
+    'version' : _Prop_version,
+    'volume' : _Prop_volume,
+}
+file._privelemdict = {
+    'file' : file,
+    'folder' : folder,
+    'item' : item,
+}
+_Enum_edfm = {
+    'MS_2d_DOS_format' : 'dfms',        # MS-DOS format
+    'Apple_Photo_format' : 'dfph',      # Apple Photo format
+    'ISO_9660_format' : 'df96', # ISO 9660 format
+    'QuickTake_format' : 'dfqt',        # QuickTake format
+    'AppleShare_format' : 'dfas',       # AppleShare format
+    'High_Sierra_format' : 'dfhs',      # High Sierra format
+    'Mac_OS_Extended_format' : 'dfh+',  # Mac OS Extended format
+    'UDF_format' : 'dfud',      # UDF format
+    'unknown_format' : 'df??',  # unknown format
+    'audio_format' : 'dfau',    # audio format
+    'Mac_OS_format' : 'dfhf',   # Mac OS format
+    'UFS_format' : 'dfuf',      # UFS format
+    'NFS_format' : 'dfnf',      # NFS format
+    'ProDOS_format' : 'dfpr',   # ProDOS format
+    'WebDAV_format' : 'dfwd',   # WebDAV format
+}
+
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+    'capp' : application,
+    'cdis' : disk,
+    'cfol' : folder,
+    'cobj' : item,
+    'file' : file,
+}
+
+_propdeclarations = {
+    'ascd' : _Prop_creation_date,
+    'asmo' : _Prop_modification_date,
+    'asty' : _Prop_file_type,
+    'busy' : _Prop_busy_status,
+    'c@#^' : _Prop__3c_Inheritance_3e_,
+    'capa' : _Prop_capacity,
+    'dfmt' : _Prop_format,
+    'extn' : _Prop_name_extension,
+    'faen' : _Prop_folder_actions_enabled,
+    'fcrt' : _Prop_creator_type,
+    'frsp' : _Prop_free_space,
+    'igpr' : _Prop_ignore_privileges,
+    'isej' : _Prop_ejectable,
+    'isrv' : _Prop_local_volume,
+    'istd' : _Prop_startup,
+    'pALL' : _Prop_properties,
+    'phys' : _Prop_physical_size,
+    'pkgf' : _Prop_package_folder,
+    'pnam' : _Prop_name,
+    'posx' : _Prop_POSIX_path,
+    'ppth' : _Prop_path,
+    'pspd' : _Prop_stationery,
+    'ptsz' : _Prop_size,
+    'url ' : _Prop_url,
+    'ver2' : _Prop_product_version,
+    'vers' : _Prop_version,
+    'visi' : _Prop_visible,
+    'volu' : _Prop_volume,
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+    'edfm' : _Enum_edfm,
+}

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/SystemEvents/Folder_Actions_Suite.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/SystemEvents/Folder_Actions_Suite.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/SystemEvents/Folder_Actions_Suite.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,287 @@
+"""Suite Folder Actions Suite: Terms and Events for controlling Folder Actions
+Level 1, version 1
+
+Generated from /System/Library/CoreServices/System Events.app
+AETE/AEUT resource version 1/0, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'faco'
+
+class Folder_Actions_Suite_Events:
+
+    _argmap_attach_action_to = {
+        'using' : 'faal',
+    }
+
+    def attach_action_to(self, _object, _attributes={}, **_arguments):
+        """attach action to: Attach an action to a folder
+        Required argument: the object for the command
+        Keyword argument using: a file containing the script to attach
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: the reply for the command
+        """
+        _code = 'faco'
+        _subcode = 'atfa'
+
+        aetools.keysubst(_arguments, self._argmap_attach_action_to)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def attached_scripts(self, _object, _attributes={}, **_arguments):
+        """attached scripts: List the actions attached to a folder
+        Required argument: the object for the command
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: the reply for the command
+        """
+        _code = 'faco'
+        _subcode = 'lact'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_do_folder_action = {
+        'with_window_size' : 'fnsz',
+        'with_item_list' : 'flst',
+        'folder_action_code' : 'actn',
+    }
+
+    def do_folder_action(self, _object, _attributes={}, **_arguments):
+        """do folder action: Event the Finder sends to the Folder Actions FBA
+        Required argument: the object for the command
+        Keyword argument with_window_size: the new window size for the folder action message to process
+        Keyword argument with_item_list: a list of items for the folder action message to process
+        Keyword argument folder_action_code: the folder action message to process
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: the reply for the command
+        """
+        _code = 'faco'
+        _subcode = 'fola'
+
+        aetools.keysubst(_arguments, self._argmap_do_folder_action)
+        _arguments['----'] = _object
+
+        aetools.enumsubst(_arguments, 'actn', _Enum_actn)
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_edit_action_of = {
+        'using_action_name' : 'snam',
+        'using_action_number' : 'indx',
+    }
+
+    def edit_action_of(self, _object, _attributes={}, **_arguments):
+        """edit action of: Edit as action of a folder
+        Required argument: the object for the command
+        Keyword argument using_action_name: ...or the name of the action to edit
+        Keyword argument using_action_number: the index number of the action to edit...
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: the reply for the command
+        """
+        _code = 'faco'
+        _subcode = 'edfa'
+
+        aetools.keysubst(_arguments, self._argmap_edit_action_of)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_remove_action_from = {
+        'using_action_name' : 'snam',
+        'using_action_number' : 'indx',
+    }
+
+    def remove_action_from(self, _object, _attributes={}, **_arguments):
+        """remove action from: Remove a folder action from a folder
+        Required argument: the object for the command
+        Keyword argument using_action_name: ...or the name of the action to remove
+        Keyword argument using_action_number: the index number of the action to remove...
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: the reply for the command
+        """
+        _code = 'faco'
+        _subcode = 'rmfa'
+
+        aetools.keysubst(_arguments, self._argmap_remove_action_from)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+
+class application(aetools.ComponentItem):
+    """application - The Folder Actions Suite host program """
+    want = 'capp'
+class _Prop__3c_Inheritance_3e_(aetools.NProperty):
+    """<Inheritance> - All of the properties of the superclass. """
+    which = 'c@#^'
+    want = 'capp'
+_3c_Inheritance_3e_ = _Prop__3c_Inheritance_3e_()
+class _Prop_folder_actions_enabled(aetools.NProperty):
+    """folder actions enabled - Are Folder Actions currently being processed? """
+    which = 'faen'
+    want = 'bool'
+folder_actions_enabled = _Prop_folder_actions_enabled()
+class _Prop_properties(aetools.NProperty):
+    """properties - every property of the Folder Actions Suite host program """
+    which = 'pALL'
+    want = '****'
+properties = _Prop_properties()
+#        element 'cdis' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'cfol' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'cobj' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'cwin' as ['name', 'indx', 'rele', 'rang', 'test', 'ID  ']
+#        element 'docu' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'file' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'foac' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'logi' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'pcap' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'pcda' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'prcs' as ['name', 'indx', 'rele', 'rang', 'test']
+
+applications = application
+
+class folder_action(aetools.ComponentItem):
+    """folder action - An action attached to a folder in the file system """
+    want = 'foac'
+class _Prop_name(aetools.NProperty):
+    """name - the name of the folder action, which is also the name of the folder """
+    which = 'pnam'
+    want = 'utxt'
+class _Prop_path(aetools.NProperty):
+    """path - the path to the folder to which the folder action applies """
+    which = 'ppth'
+    want = '****'
+class _Prop_volume(aetools.NProperty):
+    """volume - the volume on which the folder action resides """
+    which = 'volu'
+    want = 'utxt'
+#        element 'scpt' as ['name', 'indx', 'rele', 'rang', 'test']
+
+folder_actions = folder_action
+
+class script(aetools.ComponentItem):
+    """script - A script invoked by a folder action """
+    want = 'scpt'
+class _Prop_POSIX_path(aetools.NProperty):
+    """POSIX path - the POSIX file system path of the disk """
+    which = 'posx'
+    want = 'utxt'
+
+scripts = script
+application._superclassnames = []
+import Disk_Folder_File_Suite
+import Standard_Suite
+import Login_Items_Suite
+import Processes_Suite
+application._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+    'folder_actions_enabled' : _Prop_folder_actions_enabled,
+    'properties' : _Prop_properties,
+}
+application._privelemdict = {
+    'application_process' : Processes_Suite.application_process,
+    'desk_accessory_process' : Processes_Suite.desk_accessory_process,
+    'disk' : Disk_Folder_File_Suite.disk,
+    'document' : Standard_Suite.document,
+    'file' : Disk_Folder_File_Suite.file,
+    'folder' : Disk_Folder_File_Suite.folder,
+    'folder_action' : folder_action,
+    'item' : Disk_Folder_File_Suite.item,
+    'login_item' : Login_Items_Suite.login_item,
+    'process' : Processes_Suite.process,
+    'window' : Standard_Suite.window,
+}
+folder_action._superclassnames = ['item']
+folder_action._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+    'name' : _Prop_name,
+    'path' : _Prop_path,
+    'properties' : _Prop_properties,
+    'volume' : _Prop_volume,
+}
+folder_action._privelemdict = {
+    'script' : script,
+}
+script._superclassnames = ['item']
+script._privpropdict = {
+    'POSIX_path' : _Prop_POSIX_path,
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+    'name' : _Prop_name,
+    'path' : _Prop_path,
+    'properties' : _Prop_properties,
+}
+script._privelemdict = {
+}
+_Enum_actn = {
+    'items_added' : 'fget',     # items added
+    'items_removed' : 'flos',   # items removed
+    'window_closed' : 'fclo',   # window closed
+    'window_moved' : 'fsiz',    # window moved
+    'window_opened' : 'fopn',   # window opened
+}
+
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+    'capp' : application,
+    'foac' : folder_action,
+    'scpt' : script,
+}
+
+_propdeclarations = {
+    'c@#^' : _Prop__3c_Inheritance_3e_,
+    'faen' : _Prop_folder_actions_enabled,
+    'pALL' : _Prop_properties,
+    'pnam' : _Prop_name,
+    'posx' : _Prop_POSIX_path,
+    'ppth' : _Prop_path,
+    'volu' : _Prop_volume,
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+    'actn' : _Enum_actn,
+}

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/SystemEvents/Hidden_Suite.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/SystemEvents/Hidden_Suite.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/SystemEvents/Hidden_Suite.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,50 @@
+"""Suite Hidden Suite: Hidden Terms and Events for controlling the System Events application
+Level 1, version 1
+
+Generated from /System/Library/CoreServices/System Events.app
+AETE/AEUT resource version 1/0, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'tpnm'
+
+from StdSuites.Type_Names_Suite import *
+class Hidden_Suite_Events(Type_Names_Suite_Events):
+
+    def do_script(self, _object, _attributes={}, **_arguments):
+        """do script: Execute an OSA script.
+        Required argument: the object for the command
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'misc'
+        _subcode = 'dosc'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+}
+
+_propdeclarations = {
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+}

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/SystemEvents/Login_Items_Suite.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/SystemEvents/Login_Items_Suite.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/SystemEvents/Login_Items_Suite.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,74 @@
+"""Suite Login Items Suite: Terms and Events for controlling the Login Items application
+Level 1, version 1
+
+Generated from /System/Library/CoreServices/System Events.app
+AETE/AEUT resource version 1/0, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'logi'
+
+class Login_Items_Suite_Events:
+
+    pass
+
+
+class login_item(aetools.ComponentItem):
+    """login item - an item to be launched or opened at login """
+    want = 'logi'
+class _Prop__3c_Inheritance_3e_(aetools.NProperty):
+    """<Inheritance> - All of the properties of the superclass. """
+    which = 'c@#^'
+    want = 'cobj'
+class _Prop_hidden(aetools.NProperty):
+    """hidden - Is the Login Item hidden when launched? """
+    which = 'hidn'
+    want = 'bool'
+class _Prop_kind(aetools.NProperty):
+    """kind - the file type of the Login Item """
+    which = 'kind'
+    want = 'utxt'
+class _Prop_name(aetools.NProperty):
+    """name - the name of the Login Item """
+    which = 'pnam'
+    want = 'utxt'
+class _Prop_path(aetools.NProperty):
+    """path - the file system path to the Login Item """
+    which = 'ppth'
+    want = 'utxt'
+
+login_items = login_item
+import Standard_Suite
+login_item._superclassnames = ['item']
+login_item._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+    'hidden' : _Prop_hidden,
+    'kind' : _Prop_kind,
+    'name' : _Prop_name,
+    'path' : _Prop_path,
+}
+login_item._privelemdict = {
+}
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+    'logi' : login_item,
+}
+
+_propdeclarations = {
+    'c@#^' : _Prop__3c_Inheritance_3e_,
+    'hidn' : _Prop_hidden,
+    'kind' : _Prop_kind,
+    'pnam' : _Prop_name,
+    'ppth' : _Prop_path,
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+}

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/SystemEvents/Power_Suite.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/SystemEvents/Power_Suite.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/SystemEvents/Power_Suite.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,149 @@
+"""Suite Power Suite: Terms and Events for controlling System power
+Level 1, version 1
+
+Generated from /System/Library/CoreServices/System Events.app
+AETE/AEUT resource version 1/0, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'powr'
+
+class Power_Suite_Events:
+
+    def restart(self, _object, _attributes={}, **_arguments):
+        """restart: Restart the computer
+        Required argument: the object for the command
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'fndr'
+        _subcode = 'rest'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def shut_down(self, _object, _attributes={}, **_arguments):
+        """shut down: Shut Down the computer
+        Required argument: the object for the command
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'fndr'
+        _subcode = 'shut'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def sleep(self, _object, _attributes={}, **_arguments):
+        """sleep: Put the computer to sleep
+        Required argument: the object for the command
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'fndr'
+        _subcode = 'slep'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+
+class application(aetools.ComponentItem):
+    """application - The System Events application """
+    want = 'capp'
+class _Prop__3c_Inheritance_3e_(aetools.NProperty):
+    """<Inheritance> - All of the properties of the superclass. """
+    which = 'c@#^'
+    want = 'capp'
+_3c_Inheritance_3e_ = _Prop__3c_Inheritance_3e_()
+class _Prop_folder_actions_enabled(aetools.NProperty):
+    """folder actions enabled - Are Folder Actions currently being processed? """
+    which = 'faen'
+    want = 'bool'
+folder_actions_enabled = _Prop_folder_actions_enabled()
+class _Prop_properties(aetools.NProperty):
+    """properties - every property of the System Events application """
+    which = 'pALL'
+    want = '****'
+properties = _Prop_properties()
+#        element 'cdis' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'cfol' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'cobj' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'cwin' as ['name', 'indx', 'rele', 'rang', 'test', 'ID  ']
+#        element 'docu' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'file' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'foac' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'logi' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'pcap' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'pcda' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'prcs' as ['name', 'indx', 'rele', 'rang', 'test']
+
+applications = application
+application._superclassnames = []
+import Disk_Folder_File_Suite
+import Standard_Suite
+import Folder_Actions_Suite
+import Login_Items_Suite
+import Processes_Suite
+application._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+    'folder_actions_enabled' : _Prop_folder_actions_enabled,
+    'properties' : _Prop_properties,
+}
+application._privelemdict = {
+    'application_process' : Processes_Suite.application_process,
+    'desk_accessory_process' : Processes_Suite.desk_accessory_process,
+    'disk' : Disk_Folder_File_Suite.disk,
+    'document' : Standard_Suite.document,
+    'file' : Disk_Folder_File_Suite.file,
+    'folder' : Disk_Folder_File_Suite.folder,
+    'folder_action' : Folder_Actions_Suite.folder_action,
+    'item' : Disk_Folder_File_Suite.item,
+    'login_item' : Login_Items_Suite.login_item,
+    'process' : Processes_Suite.process,
+    'window' : Standard_Suite.window,
+}
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+    'capp' : application,
+}
+
+_propdeclarations = {
+    'c@#^' : _Prop__3c_Inheritance_3e_,
+    'faen' : _Prop_folder_actions_enabled,
+    'pALL' : _Prop_properties,
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+}

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/SystemEvents/Processes_Suite.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/SystemEvents/Processes_Suite.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/SystemEvents/Processes_Suite.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,214 @@
+"""Suite Processes Suite: Terms and Events for controlling Processes
+Level 1, version 1
+
+Generated from /System/Library/CoreServices/System Events.app
+AETE/AEUT resource version 1/0, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'prcs'
+
+class Processes_Suite_Events:
+
+    pass
+
+
+class application(aetools.ComponentItem):
+    """application - The Processes Suite host program """
+    want = 'capp'
+class _Prop__3c_Inheritance_3e_(aetools.NProperty):
+    """<Inheritance> - All of the properties of the superclass. """
+    which = 'c@#^'
+    want = 'capp'
+_3c_Inheritance_3e_ = _Prop__3c_Inheritance_3e_()
+class _Prop_folder_actions_enabled(aetools.NProperty):
+    """folder actions enabled - Are Folder Actions currently being processed? """
+    which = 'faen'
+    want = 'bool'
+folder_actions_enabled = _Prop_folder_actions_enabled()
+class _Prop_properties(aetools.NProperty):
+    """properties - every property of the Processes Suite host program """
+    which = 'pALL'
+    want = '****'
+properties = _Prop_properties()
+#        element 'cdis' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'cfol' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'cobj' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'cwin' as ['name', 'indx', 'rele', 'rang', 'test', 'ID  ']
+#        element 'docu' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'file' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'foac' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'logi' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'pcap' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'pcda' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'prcs' as ['name', 'indx', 'rele', 'rang', 'test']
+
+applications = application
+
+class application_process(aetools.ComponentItem):
+    """application process - A process launched from an application file """
+    want = 'pcap'
+class _Prop_application_file(aetools.NProperty):
+    """application file - a reference to the application file from which this process was launched """
+    which = 'appf'
+    want = '****'
+
+application_processes = application_process
+
+class desk_accessory_process(aetools.ComponentItem):
+    """desk accessory process - A process launched from an desk accessory file """
+    want = 'pcda'
+class _Prop_desk_accessory_file(aetools.NProperty):
+    """desk accessory file - a reference to the desk accessory file from which this process was launched """
+    which = 'dafi'
+    want = '****'
+
+desk_accessory_processes = desk_accessory_process
+
+class process(aetools.ComponentItem):
+    """process - A process running on this computer """
+    want = 'prcs'
+class _Prop_accepts_high_level_events(aetools.NProperty):
+    """accepts high level events - Is the process high-level event aware (accepts open application, open document, print document, and quit)? """
+    which = 'isab'
+    want = 'bool'
+class _Prop_accepts_remote_events(aetools.NProperty):
+    """accepts remote events - Does the process accept remote events? """
+    which = 'revt'
+    want = 'bool'
+class _Prop_classic(aetools.NProperty):
+    """classic - Is the process running in the Classic environment? """
+    which = 'clsc'
+    want = 'bool'
+class _Prop_creator_type(aetools.NProperty):
+    """creator type - the OSType of the creator of the process (the signature) """
+    which = 'fcrt'
+    want = 'utxt'
+class _Prop_file(aetools.NProperty):
+    """file - the file from which the process was launched """
+    which = 'file'
+    want = '****'
+class _Prop_file_type(aetools.NProperty):
+    """file type - the OSType of the file type of the process """
+    which = 'asty'
+    want = 'utxt'
+class _Prop_frontmost(aetools.NProperty):
+    """frontmost - Is the process the frontmost process """
+    which = 'pisf'
+    want = 'bool'
+class _Prop_has_scripting_terminology(aetools.NProperty):
+    """has scripting terminology - Does the process have a scripting terminology, i.e., can it be scripted? """
+    which = 'hscr'
+    want = 'bool'
+class _Prop_name(aetools.NProperty):
+    """name - the name of the process """
+    which = 'pnam'
+    want = 'utxt'
+class _Prop_partition_space_used(aetools.NProperty):
+    """partition space used - the number of bytes currently used in the process' partition """
+    which = 'pusd'
+    want = 'magn'
+class _Prop_total_partition_size(aetools.NProperty):
+    """total partition size - the size of the partition with which the process was launched """
+    which = 'appt'
+    want = 'magn'
+class _Prop_visible(aetools.NProperty):
+    """visible - Is the process' layer visible? """
+    which = 'pvis'
+    want = 'bool'
+
+processes = process
+application._superclassnames = []
+import Disk_Folder_File_Suite
+import Standard_Suite
+import Folder_Actions_Suite
+import Login_Items_Suite
+application._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+    'folder_actions_enabled' : _Prop_folder_actions_enabled,
+    'properties' : _Prop_properties,
+}
+application._privelemdict = {
+    'application_process' : application_process,
+    'desk_accessory_process' : desk_accessory_process,
+    'disk' : Disk_Folder_File_Suite.disk,
+    'document' : Standard_Suite.document,
+    'file' : Disk_Folder_File_Suite.file,
+    'folder' : Disk_Folder_File_Suite.folder,
+    'folder_action' : Folder_Actions_Suite.folder_action,
+    'item' : Disk_Folder_File_Suite.item,
+    'login_item' : Login_Items_Suite.login_item,
+    'process' : process,
+    'window' : Standard_Suite.window,
+}
+application_process._superclassnames = ['process']
+application_process._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+    'application_file' : _Prop_application_file,
+}
+application_process._privelemdict = {
+}
+desk_accessory_process._superclassnames = ['process']
+desk_accessory_process._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+    'desk_accessory_file' : _Prop_desk_accessory_file,
+}
+desk_accessory_process._privelemdict = {
+}
+process._superclassnames = ['item']
+process._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+    'accepts_high_level_events' : _Prop_accepts_high_level_events,
+    'accepts_remote_events' : _Prop_accepts_remote_events,
+    'classic' : _Prop_classic,
+    'creator_type' : _Prop_creator_type,
+    'file' : _Prop_file,
+    'file_type' : _Prop_file_type,
+    'frontmost' : _Prop_frontmost,
+    'has_scripting_terminology' : _Prop_has_scripting_terminology,
+    'name' : _Prop_name,
+    'partition_space_used' : _Prop_partition_space_used,
+    'properties' : _Prop_properties,
+    'total_partition_size' : _Prop_total_partition_size,
+    'visible' : _Prop_visible,
+}
+process._privelemdict = {
+}
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+    'capp' : application,
+    'pcap' : application_process,
+    'pcda' : desk_accessory_process,
+    'prcs' : process,
+}
+
+_propdeclarations = {
+    'appf' : _Prop_application_file,
+    'appt' : _Prop_total_partition_size,
+    'asty' : _Prop_file_type,
+    'c@#^' : _Prop__3c_Inheritance_3e_,
+    'clsc' : _Prop_classic,
+    'dafi' : _Prop_desk_accessory_file,
+    'faen' : _Prop_folder_actions_enabled,
+    'fcrt' : _Prop_creator_type,
+    'file' : _Prop_file,
+    'hscr' : _Prop_has_scripting_terminology,
+    'isab' : _Prop_accepts_high_level_events,
+    'pALL' : _Prop_properties,
+    'pisf' : _Prop_frontmost,
+    'pnam' : _Prop_name,
+    'pusd' : _Prop_partition_space_used,
+    'pvis' : _Prop_visible,
+    'revt' : _Prop_accepts_remote_events,
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+}

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/SystemEvents/Standard_Suite.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/SystemEvents/Standard_Suite.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/SystemEvents/Standard_Suite.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,582 @@
+"""Suite Standard Suite: Common classes and commands for most applications.
+Level 1, version 1
+
+Generated from /System/Library/CoreServices/System Events.app
+AETE/AEUT resource version 1/0, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = '????'
+
+class Standard_Suite_Events:
+
+    _argmap_close = {
+        'saving_in' : 'kfil',
+        'saving' : 'savo',
+    }
+
+    def close(self, _object, _attributes={}, **_arguments):
+        """close: Close an object.
+        Required argument: the object for the command
+        Keyword argument saving_in: The file in which to save the object.
+        Keyword argument saving: Specifies whether changes should be saved before closing.
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'core'
+        _subcode = 'clos'
+
+        aetools.keysubst(_arguments, self._argmap_close)
+        _arguments['----'] = _object
+
+        aetools.enumsubst(_arguments, 'savo', _Enum_savo)
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_count = {
+        'each' : 'kocl',
+    }
+
+    def count(self, _object, _attributes={}, **_arguments):
+        """count: Return the number of elements of a particular class within an object.
+        Required argument: the object for the command
+        Keyword argument each: The class of objects to be counted.
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: the reply for the command
+        """
+        _code = 'core'
+        _subcode = 'cnte'
+
+        aetools.keysubst(_arguments, self._argmap_count)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def delete(self, _object, _attributes={}, **_arguments):
+        """delete: Delete an object.
+        Required argument: the object for the command
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'core'
+        _subcode = 'delo'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_duplicate = {
+        'to' : 'insh',
+        'with_properties' : 'prdt',
+    }
+
+    def duplicate(self, _object, _attributes={}, **_arguments):
+        """duplicate: Copy object(s) and put the copies at a new location.
+        Required argument: the object for the command
+        Keyword argument to: The location for the new object(s).
+        Keyword argument with_properties: Properties to be set in the new duplicated object(s).
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'core'
+        _subcode = 'clon'
+
+        aetools.keysubst(_arguments, self._argmap_duplicate)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def exists(self, _object, _attributes={}, **_arguments):
+        """exists: Verify if an object exists.
+        Required argument: the object for the command
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: the reply for the command
+        """
+        _code = 'core'
+        _subcode = 'doex'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def get(self, _object, _attributes={}, **_arguments):
+        """get: Get the data for an object.
+        Required argument: the object for the command
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: the reply for the command
+        """
+        _code = 'core'
+        _subcode = 'getd'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_make = {
+        'at' : 'insh',
+        'new' : 'kocl',
+        'with_data' : 'data',
+        'with_properties' : 'prdt',
+    }
+
+    def make(self, _no_object=None, _attributes={}, **_arguments):
+        """make: Make a new object.
+        Keyword argument at: The location at which to insert the object.
+        Keyword argument new: The class of the new object.
+        Keyword argument with_data: The initial data for the object.
+        Keyword argument with_properties: The initial values for properties of the object.
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: the reply for the command
+        """
+        _code = 'core'
+        _subcode = 'crel'
+
+        aetools.keysubst(_arguments, self._argmap_make)
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_move = {
+        'to' : 'insh',
+    }
+
+    def move(self, _object, _attributes={}, **_arguments):
+        """move: Move object(s) to a new location.
+        Required argument: the object for the command
+        Keyword argument to: The new location for the object(s).
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'core'
+        _subcode = 'move'
+
+        aetools.keysubst(_arguments, self._argmap_move)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def open(self, _object=None, _attributes={}, **_arguments):
+        """open: Open an object.
+        Required argument: list of objects
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'aevt'
+        _subcode = 'odoc'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def print_(self, _object=None, _attributes={}, **_arguments):
+        """print: Print an object.
+        Required argument: list of objects
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'aevt'
+        _subcode = 'pdoc'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_quit = {
+        'saving' : 'savo',
+    }
+
+    def quit(self, _object, _attributes={}, **_arguments):
+        """quit: Quit an application.
+        Required argument: the object for the command
+        Keyword argument saving: Specifies whether changes should be saved before quitting.
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'aevt'
+        _subcode = 'quit'
+
+        aetools.keysubst(_arguments, self._argmap_quit)
+        _arguments['----'] = _object
+
+        aetools.enumsubst(_arguments, 'savo', _Enum_savo)
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_save = {
+        'in_' : 'kfil',
+        'as' : 'fltp',
+    }
+
+    def save(self, _object, _attributes={}, **_arguments):
+        """save: Save an object.
+        Required argument: the object for the command
+        Keyword argument in_: The file in which to save the object.
+        Keyword argument as: The file type in which to save the data.
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'core'
+        _subcode = 'save'
+
+        aetools.keysubst(_arguments, self._argmap_save)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_set = {
+        'to' : 'data',
+    }
+
+    def set(self, _object, _attributes={}, **_arguments):
+        """set: Set an object's data.
+        Required argument: the object for the command
+        Keyword argument to: The new value.
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'core'
+        _subcode = 'setd'
+
+        aetools.keysubst(_arguments, self._argmap_set)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+
+class application(aetools.ComponentItem):
+    """application - An application's top level scripting object. """
+    want = 'capp'
+class _Prop__3c_Inheritance_3e_(aetools.NProperty):
+    """<Inheritance> - All of the properties of the superclass. """
+    which = 'c@#^'
+    want = 'cobj'
+_3c_Inheritance_3e_ = _Prop__3c_Inheritance_3e_()
+class _Prop_frontmost(aetools.NProperty):
+    """frontmost - Is this the frontmost (active) application? """
+    which = 'pisf'
+    want = 'bool'
+frontmost = _Prop_frontmost()
+class _Prop_name(aetools.NProperty):
+    """name - The name of the application. """
+    which = 'pnam'
+    want = 'utxt'
+name = _Prop_name()
+class _Prop_version(aetools.NProperty):
+    """version - The version of the application. """
+    which = 'vers'
+    want = 'utxt'
+version = _Prop_version()
+#        element 'cwin' as ['name', 'indx', 'rele', 'rang', 'test', 'ID  ']
+#        element 'docu' as ['name', 'indx', 'rele', 'rang', 'test']
+
+applications = application
+
+class item(aetools.ComponentItem):
+    """item - A scriptable object. """
+    want = 'cobj'
+class _Prop_class_(aetools.NProperty):
+    """class - The class of the object. """
+    which = 'pcls'
+    want = 'type'
+class _Prop_properties(aetools.NProperty):
+    """properties - All of the object's properties. """
+    which = 'pALL'
+    want = 'reco'
+
+items = item
+
+class color(aetools.ComponentItem):
+    """color - A color. """
+    want = 'colr'
+
+colors = color
+
+class window(aetools.ComponentItem):
+    """window - A window. """
+    want = 'cwin'
+class _Prop_bounds(aetools.NProperty):
+    """bounds - The bounding rectangle of the window. """
+    which = 'pbnd'
+    want = 'qdrt'
+class _Prop_closeable(aetools.NProperty):
+    """closeable - Whether the window has a close box. """
+    which = 'hclb'
+    want = 'bool'
+class _Prop_document(aetools.NProperty):
+    """document - The document whose contents are being displayed in the window. """
+    which = 'docu'
+    want = 'docu'
+class _Prop_floating(aetools.NProperty):
+    """floating - Whether the window floats. """
+    which = 'isfl'
+    want = 'bool'
+class _Prop_id(aetools.NProperty):
+    """id - The unique identifier of the window. """
+    which = 'ID  '
+    want = 'long'
+class _Prop_index(aetools.NProperty):
+    """index - The index of the window in the back-to-front window ordering. """
+    which = 'pidx'
+    want = 'long'
+class _Prop_miniaturizable(aetools.NProperty):
+    """miniaturizable - Whether the window can be miniaturized. """
+    which = 'ismn'
+    want = 'bool'
+class _Prop_miniaturized(aetools.NProperty):
+    """miniaturized - Whether the window is currently miniaturized. """
+    which = 'pmnd'
+    want = 'bool'
+class _Prop_modal(aetools.NProperty):
+    """modal - Whether the window is the application's current modal window. """
+    which = 'pmod'
+    want = 'bool'
+class _Prop_resizable(aetools.NProperty):
+    """resizable - Whether the window can be resized. """
+    which = 'prsz'
+    want = 'bool'
+class _Prop_titled(aetools.NProperty):
+    """titled - Whether the window has a title bar. """
+    which = 'ptit'
+    want = 'bool'
+class _Prop_visible(aetools.NProperty):
+    """visible - Whether the window is currently visible. """
+    which = 'pvis'
+    want = 'bool'
+class _Prop_zoomable(aetools.NProperty):
+    """zoomable - Whether the window can be zoomed. """
+    which = 'iszm'
+    want = 'bool'
+class _Prop_zoomed(aetools.NProperty):
+    """zoomed - Whether the window is currently zoomed. """
+    which = 'pzum'
+    want = 'bool'
+
+windows = window
+
+class document(aetools.ComponentItem):
+    """document - A document. """
+    want = 'docu'
+class _Prop_modified(aetools.NProperty):
+    """modified - Has the document been modified since the last save? """
+    which = 'imod'
+    want = 'bool'
+class _Prop_path(aetools.NProperty):
+    """path - The document's path. """
+    which = 'ppth'
+    want = 'utxt'
+
+documents = document
+application._superclassnames = ['item']
+application._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+    'frontmost' : _Prop_frontmost,
+    'name' : _Prop_name,
+    'version' : _Prop_version,
+}
+application._privelemdict = {
+    'document' : document,
+    'window' : window,
+}
+item._superclassnames = []
+item._privpropdict = {
+    'class_' : _Prop_class_,
+    'properties' : _Prop_properties,
+}
+item._privelemdict = {
+}
+color._superclassnames = ['item']
+color._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+}
+color._privelemdict = {
+}
+window._superclassnames = ['item']
+window._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+    'bounds' : _Prop_bounds,
+    'closeable' : _Prop_closeable,
+    'document' : _Prop_document,
+    'floating' : _Prop_floating,
+    'id' : _Prop_id,
+    'index' : _Prop_index,
+    'miniaturizable' : _Prop_miniaturizable,
+    'miniaturized' : _Prop_miniaturized,
+    'modal' : _Prop_modal,
+    'name' : _Prop_name,
+    'resizable' : _Prop_resizable,
+    'titled' : _Prop_titled,
+    'visible' : _Prop_visible,
+    'zoomable' : _Prop_zoomable,
+    'zoomed' : _Prop_zoomed,
+}
+window._privelemdict = {
+}
+document._superclassnames = ['item']
+document._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+    'modified' : _Prop_modified,
+    'name' : _Prop_name,
+    'path' : _Prop_path,
+}
+document._privelemdict = {
+}
+class _3c_(aetools.NComparison):
+    """< - Less than """
+class _3d_(aetools.NComparison):
+    """= - Equal """
+class _3e_(aetools.NComparison):
+    """> - Greater than """
+class contains(aetools.NComparison):
+    """contains - Contains """
+class ends_with(aetools.NComparison):
+    """ends with - Ends with """
+class starts_with(aetools.NComparison):
+    """starts with - Starts with """
+class _b2_(aetools.NComparison):
+    """\xb2 - Less than or equal to """
+class _b3_(aetools.NComparison):
+    """\xb3 - Greater than or equal to """
+_Enum_savo = {
+    'ask' : 'ask ',     # Ask the user whether or not to save the file.
+    'yes' : 'yes ',     # Save the file.
+    'no' : 'no  ',      # Do not save the file.
+}
+
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+    'capp' : application,
+    'cobj' : item,
+    'colr' : color,
+    'cwin' : window,
+    'docu' : document,
+}
+
+_propdeclarations = {
+    'ID  ' : _Prop_id,
+    'c@#^' : _Prop__3c_Inheritance_3e_,
+    'docu' : _Prop_document,
+    'hclb' : _Prop_closeable,
+    'imod' : _Prop_modified,
+    'isfl' : _Prop_floating,
+    'ismn' : _Prop_miniaturizable,
+    'iszm' : _Prop_zoomable,
+    'pALL' : _Prop_properties,
+    'pbnd' : _Prop_bounds,
+    'pcls' : _Prop_class_,
+    'pidx' : _Prop_index,
+    'pisf' : _Prop_frontmost,
+    'pmnd' : _Prop_miniaturized,
+    'pmod' : _Prop_modal,
+    'pnam' : _Prop_name,
+    'ppth' : _Prop_path,
+    'prsz' : _Prop_resizable,
+    'ptit' : _Prop_titled,
+    'pvis' : _Prop_visible,
+    'pzum' : _Prop_zoomed,
+    'vers' : _Prop_version,
+}
+
+_compdeclarations = {
+    '<   ' : _3c_,
+    '<=  ' : _b2_,
+    '=   ' : _3d_,
+    '>   ' : _3e_,
+    '>=  ' : _b3_,
+    'bgwt' : starts_with,
+    'cont' : contains,
+    'ends' : ends_with,
+}
+
+_enumdeclarations = {
+    'savo' : _Enum_savo,
+}

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/SystemEvents/System_Events_Suite.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/SystemEvents/System_Events_Suite.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/SystemEvents/System_Events_Suite.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,109 @@
+"""Suite System Events Suite: Terms and Events for controlling the System Events application
+Level 1, version 1
+
+Generated from /System/Library/CoreServices/System Events.app
+AETE/AEUT resource version 1/0, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'sevs'
+
+class System_Events_Suite_Events:
+
+    def do_script(self, _object, _attributes={}, **_arguments):
+        """do script: Execute an OSA script.
+        Required argument: the object for the command
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'misc'
+        _subcode = 'dosc'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+
+class application(aetools.ComponentItem):
+    """application - The System Events application """
+    want = 'capp'
+class _Prop__3c_Inheritance_3e_(aetools.NProperty):
+    """<Inheritance> - All of the properties of the superclass. """
+    which = 'c@#^'
+    want = 'capp'
+_3c_Inheritance_3e_ = _Prop__3c_Inheritance_3e_()
+class _Prop_folder_actions_enabled(aetools.NProperty):
+    """folder actions enabled - Are Folder Actions currently being processed? """
+    which = 'faen'
+    want = 'bool'
+folder_actions_enabled = _Prop_folder_actions_enabled()
+class _Prop_properties(aetools.NProperty):
+    """properties - every property of the System Events application """
+    which = 'pALL'
+    want = '****'
+properties = _Prop_properties()
+#        element 'cdis' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'cfol' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'cobj' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'cwin' as ['name', 'indx', 'rele', 'rang', 'test', 'ID  ']
+#        element 'docu' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'file' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'foac' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'logi' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'pcap' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'pcda' as ['name', 'indx', 'rele', 'rang', 'test']
+#        element 'prcs' as ['name', 'indx', 'rele', 'rang', 'test']
+
+applications = application
+application._superclassnames = []
+import Disk_Folder_File_Suite
+import Standard_Suite
+import Folder_Actions_Suite
+import Login_Items_Suite
+import Processes_Suite
+application._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+    'folder_actions_enabled' : _Prop_folder_actions_enabled,
+    'properties' : _Prop_properties,
+}
+application._privelemdict = {
+    'application_process' : Processes_Suite.application_process,
+    'desk_accessory_process' : Processes_Suite.desk_accessory_process,
+    'disk' : Disk_Folder_File_Suite.disk,
+    'document' : Standard_Suite.document,
+    'file' : Disk_Folder_File_Suite.file,
+    'folder' : Disk_Folder_File_Suite.folder,
+    'folder_action' : Folder_Actions_Suite.folder_action,
+    'item' : Disk_Folder_File_Suite.item,
+    'login_item' : Login_Items_Suite.login_item,
+    'process' : Processes_Suite.process,
+    'window' : Standard_Suite.window,
+}
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+    'capp' : application,
+}
+
+_propdeclarations = {
+    'c@#^' : _Prop__3c_Inheritance_3e_,
+    'faen' : _Prop_folder_actions_enabled,
+    'pALL' : _Prop_properties,
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+}

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/SystemEvents/Text_Suite.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/SystemEvents/Text_Suite.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/SystemEvents/Text_Suite.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,195 @@
+"""Suite Text Suite: A set of basic classes for text processing.
+Level 1, version 1
+
+Generated from /System/Library/CoreServices/System Events.app
+AETE/AEUT resource version 1/0, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = '????'
+
+class Text_Suite_Events:
+
+    pass
+
+
+class attachment(aetools.ComponentItem):
+    """attachment - Represents an inline text attachment.  This class is used mainly for make commands. """
+    want = 'atts'
+class _Prop__3c_Inheritance_3e_(aetools.NProperty):
+    """<Inheritance> - All of the properties of the superclass. """
+    which = 'c@#^'
+    want = 'ctxt'
+class _Prop_file_name(aetools.NProperty):
+    """file name - The path to the file for the attachment """
+    which = 'atfn'
+    want = 'utxt'
+#        element 'catr' as ['indx', 'rele', 'rang', 'test']
+#        element 'cha ' as ['indx', 'rele', 'rang', 'test']
+#        element 'cpar' as ['indx', 'rele', 'rang', 'test']
+#        element 'cwor' as ['indx', 'rele', 'rang', 'test']
+
+class attribute_run(aetools.ComponentItem):
+    """attribute run - This subdivides the text into chunks that all have the same attributes. """
+    want = 'catr'
+class _Prop_color(aetools.NProperty):
+    """color - The color of the first character. """
+    which = 'colr'
+    want = 'colr'
+class _Prop_font(aetools.NProperty):
+    """font - The name of the font of the first character. """
+    which = 'font'
+    want = 'utxt'
+class _Prop_size(aetools.NProperty):
+    """size - The size in points of the first character. """
+    which = 'ptsz'
+    want = 'long'
+#        element 'catr' as ['indx', 'rele', 'rang', 'test']
+#        element 'cha ' as ['indx', 'rele', 'rang', 'test']
+#        element 'cpar' as ['indx', 'rele', 'rang', 'test']
+#        element 'cwor' as ['indx', 'rele', 'rang', 'test']
+
+attribute_runs = attribute_run
+
+class character(aetools.ComponentItem):
+    """character - This subdivides the text into characters. """
+    want = 'cha '
+#        element 'catr' as ['indx', 'rele', 'rang', 'test']
+#        element 'cha ' as ['indx', 'rele', 'rang', 'test']
+#        element 'cpar' as ['indx', 'rele', 'rang', 'test']
+#        element 'cwor' as ['indx', 'rele', 'rang', 'test']
+
+characters = character
+
+class paragraph(aetools.ComponentItem):
+    """paragraph - This subdivides the text into paragraphs. """
+    want = 'cpar'
+#        element 'catr' as ['indx', 'rele', 'rang', 'test']
+#        element 'cha ' as ['indx', 'rele', 'rang', 'test']
+#        element 'cpar' as ['indx', 'rele', 'rang', 'test']
+#        element 'cwor' as ['indx', 'rele', 'rang', 'test']
+
+paragraphs = paragraph
+
+class text(aetools.ComponentItem):
+    """text - Rich (styled) text """
+    want = 'ctxt'
+#        element 'catr' as ['indx', 'rele', 'rang', 'test']
+#        element 'cha ' as ['indx', 'rele', 'rang', 'test']
+#        element 'cpar' as ['indx', 'rele', 'rang', 'test']
+#        element 'cwor' as ['indx', 'rele', 'rang', 'test']
+
+class word(aetools.ComponentItem):
+    """word - This subdivides the text into words. """
+    want = 'cwor'
+#        element 'catr' as ['indx', 'rele', 'rang', 'test']
+#        element 'cha ' as ['indx', 'rele', 'rang', 'test']
+#        element 'cpar' as ['indx', 'rele', 'rang', 'test']
+#        element 'cwor' as ['indx', 'rele', 'rang', 'test']
+
+words = word
+attachment._superclassnames = ['text']
+attachment._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+    'file_name' : _Prop_file_name,
+}
+attachment._privelemdict = {
+    'attribute_run' : attribute_run,
+    'character' : character,
+    'paragraph' : paragraph,
+    'word' : word,
+}
+import Standard_Suite
+attribute_run._superclassnames = ['item']
+attribute_run._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+    'color' : _Prop_color,
+    'font' : _Prop_font,
+    'size' : _Prop_size,
+}
+attribute_run._privelemdict = {
+    'attribute_run' : attribute_run,
+    'character' : character,
+    'paragraph' : paragraph,
+    'word' : word,
+}
+character._superclassnames = ['item']
+character._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+    'color' : _Prop_color,
+    'font' : _Prop_font,
+    'size' : _Prop_size,
+}
+character._privelemdict = {
+    'attribute_run' : attribute_run,
+    'character' : character,
+    'paragraph' : paragraph,
+    'word' : word,
+}
+paragraph._superclassnames = ['item']
+paragraph._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+    'color' : _Prop_color,
+    'font' : _Prop_font,
+    'size' : _Prop_size,
+}
+paragraph._privelemdict = {
+    'attribute_run' : attribute_run,
+    'character' : character,
+    'paragraph' : paragraph,
+    'word' : word,
+}
+text._superclassnames = ['item']
+text._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+    'color' : _Prop_color,
+    'font' : _Prop_font,
+    'size' : _Prop_size,
+}
+text._privelemdict = {
+    'attribute_run' : attribute_run,
+    'character' : character,
+    'paragraph' : paragraph,
+    'word' : word,
+}
+word._superclassnames = ['item']
+word._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+    'color' : _Prop_color,
+    'font' : _Prop_font,
+    'size' : _Prop_size,
+}
+word._privelemdict = {
+    'attribute_run' : attribute_run,
+    'character' : character,
+    'paragraph' : paragraph,
+    'word' : word,
+}
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+    'atts' : attachment,
+    'catr' : attribute_run,
+    'cha ' : character,
+    'cpar' : paragraph,
+    'ctxt' : text,
+    'cwor' : word,
+}
+
+_propdeclarations = {
+    'atfn' : _Prop_file_name,
+    'c@#^' : _Prop__3c_Inheritance_3e_,
+    'colr' : _Prop_color,
+    'font' : _Prop_font,
+    'ptsz' : _Prop_size,
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+}

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/SystemEvents/__init__.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/SystemEvents/__init__.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/SystemEvents/__init__.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,140 @@
+"""
+Package generated from /System/Library/CoreServices/System Events.app
+"""
+import aetools
+Error = aetools.Error
+import Standard_Suite
+import Text_Suite
+import Disk_Folder_File_Suite
+import Folder_Actions_Suite
+import Login_Items_Suite
+import Power_Suite
+import Processes_Suite
+import System_Events_Suite
+
+
+_code_to_module = {
+    '????' : Standard_Suite,
+    '????' : Text_Suite,
+    'cdis' : Disk_Folder_File_Suite,
+    'faco' : Folder_Actions_Suite,
+    'logi' : Login_Items_Suite,
+    'powr' : Power_Suite,
+    'prcs' : Processes_Suite,
+    'sevs' : System_Events_Suite,
+}
+
+
+
+_code_to_fullname = {
+    '????' : ('SystemEvents.Standard_Suite', 'Standard_Suite'),
+    '????' : ('SystemEvents.Text_Suite', 'Text_Suite'),
+    'cdis' : ('SystemEvents.Disk_Folder_File_Suite', 'Disk_Folder_File_Suite'),
+    'faco' : ('SystemEvents.Folder_Actions_Suite', 'Folder_Actions_Suite'),
+    'logi' : ('SystemEvents.Login_Items_Suite', 'Login_Items_Suite'),
+    'powr' : ('SystemEvents.Power_Suite', 'Power_Suite'),
+    'prcs' : ('SystemEvents.Processes_Suite', 'Processes_Suite'),
+    'sevs' : ('SystemEvents.System_Events_Suite', 'System_Events_Suite'),
+}
+
+from Standard_Suite import *
+from Text_Suite import *
+from Disk_Folder_File_Suite import *
+from Folder_Actions_Suite import *
+from Login_Items_Suite import *
+from Power_Suite import *
+from Processes_Suite import *
+from System_Events_Suite import *
+
+def getbaseclasses(v):
+    if not getattr(v, '_propdict', None):
+        v._propdict = {}
+        v._elemdict = {}
+        for superclassname in getattr(v, '_superclassnames', []):
+            superclass = eval(superclassname)
+            getbaseclasses(superclass)
+            v._propdict.update(getattr(superclass, '_propdict', {}))
+            v._elemdict.update(getattr(superclass, '_elemdict', {}))
+        v._propdict.update(getattr(v, '_privpropdict', {}))
+        v._elemdict.update(getattr(v, '_privelemdict', {}))
+
+import StdSuites
+
+#
+# Set property and element dictionaries now that all classes have been defined
+#
+getbaseclasses(login_item)
+getbaseclasses(color)
+getbaseclasses(window)
+getbaseclasses(application)
+getbaseclasses(item)
+getbaseclasses(document)
+getbaseclasses(character)
+getbaseclasses(attachment)
+getbaseclasses(paragraph)
+getbaseclasses(word)
+getbaseclasses(attribute_run)
+getbaseclasses(text)
+getbaseclasses(file)
+getbaseclasses(application)
+getbaseclasses(item)
+getbaseclasses(folder)
+getbaseclasses(disk)
+getbaseclasses(script)
+getbaseclasses(application)
+getbaseclasses(folder_action)
+getbaseclasses(application)
+getbaseclasses(application)
+getbaseclasses(process)
+getbaseclasses(application_process)
+getbaseclasses(desk_accessory_process)
+getbaseclasses(application)
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+    'logi' : login_item,
+    'colr' : color,
+    'cwin' : window,
+    'capp' : application,
+    'cobj' : item,
+    'docu' : document,
+    'cha ' : character,
+    'atts' : attachment,
+    'cpar' : paragraph,
+    'cwor' : word,
+    'catr' : attribute_run,
+    'ctxt' : text,
+    'file' : file,
+    'capp' : application,
+    'cobj' : item,
+    'cfol' : folder,
+    'cdis' : disk,
+    'scpt' : script,
+    'capp' : application,
+    'foac' : folder_action,
+    'capp' : application,
+    'capp' : application,
+    'prcs' : process,
+    'pcap' : application_process,
+    'pcda' : desk_accessory_process,
+    'capp' : application,
+}
+
+
+class SystemEvents(Standard_Suite_Events,
+        Text_Suite_Events,
+        Disk_Folder_File_Suite_Events,
+        Folder_Actions_Suite_Events,
+        Login_Items_Suite_Events,
+        Power_Suite_Events,
+        Processes_Suite_Events,
+        System_Events_Suite_Events,
+        aetools.TalkTo):
+    _signature = 'sevs'
+
+    _moduleName = 'SystemEvents'
+
+    _elemdict = application._elemdict
+    _propdict = application._propdict

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Terminal/Standard_Suite.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Terminal/Standard_Suite.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Terminal/Standard_Suite.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,582 @@
+"""Suite Standard Suite: Common classes and commands for most applications.
+Level 1, version 1
+
+Generated from /Applications/Utilities/Terminal.app
+AETE/AEUT resource version 1/0, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = '????'
+
+class Standard_Suite_Events:
+
+    _argmap_close = {
+        'saving_in' : 'kfil',
+        'saving' : 'savo',
+    }
+
+    def close(self, _object, _attributes={}, **_arguments):
+        """close: Close an object.
+        Required argument: the object for the command
+        Keyword argument saving_in: The file in which to save the object.
+        Keyword argument saving: Specifies whether changes should be saved before closing.
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'core'
+        _subcode = 'clos'
+
+        aetools.keysubst(_arguments, self._argmap_close)
+        _arguments['----'] = _object
+
+        aetools.enumsubst(_arguments, 'savo', _Enum_savo)
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_count = {
+        'each' : 'kocl',
+    }
+
+    def count(self, _object, _attributes={}, **_arguments):
+        """count: Return the number of elements of a particular class within an object.
+        Required argument: the object for the command
+        Keyword argument each: The class of objects to be counted.
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: the reply for the command
+        """
+        _code = 'core'
+        _subcode = 'cnte'
+
+        aetools.keysubst(_arguments, self._argmap_count)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def delete(self, _object, _attributes={}, **_arguments):
+        """delete: Delete an object.
+        Required argument: the object for the command
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'core'
+        _subcode = 'delo'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_duplicate = {
+        'to' : 'insh',
+        'with_properties' : 'prdt',
+    }
+
+    def duplicate(self, _object, _attributes={}, **_arguments):
+        """duplicate: Copy object(s) and put the copies at a new location.
+        Required argument: the object for the command
+        Keyword argument to: The location for the new object(s).
+        Keyword argument with_properties: Properties to be set in the new duplicated object(s).
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'core'
+        _subcode = 'clon'
+
+        aetools.keysubst(_arguments, self._argmap_duplicate)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def exists(self, _object, _attributes={}, **_arguments):
+        """exists: Verify if an object exists.
+        Required argument: the object for the command
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: the reply for the command
+        """
+        _code = 'core'
+        _subcode = 'doex'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def get(self, _object, _attributes={}, **_arguments):
+        """get: Get the data for an object.
+        Required argument: the object for the command
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: the reply for the command
+        """
+        _code = 'core'
+        _subcode = 'getd'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_make = {
+        'at' : 'insh',
+        'new' : 'kocl',
+        'with_data' : 'data',
+        'with_properties' : 'prdt',
+    }
+
+    def make(self, _no_object=None, _attributes={}, **_arguments):
+        """make: Make a new object.
+        Keyword argument at: The location at which to insert the object.
+        Keyword argument new: The class of the new object.
+        Keyword argument with_data: The initial data for the object.
+        Keyword argument with_properties: The initial values for properties of the object.
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: the reply for the command
+        """
+        _code = 'core'
+        _subcode = 'crel'
+
+        aetools.keysubst(_arguments, self._argmap_make)
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_move = {
+        'to' : 'insh',
+    }
+
+    def move(self, _object, _attributes={}, **_arguments):
+        """move: Move object(s) to a new location.
+        Required argument: the object for the command
+        Keyword argument to: The new location for the object(s).
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'core'
+        _subcode = 'move'
+
+        aetools.keysubst(_arguments, self._argmap_move)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def open(self, _object=None, _attributes={}, **_arguments):
+        """open: Open an object.
+        Required argument: list of objects
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'aevt'
+        _subcode = 'odoc'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def print_(self, _object=None, _attributes={}, **_arguments):
+        """print: Print an object.
+        Required argument: list of objects
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'aevt'
+        _subcode = 'pdoc'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_quit = {
+        'saving' : 'savo',
+    }
+
+    def quit(self, _object, _attributes={}, **_arguments):
+        """quit: Quit an application.
+        Required argument: the object for the command
+        Keyword argument saving: Specifies whether changes should be saved before quitting.
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'aevt'
+        _subcode = 'quit'
+
+        aetools.keysubst(_arguments, self._argmap_quit)
+        _arguments['----'] = _object
+
+        aetools.enumsubst(_arguments, 'savo', _Enum_savo)
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_save = {
+        'in_' : 'kfil',
+        'as' : 'fltp',
+    }
+
+    def save(self, _object, _attributes={}, **_arguments):
+        """save: Save an object.
+        Required argument: the object for the command
+        Keyword argument in_: The file in which to save the object.
+        Keyword argument as: The file type in which to save the data.
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'core'
+        _subcode = 'save'
+
+        aetools.keysubst(_arguments, self._argmap_save)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_set = {
+        'to' : 'data',
+    }
+
+    def set(self, _object, _attributes={}, **_arguments):
+        """set: Set an object's data.
+        Required argument: the object for the command
+        Keyword argument to: The new value.
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'core'
+        _subcode = 'setd'
+
+        aetools.keysubst(_arguments, self._argmap_set)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+
+class application(aetools.ComponentItem):
+    """application - An application's top level scripting object. """
+    want = 'capp'
+class _Prop__3c_Inheritance_3e_(aetools.NProperty):
+    """<Inheritance> - All of the properties of the superclass. """
+    which = 'c@#^'
+    want = 'cobj'
+_3c_Inheritance_3e_ = _Prop__3c_Inheritance_3e_()
+class _Prop_frontmost(aetools.NProperty):
+    """frontmost - Is this the frontmost (active) application? """
+    which = 'pisf'
+    want = 'bool'
+frontmost = _Prop_frontmost()
+class _Prop_name(aetools.NProperty):
+    """name - The name of the application. """
+    which = 'pnam'
+    want = 'utxt'
+name = _Prop_name()
+class _Prop_version(aetools.NProperty):
+    """version - The version of the application. """
+    which = 'vers'
+    want = 'utxt'
+version = _Prop_version()
+#        element 'cwin' as ['name', 'indx', 'rele', 'rang', 'test', 'ID  ']
+#        element 'docu' as ['name', 'indx', 'rele', 'rang', 'test']
+
+applications = application
+
+class item(aetools.ComponentItem):
+    """item - A scriptable object. """
+    want = 'cobj'
+class _Prop_class_(aetools.NProperty):
+    """class - The class of the object. """
+    which = 'pcls'
+    want = 'type'
+class _Prop_properties(aetools.NProperty):
+    """properties - All of the object's properties. """
+    which = 'pALL'
+    want = 'reco'
+
+items = item
+
+class color(aetools.ComponentItem):
+    """color - A color. """
+    want = 'colr'
+
+colors = color
+
+class window(aetools.ComponentItem):
+    """window - A window. """
+    want = 'cwin'
+class _Prop_bounds(aetools.NProperty):
+    """bounds - The bounding rectangle of the window. """
+    which = 'pbnd'
+    want = 'qdrt'
+class _Prop_closeable(aetools.NProperty):
+    """closeable - Whether the window has a close box. """
+    which = 'hclb'
+    want = 'bool'
+class _Prop_document(aetools.NProperty):
+    """document - The document whose contents are being displayed in the window. """
+    which = 'docu'
+    want = 'docu'
+class _Prop_floating(aetools.NProperty):
+    """floating - Whether the window floats. """
+    which = 'isfl'
+    want = 'bool'
+class _Prop_id(aetools.NProperty):
+    """id - The unique identifier of the window. """
+    which = 'ID  '
+    want = 'long'
+class _Prop_index(aetools.NProperty):
+    """index - The index of the window in the back-to-front window ordering. """
+    which = 'pidx'
+    want = 'long'
+class _Prop_miniaturizable(aetools.NProperty):
+    """miniaturizable - Whether the window can be miniaturized. """
+    which = 'ismn'
+    want = 'bool'
+class _Prop_miniaturized(aetools.NProperty):
+    """miniaturized - Whether the window is currently miniaturized. """
+    which = 'pmnd'
+    want = 'bool'
+class _Prop_modal(aetools.NProperty):
+    """modal - Whether the window is the application's current modal window. """
+    which = 'pmod'
+    want = 'bool'
+class _Prop_resizable(aetools.NProperty):
+    """resizable - Whether the window can be resized. """
+    which = 'prsz'
+    want = 'bool'
+class _Prop_titled(aetools.NProperty):
+    """titled - Whether the window has a title bar. """
+    which = 'ptit'
+    want = 'bool'
+class _Prop_visible(aetools.NProperty):
+    """visible - Whether the window is currently visible. """
+    which = 'pvis'
+    want = 'bool'
+class _Prop_zoomable(aetools.NProperty):
+    """zoomable - Whether the window can be zoomed. """
+    which = 'iszm'
+    want = 'bool'
+class _Prop_zoomed(aetools.NProperty):
+    """zoomed - Whether the window is currently zoomed. """
+    which = 'pzum'
+    want = 'bool'
+
+windows = window
+
+class document(aetools.ComponentItem):
+    """document - A document. """
+    want = 'docu'
+class _Prop_modified(aetools.NProperty):
+    """modified - Has the document been modified since the last save? """
+    which = 'imod'
+    want = 'bool'
+class _Prop_path(aetools.NProperty):
+    """path - The document's path. """
+    which = 'ppth'
+    want = 'utxt'
+
+documents = document
+application._superclassnames = ['item']
+application._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+    'frontmost' : _Prop_frontmost,
+    'name' : _Prop_name,
+    'version' : _Prop_version,
+}
+application._privelemdict = {
+    'document' : document,
+    'window' : window,
+}
+item._superclassnames = []
+item._privpropdict = {
+    'class_' : _Prop_class_,
+    'properties' : _Prop_properties,
+}
+item._privelemdict = {
+}
+color._superclassnames = ['item']
+color._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+}
+color._privelemdict = {
+}
+window._superclassnames = ['item']
+window._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+    'bounds' : _Prop_bounds,
+    'closeable' : _Prop_closeable,
+    'document' : _Prop_document,
+    'floating' : _Prop_floating,
+    'id' : _Prop_id,
+    'index' : _Prop_index,
+    'miniaturizable' : _Prop_miniaturizable,
+    'miniaturized' : _Prop_miniaturized,
+    'modal' : _Prop_modal,
+    'name' : _Prop_name,
+    'resizable' : _Prop_resizable,
+    'titled' : _Prop_titled,
+    'visible' : _Prop_visible,
+    'zoomable' : _Prop_zoomable,
+    'zoomed' : _Prop_zoomed,
+}
+window._privelemdict = {
+}
+document._superclassnames = ['item']
+document._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+    'modified' : _Prop_modified,
+    'name' : _Prop_name,
+    'path' : _Prop_path,
+}
+document._privelemdict = {
+}
+class _3c_(aetools.NComparison):
+    """< - Less than """
+class _3d_(aetools.NComparison):
+    """= - Equal """
+class _3e_(aetools.NComparison):
+    """> - Greater than """
+class contains(aetools.NComparison):
+    """contains - Contains """
+class ends_with(aetools.NComparison):
+    """ends with - Ends with """
+class starts_with(aetools.NComparison):
+    """starts with - Starts with """
+class _b2_(aetools.NComparison):
+    """\xb2 - Less than or equal to """
+class _b3_(aetools.NComparison):
+    """\xb3 - Greater than or equal to """
+_Enum_savo = {
+    'ask' : 'ask ',     # Ask the user whether or not to save the file.
+    'yes' : 'yes ',     # Save the file.
+    'no' : 'no  ',      # Do not save the file.
+}
+
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+    'capp' : application,
+    'cobj' : item,
+    'colr' : color,
+    'cwin' : window,
+    'docu' : document,
+}
+
+_propdeclarations = {
+    'ID  ' : _Prop_id,
+    'c@#^' : _Prop__3c_Inheritance_3e_,
+    'docu' : _Prop_document,
+    'hclb' : _Prop_closeable,
+    'imod' : _Prop_modified,
+    'isfl' : _Prop_floating,
+    'ismn' : _Prop_miniaturizable,
+    'iszm' : _Prop_zoomable,
+    'pALL' : _Prop_properties,
+    'pbnd' : _Prop_bounds,
+    'pcls' : _Prop_class_,
+    'pidx' : _Prop_index,
+    'pisf' : _Prop_frontmost,
+    'pmnd' : _Prop_miniaturized,
+    'pmod' : _Prop_modal,
+    'pnam' : _Prop_name,
+    'ppth' : _Prop_path,
+    'prsz' : _Prop_resizable,
+    'ptit' : _Prop_titled,
+    'pvis' : _Prop_visible,
+    'pzum' : _Prop_zoomed,
+    'vers' : _Prop_version,
+}
+
+_compdeclarations = {
+    '<   ' : _3c_,
+    '<=  ' : _b2_,
+    '=   ' : _3d_,
+    '>   ' : _3e_,
+    '>=  ' : _b3_,
+    'bgwt' : starts_with,
+    'cont' : contains,
+    'ends' : ends_with,
+}
+
+_enumdeclarations = {
+    'savo' : _Enum_savo,
+}

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Terminal/Terminal_Suite.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Terminal/Terminal_Suite.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Terminal/Terminal_Suite.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,254 @@
+"""Suite Terminal Suite: Terms and Events for controlling the Terminal application
+Level 1, version 1
+
+Generated from /Applications/Utilities/Terminal.app
+AETE/AEUT resource version 1/0, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'trmx'
+
+class Terminal_Suite_Events:
+
+    def GetURL(self, _object, _attributes={}, **_arguments):
+        """GetURL: Opens a telnet: URL
+        Required argument: the object for the command
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'GURL'
+        _subcode = 'GURL'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_do_script = {
+        'in_' : 'kfil',
+        'with_command' : 'cmnd',
+    }
+
+    def do_script(self, _object, _attributes={}, **_arguments):
+        """do script: Run a UNIX shell script or command
+        Required argument: the object for the command
+        Keyword argument in_: the window in which to execute the command
+        Keyword argument with_command: data to be passed to the Terminal application as the command line, deprecated, use direct parameter
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: the reply for the command
+        """
+        _code = 'core'
+        _subcode = 'dosc'
+
+        aetools.keysubst(_arguments, self._argmap_do_script)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+
+class application(aetools.ComponentItem):
+    """application - The Terminal program """
+    want = 'capp'
+class _Prop__3c_Inheritance_3e_(aetools.NProperty):
+    """<Inheritance> - All of the properties of the superclass. """
+    which = 'c@#^'
+    want = 'capp'
+_3c_Inheritance_3e_ = _Prop__3c_Inheritance_3e_()
+class _Prop_properties(aetools.NProperty):
+    """properties - every property of the Terminal program """
+    which = 'pALL'
+    want = '****'
+properties = _Prop_properties()
+#        element 'cwin' as ['name', 'indx', 'rele', 'rang', 'test', 'ID  ']
+#        element 'docu' as ['name', 'indx', 'rele', 'rang', 'test']
+
+applications = application
+
+class window(aetools.ComponentItem):
+    """window - A Terminal window """
+    want = 'cwin'
+class _Prop_background_color(aetools.NProperty):
+    """background color - the background color for the window """
+    which = 'pbcl'
+    want = '****'
+class _Prop_bold_text_color(aetools.NProperty):
+    """bold text color - the bold text color for the window """
+    which = 'pbtc'
+    want = '****'
+class _Prop_bounds(aetools.NProperty):
+    """bounds - the boundary rectangle for the window, relative to the upper left corner of the screen """
+    which = 'pbnd'
+    want = '****'
+class _Prop_busy(aetools.NProperty):
+    """busy - Is the window busy running a process? """
+    which = 'busy'
+    want = 'bool'
+class _Prop_contents(aetools.NProperty):
+    """contents - the currently visible contents of the window """
+    which = 'pcnt'
+    want = 'utxt'
+class _Prop_cursor_color(aetools.NProperty):
+    """cursor color - the cursor color for the window """
+    which = 'pcuc'
+    want = '****'
+class _Prop_custom_title(aetools.NProperty):
+    """custom title - the custom title for the window """
+    which = 'titl'
+    want = 'utxt'
+class _Prop_frame(aetools.NProperty):
+    """frame - the origin and size of the window """
+    which = 'pfra'
+    want = '****'
+class _Prop_frontmost(aetools.NProperty):
+    """frontmost - Is the window in front of the other Terminal windows? """
+    which = 'pisf'
+    want = 'bool'
+class _Prop_history(aetools.NProperty):
+    """history - the contents of the entire scrolling buffer of the window """
+    which = 'hist'
+    want = 'utxt'
+class _Prop_normal_text_color(aetools.NProperty):
+    """normal text color - the normal text color for the window """
+    which = 'ptxc'
+    want = '****'
+class _Prop_number_of_columns(aetools.NProperty):
+    """number of columns - the number of columns in the window """
+    which = 'ccol'
+    want = 'long'
+class _Prop_number_of_rows(aetools.NProperty):
+    """number of rows - the number of rows in the window """
+    which = 'crow'
+    want = 'long'
+class _Prop_origin(aetools.NProperty):
+    """origin - the lower left coordinates of the window, relative to the lower left corner of the screen """
+    which = 'pori'
+    want = '****'
+class _Prop_position(aetools.NProperty):
+    """position - the upper left coordinates of the window, relative to the upper left corner of the screen """
+    which = 'ppos'
+    want = '****'
+class _Prop_processes(aetools.NProperty):
+    """processes - a list of the currently running processes """
+    which = 'prcs'
+    want = 'utxt'
+class _Prop_size(aetools.NProperty):
+    """size - the width and height of the window """
+    which = 'psiz'
+    want = '****'
+class _Prop_title_displays_custom_title(aetools.NProperty):
+    """title displays custom title - Does the title for the window contain a custom title? """
+    which = 'tdct'
+    want = 'bool'
+class _Prop_title_displays_device_name(aetools.NProperty):
+    """title displays device name - Does the title for the window contain the device name? """
+    which = 'tddn'
+    want = 'bool'
+class _Prop_title_displays_file_name(aetools.NProperty):
+    """title displays file name - Does the title for the window contain the file name? """
+    which = 'tdfn'
+    want = 'bool'
+class _Prop_title_displays_shell_path(aetools.NProperty):
+    """title displays shell path - Does the title for the window contain the shell path? """
+    which = 'tdsp'
+    want = 'bool'
+class _Prop_title_displays_window_size(aetools.NProperty):
+    """title displays window size - Does the title for the window contain the window size? """
+    which = 'tdws'
+    want = 'bool'
+
+windows = window
+application._superclassnames = []
+import Standard_Suite
+application._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+    'properties' : _Prop_properties,
+}
+application._privelemdict = {
+    'document' : Standard_Suite.document,
+    'window' : window,
+}
+window._superclassnames = []
+window._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+    'background_color' : _Prop_background_color,
+    'bold_text_color' : _Prop_bold_text_color,
+    'bounds' : _Prop_bounds,
+    'busy' : _Prop_busy,
+    'contents' : _Prop_contents,
+    'cursor_color' : _Prop_cursor_color,
+    'custom_title' : _Prop_custom_title,
+    'frame' : _Prop_frame,
+    'frontmost' : _Prop_frontmost,
+    'history' : _Prop_history,
+    'normal_text_color' : _Prop_normal_text_color,
+    'number_of_columns' : _Prop_number_of_columns,
+    'number_of_rows' : _Prop_number_of_rows,
+    'origin' : _Prop_origin,
+    'position' : _Prop_position,
+    'processes' : _Prop_processes,
+    'properties' : _Prop_properties,
+    'size' : _Prop_size,
+    'title_displays_custom_title' : _Prop_title_displays_custom_title,
+    'title_displays_device_name' : _Prop_title_displays_device_name,
+    'title_displays_file_name' : _Prop_title_displays_file_name,
+    'title_displays_shell_path' : _Prop_title_displays_shell_path,
+    'title_displays_window_size' : _Prop_title_displays_window_size,
+}
+window._privelemdict = {
+}
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+    'capp' : application,
+    'cwin' : window,
+}
+
+_propdeclarations = {
+    'busy' : _Prop_busy,
+    'c@#^' : _Prop__3c_Inheritance_3e_,
+    'ccol' : _Prop_number_of_columns,
+    'crow' : _Prop_number_of_rows,
+    'hist' : _Prop_history,
+    'pALL' : _Prop_properties,
+    'pbcl' : _Prop_background_color,
+    'pbnd' : _Prop_bounds,
+    'pbtc' : _Prop_bold_text_color,
+    'pcnt' : _Prop_contents,
+    'pcuc' : _Prop_cursor_color,
+    'pfra' : _Prop_frame,
+    'pisf' : _Prop_frontmost,
+    'pori' : _Prop_origin,
+    'ppos' : _Prop_position,
+    'prcs' : _Prop_processes,
+    'psiz' : _Prop_size,
+    'ptxc' : _Prop_normal_text_color,
+    'tdct' : _Prop_title_displays_custom_title,
+    'tddn' : _Prop_title_displays_device_name,
+    'tdfn' : _Prop_title_displays_file_name,
+    'tdsp' : _Prop_title_displays_shell_path,
+    'tdws' : _Prop_title_displays_window_size,
+    'titl' : _Prop_custom_title,
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+}

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Terminal/Text_Suite.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Terminal/Text_Suite.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Terminal/Text_Suite.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,195 @@
+"""Suite Text Suite: A set of basic classes for text processing.
+Level 1, version 1
+
+Generated from /Applications/Utilities/Terminal.app
+AETE/AEUT resource version 1/0, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = '????'
+
+class Text_Suite_Events:
+
+    pass
+
+
+class attachment(aetools.ComponentItem):
+    """attachment - Represents an inline text attachment.  This class is used mainly for make commands. """
+    want = 'atts'
+class _Prop__3c_Inheritance_3e_(aetools.NProperty):
+    """<Inheritance> - All of the properties of the superclass. """
+    which = 'c@#^'
+    want = 'ctxt'
+class _Prop_file_name(aetools.NProperty):
+    """file name - The path to the file for the attachment """
+    which = 'atfn'
+    want = 'utxt'
+#        element 'catr' as ['indx', 'rele', 'rang', 'test']
+#        element 'cha ' as ['indx', 'rele', 'rang', 'test']
+#        element 'cpar' as ['indx', 'rele', 'rang', 'test']
+#        element 'cwor' as ['indx', 'rele', 'rang', 'test']
+
+class attribute_run(aetools.ComponentItem):
+    """attribute run - This subdivides the text into chunks that all have the same attributes. """
+    want = 'catr'
+class _Prop_color(aetools.NProperty):
+    """color - The color of the first character. """
+    which = 'colr'
+    want = 'colr'
+class _Prop_font(aetools.NProperty):
+    """font - The name of the font of the first character. """
+    which = 'font'
+    want = 'utxt'
+class _Prop_size(aetools.NProperty):
+    """size - The size in points of the first character. """
+    which = 'ptsz'
+    want = 'long'
+#        element 'catr' as ['indx', 'rele', 'rang', 'test']
+#        element 'cha ' as ['indx', 'rele', 'rang', 'test']
+#        element 'cpar' as ['indx', 'rele', 'rang', 'test']
+#        element 'cwor' as ['indx', 'rele', 'rang', 'test']
+
+attribute_runs = attribute_run
+
+class character(aetools.ComponentItem):
+    """character - This subdivides the text into characters. """
+    want = 'cha '
+#        element 'catr' as ['indx', 'rele', 'rang', 'test']
+#        element 'cha ' as ['indx', 'rele', 'rang', 'test']
+#        element 'cpar' as ['indx', 'rele', 'rang', 'test']
+#        element 'cwor' as ['indx', 'rele', 'rang', 'test']
+
+characters = character
+
+class paragraph(aetools.ComponentItem):
+    """paragraph - This subdivides the text into paragraphs. """
+    want = 'cpar'
+#        element 'catr' as ['indx', 'rele', 'rang', 'test']
+#        element 'cha ' as ['indx', 'rele', 'rang', 'test']
+#        element 'cpar' as ['indx', 'rele', 'rang', 'test']
+#        element 'cwor' as ['indx', 'rele', 'rang', 'test']
+
+paragraphs = paragraph
+
+class text(aetools.ComponentItem):
+    """text - Rich (styled) text """
+    want = 'ctxt'
+#        element 'catr' as ['indx', 'rele', 'rang', 'test']
+#        element 'cha ' as ['indx', 'rele', 'rang', 'test']
+#        element 'cpar' as ['indx', 'rele', 'rang', 'test']
+#        element 'cwor' as ['indx', 'rele', 'rang', 'test']
+
+class word(aetools.ComponentItem):
+    """word - This subdivides the text into words. """
+    want = 'cwor'
+#        element 'catr' as ['indx', 'rele', 'rang', 'test']
+#        element 'cha ' as ['indx', 'rele', 'rang', 'test']
+#        element 'cpar' as ['indx', 'rele', 'rang', 'test']
+#        element 'cwor' as ['indx', 'rele', 'rang', 'test']
+
+words = word
+attachment._superclassnames = ['text']
+attachment._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+    'file_name' : _Prop_file_name,
+}
+attachment._privelemdict = {
+    'attribute_run' : attribute_run,
+    'character' : character,
+    'paragraph' : paragraph,
+    'word' : word,
+}
+import Standard_Suite
+attribute_run._superclassnames = ['item']
+attribute_run._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+    'color' : _Prop_color,
+    'font' : _Prop_font,
+    'size' : _Prop_size,
+}
+attribute_run._privelemdict = {
+    'attribute_run' : attribute_run,
+    'character' : character,
+    'paragraph' : paragraph,
+    'word' : word,
+}
+character._superclassnames = ['item']
+character._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+    'color' : _Prop_color,
+    'font' : _Prop_font,
+    'size' : _Prop_size,
+}
+character._privelemdict = {
+    'attribute_run' : attribute_run,
+    'character' : character,
+    'paragraph' : paragraph,
+    'word' : word,
+}
+paragraph._superclassnames = ['item']
+paragraph._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+    'color' : _Prop_color,
+    'font' : _Prop_font,
+    'size' : _Prop_size,
+}
+paragraph._privelemdict = {
+    'attribute_run' : attribute_run,
+    'character' : character,
+    'paragraph' : paragraph,
+    'word' : word,
+}
+text._superclassnames = ['item']
+text._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+    'color' : _Prop_color,
+    'font' : _Prop_font,
+    'size' : _Prop_size,
+}
+text._privelemdict = {
+    'attribute_run' : attribute_run,
+    'character' : character,
+    'paragraph' : paragraph,
+    'word' : word,
+}
+word._superclassnames = ['item']
+word._privpropdict = {
+    '_3c_Inheritance_3e_' : _Prop__3c_Inheritance_3e_,
+    'color' : _Prop_color,
+    'font' : _Prop_font,
+    'size' : _Prop_size,
+}
+word._privelemdict = {
+    'attribute_run' : attribute_run,
+    'character' : character,
+    'paragraph' : paragraph,
+    'word' : word,
+}
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+    'atts' : attachment,
+    'catr' : attribute_run,
+    'cha ' : character,
+    'cpar' : paragraph,
+    'ctxt' : text,
+    'cwor' : word,
+}
+
+_propdeclarations = {
+    'atfn' : _Prop_file_name,
+    'c@#^' : _Prop__3c_Inheritance_3e_,
+    'colr' : _Prop_color,
+    'font' : _Prop_font,
+    'ptsz' : _Prop_size,
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+}

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Terminal/__init__.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Terminal/__init__.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/Terminal/__init__.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,89 @@
+"""
+Package generated from /Applications/Utilities/Terminal.app
+"""
+import aetools
+Error = aetools.Error
+import Standard_Suite
+import Text_Suite
+import Terminal_Suite
+
+
+_code_to_module = {
+    '????' : Standard_Suite,
+    '????' : Text_Suite,
+    'trmx' : Terminal_Suite,
+}
+
+
+
+_code_to_fullname = {
+    '????' : ('Terminal.Standard_Suite', 'Standard_Suite'),
+    '????' : ('Terminal.Text_Suite', 'Text_Suite'),
+    'trmx' : ('Terminal.Terminal_Suite', 'Terminal_Suite'),
+}
+
+from Standard_Suite import *
+from Text_Suite import *
+from Terminal_Suite import *
+
+def getbaseclasses(v):
+    if not getattr(v, '_propdict', None):
+        v._propdict = {}
+        v._elemdict = {}
+        for superclassname in getattr(v, '_superclassnames', []):
+            superclass = eval(superclassname)
+            getbaseclasses(superclass)
+            v._propdict.update(getattr(superclass, '_propdict', {}))
+            v._elemdict.update(getattr(superclass, '_elemdict', {}))
+        v._propdict.update(getattr(v, '_privpropdict', {}))
+        v._elemdict.update(getattr(v, '_privelemdict', {}))
+
+import StdSuites
+
+#
+# Set property and element dictionaries now that all classes have been defined
+#
+getbaseclasses(color)
+getbaseclasses(window)
+getbaseclasses(application)
+getbaseclasses(item)
+getbaseclasses(document)
+getbaseclasses(window)
+getbaseclasses(application)
+getbaseclasses(character)
+getbaseclasses(attachment)
+getbaseclasses(paragraph)
+getbaseclasses(word)
+getbaseclasses(attribute_run)
+getbaseclasses(text)
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+    'colr' : color,
+    'cwin' : window,
+    'capp' : application,
+    'cobj' : item,
+    'docu' : document,
+    'cwin' : window,
+    'capp' : application,
+    'cha ' : character,
+    'atts' : attachment,
+    'cpar' : paragraph,
+    'cwor' : word,
+    'catr' : attribute_run,
+    'ctxt' : text,
+}
+
+
+class Terminal(Standard_Suite_Events,
+        Text_Suite_Events,
+        Terminal_Suite_Events,
+        aetools.TalkTo):
+    _signature = 'trmx'
+
+    _moduleName = 'Terminal'
+
+    _elemdict = application._elemdict
+    _propdict = application._propdict

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/_builtinSuites/__init__.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/_builtinSuites/__init__.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/_builtinSuites/__init__.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,27 @@
+"""
+Manually generated suite used as base class for StdSuites Required and Standard
+suites. This is needed because the events and enums in this suite belong
+in the Required suite according to the Apple docs, but they often seem to be
+in the Standard suite.
+"""
+import aetools
+import builtin_Suite
+
+
+_code_to_module = {
+        'reqd' : builtin_Suite,
+        'core' : builtin_Suite,
+}
+
+
+
+_code_to_fullname = {
+        'reqd' : ('_builtinSuites.builtin_Suite', 'builtin_Suite'),
+        'core' : ('_builtinSuites.builtin_Suite', 'builtin_Suite'),
+}
+
+from builtin_Suite import *
+
+class _builtinSuites(builtin_Suite_Events,
+                aetools.TalkTo):
+    _signature = 'ascr'

Added: vendor/Python/current/Lib/plat-mac/lib-scriptpackages/_builtinSuites/builtin_Suite.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/lib-scriptpackages/_builtinSuites/builtin_Suite.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/lib-scriptpackages/_builtinSuites/builtin_Suite.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,140 @@
+"""Suite builtin_Suite: Every application supports open, reopen, print, run, and quit
+Level 1, version 1
+"""
+
+import aetools
+import MacOS
+
+_code = 'aevt'
+
+class builtin_Suite_Events:
+
+    def open(self, _object, _attributes={}, **_arguments):
+        """open: Open the specified object(s)
+        Required argument: list of objects to open
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'aevt'
+        _subcode = 'odoc'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                        _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def run(self, _no_object=None, _attributes={}, **_arguments):
+        """run: Run an application.      Most applications will open an empty, untitled window.
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'aevt'
+        _subcode = 'oapp'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                        _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def reopen(self, _no_object=None, _attributes={}, **_arguments):
+        """reopen: Reactivate a running application.  Some applications will open a new untitled window if no window is open.
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'aevt'
+        _subcode = 'rapp'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                        _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def _print(self, _object, _attributes={}, **_arguments):
+        """print: Print the specified object(s)
+        Required argument: list of objects to print
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'aevt'
+        _subcode = 'pdoc'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                        _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_quit = {
+            'saving' : 'savo',
+    }
+
+    def quit(self, _no_object=None, _attributes={}, **_arguments):
+        """quit: Quit an application
+        Keyword argument saving: specifies whether to save currently open documents
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'aevt'
+        _subcode = 'quit'
+
+        aetools.keysubst(_arguments, self._argmap_quit)
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+        aetools.enumsubst(_arguments, 'savo', _Enum_savo)
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                        _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_close = {
+            'saving' : 'savo',
+            'saving_in' : 'kfil',
+    }
+
+_Enum_savo = {
+        'yes' : 'yes ', # Save objects now
+        'no' : 'no      ',      # Do not save objects
+        'ask' : 'ask ', # Ask the user whether to save
+}
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+}
+
+_propdeclarations = {
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+        'savo' : _Enum_savo,
+}

Added: vendor/Python/current/Lib/plat-mac/macerrors.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/macerrors.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/macerrors.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1852 @@
+svTempDisable   =   -32768  #svTempDisable
+svDisabled  =   -32640  #Reserve range -32640 to -32768 for Apple temp disables.
+fontNotOutlineErr   =   -32615  #bitmap font passed to routine that does outlines only
+kURL68kNotSupportedError    =   -30788  #kURL68kNotSupportedError
+kURLAccessNotAvailableError =   -30787  #kURLAccessNotAvailableError
+kURLInvalidConfigurationError   =   -30786  #kURLInvalidConfigurationError
+kURLExtensionFailureError   =   -30785  #kURLExtensionFailureError
+kURLFileEmptyError  =   -30783  #kURLFileEmptyError
+kURLInvalidCallError    =   -30781  #kURLInvalidCallError
+kURLUnsettablePropertyError =   -30780  #kURLUnsettablePropertyError
+kURLPropertyBufferTooSmallError =   -30779  #kURLPropertyBufferTooSmallError
+kURLUnknownPropertyError    =   -30778  #kURLUnknownPropertyError
+kURLPropertyNotYetKnownError    =   -30777  #kURLPropertyNotYetKnownError
+kURLAuthenticationError =   -30776  #kURLAuthenticationError
+kURLServerBusyError =   -30775  #kURLServerBusyError
+kURLUnsupportedSchemeError  =   -30774  #kURLUnsupportedSchemeError
+kURLInvalidURLError =   -30773  #kURLInvalidURLError
+kURLDestinationExistsError  =   -30772  #kURLDestinationExistsError
+kURLProgressAlreadyDisplayedError   =   -30771  #kURLProgressAlreadyDisplayedError
+kURLInvalidURLReferenceError    =   -30770  #kURLInvalidURLReferenceError
+controlHandleInvalidErr =   -30599  #controlHandleInvalidErr
+controlInvalidDataVersionErr    =   -30597  #controlInvalidDataVersionErr
+errItemNotControl   =   -30596  #errItemNotControl
+errCantEmbedRoot    =   -30595  #errCantEmbedRoot
+errCantEmbedIntoSelf    =   -30594  #errCantEmbedIntoSelf
+errWindowRegionCodeInvalid  =   -30593  #errWindowRegionCodeInvalid
+errControlHiddenOrDisabled  =   -30592  #errControlHiddenOrDisabled
+errDataSizeMismatch =   -30591  #errDataSizeMismatch
+errControlIsNotEmbedder =   -30590  #errControlIsNotEmbedder
+errControlsAlreadyExist =   -30589  #errControlsAlreadyExist
+errInvalidPartCode  =   -30588  #errInvalidPartCode
+errRootAlreadyExists    =   -30587  #errRootAlreadyExists
+errNoRootControl    =   -30586  #errNoRootControl
+errCouldntSetFocus  =   -30585  #errCouldntSetFocus
+errUnknownControl   =   -30584  #errUnknownControl
+errWindowDoesntSupportFocus =   -30583  #errWindowDoesntSupportFocus
+errControlDoesntSupportFocus    =   -30582  #errControlDoesntSupportFocus
+errDataNotSupported =   -30581  #errDataNotSupported
+errMessageNotSupported  =   -30580  #errMessageNotSupported
+themeMonitorDepthNotSupportedErr    =   -30567  #theme not supported at monitor depth
+themeScriptFontNotFoundErr  =   -30566  #theme font requested for uninstalled script system
+themeBadCursorIndexErr  =   -30565  #themeBadCursorIndexErr
+themeHasNoAccentsErr    =   -30564  #themeHasNoAccentsErr
+themeBadTextColorErr    =   -30563  #themeBadTextColorErr
+themeProcessNotRegisteredErr    =   -30562  #themeProcessNotRegisteredErr
+themeProcessRegisteredErr   =   -30561  #themeProcessRegisteredErr
+themeInvalidBrushErr    =   -30560  #pattern index invalid
+qtvrUninitialized   =   -30555  #qtvrUninitialized
+qtvrLibraryLoadErr  =   -30554  #qtvrLibraryLoadErr
+streamingNodeNotReadyErr    =   -30553  #streamingNodeNotReadyErr
+noMemoryNodeFailedInitialize    =   -30552  #noMemoryNodeFailedInitialize
+invalidHotSpotIDErr =   -30551  #invalidHotSpotIDErr
+invalidNodeFormatErr    =   -30550  #invalidNodeFormatErr
+limitReachedErr =   -30549  #limitReachedErr
+settingNotSupportedByNodeErr    =   -30548  #settingNotSupportedByNodeErr
+propertyNotSupportedByNodeErr   =   -30547  #propertyNotSupportedByNodeErr
+timeNotInViewErr    =   -30546  #timeNotInViewErr
+invalidViewStateErr =   -30545  #invalidViewStateErr
+invalidNodeIDErr    =   -30544  #invalidNodeIDErr
+selectorNotSupportedByNodeErr   =   -30543  #selectorNotSupportedByNodeErr
+callNotSupportedByNodeErr   =   -30542  #callNotSupportedByNodeErr
+constraintReachedErr    =   -30541  #constraintReachedErr
+notAQTVRMovieErr    =   -30540  #notAQTVRMovieErr
+kFBCnoSuchHit   =   -30532  #kFBCnoSuchHit
+kFBCbadSearchSession    =   -30531  #kFBCbadSearchSession
+kFBCindexDiskIOFailed   =   -30530  #kFBCindexDiskIOFailed
+kFBCsummarizationCanceled   =   -30529  #kFBCsummarizationCanceled
+kFBCbadIndexFileVersion =   -30528  #kFBCbadIndexFileVersion
+kFBCanalysisNotAvailable    =   -30527  #kFBCanalysisNotAvailable
+kFBCillegalSessionChange    =   -30526  #tried to add/remove vols to a session
+kFBCsomeFilesNotIndexed =   -30525  #kFBCsomeFilesNotIndexed
+kFBCsearchFailed    =   -30524  #kFBCsearchFailed
+kFBCindexNotAvailable   =   -30523  #kFBCindexNotAvailable
+kFBCindexFileDestroyed  =   -30522  #kFBCindexFileDestroyed
+kFBCaccessCanceled  =   -30521  #kFBCaccessCanceled
+kFBCindexingCanceled    =   -30520  #kFBCindexingCanceled
+kFBCnoSearchSession =   -30519  #kFBCnoSearchSession
+kFBCindexNotFound   =   -30518  #kFBCindexNotFound
+kFBCflushFailed =   -30517  #kFBCflushFailed
+kFBCaddDocFailed    =   -30516  #kFBCaddDocFailed
+kFBCaccessorStoreFailed =   -30515  #kFBCaccessorStoreFailed
+kFBCindexCreationFailed =   -30514  #couldn't create index
+kFBCmergingFailed   =   -30513  #couldn't merge index files
+kFBCtokenizationFailed  =   -30512  #couldn't read from document or query
+kFBCmoveFailed  =   -30511  #V-Twin exception caught
+kFBCdeletionFailed  =   -30510  #V-Twin exception caught
+kFBCcommitFailed    =   -30509  #V-Twin exception caught
+kFBCindexingFailed  =   -30508  #V-Twin exception caught
+kFBCvalidationFailed    =   -30507  #V-Twin exception caught
+kFBCcompactionFailed    =   -30506  #V-Twin exception caught
+kFBCbadIndexFile    =   -30505  #bad FSSpec, or bad data in file
+kFBCfileNotIndexed  =   -30504  #kFBCfileNotIndexed
+kFBCbadParam    =   -30503  #kFBCbadParam
+kFBCallocFailed =   -30502  #probably low memory
+kFBCnoIndexesFound  =   -30501  #kFBCnoIndexesFound
+kFBCvTwinExceptionErr   =   -30500  #no telling what it was
+kDSpStereoContextErr    =   -30450  #kDSpStereoContextErr
+kDSpInternalErr =   -30449  #kDSpInternalErr
+kDSpConfirmSwitchWarning    =   -30448  #kDSpConfirmSwitchWarning
+kDSpFrameRateNotReadyErr    =   -30447  #kDSpFrameRateNotReadyErr
+kDSpContextNotFoundErr  =   -30446  #kDSpContextNotFoundErr
+kDSpContextNotReservedErr   =   -30445  #kDSpContextNotReservedErr
+kDSpContextAlreadyReservedErr   =   -30444  #kDSpContextAlreadyReservedErr
+kDSpInvalidAttributesErr    =   -30443  #kDSpInvalidAttributesErr
+kDSpInvalidContextErr   =   -30442  #kDSpInvalidContextErr
+kDSpSystemSWTooOldErr   =   -30441  #kDSpSystemSWTooOldErr
+kDSpNotInitializedErr   =   -30440  #kDSpNotInitializedErr
+kISpListBusyErr =   -30429  #kISpListBusyErr
+kISpDeviceActiveErr =   -30428  #kISpDeviceActiveErr
+kISpSystemActiveErr =   -30427  #kISpSystemActiveErr
+kISpDeviceInactiveErr   =   -30426  #kISpDeviceInactiveErr
+kISpSystemInactiveErr   =   -30425  #kISpSystemInactiveErr
+kISpElementNotInListErr =   -30424  #kISpElementNotInListErr
+kISpElementInListErr    =   -30423  #kISpElementInListErr
+kISpBufferToSmallErr    =   -30422  #kISpBufferToSmallErr
+kISpSystemListErr   =   -30421  #kISpSystemListErr
+kISpInternalErr =   -30420  #kISpInternalErr
+kNSpJoinFailedErr   =   -30399  #kNSpJoinFailedErr
+kNSpCantBlockErr    =   -30398  #kNSpCantBlockErr
+kNSpMessageTooBigErr    =   -30397  #kNSpMessageTooBigErr
+kNSpSendFailedErr   =   -30396  #kNSpSendFailedErr
+kNSpConnectFailedErr    =   -30395  #kNSpConnectFailedErr
+kNSpGameTerminatedErr   =   -30394  #kNSpGameTerminatedErr
+kNSpTimeoutErr  =   -30393  #kNSpTimeoutErr
+kNSpInvalidProtocolListErr  =   -30392  #kNSpInvalidProtocolListErr
+kNSpInvalidProtocolRefErr   =   -30391  #kNSpInvalidProtocolRefErr
+kNSpInvalidDefinitionErr    =   -30390  #kNSpInvalidDefinitionErr
+kNSpAddPlayerFailedErr  =   -30389  #kNSpAddPlayerFailedErr
+kNSpCreateGroupFailedErr    =   -30388  #kNSpCreateGroupFailedErr
+kNSpNoHostVolunteersErr =   -30387  #kNSpNoHostVolunteersErr
+kNSpNoGroupsErr =   -30386  #kNSpNoGroupsErr
+kNSpNoPlayersErr    =   -30385  #kNSpNoPlayersErr
+kNSpInvalidGroupIDErr   =   -30384  #kNSpInvalidGroupIDErr
+kNSpInvalidPlayerIDErr  =   -30383  #kNSpInvalidPlayerIDErr
+kNSpNameRequiredErr =   -30382  #kNSpNameRequiredErr
+kNSpFeatureNotImplementedErr    =   -30381  #kNSpFeatureNotImplementedErr
+kNSpAddressInUseErr =   -30380  #kNSpAddressInUseErr
+kNSpRemovePlayerFailedErr   =   -30379  #kNSpRemovePlayerFailedErr
+kNSpFreeQExhaustedErr   =   -30378  #kNSpFreeQExhaustedErr
+kNSpInvalidAddressErr   =   -30377  #kNSpInvalidAddressErr
+kNSpNotAdvertisingErr   =   -30376  #kNSpNotAdvertisingErr
+kNSpAlreadyAdvertisingErr   =   -30374  #kNSpAlreadyAdvertisingErr
+kNSpMemAllocationErr    =   -30373  #kNSpMemAllocationErr
+kNSpOTVersionTooOldErr  =   -30371  #kNSpOTVersionTooOldErr
+kNSpOTNotPresentErr =   -30370  #kNSpOTNotPresentErr
+kNSpInvalidParameterErr =   -30369  #kNSpInvalidParameterErr
+kNSpInvalidGameRefErr   =   -30367  #kNSpInvalidGameRefErr
+kNSpProtocolNotAvailableErr =   -30366  #kNSpProtocolNotAvailableErr
+kNSpHostFailedErr   =   -30365  #kNSpHostFailedErr
+kNSpPipeFullErr =   -30364  #kNSpPipeFullErr
+kNSpTopologyNotSupportedErr =   -30362  #kNSpTopologyNotSupportedErr
+kNSpAlreadyInitializedErr   =   -30361  #kNSpAlreadyInitializedErr
+kNSpInitializationFailedErr =   -30360  #kNSpInitializationFailedErr
+kSSpScaleToZeroErr  =   -30344  #kSSpScaleToZeroErr
+kSSpParallelUpVectorErr =   -30343  #kSSpParallelUpVectorErr
+kSSpCantInstallErr  =   -30342  #kSSpCantInstallErr
+kSSpVersionErr  =   -30341  #kSSpVersionErr
+kSSpInternalErr =   -30340  #kSSpInternalErr
+kALMInternalErr =   -30049  #kALMInternalErr
+kALMGroupNotFoundErr    =   -30048  #kALMGroupNotFoundErr
+kALMNoSuchModuleErr =   -30047  #kALMNoSuchModuleErr
+kALMModuleCommunicationErr  =   -30046  #kALMModuleCommunicationErr
+kALMDuplicateModuleErr  =   -30045  #kALMDuplicateModuleErr
+kALMInstallationErr =   -30044  #kALMInstallationErr
+kALMDeferSwitchErr  =   -30043  #kALMDeferSwitchErr
+kALMRebootFlagsLevelErr =   -30042  #kALMRebootFlagsLevelErr
+kLocalesDefaultDisplayStatus    =   -30029  #Requested display locale unavailable, used default
+kLocalesTableFormatErr  =   -30002  #kLocalesTableFormatErr
+kLocalesBufferTooSmallErr   =   -30001  #kLocalesBufferTooSmallErr
+kFNSNameNotFoundErr =   -29589  #The name with the requested paramters was not found
+kFNSBadFlattenedSizeErr =   -29587  #flattened size didn't match input or was too small
+kFNSInsufficientDataErr =   -29586  #insufficient data for the operation
+kFNSMismatchErr =   -29585  #reference didn't match or wasn't found in profile
+kFNSDuplicateReferenceErr   =   -29584  #the ref. being added is already in the profile
+kFNSBadProfileVersionErr    =   -29583  #profile version is out of known range
+kFNSInvalidProfileErr   =   -29582  #profile is NULL or otherwise bad
+kFNSBadReferenceVersionErr  =   -29581  #ref. version is out of known range
+kFNSInvalidReferenceErr =   -29580  #ref. was NULL or otherwise bad
+kCollateInvalidCollationRef =   -29507  #kCollateInvalidCollationRef
+kCollateBufferTooSmall  =   -29506  #kCollateBufferTooSmall
+kCollateInvalidChar =   -29505  #kCollateInvalidChar
+kCollatePatternNotFoundErr  =   -29504  #kCollatePatternNotFoundErr
+kCollateUnicodeConvertFailedErr =   -29503  #kCollateUnicodeConvertFailedErr
+kCollateMissingUnicodeTableErr  =   -29502  #kCollateMissingUnicodeTableErr
+kCollateInvalidOptions  =   -29501  #kCollateInvalidOptions
+kCollateAttributesNotFoundErr   =   -29500  #kCollateAttributesNotFoundErr
+kMPInvalidIDErr =   -29299  #kMPInvalidIDErr
+kMPInsufficientResourcesErr =   -29298  #kMPInsufficientResourcesErr
+kMPTaskAbortedErr   =   -29297  #kMPTaskAbortedErr
+kMPTimeoutErr   =   -29296  #kMPTimeoutErr
+kMPDeletedErr   =   -29295  #kMPDeletedErr
+kMPBlueBlockingErr  =   -29293  #kMPBlueBlockingErr
+kMPTaskStoppedErr   =   -29292  #A convention used with MPThrowException.
+kMPTaskBlockedErr   =   -29291  #kMPTaskBlockedErr
+kMPTaskCreatedErr   =   -29290  #kMPTaskCreatedErr
+kMPProcessTerminatedErr =   -29289  #kMPProcessTerminatedErr
+kMPProcessCreatedErr    =   -29288  #kMPProcessCreatedErr
+kMPPrivilegedErr    =   -29276  #kMPPrivilegedErr
+kMPIterationEndErr  =   -29275  #kMPIterationEndErr
+kUCTextBreakLocatorMissingType  =   -25341  #Unicode text break error
+kUCOutputBufferTooSmall =   -25340  #Output buffer too small for Unicode string result
+errKCCreateChainFailed  =   -25318  #errKCCreateChainFailed
+errKCDataNotModifiable  =   -25317  #errKCDataNotModifiable
+errKCDataNotAvailable   =   -25316  #errKCDataNotAvailable
+errKCInteractionRequired    =   -25315  #errKCInteractionRequired
+errKCNoPolicyModule =   -25314  #errKCNoPolicyModule
+errKCNoCertificateModule    =   -25313  #errKCNoCertificateModule
+errKCNoStorageModule    =   -25312  #errKCNoStorageModule
+errKCKeySizeNotAllowed  =   -25311  #errKCKeySizeNotAllowed
+errKCWrongKCVersion =   -25310  #errKCWrongKCVersion
+errKCReadOnlyAttr   =   -25309  #errKCReadOnlyAttr
+errKCInteractionNotAllowed  =   -25308  #errKCInteractionNotAllowed
+errKCNoDefaultKeychain  =   -25307  #errKCNoDefaultKeychain
+errKCNoSuchClass    =   -25306  #errKCNoSuchClass
+errKCInvalidSearchRef   =   -25305  #errKCInvalidSearchRef
+errKCInvalidItemRef =   -25304  #errKCInvalidItemRef
+errKCNoSuchAttr =   -25303  #errKCNoSuchAttr
+errKCDataTooLarge   =   -25302  #errKCDataTooLarge
+errKCBufferTooSmall =   -25301  #errKCBufferTooSmall
+errKCItemNotFound   =   -25300  #errKCItemNotFound
+errKCDuplicateItem  =   -25299  #errKCDuplicateItem
+errKCInvalidCallback    =   -25298  #errKCInvalidCallback
+errKCDuplicateCallback  =   -25297  #errKCDuplicateCallback
+errKCDuplicateKeychain  =   -25296  #errKCDuplicateKeychain
+errKCInvalidKeychain    =   -25295  #errKCInvalidKeychain
+errKCNoSuchKeychain =   -25294  #errKCNoSuchKeychain
+errKCAuthFailed =   -25293  #errKCAuthFailed
+errKCReadOnly   =   -25292  #errKCReadOnly
+errKCNotAvailable   =   -25291  #errKCNotAvailable
+printerStatusOpCodeNotSupportedErr  =   -25280  #printerStatusOpCodeNotSupportedErr
+kTXNOutsideOfFrameErr   =   -22018  #kTXNOutsideOfFrameErr
+kTXNOutsideOfLineErr    =   -22017  #kTXNOutsideOfLineErr
+kTXNATSUIIsNotInstalledErr  =   -22016  #kTXNATSUIIsNotInstalledErr
+kTXNDataTypeNotAllowedErr   =   -22015  #kTXNDataTypeNotAllowedErr
+kTXNCopyNotAllowedInEchoModeErr =   -22014  #kTXNCopyNotAllowedInEchoModeErr
+kTXNCannotTurnTSMOffWhenUsingUnicodeErr =   -22013  #kTXNCannotTurnTSMOffWhenUsingUnicodeErr
+kTXNAlreadyInitializedErr   =   -22012  #kTXNAlreadyInitializedErr
+kTXNInvalidRunIndex =   -22011  #kTXNInvalidRunIndex
+kTXNSomeOrAllTagsInvalidForRunErr   =   -22010  #kTXNSomeOrAllTagsInvalidForRunErr
+kTXNAttributeTagInvalidForRunErr    =   -22009  #dataValue is set to this per invalid tag
+kTXNNoMatchErr  =   -22008  #kTXNNoMatchErr
+kTXNRunIndexOutofBoundsErr  =   -22007  #kTXNRunIndexOutofBoundsErr
+kTXNCannotSetAutoIndentErr  =   -22006  #kTXNCannotSetAutoIndentErr
+kTXNBadDefaultFileTypeWarning   =   -22005  #kTXNBadDefaultFileTypeWarning
+kTXNUserCanceledOperationErr    =   -22004  #kTXNUserCanceledOperationErr
+kTXNIllegalToCrossDataBoundariesErr =   -22003  #kTXNIllegalToCrossDataBoundariesErr
+kTXNInvalidFrameIDErr   =   -22002  #kTXNInvalidFrameIDErr
+kTXNCannotAddFrameErr   =   -22001  #kTXNCannotAddFrameErr
+kTXNEndIterationErr =   -22000  #kTXNEndIterationErr
+invalidIndexErr =   -20002  #The recordIndex parameter is not valid.
+recordDataTooBigErr =   -20001  #The record data is bigger than buffer size (1024 bytes).
+unknownInsertModeErr    =   -20000  #There is no such an insert mode.
+kModemScriptMissing =   -14002  #kModemScriptMissing
+kModemPreferencesMissing    =   -14001  #kModemPreferencesMissing
+kModemOutOfMemory   =   -14000  #kModemOutOfMemory
+kHIDBaseError   =   -13950  #kHIDBaseError
+kHIDNullStateErr    =   -13949  #kHIDNullStateErr
+kHIDBufferTooSmallErr   =   -13948  #kHIDBufferTooSmallErr
+kHIDValueOutOfRangeErr  =   -13947  #kHIDValueOutOfRangeErr
+kHIDUsageNotFoundErr    =   -13946  #kHIDUsageNotFoundErr
+kHIDNotValueArrayErr    =   -13945  #kHIDNotValueArrayErr
+kHIDInvalidPreparsedDataErr =   -13944  #kHIDInvalidPreparsedDataErr
+kHIDIncompatibleReportErr   =   -13943  #kHIDIncompatibleReportErr
+kHIDBadLogPhysValuesErr =   -13942  #kHIDBadLogPhysValuesErr
+kHIDInvalidReportTypeErr    =   -13941  #kHIDInvalidReportTypeErr
+kHIDInvalidReportLengthErr  =   -13940  #kHIDInvalidReportLengthErr
+kHIDNullPointerErr  =   -13939  #kHIDNullPointerErr
+kHIDBadParameterErr =   -13938  #kHIDBadParameterErr
+kHIDNotEnoughMemoryErr  =   -13937  #kHIDNotEnoughMemoryErr
+kHIDEndOfDescriptorErr  =   -13936  #kHIDEndOfDescriptorErr
+kHIDUsagePageZeroErr    =   -13935  #kHIDUsagePageZeroErr
+kHIDBadLogicalMinimumErr    =   -13934  #kHIDBadLogicalMinimumErr
+kHIDBadLogicalMaximumErr    =   -13933  #kHIDBadLogicalMaximumErr
+kHIDInvertedLogicalRangeErr =   -13932  #kHIDInvertedLogicalRangeErr
+kHIDInvertedPhysicalRangeErr    =   -13931  #kHIDInvertedPhysicalRangeErr
+kHIDUnmatchedUsageRangeErr  =   -13930  #kHIDUnmatchedUsageRangeErr
+kHIDInvertedUsageRangeErr   =   -13929  #kHIDInvertedUsageRangeErr
+kHIDUnmatchedStringRangeErr =   -13928  #kHIDUnmatchedStringRangeErr
+kHIDUnmatchedDesignatorRangeErr =   -13927  #kHIDUnmatchedDesignatorRangeErr
+kHIDReportSizeZeroErr   =   -13926  #kHIDReportSizeZeroErr
+kHIDReportCountZeroErr  =   -13925  #kHIDReportCountZeroErr
+kHIDReportIDZeroErr =   -13924  #kHIDReportIDZeroErr
+kHIDInvalidRangePageErr =   -13923  #kHIDInvalidRangePageErr
+kHIDDeviceNotReady  =   -13910  #The device is still initializing, try again later
+kHIDVersionIncompatibleErr  =   -13909  #kHIDVersionIncompatibleErr
+debuggingNoMatchErr =   -13887  #debugging component or option not found at this index
+debuggingNoCallbackErr  =   -13886  #debugging component has no callback
+debuggingInvalidNameErr =   -13885  #componentName or optionName is invalid (NULL)
+debuggingInvalidOptionErr   =   -13884  #optionSelectorNum is not registered
+debuggingInvalidSignatureErr    =   -13883  #componentSignature not registered
+debuggingDuplicateOptionErr =   -13882  #optionSelectorNum already registered
+debuggingDuplicateSignatureErr  =   -13881  #componentSignature already registered
+debuggingExecutionContextErr    =   -13880  #routine cannot be called at this time
+kBridgeSoftwareRunningCantSleep =   -13038  #kBridgeSoftwareRunningCantSleep
+kNoSuchPowerSource  =   -13020  #kNoSuchPowerSource
+kProcessorTempRoutineRequiresMPLib2 =   -13014  #kProcessorTempRoutineRequiresMPLib2
+kCantReportProcessorTemperatureErr  =   -13013  #kCantReportProcessorTemperatureErr
+kPowerMgtRequestDenied  =   -13010  #kPowerMgtRequestDenied
+kPowerMgtMessageNotHandled  =   -13009  #kPowerMgtMessageNotHandled
+kPowerHandlerNotFoundForProcErr =   -13008  #kPowerHandlerNotFoundForProcErr
+kPowerHandlerNotFoundForDeviceErr   =   -13007  #kPowerHandlerNotFoundForDeviceErr
+kPowerHandlerExistsForDeviceErr =   -13006  #kPowerHandlerExistsForDeviceErr
+pmRecvEndErr    =   -13005  #during receive, pmgr did not finish hs configured for this connection
+pmRecvStartErr  =   -13004  #during receive, pmgr did not start hs
+pmSendEndErr    =   -13003  #during send, pmgr did not finish hs
+pmSendStartErr  =   -13002  #during send, pmgr did not start hs
+pmReplyTOErr    =   -13001  #Timed out waiting for reply
+pmBusyErr   =   -13000  #Power Mgr never ready to start handshake
+pictureDataErr  =   -11005  #the picture data was invalid
+colorsRequestedErr  =   -11004  #the number of colors requested was illegal
+cantLoadPickMethodErr   =   -11003  #unable to load the custom pick proc
+pictInfoVerbErr =   -11002  #the passed verb was invalid
+pictInfoIDErr   =   -11001  #the internal consistancy check for the PictInfoID is wrong
+pictInfoVersionErr  =   -11000  #wrong version of the PictInfo structure
+errTaskNotFound =   -10780  #no task with that task id exists
+telNotEnoughdspBW   =   -10116  #not enough real-time for allocation
+telBadSampleRate    =   -10115  #incompatible sample rate
+telBadSWErr =   -10114  #Software not installed properly
+telDetAlreadyOn =   -10113  #detection is already turned on
+telAutoAnsNotOn =   -10112  #autoAnswer in not turned on
+telValidateFailed   =   -10111  #telValidate failed
+telBadProcID    =   -10110  #invalid procID
+telDeviceNotFound   =   -10109  #device not found
+telBadCodeResource  =   -10108  #code resource not found
+telInitFailed   =   -10107  #initialization failed
+telNoCommFolder =   -10106  #Communications/Extensions € not found
+telUnknownErr   =   -10103  #unable to set config
+telNoSuchTool   =   -10102  #unable to find tool with name specified
+telBadFunction  =   -10091  #bad msgCode specified
+telPBErr    =   -10090  #parameter block error, bad format
+telCANotDeflectable =   -10082  #CA not "deflectable"
+telCANotRejectable  =   -10081  #CA not "rejectable"
+telCANotAcceptable  =   -10080  #CA not "acceptable"
+telTermNotOpen  =   -10072  #terminal not opened via TELOpenTerm
+telStillNeeded  =   -10071  #terminal driver still needed by someone else
+telAlreadyOpen  =   -10070  #terminal already open
+telNoCallbackRef    =   -10064  #no call back reference was specified, but is required
+telDisplayModeNotSupp   =   -10063  #display mode not supported by tool
+telBadDisplayMode   =   -10062  #bad display mode specified
+telFwdTypeNotSupp   =   -10061  #forward type not supported by tool
+telDNTypeNotSupp    =   -10060  #DN type not supported by tool
+telBadRate  =   -10059  #bad rate specified
+telBadBearerType    =   -10058  #bad bearerType specified
+telBadSelect    =   -10057  #unable to select or deselect DN
+telBadParkID    =   -10056  #bad park id specified
+telBadPickupGroupID =   -10055  #bad pickup group ID specified
+telBadFwdType   =   -10054  #bad fwdType specified
+telBadFeatureID =   -10053  #bad feature ID specified
+telBadIntercomID    =   -10052  #bad intercom ID specified
+telBadPageID    =   -10051  #bad page ID specified
+telBadDNType    =   -10050  #DN type invalid
+telConfLimitExceeded    =   -10047  #attempt to exceed switch conference limits
+telCBErr    =   -10046  #call back feature not set previously
+telTransferRej  =   -10045  #transfer request rejected
+telTransferErr  =   -10044  #transfer not prepared
+telConfRej  =   -10043  #conference request was rejected
+telConfErr  =   -10042  #conference was not prepared
+telConfNoLimit  =   -10041  #no limit was specified but required
+telConfLimitErr =   -10040  #limit specified is too high for this configuration
+telFeatNotSupp  =   -10033  #feature program call not supported by this tool
+telFeatActive   =   -10032  #feature already active
+telFeatNotAvail =   -10031  #feature subscribed but not available
+telFeatNotSub   =   -10030  #feature not subscribed
+errAEPropertiesClash    =   -10025  #illegal combination of properties settings for Set Data, make new, or duplicate
+errAECantPutThatThere   =   -10024  #in make new, duplicate, etc. class can't be an element of container
+errAENotAnEnumMember    =   -10023  #enumerated value in SetData is not allowed for this property
+telIntExtNotSupp    =   -10022  #internal external type not supported by this tool
+telBadIntExt    =   -10021  #bad internal external error
+telStateNotSupp =   -10020  #device state not supported by tool
+telBadStateErr  =   -10019  #bad device state specified
+telIndexNotSupp =   -10018  #index not supported by this tool
+telBadIndex =   -10017  #bad index specified
+telAPattNotSupp =   -10016  #alerting pattern not supported by tool
+telBadAPattErr  =   -10015  #bad alerting pattern specified
+telVTypeNotSupp =   -10014  #volume type not supported by this tool
+telBadVTypeErr  =   -10013  #bad volume type error
+telBadLevelErr  =   -10012  #bad volume level setting
+telHTypeNotSupp =   -10011  #hook type not supported by this tool
+telBadHTypeErr  =   -10010  #bad hook type specified
+errAECantSupplyType =   -10009  #errAECantSupplyType
+telNoOpenErr    =   -10008  #unable to open terminal
+telNoMemErr =   -10007  #no memory to allocate handle
+errOSACantAssign    =   -10006  #Signaled when an object cannot be set in a container.
+telBadProcErr   =   -10005  #bad msgProc specified
+telBadHandErr   =   -10004  #bad handle specified
+OSAIllegalAssign    =   -10003  #Signaled when an object can never be set in a container
+telBadDNErr =   -10002  #TELDNHandle not found or invalid
+telBadTermErr   =   -10001  #invalid TELHandle or handle not found
+errAEEventFailed    =   -10000  #errAEEventFailed
+cannotMoveAttachedController    =   -9999   #cannotMoveAttachedController
+controllerHasFixedHeight    =   -9998   #controllerHasFixedHeight
+cannotSetWidthOfAttachedController  =   -9997   #cannotSetWidthOfAttachedController
+controllerBoundsNotExact    =   -9996   #controllerBoundsNotExact
+editingNotAllowed   =   -9995   #editingNotAllowed
+badControllerHeight =   -9994   #badControllerHeight
+deviceCantMeetRequest   =   -9408   #deviceCantMeetRequest
+seqGrabInfoNotAvailable =   -9407   #seqGrabInfoNotAvailable
+badSGChannel    =   -9406   #badSGChannel
+couldntGetRequiredComponent =   -9405   #couldntGetRequiredComponent
+notEnoughDiskSpaceToGrab    =   -9404   #notEnoughDiskSpaceToGrab
+notEnoughMemoryToGrab   =   -9403   #notEnoughMemoryToGrab
+cantDoThatInCurrentMode =   -9402   #cantDoThatInCurrentMode
+grabTimeComplete    =   -9401   #grabTimeComplete
+noDeviceForChannel  =   -9400   #noDeviceForChannel
+kNoCardBusCISErr    =   -9109   #No valid CIS exists for this CardBus card
+kNotZVCapableErr    =   -9108   #This socket does not support Zoomed Video
+kCardPowerOffErr    =   -9107   #Power to the card has been turned off
+kAttemptDupCardEntryErr =   -9106   #The Enabler was asked to create a duplicate card entry
+kAlreadySavedStateErr   =   -9105   #The state has been saved on previous call
+kTooManyIOWindowsErr    =   -9104   #device requested more than one I/O window
+kNotReadyErr    =   -9103   #PC Card failed to go ready
+kClientRequestDenied    =   -9102   #CS Clients should return this code inorder to
+kNoCompatibleNameErr    =   -9101   #There is no compatible driver name for this device
+kNoEnablerForCardErr    =   -9100   #No Enablers were found that can support the card
+kNoCardEnablersFoundErr =   -9099   #No Enablers were found
+kUnsupportedCardErr =   -9098   #Card not supported by generic enabler
+kNoClientTableErr   =   -9097   #The client table has not be initialized yet
+kNoMoreInterruptSlotsErr    =   -9096   #All internal Interrupt slots are in use
+kNoMoreTimerClientsErr  =   -9095   #All timer callbacks are in use
+kNoIOWindowRequestedErr =   -9094   #Request I/O window before calling configuration
+kBadCustomIFIDErr   =   -9093   #Custom interface ID is invalid
+kBadTupleDataErr    =   -9092   #Data in tuple is invalid
+kInvalidCSClientErr =   -9091   #Card Services ClientID is not registered
+kUnsupportedVsErr   =   -9090   #Unsupported Voltage Sense
+kInvalidDeviceNumber    =   -9089   #kInvalidDeviceNumber
+kPostCardEventErr   =   -9088   #_PCCSLPostCardEvent failed and dropped an event
+kCantConfigureCardErr   =   -9087   #kCantConfigureCardErr
+kPassCallToChainErr =   -9086   #kPassCallToChainErr
+kCardBusCardErr =   -9085   #kCardBusCardErr
+k16BitCardErr   =   -9084   #k16BitCardErr
+kBadDeviceErr   =   -9083   #kBadDeviceErr
+kBadLinkErr =   -9082   #kBadLinkErr
+kInvalidRegEntryErr =   -9081   #kInvalidRegEntryErr
+kNoCardSevicesSocketsErr    =   -9080   #kNoCardSevicesSocketsErr
+kOutOfResourceErr   =   -9079   #Card Services has exhausted the resource
+kNoMoreItemsErr =   -9078   #there are no more of the requested item
+kInUseErr   =   -9077   #requested resource is being used by a client
+kConfigurationLockedErr =   -9076   #a configuration has already been locked
+kWriteProtectedErr  =   -9075   #media is write-protected
+kBusyErr    =   -9074   #unable to process request at this time - try later
+kUnsupportedModeErr =   -9073   #mode is not supported
+kUnsupportedFunctionErr =   -9072   #function is not supported by this implementation
+kNoCardErr  =   -9071   #no PC card in the socket
+kGeneralFailureErr  =   -9070   #an undefined error has occurred
+kWriteFailureErr    =   -9069   #unable to complete write request
+kReadFailureErr =   -9068   #unable to complete read request
+kBadSpeedErr    =   -9067   #specified speed is unavailable
+kBadCISErr  =   -9066   #CIS on card is invalid
+kBadHandleErr   =   -9065   #clientHandle is invalid
+kBadArgsErr =   -9064   #values in argument packet are invalid
+kBadArgLengthErr    =   -9063   #ArgLength argument is invalid
+kBadWindowErr   =   -9062   #specified window is invalid
+kBadVppErr  =   -9061   #specified Vpp1 or Vpp2 power level index is invalid
+kBadVccErr  =   -9060   #specified Vcc power level index is invalid
+kBadTypeErr =   -9059   #specified window or interface type is invalid
+kBadSocketErr   =   -9058   #specified logical or physical socket number is invalid
+kBadSizeErr =   -9057   #specified size is invalid
+kBadPageErr =   -9056   #specified page is invalid
+kBadOffsetErr   =   -9055   #specified PC card memory array offset is invalid
+kBadIRQErr  =   -9054   #specified IRQ level is invalid
+kBadEDCErr  =   -9053   #specified EDC generator specified is invalid
+kBadBaseErr =   -9052   #specified base system memory address is invalid
+kBadAttributeErr    =   -9051   #specified attributes field value is invalid
+kBadAdapterErr  =   -9050   #invalid adapter number
+codecOffscreenFailedPleaseRetryErr  =   -8992   #codecOffscreenFailedPleaseRetryErr
+lockPortBitsWrongGDeviceErr =   -8991   #lockPortBitsWrongGDeviceErr
+directXObjectAlreadyExists  =   -8990   #directXObjectAlreadyExists
+codecDroppedFrameErr    =   -8989   #returned from ImageCodecDrawBand
+codecOffscreenFailedErr =   -8988   #codecOffscreenFailedErr
+codecNeedAccessKeyErr   =   -8987   #codec needs password in order to decompress
+codecParameterDialogConfirm =   -8986   #codecParameterDialogConfirm
+lockPortBitsSurfaceLostErr  =   -8985   #lockPortBitsSurfaceLostErr
+lockPortBitsBadPortErr  =   -8984   #lockPortBitsBadPortErr
+lockPortBitsWindowClippedErr    =   -8983   #lockPortBitsWindowClippedErr
+lockPortBitsWindowResizedErr    =   -8982   #lockPortBitsWindowResizedErr
+lockPortBitsWindowMovedErr  =   -8981   #lockPortBitsWindowMovedErr
+lockPortBitsBadSurfaceErr   =   -8980   #lockPortBitsBadSurfaceErr
+codecNeedToFlushChainErr    =   -8979   #codecNeedToFlushChainErr
+codecDisabledErr    =   -8978   #codec disabled itself -- pass codecFlagReenable to reset
+codecNoMemoryPleaseWaitErr  =   -8977   #codecNoMemoryPleaseWaitErr
+codecNothingToBlitErr   =   -8976   #codecNothingToBlitErr
+codecCantQueueErr   =   -8975   #codecCantQueueErr
+codecCantWhenErr    =   -8974   #codecCantWhenErr
+codecOpenErr    =   -8973   #codecOpenErr
+codecConditionErr   =   -8972   #codecConditionErr
+codecExtensionNotFoundErr   =   -8971   #codecExtensionNotFoundErr
+codecDataVersErr    =   -8970   #codecDataVersErr
+codecBadDataErr =   -8969   #codecBadDataErr
+codecWouldOffscreenErr  =   -8968   #codecWouldOffscreenErr
+codecAbortErr   =   -8967   #codecAbortErr
+codecSpoolErr   =   -8966   #codecSpoolErr
+codecImageBufErr    =   -8965   #codecImageBufErr
+codecScreenBufErr   =   -8964   #codecScreenBufErr
+codecSizeErr    =   -8963   #codecSizeErr
+codecUnimpErr   =   -8962   #codecUnimpErr
+noCodecErr  =   -8961   #noCodecErr
+codecErr    =   -8960   #codecErr
+kIllegalClockValueErr   =   -8852   #kIllegalClockValueErr
+kUTCOverflowErr =   -8851   #kUTCOverflowErr
+kUTCUnderflowErr    =   -8850   #kUTCUnderflowErr
+kATSULastErr    =   -8809   #The last ATSUI error code.
+kATSULineBreakInWord    =   -8808   #This is not an error code but is returned by ATSUBreakLine to
+kATSUCoordinateOverflowErr  =   -8807   #Used to indicate the coordinates provided to an ATSUI routine caused
+kATSUNoFontScalerAvailableErr   =   -8806   #Used when no font scaler is available for the font passed
+kATSUNoFontCmapAvailableErr =   -8805   #Used when no CMAP table can be accessed or synthesized for the
+kATSULowLevelErr    =   -8804   #Used when an error was encountered within the low level ATS
+kATSUQuickDrawTextErr   =   -8803   #Used when QuickDraw Text encounters an error rendering or measuring
+kATSUNoStyleRunsAssignedErr =   -8802   #Used when an attempt was made to measure, highlight or draw
+kATSUNotSetErr  =   -8801   #Used when the client attempts to retrieve an attribute,
+kATSUInvalidCacheErr    =   -8800   #Used when an attempt was made to read in style data
+kATSUInvalidAttributeTagErr =   -8799   #Used when an attempt was made to use a tag value that
+kATSUInvalidAttributeSizeErr    =   -8798   #Used when an attempt was made to use an attribute with a
+kATSUInvalidAttributeValueErr   =   -8797   #Used when an attempt was made to use an attribute with
+kATSUInvalidFontErr =   -8796   #Used when an attempt was made to use an invalid font ID.
+kATSUNoCorrespondingFontErr =   -8795   #This value is retrned by font ID conversion
+kATSUFontsNotMatched    =   -8794   #This value is returned by ATSUMatchFontsToText()
+kATSUFontsMatched   =   -8793   #This is not an error code but is returned by
+kATSUInvalidTextRangeErr    =   -8792   #An attempt was made to extract information
+kATSUInvalidStyleErr    =   -8791   #An attempt was made to use a ATSUStyle which
+kATSUInvalidTextLayoutErr   =   -8790   #An attempt was made to use a ATSUTextLayout
+kTECOutputBufferFullStatus  =   -8785   #output buffer has no room for conversion of next input text element (partial conversion)
+kTECNeedFlushStatus =   -8784   #kTECNeedFlushStatus
+kTECUsedFallbacksStatus =   -8783   #kTECUsedFallbacksStatus
+kTECItemUnavailableErr  =   -8771   #item (e.g. name) not available for specified region (& encoding if relevant)
+kTECGlobalsUnavailableErr   =   -8770   #globals have already been deallocated (premature TERM)
+unicodeChecksumErr  =   -8769   #unicodeChecksumErr
+unicodeNoTableErr   =   -8768   #unicodeNoTableErr
+unicodeVariantErr   =   -8767   #unicodeVariantErr
+unicodeFallbacksErr =   -8766   #unicodeFallbacksErr
+unicodePartConvertErr   =   -8765   #unicodePartConvertErr
+unicodeBufErr   =   -8764   #unicodeBufErr
+unicodeCharErr  =   -8763   #unicodeCharErr
+unicodeElementErr   =   -8762   #unicodeElementErr
+unicodeNotFoundErr  =   -8761   #unicodeNotFoundErr
+unicodeTableFormatErr   =   -8760   #unicodeTableFormatErr
+unicodeDirectionErr =   -8759   #unicodeDirectionErr
+unicodeContextualErr    =   -8758   #unicodeContextualErr
+unicodeTextEncodingDataErr  =   -8757   #unicodeTextEncodingDataErr
+kTECDirectionErr    =   -8756   #direction stack overflow, etc.
+kTECIncompleteElementErr    =   -8755   #text element may be incomplete or is too long for internal buffers
+kTECUnmappableElementErr    =   -8754   #kTECUnmappableElementErr
+kTECPartialCharErr  =   -8753   #input buffer ends in the middle of a multibyte character, conversion stopped
+kTECBadTextRunErr   =   -8752   #kTECBadTextRunErr
+kTECArrayFullErr    =   -8751   #supplied name buffer or TextRun, TextEncoding, or UnicodeMapping array is too small
+kTECBufferBelowMinimumSizeErr   =   -8750   #output buffer too small to allow processing of first input text element
+kTECNoConversionPathErr =   -8749   #kTECNoConversionPathErr
+kTECCorruptConverterErr =   -8748   #invalid converter object reference
+kTECTableFormatErr  =   -8747   #kTECTableFormatErr
+kTECTableChecksumErr    =   -8746   #kTECTableChecksumErr
+kTECMissingTableErr =   -8745   #kTECMissingTableErr
+kTextUndefinedElementErr    =   -8740   #text conversion errors
+kTextMalformedInputErr  =   -8739   #in DBCS, for example, high byte followed by invalid low byte
+kTextUnsupportedEncodingErr =   -8738   #specified encoding not supported for this operation
+kRANotEnabled   =   -7139   #kRANotEnabled
+kRACallBackFailed   =   -7138   #kRACallBackFailed
+kRADuplicateIPAddr  =   -7137   #kRADuplicateIPAddr
+kRANCPRejectedbyPeer    =   -7136   #kRANCPRejectedbyPeer
+kRAExtAuthenticationFailed  =   -7135   #kRAExtAuthenticationFailed
+kRAATalkInactive    =   -7134   #kRAATalkInactive
+kRAPeerNotResponding    =   -7133   #kRAPeerNotResponding
+kRAPPPPeerDisconnected  =   -7132   #kRAPPPPeerDisconnected
+kRAPPPUserDisconnected  =   -7131   #kRAPPPUserDisconnected
+kRAPPPNegotiationFailed =   -7130   #kRAPPPNegotiationFailed
+kRAPPPAuthenticationFailed  =   -7129   #kRAPPPAuthenticationFailed
+kRAPPPProtocolRejected  =   -7128   #kRAPPPProtocolRejected
+dcmBufferOverflowErr    =   -7127   #data is larger than buffer size
+kRANotPrimaryInterface  =   -7126   #when IPCP is not primary TCP/IP intf.
+kRATCPIPNotConfigured   =   -7125   #TCP/IP not configured, could be loaded
+kRATCPIPInactive    =   -7124   #TCP/IP inactive, cannot be loaded
+kRARemoteAccessNotReady =   -7123   #kRARemoteAccessNotReady
+kRAInitOpenTransportFailed  =   -7122   #kRAInitOpenTransportFailed
+dcmProtectedErr =   -7121   #need keyword to use dictionary
+kRAUserPwdEntryRequired =   -7120   #kRAUserPwdEntryRequired
+kRAUserPwdChangeRequired    =   -7119   #kRAUserPwdChangeRequired
+dcmBadFindMethodErr =   -7118   #no such find method supported
+kRAInvalidSerialProtocol    =   -7117   #kRAInvalidSerialProtocol
+kRAInvalidPortState =   -7116   #kRAInvalidPortState
+dcmBadKeyErr    =   -7115   #bad key information
+kRAPortBusy =   -7114   #kRAPortBusy
+kRAInstallationDamaged  =   -7113   #kRAInstallationDamaged
+dcmBadFieldTypeErr  =   -7112   #no such field type supported
+dcmBadFieldInfoErr  =   -7111   #incomplete information
+dcmNecessaryFieldErr    =   -7110   #lack required/identify field
+dcmDupRecordErr =   -7109   #same record already exist
+kRANotConnected =   -7108   #kRANotConnected
+dcmBlockFullErr =   -7107   #dictionary block full
+kRAMissingResources =   -7106   #kRAMissingResources
+dcmDictionaryBusyErr    =   -7105   #dictionary is busy
+dcmDictionaryNotOpenErr =   -7104   #dictionary not opened
+dcmPermissionErr    =   -7103   #invalid permission
+dcmBadDictionaryErr =   -7102   #invalid dictionary
+dcmNotDictionaryErr =   -7101   #not dictionary
+kRAInvalidParameter =   -7100   #kRAInvalidParameter
+laEngineNotFoundErr =   -7000   #can't find the engine
+laPropertyErr   =   -6999   #Error in properties
+kUSBUnknownDeviceErr    =   -6998   #device ref not recognised
+laPropertyIsReadOnlyErr =   -6997   #the property is read only
+laPropertyUnknownErr    =   -6996   #the property is unknown to this environment
+laPropertyValueErr  =   -6995   #Invalid property value
+laDictionaryTooManyErr  =   -6994   #too many dictionaries
+laDictionaryUnknownErr  =   -6993   #can't use this dictionary with this environment
+laDictionaryNotOpenedErr    =   -6992   #the dictionary is not opened
+laTextOverFlowErr   =   -6991   #text is too long
+laFailAnalysisErr   =   -6990   #analysis failed
+laNoMoreMorphemeErr =   -6989   #nothing to read
+laInvalidPathErr    =   -6988   #path is not correct
+kUSBNotHandled  =   -6987   #Notification was not handled   (same as NotFound)
+laEnvironmentNotFoundErr    =   -6986   #can't fint the specified environment
+laEnvironmentBusyErr    =   -6985   #specified environment is used
+laTooSmallBufferErr =   -6984   #output buffer is too small to store any result
+kUSBFlagsError  =   -6983   #Unused flags not zeroed
+kUSBAbortedError    =   -6982   #Pipe aborted
+kUSBNoBandwidthError    =   -6981   #Not enough bandwidth available
+kUSBPipeIdleError   =   -6980   #Pipe is Idle, it will not accept transactions
+kUSBPipeStalledError    =   -6979   #Pipe has stalled, error needs to be cleared
+kUSBUnknownInterfaceErr =   -6978   #Interface ref not recognised
+kUSBDeviceBusy  =   -6977   #Device is already being configured
+kUSBDevicePowerProblem  =   -6976   #Device has a power problem
+kUSBInvalidBuffer   =   -6975   #bad buffer, usually nil
+kUSBDeviceSuspended =   -6974   #Device is suspended
+kUSBDeviceNotSuspended  =   -6973   #device is not suspended for resume
+kUSBDeviceDisconnected  =   -6972   #Disconnected during suspend or reset
+kUSBTimedOut    =   -6971   #Transaction timed out.
+kUSBQueueAborted    =   -6970   #Pipe zero stall cleared.
+kUSBPortDisabled    =   -6969   #The port you are attached to is disabled, use USBDeviceReset.
+kUSBBadDispatchTable    =   -6950   #Improper driver dispatch table
+kUSBUnknownNotification =   -6949   #Notification type not defined
+kUSBQueueFull   =   -6948   #Internal queue maxxed
+kUSBLinkErr =   -6916   #kUSBLinkErr
+kUSBCRCErr  =   -6915   #Pipe stall, bad CRC
+kUSBBitstufErr  =   -6914   #Pipe stall, bitstuffing
+kUSBDataToggleErr   =   -6913   #Pipe stall, Bad data toggle
+kUSBEndpointStallErr    =   -6912   #Device didn't understand
+kUSBNotRespondingErr    =   -6911   #Pipe stall, No device, device hung
+kUSBPIDCheckErr =   -6910   #Pipe stall, PID CRC error
+kUSBWrongPIDErr =   -6909   #Pipe stall, Bad or wrong PID
+kUSBOverRunErr  =   -6908   #Packet too large or more data than buffer
+kUSBUnderRunErr =   -6907   #Less data than buffer
+kUSBRes1Err =   -6906   #kUSBRes1Err
+kUSBRes2Err =   -6905   #kUSBRes2Err
+kUSBBufOvrRunErr    =   -6904   #Host hardware failure on data in, PCI busy?
+kUSBBufUnderRunErr  =   -6903   #Host hardware failure on data out, PCI busy?
+kUSBNotSent1Err =   -6902   #Transaction not sent
+kUSBNotSent2Err =   -6901   #Transaction not sent
+kDMFoundErr =   -6232   #Did not proceed because we found an item
+kDMMainDisplayCannotMoveErr =   -6231   #Trying to move main display (or a display mirrored to it)
+kDMDisplayAlreadyInstalledErr   =   -6230   #Attempt to add an already installed display.
+kDMDisplayNotFoundErr   =   -6229   #Could not find item (will someday remove).
+kDMDriverNotDisplayMgrAwareErr  =   -6228   #Video Driver does not support display manager.
+kDMSWNotInitializedErr  =   -6227   #Required software not initialized (eg windowmanager or display mgr).
+kSysSWTooOld    =   -6226   #Missing critical pieces of System Software.
+kDMMirroringNotOn   =   -6225   #Returned by all calls that need mirroring to be on to do their thing.
+kDMCantBlock    =   -6224   #Mirroring is already on, canÕt Block now (call DMUnMirror() first).
+kDMMirroringBlocked =   -6223   #DMBlockMirroring() has been called.
+kDMWrongNumberOfDisplays    =   -6222   #Can only handle 2 displays for now.
+kDMMirroringOnAlready   =   -6221   #Returned by all calls that need mirroring to be off to do their thing.
+kDMGenErr   =   -6220   #Unexpected Error
+kQTSSUnknownErr =   -6150   #kQTSSUnknownErr
+collectionVersionErr    =   -5753   #collectionVersionErr
+collectionIndexRangeErr =   -5752   #collectionIndexRangeErr
+collectionItemNotFoundErr   =   -5751   #collectionItemNotFoundErr
+collectionItemLockedErr =   -5750   #collectionItemLockedErr
+kNavMissingKindStringErr    =   -5699   #kNavMissingKindStringErr
+kNavInvalidCustomControlMessageErr  =   -5698   #kNavInvalidCustomControlMessageErr
+kNavCustomControlMessageFailedErr   =   -5697   #kNavCustomControlMessageFailedErr
+kNavInvalidSystemConfigErr  =   -5696   #kNavInvalidSystemConfigErr
+kNavWrongDialogClassErr =   -5695   #kNavWrongDialogClassErr
+kNavWrongDialogStateErr =   -5694   #kNavWrongDialogStateErr
+dialogNoTimeoutErr  =   -5640   #dialogNoTimeoutErr
+menuInvalidErr  =   -5623   #menu is invalid
+menuItemNotFoundErr =   -5622   #specified menu item wasn't found
+menuUsesSystemDefErr    =   -5621   #GetMenuDefinition failed because the menu uses the system MDEF
+menuNotFoundErr =   -5620   #specified menu or menu ID wasn't found
+windowWrongStateErr =   -5615   #window is not in a state that is valid for the current action
+windowManagerInternalErr    =   -5614   #something really weird happened inside the window manager
+windowAttributesConflictErr =   -5613   #passed some attributes that are mutually exclusive
+windowAttributeImmutableErr =   -5612   #tried to change attributes which can't be changed
+errWindowDoesNotFitOnscreen =   -5611   #ConstrainWindowToScreen could not make the window fit onscreen
+errWindowNotFound   =   -5610   #returned from FindWindowOfClass
+errFloatingWindowsNotInitialized    =   -5609   #called HideFloatingWindows or ShowFloatingWindows without calling InitFloatingWindows
+errWindowsAlreadyInitialized    =   -5608   #tried to call InitFloatingWindows twice, or called InitWindows and then floating windows
+errUserWantsToDragWindow    =   -5607   #if returned from TrackWindowProxyDrag, you should call DragWindow on the window
+errCorruptWindowDescription =   -5606   #tried to load a corrupt window description (size or version fields incorrect)
+errUnrecognizedWindowClass  =   -5605   #tried to create a window with a bad WindowClass
+errWindowPropertyNotFound   =   -5604   #tried to get a nonexistent property
+errInvalidWindowProperty    =   -5603   #tried to access a property tag with private creator
+errWindowDoesNotHaveProxy   =   -5602   #tried to do something requiring a proxy to a window which doesnÕt have a proxy
+errUnsupportedWindowAttributesForClass  =   -5601   #tried to create a window with WindowAttributes not supported by the WindowClass
+errInvalidWindowPtr =   -5600   #tried to pass a bad WindowRef argument
+gestaltLocationErr  =   -5553   #gestalt function ptr wasn't in sysheap
+gestaltDupSelectorErr   =   -5552   #tried to add an entry that already existed
+gestaltUndefSelectorErr =   -5551   #undefined selector was passed to Gestalt
+gestaltUnknownErr   =   -5550   #value returned if Gestalt doesn't know the answer
+envVersTooBig   =   -5502   #Version bigger than call can handle
+envBadVers  =   -5501   #Version non-positive
+envNotPresent   =   -5500   #returned by glue.
+qtsAddressBusyErr   =   -5421   #qtsAddressBusyErr
+qtsConnectionFailedErr  =   -5420   #qtsConnectionFailedErr
+qtsTimeoutErr   =   -5408   #qtsTimeoutErr
+qtsUnknownValueErr  =   -5407   #qtsUnknownValueErr
+qtsTooMuchDataErr   =   -5406   #qtsTooMuchDataErr
+qtsUnsupportedFeatureErr    =   -5405   #qtsUnsupportedFeatureErr
+qtsUnsupportedRateErr   =   -5404   #qtsUnsupportedRateErr
+qtsUnsupportedDataTypeErr   =   -5403   #qtsUnsupportedDataTypeErr
+qtsBadDataErr   =   -5402   #something is wrong with the data
+qtsBadStateErr  =   -5401   #qtsBadStateErr
+qtsBadSelectorErr   =   -5400   #qtsBadSelectorErr
+errIAEndOfTextRun   =   -5388   #errIAEndOfTextRun
+errIATextExtractionErr  =   -5387   #errIATextExtractionErr
+errIAInvalidDocument    =   -5386   #errIAInvalidDocument
+errIACanceled   =   -5385   #errIACanceled
+errIABufferTooSmall =   -5384   #errIABufferTooSmall
+errIANoMoreItems    =   -5383   #errIANoMoreItems
+errIAParamErr   =   -5382   #errIAParamErr
+errIAAllocationErr  =   -5381   #errIAAllocationErr
+errIAUnknownErr =   -5380   #errIAUnknownErr
+hrURLNotHandledErr  =   -5363   #hrURLNotHandledErr
+hrUnableToResizeHandleErr   =   -5362   #hrUnableToResizeHandleErr
+hrMiscellaneousExceptionErr =   -5361   #hrMiscellaneousExceptionErr
+hrHTMLRenderingLibNotInstalledErr   =   -5360   #hrHTMLRenderingLibNotInstalledErr
+errCannotUndo   =   -5253   #errCannotUndo
+errNonContiuousAttribute    =   -5252   #errNonContiuousAttribute
+errUnknownElement   =   -5251   #errUnknownElement
+errReadOnlyText =   -5250   #errReadOnlyText
+errEmptyScrap   =   -5249   #errEmptyScrap
+errNoHiliteText =   -5248   #errNoHiliteText
+errOffsetNotOnElementBounday    =   -5247   #errOffsetNotOnElementBounday
+errInvalidRange =   -5246   #errInvalidRange
+errIteratorReachedEnd   =   -5245   #errIteratorReachedEnd
+errEngineNotFound   =   -5244   #errEngineNotFound
+errAlreadyInImagingMode =   -5243   #errAlreadyInImagingMode
+errNotInImagingMode =   -5242   #errNotInImagingMode
+errMarginWilllNotFit    =   -5241   #errMarginWilllNotFit
+errUnknownAttributeTag  =   -5240   #errUnknownAttributeTag
+afpSameNodeErr  =   -5063   #An Attempt was made to connect to a file server running on the same machine
+afpAlreadyMounted   =   -5062   #The volume is already mounted
+afpCantMountMoreSrvre   =   -5061   #The Maximum number of server connections has been reached
+afpBadDirIDType =   -5060   #afpBadDirIDType
+afpCallNotAllowed   =   -5048   #The server knows what you wanted to do, but won't let you do it just now
+afpAlreadyLoggedInErr   =   -5047   #User has been authenticated but is already logged in from another machine (and that's not allowed on this server)
+afpPwdPolicyErr =   -5046   #Password does not conform to servers password policy
+afpPwdNeedsChangeErr    =   -5045   #The password needs to be changed
+afpInsideTrashErr   =   -5044   #The folder being shared is inside the trash folder OR the shared folder is being moved into the trash folder
+afpInsideSharedErr  =   -5043   #The folder being shared is inside a shared folder OR the folder contains a shared folder and is being moved into a shared folder
+afpPwdExpiredErr    =   -5042   #The password being used is too old: this requires the user to change the password before log-in can continue
+afpPwdTooShortErr   =   -5041   #The password being set is too short: there is a minimum length that must be met or exceeded
+afpPwdSameErr   =   -5040   #Someone tried to change their password to the same password on a mantadory password change
+afpBadIDErr =   -5039   #afpBadIDErr
+afpSameObjectErr    =   -5038   #afpSameObjectErr
+afpCatalogChanged   =   -5037   #afpCatalogChanged
+afpDiffVolErr   =   -5036   #afpDiffVolErr
+afpIDExists =   -5035   #afpIDExists
+afpIDNotFound   =   -5034   #afpIDNotFound
+afpContainsSharedErr    =   -5033   #the folder being shared contains a shared folder
+afpObjectLocked =   -5032   #Object is M/R/D/W inhibited
+afpVolLocked    =   -5031   #Volume is Read-Only
+afpIconTypeError    =   -5030   #Icon size specified different from existing icon size
+afpDirNotFound  =   -5029   #Unknown directory specified
+afpCantRename   =   -5028   #AFPRename cannot rename volume
+afpServerGoingDown  =   -5027   #Server is shutting down
+afpTooManyFilesOpen =   -5026   #Maximum open file count reached
+afpObjectTypeErr    =   -5025   #File/Directory specified where Directory/File expected
+afpCallNotSupported =   -5024   #Unsupported AFP call was made
+afpUserNotAuth  =   -5023   #No AFPLogin call has successfully been made for this session
+afpSessClosed   =   -5022   #Session closed
+afpRangeOverlap =   -5021   #Some or all of range already locked by same user
+afpRangeNotLocked   =   -5020   #Tried to unlock range that was not locked by user
+afpParmErr  =   -5019   #A specified parameter was out of allowable range
+afpObjectNotFound   =   -5018   #Specified file or directory does not exist
+afpObjectExists =   -5017   #Specified destination file or directory already exists
+afpNoServer =   -5016   #Server not responding
+afpNoMoreLocks  =   -5015   #Maximum lock limit reached
+afpMiscErr  =   -5014   #Unexpected error encountered during execution
+afpLockErr  =   -5013   #Some or all of requested range is locked by another user
+afpItemNotFound =   -5012   #Unknown UserName/UserID or missing comment/APPL entry
+afpFlatVol  =   -5011   #Cannot create directory on specified volume
+afpFileBusy =   -5010   #Cannot delete an open file
+afpEofError =   -5009   #Read beyond logical end-of-file
+afpDiskFull =   -5008   #Insufficient free space on volume for operation
+afpDirNotEmpty  =   -5007   #Cannot delete non-empty directory
+afpDenyConflict =   -5006   #Specified open/deny modes conflict with current open modes
+afpCantMove =   -5005   #Move destination is offspring of source, or root was specified
+afpBitmapErr    =   -5004   #Bitmap contained bits undefined for call
+afpBadVersNum   =   -5003   #Unknown AFP protocol version number specified
+afpBadUAM   =   -5002   #Unknown user authentication method specified
+afpAuthContinue =   -5001   #Further information required to complete AFPLogin call
+afpAccessDenied =   -5000   #Insufficient access privileges for operation
+illegalScrapFlavorSizeErr   =   -4999   #illegalScrapFlavorSizeErr
+illegalScrapFlavorTypeErr   =   -4998   #illegalScrapFlavorTypeErr
+illegalScrapFlavorFlagsErr  =   -4997   #illegalScrapFlavorFlagsErr
+scrapFlavorSizeMismatchErr  =   -4996   #scrapFlavorSizeMismatchErr
+scrapFlavorFlagsMismatchErr =   -4995   #scrapFlavorFlagsMismatchErr
+nilScrapFlavorDataErr   =   -4994   #nilScrapFlavorDataErr
+noScrapPromiseKeeperErr =   -4993   #noScrapPromiseKeeperErr
+scrapPromiseNotKeptErr  =   -4992   #scrapPromiseNotKeptErr
+processStateIncorrectErr    =   -4991   #processStateIncorrectErr
+badScrapRefErr  =   -4990   #badScrapRefErr
+duplicateScrapFlavorErr =   -4989   #duplicateScrapFlavorErr
+internalScrapErr    =   -4988   #internalScrapErr
+coreFoundationUnknownErr    =   -4960   #coreFoundationUnknownErr
+badRoutingSizeErr   =   -4276   #badRoutingSizeErr
+routingNotFoundErr  =   -4275   #routingNotFoundErr
+duplicateRoutingErr =   -4274   #duplicateRoutingErr
+invalidFolderTypeErr    =   -4273   #invalidFolderTypeErr
+noMoreFolderDescErr =   -4272   #noMoreFolderDescErr
+duplicateFolderDescErr  =   -4271   #duplicateFolderDescErr
+badFolderDescErr    =   -4270   #badFolderDescErr
+cmCantGamutCheckError   =   -4217   #Gammut checking not supported by this ColorWorld
+cmNamedColorNotFound    =   -4216   #NamedColor not found
+cmCantCopyModifiedV1Profile =   -4215   #Illegal to copy version 1 profiles that have been modified
+cmRangeOverFlow =   -4214   #Color conversion warning that some output color values over/underflowed and were clipped
+cmInvalidProfileComment =   -4213   #Bad Profile comment during drawpicture
+cmNoGDevicesError   =   -4212   #Begin/End Matching -- no gdevices available
+cmInvalidDstMap =   -4211   #Destination pix/bit map was invalid
+cmInvalidSrcMap =   -4210   #Source pix/bit map was invalid
+cmInvalidColorSpace =   -4209   #Profile colorspace does not match bitmap type
+cmErrIncompatibleProfile    =   -4208   #Other ColorSync Errors
+cmSearchError   =   -4207   #cmSearchError
+cmInvalidSearch =   -4206   #Bad Search Handle
+cmInvalidProfileLocation    =   -4205   #Operation not supported for this profile location
+cmInvalidProfile    =   -4204   #A Profile must contain a 'cs1 ' tag to be valid
+cmFatalProfileErr   =   -4203   #cmFatalProfileErr
+cmCantDeleteElement =   -4202   #cmCantDeleteElement
+cmIndexRangeErr =   -4201   #Tag index out of range
+kNSLInitializationFailed    =   -4200   #UNABLE TO INITIALIZE THE MANAGER!!!!! DO NOT CONTINUE!!!!
+kNSLNotInitialized  =   -4199   #kNSLNotInitialized
+kNSLInsufficientSysVer  =   -4198   #kNSLInsufficientSysVer
+kNSLInsufficientOTVer   =   -4197   #kNSLInsufficientOTVer
+kNSLNoElementsInList    =   -4196   #kNSLNoElementsInList
+kNSLBadReferenceErr =   -4195   #kNSLBadReferenceErr
+kNSLBadServiceTypeErr   =   -4194   #kNSLBadServiceTypeErr
+kNSLBadDataTypeErr  =   -4193   #kNSLBadDataTypeErr
+kNSLBadNetConnection    =   -4192   #kNSLBadNetConnection
+kNSLNoSupportForService =   -4191   #kNSLNoSupportForService
+kNSLInvalidPluginSpec   =   -4190   #kNSLInvalidPluginSpec
+kNSLRequestBufferAlreadyInList  =   -4189   #kNSLRequestBufferAlreadyInList
+kNSLNoContextAvailable  =   -4188   #(ContinueLookup function ptr invalid)
+kNSLBufferTooSmallForData   =   -4187   #(Client buffer too small for data from plugin)
+kNSLCannotContinueLookup    =   -4186   #(Can't continue lookup; error or bad state)
+kNSLBadClientInfoPtr    =   -4185   #(nil ClientAsyncInfoPtr; no reference available)
+kNSLNullListPtr =   -4184   #(client is trying to add items to a nil list)
+kNSLBadProtocolTypeErr  =   -4183   #(client is trying to add a null protocol type)
+kNSLPluginLoadFailed    =   -4182   #(manager unable to load one of the plugins)
+kNSLNoPluginsFound  =   -4181   #(manager didn't find any valid plugins to load)
+kNSLSearchAlreadyInProgress =   -4180   #(you can only have one ongoing search per clientRef)
+kNSLNoPluginsForSearch  =   -4179   #(no plugins will respond to search request; bad protocol(s)?)
+kNSLNullNeighborhoodPtr =   -4178   #(client passed a null neighborhood ptr)
+kNSLSomePluginsFailedToLoad =   -4177   #(one or more plugins failed to load, but at least one did load; this error isn't fatal)
+kNSLErrNullPtrError =   -4176   #kNSLErrNullPtrError
+kNSLNotImplementedYet   =   -4175   #kNSLNotImplementedYet
+kNSLUILibraryNotAvailable   =   -4174   #The NSL UI Library needs to be in the Extensions Folder
+kNSLNoCarbonLib =   -4173   #kNSLNoCarbonLib
+kNSLBadURLSyntax    =   -4172   #URL contains illegal characters
+kNSLSchedulerError  =   -4171   #A custom thread routine encountered an error
+kNSL68kContextNotSupported  =   -4170   #no 68k allowed
+noHelpForItem   =   -4009   #noHelpForItem
+badProfileError =   -4008   #badProfileError
+colorSyncNotInstalled   =   -4007   #colorSyncNotInstalled
+pickerCantLive  =   -4006   #pickerCantLive
+cantLoadPackage =   -4005   #cantLoadPackage
+cantCreatePickerWindow  =   -4004   #cantCreatePickerWindow
+cantLoadPicker  =   -4003   #cantLoadPicker
+pickerResourceError =   -4002   #pickerResourceError
+requiredFlagsDontMatch  =   -4001   #requiredFlagsDontMatch
+firstPickerError    =   -4000   #firstPickerError
+kOTPortLostConnection   =   -3285   #
+kOTUserRequestedErr =   -3284   #
+kOTConfigurationChangedErr  =   -3283   #
+kOTBadConfigurationErr  =   -3282   #
+kOTPortWasEjectedErr    =   -3281   #
+kOTPortHasDiedErr   =   -3280   #
+kOTClientNotInittedErr  =   -3279   #
+kENOMSGErr  =   -3278   #
+kESRCHErr   =   -3277   #
+kEINPROGRESSErr =   -3276   #
+kENODATAErr =   -3275   #
+kENOSTRErr  =   -3274   #
+kECANCELErr =   -3273   #
+kEBADMSGErr =   -3272   #
+kENOSRErr   =   -3271   #
+kETIMEErr   =   -3270   #
+kEPROTOErr  =   -3269   #‚‚‚ fill out missing codes ‚‚‚
+kEHOSTUNREACHErr    =   -3264   #No route to host
+kEHOSTDOWNErr   =   -3263   #Host is down
+kECONNREFUSEDErr    =   -3260   #Connection refused
+kETIMEDOUTErr   =   -3259   #Connection timed out
+kETOOMANYREFSErr    =   -3258   #Too many references: can't splice
+kESHUTDOWNErr   =   -3257   #Can't send after socket shutdown
+kENOTCONNErr    =   -3256   #Socket is not connected
+kEISCONNErr =   -3255   #Socket is already connected
+kENOBUFSErr =   -3254   #No buffer space available
+kECONNRESETErr  =   -3253   #Connection reset by peer
+kECONNABORTEDErr    =   -3252   #Software caused connection abort
+kENETRESETErr   =   -3251   #Network dropped connection on reset
+kENETUNREACHErr =   -3250   #Network is unreachable
+kENETDOWNErr    =   -3249   #Network is down
+kEADDRNOTAVAILErr   =   -3248   #Can't assign requested address
+kEADDRINUSEErr  =   -3247   #Address already in use
+kEOPNOTSUPPErr  =   -3244   #Operation not supported on socket
+kESOCKTNOSUPPORTErr =   -3243   #Socket type not supported
+kEPROTONOSUPPORTErr =   -3242   #Protocol not supported
+kENOPROTOOPTErr =   -3241   #Protocol not available
+kEPROTOTYPEErr  =   -3240   #Protocol wrong type for socket
+kEMSGSIZEErr    =   -3239   #Message too long
+kEDESTADDRREQErr    =   -3238   #Destination address required
+kENOTSOCKErr    =   -3237   #Socket operation on non-socket
+kEALREADYErr    =   -3236   #
+kEWOULDBLOCKErr =   -3234   #Call would block, so was aborted
+kERANGEErr  =   -3233   #Message size too large for STREAM
+kEPIPEErr   =   -3231   #Broken pipe
+kENOTTYErr  =   -3224   #Not a character device
+kEINVALErr  =   -3221   #Invalid argument
+kENODEVErr  =   -3218   #No such device
+kOTDuplicateFoundErr    =   -3216   #OT generic duplicate found error
+kEBUSYErr   =   -3215   #Device or resource busy
+kEFAULTErr  =   -3213   #Bad address
+kEACCESErr  =   -3212   #Permission denied
+kOTOutOfMemoryErr   =   -3211   #OT ran out of memory, may be a temporary
+kEAGAINErr  =   -3210   #Try operation again later
+kEBADFErr   =   -3208   #Bad file number
+kENXIOErr   =   -3205   #No such device or address
+kEIOErr =   -3204   #I/O error
+kEINTRErr   =   -3203   #Interrupted system service
+kENORSRCErr =   -3202   #No such resource
+kOTNotFoundErr  =   -3201   #OT generic not found error
+kEPERMErr   =   -3200   #Permission denied
+kOTCanceledErr  =   -3180   #XTI2OSStatus(TCANCELED) The command was cancelled
+kOTBadSyncErr   =   -3179   #XTI2OSStatus(TBADSYNC) A synchronous call at interrupt time
+kOTProtocolErr  =   -3178   #XTI2OSStatus(TPROTO) An unspecified provider error occurred
+kOTQFullErr =   -3177   #XTI2OSStatus(TQFULL)
+kOTResAddressErr    =   -3176   #XTI2OSStatus(TRESADDR)
+kOTResQLenErr   =   -3175   #XTI2OSStatus(TRESQLEN)
+kOTProviderMismatchErr  =   -3174   #XTI2OSStatus(TPROVMISMATCH) Tried to accept on incompatible endpoint
+kOTIndOutErr    =   -3173   #XTI2OSStatus(TINDOUT) Accept failed because of pending listen
+kOTAddressBusyErr   =   -3172   #XTI2OSStatus(TADDRBUSY) Address requested is already in use
+kOTBadQLenErr   =   -3171   #XTI2OSStatus(TBADQLEN) A Bind to an in-use addr with qlen > 0
+kOTBadNameErr   =   -3170   #XTI2OSStatus(TBADNAME) A bad endpoint name was supplied
+kOTNoStructureTypeErr   =   -3169   #XTI2OSStatus(TNOSTRUCTYPE) Bad structure type requested for OTAlloc
+kOTStateChangeErr   =   -3168   #XTI2OSStatus(TSTATECHNG) State is changing - try again later
+kOTNotSupportedErr  =   -3167   #XTI2OSStatus(TNOTSUPPORT) Command is not supported
+kOTNoReleaseErr =   -3166   #XTI2OSStatus(TNOREL) No orderly release indication available
+kOTBadFlagErr   =   -3165   #XTI2OSStatus(TBADFLAG) A Bad flag value was supplied
+kOTNoUDErrErr   =   -3164   #XTI2OSStatus(TNOUDERR) No Unit Data Error indication available
+kOTNoDisconnectErr  =   -3163   #XTI2OSStatus(TNODIS) No disconnect indication available
+kOTNoDataErr    =   -3162   #XTI2OSStatus(TNODATA) No data available for reading
+kOTFlowErr  =   -3161   #XTI2OSStatus(TFLOW) Provider is flow-controlled
+kOTBufferOverflowErr    =   -3160   #XTI2OSStatus(TBUFOVFLW) Passed buffer not big enough
+kOTBadDataErr   =   -3159   #XTI2OSStatus(TBADDATA) An illegal amount of data was specified
+kOTLookErr  =   -3158   #XTI2OSStatus(TLOOK) An event occurred - call Look()
+kOTSysErrorErr  =   -3157   #XTI2OSStatus(TSYSERR) A system error occurred
+kOTBadSequenceErr   =   -3156   #XTI2OSStatus(TBADSEQ) Sequence specified does not exist
+kOTOutStateErr  =   -3155   #XTI2OSStatus(TOUTSTATE) Call issued in wrong state
+kOTNoAddressErr =   -3154   #XTI2OSStatus(TNOADDR) No address was specified
+kOTBadReferenceErr  =   -3153   #XTI2OSStatus(TBADF) Bad provider reference
+kOTAccessErr    =   -3152   #XTI2OSStatus(TACCES) Missing access permission
+kOTBadOptionErr =   -3151   #XTI2OSStatus(TBADOPT) A Bad option was specified
+kOTBadAddressErr    =   -3150   #XTI2OSStatus(TBADADDR) A Bad address was specified
+sktClosedErr    =   -3109   #sktClosedErr
+recNotFnd   =   -3108   #recNotFnd
+atpBadRsp   =   -3107   #atpBadRsp
+atpLenErr   =   -3106   #atpLenErr
+readQErr    =   -3105   #readQErr
+extractErr  =   -3104   #extractErr
+ckSumErr    =   -3103   #ckSumErr
+noMPPErr    =   -3102   #noMPPErr
+buf2SmallErr    =   -3101   #buf2SmallErr
+noPrefAppErr    =   -3032   #noPrefAppErr
+badTranslationSpecErr   =   -3031   #badTranslationSpecErr
+noTranslationPathErr    =   -3030   #noTranslationPathErr
+couldNotParseSourceFileErr  =   -3026   #Source document does not contain source type
+invalidTranslationPathErr   =   -3025   #Source type to destination type not a valid path
+retryComponentRegistrationErr   =   -3005   #retryComponentRegistrationErr
+unresolvedComponentDLLErr   =   -3004   #unresolvedComponentDLLErr
+componentDontRegister   =   -3003   #componentDontRegister
+componentNotCaptured    =   -3002   #componentNotCaptured
+validInstancesExist =   -3001   #validInstancesExist
+invalidComponentID  =   -3000   #invalidComponentID
+cfragLastErrCode    =   -2899   #The last value in the range of CFM errors.
+cfragOutputLengthErr    =   -2831   #An output parameter is too small to hold the value.
+cfragAbortClosureErr    =   -2830   #Used by notification handlers to abort a closure.
+cfragClosureIDErr   =   -2829   #The closure ID was not valid.
+cfragContainerIDErr =   -2828   #The fragment container ID was not valid.
+cfragNoRegistrationErr  =   -2827   #The registration name was not found.
+cfragNotClosureErr  =   -2826   #The closure ID was actually a connection ID.
+cfragFileSizeErr    =   -2825   #A file was too large to be mapped.
+cfragFragmentUsageErr   =   -2824   #A semantic error in usage of the fragment.
+cfragArchitectureErr    =   -2823   #A fragment has an unacceptable architecture.
+cfragNoApplicationErr   =   -2822   #No application member found in the cfrg resource.
+cfragInitFunctionErr    =   -2821   #A fragment's initialization routine returned an error.
+cfragFragmentCorruptErr =   -2820   #A fragment's container was corrupt (known format).
+cfragCFMInternalErr =   -2819   #An internal inconstistancy has been detected.
+cfragCFMStartupErr  =   -2818   #Internal error during CFM initialization.
+cfragLibConnErr =   -2817   #
+cfragInitAtBootErr  =   -2816   #A boot library has an initialization function.  (System 7 only)
+cfragInitLoopErr    =   -2815   #Circularity in required initialization order.
+cfragImportTooNewErr    =   -2814   #An import library was too new for a client.
+cfragImportTooOldErr    =   -2813   #An import library was too old for a client.
+cfragInitOrderErr   =   -2812   #
+cfragNoIDsErr   =   -2811   #No more CFM IDs for contexts, connections, etc.
+cfragNoClientMemErr =   -2810   #Out of memory for fragment mapping or section instances.
+cfragNoPrivateMemErr    =   -2809   #Out of memory for internal bookkeeping.
+cfragNoPositionErr  =   -2808   #The registration insertion point was not found.
+cfragUnresolvedErr  =   -2807   #A fragment had "hard" unresolved imports.
+cfragFragmentFormatErr  =   -2806   #A fragment's container format is unknown.
+cfragDupRegistrationErr =   -2805   #The registration name was already in use.
+cfragNoLibraryErr   =   -2804   #The named library was not found.
+cfragNoSectionErr   =   -2803   #The specified section was not found.
+cfragNoSymbolErr    =   -2802   #The specified symbol was not found.
+cfragConnectionIDErr    =   -2801   #The connection ID was not valid.
+cfragFirstErrCode   =   -2800   #The first value in the range of CFM errors.
+errASInconsistentNames  =   -2780   #English errors:
+errASNoResultReturned   =   -2763   #The range -2780 thru -2799 is reserved for dialect specific error codes. (Error codes from different dialects may overlap.)
+errASParameterNotForEvent   =   -2762   #errASParameterNotForEvent
+errASIllegalFormalParameter =   -2761   #errASIllegalFormalParameter
+errASTerminologyNestingTooDeep  =   -2760   #errASTerminologyNestingTooDeep
+OSAControlFlowError =   -2755   #Signaled when illegal control flow occurs in an application (no catcher for throw, non-lexical loop exit, etc.)
+OSAInconsistentDeclarations =   -2754   #Signaled when a variable is declared inconsistently in the same scope, such as both local and global
+OSAUndefinedVariable    =   -2753   #Signaled when a variable is accessed that has no value
+OSADuplicateHandler =   -2752   #Signaled when more than one handler is defined with the same name in a scope where the language doesn't allow it
+OSADuplicateProperty    =   -2751   #Signaled when a formal parameter, local variable, or instance variable is specified more than once.
+OSADuplicateParameter   =   -2750   #Signaled when a formal parameter, local variable, or instance variable is specified more than once
+OSATokenTooLong =   -2742   #Signaled when a name or number is too long to be parsed
+OSASyntaxTypeError  =   -2741   #Signaled when another form of syntax was expected. (e.g. "expected a <type> but found <this>")
+OSASyntaxError  =   -2740   #Signaled when a syntax error occurs. (e.g. "Syntax error" or "<this> can't go after <that>")
+errASCantCompareMoreThan32k =   -2721   #Parser/Compiler errors:
+errASCantConsiderAndIgnore  =   -2720   #errASCantConsiderAndIgnore
+errOSACantCreate    =   -2710   #errOSACantCreate
+errOSACantGetTerminology    =   -2709   #errOSACantGetTerminology
+errOSADataBlockTooLarge =   -2708   #Signaled when an intrinsic limitation is exceeded for the size of a value or data structure.
+errOSAInternalTableOverflow =   -2707   #Signaled when a runtime internal data structure overflows
+errOSAStackOverflow =   -2706   #Signaled when the runtime stack overflows
+errOSACorruptTerminology    =   -2705   #Signaled when an application's terminology resource is not readable
+errOSAAppNotHighLevelEventAware =   -2704   #Signaled when an application can't respond to AppleEvents
+errOSACantLaunch    =   -2703   #Signaled when application can't be launched or when it is remote and program linking is not enabled
+errOSANumericOverflow   =   -2702   #Signaled when integer or real value is too large to be represented
+errOSADivideByZero  =   -2701   #Signaled when there is an attempt to divide by zero
+errOSAGeneralError  =   -2700   #Signaled by user scripts or applications when no actual error code is to be returned.
+noIconDataAvailableErr  =   -2582   #The necessary icon data is not available
+noSuchIconErr   =   -2581   #The requested icon could not be found
+invalidIconRefErr   =   -2580   #The icon ref is not valid
+nrCallNotSupported  =   -2557   #This call is not available or supported on this machine
+nrTransactionAborted    =   -2556   #transaction was aborted
+nrExitedIteratorScope   =   -2555   #outer scope of iterator was exited
+nrIterationDone =   -2554   #iteration operation is done
+nrPropertyAlreadyExists =   -2553   #property already exists
+nrInvalidEntryIterationOp   =   -2552   #invalid entry iteration operation
+nrPathBufferTooSmall    =   -2551   #buffer for path is too small
+nrPathNotFound  =   -2550   #a path component lookup failed
+nrResultCodeBase    =   -2549   #nrResultCodeBase
+nrOverrunErr    =   -2548   #nrOverrunErr
+nrNotModifiedErr    =   -2547   #nrNotModifiedErr
+nrTypeMismatchErr   =   -2546   #nrTypeMismatchErr
+nrPowerSwitchAbortErr   =   -2545   #nrPowerSwitchAbortErr
+nrPowerErr  =   -2544   #nrPowerErr
+nrDataTruncatedErr  =   -2543   #nrDataTruncatedErr
+nrNotSlotDeviceErr  =   -2542   #nrNotSlotDeviceErr
+nrNameErr   =   -2541   #nrNameErr
+nrNotCreatedErr =   -2540   #nrNotCreatedErr
+nrNotFoundErr   =   -2539   #nrNotFoundErr
+nrInvalidNodeErr    =   -2538   #nrInvalidNodeErr
+nrNotEnoughMemoryErr    =   -2537   #nrNotEnoughMemoryErr
+nrLockedErr =   -2536   #nrLockedErr
+mmInternalError =   -2526   #mmInternalError
+tsmDefaultIsNotInputMethodErr   =   -2524   #Current Input source is KCHR or uchr, not Input Method  (GetDefaultInputMethod)
+tsmNoStem   =   -2523   #No stem exists for the token
+tsmNoMoreTokens =   -2522   #No more tokens are available for the source text
+tsmNoHandler    =   -2521   #No Callback Handler exists for callback
+tsmInvalidContext   =   -2520   #Invalid TSMContext specified in call
+tsmUnknownErr   =   -2519   #any other errors
+tsmUnsupportedTypeErr   =   -2518   #unSupported interface type error
+tsmScriptHasNoIMErr =   -2517   #script has no imput method or is using old IM
+tsmInputMethodIsOldErr  =   -2516   #returned by GetDefaultInputMethod
+tsmComponentAlreadyOpenErr  =   -2515   #text service already opened for the document
+tsmTSNotOpenErr =   -2514   #text service is not open
+tsmTSHasNoMenuErr   =   -2513   #the text service has no menu
+tsmUseInputWindowErr    =   -2512   #not TSM aware because we are using input window
+tsmDocumentOpenErr  =   -2511   #there are open documents
+tsmTextServiceNotFoundErr   =   -2510   #no text service found
+tsmCantOpenComponentErr =   -2509   #canÕt open the component
+tsmNoOpenTSErr  =   -2508   #no open text service
+tsmDocNotActiveErr  =   -2507   #document is NOT active
+tsmTSMDocBusyErr    =   -2506   #document is still active
+tsmInvalidDocIDErr  =   -2505   #invalid TSM documentation id
+tsmNeverRegisteredErr   =   -2504   #app never registered error (not TSM aware)
+tsmAlreadyRegisteredErr =   -2503   #want to register again error
+tsmNotAnAppErr  =   -2502   #not an application error
+tsmInputMethodNotFoundErr   =   -2501   #tsmInputMethodNotFoundErr
+tsmUnsupScriptLanguageErr   =   -2500   #tsmUnsupScriptLanguageErr
+kernelUnrecoverableErr  =   -2499   #kernelUnrecoverableErr
+kernelReturnValueErr    =   -2422   #kernelReturnValueErr
+kernelAlreadyFreeErr    =   -2421   #kernelAlreadyFreeErr
+kernelIDErr =   -2419   #kernelIDErr
+kernelExceptionErr  =   -2418   #kernelExceptionErr
+kernelTerminatedErr =   -2417   #kernelTerminatedErr
+kernelInUseErr  =   -2416   #kernelInUseErr
+kernelTimeoutErr    =   -2415   #kernelTimeoutErr
+kernelAsyncReceiveLimitErr  =   -2414   #kernelAsyncReceiveLimitErr
+kernelAsyncSendLimitErr =   -2413   #kernelAsyncSendLimitErr
+kernelAttributeErr  =   -2412   #kernelAttributeErr
+kernelExecutionLevelErr =   -2411   #kernelExecutionLevelErr
+kernelDeletePermissionErr   =   -2410   #kernelDeletePermissionErr
+kernelExecutePermissionErr  =   -2409   #kernelExecutePermissionErr
+kernelReadPermissionErr =   -2408   #kernelReadPermissionErr
+kernelWritePermissionErr    =   -2407   #kernelWritePermissionErr
+kernelObjectExistsErr   =   -2406   #kernelObjectExistsErr
+kernelUnsupportedErr    =   -2405   #kernelUnsupportedErr
+kernelPrivilegeErr  =   -2404   #kernelPrivilegeErr
+kernelOptionsErr    =   -2403   #kernelOptionsErr
+kernelCanceledErr   =   -2402   #kernelCanceledErr
+kernelIncompleteErr =   -2401   #kernelIncompleteErr
+badCallOrderErr =   -2209   #Usually due to a status call being called prior to being setup first
+noDMAErr    =   -2208   #CanÕt do DMA digitizing (i.e. can't go to requested dest
+badDepthErr =   -2207   #CanÕt digitize into this depth
+notExactSizeErr =   -2206   #CanÕt do exact size requested
+noMoreKeyColorsErr  =   -2205   #all key indexes in use
+notExactMatrixErr   =   -2204   #warning of bad matrix, digitizer did its best
+matrixErr   =   -2203   #bad matrix, digitizer did nothing
+qtParamErr  =   -2202   #bad input parameter (out of range, etc)
+digiUnimpErr    =   -2201   #feature unimplemented
+qtXMLApplicationErr =   -2159   #qtXMLApplicationErr
+qtXMLParseErr   =   -2158   #qtXMLParseErr
+qtActionNotHandledErr   =   -2157   #qtActionNotHandledErr
+notEnoughDataErr    =   -2149   #notEnoughDataErr
+urlDataHFTPURLErr   =   -2148   #urlDataHFTPURLErr
+urlDataHFTPServerDisconnectedErr    =   -2147   #urlDataHFTPServerDisconnectedErr
+urlDataHFTPNoPasswordErr    =   -2146   #urlDataHFTPNoPasswordErr
+urlDataHFTPNeedPasswordErr  =   -2145   #urlDataHFTPNeedPasswordErr
+urlDataHFTPBadNameListErr   =   -2144   #urlDataHFTPBadNameListErr
+urlDataHFTPNoNetDriverErr   =   -2143   #urlDataHFTPNoNetDriverErr
+urlDataHFTPFilenameErr  =   -2142   #urlDataHFTPFilenameErr
+urlDataHFTPPermissionsErr   =   -2141   #urlDataHFTPPermissionsErr
+urlDataHFTPQuotaErr =   -2140   #urlDataHFTPQuotaErr
+urlDataHFTPNoDirectoryErr   =   -2139   #urlDataHFTPNoDirectoryErr
+urlDataHFTPDataConnectionErr    =   -2138   #urlDataHFTPDataConnectionErr
+urlDataHFTPServerErr    =   -2137   #urlDataHFTPServerErr
+urlDataHFTPBadPasswordErr   =   -2136   #urlDataHFTPBadPasswordErr
+urlDataHFTPBadUserErr   =   -2135   #urlDataHFTPBadUserErr
+urlDataHFTPShutdownErr  =   -2134   #urlDataHFTPShutdownErr
+urlDataHFTPProtocolErr  =   -2133   #urlDataHFTPProtocolErr
+urlDataHHTTPRedirectErr =   -2132   #urlDataHHTTPRedirectErr
+urlDataHHTTPURLErr  =   -2131   #urlDataHHTTPURLErr
+urlDataHHTTPNoNetDriverErr  =   -2130   #urlDataHHTTPNoNetDriverErr
+urlDataHHTTPProtocolErr =   -2129   #urlDataHHTTPProtocolErr
+qtNetworkAlreadyAllocatedErr    =   -2127   #qtNetworkAlreadyAllocatedErr
+notAllowedToSaveMovieErr    =   -2126   #notAllowedToSaveMovieErr
+fileOffsetTooBigErr =   -2125   #fileOffsetTooBigErr
+ASDEntryNotFoundErr =   -2124   #ASDEntryNotFoundErr
+ASDBadForkErr   =   -2123   #ASDBadForkErr
+ASDBadHeaderErr =   -2122   #ASDBadHeaderErr
+AAPNotFoundErr  =   -2121   #AAPNotFoundErr
+AAPNotCreatedErr    =   -2120   #AAPNotCreatedErr
+qfcbNotCreatedErr   =   -2119   #qfcbNotCreatedErr
+qfcbNotFoundErr =   -2118   #qfcbNotFoundErr
+wackBadMetaDataErr  =   -2117   #wackBadMetaDataErr
+wackForkNotFoundErr =   -2116   #wackForkNotFoundErr
+wackBadFileErr  =   -2115   #wackBadFileErr
+unknownFormatErr    =   -2114   #unknownFormatErr
+pathNotVerifiedErr  =   -2113   #pathNotVerifiedErr
+noPathMappingErr    =   -2112   #noPathMappingErr
+emptyPathErr    =   -2111   #emptyPathErr
+pathTooLongErr  =   -2110   #pathTooLongErr
+cannotBeLeafAtomErr =   -2109   #cannotBeLeafAtomErr
+invalidAtomTypeErr  =   -2108   #invalidAtomTypeErr
+invalidAtomContainerErr =   -2107   #invalidAtomContainerErr
+invalidAtomErr  =   -2106   #invalidAtomErr
+duplicateAtomTypeAndIDErr   =   -2105   #duplicateAtomTypeAndIDErr
+atomIndexInvalidErr =   -2104   #atomIndexInvalidErr
+atomsNotOfSameTypeErr   =   -2103   #atomsNotOfSameTypeErr
+notLeafAtomErr  =   -2102   #notLeafAtomErr
+cannotFindAtomErr   =   -2101   #cannotFindAtomErr
+unsupportedProcessorErr =   -2097   #unsupportedProcessorErr
+unsupportedOSErr    =   -2096   #unsupportedOSErr
+qtmlUninitialized   =   -2095   #qtmlUninitialized
+qtmlDllEntryNotFoundErr =   -2094   #Windows specific errors (when qtml is loading)
+qtmlDllLoadErr  =   -2093   #Windows specific errors (when qtml is loading)
+componentDllEntryNotFoundErr    =   -2092   #Windows specific errors (when component is loading)
+componentDllLoadErr =   -2091   #Windows specific errors (when component is loading)
+videoOutputInUseErr =   -2090   #videoOutputInUseErr
+noExportProcAvailableErr    =   -2089   #noExportProcAvailableErr
+tuneParseOSErr  =   -2087   #tuneParseOSErr
+tunePlayerFullOSErr =   -2086   #tunePlayerFullOSErr
+noteChannelNotAllocatedOSErr    =   -2085   #noteChannelNotAllocatedOSErr
+illegalNoteChannelOSErr =   -2084   #illegalNoteChannelOSErr
+synthesizerOSErr    =   -2083   #synthesizerOSErr
+synthesizerNotRespondingOSErr   =   -2082   #synthesizerNotRespondingOSErr
+midiManagerAbsentOSErr  =   -2081   #midiManagerAbsentOSErr
+illegalControllerOSErr  =   -2080   #illegalControllerOSErr
+illegalInstrumentOSErr  =   -2079   #illegalInstrumentOSErr
+illegalKnobValueOSErr   =   -2078   #illegalKnobValueOSErr
+illegalKnobOSErr    =   -2077   #illegalKnobOSErr
+illegalChannelOSErr =   -2076   #illegalChannelOSErr
+illegalPartOSErr    =   -2075   #illegalPartOSErr
+illegalVoiceAllocationOSErr =   -2074   #illegalVoiceAllocationOSErr
+cantReceiveFromSynthesizerOSErr =   -2073   #cantReceiveFromSynthesizerOSErr
+cantSendToSynthesizerOSErr  =   -2072   #cantSendToSynthesizerOSErr
+notImplementedMusicOSErr    =   -2071   #notImplementedMusicOSErr
+internalComponentErr    =   -2070   #internalComponentErr
+invalidSpriteIDErr  =   -2069   #invalidSpriteIDErr
+invalidImageIndexErr    =   -2068   #invalidImageIndexErr
+invalidSpriteIndexErr   =   -2067   #invalidSpriteIndexErr
+gWorldsNotSameDepthAndSizeErr   =   -2066   #gWorldsNotSameDepthAndSizeErr
+invalidSpritePropertyErr    =   -2065   #invalidSpritePropertyErr
+invalidSpriteWorldPropertyErr   =   -2064   #invalidSpriteWorldPropertyErr
+missingRequiredParameterErr =   -2063   #missingRequiredParameterErr
+movieTextNotFoundErr    =   -2062   #movieTextNotFoundErr
+sourceNotFoundErr   =   -2061   #sourceNotFoundErr
+noSourceTreeFoundErr    =   -2060   #noSourceTreeFoundErr
+samplesAlreadyInMediaErr    =   -2059   #samplesAlreadyInMediaErr
+auxiliaryExportDataUnavailable  =   -2058   #auxiliaryExportDataUnavailable
+unsupportedAuxiliaryImportData  =   -2057   #unsupportedAuxiliaryImportData
+soundSupportNotAvailableErr =   -2056   #QT for Windows error
+noSoundTrackInMovieErr  =   -2055   #QT for Windows error
+noVideoTrackInMovieErr  =   -2054   #QT for Windows error
+featureUnsupported  =   -2053   #featureUnsupported
+couldNotUseAnExistingSample =   -2052   #couldNotUseAnExistingSample
+noDefaultDataRef    =   -2051   #noDefaultDataRef
+badDataRefIndex =   -2050   #badDataRefIndex
+invalidDataRefContainer =   -2049   #invalidDataRefContainer
+noMovieFound    =   -2048   #noMovieFound
+dataNoDataRef   =   -2047   #dataNoDataRef
+endOfDataReached    =   -2046   #endOfDataReached
+dataAlreadyClosed   =   -2045   #dataAlreadyClosed
+dataAlreadyOpenForWrite =   -2044   #dataAlreadyOpenForWrite
+dataNotOpenForWrite =   -2043   #dataNotOpenForWrite
+dataNotOpenForRead  =   -2042   #dataNotOpenForRead
+invalidSampleDescription    =   -2041   #invalidSampleDescription
+invalidChunkCache   =   -2040   #invalidChunkCache
+invalidSampleDescIndex  =   -2039   #invalidSampleDescIndex
+invalidChunkNum =   -2038   #invalidChunkNum
+invalidSampleNum    =   -2037   #invalidSampleNum
+invalidRect =   -2036   #invalidRect
+cantEnableTrack =   -2035   #cantEnableTrack
+internalQuickTimeError  =   -2034   #internalQuickTimeError
+badEditIndex    =   -2033   #badEditIndex
+timeNotInMedia  =   -2032   #timeNotInMedia
+timeNotInTrack  =   -2031   #timeNotInTrack
+trackNotInMovie =   -2030   #trackNotInMovie
+trackIDNotFound =   -2029   #trackIDNotFound
+badTrackIndex   =   -2028   #badTrackIndex
+maxSizeToGrowTooSmall   =   -2027   #maxSizeToGrowTooSmall
+userDataItemNotFound    =   -2026   #userDataItemNotFound
+staleEditState  =   -2025   #staleEditState
+nonMatchingEditState    =   -2024   #nonMatchingEditState
+invalidEditState    =   -2023   #invalidEditState
+cantCreateSingleForkFile    =   -2022   #happens when file already exists
+wfFileNotFound  =   -2021   #wfFileNotFound
+movieToolboxUninitialized   =   -2020   #movieToolboxUninitialized
+progressProcAborted =   -2019   #progressProcAborted
+mediaTypesDontMatch =   -2018   #mediaTypesDontMatch
+badEditList =   -2017   #badEditList
+cantPutPublicMovieAtom  =   -2016   #cantPutPublicMovieAtom
+invalidTime =   -2015   #invalidTime
+invalidDuration =   -2014   #invalidDuration
+invalidHandler  =   -2013   #invalidHandler
+invalidDataRef  =   -2012   #invalidDataRef
+invalidSampleTable  =   -2011   #invalidSampleTable
+invalidMovie    =   -2010   #invalidMovie
+invalidTrack    =   -2009   #invalidTrack
+invalidMedia    =   -2008   #invalidMedia
+noDataHandler   =   -2007   #noDataHandler
+noMediaHandler  =   -2006   #noMediaHandler
+badComponentType    =   -2005   #badComponentType
+cantOpenHandler =   -2004   #cantOpenHandler
+cantFindHandler =   -2003   #cantFindHandler
+badPublicMovieAtom  =   -2002   #badPublicMovieAtom
+badImageDescription =   -2001   #badImageDescription
+couldNotResolveDataRef  =   -2000   #couldNotResolveDataRef
+nonDragOriginatorErr    =   -1862   #illegal attempt at originator only data
+badImageErr =   -1861   #bad translucent image PixMap
+badImageRgnErr  =   -1860   #bad translucent image region
+noSuitableDisplaysErr   =   -1859   #no displays support translucency
+unsupportedForPlatformErr   =   -1858   #call is for PowerPC only
+dragNotAcceptedErr  =   -1857   #drag was not accepted by receiver
+handlerNotFoundErr  =   -1856   #handler not found
+duplicateHandlerErr =   -1855   #handler already exists
+cantGetFlavorErr    =   -1854   #error while trying to get flavor data
+duplicateFlavorErr  =   -1853   #flavor type already exists
+badDragFlavorErr    =   -1852   #unknown flavor type
+badDragItemErr  =   -1851   #unknown drag item reference
+badDragRefErr   =   -1850   #unknown drag reference
+errEndOfBody    =   -1813   #errEndOfBody
+errEndOfDocument    =   -1812   #errEndOfDocument
+errTopOfBody    =   -1811   #errTopOfBody
+errTopOfDocument    =   -1810   #errTopOfDocument
+errOffsetIsOutsideOfView    =   -1801   #errOffsetIsOutsideOfView
+errOffsetInvalid    =   -1800   #errOffsetInvalid
+errOSACantOpenComponent =   -1762   #Can't connect to scripting system with that ID
+errOSAComponentMismatch =   -1761   #Parameters are from 2 different components
+errOSADataFormatTooNew  =   -1759   #errOSADataFormatTooNew
+errOSADataFormatObsolete    =   -1758   #errOSADataFormatObsolete
+errOSANoSuchDialect =   -1757   #errOSANoSuchDialect
+errOSASourceNotAvailable    =   -1756   #errOSASourceNotAvailable
+errOSABadSelector   =   -1754   #errOSABadSelector
+errOSAScriptError   =   -1753   #errOSAScriptError
+errOSABadStorageType    =   -1752   #errOSABadStorageType
+errOSAInvalidID =   -1751   #errOSAInvalidID
+errOSASystemError   =   -1750   #errOSASystemError
+errAEBufferTooSmall =   -1741   #buffer for AEFlattenDesc too small
+errAEBuildSyntaxError   =   -1740   #AEBuildDesc and friends detected a syntax error
+errAEDescIsNull =   -1739   #attempting to perform an invalid operation on a null descriptor
+errAEStreamAlreadyConverted =   -1738   #attempt to convert a stream that has already been converted
+errAEStreamBadNesting   =   -1737   #nesting violation while streaming
+errAEDuplicateHandler   =   -1736   #attempt to install handler in table for identical class and id (1.1 or greater)
+errAEEventFiltered  =   -1735   #event has been filtered, and should not be propogated (1.1 or greater)
+errAEReceiveEscapeCurrent   =   -1734   #break out of only lowest level of AEReceive (1.1 or greater)
+errAEReceiveTerminate   =   -1733   #break out of all levels of AEReceive to the topmost (1.1 or greater)
+errAERecordingIsAlreadyOn   =   -1732   #available only in version 1.0.1 or greater
+errAEUnknownObjectType  =   -1731   #available only in version 1.0.1 or greater
+errAEEmptyListContainer =   -1730   #Attempt to pass empty list as container to accessor
+errAENegativeCount  =   -1729   #CountProc returned negative value
+errAENoSuchObject   =   -1728   #e.g.,: specifier asked for the 3rd, but there are only 2. Basically, this indicates a run-time resolution error.
+errAENotAnObjSpec   =   -1727   #Param to AEResolve not of type 'obj '
+errAEBadTestKey =   -1726   #Test is neither typeLogicalDescriptor nor typeCompDescriptor
+errAENoSuchLogical  =   -1725   #Something other than AND, OR, or NOT
+errAEAccessorNotFound   =   -1723   #Accessor proc matching wantClass and containerType or wildcards not found
+errAEWrongNumberArgs    =   -1721   #Logical op kAENOT used with other than 1 term
+errAEImpossibleRange    =   -1720   #A range like 3rd to 2nd, or 1st to all.
+errAEIllegalIndex   =   -1719   #index is out of range in a put operation
+errAEReplyNotArrived    =   -1718   #the contents of the reply you are accessing have not arrived yet
+errAEHandlerNotFound    =   -1717   #no handler in the dispatch tables fits the parameters to AEGetEventHandler or AEGetCoercionHandler
+errAEUnknownAddressType =   -1716   #the target address type is not known
+errAEParamMissed    =   -1715   #a required parameter was not accessed
+errAENotASpecialFunction    =   -1714   #there is no special function for/with this keyword
+errAENoUserInteraction  =   -1713   #no user interaction is allowed
+errAETimeout    =   -1712   #the AppleEvent timed out
+errAEWaitCanceled   =   -1711   #in AESend, the user cancelled out of wait loop for reply or receipt
+errAEUnknownSendMode    =   -1710   #mode wasn't NoReply, WaitReply, or QueueReply or Interaction level is unknown
+errAEReplyNotValid  =   -1709   #AEResetTimer was passed an invalid reply parameter
+errAEEventNotHandled    =   -1708   #the AppleEvent was not handled by any handler
+errAENotAppleEvent  =   -1707   #the event is not in AppleEvent format
+errAENewerVersion   =   -1706   #need newer version of the AppleEvent manager
+errAEBadListItem    =   -1705   #the specified list item does not exist
+errAENotAEDesc  =   -1704   #errAENotAEDesc
+errAEWrongDataType  =   -1703   #errAEWrongDataType
+errAECorruptData    =   -1702   #errAECorruptData
+errAEDescNotFound   =   -1701   #errAEDescNotFound
+errAECoercionFail   =   -1700   #bad parameter data or unable to coerce the data supplied
+errFSIteratorNotSupported   =   -1424   #The iterator's flags or container are not supported by this call
+errFSIteratorNotFound   =   -1423   #Passed FSIterator is not an open iterator
+errFSBadIteratorFlags   =   -1422   #Flags passed to FSOpenIterator are bad
+errFSForkExists =   -1421   #Named fork already exists.
+errFSRefsDifferent  =   -1420   #FSCompareFSRefs; refs are for different objects
+errFSBadSearchParams    =   -1419   #Something wrong with CatalogSearch searchParams
+errFSBadItemCount   =   -1418   #maximumItems was zero
+errFSNoMoreItems    =   -1417   #Iteration ran out of items to return
+errFSBadAllocFlags  =   -1413   #Invalid bits set in allocationFlags
+errFSBadPosMode =   -1412   #Newline bits set in positionMode
+errFSMissingName    =   -1411   #A Unicode name parameter was NULL or nameLength parameter was zero
+errFSNameTooLong    =   -1410   #File/fork name is too long to create/rename
+errFSForkNotFound   =   -1409   #Named fork does not exist
+errFSNotAFolder =   -1407   #Expected a folder, got a file
+errFSMissingCatInfo =   -1406   #A CatalogInfo parameter was NULL
+errFSBadInfoBitmap  =   -1405   #A CatalogInfoBitmap or VolumeInfoBitmap has reserved or invalid bits set
+errFSBadForkRef =   -1404   #A ForkRefNum parameter was bad
+errFSBadBuffer  =   -1403   #A buffer parameter was bad
+errFSBadForkName    =   -1402   #Fork name parameter is bad
+errFSBadFSRef   =   -1401   #FSRef parameter is bad
+errFSUnknownCall    =   -1400   #selector is not recognized by this filesystem
+badFCBErr   =   -1327   #FCBRecPtr is not valid
+volVMBusyErr    =   -1311   #can't eject because volume is in use by VM
+fsDataTooBigErr =   -1310   #file or volume is too big for system
+fileBoundsErr   =   -1309   #file's EOF, offset, mark or size is too big
+notARemountErr  =   -1308   #when _Mount allows only remounts and doesn't get one
+badFidErr   =   -1307   #file id is dangling or doesn't match with the file number
+sameFileErr =   -1306   #can't exchange a file with itself
+desktopDamagedErr   =   -1305   #desktop database files are corrupted
+catChangedErr   =   -1304   #the catalog has been modified
+diffVolErr  =   -1303   #files on different volumes
+notAFileErr =   -1302   #directory specified
+fidExists   =   -1301   #file id already exists
+fidNotFound =   -1300   #no file thread exists.
+errRefNum   =   -1280   #bad connection refNum
+errAborted  =   -1279   #control call was aborted
+errState    =   -1278   #bad connection state for this operation
+errOpening  =   -1277   #open connection request failed
+errAttention    =   -1276   #attention message too long
+errFwdReset =   -1275   #read terminated by forward reset
+errDSPQueueSize =   -1274   #DSP Read/Write Queue Too small
+errOpenDenied   =   -1273   #open connection request was denied
+reqAborted  =   -1105   #reqAborted
+noDataArea  =   -1104   #noDataArea
+noSendResp  =   -1103   #noSendResp
+cbNotFound  =   -1102   #cbNotFound
+noRelErr    =   -1101   #noRelErr
+badBuffNum  =   -1100   #badBuffNum
+badATPSkt   =   -1099   #badATPSkt
+tooManySkts =   -1098   #tooManySkts
+tooManyReqs =   -1097   #tooManyReqs
+reqFailed   =   -1096   #reqFailed
+aspNoAck    =   -1075   #No ack on attention request (server err)
+aspTooMany  =   -1074   #Too many clients (server error)
+aspSizeErr  =   -1073   #Command block too big
+aspSessClosed   =   -1072   #Session closed
+aspServerBusy   =   -1071   #Server cannot open another session
+aspParamErr =   -1070   #Parameter error
+aspNoServers    =   -1069   #No servers at that address
+aspNoMoreSess   =   -1068   #No more sessions on server
+aspBufTooSmall  =   -1067   #Buffer too small
+aspBadVersNum   =   -1066   #Server cannot support this ASP version
+nbpNISErr   =   -1029   #Error trying to open the NIS
+nbpNotFound =   -1028   #Name not found on remove
+nbpDuplicate    =   -1027   #Duplicate name exists already
+nbpConfDiff =   -1026   #Name confirmed at different socket
+nbpNoConfirm    =   -1025   #nbpNoConfirm
+nbpBuffOvr  =   -1024   #Buffer overflow in LookupName
+noMaskFoundErr  =   -1000   #Icon Utilties Error
+kFMFontContainerAccessErr   =   -985    #kFMFontContainerAccessErr
+kFMFontTableAccessErr   =   -984    #kFMFontTableAccessErr
+kFMIterationScopeModifiedErr    =   -983    #kFMIterationScopeModifiedErr
+kFMInvalidFontErr   =   -982    #kFMInvalidFontErr
+kFMInvalidFontFamilyErr =   -981    #kFMInvalidFontFamilyErr
+kFMIterationCompleted   =   -980    #kFMIterationCompleted
+guestNotAllowedErr  =   -932    #destination port requires authentication
+badLocNameErr   =   -931    #location name malformed
+badServiceMethodErr =   -930    #illegal service type, or not supported
+noUserRecErr    =   -928    #Invalid user reference number
+authFailErr =   -927    #unable to authenticate user at destination
+noInformErr =   -926    #PPCStart failed because destination did not have inform pending
+networkErr  =   -925    #An error has occurred in the network, not too likely
+noUserRefErr    =   -924    #unable to create a new userRefNum
+notLoggedInErr  =   -923    #The default userRefNum does not yet exist
+noDefaultUserErr    =   -922    #user hasn't typed in owners name in Network Setup Control Pannel
+badPortNameErr  =   -919    #PPCPortRec malformed
+sessClosedErr   =   -917    #session was closed
+portClosedErr   =   -916    #port was closed
+noResponseErr   =   -915    #unable to contact destination
+noToolboxNameErr    =   -914    #A system resource is missing, not too likely
+noMachineNameErr    =   -913    #user hasn't named his Macintosh in the Network Setup Control Panel
+userRejectErr   =   -912    #Destination rejected the session request
+noUserNameErr   =   -911    #user name unknown on destination machine
+portNameExistsErr   =   -910    #port is already open (perhaps in another app)
+badReqErr   =   -909    #bad parameter or invalid state for operation
+noSessionErr    =   -908    #Invalid session reference number
+sessTableErr    =   -907    #Out of session tables, try again later
+destPortErr =   -906    #Port does not exist at destination
+localOnlyErr    =   -905    #Network activity is currently disabled
+noGlobalsErr    =   -904    #The system is hosed, better re-boot
+noPortErr   =   -903    #Unable to open port or bad portRefNum.  If you're calling
+nameTypeErr =   -902    #Invalid or inappropriate locationKindSelector in locationName
+notInitErr  =   -900    #PPCToolBox not initialized
+notAppropriateForClassic    =   -877    #This application won't or shouldn't run on Classic (Problem 2481058).
+appVersionTooOld    =   -876    #The application's creator and version are incompatible with the current version of Mac OS.
+wrongApplicationPlatform    =   -875    #The application could not launch because the required platform is not available
+hmCloseViewActive   =   -863    #Returned from HMRemoveBalloon if CloseView was active
+hmNoBalloonUp   =   -862    #Returned from HMRemoveBalloon if no balloon was visible when call was made
+hmOperationUnsupported  =   -861    #Returned from HMShowBalloon call if bad method passed to routine
+hmUnknownHelpType   =   -859    #Returned if help msg record contained a bad type
+hmWrongVersion  =   -858    #Returned if help mgr resource was the wrong version
+hmSkippedBalloon    =   -857    #Returned from calls if helpmsg specified a skip balloon
+hmHelpManagerNotInited  =   -855    #Returned from HMGetHelpMenuHandle if help menu not setup
+hmSameAsLastBalloon =   -854    #Returned from HMShowMenuBalloon if menu & item is same as last time
+hmBalloonAborted    =   -853    #Returned if mouse was moving or mouse wasn't in window port rect
+hmHelpDisabled  =   -850    #Show Balloons mode was off, call to routine ignored
+rcDBPackNotInited   =   -813    #attempt to call other routine before InitDBPack
+rcDBWrongVersion    =   -812    #incompatible versions
+rcDBNoHandler   =   -811    #no app handler for specified data type
+rcDBBadAsyncPB  =   -810    #tried to kill a bad pb
+rcDBAsyncNotSupp    =   -809    #ddev does not support async calls
+rcDBBadDDEV =   -808    #bad ddev specified on DBInit
+rcDBBadSessNum  =   -807    #bad session number for DBGetConnInfo
+rcDBBadSessID   =   -806    #rcDBBadSessID
+rcDBExec    =   -805    #rcDBExec
+rcDBBreak   =   -804    #rcDBBreak
+rcDBBadType =   -803    #rcDBBadType
+rcDBError   =   -802    #rcDBError
+rcDBValue   =   -801    #rcDBValue
+rcDBNull    =   -800    #rcDBNull
+icTooManyProfilesErr    =   -677    #too many profiles in database
+icProfileNotFoundErr    =   -676    #profile not found
+icConfigInappropriateErr    =   -675    #incorrect manufacturer code
+icConfigNotFoundErr =   -674    #no internet configuration was found
+icNoURLErr  =   -673    #no URL found
+icNothingToOverrideErr  =   -672    #no component for the override component to capture
+icNoMoreWritersErr  =   -671    #you cannot begin a write session because someone else is already doing it
+icTruncatedErr  =   -670    #more data was present than was returned
+icInternalErr   =   -669    #Internet Config internal error
+icPrefDataErr   =   -668    #problem with preference data
+icPermErr   =   -667    #cannot set preference
+icPrefNotFoundErr   =   -666    #Internet preference not found
+vmInvalidOwningProcessErr   =   -648    #current process does not own the BackingFileID or FileViewID
+vmAddressNotInFileViewErr   =   -647    #address is not in a FileView
+vmNoMoreFileViewsErr    =   -646    #no more FileViews were found
+vmFileViewAccessErr =   -645    #requested FileViewAccess cannot be obtained
+vmInvalidFileViewIDErr  =   -644    #invalid FileViewID
+vmNoMoreBackingFilesErr =   -643    #no more BackingFiles were found
+vmBusyBackingFileErr    =   -642    #open views found on BackingFile
+vmMappingPrivilegesErr  =   -641    #requested MappingPrivileges cannot be obtained
+vmInvalidBackingFileIDErr   =   -640    #invalid BackingFileID
+noMMUErr    =   -626    #no MMU present
+cannotDeferErr  =   -625    #unable to defer additional functions
+interruptsMaskedErr =   -624    #donÕt call with interrupts masked
+notLockedErr    =   -623    #specified range of memory is not locked
+cannotMakeContiguousErr =   -622    #cannot make specified range contiguous
+notHeldErr  =   -621    #specified range of memory is not held
+notEnoughMemoryErr  =   -620    #insufficient physical memory
+threadProtocolErr   =   -619    #threadProtocolErr
+threadNotFoundErr   =   -618    #threadNotFoundErr
+threadTooManyReqsErr    =   -617    #threadTooManyReqsErr
+noUserInteractionAllowed    =   -610    #no user interaction allowed
+connectionInvalid   =   -609    #connectionInvalid
+noOutstandingHLE    =   -608    #noOutstandingHLE
+bufferIsSmall   =   -607    #error returns from Post and Accept
+appIsDaemon =   -606    #app is BG-only, and launch flags disallow this
+appMemFullErr   =   -605    #application SIZE not big enough for launch
+hardwareConfigErr   =   -604    #hardware configuration not correct for call
+protocolErr =   -603    #app made module calls in improper order
+appModeErr  =   -602    #memory mode is 32-bit, but app not 32-bit clean
+memFragErr  =   -601    #not enough room to launch app w/special requirements
+procNotFound    =   -600    #no eligible process with specified descriptor
+driverHardwareGoneErr   =   -503    #disk driver's hardware was disconnected
+hwParamErr  =   -502    #bad selector for _HWPriv
+teScrapSizeErr  =   -501    #scrap item too big for text edit record
+rgnTooBigErr    =   -500    #rgnTooBigErr
+exUserBreak =   -492    #user debugger break; execute debugger commands on stack
+strUserBreak    =   -491    #user debugger break; display string on stack
+userBreak   =   -490    #user debugger break
+notThePublisherWrn  =   -463    #not the first registered publisher for that container
+containerAlreadyOpenWrn =   -462    #container already opened by this section
+containerNotFoundWrn    =   -461    #could not find editionContainer at this time
+multiplePublisherWrn    =   -460    #A Publisher is already registered for that container
+badSubPartErr   =   -454    #can not use sub parts in this release
+badEditionFileErr   =   -453    #edition file is corrupt
+notRegisteredSectionErr =   -452    #not a registered SectionRecord
+badSectionErr   =   -451    #not a valid SectionRecord
+editionMgrInitErr   =   -450    #edition manager not inited by this app
+fsmUnknownFSMMessageErr =   -438    #unknown message passed to FSM
+fsmNoAlternateStackErr  =   -437    #no alternate stack for HFS CI
+fsmBadFSDVersionErr =   -436    #FSM version incompatible with FSD
+fsmDuplicateFSIDErr =   -435    #FSID already exists on InstallFS
+fsmBadFSDLenErr =   -434    #FSD size incompatible with current FSM vers
+fsmBadFFSNameErr    =   -433    #Name length not 1 <= length <= 31
+fsmBusyFFSErr   =   -432    #File system is busy, cannot be removed
+fsmFFSNotFoundErr   =   -431    #Foreign File system does not exist - new Pack2 could return this error too
+btKeyAttrErr    =   -417    #There is no such a key attribute.
+btKeyLenErr =   -416    #Maximum key length is too long or equal to zero.
+btRecNotFnd =   -415    #Record cannot be found.
+btDupRecErr =   -414    #Record already exists.
+btNoSpace   =   -413    #Can't allocate disk space.
+notBTree    =   -410    #The file is not a dictionary.
+gcrOnMFMErr =   -400    #gcr format on high density media error
+slotNumErr  =   -360    #invalid slot # error
+smRecNotFnd =   -351    #Record not found in the SRT.
+smSRTOvrFlErr   =   -350    #SRT over flow.
+smNoGoodOpens   =   -349    #No opens were successfull in the loop.
+smOffsetErr =   -348    #Offset was too big (temporary error
+smByteLanesErr  =   -347    #NumByteLanes was determined to be zero.
+smBadsPtrErr    =   -346    #Bad pointer was passed to sCalcsPointer
+smsGetDrvrErr   =   -345    #Error occurred during _sGetDriver.
+smNoMoresRsrcs  =   -344    #No more sResources
+smDisDrvrNamErr =   -343    #Error occurred during _sDisDrvrName.
+smGetDrvrNamErr =   -342    #Error occurred during _sGetDrvrName.
+smCkStatusErr   =   -341    #Status of slot = fail.
+smBlkMoveErr    =   -340    #_BlockMove error
+smNewPErr   =   -339    #_NewPtr error
+smSelOOBErr =   -338    #Selector out of bounds error
+smSlotOOBErr    =   -337    #Slot out of bounds error
+smNilsBlockErr  =   -336    #Nil sBlock error (Dont allocate and try to use a nil sBlock)
+smsPointerNil   =   -335    #LPointer is nil From sOffsetData. If this error occurs; check sInfo rec for more information.
+smCPUErr    =   -334    #Code revision is wrong
+smCodeRevErr    =   -333    #Code revision is wrong
+smReservedErr   =   -332    #Reserved field not zero
+smBadsList  =   -331    #Bad sList: Id1 < Id2 < Id3 ...format is not followed.
+smBadRefId  =   -330    #Reference Id not found in List
+smBusErrTO  =   -320    #BusError time out.
+smBadBoardId    =   -319    #BoardId was wrong; re-init the PRAM record.
+smReservedSlot  =   -318    #slot is reserved, VM should not use this address space.
+smInitTblVErr   =   -317    #An error occurred while trying to initialize the Slot Resource Table.
+smInitStatVErr  =   -316    #The InitStatusV field was negative after primary or secondary init.
+smNoBoardId =   -315    #No Board Id.
+smGetPRErr  =   -314    #Error occurred during _sGetPRAMRec (See SIMStatus).
+smNoBoardSRsrc  =   -313    #No Board sResource.
+smDisposePErr   =   -312    #_DisposePointer error
+smFHBlkDispErr  =   -311    #Error occurred during _sDisposePtr (Dispose of FHeader block).
+smFHBlockRdErr  =   -310    #Error occurred during _sGetFHeader.
+smBLFieldBad    =   -309    #ByteLanes field was bad.
+smUnExBusErr    =   -308    #Unexpected BusError
+smResrvErr  =   -307    #Fatal reserved error. Resreved field <> 0.
+smNosInfoArray  =   -306    #No sInfoArray. Memory Mgr error.
+smDisabledSlot  =   -305    #This slot is disabled (-305 use to be smLWTstBad)
+smNoDir =   -304    #Directory offset is Nil
+smRevisionErr   =   -303    #Wrong revison level
+smFormatErr =   -302    #FHeader Format is not Apple's
+smCRCFail   =   -301    #CRC check failed for declaration data
+smEmptySlot =   -300    #No card in slot
+nmTypErr    =   -299    #Notification Manager:wrong queue type
+smPriInitErr    =   -293    #Error; Cards could not be initialized.
+smPRAMInitErr   =   -292    #Error; Slot Resource Table could not be initialized.
+smSRTInitErr    =   -291    #Error; Slot Resource Table could not be initialized.
+smSDMInitErr    =   -290    #Error; SDM could not be initialized.
+midiInvalidCmdErr   =   -261    #command not supported for port type
+midiDupIDErr    =   -260    #duplicate client ID
+midiNameLenErr  =   -259    #name supplied is longer than 31 characters
+midiWriteErr    =   -258    #MIDIWritePacket couldn't write to all connected ports
+midiNoConErr    =   -257    #no connection exists between specified ports
+midiVConnectRmvd    =   -256    #pending virtual connection removed
+midiVConnectMade    =   -255    #pending virtual connection resolved
+midiVConnectErr =   -254    #pending virtual connection created
+midiTooManyConsErr  =   -253    #too many connections made
+midiTooManyPortsErr =   -252    #too many ports already installed in the system
+midiNoPortErr   =   -251    #no port with that ID found
+midiNoClientErr =   -250    #no client with that ID found
+badInputText    =   -247    #badInputText
+badDictFormat   =   -246    #badDictFormat
+incompatibleVoice   =   -245    #incompatibleVoice
+voiceNotFound   =   -244    #voiceNotFound
+bufTooSmall =   -243    #bufTooSmall
+synthNotReady   =   -242    #synthNotReady
+synthOpenFailed =   -241    #synthOpenFailed
+noSynthFound    =   -240    #noSynthFound
+siUnknownQuality    =   -232    #invalid quality selector (returned by driver)
+siUnknownInfoType   =   -231    #invalid info type selector (returned by driver)
+siInputDeviceErr    =   -230    #input device hardware failure
+siBadRefNum =   -229    #invalid input device reference number
+siBadDeviceName =   -228    #input device could not be opened
+siDeviceBusyErr =   -227    #input device already in use
+siInvalidSampleSize =   -226    #invalid sample size
+siInvalidSampleRate =   -225    #invalid sample rate
+siHardDriveTooSlow  =   -224    #hard drive too slow to record to disk
+siInvalidCompression    =   -223    #invalid compression type
+siNoBufferSpecified =   -222    #returned by synchronous SPBRecord if nil buffer passed
+siBadSoundInDevice  =   -221    #invalid index passed to SoundInGetIndexedDevice
+siNoSoundInHardware =   -220    #no Sound Input hardware
+siVBRCompressionNotSupported    =   -213    #vbr audio compression not supported for this operation
+noMoreRealTime  =   -212    #not enough CPU cycles left to add another task
+channelNotBusy  =   -211    #channelNotBusy
+buffersTooSmall =   -210    #can not operate in the memory allowed
+channelBusy =   -209    #the Channel is being used for a PFD already
+badFileFormat   =   -208    #was not type AIFF or was of bad format,corrupt
+notEnoughBufferSpace    =   -207    #could not allocate enough memory
+badFormat   =   -206    #Sound Manager Error Returns
+badChannel  =   -205    #Sound Manager Error Returns
+resProblem  =   -204    #Sound Manager Error Returns
+queueFull   =   -203    #Sound Manager Error Returns
+notEnoughHardwareErr    =   -201    #Sound Manager Error Returns
+noHardwareErr   =   -200    #Sound Manager Error Returns
+mapReadErr  =   -199    #map inconsistent with operation
+resAttrErr  =   -198    #attribute inconsistent with operation
+rmvRefFailed    =   -197    #RmveReference failed
+rmvResFailed    =   -196    #RmveResource failed
+addRefFailed    =   -195    #AddReference failed
+addResFailed    =   -194    #AddResource failed
+resFNotFound    =   -193    #Resource file not found
+resNotFound =   -192    #Resource not found
+inputOutOfBounds    =   -190    #Offset of Count out of bounds
+writingPastEnd  =   -189    #Writing past end of file
+resourceInMemory    =   -188    #Resource already in memory
+CantDecompress  =   -186    #resource bent ("the bends") - can't decompress a compressed resource
+badExtResource  =   -185    #extended resource has a bad format.
+cmNoCurrentProfile  =   -182    #Responder error
+cmUnsupportedDataType   =   -181    #Responder error
+cmCantDeleteProfile =   -180    #Responder error
+cmCantXYZ   =   -179    #CMM cant handle XYZ space
+cmCantConcatenateError  =   -178    #Profile can't be concatenated
+cmProfilesIdentical =   -177    #Profiles the same
+cmProfileNotFound   =   -176    #Responder error
+cmMethodNotFound    =   -175    #CMM not present
+cmMethodError   =   -171    #cmMethodError
+cmProfileError  =   -170    #cmProfileError
+cDepthErr   =   -157    #invalid pixel depth
+cResErr =   -156    #invalid resolution for MakeITable
+cDevErr =   -155    #invalid type of graphics device
+cProtectErr =   -154    #colorTable entry protection violation
+cRangeErr   =   -153    #range error on colorTable request
+cNoMemErr   =   -152    #failed to allocate memory for structure
+cTempMemErr =   -151    #failed to allocate memory for temporary structures
+cMatchErr   =   -150    #Color2Index failed to find an index
+insufficientStackErr    =   -149    #insufficientStackErr
+pixMapTooDeepErr    =   -148    #pixMapTooDeepErr
+rgnOverflowErr  =   -147    #rgnOverflowErr
+noMemForPictPlaybackErr =   -145    #noMemForPictPlaybackErr
+userCanceledErr =   -128    #userCanceledErr
+hMenuFindErr    =   -127    #could not find HMenu's parent in MenuKey (wrong error code - obsolete)
+mBarNFnd    =   -126    #system error code for MBDF not found
+updPixMemErr    =   -125    #insufficient memory to update a pixmap
+volGoneErr  =   -124    #Server volume has been disconnected.
+wrgVolTypErr    =   -123    #Wrong volume type error [operation not supported for MFS]
+badMovErr   =   -122    #Move into offspring error
+tmwdoErr    =   -121    #No free WDCB available
+dirNFErr    =   -120    #Directory not found
+memLockedErr    =   -117    #trying to move a locked block (MoveHHi)
+memSCErr    =   -116    #Size Check failed
+memBCErr    =   -115    #Block Check failed
+memPCErr    =   -114    #Pointer Check failed
+memAZErr    =   -113    #Address in zone check failed
+memPurErr   =   -112    #trying to purge a locked or non-purgeable block
+memWZErr    =   -111    #WhichZone failed (applied to free block)
+memAdrErr   =   -110    #address was odd; or out of range
+nilHandleErr    =   -109    #Master Pointer was NIL in HandleZone or other
+memFullErr  =   -108    #Not enough room in heap zone
+noTypeErr   =   -102    #No object of that type in scrap
+noScrapErr  =   -100    #No scrap exists error
+memROZWarn  =   -99 #soft error in ROZ
+portNotCf   =   -98 #driver Open error code (parameter RAM not configured for this connection)
+portInUse   =   -97 #driver Open error code (port is in use)
+portNotPwr  =   -96 #serial port not currently powered
+excessCollsns   =   -95 #excessive collisions on write
+lapProtErr  =   -94 #error in attaching/detaching protocol
+noBridgeErr =   -93 #no network bridge for non-local send
+eLenErr =   -92 #Length error ddpLenErr
+eMultiErr   =   -91 #Multicast address error ddpSktErr
+breakRecd   =   -90 #Break received (SCC)
+rcvrErr =   -89 #SCC receiver error (framing; parity; OR)
+prInitErr   =   -88 #InitUtil found the parameter ram uninitialized
+prWrErr =   -87 #parameter ram written didn't read-verify
+clkWrErr    =   -86 #time written did not verify
+clkRdErr    =   -85 #unable to read same clock value twice
+verErr  =   -84 #track failed to verify
+fmt2Err =   -83 #can't get enough sync
+fmt1Err =   -82 #can't find sector 0 after track format
+sectNFErr   =   -81 #sector number never found on a track
+seekErr =   -80 #track number wrong on address mark
+spdAdjErr   =   -79 #unable to correctly adjust disk speed
+twoSideErr  =   -78 #tried to read 2nd side on a 1-sided drive
+initIWMErr  =   -77 #unable to initialize IWM
+tk0BadErr   =   -76 #track 0 detect doesn't change
+cantStepErr =   -75 #step handshake failed
+wrUnderrun  =   -74 #write underrun occurred
+badDBtSlp   =   -73 #bad data mark bit slip nibbles
+badDCksum   =   -72 #bad data mark checksum
+noDtaMkErr  =   -71 #couldn't find a data mark header
+badBtSlpErr =   -70 #bad addr mark bit slip nibbles
+badCksmErr  =   -69 #addr mark checksum didn't check
+dataVerErr  =   -68 #read verify compare failed
+noAdrMkErr  =   -67 #couldn't find valid addr mark
+noNybErr    =   -66 #couldn't find 5 nybbles in 200 tries
+offLinErr   =   -65 #r/w requested for an off-line drive
+fontDecError    =   -64 #error during font declaration
+wrPermErr   =   -61 #write permissions error
+badMDBErr   =   -60 #bad master directory block
+fsRnErr =   -59 #file system internal error:during rename the old entry was deleted but could not be restored.
+extFSErr    =   -58 #volume in question belongs to an external fs
+noMacDskErr =   -57 #not a mac diskette (sig bytes are wrong)
+nsDrvErr    =   -56 #no such drive (tried to mount a bad drive num)
+volOnLinErr =   -55 #drive volume already on-line at MountVol
+permErr =   -54 #permissions error (on file open)
+volOffLinErr    =   -53 #volume not on line error (was Ejected)
+gfpErr  =   -52 #get file position error
+rfNumErr    =   -51 #refnum error
+paramErr    =   -50 #error in user parameter list
+opWrErr =   -49 #file already open with with write permission
+dupFNErr    =   -48 #duplicate filename (rename)
+fBsyErr =   -47 #File is busy (delete)
+vLckdErr    =   -46 #volume is locked
+fLckdErr    =   -45 #file is locked
+wPrErr  =   -44 #diskette is write protected.
+fnfErr  =   -43 #File not found
+tmfoErr =   -42 #too many files open
+mFulErr =   -41 #memory full (open) or file won't fit (load)
+posErr  =   -40 #tried to position to before start of file (r/w)
+eofErr  =   -39 #End of file
+fnOpnErr    =   -38 #File not open
+bdNamErr    =   -37 #there may be no bad names in the final system!
+ioErr   =   -36 #I/O error (bummers)
+nsvErr  =   -35 #no such volume
+dskFulErr   =   -34 #disk full
+dirFulErr   =   -33 #Directory full
+dceExtErr   =   -30 #dce extension error
+unitTblFullErr  =   -29 #unit table has no more entries
+notOpenErr  =   -28 #Couldn't rd/wr/ctl/sts cause driver not opened
+iIOAbortErr =   -27 #IO abort error (Printing Manager)
+dInstErr    =   -26 #DrvrInstall couldn't find driver in resources
+dRemovErr   =   -25 #tried to remove an open driver
+closErr =   -24 #I/O System Errors
+openErr =   -23 #I/O System Errors
+unitEmptyErr    =   -22 #I/O System Errors
+badUnitErr  =   -21 #I/O System Errors
+writErr =   -20 #I/O System Errors
+readErr =   -19 #I/O System Errors
+statusErr   =   -18 #I/O System Errors
+controlErr  =   -17 #I/O System Errors
+dsExtensionsDisabled    =   -13 #say –Extensions Disabled”
+dsHD20Installed =   -12 #say –HD20 Startup”
+dsDisassemblerInstalled =   -11 #say –Disassembler Installed”
+dsMacsBugInstalled  =   -10 #say –MacsBug Installed”
+seNoDB  =   -8  #no debugger installed to handle debugger command
+SlpTypeErr  =   -5  #invalid queue element
+unimpErr    =   -4  #unimplemented core routine
+corErr  =   -3  #core routine number out of range
+dsNoExtsDisassembler    =   -2  #not a SysErr, just a placeholder
+qErr    =   -1  #queue element not found during deletion
+tsmComponentNoErr   =   0   #component result = no error
+EPERM   =   1   #Operation not permitted
+ENOENT  =   2   #No such file or directory
+ESRCH   =   3   #No such process
+EINTR   =   4   #Interrupted system call
+EIO =   5   #Input/output error
+ENXIO   =   6   #Device not configured
+E2BIG   =   7   #Argument list too long
+ENOEXEC =   8   #Exec format error
+EBADF   =   9   #Bad file descriptor
+ECHILD  =   10  #No child processes
+EDEADLK =   11  #Resource deadlock avoided
+ENOMEM  =   12  #Cannot allocate memory
+EACCES  =   13  #Permission denied
+EFAULT  =   14  #Bad address
+ECANCELED   =   15  #Operation cancelled
+EBUSY   =   16  #Device busy
+EEXIST  =   17  #File exists
+EXDEV   =   18  #Cross-device link
+ENODEV  =   19  #Operation not supported by device
+ENOTDIR =   20  #Not a directory
+EISDIR  =   21  #Is a directory
+EINVAL  =   22  #Invalid argument
+ENFILE  =   23  #Too many open files in system
+EMFILE  =   24  #Too many open files
+ENOTTY  =   25  #Inappropriate ioctl for device
+ESIGPARM    =   26  #Signal error
+EFBIG   =   27  #File too large
+ENOSPC  =   28  #No space left on device
+ESPIPE  =   29  #Illegal seek
+EROFS   =   30  #Read-only file system
+EMLINK  =   31  #Too many links
+EPIPE   =   32  #Broken pipe
+EDOM    =   33  #Numerical argument out of domain
+ERANGE  =   34  #Result too large
+EAGAIN  =   35  #Resource temporarily unavailable
+EINPROGRESS =   36  #Operation now in progress
+EALREADY    =   37  #Operation already in progress
+ENOTSOCK    =   38  #Socket operation on non-socket
+EDESTADDRREQ    =   39  #Destination address required
+EMSGSIZE    =   40  #Message too long
+EPROTOTYPE  =   41  #Protocol wrong type for socket
+ENOPROTOOPT =   42  #Protocol not available
+EPROTONOSUPPORT =   43  #Protocol not supported
+ESOCKTNOSUPPORT =   44  #Socket type not supported
+EOPNOTSUPP  =   45  #Operation not supported
+EPFNOSUPPORT    =   46  #Protocol family not supported
+EAFNOSUPPORT    =   47  #Address family not supported by protocol family
+EADDRINUSE  =   48  #Address already in use
+EADDRNOTAVAIL   =   49  #Can't assign requested address
+ENETDOWN    =   50  #Network is down
+ENETUNREACH =   51  #Network is unreachable
+ENETRESET   =   52  #Network dropped connection on reset
+ECONNABORTED    =   53  #Software caused connection abort
+ECONNRESET  =   54  #Connection reset by peer
+ENOBUFS =   55  #No buffer space available
+EISCONN =   56  #Socket is already connected
+ENOTCONN    =   57  #Socket is not connected
+ESHUTDOWN   =   58  #Can't send after socket shutdown
+ETOOMANYREFS    =   59  #Too many references: can't splice
+ETIMEDOUT   =   60  #Operation timed out
+ECONNREFUSED    =   61  #Connection refused
+ELOOP   =   62  #Too many levels of symbolic links
+ENAMETOOLONG    =   63  #File name too long
+EHOSTDOWN   =   64  #Host is down
+EHOSTUNREACH    =   65  #No route to host
+ENOTEMPTY   =   66  #Directory not empty
+ELOOK   =   67  #Internal mapping for kOTLookErr, don't return to client
+ENOLCK  =   77  #No locks available
+ENOSYS  =   78  #Function not implemented
+EILSEQ  =   88  #Wide character encoding error
+EUNKNOWN    =   99  #Unknown error

Added: vendor/Python/current/Lib/plat-mac/macfs.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/macfs.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/macfs.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,198 @@
+"""macfs - Pure Python module designed to be backward compatible with
+macfs and MACFS.
+"""
+import sys
+import struct
+import Carbon.Res
+import Carbon.File
+import warnings
+
+warnings.warn("macfs is deprecated, use Carbon.File, Carbon.Folder or EasyDialogs",
+              DeprecationWarning, stacklevel=2)
+
+# First step: ensure we also emulate the MACFS module, which contained
+# all the constants
+
+sys.modules['MACFS'] = sys.modules[__name__]
+
+# Import all those constants
+from Carbon.Files import *
+from Carbon.Folders import *
+
+# For some obscure historical reason these are here too:
+READ = 1
+WRITE = 2
+smAllScripts = -3
+
+#
+# Find the epoch conversion for file dates in a way that works on OS9 and OSX
+import time
+if time.gmtime(0)[0] == 1970:
+    _EPOCHCONVERT = -((1970-1904)*365 + 17) * (24*60*60) + 0x100000000L
+    def _utc2time(utc):
+        t = utc[1] + _EPOCHCONVERT
+        return int(t)
+    def _time2utc(t):
+        t = int(t) - _EPOCHCONVERT
+        if t < -0x7fffffff:
+            t = t + 0x10000000L
+        return (0, int(t), 0)
+else:
+    def _utc2time(utc):
+        t = utc[1]
+        if t < 0:
+            t = t + 0x100000000L
+        return t
+    def _time2utc(t):
+        if t > 0x7fffffff:
+            t = t - 0x100000000L
+        return (0, int(t), 0)
+
+# The old name of the error object:
+error = Carbon.File.Error
+
+#
+# The various objects macfs used to export. We override them here, because some
+# of the method names are subtly different.
+#
+class FSSpec(Carbon.File.FSSpec):
+    def as_fsref(self):
+        return FSRef(self)
+
+    def NewAlias(self, src=None):
+        return Alias(Carbon.File.NewAlias(src, self))
+
+    def GetCreatorType(self):
+        finfo = self.FSpGetFInfo()
+        return finfo.Creator, finfo.Type
+
+    def SetCreatorType(self, ctor, tp):
+        finfo = self.FSpGetFInfo()
+        finfo.Creator = ctor
+        finfo.Type = tp
+        self.FSpSetFInfo(finfo)
+
+    def GetFInfo(self):
+        return self.FSpGetFInfo()
+
+    def SetFInfo(self, info):
+        return self.FSpSetFInfo(info)
+
+    def GetDates(self):
+        catInfoFlags = kFSCatInfoCreateDate|kFSCatInfoContentMod|kFSCatInfoBackupDate
+        catinfo, d1, d2, d3 = FSRef(self).FSGetCatalogInfo(catInfoFlags)
+        cdate = catinfo.createDate
+        mdate = catinfo.contentModDate
+        bdate = catinfo.backupDate
+        return _utc2time(cdate), _utc2time(mdate), _utc2time(bdate)
+
+    def SetDates(self, cdate, mdate, bdate):
+        catInfoFlags = kFSCatInfoCreateDate|kFSCatInfoContentMod|kFSCatInfoBackupDate
+        catinfo = Carbon.File.FSCatalogInfo(
+            createDate = _time2utc(cdate),
+            contentModDate = _time2utc(mdate),
+            backupDate = _time2utc(bdate))
+        FSRef(self).FSSetCatalogInfo(catInfoFlags, catinfo)
+
+class FSRef(Carbon.File.FSRef):
+    def as_fsspec(self):
+        return FSSpec(self)
+
+class Alias(Carbon.File.Alias):
+
+    def GetInfo(self, index):
+        return self.GetAliasInfo(index)
+
+    def Update(self, *args):
+        pass # print "Alias.Update not yet implemented"
+
+    def Resolve(self, src=None):
+        fss, changed = self.ResolveAlias(src)
+        return FSSpec(fss), changed
+
+from Carbon.File import FInfo
+
+# Backward-compatible type names:
+FSSpecType = FSSpec
+FSRefType = FSRef
+AliasType = Alias
+FInfoType = FInfo
+
+# Global functions:
+def ResolveAliasFile(fss, chain=1):
+    fss, isdir, isalias = Carbon.File.ResolveAliasFile(fss, chain)
+    return FSSpec(fss), isdir, isalias
+
+def RawFSSpec(data):
+    return FSSpec(rawdata=data)
+
+def RawAlias(data):
+    return Alias(rawdata=data)
+
+def FindApplication(*args):
+    raise NotImplementedError, "FindApplication no longer implemented"
+
+def NewAliasMinimalFromFullPath(path):
+    return Alias(Carbon.File.NewAliasMinimalFromFullPath(path, '', ''))
+
+# Another global function:
+from Carbon.Folder import FindFolder
+
+#
+# Finally the old Standard File routine emulators.
+#
+
+_curfolder = None
+
+def StandardGetFile(*typelist):
+    """Ask for an input file, optionally specifying 4-char file types that are
+    allowable"""
+    return PromptGetFile('', *typelist)
+
+def PromptGetFile(prompt, *typelist):
+    """Ask for an input file giving the user a prompt message. Optionally you can
+    specifying 4-char file types that are allowable"""
+    import EasyDialogs
+    warnings.warn("macfs.StandardGetFile and friends are deprecated, use EasyDialogs.AskFileForOpen",
+              DeprecationWarning, stacklevel=2)
+    if not typelist:
+        typelist = None
+    fss = EasyDialogs.AskFileForOpen(message=prompt, wanted=FSSpec,
+        typeList=typelist, defaultLocation=_handleSetFolder())
+    return fss, not fss is None
+
+def StandardPutFile(prompt, default=None):
+    """Ask the user for an output file, with a prompt. Optionally you cn supply a
+    default output filename"""
+    import EasyDialogs
+    warnings.warn("macfs.StandardGetFile and friends are deprecated, use EasyDialogs.AskFileForOpen",
+              DeprecationWarning, stacklevel=2)
+    fss = EasyDialogs.AskFileForSave(wanted=FSSpec, message=prompt,
+    savedFileName=default, defaultLocation=_handleSetFolder())
+    return fss, not fss is None
+
+def SetFolder(folder):
+    global _curfolder
+    warnings.warn("macfs.StandardGetFile and friends are deprecated, use EasyDialogs.AskFileForOpen",
+              DeprecationWarning, stacklevel=2)
+    if _curfolder:
+        rv = FSSpec(_curfolder)
+    else:
+        rv = None
+    _curfolder = folder
+    return rv
+
+def _handleSetFolder():
+    global _curfolder
+    rv = _curfolder
+    _curfolder = None
+    return rv
+
+def GetDirectory(prompt=None):
+    """Ask the user to select a folder. Optionally you can give a prompt."""
+    import EasyDialogs
+    warnings.warn("macfs.StandardGetFile and friends are deprecated, use EasyDialogs.AskFileForOpen",
+              DeprecationWarning, stacklevel=2)
+    fss = EasyDialogs.AskFolder(message=prompt, wanted=FSSpec,
+        defaultLocation=_handleSetFolder())
+    return fss, not fss is None

Added: vendor/Python/current/Lib/plat-mac/macostools.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/macostools.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/macostools.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,142 @@
+"""macostools - Various utility functions for MacOS.
+
+mkalias(src, dst) - Create a finder alias 'dst' pointing to 'src'
+copy(src, dst) - Full copy of 'src' to 'dst'
+"""
+
+from Carbon import Res
+from Carbon import File, Files
+import os
+import sys
+import MacOS
+import time
+try:
+    openrf = MacOS.openrf
+except AttributeError:
+    # Backward compatibility
+    openrf = open
+
+Error = 'macostools.Error'
+
+BUFSIZ=0x80000      # Copy in 0.5Mb chunks
+
+COPY_FLAGS = (Files.kIsStationary|Files.kNameLocked|Files.kHasBundle|
+              Files.kIsInvisible|Files.kIsAlias)
+
+#
+# Not guaranteed to be correct or stay correct (Apple doesn't tell you
+# how to do this), but it seems to work.
+#
+def mkalias(src, dst, relative=None):
+    """Create a finder alias"""
+    srcfsr = File.FSRef(src)
+    # The next line will fail under unix-Python if the destination
+    # doesn't exist yet. We should change this code to be fsref-based.
+    dstdir, dstname = os.path.split(dst)
+    if not dstdir: dstdir = os.curdir
+    dstdirfsr = File.FSRef(dstdir)
+    if relative:
+        relativefsr = File.FSRef(relative)
+        # ik mag er geen None in stoppen :-(
+        alias = File.FSNewAlias(relativefsr, srcfsr)
+    else:
+        alias = srcfsr.FSNewAliasMinimal()
+
+    dstfsr, dstfss = Res.FSCreateResourceFile(dstdirfsr, unicode(dstname),
+        File.FSGetResourceForkName())
+    h = Res.FSOpenResourceFile(dstfsr, File.FSGetResourceForkName(), 3)
+    resource = Res.Resource(alias.data)
+    resource.AddResource('alis', 0, '')
+    Res.CloseResFile(h)
+
+    dstfinfo = dstfss.FSpGetFInfo()
+    dstfinfo.Flags = dstfinfo.Flags|0x8000    # Alias flag
+    dstfss.FSpSetFInfo(dstfinfo)
+
+def mkdirs(dst):
+    """Make directories leading to 'dst' if they don't exist yet"""
+    if dst == '' or os.path.exists(dst):
+        return
+    head, tail = os.path.split(dst)
+    if os.sep == ':' and not ':' in head:
+        head = head + ':'
+    mkdirs(head)
+    os.mkdir(dst, 0777)
+
+def touched(dst):
+    """Tell the finder a file has changed. No-op on MacOSX."""
+    if sys.platform != 'mac': return
+    import warnings
+    warnings.filterwarnings("ignore", "macfs.*", DeprecationWarning, __name__)
+    import macfs
+    file_fss = macfs.FSSpec(dst)
+    vRefNum, dirID, name = file_fss.as_tuple()
+    dir_fss = macfs.FSSpec((vRefNum, dirID, ''))
+    crdate, moddate, bkdate = dir_fss.GetDates()
+    now = time.time()
+    if now == moddate:
+        now = now + 1
+    try:
+        dir_fss.SetDates(crdate, now, bkdate)
+    except macfs.error:
+        pass
+
+def touched_ae(dst):
+    """Tell the finder a file has changed"""
+    pardir = os.path.split(dst)[0]
+    if not pardir:
+        pardir = os.curdir
+    import Finder
+    f = Finder.Finder()
+    f.update(File.FSRef(pardir))
+
+def copy(src, dst, createpath=0, copydates=1, forcetype=None):
+    """Copy a file, including finder info, resource fork, etc"""
+    src = File.pathname(src)
+    dst = File.pathname(dst)
+    if createpath:
+        mkdirs(os.path.split(dst)[0])
+
+    ifp = open(src, 'rb')
+    ofp = open(dst, 'wb')
+    d = ifp.read(BUFSIZ)
+    while d:
+        ofp.write(d)
+        d = ifp.read(BUFSIZ)
+    ifp.close()
+    ofp.close()
+
+    ifp = openrf(src, '*rb')
+    ofp = openrf(dst, '*wb')
+    d = ifp.read(BUFSIZ)
+    while d:
+        ofp.write(d)
+        d = ifp.read(BUFSIZ)
+    ifp.close()
+    ofp.close()
+
+    srcfss = File.FSSpec(src)
+    dstfss = File.FSSpec(dst)
+    sf = srcfss.FSpGetFInfo()
+    df = dstfss.FSpGetFInfo()
+    df.Creator, df.Type = sf.Creator, sf.Type
+    if forcetype != None:
+        df.Type = forcetype
+    df.Flags = (sf.Flags & COPY_FLAGS)
+    dstfss.FSpSetFInfo(df)
+    if copydates:
+        srcfsr = File.FSRef(src)
+        dstfsr = File.FSRef(dst)
+        catinfo, _, _, _ = srcfsr.FSGetCatalogInfo(Files.kFSCatInfoAllDates)
+        dstfsr.FSSetCatalogInfo(Files.kFSCatInfoAllDates, catinfo)
+    touched(dstfss)
+
+def copytree(src, dst, copydates=1):
+    """Copy a complete file tree to a new destination"""
+    if os.path.isdir(src):
+        mkdirs(dst)
+        files = os.listdir(src)
+        for f in files:
+            copytree(os.path.join(src, f), os.path.join(dst, f), copydates)
+    else:
+        copy(src, dst, 1, copydates)

Added: vendor/Python/current/Lib/plat-mac/macresource.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/macresource.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/macresource.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,146 @@
+"""macresource - Locate and open the resources needed for a script."""
+
+from Carbon import Res
+import os
+import sys
+import MacOS
+import macostools
+
+class ArgumentError(TypeError): pass
+class ResourceFileNotFoundError(ImportError): pass
+
+def need(restype, resid, filename=None, modname=None):
+    """Open a resource file, if needed. restype and resid
+    are required parameters, and identify the resource for which to test. If it
+    is available we are done. If it is not available we look for a file filename
+    (default: modname with .rsrc appended) either in the same folder as
+    where modname was loaded from, or otherwise across sys.path.
+
+    Returns the refno of the resource file opened (or None)"""
+
+    if modname is None and filename is None:
+        raise ArgumentError, "Either filename or modname argument (or both) must be given"
+
+    if type(resid) is type(1):
+        try:
+            h = Res.GetResource(restype, resid)
+        except Res.Error:
+            pass
+        else:
+            return None
+    else:
+        try:
+            h = Res.GetNamedResource(restype, resid)
+        except Res.Error:
+            pass
+        else:
+            return None
+
+    # Construct a filename if we don't have one
+    if not filename:
+        if '.' in modname:
+            filename = modname.split('.')[-1] + '.rsrc'
+        else:
+            filename = modname + '.rsrc'
+
+    # Now create a list of folders to search
+    searchdirs = []
+    if modname == '__main__':
+        # If we're main we look in the current directory
+        searchdirs = [os.curdir]
+    if sys.modules.has_key(modname):
+        mod = sys.modules[modname]
+        if hasattr(mod, '__file__'):
+            searchdirs = [os.path.dirname(mod.__file__)]
+    searchdirs.extend(sys.path)
+
+    # And look for the file
+    for dir in searchdirs:
+        pathname = os.path.join(dir, filename)
+        if os.path.exists(pathname):
+            break
+    else:
+        raise ResourceFileNotFoundError, filename
+
+    refno = open_pathname(pathname)
+
+    # And check that the resource exists now
+    if type(resid) is type(1):
+        h = Res.GetResource(restype, resid)
+    else:
+        h = Res.GetNamedResource(restype, resid)
+    return refno
+
+def open_pathname(pathname, verbose=0):
+    """Open a resource file given by pathname, possibly decoding an
+    AppleSingle file"""
+    try:
+        refno = Res.FSpOpenResFile(pathname, 1)
+    except Res.Error, arg:
+        if arg[0] in (-37, -39):
+            # No resource fork. We may be on OSX, and this may be either
+            # a data-fork based resource file or a AppleSingle file
+            # from the CVS repository.
+            try:
+                refno = Res.FSOpenResourceFile(pathname, u'', 1)
+            except Res.Error, arg:
+                if arg[0] != -199:
+                    # -199 is "bad resource map"
+                    raise
+            else:
+                return refno
+            # Finally try decoding an AppleSingle file
+            pathname = _decode(pathname, verbose=verbose)
+            refno = Res.FSOpenResourceFile(pathname, u'', 1)
+        else:
+            raise
+    return refno
+
+def resource_pathname(pathname, verbose=0):
+    """Return the pathname for a resource file (either DF or RF based).
+    If the pathname given already refers to such a file simply return it,
+    otherwise first decode it."""
+    try:
+        refno = Res.FSpOpenResFile(pathname, 1)
+        Res.CloseResFile(refno)
+    except Res.Error, arg:
+        if arg[0] in (-37, -39):
+            # No resource fork. We may be on OSX, and this may be either
+            # a data-fork based resource file or a AppleSingle file
+            # from the CVS repository.
+            try:
+                refno = Res.FSOpenResourceFile(pathname, u'', 1)
+            except Res.Error, arg:
+                if arg[0] != -199:
+                    # -199 is "bad resource map"
+                    raise
+            else:
+                return refno
+            # Finally try decoding an AppleSingle file
+            pathname = _decode(pathname, verbose=verbose)
+        else:
+            raise
+    return pathname
+
+def open_error_resource():
+    """Open the resource file containing the error code to error message
+    mapping."""
+    need('Estr', 1, filename="errors.rsrc", modname=__name__)
+
+def _decode(pathname, verbose=0):
+    # Decode an AppleSingle resource file, return the new pathname.
+    newpathname = pathname + '.df.rsrc'
+    if os.path.exists(newpathname) and \
+        os.stat(newpathname).st_mtime >= os.stat(pathname).st_mtime:
+        return newpathname
+    if hasattr(os, 'access') and not \
+        os.access(os.path.dirname(pathname), os.W_OK|os.X_OK):
+        # The destination directory isn't writeable. Create the file in
+        # a temporary directory
+        import tempfile
+        fd, newpathname = tempfile.mkstemp(".rsrc")
+    if verbose:
+        print 'Decoding', pathname, 'to', newpathname
+    import applesingle
+    applesingle.decode(pathname, newpathname, resonly=1)
+    return newpathname

Added: vendor/Python/current/Lib/plat-mac/pimp.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/pimp.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/pimp.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1177 @@
+"""Package Install Manager for Python.
+
+This is currently a MacOSX-only strawman implementation.
+Despite other rumours the name stands for "Packman IMPlementation".
+
+Tools to allow easy installation of packages. The idea is that there is
+an online XML database per (platform, python-version) containing packages
+known to work with that combination. This module contains tools for getting
+and parsing the database, testing whether packages are installed, computing
+dependencies and installing packages.
+
+There is a minimal main program that works as a command line tool, but the
+intention is that the end user will use this through a GUI.
+"""
+import sys
+import os
+import popen2
+import urllib
+import urllib2
+import urlparse
+import plistlib
+import distutils.util
+import distutils.sysconfig
+import hashlib
+import tarfile
+import tempfile
+import shutil
+import time
+
+__all__ = ["PimpPreferences", "PimpDatabase", "PimpPackage", "main",
+    "getDefaultDatabase", "PIMP_VERSION", "main"]
+
+_scriptExc_NotInstalled = "pimp._scriptExc_NotInstalled"
+_scriptExc_OldInstalled = "pimp._scriptExc_OldInstalled"
+_scriptExc_BadInstalled = "pimp._scriptExc_BadInstalled"
+
+NO_EXECUTE=0
+
+PIMP_VERSION="0.5"
+
+# Flavors:
+# source: setup-based package
+# binary: tar (or other) archive created with setup.py bdist.
+# installer: something that can be opened
+DEFAULT_FLAVORORDER=['source', 'binary', 'installer']
+DEFAULT_DOWNLOADDIR='/tmp'
+DEFAULT_BUILDDIR='/tmp'
+DEFAULT_INSTALLDIR=distutils.sysconfig.get_python_lib()
+DEFAULT_PIMPDATABASE_FMT="http://www.python.org/packman/version-%s/%s-%s-%s-%s-%s.plist"
+
+def getDefaultDatabase(experimental=False):
+    if experimental:
+        status = "exp"
+    else:
+        status = "prod"
+
+    major, minor, micro, state, extra = sys.version_info
+    pyvers = '%d.%d' % (major, minor)
+    if micro == 0 and state != 'final':
+        pyvers = pyvers + '%s%d' % (state, extra)
+
+    longplatform = distutils.util.get_platform()
+    osname, release, machine = longplatform.split('-')
+    # For some platforms we may want to differentiate between
+    # installation types
+    if osname == 'darwin':
+        if sys.prefix.startswith('/System/Library/Frameworks/Python.framework'):
+            osname = 'darwin_apple'
+        elif sys.prefix.startswith('/Library/Frameworks/Python.framework'):
+            osname = 'darwin_macpython'
+        # Otherwise we don't know...
+    # Now we try various URLs by playing with the release string.
+    # We remove numbers off the end until we find a match.
+    rel = release
+    while True:
+        url = DEFAULT_PIMPDATABASE_FMT % (PIMP_VERSION, status, pyvers, osname, rel, machine)
+        try:
+            urllib2.urlopen(url)
+        except urllib2.HTTPError, arg:
+            pass
+        else:
+            break
+        if not rel:
+            # We're out of version numbers to try. Use the
+            # full release number, this will give a reasonable
+            # error message later
+            url = DEFAULT_PIMPDATABASE_FMT % (PIMP_VERSION, status, pyvers, osname, release, machine)
+            break
+        idx = rel.rfind('.')
+        if idx < 0:
+            rel = ''
+        else:
+            rel = rel[:idx]
+    return url
+
+def _cmd(output, dir, *cmditems):
+    """Internal routine to run a shell command in a given directory."""
+
+    cmd = ("cd \"%s\"; " % dir) + " ".join(cmditems)
+    if output:
+        output.write("+ %s\n" % cmd)
+    if NO_EXECUTE:
+        return 0
+    child = popen2.Popen4(cmd)
+    child.tochild.close()
+    while 1:
+        line = child.fromchild.readline()
+        if not line:
+            break
+        if output:
+            output.write(line)
+    return child.wait()
+
+class PimpDownloader:
+    """Abstract base class - Downloader for archives"""
+
+    def __init__(self, argument,
+            dir="",
+            watcher=None):
+        self.argument = argument
+        self._dir = dir
+        self._watcher = watcher
+
+    def download(self, url, filename, output=None):
+        return None
+
+    def update(self, str):
+        if self._watcher:
+            return self._watcher.update(str)
+        return True
+
+class PimpCurlDownloader(PimpDownloader):
+
+    def download(self, url, filename, output=None):
+        self.update("Downloading %s..." % url)
+        exitstatus = _cmd(output, self._dir,
+                    "curl",
+                    "--output", filename,
+                    url)
+        self.update("Downloading %s: finished" % url)
+        return (not exitstatus)
+
+class PimpUrllibDownloader(PimpDownloader):
+
+    def download(self, url, filename, output=None):
+        output = open(filename, 'wb')
+        self.update("Downloading %s: opening connection" % url)
+        keepgoing = True
+        download = urllib2.urlopen(url)
+        if download.headers.has_key("content-length"):
+            length = long(download.headers['content-length'])
+        else:
+            length = -1
+
+        data = download.read(4096) #read 4K at a time
+        dlsize = 0
+        lasttime = 0
+        while keepgoing:
+            dlsize = dlsize + len(data)
+            if len(data) == 0:
+                #this is our exit condition
+                break
+            output.write(data)
+            if int(time.time()) != lasttime:
+                # Update at most once per second
+                lasttime = int(time.time())
+                if length == -1:
+                    keepgoing = self.update("Downloading %s: %d bytes..." % (url, dlsize))
+                else:
+                    keepgoing = self.update("Downloading %s: %d%% (%d bytes)..." % (url, int(100.0*dlsize/length), dlsize))
+            data = download.read(4096)
+        if keepgoing:
+            self.update("Downloading %s: finished" % url)
+        return keepgoing
+
+class PimpUnpacker:
+    """Abstract base class - Unpacker for archives"""
+
+    _can_rename = False
+
+    def __init__(self, argument,
+            dir="",
+            renames=[],
+            watcher=None):
+        self.argument = argument
+        if renames and not self._can_rename:
+            raise RuntimeError, "This unpacker cannot rename files"
+        self._dir = dir
+        self._renames = renames
+        self._watcher = watcher
+
+    def unpack(self, archive, output=None, package=None):
+        return None
+
+    def update(self, str):
+        if self._watcher:
+            return self._watcher.update(str)
+        return True
+
+class PimpCommandUnpacker(PimpUnpacker):
+    """Unpack archives by calling a Unix utility"""
+
+    _can_rename = False
+
+    def unpack(self, archive, output=None, package=None):
+        cmd = self.argument % archive
+        if _cmd(output, self._dir, cmd):
+            return "unpack command failed"
+
+class PimpTarUnpacker(PimpUnpacker):
+    """Unpack tarfiles using the builtin tarfile module"""
+
+    _can_rename = True
+
+    def unpack(self, archive, output=None, package=None):
+        tf = tarfile.open(archive, "r")
+        members = tf.getmembers()
+        skip = []
+        if self._renames:
+            for member in members:
+                for oldprefix, newprefix in self._renames:
+                    if oldprefix[:len(self._dir)] == self._dir:
+                        oldprefix2 = oldprefix[len(self._dir):]
+                    else:
+                        oldprefix2 = None
+                    if member.name[:len(oldprefix)] == oldprefix:
+                        if newprefix is None:
+                            skip.append(member)
+                            #print 'SKIP', member.name
+                        else:
+                            member.name = newprefix + member.name[len(oldprefix):]
+                            print '    ', member.name
+                        break
+                    elif oldprefix2 and member.name[:len(oldprefix2)] == oldprefix2:
+                        if newprefix is None:
+                            skip.append(member)
+                            #print 'SKIP', member.name
+                        else:
+                            member.name = newprefix + member.name[len(oldprefix2):]
+                            #print '    ', member.name
+                        break
+                else:
+                    skip.append(member)
+                    #print '????', member.name
+        for member in members:
+            if member in skip:
+                self.update("Skipping %s" % member.name)
+                continue
+            self.update("Extracting %s" % member.name)
+            tf.extract(member, self._dir)
+        if skip:
+            names = [member.name for member in skip if member.name[-1] != '/']
+            if package:
+                names = package.filterExpectedSkips(names)
+            if names:
+                return "Not all files were unpacked: %s" % " ".join(names)
+
+ARCHIVE_FORMATS = [
+    (".tar.Z", PimpTarUnpacker, None),
+    (".taz", PimpTarUnpacker, None),
+    (".tar.gz", PimpTarUnpacker, None),
+    (".tgz", PimpTarUnpacker, None),
+    (".tar.bz", PimpTarUnpacker, None),
+    (".zip", PimpCommandUnpacker, "unzip \"%s\""),
+]
+
+class PimpPreferences:
+    """Container for per-user preferences, such as the database to use
+    and where to install packages."""
+
+    def __init__(self,
+            flavorOrder=None,
+            downloadDir=None,
+            buildDir=None,
+            installDir=None,
+            pimpDatabase=None):
+        if not flavorOrder:
+            flavorOrder = DEFAULT_FLAVORORDER
+        if not downloadDir:
+            downloadDir = DEFAULT_DOWNLOADDIR
+        if not buildDir:
+            buildDir = DEFAULT_BUILDDIR
+        if not pimpDatabase:
+            pimpDatabase = getDefaultDatabase()
+        self.setInstallDir(installDir)
+        self.flavorOrder = flavorOrder
+        self.downloadDir = downloadDir
+        self.buildDir = buildDir
+        self.pimpDatabase = pimpDatabase
+        self.watcher = None
+
+    def setWatcher(self, watcher):
+        self.watcher = watcher
+
+    def setInstallDir(self, installDir=None):
+        if installDir:
+            # Installing to non-standard location.
+            self.installLocations = [
+                ('--install-lib', installDir),
+                ('--install-headers', None),
+                ('--install-scripts', None),
+                ('--install-data', None)]
+        else:
+            installDir = DEFAULT_INSTALLDIR
+            self.installLocations = []
+        self.installDir = installDir
+
+    def isUserInstall(self):
+        return self.installDir != DEFAULT_INSTALLDIR
+
+    def check(self):
+        """Check that the preferences make sense: directories exist and are
+        writable, the install directory is on sys.path, etc."""
+
+        rv = ""
+        RWX_OK = os.R_OK|os.W_OK|os.X_OK
+        if not os.path.exists(self.downloadDir):
+            rv += "Warning: Download directory \"%s\" does not exist\n" % self.downloadDir
+        elif not os.access(self.downloadDir, RWX_OK):
+            rv += "Warning: Download directory \"%s\" is not writable or not readable\n" % self.downloadDir
+        if not os.path.exists(self.buildDir):
+            rv += "Warning: Build directory \"%s\" does not exist\n" % self.buildDir
+        elif not os.access(self.buildDir, RWX_OK):
+            rv += "Warning: Build directory \"%s\" is not writable or not readable\n" % self.buildDir
+        if not os.path.exists(self.installDir):
+            rv += "Warning: Install directory \"%s\" does not exist\n" % self.installDir
+        elif not os.access(self.installDir, RWX_OK):
+            rv += "Warning: Install directory \"%s\" is not writable or not readable\n" % self.installDir
+        else:
+            installDir = os.path.realpath(self.installDir)
+            for p in sys.path:
+                try:
+                    realpath = os.path.realpath(p)
+                except:
+                    pass
+                if installDir == realpath:
+                    break
+            else:
+                rv += "Warning: Install directory \"%s\" is not on sys.path\n" % self.installDir
+        return rv
+
+    def compareFlavors(self, left, right):
+        """Compare two flavor strings. This is part of your preferences
+        because whether the user prefers installing from source or binary is."""
+        if left in self.flavorOrder:
+            if right in self.flavorOrder:
+                return cmp(self.flavorOrder.index(left), self.flavorOrder.index(right))
+            return -1
+        if right in self.flavorOrder:
+            return 1
+        return cmp(left, right)
+
+class PimpDatabase:
+    """Class representing a pimp database. It can actually contain
+    information from multiple databases through inclusion, but the
+    toplevel database is considered the master, as its maintainer is
+    "responsible" for the contents."""
+
+    def __init__(self, prefs):
+        self._packages = []
+        self.preferences = prefs
+        self._url = ""
+        self._urllist = []
+        self._version = ""
+        self._maintainer = ""
+        self._description = ""
+
+    # Accessor functions
+    def url(self): return self._url
+    def version(self): return self._version
+    def maintainer(self): return self._maintainer
+    def description(self): return self._description
+
+    def close(self):
+        """Clean up"""
+        self._packages = []
+        self.preferences = None
+
+    def appendURL(self, url, included=0):
+        """Append packages from the database with the given URL.
+        Only the first database should specify included=0, so the
+        global information (maintainer, description) get stored."""
+
+        if url in self._urllist:
+            return
+        self._urllist.append(url)
+        fp = urllib2.urlopen(url).fp
+        plistdata = plistlib.Plist.fromFile(fp)
+        # Test here for Pimp version, etc
+        if included:
+            version = plistdata.get('Version')
+            if version and version > self._version:
+                sys.stderr.write("Warning: included database %s is for pimp version %s\n" %
+                    (url, version))
+        else:
+            self._version = plistdata.get('Version')
+            if not self._version:
+                sys.stderr.write("Warning: database has no Version information\n")
+            elif self._version > PIMP_VERSION:
+                sys.stderr.write("Warning: database version %s newer than pimp version %s\n"
+                    % (self._version, PIMP_VERSION))
+            self._maintainer = plistdata.get('Maintainer', '')
+            self._description = plistdata.get('Description', '').strip()
+            self._url = url
+        self._appendPackages(plistdata['Packages'], url)
+        others = plistdata.get('Include', [])
+        for o in others:
+            o = urllib.basejoin(url, o)
+            self.appendURL(o, included=1)
+
+    def _appendPackages(self, packages, url):
+        """Given a list of dictionaries containing package
+        descriptions create the PimpPackage objects and append them
+        to our internal storage."""
+
+        for p in packages:
+            p = dict(p)
+            if p.has_key('Download-URL'):
+                p['Download-URL'] = urllib.basejoin(url, p['Download-URL'])
+            flavor = p.get('Flavor')
+            if flavor == 'source':
+                pkg = PimpPackage_source(self, p)
+            elif flavor == 'binary':
+                pkg = PimpPackage_binary(self, p)
+            elif flavor == 'installer':
+                pkg = PimpPackage_installer(self, p)
+            elif flavor == 'hidden':
+                pkg = PimpPackage_installer(self, p)
+            else:
+                pkg = PimpPackage(self, dict(p))
+            self._packages.append(pkg)
+
+    def list(self):
+        """Return a list of all PimpPackage objects in the database."""
+
+        return self._packages
+
+    def listnames(self):
+        """Return a list of names of all packages in the database."""
+
+        rv = []
+        for pkg in self._packages:
+            rv.append(pkg.fullname())
+        rv.sort()
+        return rv
+
+    def dump(self, pathOrFile):
+        """Dump the contents of the database to an XML .plist file.
+
+        The file can be passed as either a file object or a pathname.
+        All data, including included databases, is dumped."""
+
+        packages = []
+        for pkg in self._packages:
+            packages.append(pkg.dump())
+        plistdata = {
+            'Version': self._version,
+            'Maintainer': self._maintainer,
+            'Description': self._description,
+            'Packages': packages
+            }
+        plist = plistlib.Plist(**plistdata)
+        plist.write(pathOrFile)
+
+    def find(self, ident):
+        """Find a package. The package can be specified by name
+        or as a dictionary with name, version and flavor entries.
+
+        Only name is obligatory. If there are multiple matches the
+        best one (higher version number, flavors ordered according to
+        users' preference) is returned."""
+
+        if type(ident) == str:
+            # Remove ( and ) for pseudo-packages
+            if ident[0] == '(' and ident[-1] == ')':
+                ident = ident[1:-1]
+            # Split into name-version-flavor
+            fields = ident.split('-')
+            if len(fields) < 1 or len(fields) > 3:
+                return None
+            name = fields[0]
+            if len(fields) > 1:
+                version = fields[1]
+            else:
+                version = None
+            if len(fields) > 2:
+                flavor = fields[2]
+            else:
+                flavor = None
+        else:
+            name = ident['Name']
+            version = ident.get('Version')
+            flavor = ident.get('Flavor')
+        found = None
+        for p in self._packages:
+            if name == p.name() and \
+                    (not version or version == p.version()) and \
+                    (not flavor or flavor == p.flavor()):
+                if not found or found < p:
+                    found = p
+        return found
+
+ALLOWED_KEYS = [
+    "Name",
+    "Version",
+    "Flavor",
+    "Description",
+    "Home-page",
+    "Download-URL",
+    "Install-test",
+    "Install-command",
+    "Pre-install-command",
+    "Post-install-command",
+    "Prerequisites",
+    "MD5Sum",
+    "User-install-skips",
+    "Systemwide-only",
+]
+
+class PimpPackage:
+    """Class representing a single package."""
+
+    def __init__(self, db, plistdata):
+        self._db = db
+        name = plistdata["Name"]
+        for k in plistdata.keys():
+            if not k in ALLOWED_KEYS:
+                sys.stderr.write("Warning: %s: unknown key %s\n" % (name, k))
+        self._dict = plistdata
+
+    def __getitem__(self, key):
+        return self._dict[key]
+
+    def name(self): return self._dict['Name']
+    def version(self): return self._dict.get('Version')
+    def flavor(self): return self._dict.get('Flavor')
+    def description(self): return self._dict['Description'].strip()
+    def shortdescription(self): return self.description().splitlines()[0]
+    def homepage(self): return self._dict.get('Home-page')
+    def downloadURL(self): return self._dict.get('Download-URL')
+    def systemwideOnly(self): return self._dict.get('Systemwide-only')
+
+    def fullname(self):
+        """Return the full name "name-version-flavor" of a package.
+
+        If the package is a pseudo-package, something that cannot be
+        installed through pimp, return the name in (parentheses)."""
+
+        rv = self._dict['Name']
+        if self._dict.has_key('Version'):
+            rv = rv + '-%s' % self._dict['Version']
+        if self._dict.has_key('Flavor'):
+            rv = rv + '-%s' % self._dict['Flavor']
+        if self._dict.get('Flavor') == 'hidden':
+            # Pseudo-package, show in parentheses
+            rv = '(%s)' % rv
+        return rv
+
+    def dump(self):
+        """Return a dict object containing the information on the package."""
+        return self._dict
+
+    def __cmp__(self, other):
+        """Compare two packages, where the "better" package sorts lower."""
+
+        if not isinstance(other, PimpPackage):
+            return cmp(id(self), id(other))
+        if self.name() != other.name():
+            return cmp(self.name(), other.name())
+        if self.version() != other.version():
+            return -cmp(self.version(), other.version())
+        return self._db.preferences.compareFlavors(self.flavor(), other.flavor())
+
+    def installed(self):
+        """Test wheter the package is installed.
+
+        Returns two values: a status indicator which is one of
+        "yes", "no", "old" (an older version is installed) or "bad"
+        (something went wrong during the install test) and a human
+        readable string which may contain more details."""
+
+        namespace = {
+            "NotInstalled": _scriptExc_NotInstalled,
+            "OldInstalled": _scriptExc_OldInstalled,
+            "BadInstalled": _scriptExc_BadInstalled,
+            "os": os,
+            "sys": sys,
+            }
+        installTest = self._dict['Install-test'].strip() + '\n'
+        try:
+            exec installTest in namespace
+        except ImportError, arg:
+            return "no", str(arg)
+        except _scriptExc_NotInstalled, arg:
+            return "no", str(arg)
+        except _scriptExc_OldInstalled, arg:
+            return "old", str(arg)
+        except _scriptExc_BadInstalled, arg:
+            return "bad", str(arg)
+        except:
+            sys.stderr.write("-------------------------------------\n")
+            sys.stderr.write("---- %s: install test got exception\n" % self.fullname())
+            sys.stderr.write("---- source:\n")
+            sys.stderr.write(installTest)
+            sys.stderr.write("---- exception:\n")
+            import traceback
+            traceback.print_exc(file=sys.stderr)
+            if self._db._maintainer:
+                sys.stderr.write("---- Please copy this and mail to %s\n" % self._db._maintainer)
+            sys.stderr.write("-------------------------------------\n")
+            return "bad", "Package install test got exception"
+        return "yes", ""
+
+    def prerequisites(self):
+        """Return a list of prerequisites for this package.
+
+        The list contains 2-tuples, of which the first item is either
+        a PimpPackage object or None, and the second is a descriptive
+        string. The first item can be None if this package depends on
+        something that isn't pimp-installable, in which case the descriptive
+        string should tell the user what to do."""
+
+        rv = []
+        if not self._dict.get('Download-URL'):
+            # For pseudo-packages that are already installed we don't
+            # return an error message
+            status, _  = self.installed()
+            if status == "yes":
+                return []
+            return [(None,
+                "Package %s cannot be installed automatically, see the description" %
+                    self.fullname())]
+        if self.systemwideOnly() and self._db.preferences.isUserInstall():
+            return [(None,
+                "Package %s can only be installed system-wide" %
+                    self.fullname())]
+        if not self._dict.get('Prerequisites'):
+            return []
+        for item in self._dict['Prerequisites']:
+            if type(item) == str:
+                pkg = None
+                descr = str(item)
+            else:
+                name = item['Name']
+                if item.has_key('Version'):
+                    name = name + '-' + item['Version']
+                if item.has_key('Flavor'):
+                    name = name + '-' + item['Flavor']
+                pkg = self._db.find(name)
+                if not pkg:
+                    descr = "Requires unknown %s"%name
+                else:
+                    descr = pkg.shortdescription()
+            rv.append((pkg, descr))
+        return rv
+
+
+    def downloadPackageOnly(self, output=None):
+        """Download a single package, if needed.
+
+        An MD5 signature is used to determine whether download is needed,
+        and to test that we actually downloaded what we expected.
+        If output is given it is a file-like object that will receive a log
+        of what happens.
+
+        If anything unforeseen happened the method returns an error message
+        string.
+        """
+
+        scheme, loc, path, query, frag = urlparse.urlsplit(self._dict['Download-URL'])
+        path = urllib.url2pathname(path)
+        filename = os.path.split(path)[1]
+        self.archiveFilename = os.path.join(self._db.preferences.downloadDir, filename)
+        if not self._archiveOK():
+            if scheme == 'manual':
+                return "Please download package manually and save as %s" % self.archiveFilename
+            downloader = PimpUrllibDownloader(None, self._db.preferences.downloadDir,
+                watcher=self._db.preferences.watcher)
+            if not downloader.download(self._dict['Download-URL'],
+                    self.archiveFilename, output):
+                return "download command failed"
+        if not os.path.exists(self.archiveFilename) and not NO_EXECUTE:
+            return "archive not found after download"
+        if not self._archiveOK():
+            return "archive does not have correct MD5 checksum"
+
+    def _archiveOK(self):
+        """Test an archive. It should exist and the MD5 checksum should be correct."""
+
+        if not os.path.exists(self.archiveFilename):
+            return 0
+        if not self._dict.get('MD5Sum'):
+            sys.stderr.write("Warning: no MD5Sum for %s\n" % self.fullname())
+            return 1
+        data = open(self.archiveFilename, 'rb').read()
+        checksum = hashlib.md5(data).hexdigest()
+        return checksum == self._dict['MD5Sum']
+
+    def unpackPackageOnly(self, output=None):
+        """Unpack a downloaded package archive."""
+
+        filename = os.path.split(self.archiveFilename)[1]
+        for ext, unpackerClass, arg in ARCHIVE_FORMATS:
+            if filename[-len(ext):] == ext:
+                break
+        else:
+            return "unknown extension for archive file: %s" % filename
+        self.basename = filename[:-len(ext)]
+        unpacker = unpackerClass(arg, dir=self._db.preferences.buildDir,
+                watcher=self._db.preferences.watcher)
+        rv = unpacker.unpack(self.archiveFilename, output=output)
+        if rv:
+            return rv
+
+    def installPackageOnly(self, output=None):
+        """Default install method, to be overridden by subclasses"""
+        return "%s: This package needs to be installed manually (no support for flavor=\"%s\")" \
+            % (self.fullname(), self._dict.get(flavor, ""))
+
+    def installSinglePackage(self, output=None):
+        """Download, unpack and install a single package.
+
+        If output is given it should be a file-like object and it
+        will receive a log of what happened."""
+
+        if not self._dict.get('Download-URL'):
+            return "%s: This package needs to be installed manually (no Download-URL field)" % self.fullname()
+        msg = self.downloadPackageOnly(output)
+        if msg:
+            return "%s: download: %s" % (self.fullname(), msg)
+
+        msg = self.unpackPackageOnly(output)
+        if msg:
+            return "%s: unpack: %s" % (self.fullname(), msg)
+
+        return self.installPackageOnly(output)
+
+    def beforeInstall(self):
+        """Bookkeeping before installation: remember what we have in site-packages"""
+        self._old_contents = os.listdir(self._db.preferences.installDir)
+
+    def afterInstall(self):
+        """Bookkeeping after installation: interpret any new .pth files that have
+        appeared"""
+
+        new_contents = os.listdir(self._db.preferences.installDir)
+        for fn in new_contents:
+            if fn in self._old_contents:
+                continue
+            if fn[-4:] != '.pth':
+                continue
+            fullname = os.path.join(self._db.preferences.installDir, fn)
+            f = open(fullname)
+            for line in f.readlines():
+                if not line:
+                    continue
+                if line[0] == '#':
+                    continue
+                if line[:6] == 'import':
+                    exec line
+                    continue
+                if line[-1] == '\n':
+                    line = line[:-1]
+                if not os.path.isabs(line):
+                    line = os.path.join(self._db.preferences.installDir, line)
+                line = os.path.realpath(line)
+                if not line in sys.path:
+                    sys.path.append(line)
+
+    def filterExpectedSkips(self, names):
+        """Return a list that contains only unpexpected skips"""
+        if not self._db.preferences.isUserInstall():
+            return names
+        expected_skips = self._dict.get('User-install-skips')
+        if not expected_skips:
+            return names
+        newnames = []
+        for name in names:
+            for skip in expected_skips:
+                if name[:len(skip)] == skip:
+                    break
+            else:
+                newnames.append(name)
+        return newnames
+
+class PimpPackage_binary(PimpPackage):
+
+    def unpackPackageOnly(self, output=None):
+        """We don't unpack binary packages until installing"""
+        pass
+
+    def installPackageOnly(self, output=None):
+        """Install a single source package.
+
+        If output is given it should be a file-like object and it
+        will receive a log of what happened."""
+
+        if self._dict.has_key('Install-command'):
+            return "%s: Binary package cannot have Install-command" % self.fullname()
+
+        if self._dict.has_key('Pre-install-command'):
+            if _cmd(output, '/tmp', self._dict['Pre-install-command']):
+                return "pre-install %s: running \"%s\" failed" % \
+                    (self.fullname(), self._dict['Pre-install-command'])
+
+        self.beforeInstall()
+
+        # Install by unpacking
+        filename = os.path.split(self.archiveFilename)[1]
+        for ext, unpackerClass, arg in ARCHIVE_FORMATS:
+            if filename[-len(ext):] == ext:
+                break
+        else:
+            return "%s: unknown extension for archive file: %s" % (self.fullname(), filename)
+        self.basename = filename[:-len(ext)]
+
+        install_renames = []
+        for k, newloc in self._db.preferences.installLocations:
+            if not newloc:
+                continue
+            if k == "--install-lib":
+                oldloc = DEFAULT_INSTALLDIR
+            else:
+                return "%s: Don't know installLocation %s" % (self.fullname(), k)
+            install_renames.append((oldloc, newloc))
+
+        unpacker = unpackerClass(arg, dir="/", renames=install_renames)
+        rv = unpacker.unpack(self.archiveFilename, output=output, package=self)
+        if rv:
+            return rv
+
+        self.afterInstall()
+
+        if self._dict.has_key('Post-install-command'):
+            if _cmd(output, '/tmp', self._dict['Post-install-command']):
+                return "%s: post-install: running \"%s\" failed" % \
+                    (self.fullname(), self._dict['Post-install-command'])
+
+        return None
+
+
+class PimpPackage_source(PimpPackage):
+
+    def unpackPackageOnly(self, output=None):
+        """Unpack a source package and check that setup.py exists"""
+        PimpPackage.unpackPackageOnly(self, output)
+        # Test that a setup script has been create
+        self._buildDirname = os.path.join(self._db.preferences.buildDir, self.basename)
+        setupname = os.path.join(self._buildDirname, "setup.py")
+        if not os.path.exists(setupname) and not NO_EXECUTE:
+            return "no setup.py found after unpack of archive"
+
+    def installPackageOnly(self, output=None):
+        """Install a single source package.
+
+        If output is given it should be a file-like object and it
+        will receive a log of what happened."""
+
+        if self._dict.has_key('Pre-install-command'):
+            if _cmd(output, self._buildDirname, self._dict['Pre-install-command']):
+                return "pre-install %s: running \"%s\" failed" % \
+                    (self.fullname(), self._dict['Pre-install-command'])
+
+        self.beforeInstall()
+        installcmd = self._dict.get('Install-command')
+        if installcmd and self._install_renames:
+            return "Package has install-command and can only be installed to standard location"
+        # This is the "bit-bucket" for installations: everything we don't
+        # want. After installation we check that it is actually empty
+        unwanted_install_dir = None
+        if not installcmd:
+            extra_args = ""
+            for k, v in self._db.preferences.installLocations:
+                if not v:
+                    # We don't want these files installed. Send them
+                    # to the bit-bucket.
+                    if not unwanted_install_dir:
+                        unwanted_install_dir = tempfile.mkdtemp()
+                    v = unwanted_install_dir
+                extra_args = extra_args + " %s \"%s\"" % (k, v)
+            installcmd = '"%s" setup.py install %s' % (sys.executable, extra_args)
+        if _cmd(output, self._buildDirname, installcmd):
+            return "install %s: running \"%s\" failed" % \
+                (self.fullname(), installcmd)
+        if unwanted_install_dir and os.path.exists(unwanted_install_dir):
+            unwanted_files = os.listdir(unwanted_install_dir)
+            if unwanted_files:
+                rv = "Warning: some files were not installed: %s" % " ".join(unwanted_files)
+            else:
+                rv = None
+            shutil.rmtree(unwanted_install_dir)
+            return rv
+
+        self.afterInstall()
+
+        if self._dict.has_key('Post-install-command'):
+            if _cmd(output, self._buildDirname, self._dict['Post-install-command']):
+                return "post-install %s: running \"%s\" failed" % \
+                    (self.fullname(), self._dict['Post-install-command'])
+        return None
+
+class PimpPackage_installer(PimpPackage):
+
+    def unpackPackageOnly(self, output=None):
+        """We don't unpack dmg packages until installing"""
+        pass
+
+    def installPackageOnly(self, output=None):
+        """Install a single source package.
+
+        If output is given it should be a file-like object and it
+        will receive a log of what happened."""
+
+        if self._dict.has_key('Post-install-command'):
+            return "%s: Installer package cannot have Post-install-command" % self.fullname()
+
+        if self._dict.has_key('Pre-install-command'):
+            if _cmd(output, '/tmp', self._dict['Pre-install-command']):
+                return "pre-install %s: running \"%s\" failed" % \
+                    (self.fullname(), self._dict['Pre-install-command'])
+
+        self.beforeInstall()
+
+        installcmd = self._dict.get('Install-command')
+        if installcmd:
+            if '%' in installcmd:
+                installcmd = installcmd % self.archiveFilename
+        else:
+            installcmd = 'open \"%s\"' % self.archiveFilename
+        if _cmd(output, "/tmp", installcmd):
+            return '%s: install command failed (use verbose for details)' % self.fullname()
+        return '%s: downloaded and opened. Install manually and restart Package Manager' % self.archiveFilename
+
+class PimpInstaller:
+    """Installer engine: computes dependencies and installs
+    packages in the right order."""
+
+    def __init__(self, db):
+        self._todo = []
+        self._db = db
+        self._curtodo = []
+        self._curmessages = []
+
+    def __contains__(self, package):
+        return package in self._todo
+
+    def _addPackages(self, packages):
+        for package in packages:
+            if not package in self._todo:
+                self._todo.append(package)
+
+    def _prepareInstall(self, package, force=0, recursive=1):
+        """Internal routine, recursive engine for prepareInstall.
+
+        Test whether the package is installed and (if not installed
+        or if force==1) prepend it to the temporary todo list and
+        call ourselves recursively on all prerequisites."""
+
+        if not force:
+            status, message = package.installed()
+            if status == "yes":
+                return
+        if package in self._todo or package in self._curtodo:
+            return
+        self._curtodo.insert(0, package)
+        if not recursive:
+            return
+        prereqs = package.prerequisites()
+        for pkg, descr in prereqs:
+            if pkg:
+                self._prepareInstall(pkg, False, recursive)
+            else:
+                self._curmessages.append("Problem with dependency: %s" % descr)
+
+    def prepareInstall(self, package, force=0, recursive=1):
+        """Prepare installation of a package.
+
+        If the package is already installed and force is false nothing
+        is done. If recursive is true prerequisites are installed first.
+
+        Returns a list of packages (to be passed to install) and a list
+        of messages of any problems encountered.
+        """
+
+        self._curtodo = []
+        self._curmessages = []
+        self._prepareInstall(package, force, recursive)
+        rv = self._curtodo, self._curmessages
+        self._curtodo = []
+        self._curmessages = []
+        return rv
+
+    def install(self, packages, output):
+        """Install a list of packages."""
+
+        self._addPackages(packages)
+        status = []
+        for pkg in self._todo:
+            msg = pkg.installSinglePackage(output)
+            if msg:
+                status.append(msg)
+        return status
+
+
+
+def _run(mode, verbose, force, args, prefargs, watcher):
+    """Engine for the main program"""
+
+    prefs = PimpPreferences(**prefargs)
+    if watcher:
+        prefs.setWatcher(watcher)
+    rv = prefs.check()
+    if rv:
+        sys.stdout.write(rv)
+    db = PimpDatabase(prefs)
+    db.appendURL(prefs.pimpDatabase)
+
+    if mode == 'dump':
+        db.dump(sys.stdout)
+    elif mode =='list':
+        if not args:
+            args = db.listnames()
+        print "%-20.20s\t%s" % ("Package", "Description")
+        print
+        for pkgname in args:
+            pkg = db.find(pkgname)
+            if pkg:
+                description = pkg.shortdescription()
+                pkgname = pkg.fullname()
+            else:
+                description = 'Error: no such package'
+            print "%-20.20s\t%s" % (pkgname, description)
+            if verbose:
+                print "\tHome page:\t", pkg.homepage()
+                try:
+                    print "\tDownload URL:\t", pkg.downloadURL()
+                except KeyError:
+                    pass
+                description = pkg.description()
+                description = '\n\t\t\t\t\t'.join(description.splitlines())
+                print "\tDescription:\t%s" % description
+    elif mode =='status':
+        if not args:
+            args = db.listnames()
+            print "%-20.20s\t%s\t%s" % ("Package", "Installed", "Message")
+            print
+        for pkgname in args:
+            pkg = db.find(pkgname)
+            if pkg:
+                status, msg = pkg.installed()
+                pkgname = pkg.fullname()
+            else:
+                status = 'error'
+                msg = 'No such package'
+            print "%-20.20s\t%-9.9s\t%s" % (pkgname, status, msg)
+            if verbose and status == "no":
+                prereq = pkg.prerequisites()
+                for pkg, msg in prereq:
+                    if not pkg:
+                        pkg = ''
+                    else:
+                        pkg = pkg.fullname()
+                    print "%-20.20s\tRequirement: %s %s" % ("", pkg, msg)
+    elif mode == 'install':
+        if not args:
+            print 'Please specify packages to install'
+            sys.exit(1)
+        inst = PimpInstaller(db)
+        for pkgname in args:
+            pkg = db.find(pkgname)
+            if not pkg:
+                print '%s: No such package' % pkgname
+                continue
+            list, messages = inst.prepareInstall(pkg, force)
+            if messages and not force:
+                print "%s: Not installed:" % pkgname
+                for m in messages:
+                    print "\t", m
+            else:
+                if verbose:
+                    output = sys.stdout
+                else:
+                    output = None
+                messages = inst.install(list, output)
+                if messages:
+                    print "%s: Not installed:" % pkgname
+                    for m in messages:
+                        print "\t", m
+
+def main():
+    """Minimal commandline tool to drive pimp."""
+
+    import getopt
+    def _help():
+        print "Usage: pimp [options] -s [package ...]  List installed status"
+        print "       pimp [options] -l [package ...]  Show package information"
+        print "       pimp [options] -i package ...    Install packages"
+        print "       pimp -d                          Dump database to stdout"
+        print "       pimp -V                          Print version number"
+        print "Options:"
+        print "       -v     Verbose"
+        print "       -f     Force installation"
+        print "       -D dir Set destination directory"
+        print "              (default: %s)" % DEFAULT_INSTALLDIR
+        print "       -u url URL for database"
+        sys.exit(1)
+
+    class _Watcher:
+        def update(self, msg):
+            sys.stderr.write(msg + '\r')
+            return 1
+
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], "slifvdD:Vu:")
+    except getopt.GetoptError:
+        _help()
+    if not opts and not args:
+        _help()
+    mode = None
+    force = 0
+    verbose = 0
+    prefargs = {}
+    watcher = None
+    for o, a in opts:
+        if o == '-s':
+            if mode:
+                _help()
+            mode = 'status'
+        if o == '-l':
+            if mode:
+                _help()
+            mode = 'list'
+        if o == '-d':
+            if mode:
+                _help()
+            mode = 'dump'
+        if o == '-V':
+            if mode:
+                _help()
+            mode = 'version'
+        if o == '-i':
+            mode = 'install'
+        if o == '-f':
+            force = 1
+        if o == '-v':
+            verbose = 1
+            watcher = _Watcher()
+        if o == '-D':
+            prefargs['installDir'] = a
+        if o == '-u':
+            prefargs['pimpDatabase'] = a
+    if not mode:
+        _help()
+    if mode == 'version':
+        print 'Pimp version %s; module name is %s' % (PIMP_VERSION, __name__)
+    else:
+        _run(mode, verbose, force, args, prefargs, watcher)
+
+# Finally, try to update ourselves to a newer version.
+# If the end-user updates pimp through pimp the new version
+# will be called pimp_update and live in site-packages
+# or somewhere similar
+if __name__ != 'pimp_update':
+    try:
+        import pimp_update
+    except ImportError:
+        pass
+    else:
+        if pimp_update.PIMP_VERSION <= PIMP_VERSION:
+            import warnings
+            warnings.warn("pimp_update is version %s, not newer than pimp version %s" %
+                (pimp_update.PIMP_VERSION, PIMP_VERSION))
+        else:
+            from pimp_update import *
+
+if __name__ == '__main__':
+    main()

Added: vendor/Python/current/Lib/plat-mac/plistlib.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/plistlib.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/plistlib.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,470 @@
+"""plistlib.py -- a tool to generate and parse MacOSX .plist files.
+
+The PropertList (.plist) file format is a simple XML pickle supporting
+basic object types, like dictionaries, lists, numbers and strings.
+Usually the top level object is a dictionary.
+
+To write out a plist file, use the writePlist(rootObject, pathOrFile)
+function. 'rootObject' is the top level object, 'pathOrFile' is a
+filename or a (writable) file object.
+
+To parse a plist from a file, use the readPlist(pathOrFile) function,
+with a file name or a (readable) file object as the only argument. It
+returns the top level object (again, usually a dictionary).
+
+To work with plist data in strings, you can use readPlistFromString()
+and writePlistToString().
+
+Values can be strings, integers, floats, booleans, tuples, lists,
+dictionaries, Data or datetime.datetime objects. String values (including
+dictionary keys) may be unicode strings -- they will be written out as
+UTF-8.
+
+The <data> plist type is supported through the Data class. This is a
+thin wrapper around a Python string.
+
+Generate Plist example:
+
+    pl = dict(
+        aString="Doodah",
+        aList=["A", "B", 12, 32.1, [1, 2, 3]],
+        aFloat = 0.1,
+        anInt = 728,
+        aDict=dict(
+            anotherString="<hello & hi there!>",
+            aUnicodeValue=u'M\xe4ssig, Ma\xdf',
+            aTrueValue=True,
+            aFalseValue=False,
+        ),
+        someData = Data("<binary gunk>"),
+        someMoreData = Data("<lots of binary gunk>" * 10),
+        aDate = datetime.datetime.fromtimestamp(time.mktime(time.gmtime())),
+    )
+    # unicode keys are possible, but a little awkward to use:
+    pl[u'\xc5benraa'] = "That was a unicode key."
+    writePlist(pl, fileName)
+
+Parse Plist example:
+
+    pl = readPlist(pathOrFile)
+    print pl["aKey"]
+"""
+
+
+__all__ = [
+    "readPlist", "writePlist", "readPlistFromString", "writePlistToString",
+    "readPlistFromResource", "writePlistToResource",
+    "Plist", "Data", "Dict"
+]
+# Note: the Plist and Dict classes have been deprecated.
+
+import binascii
+import datetime
+from cStringIO import StringIO
+import re
+
+
+def readPlist(pathOrFile):
+    """Read a .plist file. 'pathOrFile' may either be a file name or a
+    (readable) file object. Return the unpacked root object (which
+    usually is a dictionary).
+    """
+    didOpen = 0
+    if isinstance(pathOrFile, (str, unicode)):
+        pathOrFile = open(pathOrFile)
+        didOpen = 1
+    p = PlistParser()
+    rootObject = p.parse(pathOrFile)
+    if didOpen:
+        pathOrFile.close()
+    return rootObject
+
+
+def writePlist(rootObject, pathOrFile):
+    """Write 'rootObject' to a .plist file. 'pathOrFile' may either be a
+    file name or a (writable) file object.
+    """
+    didOpen = 0
+    if isinstance(pathOrFile, (str, unicode)):
+        pathOrFile = open(pathOrFile, "w")
+        didOpen = 1
+    writer = PlistWriter(pathOrFile)
+    writer.writeln("<plist version=\"1.0\">")
+    writer.writeValue(rootObject)
+    writer.writeln("</plist>")
+    if didOpen:
+        pathOrFile.close()
+
+
+def readPlistFromString(data):
+    """Read a plist data from a string. Return the root object.
+    """
+    return readPlist(StringIO(data))
+
+
+def writePlistToString(rootObject):
+    """Return 'rootObject' as a plist-formatted string.
+    """
+    f = StringIO()
+    writePlist(rootObject, f)
+    return f.getvalue()
+
+
+def readPlistFromResource(path, restype='plst', resid=0):
+    """Read plst resource from the resource fork of path.
+    """
+    from Carbon.File import FSRef, FSGetResourceForkName
+    from Carbon.Files import fsRdPerm
+    from Carbon import Res
+    fsRef = FSRef(path)
+    resNum = Res.FSOpenResourceFile(fsRef, FSGetResourceForkName(), fsRdPerm)
+    Res.UseResFile(resNum)
+    plistData = Res.Get1Resource(restype, resid).data
+    Res.CloseResFile(resNum)
+    return readPlistFromString(plistData)
+
+
+def writePlistToResource(rootObject, path, restype='plst', resid=0):
+    """Write 'rootObject' as a plst resource to the resource fork of path.
+    """
+    from Carbon.File import FSRef, FSGetResourceForkName
+    from Carbon.Files import fsRdWrPerm
+    from Carbon import Res
+    plistData = writePlistToString(rootObject)
+    fsRef = FSRef(path)
+    resNum = Res.FSOpenResourceFile(fsRef, FSGetResourceForkName(), fsRdWrPerm)
+    Res.UseResFile(resNum)
+    try:
+        Res.Get1Resource(restype, resid).RemoveResource()
+    except Res.Error:
+        pass
+    res = Res.Resource(plistData)
+    res.AddResource(restype, resid, '')
+    res.WriteResource()
+    Res.CloseResFile(resNum)
+
+
+class DumbXMLWriter:
+
+    def __init__(self, file, indentLevel=0, indent="\t"):
+        self.file = file
+        self.stack = []
+        self.indentLevel = indentLevel
+        self.indent = indent
+
+    def beginElement(self, element):
+        self.stack.append(element)
+        self.writeln("<%s>" % element)
+        self.indentLevel += 1
+
+    def endElement(self, element):
+        assert self.indentLevel > 0
+        assert self.stack.pop() == element
+        self.indentLevel -= 1
+        self.writeln("</%s>" % element)
+
+    def simpleElement(self, element, value=None):
+        if value is not None:
+            value = _escapeAndEncode(value)
+            self.writeln("<%s>%s</%s>" % (element, value, element))
+        else:
+            self.writeln("<%s/>" % element)
+
+    def writeln(self, line):
+        if line:
+            self.file.write(self.indentLevel * self.indent + line + "\n")
+        else:
+            self.file.write("\n")
+
+
+# Contents should conform to a subset of ISO 8601
+# (in particular, YYYY '-' MM '-' DD 'T' HH ':' MM ':' SS 'Z'.  Smaller units may be omitted with
+#  a loss of precision)
+_dateParser = re.compile(r"(?P<year>\d\d\d\d)(?:-(?P<month>\d\d)(?:-(?P<day>\d\d)(?:T(?P<hour>\d\d)(?::(?P<minute>\d\d)(?::(?P<second>\d\d))?)?)?)?)?Z")
+
+def _dateFromString(s):
+    order = ('year', 'month', 'day', 'hour', 'minute', 'second')
+    gd = _dateParser.match(s).groupdict()
+    lst = []
+    for key in order:
+        val = gd[key]
+        if val is None:
+            break
+        lst.append(int(val))
+    return datetime.datetime(*lst)
+
+def _dateToString(d):
+    return '%04d-%02d-%02dT%02d:%02d:%02dZ' % (
+        d.year, d.month, d.day,
+        d.hour, d.minute, d.second
+    )
+
+
+# Regex to find any control chars, except for \t \n and \r
+_controlCharPat = re.compile(
+    r"[\x00\x01\x02\x03\x04\x05\x06\x07\x08\x0b\x0c\x0e\x0f"
+    r"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f]")
+
+def _escapeAndEncode(text):
+    m = _controlCharPat.search(text)
+    if m is not None:
+        raise ValueError("strings can't contains control characters; "
+                         "use plistlib.Data instead")
+    text = text.replace("\r\n", "\n")       # convert DOS line endings
+    text = text.replace("\r", "\n")         # convert Mac line endings
+    text = text.replace("&", "&amp;")       # escape '&'
+    text = text.replace("<", "&lt;")        # escape '<'
+    text = text.replace(">", "&gt;")        # escape '>'
+    return text.encode("utf-8")             # encode as UTF-8
+
+
+PLISTHEADER = """\
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+"""
+
+class PlistWriter(DumbXMLWriter):
+
+    def __init__(self, file, indentLevel=0, indent="\t", writeHeader=1):
+        if writeHeader:
+            file.write(PLISTHEADER)
+        DumbXMLWriter.__init__(self, file, indentLevel, indent)
+
+    def writeValue(self, value):
+        if isinstance(value, (str, unicode)):
+            self.simpleElement("string", value)
+        elif isinstance(value, bool):
+            # must switch for bool before int, as bool is a
+            # subclass of int...
+            if value:
+                self.simpleElement("true")
+            else:
+                self.simpleElement("false")
+        elif isinstance(value, int):
+            self.simpleElement("integer", str(value))
+        elif isinstance(value, float):
+            self.simpleElement("real", repr(value))
+        elif isinstance(value, dict):
+            self.writeDict(value)
+        elif isinstance(value, Data):
+            self.writeData(value)
+        elif isinstance(value, datetime.datetime):
+            self.simpleElement("date", _dateToString(value))
+        elif isinstance(value, (tuple, list)):
+            self.writeArray(value)
+        else:
+            raise TypeError("unsuported type: %s" % type(value))
+
+    def writeData(self, data):
+        self.beginElement("data")
+        self.indentLevel -= 1
+        maxlinelength = 76 - len(self.indent.replace("\t", " " * 8) *
+                                 self.indentLevel)
+        for line in data.asBase64(maxlinelength).split("\n"):
+            if line:
+                self.writeln(line)
+        self.indentLevel += 1
+        self.endElement("data")
+
+    def writeDict(self, d):
+        self.beginElement("dict")
+        items = d.items()
+        items.sort()
+        for key, value in items:
+            if not isinstance(key, (str, unicode)):
+                raise TypeError("keys must be strings")
+            self.simpleElement("key", key)
+            self.writeValue(value)
+        self.endElement("dict")
+
+    def writeArray(self, array):
+        self.beginElement("array")
+        for value in array:
+            self.writeValue(value)
+        self.endElement("array")
+
+
+class _InternalDict(dict):
+
+    # This class is needed while Dict is scheduled for deprecation:
+    # we only need to warn when a *user* instantiates Dict or when
+    # the "attribute notation for dict keys" is used.
+
+    def __getattr__(self, attr):
+        try:
+            value = self[attr]
+        except KeyError:
+            raise AttributeError, attr
+        from warnings import warn
+        warn("Attribute access from plist dicts is deprecated, use d[key] "
+             "notation instead", PendingDeprecationWarning)
+        return value
+
+    def __setattr__(self, attr, value):
+        from warnings import warn
+        warn("Attribute access from plist dicts is deprecated, use d[key] "
+             "notation instead", PendingDeprecationWarning)
+        self[attr] = value
+
+    def __delattr__(self, attr):
+        try:
+            del self[attr]
+        except KeyError:
+            raise AttributeError, attr
+        from warnings import warn
+        warn("Attribute access from plist dicts is deprecated, use d[key] "
+             "notation instead", PendingDeprecationWarning)
+
+class Dict(_InternalDict):
+
+    def __init__(self, **kwargs):
+        from warnings import warn
+        warn("The plistlib.Dict class is deprecated, use builtin dict instead",
+             PendingDeprecationWarning)
+        super(Dict, self).__init__(**kwargs)
+
+
+class Plist(_InternalDict):
+
+    """This class has been deprecated. Use readPlist() and writePlist()
+    functions instead, together with regular dict objects.
+    """
+
+    def __init__(self, **kwargs):
+        from warnings import warn
+        warn("The Plist class is deprecated, use the readPlist() and "
+             "writePlist() functions instead", PendingDeprecationWarning)
+        super(Plist, self).__init__(**kwargs)
+
+    def fromFile(cls, pathOrFile):
+        """Deprecated. Use the readPlist() function instead."""
+        rootObject = readPlist(pathOrFile)
+        plist = cls()
+        plist.update(rootObject)
+        return plist
+    fromFile = classmethod(fromFile)
+
+    def write(self, pathOrFile):
+        """Deprecated. Use the writePlist() function instead."""
+        writePlist(self, pathOrFile)
+
+
+def _encodeBase64(s, maxlinelength=76):
+    # copied from base64.encodestring(), with added maxlinelength argument
+    maxbinsize = (maxlinelength//4)*3
+    pieces = []
+    for i in range(0, len(s), maxbinsize):
+        chunk = s[i : i + maxbinsize]
+        pieces.append(binascii.b2a_base64(chunk))
+    return "".join(pieces)
+
+class Data:
+
+    """Wrapper for binary data."""
+
+    def __init__(self, data):
+        self.data = data
+
+    def fromBase64(cls, data):
+        # base64.decodestring just calls binascii.a2b_base64;
+        # it seems overkill to use both base64 and binascii.
+        return cls(binascii.a2b_base64(data))
+    fromBase64 = classmethod(fromBase64)
+
+    def asBase64(self, maxlinelength=76):
+        return _encodeBase64(self.data, maxlinelength)
+
+    def __cmp__(self, other):
+        if isinstance(other, self.__class__):
+            return cmp(self.data, other.data)
+        elif isinstance(other, str):
+            return cmp(self.data, other)
+        else:
+            return cmp(id(self), id(other))
+
+    def __repr__(self):
+        return "%s(%s)" % (self.__class__.__name__, repr(self.data))
+
+
+class PlistParser:
+
+    def __init__(self):
+        self.stack = []
+        self.currentKey = None
+        self.root = None
+
+    def parse(self, fileobj):
+        from xml.parsers.expat import ParserCreate
+        parser = ParserCreate()
+        parser.StartElementHandler = self.handleBeginElement
+        parser.EndElementHandler = self.handleEndElement
+        parser.CharacterDataHandler = self.handleData
+        parser.ParseFile(fileobj)
+        return self.root
+
+    def handleBeginElement(self, element, attrs):
+        self.data = []
+        handler = getattr(self, "begin_" + element, None)
+        if handler is not None:
+            handler(attrs)
+
+    def handleEndElement(self, element):
+        handler = getattr(self, "end_" + element, None)
+        if handler is not None:
+            handler()
+
+    def handleData(self, data):
+        self.data.append(data)
+
+    def addObject(self, value):
+        if self.currentKey is not None:
+            self.stack[-1][self.currentKey] = value
+            self.currentKey = None
+        elif not self.stack:
+            # this is the root object
+            self.root = value
+        else:
+            self.stack[-1].append(value)
+
+    def getData(self):
+        data = "".join(self.data)
+        try:
+            data = data.encode("ascii")
+        except UnicodeError:
+            pass
+        self.data = []
+        return data
+
+    # element handlers
+
+    def begin_dict(self, attrs):
+        d = _InternalDict()
+        self.addObject(d)
+        self.stack.append(d)
+    def end_dict(self):
+        self.stack.pop()
+
+    def end_key(self):
+        self.currentKey = self.getData()
+
+    def begin_array(self, attrs):
+        a = []
+        self.addObject(a)
+        self.stack.append(a)
+    def end_array(self):
+        self.stack.pop()
+
+    def end_true(self):
+        self.addObject(True)
+    def end_false(self):
+        self.addObject(False)
+    def end_integer(self):
+        self.addObject(int(self.getData()))
+    def end_real(self):
+        self.addObject(float(self.getData()))
+    def end_string(self):
+        self.addObject(self.getData())
+    def end_data(self):
+        self.addObject(Data.fromBase64(self.getData()))
+    def end_date(self):
+        self.addObject(_dateFromString(self.getData()))

Added: vendor/Python/current/Lib/plat-mac/terminalcommand.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/terminalcommand.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/terminalcommand.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,47 @@
+"""terminalcommand.py -- A minimal interface to Terminal.app.
+
+To run a shell command in a new Terminal.app window:
+
+    import terminalcommand
+    terminalcommand.run("ls -l")
+
+No result is returned; it is purely meant as a quick way to run a script
+with a decent input/output window.
+"""
+
+#
+# This module is a fairly straightforward translation of Jack Jansen's
+# Mac/OSX/PythonLauncher/doscript.m.
+#
+
+import time
+import os
+from Carbon import AE
+from Carbon.AppleEvents import *
+
+
+TERMINAL_SIG = "trmx"
+START_TERMINAL = "/usr/bin/open /Applications/Utilities/Terminal.app"
+SEND_MODE = kAENoReply  # kAEWaitReply hangs when run from Terminal.app itself
+
+
+def run(command):
+    """Run a shell command in a new Terminal.app window."""
+    termAddress = AE.AECreateDesc(typeApplSignature, TERMINAL_SIG)
+    theEvent = AE.AECreateAppleEvent(kAECoreSuite, kAEDoScript, termAddress,
+                                     kAutoGenerateReturnID, kAnyTransactionID)
+    commandDesc = AE.AECreateDesc(typeChar, command)
+    theEvent.AEPutParamDesc(kAECommandClass, commandDesc)
+
+    try:
+        theEvent.AESend(SEND_MODE, kAENormalPriority, kAEDefaultTimeout)
+    except AE.Error, why:
+        if why[0] != -600:  # Terminal.app not yet running
+            raise
+        os.system(START_TERMINAL)
+        time.sleep(1)
+        theEvent.AESend(SEND_MODE, kAENormalPriority, kAEDefaultTimeout)
+
+
+if __name__ == "__main__":
+    run("ls -l")

Added: vendor/Python/current/Lib/plat-mac/videoreader.py
===================================================================
--- vendor/Python/current/Lib/plat-mac/videoreader.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-mac/videoreader.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,291 @@
+# Video file reader, using QuickTime
+#
+# This module was quickly ripped out of another software package, so there is a good
+# chance that it does not work as-is and it needs some hacking.
+#
+# Jack Jansen, August 2000
+#
+import sys
+from Carbon import Qt
+from Carbon import QuickTime
+from Carbon import Qd
+from Carbon import Qdoffs
+from Carbon import QDOffscreen
+from Carbon import Res
+try:
+    import MediaDescr
+except ImportError:
+    def _audiodescr(data):
+        return None
+else:
+    def _audiodescr(data):
+        return MediaDescr.SoundDescription.decode(data)
+try:
+    from imgformat import macrgb
+except ImportError:
+    macrgb = "Macintosh RGB format"
+import os
+# import audio.format
+
+class VideoFormat:
+    def __init__(self, name, descr, width, height, format):
+        self.__name = name
+        self.__descr = descr
+        self.__width = width
+        self.__height = height
+        self.__format = format
+
+    def getname(self):
+        return self.__name
+
+    def getdescr(self):
+        return self.__descr
+
+    def getsize(self):
+        return self.__width, self.__height
+
+    def getformat(self):
+        return self.__format
+
+class _Reader:
+    def __init__(self, path):
+        fd = Qt.OpenMovieFile(path, 0)
+        self.movie, d1, d2 = Qt.NewMovieFromFile(fd, 0, 0)
+        self.movietimescale = self.movie.GetMovieTimeScale()
+        try:
+            self.audiotrack = self.movie.GetMovieIndTrackType(1,
+                QuickTime.AudioMediaCharacteristic, QuickTime.movieTrackCharacteristic)
+            self.audiomedia = self.audiotrack.GetTrackMedia()
+        except Qt.Error:
+            self.audiotrack = self.audiomedia = None
+            self.audiodescr = {}
+        else:
+            handle = Res.Handle('')
+            n = self.audiomedia.GetMediaSampleDescriptionCount()
+            self.audiomedia.GetMediaSampleDescription(1, handle)
+            self.audiodescr = _audiodescr(handle.data)
+            self.audiotimescale = self.audiomedia.GetMediaTimeScale()
+            del handle
+
+        try:
+            self.videotrack = self.movie.GetMovieIndTrackType(1,
+                QuickTime.VisualMediaCharacteristic, QuickTime.movieTrackCharacteristic)
+            self.videomedia = self.videotrack.GetTrackMedia()
+        except Qt.Error:
+            self.videotrack = self.videomedia = self.videotimescale = None
+        if self.videotrack:
+            self.videotimescale = self.videomedia.GetMediaTimeScale()
+            x0, y0, x1, y1 = self.movie.GetMovieBox()
+            self.videodescr = {'width':(x1-x0), 'height':(y1-y0)}
+            self._initgworld()
+        self.videocurtime = None
+        self.audiocurtime = None
+
+
+    def __del__(self):
+        self.audiomedia = None
+        self.audiotrack = None
+        self.videomedia = None
+        self.videotrack = None
+        self.movie = None
+
+    def _initgworld(self):
+        old_port, old_dev = Qdoffs.GetGWorld()
+        try:
+            movie_w = self.videodescr['width']
+            movie_h = self.videodescr['height']
+            movie_rect = (0, 0, movie_w, movie_h)
+            self.gworld = Qdoffs.NewGWorld(32,  movie_rect, None, None, QDOffscreen.keepLocal)
+            self.pixmap = self.gworld.GetGWorldPixMap()
+            Qdoffs.LockPixels(self.pixmap)
+            Qdoffs.SetGWorld(self.gworld.as_GrafPtr(), None)
+            Qd.EraseRect(movie_rect)
+            self.movie.SetMovieGWorld(self.gworld.as_GrafPtr(), None)
+            self.movie.SetMovieBox(movie_rect)
+            self.movie.SetMovieActive(1)
+            self.movie.MoviesTask(0)
+            self.movie.SetMoviePlayHints(QuickTime.hintsHighQuality, QuickTime.hintsHighQuality)
+            # XXXX framerate
+        finally:
+            Qdoffs.SetGWorld(old_port, old_dev)
+
+    def _gettrackduration_ms(self, track):
+        tracktime = track.GetTrackDuration()
+        return self._movietime_to_ms(tracktime)
+
+    def _movietime_to_ms(self, time):
+        value, d1, d2 = Qt.ConvertTimeScale((time, self.movietimescale, None), 1000)
+        return value
+
+    def _videotime_to_ms(self, time):
+        value, d1, d2 = Qt.ConvertTimeScale((time, self.videotimescale, None), 1000)
+        return value
+
+    def _audiotime_to_ms(self, time):
+        value, d1, d2 = Qt.ConvertTimeScale((time, self.audiotimescale, None), 1000)
+        return value
+
+    def _videotime_to_movietime(self, time):
+        value, d1, d2 = Qt.ConvertTimeScale((time, self.videotimescale, None),
+                self.movietimescale)
+        return value
+
+    def HasAudio(self):
+        return not self.audiotrack is None
+
+    def HasVideo(self):
+        return not self.videotrack is None
+
+    def GetAudioDuration(self):
+        if not self.audiotrack:
+            return 0
+        return self._gettrackduration_ms(self.audiotrack)
+
+    def GetVideoDuration(self):
+        if not self.videotrack:
+            return 0
+        return self._gettrackduration_ms(self.videotrack)
+
+    def GetAudioFormat(self):
+        if not self.audiodescr:
+            return None, None, None, None, None
+        bps = self.audiodescr['sampleSize']
+        nch = self.audiodescr['numChannels']
+        if nch == 1:
+            channels = ['mono']
+        elif nch == 2:
+            channels = ['left', 'right']
+        else:
+            channels = map(lambda x: str(x+1), range(nch))
+        if bps % 8:
+            # Funny bits-per sample. We pretend not to understand
+            blocksize = 0
+            fpb = 0
+        else:
+            # QuickTime is easy (for as far as we support it): samples are always a whole
+            # number of bytes, so frames are nchannels*samplesize, and there's one frame per block.
+            blocksize = (bps/8)*nch
+            fpb = 1
+        if self.audiodescr['dataFormat'] == 'raw ':
+            encoding = 'linear-excess'
+        elif self.audiodescr['dataFormat'] == 'twos':
+            encoding = 'linear-signed'
+        else:
+            encoding = 'quicktime-coding-%s'%self.audiodescr['dataFormat']
+##      return audio.format.AudioFormatLinear('quicktime_audio', 'QuickTime Audio Format',
+##          channels, encoding, blocksize=blocksize, fpb=fpb, bps=bps)
+        return channels, encoding, blocksize, fpb, bps
+
+    def GetAudioFrameRate(self):
+        if not self.audiodescr:
+            return None
+        return int(self.audiodescr['sampleRate'])
+
+    def GetVideoFormat(self):
+        width = self.videodescr['width']
+        height = self.videodescr['height']
+        return VideoFormat('dummy_format', 'Dummy Video Format', width, height, macrgb)
+
+    def GetVideoFrameRate(self):
+        tv = self.videocurtime
+        if tv == None:
+            tv = 0
+        flags = QuickTime.nextTimeStep|QuickTime.nextTimeEdgeOK
+        tv, dur = self.videomedia.GetMediaNextInterestingTime(flags, tv, 1.0)
+        dur = self._videotime_to_ms(dur)
+        return int((1000.0/dur)+0.5)
+
+    def ReadAudio(self, nframes, time=None):
+        if not time is None:
+            self.audiocurtime = time
+        flags = QuickTime.nextTimeStep|QuickTime.nextTimeEdgeOK
+        if self.audiocurtime == None:
+            self.audiocurtime = 0
+        tv = self.audiomedia.GetMediaNextInterestingTimeOnly(flags, self.audiocurtime, 1.0)
+        if tv < 0 or (self.audiocurtime and tv < self.audiocurtime):
+            return self._audiotime_to_ms(self.audiocurtime), None
+        h = Res.Handle('')
+        desc_h = Res.Handle('')
+        size, actualtime, sampleduration, desc_index, actualcount, flags = \
+            self.audiomedia.GetMediaSample(h, 0, tv, desc_h, nframes)
+        self.audiocurtime = actualtime + actualcount*sampleduration
+        return self._audiotime_to_ms(actualtime), h.data
+
+    def ReadVideo(self, time=None):
+        if not time is None:
+            self.videocurtime = time
+        flags = QuickTime.nextTimeStep
+        if self.videocurtime == None:
+            flags = flags | QuickTime.nextTimeEdgeOK
+            self.videocurtime = 0
+        tv = self.videomedia.GetMediaNextInterestingTimeOnly(flags, self.videocurtime, 1.0)
+        if tv < 0 or (self.videocurtime and tv <= self.videocurtime):
+            return self._videotime_to_ms(self.videocurtime), None
+        self.videocurtime = tv
+        moviecurtime = self._videotime_to_movietime(self.videocurtime)
+        self.movie.SetMovieTimeValue(moviecurtime)
+        self.movie.MoviesTask(0)
+        return self._videotime_to_ms(self.videocurtime), self._getpixmapcontent()
+
+    def _getpixmapcontent(self):
+        """Shuffle the offscreen PixMap data, because it may have funny stride values"""
+        rowbytes = Qdoffs.GetPixRowBytes(self.pixmap)
+        width = self.videodescr['width']
+        height = self.videodescr['height']
+        start = 0
+        rv = ''
+        for i in range(height):
+            nextline = Qdoffs.GetPixMapBytes(self.pixmap, start, width*4)
+            start = start + rowbytes
+            rv = rv + nextline
+        return rv
+
+def reader(url):
+    try:
+        rdr = _Reader(url)
+    except IOError:
+        return None
+    return rdr
+
+def _test():
+    import EasyDialogs
+    try:
+        import img
+    except ImportError:
+        img = None
+    import MacOS
+    Qt.EnterMovies()
+    path = EasyDialogs.AskFileForOpen(message='Video to convert')
+    if not path: sys.exit(0)
+    rdr = reader(path)
+    if not rdr:
+        sys.exit(1)
+    dstdir = EasyDialogs.AskFileForSave(message='Name for output folder')
+    if not dstdir: sys.exit(0)
+    num = 0
+    os.mkdir(dstdir)
+    videofmt = rdr.GetVideoFormat()
+    imgfmt = videofmt.getformat()
+    imgw, imgh = videofmt.getsize()
+    timestamp, data = rdr.ReadVideo()
+    while data:
+        fname = 'frame%04.4d.jpg'%num
+        num = num+1
+        pname = os.path.join(dstdir, fname)
+        if not img: print 'Not',
+        print 'Writing %s, size %dx%d, %d bytes'%(fname, imgw, imgh, len(data))
+        if img:
+            wrt = img.writer(imgfmt, pname)
+            wrt.width = imgw
+            wrt.height = imgh
+            wrt.write(data)
+            timestamp, data = rdr.ReadVideo()
+            MacOS.SetCreatorAndType(pname, 'ogle', 'JPEG')
+            if num > 20:
+                print 'stopping at 20 frames so your disk does not fill up:-)'
+                break
+    print 'Total frames:', num
+
+if __name__ == '__main__':
+    _test()
+    sys.exit(1)

Added: vendor/Python/current/Lib/plat-netbsd1/IN.py
===================================================================
--- vendor/Python/current/Lib/plat-netbsd1/IN.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-netbsd1/IN.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,56 @@
+# Generated by h2py from /usr/include/netinet/in.h
+IPPROTO_IP = 0
+IPPROTO_ICMP = 1
+IPPROTO_IGMP = 2
+IPPROTO_GGP = 3
+IPPROTO_IPIP = 4
+IPPROTO_TCP = 6
+IPPROTO_EGP = 8
+IPPROTO_PUP = 12
+IPPROTO_UDP = 17
+IPPROTO_IDP = 22
+IPPROTO_TP = 29
+IPPROTO_EON = 80
+IPPROTO_ENCAP = 98
+IPPROTO_RAW = 255
+IPPROTO_MAX = 256
+IPPORT_RESERVED = 1024
+IPPORT_USERRESERVED = 5000
+def __IPADDR(x): return ((u_int32_t)(x))
+
+IN_CLASSA_NSHIFT = 24
+IN_CLASSA_MAX = 128
+IN_CLASSB_NSHIFT = 16
+IN_CLASSB_MAX = 65536
+IN_CLASSC_NSHIFT = 8
+IN_CLASSD_NSHIFT = 28
+def IN_MULTICAST(i): return IN_CLASSD(i)
+
+IN_LOOPBACKNET = 127
+IP_OPTIONS = 1
+IP_HDRINCL = 2
+IP_TOS = 3
+IP_TTL = 4
+IP_RECVOPTS = 5
+IP_RECVRETOPTS = 6
+IP_RECVDSTADDR = 7
+IP_RETOPTS = 8
+IP_MULTICAST_IF = 9
+IP_MULTICAST_TTL = 10
+IP_MULTICAST_LOOP = 11
+IP_ADD_MEMBERSHIP = 12
+IP_DROP_MEMBERSHIP = 13
+IP_RECVIF = 20
+IP_DEFAULT_MULTICAST_TTL = 1
+IP_DEFAULT_MULTICAST_LOOP = 1
+IP_MAX_MEMBERSHIPS = 20
+IPPROTO_MAXID = (IPPROTO_IDP + 1)
+IPCTL_FORWARDING = 1
+IPCTL_SENDREDIRECTS = 2
+IPCTL_DEFTTL = 3
+IPCTL_DEFMTU = 4
+IPCTL_FORWSRCRT = 5
+IPCTL_DIRECTEDBCAST = 6
+IPCTL_ALLOWSRCRT = 7
+IPCTL_MAXID = 8
+def in_nullhost(x): return ((x).s_addr == INADDR_ANY)

Added: vendor/Python/current/Lib/plat-netbsd1/regen
===================================================================
--- vendor/Python/current/Lib/plat-netbsd1/regen	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-netbsd1/regen	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,3 @@
+#! /bin/sh
+set -v
+python ../../Tools/scripts/h2py.py -i '(u_long)' /usr/include/netinet/in.h


Property changes on: vendor/Python/current/Lib/plat-netbsd1/regen
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/plat-next3/regen
===================================================================
--- vendor/Python/current/Lib/plat-next3/regen	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-next3/regen	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,6 @@
+#! /bin/sh
+set -v
+INCLUDE="/NextDeveloper/Headers;/NextDeveloper/Headers/ansi;/NextDeveloper/Headers/bsd"
+export INCLUDE
+
+python ../../Tools/scripts/h2py.py -i '(u_long)' /usr/include/bsd/netinet/in.h


Property changes on: vendor/Python/current/Lib/plat-next3/regen
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/plat-os2emx/IN.py
===================================================================
--- vendor/Python/current/Lib/plat-os2emx/IN.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-os2emx/IN.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,82 @@
+# Generated by h2py from f:/emx/include/netinet/in.h
+
+# Included from sys/param.h
+PAGE_SIZE = 0x1000
+HZ = 100
+MAXNAMLEN = 260
+MAXPATHLEN = 260
+def htonl(X): return _swapl(X)
+
+def ntohl(X): return _swapl(X)
+
+def htons(X): return _swaps(X)
+
+def ntohs(X): return _swaps(X)
+
+IPPROTO_IP = 0
+IPPROTO_ICMP = 1
+IPPROTO_IGMP = 2
+IPPROTO_GGP = 3
+IPPROTO_TCP = 6
+IPPROTO_EGP = 8
+IPPROTO_PUP = 12
+IPPROTO_UDP = 17
+IPPROTO_IDP = 22
+IPPROTO_TP = 29
+IPPROTO_EON = 80
+IPPROTO_RAW = 255
+IPPROTO_MAX = 256
+IPPORT_RESERVED = 1024
+IPPORT_USERRESERVED = 5000
+def IN_CLASSA(i): return (((long)(i) & 0x80000000) == 0)
+
+IN_CLASSA_NET = 0xff000000
+IN_CLASSA_NSHIFT = 24
+IN_CLASSA_HOST = 0x00ffffff
+IN_CLASSA_MAX = 128
+def IN_CLASSB(i): return (((long)(i) & 0xc0000000) == 0x80000000)
+
+IN_CLASSB_NET = 0xffff0000
+IN_CLASSB_NSHIFT = 16
+IN_CLASSB_HOST = 0x0000ffff
+IN_CLASSB_MAX = 65536
+def IN_CLASSC(i): return (((long)(i) & 0xe0000000) == 0xc0000000)
+
+IN_CLASSC_NET = 0xffffff00
+IN_CLASSC_NSHIFT = 8
+IN_CLASSC_HOST = 0x000000ff
+def IN_CLASSD(i): return (((long)(i) & 0xf0000000) == 0xe0000000)
+
+IN_CLASSD_NET = 0xf0000000
+IN_CLASSD_NSHIFT = 28
+IN_CLASSD_HOST = 0x0fffffff
+def IN_MULTICAST(i): return IN_CLASSD(i)
+
+def IN_EXPERIMENTAL(i): return (((long)(i) & 0xe0000000) == 0xe0000000)
+
+def IN_BADCLASS(i): return (((long)(i) & 0xf0000000) == 0xf0000000)
+
+INADDR_ANY = 0x00000000
+INADDR_LOOPBACK = 0x7f000001
+INADDR_BROADCAST = 0xffffffff
+INADDR_NONE = 0xffffffff
+INADDR_UNSPEC_GROUP = 0xe0000000
+INADDR_ALLHOSTS_GROUP = 0xe0000001
+INADDR_MAX_LOCAL_GROUP = 0xe00000ff
+IN_LOOPBACKNET = 127
+IP_OPTIONS = 1
+IP_MULTICAST_IF = 2
+IP_MULTICAST_TTL = 3
+IP_MULTICAST_LOOP = 4
+IP_ADD_MEMBERSHIP = 5
+IP_DROP_MEMBERSHIP = 6
+IP_HDRINCL = 2
+IP_TOS = 3
+IP_TTL = 4
+IP_RECVOPTS = 5
+IP_RECVRETOPTS = 6
+IP_RECVDSTADDR = 7
+IP_RETOPTS = 8
+IP_DEFAULT_MULTICAST_TTL = 1
+IP_DEFAULT_MULTICAST_LOOP = 1
+IP_MAX_MEMBERSHIPS = 20

Added: vendor/Python/current/Lib/plat-os2emx/SOCKET.py
===================================================================
--- vendor/Python/current/Lib/plat-os2emx/SOCKET.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-os2emx/SOCKET.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,106 @@
+# Generated by h2py from f:/emx/include/sys/socket.h
+
+# Included from sys/types.h
+FD_SETSIZE = 256
+
+# Included from sys/uio.h
+FREAD = 1
+FWRITE = 2
+SOCK_STREAM = 1
+SOCK_DGRAM = 2
+SOCK_RAW = 3
+SOCK_RDM = 4
+SOCK_SEQPACKET = 5
+SO_DEBUG = 0x0001
+SO_ACCEPTCONN = 0x0002
+SO_REUSEADDR = 0x0004
+SO_KEEPALIVE = 0x0008
+SO_DONTROUTE = 0x0010
+SO_BROADCAST = 0x0020
+SO_USELOOPBACK = 0x0040
+SO_LINGER = 0x0080
+SO_OOBINLINE = 0x0100
+SO_L_BROADCAST = 0x0200
+SO_RCV_SHUTDOWN = 0x0400
+SO_SND_SHUTDOWN = 0x0800
+SO_SNDBUF = 0x1001
+SO_RCVBUF = 0x1002
+SO_SNDLOWAT = 0x1003
+SO_RCVLOWAT = 0x1004
+SO_SNDTIMEO = 0x1005
+SO_RCVTIMEO = 0x1006
+SO_ERROR = 0x1007
+SO_TYPE = 0x1008
+SO_OPTIONS = 0x1010
+SOL_SOCKET = 0xffff
+AF_UNSPEC = 0
+AF_UNIX = 1
+AF_INET = 2
+AF_IMPLINK = 3
+AF_PUP = 4
+AF_CHAOS = 5
+AF_NS = 6
+AF_NBS = 7
+AF_ISO = 7
+AF_OSI = AF_ISO
+AF_ECMA = 8
+AF_DATAKIT = 9
+AF_CCITT = 10
+AF_SNA = 11
+AF_DECnet = 12
+AF_DLI = 13
+AF_LAT = 14
+AF_HYLINK = 15
+AF_APPLETALK = 16
+AF_NB = 17
+AF_NETBIOS = AF_NB
+AF_OS2 = AF_UNIX
+AF_MAX = 18
+PF_UNSPEC = AF_UNSPEC
+PF_UNIX = AF_UNIX
+PF_INET = AF_INET
+PF_IMPLINK = AF_IMPLINK
+PF_PUP = AF_PUP
+PF_CHAOS = AF_CHAOS
+PF_NS = AF_NS
+PF_NBS = AF_NBS
+PF_ISO = AF_ISO
+PF_OSI = AF_ISO
+PF_ECMA = AF_ECMA
+PF_DATAKIT = AF_DATAKIT
+PF_CCITT = AF_CCITT
+PF_SNA = AF_SNA
+PF_DECnet = AF_DECnet
+PF_DLI = AF_DLI
+PF_LAT = AF_LAT
+PF_HYLINK = AF_HYLINK
+PF_APPLETALK = AF_APPLETALK
+PF_NB = AF_NB
+PF_NETBIOS = AF_NB
+PF_OS2 = AF_UNIX
+PF_MAX = AF_MAX
+SOMAXCONN = 5
+MSG_OOB = 0x1
+MSG_PEEK = 0x2
+MSG_DONTROUTE = 0x4
+MSG_EOR = 0x8
+MSG_TRUNC = 0x10
+MSG_CTRUNC = 0x20
+MSG_WAITALL = 0x40
+MSG_MAXIOVLEN = 16
+SCM_RIGHTS = 0x01
+MT_FREE = 0
+MT_DATA = 1
+MT_HEADER = 2
+MT_SOCKET = 3
+MT_PCB = 4
+MT_RTABLE = 5
+MT_HTABLE = 6
+MT_ATABLE = 7
+MT_SONAME = 8
+MT_ZOMBIE = 9
+MT_SOOPTS = 10
+MT_FTABLE = 11
+MT_RIGHTS = 12
+MT_IFADDR = 13
+MAXSOCKETS = 2048

Added: vendor/Python/current/Lib/plat-os2emx/_emx_link.py
===================================================================
--- vendor/Python/current/Lib/plat-os2emx/_emx_link.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-os2emx/_emx_link.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,79 @@
+# _emx_link.py
+
+# Written by Andrew I MacIntyre, December 2002.
+
+"""_emx_link.py is a simplistic emulation of the Unix link(2) library routine
+for creating so-called hard links.  It is intended to be imported into
+the os module in place of the unimplemented (on OS/2) Posix link()
+function (os.link()).
+
+We do this on OS/2 by implementing a file copy, with link(2) semantics:-
+  - the target cannot already exist;
+  - we hope that the actual file open (if successful) is actually
+    atomic...
+
+Limitations of this approach/implementation include:-
+  - no support for correct link counts (EMX stat(target).st_nlink
+    is always 1);
+  - thread safety undefined;
+  - default file permissions (r+w) used, can't be over-ridden;
+  - implemented in Python so comparatively slow, especially for large
+    source files;
+  - need sufficient free disk space to store the copy.
+
+Behaviour:-
+  - any exception should propagate to the caller;
+  - want target to be an exact copy of the source, so use binary mode;
+  - returns None, same as os.link() which is implemented in posixmodule.c;
+  - target removed in the event of a failure where possible;
+  - given the motivation to write this emulation came from trying to
+    support a Unix resource lock implementation, where minimal overhead
+    during creation of the target is desirable and the files are small,
+    we read a source block before attempting to create the target so that
+    we're ready to immediately write some data into it.
+"""
+
+import os
+import errno
+
+__all__ = ['link']
+
+def link(source, target):
+    """link(source, target) -> None
+
+    Attempt to hard link the source file to the target file name.
+    On OS/2, this creates a complete copy of the source file.
+    """
+
+    s = os.open(source, os.O_RDONLY | os.O_BINARY)
+    if os.isatty(s):
+        raise OSError, (errno.EXDEV, 'Cross-device link')
+    data = os.read(s, 1024)
+
+    try:
+        t = os.open(target, os.O_WRONLY | os.O_BINARY | os.O_CREAT | os.O_EXCL)
+    except OSError:
+        os.close(s)
+        raise
+
+    try:
+        while data:
+            os.write(t, data)
+            data = os.read(s, 1024)
+    except OSError:
+        os.close(s)
+        os.close(t)
+        os.unlink(target)
+        raise
+
+    os.close(s)
+    os.close(t)
+
+if __name__ == '__main__':
+    import sys
+    try:
+        link(sys.argv[1], sys.argv[2])
+    except IndexError:
+        print 'Usage: emx_link <source> <target>'
+    except OSError:
+        print 'emx_link: %s' % str(sys.exc_info()[1])

Added: vendor/Python/current/Lib/plat-os2emx/grp.py
===================================================================
--- vendor/Python/current/Lib/plat-os2emx/grp.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-os2emx/grp.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,182 @@
+# this module is an OS/2 oriented replacement for the grp standard
+# extension module.
+
+# written by Andrew MacIntyre, April 2001.
+# updated July 2003, adding field accessor support
+
+# note that this implementation checks whether ":" or ";" as used as
+# the field separator character.
+
+"""Replacement for grp standard extension module, intended for use on
+OS/2 and similar systems which don't normally have an /etc/group file.
+
+The standard Unix group database is an ASCII text file with 4 fields per
+record (line), separated by a colon:
+  - group name (string)
+  - group password (optional encrypted string)
+  - group id (integer)
+  - group members (comma delimited list of userids, with no spaces)
+
+Note that members are only included in the group file for groups that
+aren't their primary groups.
+(see the section 8.2 of the Python Library Reference)
+
+This implementation differs from the standard Unix implementation by
+allowing use of the platform's native path separator character - ';' on OS/2,
+DOS and MS-Windows - as the field separator in addition to the Unix
+standard ":".
+
+The module looks for the group database at the following locations
+(in order first to last):
+  - ${ETC_GROUP}              (or %ETC_GROUP%)
+  - ${ETC}/group              (or %ETC%/group)
+  - ${PYTHONHOME}/Etc/group   (or %PYTHONHOME%/Etc/group)
+
+Classes
+-------
+
+None
+
+Functions
+---------
+
+getgrgid(gid) -  return the record for group-id gid as a 4-tuple
+
+getgrnam(name) - return the record for group 'name' as a 4-tuple
+
+getgrall() -     return a list of 4-tuples, each tuple being one record
+                 (NOTE: the order is arbitrary)
+
+Attributes
+----------
+
+group_file -     the path of the group database file
+
+"""
+
+import os
+
+# try and find the group file
+__group_path = []
+if os.environ.has_key('ETC_GROUP'):
+    __group_path.append(os.environ['ETC_GROUP'])
+if os.environ.has_key('ETC'):
+    __group_path.append('%s/group' % os.environ['ETC'])
+if os.environ.has_key('PYTHONHOME'):
+    __group_path.append('%s/Etc/group' % os.environ['PYTHONHOME'])
+
+group_file = None
+for __i in __group_path:
+    try:
+        __f = open(__i, 'r')
+        __f.close()
+        group_file = __i
+        break
+    except:
+        pass
+
+# decide what field separator we can try to use - Unix standard, with
+# the platform's path separator as an option.  No special field conversion
+# handlers are required for the group file.
+__field_sep = [':']
+if os.pathsep:
+    if os.pathsep != ':':
+        __field_sep.append(os.pathsep)
+
+# helper routine to identify which separator character is in use
+def __get_field_sep(record):
+    fs = None
+    for c in __field_sep:
+        # there should be 3 delimiter characters (for 4 fields)
+        if record.count(c) == 3:
+            fs = c
+            break
+    if fs:
+        return fs
+    else:
+        raise KeyError, '>> group database fields not delimited <<'
+
+# class to match the new record field name accessors.
+# the resulting object is intended to behave like a read-only tuple,
+# with each member also accessible by a field name.
+class Group:
+    def __init__(self, name, passwd, gid, mem):
+        self.__dict__['gr_name'] = name
+        self.__dict__['gr_passwd'] = passwd
+        self.__dict__['gr_gid'] = gid
+        self.__dict__['gr_mem'] = mem
+        self.__dict__['_record'] = (self.gr_name, self.gr_passwd,
+                                    self.gr_gid, self.gr_mem)
+
+    def __len__(self):
+        return 4
+
+    def __getitem__(self, key):
+        return self._record[key]
+
+    def __setattr__(self, name, value):
+        raise AttributeError('attribute read-only: %s' % name)
+
+    def __repr__(self):
+        return str(self._record)
+
+    def __cmp__(self, other):
+        this = str(self._record)
+        if this == other:
+            return 0
+        elif this < other:
+            return -1
+        else:
+            return 1
+
+
+# read the whole file, parsing each entry into tuple form
+# with dictionaries to speed recall by GID or group name
+def __read_group_file():
+    if group_file:
+        group = open(group_file, 'r')
+    else:
+        raise KeyError, '>> no group database <<'
+    gidx = {}
+    namx = {}
+    sep = None
+    while 1:
+        entry = group.readline().strip()
+        if len(entry) > 3:
+            if sep == None:
+                sep = __get_field_sep(entry)
+            fields = entry.split(sep)
+            fields[2] = int(fields[2])
+            fields[3] = [f.strip() for f in fields[3].split(',')]
+            record = Group(*fields)
+            if not gidx.has_key(fields[2]):
+                gidx[fields[2]] = record
+            if not namx.has_key(fields[0]):
+                namx[fields[0]] = record
+        elif len(entry) > 0:
+            pass                         # skip empty or malformed records
+        else:
+            break
+    group.close()
+    if len(gidx) == 0:
+        raise KeyError
+    return (gidx, namx)
+
+# return the group database entry by GID
+def getgrgid(gid):
+    g, n = __read_group_file()
+    return g[gid]
+
+# return the group database entry by group name
+def getgrnam(name):
+    g, n = __read_group_file()
+    return n[name]
+
+# return all the group database entries
+def getgrall():
+    g, n = __read_group_file()
+    return g.values()
+
+# test harness
+if __name__ == '__main__':
+    getgrall()

Added: vendor/Python/current/Lib/plat-os2emx/pwd.py
===================================================================
--- vendor/Python/current/Lib/plat-os2emx/pwd.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-os2emx/pwd.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,208 @@
+# this module is an OS/2 oriented replacement for the pwd standard
+# extension module.
+
+# written by Andrew MacIntyre, April 2001.
+# updated July 2003, adding field accessor support
+
+# note that this implementation checks whether ":" or ";" as used as
+# the field separator character.  Path conversions are are applied when
+# the database uses ":" as the field separator character.
+
+"""Replacement for pwd standard extension module, intended for use on
+OS/2 and similar systems which don't normally have an /etc/passwd file.
+
+The standard Unix password database is an ASCII text file with 7 fields
+per record (line), separated by a colon:
+  - user name (string)
+  - password (encrypted string, or "*" or "")
+  - user id (integer)
+  - group id (integer)
+  - description (usually user's name)
+  - home directory (path to user's home directory)
+  - shell (path to the user's login shell)
+
+(see the section 8.1 of the Python Library Reference)
+
+This implementation differs from the standard Unix implementation by
+allowing use of the platform's native path separator character - ';' on OS/2,
+DOS and MS-Windows - as the field separator in addition to the Unix
+standard ":".  Additionally, when ":" is the separator path conversions
+are applied to deal with any munging of the drive letter reference.
+
+The module looks for the password database at the following locations
+(in order first to last):
+  - ${ETC_PASSWD}             (or %ETC_PASSWD%)
+  - ${ETC}/passwd             (or %ETC%/passwd)
+  - ${PYTHONHOME}/Etc/passwd  (or %PYTHONHOME%/Etc/passwd)
+
+Classes
+-------
+
+None
+
+Functions
+---------
+
+getpwuid(uid) -  return the record for user-id uid as a 7-tuple
+
+getpwnam(name) - return the record for user 'name' as a 7-tuple
+
+getpwall() -     return a list of 7-tuples, each tuple being one record
+                 (NOTE: the order is arbitrary)
+
+Attributes
+----------
+
+passwd_file -    the path of the password database file
+
+"""
+
+import os
+
+# try and find the passwd file
+__passwd_path = []
+if os.environ.has_key('ETC_PASSWD'):
+    __passwd_path.append(os.environ['ETC_PASSWD'])
+if os.environ.has_key('ETC'):
+    __passwd_path.append('%s/passwd' % os.environ['ETC'])
+if os.environ.has_key('PYTHONHOME'):
+    __passwd_path.append('%s/Etc/passwd' % os.environ['PYTHONHOME'])
+
+passwd_file = None
+for __i in __passwd_path:
+    try:
+        __f = open(__i, 'r')
+        __f.close()
+        passwd_file = __i
+        break
+    except:
+        pass
+
+# path conversion handlers
+def __nullpathconv(path):
+    return path.replace(os.altsep, os.sep)
+
+def __unixpathconv(path):
+    # two known drive letter variations: "x;" and "$x"
+    if path[0] == '$':
+        conv = path[1] + ':' + path[2:]
+    elif path[1] == ';':
+        conv = path[0] + ':' + path[2:]
+    else:
+        conv = path
+    return conv.replace(os.altsep, os.sep)
+
+# decide what field separator we can try to use - Unix standard, with
+# the platform's path separator as an option.  No special field conversion
+# handler is required when using the platform's path separator as field
+# separator, but are required for the home directory and shell fields when
+# using the standard Unix (":") field separator.
+__field_sep = {':': __unixpathconv}
+if os.pathsep:
+    if os.pathsep != ':':
+        __field_sep[os.pathsep] = __nullpathconv
+
+# helper routine to identify which separator character is in use
+def __get_field_sep(record):
+    fs = None
+    for c in __field_sep.keys():
+        # there should be 6 delimiter characters (for 7 fields)
+        if record.count(c) == 6:
+            fs = c
+            break
+    if fs:
+        return fs
+    else:
+        raise KeyError, '>> passwd database fields not delimited <<'
+
+# class to match the new record field name accessors.
+# the resulting object is intended to behave like a read-only tuple,
+# with each member also accessible by a field name.
+class Passwd:
+    def __init__(self, name, passwd, uid, gid, gecos, dir, shell):
+        self.__dict__['pw_name'] = name
+        self.__dict__['pw_passwd'] = passwd
+        self.__dict__['pw_uid'] = uid
+        self.__dict__['pw_gid'] = gid
+        self.__dict__['pw_gecos'] = gecos
+        self.__dict__['pw_dir'] = dir
+        self.__dict__['pw_shell'] = shell
+        self.__dict__['_record'] = (self.pw_name, self.pw_passwd,
+                                    self.pw_uid, self.pw_gid,
+                                    self.pw_gecos, self.pw_dir,
+                                    self.pw_shell)
+
+    def __len__(self):
+        return 7
+
+    def __getitem__(self, key):
+        return self._record[key]
+
+    def __setattr__(self, name, value):
+        raise AttributeError('attribute read-only: %s' % name)
+
+    def __repr__(self):
+        return str(self._record)
+
+    def __cmp__(self, other):
+        this = str(self._record)
+        if this == other:
+            return 0
+        elif this < other:
+            return -1
+        else:
+            return 1
+
+
+# read the whole file, parsing each entry into tuple form
+# with dictionaries to speed recall by UID or passwd name
+def __read_passwd_file():
+    if passwd_file:
+        passwd = open(passwd_file, 'r')
+    else:
+        raise KeyError, '>> no password database <<'
+    uidx = {}
+    namx = {}
+    sep = None
+    while 1:
+        entry = passwd.readline().strip()
+        if len(entry) > 6:
+            if sep == None:
+                sep = __get_field_sep(entry)
+            fields = entry.split(sep)
+            for i in (2, 3):
+                fields[i] = int(fields[i])
+            for i in (5, 6):
+                fields[i] = __field_sep[sep](fields[i])
+            record = Passwd(*fields)
+            if not uidx.has_key(fields[2]):
+                uidx[fields[2]] = record
+            if not namx.has_key(fields[0]):
+                namx[fields[0]] = record
+        elif len(entry) > 0:
+            pass                         # skip empty or malformed records
+        else:
+            break
+    passwd.close()
+    if len(uidx) == 0:
+        raise KeyError
+    return (uidx, namx)
+
+# return the passwd database entry by UID
+def getpwuid(uid):
+    u, n = __read_passwd_file()
+    return u[uid]
+
+# return the passwd database entry by passwd name
+def getpwnam(name):
+    u, n = __read_passwd_file()
+    return n[name]
+
+# return all the passwd database entries
+def getpwall():
+    u, n = __read_passwd_file()
+    return n.values()
+
+# test harness
+if __name__ == '__main__':
+    getpwall()

Added: vendor/Python/current/Lib/plat-os2emx/regen
===================================================================
--- vendor/Python/current/Lib/plat-os2emx/regen	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-os2emx/regen	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,7 @@
+#! /bin/sh
+export INCLUDE=$C_INCLUDE_PATH
+set -v
+python.exe ../../Tools/scripts/h2py.py $C_INCLUDE_PATH/fcntl.h
+python.exe ../../Tools/scripts/h2py.py $C_INCLUDE_PATH/sys/socket.h
+python.exe ../../Tools/scripts/h2py.py -i '(u_long)' $C_INCLUDE_PATH/netinet/in.h
+#python.exe ../../Tools/scripts/h2py.py $C_INCLUDE_PATH/termios.h

Added: vendor/Python/current/Lib/plat-riscos/riscosenviron.py
===================================================================
--- vendor/Python/current/Lib/plat-riscos/riscosenviron.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-riscos/riscosenviron.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,45 @@
+"""A more or less complete dictionary like interface for the RISC OS environment."""
+
+import riscos
+
+class _Environ:
+    def __init__(self, initial = None):
+        pass
+    def __repr__(self):
+        return repr(riscos.getenvdict())
+    def __cmp__(self, dict):
+        return cmp(riscos.getenvdict(), dict)
+    def __len__(self):
+        return len(riscos.getenvdict())
+    def __getitem__(self, key):
+        ret = riscos.getenv(key)
+        if ret<>None:
+            return ret
+        else:
+            raise KeyError
+    def __setitem__(self, key, item):
+        riscos.putenv(key, item)
+    def __delitem__(self, key):
+        riscos.delenv(key)
+    def clear(self):
+        # too dangerous on RISC OS
+        pass
+    def copy(self):
+        return riscos.getenvdict()
+    def keys(self): return riscos.getenvdict().keys()
+    def items(self): return riscos.getenvdict().items()
+    def values(self): return riscos.getenvdict().values()
+    def has_key(self, key):
+        value = riscos.getenv(key)
+        return value<>None
+    def __contains__(self, key):
+        return riscos.getenv(key) is not None
+    def update(self, dict):
+        for k, v in dict.items():
+            riscos.putenv(k, v)
+    def get(self, key, failobj=None):
+        value = riscos.getenv(key)
+        if value<>None:
+            return value
+        else:
+            return failobj

Added: vendor/Python/current/Lib/plat-riscos/riscospath.py
===================================================================
--- vendor/Python/current/Lib/plat-riscos/riscospath.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-riscos/riscospath.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,378 @@
+# Module 'riscospath' -- common operations on RISC OS pathnames.
+
+# contributed by Andrew Clover  ( andrew at oaktree.co.uk )
+
+# The "os.path" name is an alias for this module on RISC OS systems;
+# on other systems (e.g. Mac, Windows), os.path provides the same
+# operations in a manner specific to that platform, and is an alias
+# to another module (e.g. macpath, ntpath).
+
+"""
+Instead of importing this module directly, import os and refer to this module
+as os.path.
+"""
+
+# strings representing various path-related bits and pieces
+curdir = '@'
+pardir = '^'
+extsep = '/'
+sep = '.'
+pathsep = ','
+defpath = '<Run$Dir>'
+altsep = None
+
+# Imports - make an error-generating swi object if the swi module is not
+# available (ie. we are not running on RISC OS Python)
+
+import os, stat, string
+
+try:
+    import swi
+except ImportError:
+    class _swi:
+        def swi(*a):
+            raise AttributeError, 'This function only available under RISC OS'
+        block= swi
+    swi= _swi()
+
+[_false, _true]= range(2)
+
+_roots= ['$', '&', '%', '@', '\\']
+
+
+# _allowMOSFSNames
+# After importing riscospath, set _allowMOSFSNames true if you want the module
+# to understand the "-SomeFS-" notation left over from the old BBC Master MOS,
+# as well as the standard "SomeFS:" notation. Set this to be fully backwards
+# compatible but remember that "-SomeFS-" can also be a perfectly valid file
+# name so care must be taken when splitting and joining paths.
+
+_allowMOSFSNames= _false
+
+
+## Path manipulation, RISC OS stylee.
+
+def _split(p):
+    """
+  split filing system name (including special field) and drive specifier from rest
+  of path. This is needed by many riscospath functions.
+  """
+    dash= _allowMOSFSNames and p[:1]=='-'
+    if dash:
+        q= string.find(p, '-', 1)+1
+    else:
+        if p[:1]==':':
+            q= 0
+        else:
+            q= string.find(p, ':')+1 # q= index of start of non-FS portion of path
+    s= string.find(p, '#')
+    if s==-1 or s>q:
+        s= q # find end of main FS name, not including special field
+    else:
+        for c in p[dash:s]:
+            if c not in string.ascii_letters:
+                q= 0
+                break # disallow invalid non-special-field characters in FS name
+    r= q
+    if p[q:q+1]==':':
+        r= string.find(p, '.', q+1)+1
+        if r==0:
+            r= len(p) # find end of drive name (if any) following FS name (if any)
+    return (p[:q], p[q:r], p[r:])
+
+
+def normcase(p):
+    """
+  Normalize the case of a pathname. This converts to lowercase as the native RISC
+  OS filesystems are case-insensitive. However, not all filesystems have to be,
+  and there's no simple way to find out what type an FS is argh.
+  """
+    return string.lower(p)
+
+
+def isabs(p):
+    """
+  Return whether a path is absolute. Under RISC OS, a file system specifier does
+  not make a path absolute, but a drive name or number does, and so does using the
+  symbol for root, URD, library, CSD or PSD. This means it is perfectly possible
+  to have an "absolute" URL dependent on the current working directory, and
+  equally you can have a "relative" URL that's on a completely different device to
+  the current one argh.
+  """
+    (fs, drive, path)= _split(p)
+    return drive!='' or path[:1] in _roots
+
+
+def join(a, *p):
+    """
+  Join path elements with the directory separator, replacing the entire path when
+  an absolute or FS-changing path part is found.
+  """
+    j= a
+    for b in p:
+        (fs, drive, path)= _split(b)
+        if j=='' or fs!='' or drive!='' or path[:1] in _roots:
+            j= b
+        elif j[-1]==':':
+            j= j+b
+        else:
+            j= j+'.'+b
+    return j
+
+
+def split(p):
+    """
+  Split a path in head (everything up to the last '.') and tail (the rest). FS
+  name must still be dealt with separately since special field may contain '.'.
+  """
+    (fs, drive, path)= _split(p)
+    q= string.rfind(path, '.')
+    if q!=-1:
+        return (fs+drive+path[:q], path[q+1:])
+    return ('', p)
+
+
+def splitext(p):
+    """
+  Split a path in root and extension. This assumes the 'using slash for dot and
+  dot for slash with foreign files' convention common in RISC OS is in force.
+  """
+    (tail, head)= split(p)
+    if '/' in head:
+        q= len(head)-string.rfind(head, '/')
+        return (p[:-q], p[-q:])
+    return (p, '')
+
+
+def splitdrive(p):
+    """
+  Split a pathname into a drive specification (including FS name) and the rest of
+  the path. The terminating dot of the drive name is included in the drive
+  specification.
+  """
+    (fs, drive, path)= _split(p)
+    return (fs+drive, p)
+
+
+def basename(p):
+    """
+  Return the tail (basename) part of a path.
+  """
+    return split(p)[1]
+
+
+def dirname(p):
+    """
+  Return the head (dirname) part of a path.
+  """
+    return split(p)[0]
+
+
+def commonprefix(m):
+    "Given a list of pathnames, returns the longest common leading component"
+    if not m: return ''
+    s1 = min(m)
+    s2 = max(m)
+    n = min(len(s1), len(s2))
+    for i in xrange(n):
+        if s1[i] != s2[i]:
+            return s1[:i]
+    return s1[:n]
+
+
+## File access functions. Why are we in os.path?
+
+def getsize(p):
+    """
+  Return the size of a file, reported by os.stat().
+  """
+    st= os.stat(p)
+    return st[stat.ST_SIZE]
+
+
+def getmtime(p):
+    """
+  Return the last modification time of a file, reported by os.stat().
+  """
+    st = os.stat(p)
+    return st[stat.ST_MTIME]
+
+getatime= getmtime
+
+
+# RISC OS-specific file access functions
+
+def exists(p):
+    """
+  Test whether a path exists.
+  """
+    try:
+        return swi.swi('OS_File', '5s;i', p)!=0
+    except swi.error:
+        return 0
+
+lexists = exists
+
+
+def isdir(p):
+    """
+  Is a path a directory? Includes image files.
+  """
+    try:
+        return swi.swi('OS_File', '5s;i', p) in [2, 3]
+    except swi.error:
+        return 0
+
+
+def isfile(p):
+    """
+  Test whether a path is a file, including image files.
+  """
+    try:
+        return swi.swi('OS_File', '5s;i', p) in [1, 3]
+    except swi.error:
+        return 0
+
+
+def islink(p):
+    """
+  RISC OS has no links or mounts.
+  """
+    return _false
+
+ismount= islink
+
+
+# Same-file testing.
+
+# samefile works on filename comparison since there is no ST_DEV and ST_INO is
+# not reliably unique (esp. directories). First it has to normalise the
+# pathnames, which it can do 'properly' using OS_FSControl since samefile can
+# assume it's running on RISC OS (unlike normpath).
+
+def samefile(fa, fb):
+    """
+  Test whether two pathnames reference the same actual file.
+  """
+    l= 512
+    b= swi.block(l)
+    swi.swi('OS_FSControl', 'isb..i', 37, fa, b, l)
+    fa= b.ctrlstring()
+    swi.swi('OS_FSControl', 'isb..i', 37, fb, b, l)
+    fb= b.ctrlstring()
+    return fa==fb
+
+
+def sameopenfile(a, b):
+    """
+  Test whether two open file objects reference the same file.
+  """
+    return os.fstat(a)[stat.ST_INO]==os.fstat(b)[stat.ST_INO]
+
+
+## Path canonicalisation
+
+# 'user directory' is taken as meaning the User Root Directory, which is in
+# practice never used, for anything.
+
+def expanduser(p):
+    (fs, drive, path)= _split(p)
+    l= 512
+    b= swi.block(l)
+
+    if path[:1]!='@':
+        return p
+    if fs=='':
+        fsno= swi.swi('OS_Args', '00;i')
+        swi.swi('OS_FSControl', 'iibi', 33, fsno, b, l)
+        fsname= b.ctrlstring()
+    else:
+        if fs[:1]=='-':
+            fsname= fs[1:-1]
+        else:
+            fsname= fs[:-1]
+        fsname= string.split(fsname, '#', 1)[0] # remove special field from fs
+    x= swi.swi('OS_FSControl', 'ib2s.i;.....i', 54, b, fsname, l)
+    if x<l:
+        urd= b.tostring(0, l-x-1)
+    else: # no URD! try CSD
+        x= swi.swi('OS_FSControl', 'ib0s.i;.....i', 54, b, fsname, l)
+        if x<l:
+            urd= b.tostring(0, l-x-1)
+        else: # no CSD! use root
+            urd= '$'
+    return fsname+':'+urd+path[1:]
+
+# Environment variables are in angle brackets.
+
+def expandvars(p):
+    """
+  Expand environment variables using OS_GSTrans.
+  """
+    l= 512
+    b= swi.block(l)
+    return b.tostring(0, swi.swi('OS_GSTrans', 'sbi;..i', p, b, l))
+
+
+# Return an absolute path. RISC OS' osfscontrol_canonicalise_path does this among others
+abspath = os.expand
+
+
+# realpath is a no-op on systems without islink support
+realpath = abspath
+
+
+# Normalize a path. Only special path element under RISC OS is "^" for "..".
+
+def normpath(p):
+    """
+  Normalize path, eliminating up-directory ^s.
+  """
+    (fs, drive, path)= _split(p)
+    rhs= ''
+    ups= 0
+    while path!='':
+        (path, el)= split(path)
+        if el=='^':
+            ups= ups+1
+        else:
+            if ups>0:
+                ups= ups-1
+            else:
+                if rhs=='':
+                    rhs= el
+                else:
+                    rhs= el+'.'+rhs
+    while ups>0:
+        ups= ups-1
+        rhs= '^.'+rhs
+    return fs+drive+rhs
+
+
+# Directory tree walk.
+# Independent of host system. Why am I in os.path?
+
+def walk(top, func, arg):
+    """Directory tree walk with callback function.
+
+    For each directory in the directory tree rooted at top (including top
+    itself, but excluding '.' and '..'), call func(arg, dirname, fnames).
+    dirname is the name of the directory, and fnames a list of the names of
+    the files and subdirectories in dirname (excluding '.' and '..').  func
+    may modify the fnames list in-place (e.g. via del or slice assignment),
+    and walk will only recurse into the subdirectories whose names remain in
+    fnames; this can be used to implement a filter, or to impose a specific
+    order of visiting.  No semantics are defined for, or required of, arg,
+    beyond that arg is always passed to func.  It can be used, e.g., to pass
+    a filename pattern, or a mutable object designed to accumulate
+    statistics.  Passing None for arg is common."""
+
+    try:
+        names= os.listdir(top)
+    except os.error:
+        return
+    func(arg, top, names)
+    for name in names:
+        name= join(top, name)
+        if isdir(name) and not islink(name):
+            walk(name, func, arg)

Added: vendor/Python/current/Lib/plat-riscos/rourl2path.py
===================================================================
--- vendor/Python/current/Lib/plat-riscos/rourl2path.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-riscos/rourl2path.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,71 @@
+"""riscos specific module for conversion between pathnames and URLs.
+Based on macurl2path.
+Do not import directly, use urllib instead."""
+
+import string
+import urllib
+import os
+
+__all__ = ["url2pathname","pathname2url"]
+
+__slash_dot = string.maketrans("/.", "./")
+
+def url2pathname(url):
+    """OS-specific conversion from a relative URL of the 'file' scheme
+    to a file system path; not recommended for general use."""
+    tp = urllib.splittype(url)[0]
+    if tp and tp <> 'file':
+        raise RuntimeError, 'Cannot convert non-local URL to pathname'
+    # Turn starting /// into /, an empty hostname means current host
+    if url[:3] == '///':
+        url = url[2:]
+    elif url[:2] == '//':
+        raise RuntimeError, 'Cannot convert non-local URL to pathname'
+    components = string.split(url, '/')
+    if not components[0]:
+        if '$' in components:
+            del components[0]
+        else:
+            components[0] = '$'
+    # Remove . and embedded ..
+    i = 0
+    while i < len(components):
+        if components[i] == '.':
+            del components[i]
+        elif components[i] == '..' and i > 0 and \
+                                  components[i-1] not in ('', '..'):
+            del components[i-1:i+1]
+            i -= 1
+        elif components[i] == '..':
+            components[i] = '^'
+            i += 1
+        elif components[i] == '' and i > 0 and components[i-1] <> '':
+            del components[i]
+        else:
+            i += 1
+    components = map(lambda x: urllib.unquote(x).translate(__slash_dot), components)
+    return '.'.join(components)
+
+def pathname2url(pathname):
+    """OS-specific conversion from a file system path to a relative URL
+    of the 'file' scheme; not recommended for general use."""
+    return urllib.quote('///' + pathname.translate(__slash_dot), "/$:")
+
+def test():
+    for url in ["index.html",
+                "/SCSI::SCSI4/$/Anwendung/Comm/Apps/!Fresco/Welcome",
+                "/SCSI::SCSI4/$/Anwendung/Comm/Apps/../!Fresco/Welcome",
+                "../index.html",
+                "bar/index.html",
+                "/foo/bar/index.html",
+                "/foo/bar/",
+                "/"]:
+        print '%r -> %r' % (url, url2pathname(url))
+    print "*******************************************************"
+    for path in ["SCSI::SCSI4.$.Anwendung",
+                 "PythonApp:Lib",
+                 "PythonApp:Lib.rourl2path/py"]:
+        print '%r -> %r' % (path, pathname2url(path))
+
+if __name__ == '__main__':
+    test()

Added: vendor/Python/current/Lib/plat-sunos5/CDIO.py
===================================================================
--- vendor/Python/current/Lib/plat-sunos5/CDIO.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-sunos5/CDIO.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,73 @@
+# Generated by h2py from /usr/include/sys/cdio.h
+CDROM_LBA = 0x01
+CDROM_MSF = 0x02
+CDROM_DATA_TRACK = 0x04
+CDROM_LEADOUT = 0xAA
+CDROM_AUDIO_INVALID = 0x00
+CDROM_AUDIO_PLAY = 0x11
+CDROM_AUDIO_PAUSED = 0x12
+CDROM_AUDIO_COMPLETED = 0x13
+CDROM_AUDIO_ERROR = 0x14
+CDROM_AUDIO_NO_STATUS = 0x15
+CDROM_DA_NO_SUBCODE = 0x00
+CDROM_DA_SUBQ = 0x01
+CDROM_DA_ALL_SUBCODE = 0x02
+CDROM_DA_SUBCODE_ONLY = 0x03
+CDROM_XA_DATA = 0x00
+CDROM_XA_SECTOR_DATA = 0x01
+CDROM_XA_DATA_W_ERROR = 0x02
+CDROM_BLK_512 = 512
+CDROM_BLK_1024 = 1024
+CDROM_BLK_2048 = 2048
+CDROM_BLK_2056 = 2056
+CDROM_BLK_2336 = 2336
+CDROM_BLK_2340 = 2340
+CDROM_BLK_2352 = 2352
+CDROM_BLK_2368 = 2368
+CDROM_BLK_2448 = 2448
+CDROM_BLK_2646 = 2646
+CDROM_BLK_2647 = 2647
+CDROM_BLK_SUBCODE = 96
+CDROM_NORMAL_SPEED = 0x00
+CDROM_DOUBLE_SPEED = 0x01
+CDROM_QUAD_SPEED = 0x03
+CDROM_TWELVE_SPEED = 0x0C
+CDROM_MAXIMUM_SPEED = 0xff
+CDIOC = (0x04 << 8)
+CDROMPAUSE = (CDIOC|151)
+CDROMRESUME = (CDIOC|152)
+CDROMPLAYMSF = (CDIOC|153)
+CDROMPLAYTRKIND = (CDIOC|154)
+CDROMREADTOCHDR = (CDIOC|155)
+CDROMREADTOCENTRY = (CDIOC|156)
+CDROMSTOP = (CDIOC|157)
+CDROMSTART = (CDIOC|158)
+CDROMEJECT = (CDIOC|159)
+CDROMVOLCTRL = (CDIOC|160)
+CDROMSUBCHNL = (CDIOC|161)
+CDROMREADMODE2 = (CDIOC|162)
+CDROMREADMODE1 = (CDIOC|163)
+CDROMREADOFFSET = (CDIOC|164)
+CDROMGBLKMODE = (CDIOC|165)
+CDROMSBLKMODE = (CDIOC|166)
+CDROMCDDA = (CDIOC|167)
+CDROMCDXA = (CDIOC|168)
+CDROMSUBCODE = (CDIOC|169)
+CDROMGDRVSPEED = (CDIOC|170)
+CDROMSDRVSPEED = (CDIOC|171)
+SCMD_READ_TOC = 0x43
+SCMD_PLAYAUDIO_MSF = 0x47
+SCMD_PLAYAUDIO_TI = 0x48
+SCMD_PAUSE_RESUME = 0x4B
+SCMD_READ_SUBCHANNEL = 0x42
+SCMD_PLAYAUDIO10 = 0x45
+SCMD_PLAYTRACK_REL10 = 0x49
+SCMD_READ_HEADER = 0x44
+SCMD_PLAYAUDIO12 = 0xA5
+SCMD_PLAYTRACK_REL12 = 0xA9
+SCMD_CD_PLAYBACK_CONTROL = 0xC9
+SCMD_CD_PLAYBACK_STATUS = 0xC4
+SCMD_READ_CDDA = 0xD8
+SCMD_READ_CDXA = 0xDB
+SCMD_READ_ALL_SUBCODES = 0xDF
+CDROM_MODE2_SIZE = 2336

Added: vendor/Python/current/Lib/plat-sunos5/DLFCN.py
===================================================================
--- vendor/Python/current/Lib/plat-sunos5/DLFCN.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-sunos5/DLFCN.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,27 @@
+# Generated by h2py from /usr/include/dlfcn.h
+from TYPES import *
+RTLD_LAZY = 0x00001
+RTLD_NOW = 0x00002
+RTLD_NOLOAD = 0x00004
+RTLD_GLOBAL = 0x00100
+RTLD_LOCAL = 0x00000
+RTLD_PARENT = 0x00200
+RTLD_GROUP = 0x00400
+RTLD_WORLD = 0x00800
+RTLD_NODELETE = 0x01000
+RTLD_CONFGEN = 0x10000
+RTLD_REL_RELATIVE = 0x00001
+RTLD_REL_EXEC = 0x00002
+RTLD_REL_DEPENDS = 0x00004
+RTLD_REL_PRELOAD = 0x00008
+RTLD_REL_SELF = 0x00010
+RTLD_REL_WEAK = 0x00020
+RTLD_REL_ALL = 0x00fff
+RTLD_MEMORY = 0x01000
+RTLD_STRIP = 0x02000
+RTLD_NOHEAP = 0x04000
+RTLD_CONFSET = 0x10000
+RTLD_DI_LMID = 1
+RTLD_DI_LINKMAP = 2
+RTLD_DI_CONFIGADDR = 3
+RTLD_DI_MAX = 3

Added: vendor/Python/current/Lib/plat-sunos5/IN.py
===================================================================
--- vendor/Python/current/Lib/plat-sunos5/IN.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-sunos5/IN.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1421 @@
+# Generated by h2py from /usr/include/netinet/in.h
+
+# Included from sys/feature_tests.h
+
+# Included from sys/isa_defs.h
+_CHAR_ALIGNMENT = 1
+_SHORT_ALIGNMENT = 2
+_INT_ALIGNMENT = 4
+_LONG_ALIGNMENT = 8
+_LONG_LONG_ALIGNMENT = 8
+_DOUBLE_ALIGNMENT = 8
+_LONG_DOUBLE_ALIGNMENT = 16
+_POINTER_ALIGNMENT = 8
+_MAX_ALIGNMENT = 16
+_ALIGNMENT_REQUIRED = 1
+_CHAR_ALIGNMENT = 1
+_SHORT_ALIGNMENT = 2
+_INT_ALIGNMENT = 4
+_LONG_ALIGNMENT = 4
+_LONG_LONG_ALIGNMENT = 4
+_DOUBLE_ALIGNMENT = 4
+_LONG_DOUBLE_ALIGNMENT = 4
+_POINTER_ALIGNMENT = 4
+_MAX_ALIGNMENT = 4
+_ALIGNMENT_REQUIRED = 0
+_CHAR_ALIGNMENT = 1
+_SHORT_ALIGNMENT = 2
+_INT_ALIGNMENT = 4
+_LONG_LONG_ALIGNMENT = 8
+_DOUBLE_ALIGNMENT = 8
+_ALIGNMENT_REQUIRED = 1
+_LONG_ALIGNMENT = 4
+_LONG_DOUBLE_ALIGNMENT = 8
+_POINTER_ALIGNMENT = 4
+_MAX_ALIGNMENT = 8
+_LONG_ALIGNMENT = 8
+_LONG_DOUBLE_ALIGNMENT = 16
+_POINTER_ALIGNMENT = 8
+_MAX_ALIGNMENT = 16
+_POSIX_C_SOURCE = 1
+_LARGEFILE64_SOURCE = 1
+_LARGEFILE_SOURCE = 1
+_FILE_OFFSET_BITS = 64
+_FILE_OFFSET_BITS = 32
+_POSIX_C_SOURCE = 199506L
+_POSIX_PTHREAD_SEMANTICS = 1
+_XOPEN_VERSION = 500
+_XOPEN_VERSION = 4
+_XOPEN_VERSION = 3
+from TYPES import *
+
+# Included from sys/stream.h
+
+# Included from sys/vnode.h
+from TYPES import *
+
+# Included from sys/t_lock.h
+
+# Included from sys/machlock.h
+from TYPES import *
+LOCK_HELD_VALUE = 0xff
+def SPIN_LOCK(pl): return ((pl) > ipltospl(LOCK_LEVEL))
+
+def LOCK_SAMPLE_INTERVAL(i): return (((i) & 0xff) == 0)
+
+CLOCK_LEVEL = 10
+LOCK_LEVEL = 10
+DISP_LEVEL = (LOCK_LEVEL + 1)
+PTR24_LSB = 5
+PTR24_MSB = (PTR24_LSB + 24)
+PTR24_ALIGN = 32
+PTR24_BASE = 0xe0000000
+
+# Included from sys/param.h
+from TYPES import *
+_POSIX_VDISABLE = 0
+MAX_INPUT = 512
+MAX_CANON = 256
+UID_NOBODY = 60001
+GID_NOBODY = UID_NOBODY
+UID_NOACCESS = 60002
+MAX_TASKID = 999999
+MAX_MAXPID = 999999
+DEFAULT_MAXPID = 999999
+DEFAULT_JUMPPID = 100000
+DEFAULT_MAXPID = 30000
+DEFAULT_JUMPPID = 0
+MAXUID = 2147483647
+MAXPROJID = MAXUID
+MAXLINK = 32767
+NMOUNT = 40
+CANBSIZ = 256
+NOFILE = 20
+NGROUPS_UMIN = 0
+NGROUPS_UMAX = 32
+NGROUPS_MAX_DEFAULT = 16
+NZERO = 20
+NULL = 0L
+NULL = 0
+CMASK = 022
+CDLIMIT = (1L<<11)
+NBPS = 0x20000
+NBPSCTR = 512
+UBSIZE = 512
+SCTRSHFT = 9
+SYSNAME = 9
+PREMOTE = 39
+MAXPATHLEN = 1024
+MAXSYMLINKS = 20
+MAXNAMELEN = 256
+NADDR = 13
+PIPE_BUF = 5120
+PIPE_MAX = 5120
+NBBY = 8
+MAXBSIZE = 8192
+DEV_BSIZE = 512
+DEV_BSHIFT = 9
+MAXFRAG = 8
+MAXOFF32_T = 0x7fffffff
+MAXOFF_T = 0x7fffffffffffffffl
+MAXOFFSET_T = 0x7fffffffffffffffl
+MAXOFF_T = 0x7fffffffl
+MAXOFFSET_T = 0x7fffffff
+def btodb(bytes): return   \
+
+def dbtob(db): return   \
+
+def lbtodb(bytes): return   \
+
+def ldbtob(db): return   \
+
+NCARGS32 = 0x100000
+NCARGS64 = 0x200000
+NCARGS = NCARGS64
+NCARGS = NCARGS32
+FSHIFT = 8
+FSCALE = (1<<FSHIFT)
+def DELAY(n): return drv_usecwait(n)
+
+def mmu_ptob(x): return ((x) << MMU_PAGESHIFT)
+
+def mmu_btop(x): return (((x)) >> MMU_PAGESHIFT)
+
+def mmu_btopr(x): return ((((x) + MMU_PAGEOFFSET) >> MMU_PAGESHIFT))
+
+def mmu_ptod(x): return ((x) << (MMU_PAGESHIFT - DEV_BSHIFT))
+
+def ptod(x): return ((x) << (PAGESHIFT - DEV_BSHIFT))
+
+def ptob(x): return ((x) << PAGESHIFT)
+
+def btop(x): return (((x) >> PAGESHIFT))
+
+def btopr(x): return ((((x) + PAGEOFFSET) >> PAGESHIFT))
+
+def dtop(DD): return (((DD) + NDPP - 1) >> (PAGESHIFT - DEV_BSHIFT))
+
+def dtopt(DD): return ((DD) >> (PAGESHIFT - DEV_BSHIFT))
+
+_AIO_LISTIO_MAX = (4096)
+_AIO_MAX = (-1)
+_MQ_OPEN_MAX = (32)
+_MQ_PRIO_MAX = (32)
+_SEM_NSEMS_MAX = INT_MAX
+_SEM_VALUE_MAX = INT_MAX
+
+# Included from sys/unistd.h
+_CS_PATH = 65
+_CS_LFS_CFLAGS = 68
+_CS_LFS_LDFLAGS = 69
+_CS_LFS_LIBS = 70
+_CS_LFS_LINTFLAGS = 71
+_CS_LFS64_CFLAGS = 72
+_CS_LFS64_LDFLAGS = 73
+_CS_LFS64_LIBS = 74
+_CS_LFS64_LINTFLAGS = 75
+_CS_XBS5_ILP32_OFF32_CFLAGS = 700
+_CS_XBS5_ILP32_OFF32_LDFLAGS = 701
+_CS_XBS5_ILP32_OFF32_LIBS = 702
+_CS_XBS5_ILP32_OFF32_LINTFLAGS = 703
+_CS_XBS5_ILP32_OFFBIG_CFLAGS = 705
+_CS_XBS5_ILP32_OFFBIG_LDFLAGS = 706
+_CS_XBS5_ILP32_OFFBIG_LIBS = 707
+_CS_XBS5_ILP32_OFFBIG_LINTFLAGS = 708
+_CS_XBS5_LP64_OFF64_CFLAGS = 709
+_CS_XBS5_LP64_OFF64_LDFLAGS = 710
+_CS_XBS5_LP64_OFF64_LIBS = 711
+_CS_XBS5_LP64_OFF64_LINTFLAGS = 712
+_CS_XBS5_LPBIG_OFFBIG_CFLAGS = 713
+_CS_XBS5_LPBIG_OFFBIG_LDFLAGS = 714
+_CS_XBS5_LPBIG_OFFBIG_LIBS = 715
+_CS_XBS5_LPBIG_OFFBIG_LINTFLAGS = 716
+_SC_ARG_MAX = 1
+_SC_CHILD_MAX = 2
+_SC_CLK_TCK = 3
+_SC_NGROUPS_MAX = 4
+_SC_OPEN_MAX = 5
+_SC_JOB_CONTROL = 6
+_SC_SAVED_IDS = 7
+_SC_VERSION = 8
+_SC_PASS_MAX = 9
+_SC_LOGNAME_MAX = 10
+_SC_PAGESIZE = 11
+_SC_XOPEN_VERSION = 12
+_SC_NPROCESSORS_CONF = 14
+_SC_NPROCESSORS_ONLN = 15
+_SC_STREAM_MAX = 16
+_SC_TZNAME_MAX = 17
+_SC_AIO_LISTIO_MAX = 18
+_SC_AIO_MAX = 19
+_SC_AIO_PRIO_DELTA_MAX = 20
+_SC_ASYNCHRONOUS_IO = 21
+_SC_DELAYTIMER_MAX = 22
+_SC_FSYNC = 23
+_SC_MAPPED_FILES = 24
+_SC_MEMLOCK = 25
+_SC_MEMLOCK_RANGE = 26
+_SC_MEMORY_PROTECTION = 27
+_SC_MESSAGE_PASSING = 28
+_SC_MQ_OPEN_MAX = 29
+_SC_MQ_PRIO_MAX = 30
+_SC_PRIORITIZED_IO = 31
+_SC_PRIORITY_SCHEDULING = 32
+_SC_REALTIME_SIGNALS = 33
+_SC_RTSIG_MAX = 34
+_SC_SEMAPHORES = 35
+_SC_SEM_NSEMS_MAX = 36
+_SC_SEM_VALUE_MAX = 37
+_SC_SHARED_MEMORY_OBJECTS = 38
+_SC_SIGQUEUE_MAX = 39
+_SC_SIGRT_MIN = 40
+_SC_SIGRT_MAX = 41
+_SC_SYNCHRONIZED_IO = 42
+_SC_TIMERS = 43
+_SC_TIMER_MAX = 44
+_SC_2_C_BIND = 45
+_SC_2_C_DEV = 46
+_SC_2_C_VERSION = 47
+_SC_2_FORT_DEV = 48
+_SC_2_FORT_RUN = 49
+_SC_2_LOCALEDEF = 50
+_SC_2_SW_DEV = 51
+_SC_2_UPE = 52
+_SC_2_VERSION = 53
+_SC_BC_BASE_MAX = 54
+_SC_BC_DIM_MAX = 55
+_SC_BC_SCALE_MAX = 56
+_SC_BC_STRING_MAX = 57
+_SC_COLL_WEIGHTS_MAX = 58
+_SC_EXPR_NEST_MAX = 59
+_SC_LINE_MAX = 60
+_SC_RE_DUP_MAX = 61
+_SC_XOPEN_CRYPT = 62
+_SC_XOPEN_ENH_I18N = 63
+_SC_XOPEN_SHM = 64
+_SC_2_CHAR_TERM = 66
+_SC_XOPEN_XCU_VERSION = 67
+_SC_ATEXIT_MAX = 76
+_SC_IOV_MAX = 77
+_SC_XOPEN_UNIX = 78
+_SC_PAGE_SIZE = _SC_PAGESIZE
+_SC_T_IOV_MAX = 79
+_SC_PHYS_PAGES = 500
+_SC_AVPHYS_PAGES = 501
+_SC_COHER_BLKSZ = 503
+_SC_SPLIT_CACHE = 504
+_SC_ICACHE_SZ = 505
+_SC_DCACHE_SZ = 506
+_SC_ICACHE_LINESZ = 507
+_SC_DCACHE_LINESZ = 508
+_SC_ICACHE_BLKSZ = 509
+_SC_DCACHE_BLKSZ = 510
+_SC_DCACHE_TBLKSZ = 511
+_SC_ICACHE_ASSOC = 512
+_SC_DCACHE_ASSOC = 513
+_SC_MAXPID = 514
+_SC_STACK_PROT = 515
+_SC_THREAD_DESTRUCTOR_ITERATIONS = 568
+_SC_GETGR_R_SIZE_MAX = 569
+_SC_GETPW_R_SIZE_MAX = 570
+_SC_LOGIN_NAME_MAX = 571
+_SC_THREAD_KEYS_MAX = 572
+_SC_THREAD_STACK_MIN = 573
+_SC_THREAD_THREADS_MAX = 574
+_SC_TTY_NAME_MAX = 575
+_SC_THREADS = 576
+_SC_THREAD_ATTR_STACKADDR = 577
+_SC_THREAD_ATTR_STACKSIZE = 578
+_SC_THREAD_PRIORITY_SCHEDULING = 579
+_SC_THREAD_PRIO_INHERIT = 580
+_SC_THREAD_PRIO_PROTECT = 581
+_SC_THREAD_PROCESS_SHARED = 582
+_SC_THREAD_SAFE_FUNCTIONS = 583
+_SC_XOPEN_LEGACY = 717
+_SC_XOPEN_REALTIME = 718
+_SC_XOPEN_REALTIME_THREADS = 719
+_SC_XBS5_ILP32_OFF32 = 720
+_SC_XBS5_ILP32_OFFBIG = 721
+_SC_XBS5_LP64_OFF64 = 722
+_SC_XBS5_LPBIG_OFFBIG = 723
+_PC_LINK_MAX = 1
+_PC_MAX_CANON = 2
+_PC_MAX_INPUT = 3
+_PC_NAME_MAX = 4
+_PC_PATH_MAX = 5
+_PC_PIPE_BUF = 6
+_PC_NO_TRUNC = 7
+_PC_VDISABLE = 8
+_PC_CHOWN_RESTRICTED = 9
+_PC_ASYNC_IO = 10
+_PC_PRIO_IO = 11
+_PC_SYNC_IO = 12
+_PC_FILESIZEBITS = 67
+_PC_LAST = 67
+_POSIX_VERSION = 199506L
+_POSIX2_VERSION = 199209L
+_POSIX2_C_VERSION = 199209L
+_XOPEN_XCU_VERSION = 4
+_XOPEN_REALTIME = 1
+_XOPEN_ENH_I18N = 1
+_XOPEN_SHM = 1
+_POSIX2_C_BIND = 1
+_POSIX2_CHAR_TERM = 1
+_POSIX2_LOCALEDEF = 1
+_POSIX2_C_DEV = 1
+_POSIX2_SW_DEV = 1
+_POSIX2_UPE = 1
+
+# Included from sys/mutex.h
+from TYPES import *
+def MUTEX_HELD(x): return (mutex_owned(x))
+
+
+# Included from sys/rwlock.h
+from TYPES import *
+def RW_READ_HELD(x): return (rw_read_held((x)))
+
+def RW_WRITE_HELD(x): return (rw_write_held((x)))
+
+def RW_LOCK_HELD(x): return (rw_lock_held((x)))
+
+def RW_ISWRITER(x): return (rw_iswriter(x))
+
+
+# Included from sys/semaphore.h
+
+# Included from sys/thread.h
+from TYPES import *
+
+# Included from sys/klwp.h
+from TYPES import *
+
+# Included from sys/condvar.h
+from TYPES import *
+
+# Included from sys/time.h
+
+# Included from sys/types32.h
+
+# Included from sys/int_types.h
+TIME32_MAX = INT32_MAX
+TIME32_MIN = INT32_MIN
+def TIMEVAL_OVERFLOW(tv): return \
+
+from TYPES import *
+DST_NONE = 0
+DST_USA = 1
+DST_AUST = 2
+DST_WET = 3
+DST_MET = 4
+DST_EET = 5
+DST_CAN = 6
+DST_GB = 7
+DST_RUM = 8
+DST_TUR = 9
+DST_AUSTALT = 10
+ITIMER_REAL = 0
+ITIMER_VIRTUAL = 1
+ITIMER_PROF = 2
+ITIMER_REALPROF = 3
+def ITIMERVAL_OVERFLOW(itv): return \
+
+SEC = 1
+MILLISEC = 1000
+MICROSEC = 1000000
+NANOSEC = 1000000000
+
+# Included from sys/time_impl.h
+def TIMESPEC_OVERFLOW(ts): return \
+
+def ITIMERSPEC_OVERFLOW(it): return \
+
+__CLOCK_REALTIME0 = 0
+CLOCK_VIRTUAL = 1
+CLOCK_PROF = 2
+__CLOCK_REALTIME3 = 3
+CLOCK_HIGHRES = 4
+CLOCK_MAX = 5
+CLOCK_REALTIME = __CLOCK_REALTIME3
+CLOCK_REALTIME = __CLOCK_REALTIME0
+TIMER_RELTIME = 0x0
+TIMER_ABSTIME = 0x1
+def TICK_TO_SEC(tick): return ((tick) / hz)
+
+def SEC_TO_TICK(sec): return ((sec) * hz)
+
+def TICK_TO_MSEC(tick): return \
+
+def MSEC_TO_TICK(msec): return \
+
+def MSEC_TO_TICK_ROUNDUP(msec): return \
+
+def TICK_TO_USEC(tick): return ((tick) * usec_per_tick)
+
+def USEC_TO_TICK(usec): return ((usec) / usec_per_tick)
+
+def USEC_TO_TICK_ROUNDUP(usec): return \
+
+def TICK_TO_NSEC(tick): return ((tick) * nsec_per_tick)
+
+def NSEC_TO_TICK(nsec): return ((nsec) / nsec_per_tick)
+
+def NSEC_TO_TICK_ROUNDUP(nsec): return \
+
+def TIMEVAL_TO_TICK(tvp): return \
+
+def TIMESTRUC_TO_TICK(tsp): return \
+
+
+# Included from time.h
+from TYPES import *
+
+# Included from iso/time_iso.h
+NULL = 0L
+NULL = 0
+CLOCKS_PER_SEC = 1000000
+
+# Included from sys/select.h
+FD_SETSIZE = 65536
+FD_SETSIZE = 1024
+_NBBY = 8
+NBBY = _NBBY
+def FD_ZERO(p): return bzero((p), sizeof (*(p)))
+
+
+# Included from sys/signal.h
+
+# Included from sys/iso/signal_iso.h
+SIGHUP = 1
+SIGINT = 2
+SIGQUIT = 3
+SIGILL = 4
+SIGTRAP = 5
+SIGIOT = 6
+SIGABRT = 6
+SIGEMT = 7
+SIGFPE = 8
+SIGKILL = 9
+SIGBUS = 10
+SIGSEGV = 11
+SIGSYS = 12
+SIGPIPE = 13
+SIGALRM = 14
+SIGTERM = 15
+SIGUSR1 = 16
+SIGUSR2 = 17
+SIGCLD = 18
+SIGCHLD = 18
+SIGPWR = 19
+SIGWINCH = 20
+SIGURG = 21
+SIGPOLL = 22
+SIGIO = SIGPOLL
+SIGSTOP = 23
+SIGTSTP = 24
+SIGCONT = 25
+SIGTTIN = 26
+SIGTTOU = 27
+SIGVTALRM = 28
+SIGPROF = 29
+SIGXCPU = 30
+SIGXFSZ = 31
+SIGWAITING = 32
+SIGLWP = 33
+SIGFREEZE = 34
+SIGTHAW = 35
+SIGCANCEL = 36
+SIGLOST = 37
+_SIGRTMIN = 38
+_SIGRTMAX = 45
+SIG_BLOCK = 1
+SIG_UNBLOCK = 2
+SIG_SETMASK = 3
+SIGNO_MASK = 0xFF
+SIGDEFER = 0x100
+SIGHOLD = 0x200
+SIGRELSE = 0x400
+SIGIGNORE = 0x800
+SIGPAUSE = 0x1000
+
+# Included from sys/siginfo.h
+from TYPES import *
+SIGEV_NONE = 1
+SIGEV_SIGNAL = 2
+SIGEV_THREAD = 3
+SI_NOINFO = 32767
+SI_USER = 0
+SI_LWP = (-1)
+SI_QUEUE = (-2)
+SI_TIMER = (-3)
+SI_ASYNCIO = (-4)
+SI_MESGQ = (-5)
+
+# Included from sys/machsig.h
+ILL_ILLOPC = 1
+ILL_ILLOPN = 2
+ILL_ILLADR = 3
+ILL_ILLTRP = 4
+ILL_PRVOPC = 5
+ILL_PRVREG = 6
+ILL_COPROC = 7
+ILL_BADSTK = 8
+NSIGILL = 8
+EMT_TAGOVF = 1
+EMT_CPCOVF = 2
+NSIGEMT = 2
+FPE_INTDIV = 1
+FPE_INTOVF = 2
+FPE_FLTDIV = 3
+FPE_FLTOVF = 4
+FPE_FLTUND = 5
+FPE_FLTRES = 6
+FPE_FLTINV = 7
+FPE_FLTSUB = 8
+NSIGFPE = 8
+SEGV_MAPERR = 1
+SEGV_ACCERR = 2
+NSIGSEGV = 2
+BUS_ADRALN = 1
+BUS_ADRERR = 2
+BUS_OBJERR = 3
+NSIGBUS = 3
+TRAP_BRKPT = 1
+TRAP_TRACE = 2
+TRAP_RWATCH = 3
+TRAP_WWATCH = 4
+TRAP_XWATCH = 5
+NSIGTRAP = 5
+CLD_EXITED = 1
+CLD_KILLED = 2
+CLD_DUMPED = 3
+CLD_TRAPPED = 4
+CLD_STOPPED = 5
+CLD_CONTINUED = 6
+NSIGCLD = 6
+POLL_IN = 1
+POLL_OUT = 2
+POLL_MSG = 3
+POLL_ERR = 4
+POLL_PRI = 5
+POLL_HUP = 6
+NSIGPOLL = 6
+PROF_SIG = 1
+NSIGPROF = 1
+SI_MAXSZ = 256
+SI_MAXSZ = 128
+
+# Included from sys/time_std_impl.h
+from TYPES import *
+SI32_MAXSZ = 128
+def SI_CANQUEUE(c): return ((c) <= SI_QUEUE)
+
+SA_NOCLDSTOP = 0x00020000
+SA_ONSTACK = 0x00000001
+SA_RESETHAND = 0x00000002
+SA_RESTART = 0x00000004
+SA_SIGINFO = 0x00000008
+SA_NODEFER = 0x00000010
+SA_NOCLDWAIT = 0x00010000
+SA_WAITSIG = 0x00010000
+NSIG = 46
+MAXSIG = 45
+S_SIGNAL = 1
+S_SIGSET = 2
+S_SIGACTION = 3
+S_NONE = 4
+MINSIGSTKSZ = 2048
+SIGSTKSZ = 8192
+SS_ONSTACK = 0x00000001
+SS_DISABLE = 0x00000002
+SN_PROC = 1
+SN_CANCEL = 2
+SN_SEND = 3
+
+# Included from sys/ucontext.h
+from TYPES import *
+
+# Included from sys/regset.h
+REG_CCR = (0)
+REG_PSR = (0)
+REG_PSR = (0)
+REG_PC = (1)
+REG_nPC = (2)
+REG_Y = (3)
+REG_G1 = (4)
+REG_G2 = (5)
+REG_G3 = (6)
+REG_G4 = (7)
+REG_G5 = (8)
+REG_G6 = (9)
+REG_G7 = (10)
+REG_O0 = (11)
+REG_O1 = (12)
+REG_O2 = (13)
+REG_O3 = (14)
+REG_O4 = (15)
+REG_O5 = (16)
+REG_O6 = (17)
+REG_O7 = (18)
+REG_ASI = (19)
+REG_FPRS = (20)
+REG_PS = REG_PSR
+REG_SP = REG_O6
+REG_R0 = REG_O0
+REG_R1 = REG_O1
+_NGREG = 21
+_NGREG = 19
+NGREG = _NGREG
+_NGREG32 = 19
+_NGREG64 = 21
+SPARC_MAXREGWINDOW = 31
+MAXFPQ = 16
+XRS_ID = 0x78727300
+
+# Included from v7/sys/privregs.h
+
+# Included from v7/sys/psr.h
+PSR_CWP = 0x0000001F
+PSR_ET = 0x00000020
+PSR_PS = 0x00000040
+PSR_S = 0x00000080
+PSR_PIL = 0x00000F00
+PSR_EF = 0x00001000
+PSR_EC = 0x00002000
+PSR_RSV = 0x000FC000
+PSR_ICC = 0x00F00000
+PSR_C = 0x00100000
+PSR_V = 0x00200000
+PSR_Z = 0x00400000
+PSR_N = 0x00800000
+PSR_VER = 0x0F000000
+PSR_IMPL = 0xF0000000
+PSL_ALLCC = PSR_ICC
+PSL_USER = (PSR_S)
+PSL_USERMASK = (PSR_ICC)
+PSL_UBITS = (PSR_ICC|PSR_EF)
+def USERMODE(ps): return (((ps) & PSR_PS) == 0)
+
+
+# Included from sys/fsr.h
+FSR_CEXC = 0x0000001f
+FSR_AEXC = 0x000003e0
+FSR_FCC = 0x00000c00
+FSR_PR = 0x00001000
+FSR_QNE = 0x00002000
+FSR_FTT = 0x0001c000
+FSR_VER = 0x000e0000
+FSR_TEM = 0x0f800000
+FSR_RP = 0x30000000
+FSR_RD = 0xc0000000
+FSR_VER_SHIFT = 17
+FSR_FCC1 = 0x00000003
+FSR_FCC2 = 0x0000000C
+FSR_FCC3 = 0x00000030
+FSR_CEXC_NX = 0x00000001
+FSR_CEXC_DZ = 0x00000002
+FSR_CEXC_UF = 0x00000004
+FSR_CEXC_OF = 0x00000008
+FSR_CEXC_NV = 0x00000010
+FSR_AEXC_NX = (0x1 << 5)
+FSR_AEXC_DZ = (0x2 << 5)
+FSR_AEXC_UF = (0x4 << 5)
+FSR_AEXC_OF = (0x8 << 5)
+FSR_AEXC_NV = (0x10 << 5)
+FTT_NONE = 0
+FTT_IEEE = 1
+FTT_UNFIN = 2
+FTT_UNIMP = 3
+FTT_SEQ = 4
+FTT_ALIGN = 5
+FTT_DFAULT = 6
+FSR_FTT_SHIFT = 14
+FSR_FTT_IEEE = (FTT_IEEE   << FSR_FTT_SHIFT)
+FSR_FTT_UNFIN = (FTT_UNFIN  << FSR_FTT_SHIFT)
+FSR_FTT_UNIMP = (FTT_UNIMP  << FSR_FTT_SHIFT)
+FSR_FTT_SEQ = (FTT_SEQ    << FSR_FTT_SHIFT)
+FSR_FTT_ALIGN = (FTT_ALIGN  << FSR_FTT_SHIFT)
+FSR_FTT_DFAULT = (FTT_DFAULT << FSR_FTT_SHIFT)
+FSR_TEM_NX = (0x1 << 23)
+FSR_TEM_DZ = (0x2 << 23)
+FSR_TEM_UF = (0x4 << 23)
+FSR_TEM_OF = (0x8 << 23)
+FSR_TEM_NV = (0x10 << 23)
+RP_DBLEXT = 0
+RP_SINGLE = 1
+RP_DOUBLE = 2
+RP_RESERVED = 3
+RD_NEAR = 0
+RD_ZER0 = 1
+RD_POSINF = 2
+RD_NEGINF = 3
+FPRS_DL = 0x1
+FPRS_DU = 0x2
+FPRS_FEF = 0x4
+PIL_MAX = 0xf
+def SAVE_GLOBALS(RP): return \
+
+def RESTORE_GLOBALS(RP): return \
+
+def SAVE_OUTS(RP): return \
+
+def RESTORE_OUTS(RP): return \
+
+def SAVE_WINDOW(SBP): return \
+
+def RESTORE_WINDOW(SBP): return \
+
+def STORE_FPREGS(FP): return \
+
+def LOAD_FPREGS(FP): return \
+
+_SPARC_MAXREGWINDOW = 31
+_XRS_ID = 0x78727300
+GETCONTEXT = 0
+SETCONTEXT = 1
+UC_SIGMASK = 001
+UC_STACK = 002
+UC_CPU = 004
+UC_MAU = 010
+UC_FPU = UC_MAU
+UC_INTR = 020
+UC_ASR = 040
+UC_MCONTEXT = (UC_CPU|UC_FPU|UC_ASR)
+UC_ALL = (UC_SIGMASK|UC_STACK|UC_MCONTEXT)
+_SIGQUEUE_MAX = 32
+_SIGNOTIFY_MAX = 32
+
+# Included from sys/pcb.h
+INSTR_VALID = 0x02
+NORMAL_STEP = 0x04
+WATCH_STEP = 0x08
+CPC_OVERFLOW = 0x10
+ASYNC_HWERR = 0x20
+STEP_NONE = 0
+STEP_REQUESTED = 1
+STEP_ACTIVE = 2
+STEP_WASACTIVE = 3
+
+# Included from sys/msacct.h
+LMS_USER = 0
+LMS_SYSTEM = 1
+LMS_TRAP = 2
+LMS_TFAULT = 3
+LMS_DFAULT = 4
+LMS_KFAULT = 5
+LMS_USER_LOCK = 6
+LMS_SLEEP = 7
+LMS_WAIT_CPU = 8
+LMS_STOPPED = 9
+NMSTATES = 10
+
+# Included from sys/lwp.h
+
+# Included from sys/synch.h
+from TYPES import *
+USYNC_THREAD = 0x00
+USYNC_PROCESS = 0x01
+LOCK_NORMAL = 0x00
+LOCK_ERRORCHECK = 0x02
+LOCK_RECURSIVE = 0x04
+USYNC_PROCESS_ROBUST = 0x08
+LOCK_PRIO_NONE = 0x00
+LOCK_PRIO_INHERIT = 0x10
+LOCK_PRIO_PROTECT = 0x20
+LOCK_STALL_NP = 0x00
+LOCK_ROBUST_NP = 0x40
+LOCK_OWNERDEAD = 0x1
+LOCK_NOTRECOVERABLE = 0x2
+LOCK_INITED = 0x4
+LOCK_UNMAPPED = 0x8
+LWP_DETACHED = 0x00000040
+LWP_SUSPENDED = 0x00000080
+__LWP_ASLWP = 0x00000100
+MAXSYSARGS = 8
+NORMALRETURN = 0
+JUSTRETURN = 1
+LWP_USER = 0x01
+LWP_SYS = 0x02
+TS_FREE = 0x00
+TS_SLEEP = 0x01
+TS_RUN = 0x02
+TS_ONPROC = 0x04
+TS_ZOMB = 0x08
+TS_STOPPED = 0x10
+T_INTR_THREAD = 0x0001
+T_WAKEABLE = 0x0002
+T_TOMASK = 0x0004
+T_TALLOCSTK = 0x0008
+T_WOULDBLOCK = 0x0020
+T_DONTBLOCK = 0x0040
+T_DONTPEND = 0x0080
+T_SYS_PROF = 0x0100
+T_WAITCVSEM = 0x0200
+T_WATCHPT = 0x0400
+T_PANIC = 0x0800
+TP_HOLDLWP = 0x0002
+TP_TWAIT = 0x0004
+TP_LWPEXIT = 0x0008
+TP_PRSTOP = 0x0010
+TP_CHKPT = 0x0020
+TP_EXITLWP = 0x0040
+TP_PRVSTOP = 0x0080
+TP_MSACCT = 0x0100
+TP_STOPPING = 0x0200
+TP_WATCHPT = 0x0400
+TP_PAUSE = 0x0800
+TP_CHANGEBIND = 0x1000
+TS_LOAD = 0x0001
+TS_DONT_SWAP = 0x0002
+TS_SWAPENQ = 0x0004
+TS_ON_SWAPQ = 0x0008
+TS_CSTART = 0x0100
+TS_UNPAUSE = 0x0200
+TS_XSTART = 0x0400
+TS_PSTART = 0x0800
+TS_RESUME = 0x1000
+TS_CREATE = 0x2000
+TS_ALLSTART = \
+        (TS_CSTART|TS_UNPAUSE|TS_XSTART|TS_PSTART|TS_RESUME|TS_CREATE)
+def CPR_VSTOPPED(t): return \
+
+def THREAD_TRANSITION(tp): return thread_transition(tp);
+
+def THREAD_STOP(tp): return \
+
+def THREAD_ZOMB(tp): return THREAD_SET_STATE(tp, TS_ZOMB, NULL)
+
+def SEMA_HELD(x): return (sema_held((x)))
+
+NO_LOCKS_HELD = 1
+NO_COMPETING_THREADS = 1
+
+# Included from sys/cred.h
+
+# Included from sys/uio.h
+from TYPES import *
+
+# Included from sys/resource.h
+from TYPES import *
+PRIO_PROCESS = 0
+PRIO_PGRP = 1
+PRIO_USER = 2
+RLIMIT_CPU = 0
+RLIMIT_FSIZE = 1
+RLIMIT_DATA = 2
+RLIMIT_STACK = 3
+RLIMIT_CORE = 4
+RLIMIT_NOFILE = 5
+RLIMIT_VMEM = 6
+RLIMIT_AS = RLIMIT_VMEM
+RLIM_NLIMITS = 7
+RLIM_INFINITY = (-3l)
+RLIM_SAVED_MAX = (-2l)
+RLIM_SAVED_CUR = (-1l)
+RLIM_INFINITY = 0x7fffffff
+RLIM_SAVED_MAX = 0x7ffffffe
+RLIM_SAVED_CUR = 0x7ffffffd
+RLIM32_INFINITY = 0x7fffffff
+RLIM32_SAVED_MAX = 0x7ffffffe
+RLIM32_SAVED_CUR = 0x7ffffffd
+
+# Included from sys/model.h
+
+# Included from sys/debug.h
+def ASSERT64(x): return ASSERT(x)
+
+def ASSERT32(x): return ASSERT(x)
+
+DATAMODEL_MASK = 0x0FF00000
+DATAMODEL_ILP32 = 0x00100000
+DATAMODEL_LP64 = 0x00200000
+DATAMODEL_NONE = 0
+DATAMODEL_NATIVE = DATAMODEL_LP64
+DATAMODEL_NATIVE = DATAMODEL_ILP32
+def STRUCT_SIZE(handle): return \
+
+def STRUCT_BUF(handle): return ((handle).ptr.m64)
+
+def SIZEOF_PTR(umodel): return \
+
+def STRUCT_SIZE(handle): return (sizeof (*(handle).ptr))
+
+def STRUCT_BUF(handle): return ((handle).ptr)
+
+def SIZEOF_PTR(umodel): return sizeof (caddr_t)
+
+def lwp_getdatamodel(t): return DATAMODEL_ILP32
+
+RUSAGE_SELF = 0
+RUSAGE_CHILDREN = -1
+
+# Included from vm/seg_enum.h
+
+# Included from sys/buf.h
+
+# Included from sys/kstat.h
+from TYPES import *
+KSTAT_STRLEN = 31
+def KSTAT_ENTER(k): return \
+
+def KSTAT_EXIT(k): return \
+
+KSTAT_TYPE_RAW = 0
+KSTAT_TYPE_NAMED = 1
+KSTAT_TYPE_INTR = 2
+KSTAT_TYPE_IO = 3
+KSTAT_TYPE_TIMER = 4
+KSTAT_NUM_TYPES = 5
+KSTAT_FLAG_VIRTUAL = 0x01
+KSTAT_FLAG_VAR_SIZE = 0x02
+KSTAT_FLAG_WRITABLE = 0x04
+KSTAT_FLAG_PERSISTENT = 0x08
+KSTAT_FLAG_DORMANT = 0x10
+KSTAT_FLAG_INVALID = 0x20
+KSTAT_READ = 0
+KSTAT_WRITE = 1
+KSTAT_DATA_CHAR = 0
+KSTAT_DATA_INT32 = 1
+KSTAT_DATA_UINT32 = 2
+KSTAT_DATA_INT64 = 3
+KSTAT_DATA_UINT64 = 4
+KSTAT_DATA_LONG = KSTAT_DATA_INT32
+KSTAT_DATA_ULONG = KSTAT_DATA_UINT32
+KSTAT_DATA_LONG = KSTAT_DATA_INT64
+KSTAT_DATA_ULONG = KSTAT_DATA_UINT64
+KSTAT_DATA_LONG = 7
+KSTAT_DATA_ULONG = 8
+KSTAT_DATA_LONGLONG = KSTAT_DATA_INT64
+KSTAT_DATA_ULONGLONG = KSTAT_DATA_UINT64
+KSTAT_DATA_FLOAT = 5
+KSTAT_DATA_DOUBLE = 6
+KSTAT_INTR_HARD = 0
+KSTAT_INTR_SOFT = 1
+KSTAT_INTR_WATCHDOG = 2
+KSTAT_INTR_SPURIOUS = 3
+KSTAT_INTR_MULTSVC = 4
+KSTAT_NUM_INTRS = 5
+B_BUSY = 0x0001
+B_DONE = 0x0002
+B_ERROR = 0x0004
+B_PAGEIO = 0x0010
+B_PHYS = 0x0020
+B_READ = 0x0040
+B_WRITE = 0x0100
+B_KERNBUF = 0x0008
+B_WANTED = 0x0080
+B_AGE = 0x000200
+B_ASYNC = 0x000400
+B_DELWRI = 0x000800
+B_STALE = 0x001000
+B_DONTNEED = 0x002000
+B_REMAPPED = 0x004000
+B_FREE = 0x008000
+B_INVAL = 0x010000
+B_FORCE = 0x020000
+B_HEAD = 0x040000
+B_NOCACHE = 0x080000
+B_TRUNC = 0x100000
+B_SHADOW = 0x200000
+B_RETRYWRI = 0x400000
+def notavail(bp): return \
+
+def BWRITE(bp): return \
+
+def BWRITE2(bp): return \
+
+VROOT = 0x01
+VNOCACHE = 0x02
+VNOMAP = 0x04
+VDUP = 0x08
+VNOSWAP = 0x10
+VNOMOUNT = 0x20
+VISSWAP = 0x40
+VSWAPLIKE = 0x80
+VVFSLOCK = 0x100
+VVFSWAIT = 0x200
+VVMLOCK = 0x400
+VDIROPEN = 0x800
+VVMEXEC = 0x1000
+VPXFS = 0x2000
+AT_TYPE = 0x0001
+AT_MODE = 0x0002
+AT_UID = 0x0004
+AT_GID = 0x0008
+AT_FSID = 0x0010
+AT_NODEID = 0x0020
+AT_NLINK = 0x0040
+AT_SIZE = 0x0080
+AT_ATIME = 0x0100
+AT_MTIME = 0x0200
+AT_CTIME = 0x0400
+AT_RDEV = 0x0800
+AT_BLKSIZE = 0x1000
+AT_NBLOCKS = 0x2000
+AT_VCODE = 0x4000
+AT_ALL = (AT_TYPE|AT_MODE|AT_UID|AT_GID|AT_FSID|AT_NODEID|\
+                        AT_NLINK|AT_SIZE|AT_ATIME|AT_MTIME|AT_CTIME|\
+                        AT_RDEV|AT_BLKSIZE|AT_NBLOCKS|AT_VCODE)
+AT_STAT = (AT_MODE|AT_UID|AT_GID|AT_FSID|AT_NODEID|AT_NLINK|\
+                        AT_SIZE|AT_ATIME|AT_MTIME|AT_CTIME|AT_RDEV)
+AT_TIMES = (AT_ATIME|AT_MTIME|AT_CTIME)
+AT_NOSET = (AT_NLINK|AT_RDEV|AT_FSID|AT_NODEID|AT_TYPE|\
+                        AT_BLKSIZE|AT_NBLOCKS|AT_VCODE)
+VSUID = 04000
+VSGID = 02000
+VSVTX = 01000
+VREAD = 00400
+VWRITE = 00200
+VEXEC = 00100
+MODEMASK = 07777
+PERMMASK = 00777
+def MANDMODE(mode): return (((mode) & (VSGID|(VEXEC>>3))) == VSGID)
+
+VSA_ACL = 0x0001
+VSA_ACLCNT = 0x0002
+VSA_DFACL = 0x0004
+VSA_DFACLCNT = 0x0008
+LOOKUP_DIR = 0x01
+DUMP_ALLOC = 0
+DUMP_FREE = 1
+DUMP_SCAN = 2
+ATTR_UTIME = 0x01
+ATTR_EXEC = 0x02
+ATTR_COMM = 0x04
+ATTR_HINT = 0x08
+ATTR_REAL = 0x10
+
+# Included from sys/poll.h
+POLLIN = 0x0001
+POLLPRI = 0x0002
+POLLOUT = 0x0004
+POLLRDNORM = 0x0040
+POLLWRNORM = POLLOUT
+POLLRDBAND = 0x0080
+POLLWRBAND = 0x0100
+POLLNORM = POLLRDNORM
+POLLERR = 0x0008
+POLLHUP = 0x0010
+POLLNVAL = 0x0020
+POLLREMOVE = 0x0800
+POLLRDDATA = 0x0200
+POLLNOERR = 0x0400
+POLLCLOSED = 0x8000
+
+# Included from sys/strmdep.h
+def str_aligned(X): return (((ulong_t)(X) & (sizeof (long) - 1)) == 0)
+
+
+# Included from sys/strft.h
+tdelta_t_sz = 12
+FTEV_MASK = 0x1FFF
+FTEV_ISWR = 0x8000
+FTEV_CS = 0x4000
+FTEV_PS = 0x2000
+FTEV_QMASK = 0x1F00
+FTEV_ALLOCMASK = 0x1FF8
+FTEV_ALLOCB = 0x0000
+FTEV_ESBALLOC = 0x0001
+FTEV_DESBALLOC = 0x0002
+FTEV_ESBALLOCA = 0x0003
+FTEV_DESBALLOCA = 0x0004
+FTEV_ALLOCBIG = 0x0005
+FTEV_ALLOCBW = 0x0006
+FTEV_FREEB = 0x0008
+FTEV_DUPB = 0x0009
+FTEV_COPYB = 0x000A
+FTEV_CALLER = 0x000F
+FTEV_PUT = 0x0100
+FTEV_FSYNCQ = 0x0103
+FTEV_DSYNCQ = 0x0104
+FTEV_PUTQ = 0x0105
+FTEV_GETQ = 0x0106
+FTEV_RMVQ = 0x0107
+FTEV_INSQ = 0x0108
+FTEV_PUTBQ = 0x0109
+FTEV_FLUSHQ = 0x010A
+FTEV_REPLYQ = 0x010B
+FTEV_PUTNEXT = 0x010D
+FTEV_RWNEXT = 0x010E
+FTEV_QWINNER = 0x010F
+FTEV_GEWRITE = 0x0101
+def FTFLW_HASH(h): return (((unsigned)(h))%ftflw_hash_sz)
+
+FTBLK_EVNTS = 0x9
+QENAB = 0x00000001
+QWANTR = 0x00000002
+QWANTW = 0x00000004
+QFULL = 0x00000008
+QREADR = 0x00000010
+QUSE = 0x00000020
+QNOENB = 0x00000040
+QBACK = 0x00000100
+QHLIST = 0x00000200
+QPAIR = 0x00000800
+QPERQ = 0x00001000
+QPERMOD = 0x00002000
+QMTSAFE = 0x00004000
+QMTOUTPERIM = 0x00008000
+QMT_TYPEMASK = (QPAIR|QPERQ|QPERMOD|QMTSAFE|QMTOUTPERIM)
+QINSERVICE = 0x00010000
+QWCLOSE = 0x00020000
+QEND = 0x00040000
+QWANTWSYNC = 0x00080000
+QSYNCSTR = 0x00100000
+QISDRV = 0x00200000
+QHOT = 0x00400000
+QNEXTHOT = 0x00800000
+_QINSERTING = 0x04000000
+_QREMOVING = 0x08000000
+Q_SQQUEUED = 0x01
+Q_SQDRAINING = 0x02
+QB_FULL = 0x01
+QB_WANTW = 0x02
+QB_BACK = 0x04
+NBAND = 256
+STRUIOT_NONE = -1
+STRUIOT_DONTCARE = 0
+STRUIOT_STANDARD = 1
+STRUIOT_IP = 2
+DBLK_REFMIN = 0x01
+STRUIO_SPEC = 0x01
+STRUIO_DONE = 0x02
+STRUIO_IP = 0x04
+STRUIO_ZC = 0x08
+STRUIO_ICK = 0x10
+MSGMARK = 0x01
+MSGNOLOOP = 0x02
+MSGDELIM = 0x04
+MSGNOGET = 0x08
+MSGMARKNEXT = 0x10
+MSGNOTMARKNEXT = 0x20
+M_DATA = 0x00
+M_PROTO = 0x01
+M_BREAK = 0x08
+M_PASSFP = 0x09
+M_EVENT = 0x0a
+M_SIG = 0x0b
+M_DELAY = 0x0c
+M_CTL = 0x0d
+M_IOCTL = 0x0e
+M_SETOPTS = 0x10
+M_RSE = 0x11
+M_IOCACK = 0x81
+M_IOCNAK = 0x82
+M_PCPROTO = 0x83
+M_PCSIG = 0x84
+M_READ = 0x85
+M_FLUSH = 0x86
+M_STOP = 0x87
+M_START = 0x88
+M_HANGUP = 0x89
+M_ERROR = 0x8a
+M_COPYIN = 0x8b
+M_COPYOUT = 0x8c
+M_IOCDATA = 0x8d
+M_PCRSE = 0x8e
+M_STOPI = 0x8f
+M_STARTI = 0x90
+M_PCEVENT = 0x91
+M_UNHANGUP = 0x92
+QNORM = 0x00
+QPCTL = 0x80
+IOC_MODELS = DATAMODEL_MASK
+IOC_ILP32 = DATAMODEL_ILP32
+IOC_LP64 = DATAMODEL_LP64
+IOC_NATIVE = DATAMODEL_NATIVE
+IOC_NONE = DATAMODEL_NONE
+STRCANON = 0x01
+RECOPY = 0x02
+SO_ALL = 0x003f
+SO_READOPT = 0x0001
+SO_WROFF = 0x0002
+SO_MINPSZ = 0x0004
+SO_MAXPSZ = 0x0008
+SO_HIWAT = 0x0010
+SO_LOWAT = 0x0020
+SO_MREADON = 0x0040
+SO_MREADOFF = 0x0080
+SO_NDELON = 0x0100
+SO_NDELOFF = 0x0200
+SO_ISTTY = 0x0400
+SO_ISNTTY = 0x0800
+SO_TOSTOP = 0x1000
+SO_TONSTOP = 0x2000
+SO_BAND = 0x4000
+SO_DELIM = 0x8000
+SO_NODELIM = 0x010000
+SO_STRHOLD = 0x020000
+SO_ERROPT = 0x040000
+SO_COPYOPT = 0x080000
+SO_MAXBLK = 0x100000
+DEF_IOV_MAX = 16
+INFOD_FIRSTBYTES = 0x02
+INFOD_BYTES = 0x04
+INFOD_COUNT = 0x08
+INFOD_COPYOUT = 0x10
+MODOPEN = 0x1
+CLONEOPEN = 0x2
+CONSOPEN = 0x4
+OPENFAIL = -1
+BPRI_LO = 1
+BPRI_MED = 2
+BPRI_HI = 3
+BPRI_FT = 4
+INFPSZ = -1
+FLUSHALL = 1
+FLUSHDATA = 0
+STRHIGH = 5120
+STRLOW = 1024
+MAXIOCBSZ = 1024
+PERIM_INNER = 1
+PERIM_OUTER = 2
+def datamsg(type): return \
+
+def straln(a): return (caddr_t)((intptr_t)(a) & ~(sizeof (int)-1))
+
+
+# Included from sys/byteorder.h
+def ntohl(x): return (x)
+
+def ntohs(x): return (x)
+
+def htonl(x): return (x)
+
+def htons(x): return (x)
+
+IPPROTO_IP = 0
+IPPROTO_HOPOPTS = 0
+IPPROTO_ICMP = 1
+IPPROTO_IGMP = 2
+IPPROTO_GGP = 3
+IPPROTO_ENCAP = 4
+IPPROTO_TCP = 6
+IPPROTO_EGP = 8
+IPPROTO_PUP = 12
+IPPROTO_UDP = 17
+IPPROTO_IDP = 22
+IPPROTO_IPV6 = 41
+IPPROTO_ROUTING = 43
+IPPROTO_FRAGMENT = 44
+IPPROTO_RSVP = 46
+IPPROTO_ESP = 50
+IPPROTO_AH = 51
+IPPROTO_ICMPV6 = 58
+IPPROTO_NONE = 59
+IPPROTO_DSTOPTS = 60
+IPPROTO_HELLO = 63
+IPPROTO_ND = 77
+IPPROTO_EON = 80
+IPPROTO_PIM = 103
+IPPROTO_RAW = 255
+IPPROTO_MAX = 256
+IPPORT_ECHO = 7
+IPPORT_DISCARD = 9
+IPPORT_SYSTAT = 11
+IPPORT_DAYTIME = 13
+IPPORT_NETSTAT = 15
+IPPORT_FTP = 21
+IPPORT_TELNET = 23
+IPPORT_SMTP = 25
+IPPORT_TIMESERVER = 37
+IPPORT_NAMESERVER = 42
+IPPORT_WHOIS = 43
+IPPORT_MTP = 57
+IPPORT_BOOTPS = 67
+IPPORT_BOOTPC = 68
+IPPORT_TFTP = 69
+IPPORT_RJE = 77
+IPPORT_FINGER = 79
+IPPORT_TTYLINK = 87
+IPPORT_SUPDUP = 95
+IPPORT_EXECSERVER = 512
+IPPORT_LOGINSERVER = 513
+IPPORT_CMDSERVER = 514
+IPPORT_EFSSERVER = 520
+IPPORT_BIFFUDP = 512
+IPPORT_WHOSERVER = 513
+IPPORT_ROUTESERVER = 520
+IPPORT_RESERVED = 1024
+IPPORT_USERRESERVED = 5000
+IMPLINK_IP = 155
+IMPLINK_LOWEXPER = 156
+IMPLINK_HIGHEXPER = 158
+IN_CLASSA_NSHIFT = 24
+IN_CLASSA_MAX = 128
+IN_CLASSB_NSHIFT = 16
+IN_CLASSB_MAX = 65536
+IN_CLASSC_NSHIFT = 8
+IN_CLASSD_NSHIFT = 28
+def IN_MULTICAST(i): return IN_CLASSD(i)
+
+IN_LOOPBACKNET = 127
+def IN_SET_LOOPBACK_ADDR(a): return \
+
+def IN6_IS_ADDR_UNSPECIFIED(addr): return \
+
+def IN6_IS_ADDR_LOOPBACK(addr): return \
+
+def IN6_IS_ADDR_LOOPBACK(addr): return \
+
+def IN6_IS_ADDR_MULTICAST(addr): return \
+
+def IN6_IS_ADDR_MULTICAST(addr): return \
+
+def IN6_IS_ADDR_LINKLOCAL(addr): return \
+
+def IN6_IS_ADDR_LINKLOCAL(addr): return \
+
+def IN6_IS_ADDR_SITELOCAL(addr): return \
+
+def IN6_IS_ADDR_SITELOCAL(addr): return \
+
+def IN6_IS_ADDR_V4MAPPED(addr): return \
+
+def IN6_IS_ADDR_V4MAPPED(addr): return \
+
+def IN6_IS_ADDR_V4MAPPED_ANY(addr): return \
+
+def IN6_IS_ADDR_V4MAPPED_ANY(addr): return \
+
+def IN6_IS_ADDR_V4COMPAT(addr): return \
+
+def IN6_IS_ADDR_V4COMPAT(addr): return \
+
+def IN6_IS_ADDR_MC_RESERVED(addr): return \
+
+def IN6_IS_ADDR_MC_RESERVED(addr): return \
+
+def IN6_IS_ADDR_MC_NODELOCAL(addr): return \
+
+def IN6_IS_ADDR_MC_NODELOCAL(addr): return \
+
+def IN6_IS_ADDR_MC_LINKLOCAL(addr): return \
+
+def IN6_IS_ADDR_MC_LINKLOCAL(addr): return \
+
+def IN6_IS_ADDR_MC_SITELOCAL(addr): return \
+
+def IN6_IS_ADDR_MC_SITELOCAL(addr): return \
+
+def IN6_IS_ADDR_MC_ORGLOCAL(addr): return \
+
+def IN6_IS_ADDR_MC_ORGLOCAL(addr): return \
+
+def IN6_IS_ADDR_MC_GLOBAL(addr): return \
+
+def IN6_IS_ADDR_MC_GLOBAL(addr): return \
+
+IP_OPTIONS = 1
+IP_HDRINCL = 2
+IP_TOS = 3
+IP_TTL = 4
+IP_RECVOPTS = 5
+IP_RECVRETOPTS = 6
+IP_RECVDSTADDR = 7
+IP_RETOPTS = 8
+IP_MULTICAST_IF = 0x10
+IP_MULTICAST_TTL = 0x11
+IP_MULTICAST_LOOP = 0x12
+IP_ADD_MEMBERSHIP = 0x13
+IP_DROP_MEMBERSHIP = 0x14
+IP_SEC_OPT = 0x22
+IPSEC_PREF_NEVER = 0x01
+IPSEC_PREF_REQUIRED = 0x02
+IPSEC_PREF_UNIQUE = 0x04
+IP_ADD_PROXY_ADDR = 0x40
+IP_BOUND_IF = 0x41
+IP_UNSPEC_SRC = 0x42
+IP_REUSEADDR = 0x104
+IP_DONTROUTE = 0x105
+IP_BROADCAST = 0x106
+IP_DEFAULT_MULTICAST_TTL = 1
+IP_DEFAULT_MULTICAST_LOOP = 1
+IPV6_RTHDR_TYPE_0 = 0
+IPV6_UNICAST_HOPS = 0x5
+IPV6_MULTICAST_IF = 0x6
+IPV6_MULTICAST_HOPS = 0x7
+IPV6_MULTICAST_LOOP = 0x8
+IPV6_JOIN_GROUP = 0x9
+IPV6_LEAVE_GROUP = 0xa
+IPV6_ADD_MEMBERSHIP = 0x9
+IPV6_DROP_MEMBERSHIP = 0xa
+IPV6_PKTINFO = 0xb
+IPV6_HOPLIMIT = 0xc
+IPV6_NEXTHOP = 0xd
+IPV6_HOPOPTS = 0xe
+IPV6_DSTOPTS = 0xf
+IPV6_RTHDR = 0x10
+IPV6_RTHDRDSTOPTS = 0x11
+IPV6_RECVPKTINFO = 0x12
+IPV6_RECVHOPLIMIT = 0x13
+IPV6_RECVHOPOPTS = 0x14
+IPV6_RECVDSTOPTS = 0x15
+IPV6_RECVRTHDR = 0x16
+IPV6_RECVRTHDRDSTOPTS = 0x17
+IPV6_CHECKSUM = 0x18
+IPV6_BOUND_IF = 0x41
+IPV6_UNSPEC_SRC = 0x42
+INET_ADDRSTRLEN = 16
+INET6_ADDRSTRLEN = 46
+IPV6_PAD1_OPT = 0


Property changes on: vendor/Python/current/Lib/plat-sunos5/IN.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/plat-sunos5/STROPTS.py
===================================================================
--- vendor/Python/current/Lib/plat-sunos5/STROPTS.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-sunos5/STROPTS.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1813 @@
+# Generated by h2py from /usr/include/sys/stropts.h
+
+# Included from sys/feature_tests.h
+
+# Included from sys/isa_defs.h
+_CHAR_ALIGNMENT = 1
+_SHORT_ALIGNMENT = 2
+_INT_ALIGNMENT = 4
+_LONG_ALIGNMENT = 8
+_LONG_LONG_ALIGNMENT = 8
+_DOUBLE_ALIGNMENT = 8
+_LONG_DOUBLE_ALIGNMENT = 16
+_POINTER_ALIGNMENT = 8
+_MAX_ALIGNMENT = 16
+_ALIGNMENT_REQUIRED = 1
+_CHAR_ALIGNMENT = 1
+_SHORT_ALIGNMENT = 2
+_INT_ALIGNMENT = 4
+_LONG_ALIGNMENT = 4
+_LONG_LONG_ALIGNMENT = 4
+_DOUBLE_ALIGNMENT = 4
+_LONG_DOUBLE_ALIGNMENT = 4
+_POINTER_ALIGNMENT = 4
+_MAX_ALIGNMENT = 4
+_ALIGNMENT_REQUIRED = 0
+_CHAR_ALIGNMENT = 1
+_SHORT_ALIGNMENT = 2
+_INT_ALIGNMENT = 4
+_LONG_LONG_ALIGNMENT = 8
+_DOUBLE_ALIGNMENT = 8
+_ALIGNMENT_REQUIRED = 1
+_LONG_ALIGNMENT = 4
+_LONG_DOUBLE_ALIGNMENT = 8
+_POINTER_ALIGNMENT = 4
+_MAX_ALIGNMENT = 8
+_LONG_ALIGNMENT = 8
+_LONG_DOUBLE_ALIGNMENT = 16
+_POINTER_ALIGNMENT = 8
+_MAX_ALIGNMENT = 16
+_POSIX_C_SOURCE = 1
+_LARGEFILE64_SOURCE = 1
+_LARGEFILE_SOURCE = 1
+_FILE_OFFSET_BITS = 64
+_FILE_OFFSET_BITS = 32
+_POSIX_C_SOURCE = 199506L
+_POSIX_PTHREAD_SEMANTICS = 1
+_XOPEN_VERSION = 500
+_XOPEN_VERSION = 4
+_XOPEN_VERSION = 3
+from TYPES import *
+
+# Included from sys/conf.h
+
+# Included from sys/t_lock.h
+
+# Included from sys/machlock.h
+from TYPES import *
+LOCK_HELD_VALUE = 0xff
+def SPIN_LOCK(pl): return ((pl) > ipltospl(LOCK_LEVEL))
+
+def LOCK_SAMPLE_INTERVAL(i): return (((i) & 0xff) == 0)
+
+CLOCK_LEVEL = 10
+LOCK_LEVEL = 10
+DISP_LEVEL = (LOCK_LEVEL + 1)
+PTR24_LSB = 5
+PTR24_MSB = (PTR24_LSB + 24)
+PTR24_ALIGN = 32
+PTR24_BASE = 0xe0000000
+
+# Included from sys/param.h
+from TYPES import *
+_POSIX_VDISABLE = 0
+MAX_INPUT = 512
+MAX_CANON = 256
+UID_NOBODY = 60001
+GID_NOBODY = UID_NOBODY
+UID_NOACCESS = 60002
+MAX_TASKID = 999999
+MAX_MAXPID = 999999
+DEFAULT_MAXPID = 999999
+DEFAULT_JUMPPID = 100000
+DEFAULT_MAXPID = 30000
+DEFAULT_JUMPPID = 0
+MAXUID = 2147483647
+MAXPROJID = MAXUID
+MAXLINK = 32767
+NMOUNT = 40
+CANBSIZ = 256
+NOFILE = 20
+NGROUPS_UMIN = 0
+NGROUPS_UMAX = 32
+NGROUPS_MAX_DEFAULT = 16
+NZERO = 20
+NULL = 0L
+NULL = 0
+CMASK = 022
+CDLIMIT = (1L<<11)
+NBPS = 0x20000
+NBPSCTR = 512
+UBSIZE = 512
+SCTRSHFT = 9
+SYSNAME = 9
+PREMOTE = 39
+MAXPATHLEN = 1024
+MAXSYMLINKS = 20
+MAXNAMELEN = 256
+NADDR = 13
+PIPE_BUF = 5120
+PIPE_MAX = 5120
+NBBY = 8
+MAXBSIZE = 8192
+DEV_BSIZE = 512
+DEV_BSHIFT = 9
+MAXFRAG = 8
+MAXOFF32_T = 0x7fffffff
+MAXOFF_T = 0x7fffffffffffffffl
+MAXOFFSET_T = 0x7fffffffffffffffl
+MAXOFF_T = 0x7fffffffl
+MAXOFFSET_T = 0x7fffffff
+def btodb(bytes): return   \
+
+def dbtob(db): return   \
+
+def lbtodb(bytes): return   \
+
+def ldbtob(db): return   \
+
+NCARGS32 = 0x100000
+NCARGS64 = 0x200000
+NCARGS = NCARGS64
+NCARGS = NCARGS32
+FSHIFT = 8
+FSCALE = (1<<FSHIFT)
+def DELAY(n): return drv_usecwait(n)
+
+def mmu_ptob(x): return ((x) << MMU_PAGESHIFT)
+
+def mmu_btop(x): return (((x)) >> MMU_PAGESHIFT)
+
+def mmu_btopr(x): return ((((x) + MMU_PAGEOFFSET) >> MMU_PAGESHIFT))
+
+def mmu_ptod(x): return ((x) << (MMU_PAGESHIFT - DEV_BSHIFT))
+
+def ptod(x): return ((x) << (PAGESHIFT - DEV_BSHIFT))
+
+def ptob(x): return ((x) << PAGESHIFT)
+
+def btop(x): return (((x) >> PAGESHIFT))
+
+def btopr(x): return ((((x) + PAGEOFFSET) >> PAGESHIFT))
+
+def dtop(DD): return (((DD) + NDPP - 1) >> (PAGESHIFT - DEV_BSHIFT))
+
+def dtopt(DD): return ((DD) >> (PAGESHIFT - DEV_BSHIFT))
+
+_AIO_LISTIO_MAX = (4096)
+_AIO_MAX = (-1)
+_MQ_OPEN_MAX = (32)
+_MQ_PRIO_MAX = (32)
+_SEM_NSEMS_MAX = INT_MAX
+_SEM_VALUE_MAX = INT_MAX
+
+# Included from sys/unistd.h
+_CS_PATH = 65
+_CS_LFS_CFLAGS = 68
+_CS_LFS_LDFLAGS = 69
+_CS_LFS_LIBS = 70
+_CS_LFS_LINTFLAGS = 71
+_CS_LFS64_CFLAGS = 72
+_CS_LFS64_LDFLAGS = 73
+_CS_LFS64_LIBS = 74
+_CS_LFS64_LINTFLAGS = 75
+_CS_XBS5_ILP32_OFF32_CFLAGS = 700
+_CS_XBS5_ILP32_OFF32_LDFLAGS = 701
+_CS_XBS5_ILP32_OFF32_LIBS = 702
+_CS_XBS5_ILP32_OFF32_LINTFLAGS = 703
+_CS_XBS5_ILP32_OFFBIG_CFLAGS = 705
+_CS_XBS5_ILP32_OFFBIG_LDFLAGS = 706
+_CS_XBS5_ILP32_OFFBIG_LIBS = 707
+_CS_XBS5_ILP32_OFFBIG_LINTFLAGS = 708
+_CS_XBS5_LP64_OFF64_CFLAGS = 709
+_CS_XBS5_LP64_OFF64_LDFLAGS = 710
+_CS_XBS5_LP64_OFF64_LIBS = 711
+_CS_XBS5_LP64_OFF64_LINTFLAGS = 712
+_CS_XBS5_LPBIG_OFFBIG_CFLAGS = 713
+_CS_XBS5_LPBIG_OFFBIG_LDFLAGS = 714
+_CS_XBS5_LPBIG_OFFBIG_LIBS = 715
+_CS_XBS5_LPBIG_OFFBIG_LINTFLAGS = 716
+_SC_ARG_MAX = 1
+_SC_CHILD_MAX = 2
+_SC_CLK_TCK = 3
+_SC_NGROUPS_MAX = 4
+_SC_OPEN_MAX = 5
+_SC_JOB_CONTROL = 6
+_SC_SAVED_IDS = 7
+_SC_VERSION = 8
+_SC_PASS_MAX = 9
+_SC_LOGNAME_MAX = 10
+_SC_PAGESIZE = 11
+_SC_XOPEN_VERSION = 12
+_SC_NPROCESSORS_CONF = 14
+_SC_NPROCESSORS_ONLN = 15
+_SC_STREAM_MAX = 16
+_SC_TZNAME_MAX = 17
+_SC_AIO_LISTIO_MAX = 18
+_SC_AIO_MAX = 19
+_SC_AIO_PRIO_DELTA_MAX = 20
+_SC_ASYNCHRONOUS_IO = 21
+_SC_DELAYTIMER_MAX = 22
+_SC_FSYNC = 23
+_SC_MAPPED_FILES = 24
+_SC_MEMLOCK = 25
+_SC_MEMLOCK_RANGE = 26
+_SC_MEMORY_PROTECTION = 27
+_SC_MESSAGE_PASSING = 28
+_SC_MQ_OPEN_MAX = 29
+_SC_MQ_PRIO_MAX = 30
+_SC_PRIORITIZED_IO = 31
+_SC_PRIORITY_SCHEDULING = 32
+_SC_REALTIME_SIGNALS = 33
+_SC_RTSIG_MAX = 34
+_SC_SEMAPHORES = 35
+_SC_SEM_NSEMS_MAX = 36
+_SC_SEM_VALUE_MAX = 37
+_SC_SHARED_MEMORY_OBJECTS = 38
+_SC_SIGQUEUE_MAX = 39
+_SC_SIGRT_MIN = 40
+_SC_SIGRT_MAX = 41
+_SC_SYNCHRONIZED_IO = 42
+_SC_TIMERS = 43
+_SC_TIMER_MAX = 44
+_SC_2_C_BIND = 45
+_SC_2_C_DEV = 46
+_SC_2_C_VERSION = 47
+_SC_2_FORT_DEV = 48
+_SC_2_FORT_RUN = 49
+_SC_2_LOCALEDEF = 50
+_SC_2_SW_DEV = 51
+_SC_2_UPE = 52
+_SC_2_VERSION = 53
+_SC_BC_BASE_MAX = 54
+_SC_BC_DIM_MAX = 55
+_SC_BC_SCALE_MAX = 56
+_SC_BC_STRING_MAX = 57
+_SC_COLL_WEIGHTS_MAX = 58
+_SC_EXPR_NEST_MAX = 59
+_SC_LINE_MAX = 60
+_SC_RE_DUP_MAX = 61
+_SC_XOPEN_CRYPT = 62
+_SC_XOPEN_ENH_I18N = 63
+_SC_XOPEN_SHM = 64
+_SC_2_CHAR_TERM = 66
+_SC_XOPEN_XCU_VERSION = 67
+_SC_ATEXIT_MAX = 76
+_SC_IOV_MAX = 77
+_SC_XOPEN_UNIX = 78
+_SC_PAGE_SIZE = _SC_PAGESIZE
+_SC_T_IOV_MAX = 79
+_SC_PHYS_PAGES = 500
+_SC_AVPHYS_PAGES = 501
+_SC_COHER_BLKSZ = 503
+_SC_SPLIT_CACHE = 504
+_SC_ICACHE_SZ = 505
+_SC_DCACHE_SZ = 506
+_SC_ICACHE_LINESZ = 507
+_SC_DCACHE_LINESZ = 508
+_SC_ICACHE_BLKSZ = 509
+_SC_DCACHE_BLKSZ = 510
+_SC_DCACHE_TBLKSZ = 511
+_SC_ICACHE_ASSOC = 512
+_SC_DCACHE_ASSOC = 513
+_SC_MAXPID = 514
+_SC_STACK_PROT = 515
+_SC_THREAD_DESTRUCTOR_ITERATIONS = 568
+_SC_GETGR_R_SIZE_MAX = 569
+_SC_GETPW_R_SIZE_MAX = 570
+_SC_LOGIN_NAME_MAX = 571
+_SC_THREAD_KEYS_MAX = 572
+_SC_THREAD_STACK_MIN = 573
+_SC_THREAD_THREADS_MAX = 574
+_SC_TTY_NAME_MAX = 575
+_SC_THREADS = 576
+_SC_THREAD_ATTR_STACKADDR = 577
+_SC_THREAD_ATTR_STACKSIZE = 578
+_SC_THREAD_PRIORITY_SCHEDULING = 579
+_SC_THREAD_PRIO_INHERIT = 580
+_SC_THREAD_PRIO_PROTECT = 581
+_SC_THREAD_PROCESS_SHARED = 582
+_SC_THREAD_SAFE_FUNCTIONS = 583
+_SC_XOPEN_LEGACY = 717
+_SC_XOPEN_REALTIME = 718
+_SC_XOPEN_REALTIME_THREADS = 719
+_SC_XBS5_ILP32_OFF32 = 720
+_SC_XBS5_ILP32_OFFBIG = 721
+_SC_XBS5_LP64_OFF64 = 722
+_SC_XBS5_LPBIG_OFFBIG = 723
+_PC_LINK_MAX = 1
+_PC_MAX_CANON = 2
+_PC_MAX_INPUT = 3
+_PC_NAME_MAX = 4
+_PC_PATH_MAX = 5
+_PC_PIPE_BUF = 6
+_PC_NO_TRUNC = 7
+_PC_VDISABLE = 8
+_PC_CHOWN_RESTRICTED = 9
+_PC_ASYNC_IO = 10
+_PC_PRIO_IO = 11
+_PC_SYNC_IO = 12
+_PC_FILESIZEBITS = 67
+_PC_LAST = 67
+_POSIX_VERSION = 199506L
+_POSIX2_VERSION = 199209L
+_POSIX2_C_VERSION = 199209L
+_XOPEN_XCU_VERSION = 4
+_XOPEN_REALTIME = 1
+_XOPEN_ENH_I18N = 1
+_XOPEN_SHM = 1
+_POSIX2_C_BIND = 1
+_POSIX2_CHAR_TERM = 1
+_POSIX2_LOCALEDEF = 1
+_POSIX2_C_DEV = 1
+_POSIX2_SW_DEV = 1
+_POSIX2_UPE = 1
+
+# Included from sys/mutex.h
+from TYPES import *
+def MUTEX_HELD(x): return (mutex_owned(x))
+
+
+# Included from sys/rwlock.h
+from TYPES import *
+def RW_READ_HELD(x): return (rw_read_held((x)))
+
+def RW_WRITE_HELD(x): return (rw_write_held((x)))
+
+def RW_LOCK_HELD(x): return (rw_lock_held((x)))
+
+def RW_ISWRITER(x): return (rw_iswriter(x))
+
+
+# Included from sys/semaphore.h
+
+# Included from sys/thread.h
+from TYPES import *
+
+# Included from sys/klwp.h
+from TYPES import *
+
+# Included from sys/condvar.h
+from TYPES import *
+
+# Included from sys/time.h
+
+# Included from sys/types32.h
+
+# Included from sys/int_types.h
+TIME32_MAX = INT32_MAX
+TIME32_MIN = INT32_MIN
+def TIMEVAL_OVERFLOW(tv): return \
+
+from TYPES import *
+DST_NONE = 0
+DST_USA = 1
+DST_AUST = 2
+DST_WET = 3
+DST_MET = 4
+DST_EET = 5
+DST_CAN = 6
+DST_GB = 7
+DST_RUM = 8
+DST_TUR = 9
+DST_AUSTALT = 10
+ITIMER_REAL = 0
+ITIMER_VIRTUAL = 1
+ITIMER_PROF = 2
+ITIMER_REALPROF = 3
+def ITIMERVAL_OVERFLOW(itv): return \
+
+SEC = 1
+MILLISEC = 1000
+MICROSEC = 1000000
+NANOSEC = 1000000000
+
+# Included from sys/time_impl.h
+def TIMESPEC_OVERFLOW(ts): return \
+
+def ITIMERSPEC_OVERFLOW(it): return \
+
+__CLOCK_REALTIME0 = 0
+CLOCK_VIRTUAL = 1
+CLOCK_PROF = 2
+__CLOCK_REALTIME3 = 3
+CLOCK_HIGHRES = 4
+CLOCK_MAX = 5
+CLOCK_REALTIME = __CLOCK_REALTIME3
+CLOCK_REALTIME = __CLOCK_REALTIME0
+TIMER_RELTIME = 0x0
+TIMER_ABSTIME = 0x1
+def TICK_TO_SEC(tick): return ((tick) / hz)
+
+def SEC_TO_TICK(sec): return ((sec) * hz)
+
+def TICK_TO_MSEC(tick): return \
+
+def MSEC_TO_TICK(msec): return \
+
+def MSEC_TO_TICK_ROUNDUP(msec): return \
+
+def TICK_TO_USEC(tick): return ((tick) * usec_per_tick)
+
+def USEC_TO_TICK(usec): return ((usec) / usec_per_tick)
+
+def USEC_TO_TICK_ROUNDUP(usec): return \
+
+def TICK_TO_NSEC(tick): return ((tick) * nsec_per_tick)
+
+def NSEC_TO_TICK(nsec): return ((nsec) / nsec_per_tick)
+
+def NSEC_TO_TICK_ROUNDUP(nsec): return \
+
+def TIMEVAL_TO_TICK(tvp): return \
+
+def TIMESTRUC_TO_TICK(tsp): return \
+
+
+# Included from time.h
+from TYPES import *
+
+# Included from iso/time_iso.h
+NULL = 0L
+NULL = 0
+CLOCKS_PER_SEC = 1000000
+
+# Included from sys/select.h
+FD_SETSIZE = 65536
+FD_SETSIZE = 1024
+_NBBY = 8
+NBBY = _NBBY
+def FD_ZERO(p): return bzero((p), sizeof (*(p)))
+
+
+# Included from sys/signal.h
+
+# Included from sys/iso/signal_iso.h
+SIGHUP = 1
+SIGINT = 2
+SIGQUIT = 3
+SIGILL = 4
+SIGTRAP = 5
+SIGIOT = 6
+SIGABRT = 6
+SIGEMT = 7
+SIGFPE = 8
+SIGKILL = 9
+SIGBUS = 10
+SIGSEGV = 11
+SIGSYS = 12
+SIGPIPE = 13
+SIGALRM = 14
+SIGTERM = 15
+SIGUSR1 = 16
+SIGUSR2 = 17
+SIGCLD = 18
+SIGCHLD = 18
+SIGPWR = 19
+SIGWINCH = 20
+SIGURG = 21
+SIGPOLL = 22
+SIGIO = SIGPOLL
+SIGSTOP = 23
+SIGTSTP = 24
+SIGCONT = 25
+SIGTTIN = 26
+SIGTTOU = 27
+SIGVTALRM = 28
+SIGPROF = 29
+SIGXCPU = 30
+SIGXFSZ = 31
+SIGWAITING = 32
+SIGLWP = 33
+SIGFREEZE = 34
+SIGTHAW = 35
+SIGCANCEL = 36
+SIGLOST = 37
+_SIGRTMIN = 38
+_SIGRTMAX = 45
+SIG_BLOCK = 1
+SIG_UNBLOCK = 2
+SIG_SETMASK = 3
+SIGNO_MASK = 0xFF
+SIGDEFER = 0x100
+SIGHOLD = 0x200
+SIGRELSE = 0x400
+SIGIGNORE = 0x800
+SIGPAUSE = 0x1000
+
+# Included from sys/siginfo.h
+from TYPES import *
+SIGEV_NONE = 1
+SIGEV_SIGNAL = 2
+SIGEV_THREAD = 3
+SI_NOINFO = 32767
+SI_USER = 0
+SI_LWP = (-1)
+SI_QUEUE = (-2)
+SI_TIMER = (-3)
+SI_ASYNCIO = (-4)
+SI_MESGQ = (-5)
+
+# Included from sys/machsig.h
+ILL_ILLOPC = 1
+ILL_ILLOPN = 2
+ILL_ILLADR = 3
+ILL_ILLTRP = 4
+ILL_PRVOPC = 5
+ILL_PRVREG = 6
+ILL_COPROC = 7
+ILL_BADSTK = 8
+NSIGILL = 8
+EMT_TAGOVF = 1
+EMT_CPCOVF = 2
+NSIGEMT = 2
+FPE_INTDIV = 1
+FPE_INTOVF = 2
+FPE_FLTDIV = 3
+FPE_FLTOVF = 4
+FPE_FLTUND = 5
+FPE_FLTRES = 6
+FPE_FLTINV = 7
+FPE_FLTSUB = 8
+NSIGFPE = 8
+SEGV_MAPERR = 1
+SEGV_ACCERR = 2
+NSIGSEGV = 2
+BUS_ADRALN = 1
+BUS_ADRERR = 2
+BUS_OBJERR = 3
+NSIGBUS = 3
+TRAP_BRKPT = 1
+TRAP_TRACE = 2
+TRAP_RWATCH = 3
+TRAP_WWATCH = 4
+TRAP_XWATCH = 5
+NSIGTRAP = 5
+CLD_EXITED = 1
+CLD_KILLED = 2
+CLD_DUMPED = 3
+CLD_TRAPPED = 4
+CLD_STOPPED = 5
+CLD_CONTINUED = 6
+NSIGCLD = 6
+POLL_IN = 1
+POLL_OUT = 2
+POLL_MSG = 3
+POLL_ERR = 4
+POLL_PRI = 5
+POLL_HUP = 6
+NSIGPOLL = 6
+PROF_SIG = 1
+NSIGPROF = 1
+SI_MAXSZ = 256
+SI_MAXSZ = 128
+
+# Included from sys/time_std_impl.h
+from TYPES import *
+SI32_MAXSZ = 128
+def SI_CANQUEUE(c): return ((c) <= SI_QUEUE)
+
+SA_NOCLDSTOP = 0x00020000
+SA_ONSTACK = 0x00000001
+SA_RESETHAND = 0x00000002
+SA_RESTART = 0x00000004
+SA_SIGINFO = 0x00000008
+SA_NODEFER = 0x00000010
+SA_NOCLDWAIT = 0x00010000
+SA_WAITSIG = 0x00010000
+NSIG = 46
+MAXSIG = 45
+S_SIGNAL = 1
+S_SIGSET = 2
+S_SIGACTION = 3
+S_NONE = 4
+MINSIGSTKSZ = 2048
+SIGSTKSZ = 8192
+SS_ONSTACK = 0x00000001
+SS_DISABLE = 0x00000002
+SN_PROC = 1
+SN_CANCEL = 2
+SN_SEND = 3
+
+# Included from sys/ucontext.h
+from TYPES import *
+
+# Included from sys/regset.h
+REG_CCR = (0)
+REG_PSR = (0)
+REG_PSR = (0)
+REG_PC = (1)
+REG_nPC = (2)
+REG_Y = (3)
+REG_G1 = (4)
+REG_G2 = (5)
+REG_G3 = (6)
+REG_G4 = (7)
+REG_G5 = (8)
+REG_G6 = (9)
+REG_G7 = (10)
+REG_O0 = (11)
+REG_O1 = (12)
+REG_O2 = (13)
+REG_O3 = (14)
+REG_O4 = (15)
+REG_O5 = (16)
+REG_O6 = (17)
+REG_O7 = (18)
+REG_ASI = (19)
+REG_FPRS = (20)
+REG_PS = REG_PSR
+REG_SP = REG_O6
+REG_R0 = REG_O0
+REG_R1 = REG_O1
+_NGREG = 21
+_NGREG = 19
+NGREG = _NGREG
+_NGREG32 = 19
+_NGREG64 = 21
+SPARC_MAXREGWINDOW = 31
+MAXFPQ = 16
+XRS_ID = 0x78727300
+
+# Included from v7/sys/privregs.h
+
+# Included from v7/sys/psr.h
+PSR_CWP = 0x0000001F
+PSR_ET = 0x00000020
+PSR_PS = 0x00000040
+PSR_S = 0x00000080
+PSR_PIL = 0x00000F00
+PSR_EF = 0x00001000
+PSR_EC = 0x00002000
+PSR_RSV = 0x000FC000
+PSR_ICC = 0x00F00000
+PSR_C = 0x00100000
+PSR_V = 0x00200000
+PSR_Z = 0x00400000
+PSR_N = 0x00800000
+PSR_VER = 0x0F000000
+PSR_IMPL = 0xF0000000
+PSL_ALLCC = PSR_ICC
+PSL_USER = (PSR_S)
+PSL_USERMASK = (PSR_ICC)
+PSL_UBITS = (PSR_ICC|PSR_EF)
+def USERMODE(ps): return (((ps) & PSR_PS) == 0)
+
+
+# Included from sys/fsr.h
+FSR_CEXC = 0x0000001f
+FSR_AEXC = 0x000003e0
+FSR_FCC = 0x00000c00
+FSR_PR = 0x00001000
+FSR_QNE = 0x00002000
+FSR_FTT = 0x0001c000
+FSR_VER = 0x000e0000
+FSR_TEM = 0x0f800000
+FSR_RP = 0x30000000
+FSR_RD = 0xc0000000
+FSR_VER_SHIFT = 17
+FSR_FCC1 = 0x00000003
+FSR_FCC2 = 0x0000000C
+FSR_FCC3 = 0x00000030
+FSR_CEXC_NX = 0x00000001
+FSR_CEXC_DZ = 0x00000002
+FSR_CEXC_UF = 0x00000004
+FSR_CEXC_OF = 0x00000008
+FSR_CEXC_NV = 0x00000010
+FSR_AEXC_NX = (0x1 << 5)
+FSR_AEXC_DZ = (0x2 << 5)
+FSR_AEXC_UF = (0x4 << 5)
+FSR_AEXC_OF = (0x8 << 5)
+FSR_AEXC_NV = (0x10 << 5)
+FTT_NONE = 0
+FTT_IEEE = 1
+FTT_UNFIN = 2
+FTT_UNIMP = 3
+FTT_SEQ = 4
+FTT_ALIGN = 5
+FTT_DFAULT = 6
+FSR_FTT_SHIFT = 14
+FSR_FTT_IEEE = (FTT_IEEE   << FSR_FTT_SHIFT)
+FSR_FTT_UNFIN = (FTT_UNFIN  << FSR_FTT_SHIFT)
+FSR_FTT_UNIMP = (FTT_UNIMP  << FSR_FTT_SHIFT)
+FSR_FTT_SEQ = (FTT_SEQ    << FSR_FTT_SHIFT)
+FSR_FTT_ALIGN = (FTT_ALIGN  << FSR_FTT_SHIFT)
+FSR_FTT_DFAULT = (FTT_DFAULT << FSR_FTT_SHIFT)
+FSR_TEM_NX = (0x1 << 23)
+FSR_TEM_DZ = (0x2 << 23)
+FSR_TEM_UF = (0x4 << 23)
+FSR_TEM_OF = (0x8 << 23)
+FSR_TEM_NV = (0x10 << 23)
+RP_DBLEXT = 0
+RP_SINGLE = 1
+RP_DOUBLE = 2
+RP_RESERVED = 3
+RD_NEAR = 0
+RD_ZER0 = 1
+RD_POSINF = 2
+RD_NEGINF = 3
+FPRS_DL = 0x1
+FPRS_DU = 0x2
+FPRS_FEF = 0x4
+PIL_MAX = 0xf
+def SAVE_GLOBALS(RP): return \
+
+def RESTORE_GLOBALS(RP): return \
+
+def SAVE_OUTS(RP): return \
+
+def RESTORE_OUTS(RP): return \
+
+def SAVE_WINDOW(SBP): return \
+
+def RESTORE_WINDOW(SBP): return \
+
+def STORE_FPREGS(FP): return \
+
+def LOAD_FPREGS(FP): return \
+
+_SPARC_MAXREGWINDOW = 31
+_XRS_ID = 0x78727300
+GETCONTEXT = 0
+SETCONTEXT = 1
+UC_SIGMASK = 001
+UC_STACK = 002
+UC_CPU = 004
+UC_MAU = 010
+UC_FPU = UC_MAU
+UC_INTR = 020
+UC_ASR = 040
+UC_MCONTEXT = (UC_CPU|UC_FPU|UC_ASR)
+UC_ALL = (UC_SIGMASK|UC_STACK|UC_MCONTEXT)
+_SIGQUEUE_MAX = 32
+_SIGNOTIFY_MAX = 32
+
+# Included from sys/pcb.h
+INSTR_VALID = 0x02
+NORMAL_STEP = 0x04
+WATCH_STEP = 0x08
+CPC_OVERFLOW = 0x10
+ASYNC_HWERR = 0x20
+STEP_NONE = 0
+STEP_REQUESTED = 1
+STEP_ACTIVE = 2
+STEP_WASACTIVE = 3
+
+# Included from sys/msacct.h
+LMS_USER = 0
+LMS_SYSTEM = 1
+LMS_TRAP = 2
+LMS_TFAULT = 3
+LMS_DFAULT = 4
+LMS_KFAULT = 5
+LMS_USER_LOCK = 6
+LMS_SLEEP = 7
+LMS_WAIT_CPU = 8
+LMS_STOPPED = 9
+NMSTATES = 10
+
+# Included from sys/lwp.h
+
+# Included from sys/synch.h
+from TYPES import *
+USYNC_THREAD = 0x00
+USYNC_PROCESS = 0x01
+LOCK_NORMAL = 0x00
+LOCK_ERRORCHECK = 0x02
+LOCK_RECURSIVE = 0x04
+USYNC_PROCESS_ROBUST = 0x08
+LOCK_PRIO_NONE = 0x00
+LOCK_PRIO_INHERIT = 0x10
+LOCK_PRIO_PROTECT = 0x20
+LOCK_STALL_NP = 0x00
+LOCK_ROBUST_NP = 0x40
+LOCK_OWNERDEAD = 0x1
+LOCK_NOTRECOVERABLE = 0x2
+LOCK_INITED = 0x4
+LOCK_UNMAPPED = 0x8
+LWP_DETACHED = 0x00000040
+LWP_SUSPENDED = 0x00000080
+__LWP_ASLWP = 0x00000100
+MAXSYSARGS = 8
+NORMALRETURN = 0
+JUSTRETURN = 1
+LWP_USER = 0x01
+LWP_SYS = 0x02
+TS_FREE = 0x00
+TS_SLEEP = 0x01
+TS_RUN = 0x02
+TS_ONPROC = 0x04
+TS_ZOMB = 0x08
+TS_STOPPED = 0x10
+T_INTR_THREAD = 0x0001
+T_WAKEABLE = 0x0002
+T_TOMASK = 0x0004
+T_TALLOCSTK = 0x0008
+T_WOULDBLOCK = 0x0020
+T_DONTBLOCK = 0x0040
+T_DONTPEND = 0x0080
+T_SYS_PROF = 0x0100
+T_WAITCVSEM = 0x0200
+T_WATCHPT = 0x0400
+T_PANIC = 0x0800
+TP_HOLDLWP = 0x0002
+TP_TWAIT = 0x0004
+TP_LWPEXIT = 0x0008
+TP_PRSTOP = 0x0010
+TP_CHKPT = 0x0020
+TP_EXITLWP = 0x0040
+TP_PRVSTOP = 0x0080
+TP_MSACCT = 0x0100
+TP_STOPPING = 0x0200
+TP_WATCHPT = 0x0400
+TP_PAUSE = 0x0800
+TP_CHANGEBIND = 0x1000
+TS_LOAD = 0x0001
+TS_DONT_SWAP = 0x0002
+TS_SWAPENQ = 0x0004
+TS_ON_SWAPQ = 0x0008
+TS_CSTART = 0x0100
+TS_UNPAUSE = 0x0200
+TS_XSTART = 0x0400
+TS_PSTART = 0x0800
+TS_RESUME = 0x1000
+TS_CREATE = 0x2000
+TS_ALLSTART = \
+        (TS_CSTART|TS_UNPAUSE|TS_XSTART|TS_PSTART|TS_RESUME|TS_CREATE)
+def CPR_VSTOPPED(t): return \
+
+def THREAD_TRANSITION(tp): return thread_transition(tp);
+
+def THREAD_STOP(tp): return \
+
+def THREAD_ZOMB(tp): return THREAD_SET_STATE(tp, TS_ZOMB, NULL)
+
+def SEMA_HELD(x): return (sema_held((x)))
+
+NO_LOCKS_HELD = 1
+NO_COMPETING_THREADS = 1
+FMNAMESZ = 8
+
+# Included from sys/systm.h
+from TYPES import *
+
+# Included from sys/proc.h
+
+# Included from sys/cred.h
+
+# Included from sys/user.h
+from TYPES import *
+
+# Included from sys/resource.h
+from TYPES import *
+PRIO_PROCESS = 0
+PRIO_PGRP = 1
+PRIO_USER = 2
+RLIMIT_CPU = 0
+RLIMIT_FSIZE = 1
+RLIMIT_DATA = 2
+RLIMIT_STACK = 3
+RLIMIT_CORE = 4
+RLIMIT_NOFILE = 5
+RLIMIT_VMEM = 6
+RLIMIT_AS = RLIMIT_VMEM
+RLIM_NLIMITS = 7
+RLIM_INFINITY = (-3l)
+RLIM_SAVED_MAX = (-2l)
+RLIM_SAVED_CUR = (-1l)
+RLIM_INFINITY = 0x7fffffff
+RLIM_SAVED_MAX = 0x7ffffffe
+RLIM_SAVED_CUR = 0x7ffffffd
+RLIM32_INFINITY = 0x7fffffff
+RLIM32_SAVED_MAX = 0x7ffffffe
+RLIM32_SAVED_CUR = 0x7ffffffd
+
+# Included from sys/model.h
+
+# Included from sys/debug.h
+def ASSERT64(x): return ASSERT(x)
+
+def ASSERT32(x): return ASSERT(x)
+
+DATAMODEL_MASK = 0x0FF00000
+DATAMODEL_ILP32 = 0x00100000
+DATAMODEL_LP64 = 0x00200000
+DATAMODEL_NONE = 0
+DATAMODEL_NATIVE = DATAMODEL_LP64
+DATAMODEL_NATIVE = DATAMODEL_ILP32
+def STRUCT_SIZE(handle): return \
+
+def STRUCT_BUF(handle): return ((handle).ptr.m64)
+
+def SIZEOF_PTR(umodel): return \
+
+def STRUCT_SIZE(handle): return (sizeof (*(handle).ptr))
+
+def STRUCT_BUF(handle): return ((handle).ptr)
+
+def SIZEOF_PTR(umodel): return sizeof (caddr_t)
+
+def lwp_getdatamodel(t): return DATAMODEL_ILP32
+
+RUSAGE_SELF = 0
+RUSAGE_CHILDREN = -1
+
+# Included from sys/auxv.h
+AT_NULL = 0
+AT_IGNORE = 1
+AT_EXECFD = 2
+AT_PHDR = 3
+AT_PHENT = 4
+AT_PHNUM = 5
+AT_PAGESZ = 6
+AT_BASE = 7
+AT_FLAGS = 8
+AT_ENTRY = 9
+AT_DCACHEBSIZE = 10
+AT_ICACHEBSIZE = 11
+AT_UCACHEBSIZE = 12
+AT_SUN_UID = 2000
+AT_SUN_RUID = 2001
+AT_SUN_GID = 2002
+AT_SUN_RGID = 2003
+AT_SUN_LDELF = 2004
+AT_SUN_LDSHDR = 2005
+AT_SUN_LDNAME = 2006
+AT_SUN_LPAGESZ = 2007
+AT_SUN_PLATFORM = 2008
+AT_SUN_HWCAP = 2009
+AT_SUN_IFLUSH = 2010
+AT_SUN_CPU = 2011
+AT_SUN_EMUL_ENTRY = 2012
+AT_SUN_EMUL_EXECFD = 2013
+AT_SUN_EXECNAME = 2014
+AT_SUN_MMU = 2015
+
+# Included from sys/errno.h
+EPERM = 1
+ENOENT = 2
+ESRCH = 3
+EINTR = 4
+EIO = 5
+ENXIO = 6
+E2BIG = 7
+ENOEXEC = 8
+EBADF = 9
+ECHILD = 10
+EAGAIN = 11
+ENOMEM = 12
+EACCES = 13
+EFAULT = 14
+ENOTBLK = 15
+EBUSY = 16
+EEXIST = 17
+EXDEV = 18
+ENODEV = 19
+ENOTDIR = 20
+EISDIR = 21
+EINVAL = 22
+ENFILE = 23
+EMFILE = 24
+ENOTTY = 25
+ETXTBSY = 26
+EFBIG = 27
+ENOSPC = 28
+ESPIPE = 29
+EROFS = 30
+EMLINK = 31
+EPIPE = 32
+EDOM = 33
+ERANGE = 34
+ENOMSG = 35
+EIDRM = 36
+ECHRNG = 37
+EL2NSYNC = 38
+EL3HLT = 39
+EL3RST = 40
+ELNRNG = 41
+EUNATCH = 42
+ENOCSI = 43
+EL2HLT = 44
+EDEADLK = 45
+ENOLCK = 46
+ECANCELED = 47
+ENOTSUP = 48
+EDQUOT = 49
+EBADE = 50
+EBADR = 51
+EXFULL = 52
+ENOANO = 53
+EBADRQC = 54
+EBADSLT = 55
+EDEADLOCK = 56
+EBFONT = 57
+EOWNERDEAD = 58
+ENOTRECOVERABLE = 59
+ENOSTR = 60
+ENODATA = 61
+ETIME = 62
+ENOSR = 63
+ENONET = 64
+ENOPKG = 65
+EREMOTE = 66
+ENOLINK = 67
+EADV = 68
+ESRMNT = 69
+ECOMM = 70
+EPROTO = 71
+ELOCKUNMAPPED = 72
+ENOTACTIVE = 73
+EMULTIHOP = 74
+EBADMSG = 77
+ENAMETOOLONG = 78
+EOVERFLOW = 79
+ENOTUNIQ = 80
+EBADFD = 81
+EREMCHG = 82
+ELIBACC = 83
+ELIBBAD = 84
+ELIBSCN = 85
+ELIBMAX = 86
+ELIBEXEC = 87
+EILSEQ = 88
+ENOSYS = 89
+ELOOP = 90
+ERESTART = 91
+ESTRPIPE = 92
+ENOTEMPTY = 93
+EUSERS = 94
+ENOTSOCK = 95
+EDESTADDRREQ = 96
+EMSGSIZE = 97
+EPROTOTYPE = 98
+ENOPROTOOPT = 99
+EPROTONOSUPPORT = 120
+ESOCKTNOSUPPORT = 121
+EOPNOTSUPP = 122
+EPFNOSUPPORT = 123
+EAFNOSUPPORT = 124
+EADDRINUSE = 125
+EADDRNOTAVAIL = 126
+ENETDOWN = 127
+ENETUNREACH = 128
+ENETRESET = 129
+ECONNABORTED = 130
+ECONNRESET = 131
+ENOBUFS = 132
+EISCONN = 133
+ENOTCONN = 134
+ESHUTDOWN = 143
+ETOOMANYREFS = 144
+ETIMEDOUT = 145
+ECONNREFUSED = 146
+EHOSTDOWN = 147
+EHOSTUNREACH = 148
+EWOULDBLOCK = EAGAIN
+EALREADY = 149
+EINPROGRESS = 150
+ESTALE = 151
+PSARGSZ = 80
+PSCOMSIZ = 14
+MAXCOMLEN = 16
+__KERN_NAUXV_IMPL = 19
+__KERN_NAUXV_IMPL = 21
+__KERN_NAUXV_IMPL = 21
+PSARGSZ = 80
+
+# Included from sys/watchpoint.h
+from TYPES import *
+
+# Included from vm/seg_enum.h
+
+# Included from sys/copyops.h
+from TYPES import *
+
+# Included from sys/buf.h
+
+# Included from sys/kstat.h
+from TYPES import *
+KSTAT_STRLEN = 31
+def KSTAT_ENTER(k): return \
+
+def KSTAT_EXIT(k): return \
+
+KSTAT_TYPE_RAW = 0
+KSTAT_TYPE_NAMED = 1
+KSTAT_TYPE_INTR = 2
+KSTAT_TYPE_IO = 3
+KSTAT_TYPE_TIMER = 4
+KSTAT_NUM_TYPES = 5
+KSTAT_FLAG_VIRTUAL = 0x01
+KSTAT_FLAG_VAR_SIZE = 0x02
+KSTAT_FLAG_WRITABLE = 0x04
+KSTAT_FLAG_PERSISTENT = 0x08
+KSTAT_FLAG_DORMANT = 0x10
+KSTAT_FLAG_INVALID = 0x20
+KSTAT_READ = 0
+KSTAT_WRITE = 1
+KSTAT_DATA_CHAR = 0
+KSTAT_DATA_INT32 = 1
+KSTAT_DATA_UINT32 = 2
+KSTAT_DATA_INT64 = 3
+KSTAT_DATA_UINT64 = 4
+KSTAT_DATA_LONG = KSTAT_DATA_INT32
+KSTAT_DATA_ULONG = KSTAT_DATA_UINT32
+KSTAT_DATA_LONG = KSTAT_DATA_INT64
+KSTAT_DATA_ULONG = KSTAT_DATA_UINT64
+KSTAT_DATA_LONG = 7
+KSTAT_DATA_ULONG = 8
+KSTAT_DATA_LONGLONG = KSTAT_DATA_INT64
+KSTAT_DATA_ULONGLONG = KSTAT_DATA_UINT64
+KSTAT_DATA_FLOAT = 5
+KSTAT_DATA_DOUBLE = 6
+KSTAT_INTR_HARD = 0
+KSTAT_INTR_SOFT = 1
+KSTAT_INTR_WATCHDOG = 2
+KSTAT_INTR_SPURIOUS = 3
+KSTAT_INTR_MULTSVC = 4
+KSTAT_NUM_INTRS = 5
+B_BUSY = 0x0001
+B_DONE = 0x0002
+B_ERROR = 0x0004
+B_PAGEIO = 0x0010
+B_PHYS = 0x0020
+B_READ = 0x0040
+B_WRITE = 0x0100
+B_KERNBUF = 0x0008
+B_WANTED = 0x0080
+B_AGE = 0x000200
+B_ASYNC = 0x000400
+B_DELWRI = 0x000800
+B_STALE = 0x001000
+B_DONTNEED = 0x002000
+B_REMAPPED = 0x004000
+B_FREE = 0x008000
+B_INVAL = 0x010000
+B_FORCE = 0x020000
+B_HEAD = 0x040000
+B_NOCACHE = 0x080000
+B_TRUNC = 0x100000
+B_SHADOW = 0x200000
+B_RETRYWRI = 0x400000
+def notavail(bp): return \
+
+def BWRITE(bp): return \
+
+def BWRITE2(bp): return \
+
+
+# Included from sys/aio_req.h
+
+# Included from sys/uio.h
+from TYPES import *
+WP_NOWATCH = 0x01
+WP_SETPROT = 0x02
+
+# Included from sys/timer.h
+from TYPES import *
+_TIMER_MAX = 32
+ITLK_LOCKED = 0x01
+ITLK_WANTED = 0x02
+ITLK_REMOVE = 0x04
+IT_PERLWP = 0x01
+IT_SIGNAL = 0x02
+
+# Included from sys/utrap.h
+UT_INSTRUCTION_DISABLED = 1
+UT_INSTRUCTION_ERROR = 2
+UT_INSTRUCTION_PROTECTION = 3
+UT_ILLTRAP_INSTRUCTION = 4
+UT_ILLEGAL_INSTRUCTION = 5
+UT_PRIVILEGED_OPCODE = 6
+UT_FP_DISABLED = 7
+UT_FP_EXCEPTION_IEEE_754 = 8
+UT_FP_EXCEPTION_OTHER = 9
+UT_TAG_OVERFLOW = 10
+UT_DIVISION_BY_ZERO = 11
+UT_DATA_EXCEPTION = 12
+UT_DATA_ERROR = 13
+UT_DATA_PROTECTION = 14
+UT_MEM_ADDRESS_NOT_ALIGNED = 15
+UT_PRIVILEGED_ACTION = 16
+UT_ASYNC_DATA_ERROR = 17
+UT_TRAP_INSTRUCTION_16 = 18
+UT_TRAP_INSTRUCTION_17 = 19
+UT_TRAP_INSTRUCTION_18 = 20
+UT_TRAP_INSTRUCTION_19 = 21
+UT_TRAP_INSTRUCTION_20 = 22
+UT_TRAP_INSTRUCTION_21 = 23
+UT_TRAP_INSTRUCTION_22 = 24
+UT_TRAP_INSTRUCTION_23 = 25
+UT_TRAP_INSTRUCTION_24 = 26
+UT_TRAP_INSTRUCTION_25 = 27
+UT_TRAP_INSTRUCTION_26 = 28
+UT_TRAP_INSTRUCTION_27 = 29
+UT_TRAP_INSTRUCTION_28 = 30
+UT_TRAP_INSTRUCTION_29 = 31
+UT_TRAP_INSTRUCTION_30 = 32
+UT_TRAP_INSTRUCTION_31 = 33
+UTRAP_V8P_FP_DISABLED = UT_FP_DISABLED
+UTRAP_V8P_MEM_ADDRESS_NOT_ALIGNED = UT_MEM_ADDRESS_NOT_ALIGNED
+UT_PRECISE_MAXTRAPS = 33
+
+# Included from sys/refstr.h
+
+# Included from sys/task.h
+from TYPES import *
+TASK_NORMAL = 0x0
+TASK_FINAL = 0x1
+TASK_FINALITY = 0x1
+
+# Included from sys/id_space.h
+from TYPES import *
+
+# Included from sys/vmem.h
+from TYPES import *
+VM_SLEEP = 0x00000000
+VM_NOSLEEP = 0x00000001
+VM_PANIC = 0x00000002
+VM_KMFLAGS = 0x000000ff
+VM_BESTFIT = 0x00000100
+VMEM_ALLOC = 0x01
+VMEM_FREE = 0x02
+VMEM_SPAN = 0x10
+ISP_NORMAL = 0x0
+ISP_RESERVE = 0x1
+
+# Included from sys/exacct_impl.h
+from TYPES import *
+
+# Included from sys/kmem.h
+from TYPES import *
+KM_SLEEP = 0x0000
+KM_NOSLEEP = 0x0001
+KM_PANIC = 0x0002
+KM_VMFLAGS = 0x00ff
+KM_FLAGS = 0xffff
+KMC_NOTOUCH = 0x00010000
+KMC_NODEBUG = 0x00020000
+KMC_NOMAGAZINE = 0x00040000
+KMC_NOHASH = 0x00080000
+KMC_QCACHE = 0x00100000
+_ISA_IA32 = 0
+_ISA_IA64 = 1
+SSLEEP = 1
+SRUN = 2
+SZOMB = 3
+SSTOP = 4
+SIDL = 5
+SONPROC = 6
+CLDPEND = 0x0001
+CLDCONT = 0x0002
+SSYS = 0x00000001
+STRC = 0x00000002
+SLOAD = 0x00000008
+SLOCK = 0x00000010
+SPREXEC = 0x00000020
+SPROCTR = 0x00000040
+SPRFORK = 0x00000080
+SKILLED = 0x00000100
+SULOAD = 0x00000200
+SRUNLCL = 0x00000400
+SBPTADJ = 0x00000800
+SKILLCL = 0x00001000
+SOWEUPC = 0x00002000
+SEXECED = 0x00004000
+SPASYNC = 0x00008000
+SJCTL = 0x00010000
+SNOWAIT = 0x00020000
+SVFORK = 0x00040000
+SVFWAIT = 0x00080000
+EXITLWPS = 0x00100000
+HOLDFORK = 0x00200000
+SWAITSIG = 0x00400000
+HOLDFORK1 = 0x00800000
+COREDUMP = 0x01000000
+SMSACCT = 0x02000000
+ASLWP = 0x04000000
+SPRLOCK = 0x08000000
+NOCD = 0x10000000
+HOLDWATCH = 0x20000000
+SMSFORK = 0x40000000
+SDOCORE = 0x80000000
+FORREAL = 0
+JUSTLOOKING = 1
+SUSPEND_NORMAL = 0
+SUSPEND_PAUSE = 1
+NOCLASS = (-1)
+
+# Included from sys/dditypes.h
+DDI_DEVICE_ATTR_V0 = 0x0001
+DDI_NEVERSWAP_ACC = 0x00
+DDI_STRUCTURE_LE_ACC = 0x01
+DDI_STRUCTURE_BE_ACC = 0x02
+DDI_STRICTORDER_ACC = 0x00
+DDI_UNORDERED_OK_ACC = 0x01
+DDI_MERGING_OK_ACC = 0x02
+DDI_LOADCACHING_OK_ACC = 0x03
+DDI_STORECACHING_OK_ACC = 0x04
+DDI_DATA_SZ01_ACC = 1
+DDI_DATA_SZ02_ACC = 2
+DDI_DATA_SZ04_ACC = 4
+DDI_DATA_SZ08_ACC = 8
+VERS_ACCHDL = 0x0001
+DEVID_NONE = 0
+DEVID_SCSI3_WWN = 1
+DEVID_SCSI_SERIAL = 2
+DEVID_FAB = 3
+DEVID_ENCAP = 4
+DEVID_MAXTYPE = 4
+
+# Included from sys/varargs.h
+
+# Included from sys/va_list.h
+VA_ALIGN = 8
+def _ARGSIZEOF(t): return ((sizeof (t) + VA_ALIGN - 1) & ~(VA_ALIGN - 1))
+
+VA_ALIGN = 8
+def _ARGSIZEOF(t): return ((sizeof (t) + VA_ALIGN - 1) & ~(VA_ALIGN - 1))
+
+NSYSCALL = 256
+SE_32RVAL1 = 0x0
+SE_32RVAL2 = 0x1
+SE_64RVAL = 0x2
+SE_RVAL_MASK = 0x3
+SE_LOADABLE = 0x08
+SE_LOADED = 0x10
+SE_NOUNLOAD = 0x20
+SE_ARGC = 0x40
+
+# Included from sys/devops.h
+from TYPES import *
+
+# Included from sys/poll.h
+POLLIN = 0x0001
+POLLPRI = 0x0002
+POLLOUT = 0x0004
+POLLRDNORM = 0x0040
+POLLWRNORM = POLLOUT
+POLLRDBAND = 0x0080
+POLLWRBAND = 0x0100
+POLLNORM = POLLRDNORM
+POLLERR = 0x0008
+POLLHUP = 0x0010
+POLLNVAL = 0x0020
+POLLREMOVE = 0x0800
+POLLRDDATA = 0x0200
+POLLNOERR = 0x0400
+POLLCLOSED = 0x8000
+
+# Included from vm/as.h
+
+# Included from vm/seg.h
+
+# Included from sys/vnode.h
+from TYPES import *
+VROOT = 0x01
+VNOCACHE = 0x02
+VNOMAP = 0x04
+VDUP = 0x08
+VNOSWAP = 0x10
+VNOMOUNT = 0x20
+VISSWAP = 0x40
+VSWAPLIKE = 0x80
+VVFSLOCK = 0x100
+VVFSWAIT = 0x200
+VVMLOCK = 0x400
+VDIROPEN = 0x800
+VVMEXEC = 0x1000
+VPXFS = 0x2000
+AT_TYPE = 0x0001
+AT_MODE = 0x0002
+AT_UID = 0x0004
+AT_GID = 0x0008
+AT_FSID = 0x0010
+AT_NODEID = 0x0020
+AT_NLINK = 0x0040
+AT_SIZE = 0x0080
+AT_ATIME = 0x0100
+AT_MTIME = 0x0200
+AT_CTIME = 0x0400
+AT_RDEV = 0x0800
+AT_BLKSIZE = 0x1000
+AT_NBLOCKS = 0x2000
+AT_VCODE = 0x4000
+AT_ALL = (AT_TYPE|AT_MODE|AT_UID|AT_GID|AT_FSID|AT_NODEID|\
+                        AT_NLINK|AT_SIZE|AT_ATIME|AT_MTIME|AT_CTIME|\
+                        AT_RDEV|AT_BLKSIZE|AT_NBLOCKS|AT_VCODE)
+AT_STAT = (AT_MODE|AT_UID|AT_GID|AT_FSID|AT_NODEID|AT_NLINK|\
+                        AT_SIZE|AT_ATIME|AT_MTIME|AT_CTIME|AT_RDEV)
+AT_TIMES = (AT_ATIME|AT_MTIME|AT_CTIME)
+AT_NOSET = (AT_NLINK|AT_RDEV|AT_FSID|AT_NODEID|AT_TYPE|\
+                        AT_BLKSIZE|AT_NBLOCKS|AT_VCODE)
+VSUID = 04000
+VSGID = 02000
+VSVTX = 01000
+VREAD = 00400
+VWRITE = 00200
+VEXEC = 00100
+MODEMASK = 07777
+PERMMASK = 00777
+def MANDMODE(mode): return (((mode) & (VSGID|(VEXEC>>3))) == VSGID)
+
+VSA_ACL = 0x0001
+VSA_ACLCNT = 0x0002
+VSA_DFACL = 0x0004
+VSA_DFACLCNT = 0x0008
+LOOKUP_DIR = 0x01
+DUMP_ALLOC = 0
+DUMP_FREE = 1
+DUMP_SCAN = 2
+ATTR_UTIME = 0x01
+ATTR_EXEC = 0x02
+ATTR_COMM = 0x04
+ATTR_HINT = 0x08
+ATTR_REAL = 0x10
+
+# Included from vm/faultcode.h
+FC_HWERR = 0x1
+FC_ALIGN = 0x2
+FC_OBJERR = 0x3
+FC_PROT = 0x4
+FC_NOMAP = 0x5
+FC_NOSUPPORT = 0x6
+def FC_MAKE_ERR(e): return (((e) << 8) | FC_OBJERR)
+
+def FC_CODE(fc): return ((fc) & 0xff)
+
+def FC_ERRNO(fc): return ((unsigned)(fc) >> 8)
+
+
+# Included from vm/hat.h
+from TYPES import *
+
+# Included from vm/page.h
+PAGE_HASHAVELEN = 4
+PAGE_HASHVPSHIFT = 6
+PG_EXCL = 0x0001
+PG_WAIT = 0x0002
+PG_PHYSCONTIG = 0x0004
+PG_MATCH_COLOR = 0x0008
+PG_NORELOC = 0x0010
+PG_FREE_LIST = 1
+PG_CACHE_LIST = 2
+PG_LIST_TAIL = 0
+PG_LIST_HEAD = 1
+def page_next_raw(PP): return page_nextn_raw((PP), 1)
+
+PAGE_IO_INUSE = 0x1
+PAGE_IO_WANTED = 0x2
+PGREL_NOTREL = 0x1
+PGREL_CLEAN = 0x2
+PGREL_MOD = 0x3
+P_FREE = 0x80
+P_NORELOC = 0x40
+def PP_SETAGED(pp): return ASSERT(PP_ISAGED(pp))
+
+HAT_FLAGS_RESV = 0xFF000000
+HAT_LOAD = 0x00
+HAT_LOAD_LOCK = 0x01
+HAT_LOAD_ADV = 0x04
+HAT_LOAD_CONTIG = 0x10
+HAT_LOAD_NOCONSIST = 0x20
+HAT_LOAD_SHARE = 0x40
+HAT_LOAD_REMAP = 0x80
+HAT_RELOAD_SHARE = 0x100
+HAT_PLAT_ATTR_MASK = 0xF00000
+HAT_PROT_MASK = 0x0F
+HAT_NOFAULT = 0x10
+HAT_NOSYNC = 0x20
+HAT_STRICTORDER = 0x0000
+HAT_UNORDERED_OK = 0x0100
+HAT_MERGING_OK = 0x0200
+HAT_LOADCACHING_OK = 0x0300
+HAT_STORECACHING_OK = 0x0400
+HAT_ORDER_MASK = 0x0700
+HAT_NEVERSWAP = 0x0000
+HAT_STRUCTURE_BE = 0x1000
+HAT_STRUCTURE_LE = 0x2000
+HAT_ENDIAN_MASK = 0x3000
+HAT_COW = 0x0001
+HAT_UNLOAD = 0x00
+HAT_UNLOAD_NOSYNC = 0x02
+HAT_UNLOAD_UNLOCK = 0x04
+HAT_UNLOAD_OTHER = 0x08
+HAT_UNLOAD_UNMAP = 0x10
+HAT_SYNC_DONTZERO = 0x00
+HAT_SYNC_ZERORM = 0x01
+HAT_SYNC_STOPON_REF = 0x02
+HAT_SYNC_STOPON_MOD = 0x04
+HAT_SYNC_STOPON_RM = (HAT_SYNC_STOPON_REF | HAT_SYNC_STOPON_MOD)
+HAT_DUP_ALL = 1
+HAT_DUP_COW = 2
+HAT_MAP = 0x00
+HAT_ADV_PGUNLOAD = 0x00
+HAT_FORCE_PGUNLOAD = 0x01
+P_MOD = 0x1
+P_REF = 0x2
+P_RO = 0x4
+def hat_ismod(pp): return (hat_page_getattr(pp, P_MOD))
+
+def hat_isref(pp): return (hat_page_getattr(pp, P_REF))
+
+def hat_isro(pp): return (hat_page_getattr(pp, P_RO))
+
+def hat_setmod(pp): return (hat_page_setattr(pp, P_MOD))
+
+def hat_setref(pp): return (hat_page_setattr(pp, P_REF))
+
+def hat_setrefmod(pp): return (hat_page_setattr(pp, P_REF|P_MOD))
+
+def hat_clrmod(pp): return (hat_page_clrattr(pp, P_MOD))
+
+def hat_clrref(pp): return (hat_page_clrattr(pp, P_REF))
+
+def hat_clrrefmod(pp): return (hat_page_clrattr(pp, P_REF|P_MOD))
+
+def hat_page_is_mapped(pp): return (hat_page_getshare(pp))
+
+HAT_DONTALLOC = 0
+HAT_ALLOC = 1
+HRM_SHIFT = 4
+HRM_BYTES = (1 << HRM_SHIFT)
+HRM_PAGES = ((HRM_BYTES * NBBY) / 2)
+HRM_PGPERBYTE = (NBBY/2)
+HRM_PGBYTEMASK = (HRM_PGPERBYTE-1)
+HRM_HASHSIZE = 0x200
+HRM_HASHMASK = (HRM_HASHSIZE - 1)
+HRM_BLIST_INCR = 0x200
+HRM_SWSMONID = 1
+SSL_NLEVELS = 4
+SSL_BFACTOR = 4
+SSL_LOG2BF = 2
+SEGP_ASYNC_FLUSH = 0x1
+SEGP_FORCE_WIRED = 0x2
+SEGP_SUCCESS = 0
+SEGP_FAIL = 1
+def seg_pages(seg): return \
+
+IE_NOMEM = -1
+AS_PAGLCK = 0x80
+AS_CLAIMGAP = 0x40
+AS_UNMAPWAIT = 0x20
+def AS_TYPE_64BIT(as): return \
+
+AS_LREP_LINKEDLIST = 0
+AS_LREP_SKIPLIST = 1
+AS_MUTATION_THRESH = 225
+AH_DIR = 0x1
+AH_LO = 0x0
+AH_HI = 0x1
+AH_CONTAIN = 0x2
+
+# Included from sys/ddidmareq.h
+DMA_UNIT_8 = 1
+DMA_UNIT_16 = 2
+DMA_UNIT_32 = 4
+DMALIM_VER0 = ((0x86000000) + 0)
+DDI_DMA_FORCE_PHYSICAL = 0x0100
+DMA_ATTR_V0 = 0
+DMA_ATTR_VERSION = DMA_ATTR_V0
+DDI_DMA_CALLBACK_RUNOUT = 0
+DDI_DMA_CALLBACK_DONE = 1
+DDI_DMA_WRITE = 0x0001
+DDI_DMA_READ = 0x0002
+DDI_DMA_RDWR = (DDI_DMA_READ | DDI_DMA_WRITE)
+DDI_DMA_REDZONE = 0x0004
+DDI_DMA_PARTIAL = 0x0008
+DDI_DMA_CONSISTENT = 0x0010
+DDI_DMA_EXCLUSIVE = 0x0020
+DDI_DMA_STREAMING = 0x0040
+DDI_DMA_SBUS_64BIT = 0x2000
+DDI_DMA_MAPPED = 0
+DDI_DMA_MAPOK = 0
+DDI_DMA_PARTIAL_MAP = 1
+DDI_DMA_DONE = 2
+DDI_DMA_NORESOURCES = -1
+DDI_DMA_NOMAPPING = -2
+DDI_DMA_TOOBIG = -3
+DDI_DMA_TOOSMALL = -4
+DDI_DMA_LOCKED = -5
+DDI_DMA_BADLIMITS = -6
+DDI_DMA_STALE = -7
+DDI_DMA_BADATTR = -8
+DDI_DMA_INUSE = -9
+DDI_DMA_SYNC_FORDEV = 0x0
+DDI_DMA_SYNC_FORCPU = 0x1
+DDI_DMA_SYNC_FORKERNEL = 0x2
+
+# Included from sys/ddimapreq.h
+
+# Included from sys/mman.h
+PROT_READ = 0x1
+PROT_WRITE = 0x2
+PROT_EXEC = 0x4
+PROT_USER = 0x8
+PROT_ZFOD = (PROT_READ | PROT_WRITE | PROT_EXEC | PROT_USER)
+PROT_ALL = (PROT_READ | PROT_WRITE | PROT_EXEC | PROT_USER)
+PROT_NONE = 0x0
+MAP_SHARED = 1
+MAP_PRIVATE = 2
+MAP_TYPE = 0xf
+MAP_FIXED = 0x10
+MAP_NORESERVE = 0x40
+MAP_ANON = 0x100
+MAP_ANONYMOUS = MAP_ANON
+MAP_RENAME = 0x20
+PROC_TEXT = (PROT_EXEC | PROT_READ)
+PROC_DATA = (PROT_READ | PROT_WRITE | PROT_EXEC)
+SHARED = 0x10
+PRIVATE = 0x20
+VALID_ATTR = (PROT_READ|PROT_WRITE|PROT_EXEC|SHARED|PRIVATE)
+PROT_EXCL = 0x20
+_MAP_LOW32 = 0x80
+_MAP_NEW = 0x80000000
+from TYPES import *
+MADV_NORMAL = 0
+MADV_RANDOM = 1
+MADV_SEQUENTIAL = 2
+MADV_WILLNEED = 3
+MADV_DONTNEED = 4
+MADV_FREE = 5
+MS_OLDSYNC = 0x0
+MS_SYNC = 0x4
+MS_ASYNC = 0x1
+MS_INVALIDATE = 0x2
+MC_SYNC = 1
+MC_LOCK = 2
+MC_UNLOCK = 3
+MC_ADVISE = 4
+MC_LOCKAS = 5
+MC_UNLOCKAS = 6
+MCL_CURRENT = 0x1
+MCL_FUTURE = 0x2
+DDI_MAP_VERSION = 0x0001
+DDI_MF_USER_MAPPING = 0x1
+DDI_MF_KERNEL_MAPPING = 0x2
+DDI_MF_DEVICE_MAPPING = 0x4
+DDI_ME_GENERIC = (-1)
+DDI_ME_UNIMPLEMENTED = (-2)
+DDI_ME_NORESOURCES = (-3)
+DDI_ME_UNSUPPORTED = (-4)
+DDI_ME_REGSPEC_RANGE = (-5)
+DDI_ME_RNUMBER_RANGE = (-6)
+DDI_ME_INVAL = (-7)
+
+# Included from sys/ddipropdefs.h
+def CELLS_1275_TO_BYTES(n): return ((n) * PROP_1275_CELL_SIZE)
+
+def BYTES_TO_1275_CELLS(n): return ((n) / PROP_1275_CELL_SIZE)
+
+PH_FROM_PROM = 0x01
+DDI_PROP_SUCCESS = 0
+DDI_PROP_NOT_FOUND = 1
+DDI_PROP_UNDEFINED = 2
+DDI_PROP_NO_MEMORY = 3
+DDI_PROP_INVAL_ARG = 4
+DDI_PROP_BUF_TOO_SMALL = 5
+DDI_PROP_CANNOT_DECODE = 6
+DDI_PROP_CANNOT_ENCODE = 7
+DDI_PROP_END_OF_DATA = 8
+DDI_PROP_FOUND_1275 = 255
+PROP_1275_INT_SIZE = 4
+DDI_PROP_DONTPASS = 0x0001
+DDI_PROP_CANSLEEP = 0x0002
+DDI_PROP_SYSTEM_DEF = 0x0004
+DDI_PROP_NOTPROM = 0x0008
+DDI_PROP_DONTSLEEP = 0x0010
+DDI_PROP_STACK_CREATE = 0x0020
+DDI_PROP_UNDEF_IT = 0x0040
+DDI_PROP_HW_DEF = 0x0080
+DDI_PROP_TYPE_INT = 0x0100
+DDI_PROP_TYPE_STRING = 0x0200
+DDI_PROP_TYPE_BYTE = 0x0400
+DDI_PROP_TYPE_COMPOSITE = 0x0800
+DDI_PROP_TYPE_ANY = (DDI_PROP_TYPE_INT  |       \
+                                        DDI_PROP_TYPE_STRING    |       \
+                                        DDI_PROP_TYPE_BYTE      |       \
+                                        DDI_PROP_TYPE_COMPOSITE)
+DDI_PROP_TYPE_MASK = (DDI_PROP_TYPE_INT |       \
+                                        DDI_PROP_TYPE_STRING    |       \
+                                        DDI_PROP_TYPE_BYTE      |       \
+                                        DDI_PROP_TYPE_COMPOSITE)
+DDI_RELATIVE_ADDRESSING = "relative-addressing"
+DDI_GENERIC_ADDRESSING = "generic-addressing"
+
+# Included from sys/ddidevmap.h
+KMEM_PAGEABLE = 0x100
+KMEM_NON_PAGEABLE = 0x200
+UMEM_LOCKED = 0x400
+UMEM_TRASH = 0x800
+DEVMAP_OPS_REV = 1
+DEVMAP_DEFAULTS = 0x00
+DEVMAP_MAPPING_INVALID = 0x01
+DEVMAP_ALLOW_REMAP = 0x02
+DEVMAP_USE_PAGESIZE = 0x04
+DEVMAP_SETUP_FLAGS = \
+        (DEVMAP_MAPPING_INVALID | DEVMAP_ALLOW_REMAP | DEVMAP_USE_PAGESIZE)
+DEVMAP_SETUP_DONE = 0x100
+DEVMAP_LOCK_INITED = 0x200
+DEVMAP_FAULTING = 0x400
+DEVMAP_LOCKED = 0x800
+DEVMAP_FLAG_LARGE = 0x1000
+DDI_UMEM_SLEEP = 0x0
+DDI_UMEM_NOSLEEP = 0x01
+DDI_UMEM_PAGEABLE = 0x02
+DDI_UMEM_TRASH = 0x04
+DDI_UMEMLOCK_READ = 0x01
+DDI_UMEMLOCK_WRITE = 0x02
+
+# Included from sys/nexusdefs.h
+
+# Included from sys/nexusintr.h
+BUSO_REV = 4
+BUSO_REV_3 = 3
+BUSO_REV_4 = 4
+DEVO_REV = 3
+CB_REV = 1
+DDI_IDENTIFIED = (0)
+DDI_NOT_IDENTIFIED = (-1)
+DDI_PROBE_FAILURE = ENXIO
+DDI_PROBE_DONTCARE = 0
+DDI_PROBE_PARTIAL = 1
+DDI_PROBE_SUCCESS = 2
+MAPDEV_REV = 1
+from TYPES import *
+D_NEW = 0x00
+_D_OLD = 0x01
+D_TAPE = 0x08
+D_MTSAFE = 0x0020
+_D_QNEXTLESS = 0x0040
+_D_MTOCSHARED = 0x0080
+D_MTOCEXCL = 0x0800
+D_MTPUTSHARED = 0x1000
+D_MTPERQ = 0x2000
+D_MTQPAIR = 0x4000
+D_MTPERMOD = 0x6000
+D_MTOUTPERIM = 0x8000
+_D_MTCBSHARED = 0x10000
+D_MTINNER_MOD = (D_MTPUTSHARED|_D_MTOCSHARED|_D_MTCBSHARED)
+D_MTOUTER_MOD = (D_MTOCEXCL)
+D_MP = D_MTSAFE
+D_64BIT = 0x200
+D_SYNCSTR = 0x400
+D_DEVMAP = 0x100
+D_HOTPLUG = 0x4
+SNDZERO = 0x001
+SNDPIPE = 0x002
+RNORM = 0x000
+RMSGD = 0x001
+RMSGN = 0x002
+RMODEMASK = 0x003
+RPROTDAT = 0x004
+RPROTDIS = 0x008
+RPROTNORM = 0x010
+RPROTMASK = 0x01c
+RFLUSHMASK = 0x020
+RFLUSHPCPROT = 0x020
+RERRNORM = 0x001
+RERRNONPERSIST = 0x002
+RERRMASK = (RERRNORM|RERRNONPERSIST)
+WERRNORM = 0x004
+WERRNONPERSIST = 0x008
+WERRMASK = (WERRNORM|WERRNONPERSIST)
+FLUSHR = 0x01
+FLUSHW = 0x02
+FLUSHRW = 0x03
+FLUSHBAND = 0x04
+MAPINOK = 0x01
+NOMAPIN = 0x02
+REMAPOK = 0x04
+NOREMAP = 0x08
+S_INPUT = 0x0001
+S_HIPRI = 0x0002
+S_OUTPUT = 0x0004
+S_MSG = 0x0008
+S_ERROR = 0x0010
+S_HANGUP = 0x0020
+S_RDNORM = 0x0040
+S_WRNORM = S_OUTPUT
+S_RDBAND = 0x0080
+S_WRBAND = 0x0100
+S_BANDURG = 0x0200
+RS_HIPRI = 0x01
+STRUIO_POSTPONE = 0x08
+STRUIO_MAPIN = 0x10
+MSG_HIPRI = 0x01
+MSG_ANY = 0x02
+MSG_BAND = 0x04
+MSG_XPG4 = 0x08
+MSG_IPEEK = 0x10
+MSG_DISCARDTAIL = 0x20
+MSG_HOLDSIG = 0x40
+MSG_IGNERROR = 0x80
+MSG_DELAYERROR = 0x100
+MSG_IGNFLOW = 0x200
+MSG_NOMARK = 0x400
+MORECTL = 1
+MOREDATA = 2
+MUXID_ALL = (-1)
+ANYMARK = 0x01
+LASTMARK = 0x02
+_INFTIM = -1
+INFTIM = _INFTIM

Added: vendor/Python/current/Lib/plat-sunos5/SUNAUDIODEV.py
===================================================================
--- vendor/Python/current/Lib/plat-sunos5/SUNAUDIODEV.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-sunos5/SUNAUDIODEV.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,40 @@
+# Symbolic constants for use with sunaudiodev module
+# The names are the same as in audioio.h with the leading AUDIO_
+# removed.
+
+# Not all values are supported on all releases of SunOS.
+
+# Encoding types, for fields i_encoding and o_encoding
+
+ENCODING_NONE = 0                       # no encoding assigned
+ENCODING_ULAW = 1                       # u-law encoding
+ENCODING_ALAW = 2                       # A-law encoding
+ENCODING_LINEAR = 3                     # Linear PCM encoding
+
+# Gain ranges for i_gain, o_gain and monitor_gain
+
+MIN_GAIN = 0                            # minimum gain value
+MAX_GAIN = 255                          # maximum gain value
+
+# Balance values for i_balance and o_balance
+
+LEFT_BALANCE = 0                        # left channel only
+MID_BALANCE = 32                        # equal left/right channel
+RIGHT_BALANCE = 64                      # right channel only
+BALANCE_SHIFT = 3
+
+# Port names for i_port and o_port
+
+PORT_A = 1
+PORT_B = 2
+PORT_C = 3
+PORT_D = 4
+
+SPEAKER = 0x01                          # output to built-in speaker
+HEADPHONE = 0x02                        # output to headphone jack
+LINE_OUT = 0x04                         # output to line out
+
+MICROPHONE = 0x01                       # input from microphone
+LINE_IN = 0x02                          # input from line in
+CD = 0x04                               # input from on-board CD inputs
+INTERNAL_CD_IN = CD                     # input from internal CDROM


Property changes on: vendor/Python/current/Lib/plat-sunos5/SUNAUDIODEV.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/plat-sunos5/TYPES.py
===================================================================
--- vendor/Python/current/Lib/plat-sunos5/TYPES.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-sunos5/TYPES.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,313 @@
+# Generated by h2py from /usr/include/sys/types.h
+
+# Included from sys/isa_defs.h
+_CHAR_ALIGNMENT = 1
+_SHORT_ALIGNMENT = 2
+_INT_ALIGNMENT = 4
+_LONG_ALIGNMENT = 8
+_LONG_LONG_ALIGNMENT = 8
+_DOUBLE_ALIGNMENT = 8
+_LONG_DOUBLE_ALIGNMENT = 16
+_POINTER_ALIGNMENT = 8
+_MAX_ALIGNMENT = 16
+_ALIGNMENT_REQUIRED = 1
+_CHAR_ALIGNMENT = 1
+_SHORT_ALIGNMENT = 2
+_INT_ALIGNMENT = 4
+_LONG_ALIGNMENT = 4
+_LONG_LONG_ALIGNMENT = 4
+_DOUBLE_ALIGNMENT = 4
+_LONG_DOUBLE_ALIGNMENT = 4
+_POINTER_ALIGNMENT = 4
+_MAX_ALIGNMENT = 4
+_ALIGNMENT_REQUIRED = 0
+_CHAR_ALIGNMENT = 1
+_SHORT_ALIGNMENT = 2
+_INT_ALIGNMENT = 4
+_LONG_LONG_ALIGNMENT = 8
+_DOUBLE_ALIGNMENT = 8
+_ALIGNMENT_REQUIRED = 1
+_LONG_ALIGNMENT = 4
+_LONG_DOUBLE_ALIGNMENT = 8
+_POINTER_ALIGNMENT = 4
+_MAX_ALIGNMENT = 8
+_LONG_ALIGNMENT = 8
+_LONG_DOUBLE_ALIGNMENT = 16
+_POINTER_ALIGNMENT = 8
+_MAX_ALIGNMENT = 16
+
+# Included from sys/feature_tests.h
+_POSIX_C_SOURCE = 1
+_LARGEFILE64_SOURCE = 1
+_LARGEFILE_SOURCE = 1
+_FILE_OFFSET_BITS = 64
+_FILE_OFFSET_BITS = 32
+_POSIX_C_SOURCE = 199506L
+_POSIX_PTHREAD_SEMANTICS = 1
+_XOPEN_VERSION = 500
+_XOPEN_VERSION = 4
+_XOPEN_VERSION = 3
+
+# Included from sys/machtypes.h
+
+# Included from sys/inttypes.h
+
+# Included from sys/int_types.h
+
+# Included from sys/int_limits.h
+INT8_MAX = (127)
+INT16_MAX = (32767)
+INT32_MAX = (2147483647)
+INTMAX_MAX = INT32_MAX
+INT_LEAST8_MAX = INT8_MAX
+INT_LEAST16_MAX = INT16_MAX
+INT_LEAST32_MAX = INT32_MAX
+INT8_MIN = (-128)
+INT16_MIN = (-32767-1)
+INT32_MIN = (-2147483647-1)
+INTMAX_MIN = INT32_MIN
+INT_LEAST8_MIN = INT8_MIN
+INT_LEAST16_MIN = INT16_MIN
+INT_LEAST32_MIN = INT32_MIN
+
+# Included from sys/int_const.h
+def INT8_C(c): return (c)
+
+def INT16_C(c): return (c)
+
+def INT32_C(c): return (c)
+
+def INT64_C(c): return __CONCAT__(c,l)
+
+def INT64_C(c): return __CONCAT__(c,ll)
+
+def UINT8_C(c): return __CONCAT__(c,u)
+
+def UINT16_C(c): return __CONCAT__(c,u)
+
+def UINT32_C(c): return __CONCAT__(c,u)
+
+def UINT64_C(c): return __CONCAT__(c,ul)
+
+def UINT64_C(c): return __CONCAT__(c,ull)
+
+def INTMAX_C(c): return __CONCAT__(c,l)
+
+def UINTMAX_C(c): return __CONCAT__(c,ul)
+
+def INTMAX_C(c): return __CONCAT__(c,ll)
+
+def UINTMAX_C(c): return __CONCAT__(c,ull)
+
+def INTMAX_C(c): return (c)
+
+def UINTMAX_C(c): return (c)
+
+
+# Included from sys/int_fmtio.h
+PRId8 = "d"
+PRId16 = "d"
+PRId32 = "d"
+PRId64 = "ld"
+PRId64 = "lld"
+PRIdLEAST8 = "d"
+PRIdLEAST16 = "d"
+PRIdLEAST32 = "d"
+PRIdLEAST64 = "ld"
+PRIdLEAST64 = "lld"
+PRIi8 = "i"
+PRIi16 = "i"
+PRIi32 = "i"
+PRIi64 = "li"
+PRIi64 = "lli"
+PRIiLEAST8 = "i"
+PRIiLEAST16 = "i"
+PRIiLEAST32 = "i"
+PRIiLEAST64 = "li"
+PRIiLEAST64 = "lli"
+PRIo8 = "o"
+PRIo16 = "o"
+PRIo32 = "o"
+PRIo64 = "lo"
+PRIo64 = "llo"
+PRIoLEAST8 = "o"
+PRIoLEAST16 = "o"
+PRIoLEAST32 = "o"
+PRIoLEAST64 = "lo"
+PRIoLEAST64 = "llo"
+PRIx8 = "x"
+PRIx16 = "x"
+PRIx32 = "x"
+PRIx64 = "lx"
+PRIx64 = "llx"
+PRIxLEAST8 = "x"
+PRIxLEAST16 = "x"
+PRIxLEAST32 = "x"
+PRIxLEAST64 = "lx"
+PRIxLEAST64 = "llx"
+PRIX8 = "X"
+PRIX16 = "X"
+PRIX32 = "X"
+PRIX64 = "lX"
+PRIX64 = "llX"
+PRIXLEAST8 = "X"
+PRIXLEAST16 = "X"
+PRIXLEAST32 = "X"
+PRIXLEAST64 = "lX"
+PRIXLEAST64 = "llX"
+PRIu8 = "u"
+PRIu16 = "u"
+PRIu32 = "u"
+PRIu64 = "lu"
+PRIu64 = "llu"
+PRIuLEAST8 = "u"
+PRIuLEAST16 = "u"
+PRIuLEAST32 = "u"
+PRIuLEAST64 = "lu"
+PRIuLEAST64 = "llu"
+SCNd16 = "hd"
+SCNd32 = "d"
+SCNd64 = "ld"
+SCNd64 = "lld"
+SCNi16 = "hi"
+SCNi32 = "i"
+SCNi64 = "li"
+SCNi64 = "lli"
+SCNo16 = "ho"
+SCNo32 = "o"
+SCNo64 = "lo"
+SCNo64 = "llo"
+SCNu16 = "hu"
+SCNu32 = "u"
+SCNu64 = "lu"
+SCNu64 = "llu"
+SCNx16 = "hx"
+SCNx32 = "x"
+SCNx64 = "lx"
+SCNx64 = "llx"
+PRIdMAX = "ld"
+PRIoMAX = "lo"
+PRIxMAX = "lx"
+PRIuMAX = "lu"
+PRIdMAX = "lld"
+PRIoMAX = "llo"
+PRIxMAX = "llx"
+PRIuMAX = "llu"
+PRIdMAX = "d"
+PRIoMAX = "o"
+PRIxMAX = "x"
+PRIuMAX = "u"
+SCNiMAX = "li"
+SCNdMAX = "ld"
+SCNoMAX = "lo"
+SCNxMAX = "lx"
+SCNiMAX = "lli"
+SCNdMAX = "lld"
+SCNoMAX = "llo"
+SCNxMAX = "llx"
+SCNiMAX = "i"
+SCNdMAX = "d"
+SCNoMAX = "o"
+SCNxMAX = "x"
+
+# Included from sys/types32.h
+SHRT_MIN = (-32768)
+SHRT_MAX = 32767
+USHRT_MAX = 65535
+INT_MIN = (-2147483647-1)
+INT_MAX = 2147483647
+LONG_MIN = (-9223372036854775807L-1L)
+LONG_MAX = 9223372036854775807L
+LONG_MIN = (-2147483647L-1L)
+LONG_MAX = 2147483647L
+P_MYID = (-1)
+
+# Included from sys/select.h
+
+# Included from sys/time.h
+TIME32_MAX = INT32_MAX
+TIME32_MIN = INT32_MIN
+def TIMEVAL_OVERFLOW(tv): return \
+
+from TYPES import *
+DST_NONE = 0
+DST_USA = 1
+DST_AUST = 2
+DST_WET = 3
+DST_MET = 4
+DST_EET = 5
+DST_CAN = 6
+DST_GB = 7
+DST_RUM = 8
+DST_TUR = 9
+DST_AUSTALT = 10
+ITIMER_REAL = 0
+ITIMER_VIRTUAL = 1
+ITIMER_PROF = 2
+ITIMER_REALPROF = 3
+def ITIMERVAL_OVERFLOW(itv): return \
+
+SEC = 1
+MILLISEC = 1000
+MICROSEC = 1000000
+NANOSEC = 1000000000
+
+# Included from sys/time_impl.h
+def TIMESPEC_OVERFLOW(ts): return \
+
+def ITIMERSPEC_OVERFLOW(it): return \
+
+__CLOCK_REALTIME0 = 0
+CLOCK_VIRTUAL = 1
+CLOCK_PROF = 2
+__CLOCK_REALTIME3 = 3
+CLOCK_HIGHRES = 4
+CLOCK_MAX = 5
+CLOCK_REALTIME = __CLOCK_REALTIME3
+CLOCK_REALTIME = __CLOCK_REALTIME0
+TIMER_RELTIME = 0x0
+TIMER_ABSTIME = 0x1
+
+# Included from sys/mutex.h
+from TYPES import *
+def MUTEX_HELD(x): return (mutex_owned(x))
+
+def TICK_TO_SEC(tick): return ((tick) / hz)
+
+def SEC_TO_TICK(sec): return ((sec) * hz)
+
+def TICK_TO_MSEC(tick): return \
+
+def MSEC_TO_TICK(msec): return \
+
+def MSEC_TO_TICK_ROUNDUP(msec): return \
+
+def TICK_TO_USEC(tick): return ((tick) * usec_per_tick)
+
+def USEC_TO_TICK(usec): return ((usec) / usec_per_tick)
+
+def USEC_TO_TICK_ROUNDUP(usec): return \
+
+def TICK_TO_NSEC(tick): return ((tick) * nsec_per_tick)
+
+def NSEC_TO_TICK(nsec): return ((nsec) / nsec_per_tick)
+
+def NSEC_TO_TICK_ROUNDUP(nsec): return \
+
+def TIMEVAL_TO_TICK(tvp): return \
+
+def TIMESTRUC_TO_TICK(tsp): return \
+
+
+# Included from time.h
+from TYPES import *
+
+# Included from iso/time_iso.h
+NULL = 0L
+NULL = 0
+CLOCKS_PER_SEC = 1000000
+FD_SETSIZE = 65536
+FD_SETSIZE = 1024
+_NBBY = 8
+NBBY = _NBBY
+def FD_ZERO(p): return bzero((p), sizeof (*(p)))

Added: vendor/Python/current/Lib/plat-sunos5/regen
===================================================================
--- vendor/Python/current/Lib/plat-sunos5/regen	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-sunos5/regen	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,9 @@
+#! /bin/sh
+case `uname -sr` in
+'SunOS 5.'*)	;;
+*)	echo Probably not on a Solaris 2 system 1>&2
+	exit 1;;
+esac
+set -v
+h2py -i '(u_long)' /usr/include/sys/types.h /usr/include/netinet/in.h /usr/include/sys/stropts.h /usr/include/dlfcn.h
+


Property changes on: vendor/Python/current/Lib/plat-sunos5/regen
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/plat-unixware7/IN.py
===================================================================
--- vendor/Python/current/Lib/plat-unixware7/IN.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-unixware7/IN.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,836 @@
+# Generated by h2py from /usr/include/netinet/in.h
+
+# Included from netinet/in_f.h
+def IN_CLASSA(i): return (((long)(i) & 0x80000000) == 0)
+
+IN_CLASSA_NET = 0xff000000
+IN_CLASSA_NSHIFT = 24
+IN_CLASSA_HOST = 0x00ffffff
+IN_CLASSA_MAX = 128
+def IN_CLASSB(i): return (((long)(i) & 0xc0000000) == 0x80000000)
+
+IN_CLASSB_NET = 0xffff0000
+IN_CLASSB_NSHIFT = 16
+IN_CLASSB_HOST = 0x0000ffff
+IN_CLASSB_MAX = 65536
+def IN_CLASSC(i): return (((long)(i) & 0xe0000000) == 0xc0000000)
+
+IN_CLASSC_NET = 0xffffff00
+IN_CLASSC_NSHIFT = 8
+IN_CLASSC_HOST = 0x000000ff
+def IN_CLASSD(i): return (((long)(i) & 0xf0000000) == 0xe0000000)
+
+IN_CLASSD_NET = 0xf0000000
+IN_CLASSD_NSHIFT = 28
+IN_CLASSD_HOST = 0x0fffffff
+def IN_MULTICAST(i): return IN_CLASSD(i)
+
+def IN_EXPERIMENTAL(i): return (((long)(i) & 0xe0000000) == 0xe0000000)
+
+def IN_BADCLASS(i): return (((long)(i) & 0xf0000000) == 0xf0000000)
+
+INADDR_ANY = 0x00000000
+INADDR_LOOPBACK = 0x7f000001
+INADDR_BROADCAST = 0xffffffff
+INADDR_NONE = 0xffffffff
+IN_LOOPBACKNET = 127
+INADDR_UNSPEC_GROUP = 0xe0000000
+INADDR_ALLHOSTS_GROUP = 0xe0000001
+INADDR_ALLRTRS_GROUP = 0xe0000002
+INADDR_MAX_LOCAL_GROUP = 0xe00000ff
+
+# Included from netinet/in6.h
+
+# Included from sys/types.h
+def quad_low(x): return x.val[0]
+
+ADT_EMASKSIZE = 8
+SHRT_MIN = -32768
+SHRT_MAX = 32767
+INT_MIN = (-2147483647-1)
+INT_MAX = 2147483647
+LONG_MIN = (-2147483647-1)
+LONG_MAX = 2147483647
+OFF32_MAX = LONG_MAX
+ISTAT_ASSERTED = 0
+ISTAT_ASSUMED = 1
+ISTAT_NONE = 2
+OFF_MAX = OFF32_MAX
+CLOCK_MAX = LONG_MAX
+P_MYID = (-1)
+P_MYHOSTID = (-1)
+
+# Included from sys/select.h
+FD_SETSIZE = 4096
+NBBY = 8
+NULL = 0
+
+# Included from sys/bitypes.h
+
+# Included from netinet/in6_f.h
+def IN6_IS_ADDR_UNSPECIFIED(a): return IN6_ADDR_EQUAL_L(a, 0, 0, 0, 0)
+
+def IN6_SET_ADDR_UNSPECIFIED(a): return IN6_ADDR_COPY_L(a, 0, 0, 0, 0)
+
+def IN6_IS_ADDR_ANY(a): return IN6_ADDR_EQUAL_L(a, 0, 0, 0, 0)
+
+def IN6_SET_ADDR_ANY(a): return IN6_ADDR_COPY_L(a, 0, 0, 0, 0)
+
+def IN6_IS_ADDR_LOOPBACK(a): return IN6_ADDR_EQUAL_L(a, 0, 0, 0, 0x01000000)
+
+def IN6_SET_ADDR_LOOPBACK(a): return IN6_ADDR_COPY_L(a, 0, 0, 0, 0x01000000)
+
+IN6_MC_FLAG_PERMANENT = 0x0
+IN6_MC_FLAG_TRANSIENT = 0x1
+IN6_MC_SCOPE_NODELOCAL = 0x1
+IN6_MC_SCOPE_LINKLOCAL = 0x2
+IN6_MC_SCOPE_SITELOCAL = 0x5
+IN6_MC_SCOPE_ORGLOCAL = 0x8
+IN6_MC_SCOPE_GLOBAL = 0xE
+def IN6_IS_ADDR_MC_NODELOCAL(a): return \
+
+def IN6_IS_ADDR_MC_LINKLOCAL(a): return \
+
+def IN6_IS_ADDR_MC_SITELOCAL(a): return \
+
+def IN6_IS_ADDR_MC_ORGLOCAL(a): return \
+
+def IN6_IS_ADDR_MC_GLOBAL(a): return \
+
+
+# Included from sys/convsa.h
+__NETLIB_UW211_SVR4 = 1
+__NETLIB_UW211_XPG4 = 2
+__NETLIB_GEMINI_SVR4 = 3
+__NETLIB_GEMINI_XPG4 = 4
+__NETLIB_FP1_SVR4 = 5
+__NETLIB_FP1_XPG4 = 6
+__NETLIB_BASE_VERSION__ = __NETLIB_UW211_SVR4
+__NETLIB_VERSION__ = __NETLIB_FP1_SVR4
+__NETLIB_VERSION__ = __NETLIB_FP1_XPG4
+__NETLIB_VERSION__ = __NETLIB_GEMINI_SVR4
+__NETLIB_VERSION__ = __NETLIB_GEMINI_XPG4
+__NETLIB_VERSION__ = __NETLIB_UW211_SVR4
+__NETLIB_VERSION__ = __NETLIB_UW211_XPG4
+__NETLIB_VERSION__ = __NETLIB_FP1_XPG4
+
+# Included from sys/byteorder.h
+LITTLE_ENDIAN = 1234
+BIG_ENDIAN = 4321
+PDP_ENDIAN = 3412
+
+# Included from sys/byteorder_f.h
+BYTE_ORDER = LITTLE_ENDIAN
+def htonl(hl): return __htonl(hl)
+
+def ntohl(nl): return __ntohl(nl)
+
+def htons(hs): return __htons(hs)
+
+def ntohs(ns): return __ntohs(ns)
+
+def ntohl(x): return (x)
+
+def ntohs(x): return (x)
+
+def htonl(x): return (x)
+
+def htons(x): return (x)
+
+def __NETLIB_VERSION_IS_XPG4(version): return (((version) % 2) == 0)
+
+def __NETLIB_VERSION_HAS_SALEN(version): return ((version) >= __NETLIB_GEMINI_SVR4)
+
+def __NETLIB_VERSION_IS_IKS(version): return ((version) >= __NETLIB_FP1_SVR4)
+
+def SA_FAMILY_GET(sa): return \
+
+INET6_ADDRSTRLEN = 46
+IPV6_UNICAST_HOPS = 3
+IPV6_ADDRFORM = 24
+IPV6_MULTICAST_HOPS = 25
+IPV6_MULTICAST_IF = 26
+IPV6_MULTICAST_LOOP = 27
+IPV6_ADD_MEMBERSHIP = 28
+IPV6_DROP_MEMBERSHIP = 29
+
+# Included from sys/insrem.h
+def LIST_INIT(head): return \
+
+def LIST_INIT(head): return \
+
+def remque(a): return REMQUE(a)
+
+
+# Included from sys/socket.h
+
+# Included from sys/uio.h
+SHUT_RD = 0
+SHUT_WR = 1
+SHUT_RDWR = 2
+
+# Included from sys/netconfig.h
+
+# Included from sys/cdefs.h
+def __P(protos): return protos
+
+def __STRING(x): return #x
+
+def __P(protos): return ()
+
+def __STRING(x): return "x"
+
+NETCONFIG = "/etc/netconfig"
+NETPATH = "NETPATH"
+NC_TPI_CLTS = 1
+NC_TPI_COTS = 2
+NC_TPI_COTS_ORD = 3
+NC_TPI_RAW = 4
+NC_NOFLAG = 00
+NC_VISIBLE = 01
+NC_BROADCAST = 02
+NC_NOPROTOFMLY = "-"
+NC_LOOPBACK = "loopback"
+NC_INET = "inet"
+NC_INET6 = "inet6"
+NC_IMPLINK = "implink"
+NC_PUP = "pup"
+NC_CHAOS = "chaos"
+NC_NS = "ns"
+NC_NBS = "nbs"
+NC_ECMA = "ecma"
+NC_DATAKIT = "datakit"
+NC_CCITT = "ccitt"
+NC_SNA = "sna"
+NC_DECNET = "decnet"
+NC_DLI = "dli"
+NC_LAT = "lat"
+NC_HYLINK = "hylink"
+NC_APPLETALK = "appletalk"
+NC_NIT = "nit"
+NC_IEEE802 = "ieee802"
+NC_OSI = "osi"
+NC_X25 = "x25"
+NC_OSINET = "osinet"
+NC_GOSIP = "gosip"
+NC_NETWARE = "netware"
+NC_NOPROTO = "-"
+NC_TCP = "tcp"
+NC_UDP = "udp"
+NC_ICMP = "icmp"
+NC_IPX = "ipx"
+NC_SPX = "spx"
+NC_TPI_CLTS = 1
+NC_TPI_COTS = 2
+NC_TPI_COTS_ORD = 3
+NC_TPI_RAW = 4
+SOCK_STREAM = 2
+SOCK_DGRAM = 1
+SOCK_RAW = 4
+SOCK_RDM = 5
+SOCK_SEQPACKET = 6
+SO_DEBUG = 0x0001
+SO_ACCEPTCONN = 0x0002
+SO_REUSEADDR = 0x0004
+SO_KEEPALIVE = 0x0008
+SO_DONTROUTE = 0x0010
+SO_BROADCAST = 0x0020
+SO_USELOOPBACK = 0x0040
+SO_LINGER = 0x0080
+SO_OOBINLINE = 0x0100
+SO_ORDREL = 0x0200
+SO_IMASOCKET = 0x0400
+SO_MGMT = 0x0800
+SO_REUSEPORT = 0x1000
+SO_LISTENING = 0x2000
+SO_RDWR = 0x4000
+SO_SEMA = 0x8000
+SO_DONTLINGER = (~SO_LINGER)
+SO_SNDBUF = 0x1001
+SO_RCVBUF = 0x1002
+SO_SNDLOWAT = 0x1003
+SO_RCVLOWAT = 0x1004
+SO_SNDTIMEO = 0x1005
+SO_RCVTIMEO = 0x1006
+SO_ERROR = 0x1007
+SO_TYPE = 0x1008
+SO_PROTOTYPE = 0x1009
+SO_ALLRAW = 0x100a
+SOL_SOCKET = 0xffff
+AF_UNSPEC = 0
+AF_UNIX = 1
+AF_LOCAL = AF_UNIX
+AF_INET = 2
+AF_IMPLINK = 3
+AF_PUP = 4
+AF_CHAOS = 5
+AF_NS = 6
+AF_NBS = 7
+AF_ECMA = 8
+AF_DATAKIT = 9
+AF_CCITT = 10
+AF_SNA = 11
+AF_DECnet = 12
+AF_DLI = 13
+AF_LAT = 14
+AF_HYLINK = 15
+AF_APPLETALK = 16
+AF_NIT = 17
+AF_802 = 18
+AF_OSI = 19
+AF_ISO = AF_OSI
+AF_X25 = 20
+AF_OSINET = 21
+AF_GOSIP = 22
+AF_YNET = 23
+AF_ROUTE = 24
+AF_LINK = 25
+pseudo_AF_XTP = 26
+AF_INET6 = 27
+AF_MAX = 27
+AF_INET_BSWAP = 0x0200
+PF_UNSPEC = AF_UNSPEC
+PF_UNIX = AF_UNIX
+PF_LOCAL = AF_LOCAL
+PF_INET = AF_INET
+PF_IMPLINK = AF_IMPLINK
+PF_PUP = AF_PUP
+PF_CHAOS = AF_CHAOS
+PF_NS = AF_NS
+PF_NBS = AF_NBS
+PF_ECMA = AF_ECMA
+PF_DATAKIT = AF_DATAKIT
+PF_CCITT = AF_CCITT
+PF_SNA = AF_SNA
+PF_DECnet = AF_DECnet
+PF_DLI = AF_DLI
+PF_LAT = AF_LAT
+PF_HYLINK = AF_HYLINK
+PF_APPLETALK = AF_APPLETALK
+PF_NIT = AF_NIT
+PF_802 = AF_802
+PF_OSI = AF_OSI
+PF_ISO = PF_OSI
+PF_X25 = AF_X25
+PF_OSINET = AF_OSINET
+PF_GOSIP = AF_GOSIP
+PF_YNET = AF_YNET
+PF_ROUTE = AF_ROUTE
+PF_LINK = AF_LINK
+pseudo_PF_XTP = pseudo_AF_XTP
+PF_INET6 = AF_INET6
+PF_MAX = AF_MAX
+SOMAXCONN = 5
+SCM_RIGHTS = 1
+MSG_OOB = 0x1
+MSG_PEEK = 0x2
+MSG_DONTROUTE = 0x4
+MSG_CTRUNC = 0x8
+MSG_TRUNC = 0x10
+MSG_EOR = 0x30
+MSG_WAITALL = 0x20
+MSG_MAXIOVLEN = 16
+def OPTLEN(x): return ((((x) + sizeof(long) - 1) / sizeof(long)) * sizeof(long))
+
+GIARG = 0x1
+CONTI = 0x2
+GITAB = 0x4
+SOCKETSYS = 88
+SOCKETSYS = 83
+SO_ACCEPT = 1
+SO_BIND = 2
+SO_CONNECT = 3
+SO_GETPEERNAME = 4
+SO_GETSOCKNAME = 5
+SO_GETSOCKOPT = 6
+SO_LISTEN = 7
+SO_RECV = 8
+SO_RECVFROM = 9
+SO_SEND = 10
+SO_SENDTO = 11
+SO_SETSOCKOPT = 12
+SO_SHUTDOWN = 13
+SO_SOCKET = 14
+SO_SOCKPOLL = 15
+SO_GETIPDOMAIN = 16
+SO_SETIPDOMAIN = 17
+SO_ADJTIME = 18
+
+# Included from sys/stream.h
+
+# Included from sys/cred.h
+
+# Included from sys/ksynch.h
+
+# Included from sys/dl.h
+SIGNBIT = 0x80000000
+
+# Included from sys/ipl.h
+
+# Included from sys/disp_p.h
+
+# Included from sys/trap.h
+DIVERR = 0
+SGLSTP = 1
+NMIFLT = 2
+BPTFLT = 3
+INTOFLT = 4
+BOUNDFLT = 5
+INVOPFLT = 6
+NOEXTFLT = 7
+DBLFLT = 8
+EXTOVRFLT = 9
+INVTSSFLT = 10
+SEGNPFLT = 11
+STKFLT = 12
+GPFLT = 13
+PGFLT = 14
+EXTERRFLT = 16
+ALIGNFLT = 17
+MCEFLT = 18
+USERFLT = 0x100
+TRP_PREEMPT = 0x200
+TRP_UNUSED = 0x201
+PF_ERR_MASK = 0x01
+PF_ERR_PAGE = 0
+PF_ERR_PROT = 1
+PF_ERR_WRITE = 2
+PF_ERR_USER = 4
+EVT_STRSCHED = 0x04
+EVT_GLOBCALLOUT = 0x08
+EVT_LCLCALLOUT = 0x10
+EVT_SOFTINTMASK = (EVT_STRSCHED|EVT_GLOBCALLOUT|EVT_LCLCALLOUT)
+PL0 = 0
+PL1 = 1
+PL2 = 2
+PL3 = 3
+PL4 = 4
+PL5 = 5
+PL6 = 6
+PLHI = 8
+PL7 = PLHI
+PLBASE = PL0
+PLTIMEOUT = PL1
+PLDISK = PL5
+PLSTR = PL6
+PLTTY = PLSTR
+PLMIN = PL0
+PLMIN = PL1
+MAX_INTR_LEVELS = 10
+MAX_INTR_NESTING = 50
+STRSCHED = EVT_STRSCHED
+GLOBALSOFTINT = EVT_GLOBCALLOUT
+LOCALSOFTINT = EVT_LCLCALLOUT
+
+# Included from sys/ksynch_p.h
+def GET_TIME(timep): return \
+
+LK_THRESHOLD = 500000
+
+# Included from sys/list.h
+
+# Included from sys/listasm.h
+def remque_null(e): return \
+
+def LS_ISEMPTY(listp): return \
+
+LK_BASIC = 0x1
+LK_SLEEP = 0x2
+LK_NOSTATS = 0x4
+def CYCLES_SINCE(c): return CYCLES_BETWEEN((c), CYCLES())
+
+LSB_NLKDS = 92
+EVT_RUNRUN = 0x01
+EVT_KPRUNRUN = 0x02
+SP_UNLOCKED = 0
+SP_LOCKED = 1
+KS_LOCKTEST = 0x01
+KS_MPSTATS = 0x02
+KS_DEINITED = 0x04
+KS_NVLTTRACE = 0x08
+RWS_READ = (ord('r'))
+RWS_WRITE = (ord('w'))
+RWS_UNLOCKED = (ord('u'))
+RWS_BUSY = (ord('b'))
+def SLEEP_LOCKOWNED(lkp): return \
+
+def SLEEP_DISOWN(lkp): return \
+
+KS_NOPRMPT = 0x00000001
+__KS_LOCKTEST = KS_LOCKTEST
+__KS_LOCKTEST = 0
+__KS_MPSTATS = KS_MPSTATS
+__KS_MPSTATS = 0
+__KS_NVLTTRACE = KS_NVLTTRACE
+__KS_NVLTTRACE = 0
+KSFLAGS = (__KS_LOCKTEST|__KS_MPSTATS|__KS_NVLTTRACE)
+KSVUNIPROC = 1
+KSVMPDEBUG = 2
+KSVMPNODEBUG = 3
+KSVFLAG = KSVUNIPROC
+KSVFLAG = KSVMPDEBUG
+KSVFLAG = KSVMPNODEBUG
+
+# Included from sys/ksinline.h
+_A_SP_LOCKED = 1
+_A_SP_UNLOCKED = 0
+_A_INVPL = -1
+def _ATOMIC_INT_INCR(atomic_intp): return \
+
+def _ATOMIC_INT_DECR(atomic_intp): return \
+
+def ATOMIC_INT_READ(atomic_intp): return _ATOMIC_INT_READ(atomic_intp)
+
+def ATOMIC_INT_INCR(atomic_intp): return _ATOMIC_INT_INCR(atomic_intp)
+
+def ATOMIC_INT_DECR(atomic_intp): return _ATOMIC_INT_DECR(atomic_intp)
+
+def FSPIN_INIT(lp): return
+
+def FSPIN_LOCK(l): return DISABLE()
+
+def FSPIN_TRYLOCK(l): return (DISABLE(), B_TRUE)
+
+def FSPIN_UNLOCK(l): return ENABLE()
+
+def LOCK_DEINIT(lp): return
+
+def LOCK_DEALLOC(lp): return
+
+def LOCK_OWNED(lp): return (B_TRUE)
+
+def RW_DEINIT(lp): return
+
+def RW_DEALLOC(lp): return
+
+def RW_OWNED(lp): return (B_TRUE)
+
+def IS_LOCKED(lockp): return B_FALSE
+
+def LOCK_PLMIN(lockp): return \
+
+def TRYLOCK_PLMIN(lockp): return LOCK_PLMIN(lockp)
+
+def LOCK_SH_PLMIN(lockp): return LOCK_PLMIN(lockp)
+
+def RW_RDLOCK_PLMIN(lockp): return LOCK_PLMIN(lockp)
+
+def RW_WRLOCK_PLMIN(lockp): return LOCK_PLMIN(lockp)
+
+def LOCK_DEINIT(l): return
+
+def LOCK_PLMIN(lockp): return LOCK((lockp), PLMIN)
+
+def TRYLOCK_PLMIN(lockp): return TRYLOCK((lockp), PLMIN)
+
+def LOCK_SH_PLMIN(lockp): return LOCK_SH((lockp), PLMIN)
+
+def RW_RDLOCK_PLMIN(lockp): return RW_RDLOCK((lockp), PLMIN)
+
+def RW_WRLOCK_PLMIN(lockp): return RW_WRLOCK((lockp), PLMIN)
+
+def FSPIN_IS_LOCKED(fsp): return B_FALSE
+
+def SPIN_IS_LOCKED(lockp): return B_FALSE
+
+def FSPIN_OWNED(l): return (B_TRUE)
+
+CR_MLDREAL = 0x00000001
+CR_RDUMP = 0x00000002
+def crhold(credp): return crholdn((credp), 1)
+
+def crfree(credp): return crfreen((credp), 1)
+
+
+# Included from sys/strmdep.h
+def str_aligned(X): return (((uint)(X) & (sizeof(int) - 1)) == 0)
+
+
+# Included from sys/engine.h
+
+# Included from sys/clock.h
+
+# Included from sys/time.h
+DST_NONE = 0
+DST_USA = 1
+DST_AUST = 2
+DST_WET = 3
+DST_MET = 4
+DST_EET = 5
+DST_CAN = 6
+DST_GB = 7
+DST_RUM = 8
+DST_TUR = 9
+DST_AUSTALT = 10
+ITIMER_REAL = 0
+ITIMER_VIRTUAL = 1
+ITIMER_PROF = 2
+FD_SETSIZE = 4096
+FD_NBBY = 8
+
+# Included from time.h
+NULL = 0
+CLOCKS_PER_SEC = 1000000
+
+# Included from sys/clock_p.h
+CGBITS = 4
+IDBITS = 28
+def toid_unpackcg(idval): return (((idval) >> IDBITS) & 0xf)
+
+def toid_unpackid(idval): return ((idval) & 0xfffffff)
+
+def toid_unpackcg(idval): return 0
+
+def toid_unpackid(idval): return (idval)
+
+NCALLOUT_HASH = 1024
+CALLOUT_MAXVAL = 0x7fffffff
+TO_PERIODIC = 0x80000000
+TO_IMMEDIATE = 0x80000000
+SEC = 1
+MILLISEC = 1000
+MICROSEC = 1000000
+NANOSEC = 1000000000
+SECHR = (60*60)
+SECDAY = (24*SECHR)
+SECYR = (365*SECDAY)
+def TIME_OWNED_R(cgnum): return (B_TRUE)
+
+LOOPSECONDS = 1800
+LOOPMICROSECONDS = (LOOPSECONDS * MICROSEC)
+def TICKS_SINCE(t): return TICKS_BETWEEN(t, TICKS())
+
+MAXRQS = 2
+E_OFFLINE = 0x01
+E_BAD = 0x02
+E_SHUTDOWN = 0x04
+E_DRIVER = 0x08
+E_DEFAULTKEEP = 0x100
+E_DRIVERBOUND = 0x200
+E_EXCLUSIVE = 0x400
+E_CGLEADER = 0x800
+E_NOWAY = (E_OFFLINE|E_BAD|E_SHUTDOWN)
+E_BOUND = 0x01
+E_GLOBAL = 0x00
+E_UNAVAIL = -1
+ENGINE_ONLINE = 1
+def PROCESSOR_UNMAP(e): return ((e) - engine)
+
+BOOTENG = 0
+QMOVED = 0x0001
+QWANTR = 0x0002
+QWANTW = 0x0004
+QFULL = 0x0008
+QREADR = 0x0010
+QUSE = 0x0020
+QNOENB = 0x0040
+QUP = 0x0080
+QBACK = 0x0100
+QINTER = 0x0200
+QPROCSON = 0x0400
+QTOENAB = 0x0800
+QFREEZE = 0x1000
+QBOUND = 0x2000
+QDEFCNT = 0x4000
+QENAB = 0x0001
+QSVCBUSY = 0x0002
+STRM_PUTCNT_TABLES = 31
+def STRM_MYENG_PUTCNT(sdp): return STRM_PUTCNT(l.eng_num, sdp)
+
+QB_FULL = 0x01
+QB_WANTW = 0x02
+QB_BACK = 0x04
+NBAND = 256
+DB_WASDUPED = 0x1
+DB_2PIECE = 0x2
+STRLEAKHASHSZ = 1021
+MSGMARK = 0x01
+MSGNOLOOP = 0x02
+MSGDELIM = 0x04
+MSGNOGET = 0x08
+MSGLOG = 0x10
+M_DATA = 0x00
+M_PROTO = 0x01
+M_BREAK = 0x08
+M_PASSFP = 0x09
+M_SIG = 0x0b
+M_DELAY = 0x0c
+M_CTL = 0x0d
+M_IOCTL = 0x0e
+M_SETOPTS = 0x10
+M_RSE = 0x11
+M_TRAIL = 0x12
+M_IOCACK = 0x81
+M_IOCNAK = 0x82
+M_PCPROTO = 0x83
+M_PCSIG = 0x84
+M_READ = 0x85
+M_FLUSH = 0x86
+M_STOP = 0x87
+M_START = 0x88
+M_HANGUP = 0x89
+M_ERROR = 0x8a
+M_COPYIN = 0x8b
+M_COPYOUT = 0x8c
+M_IOCDATA = 0x8d
+M_PCRSE = 0x8e
+M_STOPI = 0x8f
+M_STARTI = 0x90
+M_PCCTL = 0x91
+M_PCSETOPTS = 0x92
+QNORM = 0x00
+QPCTL = 0x80
+STRCANON = 0x01
+RECOPY = 0x02
+SO_ALL = 0x003f
+SO_READOPT = 0x0001
+SO_WROFF = 0x0002
+SO_MINPSZ = 0x0004
+SO_MAXPSZ = 0x0008
+SO_HIWAT = 0x0010
+SO_LOWAT = 0x0020
+SO_MREADON = 0x0040
+SO_MREADOFF = 0x0080
+SO_NDELON = 0x0100
+SO_NDELOFF = 0x0200
+SO_ISTTY = 0x0400
+SO_ISNTTY = 0x0800
+SO_TOSTOP = 0x1000
+SO_TONSTOP = 0x2000
+SO_BAND = 0x4000
+SO_DELIM = 0x8000
+SO_NODELIM = 0x010000
+SO_STRHOLD = 0x020000
+SO_LOOP = 0x040000
+DRVOPEN = 0x0
+MODOPEN = 0x1
+CLONEOPEN = 0x2
+OPENFAIL = -1
+BPRI_LO = 1
+BPRI_MED = 2
+BPRI_HI = 3
+INFPSZ = -1
+FLUSHALL = 1
+FLUSHDATA = 0
+STRHIGH = 5120
+STRLOW = 1024
+MAXIOCBSZ = 1024
+def straln(a): return (caddr_t)((long)(a) & ~(sizeof(int)-1))
+
+IPM_ID = 200
+ICMPM_ID = 201
+TCPM_ID = 202
+UDPM_ID = 203
+ARPM_ID = 204
+APPM_ID = 205
+RIPM_ID = 206
+PPPM_ID = 207
+AHDLCM_ID = 208
+MHDLCRIPM_ID = 209
+HDLCM_ID = 210
+PPCID_ID = 211
+IGMPM_ID = 212
+IPIPM_ID = 213
+IPPROTO_IP = 0
+IPPROTO_HOPOPTS = 0
+IPPROTO_ICMP = 1
+IPPROTO_IGMP = 2
+IPPROTO_GGP = 3
+IPPROTO_IPIP = 4
+IPPROTO_TCP = 6
+IPPROTO_EGP = 8
+IPPROTO_PUP = 12
+IPPROTO_UDP = 17
+IPPROTO_IDP = 22
+IPPROTO_TP = 29
+IPPROTO_IPV6 = 41
+IPPROTO_ROUTING = 43
+IPPROTO_FRAGMENT = 44
+IPPROTO_ESP = 50
+IPPROTO_AH = 51
+IPPROTO_ICMPV6 = 58
+IPPROTO_NONE = 59
+IPPROTO_DSTOPTS = 60
+IPPROTO_HELLO = 63
+IPPROTO_ND = 77
+IPPROTO_EON = 80
+IPPROTO_RAW = 255
+IPPROTO_MAX = 256
+IPPORT_ECHO = 7
+IPPORT_DISCARD = 9
+IPPORT_SYSTAT = 11
+IPPORT_DAYTIME = 13
+IPPORT_NETSTAT = 15
+IPPORT_FTP = 21
+IPPORT_TELNET = 23
+IPPORT_SMTP = 25
+IPPORT_TIMESERVER = 37
+IPPORT_NAMESERVER = 42
+IPPORT_WHOIS = 43
+IPPORT_MTP = 57
+IPPORT_TFTP = 69
+IPPORT_RJE = 77
+IPPORT_FINGER = 79
+IPPORT_TTYLINK = 87
+IPPORT_SUPDUP = 95
+IPPORT_EXECSERVER = 512
+IPPORT_LOGINSERVER = 513
+IPPORT_CMDSERVER = 514
+IPPORT_EFSSERVER = 520
+IPPORT_BIFFUDP = 512
+IPPORT_WHOSERVER = 513
+IPPORT_ROUTESERVER = 520
+IPPORT_RESERVED = 1024
+IPPORT_USERRESERVED = 65535
+IPPORT_RESERVED_LOW = 512
+IPPORT_RESERVED_HIGH = 1023
+IPPORT_USERRESERVED_LOW = 32768
+IPPORT_USERRESERVED_HIGH = 65535
+INET_ADDRSTRLEN = 16
+IP_OPTIONS = 1
+IP_TOS = 2
+IP_TTL = 3
+IP_HDRINCL = 4
+IP_RECVOPTS = 5
+IP_RECVRETOPTS = 6
+IP_RECVDSTADDR = 7
+IP_RETOPTS = 8
+IP_MULTICAST_IF = 9
+IP_MULTICAST_LOOP = 10
+IP_ADD_MEMBERSHIP = 11
+IP_DROP_MEMBERSHIP = 12
+IP_BROADCAST_IF = 14
+IP_RECVIFINDEX = 15
+IP_MULTICAST_TTL = 16
+MRT_INIT = 17
+MRT_DONE = 18
+MRT_ADD_VIF = 19
+MRT_DEL_VIF = 20
+MRT_ADD_MFC = 21
+MRT_DEL_MFC = 22
+MRT_VERSION = 23
+IP_DEFAULT_MULTICAST_TTL = 1
+IP_DEFAULT_MULTICAST_LOOP = 1
+IP_MAX_MEMBERSHIPS = 20
+INADDR_UNSPEC_GROUP = 0xe0000000
+INADDR_ALLHOSTS_GROUP = 0xe0000001
+INADDR_ALLRTRS_GROUP = 0xe0000002
+INADDR_MAX_LOCAL_GROUP = 0xe00000ff
+
+# Included from netinet/in_mp.h
+
+# Included from netinet/in_mp_ddi.h
+
+# Included from sys/inline.h
+IP_HIER_BASE = (20)
+def ASSERT_LOCK(x): return
+
+def ASSERT_WRLOCK(x): return
+
+def ASSERT_UNLOCK(x): return
+
+def CANPUT(q): return canput((q))
+
+def CANPUTNEXT(q): return canputnext((q))
+
+INET_DEBUG = 1

Added: vendor/Python/current/Lib/plat-unixware7/STROPTS.py
===================================================================
--- vendor/Python/current/Lib/plat-unixware7/STROPTS.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-unixware7/STROPTS.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,328 @@
+# Generated by h2py from /usr/include/sys/stropts.h
+
+# Included from sys/types.h
+def quad_low(x): return x.val[0]
+
+ADT_EMASKSIZE = 8
+SHRT_MIN = -32768
+SHRT_MAX = 32767
+INT_MIN = (-2147483647-1)
+INT_MAX = 2147483647
+LONG_MIN = (-2147483647-1)
+LONG_MAX = 2147483647
+OFF32_MAX = LONG_MAX
+ISTAT_ASSERTED = 0
+ISTAT_ASSUMED = 1
+ISTAT_NONE = 2
+OFF_MAX = OFF32_MAX
+CLOCK_MAX = LONG_MAX
+P_MYID = (-1)
+P_MYHOSTID = (-1)
+
+# Included from sys/select.h
+FD_SETSIZE = 4096
+NBBY = 8
+NULL = 0
+
+# Included from sys/conf.h
+D_NEW = 0x00
+D_OLD = 0x01
+D_DMA = 0x02
+D_BLKOFF = 0x400
+D_LFS = 0x8000
+D_STR = 0x0800
+D_MOD = 0x1000
+D_PSEUDO = 0x2000
+D_RANDOM = 0x4000
+D_HOT = 0x10000
+D_SEEKNEG = 0x04
+D_TAPE = 0x08
+D_NOBRKUP = 0x10
+D_INITPUB = 0x20
+D_NOSPECMACDATA = 0x40
+D_RDWEQ = 0x80
+SECMASK = (D_INITPUB|D_NOSPECMACDATA|D_RDWEQ)
+DAF_REQDMA = 0x1
+DAF_PHYSREQ = 0x2
+DAF_PRE8 = 0x4
+DAF_STATIC = 0x8
+DAF_STR = 0x10
+D_MP = 0x100
+D_UPF = 0x200
+ROOTFS_NAMESZ = 7
+FMNAMESZ = 8
+MCD_VERSION = 1
+DI_BCBP = 0
+DI_MEDIA = 1
+
+# Included from sys/secsys.h
+ES_MACOPENLID = 1
+ES_MACSYSLID = 2
+ES_MACROOTLID = 3
+ES_PRVINFO = 4
+ES_PRVSETCNT = 5
+ES_PRVSETS = 6
+ES_MACADTLID = 7
+ES_PRVID = 8
+ES_TPGETMAJOR = 9
+SA_EXEC = 001
+SA_WRITE = 002
+SA_READ = 004
+SA_SUBSIZE = 010
+
+# Included from sys/stropts_f.h
+X_STR = (ord('S')<<8)
+X_I_BASE = (X_STR|0200)
+X_I_NREAD = (X_STR|0201)
+X_I_PUSH = (X_STR|0202)
+X_I_POP = (X_STR|0203)
+X_I_LOOK = (X_STR|0204)
+X_I_FLUSH = (X_STR|0205)
+X_I_SRDOPT = (X_STR|0206)
+X_I_GRDOPT = (X_STR|0207)
+X_I_STR = (X_STR|0210)
+X_I_SETSIG = (X_STR|0211)
+X_I_GETSIG = (X_STR|0212)
+X_I_FIND = (X_STR|0213)
+X_I_LINK = (X_STR|0214)
+X_I_UNLINK = (X_STR|0215)
+X_I_PEEK = (X_STR|0217)
+X_I_FDINSERT = (X_STR|0220)
+X_I_SENDFD = (X_STR|0221)
+X_I_RECVFD = (X_STR|0222)
+
+# Included from unistd.h
+
+# Included from sys/unistd.h
+R_OK = 004
+W_OK = 002
+X_OK = 001
+F_OK = 000
+EFF_ONLY_OK = 010
+EX_OK = 020
+SEEK_SET = 0
+SEEK_CUR = 1
+SEEK_END = 2
+_SC_ARG_MAX = 1
+_SC_CHILD_MAX = 2
+_SC_CLK_TCK = 3
+_SC_NGROUPS_MAX = 4
+_SC_OPEN_MAX = 5
+_SC_JOB_CONTROL = 6
+_SC_SAVED_IDS = 7
+_SC_VERSION = 8
+_SC_PASS_MAX = 9
+_SC_LOGNAME_MAX = 10
+_SC_PAGESIZE = 11
+_SC_PAGE_SIZE = _SC_PAGESIZE
+_SC_XOPEN_VERSION = 12
+_SC_NACLS_MAX = 13
+_SC_NPROCESSORS_CONF = 14
+_SC_NPROCESSORS_ONLN = 15
+_SC_NPROCESSES = 39
+_SC_TOTAL_MEMORY = 40
+_SC_USEABLE_MEMORY = 41
+_SC_GENERAL_MEMORY = 42
+_SC_DEDICATED_MEMORY = 43
+_SC_NCGS_CONF = 44
+_SC_NCGS_ONLN = 45
+_SC_MAX_CPUS_PER_CG = 46
+_SC_CG_SIMPLE_IMPL = 47
+_SC_CACHE_LINE = 48
+_SC_SYSTEM_ID = 49
+_SC_THREADS = 51
+_SC_THREAD_ATTR_STACKADDR = 52
+_SC_THREAD_ATTR_STACKSIZE = 53
+_SC_THREAD_DESTRUCTOR_ITERATIONS = 54
+_SC_THREAD_KEYS_MAX = 55
+_SC_THREAD_PRIORITY_SCHEDULING = 56
+_SC_THREAD_PRIO_INHERIT = 57
+_SC_THREAD_PRIO_PROTECT = 58
+_SC_THREAD_STACK_MIN = 59
+_SC_THREAD_PROCESS_SHARED = 60
+_SC_THREAD_SAFE_FUNCTIONS = 61
+_SC_THREAD_THREADS_MAX = 62
+_SC_KERNEL_VM = 63
+_SC_TZNAME_MAX = 320
+_SC_STREAM_MAX = 321
+_SC_XOPEN_CRYPT = 323
+_SC_XOPEN_ENH_I18N = 324
+_SC_XOPEN_SHM = 325
+_SC_XOPEN_XCU_VERSION = 327
+_SC_AES_OS_VERSION = 330
+_SC_ATEXIT_MAX = 331
+_SC_2_C_BIND = 350
+_SC_2_C_DEV = 351
+_SC_2_C_VERSION = 352
+_SC_2_CHAR_TERM = 353
+_SC_2_FORT_DEV = 354
+_SC_2_FORT_RUN = 355
+_SC_2_LOCALEDEF = 356
+_SC_2_SW_DEV = 357
+_SC_2_UPE = 358
+_SC_2_VERSION = 359
+_SC_BC_BASE_MAX = 370
+_SC_BC_DIM_MAX = 371
+_SC_BC_SCALE_MAX = 372
+_SC_BC_STRING_MAX = 373
+_SC_COLL_WEIGHTS_MAX = 380
+_SC_EXPR_NEST_MAX = 381
+_SC_LINE_MAX = 382
+_SC_RE_DUP_MAX = 383
+_SC_IOV_MAX = 390
+_SC_NPROC_CONF = 391
+_SC_NPROC_ONLN = 392
+_SC_XOPEN_UNIX = 400
+_SC_SEMAPHORES = 440
+_CS_PATH = 1
+__O_CS_HOSTNAME = 2
+_CS_RELEASE = 3
+_CS_VERSION = 4
+__O_CS_MACHINE = 5
+__O_CS_ARCHITECTURE = 6
+_CS_HW_SERIAL = 7
+__O_CS_HW_PROVIDER = 8
+_CS_SRPC_DOMAIN = 9
+_CS_INITTAB_NAME = 10
+__O_CS_SYSNAME = 11
+_CS_LFS_CFLAGS = 20
+_CS_LFS_LDFLAGS = 21
+_CS_LFS_LIBS = 22
+_CS_LFS_LINTFLAGS = 23
+_CS_LFS64_CFLAGS = 24
+_CS_LFS64_LDFLAGS = 25
+_CS_LFS64_LIBS = 26
+_CS_LFS64_LINTFLAGS = 27
+_CS_ARCHITECTURE = 100
+_CS_BUSTYPES = 101
+_CS_HOSTNAME = 102
+_CS_HW_PROVIDER = 103
+_CS_KERNEL_STAMP = 104
+_CS_MACHINE = 105
+_CS_OS_BASE = 106
+_CS_OS_PROVIDER = 107
+_CS_SYSNAME = 108
+_CS_USER_LIMIT = 109
+_PC_LINK_MAX = 1
+_PC_MAX_CANON = 2
+_PC_MAX_INPUT = 3
+_PC_NAME_MAX = 4
+_PC_PATH_MAX = 5
+_PC_PIPE_BUF = 6
+_PC_NO_TRUNC = 7
+_PC_VDISABLE = 8
+_PC_CHOWN_RESTRICTED = 9
+_PC_FILESIZEBITS = 10
+_POSIX_VERSION = 199009L
+_XOPEN_VERSION = 4
+GF_PATH = "/etc/group"
+PF_PATH = "/etc/passwd"
+F_ULOCK = 0
+F_LOCK = 1
+F_TLOCK = 2
+F_TEST = 3
+_POSIX_JOB_CONTROL = 1
+_POSIX_SAVED_IDS = 1
+_POSIX_VDISABLE = 0
+NULL = 0
+STDIN_FILENO = 0
+STDOUT_FILENO = 1
+STDERR_FILENO = 2
+_XOPEN_UNIX = 1
+_XOPEN_ENH_I18N = 1
+_XOPEN_XPG4 = 1
+_POSIX2_C_VERSION = 199209L
+_POSIX2_VERSION = 199209L
+_XOPEN_XCU_VERSION = 4
+_POSIX_SEMAPHORES = 1
+_POSIX_THREADS = 1
+_POSIX_THREAD_ATTR_STACKADDR = 1
+_POSIX_THREAD_ATTR_STACKSIZE = 1
+_POSIX_THREAD_PRIORITY_SCHEDULING = 1
+_POSIX_THREAD_PROCESS_SHARED = 1
+_POSIX_THREAD_SAFE_FUNCTIONS = 1
+_POSIX2_C_BIND = 1
+_POSIX2_CHAR_TERM = 1
+_POSIX2_FORT_RUN = 1
+_POSIX2_LOCALEDEF = 1
+_POSIX2_UPE = 1
+_LFS_ASYNCHRONOUS_IO = 1
+_LFS_LARGEFILE = 1
+_LFS64_ASYNCHRONOUS_IO = 1
+_LFS64_LARGEFILE = 1
+_LFS64_STDIO = 1
+FMNAMESZ = 8
+SNDZERO = 0x001
+SNDPIPE = 0x002
+RNORM = 0x000
+RMSGD = 0x001
+RMSGN = 0x002
+RMODEMASK = 0x003
+RPROTDAT = 0x004
+RPROTDIS = 0x008
+RPROTNORM = 0x010
+RPROTMASK = 0x01c
+FLUSHR = 0x01
+FLUSHW = 0x02
+FLUSHRW = 0x03
+FLUSHBAND = 0x04
+S_INPUT = 0x0001
+S_HIPRI = 0x0002
+S_OUTPUT = 0x0004
+S_MSG = 0x0008
+S_ERROR = 0x0010
+S_HANGUP = 0x0020
+S_RDNORM = 0x0040
+S_WRNORM = S_OUTPUT
+S_RDBAND = 0x0080
+S_WRBAND = 0x0100
+S_BANDURG = 0x0200
+RS_HIPRI = 0x01
+MSG_HIPRI = 0x01
+MSG_ANY = 0x02
+MSG_BAND = 0x04
+MSG_DISCARD = 0x08
+MSG_PEEKIOCTL = 0x10
+MORECTL = 1
+MOREDATA = 2
+MUXID_ALL = (-1)
+ANYMARK = 0x01
+LASTMARK = 0x02
+STR = (ord('S')<<8)
+I_NREAD = (STR|01)
+I_PUSH = (STR|02)
+I_POP = (STR|03)
+I_LOOK = (STR|04)
+I_FLUSH = (STR|05)
+I_SRDOPT = (STR|06)
+I_GRDOPT = (STR|07)
+I_STR = (STR|010)
+I_SETSIG = (STR|011)
+I_GETSIG = (STR|012)
+I_FIND = (STR|013)
+I_LINK = (STR|014)
+I_UNLINK = (STR|015)
+I_PEEK = (STR|017)
+I_FDINSERT = (STR|020)
+I_SENDFD = (STR|021)
+I_RECVFD = (STR|022)
+I_E_RECVFD = (STR|016)
+I_RECVFD = (STR|016)
+I_RECVFD = (STR|022)
+I_SWROPT = (STR|023)
+I_GWROPT = (STR|024)
+I_LIST = (STR|025)
+I_PLINK = (STR|026)
+I_PUNLINK = (STR|027)
+I_FLUSHBAND = (STR|034)
+I_CKBAND = (STR|035)
+I_GETBAND = (STR|036)
+I_ATMARK = (STR|037)
+I_SETCLTIME = (STR|040)
+I_GETCLTIME = (STR|041)
+I_CANPUT = (STR|042)
+I_S_RECVFD = (STR|043)
+I_STATS = (STR|044)
+I_BIGPIPE = (STR|045)
+I_GETTP = (STR|046)
+INFTIM = -1

Added: vendor/Python/current/Lib/plat-unixware7/regen
===================================================================
--- vendor/Python/current/Lib/plat-unixware7/regen	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/plat-unixware7/regen	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,9 @@
+#! /bin/sh
+case `uname -sr` in
+UnixWare*)	;;
+*)	echo Probably not on a UnixWare system 1>&2
+	exit 1;;
+esac
+set -v
+h2py -i '(u_long)' /usr/include/netinet/in.h
+h2py /usr/include/sys/stropts.h


Property changes on: vendor/Python/current/Lib/plat-unixware7/regen
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/platform.py
===================================================================
--- vendor/Python/current/Lib/platform.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/platform.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1254 @@
+#!/usr/bin/env python
+
+""" This module tries to retrieve as much platform-identifying data as
+    possible. It makes this information available via function APIs.
+
+    If called from the command line, it prints the platform
+    information concatenated as single string to stdout. The output
+    format is useable as part of a filename.
+
+"""
+#    This module is maintained by Marc-Andre Lemburg <mal at egenix.com>.
+#    If you find problems, please submit bug reports/patches via the
+#    Python SourceForge Project Page and assign them to "lemburg".
+#
+#    Note: Please keep this module compatible to Python 1.5.2.
+#
+#    Still needed:
+#    * more support for WinCE
+#    * support for MS-DOS (PythonDX ?)
+#    * support for Amiga and other still unsupported platforms running Python
+#    * support for additional Linux distributions
+#
+#    Many thanks to all those who helped adding platform-specific
+#    checks (in no particular order):
+#
+#      Charles G Waldman, David Arnold, Gordon McMillan, Ben Darnell,
+#      Jeff Bauer, Cliff Crawford, Ivan Van Laningham, Josef
+#      Betancourt, Randall Hopper, Karl Putland, John Farrell, Greg
+#      Andruk, Just van Rossum, Thomas Heller, Mark R. Levinson, Mark
+#      Hammond, Bill Tutt, Hans Nowak, Uwe Zessin (OpenVMS support),
+#      Colin Kong, Trent Mick, Guido van Rossum
+#
+#    History:
+#
+#    <see CVS and SVN checkin messages for history>
+#
+#    1.0.3 - added normalization of Windows system name
+#    1.0.2 - added more Windows support
+#    1.0.1 - reformatted to make doc.py happy
+#    1.0.0 - reformatted a bit and checked into Python CVS
+#    0.8.0 - added sys.version parser and various new access
+#            APIs (python_version(), python_compiler(), etc.)
+#    0.7.2 - fixed architecture() to use sizeof(pointer) where available
+#    0.7.1 - added support for Caldera OpenLinux
+#    0.7.0 - some fixes for WinCE; untabified the source file
+#    0.6.2 - support for OpenVMS - requires version 1.5.2-V006 or higher and
+#            vms_lib.getsyi() configured
+#    0.6.1 - added code to prevent 'uname -p' on platforms which are
+#            known not to support it
+#    0.6.0 - fixed win32_ver() to hopefully work on Win95,98,NT and Win2k;
+#            did some cleanup of the interfaces - some APIs have changed
+#    0.5.5 - fixed another type in the MacOS code... should have
+#            used more coffee today ;-)
+#    0.5.4 - fixed a few typos in the MacOS code
+#    0.5.3 - added experimental MacOS support; added better popen()
+#            workarounds in _syscmd_ver() -- still not 100% elegant
+#            though
+#    0.5.2 - fixed uname() to return '' instead of 'unknown' in all
+#            return values (the system uname command tends to return
+#            'unknown' instead of just leaving the field emtpy)
+#    0.5.1 - included code for slackware dist; added exception handlers
+#            to cover up situations where platforms don't have os.popen
+#            (e.g. Mac) or fail on socket.gethostname(); fixed libc
+#            detection RE
+#    0.5.0 - changed the API names referring to system commands to *syscmd*;
+#            added java_ver(); made syscmd_ver() a private
+#            API (was system_ver() in previous versions) -- use uname()
+#            instead; extended the win32_ver() to also return processor
+#            type information
+#    0.4.0 - added win32_ver() and modified the platform() output for WinXX
+#    0.3.4 - fixed a bug in _follow_symlinks()
+#    0.3.3 - fixed popen() and "file" command invokation bugs
+#    0.3.2 - added architecture() API and support for it in platform()
+#    0.3.1 - fixed syscmd_ver() RE to support Windows NT
+#    0.3.0 - added system alias support
+#    0.2.3 - removed 'wince' again... oh well.
+#    0.2.2 - added 'wince' to syscmd_ver() supported platforms
+#    0.2.1 - added cache logic and changed the platform string format
+#    0.2.0 - changed the API to use functions instead of module globals
+#            since some action take too long to be run on module import
+#    0.1.0 - first release
+#
+#    You can always get the latest version of this module at:
+#
+#             http://www.egenix.com/files/python/platform.py
+#
+#    If that URL should fail, try contacting the author.
+
+__copyright__ = """
+    Copyright (c) 1999-2000, Marc-Andre Lemburg; mailto:mal at lemburg.com
+    Copyright (c) 2000-2003, eGenix.com Software GmbH; mailto:info at egenix.com
+
+    Permission to use, copy, modify, and distribute this software and its
+    documentation for any purpose and without fee or royalty is hereby granted,
+    provided that the above copyright notice appear in all copies and that
+    both that copyright notice and this permission notice appear in
+    supporting documentation or portions thereof, including modifications,
+    that you make.
+
+    EGENIX.COM SOFTWARE GMBH DISCLAIMS ALL WARRANTIES WITH REGARD TO
+    THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+    FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
+    INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+    FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+    NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+    WITH THE USE OR PERFORMANCE OF THIS SOFTWARE !
+
+"""
+
+__version__ = '1.0.4'
+
+import sys,string,os,re
+
+### Platform specific APIs
+
+_libc_search = re.compile(r'(__libc_init)'
+                          '|'
+                          '(GLIBC_([0-9.]+))'
+                          '|'
+                          '(libc(_\w+)?\.so(?:\.(\d[0-9.]*))?)')
+
+def libc_ver(executable=sys.executable,lib='',version='',
+
+             chunksize=2048):
+
+    """ Tries to determine the libc version that the file executable
+        (which defaults to the Python interpreter) is linked against.
+
+        Returns a tuple of strings (lib,version) which default to the
+        given parameters in case the lookup fails.
+
+        Note that the function has intimate knowledge of how different
+        libc versions add symbols to the executable and thus is probably
+        only useable for executables compiled using gcc.
+
+        The file is read and scanned in chunks of chunksize bytes.
+
+    """
+    f = open(executable,'rb')
+    binary = f.read(chunksize)
+    pos = 0
+    while 1:
+        m = _libc_search.search(binary,pos)
+        if not m:
+            binary = f.read(chunksize)
+            if not binary:
+                break
+            pos = 0
+            continue
+        libcinit,glibc,glibcversion,so,threads,soversion = m.groups()
+        if libcinit and not lib:
+            lib = 'libc'
+        elif glibc:
+            if lib != 'glibc':
+                lib = 'glibc'
+                version = glibcversion
+            elif glibcversion > version:
+                version = glibcversion
+        elif so:
+            if lib != 'glibc':
+                lib = 'libc'
+                if soversion > version:
+                    version = soversion
+                if threads and version[-len(threads):] != threads:
+                    version = version + threads
+        pos = m.end()
+    f.close()
+    return lib,version
+
+def _dist_try_harder(distname,version,id):
+
+    """ Tries some special tricks to get the distribution
+        information in case the default method fails.
+
+        Currently supports older SuSE Linux, Caldera OpenLinux and
+        Slackware Linux distributions.
+
+    """
+    if os.path.exists('/var/adm/inst-log/info'):
+        # SuSE Linux stores distribution information in that file
+        info = open('/var/adm/inst-log/info').readlines()
+        distname = 'SuSE'
+        for line in info:
+            tv = string.split(line)
+            if len(tv) == 2:
+                tag,value = tv
+            else:
+                continue
+            if tag == 'MIN_DIST_VERSION':
+                version = string.strip(value)
+            elif tag == 'DIST_IDENT':
+                values = string.split(value,'-')
+                id = values[2]
+        return distname,version,id
+
+    if os.path.exists('/etc/.installed'):
+        # Caldera OpenLinux has some infos in that file (thanks to Colin Kong)
+        info = open('/etc/.installed').readlines()
+        for line in info:
+            pkg = string.split(line,'-')
+            if len(pkg) >= 2 and pkg[0] == 'OpenLinux':
+                # XXX does Caldera support non Intel platforms ? If yes,
+                #     where can we find the needed id ?
+                return 'OpenLinux',pkg[1],id
+
+    if os.path.isdir('/usr/lib/setup'):
+        # Check for slackware verson tag file (thanks to Greg Andruk)
+        verfiles = os.listdir('/usr/lib/setup')
+        for n in range(len(verfiles)-1, -1, -1):
+            if verfiles[n][:14] != 'slack-version-':
+                del verfiles[n]
+        if verfiles:
+            verfiles.sort()
+            distname = 'slackware'
+            version = verfiles[-1][14:]
+            return distname,version,id
+
+    return distname,version,id
+
+_release_filename = re.compile(r'(\w+)[-_](release|version)')
+_release_version = re.compile(r'([\d.]+)[^(]*(?:\((.+)\))?')
+
+# Note:In supported_dists below we need 'fedora' before 'redhat' as in
+# Fedora redhat-release is a link to fedora-release.
+
+def dist(distname='',version='',id='',
+
+         supported_dists=('SuSE', 'debian', 'fedora', 'redhat', 'mandrake')):
+
+    """ Tries to determine the name of the Linux OS distribution name.
+
+        The function first looks for a distribution release file in
+        /etc and then reverts to _dist_try_harder() in case no
+        suitable files are found.
+
+        Returns a tuple (distname,version,id) which default to the
+        args given as parameters.
+
+    """
+    try:
+        etc = os.listdir('/etc')
+    except os.error:
+        # Probably not a Unix system
+        return distname,version,id
+    for file in etc:
+        m = _release_filename.match(file)
+        if m:
+            _distname,dummy = m.groups()
+            if _distname in supported_dists:
+                distname = _distname
+                break
+    else:
+        return _dist_try_harder(distname,version,id)
+    f = open('/etc/'+file,'r')
+    firstline = f.readline()
+    f.close()
+    m = _release_version.search(firstline)
+    if m:
+        _version,_id = m.groups()
+        if _version:
+            version = _version
+        if _id:
+            id = _id
+    else:
+        # Unkown format... take the first two words
+        l = string.split(string.strip(firstline))
+        if l:
+            version = l[0]
+            if len(l) > 1:
+                id = l[1]
+    return distname,version,id
+
+class _popen:
+
+    """ Fairly portable (alternative) popen implementation.
+
+        This is mostly needed in case os.popen() is not available, or
+        doesn't work as advertised, e.g. in Win9X GUI programs like
+        PythonWin or IDLE.
+
+        Writing to the pipe is currently not supported.
+
+    """
+    tmpfile = ''
+    pipe = None
+    bufsize = None
+    mode = 'r'
+
+    def __init__(self,cmd,mode='r',bufsize=None):
+
+        if mode != 'r':
+            raise ValueError,'popen()-emulation only supports read mode'
+        import tempfile
+        self.tmpfile = tmpfile = tempfile.mktemp()
+        os.system(cmd + ' > %s' % tmpfile)
+        self.pipe = open(tmpfile,'rb')
+        self.bufsize = bufsize
+        self.mode = mode
+
+    def read(self):
+
+        return self.pipe.read()
+
+    def readlines(self):
+
+        if self.bufsize is not None:
+            return self.pipe.readlines()
+
+    def close(self,
+
+              remove=os.unlink,error=os.error):
+
+        if self.pipe:
+            rc = self.pipe.close()
+        else:
+            rc = 255
+        if self.tmpfile:
+            try:
+                remove(self.tmpfile)
+            except error:
+                pass
+        return rc
+
+    # Alias
+    __del__ = close
+
+def popen(cmd, mode='r', bufsize=None):
+
+    """ Portable popen() interface.
+    """
+    # Find a working popen implementation preferring win32pipe.popen
+    # over os.popen over _popen
+    popen = None
+    if os.environ.get('OS','') == 'Windows_NT':
+        # On NT win32pipe should work; on Win9x it hangs due to bugs
+        # in the MS C lib (see MS KnowledgeBase article Q150956)
+        try:
+            import win32pipe
+        except ImportError:
+            pass
+        else:
+            popen = win32pipe.popen
+    if popen is None:
+        if hasattr(os,'popen'):
+            popen = os.popen
+            # Check whether it works... it doesn't in GUI programs
+            # on Windows platforms
+            if sys.platform == 'win32': # XXX Others too ?
+                try:
+                    popen('')
+                except os.error:
+                    popen = _popen
+        else:
+            popen = _popen
+    if bufsize is None:
+        return popen(cmd,mode)
+    else:
+        return popen(cmd,mode,bufsize)
+
+def _norm_version(version,build=''):
+
+    """ Normalize the version and build strings and return a single
+        version string using the format major.minor.build (or patchlevel).
+    """
+    l = string.split(version,'.')
+    if build:
+        l.append(build)
+    try:
+        ints = map(int,l)
+    except ValueError:
+        strings = l
+    else:
+        strings = map(str,ints)
+    version = string.join(strings[:3],'.')
+    return version
+
+_ver_output = re.compile(r'(?:([\w ]+) ([\w.]+) '
+                         '.*'
+                         'Version ([\d.]+))')
+
+def _syscmd_ver(system='',release='',version='',
+
+               supported_platforms=('win32','win16','dos','os2')):
+
+    """ Tries to figure out the OS version used and returns
+        a tuple (system,release,version).
+
+        It uses the "ver" shell command for this which is known
+        to exists on Windows, DOS and OS/2. XXX Others too ?
+
+        In case this fails, the given parameters are used as
+        defaults.
+
+    """
+    if sys.platform not in supported_platforms:
+        return system,release,version
+
+    # Try some common cmd strings
+    for cmd in ('ver','command /c ver','cmd /c ver'):
+        try:
+            pipe = popen(cmd)
+            info = pipe.read()
+            if pipe.close():
+                raise os.error,'command failed'
+            # XXX How can I supress shell errors from being written
+            #     to stderr ?
+        except os.error,why:
+            #print 'Command %s failed: %s' % (cmd,why)
+            continue
+        except IOError,why:
+            #print 'Command %s failed: %s' % (cmd,why)
+            continue
+        else:
+            break
+    else:
+        return system,release,version
+
+    # Parse the output
+    info = string.strip(info)
+    m = _ver_output.match(info)
+    if m:
+        system,release,version = m.groups()
+        # Strip trailing dots from version and release
+        if release[-1] == '.':
+            release = release[:-1]
+        if version[-1] == '.':
+            version = version[:-1]
+        # Normalize the version and build strings (eliminating additional
+        # zeros)
+        version = _norm_version(version)
+    return system,release,version
+
+def _win32_getvalue(key,name,default=''):
+
+    """ Read a value for name from the registry key.
+
+        In case this fails, default is returned.
+
+    """
+    from win32api import RegQueryValueEx
+    try:
+        return RegQueryValueEx(key,name)
+    except:
+        return default
+
+def win32_ver(release='',version='',csd='',ptype=''):
+
+    """ Get additional version information from the Windows Registry
+        and return a tuple (version,csd,ptype) referring to version
+        number, CSD level and OS type (multi/single
+        processor).
+
+        As a hint: ptype returns 'Uniprocessor Free' on single
+        processor NT machines and 'Multiprocessor Free' on multi
+        processor machines. The 'Free' refers to the OS version being
+        free of debugging code. It could also state 'Checked' which
+        means the OS version uses debugging code, i.e. code that
+        checks arguments, ranges, etc. (Thomas Heller).
+
+        Note: this function only works if Mark Hammond's win32
+        package is installed and obviously only runs on Win32
+        compatible platforms.
+
+    """
+    # XXX Is there any way to find out the processor type on WinXX ?
+    # XXX Is win32 available on Windows CE ?
+    #
+    # Adapted from code posted by Karl Putland to comp.lang.python.
+    #
+    # The mappings between reg. values and release names can be found
+    # here: http://msdn.microsoft.com/library/en-us/sysinfo/base/osversioninfo_str.asp
+
+    # Import the needed APIs
+    try:
+        import win32api
+    except ImportError:
+        return release,version,csd,ptype
+    from win32api import RegQueryValueEx,RegOpenKeyEx,RegCloseKey,GetVersionEx
+    from win32con import HKEY_LOCAL_MACHINE,VER_PLATFORM_WIN32_NT,\
+                         VER_PLATFORM_WIN32_WINDOWS
+
+    # Find out the registry key and some general version infos
+    maj,min,buildno,plat,csd = GetVersionEx()
+    version = '%i.%i.%i' % (maj,min,buildno & 0xFFFF)
+    if csd[:13] == 'Service Pack ':
+        csd = 'SP' + csd[13:]
+    if plat == VER_PLATFORM_WIN32_WINDOWS:
+        regkey = 'SOFTWARE\\Microsoft\\Windows\\CurrentVersion'
+        # Try to guess the release name
+        if maj == 4:
+            if min == 0:
+                release = '95'
+            elif min == 10:
+                release = '98'
+            elif min == 90:
+                release = 'Me'
+            else:
+                release = 'postMe'
+        elif maj == 5:
+            release = '2000'
+    elif plat == VER_PLATFORM_WIN32_NT:
+        regkey = 'SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion'
+        if maj <= 4:
+            release = 'NT'
+        elif maj == 5:
+            if min == 0:
+                release = '2000'
+            elif min == 1:
+                release = 'XP'
+            elif min == 2:
+                release = '2003Server'
+            else:
+                release = 'post2003'
+    else:
+        if not release:
+            # E.g. Win3.1 with win32s
+            release = '%i.%i' % (maj,min)
+        return release,version,csd,ptype
+
+    # Open the registry key
+    try:
+        keyCurVer = RegOpenKeyEx(HKEY_LOCAL_MACHINE,regkey)
+        # Get a value to make sure the key exists...
+        RegQueryValueEx(keyCurVer,'SystemRoot')
+    except:
+        return release,version,csd,ptype
+
+    # Parse values
+    #subversion = _win32_getvalue(keyCurVer,
+    #                            'SubVersionNumber',
+    #                            ('',1))[0]
+    #if subversion:
+    #   release = release + subversion # 95a, 95b, etc.
+    build = _win32_getvalue(keyCurVer,
+                            'CurrentBuildNumber',
+                            ('',1))[0]
+    ptype = _win32_getvalue(keyCurVer,
+                           'CurrentType',
+                           (ptype,1))[0]
+
+    # Normalize version
+    version = _norm_version(version,build)
+
+    # Close key
+    RegCloseKey(keyCurVer)
+    return release,version,csd,ptype
+
+def _mac_ver_lookup(selectors,default=None):
+
+    from gestalt import gestalt
+    import MacOS
+    l = []
+    append = l.append
+    for selector in selectors:
+        try:
+            append(gestalt(selector))
+        except (RuntimeError, MacOS.Error):
+            append(default)
+    return l
+
+def _bcd2str(bcd):
+
+    return hex(bcd)[2:]
+
+def mac_ver(release='',versioninfo=('','',''),machine=''):
+
+    """ Get MacOS version information and return it as tuple (release,
+        versioninfo, machine) with versioninfo being a tuple (version,
+        dev_stage, non_release_version).
+
+        Entries which cannot be determined are set to the paramter values
+        which default to ''. All tuple entries are strings.
+
+        Thanks to Mark R. Levinson for mailing documentation links and
+        code examples for this function. Documentation for the
+        gestalt() API is available online at:
+
+           http://www.rgaros.nl/gestalt/
+
+    """
+    # Check whether the version info module is available
+    try:
+        import gestalt
+        import MacOS
+    except ImportError:
+        return release,versioninfo,machine
+    # Get the infos
+    sysv,sysu,sysa = _mac_ver_lookup(('sysv','sysu','sysa'))
+    # Decode the infos
+    if sysv:
+        major = (sysv & 0xFF00) >> 8
+        minor = (sysv & 0x00F0) >> 4
+        patch = (sysv & 0x000F)
+        release = '%s.%i.%i' % (_bcd2str(major),minor,patch)
+    if sysu:
+        major =  int((sysu & 0xFF000000L) >> 24)
+        minor =  (sysu & 0x00F00000) >> 20
+        bugfix = (sysu & 0x000F0000) >> 16
+        stage =  (sysu & 0x0000FF00) >> 8
+        nonrel = (sysu & 0x000000FF)
+        version = '%s.%i.%i' % (_bcd2str(major),minor,bugfix)
+        nonrel = _bcd2str(nonrel)
+        stage = {0x20:'development',
+                 0x40:'alpha',
+                 0x60:'beta',
+                 0x80:'final'}.get(stage,'')
+        versioninfo = (version,stage,nonrel)
+    if sysa:
+        machine = {0x1: '68k',
+                   0x2: 'PowerPC',
+                   0xa: 'i386'}.get(sysa,'')
+    return release,versioninfo,machine
+
+def _java_getprop(name,default):
+
+    from java.lang import System
+    try:
+        return System.getProperty(name)
+    except:
+        return default
+
+def java_ver(release='',vendor='',vminfo=('','',''),osinfo=('','','')):
+
+    """ Version interface for Jython.
+
+        Returns a tuple (release,vendor,vminfo,osinfo) with vminfo being
+        a tuple (vm_name,vm_release,vm_vendor) and osinfo being a
+        tuple (os_name,os_version,os_arch).
+
+        Values which cannot be determined are set to the defaults
+        given as parameters (which all default to '').
+
+    """
+    # Import the needed APIs
+    try:
+        import java.lang
+    except ImportError:
+        return release,vendor,vminfo,osinfo
+
+    vendor = _java_getprop('java.vendor',vendor)
+    release = _java_getprop('java.version',release)
+    vm_name,vm_release,vm_vendor = vminfo
+    vm_name = _java_getprop('java.vm.name',vm_name)
+    vm_vendor = _java_getprop('java.vm.vendor',vm_vendor)
+    vm_release = _java_getprop('java.vm.version',vm_release)
+    vminfo = vm_name,vm_release,vm_vendor
+    os_name,os_version,os_arch = osinfo
+    os_arch = _java_getprop('java.os.arch',os_arch)
+    os_name = _java_getprop('java.os.name',os_name)
+    os_version = _java_getprop('java.os.version',os_version)
+    osinfo = os_name,os_version,os_arch
+
+    return release,vendor,vminfo,osinfo
+
+### System name aliasing
+
+def system_alias(system,release,version):
+
+    """ Returns (system,release,version) aliased to common
+        marketing names used for some systems.
+
+        It also does some reordering of the information in some cases
+        where it would otherwise cause confusion.
+
+    """
+    if system == 'Rhapsody':
+        # Apple's BSD derivative
+        # XXX How can we determine the marketing release number ?
+        return 'MacOS X Server',system+release,version
+
+    elif system == 'SunOS':
+        # Sun's OS
+        if release < '5':
+            # These releases use the old name SunOS
+            return system,release,version
+        # Modify release (marketing release = SunOS release - 3)
+        l = string.split(release,'.')
+        if l:
+            try:
+                major = int(l[0])
+            except ValueError:
+                pass
+            else:
+                major = major - 3
+                l[0] = str(major)
+                release = string.join(l,'.')
+        if release < '6':
+            system = 'Solaris'
+        else:
+            # XXX Whatever the new SunOS marketing name is...
+            system = 'Solaris'
+
+    elif system == 'IRIX64':
+        # IRIX reports IRIX64 on platforms with 64-bit support; yet it
+        # is really a version and not a different platform, since 32-bit
+        # apps are also supported..
+        system = 'IRIX'
+        if version:
+            version = version + ' (64bit)'
+        else:
+            version = '64bit'
+
+    elif system in ('win32','win16'):
+        # In case one of the other tricks
+        system = 'Windows'
+
+    return system,release,version
+
+### Various internal helpers
+
+def _platform(*args):
+
+    """ Helper to format the platform string in a filename
+        compatible format e.g. "system-version-machine".
+    """
+    # Format the platform string
+    platform = string.join(
+        map(string.strip,
+            filter(len,args)),
+        '-')
+
+    # Cleanup some possible filename obstacles...
+    replace = string.replace
+    platform = replace(platform,' ','_')
+    platform = replace(platform,'/','-')
+    platform = replace(platform,'\\','-')
+    platform = replace(platform,':','-')
+    platform = replace(platform,';','-')
+    platform = replace(platform,'"','-')
+    platform = replace(platform,'(','-')
+    platform = replace(platform,')','-')
+
+    # No need to report 'unknown' information...
+    platform = replace(platform,'unknown','')
+
+    # Fold '--'s and remove trailing '-'
+    while 1:
+        cleaned = replace(platform,'--','-')
+        if cleaned == platform:
+            break
+        platform = cleaned
+    while platform[-1] == '-':
+        platform = platform[:-1]
+
+    return platform
+
+def _node(default=''):
+
+    """ Helper to determine the node name of this machine.
+    """
+    try:
+        import socket
+    except ImportError:
+        # No sockets...
+        return default
+    try:
+        return socket.gethostname()
+    except socket.error:
+        # Still not working...
+        return default
+
+# os.path.abspath is new in Python 1.5.2:
+if not hasattr(os.path,'abspath'):
+
+    def _abspath(path,
+
+                 isabs=os.path.isabs,join=os.path.join,getcwd=os.getcwd,
+                 normpath=os.path.normpath):
+
+        if not isabs(path):
+            path = join(getcwd(), path)
+        return normpath(path)
+
+else:
+
+    _abspath = os.path.abspath
+
+def _follow_symlinks(filepath):
+
+    """ In case filepath is a symlink, follow it until a
+        real file is reached.
+    """
+    filepath = _abspath(filepath)
+    while os.path.islink(filepath):
+        filepath = os.path.normpath(
+            os.path.join(filepath,os.readlink(filepath)))
+    return filepath
+
+def _syscmd_uname(option,default=''):
+
+    """ Interface to the system's uname command.
+    """
+    if sys.platform in ('dos','win32','win16','os2'):
+        # XXX Others too ?
+        return default
+    try:
+        f = os.popen('uname %s 2> /dev/null' % option)
+    except (AttributeError,os.error):
+        return default
+    output = string.strip(f.read())
+    rc = f.close()
+    if not output or rc:
+        return default
+    else:
+        return output
+
+def _syscmd_file(target,default=''):
+
+    """ Interface to the system's file command.
+
+        The function uses the -b option of the file command to have it
+        ommit the filename in its output and if possible the -L option
+        to have the command follow symlinks. It returns default in
+        case the command should fail.
+
+    """
+    target = _follow_symlinks(target)
+    try:
+        f = os.popen('file %s 2> /dev/null' % target)
+    except (AttributeError,os.error):
+        return default
+    output = string.strip(f.read())
+    rc = f.close()
+    if not output or rc:
+        return default
+    else:
+        return output
+
+### Information about the used architecture
+
+# Default values for architecture; non-empty strings override the
+# defaults given as parameters
+_default_architecture = {
+    'win32': ('','WindowsPE'),
+    'win16': ('','Windows'),
+    'dos': ('','MSDOS'),
+}
+
+_architecture_split = re.compile(r'[\s,]').split
+
+def architecture(executable=sys.executable,bits='',linkage=''):
+
+    """ Queries the given executable (defaults to the Python interpreter
+        binary) for various architecture information.
+
+        Returns a tuple (bits,linkage) which contains information about
+        the bit architecture and the linkage format used for the
+        executable. Both values are returned as strings.
+
+        Values that cannot be determined are returned as given by the
+        parameter presets. If bits is given as '', the sizeof(pointer)
+        (or sizeof(long) on Python version < 1.5.2) is used as
+        indicator for the supported pointer size.
+
+        The function relies on the system's "file" command to do the
+        actual work. This is available on most if not all Unix
+        platforms. On some non-Unix platforms where the "file" command
+        does not exist and the executable is set to the Python interpreter
+        binary defaults from _default_architecture are used.
+
+    """
+    # Use the sizeof(pointer) as default number of bits if nothing
+    # else is given as default.
+    if not bits:
+        import struct
+        try:
+            size = struct.calcsize('P')
+        except struct.error:
+            # Older installations can only query longs
+            size = struct.calcsize('l')
+        bits = str(size*8) + 'bit'
+
+    # Get data from the 'file' system command
+    output = _syscmd_file(executable,'')
+
+    if not output and \
+       executable == sys.executable:
+        # "file" command did not return anything; we'll try to provide
+        # some sensible defaults then...
+        if _default_architecture.has_key(sys.platform):
+            b,l = _default_architecture[sys.platform]
+            if b:
+                bits = b
+            if l:
+                linkage = l
+        return bits,linkage
+
+    # Split the output into a list of strings omitting the filename
+    fileout = _architecture_split(output)[1:]
+
+    if 'executable' not in fileout:
+        # Format not supported
+        return bits,linkage
+
+    # Bits
+    if '32-bit' in fileout:
+        bits = '32bit'
+    elif 'N32' in fileout:
+        # On Irix only
+        bits = 'n32bit'
+    elif '64-bit' in fileout:
+        bits = '64bit'
+
+    # Linkage
+    if 'ELF' in fileout:
+        linkage = 'ELF'
+    elif 'PE' in fileout:
+        # E.g. Windows uses this format
+        if 'Windows' in fileout:
+            linkage = 'WindowsPE'
+        else:
+            linkage = 'PE'
+    elif 'COFF' in fileout:
+        linkage = 'COFF'
+    elif 'MS-DOS' in fileout:
+        linkage = 'MSDOS'
+    else:
+        # XXX the A.OUT format also falls under this class...
+        pass
+
+    return bits,linkage
+
+### Portable uname() interface
+
+_uname_cache = None
+
+def uname():
+
+    """ Fairly portable uname interface. Returns a tuple
+        of strings (system,node,release,version,machine,processor)
+        identifying the underlying platform.
+
+        Note that unlike the os.uname function this also returns
+        possible processor information as an additional tuple entry.
+
+        Entries which cannot be determined are set to ''.
+
+    """
+    global _uname_cache
+
+    if _uname_cache is not None:
+        return _uname_cache
+
+    # Get some infos from the builtin os.uname API...
+    try:
+        system,node,release,version,machine = os.uname()
+
+    except AttributeError:
+        # Hmm, no uname... we'll have to poke around the system then.
+        system = sys.platform
+        release = ''
+        version = ''
+        node = _node()
+        machine = ''
+        processor = ''
+        use_syscmd_ver = 1
+
+        # Try win32_ver() on win32 platforms
+        if system == 'win32':
+            release,version,csd,ptype = win32_ver()
+            if release and version:
+                use_syscmd_ver = 0
+
+        # Try the 'ver' system command available on some
+        # platforms
+        if use_syscmd_ver:
+            system,release,version = _syscmd_ver(system)
+            # Normalize system to what win32_ver() normally returns
+            # (_syscmd_ver() tends to return the vendor name as well)
+            if system == 'Microsoft Windows':
+                system = 'Windows'
+
+        # In case we still don't know anything useful, we'll try to
+        # help ourselves
+        if system in ('win32','win16'):
+            if not version:
+                if system == 'win32':
+                    version = '32bit'
+                else:
+                    version = '16bit'
+            system = 'Windows'
+
+        elif system[:4] == 'java':
+            release,vendor,vminfo,osinfo = java_ver()
+            system = 'Java'
+            version = string.join(vminfo,', ')
+            if not version:
+                version = vendor
+
+        elif os.name == 'mac':
+            release,(version,stage,nonrel),machine = mac_ver()
+            system = 'MacOS'
+
+    else:
+        # System specific extensions
+        if system == 'OpenVMS':
+            # OpenVMS seems to have release and version mixed up
+            if not release or release == '0':
+                release = version
+                version = ''
+            # Get processor information
+            try:
+                import vms_lib
+            except ImportError:
+                pass
+            else:
+                csid, cpu_number = vms_lib.getsyi('SYI$_CPU',0)
+                if (cpu_number >= 128):
+                    processor = 'Alpha'
+                else:
+                    processor = 'VAX'
+        else:
+            # Get processor information from the uname system command
+            processor = _syscmd_uname('-p','')
+
+    # 'unknown' is not really any useful as information; we'll convert
+    # it to '' which is more portable
+    if system == 'unknown':
+        system = ''
+    if node == 'unknown':
+        node = ''
+    if release == 'unknown':
+        release = ''
+    if version == 'unknown':
+        version = ''
+    if machine == 'unknown':
+        machine = ''
+    if processor == 'unknown':
+        processor = ''
+    _uname_cache = system,node,release,version,machine,processor
+    return _uname_cache
+
+### Direct interfaces to some of the uname() return values
+
+def system():
+
+    """ Returns the system/OS name, e.g. 'Linux', 'Windows' or 'Java'.
+
+        An empty string is returned if the value cannot be determined.
+
+    """
+    return uname()[0]
+
+def node():
+
+    """ Returns the computer's network name (which may not be fully
+        qualified)
+
+        An empty string is returned if the value cannot be determined.
+
+    """
+    return uname()[1]
+
+def release():
+
+    """ Returns the system's release, e.g. '2.2.0' or 'NT'
+
+        An empty string is returned if the value cannot be determined.
+
+    """
+    return uname()[2]
+
+def version():
+
+    """ Returns the system's release version, e.g. '#3 on degas'
+
+        An empty string is returned if the value cannot be determined.
+
+    """
+    return uname()[3]
+
+def machine():
+
+    """ Returns the machine type, e.g. 'i386'
+
+        An empty string is returned if the value cannot be determined.
+
+    """
+    return uname()[4]
+
+def processor():
+
+    """ Returns the (true) processor name, e.g. 'amdk6'
+
+        An empty string is returned if the value cannot be
+        determined. Note that many platforms do not provide this
+        information or simply return the same value as for machine(),
+        e.g.  NetBSD does this.
+
+    """
+    return uname()[5]
+
+### Various APIs for extracting information from sys.version
+
+_sys_version_parser = re.compile(r'([\w.+]+)\s*'
+                                  '\(#?([^,]+),\s*([\w ]+),\s*([\w :]+)\)\s*'
+                                  '\[([^\]]+)\]?')
+_sys_version_cache = None
+
+def _sys_version():
+
+    """ Returns a parsed version of Python's sys.version as tuple
+        (version, buildno, builddate, compiler) referring to the Python
+        version, build number, build date/time as string and the compiler
+        identification string.
+
+        Note that unlike the Python sys.version, the returned value
+        for the Python version will always include the patchlevel (it
+        defaults to '.0').
+
+    """
+    global _sys_version_cache
+
+    if _sys_version_cache is not None:
+        return _sys_version_cache
+    version, buildno, builddate, buildtime, compiler = \
+             _sys_version_parser.match(sys.version).groups()
+    builddate = builddate + ' ' + buildtime
+    l = string.split(version, '.')
+    if len(l) == 2:
+        l.append('0')
+        version = string.join(l, '.')
+    _sys_version_cache = (version, buildno, builddate, compiler)
+    return _sys_version_cache
+
+def python_version():
+
+    """ Returns the Python version as string 'major.minor.patchlevel'
+
+        Note that unlike the Python sys.version, the returned value
+        will always include the patchlevel (it defaults to 0).
+
+    """
+    return _sys_version()[0]
+
+def python_version_tuple():
+
+    """ Returns the Python version as tuple (major, minor, patchlevel)
+        of strings.
+
+        Note that unlike the Python sys.version, the returned value
+        will always include the patchlevel (it defaults to 0).
+
+    """
+    return string.split(_sys_version()[0], '.')
+
+def python_build():
+
+    """ Returns a tuple (buildno, builddate) stating the Python
+        build number and date as strings.
+
+    """
+    return _sys_version()[1:3]
+
+def python_compiler():
+
+    """ Returns a string identifying the compiler used for compiling
+        Python.
+
+    """
+    return _sys_version()[3]
+
+### The Opus Magnum of platform strings :-)
+
+_platform_cache = {}
+
+def platform(aliased=0, terse=0):
+
+    """ Returns a single string identifying the underlying platform
+        with as much useful information as possible (but no more :).
+
+        The output is intended to be human readable rather than
+        machine parseable. It may look different on different
+        platforms and this is intended.
+
+        If "aliased" is true, the function will use aliases for
+        various platforms that report system names which differ from
+        their common names, e.g. SunOS will be reported as
+        Solaris. The system_alias() function is used to implement
+        this.
+
+        Setting terse to true causes the function to return only the
+        absolute minimum information needed to identify the platform.
+
+    """
+    result = _platform_cache.get((aliased, terse), None)
+    if result is not None:
+        return result
+
+    # Get uname information and then apply platform specific cosmetics
+    # to it...
+    system,node,release,version,machine,processor = uname()
+    if machine == processor:
+        processor = ''
+    if aliased:
+        system,release,version = system_alias(system,release,version)
+
+    if system == 'Windows':
+        # MS platforms
+        rel,vers,csd,ptype = win32_ver(version)
+        if terse:
+            platform = _platform(system,release)
+        else:
+            platform = _platform(system,release,version,csd)
+
+    elif system in ('Linux',):
+        # Linux based systems
+        distname,distversion,distid = dist('')
+        if distname and not terse:
+            platform = _platform(system,release,machine,processor,
+                                 'with',
+                                 distname,distversion,distid)
+        else:
+            # If the distribution name is unknown check for libc vs. glibc
+            libcname,libcversion = libc_ver(sys.executable)
+            platform = _platform(system,release,machine,processor,
+                                 'with',
+                                 libcname+libcversion)
+    elif system == 'Java':
+        # Java platforms
+        r,v,vminfo,(os_name,os_version,os_arch) = java_ver()
+        if terse:
+            platform = _platform(system,release,version)
+        else:
+            platform = _platform(system,release,version,
+                                 'on',
+                                 os_name,os_version,os_arch)
+
+    elif system == 'MacOS':
+        # MacOS platforms
+        if terse:
+            platform = _platform(system,release)
+        else:
+            platform = _platform(system,release,machine)
+
+    else:
+        # Generic handler
+        if terse:
+            platform = _platform(system,release)
+        else:
+            bits,linkage = architecture(sys.executable)
+            platform = _platform(system,release,machine,processor,bits,linkage)
+
+    _platform_cache[(aliased, terse)] = platform
+    return platform
+
+### Command line interface
+
+if __name__ == '__main__':
+    # Default is to print the aliased verbose platform string
+    terse = ('terse' in sys.argv or '--terse' in sys.argv)
+    aliased = (not 'nonaliased' in sys.argv and not '--nonaliased' in sys.argv)
+    print platform(aliased,terse)
+    sys.exit(0)


Property changes on: vendor/Python/current/Lib/platform.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/popen2.py
===================================================================
--- vendor/Python/current/Lib/popen2.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/popen2.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,244 @@
+"""Spawn a command with pipes to its stdin, stdout, and optionally stderr.
+
+The normal os.popen(cmd, mode) call spawns a shell command and provides a
+file interface to just the input or output of the process depending on
+whether mode is 'r' or 'w'.  This module provides the functions popen2(cmd)
+and popen3(cmd) which return two or three pipes to the spawned command.
+"""
+
+import os
+import sys
+
+__all__ = ["popen2", "popen3", "popen4"]
+
+try:
+    MAXFD = os.sysconf('SC_OPEN_MAX')
+except (AttributeError, ValueError):
+    MAXFD = 256
+
+_active = []
+
+def _cleanup():
+    for inst in _active[:]:
+        if inst.poll(_deadstate=sys.maxint) >= 0:
+            try:
+                _active.remove(inst)
+            except ValueError:
+                # This can happen if two threads create a new Popen instance.
+                # It's harmless that it was already removed, so ignore.
+                pass
+
+class Popen3:
+    """Class representing a child process.  Normally instances are created
+    by the factory functions popen2() and popen3()."""
+
+    sts = -1                    # Child not completed yet
+
+    def __init__(self, cmd, capturestderr=False, bufsize=-1):
+        """The parameter 'cmd' is the shell command to execute in a
+        sub-process.  On UNIX, 'cmd' may be a sequence, in which case arguments
+        will be passed directly to the program without shell intervention (as
+        with os.spawnv()).  If 'cmd' is a string it will be passed to the shell
+        (as with os.system()).   The 'capturestderr' flag, if true, specifies
+        that the object should capture standard error output of the child
+        process.  The default is false.  If the 'bufsize' parameter is
+        specified, it specifies the size of the I/O buffers to/from the child
+        process."""
+        _cleanup()
+        self.cmd = cmd
+        p2cread, p2cwrite = os.pipe()
+        c2pread, c2pwrite = os.pipe()
+        if capturestderr:
+            errout, errin = os.pipe()
+        self.pid = os.fork()
+        if self.pid == 0:
+            # Child
+            os.dup2(p2cread, 0)
+            os.dup2(c2pwrite, 1)
+            if capturestderr:
+                os.dup2(errin, 2)
+            self._run_child(cmd)
+        os.close(p2cread)
+        self.tochild = os.fdopen(p2cwrite, 'w', bufsize)
+        os.close(c2pwrite)
+        self.fromchild = os.fdopen(c2pread, 'r', bufsize)
+        if capturestderr:
+            os.close(errin)
+            self.childerr = os.fdopen(errout, 'r', bufsize)
+        else:
+            self.childerr = None
+
+    def __del__(self):
+        # In case the child hasn't been waited on, check if it's done.
+        self.poll(_deadstate=sys.maxint)
+        if self.sts < 0:
+            if _active is not None:
+                # Child is still running, keep us alive until we can wait on it.
+                _active.append(self)
+
+    def _run_child(self, cmd):
+        if isinstance(cmd, basestring):
+            cmd = ['/bin/sh', '-c', cmd]
+        for i in xrange(3, MAXFD):
+            try:
+                os.close(i)
+            except OSError:
+                pass
+        try:
+            os.execvp(cmd[0], cmd)
+        finally:
+            os._exit(1)
+
+    def poll(self, _deadstate=None):
+        """Return the exit status of the child process if it has finished,
+        or -1 if it hasn't finished yet."""
+        if self.sts < 0:
+            try:
+                pid, sts = os.waitpid(self.pid, os.WNOHANG)
+                # pid will be 0 if self.pid hasn't terminated
+                if pid == self.pid:
+                    self.sts = sts
+            except os.error:
+                if _deadstate is not None:
+                    self.sts = _deadstate
+        return self.sts
+
+    def wait(self):
+        """Wait for and return the exit status of the child process."""
+        if self.sts < 0:
+            pid, sts = os.waitpid(self.pid, 0)
+            # This used to be a test, but it is believed to be
+            # always true, so I changed it to an assertion - mvl
+            assert pid == self.pid
+            self.sts = sts
+        return self.sts
+
+
+class Popen4(Popen3):
+    childerr = None
+
+    def __init__(self, cmd, bufsize=-1):
+        _cleanup()
+        self.cmd = cmd
+        p2cread, p2cwrite = os.pipe()
+        c2pread, c2pwrite = os.pipe()
+        self.pid = os.fork()
+        if self.pid == 0:
+            # Child
+            os.dup2(p2cread, 0)
+            os.dup2(c2pwrite, 1)
+            os.dup2(c2pwrite, 2)
+            self._run_child(cmd)
+        os.close(p2cread)
+        self.tochild = os.fdopen(p2cwrite, 'w', bufsize)
+        os.close(c2pwrite)
+        self.fromchild = os.fdopen(c2pread, 'r', bufsize)
+
+
+if sys.platform[:3] == "win" or sys.platform == "os2emx":
+    # Some things don't make sense on non-Unix platforms.
+    del Popen3, Popen4
+
+    def popen2(cmd, bufsize=-1, mode='t'):
+        """Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd' may
+        be a sequence, in which case arguments will be passed directly to the
+        program without shell intervention (as with os.spawnv()). If 'cmd' is a
+        string it will be passed to the shell (as with os.system()). If
+        'bufsize' is specified, it sets the buffer size for the I/O pipes. The
+        file objects (child_stdout, child_stdin) are returned."""
+        w, r = os.popen2(cmd, mode, bufsize)
+        return r, w
+
+    def popen3(cmd, bufsize=-1, mode='t'):
+        """Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd' may
+        be a sequence, in which case arguments will be passed directly to the
+        program without shell intervention (as with os.spawnv()). If 'cmd' is a
+        string it will be passed to the shell (as with os.system()). If
+        'bufsize' is specified, it sets the buffer size for the I/O pipes. The
+        file objects (child_stdout, child_stdin, child_stderr) are returned."""
+        w, r, e = os.popen3(cmd, mode, bufsize)
+        return r, w, e
+
+    def popen4(cmd, bufsize=-1, mode='t'):
+        """Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd' may
+        be a sequence, in which case arguments will be passed directly to the
+        program without shell intervention (as with os.spawnv()). If 'cmd' is a
+        string it will be passed to the shell (as with os.system()). If
+        'bufsize' is specified, it sets the buffer size for the I/O pipes. The
+        file objects (child_stdout_stderr, child_stdin) are returned."""
+        w, r = os.popen4(cmd, mode, bufsize)
+        return r, w
+else:
+    def popen2(cmd, bufsize=-1, mode='t'):
+        """Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd' may
+        be a sequence, in which case arguments will be passed directly to the
+        program without shell intervention (as with os.spawnv()). If 'cmd' is a
+        string it will be passed to the shell (as with os.system()). If
+        'bufsize' is specified, it sets the buffer size for the I/O pipes. The
+        file objects (child_stdout, child_stdin) are returned."""
+        inst = Popen3(cmd, False, bufsize)
+        return inst.fromchild, inst.tochild
+
+    def popen3(cmd, bufsize=-1, mode='t'):
+        """Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd' may
+        be a sequence, in which case arguments will be passed directly to the
+        program without shell intervention (as with os.spawnv()). If 'cmd' is a
+        string it will be passed to the shell (as with os.system()). If
+        'bufsize' is specified, it sets the buffer size for the I/O pipes. The
+        file objects (child_stdout, child_stdin, child_stderr) are returned."""
+        inst = Popen3(cmd, True, bufsize)
+        return inst.fromchild, inst.tochild, inst.childerr
+
+    def popen4(cmd, bufsize=-1, mode='t'):
+        """Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd' may
+        be a sequence, in which case arguments will be passed directly to the
+        program without shell intervention (as with os.spawnv()). If 'cmd' is a
+        string it will be passed to the shell (as with os.system()). If
+        'bufsize' is specified, it sets the buffer size for the I/O pipes. The
+        file objects (child_stdout_stderr, child_stdin) are returned."""
+        inst = Popen4(cmd, bufsize)
+        return inst.fromchild, inst.tochild
+
+    __all__.extend(["Popen3", "Popen4"])
+
+def _test():
+    # When the test runs, there shouldn't be any open pipes
+    _cleanup()
+    assert not _active, "Active pipes when test starts " + repr([c.cmd for c in _active])
+    cmd  = "cat"
+    teststr = "ab cd\n"
+    if os.name == "nt":
+        cmd = "more"
+    # "more" doesn't act the same way across Windows flavors,
+    # sometimes adding an extra newline at the start or the
+    # end.  So we strip whitespace off both ends for comparison.
+    expected = teststr.strip()
+    print "testing popen2..."
+    r, w = popen2(cmd)
+    w.write(teststr)
+    w.close()
+    got = r.read()
+    if got.strip() != expected:
+        raise ValueError("wrote %r read %r" % (teststr, got))
+    print "testing popen3..."
+    try:
+        r, w, e = popen3([cmd])
+    except:
+        r, w, e = popen3(cmd)
+    w.write(teststr)
+    w.close()
+    got = r.read()
+    if got.strip() != expected:
+        raise ValueError("wrote %r read %r" % (teststr, got))
+    got = e.read()
+    if got:
+        raise ValueError("unexpected %r on stderr" % (got,))
+    for inst in _active[:]:
+        inst.wait()
+    _cleanup()
+    if _active:
+        raise ValueError("_active not empty")
+    print "All OK"
+
+if __name__ == '__main__':
+    _test()

Added: vendor/Python/current/Lib/poplib.py
===================================================================
--- vendor/Python/current/Lib/poplib.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/poplib.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,423 @@
+"""A POP3 client class.
+
+Based on the J. Myers POP3 draft, Jan. 96
+"""
+
+# Author: David Ascher <david_ascher at brown.edu>
+#         [heavily stealing from nntplib.py]
+# Updated: Piers Lauder <piers at cs.su.oz.au> [Jul '97]
+# String method conversion and test jig improvements by ESR, February 2001.
+# Added the POP3_SSL class. Methods loosely based on IMAP_SSL. Hector Urtubia <urtubia at mrbook.org> Aug 2003
+
+# Example (see the test function at the end of this file)
+
+# Imports
+
+import re, socket
+
+__all__ = ["POP3","error_proto","POP3_SSL"]
+
+# Exception raised when an error or invalid response is received:
+
+class error_proto(Exception): pass
+
+# Standard Port
+POP3_PORT = 110
+
+# POP SSL PORT
+POP3_SSL_PORT = 995
+
+# Line terminators (we always output CRLF, but accept any of CRLF, LFCR, LF)
+CR = '\r'
+LF = '\n'
+CRLF = CR+LF
+
+
+class POP3:
+
+    """This class supports both the minimal and optional command sets.
+    Arguments can be strings or integers (where appropriate)
+    (e.g.: retr(1) and retr('1') both work equally well.
+
+    Minimal Command Set:
+            USER name               user(name)
+            PASS string             pass_(string)
+            STAT                    stat()
+            LIST [msg]              list(msg = None)
+            RETR msg                retr(msg)
+            DELE msg                dele(msg)
+            NOOP                    noop()
+            RSET                    rset()
+            QUIT                    quit()
+
+    Optional Commands (some servers support these):
+            RPOP name               rpop(name)
+            APOP name digest        apop(name, digest)
+            TOP msg n               top(msg, n)
+            UIDL [msg]              uidl(msg = None)
+
+    Raises one exception: 'error_proto'.
+
+    Instantiate with:
+            POP3(hostname, port=110)
+
+    NB:     the POP protocol locks the mailbox from user
+            authorization until QUIT, so be sure to get in, suck
+            the messages, and quit, each time you access the
+            mailbox.
+
+            POP is a line-based protocol, which means large mail
+            messages consume lots of python cycles reading them
+            line-by-line.
+
+            If it's available on your mail server, use IMAP4
+            instead, it doesn't suffer from the two problems
+            above.
+    """
+
+
+    def __init__(self, host, port = POP3_PORT):
+        self.host = host
+        self.port = port
+        msg = "getaddrinfo returns an empty list"
+        self.sock = None
+        for res in socket.getaddrinfo(self.host, self.port, 0, socket.SOCK_STREAM):
+            af, socktype, proto, canonname, sa = res
+            try:
+                self.sock = socket.socket(af, socktype, proto)
+                self.sock.connect(sa)
+            except socket.error, msg:
+                if self.sock:
+                    self.sock.close()
+                self.sock = None
+                continue
+            break
+        if not self.sock:
+            raise socket.error, msg
+        self.file = self.sock.makefile('rb')
+        self._debugging = 0
+        self.welcome = self._getresp()
+
+
+    def _putline(self, line):
+        if self._debugging > 1: print '*put*', repr(line)
+        self.sock.sendall('%s%s' % (line, CRLF))
+
+
+    # Internal: send one command to the server (through _putline())
+
+    def _putcmd(self, line):
+        if self._debugging: print '*cmd*', repr(line)
+        self._putline(line)
+
+
+    # Internal: return one line from the server, stripping CRLF.
+    # This is where all the CPU time of this module is consumed.
+    # Raise error_proto('-ERR EOF') if the connection is closed.
+
+    def _getline(self):
+        line = self.file.readline()
+        if self._debugging > 1: print '*get*', repr(line)
+        if not line: raise error_proto('-ERR EOF')
+        octets = len(line)
+        # server can send any combination of CR & LF
+        # however, 'readline()' returns lines ending in LF
+        # so only possibilities are ...LF, ...CRLF, CR...LF
+        if line[-2:] == CRLF:
+            return line[:-2], octets
+        if line[0] == CR:
+            return line[1:-1], octets
+        return line[:-1], octets
+
+
+    # Internal: get a response from the server.
+    # Raise 'error_proto' if the response doesn't start with '+'.
+
+    def _getresp(self):
+        resp, o = self._getline()
+        if self._debugging > 1: print '*resp*', repr(resp)
+        c = resp[:1]
+        if c != '+':
+            raise error_proto(resp)
+        return resp
+
+
+    # Internal: get a response plus following text from the server.
+
+    def _getlongresp(self):
+        resp = self._getresp()
+        list = []; octets = 0
+        line, o = self._getline()
+        while line != '.':
+            if line[:2] == '..':
+                o = o-1
+                line = line[1:]
+            octets = octets + o
+            list.append(line)
+            line, o = self._getline()
+        return resp, list, octets
+
+
+    # Internal: send a command and get the response
+
+    def _shortcmd(self, line):
+        self._putcmd(line)
+        return self._getresp()
+
+
+    # Internal: send a command and get the response plus following text
+
+    def _longcmd(self, line):
+        self._putcmd(line)
+        return self._getlongresp()
+
+
+    # These can be useful:
+
+    def getwelcome(self):
+        return self.welcome
+
+
+    def set_debuglevel(self, level):
+        self._debugging = level
+
+
+    # Here are all the POP commands:
+
+    def user(self, user):
+        """Send user name, return response
+
+        (should indicate password required).
+        """
+        return self._shortcmd('USER %s' % user)
+
+
+    def pass_(self, pswd):
+        """Send password, return response
+
+        (response includes message count, mailbox size).
+
+        NB: mailbox is locked by server from here to 'quit()'
+        """
+        return self._shortcmd('PASS %s' % pswd)
+
+
+    def stat(self):
+        """Get mailbox status.
+
+        Result is tuple of 2 ints (message count, mailbox size)
+        """
+        retval = self._shortcmd('STAT')
+        rets = retval.split()
+        if self._debugging: print '*stat*', repr(rets)
+        numMessages = int(rets[1])
+        sizeMessages = int(rets[2])
+        return (numMessages, sizeMessages)
+
+
+    def list(self, which=None):
+        """Request listing, return result.
+
+        Result without a message number argument is in form
+        ['response', ['mesg_num octets', ...], octets].
+
+        Result when a message number argument is given is a
+        single response: the "scan listing" for that message.
+        """
+        if which is not None:
+            return self._shortcmd('LIST %s' % which)
+        return self._longcmd('LIST')
+
+
+    def retr(self, which):
+        """Retrieve whole message number 'which'.
+
+        Result is in form ['response', ['line', ...], octets].
+        """
+        return self._longcmd('RETR %s' % which)
+
+
+    def dele(self, which):
+        """Delete message number 'which'.
+
+        Result is 'response'.
+        """
+        return self._shortcmd('DELE %s' % which)
+
+
+    def noop(self):
+        """Does nothing.
+
+        One supposes the response indicates the server is alive.
+        """
+        return self._shortcmd('NOOP')
+
+
+    def rset(self):
+        """Not sure what this does."""
+        return self._shortcmd('RSET')
+
+
+    def quit(self):
+        """Signoff: commit changes on server, unlock mailbox, close connection."""
+        try:
+            resp = self._shortcmd('QUIT')
+        except error_proto, val:
+            resp = val
+        self.file.close()
+        self.sock.close()
+        del self.file, self.sock
+        return resp
+
+    #__del__ = quit
+
+
+    # optional commands:
+
+    def rpop(self, user):
+        """Not sure what this does."""
+        return self._shortcmd('RPOP %s' % user)
+
+
+    timestamp = re.compile(r'\+OK.*(<[^>]+>)')
+
+    def apop(self, user, secret):
+        """Authorisation
+
+        - only possible if server has supplied a timestamp in initial greeting.
+
+        Args:
+                user    - mailbox user;
+                secret  - secret shared between client and server.
+
+        NB: mailbox is locked by server from here to 'quit()'
+        """
+        m = self.timestamp.match(self.welcome)
+        if not m:
+            raise error_proto('-ERR APOP not supported by server')
+        import hashlib
+        digest = hashlib.md5(m.group(1)+secret).digest()
+        digest = ''.join(map(lambda x:'%02x'%ord(x), digest))
+        return self._shortcmd('APOP %s %s' % (user, digest))
+
+
+    def top(self, which, howmuch):
+        """Retrieve message header of message number 'which'
+        and first 'howmuch' lines of message body.
+
+        Result is in form ['response', ['line', ...], octets].
+        """
+        return self._longcmd('TOP %s %s' % (which, howmuch))
+
+
+    def uidl(self, which=None):
+        """Return message digest (unique id) list.
+
+        If 'which', result contains unique id for that message
+        in the form 'response mesgnum uid', otherwise result is
+        the list ['response', ['mesgnum uid', ...], octets]
+        """
+        if which is not None:
+            return self._shortcmd('UIDL %s' % which)
+        return self._longcmd('UIDL')
+
+class POP3_SSL(POP3):
+    """POP3 client class over SSL connection
+
+    Instantiate with: POP3_SSL(hostname, port=995, keyfile=None, certfile=None)
+
+           hostname - the hostname of the pop3 over ssl server
+           port - port number
+           keyfile - PEM formatted file that countains your private key
+           certfile - PEM formatted certificate chain file
+
+        See the methods of the parent class POP3 for more documentation.
+    """
+
+    def __init__(self, host, port = POP3_SSL_PORT, keyfile = None, certfile = None):
+        self.host = host
+        self.port = port
+        self.keyfile = keyfile
+        self.certfile = certfile
+        self.buffer = ""
+        msg = "getaddrinfo returns an empty list"
+        self.sock = None
+        for res in socket.getaddrinfo(self.host, self.port, 0, socket.SOCK_STREAM):
+            af, socktype, proto, canonname, sa = res
+            try:
+                self.sock = socket.socket(af, socktype, proto)
+                self.sock.connect(sa)
+            except socket.error, msg:
+                if self.sock:
+                    self.sock.close()
+                self.sock = None
+                continue
+            break
+        if not self.sock:
+            raise socket.error, msg
+        self.file = self.sock.makefile('rb')
+        self.sslobj = socket.ssl(self.sock, self.keyfile, self.certfile)
+        self._debugging = 0
+        self.welcome = self._getresp()
+
+    def _fillBuffer(self):
+        localbuf = self.sslobj.read()
+        if len(localbuf) == 0:
+            raise error_proto('-ERR EOF')
+        self.buffer += localbuf
+
+    def _getline(self):
+        line = ""
+        renewline = re.compile(r'.*?\n')
+        match = renewline.match(self.buffer)
+        while not match:
+            self._fillBuffer()
+            match = renewline.match(self.buffer)
+        line = match.group(0)
+        self.buffer = renewline.sub('' ,self.buffer, 1)
+        if self._debugging > 1: print '*get*', repr(line)
+
+        octets = len(line)
+        if line[-2:] == CRLF:
+            return line[:-2], octets
+        if line[0] == CR:
+            return line[1:-1], octets
+        return line[:-1], octets
+
+    def _putline(self, line):
+        if self._debugging > 1: print '*put*', repr(line)
+        line += CRLF
+        bytes = len(line)
+        while bytes > 0:
+            sent = self.sslobj.write(line)
+            if sent == bytes:
+                break    # avoid copy
+            line = line[sent:]
+            bytes = bytes - sent
+
+    def quit(self):
+        """Signoff: commit changes on server, unlock mailbox, close connection."""
+        try:
+            resp = self._shortcmd('QUIT')
+        except error_proto, val:
+            resp = val
+        self.sock.close()
+        del self.sslobj, self.sock
+        return resp
+
+
+if __name__ == "__main__":
+    import sys
+    a = POP3(sys.argv[1])
+    print a.getwelcome()
+    a.user(sys.argv[2])
+    a.pass_(sys.argv[3])
+    a.list()
+    (numMsgs, totalSize) = a.stat()
+    for i in range(1, numMsgs + 1):
+        (header, msg, octets) = a.retr(i)
+        print "Message %d:" % i
+        for line in msg:
+            print '   ' + line
+        print '-----------------------'
+    a.quit()

Added: vendor/Python/current/Lib/posixfile.py
===================================================================
--- vendor/Python/current/Lib/posixfile.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/posixfile.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,235 @@
+"""Extended file operations available in POSIX.
+
+f = posixfile.open(filename, [mode, [bufsize]])
+      will create a new posixfile object
+
+f = posixfile.fileopen(fileobject)
+      will create a posixfile object from a builtin file object
+
+f.file()
+      will return the original builtin file object
+
+f.dup()
+      will return a new file object based on a new filedescriptor
+
+f.dup2(fd)
+      will return a new file object based on the given filedescriptor
+
+f.flags(mode)
+      will turn on the associated flag (merge)
+      mode can contain the following characters:
+
+  (character representing a flag)
+      a       append only flag
+      c       close on exec flag
+      n       no delay flag
+      s       synchronization flag
+  (modifiers)
+      !       turn flags 'off' instead of default 'on'
+      =       copy flags 'as is' instead of default 'merge'
+      ?       return a string in which the characters represent the flags
+              that are set
+
+      note: - the '!' and '=' modifiers are mutually exclusive.
+            - the '?' modifier will return the status of the flags after they
+              have been changed by other characters in the mode string
+
+f.lock(mode [, len [, start [, whence]]])
+      will (un)lock a region
+      mode can contain the following characters:
+
+  (character representing type of lock)
+      u       unlock
+      r       read lock
+      w       write lock
+  (modifiers)
+      |       wait until the lock can be granted
+      ?       return the first lock conflicting with the requested lock
+              or 'None' if there is no conflict. The lock returned is in the
+              format (mode, len, start, whence, pid) where mode is a
+              character representing the type of lock ('r' or 'w')
+
+      note: - the '?' modifier prevents a region from being locked; it is
+              query only
+"""
+
+
+class _posixfile_:
+    """File wrapper class that provides extra POSIX file routines."""
+
+    states = ['open', 'closed']
+
+    #
+    # Internal routines
+    #
+    def __repr__(self):
+        file = self._file_
+        return "<%s posixfile '%s', mode '%s' at %s>" % \
+                (self.states[file.closed], file.name, file.mode, \
+                 hex(id(self))[2:])
+
+    #
+    # Initialization routines
+    #
+    def open(self, name, mode='r', bufsize=-1):
+        import __builtin__
+        return self.fileopen(__builtin__.open(name, mode, bufsize))
+
+    def fileopen(self, file):
+        import types
+        if repr(type(file)) != "<type 'file'>":
+            raise TypeError, 'posixfile.fileopen() arg must be file object'
+        self._file_  = file
+        # Copy basic file methods
+        for maybemethod in dir(file):
+            if not maybemethod.startswith('_'):
+                attr = getattr(file, maybemethod)
+                if isinstance(attr, types.BuiltinMethodType):
+                    setattr(self, maybemethod, attr)
+        return self
+
+    #
+    # New methods
+    #
+    def file(self):
+        return self._file_
+
+    def dup(self):
+        import posix
+
+        if not hasattr(posix, 'fdopen'):
+            raise AttributeError, 'dup() method unavailable'
+
+        return posix.fdopen(posix.dup(self._file_.fileno()), self._file_.mode)
+
+    def dup2(self, fd):
+        import posix
+
+        if not hasattr(posix, 'fdopen'):
+            raise AttributeError, 'dup() method unavailable'
+
+        posix.dup2(self._file_.fileno(), fd)
+        return posix.fdopen(fd, self._file_.mode)
+
+    def flags(self, *which):
+        import fcntl, os
+
+        if which:
+            if len(which) > 1:
+                raise TypeError, 'Too many arguments'
+            which = which[0]
+        else: which = '?'
+
+        l_flags = 0
+        if 'n' in which: l_flags = l_flags | os.O_NDELAY
+        if 'a' in which: l_flags = l_flags | os.O_APPEND
+        if 's' in which: l_flags = l_flags | os.O_SYNC
+
+        file = self._file_
+
+        if '=' not in which:
+            cur_fl = fcntl.fcntl(file.fileno(), fcntl.F_GETFL, 0)
+            if '!' in which: l_flags = cur_fl & ~ l_flags
+            else: l_flags = cur_fl | l_flags
+
+        l_flags = fcntl.fcntl(file.fileno(), fcntl.F_SETFL, l_flags)
+
+        if 'c' in which:
+            arg = ('!' not in which)    # 0 is don't, 1 is do close on exec
+            l_flags = fcntl.fcntl(file.fileno(), fcntl.F_SETFD, arg)
+
+        if '?' in which:
+            which = ''                  # Return current flags
+            l_flags = fcntl.fcntl(file.fileno(), fcntl.F_GETFL, 0)
+            if os.O_APPEND & l_flags: which = which + 'a'
+            if fcntl.fcntl(file.fileno(), fcntl.F_GETFD, 0) & 1:
+                which = which + 'c'
+            if os.O_NDELAY & l_flags: which = which + 'n'
+            if os.O_SYNC & l_flags: which = which + 's'
+            return which
+
+    def lock(self, how, *args):
+        import struct, fcntl
+
+        if 'w' in how: l_type = fcntl.F_WRLCK
+        elif 'r' in how: l_type = fcntl.F_RDLCK
+        elif 'u' in how: l_type = fcntl.F_UNLCK
+        else: raise TypeError, 'no type of lock specified'
+
+        if '|' in how: cmd = fcntl.F_SETLKW
+        elif '?' in how: cmd = fcntl.F_GETLK
+        else: cmd = fcntl.F_SETLK
+
+        l_whence = 0
+        l_start = 0
+        l_len = 0
+
+        if len(args) == 1:
+            l_len = args[0]
+        elif len(args) == 2:
+            l_len, l_start = args
+        elif len(args) == 3:
+            l_len, l_start, l_whence = args
+        elif len(args) > 3:
+            raise TypeError, 'too many arguments'
+
+        # Hack by davem at magnet.com to get locking to go on freebsd;
+        # additions for AIX by Vladimir.Marangozov at imag.fr
+        import sys, os
+        if sys.platform in ('netbsd1',
+                            'openbsd2',
+                            'freebsd2', 'freebsd3', 'freebsd4', 'freebsd5',
+                            'freebsd6', 'freebsd7',
+                            'bsdos2', 'bsdos3', 'bsdos4'):
+            flock = struct.pack('lxxxxlxxxxlhh', \
+                  l_start, l_len, os.getpid(), l_type, l_whence)
+        elif sys.platform in ('aix3', 'aix4'):
+            flock = struct.pack('hhlllii', \
+                  l_type, l_whence, l_start, l_len, 0, 0, 0)
+        else:
+            flock = struct.pack('hhllhh', \
+                  l_type, l_whence, l_start, l_len, 0, 0)
+
+        flock = fcntl.fcntl(self._file_.fileno(), cmd, flock)
+
+        if '?' in how:
+            if sys.platform in ('netbsd1',
+                                'openbsd2',
+                                'freebsd2', 'freebsd3', 'freebsd4', 'freebsd5',
+                                'bsdos2', 'bsdos3', 'bsdos4'):
+                l_start, l_len, l_pid, l_type, l_whence = \
+                    struct.unpack('lxxxxlxxxxlhh', flock)
+            elif sys.platform in ('aix3', 'aix4'):
+                l_type, l_whence, l_start, l_len, l_sysid, l_pid, l_vfs = \
+                    struct.unpack('hhlllii', flock)
+            elif sys.platform == "linux2":
+                l_type, l_whence, l_start, l_len, l_pid, l_sysid = \
+                    struct.unpack('hhllhh', flock)
+            else:
+                l_type, l_whence, l_start, l_len, l_sysid, l_pid = \
+                    struct.unpack('hhllhh', flock)
+
+            if l_type != fcntl.F_UNLCK:
+                if l_type == fcntl.F_RDLCK:
+                    return 'r', l_len, l_start, l_whence, l_pid
+                else:
+                    return 'w', l_len, l_start, l_whence, l_pid
+
+def open(name, mode='r', bufsize=-1):
+    """Public routine to open a file as a posixfile object."""
+    return _posixfile_().open(name, mode, bufsize)
+
+def fileopen(file):
+    """Public routine to get a posixfile object from a Python file object."""
+    return _posixfile_().fileopen(file)
+
+#
+# Constants
+#
+SEEK_SET = 0
+SEEK_CUR = 1
+SEEK_END = 2
+
+#
+# End of posixfile.py
+#

Added: vendor/Python/current/Lib/posixpath.py
===================================================================
--- vendor/Python/current/Lib/posixpath.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/posixpath.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,453 @@
+"""Common operations on Posix pathnames.
+
+Instead of importing this module directly, import os and refer to
+this module as os.path.  The "os.path" name is an alias for this
+module on Posix systems; on other systems (e.g. Mac, Windows),
+os.path provides the same operations in a manner specific to that
+platform, and is an alias to another module (e.g. macpath, ntpath).
+
+Some of this can actually be useful on non-Posix systems too, e.g.
+for manipulation of the pathname component of URLs.
+"""
+
+import os
+import stat
+
+__all__ = ["normcase","isabs","join","splitdrive","split","splitext",
+           "basename","dirname","commonprefix","getsize","getmtime",
+           "getatime","getctime","islink","exists","lexists","isdir","isfile",
+           "ismount","walk","expanduser","expandvars","normpath","abspath",
+           "samefile","sameopenfile","samestat",
+           "curdir","pardir","sep","pathsep","defpath","altsep","extsep",
+           "devnull","realpath","supports_unicode_filenames"]
+
+# strings representing various path-related bits and pieces
+curdir = '.'
+pardir = '..'
+extsep = '.'
+sep = '/'
+pathsep = ':'
+defpath = ':/bin:/usr/bin'
+altsep = None
+devnull = '/dev/null'
+
+# Normalize the case of a pathname.  Trivial in Posix, string.lower on Mac.
+# On MS-DOS this may also turn slashes into backslashes; however, other
+# normalizations (such as optimizing '../' away) are not allowed
+# (another function should be defined to do that).
+
+def normcase(s):
+    """Normalize case of pathname.  Has no effect under Posix"""
+    return s
+
+
+# Return whether a path is absolute.
+# Trivial in Posix, harder on the Mac or MS-DOS.
+
+def isabs(s):
+    """Test whether a path is absolute"""
+    return s.startswith('/')
+
+
+# Join pathnames.
+# Ignore the previous parts if a part is absolute.
+# Insert a '/' unless the first part is empty or already ends in '/'.
+
+def join(a, *p):
+    """Join two or more pathname components, inserting '/' as needed"""
+    path = a
+    for b in p:
+        if b.startswith('/'):
+            path = b
+        elif path == '' or path.endswith('/'):
+            path +=  b
+        else:
+            path += '/' + b
+    return path
+
+
+# Split a path in head (everything up to the last '/') and tail (the
+# rest).  If the path ends in '/', tail will be empty.  If there is no
+# '/' in the path, head  will be empty.
+# Trailing '/'es are stripped from head unless it is the root.
+
+def split(p):
+    """Split a pathname.  Returns tuple "(head, tail)" where "tail" is
+    everything after the final slash.  Either part may be empty."""
+    i = p.rfind('/') + 1
+    head, tail = p[:i], p[i:]
+    if head and head != '/'*len(head):
+        head = head.rstrip('/')
+    return head, tail
+
+
+# Split a path in root and extension.
+# The extension is everything starting at the last dot in the last
+# pathname component; the root is everything before that.
+# It is always true that root + ext == p.
+
+def splitext(p):
+    """Split the extension from a pathname.  Extension is everything from the
+    last dot to the end.  Returns "(root, ext)", either part may be empty."""
+    i = p.rfind('.')
+    if i<=p.rfind('/'):
+        return p, ''
+    else:
+        return p[:i], p[i:]
+
+
+# Split a pathname into a drive specification and the rest of the
+# path.  Useful on DOS/Windows/NT; on Unix, the drive is always empty.
+
+def splitdrive(p):
+    """Split a pathname into drive and path. On Posix, drive is always
+    empty."""
+    return '', p
+
+
+# Return the tail (basename) part of a path.
+
+def basename(p):
+    """Returns the final component of a pathname"""
+    return split(p)[1]
+
+
+# Return the head (dirname) part of a path.
+
+def dirname(p):
+    """Returns the directory component of a pathname"""
+    return split(p)[0]
+
+
+# Return the longest prefix of all list elements.
+
+def commonprefix(m):
+    "Given a list of pathnames, returns the longest common leading component"
+    if not m: return ''
+    s1 = min(m)
+    s2 = max(m)
+    n = min(len(s1), len(s2))
+    for i in xrange(n):
+        if s1[i] != s2[i]:
+            return s1[:i]
+    return s1[:n]
+
+# Get size, mtime, atime of files.
+
+def getsize(filename):
+    """Return the size of a file, reported by os.stat()."""
+    return os.stat(filename).st_size
+
+def getmtime(filename):
+    """Return the last modification time of a file, reported by os.stat()."""
+    return os.stat(filename).st_mtime
+
+def getatime(filename):
+    """Return the last access time of a file, reported by os.stat()."""
+    return os.stat(filename).st_atime
+
+def getctime(filename):
+    """Return the metadata change time of a file, reported by os.stat()."""
+    return os.stat(filename).st_ctime
+
+# Is a path a symbolic link?
+# This will always return false on systems where os.lstat doesn't exist.
+
+def islink(path):
+    """Test whether a path is a symbolic link"""
+    try:
+        st = os.lstat(path)
+    except (os.error, AttributeError):
+        return False
+    return stat.S_ISLNK(st.st_mode)
+
+
+# Does a path exist?
+# This is false for dangling symbolic links.
+
+def exists(path):
+    """Test whether a path exists.  Returns False for broken symbolic links"""
+    try:
+        st = os.stat(path)
+    except os.error:
+        return False
+    return True
+
+
+# Being true for dangling symbolic links is also useful.
+
+def lexists(path):
+    """Test whether a path exists.  Returns True for broken symbolic links"""
+    try:
+        st = os.lstat(path)
+    except os.error:
+        return False
+    return True
+
+
+# Is a path a directory?
+# This follows symbolic links, so both islink() and isdir() can be true
+# for the same path.
+
+def isdir(path):
+    """Test whether a path is a directory"""
+    try:
+        st = os.stat(path)
+    except os.error:
+        return False
+    return stat.S_ISDIR(st.st_mode)
+
+
+# Is a path a regular file?
+# This follows symbolic links, so both islink() and isfile() can be true
+# for the same path.
+
+def isfile(path):
+    """Test whether a path is a regular file"""
+    try:
+        st = os.stat(path)
+    except os.error:
+        return False
+    return stat.S_ISREG(st.st_mode)
+
+
+# Are two filenames really pointing to the same file?
+
+def samefile(f1, f2):
+    """Test whether two pathnames reference the same actual file"""
+    s1 = os.stat(f1)
+    s2 = os.stat(f2)
+    return samestat(s1, s2)
+
+
+# Are two open files really referencing the same file?
+# (Not necessarily the same file descriptor!)
+
+def sameopenfile(fp1, fp2):
+    """Test whether two open file objects reference the same file"""
+    s1 = os.fstat(fp1)
+    s2 = os.fstat(fp2)
+    return samestat(s1, s2)
+
+
+# Are two stat buffers (obtained from stat, fstat or lstat)
+# describing the same file?
+
+def samestat(s1, s2):
+    """Test whether two stat buffers reference the same file"""
+    return s1.st_ino == s2.st_ino and \
+           s1.st_dev == s2.st_dev
+
+
+# Is a path a mount point?
+# (Does this work for all UNIXes?  Is it even guaranteed to work by Posix?)
+
+def ismount(path):
+    """Test whether a path is a mount point"""
+    try:
+        s1 = os.stat(path)
+        s2 = os.stat(join(path, '..'))
+    except os.error:
+        return False # It doesn't exist -- so not a mount point :-)
+    dev1 = s1.st_dev
+    dev2 = s2.st_dev
+    if dev1 != dev2:
+        return True     # path/.. on a different device as path
+    ino1 = s1.st_ino
+    ino2 = s2.st_ino
+    if ino1 == ino2:
+        return True     # path/.. is the same i-node as path
+    return False
+
+
+# Directory tree walk.
+# For each directory under top (including top itself, but excluding
+# '.' and '..'), func(arg, dirname, filenames) is called, where
+# dirname is the name of the directory and filenames is the list
+# of files (and subdirectories etc.) in the directory.
+# The func may modify the filenames list, to implement a filter,
+# or to impose a different order of visiting.
+
+def walk(top, func, arg):
+    """Directory tree walk with callback function.
+
+    For each directory in the directory tree rooted at top (including top
+    itself, but excluding '.' and '..'), call func(arg, dirname, fnames).
+    dirname is the name of the directory, and fnames a list of the names of
+    the files and subdirectories in dirname (excluding '.' and '..').  func
+    may modify the fnames list in-place (e.g. via del or slice assignment),
+    and walk will only recurse into the subdirectories whose names remain in
+    fnames; this can be used to implement a filter, or to impose a specific
+    order of visiting.  No semantics are defined for, or required of, arg,
+    beyond that arg is always passed to func.  It can be used, e.g., to pass
+    a filename pattern, or a mutable object designed to accumulate
+    statistics.  Passing None for arg is common."""
+
+    try:
+        names = os.listdir(top)
+    except os.error:
+        return
+    func(arg, top, names)
+    for name in names:
+        name = join(top, name)
+        try:
+            st = os.lstat(name)
+        except os.error:
+            continue
+        if stat.S_ISDIR(st.st_mode):
+            walk(name, func, arg)
+
+
+# Expand paths beginning with '~' or '~user'.
+# '~' means $HOME; '~user' means that user's home directory.
+# If the path doesn't begin with '~', or if the user or $HOME is unknown,
+# the path is returned unchanged (leaving error reporting to whatever
+# function is called with the expanded path as argument).
+# See also module 'glob' for expansion of *, ? and [...] in pathnames.
+# (A function should also be defined to do full *sh-style environment
+# variable expansion.)
+
+def expanduser(path):
+    """Expand ~ and ~user constructions.  If user or $HOME is unknown,
+    do nothing."""
+    if not path.startswith('~'):
+        return path
+    i = path.find('/', 1)
+    if i < 0:
+        i = len(path)
+    if i == 1:
+        if 'HOME' not in os.environ:
+            import pwd
+            userhome = pwd.getpwuid(os.getuid()).pw_dir
+        else:
+            userhome = os.environ['HOME']
+    else:
+        import pwd
+        try:
+            pwent = pwd.getpwnam(path[1:i])
+        except KeyError:
+            return path
+        userhome = pwent.pw_dir
+    userhome = userhome.rstrip('/')
+    return userhome + path[i:]
+
+
+# Expand paths containing shell variable substitutions.
+# This expands the forms $variable and ${variable} only.
+# Non-existent variables are left unchanged.
+
+_varprog = None
+
+def expandvars(path):
+    """Expand shell variables of form $var and ${var}.  Unknown variables
+    are left unchanged."""
+    global _varprog
+    if '$' not in path:
+        return path
+    if not _varprog:
+        import re
+        _varprog = re.compile(r'\$(\w+|\{[^}]*\})')
+    i = 0
+    while True:
+        m = _varprog.search(path, i)
+        if not m:
+            break
+        i, j = m.span(0)
+        name = m.group(1)
+        if name.startswith('{') and name.endswith('}'):
+            name = name[1:-1]
+        if name in os.environ:
+            tail = path[j:]
+            path = path[:i] + os.environ[name]
+            i = len(path)
+            path += tail
+        else:
+            i = j
+    return path
+
+
+# Normalize a path, e.g. A//B, A/./B and A/foo/../B all become A/B.
+# It should be understood that this may change the meaning of the path
+# if it contains symbolic links!
+
+def normpath(path):
+    """Normalize path, eliminating double slashes, etc."""
+    if path == '':
+        return '.'
+    initial_slashes = path.startswith('/')
+    # POSIX allows one or two initial slashes, but treats three or more
+    # as single slash.
+    if (initial_slashes and
+        path.startswith('//') and not path.startswith('///')):
+        initial_slashes = 2
+    comps = path.split('/')
+    new_comps = []
+    for comp in comps:
+        if comp in ('', '.'):
+            continue
+        if (comp != '..' or (not initial_slashes and not new_comps) or
+             (new_comps and new_comps[-1] == '..')):
+            new_comps.append(comp)
+        elif new_comps:
+            new_comps.pop()
+    comps = new_comps
+    path = '/'.join(comps)
+    if initial_slashes:
+        path = '/'*initial_slashes + path
+    return path or '.'
+
+
+def abspath(path):
+    """Return an absolute path."""
+    if not isabs(path):
+        path = join(os.getcwd(), path)
+    return normpath(path)
+
+
+# Return a canonical path (i.e. the absolute location of a file on the
+# filesystem).
+
+def realpath(filename):
+    """Return the canonical path of the specified filename, eliminating any
+symbolic links encountered in the path."""
+    if isabs(filename):
+        bits = ['/'] + filename.split('/')[1:]
+    else:
+        bits = [''] + filename.split('/')
+
+    for i in range(2, len(bits)+1):
+        component = join(*bits[0:i])
+        # Resolve symbolic links.
+        if islink(component):
+            resolved = _resolve_link(component)
+            if resolved is None:
+                # Infinite loop -- return original component + rest of the path
+                return abspath(join(*([component] + bits[i:])))
+            else:
+                newpath = join(*([resolved] + bits[i:]))
+                return realpath(newpath)
+
+    return abspath(filename)
+
+
+def _resolve_link(path):
+    """Internal helper function.  Takes a path and follows symlinks
+    until we either arrive at something that isn't a symlink, or
+    encounter a path we've seen before (meaning that there's a loop).
+    """
+    paths_seen = []
+    while islink(path):
+        if path in paths_seen:
+            # Already seen this path, so we must have a symlink loop
+            return None
+        paths_seen.append(path)
+        # Resolve where the link points to
+        resolved = os.readlink(path)
+        if not isabs(resolved):
+            dir = dirname(path)
+            path = normpath(join(dir, resolved))
+        else:
+            path = normpath(resolved)
+    return path
+
+supports_unicode_filenames = False

Added: vendor/Python/current/Lib/pprint.py
===================================================================
--- vendor/Python/current/Lib/pprint.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/pprint.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,315 @@
+#  Author:      Fred L. Drake, Jr.
+#               fdrake at acm.org
+#
+#  This is a simple little module I wrote to make life easier.  I didn't
+#  see anything quite like it in the library, though I may have overlooked
+#  something.  I wrote this when I was trying to read some heavily nested
+#  tuples with fairly non-descriptive content.  This is modeled very much
+#  after Lisp/Scheme - style pretty-printing of lists.  If you find it
+#  useful, thank small children who sleep at night.
+
+"""Support to pretty-print lists, tuples, & dictionaries recursively.
+
+Very simple, but useful, especially in debugging data structures.
+
+Classes
+-------
+
+PrettyPrinter()
+    Handle pretty-printing operations onto a stream using a configured
+    set of formatting parameters.
+
+Functions
+---------
+
+pformat()
+    Format a Python object into a pretty-printed representation.
+
+pprint()
+    Pretty-print a Python object to a stream [default is sys.stdout].
+
+saferepr()
+    Generate a 'standard' repr()-like value, but protect against recursive
+    data structures.
+
+"""
+
+import sys as _sys
+
+from cStringIO import StringIO as _StringIO
+
+__all__ = ["pprint","pformat","isreadable","isrecursive","saferepr",
+           "PrettyPrinter"]
+
+# cache these for faster access:
+_commajoin = ", ".join
+_id = id
+_len = len
+_type = type
+
+
+def pprint(object, stream=None, indent=1, width=80, depth=None):
+    """Pretty-print a Python object to a stream [default is sys.stdout]."""
+    printer = PrettyPrinter(
+        stream=stream, indent=indent, width=width, depth=depth)
+    printer.pprint(object)
+
+def pformat(object, indent=1, width=80, depth=None):
+    """Format a Python object into a pretty-printed representation."""
+    return PrettyPrinter(indent=indent, width=width, depth=depth).pformat(object)
+
+def saferepr(object):
+    """Version of repr() which can handle recursive data structures."""
+    return _safe_repr(object, {}, None, 0)[0]
+
+def isreadable(object):
+    """Determine if saferepr(object) is readable by eval()."""
+    return _safe_repr(object, {}, None, 0)[1]
+
+def isrecursive(object):
+    """Determine if object requires a recursive representation."""
+    return _safe_repr(object, {}, None, 0)[2]
+
+class PrettyPrinter:
+    def __init__(self, indent=1, width=80, depth=None, stream=None):
+        """Handle pretty printing operations onto a stream using a set of
+        configured parameters.
+
+        indent
+            Number of spaces to indent for each level of nesting.
+
+        width
+            Attempted maximum number of columns in the output.
+
+        depth
+            The maximum depth to print out nested structures.
+
+        stream
+            The desired output stream.  If omitted (or false), the standard
+            output stream available at construction will be used.
+
+        """
+        indent = int(indent)
+        width = int(width)
+        assert indent >= 0, "indent must be >= 0"
+        assert depth is None or depth > 0, "depth must be > 0"
+        assert width, "width must be != 0"
+        self._depth = depth
+        self._indent_per_level = indent
+        self._width = width
+        if stream is not None:
+            self._stream = stream
+        else:
+            self._stream = _sys.stdout
+
+    def pprint(self, object):
+        self._format(object, self._stream, 0, 0, {}, 0)
+        self._stream.write("\n")
+
+    def pformat(self, object):
+        sio = _StringIO()
+        self._format(object, sio, 0, 0, {}, 0)
+        return sio.getvalue()
+
+    def isrecursive(self, object):
+        return self.format(object, {}, 0, 0)[2]
+
+    def isreadable(self, object):
+        s, readable, recursive = self.format(object, {}, 0, 0)
+        return readable and not recursive
+
+    def _format(self, object, stream, indent, allowance, context, level):
+        level = level + 1
+        objid = _id(object)
+        if objid in context:
+            stream.write(_recursion(object))
+            self._recursive = True
+            self._readable = False
+            return
+        rep = self._repr(object, context, level - 1)
+        typ = _type(object)
+        sepLines = _len(rep) > (self._width - 1 - indent - allowance)
+        write = stream.write
+
+        if sepLines:
+            r = getattr(typ, "__repr__", None)
+            if issubclass(typ, dict) and r is dict.__repr__:
+                write('{')
+                if self._indent_per_level > 1:
+                    write((self._indent_per_level - 1) * ' ')
+                length = _len(object)
+                if length:
+                    context[objid] = 1
+                    indent = indent + self._indent_per_level
+                    items  = object.items()
+                    items.sort()
+                    key, ent = items[0]
+                    rep = self._repr(key, context, level)
+                    write(rep)
+                    write(': ')
+                    self._format(ent, stream, indent + _len(rep) + 2,
+                                  allowance + 1, context, level)
+                    if length > 1:
+                        for key, ent in items[1:]:
+                            rep = self._repr(key, context, level)
+                            write(',\n%s%s: ' % (' '*indent, rep))
+                            self._format(ent, stream, indent + _len(rep) + 2,
+                                          allowance + 1, context, level)
+                    indent = indent - self._indent_per_level
+                    del context[objid]
+                write('}')
+                return
+
+            if (issubclass(typ, list) and r is list.__repr__) or \
+               (issubclass(typ, tuple) and r is tuple.__repr__):
+                if issubclass(typ, list):
+                    write('[')
+                    endchar = ']'
+                else:
+                    write('(')
+                    endchar = ')'
+                if self._indent_per_level > 1:
+                    write((self._indent_per_level - 1) * ' ')
+                length = _len(object)
+                if length:
+                    context[objid] = 1
+                    indent = indent + self._indent_per_level
+                    self._format(object[0], stream, indent, allowance + 1,
+                                 context, level)
+                    if length > 1:
+                        for ent in object[1:]:
+                            write(',\n' + ' '*indent)
+                            self._format(ent, stream, indent,
+                                          allowance + 1, context, level)
+                    indent = indent - self._indent_per_level
+                    del context[objid]
+                if issubclass(typ, tuple) and length == 1:
+                    write(',')
+                write(endchar)
+                return
+
+        write(rep)
+
+    def _repr(self, object, context, level):
+        repr, readable, recursive = self.format(object, context.copy(),
+                                                self._depth, level)
+        if not readable:
+            self._readable = False
+        if recursive:
+            self._recursive = True
+        return repr
+
+    def format(self, object, context, maxlevels, level):
+        """Format object for a specific context, returning a string
+        and flags indicating whether the representation is 'readable'
+        and whether the object represents a recursive construct.
+        """
+        return _safe_repr(object, context, maxlevels, level)
+
+
+# Return triple (repr_string, isreadable, isrecursive).
+
+def _safe_repr(object, context, maxlevels, level):
+    typ = _type(object)
+    if typ is str:
+        if 'locale' not in _sys.modules:
+            return repr(object), True, False
+        if "'" in object and '"' not in object:
+            closure = '"'
+            quotes = {'"': '\\"'}
+        else:
+            closure = "'"
+            quotes = {"'": "\\'"}
+        qget = quotes.get
+        sio = _StringIO()
+        write = sio.write
+        for char in object:
+            if char.isalpha():
+                write(char)
+            else:
+                write(qget(char, repr(char)[1:-1]))
+        return ("%s%s%s" % (closure, sio.getvalue(), closure)), True, False
+
+    r = getattr(typ, "__repr__", None)
+    if issubclass(typ, dict) and r is dict.__repr__:
+        if not object:
+            return "{}", True, False
+        objid = _id(object)
+        if maxlevels and level > maxlevels:
+            return "{...}", False, objid in context
+        if objid in context:
+            return _recursion(object), False, True
+        context[objid] = 1
+        readable = True
+        recursive = False
+        components = []
+        append = components.append
+        level += 1
+        saferepr = _safe_repr
+        for k, v in sorted(object.items()):
+            krepr, kreadable, krecur = saferepr(k, context, maxlevels, level)
+            vrepr, vreadable, vrecur = saferepr(v, context, maxlevels, level)
+            append("%s: %s" % (krepr, vrepr))
+            readable = readable and kreadable and vreadable
+            if krecur or vrecur:
+                recursive = True
+        del context[objid]
+        return "{%s}" % _commajoin(components), readable, recursive
+
+    if (issubclass(typ, list) and r is list.__repr__) or \
+       (issubclass(typ, tuple) and r is tuple.__repr__):
+        if issubclass(typ, list):
+            if not object:
+                return "[]", True, False
+            format = "[%s]"
+        elif _len(object) == 1:
+            format = "(%s,)"
+        else:
+            if not object:
+                return "()", True, False
+            format = "(%s)"
+        objid = _id(object)
+        if maxlevels and level > maxlevels:
+            return format % "...", False, objid in context
+        if objid in context:
+            return _recursion(object), False, True
+        context[objid] = 1
+        readable = True
+        recursive = False
+        components = []
+        append = components.append
+        level += 1
+        for o in object:
+            orepr, oreadable, orecur = _safe_repr(o, context, maxlevels, level)
+            append(orepr)
+            if not oreadable:
+                readable = False
+            if orecur:
+                recursive = True
+        del context[objid]
+        return format % _commajoin(components), readable, recursive
+
+    rep = repr(object)
+    return rep, (rep and not rep.startswith('<')), False
+
+
+def _recursion(object):
+    return ("<Recursion on %s with id=%s>"
+            % (_type(object).__name__, _id(object)))
+
+
+def _perfcheck(object=None):
+    import time
+    if object is None:
+        object = [("string", (1, 2), [3, 4], {5: 6, 7: 8})] * 100000
+    p = PrettyPrinter()
+    t1 = time.time()
+    _safe_repr(object, {}, None, 0)
+    t2 = time.time()
+    p.pformat(object)
+    t3 = time.time()
+    print "_safe_repr:", t2 - t1
+    print "pformat:", t3 - t2
+
+if __name__ == "__main__":
+    _perfcheck()

Added: vendor/Python/current/Lib/profile.py
===================================================================
--- vendor/Python/current/Lib/profile.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/profile.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,619 @@
+#! /usr/bin/env python
+#
+# Class for profiling python code. rev 1.0  6/2/94
+#
+# Based on prior profile module by Sjoerd Mullender...
+#   which was hacked somewhat by: Guido van Rossum
+
+"""Class for profiling Python code."""
+
+# Copyright 1994, by InfoSeek Corporation, all rights reserved.
+# Written by James Roskind
+#
+# Permission to use, copy, modify, and distribute this Python software
+# and its associated documentation for any purpose (subject to the
+# restriction in the following sentence) without fee is hereby granted,
+# provided that the above copyright notice appears in all copies, and
+# that both that copyright notice and this permission notice appear in
+# supporting documentation, and that the name of InfoSeek not be used in
+# advertising or publicity pertaining to distribution of the software
+# without specific, written prior permission.  This permission is
+# explicitly restricted to the copying and modification of the software
+# to remain in Python, compiled Python, or other languages (such as C)
+# wherein the modified or derived code is exclusively imported into a
+# Python module.
+#
+# INFOSEEK CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+# SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+# FITNESS. IN NO EVENT SHALL INFOSEEK CORPORATION BE LIABLE FOR ANY
+# SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+
+
+import sys
+import os
+import time
+import marshal
+from optparse import OptionParser
+
+__all__ = ["run", "runctx", "help", "Profile"]
+
+# Sample timer for use with
+#i_count = 0
+#def integer_timer():
+#       global i_count
+#       i_count = i_count + 1
+#       return i_count
+#itimes = integer_timer # replace with C coded timer returning integers
+
+#**************************************************************************
+# The following are the static member functions for the profiler class
+# Note that an instance of Profile() is *not* needed to call them.
+#**************************************************************************
+
+def run(statement, filename=None, sort=-1):
+    """Run statement under profiler optionally saving results in filename
+
+    This function takes a single argument that can be passed to the
+    "exec" statement, and an optional file name.  In all cases this
+    routine attempts to "exec" its first argument and gather profiling
+    statistics from the execution. If no file name is present, then this
+    function automatically prints a simple profiling report, sorted by the
+    standard name string (file/line/function-name) that is presented in
+    each line.
+    """
+    prof = Profile()
+    try:
+        prof = prof.run(statement)
+    except SystemExit:
+        pass
+    if filename is not None:
+        prof.dump_stats(filename)
+    else:
+        return prof.print_stats(sort)
+
+def runctx(statement, globals, locals, filename=None):
+    """Run statement under profiler, supplying your own globals and locals,
+    optionally saving results in filename.
+
+    statement and filename have the same semantics as profile.run
+    """
+    prof = Profile()
+    try:
+        prof = prof.runctx(statement, globals, locals)
+    except SystemExit:
+        pass
+
+    if filename is not None:
+        prof.dump_stats(filename)
+    else:
+        return prof.print_stats()
+
+# Backwards compatibility.
+def help():
+    print "Documentation for the profile module can be found "
+    print "in the Python Library Reference, section 'The Python Profiler'."
+
+if os.name == "mac":
+    import MacOS
+    def _get_time_mac(timer=MacOS.GetTicks):
+        return timer() / 60.0
+
+if hasattr(os, "times"):
+    def _get_time_times(timer=os.times):
+        t = timer()
+        return t[0] + t[1]
+
+# Using getrusage(3) is better than clock(3) if available:
+# on some systems (e.g. FreeBSD), getrusage has a higher resolution
+# Furthermore, on a POSIX system, returns microseconds, which
+# wrap around after 36min.
+_has_res = 0
+try:
+    import resource
+    resgetrusage = lambda: resource.getrusage(resource.RUSAGE_SELF)
+    def _get_time_resource(timer=resgetrusage):
+        t = timer()
+        return t[0] + t[1]
+    _has_res = 1
+except ImportError:
+    pass
+
+class Profile:
+    """Profiler class.
+
+    self.cur is always a tuple.  Each such tuple corresponds to a stack
+    frame that is currently active (self.cur[-2]).  The following are the
+    definitions of its members.  We use this external "parallel stack" to
+    avoid contaminating the program that we are profiling. (old profiler
+    used to write into the frames local dictionary!!) Derived classes
+    can change the definition of some entries, as long as they leave
+    [-2:] intact (frame and previous tuple).  In case an internal error is
+    detected, the -3 element is used as the function name.
+
+    [ 0] = Time that needs to be charged to the parent frame's function.
+           It is used so that a function call will not have to access the
+           timing data for the parent frame.
+    [ 1] = Total time spent in this frame's function, excluding time in
+           subfunctions (this latter is tallied in cur[2]).
+    [ 2] = Total time spent in subfunctions, excluding time executing the
+           frame's function (this latter is tallied in cur[1]).
+    [-3] = Name of the function that corresponds to this frame.
+    [-2] = Actual frame that we correspond to (used to sync exception handling).
+    [-1] = Our parent 6-tuple (corresponds to frame.f_back).
+
+    Timing data for each function is stored as a 5-tuple in the dictionary
+    self.timings[].  The index is always the name stored in self.cur[-3].
+    The following are the definitions of the members:
+
+    [0] = The number of times this function was called, not counting direct
+          or indirect recursion,
+    [1] = Number of times this function appears on the stack, minus one
+    [2] = Total time spent internal to this function
+    [3] = Cumulative time that this function was present on the stack.  In
+          non-recursive functions, this is the total execution time from start
+          to finish of each invocation of a function, including time spent in
+          all subfunctions.
+    [4] = A dictionary indicating for each function name, the number of times
+          it was called by us.
+    """
+
+    bias = 0  # calibration constant
+
+    def __init__(self, timer=None, bias=None):
+        self.timings = {}
+        self.cur = None
+        self.cmd = ""
+        self.c_func_name = ""
+
+        if bias is None:
+            bias = self.bias
+        self.bias = bias     # Materialize in local dict for lookup speed.
+
+        if not timer:
+            if _has_res:
+                self.timer = resgetrusage
+                self.dispatcher = self.trace_dispatch
+                self.get_time = _get_time_resource
+            elif os.name == 'mac':
+                self.timer = MacOS.GetTicks
+                self.dispatcher = self.trace_dispatch_mac
+                self.get_time = _get_time_mac
+            elif hasattr(time, 'clock'):
+                self.timer = self.get_time = time.clock
+                self.dispatcher = self.trace_dispatch_i
+            elif hasattr(os, 'times'):
+                self.timer = os.times
+                self.dispatcher = self.trace_dispatch
+                self.get_time = _get_time_times
+            else:
+                self.timer = self.get_time = time.time
+                self.dispatcher = self.trace_dispatch_i
+        else:
+            self.timer = timer
+            t = self.timer() # test out timer function
+            try:
+                length = len(t)
+            except TypeError:
+                self.get_time = timer
+                self.dispatcher = self.trace_dispatch_i
+            else:
+                if length == 2:
+                    self.dispatcher = self.trace_dispatch
+                else:
+                    self.dispatcher = self.trace_dispatch_l
+                # This get_time() implementation needs to be defined
+                # here to capture the passed-in timer in the parameter
+                # list (for performance).  Note that we can't assume
+                # the timer() result contains two values in all
+                # cases.
+                def get_time_timer(timer=timer, sum=sum):
+                    return sum(timer())
+                self.get_time = get_time_timer
+        self.t = self.get_time()
+        self.simulate_call('profiler')
+
+    # Heavily optimized dispatch routine for os.times() timer
+
+    def trace_dispatch(self, frame, event, arg):
+        timer = self.timer
+        t = timer()
+        t = t[0] + t[1] - self.t - self.bias
+
+        if event == "c_call":
+            self.c_func_name = arg.__name__
+
+        if self.dispatch[event](self, frame,t):
+            t = timer()
+            self.t = t[0] + t[1]
+        else:
+            r = timer()
+            self.t = r[0] + r[1] - t # put back unrecorded delta
+
+    # Dispatch routine for best timer program (return = scalar, fastest if
+    # an integer but float works too -- and time.clock() relies on that).
+
+    def trace_dispatch_i(self, frame, event, arg):
+        timer = self.timer
+        t = timer() - self.t - self.bias
+
+        if event == "c_call":
+            self.c_func_name = arg.__name__
+
+        if self.dispatch[event](self, frame, t):
+            self.t = timer()
+        else:
+            self.t = timer() - t  # put back unrecorded delta
+
+    # Dispatch routine for macintosh (timer returns time in ticks of
+    # 1/60th second)
+
+    def trace_dispatch_mac(self, frame, event, arg):
+        timer = self.timer
+        t = timer()/60.0 - self.t - self.bias
+
+        if event == "c_call":
+            self.c_func_name = arg.__name__
+
+        if self.dispatch[event](self, frame, t):
+            self.t = timer()/60.0
+        else:
+            self.t = timer()/60.0 - t  # put back unrecorded delta
+
+    # SLOW generic dispatch routine for timer returning lists of numbers
+
+    def trace_dispatch_l(self, frame, event, arg):
+        get_time = self.get_time
+        t = get_time() - self.t - self.bias
+
+        if event == "c_call":
+            self.c_func_name = arg.__name__
+
+        if self.dispatch[event](self, frame, t):
+            self.t = get_time()
+        else:
+            self.t = get_time() - t # put back unrecorded delta
+
+    # In the event handlers, the first 3 elements of self.cur are unpacked
+    # into vrbls w/ 3-letter names.  The last two characters are meant to be
+    # mnemonic:
+    #     _pt  self.cur[0] "parent time"   time to be charged to parent frame
+    #     _it  self.cur[1] "internal time" time spent directly in the function
+    #     _et  self.cur[2] "external time" time spent in subfunctions
+
+    def trace_dispatch_exception(self, frame, t):
+        rpt, rit, ret, rfn, rframe, rcur = self.cur
+        if (rframe is not frame) and rcur:
+            return self.trace_dispatch_return(rframe, t)
+        self.cur = rpt, rit+t, ret, rfn, rframe, rcur
+        return 1
+
+
+    def trace_dispatch_call(self, frame, t):
+        if self.cur and frame.f_back is not self.cur[-2]:
+            rpt, rit, ret, rfn, rframe, rcur = self.cur
+            if not isinstance(rframe, Profile.fake_frame):
+                assert rframe.f_back is frame.f_back, ("Bad call", rfn,
+                                                       rframe, rframe.f_back,
+                                                       frame, frame.f_back)
+                self.trace_dispatch_return(rframe, 0)
+                assert (self.cur is None or \
+                        frame.f_back is self.cur[-2]), ("Bad call",
+                                                        self.cur[-3])
+        fcode = frame.f_code
+        fn = (fcode.co_filename, fcode.co_firstlineno, fcode.co_name)
+        self.cur = (t, 0, 0, fn, frame, self.cur)
+        timings = self.timings
+        if fn in timings:
+            cc, ns, tt, ct, callers = timings[fn]
+            timings[fn] = cc, ns + 1, tt, ct, callers
+        else:
+            timings[fn] = 0, 0, 0, 0, {}
+        return 1
+
+    def trace_dispatch_c_call (self, frame, t):
+        fn = ("", 0, self.c_func_name)
+        self.cur = (t, 0, 0, fn, frame, self.cur)
+        timings = self.timings
+        if timings.has_key(fn):
+            cc, ns, tt, ct, callers = timings[fn]
+            timings[fn] = cc, ns+1, tt, ct, callers
+        else:
+            timings[fn] = 0, 0, 0, 0, {}
+        return 1
+
+    def trace_dispatch_return(self, frame, t):
+        if frame is not self.cur[-2]:
+            assert frame is self.cur[-2].f_back, ("Bad return", self.cur[-3])
+            self.trace_dispatch_return(self.cur[-2], 0)
+
+        # Prefix "r" means part of the Returning or exiting frame.
+        # Prefix "p" means part of the Previous or Parent or older frame.
+
+        rpt, rit, ret, rfn, frame, rcur = self.cur
+        rit = rit + t
+        frame_total = rit + ret
+
+        ppt, pit, pet, pfn, pframe, pcur = rcur
+        self.cur = ppt, pit + rpt, pet + frame_total, pfn, pframe, pcur
+
+        timings = self.timings
+        cc, ns, tt, ct, callers = timings[rfn]
+        if not ns:
+            # This is the only occurrence of the function on the stack.
+            # Else this is a (directly or indirectly) recursive call, and
+            # its cumulative time will get updated when the topmost call to
+            # it returns.
+            ct = ct + frame_total
+            cc = cc + 1
+
+        if pfn in callers:
+            callers[pfn] = callers[pfn] + 1  # hack: gather more
+            # stats such as the amount of time added to ct courtesy
+            # of this specific call, and the contribution to cc
+            # courtesy of this call.
+        else:
+            callers[pfn] = 1
+
+        timings[rfn] = cc, ns - 1, tt + rit, ct, callers
+
+        return 1
+
+
+    dispatch = {
+        "call": trace_dispatch_call,
+        "exception": trace_dispatch_exception,
+        "return": trace_dispatch_return,
+        "c_call": trace_dispatch_c_call,
+        "c_exception": trace_dispatch_return,  # the C function returned
+        "c_return": trace_dispatch_return,
+        }
+
+
+    # The next few functions play with self.cmd. By carefully preloading
+    # our parallel stack, we can force the profiled result to include
+    # an arbitrary string as the name of the calling function.
+    # We use self.cmd as that string, and the resulting stats look
+    # very nice :-).
+
+    def set_cmd(self, cmd):
+        if self.cur[-1]: return   # already set
+        self.cmd = cmd
+        self.simulate_call(cmd)
+
+    class fake_code:
+        def __init__(self, filename, line, name):
+            self.co_filename = filename
+            self.co_line = line
+            self.co_name = name
+            self.co_firstlineno = 0
+
+        def __repr__(self):
+            return repr((self.co_filename, self.co_line, self.co_name))
+
+    class fake_frame:
+        def __init__(self, code, prior):
+            self.f_code = code
+            self.f_back = prior
+
+    def simulate_call(self, name):
+        code = self.fake_code('profile', 0, name)
+        if self.cur:
+            pframe = self.cur[-2]
+        else:
+            pframe = None
+        frame = self.fake_frame(code, pframe)
+        self.dispatch['call'](self, frame, 0)
+
+    # collect stats from pending stack, including getting final
+    # timings for self.cmd frame.
+
+    def simulate_cmd_complete(self):
+        get_time = self.get_time
+        t = get_time() - self.t
+        while self.cur[-1]:
+            # We *can* cause assertion errors here if
+            # dispatch_trace_return checks for a frame match!
+            self.dispatch['return'](self, self.cur[-2], t)
+            t = 0
+        self.t = get_time() - t
+
+
+    def print_stats(self, sort=-1):
+        import pstats
+        pstats.Stats(self).strip_dirs().sort_stats(sort). \
+                  print_stats()
+
+    def dump_stats(self, file):
+        f = open(file, 'wb')
+        self.create_stats()
+        marshal.dump(self.stats, f)
+        f.close()
+
+    def create_stats(self):
+        self.simulate_cmd_complete()
+        self.snapshot_stats()
+
+    def snapshot_stats(self):
+        self.stats = {}
+        for func, (cc, ns, tt, ct, callers) in self.timings.iteritems():
+            callers = callers.copy()
+            nc = 0
+            for callcnt in callers.itervalues():
+                nc += callcnt
+            self.stats[func] = cc, nc, tt, ct, callers
+
+
+    # The following two methods can be called by clients to use
+    # a profiler to profile a statement, given as a string.
+
+    def run(self, cmd):
+        import __main__
+        dict = __main__.__dict__
+        return self.runctx(cmd, dict, dict)
+
+    def runctx(self, cmd, globals, locals):
+        self.set_cmd(cmd)
+        sys.setprofile(self.dispatcher)
+        try:
+            exec cmd in globals, locals
+        finally:
+            sys.setprofile(None)
+        return self
+
+    # This method is more useful to profile a single function call.
+    def runcall(self, func, *args, **kw):
+        self.set_cmd(repr(func))
+        sys.setprofile(self.dispatcher)
+        try:
+            return func(*args, **kw)
+        finally:
+            sys.setprofile(None)
+
+
+    #******************************************************************
+    # The following calculates the overhead for using a profiler.  The
+    # problem is that it takes a fair amount of time for the profiler
+    # to stop the stopwatch (from the time it receives an event).
+    # Similarly, there is a delay from the time that the profiler
+    # re-starts the stopwatch before the user's code really gets to
+    # continue.  The following code tries to measure the difference on
+    # a per-event basis.
+    #
+    # Note that this difference is only significant if there are a lot of
+    # events, and relatively little user code per event.  For example,
+    # code with small functions will typically benefit from having the
+    # profiler calibrated for the current platform.  This *could* be
+    # done on the fly during init() time, but it is not worth the
+    # effort.  Also note that if too large a value specified, then
+    # execution time on some functions will actually appear as a
+    # negative number.  It is *normal* for some functions (with very
+    # low call counts) to have such negative stats, even if the
+    # calibration figure is "correct."
+    #
+    # One alternative to profile-time calibration adjustments (i.e.,
+    # adding in the magic little delta during each event) is to track
+    # more carefully the number of events (and cumulatively, the number
+    # of events during sub functions) that are seen.  If this were
+    # done, then the arithmetic could be done after the fact (i.e., at
+    # display time).  Currently, we track only call/return events.
+    # These values can be deduced by examining the callees and callers
+    # vectors for each functions.  Hence we *can* almost correct the
+    # internal time figure at print time (note that we currently don't
+    # track exception event processing counts).  Unfortunately, there
+    # is currently no similar information for cumulative sub-function
+    # time.  It would not be hard to "get all this info" at profiler
+    # time.  Specifically, we would have to extend the tuples to keep
+    # counts of this in each frame, and then extend the defs of timing
+    # tuples to include the significant two figures. I'm a bit fearful
+    # that this additional feature will slow the heavily optimized
+    # event/time ratio (i.e., the profiler would run slower, fur a very
+    # low "value added" feature.)
+    #**************************************************************
+
+    def calibrate(self, m, verbose=0):
+        if self.__class__ is not Profile:
+            raise TypeError("Subclasses must override .calibrate().")
+
+        saved_bias = self.bias
+        self.bias = 0
+        try:
+            return self._calibrate_inner(m, verbose)
+        finally:
+            self.bias = saved_bias
+
+    def _calibrate_inner(self, m, verbose):
+        get_time = self.get_time
+
+        # Set up a test case to be run with and without profiling.  Include
+        # lots of calls, because we're trying to quantify stopwatch overhead.
+        # Do not raise any exceptions, though, because we want to know
+        # exactly how many profile events are generated (one call event, +
+        # one return event, per Python-level call).
+
+        def f1(n):
+            for i in range(n):
+                x = 1
+
+        def f(m, f1=f1):
+            for i in range(m):
+                f1(100)
+
+        f(m)    # warm up the cache
+
+        # elapsed_noprofile <- time f(m) takes without profiling.
+        t0 = get_time()
+        f(m)
+        t1 = get_time()
+        elapsed_noprofile = t1 - t0
+        if verbose:
+            print "elapsed time without profiling =", elapsed_noprofile
+
+        # elapsed_profile <- time f(m) takes with profiling.  The difference
+        # is profiling overhead, only some of which the profiler subtracts
+        # out on its own.
+        p = Profile()
+        t0 = get_time()
+        p.runctx('f(m)', globals(), locals())
+        t1 = get_time()
+        elapsed_profile = t1 - t0
+        if verbose:
+            print "elapsed time with profiling =", elapsed_profile
+
+        # reported_time <- "CPU seconds" the profiler charged to f and f1.
+        total_calls = 0.0
+        reported_time = 0.0
+        for (filename, line, funcname), (cc, ns, tt, ct, callers) in \
+                p.timings.items():
+            if funcname in ("f", "f1"):
+                total_calls += cc
+                reported_time += tt
+
+        if verbose:
+            print "'CPU seconds' profiler reported =", reported_time
+            print "total # calls =", total_calls
+        if total_calls != m + 1:
+            raise ValueError("internal error: total calls = %d" % total_calls)
+
+        # reported_time - elapsed_noprofile = overhead the profiler wasn't
+        # able to measure.  Divide by twice the number of calls (since there
+        # are two profiler events per call in this test) to get the hidden
+        # overhead per event.
+        mean = (reported_time - elapsed_noprofile) / 2.0 / total_calls
+        if verbose:
+            print "mean stopwatch overhead per profile event =", mean
+        return mean
+
+#****************************************************************************
+def Stats(*args):
+    print 'Report generating functions are in the "pstats" module\a'
+
+def main():
+    usage = "profile.py [-o output_file_path] [-s sort] scriptfile [arg] ..."
+    parser = OptionParser(usage=usage)
+    parser.allow_interspersed_args = False
+    parser.add_option('-o', '--outfile', dest="outfile",
+        help="Save stats to <outfile>", default=None)
+    parser.add_option('-s', '--sort', dest="sort",
+        help="Sort order when printing to stdout, based on pstats.Stats class", default=-1)
+
+    if not sys.argv[1:]:
+        parser.print_usage()
+        sys.exit(2)
+
+    (options, args) = parser.parse_args()
+    sys.argv[:] = args
+
+    if (len(sys.argv) > 0):
+        sys.path.insert(0, os.path.dirname(sys.argv[0]))
+        run('execfile(%r)' % (sys.argv[0],), options.outfile, options.sort)
+    else:
+        parser.print_usage()
+    return parser
+
+# When invoked as main program, invoke the profiler on a script
+if __name__ == '__main__':
+    main()


Property changes on: vendor/Python/current/Lib/profile.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/pstats.py
===================================================================
--- vendor/Python/current/Lib/pstats.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/pstats.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,684 @@
+"""Class for printing reports on profiled python code."""
+
+# Class for printing reports on profiled python code. rev 1.0  4/1/94
+#
+# Based on prior profile module by Sjoerd Mullender...
+#   which was hacked somewhat by: Guido van Rossum
+#
+# see profile.doc and profile.py for more info.
+
+# Copyright 1994, by InfoSeek Corporation, all rights reserved.
+# Written by James Roskind
+#
+# Permission to use, copy, modify, and distribute this Python software
+# and its associated documentation for any purpose (subject to the
+# restriction in the following sentence) without fee is hereby granted,
+# provided that the above copyright notice appears in all copies, and
+# that both that copyright notice and this permission notice appear in
+# supporting documentation, and that the name of InfoSeek not be used in
+# advertising or publicity pertaining to distribution of the software
+# without specific, written prior permission.  This permission is
+# explicitly restricted to the copying and modification of the software
+# to remain in Python, compiled Python, or other languages (such as C)
+# wherein the modified or derived code is exclusively imported into a
+# Python module.
+#
+# INFOSEEK CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+# SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+# FITNESS. IN NO EVENT SHALL INFOSEEK CORPORATION BE LIABLE FOR ANY
+# SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+
+import sys
+import os
+import time
+import marshal
+import re
+
+__all__ = ["Stats"]
+
+class Stats:
+    """This class is used for creating reports from data generated by the
+    Profile class.  It is a "friend" of that class, and imports data either
+    by direct access to members of Profile class, or by reading in a dictionary
+    that was emitted (via marshal) from the Profile class.
+
+    The big change from the previous Profiler (in terms of raw functionality)
+    is that an "add()" method has been provided to combine Stats from
+    several distinct profile runs.  Both the constructor and the add()
+    method now take arbitrarily many file names as arguments.
+
+    All the print methods now take an argument that indicates how many lines
+    to print.  If the arg is a floating point number between 0 and 1.0, then
+    it is taken as a decimal percentage of the available lines to be printed
+    (e.g., .1 means print 10% of all available lines).  If it is an integer,
+    it is taken to mean the number of lines of data that you wish to have
+    printed.
+
+    The sort_stats() method now processes some additional options (i.e., in
+    addition to the old -1, 0, 1, or 2).  It takes an arbitrary number of
+    quoted strings to select the sort order.  For example sort_stats('time',
+    'name') sorts on the major key of 'internal function time', and on the
+    minor key of 'the name of the function'.  Look at the two tables in
+    sort_stats() and get_sort_arg_defs(self) for more examples.
+
+    All methods return self,  so you can string together commands like:
+        Stats('foo', 'goo').strip_dirs().sort_stats('calls').\
+                            print_stats(5).print_callers(5)
+    """
+
+    def __init__(self, *args, **kwds):
+        # I can't figure out how to explictly specify a stream keyword arg
+        # with *args:
+        #   def __init__(self, *args, stream=sys.stdout): ...
+        # so I use **kwds and sqauwk if something unexpected is passed in.
+        self.stream = sys.stdout
+        if "stream" in kwds:
+            self.stream = kwds["stream"]
+            del kwds["stream"]
+        if kwds:
+            keys = kwds.keys()
+            keys.sort()
+            extras = ", ".join(["%s=%s" % (k, kwds[k]) for k in keys])
+            raise ValueError, "unrecognized keyword args: %s" % extras
+        if not len(args):
+            arg = None
+        else:
+            arg = args[0]
+            args = args[1:]
+        self.init(arg)
+        self.add(*args)
+
+    def init(self, arg):
+        self.all_callees = None  # calc only if needed
+        self.files = []
+        self.fcn_list = None
+        self.total_tt = 0
+        self.total_calls = 0
+        self.prim_calls = 0
+        self.max_name_len = 0
+        self.top_level = {}
+        self.stats = {}
+        self.sort_arg_dict = {}
+        self.load_stats(arg)
+        trouble = 1
+        try:
+            self.get_top_level_stats()
+            trouble = 0
+        finally:
+            if trouble:
+                print >> self.stream, "Invalid timing data",
+                if self.files: print >> self.stream, self.files[-1],
+                print >> self.stream
+
+    def load_stats(self, arg):
+        if not arg:  self.stats = {}
+        elif isinstance(arg, basestring):
+            f = open(arg, 'rb')
+            self.stats = marshal.load(f)
+            f.close()
+            try:
+                file_stats = os.stat(arg)
+                arg = time.ctime(file_stats.st_mtime) + "    " + arg
+            except:  # in case this is not unix
+                pass
+            self.files = [ arg ]
+        elif hasattr(arg, 'create_stats'):
+            arg.create_stats()
+            self.stats = arg.stats
+            arg.stats = {}
+        if not self.stats:
+            raise TypeError,  "Cannot create or construct a %r object from '%r''" % (
+                              self.__class__, arg)
+        return
+
+    def get_top_level_stats(self):
+        for func, (cc, nc, tt, ct, callers) in self.stats.items():
+            self.total_calls += nc
+            self.prim_calls  += cc
+            self.total_tt    += tt
+            if callers.has_key(("jprofile", 0, "profiler")):
+                self.top_level[func] = None
+            if len(func_std_string(func)) > self.max_name_len:
+                self.max_name_len = len(func_std_string(func))
+
+    def add(self, *arg_list):
+        if not arg_list: return self
+        if len(arg_list) > 1: self.add(*arg_list[1:])
+        other = arg_list[0]
+        if type(self) != type(other) or self.__class__ != other.__class__:
+            other = Stats(other)
+        self.files += other.files
+        self.total_calls += other.total_calls
+        self.prim_calls += other.prim_calls
+        self.total_tt += other.total_tt
+        for func in other.top_level:
+            self.top_level[func] = None
+
+        if self.max_name_len < other.max_name_len:
+            self.max_name_len = other.max_name_len
+
+        self.fcn_list = None
+
+        for func, stat in other.stats.iteritems():
+            if func in self.stats:
+                old_func_stat = self.stats[func]
+            else:
+                old_func_stat = (0, 0, 0, 0, {},)
+            self.stats[func] = add_func_stats(old_func_stat, stat)
+        return self
+
+    def dump_stats(self, filename):
+        """Write the profile data to a file we know how to load back."""
+        f = file(filename, 'wb')
+        try:
+            marshal.dump(self.stats, f)
+        finally:
+            f.close()
+
+    # list the tuple indices and directions for sorting,
+    # along with some printable description
+    sort_arg_dict_default = {
+              "calls"     : (((1,-1),              ), "call count"),
+              "cumulative": (((3,-1),              ), "cumulative time"),
+              "file"      : (((4, 1),              ), "file name"),
+              "line"      : (((5, 1),              ), "line number"),
+              "module"    : (((4, 1),              ), "file name"),
+              "name"      : (((6, 1),              ), "function name"),
+              "nfl"       : (((6, 1),(4, 1),(5, 1),), "name/file/line"),
+              "pcalls"    : (((0,-1),              ), "call count"),
+              "stdname"   : (((7, 1),              ), "standard name"),
+              "time"      : (((2,-1),              ), "internal time"),
+              }
+
+    def get_sort_arg_defs(self):
+        """Expand all abbreviations that are unique."""
+        if not self.sort_arg_dict:
+            self.sort_arg_dict = dict = {}
+            bad_list = {}
+            for word, tup in self.sort_arg_dict_default.iteritems():
+                fragment = word
+                while fragment:
+                    if not fragment:
+                        break
+                    if fragment in dict:
+                        bad_list[fragment] = 0
+                        break
+                    dict[fragment] = tup
+                    fragment = fragment[:-1]
+            for word in bad_list:
+                del dict[word]
+        return self.sort_arg_dict
+
+    def sort_stats(self, *field):
+        if not field:
+            self.fcn_list = 0
+            return self
+        if len(field) == 1 and type(field[0]) == type(1):
+            # Be compatible with old profiler
+            field = [ {-1: "stdname",
+                      0:"calls",
+                      1:"time",
+                      2: "cumulative" }  [ field[0] ] ]
+
+        sort_arg_defs = self.get_sort_arg_defs()
+        sort_tuple = ()
+        self.sort_type = ""
+        connector = ""
+        for word in field:
+            sort_tuple = sort_tuple + sort_arg_defs[word][0]
+            self.sort_type += connector + sort_arg_defs[word][1]
+            connector = ", "
+
+        stats_list = []
+        for func, (cc, nc, tt, ct, callers) in self.stats.iteritems():
+            stats_list.append((cc, nc, tt, ct) + func +
+                              (func_std_string(func), func))
+
+        stats_list.sort(TupleComp(sort_tuple).compare)
+
+        self.fcn_list = fcn_list = []
+        for tuple in stats_list:
+            fcn_list.append(tuple[-1])
+        return self
+
+    def reverse_order(self):
+        if self.fcn_list:
+            self.fcn_list.reverse()
+        return self
+
+    def strip_dirs(self):
+        oldstats = self.stats
+        self.stats = newstats = {}
+        max_name_len = 0
+        for func, (cc, nc, tt, ct, callers) in oldstats.iteritems():
+            newfunc = func_strip_path(func)
+            if len(func_std_string(newfunc)) > max_name_len:
+                max_name_len = len(func_std_string(newfunc))
+            newcallers = {}
+            for func2, caller in callers.iteritems():
+                newcallers[func_strip_path(func2)] = caller
+
+            if newfunc in newstats:
+                newstats[newfunc] = add_func_stats(
+                                        newstats[newfunc],
+                                        (cc, nc, tt, ct, newcallers))
+            else:
+                newstats[newfunc] = (cc, nc, tt, ct, newcallers)
+        old_top = self.top_level
+        self.top_level = new_top = {}
+        for func in old_top:
+            new_top[func_strip_path(func)] = None
+
+        self.max_name_len = max_name_len
+
+        self.fcn_list = None
+        self.all_callees = None
+        return self
+
+    def calc_callees(self):
+        if self.all_callees: return
+        self.all_callees = all_callees = {}
+        for func, (cc, nc, tt, ct, callers) in self.stats.iteritems():
+            if not func in all_callees:
+                all_callees[func] = {}
+            for func2, caller in callers.iteritems():
+                if not func2 in all_callees:
+                    all_callees[func2] = {}
+                all_callees[func2][func]  = caller
+        return
+
+    #******************************************************************
+    # The following functions support actual printing of reports
+    #******************************************************************
+
+    # Optional "amount" is either a line count, or a percentage of lines.
+
+    def eval_print_amount(self, sel, list, msg):
+        new_list = list
+        if type(sel) == type(""):
+            new_list = []
+            for func in list:
+                if re.search(sel, func_std_string(func)):
+                    new_list.append(func)
+        else:
+            count = len(list)
+            if type(sel) == type(1.0) and 0.0 <= sel < 1.0:
+                count = int(count * sel + .5)
+                new_list = list[:count]
+            elif type(sel) == type(1) and 0 <= sel < count:
+                count = sel
+                new_list = list[:count]
+        if len(list) != len(new_list):
+            msg = msg + "   List reduced from %r to %r due to restriction <%r>\n" % (
+                         len(list), len(new_list), sel)
+
+        return new_list, msg
+
+    def get_print_list(self, sel_list):
+        width = self.max_name_len
+        if self.fcn_list:
+            list = self.fcn_list[:]
+            msg = "   Ordered by: " + self.sort_type + '\n'
+        else:
+            list = self.stats.keys()
+            msg = "   Random listing order was used\n"
+
+        for selection in sel_list:
+            list, msg = self.eval_print_amount(selection, list, msg)
+
+        count = len(list)
+
+        if not list:
+            return 0, list
+        print >> self.stream, msg
+        if count < len(self.stats):
+            width = 0
+            for func in list:
+                if  len(func_std_string(func)) > width:
+                    width = len(func_std_string(func))
+        return width+2, list
+
+    def print_stats(self, *amount):
+        for filename in self.files:
+            print >> self.stream, filename
+        if self.files: print >> self.stream
+        indent = ' ' * 8
+        for func in self.top_level:
+            print >> self.stream, indent, func_get_function_name(func)
+
+        print >> self.stream, indent, self.total_calls, "function calls",
+        if self.total_calls != self.prim_calls:
+            print >> self.stream, "(%d primitive calls)" % self.prim_calls,
+        print >> self.stream, "in %.3f CPU seconds" % self.total_tt
+        print >> self.stream
+        width, list = self.get_print_list(amount)
+        if list:
+            self.print_title()
+            for func in list:
+                self.print_line(func)
+            print >> self.stream
+            print >> self.stream
+        return self
+
+    def print_callees(self, *amount):
+        width, list = self.get_print_list(amount)
+        if list:
+            self.calc_callees()
+
+            self.print_call_heading(width, "called...")
+            for func in list:
+                if func in self.all_callees:
+                    self.print_call_line(width, func, self.all_callees[func])
+                else:
+                    self.print_call_line(width, func, {})
+            print >> self.stream
+            print >> self.stream
+        return self
+
+    def print_callers(self, *amount):
+        width, list = self.get_print_list(amount)
+        if list:
+            self.print_call_heading(width, "was called by...")
+            for func in list:
+                cc, nc, tt, ct, callers = self.stats[func]
+                self.print_call_line(width, func, callers, "<-")
+            print >> self.stream
+            print >> self.stream
+        return self
+
+    def print_call_heading(self, name_size, column_title):
+        print >> self.stream, "Function ".ljust(name_size) + column_title
+        # print sub-header only if we have new-style callers
+        subheader = False
+        for cc, nc, tt, ct, callers in self.stats.itervalues():
+            if callers:
+                value = callers.itervalues().next()
+                subheader = isinstance(value, tuple)
+                break
+        if subheader:
+            print >> self.stream, " "*name_size + "    ncalls  tottime  cumtime"
+
+    def print_call_line(self, name_size, source, call_dict, arrow="->"):
+        print >> self.stream, func_std_string(source).ljust(name_size) + arrow,
+        if not call_dict:
+            print >> self.stream
+            return
+        clist = call_dict.keys()
+        clist.sort()
+        indent = ""
+        for func in clist:
+            name = func_std_string(func)
+            value = call_dict[func]
+            if isinstance(value, tuple):
+                nc, cc, tt, ct = value
+                if nc != cc:
+                    substats = '%d/%d' % (nc, cc)
+                else:
+                    substats = '%d' % (nc,)
+                substats = '%s %s %s  %s' % (substats.rjust(7+2*len(indent)),
+                                             f8(tt), f8(ct), name)
+                left_width = name_size + 1
+            else:
+                substats = '%s(%r) %s' % (name, value, f8(self.stats[func][3]))
+                left_width = name_size + 3
+            print >> self.stream, indent*left_width + substats
+            indent = " "
+
+    def print_title(self):
+        print >> self.stream, '   ncalls  tottime  percall  cumtime  percall',
+        print >> self.stream, 'filename:lineno(function)'
+
+    def print_line(self, func):  # hack : should print percentages
+        cc, nc, tt, ct, callers = self.stats[func]
+        c = str(nc)
+        if nc != cc:
+            c = c + '/' + str(cc)
+        print >> self.stream, c.rjust(9),
+        print >> self.stream, f8(tt),
+        if nc == 0:
+            print >> self.stream, ' '*8,
+        else:
+            print >> self.stream, f8(tt/nc),
+        print >> self.stream, f8(ct),
+        if cc == 0:
+            print >> self.stream, ' '*8,
+        else:
+            print >> self.stream, f8(ct/cc),
+        print >> self.stream, func_std_string(func)
+
+class TupleComp:
+    """This class provides a generic function for comparing any two tuples.
+    Each instance records a list of tuple-indices (from most significant
+    to least significant), and sort direction (ascending or decending) for
+    each tuple-index.  The compare functions can then be used as the function
+    argument to the system sort() function when a list of tuples need to be
+    sorted in the instances order."""
+
+    def __init__(self, comp_select_list):
+        self.comp_select_list = comp_select_list
+
+    def compare (self, left, right):
+        for index, direction in self.comp_select_list:
+            l = left[index]
+            r = right[index]
+            if l < r:
+                return -direction
+            if l > r:
+                return direction
+        return 0
+
+#**************************************************************************
+# func_name is a triple (file:string, line:int, name:string)
+
+def func_strip_path(func_name):
+    filename, line, name = func_name
+    return os.path.basename(filename), line, name
+
+def func_get_function_name(func):
+    return func[2]
+
+def func_std_string(func_name): # match what old profile produced
+    if func_name[:2] == ('~', 0):
+        # special case for built-in functions
+        name = func_name[2]
+        if name.startswith('<') and name.endswith('>'):
+            return '{%s}' % name[1:-1]
+        else:
+            return name
+    else:
+        return "%s:%d(%s)" % func_name
+
+#**************************************************************************
+# The following functions combine statists for pairs functions.
+# The bulk of the processing involves correctly handling "call" lists,
+# such as callers and callees.
+#**************************************************************************
+
+def add_func_stats(target, source):
+    """Add together all the stats for two profile entries."""
+    cc, nc, tt, ct, callers = source
+    t_cc, t_nc, t_tt, t_ct, t_callers = target
+    return (cc+t_cc, nc+t_nc, tt+t_tt, ct+t_ct,
+              add_callers(t_callers, callers))
+
+def add_callers(target, source):
+    """Combine two caller lists in a single list."""
+    new_callers = {}
+    for func, caller in target.iteritems():
+        new_callers[func] = caller
+    for func, caller in source.iteritems():
+        if func in new_callers:
+            new_callers[func] = caller + new_callers[func]
+        else:
+            new_callers[func] = caller
+    return new_callers
+
+def count_calls(callers):
+    """Sum the caller statistics to get total number of calls received."""
+    nc = 0
+    for calls in callers.itervalues():
+        nc += calls
+    return nc
+
+#**************************************************************************
+# The following functions support printing of reports
+#**************************************************************************
+
+def f8(x):
+    return "%8.3f" % x
+
+#**************************************************************************
+# Statistics browser added by ESR, April 2001
+#**************************************************************************
+
+if __name__ == '__main__':
+    import cmd
+    try:
+        import readline
+    except ImportError:
+        pass
+
+    class ProfileBrowser(cmd.Cmd):
+        def __init__(self, profile=None):
+            cmd.Cmd.__init__(self)
+            self.prompt = "% "
+            if profile is not None:
+                self.stats = Stats(profile)
+                self.stream = self.stats.stream
+            else:
+                self.stats = None
+                self.stream = sys.stdout
+
+        def generic(self, fn, line):
+            args = line.split()
+            processed = []
+            for term in args:
+                try:
+                    processed.append(int(term))
+                    continue
+                except ValueError:
+                    pass
+                try:
+                    frac = float(term)
+                    if frac > 1 or frac < 0:
+                        print >> self.stream, "Fraction argument must be in [0, 1]"
+                        continue
+                    processed.append(frac)
+                    continue
+                except ValueError:
+                    pass
+                processed.append(term)
+            if self.stats:
+                getattr(self.stats, fn)(*processed)
+            else:
+                print >> self.stream, "No statistics object is loaded."
+            return 0
+        def generic_help(self):
+            print >> self.stream, "Arguments may be:"
+            print >> self.stream, "* An integer maximum number of entries to print."
+            print >> self.stream, "* A decimal fractional number between 0 and 1, controlling"
+            print >> self.stream, "  what fraction of selected entries to print."
+            print >> self.stream, "* A regular expression; only entries with function names"
+            print >> self.stream, "  that match it are printed."
+
+        def do_add(self, line):
+            self.stats.add(line)
+            return 0
+        def help_add(self):
+            print >> self.stream, "Add profile info from given file to current statistics object."
+
+        def do_callees(self, line):
+            return self.generic('print_callees', line)
+        def help_callees(self):
+            print >> self.stream, "Print callees statistics from the current stat object."
+            self.generic_help()
+
+        def do_callers(self, line):
+            return self.generic('print_callers', line)
+        def help_callers(self):
+            print >> self.stream, "Print callers statistics from the current stat object."
+            self.generic_help()
+
+        def do_EOF(self, line):
+            print >> self.stream, ""
+            return 1
+        def help_EOF(self):
+            print >> self.stream, "Leave the profile brower."
+
+        def do_quit(self, line):
+            return 1
+        def help_quit(self):
+            print >> self.stream, "Leave the profile brower."
+
+        def do_read(self, line):
+            if line:
+                try:
+                    self.stats = Stats(line)
+                except IOError, args:
+                    print >> self.stream, args[1]
+                    return
+                self.prompt = line + "% "
+            elif len(self.prompt) > 2:
+                line = self.prompt[-2:]
+            else:
+                print >> self.stream, "No statistics object is current -- cannot reload."
+            return 0
+        def help_read(self):
+            print >> self.stream, "Read in profile data from a specified file."
+
+        def do_reverse(self, line):
+            self.stats.reverse_order()
+            return 0
+        def help_reverse(self):
+            print >> self.stream, "Reverse the sort order of the profiling report."
+
+        def do_sort(self, line):
+            abbrevs = self.stats.get_sort_arg_defs()
+            if line and not filter(lambda x,a=abbrevs: x not in a,line.split()):
+                self.stats.sort_stats(*line.split())
+            else:
+                print >> self.stream, "Valid sort keys (unique prefixes are accepted):"
+                for (key, value) in Stats.sort_arg_dict_default.iteritems():
+                    print >> self.stream, "%s -- %s" % (key, value[1])
+            return 0
+        def help_sort(self):
+            print >> self.stream, "Sort profile data according to specified keys."
+            print >> self.stream, "(Typing `sort' without arguments lists valid keys.)"
+        def complete_sort(self, text, *args):
+            return [a for a in Stats.sort_arg_dict_default if a.startswith(text)]
+
+        def do_stats(self, line):
+            return self.generic('print_stats', line)
+        def help_stats(self):
+            print >> self.stream, "Print statistics from the current stat object."
+            self.generic_help()
+
+        def do_strip(self, line):
+            self.stats.strip_dirs()
+            return 0
+        def help_strip(self):
+            print >> self.stream, "Strip leading path information from filenames in the report."
+
+        def postcmd(self, stop, line):
+            if stop:
+                return stop
+            return None
+
+    import sys
+    if len(sys.argv) > 1:
+        initprofile = sys.argv[1]
+    else:
+        initprofile = None
+    try:
+        browser = ProfileBrowser(initprofile)
+        print >> browser.stream, "Welcome to the profile statistics browser."
+        browser.cmdloop()
+        print >> browser.stream, "Goodbye."
+    except KeyboardInterrupt:
+        pass
+
+# That's all, folks.

Added: vendor/Python/current/Lib/pty.py
===================================================================
--- vendor/Python/current/Lib/pty.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/pty.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,174 @@
+"""Pseudo terminal utilities."""
+
+# Bugs: No signal handling.  Doesn't set slave termios and window size.
+#       Only tested on Linux.
+# See:  W. Richard Stevens. 1992.  Advanced Programming in the
+#       UNIX Environment.  Chapter 19.
+# Author: Steen Lumholt -- with additions by Guido.
+
+from select import select
+import os
+import tty
+
+__all__ = ["openpty","fork","spawn"]
+
+STDIN_FILENO = 0
+STDOUT_FILENO = 1
+STDERR_FILENO = 2
+
+CHILD = 0
+
+def openpty():
+    """openpty() -> (master_fd, slave_fd)
+    Open a pty master/slave pair, using os.openpty() if possible."""
+
+    try:
+        return os.openpty()
+    except (AttributeError, OSError):
+        pass
+    master_fd, slave_name = _open_terminal()
+    slave_fd = slave_open(slave_name)
+    return master_fd, slave_fd
+
+def master_open():
+    """master_open() -> (master_fd, slave_name)
+    Open a pty master and return the fd, and the filename of the slave end.
+    Deprecated, use openpty() instead."""
+
+    try:
+        master_fd, slave_fd = os.openpty()
+    except (AttributeError, OSError):
+        pass
+    else:
+        slave_name = os.ttyname(slave_fd)
+        os.close(slave_fd)
+        return master_fd, slave_name
+
+    return _open_terminal()
+
+def _open_terminal():
+    """Open pty master and return (master_fd, tty_name).
+    SGI and generic BSD version, for when openpty() fails."""
+    try:
+        import sgi
+    except ImportError:
+        pass
+    else:
+        try:
+            tty_name, master_fd = sgi._getpty(os.O_RDWR, 0666, 0)
+        except IOError, msg:
+            raise os.error, msg
+        return master_fd, tty_name
+    for x in 'pqrstuvwxyzPQRST':
+        for y in '0123456789abcdef':
+            pty_name = '/dev/pty' + x + y
+            try:
+                fd = os.open(pty_name, os.O_RDWR)
+            except os.error:
+                continue
+            return (fd, '/dev/tty' + x + y)
+    raise os.error, 'out of pty devices'
+
+def slave_open(tty_name):
+    """slave_open(tty_name) -> slave_fd
+    Open the pty slave and acquire the controlling terminal, returning
+    opened filedescriptor.
+    Deprecated, use openpty() instead."""
+
+    result = os.open(tty_name, os.O_RDWR)
+    try:
+        from fcntl import ioctl, I_PUSH
+    except ImportError:
+        return result
+    try:
+        ioctl(result, I_PUSH, "ptem")
+        ioctl(result, I_PUSH, "ldterm")
+    except IOError:
+        pass
+    return result
+
+def fork():
+    """fork() -> (pid, master_fd)
+    Fork and make the child a session leader with a controlling terminal."""
+
+    try:
+        pid, fd = os.forkpty()
+    except (AttributeError, OSError):
+        pass
+    else:
+        if pid == CHILD:
+            try:
+                os.setsid()
+            except OSError:
+                # os.forkpty() already set us session leader
+                pass
+        return pid, fd
+
+    master_fd, slave_fd = openpty()
+    pid = os.fork()
+    if pid == CHILD:
+        # Establish a new session.
+        os.setsid()
+        os.close(master_fd)
+
+        # Slave becomes stdin/stdout/stderr of child.
+        os.dup2(slave_fd, STDIN_FILENO)
+        os.dup2(slave_fd, STDOUT_FILENO)
+        os.dup2(slave_fd, STDERR_FILENO)
+        if (slave_fd > STDERR_FILENO):
+            os.close (slave_fd)
+
+        # Explicitly open the tty to make it become a controlling tty.
+        tmp_fd = os.open(os.ttyname(STDOUT_FILENO), os.O_RDWR)
+        os.close(tmp_fd)
+    else:
+        os.close(slave_fd)
+
+    # Parent and child process.
+    return pid, master_fd
+
+def _writen(fd, data):
+    """Write all the data to a descriptor."""
+    while data != '':
+        n = os.write(fd, data)
+        data = data[n:]
+
+def _read(fd):
+    """Default read function."""
+    return os.read(fd, 1024)
+
+def _copy(master_fd, master_read=_read, stdin_read=_read):
+    """Parent copy loop.
+    Copies
+            pty master -> standard output   (master_read)
+            standard input -> pty master    (stdin_read)"""
+    while 1:
+        rfds, wfds, xfds = select(
+                [master_fd, STDIN_FILENO], [], [])
+        if master_fd in rfds:
+            data = master_read(master_fd)
+            os.write(STDOUT_FILENO, data)
+        if STDIN_FILENO in rfds:
+            data = stdin_read(STDIN_FILENO)
+            _writen(master_fd, data)
+
+def spawn(argv, master_read=_read, stdin_read=_read):
+    """Create a spawned process."""
+    if type(argv) == type(''):
+        argv = (argv,)
+    pid, master_fd = fork()
+    if pid == CHILD:
+        os.execlp(argv[0], *argv)
+    try:
+        mode = tty.tcgetattr(STDIN_FILENO)
+        tty.setraw(STDIN_FILENO)
+        restore = 1
+    except tty.error:    # This is the same as termios.error
+        restore = 0
+    try:
+        _copy(master_fd, master_read, stdin_read)
+    except (IOError, OSError):
+        if restore:
+            tty.tcsetattr(STDIN_FILENO, tty.TCSAFLUSH, mode)
+
+    os.close(master_fd)

Added: vendor/Python/current/Lib/py_compile.py
===================================================================
--- vendor/Python/current/Lib/py_compile.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/py_compile.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,164 @@
+"""Routine to "compile" a .py file to a .pyc (or .pyo) file.
+
+This module has intimate knowledge of the format of .pyc files.
+"""
+
+import __builtin__
+import imp
+import marshal
+import os
+import sys
+import traceback
+
+MAGIC = imp.get_magic()
+
+__all__ = ["compile", "main", "PyCompileError"]
+
+
+class PyCompileError(Exception):
+    """Exception raised when an error occurs while attempting to
+    compile the file.
+
+    To raise this exception, use
+
+        raise PyCompileError(exc_type,exc_value,file[,msg])
+
+    where
+
+        exc_type:   exception type to be used in error message
+                    type name can be accesses as class variable
+                    'exc_type_name'
+
+        exc_value:  exception value to be used in error message
+                    can be accesses as class variable 'exc_value'
+
+        file:       name of file being compiled to be used in error message
+                    can be accesses as class variable 'file'
+
+        msg:        string message to be written as error message
+                    If no value is given, a default exception message will be given,
+                    consistent with 'standard' py_compile output.
+                    message (or default) can be accesses as class variable 'msg'
+
+    """
+
+    def __init__(self, exc_type, exc_value, file, msg=''):
+        exc_type_name = exc_type.__name__
+        if exc_type is SyntaxError:
+            tbtext = ''.join(traceback.format_exception_only(exc_type, exc_value))
+            errmsg = tbtext.replace('File "<string>"', 'File "%s"' % file)
+        else:
+            errmsg = "Sorry: %s: %s" % (exc_type_name,exc_value)
+
+        Exception.__init__(self,msg or errmsg,exc_type_name,exc_value,file)
+
+        self.exc_type_name = exc_type_name
+        self.exc_value = exc_value
+        self.file = file
+        self.msg = msg or errmsg
+
+    def __str__(self):
+        return self.msg
+
+
+# Define an internal helper according to the platform
+if os.name == "mac":
+    import MacOS
+    def set_creator_type(file):
+        MacOS.SetCreatorAndType(file, 'Pyth', 'PYC ')
+else:
+    def set_creator_type(file):
+        pass
+
+def wr_long(f, x):
+    """Internal; write a 32-bit int to a file in little-endian order."""
+    f.write(chr( x        & 0xff))
+    f.write(chr((x >> 8)  & 0xff))
+    f.write(chr((x >> 16) & 0xff))
+    f.write(chr((x >> 24) & 0xff))
+
+def compile(file, cfile=None, dfile=None, doraise=False):
+    """Byte-compile one Python source file to Python bytecode.
+
+    Arguments:
+
+    file:    source filename
+    cfile:   target filename; defaults to source with 'c' or 'o' appended
+             ('c' normally, 'o' in optimizing mode, giving .pyc or .pyo)
+    dfile:   purported filename; defaults to source (this is the filename
+             that will show up in error messages)
+    doraise: flag indicating whether or not an exception should be
+             raised when a compile error is found. If an exception
+             occurs and this flag is set to False, a string
+             indicating the nature of the exception will be printed,
+             and the function will return to the caller. If an
+             exception occurs and this flag is set to True, a
+             PyCompileError exception will be raised.
+
+    Note that it isn't necessary to byte-compile Python modules for
+    execution efficiency -- Python itself byte-compiles a module when
+    it is loaded, and if it can, writes out the bytecode to the
+    corresponding .pyc (or .pyo) file.
+
+    However, if a Python installation is shared between users, it is a
+    good idea to byte-compile all modules upon installation, since
+    other users may not be able to write in the source directories,
+    and thus they won't be able to write the .pyc/.pyo file, and then
+    they would be byte-compiling every module each time it is loaded.
+    This can slow down program start-up considerably.
+
+    See compileall.py for a script/module that uses this module to
+    byte-compile all installed files (or all files in selected
+    directories).
+
+    """
+    f = open(file, 'U')
+    try:
+        timestamp = long(os.fstat(f.fileno()).st_mtime)
+    except AttributeError:
+        timestamp = long(os.stat(file).st_mtime)
+    codestring = f.read()
+    f.close()
+    if codestring and codestring[-1] != '\n':
+        codestring = codestring + '\n'
+    try:
+        codeobject = __builtin__.compile(codestring, dfile or file,'exec')
+    except Exception,err:
+        py_exc = PyCompileError(err.__class__,err.args,dfile or file)
+        if doraise:
+            raise py_exc
+        else:
+            sys.stderr.write(py_exc.msg + '\n')
+            return
+    if cfile is None:
+        cfile = file + (__debug__ and 'c' or 'o')
+    fc = open(cfile, 'wb')
+    fc.write('\0\0\0\0')
+    wr_long(fc, timestamp)
+    marshal.dump(codeobject, fc)
+    fc.flush()
+    fc.seek(0, 0)
+    fc.write(MAGIC)
+    fc.close()
+    set_creator_type(cfile)
+
+def main(args=None):
+    """Compile several source files.
+
+    The files named in 'args' (or on the command line, if 'args' is
+    not specified) are compiled and the resulting bytecode is cached
+    in the normal manner.  This function does not search a directory
+    structure to locate source files; it only compiles files named
+    explicitly.
+
+    """
+    if args is None:
+        args = sys.argv[1:]
+    for filename in args:
+        try:
+            compile(filename, doraise=True)
+        except PyCompileError,err:
+            sys.stderr.write(err.msg)
+
+if __name__ == "__main__":
+    main()

Added: vendor/Python/current/Lib/pyclbr.py
===================================================================
--- vendor/Python/current/Lib/pyclbr.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/pyclbr.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,340 @@
+"""Parse a Python module and describe its classes and methods.
+
+Parse enough of a Python file to recognize imports and class and
+method definitions, and to find out the superclasses of a class.
+
+The interface consists of a single function:
+        readmodule_ex(module [, path])
+where module is the name of a Python module, and path is an optional
+list of directories where the module is to be searched.  If present,
+path is prepended to the system search path sys.path.  The return
+value is a dictionary.  The keys of the dictionary are the names of
+the classes defined in the module (including classes that are defined
+via the from XXX import YYY construct).  The values are class
+instances of the class Class defined here.  One special key/value pair
+is present for packages: the key '__path__' has a list as its value
+which contains the package search path.
+
+A class is described by the class Class in this module.  Instances
+of this class have the following instance variables:
+        module -- the module name
+        name -- the name of the class
+        super -- a list of super classes (Class instances)
+        methods -- a dictionary of methods
+        file -- the file in which the class was defined
+        lineno -- the line in the file on which the class statement occurred
+The dictionary of methods uses the method names as keys and the line
+numbers on which the method was defined as values.
+If the name of a super class is not recognized, the corresponding
+entry in the list of super classes is not a class instance but a
+string giving the name of the super class.  Since import statements
+are recognized and imported modules are scanned as well, this
+shouldn't happen often.
+
+A function is described by the class Function in this module.
+Instances of this class have the following instance variables:
+        module -- the module name
+        name -- the name of the class
+        file -- the file in which the class was defined
+        lineno -- the line in the file on which the class statement occurred
+"""
+
+import sys
+import imp
+import tokenize # Python tokenizer
+from token import NAME, DEDENT, NEWLINE, OP
+from operator import itemgetter
+
+__all__ = ["readmodule", "readmodule_ex", "Class", "Function"]
+
+_modules = {}                           # cache of modules we've seen
+
+# each Python class is represented by an instance of this class
+class Class:
+    '''Class to represent a Python class.'''
+    def __init__(self, module, name, super, file, lineno):
+        self.module = module
+        self.name = name
+        if super is None:
+            super = []
+        self.super = super
+        self.methods = {}
+        self.file = file
+        self.lineno = lineno
+
+    def _addmethod(self, name, lineno):
+        self.methods[name] = lineno
+
+class Function:
+    '''Class to represent a top-level Python function'''
+    def __init__(self, module, name, file, lineno):
+        self.module = module
+        self.name = name
+        self.file = file
+        self.lineno = lineno
+
+def readmodule(module, path=[]):
+    '''Backwards compatible interface.
+
+    Call readmodule_ex() and then only keep Class objects from the
+    resulting dictionary.'''
+
+    dict = _readmodule(module, path)
+    res = {}
+    for key, value in dict.items():
+        if isinstance(value, Class):
+            res[key] = value
+    return res
+
+def readmodule_ex(module, path=[]):
+    '''Read a module file and return a dictionary of classes.
+
+    Search for MODULE in PATH and sys.path, read and parse the
+    module and return a dictionary with one entry for each class
+    found in the module.
+
+    If INPACKAGE is true, it must be the dotted name of the package in
+    which we are searching for a submodule, and then PATH must be the
+    package search path; otherwise, we are searching for a top-level
+    module, and PATH is combined with sys.path.
+    '''
+    return _readmodule(module, path)
+
+def _readmodule(module, path, inpackage=None):
+    '''Do the hard work for readmodule[_ex].'''
+    # Compute the full module name (prepending inpackage if set)
+    if inpackage:
+        fullmodule = "%s.%s" % (inpackage, module)
+    else:
+        fullmodule = module
+
+    # Check in the cache
+    if fullmodule in _modules:
+        return _modules[fullmodule]
+
+    # Initialize the dict for this module's contents
+    dict = {}
+
+    # Check if it is a built-in module; we don't do much for these
+    if module in sys.builtin_module_names and not inpackage:
+        _modules[module] = dict
+        return dict
+
+    # Check for a dotted module name
+    i = module.rfind('.')
+    if i >= 0:
+        package = module[:i]
+        submodule = module[i+1:]
+        parent = _readmodule(package, path, inpackage)
+        if inpackage:
+            package = "%s.%s" % (inpackage, package)
+        return _readmodule(submodule, parent['__path__'], package)
+
+    # Search the path for the module
+    f = None
+    if inpackage:
+        f, file, (suff, mode, type) = imp.find_module(module, path)
+    else:
+        f, file, (suff, mode, type) = imp.find_module(module, path + sys.path)
+    if type == imp.PKG_DIRECTORY:
+        dict['__path__'] = [file]
+        path = [file] + path
+        f, file, (suff, mode, type) = imp.find_module('__init__', [file])
+    _modules[fullmodule] = dict
+    if type != imp.PY_SOURCE:
+        # not Python source, can't do anything with this module
+        f.close()
+        return dict
+
+    stack = [] # stack of (class, indent) pairs
+
+    g = tokenize.generate_tokens(f.readline)
+    try:
+        for tokentype, token, start, end, line in g:
+            if tokentype == DEDENT:
+                lineno, thisindent = start
+                # close nested classes and defs
+                while stack and stack[-1][1] >= thisindent:
+                    del stack[-1]
+            elif token == 'def':
+                lineno, thisindent = start
+                # close previous nested classes and defs
+                while stack and stack[-1][1] >= thisindent:
+                    del stack[-1]
+                tokentype, meth_name, start, end, line = g.next()
+                if tokentype != NAME:
+                    continue # Syntax error
+                if stack:
+                    cur_class = stack[-1][0]
+                    if isinstance(cur_class, Class):
+                        # it's a method
+                        cur_class._addmethod(meth_name, lineno)
+                    # else it's a nested def
+                else:
+                    # it's a function
+                    dict[meth_name] = Function(fullmodule, meth_name, file, lineno)
+                stack.append((None, thisindent)) # Marker for nested fns
+            elif token == 'class':
+                lineno, thisindent = start
+                # close previous nested classes and defs
+                while stack and stack[-1][1] >= thisindent:
+                    del stack[-1]
+                tokentype, class_name, start, end, line = g.next()
+                if tokentype != NAME:
+                    continue # Syntax error
+                # parse what follows the class name
+                tokentype, token, start, end, line = g.next()
+                inherit = None
+                if token == '(':
+                    names = [] # List of superclasses
+                    # there's a list of superclasses
+                    level = 1
+                    super = [] # Tokens making up current superclass
+                    while True:
+                        tokentype, token, start, end, line = g.next()
+                        if token in (')', ',') and level == 1:
+                            n = "".join(super)
+                            if n in dict:
+                                # we know this super class
+                                n = dict[n]
+                            else:
+                                c = n.split('.')
+                                if len(c) > 1:
+                                    # super class is of the form
+                                    # module.class: look in module for
+                                    # class
+                                    m = c[-2]
+                                    c = c[-1]
+                                    if m in _modules:
+                                        d = _modules[m]
+                                        if c in d:
+                                            n = d[c]
+                            names.append(n)
+                            super = []
+                        if token == '(':
+                            level += 1
+                        elif token == ')':
+                            level -= 1
+                            if level == 0:
+                                break
+                        elif token == ',' and level == 1:
+                            pass
+                        # only use NAME and OP (== dot) tokens for type name
+                        elif tokentype in (NAME, OP) and level == 1:
+                            super.append(token)
+                        # expressions in the base list are not supported
+                    inherit = names
+                cur_class = Class(fullmodule, class_name, inherit, file, lineno)
+                if not stack:
+                    dict[class_name] = cur_class
+                stack.append((cur_class, thisindent))
+            elif token == 'import' and start[1] == 0:
+                modules = _getnamelist(g)
+                for mod, mod2 in modules:
+                    try:
+                        # Recursively read the imported module
+                        if not inpackage:
+                            _readmodule(mod, path)
+                        else:
+                            try:
+                                _readmodule(mod, path, inpackage)
+                            except ImportError:
+                                _readmodule(mod, [])
+                    except:
+                        # If we can't find or parse the imported module,
+                        # too bad -- don't die here.
+                        pass
+            elif token == 'from' and start[1] == 0:
+                mod, token = _getname(g)
+                if not mod or token != "import":
+                    continue
+                names = _getnamelist(g)
+                try:
+                    # Recursively read the imported module
+                    d = _readmodule(mod, path, inpackage)
+                except:
+                    # If we can't find or parse the imported module,
+                    # too bad -- don't die here.
+                    continue
+                # add any classes that were defined in the imported module
+                # to our name space if they were mentioned in the list
+                for n, n2 in names:
+                    if n in d:
+                        dict[n2 or n] = d[n]
+                    elif n == '*':
+                        # don't add names that start with _
+                        for n in d:
+                            if n[0] != '_':
+                                dict[n] = d[n]
+    except StopIteration:
+        pass
+
+    f.close()
+    return dict
+
+def _getnamelist(g):
+    # Helper to get a comma-separated list of dotted names plus 'as'
+    # clauses.  Return a list of pairs (name, name2) where name2 is
+    # the 'as' name, or None if there is no 'as' clause.
+    names = []
+    while True:
+        name, token = _getname(g)
+        if not name:
+            break
+        if token == 'as':
+            name2, token = _getname(g)
+        else:
+            name2 = None
+        names.append((name, name2))
+        while token != "," and "\n" not in token:
+            tokentype, token, start, end, line = g.next()
+        if token != ",":
+            break
+    return names
+
+def _getname(g):
+    # Helper to get a dotted name, return a pair (name, token) where
+    # name is the dotted name, or None if there was no dotted name,
+    # and token is the next input token.
+    parts = []
+    tokentype, token, start, end, line = g.next()
+    if tokentype != NAME and token != '*':
+        return (None, token)
+    parts.append(token)
+    while True:
+        tokentype, token, start, end, line = g.next()
+        if token != '.':
+            break
+        tokentype, token, start, end, line = g.next()
+        if tokentype != NAME:
+            break
+        parts.append(token)
+    return (".".join(parts), token)
+
+def _main():
+    # Main program for testing.
+    import os
+    mod = sys.argv[1]
+    if os.path.exists(mod):
+        path = [os.path.dirname(mod)]
+        mod = os.path.basename(mod)
+        if mod.lower().endswith(".py"):
+            mod = mod[:-3]
+    else:
+        path = []
+    dict = readmodule_ex(mod, path)
+    objs = dict.values()
+    objs.sort(lambda a, b: cmp(getattr(a, 'lineno', 0),
+                               getattr(b, 'lineno', 0)))
+    for obj in objs:
+        if isinstance(obj, Class):
+            print "class", obj.name, obj.super, obj.lineno
+            methods = sorted(obj.methods.iteritems(), key=itemgetter(1))
+            for name, lineno in methods:
+                if name != "__path__":
+                    print "  def", name, lineno
+        elif isinstance(obj, Function):
+            print "def", obj.name, obj.lineno
+
+if __name__ == "__main__":
+    _main()

Added: vendor/Python/current/Lib/pydoc.py
===================================================================
--- vendor/Python/current/Lib/pydoc.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/pydoc.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2255 @@
+#!/usr/bin/env python
+# -*- coding: Latin-1 -*-
+"""Generate Python documentation in HTML or text for interactive use.
+
+In the Python interpreter, do "from pydoc import help" to provide online
+help.  Calling help(thing) on a Python object documents the object.
+
+Or, at the shell command line outside of Python:
+
+Run "pydoc <name>" to show documentation on something.  <name> may be
+the name of a function, module, package, or a dotted reference to a
+class or function within a module or module in a package.  If the
+argument contains a path segment delimiter (e.g. slash on Unix,
+backslash on Windows) it is treated as the path to a Python source file.
+
+Run "pydoc -k <keyword>" to search for a keyword in the synopsis lines
+of all available modules.
+
+Run "pydoc -p <port>" to start an HTTP server on a given port on the
+local machine to generate documentation web pages.
+
+For platforms without a command line, "pydoc -g" starts the HTTP server
+and also pops up a little window for controlling it.
+
+Run "pydoc -w <name>" to write out the HTML documentation for a module
+to a file named "<name>.html".
+
+Module docs for core modules are assumed to be in
+
+    http://www.python.org/doc/current/lib/
+
+This can be overridden by setting the PYTHONDOCS environment variable
+to a different URL or to a local directory containing the Library
+Reference Manual pages.
+"""
+
+__author__ = "Ka-Ping Yee <ping at lfw.org>"
+__date__ = "26 February 2001"
+
+__version__ = "$Revision: 54366 $"
+__credits__ = """Guido van Rossum, for an excellent programming language.
+Tommy Burnette, the original creator of manpy.
+Paul Prescod, for all his work on onlinehelp.
+Richard Chamberlain, for the first implementation of textdoc.
+"""
+
+# Known bugs that can't be fixed here:
+#   - imp.load_module() cannot be prevented from clobbering existing
+#     loaded modules, so calling synopsis() on a binary module file
+#     changes the contents of any existing module with the same name.
+#   - If the __file__ attribute on a module is a relative path and
+#     the current directory is changed with os.chdir(), an incorrect
+#     path will be displayed.
+
+import sys, imp, os, re, types, inspect, __builtin__, pkgutil
+from repr import Repr
+from string import expandtabs, find, join, lower, split, strip, rfind, rstrip
+try:
+    from collections import deque
+except ImportError:
+    # Python 2.3 compatibility
+    class deque(list):
+        def popleft(self):
+            return self.pop(0)
+
+# --------------------------------------------------------- common routines
+
+def pathdirs():
+    """Convert sys.path into a list of absolute, existing, unique paths."""
+    dirs = []
+    normdirs = []
+    for dir in sys.path:
+        dir = os.path.abspath(dir or '.')
+        normdir = os.path.normcase(dir)
+        if normdir not in normdirs and os.path.isdir(dir):
+            dirs.append(dir)
+            normdirs.append(normdir)
+    return dirs
+
+def getdoc(object):
+    """Get the doc string or comments for an object."""
+    result = inspect.getdoc(object) or inspect.getcomments(object)
+    return result and re.sub('^ *\n', '', rstrip(result)) or ''
+
+def splitdoc(doc):
+    """Split a doc string into a synopsis line (if any) and the rest."""
+    lines = split(strip(doc), '\n')
+    if len(lines) == 1:
+        return lines[0], ''
+    elif len(lines) >= 2 and not rstrip(lines[1]):
+        return lines[0], join(lines[2:], '\n')
+    return '', join(lines, '\n')
+
+def classname(object, modname):
+    """Get a class name and qualify it with a module name if necessary."""
+    name = object.__name__
+    if object.__module__ != modname:
+        name = object.__module__ + '.' + name
+    return name
+
+def isdata(object):
+    """Check if an object is of a type that probably means it's data."""
+    return not (inspect.ismodule(object) or inspect.isclass(object) or
+                inspect.isroutine(object) or inspect.isframe(object) or
+                inspect.istraceback(object) or inspect.iscode(object))
+
+def replace(text, *pairs):
+    """Do a series of global replacements on a string."""
+    while pairs:
+        text = join(split(text, pairs[0]), pairs[1])
+        pairs = pairs[2:]
+    return text
+
+def cram(text, maxlen):
+    """Omit part of a string if needed to make it fit in a maximum length."""
+    if len(text) > maxlen:
+        pre = max(0, (maxlen-3)//2)
+        post = max(0, maxlen-3-pre)
+        return text[:pre] + '...' + text[len(text)-post:]
+    return text
+
+_re_stripid = re.compile(r' at 0x[0-9a-f]{6,16}(>+)$', re.IGNORECASE)
+def stripid(text):
+    """Remove the hexadecimal id from a Python object representation."""
+    # The behaviour of %p is implementation-dependent in terms of case.
+    if _re_stripid.search(repr(Exception)):
+        return _re_stripid.sub(r'\1', text)
+    return text
+
+def _is_some_method(obj):
+    return inspect.ismethod(obj) or inspect.ismethoddescriptor(obj)
+
+def allmethods(cl):
+    methods = {}
+    for key, value in inspect.getmembers(cl, _is_some_method):
+        methods[key] = 1
+    for base in cl.__bases__:
+        methods.update(allmethods(base)) # all your base are belong to us
+    for key in methods.keys():
+        methods[key] = getattr(cl, key)
+    return methods
+
+def _split_list(s, predicate):
+    """Split sequence s via predicate, and return pair ([true], [false]).
+
+    The return value is a 2-tuple of lists,
+        ([x for x in s if predicate(x)],
+         [x for x in s if not predicate(x)])
+    """
+
+    yes = []
+    no = []
+    for x in s:
+        if predicate(x):
+            yes.append(x)
+        else:
+            no.append(x)
+    return yes, no
+
+def visiblename(name, all=None):
+    """Decide whether to show documentation on a variable."""
+    # Certain special names are redundant.
+    if name in ('__builtins__', '__doc__', '__file__', '__path__',
+                '__module__', '__name__', '__slots__'): return 0
+    # Private names are hidden, but special names are displayed.
+    if name.startswith('__') and name.endswith('__'): return 1
+    if all is not None:
+        # only document that which the programmer exported in __all__
+        return name in all
+    else:
+        return not name.startswith('_')
+
+def classify_class_attrs(object):
+    """Wrap inspect.classify_class_attrs, with fixup for data descriptors."""
+    def fixup((name, kind, cls, value)):
+        if inspect.isdatadescriptor(value):
+            kind = 'data descriptor'
+        return name, kind, cls, value
+    return map(fixup, inspect.classify_class_attrs(object))
+
+# ----------------------------------------------------- module manipulation
+
+def ispackage(path):
+    """Guess whether a path refers to a package directory."""
+    if os.path.isdir(path):
+        for ext in ('.py', '.pyc', '.pyo'):
+            if os.path.isfile(os.path.join(path, '__init__' + ext)):
+                return True
+    return False
+
+def source_synopsis(file):
+    line = file.readline()
+    while line[:1] == '#' or not strip(line):
+        line = file.readline()
+        if not line: break
+    line = strip(line)
+    if line[:4] == 'r"""': line = line[1:]
+    if line[:3] == '"""':
+        line = line[3:]
+        if line[-1:] == '\\': line = line[:-1]
+        while not strip(line):
+            line = file.readline()
+            if not line: break
+        result = strip(split(line, '"""')[0])
+    else: result = None
+    return result
+
+def synopsis(filename, cache={}):
+    """Get the one-line summary out of a module file."""
+    mtime = os.stat(filename).st_mtime
+    lastupdate, result = cache.get(filename, (0, None))
+    if lastupdate < mtime:
+        info = inspect.getmoduleinfo(filename)
+        try:
+            file = open(filename)
+        except IOError:
+            # module can't be opened, so skip it
+            return None
+        if info and 'b' in info[2]: # binary modules have to be imported
+            try: module = imp.load_module('__temp__', file, filename, info[1:])
+            except: return None
+            result = (module.__doc__ or '').splitlines()[0]
+            del sys.modules['__temp__']
+        else: # text modules can be directly examined
+            result = source_synopsis(file)
+            file.close()
+        cache[filename] = (mtime, result)
+    return result
+
+class ErrorDuringImport(Exception):
+    """Errors that occurred while trying to import something to document it."""
+    def __init__(self, filename, (exc, value, tb)):
+        self.filename = filename
+        self.exc = exc
+        self.value = value
+        self.tb = tb
+
+    def __str__(self):
+        exc = self.exc
+        if type(exc) is types.ClassType:
+            exc = exc.__name__
+        return 'problem in %s - %s: %s' % (self.filename, exc, self.value)
+
+def importfile(path):
+    """Import a Python source file or compiled file given its path."""
+    magic = imp.get_magic()
+    file = open(path, 'r')
+    if file.read(len(magic)) == magic:
+        kind = imp.PY_COMPILED
+    else:
+        kind = imp.PY_SOURCE
+    file.close()
+    filename = os.path.basename(path)
+    name, ext = os.path.splitext(filename)
+    file = open(path, 'r')
+    try:
+        module = imp.load_module(name, file, path, (ext, 'r', kind))
+    except:
+        raise ErrorDuringImport(path, sys.exc_info())
+    file.close()
+    return module
+
+def safeimport(path, forceload=0, cache={}):
+    """Import a module; handle errors; return None if the module isn't found.
+
+    If the module *is* found but an exception occurs, it's wrapped in an
+    ErrorDuringImport exception and reraised.  Unlike __import__, if a
+    package path is specified, the module at the end of the path is returned,
+    not the package at the beginning.  If the optional 'forceload' argument
+    is 1, we reload the module from disk (unless it's a dynamic extension)."""
+    try:
+        # If forceload is 1 and the module has been previously loaded from
+        # disk, we always have to reload the module.  Checking the file's
+        # mtime isn't good enough (e.g. the module could contain a class
+        # that inherits from another module that has changed).
+        if forceload and path in sys.modules:
+            if path not in sys.builtin_module_names:
+                # Avoid simply calling reload() because it leaves names in
+                # the currently loaded module lying around if they're not
+                # defined in the new source file.  Instead, remove the
+                # module from sys.modules and re-import.  Also remove any
+                # submodules because they won't appear in the newly loaded
+                # module's namespace if they're already in sys.modules.
+                subs = [m for m in sys.modules if m.startswith(path + '.')]
+                for key in [path] + subs:
+                    # Prevent garbage collection.
+                    cache[key] = sys.modules[key]
+                    del sys.modules[key]
+        module = __import__(path)
+    except:
+        # Did the error occur before or after the module was found?
+        (exc, value, tb) = info = sys.exc_info()
+        if path in sys.modules:
+            # An error occurred while executing the imported module.
+            raise ErrorDuringImport(sys.modules[path].__file__, info)
+        elif exc is SyntaxError:
+            # A SyntaxError occurred before we could execute the module.
+            raise ErrorDuringImport(value.filename, info)
+        elif exc is ImportError and \
+             split(lower(str(value)))[:2] == ['no', 'module']:
+            # The module was not found.
+            return None
+        else:
+            # Some other error occurred during the importing process.
+            raise ErrorDuringImport(path, sys.exc_info())
+    for part in split(path, '.')[1:]:
+        try: module = getattr(module, part)
+        except AttributeError: return None
+    return module
+
+# ---------------------------------------------------- formatter base class
+
+class Doc:
+    def document(self, object, name=None, *args):
+        """Generate documentation for an object."""
+        args = (object, name) + args
+        # 'try' clause is to attempt to handle the possibility that inspect
+        # identifies something in a way that pydoc itself has issues handling;
+        # think 'super' and how it is a descriptor (which raises the exception
+        # by lacking a __name__ attribute) and an instance.
+        if inspect.isgetsetdescriptor(object): return self.docdata(*args)
+        if inspect.ismemberdescriptor(object): return self.docdata(*args)
+        try:
+            if inspect.ismodule(object): return self.docmodule(*args)
+            if inspect.isclass(object): return self.docclass(*args)
+            if inspect.isroutine(object): return self.docroutine(*args)
+        except AttributeError:
+            pass
+        if isinstance(object, property): return self.docproperty(*args)
+        return self.docother(*args)
+
+    def fail(self, object, name=None, *args):
+        """Raise an exception for unimplemented types."""
+        message = "don't know how to document object%s of type %s" % (
+            name and ' ' + repr(name), type(object).__name__)
+        raise TypeError, message
+
+    docmodule = docclass = docroutine = docother = docproperty = docdata = fail
+
+    def getdocloc(self, object):
+        """Return the location of module docs or None"""
+
+        try:
+            file = inspect.getabsfile(object)
+        except TypeError:
+            file = '(built-in)'
+
+        docloc = os.environ.get("PYTHONDOCS",
+                                "http://www.python.org/doc/current/lib")
+        basedir = os.path.join(sys.exec_prefix, "lib",
+                               "python"+sys.version[0:3])
+        if (isinstance(object, type(os)) and
+            (object.__name__ in ('errno', 'exceptions', 'gc', 'imp',
+                                 'marshal', 'posix', 'signal', 'sys',
+                                 'thread', 'zipimport') or
+             (file.startswith(basedir) and
+              not file.startswith(os.path.join(basedir, 'site-packages'))))):
+            htmlfile = "module-%s.html" % object.__name__
+            if docloc.startswith("http://"):
+                docloc = "%s/%s" % (docloc.rstrip("/"), htmlfile)
+            else:
+                docloc = os.path.join(docloc, htmlfile)
+        else:
+            docloc = None
+        return docloc
+
+# -------------------------------------------- HTML documentation generator
+
+class HTMLRepr(Repr):
+    """Class for safely making an HTML representation of a Python object."""
+    def __init__(self):
+        Repr.__init__(self)
+        self.maxlist = self.maxtuple = 20
+        self.maxdict = 10
+        self.maxstring = self.maxother = 100
+
+    def escape(self, text):
+        return replace(text, '&', '&amp;', '<', '&lt;', '>', '&gt;')
+
+    def repr(self, object):
+        return Repr.repr(self, object)
+
+    def repr1(self, x, level):
+        if hasattr(type(x), '__name__'):
+            methodname = 'repr_' + join(split(type(x).__name__), '_')
+            if hasattr(self, methodname):
+                return getattr(self, methodname)(x, level)
+        return self.escape(cram(stripid(repr(x)), self.maxother))
+
+    def repr_string(self, x, level):
+        test = cram(x, self.maxstring)
+        testrepr = repr(test)
+        if '\\' in test and '\\' not in replace(testrepr, r'\\', ''):
+            # Backslashes are only literal in the string and are never
+            # needed to make any special characters, so show a raw string.
+            return 'r' + testrepr[0] + self.escape(test) + testrepr[0]
+        return re.sub(r'((\\[\\abfnrtv\'"]|\\[0-9]..|\\x..|\\u....)+)',
+                      r'<font color="#c040c0">\1</font>',
+                      self.escape(testrepr))
+
+    repr_str = repr_string
+
+    def repr_instance(self, x, level):
+        try:
+            return self.escape(cram(stripid(repr(x)), self.maxstring))
+        except:
+            return self.escape('<%s instance>' % x.__class__.__name__)
+
+    repr_unicode = repr_string
+
+class HTMLDoc(Doc):
+    """Formatter class for HTML documentation."""
+
+    # ------------------------------------------- HTML formatting utilities
+
+    _repr_instance = HTMLRepr()
+    repr = _repr_instance.repr
+    escape = _repr_instance.escape
+
+    def page(self, title, contents):
+        """Format an HTML page."""
+        return '''
+<!doctype html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html><head><title>Python: %s</title>
+</head><body bgcolor="#f0f0f8">
+%s
+</body></html>''' % (title, contents)
+
+    def heading(self, title, fgcol, bgcol, extras=''):
+        """Format a page heading."""
+        return '''
+<table width="100%%" cellspacing=0 cellpadding=2 border=0 summary="heading">
+<tr bgcolor="%s">
+<td valign=bottom>&nbsp;<br>
+<font color="%s" face="helvetica, arial">&nbsp;<br>%s</font></td
+><td align=right valign=bottom
+><font color="%s" face="helvetica, arial">%s</font></td></tr></table>
+    ''' % (bgcol, fgcol, title, fgcol, extras or '&nbsp;')
+
+    def section(self, title, fgcol, bgcol, contents, width=6,
+                prelude='', marginalia=None, gap='&nbsp;'):
+        """Format a section with a heading."""
+        if marginalia is None:
+            marginalia = '<tt>' + '&nbsp;' * width + '</tt>'
+        result = '''<p>
+<table width="100%%" cellspacing=0 cellpadding=2 border=0 summary="section">
+<tr bgcolor="%s">
+<td colspan=3 valign=bottom>&nbsp;<br>
+<font color="%s" face="helvetica, arial">%s</font></td></tr>
+    ''' % (bgcol, fgcol, title)
+        if prelude:
+            result = result + '''
+<tr bgcolor="%s"><td rowspan=2>%s</td>
+<td colspan=2>%s</td></tr>
+<tr><td>%s</td>''' % (bgcol, marginalia, prelude, gap)
+        else:
+            result = result + '''
+<tr><td bgcolor="%s">%s</td><td>%s</td>''' % (bgcol, marginalia, gap)
+
+        return result + '\n<td width="100%%">%s</td></tr></table>' % contents
+
+    def bigsection(self, title, *args):
+        """Format a section with a big heading."""
+        title = '<big><strong>%s</strong></big>' % title
+        return self.section(title, *args)
+
+    def preformat(self, text):
+        """Format literal preformatted text."""
+        text = self.escape(expandtabs(text))
+        return replace(text, '\n\n', '\n \n', '\n\n', '\n \n',
+                             ' ', '&nbsp;', '\n', '<br>\n')
+
+    def multicolumn(self, list, format, cols=4):
+        """Format a list of items into a multi-column list."""
+        result = ''
+        rows = (len(list)+cols-1)/cols
+        for col in range(cols):
+            result = result + '<td width="%d%%" valign=top>' % (100/cols)
+            for i in range(rows*col, rows*col+rows):
+                if i < len(list):
+                    result = result + format(list[i]) + '<br>\n'
+            result = result + '</td>'
+        return '<table width="100%%" summary="list"><tr>%s</tr></table>' % result
+
+    def grey(self, text): return '<font color="#909090">%s</font>' % text
+
+    def namelink(self, name, *dicts):
+        """Make a link for an identifier, given name-to-URL mappings."""
+        for dict in dicts:
+            if name in dict:
+                return '<a href="%s">%s</a>' % (dict[name], name)
+        return name
+
+    def classlink(self, object, modname):
+        """Make a link for a class."""
+        name, module = object.__name__, sys.modules.get(object.__module__)
+        if hasattr(module, name) and getattr(module, name) is object:
+            return '<a href="%s.html#%s">%s</a>' % (
+                module.__name__, name, classname(object, modname))
+        return classname(object, modname)
+
+    def modulelink(self, object):
+        """Make a link for a module."""
+        return '<a href="%s.html">%s</a>' % (object.__name__, object.__name__)
+
+    def modpkglink(self, (name, path, ispackage, shadowed)):
+        """Make a link for a module or package to display in an index."""
+        if shadowed:
+            return self.grey(name)
+        if path:
+            url = '%s.%s.html' % (path, name)
+        else:
+            url = '%s.html' % name
+        if ispackage:
+            text = '<strong>%s</strong>&nbsp;(package)' % name
+        else:
+            text = name
+        return '<a href="%s">%s</a>' % (url, text)
+
+    def markup(self, text, escape=None, funcs={}, classes={}, methods={}):
+        """Mark up some plain text, given a context of symbols to look for.
+        Each context dictionary maps object names to anchor names."""
+        escape = escape or self.escape
+        results = []
+        here = 0
+        pattern = re.compile(r'\b((http|ftp)://\S+[\w/]|'
+                                r'RFC[- ]?(\d+)|'
+                                r'PEP[- ]?(\d+)|'
+                                r'(self\.)?(\w+))')
+        while True:
+            match = pattern.search(text, here)
+            if not match: break
+            start, end = match.span()
+            results.append(escape(text[here:start]))
+
+            all, scheme, rfc, pep, selfdot, name = match.groups()
+            if scheme:
+                url = escape(all).replace('"', '&quot;')
+                results.append('<a href="%s">%s</a>' % (url, url))
+            elif rfc:
+                url = 'http://www.rfc-editor.org/rfc/rfc%d.txt' % int(rfc)
+                results.append('<a href="%s">%s</a>' % (url, escape(all)))
+            elif pep:
+                url = 'http://www.python.org/peps/pep-%04d.html' % int(pep)
+                results.append('<a href="%s">%s</a>' % (url, escape(all)))
+            elif text[end:end+1] == '(':
+                results.append(self.namelink(name, methods, funcs, classes))
+            elif selfdot:
+                results.append('self.<strong>%s</strong>' % name)
+            else:
+                results.append(self.namelink(name, classes))
+            here = end
+        results.append(escape(text[here:]))
+        return join(results, '')
+
+    # ---------------------------------------------- type-specific routines
+
+    def formattree(self, tree, modname, parent=None):
+        """Produce HTML for a class tree as given by inspect.getclasstree()."""
+        result = ''
+        for entry in tree:
+            if type(entry) is type(()):
+                c, bases = entry
+                result = result + '<dt><font face="helvetica, arial">'
+                result = result + self.classlink(c, modname)
+                if bases and bases != (parent,):
+                    parents = []
+                    for base in bases:
+                        parents.append(self.classlink(base, modname))
+                    result = result + '(' + join(parents, ', ') + ')'
+                result = result + '\n</font></dt>'
+            elif type(entry) is type([]):
+                result = result + '<dd>\n%s</dd>\n' % self.formattree(
+                    entry, modname, c)
+        return '<dl>\n%s</dl>\n' % result
+
+    def docmodule(self, object, name=None, mod=None, *ignored):
+        """Produce HTML documentation for a module object."""
+        name = object.__name__ # ignore the passed-in name
+        try:
+            all = object.__all__
+        except AttributeError:
+            all = None
+        parts = split(name, '.')
+        links = []
+        for i in range(len(parts)-1):
+            links.append(
+                '<a href="%s.html"><font color="#ffffff">%s</font></a>' %
+                (join(parts[:i+1], '.'), parts[i]))
+        linkedname = join(links + parts[-1:], '.')
+        head = '<big><big><strong>%s</strong></big></big>' % linkedname
+        try:
+            path = inspect.getabsfile(object)
+            url = path
+            if sys.platform == 'win32':
+                import nturl2path
+                url = nturl2path.pathname2url(path)
+            filelink = '<a href="file:%s">%s</a>' % (url, path)
+        except TypeError:
+            filelink = '(built-in)'
+        info = []
+        if hasattr(object, '__version__'):
+            version = str(object.__version__)
+            if version[:11] == '$' + 'Revision: ' and version[-1:] == '$':
+                version = strip(version[11:-1])
+            info.append('version %s' % self.escape(version))
+        if hasattr(object, '__date__'):
+            info.append(self.escape(str(object.__date__)))
+        if info:
+            head = head + ' (%s)' % join(info, ', ')
+        docloc = self.getdocloc(object)
+        if docloc is not None:
+            docloc = '<br><a href="%(docloc)s">Module Docs</a>' % locals()
+        else:
+            docloc = ''
+        result = self.heading(
+            head, '#ffffff', '#7799ee',
+            '<a href=".">index</a><br>' + filelink + docloc)
+
+        modules = inspect.getmembers(object, inspect.ismodule)
+
+        classes, cdict = [], {}
+        for key, value in inspect.getmembers(object, inspect.isclass):
+            # if __all__ exists, believe it.  Otherwise use old heuristic.
+            if (all is not None or
+                (inspect.getmodule(value) or object) is object):
+                if visiblename(key, all):
+                    classes.append((key, value))
+                    cdict[key] = cdict[value] = '#' + key
+        for key, value in classes:
+            for base in value.__bases__:
+                key, modname = base.__name__, base.__module__
+                module = sys.modules.get(modname)
+                if modname != name and module and hasattr(module, key):
+                    if getattr(module, key) is base:
+                        if not key in cdict:
+                            cdict[key] = cdict[base] = modname + '.html#' + key
+        funcs, fdict = [], {}
+        for key, value in inspect.getmembers(object, inspect.isroutine):
+            # if __all__ exists, believe it.  Otherwise use old heuristic.
+            if (all is not None or
+                inspect.isbuiltin(value) or inspect.getmodule(value) is object):
+                if visiblename(key, all):
+                    funcs.append((key, value))
+                    fdict[key] = '#-' + key
+                    if inspect.isfunction(value): fdict[value] = fdict[key]
+        data = []
+        for key, value in inspect.getmembers(object, isdata):
+            if visiblename(key, all):
+                data.append((key, value))
+
+        doc = self.markup(getdoc(object), self.preformat, fdict, cdict)
+        doc = doc and '<tt>%s</tt>' % doc
+        result = result + '<p>%s</p>\n' % doc
+
+        if hasattr(object, '__path__'):
+            modpkgs = []
+            for importer, modname, ispkg in pkgutil.iter_modules(object.__path__):
+                modpkgs.append((modname, name, ispkg, 0))
+            modpkgs.sort()
+            contents = self.multicolumn(modpkgs, self.modpkglink)
+            result = result + self.bigsection(
+                'Package Contents', '#ffffff', '#aa55cc', contents)
+        elif modules:
+            contents = self.multicolumn(
+                modules, lambda (key, value), s=self: s.modulelink(value))
+            result = result + self.bigsection(
+                'Modules', '#fffff', '#aa55cc', contents)
+
+        if classes:
+            classlist = map(lambda (key, value): value, classes)
+            contents = [
+                self.formattree(inspect.getclasstree(classlist, 1), name)]
+            for key, value in classes:
+                contents.append(self.document(value, key, name, fdict, cdict))
+            result = result + self.bigsection(
+                'Classes', '#ffffff', '#ee77aa', join(contents))
+        if funcs:
+            contents = []
+            for key, value in funcs:
+                contents.append(self.document(value, key, name, fdict, cdict))
+            result = result + self.bigsection(
+                'Functions', '#ffffff', '#eeaa77', join(contents))
+        if data:
+            contents = []
+            for key, value in data:
+                contents.append(self.document(value, key))
+            result = result + self.bigsection(
+                'Data', '#ffffff', '#55aa55', join(contents, '<br>\n'))
+        if hasattr(object, '__author__'):
+            contents = self.markup(str(object.__author__), self.preformat)
+            result = result + self.bigsection(
+                'Author', '#ffffff', '#7799ee', contents)
+        if hasattr(object, '__credits__'):
+            contents = self.markup(str(object.__credits__), self.preformat)
+            result = result + self.bigsection(
+                'Credits', '#ffffff', '#7799ee', contents)
+
+        return result
+
+    def docclass(self, object, name=None, mod=None, funcs={}, classes={},
+                 *ignored):
+        """Produce HTML documentation for a class object."""
+        realname = object.__name__
+        name = name or realname
+        bases = object.__bases__
+
+        contents = []
+        push = contents.append
+
+        # Cute little class to pump out a horizontal rule between sections.
+        class HorizontalRule:
+            def __init__(self):
+                self.needone = 0
+            def maybe(self):
+                if self.needone:
+                    push('<hr>\n')
+                self.needone = 1
+        hr = HorizontalRule()
+
+        # List the mro, if non-trivial.
+        mro = deque(inspect.getmro(object))
+        if len(mro) > 2:
+            hr.maybe()
+            push('<dl><dt>Method resolution order:</dt>\n')
+            for base in mro:
+                push('<dd>%s</dd>\n' % self.classlink(base,
+                                                      object.__module__))
+            push('</dl>\n')
+
+        def spill(msg, attrs, predicate):
+            ok, attrs = _split_list(attrs, predicate)
+            if ok:
+                hr.maybe()
+                push(msg)
+                for name, kind, homecls, value in ok:
+                    push(self.document(getattr(object, name), name, mod,
+                                       funcs, classes, mdict, object))
+                    push('\n')
+            return attrs
+
+        def spilldescriptors(msg, attrs, predicate):
+            ok, attrs = _split_list(attrs, predicate)
+            if ok:
+                hr.maybe()
+                push(msg)
+                for name, kind, homecls, value in ok:
+                    push(self._docdescriptor(name, value, mod))
+            return attrs
+
+        def spilldata(msg, attrs, predicate):
+            ok, attrs = _split_list(attrs, predicate)
+            if ok:
+                hr.maybe()
+                push(msg)
+                for name, kind, homecls, value in ok:
+                    base = self.docother(getattr(object, name), name, mod)
+                    if callable(value) or inspect.isdatadescriptor(value):
+                        doc = getattr(value, "__doc__", None)
+                    else:
+                        doc = None
+                    if doc is None:
+                        push('<dl><dt>%s</dl>\n' % base)
+                    else:
+                        doc = self.markup(getdoc(value), self.preformat,
+                                          funcs, classes, mdict)
+                        doc = '<dd><tt>%s</tt>' % doc
+                        push('<dl><dt>%s%s</dl>\n' % (base, doc))
+                    push('\n')
+            return attrs
+
+        attrs = filter(lambda (name, kind, cls, value): visiblename(name),
+                       classify_class_attrs(object))
+        mdict = {}
+        for key, kind, homecls, value in attrs:
+            mdict[key] = anchor = '#' + name + '-' + key
+            value = getattr(object, key)
+            try:
+                # The value may not be hashable (e.g., a data attr with
+                # a dict or list value).
+                mdict[value] = anchor
+            except TypeError:
+                pass
+
+        while attrs:
+            if mro:
+                thisclass = mro.popleft()
+            else:
+                thisclass = attrs[0][2]
+            attrs, inherited = _split_list(attrs, lambda t: t[2] is thisclass)
+
+            if thisclass is __builtin__.object:
+                attrs = inherited
+                continue
+            elif thisclass is object:
+                tag = 'defined here'
+            else:
+                tag = 'inherited from %s' % self.classlink(thisclass,
+                                                           object.__module__)
+            tag += ':<br>\n'
+
+            # Sort attrs by name.
+            try:
+                attrs.sort(key=lambda t: t[0])
+            except TypeError:
+                attrs.sort(lambda t1, t2: cmp(t1[0], t2[0]))    # 2.3 compat
+
+            # Pump out the attrs, segregated by kind.
+            attrs = spill('Methods %s' % tag, attrs,
+                          lambda t: t[1] == 'method')
+            attrs = spill('Class methods %s' % tag, attrs,
+                          lambda t: t[1] == 'class method')
+            attrs = spill('Static methods %s' % tag, attrs,
+                          lambda t: t[1] == 'static method')
+            attrs = spilldescriptors('Data descriptors %s' % tag, attrs,
+                                     lambda t: t[1] == 'data descriptor')
+            attrs = spilldata('Data and other attributes %s' % tag, attrs,
+                              lambda t: t[1] == 'data')
+            assert attrs == []
+            attrs = inherited
+
+        contents = ''.join(contents)
+
+        if name == realname:
+            title = '<a name="%s">class <strong>%s</strong></a>' % (
+                name, realname)
+        else:
+            title = '<strong>%s</strong> = <a name="%s">class %s</a>' % (
+                name, name, realname)
+        if bases:
+            parents = []
+            for base in bases:
+                parents.append(self.classlink(base, object.__module__))
+            title = title + '(%s)' % join(parents, ', ')
+        doc = self.markup(getdoc(object), self.preformat, funcs, classes, mdict)
+        doc = doc and '<tt>%s<br>&nbsp;</tt>' % doc
+
+        return self.section(title, '#000000', '#ffc8d8', contents, 3, doc)
+
+    def formatvalue(self, object):
+        """Format an argument default value as text."""
+        return self.grey('=' + self.repr(object))
+
+    def docroutine(self, object, name=None, mod=None,
+                   funcs={}, classes={}, methods={}, cl=None):
+        """Produce HTML documentation for a function or method object."""
+        realname = object.__name__
+        name = name or realname
+        anchor = (cl and cl.__name__ or '') + '-' + name
+        note = ''
+        skipdocs = 0
+        if inspect.ismethod(object):
+            imclass = object.im_class
+            if cl:
+                if imclass is not cl:
+                    note = ' from ' + self.classlink(imclass, mod)
+            else:
+                if object.im_self is not None:
+                    note = ' method of %s instance' % self.classlink(
+                        object.im_self.__class__, mod)
+                else:
+                    note = ' unbound %s method' % self.classlink(imclass,mod)
+            object = object.im_func
+
+        if name == realname:
+            title = '<a name="%s"><strong>%s</strong></a>' % (anchor, realname)
+        else:
+            if (cl and realname in cl.__dict__ and
+                cl.__dict__[realname] is object):
+                reallink = '<a href="#%s">%s</a>' % (
+                    cl.__name__ + '-' + realname, realname)
+                skipdocs = 1
+            else:
+                reallink = realname
+            title = '<a name="%s"><strong>%s</strong></a> = %s' % (
+                anchor, name, reallink)
+        if inspect.isfunction(object):
+            args, varargs, varkw, defaults = inspect.getargspec(object)
+            argspec = inspect.formatargspec(
+                args, varargs, varkw, defaults, formatvalue=self.formatvalue)
+            if realname == '<lambda>':
+                title = '<strong>%s</strong> <em>lambda</em> ' % name
+                argspec = argspec[1:-1] # remove parentheses
+        else:
+            argspec = '(...)'
+
+        decl = title + argspec + (note and self.grey(
+               '<font face="helvetica, arial">%s</font>' % note))
+
+        if skipdocs:
+            return '<dl><dt>%s</dt></dl>\n' % decl
+        else:
+            doc = self.markup(
+                getdoc(object), self.preformat, funcs, classes, methods)
+            doc = doc and '<dd><tt>%s</tt></dd>' % doc
+            return '<dl><dt>%s</dt>%s</dl>\n' % (decl, doc)
+
+    def _docdescriptor(self, name, value, mod):
+        results = []
+        push = results.append
+
+        if name:
+            push('<dl><dt><strong>%s</strong></dt>\n' % name)
+        if value.__doc__ is not None:
+            doc = self.markup(getdoc(value), self.preformat)
+            push('<dd><tt>%s</tt></dd>\n' % doc)
+        push('</dl>\n')
+
+        return ''.join(results)
+
+    def docproperty(self, object, name=None, mod=None, cl=None):
+        """Produce html documentation for a property."""
+        return self._docdescriptor(name, object, mod)
+
+    def docother(self, object, name=None, mod=None, *ignored):
+        """Produce HTML documentation for a data object."""
+        lhs = name and '<strong>%s</strong> = ' % name or ''
+        return lhs + self.repr(object)
+
+    def docdata(self, object, name=None, mod=None, cl=None):
+        """Produce html documentation for a data descriptor."""
+        return self._docdescriptor(name, object, mod)
+
+    def index(self, dir, shadowed=None):
+        """Generate an HTML index for a directory of modules."""
+        modpkgs = []
+        if shadowed is None: shadowed = {}
+        for importer, name, ispkg in pkgutil.iter_modules([dir]):
+            modpkgs.append((name, '', ispkg, name in shadowed))
+            shadowed[name] = 1
+
+        modpkgs.sort()
+        contents = self.multicolumn(modpkgs, self.modpkglink)
+        return self.bigsection(dir, '#ffffff', '#ee77aa', contents)
+
+# -------------------------------------------- text documentation generator
+
+class TextRepr(Repr):
+    """Class for safely making a text representation of a Python object."""
+    def __init__(self):
+        Repr.__init__(self)
+        self.maxlist = self.maxtuple = 20
+        self.maxdict = 10
+        self.maxstring = self.maxother = 100
+
+    def repr1(self, x, level):
+        if hasattr(type(x), '__name__'):
+            methodname = 'repr_' + join(split(type(x).__name__), '_')
+            if hasattr(self, methodname):
+                return getattr(self, methodname)(x, level)
+        return cram(stripid(repr(x)), self.maxother)
+
+    def repr_string(self, x, level):
+        test = cram(x, self.maxstring)
+        testrepr = repr(test)
+        if '\\' in test and '\\' not in replace(testrepr, r'\\', ''):
+            # Backslashes are only literal in the string and are never
+            # needed to make any special characters, so show a raw string.
+            return 'r' + testrepr[0] + test + testrepr[0]
+        return testrepr
+
+    repr_str = repr_string
+
+    def repr_instance(self, x, level):
+        try:
+            return cram(stripid(repr(x)), self.maxstring)
+        except:
+            return '<%s instance>' % x.__class__.__name__
+
+class TextDoc(Doc):
+    """Formatter class for text documentation."""
+
+    # ------------------------------------------- text formatting utilities
+
+    _repr_instance = TextRepr()
+    repr = _repr_instance.repr
+
+    def bold(self, text):
+        """Format a string in bold by overstriking."""
+        return join(map(lambda ch: ch + '\b' + ch, text), '')
+
+    def indent(self, text, prefix='    '):
+        """Indent text by prepending a given prefix to each line."""
+        if not text: return ''
+        lines = split(text, '\n')
+        lines = map(lambda line, prefix=prefix: prefix + line, lines)
+        if lines: lines[-1] = rstrip(lines[-1])
+        return join(lines, '\n')
+
+    def section(self, title, contents):
+        """Format a section with a given heading."""
+        return self.bold(title) + '\n' + rstrip(self.indent(contents)) + '\n\n'
+
+    # ---------------------------------------------- type-specific routines
+
+    def formattree(self, tree, modname, parent=None, prefix=''):
+        """Render in text a class tree as returned by inspect.getclasstree()."""
+        result = ''
+        for entry in tree:
+            if type(entry) is type(()):
+                c, bases = entry
+                result = result + prefix + classname(c, modname)
+                if bases and bases != (parent,):
+                    parents = map(lambda c, m=modname: classname(c, m), bases)
+                    result = result + '(%s)' % join(parents, ', ')
+                result = result + '\n'
+            elif type(entry) is type([]):
+                result = result + self.formattree(
+                    entry, modname, c, prefix + '    ')
+        return result
+
+    def docmodule(self, object, name=None, mod=None):
+        """Produce text documentation for a given module object."""
+        name = object.__name__ # ignore the passed-in name
+        synop, desc = splitdoc(getdoc(object))
+        result = self.section('NAME', name + (synop and ' - ' + synop))
+
+        try:
+            all = object.__all__
+        except AttributeError:
+            all = None
+
+        try:
+            file = inspect.getabsfile(object)
+        except TypeError:
+            file = '(built-in)'
+        result = result + self.section('FILE', file)
+
+        docloc = self.getdocloc(object)
+        if docloc is not None:
+            result = result + self.section('MODULE DOCS', docloc)
+
+        if desc:
+            result = result + self.section('DESCRIPTION', desc)
+
+        classes = []
+        for key, value in inspect.getmembers(object, inspect.isclass):
+            # if __all__ exists, believe it.  Otherwise use old heuristic.
+            if (all is not None
+                or (inspect.getmodule(value) or object) is object):
+                if visiblename(key, all):
+                    classes.append((key, value))
+        funcs = []
+        for key, value in inspect.getmembers(object, inspect.isroutine):
+            # if __all__ exists, believe it.  Otherwise use old heuristic.
+            if (all is not None or
+                inspect.isbuiltin(value) or inspect.getmodule(value) is object):
+                if visiblename(key, all):
+                    funcs.append((key, value))
+        data = []
+        for key, value in inspect.getmembers(object, isdata):
+            if visiblename(key, all):
+                data.append((key, value))
+
+        if hasattr(object, '__path__'):
+            modpkgs = []
+            for importer, modname, ispkg in pkgutil.iter_modules(object.__path__):
+                if ispkg:
+                    modpkgs.append(modname + ' (package)')
+                else:
+                    modpkgs.append(modname)
+
+            modpkgs.sort()
+            result = result + self.section(
+                'PACKAGE CONTENTS', join(modpkgs, '\n'))
+
+        if classes:
+            classlist = map(lambda (key, value): value, classes)
+            contents = [self.formattree(
+                inspect.getclasstree(classlist, 1), name)]
+            for key, value in classes:
+                contents.append(self.document(value, key, name))
+            result = result + self.section('CLASSES', join(contents, '\n'))
+
+        if funcs:
+            contents = []
+            for key, value in funcs:
+                contents.append(self.document(value, key, name))
+            result = result + self.section('FUNCTIONS', join(contents, '\n'))
+
+        if data:
+            contents = []
+            for key, value in data:
+                contents.append(self.docother(value, key, name, maxlen=70))
+            result = result + self.section('DATA', join(contents, '\n'))
+
+        if hasattr(object, '__version__'):
+            version = str(object.__version__)
+            if version[:11] == '$' + 'Revision: ' and version[-1:] == '$':
+                version = strip(version[11:-1])
+            result = result + self.section('VERSION', version)
+        if hasattr(object, '__date__'):
+            result = result + self.section('DATE', str(object.__date__))
+        if hasattr(object, '__author__'):
+            result = result + self.section('AUTHOR', str(object.__author__))
+        if hasattr(object, '__credits__'):
+            result = result + self.section('CREDITS', str(object.__credits__))
+        return result
+
+    def docclass(self, object, name=None, mod=None):
+        """Produce text documentation for a given class object."""
+        realname = object.__name__
+        name = name or realname
+        bases = object.__bases__
+
+        def makename(c, m=object.__module__):
+            return classname(c, m)
+
+        if name == realname:
+            title = 'class ' + self.bold(realname)
+        else:
+            title = self.bold(name) + ' = class ' + realname
+        if bases:
+            parents = map(makename, bases)
+            title = title + '(%s)' % join(parents, ', ')
+
+        doc = getdoc(object)
+        contents = doc and [doc + '\n'] or []
+        push = contents.append
+
+        # List the mro, if non-trivial.
+        mro = deque(inspect.getmro(object))
+        if len(mro) > 2:
+            push("Method resolution order:")
+            for base in mro:
+                push('    ' + makename(base))
+            push('')
+
+        # Cute little class to pump out a horizontal rule between sections.
+        class HorizontalRule:
+            def __init__(self):
+                self.needone = 0
+            def maybe(self):
+                if self.needone:
+                    push('-' * 70)
+                self.needone = 1
+        hr = HorizontalRule()
+
+        def spill(msg, attrs, predicate):
+            ok, attrs = _split_list(attrs, predicate)
+            if ok:
+                hr.maybe()
+                push(msg)
+                for name, kind, homecls, value in ok:
+                    push(self.document(getattr(object, name),
+                                       name, mod, object))
+            return attrs
+
+        def spilldescriptors(msg, attrs, predicate):
+            ok, attrs = _split_list(attrs, predicate)
+            if ok:
+                hr.maybe()
+                push(msg)
+                for name, kind, homecls, value in ok:
+                    push(self._docdescriptor(name, value, mod))
+            return attrs
+
+        def spilldata(msg, attrs, predicate):
+            ok, attrs = _split_list(attrs, predicate)
+            if ok:
+                hr.maybe()
+                push(msg)
+                for name, kind, homecls, value in ok:
+                    if callable(value) or inspect.isdatadescriptor(value):
+                        doc = getdoc(value)
+                    else:
+                        doc = None
+                    push(self.docother(getattr(object, name),
+                                       name, mod, maxlen=70, doc=doc) + '\n')
+            return attrs
+
+        attrs = filter(lambda (name, kind, cls, value): visiblename(name),
+                       classify_class_attrs(object))
+        while attrs:
+            if mro:
+                thisclass = mro.popleft()
+            else:
+                thisclass = attrs[0][2]
+            attrs, inherited = _split_list(attrs, lambda t: t[2] is thisclass)
+
+            if thisclass is __builtin__.object:
+                attrs = inherited
+                continue
+            elif thisclass is object:
+                tag = "defined here"
+            else:
+                tag = "inherited from %s" % classname(thisclass,
+                                                      object.__module__)
+            filter(lambda t: not t[0].startswith('_'), attrs)
+
+            # Sort attrs by name.
+            attrs.sort()
+
+            # Pump out the attrs, segregated by kind.
+            attrs = spill("Methods %s:\n" % tag, attrs,
+                          lambda t: t[1] == 'method')
+            attrs = spill("Class methods %s:\n" % tag, attrs,
+                          lambda t: t[1] == 'class method')
+            attrs = spill("Static methods %s:\n" % tag, attrs,
+                          lambda t: t[1] == 'static method')
+            attrs = spilldescriptors("Data descriptors %s:\n" % tag, attrs,
+                                     lambda t: t[1] == 'data descriptor')
+            attrs = spilldata("Data and other attributes %s:\n" % tag, attrs,
+                              lambda t: t[1] == 'data')
+            assert attrs == []
+            attrs = inherited
+
+        contents = '\n'.join(contents)
+        if not contents:
+            return title + '\n'
+        return title + '\n' + self.indent(rstrip(contents), ' |  ') + '\n'
+
+    def formatvalue(self, object):
+        """Format an argument default value as text."""
+        return '=' + self.repr(object)
+
+    def docroutine(self, object, name=None, mod=None, cl=None):
+        """Produce text documentation for a function or method object."""
+        realname = object.__name__
+        name = name or realname
+        note = ''
+        skipdocs = 0
+        if inspect.ismethod(object):
+            imclass = object.im_class
+            if cl:
+                if imclass is not cl:
+                    note = ' from ' + classname(imclass, mod)
+            else:
+                if object.im_self is not None:
+                    note = ' method of %s instance' % classname(
+                        object.im_self.__class__, mod)
+                else:
+                    note = ' unbound %s method' % classname(imclass,mod)
+            object = object.im_func
+
+        if name == realname:
+            title = self.bold(realname)
+        else:
+            if (cl and realname in cl.__dict__ and
+                cl.__dict__[realname] is object):
+                skipdocs = 1
+            title = self.bold(name) + ' = ' + realname
+        if inspect.isfunction(object):
+            args, varargs, varkw, defaults = inspect.getargspec(object)
+            argspec = inspect.formatargspec(
+                args, varargs, varkw, defaults, formatvalue=self.formatvalue)
+            if realname == '<lambda>':
+                title = self.bold(name) + ' lambda '
+                argspec = argspec[1:-1] # remove parentheses
+        else:
+            argspec = '(...)'
+        decl = title + argspec + note
+
+        if skipdocs:
+            return decl + '\n'
+        else:
+            doc = getdoc(object) or ''
+            return decl + '\n' + (doc and rstrip(self.indent(doc)) + '\n')
+
+    def _docdescriptor(self, name, value, mod):
+        results = []
+        push = results.append
+
+        if name:
+            push(self.bold(name))
+            push('\n')
+        doc = getdoc(value) or ''
+        if doc:
+            push(self.indent(doc))
+            push('\n')
+        return ''.join(results)
+
+    def docproperty(self, object, name=None, mod=None, cl=None):
+        """Produce text documentation for a property."""
+        return self._docdescriptor(name, object, mod)
+
+    def docdata(self, object, name=None, mod=None, cl=None):
+        """Produce text documentation for a data descriptor."""
+        return self._docdescriptor(name, object, mod)
+
+    def docother(self, object, name=None, mod=None, parent=None, maxlen=None, doc=None):
+        """Produce text documentation for a data object."""
+        repr = self.repr(object)
+        if maxlen:
+            line = (name and name + ' = ' or '') + repr
+            chop = maxlen - len(line)
+            if chop < 0: repr = repr[:chop] + '...'
+        line = (name and self.bold(name) + ' = ' or '') + repr
+        if doc is not None:
+            line += '\n' + self.indent(str(doc))
+        return line
+
+# --------------------------------------------------------- user interfaces
+
+def pager(text):
+    """The first time this is called, determine what kind of pager to use."""
+    global pager
+    pager = getpager()
+    pager(text)
+
+def getpager():
+    """Decide what method to use for paging through text."""
+    if type(sys.stdout) is not types.FileType:
+        return plainpager
+    if not sys.stdin.isatty() or not sys.stdout.isatty():
+        return plainpager
+    if 'PAGER' in os.environ:
+        if sys.platform == 'win32': # pipes completely broken in Windows
+            return lambda text: tempfilepager(plain(text), os.environ['PAGER'])
+        elif os.environ.get('TERM') in ('dumb', 'emacs'):
+            return lambda text: pipepager(plain(text), os.environ['PAGER'])
+        else:
+            return lambda text: pipepager(text, os.environ['PAGER'])
+    if os.environ.get('TERM') in ('dumb', 'emacs'):
+        return plainpager
+    if sys.platform == 'win32' or sys.platform.startswith('os2'):
+        return lambda text: tempfilepager(plain(text), 'more <')
+    if hasattr(os, 'system') and os.system('(less) 2>/dev/null') == 0:
+        return lambda text: pipepager(text, 'less')
+
+    import tempfile
+    (fd, filename) = tempfile.mkstemp()
+    os.close(fd)
+    try:
+        if hasattr(os, 'system') and os.system('more %s' % filename) == 0:
+            return lambda text: pipepager(text, 'more')
+        else:
+            return ttypager
+    finally:
+        os.unlink(filename)
+
+def plain(text):
+    """Remove boldface formatting from text."""
+    return re.sub('.\b', '', text)
+
+def pipepager(text, cmd):
+    """Page through text by feeding it to another program."""
+    pipe = os.popen(cmd, 'w')
+    try:
+        pipe.write(text)
+        pipe.close()
+    except IOError:
+        pass # Ignore broken pipes caused by quitting the pager program.
+
+def tempfilepager(text, cmd):
+    """Page through text by invoking a program on a temporary file."""
+    import tempfile
+    filename = tempfile.mktemp()
+    file = open(filename, 'w')
+    file.write(text)
+    file.close()
+    try:
+        os.system(cmd + ' ' + filename)
+    finally:
+        os.unlink(filename)
+
+def ttypager(text):
+    """Page through text on a text terminal."""
+    lines = split(plain(text), '\n')
+    try:
+        import tty
+        fd = sys.stdin.fileno()
+        old = tty.tcgetattr(fd)
+        tty.setcbreak(fd)
+        getchar = lambda: sys.stdin.read(1)
+    except (ImportError, AttributeError):
+        tty = None
+        getchar = lambda: sys.stdin.readline()[:-1][:1]
+
+    try:
+        r = inc = os.environ.get('LINES', 25) - 1
+        sys.stdout.write(join(lines[:inc], '\n') + '\n')
+        while lines[r:]:
+            sys.stdout.write('-- more --')
+            sys.stdout.flush()
+            c = getchar()
+
+            if c in ('q', 'Q'):
+                sys.stdout.write('\r          \r')
+                break
+            elif c in ('\r', '\n'):
+                sys.stdout.write('\r          \r' + lines[r] + '\n')
+                r = r + 1
+                continue
+            if c in ('b', 'B', '\x1b'):
+                r = r - inc - inc
+                if r < 0: r = 0
+            sys.stdout.write('\n' + join(lines[r:r+inc], '\n') + '\n')
+            r = r + inc
+
+    finally:
+        if tty:
+            tty.tcsetattr(fd, tty.TCSAFLUSH, old)
+
+def plainpager(text):
+    """Simply print unformatted text.  This is the ultimate fallback."""
+    sys.stdout.write(plain(text))
+
+def describe(thing):
+    """Produce a short description of the given thing."""
+    if inspect.ismodule(thing):
+        if thing.__name__ in sys.builtin_module_names:
+            return 'built-in module ' + thing.__name__
+        if hasattr(thing, '__path__'):
+            return 'package ' + thing.__name__
+        else:
+            return 'module ' + thing.__name__
+    if inspect.isbuiltin(thing):
+        return 'built-in function ' + thing.__name__
+    if inspect.isgetsetdescriptor(thing):
+        return 'getset descriptor %s.%s.%s' % (
+            thing.__objclass__.__module__, thing.__objclass__.__name__,
+            thing.__name__)
+    if inspect.ismemberdescriptor(thing):
+        return 'member descriptor %s.%s.%s' % (
+            thing.__objclass__.__module__, thing.__objclass__.__name__,
+            thing.__name__)
+    if inspect.isclass(thing):
+        return 'class ' + thing.__name__
+    if inspect.isfunction(thing):
+        return 'function ' + thing.__name__
+    if inspect.ismethod(thing):
+        return 'method ' + thing.__name__
+    if type(thing) is types.InstanceType:
+        return 'instance of ' + thing.__class__.__name__
+    return type(thing).__name__
+
+def locate(path, forceload=0):
+    """Locate an object by name or dotted path, importing as necessary."""
+    parts = [part for part in split(path, '.') if part]
+    module, n = None, 0
+    while n < len(parts):
+        nextmodule = safeimport(join(parts[:n+1], '.'), forceload)
+        if nextmodule: module, n = nextmodule, n + 1
+        else: break
+    if module:
+        object = module
+        for part in parts[n:]:
+            try: object = getattr(object, part)
+            except AttributeError: return None
+        return object
+    else:
+        if hasattr(__builtin__, path):
+            return getattr(__builtin__, path)
+
+# --------------------------------------- interactive interpreter interface
+
+text = TextDoc()
+html = HTMLDoc()
+
+def resolve(thing, forceload=0):
+    """Given an object or a path to an object, get the object and its name."""
+    if isinstance(thing, str):
+        object = locate(thing, forceload)
+        if not object:
+            raise ImportError, 'no Python documentation found for %r' % thing
+        return object, thing
+    else:
+        return thing, getattr(thing, '__name__', None)
+
+def doc(thing, title='Python Library Documentation: %s', forceload=0):
+    """Display text documentation, given an object or a path to an object."""
+    try:
+        object, name = resolve(thing, forceload)
+        desc = describe(object)
+        module = inspect.getmodule(object)
+        if name and '.' in name:
+            desc += ' in ' + name[:name.rfind('.')]
+        elif module and module is not object:
+            desc += ' in module ' + module.__name__
+        if not (inspect.ismodule(object) or
+                inspect.isclass(object) or
+                inspect.isroutine(object) or
+                inspect.isgetsetdescriptor(object) or
+                inspect.ismemberdescriptor(object) or
+                isinstance(object, property)):
+            # If the passed object is a piece of data or an instance,
+            # document its available methods instead of its value.
+            object = type(object)
+            desc += ' object'
+        pager(title % desc + '\n\n' + text.document(object, name))
+    except (ImportError, ErrorDuringImport), value:
+        print value
+
+def writedoc(thing, forceload=0):
+    """Write HTML documentation to a file in the current directory."""
+    try:
+        object, name = resolve(thing, forceload)
+        page = html.page(describe(object), html.document(object, name))
+        file = open(name + '.html', 'w')
+        file.write(page)
+        file.close()
+        print 'wrote', name + '.html'
+    except (ImportError, ErrorDuringImport), value:
+        print value
+
+def writedocs(dir, pkgpath='', done=None):
+    """Write out HTML documentation for all modules in a directory tree."""
+    if done is None: done = {}
+    for importer, modname, ispkg in pkgutil.walk_packages([dir], pkgpath):
+        writedoc(modname)
+    return
+
+class Helper:
+    keywords = {
+        'and': 'BOOLEAN',
+        'as': 'with',
+        'assert': ('ref/assert', ''),
+        'break': ('ref/break', 'while for'),
+        'class': ('ref/class', 'CLASSES SPECIALMETHODS'),
+        'continue': ('ref/continue', 'while for'),
+        'def': ('ref/function', ''),
+        'del': ('ref/del', 'BASICMETHODS'),
+        'elif': 'if',
+        'else': ('ref/if', 'while for'),
+        'except': 'try',
+        'exec': ('ref/exec', ''),
+        'finally': 'try',
+        'for': ('ref/for', 'break continue while'),
+        'from': 'import',
+        'global': ('ref/global', 'NAMESPACES'),
+        'if': ('ref/if', 'TRUTHVALUE'),
+        'import': ('ref/import', 'MODULES'),
+        'in': ('ref/comparisons', 'SEQUENCEMETHODS2'),
+        'is': 'COMPARISON',
+        'lambda': ('ref/lambdas', 'FUNCTIONS'),
+        'not': 'BOOLEAN',
+        'or': 'BOOLEAN',
+        'pass': ('ref/pass', ''),
+        'print': ('ref/print', ''),
+        'raise': ('ref/raise', 'EXCEPTIONS'),
+        'return': ('ref/return', 'FUNCTIONS'),
+        'try': ('ref/try', 'EXCEPTIONS'),
+        'while': ('ref/while', 'break continue if TRUTHVALUE'),
+        'with': ('ref/with', 'CONTEXTMANAGERS EXCEPTIONS yield'),
+        'yield': ('ref/yield', ''),
+    }
+
+    topics = {
+        'TYPES': ('ref/types', 'STRINGS UNICODE NUMBERS SEQUENCES MAPPINGS FUNCTIONS CLASSES MODULES FILES inspect'),
+        'STRINGS': ('ref/strings', 'str UNICODE SEQUENCES STRINGMETHODS FORMATTING TYPES'),
+        'STRINGMETHODS': ('lib/string-methods', 'STRINGS FORMATTING'),
+        'FORMATTING': ('lib/typesseq-strings', 'OPERATORS'),
+        'UNICODE': ('ref/strings', 'encodings unicode SEQUENCES STRINGMETHODS FORMATTING TYPES'),
+        'NUMBERS': ('ref/numbers', 'INTEGER FLOAT COMPLEX TYPES'),
+        'INTEGER': ('ref/integers', 'int range'),
+        'FLOAT': ('ref/floating', 'float math'),
+        'COMPLEX': ('ref/imaginary', 'complex cmath'),
+        'SEQUENCES': ('lib/typesseq', 'STRINGMETHODS FORMATTING xrange LISTS'),
+        'MAPPINGS': 'DICTIONARIES',
+        'FUNCTIONS': ('lib/typesfunctions', 'def TYPES'),
+        'METHODS': ('lib/typesmethods', 'class def CLASSES TYPES'),
+        'CODEOBJECTS': ('lib/bltin-code-objects', 'compile FUNCTIONS TYPES'),
+        'TYPEOBJECTS': ('lib/bltin-type-objects', 'types TYPES'),
+        'FRAMEOBJECTS': 'TYPES',
+        'TRACEBACKS': 'TYPES',
+        'NONE': ('lib/bltin-null-object', ''),
+        'ELLIPSIS': ('lib/bltin-ellipsis-object', 'SLICINGS'),
+        'FILES': ('lib/bltin-file-objects', ''),
+        'SPECIALATTRIBUTES': ('lib/specialattrs', ''),
+        'CLASSES': ('ref/types', 'class SPECIALMETHODS PRIVATENAMES'),
+        'MODULES': ('lib/typesmodules', 'import'),
+        'PACKAGES': 'import',
+        'EXPRESSIONS': ('ref/summary', 'lambda or and not in is BOOLEAN COMPARISON BITWISE SHIFTING BINARY FORMATTING POWER UNARY ATTRIBUTES SUBSCRIPTS SLICINGS CALLS TUPLES LISTS DICTIONARIES BACKQUOTES'),
+        'OPERATORS': 'EXPRESSIONS',
+        'PRECEDENCE': 'EXPRESSIONS',
+        'OBJECTS': ('ref/objects', 'TYPES'),
+        'SPECIALMETHODS': ('ref/specialnames', 'BASICMETHODS ATTRIBUTEMETHODS CALLABLEMETHODS SEQUENCEMETHODS1 MAPPINGMETHODS SEQUENCEMETHODS2 NUMBERMETHODS CLASSES'),
+        'BASICMETHODS': ('ref/customization', 'cmp hash repr str SPECIALMETHODS'),
+        'ATTRIBUTEMETHODS': ('ref/attribute-access', 'ATTRIBUTES SPECIALMETHODS'),
+        'CALLABLEMETHODS': ('ref/callable-types', 'CALLS SPECIALMETHODS'),
+        'SEQUENCEMETHODS1': ('ref/sequence-types', 'SEQUENCES SEQUENCEMETHODS2 SPECIALMETHODS'),
+        'SEQUENCEMETHODS2': ('ref/sequence-methods', 'SEQUENCES SEQUENCEMETHODS1 SPECIALMETHODS'),
+        'MAPPINGMETHODS': ('ref/sequence-types', 'MAPPINGS SPECIALMETHODS'),
+        'NUMBERMETHODS': ('ref/numeric-types', 'NUMBERS AUGMENTEDASSIGNMENT SPECIALMETHODS'),
+        'EXECUTION': ('ref/execmodel', 'NAMESPACES DYNAMICFEATURES EXCEPTIONS'),
+        'NAMESPACES': ('ref/naming', 'global ASSIGNMENT DELETION DYNAMICFEATURES'),
+        'DYNAMICFEATURES': ('ref/dynamic-features', ''),
+        'SCOPING': 'NAMESPACES',
+        'FRAMES': 'NAMESPACES',
+        'EXCEPTIONS': ('ref/exceptions', 'try except finally raise'),
+        'COERCIONS': ('ref/coercion-rules','CONVERSIONS'),
+        'CONVERSIONS': ('ref/conversions', 'COERCIONS'),
+        'IDENTIFIERS': ('ref/identifiers', 'keywords SPECIALIDENTIFIERS'),
+        'SPECIALIDENTIFIERS': ('ref/id-classes', ''),
+        'PRIVATENAMES': ('ref/atom-identifiers', ''),
+        'LITERALS': ('ref/atom-literals', 'STRINGS BACKQUOTES NUMBERS TUPLELITERALS LISTLITERALS DICTIONARYLITERALS'),
+        'TUPLES': 'SEQUENCES',
+        'TUPLELITERALS': ('ref/exprlists', 'TUPLES LITERALS'),
+        'LISTS': ('lib/typesseq-mutable', 'LISTLITERALS'),
+        'LISTLITERALS': ('ref/lists', 'LISTS LITERALS'),
+        'DICTIONARIES': ('lib/typesmapping', 'DICTIONARYLITERALS'),
+        'DICTIONARYLITERALS': ('ref/dict', 'DICTIONARIES LITERALS'),
+        'BACKQUOTES': ('ref/string-conversions', 'repr str STRINGS LITERALS'),
+        'ATTRIBUTES': ('ref/attribute-references', 'getattr hasattr setattr ATTRIBUTEMETHODS'),
+        'SUBSCRIPTS': ('ref/subscriptions', 'SEQUENCEMETHODS1'),
+        'SLICINGS': ('ref/slicings', 'SEQUENCEMETHODS2'),
+        'CALLS': ('ref/calls', 'EXPRESSIONS'),
+        'POWER': ('ref/power', 'EXPRESSIONS'),
+        'UNARY': ('ref/unary', 'EXPRESSIONS'),
+        'BINARY': ('ref/binary', 'EXPRESSIONS'),
+        'SHIFTING': ('ref/shifting', 'EXPRESSIONS'),
+        'BITWISE': ('ref/bitwise', 'EXPRESSIONS'),
+        'COMPARISON': ('ref/comparisons', 'EXPRESSIONS BASICMETHODS'),
+        'BOOLEAN': ('ref/Booleans', 'EXPRESSIONS TRUTHVALUE'),
+        'ASSERTION': 'assert',
+        'ASSIGNMENT': ('ref/assignment', 'AUGMENTEDASSIGNMENT'),
+        'AUGMENTEDASSIGNMENT': ('ref/augassign', 'NUMBERMETHODS'),
+        'DELETION': 'del',
+        'PRINTING': 'print',
+        'RETURNING': 'return',
+        'IMPORTING': 'import',
+        'CONDITIONAL': 'if',
+        'LOOPING': ('ref/compound', 'for while break continue'),
+        'TRUTHVALUE': ('lib/truth', 'if while and or not BASICMETHODS'),
+        'DEBUGGING': ('lib/module-pdb', 'pdb'),
+        'CONTEXTMANAGERS': ('ref/context-managers', 'with'),
+    }
+
+    def __init__(self, input, output):
+        self.input = input
+        self.output = output
+        self.docdir = None
+        execdir = os.path.dirname(sys.executable)
+        homedir = os.environ.get('PYTHONHOME')
+        for dir in [os.environ.get('PYTHONDOCS'),
+                    homedir and os.path.join(homedir, 'doc'),
+                    os.path.join(execdir, 'doc'),
+                    '/usr/doc/python-docs-' + split(sys.version)[0],
+                    '/usr/doc/python-' + split(sys.version)[0],
+                    '/usr/doc/python-docs-' + sys.version[:3],
+                    '/usr/doc/python-' + sys.version[:3],
+                    os.path.join(sys.prefix, 'Resources/English.lproj/Documentation')]:
+            if dir and os.path.isdir(os.path.join(dir, 'lib')):
+                self.docdir = dir
+
+    def __repr__(self):
+        if inspect.stack()[1][3] == '?':
+            self()
+            return ''
+        return '<pydoc.Helper instance>'
+
+    def __call__(self, request=None):
+        if request is not None:
+            self.help(request)
+        else:
+            self.intro()
+            self.interact()
+            self.output.write('''
+You are now leaving help and returning to the Python interpreter.
+If you want to ask for help on a particular object directly from the
+interpreter, you can type "help(object)".  Executing "help('string')"
+has the same effect as typing a particular string at the help> prompt.
+''')
+
+    def interact(self):
+        self.output.write('\n')
+        while True:
+            try:
+                request = self.getline('help> ')
+                if not request: break
+            except (KeyboardInterrupt, EOFError):
+                break
+            request = strip(replace(request, '"', '', "'", ''))
+            if lower(request) in ('q', 'quit'): break
+            self.help(request)
+
+    def getline(self, prompt):
+        """Read one line, using raw_input when available."""
+        if self.input is sys.stdin:
+            return raw_input(prompt)
+        else:
+            self.output.write(prompt)
+            self.output.flush()
+            return self.input.readline()
+
+    def help(self, request):
+        if type(request) is type(''):
+            if request == 'help': self.intro()
+            elif request == 'keywords': self.listkeywords()
+            elif request == 'topics': self.listtopics()
+            elif request == 'modules': self.listmodules()
+            elif request[:8] == 'modules ':
+                self.listmodules(split(request)[1])
+            elif request in self.keywords: self.showtopic(request)
+            elif request in self.topics: self.showtopic(request)
+            elif request: doc(request, 'Help on %s:')
+        elif isinstance(request, Helper): self()
+        else: doc(request, 'Help on %s:')
+        self.output.write('\n')
+
+    def intro(self):
+        self.output.write('''
+Welcome to Python %s!  This is the online help utility.
+
+If this is your first time using Python, you should definitely check out
+the tutorial on the Internet at http://www.python.org/doc/tut/.
+
+Enter the name of any module, keyword, or topic to get help on writing
+Python programs and using Python modules.  To quit this help utility and
+return to the interpreter, just type "quit".
+
+To get a list of available modules, keywords, or topics, type "modules",
+"keywords", or "topics".  Each module also comes with a one-line summary
+of what it does; to list the modules whose summaries contain a given word
+such as "spam", type "modules spam".
+''' % sys.version[:3])
+
+    def list(self, items, columns=4, width=80):
+        items = items[:]
+        items.sort()
+        colw = width / columns
+        rows = (len(items) + columns - 1) / columns
+        for row in range(rows):
+            for col in range(columns):
+                i = col * rows + row
+                if i < len(items):
+                    self.output.write(items[i])
+                    if col < columns - 1:
+                        self.output.write(' ' + ' ' * (colw-1 - len(items[i])))
+            self.output.write('\n')
+
+    def listkeywords(self):
+        self.output.write('''
+Here is a list of the Python keywords.  Enter any keyword to get more help.
+
+''')
+        self.list(self.keywords.keys())
+
+    def listtopics(self):
+        self.output.write('''
+Here is a list of available topics.  Enter any topic name to get more help.
+
+''')
+        self.list(self.topics.keys())
+
+    def showtopic(self, topic):
+        if not self.docdir:
+            self.output.write('''
+Sorry, topic and keyword documentation is not available because the Python
+HTML documentation files could not be found.  If you have installed them,
+please set the environment variable PYTHONDOCS to indicate their location.
+
+On the Microsoft Windows operating system, the files can be built by
+running "hh -decompile . PythonNN.chm" in the C:\PythonNN\Doc> directory.
+''')
+            return
+        target = self.topics.get(topic, self.keywords.get(topic))
+        if not target:
+            self.output.write('no documentation found for %s\n' % repr(topic))
+            return
+        if type(target) is type(''):
+            return self.showtopic(target)
+
+        filename, xrefs = target
+        filename = self.docdir + '/' + filename + '.html'
+        try:
+            file = open(filename)
+        except:
+            self.output.write('could not read docs from %s\n' % filename)
+            return
+
+        divpat = re.compile('<div[^>]*navigat.*?</div.*?>', re.I | re.S)
+        addrpat = re.compile('<address.*?>.*?</address.*?>', re.I | re.S)
+        document = re.sub(addrpat, '', re.sub(divpat, '', file.read()))
+        file.close()
+
+        import htmllib, formatter, StringIO
+        buffer = StringIO.StringIO()
+        parser = htmllib.HTMLParser(
+            formatter.AbstractFormatter(formatter.DumbWriter(buffer)))
+        parser.start_table = parser.do_p
+        parser.end_table = lambda parser=parser: parser.do_p({})
+        parser.start_tr = parser.do_br
+        parser.start_td = parser.start_th = lambda a, b=buffer: b.write('\t')
+        parser.feed(document)
+        buffer = replace(buffer.getvalue(), '\xa0', ' ', '\n', '\n  ')
+        pager('  ' + strip(buffer) + '\n')
+        if xrefs:
+            buffer = StringIO.StringIO()
+            formatter.DumbWriter(buffer).send_flowing_data(
+                'Related help topics: ' + join(split(xrefs), ', ') + '\n')
+            self.output.write('\n%s\n' % buffer.getvalue())
+
+    def listmodules(self, key=''):
+        if key:
+            self.output.write('''
+Here is a list of matching modules.  Enter any module name to get more help.
+
+''')
+            apropos(key)
+        else:
+            self.output.write('''
+Please wait a moment while I gather a list of all available modules...
+
+''')
+            modules = {}
+            def callback(path, modname, desc, modules=modules):
+                if modname and modname[-9:] == '.__init__':
+                    modname = modname[:-9] + ' (package)'
+                if find(modname, '.') < 0:
+                    modules[modname] = 1
+            ModuleScanner().run(callback)
+            self.list(modules.keys())
+            self.output.write('''
+Enter any module name to get more help.  Or, type "modules spam" to search
+for modules whose descriptions contain the word "spam".
+''')
+
+help = Helper(sys.stdin, sys.stdout)
+
+class Scanner:
+    """A generic tree iterator."""
+    def __init__(self, roots, children, descendp):
+        self.roots = roots[:]
+        self.state = []
+        self.children = children
+        self.descendp = descendp
+
+    def next(self):
+        if not self.state:
+            if not self.roots:
+                return None
+            root = self.roots.pop(0)
+            self.state = [(root, self.children(root))]
+        node, children = self.state[-1]
+        if not children:
+            self.state.pop()
+            return self.next()
+        child = children.pop(0)
+        if self.descendp(child):
+            self.state.append((child, self.children(child)))
+        return child
+
+
+class ModuleScanner:
+    """An interruptible scanner that searches module synopses."""
+
+    def run(self, callback, key=None, completer=None):
+        if key: key = lower(key)
+        self.quit = False
+        seen = {}
+
+        for modname in sys.builtin_module_names:
+            if modname != '__main__':
+                seen[modname] = 1
+                if key is None:
+                    callback(None, modname, '')
+                else:
+                    desc = split(__import__(modname).__doc__ or '', '\n')[0]
+                    if find(lower(modname + ' - ' + desc), key) >= 0:
+                        callback(None, modname, desc)
+
+        for importer, modname, ispkg in pkgutil.walk_packages():
+            if self.quit:
+                break
+            if key is None:
+                callback(None, modname, '')
+            else:
+                loader = importer.find_module(modname)
+                if hasattr(loader,'get_source'):
+                    import StringIO
+                    desc = source_synopsis(
+                        StringIO.StringIO(loader.get_source(modname))
+                    ) or ''
+                    if hasattr(loader,'get_filename'):
+                        path = loader.get_filename(modname)
+                    else:
+                        path = None
+                else:
+                    module = loader.load_module(modname)
+                    desc = (module.__doc__ or '').splitlines()[0]
+                    path = getattr(module,'__file__',None)
+                if find(lower(modname + ' - ' + desc), key) >= 0:
+                    callback(path, modname, desc)
+
+        if completer:
+            completer()
+
+def apropos(key):
+    """Print all the one-line module summaries that contain a substring."""
+    def callback(path, modname, desc):
+        if modname[-9:] == '.__init__':
+            modname = modname[:-9] + ' (package)'
+        print modname, desc and '- ' + desc
+    try: import warnings
+    except ImportError: pass
+    else: warnings.filterwarnings('ignore') # ignore problems during import
+    ModuleScanner().run(callback, key)
+
+# --------------------------------------------------- web browser interface
+
+def serve(port, callback=None, completer=None):
+    import BaseHTTPServer, mimetools, select
+
+    # Patch up mimetools.Message so it doesn't break if rfc822 is reloaded.
+    class Message(mimetools.Message):
+        def __init__(self, fp, seekable=1):
+            Message = self.__class__
+            Message.__bases__[0].__bases__[0].__init__(self, fp, seekable)
+            self.encodingheader = self.getheader('content-transfer-encoding')
+            self.typeheader = self.getheader('content-type')
+            self.parsetype()
+            self.parseplist()
+
+    class DocHandler(BaseHTTPServer.BaseHTTPRequestHandler):
+        def send_document(self, title, contents):
+            try:
+                self.send_response(200)
+                self.send_header('Content-Type', 'text/html')
+                self.end_headers()
+                self.wfile.write(html.page(title, contents))
+            except IOError: pass
+
+        def do_GET(self):
+            path = self.path
+            if path[-5:] == '.html': path = path[:-5]
+            if path[:1] == '/': path = path[1:]
+            if path and path != '.':
+                try:
+                    obj = locate(path, forceload=1)
+                except ErrorDuringImport, value:
+                    self.send_document(path, html.escape(str(value)))
+                    return
+                if obj:
+                    self.send_document(describe(obj), html.document(obj, path))
+                else:
+                    self.send_document(path,
+'no Python documentation found for %s' % repr(path))
+            else:
+                heading = html.heading(
+'<big><big><strong>Python: Index of Modules</strong></big></big>',
+'#ffffff', '#7799ee')
+                def bltinlink(name):
+                    return '<a href="%s.html">%s</a>' % (name, name)
+                names = filter(lambda x: x != '__main__',
+                               sys.builtin_module_names)
+                contents = html.multicolumn(names, bltinlink)
+                indices = ['<p>' + html.bigsection(
+                    'Built-in Modules', '#ffffff', '#ee77aa', contents)]
+
+                seen = {}
+                for dir in sys.path:
+                    indices.append(html.index(dir, seen))
+                contents = heading + join(indices) + '''<p align=right>
+<font color="#909090" face="helvetica, arial"><strong>
+pydoc</strong> by Ka-Ping Yee &lt;ping at lfw.org&gt;</font>'''
+                self.send_document('Index of Modules', contents)
+
+        def log_message(self, *args): pass
+
+    class DocServer(BaseHTTPServer.HTTPServer):
+        def __init__(self, port, callback):
+            host = (sys.platform == 'mac') and '127.0.0.1' or 'localhost'
+            self.address = ('', port)
+            self.url = 'http://%s:%d/' % (host, port)
+            self.callback = callback
+            self.base.__init__(self, self.address, self.handler)
+
+        def serve_until_quit(self):
+            import select
+            self.quit = False
+            while not self.quit:
+                rd, wr, ex = select.select([self.socket.fileno()], [], [], 1)
+                if rd: self.handle_request()
+
+        def server_activate(self):
+            self.base.server_activate(self)
+            if self.callback: self.callback(self)
+
+    DocServer.base = BaseHTTPServer.HTTPServer
+    DocServer.handler = DocHandler
+    DocHandler.MessageClass = Message
+    try:
+        try:
+            DocServer(port, callback).serve_until_quit()
+        except (KeyboardInterrupt, select.error):
+            pass
+    finally:
+        if completer: completer()
+
+# ----------------------------------------------------- graphical interface
+
+def gui():
+    """Graphical interface (starts web server and pops up a control window)."""
+    class GUI:
+        def __init__(self, window, port=7464):
+            self.window = window
+            self.server = None
+            self.scanner = None
+
+            import Tkinter
+            self.server_frm = Tkinter.Frame(window)
+            self.title_lbl = Tkinter.Label(self.server_frm,
+                text='Starting server...\n ')
+            self.open_btn = Tkinter.Button(self.server_frm,
+                text='open browser', command=self.open, state='disabled')
+            self.quit_btn = Tkinter.Button(self.server_frm,
+                text='quit serving', command=self.quit, state='disabled')
+
+            self.search_frm = Tkinter.Frame(window)
+            self.search_lbl = Tkinter.Label(self.search_frm, text='Search for')
+            self.search_ent = Tkinter.Entry(self.search_frm)
+            self.search_ent.bind('<Return>', self.search)
+            self.stop_btn = Tkinter.Button(self.search_frm,
+                text='stop', pady=0, command=self.stop, state='disabled')
+            if sys.platform == 'win32':
+                # Trying to hide and show this button crashes under Windows.
+                self.stop_btn.pack(side='right')
+
+            self.window.title('pydoc')
+            self.window.protocol('WM_DELETE_WINDOW', self.quit)
+            self.title_lbl.pack(side='top', fill='x')
+            self.open_btn.pack(side='left', fill='x', expand=1)
+            self.quit_btn.pack(side='right', fill='x', expand=1)
+            self.server_frm.pack(side='top', fill='x')
+
+            self.search_lbl.pack(side='left')
+            self.search_ent.pack(side='right', fill='x', expand=1)
+            self.search_frm.pack(side='top', fill='x')
+            self.search_ent.focus_set()
+
+            font = ('helvetica', sys.platform == 'win32' and 8 or 10)
+            self.result_lst = Tkinter.Listbox(window, font=font, height=6)
+            self.result_lst.bind('<Button-1>', self.select)
+            self.result_lst.bind('<Double-Button-1>', self.goto)
+            self.result_scr = Tkinter.Scrollbar(window,
+                orient='vertical', command=self.result_lst.yview)
+            self.result_lst.config(yscrollcommand=self.result_scr.set)
+
+            self.result_frm = Tkinter.Frame(window)
+            self.goto_btn = Tkinter.Button(self.result_frm,
+                text='go to selected', command=self.goto)
+            self.hide_btn = Tkinter.Button(self.result_frm,
+                text='hide results', command=self.hide)
+            self.goto_btn.pack(side='left', fill='x', expand=1)
+            self.hide_btn.pack(side='right', fill='x', expand=1)
+
+            self.window.update()
+            self.minwidth = self.window.winfo_width()
+            self.minheight = self.window.winfo_height()
+            self.bigminheight = (self.server_frm.winfo_reqheight() +
+                                 self.search_frm.winfo_reqheight() +
+                                 self.result_lst.winfo_reqheight() +
+                                 self.result_frm.winfo_reqheight())
+            self.bigwidth, self.bigheight = self.minwidth, self.bigminheight
+            self.expanded = 0
+            self.window.wm_geometry('%dx%d' % (self.minwidth, self.minheight))
+            self.window.wm_minsize(self.minwidth, self.minheight)
+            self.window.tk.willdispatch()
+
+            import threading
+            threading.Thread(
+                target=serve, args=(port, self.ready, self.quit)).start()
+
+        def ready(self, server):
+            self.server = server
+            self.title_lbl.config(
+                text='Python documentation server at\n' + server.url)
+            self.open_btn.config(state='normal')
+            self.quit_btn.config(state='normal')
+
+        def open(self, event=None, url=None):
+            url = url or self.server.url
+            try:
+                import webbrowser
+                webbrowser.open(url)
+            except ImportError: # pre-webbrowser.py compatibility
+                if sys.platform == 'win32':
+                    os.system('start "%s"' % url)
+                elif sys.platform == 'mac':
+                    try: import ic
+                    except ImportError: pass
+                    else: ic.launchurl(url)
+                else:
+                    rc = os.system('netscape -remote "openURL(%s)" &' % url)
+                    if rc: os.system('netscape "%s" &' % url)
+
+        def quit(self, event=None):
+            if self.server:
+                self.server.quit = 1
+            self.window.quit()
+
+        def search(self, event=None):
+            key = self.search_ent.get()
+            self.stop_btn.pack(side='right')
+            self.stop_btn.config(state='normal')
+            self.search_lbl.config(text='Searching for "%s"...' % key)
+            self.search_ent.forget()
+            self.search_lbl.pack(side='left')
+            self.result_lst.delete(0, 'end')
+            self.goto_btn.config(state='disabled')
+            self.expand()
+
+            import threading
+            if self.scanner:
+                self.scanner.quit = 1
+            self.scanner = ModuleScanner()
+            threading.Thread(target=self.scanner.run,
+                             args=(self.update, key, self.done)).start()
+
+        def update(self, path, modname, desc):
+            if modname[-9:] == '.__init__':
+                modname = modname[:-9] + ' (package)'
+            self.result_lst.insert('end',
+                modname + ' - ' + (desc or '(no description)'))
+
+        def stop(self, event=None):
+            if self.scanner:
+                self.scanner.quit = 1
+                self.scanner = None
+
+        def done(self):
+            self.scanner = None
+            self.search_lbl.config(text='Search for')
+            self.search_lbl.pack(side='left')
+            self.search_ent.pack(side='right', fill='x', expand=1)
+            if sys.platform != 'win32': self.stop_btn.forget()
+            self.stop_btn.config(state='disabled')
+
+        def select(self, event=None):
+            self.goto_btn.config(state='normal')
+
+        def goto(self, event=None):
+            selection = self.result_lst.curselection()
+            if selection:
+                modname = split(self.result_lst.get(selection[0]))[0]
+                self.open(url=self.server.url + modname + '.html')
+
+        def collapse(self):
+            if not self.expanded: return
+            self.result_frm.forget()
+            self.result_scr.forget()
+            self.result_lst.forget()
+            self.bigwidth = self.window.winfo_width()
+            self.bigheight = self.window.winfo_height()
+            self.window.wm_geometry('%dx%d' % (self.minwidth, self.minheight))
+            self.window.wm_minsize(self.minwidth, self.minheight)
+            self.expanded = 0
+
+        def expand(self):
+            if self.expanded: return
+            self.result_frm.pack(side='bottom', fill='x')
+            self.result_scr.pack(side='right', fill='y')
+            self.result_lst.pack(side='top', fill='both', expand=1)
+            self.window.wm_geometry('%dx%d' % (self.bigwidth, self.bigheight))
+            self.window.wm_minsize(self.minwidth, self.bigminheight)
+            self.expanded = 1
+
+        def hide(self, event=None):
+            self.stop()
+            self.collapse()
+
+    import Tkinter
+    try:
+        root = Tkinter.Tk()
+        # Tk will crash if pythonw.exe has an XP .manifest
+        # file and the root has is not destroyed explicitly.
+        # If the problem is ever fixed in Tk, the explicit
+        # destroy can go.
+        try:
+            gui = GUI(root)
+            root.mainloop()
+        finally:
+            root.destroy()
+    except KeyboardInterrupt:
+        pass
+
+# -------------------------------------------------- command-line interface
+
+def ispath(x):
+    return isinstance(x, str) and find(x, os.sep) >= 0
+
+def cli():
+    """Command-line interface (looks at sys.argv to decide what to do)."""
+    import getopt
+    class BadUsage: pass
+
+    # Scripts don't get the current directory in their path by default.
+    scriptdir = os.path.dirname(sys.argv[0])
+    if scriptdir in sys.path:
+        sys.path.remove(scriptdir)
+    sys.path.insert(0, '.')
+
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], 'gk:p:w')
+        writing = 0
+
+        for opt, val in opts:
+            if opt == '-g':
+                gui()
+                return
+            if opt == '-k':
+                apropos(val)
+                return
+            if opt == '-p':
+                try:
+                    port = int(val)
+                except ValueError:
+                    raise BadUsage
+                def ready(server):
+                    print 'pydoc server ready at %s' % server.url
+                def stopped():
+                    print 'pydoc server stopped'
+                serve(port, ready, stopped)
+                return
+            if opt == '-w':
+                writing = 1
+
+        if not args: raise BadUsage
+        for arg in args:
+            if ispath(arg) and not os.path.exists(arg):
+                print 'file %r does not exist' % arg
+                break
+            try:
+                if ispath(arg) and os.path.isfile(arg):
+                    arg = importfile(arg)
+                if writing:
+                    if ispath(arg) and os.path.isdir(arg):
+                        writedocs(arg)
+                    else:
+                        writedoc(arg)
+                else:
+                    help.help(arg)
+            except ErrorDuringImport, value:
+                print value
+
+    except (getopt.error, BadUsage):
+        cmd = os.path.basename(sys.argv[0])
+        print """pydoc - the Python documentation tool
+
+%s <name> ...
+    Show text documentation on something.  <name> may be the name of a
+    Python keyword, topic, function, module, or package, or a dotted
+    reference to a class or function within a module or module in a
+    package.  If <name> contains a '%s', it is used as the path to a
+    Python source file to document. If name is 'keywords', 'topics',
+    or 'modules', a listing of these things is displayed.
+
+%s -k <keyword>
+    Search for a keyword in the synopsis lines of all available modules.
+
+%s -p <port>
+    Start an HTTP server on the given port on the local machine.
+
+%s -g
+    Pop up a graphical interface for finding and serving documentation.
+
+%s -w <name> ...
+    Write out the HTML documentation for a module to a file in the current
+    directory.  If <name> contains a '%s', it is treated as a filename; if
+    it names a directory, documentation is written for all the contents.
+""" % (cmd, os.sep, cmd, cmd, cmd, cmd, os.sep)
+
+if __name__ == '__main__': cli()


Property changes on: vendor/Python/current/Lib/pydoc.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/quopri.py
===================================================================
--- vendor/Python/current/Lib/quopri.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/quopri.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,237 @@
+#! /usr/bin/env python
+
+"""Conversions to/from quoted-printable transport encoding as per RFC 1521."""
+
+# (Dec 1991 version).
+
+__all__ = ["encode", "decode", "encodestring", "decodestring"]
+
+ESCAPE = '='
+MAXLINESIZE = 76
+HEX = '0123456789ABCDEF'
+EMPTYSTRING = ''
+
+try:
+    from binascii import a2b_qp, b2a_qp
+except ImportError:
+    a2b_qp = None
+    b2a_qp = None
+
+
+def needsquoting(c, quotetabs, header):
+    """Decide whether a particular character needs to be quoted.
+
+    The 'quotetabs' flag indicates whether embedded tabs and spaces should be
+    quoted.  Note that line-ending tabs and spaces are always encoded, as per
+    RFC 1521.
+    """
+    if c in ' \t':
+        return quotetabs
+    # if header, we have to escape _ because _ is used to escape space
+    if c == '_':
+        return header
+    return c == ESCAPE or not (' ' <= c <= '~')
+
+def quote(c):
+    """Quote a single character."""
+    i = ord(c)
+    return ESCAPE + HEX[i//16] + HEX[i%16]
+
+
+
+def encode(input, output, quotetabs, header = 0):
+    """Read 'input', apply quoted-printable encoding, and write to 'output'.
+
+    'input' and 'output' are files with readline() and write() methods.
+    The 'quotetabs' flag indicates whether embedded tabs and spaces should be
+    quoted.  Note that line-ending tabs and spaces are always encoded, as per
+    RFC 1521.
+    The 'header' flag indicates whether we are encoding spaces as _ as per
+    RFC 1522.
+    """
+
+    if b2a_qp is not None:
+        data = input.read()
+        odata = b2a_qp(data, quotetabs = quotetabs, header = header)
+        output.write(odata)
+        return
+
+    def write(s, output=output, lineEnd='\n'):
+        # RFC 1521 requires that the line ending in a space or tab must have
+        # that trailing character encoded.
+        if s and s[-1:] in ' \t':
+            output.write(s[:-1] + quote(s[-1]) + lineEnd)
+        elif s == '.':
+            output.write(quote(s) + lineEnd)
+        else:
+            output.write(s + lineEnd)
+
+    prevline = None
+    while 1:
+        line = input.readline()
+        if not line:
+            break
+        outline = []
+        # Strip off any readline induced trailing newline
+        stripped = ''
+        if line[-1:] == '\n':
+            line = line[:-1]
+            stripped = '\n'
+        # Calculate the un-length-limited encoded line
+        for c in line:
+            if needsquoting(c, quotetabs, header):
+                c = quote(c)
+            if header and c == ' ':
+                outline.append('_')
+            else:
+                outline.append(c)
+        # First, write out the previous line
+        if prevline is not None:
+            write(prevline)
+        # Now see if we need any soft line breaks because of RFC-imposed
+        # length limitations.  Then do the thisline->prevline dance.
+        thisline = EMPTYSTRING.join(outline)
+        while len(thisline) > MAXLINESIZE:
+            # Don't forget to include the soft line break `=' sign in the
+            # length calculation!
+            write(thisline[:MAXLINESIZE-1], lineEnd='=\n')
+            thisline = thisline[MAXLINESIZE-1:]
+        # Write out the current line
+        prevline = thisline
+    # Write out the last line, without a trailing newline
+    if prevline is not None:
+        write(prevline, lineEnd=stripped)
+
+def encodestring(s, quotetabs = 0, header = 0):
+    if b2a_qp is not None:
+        return b2a_qp(s, quotetabs = quotetabs, header = header)
+    from cStringIO import StringIO
+    infp = StringIO(s)
+    outfp = StringIO()
+    encode(infp, outfp, quotetabs, header)
+    return outfp.getvalue()
+
+
+
+def decode(input, output, header = 0):
+    """Read 'input', apply quoted-printable decoding, and write to 'output'.
+    'input' and 'output' are files with readline() and write() methods.
+    If 'header' is true, decode underscore as space (per RFC 1522)."""
+
+    if a2b_qp is not None:
+        data = input.read()
+        odata = a2b_qp(data, header = header)
+        output.write(odata)
+        return
+
+    new = ''
+    while 1:
+        line = input.readline()
+        if not line: break
+        i, n = 0, len(line)
+        if n > 0 and line[n-1] == '\n':
+            partial = 0; n = n-1
+            # Strip trailing whitespace
+            while n > 0 and line[n-1] in " \t\r":
+                n = n-1
+        else:
+            partial = 1
+        while i < n:
+            c = line[i]
+            if c == '_' and header:
+                new = new + ' '; i = i+1
+            elif c != ESCAPE:
+                new = new + c; i = i+1
+            elif i+1 == n and not partial:
+                partial = 1; break
+            elif i+1 < n and line[i+1] == ESCAPE:
+                new = new + ESCAPE; i = i+2
+            elif i+2 < n and ishex(line[i+1]) and ishex(line[i+2]):
+                new = new + chr(unhex(line[i+1:i+3])); i = i+3
+            else: # Bad escape sequence -- leave it in
+                new = new + c; i = i+1
+        if not partial:
+            output.write(new + '\n')
+            new = ''
+    if new:
+        output.write(new)
+
+def decodestring(s, header = 0):
+    if a2b_qp is not None:
+        return a2b_qp(s, header = header)
+    from cStringIO import StringIO
+    infp = StringIO(s)
+    outfp = StringIO()
+    decode(infp, outfp, header = header)
+    return outfp.getvalue()
+
+
+
+# Other helper functions
+def ishex(c):
+    """Return true if the character 'c' is a hexadecimal digit."""
+    return '0' <= c <= '9' or 'a' <= c <= 'f' or 'A' <= c <= 'F'
+
+def unhex(s):
+    """Get the integer value of a hexadecimal number."""
+    bits = 0
+    for c in s:
+        if '0' <= c <= '9':
+            i = ord('0')
+        elif 'a' <= c <= 'f':
+            i = ord('a')-10
+        elif 'A' <= c <= 'F':
+            i = ord('A')-10
+        else:
+            break
+        bits = bits*16 + (ord(c) - i)
+    return bits
+
+
+
+def main():
+    import sys
+    import getopt
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], 'td')
+    except getopt.error, msg:
+        sys.stdout = sys.stderr
+        print msg
+        print "usage: quopri [-t | -d] [file] ..."
+        print "-t: quote tabs"
+        print "-d: decode; default encode"
+        sys.exit(2)
+    deco = 0
+    tabs = 0
+    for o, a in opts:
+        if o == '-t': tabs = 1
+        if o == '-d': deco = 1
+    if tabs and deco:
+        sys.stdout = sys.stderr
+        print "-t and -d are mutually exclusive"
+        sys.exit(2)
+    if not args: args = ['-']
+    sts = 0
+    for file in args:
+        if file == '-':
+            fp = sys.stdin
+        else:
+            try:
+                fp = open(file)
+            except IOError, msg:
+                sys.stderr.write("%s: can't open (%s)\n" % (file, msg))
+                sts = 1
+                continue
+        if deco:
+            decode(fp, sys.stdout)
+        else:
+            encode(fp, sys.stdout, tabs)
+        if fp is not sys.stdin:
+            fp.close()
+    if sts:
+        sys.exit(sts)
+
+
+
+if __name__ == '__main__':
+    main()


Property changes on: vendor/Python/current/Lib/quopri.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/random.py
===================================================================
--- vendor/Python/current/Lib/random.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/random.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,862 @@
+"""Random variable generators.
+
+    integers
+    --------
+           uniform within range
+
+    sequences
+    ---------
+           pick random element
+           pick random sample
+           generate random permutation
+
+    distributions on the real line:
+    ------------------------------
+           uniform
+           normal (Gaussian)
+           lognormal
+           negative exponential
+           gamma
+           beta
+           pareto
+           Weibull
+
+    distributions on the circle (angles 0 to 2pi)
+    ---------------------------------------------
+           circular uniform
+           von Mises
+
+General notes on the underlying Mersenne Twister core generator:
+
+* The period is 2**19937-1.
+* It is one of the most extensively tested generators in existence.
+* Without a direct way to compute N steps forward, the semantics of
+  jumpahead(n) are weakened to simply jump to another distant state and rely
+  on the large period to avoid overlapping sequences.
+* The random() method is implemented in C, executes in a single Python step,
+  and is, therefore, threadsafe.
+
+"""
+
+from warnings import warn as _warn
+from types import MethodType as _MethodType, BuiltinMethodType as _BuiltinMethodType
+from math import log as _log, exp as _exp, pi as _pi, e as _e, ceil as _ceil
+from math import sqrt as _sqrt, acos as _acos, cos as _cos, sin as _sin
+from os import urandom as _urandom
+from binascii import hexlify as _hexlify
+
+__all__ = ["Random","seed","random","uniform","randint","choice","sample",
+           "randrange","shuffle","normalvariate","lognormvariate",
+           "expovariate","vonmisesvariate","gammavariate",
+           "gauss","betavariate","paretovariate","weibullvariate",
+           "getstate","setstate","jumpahead", "WichmannHill", "getrandbits",
+           "SystemRandom"]
+
+NV_MAGICCONST = 4 * _exp(-0.5)/_sqrt(2.0)
+TWOPI = 2.0*_pi
+LOG4 = _log(4.0)
+SG_MAGICCONST = 1.0 + _log(4.5)
+BPF = 53        # Number of bits in a float
+RECIP_BPF = 2**-BPF
+
+
+# Translated by Guido van Rossum from C source provided by
+# Adrian Baddeley.  Adapted by Raymond Hettinger for use with
+# the Mersenne Twister  and os.urandom() core generators.
+
+import _random
+
+class Random(_random.Random):
+    """Random number generator base class used by bound module functions.
+
+    Used to instantiate instances of Random to get generators that don't
+    share state.  Especially useful for multi-threaded programs, creating
+    a different instance of Random for each thread, and using the jumpahead()
+    method to ensure that the generated sequences seen by each thread don't
+    overlap.
+
+    Class Random can also be subclassed if you want to use a different basic
+    generator of your own devising: in that case, override the following
+    methods:  random(), seed(), getstate(), setstate() and jumpahead().
+    Optionally, implement a getrandombits() method so that randrange()
+    can cover arbitrarily large ranges.
+
+    """
+
+    VERSION = 2     # used by getstate/setstate
+
+    def __init__(self, x=None):
+        """Initialize an instance.
+
+        Optional argument x controls seeding, as for Random.seed().
+        """
+
+        self.seed(x)
+        self.gauss_next = None
+
+    def seed(self, a=None):
+        """Initialize internal state from hashable object.
+
+        None or no argument seeds from current time or from an operating
+        system specific randomness source if available.
+
+        If a is not None or an int or long, hash(a) is used instead.
+        """
+
+        if a is None:
+            try:
+                a = long(_hexlify(_urandom(16)), 16)
+            except NotImplementedError:
+                import time
+                a = long(time.time() * 256) # use fractional seconds
+
+        super(Random, self).seed(a)
+        self.gauss_next = None
+
+    def getstate(self):
+        """Return internal state; can be passed to setstate() later."""
+        return self.VERSION, super(Random, self).getstate(), self.gauss_next
+
+    def setstate(self, state):
+        """Restore internal state from object returned by getstate()."""
+        version = state[0]
+        if version == 2:
+            version, internalstate, self.gauss_next = state
+            super(Random, self).setstate(internalstate)
+        else:
+            raise ValueError("state with version %s passed to "
+                             "Random.setstate() of version %s" %
+                             (version, self.VERSION))
+
+## ---- Methods below this point do not need to be overridden when
+## ---- subclassing for the purpose of using a different core generator.
+
+## -------------------- pickle support  -------------------
+
+    def __getstate__(self): # for pickle
+        return self.getstate()
+
+    def __setstate__(self, state):  # for pickle
+        self.setstate(state)
+
+    def __reduce__(self):
+        return self.__class__, (), self.getstate()
+
+## -------------------- integer methods  -------------------
+
+    def randrange(self, start, stop=None, step=1, int=int, default=None,
+                  maxwidth=1L<<BPF):
+        """Choose a random item from range(start, stop[, step]).
+
+        This fixes the problem with randint() which includes the
+        endpoint; in Python this is usually not what you want.
+        Do not supply the 'int', 'default', and 'maxwidth' arguments.
+        """
+
+        # This code is a bit messy to make it fast for the
+        # common case while still doing adequate error checking.
+        istart = int(start)
+        if istart != start:
+            raise ValueError, "non-integer arg 1 for randrange()"
+        if stop is default:
+            if istart > 0:
+                if istart >= maxwidth:
+                    return self._randbelow(istart)
+                return int(self.random() * istart)
+            raise ValueError, "empty range for randrange()"
+
+        # stop argument supplied.
+        istop = int(stop)
+        if istop != stop:
+            raise ValueError, "non-integer stop for randrange()"
+        width = istop - istart
+        if step == 1 and width > 0:
+            # Note that
+            #     int(istart + self.random()*width)
+            # instead would be incorrect.  For example, consider istart
+            # = -2 and istop = 0.  Then the guts would be in
+            # -2.0 to 0.0 exclusive on both ends (ignoring that random()
+            # might return 0.0), and because int() truncates toward 0, the
+            # final result would be -1 or 0 (instead of -2 or -1).
+            #     istart + int(self.random()*width)
+            # would also be incorrect, for a subtler reason:  the RHS
+            # can return a long, and then randrange() would also return
+            # a long, but we're supposed to return an int (for backward
+            # compatibility).
+
+            if width >= maxwidth:
+                return int(istart + self._randbelow(width))
+            return int(istart + int(self.random()*width))
+        if step == 1:
+            raise ValueError, "empty range for randrange() (%d,%d, %d)" % (istart, istop, width)
+
+        # Non-unit step argument supplied.
+        istep = int(step)
+        if istep != step:
+            raise ValueError, "non-integer step for randrange()"
+        if istep > 0:
+            n = (width + istep - 1) // istep
+        elif istep < 0:
+            n = (width + istep + 1) // istep
+        else:
+            raise ValueError, "zero step for randrange()"
+
+        if n <= 0:
+            raise ValueError, "empty range for randrange()"
+
+        if n >= maxwidth:
+            return istart + istep*self._randbelow(n)
+        return istart + istep*int(self.random() * n)
+
+    def randint(self, a, b):
+        """Return random integer in range [a, b], including both end points.
+        """
+
+        return self.randrange(a, b+1)
+
+    def _randbelow(self, n, _log=_log, int=int, _maxwidth=1L<<BPF,
+                   _Method=_MethodType, _BuiltinMethod=_BuiltinMethodType):
+        """Return a random int in the range [0,n)
+
+        Handles the case where n has more bits than returned
+        by a single call to the underlying generator.
+        """
+
+        try:
+            getrandbits = self.getrandbits
+        except AttributeError:
+            pass
+        else:
+            # Only call self.getrandbits if the original random() builtin method
+            # has not been overridden or if a new getrandbits() was supplied.
+            # This assures that the two methods correspond.
+            if type(self.random) is _BuiltinMethod or type(getrandbits) is _Method:
+                k = int(1.00001 + _log(n-1, 2.0))   # 2**k > n-1 > 2**(k-2)
+                r = getrandbits(k)
+                while r >= n:
+                    r = getrandbits(k)
+                return r
+        if n >= _maxwidth:
+            _warn("Underlying random() generator does not supply \n"
+                "enough bits to choose from a population range this large")
+        return int(self.random() * n)
+
+## -------------------- sequence methods  -------------------
+
+    def choice(self, seq):
+        """Choose a random element from a non-empty sequence."""
+        return seq[int(self.random() * len(seq))]  # raises IndexError if seq is empty
+
+    def shuffle(self, x, random=None, int=int):
+        """x, random=random.random -> shuffle list x in place; return None.
+
+        Optional arg random is a 0-argument function returning a random
+        float in [0.0, 1.0); by default, the standard random.random.
+        """
+
+        if random is None:
+            random = self.random
+        for i in reversed(xrange(1, len(x))):
+            # pick an element in x[:i+1] with which to exchange x[i]
+            j = int(random() * (i+1))
+            x[i], x[j] = x[j], x[i]
+
+    def sample(self, population, k):
+        """Chooses k unique random elements from a population sequence.
+
+        Returns a new list containing elements from the population while
+        leaving the original population unchanged.  The resulting list is
+        in selection order so that all sub-slices will also be valid random
+        samples.  This allows raffle winners (the sample) to be partitioned
+        into grand prize and second place winners (the subslices).
+
+        Members of the population need not be hashable or unique.  If the
+        population contains repeats, then each occurrence is a possible
+        selection in the sample.
+
+        To choose a sample in a range of integers, use xrange as an argument.
+        This is especially fast and space efficient for sampling from a
+        large population:   sample(xrange(10000000), 60)
+        """
+
+        # XXX Although the documentation says `population` is "a sequence",
+        # XXX attempts are made to cater to any iterable with a __len__
+        # XXX method.  This has had mixed success.  Examples from both
+        # XXX sides:  sets work fine, and should become officially supported;
+        # XXX dicts are much harder, and have failed in various subtle
+        # XXX ways across attempts.  Support for mapping types should probably
+        # XXX be dropped (and users should pass mapping.keys() or .values()
+        # XXX explicitly).
+
+        # Sampling without replacement entails tracking either potential
+        # selections (the pool) in a list or previous selections in a set.
+
+        # When the number of selections is small compared to the
+        # population, then tracking selections is efficient, requiring
+        # only a small set and an occasional reselection.  For
+        # a larger number of selections, the pool tracking method is
+        # preferred since the list takes less space than the
+        # set and it doesn't suffer from frequent reselections.
+
+        n = len(population)
+        if not 0 <= k <= n:
+            raise ValueError, "sample larger than population"
+        random = self.random
+        _int = int
+        result = [None] * k
+        setsize = 21        # size of a small set minus size of an empty list
+        if k > 5:
+            setsize += 4 ** _ceil(_log(k * 3, 4)) # table size for big sets
+        if n <= setsize or hasattr(population, "keys"):
+            # An n-length list is smaller than a k-length set, or this is a
+            # mapping type so the other algorithm wouldn't work.
+            pool = list(population)
+            for i in xrange(k):         # invariant:  non-selected at [0,n-i)
+                j = _int(random() * (n-i))
+                result[i] = pool[j]
+                pool[j] = pool[n-i-1]   # move non-selected item into vacancy
+        else:
+            try:
+                selected = set()
+                selected_add = selected.add
+                for i in xrange(k):
+                    j = _int(random() * n)
+                    while j in selected:
+                        j = _int(random() * n)
+                    selected_add(j)
+                    result[i] = population[j]
+            except (TypeError, KeyError):   # handle (at least) sets
+                if isinstance(population, list):
+                    raise
+                return self.sample(tuple(population), k)
+        return result
+
+## -------------------- real-valued distributions  -------------------
+
+## -------------------- uniform distribution -------------------
+
+    def uniform(self, a, b):
+        """Get a random number in the range [a, b)."""
+        return a + (b-a) * self.random()
+
+## -------------------- normal distribution --------------------
+
+    def normalvariate(self, mu, sigma):
+        """Normal distribution.
+
+        mu is the mean, and sigma is the standard deviation.
+
+        """
+        # mu = mean, sigma = standard deviation
+
+        # Uses Kinderman and Monahan method. Reference: Kinderman,
+        # A.J. and Monahan, J.F., "Computer generation of random
+        # variables using the ratio of uniform deviates", ACM Trans
+        # Math Software, 3, (1977), pp257-260.
+
+        random = self.random
+        while 1:
+            u1 = random()
+            u2 = 1.0 - random()
+            z = NV_MAGICCONST*(u1-0.5)/u2
+            zz = z*z/4.0
+            if zz <= -_log(u2):
+                break
+        return mu + z*sigma
+
+## -------------------- lognormal distribution --------------------
+
+    def lognormvariate(self, mu, sigma):
+        """Log normal distribution.
+
+        If you take the natural logarithm of this distribution, you'll get a
+        normal distribution with mean mu and standard deviation sigma.
+        mu can have any value, and sigma must be greater than zero.
+
+        """
+        return _exp(self.normalvariate(mu, sigma))
+
+## -------------------- exponential distribution --------------------
+
+    def expovariate(self, lambd):
+        """Exponential distribution.
+
+        lambd is 1.0 divided by the desired mean.  (The parameter would be
+        called "lambda", but that is a reserved word in Python.)  Returned
+        values range from 0 to positive infinity.
+
+        """
+        # lambd: rate lambd = 1/mean
+        # ('lambda' is a Python reserved word)
+
+        random = self.random
+        u = random()
+        while u <= 1e-7:
+            u = random()
+        return -_log(u)/lambd
+
+## -------------------- von Mises distribution --------------------
+
+    def vonmisesvariate(self, mu, kappa):
+        """Circular data distribution.
+
+        mu is the mean angle, expressed in radians between 0 and 2*pi, and
+        kappa is the concentration parameter, which must be greater than or
+        equal to zero.  If kappa is equal to zero, this distribution reduces
+        to a uniform random angle over the range 0 to 2*pi.
+
+        """
+        # mu:    mean angle (in radians between 0 and 2*pi)
+        # kappa: concentration parameter kappa (>= 0)
+        # if kappa = 0 generate uniform random angle
+
+        # Based upon an algorithm published in: Fisher, N.I.,
+        # "Statistical Analysis of Circular Data", Cambridge
+        # University Press, 1993.
+
+        # Thanks to Magnus Kessler for a correction to the
+        # implementation of step 4.
+
+        random = self.random
+        if kappa <= 1e-6:
+            return TWOPI * random()
+
+        a = 1.0 + _sqrt(1.0 + 4.0 * kappa * kappa)
+        b = (a - _sqrt(2.0 * a))/(2.0 * kappa)
+        r = (1.0 + b * b)/(2.0 * b)
+
+        while 1:
+            u1 = random()
+
+            z = _cos(_pi * u1)
+            f = (1.0 + r * z)/(r + z)
+            c = kappa * (r - f)
+
+            u2 = random()
+
+            if u2 < c * (2.0 - c) or u2 <= c * _exp(1.0 - c):
+                break
+
+        u3 = random()
+        if u3 > 0.5:
+            theta = (mu % TWOPI) + _acos(f)
+        else:
+            theta = (mu % TWOPI) - _acos(f)
+
+        return theta
+
+## -------------------- gamma distribution --------------------
+
+    def gammavariate(self, alpha, beta):
+        """Gamma distribution.  Not the gamma function!
+
+        Conditions on the parameters are alpha > 0 and beta > 0.
+
+        """
+
+        # alpha > 0, beta > 0, mean is alpha*beta, variance is alpha*beta**2
+
+        # Warning: a few older sources define the gamma distribution in terms
+        # of alpha > -1.0
+        if alpha <= 0.0 or beta <= 0.0:
+            raise ValueError, 'gammavariate: alpha and beta must be > 0.0'
+
+        random = self.random
+        if alpha > 1.0:
+
+            # Uses R.C.H. Cheng, "The generation of Gamma
+            # variables with non-integral shape parameters",
+            # Applied Statistics, (1977), 26, No. 1, p71-74
+
+            ainv = _sqrt(2.0 * alpha - 1.0)
+            bbb = alpha - LOG4
+            ccc = alpha + ainv
+
+            while 1:
+                u1 = random()
+                if not 1e-7 < u1 < .9999999:
+                    continue
+                u2 = 1.0 - random()
+                v = _log(u1/(1.0-u1))/ainv
+                x = alpha*_exp(v)
+                z = u1*u1*u2
+                r = bbb+ccc*v-x
+                if r + SG_MAGICCONST - 4.5*z >= 0.0 or r >= _log(z):
+                    return x * beta
+
+        elif alpha == 1.0:
+            # expovariate(1)
+            u = random()
+            while u <= 1e-7:
+                u = random()
+            return -_log(u) * beta
+
+        else:   # alpha is between 0 and 1 (exclusive)
+
+            # Uses ALGORITHM GS of Statistical Computing - Kennedy & Gentle
+
+            while 1:
+                u = random()
+                b = (_e + alpha)/_e
+                p = b*u
+                if p <= 1.0:
+                    x = p ** (1.0/alpha)
+                else:
+                    x = -_log((b-p)/alpha)
+                u1 = random()
+                if p > 1.0:
+                    if u1 <= x ** (alpha - 1.0):
+                        break
+                elif u1 <= _exp(-x):
+                    break
+            return x * beta
+
+## -------------------- Gauss (faster alternative) --------------------
+
+    def gauss(self, mu, sigma):
+        """Gaussian distribution.
+
+        mu is the mean, and sigma is the standard deviation.  This is
+        slightly faster than the normalvariate() function.
+
+        Not thread-safe without a lock around calls.
+
+        """
+
+        # When x and y are two variables from [0, 1), uniformly
+        # distributed, then
+        #
+        #    cos(2*pi*x)*sqrt(-2*log(1-y))
+        #    sin(2*pi*x)*sqrt(-2*log(1-y))
+        #
+        # are two *independent* variables with normal distribution
+        # (mu = 0, sigma = 1).
+        # (Lambert Meertens)
+        # (corrected version; bug discovered by Mike Miller, fixed by LM)
+
+        # Multithreading note: When two threads call this function
+        # simultaneously, it is possible that they will receive the
+        # same return value.  The window is very small though.  To
+        # avoid this, you have to use a lock around all calls.  (I
+        # didn't want to slow this down in the serial case by using a
+        # lock here.)
+
+        random = self.random
+        z = self.gauss_next
+        self.gauss_next = None
+        if z is None:
+            x2pi = random() * TWOPI
+            g2rad = _sqrt(-2.0 * _log(1.0 - random()))
+            z = _cos(x2pi) * g2rad
+            self.gauss_next = _sin(x2pi) * g2rad
+
+        return mu + z*sigma
+
+## -------------------- beta --------------------
+## See
+## http://sourceforge.net/bugs/?func=detailbug&bug_id=130030&group_id=5470
+## for Ivan Frohne's insightful analysis of why the original implementation:
+##
+##    def betavariate(self, alpha, beta):
+##        # Discrete Event Simulation in C, pp 87-88.
+##
+##        y = self.expovariate(alpha)
+##        z = self.expovariate(1.0/beta)
+##        return z/(y+z)
+##
+## was dead wrong, and how it probably got that way.
+
+    def betavariate(self, alpha, beta):
+        """Beta distribution.
+
+        Conditions on the parameters are alpha > 0 and beta > 0.
+        Returned values range between 0 and 1.
+
+        """
+
+        # This version due to Janne Sinkkonen, and matches all the std
+        # texts (e.g., Knuth Vol 2 Ed 3 pg 134 "the beta distribution").
+        y = self.gammavariate(alpha, 1.)
+        if y == 0:
+            return 0.0
+        else:
+            return y / (y + self.gammavariate(beta, 1.))
+
+## -------------------- Pareto --------------------
+
+    def paretovariate(self, alpha):
+        """Pareto distribution.  alpha is the shape parameter."""
+        # Jain, pg. 495
+
+        u = 1.0 - self.random()
+        return 1.0 / pow(u, 1.0/alpha)
+
+## -------------------- Weibull --------------------
+
+    def weibullvariate(self, alpha, beta):
+        """Weibull distribution.
+
+        alpha is the scale parameter and beta is the shape parameter.
+
+        """
+        # Jain, pg. 499; bug fix courtesy Bill Arms
+
+        u = 1.0 - self.random()
+        return alpha * pow(-_log(u), 1.0/beta)
+
+## -------------------- Wichmann-Hill -------------------
+
+class WichmannHill(Random):
+
+    VERSION = 1     # used by getstate/setstate
+
+    def seed(self, a=None):
+        """Initialize internal state from hashable object.
+
+        None or no argument seeds from current time or from an operating
+        system specific randomness source if available.
+
+        If a is not None or an int or long, hash(a) is used instead.
+
+        If a is an int or long, a is used directly.  Distinct values between
+        0 and 27814431486575L inclusive are guaranteed to yield distinct
+        internal states (this guarantee is specific to the default
+        Wichmann-Hill generator).
+        """
+
+        if a is None:
+            try:
+                a = long(_hexlify(_urandom(16)), 16)
+            except NotImplementedError:
+                import time
+                a = long(time.time() * 256) # use fractional seconds
+
+        if not isinstance(a, (int, long)):
+            a = hash(a)
+
+        a, x = divmod(a, 30268)
+        a, y = divmod(a, 30306)
+        a, z = divmod(a, 30322)
+        self._seed = int(x)+1, int(y)+1, int(z)+1
+
+        self.gauss_next = None
+
+    def random(self):
+        """Get the next random number in the range [0.0, 1.0)."""
+
+        # Wichman-Hill random number generator.
+        #
+        # Wichmann, B. A. & Hill, I. D. (1982)
+        # Algorithm AS 183:
+        # An efficient and portable pseudo-random number generator
+        # Applied Statistics 31 (1982) 188-190
+        #
+        # see also:
+        #        Correction to Algorithm AS 183
+        #        Applied Statistics 33 (1984) 123
+        #
+        #        McLeod, A. I. (1985)
+        #        A remark on Algorithm AS 183
+        #        Applied Statistics 34 (1985),198-200
+
+        # This part is thread-unsafe:
+        # BEGIN CRITICAL SECTION
+        x, y, z = self._seed
+        x = (171 * x) % 30269
+        y = (172 * y) % 30307
+        z = (170 * z) % 30323
+        self._seed = x, y, z
+        # END CRITICAL SECTION
+
+        # Note:  on a platform using IEEE-754 double arithmetic, this can
+        # never return 0.0 (asserted by Tim; proof too long for a comment).
+        return (x/30269.0 + y/30307.0 + z/30323.0) % 1.0
+
+    def getstate(self):
+        """Return internal state; can be passed to setstate() later."""
+        return self.VERSION, self._seed, self.gauss_next
+
+    def setstate(self, state):
+        """Restore internal state from object returned by getstate()."""
+        version = state[0]
+        if version == 1:
+            version, self._seed, self.gauss_next = state
+        else:
+            raise ValueError("state with version %s passed to "
+                             "Random.setstate() of version %s" %
+                             (version, self.VERSION))
+
+    def jumpahead(self, n):
+        """Act as if n calls to random() were made, but quickly.
+
+        n is an int, greater than or equal to 0.
+
+        Example use:  If you have 2 threads and know that each will
+        consume no more than a million random numbers, create two Random
+        objects r1 and r2, then do
+            r2.setstate(r1.getstate())
+            r2.jumpahead(1000000)
+        Then r1 and r2 will use guaranteed-disjoint segments of the full
+        period.
+        """
+
+        if not n >= 0:
+            raise ValueError("n must be >= 0")
+        x, y, z = self._seed
+        x = int(x * pow(171, n, 30269)) % 30269
+        y = int(y * pow(172, n, 30307)) % 30307
+        z = int(z * pow(170, n, 30323)) % 30323
+        self._seed = x, y, z
+
+    def __whseed(self, x=0, y=0, z=0):
+        """Set the Wichmann-Hill seed from (x, y, z).
+
+        These must be integers in the range [0, 256).
+        """
+
+        if not type(x) == type(y) == type(z) == int:
+            raise TypeError('seeds must be integers')
+        if not (0 <= x < 256 and 0 <= y < 256 and 0 <= z < 256):
+            raise ValueError('seeds must be in range(0, 256)')
+        if 0 == x == y == z:
+            # Initialize from current time
+            import time
+            t = long(time.time() * 256)
+            t = int((t&0xffffff) ^ (t>>24))
+            t, x = divmod(t, 256)
+            t, y = divmod(t, 256)
+            t, z = divmod(t, 256)
+        # Zero is a poor seed, so substitute 1
+        self._seed = (x or 1, y or 1, z or 1)
+
+        self.gauss_next = None
+
+    def whseed(self, a=None):
+        """Seed from hashable object's hash code.
+
+        None or no argument seeds from current time.  It is not guaranteed
+        that objects with distinct hash codes lead to distinct internal
+        states.
+
+        This is obsolete, provided for compatibility with the seed routine
+        used prior to Python 2.1.  Use the .seed() method instead.
+        """
+
+        if a is None:
+            self.__whseed()
+            return
+        a = hash(a)
+        a, x = divmod(a, 256)
+        a, y = divmod(a, 256)
+        a, z = divmod(a, 256)
+        x = (x + a) % 256 or 1
+        y = (y + a) % 256 or 1
+        z = (z + a) % 256 or 1
+        self.__whseed(x, y, z)
+
+## --------------- Operating System Random Source  ------------------
+
+class SystemRandom(Random):
+    """Alternate random number generator using sources provided
+    by the operating system (such as /dev/urandom on Unix or
+    CryptGenRandom on Windows).
+
+     Not available on all systems (see os.urandom() for details).
+    """
+
+    def random(self):
+        """Get the next random number in the range [0.0, 1.0)."""
+        return (long(_hexlify(_urandom(7)), 16) >> 3) * RECIP_BPF
+
+    def getrandbits(self, k):
+        """getrandbits(k) -> x.  Generates a long int with k random bits."""
+        if k <= 0:
+            raise ValueError('number of bits must be greater than zero')
+        if k != int(k):
+            raise TypeError('number of bits should be an integer')
+        bytes = (k + 7) // 8                    # bits / 8 and rounded up
+        x = long(_hexlify(_urandom(bytes)), 16)
+        return x >> (bytes * 8 - k)             # trim excess bits
+
+    def _stub(self, *args, **kwds):
+        "Stub method.  Not used for a system random number generator."
+        return None
+    seed = jumpahead = _stub
+
+    def _notimplemented(self, *args, **kwds):
+        "Method should not be called for a system random number generator."
+        raise NotImplementedError('System entropy source does not have state.')
+    getstate = setstate = _notimplemented
+
+## -------------------- test program --------------------
+
+def _test_generator(n, func, args):
+    import time
+    print n, 'times', func.__name__
+    total = 0.0
+    sqsum = 0.0
+    smallest = 1e10
+    largest = -1e10
+    t0 = time.time()
+    for i in range(n):
+        x = func(*args)
+        total += x
+        sqsum = sqsum + x*x
+        smallest = min(x, smallest)
+        largest = max(x, largest)
+    t1 = time.time()
+    print round(t1-t0, 3), 'sec,',
+    avg = total/n
+    stddev = _sqrt(sqsum/n - avg*avg)
+    print 'avg %g, stddev %g, min %g, max %g' % \
+              (avg, stddev, smallest, largest)
+
+
+def _test(N=2000):
+    _test_generator(N, random, ())
+    _test_generator(N, normalvariate, (0.0, 1.0))
+    _test_generator(N, lognormvariate, (0.0, 1.0))
+    _test_generator(N, vonmisesvariate, (0.0, 1.0))
+    _test_generator(N, gammavariate, (0.01, 1.0))
+    _test_generator(N, gammavariate, (0.1, 1.0))
+    _test_generator(N, gammavariate, (0.1, 2.0))
+    _test_generator(N, gammavariate, (0.5, 1.0))
+    _test_generator(N, gammavariate, (0.9, 1.0))
+    _test_generator(N, gammavariate, (1.0, 1.0))
+    _test_generator(N, gammavariate, (2.0, 1.0))
+    _test_generator(N, gammavariate, (20.0, 1.0))
+    _test_generator(N, gammavariate, (200.0, 1.0))
+    _test_generator(N, gauss, (0.0, 1.0))
+    _test_generator(N, betavariate, (3.0, 3.0))
+
+# Create one instance, seeded from current time, and export its methods
+# as module-level functions.  The functions share state across all uses
+#(both in the user's code and in the Python libraries), but that's fine
+# for most programs and is easier for the casual user than making them
+# instantiate their own Random() instance.
+
+_inst = Random()
+seed = _inst.seed
+random = _inst.random
+uniform = _inst.uniform
+randint = _inst.randint
+choice = _inst.choice
+randrange = _inst.randrange
+sample = _inst.sample
+shuffle = _inst.shuffle
+normalvariate = _inst.normalvariate
+lognormvariate = _inst.lognormvariate
+expovariate = _inst.expovariate
+vonmisesvariate = _inst.vonmisesvariate
+gammavariate = _inst.gammavariate
+gauss = _inst.gauss
+betavariate = _inst.betavariate
+paretovariate = _inst.paretovariate
+weibullvariate = _inst.weibullvariate
+getstate = _inst.getstate
+setstate = _inst.setstate
+jumpahead = _inst.jumpahead
+getrandbits = _inst.getrandbits
+
+if __name__ == '__main__':
+    _test()

Added: vendor/Python/current/Lib/re.py
===================================================================
--- vendor/Python/current/Lib/re.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/re.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,315 @@
+#
+# Secret Labs' Regular Expression Engine
+#
+# re-compatible interface for the sre matching engine
+#
+# Copyright (c) 1998-2001 by Secret Labs AB.  All rights reserved.
+#
+# This version of the SRE library can be redistributed under CNRI's
+# Python 1.6 license.  For any other use, please contact Secret Labs
+# AB (info at pythonware.com).
+#
+# Portions of this engine have been developed in cooperation with
+# CNRI.  Hewlett-Packard provided funding for 1.6 integration and
+# other compatibility work.
+#
+
+r"""Support for regular expressions (RE).
+
+This module provides regular expression matching operations similar to
+those found in Perl.  It supports both 8-bit and Unicode strings; both
+the pattern and the strings being processed can contain null bytes and
+characters outside the US ASCII range.
+
+Regular expressions can contain both special and ordinary characters.
+Most ordinary characters, like "A", "a", or "0", are the simplest
+regular expressions; they simply match themselves.  You can
+concatenate ordinary characters, so last matches the string 'last'.
+
+The special characters are:
+    "."      Matches any character except a newline.
+    "^"      Matches the start of the string.
+    "$"      Matches the end of the string.
+    "*"      Matches 0 or more (greedy) repetitions of the preceding RE.
+             Greedy means that it will match as many repetitions as possible.
+    "+"      Matches 1 or more (greedy) repetitions of the preceding RE.
+    "?"      Matches 0 or 1 (greedy) of the preceding RE.
+    *?,+?,?? Non-greedy versions of the previous three special characters.
+    {m,n}    Matches from m to n repetitions of the preceding RE.
+    {m,n}?   Non-greedy version of the above.
+    "\\"      Either escapes special characters or signals a special sequence.
+    []       Indicates a set of characters.
+             A "^" as the first character indicates a complementing set.
+    "|"      A|B, creates an RE that will match either A or B.
+    (...)    Matches the RE inside the parentheses.
+             The contents can be retrieved or matched later in the string.
+    (?iLmsux) Set the I, L, M, S, U, or X flag for the RE (see below).
+    (?:...)  Non-grouping version of regular parentheses.
+    (?P<name>...) The substring matched by the group is accessible by name.
+    (?P=name)     Matches the text matched earlier by the group named name.
+    (?#...)  A comment; ignored.
+    (?=...)  Matches if ... matches next, but doesn't consume the string.
+    (?!...)  Matches if ... doesn't match next.
+
+The special sequences consist of "\\" and a character from the list
+below.  If the ordinary character is not on the list, then the
+resulting RE will match the second character.
+    \number  Matches the contents of the group of the same number.
+    \A       Matches only at the start of the string.
+    \Z       Matches only at the end of the string.
+    \b       Matches the empty string, but only at the start or end of a word.
+    \B       Matches the empty string, but not at the start or end of a word.
+    \d       Matches any decimal digit; equivalent to the set [0-9].
+    \D       Matches any non-digit character; equivalent to the set [^0-9].
+    \s       Matches any whitespace character; equivalent to [ \t\n\r\f\v].
+    \S       Matches any non-whitespace character; equiv. to [^ \t\n\r\f\v].
+    \w       Matches any alphanumeric character; equivalent to [a-zA-Z0-9_].
+             With LOCALE, it will match the set [0-9_] plus characters defined
+             as letters for the current locale.
+    \W       Matches the complement of \w.
+    \\       Matches a literal backslash.
+
+This module exports the following functions:
+    match    Match a regular expression pattern to the beginning of a string.
+    search   Search a string for the presence of a pattern.
+    sub      Substitute occurrences of a pattern found in a string.
+    subn     Same as sub, but also return the number of substitutions made.
+    split    Split a string by the occurrences of a pattern.
+    findall  Find all occurrences of a pattern in a string.
+    compile  Compile a pattern into a RegexObject.
+    purge    Clear the regular expression cache.
+    escape   Backslash all non-alphanumerics in a string.
+
+Some of the functions in this module takes flags as optional parameters:
+    I  IGNORECASE  Perform case-insensitive matching.
+    L  LOCALE      Make \w, \W, \b, \B, dependent on the current locale.
+    M  MULTILINE   "^" matches the beginning of lines as well as the string.
+                   "$" matches the end of lines as well as the string.
+    S  DOTALL      "." matches any character at all, including the newline.
+    X  VERBOSE     Ignore whitespace and comments for nicer looking RE's.
+    U  UNICODE     Make \w, \W, \b, \B, dependent on the Unicode locale.
+
+This module also defines an exception 'error'.
+
+"""
+
+import sys
+import sre_compile
+import sre_parse
+
+# public symbols
+__all__ = [ "match", "search", "sub", "subn", "split", "findall",
+    "compile", "purge", "template", "escape", "I", "L", "M", "S", "X",
+    "U", "IGNORECASE", "LOCALE", "MULTILINE", "DOTALL", "VERBOSE",
+    "UNICODE", "error" ]
+
+__version__ = "2.2.1"
+
+# flags
+I = IGNORECASE = sre_compile.SRE_FLAG_IGNORECASE # ignore case
+L = LOCALE = sre_compile.SRE_FLAG_LOCALE # assume current 8-bit locale
+U = UNICODE = sre_compile.SRE_FLAG_UNICODE # assume unicode locale
+M = MULTILINE = sre_compile.SRE_FLAG_MULTILINE # make anchors look for newline
+S = DOTALL = sre_compile.SRE_FLAG_DOTALL # make dot match newline
+X = VERBOSE = sre_compile.SRE_FLAG_VERBOSE # ignore whitespace and comments
+
+# sre extensions (experimental, don't rely on these)
+T = TEMPLATE = sre_compile.SRE_FLAG_TEMPLATE # disable backtracking
+DEBUG = sre_compile.SRE_FLAG_DEBUG # dump pattern after compilation
+
+# sre exception
+error = sre_compile.error
+
+# --------------------------------------------------------------------
+# public interface
+
+def match(pattern, string, flags=0):
+    """Try to apply the pattern at the start of the string, returning
+    a match object, or None if no match was found."""
+    return _compile(pattern, flags).match(string)
+
+def search(pattern, string, flags=0):
+    """Scan through string looking for a match to the pattern, returning
+    a match object, or None if no match was found."""
+    return _compile(pattern, flags).search(string)
+
+def sub(pattern, repl, string, count=0):
+    """Return the string obtained by replacing the leftmost
+    non-overlapping occurrences of the pattern in string by the
+    replacement repl.  repl can be either a string or a callable;
+    if a callable, it's passed the match object and must return
+    a replacement string to be used."""
+    return _compile(pattern, 0).sub(repl, string, count)
+
+def subn(pattern, repl, string, count=0):
+    """Return a 2-tuple containing (new_string, number).
+    new_string is the string obtained by replacing the leftmost
+    non-overlapping occurrences of the pattern in the source
+    string by the replacement repl.  number is the number of
+    substitutions that were made. repl can be either a string or a
+    callable; if a callable, it's passed the match object and must
+    return a replacement string to be used."""
+    return _compile(pattern, 0).subn(repl, string, count)
+
+def split(pattern, string, maxsplit=0):
+    """Split the source string by the occurrences of the pattern,
+    returning a list containing the resulting substrings."""
+    return _compile(pattern, 0).split(string, maxsplit)
+
+def findall(pattern, string, flags=0):
+    """Return a list of all non-overlapping matches in the string.
+
+    If one or more groups are present in the pattern, return a
+    list of groups; this will be a list of tuples if the pattern
+    has more than one group.
+
+    Empty matches are included in the result."""
+    return _compile(pattern, flags).findall(string)
+
+if sys.hexversion >= 0x02020000:
+    __all__.append("finditer")
+    def finditer(pattern, string, flags=0):
+        """Return an iterator over all non-overlapping matches in the
+        string.  For each match, the iterator returns a match object.
+
+        Empty matches are included in the result."""
+        return _compile(pattern, flags).finditer(string)
+
+def compile(pattern, flags=0):
+    "Compile a regular expression pattern, returning a pattern object."
+    return _compile(pattern, flags)
+
+def purge():
+    "Clear the regular expression cache"
+    _cache.clear()
+    _cache_repl.clear()
+
+def template(pattern, flags=0):
+    "Compile a template pattern, returning a pattern object"
+    return _compile(pattern, flags|T)
+
+_alphanum = {}
+for c in 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890':
+    _alphanum[c] = 1
+del c
+
+def escape(pattern):
+    "Escape all non-alphanumeric characters in pattern."
+    s = list(pattern)
+    alphanum = _alphanum
+    for i in range(len(pattern)):
+        c = pattern[i]
+        if c not in alphanum:
+            if c == "\000":
+                s[i] = "\\000"
+            else:
+                s[i] = "\\" + c
+    return pattern[:0].join(s)
+
+# --------------------------------------------------------------------
+# internals
+
+_cache = {}
+_cache_repl = {}
+
+_pattern_type = type(sre_compile.compile("", 0))
+
+_MAXCACHE = 100
+
+def _compile(*key):
+    # internal: compile pattern
+    cachekey = (type(key[0]),) + key
+    p = _cache.get(cachekey)
+    if p is not None:
+        return p
+    pattern, flags = key
+    if isinstance(pattern, _pattern_type):
+        return pattern
+    if not sre_compile.isstring(pattern):
+        raise TypeError, "first argument must be string or compiled pattern"
+    try:
+        p = sre_compile.compile(pattern, flags)
+    except error, v:
+        raise error, v # invalid expression
+    if len(_cache) >= _MAXCACHE:
+        _cache.clear()
+    _cache[cachekey] = p
+    return p
+
+def _compile_repl(*key):
+    # internal: compile replacement pattern
+    p = _cache_repl.get(key)
+    if p is not None:
+        return p
+    repl, pattern = key
+    try:
+        p = sre_parse.parse_template(repl, pattern)
+    except error, v:
+        raise error, v # invalid expression
+    if len(_cache_repl) >= _MAXCACHE:
+        _cache_repl.clear()
+    _cache_repl[key] = p
+    return p
+
+def _expand(pattern, match, template):
+    # internal: match.expand implementation hook
+    template = sre_parse.parse_template(template, pattern)
+    return sre_parse.expand_template(template, match)
+
+def _subx(pattern, template):
+    # internal: pattern.sub/subn implementation helper
+    template = _compile_repl(template, pattern)
+    if not template[0] and len(template[1]) == 1:
+        # literal replacement
+        return template[1][0]
+    def filter(match, template=template):
+        return sre_parse.expand_template(template, match)
+    return filter
+
+# register myself for pickling
+
+import copy_reg
+
+def _pickle(p):
+    return _compile, (p.pattern, p.flags)
+
+copy_reg.pickle(_pattern_type, _pickle, _compile)
+
+# --------------------------------------------------------------------
+# experimental stuff (see python-dev discussions for details)
+
+class Scanner:
+    def __init__(self, lexicon, flags=0):
+        from sre_constants import BRANCH, SUBPATTERN
+        self.lexicon = lexicon
+        # combine phrases into a compound pattern
+        p = []
+        s = sre_parse.Pattern()
+        s.flags = flags
+        for phrase, action in lexicon:
+            p.append(sre_parse.SubPattern(s, [
+                (SUBPATTERN, (len(p)+1, sre_parse.parse(phrase, flags))),
+                ]))
+        p = sre_parse.SubPattern(s, [(BRANCH, (None, p))])
+        s.groups = len(p)
+        self.scanner = sre_compile.compile(p)
+    def scan(self, string):
+        result = []
+        append = result.append
+        match = self.scanner.scanner(string).match
+        i = 0
+        while 1:
+            m = match()
+            if not m:
+                break
+            j = m.end()
+            if i == j:
+                break
+            action = self.lexicon[m.lastindex-1][1]
+            if callable(action):
+                self.match = m
+                action = action(self, m.group())
+            if action is not None:
+                append(action)
+            i = j
+        return result, string[i:]

Added: vendor/Python/current/Lib/repr.py
===================================================================
--- vendor/Python/current/Lib/repr.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/repr.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,122 @@
+"""Redo the `...` (representation) but with limits on most sizes."""
+
+__all__ = ["Repr","repr"]
+
+import __builtin__
+from itertools import islice
+
+class Repr:
+
+    def __init__(self):
+        self.maxlevel = 6
+        self.maxtuple = 6
+        self.maxlist = 6
+        self.maxarray = 5
+        self.maxdict = 4
+        self.maxset = 6
+        self.maxfrozenset = 6
+        self.maxdeque = 6
+        self.maxstring = 30
+        self.maxlong = 40
+        self.maxother = 20
+
+    def repr(self, x):
+        return self.repr1(x, self.maxlevel)
+
+    def repr1(self, x, level):
+        typename = type(x).__name__
+        if ' ' in typename:
+            parts = typename.split()
+            typename = '_'.join(parts)
+        if hasattr(self, 'repr_' + typename):
+            return getattr(self, 'repr_' + typename)(x, level)
+        else:
+            s = __builtin__.repr(x)
+            if len(s) > self.maxother:
+                i = max(0, (self.maxother-3)//2)
+                j = max(0, self.maxother-3-i)
+                s = s[:i] + '...' + s[len(s)-j:]
+            return s
+
+    def _repr_iterable(self, x, level, left, right, maxiter, trail=''):
+        n = len(x)
+        if level <= 0 and n:
+            s = '...'
+        else:
+            newlevel = level - 1
+            repr1 = self.repr1
+            pieces = [repr1(elem, newlevel) for elem in islice(x, maxiter)]
+            if n > maxiter:  pieces.append('...')
+            s = ', '.join(pieces)
+            if n == 1 and trail:  right = trail + right
+        return '%s%s%s' % (left, s, right)
+
+    def repr_tuple(self, x, level):
+        return self._repr_iterable(x, level, '(', ')', self.maxlist, ',')
+
+    def repr_list(self, x, level):
+        return self._repr_iterable(x, level, '[', ']', self.maxlist)
+
+    def repr_array(self, x, level):
+        header = "array('%s', [" % x.typecode
+        return self._repr_iterable(x, level, header, '])', self.maxarray)
+
+    def repr_set(self, x, level):
+        x = sorted(x)
+        return self._repr_iterable(x, level, 'set([', '])', self.maxset)
+
+    def repr_frozenset(self, x, level):
+        x = sorted(x)
+        return self._repr_iterable(x, level, 'frozenset([', '])',
+                                   self.maxfrozenset)
+
+    def repr_deque(self, x, level):
+        return self._repr_iterable(x, level, 'deque([', '])', self.maxdeque)
+
+    def repr_dict(self, x, level):
+        n = len(x)
+        if n == 0: return '{}'
+        if level <= 0: return '{...}'
+        newlevel = level - 1
+        repr1 = self.repr1
+        pieces = []
+        for key in islice(sorted(x), self.maxdict):
+            keyrepr = repr1(key, newlevel)
+            valrepr = repr1(x[key], newlevel)
+            pieces.append('%s: %s' % (keyrepr, valrepr))
+        if n > self.maxdict: pieces.append('...')
+        s = ', '.join(pieces)
+        return '{%s}' % (s,)
+
+    def repr_str(self, x, level):
+        s = __builtin__.repr(x[:self.maxstring])
+        if len(s) > self.maxstring:
+            i = max(0, (self.maxstring-3)//2)
+            j = max(0, self.maxstring-3-i)
+            s = __builtin__.repr(x[:i] + x[len(x)-j:])
+            s = s[:i] + '...' + s[len(s)-j:]
+        return s
+
+    def repr_long(self, x, level):
+        s = __builtin__.repr(x) # XXX Hope this isn't too slow...
+        if len(s) > self.maxlong:
+            i = max(0, (self.maxlong-3)//2)
+            j = max(0, self.maxlong-3-i)
+            s = s[:i] + '...' + s[len(s)-j:]
+        return s
+
+    def repr_instance(self, x, level):
+        try:
+            s = __builtin__.repr(x)
+            # Bugs in x.__repr__() can cause arbitrary
+            # exceptions -- then make up something
+        except:
+            return '<%s instance at %x>' % (x.__class__.__name__, id(x))
+        if len(s) > self.maxstring:
+            i = max(0, (self.maxstring-3)//2)
+            j = max(0, self.maxstring-3-i)
+            s = s[:i] + '...' + s[len(s)-j:]
+        return s
+
+aRepr = Repr()
+repr = aRepr.repr

Added: vendor/Python/current/Lib/rexec.py
===================================================================
--- vendor/Python/current/Lib/rexec.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/rexec.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,585 @@
+"""Restricted execution facilities.
+
+The class RExec exports methods r_exec(), r_eval(), r_execfile(), and
+r_import(), which correspond roughly to the built-in operations
+exec, eval(), execfile() and import, but executing the code in an
+environment that only exposes those built-in operations that are
+deemed safe.  To this end, a modest collection of 'fake' modules is
+created which mimics the standard modules by the same names.  It is a
+policy decision which built-in modules and operations are made
+available; this module provides a reasonable default, but derived
+classes can change the policies e.g. by overriding or extending class
+variables like ok_builtin_modules or methods like make_sys().
+
+XXX To do:
+- r_open should allow writing tmp dir
+- r_exec etc. with explicit globals/locals? (Use rexec("exec ... in ...")?)
+
+"""
+
+
+import sys
+import __builtin__
+import os
+import ihooks
+import imp
+
+__all__ = ["RExec"]
+
+class FileBase:
+
+    ok_file_methods = ('fileno', 'flush', 'isatty', 'read', 'readline',
+            'readlines', 'seek', 'tell', 'write', 'writelines', 'xreadlines',
+            '__iter__')
+
+
+class FileWrapper(FileBase):
+
+    # XXX This is just like a Bastion -- should use that!
+
+    def __init__(self, f):
+        for m in self.ok_file_methods:
+            if not hasattr(self, m) and hasattr(f, m):
+                setattr(self, m, getattr(f, m))
+
+    def close(self):
+        self.flush()
+
+
+TEMPLATE = """
+def %s(self, *args):
+        return getattr(self.mod, self.name).%s(*args)
+"""
+
+class FileDelegate(FileBase):
+
+    def __init__(self, mod, name):
+        self.mod = mod
+        self.name = name
+
+    for m in FileBase.ok_file_methods + ('close',):
+        exec TEMPLATE % (m, m)
+
+
+class RHooks(ihooks.Hooks):
+
+    def __init__(self, *args):
+        # Hacks to support both old and new interfaces:
+        # old interface was RHooks(rexec[, verbose])
+        # new interface is RHooks([verbose])
+        verbose = 0
+        rexec = None
+        if args and type(args[-1]) == type(0):
+            verbose = args[-1]
+            args = args[:-1]
+        if args and hasattr(args[0], '__class__'):
+            rexec = args[0]
+            args = args[1:]
+        if args:
+            raise TypeError, "too many arguments"
+        ihooks.Hooks.__init__(self, verbose)
+        self.rexec = rexec
+
+    def set_rexec(self, rexec):
+        # Called by RExec instance to complete initialization
+        self.rexec = rexec
+
+    def get_suffixes(self):
+        return self.rexec.get_suffixes()
+
+    def is_builtin(self, name):
+        return self.rexec.is_builtin(name)
+
+    def init_builtin(self, name):
+        m = __import__(name)
+        return self.rexec.copy_except(m, ())
+
+    def init_frozen(self, name): raise SystemError, "don't use this"
+    def load_source(self, *args): raise SystemError, "don't use this"
+    def load_compiled(self, *args): raise SystemError, "don't use this"
+    def load_package(self, *args): raise SystemError, "don't use this"
+
+    def load_dynamic(self, name, filename, file):
+        return self.rexec.load_dynamic(name, filename, file)
+
+    def add_module(self, name):
+        return self.rexec.add_module(name)
+
+    def modules_dict(self):
+        return self.rexec.modules
+
+    def default_path(self):
+        return self.rexec.modules['sys'].path
+
+
+# XXX Backwards compatibility
+RModuleLoader = ihooks.FancyModuleLoader
+RModuleImporter = ihooks.ModuleImporter
+
+
+class RExec(ihooks._Verbose):
+    """Basic restricted execution framework.
+
+    Code executed in this restricted environment will only have access to
+    modules and functions that are deemed safe; you can subclass RExec to
+    add or remove capabilities as desired.
+
+    The RExec class can prevent code from performing unsafe operations like
+    reading or writing disk files, or using TCP/IP sockets.  However, it does
+    not protect against code using extremely large amounts of memory or
+    processor time.
+
+    """
+
+    ok_path = tuple(sys.path)           # That's a policy decision
+
+    ok_builtin_modules = ('audioop', 'array', 'binascii',
+                          'cmath', 'errno', 'imageop',
+                          'marshal', 'math', 'md5', 'operator',
+                          'parser', 'select',
+                          'sha', '_sre', 'strop', 'struct', 'time',
+                          '_weakref')
+
+    ok_posix_names = ('error', 'fstat', 'listdir', 'lstat', 'readlink',
+                      'stat', 'times', 'uname', 'getpid', 'getppid',
+                      'getcwd', 'getuid', 'getgid', 'geteuid', 'getegid')
+
+    ok_sys_names = ('byteorder', 'copyright', 'exit', 'getdefaultencoding',
+                    'getrefcount', 'hexversion', 'maxint', 'maxunicode',
+                    'platform', 'ps1', 'ps2', 'version', 'version_info')
+
+    nok_builtin_names = ('open', 'file', 'reload', '__import__')
+
+    ok_file_types = (imp.C_EXTENSION, imp.PY_SOURCE)
+
+    def __init__(self, hooks = None, verbose = 0):
+        """Returns an instance of the RExec class.
+
+        The hooks parameter is an instance of the RHooks class or a subclass
+        of it.  If it is omitted or None, the default RHooks class is
+        instantiated.
+
+        Whenever the RExec module searches for a module (even a built-in one)
+        or reads a module's code, it doesn't actually go out to the file
+        system itself.  Rather, it calls methods of an RHooks instance that
+        was passed to or created by its constructor.  (Actually, the RExec
+        object doesn't make these calls --- they are made by a module loader
+        object that's part of the RExec object.  This allows another level of
+        flexibility, which can be useful when changing the mechanics of
+        import within the restricted environment.)
+
+        By providing an alternate RHooks object, we can control the file
+        system accesses made to import a module, without changing the
+        actual algorithm that controls the order in which those accesses are
+        made.  For instance, we could substitute an RHooks object that
+        passes all filesystem requests to a file server elsewhere, via some
+        RPC mechanism such as ILU.  Grail's applet loader uses this to support
+        importing applets from a URL for a directory.
+
+        If the verbose parameter is true, additional debugging output may be
+        sent to standard output.
+
+        """
+
+        raise RuntimeError, "This code is not secure in Python 2.2 and 2.3"
+
+        ihooks._Verbose.__init__(self, verbose)
+        # XXX There's a circular reference here:
+        self.hooks = hooks or RHooks(verbose)
+        self.hooks.set_rexec(self)
+        self.modules = {}
+        self.ok_dynamic_modules = self.ok_builtin_modules
+        list = []
+        for mname in self.ok_builtin_modules:
+            if mname in sys.builtin_module_names:
+                list.append(mname)
+        self.ok_builtin_modules = tuple(list)
+        self.set_trusted_path()
+        self.make_builtin()
+        self.make_initial_modules()
+        # make_sys must be last because it adds the already created
+        # modules to its builtin_module_names
+        self.make_sys()
+        self.loader = RModuleLoader(self.hooks, verbose)
+        self.importer = RModuleImporter(self.loader, verbose)
+
+    def set_trusted_path(self):
+        # Set the path from which dynamic modules may be loaded.
+        # Those dynamic modules must also occur in ok_builtin_modules
+        self.trusted_path = filter(os.path.isabs, sys.path)
+
+    def load_dynamic(self, name, filename, file):
+        if name not in self.ok_dynamic_modules:
+            raise ImportError, "untrusted dynamic module: %s" % name
+        if name in sys.modules:
+            src = sys.modules[name]
+        else:
+            src = imp.load_dynamic(name, filename, file)
+        dst = self.copy_except(src, [])
+        return dst
+
+    def make_initial_modules(self):
+        self.make_main()
+        self.make_osname()
+
+    # Helpers for RHooks
+
+    def get_suffixes(self):
+        return [item   # (suff, mode, type)
+                for item in imp.get_suffixes()
+                if item[2] in self.ok_file_types]
+
+    def is_builtin(self, mname):
+        return mname in self.ok_builtin_modules
+
+    # The make_* methods create specific built-in modules
+
+    def make_builtin(self):
+        m = self.copy_except(__builtin__, self.nok_builtin_names)
+        m.__import__ = self.r_import
+        m.reload = self.r_reload
+        m.open = m.file = self.r_open
+
+    def make_main(self):
+        m = self.add_module('__main__')
+
+    def make_osname(self):
+        osname = os.name
+        src = __import__(osname)
+        dst = self.copy_only(src, self.ok_posix_names)
+        dst.environ = e = {}
+        for key, value in os.environ.items():
+            e[key] = value
+
+    def make_sys(self):
+        m = self.copy_only(sys, self.ok_sys_names)
+        m.modules = self.modules
+        m.argv = ['RESTRICTED']
+        m.path = map(None, self.ok_path)
+        m.exc_info = self.r_exc_info
+        m = self.modules['sys']
+        l = self.modules.keys() + list(self.ok_builtin_modules)
+        l.sort()
+        m.builtin_module_names = tuple(l)
+
+    # The copy_* methods copy existing modules with some changes
+
+    def copy_except(self, src, exceptions):
+        dst = self.copy_none(src)
+        for name in dir(src):
+            setattr(dst, name, getattr(src, name))
+        for name in exceptions:
+            try:
+                delattr(dst, name)
+            except AttributeError:
+                pass
+        return dst
+
+    def copy_only(self, src, names):
+        dst = self.copy_none(src)
+        for name in names:
+            try:
+                value = getattr(src, name)
+            except AttributeError:
+                continue
+            setattr(dst, name, value)
+        return dst
+
+    def copy_none(self, src):
+        m = self.add_module(src.__name__)
+        m.__doc__ = src.__doc__
+        return m
+
+    # Add a module -- return an existing module or create one
+
+    def add_module(self, mname):
+        m = self.modules.get(mname)
+        if m is None:
+            self.modules[mname] = m = self.hooks.new_module(mname)
+        m.__builtins__ = self.modules['__builtin__']
+        return m
+
+    # The r* methods are public interfaces
+
+    def r_exec(self, code):
+        """Execute code within a restricted environment.
+
+        The code parameter must either be a string containing one or more
+        lines of Python code, or a compiled code object, which will be
+        executed in the restricted environment's __main__ module.
+
+        """
+        m = self.add_module('__main__')
+        exec code in m.__dict__
+
+    def r_eval(self, code):
+        """Evaluate code within a restricted environment.
+
+        The code parameter must either be a string containing a Python
+        expression, or a compiled code object, which will be evaluated in
+        the restricted environment's __main__ module.  The value of the
+        expression or code object will be returned.
+
+        """
+        m = self.add_module('__main__')
+        return eval(code, m.__dict__)
+
+    def r_execfile(self, file):
+        """Execute the Python code in the file in the restricted
+        environment's __main__ module.
+
+        """
+        m = self.add_module('__main__')
+        execfile(file, m.__dict__)
+
+    def r_import(self, mname, globals={}, locals={}, fromlist=[]):
+        """Import a module, raising an ImportError exception if the module
+        is considered unsafe.
+
+        This method is implicitly called by code executing in the
+        restricted environment.  Overriding this method in a subclass is
+        used to change the policies enforced by a restricted environment.
+
+        """
+        return self.importer.import_module(mname, globals, locals, fromlist)
+
+    def r_reload(self, m):
+        """Reload the module object, re-parsing and re-initializing it.
+
+        This method is implicitly called by code executing in the
+        restricted environment.  Overriding this method in a subclass is
+        used to change the policies enforced by a restricted environment.
+
+        """
+        return self.importer.reload(m)
+
+    def r_unload(self, m):
+        """Unload the module.
+
+        Removes it from the restricted environment's sys.modules dictionary.
+
+        This method is implicitly called by code executing in the
+        restricted environment.  Overriding this method in a subclass is
+        used to change the policies enforced by a restricted environment.
+
+        """
+        return self.importer.unload(m)
+
+    # The s_* methods are similar but also swap std{in,out,err}
+
+    def make_delegate_files(self):
+        s = self.modules['sys']
+        self.delegate_stdin = FileDelegate(s, 'stdin')
+        self.delegate_stdout = FileDelegate(s, 'stdout')
+        self.delegate_stderr = FileDelegate(s, 'stderr')
+        self.restricted_stdin = FileWrapper(sys.stdin)
+        self.restricted_stdout = FileWrapper(sys.stdout)
+        self.restricted_stderr = FileWrapper(sys.stderr)
+
+    def set_files(self):
+        if not hasattr(self, 'save_stdin'):
+            self.save_files()
+        if not hasattr(self, 'delegate_stdin'):
+            self.make_delegate_files()
+        s = self.modules['sys']
+        s.stdin = self.restricted_stdin
+        s.stdout = self.restricted_stdout
+        s.stderr = self.restricted_stderr
+        sys.stdin = self.delegate_stdin
+        sys.stdout = self.delegate_stdout
+        sys.stderr = self.delegate_stderr
+
+    def reset_files(self):
+        self.restore_files()
+        s = self.modules['sys']
+        self.restricted_stdin = s.stdin
+        self.restricted_stdout = s.stdout
+        self.restricted_stderr = s.stderr
+
+
+    def save_files(self):
+        self.save_stdin = sys.stdin
+        self.save_stdout = sys.stdout
+        self.save_stderr = sys.stderr
+
+    def restore_files(self):
+        sys.stdin = self.save_stdin
+        sys.stdout = self.save_stdout
+        sys.stderr = self.save_stderr
+
+    def s_apply(self, func, args=(), kw={}):
+        self.save_files()
+        try:
+            self.set_files()
+            r = func(*args, **kw)
+        finally:
+            self.restore_files()
+        return r
+
+    def s_exec(self, *args):
+        """Execute code within a restricted environment.
+
+        Similar to the r_exec() method, but the code will be granted access
+        to restricted versions of the standard I/O streams sys.stdin,
+        sys.stderr, and sys.stdout.
+
+        The code parameter must either be a string containing one or more
+        lines of Python code, or a compiled code object, which will be
+        executed in the restricted environment's __main__ module.
+
+        """
+        return self.s_apply(self.r_exec, args)
+
+    def s_eval(self, *args):
+        """Evaluate code within a restricted environment.
+
+        Similar to the r_eval() method, but the code will be granted access
+        to restricted versions of the standard I/O streams sys.stdin,
+        sys.stderr, and sys.stdout.
+
+        The code parameter must either be a string containing a Python
+        expression, or a compiled code object, which will be evaluated in
+        the restricted environment's __main__ module.  The value of the
+        expression or code object will be returned.
+
+        """
+        return self.s_apply(self.r_eval, args)
+
+    def s_execfile(self, *args):
+        """Execute the Python code in the file in the restricted
+        environment's __main__ module.
+
+        Similar to the r_execfile() method, but the code will be granted
+        access to restricted versions of the standard I/O streams sys.stdin,
+        sys.stderr, and sys.stdout.
+
+        """
+        return self.s_apply(self.r_execfile, args)
+
+    def s_import(self, *args):
+        """Import a module, raising an ImportError exception if the module
+        is considered unsafe.
+
+        This method is implicitly called by code executing in the
+        restricted environment.  Overriding this method in a subclass is
+        used to change the policies enforced by a restricted environment.
+
+        Similar to the r_import() method, but has access to restricted
+        versions of the standard I/O streams sys.stdin, sys.stderr, and
+        sys.stdout.
+
+        """
+        return self.s_apply(self.r_import, args)
+
+    def s_reload(self, *args):
+        """Reload the module object, re-parsing and re-initializing it.
+
+        This method is implicitly called by code executing in the
+        restricted environment.  Overriding this method in a subclass is
+        used to change the policies enforced by a restricted environment.
+
+        Similar to the r_reload() method, but has access to restricted
+        versions of the standard I/O streams sys.stdin, sys.stderr, and
+        sys.stdout.
+
+        """
+        return self.s_apply(self.r_reload, args)
+
+    def s_unload(self, *args):
+        """Unload the module.
+
+        Removes it from the restricted environment's sys.modules dictionary.
+
+        This method is implicitly called by code executing in the
+        restricted environment.  Overriding this method in a subclass is
+        used to change the policies enforced by a restricted environment.
+
+        Similar to the r_unload() method, but has access to restricted
+        versions of the standard I/O streams sys.stdin, sys.stderr, and
+        sys.stdout.
+
+        """
+        return self.s_apply(self.r_unload, args)
+
+    # Restricted open(...)
+
+    def r_open(self, file, mode='r', buf=-1):
+        """Method called when open() is called in the restricted environment.
+
+        The arguments are identical to those of the open() function, and a
+        file object (or a class instance compatible with file objects)
+        should be returned.  RExec's default behaviour is allow opening
+        any file for reading, but forbidding any attempt to write a file.
+
+        This method is implicitly called by code executing in the
+        restricted environment.  Overriding this method in a subclass is
+        used to change the policies enforced by a restricted environment.
+
+        """
+        mode = str(mode)
+        if mode not in ('r', 'rb'):
+            raise IOError, "can't open files for writing in restricted mode"
+        return open(file, mode, buf)
+
+    # Restricted version of sys.exc_info()
+
+    def r_exc_info(self):
+        ty, va, tr = sys.exc_info()
+        tr = None
+        return ty, va, tr
+
+
+def test():
+    import getopt, traceback
+    opts, args = getopt.getopt(sys.argv[1:], 'vt:')
+    verbose = 0
+    trusted = []
+    for o, a in opts:
+        if o == '-v':
+            verbose = verbose+1
+        if o == '-t':
+            trusted.append(a)
+    r = RExec(verbose=verbose)
+    if trusted:
+        r.ok_builtin_modules = r.ok_builtin_modules + tuple(trusted)
+    if args:
+        r.modules['sys'].argv = args
+        r.modules['sys'].path.insert(0, os.path.dirname(args[0]))
+    else:
+        r.modules['sys'].path.insert(0, "")
+    fp = sys.stdin
+    if args and args[0] != '-':
+        try:
+            fp = open(args[0])
+        except IOError, msg:
+            print "%s: can't open file %r" % (sys.argv[0], args[0])
+            return 1
+    if fp.isatty():
+        try:
+            import readline
+        except ImportError:
+            pass
+        import code
+        class RestrictedConsole(code.InteractiveConsole):
+            def runcode(self, co):
+                self.locals['__builtins__'] = r.modules['__builtin__']
+                r.s_apply(code.InteractiveConsole.runcode, (self, co))
+        try:
+            RestrictedConsole(r.modules['__main__'].__dict__).interact()
+        except SystemExit, n:
+            return n
+    else:
+        text = fp.read()
+        fp.close()
+        c = compile(text, fp.name, 'exec')
+        try:
+            r.s_exec(c)
+        except SystemExit, n:
+            return n
+        except:
+            traceback.print_exc()
+            return 1
+
+
+if __name__ == '__main__':
+    sys.exit(test())

Added: vendor/Python/current/Lib/rfc822.py
===================================================================
--- vendor/Python/current/Lib/rfc822.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/rfc822.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1007 @@
+"""RFC 2822 message manipulation.
+
+Note: This is only a very rough sketch of a full RFC-822 parser; in particular
+the tokenizing of addresses does not adhere to all the quoting rules.
+
+Note: RFC 2822 is a long awaited update to RFC 822.  This module should
+conform to RFC 2822, and is thus mis-named (it's not worth renaming it).  Some
+effort at RFC 2822 updates have been made, but a thorough audit has not been
+performed.  Consider any RFC 2822 non-conformance to be a bug.
+
+    RFC 2822: http://www.faqs.org/rfcs/rfc2822.html
+    RFC 822 : http://www.faqs.org/rfcs/rfc822.html (obsolete)
+
+Directions for use:
+
+To create a Message object: first open a file, e.g.:
+
+  fp = open(file, 'r')
+
+You can use any other legal way of getting an open file object, e.g. use
+sys.stdin or call os.popen().  Then pass the open file object to the Message()
+constructor:
+
+  m = Message(fp)
+
+This class can work with any input object that supports a readline method.  If
+the input object has seek and tell capability, the rewindbody method will
+work; also illegal lines will be pushed back onto the input stream.  If the
+input object lacks seek but has an `unread' method that can push back a line
+of input, Message will use that to push back illegal lines.  Thus this class
+can be used to parse messages coming from a buffered stream.
+
+The optional `seekable' argument is provided as a workaround for certain stdio
+libraries in which tell() discards buffered data before discovering that the
+lseek() system call doesn't work.  For maximum portability, you should set the
+seekable argument to zero to prevent that initial \code{tell} when passing in
+an unseekable object such as a a file object created from a socket object.  If
+it is 1 on entry -- which it is by default -- the tell() method of the open
+file object is called once; if this raises an exception, seekable is reset to
+0.  For other nonzero values of seekable, this test is not made.
+
+To get the text of a particular header there are several methods:
+
+  str = m.getheader(name)
+  str = m.getrawheader(name)
+
+where name is the name of the header, e.g. 'Subject'.  The difference is that
+getheader() strips the leading and trailing whitespace, while getrawheader()
+doesn't.  Both functions retain embedded whitespace (including newlines)
+exactly as they are specified in the header, and leave the case of the text
+unchanged.
+
+For addresses and address lists there are functions
+
+  realname, mailaddress = m.getaddr(name)
+  list = m.getaddrlist(name)
+
+where the latter returns a list of (realname, mailaddr) tuples.
+
+There is also a method
+
+  time = m.getdate(name)
+
+which parses a Date-like field and returns a time-compatible tuple,
+i.e. a tuple such as returned by time.localtime() or accepted by
+time.mktime().
+
+See the class definition for lower level access methods.
+
+There are also some utility functions here.
+"""
+# Cleanup and extensions by Eric S. Raymond <esr at thyrsus.com>
+
+import time
+
+__all__ = ["Message","AddressList","parsedate","parsedate_tz","mktime_tz"]
+
+_blanklines = ('\r\n', '\n')            # Optimization for islast()
+
+
+class Message:
+    """Represents a single RFC 2822-compliant message."""
+
+    def __init__(self, fp, seekable = 1):
+        """Initialize the class instance and read the headers."""
+        if seekable == 1:
+            # Exercise tell() to make sure it works
+            # (and then assume seek() works, too)
+            try:
+                fp.tell()
+            except (AttributeError, IOError):
+                seekable = 0
+        self.fp = fp
+        self.seekable = seekable
+        self.startofheaders = None
+        self.startofbody = None
+        #
+        if self.seekable:
+            try:
+                self.startofheaders = self.fp.tell()
+            except IOError:
+                self.seekable = 0
+        #
+        self.readheaders()
+        #
+        if self.seekable:
+            try:
+                self.startofbody = self.fp.tell()
+            except IOError:
+                self.seekable = 0
+
+    def rewindbody(self):
+        """Rewind the file to the start of the body (if seekable)."""
+        if not self.seekable:
+            raise IOError, "unseekable file"
+        self.fp.seek(self.startofbody)
+
+    def readheaders(self):
+        """Read header lines.
+
+        Read header lines up to the entirely blank line that terminates them.
+        The (normally blank) line that ends the headers is skipped, but not
+        included in the returned list.  If a non-header line ends the headers,
+        (which is an error), an attempt is made to backspace over it; it is
+        never included in the returned list.
+
+        The variable self.status is set to the empty string if all went well,
+        otherwise it is an error message.  The variable self.headers is a
+        completely uninterpreted list of lines contained in the header (so
+        printing them will reproduce the header exactly as it appears in the
+        file).
+        """
+        self.dict = {}
+        self.unixfrom = ''
+        self.headers = lst = []
+        self.status = ''
+        headerseen = ""
+        firstline = 1
+        startofline = unread = tell = None
+        if hasattr(self.fp, 'unread'):
+            unread = self.fp.unread
+        elif self.seekable:
+            tell = self.fp.tell
+        while 1:
+            if tell:
+                try:
+                    startofline = tell()
+                except IOError:
+                    startofline = tell = None
+                    self.seekable = 0
+            line = self.fp.readline()
+            if not line:
+                self.status = 'EOF in headers'
+                break
+            # Skip unix From name time lines
+            if firstline and line.startswith('From '):
+                self.unixfrom = self.unixfrom + line
+                continue
+            firstline = 0
+            if headerseen and line[0] in ' \t':
+                # It's a continuation line.
+                lst.append(line)
+                x = (self.dict[headerseen] + "\n " + line.strip())
+                self.dict[headerseen] = x.strip()
+                continue
+            elif self.iscomment(line):
+                # It's a comment.  Ignore it.
+                continue
+            elif self.islast(line):
+                # Note! No pushback here!  The delimiter line gets eaten.
+                break
+            headerseen = self.isheader(line)
+            if headerseen:
+                # It's a legal header line, save it.
+                lst.append(line)
+                self.dict[headerseen] = line[len(headerseen)+1:].strip()
+                continue
+            else:
+                # It's not a header line; throw it back and stop here.
+                if not self.dict:
+                    self.status = 'No headers'
+                else:
+                    self.status = 'Non-header line where header expected'
+                # Try to undo the read.
+                if unread:
+                    unread(line)
+                elif tell:
+                    self.fp.seek(startofline)
+                else:
+                    self.status = self.status + '; bad seek'
+                break
+
+    def isheader(self, line):
+        """Determine whether a given line is a legal header.
+
+        This method should return the header name, suitably canonicalized.
+        You may override this method in order to use Message parsing on tagged
+        data in RFC 2822-like formats with special header formats.
+        """
+        i = line.find(':')
+        if i > 0:
+            return line[:i].lower()
+        return None
+
+    def islast(self, line):
+        """Determine whether a line is a legal end of RFC 2822 headers.
+
+        You may override this method if your application wants to bend the
+        rules, e.g. to strip trailing whitespace, or to recognize MH template
+        separators ('--------').  For convenience (e.g. for code reading from
+        sockets) a line consisting of \r\n also matches.
+        """
+        return line in _blanklines
+
+    def iscomment(self, line):
+        """Determine whether a line should be skipped entirely.
+
+        You may override this method in order to use Message parsing on tagged
+        data in RFC 2822-like formats that support embedded comments or
+        free-text data.
+        """
+        return False
+
+    def getallmatchingheaders(self, name):
+        """Find all header lines matching a given header name.
+
+        Look through the list of headers and find all lines matching a given
+        header name (and their continuation lines).  A list of the lines is
+        returned, without interpretation.  If the header does not occur, an
+        empty list is returned.  If the header occurs multiple times, all
+        occurrences are returned.  Case is not important in the header name.
+        """
+        name = name.lower() + ':'
+        n = len(name)
+        lst = []
+        hit = 0
+        for line in self.headers:
+            if line[:n].lower() == name:
+                hit = 1
+            elif not line[:1].isspace():
+                hit = 0
+            if hit:
+                lst.append(line)
+        return lst
+
+    def getfirstmatchingheader(self, name):
+        """Get the first header line matching name.
+
+        This is similar to getallmatchingheaders, but it returns only the
+        first matching header (and its continuation lines).
+        """
+        name = name.lower() + ':'
+        n = len(name)
+        lst = []
+        hit = 0
+        for line in self.headers:
+            if hit:
+                if not line[:1].isspace():
+                    break
+            elif line[:n].lower() == name:
+                hit = 1
+            if hit:
+                lst.append(line)
+        return lst
+
+    def getrawheader(self, name):
+        """A higher-level interface to getfirstmatchingheader().
+
+        Return a string containing the literal text of the header but with the
+        keyword stripped.  All leading, trailing and embedded whitespace is
+        kept in the string, however.  Return None if the header does not
+        occur.
+        """
+
+        lst = self.getfirstmatchingheader(name)
+        if not lst:
+            return None
+        lst[0] = lst[0][len(name) + 1:]
+        return ''.join(lst)
+
+    def getheader(self, name, default=None):
+        """Get the header value for a name.
+
+        This is the normal interface: it returns a stripped version of the
+        header value for a given header name, or None if it doesn't exist.
+        This uses the dictionary version which finds the *last* such header.
+        """
+        return self.dict.get(name.lower(), default)
+    get = getheader
+
+    def getheaders(self, name):
+        """Get all values for a header.
+
+        This returns a list of values for headers given more than once; each
+        value in the result list is stripped in the same way as the result of
+        getheader().  If the header is not given, return an empty list.
+        """
+        result = []
+        current = ''
+        have_header = 0
+        for s in self.getallmatchingheaders(name):
+            if s[0].isspace():
+                if current:
+                    current = "%s\n %s" % (current, s.strip())
+                else:
+                    current = s.strip()
+            else:
+                if have_header:
+                    result.append(current)
+                current = s[s.find(":") + 1:].strip()
+                have_header = 1
+        if have_header:
+            result.append(current)
+        return result
+
+    def getaddr(self, name):
+        """Get a single address from a header, as a tuple.
+
+        An example return value:
+        ('Guido van Rossum', 'guido at cwi.nl')
+        """
+        # New, by Ben Escoto
+        alist = self.getaddrlist(name)
+        if alist:
+            return alist[0]
+        else:
+            return (None, None)
+
+    def getaddrlist(self, name):
+        """Get a list of addresses from a header.
+
+        Retrieves a list of addresses from a header, where each address is a
+        tuple as returned by getaddr().  Scans all named headers, so it works
+        properly with multiple To: or Cc: headers for example.
+        """
+        raw = []
+        for h in self.getallmatchingheaders(name):
+            if h[0] in ' \t':
+                raw.append(h)
+            else:
+                if raw:
+                    raw.append(', ')
+                i = h.find(':')
+                if i > 0:
+                    addr = h[i+1:]
+                raw.append(addr)
+        alladdrs = ''.join(raw)
+        a = AddressList(alladdrs)
+        return a.addresslist
+
+    def getdate(self, name):
+        """Retrieve a date field from a header.
+
+        Retrieves a date field from the named header, returning a tuple
+        compatible with time.mktime().
+        """
+        try:
+            data = self[name]
+        except KeyError:
+            return None
+        return parsedate(data)
+
+    def getdate_tz(self, name):
+        """Retrieve a date field from a header as a 10-tuple.
+
+        The first 9 elements make up a tuple compatible with time.mktime(),
+        and the 10th is the offset of the poster's time zone from GMT/UTC.
+        """
+        try:
+            data = self[name]
+        except KeyError:
+            return None
+        return parsedate_tz(data)
+
+
+    # Access as a dictionary (only finds *last* header of each type):
+
+    def __len__(self):
+        """Get the number of headers in a message."""
+        return len(self.dict)
+
+    def __getitem__(self, name):
+        """Get a specific header, as from a dictionary."""
+        return self.dict[name.lower()]
+
+    def __setitem__(self, name, value):
+        """Set the value of a header.
+
+        Note: This is not a perfect inversion of __getitem__, because any
+        changed headers get stuck at the end of the raw-headers list rather
+        than where the altered header was.
+        """
+        del self[name] # Won't fail if it doesn't exist
+        self.dict[name.lower()] = value
+        text = name + ": " + value
+        for line in text.split("\n"):
+            self.headers.append(line + "\n")
+
+    def __delitem__(self, name):
+        """Delete all occurrences of a specific header, if it is present."""
+        name = name.lower()
+        if not name in self.dict:
+            return
+        del self.dict[name]
+        name = name + ':'
+        n = len(name)
+        lst = []
+        hit = 0
+        for i in range(len(self.headers)):
+            line = self.headers[i]
+            if line[:n].lower() == name:
+                hit = 1
+            elif not line[:1].isspace():
+                hit = 0
+            if hit:
+                lst.append(i)
+        for i in reversed(lst):
+            del self.headers[i]
+
+    def setdefault(self, name, default=""):
+        lowername = name.lower()
+        if lowername in self.dict:
+            return self.dict[lowername]
+        else:
+            text = name + ": " + default
+            for line in text.split("\n"):
+                self.headers.append(line + "\n")
+            self.dict[lowername] = default
+            return default
+
+    def has_key(self, name):
+        """Determine whether a message contains the named header."""
+        return name.lower() in self.dict
+
+    def __contains__(self, name):
+        """Determine whether a message contains the named header."""
+        return name.lower() in self.dict
+
+    def __iter__(self):
+        return iter(self.dict)
+
+    def keys(self):
+        """Get all of a message's header field names."""
+        return self.dict.keys()
+
+    def values(self):
+        """Get all of a message's header field values."""
+        return self.dict.values()
+
+    def items(self):
+        """Get all of a message's headers.
+
+        Returns a list of name, value tuples.
+        """
+        return self.dict.items()
+
+    def __str__(self):
+        return ''.join(self.headers)
+
+
+# Utility functions
+# -----------------
+
+# XXX Should fix unquote() and quote() to be really conformant.
+# XXX The inverses of the parse functions may also be useful.
+
+
+def unquote(s):
+    """Remove quotes from a string."""
+    if len(s) > 1:
+        if s.startswith('"') and s.endswith('"'):
+            return s[1:-1].replace('\\\\', '\\').replace('\\"', '"')
+        if s.startswith('<') and s.endswith('>'):
+            return s[1:-1]
+    return s
+
+
+def quote(s):
+    """Add quotes around a string."""
+    return s.replace('\\', '\\\\').replace('"', '\\"')
+
+
+def parseaddr(address):
+    """Parse an address into a (realname, mailaddr) tuple."""
+    a = AddressList(address)
+    lst = a.addresslist
+    if not lst:
+        return (None, None)
+    return lst[0]
+
+
+class AddrlistClass:
+    """Address parser class by Ben Escoto.
+
+    To understand what this class does, it helps to have a copy of
+    RFC 2822 in front of you.
+
+    http://www.faqs.org/rfcs/rfc2822.html
+
+    Note: this class interface is deprecated and may be removed in the future.
+    Use rfc822.AddressList instead.
+    """
+
+    def __init__(self, field):
+        """Initialize a new instance.
+
+        `field' is an unparsed address header field, containing one or more
+        addresses.
+        """
+        self.specials = '()<>@,:;.\"[]'
+        self.pos = 0
+        self.LWS = ' \t'
+        self.CR = '\r\n'
+        self.atomends = self.specials + self.LWS + self.CR
+        # Note that RFC 2822 now specifies `.' as obs-phrase, meaning that it
+        # is obsolete syntax.  RFC 2822 requires that we recognize obsolete
+        # syntax, so allow dots in phrases.
+        self.phraseends = self.atomends.replace('.', '')
+        self.field = field
+        self.commentlist = []
+
+    def gotonext(self):
+        """Parse up to the start of the next address."""
+        while self.pos < len(self.field):
+            if self.field[self.pos] in self.LWS + '\n\r':
+                self.pos = self.pos + 1
+            elif self.field[self.pos] == '(':
+                self.commentlist.append(self.getcomment())
+            else: break
+
+    def getaddrlist(self):
+        """Parse all addresses.
+
+        Returns a list containing all of the addresses.
+        """
+        result = []
+        ad = self.getaddress()
+        while ad:
+            result += ad
+            ad = self.getaddress()
+        return result
+
+    def getaddress(self):
+        """Parse the next address."""
+        self.commentlist = []
+        self.gotonext()
+
+        oldpos = self.pos
+        oldcl = self.commentlist
+        plist = self.getphraselist()
+
+        self.gotonext()
+        returnlist = []
+
+        if self.pos >= len(self.field):
+            # Bad email address technically, no domain.
+            if plist:
+                returnlist = [(' '.join(self.commentlist), plist[0])]
+
+        elif self.field[self.pos] in '.@':
+            # email address is just an addrspec
+            # this isn't very efficient since we start over
+            self.pos = oldpos
+            self.commentlist = oldcl
+            addrspec = self.getaddrspec()
+            returnlist = [(' '.join(self.commentlist), addrspec)]
+
+        elif self.field[self.pos] == ':':
+            # address is a group
+            returnlist = []
+
+            fieldlen = len(self.field)
+            self.pos += 1
+            while self.pos < len(self.field):
+                self.gotonext()
+                if self.pos < fieldlen and self.field[self.pos] == ';':
+                    self.pos += 1
+                    break
+                returnlist = returnlist + self.getaddress()
+
+        elif self.field[self.pos] == '<':
+            # Address is a phrase then a route addr
+            routeaddr = self.getrouteaddr()
+
+            if self.commentlist:
+                returnlist = [(' '.join(plist) + ' (' + \
+                         ' '.join(self.commentlist) + ')', routeaddr)]
+            else: returnlist = [(' '.join(plist), routeaddr)]
+
+        else:
+            if plist:
+                returnlist = [(' '.join(self.commentlist), plist[0])]
+            elif self.field[self.pos] in self.specials:
+                self.pos += 1
+
+        self.gotonext()
+        if self.pos < len(self.field) and self.field[self.pos] == ',':
+            self.pos += 1
+        return returnlist
+
+    def getrouteaddr(self):
+        """Parse a route address (Return-path value).
+
+        This method just skips all the route stuff and returns the addrspec.
+        """
+        if self.field[self.pos] != '<':
+            return
+
+        expectroute = 0
+        self.pos += 1
+        self.gotonext()
+        adlist = ""
+        while self.pos < len(self.field):
+            if expectroute:
+                self.getdomain()
+                expectroute = 0
+            elif self.field[self.pos] == '>':
+                self.pos += 1
+                break
+            elif self.field[self.pos] == '@':
+                self.pos += 1
+                expectroute = 1
+            elif self.field[self.pos] == ':':
+                self.pos += 1
+            else:
+                adlist = self.getaddrspec()
+                self.pos += 1
+                break
+            self.gotonext()
+
+        return adlist
+
+    def getaddrspec(self):
+        """Parse an RFC 2822 addr-spec."""
+        aslist = []
+
+        self.gotonext()
+        while self.pos < len(self.field):
+            if self.field[self.pos] == '.':
+                aslist.append('.')
+                self.pos += 1
+            elif self.field[self.pos] == '"':
+                aslist.append('"%s"' % self.getquote())
+            elif self.field[self.pos] in self.atomends:
+                break
+            else: aslist.append(self.getatom())
+            self.gotonext()
+
+        if self.pos >= len(self.field) or self.field[self.pos] != '@':
+            return ''.join(aslist)
+
+        aslist.append('@')
+        self.pos += 1
+        self.gotonext()
+        return ''.join(aslist) + self.getdomain()
+
+    def getdomain(self):
+        """Get the complete domain name from an address."""
+        sdlist = []
+        while self.pos < len(self.field):
+            if self.field[self.pos] in self.LWS:
+                self.pos += 1
+            elif self.field[self.pos] == '(':
+                self.commentlist.append(self.getcomment())
+            elif self.field[self.pos] == '[':
+                sdlist.append(self.getdomainliteral())
+            elif self.field[self.pos] == '.':
+                self.pos += 1
+                sdlist.append('.')
+            elif self.field[self.pos] in self.atomends:
+                break
+            else: sdlist.append(self.getatom())
+        return ''.join(sdlist)
+
+    def getdelimited(self, beginchar, endchars, allowcomments = 1):
+        """Parse a header fragment delimited by special characters.
+
+        `beginchar' is the start character for the fragment.  If self is not
+        looking at an instance of `beginchar' then getdelimited returns the
+        empty string.
+
+        `endchars' is a sequence of allowable end-delimiting characters.
+        Parsing stops when one of these is encountered.
+
+        If `allowcomments' is non-zero, embedded RFC 2822 comments are allowed
+        within the parsed fragment.
+        """
+        if self.field[self.pos] != beginchar:
+            return ''
+
+        slist = ['']
+        quote = 0
+        self.pos += 1
+        while self.pos < len(self.field):
+            if quote == 1:
+                slist.append(self.field[self.pos])
+                quote = 0
+            elif self.field[self.pos] in endchars:
+                self.pos += 1
+                break
+            elif allowcomments and self.field[self.pos] == '(':
+                slist.append(self.getcomment())
+                continue        # have already advanced pos from getcomment
+            elif self.field[self.pos] == '\\':
+                quote = 1
+            else:
+                slist.append(self.field[self.pos])
+            self.pos += 1
+
+        return ''.join(slist)
+
+    def getquote(self):
+        """Get a quote-delimited fragment from self's field."""
+        return self.getdelimited('"', '"\r', 0)
+
+    def getcomment(self):
+        """Get a parenthesis-delimited fragment from self's field."""
+        return self.getdelimited('(', ')\r', 1)
+
+    def getdomainliteral(self):
+        """Parse an RFC 2822 domain-literal."""
+        return '[%s]' % self.getdelimited('[', ']\r', 0)
+
+    def getatom(self, atomends=None):
+        """Parse an RFC 2822 atom.
+
+        Optional atomends specifies a different set of end token delimiters
+        (the default is to use self.atomends).  This is used e.g. in
+        getphraselist() since phrase endings must not include the `.' (which
+        is legal in phrases)."""
+        atomlist = ['']
+        if atomends is None:
+            atomends = self.atomends
+
+        while self.pos < len(self.field):
+            if self.field[self.pos] in atomends:
+                break
+            else: atomlist.append(self.field[self.pos])
+            self.pos += 1
+
+        return ''.join(atomlist)
+
+    def getphraselist(self):
+        """Parse a sequence of RFC 2822 phrases.
+
+        A phrase is a sequence of words, which are in turn either RFC 2822
+        atoms or quoted-strings.  Phrases are canonicalized by squeezing all
+        runs of continuous whitespace into one space.
+        """
+        plist = []
+
+        while self.pos < len(self.field):
+            if self.field[self.pos] in self.LWS:
+                self.pos += 1
+            elif self.field[self.pos] == '"':
+                plist.append(self.getquote())
+            elif self.field[self.pos] == '(':
+                self.commentlist.append(self.getcomment())
+            elif self.field[self.pos] in self.phraseends:
+                break
+            else:
+                plist.append(self.getatom(self.phraseends))
+
+        return plist
+
+class AddressList(AddrlistClass):
+    """An AddressList encapsulates a list of parsed RFC 2822 addresses."""
+    def __init__(self, field):
+        AddrlistClass.__init__(self, field)
+        if field:
+            self.addresslist = self.getaddrlist()
+        else:
+            self.addresslist = []
+
+    def __len__(self):
+        return len(self.addresslist)
+
+    def __str__(self):
+        return ", ".join(map(dump_address_pair, self.addresslist))
+
+    def __add__(self, other):
+        # Set union
+        newaddr = AddressList(None)
+        newaddr.addresslist = self.addresslist[:]
+        for x in other.addresslist:
+            if not x in self.addresslist:
+                newaddr.addresslist.append(x)
+        return newaddr
+
+    def __iadd__(self, other):
+        # Set union, in-place
+        for x in other.addresslist:
+            if not x in self.addresslist:
+                self.addresslist.append(x)
+        return self
+
+    def __sub__(self, other):
+        # Set difference
+        newaddr = AddressList(None)
+        for x in self.addresslist:
+            if not x in other.addresslist:
+                newaddr.addresslist.append(x)
+        return newaddr
+
+    def __isub__(self, other):
+        # Set difference, in-place
+        for x in other.addresslist:
+            if x in self.addresslist:
+                self.addresslist.remove(x)
+        return self
+
+    def __getitem__(self, index):
+        # Make indexing, slices, and 'in' work
+        return self.addresslist[index]
+
+def dump_address_pair(pair):
+    """Dump a (name, address) pair in a canonicalized form."""
+    if pair[0]:
+        return '"' + pair[0] + '" <' + pair[1] + '>'
+    else:
+        return pair[1]
+
+# Parse a date field
+
+_monthnames = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul',
+               'aug', 'sep', 'oct', 'nov', 'dec',
+               'january', 'february', 'march', 'april', 'may', 'june', 'july',
+               'august', 'september', 'october', 'november', 'december']
+_daynames = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun']
+
+# The timezone table does not include the military time zones defined
+# in RFC822, other than Z.  According to RFC1123, the description in
+# RFC822 gets the signs wrong, so we can't rely on any such time
+# zones.  RFC1123 recommends that numeric timezone indicators be used
+# instead of timezone names.
+
+_timezones = {'UT':0, 'UTC':0, 'GMT':0, 'Z':0,
+              'AST': -400, 'ADT': -300,  # Atlantic (used in Canada)
+              'EST': -500, 'EDT': -400,  # Eastern
+              'CST': -600, 'CDT': -500,  # Central
+              'MST': -700, 'MDT': -600,  # Mountain
+              'PST': -800, 'PDT': -700   # Pacific
+              }
+
+
+def parsedate_tz(data):
+    """Convert a date string to a time tuple.
+
+    Accounts for military timezones.
+    """
+    if not data:
+        return None
+    data = data.split()
+    if data[0][-1] in (',', '.') or data[0].lower() in _daynames:
+        # There's a dayname here. Skip it
+        del data[0]
+    else:
+        # no space after the "weekday,"?
+        i = data[0].rfind(',')
+        if i >= 0:
+            data[0] = data[0][i+1:]
+    if len(data) == 3: # RFC 850 date, deprecated
+        stuff = data[0].split('-')
+        if len(stuff) == 3:
+            data = stuff + data[1:]
+    if len(data) == 4:
+        s = data[3]
+        i = s.find('+')
+        if i > 0:
+            data[3:] = [s[:i], s[i+1:]]
+        else:
+            data.append('') # Dummy tz
+    if len(data) < 5:
+        return None
+    data = data[:5]
+    [dd, mm, yy, tm, tz] = data
+    mm = mm.lower()
+    if not mm in _monthnames:
+        dd, mm = mm, dd.lower()
+        if not mm in _monthnames:
+            return None
+    mm = _monthnames.index(mm)+1
+    if mm > 12: mm = mm - 12
+    if dd[-1] == ',':
+        dd = dd[:-1]
+    i = yy.find(':')
+    if i > 0:
+        yy, tm = tm, yy
+    if yy[-1] == ',':
+        yy = yy[:-1]
+    if not yy[0].isdigit():
+        yy, tz = tz, yy
+    if tm[-1] == ',':
+        tm = tm[:-1]
+    tm = tm.split(':')
+    if len(tm) == 2:
+        [thh, tmm] = tm
+        tss = '0'
+    elif len(tm) == 3:
+        [thh, tmm, tss] = tm
+    else:
+        return None
+    try:
+        yy = int(yy)
+        dd = int(dd)
+        thh = int(thh)
+        tmm = int(tmm)
+        tss = int(tss)
+    except ValueError:
+        return None
+    tzoffset = None
+    tz = tz.upper()
+    if tz in _timezones:
+        tzoffset = _timezones[tz]
+    else:
+        try:
+            tzoffset = int(tz)
+        except ValueError:
+            pass
+    # Convert a timezone offset into seconds ; -0500 -> -18000
+    if tzoffset:
+        if tzoffset < 0:
+            tzsign = -1
+            tzoffset = -tzoffset
+        else:
+            tzsign = 1
+        tzoffset = tzsign * ( (tzoffset//100)*3600 + (tzoffset % 100)*60)
+    return (yy, mm, dd, thh, tmm, tss, 0, 1, 0, tzoffset)
+
+
+def parsedate(data):
+    """Convert a time string to a time tuple."""
+    t = parsedate_tz(data)
+    if t is None:
+        return t
+    return t[:9]
+
+
+def mktime_tz(data):
+    """Turn a 10-tuple as returned by parsedate_tz() into a UTC timestamp."""
+    if data[9] is None:
+        # No zone info, so localtime is better assumption than GMT
+        return time.mktime(data[:8] + (-1,))
+    else:
+        t = time.mktime(data[:8] + (0,))
+        return t - data[9] - time.timezone
+
+def formatdate(timeval=None):
+    """Returns time format preferred for Internet standards.
+
+    Sun, 06 Nov 1994 08:49:37 GMT  ; RFC 822, updated by RFC 1123
+
+    According to RFC 1123, day and month names must always be in
+    English.  If not for that, this code could use strftime().  It
+    can't because strftime() honors the locale and could generated
+    non-English names.
+    """
+    if timeval is None:
+        timeval = time.time()
+    timeval = time.gmtime(timeval)
+    return "%s, %02d %s %04d %02d:%02d:%02d GMT" % (
+            ("Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun")[timeval[6]],
+            timeval[2],
+            ("Jan", "Feb", "Mar", "Apr", "May", "Jun",
+             "Jul", "Aug", "Sep", "Oct", "Nov", "Dec")[timeval[1]-1],
+                                timeval[0], timeval[3], timeval[4], timeval[5])
+
+
+# When used as script, run a small test program.
+# The first command line argument must be a filename containing one
+# message in RFC-822 format.
+
+if __name__ == '__main__':
+    import sys, os
+    file = os.path.join(os.environ['HOME'], 'Mail/inbox/1')
+    if sys.argv[1:]: file = sys.argv[1]
+    f = open(file, 'r')
+    m = Message(f)
+    print 'From:', m.getaddr('from')
+    print 'To:', m.getaddrlist('to')
+    print 'Subject:', m.getheader('subject')
+    print 'Date:', m.getheader('date')
+    date = m.getdate_tz('date')
+    tz = date[-1]
+    date = time.localtime(mktime_tz(date))
+    if date:
+        print 'ParsedDate:', time.asctime(date),
+        hhmmss = tz
+        hhmm, ss = divmod(hhmmss, 60)
+        hh, mm = divmod(hhmm, 60)
+        print "%+03d%02d" % (hh, mm),
+        if ss: print ".%02d" % ss,
+        print
+    else:
+        print 'ParsedDate:', None
+    m.rewindbody()
+    n = 0
+    while f.readline():
+        n += 1
+    print 'Lines:', n
+    print '-'*70
+    print 'len =', len(m)
+    if 'Date' in m: print 'Date =', m['Date']
+    if 'X-Nonsense' in m: pass
+    print 'keys =', m.keys()
+    print 'values =', m.values()
+    print 'items =', m.items()

Added: vendor/Python/current/Lib/rlcompleter.py
===================================================================
--- vendor/Python/current/Lib/rlcompleter.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/rlcompleter.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,154 @@
+"""Word completion for GNU readline 2.0.
+
+This requires the latest extension to the readline module. The completer
+completes keywords, built-ins and globals in a selectable namespace (which
+defaults to __main__); when completing NAME.NAME..., it evaluates (!) the
+expression up to the last dot and completes its attributes.
+
+It's very cool to do "import sys" type "sys.", hit the
+completion key (twice), and see the list of names defined by the
+sys module!
+
+Tip: to use the tab key as the completion key, call
+
+    readline.parse_and_bind("tab: complete")
+
+Notes:
+
+- Exceptions raised by the completer function are *ignored* (and
+generally cause the completion to fail).  This is a feature -- since
+readline sets the tty device in raw (or cbreak) mode, printing a
+traceback wouldn't work well without some complicated hoopla to save,
+reset and restore the tty state.
+
+- The evaluation of the NAME.NAME... form may cause arbitrary
+application defined code to be executed if an object with a
+__getattr__ hook is found.  Since it is the responsibility of the
+application (or the user) to enable this feature, I consider this an
+acceptable risk.  More complicated expressions (e.g. function calls or
+indexing operations) are *not* evaluated.
+
+- GNU readline is also used by the built-in functions input() and
+raw_input(), and thus these also benefit/suffer from the completer
+features.  Clearly an interactive application can benefit by
+specifying its own completer function and using raw_input() for all
+its input.
+
+- When the original stdin is not a tty device, GNU readline is never
+used, and this module (and the readline module) are silently inactive.
+
+"""
+
+import __builtin__
+import __main__
+
+__all__ = ["Completer"]
+
+class Completer:
+    def __init__(self, namespace = None):
+        """Create a new completer for the command line.
+
+        Completer([namespace]) -> completer instance.
+
+        If unspecified, the default namespace where completions are performed
+        is __main__ (technically, __main__.__dict__). Namespaces should be
+        given as dictionaries.
+
+        Completer instances should be used as the completion mechanism of
+        readline via the set_completer() call:
+
+        readline.set_completer(Completer(my_namespace).complete)
+        """
+
+        if namespace and not isinstance(namespace, dict):
+            raise TypeError,'namespace must be a dictionary'
+
+        # Don't bind to namespace quite yet, but flag whether the user wants a
+        # specific namespace or to use __main__.__dict__. This will allow us
+        # to bind to __main__.__dict__ at completion time, not now.
+        if namespace is None:
+            self.use_main_ns = 1
+        else:
+            self.use_main_ns = 0
+            self.namespace = namespace
+
+    def complete(self, text, state):
+        """Return the next possible completion for 'text'.
+
+        This is called successively with state == 0, 1, 2, ... until it
+        returns None.  The completion should begin with 'text'.
+
+        """
+        if self.use_main_ns:
+            self.namespace = __main__.__dict__
+
+        if state == 0:
+            if "." in text:
+                self.matches = self.attr_matches(text)
+            else:
+                self.matches = self.global_matches(text)
+        try:
+            return self.matches[state]
+        except IndexError:
+            return None
+
+    def global_matches(self, text):
+        """Compute matches when text is a simple name.
+
+        Return a list of all keywords, built-in functions and names currently
+        defined in self.namespace that match.
+
+        """
+        import keyword
+        matches = []
+        n = len(text)
+        for list in [keyword.kwlist,
+                     __builtin__.__dict__,
+                     self.namespace]:
+            for word in list:
+                if word[:n] == text and word != "__builtins__":
+                    matches.append(word)
+        return matches
+
+    def attr_matches(self, text):
+        """Compute matches when text contains a dot.
+
+        Assuming the text is of the form NAME.NAME....[NAME], and is
+        evaluatable in self.namespace, it will be evaluated and its attributes
+        (as revealed by dir()) are used as possible completions.  (For class
+        instances, class members are also considered.)
+
+        WARNING: this can still invoke arbitrary C code, if an object
+        with a __getattr__ hook is evaluated.
+
+        """
+        import re
+        m = re.match(r"(\w+(\.\w+)*)\.(\w*)", text)
+        if not m:
+            return
+        expr, attr = m.group(1, 3)
+        object = eval(expr, self.namespace)
+        words = dir(object)
+        if hasattr(object,'__class__'):
+            words.append('__class__')
+            words = words + get_class_members(object.__class__)
+        matches = []
+        n = len(attr)
+        for word in words:
+            if word[:n] == attr and word != "__builtins__":
+                matches.append("%s.%s" % (expr, word))
+        return matches
+
+def get_class_members(klass):
+    ret = dir(klass)
+    if hasattr(klass,'__bases__'):
+        for base in klass.__bases__:
+            ret = ret + get_class_members(base)
+    return ret
+
+try:
+    import readline
+except ImportError:
+    pass
+else:
+    readline.set_completer(Completer().complete)

Added: vendor/Python/current/Lib/robotparser.py
===================================================================
--- vendor/Python/current/Lib/robotparser.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/robotparser.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,292 @@
+""" robotparser.py
+
+    Copyright (C) 2000  Bastian Kleineidam
+
+    You can choose between two licenses when using this package:
+    1) GNU GPLv2
+    2) PSF license for Python 2.2
+
+    The robots.txt Exclusion Protocol is implemented as specified in
+    http://info.webcrawler.com/mak/projects/robots/norobots-rfc.html
+"""
+import urlparse,urllib
+
+__all__ = ["RobotFileParser"]
+
+debug = 0
+
+def _debug(msg):
+    if debug: print msg
+
+
+class RobotFileParser:
+    """ This class provides a set of methods to read, parse and answer
+    questions about a single robots.txt file.
+
+    """
+
+    def __init__(self, url=''):
+        self.entries = []
+        self.default_entry = None
+        self.disallow_all = False
+        self.allow_all = False
+        self.set_url(url)
+        self.last_checked = 0
+
+    def mtime(self):
+        """Returns the time the robots.txt file was last fetched.
+
+        This is useful for long-running web spiders that need to
+        check for new robots.txt files periodically.
+
+        """
+        return self.last_checked
+
+    def modified(self):
+        """Sets the time the robots.txt file was last fetched to the
+        current time.
+
+        """
+        import time
+        self.last_checked = time.time()
+
+    def set_url(self, url):
+        """Sets the URL referring to a robots.txt file."""
+        self.url = url
+        self.host, self.path = urlparse.urlparse(url)[1:3]
+
+    def read(self):
+        """Reads the robots.txt URL and feeds it to the parser."""
+        opener = URLopener()
+        f = opener.open(self.url)
+        lines = []
+        line = f.readline()
+        while line:
+            lines.append(line.strip())
+            line = f.readline()
+        self.errcode = opener.errcode
+        if self.errcode == 401 or self.errcode == 403:
+            self.disallow_all = True
+            _debug("disallow all")
+        elif self.errcode >= 400:
+            self.allow_all = True
+            _debug("allow all")
+        elif self.errcode == 200 and lines:
+            _debug("parse lines")
+            self.parse(lines)
+
+    def _add_entry(self, entry):
+        if "*" in entry.useragents:
+            # the default entry is considered last
+            self.default_entry = entry
+        else:
+            self.entries.append(entry)
+
+    def parse(self, lines):
+        """parse the input lines from a robots.txt file.
+           We allow that a user-agent: line is not preceded by
+           one or more blank lines."""
+        state = 0
+        linenumber = 0
+        entry = Entry()
+
+        for line in lines:
+            linenumber = linenumber + 1
+            if not line:
+                if state==1:
+                    _debug("line %d: warning: you should insert"
+                           " allow: or disallow: directives below any"
+                           " user-agent: line" % linenumber)
+                    entry = Entry()
+                    state = 0
+                elif state==2:
+                    self._add_entry(entry)
+                    entry = Entry()
+                    state = 0
+            # remove optional comment and strip line
+            i = line.find('#')
+            if i>=0:
+                line = line[:i]
+            line = line.strip()
+            if not line:
+                continue
+            line = line.split(':', 1)
+            if len(line) == 2:
+                line[0] = line[0].strip().lower()
+                line[1] = urllib.unquote(line[1].strip())
+                if line[0] == "user-agent":
+                    if state==2:
+                        _debug("line %d: warning: you should insert a blank"
+                               " line before any user-agent"
+                               " directive" % linenumber)
+                        self._add_entry(entry)
+                        entry = Entry()
+                    entry.useragents.append(line[1])
+                    state = 1
+                elif line[0] == "disallow":
+                    if state==0:
+                        _debug("line %d: error: you must insert a user-agent:"
+                               " directive before this line" % linenumber)
+                    else:
+                        entry.rulelines.append(RuleLine(line[1], False))
+                        state = 2
+                elif line[0] == "allow":
+                    if state==0:
+                        _debug("line %d: error: you must insert a user-agent:"
+                               " directive before this line" % linenumber)
+                    else:
+                        entry.rulelines.append(RuleLine(line[1], True))
+                else:
+                    _debug("line %d: warning: unknown key %s" % (linenumber,
+                               line[0]))
+            else:
+                _debug("line %d: error: malformed line %s"%(linenumber, line))
+        if state==2:
+            self.entries.append(entry)
+        _debug("Parsed rules:\n%s" % str(self))
+
+
+    def can_fetch(self, useragent, url):
+        """using the parsed robots.txt decide if useragent can fetch url"""
+        _debug("Checking robots.txt allowance for:\n  user agent: %s\n  url: %s" %
+               (useragent, url))
+        if self.disallow_all:
+            return False
+        if self.allow_all:
+            return True
+        # search for given user agent matches
+        # the first match counts
+        url = urllib.quote(urlparse.urlparse(urllib.unquote(url))[2]) or "/"
+        for entry in self.entries:
+            if entry.applies_to(useragent):
+                return entry.allowance(url)
+        # try the default entry last
+        if self.default_entry:
+            return self.default_entry.allowance(url)
+        # agent not found ==> access granted
+        return True
+
+
+    def __str__(self):
+        ret = ""
+        for entry in self.entries:
+            ret = ret + str(entry) + "\n"
+        return ret
+
+
+class RuleLine:
+    """A rule line is a single "Allow:" (allowance==True) or "Disallow:"
+       (allowance==False) followed by a path."""
+    def __init__(self, path, allowance):
+        if path == '' and not allowance:
+            # an empty value means allow all
+            allowance = True
+        self.path = urllib.quote(path)
+        self.allowance = allowance
+
+    def applies_to(self, filename):
+        return self.path=="*" or filename.startswith(self.path)
+
+    def __str__(self):
+        return (self.allowance and "Allow" or "Disallow")+": "+self.path
+
+
+class Entry:
+    """An entry has one or more user-agents and zero or more rulelines"""
+    def __init__(self):
+        self.useragents = []
+        self.rulelines = []
+
+    def __str__(self):
+        ret = ""
+        for agent in self.useragents:
+            ret = ret + "User-agent: "+agent+"\n"
+        for line in self.rulelines:
+            ret = ret + str(line) + "\n"
+        return ret
+
+    def applies_to(self, useragent):
+        """check if this entry applies to the specified agent"""
+        # split the name token and make it lower case
+        useragent = useragent.split("/")[0].lower()
+        for agent in self.useragents:
+            if agent=='*':
+                # we have the catch-all agent
+                return True
+            agent = agent.lower()
+            if agent in useragent:
+                return True
+        return False
+
+    def allowance(self, filename):
+        """Preconditions:
+        - our agent applies to this entry
+        - filename is URL decoded"""
+        for line in self.rulelines:
+            _debug((filename, str(line), line.allowance))
+            if line.applies_to(filename):
+                return line.allowance
+        return True
+
+class URLopener(urllib.FancyURLopener):
+    def __init__(self, *args):
+        urllib.FancyURLopener.__init__(self, *args)
+        self.errcode = 200
+
+    def http_error_default(self, url, fp, errcode, errmsg, headers):
+        self.errcode = errcode
+        return urllib.FancyURLopener.http_error_default(self, url, fp, errcode,
+                                                        errmsg, headers)
+
+def _check(a,b):
+    if not b:
+        ac = "access denied"
+    else:
+        ac = "access allowed"
+    if a!=b:
+        print "failed"
+    else:
+        print "ok (%s)" % ac
+    print
+
+def _test():
+    global debug
+    rp = RobotFileParser()
+    debug = 1
+
+    # robots.txt that exists, gotten to by redirection
+    rp.set_url('http://www.musi-cal.com/robots.txt')
+    rp.read()
+
+    # test for re.escape
+    _check(rp.can_fetch('*', 'http://www.musi-cal.com/'), 1)
+    # this should match the first rule, which is a disallow
+    _check(rp.can_fetch('', 'http://www.musi-cal.com/'), 0)
+    # various cherry pickers
+    _check(rp.can_fetch('CherryPickerSE',
+                       'http://www.musi-cal.com/cgi-bin/event-search'
+                       '?city=San+Francisco'), 0)
+    _check(rp.can_fetch('CherryPickerSE/1.0',
+                       'http://www.musi-cal.com/cgi-bin/event-search'
+                       '?city=San+Francisco'), 0)
+    _check(rp.can_fetch('CherryPickerSE/1.5',
+                       'http://www.musi-cal.com/cgi-bin/event-search'
+                       '?city=San+Francisco'), 0)
+    # case sensitivity
+    _check(rp.can_fetch('ExtractorPro', 'http://www.musi-cal.com/blubba'), 0)
+    _check(rp.can_fetch('extractorpro', 'http://www.musi-cal.com/blubba'), 0)
+    # substring test
+    _check(rp.can_fetch('toolpak/1.1', 'http://www.musi-cal.com/blubba'), 0)
+    # tests for catch-all * agent
+    _check(rp.can_fetch('spam', 'http://www.musi-cal.com/search'), 0)
+    _check(rp.can_fetch('spam', 'http://www.musi-cal.com/Musician/me'), 1)
+    _check(rp.can_fetch('spam', 'http://www.musi-cal.com/'), 1)
+    _check(rp.can_fetch('spam', 'http://www.musi-cal.com/'), 1)
+
+    # robots.txt that does not exist
+    rp.set_url('http://www.lycos.com/robots.txt')
+    rp.read()
+    _check(rp.can_fetch('Mozilla', 'http://www.lycos.com/search'), 1)
+
+if __name__ == '__main__':
+    _test()

Added: vendor/Python/current/Lib/runpy.py
===================================================================
--- vendor/Python/current/Lib/runpy.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/runpy.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,104 @@
+"""runpy.py - locating and running Python code using the module namespace
+
+Provides support for locating and running Python scripts using the Python
+module namespace instead of the native filesystem.
+
+This allows Python code to play nicely with non-filesystem based PEP 302
+importers when locating support scripts as well as when importing modules.
+"""
+# Written by Nick Coghlan <ncoghlan at gmail.com>
+#    to implement PEP 338 (Executing Modules as Scripts)
+
+import sys
+import imp
+try:
+    from imp import get_loader
+except ImportError:
+    from pkgutil import get_loader
+
+__all__ = [
+    "run_module",
+]
+
+
+def _run_code(code, run_globals, init_globals,
+              mod_name, mod_fname, mod_loader):
+    """Helper for _run_module_code"""
+    if init_globals is not None:
+        run_globals.update(init_globals)
+    run_globals.update(__name__ = mod_name,
+                       __file__ = mod_fname,
+                       __loader__ = mod_loader)
+    exec code in run_globals
+    return run_globals
+
+def _run_module_code(code, init_globals=None,
+                    mod_name=None, mod_fname=None,
+                    mod_loader=None, alter_sys=False):
+    """Helper for run_module"""
+    # Set up the top level namespace dictionary
+    if alter_sys:
+        # Modify sys.argv[0] and sys.module[mod_name]
+        temp_module = imp.new_module(mod_name)
+        mod_globals = temp_module.__dict__
+        saved_argv0 = sys.argv[0]
+        restore_module = mod_name in sys.modules
+        if restore_module:
+            saved_module = sys.modules[mod_name]
+        sys.argv[0] = mod_fname
+        sys.modules[mod_name] = temp_module
+        try:
+            _run_code(code, mod_globals, init_globals,
+                      mod_name, mod_fname, mod_loader)
+        finally:
+            sys.argv[0] = saved_argv0
+        if restore_module:
+            sys.modules[mod_name] = saved_module
+        else:
+            del sys.modules[mod_name]
+        # Copy the globals of the temporary module, as they
+        # may be cleared when the temporary module goes away
+        return mod_globals.copy()
+    else:
+        # Leave the sys module alone
+        return _run_code(code, {}, init_globals,
+                         mod_name, mod_fname, mod_loader)
+
+
+# This helper is needed due to a missing component in the PEP 302
+# loader protocol (specifically, "get_filename" is non-standard)
+def _get_filename(loader, mod_name):
+    try:
+        get_filename = loader.get_filename
+    except AttributeError:
+        return None
+    else:
+        return get_filename(mod_name)
+
+
+def run_module(mod_name, init_globals=None,
+                         run_name=None, alter_sys=False):
+    """Execute a module's code without importing it
+
+       Returns the resulting top level namespace dictionary
+    """
+    loader = get_loader(mod_name)
+    if loader is None:
+        raise ImportError("No module named " + mod_name)
+    code = loader.get_code(mod_name)
+    if code is None:
+        raise ImportError("No code object available for " + mod_name)
+    filename = _get_filename(loader, mod_name)
+    if run_name is None:
+        run_name = mod_name
+    return _run_module_code(code, init_globals, run_name,
+                            filename, loader, alter_sys)
+
+
+if __name__ == "__main__":
+    # Run the module specified as the next command line argument
+    if len(sys.argv) < 2:
+        print >> sys.stderr, "No module specified for execution"
+    else:
+        del sys.argv[0] # Make the requested module sys.argv[0]
+        run_module(sys.argv[0], run_name="__main__", alter_sys=True)


Property changes on: vendor/Python/current/Lib/runpy.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/sched.py
===================================================================
--- vendor/Python/current/Lib/sched.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/sched.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,117 @@
+"""A generally useful event scheduler class.
+
+Each instance of this class manages its own queue.
+No multi-threading is implied; you are supposed to hack that
+yourself, or use a single instance per application.
+
+Each instance is parametrized with two functions, one that is
+supposed to return the current time, one that is supposed to
+implement a delay.  You can implement real-time scheduling by
+substituting time and sleep from built-in module time, or you can
+implement simulated time by writing your own functions.  This can
+also be used to integrate scheduling with STDWIN events; the delay
+function is allowed to modify the queue.  Time can be expressed as
+integers or floating point numbers, as long as it is consistent.
+
+Events are specified by tuples (time, priority, action, argument).
+As in UNIX, lower priority numbers mean higher priority; in this
+way the queue can be maintained as a priority queue.  Execution of the
+event means calling the action function, passing it the argument.
+Remember that in Python, multiple function arguments can be packed
+in a tuple.   The action function may be an instance method so it
+has another way to reference private data (besides global variables).
+Parameterless functions or methods cannot be used, however.
+"""
+
+# XXX The timefunc and delayfunc should have been defined as methods
+# XXX so you can define new kinds of schedulers using subclassing
+# XXX instead of having to define a module or class just to hold
+# XXX the global state of your particular time and delay functions.
+
+import heapq
+
+__all__ = ["scheduler"]
+
+class scheduler:
+    def __init__(self, timefunc, delayfunc):
+        """Initialize a new instance, passing the time and delay
+        functions"""
+        self.queue = []
+        self.timefunc = timefunc
+        self.delayfunc = delayfunc
+
+    def enterabs(self, time, priority, action, argument):
+        """Enter a new event in the queue at an absolute time.
+
+        Returns an ID for the event which can be used to remove it,
+        if necessary.
+
+        """
+        event = time, priority, action, argument
+        heapq.heappush(self.queue, event)
+        return event # The ID
+
+    def enter(self, delay, priority, action, argument):
+        """A variant that specifies the time as a relative time.
+
+        This is actually the more commonly used interface.
+
+        """
+        time = self.timefunc() + delay
+        return self.enterabs(time, priority, action, argument)
+
+    def cancel(self, event):
+        """Remove an event from the queue.
+
+        This must be presented the ID as returned by enter().
+        If the event is not in the queue, this raises RuntimeError.
+
+        """
+        self.queue.remove(event)
+        heapq.heapify(self.queue)
+
+    def empty(self):
+        """Check whether the queue is empty."""
+        return not self.queue
+
+    def run(self):
+        """Execute events until the queue is empty.
+
+        When there is a positive delay until the first event, the
+        delay function is called and the event is left in the queue;
+        otherwise, the event is removed from the queue and executed
+        (its action function is called, passing it the argument).  If
+        the delay function returns prematurely, it is simply
+        restarted.
+
+        It is legal for both the delay function and the action
+        function to to modify the queue or to raise an exception;
+        exceptions are not caught but the scheduler's state remains
+        well-defined so run() may be called again.
+
+        A questionably hack is added to allow other threads to run:
+        just after an event is executed, a delay of 0 is executed, to
+        avoid monopolizing the CPU when other threads are also
+        runnable.
+
+        """
+        # localize variable access to minimize overhead
+        # and to improve thread safety
+        q = self.queue
+        delayfunc = self.delayfunc
+        timefunc = self.timefunc
+        pop = heapq.heappop
+        while q:
+            time, priority, action, argument = checked_event = q[0]
+            now = timefunc()
+            if now < time:
+                delayfunc(time - now)
+            else:
+                event = pop(q)
+                # Verify that the event was not removed or altered
+                # by another thread after we last looked at q[0].
+                if event is checked_event:
+                    void = action(*argument)
+                    delayfunc(0)   # Let other threads run
+                else:
+                    heapq.heappush(event)

Added: vendor/Python/current/Lib/sets.py
===================================================================
--- vendor/Python/current/Lib/sets.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/sets.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,577 @@
+"""Classes to represent arbitrary sets (including sets of sets).
+
+This module implements sets using dictionaries whose values are
+ignored.  The usual operations (union, intersection, deletion, etc.)
+are provided as both methods and operators.
+
+Important: sets are not sequences!  While they support 'x in s',
+'len(s)', and 'for x in s', none of those operations are unique for
+sequences; for example, mappings support all three as well.  The
+characteristic operation for sequences is subscripting with small
+integers: s[i], for i in range(len(s)).  Sets don't support
+subscripting at all.  Also, sequences allow multiple occurrences and
+their elements have a definite order; sets on the other hand don't
+record multiple occurrences and don't remember the order of element
+insertion (which is why they don't support s[i]).
+
+The following classes are provided:
+
+BaseSet -- All the operations common to both mutable and immutable
+    sets. This is an abstract class, not meant to be directly
+    instantiated.
+
+Set -- Mutable sets, subclass of BaseSet; not hashable.
+
+ImmutableSet -- Immutable sets, subclass of BaseSet; hashable.
+    An iterable argument is mandatory to create an ImmutableSet.
+
+_TemporarilyImmutableSet -- A wrapper around a Set, hashable,
+    giving the same hash value as the immutable set equivalent
+    would have.  Do not use this class directly.
+
+Only hashable objects can be added to a Set. In particular, you cannot
+really add a Set as an element to another Set; if you try, what is
+actually added is an ImmutableSet built from it (it compares equal to
+the one you tried adding).
+
+When you ask if `x in y' where x is a Set and y is a Set or
+ImmutableSet, x is wrapped into a _TemporarilyImmutableSet z, and
+what's tested is actually `z in y'.
+
+"""
+
+# Code history:
+#
+# - Greg V. Wilson wrote the first version, using a different approach
+#   to the mutable/immutable problem, and inheriting from dict.
+#
+# - Alex Martelli modified Greg's version to implement the current
+#   Set/ImmutableSet approach, and make the data an attribute.
+#
+# - Guido van Rossum rewrote much of the code, made some API changes,
+#   and cleaned up the docstrings.
+#
+# - Raymond Hettinger added a number of speedups and other
+#   improvements.
+
+from __future__ import generators
+try:
+    from itertools import ifilter, ifilterfalse
+except ImportError:
+    # Code to make the module run under Py2.2
+    def ifilter(predicate, iterable):
+        if predicate is None:
+            def predicate(x):
+                return x
+        for x in iterable:
+            if predicate(x):
+                yield x
+    def ifilterfalse(predicate, iterable):
+        if predicate is None:
+            def predicate(x):
+                return x
+        for x in iterable:
+            if not predicate(x):
+                yield x
+    try:
+        True, False
+    except NameError:
+        True, False = (0==0, 0!=0)
+
+__all__ = ['BaseSet', 'Set', 'ImmutableSet']
+
+class BaseSet(object):
+    """Common base class for mutable and immutable sets."""
+
+    __slots__ = ['_data']
+
+    # Constructor
+
+    def __init__(self):
+        """This is an abstract class."""
+        # Don't call this from a concrete subclass!
+        if self.__class__ is BaseSet:
+            raise TypeError, ("BaseSet is an abstract class.  "
+                              "Use Set or ImmutableSet.")
+
+    # Standard protocols: __len__, __repr__, __str__, __iter__
+
+    def __len__(self):
+        """Return the number of elements of a set."""
+        return len(self._data)
+
+    def __repr__(self):
+        """Return string representation of a set.
+
+        This looks like 'Set([<list of elements>])'.
+        """
+        return self._repr()
+
+    # __str__ is the same as __repr__
+    __str__ = __repr__
+
+    def _repr(self, sorted=False):
+        elements = self._data.keys()
+        if sorted:
+            elements.sort()
+        return '%s(%r)' % (self.__class__.__name__, elements)
+
+    def __iter__(self):
+        """Return an iterator over the elements or a set.
+
+        This is the keys iterator for the underlying dict.
+        """
+        return self._data.iterkeys()
+
+    # Three-way comparison is not supported.  However, because __eq__ is
+    # tried before __cmp__, if Set x == Set y, x.__eq__(y) returns True and
+    # then cmp(x, y) returns 0 (Python doesn't actually call __cmp__ in this
+    # case).
+
+    def __cmp__(self, other):
+        raise TypeError, "can't compare sets using cmp()"
+
+    # Equality comparisons using the underlying dicts.  Mixed-type comparisons
+    # are allowed here, where Set == z for non-Set z always returns False,
+    # and Set != z always True.  This allows expressions like "x in y" to
+    # give the expected result when y is a sequence of mixed types, not
+    # raising a pointless TypeError just because y contains a Set, or x is
+    # a Set and y contain's a non-set ("in" invokes only __eq__).
+    # Subtle:  it would be nicer if __eq__ and __ne__ could return
+    # NotImplemented instead of True or False.  Then the other comparand
+    # would get a chance to determine the result, and if the other comparand
+    # also returned NotImplemented then it would fall back to object address
+    # comparison (which would always return False for __eq__ and always
+    # True for __ne__).  However, that doesn't work, because this type
+    # *also* implements __cmp__:  if, e.g., __eq__ returns NotImplemented,
+    # Python tries __cmp__ next, and the __cmp__ here then raises TypeError.
+
+    def __eq__(self, other):
+        if isinstance(other, BaseSet):
+            return self._data == other._data
+        else:
+            return False
+
+    def __ne__(self, other):
+        if isinstance(other, BaseSet):
+            return self._data != other._data
+        else:
+            return True
+
+    # Copying operations
+
+    def copy(self):
+        """Return a shallow copy of a set."""
+        result = self.__class__()
+        result._data.update(self._data)
+        return result
+
+    __copy__ = copy # For the copy module
+
+    def __deepcopy__(self, memo):
+        """Return a deep copy of a set; used by copy module."""
+        # This pre-creates the result and inserts it in the memo
+        # early, in case the deep copy recurses into another reference
+        # to this same set.  A set can't be an element of itself, but
+        # it can certainly contain an object that has a reference to
+        # itself.
+        from copy import deepcopy
+        result = self.__class__()
+        memo[id(self)] = result
+        data = result._data
+        value = True
+        for elt in self:
+            data[deepcopy(elt, memo)] = value
+        return result
+
+    # Standard set operations: union, intersection, both differences.
+    # Each has an operator version (e.g. __or__, invoked with |) and a
+    # method version (e.g. union).
+    # Subtle:  Each pair requires distinct code so that the outcome is
+    # correct when the type of other isn't suitable.  For example, if
+    # we did "union = __or__" instead, then Set().union(3) would return
+    # NotImplemented instead of raising TypeError (albeit that *why* it
+    # raises TypeError as-is is also a bit subtle).
+
+    def __or__(self, other):
+        """Return the union of two sets as a new set.
+
+        (I.e. all elements that are in either set.)
+        """
+        if not isinstance(other, BaseSet):
+            return NotImplemented
+        return self.union(other)
+
+    def union(self, other):
+        """Return the union of two sets as a new set.
+
+        (I.e. all elements that are in either set.)
+        """
+        result = self.__class__(self)
+        result._update(other)
+        return result
+
+    def __and__(self, other):
+        """Return the intersection of two sets as a new set.
+
+        (I.e. all elements that are in both sets.)
+        """
+        if not isinstance(other, BaseSet):
+            return NotImplemented
+        return self.intersection(other)
+
+    def intersection(self, other):
+        """Return the intersection of two sets as a new set.
+
+        (I.e. all elements that are in both sets.)
+        """
+        if not isinstance(other, BaseSet):
+            other = Set(other)
+        if len(self) <= len(other):
+            little, big = self, other
+        else:
+            little, big = other, self
+        common = ifilter(big._data.has_key, little)
+        return self.__class__(common)
+
+    def __xor__(self, other):
+        """Return the symmetric difference of two sets as a new set.
+
+        (I.e. all elements that are in exactly one of the sets.)
+        """
+        if not isinstance(other, BaseSet):
+            return NotImplemented
+        return self.symmetric_difference(other)
+
+    def symmetric_difference(self, other):
+        """Return the symmetric difference of two sets as a new set.
+
+        (I.e. all elements that are in exactly one of the sets.)
+        """
+        result = self.__class__()
+        data = result._data
+        value = True
+        selfdata = self._data
+        try:
+            otherdata = other._data
+        except AttributeError:
+            otherdata = Set(other)._data
+        for elt in ifilterfalse(otherdata.has_key, selfdata):
+            data[elt] = value
+        for elt in ifilterfalse(selfdata.has_key, otherdata):
+            data[elt] = value
+        return result
+
+    def  __sub__(self, other):
+        """Return the difference of two sets as a new Set.
+
+        (I.e. all elements that are in this set and not in the other.)
+        """
+        if not isinstance(other, BaseSet):
+            return NotImplemented
+        return self.difference(other)
+
+    def difference(self, other):
+        """Return the difference of two sets as a new Set.
+
+        (I.e. all elements that are in this set and not in the other.)
+        """
+        result = self.__class__()
+        data = result._data
+        try:
+            otherdata = other._data
+        except AttributeError:
+            otherdata = Set(other)._data
+        value = True
+        for elt in ifilterfalse(otherdata.has_key, self):
+            data[elt] = value
+        return result
+
+    # Membership test
+
+    def __contains__(self, element):
+        """Report whether an element is a member of a set.
+
+        (Called in response to the expression `element in self'.)
+        """
+        try:
+            return element in self._data
+        except TypeError:
+            transform = getattr(element, "__as_temporarily_immutable__", None)
+            if transform is None:
+                raise # re-raise the TypeError exception we caught
+            return transform() in self._data
+
+    # Subset and superset test
+
+    def issubset(self, other):
+        """Report whether another set contains this set."""
+        self._binary_sanity_check(other)
+        if len(self) > len(other):  # Fast check for obvious cases
+            return False
+        for elt in ifilterfalse(other._data.has_key, self):
+            return False
+        return True
+
+    def issuperset(self, other):
+        """Report whether this set contains another set."""
+        self._binary_sanity_check(other)
+        if len(self) < len(other):  # Fast check for obvious cases
+            return False
+        for elt in ifilterfalse(self._data.has_key, other):
+            return False
+        return True
+
+    # Inequality comparisons using the is-subset relation.
+    __le__ = issubset
+    __ge__ = issuperset
+
+    def __lt__(self, other):
+        self._binary_sanity_check(other)
+        return len(self) < len(other) and self.issubset(other)
+
+    def __gt__(self, other):
+        self._binary_sanity_check(other)
+        return len(self) > len(other) and self.issuperset(other)
+
+    # Assorted helpers
+
+    def _binary_sanity_check(self, other):
+        # Check that the other argument to a binary operation is also
+        # a set, raising a TypeError otherwise.
+        if not isinstance(other, BaseSet):
+            raise TypeError, "Binary operation only permitted between sets"
+
+    def _compute_hash(self):
+        # Calculate hash code for a set by xor'ing the hash codes of
+        # the elements.  This ensures that the hash code does not depend
+        # on the order in which elements are added to the set.  This is
+        # not called __hash__ because a BaseSet should not be hashable;
+        # only an ImmutableSet is hashable.
+        result = 0
+        for elt in self:
+            result ^= hash(elt)
+        return result
+
+    def _update(self, iterable):
+        # The main loop for update() and the subclass __init__() methods.
+        data = self._data
+
+        # Use the fast update() method when a dictionary is available.
+        if isinstance(iterable, BaseSet):
+            data.update(iterable._data)
+            return
+
+        value = True
+
+        if type(iterable) in (list, tuple, xrange):
+            # Optimized: we know that __iter__() and next() can't
+            # raise TypeError, so we can move 'try:' out of the loop.
+            it = iter(iterable)
+            while True:
+                try:
+                    for element in it:
+                        data[element] = value
+                    return
+                except TypeError:
+                    transform = getattr(element, "__as_immutable__", None)
+                    if transform is None:
+                        raise # re-raise the TypeError exception we caught
+                    data[transform()] = value
+        else:
+            # Safe: only catch TypeError where intended
+            for element in iterable:
+                try:
+                    data[element] = value
+                except TypeError:
+                    transform = getattr(element, "__as_immutable__", None)
+                    if transform is None:
+                        raise # re-raise the TypeError exception we caught
+                    data[transform()] = value
+
+
+class ImmutableSet(BaseSet):
+    """Immutable set class."""
+
+    __slots__ = ['_hashcode']
+
+    # BaseSet + hashing
+
+    def __init__(self, iterable=None):
+        """Construct an immutable set from an optional iterable."""
+        self._hashcode = None
+        self._data = {}
+        if iterable is not None:
+            self._update(iterable)
+
+    def __hash__(self):
+        if self._hashcode is None:
+            self._hashcode = self._compute_hash()
+        return self._hashcode
+
+    def __getstate__(self):
+        return self._data, self._hashcode
+
+    def __setstate__(self, state):
+        self._data, self._hashcode = state
+
+class Set(BaseSet):
+    """ Mutable set class."""
+
+    __slots__ = []
+
+    # BaseSet + operations requiring mutability; no hashing
+
+    def __init__(self, iterable=None):
+        """Construct a set from an optional iterable."""
+        self._data = {}
+        if iterable is not None:
+            self._update(iterable)
+
+    def __getstate__(self):
+        # getstate's results are ignored if it is not
+        return self._data,
+
+    def __setstate__(self, data):
+        self._data, = data
+
+    def __hash__(self):
+        """A Set cannot be hashed."""
+        # We inherit object.__hash__, so we must deny this explicitly
+        raise TypeError, "Can't hash a Set, only an ImmutableSet."
+
+    # In-place union, intersection, differences.
+    # Subtle:  The xyz_update() functions deliberately return None,
+    # as do all mutating operations on built-in container types.
+    # The __xyz__ spellings have to return self, though.
+
+    def __ior__(self, other):
+        """Update a set with the union of itself and another."""
+        self._binary_sanity_check(other)
+        self._data.update(other._data)
+        return self
+
+    def union_update(self, other):
+        """Update a set with the union of itself and another."""
+        self._update(other)
+
+    def __iand__(self, other):
+        """Update a set with the intersection of itself and another."""
+        self._binary_sanity_check(other)
+        self._data = (self & other)._data
+        return self
+
+    def intersection_update(self, other):
+        """Update a set with the intersection of itself and another."""
+        if isinstance(other, BaseSet):
+            self &= other
+        else:
+            self._data = (self.intersection(other))._data
+
+    def __ixor__(self, other):
+        """Update a set with the symmetric difference of itself and another."""
+        self._binary_sanity_check(other)
+        self.symmetric_difference_update(other)
+        return self
+
+    def symmetric_difference_update(self, other):
+        """Update a set with the symmetric difference of itself and another."""
+        data = self._data
+        value = True
+        if not isinstance(other, BaseSet):
+            other = Set(other)
+        if self is other:
+            self.clear()
+        for elt in other:
+            if elt in data:
+                del data[elt]
+            else:
+                data[elt] = value
+
+    def __isub__(self, other):
+        """Remove all elements of another set from this set."""
+        self._binary_sanity_check(other)
+        self.difference_update(other)
+        return self
+
+    def difference_update(self, other):
+        """Remove all elements of another set from this set."""
+        data = self._data
+        if not isinstance(other, BaseSet):
+            other = Set(other)
+        if self is other:
+            self.clear()
+        for elt in ifilter(data.has_key, other):
+            del data[elt]
+
+    # Python dict-like mass mutations: update, clear
+
+    def update(self, iterable):
+        """Add all values from an iterable (such as a list or file)."""
+        self._update(iterable)
+
+    def clear(self):
+        """Remove all elements from this set."""
+        self._data.clear()
+
+    # Single-element mutations: add, remove, discard
+
+    def add(self, element):
+        """Add an element to a set.
+
+        This has no effect if the element is already present.
+        """
+        try:
+            self._data[element] = True
+        except TypeError:
+            transform = getattr(element, "__as_immutable__", None)
+            if transform is None:
+                raise # re-raise the TypeError exception we caught
+            self._data[transform()] = True
+
+    def remove(self, element):
+        """Remove an element from a set; it must be a member.
+
+        If the element is not a member, raise a KeyError.
+        """
+        try:
+            del self._data[element]
+        except TypeError:
+            transform = getattr(element, "__as_temporarily_immutable__", None)
+            if transform is None:
+                raise # re-raise the TypeError exception we caught
+            del self._data[transform()]
+
+    def discard(self, element):
+        """Remove an element from a set if it is a member.
+
+        If the element is not a member, do nothing.
+        """
+        try:
+            self.remove(element)
+        except KeyError:
+            pass
+
+    def pop(self):
+        """Remove and return an arbitrary set element."""
+        return self._data.popitem()[0]
+
+    def __as_immutable__(self):
+        # Return a copy of self as an immutable set
+        return ImmutableSet(self)
+
+    def __as_temporarily_immutable__(self):
+        # Return self wrapped in a temporarily immutable set
+        return _TemporarilyImmutableSet(self)
+
+
+class _TemporarilyImmutableSet(BaseSet):
+    # Wrap a mutable set as if it was temporarily immutable.
+    # This only supplies hashing and equality comparisons.
+
+    def __init__(self, set):
+        self._set = set
+        self._data = set._data  # Needed by ImmutableSet.__eq__()
+
+    def __hash__(self):
+        return self._set._compute_hash()

Added: vendor/Python/current/Lib/sgmllib.py
===================================================================
--- vendor/Python/current/Lib/sgmllib.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/sgmllib.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,548 @@
+"""A parser for SGML, using the derived class as a static DTD."""
+
+# XXX This only supports those SGML features used by HTML.
+
+# XXX There should be a way to distinguish between PCDATA (parsed
+# character data -- the normal case), RCDATA (replaceable character
+# data -- only char and entity references and end tags are special)
+# and CDATA (character data -- only end tags are special).  RCDATA is
+# not supported at all.
+
+
+import markupbase
+import re
+
+__all__ = ["SGMLParser", "SGMLParseError"]
+
+# Regular expressions used for parsing
+
+interesting = re.compile('[&<]')
+incomplete = re.compile('&([a-zA-Z][a-zA-Z0-9]*|#[0-9]*)?|'
+                           '<([a-zA-Z][^<>]*|'
+                              '/([a-zA-Z][^<>]*)?|'
+                              '![^<>]*)?')
+
+entityref = re.compile('&([a-zA-Z][-.a-zA-Z0-9]*)[^a-zA-Z0-9]')
+charref = re.compile('&#([0-9]+)[^0-9]')
+
+starttagopen = re.compile('<[>a-zA-Z]')
+shorttagopen = re.compile('<[a-zA-Z][-.a-zA-Z0-9]*/')
+shorttag = re.compile('<([a-zA-Z][-.a-zA-Z0-9]*)/([^/]*)/')
+piclose = re.compile('>')
+endbracket = re.compile('[<>]')
+tagfind = re.compile('[a-zA-Z][-_.a-zA-Z0-9]*')
+attrfind = re.compile(
+    r'\s*([a-zA-Z_][-:.a-zA-Z_0-9]*)(\s*=\s*'
+    r'(\'[^\']*\'|"[^"]*"|[][\-a-zA-Z0-9./,:;+*%?!&$\(\)_#=~\'"@]*))?')
+
+
+class SGMLParseError(RuntimeError):
+    """Exception raised for all parse errors."""
+    pass
+
+
+# SGML parser base class -- find tags and call handler functions.
+# Usage: p = SGMLParser(); p.feed(data); ...; p.close().
+# The dtd is defined by deriving a class which defines methods
+# with special names to handle tags: start_foo and end_foo to handle
+# <foo> and </foo>, respectively, or do_foo to handle <foo> by itself.
+# (Tags are converted to lower case for this purpose.)  The data
+# between tags is passed to the parser by calling self.handle_data()
+# with some data as argument (the data may be split up in arbitrary
+# chunks).  Entity references are passed by calling
+# self.handle_entityref() with the entity reference as argument.
+
+class SGMLParser(markupbase.ParserBase):
+    # Definition of entities -- derived classes may override
+    entity_or_charref = re.compile('&(?:'
+      '([a-zA-Z][-.a-zA-Z0-9]*)|#([0-9]+)'
+      ')(;?)')
+
+    def __init__(self, verbose=0):
+        """Initialize and reset this instance."""
+        self.verbose = verbose
+        self.reset()
+
+    def reset(self):
+        """Reset this instance. Loses all unprocessed data."""
+        self.__starttag_text = None
+        self.rawdata = ''
+        self.stack = []
+        self.lasttag = '???'
+        self.nomoretags = 0
+        self.literal = 0
+        markupbase.ParserBase.reset(self)
+
+    def setnomoretags(self):
+        """Enter literal mode (CDATA) till EOF.
+
+        Intended for derived classes only.
+        """
+        self.nomoretags = self.literal = 1
+
+    def setliteral(self, *args):
+        """Enter literal mode (CDATA).
+
+        Intended for derived classes only.
+        """
+        self.literal = 1
+
+    def feed(self, data):
+        """Feed some data to the parser.
+
+        Call this as often as you want, with as little or as much text
+        as you want (may include '\n').  (This just saves the text,
+        all the processing is done by goahead().)
+        """
+
+        self.rawdata = self.rawdata + data
+        self.goahead(0)
+
+    def close(self):
+        """Handle the remaining data."""
+        self.goahead(1)
+
+    def error(self, message):
+        raise SGMLParseError(message)
+
+    # Internal -- handle data as far as reasonable.  May leave state
+    # and data to be processed by a subsequent call.  If 'end' is
+    # true, force handling all data as if followed by EOF marker.
+    def goahead(self, end):
+        rawdata = self.rawdata
+        i = 0
+        n = len(rawdata)
+        while i < n:
+            if self.nomoretags:
+                self.handle_data(rawdata[i:n])
+                i = n
+                break
+            match = interesting.search(rawdata, i)
+            if match: j = match.start()
+            else: j = n
+            if i < j:
+                self.handle_data(rawdata[i:j])
+            i = j
+            if i == n: break
+            if rawdata[i] == '<':
+                if starttagopen.match(rawdata, i):
+                    if self.literal:
+                        self.handle_data(rawdata[i])
+                        i = i+1
+                        continue
+                    k = self.parse_starttag(i)
+                    if k < 0: break
+                    i = k
+                    continue
+                if rawdata.startswith("</", i):
+                    k = self.parse_endtag(i)
+                    if k < 0: break
+                    i = k
+                    self.literal = 0
+                    continue
+                if self.literal:
+                    if n > (i + 1):
+                        self.handle_data("<")
+                        i = i+1
+                    else:
+                        # incomplete
+                        break
+                    continue
+                if rawdata.startswith("<!--", i):
+                        # Strictly speaking, a comment is --.*--
+                        # within a declaration tag <!...>.
+                        # This should be removed,
+                        # and comments handled only in parse_declaration.
+                    k = self.parse_comment(i)
+                    if k < 0: break
+                    i = k
+                    continue
+                if rawdata.startswith("<?", i):
+                    k = self.parse_pi(i)
+                    if k < 0: break
+                    i = i+k
+                    continue
+                if rawdata.startswith("<!", i):
+                    # This is some sort of declaration; in "HTML as
+                    # deployed," this should only be the document type
+                    # declaration ("<!DOCTYPE html...>").
+                    k = self.parse_declaration(i)
+                    if k < 0: break
+                    i = k
+                    continue
+            elif rawdata[i] == '&':
+                if self.literal:
+                    self.handle_data(rawdata[i])
+                    i = i+1
+                    continue
+                match = charref.match(rawdata, i)
+                if match:
+                    name = match.group(1)
+                    self.handle_charref(name)
+                    i = match.end(0)
+                    if rawdata[i-1] != ';': i = i-1
+                    continue
+                match = entityref.match(rawdata, i)
+                if match:
+                    name = match.group(1)
+                    self.handle_entityref(name)
+                    i = match.end(0)
+                    if rawdata[i-1] != ';': i = i-1
+                    continue
+            else:
+                self.error('neither < nor & ??')
+            # We get here only if incomplete matches but
+            # nothing else
+            match = incomplete.match(rawdata, i)
+            if not match:
+                self.handle_data(rawdata[i])
+                i = i+1
+                continue
+            j = match.end(0)
+            if j == n:
+                break # Really incomplete
+            self.handle_data(rawdata[i:j])
+            i = j
+        # end while
+        if end and i < n:
+            self.handle_data(rawdata[i:n])
+            i = n
+        self.rawdata = rawdata[i:]
+        # XXX if end: check for empty stack
+
+    # Extensions for the DOCTYPE scanner:
+    _decl_otherchars = '='
+
+    # Internal -- parse processing instr, return length or -1 if not terminated
+    def parse_pi(self, i):
+        rawdata = self.rawdata
+        if rawdata[i:i+2] != '<?':
+            self.error('unexpected call to parse_pi()')
+        match = piclose.search(rawdata, i+2)
+        if not match:
+            return -1
+        j = match.start(0)
+        self.handle_pi(rawdata[i+2: j])
+        j = match.end(0)
+        return j-i
+
+    def get_starttag_text(self):
+        return self.__starttag_text
+
+    # Internal -- handle starttag, return length or -1 if not terminated
+    def parse_starttag(self, i):
+        self.__starttag_text = None
+        start_pos = i
+        rawdata = self.rawdata
+        if shorttagopen.match(rawdata, i):
+            # SGML shorthand: <tag/data/ == <tag>data</tag>
+            # XXX Can data contain &... (entity or char refs)?
+            # XXX Can data contain < or > (tag characters)?
+            # XXX Can there be whitespace before the first /?
+            match = shorttag.match(rawdata, i)
+            if not match:
+                return -1
+            tag, data = match.group(1, 2)
+            self.__starttag_text = '<%s/' % tag
+            tag = tag.lower()
+            k = match.end(0)
+            self.finish_shorttag(tag, data)
+            self.__starttag_text = rawdata[start_pos:match.end(1) + 1]
+            return k
+        # XXX The following should skip matching quotes (' or ")
+        # As a shortcut way to exit, this isn't so bad, but shouldn't
+        # be used to locate the actual end of the start tag since the
+        # < or > characters may be embedded in an attribute value.
+        match = endbracket.search(rawdata, i+1)
+        if not match:
+            return -1
+        j = match.start(0)
+        # Now parse the data between i+1 and j into a tag and attrs
+        attrs = []
+        if rawdata[i:i+2] == '<>':
+            # SGML shorthand: <> == <last open tag seen>
+            k = j
+            tag = self.lasttag
+        else:
+            match = tagfind.match(rawdata, i+1)
+            if not match:
+                self.error('unexpected call to parse_starttag')
+            k = match.end(0)
+            tag = rawdata[i+1:k].lower()
+            self.lasttag = tag
+        while k < j:
+            match = attrfind.match(rawdata, k)
+            if not match: break
+            attrname, rest, attrvalue = match.group(1, 2, 3)
+            if not rest:
+                attrvalue = attrname
+            else:
+                if (attrvalue[:1] == "'" == attrvalue[-1:] or
+                    attrvalue[:1] == '"' == attrvalue[-1:]):
+                    # strip quotes
+                    attrvalue = attrvalue[1:-1]
+                attrvalue = self.entity_or_charref.sub(
+                    self._convert_ref, attrvalue)
+            attrs.append((attrname.lower(), attrvalue))
+            k = match.end(0)
+        if rawdata[j] == '>':
+            j = j+1
+        self.__starttag_text = rawdata[start_pos:j]
+        self.finish_starttag(tag, attrs)
+        return j
+
+    # Internal -- convert entity or character reference
+    def _convert_ref(self, match):
+        if match.group(2):
+            return self.convert_charref(match.group(2)) or \
+                '&#%s%s' % match.groups()[1:]
+        elif match.group(3):
+            return self.convert_entityref(match.group(1)) or \
+                '&%s;' % match.group(1)
+        else:
+            return '&%s' % match.group(1)
+
+    # Internal -- parse endtag
+    def parse_endtag(self, i):
+        rawdata = self.rawdata
+        match = endbracket.search(rawdata, i+1)
+        if not match:
+            return -1
+        j = match.start(0)
+        tag = rawdata[i+2:j].strip().lower()
+        if rawdata[j] == '>':
+            j = j+1
+        self.finish_endtag(tag)
+        return j
+
+    # Internal -- finish parsing of <tag/data/ (same as <tag>data</tag>)
+    def finish_shorttag(self, tag, data):
+        self.finish_starttag(tag, [])
+        self.handle_data(data)
+        self.finish_endtag(tag)
+
+    # Internal -- finish processing of start tag
+    # Return -1 for unknown tag, 0 for open-only tag, 1 for balanced tag
+    def finish_starttag(self, tag, attrs):
+        try:
+            method = getattr(self, 'start_' + tag)
+        except AttributeError:
+            try:
+                method = getattr(self, 'do_' + tag)
+            except AttributeError:
+                self.unknown_starttag(tag, attrs)
+                return -1
+            else:
+                self.handle_starttag(tag, method, attrs)
+                return 0
+        else:
+            self.stack.append(tag)
+            self.handle_starttag(tag, method, attrs)
+            return 1
+
+    # Internal -- finish processing of end tag
+    def finish_endtag(self, tag):
+        if not tag:
+            found = len(self.stack) - 1
+            if found < 0:
+                self.unknown_endtag(tag)
+                return
+        else:
+            if tag not in self.stack:
+                try:
+                    method = getattr(self, 'end_' + tag)
+                except AttributeError:
+                    self.unknown_endtag(tag)
+                else:
+                    self.report_unbalanced(tag)
+                return
+            found = len(self.stack)
+            for i in range(found):
+                if self.stack[i] == tag: found = i
+        while len(self.stack) > found:
+            tag = self.stack[-1]
+            try:
+                method = getattr(self, 'end_' + tag)
+            except AttributeError:
+                method = None
+            if method:
+                self.handle_endtag(tag, method)
+            else:
+                self.unknown_endtag(tag)
+            del self.stack[-1]
+
+    # Overridable -- handle start tag
+    def handle_starttag(self, tag, method, attrs):
+        method(attrs)
+
+    # Overridable -- handle end tag
+    def handle_endtag(self, tag, method):
+        method()
+
+    # Example -- report an unbalanced </...> tag.
+    def report_unbalanced(self, tag):
+        if self.verbose:
+            print '*** Unbalanced </' + tag + '>'
+            print '*** Stack:', self.stack
+
+    def convert_charref(self, name):
+        """Convert character reference, may be overridden."""
+        try:
+            n = int(name)
+        except ValueError:
+            return
+        if not 0 <= n <= 255:
+            return
+        return self.convert_codepoint(n)
+
+    def convert_codepoint(self, codepoint):
+        return chr(codepoint)
+
+    def handle_charref(self, name):
+        """Handle character reference, no need to override."""
+        replacement = self.convert_charref(name)
+        if replacement is None:
+            self.unknown_charref(name)
+        else:
+            self.handle_data(replacement)
+
+    # Definition of entities -- derived classes may override
+    entitydefs = \
+            {'lt': '<', 'gt': '>', 'amp': '&', 'quot': '"', 'apos': '\''}
+
+    def convert_entityref(self, name):
+        """Convert entity references.
+
+        As an alternative to overriding this method; one can tailor the
+        results by setting up the self.entitydefs mapping appropriately.
+        """
+        table = self.entitydefs
+        if name in table:
+            return table[name]
+        else:
+            return
+
+    def handle_entityref(self, name):
+        """Handle entity references, no need to override."""
+        replacement = self.convert_entityref(name)
+        if replacement is None:
+            self.unknown_entityref(name)
+        else:
+            self.handle_data(self.convert_entityref(name))
+
+    # Example -- handle data, should be overridden
+    def handle_data(self, data):
+        pass
+
+    # Example -- handle comment, could be overridden
+    def handle_comment(self, data):
+        pass
+
+    # Example -- handle declaration, could be overridden
+    def handle_decl(self, decl):
+        pass
+
+    # Example -- handle processing instruction, could be overridden
+    def handle_pi(self, data):
+        pass
+
+    # To be overridden -- handlers for unknown objects
+    def unknown_starttag(self, tag, attrs): pass
+    def unknown_endtag(self, tag): pass
+    def unknown_charref(self, ref): pass
+    def unknown_entityref(self, ref): pass
+
+
+class TestSGMLParser(SGMLParser):
+
+    def __init__(self, verbose=0):
+        self.testdata = ""
+        SGMLParser.__init__(self, verbose)
+
+    def handle_data(self, data):
+        self.testdata = self.testdata + data
+        if len(repr(self.testdata)) >= 70:
+            self.flush()
+
+    def flush(self):
+        data = self.testdata
+        if data:
+            self.testdata = ""
+            print 'data:', repr(data)
+
+    def handle_comment(self, data):
+        self.flush()
+        r = repr(data)
+        if len(r) > 68:
+            r = r[:32] + '...' + r[-32:]
+        print 'comment:', r
+
+    def unknown_starttag(self, tag, attrs):
+        self.flush()
+        if not attrs:
+            print 'start tag: <' + tag + '>'
+        else:
+            print 'start tag: <' + tag,
+            for name, value in attrs:
+                print name + '=' + '"' + value + '"',
+            print '>'
+
+    def unknown_endtag(self, tag):
+        self.flush()
+        print 'end tag: </' + tag + '>'
+
+    def unknown_entityref(self, ref):
+        self.flush()
+        print '*** unknown entity ref: &' + ref + ';'
+
+    def unknown_charref(self, ref):
+        self.flush()
+        print '*** unknown char ref: &#' + ref + ';'
+
+    def unknown_decl(self, data):
+        self.flush()
+        print '*** unknown decl: [' + data + ']'
+
+    def close(self):
+        SGMLParser.close(self)
+        self.flush()
+
+
+def test(args = None):
+    import sys
+
+    if args is None:
+        args = sys.argv[1:]
+
+    if args and args[0] == '-s':
+        args = args[1:]
+        klass = SGMLParser
+    else:
+        klass = TestSGMLParser
+
+    if args:
+        file = args[0]
+    else:
+        file = 'test.html'
+
+    if file == '-':
+        f = sys.stdin
+    else:
+        try:
+            f = open(file, 'r')
+        except IOError, msg:
+            print file, ":", msg
+            sys.exit(1)
+
+    data = f.read()
+    if f is not sys.stdin:
+        f.close()
+
+    x = klass()
+    for c in data:
+        x.feed(c)
+    x.close()
+
+
+if __name__ == '__main__':
+    test()

Added: vendor/Python/current/Lib/sha.py
===================================================================
--- vendor/Python/current/Lib/sha.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/sha.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,11 @@
+# $Id: sha.py 39316 2005-08-21 18:45:59Z greg $
+#
+#  Copyright (C) 2005   Gregory P. Smith (greg at electricrain.com)
+#  Licensed to PSF under a Contributor Agreement.
+
+from hashlib import sha1 as sha
+new = sha
+
+blocksize = 1        # legacy value (wrong in any useful sense)
+digest_size = 20
+digestsize = 20

Added: vendor/Python/current/Lib/shelve.py
===================================================================
--- vendor/Python/current/Lib/shelve.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/shelve.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,225 @@
+"""Manage shelves of pickled objects.
+
+A "shelf" is a persistent, dictionary-like object.  The difference
+with dbm databases is that the values (not the keys!) in a shelf can
+be essentially arbitrary Python objects -- anything that the "pickle"
+module can handle.  This includes most class instances, recursive data
+types, and objects containing lots of shared sub-objects.  The keys
+are ordinary strings.
+
+To summarize the interface (key is a string, data is an arbitrary
+object):
+
+        import shelve
+        d = shelve.open(filename) # open, with (g)dbm filename -- no suffix
+
+        d[key] = data   # store data at key (overwrites old data if
+                        # using an existing key)
+        data = d[key]   # retrieve a COPY of the data at key (raise
+                        # KeyError if no such key) -- NOTE that this
+                        # access returns a *copy* of the entry!
+        del d[key]      # delete data stored at key (raises KeyError
+                        # if no such key)
+        flag = d.has_key(key)   # true if the key exists; same as "key in d"
+        list = d.keys() # a list of all existing keys (slow!)
+
+        d.close()       # close it
+
+Dependent on the implementation, closing a persistent dictionary may
+or may not be necessary to flush changes to disk.
+
+Normally, d[key] returns a COPY of the entry.  This needs care when
+mutable entries are mutated: for example, if d[key] is a list,
+        d[key].append(anitem)
+does NOT modify the entry d[key] itself, as stored in the persistent
+mapping -- it only modifies the copy, which is then immediately
+discarded, so that the append has NO effect whatsoever.  To append an
+item to d[key] in a way that will affect the persistent mapping, use:
+        data = d[key]
+        data.append(anitem)
+        d[key] = data
+
+To avoid the problem with mutable entries, you may pass the keyword
+argument writeback=True in the call to shelve.open.  When you use:
+        d = shelve.open(filename, writeback=True)
+then d keeps a cache of all entries you access, and writes them all back
+to the persistent mapping when you call d.close().  This ensures that
+such usage as d[key].append(anitem) works as intended.
+
+However, using keyword argument writeback=True may consume vast amount
+of memory for the cache, and it may make d.close() very slow, if you
+access many of d's entries after opening it in this way: d has no way to
+check which of the entries you access are mutable and/or which ones you
+actually mutate, so it must cache, and write back at close, all of the
+entries that you access.  You can call d.sync() to write back all the
+entries in the cache, and empty the cache (d.sync() also synchronizes
+the persistent dictionary on disk, if feasible).
+"""
+
+# Try using cPickle and cStringIO if available.
+
+try:
+    from cPickle import Pickler, Unpickler
+except ImportError:
+    from pickle import Pickler, Unpickler
+
+try:
+    from cStringIO import StringIO
+except ImportError:
+    from StringIO import StringIO
+
+import UserDict
+import warnings
+
+__all__ = ["Shelf","BsdDbShelf","DbfilenameShelf","open"]
+
+class Shelf(UserDict.DictMixin):
+    """Base class for shelf implementations.
+
+    This is initialized with a dictionary-like object.
+    See the module's __doc__ string for an overview of the interface.
+    """
+
+    def __init__(self, dict, protocol=None, writeback=False):
+        self.dict = dict
+        if protocol is None:
+            protocol = 0
+        self._protocol = protocol
+        self.writeback = writeback
+        self.cache = {}
+
+    def keys(self):
+        return self.dict.keys()
+
+    def __len__(self):
+        return len(self.dict)
+
+    def has_key(self, key):
+        return self.dict.has_key(key)
+
+    def __contains__(self, key):
+        return self.dict.has_key(key)
+
+    def get(self, key, default=None):
+        if self.dict.has_key(key):
+            return self[key]
+        return default
+
+    def __getitem__(self, key):
+        try:
+            value = self.cache[key]
+        except KeyError:
+            f = StringIO(self.dict[key])
+            value = Unpickler(f).load()
+            if self.writeback:
+                self.cache[key] = value
+        return value
+
+    def __setitem__(self, key, value):
+        if self.writeback:
+            self.cache[key] = value
+        f = StringIO()
+        p = Pickler(f, self._protocol)
+        p.dump(value)
+        self.dict[key] = f.getvalue()
+
+    def __delitem__(self, key):
+        del self.dict[key]
+        try:
+            del self.cache[key]
+        except KeyError:
+            pass
+
+    def close(self):
+        self.sync()
+        try:
+            self.dict.close()
+        except AttributeError:
+            pass
+        self.dict = 0
+
+    def __del__(self):
+        if not hasattr(self, 'writeback'):
+            # __init__ didn't succeed, so don't bother closing
+            return
+        self.close()
+
+    def sync(self):
+        if self.writeback and self.cache:
+            self.writeback = False
+            for key, entry in self.cache.iteritems():
+                self[key] = entry
+            self.writeback = True
+            self.cache = {}
+        if hasattr(self.dict, 'sync'):
+            self.dict.sync()
+
+
+class BsdDbShelf(Shelf):
+    """Shelf implementation using the "BSD" db interface.
+
+    This adds methods first(), next(), previous(), last() and
+    set_location() that have no counterpart in [g]dbm databases.
+
+    The actual database must be opened using one of the "bsddb"
+    modules "open" routines (i.e. bsddb.hashopen, bsddb.btopen or
+    bsddb.rnopen) and passed to the constructor.
+
+    See the module's __doc__ string for an overview of the interface.
+    """
+
+    def __init__(self, dict, protocol=None, writeback=False):
+        Shelf.__init__(self, dict, protocol, writeback)
+
+    def set_location(self, key):
+        (key, value) = self.dict.set_location(key)
+        f = StringIO(value)
+        return (key, Unpickler(f).load())
+
+    def next(self):
+        (key, value) = self.dict.next()
+        f = StringIO(value)
+        return (key, Unpickler(f).load())
+
+    def previous(self):
+        (key, value) = self.dict.previous()
+        f = StringIO(value)
+        return (key, Unpickler(f).load())
+
+    def first(self):
+        (key, value) = self.dict.first()
+        f = StringIO(value)
+        return (key, Unpickler(f).load())
+
+    def last(self):
+        (key, value) = self.dict.last()
+        f = StringIO(value)
+        return (key, Unpickler(f).load())
+
+
+class DbfilenameShelf(Shelf):
+    """Shelf implementation using the "anydbm" generic dbm interface.
+
+    This is initialized with the filename for the dbm database.
+    See the module's __doc__ string for an overview of the interface.
+    """
+
+    def __init__(self, filename, flag='c', protocol=None, writeback=False):
+        import anydbm
+        Shelf.__init__(self, anydbm.open(filename, flag), protocol, writeback)
+
+
+def open(filename, flag='c', protocol=None, writeback=False):
+    """Open a persistent dictionary for reading and writing.
+
+    The filename parameter is the base filename for the underlying
+    database.  As a side-effect, an extension may be added to the
+    filename and more than one file may be created.  The optional flag
+    parameter has the same interpretation as the flag parameter of
+    anydbm.open(). The optional protocol parameter specifies the
+    version of the pickle protocol (0, 1, or 2).
+
+    See the module's __doc__ string for an overview of the interface.
+    """
+
+    return DbfilenameShelf(filename, flag, protocol, writeback)

Added: vendor/Python/current/Lib/shlex.py
===================================================================
--- vendor/Python/current/Lib/shlex.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/shlex.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,292 @@
+# -*- coding: iso-8859-1 -*-
+"""A lexical analyzer class for simple shell-like syntaxes."""
+
+# Module and documentation by Eric S. Raymond, 21 Dec 1998
+# Input stacking and error message cleanup added by ESR, March 2000
+# push_source() and pop_source() made explicit by ESR, January 2001.
+# Posix compliance, split(), string arguments, and
+# iterator interface by Gustavo Niemeyer, April 2003.
+
+import os.path
+import sys
+from collections import deque
+
+try:
+    from cStringIO import StringIO
+except ImportError:
+    from StringIO import StringIO
+
+__all__ = ["shlex", "split"]
+
+class shlex:
+    "A lexical analyzer class for simple shell-like syntaxes."
+    def __init__(self, instream=None, infile=None, posix=False):
+        if isinstance(instream, basestring):
+            instream = StringIO(instream)
+        if instream is not None:
+            self.instream = instream
+            self.infile = infile
+        else:
+            self.instream = sys.stdin
+            self.infile = None
+        self.posix = posix
+        if posix:
+            self.eof = None
+        else:
+            self.eof = ''
+        self.commenters = '#'
+        self.wordchars = ('abcdfeghijklmnopqrstuvwxyz'
+                          'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_')
+        if self.posix:
+            self.wordchars += ('ßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ'
+                               'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ')
+        self.whitespace = ' \t\r\n'
+        self.whitespace_split = False
+        self.quotes = '\'"'
+        self.escape = '\\'
+        self.escapedquotes = '"'
+        self.state = ' '
+        self.pushback = deque()
+        self.lineno = 1
+        self.debug = 0
+        self.token = ''
+        self.filestack = deque()
+        self.source = None
+        if self.debug:
+            print 'shlex: reading from %s, line %d' \
+                  % (self.instream, self.lineno)
+
+    def push_token(self, tok):
+        "Push a token onto the stack popped by the get_token method"
+        if self.debug >= 1:
+            print "shlex: pushing token " + repr(tok)
+        self.pushback.appendleft(tok)
+
+    def push_source(self, newstream, newfile=None):
+        "Push an input source onto the lexer's input source stack."
+        if isinstance(newstream, basestring):
+            newstream = StringIO(newstream)
+        self.filestack.appendleft((self.infile, self.instream, self.lineno))
+        self.infile = newfile
+        self.instream = newstream
+        self.lineno = 1
+        if self.debug:
+            if newfile is not None:
+                print 'shlex: pushing to file %s' % (self.infile,)
+            else:
+                print 'shlex: pushing to stream %s' % (self.instream,)
+
+    def pop_source(self):
+        "Pop the input source stack."
+        self.instream.close()
+        (self.infile, self.instream, self.lineno) = self.filestack.popleft()
+        if self.debug:
+            print 'shlex: popping to %s, line %d' \
+                  % (self.instream, self.lineno)
+        self.state = ' '
+
+    def get_token(self):
+        "Get a token from the input stream (or from stack if it's nonempty)"
+        if self.pushback:
+            tok = self.pushback.popleft()
+            if self.debug >= 1:
+                print "shlex: popping token " + repr(tok)
+            return tok
+        # No pushback.  Get a token.
+        raw = self.read_token()
+        # Handle inclusions
+        if self.source is not None:
+            while raw == self.source:
+                spec = self.sourcehook(self.read_token())
+                if spec:
+                    (newfile, newstream) = spec
+                    self.push_source(newstream, newfile)
+                raw = self.get_token()
+        # Maybe we got EOF instead?
+        while raw == self.eof:
+            if not self.filestack:
+                return self.eof
+            else:
+                self.pop_source()
+                raw = self.get_token()
+        # Neither inclusion nor EOF
+        if self.debug >= 1:
+            if raw != self.eof:
+                print "shlex: token=" + repr(raw)
+            else:
+                print "shlex: token=EOF"
+        return raw
+
+    def read_token(self):
+        quoted = False
+        escapedstate = ' '
+        while True:
+            nextchar = self.instream.read(1)
+            if nextchar == '\n':
+                self.lineno = self.lineno + 1
+            if self.debug >= 3:
+                print "shlex: in state", repr(self.state), \
+                      "I see character:", repr(nextchar)
+            if self.state is None:
+                self.token = ''        # past end of file
+                break
+            elif self.state == ' ':
+                if not nextchar:
+                    self.state = None  # end of file
+                    break
+                elif nextchar in self.whitespace:
+                    if self.debug >= 2:
+                        print "shlex: I see whitespace in whitespace state"
+                    if self.token or (self.posix and quoted):
+                        break   # emit current token
+                    else:
+                        continue
+                elif nextchar in self.commenters:
+                    self.instream.readline()
+                    self.lineno = self.lineno + 1
+                elif self.posix and nextchar in self.escape:
+                    escapedstate = 'a'
+                    self.state = nextchar
+                elif nextchar in self.wordchars:
+                    self.token = nextchar
+                    self.state = 'a'
+                elif nextchar in self.quotes:
+                    if not self.posix:
+                        self.token = nextchar
+                    self.state = nextchar
+                elif self.whitespace_split:
+                    self.token = nextchar
+                    self.state = 'a'
+                else:
+                    self.token = nextchar
+                    if self.token or (self.posix and quoted):
+                        break   # emit current token
+                    else:
+                        continue
+            elif self.state in self.quotes:
+                quoted = True
+                if not nextchar:      # end of file
+                    if self.debug >= 2:
+                        print "shlex: I see EOF in quotes state"
+                    # XXX what error should be raised here?
+                    raise ValueError, "No closing quotation"
+                if nextchar == self.state:
+                    if not self.posix:
+                        self.token = self.token + nextchar
+                        self.state = ' '
+                        break
+                    else:
+                        self.state = 'a'
+                elif self.posix and nextchar in self.escape and \
+                     self.state in self.escapedquotes:
+                    escapedstate = self.state
+                    self.state = nextchar
+                else:
+                    self.token = self.token + nextchar
+            elif self.state in self.escape:
+                if not nextchar:      # end of file
+                    if self.debug >= 2:
+                        print "shlex: I see EOF in escape state"
+                    # XXX what error should be raised here?
+                    raise ValueError, "No escaped character"
+                # In posix shells, only the quote itself or the escape
+                # character may be escaped within quotes.
+                if escapedstate in self.quotes and \
+                   nextchar != self.state and nextchar != escapedstate:
+                    self.token = self.token + self.state
+                self.token = self.token + nextchar
+                self.state = escapedstate
+            elif self.state == 'a':
+                if not nextchar:
+                    self.state = None   # end of file
+                    break
+                elif nextchar in self.whitespace:
+                    if self.debug >= 2:
+                        print "shlex: I see whitespace in word state"
+                    self.state = ' '
+                    if self.token or (self.posix and quoted):
+                        break   # emit current token
+                    else:
+                        continue
+                elif nextchar in self.commenters:
+                    self.instream.readline()
+                    self.lineno = self.lineno + 1
+                    if self.posix:
+                        self.state = ' '
+                        if self.token or (self.posix and quoted):
+                            break   # emit current token
+                        else:
+                            continue
+                elif self.posix and nextchar in self.quotes:
+                    self.state = nextchar
+                elif self.posix and nextchar in self.escape:
+                    escapedstate = 'a'
+                    self.state = nextchar
+                elif nextchar in self.wordchars or nextchar in self.quotes \
+                    or self.whitespace_split:
+                    self.token = self.token + nextchar
+                else:
+                    self.pushback.appendleft(nextchar)
+                    if self.debug >= 2:
+                        print "shlex: I see punctuation in word state"
+                    self.state = ' '
+                    if self.token:
+                        break   # emit current token
+                    else:
+                        continue
+        result = self.token
+        self.token = ''
+        if self.posix and not quoted and result == '':
+            result = None
+        if self.debug > 1:
+            if result:
+                print "shlex: raw token=" + repr(result)
+            else:
+                print "shlex: raw token=EOF"
+        return result
+
+    def sourcehook(self, newfile):
+        "Hook called on a filename to be sourced."
+        if newfile[0] == '"':
+            newfile = newfile[1:-1]
+        # This implements cpp-like semantics for relative-path inclusion.
+        if isinstance(self.infile, basestring) and not os.path.isabs(newfile):
+            newfile = os.path.join(os.path.dirname(self.infile), newfile)
+        return (newfile, open(newfile, "r"))
+
+    def error_leader(self, infile=None, lineno=None):
+        "Emit a C-compiler-like, Emacs-friendly error-message leader."
+        if infile is None:
+            infile = self.infile
+        if lineno is None:
+            lineno = self.lineno
+        return "\"%s\", line %d: " % (infile, lineno)
+
+    def __iter__(self):
+        return self
+
+    def next(self):
+        token = self.get_token()
+        if token == self.eof:
+            raise StopIteration
+        return token
+
+def split(s, comments=False):
+    lex = shlex(s, posix=True)
+    lex.whitespace_split = True
+    if not comments:
+        lex.commenters = ''
+    return list(lex)
+
+if __name__ == '__main__':
+    if len(sys.argv) == 1:
+        lexer = shlex()
+    else:
+        file = sys.argv[1]
+        lexer = shlex(open(file), file)
+    while 1:
+        tt = lexer.get_token()
+        if tt:
+            print "Token: " + repr(tt)
+        else:
+            break

Added: vendor/Python/current/Lib/shutil.py
===================================================================
--- vendor/Python/current/Lib/shutil.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/shutil.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,203 @@
+"""Utility functions for copying files and directory trees.
+
+XXX The functions here don't copy the resource fork or other metadata on Mac.
+
+"""
+
+import os
+import sys
+import stat
+from os.path import abspath
+
+__all__ = ["copyfileobj","copyfile","copymode","copystat","copy","copy2",
+           "copytree","move","rmtree","Error"]
+
+class Error(EnvironmentError):
+    pass
+
+def copyfileobj(fsrc, fdst, length=16*1024):
+    """copy data from file-like object fsrc to file-like object fdst"""
+    while 1:
+        buf = fsrc.read(length)
+        if not buf:
+            break
+        fdst.write(buf)
+
+def _samefile(src, dst):
+    # Macintosh, Unix.
+    if hasattr(os.path,'samefile'):
+        try:
+            return os.path.samefile(src, dst)
+        except OSError:
+            return False
+
+    # All other platforms: check for same pathname.
+    return (os.path.normcase(os.path.abspath(src)) ==
+            os.path.normcase(os.path.abspath(dst)))
+
+def copyfile(src, dst):
+    """Copy data from src to dst"""
+    if _samefile(src, dst):
+        raise Error, "`%s` and `%s` are the same file" % (src, dst)
+
+    fsrc = None
+    fdst = None
+    try:
+        fsrc = open(src, 'rb')
+        fdst = open(dst, 'wb')
+        copyfileobj(fsrc, fdst)
+    finally:
+        if fdst:
+            fdst.close()
+        if fsrc:
+            fsrc.close()
+
+def copymode(src, dst):
+    """Copy mode bits from src to dst"""
+    if hasattr(os, 'chmod'):
+        st = os.stat(src)
+        mode = stat.S_IMODE(st.st_mode)
+        os.chmod(dst, mode)
+
+def copystat(src, dst):
+    """Copy all stat info (mode bits, atime and mtime) from src to dst"""
+    st = os.stat(src)
+    mode = stat.S_IMODE(st.st_mode)
+    if hasattr(os, 'utime'):
+        os.utime(dst, (st.st_atime, st.st_mtime))
+    if hasattr(os, 'chmod'):
+        os.chmod(dst, mode)
+
+
+def copy(src, dst):
+    """Copy data and mode bits ("cp src dst").
+
+    The destination may be a directory.
+
+    """
+    if os.path.isdir(dst):
+        dst = os.path.join(dst, os.path.basename(src))
+    copyfile(src, dst)
+    copymode(src, dst)
+
+def copy2(src, dst):
+    """Copy data and all stat info ("cp -p src dst").
+
+    The destination may be a directory.
+
+    """
+    if os.path.isdir(dst):
+        dst = os.path.join(dst, os.path.basename(src))
+    copyfile(src, dst)
+    copystat(src, dst)
+
+
+def copytree(src, dst, symlinks=False):
+    """Recursively copy a directory tree using copy2().
+
+    The destination directory must not already exist.
+    If exception(s) occur, an Error is raised with a list of reasons.
+
+    If the optional symlinks flag is true, symbolic links in the
+    source tree result in symbolic links in the destination tree; if
+    it is false, the contents of the files pointed to by symbolic
+    links are copied.
+
+    XXX Consider this example code rather than the ultimate tool.
+
+    """
+    names = os.listdir(src)
+    os.makedirs(dst)
+    errors = []
+    for name in names:
+        srcname = os.path.join(src, name)
+        dstname = os.path.join(dst, name)
+        try:
+            if symlinks and os.path.islink(srcname):
+                linkto = os.readlink(srcname)
+                os.symlink(linkto, dstname)
+            elif os.path.isdir(srcname):
+                copytree(srcname, dstname, symlinks)
+            else:
+                copy2(srcname, dstname)
+            # XXX What about devices, sockets etc.?
+        except (IOError, os.error), why:
+            errors.append((srcname, dstname, str(why)))
+        # catch the Error from the recursive copytree so that we can
+        # continue with other files
+        except Error, err:
+            errors.extend(err.args[0])
+    try:
+        copystat(src, dst)
+    except WindowsError:
+        # can't copy file access times on Windows
+        pass
+    except OSError, why:
+        errors.extend((src, dst, str(why)))
+    if errors:
+        raise Error, errors
+
+def rmtree(path, ignore_errors=False, onerror=None):
+    """Recursively delete a directory tree.
+
+    If ignore_errors is set, errors are ignored; otherwise, if onerror
+    is set, it is called to handle the error with arguments (func,
+    path, exc_info) where func is os.listdir, os.remove, or os.rmdir;
+    path is the argument to that function that caused it to fail; and
+    exc_info is a tuple returned by sys.exc_info().  If ignore_errors
+    is false and onerror is None, an exception is raised.
+
+    """
+    if ignore_errors:
+        def onerror(*args):
+            pass
+    elif onerror is None:
+        def onerror(*args):
+            raise
+    names = []
+    try:
+        names = os.listdir(path)
+    except os.error, err:
+        onerror(os.listdir, path, sys.exc_info())
+    for name in names:
+        fullname = os.path.join(path, name)
+        try:
+            mode = os.lstat(fullname).st_mode
+        except os.error:
+            mode = 0
+        if stat.S_ISDIR(mode):
+            rmtree(fullname, ignore_errors, onerror)
+        else:
+            try:
+                os.remove(fullname)
+            except os.error, err:
+                onerror(os.remove, fullname, sys.exc_info())
+    try:
+        os.rmdir(path)
+    except os.error:
+        onerror(os.rmdir, path, sys.exc_info())
+
+def move(src, dst):
+    """Recursively move a file or directory to another location.
+
+    If the destination is on our current filesystem, then simply use
+    rename.  Otherwise, copy src to the dst and then remove src.
+    A lot more could be done here...  A look at a mv.c shows a lot of
+    the issues this implementation glosses over.
+
+    """
+
+    try:
+        os.rename(src, dst)
+    except OSError:
+        if os.path.isdir(src):
+            if destinsrc(src, dst):
+                raise Error, "Cannot move a directory '%s' into itself '%s'." % (src, dst)
+            copytree(src, dst, symlinks=True)
+            rmtree(src)
+        else:
+            copy2(src,dst)
+            os.unlink(src)
+
+def destinsrc(src, dst):
+    return abspath(dst).startswith(abspath(src))

Added: vendor/Python/current/Lib/site-packages/README
===================================================================
--- vendor/Python/current/Lib/site-packages/README	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/site-packages/README	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2 @@
+This directory exists so that 3rd party packages can be installed
+here.  Read the source for site.py for more details.

Added: vendor/Python/current/Lib/site.py
===================================================================
--- vendor/Python/current/Lib/site.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/site.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,424 @@
+"""Append module search paths for third-party packages to sys.path.
+
+****************************************************************
+* This module is automatically imported during initialization. *
+****************************************************************
+
+In earlier versions of Python (up to 1.5a3), scripts or modules that
+needed to use site-specific modules would place ``import site''
+somewhere near the top of their code.  Because of the automatic
+import, this is no longer necessary (but code that does it still
+works).
+
+This will append site-specific paths to the module search path.  On
+Unix (including Mac OSX), it starts with sys.prefix and
+sys.exec_prefix (if different) and appends
+lib/python<version>/site-packages as well as lib/site-python.
+On other platforms (such as Windows), it tries each of the
+prefixes directly, as well as with lib/site-packages appended.  The
+resulting directories, if they exist, are appended to sys.path, and
+also inspected for path configuration files.
+
+A path configuration file is a file whose name has the form
+<package>.pth; its contents are additional directories (one per line)
+to be added to sys.path.  Non-existing directories (or
+non-directories) are never added to sys.path; no directory is added to
+sys.path more than once.  Blank lines and lines beginning with
+'#' are skipped. Lines starting with 'import' are executed.
+
+For example, suppose sys.prefix and sys.exec_prefix are set to
+/usr/local and there is a directory /usr/local/lib/python2.5/site-packages
+with three subdirectories, foo, bar and spam, and two path
+configuration files, foo.pth and bar.pth.  Assume foo.pth contains the
+following:
+
+  # foo package configuration
+  foo
+  bar
+  bletch
+
+and bar.pth contains:
+
+  # bar package configuration
+  bar
+
+Then the following directories are added to sys.path, in this order:
+
+  /usr/local/lib/python2.5/site-packages/bar
+  /usr/local/lib/python2.5/site-packages/foo
+
+Note that bletch is omitted because it doesn't exist; bar precedes foo
+because bar.pth comes alphabetically before foo.pth; and spam is
+omitted because it is not mentioned in either path configuration file.
+
+After these path manipulations, an attempt is made to import a module
+named sitecustomize, which can perform arbitrary additional
+site-specific customizations.  If this import fails with an
+ImportError exception, it is silently ignored.
+
+"""
+
+import sys
+import os
+import __builtin__
+
+
+def makepath(*paths):
+    dir = os.path.abspath(os.path.join(*paths))
+    return dir, os.path.normcase(dir)
+
+def abs__file__():
+    """Set all module' __file__ attribute to an absolute path"""
+    for m in sys.modules.values():
+        if hasattr(m, '__loader__'):
+            continue   # don't mess with a PEP 302-supplied __file__
+        try:
+            m.__file__ = os.path.abspath(m.__file__)
+        except AttributeError:
+            continue
+
+def removeduppaths():
+    """ Remove duplicate entries from sys.path along with making them
+    absolute"""
+    # This ensures that the initial path provided by the interpreter contains
+    # only absolute pathnames, even if we're running from the build directory.
+    L = []
+    known_paths = set()
+    for dir in sys.path:
+        # Filter out duplicate paths (on case-insensitive file systems also
+        # if they only differ in case); turn relative paths into absolute
+        # paths.
+        dir, dircase = makepath(dir)
+        if not dircase in known_paths:
+            L.append(dir)
+            known_paths.add(dircase)
+    sys.path[:] = L
+    return known_paths
+
+# XXX This should not be part of site.py, since it is needed even when
+# using the -S option for Python.  See http://www.python.org/sf/586680
+def addbuilddir():
+    """Append ./build/lib.<platform> in case we're running in the build dir
+    (especially for Guido :-)"""
+    from distutils.util import get_platform
+    s = "build/lib.%s-%.3s" % (get_platform(), sys.version)
+    s = os.path.join(os.path.dirname(sys.path[-1]), s)
+    sys.path.append(s)
+
+def _init_pathinfo():
+    """Return a set containing all existing directory entries from sys.path"""
+    d = set()
+    for dir in sys.path:
+        try:
+            if os.path.isdir(dir):
+                dir, dircase = makepath(dir)
+                d.add(dircase)
+        except TypeError:
+            continue
+    return d
+
+def addpackage(sitedir, name, known_paths):
+    """Add a new path to known_paths by combining sitedir and 'name' or execute
+    sitedir if it starts with 'import'"""
+    if known_paths is None:
+        _init_pathinfo()
+        reset = 1
+    else:
+        reset = 0
+    fullname = os.path.join(sitedir, name)
+    try:
+        f = open(fullname, "rU")
+    except IOError:
+        return
+    try:
+        for line in f:
+            if line.startswith("#"):
+                continue
+            if line.startswith("import"):
+                exec line
+                continue
+            line = line.rstrip()
+            dir, dircase = makepath(sitedir, line)
+            if not dircase in known_paths and os.path.exists(dir):
+                sys.path.append(dir)
+                known_paths.add(dircase)
+    finally:
+        f.close()
+    if reset:
+        known_paths = None
+    return known_paths
+
+def addsitedir(sitedir, known_paths=None):
+    """Add 'sitedir' argument to sys.path if missing and handle .pth files in
+    'sitedir'"""
+    if known_paths is None:
+        known_paths = _init_pathinfo()
+        reset = 1
+    else:
+        reset = 0
+    sitedir, sitedircase = makepath(sitedir)
+    if not sitedircase in known_paths:
+        sys.path.append(sitedir)        # Add path component
+    try:
+        names = os.listdir(sitedir)
+    except os.error:
+        return
+    names.sort()
+    for name in names:
+        if name.endswith(os.extsep + "pth"):
+            addpackage(sitedir, name, known_paths)
+    if reset:
+        known_paths = None
+    return known_paths
+
+def addsitepackages(known_paths):
+    """Add site-packages (and possibly site-python) to sys.path"""
+    prefixes = [sys.prefix]
+    if sys.exec_prefix != sys.prefix:
+        prefixes.append(sys.exec_prefix)
+    for prefix in prefixes:
+        if prefix:
+            if sys.platform in ('os2emx', 'riscos'):
+                sitedirs = [os.path.join(prefix, "Lib", "site-packages")]
+            elif os.sep == '/':
+                sitedirs = [os.path.join(prefix,
+                                         "lib",
+                                         "python" + sys.version[:3],
+                                         "site-packages"),
+                            os.path.join(prefix, "lib", "site-python")]
+            else:
+                sitedirs = [prefix, os.path.join(prefix, "lib", "site-packages")]
+            if sys.platform == 'darwin':
+                # for framework builds *only* we add the standard Apple
+                # locations. Currently only per-user, but /Library and
+                # /Network/Library could be added too
+                if 'Python.framework' in prefix:
+                    home = os.environ.get('HOME')
+                    if home:
+                        sitedirs.append(
+                            os.path.join(home,
+                                         'Library',
+                                         'Python',
+                                         sys.version[:3],
+                                         'site-packages'))
+            for sitedir in sitedirs:
+                if os.path.isdir(sitedir):
+                    addsitedir(sitedir, known_paths)
+    return None
+
+
+def setBEGINLIBPATH():
+    """The OS/2 EMX port has optional extension modules that do double duty
+    as DLLs (and must use the .DLL file extension) for other extensions.
+    The library search path needs to be amended so these will be found
+    during module import.  Use BEGINLIBPATH so that these are at the start
+    of the library search path.
+
+    """
+    dllpath = os.path.join(sys.prefix, "Lib", "lib-dynload")
+    libpath = os.environ['BEGINLIBPATH'].split(';')
+    if libpath[-1]:
+        libpath.append(dllpath)
+    else:
+        libpath[-1] = dllpath
+    os.environ['BEGINLIBPATH'] = ';'.join(libpath)
+
+
+def setquit():
+    """Define new built-ins 'quit' and 'exit'.
+    These are simply strings that display a hint on how to exit.
+
+    """
+    if os.sep == ':':
+        eof = 'Cmd-Q'
+    elif os.sep == '\\':
+        eof = 'Ctrl-Z plus Return'
+    else:
+        eof = 'Ctrl-D (i.e. EOF)'
+
+    class Quitter(object):
+        def __init__(self, name):
+            self.name = name
+        def __repr__(self):
+            return 'Use %s() or %s to exit' % (self.name, eof)
+        def __call__(self, code=None):
+            # Shells like IDLE catch the SystemExit, but listen when their
+            # stdin wrapper is closed.
+            try:
+                sys.stdin.close()
+            except:
+                pass
+            raise SystemExit(code)
+    __builtin__.quit = Quitter('quit')
+    __builtin__.exit = Quitter('exit')
+
+
+class _Printer(object):
+    """interactive prompt objects for printing the license text, a list of
+    contributors and the copyright notice."""
+
+    MAXLINES = 23
+
+    def __init__(self, name, data, files=(), dirs=()):
+        self.__name = name
+        self.__data = data
+        self.__files = files
+        self.__dirs = dirs
+        self.__lines = None
+
+    def __setup(self):
+        if self.__lines:
+            return
+        data = None
+        for dir in self.__dirs:
+            for filename in self.__files:
+                filename = os.path.join(dir, filename)
+                try:
+                    fp = file(filename, "rU")
+                    data = fp.read()
+                    fp.close()
+                    break
+                except IOError:
+                    pass
+            if data:
+                break
+        if not data:
+            data = self.__data
+        self.__lines = data.split('\n')
+        self.__linecnt = len(self.__lines)
+
+    def __repr__(self):
+        self.__setup()
+        if len(self.__lines) <= self.MAXLINES:
+            return "\n".join(self.__lines)
+        else:
+            return "Type %s() to see the full %s text" % ((self.__name,)*2)
+
+    def __call__(self):
+        self.__setup()
+        prompt = 'Hit Return for more, or q (and Return) to quit: '
+        lineno = 0
+        while 1:
+            try:
+                for i in range(lineno, lineno + self.MAXLINES):
+                    print self.__lines[i]
+            except IndexError:
+                break
+            else:
+                lineno += self.MAXLINES
+                key = None
+                while key is None:
+                    key = raw_input(prompt)
+                    if key not in ('', 'q'):
+                        key = None
+                if key == 'q':
+                    break
+
+def setcopyright():
+    """Set 'copyright' and 'credits' in __builtin__"""
+    __builtin__.copyright = _Printer("copyright", sys.copyright)
+    if sys.platform[:4] == 'java':
+        __builtin__.credits = _Printer(
+            "credits",
+            "Jython is maintained by the Jython developers (www.jython.org).")
+    else:
+        __builtin__.credits = _Printer("credits", """\
+    Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands
+    for supporting Python development.  See www.python.org for more information.""")
+    here = os.path.dirname(os.__file__)
+    __builtin__.license = _Printer(
+        "license", "See http://www.python.org/%.3s/license.html" % sys.version,
+        ["LICENSE.txt", "LICENSE"],
+        [os.path.join(here, os.pardir), here, os.curdir])
+
+
+class _Helper(object):
+    """Define the built-in 'help'.
+    This is a wrapper around pydoc.help (with a twist).
+
+    """
+
+    def __repr__(self):
+        return "Type help() for interactive help, " \
+               "or help(object) for help about object."
+    def __call__(self, *args, **kwds):
+        import pydoc
+        return pydoc.help(*args, **kwds)
+
+def sethelper():
+    __builtin__.help = _Helper()
+
+def aliasmbcs():
+    """On Windows, some default encodings are not provided by Python,
+    while they are always available as "mbcs" in each locale. Make
+    them usable by aliasing to "mbcs" in such a case."""
+    if sys.platform == 'win32':
+        import locale, codecs
+        enc = locale.getdefaultlocale()[1]
+        if enc.startswith('cp'):            # "cp***" ?
+            try:
+                codecs.lookup(enc)
+            except LookupError:
+                import encodings
+                encodings._cache[enc] = encodings._unknown
+                encodings.aliases.aliases[enc] = 'mbcs'
+
+def setencoding():
+    """Set the string encoding used by the Unicode implementation.  The
+    default is 'ascii', but if you're willing to experiment, you can
+    change this."""
+    encoding = "ascii" # Default value set by _PyUnicode_Init()
+    if 0:
+        # Enable to support locale aware default string encodings.
+        import locale
+        loc = locale.getdefaultlocale()
+        if loc[1]:
+            encoding = loc[1]
+    if 0:
+        # Enable to switch off string to Unicode coercion and implicit
+        # Unicode to string conversion.
+        encoding = "undefined"
+    if encoding != "ascii":
+        # On Non-Unicode builds this will raise an AttributeError...
+        sys.setdefaultencoding(encoding) # Needs Python Unicode build !
+
+
+def execsitecustomize():
+    """Run custom site specific code, if available."""
+    try:
+        import sitecustomize
+    except ImportError:
+        pass
+
+
+def main():
+    abs__file__()
+    paths_in_sys = removeduppaths()
+    if (os.name == "posix" and sys.path and
+        os.path.basename(sys.path[-1]) == "Modules"):
+        addbuilddir()
+    paths_in_sys = addsitepackages(paths_in_sys)
+    if sys.platform == 'os2emx':
+        setBEGINLIBPATH()
+    setquit()
+    setcopyright()
+    sethelper()
+    aliasmbcs()
+    setencoding()
+    execsitecustomize()
+    # Remove sys.setdefaultencoding() so that users cannot change the
+    # encoding after initialization.  The test for presence is needed when
+    # this module is run as a script, because this code is executed twice.
+    if hasattr(sys, "setdefaultencoding"):
+        del sys.setdefaultencoding
+
+main()
+
+def _test():
+    print "sys.path = ["
+    for dir in sys.path:
+        print "    %r," % (dir,)
+    print "]"
+
+if __name__ == '__main__':
+    _test()

Added: vendor/Python/current/Lib/smtpd.py
===================================================================
--- vendor/Python/current/Lib/smtpd.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/smtpd.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,549 @@
+#! /usr/bin/env python
+"""An RFC 2821 smtp proxy.
+
+Usage: %(program)s [options] [localhost:localport [remotehost:remoteport]]
+
+Options:
+
+    --nosetuid
+    -n
+        This program generally tries to setuid `nobody', unless this flag is
+        set.  The setuid call will fail if this program is not run as root (in
+        which case, use this flag).
+
+    --version
+    -V
+        Print the version number and exit.
+
+    --class classname
+    -c classname
+        Use `classname' as the concrete SMTP proxy class.  Uses `PureProxy' by
+        default.
+
+    --debug
+    -d
+        Turn on debugging prints.
+
+    --help
+    -h
+        Print this message and exit.
+
+Version: %(__version__)s
+
+If localhost is not given then `localhost' is used, and if localport is not
+given then 8025 is used.  If remotehost is not given then `localhost' is used,
+and if remoteport is not given, then 25 is used.
+"""
+
+
+# Overview:
+#
+# This file implements the minimal SMTP protocol as defined in RFC 821.  It
+# has a hierarchy of classes which implement the backend functionality for the
+# smtpd.  A number of classes are provided:
+#
+#   SMTPServer - the base class for the backend.  Raises NotImplementedError
+#   if you try to use it.
+#
+#   DebuggingServer - simply prints each message it receives on stdout.
+#
+#   PureProxy - Proxies all messages to a real smtpd which does final
+#   delivery.  One known problem with this class is that it doesn't handle
+#   SMTP errors from the backend server at all.  This should be fixed
+#   (contributions are welcome!).
+#
+#   MailmanProxy - An experimental hack to work with GNU Mailman
+#   <www.list.org>.  Using this server as your real incoming smtpd, your
+#   mailhost will automatically recognize and accept mail destined to Mailman
+#   lists when those lists are created.  Every message not destined for a list
+#   gets forwarded to a real backend smtpd, as with PureProxy.  Again, errors
+#   are not handled correctly yet.
+#
+# Please note that this script requires Python 2.0
+#
+# Author: Barry Warsaw <barry at python.org>
+#
+# TODO:
+#
+# - support mailbox delivery
+# - alias files
+# - ESMTP
+# - handle error codes from the backend smtpd
+
+import sys
+import os
+import errno
+import getopt
+import time
+import socket
+import asyncore
+import asynchat
+
+__all__ = ["SMTPServer","DebuggingServer","PureProxy","MailmanProxy"]
+
+program = sys.argv[0]
+__version__ = 'Python SMTP proxy version 0.2'
+
+
+class Devnull:
+    def write(self, msg): pass
+    def flush(self): pass
+
+
+DEBUGSTREAM = Devnull()
+NEWLINE = '\n'
+EMPTYSTRING = ''
+COMMASPACE = ', '
+
+
+
+def usage(code, msg=''):
+    print >> sys.stderr, __doc__ % globals()
+    if msg:
+        print >> sys.stderr, msg
+    sys.exit(code)
+
+
+
+class SMTPChannel(asynchat.async_chat):
+    COMMAND = 0
+    DATA = 1
+
+    def __init__(self, server, conn, addr):
+        asynchat.async_chat.__init__(self, conn)
+        self.__server = server
+        self.__conn = conn
+        self.__addr = addr
+        self.__line = []
+        self.__state = self.COMMAND
+        self.__greeting = 0
+        self.__mailfrom = None
+        self.__rcpttos = []
+        self.__data = ''
+        self.__fqdn = socket.getfqdn()
+        self.__peer = conn.getpeername()
+        print >> DEBUGSTREAM, 'Peer:', repr(self.__peer)
+        self.push('220 %s %s' % (self.__fqdn, __version__))
+        self.set_terminator('\r\n')
+
+    # Overrides base class for convenience
+    def push(self, msg):
+        asynchat.async_chat.push(self, msg + '\r\n')
+
+    # Implementation of base class abstract method
+    def collect_incoming_data(self, data):
+        self.__line.append(data)
+
+    # Implementation of base class abstract method
+    def found_terminator(self):
+        line = EMPTYSTRING.join(self.__line)
+        print >> DEBUGSTREAM, 'Data:', repr(line)
+        self.__line = []
+        if self.__state == self.COMMAND:
+            if not line:
+                self.push('500 Error: bad syntax')
+                return
+            method = None
+            i = line.find(' ')
+            if i < 0:
+                command = line.upper()
+                arg = None
+            else:
+                command = line[:i].upper()
+                arg = line[i+1:].strip()
+            method = getattr(self, 'smtp_' + command, None)
+            if not method:
+                self.push('502 Error: command "%s" not implemented' % command)
+                return
+            method(arg)
+            return
+        else:
+            if self.__state != self.DATA:
+                self.push('451 Internal confusion')
+                return
+            # Remove extraneous carriage returns and de-transparency according
+            # to RFC 821, Section 4.5.2.
+            data = []
+            for text in line.split('\r\n'):
+                if text and text[0] == '.':
+                    data.append(text[1:])
+                else:
+                    data.append(text)
+            self.__data = NEWLINE.join(data)
+            status = self.__server.process_message(self.__peer,
+                                                   self.__mailfrom,
+                                                   self.__rcpttos,
+                                                   self.__data)
+            self.__rcpttos = []
+            self.__mailfrom = None
+            self.__state = self.COMMAND
+            self.set_terminator('\r\n')
+            if not status:
+                self.push('250 Ok')
+            else:
+                self.push(status)
+
+    # SMTP and ESMTP commands
+    def smtp_HELO(self, arg):
+        if not arg:
+            self.push('501 Syntax: HELO hostname')
+            return
+        if self.__greeting:
+            self.push('503 Duplicate HELO/EHLO')
+        else:
+            self.__greeting = arg
+            self.push('250 %s' % self.__fqdn)
+
+    def smtp_NOOP(self, arg):
+        if arg:
+            self.push('501 Syntax: NOOP')
+        else:
+            self.push('250 Ok')
+
+    def smtp_QUIT(self, arg):
+        # args is ignored
+        self.push('221 Bye')
+        self.close_when_done()
+
+    # factored
+    def __getaddr(self, keyword, arg):
+        address = None
+        keylen = len(keyword)
+        if arg[:keylen].upper() == keyword:
+            address = arg[keylen:].strip()
+            if not address:
+                pass
+            elif address[0] == '<' and address[-1] == '>' and address != '<>':
+                # Addresses can be in the form <person at dom.com> but watch out
+                # for null address, e.g. <>
+                address = address[1:-1]
+        return address
+
+    def smtp_MAIL(self, arg):
+        print >> DEBUGSTREAM, '===> MAIL', arg
+        address = self.__getaddr('FROM:', arg)
+        if not address:
+            self.push('501 Syntax: MAIL FROM:<address>')
+            return
+        if self.__mailfrom:
+            self.push('503 Error: nested MAIL command')
+            return
+        self.__mailfrom = address
+        print >> DEBUGSTREAM, 'sender:', self.__mailfrom
+        self.push('250 Ok')
+
+    def smtp_RCPT(self, arg):
+        print >> DEBUGSTREAM, '===> RCPT', arg
+        if not self.__mailfrom:
+            self.push('503 Error: need MAIL command')
+            return
+        address = self.__getaddr('TO:', arg)
+        if not address:
+            self.push('501 Syntax: RCPT TO: <address>')
+            return
+        self.__rcpttos.append(address)
+        print >> DEBUGSTREAM, 'recips:', self.__rcpttos
+        self.push('250 Ok')
+
+    def smtp_RSET(self, arg):
+        if arg:
+            self.push('501 Syntax: RSET')
+            return
+        # Resets the sender, recipients, and data, but not the greeting
+        self.__mailfrom = None
+        self.__rcpttos = []
+        self.__data = ''
+        self.__state = self.COMMAND
+        self.push('250 Ok')
+
+    def smtp_DATA(self, arg):
+        if not self.__rcpttos:
+            self.push('503 Error: need RCPT command')
+            return
+        if arg:
+            self.push('501 Syntax: DATA')
+            return
+        self.__state = self.DATA
+        self.set_terminator('\r\n.\r\n')
+        self.push('354 End data with <CR><LF>.<CR><LF>')
+
+
+
+class SMTPServer(asyncore.dispatcher):
+    def __init__(self, localaddr, remoteaddr):
+        self._localaddr = localaddr
+        self._remoteaddr = remoteaddr
+        asyncore.dispatcher.__init__(self)
+        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
+        # try to re-use a server port if possible
+        self.set_reuse_addr()
+        self.bind(localaddr)
+        self.listen(5)
+        print >> DEBUGSTREAM, \
+              '%s started at %s\n\tLocal addr: %s\n\tRemote addr:%s' % (
+            self.__class__.__name__, time.ctime(time.time()),
+            localaddr, remoteaddr)
+
+    def handle_accept(self):
+        conn, addr = self.accept()
+        print >> DEBUGSTREAM, 'Incoming connection from %s' % repr(addr)
+        channel = SMTPChannel(self, conn, addr)
+
+    # API for "doing something useful with the message"
+    def process_message(self, peer, mailfrom, rcpttos, data):
+        """Override this abstract method to handle messages from the client.
+
+        peer is a tuple containing (ipaddr, port) of the client that made the
+        socket connection to our smtp port.
+
+        mailfrom is the raw address the client claims the message is coming
+        from.
+
+        rcpttos is a list of raw addresses the client wishes to deliver the
+        message to.
+
+        data is a string containing the entire full text of the message,
+        headers (if supplied) and all.  It has been `de-transparencied'
+        according to RFC 821, Section 4.5.2.  In other words, a line
+        containing a `.' followed by other text has had the leading dot
+        removed.
+
+        This function should return None, for a normal `250 Ok' response;
+        otherwise it returns the desired response string in RFC 821 format.
+
+        """
+        raise NotImplementedError
+
+
+
+class DebuggingServer(SMTPServer):
+    # Do something with the gathered message
+    def process_message(self, peer, mailfrom, rcpttos, data):
+        inheaders = 1
+        lines = data.split('\n')
+        print '---------- MESSAGE FOLLOWS ----------'
+        for line in lines:
+            # headers first
+            if inheaders and not line:
+                print 'X-Peer:', peer[0]
+                inheaders = 0
+            print line
+        print '------------ END MESSAGE ------------'
+
+
+
+class PureProxy(SMTPServer):
+    def process_message(self, peer, mailfrom, rcpttos, data):
+        lines = data.split('\n')
+        # Look for the last header
+        i = 0
+        for line in lines:
+            if not line:
+                break
+            i += 1
+        lines.insert(i, 'X-Peer: %s' % peer[0])
+        data = NEWLINE.join(lines)
+        refused = self._deliver(mailfrom, rcpttos, data)
+        # TBD: what to do with refused addresses?
+        print >> DEBUGSTREAM, 'we got some refusals:', refused
+
+    def _deliver(self, mailfrom, rcpttos, data):
+        import smtplib
+        refused = {}
+        try:
+            s = smtplib.SMTP()
+            s.connect(self._remoteaddr[0], self._remoteaddr[1])
+            try:
+                refused = s.sendmail(mailfrom, rcpttos, data)
+            finally:
+                s.quit()
+        except smtplib.SMTPRecipientsRefused, e:
+            print >> DEBUGSTREAM, 'got SMTPRecipientsRefused'
+            refused = e.recipients
+        except (socket.error, smtplib.SMTPException), e:
+            print >> DEBUGSTREAM, 'got', e.__class__
+            # All recipients were refused.  If the exception had an associated
+            # error code, use it.  Otherwise,fake it with a non-triggering
+            # exception code.
+            errcode = getattr(e, 'smtp_code', -1)
+            errmsg = getattr(e, 'smtp_error', 'ignore')
+            for r in rcpttos:
+                refused[r] = (errcode, errmsg)
+        return refused
+
+
+
+class MailmanProxy(PureProxy):
+    def process_message(self, peer, mailfrom, rcpttos, data):
+        from cStringIO import StringIO
+        from Mailman import Utils
+        from Mailman import Message
+        from Mailman import MailList
+        # If the message is to a Mailman mailing list, then we'll invoke the
+        # Mailman script directly, without going through the real smtpd.
+        # Otherwise we'll forward it to the local proxy for disposition.
+        listnames = []
+        for rcpt in rcpttos:
+            local = rcpt.lower().split('@')[0]
+            # We allow the following variations on the theme
+            #   listname
+            #   listname-admin
+            #   listname-owner
+            #   listname-request
+            #   listname-join
+            #   listname-leave
+            parts = local.split('-')
+            if len(parts) > 2:
+                continue
+            listname = parts[0]
+            if len(parts) == 2:
+                command = parts[1]
+            else:
+                command = ''
+            if not Utils.list_exists(listname) or command not in (
+                    '', 'admin', 'owner', 'request', 'join', 'leave'):
+                continue
+            listnames.append((rcpt, listname, command))
+        # Remove all list recipients from rcpttos and forward what we're not
+        # going to take care of ourselves.  Linear removal should be fine
+        # since we don't expect a large number of recipients.
+        for rcpt, listname, command in listnames:
+            rcpttos.remove(rcpt)
+        # If there's any non-list destined recipients left,
+        print >> DEBUGSTREAM, 'forwarding recips:', ' '.join(rcpttos)
+        if rcpttos:
+            refused = self._deliver(mailfrom, rcpttos, data)
+            # TBD: what to do with refused addresses?
+            print >> DEBUGSTREAM, 'we got refusals:', refused
+        # Now deliver directly to the list commands
+        mlists = {}
+        s = StringIO(data)
+        msg = Message.Message(s)
+        # These headers are required for the proper execution of Mailman.  All
+        # MTAs in existance seem to add these if the original message doesn't
+        # have them.
+        if not msg.getheader('from'):
+            msg['From'] = mailfrom
+        if not msg.getheader('date'):
+            msg['Date'] = time.ctime(time.time())
+        for rcpt, listname, command in listnames:
+            print >> DEBUGSTREAM, 'sending message to', rcpt
+            mlist = mlists.get(listname)
+            if not mlist:
+                mlist = MailList.MailList(listname, lock=0)
+                mlists[listname] = mlist
+            # dispatch on the type of command
+            if command == '':
+                # post
+                msg.Enqueue(mlist, tolist=1)
+            elif command == 'admin':
+                msg.Enqueue(mlist, toadmin=1)
+            elif command == 'owner':
+                msg.Enqueue(mlist, toowner=1)
+            elif command == 'request':
+                msg.Enqueue(mlist, torequest=1)
+            elif command in ('join', 'leave'):
+                # TBD: this is a hack!
+                if command == 'join':
+                    msg['Subject'] = 'subscribe'
+                else:
+                    msg['Subject'] = 'unsubscribe'
+                msg.Enqueue(mlist, torequest=1)
+
+
+
+class Options:
+    setuid = 1
+    classname = 'PureProxy'
+
+
+
+def parseargs():
+    global DEBUGSTREAM
+    try:
+        opts, args = getopt.getopt(
+            sys.argv[1:], 'nVhc:d',
+            ['class=', 'nosetuid', 'version', 'help', 'debug'])
+    except getopt.error, e:
+        usage(1, e)
+
+    options = Options()
+    for opt, arg in opts:
+        if opt in ('-h', '--help'):
+            usage(0)
+        elif opt in ('-V', '--version'):
+            print >> sys.stderr, __version__
+            sys.exit(0)
+        elif opt in ('-n', '--nosetuid'):
+            options.setuid = 0
+        elif opt in ('-c', '--class'):
+            options.classname = arg
+        elif opt in ('-d', '--debug'):
+            DEBUGSTREAM = sys.stderr
+
+    # parse the rest of the arguments
+    if len(args) < 1:
+        localspec = 'localhost:8025'
+        remotespec = 'localhost:25'
+    elif len(args) < 2:
+        localspec = args[0]
+        remotespec = 'localhost:25'
+    elif len(args) < 3:
+        localspec = args[0]
+        remotespec = args[1]
+    else:
+        usage(1, 'Invalid arguments: %s' % COMMASPACE.join(args))
+
+    # split into host/port pairs
+    i = localspec.find(':')
+    if i < 0:
+        usage(1, 'Bad local spec: %s' % localspec)
+    options.localhost = localspec[:i]
+    try:
+        options.localport = int(localspec[i+1:])
+    except ValueError:
+        usage(1, 'Bad local port: %s' % localspec)
+    i = remotespec.find(':')
+    if i < 0:
+        usage(1, 'Bad remote spec: %s' % remotespec)
+    options.remotehost = remotespec[:i]
+    try:
+        options.remoteport = int(remotespec[i+1:])
+    except ValueError:
+        usage(1, 'Bad remote port: %s' % remotespec)
+    return options
+
+
+
+if __name__ == '__main__':
+    options = parseargs()
+    # Become nobody
+    if options.setuid:
+        try:
+            import pwd
+        except ImportError:
+            print >> sys.stderr, \
+                  'Cannot import module "pwd"; try running with -n option.'
+            sys.exit(1)
+        nobody = pwd.getpwnam('nobody')[2]
+        try:
+            os.setuid(nobody)
+        except OSError, e:
+            if e.errno != errno.EPERM: raise
+            print >> sys.stderr, \
+                  'Cannot setuid "nobody"; try running with -n option.'
+            sys.exit(1)
+    classname = options.classname
+    if "." in classname:
+        lastdot = classname.rfind(".")
+        mod = __import__(classname[:lastdot], globals(), locals(), [""])
+        classname = classname[lastdot+1:]
+    else:
+        import __main__ as mod
+    class_ = getattr(mod, classname)
+    proxy = class_((options.localhost, options.localport),
+                   (options.remotehost, options.remoteport))
+    try:
+        asyncore.loop()
+    except KeyboardInterrupt:
+        pass


Property changes on: vendor/Python/current/Lib/smtpd.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/smtplib.py
===================================================================
--- vendor/Python/current/Lib/smtplib.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/smtplib.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,743 @@
+#! /usr/bin/env python
+
+'''SMTP/ESMTP client class.
+
+This should follow RFC 821 (SMTP), RFC 1869 (ESMTP), RFC 2554 (SMTP
+Authentication) and RFC 2487 (Secure SMTP over TLS).
+
+Notes:
+
+Please remember, when doing ESMTP, that the names of the SMTP service
+extensions are NOT the same thing as the option keywords for the RCPT
+and MAIL commands!
+
+Example:
+
+  >>> import smtplib
+  >>> s=smtplib.SMTP("localhost")
+  >>> print s.help()
+  This is Sendmail version 8.8.4
+  Topics:
+      HELO    EHLO    MAIL    RCPT    DATA
+      RSET    NOOP    QUIT    HELP    VRFY
+      EXPN    VERB    ETRN    DSN
+  For more info use "HELP <topic>".
+  To report bugs in the implementation send email to
+      sendmail-bugs at sendmail.org.
+  For local information send email to Postmaster at your site.
+  End of HELP info
+  >>> s.putcmd("vrfy","someone at here")
+  >>> s.getreply()
+  (250, "Somebody OverHere <somebody at here.my.org>")
+  >>> s.quit()
+'''
+
+# Author: The Dragon De Monsyne <dragondm at integral.org>
+# ESMTP support, test code and doc fixes added by
+#     Eric S. Raymond <esr at thyrsus.com>
+# Better RFC 821 compliance (MAIL and RCPT, and CRLF in data)
+#     by Carey Evans <c.evans at clear.net.nz>, for picky mail servers.
+# RFC 2554 (authentication) support by Gerhard Haering <gerhard at bigfoot.de>.
+#
+# This was modified from the Python 1.5 library HTTP lib.
+
+import socket
+import re
+import email.Utils
+import base64
+import hmac
+from email.base64MIME import encode as encode_base64
+from sys import stderr
+
+__all__ = ["SMTPException","SMTPServerDisconnected","SMTPResponseException",
+           "SMTPSenderRefused","SMTPRecipientsRefused","SMTPDataError",
+           "SMTPConnectError","SMTPHeloError","SMTPAuthenticationError",
+           "quoteaddr","quotedata","SMTP"]
+
+SMTP_PORT = 25
+CRLF="\r\n"
+
+OLDSTYLE_AUTH = re.compile(r"auth=(.*)", re.I)
+
+# Exception classes used by this module.
+class SMTPException(Exception):
+    """Base class for all exceptions raised by this module."""
+
+class SMTPServerDisconnected(SMTPException):
+    """Not connected to any SMTP server.
+
+    This exception is raised when the server unexpectedly disconnects,
+    or when an attempt is made to use the SMTP instance before
+    connecting it to a server.
+    """
+
+class SMTPResponseException(SMTPException):
+    """Base class for all exceptions that include an SMTP error code.
+
+    These exceptions are generated in some instances when the SMTP
+    server returns an error code.  The error code is stored in the
+    `smtp_code' attribute of the error, and the `smtp_error' attribute
+    is set to the error message.
+    """
+
+    def __init__(self, code, msg):
+        self.smtp_code = code
+        self.smtp_error = msg
+        self.args = (code, msg)
+
+class SMTPSenderRefused(SMTPResponseException):
+    """Sender address refused.
+
+    In addition to the attributes set by on all SMTPResponseException
+    exceptions, this sets `sender' to the string that the SMTP refused.
+    """
+
+    def __init__(self, code, msg, sender):
+        self.smtp_code = code
+        self.smtp_error = msg
+        self.sender = sender
+        self.args = (code, msg, sender)
+
+class SMTPRecipientsRefused(SMTPException):
+    """All recipient addresses refused.
+
+    The errors for each recipient are accessible through the attribute
+    'recipients', which is a dictionary of exactly the same sort as
+    SMTP.sendmail() returns.
+    """
+
+    def __init__(self, recipients):
+        self.recipients = recipients
+        self.args = ( recipients,)
+
+
+class SMTPDataError(SMTPResponseException):
+    """The SMTP server didn't accept the data."""
+
+class SMTPConnectError(SMTPResponseException):
+    """Error during connection establishment."""
+
+class SMTPHeloError(SMTPResponseException):
+    """The server refused our HELO reply."""
+
+class SMTPAuthenticationError(SMTPResponseException):
+    """Authentication error.
+
+    Most probably the server didn't accept the username/password
+    combination provided.
+    """
+
+class SSLFakeSocket:
+    """A fake socket object that really wraps a SSLObject.
+
+    It only supports what is needed in smtplib.
+    """
+    def __init__(self, realsock, sslobj):
+        self.realsock = realsock
+        self.sslobj = sslobj
+
+    def send(self, str):
+        self.sslobj.write(str)
+        return len(str)
+
+    sendall = send
+
+    def close(self):
+        self.realsock.close()
+
+class SSLFakeFile:
+    """A fake file like object that really wraps a SSLObject.
+
+    It only supports what is needed in smtplib.
+    """
+    def __init__(self, sslobj):
+        self.sslobj = sslobj
+
+    def readline(self):
+        str = ""
+        chr = None
+        while chr != "\n":
+            chr = self.sslobj.read(1)
+            str += chr
+        return str
+
+    def close(self):
+        pass
+
+def quoteaddr(addr):
+    """Quote a subset of the email addresses defined by RFC 821.
+
+    Should be able to handle anything rfc822.parseaddr can handle.
+    """
+    m = (None, None)
+    try:
+        m = email.Utils.parseaddr(addr)[1]
+    except AttributeError:
+        pass
+    if m == (None, None): # Indicates parse failure or AttributeError
+        # something weird here.. punt -ddm
+        return "<%s>" % addr
+    elif m is None:
+        # the sender wants an empty return address
+        return "<>"
+    else:
+        return "<%s>" % m
+
+def quotedata(data):
+    """Quote data for email.
+
+    Double leading '.', and change Unix newline '\\n', or Mac '\\r' into
+    Internet CRLF end-of-line.
+    """
+    return re.sub(r'(?m)^\.', '..',
+        re.sub(r'(?:\r\n|\n|\r(?!\n))', CRLF, data))
+
+
+class SMTP:
+    """This class manages a connection to an SMTP or ESMTP server.
+    SMTP Objects:
+        SMTP objects have the following attributes:
+            helo_resp
+                This is the message given by the server in response to the
+                most recent HELO command.
+
+            ehlo_resp
+                This is the message given by the server in response to the
+                most recent EHLO command. This is usually multiline.
+
+            does_esmtp
+                This is a True value _after you do an EHLO command_, if the
+                server supports ESMTP.
+
+            esmtp_features
+                This is a dictionary, which, if the server supports ESMTP,
+                will _after you do an EHLO command_, contain the names of the
+                SMTP service extensions this server supports, and their
+                parameters (if any).
+
+                Note, all extension names are mapped to lower case in the
+                dictionary.
+
+        See each method's docstrings for details.  In general, there is a
+        method of the same name to perform each SMTP command.  There is also a
+        method called 'sendmail' that will do an entire mail transaction.
+        """
+    debuglevel = 0
+    file = None
+    helo_resp = None
+    ehlo_resp = None
+    does_esmtp = 0
+
+    def __init__(self, host = '', port = 0, local_hostname = None):
+        """Initialize a new instance.
+
+        If specified, `host' is the name of the remote host to which to
+        connect.  If specified, `port' specifies the port to which to connect.
+        By default, smtplib.SMTP_PORT is used.  An SMTPConnectError is raised
+        if the specified `host' doesn't respond correctly.  If specified,
+        `local_hostname` is used as the FQDN of the local host.  By default,
+        the local hostname is found using socket.getfqdn().
+
+        """
+        self.esmtp_features = {}
+        if host:
+            (code, msg) = self.connect(host, port)
+            if code != 220:
+                raise SMTPConnectError(code, msg)
+        if local_hostname is not None:
+            self.local_hostname = local_hostname
+        else:
+            # RFC 2821 says we should use the fqdn in the EHLO/HELO verb, and
+            # if that can't be calculated, that we should use a domain literal
+            # instead (essentially an encoded IP address like [A.B.C.D]).
+            fqdn = socket.getfqdn()
+            if '.' in fqdn:
+                self.local_hostname = fqdn
+            else:
+                # We can't find an fqdn hostname, so use a domain literal
+                addr = '127.0.0.1'
+                try:
+                    addr = socket.gethostbyname(socket.gethostname())
+                except socket.gaierror:
+                    pass
+                self.local_hostname = '[%s]' % addr
+
+    def set_debuglevel(self, debuglevel):
+        """Set the debug output level.
+
+        A non-false value results in debug messages for connection and for all
+        messages sent to and received from the server.
+
+        """
+        self.debuglevel = debuglevel
+
+    def connect(self, host='localhost', port = 0):
+        """Connect to a host on a given port.
+
+        If the hostname ends with a colon (`:') followed by a number, and
+        there is no port specified, that suffix will be stripped off and the
+        number interpreted as the port number to use.
+
+        Note: This method is automatically invoked by __init__, if a host is
+        specified during instantiation.
+
+        """
+        if not port and (host.find(':') == host.rfind(':')):
+            i = host.rfind(':')
+            if i >= 0:
+                host, port = host[:i], host[i+1:]
+                try: port = int(port)
+                except ValueError:
+                    raise socket.error, "nonnumeric port"
+        if not port: port = SMTP_PORT
+        if self.debuglevel > 0: print>>stderr, 'connect:', (host, port)
+        msg = "getaddrinfo returns an empty list"
+        self.sock = None
+        for res in socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM):
+            af, socktype, proto, canonname, sa = res
+            try:
+                self.sock = socket.socket(af, socktype, proto)
+                if self.debuglevel > 0: print>>stderr, 'connect:', sa
+                self.sock.connect(sa)
+            except socket.error, msg:
+                if self.debuglevel > 0: print>>stderr, 'connect fail:', msg
+                if self.sock:
+                    self.sock.close()
+                self.sock = None
+                continue
+            break
+        if not self.sock:
+            raise socket.error, msg
+        (code, msg) = self.getreply()
+        if self.debuglevel > 0: print>>stderr, "connect:", msg
+        return (code, msg)
+
+    def send(self, str):
+        """Send `str' to the server."""
+        if self.debuglevel > 0: print>>stderr, 'send:', repr(str)
+        if self.sock:
+            try:
+                self.sock.sendall(str)
+            except socket.error:
+                self.close()
+                raise SMTPServerDisconnected('Server not connected')
+        else:
+            raise SMTPServerDisconnected('please run connect() first')
+
+    def putcmd(self, cmd, args=""):
+        """Send a command to the server."""
+        if args == "":
+            str = '%s%s' % (cmd, CRLF)
+        else:
+            str = '%s %s%s' % (cmd, args, CRLF)
+        self.send(str)
+
+    def getreply(self):
+        """Get a reply from the server.
+
+        Returns a tuple consisting of:
+
+          - server response code (e.g. '250', or such, if all goes well)
+            Note: returns -1 if it can't read response code.
+
+          - server response string corresponding to response code (multiline
+            responses are converted to a single, multiline string).
+
+        Raises SMTPServerDisconnected if end-of-file is reached.
+        """
+        resp=[]
+        if self.file is None:
+            self.file = self.sock.makefile('rb')
+        while 1:
+            line = self.file.readline()
+            if line == '':
+                self.close()
+                raise SMTPServerDisconnected("Connection unexpectedly closed")
+            if self.debuglevel > 0: print>>stderr, 'reply:', repr(line)
+            resp.append(line[4:].strip())
+            code=line[:3]
+            # Check that the error code is syntactically correct.
+            # Don't attempt to read a continuation line if it is broken.
+            try:
+                errcode = int(code)
+            except ValueError:
+                errcode = -1
+                break
+            # Check if multiline response.
+            if line[3:4]!="-":
+                break
+
+        errmsg = "\n".join(resp)
+        if self.debuglevel > 0:
+            print>>stderr, 'reply: retcode (%s); Msg: %s' % (errcode,errmsg)
+        return errcode, errmsg
+
+    def docmd(self, cmd, args=""):
+        """Send a command, and return its response code."""
+        self.putcmd(cmd,args)
+        return self.getreply()
+
+    # std smtp commands
+    def helo(self, name=''):
+        """SMTP 'helo' command.
+        Hostname to send for this command defaults to the FQDN of the local
+        host.
+        """
+        self.putcmd("helo", name or self.local_hostname)
+        (code,msg)=self.getreply()
+        self.helo_resp=msg
+        return (code,msg)
+
+    def ehlo(self, name=''):
+        """ SMTP 'ehlo' command.
+        Hostname to send for this command defaults to the FQDN of the local
+        host.
+        """
+        self.esmtp_features = {}
+        self.putcmd("ehlo", name or self.local_hostname)
+        (code,msg)=self.getreply()
+        # According to RFC1869 some (badly written)
+        # MTA's will disconnect on an ehlo. Toss an exception if
+        # that happens -ddm
+        if code == -1 and len(msg) == 0:
+            self.close()
+            raise SMTPServerDisconnected("Server not connected")
+        self.ehlo_resp=msg
+        if code != 250:
+            return (code,msg)
+        self.does_esmtp=1
+        #parse the ehlo response -ddm
+        resp=self.ehlo_resp.split('\n')
+        del resp[0]
+        for each in resp:
+            # To be able to communicate with as many SMTP servers as possible,
+            # we have to take the old-style auth advertisement into account,
+            # because:
+            # 1) Else our SMTP feature parser gets confused.
+            # 2) There are some servers that only advertise the auth methods we
+            #    support using the old style.
+            auth_match = OLDSTYLE_AUTH.match(each)
+            if auth_match:
+                # This doesn't remove duplicates, but that's no problem
+                self.esmtp_features["auth"] = self.esmtp_features.get("auth", "") \
+                        + " " + auth_match.groups(0)[0]
+                continue
+
+            # RFC 1869 requires a space between ehlo keyword and parameters.
+            # It's actually stricter, in that only spaces are allowed between
+            # parameters, but were not going to check for that here.  Note
+            # that the space isn't present if there are no parameters.
+            m=re.match(r'(?P<feature>[A-Za-z0-9][A-Za-z0-9\-]*) ?',each)
+            if m:
+                feature=m.group("feature").lower()
+                params=m.string[m.end("feature"):].strip()
+                if feature == "auth":
+                    self.esmtp_features[feature] = self.esmtp_features.get(feature, "") \
+                            + " " + params
+                else:
+                    self.esmtp_features[feature]=params
+        return (code,msg)
+
+    def has_extn(self, opt):
+        """Does the server support a given SMTP service extension?"""
+        return opt.lower() in self.esmtp_features
+
+    def help(self, args=''):
+        """SMTP 'help' command.
+        Returns help text from server."""
+        self.putcmd("help", args)
+        return self.getreply()[1]
+
+    def rset(self):
+        """SMTP 'rset' command -- resets session."""
+        return self.docmd("rset")
+
+    def noop(self):
+        """SMTP 'noop' command -- doesn't do anything :>"""
+        return self.docmd("noop")
+
+    def mail(self,sender,options=[]):
+        """SMTP 'mail' command -- begins mail xfer session."""
+        optionlist = ''
+        if options and self.does_esmtp:
+            optionlist = ' ' + ' '.join(options)
+        self.putcmd("mail", "FROM:%s%s" % (quoteaddr(sender) ,optionlist))
+        return self.getreply()
+
+    def rcpt(self,recip,options=[]):
+        """SMTP 'rcpt' command -- indicates 1 recipient for this mail."""
+        optionlist = ''
+        if options and self.does_esmtp:
+            optionlist = ' ' + ' '.join(options)
+        self.putcmd("rcpt","TO:%s%s" % (quoteaddr(recip),optionlist))
+        return self.getreply()
+
+    def data(self,msg):
+        """SMTP 'DATA' command -- sends message data to server.
+
+        Automatically quotes lines beginning with a period per rfc821.
+        Raises SMTPDataError if there is an unexpected reply to the
+        DATA command; the return value from this method is the final
+        response code received when the all data is sent.
+        """
+        self.putcmd("data")
+        (code,repl)=self.getreply()
+        if self.debuglevel >0 : print>>stderr, "data:", (code,repl)
+        if code != 354:
+            raise SMTPDataError(code,repl)
+        else:
+            q = quotedata(msg)
+            if q[-2:] != CRLF:
+                q = q + CRLF
+            q = q + "." + CRLF
+            self.send(q)
+            (code,msg)=self.getreply()
+            if self.debuglevel >0 : print>>stderr, "data:", (code,msg)
+            return (code,msg)
+
+    def verify(self, address):
+        """SMTP 'verify' command -- checks for address validity."""
+        self.putcmd("vrfy", quoteaddr(address))
+        return self.getreply()
+    # a.k.a.
+    vrfy=verify
+
+    def expn(self, address):
+        """SMTP 'verify' command -- checks for address validity."""
+        self.putcmd("expn", quoteaddr(address))
+        return self.getreply()
+
+    # some useful methods
+
+    def login(self, user, password):
+        """Log in on an SMTP server that requires authentication.
+
+        The arguments are:
+            - user:     The user name to authenticate with.
+            - password: The password for the authentication.
+
+        If there has been no previous EHLO or HELO command this session, this
+        method tries ESMTP EHLO first.
+
+        This method will return normally if the authentication was successful.
+
+        This method may raise the following exceptions:
+
+         SMTPHeloError            The server didn't reply properly to
+                                  the helo greeting.
+         SMTPAuthenticationError  The server didn't accept the username/
+                                  password combination.
+         SMTPException            No suitable authentication method was
+                                  found.
+        """
+
+        def encode_cram_md5(challenge, user, password):
+            challenge = base64.decodestring(challenge)
+            response = user + " " + hmac.HMAC(password, challenge).hexdigest()
+            return encode_base64(response, eol="")
+
+        def encode_plain(user, password):
+            return encode_base64("\0%s\0%s" % (user, password), eol="")
+
+
+        AUTH_PLAIN = "PLAIN"
+        AUTH_CRAM_MD5 = "CRAM-MD5"
+        AUTH_LOGIN = "LOGIN"
+
+        if self.helo_resp is None and self.ehlo_resp is None:
+            if not (200 <= self.ehlo()[0] <= 299):
+                (code, resp) = self.helo()
+                if not (200 <= code <= 299):
+                    raise SMTPHeloError(code, resp)
+
+        if not self.has_extn("auth"):
+            raise SMTPException("SMTP AUTH extension not supported by server.")
+
+        # Authentication methods the server supports:
+        authlist = self.esmtp_features["auth"].split()
+
+        # List of authentication methods we support: from preferred to
+        # less preferred methods. Except for the purpose of testing the weaker
+        # ones, we prefer stronger methods like CRAM-MD5:
+        preferred_auths = [AUTH_CRAM_MD5, AUTH_PLAIN, AUTH_LOGIN]
+
+        # Determine the authentication method we'll use
+        authmethod = None
+        for method in preferred_auths:
+            if method in authlist:
+                authmethod = method
+                break
+
+        if authmethod == AUTH_CRAM_MD5:
+            (code, resp) = self.docmd("AUTH", AUTH_CRAM_MD5)
+            if code == 503:
+                # 503 == 'Error: already authenticated'
+                return (code, resp)
+            (code, resp) = self.docmd(encode_cram_md5(resp, user, password))
+        elif authmethod == AUTH_PLAIN:
+            (code, resp) = self.docmd("AUTH",
+                AUTH_PLAIN + " " + encode_plain(user, password))
+        elif authmethod == AUTH_LOGIN:
+            (code, resp) = self.docmd("AUTH",
+                "%s %s" % (AUTH_LOGIN, encode_base64(user, eol="")))
+            if code != 334:
+                raise SMTPAuthenticationError(code, resp)
+            (code, resp) = self.docmd(encode_base64(password, eol=""))
+        elif authmethod is None:
+            raise SMTPException("No suitable authentication method found.")
+        if code not in (235, 503):
+            # 235 == 'Authentication successful'
+            # 503 == 'Error: already authenticated'
+            raise SMTPAuthenticationError(code, resp)
+        return (code, resp)
+
+    def starttls(self, keyfile = None, certfile = None):
+        """Puts the connection to the SMTP server into TLS mode.
+
+        If the server supports TLS, this will encrypt the rest of the SMTP
+        session. If you provide the keyfile and certfile parameters,
+        the identity of the SMTP server and client can be checked. This,
+        however, depends on whether the socket module really checks the
+        certificates.
+        """
+        (resp, reply) = self.docmd("STARTTLS")
+        if resp == 220:
+            sslobj = socket.ssl(self.sock, keyfile, certfile)
+            self.sock = SSLFakeSocket(self.sock, sslobj)
+            self.file = SSLFakeFile(sslobj)
+        return (resp, reply)
+
+    def sendmail(self, from_addr, to_addrs, msg, mail_options=[],
+                 rcpt_options=[]):
+        """This command performs an entire mail transaction.
+
+        The arguments are:
+            - from_addr    : The address sending this mail.
+            - to_addrs     : A list of addresses to send this mail to.  A bare
+                             string will be treated as a list with 1 address.
+            - msg          : The message to send.
+            - mail_options : List of ESMTP options (such as 8bitmime) for the
+                             mail command.
+            - rcpt_options : List of ESMTP options (such as DSN commands) for
+                             all the rcpt commands.
+
+        If there has been no previous EHLO or HELO command this session, this
+        method tries ESMTP EHLO first.  If the server does ESMTP, message size
+        and each of the specified options will be passed to it.  If EHLO
+        fails, HELO will be tried and ESMTP options suppressed.
+
+        This method will return normally if the mail is accepted for at least
+        one recipient.  It returns a dictionary, with one entry for each
+        recipient that was refused.  Each entry contains a tuple of the SMTP
+        error code and the accompanying error message sent by the server.
+
+        This method may raise the following exceptions:
+
+         SMTPHeloError          The server didn't reply properly to
+                                the helo greeting.
+         SMTPRecipientsRefused  The server rejected ALL recipients
+                                (no mail was sent).
+         SMTPSenderRefused      The server didn't accept the from_addr.
+         SMTPDataError          The server replied with an unexpected
+                                error code (other than a refusal of
+                                a recipient).
+
+        Note: the connection will be open even after an exception is raised.
+
+        Example:
+
+         >>> import smtplib
+         >>> s=smtplib.SMTP("localhost")
+         >>> tolist=["one at one.org","two at two.org","three at three.org","four at four.org"]
+         >>> msg = '''\\
+         ... From: Me at my.org
+         ... Subject: testin'...
+         ...
+         ... This is a test '''
+         >>> s.sendmail("me at my.org",tolist,msg)
+         { "three at three.org" : ( 550 ,"User unknown" ) }
+         >>> s.quit()
+
+        In the above example, the message was accepted for delivery to three
+        of the four addresses, and one was rejected, with the error code
+        550.  If all addresses are accepted, then the method will return an
+        empty dictionary.
+
+        """
+        if self.helo_resp is None and self.ehlo_resp is None:
+            if not (200 <= self.ehlo()[0] <= 299):
+                (code,resp) = self.helo()
+                if not (200 <= code <= 299):
+                    raise SMTPHeloError(code, resp)
+        esmtp_opts = []
+        if self.does_esmtp:
+            # Hmmm? what's this? -ddm
+            # self.esmtp_features['7bit']=""
+            if self.has_extn('size'):
+                esmtp_opts.append("size=%d" % len(msg))
+            for option in mail_options:
+                esmtp_opts.append(option)
+
+        (code,resp) = self.mail(from_addr, esmtp_opts)
+        if code != 250:
+            self.rset()
+            raise SMTPSenderRefused(code, resp, from_addr)
+        senderrs={}
+        if isinstance(to_addrs, basestring):
+            to_addrs = [to_addrs]
+        for each in to_addrs:
+            (code,resp)=self.rcpt(each, rcpt_options)
+            if (code != 250) and (code != 251):
+                senderrs[each]=(code,resp)
+        if len(senderrs)==len(to_addrs):
+            # the server refused all our recipients
+            self.rset()
+            raise SMTPRecipientsRefused(senderrs)
+        (code,resp) = self.data(msg)
+        if code != 250:
+            self.rset()
+            raise SMTPDataError(code, resp)
+        #if we got here then somebody got our mail
+        return senderrs
+
+
+    def close(self):
+        """Close the connection to the SMTP server."""
+        if self.file:
+            self.file.close()
+        self.file = None
+        if self.sock:
+            self.sock.close()
+        self.sock = None
+
+
+    def quit(self):
+        """Terminate the SMTP session."""
+        self.docmd("quit")
+        self.close()
+
+
+# Test the sendmail method, which tests most of the others.
+# Note: This always sends to localhost.
+if __name__ == '__main__':
+    import sys
+
+    def prompt(prompt):
+        sys.stdout.write(prompt + ": ")
+        return sys.stdin.readline().strip()
+
+    fromaddr = prompt("From")
+    toaddrs  = prompt("To").split(',')
+    print "Enter message, end with ^D:"
+    msg = ''
+    while 1:
+        line = sys.stdin.readline()
+        if not line:
+            break
+        msg = msg + line
+    print "Message length is %d" % len(msg)
+
+    server = SMTP('localhost')
+    server.set_debuglevel(1)
+    server.sendmail(fromaddr, toaddrs, msg)
+    server.quit()


Property changes on: vendor/Python/current/Lib/smtplib.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/sndhdr.py
===================================================================
--- vendor/Python/current/Lib/sndhdr.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/sndhdr.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,228 @@
+"""Routines to help recognizing sound files.
+
+Function whathdr() recognizes various types of sound file headers.
+It understands almost all headers that SOX can decode.
+
+The return tuple contains the following items, in this order:
+- file type (as SOX understands it)
+- sampling rate (0 if unknown or hard to decode)
+- number of channels (0 if unknown or hard to decode)
+- number of frames in the file (-1 if unknown or hard to decode)
+- number of bits/sample, or 'U' for U-LAW, or 'A' for A-LAW
+
+If the file doesn't have a recognizable type, it returns None.
+If the file can't be opened, IOError is raised.
+
+To compute the total time, divide the number of frames by the
+sampling rate (a frame contains a sample for each channel).
+
+Function what() calls whathdr().  (It used to also use some
+heuristics for raw data, but this doesn't work very well.)
+
+Finally, the function test() is a simple main program that calls
+what() for all files mentioned on the argument list.  For directory
+arguments it calls what() for all files in that directory.  Default
+argument is "." (testing all files in the current directory).  The
+option -r tells it to recurse down directories found inside
+explicitly given directories.
+"""
+
+# The file structure is top-down except that the test program and its
+# subroutine come last.
+
+__all__ = ["what","whathdr"]
+
+def what(filename):
+    """Guess the type of a sound file"""
+    res = whathdr(filename)
+    return res
+
+
+def whathdr(filename):
+    """Recognize sound headers"""
+    f = open(filename, 'rb')
+    h = f.read(512)
+    for tf in tests:
+        res = tf(h, f)
+        if res:
+            return res
+    return None
+
+
+#-----------------------------------#
+# Subroutines per sound header type #
+#-----------------------------------#
+
+tests = []
+
+def test_aifc(h, f):
+    import aifc
+    if h[:4] != 'FORM':
+        return None
+    if h[8:12] == 'AIFC':
+        fmt = 'aifc'
+    elif h[8:12] == 'AIFF':
+        fmt = 'aiff'
+    else:
+        return None
+    f.seek(0)
+    try:
+        a = aifc.openfp(f, 'r')
+    except (EOFError, aifc.Error):
+        return None
+    return (fmt, a.getframerate(), a.getnchannels(), \
+            a.getnframes(), 8*a.getsampwidth())
+
+tests.append(test_aifc)
+
+
+def test_au(h, f):
+    if h[:4] == '.snd':
+        f = get_long_be
+    elif h[:4] in ('\0ds.', 'dns.'):
+        f = get_long_le
+    else:
+        return None
+    type = 'au'
+    hdr_size = f(h[4:8])
+    data_size = f(h[8:12])
+    encoding = f(h[12:16])
+    rate = f(h[16:20])
+    nchannels = f(h[20:24])
+    sample_size = 1 # default
+    if encoding == 1:
+        sample_bits = 'U'
+    elif encoding == 2:
+        sample_bits = 8
+    elif encoding == 3:
+        sample_bits = 16
+        sample_size = 2
+    else:
+        sample_bits = '?'
+    frame_size = sample_size * nchannels
+    return type, rate, nchannels, data_size/frame_size, sample_bits
+
+tests.append(test_au)
+
+
+def test_hcom(h, f):
+    if h[65:69] != 'FSSD' or h[128:132] != 'HCOM':
+        return None
+    divisor = get_long_be(h[128+16:128+20])
+    return 'hcom', 22050/divisor, 1, -1, 8
+
+tests.append(test_hcom)
+
+
+def test_voc(h, f):
+    if h[:20] != 'Creative Voice File\032':
+        return None
+    sbseek = get_short_le(h[20:22])
+    rate = 0
+    if 0 <= sbseek < 500 and h[sbseek] == '\1':
+        ratecode = ord(h[sbseek+4])
+        rate = int(1000000.0 / (256 - ratecode))
+    return 'voc', rate, 1, -1, 8
+
+tests.append(test_voc)
+
+
+def test_wav(h, f):
+    # 'RIFF' <len> 'WAVE' 'fmt ' <len>
+    if h[:4] != 'RIFF' or h[8:12] != 'WAVE' or h[12:16] != 'fmt ':
+        return None
+    style = get_short_le(h[20:22])
+    nchannels = get_short_le(h[22:24])
+    rate = get_long_le(h[24:28])
+    sample_bits = get_short_le(h[34:36])
+    return 'wav', rate, nchannels, -1, sample_bits
+
+tests.append(test_wav)
+
+
+def test_8svx(h, f):
+    if h[:4] != 'FORM' or h[8:12] != '8SVX':
+        return None
+    # Should decode it to get #channels -- assume always 1
+    return '8svx', 0, 1, 0, 8
+
+tests.append(test_8svx)
+
+
+def test_sndt(h, f):
+    if h[:5] == 'SOUND':
+        nsamples = get_long_le(h[8:12])
+        rate = get_short_le(h[20:22])
+        return 'sndt', rate, 1, nsamples, 8
+
+tests.append(test_sndt)
+
+
+def test_sndr(h, f):
+    if h[:2] == '\0\0':
+        rate = get_short_le(h[2:4])
+        if 4000 <= rate <= 25000:
+            return 'sndr', rate, 1, -1, 8
+
+tests.append(test_sndr)
+
+
+#---------------------------------------------#
+# Subroutines to extract numbers from strings #
+#---------------------------------------------#
+
+def get_long_be(s):
+    return (ord(s[0])<<24) | (ord(s[1])<<16) | (ord(s[2])<<8) | ord(s[3])
+
+def get_long_le(s):
+    return (ord(s[3])<<24) | (ord(s[2])<<16) | (ord(s[1])<<8) | ord(s[0])
+
+def get_short_be(s):
+    return (ord(s[0])<<8) | ord(s[1])
+
+def get_short_le(s):
+    return (ord(s[1])<<8) | ord(s[0])
+
+
+#--------------------#
+# Small test program #
+#--------------------#
+
+def test():
+    import sys
+    recursive = 0
+    if sys.argv[1:] and sys.argv[1] == '-r':
+        del sys.argv[1:2]
+        recursive = 1
+    try:
+        if sys.argv[1:]:
+            testall(sys.argv[1:], recursive, 1)
+        else:
+            testall(['.'], recursive, 1)
+    except KeyboardInterrupt:
+        sys.stderr.write('\n[Interrupted]\n')
+        sys.exit(1)
+
+def testall(list, recursive, toplevel):
+    import sys
+    import os
+    for filename in list:
+        if os.path.isdir(filename):
+            print filename + '/:',
+            if recursive or toplevel:
+                print 'recursing down:'
+                import glob
+                names = glob.glob(os.path.join(filename, '*'))
+                testall(names, recursive, 0)
+            else:
+                print '*** directory (use -r) ***'
+        else:
+            print filename + ':',
+            sys.stdout.flush()
+            try:
+                print what(filename)
+            except IOError:
+                print '*** not found ***'
+
+if __name__ == '__main__':
+    test()

Added: vendor/Python/current/Lib/socket.py
===================================================================
--- vendor/Python/current/Lib/socket.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/socket.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,414 @@
+# Wrapper module for _socket, providing some additional facilities
+# implemented in Python.
+
+"""\
+This module provides socket operations and some related functions.
+On Unix, it supports IP (Internet Protocol) and Unix domain sockets.
+On other systems, it only supports IP. Functions specific for a
+socket are available as methods of the socket object.
+
+Functions:
+
+socket() -- create a new socket object
+socketpair() -- create a pair of new socket objects [*]
+fromfd() -- create a socket object from an open file descriptor [*]
+gethostname() -- return the current hostname
+gethostbyname() -- map a hostname to its IP number
+gethostbyaddr() -- map an IP number or hostname to DNS info
+getservbyname() -- map a service name and a protocol name to a port number
+getprotobyname() -- mape a protocol name (e.g. 'tcp') to a number
+ntohs(), ntohl() -- convert 16, 32 bit int from network to host byte order
+htons(), htonl() -- convert 16, 32 bit int from host to network byte order
+inet_aton() -- convert IP addr string (123.45.67.89) to 32-bit packed format
+inet_ntoa() -- convert 32-bit packed format IP to string (123.45.67.89)
+ssl() -- secure socket layer support (only available if configured)
+socket.getdefaulttimeout() -- get the default timeout value
+socket.setdefaulttimeout() -- set the default timeout value
+
+ [*] not available on all platforms!
+
+Special objects:
+
+SocketType -- type object for socket objects
+error -- exception raised for I/O errors
+has_ipv6 -- boolean value indicating if IPv6 is supported
+
+Integer constants:
+
+AF_INET, AF_UNIX -- socket domains (first argument to socket() call)
+SOCK_STREAM, SOCK_DGRAM, SOCK_RAW -- socket types (second argument)
+
+Many other constants may be defined; these may be used in calls to
+the setsockopt() and getsockopt() methods.
+"""
+
+import _socket
+from _socket import *
+
+_have_ssl = False
+try:
+    import _ssl
+    from _ssl import *
+    _have_ssl = True
+except ImportError:
+    pass
+
+import os, sys
+
+try:
+    from errno import EBADF
+except ImportError:
+    EBADF = 9
+
+__all__ = ["getfqdn"]
+__all__.extend(os._get_exports_list(_socket))
+if _have_ssl:
+    __all__.extend(os._get_exports_list(_ssl))
+
+_realsocket = socket
+if _have_ssl:
+    _realssl = ssl
+    def ssl(sock, keyfile=None, certfile=None):
+        if hasattr(sock, "_sock"):
+            sock = sock._sock
+        return _realssl(sock, keyfile, certfile)
+
+# WSA error codes
+if sys.platform.lower().startswith("win"):
+    errorTab = {}
+    errorTab[10004] = "The operation was interrupted."
+    errorTab[10009] = "A bad file handle was passed."
+    errorTab[10013] = "Permission denied."
+    errorTab[10014] = "A fault occurred on the network??" # WSAEFAULT
+    errorTab[10022] = "An invalid operation was attempted."
+    errorTab[10035] = "The socket operation would block"
+    errorTab[10036] = "A blocking operation is already in progress."
+    errorTab[10048] = "The network address is in use."
+    errorTab[10054] = "The connection has been reset."
+    errorTab[10058] = "The network has been shut down."
+    errorTab[10060] = "The operation timed out."
+    errorTab[10061] = "Connection refused."
+    errorTab[10063] = "The name is too long."
+    errorTab[10064] = "The host is down."
+    errorTab[10065] = "The host is unreachable."
+    __all__.append("errorTab")
+
+
+
+def getfqdn(name=''):
+    """Get fully qualified domain name from name.
+
+    An empty argument is interpreted as meaning the local host.
+
+    First the hostname returned by gethostbyaddr() is checked, then
+    possibly existing aliases. In case no FQDN is available, hostname
+    from gethostname() is returned.
+    """
+    name = name.strip()
+    if not name or name == '0.0.0.0':
+        name = gethostname()
+    try:
+        hostname, aliases, ipaddrs = gethostbyaddr(name)
+    except error:
+        pass
+    else:
+        aliases.insert(0, hostname)
+        for name in aliases:
+            if '.' in name:
+                break
+        else:
+            name = hostname
+    return name
+
+
+_socketmethods = (
+    'bind', 'connect', 'connect_ex', 'fileno', 'listen',
+    'getpeername', 'getsockname', 'getsockopt', 'setsockopt',
+    'sendall', 'setblocking',
+    'settimeout', 'gettimeout', 'shutdown')
+
+if sys.platform == "riscos":
+    _socketmethods = _socketmethods + ('sleeptaskw',)
+
+# All the method names that must be delegated to either the real socket
+# object or the _closedsocket object.
+_delegate_methods = ("recv", "recvfrom", "recv_into", "recvfrom_into",
+                     "send", "sendto")
+
+class _closedsocket(object):
+    __slots__ = []
+    def _dummy(*args):
+        raise error(EBADF, 'Bad file descriptor')
+    # All _delegate_methods must also be initialized here.
+    send = recv = recv_into = sendto = recvfrom = recvfrom_into = _dummy
+    __getattr__ = _dummy
+
+class _socketobject(object):
+
+    __doc__ = _realsocket.__doc__
+
+    __slots__ = ["_sock", "__weakref__"] + list(_delegate_methods)
+
+    def __init__(self, family=AF_INET, type=SOCK_STREAM, proto=0, _sock=None):
+        if _sock is None:
+            _sock = _realsocket(family, type, proto)
+        self._sock = _sock
+        for method in _delegate_methods:
+            setattr(self, method, getattr(_sock, method))
+
+    def close(self):
+        self._sock = _closedsocket()
+        dummy = self._sock._dummy
+        for method in _delegate_methods:
+            setattr(self, method, dummy)
+    close.__doc__ = _realsocket.close.__doc__
+
+    def accept(self):
+        sock, addr = self._sock.accept()
+        return _socketobject(_sock=sock), addr
+    accept.__doc__ = _realsocket.accept.__doc__
+
+    def dup(self):
+        """dup() -> socket object
+
+        Return a new socket object connected to the same system resource."""
+        return _socketobject(_sock=self._sock)
+
+    def makefile(self, mode='r', bufsize=-1):
+        """makefile([mode[, bufsize]]) -> file object
+
+        Return a regular file object corresponding to the socket.  The mode
+        and bufsize arguments are as for the built-in open() function."""
+        return _fileobject(self._sock, mode, bufsize)
+
+    family = property(lambda self: self._sock.family, doc="the socket family")
+    type = property(lambda self: self._sock.type, doc="the socket type")
+    proto = property(lambda self: self._sock.proto, doc="the socket protocol")
+
+    _s = ("def %s(self, *args): return self._sock.%s(*args)\n\n"
+          "%s.__doc__ = _realsocket.%s.__doc__\n")
+    for _m in _socketmethods:
+        exec _s % (_m, _m, _m, _m)
+    del _m, _s
+
+socket = SocketType = _socketobject
+
+class _fileobject(object):
+    """Faux file object attached to a socket object."""
+
+    default_bufsize = 8192
+    name = "<socket>"
+
+    __slots__ = ["mode", "bufsize", "softspace",
+                 # "closed" is a property, see below
+                 "_sock", "_rbufsize", "_wbufsize", "_rbuf", "_wbuf",
+                 "_close"]
+
+    def __init__(self, sock, mode='rb', bufsize=-1, close=False):
+        self._sock = sock
+        self.mode = mode # Not actually used in this version
+        if bufsize < 0:
+            bufsize = self.default_bufsize
+        self.bufsize = bufsize
+        self.softspace = False
+        if bufsize == 0:
+            self._rbufsize = 1
+        elif bufsize == 1:
+            self._rbufsize = self.default_bufsize
+        else:
+            self._rbufsize = bufsize
+        self._wbufsize = bufsize
+        self._rbuf = "" # A string
+        self._wbuf = [] # A list of strings
+        self._close = close
+
+    def _getclosed(self):
+        return self._sock is None
+    closed = property(_getclosed, doc="True if the file is closed")
+
+    def close(self):
+        try:
+            if self._sock:
+                self.flush()
+        finally:
+            if self._close:
+                self._sock.close()
+            self._sock = None
+
+    def __del__(self):
+        try:
+            self.close()
+        except:
+            # close() may fail if __init__ didn't complete
+            pass
+
+    def flush(self):
+        if self._wbuf:
+            buffer = "".join(self._wbuf)
+            self._wbuf = []
+            self._sock.sendall(buffer)
+
+    def fileno(self):
+        return self._sock.fileno()
+
+    def write(self, data):
+        data = str(data) # XXX Should really reject non-string non-buffers
+        if not data:
+            return
+        self._wbuf.append(data)
+        if (self._wbufsize == 0 or
+            self._wbufsize == 1 and '\n' in data or
+            self._get_wbuf_len() >= self._wbufsize):
+            self.flush()
+
+    def writelines(self, list):
+        # XXX We could do better here for very long lists
+        # XXX Should really reject non-string non-buffers
+        self._wbuf.extend(filter(None, map(str, list)))
+        if (self._wbufsize <= 1 or
+            self._get_wbuf_len() >= self._wbufsize):
+            self.flush()
+
+    def _get_wbuf_len(self):
+        buf_len = 0
+        for x in self._wbuf:
+            buf_len += len(x)
+        return buf_len
+
+    def read(self, size=-1):
+        data = self._rbuf
+        if size < 0:
+            # Read until EOF
+            buffers = []
+            if data:
+                buffers.append(data)
+            self._rbuf = ""
+            if self._rbufsize <= 1:
+                recv_size = self.default_bufsize
+            else:
+                recv_size = self._rbufsize
+            while True:
+                data = self._sock.recv(recv_size)
+                if not data:
+                    break
+                buffers.append(data)
+            return "".join(buffers)
+        else:
+            # Read until size bytes or EOF seen, whichever comes first
+            buf_len = len(data)
+            if buf_len >= size:
+                self._rbuf = data[size:]
+                return data[:size]
+            buffers = []
+            if data:
+                buffers.append(data)
+            self._rbuf = ""
+            while True:
+                left = size - buf_len
+                recv_size = max(self._rbufsize, left)
+                data = self._sock.recv(recv_size)
+                if not data:
+                    break
+                buffers.append(data)
+                n = len(data)
+                if n >= left:
+                    self._rbuf = data[left:]
+                    buffers[-1] = data[:left]
+                    break
+                buf_len += n
+            return "".join(buffers)
+
+    def readline(self, size=-1):
+        data = self._rbuf
+        if size < 0:
+            # Read until \n or EOF, whichever comes first
+            if self._rbufsize <= 1:
+                # Speed up unbuffered case
+                assert data == ""
+                buffers = []
+                recv = self._sock.recv
+                while data != "\n":
+                    data = recv(1)
+                    if not data:
+                        break
+                    buffers.append(data)
+                return "".join(buffers)
+            nl = data.find('\n')
+            if nl >= 0:
+                nl += 1
+                self._rbuf = data[nl:]
+                return data[:nl]
+            buffers = []
+            if data:
+                buffers.append(data)
+            self._rbuf = ""
+            while True:
+                data = self._sock.recv(self._rbufsize)
+                if not data:
+                    break
+                buffers.append(data)
+                nl = data.find('\n')
+                if nl >= 0:
+                    nl += 1
+                    self._rbuf = data[nl:]
+                    buffers[-1] = data[:nl]
+                    break
+            return "".join(buffers)
+        else:
+            # Read until size bytes or \n or EOF seen, whichever comes first
+            nl = data.find('\n', 0, size)
+            if nl >= 0:
+                nl += 1
+                self._rbuf = data[nl:]
+                return data[:nl]
+            buf_len = len(data)
+            if buf_len >= size:
+                self._rbuf = data[size:]
+                return data[:size]
+            buffers = []
+            if data:
+                buffers.append(data)
+            self._rbuf = ""
+            while True:
+                data = self._sock.recv(self._rbufsize)
+                if not data:
+                    break
+                buffers.append(data)
+                left = size - buf_len
+                nl = data.find('\n', 0, left)
+                if nl >= 0:
+                    nl += 1
+                    self._rbuf = data[nl:]
+                    buffers[-1] = data[:nl]
+                    break
+                n = len(data)
+                if n >= left:
+                    self._rbuf = data[left:]
+                    buffers[-1] = data[:left]
+                    break
+                buf_len += n
+            return "".join(buffers)
+
+    def readlines(self, sizehint=0):
+        total = 0
+        list = []
+        while True:
+            line = self.readline()
+            if not line:
+                break
+            list.append(line)
+            total += len(line)
+            if sizehint and total >= sizehint:
+                break
+        return list
+
+    # Iterator protocols
+
+    def __iter__(self):
+        return self
+
+    def next(self):
+        line = self.readline()
+        if not line:
+            raise StopIteration
+        return line

Added: vendor/Python/current/Lib/sqlite3/__init__.py
===================================================================
--- vendor/Python/current/Lib/sqlite3/__init__.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/sqlite3/__init__.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,24 @@
+#-*- coding: ISO-8859-1 -*-
+# pysqlite2/__init__.py: the pysqlite2 package.
+#
+# Copyright (C) 2005 Gerhard Häring <gh at ghaering.de>
+#
+# This file is part of pysqlite.
+#
+# This software is provided 'as-is', without any express or implied
+# warranty.  In no event will the authors be held liable for any damages
+# arising from the use of this software.
+#
+# Permission is granted to anyone to use this software for any purpose,
+# including commercial applications, and to alter it and redistribute it
+# freely, subject to the following restrictions:
+#
+# 1. The origin of this software must not be misrepresented; you must not
+#    claim that you wrote the original software. If you use this software
+#    in a product, an acknowledgment in the product documentation would be
+#    appreciated but is not required.
+# 2. Altered source versions must be plainly marked as such, and must not be
+#    misrepresented as being the original software.
+# 3. This notice may not be removed or altered from any source distribution.
+
+from dbapi2 import *

Added: vendor/Python/current/Lib/sqlite3/dbapi2.py
===================================================================
--- vendor/Python/current/Lib/sqlite3/dbapi2.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/sqlite3/dbapi2.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,88 @@
+#-*- coding: ISO-8859-1 -*-
+# pysqlite2/dbapi2.py: the DB-API 2.0 interface
+#
+# Copyright (C) 2004-2005 Gerhard Häring <gh at ghaering.de>
+#
+# This file is part of pysqlite.
+#
+# This software is provided 'as-is', without any express or implied
+# warranty.  In no event will the authors be held liable for any damages
+# arising from the use of this software.
+#
+# Permission is granted to anyone to use this software for any purpose,
+# including commercial applications, and to alter it and redistribute it
+# freely, subject to the following restrictions:
+#
+# 1. The origin of this software must not be misrepresented; you must not
+#    claim that you wrote the original software. If you use this software
+#    in a product, an acknowledgment in the product documentation would be
+#    appreciated but is not required.
+# 2. Altered source versions must be plainly marked as such, and must not be
+#    misrepresented as being the original software.
+# 3. This notice may not be removed or altered from any source distribution.
+
+import datetime
+import time
+
+from _sqlite3 import *
+
+paramstyle = "qmark"
+
+threadsafety = 1
+
+apilevel = "2.0"
+
+Date = datetime.date
+
+Time = datetime.time
+
+Timestamp = datetime.datetime
+
+def DateFromTicks(ticks):
+    return apply(Date, time.localtime(ticks)[:3])
+
+def TimeFromTicks(ticks):
+    return apply(Time, time.localtime(ticks)[3:6])
+
+def TimestampFromTicks(ticks):
+    return apply(Timestamp, time.localtime(ticks)[:6])
+
+version_info = tuple([int(x) for x in version.split(".")])
+sqlite_version_info = tuple([int(x) for x in sqlite_version.split(".")])
+
+Binary = buffer
+
+def register_adapters_and_converters():
+    def adapt_date(val):
+        return val.isoformat()
+
+    def adapt_datetime(val):
+        return val.isoformat(" ")
+
+    def convert_date(val):
+        return datetime.date(*map(int, val.split("-")))
+
+    def convert_timestamp(val):
+        datepart, timepart = val.split(" ")
+        year, month, day = map(int, datepart.split("-"))
+        timepart_full = timepart.split(".")
+        hours, minutes, seconds = map(int, timepart_full[0].split(":"))
+        if len(timepart_full) == 2:
+            microseconds = int(float("0." + timepart_full[1]) * 1000000)
+        else:
+            microseconds = 0
+
+        val = datetime.datetime(year, month, day, hours, minutes, seconds, microseconds)
+        return val
+
+
+    register_adapter(datetime.date, adapt_date)
+    register_adapter(datetime.datetime, adapt_datetime)
+    register_converter("date", convert_date)
+    register_converter("timestamp", convert_timestamp)
+
+register_adapters_and_converters()
+
+# Clean up namespace
+
+del(register_adapters_and_converters)

Added: vendor/Python/current/Lib/sqlite3/test/__init__.py
===================================================================

Added: vendor/Python/current/Lib/sqlite3/test/dbapi.py
===================================================================
--- vendor/Python/current/Lib/sqlite3/test/dbapi.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/sqlite3/test/dbapi.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,732 @@
+#-*- coding: ISO-8859-1 -*-
+# pysqlite2/test/dbapi.py: tests for DB-API compliance
+#
+# Copyright (C) 2004-2005 Gerhard Häring <gh at ghaering.de>
+#
+# This file is part of pysqlite.
+#
+# This software is provided 'as-is', without any express or implied
+# warranty.  In no event will the authors be held liable for any damages
+# arising from the use of this software.
+#
+# Permission is granted to anyone to use this software for any purpose,
+# including commercial applications, and to alter it and redistribute it
+# freely, subject to the following restrictions:
+#
+# 1. The origin of this software must not be misrepresented; you must not
+#    claim that you wrote the original software. If you use this software
+#    in a product, an acknowledgment in the product documentation would be
+#    appreciated but is not required.
+# 2. Altered source versions must be plainly marked as such, and must not be
+#    misrepresented as being the original software.
+# 3. This notice may not be removed or altered from any source distribution.
+
+import unittest
+import threading
+import sqlite3 as sqlite
+
+class ModuleTests(unittest.TestCase):
+    def CheckAPILevel(self):
+        self.assertEqual(sqlite.apilevel, "2.0",
+                         "apilevel is %s, should be 2.0" % sqlite.apilevel)
+
+    def CheckThreadSafety(self):
+        self.assertEqual(sqlite.threadsafety, 1,
+                         "threadsafety is %d, should be 1" % sqlite.threadsafety)
+
+    def CheckParamStyle(self):
+        self.assertEqual(sqlite.paramstyle, "qmark",
+                         "paramstyle is '%s', should be 'qmark'" %
+                         sqlite.paramstyle)
+
+    def CheckWarning(self):
+        self.assert_(issubclass(sqlite.Warning, StandardError),
+                     "Warning is not a subclass of StandardError")
+
+    def CheckError(self):
+        self.failUnless(issubclass(sqlite.Error, StandardError),
+                        "Error is not a subclass of StandardError")
+
+    def CheckInterfaceError(self):
+        self.failUnless(issubclass(sqlite.InterfaceError, sqlite.Error),
+                        "InterfaceError is not a subclass of Error")
+
+    def CheckDatabaseError(self):
+        self.failUnless(issubclass(sqlite.DatabaseError, sqlite.Error),
+                        "DatabaseError is not a subclass of Error")
+
+    def CheckDataError(self):
+        self.failUnless(issubclass(sqlite.DataError, sqlite.DatabaseError),
+                        "DataError is not a subclass of DatabaseError")
+
+    def CheckOperationalError(self):
+        self.failUnless(issubclass(sqlite.OperationalError, sqlite.DatabaseError),
+                        "OperationalError is not a subclass of DatabaseError")
+
+    def CheckIntegrityError(self):
+        self.failUnless(issubclass(sqlite.IntegrityError, sqlite.DatabaseError),
+                        "IntegrityError is not a subclass of DatabaseError")
+
+    def CheckInternalError(self):
+        self.failUnless(issubclass(sqlite.InternalError, sqlite.DatabaseError),
+                        "InternalError is not a subclass of DatabaseError")
+
+    def CheckProgrammingError(self):
+        self.failUnless(issubclass(sqlite.ProgrammingError, sqlite.DatabaseError),
+                        "ProgrammingError is not a subclass of DatabaseError")
+
+    def CheckNotSupportedError(self):
+        self.failUnless(issubclass(sqlite.NotSupportedError,
+                                   sqlite.DatabaseError),
+                        "NotSupportedError is not a subclass of DatabaseError")
+
+class ConnectionTests(unittest.TestCase):
+    def setUp(self):
+        self.cx = sqlite.connect(":memory:")
+        cu = self.cx.cursor()
+        cu.execute("create table test(id integer primary key, name text)")
+        cu.execute("insert into test(name) values (?)", ("foo",))
+
+    def tearDown(self):
+        self.cx.close()
+
+    def CheckCommit(self):
+        self.cx.commit()
+
+    def CheckCommitAfterNoChanges(self):
+        """
+        A commit should also work when no changes were made to the database.
+        """
+        self.cx.commit()
+        self.cx.commit()
+
+    def CheckRollback(self):
+        self.cx.rollback()
+
+    def CheckRollbackAfterNoChanges(self):
+        """
+        A rollback should also work when no changes were made to the database.
+        """
+        self.cx.rollback()
+        self.cx.rollback()
+
+    def CheckCursor(self):
+        cu = self.cx.cursor()
+
+    def CheckFailedOpen(self):
+        YOU_CANNOT_OPEN_THIS = "/foo/bar/bla/23534/mydb.db"
+        try:
+            con = sqlite.connect(YOU_CANNOT_OPEN_THIS)
+        except sqlite.OperationalError:
+            return
+        self.fail("should have raised an OperationalError")
+
+    def CheckClose(self):
+        self.cx.close()
+
+    def CheckExceptions(self):
+        # Optional DB-API extension.
+        self.failUnlessEqual(self.cx.Warning, sqlite.Warning)
+        self.failUnlessEqual(self.cx.Error, sqlite.Error)
+        self.failUnlessEqual(self.cx.InterfaceError, sqlite.InterfaceError)
+        self.failUnlessEqual(self.cx.DatabaseError, sqlite.DatabaseError)
+        self.failUnlessEqual(self.cx.DataError, sqlite.DataError)
+        self.failUnlessEqual(self.cx.OperationalError, sqlite.OperationalError)
+        self.failUnlessEqual(self.cx.IntegrityError, sqlite.IntegrityError)
+        self.failUnlessEqual(self.cx.InternalError, sqlite.InternalError)
+        self.failUnlessEqual(self.cx.ProgrammingError, sqlite.ProgrammingError)
+        self.failUnlessEqual(self.cx.NotSupportedError, sqlite.NotSupportedError)
+
+class CursorTests(unittest.TestCase):
+    def setUp(self):
+        self.cx = sqlite.connect(":memory:")
+        self.cu = self.cx.cursor()
+        self.cu.execute("create table test(id integer primary key, name text, income number)")
+        self.cu.execute("insert into test(name) values (?)", ("foo",))
+
+    def tearDown(self):
+        self.cu.close()
+        self.cx.close()
+
+    def CheckExecuteNoArgs(self):
+        self.cu.execute("delete from test")
+
+    def CheckExecuteIllegalSql(self):
+        try:
+            self.cu.execute("select asdf")
+            self.fail("should have raised an OperationalError")
+        except sqlite.OperationalError:
+            return
+        except:
+            self.fail("raised wrong exception")
+
+    def CheckExecuteTooMuchSql(self):
+        try:
+            self.cu.execute("select 5+4; select 4+5")
+            self.fail("should have raised a Warning")
+        except sqlite.Warning:
+            return
+        except:
+            self.fail("raised wrong exception")
+
+    def CheckExecuteTooMuchSql2(self):
+        self.cu.execute("select 5+4; -- foo bar")
+
+    def CheckExecuteTooMuchSql3(self):
+        self.cu.execute("""
+            select 5+4;
+
+            /*
+            foo
+            */
+            """)
+
+    def CheckExecuteWrongSqlArg(self):
+        try:
+            self.cu.execute(42)
+            self.fail("should have raised a ValueError")
+        except ValueError:
+            return
+        except:
+            self.fail("raised wrong exception.")
+
+    def CheckExecuteArgInt(self):
+        self.cu.execute("insert into test(id) values (?)", (42,))
+
+    def CheckExecuteArgFloat(self):
+        self.cu.execute("insert into test(income) values (?)", (2500.32,))
+
+    def CheckExecuteArgString(self):
+        self.cu.execute("insert into test(name) values (?)", ("Hugo",))
+
+    def CheckExecuteWrongNoOfArgs1(self):
+        # too many parameters
+        try:
+            self.cu.execute("insert into test(id) values (?)", (17, "Egon"))
+            self.fail("should have raised ProgrammingError")
+        except sqlite.ProgrammingError:
+            pass
+
+    def CheckExecuteWrongNoOfArgs2(self):
+        # too little parameters
+        try:
+            self.cu.execute("insert into test(id) values (?)")
+            self.fail("should have raised ProgrammingError")
+        except sqlite.ProgrammingError:
+            pass
+
+    def CheckExecuteWrongNoOfArgs3(self):
+        # no parameters, parameters are needed
+        try:
+            self.cu.execute("insert into test(id) values (?)")
+            self.fail("should have raised ProgrammingError")
+        except sqlite.ProgrammingError:
+            pass
+
+    def CheckExecuteDictMapping(self):
+        self.cu.execute("insert into test(name) values ('foo')")
+        self.cu.execute("select name from test where name=:name", {"name": "foo"})
+        row = self.cu.fetchone()
+        self.failUnlessEqual(row[0], "foo")
+
+    def CheckExecuteDictMappingTooLittleArgs(self):
+        self.cu.execute("insert into test(name) values ('foo')")
+        try:
+            self.cu.execute("select name from test where name=:name and id=:id", {"name": "foo"})
+            self.fail("should have raised ProgrammingError")
+        except sqlite.ProgrammingError:
+            pass
+
+    def CheckExecuteDictMappingNoArgs(self):
+        self.cu.execute("insert into test(name) values ('foo')")
+        try:
+            self.cu.execute("select name from test where name=:name")
+            self.fail("should have raised ProgrammingError")
+        except sqlite.ProgrammingError:
+            pass
+
+    def CheckExecuteDictMappingUnnamed(self):
+        self.cu.execute("insert into test(name) values ('foo')")
+        try:
+            self.cu.execute("select name from test where name=?", {"name": "foo"})
+            self.fail("should have raised ProgrammingError")
+        except sqlite.ProgrammingError:
+            pass
+
+    def CheckClose(self):
+        self.cu.close()
+
+    def CheckRowcountExecute(self):
+        self.cu.execute("delete from test")
+        self.cu.execute("insert into test(name) values ('foo')")
+        self.cu.execute("insert into test(name) values ('foo')")
+        self.cu.execute("update test set name='bar'")
+        self.failUnlessEqual(self.cu.rowcount, 2)
+
+    def CheckRowcountExecutemany(self):
+        self.cu.execute("delete from test")
+        self.cu.executemany("insert into test(name) values (?)", [(1,), (2,), (3,)])
+        self.failUnlessEqual(self.cu.rowcount, 3)
+
+    def CheckTotalChanges(self):
+        self.cu.execute("insert into test(name) values ('foo')")
+        self.cu.execute("insert into test(name) values ('foo')")
+        if self.cx.total_changes < 2:
+            self.fail("total changes reported wrong value")
+
+    # Checks for executemany:
+    # Sequences are required by the DB-API, iterators
+    # enhancements in pysqlite.
+
+    def CheckExecuteManySequence(self):
+        self.cu.executemany("insert into test(income) values (?)", [(x,) for x in range(100, 110)])
+
+    def CheckExecuteManyIterator(self):
+        class MyIter:
+            def __init__(self):
+                self.value = 5
+
+            def next(self):
+                if self.value == 10:
+                    raise StopIteration
+                else:
+                    self.value += 1
+                    return (self.value,)
+
+        self.cu.executemany("insert into test(income) values (?)", MyIter())
+
+    def CheckExecuteManyGenerator(self):
+        def mygen():
+            for i in range(5):
+                yield (i,)
+
+        self.cu.executemany("insert into test(income) values (?)", mygen())
+
+    def CheckExecuteManyWrongSqlArg(self):
+        try:
+            self.cu.executemany(42, [(3,)])
+            self.fail("should have raised a ValueError")
+        except ValueError:
+            return
+        except:
+            self.fail("raised wrong exception.")
+
+    def CheckExecuteManySelect(self):
+        try:
+            self.cu.executemany("select ?", [(3,)])
+            self.fail("should have raised a ProgrammingError")
+        except sqlite.ProgrammingError:
+            return
+        except:
+            self.fail("raised wrong exception.")
+
+    def CheckExecuteManyNotIterable(self):
+        try:
+            self.cu.executemany("insert into test(income) values (?)", 42)
+            self.fail("should have raised a TypeError")
+        except TypeError:
+            return
+        except Exception, e:
+            print "raised", e.__class__
+            self.fail("raised wrong exception.")
+
+    def CheckFetchIter(self):
+        # Optional DB-API extension.
+        self.cu.execute("delete from test")
+        self.cu.execute("insert into test(id) values (?)", (5,))
+        self.cu.execute("insert into test(id) values (?)", (6,))
+        self.cu.execute("select id from test order by id")
+        lst = []
+        for row in self.cu:
+            lst.append(row[0])
+        self.failUnlessEqual(lst[0], 5)
+        self.failUnlessEqual(lst[1], 6)
+
+    def CheckFetchone(self):
+        self.cu.execute("select name from test")
+        row = self.cu.fetchone()
+        self.failUnlessEqual(row[0], "foo")
+        row = self.cu.fetchone()
+        self.failUnlessEqual(row, None)
+
+    def CheckFetchoneNoStatement(self):
+        cur = self.cx.cursor()
+        row = cur.fetchone()
+        self.failUnlessEqual(row, None)
+
+    def CheckArraySize(self):
+        # must default ot 1
+        self.failUnlessEqual(self.cu.arraysize, 1)
+
+        # now set to 2
+        self.cu.arraysize = 2
+
+        # now make the query return 3 rows
+        self.cu.execute("delete from test")
+        self.cu.execute("insert into test(name) values ('A')")
+        self.cu.execute("insert into test(name) values ('B')")
+        self.cu.execute("insert into test(name) values ('C')")
+        self.cu.execute("select name from test")
+        res = self.cu.fetchmany()
+
+        self.failUnlessEqual(len(res), 2)
+
+    def CheckFetchmany(self):
+        self.cu.execute("select name from test")
+        res = self.cu.fetchmany(100)
+        self.failUnlessEqual(len(res), 1)
+        res = self.cu.fetchmany(100)
+        self.failUnlessEqual(res, [])
+
+    def CheckFetchall(self):
+        self.cu.execute("select name from test")
+        res = self.cu.fetchall()
+        self.failUnlessEqual(len(res), 1)
+        res = self.cu.fetchall()
+        self.failUnlessEqual(res, [])
+
+    def CheckSetinputsizes(self):
+        self.cu.setinputsizes([3, 4, 5])
+
+    def CheckSetoutputsize(self):
+        self.cu.setoutputsize(5, 0)
+
+    def CheckSetoutputsizeNoColumn(self):
+        self.cu.setoutputsize(42)
+
+    def CheckCursorConnection(self):
+        # Optional DB-API extension.
+        self.failUnlessEqual(self.cu.connection, self.cx)
+
+    def CheckWrongCursorCallable(self):
+        try:
+            def f(): pass
+            cur = self.cx.cursor(f)
+            self.fail("should have raised a TypeError")
+        except TypeError:
+            return
+        self.fail("should have raised a ValueError")
+
+    def CheckCursorWrongClass(self):
+        class Foo: pass
+        foo = Foo()
+        try:
+            cur = sqlite.Cursor(foo)
+            self.fail("should have raised a ValueError")
+        except TypeError:
+            pass
+
+class ThreadTests(unittest.TestCase):
+    def setUp(self):
+        self.con = sqlite.connect(":memory:")
+        self.cur = self.con.cursor()
+        self.cur.execute("create table test(id integer primary key, name text, bin binary, ratio number, ts timestamp)")
+
+    def tearDown(self):
+        self.cur.close()
+        self.con.close()
+
+    def CheckConCursor(self):
+        def run(con, errors):
+            try:
+                cur = con.cursor()
+                errors.append("did not raise ProgrammingError")
+                return
+            except sqlite.ProgrammingError:
+                return
+            except:
+                errors.append("raised wrong exception")
+
+        errors = []
+        t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors})
+        t.start()
+        t.join()
+        if len(errors) > 0:
+            self.fail("\n".join(errors))
+
+    def CheckConCommit(self):
+        def run(con, errors):
+            try:
+                con.commit()
+                errors.append("did not raise ProgrammingError")
+                return
+            except sqlite.ProgrammingError:
+                return
+            except:
+                errors.append("raised wrong exception")
+
+        errors = []
+        t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors})
+        t.start()
+        t.join()
+        if len(errors) > 0:
+            self.fail("\n".join(errors))
+
+    def CheckConRollback(self):
+        def run(con, errors):
+            try:
+                con.rollback()
+                errors.append("did not raise ProgrammingError")
+                return
+            except sqlite.ProgrammingError:
+                return
+            except:
+                errors.append("raised wrong exception")
+
+        errors = []
+        t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors})
+        t.start()
+        t.join()
+        if len(errors) > 0:
+            self.fail("\n".join(errors))
+
+    def CheckConClose(self):
+        def run(con, errors):
+            try:
+                con.close()
+                errors.append("did not raise ProgrammingError")
+                return
+            except sqlite.ProgrammingError:
+                return
+            except:
+                errors.append("raised wrong exception")
+
+        errors = []
+        t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors})
+        t.start()
+        t.join()
+        if len(errors) > 0:
+            self.fail("\n".join(errors))
+
+    def CheckCurImplicitBegin(self):
+        def run(cur, errors):
+            try:
+                cur.execute("insert into test(name) values ('a')")
+                errors.append("did not raise ProgrammingError")
+                return
+            except sqlite.ProgrammingError:
+                return
+            except:
+                errors.append("raised wrong exception")
+
+        errors = []
+        t = threading.Thread(target=run, kwargs={"cur": self.cur, "errors": errors})
+        t.start()
+        t.join()
+        if len(errors) > 0:
+            self.fail("\n".join(errors))
+
+    def CheckCurClose(self):
+        def run(cur, errors):
+            try:
+                cur.close()
+                errors.append("did not raise ProgrammingError")
+                return
+            except sqlite.ProgrammingError:
+                return
+            except:
+                errors.append("raised wrong exception")
+
+        errors = []
+        t = threading.Thread(target=run, kwargs={"cur": self.cur, "errors": errors})
+        t.start()
+        t.join()
+        if len(errors) > 0:
+            self.fail("\n".join(errors))
+
+    def CheckCurExecute(self):
+        def run(cur, errors):
+            try:
+                cur.execute("select name from test")
+                errors.append("did not raise ProgrammingError")
+                return
+            except sqlite.ProgrammingError:
+                return
+            except:
+                errors.append("raised wrong exception")
+
+        errors = []
+        self.cur.execute("insert into test(name) values ('a')")
+        t = threading.Thread(target=run, kwargs={"cur": self.cur, "errors": errors})
+        t.start()
+        t.join()
+        if len(errors) > 0:
+            self.fail("\n".join(errors))
+
+    def CheckCurIterNext(self):
+        def run(cur, errors):
+            try:
+                row = cur.fetchone()
+                errors.append("did not raise ProgrammingError")
+                return
+            except sqlite.ProgrammingError:
+                return
+            except:
+                errors.append("raised wrong exception")
+
+        errors = []
+        self.cur.execute("insert into test(name) values ('a')")
+        self.cur.execute("select name from test")
+        t = threading.Thread(target=run, kwargs={"cur": self.cur, "errors": errors})
+        t.start()
+        t.join()
+        if len(errors) > 0:
+            self.fail("\n".join(errors))
+
+class ConstructorTests(unittest.TestCase):
+    def CheckDate(self):
+        d = sqlite.Date(2004, 10, 28)
+
+    def CheckTime(self):
+        t = sqlite.Time(12, 39, 35)
+
+    def CheckTimestamp(self):
+        ts = sqlite.Timestamp(2004, 10, 28, 12, 39, 35)
+
+    def CheckDateFromTicks(self):
+        d = sqlite.DateFromTicks(42)
+
+    def CheckTimeFromTicks(self):
+        t = sqlite.TimeFromTicks(42)
+
+    def CheckTimestampFromTicks(self):
+        ts = sqlite.TimestampFromTicks(42)
+
+    def CheckBinary(self):
+        b = sqlite.Binary(chr(0) + "'")
+
+class ExtensionTests(unittest.TestCase):
+    def CheckScriptStringSql(self):
+        con = sqlite.connect(":memory:")
+        cur = con.cursor()
+        cur.executescript("""
+            -- bla bla
+            /* a stupid comment */
+            create table a(i);
+            insert into a(i) values (5);
+            """)
+        cur.execute("select i from a")
+        res = cur.fetchone()[0]
+        self.failUnlessEqual(res, 5)
+
+    def CheckScriptStringUnicode(self):
+        con = sqlite.connect(":memory:")
+        cur = con.cursor()
+        cur.executescript(u"""
+            create table a(i);
+            insert into a(i) values (5);
+            select i from a;
+            delete from a;
+            insert into a(i) values (6);
+            """)
+        cur.execute("select i from a")
+        res = cur.fetchone()[0]
+        self.failUnlessEqual(res, 6)
+
+    def CheckScriptErrorIncomplete(self):
+        con = sqlite.connect(":memory:")
+        cur = con.cursor()
+        raised = False
+        try:
+            cur.executescript("create table test(sadfsadfdsa")
+        except sqlite.ProgrammingError:
+            raised = True
+        self.failUnlessEqual(raised, True, "should have raised an exception")
+
+    def CheckScriptErrorNormal(self):
+        con = sqlite.connect(":memory:")
+        cur = con.cursor()
+        raised = False
+        try:
+            cur.executescript("create table test(sadfsadfdsa); select foo from hurz;")
+        except sqlite.OperationalError:
+            raised = True
+        self.failUnlessEqual(raised, True, "should have raised an exception")
+
+    def CheckConnectionExecute(self):
+        con = sqlite.connect(":memory:")
+        result = con.execute("select 5").fetchone()[0]
+        self.failUnlessEqual(result, 5, "Basic test of Connection.execute")
+
+    def CheckConnectionExecutemany(self):
+        con = sqlite.connect(":memory:")
+        con.execute("create table test(foo)")
+        con.executemany("insert into test(foo) values (?)", [(3,), (4,)])
+        result = con.execute("select foo from test order by foo").fetchall()
+        self.failUnlessEqual(result[0][0], 3, "Basic test of Connection.executemany")
+        self.failUnlessEqual(result[1][0], 4, "Basic test of Connection.executemany")
+
+    def CheckConnectionExecutescript(self):
+        con = sqlite.connect(":memory:")
+        con.executescript("create table test(foo); insert into test(foo) values (5);")
+        result = con.execute("select foo from test").fetchone()[0]
+        self.failUnlessEqual(result, 5, "Basic test of Connection.executescript")
+
+class ClosedTests(unittest.TestCase):
+    def setUp(self):
+        pass
+
+    def tearDown(self):
+        pass
+
+    def CheckClosedConCursor(self):
+        con = sqlite.connect(":memory:")
+        con.close()
+        try:
+            cur = con.cursor()
+            self.fail("Should have raised a ProgrammingError")
+        except sqlite.ProgrammingError:
+            pass
+        except:
+            self.fail("Should have raised a ProgrammingError")
+
+    def CheckClosedConCommit(self):
+        con = sqlite.connect(":memory:")
+        con.close()
+        try:
+            con.commit()
+            self.fail("Should have raised a ProgrammingError")
+        except sqlite.ProgrammingError:
+            pass
+        except:
+            self.fail("Should have raised a ProgrammingError")
+
+    def CheckClosedConRollback(self):
+        con = sqlite.connect(":memory:")
+        con.close()
+        try:
+            con.rollback()
+            self.fail("Should have raised a ProgrammingError")
+        except sqlite.ProgrammingError:
+            pass
+        except:
+            self.fail("Should have raised a ProgrammingError")
+
+    def CheckClosedCurExecute(self):
+        con = sqlite.connect(":memory:")
+        cur = con.cursor()
+        con.close()
+        try:
+            cur.execute("select 4")
+            self.fail("Should have raised a ProgrammingError")
+        except sqlite.ProgrammingError:
+            pass
+        except:
+            self.fail("Should have raised a ProgrammingError")
+
+def suite():
+    module_suite = unittest.makeSuite(ModuleTests, "Check")
+    connection_suite = unittest.makeSuite(ConnectionTests, "Check")
+    cursor_suite = unittest.makeSuite(CursorTests, "Check")
+    thread_suite = unittest.makeSuite(ThreadTests, "Check")
+    constructor_suite = unittest.makeSuite(ConstructorTests, "Check")
+    ext_suite = unittest.makeSuite(ExtensionTests, "Check")
+    closed_suite = unittest.makeSuite(ClosedTests, "Check")
+    return unittest.TestSuite((module_suite, connection_suite, cursor_suite, thread_suite, constructor_suite, ext_suite, closed_suite))
+
+def test():
+    runner = unittest.TextTestRunner()
+    runner.run(suite())
+
+if __name__ == "__main__":
+    test()

Added: vendor/Python/current/Lib/sqlite3/test/factory.py
===================================================================
--- vendor/Python/current/Lib/sqlite3/test/factory.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/sqlite3/test/factory.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,164 @@
+#-*- coding: ISO-8859-1 -*-
+# pysqlite2/test/factory.py: tests for the various factories in pysqlite
+#
+# Copyright (C) 2005 Gerhard Häring <gh at ghaering.de>
+#
+# This file is part of pysqlite.
+#
+# This software is provided 'as-is', without any express or implied
+# warranty.  In no event will the authors be held liable for any damages
+# arising from the use of this software.
+#
+# Permission is granted to anyone to use this software for any purpose,
+# including commercial applications, and to alter it and redistribute it
+# freely, subject to the following restrictions:
+#
+# 1. The origin of this software must not be misrepresented; you must not
+#    claim that you wrote the original software. If you use this software
+#    in a product, an acknowledgment in the product documentation would be
+#    appreciated but is not required.
+# 2. Altered source versions must be plainly marked as such, and must not be
+#    misrepresented as being the original software.
+# 3. This notice may not be removed or altered from any source distribution.
+
+import unittest
+import sqlite3 as sqlite
+
+class MyConnection(sqlite.Connection):
+    def __init__(self, *args, **kwargs):
+        sqlite.Connection.__init__(self, *args, **kwargs)
+
+def dict_factory(cursor, row):
+    d = {}
+    for idx, col in enumerate(cursor.description):
+        d[col[0]] = row[idx]
+    return d
+
+class MyCursor(sqlite.Cursor):
+    def __init__(self, *args, **kwargs):
+        sqlite.Cursor.__init__(self, *args, **kwargs)
+        self.row_factory = dict_factory
+
+class ConnectionFactoryTests(unittest.TestCase):
+    def setUp(self):
+        self.con = sqlite.connect(":memory:", factory=MyConnection)
+
+    def tearDown(self):
+        self.con.close()
+
+    def CheckIsInstance(self):
+        self.failUnless(isinstance(self.con,
+                                   MyConnection),
+                        "connection is not instance of MyConnection")
+
+class CursorFactoryTests(unittest.TestCase):
+    def setUp(self):
+        self.con = sqlite.connect(":memory:")
+
+    def tearDown(self):
+        self.con.close()
+
+    def CheckIsInstance(self):
+        cur = self.con.cursor(factory=MyCursor)
+        self.failUnless(isinstance(cur,
+                                   MyCursor),
+                        "cursor is not instance of MyCursor")
+
+class RowFactoryTestsBackwardsCompat(unittest.TestCase):
+    def setUp(self):
+        self.con = sqlite.connect(":memory:")
+
+    def CheckIsProducedByFactory(self):
+        cur = self.con.cursor(factory=MyCursor)
+        cur.execute("select 4+5 as foo")
+        row = cur.fetchone()
+        self.failUnless(isinstance(row,
+                                   dict),
+                        "row is not instance of dict")
+        cur.close()
+
+    def tearDown(self):
+        self.con.close()
+
+class RowFactoryTests(unittest.TestCase):
+    def setUp(self):
+        self.con = sqlite.connect(":memory:")
+
+    def CheckCustomFactory(self):
+        self.con.row_factory = lambda cur, row: list(row)
+        row = self.con.execute("select 1, 2").fetchone()
+        self.failUnless(isinstance(row,
+                                   list),
+                        "row is not instance of list")
+
+    def CheckSqliteRow(self):
+        self.con.row_factory = sqlite.Row
+        row = self.con.execute("select 1 as a, 2 as b").fetchone()
+        self.failUnless(isinstance(row,
+                                   sqlite.Row),
+                        "row is not instance of sqlite.Row")
+
+        col1, col2 = row["a"], row["b"]
+        self.failUnless(col1 == 1, "by name: wrong result for column 'a'")
+        self.failUnless(col2 == 2, "by name: wrong result for column 'a'")
+
+        col1, col2 = row["A"], row["B"]
+        self.failUnless(col1 == 1, "by name: wrong result for column 'A'")
+        self.failUnless(col2 == 2, "by name: wrong result for column 'B'")
+
+        col1, col2 = row[0], row[1]
+        self.failUnless(col1 == 1, "by index: wrong result for column 0")
+        self.failUnless(col2 == 2, "by index: wrong result for column 1")
+
+    def tearDown(self):
+        self.con.close()
+
+class TextFactoryTests(unittest.TestCase):
+    def setUp(self):
+        self.con = sqlite.connect(":memory:")
+
+    def CheckUnicode(self):
+        austria = unicode("Österreich", "latin1")
+        row = self.con.execute("select ?", (austria,)).fetchone()
+        self.failUnless(type(row[0]) == unicode, "type of row[0] must be unicode")
+
+    def CheckString(self):
+        self.con.text_factory = str
+        austria = unicode("Österreich", "latin1")
+        row = self.con.execute("select ?", (austria,)).fetchone()
+        self.failUnless(type(row[0]) == str, "type of row[0] must be str")
+        self.failUnless(row[0] == austria.encode("utf-8"), "column must equal original data in UTF-8")
+
+    def CheckCustom(self):
+        self.con.text_factory = lambda x: unicode(x, "utf-8", "ignore")
+        austria = unicode("Österreich", "latin1")
+        row = self.con.execute("select ?", (austria.encode("latin1"),)).fetchone()
+        self.failUnless(type(row[0]) == unicode, "type of row[0] must be unicode")
+        self.failUnless(row[0].endswith(u"reich"), "column must contain original data")
+
+    def CheckOptimizedUnicode(self):
+        self.con.text_factory = sqlite.OptimizedUnicode
+        austria = unicode("Österreich", "latin1")
+        germany = unicode("Deutchland")
+        a_row = self.con.execute("select ?", (austria,)).fetchone()
+        d_row = self.con.execute("select ?", (germany,)).fetchone()
+        self.failUnless(type(a_row[0]) == unicode, "type of non-ASCII row must be unicode")
+        self.failUnless(type(d_row[0]) == str, "type of ASCII-only row must be str")
+
+    def tearDown(self):
+        self.con.close()
+
+def suite():
+    connection_suite = unittest.makeSuite(ConnectionFactoryTests, "Check")
+    cursor_suite = unittest.makeSuite(CursorFactoryTests, "Check")
+    row_suite_compat = unittest.makeSuite(RowFactoryTestsBackwardsCompat, "Check")
+    row_suite = unittest.makeSuite(RowFactoryTests, "Check")
+    text_suite = unittest.makeSuite(TextFactoryTests, "Check")
+    return unittest.TestSuite((connection_suite, cursor_suite, row_suite_compat, row_suite, text_suite))
+
+def test():
+    runner = unittest.TextTestRunner()
+    runner.run(suite())
+
+if __name__ == "__main__":
+    test()

Added: vendor/Python/current/Lib/sqlite3/test/hooks.py
===================================================================
--- vendor/Python/current/Lib/sqlite3/test/hooks.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/sqlite3/test/hooks.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,117 @@
+#-*- coding: ISO-8859-1 -*-
+# pysqlite2/test/hooks.py: tests for various SQLite-specific hooks
+#
+# Copyright (C) 2006 Gerhard Häring <gh at ghaering.de>
+#
+# This file is part of pysqlite.
+#
+# This software is provided 'as-is', without any express or implied
+# warranty.  In no event will the authors be held liable for any damages
+# arising from the use of this software.
+#
+# Permission is granted to anyone to use this software for any purpose,
+# including commercial applications, and to alter it and redistribute it
+# freely, subject to the following restrictions:
+#
+# 1. The origin of this software must not be misrepresented; you must not
+#    claim that you wrote the original software. If you use this software
+#    in a product, an acknowledgment in the product documentation would be
+#    appreciated but is not required.
+# 2. Altered source versions must be plainly marked as such, and must not be
+#    misrepresented as being the original software.
+# 3. This notice may not be removed or altered from any source distribution.
+
+import os, unittest
+import sqlite3 as sqlite
+
+class CollationTests(unittest.TestCase):
+    def setUp(self):
+        pass
+
+    def tearDown(self):
+        pass
+
+    def CheckCreateCollationNotCallable(self):
+        con = sqlite.connect(":memory:")
+        try:
+            con.create_collation("X", 42)
+            self.fail("should have raised a TypeError")
+        except TypeError, e:
+            self.failUnlessEqual(e.args[0], "parameter must be callable")
+
+    def CheckCreateCollationNotAscii(self):
+        con = sqlite.connect(":memory:")
+        try:
+            con.create_collation("collä", cmp)
+            self.fail("should have raised a ProgrammingError")
+        except sqlite.ProgrammingError, e:
+            pass
+
+    def CheckCollationIsUsed(self):
+        if sqlite.version_info < (3, 2, 1):  # old SQLite versions crash on this test
+            return
+        def mycoll(x, y):
+            # reverse order
+            return -cmp(x, y)
+
+        con = sqlite.connect(":memory:")
+        con.create_collation("mycoll", mycoll)
+        sql = """
+            select x from (
+            select 'a' as x
+            union
+            select 'b' as x
+            union
+            select 'c' as x
+            ) order by x collate mycoll
+            """
+        result = con.execute(sql).fetchall()
+        if result[0][0] != "c" or result[1][0] != "b" or result[2][0] != "a":
+            self.fail("the expected order was not returned")
+
+        con.create_collation("mycoll", None)
+        try:
+            result = con.execute(sql).fetchall()
+            self.fail("should have raised an OperationalError")
+        except sqlite.OperationalError, e:
+            self.failUnlessEqual(e.args[0].lower(), "no such collation sequence: mycoll")
+
+    def CheckCollationRegisterTwice(self):
+        """
+        Register two different collation functions under the same name.
+        Verify that the last one is actually used.
+        """
+        con = sqlite.connect(":memory:")
+        con.create_collation("mycoll", cmp)
+        con.create_collation("mycoll", lambda x, y: -cmp(x, y))
+        result = con.execute("""
+            select x from (select 'a' as x union select 'b' as x) order by x collate mycoll
+            """).fetchall()
+        if result[0][0] != 'b' or result[1][0] != 'a':
+            self.fail("wrong collation function is used")
+
+    def CheckDeregisterCollation(self):
+        """
+        Register a collation, then deregister it. Make sure an error is raised if we try
+        to use it.
+        """
+        con = sqlite.connect(":memory:")
+        con.create_collation("mycoll", cmp)
+        con.create_collation("mycoll", None)
+        try:
+            con.execute("select 'a' as x union select 'b' as x order by x collate mycoll")
+            self.fail("should have raised an OperationalError")
+        except sqlite.OperationalError, e:
+            if not e.args[0].startswith("no such collation sequence"):
+                self.fail("wrong OperationalError raised")
+
+def suite():
+    collation_suite = unittest.makeSuite(CollationTests, "Check")
+    return unittest.TestSuite((collation_suite,))
+
+def test():
+    runner = unittest.TextTestRunner()
+    runner.run(suite())
+
+if __name__ == "__main__":
+    test()

Added: vendor/Python/current/Lib/sqlite3/test/regression.py
===================================================================
--- vendor/Python/current/Lib/sqlite3/test/regression.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/sqlite3/test/regression.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,81 @@
+#-*- coding: ISO-8859-1 -*-
+# pysqlite2/test/regression.py: pysqlite regression tests
+#
+# Copyright (C) 2006 Gerhard Häring <gh at ghaering.de>
+#
+# This file is part of pysqlite.
+#
+# This software is provided 'as-is', without any express or implied
+# warranty.  In no event will the authors be held liable for any damages
+# arising from the use of this software.
+#
+# Permission is granted to anyone to use this software for any purpose,
+# including commercial applications, and to alter it and redistribute it
+# freely, subject to the following restrictions:
+#
+# 1. The origin of this software must not be misrepresented; you must not
+#    claim that you wrote the original software. If you use this software
+#    in a product, an acknowledgment in the product documentation would be
+#    appreciated but is not required.
+# 2. Altered source versions must be plainly marked as such, and must not be
+#    misrepresented as being the original software.
+# 3. This notice may not be removed or altered from any source distribution.
+
+import unittest
+import sqlite3 as sqlite
+
+class RegressionTests(unittest.TestCase):
+    def setUp(self):
+        self.con = sqlite.connect(":memory:")
+
+    def tearDown(self):
+        self.con.close()
+
+    def CheckPragmaUserVersion(self):
+        # This used to crash pysqlite because this pragma command returns NULL for the column name
+        cur = self.con.cursor()
+        cur.execute("pragma user_version")
+
+    def CheckPragmaSchemaVersion(self):
+        # This still crashed pysqlite <= 2.2.1
+        con = sqlite.connect(":memory:", detect_types=sqlite.PARSE_COLNAMES)
+        try:
+            cur = self.con.cursor()
+            cur.execute("pragma schema_version")
+        finally:
+            cur.close()
+            con.close()
+
+    def CheckStatementReset(self):
+        # pysqlite 2.1.0 to 2.2.0 have the problem that not all statements are
+        # reset before a rollback, but only those that are still in the
+        # statement cache. The others are not accessible from the connection object.
+        con = sqlite.connect(":memory:", cached_statements=5)
+        cursors = [con.cursor() for x in xrange(5)]
+        cursors[0].execute("create table test(x)")
+        for i in range(10):
+            cursors[0].executemany("insert into test(x) values (?)", [(x,) for x in xrange(10)])
+
+        for i in range(5):
+            cursors[i].execute(" " * i + "select x from test")
+
+        con.rollback()
+
+    def CheckColumnNameWithSpaces(self):
+        cur = self.con.cursor()
+        cur.execute('select 1 as "foo bar [datetime]"')
+        self.failUnlessEqual(cur.description[0][0], "foo bar")
+
+        cur.execute('select 1 as "foo baz"')
+        self.failUnlessEqual(cur.description[0][0], "foo baz")
+
+def suite():
+    regression_suite = unittest.makeSuite(RegressionTests, "Check")
+    return unittest.TestSuite((regression_suite,))
+
+def test():
+    runner = unittest.TextTestRunner()
+    runner.run(suite())
+
+if __name__ == "__main__":
+    test()

Added: vendor/Python/current/Lib/sqlite3/test/transactions.py
===================================================================
--- vendor/Python/current/Lib/sqlite3/test/transactions.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/sqlite3/test/transactions.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,156 @@
+#-*- coding: ISO-8859-1 -*-
+# pysqlite2/test/transactions.py: tests transactions
+#
+# Copyright (C) 2005 Gerhard Häring <gh at ghaering.de>
+#
+# This file is part of pysqlite.
+#
+# This software is provided 'as-is', without any express or implied
+# warranty.  In no event will the authors be held liable for any damages
+# arising from the use of this software.
+#
+# Permission is granted to anyone to use this software for any purpose,
+# including commercial applications, and to alter it and redistribute it
+# freely, subject to the following restrictions:
+#
+# 1. The origin of this software must not be misrepresented; you must not
+#    claim that you wrote the original software. If you use this software
+#    in a product, an acknowledgment in the product documentation would be
+#    appreciated but is not required.
+# 2. Altered source versions must be plainly marked as such, and must not be
+#    misrepresented as being the original software.
+# 3. This notice may not be removed or altered from any source distribution.
+
+import os, unittest
+import sqlite3 as sqlite
+
+def get_db_path():
+    return "sqlite_testdb"
+
+class TransactionTests(unittest.TestCase):
+    def setUp(self):
+        try:
+            os.remove(get_db_path())
+        except:
+            pass
+
+        self.con1 = sqlite.connect(get_db_path(), timeout=0.1)
+        self.cur1 = self.con1.cursor()
+
+        self.con2 = sqlite.connect(get_db_path(), timeout=0.1)
+        self.cur2 = self.con2.cursor()
+
+    def tearDown(self):
+        self.cur1.close()
+        self.con1.close()
+
+        self.cur2.close()
+        self.con2.close()
+
+        os.unlink(get_db_path())
+
+    def CheckDMLdoesAutoCommitBefore(self):
+        self.cur1.execute("create table test(i)")
+        self.cur1.execute("insert into test(i) values (5)")
+        self.cur1.execute("create table test2(j)")
+        self.cur2.execute("select i from test")
+        res = self.cur2.fetchall()
+        self.failUnlessEqual(len(res), 1)
+
+    def CheckInsertStartsTransaction(self):
+        self.cur1.execute("create table test(i)")
+        self.cur1.execute("insert into test(i) values (5)")
+        self.cur2.execute("select i from test")
+        res = self.cur2.fetchall()
+        self.failUnlessEqual(len(res), 0)
+
+    def CheckUpdateStartsTransaction(self):
+        self.cur1.execute("create table test(i)")
+        self.cur1.execute("insert into test(i) values (5)")
+        self.con1.commit()
+        self.cur1.execute("update test set i=6")
+        self.cur2.execute("select i from test")
+        res = self.cur2.fetchone()[0]
+        self.failUnlessEqual(res, 5)
+
+    def CheckDeleteStartsTransaction(self):
+        self.cur1.execute("create table test(i)")
+        self.cur1.execute("insert into test(i) values (5)")
+        self.con1.commit()
+        self.cur1.execute("delete from test")
+        self.cur2.execute("select i from test")
+        res = self.cur2.fetchall()
+        self.failUnlessEqual(len(res), 1)
+
+    def CheckReplaceStartsTransaction(self):
+        self.cur1.execute("create table test(i)")
+        self.cur1.execute("insert into test(i) values (5)")
+        self.con1.commit()
+        self.cur1.execute("replace into test(i) values (6)")
+        self.cur2.execute("select i from test")
+        res = self.cur2.fetchall()
+        self.failUnlessEqual(len(res), 1)
+        self.failUnlessEqual(res[0][0], 5)
+
+    def CheckToggleAutoCommit(self):
+        self.cur1.execute("create table test(i)")
+        self.cur1.execute("insert into test(i) values (5)")
+        self.con1.isolation_level = None
+        self.failUnlessEqual(self.con1.isolation_level, None)
+        self.cur2.execute("select i from test")
+        res = self.cur2.fetchall()
+        self.failUnlessEqual(len(res), 1)
+
+        self.con1.isolation_level = "DEFERRED"
+        self.failUnlessEqual(self.con1.isolation_level , "DEFERRED")
+        self.cur1.execute("insert into test(i) values (5)")
+        self.cur2.execute("select i from test")
+        res = self.cur2.fetchall()
+        self.failUnlessEqual(len(res), 1)
+
+    def CheckRaiseTimeout(self):
+        self.cur1.execute("create table test(i)")
+        self.cur1.execute("insert into test(i) values (5)")
+        try:
+            self.cur2.execute("insert into test(i) values (5)")
+            self.fail("should have raised an OperationalError")
+        except sqlite.OperationalError:
+            pass
+        except:
+            self.fail("should have raised an OperationalError")
+
+class SpecialCommandTests(unittest.TestCase):
+    def setUp(self):
+        self.con = sqlite.connect(":memory:")
+        self.cur = self.con.cursor()
+
+    def CheckVacuum(self):
+        self.cur.execute("create table test(i)")
+        self.cur.execute("insert into test(i) values (5)")
+        self.cur.execute("vacuum")
+
+    def CheckDropTable(self):
+        self.cur.execute("create table test(i)")
+        self.cur.execute("insert into test(i) values (5)")
+        self.cur.execute("drop table test")
+
+    def CheckPragma(self):
+        self.cur.execute("create table test(i)")
+        self.cur.execute("insert into test(i) values (5)")
+        self.cur.execute("pragma count_changes=1")
+
+    def tearDown(self):
+        self.cur.close()
+        self.con.close()
+
+def suite():
+    default_suite = unittest.makeSuite(TransactionTests, "Check")
+    special_command_suite = unittest.makeSuite(SpecialCommandTests, "Check")
+    return unittest.TestSuite((default_suite, special_command_suite))
+
+def test():
+    runner = unittest.TextTestRunner()
+    runner.run(suite())
+
+if __name__ == "__main__":
+    test()

Added: vendor/Python/current/Lib/sqlite3/test/types.py
===================================================================
--- vendor/Python/current/Lib/sqlite3/test/types.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/sqlite3/test/types.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,351 @@
+#-*- coding: ISO-8859-1 -*-
+# pysqlite2/test/types.py: tests for type conversion and detection
+#
+# Copyright (C) 2005 Gerhard Häring <gh at ghaering.de>
+#
+# This file is part of pysqlite.
+#
+# This software is provided 'as-is', without any express or implied
+# warranty.  In no event will the authors be held liable for any damages
+# arising from the use of this software.
+#
+# Permission is granted to anyone to use this software for any purpose,
+# including commercial applications, and to alter it and redistribute it
+# freely, subject to the following restrictions:
+#
+# 1. The origin of this software must not be misrepresented; you must not
+#    claim that you wrote the original software. If you use this software
+#    in a product, an acknowledgment in the product documentation would be
+#    appreciated but is not required.
+# 2. Altered source versions must be plainly marked as such, and must not be
+#    misrepresented as being the original software.
+# 3. This notice may not be removed or altered from any source distribution.
+
+import bz2, datetime
+import unittest
+import sqlite3 as sqlite
+
+class SqliteTypeTests(unittest.TestCase):
+    def setUp(self):
+        self.con = sqlite.connect(":memory:")
+        self.cur = self.con.cursor()
+        self.cur.execute("create table test(i integer, s varchar, f number, b blob)")
+
+    def tearDown(self):
+        self.cur.close()
+        self.con.close()
+
+    def CheckString(self):
+        self.cur.execute("insert into test(s) values (?)", (u"Österreich",))
+        self.cur.execute("select s from test")
+        row = self.cur.fetchone()
+        self.failUnlessEqual(row[0], u"Österreich")
+
+    def CheckSmallInt(self):
+        self.cur.execute("insert into test(i) values (?)", (42,))
+        self.cur.execute("select i from test")
+        row = self.cur.fetchone()
+        self.failUnlessEqual(row[0], 42)
+
+    def CheckLargeInt(self):
+        num = 2**40
+        self.cur.execute("insert into test(i) values (?)", (num,))
+        self.cur.execute("select i from test")
+        row = self.cur.fetchone()
+        self.failUnlessEqual(row[0], num)
+
+    def CheckFloat(self):
+        val = 3.14
+        self.cur.execute("insert into test(f) values (?)", (val,))
+        self.cur.execute("select f from test")
+        row = self.cur.fetchone()
+        self.failUnlessEqual(row[0], val)
+
+    def CheckBlob(self):
+        val = buffer("Guglhupf")
+        self.cur.execute("insert into test(b) values (?)", (val,))
+        self.cur.execute("select b from test")
+        row = self.cur.fetchone()
+        self.failUnlessEqual(row[0], val)
+
+    def CheckUnicodeExecute(self):
+        self.cur.execute(u"select 'Österreich'")
+        row = self.cur.fetchone()
+        self.failUnlessEqual(row[0], u"Österreich")
+
+class DeclTypesTests(unittest.TestCase):
+    class Foo:
+        def __init__(self, _val):
+            self.val = _val
+
+        def __cmp__(self, other):
+            if not isinstance(other, DeclTypesTests.Foo):
+                raise ValueError
+            if self.val == other.val:
+                return 0
+            else:
+                return 1
+
+        def __conform__(self, protocol):
+            if protocol is sqlite.PrepareProtocol:
+                return self.val
+            else:
+                return None
+
+        def __str__(self):
+            return "<%s>" % self.val
+
+    def setUp(self):
+        self.con = sqlite.connect(":memory:", detect_types=sqlite.PARSE_DECLTYPES)
+        self.cur = self.con.cursor()
+        self.cur.execute("create table test(i int, s str, f float, b bool, u unicode, foo foo, bin blob)")
+
+        # override float, make them always return the same number
+        sqlite.converters["FLOAT"] = lambda x: 47.2
+
+        # and implement two custom ones
+        sqlite.converters["BOOL"] = lambda x: bool(int(x))
+        sqlite.converters["FOO"] = DeclTypesTests.Foo
+
+    def tearDown(self):
+        del sqlite.converters["FLOAT"]
+        del sqlite.converters["BOOL"]
+        del sqlite.converters["FOO"]
+        self.cur.close()
+        self.con.close()
+
+    def CheckString(self):
+        # default
+        self.cur.execute("insert into test(s) values (?)", ("foo",))
+        self.cur.execute("select s from test")
+        row = self.cur.fetchone()
+        self.failUnlessEqual(row[0], "foo")
+
+    def CheckSmallInt(self):
+        # default
+        self.cur.execute("insert into test(i) values (?)", (42,))
+        self.cur.execute("select i from test")
+        row = self.cur.fetchone()
+        self.failUnlessEqual(row[0], 42)
+
+    def CheckLargeInt(self):
+        # default
+        num = 2**40
+        self.cur.execute("insert into test(i) values (?)", (num,))
+        self.cur.execute("select i from test")
+        row = self.cur.fetchone()
+        self.failUnlessEqual(row[0], num)
+
+    def CheckFloat(self):
+        # custom
+        val = 3.14
+        self.cur.execute("insert into test(f) values (?)", (val,))
+        self.cur.execute("select f from test")
+        row = self.cur.fetchone()
+        self.failUnlessEqual(row[0], 47.2)
+
+    def CheckBool(self):
+        # custom
+        self.cur.execute("insert into test(b) values (?)", (False,))
+        self.cur.execute("select b from test")
+        row = self.cur.fetchone()
+        self.failUnlessEqual(row[0], False)
+
+        self.cur.execute("delete from test")
+        self.cur.execute("insert into test(b) values (?)", (True,))
+        self.cur.execute("select b from test")
+        row = self.cur.fetchone()
+        self.failUnlessEqual(row[0], True)
+
+    def CheckUnicode(self):
+        # default
+        val = u"\xd6sterreich"
+        self.cur.execute("insert into test(u) values (?)", (val,))
+        self.cur.execute("select u from test")
+        row = self.cur.fetchone()
+        self.failUnlessEqual(row[0], val)
+
+    def CheckFoo(self):
+        val = DeclTypesTests.Foo("bla")
+        self.cur.execute("insert into test(foo) values (?)", (val,))
+        self.cur.execute("select foo from test")
+        row = self.cur.fetchone()
+        self.failUnlessEqual(row[0], val)
+
+    def CheckUnsupportedSeq(self):
+        class Bar: pass
+        val = Bar()
+        try:
+            self.cur.execute("insert into test(f) values (?)", (val,))
+            self.fail("should have raised an InterfaceError")
+        except sqlite.InterfaceError:
+            pass
+        except:
+            self.fail("should have raised an InterfaceError")
+
+    def CheckUnsupportedDict(self):
+        class Bar: pass
+        val = Bar()
+        try:
+            self.cur.execute("insert into test(f) values (:val)", {"val": val})
+            self.fail("should have raised an InterfaceError")
+        except sqlite.InterfaceError:
+            pass
+        except:
+            self.fail("should have raised an InterfaceError")
+
+    def CheckBlob(self):
+        # default
+        val = buffer("Guglhupf")
+        self.cur.execute("insert into test(bin) values (?)", (val,))
+        self.cur.execute("select bin from test")
+        row = self.cur.fetchone()
+        self.failUnlessEqual(row[0], val)
+
+class ColNamesTests(unittest.TestCase):
+    def setUp(self):
+        self.con = sqlite.connect(":memory:", detect_types=sqlite.PARSE_COLNAMES|sqlite.PARSE_DECLTYPES)
+        self.cur = self.con.cursor()
+        self.cur.execute("create table test(x foo)")
+
+        sqlite.converters["FOO"] = lambda x: "[%s]" % x
+        sqlite.converters["BAR"] = lambda x: "<%s>" % x
+        sqlite.converters["EXC"] = lambda x: 5/0
+
+    def tearDown(self):
+        del sqlite.converters["FOO"]
+        del sqlite.converters["BAR"]
+        del sqlite.converters["EXC"]
+        self.cur.close()
+        self.con.close()
+
+    def CheckDeclType(self):
+        self.cur.execute("insert into test(x) values (?)", ("xxx",))
+        self.cur.execute("select x from test")
+        val = self.cur.fetchone()[0]
+        self.failUnlessEqual(val, "[xxx]")
+
+    def CheckNone(self):
+        self.cur.execute("insert into test(x) values (?)", (None,))
+        self.cur.execute("select x from test")
+        val = self.cur.fetchone()[0]
+        self.failUnlessEqual(val, None)
+
+    def CheckColName(self):
+        self.cur.execute("insert into test(x) values (?)", ("xxx",))
+        self.cur.execute('select x as "x [bar]" from test')
+        val = self.cur.fetchone()[0]
+        self.failUnlessEqual(val, "<xxx>")
+
+        # Check if the stripping of colnames works. Everything after the first
+        # whitespace should be stripped.
+        self.failUnlessEqual(self.cur.description[0][0], "x")
+
+    def CheckCursorDescriptionNoRow(self):
+        """
+        cursor.description should at least provide the column name(s), even if
+        no row returned.
+        """
+        self.cur.execute("select * from test where 0 = 1")
+        self.assert_(self.cur.description[0][0] == "x")
+
+class ObjectAdaptationTests(unittest.TestCase):
+    def cast(obj):
+        return float(obj)
+    cast = staticmethod(cast)
+
+    def setUp(self):
+        self.con = sqlite.connect(":memory:")
+        try:
+            del sqlite.adapters[int]
+        except:
+            pass
+        sqlite.register_adapter(int, ObjectAdaptationTests.cast)
+        self.cur = self.con.cursor()
+
+    def tearDown(self):
+        del sqlite.adapters[(int, sqlite.PrepareProtocol)]
+        self.cur.close()
+        self.con.close()
+
+    def CheckCasterIsUsed(self):
+        self.cur.execute("select ?", (4,))
+        val = self.cur.fetchone()[0]
+        self.failUnlessEqual(type(val), float)
+
+class BinaryConverterTests(unittest.TestCase):
+    def convert(s):
+        return bz2.decompress(s)
+    convert = staticmethod(convert)
+
+    def setUp(self):
+        self.con = sqlite.connect(":memory:", detect_types=sqlite.PARSE_COLNAMES)
+        sqlite.register_converter("bin", BinaryConverterTests.convert)
+
+    def tearDown(self):
+        self.con.close()
+
+    def CheckBinaryInputForConverter(self):
+        testdata = "abcdefg" * 10
+        result = self.con.execute('select ? as "x [bin]"', (buffer(bz2.compress(testdata)),)).fetchone()[0]
+        self.failUnlessEqual(testdata, result)
+
+class DateTimeTests(unittest.TestCase):
+    def setUp(self):
+        self.con = sqlite.connect(":memory:", detect_types=sqlite.PARSE_DECLTYPES)
+        self.cur = self.con.cursor()
+        self.cur.execute("create table test(d date, ts timestamp)")
+
+    def tearDown(self):
+        self.cur.close()
+        self.con.close()
+
+    def CheckSqliteDate(self):
+        d = sqlite.Date(2004, 2, 14)
+        self.cur.execute("insert into test(d) values (?)", (d,))
+        self.cur.execute("select d from test")
+        d2 = self.cur.fetchone()[0]
+        self.failUnlessEqual(d, d2)
+
+    def CheckSqliteTimestamp(self):
+        ts = sqlite.Timestamp(2004, 2, 14, 7, 15, 0)
+        self.cur.execute("insert into test(ts) values (?)", (ts,))
+        self.cur.execute("select ts from test")
+        ts2 = self.cur.fetchone()[0]
+        self.failUnlessEqual(ts, ts2)
+
+    def CheckSqlTimestamp(self):
+        # The date functions are only available in SQLite version 3.1 or later
+        if sqlite.sqlite_version_info < (3, 1):
+            return
+
+        # SQLite's current_timestamp uses UTC time, while datetime.datetime.now() uses local time.
+        now = datetime.datetime.now()
+        self.cur.execute("insert into test(ts) values (current_timestamp)")
+        self.cur.execute("select ts from test")
+        ts = self.cur.fetchone()[0]
+        self.failUnlessEqual(type(ts), datetime.datetime)
+        self.failUnlessEqual(ts.year, now.year)
+
+    def CheckDateTimeSubSeconds(self):
+        ts = sqlite.Timestamp(2004, 2, 14, 7, 15, 0, 500000)
+        self.cur.execute("insert into test(ts) values (?)", (ts,))
+        self.cur.execute("select ts from test")
+        ts2 = self.cur.fetchone()[0]
+        self.failUnlessEqual(ts, ts2)
+
+def suite():
+    sqlite_type_suite = unittest.makeSuite(SqliteTypeTests, "Check")
+    decltypes_type_suite = unittest.makeSuite(DeclTypesTests, "Check")
+    colnames_type_suite = unittest.makeSuite(ColNamesTests, "Check")
+    adaptation_suite = unittest.makeSuite(ObjectAdaptationTests, "Check")
+    bin_suite = unittest.makeSuite(BinaryConverterTests, "Check")
+    date_suite = unittest.makeSuite(DateTimeTests, "Check")
+    return unittest.TestSuite((sqlite_type_suite, decltypes_type_suite, colnames_type_suite, adaptation_suite, bin_suite, date_suite))
+
+def test():
+    runner = unittest.TextTestRunner()
+    runner.run(suite())
+
+if __name__ == "__main__":
+    test()

Added: vendor/Python/current/Lib/sqlite3/test/userfunctions.py
===================================================================
--- vendor/Python/current/Lib/sqlite3/test/userfunctions.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/sqlite3/test/userfunctions.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,413 @@
+#-*- coding: ISO-8859-1 -*-
+# pysqlite2/test/userfunctions.py: tests for user-defined functions and
+#                                  aggregates.
+#
+# Copyright (C) 2005 Gerhard Häring <gh at ghaering.de>
+#
+# This file is part of pysqlite.
+#
+# This software is provided 'as-is', without any express or implied
+# warranty.  In no event will the authors be held liable for any damages
+# arising from the use of this software.
+#
+# Permission is granted to anyone to use this software for any purpose,
+# including commercial applications, and to alter it and redistribute it
+# freely, subject to the following restrictions:
+#
+# 1. The origin of this software must not be misrepresented; you must not
+#    claim that you wrote the original software. If you use this software
+#    in a product, an acknowledgment in the product documentation would be
+#    appreciated but is not required.
+# 2. Altered source versions must be plainly marked as such, and must not be
+#    misrepresented as being the original software.
+# 3. This notice may not be removed or altered from any source distribution.
+
+import unittest
+import sqlite3 as sqlite
+
+def func_returntext():
+    return "foo"
+def func_returnunicode():
+    return u"bar"
+def func_returnint():
+    return 42
+def func_returnfloat():
+    return 3.14
+def func_returnnull():
+    return None
+def func_returnblob():
+    return buffer("blob")
+def func_raiseexception():
+    5/0
+
+def func_isstring(v):
+    return type(v) is unicode
+def func_isint(v):
+    return type(v) is int
+def func_isfloat(v):
+    return type(v) is float
+def func_isnone(v):
+    return type(v) is type(None)
+def func_isblob(v):
+    return type(v) is buffer
+
+class AggrNoStep:
+    def __init__(self):
+        pass
+
+    def finalize(self):
+        return 1
+
+class AggrNoFinalize:
+    def __init__(self):
+        pass
+
+    def step(self, x):
+        pass
+
+class AggrExceptionInInit:
+    def __init__(self):
+        5/0
+
+    def step(self, x):
+        pass
+
+    def finalize(self):
+        pass
+
+class AggrExceptionInStep:
+    def __init__(self):
+        pass
+
+    def step(self, x):
+        5/0
+
+    def finalize(self):
+        return 42
+
+class AggrExceptionInFinalize:
+    def __init__(self):
+        pass
+
+    def step(self, x):
+        pass
+
+    def finalize(self):
+        5/0
+
+class AggrCheckType:
+    def __init__(self):
+        self.val = None
+
+    def step(self, whichType, val):
+        theType = {"str": unicode, "int": int, "float": float, "None": type(None), "blob": buffer}
+        self.val = int(theType[whichType] is type(val))
+
+    def finalize(self):
+        return self.val
+
+class AggrSum:
+    def __init__(self):
+        self.val = 0.0
+
+    def step(self, val):
+        self.val += val
+
+    def finalize(self):
+        return self.val
+
+class FunctionTests(unittest.TestCase):
+    def setUp(self):
+        self.con = sqlite.connect(":memory:")
+
+        self.con.create_function("returntext", 0, func_returntext)
+        self.con.create_function("returnunicode", 0, func_returnunicode)
+        self.con.create_function("returnint", 0, func_returnint)
+        self.con.create_function("returnfloat", 0, func_returnfloat)
+        self.con.create_function("returnnull", 0, func_returnnull)
+        self.con.create_function("returnblob", 0, func_returnblob)
+        self.con.create_function("raiseexception", 0, func_raiseexception)
+
+        self.con.create_function("isstring", 1, func_isstring)
+        self.con.create_function("isint", 1, func_isint)
+        self.con.create_function("isfloat", 1, func_isfloat)
+        self.con.create_function("isnone", 1, func_isnone)
+        self.con.create_function("isblob", 1, func_isblob)
+
+    def tearDown(self):
+        self.con.close()
+
+    def CheckFuncErrorOnCreate(self):
+        try:
+            self.con.create_function("bla", -100, lambda x: 2*x)
+            self.fail("should have raised an OperationalError")
+        except sqlite.OperationalError:
+            pass
+
+    def CheckFuncRefCount(self):
+        def getfunc():
+            def f():
+                return 1
+            return f
+        f = getfunc()
+        globals()["foo"] = f
+        # self.con.create_function("reftest", 0, getfunc())
+        self.con.create_function("reftest", 0, f)
+        cur = self.con.cursor()
+        cur.execute("select reftest()")
+
+    def CheckFuncReturnText(self):
+        cur = self.con.cursor()
+        cur.execute("select returntext()")
+        val = cur.fetchone()[0]
+        self.failUnlessEqual(type(val), unicode)
+        self.failUnlessEqual(val, "foo")
+
+    def CheckFuncReturnUnicode(self):
+        cur = self.con.cursor()
+        cur.execute("select returnunicode()")
+        val = cur.fetchone()[0]
+        self.failUnlessEqual(type(val), unicode)
+        self.failUnlessEqual(val, u"bar")
+
+    def CheckFuncReturnInt(self):
+        cur = self.con.cursor()
+        cur.execute("select returnint()")
+        val = cur.fetchone()[0]
+        self.failUnlessEqual(type(val), int)
+        self.failUnlessEqual(val, 42)
+
+    def CheckFuncReturnFloat(self):
+        cur = self.con.cursor()
+        cur.execute("select returnfloat()")
+        val = cur.fetchone()[0]
+        self.failUnlessEqual(type(val), float)
+        if val < 3.139 or val > 3.141:
+            self.fail("wrong value")
+
+    def CheckFuncReturnNull(self):
+        cur = self.con.cursor()
+        cur.execute("select returnnull()")
+        val = cur.fetchone()[0]
+        self.failUnlessEqual(type(val), type(None))
+        self.failUnlessEqual(val, None)
+
+    def CheckFuncReturnBlob(self):
+        cur = self.con.cursor()
+        cur.execute("select returnblob()")
+        val = cur.fetchone()[0]
+        self.failUnlessEqual(type(val), buffer)
+        self.failUnlessEqual(val, buffer("blob"))
+
+    def CheckFuncException(self):
+        cur = self.con.cursor()
+        try:
+            cur.execute("select raiseexception()")
+            cur.fetchone()
+            self.fail("should have raised OperationalError")
+        except sqlite.OperationalError, e:
+            self.failUnlessEqual(e.args[0], 'user-defined function raised exception')
+
+    def CheckParamString(self):
+        cur = self.con.cursor()
+        cur.execute("select isstring(?)", ("foo",))
+        val = cur.fetchone()[0]
+        self.failUnlessEqual(val, 1)
+
+    def CheckParamInt(self):
+        cur = self.con.cursor()
+        cur.execute("select isint(?)", (42,))
+        val = cur.fetchone()[0]
+        self.failUnlessEqual(val, 1)
+
+    def CheckParamFloat(self):
+        cur = self.con.cursor()
+        cur.execute("select isfloat(?)", (3.14,))
+        val = cur.fetchone()[0]
+        self.failUnlessEqual(val, 1)
+
+    def CheckParamNone(self):
+        cur = self.con.cursor()
+        cur.execute("select isnone(?)", (None,))
+        val = cur.fetchone()[0]
+        self.failUnlessEqual(val, 1)
+
+    def CheckParamBlob(self):
+        cur = self.con.cursor()
+        cur.execute("select isblob(?)", (buffer("blob"),))
+        val = cur.fetchone()[0]
+        self.failUnlessEqual(val, 1)
+
+class AggregateTests(unittest.TestCase):
+    def setUp(self):
+        self.con = sqlite.connect(":memory:")
+        cur = self.con.cursor()
+        cur.execute("""
+            create table test(
+                t text,
+                i integer,
+                f float,
+                n,
+                b blob
+                )
+            """)
+        cur.execute("insert into test(t, i, f, n, b) values (?, ?, ?, ?, ?)",
+            ("foo", 5, 3.14, None, buffer("blob"),))
+
+        self.con.create_aggregate("nostep", 1, AggrNoStep)
+        self.con.create_aggregate("nofinalize", 1, AggrNoFinalize)
+        self.con.create_aggregate("excInit", 1, AggrExceptionInInit)
+        self.con.create_aggregate("excStep", 1, AggrExceptionInStep)
+        self.con.create_aggregate("excFinalize", 1, AggrExceptionInFinalize)
+        self.con.create_aggregate("checkType", 2, AggrCheckType)
+        self.con.create_aggregate("mysum", 1, AggrSum)
+
+    def tearDown(self):
+        #self.cur.close()
+        #self.con.close()
+        pass
+
+    def CheckAggrErrorOnCreate(self):
+        try:
+            self.con.create_function("bla", -100, AggrSum)
+            self.fail("should have raised an OperationalError")
+        except sqlite.OperationalError:
+            pass
+
+    def CheckAggrNoStep(self):
+        cur = self.con.cursor()
+        try:
+            cur.execute("select nostep(t) from test")
+            self.fail("should have raised an AttributeError")
+        except AttributeError, e:
+            self.failUnlessEqual(e.args[0], "AggrNoStep instance has no attribute 'step'")
+
+    def CheckAggrNoFinalize(self):
+        cur = self.con.cursor()
+        try:
+            cur.execute("select nofinalize(t) from test")
+            val = cur.fetchone()[0]
+            self.fail("should have raised an OperationalError")
+        except sqlite.OperationalError, e:
+            self.failUnlessEqual(e.args[0], "user-defined aggregate's 'finalize' method raised error")
+
+    def CheckAggrExceptionInInit(self):
+        cur = self.con.cursor()
+        try:
+            cur.execute("select excInit(t) from test")
+            val = cur.fetchone()[0]
+            self.fail("should have raised an OperationalError")
+        except sqlite.OperationalError, e:
+            self.failUnlessEqual(e.args[0], "user-defined aggregate's '__init__' method raised error")
+
+    def CheckAggrExceptionInStep(self):
+        cur = self.con.cursor()
+        try:
+            cur.execute("select excStep(t) from test")
+            val = cur.fetchone()[0]
+            self.fail("should have raised an OperationalError")
+        except sqlite.OperationalError, e:
+            self.failUnlessEqual(e.args[0], "user-defined aggregate's 'step' method raised error")
+
+    def CheckAggrExceptionInFinalize(self):
+        cur = self.con.cursor()
+        try:
+            cur.execute("select excFinalize(t) from test")
+            val = cur.fetchone()[0]
+            self.fail("should have raised an OperationalError")
+        except sqlite.OperationalError, e:
+            self.failUnlessEqual(e.args[0], "user-defined aggregate's 'finalize' method raised error")
+
+    def CheckAggrCheckParamStr(self):
+        cur = self.con.cursor()
+        cur.execute("select checkType('str', ?)", ("foo",))
+        val = cur.fetchone()[0]
+        self.failUnlessEqual(val, 1)
+
+    def CheckAggrCheckParamInt(self):
+        cur = self.con.cursor()
+        cur.execute("select checkType('int', ?)", (42,))
+        val = cur.fetchone()[0]
+        self.failUnlessEqual(val, 1)
+
+    def CheckAggrCheckParamFloat(self):
+        cur = self.con.cursor()
+        cur.execute("select checkType('float', ?)", (3.14,))
+        val = cur.fetchone()[0]
+        self.failUnlessEqual(val, 1)
+
+    def CheckAggrCheckParamNone(self):
+        cur = self.con.cursor()
+        cur.execute("select checkType('None', ?)", (None,))
+        val = cur.fetchone()[0]
+        self.failUnlessEqual(val, 1)
+
+    def CheckAggrCheckParamBlob(self):
+        cur = self.con.cursor()
+        cur.execute("select checkType('blob', ?)", (buffer("blob"),))
+        val = cur.fetchone()[0]
+        self.failUnlessEqual(val, 1)
+
+    def CheckAggrCheckAggrSum(self):
+        cur = self.con.cursor()
+        cur.execute("delete from test")
+        cur.executemany("insert into test(i) values (?)", [(10,), (20,), (30,)])
+        cur.execute("select mysum(i) from test")
+        val = cur.fetchone()[0]
+        self.failUnlessEqual(val, 60)
+
+def authorizer_cb(action, arg1, arg2, dbname, source):
+    if action != sqlite.SQLITE_SELECT:
+        return sqlite.SQLITE_DENY
+    if arg2 == 'c2' or arg1 == 't2':
+        return sqlite.SQLITE_DENY
+    return sqlite.SQLITE_OK
+
+class AuthorizerTests(unittest.TestCase):
+    def setUp(self):
+        self.con = sqlite.connect(":memory:")
+        self.con.executescript("""
+            create table t1 (c1, c2);
+            create table t2 (c1, c2);
+            insert into t1 (c1, c2) values (1, 2);
+            insert into t2 (c1, c2) values (4, 5);
+            """)
+
+        # For our security test:
+        self.con.execute("select c2 from t2")
+
+        self.con.set_authorizer(authorizer_cb)
+
+    def tearDown(self):
+        pass
+
+    def CheckTableAccess(self):
+        try:
+            self.con.execute("select * from t2")
+        except sqlite.DatabaseError, e:
+            if not e.args[0].endswith("prohibited"):
+                self.fail("wrong exception text: %s" % e.args[0])
+            return
+        self.fail("should have raised an exception due to missing privileges")
+
+    def CheckColumnAccess(self):
+        try:
+            self.con.execute("select c2 from t1")
+        except sqlite.DatabaseError, e:
+            if not e.args[0].endswith("prohibited"):
+                self.fail("wrong exception text: %s" % e.args[0])
+            return
+        self.fail("should have raised an exception due to missing privileges")
+
+def suite():
+    function_suite = unittest.makeSuite(FunctionTests, "Check")
+    aggregate_suite = unittest.makeSuite(AggregateTests, "Check")
+    authorizer_suite = unittest.makeSuite(AuthorizerTests, "Check")
+    return unittest.TestSuite((function_suite, aggregate_suite, authorizer_suite))
+
+def test():
+    runner = unittest.TextTestRunner()
+    runner.run(suite())
+
+if __name__ == "__main__":
+    test()

Added: vendor/Python/current/Lib/sre.py
===================================================================
--- vendor/Python/current/Lib/sre.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/sre.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,13 @@
+"""This file is only retained for backwards compatibility.
+It will be removed in the future.  sre was moved to re in version 2.5.
+"""
+
+import warnings
+warnings.warn("The sre module is deprecated, please import re.",
+              DeprecationWarning, 2)
+
+from re import *
+from re import __all__
+
+# old pickles expect the _compile() reconstructor in this module
+from re import _compile

Added: vendor/Python/current/Lib/sre_compile.py
===================================================================
--- vendor/Python/current/Lib/sre_compile.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/sre_compile.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,531 @@
+#
+# Secret Labs' Regular Expression Engine
+#
+# convert template to internal format
+#
+# Copyright (c) 1997-2001 by Secret Labs AB.  All rights reserved.
+#
+# See the sre.py file for information on usage and redistribution.
+#
+
+"""Internal support module for sre"""
+
+import _sre, sys
+
+from sre_constants import *
+
+assert _sre.MAGIC == MAGIC, "SRE module mismatch"
+
+if _sre.CODESIZE == 2:
+    MAXCODE = 65535
+else:
+    MAXCODE = 0xFFFFFFFFL
+
+def _identityfunction(x):
+    return x
+
+def set(seq):
+    s = {}
+    for elem in seq:
+        s[elem] = 1
+    return s
+
+_LITERAL_CODES = set([LITERAL, NOT_LITERAL])
+_REPEATING_CODES = set([REPEAT, MIN_REPEAT, MAX_REPEAT])
+_SUCCESS_CODES = set([SUCCESS, FAILURE])
+_ASSERT_CODES = set([ASSERT, ASSERT_NOT])
+
+def _compile(code, pattern, flags):
+    # internal: compile a (sub)pattern
+    emit = code.append
+    _len = len
+    LITERAL_CODES = _LITERAL_CODES
+    REPEATING_CODES = _REPEATING_CODES
+    SUCCESS_CODES = _SUCCESS_CODES
+    ASSERT_CODES = _ASSERT_CODES
+    for op, av in pattern:
+        if op in LITERAL_CODES:
+            if flags & SRE_FLAG_IGNORECASE:
+                emit(OPCODES[OP_IGNORE[op]])
+                emit(_sre.getlower(av, flags))
+            else:
+                emit(OPCODES[op])
+                emit(av)
+        elif op is IN:
+            if flags & SRE_FLAG_IGNORECASE:
+                emit(OPCODES[OP_IGNORE[op]])
+                def fixup(literal, flags=flags):
+                    return _sre.getlower(literal, flags)
+            else:
+                emit(OPCODES[op])
+                fixup = _identityfunction
+            skip = _len(code); emit(0)
+            _compile_charset(av, flags, code, fixup)
+            code[skip] = _len(code) - skip
+        elif op is ANY:
+            if flags & SRE_FLAG_DOTALL:
+                emit(OPCODES[ANY_ALL])
+            else:
+                emit(OPCODES[ANY])
+        elif op in REPEATING_CODES:
+            if flags & SRE_FLAG_TEMPLATE:
+                raise error, "internal: unsupported template operator"
+                emit(OPCODES[REPEAT])
+                skip = _len(code); emit(0)
+                emit(av[0])
+                emit(av[1])
+                _compile(code, av[2], flags)
+                emit(OPCODES[SUCCESS])
+                code[skip] = _len(code) - skip
+            elif _simple(av) and op is not REPEAT:
+                if op is MAX_REPEAT:
+                    emit(OPCODES[REPEAT_ONE])
+                else:
+                    emit(OPCODES[MIN_REPEAT_ONE])
+                skip = _len(code); emit(0)
+                emit(av[0])
+                emit(av[1])
+                _compile(code, av[2], flags)
+                emit(OPCODES[SUCCESS])
+                code[skip] = _len(code) - skip
+            else:
+                emit(OPCODES[REPEAT])
+                skip = _len(code); emit(0)
+                emit(av[0])
+                emit(av[1])
+                _compile(code, av[2], flags)
+                code[skip] = _len(code) - skip
+                if op is MAX_REPEAT:
+                    emit(OPCODES[MAX_UNTIL])
+                else:
+                    emit(OPCODES[MIN_UNTIL])
+        elif op is SUBPATTERN:
+            if av[0]:
+                emit(OPCODES[MARK])
+                emit((av[0]-1)*2)
+            # _compile_info(code, av[1], flags)
+            _compile(code, av[1], flags)
+            if av[0]:
+                emit(OPCODES[MARK])
+                emit((av[0]-1)*2+1)
+        elif op in SUCCESS_CODES:
+            emit(OPCODES[op])
+        elif op in ASSERT_CODES:
+            emit(OPCODES[op])
+            skip = _len(code); emit(0)
+            if av[0] >= 0:
+                emit(0) # look ahead
+            else:
+                lo, hi = av[1].getwidth()
+                if lo != hi:
+                    raise error, "look-behind requires fixed-width pattern"
+                emit(lo) # look behind
+            _compile(code, av[1], flags)
+            emit(OPCODES[SUCCESS])
+            code[skip] = _len(code) - skip
+        elif op is CALL:
+            emit(OPCODES[op])
+            skip = _len(code); emit(0)
+            _compile(code, av, flags)
+            emit(OPCODES[SUCCESS])
+            code[skip] = _len(code) - skip
+        elif op is AT:
+            emit(OPCODES[op])
+            if flags & SRE_FLAG_MULTILINE:
+                av = AT_MULTILINE.get(av, av)
+            if flags & SRE_FLAG_LOCALE:
+                av = AT_LOCALE.get(av, av)
+            elif flags & SRE_FLAG_UNICODE:
+                av = AT_UNICODE.get(av, av)
+            emit(ATCODES[av])
+        elif op is BRANCH:
+            emit(OPCODES[op])
+            tail = []
+            tailappend = tail.append
+            for av in av[1]:
+                skip = _len(code); emit(0)
+                # _compile_info(code, av, flags)
+                _compile(code, av, flags)
+                emit(OPCODES[JUMP])
+                tailappend(_len(code)); emit(0)
+                code[skip] = _len(code) - skip
+            emit(0) # end of branch
+            for tail in tail:
+                code[tail] = _len(code) - tail
+        elif op is CATEGORY:
+            emit(OPCODES[op])
+            if flags & SRE_FLAG_LOCALE:
+                av = CH_LOCALE[av]
+            elif flags & SRE_FLAG_UNICODE:
+                av = CH_UNICODE[av]
+            emit(CHCODES[av])
+        elif op is GROUPREF:
+            if flags & SRE_FLAG_IGNORECASE:
+                emit(OPCODES[OP_IGNORE[op]])
+            else:
+                emit(OPCODES[op])
+            emit(av-1)
+        elif op is GROUPREF_EXISTS:
+            emit(OPCODES[op])
+            emit(av[0]-1)
+            skipyes = _len(code); emit(0)
+            _compile(code, av[1], flags)
+            if av[2]:
+                emit(OPCODES[JUMP])
+                skipno = _len(code); emit(0)
+                code[skipyes] = _len(code) - skipyes + 1
+                _compile(code, av[2], flags)
+                code[skipno] = _len(code) - skipno
+            else:
+                code[skipyes] = _len(code) - skipyes + 1
+        else:
+            raise ValueError, ("unsupported operand type", op)
+
+def _compile_charset(charset, flags, code, fixup=None):
+    # compile charset subprogram
+    emit = code.append
+    if fixup is None:
+        fixup = _identityfunction
+    for op, av in _optimize_charset(charset, fixup):
+        emit(OPCODES[op])
+        if op is NEGATE:
+            pass
+        elif op is LITERAL:
+            emit(fixup(av))
+        elif op is RANGE:
+            emit(fixup(av[0]))
+            emit(fixup(av[1]))
+        elif op is CHARSET:
+            code.extend(av)
+        elif op is BIGCHARSET:
+            code.extend(av)
+        elif op is CATEGORY:
+            if flags & SRE_FLAG_LOCALE:
+                emit(CHCODES[CH_LOCALE[av]])
+            elif flags & SRE_FLAG_UNICODE:
+                emit(CHCODES[CH_UNICODE[av]])
+            else:
+                emit(CHCODES[av])
+        else:
+            raise error, "internal: unsupported set operator"
+    emit(OPCODES[FAILURE])
+
+def _optimize_charset(charset, fixup):
+    # internal: optimize character set
+    out = []
+    outappend = out.append
+    charmap = [0]*256
+    try:
+        for op, av in charset:
+            if op is NEGATE:
+                outappend((op, av))
+            elif op is LITERAL:
+                charmap[fixup(av)] = 1
+            elif op is RANGE:
+                for i in range(fixup(av[0]), fixup(av[1])+1):
+                    charmap[i] = 1
+            elif op is CATEGORY:
+                # XXX: could append to charmap tail
+                return charset # cannot compress
+    except IndexError:
+        # character set contains unicode characters
+        return _optimize_unicode(charset, fixup)
+    # compress character map
+    i = p = n = 0
+    runs = []
+    runsappend = runs.append
+    for c in charmap:
+        if c:
+            if n == 0:
+                p = i
+            n = n + 1
+        elif n:
+            runsappend((p, n))
+            n = 0
+        i = i + 1
+    if n:
+        runsappend((p, n))
+    if len(runs) <= 2:
+        # use literal/range
+        for p, n in runs:
+            if n == 1:
+                outappend((LITERAL, p))
+            else:
+                outappend((RANGE, (p, p+n-1)))
+        if len(out) < len(charset):
+            return out
+    else:
+        # use bitmap
+        data = _mk_bitmap(charmap)
+        outappend((CHARSET, data))
+        return out
+    return charset
+
+def _mk_bitmap(bits):
+    data = []
+    dataappend = data.append
+    if _sre.CODESIZE == 2:
+        start = (1, 0)
+    else:
+        start = (1L, 0L)
+    m, v = start
+    for c in bits:
+        if c:
+            v = v + m
+        m = m + m
+        if m > MAXCODE:
+            dataappend(v)
+            m, v = start
+    return data
+
+# To represent a big charset, first a bitmap of all characters in the
+# set is constructed. Then, this bitmap is sliced into chunks of 256
+# characters, duplicate chunks are eliminitated, and each chunk is
+# given a number. In the compiled expression, the charset is
+# represented by a 16-bit word sequence, consisting of one word for
+# the number of different chunks, a sequence of 256 bytes (128 words)
+# of chunk numbers indexed by their original chunk position, and a
+# sequence of chunks (16 words each).
+
+# Compression is normally good: in a typical charset, large ranges of
+# Unicode will be either completely excluded (e.g. if only cyrillic
+# letters are to be matched), or completely included (e.g. if large
+# subranges of Kanji match). These ranges will be represented by
+# chunks of all one-bits or all zero-bits.
+
+# Matching can be also done efficiently: the more significant byte of
+# the Unicode character is an index into the chunk number, and the
+# less significant byte is a bit index in the chunk (just like the
+# CHARSET matching).
+
+# In UCS-4 mode, the BIGCHARSET opcode still supports only subsets
+# of the basic multilingual plane; an efficient representation
+# for all of UTF-16 has not yet been developed. This means,
+# in particular, that negated charsets cannot be represented as
+# bigcharsets.
+
+def _optimize_unicode(charset, fixup):
+    try:
+        import array
+    except ImportError:
+        return charset
+    charmap = [0]*65536
+    negate = 0
+    try:
+        for op, av in charset:
+            if op is NEGATE:
+                negate = 1
+            elif op is LITERAL:
+                charmap[fixup(av)] = 1
+            elif op is RANGE:
+                for i in xrange(fixup(av[0]), fixup(av[1])+1):
+                    charmap[i] = 1
+            elif op is CATEGORY:
+                # XXX: could expand category
+                return charset # cannot compress
+    except IndexError:
+        # non-BMP characters
+        return charset
+    if negate:
+        if sys.maxunicode != 65535:
+            # XXX: negation does not work with big charsets
+            return charset
+        for i in xrange(65536):
+            charmap[i] = not charmap[i]
+    comps = {}
+    mapping = [0]*256
+    block = 0
+    data = []
+    for i in xrange(256):
+        chunk = tuple(charmap[i*256:(i+1)*256])
+        new = comps.setdefault(chunk, block)
+        mapping[i] = new
+        if new == block:
+            block = block + 1
+            data = data + _mk_bitmap(chunk)
+    header = [block]
+    if _sre.CODESIZE == 2:
+        code = 'H'
+    else:
+        code = 'I'
+    # Convert block indices to byte array of 256 bytes
+    mapping = array.array('b', mapping).tostring()
+    # Convert byte array to word array
+    mapping = array.array(code, mapping)
+    assert mapping.itemsize == _sre.CODESIZE
+    header = header + mapping.tolist()
+    data[0:0] = header
+    return [(BIGCHARSET, data)]
+
+def _simple(av):
+    # check if av is a "simple" operator
+    lo, hi = av[2].getwidth()
+    if lo == 0 and hi == MAXREPEAT:
+        raise error, "nothing to repeat"
+    return lo == hi == 1 and av[2][0][0] != SUBPATTERN
+
+def _compile_info(code, pattern, flags):
+    # internal: compile an info block.  in the current version,
+    # this contains min/max pattern width, and an optional literal
+    # prefix or a character map
+    lo, hi = pattern.getwidth()
+    if lo == 0:
+        return # not worth it
+    # look for a literal prefix
+    prefix = []
+    prefixappend = prefix.append
+    prefix_skip = 0
+    charset = [] # not used
+    charsetappend = charset.append
+    if not (flags & SRE_FLAG_IGNORECASE):
+        # look for literal prefix
+        for op, av in pattern.data:
+            if op is LITERAL:
+                if len(prefix) == prefix_skip:
+                    prefix_skip = prefix_skip + 1
+                prefixappend(av)
+            elif op is SUBPATTERN and len(av[1]) == 1:
+                op, av = av[1][0]
+                if op is LITERAL:
+                    prefixappend(av)
+                else:
+                    break
+            else:
+                break
+        # if no prefix, look for charset prefix
+        if not prefix and pattern.data:
+            op, av = pattern.data[0]
+            if op is SUBPATTERN and av[1]:
+                op, av = av[1][0]
+                if op is LITERAL:
+                    charsetappend((op, av))
+                elif op is BRANCH:
+                    c = []
+                    cappend = c.append
+                    for p in av[1]:
+                        if not p:
+                            break
+                        op, av = p[0]
+                        if op is LITERAL:
+                            cappend((op, av))
+                        else:
+                            break
+                    else:
+                        charset = c
+            elif op is BRANCH:
+                c = []
+                cappend = c.append
+                for p in av[1]:
+                    if not p:
+                        break
+                    op, av = p[0]
+                    if op is LITERAL:
+                        cappend((op, av))
+                    else:
+                        break
+                else:
+                    charset = c
+            elif op is IN:
+                charset = av
+##     if prefix:
+##         print "*** PREFIX", prefix, prefix_skip
+##     if charset:
+##         print "*** CHARSET", charset
+    # add an info block
+    emit = code.append
+    emit(OPCODES[INFO])
+    skip = len(code); emit(0)
+    # literal flag
+    mask = 0
+    if prefix:
+        mask = SRE_INFO_PREFIX
+        if len(prefix) == prefix_skip == len(pattern.data):
+            mask = mask + SRE_INFO_LITERAL
+    elif charset:
+        mask = mask + SRE_INFO_CHARSET
+    emit(mask)
+    # pattern length
+    if lo < MAXCODE:
+        emit(lo)
+    else:
+        emit(MAXCODE)
+        prefix = prefix[:MAXCODE]
+    if hi < MAXCODE:
+        emit(hi)
+    else:
+        emit(0)
+    # add literal prefix
+    if prefix:
+        emit(len(prefix)) # length
+        emit(prefix_skip) # skip
+        code.extend(prefix)
+        # generate overlap table
+        table = [-1] + ([0]*len(prefix))
+        for i in xrange(len(prefix)):
+            table[i+1] = table[i]+1
+            while table[i+1] > 0 and prefix[i] != prefix[table[i+1]-1]:
+                table[i+1] = table[table[i+1]-1]+1
+        code.extend(table[1:]) # don't store first entry
+    elif charset:
+        _compile_charset(charset, flags, code)
+    code[skip] = len(code) - skip
+
+try:
+    unicode
+except NameError:
+    STRING_TYPES = (type(""),)
+else:
+    STRING_TYPES = (type(""), type(unicode("")))
+
+def isstring(obj):
+    for tp in STRING_TYPES:
+        if isinstance(obj, tp):
+            return 1
+    return 0
+
+def _code(p, flags):
+
+    flags = p.pattern.flags | flags
+    code = []
+
+    # compile info block
+    _compile_info(code, p, flags)
+
+    # compile the pattern
+    _compile(code, p.data, flags)
+
+    code.append(OPCODES[SUCCESS])
+
+    return code
+
+def compile(p, flags=0):
+    # internal: convert pattern list to internal format
+
+    if isstring(p):
+        import sre_parse
+        pattern = p
+        p = sre_parse.parse(p, flags)
+    else:
+        pattern = None
+
+    code = _code(p, flags)
+
+    # print code
+
+    # XXX: <fl> get rid of this limitation!
+    if p.pattern.groups > 100:
+        raise AssertionError(
+            "sorry, but this version only supports 100 named groups"
+            )
+
+    # map in either direction
+    groupindex = p.pattern.groupdict
+    indexgroup = [None] * p.pattern.groups
+    for k, i in groupindex.items():
+        indexgroup[i] = k
+
+    return _sre.compile(
+        pattern, flags, code,
+        p.pattern.groups-1,
+        groupindex, indexgroup
+        )

Added: vendor/Python/current/Lib/sre_constants.py
===================================================================
--- vendor/Python/current/Lib/sre_constants.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/sre_constants.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,261 @@
+#
+# Secret Labs' Regular Expression Engine
+#
+# various symbols used by the regular expression engine.
+# run this script to update the _sre include files!
+#
+# Copyright (c) 1998-2001 by Secret Labs AB.  All rights reserved.
+#
+# See the sre.py file for information on usage and redistribution.
+#
+
+"""Internal support module for sre"""
+
+# update when constants are added or removed
+
+MAGIC = 20031017
+
+# max code word in this release
+
+MAXREPEAT = 65535
+
+# SRE standard exception (access as sre.error)
+# should this really be here?
+
+class error(Exception):
+    pass
+
+# operators
+
+FAILURE = "failure"
+SUCCESS = "success"
+
+ANY = "any"
+ANY_ALL = "any_all"
+ASSERT = "assert"
+ASSERT_NOT = "assert_not"
+AT = "at"
+BIGCHARSET = "bigcharset"
+BRANCH = "branch"
+CALL = "call"
+CATEGORY = "category"
+CHARSET = "charset"
+GROUPREF = "groupref"
+GROUPREF_IGNORE = "groupref_ignore"
+GROUPREF_EXISTS = "groupref_exists"
+IN = "in"
+IN_IGNORE = "in_ignore"
+INFO = "info"
+JUMP = "jump"
+LITERAL = "literal"
+LITERAL_IGNORE = "literal_ignore"
+MARK = "mark"
+MAX_REPEAT = "max_repeat"
+MAX_UNTIL = "max_until"
+MIN_REPEAT = "min_repeat"
+MIN_UNTIL = "min_until"
+NEGATE = "negate"
+NOT_LITERAL = "not_literal"
+NOT_LITERAL_IGNORE = "not_literal_ignore"
+RANGE = "range"
+REPEAT = "repeat"
+REPEAT_ONE = "repeat_one"
+SUBPATTERN = "subpattern"
+MIN_REPEAT_ONE = "min_repeat_one"
+
+# positions
+AT_BEGINNING = "at_beginning"
+AT_BEGINNING_LINE = "at_beginning_line"
+AT_BEGINNING_STRING = "at_beginning_string"
+AT_BOUNDARY = "at_boundary"
+AT_NON_BOUNDARY = "at_non_boundary"
+AT_END = "at_end"
+AT_END_LINE = "at_end_line"
+AT_END_STRING = "at_end_string"
+AT_LOC_BOUNDARY = "at_loc_boundary"
+AT_LOC_NON_BOUNDARY = "at_loc_non_boundary"
+AT_UNI_BOUNDARY = "at_uni_boundary"
+AT_UNI_NON_BOUNDARY = "at_uni_non_boundary"
+
+# categories
+CATEGORY_DIGIT = "category_digit"
+CATEGORY_NOT_DIGIT = "category_not_digit"
+CATEGORY_SPACE = "category_space"
+CATEGORY_NOT_SPACE = "category_not_space"
+CATEGORY_WORD = "category_word"
+CATEGORY_NOT_WORD = "category_not_word"
+CATEGORY_LINEBREAK = "category_linebreak"
+CATEGORY_NOT_LINEBREAK = "category_not_linebreak"
+CATEGORY_LOC_WORD = "category_loc_word"
+CATEGORY_LOC_NOT_WORD = "category_loc_not_word"
+CATEGORY_UNI_DIGIT = "category_uni_digit"
+CATEGORY_UNI_NOT_DIGIT = "category_uni_not_digit"
+CATEGORY_UNI_SPACE = "category_uni_space"
+CATEGORY_UNI_NOT_SPACE = "category_uni_not_space"
+CATEGORY_UNI_WORD = "category_uni_word"
+CATEGORY_UNI_NOT_WORD = "category_uni_not_word"
+CATEGORY_UNI_LINEBREAK = "category_uni_linebreak"
+CATEGORY_UNI_NOT_LINEBREAK = "category_uni_not_linebreak"
+
+OPCODES = [
+
+    # failure=0 success=1 (just because it looks better that way :-)
+    FAILURE, SUCCESS,
+
+    ANY, ANY_ALL,
+    ASSERT, ASSERT_NOT,
+    AT,
+    BRANCH,
+    CALL,
+    CATEGORY,
+    CHARSET, BIGCHARSET,
+    GROUPREF, GROUPREF_EXISTS, GROUPREF_IGNORE,
+    IN, IN_IGNORE,
+    INFO,
+    JUMP,
+    LITERAL, LITERAL_IGNORE,
+    MARK,
+    MAX_UNTIL,
+    MIN_UNTIL,
+    NOT_LITERAL, NOT_LITERAL_IGNORE,
+    NEGATE,
+    RANGE,
+    REPEAT,
+    REPEAT_ONE,
+    SUBPATTERN,
+    MIN_REPEAT_ONE
+
+]
+
+ATCODES = [
+    AT_BEGINNING, AT_BEGINNING_LINE, AT_BEGINNING_STRING, AT_BOUNDARY,
+    AT_NON_BOUNDARY, AT_END, AT_END_LINE, AT_END_STRING,
+    AT_LOC_BOUNDARY, AT_LOC_NON_BOUNDARY, AT_UNI_BOUNDARY,
+    AT_UNI_NON_BOUNDARY
+]
+
+CHCODES = [
+    CATEGORY_DIGIT, CATEGORY_NOT_DIGIT, CATEGORY_SPACE,
+    CATEGORY_NOT_SPACE, CATEGORY_WORD, CATEGORY_NOT_WORD,
+    CATEGORY_LINEBREAK, CATEGORY_NOT_LINEBREAK, CATEGORY_LOC_WORD,
+    CATEGORY_LOC_NOT_WORD, CATEGORY_UNI_DIGIT, CATEGORY_UNI_NOT_DIGIT,
+    CATEGORY_UNI_SPACE, CATEGORY_UNI_NOT_SPACE, CATEGORY_UNI_WORD,
+    CATEGORY_UNI_NOT_WORD, CATEGORY_UNI_LINEBREAK,
+    CATEGORY_UNI_NOT_LINEBREAK
+]
+
+def makedict(list):
+    d = {}
+    i = 0
+    for item in list:
+        d[item] = i
+        i = i + 1
+    return d
+
+OPCODES = makedict(OPCODES)
+ATCODES = makedict(ATCODES)
+CHCODES = makedict(CHCODES)
+
+# replacement operations for "ignore case" mode
+OP_IGNORE = {
+    GROUPREF: GROUPREF_IGNORE,
+    IN: IN_IGNORE,
+    LITERAL: LITERAL_IGNORE,
+    NOT_LITERAL: NOT_LITERAL_IGNORE
+}
+
+AT_MULTILINE = {
+    AT_BEGINNING: AT_BEGINNING_LINE,
+    AT_END: AT_END_LINE
+}
+
+AT_LOCALE = {
+    AT_BOUNDARY: AT_LOC_BOUNDARY,
+    AT_NON_BOUNDARY: AT_LOC_NON_BOUNDARY
+}
+
+AT_UNICODE = {
+    AT_BOUNDARY: AT_UNI_BOUNDARY,
+    AT_NON_BOUNDARY: AT_UNI_NON_BOUNDARY
+}
+
+CH_LOCALE = {
+    CATEGORY_DIGIT: CATEGORY_DIGIT,
+    CATEGORY_NOT_DIGIT: CATEGORY_NOT_DIGIT,
+    CATEGORY_SPACE: CATEGORY_SPACE,
+    CATEGORY_NOT_SPACE: CATEGORY_NOT_SPACE,
+    CATEGORY_WORD: CATEGORY_LOC_WORD,
+    CATEGORY_NOT_WORD: CATEGORY_LOC_NOT_WORD,
+    CATEGORY_LINEBREAK: CATEGORY_LINEBREAK,
+    CATEGORY_NOT_LINEBREAK: CATEGORY_NOT_LINEBREAK
+}
+
+CH_UNICODE = {
+    CATEGORY_DIGIT: CATEGORY_UNI_DIGIT,
+    CATEGORY_NOT_DIGIT: CATEGORY_UNI_NOT_DIGIT,
+    CATEGORY_SPACE: CATEGORY_UNI_SPACE,
+    CATEGORY_NOT_SPACE: CATEGORY_UNI_NOT_SPACE,
+    CATEGORY_WORD: CATEGORY_UNI_WORD,
+    CATEGORY_NOT_WORD: CATEGORY_UNI_NOT_WORD,
+    CATEGORY_LINEBREAK: CATEGORY_UNI_LINEBREAK,
+    CATEGORY_NOT_LINEBREAK: CATEGORY_UNI_NOT_LINEBREAK
+}
+
+# flags
+SRE_FLAG_TEMPLATE = 1 # template mode (disable backtracking)
+SRE_FLAG_IGNORECASE = 2 # case insensitive
+SRE_FLAG_LOCALE = 4 # honour system locale
+SRE_FLAG_MULTILINE = 8 # treat target as multiline string
+SRE_FLAG_DOTALL = 16 # treat target as a single string
+SRE_FLAG_UNICODE = 32 # use unicode locale
+SRE_FLAG_VERBOSE = 64 # ignore whitespace and comments
+SRE_FLAG_DEBUG = 128 # debugging
+
+# flags for INFO primitive
+SRE_INFO_PREFIX = 1 # has prefix
+SRE_INFO_LITERAL = 2 # entire pattern is literal (given by prefix)
+SRE_INFO_CHARSET = 4 # pattern starts with character from given set
+
+if __name__ == "__main__":
+    def dump(f, d, prefix):
+        items = d.items()
+        items.sort(key=lambda a: a[1])
+        for k, v in items:
+            f.write("#define %s_%s %s\n" % (prefix, k.upper(), v))
+    f = open("sre_constants.h", "w")
+    f.write("""\
+/*
+ * Secret Labs' Regular Expression Engine
+ *
+ * regular expression matching engine
+ *
+ * NOTE: This file is generated by sre_constants.py.  If you need
+ * to change anything in here, edit sre_constants.py and run it.
+ *
+ * Copyright (c) 1997-2001 by Secret Labs AB.  All rights reserved.
+ *
+ * See the _sre.c file for information on usage and redistribution.
+ */
+
+""")
+
+    f.write("#define SRE_MAGIC %d\n" % MAGIC)
+
+    dump(f, OPCODES, "SRE_OP")
+    dump(f, ATCODES, "SRE")
+    dump(f, CHCODES, "SRE")
+
+    f.write("#define SRE_FLAG_TEMPLATE %d\n" % SRE_FLAG_TEMPLATE)
+    f.write("#define SRE_FLAG_IGNORECASE %d\n" % SRE_FLAG_IGNORECASE)
+    f.write("#define SRE_FLAG_LOCALE %d\n" % SRE_FLAG_LOCALE)
+    f.write("#define SRE_FLAG_MULTILINE %d\n" % SRE_FLAG_MULTILINE)
+    f.write("#define SRE_FLAG_DOTALL %d\n" % SRE_FLAG_DOTALL)
+    f.write("#define SRE_FLAG_UNICODE %d\n" % SRE_FLAG_UNICODE)
+    f.write("#define SRE_FLAG_VERBOSE %d\n" % SRE_FLAG_VERBOSE)
+
+    f.write("#define SRE_INFO_PREFIX %d\n" % SRE_INFO_PREFIX)
+    f.write("#define SRE_INFO_LITERAL %d\n" % SRE_INFO_LITERAL)
+    f.write("#define SRE_INFO_CHARSET %d\n" % SRE_INFO_CHARSET)
+
+    f.close()
+    print "done"

Added: vendor/Python/current/Lib/sre_parse.py
===================================================================
--- vendor/Python/current/Lib/sre_parse.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/sre_parse.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,796 @@
+#
+# Secret Labs' Regular Expression Engine
+#
+# convert re-style regular expression to sre pattern
+#
+# Copyright (c) 1998-2001 by Secret Labs AB.  All rights reserved.
+#
+# See the sre.py file for information on usage and redistribution.
+#
+
+"""Internal support module for sre"""
+
+# XXX: show string offset and offending character for all errors
+
+import sys
+
+from sre_constants import *
+
+def set(seq):
+    s = {}
+    for elem in seq:
+        s[elem] = 1
+    return s
+
+SPECIAL_CHARS = ".\\[{()*+?^$|"
+REPEAT_CHARS = "*+?{"
+
+DIGITS = set("0123456789")
+
+OCTDIGITS = set("01234567")
+HEXDIGITS = set("0123456789abcdefABCDEF")
+
+WHITESPACE = set(" \t\n\r\v\f")
+
+ESCAPES = {
+    r"\a": (LITERAL, ord("\a")),
+    r"\b": (LITERAL, ord("\b")),
+    r"\f": (LITERAL, ord("\f")),
+    r"\n": (LITERAL, ord("\n")),
+    r"\r": (LITERAL, ord("\r")),
+    r"\t": (LITERAL, ord("\t")),
+    r"\v": (LITERAL, ord("\v")),
+    r"\\": (LITERAL, ord("\\"))
+}
+
+CATEGORIES = {
+    r"\A": (AT, AT_BEGINNING_STRING), # start of string
+    r"\b": (AT, AT_BOUNDARY),
+    r"\B": (AT, AT_NON_BOUNDARY),
+    r"\d": (IN, [(CATEGORY, CATEGORY_DIGIT)]),
+    r"\D": (IN, [(CATEGORY, CATEGORY_NOT_DIGIT)]),
+    r"\s": (IN, [(CATEGORY, CATEGORY_SPACE)]),
+    r"\S": (IN, [(CATEGORY, CATEGORY_NOT_SPACE)]),
+    r"\w": (IN, [(CATEGORY, CATEGORY_WORD)]),
+    r"\W": (IN, [(CATEGORY, CATEGORY_NOT_WORD)]),
+    r"\Z": (AT, AT_END_STRING), # end of string
+}
+
+FLAGS = {
+    # standard flags
+    "i": SRE_FLAG_IGNORECASE,
+    "L": SRE_FLAG_LOCALE,
+    "m": SRE_FLAG_MULTILINE,
+    "s": SRE_FLAG_DOTALL,
+    "x": SRE_FLAG_VERBOSE,
+    # extensions
+    "t": SRE_FLAG_TEMPLATE,
+    "u": SRE_FLAG_UNICODE,
+}
+
+class Pattern:
+    # master pattern object.  keeps track of global attributes
+    def __init__(self):
+        self.flags = 0
+        self.open = []
+        self.groups = 1
+        self.groupdict = {}
+    def opengroup(self, name=None):
+        gid = self.groups
+        self.groups = gid + 1
+        if name is not None:
+            ogid = self.groupdict.get(name, None)
+            if ogid is not None:
+                raise error, ("redefinition of group name %s as group %d; "
+                              "was group %d" % (repr(name), gid,  ogid))
+            self.groupdict[name] = gid
+        self.open.append(gid)
+        return gid
+    def closegroup(self, gid):
+        self.open.remove(gid)
+    def checkgroup(self, gid):
+        return gid < self.groups and gid not in self.open
+
+class SubPattern:
+    # a subpattern, in intermediate form
+    def __init__(self, pattern, data=None):
+        self.pattern = pattern
+        if data is None:
+            data = []
+        self.data = data
+        self.width = None
+    def dump(self, level=0):
+        nl = 1
+        seqtypes = type(()), type([])
+        for op, av in self.data:
+            print level*"  " + op,; nl = 0
+            if op == "in":
+                # member sublanguage
+                print; nl = 1
+                for op, a in av:
+                    print (level+1)*"  " + op, a
+            elif op == "branch":
+                print; nl = 1
+                i = 0
+                for a in av[1]:
+                    if i > 0:
+                        print level*"  " + "or"
+                    a.dump(level+1); nl = 1
+                    i = i + 1
+            elif type(av) in seqtypes:
+                for a in av:
+                    if isinstance(a, SubPattern):
+                        if not nl: print
+                        a.dump(level+1); nl = 1
+                    else:
+                        print a, ; nl = 0
+            else:
+                print av, ; nl = 0
+            if not nl: print
+    def __repr__(self):
+        return repr(self.data)
+    def __len__(self):
+        return len(self.data)
+    def __delitem__(self, index):
+        del self.data[index]
+    def __getitem__(self, index):
+        return self.data[index]
+    def __setitem__(self, index, code):
+        self.data[index] = code
+    def __getslice__(self, start, stop):
+        return SubPattern(self.pattern, self.data[start:stop])
+    def insert(self, index, code):
+        self.data.insert(index, code)
+    def append(self, code):
+        self.data.append(code)
+    def getwidth(self):
+        # determine the width (min, max) for this subpattern
+        if self.width:
+            return self.width
+        lo = hi = 0L
+        UNITCODES = (ANY, RANGE, IN, LITERAL, NOT_LITERAL, CATEGORY)
+        REPEATCODES = (MIN_REPEAT, MAX_REPEAT)
+        for op, av in self.data:
+            if op is BRANCH:
+                i = sys.maxint
+                j = 0
+                for av in av[1]:
+                    l, h = av.getwidth()
+                    i = min(i, l)
+                    j = max(j, h)
+                lo = lo + i
+                hi = hi + j
+            elif op is CALL:
+                i, j = av.getwidth()
+                lo = lo + i
+                hi = hi + j
+            elif op is SUBPATTERN:
+                i, j = av[1].getwidth()
+                lo = lo + i
+                hi = hi + j
+            elif op in REPEATCODES:
+                i, j = av[2].getwidth()
+                lo = lo + long(i) * av[0]
+                hi = hi + long(j) * av[1]
+            elif op in UNITCODES:
+                lo = lo + 1
+                hi = hi + 1
+            elif op == SUCCESS:
+                break
+        self.width = int(min(lo, sys.maxint)), int(min(hi, sys.maxint))
+        return self.width
+
+class Tokenizer:
+    def __init__(self, string):
+        self.string = string
+        self.index = 0
+        self.__next()
+    def __next(self):
+        if self.index >= len(self.string):
+            self.next = None
+            return
+        char = self.string[self.index]
+        if char[0] == "\\":
+            try:
+                c = self.string[self.index + 1]
+            except IndexError:
+                raise error, "bogus escape (end of line)"
+            char = char + c
+        self.index = self.index + len(char)
+        self.next = char
+    def match(self, char, skip=1):
+        if char == self.next:
+            if skip:
+                self.__next()
+            return 1
+        return 0
+    def get(self):
+        this = self.next
+        self.__next()
+        return this
+    def tell(self):
+        return self.index, self.next
+    def seek(self, index):
+        self.index, self.next = index
+
+def isident(char):
+    return "a" <= char <= "z" or "A" <= char <= "Z" or char == "_"
+
+def isdigit(char):
+    return "0" <= char <= "9"
+
+def isname(name):
+    # check that group name is a valid string
+    if not isident(name[0]):
+        return False
+    for char in name[1:]:
+        if not isident(char) and not isdigit(char):
+            return False
+    return True
+
+def _class_escape(source, escape):
+    # handle escape code inside character class
+    code = ESCAPES.get(escape)
+    if code:
+        return code
+    code = CATEGORIES.get(escape)
+    if code:
+        return code
+    try:
+        c = escape[1:2]
+        if c == "x":
+            # hexadecimal escape (exactly two digits)
+            while source.next in HEXDIGITS and len(escape) < 4:
+                escape = escape + source.get()
+            escape = escape[2:]
+            if len(escape) != 2:
+                raise error, "bogus escape: %s" % repr("\\" + escape)
+            return LITERAL, int(escape, 16) & 0xff
+        elif c in OCTDIGITS:
+            # octal escape (up to three digits)
+            while source.next in OCTDIGITS and len(escape) < 4:
+                escape = escape + source.get()
+            escape = escape[1:]
+            return LITERAL, int(escape, 8) & 0xff
+        elif c in DIGITS:
+            raise error, "bogus escape: %s" % repr(escape)
+        if len(escape) == 2:
+            return LITERAL, ord(escape[1])
+    except ValueError:
+        pass
+    raise error, "bogus escape: %s" % repr(escape)
+
+def _escape(source, escape, state):
+    # handle escape code in expression
+    code = CATEGORIES.get(escape)
+    if code:
+        return code
+    code = ESCAPES.get(escape)
+    if code:
+        return code
+    try:
+        c = escape[1:2]
+        if c == "x":
+            # hexadecimal escape
+            while source.next in HEXDIGITS and len(escape) < 4:
+                escape = escape + source.get()
+            if len(escape) != 4:
+                raise ValueError
+            return LITERAL, int(escape[2:], 16) & 0xff
+        elif c == "0":
+            # octal escape
+            while source.next in OCTDIGITS and len(escape) < 4:
+                escape = escape + source.get()
+            return LITERAL, int(escape[1:], 8) & 0xff
+        elif c in DIGITS:
+            # octal escape *or* decimal group reference (sigh)
+            if source.next in DIGITS:
+                escape = escape + source.get()
+                if (escape[1] in OCTDIGITS and escape[2] in OCTDIGITS and
+                    source.next in OCTDIGITS):
+                    # got three octal digits; this is an octal escape
+                    escape = escape + source.get()
+                    return LITERAL, int(escape[1:], 8) & 0xff
+            # not an octal escape, so this is a group reference
+            group = int(escape[1:])
+            if group < state.groups:
+                if not state.checkgroup(group):
+                    raise error, "cannot refer to open group"
+                return GROUPREF, group
+            raise ValueError
+        if len(escape) == 2:
+            return LITERAL, ord(escape[1])
+    except ValueError:
+        pass
+    raise error, "bogus escape: %s" % repr(escape)
+
+def _parse_sub(source, state, nested=1):
+    # parse an alternation: a|b|c
+
+    items = []
+    itemsappend = items.append
+    sourcematch = source.match
+    while 1:
+        itemsappend(_parse(source, state))
+        if sourcematch("|"):
+            continue
+        if not nested:
+            break
+        if not source.next or sourcematch(")", 0):
+            break
+        else:
+            raise error, "pattern not properly closed"
+
+    if len(items) == 1:
+        return items[0]
+
+    subpattern = SubPattern(state)
+    subpatternappend = subpattern.append
+
+    # check if all items share a common prefix
+    while 1:
+        prefix = None
+        for item in items:
+            if not item:
+                break
+            if prefix is None:
+                prefix = item[0]
+            elif item[0] != prefix:
+                break
+        else:
+            # all subitems start with a common "prefix".
+            # move it out of the branch
+            for item in items:
+                del item[0]
+            subpatternappend(prefix)
+            continue # check next one
+        break
+
+    # check if the branch can be replaced by a character set
+    for item in items:
+        if len(item) != 1 or item[0][0] != LITERAL:
+            break
+    else:
+        # we can store this as a character set instead of a
+        # branch (the compiler may optimize this even more)
+        set = []
+        setappend = set.append
+        for item in items:
+            setappend(item[0])
+        subpatternappend((IN, set))
+        return subpattern
+
+    subpattern.append((BRANCH, (None, items)))
+    return subpattern
+
+def _parse_sub_cond(source, state, condgroup):
+    item_yes = _parse(source, state)
+    if source.match("|"):
+        item_no = _parse(source, state)
+        if source.match("|"):
+            raise error, "conditional backref with more than two branches"
+    else:
+        item_no = None
+    if source.next and not source.match(")", 0):
+        raise error, "pattern not properly closed"
+    subpattern = SubPattern(state)
+    subpattern.append((GROUPREF_EXISTS, (condgroup, item_yes, item_no)))
+    return subpattern
+
+_PATTERNENDERS = set("|)")
+_ASSERTCHARS = set("=!<")
+_LOOKBEHINDASSERTCHARS = set("=!")
+_REPEATCODES = set([MIN_REPEAT, MAX_REPEAT])
+
+def _parse(source, state):
+    # parse a simple pattern
+    subpattern = SubPattern(state)
+
+    # precompute constants into local variables
+    subpatternappend = subpattern.append
+    sourceget = source.get
+    sourcematch = source.match
+    _len = len
+    PATTERNENDERS = _PATTERNENDERS
+    ASSERTCHARS = _ASSERTCHARS
+    LOOKBEHINDASSERTCHARS = _LOOKBEHINDASSERTCHARS
+    REPEATCODES = _REPEATCODES
+
+    while 1:
+
+        if source.next in PATTERNENDERS:
+            break # end of subpattern
+        this = sourceget()
+        if this is None:
+            break # end of pattern
+
+        if state.flags & SRE_FLAG_VERBOSE:
+            # skip whitespace and comments
+            if this in WHITESPACE:
+                continue
+            if this == "#":
+                while 1:
+                    this = sourceget()
+                    if this in (None, "\n"):
+                        break
+                continue
+
+        if this and this[0] not in SPECIAL_CHARS:
+            subpatternappend((LITERAL, ord(this)))
+
+        elif this == "[":
+            # character set
+            set = []
+            setappend = set.append
+##          if sourcematch(":"):
+##              pass # handle character classes
+            if sourcematch("^"):
+                setappend((NEGATE, None))
+            # check remaining characters
+            start = set[:]
+            while 1:
+                this = sourceget()
+                if this == "]" and set != start:
+                    break
+                elif this and this[0] == "\\":
+                    code1 = _class_escape(source, this)
+                elif this:
+                    code1 = LITERAL, ord(this)
+                else:
+                    raise error, "unexpected end of regular expression"
+                if sourcematch("-"):
+                    # potential range
+                    this = sourceget()
+                    if this == "]":
+                        if code1[0] is IN:
+                            code1 = code1[1][0]
+                        setappend(code1)
+                        setappend((LITERAL, ord("-")))
+                        break
+                    elif this:
+                        if this[0] == "\\":
+                            code2 = _class_escape(source, this)
+                        else:
+                            code2 = LITERAL, ord(this)
+                        if code1[0] != LITERAL or code2[0] != LITERAL:
+                            raise error, "bad character range"
+                        lo = code1[1]
+                        hi = code2[1]
+                        if hi < lo:
+                            raise error, "bad character range"
+                        setappend((RANGE, (lo, hi)))
+                    else:
+                        raise error, "unexpected end of regular expression"
+                else:
+                    if code1[0] is IN:
+                        code1 = code1[1][0]
+                    setappend(code1)
+
+            # XXX: <fl> should move set optimization to compiler!
+            if _len(set)==1 and set[0][0] is LITERAL:
+                subpatternappend(set[0]) # optimization
+            elif _len(set)==2 and set[0][0] is NEGATE and set[1][0] is LITERAL:
+                subpatternappend((NOT_LITERAL, set[1][1])) # optimization
+            else:
+                # XXX: <fl> should add charmap optimization here
+                subpatternappend((IN, set))
+
+        elif this and this[0] in REPEAT_CHARS:
+            # repeat previous item
+            if this == "?":
+                min, max = 0, 1
+            elif this == "*":
+                min, max = 0, MAXREPEAT
+
+            elif this == "+":
+                min, max = 1, MAXREPEAT
+            elif this == "{":
+                if source.next == "}":
+                    subpatternappend((LITERAL, ord(this)))
+                    continue
+                here = source.tell()
+                min, max = 0, MAXREPEAT
+                lo = hi = ""
+                while source.next in DIGITS:
+                    lo = lo + source.get()
+                if sourcematch(","):
+                    while source.next in DIGITS:
+                        hi = hi + sourceget()
+                else:
+                    hi = lo
+                if not sourcematch("}"):
+                    subpatternappend((LITERAL, ord(this)))
+                    source.seek(here)
+                    continue
+                if lo:
+                    min = int(lo)
+                if hi:
+                    max = int(hi)
+                if max < min:
+                    raise error, "bad repeat interval"
+            else:
+                raise error, "not supported"
+            # figure out which item to repeat
+            if subpattern:
+                item = subpattern[-1:]
+            else:
+                item = None
+            if not item or (_len(item) == 1 and item[0][0] == AT):
+                raise error, "nothing to repeat"
+            if item[0][0] in REPEATCODES:
+                raise error, "multiple repeat"
+            if sourcematch("?"):
+                subpattern[-1] = (MIN_REPEAT, (min, max, item))
+            else:
+                subpattern[-1] = (MAX_REPEAT, (min, max, item))
+
+        elif this == ".":
+            subpatternappend((ANY, None))
+
+        elif this == "(":
+            group = 1
+            name = None
+            condgroup = None
+            if sourcematch("?"):
+                group = 0
+                # options
+                if sourcematch("P"):
+                    # python extensions
+                    if sourcematch("<"):
+                        # named group: skip forward to end of name
+                        name = ""
+                        while 1:
+                            char = sourceget()
+                            if char is None:
+                                raise error, "unterminated name"
+                            if char == ">":
+                                break
+                            name = name + char
+                        group = 1
+                        if not isname(name):
+                            raise error, "bad character in group name"
+                    elif sourcematch("="):
+                        # named backreference
+                        name = ""
+                        while 1:
+                            char = sourceget()
+                            if char is None:
+                                raise error, "unterminated name"
+                            if char == ")":
+                                break
+                            name = name + char
+                        if not isname(name):
+                            raise error, "bad character in group name"
+                        gid = state.groupdict.get(name)
+                        if gid is None:
+                            raise error, "unknown group name"
+                        subpatternappend((GROUPREF, gid))
+                        continue
+                    else:
+                        char = sourceget()
+                        if char is None:
+                            raise error, "unexpected end of pattern"
+                        raise error, "unknown specifier: ?P%s" % char
+                elif sourcematch(":"):
+                    # non-capturing group
+                    group = 2
+                elif sourcematch("#"):
+                    # comment
+                    while 1:
+                        if source.next is None or source.next == ")":
+                            break
+                        sourceget()
+                    if not sourcematch(")"):
+                        raise error, "unbalanced parenthesis"
+                    continue
+                elif source.next in ASSERTCHARS:
+                    # lookahead assertions
+                    char = sourceget()
+                    dir = 1
+                    if char == "<":
+                        if source.next not in LOOKBEHINDASSERTCHARS:
+                            raise error, "syntax error"
+                        dir = -1 # lookbehind
+                        char = sourceget()
+                    p = _parse_sub(source, state)
+                    if not sourcematch(")"):
+                        raise error, "unbalanced parenthesis"
+                    if char == "=":
+                        subpatternappend((ASSERT, (dir, p)))
+                    else:
+                        subpatternappend((ASSERT_NOT, (dir, p)))
+                    continue
+                elif sourcematch("("):
+                    # conditional backreference group
+                    condname = ""
+                    while 1:
+                        char = sourceget()
+                        if char is None:
+                            raise error, "unterminated name"
+                        if char == ")":
+                            break
+                        condname = condname + char
+                    group = 2
+                    if isname(condname):
+                        condgroup = state.groupdict.get(condname)
+                        if condgroup is None:
+                            raise error, "unknown group name"
+                    else:
+                        try:
+                            condgroup = int(condname)
+                        except ValueError:
+                            raise error, "bad character in group name"
+                else:
+                    # flags
+                    if not source.next in FLAGS:
+                        raise error, "unexpected end of pattern"
+                    while source.next in FLAGS:
+                        state.flags = state.flags | FLAGS[sourceget()]
+            if group:
+                # parse group contents
+                if group == 2:
+                    # anonymous group
+                    group = None
+                else:
+                    group = state.opengroup(name)
+                if condgroup:
+                    p = _parse_sub_cond(source, state, condgroup)
+                else:
+                    p = _parse_sub(source, state)
+                if not sourcematch(")"):
+                    raise error, "unbalanced parenthesis"
+                if group is not None:
+                    state.closegroup(group)
+                subpatternappend((SUBPATTERN, (group, p)))
+            else:
+                while 1:
+                    char = sourceget()
+                    if char is None:
+                        raise error, "unexpected end of pattern"
+                    if char == ")":
+                        break
+                    raise error, "unknown extension"
+
+        elif this == "^":
+            subpatternappend((AT, AT_BEGINNING))
+
+        elif this == "$":
+            subpattern.append((AT, AT_END))
+
+        elif this and this[0] == "\\":
+            code = _escape(source, this, state)
+            subpatternappend(code)
+
+        else:
+            raise error, "parser error"
+
+    return subpattern
+
+def parse(str, flags=0, pattern=None):
+    # parse 're' pattern into list of (opcode, argument) tuples
+
+    source = Tokenizer(str)
+
+    if pattern is None:
+        pattern = Pattern()
+    pattern.flags = flags
+    pattern.str = str
+
+    p = _parse_sub(source, pattern, 0)
+
+    tail = source.get()
+    if tail == ")":
+        raise error, "unbalanced parenthesis"
+    elif tail:
+        raise error, "bogus characters at end of regular expression"
+
+    if flags & SRE_FLAG_DEBUG:
+        p.dump()
+
+    if not (flags & SRE_FLAG_VERBOSE) and p.pattern.flags & SRE_FLAG_VERBOSE:
+        # the VERBOSE flag was switched on inside the pattern.  to be
+        # on the safe side, we'll parse the whole thing again...
+        return parse(str, p.pattern.flags)
+
+    return p
+
+def parse_template(source, pattern):
+    # parse 're' replacement string into list of literals and
+    # group references
+    s = Tokenizer(source)
+    sget = s.get
+    p = []
+    a = p.append
+    def literal(literal, p=p, pappend=a):
+        if p and p[-1][0] is LITERAL:
+            p[-1] = LITERAL, p[-1][1] + literal
+        else:
+            pappend((LITERAL, literal))
+    sep = source[:0]
+    if type(sep) is type(""):
+        makechar = chr
+    else:
+        makechar = unichr
+    while 1:
+        this = sget()
+        if this is None:
+            break # end of replacement string
+        if this and this[0] == "\\":
+            # group
+            c = this[1:2]
+            if c == "g":
+                name = ""
+                if s.match("<"):
+                    while 1:
+                        char = sget()
+                        if char is None:
+                            raise error, "unterminated group name"
+                        if char == ">":
+                            break
+                        name = name + char
+                if not name:
+                    raise error, "bad group name"
+                try:
+                    index = int(name)
+                    if index < 0:
+                        raise error, "negative group number"
+                except ValueError:
+                    if not isname(name):
+                        raise error, "bad character in group name"
+                    try:
+                        index = pattern.groupindex[name]
+                    except KeyError:
+                        raise IndexError, "unknown group name"
+                a((MARK, index))
+            elif c == "0":
+                if s.next in OCTDIGITS:
+                    this = this + sget()
+                    if s.next in OCTDIGITS:
+                        this = this + sget()
+                literal(makechar(int(this[1:], 8) & 0xff))
+            elif c in DIGITS:
+                isoctal = False
+                if s.next in DIGITS:
+                    this = this + sget()
+                    if (c in OCTDIGITS and this[2] in OCTDIGITS and
+                        s.next in OCTDIGITS):
+                        this = this + sget()
+                        isoctal = True
+                        literal(makechar(int(this[1:], 8) & 0xff))
+                if not isoctal:
+                    a((MARK, int(this[1:])))
+            else:
+                try:
+                    this = makechar(ESCAPES[this][1])
+                except KeyError:
+                    pass
+                literal(this)
+        else:
+            literal(this)
+    # convert template to groups and literals lists
+    i = 0
+    groups = []
+    groupsappend = groups.append
+    literals = [None] * len(p)
+    for c, s in p:
+        if c is MARK:
+            groupsappend((i, s))
+            # literal[i] is already None
+        else:
+            literals[i] = s
+        i = i + 1
+    return groups, literals
+
+def expand_template(template, match):
+    g = match.group
+    sep = match.string[:0]
+    groups, literals = template
+    literals = literals[:]
+    try:
+        for index, group in groups:
+            literals[index] = s = g(group)
+            if s is None:
+                raise error, "unmatched group"
+    except IndexError:
+        raise error, "invalid group reference"
+    return sep.join(literals)

Added: vendor/Python/current/Lib/stat.py
===================================================================
--- vendor/Python/current/Lib/stat.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/stat.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,86 @@
+"""Constants/functions for interpreting results of os.stat() and os.lstat().
+
+Suggested usage: from stat import *
+"""
+
+# XXX Strictly spoken, this module may have to be adapted for each POSIX
+# implementation; in practice, however, the numeric constants used by
+# stat() are almost universal (even for stat() emulations on non-UNIX
+# systems like MS-DOS).
+
+# Indices for stat struct members in tuple returned by os.stat()
+
+ST_MODE  = 0
+ST_INO   = 1
+ST_DEV   = 2
+ST_NLINK = 3
+ST_UID   = 4
+ST_GID   = 5
+ST_SIZE  = 6
+ST_ATIME = 7
+ST_MTIME = 8
+ST_CTIME = 9
+
+# Extract bits from the mode
+
+def S_IMODE(mode):
+    return mode & 07777
+
+def S_IFMT(mode):
+    return mode & 0170000
+
+# Constants used as S_IFMT() for various file types
+# (not all are implemented on all systems)
+
+S_IFDIR  = 0040000
+S_IFCHR  = 0020000
+S_IFBLK  = 0060000
+S_IFREG  = 0100000
+S_IFIFO  = 0010000
+S_IFLNK  = 0120000
+S_IFSOCK = 0140000
+
+# Functions to test for each file type
+
+def S_ISDIR(mode):
+    return S_IFMT(mode) == S_IFDIR
+
+def S_ISCHR(mode):
+    return S_IFMT(mode) == S_IFCHR
+
+def S_ISBLK(mode):
+    return S_IFMT(mode) == S_IFBLK
+
+def S_ISREG(mode):
+    return S_IFMT(mode) == S_IFREG
+
+def S_ISFIFO(mode):
+    return S_IFMT(mode) == S_IFIFO
+
+def S_ISLNK(mode):
+    return S_IFMT(mode) == S_IFLNK
+
+def S_ISSOCK(mode):
+    return S_IFMT(mode) == S_IFSOCK
+
+# Names for permission bits
+
+S_ISUID = 04000
+S_ISGID = 02000
+S_ENFMT = S_ISGID
+S_ISVTX = 01000
+S_IREAD = 00400
+S_IWRITE = 00200
+S_IEXEC = 00100
+S_IRWXU = 00700
+S_IRUSR = 00400
+S_IWUSR = 00200
+S_IXUSR = 00100
+S_IRWXG = 00070
+S_IRGRP = 00040
+S_IWGRP = 00020
+S_IXGRP = 00010
+S_IRWXO = 00007
+S_IROTH = 00004
+S_IWOTH = 00002
+S_IXOTH = 00001

Added: vendor/Python/current/Lib/statvfs.py
===================================================================
--- vendor/Python/current/Lib/statvfs.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/statvfs.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,15 @@
+"""Constants for interpreting the results of os.statvfs() and os.fstatvfs()."""
+
+# Indices for statvfs struct members in the tuple returned by
+# os.statvfs() and os.fstatvfs().
+
+F_BSIZE   = 0           # Preferred file system block size
+F_FRSIZE  = 1           # Fundamental file system block size
+F_BLOCKS  = 2           # Total number of file system blocks (FRSIZE)
+F_BFREE   = 3           # Total number of free blocks
+F_BAVAIL  = 4           # Free blocks available to non-superuser
+F_FILES   = 5           # Total number of file nodes
+F_FFREE   = 6           # Total number of free file nodes
+F_FAVAIL  = 7           # Free nodes available to non-superuser
+F_FLAG    = 8           # Flags (see your local statvfs man page)
+F_NAMEMAX = 9           # Maximum file name length

Added: vendor/Python/current/Lib/string.py
===================================================================
--- vendor/Python/current/Lib/string.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/string.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,529 @@
+"""A collection of string operations (most are no longer used).
+
+Warning: most of the code you see here isn't normally used nowadays.
+Beginning with Python 1.6, many of these functions are implemented as
+methods on the standard string object. They used to be implemented by
+a built-in module called strop, but strop is now obsolete itself.
+
+Public module variables:
+
+whitespace -- a string containing all characters considered whitespace
+lowercase -- a string containing all characters considered lowercase letters
+uppercase -- a string containing all characters considered uppercase letters
+letters -- a string containing all characters considered letters
+digits -- a string containing all characters considered decimal digits
+hexdigits -- a string containing all characters considered hexadecimal digits
+octdigits -- a string containing all characters considered octal digits
+punctuation -- a string containing all characters considered punctuation
+printable -- a string containing all characters considered printable
+
+"""
+
+# Some strings for ctype-style character classification
+whitespace = ' \t\n\r\v\f'
+lowercase = 'abcdefghijklmnopqrstuvwxyz'
+uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+letters = lowercase + uppercase
+ascii_lowercase = lowercase
+ascii_uppercase = uppercase
+ascii_letters = ascii_lowercase + ascii_uppercase
+digits = '0123456789'
+hexdigits = digits + 'abcdef' + 'ABCDEF'
+octdigits = '01234567'
+punctuation = """!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~"""
+printable = digits + letters + punctuation + whitespace
+
+# Case conversion helpers
+# Use str to convert Unicode literal in case of -U
+l = map(chr, xrange(256))
+_idmap = str('').join(l)
+del l
+
+# Functions which aren't available as string methods.
+
+# Capitalize the words in a string, e.g. " aBc  dEf " -> "Abc Def".
+def capwords(s, sep=None):
+    """capwords(s, [sep]) -> string
+
+    Split the argument into words using split, capitalize each
+    word using capitalize, and join the capitalized words using
+    join. Note that this replaces runs of whitespace characters by
+    a single space.
+
+    """
+    return (sep or ' ').join([x.capitalize() for x in s.split(sep)])
+
+
+# Construct a translation string
+_idmapL = None
+def maketrans(fromstr, tostr):
+    """maketrans(frm, to) -> string
+
+    Return a translation table (a string of 256 bytes long)
+    suitable for use in string.translate.  The strings frm and to
+    must be of the same length.
+
+    """
+    if len(fromstr) != len(tostr):
+        raise ValueError, "maketrans arguments must have same length"
+    global _idmapL
+    if not _idmapL:
+        _idmapL = map(None, _idmap)
+    L = _idmapL[:]
+    fromstr = map(ord, fromstr)
+    for i in range(len(fromstr)):
+        L[fromstr[i]] = tostr[i]
+    return ''.join(L)
+
+
+
+####################################################################
+import re as _re
+
+class _multimap:
+    """Helper class for combining multiple mappings.
+
+    Used by .{safe_,}substitute() to combine the mapping and keyword
+    arguments.
+    """
+    def __init__(self, primary, secondary):
+        self._primary = primary
+        self._secondary = secondary
+
+    def __getitem__(self, key):
+        try:
+            return self._primary[key]
+        except KeyError:
+            return self._secondary[key]
+
+
+class _TemplateMetaclass(type):
+    pattern = r"""
+    %(delim)s(?:
+      (?P<escaped>%(delim)s) |   # Escape sequence of two delimiters
+      (?P<named>%(id)s)      |   # delimiter and a Python identifier
+      {(?P<braced>%(id)s)}   |   # delimiter and a braced identifier
+      (?P<invalid>)              # Other ill-formed delimiter exprs
+    )
+    """
+
+    def __init__(cls, name, bases, dct):
+        super(_TemplateMetaclass, cls).__init__(name, bases, dct)
+        if 'pattern' in dct:
+            pattern = cls.pattern
+        else:
+            pattern = _TemplateMetaclass.pattern % {
+                'delim' : _re.escape(cls.delimiter),
+                'id'    : cls.idpattern,
+                }
+        cls.pattern = _re.compile(pattern, _re.IGNORECASE | _re.VERBOSE)
+
+
+class Template:
+    """A string class for supporting $-substitutions."""
+    __metaclass__ = _TemplateMetaclass
+
+    delimiter = '$'
+    idpattern = r'[_a-z][_a-z0-9]*'
+
+    def __init__(self, template):
+        self.template = template
+
+    # Search for $$, $identifier, ${identifier}, and any bare $'s
+
+    def _invalid(self, mo):
+        i = mo.start('invalid')
+        lines = self.template[:i].splitlines(True)
+        if not lines:
+            colno = 1
+            lineno = 1
+        else:
+            colno = i - len(''.join(lines[:-1]))
+            lineno = len(lines)
+        raise ValueError('Invalid placeholder in string: line %d, col %d' %
+                         (lineno, colno))
+
+    def substitute(self, *args, **kws):
+        if len(args) > 1:
+            raise TypeError('Too many positional arguments')
+        if not args:
+            mapping = kws
+        elif kws:
+            mapping = _multimap(kws, args[0])
+        else:
+            mapping = args[0]
+        # Helper function for .sub()
+        def convert(mo):
+            # Check the most common path first.
+            named = mo.group('named') or mo.group('braced')
+            if named is not None:
+                val = mapping[named]
+                # We use this idiom instead of str() because the latter will
+                # fail if val is a Unicode containing non-ASCII characters.
+                return '%s' % (val,)
+            if mo.group('escaped') is not None:
+                return self.delimiter
+            if mo.group('invalid') is not None:
+                self._invalid(mo)
+            raise ValueError('Unrecognized named group in pattern',
+                             self.pattern)
+        return self.pattern.sub(convert, self.template)
+
+    def safe_substitute(self, *args, **kws):
+        if len(args) > 1:
+            raise TypeError('Too many positional arguments')
+        if not args:
+            mapping = kws
+        elif kws:
+            mapping = _multimap(kws, args[0])
+        else:
+            mapping = args[0]
+        # Helper function for .sub()
+        def convert(mo):
+            named = mo.group('named')
+            if named is not None:
+                try:
+                    # We use this idiom instead of str() because the latter
+                    # will fail if val is a Unicode containing non-ASCII
+                    return '%s' % (mapping[named],)
+                except KeyError:
+                    return self.delimiter + named
+            braced = mo.group('braced')
+            if braced is not None:
+                try:
+                    return '%s' % (mapping[braced],)
+                except KeyError:
+                    return self.delimiter + '{' + braced + '}'
+            if mo.group('escaped') is not None:
+                return self.delimiter
+            if mo.group('invalid') is not None:
+                return self.delimiter
+            raise ValueError('Unrecognized named group in pattern',
+                             self.pattern)
+        return self.pattern.sub(convert, self.template)
+
+
+
+####################################################################
+# NOTE: Everything below here is deprecated.  Use string methods instead.
+# This stuff will go away in Python 3.0.
+
+# Backward compatible names for exceptions
+index_error = ValueError
+atoi_error = ValueError
+atof_error = ValueError
+atol_error = ValueError
+
+# convert UPPER CASE letters to lower case
+def lower(s):
+    """lower(s) -> string
+
+    Return a copy of the string s converted to lowercase.
+
+    """
+    return s.lower()
+
+# Convert lower case letters to UPPER CASE
+def upper(s):
+    """upper(s) -> string
+
+    Return a copy of the string s converted to uppercase.
+
+    """
+    return s.upper()
+
+# Swap lower case letters and UPPER CASE
+def swapcase(s):
+    """swapcase(s) -> string
+
+    Return a copy of the string s with upper case characters
+    converted to lowercase and vice versa.
+
+    """
+    return s.swapcase()
+
+# Strip leading and trailing tabs and spaces
+def strip(s, chars=None):
+    """strip(s [,chars]) -> string
+
+    Return a copy of the string s with leading and trailing
+    whitespace removed.
+    If chars is given and not None, remove characters in chars instead.
+    If chars is unicode, S will be converted to unicode before stripping.
+
+    """
+    return s.strip(chars)
+
+# Strip leading tabs and spaces
+def lstrip(s, chars=None):
+    """lstrip(s [,chars]) -> string
+
+    Return a copy of the string s with leading whitespace removed.
+    If chars is given and not None, remove characters in chars instead.
+
+    """
+    return s.lstrip(chars)
+
+# Strip trailing tabs and spaces
+def rstrip(s, chars=None):
+    """rstrip(s [,chars]) -> string
+
+    Return a copy of the string s with trailing whitespace removed.
+    If chars is given and not None, remove characters in chars instead.
+
+    """
+    return s.rstrip(chars)
+
+
+# Split a string into a list of space/tab-separated words
+def split(s, sep=None, maxsplit=-1):
+    """split(s [,sep [,maxsplit]]) -> list of strings
+
+    Return a list of the words in the string s, using sep as the
+    delimiter string.  If maxsplit is given, splits at no more than
+    maxsplit places (resulting in at most maxsplit+1 words).  If sep
+    is not specified or is None, any whitespace string is a separator.
+
+    (split and splitfields are synonymous)
+
+    """
+    return s.split(sep, maxsplit)
+splitfields = split
+
+# Split a string into a list of space/tab-separated words
+def rsplit(s, sep=None, maxsplit=-1):
+    """rsplit(s [,sep [,maxsplit]]) -> list of strings
+
+    Return a list of the words in the string s, using sep as the
+    delimiter string, starting at the end of the string and working
+    to the front.  If maxsplit is given, at most maxsplit splits are
+    done. If sep is not specified or is None, any whitespace string
+    is a separator.
+    """
+    return s.rsplit(sep, maxsplit)
+
+# Join fields with optional separator
+def join(words, sep = ' '):
+    """join(list [,sep]) -> string
+
+    Return a string composed of the words in list, with
+    intervening occurrences of sep.  The default separator is a
+    single space.
+
+    (joinfields and join are synonymous)
+
+    """
+    return sep.join(words)
+joinfields = join
+
+# Find substring, raise exception if not found
+def index(s, *args):
+    """index(s, sub [,start [,end]]) -> int
+
+    Like find but raises ValueError when the substring is not found.
+
+    """
+    return s.index(*args)
+
+# Find last substring, raise exception if not found
+def rindex(s, *args):
+    """rindex(s, sub [,start [,end]]) -> int
+
+    Like rfind but raises ValueError when the substring is not found.
+
+    """
+    return s.rindex(*args)
+
+# Count non-overlapping occurrences of substring
+def count(s, *args):
+    """count(s, sub[, start[,end]]) -> int
+
+    Return the number of occurrences of substring sub in string
+    s[start:end].  Optional arguments start and end are
+    interpreted as in slice notation.
+
+    """
+    return s.count(*args)
+
+# Find substring, return -1 if not found
+def find(s, *args):
+    """find(s, sub [,start [,end]]) -> in
+
+    Return the lowest index in s where substring sub is found,
+    such that sub is contained within s[start,end].  Optional
+    arguments start and end are interpreted as in slice notation.
+
+    Return -1 on failure.
+
+    """
+    return s.find(*args)
+
+# Find last substring, return -1 if not found
+def rfind(s, *args):
+    """rfind(s, sub [,start [,end]]) -> int
+
+    Return the highest index in s where substring sub is found,
+    such that sub is contained within s[start,end].  Optional
+    arguments start and end are interpreted as in slice notation.
+
+    Return -1 on failure.
+
+    """
+    return s.rfind(*args)
+
+# for a bit of speed
+_float = float
+_int = int
+_long = long
+
+# Convert string to float
+def atof(s):
+    """atof(s) -> float
+
+    Return the floating point number represented by the string s.
+
+    """
+    return _float(s)
+
+
+# Convert string to integer
+def atoi(s , base=10):
+    """atoi(s [,base]) -> int
+
+    Return the integer represented by the string s in the given
+    base, which defaults to 10.  The string s must consist of one
+    or more digits, possibly preceded by a sign.  If base is 0, it
+    is chosen from the leading characters of s, 0 for octal, 0x or
+    0X for hexadecimal.  If base is 16, a preceding 0x or 0X is
+    accepted.
+
+    """
+    return _int(s, base)
+
+
+# Convert string to long integer
+def atol(s, base=10):
+    """atol(s [,base]) -> long
+
+    Return the long integer represented by the string s in the
+    given base, which defaults to 10.  The string s must consist
+    of one or more digits, possibly preceded by a sign.  If base
+    is 0, it is chosen from the leading characters of s, 0 for
+    octal, 0x or 0X for hexadecimal.  If base is 16, a preceding
+    0x or 0X is accepted.  A trailing L or l is not accepted,
+    unless base is 0.
+
+    """
+    return _long(s, base)
+
+
+# Left-justify a string
+def ljust(s, width, *args):
+    """ljust(s, width[, fillchar]) -> string
+
+    Return a left-justified version of s, in a field of the
+    specified width, padded with spaces as needed.  The string is
+    never truncated.  If specified the fillchar is used instead of spaces.
+
+    """
+    return s.ljust(width, *args)
+
+# Right-justify a string
+def rjust(s, width, *args):
+    """rjust(s, width[, fillchar]) -> string
+
+    Return a right-justified version of s, in a field of the
+    specified width, padded with spaces as needed.  The string is
+    never truncated.  If specified the fillchar is used instead of spaces.
+
+    """
+    return s.rjust(width, *args)
+
+# Center a string
+def center(s, width, *args):
+    """center(s, width[, fillchar]) -> string
+
+    Return a center version of s, in a field of the specified
+    width. padded with spaces as needed.  The string is never
+    truncated.  If specified the fillchar is used instead of spaces.
+
+    """
+    return s.center(width, *args)
+
+# Zero-fill a number, e.g., (12, 3) --> '012' and (-3, 3) --> '-03'
+# Decadent feature: the argument may be a string or a number
+# (Use of this is deprecated; it should be a string as with ljust c.s.)
+def zfill(x, width):
+    """zfill(x, width) -> string
+
+    Pad a numeric string x with zeros on the left, to fill a field
+    of the specified width.  The string x is never truncated.
+
+    """
+    if not isinstance(x, basestring):
+        x = repr(x)
+    return x.zfill(width)
+
+# Expand tabs in a string.
+# Doesn't take non-printing chars into account, but does understand \n.
+def expandtabs(s, tabsize=8):
+    """expandtabs(s [,tabsize]) -> string
+
+    Return a copy of the string s with all tab characters replaced
+    by the appropriate number of spaces, depending on the current
+    column, and the tabsize (default 8).
+
+    """
+    return s.expandtabs(tabsize)
+
+# Character translation through look-up table.
+def translate(s, table, deletions=""):
+    """translate(s,table [,deletions]) -> string
+
+    Return a copy of the string s, where all characters occurring
+    in the optional argument deletions are removed, and the
+    remaining characters have been mapped through the given
+    translation table, which must be a string of length 256.  The
+    deletions argument is not allowed for Unicode strings.
+
+    """
+    if deletions:
+        return s.translate(table, deletions)
+    else:
+        # Add s[:0] so that if s is Unicode and table is an 8-bit string,
+        # table is converted to Unicode.  This means that table *cannot*
+        # be a dictionary -- for that feature, use u.translate() directly.
+        return s.translate(table + s[:0])
+
+# Capitalize a string, e.g. "aBc  dEf" -> "Abc  def".
+def capitalize(s):
+    """capitalize(s) -> string
+
+    Return a copy of the string s with only its first character
+    capitalized.
+
+    """
+    return s.capitalize()
+
+# Substring replacement (global)
+def replace(s, old, new, maxsplit=-1):
+    """replace (str, old, new[, maxsplit]) -> string
+
+    Return a copy of string str with all occurrences of substring
+    old replaced by new. If the optional argument maxsplit is
+    given, only the first maxsplit occurrences are replaced.
+
+    """
+    return s.replace(old, new, maxsplit)
+
+
+# Try importing optional built-in module "strop" -- if it exists,
+# it redefines some string operations that are 100-1000 times faster.
+# It also defines values for whitespace, lowercase and uppercase
+# that match <ctype.h>'s definitions.
+
+try:
+    from strop import maketrans, lowercase, uppercase, whitespace
+    letters = lowercase + uppercase
+except ImportError:
+    pass                                          # Use the original versions

Added: vendor/Python/current/Lib/stringold.py
===================================================================
--- vendor/Python/current/Lib/stringold.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/stringold.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,429 @@
+# module 'string' -- A collection of string operations
+
+# Warning: most of the code you see here isn't normally used nowadays.  With
+# Python 1.6, many of these functions are implemented as methods on the
+# standard string object. They used to be implemented by a built-in module
+# called strop, but strop is now obsolete itself.
+
+"""Common string manipulations.
+
+Public module variables:
+
+whitespace -- a string containing all characters considered whitespace
+lowercase -- a string containing all characters considered lowercase letters
+uppercase -- a string containing all characters considered uppercase letters
+letters -- a string containing all characters considered letters
+digits -- a string containing all characters considered decimal digits
+hexdigits -- a string containing all characters considered hexadecimal digits
+octdigits -- a string containing all characters considered octal digits
+
+"""
+
+# Some strings for ctype-style character classification
+whitespace = ' \t\n\r\v\f'
+lowercase = 'abcdefghijklmnopqrstuvwxyz'
+uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+letters = lowercase + uppercase
+digits = '0123456789'
+hexdigits = digits + 'abcdef' + 'ABCDEF'
+octdigits = '01234567'
+
+# Case conversion helpers
+_idmap = ''
+for i in range(256): _idmap = _idmap + chr(i)
+del i
+
+# Backward compatible names for exceptions
+index_error = ValueError
+atoi_error = ValueError
+atof_error = ValueError
+atol_error = ValueError
+
+# convert UPPER CASE letters to lower case
+def lower(s):
+    """lower(s) -> string
+
+    Return a copy of the string s converted to lowercase.
+
+    """
+    return s.lower()
+
+# Convert lower case letters to UPPER CASE
+def upper(s):
+    """upper(s) -> string
+
+    Return a copy of the string s converted to uppercase.
+
+    """
+    return s.upper()
+
+# Swap lower case letters and UPPER CASE
+def swapcase(s):
+    """swapcase(s) -> string
+
+    Return a copy of the string s with upper case characters
+    converted to lowercase and vice versa.
+
+    """
+    return s.swapcase()
+
+# Strip leading and trailing tabs and spaces
+def strip(s):
+    """strip(s) -> string
+
+    Return a copy of the string s with leading and trailing
+    whitespace removed.
+
+    """
+    return s.strip()
+
+# Strip leading tabs and spaces
+def lstrip(s):
+    """lstrip(s) -> string
+
+    Return a copy of the string s with leading whitespace removed.
+
+    """
+    return s.lstrip()
+
+# Strip trailing tabs and spaces
+def rstrip(s):
+    """rstrip(s) -> string
+
+    Return a copy of the string s with trailing whitespace
+    removed.
+
+    """
+    return s.rstrip()
+
+
+# Split a string into a list of space/tab-separated words
+def split(s, sep=None, maxsplit=0):
+    """split(str [,sep [,maxsplit]]) -> list of strings
+
+    Return a list of the words in the string s, using sep as the
+    delimiter string.  If maxsplit is nonzero, splits into at most
+    maxsplit words If sep is not specified, any whitespace string
+    is a separator.  Maxsplit defaults to 0.
+
+    (split and splitfields are synonymous)
+
+    """
+    return s.split(sep, maxsplit)
+splitfields = split
+
+# Join fields with optional separator
+def join(words, sep = ' '):
+    """join(list [,sep]) -> string
+
+    Return a string composed of the words in list, with
+    intervening occurrences of sep.  The default separator is a
+    single space.
+
+    (joinfields and join are synonymous)
+
+    """
+    return sep.join(words)
+joinfields = join
+
+# for a little bit of speed
+_apply = apply
+
+# Find substring, raise exception if not found
+def index(s, *args):
+    """index(s, sub [,start [,end]]) -> int
+
+    Like find but raises ValueError when the substring is not found.
+
+    """
+    return _apply(s.index, args)
+
+# Find last substring, raise exception if not found
+def rindex(s, *args):
+    """rindex(s, sub [,start [,end]]) -> int
+
+    Like rfind but raises ValueError when the substring is not found.
+
+    """
+    return _apply(s.rindex, args)
+
+# Count non-overlapping occurrences of substring
+def count(s, *args):
+    """count(s, sub[, start[,end]]) -> int
+
+    Return the number of occurrences of substring sub in string
+    s[start:end].  Optional arguments start and end are
+    interpreted as in slice notation.
+
+    """
+    return _apply(s.count, args)
+
+# Find substring, return -1 if not found
+def find(s, *args):
+    """find(s, sub [,start [,end]]) -> in
+
+    Return the lowest index in s where substring sub is found,
+    such that sub is contained within s[start,end].  Optional
+    arguments start and end are interpreted as in slice notation.
+
+    Return -1 on failure.
+
+    """
+    return _apply(s.find, args)
+
+# Find last substring, return -1 if not found
+def rfind(s, *args):
+    """rfind(s, sub [,start [,end]]) -> int
+
+    Return the highest index in s where substring sub is found,
+    such that sub is contained within s[start,end].  Optional
+    arguments start and end are interpreted as in slice notation.
+
+    Return -1 on failure.
+
+    """
+    return _apply(s.rfind, args)
+
+# for a bit of speed
+_float = float
+_int = int
+_long = long
+_StringType = type('')
+
+# Convert string to float
+def atof(s):
+    """atof(s) -> float
+
+    Return the floating point number represented by the string s.
+
+    """
+    if type(s) == _StringType:
+        return _float(s)
+    else:
+        raise TypeError('argument 1: expected string, %s found' %
+                        type(s).__name__)
+
+# Convert string to integer
+def atoi(*args):
+    """atoi(s [,base]) -> int
+
+    Return the integer represented by the string s in the given
+    base, which defaults to 10.  The string s must consist of one
+    or more digits, possibly preceded by a sign.  If base is 0, it
+    is chosen from the leading characters of s, 0 for octal, 0x or
+    0X for hexadecimal.  If base is 16, a preceding 0x or 0X is
+    accepted.
+
+    """
+    try:
+        s = args[0]
+    except IndexError:
+        raise TypeError('function requires at least 1 argument: %d given' %
+                        len(args))
+    # Don't catch type error resulting from too many arguments to int().  The
+    # error message isn't compatible but the error type is, and this function
+    # is complicated enough already.
+    if type(s) == _StringType:
+        return _apply(_int, args)
+    else:
+        raise TypeError('argument 1: expected string, %s found' %
+                        type(s).__name__)
+
+
+# Convert string to long integer
+def atol(*args):
+    """atol(s [,base]) -> long
+
+    Return the long integer represented by the string s in the
+    given base, which defaults to 10.  The string s must consist
+    of one or more digits, possibly preceded by a sign.  If base
+    is 0, it is chosen from the leading characters of s, 0 for
+    octal, 0x or 0X for hexadecimal.  If base is 16, a preceding
+    0x or 0X is accepted.  A trailing L or l is not accepted,
+    unless base is 0.
+
+    """
+    try:
+        s = args[0]
+    except IndexError:
+        raise TypeError('function requires at least 1 argument: %d given' %
+                        len(args))
+    # Don't catch type error resulting from too many arguments to long().  The
+    # error message isn't compatible but the error type is, and this function
+    # is complicated enough already.
+    if type(s) == _StringType:
+        return _apply(_long, args)
+    else:
+        raise TypeError('argument 1: expected string, %s found' %
+                        type(s).__name__)
+
+
+# Left-justify a string
+def ljust(s, width):
+    """ljust(s, width) -> string
+
+    Return a left-justified version of s, in a field of the
+    specified width, padded with spaces as needed.  The string is
+    never truncated.
+
+    """
+    n = width - len(s)
+    if n <= 0: return s
+    return s + ' '*n
+
+# Right-justify a string
+def rjust(s, width):
+    """rjust(s, width) -> string
+
+    Return a right-justified version of s, in a field of the
+    specified width, padded with spaces as needed.  The string is
+    never truncated.
+
+    """
+    n = width - len(s)
+    if n <= 0: return s
+    return ' '*n + s
+
+# Center a string
+def center(s, width):
+    """center(s, width) -> string
+
+    Return a center version of s, in a field of the specified
+    width. padded with spaces as needed.  The string is never
+    truncated.
+
+    """
+    n = width - len(s)
+    if n <= 0: return s
+    half = n/2
+    if n%2 and width%2:
+        # This ensures that center(center(s, i), j) = center(s, j)
+        half = half+1
+    return ' '*half +  s + ' '*(n-half)
+
+# Zero-fill a number, e.g., (12, 3) --> '012' and (-3, 3) --> '-03'
+# Decadent feature: the argument may be a string or a number
+# (Use of this is deprecated; it should be a string as with ljust c.s.)
+def zfill(x, width):
+    """zfill(x, width) -> string
+
+    Pad a numeric string x with zeros on the left, to fill a field
+    of the specified width.  The string x is never truncated.
+
+    """
+    if type(x) == type(''): s = x
+    else: s = repr(x)
+    n = len(s)
+    if n >= width: return s
+    sign = ''
+    if s[0] in ('-', '+'):
+        sign, s = s[0], s[1:]
+    return sign + '0'*(width-n) + s
+
+# Expand tabs in a string.
+# Doesn't take non-printing chars into account, but does understand \n.
+def expandtabs(s, tabsize=8):
+    """expandtabs(s [,tabsize]) -> string
+
+    Return a copy of the string s with all tab characters replaced
+    by the appropriate number of spaces, depending on the current
+    column, and the tabsize (default 8).
+
+    """
+    res = line = ''
+    for c in s:
+        if c == '\t':
+            c = ' '*(tabsize - len(line) % tabsize)
+        line = line + c
+        if c == '\n':
+            res = res + line
+            line = ''
+    return res + line
+
+# Character translation through look-up table.
+def translate(s, table, deletions=""):
+    """translate(s,table [,deletechars]) -> string
+
+    Return a copy of the string s, where all characters occurring
+    in the optional argument deletechars are removed, and the
+    remaining characters have been mapped through the given
+    translation table, which must be a string of length 256.
+
+    """
+    return s.translate(table, deletions)
+
+# Capitalize a string, e.g. "aBc  dEf" -> "Abc  def".
+def capitalize(s):
+    """capitalize(s) -> string
+
+    Return a copy of the string s with only its first character
+    capitalized.
+
+    """
+    return s.capitalize()
+
+# Capitalize the words in a string, e.g. " aBc  dEf " -> "Abc Def".
+def capwords(s, sep=None):
+    """capwords(s, [sep]) -> string
+
+    Split the argument into words using split, capitalize each
+    word using capitalize, and join the capitalized words using
+    join. Note that this replaces runs of whitespace characters by
+    a single space.
+
+    """
+    return join(map(capitalize, s.split(sep)), sep or ' ')
+
+# Construct a translation string
+_idmapL = None
+def maketrans(fromstr, tostr):
+    """maketrans(frm, to) -> string
+
+    Return a translation table (a string of 256 bytes long)
+    suitable for use in string.translate.  The strings frm and to
+    must be of the same length.
+
+    """
+    if len(fromstr) != len(tostr):
+        raise ValueError, "maketrans arguments must have same length"
+    global _idmapL
+    if not _idmapL:
+        _idmapL = map(None, _idmap)
+    L = _idmapL[:]
+    fromstr = map(ord, fromstr)
+    for i in range(len(fromstr)):
+        L[fromstr[i]] = tostr[i]
+    return join(L, "")
+
+# Substring replacement (global)
+def replace(s, old, new, maxsplit=0):
+    """replace (str, old, new[, maxsplit]) -> string
+
+    Return a copy of string str with all occurrences of substring
+    old replaced by new. If the optional argument maxsplit is
+    given, only the first maxsplit occurrences are replaced.
+
+    """
+    return s.replace(old, new, maxsplit)
+
+
+# XXX: transitional
+#
+# If string objects do not have methods, then we need to use the old string.py
+# library, which uses strop for many more things than just the few outlined
+# below.
+try:
+    ''.upper
+except AttributeError:
+    from stringold import *
+
+# Try importing optional built-in module "strop" -- if it exists,
+# it redefines some string operations that are 100-1000 times faster.
+# It also defines values for whitespace, lowercase and uppercase
+# that match <ctype.h>'s definitions.
+
+try:
+    from strop import maketrans, lowercase, uppercase, whitespace
+    letters = lowercase + uppercase
+except ImportError:
+    pass                                          # Use the original versions

Added: vendor/Python/current/Lib/stringprep.py
===================================================================
--- vendor/Python/current/Lib/stringprep.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/stringprep.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,272 @@
+# This file is generated by mkstringprep.py. DO NOT EDIT.
+"""Library that exposes various tables found in the StringPrep RFC 3454.
+
+There are two kinds of tables: sets, for which a member test is provided,
+and mappings, for which a mapping function is provided.
+"""
+
+from unicodedata import ucd_3_2_0 as unicodedata
+
+assert unicodedata.unidata_version == '3.2.0'
+
+def in_table_a1(code):
+    if unicodedata.category(code) != 'Cn': return False
+    c = ord(code)
+    if 0xFDD0 <= c < 0xFDF0: return False
+    return (c & 0xFFFF) not in (0xFFFE, 0xFFFF)
+
+
+b1_set = set([173, 847, 6150, 6155, 6156, 6157, 8203, 8204, 8205, 8288, 65279] + range(65024,65040))
+def in_table_b1(code):
+    return ord(code) in b1_set
+
+
+b3_exceptions = {
+0xb5:u'\u03bc', 0xdf:u'ss', 0x130:u'i\u0307', 0x149:u'\u02bcn',
+0x17f:u's', 0x1f0:u'j\u030c', 0x345:u'\u03b9', 0x37a:u' \u03b9',
+0x390:u'\u03b9\u0308\u0301', 0x3b0:u'\u03c5\u0308\u0301', 0x3c2:u'\u03c3', 0x3d0:u'\u03b2',
+0x3d1:u'\u03b8', 0x3d2:u'\u03c5', 0x3d3:u'\u03cd', 0x3d4:u'\u03cb',
+0x3d5:u'\u03c6', 0x3d6:u'\u03c0', 0x3f0:u'\u03ba', 0x3f1:u'\u03c1',
+0x3f2:u'\u03c3', 0x3f5:u'\u03b5', 0x587:u'\u0565\u0582', 0x1e96:u'h\u0331',
+0x1e97:u't\u0308', 0x1e98:u'w\u030a', 0x1e99:u'y\u030a', 0x1e9a:u'a\u02be',
+0x1e9b:u'\u1e61', 0x1f50:u'\u03c5\u0313', 0x1f52:u'\u03c5\u0313\u0300', 0x1f54:u'\u03c5\u0313\u0301',
+0x1f56:u'\u03c5\u0313\u0342', 0x1f80:u'\u1f00\u03b9', 0x1f81:u'\u1f01\u03b9', 0x1f82:u'\u1f02\u03b9',
+0x1f83:u'\u1f03\u03b9', 0x1f84:u'\u1f04\u03b9', 0x1f85:u'\u1f05\u03b9', 0x1f86:u'\u1f06\u03b9',
+0x1f87:u'\u1f07\u03b9', 0x1f88:u'\u1f00\u03b9', 0x1f89:u'\u1f01\u03b9', 0x1f8a:u'\u1f02\u03b9',
+0x1f8b:u'\u1f03\u03b9', 0x1f8c:u'\u1f04\u03b9', 0x1f8d:u'\u1f05\u03b9', 0x1f8e:u'\u1f06\u03b9',
+0x1f8f:u'\u1f07\u03b9', 0x1f90:u'\u1f20\u03b9', 0x1f91:u'\u1f21\u03b9', 0x1f92:u'\u1f22\u03b9',
+0x1f93:u'\u1f23\u03b9', 0x1f94:u'\u1f24\u03b9', 0x1f95:u'\u1f25\u03b9', 0x1f96:u'\u1f26\u03b9',
+0x1f97:u'\u1f27\u03b9', 0x1f98:u'\u1f20\u03b9', 0x1f99:u'\u1f21\u03b9', 0x1f9a:u'\u1f22\u03b9',
+0x1f9b:u'\u1f23\u03b9', 0x1f9c:u'\u1f24\u03b9', 0x1f9d:u'\u1f25\u03b9', 0x1f9e:u'\u1f26\u03b9',
+0x1f9f:u'\u1f27\u03b9', 0x1fa0:u'\u1f60\u03b9', 0x1fa1:u'\u1f61\u03b9', 0x1fa2:u'\u1f62\u03b9',
+0x1fa3:u'\u1f63\u03b9', 0x1fa4:u'\u1f64\u03b9', 0x1fa5:u'\u1f65\u03b9', 0x1fa6:u'\u1f66\u03b9',
+0x1fa7:u'\u1f67\u03b9', 0x1fa8:u'\u1f60\u03b9', 0x1fa9:u'\u1f61\u03b9', 0x1faa:u'\u1f62\u03b9',
+0x1fab:u'\u1f63\u03b9', 0x1fac:u'\u1f64\u03b9', 0x1fad:u'\u1f65\u03b9', 0x1fae:u'\u1f66\u03b9',
+0x1faf:u'\u1f67\u03b9', 0x1fb2:u'\u1f70\u03b9', 0x1fb3:u'\u03b1\u03b9', 0x1fb4:u'\u03ac\u03b9',
+0x1fb6:u'\u03b1\u0342', 0x1fb7:u'\u03b1\u0342\u03b9', 0x1fbc:u'\u03b1\u03b9', 0x1fbe:u'\u03b9',
+0x1fc2:u'\u1f74\u03b9', 0x1fc3:u'\u03b7\u03b9', 0x1fc4:u'\u03ae\u03b9', 0x1fc6:u'\u03b7\u0342',
+0x1fc7:u'\u03b7\u0342\u03b9', 0x1fcc:u'\u03b7\u03b9', 0x1fd2:u'\u03b9\u0308\u0300', 0x1fd3:u'\u03b9\u0308\u0301',
+0x1fd6:u'\u03b9\u0342', 0x1fd7:u'\u03b9\u0308\u0342', 0x1fe2:u'\u03c5\u0308\u0300', 0x1fe3:u'\u03c5\u0308\u0301',
+0x1fe4:u'\u03c1\u0313', 0x1fe6:u'\u03c5\u0342', 0x1fe7:u'\u03c5\u0308\u0342', 0x1ff2:u'\u1f7c\u03b9',
+0x1ff3:u'\u03c9\u03b9', 0x1ff4:u'\u03ce\u03b9', 0x1ff6:u'\u03c9\u0342', 0x1ff7:u'\u03c9\u0342\u03b9',
+0x1ffc:u'\u03c9\u03b9', 0x20a8:u'rs', 0x2102:u'c', 0x2103:u'\xb0c',
+0x2107:u'\u025b', 0x2109:u'\xb0f', 0x210b:u'h', 0x210c:u'h',
+0x210d:u'h', 0x2110:u'i', 0x2111:u'i', 0x2112:u'l',
+0x2115:u'n', 0x2116:u'no', 0x2119:u'p', 0x211a:u'q',
+0x211b:u'r', 0x211c:u'r', 0x211d:u'r', 0x2120:u'sm',
+0x2121:u'tel', 0x2122:u'tm', 0x2124:u'z', 0x2128:u'z',
+0x212c:u'b', 0x212d:u'c', 0x2130:u'e', 0x2131:u'f',
+0x2133:u'm', 0x213e:u'\u03b3', 0x213f:u'\u03c0', 0x2145:u'd',
+0x3371:u'hpa', 0x3373:u'au', 0x3375:u'ov', 0x3380:u'pa',
+0x3381:u'na', 0x3382:u'\u03bca', 0x3383:u'ma', 0x3384:u'ka',
+0x3385:u'kb', 0x3386:u'mb', 0x3387:u'gb', 0x338a:u'pf',
+0x338b:u'nf', 0x338c:u'\u03bcf', 0x3390:u'hz', 0x3391:u'khz',
+0x3392:u'mhz', 0x3393:u'ghz', 0x3394:u'thz', 0x33a9:u'pa',
+0x33aa:u'kpa', 0x33ab:u'mpa', 0x33ac:u'gpa', 0x33b4:u'pv',
+0x33b5:u'nv', 0x33b6:u'\u03bcv', 0x33b7:u'mv', 0x33b8:u'kv',
+0x33b9:u'mv', 0x33ba:u'pw', 0x33bb:u'nw', 0x33bc:u'\u03bcw',
+0x33bd:u'mw', 0x33be:u'kw', 0x33bf:u'mw', 0x33c0:u'k\u03c9',
+0x33c1:u'm\u03c9', 0x33c3:u'bq', 0x33c6:u'c\u2215kg', 0x33c7:u'co.',
+0x33c8:u'db', 0x33c9:u'gy', 0x33cb:u'hp', 0x33cd:u'kk',
+0x33ce:u'km', 0x33d7:u'ph', 0x33d9:u'ppm', 0x33da:u'pr',
+0x33dc:u'sv', 0x33dd:u'wb', 0xfb00:u'ff', 0xfb01:u'fi',
+0xfb02:u'fl', 0xfb03:u'ffi', 0xfb04:u'ffl', 0xfb05:u'st',
+0xfb06:u'st', 0xfb13:u'\u0574\u0576', 0xfb14:u'\u0574\u0565', 0xfb15:u'\u0574\u056b',
+0xfb16:u'\u057e\u0576', 0xfb17:u'\u0574\u056d', 0x1d400:u'a', 0x1d401:u'b',
+0x1d402:u'c', 0x1d403:u'd', 0x1d404:u'e', 0x1d405:u'f',
+0x1d406:u'g', 0x1d407:u'h', 0x1d408:u'i', 0x1d409:u'j',
+0x1d40a:u'k', 0x1d40b:u'l', 0x1d40c:u'm', 0x1d40d:u'n',
+0x1d40e:u'o', 0x1d40f:u'p', 0x1d410:u'q', 0x1d411:u'r',
+0x1d412:u's', 0x1d413:u't', 0x1d414:u'u', 0x1d415:u'v',
+0x1d416:u'w', 0x1d417:u'x', 0x1d418:u'y', 0x1d419:u'z',
+0x1d434:u'a', 0x1d435:u'b', 0x1d436:u'c', 0x1d437:u'd',
+0x1d438:u'e', 0x1d439:u'f', 0x1d43a:u'g', 0x1d43b:u'h',
+0x1d43c:u'i', 0x1d43d:u'j', 0x1d43e:u'k', 0x1d43f:u'l',
+0x1d440:u'm', 0x1d441:u'n', 0x1d442:u'o', 0x1d443:u'p',
+0x1d444:u'q', 0x1d445:u'r', 0x1d446:u's', 0x1d447:u't',
+0x1d448:u'u', 0x1d449:u'v', 0x1d44a:u'w', 0x1d44b:u'x',
+0x1d44c:u'y', 0x1d44d:u'z', 0x1d468:u'a', 0x1d469:u'b',
+0x1d46a:u'c', 0x1d46b:u'd', 0x1d46c:u'e', 0x1d46d:u'f',
+0x1d46e:u'g', 0x1d46f:u'h', 0x1d470:u'i', 0x1d471:u'j',
+0x1d472:u'k', 0x1d473:u'l', 0x1d474:u'm', 0x1d475:u'n',
+0x1d476:u'o', 0x1d477:u'p', 0x1d478:u'q', 0x1d479:u'r',
+0x1d47a:u's', 0x1d47b:u't', 0x1d47c:u'u', 0x1d47d:u'v',
+0x1d47e:u'w', 0x1d47f:u'x', 0x1d480:u'y', 0x1d481:u'z',
+0x1d49c:u'a', 0x1d49e:u'c', 0x1d49f:u'd', 0x1d4a2:u'g',
+0x1d4a5:u'j', 0x1d4a6:u'k', 0x1d4a9:u'n', 0x1d4aa:u'o',
+0x1d4ab:u'p', 0x1d4ac:u'q', 0x1d4ae:u's', 0x1d4af:u't',
+0x1d4b0:u'u', 0x1d4b1:u'v', 0x1d4b2:u'w', 0x1d4b3:u'x',
+0x1d4b4:u'y', 0x1d4b5:u'z', 0x1d4d0:u'a', 0x1d4d1:u'b',
+0x1d4d2:u'c', 0x1d4d3:u'd', 0x1d4d4:u'e', 0x1d4d5:u'f',
+0x1d4d6:u'g', 0x1d4d7:u'h', 0x1d4d8:u'i', 0x1d4d9:u'j',
+0x1d4da:u'k', 0x1d4db:u'l', 0x1d4dc:u'm', 0x1d4dd:u'n',
+0x1d4de:u'o', 0x1d4df:u'p', 0x1d4e0:u'q', 0x1d4e1:u'r',
+0x1d4e2:u's', 0x1d4e3:u't', 0x1d4e4:u'u', 0x1d4e5:u'v',
+0x1d4e6:u'w', 0x1d4e7:u'x', 0x1d4e8:u'y', 0x1d4e9:u'z',
+0x1d504:u'a', 0x1d505:u'b', 0x1d507:u'd', 0x1d508:u'e',
+0x1d509:u'f', 0x1d50a:u'g', 0x1d50d:u'j', 0x1d50e:u'k',
+0x1d50f:u'l', 0x1d510:u'm', 0x1d511:u'n', 0x1d512:u'o',
+0x1d513:u'p', 0x1d514:u'q', 0x1d516:u's', 0x1d517:u't',
+0x1d518:u'u', 0x1d519:u'v', 0x1d51a:u'w', 0x1d51b:u'x',
+0x1d51c:u'y', 0x1d538:u'a', 0x1d539:u'b', 0x1d53b:u'd',
+0x1d53c:u'e', 0x1d53d:u'f', 0x1d53e:u'g', 0x1d540:u'i',
+0x1d541:u'j', 0x1d542:u'k', 0x1d543:u'l', 0x1d544:u'm',
+0x1d546:u'o', 0x1d54a:u's', 0x1d54b:u't', 0x1d54c:u'u',
+0x1d54d:u'v', 0x1d54e:u'w', 0x1d54f:u'x', 0x1d550:u'y',
+0x1d56c:u'a', 0x1d56d:u'b', 0x1d56e:u'c', 0x1d56f:u'd',
+0x1d570:u'e', 0x1d571:u'f', 0x1d572:u'g', 0x1d573:u'h',
+0x1d574:u'i', 0x1d575:u'j', 0x1d576:u'k', 0x1d577:u'l',
+0x1d578:u'm', 0x1d579:u'n', 0x1d57a:u'o', 0x1d57b:u'p',
+0x1d57c:u'q', 0x1d57d:u'r', 0x1d57e:u's', 0x1d57f:u't',
+0x1d580:u'u', 0x1d581:u'v', 0x1d582:u'w', 0x1d583:u'x',
+0x1d584:u'y', 0x1d585:u'z', 0x1d5a0:u'a', 0x1d5a1:u'b',
+0x1d5a2:u'c', 0x1d5a3:u'd', 0x1d5a4:u'e', 0x1d5a5:u'f',
+0x1d5a6:u'g', 0x1d5a7:u'h', 0x1d5a8:u'i', 0x1d5a9:u'j',
+0x1d5aa:u'k', 0x1d5ab:u'l', 0x1d5ac:u'm', 0x1d5ad:u'n',
+0x1d5ae:u'o', 0x1d5af:u'p', 0x1d5b0:u'q', 0x1d5b1:u'r',
+0x1d5b2:u's', 0x1d5b3:u't', 0x1d5b4:u'u', 0x1d5b5:u'v',
+0x1d5b6:u'w', 0x1d5b7:u'x', 0x1d5b8:u'y', 0x1d5b9:u'z',
+0x1d5d4:u'a', 0x1d5d5:u'b', 0x1d5d6:u'c', 0x1d5d7:u'd',
+0x1d5d8:u'e', 0x1d5d9:u'f', 0x1d5da:u'g', 0x1d5db:u'h',
+0x1d5dc:u'i', 0x1d5dd:u'j', 0x1d5de:u'k', 0x1d5df:u'l',
+0x1d5e0:u'm', 0x1d5e1:u'n', 0x1d5e2:u'o', 0x1d5e3:u'p',
+0x1d5e4:u'q', 0x1d5e5:u'r', 0x1d5e6:u's', 0x1d5e7:u't',
+0x1d5e8:u'u', 0x1d5e9:u'v', 0x1d5ea:u'w', 0x1d5eb:u'x',
+0x1d5ec:u'y', 0x1d5ed:u'z', 0x1d608:u'a', 0x1d609:u'b',
+0x1d60a:u'c', 0x1d60b:u'd', 0x1d60c:u'e', 0x1d60d:u'f',
+0x1d60e:u'g', 0x1d60f:u'h', 0x1d610:u'i', 0x1d611:u'j',
+0x1d612:u'k', 0x1d613:u'l', 0x1d614:u'm', 0x1d615:u'n',
+0x1d616:u'o', 0x1d617:u'p', 0x1d618:u'q', 0x1d619:u'r',
+0x1d61a:u's', 0x1d61b:u't', 0x1d61c:u'u', 0x1d61d:u'v',
+0x1d61e:u'w', 0x1d61f:u'x', 0x1d620:u'y', 0x1d621:u'z',
+0x1d63c:u'a', 0x1d63d:u'b', 0x1d63e:u'c', 0x1d63f:u'd',
+0x1d640:u'e', 0x1d641:u'f', 0x1d642:u'g', 0x1d643:u'h',
+0x1d644:u'i', 0x1d645:u'j', 0x1d646:u'k', 0x1d647:u'l',
+0x1d648:u'm', 0x1d649:u'n', 0x1d64a:u'o', 0x1d64b:u'p',
+0x1d64c:u'q', 0x1d64d:u'r', 0x1d64e:u's', 0x1d64f:u't',
+0x1d650:u'u', 0x1d651:u'v', 0x1d652:u'w', 0x1d653:u'x',
+0x1d654:u'y', 0x1d655:u'z', 0x1d670:u'a', 0x1d671:u'b',
+0x1d672:u'c', 0x1d673:u'd', 0x1d674:u'e', 0x1d675:u'f',
+0x1d676:u'g', 0x1d677:u'h', 0x1d678:u'i', 0x1d679:u'j',
+0x1d67a:u'k', 0x1d67b:u'l', 0x1d67c:u'm', 0x1d67d:u'n',
+0x1d67e:u'o', 0x1d67f:u'p', 0x1d680:u'q', 0x1d681:u'r',
+0x1d682:u's', 0x1d683:u't', 0x1d684:u'u', 0x1d685:u'v',
+0x1d686:u'w', 0x1d687:u'x', 0x1d688:u'y', 0x1d689:u'z',
+0x1d6a8:u'\u03b1', 0x1d6a9:u'\u03b2', 0x1d6aa:u'\u03b3', 0x1d6ab:u'\u03b4',
+0x1d6ac:u'\u03b5', 0x1d6ad:u'\u03b6', 0x1d6ae:u'\u03b7', 0x1d6af:u'\u03b8',
+0x1d6b0:u'\u03b9', 0x1d6b1:u'\u03ba', 0x1d6b2:u'\u03bb', 0x1d6b3:u'\u03bc',
+0x1d6b4:u'\u03bd', 0x1d6b5:u'\u03be', 0x1d6b6:u'\u03bf', 0x1d6b7:u'\u03c0',
+0x1d6b8:u'\u03c1', 0x1d6b9:u'\u03b8', 0x1d6ba:u'\u03c3', 0x1d6bb:u'\u03c4',
+0x1d6bc:u'\u03c5', 0x1d6bd:u'\u03c6', 0x1d6be:u'\u03c7', 0x1d6bf:u'\u03c8',
+0x1d6c0:u'\u03c9', 0x1d6d3:u'\u03c3', 0x1d6e2:u'\u03b1', 0x1d6e3:u'\u03b2',
+0x1d6e4:u'\u03b3', 0x1d6e5:u'\u03b4', 0x1d6e6:u'\u03b5', 0x1d6e7:u'\u03b6',
+0x1d6e8:u'\u03b7', 0x1d6e9:u'\u03b8', 0x1d6ea:u'\u03b9', 0x1d6eb:u'\u03ba',
+0x1d6ec:u'\u03bb', 0x1d6ed:u'\u03bc', 0x1d6ee:u'\u03bd', 0x1d6ef:u'\u03be',
+0x1d6f0:u'\u03bf', 0x1d6f1:u'\u03c0', 0x1d6f2:u'\u03c1', 0x1d6f3:u'\u03b8',
+0x1d6f4:u'\u03c3', 0x1d6f5:u'\u03c4', 0x1d6f6:u'\u03c5', 0x1d6f7:u'\u03c6',
+0x1d6f8:u'\u03c7', 0x1d6f9:u'\u03c8', 0x1d6fa:u'\u03c9', 0x1d70d:u'\u03c3',
+0x1d71c:u'\u03b1', 0x1d71d:u'\u03b2', 0x1d71e:u'\u03b3', 0x1d71f:u'\u03b4',
+0x1d720:u'\u03b5', 0x1d721:u'\u03b6', 0x1d722:u'\u03b7', 0x1d723:u'\u03b8',
+0x1d724:u'\u03b9', 0x1d725:u'\u03ba', 0x1d726:u'\u03bb', 0x1d727:u'\u03bc',
+0x1d728:u'\u03bd', 0x1d729:u'\u03be', 0x1d72a:u'\u03bf', 0x1d72b:u'\u03c0',
+0x1d72c:u'\u03c1', 0x1d72d:u'\u03b8', 0x1d72e:u'\u03c3', 0x1d72f:u'\u03c4',
+0x1d730:u'\u03c5', 0x1d731:u'\u03c6', 0x1d732:u'\u03c7', 0x1d733:u'\u03c8',
+0x1d734:u'\u03c9', 0x1d747:u'\u03c3', 0x1d756:u'\u03b1', 0x1d757:u'\u03b2',
+0x1d758:u'\u03b3', 0x1d759:u'\u03b4', 0x1d75a:u'\u03b5', 0x1d75b:u'\u03b6',
+0x1d75c:u'\u03b7', 0x1d75d:u'\u03b8', 0x1d75e:u'\u03b9', 0x1d75f:u'\u03ba',
+0x1d760:u'\u03bb', 0x1d761:u'\u03bc', 0x1d762:u'\u03bd', 0x1d763:u'\u03be',
+0x1d764:u'\u03bf', 0x1d765:u'\u03c0', 0x1d766:u'\u03c1', 0x1d767:u'\u03b8',
+0x1d768:u'\u03c3', 0x1d769:u'\u03c4', 0x1d76a:u'\u03c5', 0x1d76b:u'\u03c6',
+0x1d76c:u'\u03c7', 0x1d76d:u'\u03c8', 0x1d76e:u'\u03c9', 0x1d781:u'\u03c3',
+0x1d790:u'\u03b1', 0x1d791:u'\u03b2', 0x1d792:u'\u03b3', 0x1d793:u'\u03b4',
+0x1d794:u'\u03b5', 0x1d795:u'\u03b6', 0x1d796:u'\u03b7', 0x1d797:u'\u03b8',
+0x1d798:u'\u03b9', 0x1d799:u'\u03ba', 0x1d79a:u'\u03bb', 0x1d79b:u'\u03bc',
+0x1d79c:u'\u03bd', 0x1d79d:u'\u03be', 0x1d79e:u'\u03bf', 0x1d79f:u'\u03c0',
+0x1d7a0:u'\u03c1', 0x1d7a1:u'\u03b8', 0x1d7a2:u'\u03c3', 0x1d7a3:u'\u03c4',
+0x1d7a4:u'\u03c5', 0x1d7a5:u'\u03c6', 0x1d7a6:u'\u03c7', 0x1d7a7:u'\u03c8',
+0x1d7a8:u'\u03c9', 0x1d7bb:u'\u03c3', }
+
+def map_table_b3(code):
+    r = b3_exceptions.get(ord(code))
+    if r is not None: return r
+    return code.lower()
+
+
+def map_table_b2(a):
+    al = map_table_b3(a)
+    b = unicodedata.normalize("NFKC", al)
+    bl = u"".join([map_table_b3(ch) for ch in b])
+    c = unicodedata.normalize("NFKC", bl)
+    if b != c:
+        return c
+    else:
+        return al
+
+
+def in_table_c11(code):
+    return code == u" "
+
+
+def in_table_c12(code):
+    return unicodedata.category(code) == "Zs" and code != u" "
+
+def in_table_c11_c12(code):
+    return unicodedata.category(code) == "Zs"
+
+
+def in_table_c21(code):
+    return ord(code) < 128 and unicodedata.category(code) == "Cc"
+
+c22_specials = set([1757, 1807, 6158, 8204, 8205, 8232, 8233, 65279] + range(8288,8292) + range(8298,8304) + range(65529,65533) + range(119155,119163))
+def in_table_c22(code):
+    c = ord(code)
+    if c < 128: return False
+    if unicodedata.category(code) == "Cc": return True
+    return c in c22_specials
+
+def in_table_c21_c22(code):
+    return unicodedata.category(code) == "Cc" or \
+           ord(code) in c22_specials
+
+
+def in_table_c3(code):
+    return unicodedata.category(code) == "Co"
+
+
+def in_table_c4(code):
+    c = ord(code)
+    if c < 0xFDD0: return False
+    if c < 0xFDF0: return True
+    return (ord(code) & 0xFFFF) in (0xFFFE, 0xFFFF)
+
+
+def in_table_c5(code):
+    return unicodedata.category(code) == "Cs"
+
+
+c6_set = set(range(65529,65534))
+def in_table_c6(code):
+    return ord(code) in c6_set
+
+
+c7_set = set(range(12272,12284))
+def in_table_c7(code):
+    return ord(code) in c7_set
+
+
+c8_set = set([832, 833, 8206, 8207] + range(8234,8239) + range(8298,8304))
+def in_table_c8(code):
+    return ord(code) in c8_set
+
+
+c9_set = set([917505] + range(917536,917632))
+def in_table_c9(code):
+    return ord(code) in c9_set
+
+
+def in_table_d1(code):
+    return unicodedata.bidirectional(code) in ("R","AL")
+
+
+def in_table_d2(code):
+    return unicodedata.bidirectional(code) == "L"

Added: vendor/Python/current/Lib/struct.py
===================================================================
--- vendor/Python/current/Lib/struct.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/struct.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,99 @@
+"""
+Functions to convert between Python values and C structs.
+Python strings are used to hold the data representing the C struct
+and also as format strings to describe the layout of data in the C struct.
+
+The optional first format char indicates byte order, size and alignment:
+ @: native order, size & alignment (default)
+ =: native order, std. size & alignment
+ <: little-endian, std. size & alignment
+ >: big-endian, std. size & alignment
+ !: same as >
+
+The remaining chars indicate types of args and must match exactly;
+these can be preceded by a decimal repeat count:
+ x: pad byte (no data); c:char; b:signed byte; B:unsigned byte;
+ h:short; H:unsigned short; i:int; I:unsigned int;
+ l:long; L:unsigned long; f:float; d:double.
+Special cases (preceding decimal count indicates length):
+ s:string (array of char); p: pascal string (with count byte).
+Special case (only available in native format):
+ P:an integer type that is wide enough to hold a pointer.
+Special case (not in native mode unless 'long long' in platform C):
+ q:long long; Q:unsigned long long
+Whitespace between formats is ignored.
+
+The variable struct.error is an exception raised on errors.
+"""
+__version__ = '0.1'
+
+from _struct import Struct, error
+
+_MAXCACHE = 100
+_cache = {}
+
+def _compile(fmt):
+    # Internal: compile struct pattern
+    if len(_cache) >= _MAXCACHE:
+        _cache.clear()
+    s = Struct(fmt)
+    _cache[fmt] = s
+    return s
+
+def calcsize(fmt):
+    """
+    Return size of C struct described by format string fmt.
+    See struct.__doc__ for more on format strings.
+    """
+    try:
+        o = _cache[fmt]
+    except KeyError:
+        o = _compile(fmt)
+    return o.size
+
+def pack(fmt, *args):
+    """
+    Return string containing values v1, v2, ... packed according to fmt.
+    See struct.__doc__ for more on format strings.
+    """
+    try:
+        o = _cache[fmt]
+    except KeyError:
+        o = _compile(fmt)
+    return o.pack(*args)
+
+def pack_into(fmt, buf, offset, *args):
+    """
+    Pack the values v1, v2, ... according to fmt, write
+    the packed bytes into the writable buffer buf starting at offset.
+    See struct.__doc__ for more on format strings.
+    """
+    try:
+        o = _cache[fmt]
+    except KeyError:
+        o = _compile(fmt)
+    return o.pack_into(buf, offset, *args)
+
+def unpack(fmt, s):
+    """
+    Unpack the string, containing packed C structure data, according
+    to fmt.  Requires len(string)==calcsize(fmt).
+    See struct.__doc__ for more on format strings.
+    """
+    try:
+        o = _cache[fmt]
+    except KeyError:
+        o = _compile(fmt)
+    return o.unpack(s)
+
+def unpack_from(fmt, buf, offset=0):
+    """
+    Unpack the buffer, containing packed C structure data, according to
+    fmt starting at offset. Requires len(buffer[offset:]) >= calcsize(fmt).
+    See struct.__doc__ for more on format strings.
+    """
+    try:
+        o = _cache[fmt]
+    except KeyError:
+        o = _compile(fmt)
+    return o.unpack_from(buf, offset)

Added: vendor/Python/current/Lib/subprocess.py
===================================================================
--- vendor/Python/current/Lib/subprocess.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/subprocess.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1246 @@
+# subprocess - Subprocesses with accessible I/O streams
+#
+# For more information about this module, see PEP 324.
+#
+# This module should remain compatible with Python 2.2, see PEP 291.
+#
+# Copyright (c) 2003-2005 by Peter Astrand <astrand at lysator.liu.se>
+#
+# Licensed to PSF under a Contributor Agreement.
+# See http://www.python.org/2.4/license for licensing details.
+
+r"""subprocess - Subprocesses with accessible I/O streams
+
+This module allows you to spawn processes, connect to their
+input/output/error pipes, and obtain their return codes.  This module
+intends to replace several other, older modules and functions, like:
+
+os.system
+os.spawn*
+os.popen*
+popen2.*
+commands.*
+
+Information about how the subprocess module can be used to replace these
+modules and functions can be found below.
+
+
+
+Using the subprocess module
+===========================
+This module defines one class called Popen:
+
+class Popen(args, bufsize=0, executable=None,
+            stdin=None, stdout=None, stderr=None,
+            preexec_fn=None, close_fds=False, shell=False,
+            cwd=None, env=None, universal_newlines=False,
+            startupinfo=None, creationflags=0):
+
+
+Arguments are:
+
+args should be a string, or a sequence of program arguments.  The
+program to execute is normally the first item in the args sequence or
+string, but can be explicitly set by using the executable argument.
+
+On UNIX, with shell=False (default): In this case, the Popen class
+uses os.execvp() to execute the child program.  args should normally
+be a sequence.  A string will be treated as a sequence with the string
+as the only item (the program to execute).
+
+On UNIX, with shell=True: If args is a string, it specifies the
+command string to execute through the shell.  If args is a sequence,
+the first item specifies the command string, and any additional items
+will be treated as additional shell arguments.
+
+On Windows: the Popen class uses CreateProcess() to execute the child
+program, which operates on strings.  If args is a sequence, it will be
+converted to a string using the list2cmdline method.  Please note that
+not all MS Windows applications interpret the command line the same
+way: The list2cmdline is designed for applications using the same
+rules as the MS C runtime.
+
+bufsize, if given, has the same meaning as the corresponding argument
+to the built-in open() function: 0 means unbuffered, 1 means line
+buffered, any other positive value means use a buffer of
+(approximately) that size.  A negative bufsize means to use the system
+default, which usually means fully buffered.  The default value for
+bufsize is 0 (unbuffered).
+
+stdin, stdout and stderr specify the executed programs' standard
+input, standard output and standard error file handles, respectively.
+Valid values are PIPE, an existing file descriptor (a positive
+integer), an existing file object, and None.  PIPE indicates that a
+new pipe to the child should be created.  With None, no redirection
+will occur; the child's file handles will be inherited from the
+parent.  Additionally, stderr can be STDOUT, which indicates that the
+stderr data from the applications should be captured into the same
+file handle as for stdout.
+
+If preexec_fn is set to a callable object, this object will be called
+in the child process just before the child is executed.
+
+If close_fds is true, all file descriptors except 0, 1 and 2 will be
+closed before the child process is executed.
+
+if shell is true, the specified command will be executed through the
+shell.
+
+If cwd is not None, the current directory will be changed to cwd
+before the child is executed.
+
+If env is not None, it defines the environment variables for the new
+process.
+
+If universal_newlines is true, the file objects stdout and stderr are
+opened as a text files, but lines may be terminated by any of '\n',
+the Unix end-of-line convention, '\r', the Macintosh convention or
+'\r\n', the Windows convention.  All of these external representations
+are seen as '\n' by the Python program.  Note: This feature is only
+available if Python is built with universal newline support (the
+default).  Also, the newlines attribute of the file objects stdout,
+stdin and stderr are not updated by the communicate() method.
+
+The startupinfo and creationflags, if given, will be passed to the
+underlying CreateProcess() function.  They can specify things such as
+appearance of the main window and priority for the new process.
+(Windows only)
+
+
+This module also defines two shortcut functions:
+
+call(*popenargs, **kwargs):
+    Run command with arguments.  Wait for command to complete, then
+    return the returncode attribute.
+
+    The arguments are the same as for the Popen constructor.  Example:
+
+    retcode = call(["ls", "-l"])
+
+check_call(*popenargs, **kwargs):
+    Run command with arguments.  Wait for command to complete.  If the
+    exit code was zero then return, otherwise raise
+    CalledProcessError.  The CalledProcessError object will have the
+    return code in the returncode attribute.
+
+    The arguments are the same as for the Popen constructor.  Example:
+
+    check_call(["ls", "-l"])
+
+Exceptions
+----------
+Exceptions raised in the child process, before the new program has
+started to execute, will be re-raised in the parent.  Additionally,
+the exception object will have one extra attribute called
+'child_traceback', which is a string containing traceback information
+from the childs point of view.
+
+The most common exception raised is OSError.  This occurs, for
+example, when trying to execute a non-existent file.  Applications
+should prepare for OSErrors.
+
+A ValueError will be raised if Popen is called with invalid arguments.
+
+check_call() will raise CalledProcessError, if the called process
+returns a non-zero return code.
+
+
+Security
+--------
+Unlike some other popen functions, this implementation will never call
+/bin/sh implicitly.  This means that all characters, including shell
+metacharacters, can safely be passed to child processes.
+
+
+Popen objects
+=============
+Instances of the Popen class have the following methods:
+
+poll()
+    Check if child process has terminated.  Returns returncode
+    attribute.
+
+wait()
+    Wait for child process to terminate.  Returns returncode attribute.
+
+communicate(input=None)
+    Interact with process: Send data to stdin.  Read data from stdout
+    and stderr, until end-of-file is reached.  Wait for process to
+    terminate.  The optional input argument should be a string to be
+    sent to the child process, or None, if no data should be sent to
+    the child.
+
+    communicate() returns a tuple (stdout, stderr).
+
+    Note: The data read is buffered in memory, so do not use this
+    method if the data size is large or unlimited.
+
+The following attributes are also available:
+
+stdin
+    If the stdin argument is PIPE, this attribute is a file object
+    that provides input to the child process.  Otherwise, it is None.
+
+stdout
+    If the stdout argument is PIPE, this attribute is a file object
+    that provides output from the child process.  Otherwise, it is
+    None.
+
+stderr
+    If the stderr argument is PIPE, this attribute is file object that
+    provides error output from the child process.  Otherwise, it is
+    None.
+
+pid
+    The process ID of the child process.
+
+returncode
+    The child return code.  A None value indicates that the process
+    hasn't terminated yet.  A negative value -N indicates that the
+    child was terminated by signal N (UNIX only).
+
+
+Replacing older functions with the subprocess module
+====================================================
+In this section, "a ==> b" means that b can be used as a replacement
+for a.
+
+Note: All functions in this section fail (more or less) silently if
+the executed program cannot be found; this module raises an OSError
+exception.
+
+In the following examples, we assume that the subprocess module is
+imported with "from subprocess import *".
+
+
+Replacing /bin/sh shell backquote
+---------------------------------
+output=`mycmd myarg`
+==>
+output = Popen(["mycmd", "myarg"], stdout=PIPE).communicate()[0]
+
+
+Replacing shell pipe line
+-------------------------
+output=`dmesg | grep hda`
+==>
+p1 = Popen(["dmesg"], stdout=PIPE)
+p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
+output = p2.communicate()[0]
+
+
+Replacing os.system()
+---------------------
+sts = os.system("mycmd" + " myarg")
+==>
+p = Popen("mycmd" + " myarg", shell=True)
+pid, sts = os.waitpid(p.pid, 0)
+
+Note:
+
+* Calling the program through the shell is usually not required.
+
+* It's easier to look at the returncode attribute than the
+  exitstatus.
+
+A more real-world example would look like this:
+
+try:
+    retcode = call("mycmd" + " myarg", shell=True)
+    if retcode < 0:
+        print >>sys.stderr, "Child was terminated by signal", -retcode
+    else:
+        print >>sys.stderr, "Child returned", retcode
+except OSError, e:
+    print >>sys.stderr, "Execution failed:", e
+
+
+Replacing os.spawn*
+-------------------
+P_NOWAIT example:
+
+pid = os.spawnlp(os.P_NOWAIT, "/bin/mycmd", "mycmd", "myarg")
+==>
+pid = Popen(["/bin/mycmd", "myarg"]).pid
+
+
+P_WAIT example:
+
+retcode = os.spawnlp(os.P_WAIT, "/bin/mycmd", "mycmd", "myarg")
+==>
+retcode = call(["/bin/mycmd", "myarg"])
+
+
+Vector example:
+
+os.spawnvp(os.P_NOWAIT, path, args)
+==>
+Popen([path] + args[1:])
+
+
+Environment example:
+
+os.spawnlpe(os.P_NOWAIT, "/bin/mycmd", "mycmd", "myarg", env)
+==>
+Popen(["/bin/mycmd", "myarg"], env={"PATH": "/usr/bin"})
+
+
+Replacing os.popen*
+-------------------
+pipe = os.popen(cmd, mode='r', bufsize)
+==>
+pipe = Popen(cmd, shell=True, bufsize=bufsize, stdout=PIPE).stdout
+
+pipe = os.popen(cmd, mode='w', bufsize)
+==>
+pipe = Popen(cmd, shell=True, bufsize=bufsize, stdin=PIPE).stdin
+
+
+(child_stdin, child_stdout) = os.popen2(cmd, mode, bufsize)
+==>
+p = Popen(cmd, shell=True, bufsize=bufsize,
+          stdin=PIPE, stdout=PIPE, close_fds=True)
+(child_stdin, child_stdout) = (p.stdin, p.stdout)
+
+
+(child_stdin,
+ child_stdout,
+ child_stderr) = os.popen3(cmd, mode, bufsize)
+==>
+p = Popen(cmd, shell=True, bufsize=bufsize,
+          stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True)
+(child_stdin,
+ child_stdout,
+ child_stderr) = (p.stdin, p.stdout, p.stderr)
+
+
+(child_stdin, child_stdout_and_stderr) = os.popen4(cmd, mode, bufsize)
+==>
+p = Popen(cmd, shell=True, bufsize=bufsize,
+          stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True)
+(child_stdin, child_stdout_and_stderr) = (p.stdin, p.stdout)
+
+
+Replacing popen2.*
+------------------
+Note: If the cmd argument to popen2 functions is a string, the command
+is executed through /bin/sh.  If it is a list, the command is directly
+executed.
+
+(child_stdout, child_stdin) = popen2.popen2("somestring", bufsize, mode)
+==>
+p = Popen(["somestring"], shell=True, bufsize=bufsize
+          stdin=PIPE, stdout=PIPE, close_fds=True)
+(child_stdout, child_stdin) = (p.stdout, p.stdin)
+
+
+(child_stdout, child_stdin) = popen2.popen2(["mycmd", "myarg"], bufsize, mode)
+==>
+p = Popen(["mycmd", "myarg"], bufsize=bufsize,
+          stdin=PIPE, stdout=PIPE, close_fds=True)
+(child_stdout, child_stdin) = (p.stdout, p.stdin)
+
+The popen2.Popen3 and popen3.Popen4 basically works as subprocess.Popen,
+except that:
+
+* subprocess.Popen raises an exception if the execution fails
+* the capturestderr argument is replaced with the stderr argument.
+* stdin=PIPE and stdout=PIPE must be specified.
+* popen2 closes all filedescriptors by default, but you have to specify
+  close_fds=True with subprocess.Popen.
+
+
+"""
+
+import sys
+mswindows = (sys.platform == "win32")
+
+import os
+import types
+import traceback
+
+# Exception classes used by this module.
+class CalledProcessError(Exception):
+    """This exception is raised when a process run by check_call() returns
+    a non-zero exit status.  The exit status will be stored in the
+    returncode attribute."""
+    def __init__(self, returncode, cmd):
+        self.returncode = returncode
+        self.cmd = cmd
+    def __str__(self):
+        return "Command '%s' returned non-zero exit status %d" % (self.cmd, self.returncode)
+
+
+if mswindows:
+    import threading
+    import msvcrt
+    if 0: # <-- change this to use pywin32 instead of the _subprocess driver
+        import pywintypes
+        from win32api import GetStdHandle, STD_INPUT_HANDLE, \
+                             STD_OUTPUT_HANDLE, STD_ERROR_HANDLE
+        from win32api import GetCurrentProcess, DuplicateHandle, \
+                             GetModuleFileName, GetVersion
+        from win32con import DUPLICATE_SAME_ACCESS, SW_HIDE
+        from win32pipe import CreatePipe
+        from win32process import CreateProcess, STARTUPINFO, \
+                                 GetExitCodeProcess, STARTF_USESTDHANDLES, \
+                                 STARTF_USESHOWWINDOW, CREATE_NEW_CONSOLE
+        from win32event import WaitForSingleObject, INFINITE, WAIT_OBJECT_0
+    else:
+        from _subprocess import *
+        class STARTUPINFO:
+            dwFlags = 0
+            hStdInput = None
+            hStdOutput = None
+            hStdError = None
+            wShowWindow = 0
+        class pywintypes:
+            error = IOError
+else:
+    import select
+    import errno
+    import fcntl
+    import pickle
+
+__all__ = ["Popen", "PIPE", "STDOUT", "call", "check_call", "CalledProcessError"]
+
+try:
+    MAXFD = os.sysconf("SC_OPEN_MAX")
+except:
+    MAXFD = 256
+
+# True/False does not exist on 2.2.0
+try:
+    False
+except NameError:
+    False = 0
+    True = 1
+
+_active = []
+
+def _cleanup():
+    for inst in _active[:]:
+        if inst.poll(_deadstate=sys.maxint) >= 0:
+            try:
+                _active.remove(inst)
+            except ValueError:
+                # This can happen if two threads create a new Popen instance.
+                # It's harmless that it was already removed, so ignore.
+                pass
+
+PIPE = -1
+STDOUT = -2
+
+
+def call(*popenargs, **kwargs):
+    """Run command with arguments.  Wait for command to complete, then
+    return the returncode attribute.
+
+    The arguments are the same as for the Popen constructor.  Example:
+
+    retcode = call(["ls", "-l"])
+    """
+    return Popen(*popenargs, **kwargs).wait()
+
+
+def check_call(*popenargs, **kwargs):
+    """Run command with arguments.  Wait for command to complete.  If
+    the exit code was zero then return, otherwise raise
+    CalledProcessError.  The CalledProcessError object will have the
+    return code in the returncode attribute.
+
+    The arguments are the same as for the Popen constructor.  Example:
+
+    check_call(["ls", "-l"])
+    """
+    retcode = call(*popenargs, **kwargs)
+    cmd = kwargs.get("args")
+    if cmd is None:
+        cmd = popenargs[0]
+    if retcode:
+        raise CalledProcessError(retcode, cmd)
+    return retcode
+
+
+def list2cmdline(seq):
+    """
+    Translate a sequence of arguments into a command line
+    string, using the same rules as the MS C runtime:
+
+    1) Arguments are delimited by white space, which is either a
+       space or a tab.
+
+    2) A string surrounded by double quotation marks is
+       interpreted as a single argument, regardless of white space
+       contained within.  A quoted string can be embedded in an
+       argument.
+
+    3) A double quotation mark preceded by a backslash is
+       interpreted as a literal double quotation mark.
+
+    4) Backslashes are interpreted literally, unless they
+       immediately precede a double quotation mark.
+
+    5) If backslashes immediately precede a double quotation mark,
+       every pair of backslashes is interpreted as a literal
+       backslash.  If the number of backslashes is odd, the last
+       backslash escapes the next double quotation mark as
+       described in rule 3.
+    """
+
+    # See
+    # http://msdn.microsoft.com/library/en-us/vccelng/htm/progs_12.asp
+    result = []
+    needquote = False
+    for arg in seq:
+        bs_buf = []
+
+        # Add a space to separate this argument from the others
+        if result:
+            result.append(' ')
+
+        needquote = (" " in arg) or ("\t" in arg) or arg == ""
+        if needquote:
+            result.append('"')
+
+        for c in arg:
+            if c == '\\':
+                # Don't know if we need to double yet.
+                bs_buf.append(c)
+            elif c == '"':
+                # Double backspaces.
+                result.append('\\' * len(bs_buf)*2)
+                bs_buf = []
+                result.append('\\"')
+            else:
+                # Normal char
+                if bs_buf:
+                    result.extend(bs_buf)
+                    bs_buf = []
+                result.append(c)
+
+        # Add remaining backspaces, if any.
+        if bs_buf:
+            result.extend(bs_buf)
+
+        if needquote:
+            result.extend(bs_buf)
+            result.append('"')
+
+    return ''.join(result)
+
+
+class Popen(object):
+    def __init__(self, args, bufsize=0, executable=None,
+                 stdin=None, stdout=None, stderr=None,
+                 preexec_fn=None, close_fds=False, shell=False,
+                 cwd=None, env=None, universal_newlines=False,
+                 startupinfo=None, creationflags=0):
+        """Create new Popen instance."""
+        _cleanup()
+
+        self._child_created = False
+        if not isinstance(bufsize, (int, long)):
+            raise TypeError("bufsize must be an integer")
+
+        if mswindows:
+            if preexec_fn is not None:
+                raise ValueError("preexec_fn is not supported on Windows "
+                                 "platforms")
+            if close_fds:
+                raise ValueError("close_fds is not supported on Windows "
+                                 "platforms")
+        else:
+            # POSIX
+            if startupinfo is not None:
+                raise ValueError("startupinfo is only supported on Windows "
+                                 "platforms")
+            if creationflags != 0:
+                raise ValueError("creationflags is only supported on Windows "
+                                 "platforms")
+
+        self.stdin = None
+        self.stdout = None
+        self.stderr = None
+        self.pid = None
+        self.returncode = None
+        self.universal_newlines = universal_newlines
+
+        # Input and output objects. The general principle is like
+        # this:
+        #
+        # Parent                   Child
+        # ------                   -----
+        # p2cwrite   ---stdin--->  p2cread
+        # c2pread    <--stdout---  c2pwrite
+        # errread    <--stderr---  errwrite
+        #
+        # On POSIX, the child objects are file descriptors.  On
+        # Windows, these are Windows file handles.  The parent objects
+        # are file descriptors on both platforms.  The parent objects
+        # are None when not using PIPEs. The child objects are None
+        # when not redirecting.
+
+        (p2cread, p2cwrite,
+         c2pread, c2pwrite,
+         errread, errwrite) = self._get_handles(stdin, stdout, stderr)
+
+        self._execute_child(args, executable, preexec_fn, close_fds,
+                            cwd, env, universal_newlines,
+                            startupinfo, creationflags, shell,
+                            p2cread, p2cwrite,
+                            c2pread, c2pwrite,
+                            errread, errwrite)
+
+        # On Windows, you cannot just redirect one or two handles: You
+        # either have to redirect all three or none. If the subprocess
+        # user has only redirected one or two handles, we are
+        # automatically creating PIPEs for the rest. We should close
+        # these after the process is started. See bug #1124861. 
+        if mswindows:
+            if stdin is None and p2cwrite is not None:
+                os.close(p2cwrite)
+                p2cwrite = None
+            if stdout is None and c2pread is not None:
+                os.close(c2pread)
+                c2pread = None
+            if stderr is None and errread is not None:
+                os.close(errread)
+                errread = None
+
+        if p2cwrite:
+            self.stdin = os.fdopen(p2cwrite, 'wb', bufsize)
+        if c2pread:
+            if universal_newlines:
+                self.stdout = os.fdopen(c2pread, 'rU', bufsize)
+            else:
+                self.stdout = os.fdopen(c2pread, 'rb', bufsize)
+        if errread:
+            if universal_newlines:
+                self.stderr = os.fdopen(errread, 'rU', bufsize)
+            else:
+                self.stderr = os.fdopen(errread, 'rb', bufsize)
+
+
+    def _translate_newlines(self, data):
+        data = data.replace("\r\n", "\n")
+        data = data.replace("\r", "\n")
+        return data
+
+
+    def __del__(self):
+        if not self._child_created:
+            # We didn't get to successfully create a child process.
+            return
+        # In case the child hasn't been waited on, check if it's done.
+        self.poll(_deadstate=sys.maxint)
+        if self.returncode is None and _active is not None:
+            # Child is still running, keep us alive until we can wait on it.
+            _active.append(self)
+
+
+    def communicate(self, input=None):
+        """Interact with process: Send data to stdin.  Read data from
+        stdout and stderr, until end-of-file is reached.  Wait for
+        process to terminate.  The optional input argument should be a
+        string to be sent to the child process, or None, if no data
+        should be sent to the child.
+
+        communicate() returns a tuple (stdout, stderr)."""
+
+        # Optimization: If we are only using one pipe, or no pipe at
+        # all, using select() or threads is unnecessary.
+        if [self.stdin, self.stdout, self.stderr].count(None) >= 2:
+            stdout = None
+            stderr = None
+            if self.stdin:
+                if input:
+                    self.stdin.write(input)
+                self.stdin.close()
+            elif self.stdout:
+                stdout = self.stdout.read()
+            elif self.stderr:
+                stderr = self.stderr.read()
+            self.wait()
+            return (stdout, stderr)
+
+        return self._communicate(input)
+
+
+    if mswindows:
+        #
+        # Windows methods
+        #
+        def _get_handles(self, stdin, stdout, stderr):
+            """Construct and return tupel with IO objects:
+            p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite
+            """
+            if stdin is None and stdout is None and stderr is None:
+                return (None, None, None, None, None, None)
+
+            p2cread, p2cwrite = None, None
+            c2pread, c2pwrite = None, None
+            errread, errwrite = None, None
+
+            if stdin is None:
+                p2cread = GetStdHandle(STD_INPUT_HANDLE)
+            if p2cread is not None:
+                pass
+            elif stdin is None or stdin == PIPE:
+                p2cread, p2cwrite = CreatePipe(None, 0)
+                # Detach and turn into fd
+                p2cwrite = p2cwrite.Detach()
+                p2cwrite = msvcrt.open_osfhandle(p2cwrite, 0)
+            elif isinstance(stdin, int):
+                p2cread = msvcrt.get_osfhandle(stdin)
+            else:
+                # Assuming file-like object
+                p2cread = msvcrt.get_osfhandle(stdin.fileno())
+            p2cread = self._make_inheritable(p2cread)
+
+            if stdout is None:
+                c2pwrite = GetStdHandle(STD_OUTPUT_HANDLE)
+            if c2pwrite is not None:
+                pass
+            elif stdout is None or stdout == PIPE:
+                c2pread, c2pwrite = CreatePipe(None, 0)
+                # Detach and turn into fd
+                c2pread = c2pread.Detach()
+                c2pread = msvcrt.open_osfhandle(c2pread, 0)
+            elif isinstance(stdout, int):
+                c2pwrite = msvcrt.get_osfhandle(stdout)
+            else:
+                # Assuming file-like object
+                c2pwrite = msvcrt.get_osfhandle(stdout.fileno())
+            c2pwrite = self._make_inheritable(c2pwrite)
+
+            if stderr is None:
+                errwrite = GetStdHandle(STD_ERROR_HANDLE)
+            if errwrite is not None:
+                pass
+            elif stderr is None or stderr == PIPE:
+                errread, errwrite = CreatePipe(None, 0)
+                # Detach and turn into fd
+                errread = errread.Detach()
+                errread = msvcrt.open_osfhandle(errread, 0)
+            elif stderr == STDOUT:
+                errwrite = c2pwrite
+            elif isinstance(stderr, int):
+                errwrite = msvcrt.get_osfhandle(stderr)
+            else:
+                # Assuming file-like object
+                errwrite = msvcrt.get_osfhandle(stderr.fileno())
+            errwrite = self._make_inheritable(errwrite)
+
+            return (p2cread, p2cwrite,
+                    c2pread, c2pwrite,
+                    errread, errwrite)
+
+
+        def _make_inheritable(self, handle):
+            """Return a duplicate of handle, which is inheritable"""
+            return DuplicateHandle(GetCurrentProcess(), handle,
+                                   GetCurrentProcess(), 0, 1,
+                                   DUPLICATE_SAME_ACCESS)
+
+
+        def _find_w9xpopen(self):
+            """Find and return absolut path to w9xpopen.exe"""
+            w9xpopen = os.path.join(os.path.dirname(GetModuleFileName(0)),
+                                    "w9xpopen.exe")
+            if not os.path.exists(w9xpopen):
+                # Eeek - file-not-found - possibly an embedding
+                # situation - see if we can locate it in sys.exec_prefix
+                w9xpopen = os.path.join(os.path.dirname(sys.exec_prefix),
+                                        "w9xpopen.exe")
+                if not os.path.exists(w9xpopen):
+                    raise RuntimeError("Cannot locate w9xpopen.exe, which is "
+                                       "needed for Popen to work with your "
+                                       "shell or platform.")
+            return w9xpopen
+
+
+        def _execute_child(self, args, executable, preexec_fn, close_fds,
+                           cwd, env, universal_newlines,
+                           startupinfo, creationflags, shell,
+                           p2cread, p2cwrite,
+                           c2pread, c2pwrite,
+                           errread, errwrite):
+            """Execute program (MS Windows version)"""
+
+            if not isinstance(args, types.StringTypes):
+                args = list2cmdline(args)
+
+            # Process startup details
+            if startupinfo is None:
+                startupinfo = STARTUPINFO()
+            if None not in (p2cread, c2pwrite, errwrite):
+                startupinfo.dwFlags |= STARTF_USESTDHANDLES
+                startupinfo.hStdInput = p2cread
+                startupinfo.hStdOutput = c2pwrite
+                startupinfo.hStdError = errwrite
+
+            if shell:
+                startupinfo.dwFlags |= STARTF_USESHOWWINDOW
+                startupinfo.wShowWindow = SW_HIDE
+                comspec = os.environ.get("COMSPEC", "cmd.exe")
+                args = comspec + " /c " + args
+                if (GetVersion() >= 0x80000000L or
+                        os.path.basename(comspec).lower() == "command.com"):
+                    # Win9x, or using command.com on NT. We need to
+                    # use the w9xpopen intermediate program. For more
+                    # information, see KB Q150956
+                    # (http://web.archive.org/web/20011105084002/http://support.microsoft.com/support/kb/articles/Q150/9/56.asp)
+                    w9xpopen = self._find_w9xpopen()
+                    args = '"%s" %s' % (w9xpopen, args)
+                    # Not passing CREATE_NEW_CONSOLE has been known to
+                    # cause random failures on win9x.  Specifically a
+                    # dialog: "Your program accessed mem currently in
+                    # use at xxx" and a hopeful warning about the
+                    # stability of your system.  Cost is Ctrl+C wont
+                    # kill children.
+                    creationflags |= CREATE_NEW_CONSOLE
+
+            # Start the process
+            try:
+                hp, ht, pid, tid = CreateProcess(executable, args,
+                                         # no special security
+                                         None, None,
+                                         # must inherit handles to pass std
+                                         # handles
+                                         1,
+                                         creationflags,
+                                         env,
+                                         cwd,
+                                         startupinfo)
+            except pywintypes.error, e:
+                # Translate pywintypes.error to WindowsError, which is
+                # a subclass of OSError.  FIXME: We should really
+                # translate errno using _sys_errlist (or simliar), but
+                # how can this be done from Python?
+                raise WindowsError(*e.args)
+
+            # Retain the process handle, but close the thread handle
+            self._child_created = True
+            self._handle = hp
+            self.pid = pid
+            ht.Close()
+
+            # Child is launched. Close the parent's copy of those pipe
+            # handles that only the child should have open.  You need
+            # to make sure that no handles to the write end of the
+            # output pipe are maintained in this process or else the
+            # pipe will not close when the child process exits and the
+            # ReadFile will hang.
+            if p2cread is not None:
+                p2cread.Close()
+            if c2pwrite is not None:
+                c2pwrite.Close()
+            if errwrite is not None:
+                errwrite.Close()
+
+
+        def poll(self, _deadstate=None):
+            """Check if child process has terminated.  Returns returncode
+            attribute."""
+            if self.returncode is None:
+                if WaitForSingleObject(self._handle, 0) == WAIT_OBJECT_0:
+                    self.returncode = GetExitCodeProcess(self._handle)
+            return self.returncode
+
+
+        def wait(self):
+            """Wait for child process to terminate.  Returns returncode
+            attribute."""
+            if self.returncode is None:
+                obj = WaitForSingleObject(self._handle, INFINITE)
+                self.returncode = GetExitCodeProcess(self._handle)
+            return self.returncode
+
+
+        def _readerthread(self, fh, buffer):
+            buffer.append(fh.read())
+
+
+        def _communicate(self, input):
+            stdout = None # Return
+            stderr = None # Return
+
+            if self.stdout:
+                stdout = []
+                stdout_thread = threading.Thread(target=self._readerthread,
+                                                 args=(self.stdout, stdout))
+                stdout_thread.setDaemon(True)
+                stdout_thread.start()
+            if self.stderr:
+                stderr = []
+                stderr_thread = threading.Thread(target=self._readerthread,
+                                                 args=(self.stderr, stderr))
+                stderr_thread.setDaemon(True)
+                stderr_thread.start()
+
+            if self.stdin:
+                if input is not None:
+                    self.stdin.write(input)
+                self.stdin.close()
+
+            if self.stdout:
+                stdout_thread.join()
+            if self.stderr:
+                stderr_thread.join()
+
+            # All data exchanged.  Translate lists into strings.
+            if stdout is not None:
+                stdout = stdout[0]
+            if stderr is not None:
+                stderr = stderr[0]
+
+            # Translate newlines, if requested.  We cannot let the file
+            # object do the translation: It is based on stdio, which is
+            # impossible to combine with select (unless forcing no
+            # buffering).
+            if self.universal_newlines and hasattr(file, 'newlines'):
+                if stdout:
+                    stdout = self._translate_newlines(stdout)
+                if stderr:
+                    stderr = self._translate_newlines(stderr)
+
+            self.wait()
+            return (stdout, stderr)
+
+    else:
+        #
+        # POSIX methods
+        #
+        def _get_handles(self, stdin, stdout, stderr):
+            """Construct and return tupel with IO objects:
+            p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite
+            """
+            p2cread, p2cwrite = None, None
+            c2pread, c2pwrite = None, None
+            errread, errwrite = None, None
+
+            if stdin is None:
+                pass
+            elif stdin == PIPE:
+                p2cread, p2cwrite = os.pipe()
+            elif isinstance(stdin, int):
+                p2cread = stdin
+            else:
+                # Assuming file-like object
+                p2cread = stdin.fileno()
+
+            if stdout is None:
+                pass
+            elif stdout == PIPE:
+                c2pread, c2pwrite = os.pipe()
+            elif isinstance(stdout, int):
+                c2pwrite = stdout
+            else:
+                # Assuming file-like object
+                c2pwrite = stdout.fileno()
+
+            if stderr is None:
+                pass
+            elif stderr == PIPE:
+                errread, errwrite = os.pipe()
+            elif stderr == STDOUT:
+                errwrite = c2pwrite
+            elif isinstance(stderr, int):
+                errwrite = stderr
+            else:
+                # Assuming file-like object
+                errwrite = stderr.fileno()
+
+            return (p2cread, p2cwrite,
+                    c2pread, c2pwrite,
+                    errread, errwrite)
+
+
+        def _set_cloexec_flag(self, fd):
+            try:
+                cloexec_flag = fcntl.FD_CLOEXEC
+            except AttributeError:
+                cloexec_flag = 1
+
+            old = fcntl.fcntl(fd, fcntl.F_GETFD)
+            fcntl.fcntl(fd, fcntl.F_SETFD, old | cloexec_flag)
+
+
+        def _close_fds(self, but):
+            for i in xrange(3, MAXFD):
+                if i == but:
+                    continue
+                try:
+                    os.close(i)
+                except:
+                    pass
+
+
+        def _execute_child(self, args, executable, preexec_fn, close_fds,
+                           cwd, env, universal_newlines,
+                           startupinfo, creationflags, shell,
+                           p2cread, p2cwrite,
+                           c2pread, c2pwrite,
+                           errread, errwrite):
+            """Execute program (POSIX version)"""
+
+            if isinstance(args, types.StringTypes):
+                args = [args]
+            else:
+                args = list(args)
+
+            if shell:
+                args = ["/bin/sh", "-c"] + args
+
+            if executable is None:
+                executable = args[0]
+
+            # For transferring possible exec failure from child to parent
+            # The first char specifies the exception type: 0 means
+            # OSError, 1 means some other error.
+            errpipe_read, errpipe_write = os.pipe()
+            self._set_cloexec_flag(errpipe_write)
+
+            self.pid = os.fork()
+            self._child_created = True
+            if self.pid == 0:
+                # Child
+                try:
+                    # Close parent's pipe ends
+                    if p2cwrite:
+                        os.close(p2cwrite)
+                    if c2pread:
+                        os.close(c2pread)
+                    if errread:
+                        os.close(errread)
+                    os.close(errpipe_read)
+
+                    # Dup fds for child
+                    if p2cread:
+                        os.dup2(p2cread, 0)
+                    if c2pwrite:
+                        os.dup2(c2pwrite, 1)
+                    if errwrite:
+                        os.dup2(errwrite, 2)
+
+                    # Close pipe fds.  Make sure we don't close the same
+                    # fd more than once, or standard fds.
+                    if p2cread and p2cread not in (0,):
+                        os.close(p2cread)
+                    if c2pwrite and c2pwrite not in (p2cread, 1):
+                        os.close(c2pwrite)
+                    if errwrite and errwrite not in (p2cread, c2pwrite, 2):
+                        os.close(errwrite)
+
+                    # Close all other fds, if asked for
+                    if close_fds:
+                        self._close_fds(but=errpipe_write)
+
+                    if cwd is not None:
+                        os.chdir(cwd)
+
+                    if preexec_fn:
+                        apply(preexec_fn)
+
+                    if env is None:
+                        os.execvp(executable, args)
+                    else:
+                        os.execvpe(executable, args, env)
+
+                except:
+                    exc_type, exc_value, tb = sys.exc_info()
+                    # Save the traceback and attach it to the exception object
+                    exc_lines = traceback.format_exception(exc_type,
+                                                           exc_value,
+                                                           tb)
+                    exc_value.child_traceback = ''.join(exc_lines)
+                    os.write(errpipe_write, pickle.dumps(exc_value))
+
+                # This exitcode won't be reported to applications, so it
+                # really doesn't matter what we return.
+                os._exit(255)
+
+            # Parent
+            os.close(errpipe_write)
+            if p2cread and p2cwrite:
+                os.close(p2cread)
+            if c2pwrite and c2pread:
+                os.close(c2pwrite)
+            if errwrite and errread:
+                os.close(errwrite)
+
+            # Wait for exec to fail or succeed; possibly raising exception
+            data = os.read(errpipe_read, 1048576) # Exceptions limited to 1 MB
+            os.close(errpipe_read)
+            if data != "":
+                os.waitpid(self.pid, 0)
+                child_exception = pickle.loads(data)
+                raise child_exception
+
+
+        def _handle_exitstatus(self, sts):
+            if os.WIFSIGNALED(sts):
+                self.returncode = -os.WTERMSIG(sts)
+            elif os.WIFEXITED(sts):
+                self.returncode = os.WEXITSTATUS(sts)
+            else:
+                # Should never happen
+                raise RuntimeError("Unknown child exit status!")
+
+
+        def poll(self, _deadstate=None):
+            """Check if child process has terminated.  Returns returncode
+            attribute."""
+            if self.returncode is None:
+                try:
+                    pid, sts = os.waitpid(self.pid, os.WNOHANG)
+                    if pid == self.pid:
+                        self._handle_exitstatus(sts)
+                except os.error:
+                    if _deadstate is not None:
+                        self.returncode = _deadstate
+            return self.returncode
+
+
+        def wait(self):
+            """Wait for child process to terminate.  Returns returncode
+            attribute."""
+            if self.returncode is None:
+                pid, sts = os.waitpid(self.pid, 0)
+                self._handle_exitstatus(sts)
+            return self.returncode
+
+
+        def _communicate(self, input):
+            read_set = []
+            write_set = []
+            stdout = None # Return
+            stderr = None # Return
+
+            if self.stdin:
+                # Flush stdio buffer.  This might block, if the user has
+                # been writing to .stdin in an uncontrolled fashion.
+                self.stdin.flush()
+                if input:
+                    write_set.append(self.stdin)
+                else:
+                    self.stdin.close()
+            if self.stdout:
+                read_set.append(self.stdout)
+                stdout = []
+            if self.stderr:
+                read_set.append(self.stderr)
+                stderr = []
+
+            input_offset = 0
+            while read_set or write_set:
+                rlist, wlist, xlist = select.select(read_set, write_set, [])
+
+                if self.stdin in wlist:
+                    # When select has indicated that the file is writable,
+                    # we can write up to PIPE_BUF bytes without risk
+                    # blocking.  POSIX defines PIPE_BUF >= 512
+                    bytes_written = os.write(self.stdin.fileno(), buffer(input, input_offset, 512))
+                    input_offset += bytes_written 
+                    if input_offset >= len(input):
+                        self.stdin.close()
+                        write_set.remove(self.stdin)
+
+                if self.stdout in rlist:
+                    data = os.read(self.stdout.fileno(), 1024)
+                    if data == "":
+                        self.stdout.close()
+                        read_set.remove(self.stdout)
+                    stdout.append(data)
+
+                if self.stderr in rlist:
+                    data = os.read(self.stderr.fileno(), 1024)
+                    if data == "":
+                        self.stderr.close()
+                        read_set.remove(self.stderr)
+                    stderr.append(data)
+
+            # All data exchanged.  Translate lists into strings.
+            if stdout is not None:
+                stdout = ''.join(stdout)
+            if stderr is not None:
+                stderr = ''.join(stderr)
+
+            # Translate newlines, if requested.  We cannot let the file
+            # object do the translation: It is based on stdio, which is
+            # impossible to combine with select (unless forcing no
+            # buffering).
+            if self.universal_newlines and hasattr(file, 'newlines'):
+                if stdout:
+                    stdout = self._translate_newlines(stdout)
+                if stderr:
+                    stderr = self._translate_newlines(stderr)
+
+            self.wait()
+            return (stdout, stderr)
+
+
+def _demo_posix():
+    #
+    # Example 1: Simple redirection: Get process list
+    #
+    plist = Popen(["ps"], stdout=PIPE).communicate()[0]
+    print "Process list:"
+    print plist
+
+    #
+    # Example 2: Change uid before executing child
+    #
+    if os.getuid() == 0:
+        p = Popen(["id"], preexec_fn=lambda: os.setuid(100))
+        p.wait()
+
+    #
+    # Example 3: Connecting several subprocesses
+    #
+    print "Looking for 'hda'..."
+    p1 = Popen(["dmesg"], stdout=PIPE)
+    p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
+    print repr(p2.communicate()[0])
+
+    #
+    # Example 4: Catch execution error
+    #
+    print
+    print "Trying a weird file..."
+    try:
+        print Popen(["/this/path/does/not/exist"]).communicate()
+    except OSError, e:
+        if e.errno == errno.ENOENT:
+            print "The file didn't exist.  I thought so..."
+            print "Child traceback:"
+            print e.child_traceback
+        else:
+            print "Error", e.errno
+    else:
+        print >>sys.stderr, "Gosh.  No error."
+
+
+def _demo_windows():
+    #
+    # Example 1: Connecting several subprocesses
+    #
+    print "Looking for 'PROMPT' in set output..."
+    p1 = Popen("set", stdout=PIPE, shell=True)
+    p2 = Popen('find "PROMPT"', stdin=p1.stdout, stdout=PIPE)
+    print repr(p2.communicate()[0])
+
+    #
+    # Example 2: Simple execution of program
+    #
+    print "Executing calc..."
+    p = Popen("calc")
+    p.wait()
+
+
+if __name__ == "__main__":
+    if mswindows:
+        _demo_windows()
+    else:
+        _demo_posix()

Added: vendor/Python/current/Lib/sunau.py
===================================================================
--- vendor/Python/current/Lib/sunau.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/sunau.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,474 @@
+"""Stuff to parse Sun and NeXT audio files.
+
+An audio file consists of a header followed by the data.  The structure
+of the header is as follows.
+
+        +---------------+
+        | magic word    |
+        +---------------+
+        | header size   |
+        +---------------+
+        | data size     |
+        +---------------+
+        | encoding      |
+        +---------------+
+        | sample rate   |
+        +---------------+
+        | # of channels |
+        +---------------+
+        | info          |
+        |               |
+        +---------------+
+
+The magic word consists of the 4 characters '.snd'.  Apart from the
+info field, all header fields are 4 bytes in size.  They are all
+32-bit unsigned integers encoded in big-endian byte order.
+
+The header size really gives the start of the data.
+The data size is the physical size of the data.  From the other
+parameters the number of frames can be calculated.
+The encoding gives the way in which audio samples are encoded.
+Possible values are listed below.
+The info field currently consists of an ASCII string giving a
+human-readable description of the audio file.  The info field is
+padded with NUL bytes to the header size.
+
+Usage.
+
+Reading audio files:
+        f = sunau.open(file, 'r')
+where file is either the name of a file or an open file pointer.
+The open file pointer must have methods read(), seek(), and close().
+When the setpos() and rewind() methods are not used, the seek()
+method is not  necessary.
+
+This returns an instance of a class with the following public methods:
+        getnchannels()  -- returns number of audio channels (1 for
+                           mono, 2 for stereo)
+        getsampwidth()  -- returns sample width in bytes
+        getframerate()  -- returns sampling frequency
+        getnframes()    -- returns number of audio frames
+        getcomptype()   -- returns compression type ('NONE' or 'ULAW')
+        getcompname()   -- returns human-readable version of
+                           compression type ('not compressed' matches 'NONE')
+        getparams()     -- returns a tuple consisting of all of the
+                           above in the above order
+        getmarkers()    -- returns None (for compatibility with the
+                           aifc module)
+        getmark(id)     -- raises an error since the mark does not
+                           exist (for compatibility with the aifc module)
+        readframes(n)   -- returns at most n frames of audio
+        rewind()        -- rewind to the beginning of the audio stream
+        setpos(pos)     -- seek to the specified position
+        tell()          -- return the current position
+        close()         -- close the instance (make it unusable)
+The position returned by tell() and the position given to setpos()
+are compatible and have nothing to do with the actual position in the
+file.
+The close() method is called automatically when the class instance
+is destroyed.
+
+Writing audio files:
+        f = sunau.open(file, 'w')
+where file is either the name of a file or an open file pointer.
+The open file pointer must have methods write(), tell(), seek(), and
+close().
+
+This returns an instance of a class with the following public methods:
+        setnchannels(n) -- set the number of channels
+        setsampwidth(n) -- set the sample width
+        setframerate(n) -- set the frame rate
+        setnframes(n)   -- set the number of frames
+        setcomptype(type, name)
+                        -- set the compression type and the
+                           human-readable compression type
+        setparams(tuple)-- set all parameters at once
+        tell()          -- return current position in output file
+        writeframesraw(data)
+                        -- write audio frames without pathing up the
+                           file header
+        writeframes(data)
+                        -- write audio frames and patch up the file header
+        close()         -- patch up the file header and close the
+                           output file
+You should set the parameters before the first writeframesraw or
+writeframes.  The total number of frames does not need to be set,
+but when it is set to the correct value, the header does not have to
+be patched up.
+It is best to first set all parameters, perhaps possibly the
+compression type, and then write audio frames using writeframesraw.
+When all frames have been written, either call writeframes('') or
+close() to patch up the sizes in the header.
+The close() method is called automatically when the class instance
+is destroyed.
+"""
+
+# from <multimedia/audio_filehdr.h>
+AUDIO_FILE_MAGIC = 0x2e736e64
+AUDIO_FILE_ENCODING_MULAW_8 = 1
+AUDIO_FILE_ENCODING_LINEAR_8 = 2
+AUDIO_FILE_ENCODING_LINEAR_16 = 3
+AUDIO_FILE_ENCODING_LINEAR_24 = 4
+AUDIO_FILE_ENCODING_LINEAR_32 = 5
+AUDIO_FILE_ENCODING_FLOAT = 6
+AUDIO_FILE_ENCODING_DOUBLE = 7
+AUDIO_FILE_ENCODING_ADPCM_G721 = 23
+AUDIO_FILE_ENCODING_ADPCM_G722 = 24
+AUDIO_FILE_ENCODING_ADPCM_G723_3 = 25
+AUDIO_FILE_ENCODING_ADPCM_G723_5 = 26
+AUDIO_FILE_ENCODING_ALAW_8 = 27
+
+# from <multimedia/audio_hdr.h>
+AUDIO_UNKNOWN_SIZE = 0xFFFFFFFFL        # ((unsigned)(~0))
+
+_simple_encodings = [AUDIO_FILE_ENCODING_MULAW_8,
+                     AUDIO_FILE_ENCODING_LINEAR_8,
+                     AUDIO_FILE_ENCODING_LINEAR_16,
+                     AUDIO_FILE_ENCODING_LINEAR_24,
+                     AUDIO_FILE_ENCODING_LINEAR_32,
+                     AUDIO_FILE_ENCODING_ALAW_8]
+
+class Error(Exception):
+    pass
+
+def _read_u32(file):
+    x = 0L
+    for i in range(4):
+        byte = file.read(1)
+        if byte == '':
+            raise EOFError
+        x = x*256 + ord(byte)
+    return x
+
+def _write_u32(file, x):
+    data = []
+    for i in range(4):
+        d, m = divmod(x, 256)
+        data.insert(0, m)
+        x = d
+    for i in range(4):
+        file.write(chr(int(data[i])))
+
+class Au_read:
+
+    def __init__(self, f):
+        if type(f) == type(''):
+            import __builtin__
+            f = __builtin__.open(f, 'rb')
+        self.initfp(f)
+
+    def __del__(self):
+        if self._file:
+            self.close()
+
+    def initfp(self, file):
+        self._file = file
+        self._soundpos = 0
+        magic = int(_read_u32(file))
+        if magic != AUDIO_FILE_MAGIC:
+            raise Error, 'bad magic number'
+        self._hdr_size = int(_read_u32(file))
+        if self._hdr_size < 24:
+            raise Error, 'header size too small'
+        if self._hdr_size > 100:
+            raise Error, 'header size ridiculously large'
+        self._data_size = _read_u32(file)
+        if self._data_size != AUDIO_UNKNOWN_SIZE:
+            self._data_size = int(self._data_size)
+        self._encoding = int(_read_u32(file))
+        if self._encoding not in _simple_encodings:
+            raise Error, 'encoding not (yet) supported'
+        if self._encoding in (AUDIO_FILE_ENCODING_MULAW_8,
+                  AUDIO_FILE_ENCODING_ALAW_8):
+            self._sampwidth = 2
+            self._framesize = 1
+        elif self._encoding == AUDIO_FILE_ENCODING_LINEAR_8:
+            self._framesize = self._sampwidth = 1
+        elif self._encoding == AUDIO_FILE_ENCODING_LINEAR_16:
+            self._framesize = self._sampwidth = 2
+        elif self._encoding == AUDIO_FILE_ENCODING_LINEAR_24:
+            self._framesize = self._sampwidth = 3
+        elif self._encoding == AUDIO_FILE_ENCODING_LINEAR_32:
+            self._framesize = self._sampwidth = 4
+        else:
+            raise Error, 'unknown encoding'
+        self._framerate = int(_read_u32(file))
+        self._nchannels = int(_read_u32(file))
+        self._framesize = self._framesize * self._nchannels
+        if self._hdr_size > 24:
+            self._info = file.read(self._hdr_size - 24)
+            for i in range(len(self._info)):
+                if self._info[i] == '\0':
+                    self._info = self._info[:i]
+                    break
+        else:
+            self._info = ''
+
+    def getfp(self):
+        return self._file
+
+    def getnchannels(self):
+        return self._nchannels
+
+    def getsampwidth(self):
+        return self._sampwidth
+
+    def getframerate(self):
+        return self._framerate
+
+    def getnframes(self):
+        if self._data_size == AUDIO_UNKNOWN_SIZE:
+            return AUDIO_UNKNOWN_SIZE
+        if self._encoding in _simple_encodings:
+            return self._data_size / self._framesize
+        return 0                # XXX--must do some arithmetic here
+
+    def getcomptype(self):
+        if self._encoding == AUDIO_FILE_ENCODING_MULAW_8:
+            return 'ULAW'
+        elif self._encoding == AUDIO_FILE_ENCODING_ALAW_8:
+            return 'ALAW'
+        else:
+            return 'NONE'
+
+    def getcompname(self):
+        if self._encoding == AUDIO_FILE_ENCODING_MULAW_8:
+            return 'CCITT G.711 u-law'
+        elif self._encoding == AUDIO_FILE_ENCODING_ALAW_8:
+            return 'CCITT G.711 A-law'
+        else:
+            return 'not compressed'
+
+    def getparams(self):
+        return self.getnchannels(), self.getsampwidth(), \
+                  self.getframerate(), self.getnframes(), \
+                  self.getcomptype(), self.getcompname()
+
+    def getmarkers(self):
+        return None
+
+    def getmark(self, id):
+        raise Error, 'no marks'
+
+    def readframes(self, nframes):
+        if self._encoding in _simple_encodings:
+            if nframes == AUDIO_UNKNOWN_SIZE:
+                data = self._file.read()
+            else:
+                data = self._file.read(nframes * self._framesize * self._nchannels)
+            if self._encoding == AUDIO_FILE_ENCODING_MULAW_8:
+                import audioop
+                data = audioop.ulaw2lin(data, self._sampwidth)
+            return data
+        return None             # XXX--not implemented yet
+
+    def rewind(self):
+        self._soundpos = 0
+        self._file.seek(self._hdr_size)
+
+    def tell(self):
+        return self._soundpos
+
+    def setpos(self, pos):
+        if pos < 0 or pos > self.getnframes():
+            raise Error, 'position not in range'
+        self._file.seek(pos * self._framesize + self._hdr_size)
+        self._soundpos = pos
+
+    def close(self):
+        self._file = None
+
+class Au_write:
+
+    def __init__(self, f):
+        if type(f) == type(''):
+            import __builtin__
+            f = __builtin__.open(f, 'wb')
+        self.initfp(f)
+
+    def __del__(self):
+        if self._file:
+            self.close()
+
+    def initfp(self, file):
+        self._file = file
+        self._framerate = 0
+        self._nchannels = 0
+        self._sampwidth = 0
+        self._framesize = 0
+        self._nframes = AUDIO_UNKNOWN_SIZE
+        self._nframeswritten = 0
+        self._datawritten = 0
+        self._datalength = 0
+        self._info = ''
+        self._comptype = 'ULAW' # default is U-law
+
+    def setnchannels(self, nchannels):
+        if self._nframeswritten:
+            raise Error, 'cannot change parameters after starting to write'
+        if nchannels not in (1, 2, 4):
+            raise Error, 'only 1, 2, or 4 channels supported'
+        self._nchannels = nchannels
+
+    def getnchannels(self):
+        if not self._nchannels:
+            raise Error, 'number of channels not set'
+        return self._nchannels
+
+    def setsampwidth(self, sampwidth):
+        if self._nframeswritten:
+            raise Error, 'cannot change parameters after starting to write'
+        if sampwidth not in (1, 2, 4):
+            raise Error, 'bad sample width'
+        self._sampwidth = sampwidth
+
+    def getsampwidth(self):
+        if not self._framerate:
+            raise Error, 'sample width not specified'
+        return self._sampwidth
+
+    def setframerate(self, framerate):
+        if self._nframeswritten:
+            raise Error, 'cannot change parameters after starting to write'
+        self._framerate = framerate
+
+    def getframerate(self):
+        if not self._framerate:
+            raise Error, 'frame rate not set'
+        return self._framerate
+
+    def setnframes(self, nframes):
+        if self._nframeswritten:
+            raise Error, 'cannot change parameters after starting to write'
+        if nframes < 0:
+            raise Error, '# of frames cannot be negative'
+        self._nframes = nframes
+
+    def getnframes(self):
+        return self._nframeswritten
+
+    def setcomptype(self, type, name):
+        if type in ('NONE', 'ULAW'):
+            self._comptype = type
+        else:
+            raise Error, 'unknown compression type'
+
+    def getcomptype(self):
+        return self._comptype
+
+    def getcompname(self):
+        if self._comptype == 'ULAW':
+            return 'CCITT G.711 u-law'
+        elif self._comptype == 'ALAW':
+            return 'CCITT G.711 A-law'
+        else:
+            return 'not compressed'
+
+    def setparams(self, (nchannels, sampwidth, framerate, nframes, comptype, compname)):
+        self.setnchannels(nchannels)
+        self.setsampwidth(sampwidth)
+        self.setframerate(framerate)
+        self.setnframes(nframes)
+        self.setcomptype(comptype, compname)
+
+    def getparams(self):
+        return self.getnchannels(), self.getsampwidth(), \
+                  self.getframerate(), self.getnframes(), \
+                  self.getcomptype(), self.getcompname()
+
+    def tell(self):
+        return self._nframeswritten
+
+    def writeframesraw(self, data):
+        self._ensure_header_written()
+        nframes = len(data) / self._framesize
+        if self._comptype == 'ULAW':
+            import audioop
+            data = audioop.lin2ulaw(data, self._sampwidth)
+        self._file.write(data)
+        self._nframeswritten = self._nframeswritten + nframes
+        self._datawritten = self._datawritten + len(data)
+
+    def writeframes(self, data):
+        self.writeframesraw(data)
+        if self._nframeswritten != self._nframes or \
+                  self._datalength != self._datawritten:
+            self._patchheader()
+
+    def close(self):
+        self._ensure_header_written()
+        if self._nframeswritten != self._nframes or \
+                  self._datalength != self._datawritten:
+            self._patchheader()
+        self._file.flush()
+        self._file = None
+
+    #
+    # private methods
+    #
+
+    def _ensure_header_written(self):
+        if not self._nframeswritten:
+            if not self._nchannels:
+                raise Error, '# of channels not specified'
+            if not self._sampwidth:
+                raise Error, 'sample width not specified'
+            if not self._framerate:
+                raise Error, 'frame rate not specified'
+            self._write_header()
+
+    def _write_header(self):
+        if self._comptype == 'NONE':
+            if self._sampwidth == 1:
+                encoding = AUDIO_FILE_ENCODING_LINEAR_8
+                self._framesize = 1
+            elif self._sampwidth == 2:
+                encoding = AUDIO_FILE_ENCODING_LINEAR_16
+                self._framesize = 2
+            elif self._sampwidth == 4:
+                encoding = AUDIO_FILE_ENCODING_LINEAR_32
+                self._framesize = 4
+            else:
+                raise Error, 'internal error'
+        elif self._comptype == 'ULAW':
+            encoding = AUDIO_FILE_ENCODING_MULAW_8
+            self._framesize = 1
+        else:
+            raise Error, 'internal error'
+        self._framesize = self._framesize * self._nchannels
+        _write_u32(self._file, AUDIO_FILE_MAGIC)
+        header_size = 25 + len(self._info)
+        header_size = (header_size + 7) & ~7
+        _write_u32(self._file, header_size)
+        if self._nframes == AUDIO_UNKNOWN_SIZE:
+            length = AUDIO_UNKNOWN_SIZE
+        else:
+            length = self._nframes * self._framesize
+        _write_u32(self._file, length)
+        self._datalength = length
+        _write_u32(self._file, encoding)
+        _write_u32(self._file, self._framerate)
+        _write_u32(self._file, self._nchannels)
+        self._file.write(self._info)
+        self._file.write('\0'*(header_size - len(self._info) - 24))
+
+    def _patchheader(self):
+        self._file.seek(8)
+        _write_u32(self._file, self._datawritten)
+        self._datalength = self._datawritten
+        self._file.seek(0, 2)
+
+def open(f, mode=None):
+    if mode is None:
+        if hasattr(f, 'mode'):
+            mode = f.mode
+        else:
+            mode = 'rb'
+    if mode in ('r', 'rb'):
+        return Au_read(f)
+    elif mode in ('w', 'wb'):
+        return Au_write(f)
+    else:
+        raise Error, "mode must be 'r', 'rb', 'w', or 'wb'"
+
+openfp = open

Added: vendor/Python/current/Lib/sunaudio.py
===================================================================
--- vendor/Python/current/Lib/sunaudio.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/sunaudio.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,44 @@
+"""Interpret sun audio headers."""
+
+MAGIC = '.snd'
+
+class error(Exception):
+    pass
+
+
+def get_long_be(s):
+    """Convert a 4-char value to integer."""
+    return (ord(s[0])<<24) | (ord(s[1])<<16) | (ord(s[2])<<8) | ord(s[3])
+
+
+def gethdr(fp):
+    """Read a sound header from an open file."""
+    if fp.read(4) != MAGIC:
+        raise error, 'gethdr: bad magic word'
+    hdr_size = get_long_be(fp.read(4))
+    data_size = get_long_be(fp.read(4))
+    encoding = get_long_be(fp.read(4))
+    sample_rate = get_long_be(fp.read(4))
+    channels = get_long_be(fp.read(4))
+    excess = hdr_size - 24
+    if excess < 0:
+        raise error, 'gethdr: bad hdr_size'
+    if excess > 0:
+        info = fp.read(excess)
+    else:
+        info = ''
+    return (data_size, encoding, sample_rate, channels, info)
+
+
+def printhdr(file):
+    """Read and print the sound header of a named file."""
+    hdr = gethdr(open(file, 'r'))
+    data_size, encoding, sample_rate, channels, info = hdr
+    while info[-1:] == '\0':
+        info = info[:-1]
+    print 'File name:  ', file
+    print 'Data size:  ', data_size
+    print 'Encoding:   ', encoding
+    print 'Sample rate:', sample_rate
+    print 'Channels:   ', channels
+    print 'Info:       ', repr(info)

Added: vendor/Python/current/Lib/symbol.py
===================================================================
--- vendor/Python/current/Lib/symbol.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/symbol.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,113 @@
+#! /usr/bin/env python
+
+"""Non-terminal symbols of Python grammar (from "graminit.h")."""
+
+#  This file is automatically generated; please don't muck it up!
+#
+#  To update the symbols in this file, 'cd' to the top directory of
+#  the python source tree after building the interpreter and run:
+#
+#    python Lib/symbol.py
+
+#--start constants--
+single_input = 256
+file_input = 257
+eval_input = 258
+decorator = 259
+decorators = 260
+funcdef = 261
+parameters = 262
+varargslist = 263
+fpdef = 264
+fplist = 265
+stmt = 266
+simple_stmt = 267
+small_stmt = 268
+expr_stmt = 269
+augassign = 270
+print_stmt = 271
+del_stmt = 272
+pass_stmt = 273
+flow_stmt = 274
+break_stmt = 275
+continue_stmt = 276
+return_stmt = 277
+yield_stmt = 278
+raise_stmt = 279
+import_stmt = 280
+import_name = 281
+import_from = 282
+import_as_name = 283
+dotted_as_name = 284
+import_as_names = 285
+dotted_as_names = 286
+dotted_name = 287
+global_stmt = 288
+exec_stmt = 289
+assert_stmt = 290
+compound_stmt = 291
+if_stmt = 292
+while_stmt = 293
+for_stmt = 294
+try_stmt = 295
+with_stmt = 296
+with_var = 297
+except_clause = 298
+suite = 299
+testlist_safe = 300
+old_test = 301
+old_lambdef = 302
+test = 303
+or_test = 304
+and_test = 305
+not_test = 306
+comparison = 307
+comp_op = 308
+expr = 309
+xor_expr = 310
+and_expr = 311
+shift_expr = 312
+arith_expr = 313
+term = 314
+factor = 315
+power = 316
+atom = 317
+listmaker = 318
+testlist_gexp = 319
+lambdef = 320
+trailer = 321
+subscriptlist = 322
+subscript = 323
+sliceop = 324
+exprlist = 325
+testlist = 326
+dictmaker = 327
+classdef = 328
+arglist = 329
+argument = 330
+list_iter = 331
+list_for = 332
+list_if = 333
+gen_iter = 334
+gen_for = 335
+gen_if = 336
+testlist1 = 337
+encoding_decl = 338
+yield_expr = 339
+#--end constants--
+
+sym_name = {}
+for _name, _value in globals().items():
+    if type(_value) is type(0):
+        sym_name[_value] = _name
+
+
+def main():
+    import sys
+    import token
+    if len(sys.argv) == 1:
+        sys.argv = sys.argv + ["Include/graminit.h", "Lib/symbol.py"]
+    token.main()
+
+if __name__ == "__main__":
+    main()


Property changes on: vendor/Python/current/Lib/symbol.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/symtable.py
===================================================================
--- vendor/Python/current/Lib/symtable.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/symtable.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,252 @@
+"""Interface to the compiler's internal symbol tables"""
+
+import _symtable
+from _symtable import USE, DEF_GLOBAL, DEF_LOCAL, DEF_PARAM, \
+     DEF_STAR, DEF_DOUBLESTAR, DEF_INTUPLE, DEF_FREE, \
+     DEF_FREE_GLOBAL, DEF_FREE_CLASS, DEF_IMPORT, DEF_BOUND, \
+     OPT_IMPORT_STAR, OPT_EXEC, OPT_BARE_EXEC
+
+import weakref
+
+__all__ = ["symtable", "SymbolTable", "newSymbolTable", "Class",
+           "Function", "Symbol"]
+
+def symtable(code, filename, compile_type):
+    raw = _symtable.symtable(code, filename, compile_type)
+    for top in raw.itervalues():
+        if top.name == 'top':
+            break
+    return newSymbolTable(top, filename)
+
+class SymbolTableFactory:
+    def __init__(self):
+        self.__memo = weakref.WeakValueDictionary()
+
+    def new(self, table, filename):
+        if table.type == _symtable.TYPE_FUNCTION:
+            return Function(table, filename)
+        if table.type == _symtable.TYPE_CLASS:
+            return Class(table, filename)
+        return SymbolTable(table, filename)
+
+    def __call__(self, table, filename):
+        key = table, filename
+        obj = self.__memo.get(key, None)
+        if obj is None:
+            obj = self.__memo[key] = self.new(table, filename)
+        return obj
+
+newSymbolTable = SymbolTableFactory()
+
+def is_free(flags):
+    if (flags & (USE | DEF_FREE)) \
+       and (flags & (DEF_LOCAL | DEF_PARAM | DEF_GLOBAL)):
+        return True
+    if flags & DEF_FREE_CLASS:
+        return True
+    return False
+
+class SymbolTable:
+    def __init__(self, raw_table, filename):
+        self._table = raw_table
+        self._filename = filename
+        self._symbols = {}
+
+    def __repr__(self):
+        if self.__class__ == SymbolTable:
+            kind = ""
+        else:
+            kind = "%s " % self.__class__.__name__
+
+        if self._table.name == "global":
+            return "<%sSymbolTable for module %s>" % (kind, self._filename)
+        else:
+            return "<%sSymbolTable for %s in %s>" % (kind, self._table.name,
+                                                     self._filename)
+
+    def get_type(self):
+        if self._table.type == _symtable.TYPE_MODULE:
+            return "module"
+        if self._table.type == _symtable.TYPE_FUNCTION:
+            return "function"
+        if self._table.type == _symtable.TYPE_CLASS:
+            return "class"
+        assert self._table.type in (1, 2, 3), \
+               "unexpected type: %s" % self._table.type
+
+    def get_id(self):
+        return self._table.id
+
+    def get_name(self):
+        return self._table.name
+
+    def get_lineno(self):
+        return self._table.lineno
+
+    def is_optimized(self):
+        return bool(self._table.type == _symtable.TYPE_FUNCTION
+                    and not self._table.optimized)
+
+    def is_nested(self):
+        return bool(self._table.nested)
+
+    def has_children(self):
+        return bool(self._table.children)
+
+    def has_exec(self):
+        """Return true if the scope uses exec"""
+        return bool(self._table.optimized & (OPT_EXEC | OPT_BARE_EXEC))
+
+    def has_import_star(self):
+        """Return true if the scope uses import *"""
+        return bool(self._table.optimized & OPT_IMPORT_STAR)
+
+    def get_identifiers(self):
+        return self._table.symbols.keys()
+
+    def lookup(self, name):
+        sym = self._symbols.get(name)
+        if sym is None:
+            flags = self._table.symbols[name]
+            namespaces = self.__check_children(name)
+            sym = self._symbols[name] = Symbol(name, flags, namespaces)
+        return sym
+
+    def get_symbols(self):
+        return [self.lookup(ident) for ident in self.get_identifiers()]
+
+    def __check_children(self, name):
+        return [newSymbolTable(st, self._filename)
+                for st in self._table.children
+                if st.name == name]
+
+    def get_children(self):
+        return [newSymbolTable(st, self._filename)
+                for st in self._table.children]
+
+class Function(SymbolTable):
+
+    # Default values for instance variables
+    __params = None
+    __locals = None
+    __frees = None
+    __globals = None
+
+    def __idents_matching(self, test_func):
+        return tuple([ident for ident in self.get_identifiers()
+                      if test_func(self._table.symbols[ident])])
+
+    def get_parameters(self):
+        if self.__params is None:
+            self.__params = self.__idents_matching(lambda x:x & DEF_PARAM)
+        return self.__params
+
+    def get_locals(self):
+        if self.__locals is None:
+            self.__locals = self.__idents_matching(lambda x:x & DEF_BOUND)
+        return self.__locals
+
+    def get_globals(self):
+        if self.__globals is None:
+            glob = DEF_GLOBAL | DEF_FREE_GLOBAL
+            self.__globals = self.__idents_matching(lambda x:x & glob)
+        return self.__globals
+
+    def get_frees(self):
+        if self.__frees is None:
+            self.__frees = self.__idents_matching(is_free)
+        return self.__frees
+
+class Class(SymbolTable):
+
+    __methods = None
+
+    def get_methods(self):
+        if self.__methods is None:
+            d = {}
+            for st in self._table.children:
+                d[st.name] = 1
+            self.__methods = tuple(d)
+        return self.__methods
+
+class Symbol:
+    def __init__(self, name, flags, namespaces=None):
+        self.__name = name
+        self.__flags = flags
+        self.__namespaces = namespaces or ()
+
+    def __repr__(self):
+        return "<symbol '%s'>" % self.__name
+
+    def get_name(self):
+        return self.__name
+
+    def is_referenced(self):
+        return bool(self.__flags & _symtable.USE)
+
+    def is_parameter(self):
+        return bool(self.__flags & DEF_PARAM)
+
+    def is_global(self):
+        return bool((self.__flags & DEF_GLOBAL)
+                    or (self.__flags & DEF_FREE_GLOBAL))
+
+    def is_vararg(self):
+        return bool(self.__flags & DEF_STAR)
+
+    def is_keywordarg(self):
+        return bool(self.__flags & DEF_DOUBLESTAR)
+
+    def is_local(self):
+        return bool(self.__flags & DEF_BOUND)
+
+    def is_free(self):
+        if (self.__flags & (USE | DEF_FREE)) \
+            and (self.__flags & (DEF_LOCAL | DEF_PARAM | DEF_GLOBAL)):
+            return True
+        if self.__flags & DEF_FREE_CLASS:
+            return True
+        return False
+
+    def is_imported(self):
+        return bool(self.__flags & DEF_IMPORT)
+
+    def is_assigned(self):
+        return bool(self.__flags & DEF_LOCAL)
+
+    def is_in_tuple(self):
+        return bool(self.__flags & DEF_INTUPLE)
+
+    def is_namespace(self):
+        """Returns true if name binding introduces new namespace.
+
+        If the name is used as the target of a function or class
+        statement, this will be true.
+
+        Note that a single name can be bound to multiple objects.  If
+        is_namespace() is true, the name may also be bound to other
+        objects, like an int or list, that does not introduce a new
+        namespace.
+        """
+        return bool(self.__namespaces)
+
+    def get_namespaces(self):
+        """Return a list of namespaces bound to this name"""
+        return self.__namespaces
+
+    def get_namespace(self):
+        """Returns the single namespace bound to this name.
+
+        Raises ValueError if the name is bound to multiple namespaces.
+        """
+        if len(self.__namespaces) != 1:
+            raise ValueError, "name is bound to multiple namespaces"
+        return self.__namespaces[0]
+
+if __name__ == "__main__":
+    import os, sys
+    src = open(sys.argv[0]).read()
+    mod = symtable(src, os.path.split(sys.argv[0])[1], "exec")
+    for ident in mod.get_identifiers():
+        info = mod.lookup(ident)
+        print info, info.is_local(), info.is_namespace()

Added: vendor/Python/current/Lib/tabnanny.py
===================================================================
--- vendor/Python/current/Lib/tabnanny.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/tabnanny.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,329 @@
+#! /usr/bin/env python
+
+"""The Tab Nanny despises ambiguous indentation.  She knows no mercy.
+
+tabnanny -- Detection of ambiguous indentation
+
+For the time being this module is intended to be called as a script.
+However it is possible to import it into an IDE and use the function
+check() described below.
+
+Warning: The API provided by this module is likely to change in future
+releases; such changes may not be backward compatible.
+"""
+
+# Released to the public domain, by Tim Peters, 15 April 1998.
+
+# XXX Note: this is now a standard library module.
+# XXX The API needs to undergo changes however; the current code is too
+# XXX script-like.  This will be addressed later.
+
+__version__ = "6"
+
+import os
+import sys
+import getopt
+import tokenize
+if not hasattr(tokenize, 'NL'):
+    raise ValueError("tokenize.NL doesn't exist -- tokenize module too old")
+
+__all__ = ["check", "NannyNag", "process_tokens"]
+
+verbose = 0
+filename_only = 0
+
+def errprint(*args):
+    sep = ""
+    for arg in args:
+        sys.stderr.write(sep + str(arg))
+        sep = " "
+    sys.stderr.write("\n")
+
+def main():
+    global verbose, filename_only
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], "qv")
+    except getopt.error, msg:
+        errprint(msg)
+        return
+    for o, a in opts:
+        if o == '-q':
+            filename_only = filename_only + 1
+        if o == '-v':
+            verbose = verbose + 1
+    if not args:
+        errprint("Usage:", sys.argv[0], "[-v] file_or_directory ...")
+        return
+    for arg in args:
+        check(arg)
+
+class NannyNag(Exception):
+    """
+    Raised by tokeneater() if detecting an ambiguous indent.
+    Captured and handled in check().
+    """
+    def __init__(self, lineno, msg, line):
+        self.lineno, self.msg, self.line = lineno, msg, line
+    def get_lineno(self):
+        return self.lineno
+    def get_msg(self):
+        return self.msg
+    def get_line(self):
+        return self.line
+
+def check(file):
+    """check(file_or_dir)
+
+    If file_or_dir is a directory and not a symbolic link, then recursively
+    descend the directory tree named by file_or_dir, checking all .py files
+    along the way. If file_or_dir is an ordinary Python source file, it is
+    checked for whitespace related problems. The diagnostic messages are
+    written to standard output using the print statement.
+    """
+
+    if os.path.isdir(file) and not os.path.islink(file):
+        if verbose:
+            print "%r: listing directory" % (file,)
+        names = os.listdir(file)
+        for name in names:
+            fullname = os.path.join(file, name)
+            if (os.path.isdir(fullname) and
+                not os.path.islink(fullname) or
+                os.path.normcase(name[-3:]) == ".py"):
+                check(fullname)
+        return
+
+    try:
+        f = open(file)
+    except IOError, msg:
+        errprint("%r: I/O Error: %s" % (file, msg))
+        return
+
+    if verbose > 1:
+        print "checking %r ..." % file
+
+    try:
+        process_tokens(tokenize.generate_tokens(f.readline))
+
+    except tokenize.TokenError, msg:
+        errprint("%r: Token Error: %s" % (file, msg))
+        return
+
+    except IndentationError, msg:
+        errprint("%r: Indentation Error: %s" % (file, msg))
+        return
+
+    except NannyNag, nag:
+        badline = nag.get_lineno()
+        line = nag.get_line()
+        if verbose:
+            print "%r: *** Line %d: trouble in tab city! ***" % (file, badline)
+            print "offending line: %r" % (line,)
+            print nag.get_msg()
+        else:
+            if ' ' in file: file = '"' + file + '"'
+            if filename_only: print file
+            else: print file, badline, repr(line)
+        return
+
+    if verbose:
+        print "%r: Clean bill of health." % (file,)
+
+class Whitespace:
+    # the characters used for space and tab
+    S, T = ' \t'
+
+    # members:
+    #   raw
+    #       the original string
+    #   n
+    #       the number of leading whitespace characters in raw
+    #   nt
+    #       the number of tabs in raw[:n]
+    #   norm
+    #       the normal form as a pair (count, trailing), where:
+    #       count
+    #           a tuple such that raw[:n] contains count[i]
+    #           instances of S * i + T
+    #       trailing
+    #           the number of trailing spaces in raw[:n]
+    #       It's A Theorem that m.indent_level(t) ==
+    #       n.indent_level(t) for all t >= 1 iff m.norm == n.norm.
+    #   is_simple
+    #       true iff raw[:n] is of the form (T*)(S*)
+
+    def __init__(self, ws):
+        self.raw  = ws
+        S, T = Whitespace.S, Whitespace.T
+        count = []
+        b = n = nt = 0
+        for ch in self.raw:
+            if ch == S:
+                n = n + 1
+                b = b + 1
+            elif ch == T:
+                n = n + 1
+                nt = nt + 1
+                if b >= len(count):
+                    count = count + [0] * (b - len(count) + 1)
+                count[b] = count[b] + 1
+                b = 0
+            else:
+                break
+        self.n    = n
+        self.nt   = nt
+        self.norm = tuple(count), b
+        self.is_simple = len(count) <= 1
+
+    # return length of longest contiguous run of spaces (whether or not
+    # preceding a tab)
+    def longest_run_of_spaces(self):
+        count, trailing = self.norm
+        return max(len(count)-1, trailing)
+
+    def indent_level(self, tabsize):
+        # count, il = self.norm
+        # for i in range(len(count)):
+        #    if count[i]:
+        #        il = il + (i/tabsize + 1)*tabsize * count[i]
+        # return il
+
+        # quicker:
+        # il = trailing + sum (i/ts + 1)*ts*count[i] =
+        # trailing + ts * sum (i/ts + 1)*count[i] =
+        # trailing + ts * sum i/ts*count[i] + count[i] =
+        # trailing + ts * [(sum i/ts*count[i]) + (sum count[i])] =
+        # trailing + ts * [(sum i/ts*count[i]) + num_tabs]
+        # and note that i/ts*count[i] is 0 when i < ts
+
+        count, trailing = self.norm
+        il = 0
+        for i in range(tabsize, len(count)):
+            il = il + i/tabsize * count[i]
+        return trailing + tabsize * (il + self.nt)
+
+    # return true iff self.indent_level(t) == other.indent_level(t)
+    # for all t >= 1
+    def equal(self, other):
+        return self.norm == other.norm
+
+    # return a list of tuples (ts, i1, i2) such that
+    # i1 == self.indent_level(ts) != other.indent_level(ts) == i2.
+    # Intended to be used after not self.equal(other) is known, in which
+    # case it will return at least one witnessing tab size.
+    def not_equal_witness(self, other):
+        n = max(self.longest_run_of_spaces(),
+                other.longest_run_of_spaces()) + 1
+        a = []
+        for ts in range(1, n+1):
+            if self.indent_level(ts) != other.indent_level(ts):
+                a.append( (ts,
+                           self.indent_level(ts),
+                           other.indent_level(ts)) )
+        return a
+
+    # Return True iff self.indent_level(t) < other.indent_level(t)
+    # for all t >= 1.
+    # The algorithm is due to Vincent Broman.
+    # Easy to prove it's correct.
+    # XXXpost that.
+    # Trivial to prove n is sharp (consider T vs ST).
+    # Unknown whether there's a faster general way.  I suspected so at
+    # first, but no longer.
+    # For the special (but common!) case where M and N are both of the
+    # form (T*)(S*), M.less(N) iff M.len() < N.len() and
+    # M.num_tabs() <= N.num_tabs(). Proof is easy but kinda long-winded.
+    # XXXwrite that up.
+    # Note that M is of the form (T*)(S*) iff len(M.norm[0]) <= 1.
+    def less(self, other):
+        if self.n >= other.n:
+            return False
+        if self.is_simple and other.is_simple:
+            return self.nt <= other.nt
+        n = max(self.longest_run_of_spaces(),
+                other.longest_run_of_spaces()) + 1
+        # the self.n >= other.n test already did it for ts=1
+        for ts in range(2, n+1):
+            if self.indent_level(ts) >= other.indent_level(ts):
+                return False
+        return True
+
+    # return a list of tuples (ts, i1, i2) such that
+    # i1 == self.indent_level(ts) >= other.indent_level(ts) == i2.
+    # Intended to be used after not self.less(other) is known, in which
+    # case it will return at least one witnessing tab size.
+    def not_less_witness(self, other):
+        n = max(self.longest_run_of_spaces(),
+                other.longest_run_of_spaces()) + 1
+        a = []
+        for ts in range(1, n+1):
+            if self.indent_level(ts) >= other.indent_level(ts):
+                a.append( (ts,
+                           self.indent_level(ts),
+                           other.indent_level(ts)) )
+        return a
+
+def format_witnesses(w):
+    firsts = map(lambda tup: str(tup[0]), w)
+    prefix = "at tab size"
+    if len(w) > 1:
+        prefix = prefix + "s"
+    return prefix + " " + ', '.join(firsts)
+
+def process_tokens(tokens):
+    INDENT = tokenize.INDENT
+    DEDENT = tokenize.DEDENT
+    NEWLINE = tokenize.NEWLINE
+    JUNK = tokenize.COMMENT, tokenize.NL
+    indents = [Whitespace("")]
+    check_equal = 0
+
+    for (type, token, start, end, line) in tokens:
+        if type == NEWLINE:
+            # a program statement, or ENDMARKER, will eventually follow,
+            # after some (possibly empty) run of tokens of the form
+            #     (NL | COMMENT)* (INDENT | DEDENT+)?
+            # If an INDENT appears, setting check_equal is wrong, and will
+            # be undone when we see the INDENT.
+            check_equal = 1
+
+        elif type == INDENT:
+            check_equal = 0
+            thisguy = Whitespace(token)
+            if not indents[-1].less(thisguy):
+                witness = indents[-1].not_less_witness(thisguy)
+                msg = "indent not greater e.g. " + format_witnesses(witness)
+                raise NannyNag(start[0], msg, line)
+            indents.append(thisguy)
+
+        elif type == DEDENT:
+            # there's nothing we need to check here!  what's important is
+            # that when the run of DEDENTs ends, the indentation of the
+            # program statement (or ENDMARKER) that triggered the run is
+            # equal to what's left at the top of the indents stack
+
+            # Ouch!  This assert triggers if the last line of the source
+            # is indented *and* lacks a newline -- then DEDENTs pop out
+            # of thin air.
+            # assert check_equal  # else no earlier NEWLINE, or an earlier INDENT
+            check_equal = 1
+
+            del indents[-1]
+
+        elif check_equal and type not in JUNK:
+            # this is the first "real token" following a NEWLINE, so it
+            # must be the first token of the next program statement, or an
+            # ENDMARKER; the "line" argument exposes the leading whitespace
+            # for this statement; in the case of ENDMARKER, line is an empty
+            # string, so will properly match the empty string with which the
+            # "indents" stack was seeded
+            check_equal = 0
+            thisguy = Whitespace(line)
+            if not indents[-1].equal(thisguy):
+                witness = indents[-1].not_equal_witness(thisguy)
+                msg = "indent not equal e.g. " + format_witnesses(witness)
+                raise NannyNag(start[0], msg, line)
+
+
+if __name__ == '__main__':
+    main()


Property changes on: vendor/Python/current/Lib/tabnanny.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/tarfile.py
===================================================================
--- vendor/Python/current/Lib/tarfile.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/tarfile.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2176 @@
+#!/usr/bin/env python
+# -*- coding: iso-8859-1 -*-
+#-------------------------------------------------------------------
+# tarfile.py
+#-------------------------------------------------------------------
+# Copyright (C) 2002 Lars Gustäbel <lars at gustaebel.de>
+# All rights reserved.
+#
+# Permission  is  hereby granted,  free  of charge,  to  any person
+# obtaining a  copy of  this software  and associated documentation
+# files  (the  "Software"),  to   deal  in  the  Software   without
+# restriction,  including  without limitation  the  rights to  use,
+# copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies  of  the  Software,  and to  permit  persons  to  whom the
+# Software  is  furnished  to  do  so,  subject  to  the  following
+# conditions:
+#
+# The above copyright  notice and this  permission notice shall  be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS  IS", WITHOUT WARRANTY OF ANY  KIND,
+# EXPRESS OR IMPLIED, INCLUDING  BUT NOT LIMITED TO  THE WARRANTIES
+# OF  MERCHANTABILITY,  FITNESS   FOR  A  PARTICULAR   PURPOSE  AND
+# NONINFRINGEMENT.  IN  NO  EVENT SHALL  THE  AUTHORS  OR COPYRIGHT
+# HOLDERS  BE LIABLE  FOR ANY  CLAIM, DAMAGES  OR OTHER  LIABILITY,
+# WHETHER  IN AN  ACTION OF  CONTRACT, TORT  OR OTHERWISE,  ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+"""Read from and write to tar format archives.
+"""
+
+__version__ = "$Revision: 53162 $"
+# $Source$
+
+version     = "0.8.0"
+__author__  = "Lars Gustäbel (lars at gustaebel.de)"
+__date__    = "$Date: 2006-12-27 21:36:58 +1100 (Wed, 27 Dec 2006) $"
+__cvsid__   = "$Id: tarfile.py 53162 2006-12-27 10:36:58Z lars.gustaebel $"
+__credits__ = "Gustavo Niemeyer, Niels Gustäbel, Richard Townsend."
+
+#---------
+# Imports
+#---------
+import sys
+import os
+import shutil
+import stat
+import errno
+import time
+import struct
+import copy
+
+if sys.platform == 'mac':
+    # This module needs work for MacOS9, especially in the area of pathname
+    # handling. In many places it is assumed a simple substitution of / by the
+    # local os.path.sep is good enough to convert pathnames, but this does not
+    # work with the mac rooted:path:name versus :nonrooted:path:name syntax
+    raise ImportError, "tarfile does not work for platform==mac"
+
+try:
+    import grp, pwd
+except ImportError:
+    grp = pwd = None
+
+# from tarfile import *
+__all__ = ["TarFile", "TarInfo", "is_tarfile", "TarError"]
+
+#---------------------------------------------------------
+# tar constants
+#---------------------------------------------------------
+NUL        = "\0"               # the null character
+BLOCKSIZE  = 512                # length of processing blocks
+RECORDSIZE = BLOCKSIZE * 20     # length of records
+MAGIC      = "ustar"            # magic tar string
+VERSION    = "00"               # version number
+
+LENGTH_NAME    = 100            # maximum length of a filename
+LENGTH_LINK    = 100            # maximum length of a linkname
+LENGTH_PREFIX  = 155            # maximum length of the prefix field
+MAXSIZE_MEMBER = 077777777777L  # maximum size of a file (11 octal digits)
+
+REGTYPE  = "0"                  # regular file
+AREGTYPE = "\0"                 # regular file
+LNKTYPE  = "1"                  # link (inside tarfile)
+SYMTYPE  = "2"                  # symbolic link
+CHRTYPE  = "3"                  # character special device
+BLKTYPE  = "4"                  # block special device
+DIRTYPE  = "5"                  # directory
+FIFOTYPE = "6"                  # fifo special device
+CONTTYPE = "7"                  # contiguous file
+
+GNUTYPE_LONGNAME = "L"          # GNU tar extension for longnames
+GNUTYPE_LONGLINK = "K"          # GNU tar extension for longlink
+GNUTYPE_SPARSE   = "S"          # GNU tar extension for sparse file
+
+#---------------------------------------------------------
+# tarfile constants
+#---------------------------------------------------------
+SUPPORTED_TYPES = (REGTYPE, AREGTYPE, LNKTYPE,  # file types that tarfile
+                   SYMTYPE, DIRTYPE, FIFOTYPE,  # can cope with.
+                   CONTTYPE, CHRTYPE, BLKTYPE,
+                   GNUTYPE_LONGNAME, GNUTYPE_LONGLINK,
+                   GNUTYPE_SPARSE)
+
+REGULAR_TYPES = (REGTYPE, AREGTYPE,             # file types that somehow
+                 CONTTYPE, GNUTYPE_SPARSE)      # represent regular files
+
+#---------------------------------------------------------
+# Bits used in the mode field, values in octal.
+#---------------------------------------------------------
+S_IFLNK = 0120000        # symbolic link
+S_IFREG = 0100000        # regular file
+S_IFBLK = 0060000        # block device
+S_IFDIR = 0040000        # directory
+S_IFCHR = 0020000        # character device
+S_IFIFO = 0010000        # fifo
+
+TSUID   = 04000          # set UID on execution
+TSGID   = 02000          # set GID on execution
+TSVTX   = 01000          # reserved
+
+TUREAD  = 0400           # read by owner
+TUWRITE = 0200           # write by owner
+TUEXEC  = 0100           # execute/search by owner
+TGREAD  = 0040           # read by group
+TGWRITE = 0020           # write by group
+TGEXEC  = 0010           # execute/search by group
+TOREAD  = 0004           # read by other
+TOWRITE = 0002           # write by other
+TOEXEC  = 0001           # execute/search by other
+
+#---------------------------------------------------------
+# Some useful functions
+#---------------------------------------------------------
+
+def stn(s, length):
+    """Convert a python string to a null-terminated string buffer.
+    """
+    return s[:length] + (length - len(s)) * NUL
+
+def nti(s):
+    """Convert a number field to a python number.
+    """
+    # There are two possible encodings for a number field, see
+    # itn() below.
+    if s[0] != chr(0200):
+        n = int(s.rstrip(NUL + " ") or "0", 8)
+    else:
+        n = 0L
+        for i in xrange(len(s) - 1):
+            n <<= 8
+            n += ord(s[i + 1])
+    return n
+
+def itn(n, digits=8, posix=False):
+    """Convert a python number to a number field.
+    """
+    # POSIX 1003.1-1988 requires numbers to be encoded as a string of
+    # octal digits followed by a null-byte, this allows values up to
+    # (8**(digits-1))-1. GNU tar allows storing numbers greater than
+    # that if necessary. A leading 0200 byte indicates this particular
+    # encoding, the following digits-1 bytes are a big-endian
+    # representation. This allows values up to (256**(digits-1))-1.
+    if 0 <= n < 8 ** (digits - 1):
+        s = "%0*o" % (digits - 1, n) + NUL
+    else:
+        if posix:
+            raise ValueError("overflow in number field")
+
+        if n < 0:
+            # XXX We mimic GNU tar's behaviour with negative numbers,
+            # this could raise OverflowError.
+            n = struct.unpack("L", struct.pack("l", n))[0]
+
+        s = ""
+        for i in xrange(digits - 1):
+            s = chr(n & 0377) + s
+            n >>= 8
+        s = chr(0200) + s
+    return s
+
+def calc_chksums(buf):
+    """Calculate the checksum for a member's header by summing up all
+       characters except for the chksum field which is treated as if
+       it was filled with spaces. According to the GNU tar sources,
+       some tars (Sun and NeXT) calculate chksum with signed char,
+       which will be different if there are chars in the buffer with
+       the high bit set. So we calculate two checksums, unsigned and
+       signed.
+    """
+    unsigned_chksum = 256 + sum(struct.unpack("148B", buf[:148]) + struct.unpack("356B", buf[156:512]))
+    signed_chksum = 256 + sum(struct.unpack("148b", buf[:148]) + struct.unpack("356b", buf[156:512]))
+    return unsigned_chksum, signed_chksum
+
+def copyfileobj(src, dst, length=None):
+    """Copy length bytes from fileobj src to fileobj dst.
+       If length is None, copy the entire content.
+    """
+    if length == 0:
+        return
+    if length is None:
+        shutil.copyfileobj(src, dst)
+        return
+
+    BUFSIZE = 16 * 1024
+    blocks, remainder = divmod(length, BUFSIZE)
+    for b in xrange(blocks):
+        buf = src.read(BUFSIZE)
+        if len(buf) < BUFSIZE:
+            raise IOError("end of file reached")
+        dst.write(buf)
+
+    if remainder != 0:
+        buf = src.read(remainder)
+        if len(buf) < remainder:
+            raise IOError("end of file reached")
+        dst.write(buf)
+    return
+
+filemode_table = (
+    ((S_IFLNK,      "l"),
+     (S_IFREG,      "-"),
+     (S_IFBLK,      "b"),
+     (S_IFDIR,      "d"),
+     (S_IFCHR,      "c"),
+     (S_IFIFO,      "p")),
+
+    ((TUREAD,       "r"),),
+    ((TUWRITE,      "w"),),
+    ((TUEXEC|TSUID, "s"),
+     (TSUID,        "S"),
+     (TUEXEC,       "x")),
+
+    ((TGREAD,       "r"),),
+    ((TGWRITE,      "w"),),
+    ((TGEXEC|TSGID, "s"),
+     (TSGID,        "S"),
+     (TGEXEC,       "x")),
+
+    ((TOREAD,       "r"),),
+    ((TOWRITE,      "w"),),
+    ((TOEXEC|TSVTX, "t"),
+     (TSVTX,        "T"),
+     (TOEXEC,       "x"))
+)
+
+def filemode(mode):
+    """Convert a file's mode to a string of the form
+       -rwxrwxrwx.
+       Used by TarFile.list()
+    """
+    perm = []
+    for table in filemode_table:
+        for bit, char in table:
+            if mode & bit == bit:
+                perm.append(char)
+                break
+        else:
+            perm.append("-")
+    return "".join(perm)
+
+if os.sep != "/":
+    normpath = lambda path: os.path.normpath(path).replace(os.sep, "/")
+else:
+    normpath = os.path.normpath
+
+class TarError(Exception):
+    """Base exception."""
+    pass
+class ExtractError(TarError):
+    """General exception for extract errors."""
+    pass
+class ReadError(TarError):
+    """Exception for unreadble tar archives."""
+    pass
+class CompressionError(TarError):
+    """Exception for unavailable compression methods."""
+    pass
+class StreamError(TarError):
+    """Exception for unsupported operations on stream-like TarFiles."""
+    pass
+
+#---------------------------
+# internal stream interface
+#---------------------------
+class _LowLevelFile:
+    """Low-level file object. Supports reading and writing.
+       It is used instead of a regular file object for streaming
+       access.
+    """
+
+    def __init__(self, name, mode):
+        mode = {
+            "r": os.O_RDONLY,
+            "w": os.O_WRONLY | os.O_CREAT | os.O_TRUNC,
+        }[mode]
+        if hasattr(os, "O_BINARY"):
+            mode |= os.O_BINARY
+        self.fd = os.open(name, mode)
+
+    def close(self):
+        os.close(self.fd)
+
+    def read(self, size):
+        return os.read(self.fd, size)
+
+    def write(self, s):
+        os.write(self.fd, s)
+
+class _Stream:
+    """Class that serves as an adapter between TarFile and
+       a stream-like object.  The stream-like object only
+       needs to have a read() or write() method and is accessed
+       blockwise.  Use of gzip or bzip2 compression is possible.
+       A stream-like object could be for example: sys.stdin,
+       sys.stdout, a socket, a tape device etc.
+
+       _Stream is intended to be used only internally.
+    """
+
+    def __init__(self, name, mode, comptype, fileobj, bufsize):
+        """Construct a _Stream object.
+        """
+        self._extfileobj = True
+        if fileobj is None:
+            fileobj = _LowLevelFile(name, mode)
+            self._extfileobj = False
+
+        if comptype == '*':
+            # Enable transparent compression detection for the
+            # stream interface
+            fileobj = _StreamProxy(fileobj)
+            comptype = fileobj.getcomptype()
+
+        self.name     = name or ""
+        self.mode     = mode
+        self.comptype = comptype
+        self.fileobj  = fileobj
+        self.bufsize  = bufsize
+        self.buf      = ""
+        self.pos      = 0L
+        self.closed   = False
+
+        if comptype == "gz":
+            try:
+                import zlib
+            except ImportError:
+                raise CompressionError("zlib module is not available")
+            self.zlib = zlib
+            self.crc = zlib.crc32("")
+            if mode == "r":
+                self._init_read_gz()
+            else:
+                self._init_write_gz()
+
+        if comptype == "bz2":
+            try:
+                import bz2
+            except ImportError:
+                raise CompressionError("bz2 module is not available")
+            if mode == "r":
+                self.dbuf = ""
+                self.cmp = bz2.BZ2Decompressor()
+            else:
+                self.cmp = bz2.BZ2Compressor()
+
+    def __del__(self):
+        if hasattr(self, "closed") and not self.closed:
+            self.close()
+
+    def _init_write_gz(self):
+        """Initialize for writing with gzip compression.
+        """
+        self.cmp = self.zlib.compressobj(9, self.zlib.DEFLATED,
+                                            -self.zlib.MAX_WBITS,
+                                            self.zlib.DEF_MEM_LEVEL,
+                                            0)
+        timestamp = struct.pack("<L", long(time.time()))
+        self.__write("\037\213\010\010%s\002\377" % timestamp)
+        if self.name.endswith(".gz"):
+            self.name = self.name[:-3]
+        self.__write(self.name + NUL)
+
+    def write(self, s):
+        """Write string s to the stream.
+        """
+        if self.comptype == "gz":
+            self.crc = self.zlib.crc32(s, self.crc)
+        self.pos += len(s)
+        if self.comptype != "tar":
+            s = self.cmp.compress(s)
+        self.__write(s)
+
+    def __write(self, s):
+        """Write string s to the stream if a whole new block
+           is ready to be written.
+        """
+        self.buf += s
+        while len(self.buf) > self.bufsize:
+            self.fileobj.write(self.buf[:self.bufsize])
+            self.buf = self.buf[self.bufsize:]
+
+    def close(self):
+        """Close the _Stream object. No operation should be
+           done on it afterwards.
+        """
+        if self.closed:
+            return
+
+        if self.mode == "w" and self.comptype != "tar":
+            self.buf += self.cmp.flush()
+
+        if self.mode == "w" and self.buf:
+            self.fileobj.write(self.buf)
+            self.buf = ""
+            if self.comptype == "gz":
+                # The native zlib crc is an unsigned 32-bit integer, but
+                # the Python wrapper implicitly casts that to a signed C
+                # long.  So, on a 32-bit box self.crc may "look negative",
+                # while the same crc on a 64-bit box may "look positive".
+                # To avoid irksome warnings from the `struct` module, force
+                # it to look positive on all boxes.
+                self.fileobj.write(struct.pack("<L", self.crc & 0xffffffffL))
+                self.fileobj.write(struct.pack("<L", self.pos & 0xffffFFFFL))
+
+        if not self._extfileobj:
+            self.fileobj.close()
+
+        self.closed = True
+
+    def _init_read_gz(self):
+        """Initialize for reading a gzip compressed fileobj.
+        """
+        self.cmp = self.zlib.decompressobj(-self.zlib.MAX_WBITS)
+        self.dbuf = ""
+
+        # taken from gzip.GzipFile with some alterations
+        if self.__read(2) != "\037\213":
+            raise ReadError("not a gzip file")
+        if self.__read(1) != "\010":
+            raise CompressionError("unsupported compression method")
+
+        flag = ord(self.__read(1))
+        self.__read(6)
+
+        if flag & 4:
+            xlen = ord(self.__read(1)) + 256 * ord(self.__read(1))
+            self.read(xlen)
+        if flag & 8:
+            while True:
+                s = self.__read(1)
+                if not s or s == NUL:
+                    break
+        if flag & 16:
+            while True:
+                s = self.__read(1)
+                if not s or s == NUL:
+                    break
+        if flag & 2:
+            self.__read(2)
+
+    def tell(self):
+        """Return the stream's file pointer position.
+        """
+        return self.pos
+
+    def seek(self, pos=0):
+        """Set the stream's file pointer to pos. Negative seeking
+           is forbidden.
+        """
+        if pos - self.pos >= 0:
+            blocks, remainder = divmod(pos - self.pos, self.bufsize)
+            for i in xrange(blocks):
+                self.read(self.bufsize)
+            self.read(remainder)
+        else:
+            raise StreamError("seeking backwards is not allowed")
+        return self.pos
+
+    def read(self, size=None):
+        """Return the next size number of bytes from the stream.
+           If size is not defined, return all bytes of the stream
+           up to EOF.
+        """
+        if size is None:
+            t = []
+            while True:
+                buf = self._read(self.bufsize)
+                if not buf:
+                    break
+                t.append(buf)
+            buf = "".join(t)
+        else:
+            buf = self._read(size)
+        self.pos += len(buf)
+        return buf
+
+    def _read(self, size):
+        """Return size bytes from the stream.
+        """
+        if self.comptype == "tar":
+            return self.__read(size)
+
+        c = len(self.dbuf)
+        t = [self.dbuf]
+        while c < size:
+            buf = self.__read(self.bufsize)
+            if not buf:
+                break
+            buf = self.cmp.decompress(buf)
+            t.append(buf)
+            c += len(buf)
+        t = "".join(t)
+        self.dbuf = t[size:]
+        return t[:size]
+
+    def __read(self, size):
+        """Return size bytes from stream. If internal buffer is empty,
+           read another block from the stream.
+        """
+        c = len(self.buf)
+        t = [self.buf]
+        while c < size:
+            buf = self.fileobj.read(self.bufsize)
+            if not buf:
+                break
+            t.append(buf)
+            c += len(buf)
+        t = "".join(t)
+        self.buf = t[size:]
+        return t[:size]
+# class _Stream
+
+class _StreamProxy(object):
+    """Small proxy class that enables transparent compression
+       detection for the Stream interface (mode 'r|*').
+    """
+
+    def __init__(self, fileobj):
+        self.fileobj = fileobj
+        self.buf = self.fileobj.read(BLOCKSIZE)
+
+    def read(self, size):
+        self.read = self.fileobj.read
+        return self.buf
+
+    def getcomptype(self):
+        if self.buf.startswith("\037\213\010"):
+            return "gz"
+        if self.buf.startswith("BZh91"):
+            return "bz2"
+        return "tar"
+
+    def close(self):
+        self.fileobj.close()
+# class StreamProxy
+
+class _BZ2Proxy(object):
+    """Small proxy class that enables external file object
+       support for "r:bz2" and "w:bz2" modes. This is actually
+       a workaround for a limitation in bz2 module's BZ2File
+       class which (unlike gzip.GzipFile) has no support for
+       a file object argument.
+    """
+
+    blocksize = 16 * 1024
+
+    def __init__(self, fileobj, mode):
+        self.fileobj = fileobj
+        self.mode = mode
+        self.init()
+
+    def init(self):
+        import bz2
+        self.pos = 0
+        if self.mode == "r":
+            self.bz2obj = bz2.BZ2Decompressor()
+            self.fileobj.seek(0)
+            self.buf = ""
+        else:
+            self.bz2obj = bz2.BZ2Compressor()
+
+    def read(self, size):
+        b = [self.buf]
+        x = len(self.buf)
+        while x < size:
+            try:
+                raw = self.fileobj.read(self.blocksize)
+                data = self.bz2obj.decompress(raw)
+                b.append(data)
+            except EOFError:
+                break
+            x += len(data)
+        self.buf = "".join(b)
+
+        buf = self.buf[:size]
+        self.buf = self.buf[size:]
+        self.pos += len(buf)
+        return buf
+
+    def seek(self, pos):
+        if pos < self.pos:
+            self.init()
+        self.read(pos - self.pos)
+
+    def tell(self):
+        return self.pos
+
+    def write(self, data):
+        self.pos += len(data)
+        raw = self.bz2obj.compress(data)
+        self.fileobj.write(raw)
+
+    def close(self):
+        if self.mode == "w":
+            raw = self.bz2obj.flush()
+            self.fileobj.write(raw)
+        self.fileobj.close()
+# class _BZ2Proxy
+
+#------------------------
+# Extraction file object
+#------------------------
+class _FileInFile(object):
+    """A thin wrapper around an existing file object that
+       provides a part of its data as an individual file
+       object.
+    """
+
+    def __init__(self, fileobj, offset, size, sparse=None):
+        self.fileobj = fileobj
+        self.offset = offset
+        self.size = size
+        self.sparse = sparse
+        self.position = 0
+
+    def tell(self):
+        """Return the current file position.
+        """
+        return self.position
+
+    def seek(self, position):
+        """Seek to a position in the file.
+        """
+        self.position = position
+
+    def read(self, size=None):
+        """Read data from the file.
+        """
+        if size is None:
+            size = self.size - self.position
+        else:
+            size = min(size, self.size - self.position)
+
+        if self.sparse is None:
+            return self.readnormal(size)
+        else:
+            return self.readsparse(size)
+
+    def readnormal(self, size):
+        """Read operation for regular files.
+        """
+        self.fileobj.seek(self.offset + self.position)
+        self.position += size
+        return self.fileobj.read(size)
+
+    def readsparse(self, size):
+        """Read operation for sparse files.
+        """
+        data = []
+        while size > 0:
+            buf = self.readsparsesection(size)
+            if not buf:
+                break
+            size -= len(buf)
+            data.append(buf)
+        return "".join(data)
+
+    def readsparsesection(self, size):
+        """Read a single section of a sparse file.
+        """
+        section = self.sparse.find(self.position)
+
+        if section is None:
+            return ""
+
+        size = min(size, section.offset + section.size - self.position)
+
+        if isinstance(section, _data):
+            realpos = section.realpos + self.position - section.offset
+            self.fileobj.seek(self.offset + realpos)
+            self.position += size
+            return self.fileobj.read(size)
+        else:
+            self.position += size
+            return NUL * size
+#class _FileInFile
+
+
+class ExFileObject(object):
+    """File-like object for reading an archive member.
+       Is returned by TarFile.extractfile().
+    """
+    blocksize = 1024
+
+    def __init__(self, tarfile, tarinfo):
+        self.fileobj = _FileInFile(tarfile.fileobj,
+                                   tarinfo.offset_data,
+                                   tarinfo.size,
+                                   getattr(tarinfo, "sparse", None))
+        self.name = tarinfo.name
+        self.mode = "r"
+        self.closed = False
+        self.size = tarinfo.size
+
+        self.position = 0
+        self.buffer = ""
+
+    def read(self, size=None):
+        """Read at most size bytes from the file. If size is not
+           present or None, read all data until EOF is reached.
+        """
+        if self.closed:
+            raise ValueError("I/O operation on closed file")
+
+        buf = ""
+        if self.buffer:
+            if size is None:
+                buf = self.buffer
+                self.buffer = ""
+            else:
+                buf = self.buffer[:size]
+                self.buffer = self.buffer[size:]
+
+        if size is None:
+            buf += self.fileobj.read()
+        else:
+            buf += self.fileobj.read(size - len(buf))
+
+        self.position += len(buf)
+        return buf
+
+    def readline(self, size=-1):
+        """Read one entire line from the file. If size is present
+           and non-negative, return a string with at most that
+           size, which may be an incomplete line.
+        """
+        if self.closed:
+            raise ValueError("I/O operation on closed file")
+
+        if "\n" in self.buffer:
+            pos = self.buffer.find("\n") + 1
+        else:
+            buffers = [self.buffer]
+            while True:
+                buf = self.fileobj.read(self.blocksize)
+                buffers.append(buf)
+                if not buf or "\n" in buf:
+                    self.buffer = "".join(buffers)
+                    pos = self.buffer.find("\n") + 1
+                    if pos == 0:
+                        # no newline found.
+                        pos = len(self.buffer)
+                    break
+
+        if size != -1:
+            pos = min(size, pos)
+
+        buf = self.buffer[:pos]
+        self.buffer = self.buffer[pos:]
+        self.position += len(buf)
+        return buf
+
+    def readlines(self):
+        """Return a list with all remaining lines.
+        """
+        result = []
+        while True:
+            line = self.readline()
+            if not line: break
+            result.append(line)
+        return result
+
+    def tell(self):
+        """Return the current file position.
+        """
+        if self.closed:
+            raise ValueError("I/O operation on closed file")
+
+        return self.position
+
+    def seek(self, pos, whence=os.SEEK_SET):
+        """Seek to a position in the file.
+        """
+        if self.closed:
+            raise ValueError("I/O operation on closed file")
+
+        if whence == os.SEEK_SET:
+            self.position = min(max(pos, 0), self.size)
+        elif whence == os.SEEK_CUR:
+            if pos < 0:
+                self.position = max(self.position + pos, 0)
+            else:
+                self.position = min(self.position + pos, self.size)
+        elif whence == os.SEEK_END:
+            self.position = max(min(self.size + pos, self.size), 0)
+        else:
+            raise ValueError("Invalid argument")
+
+        self.buffer = ""
+        self.fileobj.seek(self.position)
+
+    def close(self):
+        """Close the file object.
+        """
+        self.closed = True
+
+    def __iter__(self):
+        """Get an iterator over the file's lines.
+        """
+        while True:
+            line = self.readline()
+            if not line:
+                break
+            yield line
+#class ExFileObject
+
+#------------------
+# Exported Classes
+#------------------
+class TarInfo(object):
+    """Informational class which holds the details about an
+       archive member given by a tar header block.
+       TarInfo objects are returned by TarFile.getmember(),
+       TarFile.getmembers() and TarFile.gettarinfo() and are
+       usually created internally.
+    """
+
+    def __init__(self, name=""):
+        """Construct a TarInfo object. name is the optional name
+           of the member.
+        """
+        self.name = name        # member name (dirnames must end with '/')
+        self.mode = 0666        # file permissions
+        self.uid = 0            # user id
+        self.gid = 0            # group id
+        self.size = 0           # file size
+        self.mtime = 0          # modification time
+        self.chksum = 0         # header checksum
+        self.type = REGTYPE     # member type
+        self.linkname = ""      # link name
+        self.uname = "user"     # user name
+        self.gname = "group"    # group name
+        self.devmajor = 0       # device major number
+        self.devminor = 0       # device minor number
+
+        self.offset = 0         # the tar header starts here
+        self.offset_data = 0    # the file's data starts here
+
+    def __repr__(self):
+        return "<%s %r at %#x>" % (self.__class__.__name__,self.name,id(self))
+
+    @classmethod
+    def frombuf(cls, buf):
+        """Construct a TarInfo object from a 512 byte string buffer.
+        """
+        if len(buf) != BLOCKSIZE:
+            raise ValueError("truncated header")
+        if buf.count(NUL) == BLOCKSIZE:
+            raise ValueError("empty header")
+
+        tarinfo = cls()
+        tarinfo.buf = buf
+        tarinfo.name = buf[0:100].rstrip(NUL)
+        tarinfo.mode = nti(buf[100:108])
+        tarinfo.uid = nti(buf[108:116])
+        tarinfo.gid = nti(buf[116:124])
+        tarinfo.size = nti(buf[124:136])
+        tarinfo.mtime = nti(buf[136:148])
+        tarinfo.chksum = nti(buf[148:156])
+        tarinfo.type = buf[156:157]
+        tarinfo.linkname = buf[157:257].rstrip(NUL)
+        tarinfo.uname = buf[265:297].rstrip(NUL)
+        tarinfo.gname = buf[297:329].rstrip(NUL)
+        tarinfo.devmajor = nti(buf[329:337])
+        tarinfo.devminor = nti(buf[337:345])
+        prefix = buf[345:500].rstrip(NUL)
+
+        if prefix and not tarinfo.issparse():
+            tarinfo.name = prefix + "/" + tarinfo.name
+
+        if tarinfo.chksum not in calc_chksums(buf):
+            raise ValueError("invalid header")
+        return tarinfo
+
+    def tobuf(self, posix=False):
+        """Return a tar header as a string of 512 byte blocks.
+        """
+        buf = ""
+        type = self.type
+        prefix = ""
+
+        if self.name.endswith("/"):
+            type = DIRTYPE
+
+        if type in (GNUTYPE_LONGNAME, GNUTYPE_LONGLINK):
+            # Prevent "././@LongLink" from being normalized.
+            name = self.name
+        else:
+            name = normpath(self.name)
+
+        if type == DIRTYPE:
+            # directories should end with '/'
+            name += "/"
+
+        linkname = self.linkname
+        if linkname:
+            # if linkname is empty we end up with a '.'
+            linkname = normpath(linkname)
+
+        if posix:
+            if self.size > MAXSIZE_MEMBER:
+                raise ValueError("file is too large (>= 8 GB)")
+
+            if len(self.linkname) > LENGTH_LINK:
+                raise ValueError("linkname is too long (>%d)" % (LENGTH_LINK))
+
+            if len(name) > LENGTH_NAME:
+                prefix = name[:LENGTH_PREFIX + 1]
+                while prefix and prefix[-1] != "/":
+                    prefix = prefix[:-1]
+
+                name = name[len(prefix):]
+                prefix = prefix[:-1]
+
+                if not prefix or len(name) > LENGTH_NAME:
+                    raise ValueError("name is too long")
+
+        else:
+            if len(self.linkname) > LENGTH_LINK:
+                buf += self._create_gnulong(self.linkname, GNUTYPE_LONGLINK)
+
+            if len(name) > LENGTH_NAME:
+                buf += self._create_gnulong(name, GNUTYPE_LONGNAME)
+
+        parts = [
+            stn(name, 100),
+            itn(self.mode & 07777, 8, posix),
+            itn(self.uid, 8, posix),
+            itn(self.gid, 8, posix),
+            itn(self.size, 12, posix),
+            itn(self.mtime, 12, posix),
+            "        ", # checksum field
+            type,
+            stn(self.linkname, 100),
+            stn(MAGIC, 6),
+            stn(VERSION, 2),
+            stn(self.uname, 32),
+            stn(self.gname, 32),
+            itn(self.devmajor, 8, posix),
+            itn(self.devminor, 8, posix),
+            stn(prefix, 155)
+        ]
+
+        buf += struct.pack("%ds" % BLOCKSIZE, "".join(parts))
+        chksum = calc_chksums(buf[-BLOCKSIZE:])[0]
+        buf = buf[:-364] + "%06o\0" % chksum + buf[-357:]
+        self.buf = buf
+        return buf
+
+    def _create_gnulong(self, name, type):
+        """Create a GNU longname/longlink header from name.
+           It consists of an extended tar header, with the length
+           of the longname as size, followed by data blocks,
+           which contain the longname as a null terminated string.
+        """
+        name += NUL
+
+        tarinfo = self.__class__()
+        tarinfo.name = "././@LongLink"
+        tarinfo.type = type
+        tarinfo.mode = 0
+        tarinfo.size = len(name)
+
+        # create extended header
+        buf = tarinfo.tobuf()
+        # create name blocks
+        buf += name
+        blocks, remainder = divmod(len(name), BLOCKSIZE)
+        if remainder > 0:
+            buf += (BLOCKSIZE - remainder) * NUL
+        return buf
+
+    def isreg(self):
+        return self.type in REGULAR_TYPES
+    def isfile(self):
+        return self.isreg()
+    def isdir(self):
+        return self.type == DIRTYPE
+    def issym(self):
+        return self.type == SYMTYPE
+    def islnk(self):
+        return self.type == LNKTYPE
+    def ischr(self):
+        return self.type == CHRTYPE
+    def isblk(self):
+        return self.type == BLKTYPE
+    def isfifo(self):
+        return self.type == FIFOTYPE
+    def issparse(self):
+        return self.type == GNUTYPE_SPARSE
+    def isdev(self):
+        return self.type in (CHRTYPE, BLKTYPE, FIFOTYPE)
+# class TarInfo
+
+class TarFile(object):
+    """The TarFile Class provides an interface to tar archives.
+    """
+
+    debug = 0                   # May be set from 0 (no msgs) to 3 (all msgs)
+
+    dereference = False         # If true, add content of linked file to the
+                                # tar file, else the link.
+
+    ignore_zeros = False        # If true, skips empty or invalid blocks and
+                                # continues processing.
+
+    errorlevel = 0              # If 0, fatal errors only appear in debug
+                                # messages (if debug >= 0). If > 0, errors
+                                # are passed to the caller as exceptions.
+
+    posix = False               # If True, generates POSIX.1-1990-compliant
+                                # archives (no GNU extensions!)
+
+    fileobject = ExFileObject
+
+    def __init__(self, name=None, mode="r", fileobj=None):
+        """Open an (uncompressed) tar archive `name'. `mode' is either 'r' to
+           read from an existing archive, 'a' to append data to an existing
+           file or 'w' to create a new file overwriting an existing one. `mode'
+           defaults to 'r'.
+           If `fileobj' is given, it is used for reading or writing data. If it
+           can be determined, `mode' is overridden by `fileobj's mode.
+           `fileobj' is not closed, when TarFile is closed.
+        """
+        self.name = os.path.abspath(name)
+
+        if len(mode) > 1 or mode not in "raw":
+            raise ValueError("mode must be 'r', 'a' or 'w'")
+        self._mode = mode
+        self.mode = {"r": "rb", "a": "r+b", "w": "wb"}[mode]
+
+        if not fileobj:
+            fileobj = file(self.name, self.mode)
+            self._extfileobj = False
+        else:
+            if self.name is None and hasattr(fileobj, "name"):
+                self.name = os.path.abspath(fileobj.name)
+            if hasattr(fileobj, "mode"):
+                self.mode = fileobj.mode
+            self._extfileobj = True
+        self.fileobj = fileobj
+
+        # Init datastructures
+        self.closed = False
+        self.members = []       # list of members as TarInfo objects
+        self._loaded = False    # flag if all members have been read
+        self.offset = 0L        # current position in the archive file
+        self.inodes = {}        # dictionary caching the inodes of
+                                # archive members already added
+
+        if self._mode == "r":
+            self.firstmember = None
+            self.firstmember = self.next()
+
+        if self._mode == "a":
+            # Move to the end of the archive,
+            # before the first empty block.
+            self.firstmember = None
+            while True:
+                try:
+                    tarinfo = self.next()
+                except ReadError:
+                    self.fileobj.seek(0)
+                    break
+                if tarinfo is None:
+                    self.fileobj.seek(- BLOCKSIZE, 1)
+                    break
+
+        if self._mode in "aw":
+            self._loaded = True
+
+    #--------------------------------------------------------------------------
+    # Below are the classmethods which act as alternate constructors to the
+    # TarFile class. The open() method is the only one that is needed for
+    # public use; it is the "super"-constructor and is able to select an
+    # adequate "sub"-constructor for a particular compression using the mapping
+    # from OPEN_METH.
+    #
+    # This concept allows one to subclass TarFile without losing the comfort of
+    # the super-constructor. A sub-constructor is registered and made available
+    # by adding it to the mapping in OPEN_METH.
+
+    @classmethod
+    def open(cls, name=None, mode="r", fileobj=None, bufsize=20*512):
+        """Open a tar archive for reading, writing or appending. Return
+           an appropriate TarFile class.
+
+           mode:
+           'r' or 'r:*' open for reading with transparent compression
+           'r:'         open for reading exclusively uncompressed
+           'r:gz'       open for reading with gzip compression
+           'r:bz2'      open for reading with bzip2 compression
+           'a' or 'a:'  open for appending
+           'w' or 'w:'  open for writing without compression
+           'w:gz'       open for writing with gzip compression
+           'w:bz2'      open for writing with bzip2 compression
+
+           'r|*'        open a stream of tar blocks with transparent compression
+           'r|'         open an uncompressed stream of tar blocks for reading
+           'r|gz'       open a gzip compressed stream of tar blocks
+           'r|bz2'      open a bzip2 compressed stream of tar blocks
+           'w|'         open an uncompressed stream for writing
+           'w|gz'       open a gzip compressed stream for writing
+           'w|bz2'      open a bzip2 compressed stream for writing
+        """
+
+        if not name and not fileobj:
+            raise ValueError("nothing to open")
+
+        if mode in ("r", "r:*"):
+            # Find out which *open() is appropriate for opening the file.
+            for comptype in cls.OPEN_METH:
+                func = getattr(cls, cls.OPEN_METH[comptype])
+                if fileobj is not None:
+                    saved_pos = fileobj.tell()
+                try:
+                    return func(name, "r", fileobj)
+                except (ReadError, CompressionError):
+                    if fileobj is not None:
+                        fileobj.seek(saved_pos)
+                    continue
+            raise ReadError("file could not be opened successfully")
+
+        elif ":" in mode:
+            filemode, comptype = mode.split(":", 1)
+            filemode = filemode or "r"
+            comptype = comptype or "tar"
+
+            # Select the *open() function according to
+            # given compression.
+            if comptype in cls.OPEN_METH:
+                func = getattr(cls, cls.OPEN_METH[comptype])
+            else:
+                raise CompressionError("unknown compression type %r" % comptype)
+            return func(name, filemode, fileobj)
+
+        elif "|" in mode:
+            filemode, comptype = mode.split("|", 1)
+            filemode = filemode or "r"
+            comptype = comptype or "tar"
+
+            if filemode not in "rw":
+                raise ValueError("mode must be 'r' or 'w'")
+
+            t = cls(name, filemode,
+                    _Stream(name, filemode, comptype, fileobj, bufsize))
+            t._extfileobj = False
+            return t
+
+        elif mode in "aw":
+            return cls.taropen(name, mode, fileobj)
+
+        raise ValueError("undiscernible mode")
+
+    @classmethod
+    def taropen(cls, name, mode="r", fileobj=None):
+        """Open uncompressed tar archive name for reading or writing.
+        """
+        if len(mode) > 1 or mode not in "raw":
+            raise ValueError("mode must be 'r', 'a' or 'w'")
+        return cls(name, mode, fileobj)
+
+    @classmethod
+    def gzopen(cls, name, mode="r", fileobj=None, compresslevel=9):
+        """Open gzip compressed tar archive name for reading or writing.
+           Appending is not allowed.
+        """
+        if len(mode) > 1 or mode not in "rw":
+            raise ValueError("mode must be 'r' or 'w'")
+
+        try:
+            import gzip
+            gzip.GzipFile
+        except (ImportError, AttributeError):
+            raise CompressionError("gzip module is not available")
+
+        if fileobj is None:
+            fileobj = file(name, mode + "b")
+
+        try:
+            t = cls.taropen(name, mode,
+                gzip.GzipFile(name, mode, compresslevel, fileobj))
+        except IOError:
+            raise ReadError("not a gzip file")
+        t._extfileobj = False
+        return t
+
+    @classmethod
+    def bz2open(cls, name, mode="r", fileobj=None, compresslevel=9):
+        """Open bzip2 compressed tar archive name for reading or writing.
+           Appending is not allowed.
+        """
+        if len(mode) > 1 or mode not in "rw":
+            raise ValueError("mode must be 'r' or 'w'.")
+
+        try:
+            import bz2
+        except ImportError:
+            raise CompressionError("bz2 module is not available")
+
+        if fileobj is not None:
+            fileobj = _BZ2Proxy(fileobj, mode)
+        else:
+            fileobj = bz2.BZ2File(name, mode, compresslevel=compresslevel)
+
+        try:
+            t = cls.taropen(name, mode, fileobj)
+        except IOError:
+            raise ReadError("not a bzip2 file")
+        t._extfileobj = False
+        return t
+
+    # All *open() methods are registered here.
+    OPEN_METH = {
+        "tar": "taropen",   # uncompressed tar
+        "gz":  "gzopen",    # gzip compressed tar
+        "bz2": "bz2open"    # bzip2 compressed tar
+    }
+
+    #--------------------------------------------------------------------------
+    # The public methods which TarFile provides:
+
+    def close(self):
+        """Close the TarFile. In write-mode, two finishing zero blocks are
+           appended to the archive.
+        """
+        if self.closed:
+            return
+
+        if self._mode in "aw":
+            self.fileobj.write(NUL * (BLOCKSIZE * 2))
+            self.offset += (BLOCKSIZE * 2)
+            # fill up the end with zero-blocks
+            # (like option -b20 for tar does)
+            blocks, remainder = divmod(self.offset, RECORDSIZE)
+            if remainder > 0:
+                self.fileobj.write(NUL * (RECORDSIZE - remainder))
+
+        if not self._extfileobj:
+            self.fileobj.close()
+        self.closed = True
+
+    def getmember(self, name):
+        """Return a TarInfo object for member `name'. If `name' can not be
+           found in the archive, KeyError is raised. If a member occurs more
+           than once in the archive, its last occurence is assumed to be the
+           most up-to-date version.
+        """
+        tarinfo = self._getmember(name)
+        if tarinfo is None:
+            raise KeyError("filename %r not found" % name)
+        return tarinfo
+
+    def getmembers(self):
+        """Return the members of the archive as a list of TarInfo objects. The
+           list has the same order as the members in the archive.
+        """
+        self._check()
+        if not self._loaded:    # if we want to obtain a list of
+            self._load()        # all members, we first have to
+                                # scan the whole archive.
+        return self.members
+
+    def getnames(self):
+        """Return the members of the archive as a list of their names. It has
+           the same order as the list returned by getmembers().
+        """
+        return [tarinfo.name for tarinfo in self.getmembers()]
+
+    def gettarinfo(self, name=None, arcname=None, fileobj=None):
+        """Create a TarInfo object for either the file `name' or the file
+           object `fileobj' (using os.fstat on its file descriptor). You can
+           modify some of the TarInfo's attributes before you add it using
+           addfile(). If given, `arcname' specifies an alternative name for the
+           file in the archive.
+        """
+        self._check("aw")
+
+        # When fileobj is given, replace name by
+        # fileobj's real name.
+        if fileobj is not None:
+            name = fileobj.name
+
+        # Building the name of the member in the archive.
+        # Backward slashes are converted to forward slashes,
+        # Absolute paths are turned to relative paths.
+        if arcname is None:
+            arcname = name
+        arcname = normpath(arcname)
+        drv, arcname = os.path.splitdrive(arcname)
+        while arcname[0:1] == "/":
+            arcname = arcname[1:]
+
+        # Now, fill the TarInfo object with
+        # information specific for the file.
+        tarinfo = TarInfo()
+
+        # Use os.stat or os.lstat, depending on platform
+        # and if symlinks shall be resolved.
+        if fileobj is None:
+            if hasattr(os, "lstat") and not self.dereference:
+                statres = os.lstat(name)
+            else:
+                statres = os.stat(name)
+        else:
+            statres = os.fstat(fileobj.fileno())
+        linkname = ""
+
+        stmd = statres.st_mode
+        if stat.S_ISREG(stmd):
+            inode = (statres.st_ino, statres.st_dev)
+            if not self.dereference and \
+                    statres.st_nlink > 1 and inode in self.inodes:
+                # Is it a hardlink to an already
+                # archived file?
+                type = LNKTYPE
+                linkname = self.inodes[inode]
+            else:
+                # The inode is added only if its valid.
+                # For win32 it is always 0.
+                type = REGTYPE
+                if inode[0]:
+                    self.inodes[inode] = arcname
+        elif stat.S_ISDIR(stmd):
+            type = DIRTYPE
+            if arcname[-1:] != "/":
+                arcname += "/"
+        elif stat.S_ISFIFO(stmd):
+            type = FIFOTYPE
+        elif stat.S_ISLNK(stmd):
+            type = SYMTYPE
+            linkname = os.readlink(name)
+        elif stat.S_ISCHR(stmd):
+            type = CHRTYPE
+        elif stat.S_ISBLK(stmd):
+            type = BLKTYPE
+        else:
+            return None
+
+        # Fill the TarInfo object with all
+        # information we can get.
+        tarinfo.name = arcname
+        tarinfo.mode = stmd
+        tarinfo.uid = statres.st_uid
+        tarinfo.gid = statres.st_gid
+        if stat.S_ISREG(stmd):
+            tarinfo.size = statres.st_size
+        else:
+            tarinfo.size = 0L
+        tarinfo.mtime = statres.st_mtime
+        tarinfo.type = type
+        tarinfo.linkname = linkname
+        if pwd:
+            try:
+                tarinfo.uname = pwd.getpwuid(tarinfo.uid)[0]
+            except KeyError:
+                pass
+        if grp:
+            try:
+                tarinfo.gname = grp.getgrgid(tarinfo.gid)[0]
+            except KeyError:
+                pass
+
+        if type in (CHRTYPE, BLKTYPE):
+            if hasattr(os, "major") and hasattr(os, "minor"):
+                tarinfo.devmajor = os.major(statres.st_rdev)
+                tarinfo.devminor = os.minor(statres.st_rdev)
+        return tarinfo
+
+    def list(self, verbose=True):
+        """Print a table of contents to sys.stdout. If `verbose' is False, only
+           the names of the members are printed. If it is True, an `ls -l'-like
+           output is produced.
+        """
+        self._check()
+
+        for tarinfo in self:
+            if verbose:
+                print filemode(tarinfo.mode),
+                print "%s/%s" % (tarinfo.uname or tarinfo.uid,
+                                 tarinfo.gname or tarinfo.gid),
+                if tarinfo.ischr() or tarinfo.isblk():
+                    print "%10s" % ("%d,%d" \
+                                    % (tarinfo.devmajor, tarinfo.devminor)),
+                else:
+                    print "%10d" % tarinfo.size,
+                print "%d-%02d-%02d %02d:%02d:%02d" \
+                      % time.localtime(tarinfo.mtime)[:6],
+
+            print tarinfo.name,
+
+            if verbose:
+                if tarinfo.issym():
+                    print "->", tarinfo.linkname,
+                if tarinfo.islnk():
+                    print "link to", tarinfo.linkname,
+            print
+
+    def add(self, name, arcname=None, recursive=True):
+        """Add the file `name' to the archive. `name' may be any type of file
+           (directory, fifo, symbolic link, etc.). If given, `arcname'
+           specifies an alternative name for the file in the archive.
+           Directories are added recursively by default. This can be avoided by
+           setting `recursive' to False.
+        """
+        self._check("aw")
+
+        if arcname is None:
+            arcname = name
+
+        # Skip if somebody tries to archive the archive...
+        if self.name is not None and os.path.abspath(name) == self.name:
+            self._dbg(2, "tarfile: Skipped %r" % name)
+            return
+
+        # Special case: The user wants to add the current
+        # working directory.
+        if name == ".":
+            if recursive:
+                if arcname == ".":
+                    arcname = ""
+                for f in os.listdir("."):
+                    self.add(f, os.path.join(arcname, f))
+            return
+
+        self._dbg(1, name)
+
+        # Create a TarInfo object from the file.
+        tarinfo = self.gettarinfo(name, arcname)
+
+        if tarinfo is None:
+            self._dbg(1, "tarfile: Unsupported type %r" % name)
+            return
+
+        # Append the tar header and data to the archive.
+        if tarinfo.isreg():
+            f = file(name, "rb")
+            self.addfile(tarinfo, f)
+            f.close()
+
+        elif tarinfo.isdir():
+            self.addfile(tarinfo)
+            if recursive:
+                for f in os.listdir(name):
+                    self.add(os.path.join(name, f), os.path.join(arcname, f))
+
+        else:
+            self.addfile(tarinfo)
+
+    def addfile(self, tarinfo, fileobj=None):
+        """Add the TarInfo object `tarinfo' to the archive. If `fileobj' is
+           given, tarinfo.size bytes are read from it and added to the archive.
+           You can create TarInfo objects using gettarinfo().
+           On Windows platforms, `fileobj' should always be opened with mode
+           'rb' to avoid irritation about the file size.
+        """
+        self._check("aw")
+
+        tarinfo = copy.copy(tarinfo)
+
+        buf = tarinfo.tobuf(self.posix)
+        self.fileobj.write(buf)
+        self.offset += len(buf)
+
+        # If there's data to follow, append it.
+        if fileobj is not None:
+            copyfileobj(fileobj, self.fileobj, tarinfo.size)
+            blocks, remainder = divmod(tarinfo.size, BLOCKSIZE)
+            if remainder > 0:
+                self.fileobj.write(NUL * (BLOCKSIZE - remainder))
+                blocks += 1
+            self.offset += blocks * BLOCKSIZE
+
+        self.members.append(tarinfo)
+
+    def extractall(self, path=".", members=None):
+        """Extract all members from the archive to the current working
+           directory and set owner, modification time and permissions on
+           directories afterwards. `path' specifies a different directory
+           to extract to. `members' is optional and must be a subset of the
+           list returned by getmembers().
+        """
+        directories = []
+
+        if members is None:
+            members = self
+
+        for tarinfo in members:
+            if tarinfo.isdir():
+                # Extract directory with a safe mode, so that
+                # all files below can be extracted as well.
+                try:
+                    os.makedirs(os.path.join(path, tarinfo.name), 0777)
+                except EnvironmentError:
+                    pass
+                directories.append(tarinfo)
+            else:
+                self.extract(tarinfo, path)
+
+        # Reverse sort directories.
+        directories.sort(lambda a, b: cmp(a.name, b.name))
+        directories.reverse()
+
+        # Set correct owner, mtime and filemode on directories.
+        for tarinfo in directories:
+            path = os.path.join(path, tarinfo.name)
+            try:
+                self.chown(tarinfo, path)
+                self.utime(tarinfo, path)
+                self.chmod(tarinfo, path)
+            except ExtractError, e:
+                if self.errorlevel > 1:
+                    raise
+                else:
+                    self._dbg(1, "tarfile: %s" % e)
+
+    def extract(self, member, path=""):
+        """Extract a member from the archive to the current working directory,
+           using its full name. Its file information is extracted as accurately
+           as possible. `member' may be a filename or a TarInfo object. You can
+           specify a different directory using `path'.
+        """
+        self._check("r")
+
+        if isinstance(member, TarInfo):
+            tarinfo = member
+        else:
+            tarinfo = self.getmember(member)
+
+        # Prepare the link target for makelink().
+        if tarinfo.islnk():
+            tarinfo._link_target = os.path.join(path, tarinfo.linkname)
+
+        try:
+            self._extract_member(tarinfo, os.path.join(path, tarinfo.name))
+        except EnvironmentError, e:
+            if self.errorlevel > 0:
+                raise
+            else:
+                if e.filename is None:
+                    self._dbg(1, "tarfile: %s" % e.strerror)
+                else:
+                    self._dbg(1, "tarfile: %s %r" % (e.strerror, e.filename))
+        except ExtractError, e:
+            if self.errorlevel > 1:
+                raise
+            else:
+                self._dbg(1, "tarfile: %s" % e)
+
+    def extractfile(self, member):
+        """Extract a member from the archive as a file object. `member' may be
+           a filename or a TarInfo object. If `member' is a regular file, a
+           file-like object is returned. If `member' is a link, a file-like
+           object is constructed from the link's target. If `member' is none of
+           the above, None is returned.
+           The file-like object is read-only and provides the following
+           methods: read(), readline(), readlines(), seek() and tell()
+        """
+        self._check("r")
+
+        if isinstance(member, TarInfo):
+            tarinfo = member
+        else:
+            tarinfo = self.getmember(member)
+
+        if tarinfo.isreg():
+            return self.fileobject(self, tarinfo)
+
+        elif tarinfo.type not in SUPPORTED_TYPES:
+            # If a member's type is unknown, it is treated as a
+            # regular file.
+            return self.fileobject(self, tarinfo)
+
+        elif tarinfo.islnk() or tarinfo.issym():
+            if isinstance(self.fileobj, _Stream):
+                # A small but ugly workaround for the case that someone tries
+                # to extract a (sym)link as a file-object from a non-seekable
+                # stream of tar blocks.
+                raise StreamError("cannot extract (sym)link as file object")
+            else:
+                # A (sym)link's file object is its target's file object.
+                return self.extractfile(self._getmember(tarinfo.linkname,
+                                                        tarinfo))
+        else:
+            # If there's no data associated with the member (directory, chrdev,
+            # blkdev, etc.), return None instead of a file object.
+            return None
+
+    def _extract_member(self, tarinfo, targetpath):
+        """Extract the TarInfo object tarinfo to a physical
+           file called targetpath.
+        """
+        # Fetch the TarInfo object for the given name
+        # and build the destination pathname, replacing
+        # forward slashes to platform specific separators.
+        if targetpath[-1:] == "/":
+            targetpath = targetpath[:-1]
+        targetpath = os.path.normpath(targetpath)
+
+        # Create all upper directories.
+        upperdirs = os.path.dirname(targetpath)
+        if upperdirs and not os.path.exists(upperdirs):
+            ti = TarInfo()
+            ti.name  = upperdirs
+            ti.type  = DIRTYPE
+            ti.mode  = 0777
+            ti.mtime = tarinfo.mtime
+            ti.uid   = tarinfo.uid
+            ti.gid   = tarinfo.gid
+            ti.uname = tarinfo.uname
+            ti.gname = tarinfo.gname
+            try:
+                self._extract_member(ti, ti.name)
+            except:
+                pass
+
+        if tarinfo.islnk() or tarinfo.issym():
+            self._dbg(1, "%s -> %s" % (tarinfo.name, tarinfo.linkname))
+        else:
+            self._dbg(1, tarinfo.name)
+
+        if tarinfo.isreg():
+            self.makefile(tarinfo, targetpath)
+        elif tarinfo.isdir():
+            self.makedir(tarinfo, targetpath)
+        elif tarinfo.isfifo():
+            self.makefifo(tarinfo, targetpath)
+        elif tarinfo.ischr() or tarinfo.isblk():
+            self.makedev(tarinfo, targetpath)
+        elif tarinfo.islnk() or tarinfo.issym():
+            self.makelink(tarinfo, targetpath)
+        elif tarinfo.type not in SUPPORTED_TYPES:
+            self.makeunknown(tarinfo, targetpath)
+        else:
+            self.makefile(tarinfo, targetpath)
+
+        self.chown(tarinfo, targetpath)
+        if not tarinfo.issym():
+            self.chmod(tarinfo, targetpath)
+            self.utime(tarinfo, targetpath)
+
+    #--------------------------------------------------------------------------
+    # Below are the different file methods. They are called via
+    # _extract_member() when extract() is called. They can be replaced in a
+    # subclass to implement other functionality.
+
+    def makedir(self, tarinfo, targetpath):
+        """Make a directory called targetpath.
+        """
+        try:
+            os.mkdir(targetpath)
+        except EnvironmentError, e:
+            if e.errno != errno.EEXIST:
+                raise
+
+    def makefile(self, tarinfo, targetpath):
+        """Make a file called targetpath.
+        """
+        source = self.extractfile(tarinfo)
+        target = file(targetpath, "wb")
+        copyfileobj(source, target)
+        source.close()
+        target.close()
+
+    def makeunknown(self, tarinfo, targetpath):
+        """Make a file from a TarInfo object with an unknown type
+           at targetpath.
+        """
+        self.makefile(tarinfo, targetpath)
+        self._dbg(1, "tarfile: Unknown file type %r, " \
+                     "extracted as regular file." % tarinfo.type)
+
+    def makefifo(self, tarinfo, targetpath):
+        """Make a fifo called targetpath.
+        """
+        if hasattr(os, "mkfifo"):
+            os.mkfifo(targetpath)
+        else:
+            raise ExtractError("fifo not supported by system")
+
+    def makedev(self, tarinfo, targetpath):
+        """Make a character or block device called targetpath.
+        """
+        if not hasattr(os, "mknod") or not hasattr(os, "makedev"):
+            raise ExtractError("special devices not supported by system")
+
+        mode = tarinfo.mode
+        if tarinfo.isblk():
+            mode |= stat.S_IFBLK
+        else:
+            mode |= stat.S_IFCHR
+
+        os.mknod(targetpath, mode,
+                 os.makedev(tarinfo.devmajor, tarinfo.devminor))
+
+    def makelink(self, tarinfo, targetpath):
+        """Make a (symbolic) link called targetpath. If it cannot be created
+          (platform limitation), we try to make a copy of the referenced file
+          instead of a link.
+        """
+        linkpath = tarinfo.linkname
+        try:
+            if tarinfo.issym():
+                os.symlink(linkpath, targetpath)
+            else:
+                # See extract().
+                os.link(tarinfo._link_target, targetpath)
+        except AttributeError:
+            if tarinfo.issym():
+                linkpath = os.path.join(os.path.dirname(tarinfo.name),
+                                        linkpath)
+                linkpath = normpath(linkpath)
+
+            try:
+                self._extract_member(self.getmember(linkpath), targetpath)
+            except (EnvironmentError, KeyError), e:
+                linkpath = os.path.normpath(linkpath)
+                try:
+                    shutil.copy2(linkpath, targetpath)
+                except EnvironmentError, e:
+                    raise IOError("link could not be created")
+
+    def chown(self, tarinfo, targetpath):
+        """Set owner of targetpath according to tarinfo.
+        """
+        if pwd and hasattr(os, "geteuid") and os.geteuid() == 0:
+            # We have to be root to do so.
+            try:
+                g = grp.getgrnam(tarinfo.gname)[2]
+            except KeyError:
+                try:
+                    g = grp.getgrgid(tarinfo.gid)[2]
+                except KeyError:
+                    g = os.getgid()
+            try:
+                u = pwd.getpwnam(tarinfo.uname)[2]
+            except KeyError:
+                try:
+                    u = pwd.getpwuid(tarinfo.uid)[2]
+                except KeyError:
+                    u = os.getuid()
+            try:
+                if tarinfo.issym() and hasattr(os, "lchown"):
+                    os.lchown(targetpath, u, g)
+                else:
+                    if sys.platform != "os2emx":
+                        os.chown(targetpath, u, g)
+            except EnvironmentError, e:
+                raise ExtractError("could not change owner")
+
+    def chmod(self, tarinfo, targetpath):
+        """Set file permissions of targetpath according to tarinfo.
+        """
+        if hasattr(os, 'chmod'):
+            try:
+                os.chmod(targetpath, tarinfo.mode)
+            except EnvironmentError, e:
+                raise ExtractError("could not change mode")
+
+    def utime(self, tarinfo, targetpath):
+        """Set modification time of targetpath according to tarinfo.
+        """
+        if not hasattr(os, 'utime'):
+            return
+        if sys.platform == "win32" and tarinfo.isdir():
+            # According to msdn.microsoft.com, it is an error (EACCES)
+            # to use utime() on directories.
+            return
+        try:
+            os.utime(targetpath, (tarinfo.mtime, tarinfo.mtime))
+        except EnvironmentError, e:
+            raise ExtractError("could not change modification time")
+
+    #--------------------------------------------------------------------------
+    def next(self):
+        """Return the next member of the archive as a TarInfo object, when
+           TarFile is opened for reading. Return None if there is no more
+           available.
+        """
+        self._check("ra")
+        if self.firstmember is not None:
+            m = self.firstmember
+            self.firstmember = None
+            return m
+
+        # Read the next block.
+        self.fileobj.seek(self.offset)
+        while True:
+            buf = self.fileobj.read(BLOCKSIZE)
+            if not buf:
+                return None
+
+            try:
+                tarinfo = TarInfo.frombuf(buf)
+
+                # Set the TarInfo object's offset to the current position of the
+                # TarFile and set self.offset to the position where the data blocks
+                # should begin.
+                tarinfo.offset = self.offset
+                self.offset += BLOCKSIZE
+
+                tarinfo = self.proc_member(tarinfo)
+
+            except ValueError, e:
+                if self.ignore_zeros:
+                    self._dbg(2, "0x%X: empty or invalid block: %s" %
+                              (self.offset, e))
+                    self.offset += BLOCKSIZE
+                    continue
+                else:
+                    if self.offset == 0:
+                        raise ReadError("empty, unreadable or compressed "
+                                        "file: %s" % e)
+                    return None
+            break
+
+        # Some old tar programs represent a directory as a regular
+        # file with a trailing slash.
+        if tarinfo.isreg() and tarinfo.name.endswith("/"):
+            tarinfo.type = DIRTYPE
+
+        # Directory names should have a '/' at the end.
+        if tarinfo.isdir():
+            tarinfo.name += "/"
+
+        self.members.append(tarinfo)
+        return tarinfo
+
+    #--------------------------------------------------------------------------
+    # The following are methods that are called depending on the type of a
+    # member. The entry point is proc_member() which is called with a TarInfo
+    # object created from the header block from the current offset. The
+    # proc_member() method can be overridden in a subclass to add custom
+    # proc_*() methods. A proc_*() method MUST implement the following
+    # operations:
+    # 1. Set tarinfo.offset_data to the position where the data blocks begin,
+    #    if there is data that follows.
+    # 2. Set self.offset to the position where the next member's header will
+    #    begin.
+    # 3. Return tarinfo or another valid TarInfo object.
+    def proc_member(self, tarinfo):
+        """Choose the right processing method for tarinfo depending
+           on its type and call it.
+        """
+        if tarinfo.type in (GNUTYPE_LONGNAME, GNUTYPE_LONGLINK):
+            return self.proc_gnulong(tarinfo)
+        elif tarinfo.type == GNUTYPE_SPARSE:
+            return self.proc_sparse(tarinfo)
+        else:
+            return self.proc_builtin(tarinfo)
+
+    def proc_builtin(self, tarinfo):
+        """Process a builtin type member or an unknown member
+           which will be treated as a regular file.
+        """
+        tarinfo.offset_data = self.offset
+        if tarinfo.isreg() or tarinfo.type not in SUPPORTED_TYPES:
+            # Skip the following data blocks.
+            self.offset += self._block(tarinfo.size)
+        return tarinfo
+
+    def proc_gnulong(self, tarinfo):
+        """Process the blocks that hold a GNU longname
+           or longlink member.
+        """
+        buf = ""
+        count = tarinfo.size
+        while count > 0:
+            block = self.fileobj.read(BLOCKSIZE)
+            buf += block
+            self.offset += BLOCKSIZE
+            count -= BLOCKSIZE
+
+        # Fetch the next header and process it.
+        b = self.fileobj.read(BLOCKSIZE)
+        t = TarInfo.frombuf(b)
+        t.offset = self.offset
+        self.offset += BLOCKSIZE
+        next = self.proc_member(t)
+
+        # Patch the TarInfo object from the next header with
+        # the longname information.
+        next.offset = tarinfo.offset
+        if tarinfo.type == GNUTYPE_LONGNAME:
+            next.name = buf.rstrip(NUL)
+        elif tarinfo.type == GNUTYPE_LONGLINK:
+            next.linkname = buf.rstrip(NUL)
+
+        return next
+
+    def proc_sparse(self, tarinfo):
+        """Process a GNU sparse header plus extra headers.
+        """
+        buf = tarinfo.buf
+        sp = _ringbuffer()
+        pos = 386
+        lastpos = 0L
+        realpos = 0L
+        # There are 4 possible sparse structs in the
+        # first header.
+        for i in xrange(4):
+            try:
+                offset = nti(buf[pos:pos + 12])
+                numbytes = nti(buf[pos + 12:pos + 24])
+            except ValueError:
+                break
+            if offset > lastpos:
+                sp.append(_hole(lastpos, offset - lastpos))
+            sp.append(_data(offset, numbytes, realpos))
+            realpos += numbytes
+            lastpos = offset + numbytes
+            pos += 24
+
+        isextended = ord(buf[482])
+        origsize = nti(buf[483:495])
+
+        # If the isextended flag is given,
+        # there are extra headers to process.
+        while isextended == 1:
+            buf = self.fileobj.read(BLOCKSIZE)
+            self.offset += BLOCKSIZE
+            pos = 0
+            for i in xrange(21):
+                try:
+                    offset = nti(buf[pos:pos + 12])
+                    numbytes = nti(buf[pos + 12:pos + 24])
+                except ValueError:
+                    break
+                if offset > lastpos:
+                    sp.append(_hole(lastpos, offset - lastpos))
+                sp.append(_data(offset, numbytes, realpos))
+                realpos += numbytes
+                lastpos = offset + numbytes
+                pos += 24
+            isextended = ord(buf[504])
+
+        if lastpos < origsize:
+            sp.append(_hole(lastpos, origsize - lastpos))
+
+        tarinfo.sparse = sp
+
+        tarinfo.offset_data = self.offset
+        self.offset += self._block(tarinfo.size)
+        tarinfo.size = origsize
+
+        return tarinfo
+
+    #--------------------------------------------------------------------------
+    # Little helper methods:
+
+    def _block(self, count):
+        """Round up a byte count by BLOCKSIZE and return it,
+           e.g. _block(834) => 1024.
+        """
+        blocks, remainder = divmod(count, BLOCKSIZE)
+        if remainder:
+            blocks += 1
+        return blocks * BLOCKSIZE
+
+    def _getmember(self, name, tarinfo=None):
+        """Find an archive member by name from bottom to top.
+           If tarinfo is given, it is used as the starting point.
+        """
+        # Ensure that all members have been loaded.
+        members = self.getmembers()
+
+        if tarinfo is None:
+            end = len(members)
+        else:
+            end = members.index(tarinfo)
+
+        for i in xrange(end - 1, -1, -1):
+            if name == members[i].name:
+                return members[i]
+
+    def _load(self):
+        """Read through the entire archive file and look for readable
+           members.
+        """
+        while True:
+            tarinfo = self.next()
+            if tarinfo is None:
+                break
+        self._loaded = True
+
+    def _check(self, mode=None):
+        """Check if TarFile is still open, and if the operation's mode
+           corresponds to TarFile's mode.
+        """
+        if self.closed:
+            raise IOError("%s is closed" % self.__class__.__name__)
+        if mode is not None and self._mode not in mode:
+            raise IOError("bad operation for mode %r" % self._mode)
+
+    def __iter__(self):
+        """Provide an iterator object.
+        """
+        if self._loaded:
+            return iter(self.members)
+        else:
+            return TarIter(self)
+
+    def _dbg(self, level, msg):
+        """Write debugging output to sys.stderr.
+        """
+        if level <= self.debug:
+            print >> sys.stderr, msg
+# class TarFile
+
+class TarIter:
+    """Iterator Class.
+
+       for tarinfo in TarFile(...):
+           suite...
+    """
+
+    def __init__(self, tarfile):
+        """Construct a TarIter object.
+        """
+        self.tarfile = tarfile
+        self.index = 0
+    def __iter__(self):
+        """Return iterator object.
+        """
+        return self
+    def next(self):
+        """Return the next item using TarFile's next() method.
+           When all members have been read, set TarFile as _loaded.
+        """
+        # Fix for SF #1100429: Under rare circumstances it can
+        # happen that getmembers() is called during iteration,
+        # which will cause TarIter to stop prematurely.
+        if not self.tarfile._loaded:
+            tarinfo = self.tarfile.next()
+            if not tarinfo:
+                self.tarfile._loaded = True
+                raise StopIteration
+        else:
+            try:
+                tarinfo = self.tarfile.members[self.index]
+            except IndexError:
+                raise StopIteration
+        self.index += 1
+        return tarinfo
+
+# Helper classes for sparse file support
+class _section:
+    """Base class for _data and _hole.
+    """
+    def __init__(self, offset, size):
+        self.offset = offset
+        self.size = size
+    def __contains__(self, offset):
+        return self.offset <= offset < self.offset + self.size
+
+class _data(_section):
+    """Represent a data section in a sparse file.
+    """
+    def __init__(self, offset, size, realpos):
+        _section.__init__(self, offset, size)
+        self.realpos = realpos
+
+class _hole(_section):
+    """Represent a hole section in a sparse file.
+    """
+    pass
+
+class _ringbuffer(list):
+    """Ringbuffer class which increases performance
+       over a regular list.
+    """
+    def __init__(self):
+        self.idx = 0
+    def find(self, offset):
+        idx = self.idx
+        while True:
+            item = self[idx]
+            if offset in item:
+                break
+            idx += 1
+            if idx == len(self):
+                idx = 0
+            if idx == self.idx:
+                # End of File
+                return None
+        self.idx = idx
+        return item
+
+#---------------------------------------------
+# zipfile compatible TarFile class
+#---------------------------------------------
+TAR_PLAIN = 0           # zipfile.ZIP_STORED
+TAR_GZIPPED = 8         # zipfile.ZIP_DEFLATED
+class TarFileCompat:
+    """TarFile class compatible with standard module zipfile's
+       ZipFile class.
+    """
+    def __init__(self, file, mode="r", compression=TAR_PLAIN):
+        if compression == TAR_PLAIN:
+            self.tarfile = TarFile.taropen(file, mode)
+        elif compression == TAR_GZIPPED:
+            self.tarfile = TarFile.gzopen(file, mode)
+        else:
+            raise ValueError("unknown compression constant")
+        if mode[0:1] == "r":
+            members = self.tarfile.getmembers()
+            for m in members:
+                m.filename = m.name
+                m.file_size = m.size
+                m.date_time = time.gmtime(m.mtime)[:6]
+    def namelist(self):
+        return map(lambda m: m.name, self.infolist())
+    def infolist(self):
+        return filter(lambda m: m.type in REGULAR_TYPES,
+                      self.tarfile.getmembers())
+    def printdir(self):
+        self.tarfile.list()
+    def testzip(self):
+        return
+    def getinfo(self, name):
+        return self.tarfile.getmember(name)
+    def read(self, name):
+        return self.tarfile.extractfile(self.tarfile.getmember(name)).read()
+    def write(self, filename, arcname=None, compress_type=None):
+        self.tarfile.add(filename, arcname)
+    def writestr(self, zinfo, bytes):
+        try:
+            from cStringIO import StringIO
+        except ImportError:
+            from StringIO import StringIO
+        import calendar
+        zinfo.name = zinfo.filename
+        zinfo.size = zinfo.file_size
+        zinfo.mtime = calendar.timegm(zinfo.date_time)
+        self.tarfile.addfile(zinfo, StringIO(bytes))
+    def close(self):
+        self.tarfile.close()
+#class TarFileCompat
+
+#--------------------
+# exported functions
+#--------------------
+def is_tarfile(name):
+    """Return True if name points to a tar archive that we
+       are able to handle, else return False.
+    """
+    try:
+        t = open(name)
+        t.close()
+        return True
+    except TarError:
+        return False
+
+open = TarFile.open

Added: vendor/Python/current/Lib/telnetlib.py
===================================================================
--- vendor/Python/current/Lib/telnetlib.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/telnetlib.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,669 @@
+r"""TELNET client class.
+
+Based on RFC 854: TELNET Protocol Specification, by J. Postel and
+J. Reynolds
+
+Example:
+
+>>> from telnetlib import Telnet
+>>> tn = Telnet('www.python.org', 79)   # connect to finger port
+>>> tn.write('guido\r\n')
+>>> print tn.read_all()
+Login       Name               TTY         Idle    When    Where
+guido    Guido van Rossum      pts/2        <Dec  2 11:10> snag.cnri.reston..
+
+>>>
+
+Note that read_all() won't read until eof -- it just reads some data
+-- but it guarantees to read at least one byte unless EOF is hit.
+
+It is possible to pass a Telnet object to select.select() in order to
+wait until more data is available.  Note that in this case,
+read_eager() may return '' even if there was data on the socket,
+because the protocol negotiation may have eaten the data.  This is why
+EOFError is needed in some cases to distinguish between "no data" and
+"connection closed" (since the socket also appears ready for reading
+when it is closed).
+
+To do:
+- option negotiation
+- timeout should be intrinsic to the connection object instead of an
+  option on one of the read calls only
+
+"""
+
+
+# Imported modules
+import sys
+import socket
+import select
+
+__all__ = ["Telnet"]
+
+# Tunable parameters
+DEBUGLEVEL = 0
+
+# Telnet protocol defaults
+TELNET_PORT = 23
+
+# Telnet protocol characters (don't change)
+IAC  = chr(255) # "Interpret As Command"
+DONT = chr(254)
+DO   = chr(253)
+WONT = chr(252)
+WILL = chr(251)
+theNULL = chr(0)
+
+SE  = chr(240)  # Subnegotiation End
+NOP = chr(241)  # No Operation
+DM  = chr(242)  # Data Mark
+BRK = chr(243)  # Break
+IP  = chr(244)  # Interrupt process
+AO  = chr(245)  # Abort output
+AYT = chr(246)  # Are You There
+EC  = chr(247)  # Erase Character
+EL  = chr(248)  # Erase Line
+GA  = chr(249)  # Go Ahead
+SB =  chr(250)  # Subnegotiation Begin
+
+
+# Telnet protocol options code (don't change)
+# These ones all come from arpa/telnet.h
+BINARY = chr(0) # 8-bit data path
+ECHO = chr(1) # echo
+RCP = chr(2) # prepare to reconnect
+SGA = chr(3) # suppress go ahead
+NAMS = chr(4) # approximate message size
+STATUS = chr(5) # give status
+TM = chr(6) # timing mark
+RCTE = chr(7) # remote controlled transmission and echo
+NAOL = chr(8) # negotiate about output line width
+NAOP = chr(9) # negotiate about output page size
+NAOCRD = chr(10) # negotiate about CR disposition
+NAOHTS = chr(11) # negotiate about horizontal tabstops
+NAOHTD = chr(12) # negotiate about horizontal tab disposition
+NAOFFD = chr(13) # negotiate about formfeed disposition
+NAOVTS = chr(14) # negotiate about vertical tab stops
+NAOVTD = chr(15) # negotiate about vertical tab disposition
+NAOLFD = chr(16) # negotiate about output LF disposition
+XASCII = chr(17) # extended ascii character set
+LOGOUT = chr(18) # force logout
+BM = chr(19) # byte macro
+DET = chr(20) # data entry terminal
+SUPDUP = chr(21) # supdup protocol
+SUPDUPOUTPUT = chr(22) # supdup output
+SNDLOC = chr(23) # send location
+TTYPE = chr(24) # terminal type
+EOR = chr(25) # end or record
+TUID = chr(26) # TACACS user identification
+OUTMRK = chr(27) # output marking
+TTYLOC = chr(28) # terminal location number
+VT3270REGIME = chr(29) # 3270 regime
+X3PAD = chr(30) # X.3 PAD
+NAWS = chr(31) # window size
+TSPEED = chr(32) # terminal speed
+LFLOW = chr(33) # remote flow control
+LINEMODE = chr(34) # Linemode option
+XDISPLOC = chr(35) # X Display Location
+OLD_ENVIRON = chr(36) # Old - Environment variables
+AUTHENTICATION = chr(37) # Authenticate
+ENCRYPT = chr(38) # Encryption option
+NEW_ENVIRON = chr(39) # New - Environment variables
+# the following ones come from
+# http://www.iana.org/assignments/telnet-options
+# Unfortunately, that document does not assign identifiers
+# to all of them, so we are making them up
+TN3270E = chr(40) # TN3270E
+XAUTH = chr(41) # XAUTH
+CHARSET = chr(42) # CHARSET
+RSP = chr(43) # Telnet Remote Serial Port
+COM_PORT_OPTION = chr(44) # Com Port Control Option
+SUPPRESS_LOCAL_ECHO = chr(45) # Telnet Suppress Local Echo
+TLS = chr(46) # Telnet Start TLS
+KERMIT = chr(47) # KERMIT
+SEND_URL = chr(48) # SEND-URL
+FORWARD_X = chr(49) # FORWARD_X
+PRAGMA_LOGON = chr(138) # TELOPT PRAGMA LOGON
+SSPI_LOGON = chr(139) # TELOPT SSPI LOGON
+PRAGMA_HEARTBEAT = chr(140) # TELOPT PRAGMA HEARTBEAT
+EXOPL = chr(255) # Extended-Options-List
+NOOPT = chr(0)
+
+class Telnet:
+
+    """Telnet interface class.
+
+    An instance of this class represents a connection to a telnet
+    server.  The instance is initially not connected; the open()
+    method must be used to establish a connection.  Alternatively, the
+    host name and optional port number can be passed to the
+    constructor, too.
+
+    Don't try to reopen an already connected instance.
+
+    This class has many read_*() methods.  Note that some of them
+    raise EOFError when the end of the connection is read, because
+    they can return an empty string for other reasons.  See the
+    individual doc strings.
+
+    read_until(expected, [timeout])
+        Read until the expected string has been seen, or a timeout is
+        hit (default is no timeout); may block.
+
+    read_all()
+        Read all data until EOF; may block.
+
+    read_some()
+        Read at least one byte or EOF; may block.
+
+    read_very_eager()
+        Read all data available already queued or on the socket,
+        without blocking.
+
+    read_eager()
+        Read either data already queued or some data available on the
+        socket, without blocking.
+
+    read_lazy()
+        Read all data in the raw queue (processing it first), without
+        doing any socket I/O.
+
+    read_very_lazy()
+        Reads all data in the cooked queue, without doing any socket
+        I/O.
+
+    read_sb_data()
+        Reads available data between SB ... SE sequence. Don't block.
+
+    set_option_negotiation_callback(callback)
+        Each time a telnet option is read on the input flow, this callback
+        (if set) is called with the following parameters :
+        callback(telnet socket, command, option)
+            option will be chr(0) when there is no option.
+        No other action is done afterwards by telnetlib.
+
+    """
+
+    def __init__(self, host=None, port=0):
+        """Constructor.
+
+        When called without arguments, create an unconnected instance.
+        With a hostname argument, it connects the instance; a port
+        number is optional.
+
+        """
+        self.debuglevel = DEBUGLEVEL
+        self.host = host
+        self.port = port
+        self.sock = None
+        self.rawq = ''
+        self.irawq = 0
+        self.cookedq = ''
+        self.eof = 0
+        self.iacseq = '' # Buffer for IAC sequence.
+        self.sb = 0 # flag for SB and SE sequence.
+        self.sbdataq = ''
+        self.option_callback = None
+        if host is not None:
+            self.open(host, port)
+
+    def open(self, host, port=0):
+        """Connect to a host.
+
+        The optional second argument is the port number, which
+        defaults to the standard telnet port (23).
+
+        Don't try to reopen an already connected instance.
+
+        """
+        self.eof = 0
+        if not port:
+            port = TELNET_PORT
+        self.host = host
+        self.port = port
+        msg = "getaddrinfo returns an empty list"
+        for res in socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM):
+            af, socktype, proto, canonname, sa = res
+            try:
+                self.sock = socket.socket(af, socktype, proto)
+                self.sock.connect(sa)
+            except socket.error, msg:
+                if self.sock:
+                    self.sock.close()
+                self.sock = None
+                continue
+            break
+        if not self.sock:
+            raise socket.error, msg
+
+    def __del__(self):
+        """Destructor -- close the connection."""
+        self.close()
+
+    def msg(self, msg, *args):
+        """Print a debug message, when the debug level is > 0.
+
+        If extra arguments are present, they are substituted in the
+        message using the standard string formatting operator.
+
+        """
+        if self.debuglevel > 0:
+            print 'Telnet(%s,%d):' % (self.host, self.port),
+            if args:
+                print msg % args
+            else:
+                print msg
+
+    def set_debuglevel(self, debuglevel):
+        """Set the debug level.
+
+        The higher it is, the more debug output you get (on sys.stdout).
+
+        """
+        self.debuglevel = debuglevel
+
+    def close(self):
+        """Close the connection."""
+        if self.sock:
+            self.sock.close()
+        self.sock = 0
+        self.eof = 1
+        self.iacseq = ''
+        self.sb = 0
+
+    def get_socket(self):
+        """Return the socket object used internally."""
+        return self.sock
+
+    def fileno(self):
+        """Return the fileno() of the socket object used internally."""
+        return self.sock.fileno()
+
+    def write(self, buffer):
+        """Write a string to the socket, doubling any IAC characters.
+
+        Can block if the connection is blocked.  May raise
+        socket.error if the connection is closed.
+
+        """
+        if IAC in buffer:
+            buffer = buffer.replace(IAC, IAC+IAC)
+        self.msg("send %r", buffer)
+        self.sock.sendall(buffer)
+
+    def read_until(self, match, timeout=None):
+        """Read until a given string is encountered or until timeout.
+
+        When no match is found, return whatever is available instead,
+        possibly the empty string.  Raise EOFError if the connection
+        is closed and no cooked data is available.
+
+        """
+        n = len(match)
+        self.process_rawq()
+        i = self.cookedq.find(match)
+        if i >= 0:
+            i = i+n
+            buf = self.cookedq[:i]
+            self.cookedq = self.cookedq[i:]
+            return buf
+        s_reply = ([self], [], [])
+        s_args = s_reply
+        if timeout is not None:
+            s_args = s_args + (timeout,)
+            from time import time
+            time_start = time()
+        while not self.eof and select.select(*s_args) == s_reply:
+            i = max(0, len(self.cookedq)-n)
+            self.fill_rawq()
+            self.process_rawq()
+            i = self.cookedq.find(match, i)
+            if i >= 0:
+                i = i+n
+                buf = self.cookedq[:i]
+                self.cookedq = self.cookedq[i:]
+                return buf
+            if timeout is not None:
+                elapsed = time() - time_start
+                if elapsed >= timeout:
+                    break
+                s_args = s_reply + (timeout-elapsed,)
+        return self.read_very_lazy()
+
+    def read_all(self):
+        """Read all data until EOF; block until connection closed."""
+        self.process_rawq()
+        while not self.eof:
+            self.fill_rawq()
+            self.process_rawq()
+        buf = self.cookedq
+        self.cookedq = ''
+        return buf
+
+    def read_some(self):
+        """Read at least one byte of cooked data unless EOF is hit.
+
+        Return '' if EOF is hit.  Block if no data is immediately
+        available.
+
+        """
+        self.process_rawq()
+        while not self.cookedq and not self.eof:
+            self.fill_rawq()
+            self.process_rawq()
+        buf = self.cookedq
+        self.cookedq = ''
+        return buf
+
+    def read_very_eager(self):
+        """Read everything that's possible without blocking in I/O (eager).
+
+        Raise EOFError if connection closed and no cooked data
+        available.  Return '' if no cooked data available otherwise.
+        Don't block unless in the midst of an IAC sequence.
+
+        """
+        self.process_rawq()
+        while not self.eof and self.sock_avail():
+            self.fill_rawq()
+            self.process_rawq()
+        return self.read_very_lazy()
+
+    def read_eager(self):
+        """Read readily available data.
+
+        Raise EOFError if connection closed and no cooked data
+        available.  Return '' if no cooked data available otherwise.
+        Don't block unless in the midst of an IAC sequence.
+
+        """
+        self.process_rawq()
+        while not self.cookedq and not self.eof and self.sock_avail():
+            self.fill_rawq()
+            self.process_rawq()
+        return self.read_very_lazy()
+
+    def read_lazy(self):
+        """Process and return data that's already in the queues (lazy).
+
+        Raise EOFError if connection closed and no data available.
+        Return '' if no cooked data available otherwise.  Don't block
+        unless in the midst of an IAC sequence.
+
+        """
+        self.process_rawq()
+        return self.read_very_lazy()
+
+    def read_very_lazy(self):
+        """Return any data available in the cooked queue (very lazy).
+
+        Raise EOFError if connection closed and no data available.
+        Return '' if no cooked data available otherwise.  Don't block.
+
+        """
+        buf = self.cookedq
+        self.cookedq = ''
+        if not buf and self.eof and not self.rawq:
+            raise EOFError, 'telnet connection closed'
+        return buf
+
+    def read_sb_data(self):
+        """Return any data available in the SB ... SE queue.
+
+        Return '' if no SB ... SE available. Should only be called
+        after seeing a SB or SE command. When a new SB command is
+        found, old unread SB data will be discarded. Don't block.
+
+        """
+        buf = self.sbdataq
+        self.sbdataq = ''
+        return buf
+
+    def set_option_negotiation_callback(self, callback):
+        """Provide a callback function called after each receipt of a telnet option."""
+        self.option_callback = callback
+
+    def process_rawq(self):
+        """Transfer from raw queue to cooked queue.
+
+        Set self.eof when connection is closed.  Don't block unless in
+        the midst of an IAC sequence.
+
+        """
+        buf = ['', '']
+        try:
+            while self.rawq:
+                c = self.rawq_getchar()
+                if not self.iacseq:
+                    if c == theNULL:
+                        continue
+                    if c == "\021":
+                        continue
+                    if c != IAC:
+                        buf[self.sb] = buf[self.sb] + c
+                        continue
+                    else:
+                        self.iacseq += c
+                elif len(self.iacseq) == 1:
+                    # 'IAC: IAC CMD [OPTION only for WILL/WONT/DO/DONT]'
+                    if c in (DO, DONT, WILL, WONT):
+                        self.iacseq += c
+                        continue
+
+                    self.iacseq = ''
+                    if c == IAC:
+                        buf[self.sb] = buf[self.sb] + c
+                    else:
+                        if c == SB: # SB ... SE start.
+                            self.sb = 1
+                            self.sbdataq = ''
+                        elif c == SE:
+                            self.sb = 0
+                            self.sbdataq = self.sbdataq + buf[1]
+                            buf[1] = ''
+                        if self.option_callback:
+                            # Callback is supposed to look into
+                            # the sbdataq
+                            self.option_callback(self.sock, c, NOOPT)
+                        else:
+                            # We can't offer automatic processing of
+                            # suboptions. Alas, we should not get any
+                            # unless we did a WILL/DO before.
+                            self.msg('IAC %d not recognized' % ord(c))
+                elif len(self.iacseq) == 2:
+                    cmd = self.iacseq[1]
+                    self.iacseq = ''
+                    opt = c
+                    if cmd in (DO, DONT):
+                        self.msg('IAC %s %d',
+                            cmd == DO and 'DO' or 'DONT', ord(opt))
+                        if self.option_callback:
+                            self.option_callback(self.sock, cmd, opt)
+                        else:
+                            self.sock.sendall(IAC + WONT + opt)
+                    elif cmd in (WILL, WONT):
+                        self.msg('IAC %s %d',
+                            cmd == WILL and 'WILL' or 'WONT', ord(opt))
+                        if self.option_callback:
+                            self.option_callback(self.sock, cmd, opt)
+                        else:
+                            self.sock.sendall(IAC + DONT + opt)
+        except EOFError: # raised by self.rawq_getchar()
+            self.iacseq = '' # Reset on EOF
+            self.sb = 0
+            pass
+        self.cookedq = self.cookedq + buf[0]
+        self.sbdataq = self.sbdataq + buf[1]
+
+    def rawq_getchar(self):
+        """Get next char from raw queue.
+
+        Block if no data is immediately available.  Raise EOFError
+        when connection is closed.
+
+        """
+        if not self.rawq:
+            self.fill_rawq()
+            if self.eof:
+                raise EOFError
+        c = self.rawq[self.irawq]
+        self.irawq = self.irawq + 1
+        if self.irawq >= len(self.rawq):
+            self.rawq = ''
+            self.irawq = 0
+        return c
+
+    def fill_rawq(self):
+        """Fill raw queue from exactly one recv() system call.
+
+        Block if no data is immediately available.  Set self.eof when
+        connection is closed.
+
+        """
+        if self.irawq >= len(self.rawq):
+            self.rawq = ''
+            self.irawq = 0
+        # The buffer size should be fairly small so as to avoid quadratic
+        # behavior in process_rawq() above
+        buf = self.sock.recv(50)
+        self.msg("recv %r", buf)
+        self.eof = (not buf)
+        self.rawq = self.rawq + buf
+
+    def sock_avail(self):
+        """Test whether data is available on the socket."""
+        return select.select([self], [], [], 0) == ([self], [], [])
+
+    def interact(self):
+        """Interaction function, emulates a very dumb telnet client."""
+        if sys.platform == "win32":
+            self.mt_interact()
+            return
+        while 1:
+            rfd, wfd, xfd = select.select([self, sys.stdin], [], [])
+            if self in rfd:
+                try:
+                    text = self.read_eager()
+                except EOFError:
+                    print '*** Connection closed by remote host ***'
+                    break
+                if text:
+                    sys.stdout.write(text)
+                    sys.stdout.flush()
+            if sys.stdin in rfd:
+                line = sys.stdin.readline()
+                if not line:
+                    break
+                self.write(line)
+
+    def mt_interact(self):
+        """Multithreaded version of interact()."""
+        import thread
+        thread.start_new_thread(self.listener, ())
+        while 1:
+            line = sys.stdin.readline()
+            if not line:
+                break
+            self.write(line)
+
+    def listener(self):
+        """Helper for mt_interact() -- this executes in the other thread."""
+        while 1:
+            try:
+                data = self.read_eager()
+            except EOFError:
+                print '*** Connection closed by remote host ***'
+                return
+            if data:
+                sys.stdout.write(data)
+            else:
+                sys.stdout.flush()
+
+    def expect(self, list, timeout=None):
+        """Read until one from a list of a regular expressions matches.
+
+        The first argument is a list of regular expressions, either
+        compiled (re.RegexObject instances) or uncompiled (strings).
+        The optional second argument is a timeout, in seconds; default
+        is no timeout.
+
+        Return a tuple of three items: the index in the list of the
+        first regular expression that matches; the match object
+        returned; and the text read up till and including the match.
+
+        If EOF is read and no text was read, raise EOFError.
+        Otherwise, when nothing matches, return (-1, None, text) where
+        text is the text received so far (may be the empty string if a
+        timeout happened).
+
+        If a regular expression ends with a greedy match (e.g. '.*')
+        or if more than one expression can match the same input, the
+        results are undeterministic, and may depend on the I/O timing.
+
+        """
+        re = None
+        list = list[:]
+        indices = range(len(list))
+        for i in indices:
+            if not hasattr(list[i], "search"):
+                if not re: import re
+                list[i] = re.compile(list[i])
+        if timeout is not None:
+            from time import time
+            time_start = time()
+        while 1:
+            self.process_rawq()
+            for i in indices:
+                m = list[i].search(self.cookedq)
+                if m:
+                    e = m.end()
+                    text = self.cookedq[:e]
+                    self.cookedq = self.cookedq[e:]
+                    return (i, m, text)
+            if self.eof:
+                break
+            if timeout is not None:
+                elapsed = time() - time_start
+                if elapsed >= timeout:
+                    break
+                s_args = ([self.fileno()], [], [], timeout-elapsed)
+                r, w, x = select.select(*s_args)
+                if not r:
+                    break
+            self.fill_rawq()
+        text = self.read_very_lazy()
+        if not text and self.eof:
+            raise EOFError
+        return (-1, None, text)
+
+
+def test():
+    """Test program for telnetlib.
+
+    Usage: python telnetlib.py [-d] ... [host [port]]
+
+    Default host is localhost; default port is 23.
+
+    """
+    debuglevel = 0
+    while sys.argv[1:] and sys.argv[1] == '-d':
+        debuglevel = debuglevel+1
+        del sys.argv[1]
+    host = 'localhost'
+    if sys.argv[1:]:
+        host = sys.argv[1]
+    port = 0
+    if sys.argv[2:]:
+        portstr = sys.argv[2]
+        try:
+            port = int(portstr)
+        except ValueError:
+            port = socket.getservbyname(portstr, 'tcp')
+    tn = Telnet()
+    tn.set_debuglevel(debuglevel)
+    tn.open(host, port)
+    tn.interact()
+    tn.close()
+
+if __name__ == '__main__':
+    test()

Added: vendor/Python/current/Lib/tempfile.py
===================================================================
--- vendor/Python/current/Lib/tempfile.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/tempfile.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,472 @@
+"""Temporary files.
+
+This module provides generic, low- and high-level interfaces for
+creating temporary files and directories.  The interfaces listed
+as "safe" just below can be used without fear of race conditions.
+Those listed as "unsafe" cannot, and are provided for backward
+compatibility only.
+
+This module also provides some data items to the user:
+
+  TMP_MAX  - maximum number of names that will be tried before
+             giving up.
+  template - the default prefix for all temporary names.
+             You may change this to control the default prefix.
+  tempdir  - If this is set to a string before the first use of
+             any routine from this module, it will be considered as
+             another candidate location to store temporary files.
+"""
+
+__all__ = [
+    "NamedTemporaryFile", "TemporaryFile", # high level safe interfaces
+    "mkstemp", "mkdtemp",                  # low level safe interfaces
+    "mktemp",                              # deprecated unsafe interface
+    "TMP_MAX", "gettempprefix",            # constants
+    "tempdir", "gettempdir"
+   ]
+
+
+# Imports.
+
+import os as _os
+import errno as _errno
+from random import Random as _Random
+
+if _os.name == 'mac':
+    import Carbon.Folder as _Folder
+    import Carbon.Folders as _Folders
+
+try:
+    import fcntl as _fcntl
+except ImportError:
+    def _set_cloexec(fd):
+        pass
+else:
+    def _set_cloexec(fd):
+        try:
+            flags = _fcntl.fcntl(fd, _fcntl.F_GETFD, 0)
+        except IOError:
+            pass
+        else:
+            # flags read successfully, modify
+            flags |= _fcntl.FD_CLOEXEC
+            _fcntl.fcntl(fd, _fcntl.F_SETFD, flags)
+
+
+try:
+    import thread as _thread
+except ImportError:
+    import dummy_thread as _thread
+_allocate_lock = _thread.allocate_lock
+
+_text_openflags = _os.O_RDWR | _os.O_CREAT | _os.O_EXCL
+if hasattr(_os, 'O_NOINHERIT'):
+    _text_openflags |= _os.O_NOINHERIT
+if hasattr(_os, 'O_NOFOLLOW'):
+    _text_openflags |= _os.O_NOFOLLOW
+
+_bin_openflags = _text_openflags
+if hasattr(_os, 'O_BINARY'):
+    _bin_openflags |= _os.O_BINARY
+
+if hasattr(_os, 'TMP_MAX'):
+    TMP_MAX = _os.TMP_MAX
+else:
+    TMP_MAX = 10000
+
+template = "tmp"
+
+tempdir = None
+
+# Internal routines.
+
+_once_lock = _allocate_lock()
+
+if hasattr(_os, "lstat"):
+    _stat = _os.lstat
+elif hasattr(_os, "stat"):
+    _stat = _os.stat
+else:
+    # Fallback.  All we need is something that raises os.error if the
+    # file doesn't exist.
+    def _stat(fn):
+        try:
+            f = open(fn)
+        except IOError:
+            raise _os.error
+        f.close()
+
+def _exists(fn):
+    try:
+        _stat(fn)
+    except _os.error:
+        return False
+    else:
+        return True
+
+class _RandomNameSequence:
+    """An instance of _RandomNameSequence generates an endless
+    sequence of unpredictable strings which can safely be incorporated
+    into file names.  Each string is six characters long.  Multiple
+    threads can safely use the same instance at the same time.
+
+    _RandomNameSequence is an iterator."""
+
+    characters = ("abcdefghijklmnopqrstuvwxyz" +
+                  "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
+                  "0123456789-_")
+
+    def __init__(self):
+        self.mutex = _allocate_lock()
+        self.rng = _Random()
+        self.normcase = _os.path.normcase
+
+    def __iter__(self):
+        return self
+
+    def next(self):
+        m = self.mutex
+        c = self.characters
+        choose = self.rng.choice
+
+        m.acquire()
+        try:
+            letters = [choose(c) for dummy in "123456"]
+        finally:
+            m.release()
+
+        return self.normcase(''.join(letters))
+
+def _candidate_tempdir_list():
+    """Generate a list of candidate temporary directories which
+    _get_default_tempdir will try."""
+
+    dirlist = []
+
+    # First, try the environment.
+    for envname in 'TMPDIR', 'TEMP', 'TMP':
+        dirname = _os.getenv(envname)
+        if dirname: dirlist.append(dirname)
+
+    # Failing that, try OS-specific locations.
+    if _os.name == 'mac':
+        try:
+            fsr = _Folder.FSFindFolder(_Folders.kOnSystemDisk,
+                                              _Folders.kTemporaryFolderType, 1)
+            dirname = fsr.as_pathname()
+            dirlist.append(dirname)
+        except _Folder.error:
+            pass
+    elif _os.name == 'riscos':
+        dirname = _os.getenv('Wimp$ScrapDir')
+        if dirname: dirlist.append(dirname)
+    elif _os.name == 'nt':
+        dirlist.extend([ r'c:\temp', r'c:\tmp', r'\temp', r'\tmp' ])
+    else:
+        dirlist.extend([ '/tmp', '/var/tmp', '/usr/tmp' ])
+
+    # As a last resort, the current directory.
+    try:
+        dirlist.append(_os.getcwd())
+    except (AttributeError, _os.error):
+        dirlist.append(_os.curdir)
+
+    return dirlist
+
+def _get_default_tempdir():
+    """Calculate the default directory to use for temporary files.
+    This routine should be called exactly once.
+
+    We determine whether or not a candidate temp dir is usable by
+    trying to create and write to a file in that directory.  If this
+    is successful, the test file is deleted.  To prevent denial of
+    service, the name of the test file must be randomized."""
+
+    namer = _RandomNameSequence()
+    dirlist = _candidate_tempdir_list()
+    flags = _text_openflags
+
+    for dir in dirlist:
+        if dir != _os.curdir:
+            dir = _os.path.normcase(_os.path.abspath(dir))
+        # Try only a few names per directory.
+        for seq in xrange(100):
+            name = namer.next()
+            filename = _os.path.join(dir, name)
+            try:
+                fd = _os.open(filename, flags, 0600)
+                fp = _os.fdopen(fd, 'w')
+                fp.write('blat')
+                fp.close()
+                _os.unlink(filename)
+                del fp, fd
+                return dir
+            except (OSError, IOError), e:
+                if e[0] != _errno.EEXIST:
+                    break # no point trying more names in this directory
+                pass
+    raise IOError, (_errno.ENOENT,
+                    ("No usable temporary directory found in %s" % dirlist))
+
+_name_sequence = None
+
+def _get_candidate_names():
+    """Common setup sequence for all user-callable interfaces."""
+
+    global _name_sequence
+    if _name_sequence is None:
+        _once_lock.acquire()
+        try:
+            if _name_sequence is None:
+                _name_sequence = _RandomNameSequence()
+        finally:
+            _once_lock.release()
+    return _name_sequence
+
+
+def _mkstemp_inner(dir, pre, suf, flags):
+    """Code common to mkstemp, TemporaryFile, and NamedTemporaryFile."""
+
+    names = _get_candidate_names()
+
+    for seq in xrange(TMP_MAX):
+        name = names.next()
+        file = _os.path.join(dir, pre + name + suf)
+        try:
+            fd = _os.open(file, flags, 0600)
+            _set_cloexec(fd)
+            return (fd, _os.path.abspath(file))
+        except OSError, e:
+            if e.errno == _errno.EEXIST:
+                continue # try again
+            raise
+
+    raise IOError, (_errno.EEXIST, "No usable temporary file name found")
+
+
+# User visible interfaces.
+
+def gettempprefix():
+    """Accessor for tempdir.template."""
+    return template
+
+tempdir = None
+
+def gettempdir():
+    """Accessor for tempdir.tempdir."""
+    global tempdir
+    if tempdir is None:
+        _once_lock.acquire()
+        try:
+            if tempdir is None:
+                tempdir = _get_default_tempdir()
+        finally:
+            _once_lock.release()
+    return tempdir
+
+def mkstemp(suffix="", prefix=template, dir=None, text=False):
+    """mkstemp([suffix, [prefix, [dir, [text]]]])
+    User-callable function to create and return a unique temporary
+    file.  The return value is a pair (fd, name) where fd is the
+    file descriptor returned by os.open, and name is the filename.
+
+    If 'suffix' is specified, the file name will end with that suffix,
+    otherwise there will be no suffix.
+
+    If 'prefix' is specified, the file name will begin with that prefix,
+    otherwise a default prefix is used.
+
+    If 'dir' is specified, the file will be created in that directory,
+    otherwise a default directory is used.
+
+    If 'text' is specified and true, the file is opened in text
+    mode.  Else (the default) the file is opened in binary mode.  On
+    some operating systems, this makes no difference.
+
+    The file is readable and writable only by the creating user ID.
+    If the operating system uses permission bits to indicate whether a
+    file is executable, the file is executable by no one. The file
+    descriptor is not inherited by children of this process.
+
+    Caller is responsible for deleting the file when done with it.
+    """
+
+    if dir is None:
+        dir = gettempdir()
+
+    if text:
+        flags = _text_openflags
+    else:
+        flags = _bin_openflags
+
+    return _mkstemp_inner(dir, prefix, suffix, flags)
+
+
+def mkdtemp(suffix="", prefix=template, dir=None):
+    """mkdtemp([suffix, [prefix, [dir]]])
+    User-callable function to create and return a unique temporary
+    directory.  The return value is the pathname of the directory.
+
+    Arguments are as for mkstemp, except that the 'text' argument is
+    not accepted.
+
+    The directory is readable, writable, and searchable only by the
+    creating user.
+
+    Caller is responsible for deleting the directory when done with it.
+    """
+
+    if dir is None:
+        dir = gettempdir()
+
+    names = _get_candidate_names()
+
+    for seq in xrange(TMP_MAX):
+        name = names.next()
+        file = _os.path.join(dir, prefix + name + suffix)
+        try:
+            _os.mkdir(file, 0700)
+            return file
+        except OSError, e:
+            if e.errno == _errno.EEXIST:
+                continue # try again
+            raise
+
+    raise IOError, (_errno.EEXIST, "No usable temporary directory name found")
+
+def mktemp(suffix="", prefix=template, dir=None):
+    """mktemp([suffix, [prefix, [dir]]])
+    User-callable function to return a unique temporary file name.  The
+    file is not created.
+
+    Arguments are as for mkstemp, except that the 'text' argument is
+    not accepted.
+
+    This function is unsafe and should not be used.  The file name
+    refers to a file that did not exist at some point, but by the time
+    you get around to creating it, someone else may have beaten you to
+    the punch.
+    """
+
+##    from warnings import warn as _warn
+##    _warn("mktemp is a potential security risk to your program",
+##          RuntimeWarning, stacklevel=2)
+
+    if dir is None:
+        dir = gettempdir()
+
+    names = _get_candidate_names()
+    for seq in xrange(TMP_MAX):
+        name = names.next()
+        file = _os.path.join(dir, prefix + name + suffix)
+        if not _exists(file):
+            return file
+
+    raise IOError, (_errno.EEXIST, "No usable temporary filename found")
+
+class _TemporaryFileWrapper:
+    """Temporary file wrapper
+
+    This class provides a wrapper around files opened for
+    temporary use.  In particular, it seeks to automatically
+    remove the file when it is no longer needed.
+    """
+
+    def __init__(self, file, name):
+        self.file = file
+        self.name = name
+        self.close_called = False
+
+    def __getattr__(self, name):
+        file = self.__dict__['file']
+        a = getattr(file, name)
+        if type(a) != type(0):
+            setattr(self, name, a)
+        return a
+
+    # NT provides delete-on-close as a primitive, so we don't need
+    # the wrapper to do anything special.  We still use it so that
+    # file.name is useful (i.e. not "(fdopen)") with NamedTemporaryFile.
+    if _os.name != 'nt':
+
+        # Cache the unlinker so we don't get spurious errors at
+        # shutdown when the module-level "os" is None'd out.  Note
+        # that this must be referenced as self.unlink, because the
+        # name TemporaryFileWrapper may also get None'd out before
+        # __del__ is called.
+        unlink = _os.unlink
+
+        def close(self):
+            if not self.close_called:
+                self.close_called = True
+                self.file.close()
+                self.unlink(self.name)
+
+        def __del__(self):
+            self.close()
+
+def NamedTemporaryFile(mode='w+b', bufsize=-1, suffix="",
+                       prefix=template, dir=None):
+    """Create and return a temporary file.
+    Arguments:
+    'prefix', 'suffix', 'dir' -- as for mkstemp.
+    'mode' -- the mode argument to os.fdopen (default "w+b").
+    'bufsize' -- the buffer size argument to os.fdopen (default -1).
+    The file is created as mkstemp() would do it.
+
+    Returns an object with a file-like interface; the name of the file
+    is accessible as file.name.  The file will be automatically deleted
+    when it is closed.
+    """
+
+    if dir is None:
+        dir = gettempdir()
+
+    if 'b' in mode:
+        flags = _bin_openflags
+    else:
+        flags = _text_openflags
+
+    # Setting O_TEMPORARY in the flags causes the OS to delete
+    # the file when it is closed.  This is only supported by Windows.
+    if _os.name == 'nt':
+        flags |= _os.O_TEMPORARY
+
+    (fd, name) = _mkstemp_inner(dir, prefix, suffix, flags)
+    file = _os.fdopen(fd, mode, bufsize)
+    return _TemporaryFileWrapper(file, name)
+
+if _os.name != 'posix' or _os.sys.platform == 'cygwin':
+    # On non-POSIX and Cygwin systems, assume that we cannot unlink a file
+    # while it is open.
+    TemporaryFile = NamedTemporaryFile
+
+else:
+    def TemporaryFile(mode='w+b', bufsize=-1, suffix="",
+                      prefix=template, dir=None):
+        """Create and return a temporary file.
+        Arguments:
+        'prefix', 'suffix', 'dir' -- as for mkstemp.
+        'mode' -- the mode argument to os.fdopen (default "w+b").
+        'bufsize' -- the buffer size argument to os.fdopen (default -1).
+        The file is created as mkstemp() would do it.
+
+        Returns an object with a file-like interface.  The file has no
+        name, and will cease to exist when it is closed.
+        """
+
+        if dir is None:
+            dir = gettempdir()
+
+        if 'b' in mode:
+            flags = _bin_openflags
+        else:
+            flags = _text_openflags
+
+        (fd, name) = _mkstemp_inner(dir, prefix, suffix, flags)
+        try:
+            _os.unlink(name)
+            return _os.fdopen(fd, mode, bufsize)
+        except:
+            _os.close(fd)
+            raise

Added: vendor/Python/current/Lib/test/185test.db
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Lib/test/185test.db
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Lib/test/README
===================================================================
--- vendor/Python/current/Lib/test/README	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/README	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,423 @@
++++++++++++++++++++++++++++++++
+Writing Python Regression Tests
++++++++++++++++++++++++++++++++
+
+:Author: Skip Montanaro
+:Contact: skip at mojam.com
+
+Introduction
+============
+
+If you add a new module to Python or modify the functionality of an existing
+module, you should write one or more test cases to exercise that new
+functionality.  There are different ways to do this within the regression
+testing facility provided with Python; any particular test should use only
+one of these options.  Each option requires writing a test module using the
+conventions of the selected option:
+
+    - PyUnit_ based tests
+    - doctest_ based tests
+    - "traditional" Python test modules
+
+Regardless of the mechanics of the testing approach you choose,
+you will be writing unit tests (isolated tests of functions and objects
+defined by the module) using white box techniques.  Unlike black box
+testing, where you only have the external interfaces to guide your test case
+writing, in white box testing you can see the code being tested and tailor
+your test cases to exercise it more completely.  In particular, you will be
+able to refer to the C and Python code in the CVS repository when writing
+your regression test cases.
+
+.. _PyUnit:
+.. _unittest: http://www.python.org/doc/current/lib/module-unittest.html
+.. _doctest: http://www.python.org/doc/current/lib/module-doctest.html
+
+PyUnit based tests
+------------------
+The PyUnit_ framework is based on the ideas of unit testing as espoused
+by Kent Beck and the `Extreme Programming`_ (XP) movement.  The specific
+interface provided by the framework is tightly based on the JUnit_
+Java implementation of Beck's original SmallTalk test framework.  Please
+see the documentation of the unittest_ module for detailed information on
+the interface and general guidelines on writing PyUnit based tests.
+
+The test_support helper module provides two functions for use by
+PyUnit based tests in the Python regression testing framework:
+
+- ``run_unittest()`` takes a ``unittest.TestCase`` derived class as a
+  parameter and runs the tests defined in that class
+   
+- ``run_suite()`` takes a populated ``TestSuite`` instance and runs the
+  tests
+   
+``run_suite()`` is preferred because unittest files typically grow multiple
+test classes, and you might as well be prepared.
+
+All test methods in the Python regression framework have names that
+start with "``test_``" and use lower-case names with words separated with
+underscores.
+
+Test methods should *not* have docstrings!  The unittest module prints
+the docstring if there is one, but otherwise prints the function name
+and the full class name.  When there's a problem with a test, the
+latter information makes it easier to find the source for the test
+than the docstring.
+
+All PyUnit-based tests in the Python test suite use boilerplate that
+looks like this (with minor variations)::
+
+    import unittest
+    from test import test_support
+
+    class MyTestCase1(unittest.TestCase):
+
+        # Define setUp and tearDown only if needed
+
+        def setUp(self):
+            unittest.TestCase.setUp(self)
+            ... additional initialization...
+
+        def tearDown(self):
+            ... additional finalization...
+            unittest.TestCase.tearDown(self)
+
+        def test_feature_one(self):
+            # Testing feature one
+            ...unit test for feature one...
+
+        def test_feature_two(self):
+            # Testing feature two
+            ...unit test for feature two...
+
+        ...etc...
+
+    class MyTestCase2(unittest.TestCase):
+        ...same structure as MyTestCase1...
+
+    ...etc...
+
+    def test_main():
+        suite = unittest.TestSuite()
+        suite.addTest(unittest.makeSuite(MyTestCase1))
+        suite.addTest(unittest.makeSuite(MyTestCase2))
+        ...add more suites...
+        test_support.run_suite(suite)
+
+    if __name__ == "__main__":
+        test_main()
+
+This has the advantage that it allows the unittest module to be used
+as a script to run individual tests as well as working well with the
+regrtest framework.
+
+.. _Extreme Programming: http://www.extremeprogramming.org/
+.. _JUnit: http://www.junit.org/
+
+doctest based tests
+-------------------
+Tests written to use doctest_ are actually part of the docstrings for
+the module being tested.  Each test is written as a display of an
+interactive session, including the Python prompts, statements that would
+be typed by the user, and the output of those statements (including
+tracebacks, although only the exception msg needs to be retained then).
+The module in the test package is simply a wrapper that causes doctest
+to run over the tests in the module.  The test for the difflib module
+provides a convenient example::
+
+    import difflib
+    from test import test_support
+    test_support.run_doctest(difflib)
+
+If the test is successful, nothing is written to stdout (so you should not
+create a corresponding output/test_difflib file), but running regrtest
+with -v will give a detailed report, the same as if passing -v to doctest.
+
+A second argument can be passed to run_doctest to tell doctest to search
+``sys.argv`` for -v instead of using test_support's idea of verbosity.  This
+is useful for writing doctest-based tests that aren't simply running a
+doctest'ed Lib module, but contain the doctests themselves.  Then at
+times you may want to run such a test directly as a doctest, independent
+of the regrtest framework.  The tail end of test_descrtut.py is a good
+example::
+
+    def test_main(verbose=None):
+        from test import test_support, test_descrtut
+        test_support.run_doctest(test_descrtut, verbose)
+
+    if __name__ == "__main__":
+        test_main(1)
+
+If run via regrtest, ``test_main()`` is called (by regrtest) without
+specifying verbose, and then test_support's idea of verbosity is used.  But
+when run directly, ``test_main(1)`` is called, and then doctest's idea of
+verbosity is used.
+
+See the documentation for the doctest module for information on
+writing tests using the doctest framework.
+
+"traditional" Python test modules
+---------------------------------
+The mechanics of how the "traditional" test system operates are fairly
+straightforward.  When a test case is run, the output is compared with the
+expected output that is stored in .../Lib/test/output.  If the test runs to
+completion and the actual and expected outputs match, the test succeeds, if
+not, it fails.  If an ``ImportError`` or ``test_support.TestSkipped`` error
+is raised, the test is not run.
+
+Executing Test Cases
+====================
+If you are writing test cases for module spam, you need to create a file
+in .../Lib/test named test_spam.py.  In addition, if the tests are expected
+to write to stdout during a successful run, you also need to create an
+expected output file in .../Lib/test/output named test_spam ("..."
+represents the top-level directory in the Python source tree, the directory
+containing the configure script).  If needed, generate the initial version
+of the test output file by executing::
+
+    ./python Lib/test/regrtest.py -g test_spam.py
+
+from the top-level directory.
+
+Any time you modify test_spam.py you need to generate a new expected
+output file.  Don't forget to desk check the generated output to make sure
+it's really what you expected to find!  All in all it's usually better
+not to have an expected-out file (note that doctest- and unittest-based
+tests do not).
+
+To run a single test after modifying a module, simply run regrtest.py
+without the -g flag::
+
+    ./python Lib/test/regrtest.py test_spam.py
+
+While debugging a regression test, you can of course execute it
+independently of the regression testing framework and see what it prints::
+
+    ./python Lib/test/test_spam.py
+
+To run the entire test suite:
+
+- [UNIX, + other platforms where "make" works] Make the "test" target at the
+  top level::
+
+    make test
+
+- [WINDOWS] Run rt.bat from your PCBuild directory.  Read the comments at
+  the top of rt.bat for the use of special -d, -O and -q options processed
+  by rt.bat.
+
+- [OTHER] You can simply execute the two runs of regrtest (optimized and
+  non-optimized) directly::
+
+    ./python Lib/test/regrtest.py
+    ./python -O Lib/test/regrtest.py
+
+But note that this way picks up whatever .pyc and .pyo files happen to be
+around.  The makefile and rt.bat ways run the tests twice, the first time
+removing all .pyc and .pyo files from the subtree rooted at Lib/.
+
+Test cases generate output based upon values computed by the test code.
+When executed, regrtest.py compares the actual output generated by executing
+the test case with the expected output and reports success or failure.  It
+stands to reason that if the actual and expected outputs are to match, they
+must not contain any machine dependencies.  This means your test cases
+should not print out absolute machine addresses (e.g. the return value of
+the id() builtin function) or floating point numbers with large numbers of
+significant digits (unless you understand what you are doing!).
+
+
+Test Case Writing Tips
+======================
+Writing good test cases is a skilled task and is too complex to discuss in
+detail in this short document.  Many books have been written on the subject.
+I'll show my age by suggesting that Glenford Myers' `"The Art of Software
+Testing"`_, published in 1979, is still the best introduction to the subject
+available.  It is short (177 pages), easy to read, and discusses the major
+elements of software testing, though its publication predates the
+object-oriented software revolution, so doesn't cover that subject at all.
+Unfortunately, it is very expensive (about $100 new).  If you can borrow it
+or find it used (around $20), I strongly urge you to pick up a copy.
+
+The most important goal when writing test cases is to break things.  A test
+case that doesn't uncover a bug is much less valuable than one that does.
+In designing test cases you should pay attention to the following:
+
+    * Your test cases should exercise all the functions and objects defined
+      in the module, not just the ones meant to be called by users of your
+      module.  This may require you to write test code that uses the module
+      in ways you don't expect (explicitly calling internal functions, for
+      example - see test_atexit.py).
+
+    * You should consider any boundary values that may tickle exceptional
+      conditions (e.g. if you were writing regression tests for division,
+      you might well want to generate tests with numerators and denominators
+      at the limits of floating point and integer numbers on the machine
+      performing the tests as well as a denominator of zero).
+
+    * You should exercise as many paths through the code as possible.  This
+      may not always be possible, but is a goal to strive for.  In
+      particular, when considering if statements (or their equivalent), you
+      want to create test cases that exercise both the true and false
+      branches.  For loops, you should create test cases that exercise the
+      loop zero, one and multiple times.
+
+    * You should test with obviously invalid input.  If you know that a
+      function requires an integer input, try calling it with other types of
+      objects to see how it responds.
+
+    * You should test with obviously out-of-range input.  If the domain of a
+      function is only defined for positive integers, try calling it with a
+      negative integer.
+
+    * If you are going to fix a bug that wasn't uncovered by an existing
+      test, try to write a test case that exposes the bug (preferably before
+      fixing it).
+
+    * If you need to create a temporary file, you can use the filename in
+      ``test_support.TESTFN`` to do so.  It is important to remove the file
+      when done; other tests should be able to use the name without cleaning
+      up after your test.
+
+.. _"The Art of Software Testing": 
+        http://www.amazon.com/exec/obidos/ISBN=0471043281
+
+Regression Test Writing Rules
+=============================
+Each test case is different.  There is no "standard" form for a Python
+regression test case, though there are some general rules (note that
+these mostly apply only to the "classic" tests; unittest_- and doctest_-
+based tests should follow the conventions natural to those frameworks)::
+
+    * If your test case detects a failure, raise ``TestFailed`` (found in
+      ``test.test_support``).
+
+    * Import everything you'll need as early as possible.
+
+    * If you'll be importing objects from a module that is at least
+      partially platform-dependent, only import those objects you need for
+      the current test case to avoid spurious ``ImportError`` exceptions
+      that prevent the test from running to completion.
+
+    * Print all your test case results using the ``print`` statement.  For
+      non-fatal errors, print an error message (or omit a successful
+      completion print) to indicate the failure, but proceed instead of
+      raising ``TestFailed``.
+
+    * Use ``assert`` sparingly, if at all.  It's usually better to just print
+      what you got, and rely on regrtest's got-vs-expected comparison to
+      catch deviations from what you expect.  ``assert`` statements aren't
+      executed at all when regrtest is run in -O mode; and, because they
+      cause the test to stop immediately, can lead to a long & tedious
+      test-fix, test-fix, test-fix, ... cycle when things are badly broken
+      (and note that "badly broken" often includes running the test suite
+      for the first time on new platforms or under new implementations of
+      the language).
+
+Miscellaneous
+=============
+There is a test_support module in the test package you can import for
+your test case.  Import this module using either::
+
+    import test.test_support
+
+or::
+
+    from test import test_support
+
+test_support provides the following useful objects:
+
+    * ``TestFailed`` - raise this exception when your regression test detects
+      a failure.
+
+    * ``TestSkipped`` - raise this if the test could not be run because the
+      platform doesn't offer all the required facilities (like large
+      file support), even if all the required modules are available.
+
+    * ``ResourceDenied`` - this is raised when a test requires a resource that
+      is not available.  Primarily used by 'requires'.
+
+    * ``verbose`` - you can use this variable to control print output.  Many
+      modules use it.  Search for "verbose" in the test_*.py files to see
+      lots of examples.
+
+    * ``forget(module_name)`` - attempts to cause Python to "forget" that it
+      loaded a module and erase any PYC files.
+
+    * ``is_resource_enabled(resource)`` - Returns a boolean based on whether
+      the resource is enabled or not.
+
+    * ``requires(resource [, msg])`` - if the required resource is not
+      available the ResourceDenied exception is raised.
+    
+    * ``verify(condition, reason='test failed')``.  Use this instead of::
+
+          assert condition[, reason]
+
+      ``verify()`` has two advantages over ``assert``:  it works even in -O
+      mode, and it raises ``TestFailed`` on failure instead of
+      ``AssertionError``.
+
+    * ``have_unicode`` - true if Unicode is available, false otherwise.
+
+    * ``is_jython`` - true if the interpreter is Jython, false otherwise.
+
+    * ``TESTFN`` - a string that should always be used as the filename when
+      you need to create a temp file.  Also use ``try``/``finally`` to
+      ensure that your temp files are deleted before your test completes.
+      Note that you cannot unlink an open file on all operating systems, so
+      also be sure to close temp files before trying to unlink them.
+
+    * ``sortdict(dict)`` - acts like ``repr(dict.items())``, but sorts the
+      items first.  This is important when printing a dict value, because
+      the order of items produced by ``dict.items()`` is not defined by the
+      language.
+
+    * ``findfile(file)`` - you can call this function to locate a file
+      somewhere along sys.path or in the Lib/test tree - see
+      test_linuxaudiodev.py for an example of its use.
+
+    * ``fcmp(x,y)`` - you can call this function to compare two floating
+      point numbers when you expect them to only be approximately equal
+      withing a fuzz factor (``test_support.FUZZ``, which defaults to 1e-6).
+
+    * ``check_syntax(statement)`` - make sure that the statement is *not*
+      correct Python syntax.
+
+
+Python and C statement coverage results are currently available at
+
+    http://www.musi-cal.com/~skip/python/Python/dist/src/
+
+As of this writing (July, 2000) these results are being generated nightly.
+You can refer to the summaries and the test coverage output files to see
+where coverage is adequate or lacking and write test cases to beef up the
+coverage.
+
+Some Non-Obvious regrtest Features
+==================================
+    * Automagic test detection:  When you create a new test file
+      test_spam.py, you do not need to modify regrtest (or anything else)
+      to advertise its existence.  regrtest searches for and runs all
+      modules in the test directory with names of the form test_xxx.py.
+
+    * Miranda output:  If, when running test_spam.py, regrtest does not
+      find an expected-output file test/output/test_spam, regrtest
+      pretends that it did find one, containing the single line
+
+      test_spam
+
+      This allows new tests that don't expect to print anything to stdout
+      to not bother creating expected-output files.
+
+    * Two-stage testing:  To run test_spam.py, regrtest imports test_spam
+      as a module.  Most tests run to completion as a side-effect of
+      getting imported.  After importing test_spam, regrtest also executes
+      ``test_spam.test_main()``, if test_spam has a ``test_main`` attribute.
+      This is rarely required with the "traditional" Python tests, and
+      you shouldn't create a module global with name test_main unless
+      you're specifically exploiting this gimmick.  This usage does
+      prove useful with PyUnit-based tests as well, however; defining
+      a ``test_main()`` which is run by regrtest and a script-stub in the
+      test module ("``if __name__ == '__main__': test_main()``") allows
+      the test to be used like any other Python test and also work
+      with the unittest.py-as-a-script approach, allowing a developer
+      to run specific tests from the command line.

Added: vendor/Python/current/Lib/test/__init__.py
===================================================================
--- vendor/Python/current/Lib/test/__init__.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/__init__.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1 @@
+# Dummy file to make this directory a package.

Added: vendor/Python/current/Lib/test/audiotest.au
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Lib/test/audiotest.au
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Lib/test/autotest.py
===================================================================
--- vendor/Python/current/Lib/test/autotest.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/autotest.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,6 @@
+# This should be equivalent to running regrtest.py from the cmdline.
+# It can be especially handy if you're in an interactive shell, e.g.,
+# from test import autotest.
+
+from test import regrtest
+regrtest.main()

Added: vendor/Python/current/Lib/test/bad_coding.py
===================================================================
--- vendor/Python/current/Lib/test/bad_coding.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/bad_coding.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1 @@
+# -*- coding: uft-8 -*-

Added: vendor/Python/current/Lib/test/bad_coding2.py
===================================================================
--- vendor/Python/current/Lib/test/bad_coding2.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/bad_coding2.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2 @@
+#coding: utf8
+print '我'

Added: vendor/Python/current/Lib/test/badsyntax_future3.py
===================================================================
--- vendor/Python/current/Lib/test/badsyntax_future3.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/badsyntax_future3.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,10 @@
+"""This is a test"""
+from __future__ import nested_scopes
+from __future__ import rested_snopes
+
+def f(x):
+    def g(y):
+        return x + y
+    return g
+
+result = f(2)(4)

Added: vendor/Python/current/Lib/test/badsyntax_future4.py
===================================================================
--- vendor/Python/current/Lib/test/badsyntax_future4.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/badsyntax_future4.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,10 @@
+"""This is a test"""
+import __future__
+from __future__ import nested_scopes
+
+def f(x):
+    def g(y):
+        return x + y
+    return g
+
+result = f(2)(4)

Added: vendor/Python/current/Lib/test/badsyntax_future5.py
===================================================================
--- vendor/Python/current/Lib/test/badsyntax_future5.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/badsyntax_future5.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,12 @@
+"""This is a test"""
+from __future__ import nested_scopes
+import foo
+from __future__ import nested_scopes
+
+
+def f(x):
+    def g(y):
+        return x + y
+    return g
+
+result = f(2)(4)

Added: vendor/Python/current/Lib/test/badsyntax_future6.py
===================================================================
--- vendor/Python/current/Lib/test/badsyntax_future6.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/badsyntax_future6.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,10 @@
+"""This is a test"""
+"this isn't a doc string"
+from __future__ import nested_scopes
+
+def f(x):
+    def g(y):
+        return x + y
+    return g
+
+result = f(2)(4)

Added: vendor/Python/current/Lib/test/badsyntax_future7.py
===================================================================
--- vendor/Python/current/Lib/test/badsyntax_future7.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/badsyntax_future7.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,11 @@
+"""This is a test"""
+
+from __future__ import nested_scopes; import string; from __future__ import \
+     nested_scopes
+
+def f(x):
+    def g(y):
+        return x + y
+    return g
+
+result = f(2)(4)

Added: vendor/Python/current/Lib/test/badsyntax_future8.py
===================================================================
--- vendor/Python/current/Lib/test/badsyntax_future8.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/badsyntax_future8.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,10 @@
+"""This is a test"""
+
+from __future__ import *
+
+def f(x):
+    def g(y):
+        return x + y
+    return g
+
+print f(2)(4)

Added: vendor/Python/current/Lib/test/badsyntax_future9.py
===================================================================
--- vendor/Python/current/Lib/test/badsyntax_future9.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/badsyntax_future9.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,10 @@
+"""This is a test"""
+
+from __future__ import nested_scopes, braces
+
+def f(x):
+    def g(y):
+        return x + y
+    return g
+
+print f(2)(4)

Added: vendor/Python/current/Lib/test/badsyntax_nocaret.py
===================================================================
--- vendor/Python/current/Lib/test/badsyntax_nocaret.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/badsyntax_nocaret.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2 @@
+def f(x):
+    [x for x in x] = x

Added: vendor/Python/current/Lib/test/cfgparser.1
===================================================================
--- vendor/Python/current/Lib/test/cfgparser.1	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/cfgparser.1	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2 @@
+[Foo Bar]
+foo=newbar

Added: vendor/Python/current/Lib/test/check_soundcard.vbs
===================================================================
--- vendor/Python/current/Lib/test/check_soundcard.vbs	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/check_soundcard.vbs	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,13 @@
+rem Check for a working sound-card - exit with 0 if OK, 1 otherwise.
+set wmi = GetObject("winmgmts:")
+set scs = wmi.InstancesOf("win32_sounddevice")
+for each sc in scs
+   set status = sc.Properties_("Status")
+   wscript.Echo(sc.Properties_("Name") + "/" + status)
+   if status = "OK" then
+       wscript.Quit 0 rem normal exit
+   end if
+next
+rem No sound card found - exit with status code of 1
+wscript.Quit 1
+

Added: vendor/Python/current/Lib/test/cjkencodings_test.py
===================================================================
--- vendor/Python/current/Lib/test/cjkencodings_test.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/cjkencodings_test.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1004 @@
+teststring = {
+'big5': (
+"\xa6\x70\xa6\xf3\xa6\x62\x20\x50\x79\x74\x68\x6f\x6e\x20\xa4\xa4"
+"\xa8\xcf\xa5\xce\xac\x4a\xa6\xb3\xaa\xba\x20\x43\x20\x6c\x69\x62"
+"\x72\x61\x72\x79\x3f\x0a\xa1\x40\xa6\x62\xb8\xea\xb0\x54\xac\xec"
+"\xa7\xde\xa7\xd6\xb3\x74\xb5\x6f\xae\x69\xaa\xba\xa4\xb5\xa4\xd1"
+"\x2c\x20\xb6\x7d\xb5\x6f\xa4\xce\xb4\xfa\xb8\xd5\xb3\x6e\xc5\xe9"
+"\xaa\xba\xb3\x74\xab\xd7\xac\x4f\xa4\xa3\xae\x65\xa9\xbf\xb5\xf8"
+"\xaa\xba\x0a\xbd\xd2\xc3\x44\x2e\x20\xac\xb0\xa5\x5b\xa7\xd6\xb6"
+"\x7d\xb5\x6f\xa4\xce\xb4\xfa\xb8\xd5\xaa\xba\xb3\x74\xab\xd7\x2c"
+"\x20\xa7\xda\xad\xcc\xab\x4b\xb1\x60\xa7\xc6\xb1\xe6\xaf\xe0\xa7"
+"\x51\xa5\xce\xa4\x40\xa8\xc7\xa4\x77\xb6\x7d\xb5\x6f\xa6\x6e\xaa"
+"\xba\x0a\x6c\x69\x62\x72\x61\x72\x79\x2c\x20\xa8\xc3\xa6\xb3\xa4"
+"\x40\xad\xd3\x20\x66\x61\x73\x74\x20\x70\x72\x6f\x74\x6f\x74\x79"
+"\x70\x69\x6e\x67\x20\xaa\xba\x20\x70\x72\x6f\x67\x72\x61\x6d\x6d"
+"\x69\x6e\x67\x20\x6c\x61\x6e\x67\x75\x61\x67\x65\x20\xa5\x69\x0a"
+"\xa8\xd1\xa8\xcf\xa5\xce\x2e\x20\xa5\xd8\xab\x65\xa6\xb3\xb3\x5c"
+"\xb3\x5c\xa6\x68\xa6\x68\xaa\xba\x20\x6c\x69\x62\x72\x61\x72\x79"
+"\x20\xac\x4f\xa5\x48\x20\x43\x20\xbc\x67\xa6\xa8\x2c\x20\xa6\xd3"
+"\x20\x50\x79\x74\x68\x6f\x6e\x20\xac\x4f\xa4\x40\xad\xd3\x0a\x66"
+"\x61\x73\x74\x20\x70\x72\x6f\x74\x6f\x74\x79\x70\x69\x6e\x67\x20"
+"\xaa\xba\x20\x70\x72\x6f\x67\x72\x61\x6d\x6d\x69\x6e\x67\x20\x6c"
+"\x61\x6e\x67\x75\x61\x67\x65\x2e\x20\xac\x47\xa7\xda\xad\xcc\xa7"
+"\xc6\xb1\xe6\xaf\xe0\xb1\x4e\xac\x4a\xa6\xb3\xaa\xba\x0a\x43\x20"
+"\x6c\x69\x62\x72\x61\x72\x79\x20\xae\xb3\xa8\xec\x20\x50\x79\x74"
+"\x68\x6f\x6e\x20\xaa\xba\xc0\xf4\xb9\xd2\xa4\xa4\xb4\xfa\xb8\xd5"
+"\xa4\xce\xbe\xe3\xa6\x58\x2e\x20\xa8\xe4\xa4\xa4\xb3\xcc\xa5\x44"
+"\xad\x6e\xa4\x5d\xac\x4f\xa7\xda\xad\xcc\xa9\xd2\x0a\xad\x6e\xb0"
+"\x51\xbd\xd7\xaa\xba\xb0\xdd\xc3\x44\xb4\x4e\xac\x4f\x3a\x0a\x0a",
+"\xe5\xa6\x82\xe4\xbd\x95\xe5\x9c\xa8\x20\x50\x79\x74\x68\x6f\x6e"
+"\x20\xe4\xb8\xad\xe4\xbd\xbf\xe7\x94\xa8\xe6\x97\xa2\xe6\x9c\x89"
+"\xe7\x9a\x84\x20\x43\x20\x6c\x69\x62\x72\x61\x72\x79\x3f\x0a\xe3"
+"\x80\x80\xe5\x9c\xa8\xe8\xb3\x87\xe8\xa8\x8a\xe7\xa7\x91\xe6\x8a"
+"\x80\xe5\xbf\xab\xe9\x80\x9f\xe7\x99\xbc\xe5\xb1\x95\xe7\x9a\x84"
+"\xe4\xbb\x8a\xe5\xa4\xa9\x2c\x20\xe9\x96\x8b\xe7\x99\xbc\xe5\x8f"
+"\x8a\xe6\xb8\xac\xe8\xa9\xa6\xe8\xbb\x9f\xe9\xab\x94\xe7\x9a\x84"
+"\xe9\x80\x9f\xe5\xba\xa6\xe6\x98\xaf\xe4\xb8\x8d\xe5\xae\xb9\xe5"
+"\xbf\xbd\xe8\xa6\x96\xe7\x9a\x84\x0a\xe8\xaa\xb2\xe9\xa1\x8c\x2e"
+"\x20\xe7\x82\xba\xe5\x8a\xa0\xe5\xbf\xab\xe9\x96\x8b\xe7\x99\xbc"
+"\xe5\x8f\x8a\xe6\xb8\xac\xe8\xa9\xa6\xe7\x9a\x84\xe9\x80\x9f\xe5"
+"\xba\xa6\x2c\x20\xe6\x88\x91\xe5\x80\x91\xe4\xbe\xbf\xe5\xb8\xb8"
+"\xe5\xb8\x8c\xe6\x9c\x9b\xe8\x83\xbd\xe5\x88\xa9\xe7\x94\xa8\xe4"
+"\xb8\x80\xe4\xba\x9b\xe5\xb7\xb2\xe9\x96\x8b\xe7\x99\xbc\xe5\xa5"
+"\xbd\xe7\x9a\x84\x0a\x6c\x69\x62\x72\x61\x72\x79\x2c\x20\xe4\xb8"
+"\xa6\xe6\x9c\x89\xe4\xb8\x80\xe5\x80\x8b\x20\x66\x61\x73\x74\x20"
+"\x70\x72\x6f\x74\x6f\x74\x79\x70\x69\x6e\x67\x20\xe7\x9a\x84\x20"
+"\x70\x72\x6f\x67\x72\x61\x6d\x6d\x69\x6e\x67\x20\x6c\x61\x6e\x67"
+"\x75\x61\x67\x65\x20\xe5\x8f\xaf\x0a\xe4\xbe\x9b\xe4\xbd\xbf\xe7"
+"\x94\xa8\x2e\x20\xe7\x9b\xae\xe5\x89\x8d\xe6\x9c\x89\xe8\xa8\xb1"
+"\xe8\xa8\xb1\xe5\xa4\x9a\xe5\xa4\x9a\xe7\x9a\x84\x20\x6c\x69\x62"
+"\x72\x61\x72\x79\x20\xe6\x98\xaf\xe4\xbb\xa5\x20\x43\x20\xe5\xaf"
+"\xab\xe6\x88\x90\x2c\x20\xe8\x80\x8c\x20\x50\x79\x74\x68\x6f\x6e"
+"\x20\xe6\x98\xaf\xe4\xb8\x80\xe5\x80\x8b\x0a\x66\x61\x73\x74\x20"
+"\x70\x72\x6f\x74\x6f\x74\x79\x70\x69\x6e\x67\x20\xe7\x9a\x84\x20"
+"\x70\x72\x6f\x67\x72\x61\x6d\x6d\x69\x6e\x67\x20\x6c\x61\x6e\x67"
+"\x75\x61\x67\x65\x2e\x20\xe6\x95\x85\xe6\x88\x91\xe5\x80\x91\xe5"
+"\xb8\x8c\xe6\x9c\x9b\xe8\x83\xbd\xe5\xb0\x87\xe6\x97\xa2\xe6\x9c"
+"\x89\xe7\x9a\x84\x0a\x43\x20\x6c\x69\x62\x72\x61\x72\x79\x20\xe6"
+"\x8b\xbf\xe5\x88\xb0\x20\x50\x79\x74\x68\x6f\x6e\x20\xe7\x9a\x84"
+"\xe7\x92\xb0\xe5\xa2\x83\xe4\xb8\xad\xe6\xb8\xac\xe8\xa9\xa6\xe5"
+"\x8f\x8a\xe6\x95\xb4\xe5\x90\x88\x2e\x20\xe5\x85\xb6\xe4\xb8\xad"
+"\xe6\x9c\x80\xe4\xb8\xbb\xe8\xa6\x81\xe4\xb9\x9f\xe6\x98\xaf\xe6"
+"\x88\x91\xe5\x80\x91\xe6\x89\x80\x0a\xe8\xa6\x81\xe8\xa8\x8e\xe8"
+"\xab\x96\xe7\x9a\x84\xe5\x95\x8f\xe9\xa1\x8c\xe5\xb0\xb1\xe6\x98"
+"\xaf\x3a\x0a\x0a"),
+'big5hkscs': (
+"\x88\x45\x88\x5c\x8a\x73\x8b\xda\x8d\xd8\x0a",
+"\xf0\xa0\x84\x8c\xc4\x9a\xe9\xb5\xae\xe7\xbd\x93\xe6\xb4\x86\x0a"),
+'cp949': (
+"\x8c\x63\xb9\xe6\xb0\xa2\xc7\xcf\x20\xbc\x84\xbd\xc3\xc4\xdd\xb6"
+"\xf3\x0a\x0a\xa8\xc0\xa8\xc0\xb3\xb3\x21\x21\x20\xec\xd7\xce\xfa"
+"\xea\xc5\xc6\xd0\x92\xe6\x90\x70\xb1\xc5\x20\xa8\xde\xa8\xd3\xc4"
+"\x52\xa2\xaf\xa2\xaf\xa2\xaf\x20\xb1\xe0\x8a\x96\x20\xa8\xd1\xb5"
+"\xb3\x20\xa8\xc0\x2e\x20\x2e\x0a\xe4\xac\xbf\xb5\xa8\xd1\xb4\xc9"
+"\xc8\xc2\x20\x2e\x20\x2e\x20\x2e\x20\x2e\x20\xbc\xad\xbf\xef\xb7"
+"\xef\x20\xb5\xaf\xc7\xd0\xeb\xe0\x20\xca\xab\xc4\x52\x20\x21\x20"
+"\x21\x20\x21\xa4\xd0\x2e\xa4\xd0\x0a\xc8\xe5\xc8\xe5\xc8\xe5\x20"
+"\xa4\xa1\xa4\xa1\xa4\xa1\xa1\xd9\xa4\xd0\x5f\xa4\xd0\x20\xbe\xee"
+"\x90\x8a\x20\xc5\xcb\xc4\xe2\x83\x4f\x20\xb5\xae\xc0\xc0\x20\xaf"
+"\x68\xce\xfa\xb5\xe9\xeb\xe0\x20\xa8\xc0\xb5\xe5\x83\x4f\x0a\xbc"
+"\xb3\x90\x6a\x20\xca\xab\xc4\x52\x20\x2e\x20\x2e\x20\x2e\x20\x2e"
+"\x20\xb1\xbc\xbe\xd6\x9a\x66\x20\xa8\xd1\xb1\xc5\x20\xa8\xde\x90"
+"\x74\xa8\xc2\x83\x4f\x20\xec\xd7\xec\xd2\xf4\xb9\xe5\xfc\xf1\xe9"
+"\xb1\xee\xa3\x8e\x0a\xbf\xcd\xbe\xac\xc4\x52\x20\x21\x20\x21\x20"
+"\xe4\xac\xbf\xb5\xa8\xd1\x20\xca\xab\xb4\xc9\xb1\xc5\x20\xa1\xd9"
+"\xdf\xbe\xb0\xfc\x20\xbe\xf8\xb4\xc9\xb1\xc5\xb4\xc9\x20\xe4\xac"
+"\xb4\xc9\xb5\xd8\xc4\x52\x20\xb1\xdb\xbe\xd6\x8a\xdb\x0a\xa8\xde"
+"\xb7\xc1\xb5\xe0\xce\xfa\x20\x9a\xc3\xc7\xb4\xbd\xa4\xc4\x52\x20"
+"\xbe\xee\x90\x8a\x20\xec\xd7\xec\xd2\xf4\xb9\xe5\xfc\xf1\xe9\x9a"
+"\xc4\xa8\xef\xb5\xe9\x9d\xda\x21\x21\x20\xa8\xc0\xa8\xc0\xb3\xb3"
+"\xa2\xbd\x20\xa1\xd2\xa1\xd2\x2a\x0a\x0a",
+"\xeb\x98\xa0\xeb\xb0\xa9\xea\xb0\x81\xed\x95\x98\x20\xed\x8e\xb2"
+"\xec\x8b\x9c\xec\xbd\x9c\xeb\x9d\xbc\x0a\x0a\xe3\x89\xaf\xe3\x89"
+"\xaf\xeb\x82\xa9\x21\x21\x20\xe5\x9b\xa0\xe4\xb9\x9d\xe6\x9c\x88"
+"\xed\x8c\xa8\xeb\xaf\xa4\xeb\xa6\x94\xea\xb6\x88\x20\xe2\x93\xa1"
+"\xe2\x93\x96\xed\x9b\x80\xc2\xbf\xc2\xbf\xc2\xbf\x20\xea\xb8\x8d"
+"\xeb\x92\x99\x20\xe2\x93\x94\xeb\x8e\xa8\x20\xe3\x89\xaf\x2e\x20"
+"\x2e\x0a\xe4\xba\x9e\xec\x98\x81\xe2\x93\x94\xeb\x8a\xa5\xed\x9a"
+"\xb9\x20\x2e\x20\x2e\x20\x2e\x20\x2e\x20\xec\x84\x9c\xec\x9a\xb8"
+"\xeb\xa4\x84\x20\xeb\x8e\x90\xed\x95\x99\xe4\xb9\x99\x20\xe5\xae"
+"\xb6\xed\x9b\x80\x20\x21\x20\x21\x20\x21\xe3\x85\xa0\x2e\xe3\x85"
+"\xa0\x0a\xed\x9d\x90\xed\x9d\x90\xed\x9d\x90\x20\xe3\x84\xb1\xe3"
+"\x84\xb1\xe3\x84\xb1\xe2\x98\x86\xe3\x85\xa0\x5f\xe3\x85\xa0\x20"
+"\xec\x96\xb4\xeb\xa6\xa8\x20\xed\x83\xb8\xec\xbd\xb0\xea\xb8\x90"
+"\x20\xeb\x8e\x8c\xec\x9d\x91\x20\xec\xb9\x91\xe4\xb9\x9d\xeb\x93"
+"\xa4\xe4\xb9\x99\x20\xe3\x89\xaf\xeb\x93\x9c\xea\xb8\x90\x0a\xec"
+"\x84\xa4\xeb\xa6\x8c\x20\xe5\xae\xb6\xed\x9b\x80\x20\x2e\x20\x2e"
+"\x20\x2e\x20\x2e\x20\xea\xb5\xb4\xec\x95\xa0\xec\x89\x8c\x20\xe2"
+"\x93\x94\xea\xb6\x88\x20\xe2\x93\xa1\xeb\xa6\x98\xe3\x89\xb1\xea"
+"\xb8\x90\x20\xe5\x9b\xa0\xe4\xbb\x81\xe5\xb7\x9d\xef\xa6\x81\xe4"
+"\xb8\xad\xea\xb9\x8c\xec\xa6\xbc\x0a\xec\x99\x80\xec\x92\x80\xed"
+"\x9b\x80\x20\x21\x20\x21\x20\xe4\xba\x9e\xec\x98\x81\xe2\x93\x94"
+"\x20\xe5\xae\xb6\xeb\x8a\xa5\xea\xb6\x88\x20\xe2\x98\x86\xe4\xb8"
+"\x8a\xea\xb4\x80\x20\xec\x97\x86\xeb\x8a\xa5\xea\xb6\x88\xeb\x8a"
+"\xa5\x20\xe4\xba\x9e\xeb\x8a\xa5\xeb\x92\x88\xed\x9b\x80\x20\xea"
+"\xb8\x80\xec\x95\xa0\xeb\x93\xb4\x0a\xe2\x93\xa1\xeb\xa0\xa4\xeb"
+"\x93\x80\xe4\xb9\x9d\x20\xec\x8b\x80\xed\x92\x94\xec\x88\xb4\xed"
+"\x9b\x80\x20\xec\x96\xb4\xeb\xa6\xa8\x20\xe5\x9b\xa0\xe4\xbb\x81"
+"\xe5\xb7\x9d\xef\xa6\x81\xe4\xb8\xad\xec\x8b\x81\xe2\x91\xa8\xeb"
+"\x93\xa4\xec\x95\x9c\x21\x21\x20\xe3\x89\xaf\xe3\x89\xaf\xeb\x82"
+"\xa9\xe2\x99\xa1\x20\xe2\x8c\x92\xe2\x8c\x92\x2a\x0a\x0a"),
+'euc_jisx0213': (
+"\x50\x79\x74\x68\x6f\x6e\x20\xa4\xce\xb3\xab\xc8\xaf\xa4\xcf\xa1"
+"\xa2\x31\x39\x39\x30\x20\xc7\xaf\xa4\xb4\xa4\xed\xa4\xab\xa4\xe9"
+"\xb3\xab\xbb\xcf\xa4\xb5\xa4\xec\xa4\xc6\xa4\xa4\xa4\xde\xa4\xb9"
+"\xa1\xa3\x0a\xb3\xab\xc8\xaf\xbc\xd4\xa4\xce\x20\x47\x75\x69\x64"
+"\x6f\x20\x76\x61\x6e\x20\x52\x6f\x73\x73\x75\x6d\x20\xa4\xcf\xb6"
+"\xb5\xb0\xe9\xcd\xd1\xa4\xce\xa5\xd7\xa5\xed\xa5\xb0\xa5\xe9\xa5"
+"\xdf\xa5\xf3\xa5\xb0\xb8\xc0\xb8\xec\xa1\xd6\x41\x42\x43\xa1\xd7"
+"\xa4\xce\xb3\xab\xc8\xaf\xa4\xcb\xbb\xb2\xb2\xc3\xa4\xb7\xa4\xc6"
+"\xa4\xa4\xa4\xde\xa4\xb7\xa4\xbf\xa4\xac\xa1\xa2\x41\x42\x43\x20"
+"\xa4\xcf\xbc\xc2\xcd\xd1\xbe\xe5\xa4\xce\xcc\xdc\xc5\xaa\xa4\xcb"
+"\xa4\xcf\xa4\xa2\xa4\xde\xa4\xea\xc5\xac\xa4\xb7\xa4\xc6\xa4\xa4"
+"\xa4\xde\xa4\xbb\xa4\xf3\xa4\xc7\xa4\xb7\xa4\xbf\xa1\xa3\x0a\xa4"
+"\xb3\xa4\xce\xa4\xbf\xa4\xe1\xa1\xa2\x47\x75\x69\x64\x6f\x20\xa4"
+"\xcf\xa4\xe8\xa4\xea\xbc\xc2\xcd\xd1\xc5\xaa\xa4\xca\xa5\xd7\xa5"
+"\xed\xa5\xb0\xa5\xe9\xa5\xdf\xa5\xf3\xa5\xb0\xb8\xc0\xb8\xec\xa4"
+"\xce\xb3\xab\xc8\xaf\xa4\xf2\xb3\xab\xbb\xcf\xa4\xb7\xa1\xa2\xb1"
+"\xd1\xb9\xf1\x20\x42\x42\x53\x20\xca\xfc\xc1\xf7\xa4\xce\xa5\xb3"
+"\xa5\xe1\xa5\xc7\xa5\xa3\xc8\xd6\xc1\xc8\xa1\xd6\xa5\xe2\xa5\xf3"
+"\xa5\xc6\xa5\xa3\x20\xa5\xd1\xa5\xa4\xa5\xbd\xa5\xf3\xa1\xd7\xa4"
+"\xce\xa5\xd5\xa5\xa1\xa5\xf3\xa4\xc7\xa4\xa2\xa4\xeb\x20\x47\x75"
+"\x69\x64\x6f\x20\xa4\xcf\xa4\xb3\xa4\xce\xb8\xc0\xb8\xec\xa4\xf2"
+"\xa1\xd6\x50\x79\x74\x68\x6f\x6e\xa1\xd7\xa4\xc8\xcc\xbe\xa4\xc5"
+"\xa4\xb1\xa4\xde\xa4\xb7\xa4\xbf\xa1\xa3\x0a\xa4\xb3\xa4\xce\xa4"
+"\xe8\xa4\xa6\xa4\xca\xc7\xd8\xb7\xca\xa4\xab\xa4\xe9\xc0\xb8\xa4"
+"\xde\xa4\xec\xa4\xbf\x20\x50\x79\x74\x68\x6f\x6e\x20\xa4\xce\xb8"
+"\xc0\xb8\xec\xc0\xdf\xb7\xd7\xa4\xcf\xa1\xa2\xa1\xd6\xa5\xb7\xa5"
+"\xf3\xa5\xd7\xa5\xeb\xa1\xd7\xa4\xc7\xa1\xd6\xbd\xac\xc6\xc0\xa4"
+"\xac\xcd\xc6\xb0\xd7\xa1\xd7\xa4\xc8\xa4\xa4\xa4\xa6\xcc\xdc\xc9"
+"\xb8\xa4\xcb\xbd\xc5\xc5\xc0\xa4\xac\xc3\xd6\xa4\xab\xa4\xec\xa4"
+"\xc6\xa4\xa4\xa4\xde\xa4\xb9\xa1\xa3\x0a\xc2\xbf\xa4\xaf\xa4\xce"
+"\xa5\xb9\xa5\xaf\xa5\xea\xa5\xd7\xa5\xc8\xb7\xcf\xb8\xc0\xb8\xec"
+"\xa4\xc7\xa4\xcf\xa5\xe6\xa1\xbc\xa5\xb6\xa4\xce\xcc\xdc\xc0\xe8"
+"\xa4\xce\xcd\xf8\xca\xd8\xc0\xad\xa4\xf2\xcd\xa5\xc0\xe8\xa4\xb7"
+"\xa4\xc6\xbf\xa7\xa1\xb9\xa4\xca\xb5\xa1\xc7\xbd\xa4\xf2\xb8\xc0"
+"\xb8\xec\xcd\xd7\xc1\xc7\xa4\xc8\xa4\xb7\xa4\xc6\xbc\xe8\xa4\xea"
+"\xc6\xfe\xa4\xec\xa4\xeb\xbe\xec\xb9\xe7\xa4\xac\xc2\xbf\xa4\xa4"
+"\xa4\xce\xa4\xc7\xa4\xb9\xa4\xac\xa1\xa2\x50\x79\x74\x68\x6f\x6e"
+"\x20\xa4\xc7\xa4\xcf\xa4\xbd\xa4\xa6\xa4\xa4\xa4\xc3\xa4\xbf\xbe"
+"\xae\xba\xd9\xb9\xa9\xa4\xac\xc4\xc9\xb2\xc3\xa4\xb5\xa4\xec\xa4"
+"\xeb\xa4\xb3\xa4\xc8\xa4\xcf\xa4\xa2\xa4\xde\xa4\xea\xa4\xa2\xa4"
+"\xea\xa4\xde\xa4\xbb\xa4\xf3\xa1\xa3\x0a\xb8\xc0\xb8\xec\xbc\xab"
+"\xc2\xce\xa4\xce\xb5\xa1\xc7\xbd\xa4\xcf\xba\xc7\xbe\xae\xb8\xc2"
+"\xa4\xcb\xb2\xa1\xa4\xb5\xa4\xa8\xa1\xa2\xc9\xac\xcd\xd7\xa4\xca"
+"\xb5\xa1\xc7\xbd\xa4\xcf\xb3\xc8\xc4\xa5\xa5\xe2\xa5\xb8\xa5\xe5"
+"\xa1\xbc\xa5\xeb\xa4\xc8\xa4\xb7\xa4\xc6\xc4\xc9\xb2\xc3\xa4\xb9"
+"\xa4\xeb\xa1\xa2\xa4\xc8\xa4\xa4\xa4\xa6\xa4\xce\xa4\xac\x20\x50"
+"\x79\x74\x68\x6f\x6e\x20\xa4\xce\xa5\xdd\xa5\xea\xa5\xb7\xa1\xbc"
+"\xa4\xc7\xa4\xb9\xa1\xa3\x0a\x0a\xa5\xce\xa4\xf7\x20\xa5\xfe\x20"
+"\xa5\xc8\xa5\xad\xaf\xac\xaf\xda\x20\xcf\xe3\x8f\xfe\xd8\x20\x8f"
+"\xfe\xd4\x8f\xfe\xe8\x8f\xfc\xd6\x0a",
+"\x50\x79\x74\x68\x6f\x6e\x20\xe3\x81\xae\xe9\x96\x8b\xe7\x99\xba"
+"\xe3\x81\xaf\xe3\x80\x81\x31\x39\x39\x30\x20\xe5\xb9\xb4\xe3\x81"
+"\x94\xe3\x82\x8d\xe3\x81\x8b\xe3\x82\x89\xe9\x96\x8b\xe5\xa7\x8b"
+"\xe3\x81\x95\xe3\x82\x8c\xe3\x81\xa6\xe3\x81\x84\xe3\x81\xbe\xe3"
+"\x81\x99\xe3\x80\x82\x0a\xe9\x96\x8b\xe7\x99\xba\xe8\x80\x85\xe3"
+"\x81\xae\x20\x47\x75\x69\x64\x6f\x20\x76\x61\x6e\x20\x52\x6f\x73"
+"\x73\x75\x6d\x20\xe3\x81\xaf\xe6\x95\x99\xe8\x82\xb2\xe7\x94\xa8"
+"\xe3\x81\xae\xe3\x83\x97\xe3\x83\xad\xe3\x82\xb0\xe3\x83\xa9\xe3"
+"\x83\x9f\xe3\x83\xb3\xe3\x82\xb0\xe8\xa8\x80\xe8\xaa\x9e\xe3\x80"
+"\x8c\x41\x42\x43\xe3\x80\x8d\xe3\x81\xae\xe9\x96\x8b\xe7\x99\xba"
+"\xe3\x81\xab\xe5\x8f\x82\xe5\x8a\xa0\xe3\x81\x97\xe3\x81\xa6\xe3"
+"\x81\x84\xe3\x81\xbe\xe3\x81\x97\xe3\x81\x9f\xe3\x81\x8c\xe3\x80"
+"\x81\x41\x42\x43\x20\xe3\x81\xaf\xe5\xae\x9f\xe7\x94\xa8\xe4\xb8"
+"\x8a\xe3\x81\xae\xe7\x9b\xae\xe7\x9a\x84\xe3\x81\xab\xe3\x81\xaf"
+"\xe3\x81\x82\xe3\x81\xbe\xe3\x82\x8a\xe9\x81\xa9\xe3\x81\x97\xe3"
+"\x81\xa6\xe3\x81\x84\xe3\x81\xbe\xe3\x81\x9b\xe3\x82\x93\xe3\x81"
+"\xa7\xe3\x81\x97\xe3\x81\x9f\xe3\x80\x82\x0a\xe3\x81\x93\xe3\x81"
+"\xae\xe3\x81\x9f\xe3\x82\x81\xe3\x80\x81\x47\x75\x69\x64\x6f\x20"
+"\xe3\x81\xaf\xe3\x82\x88\xe3\x82\x8a\xe5\xae\x9f\xe7\x94\xa8\xe7"
+"\x9a\x84\xe3\x81\xaa\xe3\x83\x97\xe3\x83\xad\xe3\x82\xb0\xe3\x83"
+"\xa9\xe3\x83\x9f\xe3\x83\xb3\xe3\x82\xb0\xe8\xa8\x80\xe8\xaa\x9e"
+"\xe3\x81\xae\xe9\x96\x8b\xe7\x99\xba\xe3\x82\x92\xe9\x96\x8b\xe5"
+"\xa7\x8b\xe3\x81\x97\xe3\x80\x81\xe8\x8b\xb1\xe5\x9b\xbd\x20\x42"
+"\x42\x53\x20\xe6\x94\xbe\xe9\x80\x81\xe3\x81\xae\xe3\x82\xb3\xe3"
+"\x83\xa1\xe3\x83\x87\xe3\x82\xa3\xe7\x95\xaa\xe7\xb5\x84\xe3\x80"
+"\x8c\xe3\x83\xa2\xe3\x83\xb3\xe3\x83\x86\xe3\x82\xa3\x20\xe3\x83"
+"\x91\xe3\x82\xa4\xe3\x82\xbd\xe3\x83\xb3\xe3\x80\x8d\xe3\x81\xae"
+"\xe3\x83\x95\xe3\x82\xa1\xe3\x83\xb3\xe3\x81\xa7\xe3\x81\x82\xe3"
+"\x82\x8b\x20\x47\x75\x69\x64\x6f\x20\xe3\x81\xaf\xe3\x81\x93\xe3"
+"\x81\xae\xe8\xa8\x80\xe8\xaa\x9e\xe3\x82\x92\xe3\x80\x8c\x50\x79"
+"\x74\x68\x6f\x6e\xe3\x80\x8d\xe3\x81\xa8\xe5\x90\x8d\xe3\x81\xa5"
+"\xe3\x81\x91\xe3\x81\xbe\xe3\x81\x97\xe3\x81\x9f\xe3\x80\x82\x0a"
+"\xe3\x81\x93\xe3\x81\xae\xe3\x82\x88\xe3\x81\x86\xe3\x81\xaa\xe8"
+"\x83\x8c\xe6\x99\xaf\xe3\x81\x8b\xe3\x82\x89\xe7\x94\x9f\xe3\x81"
+"\xbe\xe3\x82\x8c\xe3\x81\x9f\x20\x50\x79\x74\x68\x6f\x6e\x20\xe3"
+"\x81\xae\xe8\xa8\x80\xe8\xaa\x9e\xe8\xa8\xad\xe8\xa8\x88\xe3\x81"
+"\xaf\xe3\x80\x81\xe3\x80\x8c\xe3\x82\xb7\xe3\x83\xb3\xe3\x83\x97"
+"\xe3\x83\xab\xe3\x80\x8d\xe3\x81\xa7\xe3\x80\x8c\xe7\xbf\x92\xe5"
+"\xbe\x97\xe3\x81\x8c\xe5\xae\xb9\xe6\x98\x93\xe3\x80\x8d\xe3\x81"
+"\xa8\xe3\x81\x84\xe3\x81\x86\xe7\x9b\xae\xe6\xa8\x99\xe3\x81\xab"
+"\xe9\x87\x8d\xe7\x82\xb9\xe3\x81\x8c\xe7\xbd\xae\xe3\x81\x8b\xe3"
+"\x82\x8c\xe3\x81\xa6\xe3\x81\x84\xe3\x81\xbe\xe3\x81\x99\xe3\x80"
+"\x82\x0a\xe5\xa4\x9a\xe3\x81\x8f\xe3\x81\xae\xe3\x82\xb9\xe3\x82"
+"\xaf\xe3\x83\xaa\xe3\x83\x97\xe3\x83\x88\xe7\xb3\xbb\xe8\xa8\x80"
+"\xe8\xaa\x9e\xe3\x81\xa7\xe3\x81\xaf\xe3\x83\xa6\xe3\x83\xbc\xe3"
+"\x82\xb6\xe3\x81\xae\xe7\x9b\xae\xe5\x85\x88\xe3\x81\xae\xe5\x88"
+"\xa9\xe4\xbe\xbf\xe6\x80\xa7\xe3\x82\x92\xe5\x84\xaa\xe5\x85\x88"
+"\xe3\x81\x97\xe3\x81\xa6\xe8\x89\xb2\xe3\x80\x85\xe3\x81\xaa\xe6"
+"\xa9\x9f\xe8\x83\xbd\xe3\x82\x92\xe8\xa8\x80\xe8\xaa\x9e\xe8\xa6"
+"\x81\xe7\xb4\xa0\xe3\x81\xa8\xe3\x81\x97\xe3\x81\xa6\xe5\x8f\x96"
+"\xe3\x82\x8a\xe5\x85\xa5\xe3\x82\x8c\xe3\x82\x8b\xe5\xa0\xb4\xe5"
+"\x90\x88\xe3\x81\x8c\xe5\xa4\x9a\xe3\x81\x84\xe3\x81\xae\xe3\x81"
+"\xa7\xe3\x81\x99\xe3\x81\x8c\xe3\x80\x81\x50\x79\x74\x68\x6f\x6e"
+"\x20\xe3\x81\xa7\xe3\x81\xaf\xe3\x81\x9d\xe3\x81\x86\xe3\x81\x84"
+"\xe3\x81\xa3\xe3\x81\x9f\xe5\xb0\x8f\xe7\xb4\xb0\xe5\xb7\xa5\xe3"
+"\x81\x8c\xe8\xbf\xbd\xe5\x8a\xa0\xe3\x81\x95\xe3\x82\x8c\xe3\x82"
+"\x8b\xe3\x81\x93\xe3\x81\xa8\xe3\x81\xaf\xe3\x81\x82\xe3\x81\xbe"
+"\xe3\x82\x8a\xe3\x81\x82\xe3\x82\x8a\xe3\x81\xbe\xe3\x81\x9b\xe3"
+"\x82\x93\xe3\x80\x82\x0a\xe8\xa8\x80\xe8\xaa\x9e\xe8\x87\xaa\xe4"
+"\xbd\x93\xe3\x81\xae\xe6\xa9\x9f\xe8\x83\xbd\xe3\x81\xaf\xe6\x9c"
+"\x80\xe5\xb0\x8f\xe9\x99\x90\xe3\x81\xab\xe6\x8a\xbc\xe3\x81\x95"
+"\xe3\x81\x88\xe3\x80\x81\xe5\xbf\x85\xe8\xa6\x81\xe3\x81\xaa\xe6"
+"\xa9\x9f\xe8\x83\xbd\xe3\x81\xaf\xe6\x8b\xa1\xe5\xbc\xb5\xe3\x83"
+"\xa2\xe3\x82\xb8\xe3\x83\xa5\xe3\x83\xbc\xe3\x83\xab\xe3\x81\xa8"
+"\xe3\x81\x97\xe3\x81\xa6\xe8\xbf\xbd\xe5\x8a\xa0\xe3\x81\x99\xe3"
+"\x82\x8b\xe3\x80\x81\xe3\x81\xa8\xe3\x81\x84\xe3\x81\x86\xe3\x81"
+"\xae\xe3\x81\x8c\x20\x50\x79\x74\x68\x6f\x6e\x20\xe3\x81\xae\xe3"
+"\x83\x9d\xe3\x83\xaa\xe3\x82\xb7\xe3\x83\xbc\xe3\x81\xa7\xe3\x81"
+"\x99\xe3\x80\x82\x0a\x0a\xe3\x83\x8e\xe3\x81\x8b\xe3\x82\x9a\x20"
+"\xe3\x83\x88\xe3\x82\x9a\x20\xe3\x83\x88\xe3\x82\xad\xef\xa8\xb6"
+"\xef\xa8\xb9\x20\xf0\xa1\x9a\xb4\xf0\xaa\x8e\x8c\x20\xe9\xba\x80"
+"\xe9\xbd\x81\xf0\xa9\x9b\xb0\x0a"),
+'euc_jp': (
+"\x50\x79\x74\x68\x6f\x6e\x20\xa4\xce\xb3\xab\xc8\xaf\xa4\xcf\xa1"
+"\xa2\x31\x39\x39\x30\x20\xc7\xaf\xa4\xb4\xa4\xed\xa4\xab\xa4\xe9"
+"\xb3\xab\xbb\xcf\xa4\xb5\xa4\xec\xa4\xc6\xa4\xa4\xa4\xde\xa4\xb9"
+"\xa1\xa3\x0a\xb3\xab\xc8\xaf\xbc\xd4\xa4\xce\x20\x47\x75\x69\x64"
+"\x6f\x20\x76\x61\x6e\x20\x52\x6f\x73\x73\x75\x6d\x20\xa4\xcf\xb6"
+"\xb5\xb0\xe9\xcd\xd1\xa4\xce\xa5\xd7\xa5\xed\xa5\xb0\xa5\xe9\xa5"
+"\xdf\xa5\xf3\xa5\xb0\xb8\xc0\xb8\xec\xa1\xd6\x41\x42\x43\xa1\xd7"
+"\xa4\xce\xb3\xab\xc8\xaf\xa4\xcb\xbb\xb2\xb2\xc3\xa4\xb7\xa4\xc6"
+"\xa4\xa4\xa4\xde\xa4\xb7\xa4\xbf\xa4\xac\xa1\xa2\x41\x42\x43\x20"
+"\xa4\xcf\xbc\xc2\xcd\xd1\xbe\xe5\xa4\xce\xcc\xdc\xc5\xaa\xa4\xcb"
+"\xa4\xcf\xa4\xa2\xa4\xde\xa4\xea\xc5\xac\xa4\xb7\xa4\xc6\xa4\xa4"
+"\xa4\xde\xa4\xbb\xa4\xf3\xa4\xc7\xa4\xb7\xa4\xbf\xa1\xa3\x0a\xa4"
+"\xb3\xa4\xce\xa4\xbf\xa4\xe1\xa1\xa2\x47\x75\x69\x64\x6f\x20\xa4"
+"\xcf\xa4\xe8\xa4\xea\xbc\xc2\xcd\xd1\xc5\xaa\xa4\xca\xa5\xd7\xa5"
+"\xed\xa5\xb0\xa5\xe9\xa5\xdf\xa5\xf3\xa5\xb0\xb8\xc0\xb8\xec\xa4"
+"\xce\xb3\xab\xc8\xaf\xa4\xf2\xb3\xab\xbb\xcf\xa4\xb7\xa1\xa2\xb1"
+"\xd1\xb9\xf1\x20\x42\x42\x53\x20\xca\xfc\xc1\xf7\xa4\xce\xa5\xb3"
+"\xa5\xe1\xa5\xc7\xa5\xa3\xc8\xd6\xc1\xc8\xa1\xd6\xa5\xe2\xa5\xf3"
+"\xa5\xc6\xa5\xa3\x20\xa5\xd1\xa5\xa4\xa5\xbd\xa5\xf3\xa1\xd7\xa4"
+"\xce\xa5\xd5\xa5\xa1\xa5\xf3\xa4\xc7\xa4\xa2\xa4\xeb\x20\x47\x75"
+"\x69\x64\x6f\x20\xa4\xcf\xa4\xb3\xa4\xce\xb8\xc0\xb8\xec\xa4\xf2"
+"\xa1\xd6\x50\x79\x74\x68\x6f\x6e\xa1\xd7\xa4\xc8\xcc\xbe\xa4\xc5"
+"\xa4\xb1\xa4\xde\xa4\xb7\xa4\xbf\xa1\xa3\x0a\xa4\xb3\xa4\xce\xa4"
+"\xe8\xa4\xa6\xa4\xca\xc7\xd8\xb7\xca\xa4\xab\xa4\xe9\xc0\xb8\xa4"
+"\xde\xa4\xec\xa4\xbf\x20\x50\x79\x74\x68\x6f\x6e\x20\xa4\xce\xb8"
+"\xc0\xb8\xec\xc0\xdf\xb7\xd7\xa4\xcf\xa1\xa2\xa1\xd6\xa5\xb7\xa5"
+"\xf3\xa5\xd7\xa5\xeb\xa1\xd7\xa4\xc7\xa1\xd6\xbd\xac\xc6\xc0\xa4"
+"\xac\xcd\xc6\xb0\xd7\xa1\xd7\xa4\xc8\xa4\xa4\xa4\xa6\xcc\xdc\xc9"
+"\xb8\xa4\xcb\xbd\xc5\xc5\xc0\xa4\xac\xc3\xd6\xa4\xab\xa4\xec\xa4"
+"\xc6\xa4\xa4\xa4\xde\xa4\xb9\xa1\xa3\x0a\xc2\xbf\xa4\xaf\xa4\xce"
+"\xa5\xb9\xa5\xaf\xa5\xea\xa5\xd7\xa5\xc8\xb7\xcf\xb8\xc0\xb8\xec"
+"\xa4\xc7\xa4\xcf\xa5\xe6\xa1\xbc\xa5\xb6\xa4\xce\xcc\xdc\xc0\xe8"
+"\xa4\xce\xcd\xf8\xca\xd8\xc0\xad\xa4\xf2\xcd\xa5\xc0\xe8\xa4\xb7"
+"\xa4\xc6\xbf\xa7\xa1\xb9\xa4\xca\xb5\xa1\xc7\xbd\xa4\xf2\xb8\xc0"
+"\xb8\xec\xcd\xd7\xc1\xc7\xa4\xc8\xa4\xb7\xa4\xc6\xbc\xe8\xa4\xea"
+"\xc6\xfe\xa4\xec\xa4\xeb\xbe\xec\xb9\xe7\xa4\xac\xc2\xbf\xa4\xa4"
+"\xa4\xce\xa4\xc7\xa4\xb9\xa4\xac\xa1\xa2\x50\x79\x74\x68\x6f\x6e"
+"\x20\xa4\xc7\xa4\xcf\xa4\xbd\xa4\xa6\xa4\xa4\xa4\xc3\xa4\xbf\xbe"
+"\xae\xba\xd9\xb9\xa9\xa4\xac\xc4\xc9\xb2\xc3\xa4\xb5\xa4\xec\xa4"
+"\xeb\xa4\xb3\xa4\xc8\xa4\xcf\xa4\xa2\xa4\xde\xa4\xea\xa4\xa2\xa4"
+"\xea\xa4\xde\xa4\xbb\xa4\xf3\xa1\xa3\x0a\xb8\xc0\xb8\xec\xbc\xab"
+"\xc2\xce\xa4\xce\xb5\xa1\xc7\xbd\xa4\xcf\xba\xc7\xbe\xae\xb8\xc2"
+"\xa4\xcb\xb2\xa1\xa4\xb5\xa4\xa8\xa1\xa2\xc9\xac\xcd\xd7\xa4\xca"
+"\xb5\xa1\xc7\xbd\xa4\xcf\xb3\xc8\xc4\xa5\xa5\xe2\xa5\xb8\xa5\xe5"
+"\xa1\xbc\xa5\xeb\xa4\xc8\xa4\xb7\xa4\xc6\xc4\xc9\xb2\xc3\xa4\xb9"
+"\xa4\xeb\xa1\xa2\xa4\xc8\xa4\xa4\xa4\xa6\xa4\xce\xa4\xac\x20\x50"
+"\x79\x74\x68\x6f\x6e\x20\xa4\xce\xa5\xdd\xa5\xea\xa5\xb7\xa1\xbc"
+"\xa4\xc7\xa4\xb9\xa1\xa3\x0a\x0a",
+"\x50\x79\x74\x68\x6f\x6e\x20\xe3\x81\xae\xe9\x96\x8b\xe7\x99\xba"
+"\xe3\x81\xaf\xe3\x80\x81\x31\x39\x39\x30\x20\xe5\xb9\xb4\xe3\x81"
+"\x94\xe3\x82\x8d\xe3\x81\x8b\xe3\x82\x89\xe9\x96\x8b\xe5\xa7\x8b"
+"\xe3\x81\x95\xe3\x82\x8c\xe3\x81\xa6\xe3\x81\x84\xe3\x81\xbe\xe3"
+"\x81\x99\xe3\x80\x82\x0a\xe9\x96\x8b\xe7\x99\xba\xe8\x80\x85\xe3"
+"\x81\xae\x20\x47\x75\x69\x64\x6f\x20\x76\x61\x6e\x20\x52\x6f\x73"
+"\x73\x75\x6d\x20\xe3\x81\xaf\xe6\x95\x99\xe8\x82\xb2\xe7\x94\xa8"
+"\xe3\x81\xae\xe3\x83\x97\xe3\x83\xad\xe3\x82\xb0\xe3\x83\xa9\xe3"
+"\x83\x9f\xe3\x83\xb3\xe3\x82\xb0\xe8\xa8\x80\xe8\xaa\x9e\xe3\x80"
+"\x8c\x41\x42\x43\xe3\x80\x8d\xe3\x81\xae\xe9\x96\x8b\xe7\x99\xba"
+"\xe3\x81\xab\xe5\x8f\x82\xe5\x8a\xa0\xe3\x81\x97\xe3\x81\xa6\xe3"
+"\x81\x84\xe3\x81\xbe\xe3\x81\x97\xe3\x81\x9f\xe3\x81\x8c\xe3\x80"
+"\x81\x41\x42\x43\x20\xe3\x81\xaf\xe5\xae\x9f\xe7\x94\xa8\xe4\xb8"
+"\x8a\xe3\x81\xae\xe7\x9b\xae\xe7\x9a\x84\xe3\x81\xab\xe3\x81\xaf"
+"\xe3\x81\x82\xe3\x81\xbe\xe3\x82\x8a\xe9\x81\xa9\xe3\x81\x97\xe3"
+"\x81\xa6\xe3\x81\x84\xe3\x81\xbe\xe3\x81\x9b\xe3\x82\x93\xe3\x81"
+"\xa7\xe3\x81\x97\xe3\x81\x9f\xe3\x80\x82\x0a\xe3\x81\x93\xe3\x81"
+"\xae\xe3\x81\x9f\xe3\x82\x81\xe3\x80\x81\x47\x75\x69\x64\x6f\x20"
+"\xe3\x81\xaf\xe3\x82\x88\xe3\x82\x8a\xe5\xae\x9f\xe7\x94\xa8\xe7"
+"\x9a\x84\xe3\x81\xaa\xe3\x83\x97\xe3\x83\xad\xe3\x82\xb0\xe3\x83"
+"\xa9\xe3\x83\x9f\xe3\x83\xb3\xe3\x82\xb0\xe8\xa8\x80\xe8\xaa\x9e"
+"\xe3\x81\xae\xe9\x96\x8b\xe7\x99\xba\xe3\x82\x92\xe9\x96\x8b\xe5"
+"\xa7\x8b\xe3\x81\x97\xe3\x80\x81\xe8\x8b\xb1\xe5\x9b\xbd\x20\x42"
+"\x42\x53\x20\xe6\x94\xbe\xe9\x80\x81\xe3\x81\xae\xe3\x82\xb3\xe3"
+"\x83\xa1\xe3\x83\x87\xe3\x82\xa3\xe7\x95\xaa\xe7\xb5\x84\xe3\x80"
+"\x8c\xe3\x83\xa2\xe3\x83\xb3\xe3\x83\x86\xe3\x82\xa3\x20\xe3\x83"
+"\x91\xe3\x82\xa4\xe3\x82\xbd\xe3\x83\xb3\xe3\x80\x8d\xe3\x81\xae"
+"\xe3\x83\x95\xe3\x82\xa1\xe3\x83\xb3\xe3\x81\xa7\xe3\x81\x82\xe3"
+"\x82\x8b\x20\x47\x75\x69\x64\x6f\x20\xe3\x81\xaf\xe3\x81\x93\xe3"
+"\x81\xae\xe8\xa8\x80\xe8\xaa\x9e\xe3\x82\x92\xe3\x80\x8c\x50\x79"
+"\x74\x68\x6f\x6e\xe3\x80\x8d\xe3\x81\xa8\xe5\x90\x8d\xe3\x81\xa5"
+"\xe3\x81\x91\xe3\x81\xbe\xe3\x81\x97\xe3\x81\x9f\xe3\x80\x82\x0a"
+"\xe3\x81\x93\xe3\x81\xae\xe3\x82\x88\xe3\x81\x86\xe3\x81\xaa\xe8"
+"\x83\x8c\xe6\x99\xaf\xe3\x81\x8b\xe3\x82\x89\xe7\x94\x9f\xe3\x81"
+"\xbe\xe3\x82\x8c\xe3\x81\x9f\x20\x50\x79\x74\x68\x6f\x6e\x20\xe3"
+"\x81\xae\xe8\xa8\x80\xe8\xaa\x9e\xe8\xa8\xad\xe8\xa8\x88\xe3\x81"
+"\xaf\xe3\x80\x81\xe3\x80\x8c\xe3\x82\xb7\xe3\x83\xb3\xe3\x83\x97"
+"\xe3\x83\xab\xe3\x80\x8d\xe3\x81\xa7\xe3\x80\x8c\xe7\xbf\x92\xe5"
+"\xbe\x97\xe3\x81\x8c\xe5\xae\xb9\xe6\x98\x93\xe3\x80\x8d\xe3\x81"
+"\xa8\xe3\x81\x84\xe3\x81\x86\xe7\x9b\xae\xe6\xa8\x99\xe3\x81\xab"
+"\xe9\x87\x8d\xe7\x82\xb9\xe3\x81\x8c\xe7\xbd\xae\xe3\x81\x8b\xe3"
+"\x82\x8c\xe3\x81\xa6\xe3\x81\x84\xe3\x81\xbe\xe3\x81\x99\xe3\x80"
+"\x82\x0a\xe5\xa4\x9a\xe3\x81\x8f\xe3\x81\xae\xe3\x82\xb9\xe3\x82"
+"\xaf\xe3\x83\xaa\xe3\x83\x97\xe3\x83\x88\xe7\xb3\xbb\xe8\xa8\x80"
+"\xe8\xaa\x9e\xe3\x81\xa7\xe3\x81\xaf\xe3\x83\xa6\xe3\x83\xbc\xe3"
+"\x82\xb6\xe3\x81\xae\xe7\x9b\xae\xe5\x85\x88\xe3\x81\xae\xe5\x88"
+"\xa9\xe4\xbe\xbf\xe6\x80\xa7\xe3\x82\x92\xe5\x84\xaa\xe5\x85\x88"
+"\xe3\x81\x97\xe3\x81\xa6\xe8\x89\xb2\xe3\x80\x85\xe3\x81\xaa\xe6"
+"\xa9\x9f\xe8\x83\xbd\xe3\x82\x92\xe8\xa8\x80\xe8\xaa\x9e\xe8\xa6"
+"\x81\xe7\xb4\xa0\xe3\x81\xa8\xe3\x81\x97\xe3\x81\xa6\xe5\x8f\x96"
+"\xe3\x82\x8a\xe5\x85\xa5\xe3\x82\x8c\xe3\x82\x8b\xe5\xa0\xb4\xe5"
+"\x90\x88\xe3\x81\x8c\xe5\xa4\x9a\xe3\x81\x84\xe3\x81\xae\xe3\x81"
+"\xa7\xe3\x81\x99\xe3\x81\x8c\xe3\x80\x81\x50\x79\x74\x68\x6f\x6e"
+"\x20\xe3\x81\xa7\xe3\x81\xaf\xe3\x81\x9d\xe3\x81\x86\xe3\x81\x84"
+"\xe3\x81\xa3\xe3\x81\x9f\xe5\xb0\x8f\xe7\xb4\xb0\xe5\xb7\xa5\xe3"
+"\x81\x8c\xe8\xbf\xbd\xe5\x8a\xa0\xe3\x81\x95\xe3\x82\x8c\xe3\x82"
+"\x8b\xe3\x81\x93\xe3\x81\xa8\xe3\x81\xaf\xe3\x81\x82\xe3\x81\xbe"
+"\xe3\x82\x8a\xe3\x81\x82\xe3\x82\x8a\xe3\x81\xbe\xe3\x81\x9b\xe3"
+"\x82\x93\xe3\x80\x82\x0a\xe8\xa8\x80\xe8\xaa\x9e\xe8\x87\xaa\xe4"
+"\xbd\x93\xe3\x81\xae\xe6\xa9\x9f\xe8\x83\xbd\xe3\x81\xaf\xe6\x9c"
+"\x80\xe5\xb0\x8f\xe9\x99\x90\xe3\x81\xab\xe6\x8a\xbc\xe3\x81\x95"
+"\xe3\x81\x88\xe3\x80\x81\xe5\xbf\x85\xe8\xa6\x81\xe3\x81\xaa\xe6"
+"\xa9\x9f\xe8\x83\xbd\xe3\x81\xaf\xe6\x8b\xa1\xe5\xbc\xb5\xe3\x83"
+"\xa2\xe3\x82\xb8\xe3\x83\xa5\xe3\x83\xbc\xe3\x83\xab\xe3\x81\xa8"
+"\xe3\x81\x97\xe3\x81\xa6\xe8\xbf\xbd\xe5\x8a\xa0\xe3\x81\x99\xe3"
+"\x82\x8b\xe3\x80\x81\xe3\x81\xa8\xe3\x81\x84\xe3\x81\x86\xe3\x81"
+"\xae\xe3\x81\x8c\x20\x50\x79\x74\x68\x6f\x6e\x20\xe3\x81\xae\xe3"
+"\x83\x9d\xe3\x83\xaa\xe3\x82\xb7\xe3\x83\xbc\xe3\x81\xa7\xe3\x81"
+"\x99\xe3\x80\x82\x0a\x0a"),
+'euc_kr': (
+"\xa1\xdd\x20\xc6\xc4\xc0\xcc\xbd\xe3\x28\x50\x79\x74\x68\x6f\x6e"
+"\x29\xc0\xba\x20\xb9\xe8\xbf\xec\xb1\xe2\x20\xbd\xb1\xb0\xed\x2c"
+"\x20\xb0\xad\xb7\xc2\xc7\xd1\x20\xc7\xc1\xb7\xce\xb1\xd7\xb7\xa1"
+"\xb9\xd6\x20\xbe\xf0\xbe\xee\xc0\xd4\xb4\xcf\xb4\xd9\x2e\x20\xc6"
+"\xc4\xc0\xcc\xbd\xe3\xc0\xba\x0a\xc8\xbf\xc0\xb2\xc0\xfb\xc0\xce"
+"\x20\xb0\xed\xbc\xf6\xc1\xd8\x20\xb5\xa5\xc0\xcc\xc5\xcd\x20\xb1"
+"\xb8\xc1\xb6\xbf\xcd\x20\xb0\xa3\xb4\xdc\xc7\xcf\xc1\xf6\xb8\xb8"
+"\x20\xc8\xbf\xc0\xb2\xc0\xfb\xc0\xce\x20\xb0\xb4\xc3\xbc\xc1\xf6"
+"\xc7\xe2\xc7\xc1\xb7\xce\xb1\xd7\xb7\xa1\xb9\xd6\xc0\xbb\x0a\xc1"
+"\xf6\xbf\xf8\xc7\xd5\xb4\xcf\xb4\xd9\x2e\x20\xc6\xc4\xc0\xcc\xbd"
+"\xe3\xc0\xc7\x20\xbf\xec\xbe\xc6\x28\xe9\xd0\xe4\xba\x29\xc7\xd1"
+"\x20\xb9\xae\xb9\xfd\xb0\xfa\x20\xb5\xbf\xc0\xfb\x20\xc5\xb8\xc0"
+"\xcc\xc7\xce\x2c\x20\xb1\xd7\xb8\xae\xb0\xed\x20\xc0\xce\xc5\xcd"
+"\xc7\xc1\xb8\xae\xc6\xc3\x0a\xc8\xaf\xb0\xe6\xc0\xba\x20\xc6\xc4"
+"\xc0\xcc\xbd\xe3\xc0\xbb\x20\xbd\xba\xc5\xa9\xb8\xb3\xc6\xc3\xb0"
+"\xfa\x20\xbf\xa9\xb7\xc1\x20\xba\xd0\xbe\xdf\xbf\xa1\xbc\xad\xbf"
+"\xcd\x20\xb4\xeb\xba\xce\xba\xd0\xc0\xc7\x20\xc7\xc3\xb7\xa7\xc6"
+"\xfb\xbf\xa1\xbc\xad\xc0\xc7\x20\xba\xfc\xb8\xa5\x0a\xbe\xd6\xc7"
+"\xc3\xb8\xae\xc4\xc9\xc0\xcc\xbc\xc7\x20\xb0\xb3\xb9\xdf\xc0\xbb"
+"\x20\xc7\xd2\x20\xbc\xf6\x20\xc0\xd6\xb4\xc2\x20\xc0\xcc\xbb\xf3"
+"\xc0\xfb\xc0\xce\x20\xbe\xf0\xbe\xee\xb7\xce\x20\xb8\xb8\xb5\xe9"
+"\xbe\xee\xc1\xdd\xb4\xcf\xb4\xd9\x2e\x0a\x0a",
+"\xe2\x97\x8e\x20\xed\x8c\x8c\xec\x9d\xb4\xec\x8d\xac\x28\x50\x79"
+"\x74\x68\x6f\x6e\x29\xec\x9d\x80\x20\xeb\xb0\xb0\xec\x9a\xb0\xea"
+"\xb8\xb0\x20\xec\x89\xbd\xea\xb3\xa0\x2c\x20\xea\xb0\x95\xeb\xa0"
+"\xa5\xed\x95\x9c\x20\xed\x94\x84\xeb\xa1\x9c\xea\xb7\xb8\xeb\x9e"
+"\x98\xeb\xb0\x8d\x20\xec\x96\xb8\xec\x96\xb4\xec\x9e\x85\xeb\x8b"
+"\x88\xeb\x8b\xa4\x2e\x20\xed\x8c\x8c\xec\x9d\xb4\xec\x8d\xac\xec"
+"\x9d\x80\x0a\xed\x9a\xa8\xec\x9c\xa8\xec\xa0\x81\xec\x9d\xb8\x20"
+"\xea\xb3\xa0\xec\x88\x98\xec\xa4\x80\x20\xeb\x8d\xb0\xec\x9d\xb4"
+"\xed\x84\xb0\x20\xea\xb5\xac\xec\xa1\xb0\xec\x99\x80\x20\xea\xb0"
+"\x84\xeb\x8b\xa8\xed\x95\x98\xec\xa7\x80\xeb\xa7\x8c\x20\xed\x9a"
+"\xa8\xec\x9c\xa8\xec\xa0\x81\xec\x9d\xb8\x20\xea\xb0\x9d\xec\xb2"
+"\xb4\xec\xa7\x80\xed\x96\xa5\xed\x94\x84\xeb\xa1\x9c\xea\xb7\xb8"
+"\xeb\x9e\x98\xeb\xb0\x8d\xec\x9d\x84\x0a\xec\xa7\x80\xec\x9b\x90"
+"\xed\x95\xa9\xeb\x8b\x88\xeb\x8b\xa4\x2e\x20\xed\x8c\x8c\xec\x9d"
+"\xb4\xec\x8d\xac\xec\x9d\x98\x20\xec\x9a\xb0\xec\x95\x84\x28\xe5"
+"\x84\xaa\xe9\x9b\x85\x29\xed\x95\x9c\x20\xeb\xac\xb8\xeb\xb2\x95"
+"\xea\xb3\xbc\x20\xeb\x8f\x99\xec\xa0\x81\x20\xed\x83\x80\xec\x9d"
+"\xb4\xed\x95\x91\x2c\x20\xea\xb7\xb8\xeb\xa6\xac\xea\xb3\xa0\x20"
+"\xec\x9d\xb8\xed\x84\xb0\xed\x94\x84\xeb\xa6\xac\xed\x8c\x85\x0a"
+"\xed\x99\x98\xea\xb2\xbd\xec\x9d\x80\x20\xed\x8c\x8c\xec\x9d\xb4"
+"\xec\x8d\xac\xec\x9d\x84\x20\xec\x8a\xa4\xed\x81\xac\xeb\xa6\xbd"
+"\xed\x8c\x85\xea\xb3\xbc\x20\xec\x97\xac\xeb\xa0\xa4\x20\xeb\xb6"
+"\x84\xec\x95\xbc\xec\x97\x90\xec\x84\x9c\xec\x99\x80\x20\xeb\x8c"
+"\x80\xeb\xb6\x80\xeb\xb6\x84\xec\x9d\x98\x20\xed\x94\x8c\xeb\x9e"
+"\xab\xed\x8f\xbc\xec\x97\x90\xec\x84\x9c\xec\x9d\x98\x20\xeb\xb9"
+"\xa0\xeb\xa5\xb8\x0a\xec\x95\xa0\xed\x94\x8c\xeb\xa6\xac\xec\xbc"
+"\x80\xec\x9d\xb4\xec\x85\x98\x20\xea\xb0\x9c\xeb\xb0\x9c\xec\x9d"
+"\x84\x20\xed\x95\xa0\x20\xec\x88\x98\x20\xec\x9e\x88\xeb\x8a\x94"
+"\x20\xec\x9d\xb4\xec\x83\x81\xec\xa0\x81\xec\x9d\xb8\x20\xec\x96"
+"\xb8\xec\x96\xb4\xeb\xa1\x9c\x20\xeb\xa7\x8c\xeb\x93\xa4\xec\x96"
+"\xb4\xec\xa4\x8d\xeb\x8b\x88\xeb\x8b\xa4\x2e\x0a\x0a"),
+'gb18030': (
+"\x50\x79\x74\x68\x6f\x6e\xa3\xa8\xc5\xc9\xc9\xad\xa3\xa9\xd3\xef"
+"\xd1\xd4\xca\xc7\xd2\xbb\xd6\xd6\xb9\xa6\xc4\xdc\xc7\xbf\xb4\xf3"
+"\xb6\xf8\xcd\xea\xc9\xc6\xb5\xc4\xcd\xa8\xd3\xc3\xd0\xcd\xbc\xc6"
+"\xcb\xe3\xbb\xfa\xb3\xcc\xd0\xf2\xc9\xe8\xbc\xc6\xd3\xef\xd1\xd4"
+"\xa3\xac\x0a\xd2\xd1\xbe\xad\xbe\xdf\xd3\xd0\xca\xae\xb6\xe0\xc4"
+"\xea\xb5\xc4\xb7\xa2\xd5\xb9\xc0\xfa\xca\xb7\xa3\xac\xb3\xc9\xca"
+"\xec\xc7\xd2\xce\xc8\xb6\xa8\xa1\xa3\xd5\xe2\xd6\xd6\xd3\xef\xd1"
+"\xd4\xbe\xdf\xd3\xd0\xb7\xc7\xb3\xa3\xbc\xf2\xbd\xdd\xb6\xf8\xc7"
+"\xe5\xce\xfa\x0a\xb5\xc4\xd3\xef\xb7\xa8\xcc\xd8\xb5\xe3\xa3\xac"
+"\xca\xca\xba\xcf\xcd\xea\xb3\xc9\xb8\xf7\xd6\xd6\xb8\xdf\xb2\xe3"
+"\xc8\xce\xce\xf1\xa3\xac\xbc\xb8\xba\xf5\xbf\xc9\xd2\xd4\xd4\xda"
+"\xcb\xf9\xd3\xd0\xb5\xc4\xb2\xd9\xd7\xf7\xcf\xb5\xcd\xb3\xd6\xd0"
+"\x0a\xd4\xcb\xd0\xd0\xa1\xa3\xd5\xe2\xd6\xd6\xd3\xef\xd1\xd4\xbc"
+"\xf2\xb5\xa5\xb6\xf8\xc7\xbf\xb4\xf3\xa3\xac\xca\xca\xba\xcf\xb8"
+"\xf7\xd6\xd6\xc8\xcb\xca\xbf\xd1\xa7\xcf\xb0\xca\xb9\xd3\xc3\xa1"
+"\xa3\xc4\xbf\xc7\xb0\xa3\xac\xbb\xf9\xd3\xda\xd5\xe2\x0a\xd6\xd6"
+"\xd3\xef\xd1\xd4\xb5\xc4\xcf\xe0\xb9\xd8\xbc\xbc\xca\xf5\xd5\xfd"
+"\xd4\xda\xb7\xc9\xcb\xd9\xb5\xc4\xb7\xa2\xd5\xb9\xa3\xac\xd3\xc3"
+"\xbb\xa7\xca\xfd\xc1\xbf\xbc\xb1\xbe\xe7\xc0\xa9\xb4\xf3\xa3\xac"
+"\xcf\xe0\xb9\xd8\xb5\xc4\xd7\xca\xd4\xb4\xb7\xc7\xb3\xa3\xb6\xe0"
+"\xa1\xa3\x0a\xc8\xe7\xba\xce\xd4\xda\x20\x50\x79\x74\x68\x6f\x6e"
+"\x20\xd6\xd0\xca\xb9\xd3\xc3\xbc\xc8\xd3\xd0\xb5\xc4\x20\x43\x20"
+"\x6c\x69\x62\x72\x61\x72\x79\x3f\x0a\xa1\xa1\xd4\xda\xd9\x59\xd3"
+"\x8d\xbf\xc6\xbc\xbc\xbf\xec\xcb\xd9\xb0\x6c\xd5\xb9\xb5\xc4\xbd"
+"\xf1\xcc\xec\x2c\x20\xe9\x5f\xb0\x6c\xbc\xb0\x9c\x79\xd4\x87\xdc"
+"\x9b\xf3\x77\xb5\xc4\xcb\xd9\xb6\xc8\xca\xc7\xb2\xbb\xc8\xdd\xba"
+"\xf6\xd2\x95\xb5\xc4\x0a\xd5\x6e\xee\x7d\x2e\x20\x9e\xe9\xbc\xd3"
+"\xbf\xec\xe9\x5f\xb0\x6c\xbc\xb0\x9c\x79\xd4\x87\xb5\xc4\xcb\xd9"
+"\xb6\xc8\x2c\x20\xce\xd2\x82\x83\xb1\xe3\xb3\xa3\xcf\xa3\xcd\xfb"
+"\xc4\xdc\xc0\xfb\xd3\xc3\xd2\xbb\xd0\xa9\xd2\xd1\xe9\x5f\xb0\x6c"
+"\xba\xc3\xb5\xc4\x0a\x6c\x69\x62\x72\x61\x72\x79\x2c\x20\x81\x4b"
+"\xd3\xd0\xd2\xbb\x82\x80\x20\x66\x61\x73\x74\x20\x70\x72\x6f\x74"
+"\x6f\x74\x79\x70\x69\x6e\x67\x20\xb5\xc4\x20\x70\x72\x6f\x67\x72"
+"\x61\x6d\x6d\x69\x6e\x67\x20\x6c\x61\x6e\x67\x75\x61\x67\x65\x20"
+"\xbf\xc9\x0a\xb9\xa9\xca\xb9\xd3\xc3\x2e\x20\xc4\xbf\xc7\xb0\xd3"
+"\xd0\xd4\x53\xd4\x53\xb6\xe0\xb6\xe0\xb5\xc4\x20\x6c\x69\x62\x72"
+"\x61\x72\x79\x20\xca\xc7\xd2\xd4\x20\x43\x20\x8c\x91\xb3\xc9\x2c"
+"\x20\xb6\xf8\x20\x50\x79\x74\x68\x6f\x6e\x20\xca\xc7\xd2\xbb\x82"
+"\x80\x0a\x66\x61\x73\x74\x20\x70\x72\x6f\x74\x6f\x74\x79\x70\x69"
+"\x6e\x67\x20\xb5\xc4\x20\x70\x72\x6f\x67\x72\x61\x6d\x6d\x69\x6e"
+"\x67\x20\x6c\x61\x6e\x67\x75\x61\x67\x65\x2e\x20\xb9\xca\xce\xd2"
+"\x82\x83\xcf\xa3\xcd\xfb\xc4\xdc\x8c\xa2\xbc\xc8\xd3\xd0\xb5\xc4"
+"\x0a\x43\x20\x6c\x69\x62\x72\x61\x72\x79\x20\xc4\xc3\xb5\xbd\x20"
+"\x50\x79\x74\x68\x6f\x6e\x20\xb5\xc4\xad\x68\xbe\xb3\xd6\xd0\x9c"
+"\x79\xd4\x87\xbc\xb0\xd5\xfb\xba\xcf\x2e\x20\xc6\xe4\xd6\xd0\xd7"
+"\xee\xd6\xf7\xd2\xaa\xd2\xb2\xca\xc7\xce\xd2\x82\x83\xcb\xf9\x0a"
+"\xd2\xaa\xd3\x91\xd5\x93\xb5\xc4\x86\x96\xee\x7d\xbe\xcd\xca\xc7"
+"\x3a\x0a\x83\x35\xc7\x31\x83\x33\x9a\x33\x83\x32\xb1\x31\x83\x33"
+"\x95\x31\x20\x82\x37\xd1\x36\x83\x30\x8c\x34\x83\x36\x84\x33\x20"
+"\x82\x38\x89\x35\x82\x38\xfb\x36\x83\x33\x95\x35\x20\x83\x33\xd5"
+"\x31\x82\x39\x81\x35\x20\x83\x30\xfd\x39\x83\x33\x86\x30\x20\x83"
+"\x34\xdc\x33\x83\x35\xf6\x37\x83\x35\x97\x35\x20\x83\x35\xf9\x35"
+"\x83\x30\x91\x39\x82\x38\x83\x39\x82\x39\xfc\x33\x83\x30\xf0\x34"
+"\x20\x83\x32\xeb\x39\x83\x32\xeb\x35\x82\x39\x83\x39\x2e\x0a\x0a",
+"\x50\x79\x74\x68\x6f\x6e\xef\xbc\x88\xe6\xb4\xbe\xe6\xa3\xae\xef"
+"\xbc\x89\xe8\xaf\xad\xe8\xa8\x80\xe6\x98\xaf\xe4\xb8\x80\xe7\xa7"
+"\x8d\xe5\x8a\x9f\xe8\x83\xbd\xe5\xbc\xba\xe5\xa4\xa7\xe8\x80\x8c"
+"\xe5\xae\x8c\xe5\x96\x84\xe7\x9a\x84\xe9\x80\x9a\xe7\x94\xa8\xe5"
+"\x9e\x8b\xe8\xae\xa1\xe7\xae\x97\xe6\x9c\xba\xe7\xa8\x8b\xe5\xba"
+"\x8f\xe8\xae\xbe\xe8\xae\xa1\xe8\xaf\xad\xe8\xa8\x80\xef\xbc\x8c"
+"\x0a\xe5\xb7\xb2\xe7\xbb\x8f\xe5\x85\xb7\xe6\x9c\x89\xe5\x8d\x81"
+"\xe5\xa4\x9a\xe5\xb9\xb4\xe7\x9a\x84\xe5\x8f\x91\xe5\xb1\x95\xe5"
+"\x8e\x86\xe5\x8f\xb2\xef\xbc\x8c\xe6\x88\x90\xe7\x86\x9f\xe4\xb8"
+"\x94\xe7\xa8\xb3\xe5\xae\x9a\xe3\x80\x82\xe8\xbf\x99\xe7\xa7\x8d"
+"\xe8\xaf\xad\xe8\xa8\x80\xe5\x85\xb7\xe6\x9c\x89\xe9\x9d\x9e\xe5"
+"\xb8\xb8\xe7\xae\x80\xe6\x8d\xb7\xe8\x80\x8c\xe6\xb8\x85\xe6\x99"
+"\xb0\x0a\xe7\x9a\x84\xe8\xaf\xad\xe6\xb3\x95\xe7\x89\xb9\xe7\x82"
+"\xb9\xef\xbc\x8c\xe9\x80\x82\xe5\x90\x88\xe5\xae\x8c\xe6\x88\x90"
+"\xe5\x90\x84\xe7\xa7\x8d\xe9\xab\x98\xe5\xb1\x82\xe4\xbb\xbb\xe5"
+"\x8a\xa1\xef\xbc\x8c\xe5\x87\xa0\xe4\xb9\x8e\xe5\x8f\xaf\xe4\xbb"
+"\xa5\xe5\x9c\xa8\xe6\x89\x80\xe6\x9c\x89\xe7\x9a\x84\xe6\x93\x8d"
+"\xe4\xbd\x9c\xe7\xb3\xbb\xe7\xbb\x9f\xe4\xb8\xad\x0a\xe8\xbf\x90"
+"\xe8\xa1\x8c\xe3\x80\x82\xe8\xbf\x99\xe7\xa7\x8d\xe8\xaf\xad\xe8"
+"\xa8\x80\xe7\xae\x80\xe5\x8d\x95\xe8\x80\x8c\xe5\xbc\xba\xe5\xa4"
+"\xa7\xef\xbc\x8c\xe9\x80\x82\xe5\x90\x88\xe5\x90\x84\xe7\xa7\x8d"
+"\xe4\xba\xba\xe5\xa3\xab\xe5\xad\xa6\xe4\xb9\xa0\xe4\xbd\xbf\xe7"
+"\x94\xa8\xe3\x80\x82\xe7\x9b\xae\xe5\x89\x8d\xef\xbc\x8c\xe5\x9f"
+"\xba\xe4\xba\x8e\xe8\xbf\x99\x0a\xe7\xa7\x8d\xe8\xaf\xad\xe8\xa8"
+"\x80\xe7\x9a\x84\xe7\x9b\xb8\xe5\x85\xb3\xe6\x8a\x80\xe6\x9c\xaf"
+"\xe6\xad\xa3\xe5\x9c\xa8\xe9\xa3\x9e\xe9\x80\x9f\xe7\x9a\x84\xe5"
+"\x8f\x91\xe5\xb1\x95\xef\xbc\x8c\xe7\x94\xa8\xe6\x88\xb7\xe6\x95"
+"\xb0\xe9\x87\x8f\xe6\x80\xa5\xe5\x89\xa7\xe6\x89\xa9\xe5\xa4\xa7"
+"\xef\xbc\x8c\xe7\x9b\xb8\xe5\x85\xb3\xe7\x9a\x84\xe8\xb5\x84\xe6"
+"\xba\x90\xe9\x9d\x9e\xe5\xb8\xb8\xe5\xa4\x9a\xe3\x80\x82\x0a\xe5"
+"\xa6\x82\xe4\xbd\x95\xe5\x9c\xa8\x20\x50\x79\x74\x68\x6f\x6e\x20"
+"\xe4\xb8\xad\xe4\xbd\xbf\xe7\x94\xa8\xe6\x97\xa2\xe6\x9c\x89\xe7"
+"\x9a\x84\x20\x43\x20\x6c\x69\x62\x72\x61\x72\x79\x3f\x0a\xe3\x80"
+"\x80\xe5\x9c\xa8\xe8\xb3\x87\xe8\xa8\x8a\xe7\xa7\x91\xe6\x8a\x80"
+"\xe5\xbf\xab\xe9\x80\x9f\xe7\x99\xbc\xe5\xb1\x95\xe7\x9a\x84\xe4"
+"\xbb\x8a\xe5\xa4\xa9\x2c\x20\xe9\x96\x8b\xe7\x99\xbc\xe5\x8f\x8a"
+"\xe6\xb8\xac\xe8\xa9\xa6\xe8\xbb\x9f\xe9\xab\x94\xe7\x9a\x84\xe9"
+"\x80\x9f\xe5\xba\xa6\xe6\x98\xaf\xe4\xb8\x8d\xe5\xae\xb9\xe5\xbf"
+"\xbd\xe8\xa6\x96\xe7\x9a\x84\x0a\xe8\xaa\xb2\xe9\xa1\x8c\x2e\x20"
+"\xe7\x82\xba\xe5\x8a\xa0\xe5\xbf\xab\xe9\x96\x8b\xe7\x99\xbc\xe5"
+"\x8f\x8a\xe6\xb8\xac\xe8\xa9\xa6\xe7\x9a\x84\xe9\x80\x9f\xe5\xba"
+"\xa6\x2c\x20\xe6\x88\x91\xe5\x80\x91\xe4\xbe\xbf\xe5\xb8\xb8\xe5"
+"\xb8\x8c\xe6\x9c\x9b\xe8\x83\xbd\xe5\x88\xa9\xe7\x94\xa8\xe4\xb8"
+"\x80\xe4\xba\x9b\xe5\xb7\xb2\xe9\x96\x8b\xe7\x99\xbc\xe5\xa5\xbd"
+"\xe7\x9a\x84\x0a\x6c\x69\x62\x72\x61\x72\x79\x2c\x20\xe4\xb8\xa6"
+"\xe6\x9c\x89\xe4\xb8\x80\xe5\x80\x8b\x20\x66\x61\x73\x74\x20\x70"
+"\x72\x6f\x74\x6f\x74\x79\x70\x69\x6e\x67\x20\xe7\x9a\x84\x20\x70"
+"\x72\x6f\x67\x72\x61\x6d\x6d\x69\x6e\x67\x20\x6c\x61\x6e\x67\x75"
+"\x61\x67\x65\x20\xe5\x8f\xaf\x0a\xe4\xbe\x9b\xe4\xbd\xbf\xe7\x94"
+"\xa8\x2e\x20\xe7\x9b\xae\xe5\x89\x8d\xe6\x9c\x89\xe8\xa8\xb1\xe8"
+"\xa8\xb1\xe5\xa4\x9a\xe5\xa4\x9a\xe7\x9a\x84\x20\x6c\x69\x62\x72"
+"\x61\x72\x79\x20\xe6\x98\xaf\xe4\xbb\xa5\x20\x43\x20\xe5\xaf\xab"
+"\xe6\x88\x90\x2c\x20\xe8\x80\x8c\x20\x50\x79\x74\x68\x6f\x6e\x20"
+"\xe6\x98\xaf\xe4\xb8\x80\xe5\x80\x8b\x0a\x66\x61\x73\x74\x20\x70"
+"\x72\x6f\x74\x6f\x74\x79\x70\x69\x6e\x67\x20\xe7\x9a\x84\x20\x70"
+"\x72\x6f\x67\x72\x61\x6d\x6d\x69\x6e\x67\x20\x6c\x61\x6e\x67\x75"
+"\x61\x67\x65\x2e\x20\xe6\x95\x85\xe6\x88\x91\xe5\x80\x91\xe5\xb8"
+"\x8c\xe6\x9c\x9b\xe8\x83\xbd\xe5\xb0\x87\xe6\x97\xa2\xe6\x9c\x89"
+"\xe7\x9a\x84\x0a\x43\x20\x6c\x69\x62\x72\x61\x72\x79\x20\xe6\x8b"
+"\xbf\xe5\x88\xb0\x20\x50\x79\x74\x68\x6f\x6e\x20\xe7\x9a\x84\xe7"
+"\x92\xb0\xe5\xa2\x83\xe4\xb8\xad\xe6\xb8\xac\xe8\xa9\xa6\xe5\x8f"
+"\x8a\xe6\x95\xb4\xe5\x90\x88\x2e\x20\xe5\x85\xb6\xe4\xb8\xad\xe6"
+"\x9c\x80\xe4\xb8\xbb\xe8\xa6\x81\xe4\xb9\x9f\xe6\x98\xaf\xe6\x88"
+"\x91\xe5\x80\x91\xe6\x89\x80\x0a\xe8\xa6\x81\xe8\xa8\x8e\xe8\xab"
+"\x96\xe7\x9a\x84\xe5\x95\x8f\xe9\xa1\x8c\xe5\xb0\xb1\xe6\x98\xaf"
+"\x3a\x0a\xed\x8c\x8c\xec\x9d\xb4\xec\x8d\xac\xec\x9d\x80\x20\xea"
+"\xb0\x95\xeb\xa0\xa5\xed\x95\x9c\x20\xea\xb8\xb0\xeb\x8a\xa5\xec"
+"\x9d\x84\x20\xec\xa7\x80\xeb\x8b\x8c\x20\xeb\xb2\x94\xec\x9a\xa9"
+"\x20\xec\xbb\xb4\xed\x93\xa8\xed\x84\xb0\x20\xed\x94\x84\xeb\xa1"
+"\x9c\xea\xb7\xb8\xeb\x9e\x98\xeb\xb0\x8d\x20\xec\x96\xb8\xec\x96"
+"\xb4\xeb\x8b\xa4\x2e\x0a\x0a"),
+'gb2312': (
+"\x50\x79\x74\x68\x6f\x6e\xa3\xa8\xc5\xc9\xc9\xad\xa3\xa9\xd3\xef"
+"\xd1\xd4\xca\xc7\xd2\xbb\xd6\xd6\xb9\xa6\xc4\xdc\xc7\xbf\xb4\xf3"
+"\xb6\xf8\xcd\xea\xc9\xc6\xb5\xc4\xcd\xa8\xd3\xc3\xd0\xcd\xbc\xc6"
+"\xcb\xe3\xbb\xfa\xb3\xcc\xd0\xf2\xc9\xe8\xbc\xc6\xd3\xef\xd1\xd4"
+"\xa3\xac\x0a\xd2\xd1\xbe\xad\xbe\xdf\xd3\xd0\xca\xae\xb6\xe0\xc4"
+"\xea\xb5\xc4\xb7\xa2\xd5\xb9\xc0\xfa\xca\xb7\xa3\xac\xb3\xc9\xca"
+"\xec\xc7\xd2\xce\xc8\xb6\xa8\xa1\xa3\xd5\xe2\xd6\xd6\xd3\xef\xd1"
+"\xd4\xbe\xdf\xd3\xd0\xb7\xc7\xb3\xa3\xbc\xf2\xbd\xdd\xb6\xf8\xc7"
+"\xe5\xce\xfa\x0a\xb5\xc4\xd3\xef\xb7\xa8\xcc\xd8\xb5\xe3\xa3\xac"
+"\xca\xca\xba\xcf\xcd\xea\xb3\xc9\xb8\xf7\xd6\xd6\xb8\xdf\xb2\xe3"
+"\xc8\xce\xce\xf1\xa3\xac\xbc\xb8\xba\xf5\xbf\xc9\xd2\xd4\xd4\xda"
+"\xcb\xf9\xd3\xd0\xb5\xc4\xb2\xd9\xd7\xf7\xcf\xb5\xcd\xb3\xd6\xd0"
+"\x0a\xd4\xcb\xd0\xd0\xa1\xa3\xd5\xe2\xd6\xd6\xd3\xef\xd1\xd4\xbc"
+"\xf2\xb5\xa5\xb6\xf8\xc7\xbf\xb4\xf3\xa3\xac\xca\xca\xba\xcf\xb8"
+"\xf7\xd6\xd6\xc8\xcb\xca\xbf\xd1\xa7\xcf\xb0\xca\xb9\xd3\xc3\xa1"
+"\xa3\xc4\xbf\xc7\xb0\xa3\xac\xbb\xf9\xd3\xda\xd5\xe2\x0a\xd6\xd6"
+"\xd3\xef\xd1\xd4\xb5\xc4\xcf\xe0\xb9\xd8\xbc\xbc\xca\xf5\xd5\xfd"
+"\xd4\xda\xb7\xc9\xcb\xd9\xb5\xc4\xb7\xa2\xd5\xb9\xa3\xac\xd3\xc3"
+"\xbb\xa7\xca\xfd\xc1\xbf\xbc\xb1\xbe\xe7\xc0\xa9\xb4\xf3\xa3\xac"
+"\xcf\xe0\xb9\xd8\xb5\xc4\xd7\xca\xd4\xb4\xb7\xc7\xb3\xa3\xb6\xe0"
+"\xa1\xa3\x0a\x0a",
+"\x50\x79\x74\x68\x6f\x6e\xef\xbc\x88\xe6\xb4\xbe\xe6\xa3\xae\xef"
+"\xbc\x89\xe8\xaf\xad\xe8\xa8\x80\xe6\x98\xaf\xe4\xb8\x80\xe7\xa7"
+"\x8d\xe5\x8a\x9f\xe8\x83\xbd\xe5\xbc\xba\xe5\xa4\xa7\xe8\x80\x8c"
+"\xe5\xae\x8c\xe5\x96\x84\xe7\x9a\x84\xe9\x80\x9a\xe7\x94\xa8\xe5"
+"\x9e\x8b\xe8\xae\xa1\xe7\xae\x97\xe6\x9c\xba\xe7\xa8\x8b\xe5\xba"
+"\x8f\xe8\xae\xbe\xe8\xae\xa1\xe8\xaf\xad\xe8\xa8\x80\xef\xbc\x8c"
+"\x0a\xe5\xb7\xb2\xe7\xbb\x8f\xe5\x85\xb7\xe6\x9c\x89\xe5\x8d\x81"
+"\xe5\xa4\x9a\xe5\xb9\xb4\xe7\x9a\x84\xe5\x8f\x91\xe5\xb1\x95\xe5"
+"\x8e\x86\xe5\x8f\xb2\xef\xbc\x8c\xe6\x88\x90\xe7\x86\x9f\xe4\xb8"
+"\x94\xe7\xa8\xb3\xe5\xae\x9a\xe3\x80\x82\xe8\xbf\x99\xe7\xa7\x8d"
+"\xe8\xaf\xad\xe8\xa8\x80\xe5\x85\xb7\xe6\x9c\x89\xe9\x9d\x9e\xe5"
+"\xb8\xb8\xe7\xae\x80\xe6\x8d\xb7\xe8\x80\x8c\xe6\xb8\x85\xe6\x99"
+"\xb0\x0a\xe7\x9a\x84\xe8\xaf\xad\xe6\xb3\x95\xe7\x89\xb9\xe7\x82"
+"\xb9\xef\xbc\x8c\xe9\x80\x82\xe5\x90\x88\xe5\xae\x8c\xe6\x88\x90"
+"\xe5\x90\x84\xe7\xa7\x8d\xe9\xab\x98\xe5\xb1\x82\xe4\xbb\xbb\xe5"
+"\x8a\xa1\xef\xbc\x8c\xe5\x87\xa0\xe4\xb9\x8e\xe5\x8f\xaf\xe4\xbb"
+"\xa5\xe5\x9c\xa8\xe6\x89\x80\xe6\x9c\x89\xe7\x9a\x84\xe6\x93\x8d"
+"\xe4\xbd\x9c\xe7\xb3\xbb\xe7\xbb\x9f\xe4\xb8\xad\x0a\xe8\xbf\x90"
+"\xe8\xa1\x8c\xe3\x80\x82\xe8\xbf\x99\xe7\xa7\x8d\xe8\xaf\xad\xe8"
+"\xa8\x80\xe7\xae\x80\xe5\x8d\x95\xe8\x80\x8c\xe5\xbc\xba\xe5\xa4"
+"\xa7\xef\xbc\x8c\xe9\x80\x82\xe5\x90\x88\xe5\x90\x84\xe7\xa7\x8d"
+"\xe4\xba\xba\xe5\xa3\xab\xe5\xad\xa6\xe4\xb9\xa0\xe4\xbd\xbf\xe7"
+"\x94\xa8\xe3\x80\x82\xe7\x9b\xae\xe5\x89\x8d\xef\xbc\x8c\xe5\x9f"
+"\xba\xe4\xba\x8e\xe8\xbf\x99\x0a\xe7\xa7\x8d\xe8\xaf\xad\xe8\xa8"
+"\x80\xe7\x9a\x84\xe7\x9b\xb8\xe5\x85\xb3\xe6\x8a\x80\xe6\x9c\xaf"
+"\xe6\xad\xa3\xe5\x9c\xa8\xe9\xa3\x9e\xe9\x80\x9f\xe7\x9a\x84\xe5"
+"\x8f\x91\xe5\xb1\x95\xef\xbc\x8c\xe7\x94\xa8\xe6\x88\xb7\xe6\x95"
+"\xb0\xe9\x87\x8f\xe6\x80\xa5\xe5\x89\xa7\xe6\x89\xa9\xe5\xa4\xa7"
+"\xef\xbc\x8c\xe7\x9b\xb8\xe5\x85\xb3\xe7\x9a\x84\xe8\xb5\x84\xe6"
+"\xba\x90\xe9\x9d\x9e\xe5\xb8\xb8\xe5\xa4\x9a\xe3\x80\x82\x0a\x0a"),
+'gbk': (
+"\x50\x79\x74\x68\x6f\x6e\xa3\xa8\xc5\xc9\xc9\xad\xa3\xa9\xd3\xef"
+"\xd1\xd4\xca\xc7\xd2\xbb\xd6\xd6\xb9\xa6\xc4\xdc\xc7\xbf\xb4\xf3"
+"\xb6\xf8\xcd\xea\xc9\xc6\xb5\xc4\xcd\xa8\xd3\xc3\xd0\xcd\xbc\xc6"
+"\xcb\xe3\xbb\xfa\xb3\xcc\xd0\xf2\xc9\xe8\xbc\xc6\xd3\xef\xd1\xd4"
+"\xa3\xac\x0a\xd2\xd1\xbe\xad\xbe\xdf\xd3\xd0\xca\xae\xb6\xe0\xc4"
+"\xea\xb5\xc4\xb7\xa2\xd5\xb9\xc0\xfa\xca\xb7\xa3\xac\xb3\xc9\xca"
+"\xec\xc7\xd2\xce\xc8\xb6\xa8\xa1\xa3\xd5\xe2\xd6\xd6\xd3\xef\xd1"
+"\xd4\xbe\xdf\xd3\xd0\xb7\xc7\xb3\xa3\xbc\xf2\xbd\xdd\xb6\xf8\xc7"
+"\xe5\xce\xfa\x0a\xb5\xc4\xd3\xef\xb7\xa8\xcc\xd8\xb5\xe3\xa3\xac"
+"\xca\xca\xba\xcf\xcd\xea\xb3\xc9\xb8\xf7\xd6\xd6\xb8\xdf\xb2\xe3"
+"\xc8\xce\xce\xf1\xa3\xac\xbc\xb8\xba\xf5\xbf\xc9\xd2\xd4\xd4\xda"
+"\xcb\xf9\xd3\xd0\xb5\xc4\xb2\xd9\xd7\xf7\xcf\xb5\xcd\xb3\xd6\xd0"
+"\x0a\xd4\xcb\xd0\xd0\xa1\xa3\xd5\xe2\xd6\xd6\xd3\xef\xd1\xd4\xbc"
+"\xf2\xb5\xa5\xb6\xf8\xc7\xbf\xb4\xf3\xa3\xac\xca\xca\xba\xcf\xb8"
+"\xf7\xd6\xd6\xc8\xcb\xca\xbf\xd1\xa7\xcf\xb0\xca\xb9\xd3\xc3\xa1"
+"\xa3\xc4\xbf\xc7\xb0\xa3\xac\xbb\xf9\xd3\xda\xd5\xe2\x0a\xd6\xd6"
+"\xd3\xef\xd1\xd4\xb5\xc4\xcf\xe0\xb9\xd8\xbc\xbc\xca\xf5\xd5\xfd"
+"\xd4\xda\xb7\xc9\xcb\xd9\xb5\xc4\xb7\xa2\xd5\xb9\xa3\xac\xd3\xc3"
+"\xbb\xa7\xca\xfd\xc1\xbf\xbc\xb1\xbe\xe7\xc0\xa9\xb4\xf3\xa3\xac"
+"\xcf\xe0\xb9\xd8\xb5\xc4\xd7\xca\xd4\xb4\xb7\xc7\xb3\xa3\xb6\xe0"
+"\xa1\xa3\x0a\xc8\xe7\xba\xce\xd4\xda\x20\x50\x79\x74\x68\x6f\x6e"
+"\x20\xd6\xd0\xca\xb9\xd3\xc3\xbc\xc8\xd3\xd0\xb5\xc4\x20\x43\x20"
+"\x6c\x69\x62\x72\x61\x72\x79\x3f\x0a\xa1\xa1\xd4\xda\xd9\x59\xd3"
+"\x8d\xbf\xc6\xbc\xbc\xbf\xec\xcb\xd9\xb0\x6c\xd5\xb9\xb5\xc4\xbd"
+"\xf1\xcc\xec\x2c\x20\xe9\x5f\xb0\x6c\xbc\xb0\x9c\x79\xd4\x87\xdc"
+"\x9b\xf3\x77\xb5\xc4\xcb\xd9\xb6\xc8\xca\xc7\xb2\xbb\xc8\xdd\xba"
+"\xf6\xd2\x95\xb5\xc4\x0a\xd5\x6e\xee\x7d\x2e\x20\x9e\xe9\xbc\xd3"
+"\xbf\xec\xe9\x5f\xb0\x6c\xbc\xb0\x9c\x79\xd4\x87\xb5\xc4\xcb\xd9"
+"\xb6\xc8\x2c\x20\xce\xd2\x82\x83\xb1\xe3\xb3\xa3\xcf\xa3\xcd\xfb"
+"\xc4\xdc\xc0\xfb\xd3\xc3\xd2\xbb\xd0\xa9\xd2\xd1\xe9\x5f\xb0\x6c"
+"\xba\xc3\xb5\xc4\x0a\x6c\x69\x62\x72\x61\x72\x79\x2c\x20\x81\x4b"
+"\xd3\xd0\xd2\xbb\x82\x80\x20\x66\x61\x73\x74\x20\x70\x72\x6f\x74"
+"\x6f\x74\x79\x70\x69\x6e\x67\x20\xb5\xc4\x20\x70\x72\x6f\x67\x72"
+"\x61\x6d\x6d\x69\x6e\x67\x20\x6c\x61\x6e\x67\x75\x61\x67\x65\x20"
+"\xbf\xc9\x0a\xb9\xa9\xca\xb9\xd3\xc3\x2e\x20\xc4\xbf\xc7\xb0\xd3"
+"\xd0\xd4\x53\xd4\x53\xb6\xe0\xb6\xe0\xb5\xc4\x20\x6c\x69\x62\x72"
+"\x61\x72\x79\x20\xca\xc7\xd2\xd4\x20\x43\x20\x8c\x91\xb3\xc9\x2c"
+"\x20\xb6\xf8\x20\x50\x79\x74\x68\x6f\x6e\x20\xca\xc7\xd2\xbb\x82"
+"\x80\x0a\x66\x61\x73\x74\x20\x70\x72\x6f\x74\x6f\x74\x79\x70\x69"
+"\x6e\x67\x20\xb5\xc4\x20\x70\x72\x6f\x67\x72\x61\x6d\x6d\x69\x6e"
+"\x67\x20\x6c\x61\x6e\x67\x75\x61\x67\x65\x2e\x20\xb9\xca\xce\xd2"
+"\x82\x83\xcf\xa3\xcd\xfb\xc4\xdc\x8c\xa2\xbc\xc8\xd3\xd0\xb5\xc4"
+"\x0a\x43\x20\x6c\x69\x62\x72\x61\x72\x79\x20\xc4\xc3\xb5\xbd\x20"
+"\x50\x79\x74\x68\x6f\x6e\x20\xb5\xc4\xad\x68\xbe\xb3\xd6\xd0\x9c"
+"\x79\xd4\x87\xbc\xb0\xd5\xfb\xba\xcf\x2e\x20\xc6\xe4\xd6\xd0\xd7"
+"\xee\xd6\xf7\xd2\xaa\xd2\xb2\xca\xc7\xce\xd2\x82\x83\xcb\xf9\x0a"
+"\xd2\xaa\xd3\x91\xd5\x93\xb5\xc4\x86\x96\xee\x7d\xbe\xcd\xca\xc7"
+"\x3a\x0a\x0a",
+"\x50\x79\x74\x68\x6f\x6e\xef\xbc\x88\xe6\xb4\xbe\xe6\xa3\xae\xef"
+"\xbc\x89\xe8\xaf\xad\xe8\xa8\x80\xe6\x98\xaf\xe4\xb8\x80\xe7\xa7"
+"\x8d\xe5\x8a\x9f\xe8\x83\xbd\xe5\xbc\xba\xe5\xa4\xa7\xe8\x80\x8c"
+"\xe5\xae\x8c\xe5\x96\x84\xe7\x9a\x84\xe9\x80\x9a\xe7\x94\xa8\xe5"
+"\x9e\x8b\xe8\xae\xa1\xe7\xae\x97\xe6\x9c\xba\xe7\xa8\x8b\xe5\xba"
+"\x8f\xe8\xae\xbe\xe8\xae\xa1\xe8\xaf\xad\xe8\xa8\x80\xef\xbc\x8c"
+"\x0a\xe5\xb7\xb2\xe7\xbb\x8f\xe5\x85\xb7\xe6\x9c\x89\xe5\x8d\x81"
+"\xe5\xa4\x9a\xe5\xb9\xb4\xe7\x9a\x84\xe5\x8f\x91\xe5\xb1\x95\xe5"
+"\x8e\x86\xe5\x8f\xb2\xef\xbc\x8c\xe6\x88\x90\xe7\x86\x9f\xe4\xb8"
+"\x94\xe7\xa8\xb3\xe5\xae\x9a\xe3\x80\x82\xe8\xbf\x99\xe7\xa7\x8d"
+"\xe8\xaf\xad\xe8\xa8\x80\xe5\x85\xb7\xe6\x9c\x89\xe9\x9d\x9e\xe5"
+"\xb8\xb8\xe7\xae\x80\xe6\x8d\xb7\xe8\x80\x8c\xe6\xb8\x85\xe6\x99"
+"\xb0\x0a\xe7\x9a\x84\xe8\xaf\xad\xe6\xb3\x95\xe7\x89\xb9\xe7\x82"
+"\xb9\xef\xbc\x8c\xe9\x80\x82\xe5\x90\x88\xe5\xae\x8c\xe6\x88\x90"
+"\xe5\x90\x84\xe7\xa7\x8d\xe9\xab\x98\xe5\xb1\x82\xe4\xbb\xbb\xe5"
+"\x8a\xa1\xef\xbc\x8c\xe5\x87\xa0\xe4\xb9\x8e\xe5\x8f\xaf\xe4\xbb"
+"\xa5\xe5\x9c\xa8\xe6\x89\x80\xe6\x9c\x89\xe7\x9a\x84\xe6\x93\x8d"
+"\xe4\xbd\x9c\xe7\xb3\xbb\xe7\xbb\x9f\xe4\xb8\xad\x0a\xe8\xbf\x90"
+"\xe8\xa1\x8c\xe3\x80\x82\xe8\xbf\x99\xe7\xa7\x8d\xe8\xaf\xad\xe8"
+"\xa8\x80\xe7\xae\x80\xe5\x8d\x95\xe8\x80\x8c\xe5\xbc\xba\xe5\xa4"
+"\xa7\xef\xbc\x8c\xe9\x80\x82\xe5\x90\x88\xe5\x90\x84\xe7\xa7\x8d"
+"\xe4\xba\xba\xe5\xa3\xab\xe5\xad\xa6\xe4\xb9\xa0\xe4\xbd\xbf\xe7"
+"\x94\xa8\xe3\x80\x82\xe7\x9b\xae\xe5\x89\x8d\xef\xbc\x8c\xe5\x9f"
+"\xba\xe4\xba\x8e\xe8\xbf\x99\x0a\xe7\xa7\x8d\xe8\xaf\xad\xe8\xa8"
+"\x80\xe7\x9a\x84\xe7\x9b\xb8\xe5\x85\xb3\xe6\x8a\x80\xe6\x9c\xaf"
+"\xe6\xad\xa3\xe5\x9c\xa8\xe9\xa3\x9e\xe9\x80\x9f\xe7\x9a\x84\xe5"
+"\x8f\x91\xe5\xb1\x95\xef\xbc\x8c\xe7\x94\xa8\xe6\x88\xb7\xe6\x95"
+"\xb0\xe9\x87\x8f\xe6\x80\xa5\xe5\x89\xa7\xe6\x89\xa9\xe5\xa4\xa7"
+"\xef\xbc\x8c\xe7\x9b\xb8\xe5\x85\xb3\xe7\x9a\x84\xe8\xb5\x84\xe6"
+"\xba\x90\xe9\x9d\x9e\xe5\xb8\xb8\xe5\xa4\x9a\xe3\x80\x82\x0a\xe5"
+"\xa6\x82\xe4\xbd\x95\xe5\x9c\xa8\x20\x50\x79\x74\x68\x6f\x6e\x20"
+"\xe4\xb8\xad\xe4\xbd\xbf\xe7\x94\xa8\xe6\x97\xa2\xe6\x9c\x89\xe7"
+"\x9a\x84\x20\x43\x20\x6c\x69\x62\x72\x61\x72\x79\x3f\x0a\xe3\x80"
+"\x80\xe5\x9c\xa8\xe8\xb3\x87\xe8\xa8\x8a\xe7\xa7\x91\xe6\x8a\x80"
+"\xe5\xbf\xab\xe9\x80\x9f\xe7\x99\xbc\xe5\xb1\x95\xe7\x9a\x84\xe4"
+"\xbb\x8a\xe5\xa4\xa9\x2c\x20\xe9\x96\x8b\xe7\x99\xbc\xe5\x8f\x8a"
+"\xe6\xb8\xac\xe8\xa9\xa6\xe8\xbb\x9f\xe9\xab\x94\xe7\x9a\x84\xe9"
+"\x80\x9f\xe5\xba\xa6\xe6\x98\xaf\xe4\xb8\x8d\xe5\xae\xb9\xe5\xbf"
+"\xbd\xe8\xa6\x96\xe7\x9a\x84\x0a\xe8\xaa\xb2\xe9\xa1\x8c\x2e\x20"
+"\xe7\x82\xba\xe5\x8a\xa0\xe5\xbf\xab\xe9\x96\x8b\xe7\x99\xbc\xe5"
+"\x8f\x8a\xe6\xb8\xac\xe8\xa9\xa6\xe7\x9a\x84\xe9\x80\x9f\xe5\xba"
+"\xa6\x2c\x20\xe6\x88\x91\xe5\x80\x91\xe4\xbe\xbf\xe5\xb8\xb8\xe5"
+"\xb8\x8c\xe6\x9c\x9b\xe8\x83\xbd\xe5\x88\xa9\xe7\x94\xa8\xe4\xb8"
+"\x80\xe4\xba\x9b\xe5\xb7\xb2\xe9\x96\x8b\xe7\x99\xbc\xe5\xa5\xbd"
+"\xe7\x9a\x84\x0a\x6c\x69\x62\x72\x61\x72\x79\x2c\x20\xe4\xb8\xa6"
+"\xe6\x9c\x89\xe4\xb8\x80\xe5\x80\x8b\x20\x66\x61\x73\x74\x20\x70"
+"\x72\x6f\x74\x6f\x74\x79\x70\x69\x6e\x67\x20\xe7\x9a\x84\x20\x70"
+"\x72\x6f\x67\x72\x61\x6d\x6d\x69\x6e\x67\x20\x6c\x61\x6e\x67\x75"
+"\x61\x67\x65\x20\xe5\x8f\xaf\x0a\xe4\xbe\x9b\xe4\xbd\xbf\xe7\x94"
+"\xa8\x2e\x20\xe7\x9b\xae\xe5\x89\x8d\xe6\x9c\x89\xe8\xa8\xb1\xe8"
+"\xa8\xb1\xe5\xa4\x9a\xe5\xa4\x9a\xe7\x9a\x84\x20\x6c\x69\x62\x72"
+"\x61\x72\x79\x20\xe6\x98\xaf\xe4\xbb\xa5\x20\x43\x20\xe5\xaf\xab"
+"\xe6\x88\x90\x2c\x20\xe8\x80\x8c\x20\x50\x79\x74\x68\x6f\x6e\x20"
+"\xe6\x98\xaf\xe4\xb8\x80\xe5\x80\x8b\x0a\x66\x61\x73\x74\x20\x70"
+"\x72\x6f\x74\x6f\x74\x79\x70\x69\x6e\x67\x20\xe7\x9a\x84\x20\x70"
+"\x72\x6f\x67\x72\x61\x6d\x6d\x69\x6e\x67\x20\x6c\x61\x6e\x67\x75"
+"\x61\x67\x65\x2e\x20\xe6\x95\x85\xe6\x88\x91\xe5\x80\x91\xe5\xb8"
+"\x8c\xe6\x9c\x9b\xe8\x83\xbd\xe5\xb0\x87\xe6\x97\xa2\xe6\x9c\x89"
+"\xe7\x9a\x84\x0a\x43\x20\x6c\x69\x62\x72\x61\x72\x79\x20\xe6\x8b"
+"\xbf\xe5\x88\xb0\x20\x50\x79\x74\x68\x6f\x6e\x20\xe7\x9a\x84\xe7"
+"\x92\xb0\xe5\xa2\x83\xe4\xb8\xad\xe6\xb8\xac\xe8\xa9\xa6\xe5\x8f"
+"\x8a\xe6\x95\xb4\xe5\x90\x88\x2e\x20\xe5\x85\xb6\xe4\xb8\xad\xe6"
+"\x9c\x80\xe4\xb8\xbb\xe8\xa6\x81\xe4\xb9\x9f\xe6\x98\xaf\xe6\x88"
+"\x91\xe5\x80\x91\xe6\x89\x80\x0a\xe8\xa6\x81\xe8\xa8\x8e\xe8\xab"
+"\x96\xe7\x9a\x84\xe5\x95\x8f\xe9\xa1\x8c\xe5\xb0\xb1\xe6\x98\xaf"
+"\x3a\x0a\x0a"),
+'johab': (
+"\x99\xb1\xa4\x77\x88\x62\xd0\x61\x20\xcd\x5c\xaf\xa1\xc5\xa9\x9c"
+"\x61\x0a\x0a\xdc\xc0\xdc\xc0\x90\x73\x21\x21\x20\xf1\x67\xe2\x9c"
+"\xf0\x55\xcc\x81\xa3\x89\x9f\x85\x8a\xa1\x20\xdc\xde\xdc\xd3\xd2"
+"\x7a\xd9\xaf\xd9\xaf\xd9\xaf\x20\x8b\x77\x96\xd3\x20\xdc\xd1\x95"
+"\x81\x20\xdc\xc0\x2e\x20\x2e\x0a\xed\x3c\xb5\x77\xdc\xd1\x93\x77"
+"\xd2\x73\x20\x2e\x20\x2e\x20\x2e\x20\x2e\x20\xac\xe1\xb6\x89\x9e"
+"\xa1\x20\x95\x65\xd0\x62\xf0\xe0\x20\xe0\x3b\xd2\x7a\x20\x21\x20"
+"\x21\x20\x21\x87\x41\x2e\x87\x41\x0a\xd3\x61\xd3\x61\xd3\x61\x20"
+"\x88\x41\x88\x41\x88\x41\xd9\x69\x87\x41\x5f\x87\x41\x20\xb4\xe1"
+"\x9f\x9a\x20\xc8\xa1\xc5\xc1\x8b\x7a\x20\x95\x61\xb7\x77\x20\xc3"
+"\x97\xe2\x9c\x97\x69\xf0\xe0\x20\xdc\xc0\x97\x61\x8b\x7a\x0a\xac"
+"\xe9\x9f\x7a\x20\xe0\x3b\xd2\x7a\x20\x2e\x20\x2e\x20\x2e\x20\x2e"
+"\x20\x8a\x89\xb4\x81\xae\xba\x20\xdc\xd1\x8a\xa1\x20\xdc\xde\x9f"
+"\x89\xdc\xc2\x8b\x7a\x20\xf1\x67\xf1\x62\xf5\x49\xed\xfc\xf3\xe9"
+"\x8c\x61\xbb\x9a\x0a\xb5\xc1\xb2\xa1\xd2\x7a\x20\x21\x20\x21\x20"
+"\xed\x3c\xb5\x77\xdc\xd1\x20\xe0\x3b\x93\x77\x8a\xa1\x20\xd9\x69"
+"\xea\xbe\x89\xc5\x20\xb4\xf4\x93\x77\x8a\xa1\x93\x77\x20\xed\x3c"
+"\x93\x77\x96\xc1\xd2\x7a\x20\x8b\x69\xb4\x81\x97\x7a\x0a\xdc\xde"
+"\x9d\x61\x97\x41\xe2\x9c\x20\xaf\x81\xce\xa1\xae\xa1\xd2\x7a\x20"
+"\xb4\xe1\x9f\x9a\x20\xf1\x67\xf1\x62\xf5\x49\xed\xfc\xf3\xe9\xaf"
+"\x82\xdc\xef\x97\x69\xb4\x7a\x21\x21\x20\xdc\xc0\xdc\xc0\x90\x73"
+"\xd9\xbd\x20\xd9\x62\xd9\x62\x2a\x0a\x0a",
+"\xeb\x98\xa0\xeb\xb0\xa9\xea\xb0\x81\xed\x95\x98\x20\xed\x8e\xb2"
+"\xec\x8b\x9c\xec\xbd\x9c\xeb\x9d\xbc\x0a\x0a\xe3\x89\xaf\xe3\x89"
+"\xaf\xeb\x82\xa9\x21\x21\x20\xe5\x9b\xa0\xe4\xb9\x9d\xe6\x9c\x88"
+"\xed\x8c\xa8\xeb\xaf\xa4\xeb\xa6\x94\xea\xb6\x88\x20\xe2\x93\xa1"
+"\xe2\x93\x96\xed\x9b\x80\xc2\xbf\xc2\xbf\xc2\xbf\x20\xea\xb8\x8d"
+"\xeb\x92\x99\x20\xe2\x93\x94\xeb\x8e\xa8\x20\xe3\x89\xaf\x2e\x20"
+"\x2e\x0a\xe4\xba\x9e\xec\x98\x81\xe2\x93\x94\xeb\x8a\xa5\xed\x9a"
+"\xb9\x20\x2e\x20\x2e\x20\x2e\x20\x2e\x20\xec\x84\x9c\xec\x9a\xb8"
+"\xeb\xa4\x84\x20\xeb\x8e\x90\xed\x95\x99\xe4\xb9\x99\x20\xe5\xae"
+"\xb6\xed\x9b\x80\x20\x21\x20\x21\x20\x21\xe3\x85\xa0\x2e\xe3\x85"
+"\xa0\x0a\xed\x9d\x90\xed\x9d\x90\xed\x9d\x90\x20\xe3\x84\xb1\xe3"
+"\x84\xb1\xe3\x84\xb1\xe2\x98\x86\xe3\x85\xa0\x5f\xe3\x85\xa0\x20"
+"\xec\x96\xb4\xeb\xa6\xa8\x20\xed\x83\xb8\xec\xbd\xb0\xea\xb8\x90"
+"\x20\xeb\x8e\x8c\xec\x9d\x91\x20\xec\xb9\x91\xe4\xb9\x9d\xeb\x93"
+"\xa4\xe4\xb9\x99\x20\xe3\x89\xaf\xeb\x93\x9c\xea\xb8\x90\x0a\xec"
+"\x84\xa4\xeb\xa6\x8c\x20\xe5\xae\xb6\xed\x9b\x80\x20\x2e\x20\x2e"
+"\x20\x2e\x20\x2e\x20\xea\xb5\xb4\xec\x95\xa0\xec\x89\x8c\x20\xe2"
+"\x93\x94\xea\xb6\x88\x20\xe2\x93\xa1\xeb\xa6\x98\xe3\x89\xb1\xea"
+"\xb8\x90\x20\xe5\x9b\xa0\xe4\xbb\x81\xe5\xb7\x9d\xef\xa6\x81\xe4"
+"\xb8\xad\xea\xb9\x8c\xec\xa6\xbc\x0a\xec\x99\x80\xec\x92\x80\xed"
+"\x9b\x80\x20\x21\x20\x21\x20\xe4\xba\x9e\xec\x98\x81\xe2\x93\x94"
+"\x20\xe5\xae\xb6\xeb\x8a\xa5\xea\xb6\x88\x20\xe2\x98\x86\xe4\xb8"
+"\x8a\xea\xb4\x80\x20\xec\x97\x86\xeb\x8a\xa5\xea\xb6\x88\xeb\x8a"
+"\xa5\x20\xe4\xba\x9e\xeb\x8a\xa5\xeb\x92\x88\xed\x9b\x80\x20\xea"
+"\xb8\x80\xec\x95\xa0\xeb\x93\xb4\x0a\xe2\x93\xa1\xeb\xa0\xa4\xeb"
+"\x93\x80\xe4\xb9\x9d\x20\xec\x8b\x80\xed\x92\x94\xec\x88\xb4\xed"
+"\x9b\x80\x20\xec\x96\xb4\xeb\xa6\xa8\x20\xe5\x9b\xa0\xe4\xbb\x81"
+"\xe5\xb7\x9d\xef\xa6\x81\xe4\xb8\xad\xec\x8b\x81\xe2\x91\xa8\xeb"
+"\x93\xa4\xec\x95\x9c\x21\x21\x20\xe3\x89\xaf\xe3\x89\xaf\xeb\x82"
+"\xa9\xe2\x99\xa1\x20\xe2\x8c\x92\xe2\x8c\x92\x2a\x0a\x0a"),
+'shift_jis': (
+"\x50\x79\x74\x68\x6f\x6e\x20\x82\xcc\x8a\x4a\x94\xad\x82\xcd\x81"
+"\x41\x31\x39\x39\x30\x20\x94\x4e\x82\xb2\x82\xeb\x82\xa9\x82\xe7"
+"\x8a\x4a\x8e\x6e\x82\xb3\x82\xea\x82\xc4\x82\xa2\x82\xdc\x82\xb7"
+"\x81\x42\x0a\x8a\x4a\x94\xad\x8e\xd2\x82\xcc\x20\x47\x75\x69\x64"
+"\x6f\x20\x76\x61\x6e\x20\x52\x6f\x73\x73\x75\x6d\x20\x82\xcd\x8b"
+"\xb3\x88\xe7\x97\x70\x82\xcc\x83\x76\x83\x8d\x83\x4f\x83\x89\x83"
+"\x7e\x83\x93\x83\x4f\x8c\xbe\x8c\xea\x81\x75\x41\x42\x43\x81\x76"
+"\x82\xcc\x8a\x4a\x94\xad\x82\xc9\x8e\x51\x89\xc1\x82\xb5\x82\xc4"
+"\x82\xa2\x82\xdc\x82\xb5\x82\xbd\x82\xaa\x81\x41\x41\x42\x43\x20"
+"\x82\xcd\x8e\xc0\x97\x70\x8f\xe3\x82\xcc\x96\xda\x93\x49\x82\xc9"
+"\x82\xcd\x82\xa0\x82\xdc\x82\xe8\x93\x4b\x82\xb5\x82\xc4\x82\xa2"
+"\x82\xdc\x82\xb9\x82\xf1\x82\xc5\x82\xb5\x82\xbd\x81\x42\x0a\x82"
+"\xb1\x82\xcc\x82\xbd\x82\xdf\x81\x41\x47\x75\x69\x64\x6f\x20\x82"
+"\xcd\x82\xe6\x82\xe8\x8e\xc0\x97\x70\x93\x49\x82\xc8\x83\x76\x83"
+"\x8d\x83\x4f\x83\x89\x83\x7e\x83\x93\x83\x4f\x8c\xbe\x8c\xea\x82"
+"\xcc\x8a\x4a\x94\xad\x82\xf0\x8a\x4a\x8e\x6e\x82\xb5\x81\x41\x89"
+"\x70\x8d\x91\x20\x42\x42\x53\x20\x95\xfa\x91\x97\x82\xcc\x83\x52"
+"\x83\x81\x83\x66\x83\x42\x94\xd4\x91\x67\x81\x75\x83\x82\x83\x93"
+"\x83\x65\x83\x42\x20\x83\x70\x83\x43\x83\x5c\x83\x93\x81\x76\x82"
+"\xcc\x83\x74\x83\x40\x83\x93\x82\xc5\x82\xa0\x82\xe9\x20\x47\x75"
+"\x69\x64\x6f\x20\x82\xcd\x82\xb1\x82\xcc\x8c\xbe\x8c\xea\x82\xf0"
+"\x81\x75\x50\x79\x74\x68\x6f\x6e\x81\x76\x82\xc6\x96\xbc\x82\xc3"
+"\x82\xaf\x82\xdc\x82\xb5\x82\xbd\x81\x42\x0a\x82\xb1\x82\xcc\x82"
+"\xe6\x82\xa4\x82\xc8\x94\x77\x8c\x69\x82\xa9\x82\xe7\x90\xb6\x82"
+"\xdc\x82\xea\x82\xbd\x20\x50\x79\x74\x68\x6f\x6e\x20\x82\xcc\x8c"
+"\xbe\x8c\xea\x90\xdd\x8c\x76\x82\xcd\x81\x41\x81\x75\x83\x56\x83"
+"\x93\x83\x76\x83\x8b\x81\x76\x82\xc5\x81\x75\x8f\x4b\x93\xbe\x82"
+"\xaa\x97\x65\x88\xd5\x81\x76\x82\xc6\x82\xa2\x82\xa4\x96\xda\x95"
+"\x57\x82\xc9\x8f\x64\x93\x5f\x82\xaa\x92\x75\x82\xa9\x82\xea\x82"
+"\xc4\x82\xa2\x82\xdc\x82\xb7\x81\x42\x0a\x91\xbd\x82\xad\x82\xcc"
+"\x83\x58\x83\x4e\x83\x8a\x83\x76\x83\x67\x8c\x6e\x8c\xbe\x8c\xea"
+"\x82\xc5\x82\xcd\x83\x86\x81\x5b\x83\x55\x82\xcc\x96\xda\x90\xe6"
+"\x82\xcc\x97\x98\x95\xd6\x90\xab\x82\xf0\x97\x44\x90\xe6\x82\xb5"
+"\x82\xc4\x90\x46\x81\x58\x82\xc8\x8b\x40\x94\x5c\x82\xf0\x8c\xbe"
+"\x8c\xea\x97\x76\x91\x66\x82\xc6\x82\xb5\x82\xc4\x8e\xe6\x82\xe8"
+"\x93\xfc\x82\xea\x82\xe9\x8f\xea\x8d\x87\x82\xaa\x91\xbd\x82\xa2"
+"\x82\xcc\x82\xc5\x82\xb7\x82\xaa\x81\x41\x50\x79\x74\x68\x6f\x6e"
+"\x20\x82\xc5\x82\xcd\x82\xbb\x82\xa4\x82\xa2\x82\xc1\x82\xbd\x8f"
+"\xac\x8d\xd7\x8d\x48\x82\xaa\x92\xc7\x89\xc1\x82\xb3\x82\xea\x82"
+"\xe9\x82\xb1\x82\xc6\x82\xcd\x82\xa0\x82\xdc\x82\xe8\x82\xa0\x82"
+"\xe8\x82\xdc\x82\xb9\x82\xf1\x81\x42\x0a\x8c\xbe\x8c\xea\x8e\xa9"
+"\x91\xcc\x82\xcc\x8b\x40\x94\x5c\x82\xcd\x8d\xc5\x8f\xac\x8c\xc0"
+"\x82\xc9\x89\x9f\x82\xb3\x82\xa6\x81\x41\x95\x4b\x97\x76\x82\xc8"
+"\x8b\x40\x94\x5c\x82\xcd\x8a\x67\x92\xa3\x83\x82\x83\x57\x83\x85"
+"\x81\x5b\x83\x8b\x82\xc6\x82\xb5\x82\xc4\x92\xc7\x89\xc1\x82\xb7"
+"\x82\xe9\x81\x41\x82\xc6\x82\xa2\x82\xa4\x82\xcc\x82\xaa\x20\x50"
+"\x79\x74\x68\x6f\x6e\x20\x82\xcc\x83\x7c\x83\x8a\x83\x56\x81\x5b"
+"\x82\xc5\x82\xb7\x81\x42\x0a\x0a",
+"\x50\x79\x74\x68\x6f\x6e\x20\xe3\x81\xae\xe9\x96\x8b\xe7\x99\xba"
+"\xe3\x81\xaf\xe3\x80\x81\x31\x39\x39\x30\x20\xe5\xb9\xb4\xe3\x81"
+"\x94\xe3\x82\x8d\xe3\x81\x8b\xe3\x82\x89\xe9\x96\x8b\xe5\xa7\x8b"
+"\xe3\x81\x95\xe3\x82\x8c\xe3\x81\xa6\xe3\x81\x84\xe3\x81\xbe\xe3"
+"\x81\x99\xe3\x80\x82\x0a\xe9\x96\x8b\xe7\x99\xba\xe8\x80\x85\xe3"
+"\x81\xae\x20\x47\x75\x69\x64\x6f\x20\x76\x61\x6e\x20\x52\x6f\x73"
+"\x73\x75\x6d\x20\xe3\x81\xaf\xe6\x95\x99\xe8\x82\xb2\xe7\x94\xa8"
+"\xe3\x81\xae\xe3\x83\x97\xe3\x83\xad\xe3\x82\xb0\xe3\x83\xa9\xe3"
+"\x83\x9f\xe3\x83\xb3\xe3\x82\xb0\xe8\xa8\x80\xe8\xaa\x9e\xe3\x80"
+"\x8c\x41\x42\x43\xe3\x80\x8d\xe3\x81\xae\xe9\x96\x8b\xe7\x99\xba"
+"\xe3\x81\xab\xe5\x8f\x82\xe5\x8a\xa0\xe3\x81\x97\xe3\x81\xa6\xe3"
+"\x81\x84\xe3\x81\xbe\xe3\x81\x97\xe3\x81\x9f\xe3\x81\x8c\xe3\x80"
+"\x81\x41\x42\x43\x20\xe3\x81\xaf\xe5\xae\x9f\xe7\x94\xa8\xe4\xb8"
+"\x8a\xe3\x81\xae\xe7\x9b\xae\xe7\x9a\x84\xe3\x81\xab\xe3\x81\xaf"
+"\xe3\x81\x82\xe3\x81\xbe\xe3\x82\x8a\xe9\x81\xa9\xe3\x81\x97\xe3"
+"\x81\xa6\xe3\x81\x84\xe3\x81\xbe\xe3\x81\x9b\xe3\x82\x93\xe3\x81"
+"\xa7\xe3\x81\x97\xe3\x81\x9f\xe3\x80\x82\x0a\xe3\x81\x93\xe3\x81"
+"\xae\xe3\x81\x9f\xe3\x82\x81\xe3\x80\x81\x47\x75\x69\x64\x6f\x20"
+"\xe3\x81\xaf\xe3\x82\x88\xe3\x82\x8a\xe5\xae\x9f\xe7\x94\xa8\xe7"
+"\x9a\x84\xe3\x81\xaa\xe3\x83\x97\xe3\x83\xad\xe3\x82\xb0\xe3\x83"
+"\xa9\xe3\x83\x9f\xe3\x83\xb3\xe3\x82\xb0\xe8\xa8\x80\xe8\xaa\x9e"
+"\xe3\x81\xae\xe9\x96\x8b\xe7\x99\xba\xe3\x82\x92\xe9\x96\x8b\xe5"
+"\xa7\x8b\xe3\x81\x97\xe3\x80\x81\xe8\x8b\xb1\xe5\x9b\xbd\x20\x42"
+"\x42\x53\x20\xe6\x94\xbe\xe9\x80\x81\xe3\x81\xae\xe3\x82\xb3\xe3"
+"\x83\xa1\xe3\x83\x87\xe3\x82\xa3\xe7\x95\xaa\xe7\xb5\x84\xe3\x80"
+"\x8c\xe3\x83\xa2\xe3\x83\xb3\xe3\x83\x86\xe3\x82\xa3\x20\xe3\x83"
+"\x91\xe3\x82\xa4\xe3\x82\xbd\xe3\x83\xb3\xe3\x80\x8d\xe3\x81\xae"
+"\xe3\x83\x95\xe3\x82\xa1\xe3\x83\xb3\xe3\x81\xa7\xe3\x81\x82\xe3"
+"\x82\x8b\x20\x47\x75\x69\x64\x6f\x20\xe3\x81\xaf\xe3\x81\x93\xe3"
+"\x81\xae\xe8\xa8\x80\xe8\xaa\x9e\xe3\x82\x92\xe3\x80\x8c\x50\x79"
+"\x74\x68\x6f\x6e\xe3\x80\x8d\xe3\x81\xa8\xe5\x90\x8d\xe3\x81\xa5"
+"\xe3\x81\x91\xe3\x81\xbe\xe3\x81\x97\xe3\x81\x9f\xe3\x80\x82\x0a"
+"\xe3\x81\x93\xe3\x81\xae\xe3\x82\x88\xe3\x81\x86\xe3\x81\xaa\xe8"
+"\x83\x8c\xe6\x99\xaf\xe3\x81\x8b\xe3\x82\x89\xe7\x94\x9f\xe3\x81"
+"\xbe\xe3\x82\x8c\xe3\x81\x9f\x20\x50\x79\x74\x68\x6f\x6e\x20\xe3"
+"\x81\xae\xe8\xa8\x80\xe8\xaa\x9e\xe8\xa8\xad\xe8\xa8\x88\xe3\x81"
+"\xaf\xe3\x80\x81\xe3\x80\x8c\xe3\x82\xb7\xe3\x83\xb3\xe3\x83\x97"
+"\xe3\x83\xab\xe3\x80\x8d\xe3\x81\xa7\xe3\x80\x8c\xe7\xbf\x92\xe5"
+"\xbe\x97\xe3\x81\x8c\xe5\xae\xb9\xe6\x98\x93\xe3\x80\x8d\xe3\x81"
+"\xa8\xe3\x81\x84\xe3\x81\x86\xe7\x9b\xae\xe6\xa8\x99\xe3\x81\xab"
+"\xe9\x87\x8d\xe7\x82\xb9\xe3\x81\x8c\xe7\xbd\xae\xe3\x81\x8b\xe3"
+"\x82\x8c\xe3\x81\xa6\xe3\x81\x84\xe3\x81\xbe\xe3\x81\x99\xe3\x80"
+"\x82\x0a\xe5\xa4\x9a\xe3\x81\x8f\xe3\x81\xae\xe3\x82\xb9\xe3\x82"
+"\xaf\xe3\x83\xaa\xe3\x83\x97\xe3\x83\x88\xe7\xb3\xbb\xe8\xa8\x80"
+"\xe8\xaa\x9e\xe3\x81\xa7\xe3\x81\xaf\xe3\x83\xa6\xe3\x83\xbc\xe3"
+"\x82\xb6\xe3\x81\xae\xe7\x9b\xae\xe5\x85\x88\xe3\x81\xae\xe5\x88"
+"\xa9\xe4\xbe\xbf\xe6\x80\xa7\xe3\x82\x92\xe5\x84\xaa\xe5\x85\x88"
+"\xe3\x81\x97\xe3\x81\xa6\xe8\x89\xb2\xe3\x80\x85\xe3\x81\xaa\xe6"
+"\xa9\x9f\xe8\x83\xbd\xe3\x82\x92\xe8\xa8\x80\xe8\xaa\x9e\xe8\xa6"
+"\x81\xe7\xb4\xa0\xe3\x81\xa8\xe3\x81\x97\xe3\x81\xa6\xe5\x8f\x96"
+"\xe3\x82\x8a\xe5\x85\xa5\xe3\x82\x8c\xe3\x82\x8b\xe5\xa0\xb4\xe5"
+"\x90\x88\xe3\x81\x8c\xe5\xa4\x9a\xe3\x81\x84\xe3\x81\xae\xe3\x81"
+"\xa7\xe3\x81\x99\xe3\x81\x8c\xe3\x80\x81\x50\x79\x74\x68\x6f\x6e"
+"\x20\xe3\x81\xa7\xe3\x81\xaf\xe3\x81\x9d\xe3\x81\x86\xe3\x81\x84"
+"\xe3\x81\xa3\xe3\x81\x9f\xe5\xb0\x8f\xe7\xb4\xb0\xe5\xb7\xa5\xe3"
+"\x81\x8c\xe8\xbf\xbd\xe5\x8a\xa0\xe3\x81\x95\xe3\x82\x8c\xe3\x82"
+"\x8b\xe3\x81\x93\xe3\x81\xa8\xe3\x81\xaf\xe3\x81\x82\xe3\x81\xbe"
+"\xe3\x82\x8a\xe3\x81\x82\xe3\x82\x8a\xe3\x81\xbe\xe3\x81\x9b\xe3"
+"\x82\x93\xe3\x80\x82\x0a\xe8\xa8\x80\xe8\xaa\x9e\xe8\x87\xaa\xe4"
+"\xbd\x93\xe3\x81\xae\xe6\xa9\x9f\xe8\x83\xbd\xe3\x81\xaf\xe6\x9c"
+"\x80\xe5\xb0\x8f\xe9\x99\x90\xe3\x81\xab\xe6\x8a\xbc\xe3\x81\x95"
+"\xe3\x81\x88\xe3\x80\x81\xe5\xbf\x85\xe8\xa6\x81\xe3\x81\xaa\xe6"
+"\xa9\x9f\xe8\x83\xbd\xe3\x81\xaf\xe6\x8b\xa1\xe5\xbc\xb5\xe3\x83"
+"\xa2\xe3\x82\xb8\xe3\x83\xa5\xe3\x83\xbc\xe3\x83\xab\xe3\x81\xa8"
+"\xe3\x81\x97\xe3\x81\xa6\xe8\xbf\xbd\xe5\x8a\xa0\xe3\x81\x99\xe3"
+"\x82\x8b\xe3\x80\x81\xe3\x81\xa8\xe3\x81\x84\xe3\x81\x86\xe3\x81"
+"\xae\xe3\x81\x8c\x20\x50\x79\x74\x68\x6f\x6e\x20\xe3\x81\xae\xe3"
+"\x83\x9d\xe3\x83\xaa\xe3\x82\xb7\xe3\x83\xbc\xe3\x81\xa7\xe3\x81"
+"\x99\xe3\x80\x82\x0a\x0a"),
+'shift_jisx0213': (
+"\x50\x79\x74\x68\x6f\x6e\x20\x82\xcc\x8a\x4a\x94\xad\x82\xcd\x81"
+"\x41\x31\x39\x39\x30\x20\x94\x4e\x82\xb2\x82\xeb\x82\xa9\x82\xe7"
+"\x8a\x4a\x8e\x6e\x82\xb3\x82\xea\x82\xc4\x82\xa2\x82\xdc\x82\xb7"
+"\x81\x42\x0a\x8a\x4a\x94\xad\x8e\xd2\x82\xcc\x20\x47\x75\x69\x64"
+"\x6f\x20\x76\x61\x6e\x20\x52\x6f\x73\x73\x75\x6d\x20\x82\xcd\x8b"
+"\xb3\x88\xe7\x97\x70\x82\xcc\x83\x76\x83\x8d\x83\x4f\x83\x89\x83"
+"\x7e\x83\x93\x83\x4f\x8c\xbe\x8c\xea\x81\x75\x41\x42\x43\x81\x76"
+"\x82\xcc\x8a\x4a\x94\xad\x82\xc9\x8e\x51\x89\xc1\x82\xb5\x82\xc4"
+"\x82\xa2\x82\xdc\x82\xb5\x82\xbd\x82\xaa\x81\x41\x41\x42\x43\x20"
+"\x82\xcd\x8e\xc0\x97\x70\x8f\xe3\x82\xcc\x96\xda\x93\x49\x82\xc9"
+"\x82\xcd\x82\xa0\x82\xdc\x82\xe8\x93\x4b\x82\xb5\x82\xc4\x82\xa2"
+"\x82\xdc\x82\xb9\x82\xf1\x82\xc5\x82\xb5\x82\xbd\x81\x42\x0a\x82"
+"\xb1\x82\xcc\x82\xbd\x82\xdf\x81\x41\x47\x75\x69\x64\x6f\x20\x82"
+"\xcd\x82\xe6\x82\xe8\x8e\xc0\x97\x70\x93\x49\x82\xc8\x83\x76\x83"
+"\x8d\x83\x4f\x83\x89\x83\x7e\x83\x93\x83\x4f\x8c\xbe\x8c\xea\x82"
+"\xcc\x8a\x4a\x94\xad\x82\xf0\x8a\x4a\x8e\x6e\x82\xb5\x81\x41\x89"
+"\x70\x8d\x91\x20\x42\x42\x53\x20\x95\xfa\x91\x97\x82\xcc\x83\x52"
+"\x83\x81\x83\x66\x83\x42\x94\xd4\x91\x67\x81\x75\x83\x82\x83\x93"
+"\x83\x65\x83\x42\x20\x83\x70\x83\x43\x83\x5c\x83\x93\x81\x76\x82"
+"\xcc\x83\x74\x83\x40\x83\x93\x82\xc5\x82\xa0\x82\xe9\x20\x47\x75"
+"\x69\x64\x6f\x20\x82\xcd\x82\xb1\x82\xcc\x8c\xbe\x8c\xea\x82\xf0"
+"\x81\x75\x50\x79\x74\x68\x6f\x6e\x81\x76\x82\xc6\x96\xbc\x82\xc3"
+"\x82\xaf\x82\xdc\x82\xb5\x82\xbd\x81\x42\x0a\x82\xb1\x82\xcc\x82"
+"\xe6\x82\xa4\x82\xc8\x94\x77\x8c\x69\x82\xa9\x82\xe7\x90\xb6\x82"
+"\xdc\x82\xea\x82\xbd\x20\x50\x79\x74\x68\x6f\x6e\x20\x82\xcc\x8c"
+"\xbe\x8c\xea\x90\xdd\x8c\x76\x82\xcd\x81\x41\x81\x75\x83\x56\x83"
+"\x93\x83\x76\x83\x8b\x81\x76\x82\xc5\x81\x75\x8f\x4b\x93\xbe\x82"
+"\xaa\x97\x65\x88\xd5\x81\x76\x82\xc6\x82\xa2\x82\xa4\x96\xda\x95"
+"\x57\x82\xc9\x8f\x64\x93\x5f\x82\xaa\x92\x75\x82\xa9\x82\xea\x82"
+"\xc4\x82\xa2\x82\xdc\x82\xb7\x81\x42\x0a\x91\xbd\x82\xad\x82\xcc"
+"\x83\x58\x83\x4e\x83\x8a\x83\x76\x83\x67\x8c\x6e\x8c\xbe\x8c\xea"
+"\x82\xc5\x82\xcd\x83\x86\x81\x5b\x83\x55\x82\xcc\x96\xda\x90\xe6"
+"\x82\xcc\x97\x98\x95\xd6\x90\xab\x82\xf0\x97\x44\x90\xe6\x82\xb5"
+"\x82\xc4\x90\x46\x81\x58\x82\xc8\x8b\x40\x94\x5c\x82\xf0\x8c\xbe"
+"\x8c\xea\x97\x76\x91\x66\x82\xc6\x82\xb5\x82\xc4\x8e\xe6\x82\xe8"
+"\x93\xfc\x82\xea\x82\xe9\x8f\xea\x8d\x87\x82\xaa\x91\xbd\x82\xa2"
+"\x82\xcc\x82\xc5\x82\xb7\x82\xaa\x81\x41\x50\x79\x74\x68\x6f\x6e"
+"\x20\x82\xc5\x82\xcd\x82\xbb\x82\xa4\x82\xa2\x82\xc1\x82\xbd\x8f"
+"\xac\x8d\xd7\x8d\x48\x82\xaa\x92\xc7\x89\xc1\x82\xb3\x82\xea\x82"
+"\xe9\x82\xb1\x82\xc6\x82\xcd\x82\xa0\x82\xdc\x82\xe8\x82\xa0\x82"
+"\xe8\x82\xdc\x82\xb9\x82\xf1\x81\x42\x0a\x8c\xbe\x8c\xea\x8e\xa9"
+"\x91\xcc\x82\xcc\x8b\x40\x94\x5c\x82\xcd\x8d\xc5\x8f\xac\x8c\xc0"
+"\x82\xc9\x89\x9f\x82\xb3\x82\xa6\x81\x41\x95\x4b\x97\x76\x82\xc8"
+"\x8b\x40\x94\x5c\x82\xcd\x8a\x67\x92\xa3\x83\x82\x83\x57\x83\x85"
+"\x81\x5b\x83\x8b\x82\xc6\x82\xb5\x82\xc4\x92\xc7\x89\xc1\x82\xb7"
+"\x82\xe9\x81\x41\x82\xc6\x82\xa2\x82\xa4\x82\xcc\x82\xaa\x20\x50"
+"\x79\x74\x68\x6f\x6e\x20\x82\xcc\x83\x7c\x83\x8a\x83\x56\x81\x5b"
+"\x82\xc5\x82\xb7\x81\x42\x0a\x0a\x83\x6d\x82\xf5\x20\x83\x9e\x20"
+"\x83\x67\x83\x4c\x88\x4b\x88\x79\x20\x98\x83\xfc\xd6\x20\xfc\xd2"
+"\xfc\xe6\xfb\xd4\x0a",
+"\x50\x79\x74\x68\x6f\x6e\x20\xe3\x81\xae\xe9\x96\x8b\xe7\x99\xba"
+"\xe3\x81\xaf\xe3\x80\x81\x31\x39\x39\x30\x20\xe5\xb9\xb4\xe3\x81"
+"\x94\xe3\x82\x8d\xe3\x81\x8b\xe3\x82\x89\xe9\x96\x8b\xe5\xa7\x8b"
+"\xe3\x81\x95\xe3\x82\x8c\xe3\x81\xa6\xe3\x81\x84\xe3\x81\xbe\xe3"
+"\x81\x99\xe3\x80\x82\x0a\xe9\x96\x8b\xe7\x99\xba\xe8\x80\x85\xe3"
+"\x81\xae\x20\x47\x75\x69\x64\x6f\x20\x76\x61\x6e\x20\x52\x6f\x73"
+"\x73\x75\x6d\x20\xe3\x81\xaf\xe6\x95\x99\xe8\x82\xb2\xe7\x94\xa8"
+"\xe3\x81\xae\xe3\x83\x97\xe3\x83\xad\xe3\x82\xb0\xe3\x83\xa9\xe3"
+"\x83\x9f\xe3\x83\xb3\xe3\x82\xb0\xe8\xa8\x80\xe8\xaa\x9e\xe3\x80"
+"\x8c\x41\x42\x43\xe3\x80\x8d\xe3\x81\xae\xe9\x96\x8b\xe7\x99\xba"
+"\xe3\x81\xab\xe5\x8f\x82\xe5\x8a\xa0\xe3\x81\x97\xe3\x81\xa6\xe3"
+"\x81\x84\xe3\x81\xbe\xe3\x81\x97\xe3\x81\x9f\xe3\x81\x8c\xe3\x80"
+"\x81\x41\x42\x43\x20\xe3\x81\xaf\xe5\xae\x9f\xe7\x94\xa8\xe4\xb8"
+"\x8a\xe3\x81\xae\xe7\x9b\xae\xe7\x9a\x84\xe3\x81\xab\xe3\x81\xaf"
+"\xe3\x81\x82\xe3\x81\xbe\xe3\x82\x8a\xe9\x81\xa9\xe3\x81\x97\xe3"
+"\x81\xa6\xe3\x81\x84\xe3\x81\xbe\xe3\x81\x9b\xe3\x82\x93\xe3\x81"
+"\xa7\xe3\x81\x97\xe3\x81\x9f\xe3\x80\x82\x0a\xe3\x81\x93\xe3\x81"
+"\xae\xe3\x81\x9f\xe3\x82\x81\xe3\x80\x81\x47\x75\x69\x64\x6f\x20"
+"\xe3\x81\xaf\xe3\x82\x88\xe3\x82\x8a\xe5\xae\x9f\xe7\x94\xa8\xe7"
+"\x9a\x84\xe3\x81\xaa\xe3\x83\x97\xe3\x83\xad\xe3\x82\xb0\xe3\x83"
+"\xa9\xe3\x83\x9f\xe3\x83\xb3\xe3\x82\xb0\xe8\xa8\x80\xe8\xaa\x9e"
+"\xe3\x81\xae\xe9\x96\x8b\xe7\x99\xba\xe3\x82\x92\xe9\x96\x8b\xe5"
+"\xa7\x8b\xe3\x81\x97\xe3\x80\x81\xe8\x8b\xb1\xe5\x9b\xbd\x20\x42"
+"\x42\x53\x20\xe6\x94\xbe\xe9\x80\x81\xe3\x81\xae\xe3\x82\xb3\xe3"
+"\x83\xa1\xe3\x83\x87\xe3\x82\xa3\xe7\x95\xaa\xe7\xb5\x84\xe3\x80"
+"\x8c\xe3\x83\xa2\xe3\x83\xb3\xe3\x83\x86\xe3\x82\xa3\x20\xe3\x83"
+"\x91\xe3\x82\xa4\xe3\x82\xbd\xe3\x83\xb3\xe3\x80\x8d\xe3\x81\xae"
+"\xe3\x83\x95\xe3\x82\xa1\xe3\x83\xb3\xe3\x81\xa7\xe3\x81\x82\xe3"
+"\x82\x8b\x20\x47\x75\x69\x64\x6f\x20\xe3\x81\xaf\xe3\x81\x93\xe3"
+"\x81\xae\xe8\xa8\x80\xe8\xaa\x9e\xe3\x82\x92\xe3\x80\x8c\x50\x79"
+"\x74\x68\x6f\x6e\xe3\x80\x8d\xe3\x81\xa8\xe5\x90\x8d\xe3\x81\xa5"
+"\xe3\x81\x91\xe3\x81\xbe\xe3\x81\x97\xe3\x81\x9f\xe3\x80\x82\x0a"
+"\xe3\x81\x93\xe3\x81\xae\xe3\x82\x88\xe3\x81\x86\xe3\x81\xaa\xe8"
+"\x83\x8c\xe6\x99\xaf\xe3\x81\x8b\xe3\x82\x89\xe7\x94\x9f\xe3\x81"
+"\xbe\xe3\x82\x8c\xe3\x81\x9f\x20\x50\x79\x74\x68\x6f\x6e\x20\xe3"
+"\x81\xae\xe8\xa8\x80\xe8\xaa\x9e\xe8\xa8\xad\xe8\xa8\x88\xe3\x81"
+"\xaf\xe3\x80\x81\xe3\x80\x8c\xe3\x82\xb7\xe3\x83\xb3\xe3\x83\x97"
+"\xe3\x83\xab\xe3\x80\x8d\xe3\x81\xa7\xe3\x80\x8c\xe7\xbf\x92\xe5"
+"\xbe\x97\xe3\x81\x8c\xe5\xae\xb9\xe6\x98\x93\xe3\x80\x8d\xe3\x81"
+"\xa8\xe3\x81\x84\xe3\x81\x86\xe7\x9b\xae\xe6\xa8\x99\xe3\x81\xab"
+"\xe9\x87\x8d\xe7\x82\xb9\xe3\x81\x8c\xe7\xbd\xae\xe3\x81\x8b\xe3"
+"\x82\x8c\xe3\x81\xa6\xe3\x81\x84\xe3\x81\xbe\xe3\x81\x99\xe3\x80"
+"\x82\x0a\xe5\xa4\x9a\xe3\x81\x8f\xe3\x81\xae\xe3\x82\xb9\xe3\x82"
+"\xaf\xe3\x83\xaa\xe3\x83\x97\xe3\x83\x88\xe7\xb3\xbb\xe8\xa8\x80"
+"\xe8\xaa\x9e\xe3\x81\xa7\xe3\x81\xaf\xe3\x83\xa6\xe3\x83\xbc\xe3"
+"\x82\xb6\xe3\x81\xae\xe7\x9b\xae\xe5\x85\x88\xe3\x81\xae\xe5\x88"
+"\xa9\xe4\xbe\xbf\xe6\x80\xa7\xe3\x82\x92\xe5\x84\xaa\xe5\x85\x88"
+"\xe3\x81\x97\xe3\x81\xa6\xe8\x89\xb2\xe3\x80\x85\xe3\x81\xaa\xe6"
+"\xa9\x9f\xe8\x83\xbd\xe3\x82\x92\xe8\xa8\x80\xe8\xaa\x9e\xe8\xa6"
+"\x81\xe7\xb4\xa0\xe3\x81\xa8\xe3\x81\x97\xe3\x81\xa6\xe5\x8f\x96"
+"\xe3\x82\x8a\xe5\x85\xa5\xe3\x82\x8c\xe3\x82\x8b\xe5\xa0\xb4\xe5"
+"\x90\x88\xe3\x81\x8c\xe5\xa4\x9a\xe3\x81\x84\xe3\x81\xae\xe3\x81"
+"\xa7\xe3\x81\x99\xe3\x81\x8c\xe3\x80\x81\x50\x79\x74\x68\x6f\x6e"
+"\x20\xe3\x81\xa7\xe3\x81\xaf\xe3\x81\x9d\xe3\x81\x86\xe3\x81\x84"
+"\xe3\x81\xa3\xe3\x81\x9f\xe5\xb0\x8f\xe7\xb4\xb0\xe5\xb7\xa5\xe3"
+"\x81\x8c\xe8\xbf\xbd\xe5\x8a\xa0\xe3\x81\x95\xe3\x82\x8c\xe3\x82"
+"\x8b\xe3\x81\x93\xe3\x81\xa8\xe3\x81\xaf\xe3\x81\x82\xe3\x81\xbe"
+"\xe3\x82\x8a\xe3\x81\x82\xe3\x82\x8a\xe3\x81\xbe\xe3\x81\x9b\xe3"
+"\x82\x93\xe3\x80\x82\x0a\xe8\xa8\x80\xe8\xaa\x9e\xe8\x87\xaa\xe4"
+"\xbd\x93\xe3\x81\xae\xe6\xa9\x9f\xe8\x83\xbd\xe3\x81\xaf\xe6\x9c"
+"\x80\xe5\xb0\x8f\xe9\x99\x90\xe3\x81\xab\xe6\x8a\xbc\xe3\x81\x95"
+"\xe3\x81\x88\xe3\x80\x81\xe5\xbf\x85\xe8\xa6\x81\xe3\x81\xaa\xe6"
+"\xa9\x9f\xe8\x83\xbd\xe3\x81\xaf\xe6\x8b\xa1\xe5\xbc\xb5\xe3\x83"
+"\xa2\xe3\x82\xb8\xe3\x83\xa5\xe3\x83\xbc\xe3\x83\xab\xe3\x81\xa8"
+"\xe3\x81\x97\xe3\x81\xa6\xe8\xbf\xbd\xe5\x8a\xa0\xe3\x81\x99\xe3"
+"\x82\x8b\xe3\x80\x81\xe3\x81\xa8\xe3\x81\x84\xe3\x81\x86\xe3\x81"
+"\xae\xe3\x81\x8c\x20\x50\x79\x74\x68\x6f\x6e\x20\xe3\x81\xae\xe3"
+"\x83\x9d\xe3\x83\xaa\xe3\x82\xb7\xe3\x83\xbc\xe3\x81\xa7\xe3\x81"
+"\x99\xe3\x80\x82\x0a\x0a\xe3\x83\x8e\xe3\x81\x8b\xe3\x82\x9a\x20"
+"\xe3\x83\x88\xe3\x82\x9a\x20\xe3\x83\x88\xe3\x82\xad\xef\xa8\xb6"
+"\xef\xa8\xb9\x20\xf0\xa1\x9a\xb4\xf0\xaa\x8e\x8c\x20\xe9\xba\x80"
+"\xe9\xbd\x81\xf0\xa9\x9b\xb0\x0a"),
+}

Added: vendor/Python/current/Lib/test/crashers/README
===================================================================
--- vendor/Python/current/Lib/test/crashers/README	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/crashers/README	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,20 @@
+This directory only contains tests for outstanding bugs that cause
+the interpreter to segfault.  Ideally this directory should always
+be empty.  Sometimes it may not be easy to fix the underlying cause.
+
+Each test should fail when run from the command line:
+
+	./python Lib/test/crashers/weakref_in_del.py
+
+Each test should have a link to the bug report:
+
+	# http://python.org/sf/BUG#
+
+Put as much info into a docstring or comments to help determine
+the cause of the failure.  Particularly note if the cause is
+system or environment dependent and what the variables are.
+
+Once the crash is fixed, the test case should be moved into an appropriate
+test (even if it was originally from the test suite).  This ensures the
+regression doesn't happen again.  And if it does, it should be easier
+to track down.

Added: vendor/Python/current/Lib/test/crashers/bogus_code_obj.py
===================================================================
--- vendor/Python/current/Lib/test/crashers/bogus_code_obj.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/crashers/bogus_code_obj.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,19 @@
+"""
+Broken bytecode objects can easily crash the interpreter.
+
+This is not going to be fixed.  It is generally agreed that there is no
+point in writing a bytecode verifier and putting it in CPython just for
+this.  Moreover, a verifier is bound to accept only a subset of all safe
+bytecodes, so it could lead to unnecessary breakage.
+
+For security purposes, "restricted" interpreters are not going to let
+the user build or load random bytecodes anyway.  Otherwise, this is a
+"won't fix" case.
+
+"""
+
+import types
+
+co = types.CodeType(0, 0, 0, 0, '\x04\x71\x00\x00', (),
+                    (), (), '', '', 1, '')
+exec co

Added: vendor/Python/current/Lib/test/crashers/borrowed_ref_1.py
===================================================================
--- vendor/Python/current/Lib/test/crashers/borrowed_ref_1.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/crashers/borrowed_ref_1.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,29 @@
+"""
+_PyType_Lookup() returns a borrowed reference.
+This attacks the call in dictobject.c.
+"""
+
+class A(object):
+    pass
+
+class B(object):
+    def __del__(self):
+        print 'hi'
+        del D.__missing__
+
+class D(dict):
+    class __missing__:
+        def __init__(self, *args):
+            pass
+
+
+d = D()
+a = A()
+a.cycle = a
+a.other = B()
+del a
+
+prev = None
+while 1:
+    d[5]
+    prev = (prev,)

Added: vendor/Python/current/Lib/test/crashers/borrowed_ref_2.py
===================================================================
--- vendor/Python/current/Lib/test/crashers/borrowed_ref_2.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/crashers/borrowed_ref_2.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,38 @@
+"""
+_PyType_Lookup() returns a borrowed reference.
+This attacks PyObject_GenericSetAttr().
+
+NB. on my machine this crashes in 2.5 debug but not release.
+"""
+
+class A(object):
+    pass
+
+class B(object):
+    def __del__(self):
+        print "hi"
+        del C.d
+
+class D(object):
+    def __set__(self, obj, value):
+        self.hello = 42
+
+class C(object):
+    d = D()
+
+    def g():
+        pass
+
+
+c = C()
+a = A()
+a.cycle = a
+a.other = B()
+
+lst = [None] * 1000000
+i = 0
+del a
+while 1:
+    c.d = 42         # segfaults in PyMethod_New(im_func=D.__set__, im_self=d)
+    lst[i] = c.g     # consume the free list of instancemethod objects
+    i += 1

Added: vendor/Python/current/Lib/test/crashers/dangerous_subclassing.py
===================================================================
--- vendor/Python/current/Lib/test/crashers/dangerous_subclassing.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/crashers/dangerous_subclassing.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,12 @@
+
+# http://python.org/sf/1174712
+
+import types
+
+class X(types.ModuleType, str):
+    """Such a subclassing is incorrectly allowed --
+    see the SF bug report for explanations"""
+
+if __name__ == '__main__':
+    X('name')    # segfault: ModuleType.__init__() reads
+                 # the dict at the wrong offset

Added: vendor/Python/current/Lib/test/crashers/gc_inspection.py
===================================================================
--- vendor/Python/current/Lib/test/crashers/gc_inspection.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/crashers/gc_inspection.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,32 @@
+"""
+gc.get_referrers() can be used to see objects before they are fully built.
+
+Note that this is only an example.  There are many ways to crash Python
+by using gc.get_referrers(), as well as many extension modules (even
+when they are using perfectly documented patterns to build objects).
+
+Identifying and removing all places that expose to the GC a
+partially-built object is a long-term project.  A patch was proposed on
+SF specifically for this example but I consider fixing just this single
+example a bit pointless (#1517042).
+
+A fix would include a whole-scale code review, possibly with an API
+change to decouple object creation and GC registration, and according
+fixes to the documentation for extension module writers.  It's unlikely
+to happen, though.  So this is currently classified as
+"gc.get_referrers() is dangerous, use only for debugging".
+"""
+
+import gc
+
+
+def g():
+    marker = object()
+    yield marker
+    # now the marker is in the tuple being constructed
+    [tup] = [x for x in gc.get_referrers(marker) if type(x) is tuple]
+    print tup
+    print tup[1]
+
+
+tuple(g())

Added: vendor/Python/current/Lib/test/crashers/infinite_rec_1.py
===================================================================
--- vendor/Python/current/Lib/test/crashers/infinite_rec_1.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/crashers/infinite_rec_1.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,11 @@
+
+# http://python.org/sf/1202533
+
+import new, operator
+
+class A:
+    pass
+A.__mul__ = new.instancemethod(operator.mul, None, A)
+
+if __name__ == '__main__':
+    A()*2   # segfault: infinite recursion in C

Added: vendor/Python/current/Lib/test/crashers/infinite_rec_2.py
===================================================================
--- vendor/Python/current/Lib/test/crashers/infinite_rec_2.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/crashers/infinite_rec_2.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,10 @@
+
+# http://python.org/sf/1202533
+
+class A(str):
+    __get__ = getattr
+
+if __name__ == '__main__':
+    a = A('a')
+    A.a = a
+    a.a   # segfault: infinite recursion in C

Added: vendor/Python/current/Lib/test/crashers/infinite_rec_4.py
===================================================================
--- vendor/Python/current/Lib/test/crashers/infinite_rec_4.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/crashers/infinite_rec_4.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,7 @@
+
+# http://python.org/sf/1202533
+
+if __name__ == '__main__':
+    lst = [apply]
+    lst.append(lst)
+    apply(*lst)      # segfault: infinite recursion in C

Added: vendor/Python/current/Lib/test/crashers/infinite_rec_5.py
===================================================================
--- vendor/Python/current/Lib/test/crashers/infinite_rec_5.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/crashers/infinite_rec_5.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,10 @@
+
+# http://python.org/sf/1267884
+
+import types
+
+class C:
+    __str__ = types.InstanceType.__str__
+
+if __name__ == '__main__':
+    str(C())   # segfault: infinite recursion in C

Added: vendor/Python/current/Lib/test/crashers/loosing_dict_ref.py
===================================================================
--- vendor/Python/current/Lib/test/crashers/loosing_dict_ref.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/crashers/loosing_dict_ref.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,21 @@
+
+# http://python.org/sf/1303614
+
+class Strange(object):
+    def __hash__(self):
+        return hash('hello')
+
+    def __eq__(self, other):
+        x.__dict__ = {}   # the old x.__dict__ is deallocated
+        return False
+
+
+class X(object):
+    pass
+
+if __name__ == '__main__':
+    v = 123
+    x = X()
+    x.__dict__ = {Strange(): 42,
+                  'hello': v+456}
+    x.hello  # segfault: the above dict is accessed after it's deallocated

Added: vendor/Python/current/Lib/test/crashers/modify_dict_attr.py
===================================================================
--- vendor/Python/current/Lib/test/crashers/modify_dict_attr.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/crashers/modify_dict_attr.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,19 @@
+
+# http://python.org/sf/1303614
+
+class Y(object):
+    pass
+
+class type_with_modifiable_dict(Y, type):
+    pass
+
+class MyClass(object):
+    """This class has its __dict__ attribute completely exposed:
+    user code can read, reassign and even delete it.
+    """
+    __metaclass__ = type_with_modifiable_dict
+
+
+if __name__ == '__main__':
+    del MyClass.__dict__  # if we set tp_dict to NULL,
+    print MyClass         # doing anything with MyClass segfaults

Added: vendor/Python/current/Lib/test/crashers/nasty_eq_vs_dict.py
===================================================================
--- vendor/Python/current/Lib/test/crashers/nasty_eq_vs_dict.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/crashers/nasty_eq_vs_dict.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,47 @@
+# from http://mail.python.org/pipermail/python-dev/2001-June/015239.html
+
+# if you keep changing a dictionary while looking up a key, you can
+# provoke an infinite recursion in C
+
+# At the time neither Tim nor Michael could be bothered to think of a
+# way to fix it.
+
+class Yuck:
+    def __init__(self):
+        self.i = 0
+
+    def make_dangerous(self):
+        self.i = 1
+
+    def __hash__(self):
+        # direct to slot 4 in table of size 8; slot 12 when size 16
+        return 4 + 8
+
+    def __eq__(self, other):
+        if self.i == 0:
+            # leave dict alone
+            pass
+        elif self.i == 1:
+            # fiddle to 16 slots
+            self.__fill_dict(6)
+            self.i = 2
+        else:
+            # fiddle to 8 slots
+            self.__fill_dict(4)
+            self.i = 1
+
+        return 1
+
+    def __fill_dict(self, n):
+        self.i = 0
+        dict.clear()
+        for i in range(n):
+            dict[i] = i
+        dict[self] = "OK!"
+
+y = Yuck()
+dict = {y: "OK!"}
+
+z = Yuck()
+y.make_dangerous()
+print dict[z]

Added: vendor/Python/current/Lib/test/crashers/recursion_limit_too_high.py
===================================================================
--- vendor/Python/current/Lib/test/crashers/recursion_limit_too_high.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/crashers/recursion_limit_too_high.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,16 @@
+# The following example may crash or not depending on the platform.
+# E.g. on 32-bit Intel Linux in a "standard" configuration it seems to
+# crash on Python 2.5 (but not 2.4 nor 2.3).  On Windows the import
+# eventually fails to find the module, possibly because we run out of
+# file handles.
+
+# The point of this example is to show that sys.setrecursionlimit() is a
+# hack, and not a robust solution.  This example simply exercices a path
+# where it takes many C-level recursions, consuming a lot of stack
+# space, for each Python-level recursion.  So 1000 times this amount of
+# stack space may be too much for standard platforms already.
+
+import sys
+if 'recursion_limit_too_high' in sys.modules:
+    del sys.modules['recursion_limit_too_high']
+import recursion_limit_too_high

Added: vendor/Python/current/Lib/test/crashers/recursive_call.py
===================================================================
--- vendor/Python/current/Lib/test/crashers/recursive_call.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/crashers/recursive_call.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,15 @@
+#!/usr/bin/env python
+
+# No bug report AFAIK, mail on python-dev on 2006-01-10
+
+# This is a "won't fix" case.  It is known that setting a high enough
+# recursion limit crashes by overflowing the stack.  Unless this is
+# redesigned somehow, it won't go away.
+
+import sys
+
+sys.setrecursionlimit(1 << 30)
+f = lambda f:f(f)
+
+if __name__ == '__main__':
+    f(f)

Added: vendor/Python/current/Lib/test/crashers/weakref_in_del.py
===================================================================
--- vendor/Python/current/Lib/test/crashers/weakref_in_del.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/crashers/weakref_in_del.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,17 @@
+import weakref
+
+# http://python.org/sf/1377858
+# Fixed for new-style classes in 2.5c1.
+
+ref = None
+
+def test_weakref_in_del():
+    class Target():
+        def __del__(self):
+            global ref
+            ref = weakref.ref(self)
+
+    w = Target()
+
+if __name__ == '__main__':
+    test_weakref_in_del()

Added: vendor/Python/current/Lib/test/decimaltestdata/abs.decTest
===================================================================
--- vendor/Python/current/Lib/test/decimaltestdata/abs.decTest	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/decimaltestdata/abs.decTest	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,161 @@
+------------------------------------------------------------------------
+-- abs.decTest -- decimal absolute value                              --
+-- Copyright (c) IBM Corporation, 1981, 2004.  All rights reserved.   --
+------------------------------------------------------------------------
+-- Please see the document "General Decimal Arithmetic Testcases"     --
+-- at http://www2.hursley.ibm.com/decimal for the description of      --
+-- these testcases.                                                   --
+--                                                                    --
+-- These testcases are experimental ('beta' versions), and they       --
+-- may contain errors.  They are offered on an as-is basis.  In       --
+-- particular, achieving the same results as the tests here is not    --
+-- a guarantee that an implementation complies with any Standard      --
+-- or specification.  The tests are not exhaustive.                   --
+--                                                                    --
+-- Please send comments, suggestions, and corrections to the author:  --
+--   Mike Cowlishaw, IBM Fellow                                       --
+--   IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK         --
+--   mfc at uk.ibm.com                                                   --
+------------------------------------------------------------------------
+version: 2.39
+
+-- This set of tests primarily tests the existence of the operator.
+-- Additon, subtraction, rounding, and more overflows are tested
+-- elsewhere.
+
+precision:   9
+rounding:    half_up
+maxExponent: 384
+minexponent: -383
+extended: 1
+
+absx001 abs '1'      -> '1'
+absx002 abs '-1'     -> '1'
+absx003 abs '1.00'   -> '1.00'
+absx004 abs '-1.00'  -> '1.00'
+absx005 abs '0'      -> '0'
+absx006 abs '0.00'   -> '0.00'
+absx007 abs '00.0'   -> '0.0'
+absx008 abs '00.00'  -> '0.00'
+absx009 abs '00'     -> '0'
+
+absx010 abs '-2'     -> '2'
+absx011 abs '2'      -> '2'
+absx012 abs '-2.00'  -> '2.00'
+absx013 abs '2.00'   -> '2.00'
+absx014 abs '-0'     -> '0'
+absx015 abs '-0.00'  -> '0.00'
+absx016 abs '-00.0'  -> '0.0'
+absx017 abs '-00.00' -> '0.00'
+absx018 abs '-00'    -> '0'
+
+absx020 abs '-2000000' -> '2000000'
+absx021 abs '2000000'  -> '2000000'
+precision: 7
+absx022 abs '-2000000' -> '2000000'
+absx023 abs '2000000'  -> '2000000'
+precision: 6
+absx024 abs '-2000000' -> '2.00000E+6' Rounded
+absx025 abs '2000000'  -> '2.00000E+6' Rounded
+precision: 3
+absx026 abs '-2000000' -> '2.00E+6' Rounded
+absx027 abs '2000000'  -> '2.00E+6' Rounded
+
+absx030 abs '+0.1'            -> '0.1'
+absx031 abs '-0.1'            -> '0.1'
+absx032 abs '+0.01'           -> '0.01'
+absx033 abs '-0.01'           -> '0.01'
+absx034 abs '+0.001'          -> '0.001'
+absx035 abs '-0.001'          -> '0.001'
+absx036 abs '+0.000001'       -> '0.000001'
+absx037 abs '-0.000001'       -> '0.000001'
+absx038 abs '+0.000000000001' -> '1E-12'
+absx039 abs '-0.000000000001' -> '1E-12'
+
+-- examples from decArith
+precision: 9
+absx040 abs '2.1'     ->  '2.1'
+absx041 abs '-100'    ->  '100'
+absx042 abs '101.5'   ->  '101.5'
+absx043 abs '-101.5'  ->  '101.5'
+
+-- more fixed, potential LHS swaps/overlays if done by subtract 0
+precision: 9
+absx060 abs '-56267E-10'  -> '0.0000056267'
+absx061 abs '-56267E-5'   -> '0.56267'
+absx062 abs '-56267E-2'   -> '562.67'
+absx063 abs '-56267E-1'   -> '5626.7'
+absx065 abs '-56267E-0'   -> '56267'
+
+-- overflow tests
+maxexponent: 999999999
+minexponent: -999999999
+precision: 3
+absx120 abs 9.999E+999999999 -> Infinity Inexact Overflow Rounded
+
+-- subnormals and underflow
+precision: 3
+maxexponent: 999
+minexponent: -999
+absx210 abs  1.00E-999        ->   1.00E-999
+absx211 abs  0.1E-999         ->   1E-1000   Subnormal
+absx212 abs  0.10E-999        ->   1.0E-1000 Subnormal
+absx213 abs  0.100E-999       ->   1.0E-1000 Subnormal Rounded
+absx214 abs  0.01E-999        ->   1E-1001   Subnormal
+-- next is rounded to Emin
+absx215 abs  0.999E-999       ->   1.00E-999 Inexact Rounded Subnormal Underflow
+absx216 abs  0.099E-999       ->   1.0E-1000 Inexact Rounded Subnormal Underflow
+absx217 abs  0.009E-999       ->   1E-1001   Inexact Rounded Subnormal Underflow
+absx218 abs  0.001E-999       ->   0E-1001   Inexact Rounded Subnormal Underflow
+absx219 abs  0.0009E-999      ->   0E-1001   Inexact Rounded Subnormal Underflow
+absx220 abs  0.0001E-999      ->   0E-1001   Inexact Rounded Subnormal Underflow
+
+absx230 abs -1.00E-999        ->   1.00E-999
+absx231 abs -0.1E-999         ->   1E-1000   Subnormal
+absx232 abs -0.10E-999        ->   1.0E-1000 Subnormal
+absx233 abs -0.100E-999       ->   1.0E-1000 Subnormal Rounded
+absx234 abs -0.01E-999        ->   1E-1001   Subnormal
+-- next is rounded to Emin
+absx235 abs -0.999E-999       ->   1.00E-999 Inexact Rounded Subnormal Underflow
+absx236 abs -0.099E-999       ->   1.0E-1000 Inexact Rounded Subnormal Underflow
+absx237 abs -0.009E-999       ->   1E-1001   Inexact Rounded Subnormal Underflow
+absx238 abs -0.001E-999       ->   0E-1001   Inexact Rounded Subnormal Underflow
+absx239 abs -0.0009E-999      ->   0E-1001   Inexact Rounded Subnormal Underflow
+absx240 abs -0.0001E-999      ->   0E-1001   Inexact Rounded Subnormal Underflow
+
+-- long operand tests
+maxexponent: 999
+minexponent: -999
+precision: 9
+absx301 abs 12345678000  -> 1.23456780E+10 Rounded
+absx302 abs 1234567800   -> 1.23456780E+9 Rounded
+absx303 abs 1234567890   -> 1.23456789E+9 Rounded
+absx304 abs 1234567891   -> 1.23456789E+9 Inexact Rounded
+absx305 abs 12345678901  -> 1.23456789E+10 Inexact Rounded
+absx306 abs 1234567896   -> 1.23456790E+9 Inexact Rounded
+
+precision: 15
+absx321 abs 12345678000  -> 12345678000
+absx322 abs 1234567800   -> 1234567800
+absx323 abs 1234567890   -> 1234567890
+absx324 abs 1234567891   -> 1234567891
+absx325 abs 12345678901  -> 12345678901
+absx326 abs 1234567896   -> 1234567896
+
+
+-- Specials
+precision:   9
+
+-- specials
+absx520 abs 'Inf'    -> 'Infinity'
+absx521 abs '-Inf'   -> 'Infinity'
+absx522 abs   NaN    ->  NaN
+absx523 abs  sNaN    ->  NaN   Invalid_operation
+absx524 abs   NaN22  ->  NaN22
+absx525 abs  sNaN33  ->  NaN33 Invalid_operation
+absx526 abs  -NaN22  -> -NaN22
+absx527 abs -sNaN33  -> -NaN33 Invalid_operation
+
+-- Null tests
+absx900 abs  # -> NaN Invalid_operation
+

Added: vendor/Python/current/Lib/test/decimaltestdata/add.decTest
===================================================================
--- vendor/Python/current/Lib/test/decimaltestdata/add.decTest	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/decimaltestdata/add.decTest	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1127 @@
+------------------------------------------------------------------------
+-- add.decTest -- decimal addition                                    --
+-- Copyright (c) IBM Corporation, 1981, 2004.  All rights reserved.   --
+------------------------------------------------------------------------
+-- Please see the document "General Decimal Arithmetic Testcases"     --
+-- at http://www2.hursley.ibm.com/decimal for the description of      --
+-- these testcases.                                                   --
+--                                                                    --
+-- These testcases are experimental ('beta' versions), and they       --
+-- may contain errors.  They are offered on an as-is basis.  In       --
+-- particular, achieving the same results as the tests here is not    --
+-- a guarantee that an implementation complies with any Standard      --
+-- or specification.  The tests are not exhaustive.                   --
+--                                                                    --
+-- Please send comments, suggestions, and corrections to the author:  --
+--   Mike Cowlishaw, IBM Fellow                                       --
+--   IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK         --
+--   mfc at uk.ibm.com                                                   --
+------------------------------------------------------------------------
+version: 2.39
+
+precision:   9
+rounding:    half_up
+maxExponent: 384
+minexponent: -383
+extended:    1
+
+-- [first group are 'quick confidence check']
+addx001 add 1       1       ->  2
+addx002 add 2       3       ->  5
+addx003 add '5.75'  '3.3'   ->  9.05
+addx004 add '5'     '-3'    ->  2
+addx005 add '-5'    '-3'    ->  -8
+addx006 add '-7'    '2.5'   ->  -4.5
+addx007 add '0.7'   '0.3'   ->  1.0
+addx008 add '1.25'  '1.25'  ->  2.50
+addx009 add '1.23456789'  '1.00000000' -> '2.23456789'
+addx010 add '1.23456789'  '1.00000011' -> '2.23456800'
+
+addx011 add '0.4444444444'  '0.5555555555' -> '1.00000000' Inexact Rounded
+addx012 add '0.4444444440'  '0.5555555555' -> '1.00000000' Inexact Rounded
+addx013 add '0.4444444444'  '0.5555555550' -> '0.999999999' Inexact Rounded
+addx014 add '0.44444444449'    '0' -> '0.444444444' Inexact Rounded
+addx015 add '0.444444444499'   '0' -> '0.444444444' Inexact Rounded
+addx016 add '0.4444444444999'  '0' -> '0.444444444' Inexact Rounded
+addx017 add '0.4444444445000'  '0' -> '0.444444445' Inexact Rounded
+addx018 add '0.4444444445001'  '0' -> '0.444444445' Inexact Rounded
+addx019 add '0.444444444501'   '0' -> '0.444444445' Inexact Rounded
+addx020 add '0.44444444451'    '0' -> '0.444444445' Inexact Rounded
+
+addx021 add 0 1 -> 1
+addx022 add 1 1 -> 2
+addx023 add 2 1 -> 3
+addx024 add 3 1 -> 4
+addx025 add 4 1 -> 5
+addx026 add 5 1 -> 6
+addx027 add 6 1 -> 7
+addx028 add 7 1 -> 8
+addx029 add 8 1 -> 9
+addx030 add 9 1 -> 10
+
+-- some carrying effects
+addx031 add '0.9998'  '0.0000' -> '0.9998'
+addx032 add '0.9998'  '0.0001' -> '0.9999'
+addx033 add '0.9998'  '0.0002' -> '1.0000'
+addx034 add '0.9998'  '0.0003' -> '1.0001'
+
+addx035 add '70'  '10000e+9' -> '1.00000000E+13' Inexact Rounded
+addx036 add '700'  '10000e+9' -> '1.00000000E+13' Inexact Rounded
+addx037 add '7000'  '10000e+9' -> '1.00000000E+13' Inexact Rounded
+addx038 add '70000'  '10000e+9' -> '1.00000001E+13' Inexact Rounded
+addx039 add '700000'  '10000e+9' -> '1.00000007E+13' Rounded
+
+-- symmetry:
+addx040 add '10000e+9'  '70' -> '1.00000000E+13' Inexact Rounded
+addx041 add '10000e+9'  '700' -> '1.00000000E+13' Inexact Rounded
+addx042 add '10000e+9'  '7000' -> '1.00000000E+13' Inexact Rounded
+addx044 add '10000e+9'  '70000' -> '1.00000001E+13' Inexact Rounded
+addx045 add '10000e+9'  '700000' -> '1.00000007E+13' Rounded
+
+-- same, higher precision
+precision: 15
+addx046 add '10000e+9'  '7' -> '10000000000007'
+addx047 add '10000e+9'  '70' -> '10000000000070'
+addx048 add '10000e+9'  '700' -> '10000000000700'
+addx049 add '10000e+9'  '7000' -> '10000000007000'
+addx050 add '10000e+9'  '70000' -> '10000000070000'
+addx051 add '10000e+9'  '700000' -> '10000000700000'
+
+-- examples from decarith
+addx053 add '12' '7.00' -> '19.00'
+addx054 add '1.3' '-1.07' -> '0.23'
+addx055 add '1.3' '-1.30' -> '0.00'
+addx056 add '1.3' '-2.07' -> '-0.77'
+addx057 add '1E+2' '1E+4' -> '1.01E+4'
+
+-- zero preservation
+precision: 6
+addx060 add '10000e+9'  '70000' -> '1.00000E+13' Inexact Rounded
+addx061 add 1 '0.0001' -> '1.0001'
+addx062 add 1 '0.00001' -> '1.00001'
+addx063 add 1 '0.000001' -> '1.00000' Inexact Rounded
+addx064 add 1 '0.0000001' -> '1.00000' Inexact Rounded
+addx065 add 1 '0.00000001' -> '1.00000' Inexact Rounded
+
+-- some funny zeros [in case of bad signum]
+addx070 add 1  0    -> 1
+addx071 add 1 0.    -> 1
+addx072 add 1  .0   -> 1.0
+addx073 add 1 0.0   -> 1.0
+addx074 add 1 0.00  -> 1.00
+addx075 add  0  1   -> 1
+addx076 add 0.  1   -> 1
+addx077 add  .0 1   -> 1.0
+addx078 add 0.0 1   -> 1.0
+addx079 add 0.00 1  -> 1.00
+
+precision: 9
+
+-- some carries
+addx080 add 999999998 1  -> 999999999
+addx081 add 999999999 1  -> 1.00000000E+9 Rounded
+addx082 add  99999999 1  -> 100000000
+addx083 add   9999999 1  -> 10000000
+addx084 add    999999 1  -> 1000000
+addx085 add     99999 1  -> 100000
+addx086 add      9999 1  -> 10000
+addx087 add       999 1  -> 1000
+addx088 add        99 1  -> 100
+addx089 add         9 1  -> 10
+
+
+-- more LHS swaps
+addx090 add '-56267E-10'   0 ->  '-0.0000056267'
+addx091 add '-56267E-6'    0 ->  '-0.056267'
+addx092 add '-56267E-5'    0 ->  '-0.56267'
+addx093 add '-56267E-4'    0 ->  '-5.6267'
+addx094 add '-56267E-3'    0 ->  '-56.267'
+addx095 add '-56267E-2'    0 ->  '-562.67'
+addx096 add '-56267E-1'    0 ->  '-5626.7'
+addx097 add '-56267E-0'    0 ->  '-56267'
+addx098 add '-5E-10'       0 ->  '-5E-10'
+addx099 add '-5E-7'        0 ->  '-5E-7'
+addx100 add '-5E-6'        0 ->  '-0.000005'
+addx101 add '-5E-5'        0 ->  '-0.00005'
+addx102 add '-5E-4'        0 ->  '-0.0005'
+addx103 add '-5E-1'        0 ->  '-0.5'
+addx104 add '-5E0'         0 ->  '-5'
+addx105 add '-5E1'         0 ->  '-50'
+addx106 add '-5E5'         0 ->  '-500000'
+addx107 add '-5E8'         0 ->  '-500000000'
+addx108 add '-5E9'         0 ->  '-5.00000000E+9'   Rounded
+addx109 add '-5E10'        0 ->  '-5.00000000E+10'  Rounded
+addx110 add '-5E11'        0 ->  '-5.00000000E+11'  Rounded
+addx111 add '-5E100'       0 ->  '-5.00000000E+100' Rounded
+
+-- more RHS swaps
+addx113 add 0  '-56267E-10' ->  '-0.0000056267'
+addx114 add 0  '-56267E-6'  ->  '-0.056267'
+addx116 add 0  '-56267E-5'  ->  '-0.56267'
+addx117 add 0  '-56267E-4'  ->  '-5.6267'
+addx119 add 0  '-56267E-3'  ->  '-56.267'
+addx120 add 0  '-56267E-2'  ->  '-562.67'
+addx121 add 0  '-56267E-1'  ->  '-5626.7'
+addx122 add 0  '-56267E-0'  ->  '-56267'
+addx123 add 0  '-5E-10'     ->  '-5E-10'
+addx124 add 0  '-5E-7'      ->  '-5E-7'
+addx125 add 0  '-5E-6'      ->  '-0.000005'
+addx126 add 0  '-5E-5'      ->  '-0.00005'
+addx127 add 0  '-5E-4'      ->  '-0.0005'
+addx128 add 0  '-5E-1'      ->  '-0.5'
+addx129 add 0  '-5E0'       ->  '-5'
+addx130 add 0  '-5E1'       ->  '-50'
+addx131 add 0  '-5E5'       ->  '-500000'
+addx132 add 0  '-5E8'       ->  '-500000000'
+addx133 add 0  '-5E9'       ->  '-5.00000000E+9'    Rounded
+addx134 add 0  '-5E10'      ->  '-5.00000000E+10'   Rounded
+addx135 add 0  '-5E11'      ->  '-5.00000000E+11'   Rounded
+addx136 add 0  '-5E100'     ->  '-5.00000000E+100'  Rounded
+
+-- related
+addx137 add  1  '0E-12'      ->  '1.00000000'  Rounded
+addx138 add -1  '0E-12'      ->  '-1.00000000' Rounded
+addx139 add '0E-12' 1        ->  '1.00000000'  Rounded
+addx140 add '0E-12' -1       ->  '-1.00000000' Rounded
+addx141 add 1E+4    0.0000   ->  '10000.0000'
+addx142 add 1E+4    0.00000  ->  '10000.0000'  Rounded
+addx143 add 0.000   1E+5     ->  '100000.000'
+addx144 add 0.0000  1E+5     ->  '100000.000'  Rounded
+
+-- [some of the next group are really constructor tests]
+addx146 add '00.0'  0       ->  '0.0'
+addx147 add '0.00'  0       ->  '0.00'
+addx148 add  0      '0.00'  ->  '0.00'
+addx149 add  0      '00.0'  ->  '0.0'
+addx150 add '00.0'  '0.00'  ->  '0.00'
+addx151 add '0.00'  '00.0'  ->  '0.00'
+addx152 add '3'     '.3'    ->  '3.3'
+addx153 add '3.'    '.3'    ->  '3.3'
+addx154 add '3.0'   '.3'    ->  '3.3'
+addx155 add '3.00'  '.3'    ->  '3.30'
+addx156 add '3'     '3'     ->  '6'
+addx157 add '3'     '+3'    ->  '6'
+addx158 add '3'     '-3'    ->  '0'
+addx159 add '0.3'   '-0.3'  ->  '0.0'
+addx160 add '0.03'  '-0.03' ->  '0.00'
+
+-- try borderline precision, with carries, etc.
+precision: 15
+addx161 add '1E+12' '-1'    -> '999999999999'
+addx162 add '1E+12'  '1.11' -> '1000000000001.11'
+addx163 add '1.11'  '1E+12' -> '1000000000001.11'
+addx164 add '-1'    '1E+12' -> '999999999999'
+addx165 add '7E+12' '-1'    -> '6999999999999'
+addx166 add '7E+12'  '1.11' -> '7000000000001.11'
+addx167 add '1.11'  '7E+12' -> '7000000000001.11'
+addx168 add '-1'    '7E+12' -> '6999999999999'
+
+--            123456789012345      123456789012345      1 23456789012345
+addx170 add '0.444444444444444'  '0.555555555555563' -> '1.00000000000001' Inexact Rounded
+addx171 add '0.444444444444444'  '0.555555555555562' -> '1.00000000000001' Inexact Rounded
+addx172 add '0.444444444444444'  '0.555555555555561' -> '1.00000000000001' Inexact Rounded
+addx173 add '0.444444444444444'  '0.555555555555560' -> '1.00000000000000' Inexact Rounded
+addx174 add '0.444444444444444'  '0.555555555555559' -> '1.00000000000000' Inexact Rounded
+addx175 add '0.444444444444444'  '0.555555555555558' -> '1.00000000000000' Inexact Rounded
+addx176 add '0.444444444444444'  '0.555555555555557' -> '1.00000000000000' Inexact Rounded
+addx177 add '0.444444444444444'  '0.555555555555556' -> '1.00000000000000' Rounded
+addx178 add '0.444444444444444'  '0.555555555555555' -> '0.999999999999999'
+addx179 add '0.444444444444444'  '0.555555555555554' -> '0.999999999999998'
+addx180 add '0.444444444444444'  '0.555555555555553' -> '0.999999999999997'
+addx181 add '0.444444444444444'  '0.555555555555552' -> '0.999999999999996'
+addx182 add '0.444444444444444'  '0.555555555555551' -> '0.999999999999995'
+addx183 add '0.444444444444444'  '0.555555555555550' -> '0.999999999999994'
+
+-- and some more, including residue effects and different roundings
+precision: 9
+rounding: half_up
+addx200 add '123456789' 0             -> '123456789'
+addx201 add '123456789' 0.000000001   -> '123456789' Inexact Rounded
+addx202 add '123456789' 0.000001      -> '123456789' Inexact Rounded
+addx203 add '123456789' 0.1           -> '123456789' Inexact Rounded
+addx204 add '123456789' 0.4           -> '123456789' Inexact Rounded
+addx205 add '123456789' 0.49          -> '123456789' Inexact Rounded
+addx206 add '123456789' 0.499999      -> '123456789' Inexact Rounded
+addx207 add '123456789' 0.499999999   -> '123456789' Inexact Rounded
+addx208 add '123456789' 0.5           -> '123456790' Inexact Rounded
+addx209 add '123456789' 0.500000001   -> '123456790' Inexact Rounded
+addx210 add '123456789' 0.500001      -> '123456790' Inexact Rounded
+addx211 add '123456789' 0.51          -> '123456790' Inexact Rounded
+addx212 add '123456789' 0.6           -> '123456790' Inexact Rounded
+addx213 add '123456789' 0.9           -> '123456790' Inexact Rounded
+addx214 add '123456789' 0.99999       -> '123456790' Inexact Rounded
+addx215 add '123456789' 0.999999999   -> '123456790' Inexact Rounded
+addx216 add '123456789' 1             -> '123456790'
+addx217 add '123456789' 1.000000001   -> '123456790' Inexact Rounded
+addx218 add '123456789' 1.00001       -> '123456790' Inexact Rounded
+addx219 add '123456789' 1.1           -> '123456790' Inexact Rounded
+
+rounding: half_even
+addx220 add '123456789' 0             -> '123456789'
+addx221 add '123456789' 0.000000001   -> '123456789' Inexact Rounded
+addx222 add '123456789' 0.000001      -> '123456789' Inexact Rounded
+addx223 add '123456789' 0.1           -> '123456789' Inexact Rounded
+addx224 add '123456789' 0.4           -> '123456789' Inexact Rounded
+addx225 add '123456789' 0.49          -> '123456789' Inexact Rounded
+addx226 add '123456789' 0.499999      -> '123456789' Inexact Rounded
+addx227 add '123456789' 0.499999999   -> '123456789' Inexact Rounded
+addx228 add '123456789' 0.5           -> '123456790' Inexact Rounded
+addx229 add '123456789' 0.500000001   -> '123456790' Inexact Rounded
+addx230 add '123456789' 0.500001      -> '123456790' Inexact Rounded
+addx231 add '123456789' 0.51          -> '123456790' Inexact Rounded
+addx232 add '123456789' 0.6           -> '123456790' Inexact Rounded
+addx233 add '123456789' 0.9           -> '123456790' Inexact Rounded
+addx234 add '123456789' 0.99999       -> '123456790' Inexact Rounded
+addx235 add '123456789' 0.999999999   -> '123456790' Inexact Rounded
+addx236 add '123456789' 1             -> '123456790'
+addx237 add '123456789' 1.00000001    -> '123456790' Inexact Rounded
+addx238 add '123456789' 1.00001       -> '123456790' Inexact Rounded
+addx239 add '123456789' 1.1           -> '123456790' Inexact Rounded
+-- critical few with even bottom digit...
+addx240 add '123456788' 0.499999999   -> '123456788' Inexact Rounded
+addx241 add '123456788' 0.5           -> '123456788' Inexact Rounded
+addx242 add '123456788' 0.500000001   -> '123456789' Inexact Rounded
+
+rounding: down
+addx250 add '123456789' 0             -> '123456789'
+addx251 add '123456789' 0.000000001   -> '123456789' Inexact Rounded
+addx252 add '123456789' 0.000001      -> '123456789' Inexact Rounded
+addx253 add '123456789' 0.1           -> '123456789' Inexact Rounded
+addx254 add '123456789' 0.4           -> '123456789' Inexact Rounded
+addx255 add '123456789' 0.49          -> '123456789' Inexact Rounded
+addx256 add '123456789' 0.499999      -> '123456789' Inexact Rounded
+addx257 add '123456789' 0.499999999   -> '123456789' Inexact Rounded
+addx258 add '123456789' 0.5           -> '123456789' Inexact Rounded
+addx259 add '123456789' 0.500000001   -> '123456789' Inexact Rounded
+addx260 add '123456789' 0.500001      -> '123456789' Inexact Rounded
+addx261 add '123456789' 0.51          -> '123456789' Inexact Rounded
+addx262 add '123456789' 0.6           -> '123456789' Inexact Rounded
+addx263 add '123456789' 0.9           -> '123456789' Inexact Rounded
+addx264 add '123456789' 0.99999       -> '123456789' Inexact Rounded
+addx265 add '123456789' 0.999999999   -> '123456789' Inexact Rounded
+addx266 add '123456789' 1             -> '123456790'
+addx267 add '123456789' 1.00000001    -> '123456790' Inexact Rounded
+addx268 add '123456789' 1.00001       -> '123456790' Inexact Rounded
+addx269 add '123456789' 1.1           -> '123456790' Inexact Rounded
+
+-- input preparation tests (operands should not be rounded)
+precision: 3
+rounding: half_up
+
+addx270 add '12345678900000'  9999999999999 ->  '2.23E+13' Inexact Rounded
+addx271 add  '9999999999999' 12345678900000 ->  '2.23E+13' Inexact Rounded
+
+addx272 add '12E+3'  '3444'   ->  '1.54E+4' Inexact Rounded
+addx273 add '12E+3'  '3446'   ->  '1.54E+4' Inexact Rounded
+addx274 add '12E+3'  '3449.9' ->  '1.54E+4' Inexact Rounded
+addx275 add '12E+3'  '3450.0' ->  '1.55E+4' Inexact Rounded
+addx276 add '12E+3'  '3450.1' ->  '1.55E+4' Inexact Rounded
+addx277 add '12E+3'  '3454'   ->  '1.55E+4' Inexact Rounded
+addx278 add '12E+3'  '3456'   ->  '1.55E+4' Inexact Rounded
+
+addx281 add '3444'   '12E+3'  ->  '1.54E+4' Inexact Rounded
+addx282 add '3446'   '12E+3'  ->  '1.54E+4' Inexact Rounded
+addx283 add '3449.9' '12E+3'  ->  '1.54E+4' Inexact Rounded
+addx284 add '3450.0' '12E+3'  ->  '1.55E+4' Inexact Rounded
+addx285 add '3450.1' '12E+3'  ->  '1.55E+4' Inexact Rounded
+addx286 add '3454'   '12E+3'  ->  '1.55E+4' Inexact Rounded
+addx287 add '3456'   '12E+3'  ->  '1.55E+4' Inexact Rounded
+
+rounding: half_down
+addx291 add '3444'   '12E+3'  ->  '1.54E+4' Inexact Rounded
+addx292 add '3446'   '12E+3'  ->  '1.54E+4' Inexact Rounded
+addx293 add '3449.9' '12E+3'  ->  '1.54E+4' Inexact Rounded
+addx294 add '3450.0' '12E+3'  ->  '1.54E+4' Inexact Rounded
+addx295 add '3450.1' '12E+3'  ->  '1.55E+4' Inexact Rounded
+addx296 add '3454'   '12E+3'  ->  '1.55E+4' Inexact Rounded
+addx297 add '3456'   '12E+3'  ->  '1.55E+4' Inexact Rounded
+
+-- 1 in last place tests
+rounding: half_up
+addx301 add  -1   1      ->   0
+addx302 add   0   1      ->   1
+addx303 add   1   1      ->   2
+addx304 add  12   1      ->  13
+addx305 add  98   1      ->  99
+addx306 add  99   1      -> 100
+addx307 add 100   1      -> 101
+addx308 add 101   1      -> 102
+addx309 add  -1  -1      ->  -2
+addx310 add   0  -1      ->  -1
+addx311 add   1  -1      ->   0
+addx312 add  12  -1      ->  11
+addx313 add  98  -1      ->  97
+addx314 add  99  -1      ->  98
+addx315 add 100  -1      ->  99
+addx316 add 101  -1      -> 100
+
+addx321 add -0.01  0.01    ->  0.00
+addx322 add  0.00  0.01    ->  0.01
+addx323 add  0.01  0.01    ->  0.02
+addx324 add  0.12  0.01    ->  0.13
+addx325 add  0.98  0.01    ->  0.99
+addx326 add  0.99  0.01    ->  1.00
+addx327 add  1.00  0.01    ->  1.01
+addx328 add  1.01  0.01    ->  1.02
+addx329 add -0.01 -0.01    -> -0.02
+addx330 add  0.00 -0.01    -> -0.01
+addx331 add  0.01 -0.01    ->  0.00
+addx332 add  0.12 -0.01    ->  0.11
+addx333 add  0.98 -0.01    ->  0.97
+addx334 add  0.99 -0.01    ->  0.98
+addx335 add  1.00 -0.01    ->  0.99
+addx336 add  1.01 -0.01    ->  1.00
+
+-- some more cases where adding 0 affects the coefficient
+precision: 9
+addx340 add 1E+3    0    ->         1000
+addx341 add 1E+8    0    ->    100000000
+addx342 add 1E+9    0    ->   1.00000000E+9   Rounded
+addx343 add 1E+10   0    ->   1.00000000E+10  Rounded
+-- which simply follow from these cases ...
+addx344 add 1E+3    1    ->         1001
+addx345 add 1E+8    1    ->    100000001
+addx346 add 1E+9    1    ->   1.00000000E+9   Inexact Rounded
+addx347 add 1E+10   1    ->   1.00000000E+10  Inexact Rounded
+addx348 add 1E+3    7    ->         1007
+addx349 add 1E+8    7    ->    100000007
+addx350 add 1E+9    7    ->   1.00000001E+9   Inexact Rounded
+addx351 add 1E+10   7    ->   1.00000000E+10  Inexact Rounded
+
+-- tryzeros cases
+precision:   7
+rounding:    half_up
+maxExponent: 92
+minexponent: -92
+addx361  add 0E+50 10000E+1  -> 1.0000E+5
+addx362  add 10000E+1 0E-50  -> 100000.0  Rounded
+addx363  add 10000E+1 10000E-50  -> 100000.0  Rounded Inexact
+
+-- a curiosity from JSR 13 testing
+rounding:    half_down
+precision:   10
+addx370 add 99999999 81512 -> 100081511
+precision:      6
+addx371 add 99999999 81512 -> 1.00082E+8 Rounded Inexact
+rounding:    half_up
+precision:   10
+addx372 add 99999999 81512 -> 100081511
+precision:      6
+addx373 add 99999999 81512 -> 1.00082E+8 Rounded Inexact
+rounding:    half_even
+precision:   10
+addx374 add 99999999 81512 -> 100081511
+precision:      6
+addx375 add 99999999 81512 -> 1.00082E+8 Rounded Inexact
+
+-- ulp replacement tests
+precision: 9
+maxexponent: 999999999
+minexponent: -999999999
+addx400 add   1   77e-7       ->  1.0000077
+addx401 add   1   77e-8       ->  1.00000077
+addx402 add   1   77e-9       ->  1.00000008 Inexact Rounded
+addx403 add   1   77e-10      ->  1.00000001 Inexact Rounded
+addx404 add   1   77e-11      ->  1.00000000 Inexact Rounded
+addx405 add   1   77e-12      ->  1.00000000 Inexact Rounded
+addx406 add   1   77e-999     ->  1.00000000 Inexact Rounded
+addx407 add   1   77e-9999999 ->  1.00000000 Inexact Rounded
+
+addx410 add  10   77e-7       ->  10.0000077
+addx411 add  10   77e-8       ->  10.0000008 Inexact Rounded
+addx412 add  10   77e-9       ->  10.0000001 Inexact Rounded
+addx413 add  10   77e-10      ->  10.0000000 Inexact Rounded
+addx414 add  10   77e-11      ->  10.0000000 Inexact Rounded
+addx415 add  10   77e-12      ->  10.0000000 Inexact Rounded
+addx416 add  10   77e-999     ->  10.0000000 Inexact Rounded
+addx417 add  10   77e-9999999 ->  10.0000000 Inexact Rounded
+
+addx420 add  77e-7        1   ->  1.0000077
+addx421 add  77e-8        1   ->  1.00000077
+addx422 add  77e-9        1   ->  1.00000008 Inexact Rounded
+addx423 add  77e-10       1   ->  1.00000001 Inexact Rounded
+addx424 add  77e-11       1   ->  1.00000000 Inexact Rounded
+addx425 add  77e-12       1   ->  1.00000000 Inexact Rounded
+addx426 add  77e-999      1   ->  1.00000000 Inexact Rounded
+addx427 add  77e-9999999  1   ->  1.00000000 Inexact Rounded
+
+addx430 add  77e-7       10   ->  10.0000077
+addx431 add  77e-8       10   ->  10.0000008 Inexact Rounded
+addx432 add  77e-9       10   ->  10.0000001 Inexact Rounded
+addx433 add  77e-10      10   ->  10.0000000 Inexact Rounded
+addx434 add  77e-11      10   ->  10.0000000 Inexact Rounded
+addx435 add  77e-12      10   ->  10.0000000 Inexact Rounded
+addx436 add  77e-999     10   ->  10.0000000 Inexact Rounded
+addx437 add  77e-9999999 10   ->  10.0000000 Inexact Rounded
+
+-- negative ulps
+addx440 add   1   -77e-7       ->  0.9999923
+addx441 add   1   -77e-8       ->  0.99999923
+addx442 add   1   -77e-9       ->  0.999999923
+addx443 add   1   -77e-10      ->  0.999999992 Inexact Rounded
+addx444 add   1   -77e-11      ->  0.999999999 Inexact Rounded
+addx445 add   1   -77e-12      ->  1.00000000 Inexact Rounded
+addx446 add   1   -77e-999     ->  1.00000000 Inexact Rounded
+addx447 add   1   -77e-9999999 ->  1.00000000 Inexact Rounded
+
+addx450 add  10   -77e-7       ->   9.9999923
+addx451 add  10   -77e-8       ->   9.99999923
+addx452 add  10   -77e-9       ->   9.99999992 Inexact Rounded
+addx453 add  10   -77e-10      ->   9.99999999 Inexact Rounded
+addx454 add  10   -77e-11      ->  10.0000000 Inexact Rounded
+addx455 add  10   -77e-12      ->  10.0000000 Inexact Rounded
+addx456 add  10   -77e-999     ->  10.0000000 Inexact Rounded
+addx457 add  10   -77e-9999999 ->  10.0000000 Inexact Rounded
+
+addx460 add  -77e-7        1   ->  0.9999923
+addx461 add  -77e-8        1   ->  0.99999923
+addx462 add  -77e-9        1   ->  0.999999923
+addx463 add  -77e-10       1   ->  0.999999992 Inexact Rounded
+addx464 add  -77e-11       1   ->  0.999999999 Inexact Rounded
+addx465 add  -77e-12       1   ->  1.00000000 Inexact Rounded
+addx466 add  -77e-999      1   ->  1.00000000 Inexact Rounded
+addx467 add  -77e-9999999  1   ->  1.00000000 Inexact Rounded
+
+addx470 add  -77e-7       10   ->   9.9999923
+addx471 add  -77e-8       10   ->   9.99999923
+addx472 add  -77e-9       10   ->   9.99999992 Inexact Rounded
+addx473 add  -77e-10      10   ->   9.99999999 Inexact Rounded
+addx474 add  -77e-11      10   ->  10.0000000 Inexact Rounded
+addx475 add  -77e-12      10   ->  10.0000000 Inexact Rounded
+addx476 add  -77e-999     10   ->  10.0000000 Inexact Rounded
+addx477 add  -77e-9999999 10   ->  10.0000000 Inexact Rounded
+
+-- negative ulps
+addx480 add  -1    77e-7       ->  -0.9999923
+addx481 add  -1    77e-8       ->  -0.99999923
+addx482 add  -1    77e-9       ->  -0.999999923
+addx483 add  -1    77e-10      ->  -0.999999992 Inexact Rounded
+addx484 add  -1    77e-11      ->  -0.999999999 Inexact Rounded
+addx485 add  -1    77e-12      ->  -1.00000000 Inexact Rounded
+addx486 add  -1    77e-999     ->  -1.00000000 Inexact Rounded
+addx487 add  -1    77e-9999999 ->  -1.00000000 Inexact Rounded
+
+addx490 add -10    77e-7       ->   -9.9999923
+addx491 add -10    77e-8       ->   -9.99999923
+addx492 add -10    77e-9       ->   -9.99999992 Inexact Rounded
+addx493 add -10    77e-10      ->   -9.99999999 Inexact Rounded
+addx494 add -10    77e-11      ->  -10.0000000 Inexact Rounded
+addx495 add -10    77e-12      ->  -10.0000000 Inexact Rounded
+addx496 add -10    77e-999     ->  -10.0000000 Inexact Rounded
+addx497 add -10    77e-9999999 ->  -10.0000000 Inexact Rounded
+
+addx500 add   77e-7       -1   ->  -0.9999923
+addx501 add   77e-8       -1   ->  -0.99999923
+addx502 add   77e-9       -1   ->  -0.999999923
+addx503 add   77e-10      -1   ->  -0.999999992 Inexact Rounded
+addx504 add   77e-11      -1   ->  -0.999999999 Inexact Rounded
+addx505 add   77e-12      -1   ->  -1.00000000 Inexact Rounded
+addx506 add   77e-999     -1   ->  -1.00000000 Inexact Rounded
+addx507 add   77e-9999999 -1   ->  -1.00000000 Inexact Rounded
+
+addx510 add   77e-7       -10  ->   -9.9999923
+addx511 add   77e-8       -10  ->   -9.99999923
+addx512 add   77e-9       -10  ->   -9.99999992 Inexact Rounded
+addx513 add   77e-10      -10  ->   -9.99999999 Inexact Rounded
+addx514 add   77e-11      -10  ->  -10.0000000 Inexact Rounded
+addx515 add   77e-12      -10  ->  -10.0000000 Inexact Rounded
+addx516 add   77e-999     -10  ->  -10.0000000 Inexact Rounded
+addx517 add   77e-9999999 -10  ->  -10.0000000 Inexact Rounded
+
+
+-- long operands
+maxexponent: 999
+minexponent: -999
+precision: 9
+addx521 add 12345678000 0 -> 1.23456780E+10 Rounded
+addx522 add 0 12345678000 -> 1.23456780E+10 Rounded
+addx523 add 1234567800  0 -> 1.23456780E+9 Rounded
+addx524 add 0 1234567800  -> 1.23456780E+9 Rounded
+addx525 add 1234567890  0 -> 1.23456789E+9 Rounded
+addx526 add 0 1234567890  -> 1.23456789E+9 Rounded
+addx527 add 1234567891  0 -> 1.23456789E+9 Inexact Rounded
+addx528 add 0 1234567891  -> 1.23456789E+9 Inexact Rounded
+addx529 add 12345678901 0 -> 1.23456789E+10 Inexact Rounded
+addx530 add 0 12345678901 -> 1.23456789E+10 Inexact Rounded
+addx531 add 1234567896  0 -> 1.23456790E+9 Inexact Rounded
+addx532 add 0 1234567896  -> 1.23456790E+9 Inexact Rounded
+
+precision: 15
+-- still checking
+addx541 add 12345678000 0 -> 12345678000
+addx542 add 0 12345678000 -> 12345678000
+addx543 add 1234567800  0 -> 1234567800
+addx544 add 0 1234567800  -> 1234567800
+addx545 add 1234567890  0 -> 1234567890
+addx546 add 0 1234567890  -> 1234567890
+addx547 add 1234567891  0 -> 1234567891
+addx548 add 0 1234567891  -> 1234567891
+addx549 add 12345678901 0 -> 12345678901
+addx550 add 0 12345678901 -> 12345678901
+addx551 add 1234567896  0 -> 1234567896
+addx552 add 0 1234567896  -> 1234567896
+
+-- verify a query
+precision:    16
+maxExponent: +394
+minExponent: -393
+rounding:     down
+addx561 add 1e-398 9.000000000000000E+384 -> 9.000000000000000E+384 Inexact Rounded
+addx562 add      0 9.000000000000000E+384 -> 9.000000000000000E+384 Rounded
+-- and using decimal64 bounds...
+precision:    16
+maxExponent: +384
+minExponent: -383
+rounding:     down
+addx563 add 1e-388 9.000000000000000E+374 -> 9.000000000000000E+374 Inexact Rounded
+addx564 add      0 9.000000000000000E+374 -> 9.000000000000000E+374 Rounded
+
+-- some more residue effects with extreme rounding
+precision:   9
+rounding: half_up
+addx601 add 123456789  0.000001 -> 123456789 Inexact Rounded
+rounding: half_even
+addx602 add 123456789  0.000001 -> 123456789 Inexact Rounded
+rounding: half_down
+addx603 add 123456789  0.000001 -> 123456789 Inexact Rounded
+rounding: floor
+addx604 add 123456789  0.000001 -> 123456789 Inexact Rounded
+rounding: ceiling
+addx605 add 123456789  0.000001 -> 123456790 Inexact Rounded
+rounding: up
+addx606 add 123456789  0.000001 -> 123456790 Inexact Rounded
+rounding: down
+addx607 add 123456789  0.000001 -> 123456789 Inexact Rounded
+
+rounding: half_up
+addx611 add 123456789 -0.000001 -> 123456789 Inexact Rounded
+rounding: half_even
+addx612 add 123456789 -0.000001 -> 123456789 Inexact Rounded
+rounding: half_down
+addx613 add 123456789 -0.000001 -> 123456789 Inexact Rounded
+rounding: floor
+addx614 add 123456789 -0.000001 -> 123456788 Inexact Rounded
+rounding: ceiling
+addx615 add 123456789 -0.000001 -> 123456789 Inexact Rounded
+rounding: up
+addx616 add 123456789 -0.000001 -> 123456789 Inexact Rounded
+rounding: down
+addx617 add 123456789 -0.000001 -> 123456788 Inexact Rounded
+
+rounding: half_up
+addx621 add 123456789  0.499999 -> 123456789 Inexact Rounded
+rounding: half_even
+addx622 add 123456789  0.499999 -> 123456789 Inexact Rounded
+rounding: half_down
+addx623 add 123456789  0.499999 -> 123456789 Inexact Rounded
+rounding: floor
+addx624 add 123456789  0.499999 -> 123456789 Inexact Rounded
+rounding: ceiling
+addx625 add 123456789  0.499999 -> 123456790 Inexact Rounded
+rounding: up
+addx626 add 123456789  0.499999 -> 123456790 Inexact Rounded
+rounding: down
+addx627 add 123456789  0.499999 -> 123456789 Inexact Rounded
+
+rounding: half_up
+addx631 add 123456789 -0.499999 -> 123456789 Inexact Rounded
+rounding: half_even
+addx632 add 123456789 -0.499999 -> 123456789 Inexact Rounded
+rounding: half_down
+addx633 add 123456789 -0.499999 -> 123456789 Inexact Rounded
+rounding: floor
+addx634 add 123456789 -0.499999 -> 123456788 Inexact Rounded
+rounding: ceiling
+addx635 add 123456789 -0.499999 -> 123456789 Inexact Rounded
+rounding: up
+addx636 add 123456789 -0.499999 -> 123456789 Inexact Rounded
+rounding: down
+addx637 add 123456789 -0.499999 -> 123456788 Inexact Rounded
+
+rounding: half_up
+addx641 add 123456789  0.500001 -> 123456790 Inexact Rounded
+rounding: half_even
+addx642 add 123456789  0.500001 -> 123456790 Inexact Rounded
+rounding: half_down
+addx643 add 123456789  0.500001 -> 123456790 Inexact Rounded
+rounding: floor
+addx644 add 123456789  0.500001 -> 123456789 Inexact Rounded
+rounding: ceiling
+addx645 add 123456789  0.500001 -> 123456790 Inexact Rounded
+rounding: up
+addx646 add 123456789  0.500001 -> 123456790 Inexact Rounded
+rounding: down
+addx647 add 123456789  0.500001 -> 123456789 Inexact Rounded
+
+rounding: half_up
+addx651 add 123456789 -0.500001 -> 123456788 Inexact Rounded
+rounding: half_even
+addx652 add 123456789 -0.500001 -> 123456788 Inexact Rounded
+rounding: half_down
+addx653 add 123456789 -0.500001 -> 123456788 Inexact Rounded
+rounding: floor
+addx654 add 123456789 -0.500001 -> 123456788 Inexact Rounded
+rounding: ceiling
+addx655 add 123456789 -0.500001 -> 123456789 Inexact Rounded
+rounding: up
+addx656 add 123456789 -0.500001 -> 123456789 Inexact Rounded
+rounding: down
+addx657 add 123456789 -0.500001 -> 123456788 Inexact Rounded
+
+-- long operand triangle
+rounding: half_up
+precision:  37
+addx660 add 98471198160.56524417578665886060 -23994.14313393939743548945165462 -> 98471174166.42211023638922337114834538
+precision:  36
+addx661 add 98471198160.56524417578665886060 -23994.14313393939743548945165462 -> 98471174166.4221102363892233711483454  Inexact Rounded
+precision:  35
+addx662 add 98471198160.56524417578665886060 -23994.14313393939743548945165462 -> 98471174166.422110236389223371148345   Inexact Rounded
+precision:  34
+addx663 add 98471198160.56524417578665886060 -23994.14313393939743548945165462 -> 98471174166.42211023638922337114835    Inexact Rounded
+precision:  33
+addx664 add 98471198160.56524417578665886060 -23994.14313393939743548945165462 -> 98471174166.4221102363892233711483     Inexact Rounded
+precision:  32
+addx665 add 98471198160.56524417578665886060 -23994.14313393939743548945165462 -> 98471174166.422110236389223371148      Inexact Rounded
+precision:  31
+addx666 add 98471198160.56524417578665886060 -23994.14313393939743548945165462 -> 98471174166.42211023638922337115       Inexact Rounded
+precision:  30
+addx667 add 98471198160.56524417578665886060 -23994.14313393939743548945165462 -> 98471174166.4221102363892233711        Inexact Rounded
+precision:  29
+addx668 add 98471198160.56524417578665886060 -23994.14313393939743548945165462 -> 98471174166.422110236389223371         Inexact Rounded
+precision:  28
+addx669 add 98471198160.56524417578665886060 -23994.14313393939743548945165462 -> 98471174166.42211023638922337          Inexact Rounded
+precision:  27
+addx670 add 98471198160.56524417578665886060 -23994.14313393939743548945165462 -> 98471174166.4221102363892234           Inexact Rounded
+precision:  26
+addx671 add 98471198160.56524417578665886060 -23994.14313393939743548945165462 -> 98471174166.422110236389223            Inexact Rounded
+precision:  25
+addx672 add 98471198160.56524417578665886060 -23994.14313393939743548945165462 -> 98471174166.42211023638922             Inexact Rounded
+precision:  24
+addx673 add 98471198160.56524417578665886060 -23994.14313393939743548945165462 -> 98471174166.4221102363892              Inexact Rounded
+precision:  23
+addx674 add 98471198160.56524417578665886060 -23994.14313393939743548945165462 -> 98471174166.422110236389               Inexact Rounded
+precision:  22
+addx675 add 98471198160.56524417578665886060 -23994.14313393939743548945165462 -> 98471174166.42211023639                Inexact Rounded
+precision:  21
+addx676 add 98471198160.56524417578665886060 -23994.14313393939743548945165462 -> 98471174166.4221102364                 Inexact Rounded
+precision:  20
+addx677 add 98471198160.56524417578665886060 -23994.14313393939743548945165462 -> 98471174166.422110236                  Inexact Rounded
+precision:  19
+addx678 add 98471198160.56524417578665886060 -23994.14313393939743548945165462 -> 98471174166.42211024                   Inexact Rounded
+precision:  18
+addx679 add 98471198160.56524417578665886060 -23994.14313393939743548945165462 -> 98471174166.4221102                    Inexact Rounded
+precision:  17
+addx680 add 98471198160.56524417578665886060 -23994.14313393939743548945165462 -> 98471174166.422110                     Inexact Rounded
+precision:  16
+addx681 add 98471198160.56524417578665886060 -23994.14313393939743548945165462 -> 98471174166.42211                      Inexact Rounded
+precision:  15
+addx682 add 98471198160.56524417578665886060 -23994.14313393939743548945165462 -> 98471174166.4221                       Inexact Rounded
+precision:  14
+addx683 add 98471198160.56524417578665886060 -23994.14313393939743548945165462 -> 98471174166.422                        Inexact Rounded
+precision:  13
+addx684 add 98471198160.56524417578665886060 -23994.14313393939743548945165462 -> 98471174166.42                         Inexact Rounded
+precision:  12
+addx685 add 98471198160.56524417578665886060 -23994.14313393939743548945165462 -> 98471174166.4                          Inexact Rounded
+precision:  11
+addx686 add 98471198160.56524417578665886060 -23994.14313393939743548945165462 -> 98471174166                            Inexact Rounded
+precision:  10
+addx687 add 98471198160.56524417578665886060 -23994.14313393939743548945165462 -> 9.847117417E+10                        Inexact Rounded
+precision:   9
+addx688 add 98471198160.56524417578665886060 -23994.14313393939743548945165462 -> 9.84711742E+10                         Inexact Rounded
+precision:   8
+addx689 add 98471198160.56524417578665886060 -23994.14313393939743548945165462 -> 9.8471174E+10                          Inexact Rounded
+precision:   7
+addx690 add 98471198160.56524417578665886060 -23994.14313393939743548945165462 -> 9.847117E+10                          Inexact Rounded
+precision:   6
+addx691 add 98471198160.56524417578665886060 -23994.14313393939743548945165462 -> 9.84712E+10                          Inexact Rounded
+precision:   5
+addx692 add 98471198160.56524417578665886060 -23994.14313393939743548945165462 -> 9.8471E+10                          Inexact Rounded
+precision:   4
+addx693 add 98471198160.56524417578665886060 -23994.14313393939743548945165462 -> 9.847E+10                          Inexact Rounded
+precision:   3
+addx694 add 98471198160.56524417578665886060 -23994.14313393939743548945165462 -> 9.85E+10                          Inexact Rounded
+precision:   2
+addx695 add 98471198160.56524417578665886060 -23994.14313393939743548945165462 -> 9.8E+10                          Inexact Rounded
+precision:   1
+addx696 add 98471198160.56524417578665886060 -23994.14313393939743548945165462 -> 1E+11                          Inexact Rounded
+
+-- more zeros, etc.
+rounding: half_up
+precision:   9
+
+addx701 add 5.00 1.00E-3 -> 5.00100
+addx702 add 00.00 0.000  -> 0.000
+addx703 add 00.00 0E-3   -> 0.000
+addx704 add 0E-3  00.00  -> 0.000
+
+addx710 add 0E+3  00.00  -> 0.00
+addx711 add 0E+3  00.0   -> 0.0
+addx712 add 0E+3  00.    -> 0
+addx713 add 0E+3  00.E+1 -> 0E+1
+addx714 add 0E+3  00.E+2 -> 0E+2
+addx715 add 0E+3  00.E+3 -> 0E+3
+addx716 add 0E+3  00.E+4 -> 0E+3
+addx717 add 0E+3  00.E+5 -> 0E+3
+addx718 add 0E+3  -00.0   -> 0.0
+addx719 add 0E+3  -00.    -> 0
+addx731 add 0E+3  -00.E+1 -> 0E+1
+
+addx720 add 00.00  0E+3  -> 0.00
+addx721 add 00.0   0E+3  -> 0.0
+addx722 add 00.    0E+3  -> 0
+addx723 add 00.E+1 0E+3  -> 0E+1
+addx724 add 00.E+2 0E+3  -> 0E+2
+addx725 add 00.E+3 0E+3  -> 0E+3
+addx726 add 00.E+4 0E+3  -> 0E+3
+addx727 add 00.E+5 0E+3  -> 0E+3
+addx728 add -00.00 0E+3  -> 0.00
+addx729 add -00.0  0E+3  -> 0.0
+addx730 add -00.   0E+3  -> 0
+
+addx732 add  0     0     ->  0
+addx733 add  0    -0     ->  0
+addx734 add -0     0     ->  0
+addx735 add -0    -0     -> -0     -- IEEE 854 special case
+
+addx736 add  1    -1     ->  0
+addx737 add -1    -1     -> -2
+addx738 add  1     1     ->  2
+addx739 add -1     1     ->  0
+
+addx741 add  0    -1     -> -1
+addx742 add -0    -1     -> -1
+addx743 add  0     1     ->  1
+addx744 add -0     1     ->  1
+addx745 add -1     0     -> -1
+addx746 add -1    -0     -> -1
+addx747 add  1     0     ->  1
+addx748 add  1    -0     ->  1
+
+addx751 add  0.0  -1     -> -1.0
+addx752 add -0.0  -1     -> -1.0
+addx753 add  0.0   1     ->  1.0
+addx754 add -0.0   1     ->  1.0
+addx755 add -1.0   0     -> -1.0
+addx756 add -1.0  -0     -> -1.0
+addx757 add  1.0   0     ->  1.0
+addx758 add  1.0  -0     ->  1.0
+
+addx761 add  0    -1.0   -> -1.0
+addx762 add -0    -1.0   -> -1.0
+addx763 add  0     1.0   ->  1.0
+addx764 add -0     1.0   ->  1.0
+addx765 add -1     0.0   -> -1.0
+addx766 add -1    -0.0   -> -1.0
+addx767 add  1     0.0   ->  1.0
+addx768 add  1    -0.0   ->  1.0
+
+addx771 add  0.0  -1.0   -> -1.0
+addx772 add -0.0  -1.0   -> -1.0
+addx773 add  0.0   1.0   ->  1.0
+addx774 add -0.0   1.0   ->  1.0
+addx775 add -1.0   0.0   -> -1.0
+addx776 add -1.0  -0.0   -> -1.0
+addx777 add  1.0   0.0   ->  1.0
+addx778 add  1.0  -0.0   ->  1.0
+
+-- Specials
+addx780 add -Inf  -Inf   -> -Infinity
+addx781 add -Inf  -1000  -> -Infinity
+addx782 add -Inf  -1     -> -Infinity
+addx783 add -Inf  -0     -> -Infinity
+addx784 add -Inf   0     -> -Infinity
+addx785 add -Inf   1     -> -Infinity
+addx786 add -Inf   1000  -> -Infinity
+addx787 add -1000 -Inf   -> -Infinity
+addx788 add -Inf  -Inf   -> -Infinity
+addx789 add -1    -Inf   -> -Infinity
+addx790 add -0    -Inf   -> -Infinity
+addx791 add  0    -Inf   -> -Infinity
+addx792 add  1    -Inf   -> -Infinity
+addx793 add  1000 -Inf   -> -Infinity
+addx794 add  Inf  -Inf   ->  NaN  Invalid_operation
+
+addx800 add  Inf  -Inf   ->  NaN  Invalid_operation
+addx801 add  Inf  -1000  ->  Infinity
+addx802 add  Inf  -1     ->  Infinity
+addx803 add  Inf  -0     ->  Infinity
+addx804 add  Inf   0     ->  Infinity
+addx805 add  Inf   1     ->  Infinity
+addx806 add  Inf   1000  ->  Infinity
+addx807 add  Inf   Inf   ->  Infinity
+addx808 add -1000  Inf   ->  Infinity
+addx809 add -Inf   Inf   ->  NaN  Invalid_operation
+addx810 add -1     Inf   ->  Infinity
+addx811 add -0     Inf   ->  Infinity
+addx812 add  0     Inf   ->  Infinity
+addx813 add  1     Inf   ->  Infinity
+addx814 add  1000  Inf   ->  Infinity
+addx815 add  Inf   Inf   ->  Infinity
+
+addx821 add  NaN -Inf    ->  NaN
+addx822 add  NaN -1000   ->  NaN
+addx823 add  NaN -1      ->  NaN
+addx824 add  NaN -0      ->  NaN
+addx825 add  NaN  0      ->  NaN
+addx826 add  NaN  1      ->  NaN
+addx827 add  NaN  1000   ->  NaN
+addx828 add  NaN  Inf    ->  NaN
+addx829 add  NaN  NaN    ->  NaN
+addx830 add -Inf  NaN    ->  NaN
+addx831 add -1000 NaN    ->  NaN
+addx832 add -1    NaN    ->  NaN
+addx833 add -0    NaN    ->  NaN
+addx834 add  0    NaN    ->  NaN
+addx835 add  1    NaN    ->  NaN
+addx836 add  1000 NaN    ->  NaN
+addx837 add  Inf  NaN    ->  NaN
+
+addx841 add  sNaN -Inf   ->  NaN  Invalid_operation
+addx842 add  sNaN -1000  ->  NaN  Invalid_operation
+addx843 add  sNaN -1     ->  NaN  Invalid_operation
+addx844 add  sNaN -0     ->  NaN  Invalid_operation
+addx845 add  sNaN  0     ->  NaN  Invalid_operation
+addx846 add  sNaN  1     ->  NaN  Invalid_operation
+addx847 add  sNaN  1000  ->  NaN  Invalid_operation
+addx848 add  sNaN  NaN   ->  NaN  Invalid_operation
+addx849 add  sNaN sNaN   ->  NaN  Invalid_operation
+addx850 add  NaN  sNaN   ->  NaN  Invalid_operation
+addx851 add -Inf  sNaN   ->  NaN  Invalid_operation
+addx852 add -1000 sNaN   ->  NaN  Invalid_operation
+addx853 add -1    sNaN   ->  NaN  Invalid_operation
+addx854 add -0    sNaN   ->  NaN  Invalid_operation
+addx855 add  0    sNaN   ->  NaN  Invalid_operation
+addx856 add  1    sNaN   ->  NaN  Invalid_operation
+addx857 add  1000 sNaN   ->  NaN  Invalid_operation
+addx858 add  Inf  sNaN   ->  NaN  Invalid_operation
+addx859 add  NaN  sNaN   ->  NaN  Invalid_operation
+
+-- propagating NaNs
+addx861 add  NaN1   -Inf    ->  NaN1
+addx862 add +NaN2   -1000   ->  NaN2
+addx863 add  NaN3    1000   ->  NaN3
+addx864 add  NaN4    Inf    ->  NaN4
+addx865 add  NaN5   +NaN6   ->  NaN5
+addx866 add -Inf     NaN7   ->  NaN7
+addx867 add -1000    NaN8   ->  NaN8
+addx868 add  1000    NaN9   ->  NaN9
+addx869 add  Inf    +NaN10  ->  NaN10
+addx871 add  sNaN11  -Inf   ->  NaN11  Invalid_operation
+addx872 add  sNaN12  -1000  ->  NaN12  Invalid_operation
+addx873 add  sNaN13   1000  ->  NaN13  Invalid_operation
+addx874 add  sNaN14   NaN17 ->  NaN14  Invalid_operation
+addx875 add  sNaN15  sNaN18 ->  NaN15  Invalid_operation
+addx876 add  NaN16   sNaN19 ->  NaN19  Invalid_operation
+addx877 add -Inf    +sNaN20 ->  NaN20  Invalid_operation
+addx878 add -1000    sNaN21 ->  NaN21  Invalid_operation
+addx879 add  1000    sNaN22 ->  NaN22  Invalid_operation
+addx880 add  Inf     sNaN23 ->  NaN23  Invalid_operation
+addx881 add +NaN25  +sNaN24 ->  NaN24  Invalid_operation
+addx882 add -NaN26    NaN28 -> -NaN26
+addx883 add -sNaN27  sNaN29 -> -NaN27  Invalid_operation
+addx884 add  1000    -NaN30 -> -NaN30
+addx885 add  1000   -sNaN31 -> -NaN31  Invalid_operation
+
+-- overflow, underflow and subnormal tests
+maxexponent: 999999999
+minexponent: -999999999
+precision: 9
+addx890 add 1E+999999999     9E+999999999   -> Infinity Overflow Inexact Rounded
+addx891 add 9E+999999999     1E+999999999   -> Infinity Overflow Inexact Rounded
+addx892 add -1.1E-999999999  1E-999999999   -> -1E-1000000000    Subnormal
+addx893 add 1E-999999999    -1.1e-999999999 -> -1E-1000000000    Subnormal
+addx894 add -1.0001E-999999999  1E-999999999   -> -1E-1000000003 Subnormal
+addx895 add 1E-999999999    -1.0001e-999999999 -> -1E-1000000003 Subnormal
+addx896 add -1E+999999999   -9E+999999999   -> -Infinity Overflow Inexact Rounded
+addx897 add -9E+999999999   -1E+999999999   -> -Infinity Overflow Inexact Rounded
+addx898 add +1.1E-999999999 -1E-999999999   -> 1E-1000000000    Subnormal
+addx899 add -1E-999999999   +1.1e-999999999 -> 1E-1000000000    Subnormal
+addx900 add +1.0001E-999999999 -1E-999999999   -> 1E-1000000003 Subnormal
+addx901 add -1E-999999999   +1.0001e-999999999 -> 1E-1000000003 Subnormal
+addx902 add -1E+999999999   +9E+999999999   ->  8E+999999999
+addx903 add -9E+999999999   +1E+999999999   -> -8E+999999999
+
+precision: 3
+addx904 add      0 -9.999E+999999999   -> -Infinity Inexact Overflow Rounded
+addx905 add        -9.999E+999999999 0 -> -Infinity Inexact Overflow Rounded
+addx906 add      0  9.999E+999999999   ->  Infinity Inexact Overflow Rounded
+addx907 add         9.999E+999999999 0 ->  Infinity Inexact Overflow Rounded
+
+precision: 3
+maxexponent: 999
+minexponent: -999
+addx910 add  1.00E-999   0    ->   1.00E-999
+addx911 add  0.1E-999    0    ->   1E-1000   Subnormal
+addx912 add  0.10E-999   0    ->   1.0E-1000 Subnormal
+addx913 add  0.100E-999  0    ->   1.0E-1000 Subnormal Rounded
+addx914 add  0.01E-999   0    ->   1E-1001   Subnormal
+-- next is rounded to Emin
+addx915 add  0.999E-999  0    ->   1.00E-999 Inexact Rounded Subnormal Underflow
+addx916 add  0.099E-999  0    ->   1.0E-1000 Inexact Rounded Subnormal Underflow
+addx917 add  0.009E-999  0    ->   1E-1001   Inexact Rounded Subnormal Underflow
+addx918 add  0.001E-999  0    ->   0E-1001   Inexact Rounded Subnormal Underflow
+addx919 add  0.0009E-999 0    ->   0E-1001   Inexact Rounded Subnormal Underflow
+addx920 add  0.0001E-999 0    ->   0E-1001   Inexact Rounded Subnormal Underflow
+
+addx930 add -1.00E-999   0    ->  -1.00E-999
+addx931 add -0.1E-999    0    ->  -1E-1000   Subnormal
+addx932 add -0.10E-999   0    ->  -1.0E-1000 Subnormal
+addx933 add -0.100E-999  0    ->  -1.0E-1000 Subnormal Rounded
+addx934 add -0.01E-999   0    ->  -1E-1001   Subnormal
+-- next is rounded to Emin
+addx935 add -0.999E-999  0    ->  -1.00E-999 Inexact Rounded Subnormal Underflow
+addx936 add -0.099E-999  0    ->  -1.0E-1000 Inexact Rounded Subnormal Underflow
+addx937 add -0.009E-999  0    ->  -1E-1001   Inexact Rounded Subnormal Underflow
+addx938 add -0.001E-999  0    ->  -0E-1001   Inexact Rounded Subnormal Underflow
+addx939 add -0.0009E-999 0    ->  -0E-1001   Inexact Rounded Subnormal Underflow
+addx940 add -0.0001E-999 0    ->  -0E-1001   Inexact Rounded Subnormal Underflow
+
+-- some non-zero subnormal adds
+addx950 add  1.00E-999    0.1E-999  ->   1.10E-999
+addx951 add  0.1E-999     0.1E-999  ->   2E-1000    Subnormal
+addx952 add  0.10E-999    0.1E-999  ->   2.0E-1000  Subnormal
+addx953 add  0.100E-999   0.1E-999  ->   2.0E-1000  Subnormal Rounded
+addx954 add  0.01E-999    0.1E-999  ->   1.1E-1000  Subnormal
+addx955 add  0.999E-999   0.1E-999  ->   1.10E-999  Inexact Rounded
+addx956 add  0.099E-999   0.1E-999  ->   2.0E-1000  Inexact Rounded Subnormal Underflow
+addx957 add  0.009E-999   0.1E-999  ->   1.1E-1000  Inexact Rounded Subnormal Underflow
+addx958 add  0.001E-999   0.1E-999  ->   1.0E-1000  Inexact Rounded Subnormal Underflow
+addx959 add  0.0009E-999  0.1E-999  ->   1.0E-1000  Inexact Rounded Subnormal Underflow
+addx960 add  0.0001E-999  0.1E-999  ->   1.0E-1000  Inexact Rounded Subnormal Underflow
+-- negatives...
+addx961 add  1.00E-999   -0.1E-999  ->   9.0E-1000  Subnormal
+addx962 add  0.1E-999    -0.1E-999  ->   0E-1000
+addx963 add  0.10E-999   -0.1E-999  ->   0E-1001
+addx964 add  0.100E-999  -0.1E-999  ->   0E-1001    Clamped
+addx965 add  0.01E-999   -0.1E-999  ->   -9E-1001   Subnormal
+addx966 add  0.999E-999  -0.1E-999  ->   9.0E-1000  Inexact Rounded Subnormal Underflow
+addx967 add  0.099E-999  -0.1E-999  ->   -0E-1001   Inexact Rounded Subnormal Underflow
+addx968 add  0.009E-999  -0.1E-999  ->   -9E-1001   Inexact Rounded Subnormal Underflow
+addx969 add  0.001E-999  -0.1E-999  ->   -1.0E-1000 Inexact Rounded Subnormal Underflow
+addx970 add  0.0009E-999 -0.1E-999  ->   -1.0E-1000 Inexact Rounded Subnormal Underflow
+addx971 add  0.0001E-999 -0.1E-999  ->   -1.0E-1000 Inexact Rounded Subnormal Underflow
+
+-- check overflow edge case
+precision:   7
+rounding:    half_up
+maxExponent: 96
+minExponent: -95
+addx972 apply   9.999999E+96         -> 9.999999E+96
+addx973 add     9.999999E+96  1      -> 9.999999E+96 Inexact Rounded
+addx974 add      9999999E+90  1      -> 9.999999E+96 Inexact Rounded
+addx975 add      9999999E+90  1E+90  -> Infinity Overflow Inexact Rounded
+addx976 add      9999999E+90  9E+89  -> Infinity Overflow Inexact Rounded
+addx977 add      9999999E+90  8E+89  -> Infinity Overflow Inexact Rounded
+addx978 add      9999999E+90  7E+89  -> Infinity Overflow Inexact Rounded
+addx979 add      9999999E+90  6E+89  -> Infinity Overflow Inexact Rounded
+addx980 add      9999999E+90  5E+89  -> Infinity Overflow Inexact Rounded
+addx981 add      9999999E+90  4E+89  -> 9.999999E+96 Inexact Rounded
+addx982 add      9999999E+90  3E+89  -> 9.999999E+96 Inexact Rounded
+addx983 add      9999999E+90  2E+89  -> 9.999999E+96 Inexact Rounded
+addx984 add      9999999E+90  1E+89  -> 9.999999E+96 Inexact Rounded
+
+addx985 apply  -9.999999E+96         -> -9.999999E+96
+addx986 add    -9.999999E+96 -1      -> -9.999999E+96 Inexact Rounded
+addx987 add     -9999999E+90 -1      -> -9.999999E+96 Inexact Rounded
+addx988 add     -9999999E+90 -1E+90  -> -Infinity Overflow Inexact Rounded
+addx989 add     -9999999E+90 -9E+89  -> -Infinity Overflow Inexact Rounded
+addx990 add     -9999999E+90 -8E+89  -> -Infinity Overflow Inexact Rounded
+addx991 add     -9999999E+90 -7E+89  -> -Infinity Overflow Inexact Rounded
+addx992 add     -9999999E+90 -6E+89  -> -Infinity Overflow Inexact Rounded
+addx993 add     -9999999E+90 -5E+89  -> -Infinity Overflow Inexact Rounded
+addx994 add     -9999999E+90 -4E+89  -> -9.999999E+96 Inexact Rounded
+addx995 add     -9999999E+90 -3E+89  -> -9.999999E+96 Inexact Rounded
+addx996 add     -9999999E+90 -2E+89  -> -9.999999E+96 Inexact Rounded
+addx997 add     -9999999E+90 -1E+89  -> -9.999999E+96 Inexact Rounded
+
+-- check for double-rounded subnormals
+precision:   5
+maxexponent: 79
+minexponent: -79
+-- Add: lhs and rhs 0
+addx1001 add       1.52444E-80 0 -> 1.524E-80 Inexact Rounded Subnormal Underflow
+addx1002 add       1.52445E-80 0 -> 1.524E-80 Inexact Rounded Subnormal Underflow
+addx1003 add       1.52446E-80 0 -> 1.524E-80 Inexact Rounded Subnormal Underflow
+addx1004 add       0 1.52444E-80 -> 1.524E-80 Inexact Rounded Subnormal Underflow
+addx1005 add       0 1.52445E-80 -> 1.524E-80 Inexact Rounded Subnormal Underflow
+addx1006 add       0 1.52446E-80 -> 1.524E-80 Inexact Rounded Subnormal Underflow
+
+-- Add: lhs >> rhs and vice versa
+addx1011 add       1.52444E-80 1E-100 -> 1.524E-80 Inexact Rounded Subnormal Underflow
+addx1012 add       1.52445E-80 1E-100 -> 1.524E-80 Inexact Rounded Subnormal Underflow
+addx1013 add       1.52446E-80 1E-100 -> 1.524E-80 Inexact Rounded Subnormal Underflow
+addx1014 add       1E-100 1.52444E-80 -> 1.524E-80 Inexact Rounded Subnormal Underflow
+addx1015 add       1E-100 1.52445E-80 -> 1.524E-80 Inexact Rounded Subnormal Underflow
+addx1016 add       1E-100 1.52446E-80 -> 1.524E-80 Inexact Rounded Subnormal Underflow
+
+-- Add: lhs + rhs addition carried out
+addx1021 add       1.52443E-80 1.00001E-80  -> 2.524E-80 Inexact Rounded Subnormal Underflow
+addx1022 add       1.52444E-80 1.00001E-80  -> 2.524E-80 Inexact Rounded Subnormal Underflow
+addx1023 add       1.52445E-80 1.00001E-80  -> 2.524E-80 Inexact Rounded Subnormal Underflow
+addx1024 add       1.00001E-80  1.52443E-80 -> 2.524E-80 Inexact Rounded Subnormal Underflow
+addx1025 add       1.00001E-80  1.52444E-80 -> 2.524E-80 Inexact Rounded Subnormal Underflow
+addx1026 add       1.00001E-80  1.52445E-80 -> 2.524E-80 Inexact Rounded Subnormal Underflow
+
+-- And for round down full and subnormal results
+precision:    16
+maxExponent: +384
+minExponent: -383
+rounding:     down
+
+addx1100 add 1e+2 -1e-383    -> 99.99999999999999 Rounded Inexact
+addx1101 add 1e+1 -1e-383    -> 9.999999999999999  Rounded Inexact
+addx1103 add   +1 -1e-383    -> 0.9999999999999999  Rounded Inexact
+addx1104 add 1e-1 -1e-383    -> 0.09999999999999999  Rounded Inexact
+addx1105 add 1e-2 -1e-383    -> 0.009999999999999999  Rounded Inexact
+addx1106 add 1e-3 -1e-383    -> 0.0009999999999999999  Rounded Inexact
+addx1107 add 1e-4 -1e-383    -> 0.00009999999999999999  Rounded Inexact
+addx1108 add 1e-5 -1e-383    -> 0.000009999999999999999  Rounded Inexact
+addx1109 add 1e-6 -1e-383    -> 9.999999999999999E-7  Rounded Inexact
+
+rounding:     ceiling
+addx1110 add -1e+2 +1e-383   -> -99.99999999999999 Rounded Inexact
+addx1111 add -1e+1 +1e-383   -> -9.999999999999999  Rounded Inexact
+addx1113 add    -1 +1e-383   -> -0.9999999999999999  Rounded Inexact
+addx1114 add -1e-1 +1e-383   -> -0.09999999999999999  Rounded Inexact
+addx1115 add -1e-2 +1e-383   -> -0.009999999999999999  Rounded Inexact
+addx1116 add -1e-3 +1e-383   -> -0.0009999999999999999  Rounded Inexact
+addx1117 add -1e-4 +1e-383   -> -0.00009999999999999999  Rounded Inexact
+addx1118 add -1e-5 +1e-383   -> -0.000009999999999999999  Rounded Inexact
+addx1119 add -1e-6 +1e-383   -> -9.999999999999999E-7  Rounded Inexact
+
+rounding:     down
+precision:    7
+maxExponent: +96
+minExponent: -95
+addx1130 add   1            -1e-200  -> 0.9999999  Rounded Inexact
+-- subnormal boundary
+addx1131 add   1.000000E-94  -1e-200  ->  9.999999E-95  Rounded Inexact
+addx1132 add   1.000001E-95  -1e-200  ->  1.000000E-95  Rounded Inexact
+addx1133 add   1.000000E-95  -1e-200  ->  9.99999E-96  Rounded Inexact Subnormal Underflow
+addx1134 add   0.999999E-95  -1e-200  ->  9.99998E-96  Rounded Inexact Subnormal Underflow
+addx1135 add   0.001000E-95  -1e-200  ->  9.99E-99  Rounded Inexact Subnormal Underflow
+addx1136 add   0.000999E-95  -1e-200  ->  9.98E-99  Rounded Inexact Subnormal Underflow
+addx1137 add   1.000000E-95  -1e-101  ->  9.99999E-96  Subnormal
+addx1138 add      10000E-101 -1e-200  ->  9.999E-98  Subnormal Inexact Rounded Underflow
+addx1139 add       1000E-101 -1e-200  ->  9.99E-99   Subnormal Inexact Rounded Underflow
+addx1140 add        100E-101 -1e-200  ->  9.9E-100   Subnormal Inexact Rounded Underflow
+addx1141 add         10E-101 -1e-200  ->  9E-101     Subnormal Inexact Rounded Underflow
+addx1142 add          1E-101 -1e-200  ->  0E-101     Subnormal Inexact Rounded Underflow
+addx1143 add          0E-101 -1e-200  -> -0E-101     Subnormal Inexact Rounded Underflow
+addx1144 add          1E-102 -1e-200  ->  0E-101     Subnormal Inexact Rounded Underflow
+
+addx1151 add      10000E-102 -1e-200  ->  9.99E-99  Subnormal Inexact Rounded Underflow
+addx1152 add       1000E-102 -1e-200  ->  9.9E-100  Subnormal Inexact Rounded Underflow
+addx1153 add        100E-102 -1e-200  ->  9E-101   Subnormal Inexact Rounded Underflow
+addx1154 add         10E-102 -1e-200  ->  0E-101     Subnormal Inexact Rounded Underflow
+addx1155 add          1E-102 -1e-200  ->  0E-101     Subnormal Inexact Rounded Underflow
+addx1156 add          0E-102 -1e-200  -> -0E-101     Subnormal Inexact Rounded Underflow
+addx1157 add          1E-103 -1e-200  ->  0E-101     Subnormal Inexact Rounded Underflow
+
+addx1160 add        100E-105 -1e-101  -> -0E-101 Subnormal Inexact Rounded Underflow
+addx1161 add        100E-105 -1e-201  ->  0E-101 Subnormal Inexact Rounded Underflow
+
+
+-- Null tests
+addx9990 add 10  # -> NaN Invalid_operation
+addx9991 add  # 10 -> NaN Invalid_operation

Added: vendor/Python/current/Lib/test/decimaltestdata/base.decTest
===================================================================
--- vendor/Python/current/Lib/test/decimaltestdata/base.decTest	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/decimaltestdata/base.decTest	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1272 @@
+------------------------------------------------------------------------
+-- base.decTest -- base decimal <--> string conversions               --
+-- Copyright (c) IBM Corporation, 1981, 2003.  All rights reserved.   --
+------------------------------------------------------------------------
+-- Please see the document "General Decimal Arithmetic Testcases"     --
+-- at http://www2.hursley.ibm.com/decimal for the description of      --
+-- these testcases.                                                   --
+--                                                                    --
+-- These testcases are experimental ('beta' versions), and they       --
+-- may contain errors.  They are offered on an as-is basis.  In       --
+-- particular, achieving the same results as the tests here is not    --
+-- a guarantee that an implementation complies with any Standard      --
+-- or specification.  The tests are not exhaustive.                   --
+--                                                                    --
+-- Please send comments, suggestions, and corrections to the author:  --
+--   Mike Cowlishaw, IBM Fellow                                       --
+--   IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK         --
+--   mfc at uk.ibm.com                                                   --
+------------------------------------------------------------------------
+version: 2.39
+
+-- This file tests base conversions from string to a decimal number
+-- and back to a string (in either Scientific or Engineering form)
+
+-- Note that unlike other operations the operand is subject to rounding
+-- to conform to emax and precision settings (that is, numbers will
+-- conform to rules and exponent will be in permitted range).
+
+precision:   15
+rounding:    half_up
+maxExponent: 999999999
+minExponent: -999999999
+extended:    1
+
+basx001 toSci       0 -> 0
+basx002 toSci       1 -> 1
+basx003 toSci     1.0 -> 1.0
+basx004 toSci    1.00 -> 1.00
+basx005 toSci      10 -> 10
+basx006 toSci    1000 -> 1000
+basx007 toSci    10.0 -> 10.0
+basx008 toSci    10.1 -> 10.1
+basx009 toSci    10.4 -> 10.4
+basx010 toSci    10.5 -> 10.5
+basx011 toSci    10.6 -> 10.6
+basx012 toSci    10.9 -> 10.9
+basx013 toSci    11.0 -> 11.0
+basx014 toSci  1.234 -> 1.234
+basx015 toSci  0.123 -> 0.123
+basx016 toSci  0.012 -> 0.012
+basx017 toSci  -0    -> -0
+basx018 toSci  -0.0  -> -0.0
+basx019 toSci -00.00 -> -0.00
+
+basx021 toSci     -1 -> -1
+basx022 toSci   -1.0 -> -1.0
+basx023 toSci   -0.1 -> -0.1
+basx024 toSci   -9.1 -> -9.1
+basx025 toSci   -9.11 -> -9.11
+basx026 toSci   -9.119 -> -9.119
+basx027 toSci   -9.999 -> -9.999
+
+basx030 toSci  '123456789.123456'   -> '123456789.123456'
+basx031 toSci  '123456789.000000'   -> '123456789.000000'
+basx032 toSci   '123456789123456'   -> '123456789123456'
+basx033 toSci   '0.0000123456789'   -> '0.0000123456789'
+basx034 toSci  '0.00000123456789'   -> '0.00000123456789'
+basx035 toSci '0.000000123456789'   -> '1.23456789E-7'
+basx036 toSci '0.0000000123456789'  -> '1.23456789E-8'
+
+basx037 toSci '0.123456789012344'   -> '0.123456789012344'
+basx038 toSci '0.123456789012345'   -> '0.123456789012345'
+
+-- String [many more examples are implicitly tested elsewhere]
+-- strings without E cannot generate E in result
+basx100 toSci "12"        -> '12'
+basx101 toSci "-76"       -> '-76'
+basx102 toSci "12.76"     -> '12.76'
+basx103 toSci "+12.76"    -> '12.76'
+basx104 toSci "012.76"    -> '12.76'
+basx105 toSci "+0.003"    -> '0.003'
+basx106 toSci "17."       -> '17'
+basx107 toSci ".5"        -> '0.5'
+basx108 toSci "044"       -> '44'
+basx109 toSci "0044"      -> '44'
+basx110 toSci "0.0005"      -> '0.0005'
+basx111 toSci "00.00005"    -> '0.00005'
+basx112 toSci "0.000005"    -> '0.000005'
+basx113 toSci "0.0000050"   -> '0.0000050'
+basx114 toSci "0.0000005"   -> '5E-7'
+basx115 toSci "0.00000005"  -> '5E-8'
+basx116 toSci "12345678.543210" -> '12345678.543210'
+basx117 toSci "2345678.543210" -> '2345678.543210'
+basx118 toSci "345678.543210" -> '345678.543210'
+basx119 toSci "0345678.54321" -> '345678.54321'
+basx120 toSci "345678.5432" -> '345678.5432'
+basx121 toSci "+345678.5432" -> '345678.5432'
+basx122 toSci "+0345678.5432" -> '345678.5432'
+basx123 toSci "+00345678.5432" -> '345678.5432'
+basx124 toSci "-345678.5432"  -> '-345678.5432'
+basx125 toSci "-0345678.5432"  -> '-345678.5432'
+basx126 toSci "-00345678.5432"  -> '-345678.5432'
+-- examples
+basx127 toSci "5E-6"        -> '0.000005'
+basx128 toSci "50E-7"       -> '0.0000050'
+basx129 toSci "5E-7"        -> '5E-7'
+
+
+-- [No exotics as no Unicode]
+
+-- Numbers with E
+basx130 toSci "0.000E-1"  -> '0.0000'
+basx131 toSci "0.000E-2"  -> '0.00000'
+basx132 toSci "0.000E-3"  -> '0.000000'
+basx133 toSci "0.000E-4"  -> '0E-7'
+basx134 toSci "0.00E-2"   -> '0.0000'
+basx135 toSci "0.00E-3"   -> '0.00000'
+basx136 toSci "0.00E-4"   -> '0.000000'
+basx137 toSci "0.00E-5"   -> '0E-7'
+basx138 toSci "+0E+9"     -> '0E+9'
+basx139 toSci "-0E+9"     -> '-0E+9'
+basx140 toSci "1E+9"      -> '1E+9'
+basx141 toSci "1e+09"     -> '1E+9'
+basx142 toSci "1E+90"     -> '1E+90'
+basx143 toSci "+1E+009"   -> '1E+9'
+basx144 toSci "0E+9"      -> '0E+9'
+basx145 toSci "1E+9"      -> '1E+9'
+basx146 toSci "1E+09"     -> '1E+9'
+basx147 toSci "1e+90"     -> '1E+90'
+basx148 toSci "1E+009"    -> '1E+9'
+basx149 toSci "000E+9"    -> '0E+9'
+basx150 toSci "1E9"       -> '1E+9'
+basx151 toSci "1e09"      -> '1E+9'
+basx152 toSci "1E90"      -> '1E+90'
+basx153 toSci "1E009"     -> '1E+9'
+basx154 toSci "0E9"       -> '0E+9'
+basx155 toSci "0.000e+0"  -> '0.000'
+basx156 toSci "0.000E-1"  -> '0.0000'
+basx157 toSci "4E+9"      -> '4E+9'
+basx158 toSci "44E+9"     -> '4.4E+10'
+basx159 toSci "0.73e-7"   -> '7.3E-8'
+basx160 toSci "00E+9"     -> '0E+9'
+basx161 toSci "00E-9"     -> '0E-9'
+basx162 toSci "10E+9"     -> '1.0E+10'
+basx163 toSci "10E+09"    -> '1.0E+10'
+basx164 toSci "10e+90"    -> '1.0E+91'
+basx165 toSci "10E+009"   -> '1.0E+10'
+basx166 toSci "100e+9"    -> '1.00E+11'
+basx167 toSci "100e+09"   -> '1.00E+11'
+basx168 toSci "100E+90"   -> '1.00E+92'
+basx169 toSci "100e+009"  -> '1.00E+11'
+
+basx170 toSci "1.265"     -> '1.265'
+basx171 toSci "1.265E-20" -> '1.265E-20'
+basx172 toSci "1.265E-8"  -> '1.265E-8'
+basx173 toSci "1.265E-4"  -> '0.0001265'
+basx174 toSci "1.265E-3"  -> '0.001265'
+basx175 toSci "1.265E-2"  -> '0.01265'
+basx176 toSci "1.265E-1"  -> '0.1265'
+basx177 toSci "1.265E-0"  -> '1.265'
+basx178 toSci "1.265E+1"  -> '12.65'
+basx179 toSci "1.265E+2"  -> '126.5'
+basx180 toSci "1.265E+3"  -> '1265'
+basx181 toSci "1.265E+4"  -> '1.265E+4'
+basx182 toSci "1.265E+8"  -> '1.265E+8'
+basx183 toSci "1.265E+20" -> '1.265E+20'
+
+basx190 toSci "12.65"     -> '12.65'
+basx191 toSci "12.65E-20" -> '1.265E-19'
+basx192 toSci "12.65E-8"  -> '1.265E-7'
+basx193 toSci "12.65E-4"  -> '0.001265'
+basx194 toSci "12.65E-3"  -> '0.01265'
+basx195 toSci "12.65E-2"  -> '0.1265'
+basx196 toSci "12.65E-1"  -> '1.265'
+basx197 toSci "12.65E-0"  -> '12.65'
+basx198 toSci "12.65E+1"  -> '126.5'
+basx199 toSci "12.65E+2"  -> '1265'
+basx200 toSci "12.65E+3"  -> '1.265E+4'
+basx201 toSci "12.65E+4"  -> '1.265E+5'
+basx202 toSci "12.65E+8"  -> '1.265E+9'
+basx203 toSci "12.65E+20" -> '1.265E+21'
+
+basx210 toSci "126.5"     -> '126.5'
+basx211 toSci "126.5E-20" -> '1.265E-18'
+basx212 toSci "126.5E-8"  -> '0.000001265'
+basx213 toSci "126.5E-4"  -> '0.01265'
+basx214 toSci "126.5E-3"  -> '0.1265'
+basx215 toSci "126.5E-2"  -> '1.265'
+basx216 toSci "126.5E-1"  -> '12.65'
+basx217 toSci "126.5E-0"  -> '126.5'
+basx218 toSci "126.5E+1"  -> '1265'
+basx219 toSci "126.5E+2"  -> '1.265E+4'
+basx220 toSci "126.5E+3"  -> '1.265E+5'
+basx221 toSci "126.5E+4"  -> '1.265E+6'
+basx222 toSci "126.5E+8"  -> '1.265E+10'
+basx223 toSci "126.5E+20" -> '1.265E+22'
+
+basx230 toSci "1265"     -> '1265'
+basx231 toSci "1265E-20" -> '1.265E-17'
+basx232 toSci "1265E-8"  -> '0.00001265'
+basx233 toSci "1265E-4"  -> '0.1265'
+basx234 toSci "1265E-3"  -> '1.265'
+basx235 toSci "1265E-2"  -> '12.65'
+basx236 toSci "1265E-1"  -> '126.5'
+basx237 toSci "1265E-0"  -> '1265'
+basx238 toSci "1265E+1"  -> '1.265E+4'
+basx239 toSci "1265E+2"  -> '1.265E+5'
+basx240 toSci "1265E+3"  -> '1.265E+6'
+basx241 toSci "1265E+4"  -> '1.265E+7'
+basx242 toSci "1265E+8"  -> '1.265E+11'
+basx243 toSci "1265E+20" -> '1.265E+23'
+
+basx250 toSci "0.1265"     -> '0.1265'
+basx251 toSci "0.1265E-20" -> '1.265E-21'
+basx252 toSci "0.1265E-8"  -> '1.265E-9'
+basx253 toSci "0.1265E-4"  -> '0.00001265'
+basx254 toSci "0.1265E-3"  -> '0.0001265'
+basx255 toSci "0.1265E-2"  -> '0.001265'
+basx256 toSci "0.1265E-1"  -> '0.01265'
+basx257 toSci "0.1265E-0"  -> '0.1265'
+basx258 toSci "0.1265E+1"  -> '1.265'
+basx259 toSci "0.1265E+2"  -> '12.65'
+basx260 toSci "0.1265E+3"  -> '126.5'
+basx261 toSci "0.1265E+4"  -> '1265'
+basx262 toSci "0.1265E+8"  -> '1.265E+7'
+basx263 toSci "0.1265E+20" -> '1.265E+19'
+
+basx270 toSci "0.09e999"  -> '9E+997'
+basx271 toSci "0.9e999"   -> '9E+998'
+basx272 toSci "9e999"     -> '9E+999'
+basx273 toSci "9.9e999"   -> '9.9E+999'
+basx274 toSci "9.99e999"  -> '9.99E+999'
+basx275 toSci "9.99e-999" -> '9.99E-999'
+basx276 toSci "9.9e-999"  -> '9.9E-999'
+basx277 toSci "9e-999"    -> '9E-999'
+basx279 toSci "99e-999"   -> '9.9E-998'
+basx280 toSci "999e-999"  -> '9.99E-997'
+basx281 toSci '0.9e-998'  -> '9E-999'
+basx282 toSci '0.09e-997' -> '9E-999'
+basx283 toSci '0.1e1000'  -> '1E+999'
+basx284 toSci '10e-1000'  -> '1.0E-999'
+
+-- some more negative zeros [systematic tests below]
+basx290 toSci "-0.000E-1"  -> '-0.0000'
+basx291 toSci "-0.000E-2"  -> '-0.00000'
+basx292 toSci "-0.000E-3"  -> '-0.000000'
+basx293 toSci "-0.000E-4"  -> '-0E-7'
+basx294 toSci "-0.00E-2"   -> '-0.0000'
+basx295 toSci "-0.00E-3"   -> '-0.00000'
+basx296 toSci "-0.0E-2"    -> '-0.000'
+basx297 toSci "-0.0E-3"    -> '-0.0000'
+basx298 toSci "-0E-2"      -> '-0.00'
+basx299 toSci "-0E-3"      -> '-0.000'
+
+-- Engineering notation tests
+basx301  toSci 10e12  -> 1.0E+13
+basx302  toEng 10e12  -> 10E+12
+basx303  toSci 10e11  -> 1.0E+12
+basx304  toEng 10e11  -> 1.0E+12
+basx305  toSci 10e10  -> 1.0E+11
+basx306  toEng 10e10  -> 100E+9
+basx307  toSci 10e9   -> 1.0E+10
+basx308  toEng 10e9   -> 10E+9
+basx309  toSci 10e8   -> 1.0E+9
+basx310  toEng 10e8   -> 1.0E+9
+basx311  toSci 10e7   -> 1.0E+8
+basx312  toEng 10e7   -> 100E+6
+basx313  toSci 10e6   -> 1.0E+7
+basx314  toEng 10e6   -> 10E+6
+basx315  toSci 10e5   -> 1.0E+6
+basx316  toEng 10e5   -> 1.0E+6
+basx317  toSci 10e4   -> 1.0E+5
+basx318  toEng 10e4   -> 100E+3
+basx319  toSci 10e3   -> 1.0E+4
+basx320  toEng 10e3   -> 10E+3
+basx321  toSci 10e2   -> 1.0E+3
+basx322  toEng 10e2   -> 1.0E+3
+basx323  toSci 10e1   -> 1.0E+2
+basx324  toEng 10e1   -> 100
+basx325  toSci 10e0   -> 10
+basx326  toEng 10e0   -> 10
+basx327  toSci 10e-1  -> 1.0
+basx328  toEng 10e-1  -> 1.0
+basx329  toSci 10e-2  -> 0.10
+basx330  toEng 10e-2  -> 0.10
+basx331  toSci 10e-3  -> 0.010
+basx332  toEng 10e-3  -> 0.010
+basx333  toSci 10e-4  -> 0.0010
+basx334  toEng 10e-4  -> 0.0010
+basx335  toSci 10e-5  -> 0.00010
+basx336  toEng 10e-5  -> 0.00010
+basx337  toSci 10e-6  -> 0.000010
+basx338  toEng 10e-6  -> 0.000010
+basx339  toSci 10e-7  -> 0.0000010
+basx340  toEng 10e-7  -> 0.0000010
+basx341  toSci 10e-8  -> 1.0E-7
+basx342  toEng 10e-8  -> 100E-9
+basx343  toSci 10e-9  -> 1.0E-8
+basx344  toEng 10e-9  -> 10E-9
+basx345  toSci 10e-10 -> 1.0E-9
+basx346  toEng 10e-10 -> 1.0E-9
+basx347  toSci 10e-11 -> 1.0E-10
+basx348  toEng 10e-11 -> 100E-12
+basx349  toSci 10e-12 -> 1.0E-11
+basx350  toEng 10e-12 -> 10E-12
+basx351  toSci 10e-13 -> 1.0E-12
+basx352  toEng 10e-13 -> 1.0E-12
+
+basx361  toSci 7E12  -> 7E+12
+basx362  toEng 7E12  -> 7E+12
+basx363  toSci 7E11  -> 7E+11
+basx364  toEng 7E11  -> 700E+9
+basx365  toSci 7E10  -> 7E+10
+basx366  toEng 7E10  -> 70E+9
+basx367  toSci 7E9   -> 7E+9
+basx368  toEng 7E9   -> 7E+9
+basx369  toSci 7E8   -> 7E+8
+basx370  toEng 7E8   -> 700E+6
+basx371  toSci 7E7   -> 7E+7
+basx372  toEng 7E7   -> 70E+6
+basx373  toSci 7E6   -> 7E+6
+basx374  toEng 7E6   -> 7E+6
+basx375  toSci 7E5   -> 7E+5
+basx376  toEng 7E5   -> 700E+3
+basx377  toSci 7E4   -> 7E+4
+basx378  toEng 7E4   -> 70E+3
+basx379  toSci 7E3   -> 7E+3
+basx380  toEng 7E3   -> 7E+3
+basx381  toSci 7E2   -> 7E+2
+basx382  toEng 7E2   -> 700
+basx383  toSci 7E1   -> 7E+1
+basx384  toEng 7E1   -> 70
+basx385  toSci 7E0   -> 7
+basx386  toEng 7E0   -> 7
+basx387  toSci 7E-1  -> 0.7
+basx388  toEng 7E-1  -> 0.7
+basx389  toSci 7E-2  -> 0.07
+basx390  toEng 7E-2  -> 0.07
+basx391  toSci 7E-3  -> 0.007
+basx392  toEng 7E-3  -> 0.007
+basx393  toSci 7E-4  -> 0.0007
+basx394  toEng 7E-4  -> 0.0007
+basx395  toSci 7E-5  -> 0.00007
+basx396  toEng 7E-5  -> 0.00007
+basx397  toSci 7E-6  -> 0.000007
+basx398  toEng 7E-6  -> 0.000007
+basx399  toSci 7E-7  -> 7E-7
+basx400  toEng 7E-7  -> 700E-9
+basx401  toSci 7E-8  -> 7E-8
+basx402  toEng 7E-8  -> 70E-9
+basx403  toSci 7E-9  -> 7E-9
+basx404  toEng 7E-9  -> 7E-9
+basx405  toSci 7E-10 -> 7E-10
+basx406  toEng 7E-10 -> 700E-12
+basx407  toSci 7E-11 -> 7E-11
+basx408  toEng 7E-11 -> 70E-12
+basx409  toSci 7E-12 -> 7E-12
+basx410  toEng 7E-12 -> 7E-12
+basx411  toSci 7E-13 -> 7E-13
+basx412  toEng 7E-13 -> 700E-15
+
+-- Exacts remain exact up to precision ..
+precision: 9
+basx420  toSci    100 -> 100
+basx421  toEng    100 -> 100
+basx422  toSci   1000 -> 1000
+basx423  toEng   1000 -> 1000
+basx424  toSci  999.9 ->  999.9
+basx425  toEng  999.9 ->  999.9
+basx426  toSci 1000.0 -> 1000.0
+basx427  toEng 1000.0 -> 1000.0
+basx428  toSci 1000.1 -> 1000.1
+basx429  toEng 1000.1 -> 1000.1
+basx430  toSci 10000 -> 10000
+basx431  toEng 10000 -> 10000
+basx432  toSci 100000 -> 100000
+basx433  toEng 100000 -> 100000
+basx434  toSci 1000000 -> 1000000
+basx435  toEng 1000000 -> 1000000
+basx436  toSci 10000000 -> 10000000
+basx437  toEng 10000000 -> 10000000
+basx438  toSci 100000000 -> 100000000
+basx439  toEng 100000000 -> 100000000
+basx440  toSci 1000000000    -> 1.00000000E+9    Rounded
+basx441  toEng 1000000000    -> 1.00000000E+9    Rounded
+basx442  toSci 1000000000    -> 1.00000000E+9    Rounded
+basx443  toEng 1000000000    -> 1.00000000E+9    Rounded
+basx444  toSci 1000000003    -> 1.00000000E+9    Rounded Inexact
+basx445  toEng 1000000003    -> 1.00000000E+9    Rounded Inexact
+basx446  toSci 1000000005    -> 1.00000001E+9    Rounded Inexact
+basx447  toEng 1000000005    -> 1.00000001E+9    Rounded Inexact
+basx448  toSci 10000000050   -> 1.00000001E+10   Rounded Inexact
+basx449  toEng 10000000050   -> 10.0000001E+9    Rounded Inexact
+basx450  toSci 1000000009    -> 1.00000001E+9    Rounded Inexact
+basx451  toEng 1000000009    -> 1.00000001E+9    Rounded Inexact
+basx452  toSci 10000000000   -> 1.00000000E+10   Rounded
+basx453  toEng 10000000000   -> 10.0000000E+9    Rounded
+basx454  toSci 10000000003   -> 1.00000000E+10   Rounded Inexact
+basx455  toEng 10000000003   -> 10.0000000E+9    Rounded Inexact
+basx456  toSci 10000000005   -> 1.00000000E+10   Rounded Inexact
+basx457  toEng 10000000005   -> 10.0000000E+9    Rounded Inexact
+basx458  toSci 10000000009   -> 1.00000000E+10   Rounded Inexact
+basx459  toEng 10000000009   -> 10.0000000E+9    Rounded Inexact
+basx460  toSci 100000000000  -> 1.00000000E+11   Rounded
+basx461  toEng 100000000000  -> 100.000000E+9    Rounded
+basx462  toSci 100000000300  -> 1.00000000E+11   Rounded Inexact
+basx463  toEng 100000000300  -> 100.000000E+9    Rounded Inexact
+basx464  toSci 100000000500  -> 1.00000001E+11   Rounded Inexact
+basx465  toEng 100000000500  -> 100.000001E+9    Rounded Inexact
+basx466  toSci 100000000900  -> 1.00000001E+11   Rounded Inexact
+basx467  toEng 100000000900  -> 100.000001E+9    Rounded Inexact
+basx468  toSci 1000000000000 -> 1.00000000E+12   Rounded
+basx469  toEng 1000000000000 -> 1.00000000E+12   Rounded
+basx470  toSci 1000000003000 -> 1.00000000E+12   Rounded Inexact
+basx471  toEng 1000000003000 -> 1.00000000E+12   Rounded Inexact
+basx472  toSci 1000000005000 -> 1.00000001E+12   Rounded Inexact
+basx473  toEng 1000000005000 -> 1.00000001E+12   Rounded Inexact
+basx474  toSci 1000000009000 -> 1.00000001E+12   Rounded Inexact
+basx475  toEng 1000000009000 -> 1.00000001E+12   Rounded Inexact
+
+-- check rounding modes heeded
+precision: 5
+rounding:  ceiling
+bsrx401  toSci  1.23450    ->  1.2345  Rounded
+bsrx402  toSci  1.234549   ->  1.2346  Rounded Inexact
+bsrx403  toSci  1.234550   ->  1.2346  Rounded Inexact
+bsrx404  toSci  1.234551   ->  1.2346  Rounded Inexact
+rounding:  down
+bsrx405  toSci  1.23450    ->  1.2345  Rounded
+bsrx406  toSci  1.234549   ->  1.2345  Rounded Inexact
+bsrx407  toSci  1.234550   ->  1.2345  Rounded Inexact
+bsrx408  toSci  1.234551   ->  1.2345  Rounded Inexact
+rounding:  floor
+bsrx410  toSci  1.23450    ->  1.2345  Rounded
+bsrx411  toSci  1.234549   ->  1.2345  Rounded Inexact
+bsrx412  toSci  1.234550   ->  1.2345  Rounded Inexact
+bsrx413  toSci  1.234551   ->  1.2345  Rounded Inexact
+rounding:  half_down
+bsrx415  toSci  1.23450    ->  1.2345  Rounded
+bsrx416  toSci  1.234549   ->  1.2345  Rounded Inexact
+bsrx417  toSci  1.234550   ->  1.2345  Rounded Inexact
+bsrx418  toSci  1.234650   ->  1.2346  Rounded Inexact
+bsrx419  toSci  1.234551   ->  1.2346  Rounded Inexact
+rounding:  half_even
+bsrx421  toSci  1.23450    ->  1.2345  Rounded
+bsrx422  toSci  1.234549   ->  1.2345  Rounded Inexact
+bsrx423  toSci  1.234550   ->  1.2346  Rounded Inexact
+bsrx424  toSci  1.234650   ->  1.2346  Rounded Inexact
+bsrx425  toSci  1.234551   ->  1.2346  Rounded Inexact
+rounding:  down
+bsrx426  toSci  1.23450    ->  1.2345  Rounded
+bsrx427  toSci  1.234549   ->  1.2345  Rounded Inexact
+bsrx428  toSci  1.234550   ->  1.2345  Rounded Inexact
+bsrx429  toSci  1.234551   ->  1.2345  Rounded Inexact
+rounding:  half_up
+bsrx431  toSci  1.23450    ->  1.2345  Rounded
+bsrx432  toSci  1.234549   ->  1.2345  Rounded Inexact
+bsrx433  toSci  1.234550   ->  1.2346  Rounded Inexact
+bsrx434  toSci  1.234650   ->  1.2347  Rounded Inexact
+bsrx435  toSci  1.234551   ->  1.2346  Rounded Inexact
+-- negatives
+rounding:  ceiling
+bsrx501  toSci -1.23450    -> -1.2345  Rounded
+bsrx502  toSci -1.234549   -> -1.2345  Rounded Inexact
+bsrx503  toSci -1.234550   -> -1.2345  Rounded Inexact
+bsrx504  toSci -1.234551   -> -1.2345  Rounded Inexact
+rounding:  down
+bsrx505  toSci -1.23450    -> -1.2345  Rounded
+bsrx506  toSci -1.234549   -> -1.2345  Rounded Inexact
+bsrx507  toSci -1.234550   -> -1.2345  Rounded Inexact
+bsrx508  toSci -1.234551   -> -1.2345  Rounded Inexact
+rounding:  floor
+bsrx510  toSci -1.23450    -> -1.2345  Rounded
+bsrx511  toSci -1.234549   -> -1.2346  Rounded Inexact
+bsrx512  toSci -1.234550   -> -1.2346  Rounded Inexact
+bsrx513  toSci -1.234551   -> -1.2346  Rounded Inexact
+rounding:  half_down
+bsrx515  toSci -1.23450    -> -1.2345  Rounded
+bsrx516  toSci -1.234549   -> -1.2345  Rounded Inexact
+bsrx517  toSci -1.234550   -> -1.2345  Rounded Inexact
+bsrx518  toSci -1.234650   -> -1.2346  Rounded Inexact
+bsrx519  toSci -1.234551   -> -1.2346  Rounded Inexact
+rounding:  half_even
+bsrx521  toSci -1.23450    -> -1.2345  Rounded
+bsrx522  toSci -1.234549   -> -1.2345  Rounded Inexact
+bsrx523  toSci -1.234550   -> -1.2346  Rounded Inexact
+bsrx524  toSci -1.234650   -> -1.2346  Rounded Inexact
+bsrx525  toSci -1.234551   -> -1.2346  Rounded Inexact
+rounding:  down
+bsrx526  toSci -1.23450    -> -1.2345  Rounded
+bsrx527  toSci -1.234549   -> -1.2345  Rounded Inexact
+bsrx528  toSci -1.234550   -> -1.2345  Rounded Inexact
+bsrx529  toSci -1.234551   -> -1.2345  Rounded Inexact
+rounding:  half_up
+bsrx531  toSci -1.23450    -> -1.2345  Rounded
+bsrx532  toSci -1.234549   -> -1.2345  Rounded Inexact
+bsrx533  toSci -1.234550   -> -1.2346  Rounded Inexact
+bsrx534  toSci -1.234650   -> -1.2347  Rounded Inexact
+bsrx535  toSci -1.234551   -> -1.2346  Rounded Inexact
+
+rounding:  half_up
+precision: 9
+
+-- The 'baddies' tests from DiagBigDecimal, plus some new ones
+basx500 toSci '1..2'            -> NaN Conversion_syntax
+basx501 toSci '.'               -> NaN Conversion_syntax
+basx502 toSci '..'              -> NaN Conversion_syntax
+basx503 toSci '++1'             -> NaN Conversion_syntax
+basx504 toSci '--1'             -> NaN Conversion_syntax
+basx505 toSci '-+1'             -> NaN Conversion_syntax
+basx506 toSci '+-1'             -> NaN Conversion_syntax
+basx507 toSci '12e'             -> NaN Conversion_syntax
+basx508 toSci '12e++'           -> NaN Conversion_syntax
+basx509 toSci '12f4'            -> NaN Conversion_syntax
+basx510 toSci ' +1'             -> NaN Conversion_syntax
+basx511 toSci '+ 1'             -> NaN Conversion_syntax
+basx512 toSci '12 '             -> NaN Conversion_syntax
+basx513 toSci ' + 1'            -> NaN Conversion_syntax
+basx514 toSci ' - 1 '           -> NaN Conversion_syntax
+basx515 toSci 'x'               -> NaN Conversion_syntax
+basx516 toSci '-1-'             -> NaN Conversion_syntax
+basx517 toSci '12-'             -> NaN Conversion_syntax
+basx518 toSci '3+'              -> NaN Conversion_syntax
+basx519 toSci ''                -> NaN Conversion_syntax
+basx520 toSci '1e-'             -> NaN Conversion_syntax
+basx521 toSci '7e99999a'        -> NaN Conversion_syntax
+basx522 toSci '7e123567890x'    -> NaN Conversion_syntax
+basx523 toSci '7e12356789012x'  -> NaN Conversion_syntax
+basx524 toSci ''                -> NaN Conversion_syntax
+basx525 toSci 'e100'            -> NaN Conversion_syntax
+basx526 toSci '\u0e5a'          -> NaN Conversion_syntax
+basx527 toSci '\u0b65'          -> NaN Conversion_syntax
+basx528 toSci '123,65'          -> NaN Conversion_syntax
+basx529 toSci '1.34.5'          -> NaN Conversion_syntax
+basx530 toSci '.123.5'          -> NaN Conversion_syntax
+basx531 toSci '01.35.'          -> NaN Conversion_syntax
+basx532 toSci '01.35-'          -> NaN Conversion_syntax
+basx533 toSci '0000..'          -> NaN Conversion_syntax
+basx534 toSci '.0000.'          -> NaN Conversion_syntax
+basx535 toSci '00..00'          -> NaN Conversion_syntax
+basx536 toSci '111e*123'        -> NaN Conversion_syntax
+basx537 toSci '111e123-'        -> NaN Conversion_syntax
+basx538 toSci '111e+12+'        -> NaN Conversion_syntax
+basx539 toSci '111e1-3-'        -> NaN Conversion_syntax
+basx540 toSci '111e1*23'        -> NaN Conversion_syntax
+basx541 toSci '111e1e+3'        -> NaN Conversion_syntax
+basx542 toSci '1e1.0'           -> NaN Conversion_syntax
+basx543 toSci '1e123e'          -> NaN Conversion_syntax
+basx544 toSci 'ten'             -> NaN Conversion_syntax
+basx545 toSci 'ONE'             -> NaN Conversion_syntax
+basx546 toSci '1e.1'            -> NaN Conversion_syntax
+basx547 toSci '1e1.'            -> NaN Conversion_syntax
+basx548 toSci '1ee'             -> NaN Conversion_syntax
+basx549 toSci 'e+1'             -> NaN Conversion_syntax
+basx550 toSci '1.23.4'          -> NaN Conversion_syntax
+basx551 toSci '1.2.1'           -> NaN Conversion_syntax
+basx552 toSci '1E+1.2'          -> NaN Conversion_syntax
+basx553 toSci '1E+1.2.3'        -> NaN Conversion_syntax
+basx554 toSci '1E++1'           -> NaN Conversion_syntax
+basx555 toSci '1E--1'           -> NaN Conversion_syntax
+basx556 toSci '1E+-1'           -> NaN Conversion_syntax
+basx557 toSci '1E-+1'           -> NaN Conversion_syntax
+basx558 toSci '1E''1'           -> NaN Conversion_syntax
+basx559 toSci "1E""1"           -> NaN Conversion_syntax
+basx560 toSci "1E"""""          -> NaN Conversion_syntax
+-- Near-specials
+basx561 toSci "qNaN"            -> NaN Conversion_syntax
+basx562 toSci "NaNq"            -> NaN Conversion_syntax
+basx563 toSci "NaNs"            -> NaN Conversion_syntax
+basx564 toSci "Infi"            -> NaN Conversion_syntax
+basx565 toSci "Infin"           -> NaN Conversion_syntax
+basx566 toSci "Infini"          -> NaN Conversion_syntax
+basx567 toSci "Infinit"         -> NaN Conversion_syntax
+basx568 toSci "-Infinit"        -> NaN Conversion_syntax
+basx569 toSci "0Inf"            -> NaN Conversion_syntax
+basx570 toSci "9Inf"            -> NaN Conversion_syntax
+basx571 toSci "-0Inf"           -> NaN Conversion_syntax
+basx572 toSci "-9Inf"           -> NaN Conversion_syntax
+basx573 toSci "-sNa"            -> NaN Conversion_syntax
+basx574 toSci "xNaN"            -> NaN Conversion_syntax
+basx575 toSci "0sNaN"           -> NaN Conversion_syntax
+
+-- subnormals and overflows
+basx576 toSci '99e999999999'       -> Infinity Overflow  Inexact Rounded
+basx577 toSci '999e999999999'      -> Infinity Overflow  Inexact Rounded
+basx578 toSci '0.9e-999999999'     -> 9E-1000000000 Subnormal
+basx579 toSci '0.09e-999999999'    -> 9E-1000000001 Subnormal
+basx580 toSci '0.1e1000000000'     -> 1E+999999999
+basx581 toSci '10e-1000000000'     -> 1.0E-999999999
+basx582 toSci '0.9e9999999999'     -> Infinity Overflow  Inexact Rounded
+basx583 toSci '99e-9999999999'     -> 0E-1000000007 Underflow Subnormal Inexact Rounded
+basx584 toSci '111e9999999999'     -> Infinity Overflow  Inexact Rounded
+basx585 toSci '1111e-9999999999'   -> 0E-1000000007 Underflow Subnormal Inexact Rounded
+basx586 toSci '1111e-99999999999'  -> 0E-1000000007 Underflow Subnormal Inexact Rounded
+basx587 toSci '7e1000000000'       -> Infinity Overflow  Inexact Rounded
+-- negatives the same
+basx588 toSci '-99e999999999'      -> -Infinity Overflow  Inexact Rounded
+basx589 toSci '-999e999999999'     -> -Infinity Overflow  Inexact Rounded
+basx590 toSci '-0.9e-999999999'    -> -9E-1000000000 Subnormal
+basx591 toSci '-0.09e-999999999'   -> -9E-1000000001 Subnormal
+basx592 toSci '-0.1e1000000000'    -> -1E+999999999
+basx593 toSci '-10e-1000000000'    -> -1.0E-999999999
+basx594 toSci '-0.9e9999999999'    -> -Infinity Overflow  Inexact Rounded
+basx595 toSci '-99e-9999999999'    -> -0E-1000000007 Underflow Subnormal Inexact Rounded
+basx596 toSci '-111e9999999999'    -> -Infinity Overflow  Inexact Rounded
+basx597 toSci '-1111e-9999999999'  -> -0E-1000000007 Underflow Subnormal Inexact Rounded
+basx598 toSci '-1111e-99999999999' -> -0E-1000000007 Underflow Subnormal Inexact Rounded
+basx599 toSci '-7e1000000000'      -> -Infinity Overflow  Inexact Rounded
+
+-- Zeros
+basx601 toSci 0.000000000       -> 0E-9
+basx602 toSci 0.00000000        -> 0E-8
+basx603 toSci 0.0000000         -> 0E-7
+basx604 toSci 0.000000          -> 0.000000
+basx605 toSci 0.00000           -> 0.00000
+basx606 toSci 0.0000            -> 0.0000
+basx607 toSci 0.000             -> 0.000
+basx608 toSci 0.00              -> 0.00
+basx609 toSci 0.0               -> 0.0
+basx610 toSci  .0               -> 0.0
+basx611 toSci 0.                -> 0
+basx612 toSci -.0               -> -0.0
+basx613 toSci -0.               -> -0
+basx614 toSci -0.0              -> -0.0
+basx615 toSci -0.00             -> -0.00
+basx616 toSci -0.000            -> -0.000
+basx617 toSci -0.0000           -> -0.0000
+basx618 toSci -0.00000          -> -0.00000
+basx619 toSci -0.000000         -> -0.000000
+basx620 toSci -0.0000000        -> -0E-7
+basx621 toSci -0.00000000       -> -0E-8
+basx622 toSci -0.000000000      -> -0E-9
+
+basx630 toSci  0.00E+0          -> 0.00
+basx631 toSci  0.00E+1          -> 0.0
+basx632 toSci  0.00E+2          -> 0
+basx633 toSci  0.00E+3          -> 0E+1
+basx634 toSci  0.00E+4          -> 0E+2
+basx635 toSci  0.00E+5          -> 0E+3
+basx636 toSci  0.00E+6          -> 0E+4
+basx637 toSci  0.00E+7          -> 0E+5
+basx638 toSci  0.00E+8          -> 0E+6
+basx639 toSci  0.00E+9          -> 0E+7
+
+basx640 toSci  0.0E+0           -> 0.0
+basx641 toSci  0.0E+1           -> 0
+basx642 toSci  0.0E+2           -> 0E+1
+basx643 toSci  0.0E+3           -> 0E+2
+basx644 toSci  0.0E+4           -> 0E+3
+basx645 toSci  0.0E+5           -> 0E+4
+basx646 toSci  0.0E+6           -> 0E+5
+basx647 toSci  0.0E+7           -> 0E+6
+basx648 toSci  0.0E+8           -> 0E+7
+basx649 toSci  0.0E+9           -> 0E+8
+
+basx650 toSci  0E+0             -> 0
+basx651 toSci  0E+1             -> 0E+1
+basx652 toSci  0E+2             -> 0E+2
+basx653 toSci  0E+3             -> 0E+3
+basx654 toSci  0E+4             -> 0E+4
+basx655 toSci  0E+5             -> 0E+5
+basx656 toSci  0E+6             -> 0E+6
+basx657 toSci  0E+7             -> 0E+7
+basx658 toSci  0E+8             -> 0E+8
+basx659 toSci  0E+9             -> 0E+9
+
+basx660 toSci  0.0E-0           -> 0.0
+basx661 toSci  0.0E-1           -> 0.00
+basx662 toSci  0.0E-2           -> 0.000
+basx663 toSci  0.0E-3           -> 0.0000
+basx664 toSci  0.0E-4           -> 0.00000
+basx665 toSci  0.0E-5           -> 0.000000
+basx666 toSci  0.0E-6           -> 0E-7
+basx667 toSci  0.0E-7           -> 0E-8
+basx668 toSci  0.0E-8           -> 0E-9
+basx669 toSci  0.0E-9           -> 0E-10
+
+basx670 toSci  0.00E-0          -> 0.00
+basx671 toSci  0.00E-1          -> 0.000
+basx672 toSci  0.00E-2          -> 0.0000
+basx673 toSci  0.00E-3          -> 0.00000
+basx674 toSci  0.00E-4          -> 0.000000
+basx675 toSci  0.00E-5          -> 0E-7
+basx676 toSci  0.00E-6          -> 0E-8
+basx677 toSci  0.00E-7          -> 0E-9
+basx678 toSci  0.00E-8          -> 0E-10
+basx679 toSci  0.00E-9          -> 0E-11
+
+-- Specials
+precision: 4
+basx700 toSci "NaN"             -> NaN
+basx701 toSci "nan"             -> NaN
+basx702 toSci "nAn"             -> NaN
+basx703 toSci "NAN"             -> NaN
+basx704 toSci "+NaN"            -> NaN
+basx705 toSci "+nan"            -> NaN
+basx706 toSci "+nAn"            -> NaN
+basx707 toSci "+NAN"            -> NaN
+basx708 toSci "-NaN"            -> -NaN
+basx709 toSci "-nan"            -> -NaN
+basx710 toSci "-nAn"            -> -NaN
+basx711 toSci "-NAN"            -> -NaN
+basx712 toSci 'NaN0'            -> NaN
+basx713 toSci 'NaN1'            -> NaN1
+basx714 toSci 'NaN12'           -> NaN12
+basx715 toSci 'NaN123'          -> NaN123
+basx716 toSci 'NaN1234'         -> NaN1234
+basx717 toSci 'NaN01'           -> NaN1
+basx718 toSci 'NaN012'          -> NaN12
+basx719 toSci 'NaN0123'         -> NaN123
+basx720 toSci 'NaN01234'        -> NaN1234
+basx721 toSci 'NaN001'          -> NaN1
+basx722 toSci 'NaN0012'         -> NaN12
+basx723 toSci 'NaN00123'        -> NaN123
+basx724 toSci 'NaN001234'       -> NaN1234
+basx725 toSci 'NaN12345'        -> NaN Conversion_syntax
+basx726 toSci 'NaN123e+1'       -> NaN Conversion_syntax
+basx727 toSci 'NaN12.45'        -> NaN Conversion_syntax
+basx728 toSci 'NaN-12'          -> NaN Conversion_syntax
+basx729 toSci 'NaN+12'          -> NaN Conversion_syntax
+
+basx730 toSci "sNaN"            -> sNaN
+basx731 toSci "snan"            -> sNaN
+basx732 toSci "SnAn"            -> sNaN
+basx733 toSci "SNAN"            -> sNaN
+basx734 toSci "+sNaN"           -> sNaN
+basx735 toSci "+snan"           -> sNaN
+basx736 toSci "+SnAn"           -> sNaN
+basx737 toSci "+SNAN"           -> sNaN
+basx738 toSci "-sNaN"           -> -sNaN
+basx739 toSci "-snan"           -> -sNaN
+basx740 toSci "-SnAn"           -> -sNaN
+basx741 toSci "-SNAN"           -> -sNaN
+basx742 toSci 'sNaN0000'        -> sNaN
+basx743 toSci 'sNaN7'           -> sNaN7
+basx744 toSci 'sNaN007234'      -> sNaN7234
+basx745 toSci 'sNaN72345'       -> NaN Conversion_syntax
+basx746 toSci 'sNaN72.45'       -> NaN Conversion_syntax
+basx747 toSci 'sNaN-72'         -> NaN Conversion_syntax
+
+basx748 toSci "Inf"             -> Infinity
+basx749 toSci "inf"             -> Infinity
+basx750 toSci "iNf"             -> Infinity
+basx751 toSci "INF"             -> Infinity
+basx752 toSci "+Inf"            -> Infinity
+basx753 toSci "+inf"            -> Infinity
+basx754 toSci "+iNf"            -> Infinity
+basx755 toSci "+INF"            -> Infinity
+basx756 toSci "-Inf"            -> -Infinity
+basx757 toSci "-inf"            -> -Infinity
+basx758 toSci "-iNf"            -> -Infinity
+basx759 toSci "-INF"            -> -Infinity
+
+basx760 toSci "Infinity"        -> Infinity
+basx761 toSci "infinity"        -> Infinity
+basx762 toSci "iNfInItY"        -> Infinity
+basx763 toSci "INFINITY"        -> Infinity
+basx764 toSci "+Infinity"       -> Infinity
+basx765 toSci "+infinity"       -> Infinity
+basx766 toSci "+iNfInItY"       -> Infinity
+basx767 toSci "+INFINITY"       -> Infinity
+basx768 toSci "-Infinity"       -> -Infinity
+basx769 toSci "-infinity"       -> -Infinity
+basx770 toSci "-iNfInItY"       -> -Infinity
+basx771 toSci "-INFINITY"       -> -Infinity
+
+-- Specials and zeros for toEng
+basx772 toEng "NaN"              -> NaN
+basx773 toEng "-Infinity"        -> -Infinity
+basx774 toEng "-sNaN"            -> -sNaN
+basx775 toEng "-NaN"             -> -NaN
+basx776 toEng "+Infinity"        -> Infinity
+basx778 toEng "+sNaN"            -> sNaN
+basx779 toEng "+NaN"             -> NaN
+basx780 toEng "INFINITY"         -> Infinity
+basx781 toEng "SNAN"             -> sNaN
+basx782 toEng "NAN"              -> NaN
+basx783 toEng "infinity"         -> Infinity
+basx784 toEng "snan"             -> sNaN
+basx785 toEng "nan"              -> NaN
+basx786 toEng "InFINITY"         -> Infinity
+basx787 toEng "SnAN"             -> sNaN
+basx788 toEng "nAN"              -> NaN
+basx789 toEng "iNfinity"         -> Infinity
+basx790 toEng "sNan"             -> sNaN
+basx791 toEng "Nan"              -> NaN
+basx792 toEng "Infinity"         -> Infinity
+basx793 toEng "sNaN"             -> sNaN
+
+-- Zero toEng, etc.
+basx800 toEng 0e+1              -> "0.00E+3"  -- doc example
+
+basx801 toEng 0.000000000       -> 0E-9
+basx802 toEng 0.00000000        -> 0.00E-6
+basx803 toEng 0.0000000         -> 0.0E-6
+basx804 toEng 0.000000          -> 0.000000
+basx805 toEng 0.00000           -> 0.00000
+basx806 toEng 0.0000            -> 0.0000
+basx807 toEng 0.000             -> 0.000
+basx808 toEng 0.00              -> 0.00
+basx809 toEng 0.0               -> 0.0
+basx810 toEng  .0               -> 0.0
+basx811 toEng 0.                -> 0
+basx812 toEng -.0               -> -0.0
+basx813 toEng -0.               -> -0
+basx814 toEng -0.0              -> -0.0
+basx815 toEng -0.00             -> -0.00
+basx816 toEng -0.000            -> -0.000
+basx817 toEng -0.0000           -> -0.0000
+basx818 toEng -0.00000          -> -0.00000
+basx819 toEng -0.000000         -> -0.000000
+basx820 toEng -0.0000000        -> -0.0E-6
+basx821 toEng -0.00000000       -> -0.00E-6
+basx822 toEng -0.000000000      -> -0E-9
+
+basx830 toEng  0.00E+0          -> 0.00
+basx831 toEng  0.00E+1          -> 0.0
+basx832 toEng  0.00E+2          -> 0
+basx833 toEng  0.00E+3          -> 0.00E+3
+basx834 toEng  0.00E+4          -> 0.0E+3
+basx835 toEng  0.00E+5          -> 0E+3
+basx836 toEng  0.00E+6          -> 0.00E+6
+basx837 toEng  0.00E+7          -> 0.0E+6
+basx838 toEng  0.00E+8          -> 0E+6
+basx839 toEng  0.00E+9          -> 0.00E+9
+
+basx840 toEng  0.0E+0           -> 0.0
+basx841 toEng  0.0E+1           -> 0
+basx842 toEng  0.0E+2           -> 0.00E+3
+basx843 toEng  0.0E+3           -> 0.0E+3
+basx844 toEng  0.0E+4           -> 0E+3
+basx845 toEng  0.0E+5           -> 0.00E+6
+basx846 toEng  0.0E+6           -> 0.0E+6
+basx847 toEng  0.0E+7           -> 0E+6
+basx848 toEng  0.0E+8           -> 0.00E+9
+basx849 toEng  0.0E+9           -> 0.0E+9
+
+basx850 toEng  0E+0             -> 0
+basx851 toEng  0E+1             -> 0.00E+3
+basx852 toEng  0E+2             -> 0.0E+3
+basx853 toEng  0E+3             -> 0E+3
+basx854 toEng  0E+4             -> 0.00E+6
+basx855 toEng  0E+5             -> 0.0E+6
+basx856 toEng  0E+6             -> 0E+6
+basx857 toEng  0E+7             -> 0.00E+9
+basx858 toEng  0E+8             -> 0.0E+9
+basx859 toEng  0E+9             -> 0E+9
+
+basx860 toEng  0.0E-0           -> 0.0
+basx861 toEng  0.0E-1           -> 0.00
+basx862 toEng  0.0E-2           -> 0.000
+basx863 toEng  0.0E-3           -> 0.0000
+basx864 toEng  0.0E-4           -> 0.00000
+basx865 toEng  0.0E-5           -> 0.000000
+basx866 toEng  0.0E-6           -> 0.0E-6
+basx867 toEng  0.0E-7           -> 0.00E-6
+basx868 toEng  0.0E-8           -> 0E-9
+basx869 toEng  0.0E-9           -> 0.0E-9
+
+basx870 toEng  0.00E-0          -> 0.00
+basx871 toEng  0.00E-1          -> 0.000
+basx872 toEng  0.00E-2          -> 0.0000
+basx873 toEng  0.00E-3          -> 0.00000
+basx874 toEng  0.00E-4          -> 0.000000
+basx875 toEng  0.00E-5          -> 0.0E-6
+basx876 toEng  0.00E-6          -> 0.00E-6
+basx877 toEng  0.00E-7          -> 0E-9
+basx878 toEng  0.00E-8          -> 0.0E-9
+basx879 toEng  0.00E-9          -> 0.00E-9
+
+-- Giga exponent initial tests
+maxExponent: 999999999
+minExponent: -999999999
+
+basx951 toSci '99e999'          -> '9.9E+1000'
+basx952 toSci '999e999'         -> '9.99E+1001'
+basx953 toSci '0.9e-999'        -> '9E-1000'
+basx954 toSci '0.09e-999'       -> '9E-1001'
+basx955 toSci '0.1e1001'        -> '1E+1000'
+basx956 toSci '10e-1001'        -> '1.0E-1000'
+basx957 toSci '0.9e9999'        -> '9E+9998'
+basx958 toSci '99e-9999'        -> '9.9E-9998'
+basx959 toSci '111e9997'        -> '1.11E+9999'
+basx960 toSci '1111e-9999'      -> '1.111E-9996'
+basx961 toSci '99e9999'         -> '9.9E+10000'
+basx962 toSci '999e9999'        -> '9.99E+10001'
+basx963 toSci '0.9e-9999'       -> '9E-10000'
+basx964 toSci '0.09e-9999'      -> '9E-10001'
+basx965 toSci '0.1e10001'       -> '1E+10000'
+basx966 toSci '10e-10001'       -> '1.0E-10000'
+basx967 toSci '0.9e99999'       -> '9E+99998'
+basx968 toSci '99e-99999'       -> '9.9E-99998'
+basx969 toSci '111e99999'       -> '1.11E+100001'
+basx970 toSci '1111e-99999'     -> '1.111E-99996'
+basx971 toSci "0.09e999999999"  -> '9E+999999997'
+basx972 toSci "0.9e999999999"   -> '9E+999999998'
+basx973 toSci "9e999999999"     -> '9E+999999999'
+basx974 toSci "9.9e999999999"   -> '9.9E+999999999'
+basx975 toSci "9.99e999999999"  -> '9.99E+999999999'
+basx976 toSci "9.99e-999999999" -> '9.99E-999999999'
+basx977 toSci "9.9e-999999999"  -> '9.9E-999999999'
+basx978 toSci "9e-999999999"    -> '9E-999999999'
+basx979 toSci "99e-999999999"   -> '9.9E-999999998'
+basx980 toSci "999e-999999999"  -> '9.99E-999999997'
+
+-- Varying exponent maximums
+precision: 5
+maxexponent: 0
+minexponent: 0
+emax001 toSci -1E+2  -> -Infinity Overflow Inexact Rounded
+emax002 toSci -100   -> -Infinity Overflow Inexact Rounded
+emax003 toSci  -10   -> -Infinity Overflow Inexact Rounded
+emax004 toSci   -9.9 -> -9.9
+emax005 toSci   -9   -> -9
+emax006 toSci   -1   -> -1
+emax007 toSci    0   ->  0
+emax008 toSci    1   ->  1
+emax009 toSci    9   ->  9
+emax010 toSci    9.9 ->  9.9
+emax011 toSci   10   ->  Infinity Overflow Inexact Rounded
+emax012 toSci  100   ->  Infinity Overflow Inexact Rounded
+emax013 toSci  1E+2  ->  Infinity Overflow Inexact Rounded
+emax014 toSci   0.99 ->  0.99 Subnormal
+emax015 toSci   0.1  ->  0.1 Subnormal
+emax016 toSci   0.01 ->  0.01 Subnormal
+emax017 toSci  1E-1  ->  0.1 Subnormal
+emax018 toSci  1E-2  ->  0.01 Subnormal
+
+maxexponent: 1
+minexponent: -1
+emax100 toSci -1E+3  -> -Infinity Overflow Inexact Rounded
+emax101 toSci -1E+2  -> -Infinity Overflow Inexact Rounded
+emax102 toSci -100   -> -Infinity Overflow Inexact Rounded
+emax103 toSci  -10   -> -10
+emax104 toSci   -9.9 -> -9.9
+emax105 toSci   -9   -> -9
+emax106 toSci   -1   -> -1
+emax107 toSci    0   ->  0
+emax108 toSci    1   ->  1
+emax109 toSci    9   ->  9
+emax110 toSci    9.9 ->  9.9
+emax111 toSci   10   -> 10
+emax112 toSci  100   ->  Infinity Overflow Inexact Rounded
+emax113 toSci  1E+2  ->  Infinity Overflow Inexact Rounded
+emax114 toSci  1E+3  ->  Infinity Overflow Inexact Rounded
+emax115 toSci   0.99 ->  0.99
+emax116 toSci   0.1  ->  0.1
+emax117 toSci   0.01 ->  0.01 Subnormal
+emax118 toSci  1E-1  ->  0.1
+emax119 toSci  1E-2  ->  0.01 Subnormal
+emax120 toSci  1E-3  ->  0.001 Subnormal
+emax121 toSci  1.1E-3  ->  0.0011 Subnormal
+emax122 toSci  1.11E-3  ->  0.00111 Subnormal
+emax123 toSci  1.111E-3  ->  0.00111 Subnormal Underflow Inexact Rounded
+emax124 toSci  1.1111E-3  ->  0.00111 Subnormal Underflow Inexact Rounded
+emax125 toSci  1.11111E-3  ->  0.00111 Subnormal Underflow Inexact Rounded
+
+maxexponent: 2
+minexponent: -2
+precision: 9
+emax200 toSci -1E+3  -> -Infinity Overflow Inexact Rounded
+emax201 toSci -1E+2  -> -1E+2
+emax202 toSci -100   -> -100
+emax203 toSci  -10   -> -10
+emax204 toSci   -9.9 -> -9.9
+emax205 toSci   -9   -> -9
+emax206 toSci   -1   -> -1
+emax207 toSci    0   ->  0
+emax208 toSci    1   ->  1
+emax209 toSci    9   ->  9
+emax210 toSci    9.9 ->  9.9
+emax211 toSci   10   -> 10
+emax212 toSci  100   -> 100
+emax213 toSci  1E+2  -> 1E+2
+emax214 toSci  1E+3  ->  Infinity Overflow Inexact Rounded
+emax215 toSci   0.99 ->  0.99
+emax216 toSci   0.1  ->  0.1
+emax217 toSci   0.01 ->  0.01
+emax218 toSci  0.001 ->  0.001 Subnormal
+emax219 toSci  1E-1  ->  0.1
+emax220 toSci  1E-2  ->  0.01
+emax221 toSci  1E-3  ->  0.001 Subnormal
+emax222 toSci  1E-4  ->  0.0001 Subnormal
+emax223 toSci  1E-5  ->  0.00001 Subnormal
+emax224 toSci  1E-6  ->  0.000001 Subnormal
+emax225 toSci  1E-7  ->  1E-7  Subnormal
+emax226 toSci  1E-8  ->  1E-8  Subnormal
+emax227 toSci  1E-9  ->  1E-9  Subnormal
+emax228 toSci  1E-10 ->  1E-10 Subnormal
+emax229 toSci  1E-11 ->  0E-10 Underflow Subnormal Inexact Rounded
+emax230 toSci  1E-12 ->  0E-10 Underflow Subnormal Inexact Rounded
+
+maxexponent: 7
+minexponent: -7
+emax231 toSci  1E-8  ->  1E-8 Subnormal
+emax232 toSci  1E-7  ->  1E-7
+emax233 toSci  1E-6  ->  0.000001
+emax234 toSci  1E-5  ->  0.00001
+emax235 toSci  1E+5  ->  1E+5
+emax236 toSci  1E+6  ->  1E+6
+emax237 toSci  1E+7  ->  1E+7
+emax238 toSci  1E+8  ->  Infinity Overflow Inexact Rounded
+
+maxexponent: 9
+minexponent: -9
+emax240 toSci  1E-21 ->  0E-17 Subnormal Underflow Inexact Rounded
+emax241 toSci  1E-10 ->  1E-10 Subnormal
+emax242 toSci  1E-9  ->  1E-9
+emax243 toSci  1E-8  ->  1E-8
+emax244 toSci  1E-7  ->  1E-7
+emax245 toSci  1E+7  ->  1E+7
+emax246 toSci  1E+8  ->  1E+8
+emax247 toSci  1E+9  ->  1E+9
+emax248 toSci  1E+10 ->  Infinity Overflow Inexact Rounded
+
+maxexponent: 10  -- boundary
+minexponent: -10
+emax250 toSci  1E-21 ->  0E-18 Underflow Subnormal Inexact Rounded
+emax251 toSci  1E-11 ->  1E-11 Subnormal
+emax252 toSci  1E-10 ->  1E-10
+emax253 toSci  1E-9  ->  1E-9
+emax254 toSci  1E-8  ->  1E-8
+emax255 toSci  1E+8  ->  1E+8
+emax256 toSci  1E+9  ->  1E+9
+emax257 toSci  1E+10 ->  1E+10
+emax258 toSci  1E+11 ->  Infinity Overflow Inexact Rounded
+
+emax260 toSci  1.00E-21 ->  0E-18 Underflow Subnormal Inexact Rounded
+emax261 toSci  1.00E-11 ->  1.00E-11 Subnormal
+emax262 toSci  1.00E-10 ->  1.00E-10
+emax263 toSci  1.00E-9  ->  1.00E-9
+emax264 toSci  1.00E-8  ->  1.00E-8
+emax265 toSci  1.00E+8  ->  1.00E+8
+emax266 toSci  1.00E+9  ->  1.00E+9
+emax267 toSci  1.00E+10 ->  1.00E+10
+emax268 toSci  1.00E+11 ->  Infinity Overflow Inexact Rounded
+emax270 toSci  9.99E-21 ->  0E-18 Underflow Subnormal Inexact Rounded
+emax271 toSci  9.99E-11 ->  9.99E-11 Subnormal
+emax272 toSci  9.99E-10 ->  9.99E-10
+emax273 toSci  9.99E-9  ->  9.99E-9
+emax274 toSci  9.99E-8  ->  9.99E-8
+emax275 toSci  9.99E+8  ->  9.99E+8
+emax276 toSci  9.99E+9  ->  9.99E+9
+emax277 toSci  9.99E+10 ->  9.99E+10
+emax278 toSci  9.99E+11 ->  Infinity Overflow Inexact Rounded
+
+maxexponent: 99
+minexponent: -99
+emax280 toSci  1E-120 ->  0E-107 Underflow Subnormal Inexact Rounded
+emax281 toSci  1E-100 ->  1E-100 Subnormal
+emax282 toSci  1E-99  ->  1E-99
+emax283 toSci  1E-98  ->  1E-98
+emax284 toSci  1E+98  ->  1E+98
+emax285 toSci  1E+99  ->  1E+99
+emax286 toSci  1E+100 ->  Infinity Overflow Inexact Rounded
+
+maxexponent: 999
+minexponent: -999
+emax291 toSci  1E-1000 ->  1E-1000 Subnormal
+emax292 toSci  1E-999  ->  1E-999
+emax293 toSci  1E+999  ->  1E+999
+emax294 toSci  1E+1000 ->  Infinity Overflow Inexact Rounded
+maxexponent: 9999
+minexponent: -9999
+emax301 toSci  1E-10000 ->  1E-10000 Subnormal
+emax302 toSci  1E-9999  ->  1E-9999
+emax303 toSci  1E+9999  ->  1E+9999
+emax304 toSci  1E+10000 ->  Infinity Overflow Inexact Rounded
+maxexponent: 99999
+minexponent: -99999
+emax311 toSci  1E-100000 ->  1E-100000 Subnormal
+emax312 toSci  1E-99999  ->  1E-99999
+emax313 toSci  1E+99999  ->  1E+99999
+emax314 toSci  1E+100000 ->  Infinity Overflow Inexact Rounded
+maxexponent: 999999
+minexponent: -999999
+emax321 toSci  1E-1000000 ->  1E-1000000 Subnormal
+emax322 toSci  1E-999999  ->  1E-999999
+emax323 toSci  1E+999999  ->  1E+999999
+emax324 toSci  1E+1000000 ->  Infinity Overflow Inexact Rounded
+maxexponent: 9999999
+minexponent: -9999999
+emax331 toSci  1E-10000000 ->  1E-10000000 Subnormal
+emax332 toSci  1E-9999999  ->  1E-9999999
+emax333 toSci  1E+9999999  ->  1E+9999999
+emax334 toSci  1E+10000000 ->  Infinity Overflow Inexact Rounded
+maxexponent: 99999999
+minexponent: -99999999
+emax341 toSci  1E-100000000 ->  1E-100000000 Subnormal
+emax342 toSci  1E-99999999  ->  1E-99999999
+emax343 toSci  1E+99999999  ->  1E+99999999
+emax344 toSci  1E+100000000 ->  Infinity Overflow Inexact Rounded
+
+maxexponent: 999999999
+minexponent: -999999999
+emax347 toSci  1E-1000000008     ->  0E-1000000007 Underflow Subnormal Inexact Rounded
+emax348 toSci  1E-1000000007     ->  1E-1000000007 Subnormal
+emax349 toSci  1E-1000000000     ->  1E-1000000000 Subnormal
+emax350 toSci  1E-999999999      ->  1E-999999999
+emax351 toSci  1E+999999999      ->  1E+999999999
+emax352 toSci  1E+1000000000     ->  Infinity Overflow Inexact Rounded
+emax353 toSci  1.000E-1000000000 ->  1.000E-1000000000 Subnormal
+emax354 toSci  1.000E-999999999  ->  1.000E-999999999
+emax355 toSci  1.000E+999999999  ->  1.000E+999999999
+emax356 toSci  1.000E+1000000000 ->  Infinity Overflow Inexact Rounded
+emax357 toSci  1.001E-1000000008 ->  0E-1000000007 Underflow Subnormal Inexact Rounded
+emax358 toSci  1.001E-1000000007 ->  1E-1000000007 Subnormal Inexact Rounded Underflow
+emax359 toSci  1.001E-1000000000 ->  1.001E-1000000000 Subnormal
+emax360 toSci  1.001E-999999999  ->  1.001E-999999999
+emax361 toSci  1.001E+999999999  ->  1.001E+999999999
+emax362 toSci  1.001E+1000000000 ->  Infinity Overflow Inexact Rounded
+emax363 toSci  9.000E-1000000000 ->  9.000E-1000000000 Subnormal
+emax364 toSci  9.000E-999999999  ->  9.000E-999999999
+emax365 toSci  9.000E+999999999  ->  9.000E+999999999
+emax366 toSci  9.000E+1000000000 ->  Infinity Overflow Inexact Rounded
+emax367 toSci  9.999E-1000000009 ->  0E-1000000007 Underflow Subnormal Inexact Rounded
+emax368 toSci  9.999E-1000000008 ->  1E-1000000007 Underflow Subnormal Inexact Rounded
+emax369 toSci  9.999E-1000000007 ->  1.0E-1000000006 Underflow Subnormal Inexact Rounded
+emax370 toSci  9.999E-1000000000 ->  9.999E-1000000000 Subnormal
+emax371 toSci  9.999E-999999999  ->  9.999E-999999999
+emax372 toSci  9.999E+999999999  ->  9.999E+999999999
+
+emax373 toSci  9.999E+1000000000 ->  Infinity Overflow Inexact Rounded
+emax374 toSci -1E-1000000000     -> -1E-1000000000 Subnormal
+emax375 toSci -1E-999999999      -> -1E-999999999
+emax376 toSci -1E+999999999      -> -1E+999999999
+emax377 toSci -1E+1000000000     -> -Infinity Overflow Inexact Rounded
+emax378 toSci -1.000E-1000000000 -> -1.000E-1000000000 Subnormal
+emax379 toSci -1.000E-999999999  -> -1.000E-999999999
+emax380 toSci -1.000E+999999999  -> -1.000E+999999999
+emax381 toSci -1.000E+1000000000 -> -Infinity Overflow Inexact Rounded
+emax382 toSci -1.001E-1000000008 -> -0E-1000000007 Underflow Subnormal Inexact Rounded
+emax383 toSci -1.001E-999999999  -> -1.001E-999999999
+emax384 toSci -1.001E+999999999  -> -1.001E+999999999
+emax385 toSci -1.001E+1000000000 -> -Infinity Overflow Inexact Rounded
+emax386 toSci -9.000E-1000000123 -> -0E-1000000007 Underflow Subnormal Inexact Rounded
+emax387 toSci -9.000E-999999999  -> -9.000E-999999999
+emax388 toSci -9.000E+999999999  -> -9.000E+999999999
+emax389 toSci -9.000E+1000000000 -> -Infinity Overflow Inexact Rounded
+emax390 toSci -9.999E-1000000008 -> -1E-1000000007 Underflow Subnormal Inexact Rounded
+emax391 toSci -9.999E-999999999  -> -9.999E-999999999
+emax392 toSci -9.999E+999999999  -> -9.999E+999999999
+emax393 toSci -9.999E+1000000000 -> -Infinity Overflow Inexact Rounded
+
+-- Now check 854 rounding of subnormals and proper underflow to 0
+precision:   5
+maxExponent: 999
+minexponent: -999
+rounding:    half_even
+
+emax400 toSci  1.0000E-999     -> 1.0000E-999
+emax401 toSci  0.1E-999        -> 1E-1000     Subnormal
+emax402 toSci  0.1000E-999     -> 1.000E-1000 Subnormal
+emax403 toSci  0.0100E-999     -> 1.00E-1001  Subnormal
+emax404 toSci  0.0010E-999     -> 1.0E-1002   Subnormal
+emax405 toSci  0.0001E-999     -> 1E-1003     Subnormal
+emax406 toSci  0.00010E-999    -> 1E-1003     Subnormal Rounded
+emax407 toSci  0.00013E-999    -> 1E-1003     Underflow Subnormal Inexact Rounded
+emax408 toSci  0.00015E-999    -> 2E-1003     Underflow Subnormal Inexact Rounded
+emax409 toSci  0.00017E-999    -> 2E-1003     Underflow Subnormal Inexact Rounded
+emax410 toSci  0.00023E-999    -> 2E-1003     Underflow Subnormal Inexact Rounded
+emax411 toSci  0.00025E-999    -> 2E-1003     Underflow Subnormal Inexact Rounded
+emax412 toSci  0.00027E-999    -> 3E-1003     Underflow Subnormal Inexact Rounded
+emax413 toSci  0.000149E-999   -> 1E-1003     Underflow Subnormal Inexact Rounded
+emax414 toSci  0.000150E-999   -> 2E-1003     Underflow Subnormal Inexact Rounded
+emax415 toSci  0.000151E-999   -> 2E-1003     Underflow Subnormal Inexact Rounded
+emax416 toSci  0.000249E-999   -> 2E-1003     Underflow Subnormal Inexact Rounded
+emax417 toSci  0.000250E-999   -> 2E-1003     Underflow Subnormal Inexact Rounded
+emax418 toSci  0.000251E-999   -> 3E-1003     Underflow Subnormal Inexact Rounded
+emax419 toSci  0.00009E-999    -> 1E-1003     Underflow Subnormal Inexact Rounded
+emax420 toSci  0.00005E-999    -> 0E-1003     Underflow Subnormal Inexact Rounded
+emax421 toSci  0.00003E-999    -> 0E-1003     Underflow Subnormal Inexact Rounded
+emax422 toSci  0.000009E-999   -> 0E-1003     Underflow Subnormal Inexact Rounded
+emax423 toSci  0.000005E-999   -> 0E-1003     Underflow Subnormal Inexact Rounded
+emax424 toSci  0.000003E-999   -> 0E-1003     Underflow Subnormal Inexact Rounded
+
+emax425 toSci  0.001049E-999   -> 1.0E-1002   Underflow Subnormal Inexact Rounded
+emax426 toSci  0.001050E-999   -> 1.0E-1002   Underflow Subnormal Inexact Rounded
+emax427 toSci  0.001051E-999   -> 1.1E-1002   Underflow Subnormal Inexact Rounded
+emax428 toSci  0.001149E-999   -> 1.1E-1002   Underflow Subnormal Inexact Rounded
+emax429 toSci  0.001150E-999   -> 1.2E-1002   Underflow Subnormal Inexact Rounded
+emax430 toSci  0.001151E-999   -> 1.2E-1002   Underflow Subnormal Inexact Rounded
+
+emax432 toSci  0.010049E-999   -> 1.00E-1001  Underflow Subnormal Inexact Rounded
+emax433 toSci  0.010050E-999   -> 1.00E-1001  Underflow Subnormal Inexact Rounded
+emax434 toSci  0.010051E-999   -> 1.01E-1001  Underflow Subnormal Inexact Rounded
+emax435 toSci  0.010149E-999   -> 1.01E-1001  Underflow Subnormal Inexact Rounded
+emax436 toSci  0.010150E-999   -> 1.02E-1001  Underflow Subnormal Inexact Rounded
+emax437 toSci  0.010151E-999   -> 1.02E-1001  Underflow Subnormal Inexact Rounded
+
+emax440 toSci  0.10103E-999    -> 1.010E-1000 Underflow Subnormal Inexact Rounded
+emax441 toSci  0.10105E-999    -> 1.010E-1000 Underflow Subnormal Inexact Rounded
+emax442 toSci  0.10107E-999    -> 1.011E-1000 Underflow Subnormal Inexact Rounded
+emax443 toSci  0.10113E-999    -> 1.011E-1000 Underflow Subnormal Inexact Rounded
+emax444 toSci  0.10115E-999    -> 1.012E-1000 Underflow Subnormal Inexact Rounded
+emax445 toSci  0.10117E-999    -> 1.012E-1000 Underflow Subnormal Inexact Rounded
+
+emax450 toSci  1.10730E-1000   -> 1.107E-1000 Underflow Subnormal Inexact Rounded
+emax451 toSci  1.10750E-1000   -> 1.108E-1000 Underflow Subnormal Inexact Rounded
+emax452 toSci  1.10770E-1000   -> 1.108E-1000 Underflow Subnormal Inexact Rounded
+emax453 toSci  1.10830E-1000   -> 1.108E-1000 Underflow Subnormal Inexact Rounded
+emax454 toSci  1.10850E-1000   -> 1.108E-1000 Underflow Subnormal Inexact Rounded
+emax455 toSci  1.10870E-1000   -> 1.109E-1000 Underflow Subnormal Inexact Rounded
+
+-- make sure sign OK
+emax456 toSci  -0.10103E-999   -> -1.010E-1000 Underflow Subnormal Inexact Rounded
+emax457 toSci  -0.10105E-999   -> -1.010E-1000 Underflow Subnormal Inexact Rounded
+emax458 toSci  -0.10107E-999   -> -1.011E-1000 Underflow Subnormal Inexact Rounded
+emax459 toSci  -0.10113E-999   -> -1.011E-1000 Underflow Subnormal Inexact Rounded
+emax460 toSci  -0.10115E-999   -> -1.012E-1000 Underflow Subnormal Inexact Rounded
+emax461 toSci  -0.10117E-999   -> -1.012E-1000 Underflow Subnormal Inexact Rounded
+
+-- '999s' cases
+emax464 toSci  999999E-999         -> 1.0000E-993 Inexact Rounded
+emax465 toSci  99999.0E-999        -> 9.9999E-995 Rounded
+emax466 toSci  99999.E-999         -> 9.9999E-995
+emax467 toSci  9999.9E-999         -> 9.9999E-996
+emax468 toSci  999.99E-999         -> 9.9999E-997
+emax469 toSci  99.999E-999         -> 9.9999E-998
+emax470 toSci  9.9999E-999         -> 9.9999E-999
+emax471 toSci  0.99999E-999        -> 1.0000E-999 Underflow Subnormal Inexact Rounded
+emax472 toSci  0.099999E-999       -> 1.000E-1000 Underflow Subnormal Inexact Rounded
+emax473 toSci  0.0099999E-999      -> 1.00E-1001  Underflow Subnormal Inexact Rounded
+emax474 toSci  0.00099999E-999     -> 1.0E-1002   Underflow Subnormal Inexact Rounded
+emax475 toSci  0.000099999E-999    -> 1E-1003     Underflow Subnormal Inexact Rounded
+emax476 toSci  0.0000099999E-999   -> 0E-1003     Underflow Subnormal Inexact Rounded
+emax477 toSci  0.00000099999E-999  -> 0E-1003     Underflow Subnormal Inexact Rounded
+emax478 toSci  0.000000099999E-999 -> 0E-1003     Underflow Subnormal Inexact Rounded
+
+-- Exponents with insignificant leading zeros
+precision:   16
+maxExponent: 999999999
+minexponent: -999999999
+basx1001 toSci  1e999999999 -> 1E+999999999
+basx1002 toSci  1e0999999999 -> 1E+999999999
+basx1003 toSci  1e00999999999 -> 1E+999999999
+basx1004 toSci  1e000999999999 -> 1E+999999999
+basx1005 toSci  1e000000000000999999999 -> 1E+999999999
+basx1006 toSci  1e000000000001000000007 -> Infinity Overflow Inexact Rounded
+basx1007 toSci  1e-999999999 -> 1E-999999999
+basx1008 toSci  1e-0999999999 -> 1E-999999999
+basx1009 toSci  1e-00999999999 -> 1E-999999999
+basx1010 toSci  1e-000999999999 -> 1E-999999999
+basx1011 toSci  1e-000000000000999999999 -> 1E-999999999
+basx1012 toSci  1e-000000000001000000007 -> 1E-1000000007 Subnormal
+
+-- Edge cases for int32 exponents...
+basx1021 tosci 1e+2147483649 -> Infinity Overflow Inexact Rounded
+basx1022 tosci 1e+2147483648 -> Infinity Overflow Inexact Rounded
+basx1023 tosci 1e+2147483647 -> Infinity Overflow Inexact Rounded
+basx1024 tosci 1e-2147483647 -> 0E-1000000014 Underflow Subnormal Inexact Rounded
+basx1025 tosci 1e-2147483648 -> 0E-1000000014 Underflow Subnormal Inexact Rounded
+basx1026 tosci 1e-2147483649 -> 0E-1000000014 Underflow Subnormal Inexact Rounded
+-- same unbalanced
+precision:   7
+maxExponent: 96
+minexponent: -95
+basx1031 tosci 1e+2147483649 -> Infinity Overflow Inexact Rounded
+basx1032 tosci 1e+2147483648 -> Infinity Overflow Inexact Rounded
+basx1033 tosci 1e+2147483647 -> Infinity Overflow Inexact Rounded
+basx1034 tosci 1e-2147483647 -> 0E-101 Underflow Subnormal Inexact Rounded
+basx1035 tosci 1e-2147483648 -> 0E-101 Underflow Subnormal Inexact Rounded
+basx1036 tosci 1e-2147483649 -> 0E-101 Underflow Subnormal Inexact Rounded
+
+-- check for double-rounded subnormals
+precision:   5
+maxexponent: 79
+minexponent: -79
+basx1041 toSci     1.52444E-80  ->  1.524E-80 Inexact Rounded Subnormal Underflow
+basx1042 toSci     1.52445E-80  ->  1.524E-80 Inexact Rounded Subnormal Underflow
+basx1043 toSci     1.52446E-80  ->  1.524E-80 Inexact Rounded Subnormal Underflow
+

Added: vendor/Python/current/Lib/test/decimaltestdata/clamp.decTest
===================================================================
--- vendor/Python/current/Lib/test/decimaltestdata/clamp.decTest	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/decimaltestdata/clamp.decTest	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,197 @@
+------------------------------------------------------------------------
+-- clamp.decTest -- clamped exponent tests (format-independent)       --
+-- Copyright (c) IBM Corporation, 2000, 2003.  All rights reserved.   --
+------------------------------------------------------------------------
+-- Please see the document "General Decimal Arithmetic Testcases"     --
+-- at http://www2.hursley.ibm.com/decimal for the description of      --
+-- these testcases.                                                   --
+--                                                                    --
+-- These testcases are experimental ('beta' versions), and they       --
+-- may contain errors.  They are offered on an as-is basis.  In       --
+-- particular, achieving the same results as the tests here is not    --
+-- a guarantee that an implementation complies with any Standard      --
+-- or specification.  The tests are not exhaustive.                   --
+--                                                                    --
+-- Please send comments, suggestions, and corrections to the author:  --
+--   Mike Cowlishaw, IBM Fellow                                       --
+--   IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK         --
+--   mfc at uk.ibm.com                                                   --
+------------------------------------------------------------------------
+version: 2.39
+
+-- This set of tests uses the same limits as the 8-byte concrete
+-- representation, but applies clamping without using format-specific
+-- conversions.
+
+extended:    1
+precision:   16
+rounding:    half_even
+maxExponent: 384
+minExponent: -383
+clamp:       1
+
+-- General testcases
+
+-- Normality
+clam010 apply   1234567890123456   ->  1234567890123456
+clam011 apply   1234567890123456.0 ->  1234567890123456 Rounded
+clam012 apply   1234567890123456.1 ->  1234567890123456 Rounded Inexact
+clam013 apply  -1234567890123456   -> -1234567890123456
+clam014 apply  -1234567890123456.0 -> -1234567890123456 Rounded
+clam015 apply  -1234567890123456.1 -> -1234567890123456 Rounded Inexact
+
+
+-- Nmax and similar
+clam022 apply   9.999999999999999E+384  -> 9.999999999999999E+384
+clam024 apply   1.234567890123456E+384  -> 1.234567890123456E+384
+-- fold-downs (more below)
+clam030 apply   1.23E+384               -> 1.230000000000000E+384 Clamped
+clam032 apply   1E+384                  -> 1.000000000000000E+384 Clamped
+
+clam051 apply   12345                   -> 12345
+clam053 apply   1234                    -> 1234
+clam055 apply   123                     -> 123
+clam057 apply   12                      -> 12
+clam059 apply   1                       -> 1
+clam061 apply   1.23                    -> 1.23
+clam063 apply   123.45                  -> 123.45
+
+-- Nmin and below
+clam071 apply   1E-383                  -> 1E-383
+clam073 apply   1.000000000000000E-383  -> 1.000000000000000E-383
+clam075 apply   1.000000000000001E-383  -> 1.000000000000001E-383
+
+clam077 apply   0.100000000000000E-383  -> 1.00000000000000E-384  Subnormal
+clam079 apply   0.000000000000010E-383  -> 1.0E-397               Subnormal
+clam081 apply   0.00000000000001E-383   -> 1E-397                 Subnormal
+clam083 apply   0.000000000000001E-383  -> 1E-398                 Subnormal
+
+-- underflows
+clam090 apply   1e-398                  -> #0000000000000001  Subnormal
+clam091 apply   1.9e-398                -> #0000000000000002  Subnormal Underflow Inexact Rounded
+clam092 apply   1.1e-398                -> #0000000000000001  Subnormal Underflow Inexact Rounded
+clam093 apply   1.00000000001e-398      -> #0000000000000001  Subnormal Underflow Inexact Rounded
+clam094 apply   1.00000000000001e-398   -> #0000000000000001  Subnormal Underflow Inexact Rounded
+clam095 apply   1.000000000000001e-398  -> #0000000000000001  Subnormal Underflow Inexact Rounded
+clam096 apply   0.1e-398                -> #0000000000000000  Subnormal Underflow Inexact Rounded
+clam097 apply   0.00000000001e-398      -> #0000000000000000  Subnormal Underflow Inexact Rounded
+clam098 apply   0.00000000000001e-398   -> #0000000000000000  Subnormal Underflow Inexact Rounded
+clam099 apply   0.000000000000001e-398  -> #0000000000000000  Subnormal Underflow Inexact Rounded
+
+-- Same again, negatives
+-- Nmax and similar
+clam122 apply  -9.999999999999999E+384  -> -9.999999999999999E+384
+clam124 apply  -1.234567890123456E+384  -> -1.234567890123456E+384
+-- fold-downs (more below)
+clam130 apply  -1.23E+384               -> -1.230000000000000E+384 Clamped
+clam132 apply  -1E+384                  -> -1.000000000000000E+384 Clamped
+
+clam151 apply  -12345                   -> -12345
+clam153 apply  -1234                    -> -1234
+clam155 apply  -123                     -> -123
+clam157 apply  -12                      -> -12
+clam159 apply  -1                       -> -1
+clam161 apply  -1.23                    -> -1.23
+clam163 apply  -123.45                  -> -123.45
+
+-- Nmin and below
+clam171 apply  -1E-383                  -> -1E-383
+clam173 apply  -1.000000000000000E-383  -> -1.000000000000000E-383
+clam175 apply  -1.000000000000001E-383  -> -1.000000000000001E-383
+
+clam177 apply  -0.100000000000000E-383  -> -1.00000000000000E-384  Subnormal
+clam179 apply  -0.000000000000010E-383  -> -1.0E-397               Subnormal
+clam181 apply  -0.00000000000001E-383   -> -1E-397                 Subnormal
+clam183 apply  -0.000000000000001E-383  -> -1E-398                 Subnormal
+
+-- underflows
+clam189 apply   -1e-398                 -> #8000000000000001  Subnormal
+clam190 apply   -1.0e-398               -> #8000000000000001  Subnormal Rounded
+clam191 apply   -1.9e-398               -> #8000000000000002  Subnormal Underflow Inexact Rounded
+clam192 apply   -1.1e-398               -> #8000000000000001  Subnormal Underflow Inexact Rounded
+clam193 apply   -1.00000000001e-398     -> #8000000000000001  Subnormal Underflow Inexact Rounded
+clam194 apply   -1.00000000000001e-398  -> #8000000000000001  Subnormal Underflow Inexact Rounded
+clam195 apply   -1.000000000000001e-398 -> #8000000000000001  Subnormal Underflow Inexact Rounded
+clam196 apply   -0.1e-398               -> #8000000000000000  Subnormal Underflow Inexact Rounded
+clam197 apply   -0.00000000001e-398     -> #8000000000000000  Subnormal Underflow Inexact Rounded
+clam198 apply   -0.00000000000001e-398  -> #8000000000000000  Subnormal Underflow Inexact Rounded
+clam199 apply   -0.000000000000001e-398 -> #8000000000000000  Subnormal Underflow Inexact Rounded
+
+-- zeros
+clam401 apply   0E-500                  -> 0E-398  Clamped
+clam402 apply   0E-400                  -> 0E-398  Clamped
+clam403 apply   0E-398                  -> 0E-398
+clam404 apply   0.000000000000000E-383  -> 0E-398
+clam405 apply   0E-2                    ->  0.00
+clam406 apply   0                       -> 0
+clam407 apply   0E+3                    -> 0E+3
+clam408 apply   0E+369                  -> 0E+369
+-- clamped zeros...
+clam410 apply   0E+370                  -> 0E+369 Clamped
+clam411 apply   0E+384                  -> 0E+369 Clamped
+clam412 apply   0E+400                  -> 0E+369 Clamped
+clam413 apply   0E+500                  -> 0E+369 Clamped
+
+-- negative zeros
+clam420 apply   -0E-500                 -> -0E-398 Clamped
+clam421 apply   -0E-400                 -> -0E-398 Clamped
+clam422 apply   -0E-398                 -> -0E-398
+clam423 apply   -0.000000000000000E-383 -> -0E-398
+clam424 apply   -0E-2                   -> -0.00
+clam425 apply   -0                      -> -0
+clam426 apply   -0E+3                   -> -0E+3
+clam427 apply   -0E+369                 -> -0E+369
+-- clamped zeros...
+clam431 apply   -0E+370                 -> -0E+369 Clamped
+clam432 apply   -0E+384                 -> -0E+369 Clamped
+clam433 apply   -0E+400                 -> -0E+369 Clamped
+clam434 apply   -0E+500                 -> -0E+369 Clamped
+
+-- fold-down full sequence
+clam601 apply   1E+384                  -> 1.000000000000000E+384 Clamped
+clam603 apply   1E+383                  -> 1.00000000000000E+383 Clamped
+clam605 apply   1E+382                  -> 1.0000000000000E+382 Clamped
+clam607 apply   1E+381                  -> 1.000000000000E+381 Clamped
+clam609 apply   1E+380                  -> 1.00000000000E+380 Clamped
+clam611 apply   1E+379                  -> 1.0000000000E+379 Clamped
+clam613 apply   1E+378                  -> 1.000000000E+378 Clamped
+clam615 apply   1E+377                  -> 1.00000000E+377 Clamped
+clam617 apply   1E+376                  -> 1.0000000E+376 Clamped
+clam619 apply   1E+375                  -> 1.000000E+375 Clamped
+clam621 apply   1E+374                  -> 1.00000E+374 Clamped
+clam623 apply   1E+373                  -> 1.0000E+373 Clamped
+clam625 apply   1E+372                  -> 1.000E+372 Clamped
+clam627 apply   1E+371                  -> 1.00E+371 Clamped
+clam629 apply   1E+370                  -> 1.0E+370 Clamped
+clam631 apply   1E+369                  -> 1E+369
+clam633 apply   1E+368                  -> 1E+368
+-- same with 9s
+clam641 apply   9E+384                  -> 9.000000000000000E+384 Clamped
+clam643 apply   9E+383                  -> 9.00000000000000E+383 Clamped
+clam645 apply   9E+382                  -> 9.0000000000000E+382 Clamped
+clam647 apply   9E+381                  -> 9.000000000000E+381 Clamped
+clam649 apply   9E+380                  -> 9.00000000000E+380 Clamped
+clam651 apply   9E+379                  -> 9.0000000000E+379 Clamped
+clam653 apply   9E+378                  -> 9.000000000E+378 Clamped
+clam655 apply   9E+377                  -> 9.00000000E+377 Clamped
+clam657 apply   9E+376                  -> 9.0000000E+376 Clamped
+clam659 apply   9E+375                  -> 9.000000E+375 Clamped
+clam661 apply   9E+374                  -> 9.00000E+374 Clamped
+clam663 apply   9E+373                  -> 9.0000E+373 Clamped
+clam665 apply   9E+372                  -> 9.000E+372 Clamped
+clam667 apply   9E+371                  -> 9.00E+371 Clamped
+clam669 apply   9E+370                  -> 9.0E+370 Clamped
+clam671 apply   9E+369                  -> 9E+369
+clam673 apply   9E+368                  -> 9E+368
+
+-- example from documentation
+precision:   7
+rounding:    half_even
+maxExponent: +96
+minExponent: -95
+
+clamp:       0
+clam700 apply   1.23E+96                -> 1.23E+96
+
+clamp:       1
+clam701 apply   1.23E+96                -> 1.230000E+96 Clamped

Added: vendor/Python/current/Lib/test/decimaltestdata/compare.decTest
===================================================================
--- vendor/Python/current/Lib/test/decimaltestdata/compare.decTest	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/decimaltestdata/compare.decTest	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,717 @@
+------------------------------------------------------------------------
+-- compare.decTest -- decimal comparison                              --
+-- Copyright (c) IBM Corporation, 1981, 2003.  All rights reserved.   --
+------------------------------------------------------------------------
+-- Please see the document "General Decimal Arithmetic Testcases"     --
+-- at http://www2.hursley.ibm.com/decimal for the description of      --
+-- these testcases.                                                   --
+--                                                                    --
+-- These testcases are experimental ('beta' versions), and they       --
+-- may contain errors.  They are offered on an as-is basis.  In       --
+-- particular, achieving the same results as the tests here is not    --
+-- a guarantee that an implementation complies with any Standard      --
+-- or specification.  The tests are not exhaustive.                   --
+--                                                                    --
+-- Please send comments, suggestions, and corrections to the author:  --
+--   Mike Cowlishaw, IBM Fellow                                       --
+--   IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK         --
+--   mfc at uk.ibm.com                                                   --
+------------------------------------------------------------------------
+version: 2.39
+
+-- Note that we cannot assume add/subtract tests cover paths adequately,
+-- here, because the code might be quite different (comparison cannot
+-- overflow or underflow, so actual subtractions are not necesary).
+
+extended: 1
+
+precision:   9
+rounding:    half_up
+maxExponent: 999
+minexponent: -999
+
+-- sanity checks
+comx001 compare  -2  -2  -> 0
+comx002 compare  -2  -1  -> -1
+comx003 compare  -2   0  -> -1
+comx004 compare  -2   1  -> -1
+comx005 compare  -2   2  -> -1
+comx006 compare  -1  -2  -> 1
+comx007 compare  -1  -1  -> 0
+comx008 compare  -1   0  -> -1
+comx009 compare  -1   1  -> -1
+comx010 compare  -1   2  -> -1
+comx011 compare   0  -2  -> 1
+comx012 compare   0  -1  -> 1
+comx013 compare   0   0  -> 0
+comx014 compare   0   1  -> -1
+comx015 compare   0   2  -> -1
+comx016 compare   1  -2  -> 1
+comx017 compare   1  -1  -> 1
+comx018 compare   1   0  -> 1
+comx019 compare   1   1  -> 0
+comx020 compare   1   2  -> -1
+comx021 compare   2  -2  -> 1
+comx022 compare   2  -1  -> 1
+comx023 compare   2   0  -> 1
+comx025 compare   2   1  -> 1
+comx026 compare   2   2  -> 0
+
+comx031 compare  -20  -20  -> 0
+comx032 compare  -20  -10  -> -1
+comx033 compare  -20   00  -> -1
+comx034 compare  -20   10  -> -1
+comx035 compare  -20   20  -> -1
+comx036 compare  -10  -20  -> 1
+comx037 compare  -10  -10  -> 0
+comx038 compare  -10   00  -> -1
+comx039 compare  -10   10  -> -1
+comx040 compare  -10   20  -> -1
+comx041 compare   00  -20  -> 1
+comx042 compare   00  -10  -> 1
+comx043 compare   00   00  -> 0
+comx044 compare   00   10  -> -1
+comx045 compare   00   20  -> -1
+comx046 compare   10  -20  -> 1
+comx047 compare   10  -10  -> 1
+comx048 compare   10   00  -> 1
+comx049 compare   10   10  -> 0
+comx050 compare   10   20  -> -1
+comx051 compare   20  -20  -> 1
+comx052 compare   20  -10  -> 1
+comx053 compare   20   00  -> 1
+comx055 compare   20   10  -> 1
+comx056 compare   20   20  -> 0
+
+comx061 compare  -2.0  -2.0  -> 0
+comx062 compare  -2.0  -1.0  -> -1
+comx063 compare  -2.0   0.0  -> -1
+comx064 compare  -2.0   1.0  -> -1
+comx065 compare  -2.0   2.0  -> -1
+comx066 compare  -1.0  -2.0  -> 1
+comx067 compare  -1.0  -1.0  -> 0
+comx068 compare  -1.0   0.0  -> -1
+comx069 compare  -1.0   1.0  -> -1
+comx070 compare  -1.0   2.0  -> -1
+comx071 compare   0.0  -2.0  -> 1
+comx072 compare   0.0  -1.0  -> 1
+comx073 compare   0.0   0.0  -> 0
+comx074 compare   0.0   1.0  -> -1
+comx075 compare   0.0   2.0  -> -1
+comx076 compare   1.0  -2.0  -> 1
+comx077 compare   1.0  -1.0  -> 1
+comx078 compare   1.0   0.0  -> 1
+comx079 compare   1.0   1.0  -> 0
+comx080 compare   1.0   2.0  -> -1
+comx081 compare   2.0  -2.0  -> 1
+comx082 compare   2.0  -1.0  -> 1
+comx083 compare   2.0   0.0  -> 1
+comx085 compare   2.0   1.0  -> 1
+comx086 compare   2.0   2.0  -> 0
+
+-- now some cases which might overflow if subtract were used
+maxexponent: 999999999
+minexponent: -999999999
+comx090 compare  9.99999999E+999999999 9.99999999E+999999999  -> 0
+comx091 compare -9.99999999E+999999999 9.99999999E+999999999  -> -1
+comx092 compare  9.99999999E+999999999 -9.99999999E+999999999 -> 1
+comx093 compare -9.99999999E+999999999 -9.99999999E+999999999 -> 0
+
+-- some differing length/exponent cases
+comx100 compare   7.0    7.0    -> 0
+comx101 compare   7.0    7      -> 0
+comx102 compare   7      7.0    -> 0
+comx103 compare   7E+0   7.0    -> 0
+comx104 compare   70E-1  7.0    -> 0
+comx105 compare   0.7E+1 7      -> 0
+comx106 compare   70E-1  7      -> 0
+comx107 compare   7.0    7E+0   -> 0
+comx108 compare   7.0    70E-1  -> 0
+comx109 compare   7      0.7E+1 -> 0
+comx110 compare   7      70E-1  -> 0
+
+comx120 compare   8.0    7.0    -> 1
+comx121 compare   8.0    7      -> 1
+comx122 compare   8      7.0    -> 1
+comx123 compare   8E+0   7.0    -> 1
+comx124 compare   80E-1  7.0    -> 1
+comx125 compare   0.8E+1 7      -> 1
+comx126 compare   80E-1  7      -> 1
+comx127 compare   8.0    7E+0   -> 1
+comx128 compare   8.0    70E-1  -> 1
+comx129 compare   8      0.7E+1  -> 1
+comx130 compare   8      70E-1  -> 1
+
+comx140 compare   8.0    9.0    -> -1
+comx141 compare   8.0    9      -> -1
+comx142 compare   8      9.0    -> -1
+comx143 compare   8E+0   9.0    -> -1
+comx144 compare   80E-1  9.0    -> -1
+comx145 compare   0.8E+1 9      -> -1
+comx146 compare   80E-1  9      -> -1
+comx147 compare   8.0    9E+0   -> -1
+comx148 compare   8.0    90E-1  -> -1
+comx149 compare   8      0.9E+1 -> -1
+comx150 compare   8      90E-1  -> -1
+
+-- and again, with sign changes -+ ..
+comx200 compare  -7.0    7.0    -> -1
+comx201 compare  -7.0    7      -> -1
+comx202 compare  -7      7.0    -> -1
+comx203 compare  -7E+0   7.0    -> -1
+comx204 compare  -70E-1  7.0    -> -1
+comx205 compare  -0.7E+1 7      -> -1
+comx206 compare  -70E-1  7      -> -1
+comx207 compare  -7.0    7E+0   -> -1
+comx208 compare  -7.0    70E-1  -> -1
+comx209 compare  -7      0.7E+1 -> -1
+comx210 compare  -7      70E-1  -> -1
+
+comx220 compare  -8.0    7.0    -> -1
+comx221 compare  -8.0    7      -> -1
+comx222 compare  -8      7.0    -> -1
+comx223 compare  -8E+0   7.0    -> -1
+comx224 compare  -80E-1  7.0    -> -1
+comx225 compare  -0.8E+1 7      -> -1
+comx226 compare  -80E-1  7      -> -1
+comx227 compare  -8.0    7E+0   -> -1
+comx228 compare  -8.0    70E-1  -> -1
+comx229 compare  -8      0.7E+1 -> -1
+comx230 compare  -8      70E-1  -> -1
+
+comx240 compare  -8.0    9.0    -> -1
+comx241 compare  -8.0    9      -> -1
+comx242 compare  -8      9.0    -> -1
+comx243 compare  -8E+0   9.0    -> -1
+comx244 compare  -80E-1  9.0    -> -1
+comx245 compare  -0.8E+1 9      -> -1
+comx246 compare  -80E-1  9      -> -1
+comx247 compare  -8.0    9E+0   -> -1
+comx248 compare  -8.0    90E-1  -> -1
+comx249 compare  -8      0.9E+1 -> -1
+comx250 compare  -8      90E-1  -> -1
+
+-- and again, with sign changes +- ..
+comx300 compare   7.0    -7.0    -> 1
+comx301 compare   7.0    -7      -> 1
+comx302 compare   7      -7.0    -> 1
+comx303 compare   7E+0   -7.0    -> 1
+comx304 compare   70E-1  -7.0    -> 1
+comx305 compare   .7E+1  -7      -> 1
+comx306 compare   70E-1  -7      -> 1
+comx307 compare   7.0    -7E+0   -> 1
+comx308 compare   7.0    -70E-1  -> 1
+comx309 compare   7      -.7E+1  -> 1
+comx310 compare   7      -70E-1  -> 1
+
+comx320 compare   8.0    -7.0    -> 1
+comx321 compare   8.0    -7      -> 1
+comx322 compare   8      -7.0    -> 1
+comx323 compare   8E+0   -7.0    -> 1
+comx324 compare   80E-1  -7.0    -> 1
+comx325 compare   .8E+1  -7      -> 1
+comx326 compare   80E-1  -7      -> 1
+comx327 compare   8.0    -7E+0   -> 1
+comx328 compare   8.0    -70E-1  -> 1
+comx329 compare   8      -.7E+1  -> 1
+comx330 compare   8      -70E-1  -> 1
+
+comx340 compare   8.0    -9.0    -> 1
+comx341 compare   8.0    -9      -> 1
+comx342 compare   8      -9.0    -> 1
+comx343 compare   8E+0   -9.0    -> 1
+comx344 compare   80E-1  -9.0    -> 1
+comx345 compare   .8E+1  -9      -> 1
+comx346 compare   80E-1  -9      -> 1
+comx347 compare   8.0    -9E+0   -> 1
+comx348 compare   8.0    -90E-1  -> 1
+comx349 compare   8      -.9E+1  -> 1
+comx350 compare   8      -90E-1  -> 1
+
+-- and again, with sign changes -- ..
+comx400 compare   -7.0    -7.0    -> 0
+comx401 compare   -7.0    -7      -> 0
+comx402 compare   -7      -7.0    -> 0
+comx403 compare   -7E+0   -7.0    -> 0
+comx404 compare   -70E-1  -7.0    -> 0
+comx405 compare   -.7E+1  -7      -> 0
+comx406 compare   -70E-1  -7      -> 0
+comx407 compare   -7.0    -7E+0   -> 0
+comx408 compare   -7.0    -70E-1  -> 0
+comx409 compare   -7      -.7E+1  -> 0
+comx410 compare   -7      -70E-1  -> 0
+
+comx420 compare   -8.0    -7.0    -> -1
+comx421 compare   -8.0    -7      -> -1
+comx422 compare   -8      -7.0    -> -1
+comx423 compare   -8E+0   -7.0    -> -1
+comx424 compare   -80E-1  -7.0    -> -1
+comx425 compare   -.8E+1  -7      -> -1
+comx426 compare   -80E-1  -7      -> -1
+comx427 compare   -8.0    -7E+0   -> -1
+comx428 compare   -8.0    -70E-1  -> -1
+comx429 compare   -8      -.7E+1  -> -1
+comx430 compare   -8      -70E-1  -> -1
+
+comx440 compare   -8.0    -9.0    -> 1
+comx441 compare   -8.0    -9      -> 1
+comx442 compare   -8      -9.0    -> 1
+comx443 compare   -8E+0   -9.0    -> 1
+comx444 compare   -80E-1  -9.0    -> 1
+comx445 compare   -.8E+1  -9      -> 1
+comx446 compare   -80E-1  -9      -> 1
+comx447 compare   -8.0    -9E+0   -> 1
+comx448 compare   -8.0    -90E-1  -> 1
+comx449 compare   -8      -.9E+1  -> 1
+comx450 compare   -8      -90E-1  -> 1
+
+
+-- testcases that subtract to lots of zeros at boundaries [pgr]
+precision: 40
+comx470 compare 123.4560000000000000E789 123.456E789 -> 0
+comx471 compare 123.456000000000000E-89 123.456E-89 -> 0
+comx472 compare 123.45600000000000E789 123.456E789 -> 0
+comx473 compare 123.4560000000000E-89 123.456E-89 -> 0
+comx474 compare 123.456000000000E789 123.456E789 -> 0
+comx475 compare 123.45600000000E-89 123.456E-89 -> 0
+comx476 compare 123.4560000000E789 123.456E789 -> 0
+comx477 compare 123.456000000E-89 123.456E-89 -> 0
+comx478 compare 123.45600000E789 123.456E789 -> 0
+comx479 compare 123.4560000E-89 123.456E-89 -> 0
+comx480 compare 123.456000E789 123.456E789 -> 0
+comx481 compare 123.45600E-89 123.456E-89 -> 0
+comx482 compare 123.4560E789 123.456E789 -> 0
+comx483 compare 123.456E-89 123.456E-89 -> 0
+comx484 compare 123.456E-89 123.4560000000000000E-89 -> 0
+comx485 compare 123.456E789 123.456000000000000E789 -> 0
+comx486 compare 123.456E-89 123.45600000000000E-89 -> 0
+comx487 compare 123.456E789 123.4560000000000E789 -> 0
+comx488 compare 123.456E-89 123.456000000000E-89 -> 0
+comx489 compare 123.456E789 123.45600000000E789 -> 0
+comx490 compare 123.456E-89 123.4560000000E-89 -> 0
+comx491 compare 123.456E789 123.456000000E789 -> 0
+comx492 compare 123.456E-89 123.45600000E-89 -> 0
+comx493 compare 123.456E789 123.4560000E789 -> 0
+comx494 compare 123.456E-89 123.456000E-89 -> 0
+comx495 compare 123.456E789 123.45600E789 -> 0
+comx496 compare 123.456E-89 123.4560E-89 -> 0
+comx497 compare 123.456E789 123.456E789 -> 0
+
+-- wide-ranging, around precision; signs equal
+precision: 9
+comx500 compare    1     1E-15    -> 1
+comx501 compare    1     1E-14    -> 1
+comx502 compare    1     1E-13    -> 1
+comx503 compare    1     1E-12    -> 1
+comx504 compare    1     1E-11    -> 1
+comx505 compare    1     1E-10    -> 1
+comx506 compare    1     1E-9     -> 1
+comx507 compare    1     1E-8     -> 1
+comx508 compare    1     1E-7     -> 1
+comx509 compare    1     1E-6     -> 1
+comx510 compare    1     1E-5     -> 1
+comx511 compare    1     1E-4     -> 1
+comx512 compare    1     1E-3     -> 1
+comx513 compare    1     1E-2     -> 1
+comx514 compare    1     1E-1     -> 1
+comx515 compare    1     1E-0     -> 0
+comx516 compare    1     1E+1     -> -1
+comx517 compare    1     1E+2     -> -1
+comx518 compare    1     1E+3     -> -1
+comx519 compare    1     1E+4     -> -1
+comx521 compare    1     1E+5     -> -1
+comx522 compare    1     1E+6     -> -1
+comx523 compare    1     1E+7     -> -1
+comx524 compare    1     1E+8     -> -1
+comx525 compare    1     1E+9     -> -1
+comx526 compare    1     1E+10    -> -1
+comx527 compare    1     1E+11    -> -1
+comx528 compare    1     1E+12    -> -1
+comx529 compare    1     1E+13    -> -1
+comx530 compare    1     1E+14    -> -1
+comx531 compare    1     1E+15    -> -1
+-- LR swap
+comx540 compare    1E-15  1       -> -1
+comx541 compare    1E-14  1       -> -1
+comx542 compare    1E-13  1       -> -1
+comx543 compare    1E-12  1       -> -1
+comx544 compare    1E-11  1       -> -1
+comx545 compare    1E-10  1       -> -1
+comx546 compare    1E-9   1       -> -1
+comx547 compare    1E-8   1       -> -1
+comx548 compare    1E-7   1       -> -1
+comx549 compare    1E-6   1       -> -1
+comx550 compare    1E-5   1       -> -1
+comx551 compare    1E-4   1       -> -1
+comx552 compare    1E-3   1       -> -1
+comx553 compare    1E-2   1       -> -1
+comx554 compare    1E-1   1       -> -1
+comx555 compare    1E-0   1       ->  0
+comx556 compare    1E+1   1       ->  1
+comx557 compare    1E+2   1       ->  1
+comx558 compare    1E+3   1       ->  1
+comx559 compare    1E+4   1       ->  1
+comx561 compare    1E+5   1       ->  1
+comx562 compare    1E+6   1       ->  1
+comx563 compare    1E+7   1       ->  1
+comx564 compare    1E+8   1       ->  1
+comx565 compare    1E+9   1       ->  1
+comx566 compare    1E+10  1       ->  1
+comx567 compare    1E+11  1       ->  1
+comx568 compare    1E+12  1       ->  1
+comx569 compare    1E+13  1       ->  1
+comx570 compare    1E+14  1       ->  1
+comx571 compare    1E+15  1       ->  1
+-- similar with an useful coefficient, one side only
+comx580 compare  0.000000987654321     1E-15    -> 1
+comx581 compare  0.000000987654321     1E-14    -> 1
+comx582 compare  0.000000987654321     1E-13    -> 1
+comx583 compare  0.000000987654321     1E-12    -> 1
+comx584 compare  0.000000987654321     1E-11    -> 1
+comx585 compare  0.000000987654321     1E-10    -> 1
+comx586 compare  0.000000987654321     1E-9     -> 1
+comx587 compare  0.000000987654321     1E-8     -> 1
+comx588 compare  0.000000987654321     1E-7     -> 1
+comx589 compare  0.000000987654321     1E-6     -> -1
+comx590 compare  0.000000987654321     1E-5     -> -1
+comx591 compare  0.000000987654321     1E-4     -> -1
+comx592 compare  0.000000987654321     1E-3     -> -1
+comx593 compare  0.000000987654321     1E-2     -> -1
+comx594 compare  0.000000987654321     1E-1     -> -1
+comx595 compare  0.000000987654321     1E-0     -> -1
+comx596 compare  0.000000987654321     1E+1     -> -1
+comx597 compare  0.000000987654321     1E+2     -> -1
+comx598 compare  0.000000987654321     1E+3     -> -1
+comx599 compare  0.000000987654321     1E+4     -> -1
+
+-- check some unit-y traps
+precision: 20
+comx600 compare   12            12.2345 -> -1
+comx601 compare   12.0          12.2345 -> -1
+comx602 compare   12.00         12.2345 -> -1
+comx603 compare   12.000        12.2345 -> -1
+comx604 compare   12.0000       12.2345 -> -1
+comx605 compare   12.00000      12.2345 -> -1
+comx606 compare   12.000000     12.2345 -> -1
+comx607 compare   12.0000000    12.2345 -> -1
+comx608 compare   12.00000000   12.2345 -> -1
+comx609 compare   12.000000000  12.2345 -> -1
+comx610 compare   12.1234 12            ->  1
+comx611 compare   12.1234 12.0          ->  1
+comx612 compare   12.1234 12.00         ->  1
+comx613 compare   12.1234 12.000        ->  1
+comx614 compare   12.1234 12.0000       ->  1
+comx615 compare   12.1234 12.00000      ->  1
+comx616 compare   12.1234 12.000000     ->  1
+comx617 compare   12.1234 12.0000000    ->  1
+comx618 compare   12.1234 12.00000000   ->  1
+comx619 compare   12.1234 12.000000000  ->  1
+comx620 compare  -12           -12.2345 ->  1
+comx621 compare  -12.0         -12.2345 ->  1
+comx622 compare  -12.00        -12.2345 ->  1
+comx623 compare  -12.000       -12.2345 ->  1
+comx624 compare  -12.0000      -12.2345 ->  1
+comx625 compare  -12.00000     -12.2345 ->  1
+comx626 compare  -12.000000    -12.2345 ->  1
+comx627 compare  -12.0000000   -12.2345 ->  1
+comx628 compare  -12.00000000  -12.2345 ->  1
+comx629 compare  -12.000000000 -12.2345 ->  1
+comx630 compare  -12.1234 -12           -> -1
+comx631 compare  -12.1234 -12.0         -> -1
+comx632 compare  -12.1234 -12.00        -> -1
+comx633 compare  -12.1234 -12.000       -> -1
+comx634 compare  -12.1234 -12.0000      -> -1
+comx635 compare  -12.1234 -12.00000     -> -1
+comx636 compare  -12.1234 -12.000000    -> -1
+comx637 compare  -12.1234 -12.0000000   -> -1
+comx638 compare  -12.1234 -12.00000000  -> -1
+comx639 compare  -12.1234 -12.000000000 -> -1
+precision: 9
+
+-- extended zeros
+comx640 compare   0     0   -> 0
+comx641 compare   0    -0   -> 0
+comx642 compare   0    -0.0 -> 0
+comx643 compare   0     0.0 -> 0
+comx644 compare  -0     0   -> 0
+comx645 compare  -0    -0   -> 0
+comx646 compare  -0    -0.0 -> 0
+comx647 compare  -0     0.0 -> 0
+comx648 compare   0.0   0   -> 0
+comx649 compare   0.0  -0   -> 0
+comx650 compare   0.0  -0.0 -> 0
+comx651 compare   0.0   0.0 -> 0
+comx652 compare  -0.0   0   -> 0
+comx653 compare  -0.0  -0   -> 0
+comx654 compare  -0.0  -0.0 -> 0
+comx655 compare  -0.0   0.0 -> 0
+
+comx656 compare  -0E1   0.0 -> 0
+comx657 compare  -0E2   0.0 -> 0
+comx658 compare   0E1   0.0 -> 0
+comx659 compare   0E2   0.0 -> 0
+comx660 compare  -0E1   0   -> 0
+comx661 compare  -0E2   0   -> 0
+comx662 compare   0E1   0   -> 0
+comx663 compare   0E2   0   -> 0
+comx664 compare  -0E1  -0E1 -> 0
+comx665 compare  -0E2  -0E1 -> 0
+comx666 compare   0E1  -0E1 -> 0
+comx667 compare   0E2  -0E1 -> 0
+comx668 compare  -0E1  -0E2 -> 0
+comx669 compare  -0E2  -0E2 -> 0
+comx670 compare   0E1  -0E2 -> 0
+comx671 compare   0E2  -0E2 -> 0
+comx672 compare  -0E1   0E1 -> 0
+comx673 compare  -0E2   0E1 -> 0
+comx674 compare   0E1   0E1 -> 0
+comx675 compare   0E2   0E1 -> 0
+comx676 compare  -0E1   0E2 -> 0
+comx677 compare  -0E2   0E2 -> 0
+comx678 compare   0E1   0E2 -> 0
+comx679 compare   0E2   0E2 -> 0
+
+-- trailing zeros; unit-y
+precision: 20
+comx680 compare   12    12           -> 0
+comx681 compare   12    12.0         -> 0
+comx682 compare   12    12.00        -> 0
+comx683 compare   12    12.000       -> 0
+comx684 compare   12    12.0000      -> 0
+comx685 compare   12    12.00000     -> 0
+comx686 compare   12    12.000000    -> 0
+comx687 compare   12    12.0000000   -> 0
+comx688 compare   12    12.00000000  -> 0
+comx689 compare   12    12.000000000 -> 0
+comx690 compare   12              12 -> 0
+comx691 compare   12.0            12 -> 0
+comx692 compare   12.00           12 -> 0
+comx693 compare   12.000          12 -> 0
+comx694 compare   12.0000         12 -> 0
+comx695 compare   12.00000        12 -> 0
+comx696 compare   12.000000       12 -> 0
+comx697 compare   12.0000000      12 -> 0
+comx698 compare   12.00000000     12 -> 0
+comx699 compare   12.000000000    12 -> 0
+
+-- long operand checks
+maxexponent: 999
+minexponent: -999
+precision: 9
+comx701 compare 12345678000  1 ->  1
+comx702 compare 1 12345678000  -> -1
+comx703 compare 1234567800   1 ->  1
+comx704 compare 1 1234567800   -> -1
+comx705 compare 1234567890   1 ->  1
+comx706 compare 1 1234567890   -> -1
+comx707 compare 1234567891   1 ->  1
+comx708 compare 1 1234567891   -> -1
+comx709 compare 12345678901  1 ->  1
+comx710 compare 1 12345678901  -> -1
+comx711 compare 1234567896   1 ->  1
+comx712 compare 1 1234567896   -> -1
+comx713 compare -1234567891  1 -> -1
+comx714 compare 1 -1234567891  ->  1
+comx715 compare -12345678901 1 -> -1
+comx716 compare 1 -12345678901 ->  1
+comx717 compare -1234567896  1 -> -1
+comx718 compare 1 -1234567896  ->  1
+
+precision: 15
+-- same with plenty of precision
+comx721 compare 12345678000 1 -> 1
+comx722 compare 1 12345678000 -> -1
+comx723 compare 1234567800  1 -> 1
+comx724 compare 1 1234567800  -> -1
+comx725 compare 1234567890  1 -> 1
+comx726 compare 1 1234567890  -> -1
+comx727 compare 1234567891  1 -> 1
+comx728 compare 1 1234567891  -> -1
+comx729 compare 12345678901 1 -> 1
+comx730 compare 1 12345678901 -> -1
+comx731 compare 1234567896  1 -> 1
+comx732 compare 1 1234567896  -> -1
+
+-- residue cases
+precision: 5
+comx740 compare  1  0.9999999  -> 1
+comx741 compare  1  0.999999   -> 1
+comx742 compare  1  0.99999    -> 1
+comx743 compare  1  1.0000     -> 0
+comx744 compare  1  1.00001    -> -1
+comx745 compare  1  1.000001   -> -1
+comx746 compare  1  1.0000001  -> -1
+comx750 compare  0.9999999  1  -> -1
+comx751 compare  0.999999   1  -> -1
+comx752 compare  0.99999    1  -> -1
+comx753 compare  1.0000     1  -> 0
+comx754 compare  1.00001    1  -> 1
+comx755 compare  1.000001   1  -> 1
+comx756 compare  1.0000001  1  -> 1
+
+-- a selection of longies
+comx760 compare -36852134.84194296250843579428931 -5830629.8347085025808756560357940 -> -1
+comx761 compare -36852134.84194296250843579428931 -36852134.84194296250843579428931  -> 0
+comx762 compare -36852134.94194296250843579428931 -36852134.84194296250843579428931  -> -1
+comx763 compare -36852134.84194296250843579428931 -36852134.94194296250843579428931  -> 1
+-- precisions above or below the difference should have no effect
+precision:   11
+comx764 compare -36852134.84194296250843579428931 -36852134.94194296250843579428931  -> 1
+precision:   10
+comx765 compare -36852134.84194296250843579428931 -36852134.94194296250843579428931  -> 1
+precision:    9
+comx766 compare -36852134.84194296250843579428931 -36852134.94194296250843579428931  -> 1
+precision:    8
+comx767 compare -36852134.84194296250843579428931 -36852134.94194296250843579428931  -> 1
+precision:    7
+comx768 compare -36852134.84194296250843579428931 -36852134.94194296250843579428931  -> 1
+precision:    6
+comx769 compare -36852134.84194296250843579428931 -36852134.94194296250843579428931  -> 1
+precision:    5
+comx770 compare -36852134.84194296250843579428931 -36852134.94194296250843579428931  -> 1
+precision:    4
+comx771 compare -36852134.84194296250843579428931 -36852134.94194296250843579428931  -> 1
+precision:    3
+comx772 compare -36852134.84194296250843579428931 -36852134.94194296250843579428931  -> 1
+precision:    2
+comx773 compare -36852134.84194296250843579428931 -36852134.94194296250843579428931  -> 1
+precision:    1
+comx774 compare -36852134.84194296250843579428931 -36852134.94194296250843579428931  -> 1
+
+-- Specials
+precision:   9
+comx780 compare  Inf  -Inf   ->  1
+comx781 compare  Inf  -1000  ->  1
+comx782 compare  Inf  -1     ->  1
+comx783 compare  Inf  -0     ->  1
+comx784 compare  Inf   0     ->  1
+comx785 compare  Inf   1     ->  1
+comx786 compare  Inf   1000  ->  1
+comx787 compare  Inf   Inf   ->  0
+comx788 compare -1000  Inf   -> -1
+comx789 compare -Inf   Inf   -> -1
+comx790 compare -1     Inf   -> -1
+comx791 compare -0     Inf   -> -1
+comx792 compare  0     Inf   -> -1
+comx793 compare  1     Inf   -> -1
+comx794 compare  1000  Inf   -> -1
+comx795 compare  Inf   Inf   ->  0
+
+comx800 compare -Inf  -Inf   ->  0
+comx801 compare -Inf  -1000  -> -1
+comx802 compare -Inf  -1     -> -1
+comx803 compare -Inf  -0     -> -1
+comx804 compare -Inf   0     -> -1
+comx805 compare -Inf   1     -> -1
+comx806 compare -Inf   1000  -> -1
+comx807 compare -Inf   Inf   -> -1
+comx808 compare -Inf  -Inf   ->  0
+comx809 compare -1000 -Inf   ->  1
+comx810 compare -1    -Inf   ->  1
+comx811 compare -0    -Inf   ->  1
+comx812 compare  0    -Inf   ->  1
+comx813 compare  1    -Inf   ->  1
+comx814 compare  1000 -Inf   ->  1
+comx815 compare  Inf  -Inf   ->  1
+
+comx821 compare  NaN -Inf    ->  NaN
+comx822 compare  NaN -1000   ->  NaN
+comx823 compare  NaN -1      ->  NaN
+comx824 compare  NaN -0      ->  NaN
+comx825 compare  NaN  0      ->  NaN
+comx826 compare  NaN  1      ->  NaN
+comx827 compare  NaN  1000   ->  NaN
+comx828 compare  NaN  Inf    ->  NaN
+comx829 compare  NaN  NaN    ->  NaN
+comx830 compare -Inf  NaN    ->  NaN
+comx831 compare -1000 NaN    ->  NaN
+comx832 compare -1    NaN    ->  NaN
+comx833 compare -0    NaN    ->  NaN
+comx834 compare  0    NaN    ->  NaN
+comx835 compare  1    NaN    ->  NaN
+comx836 compare  1000 NaN    ->  NaN
+comx837 compare  Inf  NaN    ->  NaN
+comx838 compare -NaN -NaN    -> -NaN
+comx839 compare +NaN -NaN    ->  NaN
+comx840 compare -NaN +NaN    -> -NaN
+
+comx841 compare  sNaN -Inf   ->  NaN  Invalid_operation
+comx842 compare  sNaN -1000  ->  NaN  Invalid_operation
+comx843 compare  sNaN -1     ->  NaN  Invalid_operation
+comx844 compare  sNaN -0     ->  NaN  Invalid_operation
+comx845 compare  sNaN  0     ->  NaN  Invalid_operation
+comx846 compare  sNaN  1     ->  NaN  Invalid_operation
+comx847 compare  sNaN  1000  ->  NaN  Invalid_operation
+comx848 compare  sNaN  NaN   ->  NaN  Invalid_operation
+comx849 compare  sNaN sNaN   ->  NaN  Invalid_operation
+comx850 compare  NaN  sNaN   ->  NaN  Invalid_operation
+comx851 compare -Inf  sNaN   ->  NaN  Invalid_operation
+comx852 compare -1000 sNaN   ->  NaN  Invalid_operation
+comx853 compare -1    sNaN   ->  NaN  Invalid_operation
+comx854 compare -0    sNaN   ->  NaN  Invalid_operation
+comx855 compare  0    sNaN   ->  NaN  Invalid_operation
+comx856 compare  1    sNaN   ->  NaN  Invalid_operation
+comx857 compare  1000 sNaN   ->  NaN  Invalid_operation
+comx858 compare  Inf  sNaN   ->  NaN  Invalid_operation
+comx859 compare  NaN  sNaN   ->  NaN  Invalid_operation
+
+-- propagating NaNs
+comx860 compare  NaN9 -Inf   ->  NaN9
+comx861 compare  NaN8  999   ->  NaN8
+comx862 compare  NaN77 Inf   ->  NaN77
+comx863 compare -NaN67 NaN5  -> -NaN67
+comx864 compare -Inf  -NaN4  -> -NaN4
+comx865 compare -999  -NaN33 -> -NaN33
+comx866 compare  Inf   NaN2  ->  NaN2
+comx867 compare -NaN41 -NaN42 -> -NaN41
+comx868 compare +NaN41 -NaN42 ->  NaN41
+comx869 compare -NaN41 +NaN42 -> -NaN41
+comx870 compare +NaN41 +NaN42 ->  NaN41
+
+comx871 compare -sNaN99 -Inf    -> -NaN99 Invalid_operation
+comx872 compare  sNaN98 -11     ->  NaN98 Invalid_operation
+comx873 compare  sNaN97  NaN    ->  NaN97 Invalid_operation
+comx874 compare  sNaN16 sNaN94  ->  NaN16 Invalid_operation
+comx875 compare  NaN85  sNaN83  ->  NaN83 Invalid_operation
+comx876 compare -Inf    sNaN92  ->  NaN92 Invalid_operation
+comx877 compare  088    sNaN81  ->  NaN81 Invalid_operation
+comx878 compare  Inf    sNaN90  ->  NaN90 Invalid_operation
+comx879 compare  NaN   -sNaN89  -> -NaN89 Invalid_operation
+
+-- overflow and underflow tests .. subnormal results now allowed
+maxExponent: 999999999
+minexponent: -999999999
+comx880 compare +1.23456789012345E-0 9E+999999999 -> -1
+comx881 compare 9E+999999999 +1.23456789012345E-0 ->  1
+comx882 compare +0.100 9E-999999999               ->  1
+comx883 compare 9E-999999999 +0.100               -> -1
+comx885 compare -1.23456789012345E-0 9E+999999999 -> -1
+comx886 compare 9E+999999999 -1.23456789012345E-0 ->  1
+comx887 compare -0.100 9E-999999999               -> -1
+comx888 compare 9E-999999999 -0.100               ->  1
+
+comx889 compare 1e-599999999 1e-400000001   -> -1
+comx890 compare 1e-599999999 1e-400000000   -> -1
+comx891 compare 1e-600000000 1e-400000000   -> -1
+comx892 compare 9e-999999998 0.01           -> -1
+comx893 compare 9e-999999998 0.1            -> -1
+comx894 compare 0.01 9e-999999998           ->  1
+comx895 compare 1e599999999 1e400000001     ->  1
+comx896 compare 1e599999999 1e400000000     ->  1
+comx897 compare 1e600000000 1e400000000     ->  1
+comx898 compare 9e999999998 100             ->  1
+comx899 compare 9e999999998 10              ->  1
+comx900 compare 100  9e999999998            -> -1
+-- signs
+comx901 compare  1e+777777777  1e+411111111 ->  1
+comx902 compare  1e+777777777 -1e+411111111 ->  1
+comx903 compare -1e+777777777  1e+411111111 -> -1
+comx904 compare -1e+777777777 -1e+411111111 -> -1
+comx905 compare  1e-777777777  1e-411111111 -> -1
+comx906 compare  1e-777777777 -1e-411111111 ->  1
+comx907 compare -1e-777777777  1e-411111111 -> -1
+comx908 compare -1e-777777777 -1e-411111111 ->  1
+
+-- Null tests
+comx990 compare 10  # -> NaN Invalid_operation
+comx991 compare  # 10 -> NaN Invalid_operation

Added: vendor/Python/current/Lib/test/decimaltestdata/decimal128.decTest
===================================================================
--- vendor/Python/current/Lib/test/decimaltestdata/decimal128.decTest	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/decimaltestdata/decimal128.decTest	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,441 @@
+------------------------------------------------------------------------
+-- decimal128.decTest -- decimal sixteen-byte format testcases        --
+-- Copyright (c) IBM Corporation, 2000, 2003.  All rights reserved.   --
+------------------------------------------------------------------------
+-- Please see the document "General Decimal Arithmetic Testcases"     --
+-- at http://www2.hursley.ibm.com/decimal for the description of      --
+-- these testcases.                                                   --
+--                                                                    --
+-- These testcases are experimental ('beta' versions), and they       --
+-- may contain errors.  They are offered on an as-is basis.  In       --
+-- particular, achieving the same results as the tests here is not    --
+-- a guarantee that an implementation complies with any Standard      --
+-- or specification.  The tests are not exhaustive.                   --
+--                                                                    --
+-- Please send comments, suggestions, and corrections to the author:  --
+--   Mike Cowlishaw, IBM Fellow                                       --
+--   IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK         --
+--   mfc at uk.ibm.com                                                   --
+------------------------------------------------------------------------
+version: 2.39
+
+-- This set of tests is for the sixteen-byte concrete representation.
+-- Its characteristics are:
+--
+--   1 bit  sign
+--   5 bits combination field
+--  12 bits exponent continuation
+-- 110 bits coefficient continuation
+--
+-- Total exponent length 14 bits
+-- Total coefficient length 114 bits (34 digits)
+--
+-- Elimit = 12287 (maximum encoded exponent)
+-- Emax   =  6144 (largest exponent value)
+-- Emin   = -6143 (smallest exponent value)
+-- bias   =  6176 (subtracted from encoded exponent) = -Etiny
+
+extended:    1
+precision:   34
+rounding:    half_up
+maxExponent: 6144
+minExponent: -6143
+
+-- General testcases
+-- (mostly derived from the Strawman 4 document and examples)
+decg001 apply   #A20780000000000000000000000003D0 -> -7.50
+decg002 apply   -7.50  -> #A20780000000000000000000000003D0
+
+-- Normality
+decf010 apply   1234567890123456789012345678901234   -> #2608134b9c1e28e56f3c127177823534
+decf011 apply   1234567890123456789012345678901234.0 -> #2608134b9c1e28e56f3c127177823534 Rounded
+decf012 apply   1234567890123456789012345678901234.1 -> #2608134b9c1e28e56f3c127177823534 Rounded Inexact
+decf013 apply  -1234567890123456789012345678901234   -> #a608134b9c1e28e56f3c127177823534
+decf014 apply  -1234567890123456789012345678901234.0 -> #a608134b9c1e28e56f3c127177823534 Rounded
+decf015 apply  -1234567890123456789012345678901234.1 -> #a608134b9c1e28e56f3c127177823534 Rounded Inexact
+
+
+-- Nmax and similar
+decf022 apply   9.999999999999999999999999999999999E+6144  -> #77ffcff3fcff3fcff3fcff3fcff3fcff
+decf023 apply   #77ffcff3fcff3fcff3fcff3fcff3fcff -> 9.999999999999999999999999999999999E+6144
+decf024 apply   1.234567890123456789012345678901234E+6144 -> #47ffd34b9c1e28e56f3c127177823534
+decf025 apply   #47ffd34b9c1e28e56f3c127177823534 -> 1.234567890123456789012345678901234E+6144
+-- fold-downs (more below)
+decf030 apply   1.23E+6144    -> #47ffd300000000000000000000000000 Clamped
+decf031 apply   #47ffd300000000000000000000000000       -> 1.230000000000000000000000000000000E+6144
+decf032 apply   1E+6144       -> #47ffc000000000000000000000000000 Clamped
+decf033 apply   #47ffc000000000000000000000000000       -> 1.000000000000000000000000000000000E+6144
+
+-- overflows
+maxExponent: 9999  -- set high so conversion causes the overflow
+minExponent: -9999
+decf040 apply   10E+6144                 -> #78000000000000000000000000000000 Overflow Rounded Inexact
+decf041 apply   1.000000000000000E+6145  -> #78000000000000000000000000000000 Overflow Rounded Inexact
+maxExponent: 6144
+minExponent: -6143
+
+decf051 apply   12345                   -> #220800000000000000000000000049c5
+decf052 apply   #220800000000000000000000000049c5       -> 12345
+decf053 apply   1234                    -> #22080000000000000000000000000534
+decf054 apply   #22080000000000000000000000000534       -> 1234
+decf055 apply   123                     -> #220800000000000000000000000000a3
+decf056 apply   #220800000000000000000000000000a3       -> 123
+decf057 apply   12                      -> #22080000000000000000000000000012
+decf058 apply   #22080000000000000000000000000012       -> 12
+decf059 apply   1                       -> #22080000000000000000000000000001
+decf060 apply   #22080000000000000000000000000001       -> 1
+decf061 apply   1.23                    -> #220780000000000000000000000000a3
+decf062 apply   #220780000000000000000000000000a3       -> 1.23
+decf063 apply   123.45                  -> #220780000000000000000000000049c5
+decf064 apply   #220780000000000000000000000049c5       -> 123.45
+
+-- Nmin and below
+decf071 apply   1E-6143                                    -> #00084000000000000000000000000001
+decf072 apply   #00084000000000000000000000000001          -> 1E-6143
+decf073 apply   1.000000000000000000000000000000000E-6143  -> #04000000000000000000000000000000
+decf074 apply   #04000000000000000000000000000000          -> 1.000000000000000000000000000000000E-6143
+decf075 apply   1.000000000000000000000000000000001E-6143  -> #04000000000000000000000000000001
+decf076 apply   #04000000000000000000000000000001          -> 1.000000000000000000000000000000001E-6143
+
+decf077 apply   0.100000000000000000000000000000000E-6143  -> #00000800000000000000000000000000      Subnormal
+decf078 apply   #00000800000000000000000000000000          -> 1.00000000000000000000000000000000E-6144  Subnormal
+decf079 apply   0.000000000000000000000000000000010E-6143  -> #00000000000000000000000000000010      Subnormal
+decf080 apply   #00000000000000000000000000000010          -> 1.0E-6175              Subnormal
+decf081 apply   0.00000000000000000000000000000001E-6143   -> #00004000000000000000000000000001      Subnormal
+decf082 apply   #00004000000000000000000000000001          -> 1E-6175                Subnormal
+decf083 apply   0.000000000000000000000000000000001E-6143  -> #00000000000000000000000000000001      Subnormal
+decf084 apply   #00000000000000000000000000000001          -> 1E-6176                 Subnormal
+
+-- underflows
+decf090 apply   1e-6176                  -> #00000000000000000000000000000001  Subnormal
+decf091 apply   1.9e-6176                -> #00000000000000000000000000000002  Subnormal Underflow Inexact Rounded
+decf092 apply   1.1e-6176                -> #00000000000000000000000000000001  Subnormal Underflow Inexact Rounded
+decf093 apply   1.00000000001e-6176      -> #00000000000000000000000000000001  Subnormal Underflow Inexact Rounded
+decf094 apply   1.00000000000001e-6176   -> #00000000000000000000000000000001  Subnormal Underflow Inexact Rounded
+decf095 apply   1.000000000000001e-6176  -> #00000000000000000000000000000001  Subnormal Underflow Inexact Rounded
+decf096 apply   0.1e-6176                -> #00000000000000000000000000000000  Subnormal Underflow Inexact Rounded
+decf097 apply   0.00000000001e-6176      -> #00000000000000000000000000000000  Subnormal Underflow Inexact Rounded
+decf098 apply   0.00000000000001e-6176   -> #00000000000000000000000000000000  Subnormal Underflow Inexact Rounded
+decf099 apply   0.000000000000001e-6176  -> #00000000000000000000000000000000  Subnormal Underflow Inexact Rounded
+decf100 apply   999999999999999999999999999999999e-6176 -> #00000ff3fcff3fcff3fcff3fcff3fcff  Subnormal
+
+-- same again, negatives
+-- Nmax and similar
+decf122 apply  -9.999999999999999999999999999999999E+6144  -> #f7ffcff3fcff3fcff3fcff3fcff3fcff
+decf123 apply   #f7ffcff3fcff3fcff3fcff3fcff3fcff -> -9.999999999999999999999999999999999E+6144
+decf124 apply  -1.234567890123456789012345678901234E+6144 -> #c7ffd34b9c1e28e56f3c127177823534
+decf125 apply   #c7ffd34b9c1e28e56f3c127177823534 -> -1.234567890123456789012345678901234E+6144
+-- fold-downs (more below)
+decf130 apply  -1.23E+6144    -> #c7ffd300000000000000000000000000 Clamped
+decf131 apply   #c7ffd300000000000000000000000000       -> -1.230000000000000000000000000000000E+6144
+decf132 apply  -1E+6144       -> #c7ffc000000000000000000000000000 Clamped
+decf133 apply   #c7ffc000000000000000000000000000       -> -1.000000000000000000000000000000000E+6144
+
+-- overflows
+maxExponent: 9999  -- set high so conversion causes the overflow
+minExponent: -9999
+decf140 apply  -10E+6144                 -> #f8000000000000000000000000000000 Overflow Rounded Inexact
+decf141 apply  -1.000000000000000E+6145  -> #f8000000000000000000000000000000 Overflow Rounded Inexact
+maxExponent: 6144
+minExponent: -6143
+
+decf151 apply  -12345                   -> #a20800000000000000000000000049c5
+decf152 apply   #a20800000000000000000000000049c5       -> -12345
+decf153 apply  -1234                    -> #a2080000000000000000000000000534
+decf154 apply   #a2080000000000000000000000000534       -> -1234
+decf155 apply  -123                     -> #a20800000000000000000000000000a3
+decf156 apply   #a20800000000000000000000000000a3       -> -123
+decf157 apply  -12                      -> #a2080000000000000000000000000012
+decf158 apply   #a2080000000000000000000000000012       -> -12
+decf159 apply  -1                       -> #a2080000000000000000000000000001
+decf160 apply   #a2080000000000000000000000000001       -> -1
+decf161 apply  -1.23                    -> #a20780000000000000000000000000a3
+decf162 apply   #a20780000000000000000000000000a3       -> -1.23
+decf163 apply  -123.45                  -> #a20780000000000000000000000049c5
+decf164 apply   #a20780000000000000000000000049c5       -> -123.45
+
+-- Nmin and below
+decf171 apply  -1E-6143                                    -> #80084000000000000000000000000001
+decf172 apply   #80084000000000000000000000000001          -> -1E-6143
+decf173 apply  -1.000000000000000000000000000000000E-6143  -> #84000000000000000000000000000000
+decf174 apply   #84000000000000000000000000000000          -> -1.000000000000000000000000000000000E-6143
+decf175 apply  -1.000000000000000000000000000000001E-6143  -> #84000000000000000000000000000001
+decf176 apply   #84000000000000000000000000000001          -> -1.000000000000000000000000000000001E-6143
+
+decf177 apply  -0.100000000000000000000000000000000E-6143  -> #80000800000000000000000000000000      Subnormal
+decf178 apply   #80000800000000000000000000000000          -> -1.00000000000000000000000000000000E-6144  Subnormal
+decf179 apply  -0.000000000000000000000000000000010E-6143  -> #80000000000000000000000000000010      Subnormal
+decf180 apply   #80000000000000000000000000000010          -> -1.0E-6175              Subnormal
+decf181 apply  -0.00000000000000000000000000000001E-6143   -> #80004000000000000000000000000001      Subnormal
+decf182 apply   #80004000000000000000000000000001          -> -1E-6175                Subnormal
+decf183 apply  -0.000000000000000000000000000000001E-6143  -> #80000000000000000000000000000001      Subnormal
+decf184 apply   #80000000000000000000000000000001          -> -1E-6176                 Subnormal
+
+-- underflows
+decf190 apply   -1e-6176                  -> #80000000000000000000000000000001  Subnormal
+decf191 apply   -1.9e-6176                -> #80000000000000000000000000000002  Subnormal Underflow Inexact Rounded
+decf192 apply   -1.1e-6176                -> #80000000000000000000000000000001  Subnormal Underflow Inexact Rounded
+decf193 apply   -1.00000000001e-6176      -> #80000000000000000000000000000001  Subnormal Underflow Inexact Rounded
+decf194 apply   -1.00000000000001e-6176   -> #80000000000000000000000000000001  Subnormal Underflow Inexact Rounded
+decf195 apply   -1.000000000000001e-6176  -> #80000000000000000000000000000001  Subnormal Underflow Inexact Rounded
+decf196 apply   -0.1e-6176                -> #80000000000000000000000000000000  Subnormal Underflow Inexact Rounded
+decf197 apply   -0.00000000001e-6176      -> #80000000000000000000000000000000  Subnormal Underflow Inexact Rounded
+decf198 apply   -0.00000000000001e-6176   -> #80000000000000000000000000000000  Subnormal Underflow Inexact Rounded
+decf199 apply   -0.000000000000001e-6176  -> #80000000000000000000000000000000  Subnormal Underflow Inexact Rounded
+decf200 apply   -999999999999999999999999999999999e-6176 -> #80000ff3fcff3fcff3fcff3fcff3fcff  Subnormal
+
+-- zeros
+decf400 apply   0E-8000                 -> #00000000000000000000000000000000  Clamped
+decf401 apply   0E-6177                 -> #00000000000000000000000000000000  Clamped
+decf402 apply   0E-6176                 -> #00000000000000000000000000000000
+decf403 apply   #00000000000000000000000000000000       -> 0E-6176
+decf404 apply   0.000000000000000000000000000000000E-6143  -> #00000000000000000000000000000000
+decf405 apply   #00000000000000000000000000000000       -> 0E-6176
+decf406 apply   0E-2                    -> #22078000000000000000000000000000
+decf407 apply   #22078000000000000000000000000000       -> 0.00
+decf408 apply   0                       -> #22080000000000000000000000000000
+decf409 apply   #22080000000000000000000000000000       -> 0
+decf410 apply   0E+3                    -> #2208c000000000000000000000000000
+decf411 apply   #2208c000000000000000000000000000       -> 0E+3
+decf412 apply   0E+6111                 -> #43ffc000000000000000000000000000
+decf413 apply   #43ffc000000000000000000000000000       -> 0E+6111
+-- clamped zeros...
+decf414 apply   0E+6112                 -> #43ffc000000000000000000000000000  Clamped
+decf415 apply   #43ffc000000000000000000000000000       -> 0E+6111
+decf416 apply   0E+6144                 -> #43ffc000000000000000000000000000  Clamped
+decf417 apply   #43ffc000000000000000000000000000       -> 0E+6111
+decf418 apply   0E+8000                 -> #43ffc000000000000000000000000000  Clamped
+decf419 apply   #43ffc000000000000000000000000000       -> 0E+6111
+
+-- negative zeros
+decf420 apply  -0E-8000                 -> #80000000000000000000000000000000  Clamped
+decf421 apply  -0E-6177                 -> #80000000000000000000000000000000  Clamped
+decf422 apply  -0E-6176                 -> #80000000000000000000000000000000
+decf423 apply   #80000000000000000000000000000000       -> -0E-6176
+decf424 apply  -0.000000000000000000000000000000000E-6143  -> #80000000000000000000000000000000
+decf425 apply   #80000000000000000000000000000000       -> -0E-6176
+decf426 apply  -0E-2                    -> #a2078000000000000000000000000000
+decf427 apply   #a2078000000000000000000000000000       -> -0.00
+decf428 apply  -0                       -> #a2080000000000000000000000000000
+decf429 apply   #a2080000000000000000000000000000       -> -0
+decf430 apply  -0E+3                    -> #a208c000000000000000000000000000
+decf431 apply   #a208c000000000000000000000000000       -> -0E+3
+decf432 apply  -0E+6111                 -> #c3ffc000000000000000000000000000
+decf433 apply   #c3ffc000000000000000000000000000       -> -0E+6111
+-- clamped zeros...
+decf434 apply  -0E+6112                 -> #c3ffc000000000000000000000000000  Clamped
+decf435 apply   #c3ffc000000000000000000000000000       -> -0E+6111
+decf436 apply  -0E+6144                 -> #c3ffc000000000000000000000000000  Clamped
+decf437 apply   #c3ffc000000000000000000000000000       -> -0E+6111
+decf438 apply  -0E+8000                 -> #c3ffc000000000000000000000000000  Clamped
+decf439 apply   #c3ffc000000000000000000000000000       -> -0E+6111
+
+-- Specials
+decf500 apply   Infinity                          -> #78000000000000000000000000000000
+decf501 apply   #78787878787878787878787878787878 -> #78000000000000000000000000000000
+decf502 apply   #78000000000000000000000000000000 -> Infinity
+decf503 apply   #79797979797979797979797979797979 -> #78000000000000000000000000000000
+decf504 apply   #79000000000000000000000000000000 -> Infinity
+decf505 apply   #7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a -> #78000000000000000000000000000000
+decf506 apply   #7a000000000000000000000000000000 -> Infinity
+decf507 apply   #7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b -> #78000000000000000000000000000000
+decf508 apply   #7b000000000000000000000000000000 -> Infinity
+
+decf509 apply   NaN                               -> #7c000000000000000000000000000000
+decf510 apply   #7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c -> #7c003c7c7c7c7c7c7c7c7c7c7c7c7c7c
+decf511 apply   #7c000000000000000000000000000000 -> NaN
+decf512 apply   #7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d -> #7c003d7d7d7d7d7d7d7d7d7d7d7d7d7d
+decf513 apply   #7d000000000000000000000000000000 -> NaN
+decf514 apply   #7e7e7e7e7e7e7e7e7e7e7e7e7e7e7e7e -> #7e003e7e7c7e7e7e7e7c7e7e7e7e7c7e
+decf515 apply   #7e000000000000000000000000000000 -> sNaN
+decf516 apply   #7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f -> #7e003f7f7c7f7f7f7f7c7f7f7f7f7c7f
+decf517 apply   #7f000000000000000000000000000000 -> sNaN
+decf518 apply   #7fffffffffffffffffffffffffffffff -> sNaN999999999999999999999999999999999
+decf519 apply   #7fffffffffffffffffffffffffffffff -> #7e000ff3fcff3fcff3fcff3fcff3fcff
+
+decf520 apply   -Infinity                         -> #f8000000000000000000000000000000
+decf521 apply   #f8787878787878787878787878787878 -> #f8000000000000000000000000000000
+decf522 apply   #f8000000000000000000000000000000 -> -Infinity
+decf523 apply   #f9797979797979797979797979797979 -> #f8000000000000000000000000000000
+decf524 apply   #f9000000000000000000000000000000 -> -Infinity
+decf525 apply   #fa7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a -> #f8000000000000000000000000000000
+decf526 apply   #fa000000000000000000000000000000 -> -Infinity
+decf527 apply   #fb7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b -> #f8000000000000000000000000000000
+decf528 apply   #fb000000000000000000000000000000 -> -Infinity
+
+decf529 apply   -NaN                              -> #fc000000000000000000000000000000
+decf530 apply   #fc7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c -> #fc003c7c7c7c7c7c7c7c7c7c7c7c7c7c
+decf531 apply   #fc000000000000000000000000000000 -> -NaN
+decf532 apply   #fd7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d -> #fc003d7d7d7d7d7d7d7d7d7d7d7d7d7d
+decf533 apply   #fd000000000000000000000000000000 -> -NaN
+decf534 apply   #fe7e7e7e7e7e7e7e7e7e7e7e7e7e7e7e -> #fe003e7e7c7e7e7e7e7c7e7e7e7e7c7e
+decf535 apply   #fe000000000000000000000000000000 -> -sNaN
+decf536 apply   #ff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f -> #fe003f7f7c7f7f7f7f7c7f7f7f7f7c7f
+decf537 apply   #ff000000000000000000000000000000 -> -sNaN
+decf538 apply   #ffffffffffffffffffffffffffffffff -> -sNaN999999999999999999999999999999999
+decf539 apply   #ffffffffffffffffffffffffffffffff -> #fe000ff3fcff3fcff3fcff3fcff3fcff
+
+decf540 apply   NaN               -> #7c000000000000000000000000000000
+decf541 apply   NaN0              -> #7c000000000000000000000000000000
+decf542 apply   NaN1              -> #7c000000000000000000000000000001
+decf543 apply   NaN12             -> #7c000000000000000000000000000012
+decf544 apply   NaN79             -> #7c000000000000000000000000000079
+decf545 apply   NaN12345          -> #7c0000000000000000000000000049c5
+decf546 apply   NaN123456         -> #7c000000000000000000000000028e56
+decf547 apply   NaN799799         -> #7c0000000000000000000000000f7fdf
+decf548 apply   NaN799799799799799799799799799799799  -> #7c003dff7fdff7fdff7fdff7fdff7fdf
+decf549 apply   NaN999999999999999999999999999999999  -> #7c000ff3fcff3fcff3fcff3fcff3fcff
+decf550 apply   NaN1234567890123456789012345678901234 -> #7c000000000000000000000000000000  -- too many digits
+
+-- fold-down full sequence
+decf600 apply   1E+6145                 -> #78000000000000000000000000000000 Overflow Inexact Rounded
+decf601 apply   1E+6144                 -> #47ffc000000000000000000000000000 Clamped
+decf602 apply   #47ffc000000000000000000000000000       -> 1.000000000000000000000000000000000E+6144
+decf603 apply   1E+6143                 -> #43ffc800000000000000000000000000 Clamped
+decf604 apply   #43ffc800000000000000000000000000       -> 1.00000000000000000000000000000000E+6143
+decf605 apply   1E+6142                 -> #43ffc100000000000000000000000000 Clamped
+decf606 apply   #43ffc100000000000000000000000000       -> 1.0000000000000000000000000000000E+6142
+decf607 apply   1E+6141                 -> #43ffc010000000000000000000000000 Clamped
+decf608 apply   #43ffc010000000000000000000000000       -> 1.000000000000000000000000000000E+6141
+decf609 apply   1E+6140                 -> #43ffc002000000000000000000000000 Clamped
+decf610 apply   #43ffc002000000000000000000000000       -> 1.00000000000000000000000000000E+6140
+decf611 apply   1E+6139                 -> #43ffc000400000000000000000000000 Clamped
+decf612 apply   #43ffc000400000000000000000000000       -> 1.0000000000000000000000000000E+6139
+decf613 apply   1E+6138                 -> #43ffc000040000000000000000000000 Clamped
+decf614 apply   #43ffc000040000000000000000000000       -> 1.000000000000000000000000000E+6138
+decf615 apply   1E+6137                 -> #43ffc000008000000000000000000000 Clamped
+decf616 apply   #43ffc000008000000000000000000000       -> 1.00000000000000000000000000E+6137
+decf617 apply   1E+6136                 -> #43ffc000001000000000000000000000 Clamped
+decf618 apply   #43ffc000001000000000000000000000       -> 1.0000000000000000000000000E+6136
+decf619 apply   1E+6135                 -> #43ffc000000100000000000000000000 Clamped
+decf620 apply   #43ffc000000100000000000000000000       -> 1.000000000000000000000000E+6135
+decf621 apply   1E+6134                 -> #43ffc000000020000000000000000000 Clamped
+decf622 apply   #43ffc000000020000000000000000000       -> 1.00000000000000000000000E+6134
+decf623 apply   1E+6133                 -> #43ffc000000004000000000000000000 Clamped
+decf624 apply   #43ffc000000004000000000000000000       -> 1.0000000000000000000000E+6133
+decf625 apply   1E+6132                 -> #43ffc000000000400000000000000000 Clamped
+decf626 apply   #43ffc000000000400000000000000000       -> 1.000000000000000000000E+6132
+decf627 apply   1E+6131                 -> #43ffc000000000080000000000000000 Clamped
+decf628 apply   #43ffc000000000080000000000000000       -> 1.00000000000000000000E+6131
+decf629 apply   1E+6130                 -> #43ffc000000000010000000000000000 Clamped
+decf630 apply   #43ffc000000000010000000000000000       -> 1.0000000000000000000E+6130
+decf631 apply   1E+6129                 -> #43ffc000000000001000000000000000 Clamped
+decf632 apply   #43ffc000000000001000000000000000       -> 1.000000000000000000E+6129
+decf633 apply   1E+6128                 -> #43ffc000000000000200000000000000 Clamped
+decf634 apply   #43ffc000000000000200000000000000       -> 1.00000000000000000E+6128
+decf635 apply   1E+6127                 -> #43ffc000000000000040000000000000 Clamped
+decf636 apply   #43ffc000000000000040000000000000       -> 1.0000000000000000E+6127
+decf637 apply   1E+6126                 -> #43ffc000000000000004000000000000 Clamped
+decf638 apply   #43ffc000000000000004000000000000       -> 1.000000000000000E+6126
+decf639 apply   1E+6125                 -> #43ffc000000000000000800000000000 Clamped
+decf640 apply   #43ffc000000000000000800000000000       -> 1.00000000000000E+6125
+decf641 apply   1E+6124                 -> #43ffc000000000000000100000000000 Clamped
+decf642 apply   #43ffc000000000000000100000000000       -> 1.0000000000000E+6124
+decf643 apply   1E+6123                 -> #43ffc000000000000000010000000000 Clamped
+decf644 apply   #43ffc000000000000000010000000000       -> 1.000000000000E+6123
+decf645 apply   1E+6122                 -> #43ffc000000000000000002000000000 Clamped
+decf646 apply   #43ffc000000000000000002000000000       -> 1.00000000000E+6122
+decf647 apply   1E+6121                 -> #43ffc000000000000000000400000000 Clamped
+decf648 apply   #43ffc000000000000000000400000000       -> 1.0000000000E+6121
+decf649 apply   1E+6120                 -> #43ffc000000000000000000040000000 Clamped
+decf650 apply   #43ffc000000000000000000040000000       -> 1.000000000E+6120
+decf651 apply   1E+6119                 -> #43ffc000000000000000000008000000 Clamped
+decf652 apply   #43ffc000000000000000000008000000       -> 1.00000000E+6119
+decf653 apply   1E+6118                 -> #43ffc000000000000000000001000000 Clamped
+decf654 apply   #43ffc000000000000000000001000000       -> 1.0000000E+6118
+decf655 apply   1E+6117                 -> #43ffc000000000000000000000100000 Clamped
+decf656 apply   #43ffc000000000000000000000100000       -> 1.000000E+6117
+decf657 apply   1E+6116                 -> #43ffc000000000000000000000020000 Clamped
+decf658 apply   #43ffc000000000000000000000020000       -> 1.00000E+6116
+decf659 apply   1E+6115                 -> #43ffc000000000000000000000004000 Clamped
+decf660 apply   #43ffc000000000000000000000004000       -> 1.0000E+6115
+decf661 apply   1E+6114                 -> #43ffc000000000000000000000000400 Clamped
+decf662 apply   #43ffc000000000000000000000000400       -> 1.000E+6114
+decf663 apply   1E+6113                 -> #43ffc000000000000000000000000080 Clamped
+decf664 apply   #43ffc000000000000000000000000080       -> 1.00E+6113
+decf665 apply   1E+6112                 -> #43ffc000000000000000000000000010 Clamped
+decf666 apply   #43ffc000000000000000000000000010       -> 1.0E+6112
+decf667 apply   1E+6111                 -> #43ffc000000000000000000000000001
+decf668 apply   #43ffc000000000000000000000000001       -> 1E+6111
+decf669 apply   1E+6110                 -> #43ff8000000000000000000000000001
+decf670 apply   #43ff8000000000000000000000000001       -> 1E+6110
+
+-- Selected DPD codes
+decf700 apply   #22080000000000000000000000000000       -> 0
+decf701 apply   #22080000000000000000000000000009       -> 9
+decf702 apply   #22080000000000000000000000000010       -> 10
+decf703 apply   #22080000000000000000000000000019       -> 19
+decf704 apply   #22080000000000000000000000000020       -> 20
+decf705 apply   #22080000000000000000000000000029       -> 29
+decf706 apply   #22080000000000000000000000000030       -> 30
+decf707 apply   #22080000000000000000000000000039       -> 39
+decf708 apply   #22080000000000000000000000000040       -> 40
+decf709 apply   #22080000000000000000000000000049       -> 49
+decf710 apply   #22080000000000000000000000000050       -> 50
+decf711 apply   #22080000000000000000000000000059       -> 59
+decf712 apply   #22080000000000000000000000000060       -> 60
+decf713 apply   #22080000000000000000000000000069       -> 69
+decf714 apply   #22080000000000000000000000000070       -> 70
+decf715 apply   #22080000000000000000000000000071       -> 71
+decf716 apply   #22080000000000000000000000000072       -> 72
+decf717 apply   #22080000000000000000000000000073       -> 73
+decf718 apply   #22080000000000000000000000000074       -> 74
+decf719 apply   #22080000000000000000000000000075       -> 75
+decf720 apply   #22080000000000000000000000000076       -> 76
+decf721 apply   #22080000000000000000000000000077       -> 77
+decf722 apply   #22080000000000000000000000000078       -> 78
+decf723 apply   #22080000000000000000000000000079       -> 79
+
+decf730 apply   #2208000000000000000000000000029e       -> 994
+decf731 apply   #2208000000000000000000000000029f       -> 995
+decf732 apply   #220800000000000000000000000002a0       -> 520
+decf733 apply   #220800000000000000000000000002a1       -> 521
+
+-- DPD: one of each of the huffman groups
+decf740 apply   #220800000000000000000000000003f7       -> 777
+decf741 apply   #220800000000000000000000000003f8       -> 778
+decf742 apply   #220800000000000000000000000003eb       -> 787
+decf743 apply   #2208000000000000000000000000037d       -> 877
+decf744 apply   #2208000000000000000000000000039f       -> 997
+decf745 apply   #220800000000000000000000000003bf       -> 979
+decf746 apply   #220800000000000000000000000003df       -> 799
+decf747 apply   #2208000000000000000000000000006e       -> 888
+
+
+-- DPD all-highs cases (includes the 24 redundant codes)
+decf750 apply   #2208000000000000000000000000006e       -> 888
+decf751 apply   #2208000000000000000000000000016e       -> 888
+decf752 apply   #2208000000000000000000000000026e       -> 888
+decf753 apply   #2208000000000000000000000000036e       -> 888
+decf754 apply   #2208000000000000000000000000006f       -> 889
+decf755 apply   #2208000000000000000000000000016f       -> 889
+decf756 apply   #2208000000000000000000000000026f       -> 889
+decf757 apply   #2208000000000000000000000000036f       -> 889
+
+decf760 apply   #2208000000000000000000000000007e       -> 898
+decf761 apply   #2208000000000000000000000000017e       -> 898
+decf762 apply   #2208000000000000000000000000027e       -> 898
+decf763 apply   #2208000000000000000000000000037e       -> 898
+decf764 apply   #2208000000000000000000000000007f       -> 899
+decf765 apply   #2208000000000000000000000000017f       -> 899
+decf766 apply   #2208000000000000000000000000027f       -> 899
+decf767 apply   #2208000000000000000000000000037f       -> 899
+
+decf770 apply   #220800000000000000000000000000ee       -> 988
+decf771 apply   #220800000000000000000000000001ee       -> 988
+decf772 apply   #220800000000000000000000000002ee       -> 988
+decf773 apply   #220800000000000000000000000003ee       -> 988
+decf774 apply   #220800000000000000000000000000ef       -> 989
+decf775 apply   #220800000000000000000000000001ef       -> 989
+decf776 apply   #220800000000000000000000000002ef       -> 989
+decf777 apply   #220800000000000000000000000003ef       -> 989
+
+decf780 apply   #220800000000000000000000000000fe       -> 998
+decf781 apply   #220800000000000000000000000001fe       -> 998
+decf782 apply   #220800000000000000000000000002fe       -> 998
+decf783 apply   #220800000000000000000000000003fe       -> 998
+decf784 apply   #220800000000000000000000000000ff       -> 999
+decf785 apply   #220800000000000000000000000001ff       -> 999
+decf786 apply   #220800000000000000000000000002ff       -> 999
+decf787 apply   #220800000000000000000000000003ff       -> 999
+

Added: vendor/Python/current/Lib/test/decimaltestdata/decimal32.decTest
===================================================================
--- vendor/Python/current/Lib/test/decimaltestdata/decimal32.decTest	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/decimaltestdata/decimal32.decTest	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,385 @@
+------------------------------------------------------------------------
+-- decimal32.decTest -- decimal four-byte format testcases            --
+-- Copyright (c) IBM Corporation, 2000, 2003.  All rights reserved.   --
+------------------------------------------------------------------------
+-- Please see the document "General Decimal Arithmetic Testcases"     --
+-- at http://www2.hursley.ibm.com/decimal for the description of      --
+-- these testcases.                                                   --
+--                                                                    --
+-- These testcases are experimental ('beta' versions), and they       --
+-- may contain errors.  They are offered on an as-is basis.  In       --
+-- particular, achieving the same results as the tests here is not    --
+-- a guarantee that an implementation complies with any Standard      --
+-- or specification.  The tests are not exhaustive.                   --
+--                                                                    --
+-- Please send comments, suggestions, and corrections to the author:  --
+--   Mike Cowlishaw, IBM Fellow                                       --
+--   IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK         --
+--   mfc at uk.ibm.com                                                   --
+------------------------------------------------------------------------
+version: 2.39
+
+-- This set of tests is for the four-byte concrete representation.
+-- Its characteristics are:
+--
+--  1 bit  sign
+--  5 bits combination field
+--  6 bits exponent continuation
+-- 20 bits coefficient continuation
+--
+-- Total exponent length 8 bits
+-- Total coefficient length 24 bits (7 digits)
+--
+-- Elimit =  191 (maximum encoded exponent)
+-- Emax   =   96 (largest exponent value)
+-- Emin   =  -95 (smallest exponent value)
+-- bias   =  101 (subtracted from encoded exponent) = -Etiny
+
+extended:    1
+precision:   7
+rounding:    half_up
+maxExponent: 96
+minExponent: -95
+
+-- General testcases
+-- (mostly derived from the Strawman 4 document and examples)
+decd001 apply   #A23003D0          -> -7.50
+decd002 apply   -7.50              -> #A23003D0
+
+-- Normality
+decd010 apply   1234567            -> #2654d2e7
+decd011 apply   1234567.0          -> #2654d2e7 Rounded
+decd012 apply   1234567.1          -> #2654d2e7 Rounded Inexact
+decd013 apply  -1234567            -> #a654d2e7
+decd014 apply  -1234567.0          -> #a654d2e7 Rounded
+decd015 apply  -1234567.1          -> #a654d2e7 Rounded Inexact
+
+
+-- Nmax and similar
+decd022 apply   9.999999E+96            -> #77f3fcff
+decd023 apply   #77f3fcff               -> 9.999999E+96
+decd024 apply   1.234567E+96            -> #47f4d2e7
+decd025 apply   #47f4d2e7               -> 1.234567E+96
+-- fold-downs (more below)
+decd030 apply   1.23E+96                -> #47f4c000 Clamped
+decd031 apply   #47f4c000               -> 1.230000E+96
+decd032 apply   1E+96                   -> #47f00000 Clamped
+decd033 apply   #47f00000               -> 1.000000E+96
+
+-- overflows
+maxExponent: 999   -- set high so conversion causes the overflow
+minExponent: -999
+decd040 apply   10E+96                  -> #78000000 Overflow Rounded Inexact
+decd041 apply   1.000000E+97            -> #78000000 Overflow Rounded Inexact
+maxExponent: 96
+minExponent: -95
+
+decd051 apply   12345                   -> #225049c5
+decd052 apply   #225049c5               -> 12345
+decd053 apply   1234                    -> #22500534
+decd054 apply   #22500534               -> 1234
+decd055 apply   123                     -> #225000a3
+decd056 apply   #225000a3               -> 123
+decd057 apply   12                      -> #22500012
+decd058 apply   #22500012               -> 12
+decd059 apply   1                       -> #22500001
+decd060 apply   #22500001               -> 1
+decd061 apply   1.23                    -> #223000a3
+decd062 apply   #223000a3               -> 1.23
+decd063 apply   123.45                  -> #223049c5
+decd064 apply   #223049c5               -> 123.45
+
+-- Nmin and below
+decd071 apply   1E-95                   -> #00600001
+decd072 apply   #00600001               -> 1E-95
+decd073 apply   1.000000E-95            -> #04000000
+decd074 apply   #04000000               -> 1.000000E-95
+decd075 apply   1.000001E-95            -> #04000001
+decd076 apply   #04000001               -> 1.000001E-95
+
+decd077 apply   0.100000E-95            -> #00020000     Subnormal
+decd07x apply   1.00000E-96             -> 1.00000E-96   Subnormal
+decd078 apply   #00020000               -> 1.00000E-96   Subnormal
+decd079 apply   0.000010E-95            -> #00000010     Subnormal
+decd080 apply   #00000010               -> 1.0E-100      Subnormal
+decd081 apply   0.000001E-95            -> #00000001     Subnormal
+decd082 apply   #00000001               -> 1E-101        Subnormal
+decd083 apply   1e-101                  -> #00000001     Subnormal
+decd084 apply   #00000001               -> 1E-101        Subnormal
+decd08x apply   1e-101                  -> 1E-101        Subnormal
+
+-- underflows
+decd090 apply   1e-101                  -> #00000001  Subnormal
+decd091 apply   1.9e-101                -> #00000002  Subnormal Underflow Inexact Rounded
+decd092 apply   1.1e-101                -> #00000001  Subnormal Underflow Inexact Rounded
+decd093 apply   1.001e-101              -> #00000001  Subnormal Underflow Inexact Rounded
+decd094 apply   1.000001e-101           -> #00000001  Subnormal Underflow Inexact Rounded
+decd095 apply   1.0000001e-101          -> #00000001  Subnormal Underflow Inexact Rounded
+decd096 apply   0.1e-101                -> #00000000  Subnormal Underflow Inexact Rounded
+decd097 apply   0.001e-101              -> #00000000  Subnormal Underflow Inexact Rounded
+decd098 apply   0.000001e-101           -> #00000000  Subnormal Underflow Inexact Rounded
+decd099 apply   0.0000001e-101          -> #00000000  Subnormal Underflow Inexact Rounded
+
+-- same again, negatives --
+
+-- Nmax and similar
+decd122 apply  -9.999999E+96            -> #f7f3fcff
+decd123 apply   #f7f3fcff               -> -9.999999E+96
+decd124 apply  -1.234567E+96            -> #c7f4d2e7
+decd125 apply   #c7f4d2e7               -> -1.234567E+96
+-- fold-downs (more below)
+decd130 apply  -1.23E+96                -> #c7f4c000 Clamped
+decd131 apply   #c7f4c000               -> -1.230000E+96
+decd132 apply  -1E+96                   -> #c7f00000 Clamped
+decd133 apply   #c7f00000               -> -1.000000E+96
+
+-- overflows
+maxExponent: 999   -- set high so conversion causes the overflow
+minExponent: -999
+decd140 apply  -10E+96                  -> #f8000000 Overflow Rounded Inexact
+decd141 apply  -1.000000E+97            -> #f8000000 Overflow Rounded Inexact
+maxExponent: 96
+minExponent: -95
+
+decd151 apply  -12345                   -> #a25049c5
+decd152 apply   #a25049c5               -> -12345
+decd153 apply  -1234                    -> #a2500534
+decd154 apply   #a2500534               -> -1234
+decd155 apply  -123                     -> #a25000a3
+decd156 apply   #a25000a3               -> -123
+decd157 apply  -12                      -> #a2500012
+decd158 apply   #a2500012               -> -12
+decd159 apply  -1                       -> #a2500001
+decd160 apply   #a2500001               -> -1
+decd161 apply  -1.23                    -> #a23000a3
+decd162 apply   #a23000a3               -> -1.23
+decd163 apply  -123.45                  -> #a23049c5
+decd164 apply   #a23049c5               -> -123.45
+
+-- Nmin and below
+decd171 apply  -1E-95                   -> #80600001
+decd172 apply   #80600001               -> -1E-95
+decd173 apply  -1.000000E-95            -> #84000000
+decd174 apply   #84000000               -> -1.000000E-95
+decd175 apply  -1.000001E-95            -> #84000001
+decd176 apply   #84000001               -> -1.000001E-95
+
+decd177 apply  -0.100000E-95            -> #80020000     Subnormal
+decd178 apply   #80020000               -> -1.00000E-96  Subnormal
+decd179 apply  -0.000010E-95            -> #80000010     Subnormal
+decd180 apply   #80000010               -> -1.0E-100     Subnormal
+decd181 apply  -0.000001E-95            -> #80000001     Subnormal
+decd182 apply   #80000001               -> -1E-101       Subnormal
+decd183 apply  -1e-101                  -> #80000001     Subnormal
+decd184 apply   #80000001               -> -1E-101       Subnormal
+
+-- underflows
+decd190 apply  -1e-101                  -> #80000001  Subnormal
+decd191 apply  -1.9e-101                -> #80000002  Subnormal Underflow Inexact Rounded
+decd192 apply  -1.1e-101                -> #80000001  Subnormal Underflow Inexact Rounded
+decd193 apply  -1.001e-101              -> #80000001  Subnormal Underflow Inexact Rounded
+decd194 apply  -1.000001e-101           -> #80000001  Subnormal Underflow Inexact Rounded
+decd195 apply  -1.0000001e-101          -> #80000001  Subnormal Underflow Inexact Rounded
+decd196 apply  -0.1e-101                -> #80000000  Subnormal Underflow Inexact Rounded
+decd197 apply  -0.001e-101              -> #80000000  Subnormal Underflow Inexact Rounded
+decd198 apply  -0.000001e-101           -> #80000000  Subnormal Underflow Inexact Rounded
+decd199 apply  -0.0000001e-101          -> #80000000  Subnormal Underflow Inexact Rounded
+
+-- zeros
+decd400 apply   0E-400                  -> #00000000  Clamped
+decd401 apply   0E-101                  -> #00000000
+decd402 apply   #00000000               -> 0E-101
+decd403 apply   0.000000E-95            -> #00000000
+decd404 apply   #00000000               -> 0E-101
+decd405 apply   0E-2                    -> #22300000
+decd406 apply   #22300000               -> 0.00
+decd407 apply   0                       -> #22500000
+decd408 apply   #22500000               -> 0
+decd409 apply   0E+3                    -> #22800000
+decd410 apply   #22800000               -> 0E+3
+decd411 apply   0E+90                   -> #43f00000
+decd412 apply   #43f00000               -> 0E+90
+-- clamped zeros...
+decd413 apply   0E+91                   -> #43f00000  Clamped
+decd414 apply   #43f00000               -> 0E+90
+decd415 apply   0E+96                   -> #43f00000  Clamped
+decd416 apply   #43f00000               -> 0E+90
+decd417 apply   0E+400                  -> #43f00000  Clamped
+decd418 apply   #43f00000               -> 0E+90
+
+-- negative zeros
+decd420 apply   -0E-400                 -> #80000000  Clamped
+decd421 apply   -0E-101                 -> #80000000
+decd422 apply   #80000000               -> -0E-101
+decd423 apply   -0.000000E-95           -> #80000000
+decd424 apply   #80000000               -> -0E-101
+decd425 apply   -0E-2                   -> #a2300000
+decd426 apply   #a2300000               -> -0.00
+decd427 apply   -0                      -> #a2500000
+decd428 apply   #a2500000               -> -0
+decd429 apply   -0E+3                   -> #a2800000
+decd430 apply   #a2800000               -> -0E+3
+decd431 apply   -0E+90                  -> #c3f00000
+decd432 apply   #c3f00000               -> -0E+90
+-- clamped zeros...
+decd433 apply   -0E+91                  -> #c3f00000  Clamped
+decd434 apply   #c3f00000               -> -0E+90
+decd435 apply   -0E+96                  -> #c3f00000  Clamped
+decd436 apply   #c3f00000               -> -0E+90
+decd437 apply   -0E+400                 -> #c3f00000  Clamped
+decd438 apply   #c3f00000               -> -0E+90
+
+-- Specials
+decd500 apply   Infinity  -> #78000000
+decd501 apply   #78787878 -> #78000000
+decd502 apply   #78000000 -> Infinity
+decd503 apply   #79797979 -> #78000000
+decd504 apply   #79000000 -> Infinity
+decd505 apply   #7a7a7a7a -> #78000000
+decd506 apply   #7a000000 -> Infinity
+decd507 apply   #7b7b7b7b -> #78000000
+decd508 apply   #7b000000 -> Infinity
+decd509 apply   #7c7c7c7c -> #7c0c7c7c
+
+decd510 apply   NaN       -> #7c000000
+decd511 apply   #7c000000 -> NaN
+decd512 apply   #7d7d7d7d -> #7c0d7d7d
+decd513 apply   #7d000000 -> NaN
+decd514 apply   #7e7e7e7e -> #7e0e7c7e
+decd515 apply   #7e000000 -> sNaN
+decd516 apply   #7f7f7f7f -> #7e0f7c7f
+decd517 apply   #7f000000 -> sNaN
+decd518 apply   #7fffffff -> sNaN999999
+decd519 apply   #7fffffff -> #7e03fcff
+
+decd520 apply   -Infinity -> #f8000000
+decd521 apply   #f8787878 -> #f8000000
+decd522 apply   #f8000000 -> -Infinity
+decd523 apply   #f9797979 -> #f8000000
+decd524 apply   #f9000000 -> -Infinity
+decd525 apply   #fa7a7a7a -> #f8000000
+decd526 apply   #fa000000 -> -Infinity
+decd527 apply   #fb7b7b7b -> #f8000000
+decd528 apply   #fb000000 -> -Infinity
+
+decd529 apply   -NaN      -> #fc000000
+decd530 apply   #fc7c7c7c -> #fc0c7c7c
+decd531 apply   #fc000000 -> -NaN
+decd532 apply   #fd7d7d7d -> #fc0d7d7d
+decd533 apply   #fd000000 -> -NaN
+decd534 apply   #fe7e7e7e -> #fe0e7c7e
+decd535 apply   #fe000000 -> -sNaN
+decd536 apply   #ff7f7f7f -> #fe0f7c7f
+decd537 apply   #ff000000 -> -sNaN
+decd538 apply   #ffffffff -> -sNaN999999
+decd539 apply   #ffffffff -> #fe03fcff
+
+-- diagnostic NaNs
+decd540 apply   NaN       -> #7c000000
+decd541 apply   NaN0      -> #7c000000
+decd542 apply   NaN1      -> #7c000001
+decd543 apply   NaN12     -> #7c000012
+decd544 apply   NaN79     -> #7c000079
+decd545 apply   NaN12345   -> #7c0049c5
+decd546 apply   NaN123456  -> #7c028e56
+decd547 apply   NaN799799  -> #7c0f7fdf
+decd548 apply   NaN999999  -> #7c03fcff
+decd549 apply   NaN1234567 -> #7c000000  -- too many digits
+
+
+-- fold-down full sequence
+decd601 apply   1E+96                   -> #47f00000 Clamped
+decd602 apply   #47f00000               -> 1.000000E+96
+decd603 apply   1E+95                   -> #43f20000 Clamped
+decd604 apply   #43f20000               -> 1.00000E+95
+decd605 apply   1E+94                   -> #43f04000 Clamped
+decd606 apply   #43f04000               -> 1.0000E+94
+decd607 apply   1E+93                   -> #43f00400 Clamped
+decd608 apply   #43f00400               -> 1.000E+93
+decd609 apply   1E+92                   -> #43f00080 Clamped
+decd610 apply   #43f00080               -> 1.00E+92
+decd611 apply   1E+91                   -> #43f00010 Clamped
+decd612 apply   #43f00010               -> 1.0E+91
+decd613 apply   1E+90                   -> #43f00001
+decd614 apply   #43f00001               -> 1E+90
+
+
+-- Selected DPD codes
+decd700 apply   #22500000       -> 0
+decd701 apply   #22500009       -> 9
+decd702 apply   #22500010       -> 10
+decd703 apply   #22500019       -> 19
+decd704 apply   #22500020       -> 20
+decd705 apply   #22500029       -> 29
+decd706 apply   #22500030       -> 30
+decd707 apply   #22500039       -> 39
+decd708 apply   #22500040       -> 40
+decd709 apply   #22500049       -> 49
+decd710 apply   #22500050       -> 50
+decd711 apply   #22500059       -> 59
+decd712 apply   #22500060       -> 60
+decd713 apply   #22500069       -> 69
+decd714 apply   #22500070       -> 70
+decd715 apply   #22500071       -> 71
+decd716 apply   #22500072       -> 72
+decd717 apply   #22500073       -> 73
+decd718 apply   #22500074       -> 74
+decd719 apply   #22500075       -> 75
+decd720 apply   #22500076       -> 76
+decd721 apply   #22500077       -> 77
+decd722 apply   #22500078       -> 78
+decd723 apply   #22500079       -> 79
+
+decd730 apply   #2250029e       -> 994
+decd731 apply   #2250029f       -> 995
+decd732 apply   #225002a0       -> 520
+decd733 apply   #225002a1       -> 521
+
+-- DPD: one of each of the huffman groups
+decd740 apply   #225003f7       -> 777
+decd741 apply   #225003f8       -> 778
+decd742 apply   #225003eb       -> 787
+decd743 apply   #2250037d       -> 877
+decd744 apply   #2250039f       -> 997
+decd745 apply   #225003bf       -> 979
+decd746 apply   #225003df       -> 799
+decd747 apply   #2250006e       -> 888
+
+
+-- DPD all-highs cases (includes the 24 redundant codes)
+decd750 apply   #2250006e       -> 888
+decd751 apply   #2250016e       -> 888
+decd752 apply   #2250026e       -> 888
+decd753 apply   #2250036e       -> 888
+decd754 apply   #2250006f       -> 889
+decd755 apply   #2250016f       -> 889
+decd756 apply   #2250026f       -> 889
+decd757 apply   #2250036f       -> 889
+
+decd760 apply   #2250007e       -> 898
+decd761 apply   #2250017e       -> 898
+decd762 apply   #2250027e       -> 898
+decd763 apply   #2250037e       -> 898
+decd764 apply   #2250007f       -> 899
+decd765 apply   #2250017f       -> 899
+decd766 apply   #2250027f       -> 899
+decd767 apply   #2250037f       -> 899
+
+decd770 apply   #225000ee       -> 988
+decd771 apply   #225001ee       -> 988
+decd772 apply   #225002ee       -> 988
+decd773 apply   #225003ee       -> 988
+decd774 apply   #225000ef       -> 989
+decd775 apply   #225001ef       -> 989
+decd776 apply   #225002ef       -> 989
+decd777 apply   #225003ef       -> 989
+
+decd780 apply   #225000fe       -> 998
+decd781 apply   #225001fe       -> 998
+decd782 apply   #225002fe       -> 998
+decd783 apply   #225003fe       -> 998
+decd784 apply   #225000ff       -> 999
+decd785 apply   #225001ff       -> 999
+decd786 apply   #225002ff       -> 999
+decd787 apply   #225003ff       -> 999
+

Added: vendor/Python/current/Lib/test/decimaltestdata/decimal64.decTest
===================================================================
--- vendor/Python/current/Lib/test/decimaltestdata/decimal64.decTest	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/decimaltestdata/decimal64.decTest	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,444 @@
+------------------------------------------------------------------------
+-- decimal64.decTest -- decimal eight-byte format testcases           --
+-- Copyright (c) IBM Corporation, 2000, 2003.  All rights reserved.   --
+------------------------------------------------------------------------
+-- Please see the document "General Decimal Arithmetic Testcases"     --
+-- at http://www2.hursley.ibm.com/decimal for the description of      --
+-- these testcases.                                                   --
+--                                                                    --
+-- These testcases are experimental ('beta' versions), and they       --
+-- may contain errors.  They are offered on an as-is basis.  In       --
+-- particular, achieving the same results as the tests here is not    --
+-- a guarantee that an implementation complies with any Standard      --
+-- or specification.  The tests are not exhaustive.                   --
+--                                                                    --
+-- Please send comments, suggestions, and corrections to the author:  --
+--   Mike Cowlishaw, IBM Fellow                                       --
+--   IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK         --
+--   mfc at uk.ibm.com                                                   --
+------------------------------------------------------------------------
+version: 2.39
+
+-- This set of tests is for the eight-byte concrete representation.
+-- Its characteristics are:
+--
+--  1 bit  sign
+--  5 bits combination field
+--  8 bits exponent continuation
+-- 50 bits coefficient continuation
+--
+-- Total exponent length 10 bits
+-- Total coefficient length 54 bits (16 digits)
+--
+-- Elimit =  767 (maximum encoded exponent)
+-- Emax   =  384 (largest exponent value)
+-- Emin   = -383 (smallest exponent value)
+-- bias   =  398 (subtracted from encoded exponent) = -Etiny
+
+extended:    1
+precision:   16
+rounding:    half_up
+maxExponent: 384
+minExponent: -383
+
+-- General testcases
+-- (mostly derived from the Strawman 4 document and examples)
+dece001 apply   #A2300000000003D0 -> -7.50
+dece002 apply   -7.50             -> #A2300000000003D0
+
+-- Normality
+dece010 apply   1234567890123456   -> #263934b9c1e28e56
+dece011 apply   1234567890123456.0 -> #263934b9c1e28e56 Rounded
+dece012 apply   1234567890123456.1 -> #263934b9c1e28e56 Rounded Inexact
+dece013 apply  -1234567890123456   -> #a63934b9c1e28e56
+dece014 apply  -1234567890123456.0 -> #a63934b9c1e28e56 Rounded
+dece015 apply  -1234567890123456.1 -> #a63934b9c1e28e56 Rounded Inexact
+
+
+-- Nmax and similar
+dece022 apply   9.999999999999999E+384  -> #77fcff3fcff3fcff
+dece023 apply   #77fcff3fcff3fcff       -> 9.999999999999999E+384
+dece024 apply   1.234567890123456E+384  -> #47fd34b9c1e28e56
+dece025 apply   #47fd34b9c1e28e56       -> 1.234567890123456E+384
+-- fold-downs (more below)
+dece030 apply   1.23E+384               -> #47fd300000000000 Clamped
+dece031 apply   #47fd300000000000       -> 1.230000000000000E+384
+dece032 apply   1E+384                  -> #47fc000000000000 Clamped
+dece033 apply   #47fc000000000000       -> 1.000000000000000E+384
+
+-- overflows
+maxExponent: 999   -- set high so conversion causes the overflow
+minExponent: -999
+dece040 apply   10E+384                 -> #7800000000000000 Overflow Rounded Inexact
+dece041 apply   1.000000000000000E+385  -> #7800000000000000 Overflow Rounded Inexact
+maxExponent: 384
+minExponent: -383
+
+dece051 apply   12345                   -> #22380000000049c5
+dece052 apply   #22380000000049c5       -> 12345
+dece053 apply   1234                    -> #2238000000000534
+dece054 apply   #2238000000000534       -> 1234
+dece055 apply   123                     -> #22380000000000a3
+dece056 apply   #22380000000000a3       -> 123
+dece057 apply   12                      -> #2238000000000012
+dece058 apply   #2238000000000012       -> 12
+dece059 apply   1                       -> #2238000000000001
+dece060 apply   #2238000000000001       -> 1
+dece061 apply   1.23                    -> #22300000000000a3
+dece062 apply   #22300000000000a3       -> 1.23
+dece063 apply   123.45                  -> #22300000000049c5
+dece064 apply   #22300000000049c5       -> 123.45
+
+-- Nmin and below
+dece071 apply   1E-383                  -> #003c000000000001
+dece072 apply   #003c000000000001       -> 1E-383
+dece073 apply   1.000000000000000E-383  -> #0400000000000000
+dece074 apply   #0400000000000000       -> 1.000000000000000E-383
+dece075 apply   1.000000000000001E-383  -> #0400000000000001
+dece076 apply   #0400000000000001       -> 1.000000000000001E-383
+
+dece077 apply   0.100000000000000E-383  -> #0000800000000000      Subnormal
+dece078 apply   #0000800000000000       -> 1.00000000000000E-384  Subnormal
+dece079 apply   0.000000000000010E-383  -> #0000000000000010      Subnormal
+dece080 apply   #0000000000000010       -> 1.0E-397               Subnormal
+dece081 apply   0.00000000000001E-383   -> #0004000000000001      Subnormal
+dece082 apply   #0004000000000001       -> 1E-397                 Subnormal
+dece083 apply   0.000000000000001E-383  -> #0000000000000001      Subnormal
+dece084 apply   #0000000000000001       -> 1E-398                 Subnormal
+
+-- underflows
+dece090 apply   1e-398                  -> #0000000000000001  Subnormal
+dece091 apply   1.9e-398                -> #0000000000000002  Subnormal Underflow Inexact Rounded
+dece092 apply   1.1e-398                -> #0000000000000001  Subnormal Underflow Inexact Rounded
+dece093 apply   1.00000000001e-398      -> #0000000000000001  Subnormal Underflow Inexact Rounded
+dece094 apply   1.00000000000001e-398   -> #0000000000000001  Subnormal Underflow Inexact Rounded
+dece095 apply   1.000000000000001e-398  -> #0000000000000001  Subnormal Underflow Inexact Rounded
+dece096 apply   0.1e-398                -> #0000000000000000  Subnormal Underflow Inexact Rounded
+dece097 apply   0.00000000001e-398      -> #0000000000000000  Subnormal Underflow Inexact Rounded
+dece098 apply   0.00000000000001e-398   -> #0000000000000000  Subnormal Underflow Inexact Rounded
+dece099 apply   0.000000000000001e-398  -> #0000000000000000  Subnormal Underflow Inexact Rounded
+
+-- Same again, negatives
+-- Nmax and similar
+dece122 apply  -9.999999999999999E+384  -> #f7fcff3fcff3fcff
+dece123 apply   #f7fcff3fcff3fcff       -> -9.999999999999999E+384
+dece124 apply  -1.234567890123456E+384  -> #c7fd34b9c1e28e56
+dece125 apply   #c7fd34b9c1e28e56       -> -1.234567890123456E+384
+-- fold-downs (more below)
+dece130 apply  -1.23E+384               -> #c7fd300000000000 Clamped
+dece131 apply   #c7fd300000000000       -> -1.230000000000000E+384
+dece132 apply  -1E+384                  -> #c7fc000000000000 Clamped
+dece133 apply   #c7fc000000000000       -> -1.000000000000000E+384
+
+-- overflows
+maxExponent: 999   -- set high so conversion causes the overflow
+minExponent: -999
+dece140 apply  -10E+384                 -> #f800000000000000 Overflow Rounded Inexact
+dece141 apply  -1.000000000000000E+385  -> #f800000000000000 Overflow Rounded Inexact
+maxExponent: 384
+minExponent: -383
+
+dece151 apply  -12345                   -> #a2380000000049c5
+dece152 apply   #a2380000000049c5       -> -12345
+dece153 apply  -1234                    -> #a238000000000534
+dece154 apply   #a238000000000534       -> -1234
+dece155 apply  -123                     -> #a2380000000000a3
+dece156 apply   #a2380000000000a3       -> -123
+dece157 apply  -12                      -> #a238000000000012
+dece158 apply   #a238000000000012       -> -12
+dece159 apply  -1                       -> #a238000000000001
+dece160 apply   #a238000000000001       -> -1
+dece161 apply  -1.23                    -> #a2300000000000a3
+dece162 apply   #a2300000000000a3       -> -1.23
+dece163 apply  -123.45                  -> #a2300000000049c5
+dece164 apply   #a2300000000049c5       -> -123.45
+
+-- Nmin and below
+dece171 apply  -1E-383                  -> #803c000000000001
+dece172 apply   #803c000000000001       -> -1E-383
+dece173 apply  -1.000000000000000E-383  -> #8400000000000000
+dece174 apply   #8400000000000000       -> -1.000000000000000E-383
+dece175 apply  -1.000000000000001E-383  -> #8400000000000001
+dece176 apply   #8400000000000001       -> -1.000000000000001E-383
+
+dece177 apply  -0.100000000000000E-383  -> #8000800000000000       Subnormal
+dece178 apply   #8000800000000000       -> -1.00000000000000E-384  Subnormal
+dece179 apply  -0.000000000000010E-383  -> #8000000000000010       Subnormal
+dece180 apply   #8000000000000010       -> -1.0E-397               Subnormal
+dece181 apply  -0.00000000000001E-383   -> #8004000000000001       Subnormal
+dece182 apply   #8004000000000001       -> -1E-397                 Subnormal
+dece183 apply  -0.000000000000001E-383  -> #8000000000000001       Subnormal
+dece184 apply   #8000000000000001       -> -1E-398                 Subnormal
+
+-- underflows
+dece189 apply   -1e-398                 -> #8000000000000001  Subnormal
+dece190 apply   -1.0e-398               -> #8000000000000001  Subnormal Rounded
+dece191 apply   -1.9e-398               -> #8000000000000002  Subnormal Underflow Inexact Rounded
+dece192 apply   -1.1e-398               -> #8000000000000001  Subnormal Underflow Inexact Rounded
+dece193 apply   -1.00000000001e-398     -> #8000000000000001  Subnormal Underflow Inexact Rounded
+dece194 apply   -1.00000000000001e-398  -> #8000000000000001  Subnormal Underflow Inexact Rounded
+dece195 apply   -1.000000000000001e-398 -> #8000000000000001  Subnormal Underflow Inexact Rounded
+dece196 apply   -0.1e-398               -> #8000000000000000  Subnormal Underflow Inexact Rounded
+dece197 apply   -0.00000000001e-398     -> #8000000000000000  Subnormal Underflow Inexact Rounded
+dece198 apply   -0.00000000000001e-398  -> #8000000000000000  Subnormal Underflow Inexact Rounded
+dece199 apply   -0.000000000000001e-398 -> #8000000000000000  Subnormal Underflow Inexact Rounded
+
+-- zeros
+dece401 apply   0E-500                  -> #0000000000000000  Clamped
+dece402 apply   0E-400                  -> #0000000000000000  Clamped
+dece403 apply   0E-398                  -> #0000000000000000
+dece404 apply   #0000000000000000       -> 0E-398
+dece405 apply   0.000000000000000E-383  -> #0000000000000000
+dece406 apply   #0000000000000000       -> 0E-398
+dece407 apply   0E-2                    -> #2230000000000000
+dece408 apply   #2230000000000000       -> 0.00
+dece409 apply   0                       -> #2238000000000000
+dece410 apply   #2238000000000000       -> 0
+dece411 apply   0E+3                    -> #2244000000000000
+dece412 apply   #2244000000000000       -> 0E+3
+dece413 apply   0E+369                  -> #43fc000000000000
+dece414 apply   #43fc000000000000       -> 0E+369
+-- clamped zeros...
+dece415 apply   0E+370                  -> #43fc000000000000  Clamped
+dece416 apply   #43fc000000000000       -> 0E+369
+dece417 apply   0E+384                  -> #43fc000000000000  Clamped
+dece418 apply   #43fc000000000000       -> 0E+369
+dece419 apply   0E+400                  -> #43fc000000000000  Clamped
+dece420 apply   #43fc000000000000       -> 0E+369
+dece421 apply   0E+500                  -> #43fc000000000000  Clamped
+dece422 apply   #43fc000000000000       -> 0E+369
+
+-- negative zeros
+dece431 apply   -0E-400                 -> #8000000000000000  Clamped
+dece432 apply   -0E-400                 -> #8000000000000000  Clamped
+dece433 apply   -0E-398                 -> #8000000000000000
+dece434 apply   #8000000000000000       -> -0E-398
+dece435 apply   -0.000000000000000E-383 -> #8000000000000000
+dece436 apply   #8000000000000000       -> -0E-398
+dece437 apply   -0E-2                   -> #a230000000000000
+dece438 apply   #a230000000000000       -> -0.00
+dece439 apply   -0                      -> #a238000000000000
+dece440 apply   #a238000000000000       -> -0
+dece441 apply   -0E+3                   -> #a244000000000000
+dece442 apply   #a244000000000000       -> -0E+3
+dece443 apply   -0E+369                 -> #c3fc000000000000
+dece444 apply   #c3fc000000000000       -> -0E+369
+-- clamped zeros...
+dece445 apply   -0E+370                 -> #c3fc000000000000  Clamped
+dece446 apply   #c3fc000000000000       -> -0E+369
+dece447 apply   -0E+384                 -> #c3fc000000000000  Clamped
+dece448 apply   #c3fc000000000000       -> -0E+369
+dece449 apply   -0E+400                 -> #c3fc000000000000  Clamped
+dece450 apply   #c3fc000000000000       -> -0E+369
+dece451 apply   -0E+500                 -> #c3fc000000000000  Clamped
+dece452 apply   #c3fc000000000000       -> -0E+369
+
+-- Specials
+dece500 apply   Infinity          -> #7800000000000000
+dece501 apply   #7878787878787878 -> #7800000000000000
+dece502 apply   #7800000000000000 -> Infinity
+dece503 apply   #7979797979797979 -> #7800000000000000
+dece504 apply   #7900000000000000 -> Infinity
+dece505 apply   #7a7a7a7a7a7a7a7a -> #7800000000000000
+dece506 apply   #7a00000000000000 -> Infinity
+dece507 apply   #7b7b7b7b7b7b7b7b -> #7800000000000000
+dece508 apply   #7b00000000000000 -> Infinity
+
+dece509 apply   NaN               -> #7c00000000000000
+dece510 apply   #7c7c7c7c7c7c7c7c -> #7c007c7c7c7c7c7c
+dece511 apply   #7c00000000000000 -> NaN
+dece512 apply   #7d7d7d7d7d7d7d7d -> #7c017d7d7d7d7d7d
+dece513 apply   #7d00000000000000 -> NaN
+dece514 apply   #7e7e7e7e7e7e7e7e -> #7e007e7e7e7e7c7e
+dece515 apply   #7e00000000000000 -> sNaN
+dece516 apply   #7f7f7f7f7f7f7f7f -> #7e007f7f7f7f7c7f
+dece517 apply   #7f00000000000000 -> sNaN
+dece518 apply   #7fffffffffffffff -> sNaN999999999999999
+dece519 apply   #7fffffffffffffff -> #7e00ff3fcff3fcff
+
+dece520 apply   -Infinity         -> #f800000000000000
+dece521 apply   #f878787878787878 -> #f800000000000000
+dece522 apply   #f800000000000000 -> -Infinity
+dece523 apply   #f979797979797979 -> #f800000000000000
+dece524 apply   #f900000000000000 -> -Infinity
+dece525 apply   #fa7a7a7a7a7a7a7a -> #f800000000000000
+dece526 apply   #fa00000000000000 -> -Infinity
+dece527 apply   #fb7b7b7b7b7b7b7b -> #f800000000000000
+dece528 apply   #fb00000000000000 -> -Infinity
+
+dece529 apply   -NaN              -> #fc00000000000000
+dece530 apply   #fc7c7c7c7c7c7c7c -> #fc007c7c7c7c7c7c
+dece531 apply   #fc00000000000000 -> -NaN
+dece532 apply   #fd7d7d7d7d7d7d7d -> #fc017d7d7d7d7d7d
+dece533 apply   #fd00000000000000 -> -NaN
+dece534 apply   #fe7e7e7e7e7e7e7e -> #fe007e7e7e7e7c7e
+dece535 apply   #fe00000000000000 -> -sNaN
+dece536 apply   #ff7f7f7f7f7f7f7f -> #fe007f7f7f7f7c7f
+dece537 apply   #ff00000000000000 -> -sNaN
+dece538 apply   #ffffffffffffffff -> -sNaN999999999999999
+dece539 apply   #ffffffffffffffff -> #fe00ff3fcff3fcff
+
+-- diagnostic NaNs
+dece540 apply   NaN                 -> #7c00000000000000
+dece541 apply   NaN0                -> #7c00000000000000
+dece542 apply   NaN1                -> #7c00000000000001
+dece543 apply   NaN12               -> #7c00000000000012
+dece544 apply   NaN79               -> #7c00000000000079
+dece545 apply   NaN12345            -> #7c000000000049c5
+dece546 apply   NaN123456           -> #7c00000000028e56
+dece547 apply   NaN799799           -> #7c000000000f7fdf
+dece548 apply   NaN799799799799799  -> #7c03dff7fdff7fdf
+dece549 apply   NaN999999999999999  -> #7c00ff3fcff3fcff
+dece550 apply   NaN1234567890123456 -> #7c00000000000000  -- too many digits
+
+-- fold-down full sequence
+dece601 apply   1E+384                  -> #47fc000000000000 Clamped
+dece602 apply   #47fc000000000000       -> 1.000000000000000E+384
+dece603 apply   1E+383                  -> #43fc800000000000 Clamped
+dece604 apply   #43fc800000000000       -> 1.00000000000000E+383
+dece605 apply   1E+382                  -> #43fc100000000000 Clamped
+dece606 apply   #43fc100000000000       -> 1.0000000000000E+382
+dece607 apply   1E+381                  -> #43fc010000000000 Clamped
+dece608 apply   #43fc010000000000       -> 1.000000000000E+381
+dece609 apply   1E+380                  -> #43fc002000000000 Clamped
+dece610 apply   #43fc002000000000       -> 1.00000000000E+380
+dece611 apply   1E+379                  -> #43fc000400000000 Clamped
+dece612 apply   #43fc000400000000       -> 1.0000000000E+379
+dece613 apply   1E+378                  -> #43fc000040000000 Clamped
+dece614 apply   #43fc000040000000       -> 1.000000000E+378
+dece615 apply   1E+377                  -> #43fc000008000000 Clamped
+dece616 apply   #43fc000008000000       -> 1.00000000E+377
+dece617 apply   1E+376                  -> #43fc000001000000 Clamped
+dece618 apply   #43fc000001000000       -> 1.0000000E+376
+dece619 apply   1E+375                  -> #43fc000000100000 Clamped
+dece620 apply   #43fc000000100000       -> 1.000000E+375
+dece621 apply   1E+374                  -> #43fc000000020000 Clamped
+dece622 apply   #43fc000000020000       -> 1.00000E+374
+dece623 apply   1E+373                  -> #43fc000000004000 Clamped
+dece624 apply   #43fc000000004000       -> 1.0000E+373
+dece625 apply   1E+372                  -> #43fc000000000400 Clamped
+dece626 apply   #43fc000000000400       -> 1.000E+372
+dece627 apply   1E+371                  -> #43fc000000000080 Clamped
+dece628 apply   #43fc000000000080       -> 1.00E+371
+dece629 apply   1E+370                  -> #43fc000000000010 Clamped
+dece630 apply   #43fc000000000010       -> 1.0E+370
+dece631 apply   1E+369                  -> #43fc000000000001
+dece632 apply   #43fc000000000001       -> 1E+369
+dece633 apply   1E+368                  -> #43f8000000000001
+dece634 apply   #43f8000000000001       -> 1E+368
+-- same with 9s
+dece641 apply   9E+384                  -> #77fc000000000000 Clamped
+dece642 apply   #77fc000000000000       -> 9.000000000000000E+384
+dece643 apply   9E+383                  -> #43fc8c0000000000 Clamped
+dece644 apply   #43fc8c0000000000       -> 9.00000000000000E+383
+dece645 apply   9E+382                  -> #43fc1a0000000000 Clamped
+dece646 apply   #43fc1a0000000000       -> 9.0000000000000E+382
+dece647 apply   9E+381                  -> #43fc090000000000 Clamped
+dece648 apply   #43fc090000000000       -> 9.000000000000E+381
+dece649 apply   9E+380                  -> #43fc002300000000 Clamped
+dece650 apply   #43fc002300000000       -> 9.00000000000E+380
+dece651 apply   9E+379                  -> #43fc000680000000 Clamped
+dece652 apply   #43fc000680000000       -> 9.0000000000E+379
+dece653 apply   9E+378                  -> #43fc000240000000 Clamped
+dece654 apply   #43fc000240000000       -> 9.000000000E+378
+dece655 apply   9E+377                  -> #43fc000008c00000 Clamped
+dece656 apply   #43fc000008c00000       -> 9.00000000E+377
+dece657 apply   9E+376                  -> #43fc000001a00000 Clamped
+dece658 apply   #43fc000001a00000       -> 9.0000000E+376
+dece659 apply   9E+375                  -> #43fc000000900000 Clamped
+dece660 apply   #43fc000000900000       -> 9.000000E+375
+dece661 apply   9E+374                  -> #43fc000000023000 Clamped
+dece662 apply   #43fc000000023000       -> 9.00000E+374
+dece663 apply   9E+373                  -> #43fc000000006800 Clamped
+dece664 apply   #43fc000000006800       -> 9.0000E+373
+dece665 apply   9E+372                  -> #43fc000000002400 Clamped
+dece666 apply   #43fc000000002400       -> 9.000E+372
+dece667 apply   9E+371                  -> #43fc00000000008c Clamped
+dece668 apply   #43fc00000000008c       -> 9.00E+371
+dece669 apply   9E+370                  -> #43fc00000000001a Clamped
+dece670 apply   #43fc00000000001a       -> 9.0E+370
+dece671 apply   9E+369                  -> #43fc000000000009
+dece672 apply   #43fc000000000009       -> 9E+369
+dece673 apply   9E+368                  -> #43f8000000000009
+dece674 apply   #43f8000000000009       -> 9E+368
+
+
+-- Selected DPD codes
+dece700 apply   #2238000000000000       -> 0
+dece701 apply   #2238000000000009       -> 9
+dece702 apply   #2238000000000010       -> 10
+dece703 apply   #2238000000000019       -> 19
+dece704 apply   #2238000000000020       -> 20
+dece705 apply   #2238000000000029       -> 29
+dece706 apply   #2238000000000030       -> 30
+dece707 apply   #2238000000000039       -> 39
+dece708 apply   #2238000000000040       -> 40
+dece709 apply   #2238000000000049       -> 49
+dece710 apply   #2238000000000050       -> 50
+dece711 apply   #2238000000000059       -> 59
+dece712 apply   #2238000000000060       -> 60
+dece713 apply   #2238000000000069       -> 69
+dece714 apply   #2238000000000070       -> 70
+dece715 apply   #2238000000000071       -> 71
+dece716 apply   #2238000000000072       -> 72
+dece717 apply   #2238000000000073       -> 73
+dece718 apply   #2238000000000074       -> 74
+dece719 apply   #2238000000000075       -> 75
+dece720 apply   #2238000000000076       -> 76
+dece721 apply   #2238000000000077       -> 77
+dece722 apply   #2238000000000078       -> 78
+dece723 apply   #2238000000000079       -> 79
+
+dece730 apply   #223800000000029e       -> 994
+dece731 apply   #223800000000029f       -> 995
+dece732 apply   #22380000000002a0       -> 520
+dece733 apply   #22380000000002a1       -> 521
+
+-- DPD: one of each of the huffman groups
+dece740 apply   #22380000000003f7       -> 777
+dece741 apply   #22380000000003f8       -> 778
+dece742 apply   #22380000000003eb       -> 787
+dece743 apply   #223800000000037d       -> 877
+dece744 apply   #223800000000039f       -> 997
+dece745 apply   #22380000000003bf       -> 979
+dece746 apply   #22380000000003df       -> 799
+dece747 apply   #223800000000006e       -> 888
+
+
+-- DPD all-highs cases (includes the 24 redundant codes)
+dece750 apply   #223800000000006e       -> 888
+dece751 apply   #223800000000016e       -> 888
+dece752 apply   #223800000000026e       -> 888
+dece753 apply   #223800000000036e       -> 888
+dece754 apply   #223800000000006f       -> 889
+dece755 apply   #223800000000016f       -> 889
+dece756 apply   #223800000000026f       -> 889
+dece757 apply   #223800000000036f       -> 889
+
+dece760 apply   #223800000000007e       -> 898
+dece761 apply   #223800000000017e       -> 898
+dece762 apply   #223800000000027e       -> 898
+dece763 apply   #223800000000037e       -> 898
+dece764 apply   #223800000000007f       -> 899
+dece765 apply   #223800000000017f       -> 899
+dece766 apply   #223800000000027f       -> 899
+dece767 apply   #223800000000037f       -> 899
+
+dece770 apply   #22380000000000ee       -> 988
+dece771 apply   #22380000000001ee       -> 988
+dece772 apply   #22380000000002ee       -> 988
+dece773 apply   #22380000000003ee       -> 988
+dece774 apply   #22380000000000ef       -> 989
+dece775 apply   #22380000000001ef       -> 989
+dece776 apply   #22380000000002ef       -> 989
+dece777 apply   #22380000000003ef       -> 989
+
+dece780 apply   #22380000000000fe       -> 998
+dece781 apply   #22380000000001fe       -> 998
+dece782 apply   #22380000000002fe       -> 998
+dece783 apply   #22380000000003fe       -> 998
+dece784 apply   #22380000000000ff       -> 999
+dece785 apply   #22380000000001ff       -> 999
+dece786 apply   #22380000000002ff       -> 999
+dece787 apply   #22380000000003ff       -> 999
+

Added: vendor/Python/current/Lib/test/decimaltestdata/divide.decTest
===================================================================
--- vendor/Python/current/Lib/test/decimaltestdata/divide.decTest	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/decimaltestdata/divide.decTest	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,818 @@
+------------------------------------------------------------------------
+-- divide.decTest -- decimal division                                 --
+-- Copyright (c) IBM Corporation, 1981, 2004.  All rights reserved.   --
+------------------------------------------------------------------------
+-- Please see the document "General Decimal Arithmetic Testcases"     --
+-- at http://www2.hursley.ibm.com/decimal for the description of      --
+-- these testcases.                                                   --
+--                                                                    --
+-- These testcases are experimental ('beta' versions), and they       --
+-- may contain errors.  They are offered on an as-is basis.  In       --
+-- particular, achieving the same results as the tests here is not    --
+-- a guarantee that an implementation complies with any Standard      --
+-- or specification.  The tests are not exhaustive.                   --
+--                                                                    --
+-- Please send comments, suggestions, and corrections to the author:  --
+--   Mike Cowlishaw, IBM Fellow                                       --
+--   IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK         --
+--   mfc at uk.ibm.com                                                   --
+------------------------------------------------------------------------
+version: 2.39
+
+extended:    1
+precision:   9
+rounding:    half_up
+maxExponent: 384
+minexponent: -383
+
+-- sanity checks
+divx001 divide  1     1    ->  1
+divx002 divide  2     1    ->  2
+divx003 divide  1     2    ->  0.5
+divx004 divide  2     2    ->  1
+divx005 divide  0     1    ->  0
+divx006 divide  0     2    ->  0
+divx007 divide  1     3    ->  0.333333333 Inexact Rounded
+divx008 divide  2     3    ->  0.666666667 Inexact Rounded
+divx009 divide  3     3    ->  1
+
+divx010 divide  2.4   1    ->  2.4
+divx011 divide  2.4   -1   ->  -2.4
+divx012 divide  -2.4  1    ->  -2.4
+divx013 divide  -2.4  -1   ->  2.4
+divx014 divide  2.40  1    ->  2.40
+divx015 divide  2.400 1    ->  2.400
+divx016 divide  2.4   2    ->  1.2
+divx017 divide  2.400 2    ->  1.200
+divx018 divide  2.    2    ->  1
+divx019 divide  20    20   ->  1
+
+divx020 divide  187   187  ->  1
+divx021 divide  5     2    ->  2.5
+divx022 divide  5     2.0    ->  2.5
+divx023 divide  5     2.000  ->  2.5
+divx024 divide  5     0.20   ->  25
+divx025 divide  5     0.200  ->  25
+divx026 divide  10    1      ->  10
+divx027 divide  100   1      ->  100
+divx028 divide  1000  1      ->  1000
+divx029 divide  1000  100    ->  10
+
+divx030 divide  1     2      ->  0.5
+divx031 divide  1     4      ->  0.25
+divx032 divide  1     8      ->  0.125
+divx033 divide  1     16     ->  0.0625
+divx034 divide  1     32     ->  0.03125
+divx035 divide  1     64     ->  0.015625
+divx040 divide  1    -2      ->  -0.5
+divx041 divide  1    -4      ->  -0.25
+divx042 divide  1    -8      ->  -0.125
+divx043 divide  1    -16     ->  -0.0625
+divx044 divide  1    -32     ->  -0.03125
+divx045 divide  1    -64     ->  -0.015625
+divx050 divide -1     2      ->  -0.5
+divx051 divide -1     4      ->  -0.25
+divx052 divide -1     8      ->  -0.125
+divx053 divide -1     16     ->  -0.0625
+divx054 divide -1     32     ->  -0.03125
+divx055 divide -1     64     ->  -0.015625
+divx060 divide -1    -2      ->  0.5
+divx061 divide -1    -4      ->  0.25
+divx062 divide -1    -8      ->  0.125
+divx063 divide -1    -16     ->  0.0625
+divx064 divide -1    -32     ->  0.03125
+divx065 divide -1    -64     ->  0.015625
+
+divx070 divide  999999999        1    ->  999999999
+divx071 divide  999999999.4      1    ->  999999999 Inexact Rounded
+divx072 divide  999999999.5      1    ->  1.00000000E+9 Inexact Rounded
+divx073 divide  999999999.9      1    ->  1.00000000E+9 Inexact Rounded
+divx074 divide  999999999.999    1    ->  1.00000000E+9 Inexact Rounded
+precision: 6
+divx080 divide  999999999     1  ->  1.00000E+9 Inexact Rounded
+divx081 divide  99999999      1  ->  1.00000E+8 Inexact Rounded
+divx082 divide  9999999       1  ->  1.00000E+7 Inexact Rounded
+divx083 divide  999999        1  ->  999999
+divx084 divide  99999         1  ->  99999
+divx085 divide  9999          1  ->  9999
+divx086 divide  999           1  ->  999
+divx087 divide  99            1  ->  99
+divx088 divide  9             1  ->  9
+
+precision: 9
+divx090 divide  0.            1    ->  0
+divx091 divide  .0            1    ->  0.0
+divx092 divide  0.00          1    ->  0.00
+divx093 divide  0.00E+9       1    ->  0E+7
+divx094 divide  0.0000E-50    1    ->  0E-54
+
+divx095 divide  1            1E-8  ->  1E+8
+divx096 divide  1            1E-9  ->  1E+9
+divx097 divide  1            1E-10 ->  1E+10
+divx098 divide  1            1E-11 ->  1E+11
+divx099 divide  1            1E-12 ->  1E+12
+
+divx100 divide  1  1   -> 1
+divx101 divide  1  2   -> 0.5
+divx102 divide  1  3   -> 0.333333333 Inexact Rounded
+divx103 divide  1  4   -> 0.25
+divx104 divide  1  5   -> 0.2
+divx105 divide  1  6   -> 0.166666667 Inexact Rounded
+divx106 divide  1  7   -> 0.142857143 Inexact Rounded
+divx107 divide  1  8   -> 0.125
+divx108 divide  1  9   -> 0.111111111 Inexact Rounded
+divx109 divide  1  10  -> 0.1
+divx110 divide  1  1   -> 1
+divx111 divide  2  1   -> 2
+divx112 divide  3  1   -> 3
+divx113 divide  4  1   -> 4
+divx114 divide  5  1   -> 5
+divx115 divide  6  1   -> 6
+divx116 divide  7  1   -> 7
+divx117 divide  8  1   -> 8
+divx118 divide  9  1   -> 9
+divx119 divide  10 1   -> 10
+
+divx120 divide  3E+1 0.001  -> 3E+4
+divx121 divide  2.200 2     -> 1.100
+
+divx130 divide  12345  4.999  ->  2469.49390 Inexact Rounded
+divx131 divide  12345  4.99   ->  2473.94790 Inexact Rounded
+divx132 divide  12345  4.9    ->  2519.38776 Inexact Rounded
+divx133 divide  12345  5      ->  2469
+divx134 divide  12345  5.1    ->  2420.58824 Inexact Rounded
+divx135 divide  12345  5.01   ->  2464.07186 Inexact Rounded
+divx136 divide  12345  5.001  ->  2468.50630 Inexact Rounded
+
+precision:   9
+maxexponent: 999999999
+minexponent: -999999999
+
+-- test possibly imprecise results
+divx220 divide 391   597 ->  0.654941374 Inexact Rounded
+divx221 divide 391  -597 -> -0.654941374 Inexact Rounded
+divx222 divide -391  597 -> -0.654941374 Inexact Rounded
+divx223 divide -391 -597 ->  0.654941374 Inexact Rounded
+
+-- test some cases that are close to exponent overflow
+maxexponent: 999999999
+minexponent: -999999999
+divx270 divide 1 1e999999999    -> 1E-999999999
+divx271 divide 1 0.9e999999999  -> 1.11111111E-999999999 Inexact Rounded
+divx272 divide 1 0.99e999999999 -> 1.01010101E-999999999 Inexact Rounded
+divx273 divide 1 0.999999999e999999999 -> 1.00000000E-999999999 Inexact Rounded
+divx274 divide 9e999999999    1 -> 9E+999999999
+divx275 divide 9.9e999999999  1 -> 9.9E+999999999
+divx276 divide 9.99e999999999 1 -> 9.99E+999999999
+divx277 divide 9.99999999e999999999 1 -> 9.99999999E+999999999
+
+divx280 divide 0.1 9e-999999999   -> 1.11111111E+999999997 Inexact Rounded
+divx281 divide 0.1 99e-999999999  -> 1.01010101E+999999996 Inexact Rounded
+divx282 divide 0.1 999e-999999999 -> 1.00100100E+999999995 Inexact Rounded
+
+divx283 divide 0.1 9e-999999998     -> 1.11111111E+999999996 Inexact Rounded
+divx284 divide 0.1 99e-999999998    -> 1.01010101E+999999995 Inexact Rounded
+divx285 divide 0.1 999e-999999998   -> 1.00100100E+999999994 Inexact Rounded
+divx286 divide 0.1 999e-999999997   -> 1.00100100E+999999993 Inexact Rounded
+divx287 divide 0.1 9999e-999999997  -> 1.00010001E+999999992 Inexact Rounded
+divx288 divide 0.1 99999e-999999997 -> 1.00001000E+999999991 Inexact Rounded
+
+-- Divide into 0 tests
+
+divx301 divide    0    7     -> 0
+divx302 divide    0    7E-5  -> 0E+5
+divx303 divide    0    7E-1  -> 0E+1
+divx304 divide    0    7E+1  -> 0.0
+divx305 divide    0    7E+5  -> 0.00000
+divx306 divide    0    7E+6  -> 0.000000
+divx307 divide    0    7E+7  -> 0E-7
+divx308 divide    0   70E-5  -> 0E+5
+divx309 divide    0   70E-1  -> 0E+1
+divx310 divide    0   70E+0  -> 0
+divx311 divide    0   70E+1  -> 0.0
+divx312 divide    0   70E+5  -> 0.00000
+divx313 divide    0   70E+6  -> 0.000000
+divx314 divide    0   70E+7  -> 0E-7
+divx315 divide    0  700E-5  -> 0E+5
+divx316 divide    0  700E-1  -> 0E+1
+divx317 divide    0  700E+0  -> 0
+divx318 divide    0  700E+1  -> 0.0
+divx319 divide    0  700E+5  -> 0.00000
+divx320 divide    0  700E+6  -> 0.000000
+divx321 divide    0  700E+7  -> 0E-7
+divx322 divide    0  700E+77 -> 0E-77
+
+divx331 divide 0E-3    7E-5  -> 0E+2
+divx332 divide 0E-3    7E-1  -> 0.00
+divx333 divide 0E-3    7E+1  -> 0.0000
+divx334 divide 0E-3    7E+5  -> 0E-8
+divx335 divide 0E-1    7E-5  -> 0E+4
+divx336 divide 0E-1    7E-1  -> 0
+divx337 divide 0E-1    7E+1  -> 0.00
+divx338 divide 0E-1    7E+5  -> 0.000000
+divx339 divide 0E+1    7E-5  -> 0E+6
+divx340 divide 0E+1    7E-1  -> 0E+2
+divx341 divide 0E+1    7E+1  -> 0
+divx342 divide 0E+1    7E+5  -> 0.0000
+divx343 divide 0E+3    7E-5  -> 0E+8
+divx344 divide 0E+3    7E-1  -> 0E+4
+divx345 divide 0E+3    7E+1  -> 0E+2
+divx346 divide 0E+3    7E+5  -> 0.00
+
+maxexponent: 92
+minexponent: -92
+precision:    7
+divx351 divide 0E-92   7E-1  -> 0E-91
+divx352 divide 0E-92   7E+1  -> 0E-93
+divx353 divide 0E-92   7E+5  -> 0E-97
+divx354 divide 0E-92   7E+6  -> 0E-98
+divx355 divide 0E-92   7E+7  -> 0E-98 Clamped
+divx356 divide 0E-92 777E-1  -> 0E-91
+divx357 divide 0E-92 777E+1  -> 0E-93
+divx358 divide 0E-92 777E+3  -> 0E-95
+divx359 divide 0E-92 777E+4  -> 0E-96
+divx360 divide 0E-92 777E+5  -> 0E-97
+divx361 divide 0E-92 777E+6  -> 0E-98
+divx362 divide 0E-92 777E+7  -> 0E-98 Clamped
+divx363 divide 0E-92   7E+92 -> 0E-98 Clamped
+
+divx371 divide 0E-92 700E-1  -> 0E-91
+divx372 divide 0E-92 700E+1  -> 0E-93
+divx373 divide 0E-92 700E+3  -> 0E-95
+divx374 divide 0E-92 700E+4  -> 0E-96
+divx375 divide 0E-92 700E+5  -> 0E-97
+divx376 divide 0E-92 700E+6  -> 0E-98
+divx377 divide 0E-92 700E+7  -> 0E-98 Clamped
+
+divx381 divide 0E+92   7E+1  -> 0E+91
+divx382 divide 0E+92   7E+0  -> 0E+92
+divx383 divide 0E+92   7E-1  -> 0E+92 Clamped
+divx384 divide 0E+90 777E+1  -> 0E+89
+divx385 divide 0E+90 777E-1  -> 0E+91
+divx386 divide 0E+90 777E-2  -> 0E+92
+divx387 divide 0E+90 777E-3  -> 0E+92 Clamped
+divx388 divide 0E+90 777E-4  -> 0E+92 Clamped
+
+divx391 divide 0E+90 700E+1  -> 0E+89
+divx392 divide 0E+90 700E-1  -> 0E+91
+divx393 divide 0E+90 700E-2  -> 0E+92
+divx394 divide 0E+90 700E-3  -> 0E+92 Clamped
+divx395 divide 0E+90 700E-4  -> 0E+92 Clamped
+
+-- input rounding checks
+maxexponent: 999
+minexponent: -999
+precision: 9
+divx401 divide 12345678000 1 -> 1.23456780E+10 Rounded
+divx402 divide 1 12345678000 -> 8.10000066E-11 Inexact Rounded
+divx403 divide 1234567800  1 -> 1.23456780E+9  Rounded
+divx404 divide 1 1234567800  -> 8.10000066E-10 Inexact Rounded
+divx405 divide 1234567890  1 -> 1.23456789E+9  Rounded
+divx406 divide 1 1234567890  -> 8.10000007E-10 Inexact Rounded
+divx407 divide 1234567891  1 -> 1.23456789E+9  Inexact Rounded
+divx408 divide 1 1234567891  -> 8.10000007E-10 Inexact Rounded
+divx409 divide 12345678901 1 -> 1.23456789E+10 Inexact Rounded
+divx410 divide 1 12345678901 -> 8.10000007E-11 Inexact Rounded
+divx411 divide 1234567896  1 -> 1.23456790E+9  Inexact Rounded
+divx412 divide 1 1234567896  -> 8.10000003E-10 Inexact Rounded
+divx413 divide 1 1234567897  -> 8.10000003E-10 Inexact Rounded
+divx414 divide 1 1234567898  -> 8.10000002E-10 Inexact Rounded
+divx415 divide 1 1234567899  -> 8.10000001E-10 Inexact Rounded
+divx416 divide 1 1234567900  -> 8.10000001E-10 Inexact Rounded
+divx417 divide 1 1234567901  -> 8.10000000E-10 Inexact Rounded
+divx418 divide 1 1234567902  -> 8.09999999E-10 Inexact Rounded
+-- some longies
+divx421 divide 1234567896.000000000000  1 -> 1.23456790E+9  Inexact Rounded
+divx422 divide 1 1234567896.000000000000  -> 8.10000003E-10 Inexact Rounded
+divx423 divide 1234567896.000000000001  1 -> 1.23456790E+9  Inexact Rounded
+divx424 divide 1 1234567896.000000000001  -> 8.10000003E-10 Inexact Rounded
+divx425 divide 1234567896.000000000000000000000000000000000000000009  1 -> 1.23456790E+9  Inexact Rounded
+divx426 divide 1 1234567896.000000000000000000000000000000000000000009  -> 8.10000003E-10 Inexact Rounded
+divx427 divide 1234567897.900010000000000000000000000000000000000009  1 -> 1.23456790E+9  Inexact Rounded
+divx428 divide 1 1234567897.900010000000000000000000000000000000000009  -> 8.10000002E-10 Inexact Rounded
+
+precision: 15
+-- still checking...
+divx441 divide 12345678000 1 -> 12345678000
+divx442 divide 1 12345678000 -> 8.10000066420005E-11 Inexact Rounded
+divx443 divide 1234567800  1 -> 1234567800
+divx444 divide 1 1234567800  -> 8.10000066420005E-10 Inexact Rounded
+divx445 divide 1234567890  1 -> 1234567890
+divx446 divide 1 1234567890  -> 8.10000007371000E-10 Inexact Rounded
+divx447 divide 1234567891  1 -> 1234567891
+divx448 divide 1 1234567891  -> 8.10000006714900E-10 Inexact Rounded
+divx449 divide 12345678901 1 -> 12345678901
+divx450 divide 1 12345678901 -> 8.10000007305390E-11 Inexact Rounded
+divx451 divide 1234567896  1 -> 1234567896
+divx452 divide 1 1234567896  -> 8.10000003434400E-10 Inexact Rounded
+
+-- high-lows
+divx453 divide 1e+1   1    ->   1E+1
+divx454 divide 1e+1   1.0  ->   1E+1
+divx455 divide 1e+1   1.00 ->   1E+1
+divx456 divide 1e+2   2    ->   5E+1
+divx457 divide 1e+2   2.0  ->   5E+1
+divx458 divide 1e+2   2.00 ->   5E+1
+
+-- some from IEEE discussions
+divx460 divide 3e0      2e0     -> 1.5
+divx461 divide 30e-1    2e0     -> 1.5
+divx462 divide 300e-2   2e0     -> 1.50
+divx464 divide 3000e-3  2e0     -> 1.500
+divx465 divide 3e0      20e-1   -> 1.5
+divx466 divide 30e-1    20e-1   -> 1.5
+divx467 divide 300e-2   20e-1   -> 1.5
+divx468 divide 3000e-3  20e-1   -> 1.50
+divx469 divide 3e0      200e-2  -> 1.5
+divx470 divide 30e-1    200e-2  -> 1.5
+divx471 divide 300e-2   200e-2  -> 1.5
+divx472 divide 3000e-3  200e-2  -> 1.5
+divx473 divide 3e0      2000e-3 -> 1.5
+divx474 divide 30e-1    2000e-3 -> 1.5
+divx475 divide 300e-2   2000e-3 -> 1.5
+divx476 divide 3000e-3  2000e-3 -> 1.5
+
+-- some reciprocals
+divx480 divide 1        1.0E+33 -> 1E-33
+divx481 divide 1        10E+33  -> 1E-34
+divx482 divide 1        1.0E-33 -> 1E+33
+divx483 divide 1        10E-33  -> 1E+32
+
+-- RMS discussion table
+maxexponent:  96
+minexponent: -95
+precision:     7
+
+divx484 divide 0e5     1e3 ->   0E+2
+divx485 divide 0e5     2e3 ->   0E+2
+divx486 divide 0e5    10e2 ->   0E+3
+divx487 divide 0e5    20e2 ->   0E+3
+divx488 divide 0e5   100e1 ->   0E+4
+divx489 divide 0e5   200e1 ->   0E+4
+
+divx491 divide 1e5     1e3 ->   1E+2
+divx492 divide 1e5     2e3 ->   5E+1
+divx493 divide 1e5    10e2 ->   1E+2
+divx494 divide 1e5    20e2 ->   5E+1
+divx495 divide 1e5   100e1 ->   1E+2
+divx496 divide 1e5   200e1 ->   5E+1
+
+-- tryzeros cases
+precision:   7
+rounding:    half_up
+maxExponent: 92
+minexponent: -92
+divx497  divide  0E+86 1000E-13  -> 0E+92 Clamped
+divx498  divide  0E-98 1000E+13  -> 0E-98 Clamped
+
+precision:   9
+rounding:    half_up
+maxExponent: 999
+minexponent: -999
+
+-- focus on trailing zeros issues
+precision:   9
+divx500 divide  1      9.9    ->  0.101010101  Inexact Rounded
+precision:   8
+divx501 divide  1      9.9    ->  0.10101010   Inexact Rounded
+precision:   7
+divx502 divide  1      9.9    ->  0.1010101    Inexact Rounded
+precision:   6
+divx503 divide  1      9.9    ->  0.101010     Inexact Rounded
+precision:   9
+
+divx511 divide 1         2    -> 0.5
+divx512 divide 1.0       2    -> 0.5
+divx513 divide 1.00      2    -> 0.50
+divx514 divide 1.000     2    -> 0.500
+divx515 divide 1.0000    2    -> 0.5000
+divx516 divide 1.00000   2    -> 0.50000
+divx517 divide 1.000000  2    -> 0.500000
+divx518 divide 1.0000000 2    -> 0.5000000
+divx519 divide 1.00      2.00 -> 0.5
+
+divx521 divide 2    1         -> 2
+divx522 divide 2    1.0       -> 2
+divx523 divide 2    1.00      -> 2
+divx524 divide 2    1.000     -> 2
+divx525 divide 2    1.0000    -> 2
+divx526 divide 2    1.00000   -> 2
+divx527 divide 2    1.000000  -> 2
+divx528 divide 2    1.0000000 -> 2
+divx529 divide 2.00 1.00      -> 2
+
+divx530 divide  2.40   2      ->  1.20
+divx531 divide  2.40   4      ->  0.60
+divx532 divide  2.40  10      ->  0.24
+divx533 divide  2.40   2.0    ->  1.2
+divx534 divide  2.40   4.0    ->  0.6
+divx535 divide  2.40  10.0    ->  0.24
+divx536 divide  2.40   2.00   ->  1.2
+divx537 divide  2.40   4.00   ->  0.6
+divx538 divide  2.40  10.00   ->  0.24
+divx539 divide  0.9    0.1    ->  9
+divx540 divide  0.9    0.01   ->  9E+1
+divx541 divide  0.9    0.001  ->  9E+2
+divx542 divide  5      2      ->  2.5
+divx543 divide  5      2.0    ->  2.5
+divx544 divide  5      2.00   ->  2.5
+divx545 divide  5      20     ->  0.25
+divx546 divide  5      20.0   ->  0.25
+divx547 divide  2.400  2      ->  1.200
+divx548 divide  2.400  2.0    ->  1.20
+divx549 divide  2.400  2.400  ->  1
+
+divx550 divide  240    1      ->  240
+divx551 divide  240    10     ->  24
+divx552 divide  240    100    ->  2.4
+divx553 divide  240    1000   ->  0.24
+divx554 divide  2400   1      ->  2400
+divx555 divide  2400   10     ->  240
+divx556 divide  2400   100    ->  24
+divx557 divide  2400   1000   ->  2.4
+
+-- +ve exponent
+precision: 5
+divx570 divide  2.4E+6     2  ->  1.2E+6
+divx571 divide  2.40E+6    2  ->  1.20E+6
+divx572 divide  2.400E+6   2  ->  1.200E+6
+divx573 divide  2.4000E+6  2  ->  1.2000E+6
+divx574 divide  24E+5      2  ->  1.2E+6
+divx575 divide  240E+4     2  ->  1.20E+6
+divx576 divide  2400E+3    2  ->  1.200E+6
+divx577 divide  24000E+2   2  ->  1.2000E+6
+precision: 6
+divx580 divide  2.4E+6     2  ->  1.2E+6
+divx581 divide  2.40E+6    2  ->  1.20E+6
+divx582 divide  2.400E+6   2  ->  1.200E+6
+divx583 divide  2.4000E+6  2  ->  1.2000E+6
+divx584 divide  24E+5      2  ->  1.2E+6
+divx585 divide  240E+4     2  ->  1.20E+6
+divx586 divide  2400E+3    2  ->  1.200E+6
+divx587 divide  24000E+2   2  ->  1.2000E+6
+precision: 7
+divx590 divide  2.4E+6     2  ->  1.2E+6
+divx591 divide  2.40E+6    2  ->  1.20E+6
+divx592 divide  2.400E+6   2  ->  1.200E+6
+divx593 divide  2.4000E+6  2  ->  1.2000E+6
+divx594 divide  24E+5      2  ->  1.2E+6
+divx595 divide  240E+4     2  ->  1.20E+6
+divx596 divide  2400E+3    2  ->  1.200E+6
+divx597 divide  24000E+2   2  ->  1.2000E+6
+precision:   9
+divx600 divide  2.4E+9     2  ->  1.2E+9
+divx601 divide  2.40E+9    2  ->  1.20E+9
+divx602 divide  2.400E+9   2  ->  1.200E+9
+divx603 divide  2.4000E+9  2  ->  1.2000E+9
+divx604 divide  24E+8      2  ->  1.2E+9
+divx605 divide  240E+7     2  ->  1.20E+9
+divx606 divide  2400E+6    2  ->  1.200E+9
+divx607 divide  24000E+5   2  ->  1.2000E+9
+
+-- long operand triangle
+precision: 33
+divx610 divide -3374988581607586061255542201048 82293895124.90045271504836568681 -> -41011408883796817797.8131097703792 Inexact Rounded
+precision: 32
+divx611 divide -3374988581607586061255542201048 82293895124.90045271504836568681 -> -41011408883796817797.813109770379  Inexact Rounded
+precision: 31
+divx612 divide -3374988581607586061255542201048 82293895124.90045271504836568681 -> -41011408883796817797.81310977038   Inexact Rounded
+precision: 30
+divx613 divide -3374988581607586061255542201048 82293895124.90045271504836568681 -> -41011408883796817797.8131097704    Inexact Rounded
+precision: 29
+divx614 divide -3374988581607586061255542201048 82293895124.90045271504836568681 -> -41011408883796817797.813109770     Inexact Rounded
+precision: 28
+divx615 divide -3374988581607586061255542201048 82293895124.90045271504836568681 -> -41011408883796817797.81310977      Inexact Rounded
+precision: 27
+divx616 divide -3374988581607586061255542201048 82293895124.90045271504836568681 -> -41011408883796817797.8131098       Inexact Rounded
+precision: 26
+divx617 divide -3374988581607586061255542201048 82293895124.90045271504836568681 -> -41011408883796817797.813110        Inexact Rounded
+precision: 25
+divx618 divide -3374988581607586061255542201048 82293895124.90045271504836568681 -> -41011408883796817797.81311         Inexact Rounded
+precision: 24
+divx619 divide -3374988581607586061255542201048 82293895124.90045271504836568681 -> -41011408883796817797.8131          Inexact Rounded
+precision: 23
+divx620 divide -3374988581607586061255542201048 82293895124.90045271504836568681 -> -41011408883796817797.813           Inexact Rounded
+precision: 22
+divx621 divide -3374988581607586061255542201048 82293895124.90045271504836568681 -> -41011408883796817797.81            Inexact Rounded
+precision: 21
+divx622 divide -3374988581607586061255542201048 82293895124.90045271504836568681 -> -41011408883796817797.8             Inexact Rounded
+precision: 20
+divx623 divide -3374988581607586061255542201048 82293895124.90045271504836568681 -> -41011408883796817798               Inexact Rounded
+precision: 19
+divx624 divide -3374988581607586061255542201048 82293895124.90045271504836568681 -> -4.101140888379681780E+19         Inexact Rounded
+precision: 18
+divx625 divide -3374988581607586061255542201048 82293895124.90045271504836568681 -> -4.10114088837968178E+19         Inexact Rounded
+precision: 17
+divx626 divide -3374988581607586061255542201048 82293895124.90045271504836568681 -> -4.1011408883796818E+19         Inexact Rounded
+precision: 16
+divx627 divide -3374988581607586061255542201048 82293895124.90045271504836568681 -> -4.101140888379682E+19         Inexact Rounded
+precision: 15
+divx628 divide -3374988581607586061255542201048 82293895124.90045271504836568681 -> -4.10114088837968E+19         Inexact Rounded
+precision: 14
+divx629 divide -3374988581607586061255542201048 82293895124.90045271504836568681 -> -4.1011408883797E+19         Inexact Rounded
+precision: 13
+divx630 divide -3374988581607586061255542201048 82293895124.90045271504836568681 -> -4.101140888380E+19         Inexact Rounded
+precision: 12
+divx631 divide -3374988581607586061255542201048 82293895124.90045271504836568681 -> -4.10114088838E+19         Inexact Rounded
+precision: 11
+divx632 divide -3374988581607586061255542201048 82293895124.90045271504836568681 -> -4.1011408884E+19         Inexact Rounded
+precision: 10
+divx633 divide -3374988581607586061255542201048 82293895124.90045271504836568681 -> -4.101140888E+19         Inexact Rounded
+precision:  9
+divx634 divide -3374988581607586061255542201048 82293895124.90045271504836568681 -> -4.10114089E+19         Inexact Rounded
+precision:  8
+divx635 divide -3374988581607586061255542201048 82293895124.90045271504836568681 -> -4.1011409E+19         Inexact Rounded
+precision:  7
+divx636 divide -3374988581607586061255542201048 82293895124.90045271504836568681 -> -4.101141E+19         Inexact Rounded
+precision:  6
+divx637 divide -3374988581607586061255542201048 82293895124.90045271504836568681 -> -4.10114E+19         Inexact Rounded
+precision:  5
+divx638 divide -3374988581607586061255542201048 82293895124.90045271504836568681 -> -4.1011E+19         Inexact Rounded
+precision:  4
+divx639 divide -3374988581607586061255542201048 82293895124.90045271504836568681 -> -4.101E+19         Inexact Rounded
+precision:  3
+divx640 divide -3374988581607586061255542201048 82293895124.90045271504836568681 -> -4.10E+19         Inexact Rounded
+precision:  2
+divx641 divide -3374988581607586061255542201048 82293895124.90045271504836568681 -> -4.1E+19         Inexact Rounded
+precision:  1
+divx642 divide -3374988581607586061255542201048 82293895124.90045271504836568681 -> -4E+19         Inexact Rounded
+
+-- more zeros, etc.
+precision:   16
+rounding:    half_up
+maxExponent: 384
+minExponent: -383
+
+divx731 divide 5.00 1E-3    -> 5.00E+3
+divx732 divide 00.00 0.000  -> NaN Division_undefined
+divx733 divide 00.00 0E-3   -> NaN Division_undefined
+divx734 divide  0    -0     -> NaN Division_undefined
+divx735 divide -0     0     -> NaN Division_undefined
+divx736 divide -0    -0     -> NaN Division_undefined
+
+divx741 divide  0    -1     -> -0
+divx742 divide -0    -1     ->  0
+divx743 divide  0     1     ->  0
+divx744 divide -0     1     -> -0
+divx745 divide -1     0     -> -Infinity Division_by_zero
+divx746 divide -1    -0     ->  Infinity Division_by_zero
+divx747 divide  1     0     ->  Infinity Division_by_zero
+divx748 divide  1    -0     -> -Infinity Division_by_zero
+
+divx751 divide  0.0  -1     -> -0.0
+divx752 divide -0.0  -1     ->  0.0
+divx753 divide  0.0   1     ->  0.0
+divx754 divide -0.0   1     -> -0.0
+divx755 divide -1.0   0     -> -Infinity Division_by_zero
+divx756 divide -1.0  -0     ->  Infinity Division_by_zero
+divx757 divide  1.0   0     ->  Infinity Division_by_zero
+divx758 divide  1.0  -0     -> -Infinity Division_by_zero
+
+divx761 divide  0    -1.0   -> -0E+1
+divx762 divide -0    -1.0   ->  0E+1
+divx763 divide  0     1.0   ->  0E+1
+divx764 divide -0     1.0   -> -0E+1
+divx765 divide -1     0.0   -> -Infinity Division_by_zero
+divx766 divide -1    -0.0   ->  Infinity Division_by_zero
+divx767 divide  1     0.0   ->  Infinity Division_by_zero
+divx768 divide  1    -0.0   -> -Infinity Division_by_zero
+
+divx771 divide  0.0  -1.0   -> -0
+divx772 divide -0.0  -1.0   ->  0
+divx773 divide  0.0   1.0   ->  0
+divx774 divide -0.0   1.0   -> -0
+divx775 divide -1.0   0.0   -> -Infinity Division_by_zero
+divx776 divide -1.0  -0.0   ->  Infinity Division_by_zero
+divx777 divide  1.0   0.0   ->  Infinity Division_by_zero
+divx778 divide  1.0  -0.0   -> -Infinity Division_by_zero
+
+-- Specials
+divx780 divide  Inf  -Inf   ->  NaN Invalid_operation
+divx781 divide  Inf  -1000  -> -Infinity
+divx782 divide  Inf  -1     -> -Infinity
+divx783 divide  Inf  -0     -> -Infinity
+divx784 divide  Inf   0     ->  Infinity
+divx785 divide  Inf   1     ->  Infinity
+divx786 divide  Inf   1000  ->  Infinity
+divx787 divide  Inf   Inf   ->  NaN Invalid_operation
+divx788 divide -1000  Inf   -> -0E-398 Clamped
+divx789 divide -Inf   Inf   ->  NaN Invalid_operation
+divx790 divide -1     Inf   -> -0E-398 Clamped
+divx791 divide -0     Inf   -> -0E-398 Clamped
+divx792 divide  0     Inf   ->  0E-398 Clamped
+divx793 divide  1     Inf   ->  0E-398 Clamped
+divx794 divide  1000  Inf   ->  0E-398 Clamped
+divx795 divide  Inf   Inf   ->  NaN Invalid_operation
+
+divx800 divide -Inf  -Inf   ->  NaN Invalid_operation
+divx801 divide -Inf  -1000  ->  Infinity
+divx802 divide -Inf  -1     ->  Infinity
+divx803 divide -Inf  -0     ->  Infinity
+divx804 divide -Inf   0     -> -Infinity
+divx805 divide -Inf   1     -> -Infinity
+divx806 divide -Inf   1000  -> -Infinity
+divx807 divide -Inf   Inf   ->  NaN Invalid_operation
+divx808 divide -1000  Inf   -> -0E-398 Clamped
+divx809 divide -Inf  -Inf   ->  NaN Invalid_operation
+divx810 divide -1    -Inf   ->  0E-398 Clamped
+divx811 divide -0    -Inf   ->  0E-398 Clamped
+divx812 divide  0    -Inf   -> -0E-398 Clamped
+divx813 divide  1    -Inf   -> -0E-398 Clamped
+divx814 divide  1000 -Inf   -> -0E-398 Clamped
+divx815 divide  Inf  -Inf   ->  NaN Invalid_operation
+
+divx821 divide  NaN -Inf    ->  NaN
+divx822 divide  NaN -1000   ->  NaN
+divx823 divide  NaN -1      ->  NaN
+divx824 divide  NaN -0      ->  NaN
+divx825 divide  NaN  0      ->  NaN
+divx826 divide  NaN  1      ->  NaN
+divx827 divide  NaN  1000   ->  NaN
+divx828 divide  NaN  Inf    ->  NaN
+divx829 divide  NaN  NaN    ->  NaN
+divx830 divide -Inf  NaN    ->  NaN
+divx831 divide -1000 NaN    ->  NaN
+divx832 divide -1    NaN    ->  NaN
+divx833 divide -0    NaN    ->  NaN
+divx834 divide  0    NaN    ->  NaN
+divx835 divide  1    NaN    ->  NaN
+divx836 divide  1000 NaN    ->  NaN
+divx837 divide  Inf  NaN    ->  NaN
+
+divx841 divide  sNaN -Inf   ->  NaN  Invalid_operation
+divx842 divide  sNaN -1000  ->  NaN  Invalid_operation
+divx843 divide  sNaN -1     ->  NaN  Invalid_operation
+divx844 divide  sNaN -0     ->  NaN  Invalid_operation
+divx845 divide  sNaN  0     ->  NaN  Invalid_operation
+divx846 divide  sNaN  1     ->  NaN  Invalid_operation
+divx847 divide  sNaN  1000  ->  NaN  Invalid_operation
+divx848 divide  sNaN  NaN   ->  NaN  Invalid_operation
+divx849 divide  sNaN sNaN   ->  NaN  Invalid_operation
+divx850 divide  NaN  sNaN   ->  NaN  Invalid_operation
+divx851 divide -Inf  sNaN   ->  NaN  Invalid_operation
+divx852 divide -1000 sNaN   ->  NaN  Invalid_operation
+divx853 divide -1    sNaN   ->  NaN  Invalid_operation
+divx854 divide -0    sNaN   ->  NaN  Invalid_operation
+divx855 divide  0    sNaN   ->  NaN  Invalid_operation
+divx856 divide  1    sNaN   ->  NaN  Invalid_operation
+divx857 divide  1000 sNaN   ->  NaN  Invalid_operation
+divx858 divide  Inf  sNaN   ->  NaN  Invalid_operation
+divx859 divide  NaN  sNaN   ->  NaN  Invalid_operation
+
+-- propagating NaNs
+divx861 divide  NaN9 -Inf   ->  NaN9
+divx862 divide  NaN8  1000  ->  NaN8
+divx863 divide  NaN7  Inf   ->  NaN7
+divx864 divide  NaN6  NaN5  ->  NaN6
+divx865 divide -Inf   NaN4  ->  NaN4
+divx866 divide -1000  NaN3  ->  NaN3
+divx867 divide  Inf   NaN2  ->  NaN2
+
+divx871 divide  sNaN99 -Inf    ->  NaN99 Invalid_operation
+divx872 divide  sNaN98 -1      ->  NaN98 Invalid_operation
+divx873 divide  sNaN97  NaN    ->  NaN97 Invalid_operation
+divx874 divide  sNaN96 sNaN94  ->  NaN96 Invalid_operation
+divx875 divide  NaN95  sNaN93  ->  NaN93 Invalid_operation
+divx876 divide -Inf    sNaN92  ->  NaN92 Invalid_operation
+divx877 divide  0      sNaN91  ->  NaN91 Invalid_operation
+divx878 divide  Inf    sNaN90  ->  NaN90 Invalid_operation
+divx879 divide  NaN    sNaN89  ->  NaN89 Invalid_operation
+
+divx881 divide  -NaN9  -Inf   ->  -NaN9
+divx882 divide  -NaN8   1000  ->  -NaN8
+divx883 divide  -NaN7   Inf   ->  -NaN7
+divx884 divide  -NaN6  -NaN5  ->  -NaN6
+divx885 divide  -Inf   -NaN4  ->  -NaN4
+divx886 divide  -1000  -NaN3  ->  -NaN3
+divx887 divide   Inf   -NaN2  ->  -NaN2
+
+divx891 divide -sNaN99 -Inf    -> -NaN99 Invalid_operation
+divx892 divide -sNaN98 -1      -> -NaN98 Invalid_operation
+divx893 divide -sNaN97  NaN    -> -NaN97 Invalid_operation
+divx894 divide -sNaN96 -sNaN94 -> -NaN96 Invalid_operation
+divx895 divide -NaN95  -sNaN93 -> -NaN93 Invalid_operation
+divx896 divide -Inf    -sNaN92 -> -NaN92 Invalid_operation
+divx897 divide  0      -sNaN91 -> -NaN91 Invalid_operation
+divx898 divide  Inf    -sNaN90 -> -NaN90 Invalid_operation
+divx899 divide -NaN    -sNaN89 -> -NaN89 Invalid_operation
+
+maxexponent: 999999999
+minexponent: -999999999
+
+-- Various flavours of divide by 0
+divx901 divide    0       0   ->  NaN Division_undefined
+divx902 divide    0.0E5   0   ->  NaN Division_undefined
+divx903 divide    0.000   0   ->  NaN Division_undefined
+divx904 divide    0.0001  0   ->  Infinity Division_by_zero
+divx905 divide    0.01    0   ->  Infinity Division_by_zero
+divx906 divide    0.1     0   ->  Infinity Division_by_zero
+divx907 divide    1       0   ->  Infinity Division_by_zero
+divx908 divide    1       0.0 ->  Infinity Division_by_zero
+divx909 divide   10       0.0 ->  Infinity Division_by_zero
+divx910 divide   1E+100   0.0 ->  Infinity Division_by_zero
+divx911 divide   1E+1000  0   ->  Infinity Division_by_zero
+
+divx921 divide   -0.0001  0   -> -Infinity Division_by_zero
+divx922 divide   -0.01    0   -> -Infinity Division_by_zero
+divx923 divide   -0.1     0   -> -Infinity Division_by_zero
+divx924 divide   -1       0   -> -Infinity Division_by_zero
+divx925 divide   -1       0.0 -> -Infinity Division_by_zero
+divx926 divide  -10       0.0 -> -Infinity Division_by_zero
+divx927 divide  -1E+100   0.0 -> -Infinity Division_by_zero
+divx928 divide  -1E+1000  0   -> -Infinity Division_by_zero
+
+divx931 divide    0.0001 -0   -> -Infinity Division_by_zero
+divx932 divide    0.01   -0   -> -Infinity Division_by_zero
+divx933 divide    0.1    -0   -> -Infinity Division_by_zero
+divx934 divide    1      -0   -> -Infinity Division_by_zero
+divx935 divide    1      -0.0 -> -Infinity Division_by_zero
+divx936 divide   10      -0.0 -> -Infinity Division_by_zero
+divx937 divide   1E+100  -0.0 -> -Infinity Division_by_zero
+divx938 divide   1E+1000 -0   -> -Infinity Division_by_zero
+
+divx941 divide   -0.0001 -0   ->  Infinity Division_by_zero
+divx942 divide   -0.01   -0   ->  Infinity Division_by_zero
+divx943 divide   -0.1    -0   ->  Infinity Division_by_zero
+divx944 divide   -1      -0   ->  Infinity Division_by_zero
+divx945 divide   -1      -0.0 ->  Infinity Division_by_zero
+divx946 divide  -10      -0.0 ->  Infinity Division_by_zero
+divx947 divide  -1E+100  -0.0 ->  Infinity Division_by_zero
+divx948 divide  -1E+1000 -0   ->  Infinity Division_by_zero
+
+-- overflow and underflow tests
+precision: 9
+maxexponent: 999999999
+minexponent: -999999999
+divx951 divide 9E+999999999 +0.23456789012345E-0 -> Infinity Inexact Overflow Rounded
+divx952 divide +0.100 9E+999999999 -> 1.111111E-1000000001 Inexact Rounded Underflow Subnormal
+divx953 divide 9E-999999999 +9.100 -> 9.8901099E-1000000000 Inexact Rounded Underflow Subnormal
+divx954 divide -1.23456789          9E+999999999 -> -1.3717421E-1000000000 Subnormal
+divx955 divide -1.23456789012345E-0 9E+999999999 -> -1.3717421E-1000000000 Underflow Subnormal Rounded Inexact
+divx956 divide -1.23456789012345E-0 7E+999999999 -> -1.7636684E-1000000000 Inexact Rounded Underflow Subnormal
+divx957 divide 9E+999999999 -0.83456789012345E-0 -> -Infinity Inexact Overflow Rounded
+divx958 divide -0.100 9E+999999999 -> -1.111111E-1000000001 Subnormal Inexact Rounded Underflow
+divx959 divide 9E-999999999 -9.100 -> -9.8901099E-1000000000 Inexact Rounded Underflow Subnormal
+
+-- overflow and underflow (additional edge tests in multiply.decTest)
+-- 'subnormal' results now possible (all hard underflow or overflow in
+-- base arithemtic)
+divx960 divide 1e-600000000 1e+400000001 -> 1E-1000000001 Subnormal
+divx961 divide 1e-600000000 1e+400000002 -> 1E-1000000002 Subnormal
+divx962 divide 1e-600000000 1e+400000003 -> 1E-1000000003 Subnormal
+divx963 divide 1e-600000000 1e+400000004 -> 1E-1000000004 Subnormal
+divx964 divide 1e-600000000 1e+400000005 -> 1E-1000000005 Subnormal
+divx965 divide 1e-600000000 1e+400000006 -> 1E-1000000006 Subnormal
+divx966 divide 1e-600000000 1e+400000007 -> 1E-1000000007 Subnormal
+divx967 divide 1e-600000000 1e+400000008 -> 0E-1000000007 Underflow Subnormal Inexact Rounded
+divx968 divide 1e-600000000 1e+400000009 -> 0E-1000000007 Underflow Subnormal Inexact Rounded
+divx969 divide 1e-600000000 1e+400000010 -> 0E-1000000007 Underflow Subnormal Inexact Rounded
+-- [no equivalent of 'subnormal' for overflow]
+divx970 divide 1e+600000000 1e-400000001 -> Infinity Overflow Inexact Rounded
+divx971 divide 1e+600000000 1e-400000002 -> Infinity Overflow Inexact Rounded
+divx972 divide 1e+600000000 1e-400000003 -> Infinity Overflow Inexact Rounded
+divx973 divide 1e+600000000 1e-400000004 -> Infinity Overflow Inexact Rounded
+divx974 divide 1e+600000000 1e-400000005 -> Infinity Overflow Inexact Rounded
+divx975 divide 1e+600000000 1e-400000006 -> Infinity Overflow Inexact Rounded
+divx976 divide 1e+600000000 1e-400000007 -> Infinity Overflow Inexact Rounded
+divx977 divide 1e+600000000 1e-400000008 -> Infinity Overflow Inexact Rounded
+divx978 divide 1e+600000000 1e-400000009 -> Infinity Overflow Inexact Rounded
+divx979 divide 1e+600000000 1e-400000010 -> Infinity Overflow Inexact Rounded
+
+-- Sign after overflow and underflow
+divx980 divide  1e-600000000  1e+400000009 ->  0E-1000000007 Underflow Subnormal Inexact Rounded
+divx981 divide  1e-600000000 -1e+400000009 -> -0E-1000000007 Underflow Subnormal Inexact Rounded
+divx982 divide -1e-600000000  1e+400000009 -> -0E-1000000007 Underflow Subnormal Inexact Rounded
+divx983 divide -1e-600000000 -1e+400000009 ->  0E-1000000007 Underflow Subnormal Inexact Rounded
+divx984 divide  1e+600000000  1e-400000009 ->  Infinity Overflow Inexact Rounded
+divx985 divide  1e+600000000 -1e-400000009 -> -Infinity Overflow Inexact Rounded
+divx986 divide -1e+600000000  1e-400000009 -> -Infinity Overflow Inexact Rounded
+divx987 divide -1e+600000000 -1e-400000009 ->  Infinity Overflow Inexact Rounded
+
+-- Long operand overflow may be a different path
+precision: 3
+divx990 divide 1000  9.999E-999999999      ->  Infinity Inexact Overflow Rounded
+divx991 divide 1000 -9.999E-999999999      -> -Infinity Inexact Overflow Rounded
+divx992 divide       9.999E+999999999 0.01 ->  Infinity Inexact Overflow Rounded
+divx993 divide      -9.999E+999999999 0.01 -> -Infinity Inexact Overflow Rounded
+
+-- check for double-rounded subnormals
+precision:   5
+maxexponent: 79
+minexponent: -79
+divx1001 divide    1.52444E-80 1      -> 1.524E-80 Inexact Rounded Subnormal Underflow
+divx1002 divide    1.52445E-80 1      -> 1.524E-80 Inexact Rounded Subnormal Underflow
+divx1003 divide    1.52446E-80 1      -> 1.524E-80 Inexact Rounded Subnormal Underflow
+
+-- a rounding problem in one implementation
+precision:   34
+rounding:    half_up
+maxExponent: 6144
+minExponent: -6143
+-- Unbounded answer to 40 digits:
+--   1.465811965811965811965811965811965811966E+7000
+divx1010 divide 343E6000  234E-1000 -> Infinity Overflow Inexact Rounded
+
+-- Null tests
+divx9998 divide 10  # -> NaN Invalid_operation
+divx9999 divide  # 10 -> NaN Invalid_operation
+

Added: vendor/Python/current/Lib/test/decimaltestdata/divideint.decTest
===================================================================
--- vendor/Python/current/Lib/test/decimaltestdata/divideint.decTest	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/decimaltestdata/divideint.decTest	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,470 @@
+------------------------------------------------------------------------
+-- divideint.decTest -- decimal integer division                      --
+-- Copyright (c) IBM Corporation, 1981, 2004.  All rights reserved.   --
+------------------------------------------------------------------------
+-- Please see the document "General Decimal Arithmetic Testcases"     --
+-- at http://www2.hursley.ibm.com/decimal for the description of      --
+-- these testcases.                                                   --
+--                                                                    --
+-- These testcases are experimental ('beta' versions), and they       --
+-- may contain errors.  They are offered on an as-is basis.  In       --
+-- particular, achieving the same results as the tests here is not    --
+-- a guarantee that an implementation complies with any Standard      --
+-- or specification.  The tests are not exhaustive.                   --
+--                                                                    --
+-- Please send comments, suggestions, and corrections to the author:  --
+--   Mike Cowlishaw, IBM Fellow                                       --
+--   IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK         --
+--   mfc at uk.ibm.com                                                   --
+------------------------------------------------------------------------
+version: 2.39
+
+extended:    1
+precision:   9
+rounding:    half_up
+maxExponent: 384
+minexponent: -383
+
+dvix001 divideint  1     1    ->  1
+dvix002 divideint  2     1    ->  2
+dvix003 divideint  1     2    ->  0
+dvix004 divideint  2     2    ->  1
+dvix005 divideint  0     1    ->  0
+dvix006 divideint  0     2    ->  0
+dvix007 divideint  1     3    ->  0
+dvix008 divideint  2     3    ->  0
+dvix009 divideint  3     3    ->  1
+
+dvix010 divideint  2.4   1    ->  2
+dvix011 divideint  2.4   -1   ->  -2
+dvix012 divideint  -2.4  1    ->  -2
+dvix013 divideint  -2.4  -1   ->  2
+dvix014 divideint  2.40  1    ->  2
+dvix015 divideint  2.400 1    ->  2
+dvix016 divideint  2.4   2    ->  1
+dvix017 divideint  2.400 2    ->  1
+dvix018 divideint  2.    2    ->  1
+dvix019 divideint  20    20   ->  1
+
+dvix020 divideint  187   187  ->  1
+dvix021 divideint  5     2    ->  2
+dvix022 divideint  5     2.0    ->  2
+dvix023 divideint  5     2.000  ->  2
+dvix024 divideint  5     0.200  ->  25
+dvix025 divideint  5     0.200  ->  25
+
+dvix030 divideint  1     2      ->  0
+dvix031 divideint  1     4      ->  0
+dvix032 divideint  1     8      ->  0
+dvix033 divideint  1     16     ->  0
+dvix034 divideint  1     32     ->  0
+dvix035 divideint  1     64     ->  0
+dvix040 divideint  1    -2      -> -0
+dvix041 divideint  1    -4      -> -0
+dvix042 divideint  1    -8      -> -0
+dvix043 divideint  1    -16     -> -0
+dvix044 divideint  1    -32     -> -0
+dvix045 divideint  1    -64     -> -0
+dvix050 divideint -1     2      -> -0
+dvix051 divideint -1     4      -> -0
+dvix052 divideint -1     8      -> -0
+dvix053 divideint -1     16     -> -0
+dvix054 divideint -1     32     -> -0
+dvix055 divideint -1     64     -> -0
+dvix060 divideint -1    -2      ->  0
+dvix061 divideint -1    -4      ->  0
+dvix062 divideint -1    -8      ->  0
+dvix063 divideint -1    -16     ->  0
+dvix064 divideint -1    -32     ->  0
+dvix065 divideint -1    -64     ->  0
+
+-- similar with powers of ten
+dvix160 divideint  1     1         ->  1
+dvix161 divideint  1     10        ->  0
+dvix162 divideint  1     100       ->  0
+dvix163 divideint  1     1000      ->  0
+dvix164 divideint  1     10000     ->  0
+dvix165 divideint  1     100000    ->  0
+dvix166 divideint  1     1000000   ->  0
+dvix167 divideint  1     10000000  ->  0
+dvix168 divideint  1     100000000 ->  0
+dvix170 divideint  1    -1         -> -1
+dvix171 divideint  1    -10        -> -0
+dvix172 divideint  1    -100       -> -0
+dvix173 divideint  1    -1000      -> -0
+dvix174 divideint  1    -10000     -> -0
+dvix175 divideint  1    -100000    -> -0
+dvix176 divideint  1    -1000000   -> -0
+dvix177 divideint  1    -10000000  -> -0
+dvix178 divideint  1    -100000000 -> -0
+dvix180 divideint -1     1         -> -1
+dvix181 divideint -1     10        -> -0
+dvix182 divideint -1     100       -> -0
+dvix183 divideint -1     1000      -> -0
+dvix184 divideint -1     10000     -> -0
+dvix185 divideint -1     100000    -> -0
+dvix186 divideint -1     1000000   -> -0
+dvix187 divideint -1     10000000  -> -0
+dvix188 divideint -1     100000000 -> -0
+dvix190 divideint -1    -1         ->  1
+dvix191 divideint -1    -10        ->  0
+dvix192 divideint -1    -100       ->  0
+dvix193 divideint -1    -1000      ->  0
+dvix194 divideint -1    -10000     ->  0
+dvix195 divideint -1    -100000    ->  0
+dvix196 divideint -1    -1000000   ->  0
+dvix197 divideint -1    -10000000  ->  0
+dvix198 divideint -1    -100000000 ->  0
+
+-- some long operand cases here
+dvix070 divideint  999999999     1  ->  999999999
+dvix071 divideint  999999999.4   1  ->  999999999
+dvix072 divideint  999999999.5   1  ->  999999999
+dvix073 divideint  999999999.9   1  ->  999999999
+dvix074 divideint  999999999.999 1  ->  999999999
+precision: 6
+dvix080 divideint  999999999     1  ->  NaN Division_impossible
+dvix081 divideint  99999999      1  ->  NaN Division_impossible
+dvix082 divideint  9999999       1  ->  NaN Division_impossible
+dvix083 divideint  999999        1  ->  999999
+dvix084 divideint  99999         1  ->  99999
+dvix085 divideint  9999          1  ->  9999
+dvix086 divideint  999           1  ->  999
+dvix087 divideint  99            1  ->  99
+dvix088 divideint  9             1  ->  9
+
+precision: 9
+dvix090 divideint  0.            1    ->  0
+dvix091 divideint  .0            1    ->  0
+dvix092 divideint  0.00          1    ->  0
+dvix093 divideint  0.00E+9       1    ->  0
+dvix094 divideint  0.0000E-50    1    ->  0
+
+dvix100 divideint  1  1   -> 1
+dvix101 divideint  1  2   -> 0
+dvix102 divideint  1  3   -> 0
+dvix103 divideint  1  4   -> 0
+dvix104 divideint  1  5   -> 0
+dvix105 divideint  1  6   -> 0
+dvix106 divideint  1  7   -> 0
+dvix107 divideint  1  8   -> 0
+dvix108 divideint  1  9   -> 0
+dvix109 divideint  1  10  -> 0
+dvix110 divideint  1  1   -> 1
+dvix111 divideint  2  1   -> 2
+dvix112 divideint  3  1   -> 3
+dvix113 divideint  4  1   -> 4
+dvix114 divideint  5  1   -> 5
+dvix115 divideint  6  1   -> 6
+dvix116 divideint  7  1   -> 7
+dvix117 divideint  8  1   -> 8
+dvix118 divideint  9  1   -> 9
+dvix119 divideint  10 1   -> 10
+
+-- from DiagBigDecimal
+dvix131 divideint  101.3   1     ->  101
+dvix132 divideint  101.0   1     ->  101
+dvix133 divideint  101.3   3     ->  33
+dvix134 divideint  101.0   3     ->  33
+dvix135 divideint  2.4     1     ->  2
+dvix136 divideint  2.400   1     ->  2
+dvix137 divideint  18      18    ->  1
+dvix138 divideint  1120    1000  ->  1
+dvix139 divideint  2.4     2     ->  1
+dvix140 divideint  2.400   2     ->  1
+dvix141 divideint  0.5     2.000 ->  0
+dvix142 divideint  8.005   7     ->  1
+dvix143 divideint  5       2     ->  2
+dvix144 divideint  0       2     ->  0
+dvix145 divideint  0.00    2     ->  0
+
+-- Others
+dvix150 divideint  12345  4.999  ->  2469
+dvix151 divideint  12345  4.99   ->  2473
+dvix152 divideint  12345  4.9    ->  2519
+dvix153 divideint  12345  5      ->  2469
+dvix154 divideint  12345  5.1    ->  2420
+dvix155 divideint  12345  5.01   ->  2464
+dvix156 divideint  12345  5.001  ->  2468
+dvix157 divideint    101  7.6    ->  13
+
+-- Various flavours of divideint by 0
+maxexponent: 999999999
+minexponent: -999999999
+dvix201 divideint  0      0   -> NaN Division_undefined
+dvix202 divideint  0.0E5  0   -> NaN Division_undefined
+dvix203 divideint  0.000  0   -> NaN Division_undefined
+dvix204 divideint  0.0001 0   -> Infinity Division_by_zero
+dvix205 divideint  0.01   0   -> Infinity Division_by_zero
+dvix206 divideint  0.1    0   -> Infinity Division_by_zero
+dvix207 divideint  1      0   -> Infinity Division_by_zero
+dvix208 divideint  1      0.0 -> Infinity Division_by_zero
+dvix209 divideint 10      0.0 -> Infinity Division_by_zero
+dvix210 divideint 1E+100  0.0 -> Infinity Division_by_zero
+dvix211 divideint 1E+1000 0   -> Infinity Division_by_zero
+dvix214 divideint  -0.0001 0   -> -Infinity Division_by_zero
+dvix215 divideint  -0.01   0   -> -Infinity Division_by_zero
+dvix216 divideint  -0.1    0   -> -Infinity Division_by_zero
+dvix217 divideint  -1      0   -> -Infinity Division_by_zero
+dvix218 divideint  -1      0.0 -> -Infinity Division_by_zero
+dvix219 divideint -10      0.0 -> -Infinity Division_by_zero
+dvix220 divideint -1E+100  0.0 -> -Infinity Division_by_zero
+dvix221 divideint -1E+1000 0   -> -Infinity Division_by_zero
+
+-- test some cases that are close to exponent overflow
+maxexponent: 999999999
+minexponent: -999999999
+dvix270 divideint 1 1e999999999    -> 0
+dvix271 divideint 1 0.9e999999999  -> 0
+dvix272 divideint 1 0.99e999999999 -> 0
+dvix273 divideint 1 0.999999999e999999999 -> 0
+dvix274 divideint 9e999999999    1       -> NaN Division_impossible
+dvix275 divideint 9.9e999999999  1       -> NaN Division_impossible
+dvix276 divideint 9.99e999999999 1       -> NaN Division_impossible
+dvix277 divideint 9.99999999e999999999 1 -> NaN Division_impossible
+
+dvix280 divideint 0.1 9e-999999999       -> NaN Division_impossible
+dvix281 divideint 0.1 99e-999999999      -> NaN Division_impossible
+dvix282 divideint 0.1 999e-999999999     -> NaN Division_impossible
+
+dvix283 divideint 0.1 9e-999999998       -> NaN Division_impossible
+dvix284 divideint 0.1 99e-999999998      -> NaN Division_impossible
+dvix285 divideint 0.1 999e-999999998     -> NaN Division_impossible
+dvix286 divideint 0.1 999e-999999997     -> NaN Division_impossible
+dvix287 divideint 0.1 9999e-999999997    -> NaN Division_impossible
+dvix288 divideint 0.1 99999e-999999997   -> NaN Division_impossible
+
+
+-- overflow and underflow tests [from divide]
+maxexponent: 999999999
+minexponent: -999999999
+dvix330 divideint +1.23456789012345E-0 9E+999999999    -> 0
+dvix331 divideint 9E+999999999 +0.23456789012345E-0 -> NaN Division_impossible
+dvix332 divideint +0.100 9E+999999999    -> 0
+dvix333 divideint 9E-999999999 +9.100    -> 0
+dvix335 divideint -1.23456789012345E-0 9E+999999999    -> -0
+dvix336 divideint 9E+999999999 -0.83456789012345E-0 -> NaN Division_impossible
+dvix337 divideint -0.100 9E+999999999    -> -0
+dvix338 divideint 9E-999999999 -9.100    -> -0
+
+-- long operand checks
+maxexponent: 999
+minexponent: -999
+precision: 9
+dvix401 divideint 12345678000 100 -> 123456780
+dvix402 divideint 1 12345678000   -> 0
+dvix403 divideint 1234567800  10  -> 123456780
+dvix404 divideint 1 1234567800    -> 0
+dvix405 divideint 1234567890  10  -> 123456789
+dvix406 divideint 1 1234567890    -> 0
+dvix407 divideint 1234567891  10  -> 123456789
+dvix408 divideint 1 1234567891    -> 0
+dvix409 divideint 12345678901 100 -> 123456789
+dvix410 divideint 1 12345678901   -> 0
+dvix411 divideint 1234567896  10  -> 123456789
+dvix412 divideint 1 1234567896    -> 0
+dvix413 divideint 12345678948 100 -> 123456789
+dvix414 divideint 12345678949 100 -> 123456789
+dvix415 divideint 12345678950 100 -> 123456789
+dvix416 divideint 12345678951 100 -> 123456789
+dvix417 divideint 12345678999 100 -> 123456789
+
+precision: 15
+dvix441 divideint 12345678000 1 -> 12345678000
+dvix442 divideint 1 12345678000 -> 0
+dvix443 divideint 1234567800  1 -> 1234567800
+dvix444 divideint 1 1234567800  -> 0
+dvix445 divideint 1234567890  1 -> 1234567890
+dvix446 divideint 1 1234567890  -> 0
+dvix447 divideint 1234567891  1 -> 1234567891
+dvix448 divideint 1 1234567891  -> 0
+dvix449 divideint 12345678901 1 -> 12345678901
+dvix450 divideint 1 12345678901 -> 0
+dvix451 divideint 1234567896  1 -> 1234567896
+dvix452 divideint 1 1234567896  -> 0
+
+precision:   9
+rounding:    half_up
+maxExponent: 999
+minexponent: -999
+
+-- more zeros, etc.
+dvix531 divideint 5.00 1E-3    -> 5000
+dvix532 divideint 00.00 0.000  -> NaN Division_undefined
+dvix533 divideint 00.00 0E-3   -> NaN Division_undefined
+dvix534 divideint  0    -0     -> NaN Division_undefined
+dvix535 divideint -0     0     -> NaN Division_undefined
+dvix536 divideint -0    -0     -> NaN Division_undefined
+
+dvix541 divideint  0    -1     -> -0
+dvix542 divideint -0    -1     ->  0
+dvix543 divideint  0     1     ->  0
+dvix544 divideint -0     1     -> -0
+dvix545 divideint -1     0     -> -Infinity Division_by_zero
+dvix546 divideint -1    -0     ->  Infinity Division_by_zero
+dvix547 divideint  1     0     ->  Infinity Division_by_zero
+dvix548 divideint  1    -0     -> -Infinity Division_by_zero
+
+dvix551 divideint  0.0  -1     -> -0
+dvix552 divideint -0.0  -1     ->  0
+dvix553 divideint  0.0   1     ->  0
+dvix554 divideint -0.0   1     -> -0
+dvix555 divideint -1.0   0     -> -Infinity Division_by_zero
+dvix556 divideint -1.0  -0     ->  Infinity Division_by_zero
+dvix557 divideint  1.0   0     ->  Infinity Division_by_zero
+dvix558 divideint  1.0  -0     -> -Infinity Division_by_zero
+
+dvix561 divideint  0    -1.0   -> -0
+dvix562 divideint -0    -1.0   ->  0
+dvix563 divideint  0     1.0   ->  0
+dvix564 divideint -0     1.0   -> -0
+dvix565 divideint -1     0.0   -> -Infinity Division_by_zero
+dvix566 divideint -1    -0.0   ->  Infinity Division_by_zero
+dvix567 divideint  1     0.0   ->  Infinity Division_by_zero
+dvix568 divideint  1    -0.0   -> -Infinity Division_by_zero
+
+dvix571 divideint  0.0  -1.0   -> -0
+dvix572 divideint -0.0  -1.0   ->  0
+dvix573 divideint  0.0   1.0   ->  0
+dvix574 divideint -0.0   1.0   -> -0
+dvix575 divideint -1.0   0.0   -> -Infinity Division_by_zero
+dvix576 divideint -1.0  -0.0   ->  Infinity Division_by_zero
+dvix577 divideint  1.0   0.0   ->  Infinity Division_by_zero
+dvix578 divideint  1.0  -0.0   -> -Infinity Division_by_zero
+
+-- Specials
+dvix580 divideint  Inf  -Inf   ->  NaN Invalid_operation
+dvix581 divideint  Inf  -1000  -> -Infinity
+dvix582 divideint  Inf  -1     -> -Infinity
+dvix583 divideint  Inf  -0     -> -Infinity
+dvix584 divideint  Inf   0     ->  Infinity
+dvix585 divideint  Inf   1     ->  Infinity
+dvix586 divideint  Inf   1000  ->  Infinity
+dvix587 divideint  Inf   Inf   ->  NaN Invalid_operation
+dvix588 divideint -1000  Inf   -> -0
+dvix589 divideint -Inf   Inf   ->  NaN Invalid_operation
+dvix590 divideint -1     Inf   -> -0
+dvix591 divideint -0     Inf   -> -0
+dvix592 divideint  0     Inf   ->  0
+dvix593 divideint  1     Inf   ->  0
+dvix594 divideint  1000  Inf   ->  0
+dvix595 divideint  Inf   Inf   ->  NaN Invalid_operation
+
+dvix600 divideint -Inf  -Inf   ->  NaN Invalid_operation
+dvix601 divideint -Inf  -1000  ->  Infinity
+dvix602 divideint -Inf  -1     ->  Infinity
+dvix603 divideint -Inf  -0     ->  Infinity
+dvix604 divideint -Inf   0     -> -Infinity
+dvix605 divideint -Inf   1     -> -Infinity
+dvix606 divideint -Inf   1000  -> -Infinity
+dvix607 divideint -Inf   Inf   ->  NaN Invalid_operation
+dvix608 divideint -1000  Inf   -> -0
+dvix609 divideint -Inf  -Inf   ->  NaN Invalid_operation
+dvix610 divideint -1    -Inf   ->  0
+dvix611 divideint -0    -Inf   ->  0
+dvix612 divideint  0    -Inf   -> -0
+dvix613 divideint  1    -Inf   -> -0
+dvix614 divideint  1000 -Inf   -> -0
+dvix615 divideint  Inf  -Inf   ->  NaN Invalid_operation
+
+dvix621 divideint  NaN -Inf    ->  NaN
+dvix622 divideint  NaN -1000   ->  NaN
+dvix623 divideint  NaN -1      ->  NaN
+dvix624 divideint  NaN -0      ->  NaN
+dvix625 divideint  NaN  0      ->  NaN
+dvix626 divideint  NaN  1      ->  NaN
+dvix627 divideint  NaN  1000   ->  NaN
+dvix628 divideint  NaN  Inf    ->  NaN
+dvix629 divideint  NaN  NaN    ->  NaN
+dvix630 divideint -Inf  NaN    ->  NaN
+dvix631 divideint -1000 NaN    ->  NaN
+dvix632 divideint -1    NaN    ->  NaN
+dvix633 divideint -0    NaN    ->  NaN
+dvix634 divideint  0    NaN    ->  NaN
+dvix635 divideint  1    NaN    ->  NaN
+dvix636 divideint  1000 NaN    ->  NaN
+dvix637 divideint  Inf  NaN    ->  NaN
+
+dvix641 divideint  sNaN -Inf   ->  NaN  Invalid_operation
+dvix642 divideint  sNaN -1000  ->  NaN  Invalid_operation
+dvix643 divideint  sNaN -1     ->  NaN  Invalid_operation
+dvix644 divideint  sNaN -0     ->  NaN  Invalid_operation
+dvix645 divideint  sNaN  0     ->  NaN  Invalid_operation
+dvix646 divideint  sNaN  1     ->  NaN  Invalid_operation
+dvix647 divideint  sNaN  1000  ->  NaN  Invalid_operation
+dvix648 divideint  sNaN  NaN   ->  NaN  Invalid_operation
+dvix649 divideint  sNaN sNaN   ->  NaN  Invalid_operation
+dvix650 divideint  NaN  sNaN   ->  NaN  Invalid_operation
+dvix651 divideint -Inf  sNaN   ->  NaN  Invalid_operation
+dvix652 divideint -1000 sNaN   ->  NaN  Invalid_operation
+dvix653 divideint -1    sNaN   ->  NaN  Invalid_operation
+dvix654 divideint -0    sNaN   ->  NaN  Invalid_operation
+dvix655 divideint  0    sNaN   ->  NaN  Invalid_operation
+dvix656 divideint  1    sNaN   ->  NaN  Invalid_operation
+dvix657 divideint  1000 sNaN   ->  NaN  Invalid_operation
+dvix658 divideint  Inf  sNaN   ->  NaN  Invalid_operation
+dvix659 divideint  NaN  sNaN   ->  NaN  Invalid_operation
+
+-- propagating NaNs
+dvix661 divideint  NaN9 -Inf   ->  NaN9
+dvix662 divideint  NaN8  1000  ->  NaN8
+dvix663 divideint  NaN7  Inf   ->  NaN7
+dvix664 divideint -NaN6  NaN5  -> -NaN6
+dvix665 divideint -Inf   NaN4  ->  NaN4
+dvix666 divideint -1000  NaN3  ->  NaN3
+dvix667 divideint  Inf  -NaN2  -> -NaN2
+
+dvix671 divideint -sNaN99 -Inf    -> -NaN99 Invalid_operation
+dvix672 divideint  sNaN98 -1      ->  NaN98 Invalid_operation
+dvix673 divideint  sNaN97  NaN    ->  NaN97 Invalid_operation
+dvix674 divideint  sNaN96 sNaN94  ->  NaN96 Invalid_operation
+dvix675 divideint  NaN95  sNaN93  ->  NaN93 Invalid_operation
+dvix676 divideint -Inf    sNaN92  ->  NaN92 Invalid_operation
+dvix677 divideint  0      sNaN91  ->  NaN91 Invalid_operation
+dvix678 divideint  Inf   -sNaN90  -> -NaN90 Invalid_operation
+dvix679 divideint  NaN    sNaN89  ->  NaN89 Invalid_operation
+
+-- some long operand cases again
+precision: 8
+dvix710 divideint  100000001     1  ->  NaN Division_impossible
+dvix711 divideint  100000000.4   1  ->  NaN Division_impossible
+dvix712 divideint  100000000.5   1  ->  NaN Division_impossible
+dvix713 divideint  100000000.9   1  ->  NaN Division_impossible
+dvix714 divideint  100000000.999 1  ->  NaN Division_impossible
+precision: 6
+dvix720 divideint  100000000     1  ->  NaN Division_impossible
+dvix721 divideint  10000000      1  ->  NaN Division_impossible
+dvix722 divideint  1000000       1  ->  NaN Division_impossible
+dvix723 divideint  100000        1  ->  100000
+dvix724 divideint  10000         1  ->  10000
+dvix725 divideint  1000          1  ->  1000
+dvix726 divideint  100           1  ->  100
+dvix727 divideint  10            1  ->  10
+dvix728 divideint  1             1  ->  1
+dvix729 divideint  1            10  ->  0
+
+precision: 9
+maxexponent: 999999999
+minexponent: -999999999
+dvix732 divideint 1 0.99e999999999 -> 0
+dvix733 divideint 1 0.999999999e999999999 -> 0
+dvix734 divideint 9e999999999    1       -> NaN Division_impossible
+dvix735 divideint 9.9e999999999  1       -> NaN Division_impossible
+dvix736 divideint 9.99e999999999 1       -> NaN Division_impossible
+dvix737 divideint 9.99999999e999999999 1 -> NaN Division_impossible
+
+dvix740 divideint 0.1 9e-999999999       -> NaN Division_impossible
+dvix741 divideint 0.1 99e-999999999      -> NaN Division_impossible
+dvix742 divideint 0.1 999e-999999999     -> NaN Division_impossible
+
+dvix743 divideint 0.1 9e-999999998       -> NaN Division_impossible
+dvix744 divideint 0.1 99e-999999998      -> NaN Division_impossible
+dvix745 divideint 0.1 999e-999999998     -> NaN Division_impossible
+dvix746 divideint 0.1 999e-999999997     -> NaN Division_impossible
+dvix747 divideint 0.1 9999e-999999997    -> NaN Division_impossible
+dvix748 divideint 0.1 99999e-999999997   -> NaN Division_impossible
+
+
+-- Null tests
+dvix900 divideint  10  # -> NaN Invalid_operation
+dvix901 divideint   # 10 -> NaN Invalid_operation

Added: vendor/Python/current/Lib/test/decimaltestdata/inexact.decTest
===================================================================
--- vendor/Python/current/Lib/test/decimaltestdata/inexact.decTest	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/decimaltestdata/inexact.decTest	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,215 @@
+------------------------------------------------------------------------
+-- inexact.decTest -- decimal inexact and rounded edge cases          --
+-- Copyright (c) IBM Corporation, 1981, 2003.  All rights reserved.   --
+------------------------------------------------------------------------
+-- Please see the document "General Decimal Arithmetic Testcases"     --
+-- at http://www2.hursley.ibm.com/decimal for the description of      --
+-- these testcases.                                                   --
+--                                                                    --
+-- These testcases are experimental ('beta' versions), and they       --
+-- may contain errors.  They are offered on an as-is basis.  In       --
+-- particular, achieving the same results as the tests here is not    --
+-- a guarantee that an implementation complies with any Standard      --
+-- or specification.  The tests are not exhaustive.                   --
+--                                                                    --
+-- Please send comments, suggestions, and corrections to the author:  --
+--   Mike Cowlishaw, IBM Fellow                                       --
+--   IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK         --
+--   mfc at uk.ibm.com                                                   --
+------------------------------------------------------------------------
+version: 2.39
+
+extended:    1
+precision:   9
+rounding:    half_up
+maxExponent: 999
+minexponent: -999
+
+inx001 add 1          1              -> 2
+inx002 add 123456789  0              -> 123456789
+inx003 add 123456789  0.0            -> 123456789 Rounded
+inx004 add 123456789  0.00           -> 123456789 Rounded
+inx005 add 123456789  1              -> 123456790
+inx006 add 123456789  0.1            -> 123456789 Inexact Rounded
+inx007 add 123456789  0.01           -> 123456789 Inexact Rounded
+inx008 add 123456789  0.001          -> 123456789 Inexact Rounded
+inx009 add 123456789  0.000001       -> 123456789 Inexact Rounded
+inx010 add 123456789  0.000000001    -> 123456789 Inexact Rounded
+inx011 add 123456789  0.000000000001 -> 123456789 Inexact Rounded
+
+inx012 add 123456789  0.9            -> 123456790 Inexact Rounded
+inx013 add 123456789  0.09           -> 123456789 Inexact Rounded
+inx014 add 123456789  0.009          -> 123456789 Inexact Rounded
+inx015 add 123456789  0.000009       -> 123456789 Inexact Rounded
+inx016 add 123456789  0.000000009    -> 123456789 Inexact Rounded
+inx017 add 123456789  0.000000000009 -> 123456789 Inexact Rounded
+
+inx021 add 1          -1              -> 0
+inx022 add 123456789  -0              -> 123456789
+inx023 add 123456789  -0.0            -> 123456789 Rounded
+inx024 add 123456789  -0.00           -> 123456789 Rounded
+inx025 add 123456789  -1              -> 123456788
+inx026 add 123456789  -0.1            -> 123456789 Inexact Rounded
+inx027 add 123456789  -0.01           -> 123456789 Inexact Rounded
+inx028 add 123456789  -0.001          -> 123456789 Inexact Rounded
+inx029 add 123456789  -0.000001       -> 123456789 Inexact Rounded
+inx030 add 123456789  -0.000000001    -> 123456789 Inexact Rounded
+inx031 add 123456789  -0.000000000001 -> 123456789 Inexact Rounded
+inx032 add 123456789  -0.9            -> 123456788 Inexact Rounded
+inx033 add 123456789  -0.09           -> 123456789 Inexact Rounded
+inx034 add 123456789  -0.009          -> 123456789 Inexact Rounded
+inx035 add 123456789  -0.000009       -> 123456789 Inexact Rounded
+inx036 add 123456789  -0.000000009    -> 123456789 Inexact Rounded
+inx037 add 123456789  -0.000000000009 -> 123456789 Inexact Rounded
+
+inx042 add  0               123456789 -> 123456789
+inx043 add  0.0             123456789 -> 123456789 Rounded
+inx044 add  0.00            123456789 -> 123456789 Rounded
+inx045 add  1               123456789 -> 123456790
+inx046 add  0.1             123456789 -> 123456789 Inexact Rounded
+inx047 add  0.01            123456789 -> 123456789 Inexact Rounded
+inx048 add  0.001           123456789 -> 123456789 Inexact Rounded
+inx049 add  0.000001        123456789 -> 123456789 Inexact Rounded
+inx050 add  0.000000001     123456789 -> 123456789 Inexact Rounded
+inx051 add  0.000000000001  123456789 -> 123456789 Inexact Rounded
+inx052 add  0.9             123456789 -> 123456790 Inexact Rounded
+inx053 add  0.09            123456789 -> 123456789 Inexact Rounded
+inx054 add  0.009           123456789 -> 123456789 Inexact Rounded
+inx055 add  0.000009        123456789 -> 123456789 Inexact Rounded
+inx056 add  0.000000009     123456789 -> 123456789 Inexact Rounded
+inx057 add  0.000000000009  123456789 -> 123456789 Inexact Rounded
+
+inx062 add  -0              123456789 -> 123456789
+inx063 add  -0.0            123456789 -> 123456789 Rounded
+inx064 add  -0.00           123456789 -> 123456789 Rounded
+inx065 add  -1              123456789 -> 123456788
+inx066 add  -0.1            123456789 -> 123456789 Inexact Rounded
+inx067 add  -0.01           123456789 -> 123456789 Inexact Rounded
+inx068 add  -0.001          123456789 -> 123456789 Inexact Rounded
+inx069 add  -0.000001       123456789 -> 123456789 Inexact Rounded
+inx070 add  -0.000000001    123456789 -> 123456789 Inexact Rounded
+inx071 add  -0.000000000001 123456789 -> 123456789 Inexact Rounded
+inx072 add  -0.9            123456789 -> 123456788 Inexact Rounded
+inx073 add  -0.09           123456789 -> 123456789 Inexact Rounded
+inx074 add  -0.009          123456789 -> 123456789 Inexact Rounded
+inx075 add  -0.000009       123456789 -> 123456789 Inexact Rounded
+inx076 add  -0.000000009    123456789 -> 123456789 Inexact Rounded
+inx077 add  -0.000000000009 123456789 -> 123456789 Inexact Rounded
+
+-- some boundaries
+inx081 add    999999999           0     -> 999999999
+inx082 add  0.999999999 0.000000000     -> 0.999999999
+inx083 add    999999999           1     -> 1.00000000E+9 Rounded
+inx084 add  0.999999999 0.000000001     -> 1.00000000    Rounded
+inx085 add    999999999           2     -> 1.00000000E+9 Inexact Rounded
+inx086 add  0.999999999 0.000000002     -> 1.00000000    Inexact Rounded
+inx087 add    999999999           3     -> 1.00000000E+9 Inexact Rounded
+inx089 add  0.999999999 0.000000003     -> 1.00000000    Inexact Rounded
+
+-- minus, plus, and subtract all assumed to work like add.
+
+-- multiply
+precision: 8
+inx101 multiply  1000  1000        ->  1000000
+inx102 multiply  9000  9000        -> 81000000
+inx103 multiply  9999  9999        -> 99980001
+inx104 multiply  1000 10000        -> 10000000
+inx105 multiply 10000 10000        -> 1.0000000E+8 Rounded
+inx106 multiply 10001 10000        -> 1.0001000E+8 Rounded
+inx107 multiply 10001 10001        -> 1.0002000E+8 Inexact Rounded
+inx108 multiply 10101 10001        -> 1.0102010E+8 Inexact Rounded
+inx109 multiply 10001 10101        -> 1.0102010E+8 Inexact Rounded
+
+-- divide
+precision: 4
+inx201 divide  1000  1000        ->  1
+inx202 divide  1000     1        ->  1000
+inx203 divide  1000     2        ->   500
+inx204 divide  1000     3        ->   333.3  Inexact Rounded
+inx205 divide  1000     4        ->   250
+inx206 divide  1000     5        ->   200
+inx207 divide  1000     6        ->   166.7  Inexact Rounded
+inx208 divide  1000     7        ->   142.9  Inexact Rounded
+inx209 divide  1000     8        ->   125
+inx210 divide  1000     9        ->   111.1  Inexact Rounded
+inx211 divide  1000    10        ->   100
+
+inx220 divide     1     1        ->   1
+inx221 divide     1     2        ->   0.5
+inx222 divide     1     4        ->   0.25
+inx223 divide     1     8        ->   0.125
+inx224 divide     1    16        ->   0.0625
+inx225 divide     1    32        ->   0.03125
+inx226 divide     1    64        ->   0.01563  Inexact Rounded
+inx227 divide     1   128        ->   0.007813 Inexact Rounded
+
+precision: 5
+inx230 divide     1     1        ->   1
+inx231 divide     1     2        ->   0.5
+inx232 divide     1     4        ->   0.25
+inx233 divide     1     8        ->   0.125
+inx234 divide     1    16        ->   0.0625
+inx235 divide     1    32        ->   0.03125
+inx236 divide     1    64        ->   0.015625
+inx237 divide     1   128        ->   0.0078125
+
+precision: 3
+inx240 divide     1     1        ->   1
+inx241 divide     1     2        ->   0.5
+inx242 divide     1     4        ->   0.25
+inx243 divide     1     8        ->   0.125
+inx244 divide     1    16        ->   0.0625
+inx245 divide     1    32        ->   0.0313   Inexact Rounded
+inx246 divide     1    64        ->   0.0156   Inexact Rounded
+inx247 divide     1   128        ->   0.00781  Inexact Rounded
+
+precision: 2
+inx250 divide     1     1        ->   1
+inx251 divide     1     2        ->   0.5
+inx252 divide     1     4        ->   0.25
+inx253 divide     1     8        ->   0.13     Inexact Rounded
+inx254 divide     1    16        ->   0.063    Inexact Rounded
+inx255 divide     1    32        ->   0.031    Inexact Rounded
+inx256 divide     1    64        ->   0.016    Inexact Rounded
+inx257 divide     1   128        ->   0.0078   Inexact Rounded
+
+precision: 1
+inx260 divide     1     1        ->   1
+inx261 divide     1     2        ->   0.5
+inx262 divide     1     4        ->   0.3      Inexact Rounded
+inx263 divide     1     8        ->   0.1      Inexact Rounded
+inx264 divide     1    16        ->   0.06     Inexact Rounded
+inx265 divide     1    32        ->   0.03     Inexact Rounded
+inx266 divide     1    64        ->   0.02     Inexact Rounded
+inx267 divide     1   128        ->   0.008    Inexact Rounded
+
+
+-- power
+precision: 4
+inx301 power    0.5     2        ->   0.25
+inx302 power    0.5     4        ->   0.0625
+inx303 power    0.5     8        ->   0.003906   Inexact Rounded
+inx304 power    0.5    16        ->   0.00001526 Inexact Rounded
+inx305 power    0.5    32        ->   2.328E-10  Inexact Rounded
+
+-- compare, divideInteger, and remainder are always exact
+
+-- rescale
+precision: 4
+inx401 rescale 0       0   -> 0
+inx402 rescale 1       0   -> 1
+inx403 rescale 0.1    +2   -> 0E+2 Inexact Rounded
+inx404 rescale 0.1    +1   -> 0E+1 Inexact Rounded
+inx405 rescale 0.1     0   -> 0 Inexact Rounded
+inx406 rescale 0.1    -1   -> 0.1
+inx407 rescale 0.1    -2   -> 0.10
+
+-- long operands cause rounding too
+precision: 9
+inx801 plus  123456789  -> 123456789
+inx802 plus  1234567890 -> 1.23456789E+9 Rounded
+inx803 plus  1234567891 -> 1.23456789E+9 Inexact Rounded
+inx804 plus  1234567892 -> 1.23456789E+9 Inexact Rounded
+inx805 plus  1234567899 -> 1.23456790E+9 Inexact Rounded
+inx806 plus  1234567900 -> 1.23456790E+9 Rounded
+

Added: vendor/Python/current/Lib/test/decimaltestdata/max.decTest
===================================================================
--- vendor/Python/current/Lib/test/decimaltestdata/max.decTest	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/decimaltestdata/max.decTest	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,376 @@
+------------------------------------------------------------------------
+-- max.decTest -- decimal maximum                                     --
+-- Copyright (c) IBM Corporation, 1981, 2004.  All rights reserved.   --
+------------------------------------------------------------------------
+-- Please see the document "General Decimal Arithmetic Testcases"     --
+-- at http://www2.hursley.ibm.com/decimal for the description of      --
+-- these testcases.                                                   --
+--                                                                    --
+-- These testcases are experimental ('beta' versions), and they       --
+-- may contain errors.  They are offered on an as-is basis.  In       --
+-- particular, achieving the same results as the tests here is not    --
+-- a guarantee that an implementation complies with any Standard      --
+-- or specification.  The tests are not exhaustive.                   --
+--                                                                    --
+-- Please send comments, suggestions, and corrections to the author:  --
+--   Mike Cowlishaw, IBM Fellow                                       --
+--   IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK         --
+--   mfc at uk.ibm.com                                                   --
+------------------------------------------------------------------------
+version: 2.39
+
+-- we assume that base comparison is tested in compare.decTest, so
+-- these mainly cover special cases and rounding
+
+extended:    1
+precision:   9
+rounding:    half_up
+maxExponent: 384
+minexponent: -383
+
+-- sanity checks
+maxx001 max  -2  -2  -> -2
+maxx002 max  -2  -1  -> -1
+maxx003 max  -2   0  ->  0
+maxx004 max  -2   1  ->  1
+maxx005 max  -2   2  ->  2
+maxx006 max  -1  -2  -> -1
+maxx007 max  -1  -1  -> -1
+maxx008 max  -1   0  ->  0
+maxx009 max  -1   1  ->  1
+maxx010 max  -1   2  ->  2
+maxx011 max   0  -2  ->  0
+maxx012 max   0  -1  ->  0
+maxx013 max   0   0  ->  0
+maxx014 max   0   1  ->  1
+maxx015 max   0   2  ->  2
+maxx016 max   1  -2  ->  1
+maxx017 max   1  -1  ->  1
+maxx018 max   1   0  ->  1
+maxx019 max   1   1  ->  1
+maxx020 max   1   2  ->  2
+maxx021 max   2  -2  ->  2
+maxx022 max   2  -1  ->  2
+maxx023 max   2   0  ->  2
+maxx025 max   2   1  ->  2
+maxx026 max   2   2  ->  2
+
+-- extended zeros
+maxx030 max   0     0   ->  0
+maxx031 max   0    -0   ->  0
+maxx032 max   0    -0.0 ->  0
+maxx033 max   0     0.0 ->  0
+maxx034 max  -0     0   ->  0    -- note: -0 = 0, but 0 chosen
+maxx035 max  -0    -0   -> -0
+maxx036 max  -0    -0.0 -> -0.0
+maxx037 max  -0     0.0 ->  0.0
+maxx038 max   0.0   0   ->  0
+maxx039 max   0.0  -0   ->  0.0
+maxx040 max   0.0  -0.0 ->  0.0
+maxx041 max   0.0   0.0 ->  0.0
+maxx042 max  -0.0   0   ->  0
+maxx043 max  -0.0  -0   -> -0.0
+maxx044 max  -0.0  -0.0 -> -0.0
+maxx045 max  -0.0   0.0 ->  0.0
+
+maxx050 max  -0E1   0E1 ->  0E+1
+maxx051 max  -0E2   0E2 ->  0E+2
+maxx052 max  -0E2   0E1 ->  0E+1
+maxx053 max  -0E1   0E2 ->  0E+2
+maxx054 max   0E1  -0E1 ->  0E+1
+maxx055 max   0E2  -0E2 ->  0E+2
+maxx056 max   0E2  -0E1 ->  0E+2
+maxx057 max   0E1  -0E2 ->  0E+1
+
+maxx058 max   0E1   0E1 ->  0E+1
+maxx059 max   0E2   0E2 ->  0E+2
+maxx060 max   0E2   0E1 ->  0E+2
+maxx061 max   0E1   0E2 ->  0E+2
+maxx062 max  -0E1  -0E1 -> -0E+1
+maxx063 max  -0E2  -0E2 -> -0E+2
+maxx064 max  -0E2  -0E1 -> -0E+1
+maxx065 max  -0E1  -0E2 -> -0E+1
+
+-- Specials
+precision: 9
+maxx090 max  Inf  -Inf   ->  Infinity
+maxx091 max  Inf  -1000  ->  Infinity
+maxx092 max  Inf  -1     ->  Infinity
+maxx093 max  Inf  -0     ->  Infinity
+maxx094 max  Inf   0     ->  Infinity
+maxx095 max  Inf   1     ->  Infinity
+maxx096 max  Inf   1000  ->  Infinity
+maxx097 max  Inf   Inf   ->  Infinity
+maxx098 max -1000  Inf   ->  Infinity
+maxx099 max -Inf   Inf   ->  Infinity
+maxx100 max -1     Inf   ->  Infinity
+maxx101 max -0     Inf   ->  Infinity
+maxx102 max  0     Inf   ->  Infinity
+maxx103 max  1     Inf   ->  Infinity
+maxx104 max  1000  Inf   ->  Infinity
+maxx105 max  Inf   Inf   ->  Infinity
+
+maxx120 max -Inf  -Inf   -> -Infinity
+maxx121 max -Inf  -1000  -> -1000
+maxx122 max -Inf  -1     -> -1
+maxx123 max -Inf  -0     -> -0
+maxx124 max -Inf   0     ->  0
+maxx125 max -Inf   1     ->  1
+maxx126 max -Inf   1000  ->  1000
+maxx127 max -Inf   Inf   ->  Infinity
+maxx128 max -Inf  -Inf   ->  -Infinity
+maxx129 max -1000 -Inf   ->  -1000
+maxx130 max -1    -Inf   ->  -1
+maxx131 max -0    -Inf   ->  -0
+maxx132 max  0    -Inf   ->  0
+maxx133 max  1    -Inf   ->  1
+maxx134 max  1000 -Inf   ->  1000
+maxx135 max  Inf  -Inf   ->  Infinity
+
+-- 2004.08.02 754r chooses number over NaN in mixed cases
+maxx141 max  NaN -Inf    -> -Infinity
+maxx142 max  NaN -1000   -> -1000
+maxx143 max  NaN -1      -> -1
+maxx144 max  NaN -0      -> -0
+maxx145 max  NaN  0      ->  0
+maxx146 max  NaN  1      ->  1
+maxx147 max  NaN  1000   ->  1000
+maxx148 max  NaN  Inf    ->  Infinity
+maxx149 max  NaN  NaN    ->  NaN
+maxx150 max -Inf  NaN    -> -Infinity
+maxx151 max -1000 NaN    -> -1000
+maxx152 max -1    NaN    -> -1
+maxx153 max -0    NaN    -> -0
+maxx154 max  0    NaN    ->  0
+maxx155 max  1    NaN    ->  1
+maxx156 max  1000 NaN    ->  1000
+maxx157 max  Inf  NaN    ->  Infinity
+
+maxx161 max  sNaN -Inf   ->  NaN  Invalid_operation
+maxx162 max  sNaN -1000  ->  NaN  Invalid_operation
+maxx163 max  sNaN -1     ->  NaN  Invalid_operation
+maxx164 max  sNaN -0     ->  NaN  Invalid_operation
+maxx165 max  sNaN  0     ->  NaN  Invalid_operation
+maxx166 max  sNaN  1     ->  NaN  Invalid_operation
+maxx167 max  sNaN  1000  ->  NaN  Invalid_operation
+maxx168 max  sNaN  NaN   ->  NaN  Invalid_operation
+maxx169 max  sNaN sNaN   ->  NaN  Invalid_operation
+maxx170 max  NaN  sNaN   ->  NaN  Invalid_operation
+maxx171 max -Inf  sNaN   ->  NaN  Invalid_operation
+maxx172 max -1000 sNaN   ->  NaN  Invalid_operation
+maxx173 max -1    sNaN   ->  NaN  Invalid_operation
+maxx174 max -0    sNaN   ->  NaN  Invalid_operation
+maxx175 max  0    sNaN   ->  NaN  Invalid_operation
+maxx176 max  1    sNaN   ->  NaN  Invalid_operation
+maxx177 max  1000 sNaN   ->  NaN  Invalid_operation
+maxx178 max  Inf  sNaN   ->  NaN  Invalid_operation
+maxx179 max  NaN  sNaN   ->  NaN  Invalid_operation
+
+-- propagating NaNs
+maxx181 max  NaN9  -Inf   -> -Infinity
+maxx182 max  NaN8     9   ->  9
+maxx183 max -NaN7   Inf   ->  Infinity
+
+maxx184 max -NaN1   NaN11 -> -NaN1
+maxx185 max  NaN2   NaN12 ->  NaN2
+maxx186 max -NaN13 -NaN7  -> -NaN13
+maxx187 max  NaN14 -NaN5  ->  NaN14
+
+maxx188 max -Inf    NaN4  -> -Infinity
+maxx189 max -9     -NaN3  -> -9
+maxx190 max  Inf    NaN2  ->  Infinity
+
+maxx191 max  sNaN99 -Inf    ->  NaN99 Invalid_operation
+maxx192 max  sNaN98 -1      ->  NaN98 Invalid_operation
+maxx193 max -sNaN97  NaN    -> -NaN97 Invalid_operation
+maxx194 max  sNaN96 sNaN94  ->  NaN96 Invalid_operation
+maxx195 max  NaN95  sNaN93  ->  NaN93 Invalid_operation
+maxx196 max -Inf    sNaN92  ->  NaN92 Invalid_operation
+maxx197 max  0      sNaN91  ->  NaN91 Invalid_operation
+maxx198 max  Inf   -sNaN90  -> -NaN90 Invalid_operation
+maxx199 max  NaN    sNaN89  ->  NaN89 Invalid_operation
+
+-- rounding checks
+maxexponent: 999
+minexponent: -999
+precision: 9
+maxx201 max 12345678000 1  -> 1.23456780E+10 Rounded
+maxx202 max 1 12345678000  -> 1.23456780E+10 Rounded
+maxx203 max 1234567800  1  -> 1.23456780E+9 Rounded
+maxx204 max 1 1234567800   -> 1.23456780E+9 Rounded
+maxx205 max 1234567890  1  -> 1.23456789E+9 Rounded
+maxx206 max 1 1234567890   -> 1.23456789E+9 Rounded
+maxx207 max 1234567891  1  -> 1.23456789E+9 Inexact Rounded
+maxx208 max 1 1234567891   -> 1.23456789E+9 Inexact Rounded
+maxx209 max 12345678901 1  -> 1.23456789E+10 Inexact Rounded
+maxx210 max 1 12345678901  -> 1.23456789E+10 Inexact Rounded
+maxx211 max 1234567896  1  -> 1.23456790E+9 Inexact Rounded
+maxx212 max 1 1234567896   -> 1.23456790E+9 Inexact Rounded
+maxx213 max -1234567891  1 -> 1
+maxx214 max 1 -1234567891  -> 1
+maxx215 max -12345678901 1 -> 1
+maxx216 max 1 -12345678901 -> 1
+maxx217 max -1234567896  1 -> 1
+maxx218 max 1 -1234567896  -> 1
+
+precision: 15
+maxx221 max 12345678000 1  -> 12345678000
+maxx222 max 1 12345678000  -> 12345678000
+maxx223 max 1234567800  1  -> 1234567800
+maxx224 max 1 1234567800   -> 1234567800
+maxx225 max 1234567890  1  -> 1234567890
+maxx226 max 1 1234567890   -> 1234567890
+maxx227 max 1234567891  1  -> 1234567891
+maxx228 max 1 1234567891   -> 1234567891
+maxx229 max 12345678901 1  -> 12345678901
+maxx230 max 1 12345678901  -> 12345678901
+maxx231 max 1234567896  1  -> 1234567896
+maxx232 max 1 1234567896   -> 1234567896
+maxx233 max -1234567891  1 -> 1
+maxx234 max 1 -1234567891  -> 1
+maxx235 max -12345678901 1 -> 1
+maxx236 max 1 -12345678901 -> 1
+maxx237 max -1234567896  1 -> 1
+maxx238 max 1 -1234567896  -> 1
+
+-- from examples
+maxx280 max '3'   '2'  ->  '3'
+maxx281 max '-10' '3'  ->  '3'
+maxx282 max '1.0' '1'  ->  '1'
+maxx283 max '1' '1.0'  ->  '1'
+maxx284 max '7' 'NaN'  ->  '7'
+
+-- overflow and underflow tests ...
+maxExponent: 999999999
+minexponent: -999999999
+maxx330 max +1.23456789012345E-0 9E+999999999 ->  9E+999999999
+maxx331 max 9E+999999999 +1.23456789012345E-0 ->  9E+999999999
+maxx332 max +0.100 9E-999999999               ->  0.100
+maxx333 max 9E-999999999 +0.100               ->  0.100
+maxx335 max -1.23456789012345E-0 9E+999999999 ->  9E+999999999
+maxx336 max 9E+999999999 -1.23456789012345E-0 ->  9E+999999999
+maxx337 max -0.100 9E-999999999               ->  9E-999999999
+maxx338 max 9E-999999999 -0.100               ->  9E-999999999
+
+maxx339 max 1e-599999999 1e-400000001   ->  1E-400000001
+maxx340 max 1e-599999999 1e-400000000   ->  1E-400000000
+maxx341 max 1e-600000000 1e-400000000   ->  1E-400000000
+maxx342 max 9e-999999998 0.01           ->  0.01
+maxx343 max 9e-999999998 0.1            ->  0.1
+maxx344 max 0.01 9e-999999998           ->  0.01
+maxx345 max 1e599999999 1e400000001     ->  1E+599999999
+maxx346 max 1e599999999 1e400000000     ->  1E+599999999
+maxx347 max 1e600000000 1e400000000     ->  1E+600000000
+maxx348 max 9e999999998 100             ->  9E+999999998
+maxx349 max 9e999999998 10              ->  9E+999999998
+maxx350 max 100  9e999999998            ->  9E+999999998
+-- signs
+maxx351 max  1e+777777777  1e+411111111 ->  1E+777777777
+maxx352 max  1e+777777777 -1e+411111111 ->  1E+777777777
+maxx353 max -1e+777777777  1e+411111111 ->  1E+411111111
+maxx354 max -1e+777777777 -1e+411111111 -> -1E+411111111
+maxx355 max  1e-777777777  1e-411111111 ->  1E-411111111
+maxx356 max  1e-777777777 -1e-411111111 ->  1E-777777777
+maxx357 max -1e-777777777  1e-411111111 ->  1E-411111111
+maxx358 max -1e-777777777 -1e-411111111 -> -1E-777777777
+
+-- expanded list from min/max 754r purple prose
+-- [explicit tests for exponent ordering]
+maxx401 max  Inf    1.1     ->  Infinity
+maxx402 max  1.1    1       ->  1.1
+maxx403 max  1      1.0     ->  1
+maxx404 max  1.0    0.1     ->  1.0
+maxx405 max  0.1    0.10    ->  0.1
+maxx406 max  0.10   0.100   ->  0.10
+maxx407 max  0.10   0       ->  0.10
+maxx408 max  0      0.0     ->  0
+maxx409 max  0.0   -0       ->  0.0
+maxx410 max  0.0   -0.0     ->  0.0
+maxx411 max  0.00  -0.0     ->  0.00
+maxx412 max  0.0   -0.00    ->  0.0
+maxx413 max  0     -0.0     ->  0
+maxx414 max  0     -0       ->  0
+maxx415 max -0.0   -0       -> -0.0
+maxx416 max -0     -0.100   -> -0
+maxx417 max -0.100 -0.10    -> -0.100
+maxx418 max -0.10  -0.1     -> -0.10
+maxx419 max -0.1   -1.0     -> -0.1
+maxx420 max -1.0   -1       -> -1.0
+maxx421 max -1     -1.1     -> -1
+maxx423 max -1.1   -Inf     -> -1.1
+-- same with operands reversed
+maxx431 max  1.1    Inf     ->  Infinity
+maxx432 max  1      1.1     ->  1.1
+maxx433 max  1.0    1       ->  1
+maxx434 max  0.1    1.0     ->  1.0
+maxx435 max  0.10   0.1     ->  0.1
+maxx436 max  0.100  0.10    ->  0.10
+maxx437 max  0      0.10    ->  0.10
+maxx438 max  0.0    0       ->  0
+maxx439 max -0      0.0     ->  0.0
+maxx440 max -0.0    0.0     ->  0.0
+maxx441 max -0.0    0.00    ->  0.00
+maxx442 max -0.00   0.0     ->  0.0
+maxx443 max -0.0    0       ->  0
+maxx444 max -0      0       ->  0
+maxx445 max -0     -0.0     -> -0.0
+maxx446 max -0.100 -0       -> -0
+maxx447 max -0.10  -0.100   -> -0.100
+maxx448 max -0.1   -0.10    -> -0.10
+maxx449 max -1.0   -0.1     -> -0.1
+maxx450 max -1     -1.0     -> -1.0
+maxx451 max -1.1   -1       -> -1
+maxx453 max -Inf   -1.1     -> -1.1
+-- largies
+maxx460 max  1000   1E+3    ->  1E+3
+maxx461 max  1E+3   1000    ->  1E+3
+maxx462 max  1000  -1E+3    ->  1000
+maxx463 max  1E+3  -1000    ->  1E+3
+maxx464 max -1000   1E+3    ->  1E+3
+maxx465 max -1E+3   1000    ->  1000
+maxx466 max -1000  -1E+3    -> -1000
+maxx467 max -1E+3  -1000    -> -1000
+
+
+-- overflow tests
+maxexponent: 999999999
+minexponent: -999999999
+precision: 3
+maxx500 max 9.999E+999999999  0 ->  Infinity Inexact Overflow Rounded
+maxx501 max -9.999E+999999999 0 ->  0
+
+-- subnormals and underflow
+precision: 3
+maxexponent: 999
+minexponent: -999
+maxx510 max  1.00E-999       0  ->   1.00E-999
+maxx511 max  0.1E-999        0  ->   1E-1000   Subnormal
+maxx512 max  0.10E-999       0  ->   1.0E-1000 Subnormal
+maxx513 max  0.100E-999      0  ->   1.0E-1000 Subnormal Rounded
+maxx514 max  0.01E-999       0  ->   1E-1001   Subnormal
+-- next is rounded to Emin
+maxx515 max  0.999E-999      0  ->   1.00E-999 Inexact Rounded Subnormal Underflow
+maxx516 max  0.099E-999      0  ->   1.0E-1000 Inexact Rounded Subnormal Underflow
+maxx517 max  0.009E-999      0  ->   1E-1001   Inexact Rounded Subnormal Underflow
+maxx518 max  0.001E-999      0  ->   0E-1001   Inexact Rounded Subnormal Underflow
+maxx519 max  0.0009E-999     0  ->   0E-1001   Inexact Rounded Subnormal Underflow
+maxx520 max  0.0001E-999     0  ->   0E-1001   Inexact Rounded Subnormal Underflow
+
+maxx530 max -1.00E-999       0  ->   0
+maxx531 max -0.1E-999        0  ->   0
+maxx532 max -0.10E-999       0  ->   0
+maxx533 max -0.100E-999      0  ->   0
+maxx534 max -0.01E-999       0  ->   0
+maxx535 max -0.999E-999      0  ->   0
+maxx536 max -0.099E-999      0  ->   0
+maxx537 max -0.009E-999      0  ->   0
+maxx538 max -0.001E-999      0  ->   0
+maxx539 max -0.0009E-999     0  ->   0
+maxx540 max -0.0001E-999     0  ->   0
+
+-- Null tests
+maxx900 max 10  #  -> NaN Invalid_operation
+maxx901 max  # 10  -> NaN Invalid_operation
+
+
+

Added: vendor/Python/current/Lib/test/decimaltestdata/min.decTest
===================================================================
--- vendor/Python/current/Lib/test/decimaltestdata/min.decTest	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/decimaltestdata/min.decTest	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,363 @@
+------------------------------------------------------------------------
+-- min.decTest -- decimal minimum                                     --
+-- Copyright (c) IBM Corporation, 1981, 2004.  All rights reserved.   --
+------------------------------------------------------------------------
+-- Please see the document "General Decimal Arithmetic Testcases"     --
+-- at http://www2.hursley.ibm.com/decimal for the description of      --
+-- these testcases.                                                   --
+--                                                                    --
+-- These testcases are experimental ('beta' versions), and they       --
+-- may contain errors.  They are offered on an as-is basis.  In       --
+-- particular, achieving the same results as the tests here is not    --
+-- a guarantee that an implementation complies with any Standard      --
+-- or specification.  The tests are not exhaustive.                   --
+--                                                                    --
+-- Please send comments, suggestions, and corrections to the author:  --
+--   Mike Cowlishaw, IBM Fellow                                       --
+--   IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK         --
+--   mfc at uk.ibm.com                                                   --
+------------------------------------------------------------------------
+version: 2.39
+
+-- we assume that base comparison is tested in compare.decTest, so
+-- these mainly cover special cases and rounding
+
+extended:    1
+precision:   9
+rounding:    half_up
+maxExponent: 384
+minexponent: -383
+
+-- sanity checks
+mnmx001 min  -2  -2  -> -2
+mnmx002 min  -2  -1  -> -2
+mnmx003 min  -2   0  -> -2
+mnmx004 min  -2   1  -> -2
+mnmx005 min  -2   2  -> -2
+mnmx006 min  -1  -2  -> -2
+mnmx007 min  -1  -1  -> -1
+mnmx008 min  -1   0  -> -1
+mnmx009 min  -1   1  -> -1
+mnmx010 min  -1   2  -> -1
+mnmx011 min   0  -2  -> -2
+mnmx012 min   0  -1  -> -1
+mnmx013 min   0   0  ->  0
+mnmx014 min   0   1  ->  0
+mnmx015 min   0   2  ->  0
+mnmx016 min   1  -2  -> -2
+mnmx017 min   1  -1  -> -1
+mnmx018 min   1   0  ->  0
+mnmx019 min   1   1  ->  1
+mnmx020 min   1   2  ->  1
+mnmx021 min   2  -2  -> -2
+mnmx022 min   2  -1  -> -1
+mnmx023 min   2   0  ->  0
+mnmx025 min   2   1  ->  1
+mnmx026 min   2   2  ->  2
+
+-- extended zeros
+mnmx030 min   0     0   ->  0
+mnmx031 min   0    -0   -> -0
+mnmx032 min   0    -0.0 -> -0.0
+mnmx033 min   0     0.0 ->  0.0
+mnmx034 min  -0     0   -> -0
+mnmx035 min  -0    -0   -> -0
+mnmx036 min  -0    -0.0 -> -0
+mnmx037 min  -0     0.0 -> -0
+mnmx038 min   0.0   0   ->  0.0
+mnmx039 min   0.0  -0   -> -0
+mnmx040 min   0.0  -0.0 -> -0.0
+mnmx041 min   0.0   0.0 ->  0.0
+mnmx042 min  -0.0   0   -> -0.0
+mnmx043 min  -0.0  -0   -> -0
+mnmx044 min  -0.0  -0.0 -> -0.0
+mnmx045 min  -0.0   0.0 -> -0.0
+
+mnmx046 min   0E1  -0E1 -> -0E+1
+mnmx047 min  -0E1   0E2 -> -0E+1
+mnmx048 min   0E2   0E1 ->  0E+1
+mnmx049 min   0E1   0E2 ->  0E+1
+mnmx050 min  -0E3  -0E2 -> -0E+3
+mnmx051 min  -0E2  -0E3 -> -0E+3
+
+-- Specials
+precision: 9
+mnmx090 min  Inf  -Inf   -> -Infinity
+mnmx091 min  Inf  -1000  -> -1000
+mnmx092 min  Inf  -1     -> -1
+mnmx093 min  Inf  -0     -> -0
+mnmx094 min  Inf   0     ->  0
+mnmx095 min  Inf   1     ->  1
+mnmx096 min  Inf   1000  ->  1000
+mnmx097 min  Inf   Inf   ->  Infinity
+mnmx098 min -1000  Inf   -> -1000
+mnmx099 min -Inf   Inf   -> -Infinity
+mnmx100 min -1     Inf   -> -1
+mnmx101 min -0     Inf   -> -0
+mnmx102 min  0     Inf   ->  0
+mnmx103 min  1     Inf   ->  1
+mnmx104 min  1000  Inf   ->  1000
+mnmx105 min  Inf   Inf   ->  Infinity
+
+mnmx120 min -Inf  -Inf   -> -Infinity
+mnmx121 min -Inf  -1000  -> -Infinity
+mnmx122 min -Inf  -1     -> -Infinity
+mnmx123 min -Inf  -0     -> -Infinity
+mnmx124 min -Inf   0     -> -Infinity
+mnmx125 min -Inf   1     -> -Infinity
+mnmx126 min -Inf   1000  -> -Infinity
+mnmx127 min -Inf   Inf   -> -Infinity
+mnmx128 min -Inf  -Inf   -> -Infinity
+mnmx129 min -1000 -Inf   -> -Infinity
+mnmx130 min -1    -Inf   -> -Infinity
+mnmx131 min -0    -Inf   -> -Infinity
+mnmx132 min  0    -Inf   -> -Infinity
+mnmx133 min  1    -Inf   -> -Infinity
+mnmx134 min  1000 -Inf   -> -Infinity
+mnmx135 min  Inf  -Inf   -> -Infinity
+
+-- 2004.08.02 754r chooses number over NaN in mixed cases
+mnmx141 min  NaN -Inf    ->  -Infinity
+mnmx142 min  NaN -1000   ->  -1000
+mnmx143 min  NaN -1      ->  -1
+mnmx144 min  NaN -0      ->  -0
+mnmx145 min  NaN  0      ->  0
+mnmx146 min  NaN  1      ->  1
+mnmx147 min  NaN  1000   ->  1000
+mnmx148 min  NaN  Inf    ->  Infinity
+mnmx149 min  NaN  NaN    ->  NaN
+mnmx150 min -Inf  NaN    -> -Infinity
+mnmx151 min -1000 NaN    -> -1000
+mnmx152 min -1   -NaN    -> -1
+mnmx153 min -0    NaN    -> -0
+mnmx154 min  0   -NaN    ->  0
+mnmx155 min  1    NaN    ->  1
+mnmx156 min  1000 NaN    ->  1000
+mnmx157 min  Inf  NaN    ->  Infinity
+
+mnmx161 min  sNaN -Inf   ->  NaN  Invalid_operation
+mnmx162 min  sNaN -1000  ->  NaN  Invalid_operation
+mnmx163 min  sNaN -1     ->  NaN  Invalid_operation
+mnmx164 min  sNaN -0     ->  NaN  Invalid_operation
+mnmx165 min -sNaN  0     -> -NaN  Invalid_operation
+mnmx166 min -sNaN  1     -> -NaN  Invalid_operation
+mnmx167 min  sNaN  1000  ->  NaN  Invalid_operation
+mnmx168 min  sNaN  NaN   ->  NaN  Invalid_operation
+mnmx169 min  sNaN sNaN   ->  NaN  Invalid_operation
+mnmx170 min  NaN  sNaN   ->  NaN  Invalid_operation
+mnmx171 min -Inf  sNaN   ->  NaN  Invalid_operation
+mnmx172 min -1000 sNaN   ->  NaN  Invalid_operation
+mnmx173 min -1    sNaN   ->  NaN  Invalid_operation
+mnmx174 min -0    sNaN   ->  NaN  Invalid_operation
+mnmx175 min  0    sNaN   ->  NaN  Invalid_operation
+mnmx176 min  1    sNaN   ->  NaN  Invalid_operation
+mnmx177 min  1000 sNaN   ->  NaN  Invalid_operation
+mnmx178 min  Inf  sNaN   ->  NaN  Invalid_operation
+mnmx179 min  NaN  sNaN   ->  NaN  Invalid_operation
+
+-- propagating NaNs
+mnmx181 min  NaN9   -Inf   -> -Infinity
+mnmx182 min -NaN8    9990  ->  9990
+mnmx183 min  NaN71   Inf   ->  Infinity
+
+mnmx184 min  NaN1    NaN54 ->  NaN1
+mnmx185 min  NaN22  -NaN53 ->  NaN22
+mnmx186 min -NaN3    NaN6  -> -NaN3
+mnmx187 min -NaN44   NaN7  -> -NaN44
+
+mnmx188 min -Inf     NaN41 -> -Infinity
+mnmx189 min -9999   -NaN33 -> -9999
+mnmx190 min  Inf     NaN2  ->  Infinity
+
+mnmx191 min  sNaN99 -Inf    ->  NaN99 Invalid_operation
+mnmx192 min  sNaN98 -11     ->  NaN98 Invalid_operation
+mnmx193 min -sNaN97  NaN8   -> -NaN97 Invalid_operation
+mnmx194 min  sNaN69 sNaN94  ->  NaN69 Invalid_operation
+mnmx195 min  NaN95  sNaN93  ->  NaN93 Invalid_operation
+mnmx196 min -Inf    sNaN92  ->  NaN92 Invalid_operation
+mnmx197 min  088    sNaN91  ->  NaN91 Invalid_operation
+mnmx198 min  Inf   -sNaN90  -> -NaN90 Invalid_operation
+mnmx199 min  NaN    sNaN86  ->  NaN86 Invalid_operation
+
+-- rounding checks -- chosen is rounded, or not
+maxExponent: 999
+minexponent: -999
+precision: 9
+mnmx201 min -12345678000 1  -> -1.23456780E+10 Rounded
+mnmx202 min 1 -12345678000  -> -1.23456780E+10 Rounded
+mnmx203 min -1234567800  1  -> -1.23456780E+9 Rounded
+mnmx204 min 1 -1234567800   -> -1.23456780E+9 Rounded
+mnmx205 min -1234567890  1  -> -1.23456789E+9 Rounded
+mnmx206 min 1 -1234567890   -> -1.23456789E+9 Rounded
+mnmx207 min -1234567891  1  -> -1.23456789E+9 Inexact Rounded
+mnmx208 min 1 -1234567891   -> -1.23456789E+9 Inexact Rounded
+mnmx209 min -12345678901 1  -> -1.23456789E+10 Inexact Rounded
+mnmx210 min 1 -12345678901  -> -1.23456789E+10 Inexact Rounded
+mnmx211 min -1234567896  1  -> -1.23456790E+9 Inexact Rounded
+mnmx212 min 1 -1234567896   -> -1.23456790E+9 Inexact Rounded
+mnmx213 min 1234567891  1   -> 1
+mnmx214 min 1 1234567891    -> 1
+mnmx215 min 12345678901 1   -> 1
+mnmx216 min 1 12345678901   -> 1
+mnmx217 min 1234567896  1   -> 1
+mnmx218 min 1 1234567896    -> 1
+
+precision: 15
+mnmx221 min -12345678000 1  -> -12345678000
+mnmx222 min 1 -12345678000  -> -12345678000
+mnmx223 min -1234567800  1  -> -1234567800
+mnmx224 min 1 -1234567800   -> -1234567800
+mnmx225 min -1234567890  1  -> -1234567890
+mnmx226 min 1 -1234567890   -> -1234567890
+mnmx227 min -1234567891  1  -> -1234567891
+mnmx228 min 1 -1234567891   -> -1234567891
+mnmx229 min -12345678901 1  -> -12345678901
+mnmx230 min 1 -12345678901  -> -12345678901
+mnmx231 min -1234567896  1  -> -1234567896
+mnmx232 min 1 -1234567896   -> -1234567896
+mnmx233 min 1234567891  1   -> 1
+mnmx234 min 1 1234567891    -> 1
+mnmx235 min 12345678901 1   -> 1
+mnmx236 min 1 12345678901   -> 1
+mnmx237 min 1234567896  1   -> 1
+mnmx238 min 1 1234567896    -> 1
+
+-- from examples
+mnmx280 min '3'   '2'  ->  '2'
+mnmx281 min '-10' '3'  ->  '-10'
+mnmx282 min '1.0' '1'  ->  '1.0'
+mnmx283 min '1' '1.0'  ->  '1.0'
+mnmx284 min '7' 'NaN'  ->  '7'
+
+-- overflow and underflow tests .. subnormal results [inputs] now allowed
+maxExponent: 999999999
+minexponent: -999999999
+mnmx330 min -1.23456789012345E-0 -9E+999999999 -> -9E+999999999
+mnmx331 min -9E+999999999 -1.23456789012345E-0 -> -9E+999999999
+mnmx332 min -0.100 -9E-999999999               -> -0.100
+mnmx333 min -9E-999999999 -0.100               -> -0.100
+mnmx335 min +1.23456789012345E-0 -9E+999999999 -> -9E+999999999
+mnmx336 min -9E+999999999 1.23456789012345E-0  -> -9E+999999999
+mnmx337 min +0.100 -9E-999999999               -> -9E-999999999
+mnmx338 min -9E-999999999 0.100                -> -9E-999999999
+
+mnmx339 min -1e-599999999 -1e-400000001   ->  -1E-400000001
+mnmx340 min -1e-599999999 -1e-400000000   ->  -1E-400000000
+mnmx341 min -1e-600000000 -1e-400000000   ->  -1E-400000000
+mnmx342 min -9e-999999998 -0.01           ->  -0.01
+mnmx343 min -9e-999999998 -0.1            ->  -0.1
+mnmx344 min -0.01         -9e-999999998   ->  -0.01
+mnmx345 min -1e599999999  -1e400000001    ->  -1E+599999999
+mnmx346 min -1e599999999  -1e400000000    ->  -1E+599999999
+mnmx347 min -1e600000000  -1e400000000    ->  -1E+600000000
+mnmx348 min -9e999999998  -100            ->  -9E+999999998
+mnmx349 min -9e999999998  -10             ->  -9E+999999998
+mnmx350 min -100          -9e999999998    ->  -9E+999999998
+-- signs
+mnmx351 min -1e+777777777 -1e+411111111 -> -1E+777777777
+mnmx352 min -1e+777777777 +1e+411111111 -> -1E+777777777
+mnmx353 min +1e+777777777 -1e+411111111 -> -1E+411111111
+mnmx354 min +1e+777777777 +1e+411111111 ->  1E+411111111
+mnmx355 min -1e-777777777 -1e-411111111 -> -1E-411111111
+mnmx356 min -1e-777777777 +1e-411111111 -> -1E-777777777
+mnmx357 min +1e-777777777 -1e-411111111 -> -1E-411111111
+mnmx358 min +1e-777777777 +1e-411111111 ->  1E-777777777
+
+-- expanded list from min/max 754r purple prose
+-- [explicit tests for exponent ordering]
+mnmx401 min  Inf    1.1     ->  1.1
+mnmx402 min  1.1    1       ->  1
+mnmx403 min  1      1.0     ->  1.0
+mnmx404 min  1.0    0.1     ->  0.1
+mnmx405 min  0.1    0.10    ->  0.10
+mnmx406 min  0.10   0.100   ->  0.100
+mnmx407 min  0.10   0       ->  0
+mnmx408 min  0      0.0     ->  0.0
+mnmx409 min  0.0   -0       -> -0
+mnmx410 min  0.0   -0.0     -> -0.0
+mnmx411 min  0.00  -0.0     -> -0.0
+mnmx412 min  0.0   -0.00    -> -0.00
+mnmx413 min  0     -0.0     -> -0.0
+mnmx414 min  0     -0       -> -0
+mnmx415 min -0.0   -0       -> -0
+mnmx416 min -0     -0.100   -> -0.100
+mnmx417 min -0.100 -0.10    -> -0.10
+mnmx418 min -0.10  -0.1     -> -0.1
+mnmx419 min -0.1   -1.0     -> -1.0
+mnmx420 min -1.0   -1       -> -1
+mnmx421 min -1     -1.1     -> -1.1
+mnmx423 min -1.1   -Inf     -> -Infinity
+-- same with operands reversed
+mnmx431 min  1.1    Inf     ->  1.1
+mnmx432 min  1      1.1     ->  1
+mnmx433 min  1.0    1       ->  1.0
+mnmx434 min  0.1    1.0     ->  0.1
+mnmx435 min  0.10   0.1     ->  0.10
+mnmx436 min  0.100  0.10    ->  0.100
+mnmx437 min  0      0.10    ->  0
+mnmx438 min  0.0    0       ->  0.0
+mnmx439 min -0      0.0     -> -0
+mnmx440 min -0.0    0.0     -> -0.0
+mnmx441 min -0.0    0.00    -> -0.0
+mnmx442 min -0.00   0.0     -> -0.00
+mnmx443 min -0.0    0       -> -0.0
+mnmx444 min -0      0       -> -0
+mnmx445 min -0     -0.0     -> -0
+mnmx446 min -0.100 -0       -> -0.100
+mnmx447 min -0.10  -0.100   -> -0.10
+mnmx448 min -0.1   -0.10    -> -0.1
+mnmx449 min -1.0   -0.1     -> -1.0
+mnmx450 min -1     -1.0     -> -1
+mnmx451 min -1.1   -1       -> -1.1
+mnmx453 min -Inf   -1.1     -> -Infinity
+-- largies
+mnmx460 min  1000   1E+3    ->  1000
+mnmx461 min  1E+3   1000    ->  1000
+mnmx462 min  1000  -1E+3    -> -1E+3
+mnmx463 min  1E+3  -1000    -> -1000
+mnmx464 min -1000   1E+3    -> -1000
+mnmx465 min -1E+3   1000    -> -1E+3
+mnmx466 min -1000  -1E+3    -> -1E+3
+mnmx467 min -1E+3  -1000    -> -1E+3
+
+
+-- overflow tests
+maxexponent: 999999999
+minexponent: -999999999
+precision: 3
+mnmx500 min 9.999E+999999999  0 ->  0
+mnmx501 min -9.999E+999999999 0 -> -Infinity Inexact Overflow Rounded
+
+-- subnormals and underflow
+precision: 3
+maxexponent: 999
+minexponent: -999
+mnmx510 min  1.00E-999       0  ->   0
+mnmx511 min  0.1E-999        0  ->   0
+mnmx512 min  0.10E-999       0  ->   0
+mnmx513 min  0.100E-999      0  ->   0
+mnmx514 min  0.01E-999       0  ->   0
+mnmx515 min  0.999E-999      0  ->   0
+mnmx516 min  0.099E-999      0  ->   0
+mnmx517 min  0.009E-999      0  ->   0
+mnmx518 min  0.001E-999      0  ->   0
+mnmx519 min  0.0009E-999     0  ->   0
+mnmx520 min  0.0001E-999     0  ->   0
+
+mnmx530 min -1.00E-999       0  ->  -1.00E-999
+mnmx531 min -0.1E-999        0  ->  -1E-1000   Subnormal
+mnmx532 min -0.10E-999       0  ->  -1.0E-1000 Subnormal
+mnmx533 min -0.100E-999      0  ->  -1.0E-1000 Subnormal Rounded
+mnmx534 min -0.01E-999       0  ->  -1E-1001   Subnormal
+-- next is rounded to Emin
+mnmx535 min -0.999E-999      0  ->  -1.00E-999 Inexact Rounded Subnormal Underflow
+mnmx536 min -0.099E-999      0  ->  -1.0E-1000 Inexact Rounded Subnormal Underflow
+mnmx537 min -0.009E-999      0  ->  -1E-1001   Inexact Rounded Subnormal Underflow
+mnmx538 min -0.001E-999      0  ->  -0E-1001   Inexact Rounded Subnormal Underflow
+mnmx539 min -0.0009E-999     0  ->  -0E-1001   Inexact Rounded Subnormal Underflow
+mnmx540 min -0.0001E-999     0  ->  -0E-1001   Inexact Rounded Subnormal Underflow
+
+
+-- Null tests
+mnm900 min 10  # -> NaN Invalid_operation
+mnm901 min  # 10 -> NaN Invalid_operation

Added: vendor/Python/current/Lib/test/decimaltestdata/minus.decTest
===================================================================
--- vendor/Python/current/Lib/test/decimaltestdata/minus.decTest	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/decimaltestdata/minus.decTest	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,182 @@
+------------------------------------------------------------------------
+-- minus.decTest -- decimal negation                                  --
+-- Copyright (c) IBM Corporation, 1981, 2004.  All rights reserved.   --
+------------------------------------------------------------------------
+-- Please see the document "General Decimal Arithmetic Testcases"     --
+-- at http://www2.hursley.ibm.com/decimal for the description of      --
+-- these testcases.                                                   --
+--                                                                    --
+-- These testcases are experimental ('beta' versions), and they       --
+-- may contain errors.  They are offered on an as-is basis.  In       --
+-- particular, achieving the same results as the tests here is not    --
+-- a guarantee that an implementation complies with any Standard      --
+-- or specification.  The tests are not exhaustive.                   --
+--                                                                    --
+-- Please send comments, suggestions, and corrections to the author:  --
+--   Mike Cowlishaw, IBM Fellow                                       --
+--   IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK         --
+--   mfc at uk.ibm.com                                                   --
+------------------------------------------------------------------------
+version: 2.39
+
+-- This set of tests primarily tests the existence of the operator.
+-- Subtraction, rounding, and more overflows are tested elsewhere.
+
+extended:    1
+precision:   9
+rounding:    half_up
+maxExponent: 384
+minexponent: -383
+
+minx001 minus '1'      -> '-1'
+minx002 minus '-1'     -> '1'
+minx003 minus '1.00'   -> '-1.00'
+minx004 minus '-1.00'  -> '1.00'
+minx005 minus '0'      -> '0'
+minx006 minus '0.00'   -> '0.00'
+minx007 minus '00.0'   -> '0.0'
+minx008 minus '00.00'  -> '0.00'
+minx009 minus '00'     -> '0'
+
+minx010 minus '-2'     -> '2'
+minx011 minus '2'      -> '-2'
+minx012 minus '-2.00'  -> '2.00'
+minx013 minus '2.00'   -> '-2.00'
+minx014 minus '-0'     -> '0'
+minx015 minus '-0.00'  -> '0.00'
+minx016 minus '-00.0'  -> '0.0'
+minx017 minus '-00.00' -> '0.00'
+minx018 minus '-00'    -> '0'
+
+-- "lhs" zeros in plus and minus have exponent = operand
+minx020 minus '-0E3'   -> '0E+3'
+minx021 minus '-0E2'   -> '0E+2'
+minx022 minus '-0E1'   -> '0E+1'
+minx023 minus '-0E0'   -> '0'
+minx024 minus '+0E0'   -> '0'
+minx025 minus '+0E1'   -> '0E+1'
+minx026 minus '+0E2'   -> '0E+2'
+minx027 minus '+0E3'   -> '0E+3'
+
+minx030 minus '-5E3'   -> '5E+3'
+minx031 minus '-5E8'   -> '5E+8'
+minx032 minus '-5E13'  -> '5E+13'
+minx033 minus '-5E18'  -> '5E+18'
+minx034 minus '+5E3'   -> '-5E+3'
+minx035 minus '+5E8'   -> '-5E+8'
+minx036 minus '+5E13'  -> '-5E+13'
+minx037 minus '+5E18'  -> '-5E+18'
+
+minx050 minus '-2000000' -> '2000000'
+minx051 minus '2000000'  -> '-2000000'
+precision: 7
+minx052 minus '-2000000' -> '2000000'
+minx053 minus '2000000'  -> '-2000000'
+precision: 6
+minx054 minus '-2000000' -> '2.00000E+6' Rounded
+minx055 minus '2000000'  -> '-2.00000E+6' Rounded
+precision: 3
+minx056 minus '-2000000' -> '2.00E+6' Rounded
+minx057 minus '2000000'  -> '-2.00E+6' Rounded
+
+-- more fixed, potential LHS swaps/overlays if done by 0 subtract x
+precision: 9
+minx060 minus '56267E-10'   -> '-0.0000056267'
+minx061 minus '56267E-5'    -> '-0.56267'
+minx062 minus '56267E-2'    -> '-562.67'
+minx063 minus '56267E-1'    -> '-5626.7'
+minx065 minus '56267E-0'    -> '-56267'
+minx066 minus '56267E+0'    -> '-56267'
+minx067 minus '56267E+1'    -> '-5.6267E+5'
+minx068 minus '56267E+2'    -> '-5.6267E+6'
+minx069 minus '56267E+3'    -> '-5.6267E+7'
+minx070 minus '56267E+4'    -> '-5.6267E+8'
+minx071 minus '56267E+5'    -> '-5.6267E+9'
+minx072 minus '56267E+6'    -> '-5.6267E+10'
+minx080 minus '-56267E-10'  -> '0.0000056267'
+minx081 minus '-56267E-5'   -> '0.56267'
+minx082 minus '-56267E-2'   -> '562.67'
+minx083 minus '-56267E-1'   -> '5626.7'
+minx085 minus '-56267E-0'   -> '56267'
+minx086 minus '-56267E+0'   -> '56267'
+minx087 minus '-56267E+1'   -> '5.6267E+5'
+minx088 minus '-56267E+2'   -> '5.6267E+6'
+minx089 minus '-56267E+3'   -> '5.6267E+7'
+minx090 minus '-56267E+4'   -> '5.6267E+8'
+minx091 minus '-56267E+5'   -> '5.6267E+9'
+minx092 minus '-56267E+6'   -> '5.6267E+10'
+
+
+-- overflow tests
+maxexponent: 999999999
+minexponent: -999999999
+precision: 3
+minx100 minus 9.999E+999999999  -> -Infinity Inexact Overflow Rounded
+minx101 minus -9.999E+999999999 ->  Infinity Inexact Overflow Rounded
+
+-- subnormals and underflow
+precision: 3
+maxexponent: 999
+minexponent: -999
+minx110 minus  1.00E-999        ->  -1.00E-999
+minx111 minus  0.1E-999         ->  -1E-1000   Subnormal
+minx112 minus  0.10E-999        ->  -1.0E-1000 Subnormal
+minx113 minus  0.100E-999       ->  -1.0E-1000 Subnormal Rounded
+minx114 minus  0.01E-999        ->  -1E-1001   Subnormal
+-- next is rounded to Emin
+minx115 minus  0.999E-999       ->  -1.00E-999 Inexact Rounded Subnormal Underflow
+minx116 minus  0.099E-999       ->  -1.0E-1000 Inexact Rounded Subnormal Underflow
+minx117 minus  0.009E-999       ->  -1E-1001   Inexact Rounded Subnormal Underflow
+minx118 minus  0.001E-999       ->  -0E-1001   Inexact Rounded Subnormal Underflow
+minx119 minus  0.0009E-999      ->  -0E-1001   Inexact Rounded Subnormal Underflow
+minx120 minus  0.0001E-999      ->  -0E-1001   Inexact Rounded Subnormal Underflow
+
+minx130 minus -1.00E-999        ->   1.00E-999
+minx131 minus -0.1E-999         ->   1E-1000   Subnormal
+minx132 minus -0.10E-999        ->   1.0E-1000 Subnormal
+minx133 minus -0.100E-999       ->   1.0E-1000 Subnormal Rounded
+minx134 minus -0.01E-999        ->   1E-1001   Subnormal
+-- next is rounded to Emin
+minx135 minus -0.999E-999       ->   1.00E-999 Inexact Rounded Subnormal Underflow
+minx136 minus -0.099E-999       ->   1.0E-1000 Inexact Rounded Subnormal Underflow
+minx137 minus -0.009E-999       ->   1E-1001   Inexact Rounded Subnormal Underflow
+minx138 minus -0.001E-999       ->   0E-1001   Inexact Rounded Subnormal Underflow
+minx139 minus -0.0009E-999      ->   0E-1001   Inexact Rounded Subnormal Underflow
+minx140 minus -0.0001E-999      ->   0E-1001   Inexact Rounded Subnormal Underflow
+
+
+-- long operand checks
+maxexponent: 999
+minexponent: -999
+precision: 9
+minx301 minus 12345678000  -> -1.23456780E+10 Rounded
+minx302 minus 1234567800   -> -1.23456780E+9 Rounded
+minx303 minus 1234567890   -> -1.23456789E+9 Rounded
+minx304 minus 1234567891   -> -1.23456789E+9 Inexact Rounded
+minx305 minus 12345678901  -> -1.23456789E+10 Inexact Rounded
+minx306 minus 1234567896   -> -1.23456790E+9 Inexact Rounded
+
+precision: 15
+-- still checking
+minx321 minus 12345678000  -> -12345678000
+minx322 minus 1234567800   -> -1234567800
+minx323 minus 1234567890   -> -1234567890
+minx324 minus 1234567891   -> -1234567891
+minx325 minus 12345678901  -> -12345678901
+minx326 minus 1234567896   -> -1234567896
+
+-- specials
+minx420 minus 'Inf'    -> '-Infinity'
+minx421 minus '-Inf'   -> 'Infinity'
+minx422 minus   NaN    ->  NaN
+minx423 minus  sNaN    ->  NaN    Invalid_operation
+minx424 minus   NaN255 ->  NaN255
+minx425 minus  sNaN256 ->  NaN256 Invalid_operation
+minx426 minus  -NaN    -> -NaN
+minx427 minus -sNaN    -> -NaN    Invalid_operation
+minx428 minus  -NaN255 -> -NaN255
+minx429 minus -sNaN256 -> -NaN256 Invalid_operation
+
+-- Null tests
+minx900 minus  # -> NaN Invalid_operation
+

Added: vendor/Python/current/Lib/test/decimaltestdata/multiply.decTest
===================================================================
--- vendor/Python/current/Lib/test/decimaltestdata/multiply.decTest	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/decimaltestdata/multiply.decTest	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,651 @@
+------------------------------------------------------------------------
+-- multiply.decTest -- decimal multiplication                         --
+-- Copyright (c) IBM Corporation, 1981, 2004.  All rights reserved.   --
+------------------------------------------------------------------------
+-- Please see the document "General Decimal Arithmetic Testcases"     --
+-- at http://www2.hursley.ibm.com/decimal for the description of      --
+-- these testcases.                                                   --
+--                                                                    --
+-- These testcases are experimental ('beta' versions), and they       --
+-- may contain errors.  They are offered on an as-is basis.  In       --
+-- particular, achieving the same results as the tests here is not    --
+-- a guarantee that an implementation complies with any Standard      --
+-- or specification.  The tests are not exhaustive.                   --
+--                                                                    --
+-- Please send comments, suggestions, and corrections to the author:  --
+--   Mike Cowlishaw, IBM Fellow                                       --
+--   IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK         --
+--   mfc at uk.ibm.com                                                   --
+------------------------------------------------------------------------
+version: 2.39
+
+extended:    1
+precision:   9
+rounding:    half_up
+maxExponent: 384
+minexponent: -383
+
+-- sanity checks (as base, above)
+mulx000 multiply 2      2 -> 4
+mulx001 multiply 2      3 -> 6
+mulx002 multiply 5      1 -> 5
+mulx003 multiply 5      2 -> 10
+mulx004 multiply 1.20   2 -> 2.40
+mulx005 multiply 1.20   0 -> 0.00
+mulx006 multiply 1.20  -2 -> -2.40
+mulx007 multiply -1.20  2 -> -2.40
+mulx008 multiply -1.20  0 -> -0.00
+mulx009 multiply -1.20 -2 -> 2.40
+mulx010 multiply 5.09 7.1 -> 36.139
+mulx011 multiply 2.5    4 -> 10.0
+mulx012 multiply 2.50   4 -> 10.00
+mulx013 multiply 1.23456789 1.00000000 -> 1.23456789 Rounded
+mulx014 multiply 9.999999999 9.999999999 -> 100.000000 Inexact Rounded
+mulx015 multiply 2.50   4 -> 10.00
+precision: 6
+mulx016 multiply 2.50   4 -> 10.00
+mulx017 multiply 9.999999999 9.999999999 -> 100.000 Inexact Rounded
+
+-- 1999.12.21: next one is a edge case if intermediate longs are used
+precision: 15
+mulx019 multiply 999999999999 9765625 -> 9.76562499999023E+18 Inexact Rounded
+precision: 30
+mulx160 multiply 999999999999 9765625 -> 9765624999990234375
+precision: 9
+-----
+
+-- zeros, etc.
+mulx020 multiply  0      0     ->  0
+mulx021 multiply  0     -0     -> -0
+mulx022 multiply -0      0     -> -0
+mulx023 multiply -0     -0     ->  0
+mulx030 multiply  5.00   1E-3  ->  0.00500
+mulx031 multiply  00.00  0.000 ->  0.00000
+mulx032 multiply  00.00  0E-3  ->  0.00000     -- rhs is 0
+mulx033 multiply  0E-3   00.00 ->  0.00000     -- lhs is 0
+mulx034 multiply -5.00   1E-3  -> -0.00500
+mulx035 multiply -00.00  0.000 -> -0.00000
+mulx036 multiply -00.00  0E-3  -> -0.00000     -- rhs is 0
+mulx037 multiply -0E-3   00.00 -> -0.00000     -- lhs is 0
+mulx038 multiply  5.00  -1E-3  -> -0.00500
+mulx039 multiply  00.00 -0.000 -> -0.00000
+mulx040 multiply  00.00 -0E-3  -> -0.00000     -- rhs is 0
+mulx041 multiply  0E-3  -00.00 -> -0.00000     -- lhs is 0
+mulx042 multiply -5.00  -1E-3  ->  0.00500
+mulx043 multiply -00.00 -0.000 ->  0.00000
+mulx044 multiply -00.00 -0E-3  ->  0.00000     -- rhs is 0
+mulx045 multiply -0E-3  -00.00 ->  0.00000     -- lhs is 0
+
+-- examples from decarith
+mulx050 multiply 1.20 3        -> 3.60
+mulx051 multiply 7    3        -> 21
+mulx052 multiply 0.9  0.8      -> 0.72
+mulx053 multiply 0.9  -0       -> -0.0
+mulx054 multiply 654321 654321 -> 4.28135971E+11  Inexact Rounded
+
+mulx060 multiply 123.45 1e7  ->  1.2345E+9
+mulx061 multiply 123.45 1e8  ->  1.2345E+10
+mulx062 multiply 123.45 1e+9 ->  1.2345E+11
+mulx063 multiply 123.45 1e10 ->  1.2345E+12
+mulx064 multiply 123.45 1e11 ->  1.2345E+13
+mulx065 multiply 123.45 1e12 ->  1.2345E+14
+mulx066 multiply 123.45 1e13 ->  1.2345E+15
+
+
+-- test some intermediate lengths
+precision: 9
+mulx080 multiply 0.1 123456789           -> 12345678.9
+mulx081 multiply 0.1 1234567891          -> 123456789 Inexact Rounded
+mulx082 multiply 0.1 12345678912         -> 1.23456789E+9 Inexact Rounded
+mulx083 multiply 0.1 12345678912345      -> 1.23456789E+12 Inexact Rounded
+mulx084 multiply 0.1 123456789           -> 12345678.9
+precision: 8
+mulx085 multiply 0.1 12345678912         -> 1.2345679E+9 Inexact Rounded
+mulx086 multiply 0.1 12345678912345      -> 1.2345679E+12 Inexact Rounded
+precision: 7
+mulx087 multiply 0.1 12345678912         -> 1.234568E+9 Inexact Rounded
+mulx088 multiply 0.1 12345678912345      -> 1.234568E+12 Inexact Rounded
+
+precision: 9
+mulx090 multiply 123456789          0.1 -> 12345678.9
+mulx091 multiply 1234567891         0.1 -> 123456789 Inexact Rounded
+mulx092 multiply 12345678912        0.1 -> 1.23456789E+9 Inexact Rounded
+mulx093 multiply 12345678912345     0.1 -> 1.23456789E+12 Inexact Rounded
+mulx094 multiply 123456789          0.1 -> 12345678.9
+precision: 8
+mulx095 multiply 12345678912        0.1 -> 1.2345679E+9 Inexact Rounded
+mulx096 multiply 12345678912345     0.1 -> 1.2345679E+12 Inexact Rounded
+precision: 7
+mulx097 multiply 12345678912        0.1 -> 1.234568E+9 Inexact Rounded
+mulx098 multiply 12345678912345     0.1 -> 1.234568E+12 Inexact Rounded
+
+-- test some more edge cases and carries
+maxexponent: 9999
+minexponent: -9999
+precision: 33
+mulx101 multiply 9 9   -> 81
+mulx102 multiply 9 90   -> 810
+mulx103 multiply 9 900   -> 8100
+mulx104 multiply 9 9000   -> 81000
+mulx105 multiply 9 90000   -> 810000
+mulx106 multiply 9 900000   -> 8100000
+mulx107 multiply 9 9000000   -> 81000000
+mulx108 multiply 9 90000000   -> 810000000
+mulx109 multiply 9 900000000   -> 8100000000
+mulx110 multiply 9 9000000000   -> 81000000000
+mulx111 multiply 9 90000000000   -> 810000000000
+mulx112 multiply 9 900000000000   -> 8100000000000
+mulx113 multiply 9 9000000000000   -> 81000000000000
+mulx114 multiply 9 90000000000000   -> 810000000000000
+mulx115 multiply 9 900000000000000   -> 8100000000000000
+mulx116 multiply 9 9000000000000000   -> 81000000000000000
+mulx117 multiply 9 90000000000000000   -> 810000000000000000
+mulx118 multiply 9 900000000000000000   -> 8100000000000000000
+mulx119 multiply 9 9000000000000000000   -> 81000000000000000000
+mulx120 multiply 9 90000000000000000000   -> 810000000000000000000
+mulx121 multiply 9 900000000000000000000   -> 8100000000000000000000
+mulx122 multiply 9 9000000000000000000000   -> 81000000000000000000000
+mulx123 multiply 9 90000000000000000000000   -> 810000000000000000000000
+-- test some more edge cases without carries
+mulx131 multiply 3 3   -> 9
+mulx132 multiply 3 30   -> 90
+mulx133 multiply 3 300   -> 900
+mulx134 multiply 3 3000   -> 9000
+mulx135 multiply 3 30000   -> 90000
+mulx136 multiply 3 300000   -> 900000
+mulx137 multiply 3 3000000   -> 9000000
+mulx138 multiply 3 30000000   -> 90000000
+mulx139 multiply 3 300000000   -> 900000000
+mulx140 multiply 3 3000000000   -> 9000000000
+mulx141 multiply 3 30000000000   -> 90000000000
+mulx142 multiply 3 300000000000   -> 900000000000
+mulx143 multiply 3 3000000000000   -> 9000000000000
+mulx144 multiply 3 30000000000000   -> 90000000000000
+mulx145 multiply 3 300000000000000   -> 900000000000000
+mulx146 multiply 3 3000000000000000   -> 9000000000000000
+mulx147 multiply 3 30000000000000000   -> 90000000000000000
+mulx148 multiply 3 300000000000000000   -> 900000000000000000
+mulx149 multiply 3 3000000000000000000   -> 9000000000000000000
+mulx150 multiply 3 30000000000000000000   -> 90000000000000000000
+mulx151 multiply 3 300000000000000000000   -> 900000000000000000000
+mulx152 multiply 3 3000000000000000000000   -> 9000000000000000000000
+mulx153 multiply 3 30000000000000000000000   -> 90000000000000000000000
+
+maxexponent: 999999999
+minexponent: -999999999
+precision: 9
+-- test some cases that are close to exponent overflow/underflow
+mulx170 multiply 1 9e999999999    -> 9E+999999999
+mulx171 multiply 1 9.9e999999999  -> 9.9E+999999999
+mulx172 multiply 1 9.99e999999999 -> 9.99E+999999999
+mulx173 multiply 9e999999999    1 -> 9E+999999999
+mulx174 multiply 9.9e999999999  1 -> 9.9E+999999999
+mulx176 multiply 9.99e999999999 1 -> 9.99E+999999999
+mulx177 multiply 1 9.99999999e999999999 -> 9.99999999E+999999999
+mulx178 multiply 9.99999999e999999999 1 -> 9.99999999E+999999999
+
+mulx180 multiply 0.1 9e-999999998   -> 9E-999999999
+mulx181 multiply 0.1 99e-999999998  -> 9.9E-999999998
+mulx182 multiply 0.1 999e-999999998 -> 9.99E-999999997
+
+mulx183 multiply 0.1 9e-999999998     -> 9E-999999999
+mulx184 multiply 0.1 99e-999999998    -> 9.9E-999999998
+mulx185 multiply 0.1 999e-999999998   -> 9.99E-999999997
+mulx186 multiply 0.1 999e-999999997   -> 9.99E-999999996
+mulx187 multiply 0.1 9999e-999999997  -> 9.999E-999999995
+mulx188 multiply 0.1 99999e-999999997 -> 9.9999E-999999994
+
+mulx190 multiply 1 9e-999999998   -> 9E-999999998
+mulx191 multiply 1 99e-999999998  -> 9.9E-999999997
+mulx192 multiply 1 999e-999999998 -> 9.99E-999999996
+mulx193 multiply 9e-999999998   1 -> 9E-999999998
+mulx194 multiply 99e-999999998  1 -> 9.9E-999999997
+mulx195 multiply 999e-999999998 1 -> 9.99E-999999996
+
+mulx196 multiply 1e-599999999 1e-400000000 -> 1E-999999999
+mulx197 multiply 1e-600000000 1e-399999999 -> 1E-999999999
+mulx198 multiply 1.2e-599999999 1.2e-400000000 -> 1.44E-999999999
+mulx199 multiply 1.2e-600000000 1.2e-399999999 -> 1.44E-999999999
+
+mulx201 multiply 1e599999999 1e400000000 -> 1E+999999999
+mulx202 multiply 1e600000000 1e399999999 -> 1E+999999999
+mulx203 multiply 1.2e599999999 1.2e400000000 -> 1.44E+999999999
+mulx204 multiply 1.2e600000000 1.2e399999999 -> 1.44E+999999999
+
+-- long operand triangle
+precision: 33
+mulx246 multiply 30269.587755640502150977251770554 4.8046009735990873395936309640543 -> 145433.290801193369671916511992830 Inexact Rounded
+precision: 32
+mulx247 multiply 30269.587755640502150977251770554 4.8046009735990873395936309640543 -> 145433.29080119336967191651199283  Inexact Rounded
+precision: 31
+mulx248 multiply 30269.587755640502150977251770554 4.8046009735990873395936309640543 -> 145433.2908011933696719165119928   Inexact Rounded
+precision: 30
+mulx249 multiply 30269.587755640502150977251770554 4.8046009735990873395936309640543 -> 145433.290801193369671916511993    Inexact Rounded
+precision: 29
+mulx250 multiply 30269.587755640502150977251770554 4.8046009735990873395936309640543 -> 145433.29080119336967191651199     Inexact Rounded
+precision: 28
+mulx251 multiply 30269.587755640502150977251770554 4.8046009735990873395936309640543 -> 145433.2908011933696719165120      Inexact Rounded
+precision: 27
+mulx252 multiply 30269.587755640502150977251770554 4.8046009735990873395936309640543 -> 145433.290801193369671916512       Inexact Rounded
+precision: 26
+mulx253 multiply 30269.587755640502150977251770554 4.8046009735990873395936309640543 -> 145433.29080119336967191651        Inexact Rounded
+precision: 25
+mulx254 multiply 30269.587755640502150977251770554 4.8046009735990873395936309640543 -> 145433.2908011933696719165         Inexact Rounded
+precision: 24
+mulx255 multiply 30269.587755640502150977251770554 4.8046009735990873395936309640543 -> 145433.290801193369671917          Inexact Rounded
+precision: 23
+mulx256 multiply 30269.587755640502150977251770554 4.8046009735990873395936309640543 -> 145433.29080119336967192           Inexact Rounded
+precision: 22
+mulx257 multiply 30269.587755640502150977251770554 4.8046009735990873395936309640543 -> 145433.2908011933696719            Inexact Rounded
+precision: 21
+mulx258 multiply 30269.587755640502150977251770554 4.8046009735990873395936309640543 -> 145433.290801193369672             Inexact Rounded
+precision: 20
+mulx259 multiply 30269.587755640502150977251770554 4.8046009735990873395936309640543 -> 145433.29080119336967              Inexact Rounded
+precision: 19
+mulx260 multiply 30269.587755640502150977251770554 4.8046009735990873395936309640543 -> 145433.2908011933697               Inexact Rounded
+precision: 18
+mulx261 multiply 30269.587755640502150977251770554 4.8046009735990873395936309640543 -> 145433.290801193370                Inexact Rounded
+precision: 17
+mulx262 multiply 30269.587755640502150977251770554 4.8046009735990873395936309640543 -> 145433.29080119337                 Inexact Rounded
+precision: 16
+mulx263 multiply 30269.587755640502150977251770554 4.8046009735990873395936309640543 -> 145433.2908011934                  Inexact Rounded
+precision: 15
+mulx264 multiply 30269.587755640502150977251770554 4.8046009735990873395936309640543 -> 145433.290801193                   Inexact Rounded
+precision: 14
+mulx265 multiply 30269.587755640502150977251770554 4.8046009735990873395936309640543 -> 145433.29080119                    Inexact Rounded
+precision: 13
+mulx266 multiply 30269.587755640502150977251770554 4.8046009735990873395936309640543 -> 145433.2908012                     Inexact Rounded
+precision: 12
+mulx267 multiply 30269.587755640502150977251770554 4.8046009735990873395936309640543 -> 145433.290801                      Inexact Rounded
+precision: 11
+mulx268 multiply 30269.587755640502150977251770554 4.8046009735990873395936309640543 -> 145433.29080                       Inexact Rounded
+precision: 10
+mulx269 multiply 30269.587755640502150977251770554 4.8046009735990873395936309640543 -> 145433.2908                        Inexact Rounded
+precision:  9
+mulx270 multiply 30269.587755640502150977251770554 4.8046009735990873395936309640543 -> 145433.291                         Inexact Rounded
+precision:  8
+mulx271 multiply 30269.587755640502150977251770554 4.8046009735990873395936309640543 -> 145433.29                          Inexact Rounded
+precision:  7
+mulx272 multiply 30269.587755640502150977251770554 4.8046009735990873395936309640543 -> 145433.3                           Inexact Rounded
+precision:  6
+mulx273 multiply 30269.587755640502150977251770554 4.8046009735990873395936309640543 -> 145433                            Inexact Rounded
+precision:  5
+mulx274 multiply 30269.587755640502150977251770554 4.8046009735990873395936309640543 -> 1.4543E+5                         Inexact Rounded
+precision:  4
+mulx275 multiply 30269.587755640502150977251770554 4.8046009735990873395936309640543 -> 1.454E+5                         Inexact Rounded
+precision:  3
+mulx276 multiply 30269.587755640502150977251770554 4.8046009735990873395936309640543 -> 1.45E+5                         Inexact Rounded
+precision:  2
+mulx277 multiply 30269.587755640502150977251770554 4.8046009735990873395936309640543 -> 1.5E+5                         Inexact Rounded
+precision:  1
+mulx278 multiply 30269.587755640502150977251770554 4.8046009735990873395936309640543 -> 1E+5                          Inexact Rounded
+
+-- tryzeros cases
+precision:   7
+rounding:    half_up
+maxExponent: 92
+minexponent: -92
+mulx504  multiply  0E-60 1000E-60  -> 0E-98 Clamped
+mulx505  multiply  100E+60 0E+60   -> 0E+92 Clamped
+
+-- mixed with zeros
+maxexponent: 999999999
+minexponent: -999999999
+precision: 9
+mulx541 multiply  0    -1     -> -0
+mulx542 multiply -0    -1     ->  0
+mulx543 multiply  0     1     ->  0
+mulx544 multiply -0     1     -> -0
+mulx545 multiply -1     0     -> -0
+mulx546 multiply -1    -0     ->  0
+mulx547 multiply  1     0     ->  0
+mulx548 multiply  1    -0     -> -0
+
+mulx551 multiply  0.0  -1     -> -0.0
+mulx552 multiply -0.0  -1     ->  0.0
+mulx553 multiply  0.0   1     ->  0.0
+mulx554 multiply -0.0   1     -> -0.0
+mulx555 multiply -1.0   0     -> -0.0
+mulx556 multiply -1.0  -0     ->  0.0
+mulx557 multiply  1.0   0     ->  0.0
+mulx558 multiply  1.0  -0     -> -0.0
+
+mulx561 multiply  0    -1.0   -> -0.0
+mulx562 multiply -0    -1.0   ->  0.0
+mulx563 multiply  0     1.0   ->  0.0
+mulx564 multiply -0     1.0   -> -0.0
+mulx565 multiply -1     0.0   -> -0.0
+mulx566 multiply -1    -0.0   ->  0.0
+mulx567 multiply  1     0.0   ->  0.0
+mulx568 multiply  1    -0.0   -> -0.0
+
+mulx571 multiply  0.0  -1.0   -> -0.00
+mulx572 multiply -0.0  -1.0   ->  0.00
+mulx573 multiply  0.0   1.0   ->  0.00
+mulx574 multiply -0.0   1.0   -> -0.00
+mulx575 multiply -1.0   0.0   -> -0.00
+mulx576 multiply -1.0  -0.0   ->  0.00
+mulx577 multiply  1.0   0.0   ->  0.00
+mulx578 multiply  1.0  -0.0   -> -0.00
+
+
+-- Specials
+mulx580 multiply  Inf  -Inf   -> -Infinity
+mulx581 multiply  Inf  -1000  -> -Infinity
+mulx582 multiply  Inf  -1     -> -Infinity
+mulx583 multiply  Inf  -0     ->  NaN  Invalid_operation
+mulx584 multiply  Inf   0     ->  NaN  Invalid_operation
+mulx585 multiply  Inf   1     ->  Infinity
+mulx586 multiply  Inf   1000  ->  Infinity
+mulx587 multiply  Inf   Inf   ->  Infinity
+mulx588 multiply -1000  Inf   -> -Infinity
+mulx589 multiply -Inf   Inf   -> -Infinity
+mulx590 multiply -1     Inf   -> -Infinity
+mulx591 multiply -0     Inf   ->  NaN  Invalid_operation
+mulx592 multiply  0     Inf   ->  NaN  Invalid_operation
+mulx593 multiply  1     Inf   ->  Infinity
+mulx594 multiply  1000  Inf   ->  Infinity
+mulx595 multiply  Inf   Inf   ->  Infinity
+
+mulx600 multiply -Inf  -Inf   ->  Infinity
+mulx601 multiply -Inf  -1000  ->  Infinity
+mulx602 multiply -Inf  -1     ->  Infinity
+mulx603 multiply -Inf  -0     ->  NaN  Invalid_operation
+mulx604 multiply -Inf   0     ->  NaN  Invalid_operation
+mulx605 multiply -Inf   1     -> -Infinity
+mulx606 multiply -Inf   1000  -> -Infinity
+mulx607 multiply -Inf   Inf   -> -Infinity
+mulx608 multiply -1000  Inf   -> -Infinity
+mulx609 multiply -Inf  -Inf   ->  Infinity
+mulx610 multiply -1    -Inf   ->  Infinity
+mulx611 multiply -0    -Inf   ->  NaN  Invalid_operation
+mulx612 multiply  0    -Inf   ->  NaN  Invalid_operation
+mulx613 multiply  1    -Inf   -> -Infinity
+mulx614 multiply  1000 -Inf   -> -Infinity
+mulx615 multiply  Inf  -Inf   -> -Infinity
+
+mulx621 multiply  NaN -Inf    ->  NaN
+mulx622 multiply  NaN -1000   ->  NaN
+mulx623 multiply  NaN -1      ->  NaN
+mulx624 multiply  NaN -0      ->  NaN
+mulx625 multiply  NaN  0      ->  NaN
+mulx626 multiply  NaN  1      ->  NaN
+mulx627 multiply  NaN  1000   ->  NaN
+mulx628 multiply  NaN  Inf    ->  NaN
+mulx629 multiply  NaN  NaN    ->  NaN
+mulx630 multiply -Inf  NaN    ->  NaN
+mulx631 multiply -1000 NaN    ->  NaN
+mulx632 multiply -1    NaN    ->  NaN
+mulx633 multiply -0    NaN    ->  NaN
+mulx634 multiply  0    NaN    ->  NaN
+mulx635 multiply  1    NaN    ->  NaN
+mulx636 multiply  1000 NaN    ->  NaN
+mulx637 multiply  Inf  NaN    ->  NaN
+
+mulx641 multiply  sNaN -Inf   ->  NaN  Invalid_operation
+mulx642 multiply  sNaN -1000  ->  NaN  Invalid_operation
+mulx643 multiply  sNaN -1     ->  NaN  Invalid_operation
+mulx644 multiply  sNaN -0     ->  NaN  Invalid_operation
+mulx645 multiply  sNaN  0     ->  NaN  Invalid_operation
+mulx646 multiply  sNaN  1     ->  NaN  Invalid_operation
+mulx647 multiply  sNaN  1000  ->  NaN  Invalid_operation
+mulx648 multiply  sNaN  NaN   ->  NaN  Invalid_operation
+mulx649 multiply  sNaN sNaN   ->  NaN  Invalid_operation
+mulx650 multiply  NaN  sNaN   ->  NaN  Invalid_operation
+mulx651 multiply -Inf  sNaN   ->  NaN  Invalid_operation
+mulx652 multiply -1000 sNaN   ->  NaN  Invalid_operation
+mulx653 multiply -1    sNaN   ->  NaN  Invalid_operation
+mulx654 multiply -0    sNaN   ->  NaN  Invalid_operation
+mulx655 multiply  0    sNaN   ->  NaN  Invalid_operation
+mulx656 multiply  1    sNaN   ->  NaN  Invalid_operation
+mulx657 multiply  1000 sNaN   ->  NaN  Invalid_operation
+mulx658 multiply  Inf  sNaN   ->  NaN  Invalid_operation
+mulx659 multiply  NaN  sNaN   ->  NaN  Invalid_operation
+
+-- propagating NaNs
+mulx661 multiply  NaN9 -Inf   ->  NaN9
+mulx662 multiply  NaN8  999   ->  NaN8
+mulx663 multiply  NaN71 Inf   ->  NaN71
+mulx664 multiply  NaN6  NaN5  ->  NaN6
+mulx665 multiply -Inf   NaN4  ->  NaN4
+mulx666 multiply -999   NaN33 ->  NaN33
+mulx667 multiply  Inf   NaN2  ->  NaN2
+
+mulx671 multiply  sNaN99 -Inf    ->  NaN99 Invalid_operation
+mulx672 multiply  sNaN98 -11     ->  NaN98 Invalid_operation
+mulx673 multiply  sNaN97  NaN    ->  NaN97 Invalid_operation
+mulx674 multiply  sNaN16 sNaN94  ->  NaN16 Invalid_operation
+mulx675 multiply  NaN95  sNaN93  ->  NaN93 Invalid_operation
+mulx676 multiply -Inf    sNaN92  ->  NaN92 Invalid_operation
+mulx677 multiply  088    sNaN91  ->  NaN91 Invalid_operation
+mulx678 multiply  Inf    sNaN90  ->  NaN90 Invalid_operation
+mulx679 multiply  NaN    sNaN89  ->  NaN89 Invalid_operation
+
+mulx681 multiply -NaN9 -Inf   -> -NaN9
+mulx682 multiply -NaN8  999   -> -NaN8
+mulx683 multiply -NaN71 Inf   -> -NaN71
+mulx684 multiply -NaN6 -NaN5  -> -NaN6
+mulx685 multiply -Inf  -NaN4  -> -NaN4
+mulx686 multiply -999  -NaN33 -> -NaN33
+mulx687 multiply  Inf  -NaN2  -> -NaN2
+
+mulx691 multiply -sNaN99 -Inf    -> -NaN99 Invalid_operation
+mulx692 multiply -sNaN98 -11     -> -NaN98 Invalid_operation
+mulx693 multiply -sNaN97  NaN    -> -NaN97 Invalid_operation
+mulx694 multiply -sNaN16 -sNaN94 -> -NaN16 Invalid_operation
+mulx695 multiply -NaN95  -sNaN93 -> -NaN93 Invalid_operation
+mulx696 multiply -Inf    -sNaN92 -> -NaN92 Invalid_operation
+mulx697 multiply  088    -sNaN91 -> -NaN91 Invalid_operation
+mulx698 multiply  Inf    -sNaN90 -> -NaN90 Invalid_operation
+mulx699 multiply -NaN    -sNaN89 -> -NaN89 Invalid_operation
+
+mulx701 multiply -NaN  -Inf   -> -NaN
+mulx702 multiply -NaN   999   -> -NaN
+mulx703 multiply -NaN   Inf   -> -NaN
+mulx704 multiply -NaN  -NaN   -> -NaN
+mulx705 multiply -Inf  -NaN0  -> -NaN
+mulx706 multiply -999  -NaN   -> -NaN
+mulx707 multiply  Inf  -NaN   -> -NaN
+
+mulx711 multiply -sNaN   -Inf    -> -NaN Invalid_operation
+mulx712 multiply -sNaN   -11     -> -NaN Invalid_operation
+mulx713 multiply -sNaN00  NaN    -> -NaN Invalid_operation
+mulx714 multiply -sNaN   -sNaN   -> -NaN Invalid_operation
+mulx715 multiply -NaN    -sNaN   -> -NaN Invalid_operation
+mulx716 multiply -Inf    -sNaN   -> -NaN Invalid_operation
+mulx717 multiply  088    -sNaN   -> -NaN Invalid_operation
+mulx718 multiply  Inf    -sNaN   -> -NaN Invalid_operation
+mulx719 multiply -NaN    -sNaN   -> -NaN Invalid_operation
+
+-- overflow and underflow tests .. note subnormal results
+maxexponent: 999999999
+minexponent: -999999999
+mulx730 multiply +1.23456789012345E-0 9E+999999999 -> Infinity Inexact Overflow Rounded
+mulx731 multiply 9E+999999999 +1.23456789012345E-0 -> Infinity Inexact Overflow Rounded
+mulx732 multiply +0.100 9E-999999999 -> 9.00E-1000000000 Subnormal
+mulx733 multiply 9E-999999999 +0.100 -> 9.00E-1000000000 Subnormal
+mulx735 multiply -1.23456789012345E-0 9E+999999999 -> -Infinity Inexact Overflow Rounded
+mulx736 multiply 9E+999999999 -1.23456789012345E-0 -> -Infinity Inexact Overflow Rounded
+mulx737 multiply -0.100 9E-999999999 -> -9.00E-1000000000 Subnormal
+mulx738 multiply 9E-999999999 -0.100 -> -9.00E-1000000000 Subnormal
+
+mulx739 multiply 1e-599999999 1e-400000001 -> 1E-1000000000 Subnormal
+mulx740 multiply 1e-599999999 1e-400000000 -> 1E-999999999
+mulx741 multiply 1e-600000000 1e-400000000 -> 1E-1000000000 Subnormal
+mulx742 multiply 9e-999999998 0.01 -> 9E-1000000000 Subnormal
+mulx743 multiply 9e-999999998 0.1  -> 9E-999999999
+mulx744 multiply 0.01 9e-999999998 -> 9E-1000000000 Subnormal
+mulx745 multiply 1e599999999 1e400000001 -> Infinity Overflow Inexact Rounded
+mulx746 multiply 1e599999999 1e400000000 -> 1E+999999999
+mulx747 multiply 1e600000000 1e400000000 -> Infinity Overflow Inexact Rounded
+mulx748 multiply 9e999999998 100  -> Infinity Overflow Inexact Rounded
+mulx749 multiply 9e999999998 10   -> 9.0E+999999999
+mulx750 multiply 100  9e999999998 -> Infinity Overflow Inexact Rounded
+-- signs
+mulx751 multiply  1e+777777777  1e+411111111 ->  Infinity Overflow Inexact Rounded
+mulx752 multiply  1e+777777777 -1e+411111111 -> -Infinity Overflow Inexact Rounded
+mulx753 multiply -1e+777777777  1e+411111111 -> -Infinity Overflow Inexact Rounded
+mulx754 multiply -1e+777777777 -1e+411111111 ->  Infinity Overflow Inexact Rounded
+mulx755 multiply  1e-777777777  1e-411111111 ->  0E-1000000007 Underflow Subnormal Inexact Rounded
+mulx756 multiply  1e-777777777 -1e-411111111 -> -0E-1000000007 Underflow Subnormal Inexact Rounded
+mulx757 multiply -1e-777777777  1e-411111111 -> -0E-1000000007 Underflow Subnormal Inexact Rounded
+mulx758 multiply -1e-777777777 -1e-411111111 ->  0E-1000000007 Underflow Subnormal Inexact Rounded
+
+-- 'subnormal' boundary (all hard underflow or overflow in base arithemtic)
+precision: 9
+mulx760 multiply 1e-600000000 1e-400000001 -> 1E-1000000001 Subnormal
+mulx761 multiply 1e-600000000 1e-400000002 -> 1E-1000000002 Subnormal
+mulx762 multiply 1e-600000000 1e-400000003 -> 1E-1000000003 Subnormal
+mulx763 multiply 1e-600000000 1e-400000004 -> 1E-1000000004 Subnormal
+mulx764 multiply 1e-600000000 1e-400000005 -> 1E-1000000005 Subnormal
+mulx765 multiply 1e-600000000 1e-400000006 -> 1E-1000000006 Subnormal
+mulx766 multiply 1e-600000000 1e-400000007 -> 1E-1000000007 Subnormal
+mulx767 multiply 1e-600000000 1e-400000008 -> 0E-1000000007 Underflow Subnormal Inexact Rounded
+mulx768 multiply 1e-600000000 1e-400000009 -> 0E-1000000007 Underflow Subnormal Inexact Rounded
+mulx769 multiply 1e-600000000 1e-400000010 -> 0E-1000000007 Underflow Subnormal Inexact Rounded
+-- [no equivalent of 'subnormal' for overflow]
+mulx770 multiply 1e+600000000 1e+400000001 -> Infinity Overflow Inexact Rounded
+mulx771 multiply 1e+600000000 1e+400000002 -> Infinity Overflow Inexact Rounded
+mulx772 multiply 1e+600000000 1e+400000003 -> Infinity Overflow Inexact Rounded
+mulx773 multiply 1e+600000000 1e+400000004 -> Infinity Overflow Inexact Rounded
+mulx774 multiply 1e+600000000 1e+400000005 -> Infinity Overflow Inexact Rounded
+mulx775 multiply 1e+600000000 1e+400000006 -> Infinity Overflow Inexact Rounded
+mulx776 multiply 1e+600000000 1e+400000007 -> Infinity Overflow Inexact Rounded
+mulx777 multiply 1e+600000000 1e+400000008 -> Infinity Overflow Inexact Rounded
+mulx778 multiply 1e+600000000 1e+400000009 -> Infinity Overflow Inexact Rounded
+mulx779 multiply 1e+600000000 1e+400000010 -> Infinity Overflow Inexact Rounded
+
+-- 'subnormal' test edge condition at higher precisions
+precision: 99
+mulx780 multiply 1e-600000000 1e-400000007 -> 1E-1000000007 Subnormal
+mulx781 multiply 1e-600000000 1e-400000008 -> 1E-1000000008 Subnormal
+mulx782 multiply 1e-600000000 1e-400000097 -> 1E-1000000097 Subnormal
+mulx783 multiply 1e-600000000 1e-400000098 -> 0E-1000000097 Underflow Subnormal Inexact Rounded
+precision: 999
+mulx784 multiply 1e-600000000 1e-400000997 -> 1E-1000000997 Subnormal
+mulx785 multiply 1e-600000000 1e-400000998 -> 0E-1000000997 Underflow Subnormal Inexact Rounded
+
+-- following testcases [through mulx800] not yet run against code
+precision: 9999
+mulx786 multiply 1e-600000000 1e-400009997 -> 1E-1000009997 Subnormal
+mulx787 multiply 1e-600000000 1e-400009998 -> 0E-1000009997 Underflow Subnormal Inexact Rounded
+precision: 99999
+mulx788 multiply 1e-600000000 1e-400099997 -> 1E-1000099997 Subnormal
+mulx789 multiply 1e-600000000 1e-400099998 -> 0E-1000099997 Underflow Subnormal Inexact Rounded
+precision: 999999
+mulx790 multiply 1e-600000000 1e-400999997 -> 1E-1000999997 Subnormal
+mulx791 multiply 1e-600000000 1e-400999998 -> 0E-1000999997 Underflow Subnormal Inexact Rounded
+precision: 9999999
+mulx792 multiply 1e-600000000 1e-409999997 -> 1E-1009999997 Subnormal
+mulx793 multiply 1e-600000000 1e-409999998 -> 0E-1009999997 Underflow Subnormal Inexact Rounded
+precision: 99999999
+mulx794 multiply 1e-600000000 1e-499999997 -> 1E-1099999997 Subnormal
+mulx795 multiply 1e-600000000 1e-499999998 -> 0E-1099999997 Underflow Subnormal Inexact Rounded
+precision: 999999999
+mulx796 multiply 1e-999999999 1e-999999997 -> 1E-1999999996 Subnormal
+mulx797 multiply 1e-999999999 1e-999999998 -> 1E-1999999997 Subnormal
+mulx798 multiply 1e-999999999 1e-999999999 -> 0E-1999999997 Underflow Subnormal Inexact Rounded
+mulx799 multiply 1e-600000000 1e-400000007 -> 1E-1000000007 Subnormal
+mulx800 multiply 1e-600000000 1e-400000008 -> 1E-1000000008 Subnormal
+
+-- test subnormals rounding
+precision:   5
+maxExponent: 999
+minexponent: -999
+rounding:    half_even
+
+mulx801 multiply  1.0000E-999  1     -> 1.0000E-999
+mulx802 multiply  1.000E-999   1e-1  -> 1.000E-1000 Subnormal
+mulx803 multiply  1.00E-999    1e-2  -> 1.00E-1001  Subnormal
+mulx804 multiply  1.0E-999     1e-3  -> 1.0E-1002   Subnormal
+mulx805 multiply  1.0E-999     1e-4  -> 1E-1003     Subnormal Rounded
+mulx806 multiply  1.3E-999     1e-4  -> 1E-1003     Underflow Subnormal Inexact Rounded
+mulx807 multiply  1.5E-999     1e-4  -> 2E-1003     Underflow Subnormal Inexact Rounded
+mulx808 multiply  1.7E-999     1e-4  -> 2E-1003     Underflow Subnormal Inexact Rounded
+mulx809 multiply  2.3E-999     1e-4  -> 2E-1003     Underflow Subnormal Inexact Rounded
+mulx810 multiply  2.5E-999     1e-4  -> 2E-1003     Underflow Subnormal Inexact Rounded
+mulx811 multiply  2.7E-999     1e-4  -> 3E-1003     Underflow Subnormal Inexact Rounded
+mulx812 multiply  1.49E-999    1e-4  -> 1E-1003     Underflow Subnormal Inexact Rounded
+mulx813 multiply  1.50E-999    1e-4  -> 2E-1003     Underflow Subnormal Inexact Rounded
+mulx814 multiply  1.51E-999    1e-4  -> 2E-1003     Underflow Subnormal Inexact Rounded
+mulx815 multiply  2.49E-999    1e-4  -> 2E-1003     Underflow Subnormal Inexact Rounded
+mulx816 multiply  2.50E-999    1e-4  -> 2E-1003     Underflow Subnormal Inexact Rounded
+mulx817 multiply  2.51E-999    1e-4  -> 3E-1003     Underflow Subnormal Inexact Rounded
+
+mulx818 multiply  1E-999       1e-4  -> 1E-1003     Subnormal
+mulx819 multiply  3E-999       1e-5  -> 0E-1003     Underflow Subnormal Inexact Rounded
+mulx820 multiply  5E-999       1e-5  -> 0E-1003     Underflow Subnormal Inexact Rounded
+mulx821 multiply  7E-999       1e-5  -> 1E-1003     Underflow Subnormal Inexact Rounded
+mulx822 multiply  9E-999       1e-5  -> 1E-1003     Underflow Subnormal Inexact Rounded
+mulx823 multiply  9.9E-999     1e-5  -> 1E-1003     Underflow Subnormal Inexact Rounded
+
+mulx824 multiply  1E-999      -1e-4  -> -1E-1003    Subnormal
+mulx825 multiply  3E-999      -1e-5  -> -0E-1003    Underflow Subnormal Inexact Rounded
+mulx826 multiply -5E-999       1e-5  -> -0E-1003    Underflow Subnormal Inexact Rounded
+mulx827 multiply  7E-999      -1e-5  -> -1E-1003    Underflow Subnormal Inexact Rounded
+mulx828 multiply -9E-999       1e-5  -> -1E-1003    Underflow Subnormal Inexact Rounded
+mulx829 multiply  9.9E-999    -1e-5  -> -1E-1003    Underflow Subnormal Inexact Rounded
+mulx830 multiply  3.0E-999    -1e-5  -> -0E-1003    Underflow Subnormal Inexact Rounded
+
+mulx831 multiply  1.0E-501     1e-501 -> 1.0E-1002   Subnormal
+mulx832 multiply  2.0E-501     2e-501 -> 4.0E-1002   Subnormal
+mulx833 multiply  4.0E-501     4e-501 -> 1.60E-1001  Subnormal
+mulx834 multiply 10.0E-501    10e-501 -> 1.000E-1000 Subnormal
+mulx835 multiply 30.0E-501    30e-501 -> 9.000E-1000 Subnormal
+mulx836 multiply 40.0E-501    40e-501 -> 1.6000E-999
+
+-- squares
+mulx840 multiply  1E-502       1e-502 -> 0E-1003     Underflow Subnormal Inexact Rounded
+mulx841 multiply  1E-501       1e-501 -> 1E-1002     Subnormal
+mulx842 multiply  2E-501       2e-501 -> 4E-1002     Subnormal
+mulx843 multiply  4E-501       4e-501 -> 1.6E-1001   Subnormal
+mulx844 multiply 10E-501      10e-501 -> 1.00E-1000  Subnormal
+mulx845 multiply 30E-501      30e-501 -> 9.00E-1000  Subnormal
+mulx846 multiply 40E-501      40e-501 -> 1.600E-999
+
+-- cubes
+mulx850 multiply  1E-670     1e-335 -> 0E-1003    Underflow Subnormal Inexact Rounded
+mulx851 multiply  1E-668     1e-334 -> 1E-1002    Subnormal
+mulx852 multiply  4E-668     2e-334 -> 8E-1002    Subnormal
+mulx853 multiply  9E-668     3e-334 -> 2.7E-1001  Subnormal
+mulx854 multiply 16E-668     4e-334 -> 6.4E-1001  Subnormal
+mulx855 multiply 25E-668     5e-334 -> 1.25E-1000 Subnormal
+mulx856 multiply 10E-668   100e-334 -> 1.000E-999
+
+-- test from 0.099 ** 999 at 15 digits
+precision: 19
+mulx860 multiply  6636851557994578716E-520 6636851557994578716E-520 -> 4.40477986028551E-1003 Underflow Subnormal Inexact Rounded
+
+-- Long operand overflow may be a different path
+precision: 3
+maxExponent: 999999999
+minexponent: -999999999
+mulx870 multiply 1  9.999E+999999999   ->  Infinity Inexact Overflow Rounded
+mulx871 multiply 1 -9.999E+999999999   -> -Infinity Inexact Overflow Rounded
+mulx872 multiply    9.999E+999999999 1 ->  Infinity Inexact Overflow Rounded
+mulx873 multiply   -9.999E+999999999 1 -> -Infinity Inexact Overflow Rounded
+
+-- check for double-rounded subnormals
+precision:   5
+maxexponent: 79
+minexponent: -79
+mulx881 multiply  1.2347E-40  1.2347E-40  ->  1.524E-80 Inexact Rounded Subnormal Underflow
+mulx882 multiply  1.234E-40  1.234E-40  ->  1.523E-80 Inexact Rounded Subnormal Underflow
+mulx883 multiply  1.23E-40   1.23E-40   ->  1.513E-80 Inexact Rounded Subnormal Underflow
+mulx884 multiply  1.2E-40    1.2E-40    ->  1.44E-80  Subnormal
+mulx885 multiply  1.2E-40    1.2E-41    ->  1.44E-81  Subnormal
+mulx886 multiply  1.2E-40    1.2E-42    ->  1.4E-82   Subnormal Inexact Rounded Underflow
+mulx887 multiply  1.2E-40    1.3E-42    ->  1.6E-82   Subnormal Inexact Rounded Underflow
+mulx888 multiply  1.3E-40    1.3E-42    ->  1.7E-82   Subnormal Inexact Rounded Underflow
+
+mulx891 multiply  1.2345E-39   1.234E-40  ->  1.5234E-79 Inexact Rounded
+mulx892 multiply  1.23456E-39  1.234E-40  ->  1.5234E-79 Inexact Rounded
+mulx893 multiply  1.2345E-40   1.234E-40  ->  1.523E-80  Inexact Rounded Subnormal Underflow
+mulx894 multiply  1.23456E-40  1.234E-40  ->  1.523E-80  Inexact Rounded Subnormal Underflow
+mulx895 multiply  1.2345E-41   1.234E-40  ->  1.52E-81   Inexact Rounded Subnormal Underflow
+mulx896 multiply  1.23456E-41  1.234E-40  ->  1.52E-81   Inexact Rounded Subnormal Underflow
+
+-- Null tests
+mulx900 multiply 10  # -> NaN Invalid_operation
+mulx901 multiply  # 10 -> NaN Invalid_operation
+

Added: vendor/Python/current/Lib/test/decimaltestdata/normalize.decTest
===================================================================
--- vendor/Python/current/Lib/test/decimaltestdata/normalize.decTest	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/decimaltestdata/normalize.decTest	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,225 @@
+------------------------------------------------------------------------
+-- normalize.decTest -- remove trailing zeros                         --
+-- Copyright (c) IBM Corporation, 2003.  All rights reserved.         --
+------------------------------------------------------------------------
+-- Please see the document "General Decimal Arithmetic Testcases"     --
+-- at http://www2.hursley.ibm.com/decimal for the description of      --
+-- these testcases.                                                   --
+--                                                                    --
+-- These testcases are experimental ('beta' versions), and they       --
+-- may contain errors.  They are offered on an as-is basis.  In       --
+-- particular, achieving the same results as the tests here is not    --
+-- a guarantee that an implementation complies with any Standard      --
+-- or specification.  The tests are not exhaustive.                   --
+--                                                                    --
+-- Please send comments, suggestions, and corrections to the author:  --
+--   Mike Cowlishaw, IBM Fellow                                       --
+--   IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK         --
+--   mfc at uk.ibm.com                                                   --
+------------------------------------------------------------------------
+version: 2.39
+
+extended:    1
+precision:   9
+rounding:    half_up
+maxExponent: 999
+minexponent: -999
+
+nrmx001 normalize '1'      -> '1'
+nrmx002 normalize '-1'     -> '-1'
+nrmx003 normalize '1.00'   -> '1'
+nrmx004 normalize '-1.00'  -> '-1'
+nrmx005 normalize '0'      -> '0'
+nrmx006 normalize '0.00'   -> '0'
+nrmx007 normalize '00.0'   -> '0'
+nrmx008 normalize '00.00'  -> '0'
+nrmx009 normalize '00'     -> '0'
+nrmx010 normalize '0E+1'   -> '0'
+nrmx011 normalize '0E+5'   -> '0'
+
+nrmx012 normalize '-2'     -> '-2'
+nrmx013 normalize '2'      -> '2'
+nrmx014 normalize '-2.00'  -> '-2'
+nrmx015 normalize '2.00'   -> '2'
+nrmx016 normalize '-0'     -> '-0'
+nrmx017 normalize '-0.00'  -> '-0'
+nrmx018 normalize '-00.0'  -> '-0'
+nrmx019 normalize '-00.00' -> '-0'
+nrmx020 normalize '-00'    -> '-0'
+nrmx021 normalize '-0E+5'   -> '-0'
+nrmx022 normalize '-0E+1'  -> '-0'
+
+nrmx030 normalize '+0.1'            -> '0.1'
+nrmx031 normalize '-0.1'            -> '-0.1'
+nrmx032 normalize '+0.01'           -> '0.01'
+nrmx033 normalize '-0.01'           -> '-0.01'
+nrmx034 normalize '+0.001'          -> '0.001'
+nrmx035 normalize '-0.001'          -> '-0.001'
+nrmx036 normalize '+0.000001'       -> '0.000001'
+nrmx037 normalize '-0.000001'       -> '-0.000001'
+nrmx038 normalize '+0.000000000001' -> '1E-12'
+nrmx039 normalize '-0.000000000001' -> '-1E-12'
+
+nrmx041 normalize 1.1        -> 1.1
+nrmx042 normalize 1.10       -> 1.1
+nrmx043 normalize 1.100      -> 1.1
+nrmx044 normalize 1.110      -> 1.11
+nrmx045 normalize -1.1       -> -1.1
+nrmx046 normalize -1.10      -> -1.1
+nrmx047 normalize -1.100     -> -1.1
+nrmx048 normalize -1.110     -> -1.11
+nrmx049 normalize 9.9        -> 9.9
+nrmx050 normalize 9.90       -> 9.9
+nrmx051 normalize 9.900      -> 9.9
+nrmx052 normalize 9.990      -> 9.99
+nrmx053 normalize -9.9       -> -9.9
+nrmx054 normalize -9.90      -> -9.9
+nrmx055 normalize -9.900     -> -9.9
+nrmx056 normalize -9.990     -> -9.99
+
+-- some trailing fractional zeros with zeros in units
+nrmx060 normalize  10.0        -> 1E+1
+nrmx061 normalize  10.00       -> 1E+1
+nrmx062 normalize  100.0       -> 1E+2
+nrmx063 normalize  100.00      -> 1E+2
+nrmx064 normalize  1.1000E+3   -> 1.1E+3
+nrmx065 normalize  1.10000E+3  -> 1.1E+3
+nrmx066 normalize -10.0        -> -1E+1
+nrmx067 normalize -10.00       -> -1E+1
+nrmx068 normalize -100.0       -> -1E+2
+nrmx069 normalize -100.00      -> -1E+2
+nrmx070 normalize -1.1000E+3   -> -1.1E+3
+nrmx071 normalize -1.10000E+3  -> -1.1E+3
+
+-- some insignificant trailing zeros with positive exponent
+nrmx080 normalize  10E+1       -> 1E+2
+nrmx081 normalize  100E+1      -> 1E+3
+nrmx082 normalize  1.0E+2      -> 1E+2
+nrmx083 normalize  1.0E+3      -> 1E+3
+nrmx084 normalize  1.1E+3      -> 1.1E+3
+nrmx085 normalize  1.00E+3     -> 1E+3
+nrmx086 normalize  1.10E+3     -> 1.1E+3
+nrmx087 normalize -10E+1       -> -1E+2
+nrmx088 normalize -100E+1      -> -1E+3
+nrmx089 normalize -1.0E+2      -> -1E+2
+nrmx090 normalize -1.0E+3      -> -1E+3
+nrmx091 normalize -1.1E+3      -> -1.1E+3
+nrmx092 normalize -1.00E+3     -> -1E+3
+nrmx093 normalize -1.10E+3     -> -1.1E+3
+
+-- some significant trailing zeros, were we to be trimming
+nrmx100 normalize  11          -> 11
+nrmx101 normalize  10          -> 1E+1
+nrmx102 normalize  10.         -> 1E+1
+nrmx103 normalize  1.1E+1      -> 11
+nrmx104 normalize  1.0E+1      -> 1E+1
+nrmx105 normalize  1.10E+2     -> 1.1E+2
+nrmx106 normalize  1.00E+2     -> 1E+2
+nrmx107 normalize  1.100E+3    -> 1.1E+3
+nrmx108 normalize  1.000E+3    -> 1E+3
+nrmx109 normalize  1.000000E+6 -> 1E+6
+nrmx110 normalize -11          -> -11
+nrmx111 normalize -10          -> -1E+1
+nrmx112 normalize -10.         -> -1E+1
+nrmx113 normalize -1.1E+1      -> -11
+nrmx114 normalize -1.0E+1      -> -1E+1
+nrmx115 normalize -1.10E+2     -> -1.1E+2
+nrmx116 normalize -1.00E+2     -> -1E+2
+nrmx117 normalize -1.100E+3    -> -1.1E+3
+nrmx118 normalize -1.000E+3    -> -1E+3
+nrmx119 normalize -1.00000E+5  -> -1E+5
+nrmx120 normalize -1.000000E+6 -> -1E+6
+nrmx121 normalize -10.00000E+6 -> -1E+7
+nrmx122 normalize -100.0000E+6 -> -1E+8
+nrmx123 normalize -1000.000E+6 -> -1E+9
+nrmx124 normalize -10000.00E+6 -> -1E+10
+nrmx125 normalize -100000.0E+6 -> -1E+11
+nrmx126 normalize -1000000.E+6 -> -1E+12
+
+-- examples from decArith
+nrmx140 normalize '2.1'     ->  '2.1'
+nrmx141 normalize '-2.0'    ->  '-2'
+nrmx142 normalize '1.200'   ->  '1.2'
+nrmx143 normalize '-120'    ->  '-1.2E+2'
+nrmx144 normalize '120.00'  ->  '1.2E+2'
+nrmx145 normalize '0.00'    ->  '0'
+
+-- overflow tests
+maxexponent: 999999999
+minexponent: -999999999
+precision: 3
+nrmx160 normalize 9.999E+999999999  ->  Infinity Inexact Overflow Rounded
+nrmx161 normalize -9.999E+999999999 -> -Infinity Inexact Overflow Rounded
+
+-- subnormals and underflow
+precision: 3
+maxexponent: 999
+minexponent: -999
+nrmx210 normalize  1.00E-999        ->   1E-999
+nrmx211 normalize  0.1E-999         ->   1E-1000   Subnormal
+nrmx212 normalize  0.10E-999        ->   1E-1000   Subnormal
+nrmx213 normalize  0.100E-999       ->   1E-1000   Subnormal Rounded
+nrmx214 normalize  0.01E-999        ->   1E-1001   Subnormal
+-- next is rounded to Emin
+nrmx215 normalize  0.999E-999       ->   1E-999    Inexact Rounded Subnormal Underflow
+nrmx216 normalize  0.099E-999       ->   1E-1000   Inexact Rounded Subnormal Underflow
+nrmx217 normalize  0.009E-999       ->   1E-1001   Inexact Rounded Subnormal Underflow
+nrmx218 normalize  0.001E-999       ->   0         Inexact Rounded Subnormal Underflow
+nrmx219 normalize  0.0009E-999      ->   0         Inexact Rounded Subnormal Underflow
+nrmx220 normalize  0.0001E-999      ->   0         Inexact Rounded Subnormal Underflow
+
+nrmx230 normalize -1.00E-999        ->  -1E-999
+nrmx231 normalize -0.1E-999         ->  -1E-1000   Subnormal
+nrmx232 normalize -0.10E-999        ->  -1E-1000   Subnormal
+nrmx233 normalize -0.100E-999       ->  -1E-1000   Subnormal Rounded
+nrmx234 normalize -0.01E-999        ->  -1E-1001   Subnormal
+-- next is rounded to Emin
+nrmx235 normalize -0.999E-999       ->  -1E-999    Inexact Rounded Subnormal Underflow
+nrmx236 normalize -0.099E-999       ->  -1E-1000   Inexact Rounded Subnormal Underflow
+nrmx237 normalize -0.009E-999       ->  -1E-1001   Inexact Rounded Subnormal Underflow
+nrmx238 normalize -0.001E-999       ->  -0         Inexact Rounded Subnormal Underflow
+nrmx239 normalize -0.0009E-999      ->  -0         Inexact Rounded Subnormal Underflow
+nrmx240 normalize -0.0001E-999      ->  -0         Inexact Rounded Subnormal Underflow
+
+-- more reshaping
+precision: 9
+nrmx260 normalize '56260E-10'   -> '0.000005626'
+nrmx261 normalize '56260E-5'    -> '0.5626'
+nrmx262 normalize '56260E-2'    -> '562.6'
+nrmx263 normalize '56260E-1'    -> '5626'
+nrmx265 normalize '56260E-0'    -> '5.626E+4'
+nrmx266 normalize '56260E+0'    -> '5.626E+4'
+nrmx267 normalize '56260E+1'    -> '5.626E+5'
+nrmx268 normalize '56260E+2'    -> '5.626E+6'
+nrmx269 normalize '56260E+3'    -> '5.626E+7'
+nrmx270 normalize '56260E+4'    -> '5.626E+8'
+nrmx271 normalize '56260E+5'    -> '5.626E+9'
+nrmx272 normalize '56260E+6'    -> '5.626E+10'
+nrmx280 normalize '-56260E-10'  -> '-0.000005626'
+nrmx281 normalize '-56260E-5'   -> '-0.5626'
+nrmx282 normalize '-56260E-2'   -> '-562.6'
+nrmx283 normalize '-56260E-1'   -> '-5626'
+nrmx285 normalize '-56260E-0'   -> '-5.626E+4'
+nrmx286 normalize '-56260E+0'   -> '-5.626E+4'
+nrmx287 normalize '-56260E+1'   -> '-5.626E+5'
+nrmx288 normalize '-56260E+2'   -> '-5.626E+6'
+nrmx289 normalize '-56260E+3'   -> '-5.626E+7'
+nrmx290 normalize '-56260E+4'   -> '-5.626E+8'
+nrmx291 normalize '-56260E+5'   -> '-5.626E+9'
+nrmx292 normalize '-56260E+6'   -> '-5.626E+10'
+
+
+-- specials
+nrmx820 normalize 'Inf'    -> 'Infinity'
+nrmx821 normalize '-Inf'   -> '-Infinity'
+nrmx822 normalize   NaN    ->  NaN
+nrmx823 normalize  sNaN    ->  NaN    Invalid_operation
+nrmx824 normalize   NaN101 ->  NaN101
+nrmx825 normalize  sNaN010 ->  NaN10  Invalid_operation
+nrmx827 normalize  -NaN    -> -NaN
+nrmx828 normalize -sNaN    -> -NaN    Invalid_operation
+nrmx829 normalize  -NaN101 -> -NaN101
+nrmx830 normalize -sNaN010 -> -NaN10  Invalid_operation
+
+-- Null test
+nrmx900 normalize  # -> NaN Invalid_operation

Added: vendor/Python/current/Lib/test/decimaltestdata/plus.decTest
===================================================================
--- vendor/Python/current/Lib/test/decimaltestdata/plus.decTest	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/decimaltestdata/plus.decTest	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,181 @@
+------------------------------------------------------------------------
+-- plus.decTest -- decimal monadic addition                           --
+-- Copyright (c) IBM Corporation, 1981, 2004.  All rights reserved.   --
+------------------------------------------------------------------------
+-- Please see the document "General Decimal Arithmetic Testcases"     --
+-- at http://www2.hursley.ibm.com/decimal for the description of      --
+-- these testcases.                                                   --
+--                                                                    --
+-- These testcases are experimental ('beta' versions), and they       --
+-- may contain errors.  They are offered on an as-is basis.  In       --
+-- particular, achieving the same results as the tests here is not    --
+-- a guarantee that an implementation complies with any Standard      --
+-- or specification.  The tests are not exhaustive.                   --
+--                                                                    --
+-- Please send comments, suggestions, and corrections to the author:  --
+--   Mike Cowlishaw, IBM Fellow                                       --
+--   IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK         --
+--   mfc at uk.ibm.com                                                   --
+------------------------------------------------------------------------
+version: 2.39
+
+-- This set of tests primarily tests the existence of the operator.
+-- Addition and rounding, and most overflows, are tested elsewhere.
+
+extended:    1
+precision:   9
+rounding:    half_up
+maxExponent: 384
+minexponent: -383
+
+plux001 plus '1'      -> '1'
+plux002 plus '-1'     -> '-1'
+plux003 plus '1.00'   -> '1.00'
+plux004 plus '-1.00'  -> '-1.00'
+plux005 plus '0'      -> '0'
+plux006 plus '0.00'   -> '0.00'
+plux007 plus '00.0'   -> '0.0'
+plux008 plus '00.00'  -> '0.00'
+plux009 plus '00'     -> '0'
+
+plux010 plus '-2'     -> '-2'
+plux011 plus '2'      -> '2'
+plux012 plus '-2.00'  -> '-2.00'
+plux013 plus '2.00'   -> '2.00'
+plux014 plus '-0'     -> '0'
+plux015 plus '-0.00'  -> '0.00'
+plux016 plus '-00.0'  -> '0.0'
+plux017 plus '-00.00' -> '0.00'
+plux018 plus '-00'    -> '0'
+
+plux020 plus '-2000000' -> '-2000000'
+plux021 plus '2000000'  -> '2000000'
+precision: 7
+plux022 plus '-2000000' -> '-2000000'
+plux023 plus '2000000'  -> '2000000'
+precision: 6
+plux024 plus '-2000000' -> '-2.00000E+6' Rounded
+plux025 plus '2000000'  -> '2.00000E+6' Rounded
+precision: 3
+plux026 plus '-2000000' -> '-2.00E+6' Rounded
+plux027 plus '2000000'  -> '2.00E+6' Rounded
+
+-- more fixed, potential LHS swaps if done by add 0
+precision: 9
+plux060 plus '56267E-10'   -> '0.0000056267'
+plux061 plus '56267E-5'    -> '0.56267'
+plux062 plus '56267E-2'    -> '562.67'
+plux063 plus '56267E-1'    -> '5626.7'
+plux065 plus '56267E-0'    -> '56267'
+plux066 plus '56267E+0'    -> '56267'
+plux067 plus '56267E+1'    -> '5.6267E+5'
+plux068 plus '56267E+2'    -> '5.6267E+6'
+plux069 plus '56267E+3'    -> '5.6267E+7'
+plux070 plus '56267E+4'    -> '5.6267E+8'
+plux071 plus '56267E+5'    -> '5.6267E+9'
+plux072 plus '56267E+6'    -> '5.6267E+10'
+plux080 plus '-56267E-10'  -> '-0.0000056267'
+plux081 plus '-56267E-5'   -> '-0.56267'
+plux082 plus '-56267E-2'   -> '-562.67'
+plux083 plus '-56267E-1'   -> '-5626.7'
+plux085 plus '-56267E-0'   -> '-56267'
+plux086 plus '-56267E+0'   -> '-56267'
+plux087 plus '-56267E+1'   -> '-5.6267E+5'
+plux088 plus '-56267E+2'   -> '-5.6267E+6'
+plux089 plus '-56267E+3'   -> '-5.6267E+7'
+plux090 plus '-56267E+4'   -> '-5.6267E+8'
+plux091 plus '-56267E+5'   -> '-5.6267E+9'
+plux092 plus '-56267E+6'   -> '-5.6267E+10'
+
+-- "lhs" zeros in plus and minus have exponent = operand
+plux120 plus '-0E3'   -> '0E+3'
+plux121 plus '-0E2'   -> '0E+2'
+plux122 plus '-0E1'   -> '0E+1'
+plux123 plus '-0E0'   -> '0'
+plux124 plus '+0E0'   -> '0'
+plux125 plus '+0E1'   -> '0E+1'
+plux126 plus '+0E2'   -> '0E+2'
+plux127 plus '+0E3'   -> '0E+3'
+
+plux130 plus '-5E3'   -> '-5E+3'
+plux131 plus '-5E8'   -> '-5E+8'
+plux132 plus '-5E13'  -> '-5E+13'
+plux133 plus '-5E18'  -> '-5E+18'
+plux134 plus '+5E3'   -> '5E+3'
+plux135 plus '+5E8'   -> '5E+8'
+plux136 plus '+5E13'  -> '5E+13'
+plux137 plus '+5E18'  -> '5E+18'
+
+-- specials
+plux150 plus 'Inf'    -> 'Infinity'
+plux151 plus '-Inf'   -> '-Infinity'
+plux152 plus   NaN    ->  NaN
+plux153 plus  sNaN    ->  NaN   Invalid_operation
+plux154 plus   NaN77  ->  NaN77
+plux155 plus  sNaN88  ->  NaN88 Invalid_operation
+plux156 plus  -NaN    -> -NaN
+plux157 plus -sNaN    -> -NaN   Invalid_operation
+plux158 plus  -NaN77  -> -NaN77
+plux159 plus -sNaN88  -> -NaN88 Invalid_operation
+
+-- overflow tests
+maxexponent: 999999999
+minexponent: -999999999
+precision: 3
+plux160 plus 9.999E+999999999  ->  Infinity Inexact Overflow Rounded
+plux161 plus -9.999E+999999999 -> -Infinity Inexact Overflow Rounded
+
+-- subnormals and underflow
+precision: 3
+maxexponent: 999
+minexponent: -999
+plux210 plus  1.00E-999        ->   1.00E-999
+plux211 plus  0.1E-999         ->   1E-1000   Subnormal
+plux212 plus  0.10E-999        ->   1.0E-1000 Subnormal
+plux213 plus  0.100E-999       ->   1.0E-1000 Subnormal Rounded
+plux214 plus  0.01E-999        ->   1E-1001   Subnormal
+-- next is rounded to Emin
+plux215 plus  0.999E-999       ->   1.00E-999 Inexact Rounded Subnormal Underflow
+plux216 plus  0.099E-999       ->   1.0E-1000 Inexact Rounded Subnormal Underflow
+plux217 plus  0.009E-999       ->   1E-1001   Inexact Rounded Subnormal Underflow
+plux218 plus  0.001E-999       ->   0E-1001   Inexact Rounded Subnormal Underflow
+plux219 plus  0.0009E-999      ->   0E-1001   Inexact Rounded Subnormal Underflow
+plux220 plus  0.0001E-999      ->   0E-1001   Inexact Rounded Subnormal Underflow
+
+plux230 plus -1.00E-999        ->  -1.00E-999
+plux231 plus -0.1E-999         ->  -1E-1000   Subnormal
+plux232 plus -0.10E-999        ->  -1.0E-1000 Subnormal
+plux233 plus -0.100E-999       ->  -1.0E-1000 Subnormal Rounded
+plux234 plus -0.01E-999        ->  -1E-1001   Subnormal
+-- next is rounded to Emin
+plux235 plus -0.999E-999       ->  -1.00E-999 Inexact Rounded Subnormal Underflow
+plux236 plus -0.099E-999       ->  -1.0E-1000 Inexact Rounded Subnormal Underflow
+plux237 plus -0.009E-999       ->  -1E-1001   Inexact Rounded Subnormal Underflow
+plux238 plus -0.001E-999       ->  -0E-1001   Inexact Rounded Subnormal Underflow
+plux239 plus -0.0009E-999      ->  -0E-1001   Inexact Rounded Subnormal Underflow
+plux240 plus -0.0001E-999      ->  -0E-1001   Inexact Rounded Subnormal Underflow
+
+-- long operand checks
+maxexponent: 999
+minexponent: -999
+precision: 9
+plux301 plus 12345678000  -> 1.23456780E+10 Rounded
+plux302 plus 1234567800   -> 1.23456780E+9 Rounded
+plux303 plus 1234567890   -> 1.23456789E+9 Rounded
+plux304 plus 1234567891   -> 1.23456789E+9 Inexact Rounded
+plux305 plus 12345678901  -> 1.23456789E+10 Inexact Rounded
+plux306 plus 1234567896   -> 1.23456790E+9 Inexact Rounded
+
+-- still checking
+precision: 15
+plux321 plus 12345678000  -> 12345678000
+plux322 plus 1234567800   -> 1234567800
+plux323 plus 1234567890   -> 1234567890
+plux324 plus 1234567891   -> 1234567891
+plux325 plus 12345678901  -> 12345678901
+plux326 plus 1234567896   -> 1234567896
+precision: 9
+
+-- Null tests
+plu900 plus  # -> NaN Invalid_operation
+

Added: vendor/Python/current/Lib/test/decimaltestdata/power.decTest
===================================================================
--- vendor/Python/current/Lib/test/decimaltestdata/power.decTest	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/decimaltestdata/power.decTest	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,651 @@
+----------------------------------------------------------------------
+-- power.decTest -- decimal exponentiation                            --
+-- Copyright (c) IBM Corporation, 1981, 2003.  All rights reserved.   --
+------------------------------------------------------------------------
+-- Please see the document "General Decimal Arithmetic Testcases"     --
+-- at http://www2.hursley.ibm.com/decimal for the description of      --
+-- these testcases.                                                   --
+--                                                                    --
+-- These testcases are experimental ('beta' versions), and they       --
+-- may contain errors.  They are offered on an as-is basis.  In       --
+-- particular, achieving the same results as the tests here is not    --
+-- a guarantee that an implementation complies with any Standard      --
+-- or specification.  The tests are not exhaustive.                   --
+--                                                                    --
+-- Please send comments, suggestions, and corrections to the author:  --
+--   Mike Cowlishaw, IBM Fellow                                       --
+--   IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK         --
+--   mfc at uk.ibm.com                                                   --
+------------------------------------------------------------------------
+version: 2.39
+
+-- This set of testcases tests raising numbers to an integer power only.
+-- If arbitrary powers were supported, 1 ulp differences would be
+-- permitted.
+
+extended:    1
+precision:   9
+rounding:    half_up
+maxExponent: 999
+minexponent: -999
+
+-- base checks.  Note 0**0 is an error.
+powx001 power    '0'  '0'         -> NaN Invalid_operation
+powx002 power    '0'  '1'         -> '0'
+powx003 power    '0'  '2'         -> '0'
+powx004 power    '1'  '0'         -> '1'
+powx005 power    '1'  '1'         -> '1'
+powx006 power    '1'  '2'         -> '1'
+
+powx010 power    '2'  '0'         -> '1'
+powx011 power    '2'  '1'         -> '2'
+powx012 power    '2'  '2'         -> '4'
+powx013 power    '2'  '3'         -> '8'
+powx014 power    '2'  '4'         -> '16'
+powx015 power    '2'  '5'         -> '32'
+powx016 power    '2'  '6'         -> '64'
+powx017 power    '2'  '7'         -> '128'
+powx018 power    '2'  '8'         -> '256'
+powx019 power    '2'  '9'         -> '512'
+powx020 power    '2'  '10'        -> '1024'
+powx021 power    '2'  '11'        -> '2048'
+powx022 power    '2'  '12'        -> '4096'
+powx023 power    '2'  '15'        -> '32768'
+powx024 power    '2'  '16'        -> '65536'
+powx025 power    '2'  '31'        -> '2.14748365E+9' Inexact Rounded
+-- NB 0 not stripped in next
+powx026 power    '2'  '32'        -> '4.29496730E+9' Inexact Rounded
+precision: 10
+powx027 power    '2'  '31'        -> '2147483648'
+powx028 power    '2'  '32'        -> '4294967296'
+precision: 9
+
+powx030 power    '3'  '2'         -> 9
+powx031 power    '4'  '2'         -> 16
+powx032 power    '5'  '2'         -> 25
+powx033 power    '6'  '2'         -> 36
+powx034 power    '7'  '2'         -> 49
+powx035 power    '8'  '2'         -> 64
+powx036 power    '9'  '2'         -> 81
+powx037 power    '10' '2'         -> 100
+powx038 power    '11' '2'         -> 121
+powx039 power    '12' '2'         -> 144
+
+powx040 power    '3'  '3'         -> 27
+powx041 power    '4'  '3'         -> 64
+powx042 power    '5'  '3'         -> 125
+powx043 power    '6'  '3'         -> 216
+powx044 power    '7'  '3'         -> 343
+
+powx050 power   '10'  '0'         -> 1
+powx051 power   '10'  '1'         -> 10
+powx052 power   '10'  '2'         -> 100
+powx053 power   '10'  '3'         -> 1000
+powx054 power   '10'  '4'         -> 10000
+powx055 power   '10'  '5'         -> 100000
+powx056 power   '10'  '6'         -> 1000000
+powx057 power   '10'  '7'         -> 10000000
+powx058 power   '10'  '8'         -> 100000000
+powx059 power   '10'  '9'         -> 1.00000000E+9 Rounded
+powx060 power   '10'  '22'        -> 1.00000000E+22 Rounded
+powx061 power   '10'  '77'        -> 1.00000000E+77 Rounded
+powx062 power   '10'  '99'        -> 1.00000000E+99 Rounded
+
+maxexponent: 999999999
+minexponent: -999999999
+powx063 power   '10'  '999999999' -> '1.00000000E+999999999' Rounded
+powx064 power   '10'  '999999998' -> '1.00000000E+999999998' Rounded
+powx065 power   '10'  '999999997' -> '1.00000000E+999999997' Rounded
+powx066 power   '10'  '333333333' -> '1.00000000E+333333333' Rounded
+
+powx070 power  '0.3'  '0'           -> '1'
+powx071 power  '0.3'  '1'           -> '0.3'
+powx072 power  '0.3'  '1.00'        -> '0.3'
+powx073 power  '0.3'  '2.00'        -> '0.09'
+powx074 power  '0.3'  '2.000000000' -> '0.09'
+powx075 power  '6.0'  '1'           -> '6.0'     -- NB zeros not stripped
+powx076 power  '6.0'  '2'           -> '36.00'   -- ..
+powx077 power   '-3'  '2'           -> '9'       -- from NetRexx book
+powx078 power    '4'  '3'           -> '64'      -- .. (sort of)
+
+powx080 power   0.1    0            -> 1
+powx081 power   0.1    1            -> 0.1
+powx082 power   0.1    2            -> 0.01
+powx083 power   0.1    3            -> 0.001
+powx084 power   0.1    4            -> 0.0001
+powx085 power   0.1    5            -> 0.00001
+powx086 power   0.1    6            -> 0.000001
+powx087 power   0.1    7            -> 1E-7
+powx088 power   0.1    8            -> 1E-8
+powx089 power   0.1    9            -> 1E-9
+
+powx090 power   101    2            -> 10201
+powx091 power   101    3            -> 1030301
+powx092 power   101    4            -> 104060401
+powx093 power   101    5            -> 1.05101005E+10 Inexact Rounded
+powx094 power   101    6            -> 1.06152015E+12 Inexact Rounded
+powx095 power   101    7            -> 1.07213535E+14 Inexact Rounded
+
+-- negative powers
+powx101 power  '2'  '-1'  -> 0.5
+powx102 power  '2'  '-2'  -> 0.25
+powx103 power  '2'  '-4'  -> 0.0625
+powx104 power  '2'  '-8'  -> 0.00390625
+powx105 power  '2'  '-16' -> 0.0000152587891 Inexact Rounded
+powx106 power  '2'  '-32' -> 2.32830644E-10 Inexact Rounded
+powx108 power  '2'  '-64' -> 5.42101086E-20 Inexact Rounded
+powx110 power  '10'  '-8' -> 1E-8
+powx111 power  '10'  '-7' -> 1E-7
+powx112 power  '10'  '-6' -> 0.000001
+powx113 power  '10'  '-5' -> 0.00001
+powx114 power  '10'  '-4' -> 0.0001
+powx115 power  '10'  '-3' -> 0.001
+powx116 power  '10'  '-2' -> 0.01
+powx117 power  '10'  '-1' -> 0.1
+
+powx118 power  '10'  '-333333333'   -> 1E-333333333
+powx119 power  '10'  '-999999998'   -> 1E-999999998
+powx120 power  '10'  '-999999999'   -> 1E-999999999
+powx121 power  '10'  '-77'          -> '1E-77'
+powx122 power  '10'  '-22'          -> '1E-22'
+
+powx123 power   '2'  '-1'           -> '0.5'
+powx124 power   '2'  '-2'           -> '0.25'
+powx125 power   '2'  '-4'           -> '0.0625'
+powx126 power   '0'  '-1'           -> Infinity Division_by_zero
+powx127 power   '0'  '-2'           -> Infinity Division_by_zero
+powx128 power   -0   '-1'           -> -Infinity Division_by_zero
+powx129 power   -0   '-2'           -> Infinity Division_by_zero
+
+-- out-of-range edge cases
+powx181 power   '7'   '999999998'   -> 2.10892313E+845098038 Inexact Rounded
+powx182 power   '7'   '999999999'   -> 1.47624619E+845098039 Inexact Rounded
+powx183 power   '7'   '1000000000'  -> NaN Invalid_operation
+powx184 power   '7'   '1000000001'  -> NaN Invalid_operation
+powx185 power   '7'   '10000000000' -> NaN Invalid_operation
+powx186 power   '7'   '-1000000001' -> NaN Invalid_operation
+powx187 power   '7'   '-1000000000' -> NaN Invalid_operation
+powx189 power   '7'   '-999999999'  -> 6.77393787E-845098040 Inexact Rounded
+powx190 power   '7'   '-999999998'  -> 4.74175651E-845098039 Inexact Rounded
+
+-- some baddies [more below]
+powx191 power   '2'   '2.000001'     -> NaN Invalid_operation
+powx192 power   '2'   '2.00000000'   -> 4
+powx193 power   '2'   '2.000000001'  -> NaN Invalid_operation
+powx194 power   '2'   '2.0000000001' -> NaN Invalid_operation
+
+-- "0.5" tests from original Rexx diagnostics [loop unrolled]
+powx200 power   0.5    0            -> 1
+powx201 power   0.5    1            -> 0.5
+powx202 power   0.5    2            -> 0.25
+powx203 power   0.5    3            -> 0.125
+powx204 power   0.5    4            -> 0.0625
+powx205 power   0.5    5            -> 0.03125
+powx206 power   0.5    6            -> 0.015625
+powx207 power   0.5    7            -> 0.0078125
+powx208 power   0.5    8            -> 0.00390625
+powx209 power   0.5    9            -> 0.001953125
+powx210 power   0.5   10            -> 0.0009765625
+
+-- A (rare) case where the last digit is not within 0.5 ULP
+precision: 9
+powx215 power "-21971575.0E+31454441" "-7" -> "-4.04549503E-220181139" Inexact Rounded
+precision: 20
+powx216 power "-21971575.0E+31454441" "-7" -> "-4.0454950249324891788E-220181139" Inexact Rounded
+
+-- The Vienna case.  Checks both setup and 1/acc working precision
+-- Modified 1998.12.14 as RHS no longer rounded before use (must fit)
+-- Modified 1990.02.04 as LHS is now rounded (instead of truncated to guard)
+--    '123456789E+10'    -- lhs .. rounded to 1.23E+18
+--    '-1.23000e+2'      -- rhs .. [was: -1.23455e+2, rounds to -123]
+-- Modified 2002.10.06 -- finally, no input rounding
+-- With input rounding, result would be 8.74E-2226
+precision: 3
+powx219 power '123456789E+10' '-1.23000e+2' -> '5.54E-2226' Inexact Rounded
+
+-- whole number checks
+precision: 9
+powx221 power 1 1234 -> 1
+precision: 4
+powx222 power 1 1234 -> 1
+precision: 3
+powx223 power 1 1234     -> 1
+powx224 power 1 12.34e+2 -> 1
+powx225 power 1 12.3     -> NaN Invalid_operation
+powx226 power 1 12.0     -> 1
+powx227 power 1 1.01     -> NaN Invalid_operation
+powx228 power 2 1.00     -> 2
+powx229 power 2 2.00     -> 4
+precision: 9
+powx230 power 1 1.0001           -> NaN Invalid_operation
+powx231 power 1 1.0000001        -> NaN Invalid_operation
+powx232 power 1 1.0000000001     -> NaN Invalid_operation
+powx233 power 1 1.0000000000001  -> NaN Invalid_operation
+precision: 5
+powx234 power 1 1.0001           -> NaN Invalid_operation
+powx235 power 1 1.0000001        -> NaN Invalid_operation
+powx236 power 1 1.0000000001     -> NaN Invalid_operation
+powx237 power 1 1.0000000000001  -> NaN Invalid_operation
+powx238 power 1 1.0000000000001  -> NaN Invalid_operation
+
+maxexponent: 999999999
+minexponent: -999999999
+powx239 power 1 5.67E-987654321  -> NaN Invalid_operation
+
+powx240 power 1  100000000 -> 1
+powx241 power 1  999999998 -> 1
+powx242 power 1  999999999 -> 1
+powx243 power 1 1000000000 -> NaN Invalid_operation
+powx244 power 1 9999999999 -> NaN Invalid_operation
+
+-- Checks for 'Too much precision needed'
+-- For x^12, digits+elength+1 = digits+3
+precision: 999999999
+powx249 add 1 1 -> 2   -- check basic operation at this precision
+powx250 power          2 12  -> Infinity Overflow
+precision: 999999998
+powx251 power          2 12  -> Infinity Overflow
+precision: 999999997
+powx252 power          2 12  -> Infinity Overflow
+precision: 999999996
+powx253 power          2 12  -> 4096
+precision: 999999995
+powx254 power          2 12  -> 4096
+
+-- zeros
+maxexponent: +96
+minexponent: -95
+precision: 7
+powx260 power          0E-34 3  ->  0E-101 Clamped
+powx261 power          0E-33 3  ->  0E-99
+powx262 power          0E-32 3  ->  0E-96
+powx263 power          0E-30 3  ->  0E-90
+powx264 power          0E-10 3  ->  0E-30
+powx265 power          0E-1  3  ->  0.000
+powx266 power          0E+0  3  ->  0
+powx267 power          0     3  ->  0
+powx268 power          0E+1  3  ->  0E+3
+powx269 power          0E+10 3  ->  0E+30
+powx270 power          0E+30 3  ->  0E+90
+powx271 power          0E+32 3  ->  0E+96
+powx272 power          0E+33 3  ->  0E+96  Clamped
+
+-- overflow and underflow tests
+maxexponent: 999999999
+minexponent: -999999999
+precision: 9
+powx280 power  9            999999999 -> 3.05550054E+954242508 Inexact Rounded
+powx281 power 10            999999999 -> 1.00000000E+999999999 Rounded
+powx282 power 10.0001       999999999 -> Infinity Overflow Inexact Rounded
+powx283 power 10.1          999999999 -> Infinity Overflow Inexact Rounded
+powx284 power 11            999999999 -> Infinity Overflow Inexact Rounded
+powx285 power 12            999999999 -> Infinity Overflow Inexact Rounded
+powx286 power 999           999999999 -> Infinity Overflow Inexact Rounded
+powx287 power 999999        999999999 -> Infinity Overflow Inexact Rounded
+powx288 power 999999999     999999999 -> Infinity Overflow Inexact Rounded
+powx289 power 9.9E999999999 999999999 -> Infinity Overflow Inexact Rounded
+
+powx290 power 0.5           999999999 -> 4.33559594E-301029996 Inexact Rounded
+powx291 power 0.1           999999999 -> 1E-999999999  -- unrounded
+powx292 power 0.09          999999999 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+powx293 power 0.05          999999999 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+powx294 power 0.01          999999999 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+powx295 power 0.0001        999999999 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+powx297 power 0.0000001     999999999 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+powx298 power 0.0000000001  999999999 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+powx299 power 1E-999999999  999999999 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+
+powx310 power -9             999999999 -> -3.05550054E+954242508 Inexact Rounded
+powx311 power -10            999999999 -> -1.00000000E+999999999 Rounded
+powx312 power -10.0001       999999999 -> -Infinity Overflow Inexact Rounded
+powx313 power -10.1          999999999 -> -Infinity Overflow Inexact Rounded
+powx314 power -11            999999999 -> -Infinity Overflow Inexact Rounded
+powx315 power -12            999999999 -> -Infinity Overflow Inexact Rounded
+powx316 power -999           999999999 -> -Infinity Overflow Inexact Rounded
+powx317 power -999999        999999999 -> -Infinity Overflow Inexact Rounded
+powx318 power -999999999     999999999 -> -Infinity Overflow Inexact Rounded
+powx319 power -9.9E999999999 999999999 -> -Infinity Overflow Inexact Rounded
+
+powx320 power -0.5           999999999 -> -4.33559594E-301029996 Inexact Rounded
+powx321 power -0.1           999999999 -> -1E-999999999
+powx322 power -0.09          999999999 -> -0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+powx323 power -0.05          999999999 -> -0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+powx324 power -0.01          999999999 -> -0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+powx325 power -0.0001        999999999 -> -0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+powx327 power -0.0000001     999999999 -> -0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+powx328 power -0.0000000001  999999999 -> -0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+powx329 power -1E-999999999  999999999 -> -0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+
+-- note no trim of next result
+powx330 power -9             999999998 ->  3.39500060E+954242507 Inexact Rounded
+powx331 power -10            999999998 ->  1.00000000E+999999998 Rounded
+powx332 power -10.0001       999999998 ->  Infinity Overflow Inexact Rounded
+powx333 power -10.1          999999998 ->  Infinity Overflow Inexact Rounded
+powx334 power -11            999999998 ->  Infinity Overflow Inexact Rounded
+powx335 power -12            999999998 ->  Infinity Overflow Inexact Rounded
+powx336 power -999           999999998 ->  Infinity Overflow Inexact Rounded
+powx337 power -999999        999999998 ->  Infinity Overflow Inexact Rounded
+powx338 power -999999999     999999998 ->  Infinity Overflow Inexact Rounded
+powx339 power -9.9E999999999 999999998 ->  Infinity Overflow Inexact Rounded
+
+powx340 power -0.5           999999998 ->  8.67119187E-301029996 Inexact Rounded
+powx341 power -0.1           999999998 ->  1E-999999998  -- NB exact unrounded
+powx342 power -0.09          999999998 ->  0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+powx343 power -0.05          999999998 ->  0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+powx344 power -0.01          999999998 ->  0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+powx345 power -0.0001        999999998 ->  0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+powx347 power -0.0000001     999999998 ->  0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+powx348 power -0.0000000001  999999998 ->  0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+powx349 power -1E-999999999  999999998 ->  0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+
+-- some subnormals
+precision: 9
+-- [precision is 9, so smallest exponent is -1000000007
+powx350 power  1e-1          500000000 ->  1E-500000000
+powx351 power  1e-2          999999999 ->  0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+powx352 power  1e-2          500000000 ->  1E-1000000000 Subnormal
+powx353 power  1e-2          500000001 ->  1E-1000000002 Subnormal
+powx354 power  1e-2          500000002 ->  1E-1000000004 Subnormal
+powx355 power  1e-2          500000003 ->  1E-1000000006 Subnormal
+powx356 power  1e-2          500000004 ->  0E-1000000007 Underflow Subnormal Inexact Rounded
+
+powx360 power  0.010001      500000000 ->  4.34941988E-999978287 Inexact Rounded
+powx361 power  0.010000001   500000000 ->  5.18469257E-999999979 Inexact Rounded
+powx362 power  0.010000001   500000001 ->  5.18469309E-999999981 Inexact Rounded
+powx363 power  0.0100000009  500000000 ->  3.49342003E-999999981 Inexact Rounded
+powx364 power  0.0100000001  500000000 ->  1.48413155E-999999998 Inexact Rounded
+powx365 power  0.01          500000000 ->  1E-1000000000 Subnormal
+powx366 power  0.0099999999  500000000 ->  6.7379E-1000000003 Underflow Subnormal Inexact Rounded
+powx367 power  0.0099999998  500000000 ->  4.54E-1000000005 Underflow Subnormal Inexact Rounded
+powx368 power  0.0099999997  500000000 ->  3E-1000000007 Underflow Subnormal Inexact Rounded
+powx369 power  0.0099999996  500000000 ->  0E-1000000007 Underflow Subnormal Inexact Rounded
+powx370 power  0.009         500000000 ->  0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+
+-- 1/subnormal -> overflow
+powx371 power  1e-1         -500000000 ->  1E+500000000
+powx372 power  1e-2         -999999999 ->  Infinity Overflow Inexact Rounded
+powx373 power  1e-2         -500000000 ->  Infinity Overflow Inexact Rounded
+powx374 power  1e-2         -500000001 ->  Infinity Overflow Inexact Rounded
+powx375 power  1e-2         -500000002 ->  Infinity Overflow Inexact Rounded
+powx376 power  1e-2         -500000003 ->  Infinity Overflow Inexact Rounded
+powx377 power  1e-2         -500000004 ->  Infinity Overflow Inexact Rounded
+
+powx381 power  0.010001     -500000000 ->  2.29915719E+999978286 Inexact Rounded
+powx382 power  0.010000001  -500000000 ->  1.92875467E+999999978 Inexact Rounded
+powx383 power  0.010000001  -500000001 ->  1.92875448E+999999980 Inexact Rounded
+powx384 power  0.0100000009 -500000000 ->  2.86252438E+999999980 Inexact Rounded
+powx385 power  0.0100000001 -500000000 ->  6.73794717E+999999997 Inexact Rounded
+powx386 power  0.01         -500000000 ->  Infinity Overflow Inexact Rounded
+powx387 power  0.009999     -500000000 ->  Infinity Overflow Inexact Rounded
+
+-- negative power giving subnormal
+powx388 power  100.000001   -500000000 ->  6.7379E-1000000003 Underflow Subnormal Inexact Rounded
+
+-- some more edge cases
+precision:   15
+maxExponent: 999
+minexponent: -999
+powx391 power  0.1   999 -> 1E-999
+powx392 power  0.099 999 -> 4.360732062E-1004 Underflow Subnormal Inexact Rounded
+powx393 power  0.098 999 -> 1.71731E-1008 Underflow Subnormal Inexact Rounded
+powx394 power  0.097 999 -> 6E-1013 Underflow Subnormal Inexact Rounded
+powx395 power  0.096 999 -> 0E-1013 Underflow Subnormal Inexact Rounded
+powx396 power  0.01  999 -> 0E-1013 Underflow Subnormal Inexact Rounded Clamped
+
+-- multiply tests are here to aid checking and test for consistent handling
+-- of underflow
+precision: 5
+maxexponent: 999
+minexponent: -999
+
+-- squares
+mulx400 multiply  1E-502     1e-502 -> 0E-1003    Subnormal Inexact Underflow Rounded
+mulx401 multiply  1E-501     1e-501 -> 1E-1002    Subnormal
+mulx402 multiply  2E-501     2e-501 -> 4E-1002    Subnormal
+mulx403 multiply  4E-501     4e-501 -> 1.6E-1001  Subnormal
+mulx404 multiply 10E-501    10e-501 -> 1.00E-1000 Subnormal
+mulx405 multiply 30E-501    30e-501 -> 9.00E-1000 Subnormal
+mulx406 multiply 40E-501    40e-501 -> 1.600E-999
+
+powx400 power     1E-502     2      -> 0E-1003    Underflow Subnormal Inexact Rounded
+powx401 power     1E-501     2      -> 1E-1002    Subnormal
+powx402 power     2E-501     2      -> 4E-1002    Subnormal
+powx403 power     4E-501     2      -> 1.6E-1001  Subnormal
+powx404 power    10E-501     2      -> 1.00E-1000 Subnormal
+powx405 power    30E-501     2      -> 9.00E-1000 Subnormal
+powx406 power    40E-501     2      -> 1.600E-999
+
+-- cubes
+mulx410 multiply  1E-670     1e-335 -> 0E-1003    Underflow Subnormal Inexact Rounded
+mulx411 multiply  1E-668     1e-334 -> 1E-1002    Subnormal
+mulx412 multiply  4E-668     2e-334 -> 8E-1002    Subnormal
+mulx413 multiply  9E-668     3e-334 -> 2.7E-1001  Subnormal
+mulx414 multiply 16E-668     4e-334 -> 6.4E-1001  Subnormal
+mulx415 multiply 25E-668     5e-334 -> 1.25E-1000 Subnormal
+mulx416 multiply 10E-668   100e-334 -> 1.000E-999
+
+powx410 power     1E-335     3      -> 0E-1003    Underflow Subnormal Inexact Rounded
+powx411 power     1E-334     3      -> 1E-1002    Subnormal
+powx412 power     2E-334     3      -> 8E-1002    Subnormal
+powx413 power     3E-334     3      -> 2.7E-1001  Subnormal
+powx414 power     4E-334     3      -> 6.4E-1001  Subnormal
+powx415 power     5E-334     3      -> 1.25E-1000 Subnormal
+powx416 power    10E-334     3      -> 1.000E-999
+
+-- negative powers, testing subnormals
+precision:   5
+maxExponent: 999
+minexponent: -999
+powx421 power  2.5E-501     -2         ->  Infinity Overflow Inexact Rounded
+powx422 power  2.5E-500     -2         ->  1.6E+999
+
+powx423 power  2.5E+499     -2         ->  1.6E-999
+powx424 power  2.5E+500     -2         ->  1.6E-1001 Subnormal
+powx425 power  2.5E+501     -2         ->    2E-1003 Underflow Subnormal Inexact Rounded
+powx426 power  2.5E+502     -2         ->    0E-1003 Underflow Subnormal Inexact Rounded
+
+powx427 power 0.25E+499     -2         ->  1.6E-997
+powx428 power 0.25E+500     -2         ->  1.6E-999
+powx429 power 0.25E+501     -2         ->  1.6E-1001 Subnormal
+powx430 power 0.25E+502     -2         ->    2E-1003 Underflow Subnormal Inexact Rounded
+powx431 power 0.25E+503     -2         ->    0E-1003 Underflow Subnormal Inexact Rounded
+
+powx432 power 0.04E+499     -2         ->  6.25E-996
+powx433 power 0.04E+500     -2         ->  6.25E-998
+powx434 power 0.04E+501     -2         ->  6.25E-1000 Subnormal
+powx435 power 0.04E+502     -2         ->   6.3E-1002 Underflow Subnormal Inexact Rounded
+powx436 power 0.04E+503     -2         ->     1E-1003 Underflow Subnormal Inexact Rounded
+powx437 power 0.04E+504     -2         ->     0E-1003 Underflow Subnormal Inexact Rounded
+
+powx441 power 0.04E+334     -3         ->  1.5625E-998
+powx442 power 0.04E+335     -3         ->    1.56E-1001 Underflow Subnormal Inexact Rounded
+powx443 power 0.04E+336     -3         ->       0E-1003 Underflow Subnormal Inexact Rounded
+powx444 power 0.25E+333     -3         ->     6.4E-998
+powx445 power 0.25E+334     -3         ->     6.4E-1001 Subnormal
+powx446 power 0.25E+335     -3         ->       1E-1003 Underflow Subnormal Inexact Rounded
+powx447 power 0.25E+336     -3         ->       0E-1003 Underflow Subnormal Inexact Rounded Clamped
+-- check sign for cubes  and a few squares
+powx448 power -0.04E+334    -3         -> -1.5625E-998
+powx449 power -0.04E+335    -3         ->   -1.56E-1001 Underflow Subnormal Inexact Rounded
+powx450 power -0.04E+336    -3         ->      -0E-1003 Underflow Subnormal Inexact Rounded
+powx451 power -0.25E+333    -3         ->    -6.4E-998
+powx452 power -0.25E+334    -3         ->    -6.4E-1001 Subnormal
+powx453 power -0.25E+335    -3         ->      -1E-1003 Underflow Subnormal Inexact Rounded
+powx454 power -0.25E+336    -3         ->      -0E-1003 Underflow Subnormal Inexact Rounded Clamped
+powx455 power -0.04E+499    -2         ->    6.25E-996
+powx456 power -0.04E+500    -2         ->    6.25E-998
+powx457 power -0.04E+501    -2         ->    6.25E-1000 Subnormal
+powx458 power -0.04E+502    -2         ->     6.3E-1002 Underflow Subnormal Inexact Rounded
+
+-- test -0s
+precision: 9
+powx560 power  0  0        ->  NaN Invalid_operation
+powx561 power  0 -0        ->  NaN Invalid_operation
+powx562 power -0  0        ->  NaN Invalid_operation
+powx563 power -0 -0        ->  NaN Invalid_operation
+powx564 power  1  0        ->  1
+powx565 power  1 -0        ->  1
+powx566 power -1  0        ->  1
+powx567 power -1 -0        ->  1
+powx568 power  0  1        ->  0
+powx569 power  0 -1        ->  Infinity Division_by_zero
+powx570 power -0  1        -> -0
+powx571 power -0 -1        -> -Infinity Division_by_zero
+powx572 power  0  2        ->  0
+powx573 power  0 -2        ->  Infinity Division_by_zero
+powx574 power -0  2        ->  0
+powx575 power -0 -2        ->  Infinity Division_by_zero
+powx576 power  0  3        ->  0
+powx577 power  0 -3        ->  Infinity Division_by_zero
+powx578 power -0  3        -> -0
+powx579 power -0 -3        -> -Infinity Division_by_zero
+
+-- Specials
+powx580 power  Inf  -Inf   ->  NaN  Invalid_operation
+powx581 power  Inf  -1000  ->  0
+powx582 power  Inf  -1     ->  0
+powx583 power  Inf  -0     ->  1
+powx584 power  Inf   0     ->  1
+powx585 power  Inf   1     ->  Infinity
+powx586 power  Inf   1000  ->  Infinity
+powx587 power  Inf   Inf   ->  NaN  Invalid_operation
+powx588 power -1000  Inf   ->  NaN  Invalid_operation
+powx589 power -Inf   Inf   ->  NaN  Invalid_operation
+powx590 power -1     Inf   ->  NaN  Invalid_operation
+powx591 power -0     Inf   ->  NaN  Invalid_operation
+powx592 power  0     Inf   ->  NaN  Invalid_operation
+powx593 power  1     Inf   ->  NaN  Invalid_operation
+powx594 power  1000  Inf   ->  NaN  Invalid_operation
+powx595 power  Inf   Inf   ->  NaN  Invalid_operation
+
+powx600 power -Inf  -Inf   ->  NaN  Invalid_operation
+powx601 power -Inf  -1000  ->  0
+powx602 power -Inf  -1     -> -0
+powx603 power -Inf  -0     ->  1
+powx604 power -Inf   0     ->  1
+powx605 power -Inf   1     -> -Infinity
+powx606 power -Inf   1000  ->  Infinity
+powx607 power -Inf   Inf   ->  NaN  Invalid_operation
+powx608 power -1000  Inf   ->  NaN  Invalid_operation
+powx609 power -Inf  -Inf   ->  NaN  Invalid_operation
+powx610 power -1    -Inf   ->  NaN  Invalid_operation
+powx611 power -0    -Inf   ->  NaN  Invalid_operation
+powx612 power  0    -Inf   ->  NaN  Invalid_operation
+powx613 power  1    -Inf   ->  NaN  Invalid_operation
+powx614 power  1000 -Inf   ->  NaN  Invalid_operation
+powx615 power  Inf  -Inf   ->  NaN  Invalid_operation
+
+powx621 power  NaN -Inf    ->  NaN  Invalid_operation
+powx622 power  NaN -1000   ->  NaN
+powx623 power  NaN -1      ->  NaN
+powx624 power  NaN -0      ->  NaN
+powx625 power  NaN  0      ->  NaN
+powx626 power  NaN  1      ->  NaN
+powx627 power  NaN  1000   ->  NaN
+powx628 power  NaN  Inf    ->  NaN  Invalid_operation
+powx629 power  NaN  NaN    ->  NaN
+powx630 power -Inf  NaN    ->  NaN
+powx631 power -1000 NaN    ->  NaN
+powx632 power -1    NaN    ->  NaN
+powx633 power -0    NaN    ->  NaN
+powx634 power  0    NaN    ->  NaN
+powx635 power  1    NaN    ->  NaN
+powx636 power  1000 NaN    ->  NaN
+powx637 power  Inf  NaN    ->  NaN
+
+powx641 power  sNaN -Inf   ->  NaN  Invalid_operation
+powx642 power  sNaN -1000  ->  NaN  Invalid_operation
+powx643 power  sNaN -1     ->  NaN  Invalid_operation
+powx644 power  sNaN -0     ->  NaN  Invalid_operation
+powx645 power  sNaN  0     ->  NaN  Invalid_operation
+powx646 power  sNaN  1     ->  NaN  Invalid_operation
+powx647 power  sNaN  1000  ->  NaN  Invalid_operation
+powx648 power  sNaN  NaN   ->  NaN  Invalid_operation
+powx649 power  sNaN sNaN   ->  NaN  Invalid_operation
+powx650 power  NaN  sNaN   ->  NaN  Invalid_operation
+powx651 power -Inf  sNaN   ->  NaN  Invalid_operation
+powx652 power -1000 sNaN   ->  NaN  Invalid_operation
+powx653 power -1    sNaN   ->  NaN  Invalid_operation
+powx654 power -0    sNaN   ->  NaN  Invalid_operation
+powx655 power  0    sNaN   ->  NaN  Invalid_operation
+powx656 power  1    sNaN   ->  NaN  Invalid_operation
+powx657 power  1000 sNaN   ->  NaN  Invalid_operation
+powx658 power  Inf  sNaN   ->  NaN  Invalid_operation
+powx659 power  NaN  sNaN   ->  NaN  Invalid_operation
+
+-- NaN propagation
+powx660 power  NaN3  sNaN7  ->  NaN7  Invalid_operation
+powx661 power  sNaN8  NaN6  ->  NaN8  Invalid_operation
+powx662 power  1     sNaN7  ->  NaN7  Invalid_operation
+powx663 power  sNaN8  1     ->  NaN8  Invalid_operation
+powx664 power  Inf   sNaN7  ->  NaN7  Invalid_operation
+powx665 power  sNaN8  Inf   ->  NaN   Invalid_operation
+powx666 power  Inf    NaN9  ->  NaN9
+powx667 power  NaN6   Inf   ->  NaN   Invalid_operation
+powx668 power  1      NaN5  ->  NaN5
+powx669 power  NaN2   1     ->  NaN2
+powx670 power  NaN2   Nan4  ->  NaN2
+powx671 power  NaN    Nan4  ->  NaN
+powx672 power  NaN345 Nan   ->  NaN345
+powx673 power  Inf    -sNaN7 -> -NaN7 Invalid_operation
+powx674 power  -sNaN8  Inf   -> NaN   Invalid_operation
+powx675 power  Inf    -NaN9  -> -NaN9
+powx676 power  -NaN6   Inf   -> NaN   Invalid_operation
+powx677 power  -NaN2  -Nan4  -> -NaN2
+
+-- Examples from extended specification
+powx690 power  Inf  -2     ->  0
+powx691 power  Inf  -1     ->  0
+powx692 power  Inf   0     ->  1
+powx693 power  Inf   1     ->  Infinity
+powx694 power  Inf   2     ->  Infinity
+powx695 power -Inf  -2     ->  0
+powx696 power -Inf  -1     ->  -0
+powx697 power -Inf   0     ->  1
+powx698 power -Inf   1     ->  -Infinity
+powx699 power -Inf   2     ->  Infinity
+powx700 power    0   0     ->  NaN Invalid_operation
+
+-- long operand and RHS range checks
+maxexponent: 999
+minexponent: -999
+precision: 9
+powx701 power 12345678000 1 -> 1.23456780E+10 Rounded
+powx702 power 1234567800  1 -> 1.23456780E+9 Rounded
+powx703 power 1234567890  1 -> 1.23456789E+9 Rounded
+powx704 power 1234567891  1 -> 1.23456789E+9 Inexact Rounded
+powx705 power 12345678901 1 -> 1.23456789E+10 Inexact Rounded
+powx706 power 1234567896  1 -> 1.23456790E+9 Inexact Rounded
+powx707 power 1 12345678000  -> NaN Invalid_operation
+powx708 power 1 1234567800   -> NaN Invalid_operation
+powx709 power 1 1234567890   -> NaN Invalid_operation
+powx710 power 1 11234567891  -> NaN Invalid_operation
+powx711 power 1 12345678901  -> NaN Invalid_operation
+powx712 power 1 1234567896   -> NaN Invalid_operation
+powx713 power 1 -1234567896  -> NaN Invalid_operation
+powx714 power 1 1000000000   -> NaN Invalid_operation
+powx715 power 1 -1000000000  -> NaN Invalid_operation
+
+precision: 15
+-- still checking
+powx741 power 12345678000 1 -> 12345678000
+powx742 power 1234567800  1 -> 1234567800
+powx743 power 1234567890  1 -> 1234567890
+powx744 power 1234567891  1 -> 1234567891
+powx745 power 12345678901 1 -> 12345678901
+powx746 power 1234567896  1 -> 1234567896
+powx747 power 1 12345678000  -> NaN Invalid_operation
+powx748 power 1 -1234567896  -> NaN Invalid_operation
+powx749 power 1 1000000000   -> NaN Invalid_operation
+powx740 power 1 -1000000000  -> NaN Invalid_operation
+
+-- check for double-rounded subnormals
+precision:   5
+maxexponent: 79
+minexponent: -79
+powx750 power     1.2347E-40  2      ->  1.524E-80 Inexact Rounded Subnormal Underflow
+
+-- Null tests
+powx900 power  1 # -> NaN Invalid_operation
+powx901 power  # 1 -> NaN Invalid_operation
+

Added: vendor/Python/current/Lib/test/decimaltestdata/quantize.decTest
===================================================================
--- vendor/Python/current/Lib/test/decimaltestdata/quantize.decTest	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/decimaltestdata/quantize.decTest	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,780 @@
+------------------------------------------------------------------------
+-- quantize.decTest -- decimal quantize operation                     --
+-- Copyright (c) IBM Corporation, 1981, 2004.  All rights reserved.   --
+------------------------------------------------------------------------
+-- Please see the document "General Decimal Arithmetic Testcases"     --
+-- at http://www2.hursley.ibm.com/decimal for the description of      --
+-- these testcases.                                                   --
+--                                                                    --
+-- These testcases are experimental ('beta' versions), and they       --
+-- may contain errors.  They are offered on an as-is basis.  In       --
+-- particular, achieving the same results as the tests here is not    --
+-- a guarantee that an implementation complies with any Standard      --
+-- or specification.  The tests are not exhaustive.                   --
+--                                                                    --
+-- Please send comments, suggestions, and corrections to the author:  --
+--   Mike Cowlishaw, IBM Fellow                                       --
+--   IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK         --
+--   mfc at uk.ibm.com                                                   --
+------------------------------------------------------------------------
+version: 2.39
+
+-- Most of the tests here assume a "regular pattern", where the
+-- sign and coefficient are +1.
+-- 2004.03.15 Underflow for quantize is suppressed
+
+extended:    1
+precision:   9
+rounding:    half_up
+maxExponent: 999
+minexponent: -999
+
+-- sanity checks
+quax001 quantize 0       1e0   -> 0
+quax002 quantize 1       1e0   -> 1
+quax003 quantize 0.1    1e+2   -> 0E+2 Inexact Rounded
+quax005 quantize 0.1    1e+1   -> 0E+1 Inexact Rounded
+quax006 quantize 0.1     1e0   -> 0 Inexact Rounded
+quax007 quantize 0.1    1e-1   -> 0.1
+quax008 quantize 0.1    1e-2   -> 0.10
+quax009 quantize 0.1    1e-3   -> 0.100
+quax010 quantize 0.9    1e+2   -> 0E+2 Inexact Rounded
+quax011 quantize 0.9    1e+1   -> 0E+1 Inexact Rounded
+quax012 quantize 0.9    1e+0   -> 1 Inexact Rounded
+quax013 quantize 0.9    1e-1   -> 0.9
+quax014 quantize 0.9    1e-2   -> 0.90
+quax015 quantize 0.9    1e-3   -> 0.900
+-- negatives
+quax021 quantize -0      1e0   -> -0
+quax022 quantize -1      1e0   -> -1
+quax023 quantize -0.1   1e+2   -> -0E+2 Inexact Rounded
+quax025 quantize -0.1   1e+1   -> -0E+1 Inexact Rounded
+quax026 quantize -0.1    1e0   -> -0 Inexact Rounded
+quax027 quantize -0.1   1e-1   -> -0.1
+quax028 quantize -0.1   1e-2   -> -0.10
+quax029 quantize -0.1   1e-3   -> -0.100
+quax030 quantize -0.9   1e+2   -> -0E+2 Inexact Rounded
+quax031 quantize -0.9   1e+1   -> -0E+1 Inexact Rounded
+quax032 quantize -0.9   1e+0   -> -1 Inexact Rounded
+quax033 quantize -0.9   1e-1   -> -0.9
+quax034 quantize -0.9   1e-2   -> -0.90
+quax035 quantize -0.9   1e-3   -> -0.900
+quax036 quantize -0.5   1e+2   -> -0E+2 Inexact Rounded
+quax037 quantize -0.5   1e+1   -> -0E+1 Inexact Rounded
+quax038 quantize -0.5   1e+0   -> -1 Inexact Rounded
+quax039 quantize -0.5   1e-1   -> -0.5
+quax040 quantize -0.5   1e-2   -> -0.50
+quax041 quantize -0.5   1e-3   -> -0.500
+quax042 quantize -0.9   1e+2   -> -0E+2 Inexact Rounded
+quax043 quantize -0.9   1e+1   -> -0E+1 Inexact Rounded
+quax044 quantize -0.9   1e+0   -> -1 Inexact Rounded
+quax045 quantize -0.9   1e-1   -> -0.9
+quax046 quantize -0.9   1e-2   -> -0.90
+quax047 quantize -0.9   1e-3   -> -0.900
+
+-- examples from Specification
+quax060 quantize 2.17   0.001  -> 2.170
+quax061 quantize 2.17   0.01   -> 2.17
+quax062 quantize 2.17   0.1    -> 2.2 Inexact Rounded
+quax063 quantize 2.17   1e+0   -> 2 Inexact Rounded
+quax064 quantize 2.17   1e+1   -> 0E+1 Inexact Rounded
+quax065 quantize -Inf    Inf   -> -Infinity
+quax066 quantize 2       Inf   -> NaN Invalid_operation
+quax067 quantize -0.1    1     -> -0 Inexact Rounded
+quax068 quantize -0      1e+5     -> -0E+5
+quax069 quantize +35236450.6 1e-2 -> NaN Invalid_operation
+quax070 quantize -35236450.6 1e-2 -> NaN Invalid_operation
+quax071 quantize 217    1e-1   -> 217.0
+quax072 quantize 217    1e+0   -> 217
+quax073 quantize 217    1e+1   -> 2.2E+2 Inexact Rounded
+quax074 quantize 217    1e+2   -> 2E+2 Inexact Rounded
+
+-- general tests ..
+quax089 quantize 12     1e+4   -> 0E+4 Inexact Rounded
+quax090 quantize 12     1e+3   -> 0E+3 Inexact Rounded
+quax091 quantize 12     1e+2   -> 0E+2 Inexact Rounded
+quax092 quantize 12     1e+1   -> 1E+1 Inexact Rounded
+quax093 quantize 1.2345 1e-2   -> 1.23 Inexact Rounded
+quax094 quantize 1.2355 1e-2   -> 1.24 Inexact Rounded
+quax095 quantize 1.2345 1e-6   -> 1.234500
+quax096 quantize 9.9999 1e-2   -> 10.00 Inexact Rounded
+quax097 quantize 0.0001 1e-2   -> 0.00 Inexact Rounded
+quax098 quantize 0.001  1e-2   -> 0.00 Inexact Rounded
+quax099 quantize 0.009  1e-2   -> 0.01 Inexact Rounded
+quax100 quantize 92     1e+2   -> 1E+2 Inexact Rounded
+
+quax101 quantize -1      1e0   ->  -1
+quax102 quantize -1     1e-1   ->  -1.0
+quax103 quantize -1     1e-2   ->  -1.00
+quax104 quantize  0      1e0   ->  0
+quax105 quantize  0     1e-1   ->  0.0
+quax106 quantize  0     1e-2   ->  0.00
+quax107 quantize  0.00   1e0   ->  0
+quax108 quantize  0     1e+1   ->  0E+1
+quax109 quantize  0     1e+2   ->  0E+2
+quax110 quantize +1      1e0   ->  1
+quax111 quantize +1     1e-1   ->  1.0
+quax112 quantize +1     1e-2   ->  1.00
+
+quax120 quantize   1.04  1e-3 ->  1.040
+quax121 quantize   1.04  1e-2 ->  1.04
+quax122 quantize   1.04  1e-1 ->  1.0 Inexact Rounded
+quax123 quantize   1.04   1e0 ->  1 Inexact Rounded
+quax124 quantize   1.05  1e-3 ->  1.050
+quax125 quantize   1.05  1e-2 ->  1.05
+quax126 quantize   1.05  1e-1 ->  1.1 Inexact Rounded
+quax127 quantize   1.05   1e0 ->  1 Inexact Rounded
+quax128 quantize   1.05  1e-3 ->  1.050
+quax129 quantize   1.05  1e-2 ->  1.05
+quax130 quantize   1.05  1e-1 ->  1.1 Inexact Rounded
+quax131 quantize   1.05   1e0 ->  1 Inexact Rounded
+quax132 quantize   1.06  1e-3 ->  1.060
+quax133 quantize   1.06  1e-2 ->  1.06
+quax134 quantize   1.06  1e-1 ->  1.1 Inexact Rounded
+quax135 quantize   1.06   1e0 ->  1 Inexact Rounded
+
+quax140 quantize   -10    1e-2  ->  -10.00
+quax141 quantize   +1     1e-2  ->  1.00
+quax142 quantize   +10    1e-2  ->  10.00
+quax143 quantize   1E+10  1e-2  ->  NaN Invalid_operation
+quax144 quantize   1E-10  1e-2  ->  0.00 Inexact Rounded
+quax145 quantize   1E-3   1e-2  ->  0.00 Inexact Rounded
+quax146 quantize   1E-2   1e-2  ->  0.01
+quax147 quantize   1E-1   1e-2  ->  0.10
+quax148 quantize   0E-10  1e-2  ->  0.00
+
+quax150 quantize   1.0600 1e-5 ->  1.06000
+quax151 quantize   1.0600 1e-4 ->  1.0600
+quax152 quantize   1.0600 1e-3 ->  1.060 Rounded
+quax153 quantize   1.0600 1e-2 ->  1.06 Rounded
+quax154 quantize   1.0600 1e-1 ->  1.1 Inexact Rounded
+quax155 quantize   1.0600  1e0 ->  1 Inexact Rounded
+
+-- base tests with non-1 coefficients
+quax161 quantize 0      -9e0   -> 0
+quax162 quantize 1      -7e0   -> 1
+quax163 quantize 0.1   -1e+2   -> 0E+2 Inexact Rounded
+quax165 quantize 0.1    0e+1   -> 0E+1 Inexact Rounded
+quax166 quantize 0.1     2e0   -> 0 Inexact Rounded
+quax167 quantize 0.1    3e-1   -> 0.1
+quax168 quantize 0.1   44e-2   -> 0.10
+quax169 quantize 0.1  555e-3   -> 0.100
+quax170 quantize 0.9 6666e+2   -> 0E+2 Inexact Rounded
+quax171 quantize 0.9 -777e+1   -> 0E+1 Inexact Rounded
+quax172 quantize 0.9  -88e+0   -> 1 Inexact Rounded
+quax173 quantize 0.9   -9e-1   -> 0.9
+quax174 quantize 0.9    0e-2   -> 0.90
+quax175 quantize 0.9  1.1e-3   -> 0.9000
+-- negatives
+quax181 quantize -0    1.1e0   -> -0.0
+quax182 quantize -1     -1e0   -> -1
+quax183 quantize -0.1  11e+2   -> -0E+2 Inexact Rounded
+quax185 quantize -0.1 111e+1   -> -0E+1 Inexact Rounded
+quax186 quantize -0.1   71e0   -> -0 Inexact Rounded
+quax187 quantize -0.1 -91e-1   -> -0.1
+quax188 quantize -0.1 -.1e-2   -> -0.100
+quax189 quantize -0.1  -1e-3   -> -0.100
+quax190 quantize -0.9   0e+2   -> -0E+2 Inexact Rounded
+quax191 quantize -0.9  -0e+1   -> -0E+1 Inexact Rounded
+quax192 quantize -0.9 -10e+0   -> -1 Inexact Rounded
+quax193 quantize -0.9 100e-1   -> -0.9
+quax194 quantize -0.9 999e-2   -> -0.90
+
+-- +ve exponents ..
+quax201 quantize   -1   1e+0 ->  -1
+quax202 quantize   -1   1e+1 ->  -0E+1 Inexact Rounded
+quax203 quantize   -1   1e+2 ->  -0E+2 Inexact Rounded
+quax204 quantize    0   1e+0 ->  0
+quax205 quantize    0   1e+1 ->  0E+1
+quax206 quantize    0   1e+2 ->  0E+2
+quax207 quantize   +1   1e+0 ->  1
+quax208 quantize   +1   1e+1 ->  0E+1 Inexact Rounded
+quax209 quantize   +1   1e+2 ->  0E+2 Inexact Rounded
+
+quax220 quantize   1.04 1e+3 ->  0E+3 Inexact Rounded
+quax221 quantize   1.04 1e+2 ->  0E+2 Inexact Rounded
+quax222 quantize   1.04 1e+1 ->  0E+1 Inexact Rounded
+quax223 quantize   1.04 1e+0 ->  1 Inexact Rounded
+quax224 quantize   1.05 1e+3 ->  0E+3 Inexact Rounded
+quax225 quantize   1.05 1e+2 ->  0E+2 Inexact Rounded
+quax226 quantize   1.05 1e+1 ->  0E+1 Inexact Rounded
+quax227 quantize   1.05 1e+0 ->  1 Inexact Rounded
+quax228 quantize   1.05 1e+3 ->  0E+3 Inexact Rounded
+quax229 quantize   1.05 1e+2 ->  0E+2 Inexact Rounded
+quax230 quantize   1.05 1e+1 ->  0E+1 Inexact Rounded
+quax231 quantize   1.05 1e+0 ->  1 Inexact Rounded
+quax232 quantize   1.06 1e+3 ->  0E+3 Inexact Rounded
+quax233 quantize   1.06 1e+2 ->  0E+2 Inexact Rounded
+quax234 quantize   1.06 1e+1 ->  0E+1 Inexact Rounded
+quax235 quantize   1.06 1e+0 ->  1 Inexact Rounded
+
+quax240 quantize   -10   1e+1  ->  -1E+1 Rounded
+quax241 quantize   +1    1e+1  ->  0E+1 Inexact Rounded
+quax242 quantize   +10   1e+1  ->  1E+1 Rounded
+quax243 quantize   1E+1  1e+1  ->  1E+1          -- underneath this is E+1
+quax244 quantize   1E+2  1e+1  ->  1.0E+2        -- underneath this is E+1
+quax245 quantize   1E+3  1e+1  ->  1.00E+3       -- underneath this is E+1
+quax246 quantize   1E+4  1e+1  ->  1.000E+4      -- underneath this is E+1
+quax247 quantize   1E+5  1e+1  ->  1.0000E+5     -- underneath this is E+1
+quax248 quantize   1E+6  1e+1  ->  1.00000E+6    -- underneath this is E+1
+quax249 quantize   1E+7  1e+1  ->  1.000000E+7   -- underneath this is E+1
+quax250 quantize   1E+8  1e+1  ->  1.0000000E+8  -- underneath this is E+1
+quax251 quantize   1E+9  1e+1  ->  1.00000000E+9 -- underneath this is E+1
+-- next one tries to add 9 zeros
+quax252 quantize   1E+10 1e+1  ->  NaN Invalid_operation
+quax253 quantize   1E-10 1e+1  ->  0E+1 Inexact Rounded
+quax254 quantize   1E-2  1e+1  ->  0E+1 Inexact Rounded
+quax255 quantize   0E-10 1e+1  ->  0E+1
+quax256 quantize  -0E-10 1e+1  -> -0E+1
+quax257 quantize  -0E-1  1e+1  -> -0E+1
+quax258 quantize  -0     1e+1  -> -0E+1
+quax259 quantize  -0E+1  1e+1  -> -0E+1
+
+quax260 quantize   -10   1e+2  ->  -0E+2 Inexact Rounded
+quax261 quantize   +1    1e+2  ->  0E+2 Inexact Rounded
+quax262 quantize   +10   1e+2  ->  0E+2 Inexact Rounded
+quax263 quantize   1E+1  1e+2  ->  0E+2 Inexact Rounded
+quax264 quantize   1E+2  1e+2  ->  1E+2
+quax265 quantize   1E+3  1e+2  ->  1.0E+3
+quax266 quantize   1E+4  1e+2  ->  1.00E+4
+quax267 quantize   1E+5  1e+2  ->  1.000E+5
+quax268 quantize   1E+6  1e+2  ->  1.0000E+6
+quax269 quantize   1E+7  1e+2  ->  1.00000E+7
+quax270 quantize   1E+8  1e+2  ->  1.000000E+8
+quax271 quantize   1E+9  1e+2  ->  1.0000000E+9
+quax272 quantize   1E+10 1e+2  ->  1.00000000E+10
+quax273 quantize   1E-10 1e+2  ->  0E+2 Inexact Rounded
+quax274 quantize   1E-2  1e+2  ->  0E+2 Inexact Rounded
+quax275 quantize   0E-10 1e+2  ->  0E+2
+
+quax280 quantize   -10   1e+3  ->  -0E+3 Inexact Rounded
+quax281 quantize   +1    1e+3  ->  0E+3 Inexact Rounded
+quax282 quantize   +10   1e+3  ->  0E+3 Inexact Rounded
+quax283 quantize   1E+1  1e+3  ->  0E+3 Inexact Rounded
+quax284 quantize   1E+2  1e+3  ->  0E+3 Inexact Rounded
+quax285 quantize   1E+3  1e+3  ->  1E+3
+quax286 quantize   1E+4  1e+3  ->  1.0E+4
+quax287 quantize   1E+5  1e+3  ->  1.00E+5
+quax288 quantize   1E+6  1e+3  ->  1.000E+6
+quax289 quantize   1E+7  1e+3  ->  1.0000E+7
+quax290 quantize   1E+8  1e+3  ->  1.00000E+8
+quax291 quantize   1E+9  1e+3  ->  1.000000E+9
+quax292 quantize   1E+10 1e+3  ->  1.0000000E+10
+quax293 quantize   1E-10 1e+3  ->  0E+3 Inexact Rounded
+quax294 quantize   1E-2  1e+3  ->  0E+3 Inexact Rounded
+quax295 quantize   0E-10 1e+3  ->  0E+3
+
+-- round up from below [sign wrong in JIT compiler once]
+quax300 quantize   0.0078 1e-5 ->  0.00780
+quax301 quantize   0.0078 1e-4 ->  0.0078
+quax302 quantize   0.0078 1e-3 ->  0.008 Inexact Rounded
+quax303 quantize   0.0078 1e-2 ->  0.01 Inexact Rounded
+quax304 quantize   0.0078 1e-1 ->  0.0 Inexact Rounded
+quax305 quantize   0.0078  1e0 ->  0 Inexact Rounded
+quax306 quantize   0.0078 1e+1 ->  0E+1 Inexact Rounded
+quax307 quantize   0.0078 1e+2 ->  0E+2 Inexact Rounded
+
+quax310 quantize  -0.0078 1e-5 -> -0.00780
+quax311 quantize  -0.0078 1e-4 -> -0.0078
+quax312 quantize  -0.0078 1e-3 -> -0.008 Inexact Rounded
+quax313 quantize  -0.0078 1e-2 -> -0.01 Inexact Rounded
+quax314 quantize  -0.0078 1e-1 -> -0.0 Inexact Rounded
+quax315 quantize  -0.0078  1e0 -> -0 Inexact Rounded
+quax316 quantize  -0.0078 1e+1 -> -0E+1 Inexact Rounded
+quax317 quantize  -0.0078 1e+2 -> -0E+2 Inexact Rounded
+
+quax320 quantize   0.078 1e-5 ->  0.07800
+quax321 quantize   0.078 1e-4 ->  0.0780
+quax322 quantize   0.078 1e-3 ->  0.078
+quax323 quantize   0.078 1e-2 ->  0.08 Inexact Rounded
+quax324 quantize   0.078 1e-1 ->  0.1 Inexact Rounded
+quax325 quantize   0.078  1e0 ->  0 Inexact Rounded
+quax326 quantize   0.078 1e+1 ->  0E+1 Inexact Rounded
+quax327 quantize   0.078 1e+2 ->  0E+2 Inexact Rounded
+
+quax330 quantize  -0.078 1e-5 -> -0.07800
+quax331 quantize  -0.078 1e-4 -> -0.0780
+quax332 quantize  -0.078 1e-3 -> -0.078
+quax333 quantize  -0.078 1e-2 -> -0.08 Inexact Rounded
+quax334 quantize  -0.078 1e-1 -> -0.1 Inexact Rounded
+quax335 quantize  -0.078  1e0 -> -0 Inexact Rounded
+quax336 quantize  -0.078 1e+1 -> -0E+1 Inexact Rounded
+quax337 quantize  -0.078 1e+2 -> -0E+2 Inexact Rounded
+
+quax340 quantize   0.78 1e-5 ->  0.78000
+quax341 quantize   0.78 1e-4 ->  0.7800
+quax342 quantize   0.78 1e-3 ->  0.780
+quax343 quantize   0.78 1e-2 ->  0.78
+quax344 quantize   0.78 1e-1 ->  0.8 Inexact Rounded
+quax345 quantize   0.78  1e0 ->  1 Inexact Rounded
+quax346 quantize   0.78 1e+1 ->  0E+1 Inexact Rounded
+quax347 quantize   0.78 1e+2 ->  0E+2 Inexact Rounded
+
+quax350 quantize  -0.78 1e-5 -> -0.78000
+quax351 quantize  -0.78 1e-4 -> -0.7800
+quax352 quantize  -0.78 1e-3 -> -0.780
+quax353 quantize  -0.78 1e-2 -> -0.78
+quax354 quantize  -0.78 1e-1 -> -0.8 Inexact Rounded
+quax355 quantize  -0.78  1e0 -> -1 Inexact Rounded
+quax356 quantize  -0.78 1e+1 -> -0E+1 Inexact Rounded
+quax357 quantize  -0.78 1e+2 -> -0E+2 Inexact Rounded
+
+quax360 quantize   7.8 1e-5 ->  7.80000
+quax361 quantize   7.8 1e-4 ->  7.8000
+quax362 quantize   7.8 1e-3 ->  7.800
+quax363 quantize   7.8 1e-2 ->  7.80
+quax364 quantize   7.8 1e-1 ->  7.8
+quax365 quantize   7.8  1e0 ->  8 Inexact Rounded
+quax366 quantize   7.8 1e+1 ->  1E+1 Inexact Rounded
+quax367 quantize   7.8 1e+2 ->  0E+2 Inexact Rounded
+quax368 quantize   7.8 1e+3 ->  0E+3 Inexact Rounded
+
+quax370 quantize  -7.8 1e-5 -> -7.80000
+quax371 quantize  -7.8 1e-4 -> -7.8000
+quax372 quantize  -7.8 1e-3 -> -7.800
+quax373 quantize  -7.8 1e-2 -> -7.80
+quax374 quantize  -7.8 1e-1 -> -7.8
+quax375 quantize  -7.8  1e0 -> -8 Inexact Rounded
+quax376 quantize  -7.8 1e+1 -> -1E+1 Inexact Rounded
+quax377 quantize  -7.8 1e+2 -> -0E+2 Inexact Rounded
+quax378 quantize  -7.8 1e+3 -> -0E+3 Inexact Rounded
+
+-- some individuals
+precision: 9
+quax380 quantize   352364.506 1e-2 -> 352364.51 Inexact Rounded
+quax381 quantize   3523645.06 1e-2 -> 3523645.06
+quax382 quantize   35236450.6 1e-2 -> NaN Invalid_operation
+quax383 quantize   352364506  1e-2 -> NaN Invalid_operation
+quax384 quantize  -352364.506 1e-2 -> -352364.51 Inexact Rounded
+quax385 quantize  -3523645.06 1e-2 -> -3523645.06
+quax386 quantize  -35236450.6 1e-2 -> NaN Invalid_operation
+quax387 quantize  -352364506  1e-2 -> NaN Invalid_operation
+
+rounding: down
+quax389 quantize   35236450.6 1e-2 -> NaN Invalid_operation
+-- ? should that one instead have been:
+-- quax389 quantize   35236450.6 1e-2 -> NaN Invalid_operation
+rounding: half_up
+
+-- and a few more from e-mail discussions
+precision: 7
+quax391 quantize  12.34567  1e-3 -> 12.346   Inexact Rounded
+quax392 quantize  123.4567  1e-3 -> 123.457  Inexact Rounded
+quax393 quantize  1234.567  1e-3 -> 1234.567
+quax394 quantize  12345.67  1e-3 -> NaN Invalid_operation
+quax395 quantize  123456.7  1e-3 -> NaN Invalid_operation
+quax396 quantize  1234567.  1e-3 -> NaN Invalid_operation
+
+-- some 9999 round-up cases
+precision: 9
+quax400 quantize   9.999        1e-5  ->  9.99900
+quax401 quantize   9.999        1e-4  ->  9.9990
+quax402 quantize   9.999        1e-3  ->  9.999
+quax403 quantize   9.999        1e-2  -> 10.00     Inexact Rounded
+quax404 quantize   9.999        1e-1  -> 10.0      Inexact Rounded
+quax405 quantize   9.999         1e0  -> 10        Inexact Rounded
+quax406 quantize   9.999         1e1  -> 1E+1      Inexact Rounded
+quax407 quantize   9.999         1e2  -> 0E+2      Inexact Rounded
+
+quax410 quantize   0.999        1e-5  ->  0.99900
+quax411 quantize   0.999        1e-4  ->  0.9990
+quax412 quantize   0.999        1e-3  ->  0.999
+quax413 quantize   0.999        1e-2  ->  1.00     Inexact Rounded
+quax414 quantize   0.999        1e-1  ->  1.0      Inexact Rounded
+quax415 quantize   0.999         1e0  ->  1        Inexact Rounded
+quax416 quantize   0.999         1e1  -> 0E+1      Inexact Rounded
+
+quax420 quantize   0.0999       1e-5  ->  0.09990
+quax421 quantize   0.0999       1e-4  ->  0.0999
+quax422 quantize   0.0999       1e-3  ->  0.100    Inexact Rounded
+quax423 quantize   0.0999       1e-2  ->  0.10     Inexact Rounded
+quax424 quantize   0.0999       1e-1  ->  0.1      Inexact Rounded
+quax425 quantize   0.0999        1e0  ->  0        Inexact Rounded
+quax426 quantize   0.0999        1e1  -> 0E+1      Inexact Rounded
+
+quax430 quantize   0.00999      1e-5  ->  0.00999
+quax431 quantize   0.00999      1e-4  ->  0.0100   Inexact Rounded
+quax432 quantize   0.00999      1e-3  ->  0.010    Inexact Rounded
+quax433 quantize   0.00999      1e-2  ->  0.01     Inexact Rounded
+quax434 quantize   0.00999      1e-1  ->  0.0      Inexact Rounded
+quax435 quantize   0.00999       1e0  ->  0        Inexact Rounded
+quax436 quantize   0.00999       1e1  -> 0E+1      Inexact Rounded
+
+quax440 quantize   0.000999     1e-5  ->  0.00100  Inexact Rounded
+quax441 quantize   0.000999     1e-4  ->  0.0010   Inexact Rounded
+quax442 quantize   0.000999     1e-3  ->  0.001    Inexact Rounded
+quax443 quantize   0.000999     1e-2  ->  0.00     Inexact Rounded
+quax444 quantize   0.000999     1e-1  ->  0.0      Inexact Rounded
+quax445 quantize   0.000999      1e0  ->  0        Inexact Rounded
+quax446 quantize   0.000999      1e1  -> 0E+1      Inexact Rounded
+
+precision: 8
+quax449 quantize   9.999E-15    1e-23 ->  NaN Invalid_operation
+quax450 quantize   9.999E-15    1e-22 ->  9.9990000E-15
+quax451 quantize   9.999E-15    1e-21 ->  9.999000E-15
+quax452 quantize   9.999E-15    1e-20 ->  9.99900E-15
+quax453 quantize   9.999E-15    1e-19 ->  9.9990E-15
+quax454 quantize   9.999E-15    1e-18 ->  9.999E-15
+quax455 quantize   9.999E-15    1e-17 ->  1.000E-14 Inexact Rounded
+quax456 quantize   9.999E-15    1e-16 ->  1.00E-14  Inexact Rounded
+quax457 quantize   9.999E-15    1e-15 ->  1.0E-14   Inexact Rounded
+quax458 quantize   9.999E-15    1e-14 ->  1E-14     Inexact Rounded
+quax459 quantize   9.999E-15    1e-13 ->  0E-13     Inexact Rounded
+quax460 quantize   9.999E-15    1e-12 ->  0E-12     Inexact Rounded
+quax461 quantize   9.999E-15    1e-11 ->  0E-11     Inexact Rounded
+quax462 quantize   9.999E-15    1e-10 ->  0E-10     Inexact Rounded
+quax463 quantize   9.999E-15     1e-9 ->  0E-9      Inexact Rounded
+quax464 quantize   9.999E-15     1e-8 ->  0E-8      Inexact Rounded
+quax465 quantize   9.999E-15     1e-7 ->  0E-7      Inexact Rounded
+quax466 quantize   9.999E-15     1e-6 ->  0.000000  Inexact Rounded
+quax467 quantize   9.999E-15     1e-5 ->  0.00000   Inexact Rounded
+quax468 quantize   9.999E-15     1e-4 ->  0.0000    Inexact Rounded
+quax469 quantize   9.999E-15     1e-3 ->  0.000     Inexact Rounded
+quax470 quantize   9.999E-15     1e-2 ->  0.00      Inexact Rounded
+quax471 quantize   9.999E-15     1e-1 ->  0.0       Inexact Rounded
+quax472 quantize   9.999E-15      1e0 ->  0         Inexact Rounded
+quax473 quantize   9.999E-15      1e1 ->  0E+1      Inexact Rounded
+
+-- long operand checks [rhs checks removed]
+maxexponent: 999
+minexponent: -999
+precision: 9
+quax481 quantize 12345678000 1e+3 -> 1.2345678E+10 Rounded
+quax482 quantize 1234567800  1e+1 -> 1.23456780E+9 Rounded
+quax483 quantize 1234567890  1e+1 -> 1.23456789E+9 Rounded
+quax484 quantize 1234567891  1e+1 -> 1.23456789E+9 Inexact Rounded
+quax485 quantize 12345678901 1e+2 -> 1.23456789E+10 Inexact Rounded
+quax486 quantize 1234567896  1e+1 -> 1.23456790E+9 Inexact Rounded
+-- a potential double-round
+quax487 quantize 1234.987643 1e-4 -> 1234.9876 Inexact Rounded
+quax488 quantize 1234.987647 1e-4 -> 1234.9876 Inexact Rounded
+
+precision: 15
+quax491 quantize 12345678000 1e+3 -> 1.2345678E+10 Rounded
+quax492 quantize 1234567800  1e+1 -> 1.23456780E+9 Rounded
+quax493 quantize 1234567890  1e+1 -> 1.23456789E+9 Rounded
+quax494 quantize 1234567891  1e+1 -> 1.23456789E+9 Inexact Rounded
+quax495 quantize 12345678901 1e+2 -> 1.23456789E+10 Inexact Rounded
+quax496 quantize 1234567896  1e+1 -> 1.23456790E+9 Inexact Rounded
+quax497 quantize 1234.987643 1e-4 -> 1234.9876 Inexact Rounded
+quax498 quantize 1234.987647 1e-4 -> 1234.9876 Inexact Rounded
+
+-- Zeros
+quax500 quantize   0     1e1 ->  0E+1
+quax501 quantize   0     1e0 ->  0
+quax502 quantize   0    1e-1 ->  0.0
+quax503 quantize   0.0  1e-1 ->  0.0
+quax504 quantize   0.0   1e0 ->  0
+quax505 quantize   0.0  1e+1 ->  0E+1
+quax506 quantize   0E+1 1e-1 ->  0.0
+quax507 quantize   0E+1  1e0 ->  0
+quax508 quantize   0E+1 1e+1 ->  0E+1
+quax509 quantize  -0     1e1 -> -0E+1
+quax510 quantize  -0     1e0 -> -0
+quax511 quantize  -0    1e-1 -> -0.0
+quax512 quantize  -0.0  1e-1 -> -0.0
+quax513 quantize  -0.0   1e0 -> -0
+quax514 quantize  -0.0  1e+1 -> -0E+1
+quax515 quantize  -0E+1 1e-1 -> -0.0
+quax516 quantize  -0E+1  1e0 -> -0
+quax517 quantize  -0E+1 1e+1 -> -0E+1
+
+-- Suspicious RHS values
+maxexponent: 999999999
+minexponent: -999999999
+precision: 15
+quax520 quantize   1.234    1e999999000 -> 0E+999999000 Inexact Rounded
+quax521 quantize 123.456    1e999999000 -> 0E+999999000 Inexact Rounded
+quax522 quantize   1.234    1e999999999 -> 0E+999999999 Inexact Rounded
+quax523 quantize 123.456    1e999999999 -> 0E+999999999 Inexact Rounded
+quax524 quantize 123.456   1e1000000000 -> NaN Invalid_operation
+quax525 quantize 123.456  1e12345678903 -> NaN Invalid_operation
+-- next four are "won't fit" overflows
+quax526 quantize   1.234   1e-999999000 -> NaN Invalid_operation
+quax527 quantize 123.456   1e-999999000 -> NaN Invalid_operation
+quax528 quantize   1.234   1e-999999999 -> NaN Invalid_operation
+quax529 quantize 123.456   1e-999999999 -> NaN Invalid_operation
+quax530 quantize 123.456  1e-1000000014 -> NaN Invalid_operation
+quax531 quantize 123.456 1e-12345678903 -> NaN Invalid_operation
+
+maxexponent: 999
+minexponent: -999
+precision: 15
+quax532 quantize   1.234E+999    1e999 -> 1E+999    Inexact Rounded
+quax533 quantize   1.234E+998    1e999 -> 0E+999    Inexact Rounded
+quax534 quantize   1.234         1e999 -> 0E+999    Inexact Rounded
+quax535 quantize   1.234        1e1000 -> NaN Invalid_operation
+quax536 quantize   1.234        1e5000 -> NaN Invalid_operation
+quax537 quantize   0            1e-999 -> 0E-999
+-- next two are "won't fit" overflows
+quax538 quantize   1.234        1e-999 -> NaN Invalid_operation
+quax539 quantize   1.234       1e-1000 -> NaN Invalid_operation
+quax540 quantize   1.234       1e-5000 -> NaN Invalid_operation
+-- [more below]
+
+-- check bounds (lhs maybe out of range for destination, etc.)
+precision:     7
+quax541 quantize   1E+999   1e+999 -> 1E+999
+quax542 quantize   1E+1000  1e+999 -> NaN Invalid_operation
+quax543 quantize   1E+999  1e+1000 -> NaN Invalid_operation
+quax544 quantize   1E-999   1e-999 -> 1E-999
+quax545 quantize   1E-1000  1e-999 -> 0E-999    Inexact Rounded
+quax546 quantize   1E-999  1e-1000 -> 1.0E-999
+quax547 quantize   1E-1005  1e-999 -> 0E-999    Inexact Rounded
+quax548 quantize   1E-1006  1e-999 -> 0E-999    Inexact Rounded
+quax549 quantize   1E-1007  1e-999 -> 0E-999    Inexact Rounded
+quax550 quantize   1E-998  1e-1005 -> NaN Invalid_operation  -- won't fit
+quax551 quantize   1E-999  1e-1005 -> 1.000000E-999
+quax552 quantize   1E-1000 1e-1005 -> 1.00000E-1000 Subnormal
+quax553 quantize   1E-999  1e-1006 -> NaN Invalid_operation
+quax554 quantize   1E-999  1e-1007 -> NaN Invalid_operation
+-- related subnormal rounding
+quax555 quantize   1.666666E-999  1e-1005 -> 1.666666E-999
+quax556 quantize   1.666666E-1000 1e-1005 -> 1.66667E-1000  Subnormal Inexact Rounded
+quax557 quantize   1.666666E-1001 1e-1005 -> 1.6667E-1001  Subnormal Inexact Rounded
+quax558 quantize   1.666666E-1002 1e-1005 -> 1.667E-1002  Subnormal Inexact Rounded
+quax559 quantize   1.666666E-1003 1e-1005 -> 1.67E-1003  Subnormal Inexact Rounded
+quax560 quantize   1.666666E-1004 1e-1005 -> 1.7E-1004  Subnormal Inexact Rounded
+quax561 quantize   1.666666E-1005 1e-1005 -> 2E-1005  Subnormal Inexact Rounded
+quax562 quantize   1.666666E-1006 1e-1005 -> 0E-1005   Inexact Rounded
+quax563 quantize   1.666666E-1007 1e-1005 -> 0E-1005   Inexact Rounded
+
+-- Specials
+quax580 quantize  Inf    -Inf   ->  Infinity
+quax581 quantize  Inf  1e-1000  ->  NaN  Invalid_operation
+quax582 quantize  Inf  1e-1     ->  NaN  Invalid_operation
+quax583 quantize  Inf   1e0     ->  NaN  Invalid_operation
+quax584 quantize  Inf   1e1     ->  NaN  Invalid_operation
+quax585 quantize  Inf   1e1000  ->  NaN  Invalid_operation
+quax586 quantize  Inf     Inf   ->  Infinity
+quax587 quantize -1000    Inf   ->  NaN  Invalid_operation
+quax588 quantize -Inf     Inf   ->  -Infinity
+quax589 quantize -1       Inf   ->  NaN  Invalid_operation
+quax590 quantize  0       Inf   ->  NaN  Invalid_operation
+quax591 quantize  1       Inf   ->  NaN  Invalid_operation
+quax592 quantize  1000    Inf   ->  NaN  Invalid_operation
+quax593 quantize  Inf     Inf   ->  Infinity
+quax594 quantize  Inf  1e-0     ->  NaN  Invalid_operation
+quax595 quantize -0       Inf   ->  NaN  Invalid_operation
+
+quax600 quantize -Inf    -Inf   ->  -Infinity
+quax601 quantize -Inf  1e-1000  ->  NaN  Invalid_operation
+quax602 quantize -Inf  1e-1     ->  NaN  Invalid_operation
+quax603 quantize -Inf   1e0     ->  NaN  Invalid_operation
+quax604 quantize -Inf   1e1     ->  NaN  Invalid_operation
+quax605 quantize -Inf   1e1000  ->  NaN  Invalid_operation
+quax606 quantize -Inf     Inf   ->  -Infinity
+quax607 quantize -1000    Inf   ->  NaN  Invalid_operation
+quax608 quantize -Inf    -Inf   ->  -Infinity
+quax609 quantize -1      -Inf   ->  NaN  Invalid_operation
+quax610 quantize  0      -Inf   ->  NaN  Invalid_operation
+quax611 quantize  1      -Inf   ->  NaN  Invalid_operation
+quax612 quantize  1000   -Inf   ->  NaN  Invalid_operation
+quax613 quantize  Inf    -Inf   ->  Infinity
+quax614 quantize -Inf  1e-0     ->  NaN  Invalid_operation
+quax615 quantize -0      -Inf   ->  NaN  Invalid_operation
+
+quax621 quantize  NaN   -Inf    ->  NaN
+quax622 quantize  NaN 1e-1000   ->  NaN
+quax623 quantize  NaN 1e-1      ->  NaN
+quax624 quantize  NaN  1e0      ->  NaN
+quax625 quantize  NaN  1e1      ->  NaN
+quax626 quantize  NaN  1e1000   ->  NaN
+quax627 quantize  NaN    Inf    ->  NaN
+quax628 quantize  NaN    NaN    ->  NaN
+quax629 quantize -Inf    NaN    ->  NaN
+quax630 quantize -1000   NaN    ->  NaN
+quax631 quantize -1      NaN    ->  NaN
+quax632 quantize  0      NaN    ->  NaN
+quax633 quantize  1      NaN    ->  NaN
+quax634 quantize  1000   NaN    ->  NaN
+quax635 quantize  Inf    NaN    ->  NaN
+quax636 quantize  NaN 1e-0      ->  NaN
+quax637 quantize -0      NaN    ->  NaN
+
+quax641 quantize  sNaN   -Inf   ->  NaN  Invalid_operation
+quax642 quantize  sNaN 1e-1000  ->  NaN  Invalid_operation
+quax643 quantize  sNaN 1e-1     ->  NaN  Invalid_operation
+quax644 quantize  sNaN  1e0     ->  NaN  Invalid_operation
+quax645 quantize  sNaN  1e1     ->  NaN  Invalid_operation
+quax646 quantize  sNaN  1e1000  ->  NaN  Invalid_operation
+quax647 quantize  sNaN    NaN   ->  NaN  Invalid_operation
+quax648 quantize  sNaN   sNaN   ->  NaN  Invalid_operation
+quax649 quantize  NaN    sNaN   ->  NaN  Invalid_operation
+quax650 quantize -Inf    sNaN   ->  NaN  Invalid_operation
+quax651 quantize -1000   sNaN   ->  NaN  Invalid_operation
+quax652 quantize -1      sNaN   ->  NaN  Invalid_operation
+quax653 quantize  0      sNaN   ->  NaN  Invalid_operation
+quax654 quantize  1      sNaN   ->  NaN  Invalid_operation
+quax655 quantize  1000   sNaN   ->  NaN  Invalid_operation
+quax656 quantize  Inf    sNaN   ->  NaN  Invalid_operation
+quax657 quantize  NaN    sNaN   ->  NaN  Invalid_operation
+quax658 quantize  sNaN 1e-0     ->  NaN  Invalid_operation
+quax659 quantize -0      sNaN   ->  NaN  Invalid_operation
+
+-- propagating NaNs
+quax661 quantize  NaN9 -Inf   ->  NaN9
+quax662 quantize  NaN8  919   ->  NaN8
+quax663 quantize  NaN71 Inf   ->  NaN71
+quax664 quantize  NaN6  NaN5  ->  NaN6
+quax665 quantize -Inf   NaN4  ->  NaN4
+quax666 quantize -919   NaN31 ->  NaN31
+quax667 quantize  Inf   NaN2  ->  NaN2
+
+quax671 quantize  sNaN99 -Inf    ->  NaN99 Invalid_operation
+quax672 quantize  sNaN98 -11     ->  NaN98 Invalid_operation
+quax673 quantize  sNaN97  NaN    ->  NaN97 Invalid_operation
+quax674 quantize  sNaN16 sNaN94  ->  NaN16 Invalid_operation
+quax675 quantize  NaN95  sNaN93  ->  NaN93 Invalid_operation
+quax676 quantize -Inf    sNaN92  ->  NaN92 Invalid_operation
+quax677 quantize  088    sNaN91  ->  NaN91 Invalid_operation
+quax678 quantize  Inf    sNaN90  ->  NaN90 Invalid_operation
+quax679 quantize  NaN    sNaN88  ->  NaN88 Invalid_operation
+
+quax681 quantize -NaN9 -Inf   -> -NaN9
+quax682 quantize -NaN8  919   -> -NaN8
+quax683 quantize -NaN71 Inf   -> -NaN71
+quax684 quantize -NaN6 -NaN5  -> -NaN6
+quax685 quantize -Inf  -NaN4  -> -NaN4
+quax686 quantize -919  -NaN31 -> -NaN31
+quax687 quantize  Inf  -NaN2  -> -NaN2
+
+quax691 quantize -sNaN99 -Inf    -> -NaN99 Invalid_operation
+quax692 quantize -sNaN98 -11     -> -NaN98 Invalid_operation
+quax693 quantize -sNaN97  NaN    -> -NaN97 Invalid_operation
+quax694 quantize -sNaN16 sNaN94  -> -NaN16 Invalid_operation
+quax695 quantize -NaN95 -sNaN93  -> -NaN93 Invalid_operation
+quax696 quantize -Inf   -sNaN92  -> -NaN92 Invalid_operation
+quax697 quantize  088   -sNaN91  -> -NaN91 Invalid_operation
+quax698 quantize  Inf   -sNaN90  -> -NaN90 Invalid_operation
+quax699 quantize  NaN   -sNaN88  -> -NaN88 Invalid_operation
+
+-- subnormals and underflow
+precision: 4
+maxexponent: 999
+minexponent: -999
+quax710 quantize  1.00E-999    1e-999  ->   1E-999    Rounded
+quax711 quantize  0.1E-999    2e-1000  ->   1E-1000   Subnormal
+quax712 quantize  0.10E-999   3e-1000  ->   1E-1000   Subnormal Rounded
+quax713 quantize  0.100E-999  4e-1000  ->   1E-1000   Subnormal Rounded
+quax714 quantize  0.01E-999   5e-1001  ->   1E-1001   Subnormal
+-- next is rounded to Emin
+quax715 quantize  0.999E-999   1e-999  ->   1E-999    Inexact Rounded
+quax716 quantize  0.099E-999 10e-1000  ->   1E-1000   Inexact Rounded Subnormal
+
+quax717 quantize  0.009E-999  1e-1001  ->   1E-1001   Inexact Rounded Subnormal
+quax718 quantize  0.001E-999  1e-1001  ->   0E-1001   Inexact Rounded
+quax719 quantize  0.0009E-999 1e-1001  ->   0E-1001   Inexact Rounded
+quax720 quantize  0.0001E-999 1e-1001  ->   0E-1001   Inexact Rounded
+
+quax730 quantize -1.00E-999   1e-999  ->  -1E-999     Rounded
+quax731 quantize -0.1E-999    1e-999  ->  -0E-999     Rounded Inexact
+quax732 quantize -0.10E-999   1e-999  ->  -0E-999     Rounded Inexact
+quax733 quantize -0.100E-999  1e-999  ->  -0E-999     Rounded Inexact
+quax734 quantize -0.01E-999   1e-999  ->  -0E-999     Inexact Rounded
+-- next is rounded to Emin
+quax735 quantize -0.999E-999 90e-999  ->  -1E-999     Inexact Rounded
+quax736 quantize -0.099E-999 -1e-999  ->  -0E-999     Inexact Rounded
+quax737 quantize -0.009E-999 -1e-999  ->  -0E-999     Inexact Rounded
+quax738 quantize -0.001E-999 -0e-999  ->  -0E-999     Inexact Rounded
+quax739 quantize -0.0001E-999 0e-999  ->  -0E-999     Inexact Rounded
+
+quax740 quantize -1.00E-999   1e-1000 ->  -1.0E-999   Rounded
+quax741 quantize -0.1E-999    1e-1000 ->  -1E-1000    Subnormal
+quax742 quantize -0.10E-999   1e-1000 ->  -1E-1000    Subnormal Rounded
+quax743 quantize -0.100E-999  1e-1000 ->  -1E-1000    Subnormal Rounded
+quax744 quantize -0.01E-999   1e-1000 ->  -0E-1000    Inexact Rounded
+-- next is rounded to Emin
+quax745 quantize -0.999E-999  1e-1000 ->  -1.0E-999   Inexact Rounded
+quax746 quantize -0.099E-999  1e-1000 ->  -1E-1000    Inexact Rounded Subnormal
+quax747 quantize -0.009E-999  1e-1000 ->  -0E-1000    Inexact Rounded
+quax748 quantize -0.001E-999  1e-1000 ->  -0E-1000    Inexact Rounded
+quax749 quantize -0.0001E-999 1e-1000 ->  -0E-1000    Inexact Rounded
+
+quax750 quantize -1.00E-999   1e-1001 ->  -1.00E-999
+quax751 quantize -0.1E-999    1e-1001 ->  -1.0E-1000  Subnormal
+quax752 quantize -0.10E-999   1e-1001 ->  -1.0E-1000  Subnormal
+quax753 quantize -0.100E-999  1e-1001 ->  -1.0E-1000  Subnormal Rounded
+quax754 quantize -0.01E-999   1e-1001 ->  -1E-1001    Subnormal
+-- next is rounded to Emin
+quax755 quantize -0.999E-999  1e-1001 ->  -1.00E-999  Inexact Rounded
+quax756 quantize -0.099E-999  1e-1001 ->  -1.0E-1000  Inexact Rounded Subnormal
+quax757 quantize -0.009E-999  1e-1001 ->  -1E-1001    Inexact Rounded Subnormal
+quax758 quantize -0.001E-999  1e-1001 ->  -0E-1001    Inexact Rounded
+quax759 quantize -0.0001E-999 1e-1001 ->  -0E-1001    Inexact Rounded
+
+quax760 quantize -1.00E-999   1e-1002 ->  -1.000E-999
+quax761 quantize -0.1E-999    1e-1002 ->  -1.00E-1000  Subnormal
+quax762 quantize -0.10E-999   1e-1002 ->  -1.00E-1000  Subnormal
+quax763 quantize -0.100E-999  1e-1002 ->  -1.00E-1000  Subnormal
+quax764 quantize -0.01E-999   1e-1002 ->  -1.0E-1001   Subnormal
+quax765 quantize -0.999E-999  1e-1002 ->  -9.99E-1000  Subnormal
+quax766 quantize -0.099E-999  1e-1002 ->  -9.9E-1001   Subnormal
+quax767 quantize -0.009E-999  1e-1002 ->  -9E-1002     Subnormal
+quax768 quantize -0.001E-999  1e-1002 ->  -1E-1002     Subnormal
+quax769 quantize -0.0001E-999 1e-1002 ->  -0E-1002     Inexact Rounded
+
+-- rhs must be no less than Etiny
+quax770 quantize -1.00E-999   1e-1003 ->  NaN Invalid_operation
+quax771 quantize -0.1E-999    1e-1003 ->  NaN Invalid_operation
+quax772 quantize -0.10E-999   1e-1003 ->  NaN Invalid_operation
+quax773 quantize -0.100E-999  1e-1003 ->  NaN Invalid_operation
+quax774 quantize -0.01E-999   1e-1003 ->  NaN Invalid_operation
+quax775 quantize -0.999E-999  1e-1003 ->  NaN Invalid_operation
+quax776 quantize -0.099E-999  1e-1003 ->  NaN Invalid_operation
+quax777 quantize -0.009E-999  1e-1003 ->  NaN Invalid_operation
+quax778 quantize -0.001E-999  1e-1003 ->  NaN Invalid_operation
+quax779 quantize -0.0001E-999 1e-1003 ->  NaN Invalid_operation
+quax780 quantize -0.0001E-999 1e-1004 ->  NaN Invalid_operation
+
+precision:   9
+maxExponent: 999999999
+minexponent: -999999999
+
+-- some extremes derived from Rescale testcases
+quax801 quantize   0   1e1000000000 -> NaN Invalid_operation
+quax802 quantize   0  1e-1000000000 -> 0E-1000000000
+quax803 quantize   0   1e2000000000 -> NaN Invalid_operation
+quax804 quantize   0  1e-2000000000 -> NaN Invalid_operation
+quax805 quantize   0   1e3000000000 -> NaN Invalid_operation
+quax806 quantize   0  1e-3000000000 -> NaN Invalid_operation
+quax807 quantize   0   1e4000000000 -> NaN Invalid_operation
+quax808 quantize   0  1e-4000000000 -> NaN Invalid_operation
+quax809 quantize   0   1e5000000000 -> NaN Invalid_operation
+quax810 quantize   0  1e-5000000000 -> NaN Invalid_operation
+quax811 quantize   0   1e6000000000 -> NaN Invalid_operation
+quax812 quantize   0  1e-6000000000 -> NaN Invalid_operation
+quax813 quantize   0   1e7000000000 -> NaN Invalid_operation
+quax814 quantize   0  1e-7000000000 -> NaN Invalid_operation
+quax815 quantize   0   1e8000000000 -> NaN Invalid_operation
+quax816 quantize   0  1e-8000000000 -> NaN Invalid_operation
+quax817 quantize   0   1e9000000000 -> NaN Invalid_operation
+quax818 quantize   0  1e-9000000000 -> NaN Invalid_operation
+quax819 quantize   0   1e9999999999 -> NaN Invalid_operation
+quax820 quantize   0  1e-9999999999 -> NaN Invalid_operation
+quax821 quantize   0   1e10000000000 -> NaN Invalid_operation
+quax822 quantize   0  1e-10000000000 -> NaN Invalid_operation
+
+quax843 quantize   0    1e999999999 -> 0E+999999999
+quax844 quantize   0   1e1000000000 -> NaN Invalid_operation
+quax845 quantize   0   1e-999999999 -> 0E-999999999
+quax846 quantize   0  1e-1000000000 -> 0E-1000000000
+quax847 quantize   0  1e-1000000001 -> 0E-1000000001
+quax848 quantize   0  1e-1000000002 -> 0E-1000000002
+quax849 quantize   0  1e-1000000003 -> 0E-1000000003
+quax850 quantize   0  1e-1000000004 -> 0E-1000000004
+quax851 quantize   0  1e-1000000005 -> 0E-1000000005
+quax852 quantize   0  1e-1000000006 -> 0E-1000000006
+quax853 quantize   0  1e-1000000007 -> 0E-1000000007
+quax854 quantize   0  1e-1000000008 -> NaN Invalid_operation
+
+quax861 quantize   1  1e+2147483649 -> NaN Invalid_operation
+quax862 quantize   1  1e+2147483648 -> NaN Invalid_operation
+quax863 quantize   1  1e+2147483647 -> NaN Invalid_operation
+quax864 quantize   1  1e-2147483647 -> NaN Invalid_operation
+quax865 quantize   1  1e-2147483648 -> NaN Invalid_operation
+quax866 quantize   1  1e-2147483649 -> NaN Invalid_operation
+
+-- Null tests
+quax900 quantize 10    # -> NaN Invalid_operation
+quax901 quantize  # 1e10 -> NaN Invalid_operation

Added: vendor/Python/current/Lib/test/decimaltestdata/randomBound32.decTest
===================================================================
--- vendor/Python/current/Lib/test/decimaltestdata/randomBound32.decTest	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/decimaltestdata/randomBound32.decTest	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2443 @@
+------------------------------------------------------------------------
+-- randomBound32.decTest -- decimal testcases -- boundaries near 32   --
+-- Copyright (c) IBM Corporation, 1981, 2003.  All rights reserved.   --
+------------------------------------------------------------------------
+-- Please see the document "General Decimal Arithmetic Testcases"     --
+-- at http://www2.hursley.ibm.com/decimal for the description of      --
+-- these testcases.                                                   --
+--                                                                    --
+-- These testcases are experimental ('beta' versions), and they       --
+-- may contain errors.  They are offered on an as-is basis.  In       --
+-- particular, achieving the same results as the tests here is not    --
+-- a guarantee that an implementation complies with any Standard      --
+-- or specification.  The tests are not exhaustive.                   --
+--                                                                    --
+-- Please send comments, suggestions, and corrections to the author:  --
+--   Mike Cowlishaw, IBM Fellow                                       --
+--   IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK         --
+--   mfc at uk.ibm.com                                                   --
+------------------------------------------------------------------------
+version: 2.39
+
+-- These testcases test calculations at precisions 31, 32, and 33, to
+-- exercise the boundaries around 2**5
+
+-- randomly generated testcases [26 Sep 2001]
+extended:    1
+precision:   31
+rounding:    half_up
+maxExponent: 9999
+minexponent: -9999
+
+addx3001 add 4953734675913.065314738743322579 0218.932010396534371704930714860E+797 -> 2.189320103965343717049307148600E+799 Inexact Rounded
+comx3001 compare 4953734675913.065314738743322579 0218.932010396534371704930714860E+797 -> -1
+divx3001 divide 4953734675913.065314738743322579 0218.932010396534371704930714860E+797 -> 2.262681764507965005284080800438E-787 Inexact Rounded
+dvix3001 divideint 4953734675913.065314738743322579 0218.932010396534371704930714860E+797 -> 0
+mulx3001 multiply 4953734675913.065314738743322579 0218.932010396534371704930714860E+797 -> 1.084531091568672041923151632066E+812 Inexact Rounded
+powx3001 power 4953734675913.065314738743322579 2 -> 24539487239343522246155890.99495 Inexact Rounded
+remx3001 remainder 4953734675913.065314738743322579 0218.932010396534371704930714860E+797 -> 4953734675913.065314738743322579
+subx3001 subtract 4953734675913.065314738743322579 0218.932010396534371704930714860E+797 -> -2.189320103965343717049307148600E+799 Inexact Rounded
+addx3002 add 9641.684323386955881595490347910E-844 -78864532047.12287484430980636798E+934 -> -7.886453204712287484430980636798E+944 Inexact Rounded
+comx3002 compare 9641.684323386955881595490347910E-844 -78864532047.12287484430980636798E+934 -> 1
+divx3002 divide 9641.684323386955881595490347910E-844 -78864532047.12287484430980636798E+934 -> -1.222562801441069667849402782716E-1785 Inexact Rounded
+dvix3002 divideint 9641.684323386955881595490347910E-844 -78864532047.12287484430980636798E+934 -> -0
+mulx3002 multiply 9641.684323386955881595490347910E-844 -78864532047.12287484430980636798E+934 -> -7.603869223099928141659831589905E+104 Inexact Rounded
+powx3002 power 9641.684323386955881595490347910E-844 -8 -> 1.338988152067180337738955757587E+6720 Inexact Rounded
+remx3002 remainder 9641.684323386955881595490347910E-844 -78864532047.12287484430980636798E+934 -> 9.641684323386955881595490347910E-841
+subx3002 subtract 9641.684323386955881595490347910E-844 -78864532047.12287484430980636798E+934 -> 7.886453204712287484430980636798E+944 Inexact Rounded
+addx3003 add -1.028048571628326871054964307774E+529 49200008645699.35577937582714739 -> -1.028048571628326871054964307774E+529 Inexact Rounded
+comx3003 compare -1.028048571628326871054964307774E+529 49200008645699.35577937582714739 -> -1
+divx3003 divide -1.028048571628326871054964307774E+529 49200008645699.35577937582714739 -> -2.089529249946971482861843692465E+515 Inexact Rounded
+dvix3003 divideint -1.028048571628326871054964307774E+529 49200008645699.35577937582714739 -> NaN Division_impossible
+mulx3003 multiply -1.028048571628326871054964307774E+529 49200008645699.35577937582714739 -> -5.057999861231255549283737861207E+542 Inexact Rounded
+powx3003 power -1.028048571628326871054964307774E+529 5 -> -1.148333858253704284232780819739E+2645 Inexact Rounded
+remx3003 remainder -1.028048571628326871054964307774E+529 49200008645699.35577937582714739 -> NaN Division_impossible
+subx3003 subtract -1.028048571628326871054964307774E+529 49200008645699.35577937582714739 -> -1.028048571628326871054964307774E+529 Inexact Rounded
+addx3004 add 479084.8561808930525417735205519 084157571054.2691784660983989931 -> 84158050139.12535935915094076662 Inexact Rounded
+comx3004 compare 479084.8561808930525417735205519 084157571054.2691784660983989931 -> -1
+divx3004 divide 479084.8561808930525417735205519 084157571054.2691784660983989931 -> 0.000005692712493709617905493710207969 Inexact Rounded
+dvix3004 divideint 479084.8561808930525417735205519 084157571054.2691784660983989931 -> 0
+mulx3004 multiply 479084.8561808930525417735205519 084157571054.2691784660983989931 -> 40318617825067837.47317700523687 Inexact Rounded
+powx3004 power 479084.8561808930525417735205519 8 -> 2.775233598021235973545933045837E+45 Inexact Rounded
+remx3004 remainder 479084.8561808930525417735205519 084157571054.2691784660983989931 -> 479084.8561808930525417735205519
+subx3004 subtract 479084.8561808930525417735205519 084157571054.2691784660983989931 -> -84157091969.41299757304585721958 Inexact Rounded
+addx3005 add -0363750788.573782205664349562931 -3172.080934464133691909905980096 -> -363753960.6547166697980414728370 Inexact Rounded
+comx3005 compare -0363750788.573782205664349562931 -3172.080934464133691909905980096 -> -1
+divx3005 divide -0363750788.573782205664349562931 -3172.080934464133691909905980096 -> 114672.6064337420167096295290890 Inexact Rounded
+dvix3005 divideint -0363750788.573782205664349562931 -3172.080934464133691909905980096 -> 114672
+mulx3005 multiply -0363750788.573782205664349562931 -3172.080934464133691909905980096 -> 1153846941331.188583292239230818 Inexact Rounded
+powx3005 power -0363750788.573782205664349562931 -3172 -> 0E-10029 Underflow Subnormal Inexact Rounded Clamped
+remx3005 remainder -0363750788.573782205664349562931 -3172.080934464133691909905980096 -> -1923.656911066945656824381431488
+subx3005 subtract -0363750788.573782205664349562931 -3172.080934464133691909905980096 -> -363747616.4928477415306576530250 Inexact Rounded
+addx3006 add 1381026551423669919010191878449 -82.66614775445371254999357800739 -> 1381026551423669919010191878366 Inexact Rounded
+comx3006 compare 1381026551423669919010191878449 -82.66614775445371254999357800739 -> 1
+divx3006 divide 1381026551423669919010191878449 -82.66614775445371254999357800739 -> -16706071214613552377376639557.90 Inexact Rounded
+dvix3006 divideint 1381026551423669919010191878449 -82.66614775445371254999357800739 -> -16706071214613552377376639557
+mulx3006 multiply 1381026551423669919010191878449 -82.66614775445371254999357800739 -> -1.141641449528127656560770057228E+32 Inexact Rounded
+powx3006 power 1381026551423669919010191878449 -83 -> 2.307977908106564299925193011052E-2502 Inexact Rounded
+remx3006 remainder 1381026551423669919010191878449 -82.66614775445371254999357800739 -> 74.22115953553602036042168767377
+subx3006 subtract 1381026551423669919010191878449 -82.66614775445371254999357800739 -> 1381026551423669919010191878532 Inexact Rounded
+addx3007 add 4627.026960423072127953556635585 -4410583132901.830017479741231131 -> -4410583128274.803057056669103177 Inexact Rounded
+comx3007 compare 4627.026960423072127953556635585 -4410583132901.830017479741231131 -> 1
+divx3007 divide 4627.026960423072127953556635585 -4410583132901.830017479741231131 -> -1.049073743992404570569003129346E-9 Inexact Rounded
+dvix3007 divideint 4627.026960423072127953556635585 -4410583132901.830017479741231131 -> -0
+mulx3007 multiply 4627.026960423072127953556635585 -4410583132901.830017479741231131 -> -20407887067124025.31576887565113 Inexact Rounded
+powx3007 power 4627.026960423072127953556635585 -4 -> 2.181684167222334934221407781701E-15 Inexact Rounded
+remx3007 remainder 4627.026960423072127953556635585 -4410583132901.830017479741231131 -> 4627.026960423072127953556635585
+subx3007 subtract 4627.026960423072127953556635585 -4410583132901.830017479741231131 -> 4410583137528.856977902813359085 Inexact Rounded
+addx3008 add 75353574493.84484153484918212042 -8684111695095849922263044191221 -> -8684111695095849922187690616727 Inexact Rounded
+comx3008 compare 75353574493.84484153484918212042 -8684111695095849922263044191221 -> 1
+divx3008 divide 75353574493.84484153484918212042 -8684111695095849922263044191221 -> -8.677177026223536475531592432118E-21 Inexact Rounded
+dvix3008 divideint 75353574493.84484153484918212042 -8684111695095849922263044191221 -> -0
+mulx3008 multiply 75353574493.84484153484918212042 -8684111695095849922263044191221 -> -6.543788575292743281456830701127E+41 Inexact Rounded
+powx3008 power 75353574493.84484153484918212042 -9 -> 1.276630670287906925570645490708E-98 Inexact Rounded
+remx3008 remainder 75353574493.84484153484918212042 -8684111695095849922263044191221 -> 75353574493.84484153484918212042
+subx3008 subtract 75353574493.84484153484918212042 -8684111695095849922263044191221 -> 8684111695095849922338397765715 Inexact Rounded
+addx3009 add 6907058.216435355874729592373011 2.857005446917670515662398741545 -> 6907061.073440802792400108035410 Inexact Rounded
+comx3009 compare 6907058.216435355874729592373011 2.857005446917670515662398741545 -> 1
+divx3009 divide 6907058.216435355874729592373011 2.857005446917670515662398741545 -> 2417586.646146283856436864121104 Inexact Rounded
+dvix3009 divideint 6907058.216435355874729592373011 2.857005446917670515662398741545 -> 2417586
+mulx3009 multiply 6907058.216435355874729592373011 2.857005446917670515662398741545 -> 19733502.94653326211623698034717 Inexact Rounded
+powx3009 power 6907058.216435355874729592373011 3 -> 329518156646369505494.8971353240 Inexact Rounded
+remx3009 remainder 6907058.216435355874729592373011 2.857005446917670515662398741545 -> 1.846043452483451396449034189630
+subx3009 subtract 6907058.216435355874729592373011 2.857005446917670515662398741545 -> 6907055.359429908957059076710612 Inexact Rounded
+addx3010 add -38949530427253.24030680468677190 712168021.1265384466442576619064E-992 -> -38949530427253.24030680468677190 Inexact Rounded
+comx3010 compare -38949530427253.24030680468677190 712168021.1265384466442576619064E-992 -> -1
+divx3010 divide -38949530427253.24030680468677190 712168021.1265384466442576619064E-992 -> -5.469149031100999700489221122509E+996 Inexact Rounded
+dvix3010 divideint -38949530427253.24030680468677190 712168021.1265384466442576619064E-992 -> NaN Division_impossible
+mulx3010 multiply -38949530427253.24030680468677190 712168021.1265384466442576619064E-992 -> -2.773861000818483769292240109417E-970 Inexact Rounded
+powx3010 power -38949530427253.24030680468677190 7 -> -1.359926959823071332599817363877E+95 Inexact Rounded
+remx3010 remainder -38949530427253.24030680468677190 712168021.1265384466442576619064E-992 -> NaN Division_impossible
+subx3010 subtract -38949530427253.24030680468677190 712168021.1265384466442576619064E-992 -> -38949530427253.24030680468677190 Inexact Rounded
+addx3011 add -0708069.025667471996378081482549 -562842.4701520787831018732202804 -> -1270911.495819550779479954702829 Inexact Rounded
+comx3011 compare -0708069.025667471996378081482549 -562842.4701520787831018732202804 -> -1
+divx3011 divide -0708069.025667471996378081482549 -562842.4701520787831018732202804 -> 1.258023449218665608349145394069 Inexact Rounded
+dvix3011 divideint -0708069.025667471996378081482549 -562842.4701520787831018732202804 -> 1
+mulx3011 multiply -0708069.025667471996378081482549 -562842.4701520787831018732202804 -> 398531319444.8556128729086112205 Inexact Rounded
+powx3011 power -0708069.025667471996378081482549 -562842 -> 0E-10029 Underflow Subnormal Inexact Rounded Clamped
+remx3011 remainder -0708069.025667471996378081482549 -562842.4701520787831018732202804 -> -145226.5555153932132762082622686
+subx3011 subtract -0708069.025667471996378081482549 -562842.4701520787831018732202804 -> -145226.5555153932132762082622686
+addx3012 add 4055087.246994644709729942673976 -43183146921897.67383476104084575E+211 -> -4.318314692189767383476104084575E+224 Inexact Rounded
+comx3012 compare 4055087.246994644709729942673976 -43183146921897.67383476104084575E+211 -> 1
+divx3012 divide 4055087.246994644709729942673976 -43183146921897.67383476104084575E+211 -> -9.390439409913307906923909630247E-219 Inexact Rounded
+dvix3012 divideint 4055087.246994644709729942673976 -43183146921897.67383476104084575E+211 -> -0
+mulx3012 multiply 4055087.246994644709729942673976 -43183146921897.67383476104084575E+211 -> -1.751114283680833039197637874453E+231 Inexact Rounded
+powx3012 power 4055087.246994644709729942673976 -4 -> 3.698274893849241116195795515302E-27 Inexact Rounded
+remx3012 remainder 4055087.246994644709729942673976 -43183146921897.67383476104084575E+211 -> 4055087.246994644709729942673976
+subx3012 subtract 4055087.246994644709729942673976 -43183146921897.67383476104084575E+211 -> 4.318314692189767383476104084575E+224 Inexact Rounded
+addx3013 add 4502895892520.396581348110906909E-512 -815.9047305921862348263521876034 -> -815.9047305921862348263521876034 Inexact Rounded
+comx3013 compare 4502895892520.396581348110906909E-512 -815.9047305921862348263521876034 -> 1
+divx3013 divide 4502895892520.396581348110906909E-512 -815.9047305921862348263521876034 -> -5.518899111238367862234798433551E-503 Inexact Rounded
+dvix3013 divideint 4502895892520.396581348110906909E-512 -815.9047305921862348263521876034 -> -0
+mulx3013 multiply 4502895892520.396581348110906909E-512 -815.9047305921862348263521876034 -> -3.673934060071516156604453756541E-497 Inexact Rounded
+powx3013 power 4502895892520.396581348110906909E-512 -816 -> Infinity Overflow Inexact Rounded
+remx3013 remainder 4502895892520.396581348110906909E-512 -815.9047305921862348263521876034 -> 4.502895892520396581348110906909E-500
+subx3013 subtract 4502895892520.396581348110906909E-512 -815.9047305921862348263521876034 -> 815.9047305921862348263521876034 Inexact Rounded
+addx3014 add 467.6721295072628100260239179865 -02.07155073395573569852316073025 -> 465.6005787733070743275007572563 Inexact Rounded
+comx3014 compare 467.6721295072628100260239179865 -02.07155073395573569852316073025 -> 1
+divx3014 divide 467.6721295072628100260239179865 -02.07155073395573569852316073025 -> -225.7594380101027705997496045999 Inexact Rounded
+dvix3014 divideint 467.6721295072628100260239179865 -02.07155073395573569852316073025 -> -225
+mulx3014 multiply 467.6721295072628100260239179865 -02.07155073395573569852316073025 -> -968.8065431314121523074875069807 Inexact Rounded
+powx3014 power 467.6721295072628100260239179865 -2 -> 0.000004572113694193221810609836080931 Inexact Rounded
+remx3014 remainder 467.6721295072628100260239179865 -02.07155073395573569852316073025 -> 1.57321436722227785831275368025
+subx3014 subtract 467.6721295072628100260239179865 -02.07155073395573569852316073025 -> 469.7436802412185457245470787168 Inexact Rounded
+addx3015 add 2.156795313311150143949997552501E-571 -8677147.586389401682712180146855 -> -8677147.586389401682712180146855 Inexact Rounded
+comx3015 compare 2.156795313311150143949997552501E-571 -8677147.586389401682712180146855 -> 1
+divx3015 divide 2.156795313311150143949997552501E-571 -8677147.586389401682712180146855 -> -2.485604044230163799604243529005E-578 Inexact Rounded
+dvix3015 divideint 2.156795313311150143949997552501E-571 -8677147.586389401682712180146855 -> -0
+mulx3015 multiply 2.156795313311150143949997552501E-571 -8677147.586389401682712180146855 -> -1.871483124723381986272837942577E-564 Inexact Rounded
+powx3015 power 2.156795313311150143949997552501E-571 -8677148 -> Infinity Overflow Inexact Rounded
+remx3015 remainder 2.156795313311150143949997552501E-571 -8677147.586389401682712180146855 -> 2.156795313311150143949997552501E-571
+subx3015 subtract 2.156795313311150143949997552501E-571 -8677147.586389401682712180146855 -> 8677147.586389401682712180146855 Inexact Rounded
+addx3016 add -974953.2801637208368002585822457 -693095793.3667578067802698191246 -> -694070746.6469215276170700777068 Inexact Rounded
+comx3016 compare -974953.2801637208368002585822457 -693095793.3667578067802698191246 -> 1
+divx3016 divide -974953.2801637208368002585822457 -693095793.3667578067802698191246 -> 0.001406664546942092941961075608769 Inexact Rounded
+dvix3016 divideint -974953.2801637208368002585822457 -693095793.3667578067802698191246 -> 0
+mulx3016 multiply -974953.2801637208368002585822457 -693095793.3667578067802698191246 -> 675736017210596.9899587749991363 Inexact Rounded
+powx3016 power -974953.2801637208368002585822457 -693095793 -> -0E-10029 Underflow Subnormal Inexact Rounded Clamped
+remx3016 remainder -974953.2801637208368002585822457 -693095793.3667578067802698191246 -> -974953.2801637208368002585822457
+subx3016 subtract -974953.2801637208368002585822457 -693095793.3667578067802698191246 -> 692120840.0865940859434695605424 Inexact Rounded
+addx3017 add -7634680140009571846155654339781 3009630949502.035852433434214413E-490 -> -7634680140009571846155654339781 Inexact Rounded
+comx3017 compare -7634680140009571846155654339781 3009630949502.035852433434214413E-490 -> -1
+divx3017 divide -7634680140009571846155654339781 3009630949502.035852433434214413E-490 -> -2.536749610869326753741024659948E+508 Inexact Rounded
+dvix3017 divideint -7634680140009571846155654339781 3009630949502.035852433434214413E-490 -> NaN Division_impossible
+mulx3017 multiply -7634680140009571846155654339781 3009630949502.035852433434214413E-490 -> -2.297756963892134373657544025107E-447 Inexact Rounded
+powx3017 power -7634680140009571846155654339781 3 -> -4.450128382072157170207584847831E+92 Inexact Rounded
+remx3017 remainder -7634680140009571846155654339781 3009630949502.035852433434214413E-490 -> NaN Division_impossible
+subx3017 subtract -7634680140009571846155654339781 3009630949502.035852433434214413E-490 -> -7634680140009571846155654339781 Inexact Rounded
+addx3018 add 262273.0222851186523650889896428E-624 74177.21073338090843145838835480 -> 74177.21073338090843145838835480 Inexact Rounded
+comx3018 compare 262273.0222851186523650889896428E-624 74177.21073338090843145838835480 -> -1
+divx3018 divide 262273.0222851186523650889896428E-624 74177.21073338090843145838835480 -> 3.535762799545274329358292065343E-624 Inexact Rounded
+dvix3018 divideint 262273.0222851186523650889896428E-624 74177.21073338090843145838835480 -> 0
+mulx3018 multiply 262273.0222851186523650889896428E-624 74177.21073338090843145838835480 -> 1.945468124372395349192665031675E-614 Inexact Rounded
+powx3018 power 262273.0222851186523650889896428E-624 74177 -> 0E-10029 Underflow Subnormal Inexact Rounded Clamped
+remx3018 remainder 262273.0222851186523650889896428E-624 74177.21073338090843145838835480 -> 2.622730222851186523650889896428E-619
+subx3018 subtract 262273.0222851186523650889896428E-624 74177.21073338090843145838835480 -> -74177.21073338090843145838835480 Inexact Rounded
+addx3019 add -8036052748815903177624716581732 -066677357.4438809548850966167573 -> -8036052748815903177624783259089 Inexact Rounded
+comx3019 compare -8036052748815903177624716581732 -066677357.4438809548850966167573 -> -1
+divx3019 divide -8036052748815903177624716581732 -066677357.4438809548850966167573 -> 120521464210387351732732.6271469 Inexact Rounded
+dvix3019 divideint -8036052748815903177624716581732 -066677357.4438809548850966167573 -> 120521464210387351732732
+mulx3019 multiply -8036052748815903177624716581732 -066677357.4438809548850966167573 -> 5.358227615706800711033262124598E+38 Inexact Rounded
+powx3019 power -8036052748815903177624716581732 -66677357 -> -0E-10029 Underflow Subnormal Inexact Rounded Clamped
+remx3019 remainder -8036052748815903177624716581732 -066677357.4438809548850966167573 -> -41816499.5048993028288978900564
+subx3019 subtract -8036052748815903177624716581732 -066677357.4438809548850966167573 -> -8036052748815903177624649904375 Inexact Rounded
+addx3020 add 883429.5928031498103637713570166E+765 -43978.97283712939198111043032726 -> 8.834295928031498103637713570166E+770 Inexact Rounded
+comx3020 compare 883429.5928031498103637713570166E+765 -43978.97283712939198111043032726 -> 1
+divx3020 divide 883429.5928031498103637713570166E+765 -43978.97283712939198111043032726 -> -2.008754492913739633208672455025E+766 Inexact Rounded
+dvix3020 divideint 883429.5928031498103637713570166E+765 -43978.97283712939198111043032726 -> NaN Division_impossible
+mulx3020 multiply 883429.5928031498103637713570166E+765 -43978.97283712939198111043032726 -> -3.885232606540600490321438191516E+775 Inexact Rounded
+powx3020 power 883429.5928031498103637713570166E+765 -43979 -> 0E-10029 Underflow Subnormal Inexact Rounded Clamped
+remx3020 remainder 883429.5928031498103637713570166E+765 -43978.97283712939198111043032726 -> NaN Division_impossible
+subx3020 subtract 883429.5928031498103637713570166E+765 -43978.97283712939198111043032726 -> 8.834295928031498103637713570166E+770 Inexact Rounded
+addx3021 add 24791301060.37938360567775506973 -5613327866480.322649080205877564 -> -5588536565419.943265474528122494 Inexact Rounded
+comx3021 compare 24791301060.37938360567775506973 -5613327866480.322649080205877564 -> 1
+divx3021 divide 24791301060.37938360567775506973 -5613327866480.322649080205877564 -> -0.004416506865458415275182120038399 Inexact Rounded
+dvix3021 divideint 24791301060.37938360567775506973 -5613327866480.322649080205877564 -> -0
+mulx3021 multiply 24791301060.37938360567775506973 -5613327866480.322649080205877564 -> -139161701088530765925120.8408852 Inexact Rounded
+powx3021 power 24791301060.37938360567775506973 -6 -> 4.307289712375673028996126249656E-63 Inexact Rounded
+remx3021 remainder 24791301060.37938360567775506973 -5613327866480.322649080205877564 -> 24791301060.37938360567775506973
+subx3021 subtract 24791301060.37938360567775506973 -5613327866480.322649080205877564 -> 5638119167540.702032685883632634 Inexact Rounded
+addx3022 add -930711443.9474781586162910776139 -740.3860979292775472622798348030 -> -930712184.3335760878938383398937 Inexact Rounded
+comx3022 compare -930711443.9474781586162910776139 -740.3860979292775472622798348030 -> -1
+divx3022 divide -930711443.9474781586162910776139 -740.3860979292775472622798348030 -> 1257062.290270583507131602958799 Inexact Rounded
+dvix3022 divideint -930711443.9474781586162910776139 -740.3860979292775472622798348030 -> 1257062
+mulx3022 multiply -930711443.9474781586162910776139 -740.3860979292775472622798348030 -> 689085814282.3968746911100154133 Inexact Rounded
+powx3022 power -930711443.9474781586162910776139 -740 -> 1.193603394165051899997226995178E-6637 Inexact Rounded
+remx3022 remainder -930711443.9474781586162910776139 -740.3860979292775472622798348030 -> -214.9123046664996750639167712140
+subx3022 subtract -930711443.9474781586162910776139 -740.3860979292775472622798348030 -> -930710703.5613802293387438153341 Inexact Rounded
+addx3023 add 2358276428765.064191082773385539 214.3589796082328665878602304469 -> 2358276428979.423170691006252127 Inexact Rounded
+comx3023 compare 2358276428765.064191082773385539 214.3589796082328665878602304469 -> 1
+divx3023 divide 2358276428765.064191082773385539 214.3589796082328665878602304469 -> 11001528525.07089502152736489473 Inexact Rounded
+dvix3023 divideint 2358276428765.064191082773385539 214.3589796082328665878602304469 -> 11001528525
+mulx3023 multiply 2358276428765.064191082773385539 214.3589796082328665878602304469 -> 505517728904226.6233443209659001 Inexact Rounded
+powx3023 power 2358276428765.064191082773385539 214 -> 5.435856480782850080741276939256E+2647 Inexact Rounded
+remx3023 remainder 2358276428765.064191082773385539 214.3589796082328665878602304469 -> 15.1969844739096415643561521775
+subx3023 subtract 2358276428765.064191082773385539 214.3589796082328665878602304469 -> 2358276428550.705211474540518951 Inexact Rounded
+addx3024 add -3.868744449795653651638308926987E+750 8270.472492965559872384018329418 -> -3.868744449795653651638308926987E+750 Inexact Rounded
+comx3024 compare -3.868744449795653651638308926987E+750 8270.472492965559872384018329418 -> -1
+divx3024 divide -3.868744449795653651638308926987E+750 8270.472492965559872384018329418 -> -4.677779235812959233092739433453E+746 Inexact Rounded
+dvix3024 divideint -3.868744449795653651638308926987E+750 8270.472492965559872384018329418 -> NaN Division_impossible
+mulx3024 multiply -3.868744449795653651638308926987E+750 8270.472492965559872384018329418 -> -3.199634455434813294426505526063E+754 Inexact Rounded
+powx3024 power -3.868744449795653651638308926987E+750 8270 -> Infinity Overflow Inexact Rounded
+remx3024 remainder -3.868744449795653651638308926987E+750 8270.472492965559872384018329418 -> NaN Division_impossible
+subx3024 subtract -3.868744449795653651638308926987E+750 8270.472492965559872384018329418 -> -3.868744449795653651638308926987E+750 Inexact Rounded
+addx3025 add 140422069.5863246490180206814374E-447 -567195652586.2454217069003186487 -> -567195652586.2454217069003186487 Inexact Rounded
+comx3025 compare 140422069.5863246490180206814374E-447 -567195652586.2454217069003186487 -> 1
+divx3025 divide 140422069.5863246490180206814374E-447 -567195652586.2454217069003186487 -> -2.475725421131866851190640203633E-451 Inexact Rounded
+dvix3025 divideint 140422069.5863246490180206814374E-447 -567195652586.2454217069003186487 -> -0
+mulx3025 multiply 140422069.5863246490180206814374E-447 -567195652586.2454217069003186487 -> -7.964678739652657498503799559950E-428 Inexact Rounded
+powx3025 power 140422069.5863246490180206814374E-447 -6 -> 1.304330899731988395473578425854E+2633 Inexact Rounded
+remx3025 remainder 140422069.5863246490180206814374E-447 -567195652586.2454217069003186487 -> 1.404220695863246490180206814374E-439
+subx3025 subtract 140422069.5863246490180206814374E-447 -567195652586.2454217069003186487 -> 567195652586.2454217069003186487 Inexact Rounded
+addx3026 add 75929096475.63450425339472559646E+153 -0945260193.503803519572604151290E+459 -> -9.452601935038035195726041512900E+467 Inexact Rounded
+comx3026 compare 75929096475.63450425339472559646E+153 -0945260193.503803519572604151290E+459 -> 1
+divx3026 divide 75929096475.63450425339472559646E+153 -0945260193.503803519572604151290E+459 -> -8.032613347885465805613265604973E-305 Inexact Rounded
+dvix3026 divideint 75929096475.63450425339472559646E+153 -0945260193.503803519572604151290E+459 -> -0
+mulx3026 multiply 75929096475.63450425339472559646E+153 -0945260193.503803519572604151290E+459 -> -7.177275242712723733041569606882E+631 Inexact Rounded
+powx3026 power 75929096475.63450425339472559646E+153 -9 -> 1.192136299657177324051477375561E-1475 Inexact Rounded
+remx3026 remainder 75929096475.63450425339472559646E+153 -0945260193.503803519572604151290E+459 -> 7.592909647563450425339472559646E+163
+subx3026 subtract 75929096475.63450425339472559646E+153 -0945260193.503803519572604151290E+459 -> 9.452601935038035195726041512900E+467 Inexact Rounded
+addx3027 add 6312318309.142044953357460463732 -5641317823.202274083982487558514E+628 -> -5.641317823202274083982487558514E+637 Inexact Rounded
+comx3027 compare 6312318309.142044953357460463732 -5641317823.202274083982487558514E+628 -> 1
+divx3027 divide 6312318309.142044953357460463732 -5641317823.202274083982487558514E+628 -> -1.118943925332481944765809682502E-628 Inexact Rounded
+dvix3027 divideint 6312318309.142044953357460463732 -5641317823.202274083982487558514E+628 -> -0
+mulx3027 multiply 6312318309.142044953357460463732 -5641317823.202274083982487558514E+628 -> -3.560979378308906043783023726787E+647 Inexact Rounded
+powx3027 power 6312318309.142044953357460463732 -6 -> 1.580762611512787720076533747265E-59 Inexact Rounded
+remx3027 remainder 6312318309.142044953357460463732 -5641317823.202274083982487558514E+628 -> 6312318309.142044953357460463732
+subx3027 subtract 6312318309.142044953357460463732 -5641317823.202274083982487558514E+628 -> 5.641317823202274083982487558514E+637 Inexact Rounded
+addx3028 add 93793652428100.52105928239469937 917.2571313109730433369594936416E-712 -> 93793652428100.52105928239469937 Inexact Rounded
+comx3028 compare 93793652428100.52105928239469937 917.2571313109730433369594936416E-712 -> 1
+divx3028 divide 93793652428100.52105928239469937 917.2571313109730433369594936416E-712 -> 1.022544815694674972559924997256E+723 Inexact Rounded
+dvix3028 divideint 93793652428100.52105928239469937 917.2571313109730433369594936416E-712 -> NaN Division_impossible
+mulx3028 multiply 93793652428100.52105928239469937 917.2571313109730433369594936416E-712 -> 8.603289656137796526769786965341E-696 Inexact Rounded
+powx3028 power 93793652428100.52105928239469937 9 -> 5.617732206663136654187263964365E+125 Inexact Rounded
+remx3028 remainder 93793652428100.52105928239469937 917.2571313109730433369594936416E-712 -> NaN Division_impossible
+subx3028 subtract 93793652428100.52105928239469937 917.2571313109730433369594936416E-712 -> 93793652428100.52105928239469937 Inexact Rounded
+addx3029 add 98471198160.56524417578665886060 -23994.14313393939743548945165462 -> 98471174166.42211023638922337115 Inexact Rounded
+comx3029 compare 98471198160.56524417578665886060 -23994.14313393939743548945165462 -> 1
+divx3029 divide 98471198160.56524417578665886060 -23994.14313393939743548945165462 -> -4103968.106336710126241266685434 Inexact Rounded
+dvix3029 divideint 98471198160.56524417578665886060 -23994.14313393939743548945165462 -> -4103968
+mulx3029 multiply 98471198160.56524417578665886060 -23994.14313393939743548945165462 -> -2362732023235112.375960528304974 Inexact Rounded
+powx3029 power 98471198160.56524417578665886060 -23994 -> 0E-10029 Underflow Subnormal Inexact Rounded Clamped
+remx3029 remainder 98471198160.56524417578665886060 -23994.14313393939743548945165462 -> 2551.45824316125588493249246784
+subx3029 subtract 98471198160.56524417578665886060 -23994.14313393939743548945165462 -> 98471222154.70837811518409435005 Inexact Rounded
+addx3030 add 329326552.0208398002250836592043 -02451.10065397010591546041034041 -> 329324100.9201858301191681987940 Inexact Rounded
+comx3030 compare 329326552.0208398002250836592043 -02451.10065397010591546041034041 -> 1
+divx3030 divide 329326552.0208398002250836592043 -02451.10065397010591546041034041 -> -134358.6406732917173739187421978 Inexact Rounded
+dvix3030 divideint 329326552.0208398002250836592043 -02451.10065397010591546041034041 -> -134358
+mulx3030 multiply 329326552.0208398002250836592043 -02451.10065397010591546041034041 -> -807212527028.0005401736893474430 Inexact Rounded
+powx3030 power 329326552.0208398002250836592043 -2451 -> 0E-10029 Underflow Subnormal Inexact Rounded Clamped
+remx3030 remainder 329326552.0208398002250836592043 -02451.10065397010591546041034041 -> 1570.35472430963565384668749322
+subx3030 subtract 329326552.0208398002250836592043 -02451.10065397010591546041034041 -> 329329003.1214937703309991196146 Inexact Rounded
+addx3031 add -92980.68431371090354435763218439 -2282178507046019721925800997065 -> -2282178507046019721925801090046 Inexact Rounded
+comx3031 compare -92980.68431371090354435763218439 -2282178507046019721925800997065 -> 1
+divx3031 divide -92980.68431371090354435763218439 -2282178507046019721925800997065 -> 4.074207342968196863070496994457E-26 Inexact Rounded
+dvix3031 divideint -92980.68431371090354435763218439 -2282178507046019721925800997065 -> 0
+mulx3031 multiply -92980.68431371090354435763218439 -2282178507046019721925800997065 -> 2.121985193111820147170707717938E+35 Inexact Rounded
+powx3031 power -92980.68431371090354435763218439 -2 -> 1.156683455371909793870207184337E-10 Inexact Rounded
+remx3031 remainder -92980.68431371090354435763218439 -2282178507046019721925800997065 -> -92980.68431371090354435763218439
+subx3031 subtract -92980.68431371090354435763218439 -2282178507046019721925800997065 -> 2282178507046019721925800904084 Inexact Rounded
+addx3032 add 12135817762.27858606259822256987E+738 98.35649167872356132249561021910E-902 -> 1.213581776227858606259822256987E+748 Inexact Rounded
+comx3032 compare 12135817762.27858606259822256987E+738 98.35649167872356132249561021910E-902 -> 1
+divx3032 divide 12135817762.27858606259822256987E+738 98.35649167872356132249561021910E-902 -> 1.233860374149945561886955398724E+1648 Inexact Rounded
+dvix3032 divideint 12135817762.27858606259822256987E+738 98.35649167872356132249561021910E-902 -> NaN Division_impossible
+mulx3032 multiply 12135817762.27858606259822256987E+738 98.35649167872356132249561021910E-902 -> 1.193636458750059340733188876015E-152 Inexact Rounded
+powx3032 power 12135817762.27858606259822256987E+738 10 -> 6.929317520577437720457517499936E+7480 Inexact Rounded
+remx3032 remainder 12135817762.27858606259822256987E+738 98.35649167872356132249561021910E-902 -> NaN Division_impossible
+subx3032 subtract 12135817762.27858606259822256987E+738 98.35649167872356132249561021910E-902 -> 1.213581776227858606259822256987E+748 Inexact Rounded
+addx3033 add 37.27457578793521166809739140081 -392550.4790095035979998355569916 -> -392513.2044337156627881674596002 Inexact Rounded
+comx3033 compare 37.27457578793521166809739140081 -392550.4790095035979998355569916 -> 1
+divx3033 divide 37.27457578793521166809739140081 -392550.4790095035979998355569916 -> -0.00009495486002714264641177211062199 Inexact Rounded
+dvix3033 divideint 37.27457578793521166809739140081 -392550.4790095035979998355569916 -> -0
+mulx3033 multiply 37.27457578793521166809739140081 -392550.4790095035979998355569916 -> -14632152.58043001234518095997140 Inexact Rounded
+powx3033 power 37.27457578793521166809739140081 -392550 -> 0E-10029 Underflow Subnormal Inexact Rounded Clamped
+remx3033 remainder 37.27457578793521166809739140081 -392550.4790095035979998355569916 -> 37.27457578793521166809739140081
+subx3033 subtract 37.27457578793521166809739140081 -392550.4790095035979998355569916 -> 392587.7535852915332115036543830 Inexact Rounded
+addx3034 add -2787.980590304199878755265273703 7117631179305319208210387565324 -> 7117631179305319208210387562536 Inexact Rounded
+comx3034 compare -2787.980590304199878755265273703 7117631179305319208210387565324 -> -1
+divx3034 divide -2787.980590304199878755265273703 7117631179305319208210387565324 -> -3.917006262435063093475140250870E-28 Inexact Rounded
+dvix3034 divideint -2787.980590304199878755265273703 7117631179305319208210387565324 -> -0
+mulx3034 multiply -2787.980590304199878755265273703 7117631179305319208210387565324 -> -1.984381757684722217801410305714E+34 Inexact Rounded
+powx3034 power -2787.980590304199878755265273703 7 -> -1309266999233099220127139.440082 Inexact Rounded
+remx3034 remainder -2787.980590304199878755265273703 7117631179305319208210387565324 -> -2787.980590304199878755265273703
+subx3034 subtract -2787.980590304199878755265273703 7117631179305319208210387565324 -> -7117631179305319208210387568112 Inexact Rounded
+addx3035 add -9890633.854609434943559831911276E+971 -1939985729.436827777055699361237 -> -9.890633854609434943559831911276E+977 Inexact Rounded
+comx3035 compare -9890633.854609434943559831911276E+971 -1939985729.436827777055699361237 -> -1
+divx3035 divide -9890633.854609434943559831911276E+971 -1939985729.436827777055699361237 -> 5.098302376420396260404821158158E+968 Inexact Rounded
+dvix3035 divideint -9890633.854609434943559831911276E+971 -1939985729.436827777055699361237 -> NaN Division_impossible
+mulx3035 multiply -9890633.854609434943559831911276E+971 -1939985729.436827777055699361237 -> 1.918768853302706825964087702307E+987 Inexact Rounded
+powx3035 power -9890633.854609434943559831911276E+971 -2 -> 1.022237362667592867768511487814E-1956 Inexact Rounded
+remx3035 remainder -9890633.854609434943559831911276E+971 -1939985729.436827777055699361237 -> NaN Division_impossible
+subx3035 subtract -9890633.854609434943559831911276E+971 -1939985729.436827777055699361237 -> -9.890633854609434943559831911276E+977 Inexact Rounded
+addx3036 add 3944570323.331121750661920475191 -17360722.28878145641394962484366 -> 3927209601.042340294247970850347 Inexact Rounded
+comx3036 compare 3944570323.331121750661920475191 -17360722.28878145641394962484366 -> 1
+divx3036 divide 3944570323.331121750661920475191 -17360722.28878145641394962484366 -> -227.2123393091837706827708196101 Inexact Rounded
+dvix3036 divideint 3944570323.331121750661920475191 -17360722.28878145641394962484366 -> -227
+mulx3036 multiply 3944570323.331121750661920475191 -17360722.28878145641394962484366 -> -68480589931920481.56020043213767 Inexact Rounded
+powx3036 power 3944570323.331121750661920475191 -17360722 -> 0E-10029 Underflow Subnormal Inexact Rounded Clamped
+remx3036 remainder 3944570323.331121750661920475191 -17360722.28878145641394962484366 -> 3686363.77773114469535563568018
+subx3036 subtract 3944570323.331121750661920475191 -17360722.28878145641394962484366 -> 3961931045.619903207075870100035 Inexact Rounded
+addx3037 add 19544.14018503427029002552872707 1786697762.885178994182133839546 -> 1786717307.025364028452423865075 Inexact Rounded
+comx3037 compare 19544.14018503427029002552872707 1786697762.885178994182133839546 -> -1
+divx3037 divide 19544.14018503427029002552872707 1786697762.885178994182133839546 -> 0.00001093869404832867759234359871991 Inexact Rounded
+dvix3037 divideint 19544.14018503427029002552872707 1786697762.885178994182133839546 -> 0
+mulx3037 multiply 19544.14018503427029002552872707 1786697762.885178994182133839546 -> 34919471546115.05897163496162290 Inexact Rounded
+powx3037 power 19544.14018503427029002552872707 2 -> 381973415.5722714009298802557940 Inexact Rounded
+remx3037 remainder 19544.14018503427029002552872707 1786697762.885178994182133839546 -> 19544.14018503427029002552872707
+subx3037 subtract 19544.14018503427029002552872707 1786697762.885178994182133839546 -> -1786678218.744993959911843814017 Inexact Rounded
+addx3038 add -05.75485957937617757983513662981 5564476875.989640431173694372083 -> 5564476870.234780851797516792248 Inexact Rounded
+comx3038 compare -05.75485957937617757983513662981 5564476875.989640431173694372083 -> -1
+divx3038 divide -05.75485957937617757983513662981 5564476875.989640431173694372083 -> -1.034213944568271324841608825136E-9 Inexact Rounded
+dvix3038 divideint -05.75485957937617757983513662981 5564476875.989640431173694372083 -> -0
+mulx3038 multiply -05.75485957937617757983513662981 5564476875.989640431173694372083 -> -32022783054.00620878436398990135 Inexact Rounded
+powx3038 power -05.75485957937617757983513662981 6 -> 36325.23118223611421303238908472 Inexact Rounded
+remx3038 remainder -05.75485957937617757983513662981 5564476875.989640431173694372083 -> -5.75485957937617757983513662981
+subx3038 subtract -05.75485957937617757983513662981 5564476875.989640431173694372083 -> -5564476881.744500010549871951918 Inexact Rounded
+addx3039 add -4208820.898718069194008526302746 626887.7553774705678201112845462E+206 -> 6.268877553774705678201112845462E+211 Inexact Rounded
+comx3039 compare -4208820.898718069194008526302746 626887.7553774705678201112845462E+206 -> -1
+divx3039 divide -4208820.898718069194008526302746 626887.7553774705678201112845462E+206 -> -6.713834913211527184907421856434E-206 Inexact Rounded
+dvix3039 divideint -4208820.898718069194008526302746 626887.7553774705678201112845462E+206 -> -0
+mulx3039 multiply -4208820.898718069194008526302746 626887.7553774705678201112845462E+206 -> -2.638458285983158789458925170267E+218 Inexact Rounded
+powx3039 power -4208820.898718069194008526302746 6 -> 5.558564783291260359142223337994E+39 Inexact Rounded
+remx3039 remainder -4208820.898718069194008526302746 626887.7553774705678201112845462E+206 -> -4208820.898718069194008526302746
+subx3039 subtract -4208820.898718069194008526302746 626887.7553774705678201112845462E+206 -> -6.268877553774705678201112845462E+211 Inexact Rounded
+addx3040 add -70077195478066.30896979085821269E+549 4607.163248554155483681430013073 -> -7.007719547806630896979085821269E+562 Inexact Rounded
+comx3040 compare -70077195478066.30896979085821269E+549 4607.163248554155483681430013073 -> -1
+divx3040 divide -70077195478066.30896979085821269E+549 4607.163248554155483681430013073 -> -1.521048673498997627360230078306E+559 Inexact Rounded
+dvix3040 divideint -70077195478066.30896979085821269E+549 4607.163248554155483681430013073 -> NaN Division_impossible
+mulx3040 multiply -70077195478066.30896979085821269E+549 4607.163248554155483681430013073 -> -3.228570795682925509478191397878E+566 Inexact Rounded
+powx3040 power -70077195478066.30896979085821269E+549 4607 -> -Infinity Overflow Inexact Rounded
+remx3040 remainder -70077195478066.30896979085821269E+549 4607.163248554155483681430013073 -> NaN Division_impossible
+subx3040 subtract -70077195478066.30896979085821269E+549 4607.163248554155483681430013073 -> -7.007719547806630896979085821269E+562 Inexact Rounded
+addx3041 add -442941.7541811527940918244383454 -068126768.0563559819156379151016 -> -68569709.81053713470972973953995 Inexact Rounded
+comx3041 compare -442941.7541811527940918244383454 -068126768.0563559819156379151016 -> 1
+divx3041 divide -442941.7541811527940918244383454 -068126768.0563559819156379151016 -> 0.006501728568934042143913111768557 Inexact Rounded
+dvix3041 divideint -442941.7541811527940918244383454 -068126768.0563559819156379151016 -> 0
+mulx3041 multiply -442941.7541811527940918244383454 -068126768.0563559819156379151016 -> 30176190149574.84386395947593970 Inexact Rounded
+powx3041 power -442941.7541811527940918244383454 -68126768 -> 0E-10029 Underflow Subnormal Inexact Rounded Clamped
+remx3041 remainder -442941.7541811527940918244383454 -068126768.0563559819156379151016 -> -442941.7541811527940918244383454
+subx3041 subtract -442941.7541811527940918244383454 -068126768.0563559819156379151016 -> 67683826.30217482912154609066325 Inexact Rounded
+addx3042 add -040726778711.8677615616711676159 299691.9430345259174614997064916 -> -40726479019.92472703575370611619 Inexact Rounded
+comx3042 compare -040726778711.8677615616711676159 299691.9430345259174614997064916 -> -1
+divx3042 divide -040726778711.8677615616711676159 299691.9430345259174614997064916 -> -135895.4741975690872548233111888 Inexact Rounded
+dvix3042 divideint -040726778711.8677615616711676159 299691.9430345259174614997064916 -> -135895
+mulx3042 multiply -040726778711.8677615616711676159 299691.9430345259174614997064916 -> -12205487445696816.02175665622242 Inexact Rounded
+powx3042 power -040726778711.8677615616711676159 299692 -> Infinity Overflow Inexact Rounded
+remx3042 remainder -040726778711.8677615616711676159 299691.9430345259174614997064916 -> -142113.1908620082406650022240180
+subx3042 subtract -040726778711.8677615616711676159 299691.9430345259174614997064916 -> -40727078403.81079608758862911561 Inexact Rounded
+addx3043 add -1934197520.738366912179143085955 3.810751422515178400293693371519 -> -1934197516.927615489663964685661 Inexact Rounded
+comx3043 compare -1934197520.738366912179143085955 3.810751422515178400293693371519 -> -1
+divx3043 divide -1934197520.738366912179143085955 3.810751422515178400293693371519 -> -507563287.7312566071537233697473 Inexact Rounded
+dvix3043 divideint -1934197520.738366912179143085955 3.810751422515178400293693371519 -> -507563287
+mulx3043 multiply -1934197520.738366912179143085955 3.810751422515178400293693371519 -> -7370745953.579062985130438309023 Inexact Rounded
+powx3043 power -1934197520.738366912179143085955 4 -> 1.399597922275400947497855539475E+37 Inexact Rounded
+remx3043 remainder -1934197520.738366912179143085955 3.810751422515178400293693371519 -> -2.786637155934674312936704177047
+subx3043 subtract -1934197520.738366912179143085955 3.810751422515178400293693371519 -> -1934197524.549118334694321486249 Inexact Rounded
+addx3044 add 813262.7723533833038829559646830 -303284822716.8282178131118185907 -> -303284009454.0558644298079356347 Inexact Rounded
+comx3044 compare 813262.7723533833038829559646830 -303284822716.8282178131118185907 -> 1
+divx3044 divide 813262.7723533833038829559646830 -303284822716.8282178131118185907 -> -0.000002681514904267770294213381485108 Inexact Rounded
+dvix3044 divideint 813262.7723533833038829559646830 -303284822716.8282178131118185907 -> -0
+mulx3044 multiply 813262.7723533833038829559646830 -303284822716.8282178131118185907 -> -246650255735392080.1357404280431 Inexact Rounded
+powx3044 power 813262.7723533833038829559646830 -3 -> 1.859119568310997605545914895133E-18 Inexact Rounded
+remx3044 remainder 813262.7723533833038829559646830 -303284822716.8282178131118185907 -> 813262.7723533833038829559646830
+subx3044 subtract 813262.7723533833038829559646830 -303284822716.8282178131118185907 -> 303285635979.6005711964157015467 Inexact Rounded
+addx3045 add 36105954884.94621434979365589311 745558205.7692397481313005659523E-952 -> 36105954884.94621434979365589311 Inexact Rounded
+comx3045 compare 36105954884.94621434979365589311 745558205.7692397481313005659523E-952 -> 1
+divx3045 divide 36105954884.94621434979365589311 745558205.7692397481313005659523E-952 -> 4.842808328786805821411674302686E+953 Inexact Rounded
+dvix3045 divideint 36105954884.94621434979365589311 745558205.7692397481313005659523E-952 -> NaN Division_impossible
+mulx3045 multiply 36105954884.94621434979365589311 745558205.7692397481313005659523E-952 -> 2.691909094160561673391352743869E-933 Inexact Rounded
+powx3045 power 36105954884.94621434979365589311 7 -> 7.999297449713301719582732447386E+73 Inexact Rounded
+remx3045 remainder 36105954884.94621434979365589311 745558205.7692397481313005659523E-952 -> NaN Division_impossible
+subx3045 subtract 36105954884.94621434979365589311 745558205.7692397481313005659523E-952 -> 36105954884.94621434979365589311 Inexact Rounded
+addx3046 add -075537177538.1814516621962185490 26980775255.51542856483122484898 -> -48556402282.66602309736499370002
+comx3046 compare -075537177538.1814516621962185490 26980775255.51542856483122484898 -> -1
+divx3046 divide -075537177538.1814516621962185490 26980775255.51542856483122484898 -> -2.799666682029089956269018541649 Inexact Rounded
+dvix3046 divideint -075537177538.1814516621962185490 26980775255.51542856483122484898 -> -2
+mulx3046 multiply -075537177538.1814516621962185490 26980775255.51542856483122484898 -> -2038051610593641947717.268652175 Inexact Rounded
+powx3046 power -075537177538.1814516621962185490 3 -> -4.310049518987988084595264617727E+32 Inexact Rounded
+remx3046 remainder -075537177538.1814516621962185490 26980775255.51542856483122484898 -> -21575627027.15059453253376885104
+subx3046 subtract -075537177538.1814516621962185490 26980775255.51542856483122484898 -> -102517952793.6968802270274433980 Inexact Rounded
+addx3047 add -4223765.415319564898840040697647 -2590590305497454185455459149918E-215 -> -4223765.415319564898840040697647 Inexact Rounded
+comx3047 compare -4223765.415319564898840040697647 -2590590305497454185455459149918E-215 -> -1
+divx3047 divide -4223765.415319564898840040697647 -2590590305497454185455459149918E-215 -> 1.630425855588347356570076909053E+191 Inexact Rounded
+dvix3047 divideint -4223765.415319564898840040697647 -2590590305497454185455459149918E-215 -> NaN Division_impossible
+mulx3047 multiply -4223765.415319564898840040697647 -2590590305497454185455459149918E-215 -> 1.094204573762229308798604845395E-178 Inexact Rounded
+powx3047 power -4223765.415319564898840040697647 -3 -> -1.327090775863616939309569791138E-20 Inexact Rounded
+remx3047 remainder -4223765.415319564898840040697647 -2590590305497454185455459149918E-215 -> NaN Division_impossible
+subx3047 subtract -4223765.415319564898840040697647 -2590590305497454185455459149918E-215 -> -4223765.415319564898840040697647 Inexact Rounded
+addx3048 add -6468.903738522951259063099946195 -7877.324314273694312164407794939E+267 -> -7.877324314273694312164407794939E+270 Inexact Rounded
+comx3048 compare -6468.903738522951259063099946195 -7877.324314273694312164407794939E+267 -> 1
+divx3048 divide -6468.903738522951259063099946195 -7877.324314273694312164407794939E+267 -> 8.212057140774706874666307246628E-268 Inexact Rounded
+dvix3048 divideint -6468.903738522951259063099946195 -7877.324314273694312164407794939E+267 -> 0
+mulx3048 multiply -6468.903738522951259063099946195 -7877.324314273694312164407794939E+267 -> 5.095765270616284455922747530676E+274 Inexact Rounded
+powx3048 power -6468.903738522951259063099946195 -8 -> 3.261027724982089298030362367616E-31 Inexact Rounded
+remx3048 remainder -6468.903738522951259063099946195 -7877.324314273694312164407794939E+267 -> -6468.903738522951259063099946195
+subx3048 subtract -6468.903738522951259063099946195 -7877.324314273694312164407794939E+267 -> 7.877324314273694312164407794939E+270 Inexact Rounded
+addx3049 add -9567221.183663236817239254783372E-203 1650.198961256061165362319471264 -> 1650.198961256061165362319471264 Inexact Rounded
+comx3049 compare -9567221.183663236817239254783372E-203 1650.198961256061165362319471264 -> -1
+divx3049 divide -9567221.183663236817239254783372E-203 1650.198961256061165362319471264 -> -5.797616777301250711985729776957E-200 Inexact Rounded
+dvix3049 divideint -9567221.183663236817239254783372E-203 1650.198961256061165362319471264 -> -0
+mulx3049 multiply -9567221.183663236817239254783372E-203 1650.198961256061165362319471264 -> -1.578781845938805737527304303976E-193 Inexact Rounded
+powx3049 power -9567221.183663236817239254783372E-203 1650 -> 0E-10029 Underflow Subnormal Inexact Rounded Clamped
+remx3049 remainder -9567221.183663236817239254783372E-203 1650.198961256061165362319471264 -> -9.567221183663236817239254783372E-197
+subx3049 subtract -9567221.183663236817239254783372E-203 1650.198961256061165362319471264 -> -1650.198961256061165362319471264 Inexact Rounded
+addx3050 add 8812306098770.200752139142033569E-428 26790.17380163975186972720427030E+568 -> 2.679017380163975186972720427030E+572 Inexact Rounded
+comx3050 compare 8812306098770.200752139142033569E-428 26790.17380163975186972720427030E+568 -> -1
+divx3050 divide 8812306098770.200752139142033569E-428 26790.17380163975186972720427030E+568 -> 3.289379965960065573444140749635E-988 Inexact Rounded
+dvix3050 divideint 8812306098770.200752139142033569E-428 26790.17380163975186972720427030E+568 -> 0
+mulx3050 multiply 8812306098770.200752139142033569E-428 26790.17380163975186972720427030E+568 -> 2.360832119793036398127652187732E+157 Inexact Rounded
+powx3050 power 8812306098770.200752139142033569E-428 3 -> 6.843349527476967274129043949969E-1246 Inexact Rounded
+remx3050 remainder 8812306098770.200752139142033569E-428 26790.17380163975186972720427030E+568 -> 8.812306098770200752139142033569E-416
+subx3050 subtract 8812306098770.200752139142033569E-428 26790.17380163975186972720427030E+568 -> -2.679017380163975186972720427030E+572 Inexact Rounded
+addx3051 add 80108033.12724838718736922500904 -706207255092.7645192310078892869 -> -706127147059.6372708438205200619 Inexact Rounded
+comx3051 compare 80108033.12724838718736922500904 -706207255092.7645192310078892869 -> 1
+divx3051 divide 80108033.12724838718736922500904 -706207255092.7645192310078892869 -> -0.0001134341690057060105325397863996 Inexact Rounded
+dvix3051 divideint 80108033.12724838718736922500904 -706207255092.7645192310078892869 -> -0
+mulx3051 multiply 80108033.12724838718736922500904 -706207255092.7645192310078892869 -> -56572874185674332398.36004114372 Inexact Rounded
+powx3051 power 80108033.12724838718736922500904 -7 -> 4.723539145042336483008674060324E-56 Inexact Rounded
+remx3051 remainder 80108033.12724838718736922500904 -706207255092.7645192310078892869 -> 80108033.12724838718736922500904
+subx3051 subtract 80108033.12724838718736922500904 -706207255092.7645192310078892869 -> 706287363125.8917676181952585119 Inexact Rounded
+addx3052 add -37942846282.76101663789059003505 -5.649456053942850351313869983197 -> -37942846288.41047269183344038636 Inexact Rounded
+comx3052 compare -37942846282.76101663789059003505 -5.649456053942850351313869983197 -> -1
+divx3052 divide -37942846282.76101663789059003505 -5.649456053942850351313869983197 -> 6716194607.139224735032566328960 Inexact Rounded
+dvix3052 divideint -37942846282.76101663789059003505 -5.649456053942850351313869983197 -> 6716194607
+mulx3052 multiply -37942846282.76101663789059003505 -5.649456053942850351313869983197 -> 214356442635.9672009449140933366 Inexact Rounded
+powx3052 power -37942846282.76101663789059003505 -6 -> 3.351355986382646046773008753885E-64 Inexact Rounded
+remx3052 remainder -37942846282.76101663789059003505 -5.649456053942850351313869983197 -> -0.786544022188321089603127981421
+subx3052 subtract -37942846282.76101663789059003505 -5.649456053942850351313869983197 -> -37942846277.11156058394773968374 Inexact Rounded
+addx3053 add 92659632115305.13735437728445541 6483438.317862851676468094261410E-139 -> 92659632115305.13735437728445541 Inexact Rounded
+comx3053 compare 92659632115305.13735437728445541 6483438.317862851676468094261410E-139 -> 1
+divx3053 divide 92659632115305.13735437728445541 6483438.317862851676468094261410E-139 -> 1.429174267919135710410529211791E+146 Inexact Rounded
+dvix3053 divideint 92659632115305.13735437728445541 6483438.317862851676468094261410E-139 -> NaN Division_impossible
+mulx3053 multiply 92659632115305.13735437728445541 6483438.317862851676468094261410E-139 -> 6.007530093754446085819255987878E-119 Inexact Rounded
+powx3053 power 92659632115305.13735437728445541 6 -> 6.329121451953461546696051563323E+83 Inexact Rounded
+remx3053 remainder 92659632115305.13735437728445541 6483438.317862851676468094261410E-139 -> NaN Division_impossible
+subx3053 subtract 92659632115305.13735437728445541 6483438.317862851676468094261410E-139 -> 92659632115305.13735437728445541 Inexact Rounded
+addx3054 add 2838948.589837595494152150647194 569547026247.5469563701415715960 -> 569549865196.1367939656357237466 Inexact Rounded
+comx3054 compare 2838948.589837595494152150647194 569547026247.5469563701415715960 -> -1
+divx3054 divide 2838948.589837595494152150647194 569547026247.5469563701415715960 -> 0.000004984572755198057481907281080406 Inexact Rounded
+dvix3054 divideint 2838948.589837595494152150647194 569547026247.5469563701415715960 -> 0
+mulx3054 multiply 2838948.589837595494152150647194 569547026247.5469563701415715960 -> 1616914727011669419.390959984273 Inexact Rounded
+powx3054 power 2838948.589837595494152150647194 6 -> 5.235343334986059753096884080673E+38 Inexact Rounded
+remx3054 remainder 2838948.589837595494152150647194 569547026247.5469563701415715960 -> 2838948.589837595494152150647194
+subx3054 subtract 2838948.589837595494152150647194 569547026247.5469563701415715960 -> -569544187298.9571187746474194454 Inexact Rounded
+addx3055 add 524995204523.6053307941775794287E+694 1589600879689517100527293028553 -> 5.249952045236053307941775794287E+705 Inexact Rounded
+comx3055 compare 524995204523.6053307941775794287E+694 1589600879689517100527293028553 -> 1
+divx3055 divide 524995204523.6053307941775794287E+694 1589600879689517100527293028553 -> 3.302685669286670708554753139233E+675 Inexact Rounded
+dvix3055 divideint 524995204523.6053307941775794287E+694 1589600879689517100527293028553 -> NaN Division_impossible
+mulx3055 multiply 524995204523.6053307941775794287E+694 1589600879689517100527293028553 -> 8.345328389435009812933599889447E+735 Inexact Rounded
+powx3055 power 524995204523.6053307941775794287E+694 2 -> 2.756199647727821911857160230849E+1411 Inexact Rounded
+remx3055 remainder 524995204523.6053307941775794287E+694 1589600879689517100527293028553 -> NaN Division_impossible
+subx3055 subtract 524995204523.6053307941775794287E+694 1589600879689517100527293028553 -> 5.249952045236053307941775794287E+705 Inexact Rounded
+addx3056 add -57131573677452.15449921725097290 4669681430736.326858508715643769 -> -52461892246715.82764070853532913 Inexact Rounded
+comx3056 compare -57131573677452.15449921725097290 4669681430736.326858508715643769 -> -1
+divx3056 divide -57131573677452.15449921725097290 4669681430736.326858508715643769 -> -12.23457628210057733643575143694 Inexact Rounded
+dvix3056 divideint -57131573677452.15449921725097290 4669681430736.326858508715643769 -> -12
+mulx3056 multiply -57131573677452.15449921725097290 4669681430736.326858508715643769 -> -266786248710342647746063322.0544 Inexact Rounded
+powx3056 power -57131573677452.15449921725097290 5 -> -6.086686503752679375430019503679E+68 Inexact Rounded
+remx3056 remainder -57131573677452.15449921725097290 4669681430736.326858508715643769 -> -1095396508616.232197112663247672
+subx3056 subtract -57131573677452.15449921725097290 4669681430736.326858508715643769 -> -61801255108188.48135772596661667 Inexact Rounded
+addx3057 add 90794826.55528018781830463383411 -5.471502270351231110027647216128 -> 90794821.08377791746707352380646 Inexact Rounded
+comx3057 compare 90794826.55528018781830463383411 -5.471502270351231110027647216128 -> 1
+divx3057 divide 90794826.55528018781830463383411 -5.471502270351231110027647216128 -> -16594131.20365054928428313232246 Inexact Rounded
+dvix3057 divideint 90794826.55528018781830463383411 -5.471502270351231110027647216128 -> -16594131
+mulx3057 multiply 90794826.55528018781830463383411 -5.471502270351231110027647216128 -> -496784099.6333617958496589124964 Inexact Rounded
+powx3057 power 90794826.55528018781830463383411 -5 -> 1.620669590532856523565742953997E-40 Inexact Rounded
+remx3057 remainder 90794826.55528018781830463383411 -5.471502270351231110027647216128 -> 1.114274442767230442307896655232
+subx3057 subtract 90794826.55528018781830463383411 -5.471502270351231110027647216128 -> 90794832.02678245816953574386176 Inexact Rounded
+addx3058 add 58508794729.35191160840980489138 -47060867.24988279680824397447551 -> 58461733862.10202881160156091690 Inexact Rounded
+comx3058 compare 58508794729.35191160840980489138 -47060867.24988279680824397447551 -> 1
+divx3058 divide 58508794729.35191160840980489138 -47060867.24988279680824397447551 -> -1243.257894477021678809337875304 Inexact Rounded
+dvix3058 divideint 58508794729.35191160840980489138 -47060867.24988279680824397447551 -> -1243
+mulx3058 multiply 58508794729.35191160840980489138 -47060867.24988279680824397447551 -> -2753474621708672573.249029643967 Inexact Rounded
+powx3058 power 58508794729.35191160840980489138 -47060867 -> 0E-10029 Underflow Subnormal Inexact Rounded Clamped
+remx3058 remainder 58508794729.35191160840980489138 -47060867.24988279680824397447551 -> 12136737.74759517576254461832107
+subx3058 subtract 58508794729.35191160840980489138 -47060867.24988279680824397447551 -> 58555855596.60179440521804886586 Inexact Rounded
+addx3059 add -746104.0768078474426464219416332E+006 9595418.300613754556671852801667E+385 -> 9.595418300613754556671852801667E+391 Inexact Rounded
+comx3059 compare -746104.0768078474426464219416332E+006 9595418.300613754556671852801667E+385 -> -1
+divx3059 divide -746104.0768078474426464219416332E+006 9595418.300613754556671852801667E+385 -> -7.775628465932789700547872511745E-381 Inexact Rounded
+dvix3059 divideint -746104.0768078474426464219416332E+006 9595418.300613754556671852801667E+385 -> -0
+mulx3059 multiply -746104.0768078474426464219416332E+006 9595418.300613754556671852801667E+385 -> -7.159180712764549711669939947084E+403 Inexact Rounded
+powx3059 power -746104.0768078474426464219416332E+006 10 -> 5.345571346302582882805035996696E+118 Inexact Rounded
+remx3059 remainder -746104.0768078474426464219416332E+006 9595418.300613754556671852801667E+385 -> -746104076807.8474426464219416332
+subx3059 subtract -746104.0768078474426464219416332E+006 9595418.300613754556671852801667E+385 -> -9.595418300613754556671852801667E+391 Inexact Rounded
+addx3060 add 55.99427632688387400403789659459E+119 -9.170530450881612853998489340127 -> 5.599427632688387400403789659459E+120 Inexact Rounded
+comx3060 compare 55.99427632688387400403789659459E+119 -9.170530450881612853998489340127 -> 1
+divx3060 divide 55.99427632688387400403789659459E+119 -9.170530450881612853998489340127 -> -6.105892851759828176655685111491E+119 Inexact Rounded
+dvix3060 divideint 55.99427632688387400403789659459E+119 -9.170530450881612853998489340127 -> NaN Division_impossible
+mulx3060 multiply 55.99427632688387400403789659459E+119 -9.170530450881612853998489340127 -> -5.134972161307679939281170944556E+121 Inexact Rounded
+powx3060 power 55.99427632688387400403789659459E+119 -9 -> 1.848022584764384077672041056396E-1087 Inexact Rounded
+remx3060 remainder 55.99427632688387400403789659459E+119 -9.170530450881612853998489340127 -> NaN Division_impossible
+subx3060 subtract 55.99427632688387400403789659459E+119 -9.170530450881612853998489340127 -> 5.599427632688387400403789659459E+120 Inexact Rounded
+addx3061 add -41214265628.83801241467317270595 1015336323798389903361978271354 -> 1015336323798389903320764005725 Inexact Rounded
+comx3061 compare -41214265628.83801241467317270595 1015336323798389903361978271354 -> -1
+divx3061 divide -41214265628.83801241467317270595 1015336323798389903361978271354 -> -4.059173759750342247620706384027E-20 Inexact Rounded
+dvix3061 divideint -41214265628.83801241467317270595 1015336323798389903361978271354 -> -0
+mulx3061 multiply -41214265628.83801241467317270595 1015336323798389903361978271354 -> -4.184634095163472384028549378392E+40 Inexact Rounded
+powx3061 power -41214265628.83801241467317270595 1 -> -41214265628.83801241467317270595
+remx3061 remainder -41214265628.83801241467317270595 1015336323798389903361978271354 -> -41214265628.83801241467317270595
+subx3061 subtract -41214265628.83801241467317270595 1015336323798389903361978271354 -> -1015336323798389903403192536983 Inexact Rounded
+addx3062 add 89937.39749201095570357557430822 82351554210093.60879476027800331 -> 82351554300031.00628677123370689 Inexact Rounded
+comx3062 compare 89937.39749201095570357557430822 82351554210093.60879476027800331 -> -1
+divx3062 divide 89937.39749201095570357557430822 82351554210093.60879476027800331 -> 1.092115362662913415592930982129E-9 Inexact Rounded
+dvix3062 divideint 89937.39749201095570357557430822 82351554210093.60879476027800331 -> 0
+mulx3062 multiply 89937.39749201095570357557430822 82351554210093.60879476027800331 -> 7406484465078077191.920015793662 Inexact Rounded
+powx3062 power 89937.39749201095570357557430822 8 -> 4.280776267723913043050100934291E+39 Inexact Rounded
+remx3062 remainder 89937.39749201095570357557430822 82351554210093.60879476027800331 -> 89937.39749201095570357557430822
+subx3062 subtract 89937.39749201095570357557430822 82351554210093.60879476027800331 -> -82351554120156.21130274932229973 Inexact Rounded
+addx3063 add 01712661.64677082156284125486943E+359 57932.78435529483241552042115837E-037 -> 1.712661646770821562841254869430E+365 Inexact Rounded
+comx3063 compare 01712661.64677082156284125486943E+359 57932.78435529483241552042115837E-037 -> 1
+divx3063 divide 01712661.64677082156284125486943E+359 57932.78435529483241552042115837E-037 -> 2.956290925475414185960999788848E+397 Inexact Rounded
+dvix3063 divideint 01712661.64677082156284125486943E+359 57932.78435529483241552042115837E-037 -> NaN Division_impossible
+mulx3063 multiply 01712661.64677082156284125486943E+359 57932.78435529483241552042115837E-037 -> 9.921925785595813587655312307930E+332 Inexact Rounded
+powx3063 power 01712661.64677082156284125486943E+359 6 -> 2.523651803323047711735501944959E+2191 Inexact Rounded
+remx3063 remainder 01712661.64677082156284125486943E+359 57932.78435529483241552042115837E-037 -> NaN Division_impossible
+subx3063 subtract 01712661.64677082156284125486943E+359 57932.78435529483241552042115837E-037 -> 1.712661646770821562841254869430E+365 Inexact Rounded
+addx3064 add -2647593306.528617691373470059213 -655531558709.4582168930191014461 -> -658179152015.9868345843925715053 Inexact Rounded
+comx3064 compare -2647593306.528617691373470059213 -655531558709.4582168930191014461 -> 1
+divx3064 divide -2647593306.528617691373470059213 -655531558709.4582168930191014461 -> 0.004038849497560303158639192895544 Inexact Rounded
+dvix3064 divideint -2647593306.528617691373470059213 -655531558709.4582168930191014461 -> 0
+mulx3064 multiply -2647593306.528617691373470059213 -655531558709.4582168930191014461 -> 1735580967057433153120.099643641 Inexact Rounded
+powx3064 power -2647593306.528617691373470059213 -7 -> -1.096581914005902583413810201571E-66 Inexact Rounded
+remx3064 remainder -2647593306.528617691373470059213 -655531558709.4582168930191014461 -> -2647593306.528617691373470059213
+subx3064 subtract -2647593306.528617691373470059213 -655531558709.4582168930191014461 -> 652883965402.9295992016456313869 Inexact Rounded
+addx3065 add 2904078690665765116603253099668E-329 -71.45586619176091599264717047885E+787 -> -7.145586619176091599264717047885E+788 Inexact Rounded
+comx3065 compare 2904078690665765116603253099668E-329 -71.45586619176091599264717047885E+787 -> 1
+divx3065 divide 2904078690665765116603253099668E-329 -71.45586619176091599264717047885E+787 -> -4.064157144036712325084472022316E-1088 Inexact Rounded
+dvix3065 divideint 2904078690665765116603253099668E-329 -71.45586619176091599264717047885E+787 -> -0
+mulx3065 multiply 2904078690665765116603253099668E-329 -71.45586619176091599264717047885E+787 -> -2.075134583305571527962710017262E+490 Inexact Rounded
+powx3065 power 2904078690665765116603253099668E-329 -7 -> 5.740389208842895561250128407803E+2089 Inexact Rounded
+remx3065 remainder 2904078690665765116603253099668E-329 -71.45586619176091599264717047885E+787 -> 2.904078690665765116603253099668E-299
+subx3065 subtract 2904078690665765116603253099668E-329 -71.45586619176091599264717047885E+787 -> 7.145586619176091599264717047885E+788 Inexact Rounded
+addx3066 add 22094338972.39109726522477999515 -409846549371.3900805039668417203E-499 -> 22094338972.39109726522477999515 Inexact Rounded
+comx3066 compare 22094338972.39109726522477999515 -409846549371.3900805039668417203E-499 -> 1
+divx3066 divide 22094338972.39109726522477999515 -409846549371.3900805039668417203E-499 -> -5.390880808019174194010224736965E+497 Inexact Rounded
+dvix3066 divideint 22094338972.39109726522477999515 -409846549371.3900805039668417203E-499 -> NaN Division_impossible
+mulx3066 multiply 22094338972.39109726522477999515 -409846549371.3900805039668417203E-499 -> -9.055288588476315822113975426730E-478 Inexact Rounded
+powx3066 power 22094338972.39109726522477999515 -4 -> 4.196391022354122686725315209967E-42 Inexact Rounded
+remx3066 remainder 22094338972.39109726522477999515 -409846549371.3900805039668417203E-499 -> NaN Division_impossible
+subx3066 subtract 22094338972.39109726522477999515 -409846549371.3900805039668417203E-499 -> 22094338972.39109726522477999515 Inexact Rounded
+addx3067 add -3374988581607586061255542201048 82293895124.90045271504836568681 -> -3374988581607586061173248305923 Inexact Rounded
+comx3067 compare -3374988581607586061255542201048 82293895124.90045271504836568681 -> -1
+divx3067 divide -3374988581607586061255542201048 82293895124.90045271504836568681 -> -41011408883796817797.81310977038 Inexact Rounded
+dvix3067 divideint -3374988581607586061255542201048 82293895124.90045271504836568681 -> -41011408883796817797
+mulx3067 multiply -3374988581607586061255542201048 82293895124.90045271504836568681 -> -2.777409563825512202793336132310E+41 Inexact Rounded
+powx3067 power -3374988581607586061255542201048 8 -> 1.683365657238878057620634207267E+244 Inexact Rounded
+remx3067 remainder -3374988581607586061255542201048 82293895124.90045271504836568681 -> -66913970168.62046257175566384243
+subx3067 subtract -3374988581607586061255542201048 82293895124.90045271504836568681 -> -3374988581607586061337836096173 Inexact Rounded
+addx3068 add -84172558160661.35863831029352323 -11271.58916600931155937291904890 -> -84172558171932.94780431960508260 Inexact Rounded
+comx3068 compare -84172558160661.35863831029352323 -11271.58916600931155937291904890 -> -1
+divx3068 divide -84172558160661.35863831029352323 -11271.58916600931155937291904890 -> 7467674426.467986736459678347587 Inexact Rounded
+dvix3068 divideint -84172558160661.35863831029352323 -11271.58916600931155937291904890 -> 7467674426
+mulx3068 multiply -84172558160661.35863831029352323 -11271.58916600931155937291904890 -> 948758494638999235.1953022970755 Inexact Rounded
+powx3068 power -84172558160661.35863831029352323 -11272 -> 0E-10029 Underflow Subnormal Inexact Rounded Clamped
+remx3068 remainder -84172558160661.35863831029352323 -11271.58916600931155937291904890 -> -5274.95422851496534479122656860
+subx3068 subtract -84172558160661.35863831029352323 -11271.58916600931155937291904890 -> -84172558149389.76947230098196386 Inexact Rounded
+addx3069 add -70046932324614.90596396237508541E-568 33.63163964004608865836577297698E-918 -> -7.004693232461490596396237508541E-555 Inexact Rounded
+comx3069 compare -70046932324614.90596396237508541E-568 33.63163964004608865836577297698E-918 -> -1
+divx3069 divide -70046932324614.90596396237508541E-568 33.63163964004608865836577297698E-918 -> -2.082768876995463487926920072359E+362 Inexact Rounded
+dvix3069 divideint -70046932324614.90596396237508541E-568 33.63163964004608865836577297698E-918 -> NaN Division_impossible
+mulx3069 multiply -70046932324614.90596396237508541E-568 33.63163964004608865836577297698E-918 -> -2.355793185832144388285949021738E-1471 Inexact Rounded
+powx3069 power -70046932324614.90596396237508541E-568 3 -> -3.436903678302639677280508409829E-1663 Inexact Rounded
+remx3069 remainder -70046932324614.90596396237508541E-568 33.63163964004608865836577297698E-918 -> NaN Division_impossible
+subx3069 subtract -70046932324614.90596396237508541E-568 33.63163964004608865836577297698E-918 -> -7.004693232461490596396237508541E-555 Inexact Rounded
+addx3070 add 0004125384407.053782660115680886 -391429084.5847321402514385603223E-648 -> 4125384407.053782660115680886000 Inexact Rounded
+comx3070 compare 0004125384407.053782660115680886 -391429084.5847321402514385603223E-648 -> 1
+divx3070 divide 0004125384407.053782660115680886 -391429084.5847321402514385603223E-648 -> -1.053928941287132717250540955457E+649 Inexact Rounded
+dvix3070 divideint 0004125384407.053782660115680886 -391429084.5847321402514385603223E-648 -> NaN Division_impossible
+mulx3070 multiply 0004125384407.053782660115680886 -391429084.5847321402514385603223E-648 -> -1.614795442013190139080634449273E-630 Inexact Rounded
+powx3070 power 0004125384407.053782660115680886 -4 -> 3.452568541597450106266555783362E-39 Inexact Rounded
+remx3070 remainder 0004125384407.053782660115680886 -391429084.5847321402514385603223E-648 -> NaN Division_impossible
+subx3070 subtract 0004125384407.053782660115680886 -391429084.5847321402514385603223E-648 -> 4125384407.053782660115680886000 Inexact Rounded
+addx3071 add -31823131.15691583393820628480997E-440 92913.91582947237200286427030028E+771 -> 9.291391582947237200286427030028E+775 Inexact Rounded
+comx3071 compare -31823131.15691583393820628480997E-440 92913.91582947237200286427030028E+771 -> -1
+divx3071 divide -31823131.15691583393820628480997E-440 92913.91582947237200286427030028E+771 -> -3.425012375468251447194400841658E-1209 Inexact Rounded
+dvix3071 divideint -31823131.15691583393820628480997E-440 92913.91582947237200286427030028E+771 -> -0
+mulx3071 multiply -31823131.15691583393820628480997E-440 92913.91582947237200286427030028E+771 -> -2.956811729743937541973845029816E+343 Inexact Rounded
+powx3071 power -31823131.15691583393820628480997E-440 9 -> -3.347234803487575870321338308655E-3893 Inexact Rounded
+remx3071 remainder -31823131.15691583393820628480997E-440 92913.91582947237200286427030028E+771 -> -3.182313115691583393820628480997E-433
+subx3071 subtract -31823131.15691583393820628480997E-440 92913.91582947237200286427030028E+771 -> -9.291391582947237200286427030028E+775 Inexact Rounded
+addx3072 add 55573867888.91575330563698128150 599.5231614736232188354393212234 -> 55573868488.43891477926020011694 Inexact Rounded
+comx3072 compare 55573867888.91575330563698128150 599.5231614736232188354393212234 -> 1
+divx3072 divide 55573867888.91575330563698128150 599.5231614736232188354393212234 -> 92696782.14318796763098335498657 Inexact Rounded
+dvix3072 divideint 55573867888.91575330563698128150 599.5231614736232188354393212234 -> 92696782
+mulx3072 multiply 55573867888.91575330563698128150 599.5231614736232188354393212234 -> 33317820972080.24347717542221477 Inexact Rounded
+powx3072 power 55573867888.91575330563698128150 600 -> 8.363240671070136278221965616973E+6446 Inexact Rounded
+remx3072 remainder 55573867888.91575330563698128150 599.5231614736232188354393212234 -> 85.8445030391099686478265169012
+subx3072 subtract 55573867888.91575330563698128150 599.5231614736232188354393212234 -> 55573867289.39259183201376244606 Inexact Rounded
+addx3073 add -5447727448431680878699555714796E-800 5487207.142687001607026665515349E-362 -> 5.487207142687001607026665515349E-356 Inexact Rounded
+comx3073 compare -5447727448431680878699555714796E-800 5487207.142687001607026665515349E-362 -> -1
+divx3073 divide -5447727448431680878699555714796E-800 5487207.142687001607026665515349E-362 -> -9.928051387110587327889009363069E-415 Inexact Rounded
+dvix3073 divideint -5447727448431680878699555714796E-800 5487207.142687001607026665515349E-362 -> -0
+mulx3073 multiply -5447727448431680878699555714796E-800 5487207.142687001607026665515349E-362 -> -2.989280896644635352838087864373E-1125 Inexact Rounded
+powx3073 power -5447727448431680878699555714796E-800 5 -> -4.798183553278543065204833300725E-3847 Inexact Rounded
+remx3073 remainder -5447727448431680878699555714796E-800 5487207.142687001607026665515349E-362 -> -5.447727448431680878699555714796E-770
+subx3073 subtract -5447727448431680878699555714796E-800 5487207.142687001607026665515349E-362 -> -5.487207142687001607026665515349E-356 Inexact Rounded
+addx3074 add 0418349404834.547110239542290134 09819915.92405288066606124554841 -> 418359224750.4711631202083513795 Inexact Rounded
+comx3074 compare 0418349404834.547110239542290134 09819915.92405288066606124554841 -> 1
+divx3074 divide 0418349404834.547110239542290134 09819915.92405288066606124554841 -> 42602.13713335803513874339309132 Inexact Rounded
+dvix3074 divideint 0418349404834.547110239542290134 09819915.92405288066606124554841 -> 42602
+mulx3074 multiply 0418349404834.547110239542290134 09819915.92405288066606124554841 -> 4108155982352814348.343441299082 Inexact Rounded
+powx3074 power 0418349404834.547110239542290134 9819916 -> Infinity Overflow Inexact Rounded
+remx3074 remainder 0418349404834.547110239542290134 09819915.92405288066606124554841 -> 1346638.04628810400110728063718
+subx3074 subtract 0418349404834.547110239542290134 09819915.92405288066606124554841 -> 418339584918.6230573588762288885 Inexact Rounded
+addx3075 add -262021.7565194737396448014286436 -7983992600094836304387324162042E+390 -> -7.983992600094836304387324162042E+420 Inexact Rounded
+comx3075 compare -262021.7565194737396448014286436 -7983992600094836304387324162042E+390 -> 1
+divx3075 divide -262021.7565194737396448014286436 -7983992600094836304387324162042E+390 -> 3.281838669494274896180376328433E-416 Inexact Rounded
+dvix3075 divideint -262021.7565194737396448014286436 -7983992600094836304387324162042E+390 -> 0
+mulx3075 multiply -262021.7565194737396448014286436 -7983992600094836304387324162042E+390 -> 2.091979765115329268275803385534E+426 Inexact Rounded
+powx3075 power -262021.7565194737396448014286436 -8 -> 4.500918721033033032706782304195E-44 Inexact Rounded
+remx3075 remainder -262021.7565194737396448014286436 -7983992600094836304387324162042E+390 -> -262021.7565194737396448014286436
+subx3075 subtract -262021.7565194737396448014286436 -7983992600094836304387324162042E+390 -> 7.983992600094836304387324162042E+420 Inexact Rounded
+addx3076 add 48696050631.42565380301204592392E-505 -33868752339.85057267609967806187E+821 -> -3.386875233985057267609967806187E+831 Inexact Rounded
+comx3076 compare 48696050631.42565380301204592392E-505 -33868752339.85057267609967806187E+821 -> 1
+divx3076 divide 48696050631.42565380301204592392E-505 -33868752339.85057267609967806187E+821 -> -1.437786964892976582009952172420E-1326 Inexact Rounded
+dvix3076 divideint 48696050631.42565380301204592392E-505 -33868752339.85057267609967806187E+821 -> -0
+mulx3076 multiply 48696050631.42565380301204592392E-505 -33868752339.85057267609967806187E+821 -> -1.649274478764579569246425611629E+337 Inexact Rounded
+powx3076 power 48696050631.42565380301204592392E-505 -3 -> 8.660017688773759463020340778853E+1482 Inexact Rounded
+remx3076 remainder 48696050631.42565380301204592392E-505 -33868752339.85057267609967806187E+821 -> 4.869605063142565380301204592392E-495
+subx3076 subtract 48696050631.42565380301204592392E-505 -33868752339.85057267609967806187E+821 -> 3.386875233985057267609967806187E+831 Inexact Rounded
+addx3077 add 95316999.19440144356471126680708 -60791.33805057402845885978390435 -> 95256207.85635086953625240702318 Inexact Rounded
+comx3077 compare 95316999.19440144356471126680708 -60791.33805057402845885978390435 -> 1
+divx3077 divide 95316999.19440144356471126680708 -60791.33805057402845885978390435 -> -1567.937180706641856870286122623 Inexact Rounded
+dvix3077 divideint 95316999.19440144356471126680708 -60791.33805057402845885978390435 -> -1567
+mulx3077 multiply 95316999.19440144356471126680708 -60791.33805057402845885978390435 -> -5794447919993.150493301061195714 Inexact Rounded
+powx3077 power 95316999.19440144356471126680708 -60791 -> 0E-10029 Underflow Subnormal Inexact Rounded Clamped
+remx3077 remainder 95316999.19440144356471126680708 -60791.33805057402845885978390435 -> 56972.46915194096967798542896355
+subx3077 subtract 95316999.19440144356471126680708 -60791.33805057402845885978390435 -> 95377790.53245201759317012659098 Inexact Rounded
+addx3078 add -5326702296402708234722215224979E-136 8032459.450998820205916538543258 -> 8032459.450998820205916538543258 Inexact Rounded
+comx3078 compare -5326702296402708234722215224979E-136 8032459.450998820205916538543258 -> -1
+divx3078 divide -5326702296402708234722215224979E-136 8032459.450998820205916538543258 -> -6.631471131473117487839243582873E-113 Inexact Rounded
+dvix3078 divideint -5326702296402708234722215224979E-136 8032459.450998820205916538543258 -> -0
+mulx3078 multiply -5326702296402708234722215224979E-136 8032459.450998820205916538543258 -> -4.278652020339705265013632757349E-99 Inexact Rounded
+powx3078 power -5326702296402708234722215224979E-136 8032459 -> -0E-10029 Underflow Subnormal Inexact Rounded Clamped
+remx3078 remainder -5326702296402708234722215224979E-136 8032459.450998820205916538543258 -> -5.326702296402708234722215224979E-106
+subx3078 subtract -5326702296402708234722215224979E-136 8032459.450998820205916538543258 -> -8032459.450998820205916538543258 Inexact Rounded
+addx3079 add 67.18750684079501575335482615780E-281 734.1168841683438410314843011541E-854 -> 6.718750684079501575335482615780E-280 Inexact Rounded
+comx3079 compare 67.18750684079501575335482615780E-281 734.1168841683438410314843011541E-854 -> 1
+divx3079 divide 67.18750684079501575335482615780E-281 734.1168841683438410314843011541E-854 -> 9.152153872187460598958616592442E+571 Inexact Rounded
+dvix3079 divideint 67.18750684079501575335482615780E-281 734.1168841683438410314843011541E-854 -> NaN Division_impossible
+mulx3079 multiply 67.18750684079501575335482615780E-281 734.1168841683438410314843011541E-854 -> 4.932348317700372401849231767007E-1131 Inexact Rounded
+powx3079 power 67.18750684079501575335482615780E-281 7 -> 6.180444071023111300817518409550E-1955 Inexact Rounded
+remx3079 remainder 67.18750684079501575335482615780E-281 734.1168841683438410314843011541E-854 -> NaN Division_impossible
+subx3079 subtract 67.18750684079501575335482615780E-281 734.1168841683438410314843011541E-854 -> 6.718750684079501575335482615780E-280 Inexact Rounded
+addx3080 add -8739299372114.092482914139281669 507610074.7343577029345077385838 -> -8738791762039.358125211204773930 Inexact Rounded
+comx3080 compare -8739299372114.092482914139281669 507610074.7343577029345077385838 -> -1
+divx3080 divide -8739299372114.092482914139281669 507610074.7343577029345077385838 -> -17216.56012577673731612130068130 Inexact Rounded
+dvix3080 divideint -8739299372114.092482914139281669 507610074.7343577029345077385838 -> -17216
+mulx3080 multiply -8739299372114.092482914139281669 507610074.7343577029345077385838 -> -4436156407404759833857.580707024 Inexact Rounded
+powx3080 power -8739299372114.092482914139281669 507610075 -> -Infinity Overflow Inexact Rounded
+remx3080 remainder -8739299372114.092482914139281669 507610074.7343577029345077385838 -> -284325487.3902691936540542102992
+subx3080 subtract -8739299372114.092482914139281669 507610074.7343577029345077385838 -> -8739806982188.826840617073789408 Inexact Rounded
+addx3081 add 2454.002078468928665008217727731 583546039.6233842869119950982009E-147 -> 2454.002078468928665008217727731 Inexact Rounded
+comx3081 compare 2454.002078468928665008217727731 583546039.6233842869119950982009E-147 -> 1
+divx3081 divide 2454.002078468928665008217727731 583546039.6233842869119950982009E-147 -> 4.205327278123112611006652533618E+141 Inexact Rounded
+dvix3081 divideint 2454.002078468928665008217727731 583546039.6233842869119950982009E-147 -> NaN Division_impossible
+mulx3081 multiply 2454.002078468928665008217727731 583546039.6233842869119950982009E-147 -> 1.432023194118096842806010293027E-135 Inexact Rounded
+powx3081 power 2454.002078468928665008217727731 6 -> 218398452792293853786.9263054420 Inexact Rounded
+remx3081 remainder 2454.002078468928665008217727731 583546039.6233842869119950982009E-147 -> NaN Division_impossible
+subx3081 subtract 2454.002078468928665008217727731 583546039.6233842869119950982009E-147 -> 2454.002078468928665008217727731 Inexact Rounded
+addx3082 add 764578.5204849936912066033177429 64603.13571259164812609436832506 -> 829181.6561975853393326976860680 Inexact Rounded
+comx3082 compare 764578.5204849936912066033177429 64603.13571259164812609436832506 -> 1
+divx3082 divide 764578.5204849936912066033177429 64603.13571259164812609436832506 -> 11.83500633601553578851124281417 Inexact Rounded
+dvix3082 divideint 764578.5204849936912066033177429 64603.13571259164812609436832506 -> 11
+mulx3082 multiply 764578.5204849936912066033177429 64603.13571259164812609436832506 -> 49394169921.82458094138096628957 Inexact Rounded
+powx3082 power 764578.5204849936912066033177429 64603 -> Infinity Overflow Inexact Rounded
+remx3082 remainder 764578.5204849936912066033177429 64603.13571259164812609436832506 -> 53944.02764648556181956526616724
+subx3082 subtract 764578.5204849936912066033177429 64603.13571259164812609436832506 -> 699975.3847724020430805089494178 Inexact Rounded
+addx3083 add 079203.7330103777716903518367560 846388934347.6324036132959664705 -> 846389013551.3654139910676568223 Inexact Rounded
+comx3083 compare 079203.7330103777716903518367560 846388934347.6324036132959664705 -> -1
+divx3083 divide 079203.7330103777716903518367560 846388934347.6324036132959664705 -> 9.357841270860339858146471876044E-8 Inexact Rounded
+dvix3083 divideint 079203.7330103777716903518367560 846388934347.6324036132959664705 -> 0
+mulx3083 multiply 079203.7330103777716903518367560 846388934347.6324036132959664705 -> 67037163179008037.19983564789203 Inexact Rounded
+powx3083 power 079203.7330103777716903518367560 8 -> 1.548692549503356788115682996756E+39 Inexact Rounded
+remx3083 remainder 079203.7330103777716903518367560 846388934347.6324036132959664705 -> 79203.7330103777716903518367560
+subx3083 subtract 079203.7330103777716903518367560 846388934347.6324036132959664705 -> -846388855143.8993932355242761187 Inexact Rounded
+addx3084 add -4278.581514688669249247007127899E-329 5.474973992953902631890208360829 -> 5.474973992953902631890208360829 Inexact Rounded
+comx3084 compare -4278.581514688669249247007127899E-329 5.474973992953902631890208360829 -> -1
+divx3084 divide -4278.581514688669249247007127899E-329 5.474973992953902631890208360829 -> -7.814797878848469282033896969532E-327 Inexact Rounded
+dvix3084 divideint -4278.581514688669249247007127899E-329 5.474973992953902631890208360829 -> -0
+mulx3084 multiply -4278.581514688669249247007127899E-329 5.474973992953902631890208360829 -> -2.342512251965378028433584538870E-325 Inexact Rounded
+powx3084 power -4278.581514688669249247007127899E-329 5 -> -1.433834587801771244104676682986E-1627 Inexact Rounded
+remx3084 remainder -4278.581514688669249247007127899E-329 5.474973992953902631890208360829 -> -4.278581514688669249247007127899E-326
+subx3084 subtract -4278.581514688669249247007127899E-329 5.474973992953902631890208360829 -> -5.474973992953902631890208360829 Inexact Rounded
+addx3085 add 60867019.81764798845468445196869E+651 6.149612565404080501157093851895E+817 -> 6.149612565404080501157093851895E+817 Inexact Rounded
+comx3085 compare 60867019.81764798845468445196869E+651 6.149612565404080501157093851895E+817 -> -1
+divx3085 divide 60867019.81764798845468445196869E+651 6.149612565404080501157093851895E+817 -> 9.897699923417617920996187420968E-160 Inexact Rounded
+dvix3085 divideint 60867019.81764798845468445196869E+651 6.149612565404080501157093851895E+817 -> 0
+mulx3085 multiply 60867019.81764798845468445196869E+651 6.149612565404080501157093851895E+817 -> 3.743085898893072544197564013497E+1476 Inexact Rounded
+powx3085 power 60867019.81764798845468445196869E+651 6 -> 5.085014897388871736767602086646E+3952 Inexact Rounded
+remx3085 remainder 60867019.81764798845468445196869E+651 6.149612565404080501157093851895E+817 -> 6.086701981764798845468445196869E+658
+subx3085 subtract 60867019.81764798845468445196869E+651 6.149612565404080501157093851895E+817 -> -6.149612565404080501157093851895E+817 Inexact Rounded
+addx3086 add 18554417738217.62218590965803605E-382 -0894505909529.052378474618435782E+527 -> -8.945059095290523784746184357820E+538 Inexact Rounded
+comx3086 compare 18554417738217.62218590965803605E-382 -0894505909529.052378474618435782E+527 -> 1
+divx3086 divide 18554417738217.62218590965803605E-382 -0894505909529.052378474618435782E+527 -> -2.074264411286709228674841672954E-908 Inexact Rounded
+dvix3086 divideint 18554417738217.62218590965803605E-382 -0894505909529.052378474618435782E+527 -> -0
+mulx3086 multiply 18554417738217.62218590965803605E-382 -0894505909529.052378474618435782E+527 -> -1.659703631470633700884136887614E+170 Inexact Rounded
+powx3086 power 18554417738217.62218590965803605E-382 -9 -> 3.836842998295531899082688721531E+3318 Inexact Rounded
+remx3086 remainder 18554417738217.62218590965803605E-382 -0894505909529.052378474618435782E+527 -> 1.855441773821762218590965803605E-369
+subx3086 subtract 18554417738217.62218590965803605E-382 -0894505909529.052378474618435782E+527 -> 8.945059095290523784746184357820E+538 Inexact Rounded
+addx3087 add 69073355517144.36356688642213839 997784782535.6104634823627327033E+116 -> 9.977847825356104634823627327033E+127 Inexact Rounded
+comx3087 compare 69073355517144.36356688642213839 997784782535.6104634823627327033E+116 -> -1
+divx3087 divide 69073355517144.36356688642213839 997784782535.6104634823627327033E+116 -> 6.922670772910807388395384866884E-115 Inexact Rounded
+dvix3087 divideint 69073355517144.36356688642213839 997784782535.6104634823627327033E+116 -> 0
+mulx3087 multiply 69073355517144.36356688642213839 997784782535.6104634823627327033E+116 -> 6.892034301367879802693422066425E+141 Inexact Rounded
+powx3087 power 69073355517144.36356688642213839 10 -> 2.472324890841334302628435461516E+138 Inexact Rounded
+remx3087 remainder 69073355517144.36356688642213839 997784782535.6104634823627327033E+116 -> 69073355517144.36356688642213839
+subx3087 subtract 69073355517144.36356688642213839 997784782535.6104634823627327033E+116 -> -9.977847825356104634823627327033E+127 Inexact Rounded
+addx3088 add 450282259072.8657099359104277477 -1791307965314309175477911369824 -> -1791307965314309175027629110751 Inexact Rounded
+comx3088 compare 450282259072.8657099359104277477 -1791307965314309175477911369824 -> 1
+divx3088 divide 450282259072.8657099359104277477 -1791307965314309175477911369824 -> -2.513706564096350714213771006483E-19 Inexact Rounded
+dvix3088 divideint 450282259072.8657099359104277477 -1791307965314309175477911369824 -> -0
+mulx3088 multiply 450282259072.8657099359104277477 -1791307965314309175477911369824 -> -8.065941973169457071650996861677E+41 Inexact Rounded
+powx3088 power 450282259072.8657099359104277477 -2 -> 4.932082442194544671633570348838E-24 Inexact Rounded
+remx3088 remainder 450282259072.8657099359104277477 -1791307965314309175477911369824 -> 450282259072.8657099359104277477
+subx3088 subtract 450282259072.8657099359104277477 -1791307965314309175477911369824 -> 1791307965314309175928193628897 Inexact Rounded
+addx3089 add 954678411.7838149266455177850037 142988.7096204254529284334278794 -> 954821400.4934353520984462184316 Inexact Rounded
+comx3089 compare 954678411.7838149266455177850037 142988.7096204254529284334278794 -> 1
+divx3089 divide 954678411.7838149266455177850037 142988.7096204254529284334278794 -> 6676.599951968811589335427770046 Inexact Rounded
+dvix3089 divideint 954678411.7838149266455177850037 142988.7096204254529284334278794 -> 6676
+mulx3089 multiply 954678411.7838149266455177850037 142988.7096204254529284334278794 -> 136508234203444.8694879431412375 Inexact Rounded
+powx3089 power 954678411.7838149266455177850037 142989 -> Infinity Overflow Inexact Rounded
+remx3089 remainder 954678411.7838149266455177850037 142988.7096204254529284334278794 -> 85786.3578546028952962204808256
+subx3089 subtract 954678411.7838149266455177850037 142988.7096204254529284334278794 -> 954535423.0741945011925893515758 Inexact Rounded
+addx3090 add -9244530976.220812127155852389807E+557 541089.4715446858896619078627941 -> -9.244530976220812127155852389807E+566 Inexact Rounded
+comx3090 compare -9244530976.220812127155852389807E+557 541089.4715446858896619078627941 -> -1
+divx3090 divide -9244530976.220812127155852389807E+557 541089.4715446858896619078627941 -> -1.708503207395591002370649848757E+561 Inexact Rounded
+dvix3090 divideint -9244530976.220812127155852389807E+557 541089.4715446858896619078627941 -> NaN Division_impossible
+mulx3090 multiply -9244530976.220812127155852389807E+557 541089.4715446858896619078627941 -> -5.002118380601798392363043558941E+572 Inexact Rounded
+powx3090 power -9244530976.220812127155852389807E+557 541089 -> -Infinity Overflow Inexact Rounded
+remx3090 remainder -9244530976.220812127155852389807E+557 541089.4715446858896619078627941 -> NaN Division_impossible
+subx3090 subtract -9244530976.220812127155852389807E+557 541089.4715446858896619078627941 -> -9.244530976220812127155852389807E+566 Inexact Rounded
+addx3091 add -75492024.20990197005974241975449 -14760421311348.35269044633000927 -> -14760496803372.56259241638975169 Inexact Rounded
+comx3091 compare -75492024.20990197005974241975449 -14760421311348.35269044633000927 -> 1
+divx3091 divide -75492024.20990197005974241975449 -14760421311348.35269044633000927 -> 0.000005114489797920668836278344635108 Inexact Rounded
+dvix3091 divideint -75492024.20990197005974241975449 -14760421311348.35269044633000927 -> 0
+mulx3091 multiply -75492024.20990197005974241975449 -14760421311348.35269044633000927 -> 1114294082984662825831.464787487 Inexact Rounded
+powx3091 power -75492024.20990197005974241975449 -1 -> -1.324643246046162082348970735576E-8 Inexact Rounded
+remx3091 remainder -75492024.20990197005974241975449 -14760421311348.35269044633000927 -> -75492024.20990197005974241975449
+subx3091 subtract -75492024.20990197005974241975449 -14760421311348.35269044633000927 -> 14760345819324.14278847627026685 Inexact Rounded
+addx3092 add 317747.6972215715434186596178036E-452 24759763.33144824613591228097330E+092 -> 2.475976333144824613591228097330E+99 Inexact Rounded
+comx3092 compare 317747.6972215715434186596178036E-452 24759763.33144824613591228097330E+092 -> -1
+divx3092 divide 317747.6972215715434186596178036E-452 24759763.33144824613591228097330E+092 -> 1.283322837007852247594216151634E-546 Inexact Rounded
+dvix3092 divideint 317747.6972215715434186596178036E-452 24759763.33144824613591228097330E+092 -> 0
+mulx3092 multiply 317747.6972215715434186596178036E-452 24759763.33144824613591228097330E+092 -> 7.867357782318786860404997647513E-348 Inexact Rounded
+powx3092 power 317747.6972215715434186596178036E-452 2 -> 1.009635990896115043331231496209E-893 Inexact Rounded
+remx3092 remainder 317747.6972215715434186596178036E-452 24759763.33144824613591228097330E+092 -> 3.177476972215715434186596178036E-447
+subx3092 subtract 317747.6972215715434186596178036E-452 24759763.33144824613591228097330E+092 -> -2.475976333144824613591228097330E+99 Inexact Rounded
+addx3093 add -8.153334430358647134334545353427 -9.717872025814596548462854853522 -> -17.87120645617324368279740020695 Inexact Rounded
+comx3093 compare -8.153334430358647134334545353427 -9.717872025814596548462854853522 -> 1
+divx3093 divide -8.153334430358647134334545353427 -9.717872025814596548462854853522 -> 0.8390040956188859972044344532019 Inexact Rounded
+dvix3093 divideint -8.153334430358647134334545353427 -9.717872025814596548462854853522 -> 0
+mulx3093 multiply -8.153334430358647134334545353427 -9.717872025814596548462854853522 -> 79.23306057789328578902960605222 Inexact Rounded
+powx3093 power -8.153334430358647134334545353427 -10 -> 7.702778966876727056635952801162E-10 Inexact Rounded
+remx3093 remainder -8.153334430358647134334545353427 -9.717872025814596548462854853522 -> -8.153334430358647134334545353427
+subx3093 subtract -8.153334430358647134334545353427 -9.717872025814596548462854853522 -> 1.564537595455949414128309500095
+addx3094 add 7.267345197492967332320456062961E-478 5054015481833.263541189916208065 -> 5054015481833.263541189916208065 Inexact Rounded
+comx3094 compare 7.267345197492967332320456062961E-478 5054015481833.263541189916208065 -> -1
+divx3094 divide 7.267345197492967332320456062961E-478 5054015481833.263541189916208065 -> 1.437934890309606594895299558654E-490 Inexact Rounded
+dvix3094 divideint 7.267345197492967332320456062961E-478 5054015481833.263541189916208065 -> 0
+mulx3094 multiply 7.267345197492967332320456062961E-478 5054015481833.263541189916208065 -> 3.672927513995607308048737751972E-465 Inexact Rounded
+powx3094 power 7.267345197492967332320456062961E-478 5 -> 2.027117616846668568108096583897E-2386 Inexact Rounded
+remx3094 remainder 7.267345197492967332320456062961E-478 5054015481833.263541189916208065 -> 7.267345197492967332320456062961E-478
+subx3094 subtract 7.267345197492967332320456062961E-478 5054015481833.263541189916208065 -> -5054015481833.263541189916208065 Inexact Rounded
+addx3095 add -1223354029.862567054230912271171 8135774223401322785475014855625 -> 8135774223401322785473791501595 Inexact Rounded
+comx3095 compare -1223354029.862567054230912271171 8135774223401322785475014855625 -> -1
+divx3095 divide -1223354029.862567054230912271171 8135774223401322785475014855625 -> -1.503672540892020337688277553692E-22 Inexact Rounded
+dvix3095 divideint -1223354029.862567054230912271171 8135774223401322785475014855625 -> -0
+mulx3095 multiply -1223354029.862567054230912271171 8135774223401322785475014855625 -> -9.952932182250005119307429060894E+39 Inexact Rounded
+powx3095 power -1223354029.862567054230912271171 8 -> 5.016689887192830666848068841227E+72 Inexact Rounded
+remx3095 remainder -1223354029.862567054230912271171 8135774223401322785475014855625 -> -1223354029.862567054230912271171
+subx3095 subtract -1223354029.862567054230912271171 8135774223401322785475014855625 -> -8135774223401322785476238209655 Inexact Rounded
+addx3096 add 285397644111.5655679961211349982E+645 -2479499427613157519359627280704 -> 2.853976441115655679961211349982E+656 Inexact Rounded
+comx3096 compare 285397644111.5655679961211349982E+645 -2479499427613157519359627280704 -> 1
+divx3096 divide 285397644111.5655679961211349982E+645 -2479499427613157519359627280704 -> -1.151029280076495626421134733122E+626 Inexact Rounded
+dvix3096 divideint 285397644111.5655679961211349982E+645 -2479499427613157519359627280704 -> NaN Division_impossible
+mulx3096 multiply 285397644111.5655679961211349982E+645 -2479499427613157519359627280704 -> -7.076432952167704614138411740001E+686 Inexact Rounded
+powx3096 power 285397644111.5655679961211349982E+645 -2 -> 1.227719722087860401233030479451E-1313 Inexact Rounded
+remx3096 remainder 285397644111.5655679961211349982E+645 -2479499427613157519359627280704 -> NaN Division_impossible
+subx3096 subtract 285397644111.5655679961211349982E+645 -2479499427613157519359627280704 -> 2.853976441115655679961211349982E+656 Inexact Rounded
+addx3097 add -4673112.663442366293812346653429 -3429.998403142546001438238460958 -> -4676542.661845508839813784891890 Inexact Rounded
+comx3097 compare -4673112.663442366293812346653429 -3429.998403142546001438238460958 -> -1
+divx3097 divide -4673112.663442366293812346653429 -3429.998403142546001438238460958 -> 1362.424151323477505064686589716 Inexact Rounded
+dvix3097 divideint -4673112.663442366293812346653429 -3429.998403142546001438238460958 -> 1362
+mulx3097 multiply -4673112.663442366293812346653429 -3429.998403142546001438238460958 -> 16028768973.31252639476148371361 Inexact Rounded
+powx3097 power -4673112.663442366293812346653429 -3430 -> 0E-10029 Underflow Subnormal Inexact Rounded Clamped
+remx3097 remainder -4673112.663442366293812346653429 -3429.998403142546001438238460958 -> -1454.838362218639853465869604204
+subx3097 subtract -4673112.663442366293812346653429 -3429.998403142546001438238460958 -> -4669682.665039223747810908414968 Inexact Rounded
+addx3098 add 88.96492479681278079861456051103 386939.4621006514751889096510923E+139 -> 3.869394621006514751889096510923E+144 Inexact Rounded
+comx3098 compare 88.96492479681278079861456051103 386939.4621006514751889096510923E+139 -> -1
+divx3098 divide 88.96492479681278079861456051103 386939.4621006514751889096510923E+139 -> 2.299194926095985647821385937618E-143 Inexact Rounded
+dvix3098 divideint 88.96492479681278079861456051103 386939.4621006514751889096510923E+139 -> 0
+mulx3098 multiply 88.96492479681278079861456051103 386939.4621006514751889096510923E+139 -> 3.442404014670364763780946297856E+146 Inexact Rounded
+powx3098 power 88.96492479681278079861456051103 4 -> 62643391.73078290226474758858970 Inexact Rounded
+remx3098 remainder 88.96492479681278079861456051103 386939.4621006514751889096510923E+139 -> 88.96492479681278079861456051103
+subx3098 subtract 88.96492479681278079861456051103 386939.4621006514751889096510923E+139 -> -3.869394621006514751889096510923E+144 Inexact Rounded
+addx3099 add 064326846.4286437304788069444326E-942 92.23649942010862087149015091350 -> 92.23649942010862087149015091350 Inexact Rounded
+comx3099 compare 064326846.4286437304788069444326E-942 92.23649942010862087149015091350 -> -1
+divx3099 divide 064326846.4286437304788069444326E-942 92.23649942010862087149015091350 -> 6.974120530708230229344349531719E-937 Inexact Rounded
+dvix3099 divideint 064326846.4286437304788069444326E-942 92.23649942010862087149015091350 -> 0
+mulx3099 multiply 064326846.4286437304788069444326E-942 92.23649942010862087149015091350 -> 5.933283133313013755814405436342E-933 Inexact Rounded
+powx3099 power 064326846.4286437304788069444326E-942 92 -> 0E-10029 Underflow Subnormal Inexact Rounded Clamped
+remx3099 remainder 064326846.4286437304788069444326E-942 92.23649942010862087149015091350 -> 6.43268464286437304788069444326E-935
+subx3099 subtract 064326846.4286437304788069444326E-942 92.23649942010862087149015091350 -> -92.23649942010862087149015091350 Inexact Rounded
+addx3100 add 504507.0043949324433170405699360 605387.7175522955344659311072099 -> 1109894.721947227977782971677146 Inexact Rounded
+comx3100 compare 504507.0043949324433170405699360 605387.7175522955344659311072099 -> -1
+divx3100 divide 504507.0043949324433170405699360 605387.7175522955344659311072099 -> 0.8333618105678718895216067463832 Inexact Rounded
+dvix3100 divideint 504507.0043949324433170405699360 605387.7175522955344659311072099 -> 0
+mulx3100 multiply 504507.0043949324433170405699360 605387.7175522955344659311072099 -> 305422343879.7940838630401656585 Inexact Rounded
+powx3100 power 504507.0043949324433170405699360 605388 -> Infinity Overflow Inexact Rounded
+remx3100 remainder 504507.0043949324433170405699360 605387.7175522955344659311072099 -> 504507.0043949324433170405699360
+subx3100 subtract 504507.0043949324433170405699360 605387.7175522955344659311072099 -> -100880.7131573630911488905372739
+
+-- randomly generated testcases [26 Sep 2001]
+precision: 32
+rounding: half_up
+maxExponent: 9999
+
+addx3201 add 1.5283550163839789319142430253644 -1.6578158484822969520405291379492 -> -0.1294608320983180201262861125848
+comx3201 compare 1.5283550163839789319142430253644 -1.6578158484822969520405291379492 -> 1
+divx3201 divide 1.5283550163839789319142430253644 -1.6578158484822969520405291379492 -> -0.92190879812324313630282980110280 Inexact Rounded
+dvix3201 divideint 1.5283550163839789319142430253644 -1.6578158484822969520405291379492 -> -0
+mulx3201 multiply 1.5283550163839789319142430253644 -1.6578158484822969520405291379492 -> -2.5337311682687808926633910761614 Inexact Rounded
+powx3201 power 1.5283550163839789319142430253644 -2 -> 0.42810618916584924451466691603128 Inexact Rounded
+remx3201 remainder 1.5283550163839789319142430253644 -1.6578158484822969520405291379492 -> 1.5283550163839789319142430253644
+subx3201 subtract 1.5283550163839789319142430253644 -1.6578158484822969520405291379492 -> 3.1861708648662758839547721633136
+addx3202 add -622903030605.2867503937836507326 6519388607.1331855704471328795821 -> -616383641998.15356482333651785302 Inexact Rounded
+comx3202 compare -622903030605.2867503937836507326 6519388607.1331855704471328795821 -> -1
+divx3202 divide -622903030605.2867503937836507326 6519388607.1331855704471328795821 -> -95.546234185785110491676894153510 Inexact Rounded
+dvix3202 divideint -622903030605.2867503937836507326 6519388607.1331855704471328795821 -> -95
+mulx3202 multiply -622903030605.2867503937836507326 6519388607.1331855704471328795821 -> -4060946921076840449949.6988828486 Inexact Rounded
+powx3202 power -622903030605.2867503937836507326 7 -> -3.6386736597702404352813308064300E+82 Inexact Rounded
+remx3202 remainder -622903030605.2867503937836507326 6519388607.1331855704471328795821 -> -3561112927.6341212013060271723005
+subx3202 subtract -622903030605.2867503937836507326 6519388607.1331855704471328795821 -> -629422419212.41993596423078361218 Inexact Rounded
+addx3203 add -5675915.2465457487632250245209054 73913909880.381367895205086027416 -> 73908233965.134822146441861002895 Inexact Rounded
+comx3203 compare -5675915.2465457487632250245209054 73913909880.381367895205086027416 -> -1
+divx3203 divide -5675915.2465457487632250245209054 73913909880.381367895205086027416 -> -0.000076790894376056827552388054657082 Inexact Rounded
+dvix3203 divideint -5675915.2465457487632250245209054 73913909880.381367895205086027416 -> -0
+mulx3203 multiply -5675915.2465457487632250245209054 73913909880.381367895205086027416 -> -419529088021865067.23307352973589 Inexact Rounded
+powx3203 power -5675915.2465457487632250245209054 7 -> -1.8978038060207777231389234721908E+47 Inexact Rounded
+remx3203 remainder -5675915.2465457487632250245209054 73913909880.381367895205086027416 -> -5675915.2465457487632250245209054
+subx3203 subtract -5675915.2465457487632250245209054 73913909880.381367895205086027416 -> -73919585795.627913643968311051937 Inexact Rounded
+addx3204 add 97.647321172555144900685605318635 4.8620911587547548751209841570885 -> 102.50941233130989977580658947572 Inexact Rounded
+comx3204 compare 97.647321172555144900685605318635 4.8620911587547548751209841570885 -> 1
+divx3204 divide 97.647321172555144900685605318635 4.8620911587547548751209841570885 -> 20.083399916665466374741708949621 Inexact Rounded
+dvix3204 divideint 97.647321172555144900685605318635 4.8620911587547548751209841570885 -> 20
+mulx3204 multiply 97.647321172555144900685605318635 4.8620911587547548751209841570885 -> 474.77017694916635398652276042175 Inexact Rounded
+powx3204 power 97.647321172555144900685605318635 5 -> 8877724578.7935312939231828719842 Inexact Rounded
+remx3204 remainder 97.647321172555144900685605318635 4.8620911587547548751209841570885 -> 0.4054979974600473982659221768650
+subx3204 subtract 97.647321172555144900685605318635 4.8620911587547548751209841570885 -> 92.785230013800390025564621161547 Inexact Rounded
+addx3205 add -9717253267024.5380651435435603552 -2669.2539695193820424002013488480E+363 -> -2.6692539695193820424002013488480E+366 Inexact Rounded
+comx3205 compare -9717253267024.5380651435435603552 -2669.2539695193820424002013488480E+363 -> 1
+divx3205 divide -9717253267024.5380651435435603552 -2669.2539695193820424002013488480E+363 -> 3.6404378818903462695633337631098E-354 Inexact Rounded
+dvix3205 divideint -9717253267024.5380651435435603552 -2669.2539695193820424002013488480E+363 -> 0
+mulx3205 multiply -9717253267024.5380651435435603552 -2669.2539695193820424002013488480E+363 -> 2.5937816855830431899123217912144E+379 Inexact Rounded
+powx3205 power -9717253267024.5380651435435603552 -3 -> -1.0898567880085337780041328661330E-39 Inexact Rounded
+remx3205 remainder -9717253267024.5380651435435603552 -2669.2539695193820424002013488480E+363 -> -9717253267024.5380651435435603552
+subx3205 subtract -9717253267024.5380651435435603552 -2669.2539695193820424002013488480E+363 -> 2.6692539695193820424002013488480E+366 Inexact Rounded
+addx3206 add -4.0817391717190128506083001702335E-767 12772.807105920712660991033689206 -> 12772.807105920712660991033689206 Inexact Rounded
+comx3206 compare -4.0817391717190128506083001702335E-767 12772.807105920712660991033689206 -> -1
+divx3206 divide -4.0817391717190128506083001702335E-767 12772.807105920712660991033689206 -> -3.1956477052150593175206769891434E-771 Inexact Rounded
+dvix3206 divideint -4.0817391717190128506083001702335E-767 12772.807105920712660991033689206 -> -0
+mulx3206 multiply -4.0817391717190128506083001702335E-767 12772.807105920712660991033689206 -> -5.2135267097047531336100750110314E-763 Inexact Rounded
+powx3206 power -4.0817391717190128506083001702335E-767 12773 -> -0E-10030 Underflow Subnormal Inexact Rounded Clamped
+remx3206 remainder -4.0817391717190128506083001702335E-767 12772.807105920712660991033689206 -> -4.0817391717190128506083001702335E-767
+subx3206 subtract -4.0817391717190128506083001702335E-767 12772.807105920712660991033689206 -> -12772.807105920712660991033689206 Inexact Rounded
+addx3207 add 68625322655934146845003028928647 -59.634169944840280159782488098700 -> 68625322655934146845003028928587 Inexact Rounded
+comx3207 compare 68625322655934146845003028928647 -59.634169944840280159782488098700 -> 1
+divx3207 divide 68625322655934146845003028928647 -59.634169944840280159782488098700 -> -1150771826276954946844322988192.5 Inexact Rounded
+dvix3207 divideint 68625322655934146845003028928647 -59.634169944840280159782488098700 -> -1150771826276954946844322988192
+mulx3207 multiply 68625322655934146845003028928647 -59.634169944840280159782488098700 -> -4.0924141537834748501140151997778E+33 Inexact Rounded
+powx3207 power 68625322655934146845003028928647 -60 -> 6.4704731111943370171711131942603E-1911 Inexact Rounded
+remx3207 remainder 68625322655934146845003028928647 -59.634169944840280159782488098700 -> 28.201254004897257552939369449600
+subx3207 subtract 68625322655934146845003028928647 -59.634169944840280159782488098700 -> 68625322655934146845003028928707 Inexact Rounded
+addx3208 add 732515.76532049290815665856727641 -92134479835821.319619827023729829 -> -92134479103305.554299334115573170 Inexact Rounded
+comx3208 compare 732515.76532049290815665856727641 -92134479835821.319619827023729829 -> 1
+divx3208 divide 732515.76532049290815665856727641 -92134479835821.319619827023729829 -> -7.9505063318943846655593887991914E-9 Inexact Rounded
+dvix3208 divideint 732515.76532049290815665856727641 -92134479835821.319619827023729829 -> -0
+mulx3208 multiply 732515.76532049290815665856727641 -92134479835821.319619827023729829 -> -67489959009342175728.710494356322 Inexact Rounded
+powx3208 power 732515.76532049290815665856727641 -9 -> 1.6468241050443471359358016585877E-53 Inexact Rounded
+remx3208 remainder 732515.76532049290815665856727641 -92134479835821.319619827023729829 -> 732515.76532049290815665856727641
+subx3208 subtract 732515.76532049290815665856727641 -92134479835821.319619827023729829 -> 92134480568337.084940319931886488 Inexact Rounded
+addx3209 add -30.458011942978338421676454778733 -5023372024597665102336430410403E+831 -> -5.0233720245976651023364304104030E+861 Inexact Rounded
+comx3209 compare -30.458011942978338421676454778733 -5023372024597665102336430410403E+831 -> 1
+divx3209 divide -30.458011942978338421676454778733 -5023372024597665102336430410403E+831 -> 6.0632602550311410821483001305010E-861 Inexact Rounded
+dvix3209 divideint -30.458011942978338421676454778733 -5023372024597665102336430410403E+831 -> 0
+mulx3209 multiply -30.458011942978338421676454778733 -5023372024597665102336430410403E+831 -> 1.5300192511921895929031818638961E+863 Inexact Rounded
+powx3209 power -30.458011942978338421676454778733 -5 -> -3.8149797481405136042487643253109E-8 Inexact Rounded
+remx3209 remainder -30.458011942978338421676454778733 -5023372024597665102336430410403E+831 -> -30.458011942978338421676454778733
+subx3209 subtract -30.458011942978338421676454778733 -5023372024597665102336430410403E+831 -> 5.0233720245976651023364304104030E+861 Inexact Rounded
+addx3210 add -89640.094149414644660480286430462 -58703419758.800889903227509215474 -> -58703509398.895039317872169695760 Inexact Rounded
+comx3210 compare -89640.094149414644660480286430462 -58703419758.800889903227509215474 -> 1
+divx3210 divide -89640.094149414644660480286430462 -58703419758.800889903227509215474 -> 0.0000015269995260536025237167199970238 Inexact Rounded
+dvix3210 divideint -89640.094149414644660480286430462 -58703419758.800889903227509215474 -> 0
+mulx3210 multiply -89640.094149414644660480286430462 -58703419758.800889903227509215474 -> 5262180074071519.7018252171579753 Inexact Rounded
+powx3210 power -89640.094149414644660480286430462 -6 -> 1.9274635591165405888724595165741E-30 Inexact Rounded
+remx3210 remainder -89640.094149414644660480286430462 -58703419758.800889903227509215474 -> -89640.094149414644660480286430462
+subx3210 subtract -89640.094149414644660480286430462 -58703419758.800889903227509215474 -> 58703330118.706740488582848735188 Inexact Rounded
+addx3211 add 458653.1567870081810052917714259 18353106238.516235116080449814053E-038 -> 458653.15678700818100529177142590 Inexact Rounded
+comx3211 compare 458653.1567870081810052917714259 18353106238.516235116080449814053E-038 -> 1
+divx3211 divide 458653.1567870081810052917714259 18353106238.516235116080449814053E-038 -> 2.4990492117594160215641311760498E+33 Inexact Rounded
+dvix3211 divideint 458653.1567870081810052917714259 18353106238.516235116080449814053E-038 -> NaN Division_impossible
+mulx3211 multiply 458653.1567870081810052917714259 18353106238.516235116080449814053E-038 -> 8.4177101131428047497998594379593E-23 Inexact Rounded
+powx3211 power 458653.1567870081810052917714259 2 -> 210362718230.68790865117452429990 Inexact Rounded
+remx3211 remainder 458653.1567870081810052917714259 18353106238.516235116080449814053E-038 -> NaN Division_impossible
+subx3211 subtract 458653.1567870081810052917714259 18353106238.516235116080449814053E-038 -> 458653.15678700818100529177142590 Inexact Rounded
+addx3212 add 913391.42744224458216174967853722 -21051638.816432817393202262710630E+432 -> -2.1051638816432817393202262710630E+439 Inexact Rounded
+comx3212 compare 913391.42744224458216174967853722 -21051638.816432817393202262710630E+432 -> 1
+divx3212 divide 913391.42744224458216174967853722 -21051638.816432817393202262710630E+432 -> -4.3388138824102151127273259092613E-434 Inexact Rounded
+dvix3212 divideint 913391.42744224458216174967853722 -21051638.816432817393202262710630E+432 -> -0
+mulx3212 multiply 913391.42744224458216174967853722 -21051638.816432817393202262710630E+432 -> -1.9228386428540135340600836707270E+445 Inexact Rounded
+powx3212 power 913391.42744224458216174967853722 -2 -> 1.1986327439971532470297300128074E-12 Inexact Rounded
+remx3212 remainder 913391.42744224458216174967853722 -21051638.816432817393202262710630E+432 -> 913391.42744224458216174967853722
+subx3212 subtract 913391.42744224458216174967853722 -21051638.816432817393202262710630E+432 -> 2.1051638816432817393202262710630E+439 Inexact Rounded
+addx3213 add -917591456829.12109027484399536567 -28892177726858026955513438843371E+708 -> -2.8892177726858026955513438843371E+739 Inexact Rounded
+comx3213 compare -917591456829.12109027484399536567 -28892177726858026955513438843371E+708 -> 1
+divx3213 divide -917591456829.12109027484399536567 -28892177726858026955513438843371E+708 -> 3.1759165595057674196644927106447E-728 Inexact Rounded
+dvix3213 divideint -917591456829.12109027484399536567 -28892177726858026955513438843371E+708 -> 0
+mulx3213 multiply -917591456829.12109027484399536567 -28892177726858026955513438843371E+708 -> 2.6511215451353541156703914721725E+751 Inexact Rounded
+powx3213 power -917591456829.12109027484399536567 -3 -> -1.2943505591853739240003453341911E-36 Inexact Rounded
+remx3213 remainder -917591456829.12109027484399536567 -28892177726858026955513438843371E+708 -> -917591456829.12109027484399536567
+subx3213 subtract -917591456829.12109027484399536567 -28892177726858026955513438843371E+708 -> 2.8892177726858026955513438843371E+739 Inexact Rounded
+addx3214 add 34938410840645.913399699219228218 30.818220393242402846077755480548 -> 34938410840676.731620092461631064 Inexact Rounded
+comx3214 compare 34938410840645.913399699219228218 30.818220393242402846077755480548 -> 1
+divx3214 divide 34938410840645.913399699219228218 30.818220393242402846077755480548 -> 1133693327999.7879503260098666966 Inexact Rounded
+dvix3214 divideint 34938410840645.913399699219228218 30.818220393242402846077755480548 -> 1133693327999
+mulx3214 multiply 34938410840645.913399699219228218 30.818220393242402846077755480548 -> 1076739645476675.3318519289128961 Inexact Rounded
+powx3214 power 34938410840645.913399699219228218 31 -> 6.9566085958798732786509909683267E+419 Inexact Rounded
+remx3214 remainder 34938410840645.913399699219228218 30.818220393242402846077755480548 -> 24.283226805899273551376371736548
+subx3214 subtract 34938410840645.913399699219228218 30.818220393242402846077755480548 -> 34938410840615.095179305976825372 Inexact Rounded
+addx3215 add 6034.7374411022598081745006769023E-517 29771833428054709077850588904653 -> 29771833428054709077850588904653 Inexact Rounded
+comx3215 compare 6034.7374411022598081745006769023E-517 29771833428054709077850588904653 -> -1
+divx3215 divide 6034.7374411022598081745006769023E-517 29771833428054709077850588904653 -> 2.0269955680376683526099444523691E-545 Inexact Rounded
+dvix3215 divideint 6034.7374411022598081745006769023E-517 29771833428054709077850588904653 -> 0
+mulx3215 multiply 6034.7374411022598081745006769023E-517 29771833428054709077850588904653 -> 1.7966519787854159464382359411642E-482 Inexact Rounded
+powx3215 power 6034.7374411022598081745006769023E-517 3 -> 2.1977340597301840681528507640032E-1540 Inexact Rounded
+remx3215 remainder 6034.7374411022598081745006769023E-517 29771833428054709077850588904653 -> 6.0347374411022598081745006769023E-514
+subx3215 subtract 6034.7374411022598081745006769023E-517 29771833428054709077850588904653 -> -29771833428054709077850588904653 Inexact Rounded
+addx3216 add -5565747671734.1686009705574503152 -490.30899494881071282787487030303 -> -5565747672224.4775959193681631431 Inexact Rounded
+comx3216 compare -5565747671734.1686009705574503152 -490.30899494881071282787487030303 -> -1
+divx3216 divide -5565747671734.1686009705574503152 -490.30899494881071282787487030303 -> 11351510433.365074871574519756245 Inexact Rounded
+dvix3216 divideint -5565747671734.1686009705574503152 -490.30899494881071282787487030303 -> 11351510433
+mulx3216 multiply -5565747671734.1686009705574503152 -490.30899494881071282787487030303 -> 2728936147066663.4580064428639745 Inexact Rounded
+powx3216 power -5565747671734.1686009705574503152 -490 -> 4.9371745297619526113991728953197E-6246 Inexact Rounded
+remx3216 remainder -5565747671734.1686009705574503152 -490.30899494881071282787487030303 -> -178.99949336276892685183308348801
+subx3216 subtract -5565747671734.1686009705574503152 -490.30899494881071282787487030303 -> -5565747671243.8596060217467374873 Inexact Rounded
+addx3217 add 319545511.89203495546689273564728E+036 -2955943533943321899150310192061 -> 3.1954551189203199952335879232538E+44 Inexact Rounded
+comx3217 compare 319545511.89203495546689273564728E+036 -2955943533943321899150310192061 -> 1
+divx3217 divide 319545511.89203495546689273564728E+036 -2955943533943321899150310192061 -> -108102711781422.68663084859902931 Inexact Rounded
+dvix3217 divideint 319545511.89203495546689273564728E+036 -2955943533943321899150310192061 -> -108102711781422
+mulx3217 multiply 319545511.89203495546689273564728E+036 -2955943533943321899150310192061 -> -9.4455848967786959996525702197139E+74 Inexact Rounded
+powx3217 power 319545511.89203495546689273564728E+036 -3 -> 3.0647978448946294457985223953472E-134 Inexact Rounded
+remx3217 remainder 319545511.89203495546689273564728E+036 -2955943533943321899150310192061 -> 2029642017122316721531728309258
+subx3217 subtract 319545511.89203495546689273564728E+036 -2955943533943321899150310192061 -> 3.1954551189203791141042667896918E+44 Inexact Rounded
+addx3218 add -36852134.84194296250843579428931 -5830629.8347085025808716360357940 -> -42682764.676651465089307430325104 Rounded
+comx3218 compare -36852134.84194296250843579428931 -5830629.8347085025808716360357940 -> -1
+divx3218 divide -36852134.84194296250843579428931 -5830629.8347085025808716360357940 -> 6.3204380807318655475459047410160 Inexact Rounded
+dvix3218 divideint -36852134.84194296250843579428931 -5830629.8347085025808716360357940 -> 6
+mulx3218 multiply -36852134.84194296250843579428931 -5830629.8347085025808716360357940 -> 214871156882133.34437417534873098 Inexact Rounded
+powx3218 power -36852134.84194296250843579428931 -5830630 -> 0E-10030 Underflow Subnormal Inexact Rounded Clamped
+remx3218 remainder -36852134.84194296250843579428931 -5830629.8347085025808716360357940 -> -1868355.8336919470232059780745460
+subx3218 subtract -36852134.84194296250843579428931 -5830629.8347085025808716360357940 -> -31021505.007234459927564158253516 Rounded
+addx3219 add 8.6021905001798578659275880018221E-374 -39505285344943.729681835377530908 -> -39505285344943.729681835377530908 Inexact Rounded
+comx3219 compare 8.6021905001798578659275880018221E-374 -39505285344943.729681835377530908 -> 1
+divx3219 divide 8.6021905001798578659275880018221E-374 -39505285344943.729681835377530908 -> -2.1774783867700502002511486885272E-387 Inexact Rounded
+dvix3219 divideint 8.6021905001798578659275880018221E-374 -39505285344943.729681835377530908 -> -0
+mulx3219 multiply 8.6021905001798578659275880018221E-374 -39505285344943.729681835377530908 -> -3.3983199030116951081865430362053E-360 Inexact Rounded
+powx3219 power 8.6021905001798578659275880018221E-374 -4 -> 1.8262649155820433126240754123257E+1492 Inexact Rounded
+remx3219 remainder 8.6021905001798578659275880018221E-374 -39505285344943.729681835377530908 -> 8.6021905001798578659275880018221E-374
+subx3219 subtract 8.6021905001798578659275880018221E-374 -39505285344943.729681835377530908 -> 39505285344943.729681835377530908 Inexact Rounded
+addx3220 add -54863165.152174109720312887805017 736.1398476560169141105328256628 -> -54862429.012326453703398777272191 Inexact Rounded
+comx3220 compare -54863165.152174109720312887805017 736.1398476560169141105328256628 -> -1
+divx3220 divide -54863165.152174109720312887805017 736.1398476560169141105328256628 -> -74528.182826764384088602813142847 Inexact Rounded
+dvix3220 divideint -54863165.152174109720312887805017 736.1398476560169141105328256628 -> -74528
+mulx3220 multiply -54863165.152174109720312887805017 736.1398476560169141105328256628 -> -40386962037.048345148338122539405 Inexact Rounded
+powx3220 power -54863165.152174109720312887805017 736 -> 1.2903643981679111625370174573639E+5696 Inexact Rounded
+remx3220 remainder -54863165.152174109720312887805017 736.1398476560169141105328256628 -> -134.5860664811454830973740198416
+subx3220 subtract -54863165.152174109720312887805017 736.1398476560169141105328256628 -> -54863901.292021765737226998337843 Inexact Rounded
+addx3221 add -3263743464517851012531708810307 2457206.2471248382136273643208109 -> -3263743464517851012531706353100.8 Inexact Rounded
+comx3221 compare -3263743464517851012531708810307 2457206.2471248382136273643208109 -> -1
+divx3221 divide -3263743464517851012531708810307 2457206.2471248382136273643208109 -> -1328233422952076975055082.5768082 Inexact Rounded
+dvix3221 divideint -3263743464517851012531708810307 2457206.2471248382136273643208109 -> -1328233422952076975055082
+mulx3221 multiply -3263743464517851012531708810307 2457206.2471248382136273643208109 -> -8.0196908300261262548565838031943E+36 Inexact Rounded
+powx3221 power -3263743464517851012531708810307 2457206 -> Infinity Overflow Inexact Rounded
+remx3221 remainder -3263743464517851012531708810307 2457206.2471248382136273643208109 -> -1417336.7573398366062994535940062
+subx3221 subtract -3263743464517851012531708810307 2457206.2471248382136273643208109 -> -3263743464517851012531711267513.2 Inexact Rounded
+addx3222 add 2856586744.0548637797291151154902E-895 953545637646.57694835860339582821E+080 -> 9.5354563764657694835860339582821E+91 Inexact Rounded
+comx3222 compare 2856586744.0548637797291151154902E-895 953545637646.57694835860339582821E+080 -> -1
+divx3222 divide 2856586744.0548637797291151154902E-895 953545637646.57694835860339582821E+080 -> 2.9957525170007980008712828968300E-978 Inexact Rounded
+dvix3222 divideint 2856586744.0548637797291151154902E-895 953545637646.57694835860339582821E+080 -> 0
+mulx3222 multiply 2856586744.0548637797291151154902E-895 953545637646.57694835860339582821E+080 -> 2.7238858283525541854826594343954E-794 Inexact Rounded
+powx3222 power 2856586744.0548637797291151154902E-895 10 -> 3.6180466753307072256807593988336E-8856 Inexact Rounded
+remx3222 remainder 2856586744.0548637797291151154902E-895 953545637646.57694835860339582821E+080 -> 2.8565867440548637797291151154902E-886
+subx3222 subtract 2856586744.0548637797291151154902E-895 953545637646.57694835860339582821E+080 -> -9.5354563764657694835860339582821E+91 Inexact Rounded
+addx3223 add 5624157233.3433661009203529937625 626098409265.93738586750090160638 -> 631722566499.28075196842125460014 Inexact Rounded
+comx3223 compare 5624157233.3433661009203529937625 626098409265.93738586750090160638 -> -1
+divx3223 divide 5624157233.3433661009203529937625 626098409265.93738586750090160638 -> 0.0089828645946207580492752544218316 Inexact Rounded
+dvix3223 divideint 5624157233.3433661009203529937625 626098409265.93738586750090160638 -> 0
+mulx3223 multiply 5624157233.3433661009203529937625 626098409265.93738586750090160638 -> 3521275897257796938833.8975037909 Inexact Rounded
+powx3223 power 5624157233.3433661009203529937625 6 -> 3.1647887196303262540158328459030E+58 Inexact Rounded
+remx3223 remainder 5624157233.3433661009203529937625 626098409265.93738586750090160638 -> 5624157233.3433661009203529937625
+subx3223 subtract 5624157233.3433661009203529937625 626098409265.93738586750090160638 -> -620474252032.59401976658054861262 Inexact Rounded
+addx3224 add -213499362.91476998701834067092611 419272438.02555757699863022643444 -> 205773075.11078758998028955550833
+comx3224 compare -213499362.91476998701834067092611 419272438.02555757699863022643444 -> -1
+divx3224 divide -213499362.91476998701834067092611 419272438.02555757699863022643444 -> -0.50921392286166855779828061147786 Inexact Rounded
+dvix3224 divideint -213499362.91476998701834067092611 419272438.02555757699863022643444 -> -0
+mulx3224 multiply -213499362.91476998701834067092611 419272438.02555757699863022643444 -> -89514398406178925.073260776410672 Inexact Rounded
+powx3224 power -213499362.91476998701834067092611 419272438 -> Infinity Overflow Inexact Rounded
+remx3224 remainder -213499362.91476998701834067092611 419272438.02555757699863022643444 -> -213499362.91476998701834067092611
+subx3224 subtract -213499362.91476998701834067092611 419272438.02555757699863022643444 -> -632771800.94032756401697089736055
+addx3225 add 30269.587755640502150977251770554 4.8046009735990873395936309640543 -> 30274.392356614101238316845401518 Inexact Rounded
+comx3225 compare 30269.587755640502150977251770554 4.8046009735990873395936309640543 -> 1
+divx3225 divide 30269.587755640502150977251770554 4.8046009735990873395936309640543 -> 6300.1252178837655359831527173832 Inexact Rounded
+dvix3225 divideint 30269.587755640502150977251770554 4.8046009735990873395936309640543 -> 6300
+mulx3225 multiply 30269.587755640502150977251770554 4.8046009735990873395936309640543 -> 145433.29080119336967191651199283 Inexact Rounded
+powx3225 power 30269.587755640502150977251770554 5 -> 25411630481547464128383.220368208 Inexact Rounded
+remx3225 remainder 30269.587755640502150977251770554 4.8046009735990873395936309640543 -> 0.6016219662519115373766970119100
+subx3225 subtract 30269.587755640502150977251770554 4.8046009735990873395936309640543 -> 30264.783154666903063637658139590 Inexact Rounded
+addx3226 add 47.525676459351505682005359699680E+704 -58631943508436657383369760970210 -> 4.7525676459351505682005359699680E+705 Inexact Rounded
+comx3226 compare 47.525676459351505682005359699680E+704 -58631943508436657383369760970210 -> 1
+divx3226 divide 47.525676459351505682005359699680E+704 -58631943508436657383369760970210 -> -8.1057651538555854520994438038537E+673 Inexact Rounded
+dvix3226 divideint 47.525676459351505682005359699680E+704 -58631943508436657383369760970210 -> NaN Division_impossible
+mulx3226 multiply 47.525676459351505682005359699680E+704 -58631943508436657383369760970210 -> -2.7865227773649353769876975366506E+737 Inexact Rounded
+powx3226 power 47.525676459351505682005359699680E+704 -6 -> 8.6782100393941226535150385475463E-4235 Inexact Rounded
+remx3226 remainder 47.525676459351505682005359699680E+704 -58631943508436657383369760970210 -> NaN Division_impossible
+subx3226 subtract 47.525676459351505682005359699680E+704 -58631943508436657383369760970210 -> 4.7525676459351505682005359699680E+705 Inexact Rounded
+addx3227 add -74396862273800.625679130772935550 -115616605.52826981284183992013157 -> -74396977890406.153948943614775470 Inexact Rounded
+comx3227 compare -74396862273800.625679130772935550 -115616605.52826981284183992013157 -> -1
+divx3227 divide -74396862273800.625679130772935550 -115616605.52826981284183992013157 -> 643479.03948459716424778005613112 Inexact Rounded
+dvix3227 divideint -74396862273800.625679130772935550 -115616605.52826981284183992013157 -> 643479
+mulx3227 multiply -74396862273800.625679130772935550 -115616605.52826981284183992013157 -> 8601512678051025297297.7169654467 Inexact Rounded
+powx3227 power -74396862273800.625679130772935550 -115616606 -> 0E-10030 Underflow Subnormal Inexact Rounded Clamped
+remx3227 remainder -74396862273800.625679130772935550 -115616605.52826981284183992013157 -> -4565075.09478147646296920746797
+subx3227 subtract -74396862273800.625679130772935550 -115616605.52826981284183992013157 -> -74396746657195.097409317931095630 Inexact Rounded
+addx3228 add 67585560.562561229497720955705979 826.96290288608566737177503451613 -> 67586387.525464115583388327481014 Inexact Rounded
+comx3228 compare 67585560.562561229497720955705979 826.96290288608566737177503451613 -> 1
+divx3228 divide 67585560.562561229497720955705979 826.96290288608566737177503451613 -> 81727.439437354248789852715586510 Inexact Rounded
+dvix3228 divideint 67585560.562561229497720955705979 826.96290288608566737177503451613 -> 81727
+mulx3228 multiply 67585560.562561229497720955705979 826.96290288608566737177503451613 -> 55890751355.998983433895910295596 Inexact Rounded
+powx3228 power 67585560.562561229497720955705979 827 -> 1.9462204583352191108781197788255E+6475 Inexact Rounded
+remx3228 remainder 67585560.562561229497720955705979 826.96290288608566737177503451613 -> 363.39839010616042789746007924349
+subx3228 subtract 67585560.562561229497720955705979 826.96290288608566737177503451613 -> 67584733.599658343412053583930944 Inexact Rounded
+addx3229 add 6877386868.9498051860742298735156E-232 390.3154289860643509393769754551 -> 390.31542898606435093937697545510 Inexact Rounded
+comx3229 compare 6877386868.9498051860742298735156E-232 390.3154289860643509393769754551 -> -1
+divx3229 divide 6877386868.9498051860742298735156E-232 390.3154289860643509393769754551 -> 1.7620074325054038174571564409871E-225 Inexact Rounded
+dvix3229 divideint 6877386868.9498051860742298735156E-232 390.3154289860643509393769754551 -> 0
+mulx3229 multiply 6877386868.9498051860742298735156E-232 390.3154289860643509393769754551 -> 2.6843502060572691408091663822732E-220 Inexact Rounded
+powx3229 power 6877386868.9498051860742298735156E-232 390 -> 0E-10030 Underflow Subnormal Inexact Rounded Clamped
+remx3229 remainder 6877386868.9498051860742298735156E-232 390.3154289860643509393769754551 -> 6.8773868689498051860742298735156E-223
+subx3229 subtract 6877386868.9498051860742298735156E-232 390.3154289860643509393769754551 -> -390.31542898606435093937697545510 Inexact Rounded
+addx3230 add -1647335.201144609256134925838937 -186654823782.50459802235024230856 -> -186656471117.70574263160637723440 Inexact Rounded
+comx3230 compare -1647335.201144609256134925838937 -186654823782.50459802235024230856 -> 1
+divx3230 divide -1647335.201144609256134925838937 -186654823782.50459802235024230856 -> 0.0000088255699357876233458660331146583 Inexact Rounded
+dvix3230 divideint -1647335.201144609256134925838937 -186654823782.50459802235024230856 -> 0
+mulx3230 multiply -1647335.201144609256134925838937 -186654823782.50459802235024230856 -> 307483061680363807.48775619333285 Inexact Rounded
+powx3230 power -1647335.201144609256134925838937 -2 -> 3.6849876990439502152784389237891E-13 Inexact Rounded
+remx3230 remainder -1647335.201144609256134925838937 -186654823782.50459802235024230856 -> -1647335.201144609256134925838937
+subx3230 subtract -1647335.201144609256134925838937 -186654823782.50459802235024230856 -> 186653176447.30345341309410738272 Inexact Rounded
+addx3231 add 41407818140948.866630923934138155 -5156.7624534000311342310106671627E-963 -> 41407818140948.866630923934138155 Inexact Rounded
+comx3231 compare 41407818140948.866630923934138155 -5156.7624534000311342310106671627E-963 -> 1
+divx3231 divide 41407818140948.866630923934138155 -5156.7624534000311342310106671627E-963 -> -8.0298091128179204076796507697517E+972 Inexact Rounded
+dvix3231 divideint 41407818140948.866630923934138155 -5156.7624534000311342310106671627E-963 -> NaN Division_impossible
+mulx3231 multiply 41407818140948.866630923934138155 -5156.7624534000311342310106671627E-963 -> -2.1353028186646179369220834691156E-946 Inexact Rounded
+powx3231 power 41407818140948.866630923934138155 -5 -> 8.2146348556648547525693528004081E-69 Inexact Rounded
+remx3231 remainder 41407818140948.866630923934138155 -5156.7624534000311342310106671627E-963 -> NaN Division_impossible
+subx3231 subtract 41407818140948.866630923934138155 -5156.7624534000311342310106671627E-963 -> 41407818140948.866630923934138155 Inexact Rounded
+addx3232 add -6.6547424012516834662011706165297 -574454585580.06215974139884746441 -> -574454585586.71690214265053093061 Inexact Rounded
+comx3232 compare -6.6547424012516834662011706165297 -574454585580.06215974139884746441 -> 1
+divx3232 divide -6.6547424012516834662011706165297 -574454585580.06215974139884746441 -> 1.1584453442097568745411568037078E-11 Inexact Rounded
+dvix3232 divideint -6.6547424012516834662011706165297 -574454585580.06215974139884746441 -> 0
+mulx3232 multiply -6.6547424012516834662011706165297 -574454585580.06215974139884746441 -> 3822847288253.1035559206691532826 Inexact Rounded
+powx3232 power -6.6547424012516834662011706165297 -6 -> 0.000011513636283388791488128239232906 Inexact Rounded
+remx3232 remainder -6.6547424012516834662011706165297 -574454585580.06215974139884746441 -> -6.6547424012516834662011706165297
+subx3232 subtract -6.6547424012516834662011706165297 -574454585580.06215974139884746441 -> 574454585573.40741734014716399821 Inexact Rounded
+addx3233 add -27627.758745381267780885067447671 -23385972189441.709586433758111062 -> -23385972217069.468331815025891947 Inexact Rounded
+comx3233 compare -27627.758745381267780885067447671 -23385972189441.709586433758111062 -> 1
+divx3233 divide -27627.758745381267780885067447671 -23385972189441.709586433758111062 -> 1.1813816642548920194709898111624E-9 Inexact Rounded
+dvix3233 divideint -27627.758745381267780885067447671 -23385972189441.709586433758111062 -> 0
+mulx3233 multiply -27627.758745381267780885067447671 -23385972189441.709586433758111062 -> 646101997676091306.41485393678655 Inexact Rounded
+powx3233 power -27627.758745381267780885067447671 -2 -> 1.3101128009560812529198521922269E-9 Inexact Rounded
+remx3233 remainder -27627.758745381267780885067447671 -23385972189441.709586433758111062 -> -27627.758745381267780885067447671
+subx3233 subtract -27627.758745381267780885067447671 -23385972189441.709586433758111062 -> 23385972161813.950841052490330177 Inexact Rounded
+addx3234 add 209819.74379099914752963711944307E-228 -440230.6700989532467831370320266E-960 -> 2.0981974379099914752963711944307E-223 Inexact Rounded
+comx3234 compare 209819.74379099914752963711944307E-228 -440230.6700989532467831370320266E-960 -> 1
+divx3234 divide 209819.74379099914752963711944307E-228 -440230.6700989532467831370320266E-960 -> -4.7661318949867060595545765053187E+731 Inexact Rounded
+dvix3234 divideint 209819.74379099914752963711944307E-228 -440230.6700989532467831370320266E-960 -> NaN Division_impossible
+mulx3234 multiply 209819.74379099914752963711944307E-228 -440230.6700989532467831370320266E-960 -> -9.2369086409102239573726316593648E-1178 Inexact Rounded
+powx3234 power 209819.74379099914752963711944307E-228 -4 -> 5.1595828494111690910650919776705E+890 Inexact Rounded
+remx3234 remainder 209819.74379099914752963711944307E-228 -440230.6700989532467831370320266E-960 -> NaN Division_impossible
+subx3234 subtract 209819.74379099914752963711944307E-228 -440230.6700989532467831370320266E-960 -> 2.0981974379099914752963711944307E-223 Inexact Rounded
+addx3235 add 2.3488457600415474270259330865184 9182434.6660212482500376220508605E-612 -> 2.3488457600415474270259330865184 Inexact Rounded
+comx3235 compare 2.3488457600415474270259330865184 9182434.6660212482500376220508605E-612 -> 1
+divx3235 divide 2.3488457600415474270259330865184 9182434.6660212482500376220508605E-612 -> 2.5579771002708402753412266574941E+605 Inexact Rounded
+dvix3235 divideint 2.3488457600415474270259330865184 9182434.6660212482500376220508605E-612 -> NaN Division_impossible
+mulx3235 multiply 2.3488457600415474270259330865184 9182434.6660212482500376220508605E-612 -> 2.1568122732142531556215204459407E-605 Inexact Rounded
+powx3235 power 2.3488457600415474270259330865184 9 -> 2176.1583446147511579113022622255 Inexact Rounded
+remx3235 remainder 2.3488457600415474270259330865184 9182434.6660212482500376220508605E-612 -> NaN Division_impossible
+subx3235 subtract 2.3488457600415474270259330865184 9182434.6660212482500376220508605E-612 -> 2.3488457600415474270259330865184 Inexact Rounded
+addx3236 add -5107586300197.9703941034404557409 56609.05486055057838678039496686E-768 -> -5107586300197.9703941034404557409 Inexact Rounded
+comx3236 compare -5107586300197.9703941034404557409 56609.05486055057838678039496686E-768 -> -1
+divx3236 divide -5107586300197.9703941034404557409 56609.05486055057838678039496686E-768 -> -9.0225606358909877855326357402242E+775 Inexact Rounded
+dvix3236 divideint -5107586300197.9703941034404557409 56609.05486055057838678039496686E-768 -> NaN Division_impossible
+mulx3236 multiply -5107586300197.9703941034404557409 56609.05486055057838678039496686E-768 -> -2.8913563307290346152596212593532E-751 Inexact Rounded
+powx3236 power -5107586300197.9703941034404557409 6 -> 1.7753920894188022125919559565029E+76 Inexact Rounded
+remx3236 remainder -5107586300197.9703941034404557409 56609.05486055057838678039496686E-768 -> NaN Division_impossible
+subx3236 subtract -5107586300197.9703941034404557409 56609.05486055057838678039496686E-768 -> -5107586300197.9703941034404557409 Inexact Rounded
+addx3237 add -70454070095869.70717871212601390 -6200178.370249260009168888392406 -> -70454076296048.077427972135182788 Inexact Rounded
+comx3237 compare -70454070095869.70717871212601390 -6200178.370249260009168888392406 -> -1
+divx3237 divide -70454070095869.70717871212601390 -6200178.370249260009168888392406 -> 11363232.779549422490548997517194 Inexact Rounded
+dvix3237 divideint -70454070095869.70717871212601390 -6200178.370249260009168888392406 -> 11363232
+mulx3237 multiply -70454070095869.70717871212601390 -6200178.370249260009168888392406 -> 436827801504436566945.76663687924 Inexact Rounded
+powx3237 power -70454070095869.70717871212601390 -6200178 -> 0E-10030 Underflow Subnormal Inexact Rounded Clamped
+remx3237 remainder -70454070095869.70717871212601390 -6200178.370249260009168888392406 -> -4833345.467866203920028883583808
+subx3237 subtract -70454070095869.70717871212601390 -6200178.370249260009168888392406 -> -70454063895691.336929452116845012 Inexact Rounded
+addx3238 add 29119.220621511046558757900645228 3517612.8810761470018676311863010E-222 -> 29119.220621511046558757900645228 Inexact Rounded
+comx3238 compare 29119.220621511046558757900645228 3517612.8810761470018676311863010E-222 -> 1
+divx3238 divide 29119.220621511046558757900645228 3517612.8810761470018676311863010E-222 -> 8.2781197380089684063239752337467E+219 Inexact Rounded
+dvix3238 divideint 29119.220621511046558757900645228 3517612.8810761470018676311863010E-222 -> NaN Division_impossible
+mulx3238 multiply 29119.220621511046558757900645228 3517612.8810761470018676311863010E-222 -> 1.0243014554512542440592768088600E-211 Inexact Rounded
+powx3238 power 29119.220621511046558757900645228 4 -> 718983605328417461.32835984217255 Inexact Rounded
+remx3238 remainder 29119.220621511046558757900645228 3517612.8810761470018676311863010E-222 -> NaN Division_impossible
+subx3238 subtract 29119.220621511046558757900645228 3517612.8810761470018676311863010E-222 -> 29119.220621511046558757900645228 Inexact Rounded
+addx3239 add -5168.2214111091132913776042214525 -5690274.0971173476527123568627720 -> -5695442.3185284567660037344669935 Inexact Rounded
+comx3239 compare -5168.2214111091132913776042214525 -5690274.0971173476527123568627720 -> 1
+divx3239 divide -5168.2214111091132913776042214525 -5690274.0971173476527123568627720 -> 0.00090825526554639915580539316714451 Inexact Rounded
+dvix3239 divideint -5168.2214111091132913776042214525 -5690274.0971173476527123568627720 -> 0
+mulx3239 multiply -5168.2214111091132913776042214525 -5690274.0971173476527123568627720 -> 29408596423.801454053855793898323 Inexact Rounded
+powx3239 power -5168.2214111091132913776042214525 -5690274 -> 0E-10030 Underflow Subnormal Inexact Rounded Clamped
+remx3239 remainder -5168.2214111091132913776042214525 -5690274.0971173476527123568627720 -> -5168.2214111091132913776042214525
+subx3239 subtract -5168.2214111091132913776042214525 -5690274.0971173476527123568627720 -> 5685105.8757062385394209792585505 Inexact Rounded
+addx3240 add 33783.060857197067391462144517964 -2070.0806959465088198508322815406 -> 31712.980161250558571611312236423 Inexact Rounded
+comx3240 compare 33783.060857197067391462144517964 -2070.0806959465088198508322815406 -> 1
+divx3240 divide 33783.060857197067391462144517964 -2070.0806959465088198508322815406 -> -16.319683055519892881394358449220 Inexact Rounded
+dvix3240 divideint 33783.060857197067391462144517964 -2070.0806959465088198508322815406 -> -16
+mulx3240 multiply 33783.060857197067391462144517964 -2070.0806959465088198508322815406 -> -69933662.130469766080574235843448 Inexact Rounded
+powx3240 power 33783.060857197067391462144517964 -2070 -> 3.9181336001803008597293818984406E-9375 Inexact Rounded
+remx3240 remainder 33783.060857197067391462144517964 -2070.0806959465088198508322815406 -> 661.7697220529262738488280133144
+subx3240 subtract 33783.060857197067391462144517964 -2070.0806959465088198508322815406 -> 35853.141553143576211312976799505 Inexact Rounded
+addx3241 add 42207435091050.840296353874733169E-905 73330633078.828216018536326743325E+976 -> 7.3330633078828216018536326743325E+986 Inexact Rounded
+comx3241 compare 42207435091050.840296353874733169E-905 73330633078.828216018536326743325E+976 -> -1
+divx3241 divide 42207435091050.840296353874733169E-905 73330633078.828216018536326743325E+976 -> 5.7557712676064206636178247554056E-1879 Inexact Rounded
+dvix3241 divideint 42207435091050.840296353874733169E-905 73330633078.828216018536326743325E+976 -> 0
+mulx3241 multiply 42207435091050.840296353874733169E-905 73330633078.828216018536326743325E+976 -> 3.0950979358603075650592433398939E+95 Inexact Rounded
+powx3241 power 42207435091050.840296353874733169E-905 7 -> 2.3862872940615283599573082966642E-6240 Inexact Rounded
+remx3241 remainder 42207435091050.840296353874733169E-905 73330633078.828216018536326743325E+976 -> 4.2207435091050840296353874733169E-892
+subx3241 subtract 42207435091050.840296353874733169E-905 73330633078.828216018536326743325E+976 -> -7.3330633078828216018536326743325E+986 Inexact Rounded
+addx3242 add -71800.806700868784841045406679641 -39617456964250697902519150526701 -> -39617456964250697902519150598502 Inexact Rounded
+comx3242 compare -71800.806700868784841045406679641 -39617456964250697902519150526701 -> 1
+divx3242 divide -71800.806700868784841045406679641 -39617456964250697902519150526701 -> 1.8123527405017220178579049964126E-27 Inexact Rounded
+dvix3242 divideint -71800.806700868784841045406679641 -39617456964250697902519150526701 -> 0
+mulx3242 multiply -71800.806700868784841045406679641 -39617456964250697902519150526701 -> 2.8445653694701522164901827524538E+36 Inexact Rounded
+powx3242 power -71800.806700868784841045406679641 -4 -> 3.7625536850895480882178599428774E-20 Inexact Rounded
+remx3242 remainder -71800.806700868784841045406679641 -39617456964250697902519150526701 -> -71800.806700868784841045406679641
+subx3242 subtract -71800.806700868784841045406679641 -39617456964250697902519150526701 -> 39617456964250697902519150454900 Inexact Rounded
+addx3243 add 53627480801.631504892310016062160 328259.56947661049313311983109503 -> 53627809061.200981502803149181991 Inexact Rounded
+comx3243 compare 53627480801.631504892310016062160 328259.56947661049313311983109503 -> 1
+divx3243 divide 53627480801.631504892310016062160 328259.56947661049313311983109503 -> 163369.13159039717901500465109839 Inexact Rounded
+dvix3243 divideint 53627480801.631504892310016062160 328259.56947661049313311983109503 -> 163369
+mulx3243 multiply 53627480801.631504892310016062160 328259.56947661049313311983109503 -> 17603733760058752.363123585224369 Inexact Rounded
+powx3243 power 53627480801.631504892310016062160 328260 -> Infinity Overflow Inexact Rounded
+remx3243 remainder 53627480801.631504892310016062160 328259.56947661049313311983109503 -> 43195.80712523964536237599604393
+subx3243 subtract 53627480801.631504892310016062160 328259.56947661049313311983109503 -> 53627152542.062028281816882942329 Inexact Rounded
+addx3244 add -5052601598.5559371338428368438728 -97855372.224321664785314782556064 -> -5150456970.7802587986281516264289 Inexact Rounded
+comx3244 compare -5052601598.5559371338428368438728 -97855372.224321664785314782556064 -> -1
+divx3244 divide -5052601598.5559371338428368438728 -97855372.224321664785314782556064 -> 51.633359351732432283879274192947 Inexact Rounded
+dvix3244 divideint -5052601598.5559371338428368438728 -97855372.224321664785314782556064 -> 51
+mulx3244 multiply -5052601598.5559371338428368438728 -97855372.224321664785314782556064 -> 494424210127893893.12581512954787 Inexact Rounded
+powx3244 power -5052601598.5559371338428368438728 -97855372 -> 0E-10030 Underflow Subnormal Inexact Rounded Clamped
+remx3244 remainder -5052601598.5559371338428368438728 -97855372.224321664785314782556064 -> -61977615.115532229791782933513536
+subx3244 subtract -5052601598.5559371338428368438728 -97855372.224321664785314782556064 -> -4954746226.3316154690575220613167 Inexact Rounded
+addx3245 add 4208134320733.7069742988228068191E+146 4270869.1760149477598920960628392E+471 -> 4.2708691760149477598920960628392E+477 Inexact Rounded
+comx3245 compare 4208134320733.7069742988228068191E+146 4270869.1760149477598920960628392E+471 -> -1
+divx3245 divide 4208134320733.7069742988228068191E+146 4270869.1760149477598920960628392E+471 -> 9.8531098643021951048744078027283E-320 Inexact Rounded
+dvix3245 divideint 4208134320733.7069742988228068191E+146 4270869.1760149477598920960628392E+471 -> 0
+mulx3245 multiply 4208134320733.7069742988228068191E+146 4270869.1760149477598920960628392E+471 -> 1.7972391158952189002169082753183E+636 Inexact Rounded
+powx3245 power 4208134320733.7069742988228068191E+146 4 -> 3.1358723439830872127129821963857E+634 Inexact Rounded
+remx3245 remainder 4208134320733.7069742988228068191E+146 4270869.1760149477598920960628392E+471 -> 4.2081343207337069742988228068191E+158
+subx3245 subtract 4208134320733.7069742988228068191E+146 4270869.1760149477598920960628392E+471 -> -4.2708691760149477598920960628392E+477 Inexact Rounded
+addx3246 add -8.5077009657942581515590471189084E+308 9652145155.374217047842114042376E-250 -> -8.5077009657942581515590471189084E+308 Inexact Rounded
+comx3246 compare -8.5077009657942581515590471189084E+308 9652145155.374217047842114042376E-250 -> -1
+divx3246 divide -8.5077009657942581515590471189084E+308 9652145155.374217047842114042376E-250 -> -8.8143110457236089978070419047970E+548 Inexact Rounded
+dvix3246 divideint -8.5077009657942581515590471189084E+308 9652145155.374217047842114042376E-250 -> NaN Division_impossible
+mulx3246 multiply -8.5077009657942581515590471189084E+308 9652145155.374217047842114042376E-250 -> -8.2117564660363596283732942091852E+68 Inexact Rounded
+powx3246 power -8.5077009657942581515590471189084E+308 10 -> 1.9866536812573207868350640760678E+3089 Inexact Rounded
+remx3246 remainder -8.5077009657942581515590471189084E+308 9652145155.374217047842114042376E-250 -> NaN Division_impossible
+subx3246 subtract -8.5077009657942581515590471189084E+308 9652145155.374217047842114042376E-250 -> -8.5077009657942581515590471189084E+308 Inexact Rounded
+addx3247 add -9504.9703032286960790904181078063E+619 -86.245956949049186533469206485003 -> -9.5049703032286960790904181078063E+622 Inexact Rounded
+comx3247 compare -9504.9703032286960790904181078063E+619 -86.245956949049186533469206485003 -> -1
+divx3247 divide -9504.9703032286960790904181078063E+619 -86.245956949049186533469206485003 -> 1.1020772033225707125391212519421E+621 Inexact Rounded
+dvix3247 divideint -9504.9703032286960790904181078063E+619 -86.245956949049186533469206485003 -> NaN Division_impossible
+mulx3247 multiply -9504.9703032286960790904181078063E+619 -86.245956949049186533469206485003 -> 8.1976525957425311427858087117655E+624 Inexact Rounded
+powx3247 power -9504.9703032286960790904181078063E+619 -86 -> 0E-10030 Underflow Subnormal Inexact Rounded Clamped
+remx3247 remainder -9504.9703032286960790904181078063E+619 -86.245956949049186533469206485003 -> NaN Division_impossible
+subx3247 subtract -9504.9703032286960790904181078063E+619 -86.245956949049186533469206485003 -> -9.5049703032286960790904181078063E+622 Inexact Rounded
+addx3248 add -440220916.66716743026896931194749 -102725.01594377871560564824358775 -> -440323641.68311120898457496019108 Inexact Rounded
+comx3248 compare -440220916.66716743026896931194749 -102725.01594377871560564824358775 -> -1
+divx3248 divide -440220916.66716743026896931194749 -102725.01594377871560564824358775 -> 4285.4305022264473269770246126234 Inexact Rounded
+dvix3248 divideint -440220916.66716743026896931194749 -102725.01594377871560564824358775 -> 4285
+mulx3248 multiply -440220916.66716743026896931194749 -102725.01594377871560564824358775 -> 45221700683419.655596771711603505 Inexact Rounded
+powx3248 power -440220916.66716743026896931194749 -102725 -> -0E-10030 Underflow Subnormal Inexact Rounded Clamped
+remx3248 remainder -440220916.66716743026896931194749 -102725.01594377871560564824358775 -> -44223.34807563389876658817398125
+subx3248 subtract -440220916.66716743026896931194749 -102725.01594377871560564824358775 -> -440118191.65122365155336366370390 Inexact Rounded
+addx3249 add -46.250735086006350517943464758019 14656357555174.263295266074908024 -> 14656357555128.012560180068557506 Inexact Rounded
+comx3249 compare -46.250735086006350517943464758019 14656357555174.263295266074908024 -> -1
+divx3249 divide -46.250735086006350517943464758019 14656357555174.263295266074908024 -> -3.1556773169523313932207725522866E-12 Inexact Rounded
+dvix3249 divideint -46.250735086006350517943464758019 14656357555174.263295266074908024 -> -0
+mulx3249 multiply -46.250735086006350517943464758019 14656357555174.263295266074908024 -> -677867310610152.55569620459788530 Inexact Rounded
+powx3249 power -46.250735086006350517943464758019 1 -> -46.250735086006350517943464758019
+remx3249 remainder -46.250735086006350517943464758019 14656357555174.263295266074908024 -> -46.250735086006350517943464758019
+subx3249 subtract -46.250735086006350517943464758019 14656357555174.263295266074908024 -> -14656357555220.514030352081258542 Inexact Rounded
+addx3250 add -61641121299391.316420647102699627E+763 -91896469863.461006903590004188187E+474 -> -6.1641121299391316420647102699627E+776 Inexact Rounded
+comx3250 compare -61641121299391.316420647102699627E+763 -91896469863.461006903590004188187E+474 -> -1
+divx3250 divide -61641121299391.316420647102699627E+763 -91896469863.461006903590004188187E+474 -> 6.7076702065897819604716946852581E+291 Inexact Rounded
+dvix3250 divideint -61641121299391.316420647102699627E+763 -91896469863.461006903590004188187E+474 -> NaN Division_impossible
+mulx3250 multiply -61641121299391.316420647102699627E+763 -91896469863.461006903590004188187E+474 -> 5.6646014458394584921579417504939E+1261 Inexact Rounded
+powx3250 power -61641121299391.316420647102699627E+763 -9 -> -7.7833261179975532508748150708605E-6992 Inexact Rounded
+remx3250 remainder -61641121299391.316420647102699627E+763 -91896469863.461006903590004188187E+474 -> NaN Division_impossible
+subx3250 subtract -61641121299391.316420647102699627E+763 -91896469863.461006903590004188187E+474 -> -6.1641121299391316420647102699627E+776 Inexact Rounded
+addx3251 add 96668419802749.555738010239087449E-838 -19498732131365824921639467044927E-542 -> -1.9498732131365824921639467044927E-511 Inexact Rounded
+comx3251 compare 96668419802749.555738010239087449E-838 -19498732131365824921639467044927E-542 -> 1
+divx3251 divide 96668419802749.555738010239087449E-838 -19498732131365824921639467044927E-542 -> -4.9576772044192514715453215933704E-314 Inexact Rounded
+dvix3251 divideint 96668419802749.555738010239087449E-838 -19498732131365824921639467044927E-542 -> -0
+mulx3251 multiply 96668419802749.555738010239087449E-838 -19498732131365824921639467044927E-542 -> -1.8849116232962331617140676274611E-1335 Inexact Rounded
+powx3251 power 96668419802749.555738010239087449E-838 -2 -> 1.0701157625268896323611633350003E+1648 Inexact Rounded
+remx3251 remainder 96668419802749.555738010239087449E-838 -19498732131365824921639467044927E-542 -> 9.6668419802749555738010239087449E-825
+subx3251 subtract 96668419802749.555738010239087449E-838 -19498732131365824921639467044927E-542 -> 1.9498732131365824921639467044927E-511 Inexact Rounded
+addx3252 add -8534543911197995906031245719519E+124 16487117050031.594886541650897974 -> -8.5345439111979959060312457195190E+154 Inexact Rounded
+comx3252 compare -8534543911197995906031245719519E+124 16487117050031.594886541650897974 -> -1
+divx3252 divide -8534543911197995906031245719519E+124 16487117050031.594886541650897974 -> -5.1764925822381062287959523371316E+141 Inexact Rounded
+dvix3252 divideint -8534543911197995906031245719519E+124 16487117050031.594886541650897974 -> NaN Division_impossible
+mulx3252 multiply -8534543911197995906031245719519E+124 16487117050031.594886541650897974 -> -1.4071002443255581217471698731240E+168 Inexact Rounded
+powx3252 power -8534543911197995906031245719519E+124 2 -> 7.2838439772166785429482995041337E+309 Inexact Rounded
+remx3252 remainder -8534543911197995906031245719519E+124 16487117050031.594886541650897974 -> NaN Division_impossible
+subx3252 subtract -8534543911197995906031245719519E+124 16487117050031.594886541650897974 -> -8.5345439111979959060312457195190E+154 Inexact Rounded
+addx3253 add -62663404777.352508979582846931050 9.2570938837239134052589184917186E+916 -> 9.2570938837239134052589184917186E+916 Inexact Rounded
+comx3253 compare -62663404777.352508979582846931050 9.2570938837239134052589184917186E+916 -> -1
+divx3253 divide -62663404777.352508979582846931050 9.2570938837239134052589184917186E+916 -> -6.7692307720384142592597124956951E-907 Inexact Rounded
+dvix3253 divideint -62663404777.352508979582846931050 9.2570938837239134052589184917186E+916 -> -0
+mulx3253 multiply -62663404777.352508979582846931050 9.2570938837239134052589184917186E+916 -> -5.8008102109774576654709018012876E+927 Inexact Rounded
+powx3253 power -62663404777.352508979582846931050 9 -> -1.4897928814133059615670462753825E+97 Inexact Rounded
+remx3253 remainder -62663404777.352508979582846931050 9.2570938837239134052589184917186E+916 -> -62663404777.352508979582846931050
+subx3253 subtract -62663404777.352508979582846931050 9.2570938837239134052589184917186E+916 -> -9.2570938837239134052589184917186E+916 Inexact Rounded
+addx3254 add 1.744601214474560992754529320172E-827 -17.353669504253419489494030651507E-631 -> -1.7353669504253419489494030651507E-630 Inexact Rounded
+comx3254 compare 1.744601214474560992754529320172E-827 -17.353669504253419489494030651507E-631 -> 1
+divx3254 divide 1.744601214474560992754529320172E-827 -17.353669504253419489494030651507E-631 -> -1.0053212169604565230497117966004E-197 Inexact Rounded
+dvix3254 divideint 1.744601214474560992754529320172E-827 -17.353669504253419489494030651507E-631 -> -0
+mulx3254 multiply 1.744601214474560992754529320172E-827 -17.353669504253419489494030651507E-631 -> -3.0275232892710668432895049546233E-1457 Inexact Rounded
+powx3254 power 1.744601214474560992754529320172E-827 -2 -> 3.2855468099615282394992542515980E+1653 Inexact Rounded
+remx3254 remainder 1.744601214474560992754529320172E-827 -17.353669504253419489494030651507E-631 -> 1.744601214474560992754529320172E-827
+subx3254 subtract 1.744601214474560992754529320172E-827 -17.353669504253419489494030651507E-631 -> 1.7353669504253419489494030651507E-630 Inexact Rounded
+addx3255 add 0367191549036702224827734853471 4410320662415266533763143837742E+721 -> 4.4103206624152665337631438377420E+751 Inexact Rounded
+comx3255 compare 0367191549036702224827734853471 4410320662415266533763143837742E+721 -> -1
+divx3255 divide 0367191549036702224827734853471 4410320662415266533763143837742E+721 -> 8.3257335949720619093963917942525E-723 Inexact Rounded
+dvix3255 divideint 0367191549036702224827734853471 4410320662415266533763143837742E+721 -> 0
+mulx3255 multiply 0367191549036702224827734853471 4410320662415266533763143837742E+721 -> 1.6194324757808363802947192054966E+781 Inexact Rounded
+powx3255 power 0367191549036702224827734853471 4 -> 1.8179030119354318182493703269258E+118 Inexact Rounded
+remx3255 remainder 0367191549036702224827734853471 4410320662415266533763143837742E+721 -> 367191549036702224827734853471
+subx3255 subtract 0367191549036702224827734853471 4410320662415266533763143837742E+721 -> -4.4103206624152665337631438377420E+751 Inexact Rounded
+addx3256 add 097704116.4492566721965710365073 -96736.400939809433556067504289145 -> 97607380.048316862763014969003011 Inexact Rounded
+comx3256 compare 097704116.4492566721965710365073 -96736.400939809433556067504289145 -> 1
+divx3256 divide 097704116.4492566721965710365073 -96736.400939809433556067504289145 -> -1010.0036335861757252324592571874 Inexact Rounded
+dvix3256 divideint 097704116.4492566721965710365073 -96736.400939809433556067504289145 -> -1010
+mulx3256 multiply 097704116.4492566721965710365073 -96736.400939809433556067504289145 -> -9451544582305.1234805483449772252 Inexact Rounded
+powx3256 power 097704116.4492566721965710365073 -96736 -> 0E-10030 Underflow Subnormal Inexact Rounded Clamped
+remx3256 remainder 097704116.4492566721965710365073 -96736.400939809433556067504289145 -> 351.500049144304942857175263550
+subx3256 subtract 097704116.4492566721965710365073 -96736.400939809433556067504289145 -> 97800852.850196481630127104011589 Inexact Rounded
+addx3257 add 19533298.147150158931958733807878 80.141668338350708476637377647025E-641 -> 19533298.147150158931958733807878 Inexact Rounded
+comx3257 compare 19533298.147150158931958733807878 80.141668338350708476637377647025E-641 -> 1
+divx3257 divide 19533298.147150158931958733807878 80.141668338350708476637377647025E-641 -> 2.4373460837728485395672882395171E+646 Inexact Rounded
+dvix3257 divideint 19533298.147150158931958733807878 80.141668338350708476637377647025E-641 -> NaN Division_impossible
+mulx3257 multiply 19533298.147150158931958733807878 80.141668338350708476637377647025E-641 -> 1.5654311016630284502459158971272E-632 Inexact Rounded
+powx3257 power 19533298.147150158931958733807878 8 -> 2.1193595047638230427530063654613E+58 Inexact Rounded
+remx3257 remainder 19533298.147150158931958733807878 80.141668338350708476637377647025E-641 -> NaN Division_impossible
+subx3257 subtract 19533298.147150158931958733807878 80.141668338350708476637377647025E-641 -> 19533298.147150158931958733807878 Inexact Rounded
+addx3258 add -23765003221220177430797028997378 -15203369569.373411506379096871224E-945 -> -23765003221220177430797028997378 Inexact Rounded
+comx3258 compare -23765003221220177430797028997378 -15203369569.373411506379096871224E-945 -> -1
+divx3258 divide -23765003221220177430797028997378 -15203369569.373411506379096871224E-945 -> 1.5631405336020930064824135669541E+966 Inexact Rounded
+dvix3258 divideint -23765003221220177430797028997378 -15203369569.373411506379096871224E-945 -> NaN Division_impossible
+mulx3258 multiply -23765003221220177430797028997378 -15203369569.373411506379096871224E-945 -> 3.6130812678955994625210007005216E-904 Inexact Rounded
+powx3258 power -23765003221220177430797028997378 -2 -> 1.7706154318483481190364979209436E-63 Inexact Rounded
+remx3258 remainder -23765003221220177430797028997378 -15203369569.373411506379096871224E-945 -> NaN Division_impossible
+subx3258 subtract -23765003221220177430797028997378 -15203369569.373411506379096871224E-945 -> -23765003221220177430797028997378 Inexact Rounded
+addx3259 add 129255.41937932433359193338910552E+932 -281253953.38990382799508873560320 -> 1.2925541937932433359193338910552E+937 Inexact Rounded
+comx3259 compare 129255.41937932433359193338910552E+932 -281253953.38990382799508873560320 -> 1
+divx3259 divide 129255.41937932433359193338910552E+932 -281253953.38990382799508873560320 -> -4.5956836453828213050223260551064E+928 Inexact Rounded
+dvix3259 divideint 129255.41937932433359193338910552E+932 -281253953.38990382799508873560320 -> NaN Division_impossible
+mulx3259 multiply 129255.41937932433359193338910552E+932 -281253953.38990382799508873560320 -> -3.6353597697504958096931088780367E+945 Inexact Rounded
+powx3259 power 129255.41937932433359193338910552E+932 -281253953 -> 0E-10030 Underflow Subnormal Inexact Rounded Clamped
+remx3259 remainder 129255.41937932433359193338910552E+932 -281253953.38990382799508873560320 -> NaN Division_impossible
+subx3259 subtract 129255.41937932433359193338910552E+932 -281253953.38990382799508873560320 -> 1.2925541937932433359193338910552E+937 Inexact Rounded
+addx3260 add -86863.276249466008289214762980838 531.50602652732088208397655484476 -> -86331.770222938687407130786425993 Inexact Rounded
+comx3260 compare -86863.276249466008289214762980838 531.50602652732088208397655484476 -> -1
+divx3260 divide -86863.276249466008289214762980838 531.50602652732088208397655484476 -> -163.42858201815891408475902229649 Inexact Rounded
+dvix3260 divideint -86863.276249466008289214762980838 531.50602652732088208397655484476 -> -163
+mulx3260 multiply -86863.276249466008289214762980838 531.50602652732088208397655484476 -> -46168354.810498682140456143534524 Inexact Rounded
+powx3260 power -86863.276249466008289214762980838 532 -> 2.8897579184173839519859710217510E+2627 Inexact Rounded
+remx3260 remainder -86863.276249466008289214762980838 531.50602652732088208397655484476 -> -227.79392551270450952658454114212
+subx3260 subtract -86863.276249466008289214762980838 531.50602652732088208397655484476 -> -87394.782275993329171298739535683 Inexact Rounded
+addx3261 add -40707.169006771111855573524157083 -68795521421321853333274411827749 -> -68795521421321853333274411868456 Inexact Rounded
+comx3261 compare -40707.169006771111855573524157083 -68795521421321853333274411827749 -> 1
+divx3261 divide -40707.169006771111855573524157083 -68795521421321853333274411827749 -> 5.9171248601300236694386185513139E-28 Inexact Rounded
+dvix3261 divideint -40707.169006771111855573524157083 -68795521421321853333274411827749 -> 0
+mulx3261 multiply -40707.169006771111855573524157083 -68795521421321853333274411827749 -> 2.8004709174066910577370895499575E+36 Inexact Rounded
+powx3261 power -40707.169006771111855573524157083 -7 -> -5.3988802915897595722440392884051E-33 Inexact Rounded
+remx3261 remainder -40707.169006771111855573524157083 -68795521421321853333274411827749 -> -40707.169006771111855573524157083
+subx3261 subtract -40707.169006771111855573524157083 -68795521421321853333274411827749 -> 68795521421321853333274411787042 Inexact Rounded
+addx3262 add -90838752568673.728630494658778003E+095 -738.01370301217606577533107981431 -> -9.0838752568673728630494658778003E+108 Inexact Rounded
+comx3262 compare -90838752568673.728630494658778003E+095 -738.01370301217606577533107981431 -> -1
+divx3262 divide -90838752568673.728630494658778003E+095 -738.01370301217606577533107981431 -> 1.2308545518588430875268553851424E+106 Inexact Rounded
+dvix3262 divideint -90838752568673.728630494658778003E+095 -738.01370301217606577533107981431 -> NaN Division_impossible
+mulx3262 multiply -90838752568673.728630494658778003E+095 -738.01370301217606577533107981431 -> 6.7040244160213718891633678248127E+111 Inexact Rounded
+powx3262 power -90838752568673.728630494658778003E+095 -738 -> 0E-10030 Underflow Subnormal Inexact Rounded Clamped
+remx3262 remainder -90838752568673.728630494658778003E+095 -738.01370301217606577533107981431 -> NaN Division_impossible
+subx3262 subtract -90838752568673.728630494658778003E+095 -738.01370301217606577533107981431 -> -9.0838752568673728630494658778003E+108 Inexact Rounded
+addx3263 add -4245360967593.9206771555839718158E-682 -3.119606239042530207103203508057 -> -3.1196062390425302071032035080570 Inexact Rounded
+comx3263 compare -4245360967593.9206771555839718158E-682 -3.119606239042530207103203508057 -> 1
+divx3263 divide -4245360967593.9206771555839718158E-682 -3.119606239042530207103203508057 -> 1.3608643662980066356437236081969E-670 Inexact Rounded
+dvix3263 divideint -4245360967593.9206771555839718158E-682 -3.119606239042530207103203508057 -> 0
+mulx3263 multiply -4245360967593.9206771555839718158E-682 -3.119606239042530207103203508057 -> 1.3243854561493627844105290415330E-669 Inexact Rounded
+powx3263 power -4245360967593.9206771555839718158E-682 -3 -> -1.3069414504933253288042820429894E+2008 Inexact Rounded
+remx3263 remainder -4245360967593.9206771555839718158E-682 -3.119606239042530207103203508057 -> -4.2453609675939206771555839718158E-670
+subx3263 subtract -4245360967593.9206771555839718158E-682 -3.119606239042530207103203508057 -> 3.1196062390425302071032035080570 Inexact Rounded
+addx3264 add -3422145405774.0800213000547612240E-023 -60810.964656409650839011321706310 -> -60810.964656409685060465379447110 Inexact Rounded
+comx3264 compare -3422145405774.0800213000547612240E-023 -60810.964656409650839011321706310 -> 1
+divx3264 divide -3422145405774.0800213000547612240E-023 -60810.964656409650839011321706310 -> 5.6275137635287882875914124742650E-16 Inexact Rounded
+dvix3264 divideint -3422145405774.0800213000547612240E-023 -60810.964656409650839011321706310 -> 0
+mulx3264 multiply -3422145405774.0800213000547612240E-023 -60810.964656409650839011321706310 -> 0.0000020810396331962224323288744910607 Inexact Rounded
+powx3264 power -3422145405774.0800213000547612240E-023 -60811 -> -Infinity Overflow Inexact Rounded
+remx3264 remainder -3422145405774.0800213000547612240E-023 -60810.964656409650839011321706310 -> -3.4221454057740800213000547612240E-11
+subx3264 subtract -3422145405774.0800213000547612240E-023 -60810.964656409650839011321706310 -> 60810.964656409616617557263965510 Inexact Rounded
+addx3265 add -24521811.07649485796598387627478E-661 -94860846133404815410816234000694 -> -94860846133404815410816234000694 Inexact Rounded
+comx3265 compare -24521811.07649485796598387627478E-661 -94860846133404815410816234000694 -> 1
+divx3265 divide -24521811.07649485796598387627478E-661 -94860846133404815410816234000694 -> 2.5850297647576657819483988845904E-686 Inexact Rounded
+dvix3265 divideint -24521811.07649485796598387627478E-661 -94860846133404815410816234000694 -> 0
+mulx3265 multiply -24521811.07649485796598387627478E-661 -94860846133404815410816234000694 -> 2.3261597474398006215017751785104E-622 Inexact Rounded
+powx3265 power -24521811.07649485796598387627478E-661 -9 -> -3.1190843559949184618590264246586E+5882 Inexact Rounded
+remx3265 remainder -24521811.07649485796598387627478E-661 -94860846133404815410816234000694 -> -2.452181107649485796598387627478E-654
+subx3265 subtract -24521811.07649485796598387627478E-661 -94860846133404815410816234000694 -> 94860846133404815410816234000694 Inexact Rounded
+addx3266 add -5042529937498.8944492248538951438 3891904674.4549170968807145612549 -> -5038638032824.4395321279731805825 Inexact Rounded
+comx3266 compare -5042529937498.8944492248538951438 3891904674.4549170968807145612549 -> -1
+divx3266 divide -5042529937498.8944492248538951438 3891904674.4549170968807145612549 -> -1295.6457979549894351378127413283 Inexact Rounded
+dvix3266 divideint -5042529937498.8944492248538951438 3891904674.4549170968807145612549 -> -1295
+mulx3266 multiply -5042529937498.8944492248538951438 3891904674.4549170968807145612549 -> -19625045834830808256871.952659048 Inexact Rounded
+powx3266 power -5042529937498.8944492248538951438 4 -> 6.4653782991800009492580180960839E+50 Inexact Rounded
+remx3266 remainder -5042529937498.8944492248538951438 3891904674.4549170968807145612549 -> -2513384079.7768087643285383187045
+subx3266 subtract -5042529937498.8944492248538951438 3891904674.4549170968807145612549 -> -5046421842173.3493663217346097051 Inexact Rounded
+addx3267 add -535824163.54531747646293693868651E-665 2732988.5891363639325008206099712 -> 2732988.5891363639325008206099712 Inexact Rounded
+comx3267 compare -535824163.54531747646293693868651E-665 2732988.5891363639325008206099712 -> -1
+divx3267 divide -535824163.54531747646293693868651E-665 2732988.5891363639325008206099712 -> -1.9605795855687791246611683328346E-663 Inexact Rounded
+dvix3267 divideint -535824163.54531747646293693868651E-665 2732988.5891363639325008206099712 -> -0
+mulx3267 multiply -535824163.54531747646293693868651E-665 2732988.5891363639325008206099712 -> -1.4644013247528895376254850705597E-650 Inexact Rounded
+powx3267 power -535824163.54531747646293693868651E-665 2732989 -> -0E-10030 Underflow Subnormal Inexact Rounded Clamped
+remx3267 remainder -535824163.54531747646293693868651E-665 2732988.5891363639325008206099712 -> -5.3582416354531747646293693868651E-657
+subx3267 subtract -535824163.54531747646293693868651E-665 2732988.5891363639325008206099712 -> -2732988.5891363639325008206099712 Inexact Rounded
+addx3268 add 24032.702008553084252925140858134E-509 52864854.899420632375589206704068 -> 52864854.899420632375589206704068 Inexact Rounded
+comx3268 compare 24032.702008553084252925140858134E-509 52864854.899420632375589206704068 -> -1
+divx3268 divide 24032.702008553084252925140858134E-509 52864854.899420632375589206704068 -> 4.5460641203455697917573431961511E-513 Inexact Rounded
+dvix3268 divideint 24032.702008553084252925140858134E-509 52864854.899420632375589206704068 -> 0
+mulx3268 multiply 24032.702008553084252925140858134E-509 52864854.899420632375589206704068 -> 1.2704853045231735885074945710576E-497 Inexact Rounded
+powx3268 power 24032.702008553084252925140858134E-509 52864855 -> 0E-10030 Underflow Subnormal Inexact Rounded Clamped
+remx3268 remainder 24032.702008553084252925140858134E-509 52864854.899420632375589206704068 -> 2.4032702008553084252925140858134E-505
+subx3268 subtract 24032.702008553084252925140858134E-509 52864854.899420632375589206704068 -> -52864854.899420632375589206704068 Inexact Rounded
+addx3269 add 71553220259.938950698030519906727E-496 754.44220417415325444943566016062 -> 754.44220417415325444943566016062 Inexact Rounded
+comx3269 compare 71553220259.938950698030519906727E-496 754.44220417415325444943566016062 -> -1
+divx3269 divide 71553220259.938950698030519906727E-496 754.44220417415325444943566016062 -> 9.4842547068617879794218050008353E-489 Inexact Rounded
+dvix3269 divideint 71553220259.938950698030519906727E-496 754.44220417415325444943566016062 -> 0
+mulx3269 multiply 71553220259.938950698030519906727E-496 754.44220417415325444943566016062 -> 5.3982769208667021044675146787248E-483 Inexact Rounded
+powx3269 power 71553220259.938950698030519906727E-496 754 -> 0E-10030 Underflow Subnormal Inexact Rounded Clamped
+remx3269 remainder 71553220259.938950698030519906727E-496 754.44220417415325444943566016062 -> 7.1553220259938950698030519906727E-486
+subx3269 subtract 71553220259.938950698030519906727E-496 754.44220417415325444943566016062 -> -754.44220417415325444943566016062 Inexact Rounded
+addx3270 add 35572.960284795962697740953932508 520.39506364687594082725754878910E-731 -> 35572.960284795962697740953932508 Inexact Rounded
+comx3270 compare 35572.960284795962697740953932508 520.39506364687594082725754878910E-731 -> 1
+divx3270 divide 35572.960284795962697740953932508 520.39506364687594082725754878910E-731 -> 6.8357605153869556504869061469852E+732 Inexact Rounded
+dvix3270 divideint 35572.960284795962697740953932508 520.39506364687594082725754878910E-731 -> NaN Division_impossible
+mulx3270 multiply 35572.960284795962697740953932508 520.39506364687594082725754878910E-731 -> 1.8511992931514185102474609686066E-724 Inexact Rounded
+powx3270 power 35572.960284795962697740953932508 5 -> 56963942247985404337401.149353169 Inexact Rounded
+remx3270 remainder 35572.960284795962697740953932508 520.39506364687594082725754878910E-731 -> NaN Division_impossible
+subx3270 subtract 35572.960284795962697740953932508 520.39506364687594082725754878910E-731 -> 35572.960284795962697740953932508 Inexact Rounded
+addx3271 add 53035405018123760598334895413057E+818 -9558464247240.4476790042911379151 -> 5.3035405018123760598334895413057E+849 Inexact Rounded
+comx3271 compare 53035405018123760598334895413057E+818 -9558464247240.4476790042911379151 -> 1
+divx3271 divide 53035405018123760598334895413057E+818 -9558464247240.4476790042911379151 -> -5.5485278436266802470202487233285E+836 Inexact Rounded
+dvix3271 divideint 53035405018123760598334895413057E+818 -9558464247240.4476790042911379151 -> NaN Division_impossible
+mulx3271 multiply 53035405018123760598334895413057E+818 -9558464247240.4476790042911379151 -> -5.0693702270365259274203181894613E+862 Inexact Rounded
+powx3271 power 53035405018123760598334895413057E+818 -10 -> 5.6799053935427267944455848135618E-8498 Inexact Rounded
+remx3271 remainder 53035405018123760598334895413057E+818 -9558464247240.4476790042911379151 -> NaN Division_impossible
+subx3271 subtract 53035405018123760598334895413057E+818 -9558464247240.4476790042911379151 -> 5.3035405018123760598334895413057E+849 Inexact Rounded
+addx3272 add 95.490751127249945886828257312118 987.01498316307365714167410690192E+133 -> 9.8701498316307365714167410690192E+135 Inexact Rounded
+comx3272 compare 95.490751127249945886828257312118 987.01498316307365714167410690192E+133 -> -1
+divx3272 divide 95.490751127249945886828257312118 987.01498316307365714167410690192E+133 -> 9.6747012716293341927566515915016E-135 Inexact Rounded
+dvix3272 divideint 95.490751127249945886828257312118 987.01498316307365714167410690192E+133 -> 0
+mulx3272 multiply 95.490751127249945886828257312118 987.01498316307365714167410690192E+133 -> 9.4250802116091862185764800227004E+137 Inexact Rounded
+powx3272 power 95.490751127249945886828257312118 10 -> 63039548646186864162.847491534337 Inexact Rounded
+remx3272 remainder 95.490751127249945886828257312118 987.01498316307365714167410690192E+133 -> 95.490751127249945886828257312118
+subx3272 subtract 95.490751127249945886828257312118 987.01498316307365714167410690192E+133 -> -9.8701498316307365714167410690192E+135 Inexact Rounded
+addx3273 add 69434850287.460788550936730296153 -35119136549015044241569827542264 -> -35119136549015044241500392691977 Inexact Rounded
+comx3273 compare 69434850287.460788550936730296153 -35119136549015044241569827542264 -> 1
+divx3273 divide 69434850287.460788550936730296153 -35119136549015044241569827542264 -> -1.9771229338327273644129394734299E-21 Inexact Rounded
+dvix3273 divideint 69434850287.460788550936730296153 -35119136549015044241569827542264 -> -0
+mulx3273 multiply 69434850287.460788550936730296153 -35119136549015044241569827542264 -> -2.4384919885057519302646522425980E+42 Inexact Rounded
+powx3273 power 69434850287.460788550936730296153 -4 -> 4.3021939605842038995370443743844E-44 Inexact Rounded
+remx3273 remainder 69434850287.460788550936730296153 -35119136549015044241569827542264 -> 69434850287.460788550936730296153
+subx3273 subtract 69434850287.460788550936730296153 -35119136549015044241569827542264 -> 35119136549015044241639262392551 Inexact Rounded
+addx3274 add -392.22739924621965621739098725407 -65551274.987160998195282109612136 -> -65551667.214560244414938327003123 Inexact Rounded
+comx3274 compare -392.22739924621965621739098725407 -65551274.987160998195282109612136 -> 1
+divx3274 divide -392.22739924621965621739098725407 -65551274.987160998195282109612136 -> 0.0000059835205237890809449684317245033 Inexact Rounded
+dvix3274 divideint -392.22739924621965621739098725407 -65551274.987160998195282109612136 -> 0
+mulx3274 multiply -392.22739924621965621739098725407 -65551274.987160998195282109612136 -> 25711006105.487929108329637701882 Inexact Rounded
+powx3274 power -392.22739924621965621739098725407 -65551275 -> -0E-10030 Underflow Subnormal Inexact Rounded Clamped
+remx3274 remainder -392.22739924621965621739098725407 -65551274.987160998195282109612136 -> -392.22739924621965621739098725407
+subx3274 subtract -392.22739924621965621739098725407 -65551274.987160998195282109612136 -> 65550882.759761751975625892221149 Inexact Rounded
+addx3275 add 6413265.4423561191792972085539457 24514.222704714139350026165721146 -> 6437779.6650608333186472347196668 Inexact Rounded
+comx3275 compare 6413265.4423561191792972085539457 24514.222704714139350026165721146 -> 1
+divx3275 divide 6413265.4423561191792972085539457 24514.222704714139350026165721146 -> 261.61406460270241498757868681883 Inexact Rounded
+dvix3275 divideint 6413265.4423561191792972085539457 24514.222704714139350026165721146 -> 261
+mulx3275 multiply 6413265.4423561191792972085539457 24514.222704714139350026165721146 -> 157216217318.36494525300694583138 Inexact Rounded
+powx3275 power 6413265.4423561191792972085539457 24514 -> Infinity Overflow Inexact Rounded
+remx3275 remainder 6413265.4423561191792972085539457 24514.222704714139350026165721146 -> 15053.316425728808940379300726594
+subx3275 subtract 6413265.4423561191792972085539457 24514.222704714139350026165721146 -> 6388751.2196514050399471823882246 Inexact Rounded
+addx3276 add -6.9667706389122107760046184064057E+487 32.405810703971538278419625527234 -> -6.9667706389122107760046184064057E+487 Inexact Rounded
+comx3276 compare -6.9667706389122107760046184064057E+487 32.405810703971538278419625527234 -> -1
+divx3276 divide -6.9667706389122107760046184064057E+487 32.405810703971538278419625527234 -> -2.1498522911689997341347293419761E+486 Inexact Rounded
+dvix3276 divideint -6.9667706389122107760046184064057E+487 32.405810703971538278419625527234 -> NaN Division_impossible
+mulx3276 multiply -6.9667706389122107760046184064057E+487 32.405810703971538278419625527234 -> -2.2576385054257595259511556258470E+489 Inexact Rounded
+powx3276 power -6.9667706389122107760046184064057E+487 32 -> Infinity Overflow Inexact Rounded
+remx3276 remainder -6.9667706389122107760046184064057E+487 32.405810703971538278419625527234 -> NaN Division_impossible
+subx3276 subtract -6.9667706389122107760046184064057E+487 32.405810703971538278419625527234 -> -6.9667706389122107760046184064057E+487 Inexact Rounded
+addx3277 add 378204716633.40024100602896057615 -0300218714378.322231269606216516 -> 77986002255.07800973642274406015
+comx3277 compare 378204716633.40024100602896057615 -0300218714378.322231269606216516 -> 1
+divx3277 divide 378204716633.40024100602896057615 -0300218714378.322231269606216516 -> -1.2597639604731753284599748820876 Inexact Rounded
+dvix3277 divideint 378204716633.40024100602896057615 -0300218714378.322231269606216516 -> -1
+mulx3277 multiply 378204716633.40024100602896057615 -0300218714378.322231269606216516 -> -113544133799497082075557.21180430 Inexact Rounded
+powx3277 power 378204716633.40024100602896057615 -3 -> 1.8484988212401886887562779996737E-35 Inexact Rounded
+remx3277 remainder 378204716633.40024100602896057615 -0300218714378.322231269606216516 -> 77986002255.07800973642274406015
+subx3277 subtract 378204716633.40024100602896057615 -0300218714378.322231269606216516 -> 678423431011.72247227563517709215
+addx3278 add -44234.512012457148027685282969235E+501 2132572.4571987908375002100894927 -> -4.4234512012457148027685282969235E+505 Inexact Rounded
+comx3278 compare -44234.512012457148027685282969235E+501 2132572.4571987908375002100894927 -> -1
+divx3278 divide -44234.512012457148027685282969235E+501 2132572.4571987908375002100894927 -> -2.0742325477916347193181603963257E+499 Inexact Rounded
+dvix3278 divideint -44234.512012457148027685282969235E+501 2132572.4571987908375002100894927 -> NaN Division_impossible
+mulx3278 multiply -44234.512012457148027685282969235E+501 2132572.4571987908375002100894927 -> -9.4333301975395170465982968019915E+511 Inexact Rounded
+powx3278 power -44234.512012457148027685282969235E+501 2132572 -> Infinity Overflow Inexact Rounded
+remx3278 remainder -44234.512012457148027685282969235E+501 2132572.4571987908375002100894927 -> NaN Division_impossible
+subx3278 subtract -44234.512012457148027685282969235E+501 2132572.4571987908375002100894927 -> -4.4234512012457148027685282969235E+505 Inexact Rounded
+addx3279 add -3554.5895974968741465654022772100E-073 9752.0428746722497621936998533848E+516 -> 9.7520428746722497621936998533848E+519 Inexact Rounded
+comx3279 compare -3554.5895974968741465654022772100E-073 9752.0428746722497621936998533848E+516 -> -1
+divx3279 divide -3554.5895974968741465654022772100E-073 9752.0428746722497621936998533848E+516 -> -3.6449692061227100572768330912162E-590 Inexact Rounded
+dvix3279 divideint -3554.5895974968741465654022772100E-073 9752.0428746722497621936998533848E+516 -> -0
+mulx3279 multiply -3554.5895974968741465654022772100E-073 9752.0428746722497621936998533848E+516 -> -3.4664510156653491769901435777060E+450 Inexact Rounded
+powx3279 power -3554.5895974968741465654022772100E-073 10 -> 3.2202875716019266933215387456197E-695 Inexact Rounded
+remx3279 remainder -3554.5895974968741465654022772100E-073 9752.0428746722497621936998533848E+516 -> -3.5545895974968741465654022772100E-70
+subx3279 subtract -3554.5895974968741465654022772100E-073 9752.0428746722497621936998533848E+516 -> -9.7520428746722497621936998533848E+519 Inexact Rounded
+addx3280 add 750187685.63632608923397234391668 4633194252863.6730625972669246025 -> 4633944440549.3093886865008969464 Inexact Rounded
+comx3280 compare 750187685.63632608923397234391668 4633194252863.6730625972669246025 -> -1
+divx3280 divide 750187685.63632608923397234391668 4633194252863.6730625972669246025 -> 0.00016191587157664541463871807382759 Inexact Rounded
+dvix3280 divideint 750187685.63632608923397234391668 4633194252863.6730625972669246025 -> 0
+mulx3280 multiply 750187685.63632608923397234391668 4633194252863.6730625972669246025 -> 3475765273659325895012.7612107556 Inexact Rounded
+powx3280 power 750187685.63632608923397234391668 5 -> 2.3760176068829529745152188798557E+44 Inexact Rounded
+remx3280 remainder 750187685.63632608923397234391668 4633194252863.6730625972669246025 -> 750187685.63632608923397234391668
+subx3280 subtract 750187685.63632608923397234391668 4633194252863.6730625972669246025 -> -4632444065178.0367365080329522586 Inexact Rounded
+addx3281 add 30190034242853.251165951457589386E-028 8038885676.3204238322976087799751E+018 -> 8038885676320423832297608779.9751 Inexact Rounded
+comx3281 compare 30190034242853.251165951457589386E-028 8038885676.3204238322976087799751E+018 -> -1
+divx3281 divide 30190034242853.251165951457589386E-028 8038885676.3204238322976087799751E+018 -> 3.7554998862319807295903348960280E-43 Inexact Rounded
+dvix3281 divideint 30190034242853.251165951457589386E-028 8038885676.3204238322976087799751E+018 -> 0
+mulx3281 multiply 30190034242853.251165951457589386E-028 8038885676.3204238322976087799751E+018 -> 24269423384249.611263728854793731 Inexact Rounded
+powx3281 power 30190034242853.251165951457589386E-028 8 -> 6.9009494305612589578332690692113E-117 Inexact Rounded
+remx3281 remainder 30190034242853.251165951457589386E-028 8038885676.3204238322976087799751E+018 -> 3.0190034242853251165951457589386E-15
+subx3281 subtract 30190034242853.251165951457589386E-028 8038885676.3204238322976087799751E+018 -> -8038885676320423832297608779.9751 Inexact Rounded
+addx3282 add 65.537942676774715953400768803539 125946917260.87536506197191782198 -> 125946917326.41330773874663377538 Inexact Rounded
+comx3282 compare 65.537942676774715953400768803539 125946917260.87536506197191782198 -> -1
+divx3282 divide 65.537942676774715953400768803539 125946917260.87536506197191782198 -> 5.2036162616846894920389414735878E-10 Inexact Rounded
+dvix3282 divideint 65.537942676774715953400768803539 125946917260.87536506197191782198 -> 0
+mulx3282 multiply 65.537942676774715953400768803539 125946917260.87536506197191782198 -> 8254301843759.7376990957355411370 Inexact Rounded
+powx3282 power 65.537942676774715953400768803539 1 -> 65.537942676774715953400768803539
+remx3282 remainder 65.537942676774715953400768803539 125946917260.87536506197191782198 -> 65.537942676774715953400768803539
+subx3282 subtract 65.537942676774715953400768803539 125946917260.87536506197191782198 -> -125946917195.33742238519720186858 Inexact Rounded
+addx3283 add 8015272348677.5489394183881813700 949.23027111499779258284877920022 -> 8015272349626.7792105333859739528 Inexact Rounded
+comx3283 compare 8015272348677.5489394183881813700 949.23027111499779258284877920022 -> 1
+divx3283 divide 8015272348677.5489394183881813700 949.23027111499779258284877920022 -> 8443970438.5560107978790084430110 Inexact Rounded
+dvix3283 divideint 8015272348677.5489394183881813700 949.23027111499779258284877920022 -> 8443970438
+mulx3283 multiply 8015272348677.5489394183881813700 949.23027111499779258284877920022 -> 7608339144595734.8984281431471741 Inexact Rounded
+powx3283 power 8015272348677.5489394183881813700 949 -> Infinity Overflow Inexact Rounded
+remx3283 remainder 8015272348677.5489394183881813700 949.23027111499779258284877920022 -> 527.78228041355742397895303690364
+subx3283 subtract 8015272348677.5489394183881813700 949.23027111499779258284877920022 -> 8015272347728.3186683033903887872 Inexact Rounded
+addx3284 add -32595333982.67068622120451804225 69130.052233649808750113141502465E-862 -> -32595333982.670686221204518042250 Inexact Rounded
+comx3284 compare -32595333982.67068622120451804225 69130.052233649808750113141502465E-862 -> -1
+divx3284 divide -32595333982.67068622120451804225 69130.052233649808750113141502465E-862 -> -4.7150744038935574574681609457727E+867 Inexact Rounded
+dvix3284 divideint -32595333982.67068622120451804225 69130.052233649808750113141502465E-862 -> NaN Division_impossible
+mulx3284 multiply -32595333982.67068622120451804225 69130.052233649808750113141502465E-862 -> -2.2533171407952851885446213697715E-847 Inexact Rounded
+powx3284 power -32595333982.67068622120451804225 7 -> -3.9092014148031739666525606093306E+73 Inexact Rounded
+remx3284 remainder -32595333982.67068622120451804225 69130.052233649808750113141502465E-862 -> NaN Division_impossible
+subx3284 subtract -32595333982.67068622120451804225 69130.052233649808750113141502465E-862 -> -32595333982.670686221204518042250 Inexact Rounded
+addx3285 add -17544189017145.710117633021800426E-537 292178000.06450804618299520094843 -> 292178000.06450804618299520094843 Inexact Rounded
+comx3285 compare -17544189017145.710117633021800426E-537 292178000.06450804618299520094843 -> -1
+divx3285 divide -17544189017145.710117633021800426E-537 292178000.06450804618299520094843 -> -6.0046235559392715334668277026896E-533 Inexact Rounded
+dvix3285 divideint -17544189017145.710117633021800426E-537 292178000.06450804618299520094843 -> -0
+mulx3285 multiply -17544189017145.710117633021800426E-537 292178000.06450804618299520094843 -> -5.1260260597833406461110136952456E-516 Inexact Rounded
+powx3285 power -17544189017145.710117633021800426E-537 292178000 -> 0E-10030 Underflow Subnormal Inexact Rounded Clamped
+remx3285 remainder -17544189017145.710117633021800426E-537 292178000.06450804618299520094843 -> -1.7544189017145710117633021800426E-524
+subx3285 subtract -17544189017145.710117633021800426E-537 292178000.06450804618299520094843 -> -292178000.06450804618299520094843 Inexact Rounded
+addx3286 add -506650.99395649907139204052441630 11.018427502031650148962067367158 -> -506639.97552899703974189156234893 Inexact Rounded
+comx3286 compare -506650.99395649907139204052441630 11.018427502031650148962067367158 -> -1
+divx3286 divide -506650.99395649907139204052441630 11.018427502031650148962067367158 -> -45982.150707356329027698717189104 Inexact Rounded
+dvix3286 divideint -506650.99395649907139204052441630 11.018427502031650148962067367158 -> -45982
+mulx3286 multiply -506650.99395649907139204052441630 11.018427502031650148962067367158 -> -5582497.2457419607392940234271222 Inexact Rounded
+powx3286 power -506650.99395649907139204052441630 11 -> -5.6467412678809885333313818078829E+62 Inexact Rounded
+remx3286 remainder -506650.99395649907139204052441630 11.018427502031650148962067367158 -> -1.660558079734242466742739640844
+subx3286 subtract -506650.99395649907139204052441630 11.018427502031650148962067367158 -> -506662.01238400110304218948648367 Inexact Rounded
+addx3287 add 4846835159.5922372307656000769395E-241 -84.001893040865864590122330800768 -> -84.001893040865864590122330800768 Inexact Rounded
+comx3287 compare 4846835159.5922372307656000769395E-241 -84.001893040865864590122330800768 -> 1
+divx3287 divide 4846835159.5922372307656000769395E-241 -84.001893040865864590122330800768 -> -5.7699118247660357814641813260524E-234 Inexact Rounded
+dvix3287 divideint 4846835159.5922372307656000769395E-241 -84.001893040865864590122330800768 -> -0
+mulx3287 multiply 4846835159.5922372307656000769395E-241 -84.001893040865864590122330800768 -> -4.0714332866277514481192856925775E-230 Inexact Rounded
+powx3287 power 4846835159.5922372307656000769395E-241 -84 -> Infinity Overflow Inexact Rounded
+remx3287 remainder 4846835159.5922372307656000769395E-241 -84.001893040865864590122330800768 -> 4.8468351595922372307656000769395E-232
+subx3287 subtract 4846835159.5922372307656000769395E-241 -84.001893040865864590122330800768 -> 84.001893040865864590122330800768 Inexact Rounded
+addx3288 add -35.029311013822259358116556164908 -3994308878.1994645313414534209127 -> -3994308913.2287755451637127790293 Inexact Rounded
+comx3288 compare -35.029311013822259358116556164908 -3994308878.1994645313414534209127 -> 1
+divx3288 divide -35.029311013822259358116556164908 -3994308878.1994645313414534209127 -> 8.7698052609323004543538163061774E-9 Inexact Rounded
+dvix3288 divideint -35.029311013822259358116556164908 -3994308878.1994645313414534209127 -> 0
+mulx3288 multiply -35.029311013822259358116556164908 -3994308878.1994645313414534209127 -> 139917887979.72053637272961120639 Inexact Rounded
+powx3288 power -35.029311013822259358116556164908 -4 -> 6.6416138040522124693495178218096E-7 Inexact Rounded
+remx3288 remainder -35.029311013822259358116556164908 -3994308878.1994645313414534209127 -> -35.029311013822259358116556164908
+subx3288 subtract -35.029311013822259358116556164908 -3994308878.1994645313414534209127 -> 3994308843.1701535175191940627961 Inexact Rounded
+addx3289 add 7606663750.6735265233044420887018E+166 -5491814639.4484565418284686127552E+365 -> -5.4918146394484565418284686127552E+374 Inexact Rounded
+comx3289 compare 7606663750.6735265233044420887018E+166 -5491814639.4484565418284686127552E+365 -> 1
+divx3289 divide 7606663750.6735265233044420887018E+166 -5491814639.4484565418284686127552E+365 -> -1.3850911310869487895947733090204E-199 Inexact Rounded
+dvix3289 divideint 7606663750.6735265233044420887018E+166 -5491814639.4484565418284686127552E+365 -> -0
+mulx3289 multiply 7606663750.6735265233044420887018E+166 -5491814639.4484565418284686127552E+365 -> -4.1774387343310777190917128006589E+550 Inexact Rounded
+powx3289 power 7606663750.6735265233044420887018E+166 -5 -> 3.9267106978887346373957314818178E-880 Inexact Rounded
+remx3289 remainder 7606663750.6735265233044420887018E+166 -5491814639.4484565418284686127552E+365 -> 7.6066637506735265233044420887018E+175
+subx3289 subtract 7606663750.6735265233044420887018E+166 -5491814639.4484565418284686127552E+365 -> 5.4918146394484565418284686127552E+374 Inexact Rounded
+addx3290 add -25677.829660831741274207326697052E-163 -94135395124193048560172705082029E-862 -> -2.5677829660831741274207326697052E-159 Inexact Rounded
+comx3290 compare -25677.829660831741274207326697052E-163 -94135395124193048560172705082029E-862 -> -1
+divx3290 divide -25677.829660831741274207326697052E-163 -94135395124193048560172705082029E-862 -> 2.7277550199853009708493167299838E+671 Inexact Rounded
+dvix3290 divideint -25677.829660831741274207326697052E-163 -94135395124193048560172705082029E-862 -> NaN Division_impossible
+mulx3290 multiply -25677.829660831741274207326697052E-163 -94135395124193048560172705082029E-862 -> 2.4171926410541199393728294762559E-989 Inexact Rounded
+powx3290 power -25677.829660831741274207326697052E-163 -9 -> -2.0605121420682764897867221992174E+1427 Inexact Rounded
+remx3290 remainder -25677.829660831741274207326697052E-163 -94135395124193048560172705082029E-862 -> NaN Division_impossible
+subx3290 subtract -25677.829660831741274207326697052E-163 -94135395124193048560172705082029E-862 -> -2.5677829660831741274207326697052E-159 Inexact Rounded
+addx3291 add 97271576094.456406729671729224827 -1.5412563837540810793697955063295E+554 -> -1.5412563837540810793697955063295E+554 Inexact Rounded
+comx3291 compare 97271576094.456406729671729224827 -1.5412563837540810793697955063295E+554 -> 1
+divx3291 divide 97271576094.456406729671729224827 -1.5412563837540810793697955063295E+554 -> -6.3111872313890646144473652645030E-544 Inexact Rounded
+dvix3291 divideint 97271576094.456406729671729224827 -1.5412563837540810793697955063295E+554 -> -0
+mulx3291 multiply 97271576094.456406729671729224827 -1.5412563837540810793697955063295E+554 -> -1.4992043761340180288065959300090E+565 Inexact Rounded
+powx3291 power 97271576094.456406729671729224827 -2 -> 1.0568858765852073181352309401343E-22 Inexact Rounded
+remx3291 remainder 97271576094.456406729671729224827 -1.5412563837540810793697955063295E+554 -> 97271576094.456406729671729224827
+subx3291 subtract 97271576094.456406729671729224827 -1.5412563837540810793697955063295E+554 -> 1.5412563837540810793697955063295E+554 Inexact Rounded
+addx3292 add 41139789894.401826915757391777563 -1.8729920305671057957156159690823E-020 -> 41139789894.401826915757391777544 Inexact Rounded
+comx3292 compare 41139789894.401826915757391777563 -1.8729920305671057957156159690823E-020 -> 1
+divx3292 divide 41139789894.401826915757391777563 -1.8729920305671057957156159690823E-020 -> -2196474369511625389289506461551.0 Inexact Rounded
+dvix3292 divideint 41139789894.401826915757391777563 -1.8729920305671057957156159690823E-020 -> -2196474369511625389289506461551
+mulx3292 multiply 41139789894.401826915757391777563 -1.8729920305671057957156159690823E-020 -> -7.7054498611419776714291080928601E-10 Inexact Rounded
+powx3292 power 41139789894.401826915757391777563 -2 -> 5.9084812442741091550891451069919E-22 Inexact Rounded
+remx3292 remainder 41139789894.401826915757391777563 -1.8729920305671057957156159690823E-020 -> 6.98141022640544018935102953527E-22
+subx3292 subtract 41139789894.401826915757391777563 -1.8729920305671057957156159690823E-020 -> 41139789894.401826915757391777582 Inexact Rounded
+addx3293 add -83310831287241.777598696853498149 -54799825033.797100418162985103519E-330 -> -83310831287241.777598696853498149 Inexact Rounded
+comx3293 compare -83310831287241.777598696853498149 -54799825033.797100418162985103519E-330 -> -1
+divx3293 divide -83310831287241.777598696853498149 -54799825033.797100418162985103519E-330 -> 1.5202754978845438636605170857478E+333 Inexact Rounded
+dvix3293 divideint -83310831287241.777598696853498149 -54799825033.797100418162985103519E-330 -> NaN Division_impossible
+mulx3293 multiply -83310831287241.777598696853498149 -54799825033.797100418162985103519E-330 -> 4.5654189779610386760330527839588E-306 Inexact Rounded
+powx3293 power -83310831287241.777598696853498149 -5 -> -2.4916822606682624827900581728387E-70 Inexact Rounded
+remx3293 remainder -83310831287241.777598696853498149 -54799825033.797100418162985103519E-330 -> NaN Division_impossible
+subx3293 subtract -83310831287241.777598696853498149 -54799825033.797100418162985103519E-330 -> -83310831287241.777598696853498149 Inexact Rounded
+addx3294 add 4506653461.4414974233678331771169 -74955470.977653038010031457181957E-887 -> 4506653461.4414974233678331771169 Inexact Rounded
+comx3294 compare 4506653461.4414974233678331771169 -74955470.977653038010031457181957E-887 -> 1
+divx3294 divide 4506653461.4414974233678331771169 -74955470.977653038010031457181957E-887 -> -6.0124409901781490054438220048629E+888 Inexact Rounded
+dvix3294 divideint 4506653461.4414974233678331771169 -74955470.977653038010031457181957E-887 -> NaN Division_impossible
+mulx3294 multiply 4506653461.4414974233678331771169 -74955470.977653038010031457181957E-887 -> -3.3779833273541776470902903512949E-870 Inexact Rounded
+powx3294 power 4506653461.4414974233678331771169 -7 -> 2.6486272911486461102735412463189E-68 Inexact Rounded
+remx3294 remainder 4506653461.4414974233678331771169 -74955470.977653038010031457181957E-887 -> NaN Division_impossible
+subx3294 subtract 4506653461.4414974233678331771169 -74955470.977653038010031457181957E-887 -> 4506653461.4414974233678331771169 Inexact Rounded
+addx3295 add 23777.857951114967684767609401626 720760.03897144157012301385227528 -> 744537.89692255653780778146167691 Inexact Rounded
+comx3295 compare 23777.857951114967684767609401626 720760.03897144157012301385227528 -> -1
+divx3295 divide 23777.857951114967684767609401626 720760.03897144157012301385227528 -> 0.032989978169498808275308039034795 Inexact Rounded
+dvix3295 divideint 23777.857951114967684767609401626 720760.03897144157012301385227528 -> 0
+mulx3295 multiply 23777.857951114967684767609401626 720760.03897144157012301385227528 -> 17138129823.503025913034987537096 Inexact Rounded
+powx3295 power 23777.857951114967684767609401626 720760 -> Infinity Overflow Inexact Rounded
+remx3295 remainder 23777.857951114967684767609401626 720760.03897144157012301385227528 -> 23777.857951114967684767609401626
+subx3295 subtract 23777.857951114967684767609401626 720760.03897144157012301385227528 -> -696982.18102032660243824624287365 Inexact Rounded
+addx3296 add -21337853323980858055292469611948 6080272840.3071490445256786982100E+532 -> 6.0802728403071490445256786982100E+541 Inexact Rounded
+comx3296 compare -21337853323980858055292469611948 6080272840.3071490445256786982100E+532 -> -1
+divx3296 divide -21337853323980858055292469611948 6080272840.3071490445256786982100E+532 -> -3.5093578667274020123788514069885E-511 Inexact Rounded
+dvix3296 divideint -21337853323980858055292469611948 6080272840.3071490445256786982100E+532 -> -0
+mulx3296 multiply -21337853323980858055292469611948 6080272840.3071490445256786982100E+532 -> -1.2973997003625843317417981902198E+573 Inexact Rounded
+powx3296 power -21337853323980858055292469611948 6 -> 9.4385298321304970306180652097874E+187 Inexact Rounded
+remx3296 remainder -21337853323980858055292469611948 6080272840.3071490445256786982100E+532 -> -21337853323980858055292469611948
+subx3296 subtract -21337853323980858055292469611948 6080272840.3071490445256786982100E+532 -> -6.0802728403071490445256786982100E+541 Inexact Rounded
+addx3297 add -818409238.0423893439849743856947 756.39156265972753259267069158760 -> -818408481.65082668425744179302401 Inexact Rounded
+comx3297 compare -818409238.0423893439849743856947 756.39156265972753259267069158760 -> -1
+divx3297 divide -818409238.0423893439849743856947 756.39156265972753259267069158760 -> -1081991.4954690752676494129493403 Inexact Rounded
+dvix3297 divideint -818409238.0423893439849743856947 756.39156265972753259267069158760 -> -1081991
+mulx3297 multiply -818409238.0423893439849743856947 756.39156265972753259267069158760 -> -619037842458.03980537370328252817 Inexact Rounded
+powx3297 power -818409238.0423893439849743856947 756 -> 1.6058883946373232750995543573461E+6738 Inexact Rounded
+remx3297 remainder -818409238.0423893439849743856947 756.39156265972753259267069158760 -> -374.76862809126749803143314108840
+subx3297 subtract -818409238.0423893439849743856947 756.39156265972753259267069158760 -> -818409994.43395200371250697836539 Inexact Rounded
+addx3298 add 47567380384943.87013600286155046 65.084709374908275826942076480326 -> 47567380385008.954845377769826287 Inexact Rounded
+comx3298 compare 47567380384943.87013600286155046 65.084709374908275826942076480326 -> 1
+divx3298 divide 47567380384943.87013600286155046 65.084709374908275826942076480326 -> 730853388480.86247690474303493972 Inexact Rounded
+dvix3298 divideint 47567380384943.87013600286155046 65.084709374908275826942076480326 -> 730853388480
+mulx3298 multiply 47567380384943.87013600286155046 65.084709374908275826942076480326 -> 3095909128079784.3348591472999468 Inexact Rounded
+powx3298 power 47567380384943.87013600286155046 65 -> 1.0594982876763214301042437482634E+889 Inexact Rounded
+remx3298 remainder 47567380384943.87013600286155046 65.084709374908275826942076480326 -> 56.134058687770878126430844955520
+subx3298 subtract 47567380384943.87013600286155046 65.084709374908275826942076480326 -> 47567380384878.785426627953274633 Inexact Rounded
+addx3299 add -296615544.05897984545127115290251 -5416115.4315053536014016450973264 -> -302031659.49048519905267279799984 Inexact Rounded
+comx3299 compare -296615544.05897984545127115290251 -5416115.4315053536014016450973264 -> -1
+divx3299 divide -296615544.05897984545127115290251 -5416115.4315053536014016450973264 -> 54.765366028496664530688259272591 Inexact Rounded
+dvix3299 divideint -296615544.05897984545127115290251 -5416115.4315053536014016450973264 -> 54
+mulx3299 multiply -296615544.05897984545127115290251 -5416115.4315053536014016450973264 -> 1606504025402196.8484885386501478 Inexact Rounded
+powx3299 power -296615544.05897984545127115290251 -5416115 -> -0E-10030 Underflow Subnormal Inexact Rounded Clamped
+remx3299 remainder -296615544.05897984545127115290251 -5416115.4315053536014016450973264 -> -4145310.7576907509755823176468844
+subx3299 subtract -296615544.05897984545127115290251 -5416115.4315053536014016450973264 -> -291199428.62747449184986950780518 Inexact Rounded
+addx3300 add 61391705914.046707180652185247584E+739 -675982087721.91856456125242297346 -> 6.1391705914046707180652185247584E+749 Inexact Rounded
+comx3300 compare 61391705914.046707180652185247584E+739 -675982087721.91856456125242297346 -> 1
+divx3300 divide 61391705914.046707180652185247584E+739 -675982087721.91856456125242297346 -> -9.0818539468906248593699700040068E+737 Inexact Rounded
+dvix3300 divideint 61391705914.046707180652185247584E+739 -675982087721.91856456125242297346 -> NaN Division_impossible
+mulx3300 multiply 61391705914.046707180652185247584E+739 -675982087721.91856456125242297346 -> -4.1499693532587347944890300176290E+761 Inexact Rounded
+powx3300 power 61391705914.046707180652185247584E+739 -7 -> 3.0425105291210947473420999890124E-5249 Inexact Rounded
+remx3300 remainder 61391705914.046707180652185247584E+739 -675982087721.91856456125242297346 -> NaN Division_impossible
+subx3300 subtract 61391705914.046707180652185247584E+739 -675982087721.91856456125242297346 -> 6.1391705914046707180652185247584E+749 Inexact Rounded
+
+-- randomly generated testcases [26 Sep 2001]
+precision: 33
+rounding: half_up
+maxExponent: 9999
+
+addx3401 add 042.668056830485571428877212944418 -01364112374639.4941124016455321071 -> -1364112374596.82605557115996067822 Inexact Rounded
+comx3401 compare 042.668056830485571428877212944418 -01364112374639.4941124016455321071 -> 1
+divx3401 divide 042.668056830485571428877212944418 -01364112374639.4941124016455321071 -> -3.12789896373176963160811150593867E-11 Inexact Rounded
+dvix3401 divideint 042.668056830485571428877212944418 -01364112374639.4941124016455321071 -> -0
+mulx3401 multiply 042.668056830485571428877212944418 -01364112374639.4941124016455321071 -> -58204024324286.5595453066065234923 Inexact Rounded
+powx3401 power 042.668056830485571428877212944418 -1 -> 0.0234367363850869744523417227148909 Inexact Rounded
+remx3401 remainder 042.668056830485571428877212944418 -01364112374639.4941124016455321071 -> 42.668056830485571428877212944418
+subx3401 subtract 042.668056830485571428877212944418 -01364112374639.4941124016455321071 -> 1364112374682.16216923213110353598 Inexact Rounded
+addx3402 add -327.179426341653256363531809227344E+453 759067457.107518663444899356760793 -> -3.27179426341653256363531809227344E+455 Inexact Rounded
+comx3402 compare -327.179426341653256363531809227344E+453 759067457.107518663444899356760793 -> -1
+divx3402 divide -327.179426341653256363531809227344E+453 759067457.107518663444899356760793 -> -4.31028129684803083255704680611589E+446 Inexact Rounded
+dvix3402 divideint -327.179426341653256363531809227344E+453 759067457.107518663444899356760793 -> NaN Division_impossible
+mulx3402 multiply -327.179426341653256363531809227344E+453 759067457.107518663444899356760793 -> -2.48351255171055445110558613627379E+464 Inexact Rounded
+powx3402 power -327.179426341653256363531809227344E+453 759067457 -> -Infinity Overflow Inexact Rounded
+remx3402 remainder -327.179426341653256363531809227344E+453 759067457.107518663444899356760793 -> NaN Division_impossible
+subx3402 subtract -327.179426341653256363531809227344E+453 759067457.107518663444899356760793 -> -3.27179426341653256363531809227344E+455 Inexact Rounded
+addx3403 add 81721.5803096185422787702538493471 900099473.245809628076790757217328 -> 900181194.826119246619069527471177 Inexact Rounded
+comx3403 compare 81721.5803096185422787702538493471 900099473.245809628076790757217328 -> -1
+divx3403 divide 81721.5803096185422787702538493471 900099473.245809628076790757217328 -> 0.0000907917210693679220610511319812826 Inexact Rounded
+dvix3403 divideint 81721.5803096185422787702538493471 900099473.245809628076790757217328 -> 0
+mulx3403 multiply 81721.5803096185422787702538493471 900099473.245809628076790757217328 -> 73557551389502.7779979042453102926 Inexact Rounded
+powx3403 power 81721.5803096185422787702538493471 900099473 -> Infinity Overflow Inexact Rounded
+remx3403 remainder 81721.5803096185422787702538493471 900099473.245809628076790757217328 -> 81721.5803096185422787702538493471
+subx3403 subtract 81721.5803096185422787702538493471 900099473.245809628076790757217328 -> -900017751.665500009534511986963479 Inexact Rounded
+addx3404 add 3991.56734635183403814636354392163E-807 72.3239822255871305731314565069132 -> 72.3239822255871305731314565069132 Inexact Rounded
+comx3404 compare 3991.56734635183403814636354392163E-807 72.3239822255871305731314565069132 -> -1
+divx3404 divide 3991.56734635183403814636354392163E-807 72.3239822255871305731314565069132 -> 5.51900935695390664984598248115290E-806 Inexact Rounded
+dvix3404 divideint 3991.56734635183403814636354392163E-807 72.3239822255871305731314565069132 -> 0
+mulx3404 multiply 3991.56734635183403814636354392163E-807 72.3239822255871305731314565069132 -> 2.88686045809784034794803928177854E-802 Inexact Rounded
+powx3404 power 3991.56734635183403814636354392163E-807 72 -> 0E-10031 Underflow Subnormal Inexact Rounded Clamped
+remx3404 remainder 3991.56734635183403814636354392163E-807 72.3239822255871305731314565069132 -> 3.99156734635183403814636354392163E-804
+subx3404 subtract 3991.56734635183403814636354392163E-807 72.3239822255871305731314565069132 -> -72.3239822255871305731314565069132 Inexact Rounded
+addx3405 add -66.3393308595957726456416979163306 5.08486573050459213864684589662559 -> -61.2544651290911805069948520197050 Inexact Rounded
+comx3405 compare -66.3393308595957726456416979163306 5.08486573050459213864684589662559 -> -1
+divx3405 divide -66.3393308595957726456416979163306 5.08486573050459213864684589662559 -> -13.0464272560079276694749924915850 Inexact Rounded
+dvix3405 divideint -66.3393308595957726456416979163306 5.08486573050459213864684589662559 -> -13
+mulx3405 multiply -66.3393308595957726456416979163306 5.08486573050459213864684589662559 -> -337.326590072564290813539036280205 Inexact Rounded
+powx3405 power -66.3393308595957726456416979163306 5 -> -1284858888.27285822259184896667990 Inexact Rounded
+remx3405 remainder -66.3393308595957726456416979163306 5.08486573050459213864684589662559 -> -0.23607636303607484323270126019793
+subx3405 subtract -66.3393308595957726456416979163306 5.08486573050459213864684589662559 -> -71.4241965901003647842885438129562 Inexact Rounded
+addx3406 add -393606.873703567753255097095208112E+111 -2124339550.86891093200758095660557 -> -3.93606873703567753255097095208112E+116 Inexact Rounded
+comx3406 compare -393606.873703567753255097095208112E+111 -2124339550.86891093200758095660557 -> -1
+divx3406 divide -393606.873703567753255097095208112E+111 -2124339550.86891093200758095660557 -> 1.85284350396137075010428736564737E+107 Inexact Rounded
+dvix3406 divideint -393606.873703567753255097095208112E+111 -2124339550.86891093200758095660557 -> NaN Division_impossible
+mulx3406 multiply -393606.873703567753255097095208112E+111 -2124339550.86891093200758095660557 -> 8.36154649302353269818801263275941E+125 Inexact Rounded
+powx3406 power -393606.873703567753255097095208112E+111 -2 -> 6.45467904123103560528919747688443E-234 Inexact Rounded
+remx3406 remainder -393606.873703567753255097095208112E+111 -2124339550.86891093200758095660557 -> NaN Division_impossible
+subx3406 subtract -393606.873703567753255097095208112E+111 -2124339550.86891093200758095660557 -> -3.93606873703567753255097095208112E+116 Inexact Rounded
+addx3407 add -019133598.609812524622150421584346 -858439846.628367734642622922030051 -> -877573445.238180259264773343614397
+comx3407 compare -019133598.609812524622150421584346 -858439846.628367734642622922030051 -> 1
+divx3407 divide -019133598.609812524622150421584346 -858439846.628367734642622922030051 -> 0.0222888053076312565797460650311070 Inexact Rounded
+dvix3407 divideint -019133598.609812524622150421584346 -858439846.628367734642622922030051 -> 0
+mulx3407 multiply -019133598.609812524622150421584346 -858439846.628367734642622922030051 -> 16425043456056213.7395191514029288 Inexact Rounded
+powx3407 power -019133598.609812524622150421584346 -858439847 -> -0E-10031 Underflow Subnormal Inexact Rounded Clamped
+remx3407 remainder -019133598.609812524622150421584346 -858439846.628367734642622922030051 -> -19133598.609812524622150421584346
+subx3407 subtract -019133598.609812524622150421584346 -858439846.628367734642622922030051 -> 839306248.018555210020472500445705
+addx3408 add 465.351982159046525762715549761814 240444.975944666924657629172844780 -> 240910.327926825971183391888394542 Inexact Rounded
+comx3408 compare 465.351982159046525762715549761814 240444.975944666924657629172844780 -> -1
+divx3408 divide 465.351982159046525762715549761814 240444.975944666924657629172844780 -> 0.00193537827243326122782974132829095 Inexact Rounded
+dvix3408 divideint 465.351982159046525762715549761814 240444.975944666924657629172844780 -> 0
+mulx3408 multiply 465.351982159046525762715549761814 240444.975944666924657629172844780 -> 111891546.156035013780371395668674 Inexact Rounded
+powx3408 power 465.351982159046525762715549761814 240445 -> Infinity Overflow Inexact Rounded
+remx3408 remainder 465.351982159046525762715549761814 240444.975944666924657629172844780 -> 465.351982159046525762715549761814
+subx3408 subtract 465.351982159046525762715549761814 240444.975944666924657629172844780 -> -239979.623962507878131866457295018 Inexact Rounded
+addx3409 add 28066955004783.1076824222873384828 571699969.220753535758504907561016E-718 -> 28066955004783.1076824222873384828 Inexact Rounded
+comx3409 compare 28066955004783.1076824222873384828 571699969.220753535758504907561016E-718 -> 1
+divx3409 divide 28066955004783.1076824222873384828 571699969.220753535758504907561016E-718 -> 4.90938543219432390013656968123815E+722 Inexact Rounded
+dvix3409 divideint 28066955004783.1076824222873384828 571699969.220753535758504907561016E-718 -> NaN Division_impossible
+mulx3409 multiply 28066955004783.1076824222873384828 571699969.220753535758504907561016E-718 -> 1.60458773123547770690452195569223E-696 Inexact Rounded
+powx3409 power 28066955004783.1076824222873384828 6 -> 4.88845689938951583020171325568218E+80 Inexact Rounded
+remx3409 remainder 28066955004783.1076824222873384828 571699969.220753535758504907561016E-718 -> NaN Division_impossible
+subx3409 subtract 28066955004783.1076824222873384828 571699969.220753535758504907561016E-718 -> 28066955004783.1076824222873384828 Inexact Rounded
+addx3410 add 28275236927392.4960902824105246047 28212038.4825243127096613158419270E+422 -> 2.82120384825243127096613158419270E+429 Inexact Rounded
+comx3410 compare 28275236927392.4960902824105246047 28212038.4825243127096613158419270E+422 -> -1
+divx3410 divide 28275236927392.4960902824105246047 28212038.4825243127096613158419270E+422 -> 1.00224012330435927467559203688861E-416 Inexact Rounded
+dvix3410 divideint 28275236927392.4960902824105246047 28212038.4825243127096613158419270E+422 -> 0
+mulx3410 multiply 28275236927392.4960902824105246047 28212038.4825243127096613158419270E+422 -> 7.97702072298089605706798770013561E+442 Inexact Rounded
+powx3410 power 28275236927392.4960902824105246047 3 -> 2.26057415546622161347322061281516E+40 Inexact Rounded
+remx3410 remainder 28275236927392.4960902824105246047 28212038.4825243127096613158419270E+422 -> 28275236927392.4960902824105246047
+subx3410 subtract 28275236927392.4960902824105246047 28212038.4825243127096613158419270E+422 -> -2.82120384825243127096613158419270E+429 Inexact Rounded
+addx3411 add 11791.8644211874630234271801789996 -8.45457275930363860982261343159741 -> 11783.4098484281593848173575655680 Inexact Rounded
+comx3411 compare 11791.8644211874630234271801789996 -8.45457275930363860982261343159741 -> 1
+divx3411 divide 11791.8644211874630234271801789996 -8.45457275930363860982261343159741 -> -1394.73214754836418731335761858151 Inexact Rounded
+dvix3411 divideint 11791.8644211874630234271801789996 -8.45457275930363860982261343159741 -> -1394
+mulx3411 multiply 11791.8644211874630234271801789996 -8.45457275930363860982261343159741 -> -99695.1757167732926302533138186716 Inexact Rounded
+powx3411 power 11791.8644211874630234271801789996 -8 -> 2.67510099318723516565332928253711E-33 Inexact Rounded
+remx3411 remainder 11791.8644211874630234271801789996 -8.45457275930363860982261343159741 -> 6.18999471819080133445705535281046
+subx3411 subtract 11791.8644211874630234271801789996 -8.45457275930363860982261343159741 -> 11800.3189939467666620370027924312 Inexact Rounded
+addx3412 add 44.7085340739581668975502342787578 -9337.05408133023920640485556647937 -> -9292.34554725628103950730533220061 Inexact Rounded
+comx3412 compare 44.7085340739581668975502342787578 -9337.05408133023920640485556647937 -> 1
+divx3412 divide 44.7085340739581668975502342787578 -9337.05408133023920640485556647937 -> -0.00478829121953512281527242631775613 Inexact Rounded
+dvix3412 divideint 44.7085340739581668975502342787578 -9337.05408133023920640485556647937 -> -0
+mulx3412 multiply 44.7085340739581668975502342787578 -9337.05408133023920640485556647937 -> -417446.000545543168866158913077419 Inexact Rounded
+powx3412 power 44.7085340739581668975502342787578 -9337 -> 0E-10031 Underflow Subnormal Inexact Rounded Clamped
+remx3412 remainder 44.7085340739581668975502342787578 -9337.05408133023920640485556647937 -> 44.7085340739581668975502342787578
+subx3412 subtract 44.7085340739581668975502342787578 -9337.05408133023920640485556647937 -> 9381.76261540419737330240580075813 Inexact Rounded
+addx3413 add 93354527428804.5458053295581965867E+576 -856525909852.318790321300941615314 -> 9.33545274288045458053295581965867E+589 Inexact Rounded
+comx3413 compare 93354527428804.5458053295581965867E+576 -856525909852.318790321300941615314 -> 1
+divx3413 divide 93354527428804.5458053295581965867E+576 -856525909852.318790321300941615314 -> -1.08992064752484400353231056271614E+578 Inexact Rounded
+dvix3413 divideint 93354527428804.5458053295581965867E+576 -856525909852.318790321300941615314 -> NaN Division_impossible
+mulx3413 multiply 93354527428804.5458053295581965867E+576 -856525909852.318790321300941615314 -> -7.99605715447900642683774360731254E+601 Inexact Rounded
+powx3413 power 93354527428804.5458053295581965867E+576 -9 -> 1.85687015691763406448005521221518E-5310 Inexact Rounded
+remx3413 remainder 93354527428804.5458053295581965867E+576 -856525909852.318790321300941615314 -> NaN Division_impossible
+subx3413 subtract 93354527428804.5458053295581965867E+576 -856525909852.318790321300941615314 -> 9.33545274288045458053295581965867E+589 Inexact Rounded
+addx3414 add -367399415798804503177950040443482 -54845683.9691776397285506712812754 -> -367399415798804503177950095289166 Inexact Rounded
+comx3414 compare -367399415798804503177950040443482 -54845683.9691776397285506712812754 -> -1
+divx3414 divide -367399415798804503177950040443482 -54845683.9691776397285506712812754 -> 6698784465980529140072174.30474769 Inexact Rounded
+dvix3414 divideint -367399415798804503177950040443482 -54845683.9691776397285506712812754 -> 6698784465980529140072174
+mulx3414 multiply -367399415798804503177950040443482 -54845683.9691776397285506712812754 -> 2.01502722493617222018040789291414E+40 Inexact Rounded
+powx3414 power -367399415798804503177950040443482 -54845684 -> 0E-10031 Underflow Subnormal Inexact Rounded Clamped
+remx3414 remainder -367399415798804503177950040443482 -54845683.9691776397285506712812754 -> -16714095.6549657189177857892292804
+subx3414 subtract -367399415798804503177950040443482 -54845683.9691776397285506712812754 -> -367399415798804503177949985597798 Inexact Rounded
+addx3415 add -2.87155919781024108503670175443740 89529730130.6427881332776797193807 -> 89529730127.7712289354674386343440 Inexact Rounded
+comx3415 compare -2.87155919781024108503670175443740 89529730130.6427881332776797193807 -> -1
+divx3415 divide -2.87155919781024108503670175443740 89529730130.6427881332776797193807 -> -3.20738060264454013174835928754430E-11 Inexact Rounded
+dvix3415 divideint -2.87155919781024108503670175443740 89529730130.6427881332776797193807 -> -0
+mulx3415 multiply -2.87155919781024108503670175443740 89529730130.6427881332776797193807 -> -257089920034.115975469931085527642 Inexact Rounded
+powx3415 power -2.87155919781024108503670175443740 9 -> -13275.7774683251354527310820885737 Inexact Rounded
+remx3415 remainder -2.87155919781024108503670175443740 89529730130.6427881332776797193807 -> -2.87155919781024108503670175443740
+subx3415 subtract -2.87155919781024108503670175443740 89529730130.6427881332776797193807 -> -89529730133.5143473310879208044174 Inexact Rounded
+addx3416 add -010.693934338179479652178057279204E+188 26484.8887731973153745666514260684 -> -1.06939343381794796521780572792040E+189 Inexact Rounded
+comx3416 compare -010.693934338179479652178057279204E+188 26484.8887731973153745666514260684 -> -1
+divx3416 divide -010.693934338179479652178057279204E+188 26484.8887731973153745666514260684 -> -4.03774938598259547575707503087638E+184 Inexact Rounded
+dvix3416 divideint -010.693934338179479652178057279204E+188 26484.8887731973153745666514260684 -> NaN Division_impossible
+mulx3416 multiply -010.693934338179479652178057279204E+188 26484.8887731973153745666514260684 -> -2.83227661494558963558481633880647E+193 Inexact Rounded
+powx3416 power -010.693934338179479652178057279204E+188 26485 -> -Infinity Overflow Inexact Rounded
+remx3416 remainder -010.693934338179479652178057279204E+188 26484.8887731973153745666514260684 -> NaN Division_impossible
+subx3416 subtract -010.693934338179479652178057279204E+188 26484.8887731973153745666514260684 -> -1.06939343381794796521780572792040E+189 Inexact Rounded
+addx3417 add 611655569568.832698912762075889186 010182743219.475839030505966016982 -> 621838312788.308537943268041906168
+comx3417 compare 611655569568.832698912762075889186 010182743219.475839030505966016982 -> 1
+divx3417 divide 611655569568.832698912762075889186 010182743219.475839030505966016982 -> 60.0678575886074367081836436812959 Inexact Rounded
+dvix3417 divideint 611655569568.832698912762075889186 010182743219.475839030505966016982 -> 60
+mulx3417 multiply 611655569568.832698912762075889186 010182743219.475839030505966016982 -> 6228331603681663511826.60450280350 Inexact Rounded
+powx3417 power 611655569568.832698912762075889186 1 -> 611655569568.832698912762075889186
+remx3417 remainder 611655569568.832698912762075889186 010182743219.475839030505966016982 -> 690976400.282357082404114870266
+subx3417 subtract 611655569568.832698912762075889186 010182743219.475839030505966016982 -> 601472826349.356859882256109872204
+addx3418 add 3457947.39062863674882672518304442 -01.9995218868908849056866549811425 -> 3457945.39110674985794181949638944 Inexact Rounded
+comx3418 compare 3457947.39062863674882672518304442 -01.9995218868908849056866549811425 -> 1
+divx3418 divide 3457947.39062863674882672518304442 -01.9995218868908849056866549811425 -> -1729387.11663991852426428263230475 Inexact Rounded
+dvix3418 divideint 3457947.39062863674882672518304442 -01.9995218868908849056866549811425 -> -1729387
+mulx3418 multiply 3457947.39062863674882672518304442 -01.9995218868908849056866549811425 -> -6914241.49127918361259252956576654 Inexact Rounded
+powx3418 power 3457947.39062863674882672518304442 -2 -> 8.36302195229701913376802373659526E-14 Inexact Rounded
+remx3418 remainder 3457947.39062863674882672518304442 -01.9995218868908849056866549811425 -> 0.2332240699744359979851713353525
+subx3418 subtract 3457947.39062863674882672518304442 -01.9995218868908849056866549811425 -> 3457949.39015052363971163086969940 Inexact Rounded
+addx3419 add -53308666960535.7393391289364591513 -6527.00547629475578694521436764596E-442 -> -53308666960535.7393391289364591513 Inexact Rounded
+comx3419 compare -53308666960535.7393391289364591513 -6527.00547629475578694521436764596E-442 -> -1
+divx3419 divide -53308666960535.7393391289364591513 -6527.00547629475578694521436764596E-442 -> 8.16740037282731870883136714441204E+451 Inexact Rounded
+dvix3419 divideint -53308666960535.7393391289364591513 -6527.00547629475578694521436764596E-442 -> NaN Division_impossible
+mulx3419 multiply -53308666960535.7393391289364591513 -6527.00547629475578694521436764596E-442 -> 3.47945961185390084641156250100085E-425 Inexact Rounded
+powx3419 power -53308666960535.7393391289364591513 -7 -> -8.17363502380497033342380498988958E-97 Inexact Rounded
+remx3419 remainder -53308666960535.7393391289364591513 -6527.00547629475578694521436764596E-442 -> NaN Division_impossible
+subx3419 subtract -53308666960535.7393391289364591513 -6527.00547629475578694521436764596E-442 -> -53308666960535.7393391289364591513 Inexact Rounded
+addx3420 add -5568057.17870139549478277980540034 -407906443.141342175740471849723638 -> -413474500.320043571235254629529038 Inexact Rounded
+comx3420 compare -5568057.17870139549478277980540034 -407906443.141342175740471849723638 -> 1
+divx3420 divide -5568057.17870139549478277980540034 -407906443.141342175740471849723638 -> 0.0136503290701197094953429018013146 Inexact Rounded
+dvix3420 divideint -5568057.17870139549478277980540034 -407906443.141342175740471849723638 -> 0
+mulx3420 multiply -5568057.17870139549478277980540034 -407906443.141342175740471849723638 -> 2271246398971702.91169807728132089 Inexact Rounded
+powx3420 power -5568057.17870139549478277980540034 -407906443 -> -0E-10031 Underflow Subnormal Inexact Rounded Clamped
+remx3420 remainder -5568057.17870139549478277980540034 -407906443.141342175740471849723638 -> -5568057.17870139549478277980540034
+subx3420 subtract -5568057.17870139549478277980540034 -407906443.141342175740471849723638 -> 402338385.962640780245689069918238 Inexact Rounded
+addx3421 add 9804385273.49533524416415189990857 84.1433929743544659553964804646569 -> 9804385357.63872821851861785530505 Inexact Rounded
+comx3421 compare 9804385273.49533524416415189990857 84.1433929743544659553964804646569 -> 1
+divx3421 divide 9804385273.49533524416415189990857 84.1433929743544659553964804646569 -> 116519965.821719977402398190558439 Inexact Rounded
+dvix3421 divideint 9804385273.49533524416415189990857 84.1433929743544659553964804646569 -> 116519965
+mulx3421 multiply 9804385273.49533524416415189990857 84.1433929743544659553964804646569 -> 824974242939.691780798621180901714 Inexact Rounded
+powx3421 power 9804385273.49533524416415189990857 84 -> 1.90244010779692739037080418507909E+839 Inexact Rounded
+remx3421 remainder 9804385273.49533524416415189990857 84.1433929743544659553964804646569 -> 69.1423069734476624350435642749915
+subx3421 subtract 9804385273.49533524416415189990857 84.1433929743544659553964804646569 -> 9804385189.35194226980968594451209 Inexact Rounded
+addx3422 add -5234910986592.18801727046580014273E-547 -5874220715892.91440069210512515154 -> -5874220715892.91440069210512515154 Inexact Rounded
+comx3422 compare -5234910986592.18801727046580014273E-547 -5874220715892.91440069210512515154 -> 1
+divx3422 divide -5234910986592.18801727046580014273E-547 -5874220715892.91440069210512515154 -> 8.91166886601477021757439826903776E-548 Inexact Rounded
+dvix3422 divideint -5234910986592.18801727046580014273E-547 -5874220715892.91440069210512515154 -> 0
+mulx3422 multiply -5234910986592.18801727046580014273E-547 -5874220715892.91440069210512515154 -> 3.07510225632952455144944282925583E-522 Inexact Rounded
+powx3422 power -5234910986592.18801727046580014273E-547 -6 -> 4.85896970703117149235935037271084E+3205 Inexact Rounded
+remx3422 remainder -5234910986592.18801727046580014273E-547 -5874220715892.91440069210512515154 -> -5.23491098659218801727046580014273E-535
+subx3422 subtract -5234910986592.18801727046580014273E-547 -5874220715892.91440069210512515154 -> 5874220715892.91440069210512515154 Inexact Rounded
+addx3423 add 698416560151955285929747633786867E-495 51754681.6784872628933218985216916E-266 -> 5.17546816784872628933218985216916E-259 Inexact Rounded
+comx3423 compare 698416560151955285929747633786867E-495 51754681.6784872628933218985216916E-266 -> -1
+divx3423 divide 698416560151955285929747633786867E-495 51754681.6784872628933218985216916E-266 -> 1.34947513442491971488363250398908E-204 Inexact Rounded
+dvix3423 divideint 698416560151955285929747633786867E-495 51754681.6784872628933218985216916E-266 -> 0
+mulx3423 multiply 698416560151955285929747633786867E-495 51754681.6784872628933218985216916E-266 -> 3.61463267496484976064271305679796E-721 Inexact Rounded
+powx3423 power 698416560151955285929747633786867E-495 5 -> 1.66177661007189430761396979787413E-2311 Inexact Rounded
+remx3423 remainder 698416560151955285929747633786867E-495 51754681.6784872628933218985216916E-266 -> 6.98416560151955285929747633786867E-463
+subx3423 subtract 698416560151955285929747633786867E-495 51754681.6784872628933218985216916E-266 -> -5.17546816784872628933218985216916E-259 Inexact Rounded
+addx3424 add 107635.497735316515080720330536027 -3972075.83989512668362609609006425E-605 -> 107635.497735316515080720330536027 Inexact Rounded
+comx3424 compare 107635.497735316515080720330536027 -3972075.83989512668362609609006425E-605 -> 1
+divx3424 divide 107635.497735316515080720330536027 -3972075.83989512668362609609006425E-605 -> -2.70980469844599888443309571235597E+603 Inexact Rounded
+dvix3424 divideint 107635.497735316515080720330536027 -3972075.83989512668362609609006425E-605 -> NaN Division_impossible
+mulx3424 multiply 107635.497735316515080720330536027 -3972075.83989512668362609609006425E-605 -> -4.27536360069537352698066408021773E-594 Inexact Rounded
+powx3424 power 107635.497735316515080720330536027 -4 -> 7.45037111502910487803432806334714E-21 Inexact Rounded
+remx3424 remainder 107635.497735316515080720330536027 -3972075.83989512668362609609006425E-605 -> NaN Division_impossible
+subx3424 subtract 107635.497735316515080720330536027 -3972075.83989512668362609609006425E-605 -> 107635.497735316515080720330536027 Inexact Rounded
+addx3425 add -32174291345686.5371446616670961807 79518863759385.5925052747867099091E+408 -> 7.95188637593855925052747867099091E+421 Inexact Rounded
+comx3425 compare -32174291345686.5371446616670961807 79518863759385.5925052747867099091E+408 -> -1
+divx3425 divide -32174291345686.5371446616670961807 79518863759385.5925052747867099091E+408 -> -4.04612060894658007715621807881076E-409 Inexact Rounded
+dvix3425 divideint -32174291345686.5371446616670961807 79518863759385.5925052747867099091E+408 -> -0
+mulx3425 multiply -32174291345686.5371446616670961807 79518863759385.5925052747867099091E+408 -> -2.55846309007242668513226814043593E+435 Inexact Rounded
+powx3425 power -32174291345686.5371446616670961807 8 -> 1.14834377656109143210058690590666E+108 Inexact Rounded
+remx3425 remainder -32174291345686.5371446616670961807 79518863759385.5925052747867099091E+408 -> -32174291345686.5371446616670961807
+subx3425 subtract -32174291345686.5371446616670961807 79518863759385.5925052747867099091E+408 -> -7.95188637593855925052747867099091E+421 Inexact Rounded
+addx3426 add -8151730494.53190523620899410544099E+688 -93173.0631474527142307644239919480E+900 -> -9.31730631474527142307644239919480E+904 Inexact Rounded
+comx3426 compare -8151730494.53190523620899410544099E+688 -93173.0631474527142307644239919480E+900 -> 1
+divx3426 divide -8151730494.53190523620899410544099E+688 -93173.0631474527142307644239919480E+900 -> 8.74902060655796717043678441884283E-208 Inexact Rounded
+dvix3426 divideint -8151730494.53190523620899410544099E+688 -93173.0631474527142307644239919480E+900 -> 0
+mulx3426 multiply -8151730494.53190523620899410544099E+688 -93173.0631474527142307644239919480E+900 -> 7.59521700128037149179751467730962E+1602 Inexact Rounded
+powx3426 power -8151730494.53190523620899410544099E+688 -9 -> -6.29146352774842448375275282183700E-6282 Inexact Rounded
+remx3426 remainder -8151730494.53190523620899410544099E+688 -93173.0631474527142307644239919480E+900 -> -8.15173049453190523620899410544099E+697
+subx3426 subtract -8151730494.53190523620899410544099E+688 -93173.0631474527142307644239919480E+900 -> 9.31730631474527142307644239919480E+904 Inexact Rounded
+addx3427 add 1.33649801345976199708341799505220 -56623.0530039528969825480755159562E+459 -> -5.66230530039528969825480755159562E+463 Inexact Rounded
+comx3427 compare 1.33649801345976199708341799505220 -56623.0530039528969825480755159562E+459 -> 1
+divx3427 divide 1.33649801345976199708341799505220 -56623.0530039528969825480755159562E+459 -> -2.36034255052700900395787131334608E-464 Inexact Rounded
+dvix3427 divideint 1.33649801345976199708341799505220 -56623.0530039528969825480755159562E+459 -> -0
+mulx3427 multiply 1.33649801345976199708341799505220 -56623.0530039528969825480755159562E+459 -> -7.56765978558098558928268129700052E+463 Inexact Rounded
+powx3427 power 1.33649801345976199708341799505220 -6 -> 0.175464835912284900180305028965188 Inexact Rounded
+remx3427 remainder 1.33649801345976199708341799505220 -56623.0530039528969825480755159562E+459 -> 1.33649801345976199708341799505220
+subx3427 subtract 1.33649801345976199708341799505220 -56623.0530039528969825480755159562E+459 -> 5.66230530039528969825480755159562E+463 Inexact Rounded
+addx3428 add 67762238162788.6551061476018185196 -6140.75837959248100352788853809376E-822 -> 67762238162788.6551061476018185196 Inexact Rounded
+comx3428 compare 67762238162788.6551061476018185196 -6140.75837959248100352788853809376E-822 -> 1
+divx3428 divide 67762238162788.6551061476018185196 -6140.75837959248100352788853809376E-822 -> -1.10348321777294157014941951870409E+832 Inexact Rounded
+dvix3428 divideint 67762238162788.6551061476018185196 -6140.75837959248100352788853809376E-822 -> NaN Division_impossible
+mulx3428 multiply 67762238162788.6551061476018185196 -6140.75837959248100352788853809376E-822 -> -4.16111531818085838717201828773857E-805 Inexact Rounded
+powx3428 power 67762238162788.6551061476018185196 -6 -> 1.03293631708006509074972764670281E-83 Inexact Rounded
+remx3428 remainder 67762238162788.6551061476018185196 -6140.75837959248100352788853809376E-822 -> NaN Division_impossible
+subx3428 subtract 67762238162788.6551061476018185196 -6140.75837959248100352788853809376E-822 -> 67762238162788.6551061476018185196 Inexact Rounded
+addx3429 add 4286562.76568866751577306056498271 6286.77291578497580015557979349893E+820 -> 6.28677291578497580015557979349893E+823 Inexact Rounded
+comx3429 compare 4286562.76568866751577306056498271 6286.77291578497580015557979349893E+820 -> -1
+divx3429 divide 4286562.76568866751577306056498271 6286.77291578497580015557979349893E+820 -> 6.81838333133660025740681459349372E-818 Inexact Rounded
+dvix3429 divideint 4286562.76568866751577306056498271 6286.77291578497580015557979349893E+820 -> 0
+mulx3429 multiply 4286562.76568866751577306056498271 6286.77291578497580015557979349893E+820 -> 2.69486466971438542975159893306219E+830 Inexact Rounded
+powx3429 power 4286562.76568866751577306056498271 6 -> 6.20376193064412081058181881805108E+39 Inexact Rounded
+remx3429 remainder 4286562.76568866751577306056498271 6286.77291578497580015557979349893E+820 -> 4286562.76568866751577306056498271
+subx3429 subtract 4286562.76568866751577306056498271 6286.77291578497580015557979349893E+820 -> -6.28677291578497580015557979349893E+823 Inexact Rounded
+addx3430 add -765782.827432642697305644096365566 67.1634368459576834692758114618652 -> -765715.663995796739622174820554104 Inexact Rounded
+comx3430 compare -765782.827432642697305644096365566 67.1634368459576834692758114618652 -> -1
+divx3430 divide -765782.827432642697305644096365566 67.1634368459576834692758114618652 -> -11401.7814363639478774761697650867 Inexact Rounded
+dvix3430 divideint -765782.827432642697305644096365566 67.1634368459576834692758114618652 -> -11401
+mulx3430 multiply -765782.827432642697305644096365566 67.1634368459576834692758114618652 -> -51432606.5679912088468256122315944 Inexact Rounded
+powx3430 power -765782.827432642697305644096365566 67 -> -1.71821200770749773595473594136582E+394 Inexact Rounded
+remx3430 remainder -765782.827432642697305644096365566 67.1634368459576834692758114618652 -> -52.4839518791480724305698888408548
+subx3430 subtract -765782.827432642697305644096365566 67.1634368459576834692758114618652 -> -765849.990869488654989113372177028 Inexact Rounded
+addx3431 add 46.2835931916106252756465724211276 59.2989237834093118332826617957791 -> 105.582516975019937108929234216907 Inexact Rounded
+comx3431 compare 46.2835931916106252756465724211276 59.2989237834093118332826617957791 -> -1
+divx3431 divide 46.2835931916106252756465724211276 59.2989237834093118332826617957791 -> 0.780513207299722975882416995140701 Inexact Rounded
+dvix3431 divideint 46.2835931916106252756465724211276 59.2989237834093118332826617957791 -> 0
+mulx3431 multiply 46.2835931916106252756465724211276 59.2989237834093118332826617957791 -> 2744.56726509164060561370653286614 Inexact Rounded
+powx3431 power 46.2835931916106252756465724211276 59 -> 1.82052645780601002671007943923993E+98 Inexact Rounded
+remx3431 remainder 46.2835931916106252756465724211276 59.2989237834093118332826617957791 -> 46.2835931916106252756465724211276
+subx3431 subtract 46.2835931916106252756465724211276 59.2989237834093118332826617957791 -> -13.0153305917986865576360893746515
+addx3432 add -3029555.82298840234029474459694644 857535844655004737373089601128532 -> 857535844655004737373089598098976 Inexact Rounded
+comx3432 compare -3029555.82298840234029474459694644 857535844655004737373089601128532 -> -1
+divx3432 divide -3029555.82298840234029474459694644 857535844655004737373089601128532 -> -3.53286202771759704502126811323937E-27 Inexact Rounded
+dvix3432 divideint -3029555.82298840234029474459694644 857535844655004737373089601128532 -> -0
+mulx3432 multiply -3029555.82298840234029474459694644 857535844655004737373089601128532 -> -2.59795271159584761928986181925721E+39 Inexact Rounded
+powx3432 power -3029555.82298840234029474459694644 9 -> -2.14986224790431302561340100746360E+58 Inexact Rounded
+remx3432 remainder -3029555.82298840234029474459694644 857535844655004737373089601128532 -> -3029555.82298840234029474459694644
+subx3432 subtract -3029555.82298840234029474459694644 857535844655004737373089601128532 -> -857535844655004737373089604158088 Inexact Rounded
+addx3433 add -0138466789523.10694176543700501945E-948 481026979918882487383654367924619 -> 481026979918882487383654367924619 Inexact Rounded
+comx3433 compare -0138466789523.10694176543700501945E-948 481026979918882487383654367924619 -> -1
+divx3433 divide -0138466789523.10694176543700501945E-948 481026979918882487383654367924619 -> -2.87856597038397207797777811199804E-970 Inexact Rounded
+dvix3433 divideint -0138466789523.10694176543700501945E-948 481026979918882487383654367924619 -> -0
+mulx3433 multiply -0138466789523.10694176543700501945E-948 481026979918882487383654367924619 -> -6.66062615833636908683785283687416E-905 Inexact Rounded
+powx3433 power -0138466789523.10694176543700501945E-948 5 -> -5.09012109092637525843636056746667E-4685 Inexact Rounded
+remx3433 remainder -0138466789523.10694176543700501945E-948 481026979918882487383654367924619 -> -1.3846678952310694176543700501945E-937
+subx3433 subtract -0138466789523.10694176543700501945E-948 481026979918882487383654367924619 -> -481026979918882487383654367924619 Inexact Rounded
+addx3434 add -9593566466.96690575714244442109870 -87632034347.4845477961976776833770E+769 -> -8.76320343474845477961976776833770E+779 Inexact Rounded
+comx3434 compare -9593566466.96690575714244442109870 -87632034347.4845477961976776833770E+769 -> 1
+divx3434 divide -9593566466.96690575714244442109870 -87632034347.4845477961976776833770E+769 -> 1.09475564939253134070730299863765E-770 Inexact Rounded
+dvix3434 divideint -9593566466.96690575714244442109870 -87632034347.4845477961976776833770E+769 -> 0
+mulx3434 multiply -9593566466.96690575714244442109870 -87632034347.4845477961976776833770E+769 -> 8.40703746148119867711463485065336E+789 Inexact Rounded
+powx3434 power -9593566466.96690575714244442109870 -9 -> -1.45271091841882960010964421066745E-90 Inexact Rounded
+remx3434 remainder -9593566466.96690575714244442109870 -87632034347.4845477961976776833770E+769 -> -9593566466.96690575714244442109870
+subx3434 subtract -9593566466.96690575714244442109870 -87632034347.4845477961976776833770E+769 -> 8.76320343474845477961976776833770E+779 Inexact Rounded
+addx3435 add -3189.30765477670526823106100241863E-898 565688889.355241946154894311253202E-466 -> 5.65688889355241946154894311253202E-458 Inexact Rounded
+comx3435 compare -3189.30765477670526823106100241863E-898 565688889.355241946154894311253202E-466 -> -1
+divx3435 divide -3189.30765477670526823106100241863E-898 565688889.355241946154894311253202E-466 -> -5.63791814686655486612569970629128E-438 Inexact Rounded
+dvix3435 divideint -3189.30765477670526823106100241863E-898 565688889.355241946154894311253202E-466 -> -0
+mulx3435 multiply -3189.30765477670526823106100241863E-898 565688889.355241946154894311253202E-466 -> -1.80415590504280580443565448126548E-1352 Inexact Rounded
+powx3435 power -3189.30765477670526823106100241863E-898 6 -> 1.05239431027683904514311527228736E-5367 Inexact Rounded
+remx3435 remainder -3189.30765477670526823106100241863E-898 565688889.355241946154894311253202E-466 -> -3.18930765477670526823106100241863E-895
+subx3435 subtract -3189.30765477670526823106100241863E-898 565688889.355241946154894311253202E-466 -> -5.65688889355241946154894311253202E-458 Inexact Rounded
+addx3436 add -17084552395.6714834680088150543965 -631925802672.685034379197328370812E+527 -> -6.31925802672685034379197328370812E+538 Inexact Rounded
+comx3436 compare -17084552395.6714834680088150543965 -631925802672.685034379197328370812E+527 -> 1
+divx3436 divide -17084552395.6714834680088150543965 -631925802672.685034379197328370812E+527 -> 2.70356936263934622050341328519534E-529 Inexact Rounded
+dvix3436 divideint -17084552395.6714834680088150543965 -631925802672.685034379197328370812E+527 -> 0
+mulx3436 multiply -17084552395.6714834680088150543965 -631925802672.685034379197328370812E+527 -> 1.07961694859382462346866817306769E+549 Inexact Rounded
+powx3436 power -17084552395.6714834680088150543965 -6 -> 4.02141014977177984123011868387622E-62 Inexact Rounded
+remx3436 remainder -17084552395.6714834680088150543965 -631925802672.685034379197328370812E+527 -> -17084552395.6714834680088150543965
+subx3436 subtract -17084552395.6714834680088150543965 -631925802672.685034379197328370812E+527 -> 6.31925802672685034379197328370812E+538 Inexact Rounded
+addx3437 add 034956830.349823306815911887469760 -61600816.0672274126966042956781665E-667 -> 34956830.3498233068159118874697600 Inexact Rounded
+comx3437 compare 034956830.349823306815911887469760 -61600816.0672274126966042956781665E-667 -> 1
+divx3437 divide 034956830.349823306815911887469760 -61600816.0672274126966042956781665E-667 -> -5.67473494371787737607169979602343E+666 Inexact Rounded
+dvix3437 divideint 034956830.349823306815911887469760 -61600816.0672274126966042956781665E-667 -> NaN Division_impossible
+mulx3437 multiply 034956830.349823306815911887469760 -61600816.0672274126966042956781665E-667 -> -2.15336927667273841617128781173293E-652 Inexact Rounded
+powx3437 power 034956830.349823306815911887469760 -6 -> 5.48034272566098493462169431762597E-46 Inexact Rounded
+remx3437 remainder 034956830.349823306815911887469760 -61600816.0672274126966042956781665E-667 -> NaN Division_impossible
+subx3437 subtract 034956830.349823306815911887469760 -61600816.0672274126966042956781665E-667 -> 34956830.3498233068159118874697600 Inexact Rounded
+addx3438 add -763.440067781256632695791981893608 19.9263811350611007833220620745413 -> -743.513686646195531912469919819067 Inexact Rounded
+comx3438 compare -763.440067781256632695791981893608 19.9263811350611007833220620745413 -> -1
+divx3438 divide -763.440067781256632695791981893608 19.9263811350611007833220620745413 -> -38.3130314835722766807703585435688 Inexact Rounded
+dvix3438 divideint -763.440067781256632695791981893608 19.9263811350611007833220620745413 -> -38
+mulx3438 multiply -763.440067781256632695791981893608 19.9263811350611007833220620745413 -> -15212.5977643862002585039364868883 Inexact Rounded
+powx3438 power -763.440067781256632695791981893608 20 -> 4.52375407727336769552481661250924E+57 Inexact Rounded
+remx3438 remainder -763.440067781256632695791981893608 19.9263811350611007833220620745413 -> -6.2375846489348029295536230610386
+subx3438 subtract -763.440067781256632695791981893608 19.9263811350611007833220620745413 -> -783.366448916317733479114043968149 Inexact Rounded
+addx3439 add -510472027868440667684575147556654E+789 834872378550801889983927148587909 -> -5.10472027868440667684575147556654E+821 Inexact Rounded
+comx3439 compare -510472027868440667684575147556654E+789 834872378550801889983927148587909 -> -1
+divx3439 divide -510472027868440667684575147556654E+789 834872378550801889983927148587909 -> -6.11437198047603754107526874071737E+788 Inexact Rounded
+dvix3439 divideint -510472027868440667684575147556654E+789 834872378550801889983927148587909 -> NaN Division_impossible
+mulx3439 multiply -510472027868440667684575147556654E+789 834872378550801889983927148587909 -> -4.26178996090176289115594057419892E+854 Inexact Rounded
+powx3439 power -510472027868440667684575147556654E+789 8 -> 4.61079266619522147262600755274182E+6573 Inexact Rounded
+remx3439 remainder -510472027868440667684575147556654E+789 834872378550801889983927148587909 -> NaN Division_impossible
+subx3439 subtract -510472027868440667684575147556654E+789 834872378550801889983927148587909 -> -5.10472027868440667684575147556654E+821 Inexact Rounded
+addx3440 add 070304761.560517086676993503034828E-094 -17773.7446959771077104057845273992E-761 -> 7.03047615605170866769935030348280E-87 Inexact Rounded
+comx3440 compare 070304761.560517086676993503034828E-094 -17773.7446959771077104057845273992E-761 -> 1
+divx3440 divide 070304761.560517086676993503034828E-094 -17773.7446959771077104057845273992E-761 -> -3.95554019499502537743883483402608E+670 Inexact Rounded
+dvix3440 divideint 070304761.560517086676993503034828E-094 -17773.7446959771077104057845273992E-761 -> NaN Division_impossible
+mulx3440 multiply 070304761.560517086676993503034828E-094 -17773.7446959771077104057845273992E-761 -> -1.24957888288817581538108991453732E-843 Inexact Rounded
+powx3440 power 070304761.560517086676993503034828E-094 -2 -> 2.02316135427631488479902919959627E+172 Inexact Rounded
+remx3440 remainder 070304761.560517086676993503034828E-094 -17773.7446959771077104057845273992E-761 -> NaN Division_impossible
+subx3440 subtract 070304761.560517086676993503034828E-094 -17773.7446959771077104057845273992E-761 -> 7.03047615605170866769935030348280E-87 Inexact Rounded
+addx3441 add -0970725697662.27605454336231195463 -4541.41897546697187157913886433474 -> -970725702203.695030010334183533769 Inexact Rounded
+comx3441 compare -0970725697662.27605454336231195463 -4541.41897546697187157913886433474 -> -1
+divx3441 divide -0970725697662.27605454336231195463 -4541.41897546697187157913886433474 -> 213749425.654447811698884007553614 Inexact Rounded
+dvix3441 divideint -0970725697662.27605454336231195463 -4541.41897546697187157913886433474 -> 213749425
+mulx3441 multiply -0970725697662.27605454336231195463 -4541.41897546697187157913886433474 -> 4408472103336875.21161867891724392 Inexact Rounded
+powx3441 power -0970725697662.27605454336231195463 -4541 -> -0E-10031 Underflow Subnormal Inexact Rounded Clamped
+remx3441 remainder -0970725697662.27605454336231195463 -4541.41897546697187157913886433474 -> -2972.12171050214753770792631747550
+subx3441 subtract -0970725697662.27605454336231195463 -4541.41897546697187157913886433474 -> -970725693120.857079076390440375491 Inexact Rounded
+addx3442 add -808178238631844268316111259558675 -598400.265108644514211244980426520 -> -808178238631844268316111260157075 Inexact Rounded
+comx3442 compare -808178238631844268316111259558675 -598400.265108644514211244980426520 -> -1
+divx3442 divide -808178238631844268316111259558675 -598400.265108644514211244980426520 -> 1350564640015847635178945884.97836 Inexact Rounded
+dvix3442 divideint -808178238631844268316111259558675 -598400.265108644514211244980426520 -> 1350564640015847635178945884
+mulx3442 multiply -808178238631844268316111259558675 -598400.265108644514211244980426520 -> 4.83614072252332979731348423145208E+38 Inexact Rounded
+powx3442 power -808178238631844268316111259558675 -598400 -> 0E-10031 Underflow Subnormal Inexact Rounded Clamped
+remx3442 remainder -808178238631844268316111259558675 -598400.265108644514211244980426520 -> -585452.097764536570956813681556320
+subx3442 subtract -808178238631844268316111259558675 -598400.265108644514211244980426520 -> -808178238631844268316111258960275 Inexact Rounded
+addx3443 add -9.90826595069053564311371766315200 -031.625916781307847864872329806646 -> -41.5341827319983835079860474697980 Rounded
+comx3443 compare -9.90826595069053564311371766315200 -031.625916781307847864872329806646 -> 1
+divx3443 divide -9.90826595069053564311371766315200 -031.625916781307847864872329806646 -> 0.313295770023233218639213140599856 Inexact Rounded
+dvix3443 divideint -9.90826595069053564311371766315200 -031.625916781307847864872329806646 -> 0
+mulx3443 multiply -9.90826595069053564311371766315200 -031.625916781307847864872329806646 -> 313.357994403604968250936036978086 Inexact Rounded
+powx3443 power -9.90826595069053564311371766315200 -32 -> 1.34299698259038003011439568004625E-32 Inexact Rounded
+remx3443 remainder -9.90826595069053564311371766315200 -031.625916781307847864872329806646 -> -9.90826595069053564311371766315200
+subx3443 subtract -9.90826595069053564311371766315200 -031.625916781307847864872329806646 -> 21.7176508306173122217586121434940 Rounded
+addx3444 add -196925.469891897719160698483752907 -41268.9975444533794067723958739778 -> -238194.467436351098567470879626885 Inexact Rounded
+comx3444 compare -196925.469891897719160698483752907 -41268.9975444533794067723958739778 -> -1
+divx3444 divide -196925.469891897719160698483752907 -41268.9975444533794067723958739778 -> 4.77175317088274715226553516820589 Inexact Rounded
+dvix3444 divideint -196925.469891897719160698483752907 -41268.9975444533794067723958739778 -> 4
+mulx3444 multiply -196925.469891897719160698483752907 -41268.9975444533794067723958739778 -> 8126916733.40905487026003135987472 Inexact Rounded
+powx3444 power -196925.469891897719160698483752907 -41269 -> -0E-10031 Underflow Subnormal Inexact Rounded Clamped
+remx3444 remainder -196925.469891897719160698483752907 -41268.9975444533794067723958739778 -> -31849.4797140842015336089002569958
+subx3444 subtract -196925.469891897719160698483752907 -41268.9975444533794067723958739778 -> -155656.472347444339753926087878929 Inexact Rounded
+addx3445 add 421071135212152225162086005824310 1335320330.08964354845796510145246E-604 -> 421071135212152225162086005824310 Inexact Rounded
+comx3445 compare 421071135212152225162086005824310 1335320330.08964354845796510145246E-604 -> 1
+divx3445 divide 421071135212152225162086005824310 1335320330.08964354845796510145246E-604 -> 3.15333426537349744281860005497304E+627 Inexact Rounded
+dvix3445 divideint 421071135212152225162086005824310 1335320330.08964354845796510145246E-604 -> NaN Division_impossible
+mulx3445 multiply 421071135212152225162086005824310 1335320330.08964354845796510145246E-604 -> 5.62264847262712040027311932121460E-563 Inexact Rounded
+powx3445 power 421071135212152225162086005824310 1 -> 421071135212152225162086005824310
+remx3445 remainder 421071135212152225162086005824310 1335320330.08964354845796510145246E-604 -> NaN Division_impossible
+subx3445 subtract 421071135212152225162086005824310 1335320330.08964354845796510145246E-604 -> 421071135212152225162086005824310 Inexact Rounded
+addx3446 add 1249441.46421514282301182772247227 -0289848.71208912281976374705180836E-676 -> 1249441.46421514282301182772247227 Inexact Rounded
+comx3446 compare 1249441.46421514282301182772247227 -0289848.71208912281976374705180836E-676 -> 1
+divx3446 divide 1249441.46421514282301182772247227 -0289848.71208912281976374705180836E-676 -> -4.31066764178328992440635387255816E+676 Inexact Rounded
+dvix3446 divideint 1249441.46421514282301182772247227 -0289848.71208912281976374705180836E-676 -> NaN Division_impossible
+mulx3446 multiply 1249441.46421514282301182772247227 -0289848.71208912281976374705180836E-676 -> -3.62148999233506984566620611700349E-665 Inexact Rounded
+powx3446 power 1249441.46421514282301182772247227 -3 -> 5.12686942572191282348415024932322E-19 Inexact Rounded
+remx3446 remainder 1249441.46421514282301182772247227 -0289848.71208912281976374705180836E-676 -> NaN Division_impossible
+subx3446 subtract 1249441.46421514282301182772247227 -0289848.71208912281976374705180836E-676 -> 1249441.46421514282301182772247227 Inexact Rounded
+addx3447 add 74815000.4716875558358937279052903 -690425401708167622194241915195001E+891 -> -6.90425401708167622194241915195001E+923 Inexact Rounded
+comx3447 compare 74815000.4716875558358937279052903 -690425401708167622194241915195001E+891 -> 1
+divx3447 divide 74815000.4716875558358937279052903 -690425401708167622194241915195001E+891 -> -1.08360729901578455109968388309079E-916 Inexact Rounded
+dvix3447 divideint 74815000.4716875558358937279052903 -690425401708167622194241915195001E+891 -> -0
+mulx3447 multiply 74815000.4716875558358937279052903 -690425401708167622194241915195001E+891 -> -5.16541767544616308732028810026275E+931 Inexact Rounded
+powx3447 power 74815000.4716875558358937279052903 -7 -> 7.62218032252683815537906972439985E-56 Inexact Rounded
+remx3447 remainder 74815000.4716875558358937279052903 -690425401708167622194241915195001E+891 -> 74815000.4716875558358937279052903
+subx3447 subtract 74815000.4716875558358937279052903 -690425401708167622194241915195001E+891 -> 6.90425401708167622194241915195001E+923 Inexact Rounded
+addx3448 add -1683993.51210241555668790556759021 -72394384927344.8402585228267493374 -> -72394386611338.3523609383834372430 Inexact Rounded
+comx3448 compare -1683993.51210241555668790556759021 -72394384927344.8402585228267493374 -> 1
+divx3448 divide -1683993.51210241555668790556759021 -72394384927344.8402585228267493374 -> 2.32613829621244113284301004158794E-8 Inexact Rounded
+dvix3448 divideint -1683993.51210241555668790556759021 -72394384927344.8402585228267493374 -> 0
+mulx3448 multiply -1683993.51210241555668790556759021 -72394384927344.8402585228267493374 -> 121911674530293613615.441384822381 Inexact Rounded
+powx3448 power -1683993.51210241555668790556759021 -7 -> -2.60385683509956889000676113860292E-44 Inexact Rounded
+remx3448 remainder -1683993.51210241555668790556759021 -72394384927344.8402585228267493374 -> -1683993.51210241555668790556759021
+subx3448 subtract -1683993.51210241555668790556759021 -72394384927344.8402585228267493374 -> 72394383243351.3281561072700614318 Inexact Rounded
+addx3449 add -763.148530974741766171756970448158 517370.808956957601473642272664647 -> 516607.660425982859707470515694199 Inexact Rounded
+comx3449 compare -763.148530974741766171756970448158 517370.808956957601473642272664647 -> -1
+divx3449 divide -763.148530974741766171756970448158 517370.808956957601473642272664647 -> -0.00147505139014951946381155525173867 Inexact Rounded
+dvix3449 divideint -763.148530974741766171756970448158 517370.808956957601473642272664647 -> -0
+mulx3449 multiply -763.148530974741766171756970448158 517370.808956957601473642272664647 -> -394830772.824715962925351447322187 Inexact Rounded
+powx3449 power -763.148530974741766171756970448158 517371 -> -Infinity Overflow Inexact Rounded
+remx3449 remainder -763.148530974741766171756970448158 517370.808956957601473642272664647 -> -763.148530974741766171756970448158
+subx3449 subtract -763.148530974741766171756970448158 517370.808956957601473642272664647 -> -518133.957487932343239814029635095 Inexact Rounded
+addx3450 add -77.5841338812312523460591226178754 -927540422.641025050968830154578151E+524 -> -9.27540422641025050968830154578151E+532 Inexact Rounded
+comx3450 compare -77.5841338812312523460591226178754 -927540422.641025050968830154578151E+524 -> 1
+divx3450 divide -77.5841338812312523460591226178754 -927540422.641025050968830154578151E+524 -> 8.36450164191471769978415758342237E-532 Inexact Rounded
+dvix3450 divideint -77.5841338812312523460591226178754 -927540422.641025050968830154578151E+524 -> 0
+mulx3450 multiply -77.5841338812312523460591226178754 -927540422.641025050968830154578151E+524 -> 7.19624203304351070562409746475943E+534 Inexact Rounded
+powx3450 power -77.5841338812312523460591226178754 -9 -> -9.81846856873938549466341693997829E-18 Inexact Rounded
+remx3450 remainder -77.5841338812312523460591226178754 -927540422.641025050968830154578151E+524 -> -77.5841338812312523460591226178754
+subx3450 subtract -77.5841338812312523460591226178754 -927540422.641025050968830154578151E+524 -> 9.27540422641025050968830154578151E+532 Inexact Rounded
+addx3451 add 5176295309.89943746236102209837813 -129733.103628797477167908698565465 -> 5176165576.79580866488385418967956 Inexact Rounded
+comx3451 compare 5176295309.89943746236102209837813 -129733.103628797477167908698565465 -> 1
+divx3451 divide 5176295309.89943746236102209837813 -129733.103628797477167908698565465 -> -39899.5720067736855444089432524094 Inexact Rounded
+dvix3451 divideint 5176295309.89943746236102209837813 -129733.103628797477167908698565465 -> -39899
+mulx3451 multiply 5176295309.89943746236102209837813 -129733.103628797477167908698565465 -> -671536855852442.071887385512001794 Inexact Rounded
+powx3451 power 5176295309.89943746236102209837813 -129733 -> 0E-10031 Underflow Subnormal Inexact Rounded Clamped
+remx3451 remainder 5176295309.89943746236102209837813 -129733.103628797477167908698565465 -> 74208.214046920838632934314641965
+subx3451 subtract 5176295309.89943746236102209837813 -129733.103628797477167908698565465 -> 5176425043.00306625983819000707670 Inexact Rounded
+addx3452 add 4471634841166.90197229286530307326E+172 31511104397.8671727003201890825879E-955 -> 4.47163484116690197229286530307326E+184 Inexact Rounded
+comx3452 compare 4471634841166.90197229286530307326E+172 31511104397.8671727003201890825879E-955 -> 1
+divx3452 divide 4471634841166.90197229286530307326E+172 31511104397.8671727003201890825879E-955 -> 1.41906636616314987705536737025932E+1129 Inexact Rounded
+dvix3452 divideint 4471634841166.90197229286530307326E+172 31511104397.8671727003201890825879E-955 -> NaN Division_impossible
+mulx3452 multiply 4471634841166.90197229286530307326E+172 31511104397.8671727003201890825879E-955 -> 1.40906152309150441010046222214810E-760 Inexact Rounded
+powx3452 power 4471634841166.90197229286530307326E+172 3 -> 8.94126556389673498386397569249516E+553 Inexact Rounded
+remx3452 remainder 4471634841166.90197229286530307326E+172 31511104397.8671727003201890825879E-955 -> NaN Division_impossible
+subx3452 subtract 4471634841166.90197229286530307326E+172 31511104397.8671727003201890825879E-955 -> 4.47163484116690197229286530307326E+184 Inexact Rounded
+addx3453 add -8189130.15945231049670285726774317 2.57912402871404325831670923864936E-366 -> -8189130.15945231049670285726774317 Inexact Rounded
+comx3453 compare -8189130.15945231049670285726774317 2.57912402871404325831670923864936E-366 -> -1
+divx3453 divide -8189130.15945231049670285726774317 2.57912402871404325831670923864936E-366 -> -3.17515949922556778343526099830093E+372 Inexact Rounded
+dvix3453 divideint -8189130.15945231049670285726774317 2.57912402871404325831670923864936E-366 -> NaN Division_impossible
+mulx3453 multiply -8189130.15945231049670285726774317 2.57912402871404325831670923864936E-366 -> -2.11207823685103185039979144161848E-359 Inexact Rounded
+powx3453 power -8189130.15945231049670285726774317 3 -> -549178241054875982731.000937875885 Inexact Rounded
+remx3453 remainder -8189130.15945231049670285726774317 2.57912402871404325831670923864936E-366 -> NaN Division_impossible
+subx3453 subtract -8189130.15945231049670285726774317 2.57912402871404325831670923864936E-366 -> -8189130.15945231049670285726774317 Inexact Rounded
+addx3454 add -254346232981353293392888785643245 -764.416902486152093758287929678445 -> -254346232981353293392888785644009 Inexact Rounded
+comx3454 compare -254346232981353293392888785643245 -764.416902486152093758287929678445 -> -1
+divx3454 divide -254346232981353293392888785643245 -764.416902486152093758287929678445 -> 332732350833857889204406356900.665 Inexact Rounded
+dvix3454 divideint -254346232981353293392888785643245 -764.416902486152093758287929678445 -> 332732350833857889204406356900
+mulx3454 multiply -254346232981353293392888785643245 -764.416902486152093758287929678445 -> 1.94426559574627262006307326336289E+35 Inexact Rounded
+powx3454 power -254346232981353293392888785643245 -764 -> 0E-10031 Underflow Subnormal Inexact Rounded Clamped
+remx3454 remainder -254346232981353293392888785643245 -764.416902486152093758287929678445 -> -508.299323962538610580669092979500
+subx3454 subtract -254346232981353293392888785643245 -764.416902486152093758287929678445 -> -254346232981353293392888785642481 Inexact Rounded
+addx3455 add -2875.36745499544177964804277329726 -13187.8492045054802205691248267638 -> -16063.2166595009220002171676000611 Inexact Rounded
+comx3455 compare -2875.36745499544177964804277329726 -13187.8492045054802205691248267638 -> 1
+divx3455 divide -2875.36745499544177964804277329726 -13187.8492045054802205691248267638 -> 0.218031569091122520391599541575615 Inexact Rounded
+dvix3455 divideint -2875.36745499544177964804277329726 -13187.8492045054802205691248267638 -> 0
+mulx3455 multiply -2875.36745499544177964804277329726 -13187.8492045054802205691248267638 -> 37919912.4040225840727281633024665 Inexact Rounded
+powx3455 power -2875.36745499544177964804277329726 -13188 -> 0E-10031 Underflow Subnormal Inexact Rounded Clamped
+remx3455 remainder -2875.36745499544177964804277329726 -13187.8492045054802205691248267638 -> -2875.36745499544177964804277329726
+subx3455 subtract -2875.36745499544177964804277329726 -13187.8492045054802205691248267638 -> 10312.4817495100384409210820534665 Inexact Rounded
+addx3456 add -7.26927570984219944693602140223103 0160883021541.32275286769110003971E-438 -> -7.26927570984219944693602140223103 Inexact Rounded
+comx3456 compare -7.26927570984219944693602140223103 0160883021541.32275286769110003971E-438 -> -1
+divx3456 divide -7.26927570984219944693602140223103 0160883021541.32275286769110003971E-438 -> -4.51836100553039917574557235275173E+427 Inexact Rounded
+dvix3456 divideint -7.26927570984219944693602140223103 0160883021541.32275286769110003971E-438 -> NaN Division_impossible
+mulx3456 multiply -7.26927570984219944693602140223103 0160883021541.32275286769110003971E-438 -> -1.16950304061635681891361504442479E-426 Inexact Rounded
+powx3456 power -7.26927570984219944693602140223103 2 -> 52.8423693457018126451998096211036 Inexact Rounded
+remx3456 remainder -7.26927570984219944693602140223103 0160883021541.32275286769110003971E-438 -> NaN Division_impossible
+subx3456 subtract -7.26927570984219944693602140223103 0160883021541.32275286769110003971E-438 -> -7.26927570984219944693602140223103 Inexact Rounded
+addx3457 add -28567151.6868762752241056540028515E+498 -4470.15455137546427645290210989675 -> -2.85671516868762752241056540028515E+505 Inexact Rounded
+comx3457 compare -28567151.6868762752241056540028515E+498 -4470.15455137546427645290210989675 -> -1
+divx3457 divide -28567151.6868762752241056540028515E+498 -4470.15455137546427645290210989675 -> 6.39064071690455919792707589054106E+501 Inexact Rounded
+dvix3457 divideint -28567151.6868762752241056540028515E+498 -4470.15455137546427645290210989675 -> NaN Division_impossible
+mulx3457 multiply -28567151.6868762752241056540028515E+498 -4470.15455137546427645290210989675 -> 1.27699583132923253605397736797000E+509 Inexact Rounded
+powx3457 power -28567151.6868762752241056540028515E+498 -4470 -> 0E-10031 Underflow Subnormal Inexact Rounded Clamped
+remx3457 remainder -28567151.6868762752241056540028515E+498 -4470.15455137546427645290210989675 -> NaN Division_impossible
+subx3457 subtract -28567151.6868762752241056540028515E+498 -4470.15455137546427645290210989675 -> -2.85671516868762752241056540028515E+505 Inexact Rounded
+addx3458 add 7191753.79974136447257468282073718 81.3878426176038487948375777384429 -> 7191835.18758398207642347765831492 Inexact Rounded
+comx3458 compare 7191753.79974136447257468282073718 81.3878426176038487948375777384429 -> 1
+divx3458 divide 7191753.79974136447257468282073718 81.3878426176038487948375777384429 -> 88363.9812586188186733935569874100 Inexact Rounded
+dvix3458 divideint 7191753.79974136447257468282073718 81.3878426176038487948375777384429 -> 88363
+mulx3458 multiply 7191753.79974136447257468282073718 81.3878426176038487948375777384429 -> 585321326.397904638863485891524555 Inexact Rounded
+powx3458 power 7191753.79974136447257468282073718 81 -> 2.53290983138561482612557404148760E+555 Inexact Rounded
+remx3458 remainder 7191753.79974136447257468282073718 81.3878426176038487948375777384429 -> 79.8625220355815164499390351500273
+subx3458 subtract 7191753.79974136447257468282073718 81.3878426176038487948375777384429 -> 7191672.41189874686872588798315944 Inexact Rounded
+addx3459 add 502975804.069864536104621700404770 684.790028432074527960269515227243 -> 502976488.859892968179149660674285 Inexact Rounded
+comx3459 compare 502975804.069864536104621700404770 684.790028432074527960269515227243 -> 1
+divx3459 divide 502975804.069864536104621700404770 684.790028432074527960269515227243 -> 734496.390406706323899801641278933 Inexact Rounded
+dvix3459 divideint 502975804.069864536104621700404770 684.790028432074527960269515227243 -> 734496
+mulx3459 multiply 502975804.069864536104621700404770 684.790028432074527960269515227243 -> 344432815169.648082754214631086270 Inexact Rounded
+powx3459 power 502975804.069864536104621700404770 685 -> 3.62876716573623552761739177592677E+5960 Inexact Rounded
+remx3459 remainder 502975804.069864536104621700404770 684.790028432074527960269515227243 -> 267.346619523615915582548420925472
+subx3459 subtract 502975804.069864536104621700404770 684.790028432074527960269515227243 -> 502975119.279836104030093740135255 Inexact Rounded
+addx3460 add 1505368.42063731861590460453659570 -465242.678439951462767630022819105 -> 1040125.74219736715313697451377660 Inexact Rounded
+comx3460 compare 1505368.42063731861590460453659570 -465242.678439951462767630022819105 -> 1
+divx3460 divide 1505368.42063731861590460453659570 -465242.678439951462767630022819105 -> -3.23566278503319947059213001405065 Inexact Rounded
+dvix3460 divideint 1505368.42063731861590460453659570 -465242.678439951462767630022819105 -> -3
+mulx3460 multiply 1505368.42063731861590460453659570 -465242.678439951462767630022819105 -> -700361636056.225618266296899048765 Inexact Rounded
+powx3460 power 1505368.42063731861590460453659570 -465243 -> 0E-10031 Underflow Subnormal Inexact Rounded Clamped
+remx3460 remainder 1505368.42063731861590460453659570 -465242.678439951462767630022819105 -> 109640.385317464227601714468138385
+subx3460 subtract 1505368.42063731861590460453659570 -465242.678439951462767630022819105 -> 1970611.09907727007867223455941481 Inexact Rounded
+addx3461 add 69225023.2850142784063416137144829 8584050.06648191798834819995325693 -> 77809073.3514961963946898136677398 Inexact Rounded
+comx3461 compare 69225023.2850142784063416137144829 8584050.06648191798834819995325693 -> 1
+divx3461 divide 69225023.2850142784063416137144829 8584050.06648191798834819995325693 -> 8.06437785764050431295652411163382 Inexact Rounded
+dvix3461 divideint 69225023.2850142784063416137144829 8584050.06648191798834819995325693 -> 8
+mulx3461 multiply 69225023.2850142784063416137144829 8584050.06648191798834819995325693 -> 594231065731939.137329770485497261 Inexact Rounded
+powx3461 power 69225023.2850142784063416137144829 8584050 -> Infinity Overflow Inexact Rounded
+remx3461 remainder 69225023.2850142784063416137144829 8584050.06648191798834819995325693 -> 552622.75315893449955601408842746
+subx3461 subtract 69225023.2850142784063416137144829 8584050.06648191798834819995325693 -> 60640973.2185323604179934137612260 Inexact Rounded
+addx3462 add -55669501853.7751006841940471339310E+614 061400538.186044693233816566977189 -> -5.56695018537751006841940471339310E+624 Inexact Rounded
+comx3462 compare -55669501853.7751006841940471339310E+614 061400538.186044693233816566977189 -> -1
+divx3462 divide -55669501853.7751006841940471339310E+614 061400538.186044693233816566977189 -> -9.06661464189378059067792554300676E+616 Inexact Rounded
+dvix3462 divideint -55669501853.7751006841940471339310E+614 061400538.186044693233816566977189 -> NaN Division_impossible
+mulx3462 multiply -55669501853.7751006841940471339310E+614 061400538.186044693233816566977189 -> -3.41813737437080390787865389703565E+632 Inexact Rounded
+powx3462 power -55669501853.7751006841940471339310E+614 61400538 -> Infinity Overflow Inexact Rounded
+remx3462 remainder -55669501853.7751006841940471339310E+614 061400538.186044693233816566977189 -> NaN Division_impossible
+subx3462 subtract -55669501853.7751006841940471339310E+614 061400538.186044693233816566977189 -> -5.56695018537751006841940471339310E+624 Inexact Rounded
+addx3463 add -527566.521273992424649346837337602E-408 -834662.599983953345718523807123972 -> -834662.599983953345718523807123972 Inexact Rounded
+comx3463 compare -527566.521273992424649346837337602E-408 -834662.599983953345718523807123972 -> 1
+divx3463 divide -527566.521273992424649346837337602E-408 -834662.599983953345718523807123972 -> 6.32071595497552015656909892339226E-409 Inexact Rounded
+dvix3463 divideint -527566.521273992424649346837337602E-408 -834662.599983953345718523807123972 -> 0
+mulx3463 multiply -527566.521273992424649346837337602E-408 -834662.599983953345718523807123972 -> 4.40340044311040151960763108019957E-397 Inexact Rounded
+powx3463 power -527566.521273992424649346837337602E-408 -834663 -> -Infinity Overflow Inexact Rounded
+remx3463 remainder -527566.521273992424649346837337602E-408 -834662.599983953345718523807123972 -> -5.27566521273992424649346837337602E-403
+subx3463 subtract -527566.521273992424649346837337602E-408 -834662.599983953345718523807123972 -> 834662.599983953345718523807123972 Inexact Rounded
+addx3464 add 69065510.0459653699418083455335366 694848643848212520086960886818157E-853 -> 69065510.0459653699418083455335366 Inexact Rounded
+comx3464 compare 69065510.0459653699418083455335366 694848643848212520086960886818157E-853 -> 1
+divx3464 divide 69065510.0459653699418083455335366 694848643848212520086960886818157E-853 -> 9.93964810285396646889830919492683E+827 Inexact Rounded
+dvix3464 divideint 69065510.0459653699418083455335366 694848643848212520086960886818157E-853 -> NaN Division_impossible
+mulx3464 multiply 69065510.0459653699418083455335366 694848643848212520086960886818157E-853 -> 4.79900759921241352562381181332720E-813 Inexact Rounded
+powx3464 power 69065510.0459653699418083455335366 7 -> 7.49598249763416483824919118973567E+54 Inexact Rounded
+remx3464 remainder 69065510.0459653699418083455335366 694848643848212520086960886818157E-853 -> NaN Division_impossible
+subx3464 subtract 69065510.0459653699418083455335366 694848643848212520086960886818157E-853 -> 69065510.0459653699418083455335366 Inexact Rounded
+addx3465 add -2921982.82411285505229122890041841 -72994.6523840298017471962569778803E-763 -> -2921982.82411285505229122890041841 Inexact Rounded
+comx3465 compare -2921982.82411285505229122890041841 -72994.6523840298017471962569778803E-763 -> -1
+divx3465 divide -2921982.82411285505229122890041841 -72994.6523840298017471962569778803E-763 -> 4.00300943792444663467732029501716E+764 Inexact Rounded
+dvix3465 divideint -2921982.82411285505229122890041841 -72994.6523840298017471962569778803E-763 -> NaN Division_impossible
+mulx3465 multiply -2921982.82411285505229122890041841 -72994.6523840298017471962569778803E-763 -> 2.13289120518223547921212412642411E-752 Inexact Rounded
+powx3465 power -2921982.82411285505229122890041841 -7 -> -5.49865394870631248479668782154131E-46 Inexact Rounded
+remx3465 remainder -2921982.82411285505229122890041841 -72994.6523840298017471962569778803E-763 -> NaN Division_impossible
+subx3465 subtract -2921982.82411285505229122890041841 -72994.6523840298017471962569778803E-763 -> -2921982.82411285505229122890041841 Inexact Rounded
+addx3466 add 4.51117459466491451401835756593793 3873385.19981811640063144338087230 -> 3873389.71099271106554595739922987 Inexact Rounded
+comx3466 compare 4.51117459466491451401835756593793 3873385.19981811640063144338087230 -> -1
+divx3466 divide 4.51117459466491451401835756593793 3873385.19981811640063144338087230 -> 0.00000116465942888322776753062580106351 Inexact Rounded
+dvix3466 divideint 4.51117459466491451401835756593793 3873385.19981811640063144338087230 -> 0
+mulx3466 multiply 4.51117459466491451401835756593793 3873385.19981811640063144338087230 -> 17473516.9087705701652062546164705 Inexact Rounded
+powx3466 power 4.51117459466491451401835756593793 3873385 -> Infinity Overflow Inexact Rounded
+remx3466 remainder 4.51117459466491451401835756593793 3873385.19981811640063144338087230 -> 4.51117459466491451401835756593793
+subx3466 subtract 4.51117459466491451401835756593793 3873385.19981811640063144338087230 -> -3873380.68864352173571692936251473 Inexact Rounded
+addx3467 add 49553763474698.8118661758811091120 36.1713861293896216593840817950781E+410 -> 3.61713861293896216593840817950781E+411 Inexact Rounded
+comx3467 compare 49553763474698.8118661758811091120 36.1713861293896216593840817950781E+410 -> -1
+divx3467 divide 49553763474698.8118661758811091120 36.1713861293896216593840817950781E+410 -> 1.36997137177543416190811827685231E-398 Inexact Rounded
+dvix3467 divideint 49553763474698.8118661758811091120 36.1713861293896216593840817950781E+410 -> 0
+mulx3467 multiply 49553763474698.8118661758811091120 36.1713861293896216593840817950781E+410 -> 1.79242831280777466554271332425735E+425 Inexact Rounded
+powx3467 power 49553763474698.8118661758811091120 4 -> 6.02985091099730236635954801474802E+54 Inexact Rounded
+remx3467 remainder 49553763474698.8118661758811091120 36.1713861293896216593840817950781E+410 -> 49553763474698.8118661758811091120
+subx3467 subtract 49553763474698.8118661758811091120 36.1713861293896216593840817950781E+410 -> -3.61713861293896216593840817950781E+411 Inexact Rounded
+addx3468 add 755985583344.379951506071499170749E+956 746921095569971477373643487285780 -> 7.55985583344379951506071499170749E+967 Inexact Rounded
+comx3468 compare 755985583344.379951506071499170749E+956 746921095569971477373643487285780 -> 1
+divx3468 divide 755985583344.379951506071499170749E+956 746921095569971477373643487285780 -> 1.01213580367212873025671916758669E+935 Inexact Rounded
+dvix3468 divideint 755985583344.379951506071499170749E+956 746921095569971477373643487285780 -> NaN Division_impossible
+mulx3468 multiply 755985583344.379951506071499170749E+956 746921095569971477373643487285780 -> 5.64661580146688255286933753616580E+1000 Inexact Rounded
+powx3468 power 755985583344.379951506071499170749E+956 7 -> 1.41121958516547725677142981375469E+6775 Inexact Rounded
+remx3468 remainder 755985583344.379951506071499170749E+956 746921095569971477373643487285780 -> NaN Division_impossible
+subx3468 subtract 755985583344.379951506071499170749E+956 746921095569971477373643487285780 -> 7.55985583344379951506071499170749E+967 Inexact Rounded
+addx3469 add -20101668541.7472260497594230105456 -395562148.345003931161532101109964 -> -20497230690.0922299809209551116556 Inexact Rounded
+comx3469 compare -20101668541.7472260497594230105456 -395562148.345003931161532101109964 -> -1
+divx3469 divide -20101668541.7472260497594230105456 -395562148.345003931161532101109964 -> 50.8179779735012053661447873666816 Inexact Rounded
+dvix3469 divideint -20101668541.7472260497594230105456 -395562148.345003931161532101109964 -> 50
+mulx3469 multiply -20101668541.7472260497594230105456 -395562148.345003931161532101109964 -> 7951459193692715079.09328760016914 Inexact Rounded
+powx3469 power -20101668541.7472260497594230105456 -395562148 -> 0E-10031 Underflow Subnormal Inexact Rounded Clamped
+remx3469 remainder -20101668541.7472260497594230105456 -395562148.345003931161532101109964 -> -323561124.497029491682817955047400
+subx3469 subtract -20101668541.7472260497594230105456 -395562148.345003931161532101109964 -> -19706106393.4022221185978909094356 Inexact Rounded
+addx3470 add 5583903.18072100716072011264668631 460868914694.088387067451312500723 -> 460874498597.269108074612032613370 Inexact Rounded
+comx3470 compare 5583903.18072100716072011264668631 460868914694.088387067451312500723 -> -1
+divx3470 divide 5583903.18072100716072011264668631 460868914694.088387067451312500723 -> 0.0000121160334374633240168068405467307 Inexact Rounded
+dvix3470 divideint 5583903.18072100716072011264668631 460868914694.088387067451312500723 -> 0
+mulx3470 multiply 5583903.18072100716072011264668631 460868914694.088387067451312500723 -> 2573447398655758659.39475672905225 Inexact Rounded
+powx3470 power 5583903.18072100716072011264668631 5 -> 5.42861943589418603298670454702901E+33 Inexact Rounded
+remx3470 remainder 5583903.18072100716072011264668631 460868914694.088387067451312500723 -> 5583903.18072100716072011264668631
+subx3470 subtract 5583903.18072100716072011264668631 460868914694.088387067451312500723 -> -460863330790.907666060290592388076 Inexact Rounded
+addx3471 add -955638397975240685017992436116257E+020 -508580.148958769104511751975720470E+662 -> -5.08580148958769104511751975720470E+667 Inexact Rounded
+comx3471 compare -955638397975240685017992436116257E+020 -508580.148958769104511751975720470E+662 -> 1
+divx3471 divide -955638397975240685017992436116257E+020 -508580.148958769104511751975720470E+662 -> 1.87903204624039476408191264564568E-615 Inexact Rounded
+dvix3471 divideint -955638397975240685017992436116257E+020 -508580.148958769104511751975720470E+662 -> 0
+mulx3471 multiply -955638397975240685017992436116257E+020 -508580.148958769104511751975720470E+662 -> 4.86018718792967378985838739820108E+720 Inexact Rounded
+powx3471 power -955638397975240685017992436116257E+020 -5 -> -1.25467730420304189161768408462414E-265 Inexact Rounded
+remx3471 remainder -955638397975240685017992436116257E+020 -508580.148958769104511751975720470E+662 -> -9.55638397975240685017992436116257E+52
+subx3471 subtract -955638397975240685017992436116257E+020 -508580.148958769104511751975720470E+662 -> 5.08580148958769104511751975720470E+667 Inexact Rounded
+addx3472 add -136243796098020983814115584402407E+796 6589108083.99750311651581032447390 -> -1.36243796098020983814115584402407E+828 Inexact Rounded
+comx3472 compare -136243796098020983814115584402407E+796 6589108083.99750311651581032447390 -> -1
+divx3472 divide -136243796098020983814115584402407E+796 6589108083.99750311651581032447390 -> -2.06771226638255600634939371365920E+818 Inexact Rounded
+dvix3472 divideint -136243796098020983814115584402407E+796 6589108083.99750311651581032447390 -> NaN Division_impossible
+mulx3472 multiply -136243796098020983814115584402407E+796 6589108083.99750311651581032447390 -> -8.97725098263977535966921696143011E+837 Inexact Rounded
+powx3472 power -136243796098020983814115584402407E+796 7 -> -8.71399185551742199752832286984005E+5796 Inexact Rounded
+remx3472 remainder -136243796098020983814115584402407E+796 6589108083.99750311651581032447390 -> NaN Division_impossible
+subx3472 subtract -136243796098020983814115584402407E+796 6589108083.99750311651581032447390 -> -1.36243796098020983814115584402407E+828 Inexact Rounded
+addx3473 add -808498.482718304598213092937543934E+521 48005.1465097914355096301483788905 -> -8.08498482718304598213092937543934E+526 Inexact Rounded
+comx3473 compare -808498.482718304598213092937543934E+521 48005.1465097914355096301483788905 -> -1
+divx3473 divide -808498.482718304598213092937543934E+521 48005.1465097914355096301483788905 -> -1.68419126177106468565397017107736E+522 Inexact Rounded
+dvix3473 divideint -808498.482718304598213092937543934E+521 48005.1465097914355096301483788905 -> NaN Division_impossible
+mulx3473 multiply -808498.482718304598213092937543934E+521 48005.1465097914355096301483788905 -> -3.88120881158362912220132691803539E+531 Inexact Rounded
+powx3473 power -808498.482718304598213092937543934E+521 48005 -> -Infinity Overflow Inexact Rounded
+remx3473 remainder -808498.482718304598213092937543934E+521 48005.1465097914355096301483788905 -> NaN Division_impossible
+subx3473 subtract -808498.482718304598213092937543934E+521 48005.1465097914355096301483788905 -> -8.08498482718304598213092937543934E+526 Inexact Rounded
+addx3474 add -812.266340554281305985524813074211E+396 -3195.63111559114001594257448970812E+986 -> -3.19563111559114001594257448970812E+989 Inexact Rounded
+comx3474 compare -812.266340554281305985524813074211E+396 -3195.63111559114001594257448970812E+986 -> 1
+divx3474 divide -812.266340554281305985524813074211E+396 -3195.63111559114001594257448970812E+986 -> 2.54180257724779721448484781056040E-591 Inexact Rounded
+dvix3474 divideint -812.266340554281305985524813074211E+396 -3195.63111559114001594257448970812E+986 -> 0
+mulx3474 multiply -812.266340554281305985524813074211E+396 -3195.63111559114001594257448970812E+986 -> 2.59570359202261082537505332325404E+1388 Inexact Rounded
+powx3474 power -812.266340554281305985524813074211E+396 -3 -> -1.86596988030914616216741808216469E-1197 Inexact Rounded
+remx3474 remainder -812.266340554281305985524813074211E+396 -3195.63111559114001594257448970812E+986 -> -8.12266340554281305985524813074211E+398
+subx3474 subtract -812.266340554281305985524813074211E+396 -3195.63111559114001594257448970812E+986 -> 3.19563111559114001594257448970812E+989 Inexact Rounded
+addx3475 add -929889.720905183397678866648217793E+134 -280300190774.057595671079264841349 -> -9.29889720905183397678866648217793E+139 Inexact Rounded
+comx3475 compare -929889.720905183397678866648217793E+134 -280300190774.057595671079264841349 -> -1
+divx3475 divide -929889.720905183397678866648217793E+134 -280300190774.057595671079264841349 -> 3.31747801646964399331556971055197E+128 Inexact Rounded
+dvix3475 divideint -929889.720905183397678866648217793E+134 -280300190774.057595671079264841349 -> NaN Division_impossible
+mulx3475 multiply -929889.720905183397678866648217793E+134 -280300190774.057595671079264841349 -> 2.60648266168558079957349074609920E+151 Inexact Rounded
+powx3475 power -929889.720905183397678866648217793E+134 -3 -> -1.24367143370300189518778505830181E-420 Inexact Rounded
+remx3475 remainder -929889.720905183397678866648217793E+134 -280300190774.057595671079264841349 -> NaN Division_impossible
+subx3475 subtract -929889.720905183397678866648217793E+134 -280300190774.057595671079264841349 -> -9.29889720905183397678866648217793E+139 Inexact Rounded
+addx3476 add 83946.0157801953636255078996185540 492670373.235391665758701500314473 -> 492754319.251171861122327008214092 Inexact Rounded
+comx3476 compare 83946.0157801953636255078996185540 492670373.235391665758701500314473 -> -1
+divx3476 divide 83946.0157801953636255078996185540 492670373.235391665758701500314473 -> 0.000170389819117633485695890041185782 Inexact Rounded
+dvix3476 divideint 83946.0157801953636255078996185540 492670373.235391665758701500314473 -> 0
+mulx3476 multiply 83946.0157801953636255078996185540 492670373.235391665758701500314473 -> 41357714926052.9282985560380064649 Inexact Rounded
+powx3476 power 83946.0157801953636255078996185540 492670373 -> Infinity Overflow Inexact Rounded
+remx3476 remainder 83946.0157801953636255078996185540 492670373.235391665758701500314473 -> 83946.0157801953636255078996185540
+subx3476 subtract 83946.0157801953636255078996185540 492670373.235391665758701500314473 -> -492586427.219611470395075992414854 Inexact Rounded
+addx3477 add 7812758113817.99135851825223122508 3037492.36716301443309571918002123E-157 -> 7812758113817.99135851825223122508 Inexact Rounded
+comx3477 compare 7812758113817.99135851825223122508 3037492.36716301443309571918002123E-157 -> 1
+divx3477 divide 7812758113817.99135851825223122508 3037492.36716301443309571918002123E-157 -> 2.57210790001590171809512871857381E+163 Inexact Rounded
+dvix3477 divideint 7812758113817.99135851825223122508 3037492.36716301443309571918002123E-157 -> NaN Division_impossible
+mulx3477 multiply 7812758113817.99135851825223122508 3037492.36716301443309571918002123E-157 -> 2.37311931372130583136091717093935E-138 Inexact Rounded
+powx3477 power 7812758113817.99135851825223122508 3 -> 4.76884421816246896090414314934253E+38 Inexact Rounded
+remx3477 remainder 7812758113817.99135851825223122508 3037492.36716301443309571918002123E-157 -> NaN Division_impossible
+subx3477 subtract 7812758113817.99135851825223122508 3037492.36716301443309571918002123E-157 -> 7812758113817.99135851825223122508 Inexact Rounded
+addx3478 add 489191747.148674326757767356626016 01136942.1182277580093027768490545 -> 490328689.266902084767070133475071 Inexact Rounded
+comx3478 compare 489191747.148674326757767356626016 01136942.1182277580093027768490545 -> 1
+divx3478 divide 489191747.148674326757767356626016 01136942.1182277580093027768490545 -> 430.269702657525223124148258641358 Inexact Rounded
+dvix3478 divideint 489191747.148674326757767356626016 01136942.1182277580093027768490545 -> 430
+mulx3478 multiply 489191747.148674326757767356626016 01136942.1182277580093027768490545 -> 556182701222751.588454129518830550 Inexact Rounded
+powx3478 power 489191747.148674326757767356626016 1136942 -> Infinity Overflow Inexact Rounded
+remx3478 remainder 489191747.148674326757767356626016 01136942.1182277580093027768490545 -> 306636.3107383827575733115325810
+subx3478 subtract 489191747.148674326757767356626016 01136942.1182277580093027768490545 -> 488054805.030446568748464579776962 Inexact Rounded
+addx3479 add -599369540.373174482335865567937853E+289 -38288383205.6749439588707955585209 -> -5.99369540373174482335865567937853E+297 Inexact Rounded
+comx3479 compare -599369540.373174482335865567937853E+289 -38288383205.6749439588707955585209 -> -1
+divx3479 divide -599369540.373174482335865567937853E+289 -38288383205.6749439588707955585209 -> 1.56540833065089684132688143737586E+287 Inexact Rounded
+dvix3479 divideint -599369540.373174482335865567937853E+289 -38288383205.6749439588707955585209 -> NaN Division_impossible
+mulx3479 multiply -599369540.373174482335865567937853E+289 -38288383205.6749439588707955585209 -> 2.29488906436173641324091638963715E+308 Inexact Rounded
+powx3479 power -599369540.373174482335865567937853E+289 -4 -> 7.74856580646291366270329165540958E-1192 Inexact Rounded
+remx3479 remainder -599369540.373174482335865567937853E+289 -38288383205.6749439588707955585209 -> NaN Division_impossible
+subx3479 subtract -599369540.373174482335865567937853E+289 -38288383205.6749439588707955585209 -> -5.99369540373174482335865567937853E+297 Inexact Rounded
+addx3480 add -3376883870.85961692148022521960139 -65247489449.7334589731171980408284 -> -68624373320.5930758945974232604298 Inexact Rounded
+comx3480 compare -3376883870.85961692148022521960139 -65247489449.7334589731171980408284 -> 1
+divx3480 divide -3376883870.85961692148022521960139 -65247489449.7334589731171980408284 -> 0.0517550008335747813596332404664731 Inexact Rounded
+dvix3480 divideint -3376883870.85961692148022521960139 -65247489449.7334589731171980408284 -> 0
+mulx3480 multiply -3376883870.85961692148022521960139 -65247489449.7334589731171980408284 -> 220333194736887939420.719579906257 Inexact Rounded
+powx3480 power -3376883870.85961692148022521960139 -7 -> -1.99704163718361153125735756179280E-67 Inexact Rounded
+remx3480 remainder -3376883870.85961692148022521960139 -65247489449.7334589731171980408284 -> -3376883870.85961692148022521960139
+subx3480 subtract -3376883870.85961692148022521960139 -65247489449.7334589731171980408284 -> 61870605578.8738420516369728212270 Inexact Rounded
+addx3481 add 58.6776780370008364590621772421025 01.5925518866529044494309229975160 -> 60.2702299236537409084931002396185
+comx3481 compare 58.6776780370008364590621772421025 01.5925518866529044494309229975160 -> 1
+divx3481 divide 58.6776780370008364590621772421025 01.5925518866529044494309229975160 -> 36.8450651616286048437498576613622 Inexact Rounded
+dvix3481 divideint 58.6776780370008364590621772421025 01.5925518866529044494309229975160 -> 36
+mulx3481 multiply 58.6776780370008364590621772421025 01.5925518866529044494309229975160 -> 93.4472468622373769590900258060029 Inexact Rounded
+powx3481 power 58.6776780370008364590621772421025 2 -> 3443.06989981393033632008313505230 Inexact Rounded
+remx3481 remainder 58.6776780370008364590621772421025 01.5925518866529044494309229975160 -> 1.3458101174962762795489493315265
+subx3481 subtract 58.6776780370008364590621772421025 01.5925518866529044494309229975160 -> 57.0851261503479320096312542445865
+addx3482 add 4099616339.96249499552808575717579 290.795187361072489816791525139895 -> 4099616630.75768235660057557396732 Inexact Rounded
+comx3482 compare 4099616339.96249499552808575717579 290.795187361072489816791525139895 -> 1
+divx3482 divide 4099616339.96249499552808575717579 290.795187361072489816791525139895 -> 14097951.1289920788134209002390834 Inexact Rounded
+dvix3482 divideint 4099616339.96249499552808575717579 290.795187361072489816791525139895 -> 14097951
+mulx3482 multiply 4099616339.96249499552808575717579 290.795187361072489816791525139895 -> 1192148701687.90798437501397900174 Inexact Rounded
+powx3482 power 4099616339.96249499552808575717579 291 -> 2.03364757877800497409765979877258E+2797 Inexact Rounded
+remx3482 remainder 4099616339.96249499552808575717579 290.795187361072489816791525139895 -> 37.510275726642959858538282144855
+subx3482 subtract 4099616339.96249499552808575717579 290.795187361072489816791525139895 -> 4099616049.16730763445559594038426 Inexact Rounded
+addx3483 add 85870777.2282833141709970713739108 -2140392861153.69401346398478113715 -> -2140306990376.46573014981378406578 Inexact Rounded
+comx3483 compare 85870777.2282833141709970713739108 -2140392861153.69401346398478113715 -> 1
+divx3483 divide 85870777.2282833141709970713739108 -2140392861153.69401346398478113715 -> -0.0000401191663393971853092748263233128 Inexact Rounded
+dvix3483 divideint 85870777.2282833141709970713739108 -2140392861153.69401346398478113715 -> -0
+mulx3483 multiply 85870777.2282833141709970713739108 -2140392861153.69401346398478113715 -> -183797198561136797328.508878254848 Inexact Rounded
+powx3483 power 85870777.2282833141709970713739108 -2 -> 1.35615463448707573424578785973269E-16 Inexact Rounded
+remx3483 remainder 85870777.2282833141709970713739108 -2140392861153.69401346398478113715 -> 85870777.2282833141709970713739108
+subx3483 subtract 85870777.2282833141709970713739108 -2140392861153.69401346398478113715 -> 2140478731930.92229677815577820852 Inexact Rounded
+addx3484 add 20900.9693761555165742010339929779 -38.7546147649523793463260940289585 -> 20862.2147613905641948547078989489 Inexact Rounded
+comx3484 compare 20900.9693761555165742010339929779 -38.7546147649523793463260940289585 -> 1
+divx3484 divide 20900.9693761555165742010339929779 -38.7546147649523793463260940289585 -> -539.315627388386430188627412639767 Inexact Rounded
+dvix3484 divideint 20900.9693761555165742010339929779 -38.7546147649523793463260940289585 -> -539
+mulx3484 multiply 20900.9693761555165742010339929779 -38.7546147649523793463260940289585 -> -810009.016386974103738622793670566 Inexact Rounded
+powx3484 power 20900.9693761555165742010339929779 -39 -> 3.26219014701526335296044439989665E-169 Inexact Rounded
+remx3484 remainder 20900.9693761555165742010339929779 -38.7546147649523793463260940289585 -> 12.2320178461841065312693113692685
+subx3484 subtract 20900.9693761555165742010339929779 -38.7546147649523793463260940289585 -> 20939.7239909204689535473600870069 Inexact Rounded
+addx3485 add 448.827596155587910947511170319456 379130153.382794042652974596286062 -> 379130602.210390198240885543797232 Inexact Rounded
+comx3485 compare 448.827596155587910947511170319456 379130153.382794042652974596286062 -> -1
+divx3485 divide 448.827596155587910947511170319456 379130153.382794042652974596286062 -> 0.00000118383513458615061394140895596979 Inexact Rounded
+dvix3485 divideint 448.827596155587910947511170319456 379130153.382794042652974596286062 -> 0
+mulx3485 multiply 448.827596155587910947511170319456 379130153.382794042652974596286062 -> 170164075372.898786469094460692097 Inexact Rounded
+powx3485 power 448.827596155587910947511170319456 379130153 -> Infinity Overflow Inexact Rounded
+remx3485 remainder 448.827596155587910947511170319456 379130153.382794042652974596286062 -> 448.827596155587910947511170319456
+subx3485 subtract 448.827596155587910947511170319456 379130153.382794042652974596286062 -> -379129704.555197887065063648774892 Inexact Rounded
+addx3486 add 98.4134807921002817357000140482039 3404725543.77032945444654351546779 -> 3404725642.18381024654682525116780 Inexact Rounded
+comx3486 compare 98.4134807921002817357000140482039 3404725543.77032945444654351546779 -> -1
+divx3486 divide 98.4134807921002817357000140482039 3404725543.77032945444654351546779 -> 2.89049673833970863420201979291523E-8 Inexact Rounded
+dvix3486 divideint 98.4134807921002817357000140482039 3404725543.77032945444654351546779 -> 0
+mulx3486 multiply 98.4134807921002817357000140482039 3404725543.77032945444654351546779 -> 335070891904.214504811798212040413 Inexact Rounded
+powx3486 power 98.4134807921002817357000140482039 3 -> 953155.543384739667965055839894682 Inexact Rounded
+remx3486 remainder 98.4134807921002817357000140482039 3404725543.77032945444654351546779 -> 98.4134807921002817357000140482039
+subx3486 subtract 98.4134807921002817357000140482039 3404725543.77032945444654351546779 -> -3404725445.35684866234626177976778 Inexact Rounded
+addx3487 add 545746433.649359734136476718176330E-787 -5149957099709.12830072802043560650E-437 -> -5.14995709970912830072802043560650E-425 Inexact Rounded
+comx3487 compare 545746433.649359734136476718176330E-787 -5149957099709.12830072802043560650E-437 -> 1
+divx3487 divide 545746433.649359734136476718176330E-787 -5149957099709.12830072802043560650E-437 -> -1.05971064046375011086850722752614E-354 Inexact Rounded
+dvix3487 divideint 545746433.649359734136476718176330E-787 -5149957099709.12830072802043560650E-437 -> -0
+mulx3487 multiply 545746433.649359734136476718176330E-787 -5149957099709.12830072802043560650E-437 -> -2.81057072061345688074304873033317E-1203 Inexact Rounded
+powx3487 power 545746433.649359734136476718176330E-787 -5 -> 2.06559640092667166976186801348662E+3891 Inexact Rounded
+remx3487 remainder 545746433.649359734136476718176330E-787 -5149957099709.12830072802043560650E-437 -> 5.45746433649359734136476718176330E-779
+subx3487 subtract 545746433.649359734136476718176330E-787 -5149957099709.12830072802043560650E-437 -> 5.14995709970912830072802043560650E-425 Inexact Rounded
+addx3488 add 741304513547.273820525801608231737 0396.22823128272584928019323186355E-830 -> 741304513547.273820525801608231737 Inexact Rounded
+comx3488 compare 741304513547.273820525801608231737 0396.22823128272584928019323186355E-830 -> 1
+divx3488 divide 741304513547.273820525801608231737 0396.22823128272584928019323186355E-830 -> 1.87090281565101612623398174727653E+839 Inexact Rounded
+dvix3488 divideint 741304513547.273820525801608231737 0396.22823128272584928019323186355E-830 -> NaN Division_impossible
+mulx3488 multiply 741304513547.273820525801608231737 0396.22823128272584928019323186355E-830 -> 2.93725776244737788947443361076095E-816 Inexact Rounded
+powx3488 power 741304513547.273820525801608231737 4 -> 3.01985838652892073903194846668712E+47 Inexact Rounded
+remx3488 remainder 741304513547.273820525801608231737 0396.22823128272584928019323186355E-830 -> NaN Division_impossible
+subx3488 subtract 741304513547.273820525801608231737 0396.22823128272584928019323186355E-830 -> 741304513547.273820525801608231737 Inexact Rounded
+addx3489 add -706.145005094292315613907254240553 4739.82486195739758308735946332234 -> 4033.67985686310526747345220908179 Inexact Rounded
+comx3489 compare -706.145005094292315613907254240553 4739.82486195739758308735946332234 -> -1
+divx3489 divide -706.145005094292315613907254240553 4739.82486195739758308735946332234 -> -0.148981244172527671907534117771626 Inexact Rounded
+dvix3489 divideint -706.145005094292315613907254240553 4739.82486195739758308735946332234 -> -0
+mulx3489 multiply -706.145005094292315613907254240553 4739.82486195739758308735946332234 -> -3347003.65129295988793454267973464 Inexact Rounded
+powx3489 power -706.145005094292315613907254240553 4740 -> Infinity Overflow Inexact Rounded
+remx3489 remainder -706.145005094292315613907254240553 4739.82486195739758308735946332234 -> -706.145005094292315613907254240553
+subx3489 subtract -706.145005094292315613907254240553 4739.82486195739758308735946332234 -> -5445.96986705168989870126671756289 Inexact Rounded
+addx3490 add -769925786.823099083228795187975893 -31201.9980469760239870067820594790 -> -769956988.821146059252782194757952 Inexact Rounded
+comx3490 compare -769925786.823099083228795187975893 -31201.9980469760239870067820594790 -> -1
+divx3490 divide -769925786.823099083228795187975893 -31201.9980469760239870067820594790 -> 24675.5283319978698932292028650803 Inexact Rounded
+dvix3490 divideint -769925786.823099083228795187975893 -31201.9980469760239870067820594790 -> 24675
+mulx3490 multiply -769925786.823099083228795187975893 -31201.9980469760239870067820594790 -> 24023222896770.8161787236737395477 Inexact Rounded
+powx3490 power -769925786.823099083228795187975893 -31202 -> 0E-10031 Underflow Subnormal Inexact Rounded Clamped
+remx3490 remainder -769925786.823099083228795187975893 -31201.9980469760239870067820594790 -> -16485.0139656913494028406582486750
+subx3490 subtract -769925786.823099083228795187975893 -31201.9980469760239870067820594790 -> -769894584.825052107204808181193834 Inexact Rounded
+addx3491 add 84438610546049.7256507419289692857E+906 052604240766736461898844111790311 -> 8.44386105460497256507419289692857E+919 Inexact Rounded
+comx3491 compare 84438610546049.7256507419289692857E+906 052604240766736461898844111790311 -> 1
+divx3491 divide 84438610546049.7256507419289692857E+906 052604240766736461898844111790311 -> 1.60516736512701978695559003341922E+888 Inexact Rounded
+dvix3491 divideint 84438610546049.7256507419289692857E+906 052604240766736461898844111790311 -> NaN Division_impossible
+mulx3491 multiply 84438610546049.7256507419289692857E+906 052604240766736461898844111790311 -> 4.44182899917309231779837668210610E+951 Inexact Rounded
+powx3491 power 84438610546049.7256507419289692857E+906 5 -> 4.29245144719689283247342866988213E+4599 Inexact Rounded
+remx3491 remainder 84438610546049.7256507419289692857E+906 052604240766736461898844111790311 -> NaN Division_impossible
+subx3491 subtract 84438610546049.7256507419289692857E+906 052604240766736461898844111790311 -> 8.44386105460497256507419289692857E+919 Inexact Rounded
+addx3492 add 549760.911304725795164589619286514 165.160089615604924207754883953484 -> 549926.071394341400088797374170467 Inexact Rounded
+comx3492 compare 549760.911304725795164589619286514 165.160089615604924207754883953484 -> 1
+divx3492 divide 549760.911304725795164589619286514 165.160089615604924207754883953484 -> 3328.65471667062107598395714348089 Inexact Rounded
+dvix3492 divideint 549760.911304725795164589619286514 165.160089615604924207754883953484 -> 3328
+mulx3492 multiply 549760.911304725795164589619286514 165.160089615604924207754883953484 -> 90798561.3782451425861113694732484 Inexact Rounded
+powx3492 power 549760.911304725795164589619286514 165 -> 1.34488925442386544028875603347654E+947 Inexact Rounded
+remx3492 remainder 549760.911304725795164589619286514 165.160089615604924207754883953484 -> 108.133063992607401181365489319248
+subx3492 subtract 549760.911304725795164589619286514 165.160089615604924207754883953484 -> 549595.751215110190240381864402561 Inexact Rounded
+addx3493 add 3650514.18649737956855828939662794 08086721.4036886948248274834735629 -> 11737235.5901860743933857728701908 Inexact Rounded
+comx3493 compare 3650514.18649737956855828939662794 08086721.4036886948248274834735629 -> -1
+divx3493 divide 3650514.18649737956855828939662794 08086721.4036886948248274834735629 -> 0.451420792712387250865423208234291 Inexact Rounded
+dvix3493 divideint 3650514.18649737956855828939662794 08086721.4036886948248274834735629 -> 0
+mulx3493 multiply 3650514.18649737956855828939662794 08086721.4036886948248274834735629 -> 29520691206417.5831886752808745421 Inexact Rounded
+powx3493 power 3650514.18649737956855828939662794 8086721 -> Infinity Overflow Inexact Rounded
+remx3493 remainder 3650514.18649737956855828939662794 08086721.4036886948248274834735629 -> 3650514.18649737956855828939662794
+subx3493 subtract 3650514.18649737956855828939662794 08086721.4036886948248274834735629 -> -4436207.21719131525626919407693496
+addx3494 add 55067723881950.1346958179604099594 -8.90481481687182931431054785192083 -> 55067723881941.2298810010885806451 Inexact Rounded
+comx3494 compare 55067723881950.1346958179604099594 -8.90481481687182931431054785192083 -> 1
+divx3494 divide 55067723881950.1346958179604099594 -8.90481481687182931431054785192083 -> -6184039198391.19853088419484117054 Inexact Rounded
+dvix3494 divideint 55067723881950.1346958179604099594 -8.90481481687182931431054785192083 -> -6184039198391
+mulx3494 multiply 55067723881950.1346958179604099594 -8.90481481687182931431054785192083 -> -490367883555396.250365158593373279 Inexact Rounded
+powx3494 power 55067723881950.1346958179604099594 -9 -> 2.14746386538529270173788457887121E-124 Inexact Rounded
+remx3494 remainder 55067723881950.1346958179604099594 -8.90481481687182931431054785192083 -> 1.76788075918488693086347720461547
+subx3494 subtract 55067723881950.1346958179604099594 -8.90481481687182931431054785192083 -> 55067723881959.0395106348322392737 Inexact Rounded
+addx3495 add 868251123.413992653362860637541060E+019 5579665045.37858308541154858567656E+131 -> 5.57966504537858308541154858567656E+140 Inexact Rounded
+comx3495 compare 868251123.413992653362860637541060E+019 5579665045.37858308541154858567656E+131 -> -1
+divx3495 divide 868251123.413992653362860637541060E+019 5579665045.37858308541154858567656E+131 -> 1.55609900657590706155251902725027E-113 Inexact Rounded
+dvix3495 divideint 868251123.413992653362860637541060E+019 5579665045.37858308541154858567656E+131 -> 0
+mulx3495 multiply 868251123.413992653362860637541060E+019 5579665045.37858308541154858567656E+131 -> 4.84455044392374106106966779322483E+168 Inexact Rounded
+powx3495 power 868251123.413992653362860637541060E+019 6 -> 4.28422354304291884802690733853227E+167 Inexact Rounded
+remx3495 remainder 868251123.413992653362860637541060E+019 5579665045.37858308541154858567656E+131 -> 8682511234139926533628606375.41060
+subx3495 subtract 868251123.413992653362860637541060E+019 5579665045.37858308541154858567656E+131 -> -5.57966504537858308541154858567656E+140 Inexact Rounded
+addx3496 add -646.464431574014407536004990059069 -798.679560020414523841321724649594E-037 -> -646.464431574014407536004990059069 Inexact Rounded
+comx3496 compare -646.464431574014407536004990059069 -798.679560020414523841321724649594E-037 -> -1
+divx3496 divide -646.464431574014407536004990059069 -798.679560020414523841321724649594E-037 -> 8.09416521887063886613527228353543E+36 Inexact Rounded
+dvix3496 divideint -646.464431574014407536004990059069 -798.679560020414523841321724649594E-037 -> NaN Division_impossible
+mulx3496 multiply -646.464431574014407536004990059069 -798.679560020414523841321724649594E-037 -> 5.16317927778381197995451363439626E-32 Inexact Rounded
+powx3496 power -646.464431574014407536004990059069 -8 -> 3.27825641569860861774700548035691E-23 Inexact Rounded
+remx3496 remainder -646.464431574014407536004990059069 -798.679560020414523841321724649594E-037 -> NaN Division_impossible
+subx3496 subtract -646.464431574014407536004990059069 -798.679560020414523841321724649594E-037 -> -646.464431574014407536004990059069 Inexact Rounded
+addx3497 add 354.546679975219753598558273421556 -7039.46386812239015144581761752927E-448 -> 354.546679975219753598558273421556 Inexact Rounded
+comx3497 compare 354.546679975219753598558273421556 -7039.46386812239015144581761752927E-448 -> 1
+divx3497 divide 354.546679975219753598558273421556 -7039.46386812239015144581761752927E-448 -> -5.03655799102477192579414523352028E+446 Inexact Rounded
+dvix3497 divideint 354.546679975219753598558273421556 -7039.46386812239015144581761752927E-448 -> NaN Division_impossible
+mulx3497 multiply 354.546679975219753598558273421556 -7039.46386812239015144581761752927E-448 -> -2.49581854324831161267369292071408E-442 Inexact Rounded
+powx3497 power 354.546679975219753598558273421556 -7 -> 1.41999246365875617298270414304233E-18 Inexact Rounded
+remx3497 remainder 354.546679975219753598558273421556 -7039.46386812239015144581761752927E-448 -> NaN Division_impossible
+subx3497 subtract 354.546679975219753598558273421556 -7039.46386812239015144581761752927E-448 -> 354.546679975219753598558273421556 Inexact Rounded
+addx3498 add 91936087917435.5974889495278215874 -67080823344.8903392584327136082486E-757 -> 91936087917435.5974889495278215874 Inexact Rounded
+comx3498 compare 91936087917435.5974889495278215874 -67080823344.8903392584327136082486E-757 -> 1
+divx3498 divide 91936087917435.5974889495278215874 -67080823344.8903392584327136082486E-757 -> -1.37052712434303366569304688993783E+760 Inexact Rounded
+dvix3498 divideint 91936087917435.5974889495278215874 -67080823344.8903392584327136082486E-757 -> NaN Division_impossible
+mulx3498 multiply 91936087917435.5974889495278215874 -67080823344.8903392584327136082486E-757 -> -6.16714847260980448099292763939423E-733 Inexact Rounded
+powx3498 power 91936087917435.5974889495278215874 -7 -> 1.80134899939035708719659065082630E-98 Inexact Rounded
+remx3498 remainder 91936087917435.5974889495278215874 -67080823344.8903392584327136082486E-757 -> NaN Division_impossible
+subx3498 subtract 91936087917435.5974889495278215874 -67080823344.8903392584327136082486E-757 -> 91936087917435.5974889495278215874 Inexact Rounded
+addx3499 add -07345.6422518528556136521417259811E-600 41188325.7041362608934957584583381E-763 -> -7.34564225185285561365214172598110E-597 Inexact Rounded
+comx3499 compare -07345.6422518528556136521417259811E-600 41188325.7041362608934957584583381E-763 -> -1
+divx3499 divide -07345.6422518528556136521417259811E-600 41188325.7041362608934957584583381E-763 -> -1.78342822299163842247184303878022E+159 Inexact Rounded
+dvix3499 divideint -07345.6422518528556136521417259811E-600 41188325.7041362608934957584583381E-763 -> NaN Division_impossible
+mulx3499 multiply -07345.6422518528556136521417259811E-600 41188325.7041362608934957584583381E-763 -> -3.02554705575380338274126867655676E-1352 Inexact Rounded
+powx3499 power -07345.6422518528556136521417259811E-600 4 -> 2.91151541552217582082937236255996E-2385 Inexact Rounded
+remx3499 remainder -07345.6422518528556136521417259811E-600 41188325.7041362608934957584583381E-763 -> NaN Division_impossible
+subx3499 subtract -07345.6422518528556136521417259811E-600 41188325.7041362608934957584583381E-763 -> -7.34564225185285561365214172598110E-597 Inexact Rounded
+addx3500 add -253280724.939458021588167965038184 616988.426425908872398170896375634E+396 -> 6.16988426425908872398170896375634E+401 Inexact Rounded
+comx3500 compare -253280724.939458021588167965038184 616988.426425908872398170896375634E+396 -> -1
+divx3500 divide -253280724.939458021588167965038184 616988.426425908872398170896375634E+396 -> -4.10511306357337753351655511866170E-394 Inexact Rounded
+dvix3500 divideint -253280724.939458021588167965038184 616988.426425908872398170896375634E+396 -> -0
+mulx3500 multiply -253280724.939458021588167965038184 616988.426425908872398170896375634E+396 -> -1.56271275924409657991913620522315E+410 Inexact Rounded
+powx3500 power -253280724.939458021588167965038184 6 -> 2.64005420221406808782284459794424E+50 Inexact Rounded
+remx3500 remainder -253280724.939458021588167965038184 616988.426425908872398170896375634E+396 -> -253280724.939458021588167965038184
+subx3500 subtract -253280724.939458021588167965038184 616988.426425908872398170896375634E+396 -> -6.16988426425908872398170896375634E+401 Inexact Rounded

Added: vendor/Python/current/Lib/test/decimaltestdata/randoms.decTest
===================================================================
--- vendor/Python/current/Lib/test/decimaltestdata/randoms.decTest	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/decimaltestdata/randoms.decTest	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,4029 @@
+------------------------------------------------------------------------
+-- randoms.decTest -- decimal random testcases                        --
+-- Copyright (c) IBM Corporation, 1981, 2003.  All rights reserved.   --
+------------------------------------------------------------------------
+-- Please see the document "General Decimal Arithmetic Testcases"     --
+-- at http://www2.hursley.ibm.com/decimal for the description of      --
+-- these testcases.                                                   --
+--                                                                    --
+-- These testcases are experimental ('beta' versions), and they       --
+-- may contain errors.  They are offered on an as-is basis.  In       --
+-- particular, achieving the same results as the tests here is not    --
+-- a guarantee that an implementation complies with any Standard      --
+-- or specification.  The tests are not exhaustive.                   --
+--                                                                    --
+-- Please send comments, suggestions, and corrections to the author:  --
+--   Mike Cowlishaw, IBM Fellow                                       --
+--   IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK         --
+--   mfc at uk.ibm.com                                                   --
+------------------------------------------------------------------------
+version: 2.39
+
+extended:    1
+maxexponent: 999999999
+minexponent: -999999999
+precision:   9
+rounding:    half_up
+
+-- Randomly generated testcases [31 Dec 2000, with results defined for
+-- all cases [27 Oct 2001], and no trim/finish [9 Jun 2002]
+xadd001 add 905.67402 -202896611.E-780472620 -> 905.674020 Inexact Rounded
+xcom001 compare 905.67402 -202896611.E-780472620 -> 1
+xdiv001 divide 905.67402 -202896611.E-780472620 -> -4.46372177E+780472614 Inexact Rounded
+xdvi001 divideint 905.67402 -202896611.E-780472620 -> NaN Division_impossible
+xmul001 multiply 905.67402 -202896611.E-780472620 -> -1.83758189E-780472609 Inexact Rounded
+xpow001 power 905.67402 -2 -> 0.00000121914730 Inexact Rounded
+xrem001 remainder 905.67402 -202896611.E-780472620 -> NaN Division_impossible
+xsub001 subtract 905.67402 -202896611.E-780472620 -> 905.674020 Inexact Rounded
+xadd002 add 3915134.7 -597164907. -> -593249772 Inexact Rounded
+xcom002 compare 3915134.7 -597164907. -> 1
+xdiv002 divide 3915134.7 -597164907. -> -0.00655620358 Inexact Rounded
+xdvi002 divideint 3915134.7 -597164907. -> -0
+xmul002 multiply 3915134.7 -597164907. -> -2.33798105E+15 Inexact Rounded
+xpow002 power 3915134.7 -597164907 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem002 remainder 3915134.7 -597164907. -> 3915134.7
+xsub002 subtract 3915134.7 -597164907. -> 601080042 Inexact Rounded
+xadd003 add 309759261 62663.487 -> 309821924 Inexact Rounded
+xcom003 compare 309759261 62663.487 -> 1
+xdiv003 divide 309759261 62663.487 -> 4943.21775 Inexact Rounded
+xdvi003 divideint 309759261 62663.487 -> 4943
+xmul003 multiply 309759261 62663.487 -> 1.94105954E+13 Inexact Rounded
+xpow003 power 309759261 62663 -> 1.13679199E+532073 Inexact Rounded
+xrem003 remainder 309759261 62663.487 -> 13644.759
+xsub003 subtract 309759261 62663.487 -> 309696598 Inexact Rounded
+xadd004 add 3.93591888E-236595626 7242375.00 -> 7242375.00 Inexact Rounded
+xcom004 compare 3.93591888E-236595626 7242375.00 -> -1
+xdiv004 divide 3.93591888E-236595626 7242375.00 -> 5.43456930E-236595633 Inexact Rounded
+xdvi004 divideint 3.93591888E-236595626 7242375.00 -> 0
+xmul004 multiply 3.93591888E-236595626 7242375.00 -> 2.85054005E-236595619 Inexact Rounded
+xpow004 power 3.93591888E-236595626 7242375 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem004 remainder 3.93591888E-236595626 7242375.00 -> 3.93591888E-236595626
+xsub004 subtract 3.93591888E-236595626 7242375.00 -> -7242375.00 Inexact Rounded
+xadd005 add 323902.714 -608669.607E-657060568 -> 323902.714 Inexact Rounded
+xcom005 compare 323902.714 -608669.607E-657060568 -> 1
+xdiv005 divide 323902.714 -608669.607E-657060568 -> -5.32148657E+657060567 Inexact Rounded
+xdvi005 divideint 323902.714 -608669.607E-657060568 -> NaN Division_impossible
+xmul005 multiply 323902.714 -608669.607E-657060568 -> -1.97149738E-657060557 Inexact Rounded
+xpow005 power 323902.714 -6 -> 8.65989204E-34 Inexact Rounded
+xrem005 remainder 323902.714 -608669.607E-657060568 -> NaN Division_impossible
+xsub005 subtract 323902.714 -608669.607E-657060568 -> 323902.714 Inexact Rounded
+xadd006 add 5.11970092 -8807.22036 -> -8802.10066 Inexact Rounded
+xcom006 compare 5.11970092 -8807.22036 -> 1
+xdiv006 divide 5.11970092 -8807.22036 -> -0.000581307236 Inexact Rounded
+xdvi006 divideint 5.11970092 -8807.22036 -> -0
+xmul006 multiply 5.11970092 -8807.22036 -> -45090.3342 Inexact Rounded
+xpow006 power 5.11970092 -8807 -> 4.81819262E-6247 Inexact Rounded
+xrem006 remainder 5.11970092 -8807.22036 -> 5.11970092
+xsub006 subtract 5.11970092 -8807.22036 -> 8812.34006 Inexact Rounded
+xadd007 add -7.99874516 4561.83758 -> 4553.83883 Inexact Rounded
+xcom007 compare -7.99874516 4561.83758 -> -1
+xdiv007 divide -7.99874516 4561.83758 -> -0.00175340420 Inexact Rounded
+xdvi007 divideint -7.99874516 4561.83758 -> -0
+xmul007 multiply -7.99874516 4561.83758 -> -36488.9763 Inexact Rounded
+xpow007 power -7.99874516 4562 -> 3.85236199E+4119 Inexact Rounded
+xrem007 remainder -7.99874516 4561.83758 -> -7.99874516
+xsub007 subtract -7.99874516 4561.83758 -> -4569.83633 Inexact Rounded
+xadd008 add 297802878 -927206.324 -> 296875672 Inexact Rounded
+xcom008 compare 297802878 -927206.324 -> 1
+xdiv008 divide 297802878 -927206.324 -> -321.182967 Inexact Rounded
+xdvi008 divideint 297802878 -927206.324 -> -321
+xmul008 multiply 297802878 -927206.324 -> -2.76124712E+14 Inexact Rounded
+xpow008 power 297802878 -927206 -> 1.94602810E-7857078 Inexact Rounded
+xrem008 remainder 297802878 -927206.324 -> 169647.996
+xsub008 subtract 297802878 -927206.324 -> 298730084 Inexact Rounded
+xadd009 add -766.651824 31300.3619 -> 30533.7101 Inexact Rounded
+xcom009 compare -766.651824 31300.3619 -> -1
+xdiv009 divide -766.651824 31300.3619 -> -0.0244933853 Inexact Rounded
+xdvi009 divideint -766.651824 31300.3619 -> -0
+xmul009 multiply -766.651824 31300.3619 -> -23996479.5 Inexact Rounded
+xpow009 power -766.651824 31300 -> 8.37189011E+90287 Inexact Rounded
+xrem009 remainder -766.651824 31300.3619 -> -766.651824
+xsub009 subtract -766.651824 31300.3619 -> -32067.0137 Inexact Rounded
+xadd010 add -56746.8689E+934981942 471002521. -> -5.67468689E+934981946 Inexact Rounded
+xcom010 compare -56746.8689E+934981942 471002521. -> -1
+xdiv010 divide -56746.8689E+934981942 471002521. -> -1.20481030E+934981938 Inexact Rounded
+xdvi010 divideint -56746.8689E+934981942 471002521. -> NaN Division_impossible
+xmul010 multiply -56746.8689E+934981942 471002521. -> -2.67279183E+934981955 Inexact Rounded
+xpow010 power -56746.8689E+934981942 471002521 -> -Infinity Overflow Inexact Rounded
+xrem010 remainder -56746.8689E+934981942 471002521. -> NaN Division_impossible
+xsub010 subtract -56746.8689E+934981942 471002521. -> -5.67468689E+934981946 Inexact Rounded
+xadd011 add 456417160 -41346.1024 -> 456375814 Inexact Rounded
+xcom011 compare 456417160 -41346.1024 -> 1
+xdiv011 divide 456417160 -41346.1024 -> -11038.9404 Inexact Rounded
+xdvi011 divideint 456417160 -41346.1024 -> -11038
+xmul011 multiply 456417160 -41346.1024 -> -1.88710706E+13 Inexact Rounded
+xpow011 power 456417160 -41346 -> 1.04766863E-358030 Inexact Rounded
+xrem011 remainder 456417160 -41346.1024 -> 38881.7088
+xsub011 subtract 456417160 -41346.1024 -> 456458506 Inexact Rounded
+xadd012 add 102895.722 -2.62214826 -> 102893.100 Inexact Rounded
+xcom012 compare 102895.722 -2.62214826 -> 1
+xdiv012 divide 102895.722 -2.62214826 -> -39241.0008 Inexact Rounded
+xdvi012 divideint 102895.722 -2.62214826 -> -39241
+xmul012 multiply 102895.722 -2.62214826 -> -269807.838 Inexact Rounded
+xpow012 power 102895.722 -3 -> 9.17926786E-16 Inexact Rounded
+xrem012 remainder 102895.722 -2.62214826 -> 0.00212934
+xsub012 subtract 102895.722 -2.62214826 -> 102898.344 Inexact Rounded
+xadd013 add 61.3033331E+157644141 -567740.918E-893439456 -> 6.13033331E+157644142 Inexact Rounded
+xcom013 compare 61.3033331E+157644141 -567740.918E-893439456 -> 1
+xdiv013 divide 61.3033331E+157644141 -567740.918E-893439456 -> -Infinity Inexact Overflow Rounded
+xdvi013 divideint 61.3033331E+157644141 -567740.918E-893439456 -> NaN Division_impossible
+xmul013 multiply 61.3033331E+157644141 -567740.918E-893439456 -> -3.48044106E-735795308 Inexact Rounded
+xpow013 power 61.3033331E+157644141 -6 -> 1.88406322E-945864857 Inexact Rounded
+xrem013 remainder 61.3033331E+157644141 -567740.918E-893439456 -> NaN Division_impossible
+xsub013 subtract 61.3033331E+157644141 -567740.918E-893439456 -> 6.13033331E+157644142 Inexact Rounded
+xadd014 add 80223.3897 73921.0383E-467772675 -> 80223.3897 Inexact Rounded
+xcom014 compare 80223.3897 73921.0383E-467772675 -> 1
+xdiv014 divide 80223.3897 73921.0383E-467772675 -> 1.08525789E+467772675 Inexact Rounded
+xdvi014 divideint 80223.3897 73921.0383E-467772675 -> NaN Division_impossible
+xmul014 multiply 80223.3897 73921.0383E-467772675 -> 5.93019626E-467772666 Inexact Rounded
+xpow014 power 80223.3897 7 -> 2.13848919E+34 Inexact Rounded
+xrem014 remainder 80223.3897 73921.0383E-467772675 -> NaN Division_impossible
+xsub014 subtract 80223.3897 73921.0383E-467772675 -> 80223.3897 Inexact Rounded
+xadd015 add -654645.954 -9.12535752 -> -654655.079 Inexact Rounded
+xcom015 compare -654645.954 -9.12535752 -> -1
+xdiv015 divide -654645.954 -9.12535752 -> 71739.2116 Inexact Rounded
+xdvi015 divideint -654645.954 -9.12535752 -> 71739
+xmul015 multiply -654645.954 -9.12535752 -> 5973878.38 Inexact Rounded
+xpow015 power -654645.954 -9 -> -4.52836690E-53 Inexact Rounded
+xrem015 remainder -654645.954 -9.12535752 -> -1.93087272
+xsub015 subtract -654645.954 -9.12535752 -> -654636.829 Inexact Rounded
+xadd016 add 63.1917772E-706014634 -7.56253257E-138579234 -> -7.56253257E-138579234 Inexact Rounded
+xcom016 compare 63.1917772E-706014634 -7.56253257E-138579234 -> 1
+xdiv016 divide 63.1917772E-706014634 -7.56253257E-138579234 -> -8.35590149E-567435400 Inexact Rounded
+xdvi016 divideint 63.1917772E-706014634 -7.56253257E-138579234 -> -0
+xmul016 multiply 63.1917772E-706014634 -7.56253257E-138579234 -> -4.77889873E-844593866 Inexact Rounded
+xpow016 power 63.1917772E-706014634 -8 -> Infinity Overflow Inexact Rounded
+xrem016 remainder 63.1917772E-706014634 -7.56253257E-138579234 -> 6.31917772E-706014633
+xsub016 subtract 63.1917772E-706014634 -7.56253257E-138579234 -> 7.56253257E-138579234 Inexact Rounded
+xadd017 add -39674.7190 2490607.78 -> 2450933.06 Inexact Rounded
+xcom017 compare -39674.7190 2490607.78 -> -1
+xdiv017 divide -39674.7190 2490607.78 -> -0.0159297338 Inexact Rounded
+xdvi017 divideint -39674.7190 2490607.78 -> -0
+xmul017 multiply -39674.7190 2490607.78 -> -9.88141638E+10 Inexact Rounded
+xpow017 power -39674.7190 2490608 -> 2.55032329E+11453095 Inexact Rounded
+xrem017 remainder -39674.7190 2490607.78 -> -39674.7190
+xsub017 subtract -39674.7190 2490607.78 -> -2530282.50 Inexact Rounded
+xadd018 add -3364.59737E-600363681 896487.451 -> 896487.451 Inexact Rounded
+xcom018 compare -3364.59737E-600363681 896487.451 -> -1
+xdiv018 divide -3364.59737E-600363681 896487.451 -> -3.75308920E-600363684 Inexact Rounded
+xdvi018 divideint -3364.59737E-600363681 896487.451 -> -0
+xmul018 multiply -3364.59737E-600363681 896487.451 -> -3.01631932E-600363672 Inexact Rounded
+xpow018 power -3364.59737E-600363681 896487 -> -0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem018 remainder -3364.59737E-600363681 896487.451 -> -3.36459737E-600363678
+xsub018 subtract -3364.59737E-600363681 896487.451 -> -896487.451 Inexact Rounded
+xadd019 add -64138.0578 31759011.3E+697488342 -> 3.17590113E+697488349 Inexact Rounded
+xcom019 compare -64138.0578 31759011.3E+697488342 -> -1
+xdiv019 divide -64138.0578 31759011.3E+697488342 -> -2.01952313E-697488345 Inexact Rounded
+xdvi019 divideint -64138.0578 31759011.3E+697488342 -> -0
+xmul019 multiply -64138.0578 31759011.3E+697488342 -> -2.03696130E+697488354 Inexact Rounded
+xpow019 power -64138.0578 3 -> -2.63844116E+14 Inexact Rounded
+xrem019 remainder -64138.0578 31759011.3E+697488342 -> -64138.0578
+xsub019 subtract -64138.0578 31759011.3E+697488342 -> -3.17590113E+697488349 Inexact Rounded
+xadd020 add 61399.8527 -64344484.5 -> -64283084.6 Inexact Rounded
+xcom020 compare 61399.8527 -64344484.5 -> 1
+xdiv020 divide 61399.8527 -64344484.5 -> -0.000954236454 Inexact Rounded
+xdvi020 divideint 61399.8527 -64344484.5 -> -0
+xmul020 multiply 61399.8527 -64344484.5 -> -3.95074187E+12 Inexact Rounded
+xpow020 power 61399.8527 -64344485 -> 1.27378842E-308092161 Inexact Rounded
+xrem020 remainder 61399.8527 -64344484.5 -> 61399.8527
+xsub020 subtract 61399.8527 -64344484.5 -> 64405884.4 Inexact Rounded
+xadd021 add -722960.204 -26154599.8 -> -26877560.0 Inexact Rounded
+xcom021 compare -722960.204 -26154599.8 -> 1
+xdiv021 divide -722960.204 -26154599.8 -> 0.0276417995 Inexact Rounded
+xdvi021 divideint -722960.204 -26154599.8 -> 0
+xmul021 multiply -722960.204 -26154599.8 -> 1.89087348E+13 Inexact Rounded
+xpow021 power -722960.204 -26154600 -> 5.34236139E-153242794 Inexact Rounded
+xrem021 remainder -722960.204 -26154599.8 -> -722960.204
+xsub021 subtract -722960.204 -26154599.8 -> 25431639.6 Inexact Rounded
+xadd022 add 9.47109959E+230565093 73354723.2 -> 9.47109959E+230565093 Inexact Rounded
+xcom022 compare 9.47109959E+230565093 73354723.2 -> 1
+xdiv022 divide 9.47109959E+230565093 73354723.2 -> 1.29113698E+230565086 Inexact Rounded
+xdvi022 divideint 9.47109959E+230565093 73354723.2 -> NaN Division_impossible
+xmul022 multiply 9.47109959E+230565093 73354723.2 -> 6.94749889E+230565101 Inexact Rounded
+xpow022 power 9.47109959E+230565093 73354723 -> Infinity Overflow Inexact Rounded
+xrem022 remainder 9.47109959E+230565093 73354723.2 -> NaN Division_impossible
+xsub022 subtract 9.47109959E+230565093 73354723.2 -> 9.47109959E+230565093 Inexact Rounded
+xadd023 add 43.7456245 547441956. -> 547442000 Inexact Rounded
+xcom023 compare 43.7456245 547441956. -> -1
+xdiv023 divide 43.7456245 547441956. -> 7.99091557E-8 Inexact Rounded
+xdvi023 divideint 43.7456245 547441956. -> 0
+xmul023 multiply 43.7456245 547441956. -> 2.39481902E+10 Inexact Rounded
+xpow023 power 43.7456245 547441956 -> 2.91742391E+898316458 Inexact Rounded
+xrem023 remainder 43.7456245 547441956. -> 43.7456245
+xsub023 subtract 43.7456245 547441956. -> -547441912 Inexact Rounded
+xadd024 add -73150542E-242017390 -8.15869954 -> -8.15869954 Inexact Rounded
+xcom024 compare -73150542E-242017390 -8.15869954 -> 1
+xdiv024 divide -73150542E-242017390 -8.15869954 -> 8.96595611E-242017384 Inexact Rounded
+xdvi024 divideint -73150542E-242017390 -8.15869954 -> 0
+xmul024 multiply -73150542E-242017390 -8.15869954 -> 5.96813293E-242017382 Inexact Rounded
+xpow024 power -73150542E-242017390 -8 -> Infinity Overflow Inexact Rounded
+xrem024 remainder -73150542E-242017390 -8.15869954 -> -7.3150542E-242017383
+xsub024 subtract -73150542E-242017390 -8.15869954 -> 8.15869954 Inexact Rounded
+xadd025 add 2015.62109E+299897596 -11788916.1 -> 2.01562109E+299897599 Inexact Rounded
+xcom025 compare 2015.62109E+299897596 -11788916.1 -> 1
+xdiv025 divide 2015.62109E+299897596 -11788916.1 -> -1.70975947E+299897592 Inexact Rounded
+xdvi025 divideint 2015.62109E+299897596 -11788916.1 -> NaN Division_impossible
+xmul025 multiply 2015.62109E+299897596 -11788916.1 -> -2.37619879E+299897606 Inexact Rounded
+xpow025 power 2015.62109E+299897596 -11788916 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem025 remainder 2015.62109E+299897596 -11788916.1 -> NaN Division_impossible
+xsub025 subtract 2015.62109E+299897596 -11788916.1 -> 2.01562109E+299897599 Inexact Rounded
+xadd026 add 29.498114 -26486451 -> -26486421.5 Inexact Rounded
+xcom026 compare 29.498114 -26486451 -> 1
+xdiv026 divide 29.498114 -26486451 -> -0.00000111370580 Inexact Rounded
+xdvi026 divideint 29.498114 -26486451 -> -0
+xmul026 multiply 29.498114 -26486451 -> -781300351 Inexact Rounded
+xpow026 power 29.498114 -26486451 -> 4.22252513E-38929634 Inexact Rounded
+xrem026 remainder 29.498114 -26486451 -> 29.498114
+xsub026 subtract 29.498114 -26486451 -> 26486480.5 Inexact Rounded
+xadd027 add 244375043.E+130840878 -9.44522029 -> 2.44375043E+130840886 Inexact Rounded
+xcom027 compare 244375043.E+130840878 -9.44522029 -> 1
+xdiv027 divide 244375043.E+130840878 -9.44522029 -> -2.58728791E+130840885 Inexact Rounded
+xdvi027 divideint 244375043.E+130840878 -9.44522029 -> NaN Division_impossible
+xmul027 multiply 244375043.E+130840878 -9.44522029 -> -2.30817611E+130840887 Inexact Rounded
+xpow027 power 244375043.E+130840878 -9 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem027 remainder 244375043.E+130840878 -9.44522029 -> NaN Division_impossible
+xsub027 subtract 244375043.E+130840878 -9.44522029 -> 2.44375043E+130840886 Inexact Rounded
+xadd028 add -349388.759 -196215.776 -> -545604.535
+xcom028 compare -349388.759 -196215.776 -> -1
+xdiv028 divide -349388.759 -196215.776 -> 1.78063541 Inexact Rounded
+xdvi028 divideint -349388.759 -196215.776 -> 1
+xmul028 multiply -349388.759 -196215.776 -> 6.85555865E+10 Inexact Rounded
+xpow028 power -349388.759 -196216 -> 1.24551752E-1087686 Inexact Rounded
+xrem028 remainder -349388.759 -196215.776 -> -153172.983
+xsub028 subtract -349388.759 -196215.776 -> -153172.983
+xadd029 add -70905112.4 -91353968.8 -> -162259081 Inexact Rounded
+xcom029 compare -70905112.4 -91353968.8 -> 1
+xdiv029 divide -70905112.4 -91353968.8 -> 0.776157986 Inexact Rounded
+xdvi029 divideint -70905112.4 -91353968.8 -> 0
+xmul029 multiply -70905112.4 -91353968.8 -> 6.47746343E+15 Inexact Rounded
+xpow029 power -70905112.4 -91353969 -> -3.05944741E-717190554 Inexact Rounded
+xrem029 remainder -70905112.4 -91353968.8 -> -70905112.4
+xsub029 subtract -70905112.4 -91353968.8 -> 20448856.4
+xadd030 add -225094.28 -88.7723542 -> -225183.052 Inexact Rounded
+xcom030 compare -225094.28 -88.7723542 -> -1
+xdiv030 divide -225094.28 -88.7723542 -> 2535.63491 Inexact Rounded
+xdvi030 divideint -225094.28 -88.7723542 -> 2535
+xmul030 multiply -225094.28 -88.7723542 -> 19982149.2 Inexact Rounded
+xpow030 power -225094.28 -89 -> -4.36076964E-477 Inexact Rounded
+xrem030 remainder -225094.28 -88.7723542 -> -56.3621030
+xsub030 subtract -225094.28 -88.7723542 -> -225005.508 Inexact Rounded
+xadd031 add 50.4442340 82.7952169E+880120759 -> 8.27952169E+880120760 Inexact Rounded
+xcom031 compare 50.4442340 82.7952169E+880120759 -> -1
+xdiv031 divide 50.4442340 82.7952169E+880120759 -> 6.09265075E-880120760 Inexact Rounded
+xdvi031 divideint 50.4442340 82.7952169E+880120759 -> 0
+xmul031 multiply 50.4442340 82.7952169E+880120759 -> 4.17654130E+880120762 Inexact Rounded
+xpow031 power 50.4442340 8 -> 4.19268518E+13 Inexact Rounded
+xrem031 remainder 50.4442340 82.7952169E+880120759 -> 50.4442340
+xsub031 subtract 50.4442340 82.7952169E+880120759 -> -8.27952169E+880120760 Inexact Rounded
+xadd032 add -32311.9037 8.36379449 -> -32303.5399 Inexact Rounded
+xcom032 compare -32311.9037 8.36379449 -> -1
+xdiv032 divide -32311.9037 8.36379449 -> -3863.30675 Inexact Rounded
+xdvi032 divideint -32311.9037 8.36379449 -> -3863
+xmul032 multiply -32311.9037 8.36379449 -> -270250.122 Inexact Rounded
+xpow032 power -32311.9037 8 -> 1.18822960E+36 Inexact Rounded
+xrem032 remainder -32311.9037 8.36379449 -> -2.56558513
+xsub032 subtract -32311.9037 8.36379449 -> -32320.2675 Inexact Rounded
+xadd033 add 615396156.E+549895291 -29530247.4 -> 6.15396156E+549895299 Inexact Rounded
+xcom033 compare 615396156.E+549895291 -29530247.4 -> 1
+xdiv033 divide 615396156.E+549895291 -29530247.4 -> -2.08395191E+549895292 Inexact Rounded
+xdvi033 divideint 615396156.E+549895291 -29530247.4 -> NaN Division_impossible
+xmul033 multiply 615396156.E+549895291 -29530247.4 -> -1.81728007E+549895307 Inexact Rounded
+xpow033 power 615396156.E+549895291 -29530247 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem033 remainder 615396156.E+549895291 -29530247.4 -> NaN Division_impossible
+xsub033 subtract 615396156.E+549895291 -29530247.4 -> 6.15396156E+549895299 Inexact Rounded
+xadd034 add 592.142173E-419941416 -3.46079109E-844011845 -> 5.92142173E-419941414 Inexact Rounded
+xcom034 compare 592.142173E-419941416 -3.46079109E-844011845 -> 1
+xdiv034 divide 592.142173E-419941416 -3.46079109E-844011845 -> -1.71100236E+424070431 Inexact Rounded
+xdvi034 divideint 592.142173E-419941416 -3.46079109E-844011845 -> NaN Division_impossible
+xmul034 multiply 592.142173E-419941416 -3.46079109E-844011845 -> -0E-1000000007 Underflow Subnormal Inexact Rounded
+xpow034 power 592.142173E-419941416 -3 -> Infinity Overflow Inexact Rounded
+xrem034 remainder 592.142173E-419941416 -3.46079109E-844011845 -> NaN Division_impossible
+xsub034 subtract 592.142173E-419941416 -3.46079109E-844011845 -> 5.92142173E-419941414 Inexact Rounded
+xadd035 add 849.515993E-878446473 -1039.08778 -> -1039.08778 Inexact Rounded
+xcom035 compare 849.515993E-878446473 -1039.08778 -> 1
+xdiv035 divide 849.515993E-878446473 -1039.08778 -> -8.17559411E-878446474 Inexact Rounded
+xdvi035 divideint 849.515993E-878446473 -1039.08778 -> -0
+xmul035 multiply 849.515993E-878446473 -1039.08778 -> -8.82721687E-878446468 Inexact Rounded
+xpow035 power 849.515993E-878446473 -1039 -> Infinity Overflow Inexact Rounded
+xrem035 remainder 849.515993E-878446473 -1039.08778 -> 8.49515993E-878446471
+xsub035 subtract 849.515993E-878446473 -1039.08778 -> 1039.08778 Inexact Rounded
+xadd036 add 213361789 -599.644851 -> 213361189 Inexact Rounded
+xcom036 compare 213361789 -599.644851 -> 1
+xdiv036 divide 213361789 -599.644851 -> -355813.593 Inexact Rounded
+xdvi036 divideint 213361789 -599.644851 -> -355813
+xmul036 multiply 213361789 -599.644851 -> -1.27941298E+11 Inexact Rounded
+xpow036 power 213361789 -600 -> 3.38854684E-4998 Inexact Rounded
+xrem036 remainder 213361789 -599.644851 -> 355.631137
+xsub036 subtract 213361789 -599.644851 -> 213362389 Inexact Rounded
+xadd037 add -795522555. -298.037702 -> -795522853 Inexact Rounded
+xcom037 compare -795522555. -298.037702 -> -1
+xdiv037 divide -795522555. -298.037702 -> 2669201.08 Inexact Rounded
+xdvi037 divideint -795522555. -298.037702 -> 2669201
+xmul037 multiply -795522555. -298.037702 -> 2.37095714E+11 Inexact Rounded
+xpow037 power -795522555. -298 -> 4.03232712E-2653 Inexact Rounded
+xrem037 remainder -795522555. -298.037702 -> -22.783898
+xsub037 subtract -795522555. -298.037702 -> -795522257 Inexact Rounded
+xadd038 add -501260651. -8761893.0E-689281479 -> -501260651 Inexact Rounded
+xcom038 compare -501260651. -8761893.0E-689281479 -> -1
+xdiv038 divide -501260651. -8761893.0E-689281479 -> 5.72091728E+689281480 Inexact Rounded
+xdvi038 divideint -501260651. -8761893.0E-689281479 -> NaN Division_impossible
+xmul038 multiply -501260651. -8761893.0E-689281479 -> 4.39199219E-689281464 Inexact Rounded
+xpow038 power -501260651. -9 -> -5.00526961E-79 Inexact Rounded
+xrem038 remainder -501260651. -8761893.0E-689281479 -> NaN Division_impossible
+xsub038 subtract -501260651. -8761893.0E-689281479 -> -501260651 Inexact Rounded
+xadd039 add -1.70781105E-848889023 36504769.4 -> 36504769.4 Inexact Rounded
+xcom039 compare -1.70781105E-848889023 36504769.4 -> -1
+xdiv039 divide -1.70781105E-848889023 36504769.4 -> -4.67832307E-848889031 Inexact Rounded
+xdvi039 divideint -1.70781105E-848889023 36504769.4 -> -0
+xmul039 multiply -1.70781105E-848889023 36504769.4 -> -6.23432486E-848889016 Inexact Rounded
+xpow039 power -1.70781105E-848889023 36504769 -> -0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem039 remainder -1.70781105E-848889023 36504769.4 -> -1.70781105E-848889023
+xsub039 subtract -1.70781105E-848889023 36504769.4 -> -36504769.4 Inexact Rounded
+xadd040 add -5290.54984E-490626676 842535254 -> 842535254 Inexact Rounded
+xcom040 compare -5290.54984E-490626676 842535254 -> -1
+xdiv040 divide -5290.54984E-490626676 842535254 -> -6.27932162E-490626682 Inexact Rounded
+xdvi040 divideint -5290.54984E-490626676 842535254 -> -0
+xmul040 multiply -5290.54984E-490626676 842535254 -> -4.45747475E-490626664 Inexact Rounded
+xpow040 power -5290.54984E-490626676 842535254 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem040 remainder -5290.54984E-490626676 842535254 -> -5.29054984E-490626673
+xsub040 subtract -5290.54984E-490626676 842535254 -> -842535254 Inexact Rounded
+xadd041 add 608.31825E+535268120 -59609.0993 -> 6.08318250E+535268122 Inexact Rounded
+xcom041 compare 608.31825E+535268120 -59609.0993 -> 1
+xdiv041 divide 608.31825E+535268120 -59609.0993 -> -1.02051240E+535268118 Inexact Rounded
+xdvi041 divideint 608.31825E+535268120 -59609.0993 -> NaN Division_impossible
+xmul041 multiply 608.31825E+535268120 -59609.0993 -> -3.62613030E+535268127 Inexact Rounded
+xpow041 power 608.31825E+535268120 -59609 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem041 remainder 608.31825E+535268120 -59609.0993 -> NaN Division_impossible
+xsub041 subtract 608.31825E+535268120 -59609.0993 -> 6.08318250E+535268122 Inexact Rounded
+xadd042 add -4629035.31 -167.884398 -> -4629203.19 Inexact Rounded
+xcom042 compare -4629035.31 -167.884398 -> -1
+xdiv042 divide -4629035.31 -167.884398 -> 27572.7546 Inexact Rounded
+xdvi042 divideint -4629035.31 -167.884398 -> 27572
+xmul042 multiply -4629035.31 -167.884398 -> 777142806 Inexact Rounded
+xpow042 power -4629035.31 -168 -> 1.57614831E-1120 Inexact Rounded
+xrem042 remainder -4629035.31 -167.884398 -> -126.688344
+xsub042 subtract -4629035.31 -167.884398 -> -4628867.43 Inexact Rounded
+xadd043 add -66527378. -706400268. -> -772927646
+xcom043 compare -66527378. -706400268. -> 1
+xdiv043 divide -66527378. -706400268. -> 0.0941780192 Inexact Rounded
+xdvi043 divideint -66527378. -706400268. -> 0
+xmul043 multiply -66527378. -706400268. -> 4.69949576E+16 Inexact Rounded
+xpow043 power -66527378. -706400268 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem043 remainder -66527378. -706400268. -> -66527378
+xsub043 subtract -66527378. -706400268. -> 639872890
+xadd044 add -2510497.53 372882462. -> 370371964 Inexact Rounded
+xcom044 compare -2510497.53 372882462. -> -1
+xdiv044 divide -2510497.53 372882462. -> -0.00673267795 Inexact Rounded
+xdvi044 divideint -2510497.53 372882462. -> -0
+xmul044 multiply -2510497.53 372882462. -> -9.36120500E+14 Inexact Rounded
+xpow044 power -2510497.53 372882462 -> Infinity Overflow Inexact Rounded
+xrem044 remainder -2510497.53 372882462. -> -2510497.53
+xsub044 subtract -2510497.53 372882462. -> -375392960 Inexact Rounded
+xadd045 add 136.255393E+53329961 -53494.7201E+720058060 -> -5.34947201E+720058064 Inexact Rounded
+xcom045 compare 136.255393E+53329961 -53494.7201E+720058060 -> 1
+xdiv045 divide 136.255393E+53329961 -53494.7201E+720058060 -> -2.54708115E-666728102 Inexact Rounded
+xdvi045 divideint 136.255393E+53329961 -53494.7201E+720058060 -> -0
+xmul045 multiply 136.255393E+53329961 -53494.7201E+720058060 -> -7.28894411E+773388027 Inexact Rounded
+xpow045 power 136.255393E+53329961 -5 -> 2.12927373E-266649816 Inexact Rounded
+xrem045 remainder 136.255393E+53329961 -53494.7201E+720058060 -> 1.36255393E+53329963
+xsub045 subtract 136.255393E+53329961 -53494.7201E+720058060 -> 5.34947201E+720058064 Inexact Rounded
+xadd046 add -876673.100 -6150.92266 -> -882824.023 Inexact Rounded
+xcom046 compare -876673.100 -6150.92266 -> -1
+xdiv046 divide -876673.100 -6150.92266 -> 142.527089 Inexact Rounded
+xdvi046 divideint -876673.100 -6150.92266 -> 142
+xmul046 multiply -876673.100 -6150.92266 -> 5.39234844E+9 Inexact Rounded
+xpow046 power -876673.100 -6151 -> -4.03111774E-36555 Inexact Rounded
+xrem046 remainder -876673.100 -6150.92266 -> -3242.08228
+xsub046 subtract -876673.100 -6150.92266 -> -870522.177 Inexact Rounded
+xadd047 add -2.45151797E+911306117 27235771 -> -2.45151797E+911306117 Inexact Rounded
+xcom047 compare -2.45151797E+911306117 27235771 -> -1
+xdiv047 divide -2.45151797E+911306117 27235771 -> -9.00109628E+911306109 Inexact Rounded
+xdvi047 divideint -2.45151797E+911306117 27235771 -> NaN Division_impossible
+xmul047 multiply -2.45151797E+911306117 27235771 -> -6.67689820E+911306124 Inexact Rounded
+xpow047 power -2.45151797E+911306117 27235771 -> -Infinity Overflow Inexact Rounded
+xrem047 remainder -2.45151797E+911306117 27235771 -> NaN Division_impossible
+xsub047 subtract -2.45151797E+911306117 27235771 -> -2.45151797E+911306117 Inexact Rounded
+xadd048 add -9.15117551 -4.95100733E-314511326 -> -9.15117551 Inexact Rounded
+xcom048 compare -9.15117551 -4.95100733E-314511326 -> -1
+xdiv048 divide -9.15117551 -4.95100733E-314511326 -> 1.84834618E+314511326 Inexact Rounded
+xdvi048 divideint -9.15117551 -4.95100733E-314511326 -> NaN Division_impossible
+xmul048 multiply -9.15117551 -4.95100733E-314511326 -> 4.53075370E-314511325 Inexact Rounded
+xpow048 power -9.15117551 -5 -> -0.0000155817265 Inexact Rounded
+xrem048 remainder -9.15117551 -4.95100733E-314511326 -> NaN Division_impossible
+xsub048 subtract -9.15117551 -4.95100733E-314511326 -> -9.15117551 Inexact Rounded
+xadd049 add 3.61890453E-985606128 30664416. -> 30664416.0 Inexact Rounded
+xcom049 compare 3.61890453E-985606128 30664416. -> -1
+xdiv049 divide 3.61890453E-985606128 30664416. -> 1.18016418E-985606135 Inexact Rounded
+xdvi049 divideint 3.61890453E-985606128 30664416. -> 0
+xmul049 multiply 3.61890453E-985606128 30664416. -> 1.10971594E-985606120 Inexact Rounded
+xpow049 power 3.61890453E-985606128 30664416 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem049 remainder 3.61890453E-985606128 30664416. -> 3.61890453E-985606128
+xsub049 subtract 3.61890453E-985606128 30664416. -> -30664416.0 Inexact Rounded
+xadd050 add -257674602E+216723382 -70820959.4 -> -2.57674602E+216723390 Inexact Rounded
+xcom050 compare -257674602E+216723382 -70820959.4 -> -1
+xdiv050 divide -257674602E+216723382 -70820959.4 -> 3.63839468E+216723382 Inexact Rounded
+xdvi050 divideint -257674602E+216723382 -70820959.4 -> NaN Division_impossible
+xmul050 multiply -257674602E+216723382 -70820959.4 -> 1.82487625E+216723398 Inexact Rounded
+xpow050 power -257674602E+216723382 -70820959 -> -0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem050 remainder -257674602E+216723382 -70820959.4 -> NaN Division_impossible
+xsub050 subtract -257674602E+216723382 -70820959.4 -> -2.57674602E+216723390 Inexact Rounded
+xadd051 add 218699.206 556944241. -> 557162940 Inexact Rounded
+xcom051 compare 218699.206 556944241. -> -1
+xdiv051 divide 218699.206 556944241. -> 0.000392677022 Inexact Rounded
+xdvi051 divideint 218699.206 556944241. -> 0
+xmul051 multiply 218699.206 556944241. -> 1.21803263E+14 Inexact Rounded
+xpow051 power 218699.206 556944241 -> Infinity Overflow Inexact Rounded
+xrem051 remainder 218699.206 556944241. -> 218699.206
+xsub051 subtract 218699.206 556944241. -> -556725542 Inexact Rounded
+xadd052 add 106211716. -3456793.74 -> 102754922 Inexact Rounded
+xcom052 compare 106211716. -3456793.74 -> 1
+xdiv052 divide 106211716. -3456793.74 -> -30.7255000 Inexact Rounded
+xdvi052 divideint 106211716. -3456793.74 -> -30
+xmul052 multiply 106211716. -3456793.74 -> -3.67151995E+14 Inexact Rounded
+xpow052 power 106211716. -3456794 -> 2.07225581E-27744825 Inexact Rounded
+xrem052 remainder 106211716. -3456793.74 -> 2507903.80
+xsub052 subtract 106211716. -3456793.74 -> 109668510 Inexact Rounded
+xadd053 add 1.25018078 399856.763E-726816740 -> 1.25018078 Inexact Rounded
+xcom053 compare 1.25018078 399856.763E-726816740 -> 1
+xdiv053 divide 1.25018078 399856.763E-726816740 -> 3.12657155E+726816734 Inexact Rounded
+xdvi053 divideint 1.25018078 399856.763E-726816740 -> NaN Division_impossible
+xmul053 multiply 1.25018078 399856.763E-726816740 -> 4.99893240E-726816735 Inexact Rounded
+xpow053 power 1.25018078 4 -> 2.44281890 Inexact Rounded
+xrem053 remainder 1.25018078 399856.763E-726816740 -> NaN Division_impossible
+xsub053 subtract 1.25018078 399856.763E-726816740 -> 1.25018078 Inexact Rounded
+xadd054 add 364.99811 -46222.0505 -> -45857.0524 Inexact Rounded
+xcom054 compare 364.99811 -46222.0505 -> 1
+xdiv054 divide 364.99811 -46222.0505 -> -0.00789662306 Inexact Rounded
+xdvi054 divideint 364.99811 -46222.0505 -> -0
+xmul054 multiply 364.99811 -46222.0505 -> -16870961.1 Inexact Rounded
+xpow054 power 364.99811 -46222 -> 6.35570856E-118435 Inexact Rounded
+xrem054 remainder 364.99811 -46222.0505 -> 364.99811
+xsub054 subtract 364.99811 -46222.0505 -> 46587.0486 Inexact Rounded
+xadd055 add -392217576. -958364096 -> -1.35058167E+9 Inexact Rounded
+xcom055 compare -392217576. -958364096 -> 1
+xdiv055 divide -392217576. -958364096 -> 0.409257377 Inexact Rounded
+xdvi055 divideint -392217576. -958364096 -> 0
+xmul055 multiply -392217576. -958364096 -> 3.75887243E+17 Inexact Rounded
+xpow055 power -392217576. -958364096 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem055 remainder -392217576. -958364096 -> -392217576
+xsub055 subtract -392217576. -958364096 -> 566146520
+xadd056 add 169601285 714526.639 -> 170315812 Inexact Rounded
+xcom056 compare 169601285 714526.639 -> 1
+xdiv056 divide 169601285 714526.639 -> 237.361738 Inexact Rounded
+xdvi056 divideint 169601285 714526.639 -> 237
+xmul056 multiply 169601285 714526.639 -> 1.21184636E+14 Inexact Rounded
+xpow056 power 169601285 714527 -> 2.06052444E+5880149 Inexact Rounded
+xrem056 remainder 169601285 714526.639 -> 258471.557
+xsub056 subtract 169601285 714526.639 -> 168886758 Inexact Rounded
+xadd057 add -674.094552E+586944319 6354.2668E+589657266 -> 6.35426680E+589657269 Inexact Rounded
+xcom057 compare -674.094552E+586944319 6354.2668E+589657266 -> -1
+xdiv057 divide -674.094552E+586944319 6354.2668E+589657266 -> -1.06085340E-2712948 Inexact Rounded
+xdvi057 divideint -674.094552E+586944319 6354.2668E+589657266 -> -0
+xmul057 multiply -674.094552E+586944319 6354.2668E+589657266 -> -Infinity Inexact Overflow Rounded
+xpow057 power -674.094552E+586944319 6 -> Infinity Overflow Inexact Rounded
+xrem057 remainder -674.094552E+586944319 6354.2668E+589657266 -> -6.74094552E+586944321
+xsub057 subtract -674.094552E+586944319 6354.2668E+589657266 -> -6.35426680E+589657269 Inexact Rounded
+xadd058 add 151795163E-371727182 -488.09788E-738852245 -> 1.51795163E-371727174 Inexact Rounded
+xcom058 compare 151795163E-371727182 -488.09788E-738852245 -> 1
+xdiv058 divide 151795163E-371727182 -488.09788E-738852245 -> -3.10993285E+367125068 Inexact Rounded
+xdvi058 divideint 151795163E-371727182 -488.09788E-738852245 -> NaN Division_impossible
+xmul058 multiply 151795163E-371727182 -488.09788E-738852245 -> -0E-1000000007 Underflow Subnormal Inexact Rounded
+xpow058 power 151795163E-371727182 -5 -> Infinity Overflow Inexact Rounded
+xrem058 remainder 151795163E-371727182 -488.09788E-738852245 -> NaN Division_impossible
+xsub058 subtract 151795163E-371727182 -488.09788E-738852245 -> 1.51795163E-371727174 Inexact Rounded
+xadd059 add -746.293386 927749.647 -> 927003.354 Inexact Rounded
+xcom059 compare -746.293386 927749.647 -> -1
+xdiv059 divide -746.293386 927749.647 -> -0.000804412471 Inexact Rounded
+xdvi059 divideint -746.293386 927749.647 -> -0
+xmul059 multiply -746.293386 927749.647 -> -692373425 Inexact Rounded
+xpow059 power -746.293386 927750 -> 7.49278741E+2665341 Inexact Rounded
+xrem059 remainder -746.293386 927749.647 -> -746.293386
+xsub059 subtract -746.293386 927749.647 -> -928495.940 Inexact Rounded
+xadd060 add 888946471E+241331592 -235739.595 -> 8.88946471E+241331600 Inexact Rounded
+xcom060 compare 888946471E+241331592 -235739.595 -> 1
+xdiv060 divide 888946471E+241331592 -235739.595 -> -3.77088317E+241331595 Inexact Rounded
+xdvi060 divideint 888946471E+241331592 -235739.595 -> NaN Division_impossible
+xmul060 multiply 888946471E+241331592 -235739.595 -> -2.09559881E+241331606 Inexact Rounded
+xpow060 power 888946471E+241331592 -235740 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem060 remainder 888946471E+241331592 -235739.595 -> NaN Division_impossible
+xsub060 subtract 888946471E+241331592 -235739.595 -> 8.88946471E+241331600 Inexact Rounded
+xadd061 add 6.64377249 79161.1070E+619453776 -> 7.91611070E+619453780 Inexact Rounded
+xcom061 compare 6.64377249 79161.1070E+619453776 -> -1
+xdiv061 divide 6.64377249 79161.1070E+619453776 -> 8.39272307E-619453781 Inexact Rounded
+xdvi061 divideint 6.64377249 79161.1070E+619453776 -> 0
+xmul061 multiply 6.64377249 79161.1070E+619453776 -> 5.25928385E+619453781 Inexact Rounded
+xpow061 power 6.64377249 8 -> 3795928.44 Inexact Rounded
+xrem061 remainder 6.64377249 79161.1070E+619453776 -> 6.64377249
+xsub061 subtract 6.64377249 79161.1070E+619453776 -> -7.91611070E+619453780 Inexact Rounded
+xadd062 add 3146.66571E-313373366 88.5282010 -> 88.5282010 Inexact Rounded
+xcom062 compare 3146.66571E-313373366 88.5282010 -> -1
+xdiv062 divide 3146.66571E-313373366 88.5282010 -> 3.55442184E-313373365 Inexact Rounded
+xdvi062 divideint 3146.66571E-313373366 88.5282010 -> 0
+xmul062 multiply 3146.66571E-313373366 88.5282010 -> 2.78568654E-313373361 Inexact Rounded
+xpow062 power 3146.66571E-313373366 89 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem062 remainder 3146.66571E-313373366 88.5282010 -> 3.14666571E-313373363
+xsub062 subtract 3146.66571E-313373366 88.5282010 -> -88.5282010 Inexact Rounded
+xadd063 add 6.44693097 -87195.8711 -> -87189.4242 Inexact Rounded
+xcom063 compare 6.44693097 -87195.8711 -> 1
+xdiv063 divide 6.44693097 -87195.8711 -> -0.0000739361955 Inexact Rounded
+xdvi063 divideint 6.44693097 -87195.8711 -> -0
+xmul063 multiply 6.44693097 -87195.8711 -> -562145.762 Inexact Rounded
+xpow063 power 6.44693097 -87196 -> 4.50881730E-70573 Inexact Rounded
+xrem063 remainder 6.44693097 -87195.8711 -> 6.44693097
+xsub063 subtract 6.44693097 -87195.8711 -> 87202.3180 Inexact Rounded
+xadd064 add -2113132.56E+577957840 981125821 -> -2.11313256E+577957846 Inexact Rounded
+xcom064 compare -2113132.56E+577957840 981125821 -> -1
+xdiv064 divide -2113132.56E+577957840 981125821 -> -2.15378345E+577957837 Inexact Rounded
+xdvi064 divideint -2113132.56E+577957840 981125821 -> NaN Division_impossible
+xmul064 multiply -2113132.56E+577957840 981125821 -> -2.07324892E+577957855 Inexact Rounded
+xpow064 power -2113132.56E+577957840 981125821 -> -Infinity Overflow Inexact Rounded
+xrem064 remainder -2113132.56E+577957840 981125821 -> NaN Division_impossible
+xsub064 subtract -2113132.56E+577957840 981125821 -> -2.11313256E+577957846 Inexact Rounded
+xadd065 add -7701.42814 72667.5181 -> 64966.0900 Inexact Rounded
+xcom065 compare -7701.42814 72667.5181 -> -1
+xdiv065 divide -7701.42814 72667.5181 -> -0.105981714 Inexact Rounded
+xdvi065 divideint -7701.42814 72667.5181 -> -0
+xmul065 multiply -7701.42814 72667.5181 -> -559643669 Inexact Rounded
+xpow065 power -7701.42814 72668 -> 2.29543837E+282429 Inexact Rounded
+xrem065 remainder -7701.42814 72667.5181 -> -7701.42814
+xsub065 subtract -7701.42814 72667.5181 -> -80368.9462 Inexact Rounded
+xadd066 add -851.754789 -582659.149 -> -583510.904 Inexact Rounded
+xcom066 compare -851.754789 -582659.149 -> 1
+xdiv066 divide -851.754789 -582659.149 -> 0.00146184058 Inexact Rounded
+xdvi066 divideint -851.754789 -582659.149 -> 0
+xmul066 multiply -851.754789 -582659.149 -> 496282721 Inexact Rounded
+xpow066 power -851.754789 -582659 -> -6.83532593E-1707375 Inexact Rounded
+xrem066 remainder -851.754789 -582659.149 -> -851.754789
+xsub066 subtract -851.754789 -582659.149 -> 581807.394 Inexact Rounded
+xadd067 add -5.01992943 7852.16531 -> 7847.14538 Inexact Rounded
+xcom067 compare -5.01992943 7852.16531 -> -1
+xdiv067 divide -5.01992943 7852.16531 -> -0.000639305113 Inexact Rounded
+xdvi067 divideint -5.01992943 7852.16531 -> -0
+xmul067 multiply -5.01992943 7852.16531 -> -39417.3157 Inexact Rounded
+xpow067 power -5.01992943 7852 -> 7.54481448E+5501 Inexact Rounded
+xrem067 remainder -5.01992943 7852.16531 -> -5.01992943
+xsub067 subtract -5.01992943 7852.16531 -> -7857.18524 Inexact Rounded
+xadd068 add -12393257.2 76803689E+949125770 -> 7.68036890E+949125777 Inexact Rounded
+xcom068 compare -12393257.2 76803689E+949125770 -> -1
+xdiv068 divide -12393257.2 76803689E+949125770 -> -1.61362786E-949125771 Inexact Rounded
+xdvi068 divideint -12393257.2 76803689E+949125770 -> -0
+xmul068 multiply -12393257.2 76803689E+949125770 -> -9.51847872E+949125784 Inexact Rounded
+xpow068 power -12393257.2 8 -> 5.56523750E+56 Inexact Rounded
+xrem068 remainder -12393257.2 76803689E+949125770 -> -12393257.2
+xsub068 subtract -12393257.2 76803689E+949125770 -> -7.68036890E+949125777 Inexact Rounded
+xadd069 add -754771634.E+716555026 -292336.311 -> -7.54771634E+716555034 Inexact Rounded
+xcom069 compare -754771634.E+716555026 -292336.311 -> -1
+xdiv069 divide -754771634.E+716555026 -292336.311 -> 2.58186070E+716555029 Inexact Rounded
+xdvi069 divideint -754771634.E+716555026 -292336.311 -> NaN Division_impossible
+xmul069 multiply -754771634.E+716555026 -292336.311 -> 2.20647155E+716555040 Inexact Rounded
+xpow069 power -754771634.E+716555026 -292336 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem069 remainder -754771634.E+716555026 -292336.311 -> NaN Division_impossible
+xsub069 subtract -754771634.E+716555026 -292336.311 -> -7.54771634E+716555034 Inexact Rounded
+xadd070 add -915006.171E+614548652 -314086965. -> -9.15006171E+614548657 Inexact Rounded
+xcom070 compare -915006.171E+614548652 -314086965. -> -1
+xdiv070 divide -915006.171E+614548652 -314086965. -> 2.91322555E+614548649 Inexact Rounded
+xdvi070 divideint -915006.171E+614548652 -314086965. -> NaN Division_impossible
+xmul070 multiply -915006.171E+614548652 -314086965. -> 2.87391511E+614548666 Inexact Rounded
+xpow070 power -915006.171E+614548652 -314086965 -> -0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem070 remainder -915006.171E+614548652 -314086965. -> NaN Division_impossible
+xsub070 subtract -915006.171E+614548652 -314086965. -> -9.15006171E+614548657 Inexact Rounded
+xadd071 add -296590035 -481734529 -> -778324564
+xcom071 compare -296590035 -481734529 -> 1
+xdiv071 divide -296590035 -481734529 -> 0.615671116 Inexact Rounded
+xdvi071 divideint -296590035 -481734529 -> 0
+xmul071 multiply -296590035 -481734529 -> 1.42877661E+17 Inexact Rounded
+xpow071 power -296590035 -481734529 -> -0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem071 remainder -296590035 -481734529 -> -296590035
+xsub071 subtract -296590035 -481734529 -> 185144494
+xadd072 add 8.27822605 9241557.19 -> 9241565.47 Inexact Rounded
+xcom072 compare 8.27822605 9241557.19 -> -1
+xdiv072 divide 8.27822605 9241557.19 -> 8.95760950E-7 Inexact Rounded
+xdvi072 divideint 8.27822605 9241557.19 -> 0
+xmul072 multiply 8.27822605 9241557.19 -> 76503699.5 Inexact Rounded
+xpow072 power 8.27822605 9241557 -> 5.10219969E+8483169 Inexact Rounded
+xrem072 remainder 8.27822605 9241557.19 -> 8.27822605
+xsub072 subtract 8.27822605 9241557.19 -> -9241548.91 Inexact Rounded
+xadd073 add -1.43581098 7286313.54 -> 7286312.10 Inexact Rounded
+xcom073 compare -1.43581098 7286313.54 -> -1
+xdiv073 divide -1.43581098 7286313.54 -> -1.97055887E-7 Inexact Rounded
+xdvi073 divideint -1.43581098 7286313.54 -> -0
+xmul073 multiply -1.43581098 7286313.54 -> -10461769.0 Inexact Rounded
+xpow073 power -1.43581098 7286314 -> 1.09389741E+1144660 Inexact Rounded
+xrem073 remainder -1.43581098 7286313.54 -> -1.43581098
+xsub073 subtract -1.43581098 7286313.54 -> -7286314.98 Inexact Rounded
+xadd074 add -699036193. 759263.509E+533543625 -> 7.59263509E+533543630 Inexact Rounded
+xcom074 compare -699036193. 759263.509E+533543625 -> -1
+xdiv074 divide -699036193. 759263.509E+533543625 -> -9.20676662E-533543623 Inexact Rounded
+xdvi074 divideint -699036193. 759263.509E+533543625 -> -0
+xmul074 multiply -699036193. 759263.509E+533543625 -> -5.30752673E+533543639 Inexact Rounded
+xpow074 power -699036193. 8 -> 5.70160724E+70 Inexact Rounded
+xrem074 remainder -699036193. 759263.509E+533543625 -> -699036193
+xsub074 subtract -699036193. 759263.509E+533543625 -> -7.59263509E+533543630 Inexact Rounded
+xadd075 add -83.7273615E-305281957 -287779593.E+458777774 -> -2.87779593E+458777782 Inexact Rounded
+xcom075 compare -83.7273615E-305281957 -287779593.E+458777774 -> 1
+xdiv075 divide -83.7273615E-305281957 -287779593.E+458777774 -> 2.90942664E-764059738 Inexact Rounded
+xdvi075 divideint -83.7273615E-305281957 -287779593.E+458777774 -> 0
+xmul075 multiply -83.7273615E-305281957 -287779593.E+458777774 -> 2.40950260E+153495827 Inexact Rounded
+xpow075 power -83.7273615E-305281957 -3 -> -1.70371828E+915845865 Inexact Rounded
+xrem075 remainder -83.7273615E-305281957 -287779593.E+458777774 -> -8.37273615E-305281956
+xsub075 subtract -83.7273615E-305281957 -287779593.E+458777774 -> 2.87779593E+458777782 Inexact Rounded
+xadd076 add 8.48503224 6522.03316 -> 6530.51819 Inexact Rounded
+xcom076 compare 8.48503224 6522.03316 -> -1
+xdiv076 divide 8.48503224 6522.03316 -> 0.00130097962 Inexact Rounded
+xdvi076 divideint 8.48503224 6522.03316 -> 0
+xmul076 multiply 8.48503224 6522.03316 -> 55339.6616 Inexact Rounded
+xpow076 power 8.48503224 6522 -> 4.76547542E+6056 Inexact Rounded
+xrem076 remainder 8.48503224 6522.03316 -> 8.48503224
+xsub076 subtract 8.48503224 6522.03316 -> -6513.54813 Inexact Rounded
+xadd077 add 527916091 -809.054070 -> 527915282 Inexact Rounded
+xcom077 compare 527916091 -809.054070 -> 1
+xdiv077 divide 527916091 -809.054070 -> -652510.272 Inexact Rounded
+xdvi077 divideint 527916091 -809.054070 -> -652510
+xmul077 multiply 527916091 -809.054070 -> -4.27112662E+11 Inexact Rounded
+xpow077 power 527916091 -809 -> 2.78609697E-7057 Inexact Rounded
+xrem077 remainder 527916091 -809.054070 -> 219.784300
+xsub077 subtract 527916091 -809.054070 -> 527916900 Inexact Rounded
+xadd078 add 3857058.60 5792997.58E+881077409 -> 5.79299758E+881077415 Inexact Rounded
+xcom078 compare 3857058.60 5792997.58E+881077409 -> -1
+xdiv078 divide 3857058.60 5792997.58E+881077409 -> 6.65813950E-881077410 Inexact Rounded
+xdvi078 divideint 3857058.60 5792997.58E+881077409 -> 0
+xmul078 multiply 3857058.60 5792997.58E+881077409 -> 2.23439311E+881077422 Inexact Rounded
+xpow078 power 3857058.60 6 -> 3.29258824E+39 Inexact Rounded
+xrem078 remainder 3857058.60 5792997.58E+881077409 -> 3857058.60
+xsub078 subtract 3857058.60 5792997.58E+881077409 -> -5.79299758E+881077415 Inexact Rounded
+xadd079 add -66587363.E+556538173 -551902402E+357309146 -> -6.65873630E+556538180 Inexact Rounded
+xcom079 compare -66587363.E+556538173 -551902402E+357309146 -> -1
+xdiv079 divide -66587363.E+556538173 -551902402E+357309146 -> 1.20650613E+199229026 Inexact Rounded
+xdvi079 divideint -66587363.E+556538173 -551902402E+357309146 -> NaN Division_impossible
+xmul079 multiply -66587363.E+556538173 -551902402E+357309146 -> 3.67497256E+913847335 Inexact Rounded
+xpow079 power -66587363.E+556538173 -6 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem079 remainder -66587363.E+556538173 -551902402E+357309146 -> NaN Division_impossible
+xsub079 subtract -66587363.E+556538173 -551902402E+357309146 -> -6.65873630E+556538180 Inexact Rounded
+xadd080 add -580.502955 38125521.7 -> 38124941.2 Inexact Rounded
+xcom080 compare -580.502955 38125521.7 -> -1
+xdiv080 divide -580.502955 38125521.7 -> -0.0000152260987 Inexact Rounded
+xdvi080 divideint -580.502955 38125521.7 -> -0
+xmul080 multiply -580.502955 38125521.7 -> -2.21319780E+10 Inexact Rounded
+xpow080 power -580.502955 38125522 -> 6.07262078E+105371486 Inexact Rounded
+xrem080 remainder -580.502955 38125521.7 -> -580.502955
+xsub080 subtract -580.502955 38125521.7 -> -38126102.2 Inexact Rounded
+xadd081 add -9627363.00 -80616885E-749891394 -> -9627363.00 Inexact Rounded
+xcom081 compare -9627363.00 -80616885E-749891394 -> -1
+xdiv081 divide -9627363.00 -80616885E-749891394 -> 1.19421173E+749891393 Inexact Rounded
+xdvi081 divideint -9627363.00 -80616885E-749891394 -> NaN Division_impossible
+xmul081 multiply -9627363.00 -80616885E-749891394 -> 7.76128016E-749891380 Inexact Rounded
+xpow081 power -9627363.00 -8 -> 1.35500601E-56 Inexact Rounded
+xrem081 remainder -9627363.00 -80616885E-749891394 -> NaN Division_impossible
+xsub081 subtract -9627363.00 -80616885E-749891394 -> -9627363.00 Inexact Rounded
+xadd082 add -526.594855E+803110107 -64.5451639 -> -5.26594855E+803110109 Inexact Rounded
+xcom082 compare -526.594855E+803110107 -64.5451639 -> -1
+xdiv082 divide -526.594855E+803110107 -64.5451639 -> 8.15854858E+803110107 Inexact Rounded
+xdvi082 divideint -526.594855E+803110107 -64.5451639 -> NaN Division_impossible
+xmul082 multiply -526.594855E+803110107 -64.5451639 -> 3.39891512E+803110111 Inexact Rounded
+xpow082 power -526.594855E+803110107 -65 -> -0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem082 remainder -526.594855E+803110107 -64.5451639 -> NaN Division_impossible
+xsub082 subtract -526.594855E+803110107 -64.5451639 -> -5.26594855E+803110109 Inexact Rounded
+xadd083 add -8378.55499 760.131257 -> -7618.42373 Inexact Rounded
+xcom083 compare -8378.55499 760.131257 -> -1
+xdiv083 divide -8378.55499 760.131257 -> -11.0225108 Inexact Rounded
+xdvi083 divideint -8378.55499 760.131257 -> -11
+xmul083 multiply -8378.55499 760.131257 -> -6368801.54 Inexact Rounded
+xpow083 power -8378.55499 760 -> 4.06007928E+2981 Inexact Rounded
+xrem083 remainder -8378.55499 760.131257 -> -17.111163
+xsub083 subtract -8378.55499 760.131257 -> -9138.68625 Inexact Rounded
+xadd084 add -717.697718 984304413 -> 984303695 Inexact Rounded
+xcom084 compare -717.697718 984304413 -> -1
+xdiv084 divide -717.697718 984304413 -> -7.29142030E-7 Inexact Rounded
+xdvi084 divideint -717.697718 984304413 -> -0
+xmul084 multiply -717.697718 984304413 -> -7.06433031E+11 Inexact Rounded
+xpow084 power -717.697718 984304413 -> -Infinity Overflow Inexact Rounded
+xrem084 remainder -717.697718 984304413 -> -717.697718
+xsub084 subtract -717.697718 984304413 -> -984305131 Inexact Rounded
+xadd085 add -76762243.4E-741100094 -273.706674 -> -273.706674 Inexact Rounded
+xcom085 compare -76762243.4E-741100094 -273.706674 -> 1
+xdiv085 divide -76762243.4E-741100094 -273.706674 -> 2.80454409E-741100089 Inexact Rounded
+xdvi085 divideint -76762243.4E-741100094 -273.706674 -> 0
+xmul085 multiply -76762243.4E-741100094 -273.706674 -> 2.10103383E-741100084 Inexact Rounded
+xpow085 power -76762243.4E-741100094 -274 -> Infinity Overflow Inexact Rounded
+xrem085 remainder -76762243.4E-741100094 -273.706674 -> -7.67622434E-741100087
+xsub085 subtract -76762243.4E-741100094 -273.706674 -> 273.706674 Inexact Rounded
+xadd086 add -701.518354E+786274918 8822750.68E+243052107 -> -7.01518354E+786274920 Inexact Rounded
+xcom086 compare -701.518354E+786274918 8822750.68E+243052107 -> -1
+xdiv086 divide -701.518354E+786274918 8822750.68E+243052107 -> -7.95124309E+543222806 Inexact Rounded
+xdvi086 divideint -701.518354E+786274918 8822750.68E+243052107 -> NaN Division_impossible
+xmul086 multiply -701.518354E+786274918 8822750.68E+243052107 -> -Infinity Inexact Overflow Rounded
+xpow086 power -701.518354E+786274918 9 -> -Infinity Overflow Inexact Rounded
+xrem086 remainder -701.518354E+786274918 8822750.68E+243052107 -> NaN Division_impossible
+xsub086 subtract -701.518354E+786274918 8822750.68E+243052107 -> -7.01518354E+786274920 Inexact Rounded
+xadd087 add -359866845. -4.57434117 -> -359866850 Inexact Rounded
+xcom087 compare -359866845. -4.57434117 -> -1
+xdiv087 divide -359866845. -4.57434117 -> 78670748.8 Inexact Rounded
+xdvi087 divideint -359866845. -4.57434117 -> 78670748
+xmul087 multiply -359866845. -4.57434117 -> 1.64615372E+9 Inexact Rounded
+xpow087 power -359866845. -5 -> -1.65687909E-43 Inexact Rounded
+xrem087 remainder -359866845. -4.57434117 -> -3.54890484
+xsub087 subtract -359866845. -4.57434117 -> -359866840 Inexact Rounded
+xadd088 add 779934536. -76562645.7 -> 703371890 Inexact Rounded
+xcom088 compare 779934536. -76562645.7 -> 1
+xdiv088 divide 779934536. -76562645.7 -> -10.1868807 Inexact Rounded
+xdvi088 divideint 779934536. -76562645.7 -> -10
+xmul088 multiply 779934536. -76562645.7 -> -5.97138515E+16 Inexact Rounded
+xpow088 power 779934536. -76562646 -> 3.36739063E-680799501 Inexact Rounded
+xrem088 remainder 779934536. -76562645.7 -> 14308079.0
+xsub088 subtract 779934536. -76562645.7 -> 856497182 Inexact Rounded
+xadd089 add -4820.95451 3516234.99E+303303176 -> 3.51623499E+303303182 Inexact Rounded
+xcom089 compare -4820.95451 3516234.99E+303303176 -> -1
+xdiv089 divide -4820.95451 3516234.99E+303303176 -> -1.37105584E-303303179 Inexact Rounded
+xdvi089 divideint -4820.95451 3516234.99E+303303176 -> -0
+xmul089 multiply -4820.95451 3516234.99E+303303176 -> -1.69516089E+303303186 Inexact Rounded
+xpow089 power -4820.95451 4 -> 5.40172082E+14 Inexact Rounded
+xrem089 remainder -4820.95451 3516234.99E+303303176 -> -4820.95451
+xsub089 subtract -4820.95451 3516234.99E+303303176 -> -3.51623499E+303303182 Inexact Rounded
+xadd090 add 69355976.9 -9.57838562E+758804984 -> -9.57838562E+758804984 Inexact Rounded
+xcom090 compare 69355976.9 -9.57838562E+758804984 -> 1
+xdiv090 divide 69355976.9 -9.57838562E+758804984 -> -7.24088376E-758804978 Inexact Rounded
+xdvi090 divideint 69355976.9 -9.57838562E+758804984 -> -0
+xmul090 multiply 69355976.9 -9.57838562E+758804984 -> -6.64318292E+758804992 Inexact Rounded
+xpow090 power 69355976.9 -10 -> 3.88294346E-79 Inexact Rounded
+xrem090 remainder 69355976.9 -9.57838562E+758804984 -> 69355976.9
+xsub090 subtract 69355976.9 -9.57838562E+758804984 -> 9.57838562E+758804984 Inexact Rounded
+xadd091 add -12672093.1 8569.78255E-382866025 -> -12672093.1 Inexact Rounded
+xcom091 compare -12672093.1 8569.78255E-382866025 -> -1
+xdiv091 divide -12672093.1 8569.78255E-382866025 -> -1.47869482E+382866028 Inexact Rounded
+xdvi091 divideint -12672093.1 8569.78255E-382866025 -> NaN Division_impossible
+xmul091 multiply -12672093.1 8569.78255E-382866025 -> -1.08597082E-382866014 Inexact Rounded
+xpow091 power -12672093.1 9 -> -8.42626658E+63 Inexact Rounded
+xrem091 remainder -12672093.1 8569.78255E-382866025 -> NaN Division_impossible
+xsub091 subtract -12672093.1 8569.78255E-382866025 -> -12672093.1 Inexact Rounded
+xadd092 add -5910750.2 66150383E-662459241 -> -5910750.20 Inexact Rounded
+xcom092 compare -5910750.2 66150383E-662459241 -> -1
+xdiv092 divide -5910750.2 66150383E-662459241 -> -8.93532272E+662459239 Inexact Rounded
+xdvi092 divideint -5910750.2 66150383E-662459241 -> NaN Division_impossible
+xmul092 multiply -5910750.2 66150383E-662459241 -> -3.90998390E-662459227 Inexact Rounded
+xpow092 power -5910750.2 7 -> -2.52056696E+47 Inexact Rounded
+xrem092 remainder -5910750.2 66150383E-662459241 -> NaN Division_impossible
+xsub092 subtract -5910750.2 66150383E-662459241 -> -5910750.20 Inexact Rounded
+xadd093 add -532577268.E-163806629 -240650398E-650110558 -> -5.32577268E-163806621 Inexact Rounded
+xcom093 compare -532577268.E-163806629 -240650398E-650110558 -> -1
+xdiv093 divide -532577268.E-163806629 -240650398E-650110558 -> 2.21307454E+486303929 Inexact Rounded
+xdvi093 divideint -532577268.E-163806629 -240650398E-650110558 -> NaN Division_impossible
+xmul093 multiply -532577268.E-163806629 -240650398E-650110558 -> 1.28164932E-813917170 Inexact Rounded
+xpow093 power -532577268.E-163806629 -2 -> 3.52561389E+327613240 Inexact Rounded
+xrem093 remainder -532577268.E-163806629 -240650398E-650110558 -> NaN Division_impossible
+xsub093 subtract -532577268.E-163806629 -240650398E-650110558 -> -5.32577268E-163806621 Inexact Rounded
+xadd094 add -671.507198E-908587890 3057429.32E-555230623 -> 3.05742932E-555230617 Inexact Rounded
+xcom094 compare -671.507198E-908587890 3057429.32E-555230623 -> -1
+xdiv094 divide -671.507198E-908587890 3057429.32E-555230623 -> -2.19631307E-353357271 Inexact Rounded
+xdvi094 divideint -671.507198E-908587890 3057429.32E-555230623 -> -0
+xmul094 multiply -671.507198E-908587890 3057429.32E-555230623 -> -0E-1000000007 Underflow Subnormal Inexact Rounded
+xpow094 power -671.507198E-908587890 3 -> -0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem094 remainder -671.507198E-908587890 3057429.32E-555230623 -> -6.71507198E-908587888
+xsub094 subtract -671.507198E-908587890 3057429.32E-555230623 -> -3.05742932E-555230617 Inexact Rounded
+xadd095 add -294.994352E+346452027 -6061853.0 -> -2.94994352E+346452029 Inexact Rounded
+xcom095 compare -294.994352E+346452027 -6061853.0 -> -1
+xdiv095 divide -294.994352E+346452027 -6061853.0 -> 4.86640557E+346452022 Inexact Rounded
+xdvi095 divideint -294.994352E+346452027 -6061853.0 -> NaN Division_impossible
+xmul095 multiply -294.994352E+346452027 -6061853.0 -> 1.78821240E+346452036 Inexact Rounded
+xpow095 power -294.994352E+346452027 -6061853 -> -0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem095 remainder -294.994352E+346452027 -6061853.0 -> NaN Division_impossible
+xsub095 subtract -294.994352E+346452027 -6061853.0 -> -2.94994352E+346452029 Inexact Rounded
+xadd096 add 329579114 146780548. -> 476359662
+xcom096 compare 329579114 146780548. -> 1
+xdiv096 divide 329579114 146780548. -> 2.24538686 Inexact Rounded
+xdvi096 divideint 329579114 146780548. -> 2
+xmul096 multiply 329579114 146780548. -> 4.83758030E+16 Inexact Rounded
+xpow096 power 329579114 146780548 -> Infinity Overflow Inexact Rounded
+xrem096 remainder 329579114 146780548. -> 36018018
+xsub096 subtract 329579114 146780548. -> 182798566
+xadd097 add -789904.686E-217225000 -1991.07181E-84080059 -> -1.99107181E-84080056 Inexact Rounded
+xcom097 compare -789904.686E-217225000 -1991.07181E-84080059 -> 1
+xdiv097 divide -789904.686E-217225000 -1991.07181E-84080059 -> 3.96723354E-133144939 Inexact Rounded
+xdvi097 divideint -789904.686E-217225000 -1991.07181E-84080059 -> 0
+xmul097 multiply -789904.686E-217225000 -1991.07181E-84080059 -> 1.57275695E-301305050 Inexact Rounded
+xpow097 power -789904.686E-217225000 -2 -> 1.60269403E+434449988 Inexact Rounded
+xrem097 remainder -789904.686E-217225000 -1991.07181E-84080059 -> -7.89904686E-217224995
+xsub097 subtract -789904.686E-217225000 -1991.07181E-84080059 -> 1.99107181E-84080056 Inexact Rounded
+xadd098 add 59893.3544 -408595868 -> -408535975 Inexact Rounded
+xcom098 compare 59893.3544 -408595868 -> 1
+xdiv098 divide 59893.3544 -408595868 -> -0.000146583358 Inexact Rounded
+xdvi098 divideint 59893.3544 -408595868 -> -0
+xmul098 multiply 59893.3544 -408595868 -> -2.44721771E+13 Inexact Rounded
+xpow098 power 59893.3544 -408595868 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem098 remainder 59893.3544 -408595868 -> 59893.3544
+xsub098 subtract 59893.3544 -408595868 -> 408655761 Inexact Rounded
+xadd099 add 129.878613 -54652.7288E-963564940 -> 129.878613 Inexact Rounded
+xcom099 compare 129.878613 -54652.7288E-963564940 -> 1
+xdiv099 divide 129.878613 -54652.7288E-963564940 -> -2.37643418E+963564937 Inexact Rounded
+xdvi099 divideint 129.878613 -54652.7288E-963564940 -> NaN Division_impossible
+xmul099 multiply 129.878613 -54652.7288E-963564940 -> -7.09822061E-963564934 Inexact Rounded
+xpow099 power 129.878613 -5 -> 2.70590029E-11 Inexact Rounded
+xrem099 remainder 129.878613 -54652.7288E-963564940 -> NaN Division_impossible
+xsub099 subtract 129.878613 -54652.7288E-963564940 -> 129.878613 Inexact Rounded
+xadd100 add 9866.99208 708756501. -> 708766368 Inexact Rounded
+xcom100 compare 9866.99208 708756501. -> -1
+xdiv100 divide 9866.99208 708756501. -> 0.0000139215543 Inexact Rounded
+xdvi100 divideint 9866.99208 708756501. -> 0
+xmul100 multiply 9866.99208 708756501. -> 6.99329478E+12 Inexact Rounded
+xpow100 power 9866.99208 708756501 -> Infinity Overflow Inexact Rounded
+xrem100 remainder 9866.99208 708756501. -> 9866.99208
+xsub100 subtract 9866.99208 708756501. -> -708746634 Inexact Rounded
+xadd101 add -78810.6297 -399884.68 -> -478695.310 Inexact Rounded
+xcom101 compare -78810.6297 -399884.68 -> 1
+xdiv101 divide -78810.6297 -399884.68 -> 0.197083393 Inexact Rounded
+xdvi101 divideint -78810.6297 -399884.68 -> 0
+xmul101 multiply -78810.6297 -399884.68 -> 3.15151634E+10 Inexact Rounded
+xpow101 power -78810.6297 -399885 -> -1.54252408E-1958071 Inexact Rounded
+xrem101 remainder -78810.6297 -399884.68 -> -78810.6297
+xsub101 subtract -78810.6297 -399884.68 -> 321074.050 Inexact Rounded
+xadd102 add 409189761 -771.471460 -> 409188990 Inexact Rounded
+xcom102 compare 409189761 -771.471460 -> 1
+xdiv102 divide 409189761 -771.471460 -> -530401.683 Inexact Rounded
+xdvi102 divideint 409189761 -771.471460 -> -530401
+xmul102 multiply 409189761 -771.471460 -> -3.15678222E+11 Inexact Rounded
+xpow102 power 409189761 -771 -> 1.60698414E-6640 Inexact Rounded
+xrem102 remainder 409189761 -771.471460 -> 527.144540
+xsub102 subtract 409189761 -771.471460 -> 409190532 Inexact Rounded
+xadd103 add -1.68748838 460.46924 -> 458.781752 Inexact Rounded
+xcom103 compare -1.68748838 460.46924 -> -1
+xdiv103 divide -1.68748838 460.46924 -> -0.00366471467 Inexact Rounded
+xdvi103 divideint -1.68748838 460.46924 -> -0
+xmul103 multiply -1.68748838 460.46924 -> -777.036492 Inexact Rounded
+xpow103 power -1.68748838 460 -> 3.39440648E+104 Inexact Rounded
+xrem103 remainder -1.68748838 460.46924 -> -1.68748838
+xsub103 subtract -1.68748838 460.46924 -> -462.156728 Inexact Rounded
+xadd104 add 553527296. -7924.40185 -> 553519372 Inexact Rounded
+xcom104 compare 553527296. -7924.40185 -> 1
+xdiv104 divide 553527296. -7924.40185 -> -69850.9877 Inexact Rounded
+xdvi104 divideint 553527296. -7924.40185 -> -69850
+xmul104 multiply 553527296. -7924.40185 -> -4.38637273E+12 Inexact Rounded
+xpow104 power 553527296. -7924 -> 2.32397213E-69281 Inexact Rounded
+xrem104 remainder 553527296. -7924.40185 -> 7826.77750
+xsub104 subtract 553527296. -7924.40185 -> 553535220 Inexact Rounded
+xadd105 add -38.7465207 64936.2942 -> 64897.5477 Inexact Rounded
+xcom105 compare -38.7465207 64936.2942 -> -1
+xdiv105 divide -38.7465207 64936.2942 -> -0.000596685123 Inexact Rounded
+xdvi105 divideint -38.7465207 64936.2942 -> -0
+xmul105 multiply -38.7465207 64936.2942 -> -2516055.47 Inexact Rounded
+xpow105 power -38.7465207 64936 -> 3.01500762E+103133 Inexact Rounded
+xrem105 remainder -38.7465207 64936.2942 -> -38.7465207
+xsub105 subtract -38.7465207 64936.2942 -> -64975.0407 Inexact Rounded
+xadd106 add -201075.248 845.663928 -> -200229.584 Inexact Rounded
+xcom106 compare -201075.248 845.663928 -> -1
+xdiv106 divide -201075.248 845.663928 -> -237.772053 Inexact Rounded
+xdvi106 divideint -201075.248 845.663928 -> -237
+xmul106 multiply -201075.248 845.663928 -> -170042084 Inexact Rounded
+xpow106 power -201075.248 846 -> 4.37911767E+4486 Inexact Rounded
+xrem106 remainder -201075.248 845.663928 -> -652.897064
+xsub106 subtract -201075.248 845.663928 -> -201920.912 Inexact Rounded
+xadd107 add 91048.4559 75953609.3 -> 76044657.8 Inexact Rounded
+xcom107 compare 91048.4559 75953609.3 -> -1
+xdiv107 divide 91048.4559 75953609.3 -> 0.00119873771 Inexact Rounded
+xdvi107 divideint 91048.4559 75953609.3 -> 0
+xmul107 multiply 91048.4559 75953609.3 -> 6.91545885E+12 Inexact Rounded
+xpow107 power 91048.4559 75953609 -> 6.94467746E+376674650 Inexact Rounded
+xrem107 remainder 91048.4559 75953609.3 -> 91048.4559
+xsub107 subtract 91048.4559 75953609.3 -> -75862560.8 Inexact Rounded
+xadd108 add 6898273.86E-252097460 15.3456196 -> 15.3456196 Inexact Rounded
+xcom108 compare 6898273.86E-252097460 15.3456196 -> -1
+xdiv108 divide 6898273.86E-252097460 15.3456196 -> 4.49527229E-252097455 Inexact Rounded
+xdvi108 divideint 6898273.86E-252097460 15.3456196 -> 0
+xmul108 multiply 6898273.86E-252097460 15.3456196 -> 1.05858287E-252097452 Inexact Rounded
+xpow108 power 6898273.86E-252097460 15 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem108 remainder 6898273.86E-252097460 15.3456196 -> 6.89827386E-252097454
+xsub108 subtract 6898273.86E-252097460 15.3456196 -> -15.3456196 Inexact Rounded
+xadd109 add 88.4370343 -980709105E-869899289 -> 88.4370343 Inexact Rounded
+xcom109 compare 88.4370343 -980709105E-869899289 -> 1
+xdiv109 divide 88.4370343 -980709105E-869899289 -> -9.01766220E+869899281 Inexact Rounded
+xdvi109 divideint 88.4370343 -980709105E-869899289 -> NaN Division_impossible
+xmul109 multiply 88.4370343 -980709105E-869899289 -> -8.67310048E-869899279 Inexact Rounded
+xpow109 power 88.4370343 -10 -> 3.41710479E-20 Inexact Rounded
+xrem109 remainder 88.4370343 -980709105E-869899289 -> NaN Division_impossible
+xsub109 subtract 88.4370343 -980709105E-869899289 -> 88.4370343 Inexact Rounded
+xadd110 add -17643.39 2.0352568E+304871331 -> 2.03525680E+304871331 Inexact Rounded
+xcom110 compare -17643.39 2.0352568E+304871331 -> -1
+xdiv110 divide -17643.39 2.0352568E+304871331 -> -8.66887658E-304871328 Inexact Rounded
+xdvi110 divideint -17643.39 2.0352568E+304871331 -> -0
+xmul110 multiply -17643.39 2.0352568E+304871331 -> -3.59088295E+304871335 Inexact Rounded
+xpow110 power -17643.39 2 -> 311289211 Inexact Rounded
+xrem110 remainder -17643.39 2.0352568E+304871331 -> -17643.39
+xsub110 subtract -17643.39 2.0352568E+304871331 -> -2.03525680E+304871331 Inexact Rounded
+xadd111 add 4589785.16 7459.04237 -> 4597244.20 Inexact Rounded
+xcom111 compare 4589785.16 7459.04237 -> 1
+xdiv111 divide 4589785.16 7459.04237 -> 615.331692 Inexact Rounded
+xdvi111 divideint 4589785.16 7459.04237 -> 615
+xmul111 multiply 4589785.16 7459.04237 -> 3.42354020E+10 Inexact Rounded
+xpow111 power 4589785.16 7459 -> 2.03795258E+49690 Inexact Rounded
+xrem111 remainder 4589785.16 7459.04237 -> 2474.10245
+xsub111 subtract 4589785.16 7459.04237 -> 4582326.12 Inexact Rounded
+xadd112 add -51.1632090E-753968082 8.96207471E-585797887 -> 8.96207471E-585797887 Inexact Rounded
+xcom112 compare -51.1632090E-753968082 8.96207471E-585797887 -> -1
+xdiv112 divide -51.1632090E-753968082 8.96207471E-585797887 -> -5.70885768E-168170195 Inexact Rounded
+xdvi112 divideint -51.1632090E-753968082 8.96207471E-585797887 -> -0
+xmul112 multiply -51.1632090E-753968082 8.96207471E-585797887 -> -0E-1000000007 Underflow Subnormal Inexact Rounded
+xpow112 power -51.1632090E-753968082 9 -> -0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem112 remainder -51.1632090E-753968082 8.96207471E-585797887 -> -5.11632090E-753968081
+xsub112 subtract -51.1632090E-753968082 8.96207471E-585797887 -> -8.96207471E-585797887 Inexact Rounded
+xadd113 add 982.217817 7224909.4E-45243816 -> 982.217817 Inexact Rounded
+xcom113 compare 982.217817 7224909.4E-45243816 -> 1
+xdiv113 divide 982.217817 7224909.4E-45243816 -> 1.35948807E+45243812 Inexact Rounded
+xdvi113 divideint 982.217817 7224909.4E-45243816 -> NaN Division_impossible
+xmul113 multiply 982.217817 7224909.4E-45243816 -> 7.09643474E-45243807 Inexact Rounded
+xpow113 power 982.217817 7 -> 8.81971709E+20 Inexact Rounded
+xrem113 remainder 982.217817 7224909.4E-45243816 -> NaN Division_impossible
+xsub113 subtract 982.217817 7224909.4E-45243816 -> 982.217817 Inexact Rounded
+xadd114 add 503712056. -57490703.5E+924890183 -> -5.74907035E+924890190 Inexact Rounded
+xcom114 compare 503712056. -57490703.5E+924890183 -> 1
+xdiv114 divide 503712056. -57490703.5E+924890183 -> -8.76162623E-924890183 Inexact Rounded
+xdvi114 divideint 503712056. -57490703.5E+924890183 -> -0
+xmul114 multiply 503712056. -57490703.5E+924890183 -> -2.89587605E+924890199 Inexact Rounded
+xpow114 power 503712056. -6 -> 6.12217764E-53 Inexact Rounded
+xrem114 remainder 503712056. -57490703.5E+924890183 -> 503712056
+xsub114 subtract 503712056. -57490703.5E+924890183 -> 5.74907035E+924890190 Inexact Rounded
+xadd115 add 883.849223 249259171 -> 249260055 Inexact Rounded
+xcom115 compare 883.849223 249259171 -> -1
+xdiv115 divide 883.849223 249259171 -> 0.00000354590453 Inexact Rounded
+xdvi115 divideint 883.849223 249259171 -> 0
+xmul115 multiply 883.849223 249259171 -> 2.20307525E+11 Inexact Rounded
+xpow115 power 883.849223 249259171 -> 5.15642844E+734411783 Inexact Rounded
+xrem115 remainder 883.849223 249259171 -> 883.849223
+xsub115 subtract 883.849223 249259171 -> -249258287 Inexact Rounded
+xadd116 add 245.092853E+872642874 828195.152E+419771532 -> 2.45092853E+872642876 Inexact Rounded
+xcom116 compare 245.092853E+872642874 828195.152E+419771532 -> 1
+xdiv116 divide 245.092853E+872642874 828195.152E+419771532 -> 2.95936112E+452871338 Inexact Rounded
+xdvi116 divideint 245.092853E+872642874 828195.152E+419771532 -> NaN Division_impossible
+xmul116 multiply 245.092853E+872642874 828195.152E+419771532 -> Infinity Inexact Overflow Rounded
+xpow116 power 245.092853E+872642874 8 -> Infinity Overflow Inexact Rounded
+xrem116 remainder 245.092853E+872642874 828195.152E+419771532 -> NaN Division_impossible
+xsub116 subtract 245.092853E+872642874 828195.152E+419771532 -> 2.45092853E+872642876 Inexact Rounded
+xadd117 add -83658638.6E+728551928 2952478.42 -> -8.36586386E+728551935 Inexact Rounded
+xcom117 compare -83658638.6E+728551928 2952478.42 -> -1
+xdiv117 divide -83658638.6E+728551928 2952478.42 -> -2.83350551E+728551929 Inexact Rounded
+xdvi117 divideint -83658638.6E+728551928 2952478.42 -> NaN Division_impossible
+xmul117 multiply -83658638.6E+728551928 2952478.42 -> -2.47000325E+728551942 Inexact Rounded
+xpow117 power -83658638.6E+728551928 2952478 -> Infinity Overflow Inexact Rounded
+xrem117 remainder -83658638.6E+728551928 2952478.42 -> NaN Division_impossible
+xsub117 subtract -83658638.6E+728551928 2952478.42 -> -8.36586386E+728551935 Inexact Rounded
+xadd118 add -6291780.97 269967.394E-22000817 -> -6291780.97 Inexact Rounded
+xcom118 compare -6291780.97 269967.394E-22000817 -> -1
+xdiv118 divide -6291780.97 269967.394E-22000817 -> -2.33057069E+22000818 Inexact Rounded
+xdvi118 divideint -6291780.97 269967.394E-22000817 -> NaN Division_impossible
+xmul118 multiply -6291780.97 269967.394E-22000817 -> -1.69857571E-22000805 Inexact Rounded
+xpow118 power -6291780.97 3 -> -2.49069636E+20 Inexact Rounded
+xrem118 remainder -6291780.97 269967.394E-22000817 -> NaN Division_impossible
+xsub118 subtract -6291780.97 269967.394E-22000817 -> -6291780.97 Inexact Rounded
+xadd119 add 978571348.E+222382547 6006.19370 -> 9.78571348E+222382555 Inexact Rounded
+xcom119 compare 978571348.E+222382547 6006.19370 -> 1
+xdiv119 divide 978571348.E+222382547 6006.19370 -> 1.62927038E+222382552 Inexact Rounded
+xdvi119 divideint 978571348.E+222382547 6006.19370 -> NaN Division_impossible
+xmul119 multiply 978571348.E+222382547 6006.19370 -> 5.87748907E+222382559 Inexact Rounded
+xpow119 power 978571348.E+222382547 6006 -> Infinity Overflow Inexact Rounded
+xrem119 remainder 978571348.E+222382547 6006.19370 -> NaN Division_impossible
+xsub119 subtract 978571348.E+222382547 6006.19370 -> 9.78571348E+222382555 Inexact Rounded
+xadd120 add 14239029. -36527.2221 -> 14202501.8 Inexact Rounded
+xcom120 compare 14239029. -36527.2221 -> 1
+xdiv120 divide 14239029. -36527.2221 -> -389.819652 Inexact Rounded
+xdvi120 divideint 14239029. -36527.2221 -> -389
+xmul120 multiply 14239029. -36527.2221 -> -5.20112175E+11 Inexact Rounded
+xpow120 power 14239029. -36527 -> 6.64292731E-261296 Inexact Rounded
+xrem120 remainder 14239029. -36527.2221 -> 29939.6031
+xsub120 subtract 14239029. -36527.2221 -> 14275556.2 Inexact Rounded
+xadd121 add 72333.2654E-544425548 -690.664836E+662155120 -> -6.90664836E+662155122 Inexact Rounded
+xcom121 compare 72333.2654E-544425548 -690.664836E+662155120 -> 1
+xdiv121 divide 72333.2654E-544425548 -690.664836E+662155120 -> -0E-1000000007 Inexact Rounded Underflow Subnormal
+xdvi121 divideint 72333.2654E-544425548 -690.664836E+662155120 -> -0
+xmul121 multiply 72333.2654E-544425548 -690.664836E+662155120 -> -4.99580429E+117729579 Inexact Rounded
+xpow121 power 72333.2654E-544425548 -7 -> Infinity Overflow Inexact Rounded
+xrem121 remainder 72333.2654E-544425548 -690.664836E+662155120 -> 7.23332654E-544425544
+xsub121 subtract 72333.2654E-544425548 -690.664836E+662155120 -> 6.90664836E+662155122 Inexact Rounded
+xadd122 add -37721.1567E-115787341 -828949864E-76251747 -> -8.28949864E-76251739 Inexact Rounded
+xcom122 compare -37721.1567E-115787341 -828949864E-76251747 -> 1
+xdiv122 divide -37721.1567E-115787341 -828949864E-76251747 -> 4.55047505E-39535599 Inexact Rounded
+xdvi122 divideint -37721.1567E-115787341 -828949864E-76251747 -> 0
+xmul122 multiply -37721.1567E-115787341 -828949864E-76251747 -> 3.12689477E-192039075 Inexact Rounded
+xpow122 power -37721.1567E-115787341 -8 -> 2.43960765E+926298691 Inexact Rounded
+xrem122 remainder -37721.1567E-115787341 -828949864E-76251747 -> -3.77211567E-115787337
+xsub122 subtract -37721.1567E-115787341 -828949864E-76251747 -> 8.28949864E-76251739 Inexact Rounded
+xadd123 add -2078852.83E-647080089 -119779858.E+734665461 -> -1.19779858E+734665469 Inexact Rounded
+xcom123 compare -2078852.83E-647080089 -119779858.E+734665461 -> 1
+xdiv123 divide -2078852.83E-647080089 -119779858.E+734665461 -> 0E-1000000007 Inexact Rounded Underflow Subnormal
+xdvi123 divideint -2078852.83E-647080089 -119779858.E+734665461 -> 0
+xmul123 multiply -2078852.83E-647080089 -119779858.E+734665461 -> 2.49004697E+87585386 Inexact Rounded
+xpow123 power -2078852.83E-647080089 -1 -> -4.81034533E+647080082 Inexact Rounded
+xrem123 remainder -2078852.83E-647080089 -119779858.E+734665461 -> -2.07885283E-647080083
+xsub123 subtract -2078852.83E-647080089 -119779858.E+734665461 -> 1.19779858E+734665469 Inexact Rounded
+xadd124 add -79145.3625 -7718.57307 -> -86863.9356 Inexact Rounded
+xcom124 compare -79145.3625 -7718.57307 -> -1
+xdiv124 divide -79145.3625 -7718.57307 -> 10.2538852 Inexact Rounded
+xdvi124 divideint -79145.3625 -7718.57307 -> 10
+xmul124 multiply -79145.3625 -7718.57307 -> 610889264 Inexact Rounded
+xpow124 power -79145.3625 -7719 -> -1.13181941E-37811 Inexact Rounded
+xrem124 remainder -79145.3625 -7718.57307 -> -1959.63180
+xsub124 subtract -79145.3625 -7718.57307 -> -71426.7894 Inexact Rounded
+xadd125 add 2103890.49E+959247237 20024.3017 -> 2.10389049E+959247243 Inexact Rounded
+xcom125 compare 2103890.49E+959247237 20024.3017 -> 1
+xdiv125 divide 2103890.49E+959247237 20024.3017 -> 1.05066859E+959247239 Inexact Rounded
+xdvi125 divideint 2103890.49E+959247237 20024.3017 -> NaN Division_impossible
+xmul125 multiply 2103890.49E+959247237 20024.3017 -> 4.21289379E+959247247 Inexact Rounded
+xpow125 power 2103890.49E+959247237 20024 -> Infinity Overflow Inexact Rounded
+xrem125 remainder 2103890.49E+959247237 20024.3017 -> NaN Division_impossible
+xsub125 subtract 2103890.49E+959247237 20024.3017 -> 2.10389049E+959247243 Inexact Rounded
+xadd126 add 911249557 79810804.9 -> 991060362 Inexact Rounded
+xcom126 compare 911249557 79810804.9 -> 1
+xdiv126 divide 911249557 79810804.9 -> 11.4176214 Inexact Rounded
+xdvi126 divideint 911249557 79810804.9 -> 11
+xmul126 multiply 911249557 79810804.9 -> 7.27275606E+16 Inexact Rounded
+xpow126 power 911249557 79810805 -> 6.77595741E+715075867 Inexact Rounded
+xrem126 remainder 911249557 79810804.9 -> 33330703.1
+xsub126 subtract 911249557 79810804.9 -> 831438752 Inexact Rounded
+xadd127 add 341134.994 3.37486292 -> 341138.369 Inexact Rounded
+xcom127 compare 341134.994 3.37486292 -> 1
+xdiv127 divide 341134.994 3.37486292 -> 101081.141 Inexact Rounded
+xdvi127 divideint 341134.994 3.37486292 -> 101081
+xmul127 multiply 341134.994 3.37486292 -> 1151283.84 Inexact Rounded
+xpow127 power 341134.994 3 -> 3.96989314E+16 Inexact Rounded
+xrem127 remainder 341134.994 3.37486292 -> 0.47518348
+xsub127 subtract 341134.994 3.37486292 -> 341131.619 Inexact Rounded
+xadd128 add 244.23634 512706190E-341459836 -> 244.236340 Inexact Rounded
+xcom128 compare 244.23634 512706190E-341459836 -> 1
+xdiv128 divide 244.23634 512706190E-341459836 -> 4.76367059E+341459829 Inexact Rounded
+xdvi128 divideint 244.23634 512706190E-341459836 -> NaN Division_impossible
+xmul128 multiply 244.23634 512706190E-341459836 -> 1.25221483E-341459825 Inexact Rounded
+xpow128 power 244.23634 5 -> 8.69063312E+11 Inexact Rounded
+xrem128 remainder 244.23634 512706190E-341459836 -> NaN Division_impossible
+xsub128 subtract 244.23634 512706190E-341459836 -> 244.236340 Inexact Rounded
+xadd129 add -9.22783849E+171585954 -99.0946800 -> -9.22783849E+171585954 Inexact Rounded
+xcom129 compare -9.22783849E+171585954 -99.0946800 -> -1
+xdiv129 divide -9.22783849E+171585954 -99.0946800 -> 9.31214318E+171585952 Inexact Rounded
+xdvi129 divideint -9.22783849E+171585954 -99.0946800 -> NaN Division_impossible
+xmul129 multiply -9.22783849E+171585954 -99.0946800 -> 9.14429702E+171585956 Inexact Rounded
+xpow129 power -9.22783849E+171585954 -99 -> -0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem129 remainder -9.22783849E+171585954 -99.0946800 -> NaN Division_impossible
+xsub129 subtract -9.22783849E+171585954 -99.0946800 -> -9.22783849E+171585954 Inexact Rounded
+xadd130 add 699631.893 -226.423958 -> 699405.469 Inexact Rounded
+xcom130 compare 699631.893 -226.423958 -> 1
+xdiv130 divide 699631.893 -226.423958 -> -3089.91990 Inexact Rounded
+xdvi130 divideint 699631.893 -226.423958 -> -3089
+xmul130 multiply 699631.893 -226.423958 -> -158413422 Inexact Rounded
+xpow130 power 699631.893 -226 -> 1.14675511E-1321 Inexact Rounded
+xrem130 remainder 699631.893 -226.423958 -> 208.286738
+xsub130 subtract 699631.893 -226.423958 -> 699858.317 Inexact Rounded
+xadd131 add -249350139.E-571793673 775732428. -> 775732428 Inexact Rounded
+xcom131 compare -249350139.E-571793673 775732428. -> -1
+xdiv131 divide -249350139.E-571793673 775732428. -> -3.21438334E-571793674 Inexact Rounded
+xdvi131 divideint -249350139.E-571793673 775732428. -> -0
+xmul131 multiply -249350139.E-571793673 775732428. -> -1.93428989E-571793656 Inexact Rounded
+xpow131 power -249350139.E-571793673 775732428 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem131 remainder -249350139.E-571793673 775732428. -> -2.49350139E-571793665
+xsub131 subtract -249350139.E-571793673 775732428. -> -775732428 Inexact Rounded
+xadd132 add 5.11629020 -480.53194 -> -475.415650 Inexact Rounded
+xcom132 compare 5.11629020 -480.53194 -> 1
+xdiv132 divide 5.11629020 -480.53194 -> -0.0106471387 Inexact Rounded
+xdvi132 divideint 5.11629020 -480.53194 -> -0
+xmul132 multiply 5.11629020 -480.53194 -> -2458.54086 Inexact Rounded
+xpow132 power 5.11629020 -481 -> 9.83021951E-342 Inexact Rounded
+xrem132 remainder 5.11629020 -480.53194 -> 5.11629020
+xsub132 subtract 5.11629020 -480.53194 -> 485.648230 Inexact Rounded
+xadd133 add -8.23352673E-446723147 -530710.866 -> -530710.866 Inexact Rounded
+xcom133 compare -8.23352673E-446723147 -530710.866 -> 1
+xdiv133 divide -8.23352673E-446723147 -530710.866 -> 1.55141476E-446723152 Inexact Rounded
+xdvi133 divideint -8.23352673E-446723147 -530710.866 -> 0
+xmul133 multiply -8.23352673E-446723147 -530710.866 -> 4.36962210E-446723141 Inexact Rounded
+xpow133 power -8.23352673E-446723147 -530711 -> -Infinity Overflow Inexact Rounded
+xrem133 remainder -8.23352673E-446723147 -530710.866 -> -8.23352673E-446723147
+xsub133 subtract -8.23352673E-446723147 -530710.866 -> 530710.866 Inexact Rounded
+xadd134 add 7.0598608 -95908.35 -> -95901.2901 Inexact Rounded
+xcom134 compare 7.0598608 -95908.35 -> 1
+xdiv134 divide 7.0598608 -95908.35 -> -0.0000736104917 Inexact Rounded
+xdvi134 divideint 7.0598608 -95908.35 -> -0
+xmul134 multiply 7.0598608 -95908.35 -> -677099.601 Inexact Rounded
+xpow134 power 7.0598608 -95908 -> 4.57073877E-81407 Inexact Rounded
+xrem134 remainder 7.0598608 -95908.35 -> 7.0598608
+xsub134 subtract 7.0598608 -95908.35 -> 95915.4099 Inexact Rounded
+xadd135 add -7.91189845E+207202706 1532.71847E+509944335 -> 1.53271847E+509944338 Inexact Rounded
+xcom135 compare -7.91189845E+207202706 1532.71847E+509944335 -> -1
+xdiv135 divide -7.91189845E+207202706 1532.71847E+509944335 -> -5.16200372E-302741632 Inexact Rounded
+xdvi135 divideint -7.91189845E+207202706 1532.71847E+509944335 -> -0
+xmul135 multiply -7.91189845E+207202706 1532.71847E+509944335 -> -1.21267129E+717147045 Inexact Rounded
+xpow135 power -7.91189845E+207202706 2 -> 6.25981371E+414405413 Inexact Rounded
+xrem135 remainder -7.91189845E+207202706 1532.71847E+509944335 -> -7.91189845E+207202706
+xsub135 subtract -7.91189845E+207202706 1532.71847E+509944335 -> -1.53271847E+509944338 Inexact Rounded
+xadd136 add 208839370.E-215147432 -75.9420559 -> -75.9420559 Inexact Rounded
+xcom136 compare 208839370.E-215147432 -75.9420559 -> 1
+xdiv136 divide 208839370.E-215147432 -75.9420559 -> -2.74998310E-215147426 Inexact Rounded
+xdvi136 divideint 208839370.E-215147432 -75.9420559 -> -0
+xmul136 multiply 208839370.E-215147432 -75.9420559 -> -1.58596911E-215147422 Inexact Rounded
+xpow136 power 208839370.E-215147432 -76 -> Infinity Overflow Inexact Rounded
+xrem136 remainder 208839370.E-215147432 -75.9420559 -> 2.08839370E-215147424
+xsub136 subtract 208839370.E-215147432 -75.9420559 -> 75.9420559 Inexact Rounded
+xadd137 add 427.754244E-353328369 4705.0796 -> 4705.07960 Inexact Rounded
+xcom137 compare 427.754244E-353328369 4705.0796 -> -1
+xdiv137 divide 427.754244E-353328369 4705.0796 -> 9.09132853E-353328371 Inexact Rounded
+xdvi137 divideint 427.754244E-353328369 4705.0796 -> 0
+xmul137 multiply 427.754244E-353328369 4705.0796 -> 2.01261777E-353328363 Inexact Rounded
+xpow137 power 427.754244E-353328369 4705 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem137 remainder 427.754244E-353328369 4705.0796 -> 4.27754244E-353328367
+xsub137 subtract 427.754244E-353328369 4705.0796 -> -4705.07960 Inexact Rounded
+xadd138 add 44911.089 -95.1733605E-313081848 -> 44911.0890 Inexact Rounded
+xcom138 compare 44911.089 -95.1733605E-313081848 -> 1
+xdiv138 divide 44911.089 -95.1733605E-313081848 -> -4.71887183E+313081850 Inexact Rounded
+xdvi138 divideint 44911.089 -95.1733605E-313081848 -> NaN Division_impossible
+xmul138 multiply 44911.089 -95.1733605E-313081848 -> -4.27433926E-313081842 Inexact Rounded
+xpow138 power 44911.089 -10 -> 2.99546425E-47 Inexact Rounded
+xrem138 remainder 44911.089 -95.1733605E-313081848 -> NaN Division_impossible
+xsub138 subtract 44911.089 -95.1733605E-313081848 -> 44911.0890 Inexact Rounded
+xadd139 add 452371821. -4109709.19 -> 448262112 Inexact Rounded
+xcom139 compare 452371821. -4109709.19 -> 1
+xdiv139 divide 452371821. -4109709.19 -> -110.073925 Inexact Rounded
+xdvi139 divideint 452371821. -4109709.19 -> -110
+xmul139 multiply 452371821. -4109709.19 -> -1.85911663E+15 Inexact Rounded
+xpow139 power 452371821. -4109709 -> 1.15528807E-35571568 Inexact Rounded
+xrem139 remainder 452371821. -4109709.19 -> 303810.10
+xsub139 subtract 452371821. -4109709.19 -> 456481530 Inexact Rounded
+xadd140 add 94007.4392 -9467725.5E+681898234 -> -9.46772550E+681898240 Inexact Rounded
+xcom140 compare 94007.4392 -9467725.5E+681898234 -> 1
+xdiv140 divide 94007.4392 -9467725.5E+681898234 -> -9.92925272E-681898237 Inexact Rounded
+xdvi140 divideint 94007.4392 -9467725.5E+681898234 -> -0
+xmul140 multiply 94007.4392 -9467725.5E+681898234 -> -8.90036629E+681898245 Inexact Rounded
+xpow140 power 94007.4392 -9 -> 1.74397397E-45 Inexact Rounded
+xrem140 remainder 94007.4392 -9467725.5E+681898234 -> 94007.4392
+xsub140 subtract 94007.4392 -9467725.5E+681898234 -> 9.46772550E+681898240 Inexact Rounded
+xadd141 add 99147554.0E-751410586 38313.6423 -> 38313.6423 Inexact Rounded
+xcom141 compare 99147554.0E-751410586 38313.6423 -> -1
+xdiv141 divide 99147554.0E-751410586 38313.6423 -> 2.58778722E-751410583 Inexact Rounded
+xdvi141 divideint 99147554.0E-751410586 38313.6423 -> 0
+xmul141 multiply 99147554.0E-751410586 38313.6423 -> 3.79870392E-751410574 Inexact Rounded
+xpow141 power 99147554.0E-751410586 38314 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem141 remainder 99147554.0E-751410586 38313.6423 -> 9.91475540E-751410579
+xsub141 subtract 99147554.0E-751410586 38313.6423 -> -38313.6423 Inexact Rounded
+xadd142 add -7919.30254 -669.607854 -> -8588.91039 Inexact Rounded
+xcom142 compare -7919.30254 -669.607854 -> -1
+xdiv142 divide -7919.30254 -669.607854 -> 11.8267767 Inexact Rounded
+xdvi142 divideint -7919.30254 -669.607854 -> 11
+xmul142 multiply -7919.30254 -669.607854 -> 5302827.18 Inexact Rounded
+xpow142 power -7919.30254 -670 -> 7.58147724E-2613 Inexact Rounded
+xrem142 remainder -7919.30254 -669.607854 -> -553.616146
+xsub142 subtract -7919.30254 -669.607854 -> -7249.69469 Inexact Rounded
+xadd143 add 461.58280E+136110821 710666052.E-383754231 -> 4.61582800E+136110823 Inexact Rounded
+xcom143 compare 461.58280E+136110821 710666052.E-383754231 -> 1
+xdiv143 divide 461.58280E+136110821 710666052.E-383754231 -> 6.49507316E+519865045 Inexact Rounded
+xdvi143 divideint 461.58280E+136110821 710666052.E-383754231 -> NaN Division_impossible
+xmul143 multiply 461.58280E+136110821 710666052.E-383754231 -> 3.28031226E-247643399 Inexact Rounded
+xpow143 power 461.58280E+136110821 7 -> 4.46423781E+952775765 Inexact Rounded
+xrem143 remainder 461.58280E+136110821 710666052.E-383754231 -> NaN Division_impossible
+xsub143 subtract 461.58280E+136110821 710666052.E-383754231 -> 4.61582800E+136110823 Inexact Rounded
+xadd144 add 3455755.47E-112465506 771.674306 -> 771.674306 Inexact Rounded
+xcom144 compare 3455755.47E-112465506 771.674306 -> -1
+xdiv144 divide 3455755.47E-112465506 771.674306 -> 4.47825649E-112465503 Inexact Rounded
+xdvi144 divideint 3455755.47E-112465506 771.674306 -> 0
+xmul144 multiply 3455755.47E-112465506 771.674306 -> 2.66671770E-112465497 Inexact Rounded
+xpow144 power 3455755.47E-112465506 772 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem144 remainder 3455755.47E-112465506 771.674306 -> 3.45575547E-112465500
+xsub144 subtract 3455755.47E-112465506 771.674306 -> -771.674306 Inexact Rounded
+xadd145 add -477067757.E-961684940 7.70122608E-741072245 -> 7.70122608E-741072245 Inexact Rounded
+xcom145 compare -477067757.E-961684940 7.70122608E-741072245 -> -1
+xdiv145 divide -477067757.E-961684940 7.70122608E-741072245 -> -6.19469877E-220612688 Inexact Rounded
+xdvi145 divideint -477067757.E-961684940 7.70122608E-741072245 -> -0
+xmul145 multiply -477067757.E-961684940 7.70122608E-741072245 -> -0E-1000000007 Underflow Subnormal Inexact Rounded
+xpow145 power -477067757.E-961684940 8 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem145 remainder -477067757.E-961684940 7.70122608E-741072245 -> -4.77067757E-961684932
+xsub145 subtract -477067757.E-961684940 7.70122608E-741072245 -> -7.70122608E-741072245 Inexact Rounded
+xadd146 add 76482.352 8237806.8 -> 8314289.15 Inexact Rounded
+xcom146 compare 76482.352 8237806.8 -> -1
+xdiv146 divide 76482.352 8237806.8 -> 0.00928430999 Inexact Rounded
+xdvi146 divideint 76482.352 8237806.8 -> 0
+xmul146 multiply 76482.352 8237806.8 -> 6.30046839E+11 Inexact Rounded
+xpow146 power 76482.352 8237807 -> 8.44216559E+40229834 Inexact Rounded
+xrem146 remainder 76482.352 8237806.8 -> 76482.352
+xsub146 subtract 76482.352 8237806.8 -> -8161324.45 Inexact Rounded
+xadd147 add 1.21505164E-565556504 9.26146573 -> 9.26146573 Inexact Rounded
+xcom147 compare 1.21505164E-565556504 9.26146573 -> -1
+xdiv147 divide 1.21505164E-565556504 9.26146573 -> 1.31194314E-565556505 Inexact Rounded
+xdvi147 divideint 1.21505164E-565556504 9.26146573 -> 0
+xmul147 multiply 1.21505164E-565556504 9.26146573 -> 1.12531591E-565556503 Inexact Rounded
+xpow147 power 1.21505164E-565556504 9 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem147 remainder 1.21505164E-565556504 9.26146573 -> 1.21505164E-565556504
+xsub147 subtract 1.21505164E-565556504 9.26146573 -> -9.26146573 Inexact Rounded
+xadd148 add -8303060.25E-169894883 901561.985 -> 901561.985 Inexact Rounded
+xcom148 compare -8303060.25E-169894883 901561.985 -> -1
+xdiv148 divide -8303060.25E-169894883 901561.985 -> -9.20963881E-169894883 Inexact Rounded
+xdvi148 divideint -8303060.25E-169894883 901561.985 -> -0
+xmul148 multiply -8303060.25E-169894883 901561.985 -> -7.48572348E-169894871 Inexact Rounded
+xpow148 power -8303060.25E-169894883 901562 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem148 remainder -8303060.25E-169894883 901561.985 -> -8.30306025E-169894877
+xsub148 subtract -8303060.25E-169894883 901561.985 -> -901561.985 Inexact Rounded
+xadd149 add -592464.92 71445510.7 -> 70853045.8 Inexact Rounded
+xcom149 compare -592464.92 71445510.7 -> -1
+xdiv149 divide -592464.92 71445510.7 -> -0.00829254231 Inexact Rounded
+xdvi149 divideint -592464.92 71445510.7 -> -0
+xmul149 multiply -592464.92 71445510.7 -> -4.23289588E+13 Inexact Rounded
+xpow149 power -592464.92 71445511 -> -1.58269108E+412430832 Inexact Rounded
+xrem149 remainder -592464.92 71445510.7 -> -592464.92
+xsub149 subtract -592464.92 71445510.7 -> -72037975.6 Inexact Rounded
+xadd150 add -73774.4165 -39.8243027 -> -73814.2408 Inexact Rounded
+xcom150 compare -73774.4165 -39.8243027 -> -1
+xdiv150 divide -73774.4165 -39.8243027 -> 1852.49738 Inexact Rounded
+xdvi150 divideint -73774.4165 -39.8243027 -> 1852
+xmul150 multiply -73774.4165 -39.8243027 -> 2938014.69 Inexact Rounded
+xpow150 power -73774.4165 -40 -> 1.92206765E-195 Inexact Rounded
+xrem150 remainder -73774.4165 -39.8243027 -> -19.8078996
+xsub150 subtract -73774.4165 -39.8243027 -> -73734.5922 Inexact Rounded
+xadd151 add -524724715. -55763.7937 -> -524780479 Inexact Rounded
+xcom151 compare -524724715. -55763.7937 -> -1
+xdiv151 divide -524724715. -55763.7937 -> 9409.77434 Inexact Rounded
+xdvi151 divideint -524724715. -55763.7937 -> 9409
+xmul151 multiply -524724715. -55763.7937 -> 2.92606408E+13 Inexact Rounded
+xpow151 power -524724715. -55764 -> 5.47898351E-486259 Inexact Rounded
+xrem151 remainder -524724715. -55763.7937 -> -43180.0767
+xsub151 subtract -524724715. -55763.7937 -> -524668951 Inexact Rounded
+xadd152 add 7.53800427 784873768E-9981146 -> 7.53800427 Inexact Rounded
+xcom152 compare 7.53800427 784873768E-9981146 -> 1
+xdiv152 divide 7.53800427 784873768E-9981146 -> 9.60409760E+9981137 Inexact Rounded
+xdvi152 divideint 7.53800427 784873768E-9981146 -> NaN Division_impossible
+xmul152 multiply 7.53800427 784873768E-9981146 -> 5.91638181E-9981137 Inexact Rounded
+xpow152 power 7.53800427 8 -> 10424399.2 Inexact Rounded
+xrem152 remainder 7.53800427 784873768E-9981146 -> NaN Division_impossible
+xsub152 subtract 7.53800427 784873768E-9981146 -> 7.53800427 Inexact Rounded
+xadd153 add 37.6027452 7.22454233 -> 44.8272875 Inexact Rounded
+xcom153 compare 37.6027452 7.22454233 -> 1
+xdiv153 divide 37.6027452 7.22454233 -> 5.20486191 Inexact Rounded
+xdvi153 divideint 37.6027452 7.22454233 -> 5
+xmul153 multiply 37.6027452 7.22454233 -> 271.662624 Inexact Rounded
+xpow153 power 37.6027452 7 -> 1.06300881E+11 Inexact Rounded
+xrem153 remainder 37.6027452 7.22454233 -> 1.48003355
+xsub153 subtract 37.6027452 7.22454233 -> 30.3782029 Inexact Rounded
+xadd154 add 2447660.39 -36981.4253 -> 2410678.96 Inexact Rounded
+xcom154 compare 2447660.39 -36981.4253 -> 1
+xdiv154 divide 2447660.39 -36981.4253 -> -66.1862102 Inexact Rounded
+xdvi154 divideint 2447660.39 -36981.4253 -> -66
+xmul154 multiply 2447660.39 -36981.4253 -> -9.05179699E+10 Inexact Rounded
+xpow154 power 2447660.39 -36981 -> 3.92066064E-236263 Inexact Rounded
+xrem154 remainder 2447660.39 -36981.4253 -> 6886.3202
+xsub154 subtract 2447660.39 -36981.4253 -> 2484641.82 Inexact Rounded
+xadd155 add 2160.36419 1418.33574E+656265382 -> 1.41833574E+656265385 Inexact Rounded
+xcom155 compare 2160.36419 1418.33574E+656265382 -> -1
+xdiv155 divide 2160.36419 1418.33574E+656265382 -> 1.52316841E-656265382 Inexact Rounded
+xdvi155 divideint 2160.36419 1418.33574E+656265382 -> 0
+xmul155 multiply 2160.36419 1418.33574E+656265382 -> 3.06412174E+656265388 Inexact Rounded
+xpow155 power 2160.36419 1 -> 2160.36419
+xrem155 remainder 2160.36419 1418.33574E+656265382 -> 2160.36419
+xsub155 subtract 2160.36419 1418.33574E+656265382 -> -1.41833574E+656265385 Inexact Rounded
+xadd156 add 8926.44939 54.9430027 -> 8981.39239 Inexact Rounded
+xcom156 compare 8926.44939 54.9430027 -> 1
+xdiv156 divide 8926.44939 54.9430027 -> 162.467447 Inexact Rounded
+xdvi156 divideint 8926.44939 54.9430027 -> 162
+xmul156 multiply 8926.44939 54.9430027 -> 490445.933 Inexact Rounded
+xpow156 power 8926.44939 55 -> 1.93789877E+217 Inexact Rounded
+xrem156 remainder 8926.44939 54.9430027 -> 25.6829526
+xsub156 subtract 8926.44939 54.9430027 -> 8871.50639 Inexact Rounded
+xadd157 add 861588029 -41657398E+77955925 -> -4.16573980E+77955932 Inexact Rounded
+xcom157 compare 861588029 -41657398E+77955925 -> 1
+xdiv157 divide 861588029 -41657398E+77955925 -> -2.06827135E-77955924 Inexact Rounded
+xdvi157 divideint 861588029 -41657398E+77955925 -> -0
+xmul157 multiply 861588029 -41657398E+77955925 -> -3.58915154E+77955941 Inexact Rounded
+xpow157 power 861588029 -4 -> 1.81468553E-36 Inexact Rounded
+xrem157 remainder 861588029 -41657398E+77955925 -> 861588029
+xsub157 subtract 861588029 -41657398E+77955925 -> 4.16573980E+77955932 Inexact Rounded
+xadd158 add -34.5253062 52.6722019 -> 18.1468957
+xcom158 compare -34.5253062 52.6722019 -> -1
+xdiv158 divide -34.5253062 52.6722019 -> -0.655474899 Inexact Rounded
+xdvi158 divideint -34.5253062 52.6722019 -> -0
+xmul158 multiply -34.5253062 52.6722019 -> -1818.52390 Inexact Rounded
+xpow158 power -34.5253062 53 -> -3.32115821E+81 Inexact Rounded
+xrem158 remainder -34.5253062 52.6722019 -> -34.5253062
+xsub158 subtract -34.5253062 52.6722019 -> -87.1975081
+xadd159 add -18861647. 99794586.7 -> 80932939.7
+xcom159 compare -18861647. 99794586.7 -> -1
+xdiv159 divide -18861647. 99794586.7 -> -0.189004711 Inexact Rounded
+xdvi159 divideint -18861647. 99794586.7 -> -0
+xmul159 multiply -18861647. 99794586.7 -> -1.88229027E+15 Inexact Rounded
+xpow159 power -18861647. 99794587 -> -4.28957460E+726063462 Inexact Rounded
+xrem159 remainder -18861647. 99794586.7 -> -18861647.0
+xsub159 subtract -18861647. 99794586.7 -> -118656234 Inexact Rounded
+xadd160 add 322192.407 461.67044 -> 322654.077 Inexact Rounded
+xcom160 compare 322192.407 461.67044 -> 1
+xdiv160 divide 322192.407 461.67044 -> 697.883986 Inexact Rounded
+xdvi160 divideint 322192.407 461.67044 -> 697
+xmul160 multiply 322192.407 461.67044 -> 148746710 Inexact Rounded
+xpow160 power 322192.407 462 -> 5.61395873E+2544 Inexact Rounded
+xrem160 remainder 322192.407 461.67044 -> 408.11032
+xsub160 subtract 322192.407 461.67044 -> 321730.737 Inexact Rounded
+xadd161 add -896298518E+61412314 78873.8049 -> -8.96298518E+61412322 Inexact Rounded
+xcom161 compare -896298518E+61412314 78873.8049 -> -1
+xdiv161 divide -896298518E+61412314 78873.8049 -> -1.13637033E+61412318 Inexact Rounded
+xdvi161 divideint -896298518E+61412314 78873.8049 -> NaN Division_impossible
+xmul161 multiply -896298518E+61412314 78873.8049 -> -7.06944744E+61412327 Inexact Rounded
+xpow161 power -896298518E+61412314 78874 -> Infinity Overflow Inexact Rounded
+xrem161 remainder -896298518E+61412314 78873.8049 -> NaN Division_impossible
+xsub161 subtract -896298518E+61412314 78873.8049 -> -8.96298518E+61412322 Inexact Rounded
+xadd162 add 293.773732 479899052E+789950177 -> 4.79899052E+789950185 Inexact Rounded
+xcom162 compare 293.773732 479899052E+789950177 -> -1
+xdiv162 divide 293.773732 479899052E+789950177 -> 6.12157350E-789950184 Inexact Rounded
+xdvi162 divideint 293.773732 479899052E+789950177 -> 0
+xmul162 multiply 293.773732 479899052E+789950177 -> 1.40981735E+789950188 Inexact Rounded
+xpow162 power 293.773732 5 -> 2.18808809E+12 Inexact Rounded
+xrem162 remainder 293.773732 479899052E+789950177 -> 293.773732
+xsub162 subtract 293.773732 479899052E+789950177 -> -4.79899052E+789950185 Inexact Rounded
+xadd163 add -103519362 51897955.3 -> -51621406.7
+xcom163 compare -103519362 51897955.3 -> -1
+xdiv163 divide -103519362 51897955.3 -> -1.99467130 Inexact Rounded
+xdvi163 divideint -103519362 51897955.3 -> -1
+xmul163 multiply -103519362 51897955.3 -> -5.37244322E+15 Inexact Rounded
+xpow163 power -103519362 51897955 -> -4.28858229E+415963229 Inexact Rounded
+xrem163 remainder -103519362 51897955.3 -> -51621406.7
+xsub163 subtract -103519362 51897955.3 -> -155417317 Inexact Rounded
+xadd164 add 37380.7802 -277719788. -> -277682407 Inexact Rounded
+xcom164 compare 37380.7802 -277719788. -> 1
+xdiv164 divide 37380.7802 -277719788. -> -0.000134598908 Inexact Rounded
+xdvi164 divideint 37380.7802 -277719788. -> -0
+xmul164 multiply 37380.7802 -277719788. -> -1.03813824E+13 Inexact Rounded
+xpow164 power 37380.7802 -277719788 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem164 remainder 37380.7802 -277719788. -> 37380.7802
+xsub164 subtract 37380.7802 -277719788. -> 277757169 Inexact Rounded
+xadd165 add 320133844. -977517477 -> -657383633
+xcom165 compare 320133844. -977517477 -> 1
+xdiv165 divide 320133844. -977517477 -> -0.327496798 Inexact Rounded
+xdvi165 divideint 320133844. -977517477 -> -0
+xmul165 multiply 320133844. -977517477 -> -3.12936427E+17 Inexact Rounded
+xpow165 power 320133844. -977517477 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem165 remainder 320133844. -977517477 -> 320133844
+xsub165 subtract 320133844. -977517477 -> 1.29765132E+9 Inexact Rounded
+xadd166 add 721776701E+933646161 -5689279.64E+669903645 -> 7.21776701E+933646169 Inexact Rounded
+xcom166 compare 721776701E+933646161 -5689279.64E+669903645 -> 1
+xdiv166 divide 721776701E+933646161 -5689279.64E+669903645 -> -1.26866097E+263742518 Inexact Rounded
+xdvi166 divideint 721776701E+933646161 -5689279.64E+669903645 -> NaN Division_impossible
+xmul166 multiply 721776701E+933646161 -5689279.64E+669903645 -> -Infinity Inexact Overflow Rounded
+xpow166 power 721776701E+933646161 -6 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem166 remainder 721776701E+933646161 -5689279.64E+669903645 -> NaN Division_impossible
+xsub166 subtract 721776701E+933646161 -5689279.64E+669903645 -> 7.21776701E+933646169 Inexact Rounded
+xadd167 add -5409.00482 -2.16149386 -> -5411.16631 Inexact Rounded
+xcom167 compare -5409.00482 -2.16149386 -> -1
+xdiv167 divide -5409.00482 -2.16149386 -> 2502.43821 Inexact Rounded
+xdvi167 divideint -5409.00482 -2.16149386 -> 2502
+xmul167 multiply -5409.00482 -2.16149386 -> 11691.5307 Inexact Rounded
+xpow167 power -5409.00482 -2 -> 3.41794652E-8 Inexact Rounded
+xrem167 remainder -5409.00482 -2.16149386 -> -0.94718228
+xsub167 subtract -5409.00482 -2.16149386 -> -5406.84333 Inexact Rounded
+xadd168 add -957960.367 322.858170 -> -957637.509 Inexact Rounded
+xcom168 compare -957960.367 322.858170 -> -1
+xdiv168 divide -957960.367 322.858170 -> -2967.12444 Inexact Rounded
+xdvi168 divideint -957960.367 322.858170 -> -2967
+xmul168 multiply -957960.367 322.858170 -> -309285331 Inexact Rounded
+xpow168 power -957960.367 323 -> -9.44617460E+1931 Inexact Rounded
+xrem168 remainder -957960.367 322.858170 -> -40.176610
+xsub168 subtract -957960.367 322.858170 -> -958283.225 Inexact Rounded
+xadd169 add -11817.8754E+613893442 -3.84735082E+888333249 -> -3.84735082E+888333249 Inexact Rounded
+xcom169 compare -11817.8754E+613893442 -3.84735082E+888333249 -> 1
+xdiv169 divide -11817.8754E+613893442 -3.84735082E+888333249 -> 3.07169165E-274439804 Inexact Rounded
+xdvi169 divideint -11817.8754E+613893442 -3.84735082E+888333249 -> 0
+xmul169 multiply -11817.8754E+613893442 -3.84735082E+888333249 -> Infinity Inexact Overflow Rounded
+xpow169 power -11817.8754E+613893442 -4 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem169 remainder -11817.8754E+613893442 -3.84735082E+888333249 -> -1.18178754E+613893446
+xsub169 subtract -11817.8754E+613893442 -3.84735082E+888333249 -> 3.84735082E+888333249 Inexact Rounded
+xadd170 add 840258203 58363.980E-906584723 -> 840258203 Inexact Rounded
+xcom170 compare 840258203 58363.980E-906584723 -> 1
+xdiv170 divide 840258203 58363.980E-906584723 -> 1.43968626E+906584727 Inexact Rounded
+xdvi170 divideint 840258203 58363.980E-906584723 -> NaN Division_impossible
+xmul170 multiply 840258203 58363.980E-906584723 -> 4.90408130E-906584710 Inexact Rounded
+xpow170 power 840258203 6 -> 3.51946431E+53 Inexact Rounded
+xrem170 remainder 840258203 58363.980E-906584723 -> NaN Division_impossible
+xsub170 subtract 840258203 58363.980E-906584723 -> 840258203 Inexact Rounded
+xadd171 add -205842096. -191342.721 -> -206033439 Inexact Rounded
+xcom171 compare -205842096. -191342.721 -> -1
+xdiv171 divide -205842096. -191342.721 -> 1075.77699 Inexact Rounded
+xdvi171 divideint -205842096. -191342.721 -> 1075
+xmul171 multiply -205842096. -191342.721 -> 3.93863867E+13 Inexact Rounded
+xpow171 power -205842096. -191343 -> -2.66955553E-1590737 Inexact Rounded
+xrem171 remainder -205842096. -191342.721 -> -148670.925
+xsub171 subtract -205842096. -191342.721 -> -205650753 Inexact Rounded
+xadd172 add 42501124. 884.938498E+123341480 -> 8.84938498E+123341482 Inexact Rounded
+xcom172 compare 42501124. 884.938498E+123341480 -> -1
+xdiv172 divide 42501124. 884.938498E+123341480 -> 4.80272065E-123341476 Inexact Rounded
+xdvi172 divideint 42501124. 884.938498E+123341480 -> 0
+xmul172 multiply 42501124. 884.938498E+123341480 -> 3.76108808E+123341490 Inexact Rounded
+xpow172 power 42501124. 9 -> 4.52484536E+68 Inexact Rounded
+xrem172 remainder 42501124. 884.938498E+123341480 -> 42501124
+xsub172 subtract 42501124. 884.938498E+123341480 -> -8.84938498E+123341482 Inexact Rounded
+xadd173 add -57809452. -620380746 -> -678190198
+xcom173 compare -57809452. -620380746 -> 1
+xdiv173 divide -57809452. -620380746 -> 0.0931838268 Inexact Rounded
+xdvi173 divideint -57809452. -620380746 -> 0
+xmul173 multiply -57809452. -620380746 -> 3.58638710E+16 Inexact Rounded
+xpow173 power -57809452. -620380746 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem173 remainder -57809452. -620380746 -> -57809452
+xsub173 subtract -57809452. -620380746 -> 562571294
+xadd174 add -8022370.31 9858581.6 -> 1836211.29
+xcom174 compare -8022370.31 9858581.6 -> -1
+xdiv174 divide -8022370.31 9858581.6 -> -0.813744881 Inexact Rounded
+xdvi174 divideint -8022370.31 9858581.6 -> -0
+xmul174 multiply -8022370.31 9858581.6 -> -7.90891923E+13 Inexact Rounded
+xpow174 power -8022370.31 9858582 -> 2.34458249E+68066634 Inexact Rounded
+xrem174 remainder -8022370.31 9858581.6 -> -8022370.31
+xsub174 subtract -8022370.31 9858581.6 -> -17880951.9 Inexact Rounded
+xadd175 add 2.49065060E+592139141 -5432.72014E-419965357 -> 2.49065060E+592139141 Inexact Rounded
+xcom175 compare 2.49065060E+592139141 -5432.72014E-419965357 -> 1
+xdiv175 divide 2.49065060E+592139141 -5432.72014E-419965357 -> -Infinity Inexact Overflow Rounded
+xdvi175 divideint 2.49065060E+592139141 -5432.72014E-419965357 -> NaN Division_impossible
+xmul175 multiply 2.49065060E+592139141 -5432.72014E-419965357 -> -1.35310077E+172173788 Inexact Rounded
+xpow175 power 2.49065060E+592139141 -5 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem175 remainder 2.49065060E+592139141 -5432.72014E-419965357 -> NaN Division_impossible
+xsub175 subtract 2.49065060E+592139141 -5432.72014E-419965357 -> 2.49065060E+592139141 Inexact Rounded
+xadd176 add -697273715E-242824870 -3.81757506 -> -3.81757506 Inexact Rounded
+xcom176 compare -697273715E-242824870 -3.81757506 -> 1
+xdiv176 divide -697273715E-242824870 -3.81757506 -> 1.82648331E-242824862 Inexact Rounded
+xdvi176 divideint -697273715E-242824870 -3.81757506 -> 0
+xmul176 multiply -697273715E-242824870 -3.81757506 -> 2.66189474E-242824861 Inexact Rounded
+xpow176 power -697273715E-242824870 -4 -> 4.23045251E+971299444 Inexact Rounded
+xrem176 remainder -697273715E-242824870 -3.81757506 -> -6.97273715E-242824862
+xsub176 subtract -697273715E-242824870 -3.81757506 -> 3.81757506 Inexact Rounded
+xadd177 add -7.42204403E-315716280 -8156111.67E+283261636 -> -8.15611167E+283261642 Inexact Rounded
+xcom177 compare -7.42204403E-315716280 -8156111.67E+283261636 -> 1
+xdiv177 divide -7.42204403E-315716280 -8156111.67E+283261636 -> 9.09997843E-598977923 Inexact Rounded
+xdvi177 divideint -7.42204403E-315716280 -8156111.67E+283261636 -> 0
+xmul177 multiply -7.42204403E-315716280 -8156111.67E+283261636 -> 6.05350199E-32454637 Inexact Rounded
+xpow177 power -7.42204403E-315716280 -8 -> Infinity Overflow Inexact Rounded
+xrem177 remainder -7.42204403E-315716280 -8156111.67E+283261636 -> -7.42204403E-315716280
+xsub177 subtract -7.42204403E-315716280 -8156111.67E+283261636 -> 8.15611167E+283261642 Inexact Rounded
+xadd178 add 738063892 89900467.8 -> 827964360 Inexact Rounded
+xcom178 compare 738063892 89900467.8 -> 1
+xdiv178 divide 738063892 89900467.8 -> 8.20978923 Inexact Rounded
+xdvi178 divideint 738063892 89900467.8 -> 8
+xmul178 multiply 738063892 89900467.8 -> 6.63522892E+16 Inexact Rounded
+xpow178 power 738063892 89900468 -> 1.53166723E+797245797 Inexact Rounded
+xrem178 remainder 738063892 89900467.8 -> 18860149.6
+xsub178 subtract 738063892 89900467.8 -> 648163424 Inexact Rounded
+xadd179 add -630309366 -884783.338E-21595410 -> -630309366 Inexact Rounded
+xcom179 compare -630309366 -884783.338E-21595410 -> -1
+xdiv179 divide -630309366 -884783.338E-21595410 -> 7.12388377E+21595412 Inexact Rounded
+xdvi179 divideint -630309366 -884783.338E-21595410 -> NaN Division_impossible
+xmul179 multiply -630309366 -884783.338E-21595410 -> 5.57687225E-21595396 Inexact Rounded
+xpow179 power -630309366 -9 -> -6.36819210E-80 Inexact Rounded
+xrem179 remainder -630309366 -884783.338E-21595410 -> NaN Division_impossible
+xsub179 subtract -630309366 -884783.338E-21595410 -> -630309366 Inexact Rounded
+xadd180 add 613.207774 -3007.78608 -> -2394.57831 Inexact Rounded
+xcom180 compare 613.207774 -3007.78608 -> 1
+xdiv180 divide 613.207774 -3007.78608 -> -0.203873466 Inexact Rounded
+xdvi180 divideint 613.207774 -3007.78608 -> -0
+xmul180 multiply 613.207774 -3007.78608 -> -1844397.81 Inexact Rounded
+xpow180 power 613.207774 -3008 -> 7.51939160E-8386 Inexact Rounded
+xrem180 remainder 613.207774 -3007.78608 -> 613.207774
+xsub180 subtract 613.207774 -3007.78608 -> 3620.99385 Inexact Rounded
+xadd181 add -93006222.3 -3.08964619 -> -93006225.4 Inexact Rounded
+xcom181 compare -93006222.3 -3.08964619 -> -1
+xdiv181 divide -93006222.3 -3.08964619 -> 30102547.9 Inexact Rounded
+xdvi181 divideint -93006222.3 -3.08964619 -> 30102547
+xmul181 multiply -93006222.3 -3.08964619 -> 287356320 Inexact Rounded
+xpow181 power -93006222.3 -3 -> -1.24297956E-24 Inexact Rounded
+xrem181 remainder -93006222.3 -3.08964619 -> -2.65215407
+xsub181 subtract -93006222.3 -3.08964619 -> -93006219.2 Inexact Rounded
+xadd182 add -18116.0621 34096.306E-270347092 -> -18116.0621 Inexact Rounded
+xcom182 compare -18116.0621 34096.306E-270347092 -> -1
+xdiv182 divide -18116.0621 34096.306E-270347092 -> -5.31320375E+270347091 Inexact Rounded
+xdvi182 divideint -18116.0621 34096.306E-270347092 -> NaN Division_impossible
+xmul182 multiply -18116.0621 34096.306E-270347092 -> -6.17690797E-270347084 Inexact Rounded
+xpow182 power -18116.0621 3 -> -5.94554133E+12 Inexact Rounded
+xrem182 remainder -18116.0621 34096.306E-270347092 -> NaN Division_impossible
+xsub182 subtract -18116.0621 34096.306E-270347092 -> -18116.0621 Inexact Rounded
+xadd183 add 19272386.9 -410442379. -> -391169992 Inexact Rounded
+xcom183 compare 19272386.9 -410442379. -> 1
+xdiv183 divide 19272386.9 -410442379. -> -0.0469551584 Inexact Rounded
+xdvi183 divideint 19272386.9 -410442379. -> -0
+xmul183 multiply 19272386.9 -410442379. -> -7.91020433E+15 Inexact Rounded
+xpow183 power 19272386.9 -410442379 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem183 remainder 19272386.9 -410442379. -> 19272386.9
+xsub183 subtract 19272386.9 -410442379. -> 429714766 Inexact Rounded
+xadd184 add 4180.30821 -1.6439543E-624759104 -> 4180.30821 Inexact Rounded
+xcom184 compare 4180.30821 -1.6439543E-624759104 -> 1
+xdiv184 divide 4180.30821 -1.6439543E-624759104 -> -2.54283724E+624759107 Inexact Rounded
+xdvi184 divideint 4180.30821 -1.6439543E-624759104 -> NaN Division_impossible
+xmul184 multiply 4180.30821 -1.6439543E-624759104 -> -6.87223566E-624759101 Inexact Rounded
+xpow184 power 4180.30821 -2 -> 5.72246828E-8 Inexact Rounded
+xrem184 remainder 4180.30821 -1.6439543E-624759104 -> NaN Division_impossible
+xsub184 subtract 4180.30821 -1.6439543E-624759104 -> 4180.30821 Inexact Rounded
+xadd185 add 571.536725 389.899220 -> 961.435945
+xcom185 compare 571.536725 389.899220 -> 1
+xdiv185 divide 571.536725 389.899220 -> 1.46585757 Inexact Rounded
+xdvi185 divideint 571.536725 389.899220 -> 1
+xmul185 multiply 571.536725 389.899220 -> 222841.723 Inexact Rounded
+xpow185 power 571.536725 390 -> 1.76691373E+1075 Inexact Rounded
+xrem185 remainder 571.536725 389.899220 -> 181.637505
+xsub185 subtract 571.536725 389.899220 -> 181.637505
+xadd186 add -622007306.E+159924886 -126.971745 -> -6.22007306E+159924894 Inexact Rounded
+xcom186 compare -622007306.E+159924886 -126.971745 -> -1
+xdiv186 divide -622007306.E+159924886 -126.971745 -> 4.89878521E+159924892 Inexact Rounded
+xdvi186 divideint -622007306.E+159924886 -126.971745 -> NaN Division_impossible
+xmul186 multiply -622007306.E+159924886 -126.971745 -> 7.89773530E+159924896 Inexact Rounded
+xpow186 power -622007306.E+159924886 -127 -> -0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem186 remainder -622007306.E+159924886 -126.971745 -> NaN Division_impossible
+xsub186 subtract -622007306.E+159924886 -126.971745 -> -6.22007306E+159924894 Inexact Rounded
+xadd187 add -29.356551E-282816139 37141748E-903397821 -> -2.93565510E-282816138 Inexact Rounded
+xcom187 compare -29.356551E-282816139 37141748E-903397821 -> -1
+xdiv187 divide -29.356551E-282816139 37141748E-903397821 -> -7.90392283E+620581675 Inexact Rounded
+xdvi187 divideint -29.356551E-282816139 37141748E-903397821 -> NaN Division_impossible
+xmul187 multiply -29.356551E-282816139 37141748E-903397821 -> -0E-1000000007 Underflow Subnormal Inexact Rounded
+xpow187 power -29.356551E-282816139 4 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem187 remainder -29.356551E-282816139 37141748E-903397821 -> NaN Division_impossible
+xsub187 subtract -29.356551E-282816139 37141748E-903397821 -> -2.93565510E-282816138 Inexact Rounded
+xadd188 add 92427442.4 674334898. -> 766762340 Inexact Rounded
+xcom188 compare 92427442.4 674334898. -> -1
+xdiv188 divide 92427442.4 674334898. -> 0.137064599 Inexact Rounded
+xdvi188 divideint 92427442.4 674334898. -> 0
+xmul188 multiply 92427442.4 674334898. -> 6.23270499E+16 Inexact Rounded
+xpow188 power 92427442.4 674334898 -> Infinity Overflow Inexact Rounded
+xrem188 remainder 92427442.4 674334898. -> 92427442.4
+xsub188 subtract 92427442.4 674334898. -> -581907456 Inexact Rounded
+xadd189 add 44651895.7 -910508.438 -> 43741387.3 Inexact Rounded
+xcom189 compare 44651895.7 -910508.438 -> 1
+xdiv189 divide 44651895.7 -910508.438 -> -49.0406171 Inexact Rounded
+xdvi189 divideint 44651895.7 -910508.438 -> -49
+xmul189 multiply 44651895.7 -910508.438 -> -4.06559278E+13 Inexact Rounded
+xpow189 power 44651895.7 -910508 -> 3.72264277E-6965241 Inexact Rounded
+xrem189 remainder 44651895.7 -910508.438 -> 36982.238
+xsub189 subtract 44651895.7 -910508.438 -> 45562404.1 Inexact Rounded
+xadd190 add 647897872.E+374021790 -467.423029 -> 6.47897872E+374021798 Inexact Rounded
+xcom190 compare 647897872.E+374021790 -467.423029 -> 1
+xdiv190 divide 647897872.E+374021790 -467.423029 -> -1.38610601E+374021796 Inexact Rounded
+xdvi190 divideint 647897872.E+374021790 -467.423029 -> NaN Division_impossible
+xmul190 multiply 647897872.E+374021790 -467.423029 -> -3.02842386E+374021801 Inexact Rounded
+xpow190 power 647897872.E+374021790 -467 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem190 remainder 647897872.E+374021790 -467.423029 -> NaN Division_impossible
+xsub190 subtract 647897872.E+374021790 -467.423029 -> 6.47897872E+374021798 Inexact Rounded
+xadd191 add 25.2592149 59.0436981 -> 84.3029130
+xcom191 compare 25.2592149 59.0436981 -> -1
+xdiv191 divide 25.2592149 59.0436981 -> 0.427805434 Inexact Rounded
+xdvi191 divideint 25.2592149 59.0436981 -> 0
+xmul191 multiply 25.2592149 59.0436981 -> 1491.39746 Inexact Rounded
+xpow191 power 25.2592149 59 -> 5.53058435E+82 Inexact Rounded
+xrem191 remainder 25.2592149 59.0436981 -> 25.2592149
+xsub191 subtract 25.2592149 59.0436981 -> -33.7844832
+xadd192 add -6.850835 -1273.48240 -> -1280.33324 Inexact Rounded
+xcom192 compare -6.850835 -1273.48240 -> 1
+xdiv192 divide -6.850835 -1273.48240 -> 0.00537960713 Inexact Rounded
+xdvi192 divideint -6.850835 -1273.48240 -> 0
+xmul192 multiply -6.850835 -1273.48240 -> 8724.41780 Inexact Rounded
+xpow192 power -6.850835 -1273 -> -1.25462678E-1064 Inexact Rounded
+xrem192 remainder -6.850835 -1273.48240 -> -6.850835
+xsub192 subtract -6.850835 -1273.48240 -> 1266.63157 Inexact Rounded
+xadd193 add 174.272325 5638.16229 -> 5812.43462 Inexact Rounded
+xcom193 compare 174.272325 5638.16229 -> -1
+xdiv193 divide 174.272325 5638.16229 -> 0.0309094198 Inexact Rounded
+xdvi193 divideint 174.272325 5638.16229 -> 0
+xmul193 multiply 174.272325 5638.16229 -> 982575.651 Inexact Rounded
+xpow193 power 174.272325 5638 -> 1.11137724E+12636 Inexact Rounded
+xrem193 remainder 174.272325 5638.16229 -> 174.272325
+xsub193 subtract 174.272325 5638.16229 -> -5463.88997 Inexact Rounded
+xadd194 add 3455629.76 -8.27332322 -> 3455621.49 Inexact Rounded
+xcom194 compare 3455629.76 -8.27332322 -> 1
+xdiv194 divide 3455629.76 -8.27332322 -> -417683.399 Inexact Rounded
+xdvi194 divideint 3455629.76 -8.27332322 -> -417683
+xmul194 multiply 3455629.76 -8.27332322 -> -28589541.9 Inexact Rounded
+xpow194 power 3455629.76 -8 -> 4.91793015E-53 Inexact Rounded
+xrem194 remainder 3455629.76 -8.27332322 -> 3.29750074
+xsub194 subtract 3455629.76 -8.27332322 -> 3455638.03 Inexact Rounded
+xadd195 add -924337723E-640771235 86639377.1 -> 86639377.1 Inexact Rounded
+xcom195 compare -924337723E-640771235 86639377.1 -> -1
+xdiv195 divide -924337723E-640771235 86639377.1 -> -1.06687947E-640771234 Inexact Rounded
+xdvi195 divideint -924337723E-640771235 86639377.1 -> -0
+xmul195 multiply -924337723E-640771235 86639377.1 -> -8.00840446E-640771219 Inexact Rounded
+xpow195 power -924337723E-640771235 86639377 -> -0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem195 remainder -924337723E-640771235 86639377.1 -> -9.24337723E-640771227
+xsub195 subtract -924337723E-640771235 86639377.1 -> -86639377.1 Inexact Rounded
+xadd196 add -620236932.E+656823969 3364722.73 -> -6.20236932E+656823977 Inexact Rounded
+xcom196 compare -620236932.E+656823969 3364722.73 -> -1
+xdiv196 divide -620236932.E+656823969 3364722.73 -> -1.84335228E+656823971 Inexact Rounded
+xdvi196 divideint -620236932.E+656823969 3364722.73 -> NaN Division_impossible
+xmul196 multiply -620236932.E+656823969 3364722.73 -> -2.08692530E+656823984 Inexact Rounded
+xpow196 power -620236932.E+656823969 3364723 -> -Infinity Overflow Inexact Rounded
+xrem196 remainder -620236932.E+656823969 3364722.73 -> NaN Division_impossible
+xsub196 subtract -620236932.E+656823969 3364722.73 -> -6.20236932E+656823977 Inexact Rounded
+xadd197 add 9.10025079 702777882E-8192234 -> 9.10025079 Inexact Rounded
+xcom197 compare 9.10025079 702777882E-8192234 -> 1
+xdiv197 divide 9.10025079 702777882E-8192234 -> 1.29489715E+8192226 Inexact Rounded
+xdvi197 divideint 9.10025079 702777882E-8192234 -> NaN Division_impossible
+xmul197 multiply 9.10025079 702777882E-8192234 -> 6.39545498E-8192225 Inexact Rounded
+xpow197 power 9.10025079 7 -> 5168607.19 Inexact Rounded
+xrem197 remainder 9.10025079 702777882E-8192234 -> NaN Division_impossible
+xsub197 subtract 9.10025079 702777882E-8192234 -> 9.10025079 Inexact Rounded
+xadd198 add -18857539.9 813013129. -> 794155589 Inexact Rounded
+xcom198 compare -18857539.9 813013129. -> -1
+xdiv198 divide -18857539.9 813013129. -> -0.0231946315 Inexact Rounded
+xdvi198 divideint -18857539.9 813013129. -> -0
+xmul198 multiply -18857539.9 813013129. -> -1.53314275E+16 Inexact Rounded
+xpow198 power -18857539.9 813013129 -> -Infinity Overflow Inexact Rounded
+xrem198 remainder -18857539.9 813013129. -> -18857539.9
+xsub198 subtract -18857539.9 813013129. -> -831870669 Inexact Rounded
+xadd199 add -8.29530327 3243419.57E+35688332 -> 3.24341957E+35688338 Inexact Rounded
+xcom199 compare -8.29530327 3243419.57E+35688332 -> -1
+xdiv199 divide -8.29530327 3243419.57E+35688332 -> -2.55757946E-35688338 Inexact Rounded
+xdvi199 divideint -8.29530327 3243419.57E+35688332 -> -0
+xmul199 multiply -8.29530327 3243419.57E+35688332 -> -2.69051490E+35688339 Inexact Rounded
+xpow199 power -8.29530327 3 -> -570.816876 Inexact Rounded
+xrem199 remainder -8.29530327 3243419.57E+35688332 -> -8.29530327
+xsub199 subtract -8.29530327 3243419.57E+35688332 -> -3.24341957E+35688338 Inexact Rounded
+xadd200 add -57101683.5 763551341E+991491712 -> 7.63551341E+991491720 Inexact Rounded
+xcom200 compare -57101683.5 763551341E+991491712 -> -1
+xdiv200 divide -57101683.5 763551341E+991491712 -> -7.47843405E-991491714 Inexact Rounded
+xdvi200 divideint -57101683.5 763551341E+991491712 -> -0
+xmul200 multiply -57101683.5 763551341E+991491712 -> -4.36000670E+991491728 Inexact Rounded
+xpow200 power -57101683.5 8 -> 1.13029368E+62 Inexact Rounded
+xrem200 remainder -57101683.5 763551341E+991491712 -> -57101683.5
+xsub200 subtract -57101683.5 763551341E+991491712 -> -7.63551341E+991491720 Inexact Rounded
+xadd201 add -603326.740 1710.95183 -> -601615.788 Inexact Rounded
+xcom201 compare -603326.740 1710.95183 -> -1
+xdiv201 divide -603326.740 1710.95183 -> -352.626374 Inexact Rounded
+xdvi201 divideint -603326.740 1710.95183 -> -352
+xmul201 multiply -603326.740 1710.95183 -> -1.03226299E+9 Inexact Rounded
+xpow201 power -603326.740 1711 -> -3.35315976E+9890 Inexact Rounded
+xrem201 remainder -603326.740 1710.95183 -> -1071.69584
+xsub201 subtract -603326.740 1710.95183 -> -605037.692 Inexact Rounded
+xadd202 add -48142763.3 -943434114 -> -991576877 Inexact Rounded
+xcom202 compare -48142763.3 -943434114 -> 1
+xdiv202 divide -48142763.3 -943434114 -> 0.0510292797 Inexact Rounded
+xdvi202 divideint -48142763.3 -943434114 -> 0
+xmul202 multiply -48142763.3 -943434114 -> 4.54195252E+16 Inexact Rounded
+xpow202 power -48142763.3 -943434114 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem202 remainder -48142763.3 -943434114 -> -48142763.3
+xsub202 subtract -48142763.3 -943434114 -> 895291351 Inexact Rounded
+xadd203 add -204.586767 -235.531847 -> -440.118614
+xcom203 compare -204.586767 -235.531847 -> 1
+xdiv203 divide -204.586767 -235.531847 -> 0.868616154 Inexact Rounded
+xdvi203 divideint -204.586767 -235.531847 -> 0
+xmul203 multiply -204.586767 -235.531847 -> 48186.6991 Inexact Rounded
+xpow203 power -204.586767 -236 -> 4.29438222E-546 Inexact Rounded
+xrem203 remainder -204.586767 -235.531847 -> -204.586767
+xsub203 subtract -204.586767 -235.531847 -> 30.945080
+xadd204 add -70.3805581 830137.913 -> 830067.532 Inexact Rounded
+xcom204 compare -70.3805581 830137.913 -> -1
+xdiv204 divide -70.3805581 830137.913 -> -0.0000847817658 Inexact Rounded
+xdvi204 divideint -70.3805581 830137.913 -> -0
+xmul204 multiply -70.3805581 830137.913 -> -58425569.6 Inexact Rounded
+xpow204 power -70.3805581 830138 -> 4.95165841E+1533640 Inexact Rounded
+xrem204 remainder -70.3805581 830137.913 -> -70.3805581
+xsub204 subtract -70.3805581 830137.913 -> -830208.294 Inexact Rounded
+xadd205 add -8818.47606 -60766.4571 -> -69584.9332 Inexact Rounded
+xcom205 compare -8818.47606 -60766.4571 -> 1
+xdiv205 divide -8818.47606 -60766.4571 -> 0.145120787 Inexact Rounded
+xdvi205 divideint -8818.47606 -60766.4571 -> 0
+xmul205 multiply -8818.47606 -60766.4571 -> 535867547 Inexact Rounded
+xpow205 power -8818.47606 -60766 -> 1.64487755E-239746 Inexact Rounded
+xrem205 remainder -8818.47606 -60766.4571 -> -8818.47606
+xsub205 subtract -8818.47606 -60766.4571 -> 51947.9810 Inexact Rounded
+xadd206 add 37060929.3E-168439509 -79576717.1 -> -79576717.1 Inexact Rounded
+xcom206 compare 37060929.3E-168439509 -79576717.1 -> 1
+xdiv206 divide 37060929.3E-168439509 -79576717.1 -> -4.65725788E-168439510 Inexact Rounded
+xdvi206 divideint 37060929.3E-168439509 -79576717.1 -> -0
+xmul206 multiply 37060929.3E-168439509 -79576717.1 -> -2.94918709E-168439494 Inexact Rounded
+xpow206 power 37060929.3E-168439509 -79576717 -> Infinity Overflow Inexact Rounded
+xrem206 remainder 37060929.3E-168439509 -79576717.1 -> 3.70609293E-168439502
+xsub206 subtract 37060929.3E-168439509 -79576717.1 -> 79576717.1 Inexact Rounded
+xadd207 add -656285310. -107221462. -> -763506772
+xcom207 compare -656285310. -107221462. -> -1
+xdiv207 divide -656285310. -107221462. -> 6.12083904 Inexact Rounded
+xdvi207 divideint -656285310. -107221462. -> 6
+xmul207 multiply -656285310. -107221462. -> 7.03678704E+16 Inexact Rounded
+xpow207 power -656285310. -107221462 -> 8.05338080E-945381569 Inexact Rounded
+xrem207 remainder -656285310. -107221462. -> -12956538
+xsub207 subtract -656285310. -107221462. -> -549063848
+xadd208 add 653397.125 7195.30990 -> 660592.435 Inexact Rounded
+xcom208 compare 653397.125 7195.30990 -> 1
+xdiv208 divide 653397.125 7195.30990 -> 90.8087538 Inexact Rounded
+xdvi208 divideint 653397.125 7195.30990 -> 90
+xmul208 multiply 653397.125 7195.30990 -> 4.70139480E+9 Inexact Rounded
+xpow208 power 653397.125 7195 -> 1.58522983E+41840 Inexact Rounded
+xrem208 remainder 653397.125 7195.30990 -> 5819.23400
+xsub208 subtract 653397.125 7195.30990 -> 646201.815 Inexact Rounded
+xadd209 add 56221910.0E+857909374 -58.7247929 -> 5.62219100E+857909381 Inexact Rounded
+xcom209 compare 56221910.0E+857909374 -58.7247929 -> 1
+xdiv209 divide 56221910.0E+857909374 -58.7247929 -> -9.57379451E+857909379 Inexact Rounded
+xdvi209 divideint 56221910.0E+857909374 -58.7247929 -> NaN Division_impossible
+xmul209 multiply 56221910.0E+857909374 -58.7247929 -> -3.30162002E+857909383 Inexact Rounded
+xpow209 power 56221910.0E+857909374 -59 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem209 remainder 56221910.0E+857909374 -58.7247929 -> NaN Division_impossible
+xsub209 subtract 56221910.0E+857909374 -58.7247929 -> 5.62219100E+857909381 Inexact Rounded
+xadd210 add 809862859E+643769974 -5.06784016 -> 8.09862859E+643769982 Inexact Rounded
+xcom210 compare 809862859E+643769974 -5.06784016 -> 1
+xdiv210 divide 809862859E+643769974 -5.06784016 -> -1.59804341E+643769982 Inexact Rounded
+xdvi210 divideint 809862859E+643769974 -5.06784016 -> NaN Division_impossible
+xmul210 multiply 809862859E+643769974 -5.06784016 -> -4.10425552E+643769983 Inexact Rounded
+xpow210 power 809862859E+643769974 -5 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem210 remainder 809862859E+643769974 -5.06784016 -> NaN Division_impossible
+xsub210 subtract 809862859E+643769974 -5.06784016 -> 8.09862859E+643769982 Inexact Rounded
+xadd211 add -62011.4563E-117563240 -57.1731586E+115657204 -> -5.71731586E+115657205 Inexact Rounded
+xcom211 compare -62011.4563E-117563240 -57.1731586E+115657204 -> 1
+xdiv211 divide -62011.4563E-117563240 -57.1731586E+115657204 -> 1.08462534E-233220441 Inexact Rounded
+xdvi211 divideint -62011.4563E-117563240 -57.1731586E+115657204 -> 0
+xmul211 multiply -62011.4563E-117563240 -57.1731586E+115657204 -> 3.54539083E-1906030 Inexact Rounded
+xpow211 power -62011.4563E-117563240 -6 -> 1.75860546E+705379411 Inexact Rounded
+xrem211 remainder -62011.4563E-117563240 -57.1731586E+115657204 -> -6.20114563E-117563236
+xsub211 subtract -62011.4563E-117563240 -57.1731586E+115657204 -> 5.71731586E+115657205 Inexact Rounded
+xadd212 add 315.33351 91588.837E-536020149 -> 315.333510 Inexact Rounded
+xcom212 compare 315.33351 91588.837E-536020149 -> 1
+xdiv212 divide 315.33351 91588.837E-536020149 -> 3.44292515E+536020146 Inexact Rounded
+xdvi212 divideint 315.33351 91588.837E-536020149 -> NaN Division_impossible
+xmul212 multiply 315.33351 91588.837E-536020149 -> 2.88810294E-536020142 Inexact Rounded
+xpow212 power 315.33351 9 -> 3.08269902E+22 Inexact Rounded
+xrem212 remainder 315.33351 91588.837E-536020149 -> NaN Division_impossible
+xsub212 subtract 315.33351 91588.837E-536020149 -> 315.333510 Inexact Rounded
+xadd213 add 739.944710 202949.175 -> 203689.120 Inexact Rounded
+xcom213 compare 739.944710 202949.175 -> -1
+xdiv213 divide 739.944710 202949.175 -> 0.00364596067 Inexact Rounded
+xdvi213 divideint 739.944710 202949.175 -> 0
+xmul213 multiply 739.944710 202949.175 -> 150171168 Inexact Rounded
+xpow213 power 739.944710 202949 -> 1.32611729E+582301 Inexact Rounded
+xrem213 remainder 739.944710 202949.175 -> 739.944710
+xsub213 subtract 739.944710 202949.175 -> -202209.230 Inexact Rounded
+xadd214 add 87686.8016 4204890.40 -> 4292577.20 Inexact Rounded
+xcom214 compare 87686.8016 4204890.40 -> -1
+xdiv214 divide 87686.8016 4204890.40 -> 0.0208535285 Inexact Rounded
+xdvi214 divideint 87686.8016 4204890.40 -> 0
+xmul214 multiply 87686.8016 4204890.40 -> 3.68713390E+11 Inexact Rounded
+xpow214 power 87686.8016 4204890 -> 5.14846981E+20784494 Inexact Rounded
+xrem214 remainder 87686.8016 4204890.40 -> 87686.8016
+xsub214 subtract 87686.8016 4204890.40 -> -4117203.60 Inexact Rounded
+xadd215 add 987126721.E-725794834 4874166.23 -> 4874166.23 Inexact Rounded
+xcom215 compare 987126721.E-725794834 4874166.23 -> -1
+xdiv215 divide 987126721.E-725794834 4874166.23 -> 2.02522170E-725794832 Inexact Rounded
+xdvi215 divideint 987126721.E-725794834 4874166.23 -> 0
+xmul215 multiply 987126721.E-725794834 4874166.23 -> 4.81141973E-725794819 Inexact Rounded
+xpow215 power 987126721.E-725794834 4874166 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem215 remainder 987126721.E-725794834 4874166.23 -> 9.87126721E-725794826
+xsub215 subtract 987126721.E-725794834 4874166.23 -> -4874166.23 Inexact Rounded
+xadd216 add 728148726.E-661695938 32798.5202 -> 32798.5202 Inexact Rounded
+xcom216 compare 728148726.E-661695938 32798.5202 -> -1
+xdiv216 divide 728148726.E-661695938 32798.5202 -> 2.22006579E-661695934 Inexact Rounded
+xdvi216 divideint 728148726.E-661695938 32798.5202 -> 0
+xmul216 multiply 728148726.E-661695938 32798.5202 -> 2.38822007E-661695925 Inexact Rounded
+xpow216 power 728148726.E-661695938 32799 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem216 remainder 728148726.E-661695938 32798.5202 -> 7.28148726E-661695930
+xsub216 subtract 728148726.E-661695938 32798.5202 -> -32798.5202 Inexact Rounded
+xadd217 add 7428219.97 667.326760 -> 7428887.30 Inexact Rounded
+xcom217 compare 7428219.97 667.326760 -> 1
+xdiv217 divide 7428219.97 667.326760 -> 11131.3084 Inexact Rounded
+xdvi217 divideint 7428219.97 667.326760 -> 11131
+xmul217 multiply 7428219.97 667.326760 -> 4.95704997E+9 Inexact Rounded
+xpow217 power 7428219.97 667 -> 7.58808510E+4582 Inexact Rounded
+xrem217 remainder 7428219.97 667.326760 -> 205.804440
+xsub217 subtract 7428219.97 667.326760 -> 7427552.64 Inexact Rounded
+xadd218 add -7291.19212 209.64966E-588526476 -> -7291.19212 Inexact Rounded
+xcom218 compare -7291.19212 209.64966E-588526476 -> -1
+xdiv218 divide -7291.19212 209.64966E-588526476 -> -3.47779821E+588526477 Inexact Rounded
+xdvi218 divideint -7291.19212 209.64966E-588526476 -> NaN Division_impossible
+xmul218 multiply -7291.19212 209.64966E-588526476 -> -1.52859595E-588526470 Inexact Rounded
+xpow218 power -7291.19212 2 -> 53161482.5 Inexact Rounded
+xrem218 remainder -7291.19212 209.64966E-588526476 -> NaN Division_impossible
+xsub218 subtract -7291.19212 209.64966E-588526476 -> -7291.19212 Inexact Rounded
+xadd219 add -358.24550 -4447.78675E+601402509 -> -4.44778675E+601402512 Inexact Rounded
+xcom219 compare -358.24550 -4447.78675E+601402509 -> 1
+xdiv219 divide -358.24550 -4447.78675E+601402509 -> 8.05446664E-601402511 Inexact Rounded
+xdvi219 divideint -358.24550 -4447.78675E+601402509 -> 0
+xmul219 multiply -358.24550 -4447.78675E+601402509 -> 1.59339959E+601402515 Inexact Rounded
+xpow219 power -358.24550 -4 -> 6.07123474E-11 Inexact Rounded
+xrem219 remainder -358.24550 -4447.78675E+601402509 -> -358.24550
+xsub219 subtract -358.24550 -4447.78675E+601402509 -> 4.44778675E+601402512 Inexact Rounded
+xadd220 add 118.621826 -2.72010038 -> 115.901726 Inexact Rounded
+xcom220 compare 118.621826 -2.72010038 -> 1
+xdiv220 divide 118.621826 -2.72010038 -> -43.6093561 Inexact Rounded
+xdvi220 divideint 118.621826 -2.72010038 -> -43
+xmul220 multiply 118.621826 -2.72010038 -> -322.663274 Inexact Rounded
+xpow220 power 118.621826 -3 -> 5.99109471E-7 Inexact Rounded
+xrem220 remainder 118.621826 -2.72010038 -> 1.65750966
+xsub220 subtract 118.621826 -2.72010038 -> 121.341926 Inexact Rounded
+xadd221 add 8071961.94 -135533740.E-102451543 -> 8071961.94 Inexact Rounded
+xcom221 compare 8071961.94 -135533740.E-102451543 -> 1
+xdiv221 divide 8071961.94 -135533740.E-102451543 -> -5.95568450E+102451541 Inexact Rounded
+xdvi221 divideint 8071961.94 -135533740.E-102451543 -> NaN Division_impossible
+xmul221 multiply 8071961.94 -135533740.E-102451543 -> -1.09402319E-102451528 Inexact Rounded
+xpow221 power 8071961.94 -1 -> 1.23885619E-7 Inexact Rounded
+xrem221 remainder 8071961.94 -135533740.E-102451543 -> NaN Division_impossible
+xsub221 subtract 8071961.94 -135533740.E-102451543 -> 8071961.94 Inexact Rounded
+xadd222 add 64262528.5E+812118682 -8692.94447E-732186947 -> 6.42625285E+812118689 Inexact Rounded
+xcom222 compare 64262528.5E+812118682 -8692.94447E-732186947 -> 1
+xdiv222 divide 64262528.5E+812118682 -8692.94447E-732186947 -> -Infinity Inexact Overflow Rounded
+xdvi222 divideint 64262528.5E+812118682 -8692.94447E-732186947 -> NaN Division_impossible
+xmul222 multiply 64262528.5E+812118682 -8692.94447E-732186947 -> -5.58630592E+79931746 Inexact Rounded
+xpow222 power 64262528.5E+812118682 -9 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem222 remainder 64262528.5E+812118682 -8692.94447E-732186947 -> NaN Division_impossible
+xsub222 subtract 64262528.5E+812118682 -8692.94447E-732186947 -> 6.42625285E+812118689 Inexact Rounded
+xadd223 add -35544.4029 -567830.130 -> -603374.533 Inexact Rounded
+xcom223 compare -35544.4029 -567830.130 -> 1
+xdiv223 divide -35544.4029 -567830.130 -> 0.0625968948 Inexact Rounded
+xdvi223 divideint -35544.4029 -567830.130 -> 0
+xmul223 multiply -35544.4029 -567830.130 -> 2.01831829E+10 Inexact Rounded
+xpow223 power -35544.4029 -567830 -> 3.77069368E-2584065 Inexact Rounded
+xrem223 remainder -35544.4029 -567830.130 -> -35544.4029
+xsub223 subtract -35544.4029 -567830.130 -> 532285.727 Inexact Rounded
+xadd224 add -7.16513047E+59297103 87767.8211 -> -7.16513047E+59297103 Inexact Rounded
+xcom224 compare -7.16513047E+59297103 87767.8211 -> -1
+xdiv224 divide -7.16513047E+59297103 87767.8211 -> -8.16373288E+59297098 Inexact Rounded
+xdvi224 divideint -7.16513047E+59297103 87767.8211 -> NaN Division_impossible
+xmul224 multiply -7.16513047E+59297103 87767.8211 -> -6.28867889E+59297108 Inexact Rounded
+xpow224 power -7.16513047E+59297103 87768 -> Infinity Overflow Inexact Rounded
+xrem224 remainder -7.16513047E+59297103 87767.8211 -> NaN Division_impossible
+xsub224 subtract -7.16513047E+59297103 87767.8211 -> -7.16513047E+59297103 Inexact Rounded
+xadd225 add -509.483395 -147242915. -> -147243424 Inexact Rounded
+xcom225 compare -509.483395 -147242915. -> 1
+xdiv225 divide -509.483395 -147242915. -> 0.00000346015559 Inexact Rounded
+xdvi225 divideint -509.483395 -147242915. -> 0
+xmul225 multiply -509.483395 -147242915. -> 7.50178202E+10 Inexact Rounded
+xpow225 power -509.483395 -147242915 -> -3.10760519E-398605718 Inexact Rounded
+xrem225 remainder -509.483395 -147242915. -> -509.483395
+xsub225 subtract -509.483395 -147242915. -> 147242406 Inexact Rounded
+xadd226 add -7919047.28E+956041629 -367667329 -> -7.91904728E+956041635 Inexact Rounded
+xcom226 compare -7919047.28E+956041629 -367667329 -> -1
+xdiv226 divide -7919047.28E+956041629 -367667329 -> 2.15386211E+956041627 Inexact Rounded
+xdvi226 divideint -7919047.28E+956041629 -367667329 -> NaN Division_impossible
+xmul226 multiply -7919047.28E+956041629 -367667329 -> 2.91157496E+956041644 Inexact Rounded
+xpow226 power -7919047.28E+956041629 -367667329 -> -0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem226 remainder -7919047.28E+956041629 -367667329 -> NaN Division_impossible
+xsub226 subtract -7919047.28E+956041629 -367667329 -> -7.91904728E+956041635 Inexact Rounded
+xadd227 add 895612630. -36.4104040 -> 895612594 Inexact Rounded
+xcom227 compare 895612630. -36.4104040 -> 1
+xdiv227 divide 895612630. -36.4104040 -> -24597712.0 Inexact Rounded
+xdvi227 divideint 895612630. -36.4104040 -> -24597711
+xmul227 multiply 895612630. -36.4104040 -> -3.26096177E+10 Inexact Rounded
+xpow227 power 895612630. -36 -> 5.29264130E-323 Inexact Rounded
+xrem227 remainder 895612630. -36.4104040 -> 35.0147560
+xsub227 subtract 895612630. -36.4104040 -> 895612666 Inexact Rounded
+xadd228 add 25455.4973 2955.00006E+528196218 -> 2.95500006E+528196221 Inexact Rounded
+xcom228 compare 25455.4973 2955.00006E+528196218 -> -1
+xdiv228 divide 25455.4973 2955.00006E+528196218 -> 8.61438131E-528196218 Inexact Rounded
+xdvi228 divideint 25455.4973 2955.00006E+528196218 -> 0
+xmul228 multiply 25455.4973 2955.00006E+528196218 -> 7.52209960E+528196225 Inexact Rounded
+xpow228 power 25455.4973 3 -> 1.64947128E+13 Inexact Rounded
+xrem228 remainder 25455.4973 2955.00006E+528196218 -> 25455.4973
+xsub228 subtract 25455.4973 2955.00006E+528196218 -> -2.95500006E+528196221 Inexact Rounded
+xadd229 add -112.294144E+273414172 -71448007.7 -> -1.12294144E+273414174 Inexact Rounded
+xcom229 compare -112.294144E+273414172 -71448007.7 -> -1
+xdiv229 divide -112.294144E+273414172 -71448007.7 -> 1.57169035E+273414166 Inexact Rounded
+xdvi229 divideint -112.294144E+273414172 -71448007.7 -> NaN Division_impossible
+xmul229 multiply -112.294144E+273414172 -71448007.7 -> 8.02319287E+273414181 Inexact Rounded
+xpow229 power -112.294144E+273414172 -71448008 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem229 remainder -112.294144E+273414172 -71448007.7 -> NaN Division_impossible
+xsub229 subtract -112.294144E+273414172 -71448007.7 -> -1.12294144E+273414174 Inexact Rounded
+xadd230 add 62871.2202 2484.0382E+211662557 -> 2.48403820E+211662560 Inexact Rounded
+xcom230 compare 62871.2202 2484.0382E+211662557 -> -1
+xdiv230 divide 62871.2202 2484.0382E+211662557 -> 2.53100859E-211662556 Inexact Rounded
+xdvi230 divideint 62871.2202 2484.0382E+211662557 -> 0
+xmul230 multiply 62871.2202 2484.0382E+211662557 -> 1.56174513E+211662565 Inexact Rounded
+xpow230 power 62871.2202 2 -> 3.95279033E+9 Inexact Rounded
+xrem230 remainder 62871.2202 2484.0382E+211662557 -> 62871.2202
+xsub230 subtract 62871.2202 2484.0382E+211662557 -> -2.48403820E+211662560 Inexact Rounded
+xadd231 add 71.9281575 -9810012.5 -> -9809940.57 Inexact Rounded
+xcom231 compare 71.9281575 -9810012.5 -> 1
+xdiv231 divide 71.9281575 -9810012.5 -> -0.00000733211680 Inexact Rounded
+xdvi231 divideint 71.9281575 -9810012.5 -> -0
+xmul231 multiply 71.9281575 -9810012.5 -> -705616124 Inexact Rounded
+xpow231 power 71.9281575 -9810013 -> 2.00363798E-18216203 Inexact Rounded
+xrem231 remainder 71.9281575 -9810012.5 -> 71.9281575
+xsub231 subtract 71.9281575 -9810012.5 -> 9810084.43 Inexact Rounded
+xadd232 add -6388022. -88.042967 -> -6388110.04 Inexact Rounded
+xcom232 compare -6388022. -88.042967 -> -1
+xdiv232 divide -6388022. -88.042967 -> 72555.7329 Inexact Rounded
+xdvi232 divideint -6388022. -88.042967 -> 72555
+xmul232 multiply -6388022. -88.042967 -> 562420410 Inexact Rounded
+xpow232 power -6388022. -88 -> 1.34201238E-599 Inexact Rounded
+xrem232 remainder -6388022. -88.042967 -> -64.529315
+xsub232 subtract -6388022. -88.042967 -> -6387933.96 Inexact Rounded
+xadd233 add 372567445. 96.0992141 -> 372567541 Inexact Rounded
+xcom233 compare 372567445. 96.0992141 -> 1
+xdiv233 divide 372567445. 96.0992141 -> 3876904.18 Inexact Rounded
+xdvi233 divideint 372567445. 96.0992141 -> 3876904
+xmul233 multiply 372567445. 96.0992141 -> 3.58034387E+10 Inexact Rounded
+xpow233 power 372567445. 96 -> 6.84968715E+822 Inexact Rounded
+xrem233 remainder 372567445. 96.0992141 -> 17.4588536
+xsub233 subtract 372567445. 96.0992141 -> 372567349 Inexact Rounded
+xadd234 add 802.156517 -174409310.E-255338020 -> 802.156517 Inexact Rounded
+xcom234 compare 802.156517 -174409310.E-255338020 -> 1
+xdiv234 divide 802.156517 -174409310.E-255338020 -> -4.59927579E+255338014 Inexact Rounded
+xdvi234 divideint 802.156517 -174409310.E-255338020 -> NaN Division_impossible
+xmul234 multiply 802.156517 -174409310.E-255338020 -> -1.39903565E-255338009 Inexact Rounded
+xpow234 power 802.156517 -2 -> 0.00000155411005 Inexact Rounded
+xrem234 remainder 802.156517 -174409310.E-255338020 -> NaN Division_impossible
+xsub234 subtract 802.156517 -174409310.E-255338020 -> 802.156517 Inexact Rounded
+xadd235 add -3.65207541 74501982.0 -> 74501978.3 Inexact Rounded
+xcom235 compare -3.65207541 74501982.0 -> -1
+xdiv235 divide -3.65207541 74501982.0 -> -4.90198423E-8 Inexact Rounded
+xdvi235 divideint -3.65207541 74501982.0 -> -0
+xmul235 multiply -3.65207541 74501982.0 -> -272086856 Inexact Rounded
+xpow235 power -3.65207541 74501982 -> 2.10339452E+41910325 Inexact Rounded
+xrem235 remainder -3.65207541 74501982.0 -> -3.65207541
+xsub235 subtract -3.65207541 74501982.0 -> -74501985.7 Inexact Rounded
+xadd236 add -5297.76981 -859.719404 -> -6157.48921 Inexact Rounded
+xcom236 compare -5297.76981 -859.719404 -> -1
+xdiv236 divide -5297.76981 -859.719404 -> 6.16220802 Inexact Rounded
+xdvi236 divideint -5297.76981 -859.719404 -> 6
+xmul236 multiply -5297.76981 -859.719404 -> 4554595.50 Inexact Rounded
+xpow236 power -5297.76981 -860 -> 1.90523108E-3203 Inexact Rounded
+xrem236 remainder -5297.76981 -859.719404 -> -139.453386
+xsub236 subtract -5297.76981 -859.719404 -> -4438.05041 Inexact Rounded
+xadd237 add -684172.592 766.448597E+288361959 -> 7.66448597E+288361961 Inexact Rounded
+xcom237 compare -684172.592 766.448597E+288361959 -> -1
+xdiv237 divide -684172.592 766.448597E+288361959 -> -8.92652938E-288361957 Inexact Rounded
+xdvi237 divideint -684172.592 766.448597E+288361959 -> -0
+xmul237 multiply -684172.592 766.448597E+288361959 -> -5.24383123E+288361967 Inexact Rounded
+xpow237 power -684172.592 8 -> 4.80093005E+46 Inexact Rounded
+xrem237 remainder -684172.592 766.448597E+288361959 -> -684172.592
+xsub237 subtract -684172.592 766.448597E+288361959 -> -7.66448597E+288361961 Inexact Rounded
+xadd238 add 626919.219 57469.8727E+13188610 -> 5.74698727E+13188614 Inexact Rounded
+xcom238 compare 626919.219 57469.8727E+13188610 -> -1
+xdiv238 divide 626919.219 57469.8727E+13188610 -> 1.09086586E-13188609 Inexact Rounded
+xdvi238 divideint 626919.219 57469.8727E+13188610 -> 0
+xmul238 multiply 626919.219 57469.8727E+13188610 -> 3.60289677E+13188620 Inexact Rounded
+xpow238 power 626919.219 6 -> 6.07112959E+34 Inexact Rounded
+xrem238 remainder 626919.219 57469.8727E+13188610 -> 626919.219
+xsub238 subtract 626919.219 57469.8727E+13188610 -> -5.74698727E+13188614 Inexact Rounded
+xadd239 add -77480.5840 893265.594E+287982552 -> 8.93265594E+287982557 Inexact Rounded
+xcom239 compare -77480.5840 893265.594E+287982552 -> -1
+xdiv239 divide -77480.5840 893265.594E+287982552 -> -8.67385742E-287982554 Inexact Rounded
+xdvi239 divideint -77480.5840 893265.594E+287982552 -> -0
+xmul239 multiply -77480.5840 893265.594E+287982552 -> -6.92107399E+287982562 Inexact Rounded
+xpow239 power -77480.5840 9 -> -1.00631969E+44 Inexact Rounded
+xrem239 remainder -77480.5840 893265.594E+287982552 -> -77480.5840
+xsub239 subtract -77480.5840 893265.594E+287982552 -> -8.93265594E+287982557 Inexact Rounded
+xadd240 add -7177620.29 7786343.83 -> 608723.54
+xcom240 compare -7177620.29 7786343.83 -> -1
+xdiv240 divide -7177620.29 7786343.83 -> -0.921821647 Inexact Rounded
+xdvi240 divideint -7177620.29 7786343.83 -> -0
+xmul240 multiply -7177620.29 7786343.83 -> -5.58874195E+13 Inexact Rounded
+xpow240 power -7177620.29 7786344 -> 2.96037074E+53383022 Inexact Rounded
+xrem240 remainder -7177620.29 7786343.83 -> -7177620.29
+xsub240 subtract -7177620.29 7786343.83 -> -14963964.1 Inexact Rounded
+xadd241 add 9.6224130 4.50355112 -> 14.1259641 Inexact Rounded
+xcom241 compare 9.6224130 4.50355112 -> 1
+xdiv241 divide 9.6224130 4.50355112 -> 2.13662791 Inexact Rounded
+xdvi241 divideint 9.6224130 4.50355112 -> 2
+xmul241 multiply 9.6224130 4.50355112 -> 43.3350288 Inexact Rounded
+xpow241 power 9.6224130 5 -> 82493.5448 Inexact Rounded
+xrem241 remainder 9.6224130 4.50355112 -> 0.61531076
+xsub241 subtract 9.6224130 4.50355112 -> 5.11886188
+xadd242 add -66.6337347E-597410086 -818812885 -> -818812885 Inexact Rounded
+xcom242 compare -66.6337347E-597410086 -818812885 -> 1
+xdiv242 divide -66.6337347E-597410086 -818812885 -> 8.13784638E-597410094 Inexact Rounded
+xdvi242 divideint -66.6337347E-597410086 -818812885 -> 0
+xmul242 multiply -66.6337347E-597410086 -818812885 -> 5.45605605E-597410076 Inexact Rounded
+xpow242 power -66.6337347E-597410086 -818812885 -> -Infinity Overflow Inexact Rounded
+xrem242 remainder -66.6337347E-597410086 -818812885 -> -6.66337347E-597410085
+xsub242 subtract -66.6337347E-597410086 -818812885 -> 818812885 Inexact Rounded
+xadd243 add 65587553.7 600574.736 -> 66188128.4 Inexact Rounded
+xcom243 compare 65587553.7 600574.736 -> 1
+xdiv243 divide 65587553.7 600574.736 -> 109.207980 Inexact Rounded
+xdvi243 divideint 65587553.7 600574.736 -> 109
+xmul243 multiply 65587553.7 600574.736 -> 3.93902277E+13 Inexact Rounded
+xpow243 power 65587553.7 600575 -> 3.40404817E+4694587 Inexact Rounded
+xrem243 remainder 65587553.7 600574.736 -> 124907.476
+xsub243 subtract 65587553.7 600574.736 -> 64986979.0 Inexact Rounded
+xadd244 add -32401.939 -585200217. -> -585232619 Inexact Rounded
+xcom244 compare -32401.939 -585200217. -> 1
+xdiv244 divide -32401.939 -585200217. -> 0.0000553689798 Inexact Rounded
+xdvi244 divideint -32401.939 -585200217. -> 0
+xmul244 multiply -32401.939 -585200217. -> 1.89616217E+13 Inexact Rounded
+xpow244 power -32401.939 -585200217 -> -0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem244 remainder -32401.939 -585200217. -> -32401.939
+xsub244 subtract -32401.939 -585200217. -> 585167815 Inexact Rounded
+xadd245 add 69573.988 -9.77003465E+740933668 -> -9.77003465E+740933668 Inexact Rounded
+xcom245 compare 69573.988 -9.77003465E+740933668 -> 1
+xdiv245 divide 69573.988 -9.77003465E+740933668 -> -7.12116082E-740933665 Inexact Rounded
+xdvi245 divideint 69573.988 -9.77003465E+740933668 -> -0
+xmul245 multiply 69573.988 -9.77003465E+740933668 -> -6.79740273E+740933673 Inexact Rounded
+xpow245 power 69573.988 -10 -> 3.76297229E-49 Inexact Rounded
+xrem245 remainder 69573.988 -9.77003465E+740933668 -> 69573.988
+xsub245 subtract 69573.988 -9.77003465E+740933668 -> 9.77003465E+740933668 Inexact Rounded
+xadd246 add 2362.06251 -433149546.E-152643629 -> 2362.06251 Inexact Rounded
+xcom246 compare 2362.06251 -433149546.E-152643629 -> 1
+xdiv246 divide 2362.06251 -433149546.E-152643629 -> -5.45322633E+152643623 Inexact Rounded
+xdvi246 divideint 2362.06251 -433149546.E-152643629 -> NaN Division_impossible
+xmul246 multiply 2362.06251 -433149546.E-152643629 -> -1.02312630E-152643617 Inexact Rounded
+xpow246 power 2362.06251 -4 -> 3.21243577E-14 Inexact Rounded
+xrem246 remainder 2362.06251 -433149546.E-152643629 -> NaN Division_impossible
+xsub246 subtract 2362.06251 -433149546.E-152643629 -> 2362.06251 Inexact Rounded
+xadd247 add -615.23488E+249953452 -21437483.7 -> -6.15234880E+249953454 Inexact Rounded
+xcom247 compare -615.23488E+249953452 -21437483.7 -> -1
+xdiv247 divide -615.23488E+249953452 -21437483.7 -> 2.86990250E+249953447 Inexact Rounded
+xdvi247 divideint -615.23488E+249953452 -21437483.7 -> NaN Division_impossible
+xmul247 multiply -615.23488E+249953452 -21437483.7 -> 1.31890877E+249953462 Inexact Rounded
+xpow247 power -615.23488E+249953452 -21437484 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem247 remainder -615.23488E+249953452 -21437483.7 -> NaN Division_impossible
+xsub247 subtract -615.23488E+249953452 -21437483.7 -> -6.15234880E+249953454 Inexact Rounded
+xadd248 add 216741082. 250290244 -> 467031326
+xcom248 compare 216741082. 250290244 -> -1
+xdiv248 divide 216741082. 250290244 -> 0.865958970 Inexact Rounded
+xdvi248 divideint 216741082. 250290244 -> 0
+xmul248 multiply 216741082. 250290244 -> 5.42481783E+16 Inexact Rounded
+xpow248 power 216741082. 250290244 -> Infinity Overflow Inexact Rounded
+xrem248 remainder 216741082. 250290244 -> 216741082
+xsub248 subtract 216741082. 250290244 -> -33549162
+xadd249 add -6364720.49 5539245.64 -> -825474.85
+xcom249 compare -6364720.49 5539245.64 -> -1
+xdiv249 divide -6364720.49 5539245.64 -> -1.14902297 Inexact Rounded
+xdvi249 divideint -6364720.49 5539245.64 -> -1
+xmul249 multiply -6364720.49 5539245.64 -> -3.52557502E+13 Inexact Rounded
+xpow249 power -6364720.49 5539246 -> 2.96894641E+37687807 Inexact Rounded
+xrem249 remainder -6364720.49 5539245.64 -> -825474.85
+xsub249 subtract -6364720.49 5539245.64 -> -11903966.1 Inexact Rounded
+xadd250 add -814599.475 -14.5431191 -> -814614.018 Inexact Rounded
+xcom250 compare -814599.475 -14.5431191 -> -1
+xdiv250 divide -814599.475 -14.5431191 -> 56012.7074 Inexact Rounded
+xdvi250 divideint -814599.475 -14.5431191 -> 56012
+xmul250 multiply -814599.475 -14.5431191 -> 11846817.2 Inexact Rounded
+xpow250 power -814599.475 -15 -> -2.16689622E-89 Inexact Rounded
+xrem250 remainder -814599.475 -14.5431191 -> -10.2879708
+xsub250 subtract -814599.475 -14.5431191 -> -814584.932 Inexact Rounded
+xadd251 add -877498.755 507408724E-168628106 -> -877498.755 Inexact Rounded
+xcom251 compare -877498.755 507408724E-168628106 -> -1
+xdiv251 divide -877498.755 507408724E-168628106 -> -1.72937262E+168628103 Inexact Rounded
+xdvi251 divideint -877498.755 507408724E-168628106 -> NaN Division_impossible
+xmul251 multiply -877498.755 507408724E-168628106 -> -4.45250524E-168628092 Inexact Rounded
+xpow251 power -877498.755 5 -> -5.20274505E+29 Inexact Rounded
+xrem251 remainder -877498.755 507408724E-168628106 -> NaN Division_impossible
+xsub251 subtract -877498.755 507408724E-168628106 -> -877498.755 Inexact Rounded
+xadd252 add 10634446.5E+475783861 50.7213056E+17807809 -> 1.06344465E+475783868 Inexact Rounded
+xcom252 compare 10634446.5E+475783861 50.7213056E+17807809 -> 1
+xdiv252 divide 10634446.5E+475783861 50.7213056E+17807809 -> 2.09664289E+457976057 Inexact Rounded
+xdvi252 divideint 10634446.5E+475783861 50.7213056E+17807809 -> NaN Division_impossible
+xmul252 multiply 10634446.5E+475783861 50.7213056E+17807809 -> 5.39393011E+493591678 Inexact Rounded
+xpow252 power 10634446.5E+475783861 5 -> Infinity Overflow Inexact Rounded
+xrem252 remainder 10634446.5E+475783861 50.7213056E+17807809 -> NaN Division_impossible
+xsub252 subtract 10634446.5E+475783861 50.7213056E+17807809 -> 1.06344465E+475783868 Inexact Rounded
+xadd253 add -162726.257E-597285918 -4391.54799 -> -4391.54799 Inexact Rounded
+xcom253 compare -162726.257E-597285918 -4391.54799 -> 1
+xdiv253 divide -162726.257E-597285918 -4391.54799 -> 3.70544185E-597285917 Inexact Rounded
+xdvi253 divideint -162726.257E-597285918 -4391.54799 -> 0
+xmul253 multiply -162726.257E-597285918 -4391.54799 -> 7.14620167E-597285910 Inexact Rounded
+xpow253 power -162726.257E-597285918 -4392 -> Infinity Overflow Inexact Rounded
+xrem253 remainder -162726.257E-597285918 -4391.54799 -> -1.62726257E-597285913
+xsub253 subtract -162726.257E-597285918 -4391.54799 -> 4391.54799 Inexact Rounded
+xadd254 add 700354586.E-99856707 7198.0493E+436250299 -> 7.19804930E+436250302 Inexact Rounded
+xcom254 compare 700354586.E-99856707 7198.0493E+436250299 -> -1
+xdiv254 divide 700354586.E-99856707 7198.0493E+436250299 -> 9.72978312E-536107002 Inexact Rounded
+xdvi254 divideint 700354586.E-99856707 7198.0493E+436250299 -> 0
+xmul254 multiply 700354586.E-99856707 7198.0493E+436250299 -> 5.04118684E+336393604 Inexact Rounded
+xpow254 power 700354586.E-99856707 7 -> 8.26467610E-698996888 Inexact Rounded
+xrem254 remainder 700354586.E-99856707 7198.0493E+436250299 -> 7.00354586E-99856699
+xsub254 subtract 700354586.E-99856707 7198.0493E+436250299 -> -7.19804930E+436250302 Inexact Rounded
+xadd255 add 39617663E-463704664 -895.290346 -> -895.290346 Inexact Rounded
+xcom255 compare 39617663E-463704664 -895.290346 -> 1
+xdiv255 divide 39617663E-463704664 -895.290346 -> -4.42511898E-463704660 Inexact Rounded
+xdvi255 divideint 39617663E-463704664 -895.290346 -> -0
+xmul255 multiply 39617663E-463704664 -895.290346 -> -3.54693112E-463704654 Inexact Rounded
+xpow255 power 39617663E-463704664 -895 -> Infinity Overflow Inexact Rounded
+xrem255 remainder 39617663E-463704664 -895.290346 -> 3.9617663E-463704657
+xsub255 subtract 39617663E-463704664 -895.290346 -> 895.290346 Inexact Rounded
+xadd256 add 5350882.59 -36329829 -> -30978946.4 Inexact Rounded
+xcom256 compare 5350882.59 -36329829 -> 1
+xdiv256 divide 5350882.59 -36329829 -> -0.147286204 Inexact Rounded
+xdvi256 divideint 5350882.59 -36329829 -> -0
+xmul256 multiply 5350882.59 -36329829 -> -1.94396649E+14 Inexact Rounded
+xpow256 power 5350882.59 -36329829 -> 9.77006107E-244442546 Inexact Rounded
+xrem256 remainder 5350882.59 -36329829 -> 5350882.59
+xsub256 subtract 5350882.59 -36329829 -> 41680711.6 Inexact Rounded
+xadd257 add 91966.4084E+210382952 166740.46E-42001390 -> 9.19664084E+210382956 Inexact Rounded
+xcom257 compare 91966.4084E+210382952 166740.46E-42001390 -> 1
+xdiv257 divide 91966.4084E+210382952 166740.46E-42001390 -> 5.51554244E+252384341 Inexact Rounded
+xdvi257 divideint 91966.4084E+210382952 166740.46E-42001390 -> NaN Division_impossible
+xmul257 multiply 91966.4084E+210382952 166740.46E-42001390 -> 1.53345212E+168381572 Inexact Rounded
+xpow257 power 91966.4084E+210382952 2 -> 8.45782027E+420765913 Inexact Rounded
+xrem257 remainder 91966.4084E+210382952 166740.46E-42001390 -> NaN Division_impossible
+xsub257 subtract 91966.4084E+210382952 166740.46E-42001390 -> 9.19664084E+210382956 Inexact Rounded
+xadd258 add 231899031.E-481759076 726.337100 -> 726.337100 Inexact Rounded
+xcom258 compare 231899031.E-481759076 726.337100 -> -1
+xdiv258 divide 231899031.E-481759076 726.337100 -> 3.19271907E-481759071 Inexact Rounded
+xdvi258 divideint 231899031.E-481759076 726.337100 -> 0
+xmul258 multiply 231899031.E-481759076 726.337100 -> 1.68436870E-481759065 Inexact Rounded
+xpow258 power 231899031.E-481759076 726 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem258 remainder 231899031.E-481759076 726.337100 -> 2.31899031E-481759068
+xsub258 subtract 231899031.E-481759076 726.337100 -> -726.337100 Inexact Rounded
+xadd259 add -9611312.33 22109735.9 -> 12498423.6 Inexact Rounded
+xcom259 compare -9611312.33 22109735.9 -> -1
+xdiv259 divide -9611312.33 22109735.9 -> -0.434709504 Inexact Rounded
+xdvi259 divideint -9611312.33 22109735.9 -> -0
+xmul259 multiply -9611312.33 22109735.9 -> -2.12503577E+14 Inexact Rounded
+xpow259 power -9611312.33 22109736 -> 6.74530828E+154387481 Inexact Rounded
+xrem259 remainder -9611312.33 22109735.9 -> -9611312.33
+xsub259 subtract -9611312.33 22109735.9 -> -31721048.2 Inexact Rounded
+xadd260 add -5604938.15E-36812542 735937577. -> 735937577 Inexact Rounded
+xcom260 compare -5604938.15E-36812542 735937577. -> -1
+xdiv260 divide -5604938.15E-36812542 735937577. -> -7.61605104E-36812545 Inexact Rounded
+xdvi260 divideint -5604938.15E-36812542 735937577. -> -0
+xmul260 multiply -5604938.15E-36812542 735937577. -> -4.12488460E-36812527 Inexact Rounded
+xpow260 power -5604938.15E-36812542 735937577 -> -0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem260 remainder -5604938.15E-36812542 735937577. -> -5.60493815E-36812536
+xsub260 subtract -5604938.15E-36812542 735937577. -> -735937577 Inexact Rounded
+xadd261 add 693881413. 260547224E-480281418 -> 693881413 Inexact Rounded
+xcom261 compare 693881413. 260547224E-480281418 -> 1
+xdiv261 divide 693881413. 260547224E-480281418 -> 2.66316947E+480281418 Inexact Rounded
+xdvi261 divideint 693881413. 260547224E-480281418 -> NaN Division_impossible
+xmul261 multiply 693881413. 260547224E-480281418 -> 1.80788876E-480281401 Inexact Rounded
+xpow261 power 693881413. 3 -> 3.34084066E+26 Inexact Rounded
+xrem261 remainder 693881413. 260547224E-480281418 -> NaN Division_impossible
+xsub261 subtract 693881413. 260547224E-480281418 -> 693881413 Inexact Rounded
+xadd262 add -34865.7378E-368768024 2297117.88 -> 2297117.88 Inexact Rounded
+xcom262 compare -34865.7378E-368768024 2297117.88 -> -1
+xdiv262 divide -34865.7378E-368768024 2297117.88 -> -1.51780360E-368768026 Inexact Rounded
+xdvi262 divideint -34865.7378E-368768024 2297117.88 -> -0
+xmul262 multiply -34865.7378E-368768024 2297117.88 -> -8.00907097E-368768014 Inexact Rounded
+xpow262 power -34865.7378E-368768024 2297118 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem262 remainder -34865.7378E-368768024 2297117.88 -> -3.48657378E-368768020
+xsub262 subtract -34865.7378E-368768024 2297117.88 -> -2297117.88 Inexact Rounded
+xadd263 add 1123.32456 7.86747918E+930888796 -> 7.86747918E+930888796 Inexact Rounded
+xcom263 compare 1123.32456 7.86747918E+930888796 -> -1
+xdiv263 divide 1123.32456 7.86747918E+930888796 -> 1.42780748E-930888794 Inexact Rounded
+xdvi263 divideint 1123.32456 7.86747918E+930888796 -> 0
+xmul263 multiply 1123.32456 7.86747918E+930888796 -> 8.83773259E+930888799 Inexact Rounded
+xpow263 power 1123.32456 8 -> 2.53537401E+24 Inexact Rounded
+xrem263 remainder 1123.32456 7.86747918E+930888796 -> 1123.32456
+xsub263 subtract 1123.32456 7.86747918E+930888796 -> -7.86747918E+930888796 Inexact Rounded
+xadd264 add 56.6607465E+467812565 909552512E+764516200 -> 9.09552512E+764516208 Inexact Rounded
+xcom264 compare 56.6607465E+467812565 909552512E+764516200 -> -1
+xdiv264 divide 56.6607465E+467812565 909552512E+764516200 -> 6.22951899E-296703643 Inexact Rounded
+xdvi264 divideint 56.6607465E+467812565 909552512E+764516200 -> 0
+xmul264 multiply 56.6607465E+467812565 909552512E+764516200 -> Infinity Inexact Overflow Rounded
+xpow264 power 56.6607465E+467812565 9 -> Infinity Overflow Inexact Rounded
+xrem264 remainder 56.6607465E+467812565 909552512E+764516200 -> 5.66607465E+467812566
+xsub264 subtract 56.6607465E+467812565 909552512E+764516200 -> -9.09552512E+764516208 Inexact Rounded
+xadd265 add -1.85771840E+365552540 -73028339.7 -> -1.85771840E+365552540 Inexact Rounded
+xcom265 compare -1.85771840E+365552540 -73028339.7 -> -1
+xdiv265 divide -1.85771840E+365552540 -73028339.7 -> 2.54383217E+365552532 Inexact Rounded
+xdvi265 divideint -1.85771840E+365552540 -73028339.7 -> NaN Division_impossible
+xmul265 multiply -1.85771840E+365552540 -73028339.7 -> 1.35666090E+365552548 Inexact Rounded
+xpow265 power -1.85771840E+365552540 -73028340 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem265 remainder -1.85771840E+365552540 -73028339.7 -> NaN Division_impossible
+xsub265 subtract -1.85771840E+365552540 -73028339.7 -> -1.85771840E+365552540 Inexact Rounded
+xadd266 add 34.1935525 -40767.6450 -> -40733.4514 Inexact Rounded
+xcom266 compare 34.1935525 -40767.6450 -> 1
+xdiv266 divide 34.1935525 -40767.6450 -> -0.000838742402 Inexact Rounded
+xdvi266 divideint 34.1935525 -40767.6450 -> -0
+xmul266 multiply 34.1935525 -40767.6450 -> -1393990.61 Inexact Rounded
+xpow266 power 34.1935525 -40768 -> 1.45174210E-62536 Inexact Rounded
+xrem266 remainder 34.1935525 -40767.6450 -> 34.1935525
+xsub266 subtract 34.1935525 -40767.6450 -> 40801.8386 Inexact Rounded
+xadd267 add 26.0009168E+751618294 -304019.929 -> 2.60009168E+751618295 Inexact Rounded
+xcom267 compare 26.0009168E+751618294 -304019.929 -> 1
+xdiv267 divide 26.0009168E+751618294 -304019.929 -> -8.55237250E+751618289 Inexact Rounded
+xdvi267 divideint 26.0009168E+751618294 -304019.929 -> NaN Division_impossible
+xmul267 multiply 26.0009168E+751618294 -304019.929 -> -7.90479688E+751618300 Inexact Rounded
+xpow267 power 26.0009168E+751618294 -304020 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem267 remainder 26.0009168E+751618294 -304019.929 -> NaN Division_impossible
+xsub267 subtract 26.0009168E+751618294 -304019.929 -> 2.60009168E+751618295 Inexact Rounded
+xadd268 add -58.4853072E+588540055 -4647.3205 -> -5.84853072E+588540056 Inexact Rounded
+xcom268 compare -58.4853072E+588540055 -4647.3205 -> -1
+xdiv268 divide -58.4853072E+588540055 -4647.3205 -> 1.25847372E+588540053 Inexact Rounded
+xdvi268 divideint -58.4853072E+588540055 -4647.3205 -> NaN Division_impossible
+xmul268 multiply -58.4853072E+588540055 -4647.3205 -> 2.71799967E+588540060 Inexact Rounded
+xpow268 power -58.4853072E+588540055 -4647 -> -0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem268 remainder -58.4853072E+588540055 -4647.3205 -> NaN Division_impossible
+xsub268 subtract -58.4853072E+588540055 -4647.3205 -> -5.84853072E+588540056 Inexact Rounded
+xadd269 add 51.025101 -4467691.57 -> -4467640.54 Inexact Rounded
+xcom269 compare 51.025101 -4467691.57 -> 1
+xdiv269 divide 51.025101 -4467691.57 -> -0.0000114209095 Inexact Rounded
+xdvi269 divideint 51.025101 -4467691.57 -> -0
+xmul269 multiply 51.025101 -4467691.57 -> -227964414 Inexact Rounded
+xpow269 power 51.025101 -4467692 -> 4.49462589E-7629853 Inexact Rounded
+xrem269 remainder 51.025101 -4467691.57 -> 51.025101
+xsub269 subtract 51.025101 -4467691.57 -> 4467742.60 Inexact Rounded
+xadd270 add -2214.76582 379785372E+223117572 -> 3.79785372E+223117580 Inexact Rounded
+xcom270 compare -2214.76582 379785372E+223117572 -> -1
+xdiv270 divide -2214.76582 379785372E+223117572 -> -5.83162487E-223117578 Inexact Rounded
+xdvi270 divideint -2214.76582 379785372E+223117572 -> -0
+xmul270 multiply -2214.76582 379785372E+223117572 -> -8.41135661E+223117583 Inexact Rounded
+xpow270 power -2214.76582 4 -> 2.40608658E+13 Inexact Rounded
+xrem270 remainder -2214.76582 379785372E+223117572 -> -2214.76582
+xsub270 subtract -2214.76582 379785372E+223117572 -> -3.79785372E+223117580 Inexact Rounded
+xadd271 add -2564.75207E-841443929 -653498187 -> -653498187 Inexact Rounded
+xcom271 compare -2564.75207E-841443929 -653498187 -> 1
+xdiv271 divide -2564.75207E-841443929 -653498187 -> 3.92465063E-841443935 Inexact Rounded
+xdvi271 divideint -2564.75207E-841443929 -653498187 -> 0
+xmul271 multiply -2564.75207E-841443929 -653498187 -> 1.67606083E-841443917 Inexact Rounded
+xpow271 power -2564.75207E-841443929 -653498187 -> -Infinity Overflow Inexact Rounded
+xrem271 remainder -2564.75207E-841443929 -653498187 -> -2.56475207E-841443926
+xsub271 subtract -2564.75207E-841443929 -653498187 -> 653498187 Inexact Rounded
+xadd272 add 513115529. 27775075.6E+217133352 -> 2.77750756E+217133359 Inexact Rounded
+xcom272 compare 513115529. 27775075.6E+217133352 -> -1
+xdiv272 divide 513115529. 27775075.6E+217133352 -> 1.84739562E-217133351 Inexact Rounded
+xdvi272 divideint 513115529. 27775075.6E+217133352 -> 0
+xmul272 multiply 513115529. 27775075.6E+217133352 -> 1.42518226E+217133368 Inexact Rounded
+xpow272 power 513115529. 3 -> 1.35096929E+26 Inexact Rounded
+xrem272 remainder 513115529. 27775075.6E+217133352 -> 513115529
+xsub272 subtract 513115529. 27775075.6E+217133352 -> -2.77750756E+217133359 Inexact Rounded
+xadd273 add -247157.208 -532990.453 -> -780147.661
+xcom273 compare -247157.208 -532990.453 -> 1
+xdiv273 divide -247157.208 -532990.453 -> 0.463717890 Inexact Rounded
+xdvi273 divideint -247157.208 -532990.453 -> 0
+xmul273 multiply -247157.208 -532990.453 -> 1.31732432E+11 Inexact Rounded
+xpow273 power -247157.208 -532990 -> 1.48314033E-2874401 Inexact Rounded
+xrem273 remainder -247157.208 -532990.453 -> -247157.208
+xsub273 subtract -247157.208 -532990.453 -> 285833.245
+xadd274 add 40.2490764E-339482253 7626.85442E+594264540 -> 7.62685442E+594264543 Inexact Rounded
+xcom274 compare 40.2490764E-339482253 7626.85442E+594264540 -> -1
+xdiv274 divide 40.2490764E-339482253 7626.85442E+594264540 -> 5.27728395E-933746796 Inexact Rounded
+xdvi274 divideint 40.2490764E-339482253 7626.85442E+594264540 -> 0
+xmul274 multiply 40.2490764E-339482253 7626.85442E+594264540 -> 3.06973846E+254782292 Inexact Rounded
+xpow274 power 40.2490764E-339482253 8 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem274 remainder 40.2490764E-339482253 7626.85442E+594264540 -> 4.02490764E-339482252
+xsub274 subtract 40.2490764E-339482253 7626.85442E+594264540 -> -7.62685442E+594264543 Inexact Rounded
+xadd275 add -1156008.8 -8870382.36 -> -10026391.2 Inexact Rounded
+xcom275 compare -1156008.8 -8870382.36 -> 1
+xdiv275 divide -1156008.8 -8870382.36 -> 0.130322319 Inexact Rounded
+xdvi275 divideint -1156008.8 -8870382.36 -> 0
+xmul275 multiply -1156008.8 -8870382.36 -> 1.02542401E+13 Inexact Rounded
+xpow275 power -1156008.8 -8870382 -> 4.32494996E-53780782 Inexact Rounded
+xrem275 remainder -1156008.8 -8870382.36 -> -1156008.80
+xsub275 subtract -1156008.8 -8870382.36 -> 7714373.56
+xadd276 add 880097928. -52455011.1E+204538218 -> -5.24550111E+204538225 Inexact Rounded
+xcom276 compare 880097928. -52455011.1E+204538218 -> 1
+xdiv276 divide 880097928. -52455011.1E+204538218 -> -1.67781478E-204538217 Inexact Rounded
+xdvi276 divideint 880097928. -52455011.1E+204538218 -> -0
+xmul276 multiply 880097928. -52455011.1E+204538218 -> -4.61655466E+204538234 Inexact Rounded
+xpow276 power 880097928. -5 -> 1.89384751E-45 Inexact Rounded
+xrem276 remainder 880097928. -52455011.1E+204538218 -> 880097928
+xsub276 subtract 880097928. -52455011.1E+204538218 -> 5.24550111E+204538225 Inexact Rounded
+xadd277 add 5796.2524 34458329.7E+832129426 -> 3.44583297E+832129433 Inexact Rounded
+xcom277 compare 5796.2524 34458329.7E+832129426 -> -1
+xdiv277 divide 5796.2524 34458329.7E+832129426 -> 1.68210486E-832129430 Inexact Rounded
+xdvi277 divideint 5796.2524 34458329.7E+832129426 -> 0
+xmul277 multiply 5796.2524 34458329.7E+832129426 -> 1.99729176E+832129437 Inexact Rounded
+xpow277 power 5796.2524 3 -> 1.94734037E+11 Inexact Rounded
+xrem277 remainder 5796.2524 34458329.7E+832129426 -> 5796.2524
+xsub277 subtract 5796.2524 34458329.7E+832129426 -> -3.44583297E+832129433 Inexact Rounded
+xadd278 add 27.1000923E-218032223 -45.0198341 -> -45.0198341 Inexact Rounded
+xcom278 compare 27.1000923E-218032223 -45.0198341 -> 1
+xdiv278 divide 27.1000923E-218032223 -45.0198341 -> -6.01958955E-218032224 Inexact Rounded
+xdvi278 divideint 27.1000923E-218032223 -45.0198341 -> -0
+xmul278 multiply 27.1000923E-218032223 -45.0198341 -> -1.22004166E-218032220 Inexact Rounded
+xpow278 power 27.1000923E-218032223 -45 -> Infinity Overflow Inexact Rounded
+xrem278 remainder 27.1000923E-218032223 -45.0198341 -> 2.71000923E-218032222
+xsub278 subtract 27.1000923E-218032223 -45.0198341 -> 45.0198341 Inexact Rounded
+xadd279 add 42643477.8 26118465E-730390549 -> 42643477.8 Inexact Rounded
+xcom279 compare 42643477.8 26118465E-730390549 -> 1
+xdiv279 divide 42643477.8 26118465E-730390549 -> 1.63269464E+730390549 Inexact Rounded
+xdvi279 divideint 42643477.8 26118465E-730390549 -> NaN Division_impossible
+xmul279 multiply 42643477.8 26118465E-730390549 -> 1.11378218E-730390534 Inexact Rounded
+xpow279 power 42643477.8 3 -> 7.75457230E+22 Inexact Rounded
+xrem279 remainder 42643477.8 26118465E-730390549 -> NaN Division_impossible
+xsub279 subtract 42643477.8 26118465E-730390549 -> 42643477.8 Inexact Rounded
+xadd280 add -31918.9176E-163031657 -21.5422824E-807317258 -> -3.19189176E-163031653 Inexact Rounded
+xcom280 compare -31918.9176E-163031657 -21.5422824E-807317258 -> -1
+xdiv280 divide -31918.9176E-163031657 -21.5422824E-807317258 -> 1.48168690E+644285604 Inexact Rounded
+xdvi280 divideint -31918.9176E-163031657 -21.5422824E-807317258 -> NaN Division_impossible
+xmul280 multiply -31918.9176E-163031657 -21.5422824E-807317258 -> 6.87606337E-970348910 Inexact Rounded
+xpow280 power -31918.9176E-163031657 -2 -> 9.81530250E+326063304 Inexact Rounded
+xrem280 remainder -31918.9176E-163031657 -21.5422824E-807317258 -> NaN Division_impossible
+xsub280 subtract -31918.9176E-163031657 -21.5422824E-807317258 -> -3.19189176E-163031653 Inexact Rounded
+xadd281 add 84224841.0 2.62548255E+647087608 -> 2.62548255E+647087608 Inexact Rounded
+xcom281 compare 84224841.0 2.62548255E+647087608 -> -1
+xdiv281 divide 84224841.0 2.62548255E+647087608 -> 3.20797565E-647087601 Inexact Rounded
+xdvi281 divideint 84224841.0 2.62548255E+647087608 -> 0
+xmul281 multiply 84224841.0 2.62548255E+647087608 -> 2.21130850E+647087616 Inexact Rounded
+xpow281 power 84224841.0 3 -> 5.97476185E+23 Inexact Rounded
+xrem281 remainder 84224841.0 2.62548255E+647087608 -> 84224841.0
+xsub281 subtract 84224841.0 2.62548255E+647087608 -> -2.62548255E+647087608 Inexact Rounded
+xadd282 add -64413698.9 -6674.1055E-701047852 -> -64413698.9 Inexact Rounded
+xcom282 compare -64413698.9 -6674.1055E-701047852 -> -1
+xdiv282 divide -64413698.9 -6674.1055E-701047852 -> 9.65128569E+701047855 Inexact Rounded
+xdvi282 divideint -64413698.9 -6674.1055E-701047852 -> NaN Division_impossible
+xmul282 multiply -64413698.9 -6674.1055E-701047852 -> 4.29903822E-701047841 Inexact Rounded
+xpow282 power -64413698.9 -7 -> -2.17346338E-55 Inexact Rounded
+xrem282 remainder -64413698.9 -6674.1055E-701047852 -> NaN Division_impossible
+xsub282 subtract -64413698.9 -6674.1055E-701047852 -> -64413698.9 Inexact Rounded
+xadd283 add -62.5059208 9.5795779E-898350012 -> -62.5059208 Inexact Rounded
+xcom283 compare -62.5059208 9.5795779E-898350012 -> -1
+xdiv283 divide -62.5059208 9.5795779E-898350012 -> -6.52491388E+898350012 Inexact Rounded
+xdvi283 divideint -62.5059208 9.5795779E-898350012 -> NaN Division_impossible
+xmul283 multiply -62.5059208 9.5795779E-898350012 -> -5.98780338E-898350010 Inexact Rounded
+xpow283 power -62.5059208 10 -> 9.10356659E+17 Inexact Rounded
+xrem283 remainder -62.5059208 9.5795779E-898350012 -> NaN Division_impossible
+xsub283 subtract -62.5059208 9.5795779E-898350012 -> -62.5059208 Inexact Rounded
+xadd284 add 9090950.80 436.400932 -> 9091387.20 Inexact Rounded
+xcom284 compare 9090950.80 436.400932 -> 1
+xdiv284 divide 9090950.80 436.400932 -> 20831.6485 Inexact Rounded
+xdvi284 divideint 9090950.80 436.400932 -> 20831
+xmul284 multiply 9090950.80 436.400932 -> 3.96729940E+9 Inexact Rounded
+xpow284 power 9090950.80 436 -> 8.98789557E+3033 Inexact Rounded
+xrem284 remainder 9090950.80 436.400932 -> 282.985508
+xsub284 subtract 9090950.80 436.400932 -> 9090514.40 Inexact Rounded
+xadd285 add -89833825.7E+329205393 -779430.194 -> -8.98338257E+329205400 Inexact Rounded
+xcom285 compare -89833825.7E+329205393 -779430.194 -> -1
+xdiv285 divide -89833825.7E+329205393 -779430.194 -> 1.15255768E+329205395 Inexact Rounded
+xdvi285 divideint -89833825.7E+329205393 -779430.194 -> NaN Division_impossible
+xmul285 multiply -89833825.7E+329205393 -779430.194 -> 7.00191962E+329205406 Inexact Rounded
+xpow285 power -89833825.7E+329205393 -779430 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem285 remainder -89833825.7E+329205393 -779430.194 -> NaN Division_impossible
+xsub285 subtract -89833825.7E+329205393 -779430.194 -> -8.98338257E+329205400 Inexact Rounded
+xadd286 add -714562.019E+750205688 704079764 -> -7.14562019E+750205693 Inexact Rounded
+xcom286 compare -714562.019E+750205688 704079764 -> -1
+xdiv286 divide -714562.019E+750205688 704079764 -> -1.01488788E+750205685 Inexact Rounded
+xdvi286 divideint -714562.019E+750205688 704079764 -> NaN Division_impossible
+xmul286 multiply -714562.019E+750205688 704079764 -> -5.03108658E+750205702 Inexact Rounded
+xpow286 power -714562.019E+750205688 704079764 -> Infinity Overflow Inexact Rounded
+xrem286 remainder -714562.019E+750205688 704079764 -> NaN Division_impossible
+xsub286 subtract -714562.019E+750205688 704079764 -> -7.14562019E+750205693 Inexact Rounded
+xadd287 add -584537670. 31139.7737E-146687560 -> -584537670 Inexact Rounded
+xcom287 compare -584537670. 31139.7737E-146687560 -> -1
+xdiv287 divide -584537670. 31139.7737E-146687560 -> -1.87714168E+146687564 Inexact Rounded
+xdvi287 divideint -584537670. 31139.7737E-146687560 -> NaN Division_impossible
+xmul287 multiply -584537670. 31139.7737E-146687560 -> -1.82023708E-146687547 Inexact Rounded
+xpow287 power -584537670. 3 -> -1.99727337E+26 Inexact Rounded
+xrem287 remainder -584537670. 31139.7737E-146687560 -> NaN Division_impossible
+xsub287 subtract -584537670. 31139.7737E-146687560 -> -584537670 Inexact Rounded
+xadd288 add -4.18074650E-858746879 571035.277E-279409165 -> 5.71035277E-279409160 Inexact Rounded
+xcom288 compare -4.18074650E-858746879 571035.277E-279409165 -> -1
+xdiv288 divide -4.18074650E-858746879 571035.277E-279409165 -> -7.32134540E-579337720 Inexact Rounded
+xdvi288 divideint -4.18074650E-858746879 571035.277E-279409165 -> -0
+xmul288 multiply -4.18074650E-858746879 571035.277E-279409165 -> -0E-1000000007 Underflow Subnormal Inexact Rounded
+xpow288 power -4.18074650E-858746879 6 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem288 remainder -4.18074650E-858746879 571035.277E-279409165 -> -4.18074650E-858746879
+xsub288 subtract -4.18074650E-858746879 571035.277E-279409165 -> -5.71035277E-279409160 Inexact Rounded
+xadd289 add 5.15309635 -695649.219E+451948183 -> -6.95649219E+451948188 Inexact Rounded
+xcom289 compare 5.15309635 -695649.219E+451948183 -> 1
+xdiv289 divide 5.15309635 -695649.219E+451948183 -> -7.40760747E-451948189 Inexact Rounded
+xdvi289 divideint 5.15309635 -695649.219E+451948183 -> -0
+xmul289 multiply 5.15309635 -695649.219E+451948183 -> -3.58474745E+451948189 Inexact Rounded
+xpow289 power 5.15309635 -7 -> 0.0000103638749 Inexact Rounded
+xrem289 remainder 5.15309635 -695649.219E+451948183 -> 5.15309635
+xsub289 subtract 5.15309635 -695649.219E+451948183 -> 6.95649219E+451948188 Inexact Rounded
+xadd290 add -940030153.E+83797657 -4.11510193 -> -9.40030153E+83797665 Inexact Rounded
+xcom290 compare -940030153.E+83797657 -4.11510193 -> -1
+xdiv290 divide -940030153.E+83797657 -4.11510193 -> 2.28434233E+83797665 Inexact Rounded
+xdvi290 divideint -940030153.E+83797657 -4.11510193 -> NaN Division_impossible
+xmul290 multiply -940030153.E+83797657 -4.11510193 -> 3.86831990E+83797666 Inexact Rounded
+xpow290 power -940030153.E+83797657 -4 -> 1.28065710E-335190664 Inexact Rounded
+xrem290 remainder -940030153.E+83797657 -4.11510193 -> NaN Division_impossible
+xsub290 subtract -940030153.E+83797657 -4.11510193 -> -9.40030153E+83797665 Inexact Rounded
+xadd291 add 89088.9683E+587739290 1.31932110 -> 8.90889683E+587739294 Inexact Rounded
+xcom291 compare 89088.9683E+587739290 1.31932110 -> 1
+xdiv291 divide 89088.9683E+587739290 1.31932110 -> 6.75263727E+587739294 Inexact Rounded
+xdvi291 divideint 89088.9683E+587739290 1.31932110 -> NaN Division_impossible
+xmul291 multiply 89088.9683E+587739290 1.31932110 -> 1.17536956E+587739295 Inexact Rounded
+xpow291 power 89088.9683E+587739290 1 -> 8.90889683E+587739294
+xrem291 remainder 89088.9683E+587739290 1.31932110 -> NaN Division_impossible
+xsub291 subtract 89088.9683E+587739290 1.31932110 -> 8.90889683E+587739294 Inexact Rounded
+xadd292 add 3336750 6.47961126 -> 3336756.48 Inexact Rounded
+xcom292 compare 3336750 6.47961126 -> 1
+xdiv292 divide 3336750 6.47961126 -> 514961.448 Inexact Rounded
+xdvi292 divideint 3336750 6.47961126 -> 514961
+xmul292 multiply 3336750 6.47961126 -> 21620842.9 Inexact Rounded
+xpow292 power 3336750 6 -> 1.38019997E+39 Inexact Rounded
+xrem292 remainder 3336750 6.47961126 -> 2.90593914
+xsub292 subtract 3336750 6.47961126 -> 3336743.52 Inexact Rounded
+xadd293 add 904654622. 692065270.E+329081915 -> 6.92065270E+329081923 Inexact Rounded
+xcom293 compare 904654622. 692065270.E+329081915 -> -1
+xdiv293 divide 904654622. 692065270.E+329081915 -> 1.30718107E-329081915 Inexact Rounded
+xdvi293 divideint 904654622. 692065270.E+329081915 -> 0
+xmul293 multiply 904654622. 692065270.E+329081915 -> 6.26080045E+329081932 Inexact Rounded
+xpow293 power 904654622. 7 -> 4.95883485E+62 Inexact Rounded
+xrem293 remainder 904654622. 692065270.E+329081915 -> 904654622
+xsub293 subtract 904654622. 692065270.E+329081915 -> -6.92065270E+329081923 Inexact Rounded
+xadd294 add 304804380 -4681.23698 -> 304799699 Inexact Rounded
+xcom294 compare 304804380 -4681.23698 -> 1
+xdiv294 divide 304804380 -4681.23698 -> -65111.9312 Inexact Rounded
+xdvi294 divideint 304804380 -4681.23698 -> -65111
+xmul294 multiply 304804380 -4681.23698 -> -1.42686154E+12 Inexact Rounded
+xpow294 power 304804380 -4681 -> 1.98037102E-39714 Inexact Rounded
+xrem294 remainder 304804380 -4681.23698 -> 4358.99522
+xsub294 subtract 304804380 -4681.23698 -> 304809061 Inexact Rounded
+xadd295 add 674.55569 -82981.2684E+852890752 -> -8.29812684E+852890756 Inexact Rounded
+xcom295 compare 674.55569 -82981.2684E+852890752 -> 1
+xdiv295 divide 674.55569 -82981.2684E+852890752 -> -8.12901156E-852890755 Inexact Rounded
+xdvi295 divideint 674.55569 -82981.2684E+852890752 -> -0
+xmul295 multiply 674.55569 -82981.2684E+852890752 -> -5.59754868E+852890759 Inexact Rounded
+xpow295 power 674.55569 -8 -> 2.33269265E-23 Inexact Rounded
+xrem295 remainder 674.55569 -82981.2684E+852890752 -> 674.55569
+xsub295 subtract 674.55569 -82981.2684E+852890752 -> 8.29812684E+852890756 Inexact Rounded
+xadd296 add -5111.51025E-108006096 5448870.4E+279212255 -> 5.44887040E+279212261 Inexact Rounded
+xcom296 compare -5111.51025E-108006096 5448870.4E+279212255 -> -1
+xdiv296 divide -5111.51025E-108006096 5448870.4E+279212255 -> -9.38086222E-387218355 Inexact Rounded
+xdvi296 divideint -5111.51025E-108006096 5448870.4E+279212255 -> -0
+xmul296 multiply -5111.51025E-108006096 5448870.4E+279212255 -> -2.78519569E+171206169 Inexact Rounded
+xpow296 power -5111.51025E-108006096 5 -> -3.48936323E-540030462 Inexact Rounded
+xrem296 remainder -5111.51025E-108006096 5448870.4E+279212255 -> -5.11151025E-108006093
+xsub296 subtract -5111.51025E-108006096 5448870.4E+279212255 -> -5.44887040E+279212261 Inexact Rounded
+xadd297 add -2623.45068 -466463938. -> -466466561 Inexact Rounded
+xcom297 compare -2623.45068 -466463938. -> 1
+xdiv297 divide -2623.45068 -466463938. -> 0.00000562412325 Inexact Rounded
+xdvi297 divideint -2623.45068 -466463938. -> 0
+xmul297 multiply -2623.45068 -466463938. -> 1.22374514E+12 Inexact Rounded
+xpow297 power -2623.45068 -466463938 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem297 remainder -2623.45068 -466463938. -> -2623.45068
+xsub297 subtract -2623.45068 -466463938. -> 466461315 Inexact Rounded
+xadd298 add 299350.435 3373.33551 -> 302723.771 Inexact Rounded
+xcom298 compare 299350.435 3373.33551 -> 1
+xdiv298 divide 299350.435 3373.33551 -> 88.7401903 Inexact Rounded
+xdvi298 divideint 299350.435 3373.33551 -> 88
+xmul298 multiply 299350.435 3373.33551 -> 1.00980945E+9 Inexact Rounded
+xpow298 power 299350.435 3373 -> 1.42817370E+18471 Inexact Rounded
+xrem298 remainder 299350.435 3373.33551 -> 2496.91012
+xsub298 subtract 299350.435 3373.33551 -> 295977.099 Inexact Rounded
+xadd299 add -6589947.80 -2448.75933E-591549734 -> -6589947.80 Inexact Rounded
+xcom299 compare -6589947.80 -2448.75933E-591549734 -> -1
+xdiv299 divide -6589947.80 -2448.75933E-591549734 -> 2.69113739E+591549737 Inexact Rounded
+xdvi299 divideint -6589947.80 -2448.75933E-591549734 -> NaN Division_impossible
+xmul299 multiply -6589947.80 -2448.75933E-591549734 -> 1.61371962E-591549724 Inexact Rounded
+xpow299 power -6589947.80 -2 -> 2.30269305E-14 Inexact Rounded
+xrem299 remainder -6589947.80 -2448.75933E-591549734 -> NaN Division_impossible
+xsub299 subtract -6589947.80 -2448.75933E-591549734 -> -6589947.80 Inexact Rounded
+xadd300 add 3774.5358E-491090520 173.060090 -> 173.060090 Inexact Rounded
+xcom300 compare 3774.5358E-491090520 173.060090 -> -1
+xdiv300 divide 3774.5358E-491090520 173.060090 -> 2.18105503E-491090519 Inexact Rounded
+xdvi300 divideint 3774.5358E-491090520 173.060090 -> 0
+xmul300 multiply 3774.5358E-491090520 173.060090 -> 6.53221505E-491090515 Inexact Rounded
+xpow300 power 3774.5358E-491090520 173 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem300 remainder 3774.5358E-491090520 173.060090 -> 3.7745358E-491090517
+xsub300 subtract 3774.5358E-491090520 173.060090 -> -173.060090 Inexact Rounded
+xadd301 add -13.6783690 -453.610117 -> -467.288486 Rounded
+xcom301 compare -13.6783690 -453.610117 -> 1
+xdiv301 divide -13.6783690 -453.610117 -> 0.0301544619 Inexact Rounded
+xdvi301 divideint -13.6783690 -453.610117 -> 0
+xmul301 multiply -13.6783690 -453.610117 -> 6204.64656 Inexact Rounded
+xpow301 power -13.6783690 -454 -> 1.73948535E-516 Inexact Rounded
+xrem301 remainder -13.6783690 -453.610117 -> -13.6783690
+xsub301 subtract -13.6783690 -453.610117 -> 439.931748 Rounded
+xadd302 add -990100927.E-615244634 223801.421E+247632618 -> 2.23801421E+247632623 Inexact Rounded
+xcom302 compare -990100927.E-615244634 223801.421E+247632618 -> -1
+xdiv302 divide -990100927.E-615244634 223801.421E+247632618 -> -4.42401537E-862877249 Inexact Rounded
+xdvi302 divideint -990100927.E-615244634 223801.421E+247632618 -> -0
+xmul302 multiply -990100927.E-615244634 223801.421E+247632618 -> -2.21585994E-367612002 Inexact Rounded
+xpow302 power -990100927.E-615244634 2 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem302 remainder -990100927.E-615244634 223801.421E+247632618 -> -9.90100927E-615244626
+xsub302 subtract -990100927.E-615244634 223801.421E+247632618 -> -2.23801421E+247632623 Inexact Rounded
+xadd303 add 1275.10292 -667965353 -> -667964078 Inexact Rounded
+xcom303 compare 1275.10292 -667965353 -> 1
+xdiv303 divide 1275.10292 -667965353 -> -0.00000190893572 Inexact Rounded
+xdvi303 divideint 1275.10292 -667965353 -> -0
+xmul303 multiply 1275.10292 -667965353 -> -8.51724572E+11 Inexact Rounded
+xpow303 power 1275.10292 -667965353 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem303 remainder 1275.10292 -667965353 -> 1275.10292
+xsub303 subtract 1275.10292 -667965353 -> 667966628 Inexact Rounded
+xadd304 add -8.76375480E-596792197 992.077361 -> 992.077361 Inexact Rounded
+xcom304 compare -8.76375480E-596792197 992.077361 -> -1
+xdiv304 divide -8.76375480E-596792197 992.077361 -> -8.83374134E-596792200 Inexact Rounded
+xdvi304 divideint -8.76375480E-596792197 992.077361 -> -0
+xmul304 multiply -8.76375480E-596792197 992.077361 -> -8.69432273E-596792194 Inexact Rounded
+xpow304 power -8.76375480E-596792197 992 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem304 remainder -8.76375480E-596792197 992.077361 -> -8.76375480E-596792197
+xsub304 subtract -8.76375480E-596792197 992.077361 -> -992.077361 Inexact Rounded
+xadd305 add 953.976935E+385444720 96503.3378 -> 9.53976935E+385444722 Inexact Rounded
+xcom305 compare 953.976935E+385444720 96503.3378 -> 1
+xdiv305 divide 953.976935E+385444720 96503.3378 -> 9.88542942E+385444717 Inexact Rounded
+xdvi305 divideint 953.976935E+385444720 96503.3378 -> NaN Division_impossible
+xmul305 multiply 953.976935E+385444720 96503.3378 -> 9.20619584E+385444727 Inexact Rounded
+xpow305 power 953.976935E+385444720 96503 -> Infinity Overflow Inexact Rounded
+xrem305 remainder 953.976935E+385444720 96503.3378 -> NaN Division_impossible
+xsub305 subtract 953.976935E+385444720 96503.3378 -> 9.53976935E+385444722 Inexact Rounded
+xadd306 add 213577152 -986710073E+31900046 -> -9.86710073E+31900054 Inexact Rounded
+xcom306 compare 213577152 -986710073E+31900046 -> 1
+xdiv306 divide 213577152 -986710073E+31900046 -> -2.16453807E-31900047 Inexact Rounded
+xdvi306 divideint 213577152 -986710073E+31900046 -> -0
+xmul306 multiply 213577152 -986710073E+31900046 -> -2.10738727E+31900063 Inexact Rounded
+xpow306 power 213577152 -10 -> 5.06351487E-84 Inexact Rounded
+xrem306 remainder 213577152 -986710073E+31900046 -> 213577152
+xsub306 subtract 213577152 -986710073E+31900046 -> 9.86710073E+31900054 Inexact Rounded
+xadd307 add 91393.9398E-323439228 -135.701000 -> -135.701000 Inexact Rounded
+xcom307 compare 91393.9398E-323439228 -135.701000 -> 1
+xdiv307 divide 91393.9398E-323439228 -135.701000 -> -6.73494962E-323439226 Inexact Rounded
+xdvi307 divideint 91393.9398E-323439228 -135.701000 -> -0
+xmul307 multiply 91393.9398E-323439228 -135.701000 -> -1.24022490E-323439221 Inexact Rounded
+xpow307 power 91393.9398E-323439228 -136 -> Infinity Overflow Inexact Rounded
+xrem307 remainder 91393.9398E-323439228 -135.701000 -> 9.13939398E-323439224
+xsub307 subtract 91393.9398E-323439228 -135.701000 -> 135.701000 Inexact Rounded
+xadd308 add -396.503557 45757264.E-254363788 -> -396.503557 Inexact Rounded
+xcom308 compare -396.503557 45757264.E-254363788 -> -1
+xdiv308 divide -396.503557 45757264.E-254363788 -> -8.66536856E+254363782 Inexact Rounded
+xdvi308 divideint -396.503557 45757264.E-254363788 -> NaN Division_impossible
+xmul308 multiply -396.503557 45757264.E-254363788 -> -1.81429179E-254363778 Inexact Rounded
+xpow308 power -396.503557 5 -> -9.80021128E+12 Inexact Rounded
+xrem308 remainder -396.503557 45757264.E-254363788 -> NaN Division_impossible
+xsub308 subtract -396.503557 45757264.E-254363788 -> -396.503557 Inexact Rounded
+xadd309 add 59807846.1 1.53345254 -> 59807847.6 Inexact Rounded
+xcom309 compare 59807846.1 1.53345254 -> 1
+xdiv309 divide 59807846.1 1.53345254 -> 39002084.9 Inexact Rounded
+xdvi309 divideint 59807846.1 1.53345254 -> 39002084
+xmul309 multiply 59807846.1 1.53345254 -> 91712493.5 Inexact Rounded
+xpow309 power 59807846.1 2 -> 3.57697846E+15 Inexact Rounded
+xrem309 remainder 59807846.1 1.53345254 -> 1.32490664
+xsub309 subtract 59807846.1 1.53345254 -> 59807844.6 Inexact Rounded
+xadd310 add -8046158.45 8.3635397 -> -8046150.09 Inexact Rounded
+xcom310 compare -8046158.45 8.3635397 -> -1
+xdiv310 divide -8046158.45 8.3635397 -> -962051.803 Inexact Rounded
+xdvi310 divideint -8046158.45 8.3635397 -> -962051
+xmul310 multiply -8046158.45 8.3635397 -> -67294365.6 Inexact Rounded
+xpow310 power -8046158.45 8 -> 1.75674467E+55 Inexact Rounded
+xrem310 remainder -8046158.45 8.3635397 -> -6.7180753
+xsub310 subtract -8046158.45 8.3635397 -> -8046166.81 Inexact Rounded
+xadd311 add 55.1123381E+50627250 -94.0355047E-162540316 -> 5.51123381E+50627251 Inexact Rounded
+xcom311 compare 55.1123381E+50627250 -94.0355047E-162540316 -> 1
+xdiv311 divide 55.1123381E+50627250 -94.0355047E-162540316 -> -5.86080101E+213167565 Inexact Rounded
+xdvi311 divideint 55.1123381E+50627250 -94.0355047E-162540316 -> NaN Division_impossible
+xmul311 multiply 55.1123381E+50627250 -94.0355047E-162540316 -> -5.18251653E-111913063 Inexact Rounded
+xpow311 power 55.1123381E+50627250 -9 -> 2.13186881E-455645266 Inexact Rounded
+xrem311 remainder 55.1123381E+50627250 -94.0355047E-162540316 -> NaN Division_impossible
+xsub311 subtract 55.1123381E+50627250 -94.0355047E-162540316 -> 5.51123381E+50627251 Inexact Rounded
+xadd312 add -948.038054 3580.84510 -> 2632.80705 Inexact Rounded
+xcom312 compare -948.038054 3580.84510 -> -1
+xdiv312 divide -948.038054 3580.84510 -> -0.264752601 Inexact Rounded
+xdvi312 divideint -948.038054 3580.84510 -> -0
+xmul312 multiply -948.038054 3580.84510 -> -3394777.42 Inexact Rounded
+xpow312 power -948.038054 3581 -> -1.03058288E+10660 Inexact Rounded
+xrem312 remainder -948.038054 3580.84510 -> -948.038054
+xsub312 subtract -948.038054 3580.84510 -> -4528.88315 Inexact Rounded
+xadd313 add -6026.42752 -14.2286406E-334921364 -> -6026.42752 Inexact Rounded
+xcom313 compare -6026.42752 -14.2286406E-334921364 -> -1
+xdiv313 divide -6026.42752 -14.2286406E-334921364 -> 4.23542044E+334921366 Inexact Rounded
+xdvi313 divideint -6026.42752 -14.2286406E-334921364 -> NaN Division_impossible
+xmul313 multiply -6026.42752 -14.2286406E-334921364 -> 8.57478713E-334921360 Inexact Rounded
+xpow313 power -6026.42752 -1 -> -0.000165935788 Inexact Rounded
+xrem313 remainder -6026.42752 -14.2286406E-334921364 -> NaN Division_impossible
+xsub313 subtract -6026.42752 -14.2286406E-334921364 -> -6026.42752 Inexact Rounded
+xadd314 add 79551.5014 -538.186229 -> 79013.3152 Inexact Rounded
+xcom314 compare 79551.5014 -538.186229 -> 1
+xdiv314 divide 79551.5014 -538.186229 -> -147.814078 Inexact Rounded
+xdvi314 divideint 79551.5014 -538.186229 -> -147
+xmul314 multiply 79551.5014 -538.186229 -> -42813522.5 Inexact Rounded
+xpow314 power 79551.5014 -538 -> 2.82599389E-2637 Inexact Rounded
+xrem314 remainder 79551.5014 -538.186229 -> 438.125737
+xsub314 subtract 79551.5014 -538.186229 -> 80089.6876 Inexact Rounded
+xadd315 add 42706056.E+623578292 -690.327745 -> 4.27060560E+623578299 Inexact Rounded
+xcom315 compare 42706056.E+623578292 -690.327745 -> 1
+xdiv315 divide 42706056.E+623578292 -690.327745 -> -6.18634501E+623578296 Inexact Rounded
+xdvi315 divideint 42706056.E+623578292 -690.327745 -> NaN Division_impossible
+xmul315 multiply 42706056.E+623578292 -690.327745 -> -2.94811753E+623578302 Inexact Rounded
+xpow315 power 42706056.E+623578292 -690 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem315 remainder 42706056.E+623578292 -690.327745 -> NaN Division_impossible
+xsub315 subtract 42706056.E+623578292 -690.327745 -> 4.27060560E+623578299 Inexact Rounded
+xadd316 add 2454136.08E+502374077 856268.795E-356664934 -> 2.45413608E+502374083 Inexact Rounded
+xcom316 compare 2454136.08E+502374077 856268.795E-356664934 -> 1
+xdiv316 divide 2454136.08E+502374077 856268.795E-356664934 -> 2.86608142E+859039011 Inexact Rounded
+xdvi316 divideint 2454136.08E+502374077 856268.795E-356664934 -> NaN Division_impossible
+xmul316 multiply 2454136.08E+502374077 856268.795E-356664934 -> 2.10140014E+145709155 Inexact Rounded
+xpow316 power 2454136.08E+502374077 9 -> Infinity Overflow Inexact Rounded
+xrem316 remainder 2454136.08E+502374077 856268.795E-356664934 -> NaN Division_impossible
+xsub316 subtract 2454136.08E+502374077 856268.795E-356664934 -> 2.45413608E+502374083 Inexact Rounded
+xadd317 add -3264204.54 -42704.501 -> -3306909.04 Inexact Rounded
+xcom317 compare -3264204.54 -42704.501 -> -1
+xdiv317 divide -3264204.54 -42704.501 -> 76.4370140 Inexact Rounded
+xdvi317 divideint -3264204.54 -42704.501 -> 76
+xmul317 multiply -3264204.54 -42704.501 -> 1.39396226E+11 Inexact Rounded
+xpow317 power -3264204.54 -42705 -> -1.37293410E-278171 Inexact Rounded
+xrem317 remainder -3264204.54 -42704.501 -> -18662.464
+xsub317 subtract -3264204.54 -42704.501 -> -3221500.04 Inexact Rounded
+xadd318 add 1.21265492 44102.6073 -> 44103.8200 Inexact Rounded
+xcom318 compare 1.21265492 44102.6073 -> -1
+xdiv318 divide 1.21265492 44102.6073 -> 0.0000274962183 Inexact Rounded
+xdvi318 divideint 1.21265492 44102.6073 -> 0
+xmul318 multiply 1.21265492 44102.6073 -> 53481.2437 Inexact Rounded
+xpow318 power 1.21265492 44103 -> 1.15662573E+3693 Inexact Rounded
+xrem318 remainder 1.21265492 44102.6073 -> 1.21265492
+xsub318 subtract 1.21265492 44102.6073 -> -44101.3946 Inexact Rounded
+xadd319 add -19.054711E+975514652 -22144.0822 -> -1.90547110E+975514653 Inexact Rounded
+xcom319 compare -19.054711E+975514652 -22144.0822 -> -1
+xdiv319 divide -19.054711E+975514652 -22144.0822 -> 8.60487729E+975514648 Inexact Rounded
+xdvi319 divideint -19.054711E+975514652 -22144.0822 -> NaN Division_impossible
+xmul319 multiply -19.054711E+975514652 -22144.0822 -> 4.21949087E+975514657 Inexact Rounded
+xpow319 power -19.054711E+975514652 -22144 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem319 remainder -19.054711E+975514652 -22144.0822 -> NaN Division_impossible
+xsub319 subtract -19.054711E+975514652 -22144.0822 -> -1.90547110E+975514653 Inexact Rounded
+xadd320 add 745.78452 -1922.00670E+375923302 -> -1.92200670E+375923305 Inexact Rounded
+xcom320 compare 745.78452 -1922.00670E+375923302 -> 1
+xdiv320 divide 745.78452 -1922.00670E+375923302 -> -3.88023892E-375923303 Inexact Rounded
+xdvi320 divideint 745.78452 -1922.00670E+375923302 -> -0
+xmul320 multiply 745.78452 -1922.00670E+375923302 -> -1.43340284E+375923308 Inexact Rounded
+xpow320 power 745.78452 -2 -> 0.00000179793204 Inexact Rounded
+xrem320 remainder 745.78452 -1922.00670E+375923302 -> 745.78452
+xsub320 subtract 745.78452 -1922.00670E+375923302 -> 1.92200670E+375923305 Inexact Rounded
+xadd321 add -963717836 -823989308 -> -1.78770714E+9 Inexact Rounded
+xcom321 compare -963717836 -823989308 -> -1
+xdiv321 divide -963717836 -823989308 -> 1.16957566 Inexact Rounded
+xdvi321 divideint -963717836 -823989308 -> 1
+xmul321 multiply -963717836 -823989308 -> 7.94093193E+17 Inexact Rounded
+xpow321 power -963717836 -823989308 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem321 remainder -963717836 -823989308 -> -139728528
+xsub321 subtract -963717836 -823989308 -> -139728528
+xadd322 add 82.4185291E-321919303 -215747737.E-995147400 -> 8.24185291E-321919302 Inexact Rounded
+xcom322 compare 82.4185291E-321919303 -215747737.E-995147400 -> 1
+xdiv322 divide 82.4185291E-321919303 -215747737.E-995147400 -> -3.82013412E+673228090 Inexact Rounded
+xdvi322 divideint 82.4185291E-321919303 -215747737.E-995147400 -> NaN Division_impossible
+xmul322 multiply 82.4185291E-321919303 -215747737.E-995147400 -> -0E-1000000007 Underflow Subnormal Inexact Rounded
+xpow322 power 82.4185291E-321919303 -2 -> 1.47214396E+643838602 Inexact Rounded
+xrem322 remainder 82.4185291E-321919303 -215747737.E-995147400 -> NaN Division_impossible
+xsub322 subtract 82.4185291E-321919303 -215747737.E-995147400 -> 8.24185291E-321919302 Inexact Rounded
+xadd323 add -808328.607E-790810342 53075.7082 -> 53075.7082 Inexact Rounded
+xcom323 compare -808328.607E-790810342 53075.7082 -> -1
+xdiv323 divide -808328.607E-790810342 53075.7082 -> -1.52297281E-790810341 Inexact Rounded
+xdvi323 divideint -808328.607E-790810342 53075.7082 -> -0
+xmul323 multiply -808328.607E-790810342 53075.7082 -> -4.29026133E-790810332 Inexact Rounded
+xpow323 power -808328.607E-790810342 53076 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem323 remainder -808328.607E-790810342 53075.7082 -> -8.08328607E-790810337
+xsub323 subtract -808328.607E-790810342 53075.7082 -> -53075.7082 Inexact Rounded
+xadd324 add 700592.720 -698485.085 -> 2107.635
+xcom324 compare 700592.720 -698485.085 -> 1
+xdiv324 divide 700592.720 -698485.085 -> -1.00301744 Inexact Rounded
+xdvi324 divideint 700592.720 -698485.085 -> -1
+xmul324 multiply 700592.720 -698485.085 -> -4.89353566E+11 Inexact Rounded
+xpow324 power 700592.720 -698485 -> 8.83690000E-4082971 Inexact Rounded
+xrem324 remainder 700592.720 -698485.085 -> 2107.635
+xsub324 subtract 700592.720 -698485.085 -> 1399077.81 Inexact Rounded
+xadd325 add -80273928.0 661346.239 -> -79612581.8 Inexact Rounded
+xcom325 compare -80273928.0 661346.239 -> -1
+xdiv325 divide -80273928.0 661346.239 -> -121.379579 Inexact Rounded
+xdvi325 divideint -80273928.0 661346.239 -> -121
+xmul325 multiply -80273928.0 661346.239 -> -5.30888604E+13 Inexact Rounded
+xpow325 power -80273928.0 661346 -> 5.45664856E+5227658 Inexact Rounded
+xrem325 remainder -80273928.0 661346.239 -> -251033.081
+xsub325 subtract -80273928.0 661346.239 -> -80935274.2 Inexact Rounded
+xadd326 add -24018251.0E+819786764 59141.9600E-167165065 -> -2.40182510E+819786771 Inexact Rounded
+xcom326 compare -24018251.0E+819786764 59141.9600E-167165065 -> -1
+xdiv326 divide -24018251.0E+819786764 59141.9600E-167165065 -> -4.06111854E+986951831 Inexact Rounded
+xdvi326 divideint -24018251.0E+819786764 59141.9600E-167165065 -> NaN Division_impossible
+xmul326 multiply -24018251.0E+819786764 59141.9600E-167165065 -> -1.42048644E+652621711 Inexact Rounded
+xpow326 power -24018251.0E+819786764 6 -> Infinity Overflow Inexact Rounded
+xrem326 remainder -24018251.0E+819786764 59141.9600E-167165065 -> NaN Division_impossible
+xsub326 subtract -24018251.0E+819786764 59141.9600E-167165065 -> -2.40182510E+819786771 Inexact Rounded
+xadd327 add 2512953.3 -3769170.35E-993621645 -> 2512953.30 Inexact Rounded
+xcom327 compare 2512953.3 -3769170.35E-993621645 -> 1
+xdiv327 divide 2512953.3 -3769170.35E-993621645 -> -6.66712583E+993621644 Inexact Rounded
+xdvi327 divideint 2512953.3 -3769170.35E-993621645 -> NaN Division_impossible
+xmul327 multiply 2512953.3 -3769170.35E-993621645 -> -9.47174907E-993621633 Inexact Rounded
+xpow327 power 2512953.3 -4 -> 2.50762349E-26 Inexact Rounded
+xrem327 remainder 2512953.3 -3769170.35E-993621645 -> NaN Division_impossible
+xsub327 subtract 2512953.3 -3769170.35E-993621645 -> 2512953.30 Inexact Rounded
+xadd328 add -682.796370 71131.0224 -> 70448.2260 Inexact Rounded
+xcom328 compare -682.796370 71131.0224 -> -1
+xdiv328 divide -682.796370 71131.0224 -> -0.00959913617 Inexact Rounded
+xdvi328 divideint -682.796370 71131.0224 -> -0
+xmul328 multiply -682.796370 71131.0224 -> -48568003.9 Inexact Rounded
+xpow328 power -682.796370 71131 -> -9.28114741E+201605 Inexact Rounded
+xrem328 remainder -682.796370 71131.0224 -> -682.796370
+xsub328 subtract -682.796370 71131.0224 -> -71813.8188 Inexact Rounded
+xadd329 add 89.9997490 -4993.69831 -> -4903.69856 Inexact Rounded
+xcom329 compare 89.9997490 -4993.69831 -> 1
+xdiv329 divide 89.9997490 -4993.69831 -> -0.0180226644 Inexact Rounded
+xdvi329 divideint 89.9997490 -4993.69831 -> -0
+xmul329 multiply 89.9997490 -4993.69831 -> -449431.594 Inexact Rounded
+xpow329 power 89.9997490 -4994 -> 3.30336526E-9760 Inexact Rounded
+xrem329 remainder 89.9997490 -4993.69831 -> 89.9997490
+xsub329 subtract 89.9997490 -4993.69831 -> 5083.69806 Inexact Rounded
+xadd330 add 76563354.6E-112338836 278271.585E-511481095 -> 7.65633546E-112338829 Inexact Rounded
+xcom330 compare 76563354.6E-112338836 278271.585E-511481095 -> 1
+xdiv330 divide 76563354.6E-112338836 278271.585E-511481095 -> 2.75138960E+399142261 Inexact Rounded
+xdvi330 divideint 76563354.6E-112338836 278271.585E-511481095 -> NaN Division_impossible
+xmul330 multiply 76563354.6E-112338836 278271.585E-511481095 -> 2.13054060E-623819918 Inexact Rounded
+xpow330 power 76563354.6E-112338836 3 -> 4.48810347E-337016485 Inexact Rounded
+xrem330 remainder 76563354.6E-112338836 278271.585E-511481095 -> NaN Division_impossible
+xsub330 subtract 76563354.6E-112338836 278271.585E-511481095 -> 7.65633546E-112338829 Inexact Rounded
+xadd331 add -932499.010 873.377701E-502190452 -> -932499.010 Inexact Rounded
+xcom331 compare -932499.010 873.377701E-502190452 -> -1
+xdiv331 divide -932499.010 873.377701E-502190452 -> -1.06769272E+502190455 Inexact Rounded
+xdvi331 divideint -932499.010 873.377701E-502190452 -> NaN Division_impossible
+xmul331 multiply -932499.010 873.377701E-502190452 -> -8.14423842E-502190444 Inexact Rounded
+xpow331 power -932499.010 9 -> -5.33132815E+53 Inexact Rounded
+xrem331 remainder -932499.010 873.377701E-502190452 -> NaN Division_impossible
+xsub331 subtract -932499.010 873.377701E-502190452 -> -932499.010 Inexact Rounded
+xadd332 add -7735918.21E+799514797 -7748.78023 -> -7.73591821E+799514803 Inexact Rounded
+xcom332 compare -7735918.21E+799514797 -7748.78023 -> -1
+xdiv332 divide -7735918.21E+799514797 -7748.78023 -> 9.98340123E+799514799 Inexact Rounded
+xdvi332 divideint -7735918.21E+799514797 -7748.78023 -> NaN Division_impossible
+xmul332 multiply -7735918.21E+799514797 -7748.78023 -> 5.99439301E+799514807 Inexact Rounded
+xpow332 power -7735918.21E+799514797 -7749 -> -0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem332 remainder -7735918.21E+799514797 -7748.78023 -> NaN Division_impossible
+xsub332 subtract -7735918.21E+799514797 -7748.78023 -> -7.73591821E+799514803 Inexact Rounded
+xadd333 add -3708780.75E+445232787 980.006567E-780728623 -> -3.70878075E+445232793 Inexact Rounded
+xcom333 compare -3708780.75E+445232787 980.006567E-780728623 -> -1
+xdiv333 divide -3708780.75E+445232787 980.006567E-780728623 -> -Infinity Inexact Overflow Rounded
+xdvi333 divideint -3708780.75E+445232787 980.006567E-780728623 -> NaN Division_impossible
+xmul333 multiply -3708780.75E+445232787 980.006567E-780728623 -> -3.63462949E-335495827 Inexact Rounded
+xpow333 power -3708780.75E+445232787 10 -> Infinity Overflow Inexact Rounded
+xrem333 remainder -3708780.75E+445232787 980.006567E-780728623 -> NaN Division_impossible
+xsub333 subtract -3708780.75E+445232787 980.006567E-780728623 -> -3.70878075E+445232793 Inexact Rounded
+xadd334 add -5205124.44E-140588661 -495394029.E-620856313 -> -5.20512444E-140588655 Inexact Rounded
+xcom334 compare -5205124.44E-140588661 -495394029.E-620856313 -> -1
+xdiv334 divide -5205124.44E-140588661 -495394029.E-620856313 -> 1.05070391E+480267650 Inexact Rounded
+xdvi334 divideint -5205124.44E-140588661 -495394029.E-620856313 -> NaN Division_impossible
+xmul334 multiply -5205124.44E-140588661 -495394029.E-620856313 -> 2.57858757E-761444959 Inexact Rounded
+xpow334 power -5205124.44E-140588661 -5 -> -2.61724523E+702943271 Inexact Rounded
+xrem334 remainder -5205124.44E-140588661 -495394029.E-620856313 -> NaN Division_impossible
+xsub334 subtract -5205124.44E-140588661 -495394029.E-620856313 -> -5.20512444E-140588655 Inexact Rounded
+xadd335 add -8868.72074 5592399.93 -> 5583531.21 Inexact Rounded
+xcom335 compare -8868.72074 5592399.93 -> -1
+xdiv335 divide -8868.72074 5592399.93 -> -0.00158585238 Inexact Rounded
+xdvi335 divideint -8868.72074 5592399.93 -> -0
+xmul335 multiply -8868.72074 5592399.93 -> -4.95974332E+10 Inexact Rounded
+xpow335 power -8868.72074 5592400 -> 5.55074142E+22078017 Inexact Rounded
+xrem335 remainder -8868.72074 5592399.93 -> -8868.72074
+xsub335 subtract -8868.72074 5592399.93 -> -5601268.65 Inexact Rounded
+xadd336 add -74.7852037E-175205809 4.14316542 -> 4.14316542 Inexact Rounded
+xcom336 compare -74.7852037E-175205809 4.14316542 -> -1
+xdiv336 divide -74.7852037E-175205809 4.14316542 -> -1.80502577E-175205808 Inexact Rounded
+xdvi336 divideint -74.7852037E-175205809 4.14316542 -> -0
+xmul336 multiply -74.7852037E-175205809 4.14316542 -> -3.09847470E-175205807 Inexact Rounded
+xpow336 power -74.7852037E-175205809 4 -> 3.12797104E-700823229 Inexact Rounded
+xrem336 remainder -74.7852037E-175205809 4.14316542 -> -7.47852037E-175205808
+xsub336 subtract -74.7852037E-175205809 4.14316542 -> -4.14316542 Inexact Rounded
+xadd337 add 84196.1091E+242628748 8.07523036E-288231467 -> 8.41961091E+242628752 Inexact Rounded
+xcom337 compare 84196.1091E+242628748 8.07523036E-288231467 -> 1
+xdiv337 divide 84196.1091E+242628748 8.07523036E-288231467 -> 1.04264653E+530860219 Inexact Rounded
+xdvi337 divideint 84196.1091E+242628748 8.07523036E-288231467 -> NaN Division_impossible
+xmul337 multiply 84196.1091E+242628748 8.07523036E-288231467 -> 6.79902976E-45602714 Inexact Rounded
+xpow337 power 84196.1091E+242628748 8 -> Infinity Overflow Inexact Rounded
+xrem337 remainder 84196.1091E+242628748 8.07523036E-288231467 -> NaN Division_impossible
+xsub337 subtract 84196.1091E+242628748 8.07523036E-288231467 -> 8.41961091E+242628752 Inexact Rounded
+xadd338 add 38660103.1 -6671.73085E+900998477 -> -6.67173085E+900998480 Inexact Rounded
+xcom338 compare 38660103.1 -6671.73085E+900998477 -> 1
+xdiv338 divide 38660103.1 -6671.73085E+900998477 -> -5.79461372E-900998474 Inexact Rounded
+xdvi338 divideint 38660103.1 -6671.73085E+900998477 -> -0
+xmul338 multiply 38660103.1 -6671.73085E+900998477 -> -2.57929803E+900998488 Inexact Rounded
+xpow338 power 38660103.1 -7 -> 7.74745290E-54 Inexact Rounded
+xrem338 remainder 38660103.1 -6671.73085E+900998477 -> 38660103.1
+xsub338 subtract 38660103.1 -6671.73085E+900998477 -> 6.67173085E+900998480 Inexact Rounded
+xadd339 add -52.2659460 -296404199E+372050476 -> -2.96404199E+372050484 Inexact Rounded
+xcom339 compare -52.2659460 -296404199E+372050476 -> 1
+xdiv339 divide -52.2659460 -296404199E+372050476 -> 1.76333352E-372050483 Inexact Rounded
+xdvi339 divideint -52.2659460 -296404199E+372050476 -> 0
+xmul339 multiply -52.2659460 -296404199E+372050476 -> 1.54918459E+372050486 Inexact Rounded
+xpow339 power -52.2659460 -3 -> -0.00000700395833 Inexact Rounded
+xrem339 remainder -52.2659460 -296404199E+372050476 -> -52.2659460
+xsub339 subtract -52.2659460 -296404199E+372050476 -> 2.96404199E+372050484 Inexact Rounded
+xadd340 add 6.06625013 -276.359186 -> -270.292936 Inexact Rounded
+xcom340 compare 6.06625013 -276.359186 -> 1
+xdiv340 divide 6.06625013 -276.359186 -> -0.0219506007 Inexact Rounded
+xdvi340 divideint 6.06625013 -276.359186 -> -0
+xmul340 multiply 6.06625013 -276.359186 -> -1676.46395 Inexact Rounded
+xpow340 power 6.06625013 -276 -> 8.20339149E-217 Inexact Rounded
+xrem340 remainder 6.06625013 -276.359186 -> 6.06625013
+xsub340 subtract 6.06625013 -276.359186 -> 282.425436 Inexact Rounded
+xadd341 add -62971617.5E-241444744 46266799.3 -> 46266799.3 Inexact Rounded
+xcom341 compare -62971617.5E-241444744 46266799.3 -> -1
+xdiv341 divide -62971617.5E-241444744 46266799.3 -> -1.36105411E-241444744 Inexact Rounded
+xdvi341 divideint -62971617.5E-241444744 46266799.3 -> -0
+xmul341 multiply -62971617.5E-241444744 46266799.3 -> -2.91349519E-241444729 Inexact Rounded
+xpow341 power -62971617.5E-241444744 46266799 -> -0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem341 remainder -62971617.5E-241444744 46266799.3 -> -6.29716175E-241444737
+xsub341 subtract -62971617.5E-241444744 46266799.3 -> -46266799.3 Inexact Rounded
+xadd342 add -5.36917800 -311124593.E-976066491 -> -5.36917800 Inexact Rounded
+xcom342 compare -5.36917800 -311124593.E-976066491 -> -1
+xdiv342 divide -5.36917800 -311124593.E-976066491 -> 1.72573243E+976066483 Inexact Rounded
+xdvi342 divideint -5.36917800 -311124593.E-976066491 -> NaN Division_impossible
+xmul342 multiply -5.36917800 -311124593.E-976066491 -> 1.67048332E-976066482 Inexact Rounded
+xpow342 power -5.36917800 -3 -> -0.00646065565 Inexact Rounded
+xrem342 remainder -5.36917800 -311124593.E-976066491 -> NaN Division_impossible
+xsub342 subtract -5.36917800 -311124593.E-976066491 -> -5.36917800 Inexact Rounded
+xadd343 add 2467915.01 -92.5558322 -> 2467822.45 Inexact Rounded
+xcom343 compare 2467915.01 -92.5558322 -> 1
+xdiv343 divide 2467915.01 -92.5558322 -> -26664.0681 Inexact Rounded
+xdvi343 divideint 2467915.01 -92.5558322 -> -26664
+xmul343 multiply 2467915.01 -92.5558322 -> -228419928 Inexact Rounded
+xpow343 power 2467915.01 -93 -> 3.26055444E-595 Inexact Rounded
+xrem343 remainder 2467915.01 -92.5558322 -> 6.3002192
+xsub343 subtract 2467915.01 -92.5558322 -> 2468007.57 Inexact Rounded
+xadd344 add 187.232671 -840.469347 -> -653.236676
+xcom344 compare 187.232671 -840.469347 -> 1
+xdiv344 divide 187.232671 -840.469347 -> -0.222771564 Inexact Rounded
+xdvi344 divideint 187.232671 -840.469347 -> -0
+xmul344 multiply 187.232671 -840.469347 -> -157363.321 Inexact Rounded
+xpow344 power 187.232671 -840 -> 1.58280862E-1909 Inexact Rounded
+xrem344 remainder 187.232671 -840.469347 -> 187.232671
+xsub344 subtract 187.232671 -840.469347 -> 1027.70202 Inexact Rounded
+xadd345 add 81233.6823 -5192.21666E+309315093 -> -5.19221666E+309315096 Inexact Rounded
+xcom345 compare 81233.6823 -5192.21666E+309315093 -> 1
+xdiv345 divide 81233.6823 -5192.21666E+309315093 -> -1.56452798E-309315092 Inexact Rounded
+xdvi345 divideint 81233.6823 -5192.21666E+309315093 -> -0
+xmul345 multiply 81233.6823 -5192.21666E+309315093 -> -4.21782879E+309315101 Inexact Rounded
+xpow345 power 81233.6823 -5 -> 2.82695763E-25 Inexact Rounded
+xrem345 remainder 81233.6823 -5192.21666E+309315093 -> 81233.6823
+xsub345 subtract 81233.6823 -5192.21666E+309315093 -> 5.19221666E+309315096 Inexact Rounded
+xadd346 add -854.586113 -79.8715762E-853065103 -> -854.586113 Inexact Rounded
+xcom346 compare -854.586113 -79.8715762E-853065103 -> -1
+xdiv346 divide -854.586113 -79.8715762E-853065103 -> 1.06995023E+853065104 Inexact Rounded
+xdvi346 divideint -854.586113 -79.8715762E-853065103 -> NaN Division_impossible
+xmul346 multiply -854.586113 -79.8715762E-853065103 -> 6.82571398E-853065099 Inexact Rounded
+xpow346 power -854.586113 -8 -> 3.51522679E-24 Inexact Rounded
+xrem346 remainder -854.586113 -79.8715762E-853065103 -> NaN Division_impossible
+xsub346 subtract -854.586113 -79.8715762E-853065103 -> -854.586113 Inexact Rounded
+xadd347 add 78872665.3 172.102119 -> 78872837.4 Inexact Rounded
+xcom347 compare 78872665.3 172.102119 -> 1
+xdiv347 divide 78872665.3 172.102119 -> 458289.914 Inexact Rounded
+xdvi347 divideint 78872665.3 172.102119 -> 458289
+xmul347 multiply 78872665.3 172.102119 -> 1.35741528E+10 Inexact Rounded
+xpow347 power 78872665.3 172 -> 1.86793137E+1358 Inexact Rounded
+xrem347 remainder 78872665.3 172.102119 -> 157.285609
+xsub347 subtract 78872665.3 172.102119 -> 78872493.2 Inexact Rounded
+xadd348 add 328268.1E-436315617 -204.522245 -> -204.522245 Inexact Rounded
+xcom348 compare 328268.1E-436315617 -204.522245 -> 1
+xdiv348 divide 328268.1E-436315617 -204.522245 -> -1.60504839E-436315614 Inexact Rounded
+xdvi348 divideint 328268.1E-436315617 -204.522245 -> -0
+xmul348 multiply 328268.1E-436315617 -204.522245 -> -6.71381288E-436315610 Inexact Rounded
+xpow348 power 328268.1E-436315617 -205 -> Infinity Overflow Inexact Rounded
+xrem348 remainder 328268.1E-436315617 -204.522245 -> 3.282681E-436315612
+xsub348 subtract 328268.1E-436315617 -204.522245 -> 204.522245 Inexact Rounded
+xadd349 add -4037911.02E+641367645 29.5713010 -> -4.03791102E+641367651 Inexact Rounded
+xcom349 compare -4037911.02E+641367645 29.5713010 -> -1
+xdiv349 divide -4037911.02E+641367645 29.5713010 -> -1.36548305E+641367650 Inexact Rounded
+xdvi349 divideint -4037911.02E+641367645 29.5713010 -> NaN Division_impossible
+xmul349 multiply -4037911.02E+641367645 29.5713010 -> -1.19406282E+641367653 Inexact Rounded
+xpow349 power -4037911.02E+641367645 30 -> Infinity Overflow Inexact Rounded
+xrem349 remainder -4037911.02E+641367645 29.5713010 -> NaN Division_impossible
+xsub349 subtract -4037911.02E+641367645 29.5713010 -> -4.03791102E+641367651 Inexact Rounded
+xadd350 add -688755561.E-95301699 978.275312E+913812609 -> 9.78275312E+913812611 Inexact Rounded
+xcom350 compare -688755561.E-95301699 978.275312E+913812609 -> -1
+xdiv350 divide -688755561.E-95301699 978.275312E+913812609 -> -0E-1000000007 Inexact Rounded Underflow Subnormal
+xdvi350 divideint -688755561.E-95301699 978.275312E+913812609 -> -0
+xmul350 multiply -688755561.E-95301699 978.275312E+913812609 -> -6.73792561E+818510921 Inexact Rounded
+xpow350 power -688755561.E-95301699 10 -> 2.40243244E-953016902 Inexact Rounded
+xrem350 remainder -688755561.E-95301699 978.275312E+913812609 -> -6.88755561E-95301691
+xsub350 subtract -688755561.E-95301699 978.275312E+913812609 -> -9.78275312E+913812611 Inexact Rounded
+xadd351 add -5.47345502 59818.7580 -> 59813.2845 Inexact Rounded
+xcom351 compare -5.47345502 59818.7580 -> -1
+xdiv351 divide -5.47345502 59818.7580 -> -0.0000915006463 Inexact Rounded
+xdvi351 divideint -5.47345502 59818.7580 -> -0
+xmul351 multiply -5.47345502 59818.7580 -> -327415.281 Inexact Rounded
+xpow351 power -5.47345502 59819 -> -1.16914146E+44162 Inexact Rounded
+xrem351 remainder -5.47345502 59818.7580 -> -5.47345502
+xsub351 subtract -5.47345502 59818.7580 -> -59824.2315 Inexact Rounded
+xadd352 add 563891620E-361354567 -845900362. -> -845900362 Inexact Rounded
+xcom352 compare 563891620E-361354567 -845900362. -> 1
+xdiv352 divide 563891620E-361354567 -845900362. -> -6.66617069E-361354568 Inexact Rounded
+xdvi352 divideint 563891620E-361354567 -845900362. -> -0
+xmul352 multiply 563891620E-361354567 -845900362. -> -4.76996125E-361354550 Inexact Rounded
+xpow352 power 563891620E-361354567 -845900362 -> Infinity Overflow Inexact Rounded
+xrem352 remainder 563891620E-361354567 -845900362. -> 5.63891620E-361354559
+xsub352 subtract 563891620E-361354567 -845900362. -> 845900362 Inexact Rounded
+xadd353 add -69.7231286 85773.7504 -> 85704.0273 Inexact Rounded
+xcom353 compare -69.7231286 85773.7504 -> -1
+xdiv353 divide -69.7231286 85773.7504 -> -0.000812872566 Inexact Rounded
+xdvi353 divideint -69.7231286 85773.7504 -> -0
+xmul353 multiply -69.7231286 85773.7504 -> -5980414.23 Inexact Rounded
+xpow353 power -69.7231286 85774 -> 6.41714261E+158113 Inexact Rounded
+xrem353 remainder -69.7231286 85773.7504 -> -69.7231286
+xsub353 subtract -69.7231286 85773.7504 -> -85843.4735 Inexact Rounded
+xadd354 add 5125.51188 73814638.4E-500934741 -> 5125.51188 Inexact Rounded
+xcom354 compare 5125.51188 73814638.4E-500934741 -> 1
+xdiv354 divide 5125.51188 73814638.4E-500934741 -> 6.94376074E+500934736 Inexact Rounded
+xdvi354 divideint 5125.51188 73814638.4E-500934741 -> NaN Division_impossible
+xmul354 multiply 5125.51188 73814638.4E-500934741 -> 3.78337806E-500934730 Inexact Rounded
+xpow354 power 5125.51188 7 -> 9.29310216E+25 Inexact Rounded
+xrem354 remainder 5125.51188 73814638.4E-500934741 -> NaN Division_impossible
+xsub354 subtract 5125.51188 73814638.4E-500934741 -> 5125.51188 Inexact Rounded
+xadd355 add -54.6254096 -332921899. -> -332921954 Inexact Rounded
+xcom355 compare -54.6254096 -332921899. -> 1
+xdiv355 divide -54.6254096 -332921899. -> 1.64078752E-7 Inexact Rounded
+xdvi355 divideint -54.6254096 -332921899. -> 0
+xmul355 multiply -54.6254096 -332921899. -> 1.81859951E+10 Inexact Rounded
+xpow355 power -54.6254096 -332921899 -> -1.01482569E-578416745 Inexact Rounded
+xrem355 remainder -54.6254096 -332921899. -> -54.6254096
+xsub355 subtract -54.6254096 -332921899. -> 332921844 Inexact Rounded
+xadd356 add -9.04778095E-591874079 8719.40286 -> 8719.40286 Inexact Rounded
+xcom356 compare -9.04778095E-591874079 8719.40286 -> -1
+xdiv356 divide -9.04778095E-591874079 8719.40286 -> -1.03766062E-591874082 Inexact Rounded
+xdvi356 divideint -9.04778095E-591874079 8719.40286 -> -0
+xmul356 multiply -9.04778095E-591874079 8719.40286 -> -7.88912471E-591874075 Inexact Rounded
+xpow356 power -9.04778095E-591874079 8719 -> -0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem356 remainder -9.04778095E-591874079 8719.40286 -> -9.04778095E-591874079
+xsub356 subtract -9.04778095E-591874079 8719.40286 -> -8719.40286 Inexact Rounded
+xadd357 add -21006.1733E+884684431 -48872.9175 -> -2.10061733E+884684435 Inexact Rounded
+xcom357 compare -21006.1733E+884684431 -48872.9175 -> -1
+xdiv357 divide -21006.1733E+884684431 -48872.9175 -> 4.29812141E+884684430 Inexact Rounded
+xdvi357 divideint -21006.1733E+884684431 -48872.9175 -> NaN Division_impossible
+xmul357 multiply -21006.1733E+884684431 -48872.9175 -> 1.02663297E+884684440 Inexact Rounded
+xpow357 power -21006.1733E+884684431 -48873 -> -0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem357 remainder -21006.1733E+884684431 -48872.9175 -> NaN Division_impossible
+xsub357 subtract -21006.1733E+884684431 -48872.9175 -> -2.10061733E+884684435 Inexact Rounded
+xadd358 add -1546783 -51935370.4 -> -53482153.4
+xcom358 compare -1546783 -51935370.4 -> 1
+xdiv358 divide -1546783 -51935370.4 -> 0.0297828433 Inexact Rounded
+xdvi358 divideint -1546783 -51935370.4 -> 0
+xmul358 multiply -1546783 -51935370.4 -> 8.03327480E+13 Inexact Rounded
+xpow358 power -1546783 -51935370 -> 3.36022461E-321450306 Inexact Rounded
+xrem358 remainder -1546783 -51935370.4 -> -1546783.0
+xsub358 subtract -1546783 -51935370.4 -> 50388587.4
+xadd359 add 61302486.8 205.490417 -> 61302692.3 Inexact Rounded
+xcom359 compare 61302486.8 205.490417 -> 1
+xdiv359 divide 61302486.8 205.490417 -> 298322.850 Inexact Rounded
+xdvi359 divideint 61302486.8 205.490417 -> 298322
+xmul359 multiply 61302486.8 205.490417 -> 1.25970736E+10 Inexact Rounded
+xpow359 power 61302486.8 205 -> 2.71024755E+1596 Inexact Rounded
+xrem359 remainder 61302486.8 205.490417 -> 174.619726
+xsub359 subtract 61302486.8 205.490417 -> 61302281.3 Inexact Rounded
+xadd360 add -318180109. -54008744.6E-170931002 -> -318180109 Inexact Rounded
+xcom360 compare -318180109. -54008744.6E-170931002 -> -1
+xdiv360 divide -318180109. -54008744.6E-170931002 -> 5.89127023E+170931002 Inexact Rounded
+xdvi360 divideint -318180109. -54008744.6E-170931002 -> NaN Division_impossible
+xmul360 multiply -318180109. -54008744.6E-170931002 -> 1.71845082E-170930986 Inexact Rounded
+xpow360 power -318180109. -5 -> -3.06644280E-43 Inexact Rounded
+xrem360 remainder -318180109. -54008744.6E-170931002 -> NaN Division_impossible
+xsub360 subtract -318180109. -54008744.6E-170931002 -> -318180109 Inexact Rounded
+xadd361 add -28486137.1E+901441714 -42454.940 -> -2.84861371E+901441721 Inexact Rounded
+xcom361 compare -28486137.1E+901441714 -42454.940 -> -1
+xdiv361 divide -28486137.1E+901441714 -42454.940 -> 6.70973439E+901441716 Inexact Rounded
+xdvi361 divideint -28486137.1E+901441714 -42454.940 -> NaN Division_impossible
+xmul361 multiply -28486137.1E+901441714 -42454.940 -> 1.20937724E+901441726 Inexact Rounded
+xpow361 power -28486137.1E+901441714 -42455 -> -0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem361 remainder -28486137.1E+901441714 -42454.940 -> NaN Division_impossible
+xsub361 subtract -28486137.1E+901441714 -42454.940 -> -2.84861371E+901441721 Inexact Rounded
+xadd362 add -546398328. -27.9149712 -> -546398356 Inexact Rounded
+xcom362 compare -546398328. -27.9149712 -> -1
+xdiv362 divide -546398328. -27.9149712 -> 19573666.2 Inexact Rounded
+xdvi362 divideint -546398328. -27.9149712 -> 19573666
+xmul362 multiply -546398328. -27.9149712 -> 1.52526936E+10 Inexact Rounded
+xpow362 power -546398328. -28 -> 2.23737032E-245 Inexact Rounded
+xrem362 remainder -546398328. -27.9149712 -> -5.3315808
+xsub362 subtract -546398328. -27.9149712 -> -546398300 Inexact Rounded
+xadd363 add 5402066.1E-284978216 622.751128 -> 622.751128 Inexact Rounded
+xcom363 compare 5402066.1E-284978216 622.751128 -> -1
+xdiv363 divide 5402066.1E-284978216 622.751128 -> 8.67451837E-284978213 Inexact Rounded
+xdvi363 divideint 5402066.1E-284978216 622.751128 -> 0
+xmul363 multiply 5402066.1E-284978216 622.751128 -> 3.36414276E-284978207 Inexact Rounded
+xpow363 power 5402066.1E-284978216 623 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem363 remainder 5402066.1E-284978216 622.751128 -> 5.4020661E-284978210
+xsub363 subtract 5402066.1E-284978216 622.751128 -> -622.751128 Inexact Rounded
+xadd364 add 18845620 3129.43753 -> 18848749.4 Inexact Rounded
+xcom364 compare 18845620 3129.43753 -> 1
+xdiv364 divide 18845620 3129.43753 -> 6022.04704 Inexact Rounded
+xdvi364 divideint 18845620 3129.43753 -> 6022
+xmul364 multiply 18845620 3129.43753 -> 5.89761905E+10 Inexact Rounded
+xpow364 power 18845620 3129 -> 1.35967443E+22764 Inexact Rounded
+xrem364 remainder 18845620 3129.43753 -> 147.19434
+xsub364 subtract 18845620 3129.43753 -> 18842490.6 Inexact Rounded
+xadd365 add 50707.1412E+912475670 -198098.186E+701407524 -> 5.07071412E+912475674 Inexact Rounded
+xcom365 compare 50707.1412E+912475670 -198098.186E+701407524 -> 1
+xdiv365 divide 50707.1412E+912475670 -198098.186E+701407524 -> -2.55969740E+211068145 Inexact Rounded
+xdvi365 divideint 50707.1412E+912475670 -198098.186E+701407524 -> NaN Division_impossible
+xmul365 multiply 50707.1412E+912475670 -198098.186E+701407524 -> -Infinity Inexact Overflow Rounded
+xpow365 power 50707.1412E+912475670 -2 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem365 remainder 50707.1412E+912475670 -198098.186E+701407524 -> NaN Division_impossible
+xsub365 subtract 50707.1412E+912475670 -198098.186E+701407524 -> 5.07071412E+912475674 Inexact Rounded
+xadd366 add 55.8245006E+928885991 99170843.9E-47402167 -> 5.58245006E+928885992 Inexact Rounded
+xcom366 compare 55.8245006E+928885991 99170843.9E-47402167 -> 1
+xdiv366 divide 55.8245006E+928885991 99170843.9E-47402167 -> 5.62912429E+976288151 Inexact Rounded
+xdvi366 divideint 55.8245006E+928885991 99170843.9E-47402167 -> NaN Division_impossible
+xmul366 multiply 55.8245006E+928885991 99170843.9E-47402167 -> 5.53616283E+881483833 Inexact Rounded
+xpow366 power 55.8245006E+928885991 10 -> Infinity Overflow Inexact Rounded
+xrem366 remainder 55.8245006E+928885991 99170843.9E-47402167 -> NaN Division_impossible
+xsub366 subtract 55.8245006E+928885991 99170843.9E-47402167 -> 5.58245006E+928885992 Inexact Rounded
+xadd367 add 13.8003883E-386224921 -84126481.9E-296378341 -> -8.41264819E-296378334 Inexact Rounded
+xcom367 compare 13.8003883E-386224921 -84126481.9E-296378341 -> 1
+xdiv367 divide 13.8003883E-386224921 -84126481.9E-296378341 -> -1.64043331E-89846587 Inexact Rounded
+xdvi367 divideint 13.8003883E-386224921 -84126481.9E-296378341 -> -0
+xmul367 multiply 13.8003883E-386224921 -84126481.9E-296378341 -> -1.16097812E-682603253 Inexact Rounded
+xpow367 power 13.8003883E-386224921 -8 -> Infinity Overflow Inexact Rounded
+xrem367 remainder 13.8003883E-386224921 -84126481.9E-296378341 -> 1.38003883E-386224920
+xsub367 subtract 13.8003883E-386224921 -84126481.9E-296378341 -> 8.41264819E-296378334 Inexact Rounded
+xadd368 add 9820.90457 46671.5915 -> 56492.4961 Inexact Rounded
+xcom368 compare 9820.90457 46671.5915 -> -1
+xdiv368 divide 9820.90457 46671.5915 -> 0.210425748 Inexact Rounded
+xdvi368 divideint 9820.90457 46671.5915 -> 0
+xmul368 multiply 9820.90457 46671.5915 -> 458357246 Inexact Rounded
+xpow368 power 9820.90457 46672 -> 4.94753070E+186321 Inexact Rounded
+xrem368 remainder 9820.90457 46671.5915 -> 9820.90457
+xsub368 subtract 9820.90457 46671.5915 -> -36850.6869 Inexact Rounded
+xadd369 add 7.22436006E+831949153 -11168830E+322331045 -> 7.22436006E+831949153 Inexact Rounded
+xcom369 compare 7.22436006E+831949153 -11168830E+322331045 -> 1
+xdiv369 divide 7.22436006E+831949153 -11168830E+322331045 -> -6.46832306E+509618101 Inexact Rounded
+xdvi369 divideint 7.22436006E+831949153 -11168830E+322331045 -> NaN Division_impossible
+xmul369 multiply 7.22436006E+831949153 -11168830E+322331045 -> -Infinity Inexact Overflow Rounded
+xpow369 power 7.22436006E+831949153 -1 -> 1.38420565E-831949154 Inexact Rounded
+xrem369 remainder 7.22436006E+831949153 -11168830E+322331045 -> NaN Division_impossible
+xsub369 subtract 7.22436006E+831949153 -11168830E+322331045 -> 7.22436006E+831949153 Inexact Rounded
+xadd370 add 472648900 -207.784153 -> 472648692 Inexact Rounded
+xcom370 compare 472648900 -207.784153 -> 1
+xdiv370 divide 472648900 -207.784153 -> -2274711.01 Inexact Rounded
+xdvi370 divideint 472648900 -207.784153 -> -2274711
+xmul370 multiply 472648900 -207.784153 -> -9.82089514E+10 Inexact Rounded
+xpow370 power 472648900 -208 -> 4.96547145E-1805 Inexact Rounded
+xrem370 remainder 472648900 -207.784153 -> 1.545217
+xsub370 subtract 472648900 -207.784153 -> 472649108 Inexact Rounded
+xadd371 add -8754.49306 -818.165153E+631475457 -> -8.18165153E+631475459 Inexact Rounded
+xcom371 compare -8754.49306 -818.165153E+631475457 -> 1
+xdiv371 divide -8754.49306 -818.165153E+631475457 -> 1.07001539E-631475456 Inexact Rounded
+xdvi371 divideint -8754.49306 -818.165153E+631475457 -> 0
+xmul371 multiply -8754.49306 -818.165153E+631475457 -> 7.16262115E+631475463 Inexact Rounded
+xpow371 power -8754.49306 -8 -> 2.89835767E-32 Inexact Rounded
+xrem371 remainder -8754.49306 -818.165153E+631475457 -> -8754.49306
+xsub371 subtract -8754.49306 -818.165153E+631475457 -> 8.18165153E+631475459 Inexact Rounded
+xadd372 add 98750864 191380.551 -> 98942244.6 Inexact Rounded
+xcom372 compare 98750864 191380.551 -> 1
+xdiv372 divide 98750864 191380.551 -> 515.992161 Inexact Rounded
+xdvi372 divideint 98750864 191380.551 -> 515
+xmul372 multiply 98750864 191380.551 -> 1.88989948E+13 Inexact Rounded
+xpow372 power 98750864 191381 -> 1.70908809E+1530003 Inexact Rounded
+xrem372 remainder 98750864 191380.551 -> 189880.235
+xsub372 subtract 98750864 191380.551 -> 98559483.4 Inexact Rounded
+xadd373 add 725292561. -768963606.E+340762986 -> -7.68963606E+340762994 Inexact Rounded
+xcom373 compare 725292561. -768963606.E+340762986 -> 1
+xdiv373 divide 725292561. -768963606.E+340762986 -> -9.43207917E-340762987 Inexact Rounded
+xdvi373 divideint 725292561. -768963606.E+340762986 -> -0
+xmul373 multiply 725292561. -768963606.E+340762986 -> -5.57723583E+340763003 Inexact Rounded
+xpow373 power 725292561. -8 -> 1.30585277E-71 Inexact Rounded
+xrem373 remainder 725292561. -768963606.E+340762986 -> 725292561
+xsub373 subtract 725292561. -768963606.E+340762986 -> 7.68963606E+340762994 Inexact Rounded
+xadd374 add 1862.80445 648254483. -> 648256346 Inexact Rounded
+xcom374 compare 1862.80445 648254483. -> -1
+xdiv374 divide 1862.80445 648254483. -> 0.00000287356972 Inexact Rounded
+xdvi374 divideint 1862.80445 648254483. -> 0
+xmul374 multiply 1862.80445 648254483. -> 1.20757134E+12 Inexact Rounded
+xpow374 power 1862.80445 648254483 -> Infinity Overflow Inexact Rounded
+xrem374 remainder 1862.80445 648254483. -> 1862.80445
+xsub374 subtract 1862.80445 648254483. -> -648252620 Inexact Rounded
+xadd375 add -5549320.1 -93580684.1 -> -99130004.2
+xcom375 compare -5549320.1 -93580684.1 -> 1
+xdiv375 divide -5549320.1 -93580684.1 -> 0.0592998454 Inexact Rounded
+xdvi375 divideint -5549320.1 -93580684.1 -> 0
+xmul375 multiply -5549320.1 -93580684.1 -> 5.19309171E+14 Inexact Rounded
+xpow375 power -5549320.1 -93580684 -> 4.20662080E-631130572 Inexact Rounded
+xrem375 remainder -5549320.1 -93580684.1 -> -5549320.1
+xsub375 subtract -5549320.1 -93580684.1 -> 88031364.0
+xadd376 add -14677053.1 -25784.7358 -> -14702837.8 Inexact Rounded
+xcom376 compare -14677053.1 -25784.7358 -> -1
+xdiv376 divide -14677053.1 -25784.7358 -> 569.214795 Inexact Rounded
+xdvi376 divideint -14677053.1 -25784.7358 -> 569
+xmul376 multiply -14677053.1 -25784.7358 -> 3.78443937E+11 Inexact Rounded
+xpow376 power -14677053.1 -25785 -> -1.64760831E-184792 Inexact Rounded
+xrem376 remainder -14677053.1 -25784.7358 -> -5538.4298
+xsub376 subtract -14677053.1 -25784.7358 -> -14651268.4 Inexact Rounded
+xadd377 add 547402.308E+571687617 -7835797.01E+500067364 -> 5.47402308E+571687622 Inexact Rounded
+xcom377 compare 547402.308E+571687617 -7835797.01E+500067364 -> 1
+xdiv377 divide 547402.308E+571687617 -7835797.01E+500067364 -> -6.98591742E+71620251 Inexact Rounded
+xdvi377 divideint 547402.308E+571687617 -7835797.01E+500067364 -> NaN Division_impossible
+xmul377 multiply 547402.308E+571687617 -7835797.01E+500067364 -> -Infinity Inexact Overflow Rounded
+xpow377 power 547402.308E+571687617 -8 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem377 remainder 547402.308E+571687617 -7835797.01E+500067364 -> NaN Division_impossible
+xsub377 subtract 547402.308E+571687617 -7835797.01E+500067364 -> 5.47402308E+571687622 Inexact Rounded
+xadd378 add -4131738.09 7579.07566 -> -4124159.01 Inexact Rounded
+xcom378 compare -4131738.09 7579.07566 -> -1
+xdiv378 divide -4131738.09 7579.07566 -> -545.150659 Inexact Rounded
+xdvi378 divideint -4131738.09 7579.07566 -> -545
+xmul378 multiply -4131738.09 7579.07566 -> -3.13147556E+10 Inexact Rounded
+xpow378 power -4131738.09 7579 -> -4.68132794E+50143 Inexact Rounded
+xrem378 remainder -4131738.09 7579.07566 -> -1141.85530
+xsub378 subtract -4131738.09 7579.07566 -> -4139317.17 Inexact Rounded
+xadd379 add 504544.648 -7678.96133E-662143268 -> 504544.648 Inexact Rounded
+xcom379 compare 504544.648 -7678.96133E-662143268 -> 1
+xdiv379 divide 504544.648 -7678.96133E-662143268 -> -6.57048039E+662143269 Inexact Rounded
+xdvi379 divideint 504544.648 -7678.96133E-662143268 -> NaN Division_impossible
+xmul379 multiply 504544.648 -7678.96133E-662143268 -> -3.87437884E-662143259 Inexact Rounded
+xpow379 power 504544.648 -8 -> 2.38124001E-46 Inexact Rounded
+xrem379 remainder 504544.648 -7678.96133E-662143268 -> NaN Division_impossible
+xsub379 subtract 504544.648 -7678.96133E-662143268 -> 504544.648 Inexact Rounded
+xadd380 add 829898241 8912.99114E+929228149 -> 8.91299114E+929228152 Inexact Rounded
+xcom380 compare 829898241 8912.99114E+929228149 -> -1
+xdiv380 divide 829898241 8912.99114E+929228149 -> 9.31110811E-929228145 Inexact Rounded
+xdvi380 divideint 829898241 8912.99114E+929228149 -> 0
+xmul380 multiply 829898241 8912.99114E+929228149 -> 7.39687567E+929228161 Inexact Rounded
+xpow380 power 829898241 9 -> 1.86734084E+80 Inexact Rounded
+xrem380 remainder 829898241 8912.99114E+929228149 -> 829898241
+xsub380 subtract 829898241 8912.99114E+929228149 -> -8.91299114E+929228152 Inexact Rounded
+xadd381 add 53.6891691 -11.2371140 -> 42.4520551
+xcom381 compare 53.6891691 -11.2371140 -> 1
+xdiv381 divide 53.6891691 -11.2371140 -> -4.77784323 Inexact Rounded
+xdvi381 divideint 53.6891691 -11.2371140 -> -4
+xmul381 multiply 53.6891691 -11.2371140 -> -603.311314 Inexact Rounded
+xpow381 power 53.6891691 -11 -> 9.35936725E-20 Inexact Rounded
+xrem381 remainder 53.6891691 -11.2371140 -> 8.7407131
+xsub381 subtract 53.6891691 -11.2371140 -> 64.9262831
+xadd382 add -93951823.4 -25317.8645 -> -93977141.3 Inexact Rounded
+xcom382 compare -93951823.4 -25317.8645 -> -1
+xdiv382 divide -93951823.4 -25317.8645 -> 3710.89052 Inexact Rounded
+xdvi382 divideint -93951823.4 -25317.8645 -> 3710
+xmul382 multiply -93951823.4 -25317.8645 -> 2.37865953E+12 Inexact Rounded
+xpow382 power -93951823.4 -25318 -> 9.67857714E-201859 Inexact Rounded
+xrem382 remainder -93951823.4 -25317.8645 -> -22546.1050
+xsub382 subtract -93951823.4 -25317.8645 -> -93926505.5 Inexact Rounded
+xadd383 add 446919.123 951338490. -> 951785409 Inexact Rounded
+xcom383 compare 446919.123 951338490. -> -1
+xdiv383 divide 446919.123 951338490. -> 0.000469779293 Inexact Rounded
+xdvi383 divideint 446919.123 951338490. -> 0
+xmul383 multiply 446919.123 951338490. -> 4.25171364E+14 Inexact Rounded
+xpow383 power 446919.123 951338490 -> Infinity Overflow Inexact Rounded
+xrem383 remainder 446919.123 951338490. -> 446919.123
+xsub383 subtract 446919.123 951338490. -> -950891571 Inexact Rounded
+xadd384 add -8.01787748 -88.3076852 -> -96.3255627 Inexact Rounded
+xcom384 compare -8.01787748 -88.3076852 -> 1
+xdiv384 divide -8.01787748 -88.3076852 -> 0.0907947871 Inexact Rounded
+xdvi384 divideint -8.01787748 -88.3076852 -> 0
+xmul384 multiply -8.01787748 -88.3076852 -> 708.040200 Inexact Rounded
+xpow384 power -8.01787748 -88 -> 2.77186088E-80 Inexact Rounded
+xrem384 remainder -8.01787748 -88.3076852 -> -8.01787748
+xsub384 subtract -8.01787748 -88.3076852 -> 80.2898077 Inexact Rounded
+xadd385 add 517458139 -999731.548 -> 516458407 Inexact Rounded
+xcom385 compare 517458139 -999731.548 -> 1
+xdiv385 divide 517458139 -999731.548 -> -517.597089 Inexact Rounded
+xdvi385 divideint 517458139 -999731.548 -> -517
+xmul385 multiply 517458139 -999731.548 -> -5.17319226E+14 Inexact Rounded
+xpow385 power 517458139 -999732 -> 1.24821346E-8711540 Inexact Rounded
+xrem385 remainder 517458139 -999731.548 -> 596928.684
+xsub385 subtract 517458139 -999731.548 -> 518457871 Inexact Rounded
+xadd386 add -405543440 -4013.18295 -> -405547453 Inexact Rounded
+xcom386 compare -405543440 -4013.18295 -> -1
+xdiv386 divide -405543440 -4013.18295 -> 101052.816 Inexact Rounded
+xdvi386 divideint -405543440 -4013.18295 -> 101052
+xmul386 multiply -405543440 -4013.18295 -> 1.62752002E+12 Inexact Rounded
+xpow386 power -405543440 -4013 -> -8.83061932E-34545 Inexact Rounded
+xrem386 remainder -405543440 -4013.18295 -> -3276.53660
+xsub386 subtract -405543440 -4013.18295 -> -405539427 Inexact Rounded
+xadd387 add -49245250.1E+682760825 -848776.637 -> -4.92452501E+682760832 Inexact Rounded
+xcom387 compare -49245250.1E+682760825 -848776.637 -> -1
+xdiv387 divide -49245250.1E+682760825 -848776.637 -> 5.80190924E+682760826 Inexact Rounded
+xdvi387 divideint -49245250.1E+682760825 -848776.637 -> NaN Division_impossible
+xmul387 multiply -49245250.1E+682760825 -848776.637 -> 4.17982178E+682760838 Inexact Rounded
+xpow387 power -49245250.1E+682760825 -848777 -> -0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem387 remainder -49245250.1E+682760825 -848776.637 -> NaN Division_impossible
+xsub387 subtract -49245250.1E+682760825 -848776.637 -> -4.92452501E+682760832 Inexact Rounded
+xadd388 add -151144455 -170371.29 -> -151314826 Inexact Rounded
+xcom388 compare -151144455 -170371.29 -> -1
+xdiv388 divide -151144455 -170371.29 -> 887.147447 Inexact Rounded
+xdvi388 divideint -151144455 -170371.29 -> 887
+xmul388 multiply -151144455 -170371.29 -> 2.57506758E+13 Inexact Rounded
+xpow388 power -151144455 -170371 -> -5.86496369E-1393532 Inexact Rounded
+xrem388 remainder -151144455 -170371.29 -> -25120.77
+xsub388 subtract -151144455 -170371.29 -> -150974084 Inexact Rounded
+xadd389 add -729236746.E+662737067 9.10823602 -> -7.29236746E+662737075 Inexact Rounded
+xcom389 compare -729236746.E+662737067 9.10823602 -> -1
+xdiv389 divide -729236746.E+662737067 9.10823602 -> -8.00634442E+662737074 Inexact Rounded
+xdvi389 divideint -729236746.E+662737067 9.10823602 -> NaN Division_impossible
+xmul389 multiply -729236746.E+662737067 9.10823602 -> -6.64206040E+662737076 Inexact Rounded
+xpow389 power -729236746.E+662737067 9 -> -Infinity Overflow Inexact Rounded
+xrem389 remainder -729236746.E+662737067 9.10823602 -> NaN Division_impossible
+xsub389 subtract -729236746.E+662737067 9.10823602 -> -7.29236746E+662737075 Inexact Rounded
+xadd390 add 534.394729 -2369839.37 -> -2369304.98 Inexact Rounded
+xcom390 compare 534.394729 -2369839.37 -> 1
+xdiv390 divide 534.394729 -2369839.37 -> -0.000225498291 Inexact Rounded
+xdvi390 divideint 534.394729 -2369839.37 -> -0
+xmul390 multiply 534.394729 -2369839.37 -> -1.26642967E+9 Inexact Rounded
+xpow390 power 534.394729 -2369839 -> 7.12522896E-6464595 Inexact Rounded
+xrem390 remainder 534.394729 -2369839.37 -> 534.394729
+xsub390 subtract 534.394729 -2369839.37 -> 2370373.76 Inexact Rounded
+xadd391 add 89100.1797 224.370309 -> 89324.5500 Inexact Rounded
+xcom391 compare 89100.1797 224.370309 -> 1
+xdiv391 divide 89100.1797 224.370309 -> 397.112167 Inexact Rounded
+xdvi391 divideint 89100.1797 224.370309 -> 397
+xmul391 multiply 89100.1797 224.370309 -> 19991434.9 Inexact Rounded
+xpow391 power 89100.1797 224 -> 5.92654936E+1108 Inexact Rounded
+xrem391 remainder 89100.1797 224.370309 -> 25.167027
+xsub391 subtract 89100.1797 224.370309 -> 88875.8094 Inexact Rounded
+xadd392 add -821377.777 38.552821 -> -821339.224 Inexact Rounded
+xcom392 compare -821377.777 38.552821 -> -1
+xdiv392 divide -821377.777 38.552821 -> -21305.2575 Inexact Rounded
+xdvi392 divideint -821377.777 38.552821 -> -21305
+xmul392 multiply -821377.777 38.552821 -> -31666430.4 Inexact Rounded
+xpow392 power -821377.777 39 -> -4.64702482E+230 Inexact Rounded
+xrem392 remainder -821377.777 38.552821 -> -9.925595
+xsub392 subtract -821377.777 38.552821 -> -821416.330 Inexact Rounded
+xadd393 add -392640.782 -2571619.5E+113237865 -> -2.57161950E+113237871 Inexact Rounded
+xcom393 compare -392640.782 -2571619.5E+113237865 -> 1
+xdiv393 divide -392640.782 -2571619.5E+113237865 -> 1.52682301E-113237866 Inexact Rounded
+xdvi393 divideint -392640.782 -2571619.5E+113237865 -> 0
+xmul393 multiply -392640.782 -2571619.5E+113237865 -> 1.00972269E+113237877 Inexact Rounded
+xpow393 power -392640.782 -3 -> -1.65201422E-17 Inexact Rounded
+xrem393 remainder -392640.782 -2571619.5E+113237865 -> -392640.782
+xsub393 subtract -392640.782 -2571619.5E+113237865 -> 2.57161950E+113237871 Inexact Rounded
+xadd394 add -651397.712 -723.59673 -> -652121.309 Inexact Rounded
+xcom394 compare -651397.712 -723.59673 -> -1
+xdiv394 divide -651397.712 -723.59673 -> 900.222023 Inexact Rounded
+xdvi394 divideint -651397.712 -723.59673 -> 900
+xmul394 multiply -651397.712 -723.59673 -> 471349254 Inexact Rounded
+xpow394 power -651397.712 -724 -> 5.96115415E-4210 Inexact Rounded
+xrem394 remainder -651397.712 -723.59673 -> -160.65500
+xsub394 subtract -651397.712 -723.59673 -> -650674.115 Inexact Rounded
+xadd395 add 86.6890892 940380864 -> 940380951 Inexact Rounded
+xcom395 compare 86.6890892 940380864 -> -1
+xdiv395 divide 86.6890892 940380864 -> 9.21850843E-8 Inexact Rounded
+xdvi395 divideint 86.6890892 940380864 -> 0
+xmul395 multiply 86.6890892 940380864 -> 8.15207606E+10 Inexact Rounded
+xpow395 power 86.6890892 940380864 -> Infinity Overflow Inexact Rounded
+xrem395 remainder 86.6890892 940380864 -> 86.6890892
+xsub395 subtract 86.6890892 940380864 -> -940380777 Inexact Rounded
+xadd396 add 4880.06442E-382222621 -115627239E-912834031 -> 4.88006442E-382222618 Inexact Rounded
+xcom396 compare 4880.06442E-382222621 -115627239E-912834031 -> 1
+xdiv396 divide 4880.06442E-382222621 -115627239E-912834031 -> -4.22051453E+530611405 Inexact Rounded
+xdvi396 divideint 4880.06442E-382222621 -115627239E-912834031 -> NaN Division_impossible
+xmul396 multiply 4880.06442E-382222621 -115627239E-912834031 -> -0E-1000000007 Underflow Subnormal Inexact Rounded
+xpow396 power 4880.06442E-382222621 -1 -> 2.04915328E+382222617 Inexact Rounded
+xrem396 remainder 4880.06442E-382222621 -115627239E-912834031 -> NaN Division_impossible
+xsub396 subtract 4880.06442E-382222621 -115627239E-912834031 -> 4.88006442E-382222618 Inexact Rounded
+xadd397 add 173398265E-532383158 3462.51450E+80986915 -> 3.46251450E+80986918 Inexact Rounded
+xcom397 compare 173398265E-532383158 3462.51450E+80986915 -> -1
+xdiv397 divide 173398265E-532383158 3462.51450E+80986915 -> 5.00787116E-613370069 Inexact Rounded
+xdvi397 divideint 173398265E-532383158 3462.51450E+80986915 -> 0
+xmul397 multiply 173398265E-532383158 3462.51450E+80986915 -> 6.00394007E-451396232 Inexact Rounded
+xpow397 power 173398265E-532383158 3 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem397 remainder 173398265E-532383158 3462.51450E+80986915 -> 1.73398265E-532383150
+xsub397 subtract 173398265E-532383158 3462.51450E+80986915 -> -3.46251450E+80986918 Inexact Rounded
+xadd398 add -1522176.78 -6631061.77 -> -8153238.55
+xcom398 compare -1522176.78 -6631061.77 -> 1
+xdiv398 divide -1522176.78 -6631061.77 -> 0.229552496 Inexact Rounded
+xdvi398 divideint -1522176.78 -6631061.77 -> 0
+xmul398 multiply -1522176.78 -6631061.77 -> 1.00936483E+13 Inexact Rounded
+xpow398 power -1522176.78 -6631062 -> 4.54268854E-40996310 Inexact Rounded
+xrem398 remainder -1522176.78 -6631061.77 -> -1522176.78
+xsub398 subtract -1522176.78 -6631061.77 -> 5108884.99
+xadd399 add 538.10453 522934310 -> 522934848 Inexact Rounded
+xcom399 compare 538.10453 522934310 -> -1
+xdiv399 divide 538.10453 522934310 -> 0.00000102900980 Inexact Rounded
+xdvi399 divideint 538.10453 522934310 -> 0
+xmul399 multiply 538.10453 522934310 -> 2.81393321E+11 Inexact Rounded
+xpow399 power 538.10453 522934310 -> Infinity Overflow Inexact Rounded
+xrem399 remainder 538.10453 522934310 -> 538.10453
+xsub399 subtract 538.10453 522934310 -> -522933772 Inexact Rounded
+xadd400 add 880243.444E-750940977 -354.601578E-204943740 -> -3.54601578E-204943738 Inexact Rounded
+xcom400 compare 880243.444E-750940977 -354.601578E-204943740 -> 1
+xdiv400 divide 880243.444E-750940977 -354.601578E-204943740 -> -2.48234497E-545997234 Inexact Rounded
+xdvi400 divideint 880243.444E-750940977 -354.601578E-204943740 -> -0
+xmul400 multiply 880243.444E-750940977 -354.601578E-204943740 -> -3.12135714E-955884709 Inexact Rounded
+xpow400 power 880243.444E-750940977 -4 -> Infinity Overflow Inexact Rounded
+xrem400 remainder 880243.444E-750940977 -354.601578E-204943740 -> 8.80243444E-750940972
+xsub400 subtract 880243.444E-750940977 -354.601578E-204943740 -> 3.54601578E-204943738 Inexact Rounded
+xadd401 add 968370.780 6677268.73 -> 7645639.51 Rounded
+xcom401 compare 968370.780 6677268.73 -> -1
+xdiv401 divide 968370.780 6677268.73 -> 0.145024982 Inexact Rounded
+xdvi401 divideint 968370.780 6677268.73 -> 0
+xmul401 multiply 968370.780 6677268.73 -> 6.46607193E+12 Inexact Rounded
+xpow401 power 968370.780 6677269 -> 3.29990931E+39970410 Inexact Rounded
+xrem401 remainder 968370.780 6677268.73 -> 968370.780
+xsub401 subtract 968370.780 6677268.73 -> -5708897.95 Rounded
+xadd402 add -97.7474945 31248241.5 -> 31248143.8 Inexact Rounded
+xcom402 compare -97.7474945 31248241.5 -> -1
+xdiv402 divide -97.7474945 31248241.5 -> -0.00000312809585 Inexact Rounded
+xdvi402 divideint -97.7474945 31248241.5 -> -0
+xmul402 multiply -97.7474945 31248241.5 -> -3.05443731E+9 Inexact Rounded
+xpow402 power -97.7474945 31248242 -> 2.90714257E+62187302 Inexact Rounded
+xrem402 remainder -97.7474945 31248241.5 -> -97.7474945
+xsub402 subtract -97.7474945 31248241.5 -> -31248339.2 Inexact Rounded
+xadd403 add -187582786.E+369916952 957840435E+744365567 -> 9.57840435E+744365575 Inexact Rounded
+xcom403 compare -187582786.E+369916952 957840435E+744365567 -> -1
+xdiv403 divide -187582786.E+369916952 957840435E+744365567 -> -1.95839285E-374448616 Inexact Rounded
+xdvi403 divideint -187582786.E+369916952 957840435E+744365567 -> -0
+xmul403 multiply -187582786.E+369916952 957840435E+744365567 -> -Infinity Inexact Overflow Rounded
+xpow403 power -187582786.E+369916952 10 -> Infinity Overflow Inexact Rounded
+xrem403 remainder -187582786.E+369916952 957840435E+744365567 -> -1.87582786E+369916960
+xsub403 subtract -187582786.E+369916952 957840435E+744365567 -> -9.57840435E+744365575 Inexact Rounded
+xadd404 add -328026144. -125499735. -> -453525879
+xcom404 compare -328026144. -125499735. -> -1
+xdiv404 divide -328026144. -125499735. -> 2.61375965 Inexact Rounded
+xdvi404 divideint -328026144. -125499735. -> 2
+xmul404 multiply -328026144. -125499735. -> 4.11671941E+16 Inexact Rounded
+xpow404 power -328026144. -125499735 -> -0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem404 remainder -328026144. -125499735. -> -77026674
+xsub404 subtract -328026144. -125499735. -> -202526409
+xadd405 add -99424150.2E-523662102 3712.35030 -> 3712.35030 Inexact Rounded
+xcom405 compare -99424150.2E-523662102 3712.35030 -> -1
+xdiv405 divide -99424150.2E-523662102 3712.35030 -> -2.67819958E-523662098 Inexact Rounded
+xdvi405 divideint -99424150.2E-523662102 3712.35030 -> -0
+xmul405 multiply -99424150.2E-523662102 3712.35030 -> -3.69097274E-523662091 Inexact Rounded
+xpow405 power -99424150.2E-523662102 3712 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem405 remainder -99424150.2E-523662102 3712.35030 -> -9.94241502E-523662095
+xsub405 subtract -99424150.2E-523662102 3712.35030 -> -3712.35030 Inexact Rounded
+xadd406 add 14838.0718 9489893.28E+830631266 -> 9.48989328E+830631272 Inexact Rounded
+xcom406 compare 14838.0718 9489893.28E+830631266 -> -1
+xdiv406 divide 14838.0718 9489893.28E+830631266 -> 1.56356572E-830631269 Inexact Rounded
+xdvi406 divideint 14838.0718 9489893.28E+830631266 -> 0
+xmul406 multiply 14838.0718 9489893.28E+830631266 -> 1.40811718E+830631277 Inexact Rounded
+xpow406 power 14838.0718 9 -> 3.48656057E+37 Inexact Rounded
+xrem406 remainder 14838.0718 9489893.28E+830631266 -> 14838.0718
+xsub406 subtract 14838.0718 9489893.28E+830631266 -> -9.48989328E+830631272 Inexact Rounded
+xadd407 add 71207472.8 -31835.0809 -> 71175637.7 Inexact Rounded
+xcom407 compare 71207472.8 -31835.0809 -> 1
+xdiv407 divide 71207472.8 -31835.0809 -> -2236.76117 Inexact Rounded
+xdvi407 divideint 71207472.8 -31835.0809 -> -2236
+xmul407 multiply 71207472.8 -31835.0809 -> -2.26689566E+12 Inexact Rounded
+xpow407 power 71207472.8 -31835 -> 7.05333953E-249986 Inexact Rounded
+xrem407 remainder 71207472.8 -31835.0809 -> 24231.9076
+xsub407 subtract 71207472.8 -31835.0809 -> 71239307.9 Inexact Rounded
+xadd408 add -20440.4394 -44.4064328E+511085806 -> -4.44064328E+511085807 Inexact Rounded
+xcom408 compare -20440.4394 -44.4064328E+511085806 -> 1
+xdiv408 divide -20440.4394 -44.4064328E+511085806 -> 4.60303567E-511085804 Inexact Rounded
+xdvi408 divideint -20440.4394 -44.4064328E+511085806 -> 0
+xmul408 multiply -20440.4394 -44.4064328E+511085806 -> 9.07686999E+511085811 Inexact Rounded
+xpow408 power -20440.4394 -4 -> 5.72847590E-18 Inexact Rounded
+xrem408 remainder -20440.4394 -44.4064328E+511085806 -> -20440.4394
+xsub408 subtract -20440.4394 -44.4064328E+511085806 -> 4.44064328E+511085807 Inexact Rounded
+xadd409 add -54.3684171E-807210192 1.04592973E-984041807 -> -5.43684171E-807210191 Inexact Rounded
+xcom409 compare -54.3684171E-807210192 1.04592973E-984041807 -> -1
+xdiv409 divide -54.3684171E-807210192 1.04592973E-984041807 -> -5.19809463E+176831616 Inexact Rounded
+xdvi409 divideint -54.3684171E-807210192 1.04592973E-984041807 -> NaN Division_impossible
+xmul409 multiply -54.3684171E-807210192 1.04592973E-984041807 -> -0E-1000000007 Underflow Subnormal Inexact Rounded
+xpow409 power -54.3684171E-807210192 1 -> -5.43684171E-807210191
+xrem409 remainder -54.3684171E-807210192 1.04592973E-984041807 -> NaN Division_impossible
+xsub409 subtract -54.3684171E-807210192 1.04592973E-984041807 -> -5.43684171E-807210191 Inexact Rounded
+xadd410 add 54310060.5E+948159739 274320701.E+205880484 -> 5.43100605E+948159746 Inexact Rounded
+xcom410 compare 54310060.5E+948159739 274320701.E+205880484 -> 1
+xdiv410 divide 54310060.5E+948159739 274320701.E+205880484 -> 1.97980175E+742279254 Inexact Rounded
+xdvi410 divideint 54310060.5E+948159739 274320701.E+205880484 -> NaN Division_impossible
+xmul410 multiply 54310060.5E+948159739 274320701.E+205880484 -> Infinity Inexact Overflow Rounded
+xpow410 power 54310060.5E+948159739 3 -> Infinity Overflow Inexact Rounded
+xrem410 remainder 54310060.5E+948159739 274320701.E+205880484 -> NaN Division_impossible
+xsub410 subtract 54310060.5E+948159739 274320701.E+205880484 -> 5.43100605E+948159746 Inexact Rounded
+xadd411 add -657.186702 426844.39 -> 426187.203 Inexact Rounded
+xcom411 compare -657.186702 426844.39 -> -1
+xdiv411 divide -657.186702 426844.39 -> -0.00153964001 Inexact Rounded
+xdvi411 divideint -657.186702 426844.39 -> -0
+xmul411 multiply -657.186702 426844.39 -> -280516457 Inexact Rounded
+xpow411 power -657.186702 426844 -> 3.50000575E+1202713 Inexact Rounded
+xrem411 remainder -657.186702 426844.39 -> -657.186702
+xsub411 subtract -657.186702 426844.39 -> -427501.577 Inexact Rounded
+xadd412 add -41593077.0 -688607.564 -> -42281684.6 Inexact Rounded
+xcom412 compare -41593077.0 -688607.564 -> -1
+xdiv412 divide -41593077.0 -688607.564 -> 60.4017138 Inexact Rounded
+xdvi412 divideint -41593077.0 -688607.564 -> 60
+xmul412 multiply -41593077.0 -688607.564 -> 2.86413074E+13 Inexact Rounded
+xpow412 power -41593077.0 -688608 -> 1.42150750E-5246519 Inexact Rounded
+xrem412 remainder -41593077.0 -688607.564 -> -276623.160
+xsub412 subtract -41593077.0 -688607.564 -> -40904469.4 Inexact Rounded
+xadd413 add -5786.38132 190556652.E+177045877 -> 1.90556652E+177045885 Inexact Rounded
+xcom413 compare -5786.38132 190556652.E+177045877 -> -1
+xdiv413 divide -5786.38132 190556652.E+177045877 -> -3.03656748E-177045882 Inexact Rounded
+xdvi413 divideint -5786.38132 190556652.E+177045877 -> -0
+xmul413 multiply -5786.38132 190556652.E+177045877 -> -1.10263345E+177045889 Inexact Rounded
+xpow413 power -5786.38132 2 -> 33482208.8 Inexact Rounded
+xrem413 remainder -5786.38132 190556652.E+177045877 -> -5786.38132
+xsub413 subtract -5786.38132 190556652.E+177045877 -> -1.90556652E+177045885 Inexact Rounded
+xadd414 add 737622.974 -241560693E+249506565 -> -2.41560693E+249506573 Inexact Rounded
+xcom414 compare 737622.974 -241560693E+249506565 -> 1
+xdiv414 divide 737622.974 -241560693E+249506565 -> -3.05357202E-249506568 Inexact Rounded
+xdvi414 divideint 737622.974 -241560693E+249506565 -> -0
+xmul414 multiply 737622.974 -241560693E+249506565 -> -1.78180717E+249506579 Inexact Rounded
+xpow414 power 737622.974 -2 -> 1.83793916E-12 Inexact Rounded
+xrem414 remainder 737622.974 -241560693E+249506565 -> 737622.974
+xsub414 subtract 737622.974 -241560693E+249506565 -> 2.41560693E+249506573 Inexact Rounded
+xadd415 add 5615373.52 -7.27583808E-949781048 -> 5615373.52 Inexact Rounded
+xcom415 compare 5615373.52 -7.27583808E-949781048 -> 1
+xdiv415 divide 5615373.52 -7.27583808E-949781048 -> -7.71783739E+949781053 Inexact Rounded
+xdvi415 divideint 5615373.52 -7.27583808E-949781048 -> NaN Division_impossible
+xmul415 multiply 5615373.52 -7.27583808E-949781048 -> -4.08565485E-949781041 Inexact Rounded
+xpow415 power 5615373.52 -7 -> 5.68001460E-48 Inexact Rounded
+xrem415 remainder 5615373.52 -7.27583808E-949781048 -> NaN Division_impossible
+xsub415 subtract 5615373.52 -7.27583808E-949781048 -> 5615373.52 Inexact Rounded
+xadd416 add 644136.179 -835708.103 -> -191571.924
+xcom416 compare 644136.179 -835708.103 -> 1
+xdiv416 divide 644136.179 -835708.103 -> -0.770766942 Inexact Rounded
+xdvi416 divideint 644136.179 -835708.103 -> -0
+xmul416 multiply 644136.179 -835708.103 -> -5.38309824E+11 Inexact Rounded
+xpow416 power 644136.179 -835708 -> 7.41936858E-4854610 Inexact Rounded
+xrem416 remainder 644136.179 -835708.103 -> 644136.179
+xsub416 subtract 644136.179 -835708.103 -> 1479844.28 Inexact Rounded
+xadd417 add -307.419521E+466861843 -738689976.E-199032711 -> -3.07419521E+466861845 Inexact Rounded
+xcom417 compare -307.419521E+466861843 -738689976.E-199032711 -> -1
+xdiv417 divide -307.419521E+466861843 -738689976.E-199032711 -> 4.16168529E+665894547 Inexact Rounded
+xdvi417 divideint -307.419521E+466861843 -738689976.E-199032711 -> NaN Division_impossible
+xmul417 multiply -307.419521E+466861843 -738689976.E-199032711 -> 2.27087719E+267829143 Inexact Rounded
+xpow417 power -307.419521E+466861843 -7 -> -0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem417 remainder -307.419521E+466861843 -738689976.E-199032711 -> NaN Division_impossible
+xsub417 subtract -307.419521E+466861843 -738689976.E-199032711 -> -3.07419521E+466861845 Inexact Rounded
+xadd418 add -619642.130 -226740537.E-902590153 -> -619642.130 Inexact Rounded
+xcom418 compare -619642.130 -226740537.E-902590153 -> -1
+xdiv418 divide -619642.130 -226740537.E-902590153 -> 2.73282466E+902590150 Inexact Rounded
+xdvi418 divideint -619642.130 -226740537.E-902590153 -> NaN Division_impossible
+xmul418 multiply -619642.130 -226740537.E-902590153 -> 1.40497989E-902590139 Inexact Rounded
+xpow418 power -619642.130 -2 -> 2.60446259E-12 Inexact Rounded
+xrem418 remainder -619642.130 -226740537.E-902590153 -> NaN Division_impossible
+xsub418 subtract -619642.130 -226740537.E-902590153 -> -619642.130 Inexact Rounded
+xadd419 add -31068.7549 -3.41495042E+86001379 -> -3.41495042E+86001379 Inexact Rounded
+xcom419 compare -31068.7549 -3.41495042E+86001379 -> 1
+xdiv419 divide -31068.7549 -3.41495042E+86001379 -> 9.09786412E-86001376 Inexact Rounded
+xdvi419 divideint -31068.7549 -3.41495042E+86001379 -> 0
+xmul419 multiply -31068.7549 -3.41495042E+86001379 -> 1.06098258E+86001384 Inexact Rounded
+xpow419 power -31068.7549 -3 -> -3.33448258E-14 Inexact Rounded
+xrem419 remainder -31068.7549 -3.41495042E+86001379 -> -31068.7549
+xsub419 subtract -31068.7549 -3.41495042E+86001379 -> 3.41495042E+86001379 Inexact Rounded
+xadd420 add -68951173. -211804977.E-97318126 -> -68951173.0 Inexact Rounded
+xcom420 compare -68951173. -211804977.E-97318126 -> -1
+xdiv420 divide -68951173. -211804977.E-97318126 -> 3.25540854E+97318125 Inexact Rounded
+xdvi420 divideint -68951173. -211804977.E-97318126 -> NaN Division_impossible
+xmul420 multiply -68951173. -211804977.E-97318126 -> 1.46042016E-97318110 Inexact Rounded
+xpow420 power -68951173. -2 -> 2.10337488E-16 Inexact Rounded
+xrem420 remainder -68951173. -211804977.E-97318126 -> NaN Division_impossible
+xsub420 subtract -68951173. -211804977.E-97318126 -> -68951173.0 Inexact Rounded
+xadd421 add -4.09492571E-301749490 434.20199E-749390952 -> -4.09492571E-301749490 Inexact Rounded
+xcom421 compare -4.09492571E-301749490 434.20199E-749390952 -> -1
+xdiv421 divide -4.09492571E-301749490 434.20199E-749390952 -> -9.43092341E+447641459 Inexact Rounded
+xdvi421 divideint -4.09492571E-301749490 434.20199E-749390952 -> NaN Division_impossible
+xmul421 multiply -4.09492571E-301749490 434.20199E-749390952 -> -0E-1000000007 Underflow Subnormal Inexact Rounded
+xpow421 power -4.09492571E-301749490 4 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem421 remainder -4.09492571E-301749490 434.20199E-749390952 -> NaN Division_impossible
+xsub421 subtract -4.09492571E-301749490 434.20199E-749390952 -> -4.09492571E-301749490 Inexact Rounded
+xadd422 add 3898.03188 -82572.615 -> -78674.5831 Inexact Rounded
+xcom422 compare 3898.03188 -82572.615 -> 1
+xdiv422 divide 3898.03188 -82572.615 -> -0.0472073202 Inexact Rounded
+xdvi422 divideint 3898.03188 -82572.615 -> -0
+xmul422 multiply 3898.03188 -82572.615 -> -321870686 Inexact Rounded
+xpow422 power 3898.03188 -82573 -> 1.33010737E-296507 Inexact Rounded
+xrem422 remainder 3898.03188 -82572.615 -> 3898.03188
+xsub422 subtract 3898.03188 -82572.615 -> 86470.6469 Inexact Rounded
+xadd423 add -1.7619356 -2546.64043 -> -2548.40237 Inexact Rounded
+xcom423 compare -1.7619356 -2546.64043 -> 1
+xdiv423 divide -1.7619356 -2546.64043 -> 0.000691866657 Inexact Rounded
+xdvi423 divideint -1.7619356 -2546.64043 -> 0
+xmul423 multiply -1.7619356 -2546.64043 -> 4487.01643 Inexact Rounded
+xpow423 power -1.7619356 -2547 -> -2.90664557E-627 Inexact Rounded
+xrem423 remainder -1.7619356 -2546.64043 -> -1.7619356
+xsub423 subtract -1.7619356 -2546.64043 -> 2544.87849 Inexact Rounded
+xadd424 add 59714.1968 29734388.6E-564525525 -> 59714.1968 Inexact Rounded
+xcom424 compare 59714.1968 29734388.6E-564525525 -> 1
+xdiv424 divide 59714.1968 29734388.6E-564525525 -> 2.00825373E+564525522 Inexact Rounded
+xdvi424 divideint 59714.1968 29734388.6E-564525525 -> NaN Division_impossible
+xmul424 multiply 59714.1968 29734388.6E-564525525 -> 1.77556513E-564525513 Inexact Rounded
+xpow424 power 59714.1968 3 -> 2.12928005E+14 Inexact Rounded
+xrem424 remainder 59714.1968 29734388.6E-564525525 -> NaN Division_impossible
+xsub424 subtract 59714.1968 29734388.6E-564525525 -> 59714.1968 Inexact Rounded
+xadd425 add 6.88891136E-935467395 -785049.562E-741671442 -> -7.85049562E-741671437 Inexact Rounded
+xcom425 compare 6.88891136E-935467395 -785049.562E-741671442 -> 1
+xdiv425 divide 6.88891136E-935467395 -785049.562E-741671442 -> -8.77512923E-193795959 Inexact Rounded
+xdvi425 divideint 6.88891136E-935467395 -785049.562E-741671442 -> -0
+xmul425 multiply 6.88891136E-935467395 -785049.562E-741671442 -> -0E-1000000007 Underflow Subnormal Inexact Rounded
+xpow425 power 6.88891136E-935467395 -8 -> Infinity Overflow Inexact Rounded
+xrem425 remainder 6.88891136E-935467395 -785049.562E-741671442 -> 6.88891136E-935467395
+xsub425 subtract 6.88891136E-935467395 -785049.562E-741671442 -> 7.85049562E-741671437 Inexact Rounded
+xadd426 add 975566251 -519.858530 -> 975565731 Inexact Rounded
+xcom426 compare 975566251 -519.858530 -> 1
+xdiv426 divide 975566251 -519.858530 -> -1876599.49 Inexact Rounded
+xdvi426 divideint 975566251 -519.858530 -> -1876599
+xmul426 multiply 975566251 -519.858530 -> -5.07156437E+11 Inexact Rounded
+xpow426 power 975566251 -520 -> 3.85905300E-4675 Inexact Rounded
+xrem426 remainder 975566251 -519.858530 -> 253.460530
+xsub426 subtract 975566251 -519.858530 -> 975566771 Inexact Rounded
+xadd427 add 307401954 -231481582. -> 75920372
+xcom427 compare 307401954 -231481582. -> 1
+xdiv427 divide 307401954 -231481582. -> -1.32797586 Inexact Rounded
+xdvi427 divideint 307401954 -231481582. -> -1
+xmul427 multiply 307401954 -231481582. -> -7.11578906E+16 Inexact Rounded
+xpow427 power 307401954 -231481582 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem427 remainder 307401954 -231481582. -> 75920372
+xsub427 subtract 307401954 -231481582. -> 538883536
+xadd428 add 2237645.48E+992947388 -60618055.3E-857316706 -> 2.23764548E+992947394 Inexact Rounded
+xcom428 compare 2237645.48E+992947388 -60618055.3E-857316706 -> 1
+xdiv428 divide 2237645.48E+992947388 -60618055.3E-857316706 -> -Infinity Inexact Overflow Rounded
+xdvi428 divideint 2237645.48E+992947388 -60618055.3E-857316706 -> NaN Division_impossible
+xmul428 multiply 2237645.48E+992947388 -60618055.3E-857316706 -> -1.35641717E+135630696 Inexact Rounded
+xpow428 power 2237645.48E+992947388 -6 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem428 remainder 2237645.48E+992947388 -60618055.3E-857316706 -> NaN Division_impossible
+xsub428 subtract 2237645.48E+992947388 -60618055.3E-857316706 -> 2.23764548E+992947394 Inexact Rounded
+xadd429 add -403903.851 35.5049687E-72095155 -> -403903.851 Inexact Rounded
+xcom429 compare -403903.851 35.5049687E-72095155 -> -1
+xdiv429 divide -403903.851 35.5049687E-72095155 -> -1.13759810E+72095159 Inexact Rounded
+xdvi429 divideint -403903.851 35.5049687E-72095155 -> NaN Division_impossible
+xmul429 multiply -403903.851 35.5049687E-72095155 -> -1.43405936E-72095148 Inexact Rounded
+xpow429 power -403903.851 4 -> 2.66141117E+22 Inexact Rounded
+xrem429 remainder -403903.851 35.5049687E-72095155 -> NaN Division_impossible
+xsub429 subtract -403903.851 35.5049687E-72095155 -> -403903.851 Inexact Rounded
+xadd430 add 6.48674979 -621732.532E+422575800 -> -6.21732532E+422575805 Inexact Rounded
+xcom430 compare 6.48674979 -621732.532E+422575800 -> 1
+xdiv430 divide 6.48674979 -621732.532E+422575800 -> -1.04333447E-422575805 Inexact Rounded
+xdvi430 divideint 6.48674979 -621732.532E+422575800 -> -0
+xmul430 multiply 6.48674979 -621732.532E+422575800 -> -4.03302337E+422575806 Inexact Rounded
+xpow430 power 6.48674979 -6 -> 0.0000134226146 Inexact Rounded
+xrem430 remainder 6.48674979 -621732.532E+422575800 -> 6.48674979
+xsub430 subtract 6.48674979 -621732.532E+422575800 -> 6.21732532E+422575805 Inexact Rounded
+xadd431 add -31401.9418 36.3960679 -> -31365.5457 Inexact Rounded
+xcom431 compare -31401.9418 36.3960679 -> -1
+xdiv431 divide -31401.9418 36.3960679 -> -862.783911 Inexact Rounded
+xdvi431 divideint -31401.9418 36.3960679 -> -862
+xmul431 multiply -31401.9418 36.3960679 -> -1142907.21 Inexact Rounded
+xpow431 power -31401.9418 36 -> 7.77023505E+161 Inexact Rounded
+xrem431 remainder -31401.9418 36.3960679 -> -28.5312702
+xsub431 subtract -31401.9418 36.3960679 -> -31438.3379 Inexact Rounded
+xadd432 add 31345321.1 51.5482191 -> 31345372.6 Inexact Rounded
+xcom432 compare 31345321.1 51.5482191 -> 1
+xdiv432 divide 31345321.1 51.5482191 -> 608077.673 Inexact Rounded
+xdvi432 divideint 31345321.1 51.5482191 -> 608077
+xmul432 multiply 31345321.1 51.5482191 -> 1.61579548E+9 Inexact Rounded
+xpow432 power 31345321.1 52 -> 6.32385059E+389 Inexact Rounded
+xrem432 remainder 31345321.1 51.5482191 -> 34.6743293
+xsub432 subtract 31345321.1 51.5482191 -> 31345269.6 Inexact Rounded
+xadd433 add -64.172844 -28506227.2E-767965800 -> -64.1728440 Inexact Rounded
+xcom433 compare -64.172844 -28506227.2E-767965800 -> -1
+xdiv433 divide -64.172844 -28506227.2E-767965800 -> 2.25118686E+767965794 Inexact Rounded
+xdvi433 divideint -64.172844 -28506227.2E-767965800 -> NaN Division_impossible
+xmul433 multiply -64.172844 -28506227.2E-767965800 -> 1.82932567E-767965791 Inexact Rounded
+xpow433 power -64.172844 -3 -> -0.00000378395654 Inexact Rounded
+xrem433 remainder -64.172844 -28506227.2E-767965800 -> NaN Division_impossible
+xsub433 subtract -64.172844 -28506227.2E-767965800 -> -64.1728440 Inexact Rounded
+xadd434 add 70437.1551 -62916.1233 -> 7521.0318
+xcom434 compare 70437.1551 -62916.1233 -> 1
+xdiv434 divide 70437.1551 -62916.1233 -> -1.11954061 Inexact Rounded
+xdvi434 divideint 70437.1551 -62916.1233 -> -1
+xmul434 multiply 70437.1551 -62916.1233 -> -4.43163274E+9 Inexact Rounded
+xpow434 power 70437.1551 -62916 -> 5.02945060E-305005 Inexact Rounded
+xrem434 remainder 70437.1551 -62916.1233 -> 7521.0318
+xsub434 subtract 70437.1551 -62916.1233 -> 133353.278 Inexact Rounded
+xadd435 add 916260164 -58.4017325 -> 916260106 Inexact Rounded
+xcom435 compare 916260164 -58.4017325 -> 1
+xdiv435 divide 916260164 -58.4017325 -> -15688920.9 Inexact Rounded
+xdvi435 divideint 916260164 -58.4017325 -> -15688920
+xmul435 multiply 916260164 -58.4017325 -> -5.35111810E+10 Inexact Rounded
+xpow435 power 916260164 -58 -> 1.59554587E-520 Inexact Rounded
+xrem435 remainder 916260164 -58.4017325 -> 54.9461000
+xsub435 subtract 916260164 -58.4017325 -> 916260222 Inexact Rounded
+xadd436 add 19889085.3E-46816480 1581683.94 -> 1581683.94 Inexact Rounded
+xcom436 compare 19889085.3E-46816480 1581683.94 -> -1
+xdiv436 divide 19889085.3E-46816480 1581683.94 -> 1.25746268E-46816479 Inexact Rounded
+xdvi436 divideint 19889085.3E-46816480 1581683.94 -> 0
+xmul436 multiply 19889085.3E-46816480 1581683.94 -> 3.14582468E-46816467 Inexact Rounded
+xpow436 power 19889085.3E-46816480 1581684 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem436 remainder 19889085.3E-46816480 1581683.94 -> 1.98890853E-46816473
+xsub436 subtract 19889085.3E-46816480 1581683.94 -> -1581683.94 Inexact Rounded
+xadd437 add -56312.3383 789.466064 -> -55522.8722 Inexact Rounded
+xcom437 compare -56312.3383 789.466064 -> -1
+xdiv437 divide -56312.3383 789.466064 -> -71.3296503 Inexact Rounded
+xdvi437 divideint -56312.3383 789.466064 -> -71
+xmul437 multiply -56312.3383 789.466064 -> -44456680.1 Inexact Rounded
+xpow437 power -56312.3383 789 -> -1.68348724E+3748 Inexact Rounded
+xrem437 remainder -56312.3383 789.466064 -> -260.247756
+xsub437 subtract -56312.3383 789.466064 -> -57101.8044 Inexact Rounded
+xadd438 add 183442.849 -925876106 -> -925692663 Inexact Rounded
+xcom438 compare 183442.849 -925876106 -> 1
+xdiv438 divide 183442.849 -925876106 -> -0.000198128937 Inexact Rounded
+xdvi438 divideint 183442.849 -925876106 -> -0
+xmul438 multiply 183442.849 -925876106 -> -1.69845351E+14 Inexact Rounded
+xpow438 power 183442.849 -925876106 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem438 remainder 183442.849 -925876106 -> 183442.849
+xsub438 subtract 183442.849 -925876106 -> 926059549 Inexact Rounded
+xadd439 add 971113.655E-695540249 -419351120E-977743823 -> 9.71113655E-695540244 Inexact Rounded
+xcom439 compare 971113.655E-695540249 -419351120E-977743823 -> 1
+xdiv439 divide 971113.655E-695540249 -419351120E-977743823 -> -2.31575310E+282203571 Inexact Rounded
+xdvi439 divideint 971113.655E-695540249 -419351120E-977743823 -> NaN Division_impossible
+xmul439 multiply 971113.655E-695540249 -419351120E-977743823 -> -0E-1000000007 Underflow Subnormal Inexact Rounded
+xpow439 power 971113.655E-695540249 -4 -> Infinity Overflow Inexact Rounded
+xrem439 remainder 971113.655E-695540249 -419351120E-977743823 -> NaN Division_impossible
+xsub439 subtract 971113.655E-695540249 -419351120E-977743823 -> 9.71113655E-695540244 Inexact Rounded
+xadd440 add 859658551. 72338.2054 -> 859730889 Inexact Rounded
+xcom440 compare 859658551. 72338.2054 -> 1
+xdiv440 divide 859658551. 72338.2054 -> 11883.8800 Inexact Rounded
+xdvi440 divideint 859658551. 72338.2054 -> 11883
+xmul440 multiply 859658551. 72338.2054 -> 6.21861568E+13 Inexact Rounded
+xpow440 power 859658551. 72338 -> 1.87620450E+646291 Inexact Rounded
+xrem440 remainder 859658551. 72338.2054 -> 63656.2318
+xsub440 subtract 859658551. 72338.2054 -> 859586213 Inexact Rounded
+xadd441 add -3.86446630E+426816068 -664.534737 -> -3.86446630E+426816068 Inexact Rounded
+xcom441 compare -3.86446630E+426816068 -664.534737 -> -1
+xdiv441 divide -3.86446630E+426816068 -664.534737 -> 5.81529615E+426816065 Inexact Rounded
+xdvi441 divideint -3.86446630E+426816068 -664.534737 -> NaN Division_impossible
+xmul441 multiply -3.86446630E+426816068 -664.534737 -> 2.56807210E+426816071 Inexact Rounded
+xpow441 power -3.86446630E+426816068 -665 -> -0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem441 remainder -3.86446630E+426816068 -664.534737 -> NaN Division_impossible
+xsub441 subtract -3.86446630E+426816068 -664.534737 -> -3.86446630E+426816068 Inexact Rounded
+xadd442 add -969.881818 31170.8555 -> 30200.9737 Inexact Rounded
+xcom442 compare -969.881818 31170.8555 -> -1
+xdiv442 divide -969.881818 31170.8555 -> -0.0311150208 Inexact Rounded
+xdvi442 divideint -969.881818 31170.8555 -> -0
+xmul442 multiply -969.881818 31170.8555 -> -30232046.0 Inexact Rounded
+xpow442 power -969.881818 31171 -> -1.02865894E+93099 Inexact Rounded
+xrem442 remainder -969.881818 31170.8555 -> -969.881818
+xsub442 subtract -969.881818 31170.8555 -> -32140.7373 Inexact Rounded
+xadd443 add 7980537.27 85.4040512 -> 7980622.67 Inexact Rounded
+xcom443 compare 7980537.27 85.4040512 -> 1
+xdiv443 divide 7980537.27 85.4040512 -> 93444.4814 Inexact Rounded
+xdvi443 divideint 7980537.27 85.4040512 -> 93444
+xmul443 multiply 7980537.27 85.4040512 -> 681570214 Inexact Rounded
+xpow443 power 7980537.27 85 -> 4.70685763E+586 Inexact Rounded
+xrem443 remainder 7980537.27 85.4040512 -> 41.1096672
+xsub443 subtract 7980537.27 85.4040512 -> 7980451.87 Inexact Rounded
+xadd444 add -114609916. 7525.14981 -> -114602391 Inexact Rounded
+xcom444 compare -114609916. 7525.14981 -> -1
+xdiv444 divide -114609916. 7525.14981 -> -15230.2504 Inexact Rounded
+xdvi444 divideint -114609916. 7525.14981 -> -15230
+xmul444 multiply -114609916. 7525.14981 -> -8.62456788E+11 Inexact Rounded
+xpow444 power -114609916. 7525 -> -4.43620445E+60645 Inexact Rounded
+xrem444 remainder -114609916. 7525.14981 -> -1884.39370
+xsub444 subtract -114609916. 7525.14981 -> -114617441 Inexact Rounded
+xadd445 add 8.43404682E-500572568 474526719 -> 474526719 Inexact Rounded
+xcom445 compare 8.43404682E-500572568 474526719 -> -1
+xdiv445 divide 8.43404682E-500572568 474526719 -> 1.77735973E-500572576 Inexact Rounded
+xdvi445 divideint 8.43404682E-500572568 474526719 -> 0
+xmul445 multiply 8.43404682E-500572568 474526719 -> 4.00218057E-500572559 Inexact Rounded
+xpow445 power 8.43404682E-500572568 474526719 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem445 remainder 8.43404682E-500572568 474526719 -> 8.43404682E-500572568
+xsub445 subtract 8.43404682E-500572568 474526719 -> -474526719 Inexact Rounded
+xadd446 add 188006433 2260.17037E-978192525 -> 188006433 Inexact Rounded
+xcom446 compare 188006433 2260.17037E-978192525 -> 1
+xdiv446 divide 188006433 2260.17037E-978192525 -> 8.31824165E+978192529 Inexact Rounded
+xdvi446 divideint 188006433 2260.17037E-978192525 -> NaN Division_impossible
+xmul446 multiply 188006433 2260.17037E-978192525 -> 4.24926569E-978192514 Inexact Rounded
+xpow446 power 188006433 2 -> 3.53464188E+16 Inexact Rounded
+xrem446 remainder 188006433 2260.17037E-978192525 -> NaN Division_impossible
+xsub446 subtract 188006433 2260.17037E-978192525 -> 188006433 Inexact Rounded
+xadd447 add -9.95836312 -866466703 -> -866466713 Inexact Rounded
+xcom447 compare -9.95836312 -866466703 -> 1
+xdiv447 divide -9.95836312 -866466703 -> 1.14930707E-8 Inexact Rounded
+xdvi447 divideint -9.95836312 -866466703 -> 0
+xmul447 multiply -9.95836312 -866466703 -> 8.62859006E+9 Inexact Rounded
+xpow447 power -9.95836312 -866466703 -> -6.71744368E-864896630 Inexact Rounded
+xrem447 remainder -9.95836312 -866466703 -> -9.95836312
+xsub447 subtract -9.95836312 -866466703 -> 866466693 Inexact Rounded
+xadd448 add 80919339.2E-967231586 219.824266 -> 219.824266 Inexact Rounded
+xcom448 compare 80919339.2E-967231586 219.824266 -> -1
+xdiv448 divide 80919339.2E-967231586 219.824266 -> 3.68109220E-967231581 Inexact Rounded
+xdvi448 divideint 80919339.2E-967231586 219.824266 -> 0
+xmul448 multiply 80919339.2E-967231586 219.824266 -> 1.77880343E-967231576 Inexact Rounded
+xpow448 power 80919339.2E-967231586 220 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem448 remainder 80919339.2E-967231586 219.824266 -> 8.09193392E-967231579
+xsub448 subtract 80919339.2E-967231586 219.824266 -> -219.824266 Inexact Rounded
+xadd449 add 159579.444 -89827.5229 -> 69751.9211
+xcom449 compare 159579.444 -89827.5229 -> 1
+xdiv449 divide 159579.444 -89827.5229 -> -1.77650946 Inexact Rounded
+xdvi449 divideint 159579.444 -89827.5229 -> -1
+xmul449 multiply 159579.444 -89827.5229 -> -1.43346262E+10 Inexact Rounded
+xpow449 power 159579.444 -89828 -> 9.69955849E-467374 Inexact Rounded
+xrem449 remainder 159579.444 -89827.5229 -> 69751.9211
+xsub449 subtract 159579.444 -89827.5229 -> 249406.967 Inexact Rounded
+xadd450 add -4.54000153 6966333.74 -> 6966329.20 Inexact Rounded
+xcom450 compare -4.54000153 6966333.74 -> -1
+xdiv450 divide -4.54000153 6966333.74 -> -6.51706005E-7 Inexact Rounded
+xdvi450 divideint -4.54000153 6966333.74 -> -0
+xmul450 multiply -4.54000153 6966333.74 -> -31627165.8 Inexact Rounded
+xpow450 power -4.54000153 6966334 -> 3.52568913E+4577271 Inexact Rounded
+xrem450 remainder -4.54000153 6966333.74 -> -4.54000153
+xsub450 subtract -4.54000153 6966333.74 -> -6966338.28 Inexact Rounded
+xadd451 add 28701538.7E-391015649 -920999192. -> -920999192 Inexact Rounded
+xcom451 compare 28701538.7E-391015649 -920999192. -> 1
+xdiv451 divide 28701538.7E-391015649 -920999192. -> -3.11634787E-391015651 Inexact Rounded
+xdvi451 divideint 28701538.7E-391015649 -920999192. -> -0
+xmul451 multiply 28701538.7E-391015649 -920999192. -> -2.64340940E-391015633 Inexact Rounded
+xpow451 power 28701538.7E-391015649 -920999192 -> Infinity Overflow Inexact Rounded
+xrem451 remainder 28701538.7E-391015649 -920999192. -> 2.87015387E-391015642
+xsub451 subtract 28701538.7E-391015649 -920999192. -> 920999192 Inexact Rounded
+xadd452 add -361382575. -7976.15286E+898491169 -> -7.97615286E+898491172 Inexact Rounded
+xcom452 compare -361382575. -7976.15286E+898491169 -> 1
+xdiv452 divide -361382575. -7976.15286E+898491169 -> 4.53078798E-898491165 Inexact Rounded
+xdvi452 divideint -361382575. -7976.15286E+898491169 -> 0
+xmul452 multiply -361382575. -7976.15286E+898491169 -> 2.88244266E+898491181 Inexact Rounded
+xpow452 power -361382575. -8 -> 3.43765536E-69 Inexact Rounded
+xrem452 remainder -361382575. -7976.15286E+898491169 -> -361382575
+xsub452 subtract -361382575. -7976.15286E+898491169 -> 7.97615286E+898491172 Inexact Rounded
+xadd453 add 7021805.61 1222952.83 -> 8244758.44
+xcom453 compare 7021805.61 1222952.83 -> 1
+xdiv453 divide 7021805.61 1222952.83 -> 5.74168148 Inexact Rounded
+xdvi453 divideint 7021805.61 1222952.83 -> 5
+xmul453 multiply 7021805.61 1222952.83 -> 8.58733704E+12 Inexact Rounded
+xpow453 power 7021805.61 1222953 -> 1.26540553E+8372885 Inexact Rounded
+xrem453 remainder 7021805.61 1222952.83 -> 907041.46
+xsub453 subtract 7021805.61 1222952.83 -> 5798852.78
+xadd454 add -40.4811667 -79655.5635 -> -79696.0447 Inexact Rounded
+xcom454 compare -40.4811667 -79655.5635 -> 1
+xdiv454 divide -40.4811667 -79655.5635 -> 0.000508202628 Inexact Rounded
+xdvi454 divideint -40.4811667 -79655.5635 -> 0
+xmul454 multiply -40.4811667 -79655.5635 -> 3224550.14 Inexact Rounded
+xpow454 power -40.4811667 -79656 -> 4.50174275E-128028 Inexact Rounded
+xrem454 remainder -40.4811667 -79655.5635 -> -40.4811667
+xsub454 subtract -40.4811667 -79655.5635 -> 79615.0823 Inexact Rounded
+xadd455 add -8755674.38E+117168177 148.903404 -> -8.75567438E+117168183 Inexact Rounded
+xcom455 compare -8755674.38E+117168177 148.903404 -> -1
+xdiv455 divide -8755674.38E+117168177 148.903404 -> -5.88010357E+117168181 Inexact Rounded
+xdvi455 divideint -8755674.38E+117168177 148.903404 -> NaN Division_impossible
+xmul455 multiply -8755674.38E+117168177 148.903404 -> -1.30374972E+117168186 Inexact Rounded
+xpow455 power -8755674.38E+117168177 149 -> -Infinity Overflow Inexact Rounded
+xrem455 remainder -8755674.38E+117168177 148.903404 -> NaN Division_impossible
+xsub455 subtract -8755674.38E+117168177 148.903404 -> -8.75567438E+117168183 Inexact Rounded
+xadd456 add 34.5329781E+382829392 -45.2177309 -> 3.45329781E+382829393 Inexact Rounded
+xcom456 compare 34.5329781E+382829392 -45.2177309 -> 1
+xdiv456 divide 34.5329781E+382829392 -45.2177309 -> -7.63704357E+382829391 Inexact Rounded
+xdvi456 divideint 34.5329781E+382829392 -45.2177309 -> NaN Division_impossible
+xmul456 multiply 34.5329781E+382829392 -45.2177309 -> -1.56150291E+382829395 Inexact Rounded
+xpow456 power 34.5329781E+382829392 -45 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem456 remainder 34.5329781E+382829392 -45.2177309 -> NaN Division_impossible
+xsub456 subtract 34.5329781E+382829392 -45.2177309 -> 3.45329781E+382829393 Inexact Rounded
+xadd457 add -37958476.0 584367.935 -> -37374108.1 Inexact Rounded
+xcom457 compare -37958476.0 584367.935 -> -1
+xdiv457 divide -37958476.0 584367.935 -> -64.9564662 Inexact Rounded
+xdvi457 divideint -37958476.0 584367.935 -> -64
+xmul457 multiply -37958476.0 584367.935 -> -2.21817162E+13 Inexact Rounded
+xpow457 power -37958476.0 584368 -> 3.20538268E+4429105 Inexact Rounded
+xrem457 remainder -37958476.0 584367.935 -> -558928.160
+xsub457 subtract -37958476.0 584367.935 -> -38542843.9 Inexact Rounded
+xadd458 add 495233.553E-414152215 62352759.2 -> 62352759.2 Inexact Rounded
+xcom458 compare 495233.553E-414152215 62352759.2 -> -1
+xdiv458 divide 495233.553E-414152215 62352759.2 -> 7.94244809E-414152218 Inexact Rounded
+xdvi458 divideint 495233.553E-414152215 62352759.2 -> 0
+xmul458 multiply 495233.553E-414152215 62352759.2 -> 3.08791785E-414152202 Inexact Rounded
+xpow458 power 495233.553E-414152215 62352759 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem458 remainder 495233.553E-414152215 62352759.2 -> 4.95233553E-414152210
+xsub458 subtract 495233.553E-414152215 62352759.2 -> -62352759.2 Inexact Rounded
+xadd459 add -502343060 -96828.994 -> -502439889 Inexact Rounded
+xcom459 compare -502343060 -96828.994 -> -1
+xdiv459 divide -502343060 -96828.994 -> 5187.94050 Inexact Rounded
+xdvi459 divideint -502343060 -96828.994 -> 5187
+xmul459 multiply -502343060 -96828.994 -> 4.86413731E+13 Inexact Rounded
+xpow459 power -502343060 -96829 -> -6.78602119E-842510 Inexact Rounded
+xrem459 remainder -502343060 -96828.994 -> -91068.122
+xsub459 subtract -502343060 -96828.994 -> -502246231 Inexact Rounded
+xadd460 add -22.439639E+916362878 -39.4037681 -> -2.24396390E+916362879 Inexact Rounded
+xcom460 compare -22.439639E+916362878 -39.4037681 -> -1
+xdiv460 divide -22.439639E+916362878 -39.4037681 -> 5.69479521E+916362877 Inexact Rounded
+xdvi460 divideint -22.439639E+916362878 -39.4037681 -> NaN Division_impossible
+xmul460 multiply -22.439639E+916362878 -39.4037681 -> 8.84206331E+916362880 Inexact Rounded
+xpow460 power -22.439639E+916362878 -39 -> -0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem460 remainder -22.439639E+916362878 -39.4037681 -> NaN Division_impossible
+xsub460 subtract -22.439639E+916362878 -39.4037681 -> -2.24396390E+916362879 Inexact Rounded
+xadd461 add 718180.587E-957473722 1.66223443 -> 1.66223443 Inexact Rounded
+xcom461 compare 718180.587E-957473722 1.66223443 -> -1
+xdiv461 divide 718180.587E-957473722 1.66223443 -> 4.32057340E-957473717 Inexact Rounded
+xdvi461 divideint 718180.587E-957473722 1.66223443 -> 0
+xmul461 multiply 718180.587E-957473722 1.66223443 -> 1.19378450E-957473716 Inexact Rounded
+xpow461 power 718180.587E-957473722 2 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem461 remainder 718180.587E-957473722 1.66223443 -> 7.18180587E-957473717
+xsub461 subtract 718180.587E-957473722 1.66223443 -> -1.66223443 Inexact Rounded
+xadd462 add -51592.2698 -713885.741 -> -765478.011 Inexact Rounded
+xcom462 compare -51592.2698 -713885.741 -> 1
+xdiv462 divide -51592.2698 -713885.741 -> 0.0722696460 Inexact Rounded
+xdvi462 divideint -51592.2698 -713885.741 -> 0
+xmul462 multiply -51592.2698 -713885.741 -> 3.68309858E+10 Inexact Rounded
+xpow462 power -51592.2698 -713886 -> 6.38576921E-3364249 Inexact Rounded
+xrem462 remainder -51592.2698 -713885.741 -> -51592.2698
+xsub462 subtract -51592.2698 -713885.741 -> 662293.471 Inexact Rounded
+xadd463 add 51.2279848E+80439745 207.55925E+865165070 -> 2.07559250E+865165072 Inexact Rounded
+xcom463 compare 51.2279848E+80439745 207.55925E+865165070 -> -1
+xdiv463 divide 51.2279848E+80439745 207.55925E+865165070 -> 2.46811379E-784725326 Inexact Rounded
+xdvi463 divideint 51.2279848E+80439745 207.55925E+865165070 -> 0
+xmul463 multiply 51.2279848E+80439745 207.55925E+865165070 -> 1.06328421E+945604819 Inexact Rounded
+xpow463 power 51.2279848E+80439745 2 -> 2.62430643E+160879493 Inexact Rounded
+xrem463 remainder 51.2279848E+80439745 207.55925E+865165070 -> 5.12279848E+80439746
+xsub463 subtract 51.2279848E+80439745 207.55925E+865165070 -> -2.07559250E+865165072 Inexact Rounded
+xadd464 add -5983.23468 -39.9544513 -> -6023.18913 Inexact Rounded
+xcom464 compare -5983.23468 -39.9544513 -> -1
+xdiv464 divide -5983.23468 -39.9544513 -> 149.751392 Inexact Rounded
+xdvi464 divideint -5983.23468 -39.9544513 -> 149
+xmul464 multiply -5983.23468 -39.9544513 -> 239056.859 Inexact Rounded
+xpow464 power -5983.23468 -40 -> 8.36678291E-152 Inexact Rounded
+xrem464 remainder -5983.23468 -39.9544513 -> -30.0214363
+xsub464 subtract -5983.23468 -39.9544513 -> -5943.28023 Inexact Rounded
+xadd465 add 921639332.E-917542963 287325.891 -> 287325.891 Inexact Rounded
+xcom465 compare 921639332.E-917542963 287325.891 -> -1
+xdiv465 divide 921639332.E-917542963 287325.891 -> 3.20764456E-917542960 Inexact Rounded
+xdvi465 divideint 921639332.E-917542963 287325.891 -> 0
+xmul465 multiply 921639332.E-917542963 287325.891 -> 2.64810842E-917542949 Inexact Rounded
+xpow465 power 921639332.E-917542963 287326 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem465 remainder 921639332.E-917542963 287325.891 -> 9.21639332E-917542955
+xsub465 subtract 921639332.E-917542963 287325.891 -> -287325.891 Inexact Rounded
+xadd466 add 91095916.8E-787312969 -58643.418E+58189880 -> -5.86434180E+58189884 Inexact Rounded
+xcom466 compare 91095916.8E-787312969 -58643.418E+58189880 -> 1
+xdiv466 divide 91095916.8E-787312969 -58643.418E+58189880 -> -1.55338689E-845502846 Inexact Rounded
+xdvi466 divideint 91095916.8E-787312969 -58643.418E+58189880 -> -0
+xmul466 multiply 91095916.8E-787312969 -58643.418E+58189880 -> -5.34217593E-729123077 Inexact Rounded
+xpow466 power 91095916.8E-787312969 -6 -> Infinity Overflow Inexact Rounded
+xrem466 remainder 91095916.8E-787312969 -58643.418E+58189880 -> 9.10959168E-787312962
+xsub466 subtract 91095916.8E-787312969 -58643.418E+58189880 -> 5.86434180E+58189884 Inexact Rounded
+xadd467 add -6410.5555 -234964259 -> -234970670 Inexact Rounded
+xcom467 compare -6410.5555 -234964259 -> 1
+xdiv467 divide -6410.5555 -234964259 -> 0.0000272831090 Inexact Rounded
+xdvi467 divideint -6410.5555 -234964259 -> 0
+xmul467 multiply -6410.5555 -234964259 -> 1.50625142E+12 Inexact Rounded
+xpow467 power -6410.5555 -234964259 -> -1.27064467E-894484419 Inexact Rounded
+xrem467 remainder -6410.5555 -234964259 -> -6410.5555
+xsub467 subtract -6410.5555 -234964259 -> 234957848 Inexact Rounded
+xadd468 add -5.32711606 -8447286.21 -> -8447291.54 Inexact Rounded
+xcom468 compare -5.32711606 -8447286.21 -> 1
+xdiv468 divide -5.32711606 -8447286.21 -> 6.30630468E-7 Inexact Rounded
+xdvi468 divideint -5.32711606 -8447286.21 -> 0
+xmul468 multiply -5.32711606 -8447286.21 -> 44999674.0 Inexact Rounded
+xpow468 power -5.32711606 -8447286 -> 9.09138729E-6136888 Inexact Rounded
+xrem468 remainder -5.32711606 -8447286.21 -> -5.32711606
+xsub468 subtract -5.32711606 -8447286.21 -> 8447280.88 Inexact Rounded
+xadd469 add -82272171.8 -776.238587E-372690416 -> -82272171.8 Inexact Rounded
+xcom469 compare -82272171.8 -776.238587E-372690416 -> -1
+xdiv469 divide -82272171.8 -776.238587E-372690416 -> 1.05988253E+372690421 Inexact Rounded
+xdvi469 divideint -82272171.8 -776.238587E-372690416 -> NaN Division_impossible
+xmul469 multiply -82272171.8 -776.238587E-372690416 -> 6.38628344E-372690406 Inexact Rounded
+xpow469 power -82272171.8 -8 -> 4.76404994E-64 Inexact Rounded
+xrem469 remainder -82272171.8 -776.238587E-372690416 -> NaN Division_impossible
+xsub469 subtract -82272171.8 -776.238587E-372690416 -> -82272171.8 Inexact Rounded
+xadd470 add 412411244.E-774339264 866452.465 -> 866452.465 Inexact Rounded
+xcom470 compare 412411244.E-774339264 866452.465 -> -1
+xdiv470 divide 412411244.E-774339264 866452.465 -> 4.75976768E-774339262 Inexact Rounded
+xdvi470 divideint 412411244.E-774339264 866452.465 -> 0
+xmul470 multiply 412411244.E-774339264 866452.465 -> 3.57334739E-774339250 Inexact Rounded
+xpow470 power 412411244.E-774339264 866452 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem470 remainder 412411244.E-774339264 866452.465 -> 4.12411244E-774339256
+xsub470 subtract 412411244.E-774339264 866452.465 -> -866452.465 Inexact Rounded
+xadd471 add -103.474598 -3.01660661E-446661257 -> -103.474598 Inexact Rounded
+xcom471 compare -103.474598 -3.01660661E-446661257 -> -1
+xdiv471 divide -103.474598 -3.01660661E-446661257 -> 3.43016546E+446661258 Inexact Rounded
+xdvi471 divideint -103.474598 -3.01660661E-446661257 -> NaN Division_impossible
+xmul471 multiply -103.474598 -3.01660661E-446661257 -> 3.12142156E-446661255 Inexact Rounded
+xpow471 power -103.474598 -3 -> -9.02607123E-7 Inexact Rounded
+xrem471 remainder -103.474598 -3.01660661E-446661257 -> NaN Division_impossible
+xsub471 subtract -103.474598 -3.01660661E-446661257 -> -103.474598 Inexact Rounded
+xadd472 add -31027.8323 -475378186. -> -475409214 Inexact Rounded
+xcom472 compare -31027.8323 -475378186. -> 1
+xdiv472 divide -31027.8323 -475378186. -> 0.0000652697856 Inexact Rounded
+xdvi472 divideint -31027.8323 -475378186. -> 0
+xmul472 multiply -31027.8323 -475378186. -> 1.47499546E+13 Inexact Rounded
+xpow472 power -31027.8323 -475378186 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem472 remainder -31027.8323 -475378186. -> -31027.8323
+xsub472 subtract -31027.8323 -475378186. -> 475347158 Inexact Rounded
+xadd473 add -1199339.72 -5.73068392E+53774632 -> -5.73068392E+53774632 Inexact Rounded
+xcom473 compare -1199339.72 -5.73068392E+53774632 -> 1
+xdiv473 divide -1199339.72 -5.73068392E+53774632 -> 2.09283872E-53774627 Inexact Rounded
+xdvi473 divideint -1199339.72 -5.73068392E+53774632 -> 0
+xmul473 multiply -1199339.72 -5.73068392E+53774632 -> 6.87303685E+53774638 Inexact Rounded
+xpow473 power -1199339.72 -6 -> 3.36005741E-37 Inexact Rounded
+xrem473 remainder -1199339.72 -5.73068392E+53774632 -> -1199339.72
+xsub473 subtract -1199339.72 -5.73068392E+53774632 -> 5.73068392E+53774632 Inexact Rounded
+xadd474 add -732908.930E+364345433 -3486146.26 -> -7.32908930E+364345438 Inexact Rounded
+xcom474 compare -732908.930E+364345433 -3486146.26 -> -1
+xdiv474 divide -732908.930E+364345433 -3486146.26 -> 2.10234705E+364345432 Inexact Rounded
+xdvi474 divideint -732908.930E+364345433 -3486146.26 -> NaN Division_impossible
+xmul474 multiply -732908.930E+364345433 -3486146.26 -> 2.55502773E+364345445 Inexact Rounded
+xpow474 power -732908.930E+364345433 -3486146 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem474 remainder -732908.930E+364345433 -3486146.26 -> NaN Division_impossible
+xsub474 subtract -732908.930E+364345433 -3486146.26 -> -7.32908930E+364345438 Inexact Rounded
+xadd475 add -2376150.83 -46777583.3 -> -49153734.1 Inexact Rounded
+xcom475 compare -2376150.83 -46777583.3 -> 1
+xdiv475 divide -2376150.83 -46777583.3 -> 0.0507967847 Inexact Rounded
+xdvi475 divideint -2376150.83 -46777583.3 -> 0
+xmul475 multiply -2376150.83 -46777583.3 -> 1.11150593E+14 Inexact Rounded
+xpow475 power -2376150.83 -46777583 -> -3.51886193E-298247976 Inexact Rounded
+xrem475 remainder -2376150.83 -46777583.3 -> -2376150.83
+xsub475 subtract -2376150.83 -46777583.3 -> 44401432.5 Inexact Rounded
+xadd476 add 6.3664211 -140854908. -> -140854902 Inexact Rounded
+xcom476 compare 6.3664211 -140854908. -> 1
+xdiv476 divide 6.3664211 -140854908. -> -4.51984328E-8 Inexact Rounded
+xdvi476 divideint 6.3664211 -140854908. -> -0
+xmul476 multiply 6.3664211 -140854908. -> -896741658 Inexact Rounded
+xpow476 power 6.3664211 -140854908 -> 7.25432803E-113232608 Inexact Rounded
+xrem476 remainder 6.3664211 -140854908. -> 6.3664211
+xsub476 subtract 6.3664211 -140854908. -> 140854914 Inexact Rounded
+xadd477 add -15.791522 1902.30210E+90741844 -> 1.90230210E+90741847 Inexact Rounded
+xcom477 compare -15.791522 1902.30210E+90741844 -> -1
+xdiv477 divide -15.791522 1902.30210E+90741844 -> -8.30126929E-90741847 Inexact Rounded
+xdvi477 divideint -15.791522 1902.30210E+90741844 -> -0
+xmul477 multiply -15.791522 1902.30210E+90741844 -> -3.00402455E+90741848 Inexact Rounded
+xpow477 power -15.791522 2 -> 249.372167 Inexact Rounded
+xrem477 remainder -15.791522 1902.30210E+90741844 -> -15.791522
+xsub477 subtract -15.791522 1902.30210E+90741844 -> -1.90230210E+90741847 Inexact Rounded
+xadd478 add 15356.1505E+373950429 2.88020400 -> 1.53561505E+373950433 Inexact Rounded
+xcom478 compare 15356.1505E+373950429 2.88020400 -> 1
+xdiv478 divide 15356.1505E+373950429 2.88020400 -> 5.33161905E+373950432 Inexact Rounded
+xdvi478 divideint 15356.1505E+373950429 2.88020400 -> NaN Division_impossible
+xmul478 multiply 15356.1505E+373950429 2.88020400 -> 4.42288461E+373950433 Inexact Rounded
+xpow478 power 15356.1505E+373950429 3 -> Infinity Overflow Inexact Rounded
+xrem478 remainder 15356.1505E+373950429 2.88020400 -> NaN Division_impossible
+xsub478 subtract 15356.1505E+373950429 2.88020400 -> 1.53561505E+373950433 Inexact Rounded
+xadd479 add -3.12001326E+318884762 9567.21595 -> -3.12001326E+318884762 Inexact Rounded
+xcom479 compare -3.12001326E+318884762 9567.21595 -> -1
+xdiv479 divide -3.12001326E+318884762 9567.21595 -> -3.26115066E+318884758 Inexact Rounded
+xdvi479 divideint -3.12001326E+318884762 9567.21595 -> NaN Division_impossible
+xmul479 multiply -3.12001326E+318884762 9567.21595 -> -2.98498406E+318884766 Inexact Rounded
+xpow479 power -3.12001326E+318884762 9567 -> -Infinity Overflow Inexact Rounded
+xrem479 remainder -3.12001326E+318884762 9567.21595 -> NaN Division_impossible
+xsub479 subtract -3.12001326E+318884762 9567.21595 -> -3.12001326E+318884762 Inexact Rounded
+xadd480 add 49436.6528 751.919517 -> 50188.5723 Inexact Rounded
+xcom480 compare 49436.6528 751.919517 -> 1
+xdiv480 divide 49436.6528 751.919517 -> 65.7472664 Inexact Rounded
+xdvi480 divideint 49436.6528 751.919517 -> 65
+xmul480 multiply 49436.6528 751.919517 -> 37172384.1 Inexact Rounded
+xpow480 power 49436.6528 752 -> 8.41185718E+3529 Inexact Rounded
+xrem480 remainder 49436.6528 751.919517 -> 561.884195
+xsub480 subtract 49436.6528 751.919517 -> 48684.7333 Inexact Rounded
+xadd481 add 552.669453 8.3725760E+16223526 -> 8.37257600E+16223526 Inexact Rounded
+xcom481 compare 552.669453 8.3725760E+16223526 -> -1
+xdiv481 divide 552.669453 8.3725760E+16223526 -> 6.60094878E-16223525 Inexact Rounded
+xdvi481 divideint 552.669453 8.3725760E+16223526 -> 0
+xmul481 multiply 552.669453 8.3725760E+16223526 -> 4.62726700E+16223529 Inexact Rounded
+xpow481 power 552.669453 8 -> 8.70409632E+21 Inexact Rounded
+xrem481 remainder 552.669453 8.3725760E+16223526 -> 552.669453
+xsub481 subtract 552.669453 8.3725760E+16223526 -> -8.37257600E+16223526 Inexact Rounded
+xadd482 add -3266303 453741.520 -> -2812561.48 Rounded
+xcom482 compare -3266303 453741.520 -> -1
+xdiv482 divide -3266303 453741.520 -> -7.19859844 Inexact Rounded
+xdvi482 divideint -3266303 453741.520 -> -7
+xmul482 multiply -3266303 453741.520 -> -1.48205729E+12 Inexact Rounded
+xpow482 power -3266303 453742 -> 1.02497315E+2955701 Inexact Rounded
+xrem482 remainder -3266303 453741.520 -> -90112.360
+xsub482 subtract -3266303 453741.520 -> -3720044.52 Rounded
+xadd483 add 12302757.4 542922.487E+414443353 -> 5.42922487E+414443358 Inexact Rounded
+xcom483 compare 12302757.4 542922.487E+414443353 -> -1
+xdiv483 divide 12302757.4 542922.487E+414443353 -> 2.26602465E-414443352 Inexact Rounded
+xdvi483 divideint 12302757.4 542922.487E+414443353 -> 0
+xmul483 multiply 12302757.4 542922.487E+414443353 -> 6.67944364E+414443365 Inexact Rounded
+xpow483 power 12302757.4 5 -> 2.81846276E+35 Inexact Rounded
+xrem483 remainder 12302757.4 542922.487E+414443353 -> 12302757.4
+xsub483 subtract 12302757.4 542922.487E+414443353 -> -5.42922487E+414443358 Inexact Rounded
+xadd484 add -5670757.79E-784754984 128144.503 -> 128144.503 Inexact Rounded
+xcom484 compare -5670757.79E-784754984 128144.503 -> -1
+xdiv484 divide -5670757.79E-784754984 128144.503 -> -4.42528369E-784754983 Inexact Rounded
+xdvi484 divideint -5670757.79E-784754984 128144.503 -> -0
+xmul484 multiply -5670757.79E-784754984 128144.503 -> -7.26676439E-784754973 Inexact Rounded
+xpow484 power -5670757.79E-784754984 128145 -> -0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem484 remainder -5670757.79E-784754984 128144.503 -> -5.67075779E-784754978
+xsub484 subtract -5670757.79E-784754984 128144.503 -> -128144.503 Inexact Rounded
+xadd485 add 22.7721968E+842530698 5223.70462 -> 2.27721968E+842530699 Inexact Rounded
+xcom485 compare 22.7721968E+842530698 5223.70462 -> 1
+xdiv485 divide 22.7721968E+842530698 5223.70462 -> 4.35939596E+842530695 Inexact Rounded
+xdvi485 divideint 22.7721968E+842530698 5223.70462 -> NaN Division_impossible
+xmul485 multiply 22.7721968E+842530698 5223.70462 -> 1.18955230E+842530703 Inexact Rounded
+xpow485 power 22.7721968E+842530698 5224 -> Infinity Overflow Inexact Rounded
+xrem485 remainder 22.7721968E+842530698 5223.70462 -> NaN Division_impossible
+xsub485 subtract 22.7721968E+842530698 5223.70462 -> 2.27721968E+842530699 Inexact Rounded
+xadd486 add 88.5158199E-980164357 325846116 -> 325846116 Inexact Rounded
+xcom486 compare 88.5158199E-980164357 325846116 -> -1
+xdiv486 divide 88.5158199E-980164357 325846116 -> 2.71649148E-980164364 Inexact Rounded
+xdvi486 divideint 88.5158199E-980164357 325846116 -> 0
+xmul486 multiply 88.5158199E-980164357 325846116 -> 2.88425361E-980164347 Inexact Rounded
+xpow486 power 88.5158199E-980164357 325846116 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem486 remainder 88.5158199E-980164357 325846116 -> 8.85158199E-980164356
+xsub486 subtract 88.5158199E-980164357 325846116 -> -325846116 Inexact Rounded
+xadd487 add -22881.0408 5.63661562 -> -22875.4042 Inexact Rounded
+xcom487 compare -22881.0408 5.63661562 -> -1
+xdiv487 divide -22881.0408 5.63661562 -> -4059.35802 Inexact Rounded
+xdvi487 divideint -22881.0408 5.63661562 -> -4059
+xmul487 multiply -22881.0408 5.63661562 -> -128971.632 Inexact Rounded
+xpow487 power -22881.0408 6 -> 1.43500909E+26 Inexact Rounded
+xrem487 remainder -22881.0408 5.63661562 -> -2.01799842
+xsub487 subtract -22881.0408 5.63661562 -> -22886.6774 Inexact Rounded
+xadd488 add -7157.57449 -76.4455519E-85647047 -> -7157.57449 Inexact Rounded
+xcom488 compare -7157.57449 -76.4455519E-85647047 -> -1
+xdiv488 divide -7157.57449 -76.4455519E-85647047 -> 9.36297052E+85647048 Inexact Rounded
+xdvi488 divideint -7157.57449 -76.4455519E-85647047 -> NaN Division_impossible
+xmul488 multiply -7157.57449 -76.4455519E-85647047 -> 5.47164732E-85647042 Inexact Rounded
+xpow488 power -7157.57449 -8 -> 1.45168700E-31 Inexact Rounded
+xrem488 remainder -7157.57449 -76.4455519E-85647047 -> NaN Division_impossible
+xsub488 subtract -7157.57449 -76.4455519E-85647047 -> -7157.57449 Inexact Rounded
+xadd489 add -503113.801 -9715149.82E-612184422 -> -503113.801 Inexact Rounded
+xcom489 compare -503113.801 -9715149.82E-612184422 -> -1
+xdiv489 divide -503113.801 -9715149.82E-612184422 -> 5.17865201E+612184420 Inexact Rounded
+xdvi489 divideint -503113.801 -9715149.82E-612184422 -> NaN Division_impossible
+xmul489 multiply -503113.801 -9715149.82E-612184422 -> 4.88782595E-612184410 Inexact Rounded
+xpow489 power -503113.801 -10 -> 9.62360287E-58 Inexact Rounded
+xrem489 remainder -503113.801 -9715149.82E-612184422 -> NaN Division_impossible
+xsub489 subtract -503113.801 -9715149.82E-612184422 -> -503113.801 Inexact Rounded
+xadd490 add -3066962.41 -55.3096879 -> -3067017.72 Inexact Rounded
+xcom490 compare -3066962.41 -55.3096879 -> -1
+xdiv490 divide -3066962.41 -55.3096879 -> 55450.7271 Inexact Rounded
+xdvi490 divideint -3066962.41 -55.3096879 -> 55450
+xmul490 multiply -3066962.41 -55.3096879 -> 169632734 Inexact Rounded
+xpow490 power -3066962.41 -55 -> -1.70229600E-357 Inexact Rounded
+xrem490 remainder -3066962.41 -55.3096879 -> -40.2159450
+xsub490 subtract -3066962.41 -55.3096879 -> -3066907.10 Inexact Rounded
+xadd491 add -53311.5738E+156608936 -7.45890666 -> -5.33115738E+156608940 Inexact Rounded
+xcom491 compare -53311.5738E+156608936 -7.45890666 -> -1
+xdiv491 divide -53311.5738E+156608936 -7.45890666 -> 7.14737109E+156608939 Inexact Rounded
+xdvi491 divideint -53311.5738E+156608936 -7.45890666 -> NaN Division_impossible
+xmul491 multiply -53311.5738E+156608936 -7.45890666 -> 3.97646053E+156608941 Inexact Rounded
+xpow491 power -53311.5738E+156608936 -7 -> -0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem491 remainder -53311.5738E+156608936 -7.45890666 -> NaN Division_impossible
+xsub491 subtract -53311.5738E+156608936 -7.45890666 -> -5.33115738E+156608940 Inexact Rounded
+xadd492 add 998890068. -92.057879 -> 998889976 Inexact Rounded
+xcom492 compare 998890068. -92.057879 -> 1
+xdiv492 divide 998890068. -92.057879 -> -10850674.4 Inexact Rounded
+xdvi492 divideint 998890068. -92.057879 -> -10850674
+xmul492 multiply 998890068. -92.057879 -> -9.19557010E+10 Inexact Rounded
+xpow492 power 998890068. -92 -> 1.10757225E-828 Inexact Rounded
+xrem492 remainder 998890068. -92.057879 -> 33.839554
+xsub492 subtract 998890068. -92.057879 -> 998890160 Inexact Rounded
+xadd493 add 122.495591 -407836028. -> -407835906 Inexact Rounded
+xcom493 compare 122.495591 -407836028. -> 1
+xdiv493 divide 122.495591 -407836028. -> -3.00355002E-7 Inexact Rounded
+xdvi493 divideint 122.495591 -407836028. -> -0
+xmul493 multiply 122.495591 -407836028. -> -4.99581153E+10 Inexact Rounded
+xpow493 power 122.495591 -407836028 -> 4.82463773E-851610754 Inexact Rounded
+xrem493 remainder 122.495591 -407836028. -> 122.495591
+xsub493 subtract 122.495591 -407836028. -> 407836150 Inexact Rounded
+xadd494 add 187098.488 6220.05584E-236541249 -> 187098.488 Inexact Rounded
+xcom494 compare 187098.488 6220.05584E-236541249 -> 1
+xdiv494 divide 187098.488 6220.05584E-236541249 -> 3.00798727E+236541250 Inexact Rounded
+xdvi494 divideint 187098.488 6220.05584E-236541249 -> NaN Division_impossible
+xmul494 multiply 187098.488 6220.05584E-236541249 -> 1.16376304E-236541240 Inexact Rounded
+xpow494 power 187098.488 6 -> 4.28964811E+31 Inexact Rounded
+xrem494 remainder 187098.488 6220.05584E-236541249 -> NaN Division_impossible
+xsub494 subtract 187098.488 6220.05584E-236541249 -> 187098.488 Inexact Rounded
+xadd495 add 4819899.21E+432982550 -727441917 -> 4.81989921E+432982556 Inexact Rounded
+xcom495 compare 4819899.21E+432982550 -727441917 -> 1
+xdiv495 divide 4819899.21E+432982550 -727441917 -> -6.62582001E+432982547 Inexact Rounded
+xdvi495 divideint 4819899.21E+432982550 -727441917 -> NaN Division_impossible
+xmul495 multiply 4819899.21E+432982550 -727441917 -> -3.50619672E+432982565 Inexact Rounded
+xpow495 power 4819899.21E+432982550 -727441917 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem495 remainder 4819899.21E+432982550 -727441917 -> NaN Division_impossible
+xsub495 subtract 4819899.21E+432982550 -727441917 -> 4.81989921E+432982556 Inexact Rounded
+xadd496 add 5770.01020E+507459752 -4208339.33E-129766680 -> 5.77001020E+507459755 Inexact Rounded
+xcom496 compare 5770.01020E+507459752 -4208339.33E-129766680 -> 1
+xdiv496 divide 5770.01020E+507459752 -4208339.33E-129766680 -> -1.37108958E+637226429 Inexact Rounded
+xdvi496 divideint 5770.01020E+507459752 -4208339.33E-129766680 -> NaN Division_impossible
+xmul496 multiply 5770.01020E+507459752 -4208339.33E-129766680 -> -2.42821609E+377693082 Inexact Rounded
+xpow496 power 5770.01020E+507459752 -4 -> 0E-1000000007 Underflow Subnormal Inexact Rounded Clamped
+xrem496 remainder 5770.01020E+507459752 -4208339.33E-129766680 -> NaN Division_impossible
+xsub496 subtract 5770.01020E+507459752 -4208339.33E-129766680 -> 5.77001020E+507459755 Inexact Rounded
+xadd497 add -286.371320 710319152 -> 710318866 Inexact Rounded
+xcom497 compare -286.371320 710319152 -> -1
+xdiv497 divide -286.371320 710319152 -> -4.03158664E-7 Inexact Rounded
+xdvi497 divideint -286.371320 710319152 -> -0
+xmul497 multiply -286.371320 710319152 -> -2.03415033E+11 Inexact Rounded
+xpow497 power -286.371320 710319152 -> Infinity Overflow Inexact Rounded
+xrem497 remainder -286.371320 710319152 -> -286.371320
+xsub497 subtract -286.371320 710319152 -> -710319438 Inexact Rounded
+xadd498 add -7.27403536 -481469656E-835183700 -> -7.27403536 Inexact Rounded
+xcom498 compare -7.27403536 -481469656E-835183700 -> -1
+xdiv498 divide -7.27403536 -481469656E-835183700 -> 1.51079830E+835183692 Inexact Rounded
+xdvi498 divideint -7.27403536 -481469656E-835183700 -> NaN Division_impossible
+xmul498 multiply -7.27403536 -481469656E-835183700 -> 3.50222730E-835183691 Inexact Rounded
+xpow498 power -7.27403536 -5 -> -0.0000491046885 Inexact Rounded
+xrem498 remainder -7.27403536 -481469656E-835183700 -> NaN Division_impossible
+xsub498 subtract -7.27403536 -481469656E-835183700 -> -7.27403536 Inexact Rounded
+xadd499 add -6157.74292 -94075286.2E+92555877 -> -9.40752862E+92555884 Inexact Rounded
+xcom499 compare -6157.74292 -94075286.2E+92555877 -> 1
+xdiv499 divide -6157.74292 -94075286.2E+92555877 -> 6.54554790E-92555882 Inexact Rounded
+xdvi499 divideint -6157.74292 -94075286.2E+92555877 -> 0
+xmul499 multiply -6157.74292 -94075286.2E+92555877 -> 5.79291428E+92555888 Inexact Rounded
+xpow499 power -6157.74292 -9 -> -7.85608218E-35 Inexact Rounded
+xrem499 remainder -6157.74292 -94075286.2E+92555877 -> -6157.74292
+xsub499 subtract -6157.74292 -94075286.2E+92555877 -> 9.40752862E+92555884 Inexact Rounded
+xadd500 add -525445087.E+231529167 188227460 -> -5.25445087E+231529175 Inexact Rounded
+xcom500 compare -525445087.E+231529167 188227460 -> -1
+xdiv500 divide -525445087.E+231529167 188227460 -> -2.79154321E+231529167 Inexact Rounded
+xdvi500 divideint -525445087.E+231529167 188227460 -> NaN Division_impossible
+xmul500 multiply -525445087.E+231529167 188227460 -> -9.89031941E+231529183 Inexact Rounded
+xpow500 power -525445087.E+231529167 188227460 -> Infinity Overflow Inexact Rounded
+xrem500 remainder -525445087.E+231529167 188227460 -> NaN Division_impossible
+xsub500 subtract -525445087.E+231529167 188227460 -> -5.25445087E+231529175 Inexact Rounded

Added: vendor/Python/current/Lib/test/decimaltestdata/remainder.decTest
===================================================================
--- vendor/Python/current/Lib/test/decimaltestdata/remainder.decTest	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/decimaltestdata/remainder.decTest	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,629 @@
+------------------------------------------------------------------------
+-- remainder.decTest -- decimal remainder                             --
+-- Copyright (c) IBM Corporation, 1981, 2004.  All rights reserved.   --
+------------------------------------------------------------------------
+-- Please see the document "General Decimal Arithmetic Testcases"     --
+-- at http://www2.hursley.ibm.com/decimal for the description of      --
+-- these testcases.                                                   --
+--                                                                    --
+-- These testcases are experimental ('beta' versions), and they       --
+-- may contain errors.  They are offered on an as-is basis.  In       --
+-- particular, achieving the same results as the tests here is not    --
+-- a guarantee that an implementation complies with any Standard      --
+-- or specification.  The tests are not exhaustive.                   --
+--                                                                    --
+-- Please send comments, suggestions, and corrections to the author:  --
+--   Mike Cowlishaw, IBM Fellow                                       --
+--   IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK         --
+--   mfc at uk.ibm.com                                                   --
+------------------------------------------------------------------------
+version: 2.39
+
+extended:    1
+precision:   9
+rounding:    half_up
+maxExponent: 384
+minexponent: -383
+
+-- sanity checks (as base, above)
+remx001 remainder  1     1    ->  0
+remx002 remainder  2     1    ->  0
+remx003 remainder  1     2    ->  1
+remx004 remainder  2     2    ->  0
+remx005 remainder  0     1    ->  0
+remx006 remainder  0     2    ->  0
+remx007 remainder  1     3    ->  1
+remx008 remainder  2     3    ->  2
+remx009 remainder  3     3    ->  0
+
+remx010 remainder  2.4   1    ->  0.4
+remx011 remainder  2.4   -1   ->  0.4
+remx012 remainder  -2.4  1    ->  -0.4
+remx013 remainder  -2.4  -1   ->  -0.4
+remx014 remainder  2.40  1    ->  0.40
+remx015 remainder  2.400 1    ->  0.400
+remx016 remainder  2.4   2    ->  0.4
+remx017 remainder  2.400 2    ->  0.400
+remx018 remainder  2.    2    ->  0
+remx019 remainder  20    20   ->  0
+
+remx020 remainder  187   187    ->  0
+remx021 remainder  5     2      ->  1
+remx022 remainder  5     2.0    ->  1.0
+remx023 remainder  5     2.000  ->  1.000
+remx024 remainder  5     0.200  ->  0.000
+remx025 remainder  5     0.200  ->  0.000
+
+remx030 remainder  1     2      ->  1
+remx031 remainder  1     4      ->  1
+remx032 remainder  1     8      ->  1
+
+remx033 remainder  1     16     ->  1
+remx034 remainder  1     32     ->  1
+remx035 remainder  1     64     ->  1
+remx040 remainder  1    -2      ->  1
+remx041 remainder  1    -4      ->  1
+remx042 remainder  1    -8      ->  1
+remx043 remainder  1    -16     ->  1
+remx044 remainder  1    -32     ->  1
+remx045 remainder  1    -64     ->  1
+remx050 remainder -1     2      ->  -1
+remx051 remainder -1     4      ->  -1
+remx052 remainder -1     8      ->  -1
+remx053 remainder -1     16     ->  -1
+remx054 remainder -1     32     ->  -1
+remx055 remainder -1     64     ->  -1
+remx060 remainder -1    -2      ->  -1
+remx061 remainder -1    -4      ->  -1
+remx062 remainder -1    -8      ->  -1
+remx063 remainder -1    -16     ->  -1
+remx064 remainder -1    -32     ->  -1
+remx065 remainder -1    -64     ->  -1
+
+remx066 remainder  999999999     1  -> 0
+remx067 remainder  999999999.4   1  -> 0.4
+remx068 remainder  999999999.5   1  -> 0.5
+remx069 remainder  999999999.9   1  -> 0.9
+remx070 remainder  999999999.999 1  -> 0.999
+precision: 6
+remx071 remainder  999999999     1  -> NaN Division_impossible
+remx072 remainder  99999999      1  -> NaN Division_impossible
+remx073 remainder  9999999       1  -> NaN Division_impossible
+remx074 remainder  999999        1  -> 0
+remx075 remainder  99999         1  -> 0
+remx076 remainder  9999          1  -> 0
+remx077 remainder  999           1  -> 0
+remx078 remainder  99            1  -> 0
+remx079 remainder  9             1  -> 0
+
+precision: 9
+remx080 remainder  0.            1  -> 0
+remx081 remainder  .0            1  -> 0.0
+remx082 remainder  0.00          1  -> 0.00
+remx083 remainder  0.00E+9       1  -> 0
+remx084 remainder  0.00E+3       1  -> 0
+remx085 remainder  0.00E+2       1  -> 0
+remx086 remainder  0.00E+1       1  -> 0.0
+remx087 remainder  0.00E+0       1  -> 0.00
+remx088 remainder  0.00E-0       1  -> 0.00
+remx089 remainder  0.00E-1       1  -> 0.000
+remx090 remainder  0.00E-2       1  -> 0.0000
+remx091 remainder  0.00E-3       1  -> 0.00000
+remx092 remainder  0.00E-4       1  -> 0.000000
+remx093 remainder  0.00E-5       1  -> 0E-7
+remx094 remainder  0.00E-6       1  -> 0E-8
+remx095 remainder  0.0000E-50    1  -> 0E-54
+
+-- Various flavours of remainder by 0
+precision: 9
+maxexponent: 999999999
+minexponent: -999999999
+remx101 remainder  0       0   -> NaN Division_undefined
+remx102 remainder  0      -0   -> NaN Division_undefined
+remx103 remainder -0       0   -> NaN Division_undefined
+remx104 remainder -0      -0   -> NaN Division_undefined
+remx105 remainder  0.0E5   0   -> NaN Division_undefined
+remx106 remainder  0.000   0   -> NaN Division_undefined
+-- [Some think this next group should be Division_by_zero exception, but
+-- IEEE 854 is explicit that it is Invalid operation .. for
+-- remainder-near, anyway]
+remx107 remainder  0.0001  0   -> NaN Invalid_operation
+remx108 remainder  0.01    0   -> NaN Invalid_operation
+remx109 remainder  0.1     0   -> NaN Invalid_operation
+remx110 remainder  1       0   -> NaN Invalid_operation
+remx111 remainder  1       0.0 -> NaN Invalid_operation
+remx112 remainder 10       0.0 -> NaN Invalid_operation
+remx113 remainder 1E+100   0.0 -> NaN Invalid_operation
+remx114 remainder 1E+1000  0   -> NaN Invalid_operation
+remx115 remainder  0.0001 -0   -> NaN Invalid_operation
+remx116 remainder  0.01   -0   -> NaN Invalid_operation
+remx119 remainder  0.1    -0   -> NaN Invalid_operation
+remx120 remainder  1      -0   -> NaN Invalid_operation
+remx121 remainder  1      -0.0 -> NaN Invalid_operation
+remx122 remainder 10      -0.0 -> NaN Invalid_operation
+remx123 remainder 1E+100  -0.0 -> NaN Invalid_operation
+remx124 remainder 1E+1000 -0   -> NaN Invalid_operation
+-- and zeros on left
+remx130 remainder  0      1   ->  0
+remx131 remainder  0     -1   ->  0
+remx132 remainder  0.0    1   ->  0.0
+remx133 remainder  0.0   -1   ->  0.0
+remx134 remainder -0      1   -> -0
+remx135 remainder -0     -1   -> -0
+remx136 remainder -0.0    1   -> -0.0
+remx137 remainder -0.0   -1   -> -0.0
+
+-- 0.5ers
+remx143 remainder   0.5  2     ->  0.5
+remx144 remainder   0.5  2.1   ->  0.5
+remx145 remainder   0.5  2.01  ->  0.50
+remx146 remainder   0.5  2.001 ->  0.500
+remx147 remainder   0.50 2     ->  0.50
+remx148 remainder   0.50 2.01  ->  0.50
+remx149 remainder   0.50 2.001 ->  0.500
+
+-- steadies
+remx150 remainder  1  1   -> 0
+remx151 remainder  1  2   -> 1
+remx152 remainder  1  3   -> 1
+remx153 remainder  1  4   -> 1
+remx154 remainder  1  5   -> 1
+remx155 remainder  1  6   -> 1
+remx156 remainder  1  7   -> 1
+remx157 remainder  1  8   -> 1
+remx158 remainder  1  9   -> 1
+remx159 remainder  1  10  -> 1
+remx160 remainder  1  1   -> 0
+remx161 remainder  2  1   -> 0
+remx162 remainder  3  1   -> 0
+remx163 remainder  4  1   -> 0
+remx164 remainder  5  1   -> 0
+remx165 remainder  6  1   -> 0
+remx166 remainder  7  1   -> 0
+remx167 remainder  8  1   -> 0
+remx168 remainder  9  1   -> 0
+remx169 remainder  10 1   -> 0
+
+-- some differences from remainderNear
+remx171 remainder   0.4  1.020 ->  0.400
+remx172 remainder   0.50 1.020 ->  0.500
+remx173 remainder   0.51 1.020 ->  0.510
+remx174 remainder   0.52 1.020 ->  0.520
+remx175 remainder   0.6  1.020 ->  0.600
+
+
+-- More flavours of remainder by 0
+maxexponent: 999999999
+minexponent: -999999999
+remx201 remainder  0      0   -> NaN Division_undefined
+remx202 remainder  0.0E5  0   -> NaN Division_undefined
+remx203 remainder  0.000  0   -> NaN Division_undefined
+remx204 remainder  0.0001 0   -> NaN Invalid_operation
+remx205 remainder  0.01   0   -> NaN Invalid_operation
+remx206 remainder  0.1    0   -> NaN Invalid_operation
+remx207 remainder  1      0   -> NaN Invalid_operation
+remx208 remainder  1      0.0 -> NaN Invalid_operation
+remx209 remainder 10      0.0 -> NaN Invalid_operation
+remx210 remainder 1E+100  0.0 -> NaN Invalid_operation
+remx211 remainder 1E+1000 0   -> NaN Invalid_operation
+
+-- some differences from remainderNear
+remx231 remainder  -0.4  1.020 -> -0.400
+remx232 remainder  -0.50 1.020 -> -0.500
+remx233 remainder  -0.51 1.020 -> -0.510
+remx234 remainder  -0.52 1.020 -> -0.520
+remx235 remainder  -0.6  1.020 -> -0.600
+
+-- high Xs
+remx240 remainder  1E+2  1.00  ->  0.00
+
+
+-- test some cases that are close to exponent overflow
+maxexponent: 999999999
+minexponent: -999999999
+remx270 remainder 1 1e999999999    -> 1
+remx271 remainder 1 0.9e999999999  -> 1
+remx272 remainder 1 0.99e999999999 -> 1
+remx273 remainder 1 0.999999999e999999999 -> 1
+remx274 remainder 9e999999999          1 -> NaN Division_impossible
+remx275 remainder 9.9e999999999        1 -> NaN Division_impossible
+remx276 remainder 9.99e999999999       1 -> NaN Division_impossible
+remx277 remainder 9.99999999e999999999 1 -> NaN Division_impossible
+
+remx280 remainder 0.1 9e-999999999       -> NaN Division_impossible
+remx281 remainder 0.1 99e-999999999      -> NaN Division_impossible
+remx282 remainder 0.1 999e-999999999     -> NaN Division_impossible
+
+remx283 remainder 0.1 9e-999999998       -> NaN Division_impossible
+remx284 remainder 0.1 99e-999999998      -> NaN Division_impossible
+remx285 remainder 0.1 999e-999999998     -> NaN Division_impossible
+remx286 remainder 0.1 999e-999999997     -> NaN Division_impossible
+remx287 remainder 0.1 9999e-999999997    -> NaN Division_impossible
+remx288 remainder 0.1 99999e-999999997   -> NaN Division_impossible
+
+-- remx3xx are from DiagBigDecimal
+remx301 remainder   1    3     ->  1
+remx302 remainder   5    5     ->  0
+remx303 remainder   13   10    ->  3
+remx304 remainder   13   50    ->  13
+remx305 remainder   13   100   ->  13
+remx306 remainder   13   1000  ->  13
+remx307 remainder   .13    1   ->  0.13
+remx308 remainder   0.133  1   ->  0.133
+remx309 remainder   0.1033 1   ->  0.1033
+remx310 remainder   1.033  1   ->  0.033
+remx311 remainder   10.33  1   ->  0.33
+remx312 remainder   10.33 10   ->  0.33
+remx313 remainder   103.3  1   ->  0.3
+remx314 remainder   133   10   ->  3
+remx315 remainder   1033  10   ->  3
+remx316 remainder   1033  50   ->  33
+remx317 remainder   101.0  3   ->  2.0
+remx318 remainder   102.0  3   ->  0.0
+remx319 remainder   103.0  3   ->  1.0
+remx320 remainder   2.40   1   ->  0.40
+remx321 remainder   2.400  1   ->  0.400
+remx322 remainder   2.4    1   ->  0.4
+remx323 remainder   2.4    2   ->  0.4
+remx324 remainder   2.400  2   ->  0.400
+remx325 remainder   1   0.3    ->  0.1
+remx326 remainder   1   0.30   ->  0.10
+remx327 remainder   1   0.300  ->  0.100
+remx328 remainder   1   0.3000 ->  0.1000
+remx329 remainder   1.0    0.3 ->  0.1
+remx330 remainder   1.00   0.3 ->  0.10
+remx331 remainder   1.000  0.3 ->  0.100
+remx332 remainder   1.0000 0.3 ->  0.1000
+remx333 remainder   0.5  2     ->  0.5
+remx334 remainder   0.5  2.1   ->  0.5
+remx335 remainder   0.5  2.01  ->  0.50
+remx336 remainder   0.5  2.001 ->  0.500
+remx337 remainder   0.50 2     ->  0.50
+remx338 remainder   0.50 2.01  ->  0.50
+remx339 remainder   0.50 2.001 ->  0.500
+
+remx340 remainder   0.5   0.5000001    ->  0.5000000
+remx341 remainder   0.5   0.50000001    ->  0.50000000
+remx342 remainder   0.5   0.500000001    ->  0.500000000
+remx343 remainder   0.5   0.5000000001    ->  0.500000000  Rounded
+remx344 remainder   0.5   0.50000000001    ->  0.500000000  Rounded
+remx345 remainder   0.5   0.4999999    ->  1E-7
+remx346 remainder   0.5   0.49999999    ->  1E-8
+remx347 remainder   0.5   0.499999999    ->  1E-9
+remx348 remainder   0.5   0.4999999999    ->  1E-10
+remx349 remainder   0.5   0.49999999999    ->  1E-11
+remx350 remainder   0.5   0.499999999999    ->  1E-12
+
+remx351 remainder   0.03  7  ->  0.03
+remx352 remainder   5   2    ->  1
+remx353 remainder   4.1   2    ->  0.1
+remx354 remainder   4.01   2    ->  0.01
+remx355 remainder   4.001   2    ->  0.001
+remx356 remainder   4.0001   2    ->  0.0001
+remx357 remainder   4.00001   2    ->  0.00001
+remx358 remainder   4.000001   2    ->  0.000001
+remx359 remainder   4.0000001   2    ->  1E-7
+
+remx360 remainder   1.2   0.7345 ->  0.4655
+remx361 remainder   0.8   12     ->  0.8
+remx362 remainder   0.8   0.2    ->  0.0
+remx363 remainder   0.8   0.3    ->  0.2
+remx364 remainder   0.800   12   ->  0.800
+remx365 remainder   0.800   1.7  ->  0.800
+remx366 remainder   2.400   2    ->  0.400
+
+precision: 6
+remx371 remainder   2.400  2        ->  0.400
+precision: 3
+-- long operand, rounded, case
+remx372 remainder   12345678900000 12e+12 -> 3.46E+11 Inexact Rounded
+--                  12000000000000
+
+precision: 5
+remx381 remainder 12345  1         ->  0
+remx382 remainder 12345  1.0001    ->  0.7657
+remx383 remainder 12345  1.001     ->  0.668
+remx384 remainder 12345  1.01      ->  0.78
+remx385 remainder 12345  1.1       ->  0.8
+remx386 remainder 12355  4         ->  3
+remx387 remainder 12345  4         ->  1
+remx388 remainder 12355  4.0001    ->  2.6912
+remx389 remainder 12345  4.0001    ->  0.6914
+remx390 remainder 12345  4.9       ->  1.9
+remx391 remainder 12345  4.99      ->  4.73
+remx392 remainder 12345  4.999     ->  2.469
+remx393 remainder 12345  4.9999    ->  0.2469
+remx394 remainder 12345  5         ->  0
+remx395 remainder 12345  5.0001    ->  4.7532
+remx396 remainder 12345  5.001     ->  2.532
+remx397 remainder 12345  5.01      ->  0.36
+remx398 remainder 12345  5.1       ->  3.0
+
+precision: 9
+-- the nasty division-by-1 cases
+remx401 remainder   0.5         1   ->  0.5
+remx402 remainder   0.55        1   ->  0.55
+remx403 remainder   0.555       1   ->  0.555
+remx404 remainder   0.5555      1   ->  0.5555
+remx405 remainder   0.55555     1   ->  0.55555
+remx406 remainder   0.555555    1   ->  0.555555
+remx407 remainder   0.5555555   1   ->  0.5555555
+remx408 remainder   0.55555555  1   ->  0.55555555
+remx409 remainder   0.555555555 1   ->  0.555555555
+
+
+-- Specials
+remx680 remainder  Inf  -Inf   ->  NaN Invalid_operation
+remx681 remainder  Inf  -1000  ->  NaN Invalid_operation
+remx682 remainder  Inf  -1     ->  NaN Invalid_operation
+remx683 remainder  Inf   0     ->  NaN Invalid_operation
+remx684 remainder  Inf  -0     ->  NaN Invalid_operation
+remx685 remainder  Inf   1     ->  NaN Invalid_operation
+remx686 remainder  Inf   1000  ->  NaN Invalid_operation
+remx687 remainder  Inf   Inf   ->  NaN Invalid_operation
+remx688 remainder -1000  Inf   -> -1000
+remx689 remainder -Inf   Inf   ->  NaN Invalid_operation
+remx691 remainder -1     Inf   -> -1
+remx692 remainder  0     Inf   ->  0
+remx693 remainder -0     Inf   -> -0
+remx694 remainder  1     Inf   ->  1
+remx695 remainder  1000  Inf   ->  1000
+remx696 remainder  Inf   Inf   ->  NaN Invalid_operation
+
+remx700 remainder -Inf  -Inf   ->  NaN Invalid_operation
+remx701 remainder -Inf  -1000  ->  NaN Invalid_operation
+remx702 remainder -Inf  -1     ->  NaN Invalid_operation
+remx703 remainder -Inf  -0     ->  NaN Invalid_operation
+remx704 remainder -Inf   0     ->  NaN Invalid_operation
+remx705 remainder -Inf   1     ->  NaN Invalid_operation
+remx706 remainder -Inf   1000  ->  NaN Invalid_operation
+remx707 remainder -Inf   Inf   ->  NaN Invalid_operation
+remx708 remainder -Inf  -Inf   ->  NaN Invalid_operation
+remx709 remainder -1000  Inf   -> -1000
+remx710 remainder -1    -Inf   -> -1
+remx711 remainder -0    -Inf   -> -0
+remx712 remainder  0    -Inf   ->  0
+remx713 remainder  1    -Inf   ->  1
+remx714 remainder  1000 -Inf   ->  1000
+remx715 remainder  Inf  -Inf   ->  NaN Invalid_operation
+
+remx721 remainder  NaN -Inf    ->  NaN
+remx722 remainder  NaN -1000   ->  NaN
+remx723 remainder  NaN -1      ->  NaN
+remx724 remainder  NaN -0      ->  NaN
+remx725 remainder -NaN  0      -> -NaN
+remx726 remainder  NaN  1      ->  NaN
+remx727 remainder  NaN  1000   ->  NaN
+remx728 remainder  NaN  Inf    ->  NaN
+remx729 remainder  NaN -NaN    ->  NaN
+remx730 remainder -Inf  NaN    ->  NaN
+remx731 remainder -1000 NaN    ->  NaN
+remx732 remainder -1    NaN    ->  NaN
+remx733 remainder -0   -NaN    -> -NaN
+remx734 remainder  0    NaN    ->  NaN
+remx735 remainder  1   -NaN    -> -NaN
+remx736 remainder  1000 NaN    ->  NaN
+remx737 remainder  Inf  NaN    ->  NaN
+
+remx741 remainder  sNaN -Inf   ->  NaN  Invalid_operation
+remx742 remainder  sNaN -1000  ->  NaN  Invalid_operation
+remx743 remainder -sNaN -1     -> -NaN  Invalid_operation
+remx744 remainder  sNaN -0     ->  NaN  Invalid_operation
+remx745 remainder  sNaN  0     ->  NaN  Invalid_operation
+remx746 remainder  sNaN  1     ->  NaN  Invalid_operation
+remx747 remainder  sNaN  1000  ->  NaN  Invalid_operation
+remx749 remainder  sNaN  NaN   ->  NaN  Invalid_operation
+remx750 remainder  sNaN sNaN   ->  NaN  Invalid_operation
+remx751 remainder  NaN  sNaN   ->  NaN  Invalid_operation
+remx752 remainder -Inf  sNaN   ->  NaN  Invalid_operation
+remx753 remainder -1000 sNaN   ->  NaN  Invalid_operation
+remx754 remainder -1    sNaN   ->  NaN  Invalid_operation
+remx755 remainder -0    sNaN   ->  NaN  Invalid_operation
+remx756 remainder  0    sNaN   ->  NaN  Invalid_operation
+remx757 remainder  1    sNaN   ->  NaN  Invalid_operation
+remx758 remainder  1000 sNaN   ->  NaN  Invalid_operation
+remx759 remainder  Inf -sNaN   -> -NaN  Invalid_operation
+
+-- propaging NaNs
+remx760 remainder  NaN1   NaN7   ->  NaN1
+remx761 remainder sNaN2   NaN8   ->  NaN2 Invalid_operation
+remx762 remainder  NaN3  sNaN9   ->  NaN9 Invalid_operation
+remx763 remainder sNaN4  sNaN10  ->  NaN4 Invalid_operation
+remx764 remainder    15   NaN11  ->  NaN11
+remx765 remainder  NaN6   NaN12  ->  NaN6
+remx766 remainder  Inf    NaN13  ->  NaN13
+remx767 remainder  NaN14  -Inf   ->  NaN14
+remx768 remainder    0    NaN15  ->  NaN15
+remx769 remainder  NaN16   -0    ->  NaN16
+
+-- test some cases that are close to exponent overflow
+maxexponent: 999999999
+minexponent: -999999999
+remx770 remainder 1 1e999999999    -> 1
+remx771 remainder 1 0.9e999999999  -> 1
+remx772 remainder 1 0.99e999999999 -> 1
+remx773 remainder 1 0.999999999e999999999 -> 1
+remx774 remainder 9e999999999          1 -> NaN Division_impossible
+remx775 remainder 9.9e999999999        1 -> NaN Division_impossible
+remx776 remainder 9.99e999999999       1 -> NaN Division_impossible
+remx777 remainder 9.99999999e999999999 1 -> NaN Division_impossible
+
+-- long operand checks
+maxexponent: 999
+minexponent: -999
+precision: 9
+remx801 remainder 12345678000 100 -> 0
+remx802 remainder 1 12345678000   -> 1
+remx803 remainder 1234567800  10  -> 0
+remx804 remainder 1 1234567800    -> 1
+remx805 remainder 1234567890  10  -> 0
+remx806 remainder 1 1234567890    -> 1
+remx807 remainder 1234567891  10  -> 1
+remx808 remainder 1 1234567891    -> 1
+remx809 remainder 12345678901 100 -> 1
+remx810 remainder 1 12345678901   -> 1
+remx811 remainder 1234567896  10  -> 6
+remx812 remainder 1 1234567896    -> 1
+
+precision: 15
+remx821 remainder 12345678000 100 -> 0
+remx822 remainder 1 12345678000   -> 1
+remx823 remainder 1234567800  10  -> 0
+remx824 remainder 1 1234567800    -> 1
+remx825 remainder 1234567890  10  -> 0
+remx826 remainder 1 1234567890    -> 1
+remx827 remainder 1234567891  10  -> 1
+remx828 remainder 1 1234567891    -> 1
+remx829 remainder 12345678901 100 -> 1
+remx830 remainder 1 12345678901   -> 1
+remx831 remainder 1234567896  10  -> 6
+remx832 remainder 1 1234567896    -> 1
+
+-- worries from divideint
+precision: 8
+remx840 remainder  100000000.0   1  ->  NaN Division_impossible
+remx841 remainder  100000000.4   1  ->  NaN Division_impossible
+remx842 remainder  100000000.5   1  ->  NaN Division_impossible
+remx843 remainder  100000000.9   1  ->  NaN Division_impossible
+remx844 remainder  100000000.999 1  ->  NaN Division_impossible
+precision: 6
+remx850 remainder  100000003     5  ->  NaN Division_impossible
+remx851 remainder  10000003      5  ->  NaN Division_impossible
+remx852 remainder  1000003       5  ->  3
+remx853 remainder  100003        5  ->  3
+remx854 remainder  10003         5  ->  3
+remx855 remainder  1003          5  ->  3
+remx856 remainder  103           5  ->  3
+remx857 remainder  13            5  ->  3
+remx858 remainder  1             5  ->  1
+
+-- Vladimir's cases
+remx860 remainder 123.0e1 10000000000000000 -> 1230
+remx861 remainder 1230    10000000000000000 -> 1230
+remx862 remainder 12.3e2  10000000000000000 -> 1230
+remx863 remainder 1.23e3  10000000000000000 -> 1230
+remx864 remainder 123e1   10000000000000000 -> 1230
+remx870 remainder 123e1    1000000000000000 -> 1230
+remx871 remainder 123e1     100000000000000 -> 1230
+remx872 remainder 123e1      10000000000000 -> 1230
+remx873 remainder 123e1       1000000000000 -> 1230
+remx874 remainder 123e1        100000000000 -> 1230
+remx875 remainder 123e1         10000000000 -> 1230
+remx876 remainder 123e1          1000000000 -> 1230
+remx877 remainder 123e1           100000000 -> 1230
+remx878 remainder 1230            100000000 -> 1230
+remx879 remainder 123e1            10000000 -> 1230
+remx880 remainder 123e1             1000000 -> 1230
+remx881 remainder 123e1              100000 -> 1230
+remx882 remainder 123e1               10000 -> 1230
+remx883 remainder 123e1                1000 ->  230
+remx884 remainder 123e1                 100 ->   30
+remx885 remainder 123e1                  10 ->    0
+remx886 remainder 123e1                   1 ->    0
+
+remx889 remainder 123e1   20000000000000000 -> 1230
+remx890 remainder 123e1    2000000000000000 -> 1230
+remx891 remainder 123e1     200000000000000 -> 1230
+remx892 remainder 123e1      20000000000000 -> 1230
+remx893 remainder 123e1       2000000000000 -> 1230
+remx894 remainder 123e1        200000000000 -> 1230
+remx895 remainder 123e1         20000000000 -> 1230
+remx896 remainder 123e1          2000000000 -> 1230
+remx897 remainder 123e1           200000000 -> 1230
+remx899 remainder 123e1            20000000 -> 1230
+remx900 remainder 123e1             2000000 -> 1230
+remx901 remainder 123e1              200000 -> 1230
+remx902 remainder 123e1               20000 -> 1230
+remx903 remainder 123e1                2000 -> 1230
+remx904 remainder 123e1                 200 ->   30
+remx905 remainder 123e1                  20 ->   10
+remx906 remainder 123e1                   2 ->    0
+
+remx909 remainder 123e1   50000000000000000 -> 1230
+remx910 remainder 123e1    5000000000000000 -> 1230
+remx911 remainder 123e1     500000000000000 -> 1230
+remx912 remainder 123e1      50000000000000 -> 1230
+remx913 remainder 123e1       5000000000000 -> 1230
+remx914 remainder 123e1        500000000000 -> 1230
+remx915 remainder 123e1         50000000000 -> 1230
+remx916 remainder 123e1          5000000000 -> 1230
+remx917 remainder 123e1           500000000 -> 1230
+remx919 remainder 123e1            50000000 -> 1230
+remx920 remainder 123e1             5000000 -> 1230
+remx921 remainder 123e1              500000 -> 1230
+remx922 remainder 123e1               50000 -> 1230
+remx923 remainder 123e1                5000 -> 1230
+remx924 remainder 123e1                 500 ->  230
+remx925 remainder 123e1                  50 ->   30
+remx926 remainder 123e1                   5 ->    0
+
+remx929 remainder 123e1   90000000000000000 -> 1230
+remx930 remainder 123e1    9000000000000000 -> 1230
+remx931 remainder 123e1     900000000000000 -> 1230
+remx932 remainder 123e1      90000000000000 -> 1230
+remx933 remainder 123e1       9000000000000 -> 1230
+remx934 remainder 123e1        900000000000 -> 1230
+remx935 remainder 123e1         90000000000 -> 1230
+remx936 remainder 123e1          9000000000 -> 1230
+remx937 remainder 123e1           900000000 -> 1230
+remx939 remainder 123e1            90000000 -> 1230
+remx940 remainder 123e1             9000000 -> 1230
+remx941 remainder 123e1              900000 -> 1230
+remx942 remainder 123e1               90000 -> 1230
+remx943 remainder 123e1                9000 -> 1230
+remx944 remainder 123e1                 900 ->  330
+remx945 remainder 123e1                  90 ->   60
+remx946 remainder 123e1                   9 ->    6
+
+remx950 remainder 123e1   10000000000000000 -> 1230
+remx951 remainder 123e1   100000000000000000 -> 1230
+remx952 remainder 123e1   1000000000000000000 -> 1230
+remx953 remainder 123e1   10000000000000000000 -> 1230
+remx954 remainder 123e1   100000000000000000000 -> 1230
+remx955 remainder 123e1   1000000000000000000000 -> 1230
+remx956 remainder 123e1   10000000000000000000000 -> 1230
+remx957 remainder 123e1   100000000000000000000000 -> 1230
+remx958 remainder 123e1   1000000000000000000000000 -> 1230
+remx959 remainder 123e1   10000000000000000000000000 -> 1230
+
+remx960 remainder 123e1   19999999999999999 -> 1230
+remx961 remainder 123e1   199999999999999990 -> 1230
+remx962 remainder 123e1   1999999999999999999 -> 1230
+remx963 remainder 123e1   19999999999999999990 -> 1230
+remx964 remainder 123e1   199999999999999999999 -> 1230
+remx965 remainder 123e1   1999999999999999999990 -> 1230
+remx966 remainder 123e1   19999999999999999999999 -> 1230
+remx967 remainder 123e1   199999999999999999999990 -> 1230
+remx968 remainder 123e1   1999999999999999999999999 -> 1230
+remx969 remainder 123e1   19999999999999999999999990 -> 1230
+
+remx970 remainder 1e1   10000000000000000 -> 10
+remx971 remainder 1e1   100000000000000000 -> 10
+remx972 remainder 1e1   1000000000000000000 -> 10
+remx973 remainder 1e1   10000000000000000000 -> 10
+remx974 remainder 1e1   100000000000000000000 -> 10
+remx975 remainder 1e1   1000000000000000000000 -> 10
+remx976 remainder 1e1   10000000000000000000000 -> 10
+remx977 remainder 1e1   100000000000000000000000 -> 10
+remx978 remainder 1e1   1000000000000000000000000 -> 10
+remx979 remainder 1e1   10000000000000000000000000 -> 10
+
+remx980 remainder 123e1 1000E999999 -> 1.23E+3  -- 123E+1 internally
+
+-- overflow and underflow tests [from divide]
+precision: 9
+maxexponent: 999999999
+minexponent: -999999999
+remx990 remainder +1.23456789012345E-0 9E+999999999 -> 1.23456789 Inexact Rounded
+remx991 remainder 9E+999999999 +0.23456789012345E-0 -> NaN Division_impossible
+remx992 remainder +0.100 9E+999999999               -> 0.100
+remx993 remainder 9E-999999999 +9.100               -> 9E-999999999
+remx995 remainder -1.23456789012345E-0 9E+999999999 -> -1.23456789 Inexact Rounded
+remx996 remainder 9E+999999999 -0.83456789012345E-0 -> NaN Division_impossible
+remx997 remainder -0.100 9E+999999999               -> -0.100
+remx998 remainder 9E-999999999 -9.100               -> 9E-999999999
+
+-- Null tests
+remx1000 remainder 10  # -> NaN Invalid_operation
+remx1001 remainder  # 10 -> NaN Invalid_operation
+

Added: vendor/Python/current/Lib/test/decimaltestdata/remainderNear.decTest
===================================================================
--- vendor/Python/current/Lib/test/decimaltestdata/remainderNear.decTest	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/decimaltestdata/remainderNear.decTest	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,560 @@
+------------------------------------------------------------------------
+-- remainderNear.decTest -- decimal remainder-near (IEEE remainder)   --
+-- Copyright (c) IBM Corporation, 1981, 2004.  All rights reserved.   --
+------------------------------------------------------------------------
+-- Please see the document "General Decimal Arithmetic Testcases"     --
+-- at http://www2.hursley.ibm.com/decimal for the description of      --
+-- these testcases.                                                   --
+--                                                                    --
+-- These testcases are experimental ('beta' versions), and they       --
+-- may contain errors.  They are offered on an as-is basis.  In       --
+-- particular, achieving the same results as the tests here is not    --
+-- a guarantee that an implementation complies with any Standard      --
+-- or specification.  The tests are not exhaustive.                   --
+--                                                                    --
+-- Please send comments, suggestions, and corrections to the author:  --
+--   Mike Cowlishaw, IBM Fellow                                       --
+--   IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK         --
+--   mfc at uk.ibm.com                                                   --
+------------------------------------------------------------------------
+version: 2.39
+
+extended:    1
+precision:   9
+rounding:    half_up
+maxExponent: 384
+minexponent: -383
+
+rmnx001 remaindernear  1     1    ->  0
+rmnx002 remaindernear  2     1    ->  0
+rmnx003 remaindernear  1     2    ->  1
+rmnx004 remaindernear  2     2    ->  0
+rmnx005 remaindernear  0     1    ->  0
+rmnx006 remaindernear  0     2    ->  0
+rmnx007 remaindernear  1     3    ->  1
+rmnx008 remaindernear  2     3    -> -1
+rmnx009 remaindernear  3     3    ->  0
+
+rmnx010 remaindernear  2.4   1    ->  0.4
+rmnx011 remaindernear  2.4   -1   ->  0.4
+rmnx012 remaindernear  -2.4  1    ->  -0.4
+rmnx013 remaindernear  -2.4  -1   ->  -0.4
+rmnx014 remaindernear  2.40  1    ->  0.40
+rmnx015 remaindernear  2.400 1    ->  0.400
+rmnx016 remaindernear  2.4   2    ->  0.4
+rmnx017 remaindernear  2.400 2    ->  0.400
+rmnx018 remaindernear  2.    2    ->  0
+rmnx019 remaindernear  20    20   ->  0
+
+rmnx020 remaindernear  187   187    ->  0
+rmnx021 remaindernear  5     2      ->  1
+rmnx022 remaindernear  5     2.0    ->  1.0
+rmnx023 remaindernear  5     2.000  ->  1.000
+rmnx024 remaindernear  5     0.200  ->  0.000
+rmnx025 remaindernear  5     0.200  ->  0.000
+
+rmnx030 remaindernear  1     2      ->  1
+rmnx031 remaindernear  1     4      ->  1
+rmnx032 remaindernear  1     8      ->  1
+rmnx033 remaindernear  1     16     ->  1
+rmnx034 remaindernear  1     32     ->  1
+rmnx035 remaindernear  1     64     ->  1
+rmnx040 remaindernear  1    -2      ->  1
+rmnx041 remaindernear  1    -4      ->  1
+rmnx042 remaindernear  1    -8      ->  1
+rmnx043 remaindernear  1    -16     ->  1
+rmnx044 remaindernear  1    -32     ->  1
+rmnx045 remaindernear  1    -64     ->  1
+rmnx050 remaindernear -1     2      ->  -1
+rmnx051 remaindernear -1     4      ->  -1
+rmnx052 remaindernear -1     8      ->  -1
+rmnx053 remaindernear -1     16     ->  -1
+rmnx054 remaindernear -1     32     ->  -1
+rmnx055 remaindernear -1     64     ->  -1
+rmnx060 remaindernear -1    -2      ->  -1
+rmnx061 remaindernear -1    -4      ->  -1
+rmnx062 remaindernear -1    -8      ->  -1
+rmnx063 remaindernear -1    -16     ->  -1
+rmnx064 remaindernear -1    -32     ->  -1
+rmnx065 remaindernear -1    -64     ->  -1
+
+rmnx066 remaindernear  999999997     1  -> 0
+rmnx067 remaindernear  999999997.4   1  -> 0.4
+rmnx068 remaindernear  999999997.5   1  -> -0.5
+rmnx069 remaindernear  999999997.9   1  -> -0.1
+rmnx070 remaindernear  999999997.999 1  -> -0.001
+
+rmnx071 remaindernear  999999998     1  -> 0
+rmnx072 remaindernear  999999998.4   1  -> 0.4
+rmnx073 remaindernear  999999998.5   1  -> 0.5
+rmnx074 remaindernear  999999998.9   1  -> -0.1
+rmnx075 remaindernear  999999998.999 1  -> -0.001
+
+rmnx076 remaindernear  999999999     1  -> 0
+rmnx077 remaindernear  999999999.4   1  -> 0.4
+rmnx078 remaindernear  999999999.5   1  -> NaN Division_impossible
+rmnx079 remaindernear  999999999.9   1  -> NaN Division_impossible
+rmnx080 remaindernear  999999999.999 1  -> NaN Division_impossible
+
+precision: 6
+rmnx081 remaindernear  999999999     1  -> NaN Division_impossible
+rmnx082 remaindernear  99999999      1  -> NaN Division_impossible
+rmnx083 remaindernear  9999999       1  -> NaN Division_impossible
+rmnx084 remaindernear  999999        1  -> 0
+rmnx085 remaindernear  99999         1  -> 0
+rmnx086 remaindernear  9999          1  -> 0
+rmnx087 remaindernear  999           1  -> 0
+rmnx088 remaindernear  99            1  -> 0
+rmnx089 remaindernear  9             1  -> 0
+
+precision: 9
+rmnx090 remaindernear  0.            1  -> 0
+rmnx091 remaindernear  .0            1  -> 0.0
+rmnx092 remaindernear  0.00          1  -> 0.00
+rmnx093 remaindernear  0.00E+9       1  -> 0
+rmnx094 remaindernear  0.0000E-50    1  -> 0E-54
+
+
+-- Various flavours of remaindernear by 0
+precision: 9
+maxexponent: 999999999
+minexponent: -999999999
+rmnx101 remaindernear  0       0   -> NaN Division_undefined
+rmnx102 remaindernear  0      -0   -> NaN Division_undefined
+rmnx103 remaindernear -0       0   -> NaN Division_undefined
+rmnx104 remaindernear -0      -0   -> NaN Division_undefined
+rmnx105 remaindernear  0.0E5   0   -> NaN Division_undefined
+rmnx106 remaindernear  0.000   0   -> NaN Division_undefined
+-- [Some think this next group should be Division_by_zero exception,
+-- but IEEE 854 is explicit that it is Invalid operation .. for
+-- remaindernear-near, anyway]
+rmnx107 remaindernear  0.0001  0   -> NaN Invalid_operation
+rmnx108 remaindernear  0.01    0   -> NaN Invalid_operation
+rmnx109 remaindernear  0.1     0   -> NaN Invalid_operation
+rmnx110 remaindernear  1       0   -> NaN Invalid_operation
+rmnx111 remaindernear  1       0.0 -> NaN Invalid_operation
+rmnx112 remaindernear 10       0.0 -> NaN Invalid_operation
+rmnx113 remaindernear 1E+100   0.0 -> NaN Invalid_operation
+rmnx114 remaindernear 1E+1000  0   -> NaN Invalid_operation
+rmnx115 remaindernear  0.0001 -0   -> NaN Invalid_operation
+rmnx116 remaindernear  0.01   -0   -> NaN Invalid_operation
+rmnx119 remaindernear  0.1    -0   -> NaN Invalid_operation
+rmnx120 remaindernear  1      -0   -> NaN Invalid_operation
+rmnx121 remaindernear  1      -0.0 -> NaN Invalid_operation
+rmnx122 remaindernear 10      -0.0 -> NaN Invalid_operation
+rmnx123 remaindernear 1E+100  -0.0 -> NaN Invalid_operation
+rmnx124 remaindernear 1E+1000 -0   -> NaN Invalid_operation
+-- and zeros on left
+rmnx130 remaindernear  0      1   ->  0
+rmnx131 remaindernear  0     -1   ->  0
+rmnx132 remaindernear  0.0    1   ->  0.0
+rmnx133 remaindernear  0.0   -1   ->  0.0
+rmnx134 remaindernear -0      1   -> -0
+rmnx135 remaindernear -0     -1   -> -0
+rmnx136 remaindernear -0.0    1   -> -0.0
+rmnx137 remaindernear -0.0   -1   -> -0.0
+
+-- 0.5ers
+rmmx143 remaindernear   0.5  2     ->  0.5
+rmmx144 remaindernear   0.5  2.1   ->  0.5
+rmmx145 remaindernear   0.5  2.01  ->  0.50
+rmmx146 remaindernear   0.5  2.001 ->  0.500
+rmmx147 remaindernear   0.50 2     ->  0.50
+rmmx148 remaindernear   0.50 2.01  ->  0.50
+rmmx149 remaindernear   0.50 2.001 ->  0.500
+
+-- some differences from remainder
+rmnx150 remaindernear   0.4  1.020 ->  0.400
+rmnx151 remaindernear   0.50 1.020 ->  0.500
+rmnx152 remaindernear   0.51 1.020 ->  0.510
+rmnx153 remaindernear   0.52 1.020 -> -0.500
+rmnx154 remaindernear   0.6  1.020 -> -0.420
+rmnx155 remaindernear   0.49 1     ->  0.49
+rmnx156 remaindernear   0.50 1     ->  0.50
+rmnx157 remaindernear   1.50 1     -> -0.50
+rmnx158 remaindernear   2.50 1     ->  0.50
+rmnx159 remaindernear   9.50 1     -> -0.50
+rmnx160 remaindernear   0.51 1     -> -0.49
+
+-- the nasty division-by-1 cases
+rmnx161 remaindernear   0.4         1   ->  0.4
+rmnx162 remaindernear   0.45        1   ->  0.45
+rmnx163 remaindernear   0.455       1   ->  0.455
+rmnx164 remaindernear   0.4555      1   ->  0.4555
+rmnx165 remaindernear   0.45555     1   ->  0.45555
+rmnx166 remaindernear   0.455555    1   ->  0.455555
+rmnx167 remaindernear   0.4555555   1   ->  0.4555555
+rmnx168 remaindernear   0.45555555  1   ->  0.45555555
+rmnx169 remaindernear   0.455555555 1   ->  0.455555555
+-- with spill...
+rmnx171 remaindernear   0.5         1   ->  0.5
+rmnx172 remaindernear   0.55        1   -> -0.45
+rmnx173 remaindernear   0.555       1   -> -0.445
+rmnx174 remaindernear   0.5555      1   -> -0.4445
+rmnx175 remaindernear   0.55555     1   -> -0.44445
+rmnx176 remaindernear   0.555555    1   -> -0.444445
+rmnx177 remaindernear   0.5555555   1   -> -0.4444445
+rmnx178 remaindernear   0.55555555  1   -> -0.44444445
+rmnx179 remaindernear   0.555555555 1   -> -0.444444445
+
+-- progression
+rmnx180 remaindernear  1  1   -> 0
+rmnx181 remaindernear  1  2   -> 1
+rmnx182 remaindernear  1  3   -> 1
+rmnx183 remaindernear  1  4   -> 1
+rmnx184 remaindernear  1  5   -> 1
+rmnx185 remaindernear  1  6   -> 1
+rmnx186 remaindernear  1  7   -> 1
+rmnx187 remaindernear  1  8   -> 1
+rmnx188 remaindernear  1  9   -> 1
+rmnx189 remaindernear  1  10  -> 1
+rmnx190 remaindernear  1  1   -> 0
+rmnx191 remaindernear  2  1   -> 0
+rmnx192 remaindernear  3  1   -> 0
+rmnx193 remaindernear  4  1   -> 0
+rmnx194 remaindernear  5  1   -> 0
+rmnx195 remaindernear  6  1   -> 0
+rmnx196 remaindernear  7  1   -> 0
+rmnx197 remaindernear  8  1   -> 0
+rmnx198 remaindernear  9  1   -> 0
+rmnx199 remaindernear  10 1   -> 0
+
+
+-- Various flavours of remaindernear by 0
+maxexponent: 999999999
+minexponent: -999999999
+rmnx201 remaindernear  0      0   -> NaN Division_undefined
+rmnx202 remaindernear  0.0E5  0   -> NaN Division_undefined
+rmnx203 remaindernear  0.000  0   -> NaN Division_undefined
+rmnx204 remaindernear  0.0001 0   -> NaN Invalid_operation
+rmnx205 remaindernear  0.01   0   -> NaN Invalid_operation
+rmnx206 remaindernear  0.1    0   -> NaN Invalid_operation
+rmnx207 remaindernear  1      0   -> NaN Invalid_operation
+rmnx208 remaindernear  1      0.0 -> NaN Invalid_operation
+rmnx209 remaindernear 10      0.0 -> NaN Invalid_operation
+rmnx210 remaindernear 1E+100  0.0 -> NaN Invalid_operation
+rmnx211 remaindernear 1E+1000 0   -> NaN Invalid_operation
+
+-- tests from the extended specification
+rmnx221 remaindernear 2.1     3   -> -0.9
+rmnx222 remaindernear  10     6   -> -2
+rmnx223 remaindernear  10     3   ->  1
+rmnx224 remaindernear -10     3   -> -1
+rmnx225 remaindernear  10.2   1   -> 0.2
+rmnx226 remaindernear  10     0.3 -> 0.1
+rmnx227 remaindernear   3.6   1.3 -> -0.3
+
+-- some differences from remainder
+rmnx231 remaindernear   0.4  1.020 ->  0.400
+rmnx232 remaindernear   0.50 1.020 ->  0.500
+rmnx233 remaindernear   0.51 1.020 ->  0.510
+rmnx234 remaindernear   0.52 1.020 -> -0.500
+rmnx235 remaindernear   0.6  1.020 -> -0.420
+
+-- test some cases that are close to exponent overflow
+maxexponent: 999999999
+minexponent: -999999999
+rmnx270 remaindernear 1 1e999999999    -> 1
+rmnx271 remaindernear 1 0.9e999999999  -> 1
+rmnx272 remaindernear 1 0.99e999999999 -> 1
+rmnx273 remaindernear 1 0.999999999e999999999 -> 1
+rmnx274 remaindernear 9e999999999          1 -> NaN Division_impossible
+rmnx275 remaindernear 9.9e999999999        1 -> NaN Division_impossible
+rmnx276 remaindernear 9.99e999999999       1 -> NaN Division_impossible
+rmnx277 remaindernear 9.99999999e999999999 1 -> NaN Division_impossible
+
+rmnx280 remaindernear 0.1 9e-999999999       -> NaN Division_impossible
+rmnx281 remaindernear 0.1 99e-999999999      -> NaN Division_impossible
+rmnx282 remaindernear 0.1 999e-999999999     -> NaN Division_impossible
+
+rmnx283 remaindernear 0.1 9e-999999998       -> NaN Division_impossible
+rmnx284 remaindernear 0.1 99e-999999998      -> NaN Division_impossible
+rmnx285 remaindernear 0.1 999e-999999998     -> NaN Division_impossible
+rmnx286 remaindernear 0.1 999e-999999997     -> NaN Division_impossible
+rmnx287 remaindernear 0.1 9999e-999999997    -> NaN Division_impossible
+rmnx288 remaindernear 0.1 99999e-999999997   -> NaN Division_impossible
+
+-- rmnx3xx are from DiagBigDecimal
+rmnx301 remaindernear   1    3     ->  1
+rmnx302 remaindernear   5    5     ->  0
+rmnx303 remaindernear   13   10    ->  3
+rmnx304 remaindernear   13   50    ->  13
+rmnx305 remaindernear   13   100   ->  13
+rmnx306 remaindernear   13   1000  ->  13
+rmnx307 remaindernear   .13    1   ->  0.13
+rmnx308 remaindernear   0.133  1   ->  0.133
+rmnx309 remaindernear   0.1033 1   ->  0.1033
+rmnx310 remaindernear   1.033  1   ->  0.033
+rmnx311 remaindernear   10.33  1   ->  0.33
+rmnx312 remaindernear   10.33 10   ->  0.33
+rmnx313 remaindernear   103.3  1   ->  0.3
+rmnx314 remaindernear   133   10   ->  3
+rmnx315 remaindernear   1033  10   ->  3
+rmnx316 remaindernear   1033  50   -> -17
+rmnx317 remaindernear   101.0  3   -> -1.0
+rmnx318 remaindernear   102.0  3   ->  0.0
+rmnx319 remaindernear   103.0  3   ->  1.0
+rmnx320 remaindernear   2.40   1   ->  0.40
+rmnx321 remaindernear   2.400  1   ->  0.400
+rmnx322 remaindernear   2.4    1   ->  0.4
+rmnx323 remaindernear   2.4    2   ->  0.4
+rmnx324 remaindernear   2.400  2   ->  0.400
+rmnx325 remaindernear   1   0.3    ->  0.1
+rmnx326 remaindernear   1   0.30   ->  0.10
+rmnx327 remaindernear   1   0.300  ->  0.100
+rmnx328 remaindernear   1   0.3000 ->  0.1000
+rmnx329 remaindernear   1.0    0.3 ->  0.1
+rmnx330 remaindernear   1.00   0.3 ->  0.10
+rmnx331 remaindernear   1.000  0.3 ->  0.100
+rmnx332 remaindernear   1.0000 0.3 ->  0.1000
+rmnx333 remaindernear   0.5  2     ->  0.5
+rmnx334 remaindernear   0.5  2.1   ->  0.5
+rmnx335 remaindernear   0.5  2.01  ->  0.50
+rmnx336 remaindernear   0.5  2.001 ->  0.500
+rmnx337 remaindernear   0.50 2     ->  0.50
+rmnx338 remaindernear   0.50 2.01  ->  0.50
+rmnx339 remaindernear   0.50 2.001 ->  0.500
+
+rmnx340 remaindernear   0.5   0.5000001    ->  -1E-7
+rmnx341 remaindernear   0.5   0.50000001    ->  -1E-8
+rmnx342 remaindernear   0.5   0.500000001    ->  -1E-9
+rmnx343 remaindernear   0.5   0.5000000001    ->  -1E-10
+rmnx344 remaindernear   0.5   0.50000000001    ->  -1E-11
+rmnx345 remaindernear   0.5   0.4999999    ->  1E-7
+rmnx346 remaindernear   0.5   0.49999999    ->  1E-8
+rmnx347 remaindernear   0.5   0.499999999    ->  1E-9
+rmnx348 remaindernear   0.5   0.4999999999    ->  1E-10
+rmnx349 remaindernear   0.5   0.49999999999    ->  1E-11
+
+rmnx350 remaindernear   0.03  7  ->  0.03
+rmnx351 remaindernear   5   2    ->  1
+rmnx352 remaindernear   4.1   2    ->  0.1
+rmnx353 remaindernear   4.01   2    ->  0.01
+rmnx354 remaindernear   4.001   2    ->  0.001
+rmnx355 remaindernear   4.0001   2    ->  0.0001
+rmnx356 remaindernear   4.00001   2    ->  0.00001
+rmnx357 remaindernear   4.000001   2    ->  0.000001
+rmnx358 remaindernear   4.0000001   2    ->  1E-7
+
+rmnx360 remaindernear   1.2   0.7345 -> -0.2690
+rmnx361 remaindernear   0.8   12     ->  0.8
+rmnx362 remaindernear   0.8   0.2    ->  0.0
+rmnx363 remaindernear   0.8   0.3    -> -0.1
+rmnx364 remaindernear   0.800   12   ->  0.800
+rmnx365 remaindernear   0.800   1.7  ->  0.800
+rmnx366 remaindernear   2.400   2    ->  0.400
+
+precision: 6
+rmnx371 remaindernear   2.400  2        ->  0.400
+precision: 3
+rmnx372 remaindernear   12345678900000 12e+12 -> 3.46E+11 Inexact Rounded
+
+precision: 5
+rmnx381 remaindernear 12345  1         ->  0
+rmnx382 remaindernear 12345  1.0001    -> -0.2344
+rmnx383 remaindernear 12345  1.001     -> -0.333
+rmnx384 remaindernear 12345  1.01      -> -0.23
+rmnx385 remaindernear 12345  1.1       -> -0.3
+rmnx386 remaindernear 12355  4         -> -1
+rmnx387 remaindernear 12345  4         ->  1
+rmnx388 remaindernear 12355  4.0001    -> -1.3089
+rmnx389 remaindernear 12345  4.0001    ->  0.6914
+rmnx390 remaindernear 12345  4.9       ->  1.9
+rmnx391 remaindernear 12345  4.99      -> -0.26
+rmnx392 remaindernear 12345  4.999     ->  2.469
+rmnx393 remaindernear 12345  4.9999    ->  0.2469
+rmnx394 remaindernear 12345  5         ->  0
+rmnx395 remaindernear 12345  5.0001    -> -0.2469
+rmnx396 remaindernear 12345  5.001     -> -2.469
+rmnx397 remaindernear 12345  5.01      ->  0.36
+rmnx398 remaindernear 12345  5.1       -> -2.1
+
+precision: 9
+-- some nasty division-by-1 cases [some similar above]
+rmnx401 remaindernear   0.4         1   ->  0.4
+rmnx402 remaindernear   0.45        1   ->  0.45
+rmnx403 remaindernear   0.455       1   ->  0.455
+rmnx404 remaindernear   0.4555      1   ->  0.4555
+rmnx405 remaindernear   0.45555     1   ->  0.45555
+rmnx406 remaindernear   0.455555    1   ->  0.455555
+rmnx407 remaindernear   0.4555555   1   ->  0.4555555
+rmnx408 remaindernear   0.45555555  1   ->  0.45555555
+rmnx409 remaindernear   0.455555555 1   ->  0.455555555
+
+-- some tricky LHSs
+rmnx420 remaindernear   99999999.999999999   1E+8   -> -1E-9
+rmnx421 remaindernear  999999999.999999999   1E+9   -> -1E-9
+precision: 9
+rmnx430 remaindernear   0.455555555 1   ->  0.455555555
+precision: 8
+rmnx431 remaindernear   0.455555555 1   ->  0.45555556 Inexact Rounded
+precision: 7
+rmnx432 remaindernear   0.455555555 1   ->  0.4555556  Inexact Rounded
+precision: 6
+rmnx433 remaindernear   0.455555555 1   ->  0.455556   Inexact Rounded
+precision: 5
+rmnx434 remaindernear   0.455555555 1   ->  0.45556    Inexact Rounded
+precision: 4
+rmnx435 remaindernear   0.455555555 1   ->  0.4556     Inexact Rounded
+precision: 3
+rmnx436 remaindernear   0.455555555 1   ->  0.456      Inexact Rounded
+precision: 2
+rmnx437 remaindernear   0.455555555 1   ->  0.46       Inexact Rounded
+precision: 1
+rmnx438 remaindernear   0.455555555 1   ->  0.5        Inexact Rounded
+
+-- early tests; from text descriptions
+precision: 9
+rmnx601 remaindernear  10   6  -> -2
+rmnx602 remaindernear -10   6  -> 2
+rmnx603 remaindernear  11   3  -> -1
+rmnx604 remaindernear  11   5  -> 1
+rmnx605 remaindernear   7.7 8  -> -0.3
+rmnx606 remaindernear  31.5 3  -> 1.5    -- i=10
+rmnx607 remaindernear  34.5 3  -> -1.5   -- i=11
+
+-- Specials
+rmnx680 remaindernear  Inf  -Inf   ->  NaN Invalid_operation
+rmnx681 remaindernear  Inf  -1000  ->  NaN Invalid_operation
+rmnx682 remaindernear  Inf  -1     ->  NaN Invalid_operation
+rmnx683 remaindernear  Inf   0     ->  NaN Invalid_operation
+rmnx684 remaindernear  Inf  -0     ->  NaN Invalid_operation
+rmnx685 remaindernear  Inf   1     ->  NaN Invalid_operation
+rmnx686 remaindernear  Inf   1000  ->  NaN Invalid_operation
+rmnx687 remaindernear  Inf   Inf   ->  NaN Invalid_operation
+rmnx688 remaindernear -1000  Inf   -> -1000
+rmnx689 remaindernear -Inf   Inf   ->  NaN Invalid_operation
+rmnx691 remaindernear -1     Inf   -> -1
+rmnx692 remaindernear  0     Inf   ->  0
+rmnx693 remaindernear -0     Inf   -> -0
+rmnx694 remaindernear  1     Inf   ->  1
+rmnx695 remaindernear  1000  Inf   ->  1000
+rmnx696 remaindernear  Inf   Inf   ->  NaN Invalid_operation
+
+rmnx700 remaindernear -Inf  -Inf   ->  NaN Invalid_operation
+rmnx701 remaindernear -Inf  -1000  ->  NaN Invalid_operation
+rmnx702 remaindernear -Inf  -1     ->  NaN Invalid_operation
+rmnx703 remaindernear -Inf  -0     ->  NaN Invalid_operation
+rmnx704 remaindernear -Inf   0     ->  NaN Invalid_operation
+rmnx705 remaindernear -Inf   1     ->  NaN Invalid_operation
+rmnx706 remaindernear -Inf   1000  ->  NaN Invalid_operation
+rmnx707 remaindernear -Inf   Inf   ->  NaN Invalid_operation
+rmnx708 remaindernear -Inf  -Inf   ->  NaN Invalid_operation
+rmnx709 remaindernear -1000  Inf   -> -1000
+rmnx710 remaindernear -1    -Inf   -> -1
+rmnx711 remaindernear -0    -Inf   -> -0
+rmnx712 remaindernear  0    -Inf   ->  0
+rmnx713 remaindernear  1    -Inf   ->  1
+rmnx714 remaindernear  1000 -Inf   ->  1000
+rmnx715 remaindernear  Inf  -Inf   ->  NaN Invalid_operation
+
+rmnx721 remaindernear  NaN -Inf    ->  NaN
+rmnx722 remaindernear  NaN -1000   ->  NaN
+rmnx723 remaindernear  NaN -1      ->  NaN
+rmnx724 remaindernear  NaN -0      ->  NaN
+rmnx725 remaindernear  NaN  0      ->  NaN
+rmnx726 remaindernear  NaN  1      ->  NaN
+rmnx727 remaindernear  NaN  1000   ->  NaN
+rmnx728 remaindernear  NaN  Inf    ->  NaN
+rmnx729 remaindernear  NaN  NaN    ->  NaN
+rmnx730 remaindernear -Inf  NaN    ->  NaN
+rmnx731 remaindernear -1000 NaN    ->  NaN
+rmnx732 remaindernear -1   -NaN    -> -NaN
+rmnx733 remaindernear -0    NaN    ->  NaN
+rmnx734 remaindernear  0    NaN    ->  NaN
+rmnx735 remaindernear  1    NaN    ->  NaN
+rmnx736 remaindernear  1000 NaN    ->  NaN
+rmnx737 remaindernear  Inf  NaN    ->  NaN
+
+rmnx741 remaindernear  sNaN -Inf   ->  NaN  Invalid_operation
+rmnx742 remaindernear  sNaN -1000  ->  NaN  Invalid_operation
+rmnx743 remaindernear -sNaN -1     -> -NaN  Invalid_operation
+rmnx744 remaindernear  sNaN -0     ->  NaN  Invalid_operation
+rmnx745 remaindernear  sNaN  0     ->  NaN  Invalid_operation
+rmnx746 remaindernear  sNaN  1     ->  NaN  Invalid_operation
+rmnx747 remaindernear  sNaN  1000  ->  NaN  Invalid_operation
+rmnx749 remaindernear  sNaN  NaN   ->  NaN  Invalid_operation
+rmnx750 remaindernear  sNaN sNaN   ->  NaN  Invalid_operation
+rmnx751 remaindernear  NaN  sNaN   ->  NaN  Invalid_operation
+rmnx752 remaindernear -Inf  sNaN   ->  NaN  Invalid_operation
+rmnx753 remaindernear -1000 sNaN   ->  NaN  Invalid_operation
+rmnx754 remaindernear -1    sNaN   ->  NaN  Invalid_operation
+rmnx755 remaindernear -0   -sNaN   -> -NaN  Invalid_operation
+rmnx756 remaindernear  0    sNaN   ->  NaN  Invalid_operation
+rmnx757 remaindernear  1    sNaN   ->  NaN  Invalid_operation
+rmnx758 remaindernear  1000 sNaN   ->  NaN  Invalid_operation
+rmnx759 remaindernear  Inf  sNaN   ->  NaN  Invalid_operation
+rmnx760 remaindernear  NaN  sNaN   ->  NaN  Invalid_operation
+
+-- propaging NaNs
+rmnx761 remaindernear  NaN1   NaN7   ->  NaN1
+rmnx762 remaindernear sNaN2   NaN8   ->  NaN2 Invalid_operation
+rmnx763 remaindernear  NaN3 -sNaN9   -> -NaN9 Invalid_operation
+rmnx764 remaindernear sNaN4  sNaN10  ->  NaN4 Invalid_operation
+rmnx765 remaindernear    15   NaN11  ->  NaN11
+rmnx766 remaindernear  NaN6   NaN12  ->  NaN6
+rmnx767 remaindernear  Inf   -NaN13  -> -NaN13
+rmnx768 remaindernear  NaN14  -Inf   ->  NaN14
+rmnx769 remaindernear    0    NaN15  ->  NaN15
+rmnx770 remaindernear -NaN16   -0    -> -NaN16
+
+-- test some cases that are close to exponent overflow
+maxexponent: 999999999
+minexponent: -999999999
+rmnx780 remaindernear 1 1e999999999    -> 1
+rmnx781 remaindernear 1 0.9e999999999  -> 1
+rmnx782 remaindernear 1 0.99e999999999 -> 1
+rmnx783 remaindernear 1 0.999999999e999999999 -> 1
+rmnx784 remaindernear 9e999999999          1 -> NaN Division_impossible
+rmnx785 remaindernear 9.9e999999999        1 -> NaN Division_impossible
+rmnx786 remaindernear 9.99e999999999       1 -> NaN Division_impossible
+rmnx787 remaindernear 9.99999999e999999999 1 -> NaN Division_impossible
+
+
+-- overflow and underflow tests [from divide]
+precision: 9
+maxexponent: 999999999
+minexponent: -999999999
+rmnx790 remaindernear +1.23456789012345E-0 9E+999999999 -> 1.23456789 Inexact Rounded
+rmnx791 remaindernear 9E+999999999 +0.23456789012345E-0 -> NaN Division_impossible
+rmnx792 remaindernear +0.100 9E+999999999               -> 0.100
+rmnx793 remaindernear 9E-999999999 +9.100               -> 9E-999999999
+rmnx795 remaindernear -1.23456789012345E-0 9E+999999999 -> -1.23456789 Inexact Rounded
+rmnx796 remaindernear 9E+999999999 -0.83456789012345E-0 -> NaN Division_impossible
+rmnx797 remaindernear -0.100 9E+999999999               -> -0.100
+rmnx798 remaindernear 9E-999999999 -9.100               -> 9E-999999999
+
+-- long operands checks
+maxexponent: 999
+minexponent: -999
+precision: 9
+rmnx801 remaindernear 12345678000 100 -> 0
+rmnx802 remaindernear 1 12345678000   -> 1
+rmnx803 remaindernear 1234567800  10  -> 0
+rmnx804 remaindernear 1 1234567800    -> 1
+rmnx805 remaindernear 1234567890  10  -> 0
+rmnx806 remaindernear 1 1234567890    -> 1
+rmnx807 remaindernear 1234567891  10  -> 1
+rmnx808 remaindernear 1 1234567891    -> 1
+rmnx809 remaindernear 12345678901 100 -> 1
+rmnx810 remaindernear 1 12345678901   -> 1
+rmnx811 remaindernear 1234567896  10  -> -4
+rmnx812 remaindernear 1 1234567896    -> 1
+
+precision: 15
+rmnx841 remaindernear 12345678000 100 -> 0
+rmnx842 remaindernear 1 12345678000   -> 1
+rmnx843 remaindernear 1234567800  10  -> 0
+rmnx844 remaindernear 1 1234567800    -> 1
+rmnx845 remaindernear 1234567890  10  -> 0
+rmnx846 remaindernear 1 1234567890    -> 1
+rmnx847 remaindernear 1234567891  10  -> 1
+rmnx848 remaindernear 1 1234567891    -> 1
+rmnx849 remaindernear 12345678901 100 -> 1
+rmnx850 remaindernear 1 12345678901   -> 1
+rmnx851 remaindernear 1234567896  10  -> -4
+rmnx852 remaindernear 1 1234567896    -> 1
+
+-- Null tests
+rmnx900 remaindernear 10  # -> NaN Invalid_operation
+rmnx901 remaindernear  # 10 -> NaN Invalid_operation

Added: vendor/Python/current/Lib/test/decimaltestdata/rescale.decTest
===================================================================
--- vendor/Python/current/Lib/test/decimaltestdata/rescale.decTest	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/decimaltestdata/rescale.decTest	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,758 @@
+------------------------------------------------------------------------
+-- rescale.decTest -- decimal rescale operation                       --
+-- Copyright (c) IBM Corporation, 1981, 2004.  All rights reserved.   --
+------------------------------------------------------------------------
+-- Please see the document "General Decimal Arithmetic Testcases"     --
+-- at http://www2.hursley.ibm.com/decimal for the description of      --
+-- these testcases.                                                   --
+--                                                                    --
+-- These testcases are experimental ('beta' versions), and they       --
+-- may contain errors.  They are offered on an as-is basis.  In       --
+-- particular, achieving the same results as the tests here is not    --
+-- a guarantee that an implementation complies with any Standard      --
+-- or specification.  The tests are not exhaustive.                   --
+--                                                                    --
+-- Please send comments, suggestions, and corrections to the author:  --
+--   Mike Cowlishaw, IBM Fellow                                       --
+--   IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK         --
+--   mfc at uk.ibm.com                                                   --
+------------------------------------------------------------------------
+version: 2.39
+
+-- [obsolete]   Quantize.decTest has the improved version
+
+-- 2004.03.15 Underflow for quantize is suppressed
+
+extended:    1
+precision:   9
+rounding:    half_up
+maxExponent: 999
+minexponent: -999
+
+-- sanity checks
+
+resx001 rescale 0       0   -> 0
+resx002 rescale 1       0   -> 1
+resx003 rescale 0.1    +2   -> 0E+2 Inexact Rounded
+resx005 rescale 0.1    +1   -> 0E+1 Inexact Rounded
+resx006 rescale 0.1     0   -> 0 Inexact Rounded
+resx007 rescale 0.1    -1   -> 0.1
+resx008 rescale 0.1    -2   -> 0.10
+resx009 rescale 0.1    -3   -> 0.100
+resx010 rescale 0.9    +2   -> 0E+2 Inexact Rounded
+resx011 rescale 0.9    +1   -> 0E+1 Inexact Rounded
+resx012 rescale 0.9    +0   -> 1 Inexact Rounded
+resx013 rescale 0.9    -1   -> 0.9
+resx014 rescale 0.9    -2   -> 0.90
+resx015 rescale 0.9    -3   -> 0.900
+-- negatives
+resx021 rescale -0      0   -> -0
+resx022 rescale -1      0   -> -1
+resx023 rescale -0.1   +2   -> -0E+2 Inexact Rounded
+resx025 rescale -0.1   +1   -> -0E+1 Inexact Rounded
+resx026 rescale -0.1    0   -> -0 Inexact Rounded
+resx027 rescale -0.1   -1   -> -0.1
+resx028 rescale -0.1   -2   -> -0.10
+resx029 rescale -0.1   -3   -> -0.100
+resx030 rescale -0.9   +2   -> -0E+2 Inexact Rounded
+resx031 rescale -0.9   +1   -> -0E+1 Inexact Rounded
+resx032 rescale -0.9   +0   -> -1 Inexact Rounded
+resx033 rescale -0.9   -1   -> -0.9
+resx034 rescale -0.9   -2   -> -0.90
+resx035 rescale -0.9   -3   -> -0.900
+resx036 rescale -0.5   +2   -> -0E+2 Inexact Rounded
+resx037 rescale -0.5   +1   -> -0E+1 Inexact Rounded
+resx038 rescale -0.5   +0   -> -1 Inexact Rounded
+resx039 rescale -0.5   -1   -> -0.5
+resx040 rescale -0.5   -2   -> -0.50
+resx041 rescale -0.5   -3   -> -0.500
+resx042 rescale -0.9   +2   -> -0E+2 Inexact Rounded
+resx043 rescale -0.9   +1   -> -0E+1 Inexact Rounded
+resx044 rescale -0.9   +0   -> -1 Inexact Rounded
+resx045 rescale -0.9   -1   -> -0.9
+resx046 rescale -0.9   -2   -> -0.90
+resx047 rescale -0.9   -3   -> -0.900
+
+-- examples from Specification
+resx060 rescale 2.17   -3   -> 2.170
+resx061 rescale 2.17   -2   -> 2.17
+resx062 rescale 2.17   -1   -> 2.2 Inexact Rounded
+resx063 rescale 2.17    0   -> 2 Inexact Rounded
+resx064 rescale 2.17   +1   -> 0E+1 Inexact Rounded
+resx065 rescale 2      Inf  -> NaN Invalid_operation
+resx066 rescale -0.1    0   -> -0 Inexact Rounded
+resx067 rescale -0      5   -> -0E+5
+resx068 rescale +35236450.6 -2 -> NaN Invalid_operation
+resx069 rescale -35236450.6 -2 -> NaN Invalid_operation
+resx070 rescale 217    -1   -> 217.0
+resx071 rescale 217     0   -> 217
+resx072 rescale 217    +1   -> 2.2E+2 Inexact Rounded
+resx073 rescale 217    +2   -> 2E+2 Inexact Rounded
+
+-- general tests ..
+resx089 rescale 12     +4   -> 0E+4 Inexact Rounded
+resx090 rescale 12     +3   -> 0E+3 Inexact Rounded
+resx091 rescale 12     +2   -> 0E+2 Inexact Rounded
+resx092 rescale 12     +1   -> 1E+1 Inexact Rounded
+resx093 rescale 1.2345 -2   -> 1.23 Inexact Rounded
+resx094 rescale 1.2355 -2   -> 1.24 Inexact Rounded
+resx095 rescale 1.2345 -6   -> 1.234500
+resx096 rescale 9.9999 -2   -> 10.00 Inexact Rounded
+resx097 rescale 0.0001 -2   -> 0.00 Inexact Rounded
+resx098 rescale 0.001  -2   -> 0.00 Inexact Rounded
+resx099 rescale 0.009  -2   -> 0.01 Inexact Rounded
+resx100 rescale 92     +2   -> 1E+2 Inexact Rounded
+
+resx101 rescale -1      0   ->  -1
+resx102 rescale -1     -1   ->  -1.0
+resx103 rescale -1     -2   ->  -1.00
+resx104 rescale  0      0   ->  0
+resx105 rescale  0     -1   ->  0.0
+resx106 rescale  0     -2   ->  0.00
+resx107 rescale  0.00   0   ->  0
+resx108 rescale  0     +1   ->  0E+1
+resx109 rescale  0     +2   ->  0E+2
+resx110 rescale +1      0   ->  1
+resx111 rescale +1     -1   ->  1.0
+resx112 rescale +1     -2   ->  1.00
+
+resx120 rescale   1.04  -3 ->  1.040
+resx121 rescale   1.04  -2 ->  1.04
+resx122 rescale   1.04  -1 ->  1.0 Inexact Rounded
+resx123 rescale   1.04   0 ->  1 Inexact Rounded
+resx124 rescale   1.05  -3 ->  1.050
+resx125 rescale   1.05  -2 ->  1.05
+resx126 rescale   1.05  -1 ->  1.1 Inexact Rounded
+resx127 rescale   1.05   0 ->  1 Inexact Rounded
+resx128 rescale   1.05  -3 ->  1.050
+resx129 rescale   1.05  -2 ->  1.05
+resx130 rescale   1.05  -1 ->  1.1 Inexact Rounded
+resx131 rescale   1.05   0 ->  1 Inexact Rounded
+resx132 rescale   1.06  -3 ->  1.060
+resx133 rescale   1.06  -2 ->  1.06
+resx134 rescale   1.06  -1 ->  1.1 Inexact Rounded
+resx135 rescale   1.06   0 ->  1 Inexact Rounded
+
+resx140 rescale   -10    -2  ->  -10.00
+resx141 rescale   +1     -2  ->  1.00
+resx142 rescale   +10    -2  ->  10.00
+resx143 rescale   1E+10  -2  ->  NaN Invalid_operation
+resx144 rescale   1E-10  -2  ->  0.00 Inexact Rounded
+resx145 rescale   1E-3   -2  ->  0.00 Inexact Rounded
+resx146 rescale   1E-2   -2  ->  0.01
+resx147 rescale   1E-1   -2  ->  0.10
+resx148 rescale   0E-10  -2  ->  0.00
+
+resx150 rescale   1.0600 -5 ->  1.06000
+resx151 rescale   1.0600 -4 ->  1.0600
+resx152 rescale   1.0600 -3 ->  1.060 Rounded
+resx153 rescale   1.0600 -2 ->  1.06 Rounded
+resx154 rescale   1.0600 -1 ->  1.1 Inexact Rounded
+resx155 rescale   1.0600  0 ->  1 Inexact Rounded
+
+-- +ve exponents ..
+resx201 rescale   -1   +0 ->  -1
+resx202 rescale   -1   +1 ->  -0E+1 Inexact Rounded
+resx203 rescale   -1   +2 ->  -0E+2 Inexact Rounded
+resx204 rescale    0   +0 ->  0
+resx205 rescale    0   +1 ->  0E+1
+resx206 rescale    0   +2 ->  0E+2
+resx207 rescale   +1   +0 ->  1
+resx208 rescale   +1   +1 ->  0E+1 Inexact Rounded
+resx209 rescale   +1   +2 ->  0E+2 Inexact Rounded
+
+resx220 rescale   1.04 +3 ->  0E+3 Inexact Rounded
+resx221 rescale   1.04 +2 ->  0E+2 Inexact Rounded
+resx222 rescale   1.04 +1 ->  0E+1 Inexact Rounded
+resx223 rescale   1.04 +0 ->  1 Inexact Rounded
+resx224 rescale   1.05 +3 ->  0E+3 Inexact Rounded
+resx225 rescale   1.05 +2 ->  0E+2 Inexact Rounded
+resx226 rescale   1.05 +1 ->  0E+1 Inexact Rounded
+resx227 rescale   1.05 +0 ->  1 Inexact Rounded
+resx228 rescale   1.05 +3 ->  0E+3 Inexact Rounded
+resx229 rescale   1.05 +2 ->  0E+2 Inexact Rounded
+resx230 rescale   1.05 +1 ->  0E+1 Inexact Rounded
+resx231 rescale   1.05 +0 ->  1 Inexact Rounded
+resx232 rescale   1.06 +3 ->  0E+3 Inexact Rounded
+resx233 rescale   1.06 +2 ->  0E+2 Inexact Rounded
+resx234 rescale   1.06 +1 ->  0E+1 Inexact Rounded
+resx235 rescale   1.06 +0 ->  1 Inexact Rounded
+
+resx240 rescale   -10   +1  ->  -1E+1 Rounded
+resx241 rescale   +1    +1  ->  0E+1 Inexact Rounded
+resx242 rescale   +10   +1  ->  1E+1 Rounded
+resx243 rescale   1E+1  +1  ->  1E+1          -- underneath this is E+1
+resx244 rescale   1E+2  +1  ->  1.0E+2        -- underneath this is E+1
+resx245 rescale   1E+3  +1  ->  1.00E+3       -- underneath this is E+1
+resx246 rescale   1E+4  +1  ->  1.000E+4      -- underneath this is E+1
+resx247 rescale   1E+5  +1  ->  1.0000E+5     -- underneath this is E+1
+resx248 rescale   1E+6  +1  ->  1.00000E+6    -- underneath this is E+1
+resx249 rescale   1E+7  +1  ->  1.000000E+7   -- underneath this is E+1
+resx250 rescale   1E+8  +1  ->  1.0000000E+8  -- underneath this is E+1
+resx251 rescale   1E+9  +1  ->  1.00000000E+9 -- underneath this is E+1
+-- next one tries to add 9 zeros
+resx252 rescale   1E+10 +1  ->  NaN Invalid_operation
+resx253 rescale   1E-10 +1  ->  0E+1 Inexact Rounded
+resx254 rescale   1E-2  +1  ->  0E+1 Inexact Rounded
+resx255 rescale   0E-10 +1  ->  0E+1
+resx256 rescale  -0E-10 +1  -> -0E+1
+resx257 rescale  -0E-1  +1  -> -0E+1
+resx258 rescale  -0     +1  -> -0E+1
+resx259 rescale  -0E+1  +1  -> -0E+1
+
+resx260 rescale   -10   +2  ->  -0E+2 Inexact Rounded
+resx261 rescale   +1    +2  ->  0E+2 Inexact Rounded
+resx262 rescale   +10   +2  ->  0E+2 Inexact Rounded
+resx263 rescale   1E+1  +2  ->  0E+2 Inexact Rounded
+resx264 rescale   1E+2  +2  ->  1E+2
+resx265 rescale   1E+3  +2  ->  1.0E+3
+resx266 rescale   1E+4  +2  ->  1.00E+4
+resx267 rescale   1E+5  +2  ->  1.000E+5
+resx268 rescale   1E+6  +2  ->  1.0000E+6
+resx269 rescale   1E+7  +2  ->  1.00000E+7
+resx270 rescale   1E+8  +2  ->  1.000000E+8
+resx271 rescale   1E+9  +2  ->  1.0000000E+9
+resx272 rescale   1E+10 +2  ->  1.00000000E+10
+resx273 rescale   1E-10 +2  ->  0E+2 Inexact Rounded
+resx274 rescale   1E-2  +2  ->  0E+2 Inexact Rounded
+resx275 rescale   0E-10 +2  ->  0E+2
+
+resx280 rescale   -10   +3  ->  -0E+3 Inexact Rounded
+resx281 rescale   +1    +3  ->  0E+3 Inexact Rounded
+resx282 rescale   +10   +3  ->  0E+3 Inexact Rounded
+resx283 rescale   1E+1  +3  ->  0E+3 Inexact Rounded
+resx284 rescale   1E+2  +3  ->  0E+3 Inexact Rounded
+resx285 rescale   1E+3  +3  ->  1E+3
+resx286 rescale   1E+4  +3  ->  1.0E+4
+resx287 rescale   1E+5  +3  ->  1.00E+5
+resx288 rescale   1E+6  +3  ->  1.000E+6
+resx289 rescale   1E+7  +3  ->  1.0000E+7
+resx290 rescale   1E+8  +3  ->  1.00000E+8
+resx291 rescale   1E+9  +3  ->  1.000000E+9
+resx292 rescale   1E+10 +3  ->  1.0000000E+10
+resx293 rescale   1E-10 +3  ->  0E+3 Inexact Rounded
+resx294 rescale   1E-2  +3  ->  0E+3 Inexact Rounded
+resx295 rescale   0E-10 +3  ->  0E+3
+
+-- round up from below [sign wrong in JIT compiler once]
+resx300 rescale   0.0078 -5 ->  0.00780
+resx301 rescale   0.0078 -4 ->  0.0078
+resx302 rescale   0.0078 -3 ->  0.008 Inexact Rounded
+resx303 rescale   0.0078 -2 ->  0.01 Inexact Rounded
+resx304 rescale   0.0078 -1 ->  0.0 Inexact Rounded
+resx305 rescale   0.0078  0 ->  0 Inexact Rounded
+resx306 rescale   0.0078 +1 ->  0E+1 Inexact Rounded
+resx307 rescale   0.0078 +2 ->  0E+2 Inexact Rounded
+
+resx310 rescale  -0.0078 -5 -> -0.00780
+resx311 rescale  -0.0078 -4 -> -0.0078
+resx312 rescale  -0.0078 -3 -> -0.008 Inexact Rounded
+resx313 rescale  -0.0078 -2 -> -0.01 Inexact Rounded
+resx314 rescale  -0.0078 -1 -> -0.0 Inexact Rounded
+resx315 rescale  -0.0078  0 -> -0 Inexact Rounded
+resx316 rescale  -0.0078 +1 -> -0E+1 Inexact Rounded
+resx317 rescale  -0.0078 +2 -> -0E+2 Inexact Rounded
+
+resx320 rescale   0.078 -5 ->  0.07800
+resx321 rescale   0.078 -4 ->  0.0780
+resx322 rescale   0.078 -3 ->  0.078
+resx323 rescale   0.078 -2 ->  0.08 Inexact Rounded
+resx324 rescale   0.078 -1 ->  0.1 Inexact Rounded
+resx325 rescale   0.078  0 ->  0 Inexact Rounded
+resx326 rescale   0.078 +1 ->  0E+1 Inexact Rounded
+resx327 rescale   0.078 +2 ->  0E+2 Inexact Rounded
+
+resx330 rescale  -0.078 -5 -> -0.07800
+resx331 rescale  -0.078 -4 -> -0.0780
+resx332 rescale  -0.078 -3 -> -0.078
+resx333 rescale  -0.078 -2 -> -0.08 Inexact Rounded
+resx334 rescale  -0.078 -1 -> -0.1 Inexact Rounded
+resx335 rescale  -0.078  0 -> -0 Inexact Rounded
+resx336 rescale  -0.078 +1 -> -0E+1 Inexact Rounded
+resx337 rescale  -0.078 +2 -> -0E+2 Inexact Rounded
+
+resx340 rescale   0.78 -5 ->  0.78000
+resx341 rescale   0.78 -4 ->  0.7800
+resx342 rescale   0.78 -3 ->  0.780
+resx343 rescale   0.78 -2 ->  0.78
+resx344 rescale   0.78 -1 ->  0.8 Inexact Rounded
+resx345 rescale   0.78  0 ->  1 Inexact Rounded
+resx346 rescale   0.78 +1 ->  0E+1 Inexact Rounded
+resx347 rescale   0.78 +2 ->  0E+2 Inexact Rounded
+
+resx350 rescale  -0.78 -5 -> -0.78000
+resx351 rescale  -0.78 -4 -> -0.7800
+resx352 rescale  -0.78 -3 -> -0.780
+resx353 rescale  -0.78 -2 -> -0.78
+resx354 rescale  -0.78 -1 -> -0.8 Inexact Rounded
+resx355 rescale  -0.78  0 -> -1 Inexact Rounded
+resx356 rescale  -0.78 +1 -> -0E+1 Inexact Rounded
+resx357 rescale  -0.78 +2 -> -0E+2 Inexact Rounded
+
+resx360 rescale   7.8 -5 ->  7.80000
+resx361 rescale   7.8 -4 ->  7.8000
+resx362 rescale   7.8 -3 ->  7.800
+resx363 rescale   7.8 -2 ->  7.80
+resx364 rescale   7.8 -1 ->  7.8
+resx365 rescale   7.8  0 ->  8 Inexact Rounded
+resx366 rescale   7.8 +1 ->  1E+1 Inexact Rounded
+resx367 rescale   7.8 +2 ->  0E+2 Inexact Rounded
+resx368 rescale   7.8 +3 ->  0E+3 Inexact Rounded
+
+resx370 rescale  -7.8 -5 -> -7.80000
+resx371 rescale  -7.8 -4 -> -7.8000
+resx372 rescale  -7.8 -3 -> -7.800
+resx373 rescale  -7.8 -2 -> -7.80
+resx374 rescale  -7.8 -1 -> -7.8
+resx375 rescale  -7.8  0 -> -8 Inexact Rounded
+resx376 rescale  -7.8 +1 -> -1E+1 Inexact Rounded
+resx377 rescale  -7.8 +2 -> -0E+2 Inexact Rounded
+resx378 rescale  -7.8 +3 -> -0E+3 Inexact Rounded
+
+-- some individuals
+precision: 9
+resx380 rescale   352364.506 -2 -> 352364.51 Inexact Rounded
+resx381 rescale   3523645.06 -2 -> 3523645.06
+resx382 rescale   35236450.6 -2 -> NaN Invalid_operation
+resx383 rescale   352364506  -2 -> NaN Invalid_operation
+resx384 rescale  -352364.506 -2 -> -352364.51 Inexact Rounded
+resx385 rescale  -3523645.06 -2 -> -3523645.06
+resx386 rescale  -35236450.6 -2 -> NaN Invalid_operation
+resx387 rescale  -352364506  -2 -> NaN Invalid_operation
+
+rounding: down
+resx389 rescale   35236450.6 -2 -> NaN Invalid_operation
+-- ? should that one instead have been:
+-- resx389 rescale   35236450.6 -2 -> NaN Invalid_operation
+rounding: half_up
+
+-- and a few more from e-mail discussions
+precision: 7
+resx391 rescale  12.34567  -3 -> 12.346   Inexact Rounded
+resx392 rescale  123.4567  -3 -> 123.457  Inexact Rounded
+resx393 rescale  1234.567  -3 -> 1234.567
+resx394 rescale  12345.67  -3 -> NaN Invalid_operation
+resx395 rescale  123456.7  -3 -> NaN Invalid_operation
+resx396 rescale  1234567.  -3 -> NaN Invalid_operation
+
+-- some 9999 round-up cases
+precision: 9
+resx400 rescale   9.999        -5  ->  9.99900
+resx401 rescale   9.999        -4  ->  9.9990
+resx402 rescale   9.999        -3  ->  9.999
+resx403 rescale   9.999        -2  -> 10.00     Inexact Rounded
+resx404 rescale   9.999        -1  -> 10.0      Inexact Rounded
+resx405 rescale   9.999         0  -> 10        Inexact Rounded
+resx406 rescale   9.999         1  -> 1E+1      Inexact Rounded
+resx407 rescale   9.999         2  -> 0E+2      Inexact Rounded
+
+resx410 rescale   0.999        -5  ->  0.99900
+resx411 rescale   0.999        -4  ->  0.9990
+resx412 rescale   0.999        -3  ->  0.999
+resx413 rescale   0.999        -2  ->  1.00     Inexact Rounded
+resx414 rescale   0.999        -1  ->  1.0      Inexact Rounded
+resx415 rescale   0.999         0  ->  1        Inexact Rounded
+resx416 rescale   0.999         1  -> 0E+1      Inexact Rounded
+
+resx420 rescale   0.0999       -5  ->  0.09990
+resx421 rescale   0.0999       -4  ->  0.0999
+resx422 rescale   0.0999       -3  ->  0.100    Inexact Rounded
+resx423 rescale   0.0999       -2  ->  0.10     Inexact Rounded
+resx424 rescale   0.0999       -1  ->  0.1      Inexact Rounded
+resx425 rescale   0.0999        0  ->  0        Inexact Rounded
+resx426 rescale   0.0999        1  -> 0E+1      Inexact Rounded
+
+resx430 rescale   0.00999      -5  ->  0.00999
+resx431 rescale   0.00999      -4  ->  0.0100   Inexact Rounded
+resx432 rescale   0.00999      -3  ->  0.010    Inexact Rounded
+resx433 rescale   0.00999      -2  ->  0.01     Inexact Rounded
+resx434 rescale   0.00999      -1  ->  0.0      Inexact Rounded
+resx435 rescale   0.00999       0  ->  0        Inexact Rounded
+resx436 rescale   0.00999       1  -> 0E+1      Inexact Rounded
+
+resx440 rescale   0.000999     -5  ->  0.00100  Inexact Rounded
+resx441 rescale   0.000999     -4  ->  0.0010   Inexact Rounded
+resx442 rescale   0.000999     -3  ->  0.001    Inexact Rounded
+resx443 rescale   0.000999     -2  ->  0.00     Inexact Rounded
+resx444 rescale   0.000999     -1  ->  0.0      Inexact Rounded
+resx445 rescale   0.000999      0  ->  0        Inexact Rounded
+resx446 rescale   0.000999      1  -> 0E+1      Inexact Rounded
+
+precision: 8
+resx449 rescale   9.999E-15    -23 ->  NaN Invalid_operation
+resx450 rescale   9.999E-15    -22 ->  9.9990000E-15
+resx451 rescale   9.999E-15    -21 ->  9.999000E-15
+resx452 rescale   9.999E-15    -20 ->  9.99900E-15
+resx453 rescale   9.999E-15    -19 ->  9.9990E-15
+resx454 rescale   9.999E-15    -18 ->  9.999E-15
+resx455 rescale   9.999E-15    -17 ->  1.000E-14 Inexact Rounded
+resx456 rescale   9.999E-15    -16 ->  1.00E-14  Inexact Rounded
+resx457 rescale   9.999E-15    -15 ->  1.0E-14   Inexact Rounded
+resx458 rescale   9.999E-15    -14 ->  1E-14     Inexact Rounded
+resx459 rescale   9.999E-15    -13 ->  0E-13     Inexact Rounded
+resx460 rescale   9.999E-15    -12 ->  0E-12     Inexact Rounded
+resx461 rescale   9.999E-15    -11 ->  0E-11     Inexact Rounded
+resx462 rescale   9.999E-15    -10 ->  0E-10     Inexact Rounded
+resx463 rescale   9.999E-15     -9 ->  0E-9      Inexact Rounded
+resx464 rescale   9.999E-15     -8 ->  0E-8      Inexact Rounded
+resx465 rescale   9.999E-15     -7 ->  0E-7      Inexact Rounded
+resx466 rescale   9.999E-15     -6 ->  0.000000  Inexact Rounded
+resx467 rescale   9.999E-15     -5 ->  0.00000   Inexact Rounded
+resx468 rescale   9.999E-15     -4 ->  0.0000    Inexact Rounded
+resx469 rescale   9.999E-15     -3 ->  0.000     Inexact Rounded
+resx470 rescale   9.999E-15     -2 ->  0.00      Inexact Rounded
+resx471 rescale   9.999E-15     -1 ->  0.0       Inexact Rounded
+resx472 rescale   9.999E-15      0 ->  0         Inexact Rounded
+resx473 rescale   9.999E-15      1 ->  0E+1      Inexact Rounded
+
+-- long operand checks [rhs checks removed]
+maxexponent: 999
+minexponent: -999
+precision: 9
+resx481 rescale 12345678000 +3 -> 1.2345678E+10 Rounded
+resx482 rescale 1234567800  +1 -> 1.23456780E+9 Rounded
+resx483 rescale 1234567890  +1 -> 1.23456789E+9 Rounded
+resx484 rescale 1234567891  +1 -> 1.23456789E+9 Inexact Rounded
+resx485 rescale 12345678901 +2 -> 1.23456789E+10 Inexact Rounded
+resx486 rescale 1234567896  +1 -> 1.23456790E+9 Inexact Rounded
+-- a potential double-round
+resx487 rescale 1234.987643 -4 -> 1234.9876 Inexact Rounded
+resx488 rescale 1234.987647 -4 -> 1234.9876 Inexact Rounded
+
+precision: 15
+resx491 rescale 12345678000 +3 -> 1.2345678E+10 Rounded
+resx492 rescale 1234567800  +1 -> 1.23456780E+9 Rounded
+resx493 rescale 1234567890  +1 -> 1.23456789E+9 Rounded
+resx494 rescale 1234567891  +1 -> 1.23456789E+9 Inexact Rounded
+resx495 rescale 12345678901 +2 -> 1.23456789E+10 Inexact Rounded
+resx496 rescale 1234567896  +1 -> 1.23456790E+9 Inexact Rounded
+resx497 rescale 1234.987643 -4 -> 1234.9876 Inexact Rounded
+resx498 rescale 1234.987647 -4 -> 1234.9876 Inexact Rounded
+
+-- Zeros
+resx500 rescale   0     1 ->  0E+1
+resx501 rescale   0     0 ->  0
+resx502 rescale   0    -1 ->  0.0
+resx503 rescale   0.0  -1 ->  0.0
+resx504 rescale   0.0   0 ->  0
+resx505 rescale   0.0  +1 ->  0E+1
+resx506 rescale   0E+1 -1 ->  0.0
+resx507 rescale   0E+1  0 ->  0
+resx508 rescale   0E+1 +1 ->  0E+1
+resx509 rescale  -0     1 -> -0E+1
+resx510 rescale  -0     0 -> -0
+resx511 rescale  -0    -1 -> -0.0
+resx512 rescale  -0.0  -1 -> -0.0
+resx513 rescale  -0.0   0 -> -0
+resx514 rescale  -0.0  +1 -> -0E+1
+resx515 rescale  -0E+1 -1 -> -0.0
+resx516 rescale  -0E+1  0 -> -0
+resx517 rescale  -0E+1 +1 -> -0E+1
+
+-- Suspicious RHS values
+maxexponent: 999999999
+minexponent: -999999999
+precision: 15
+resx520 rescale   1.234    999999E+3 -> 0E+999999000 Inexact Rounded
+resx521 rescale 123.456    999999E+3 -> 0E+999999000 Inexact Rounded
+resx522 rescale   1.234    999999999 -> 0E+999999999 Inexact Rounded
+resx523 rescale 123.456    999999999 -> 0E+999999999 Inexact Rounded
+resx524 rescale 123.456   1000000000 -> NaN Invalid_operation
+resx525 rescale 123.456  12345678903 -> NaN Invalid_operation
+-- next four are "won't fit" overflows
+resx526 rescale   1.234   -999999E+3 -> NaN Invalid_operation
+resx527 rescale 123.456   -999999E+3 -> NaN Invalid_operation
+resx528 rescale   1.234   -999999999 -> NaN Invalid_operation
+resx529 rescale 123.456   -999999999 -> NaN Invalid_operation
+resx530 rescale 123.456  -1000000014 -> NaN Invalid_operation
+resx531 rescale 123.456 -12345678903 -> NaN Invalid_operation
+
+maxexponent: 999
+minexponent: -999
+precision: 15
+resx532 rescale   1.234E+999    999 -> 1E+999    Inexact Rounded
+resx533 rescale   1.234E+998    999 -> 0E+999    Inexact Rounded
+resx534 rescale   1.234         999 -> 0E+999    Inexact Rounded
+resx535 rescale   1.234        1000 -> NaN Invalid_operation
+resx536 rescale   1.234        5000 -> NaN Invalid_operation
+resx537 rescale   0            -999 -> 0E-999
+-- next two are "won't fit" overflows
+resx538 rescale   1.234        -999 -> NaN Invalid_operation
+resx539 rescale   1.234       -1000 -> NaN Invalid_operation
+resx540 rescale   1.234       -5000 -> NaN Invalid_operation
+-- [more below]
+
+-- check bounds (lhs maybe out of range for destination, etc.)
+precision:     7
+resx541 rescale   1E+999   +999 -> 1E+999
+resx542 rescale   1E+1000  +999 -> NaN Invalid_operation
+resx543 rescale   1E+999  +1000 -> NaN Invalid_operation
+resx544 rescale   1E-999   -999 -> 1E-999
+resx545 rescale   1E-1000  -999 -> 0E-999    Inexact Rounded
+resx546 rescale   1E-999  -1000 -> 1.0E-999
+resx547 rescale   1E-1005  -999 -> 0E-999    Inexact Rounded
+resx548 rescale   1E-1006  -999 -> 0E-999    Inexact Rounded
+resx549 rescale   1E-1007  -999 -> 0E-999    Inexact Rounded
+resx550 rescale   1E-998  -1005 -> NaN Invalid_operation  -- won't fit
+resx551 rescale   1E-999  -1005 -> 1.000000E-999
+resx552 rescale   1E-1000 -1005 -> 1.00000E-1000 Subnormal
+resx553 rescale   1E-999  -1006 -> NaN Invalid_operation
+resx554 rescale   1E-999  -1007 -> NaN Invalid_operation
+-- related subnormal rounding
+resx555 rescale   1.666666E-999  -1005 -> 1.666666E-999
+resx556 rescale   1.666666E-1000 -1005 -> 1.66667E-1000  Subnormal Inexact Rounded
+resx557 rescale   1.666666E-1001 -1005 -> 1.6667E-1001  Subnormal Inexact Rounded
+resx558 rescale   1.666666E-1002 -1005 -> 1.667E-1002  Subnormal Inexact Rounded
+resx559 rescale   1.666666E-1003 -1005 -> 1.67E-1003  Subnormal Inexact Rounded
+resx560 rescale   1.666666E-1004 -1005 -> 1.7E-1004  Subnormal Inexact Rounded
+resx561 rescale   1.666666E-1005 -1005 -> 2E-1005  Subnormal Inexact Rounded
+resx562 rescale   1.666666E-1006 -1005 -> 0E-1005   Inexact Rounded
+resx563 rescale   1.666666E-1007 -1005 -> 0E-1005   Inexact Rounded
+
+-- fractional RHS, some good and some bad
+precision: 9
+resx564 rescale   222 +2.0           -> 2E+2 Inexact Rounded
+resx565 rescale   222 +2.00000000    -> 2E+2 Inexact Rounded
+resx566 rescale   222 +2.00100000000 -> NaN Invalid_operation
+resx567 rescale   222 +2.000001      -> NaN Invalid_operation
+resx568 rescale   222 +2.000000001   -> NaN Invalid_operation
+resx569 rescale   222 +2.0000000001  -> NaN Invalid_operation
+resx570 rescale   222 +2.00000000001 -> NaN Invalid_operation
+resx571 rescale   222 +2.99999999999 -> NaN Invalid_operation
+resx572 rescale   222 -2.00000000    -> 222.00
+resx573 rescale   222 -2.00100000000 -> NaN Invalid_operation
+resx574 rescale   222 -2.0000001000  -> NaN Invalid_operation
+resx575 rescale   222 -2.00000000001 -> NaN Invalid_operation
+resx576 rescale   222 -2.99999999999 -> NaN Invalid_operation
+
+-- Specials
+resx580 rescale  Inf  -Inf   ->  Infinity
+resx581 rescale  Inf  -1000  ->  NaN  Invalid_operation
+resx582 rescale  Inf  -1     ->  NaN  Invalid_operation
+resx583 rescale  Inf   0     ->  NaN  Invalid_operation
+resx584 rescale  Inf   1     ->  NaN  Invalid_operation
+resx585 rescale  Inf   1000  ->  NaN  Invalid_operation
+resx586 rescale  Inf   Inf   ->  Infinity
+resx587 rescale -1000  Inf   ->  NaN  Invalid_operation
+resx588 rescale -Inf   Inf   ->  -Infinity
+resx589 rescale -1     Inf   ->  NaN  Invalid_operation
+resx590 rescale  0     Inf   ->  NaN  Invalid_operation
+resx591 rescale  1     Inf   ->  NaN  Invalid_operation
+resx592 rescale  1000  Inf   ->  NaN  Invalid_operation
+resx593 rescale  Inf   Inf   ->  Infinity
+resx594 rescale  Inf  -0     ->  NaN  Invalid_operation
+resx595 rescale -0     Inf   ->  NaN  Invalid_operation
+
+resx600 rescale -Inf  -Inf   ->  -Infinity
+resx601 rescale -Inf  -1000  ->  NaN  Invalid_operation
+resx602 rescale -Inf  -1     ->  NaN  Invalid_operation
+resx603 rescale -Inf   0     ->  NaN  Invalid_operation
+resx604 rescale -Inf   1     ->  NaN  Invalid_operation
+resx605 rescale -Inf   1000  ->  NaN  Invalid_operation
+resx606 rescale -Inf   Inf   ->  -Infinity
+resx607 rescale -1000  Inf   ->  NaN  Invalid_operation
+resx608 rescale -Inf  -Inf   ->  -Infinity
+resx609 rescale -1    -Inf   ->  NaN  Invalid_operation
+resx610 rescale  0    -Inf   ->  NaN  Invalid_operation
+resx611 rescale  1    -Inf   ->  NaN  Invalid_operation
+resx612 rescale  1000 -Inf   ->  NaN  Invalid_operation
+resx613 rescale  Inf  -Inf   ->  Infinity
+resx614 rescale -Inf  -0     ->  NaN  Invalid_operation
+resx615 rescale -0    -Inf   ->  NaN  Invalid_operation
+
+resx621 rescale  NaN -Inf    ->  NaN
+resx622 rescale  NaN -1000   ->  NaN
+resx623 rescale  NaN -1      ->  NaN
+resx624 rescale  NaN  0      ->  NaN
+resx625 rescale  NaN  1      ->  NaN
+resx626 rescale  NaN  1000   ->  NaN
+resx627 rescale  NaN  Inf    ->  NaN
+resx628 rescale  NaN  NaN    ->  NaN
+resx629 rescale -Inf  NaN    ->  NaN
+resx630 rescale -1000 NaN    ->  NaN
+resx631 rescale -1    NaN    ->  NaN
+resx632 rescale  0    NaN    ->  NaN
+resx633 rescale  1   -NaN    -> -NaN
+resx634 rescale  1000 NaN    ->  NaN
+resx635 rescale  Inf  NaN    ->  NaN
+resx636 rescale  NaN -0      ->  NaN
+resx637 rescale -0    NaN    ->  NaN
+
+resx641 rescale  sNaN -Inf   ->  NaN  Invalid_operation
+resx642 rescale  sNaN -1000  ->  NaN  Invalid_operation
+resx643 rescale  sNaN -1     ->  NaN  Invalid_operation
+resx644 rescale  sNaN  0     ->  NaN  Invalid_operation
+resx645 rescale  sNaN  1     ->  NaN  Invalid_operation
+resx646 rescale  sNaN  1000  ->  NaN  Invalid_operation
+resx647 rescale -sNaN  NaN   -> -NaN  Invalid_operation
+resx648 rescale  sNaN -sNaN  ->  NaN  Invalid_operation
+resx649 rescale  NaN  sNaN   ->  NaN  Invalid_operation
+resx650 rescale -Inf  sNaN   ->  NaN  Invalid_operation
+resx651 rescale -1000 sNaN   ->  NaN  Invalid_operation
+resx652 rescale -1    sNaN   ->  NaN  Invalid_operation
+resx653 rescale  0    sNaN   ->  NaN  Invalid_operation
+resx654 rescale  1   -sNaN   -> -NaN  Invalid_operation
+resx655 rescale  1000 sNaN   ->  NaN  Invalid_operation
+resx656 rescale  Inf  sNaN   ->  NaN  Invalid_operation
+resx657 rescale  NaN  sNaN   ->  NaN  Invalid_operation
+resx658 rescale  sNaN -0     ->  NaN  Invalid_operation
+resx659 rescale -0    sNaN   ->  NaN  Invalid_operation
+
+-- propagating NaNs
+resx661 rescale  NaN9 -Inf   ->  NaN9
+resx662 rescale  NaN81 919   ->  NaN81
+resx663 rescale  NaN72 Inf   ->  NaN72
+resx664 rescale -NaN66 NaN5  -> -NaN66
+resx665 rescale -Inf   NaN4  ->  NaN4
+resx666 rescale -919   NaN32 ->  NaN32
+resx667 rescale  Inf   NaN2  ->  NaN2
+
+resx671 rescale  sNaN99 -Inf    ->  NaN99 Invalid_operation
+resx672 rescale -sNaN98 -11     -> -NaN98 Invalid_operation
+resx673 rescale  sNaN97  NaN    ->  NaN97 Invalid_operation
+resx674 rescale  sNaN16 sNaN94  ->  NaN16 Invalid_operation
+resx675 rescale  NaN95  sNaN93  ->  NaN93 Invalid_operation
+resx676 rescale -Inf    sNaN92  ->  NaN92 Invalid_operation
+resx677 rescale  088   -sNaN91  -> -NaN91 Invalid_operation
+resx678 rescale  Inf   -sNaN90  -> -NaN90 Invalid_operation
+resx679 rescale  NaN    sNaN87  ->  NaN87 Invalid_operation
+
+-- subnormals and underflow
+precision: 4
+maxexponent: 999
+minexponent: -999
+resx710 rescale  1.00E-999    -999  ->   1E-999    Rounded
+resx711 rescale  0.1E-999    -1000  ->   1E-1000   Subnormal
+resx712 rescale  0.10E-999   -1000  ->   1E-1000   Subnormal Rounded
+resx713 rescale  0.100E-999  -1000  ->   1E-1000   Subnormal Rounded
+resx714 rescale  0.01E-999   -1001  ->   1E-1001   Subnormal
+-- next is rounded to Emin
+resx715 rescale  0.999E-999   -999  ->   1E-999    Inexact Rounded
+resx716 rescale  0.099E-999  -1000  ->   1E-1000   Inexact Rounded Subnormal
+
+resx717 rescale  0.009E-999  -1001  ->   1E-1001   Inexact Rounded Subnormal
+resx718 rescale  0.001E-999  -1001  ->   0E-1001   Inexact Rounded
+resx719 rescale  0.0009E-999 -1001  ->   0E-1001   Inexact Rounded
+resx720 rescale  0.0001E-999 -1001  ->   0E-1001   Inexact Rounded
+
+resx730 rescale -1.00E-999   -999  ->  -1E-999     Rounded
+resx731 rescale -0.1E-999    -999  ->  -0E-999     Rounded Inexact
+resx732 rescale -0.10E-999   -999  ->  -0E-999     Rounded Inexact
+resx733 rescale -0.100E-999  -999  ->  -0E-999     Rounded Inexact
+resx734 rescale -0.01E-999   -999  ->  -0E-999     Inexact Rounded
+-- next is rounded to Emin
+resx735 rescale -0.999E-999  -999  ->  -1E-999     Inexact Rounded
+resx736 rescale -0.099E-999  -999  ->  -0E-999     Inexact Rounded
+resx737 rescale -0.009E-999  -999  ->  -0E-999     Inexact Rounded
+resx738 rescale -0.001E-999  -999  ->  -0E-999     Inexact Rounded
+resx739 rescale -0.0001E-999 -999  ->  -0E-999     Inexact Rounded
+
+resx740 rescale -1.00E-999   -1000 ->  -1.0E-999   Rounded
+resx741 rescale -0.1E-999    -1000 ->  -1E-1000    Subnormal
+resx742 rescale -0.10E-999   -1000 ->  -1E-1000    Subnormal Rounded
+resx743 rescale -0.100E-999  -1000 ->  -1E-1000    Subnormal Rounded
+resx744 rescale -0.01E-999   -1000 ->  -0E-1000    Inexact Rounded
+-- next is rounded to Emin
+resx745 rescale -0.999E-999  -1000 ->  -1.0E-999   Inexact Rounded
+resx746 rescale -0.099E-999  -1000 ->  -1E-1000    Inexact Rounded Subnormal
+resx747 rescale -0.009E-999  -1000 ->  -0E-1000    Inexact Rounded
+resx748 rescale -0.001E-999  -1000 ->  -0E-1000    Inexact Rounded
+resx749 rescale -0.0001E-999 -1000 ->  -0E-1000    Inexact Rounded
+
+resx750 rescale -1.00E-999   -1001 ->  -1.00E-999
+resx751 rescale -0.1E-999    -1001 ->  -1.0E-1000  Subnormal
+resx752 rescale -0.10E-999   -1001 ->  -1.0E-1000  Subnormal
+resx753 rescale -0.100E-999  -1001 ->  -1.0E-1000  Subnormal Rounded
+resx754 rescale -0.01E-999   -1001 ->  -1E-1001    Subnormal
+-- next is rounded to Emin
+resx755 rescale -0.999E-999  -1001 ->  -1.00E-999  Inexact Rounded
+resx756 rescale -0.099E-999  -1001 ->  -1.0E-1000  Inexact Rounded Subnormal
+resx757 rescale -0.009E-999  -1001 ->  -1E-1001    Inexact Rounded Subnormal
+resx758 rescale -0.001E-999  -1001 ->  -0E-1001    Inexact Rounded
+resx759 rescale -0.0001E-999 -1001 ->  -0E-1001    Inexact Rounded
+
+resx760 rescale -1.00E-999   -1002 ->  -1.000E-999
+resx761 rescale -0.1E-999    -1002 ->  -1.00E-1000  Subnormal
+resx762 rescale -0.10E-999   -1002 ->  -1.00E-1000  Subnormal
+resx763 rescale -0.100E-999  -1002 ->  -1.00E-1000  Subnormal
+resx764 rescale -0.01E-999   -1002 ->  -1.0E-1001   Subnormal
+resx765 rescale -0.999E-999  -1002 ->  -9.99E-1000  Subnormal
+resx766 rescale -0.099E-999  -1002 ->  -9.9E-1001   Subnormal
+resx767 rescale -0.009E-999  -1002 ->  -9E-1002     Subnormal
+resx768 rescale -0.001E-999  -1002 ->  -1E-1002     Subnormal
+resx769 rescale -0.0001E-999 -1002 ->  -0E-1002     Inexact Rounded
+
+-- rhs must be no less than Etiny
+resx770 rescale -1.00E-999   -1003 ->  NaN Invalid_operation
+resx771 rescale -0.1E-999    -1003 ->  NaN Invalid_operation
+resx772 rescale -0.10E-999   -1003 ->  NaN Invalid_operation
+resx773 rescale -0.100E-999  -1003 ->  NaN Invalid_operation
+resx774 rescale -0.01E-999   -1003 ->  NaN Invalid_operation
+resx775 rescale -0.999E-999  -1003 ->  NaN Invalid_operation
+resx776 rescale -0.099E-999  -1003 ->  NaN Invalid_operation
+resx777 rescale -0.009E-999  -1003 ->  NaN Invalid_operation
+resx778 rescale -0.001E-999  -1003 ->  NaN Invalid_operation
+resx779 rescale -0.0001E-999 -1003 ->  NaN Invalid_operation
+
+precision:   9
+maxExponent: 999999999
+minexponent: -999999999
+
+-- getInt worries
+resx801 rescale   0   1000000000 -> NaN Invalid_operation
+resx802 rescale   0  -1000000000 -> 0E-1000000000
+resx803 rescale   0   2000000000 -> NaN Invalid_operation
+resx804 rescale   0  -2000000000 -> NaN Invalid_operation
+resx805 rescale   0   3000000000 -> NaN Invalid_operation
+resx806 rescale   0  -3000000000 -> NaN Invalid_operation
+resx807 rescale   0   4000000000 -> NaN Invalid_operation
+resx808 rescale   0  -4000000000 -> NaN Invalid_operation
+resx809 rescale   0   5000000000 -> NaN Invalid_operation
+resx810 rescale   0  -5000000000 -> NaN Invalid_operation
+resx811 rescale   0   6000000000 -> NaN Invalid_operation
+resx812 rescale   0  -6000000000 -> NaN Invalid_operation
+resx813 rescale   0   7000000000 -> NaN Invalid_operation
+resx814 rescale   0  -7000000000 -> NaN Invalid_operation
+resx815 rescale   0   8000000000 -> NaN Invalid_operation
+resx816 rescale   0  -8000000000 -> NaN Invalid_operation
+resx817 rescale   0   9000000000 -> NaN Invalid_operation
+resx818 rescale   0  -9000000000 -> NaN Invalid_operation
+resx819 rescale   0   9999999999 -> NaN Invalid_operation
+resx820 rescale   0  -9999999999 -> NaN Invalid_operation
+resx821 rescale   0   10000000000 -> NaN Invalid_operation
+resx822 rescale   0  -10000000000 -> NaN Invalid_operation
+
+resx831 rescale   1   0E-1       -> 1
+resx832 rescale   1   0E-2       -> 1
+resx833 rescale   1   0E-3       -> 1
+resx834 rescale   1   0E-4       -> 1
+resx835 rescale   1   0E-100     -> 1
+resx836 rescale   1   0E-100000  -> 1
+resx837 rescale   1   0E+100     -> 1
+resx838 rescale   1   0E+100000  -> 1
+
+resx841 rescale   0   5E-1000000 -> NaN Invalid_operation
+resx842 rescale   0   5E-1000000 -> NaN Invalid_operation
+resx843 rescale   0    999999999 -> 0E+999999999
+resx844 rescale   0   1000000000 -> NaN Invalid_operation
+resx845 rescale   0   -999999999 -> 0E-999999999
+resx846 rescale   0  -1000000000 -> 0E-1000000000
+resx847 rescale   0  -1000000001 -> 0E-1000000001
+resx848 rescale   0  -1000000002 -> 0E-1000000002
+resx849 rescale   0  -1000000003 -> 0E-1000000003
+resx850 rescale   0  -1000000004 -> 0E-1000000004
+resx851 rescale   0  -1000000005 -> 0E-1000000005
+resx852 rescale   0  -1000000006 -> 0E-1000000006
+resx853 rescale   0  -1000000007 -> 0E-1000000007
+resx854 rescale   0  -1000000008 -> NaN Invalid_operation
+
+resx861 rescale   1  +2147483649 -> NaN Invalid_operation
+resx862 rescale   1  +2147483648 -> NaN Invalid_operation
+resx863 rescale   1  +2147483647 -> NaN Invalid_operation
+resx864 rescale   1  -2147483647 -> NaN Invalid_operation
+resx865 rescale   1  -2147483648 -> NaN Invalid_operation
+resx866 rescale   1  -2147483649 -> NaN Invalid_operation
+
+-- Null tests
+res900 rescale 10  # -> NaN Invalid_operation
+res901 rescale  # 10 -> NaN Invalid_operation

Added: vendor/Python/current/Lib/test/decimaltestdata/rounding.decTest
===================================================================
--- vendor/Python/current/Lib/test/decimaltestdata/rounding.decTest	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/decimaltestdata/rounding.decTest	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1079 @@
+------------------------------------------------------------------------
+-- rounding.decTest -- decimal rounding modes testcases               --
+-- Copyright (c) IBM Corporation, 1981, 2003.  All rights reserved.   --
+------------------------------------------------------------------------
+-- Please see the document "General Decimal Arithmetic Testcases"     --
+-- at http://www2.hursley.ibm.com/decimal for the description of      --
+-- these testcases.                                                   --
+--                                                                    --
+-- These testcases are experimental ('beta' versions), and they       --
+-- may contain errors.  They are offered on an as-is basis.  In       --
+-- particular, achieving the same results as the tests here is not    --
+-- a guarantee that an implementation complies with any Standard      --
+-- or specification.  The tests are not exhaustive.                   --
+--                                                                    --
+-- Please send comments, suggestions, and corrections to the author:  --
+--   Mike Cowlishaw, IBM Fellow                                       --
+--   IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK         --
+--   mfc at uk.ibm.com                                                   --
+------------------------------------------------------------------------
+version: 2.39
+
+-- These tests require that implementations take account of residues in
+-- order to get correct results for some rounding modes.  Rather than
+-- single rounding tests we therefore need tests for most operators.
+-- [We do assume add/minus/plus/subtract are common paths, however, as
+-- is rounding of negatives (if the latter works for addition, assume it
+-- works for the others, too).]
+--
+-- Underflow Subnormal and overflow behaviours are tested under the individual
+-- operators.
+
+extended:    1
+precision:   5           -- for easier visual inspection
+maxExponent: 999
+minexponent: -999
+
+-- Addition operators -------------------------------------------------
+rounding: down
+
+radx100  add 12345 -0.1       -> 12344 Inexact Rounded
+radx101  add 12345 -0.01      -> 12344 Inexact Rounded
+radx102  add 12345 -0.001     -> 12344 Inexact Rounded
+radx103  add 12345 -0.00001   -> 12344 Inexact Rounded
+radx104  add 12345 -0.000001  -> 12344 Inexact Rounded
+radx105  add 12345 -0.0000001 -> 12344 Inexact Rounded
+radx106  add 12345  0         -> 12345
+radx107  add 12345  0.0000001 -> 12345 Inexact Rounded
+radx108  add 12345  0.000001  -> 12345 Inexact Rounded
+radx109  add 12345  0.00001   -> 12345 Inexact Rounded
+radx110  add 12345  0.0001    -> 12345 Inexact Rounded
+radx111  add 12345  0.001     -> 12345 Inexact Rounded
+radx112  add 12345  0.01      -> 12345 Inexact Rounded
+radx113  add 12345  0.1       -> 12345 Inexact Rounded
+
+radx115  add 12346  0.49999   -> 12346 Inexact Rounded
+radx116  add 12346  0.5       -> 12346 Inexact Rounded
+radx117  add 12346  0.50001   -> 12346 Inexact Rounded
+
+radx120  add 12345  0.4       -> 12345 Inexact Rounded
+radx121  add 12345  0.49      -> 12345 Inexact Rounded
+radx122  add 12345  0.499     -> 12345 Inexact Rounded
+radx123  add 12345  0.49999   -> 12345 Inexact Rounded
+radx124  add 12345  0.5       -> 12345 Inexact Rounded
+radx125  add 12345  0.50001   -> 12345 Inexact Rounded
+radx126  add 12345  0.5001    -> 12345 Inexact Rounded
+radx127  add 12345  0.501     -> 12345 Inexact Rounded
+radx128  add 12345  0.51      -> 12345 Inexact Rounded
+radx129  add 12345  0.6       -> 12345 Inexact Rounded
+
+rounding: half_down
+
+radx140  add 12345 -0.1       -> 12345 Inexact Rounded
+radx141  add 12345 -0.01      -> 12345 Inexact Rounded
+radx142  add 12345 -0.001     -> 12345 Inexact Rounded
+radx143  add 12345 -0.00001   -> 12345 Inexact Rounded
+radx144  add 12345 -0.000001  -> 12345 Inexact Rounded
+radx145  add 12345 -0.0000001 -> 12345 Inexact Rounded
+radx146  add 12345  0         -> 12345
+radx147  add 12345  0.0000001 -> 12345 Inexact Rounded
+radx148  add 12345  0.000001  -> 12345 Inexact Rounded
+radx149  add 12345  0.00001   -> 12345 Inexact Rounded
+radx150  add 12345  0.0001    -> 12345 Inexact Rounded
+radx151  add 12345  0.001     -> 12345 Inexact Rounded
+radx152  add 12345  0.01      -> 12345 Inexact Rounded
+radx153  add 12345  0.1       -> 12345 Inexact Rounded
+
+radx155  add 12346  0.49999   -> 12346 Inexact Rounded
+radx156  add 12346  0.5       -> 12346 Inexact Rounded
+radx157  add 12346  0.50001   -> 12347 Inexact Rounded
+
+radx160  add 12345  0.4       -> 12345 Inexact Rounded
+radx161  add 12345  0.49      -> 12345 Inexact Rounded
+radx162  add 12345  0.499     -> 12345 Inexact Rounded
+radx163  add 12345  0.49999   -> 12345 Inexact Rounded
+radx164  add 12345  0.5       -> 12345 Inexact Rounded
+radx165  add 12345  0.50001   -> 12346 Inexact Rounded
+radx166  add 12345  0.5001    -> 12346 Inexact Rounded
+radx167  add 12345  0.501     -> 12346 Inexact Rounded
+radx168  add 12345  0.51      -> 12346 Inexact Rounded
+radx169  add 12345  0.6       -> 12346 Inexact Rounded
+
+rounding: half_even
+
+radx170  add 12345 -0.1       -> 12345 Inexact Rounded
+radx171  add 12345 -0.01      -> 12345 Inexact Rounded
+radx172  add 12345 -0.001     -> 12345 Inexact Rounded
+radx173  add 12345 -0.00001   -> 12345 Inexact Rounded
+radx174  add 12345 -0.000001  -> 12345 Inexact Rounded
+radx175  add 12345 -0.0000001 -> 12345 Inexact Rounded
+radx176  add 12345  0         -> 12345
+radx177  add 12345  0.0000001 -> 12345 Inexact Rounded
+radx178  add 12345  0.000001  -> 12345 Inexact Rounded
+radx179  add 12345  0.00001   -> 12345 Inexact Rounded
+radx180  add 12345  0.0001    -> 12345 Inexact Rounded
+radx181  add 12345  0.001     -> 12345 Inexact Rounded
+radx182  add 12345  0.01      -> 12345 Inexact Rounded
+radx183  add 12345  0.1       -> 12345 Inexact Rounded
+
+radx185  add 12346  0.49999   -> 12346 Inexact Rounded
+radx186  add 12346  0.5       -> 12346 Inexact Rounded
+radx187  add 12346  0.50001   -> 12347 Inexact Rounded
+
+radx190  add 12345  0.4       -> 12345 Inexact Rounded
+radx191  add 12345  0.49      -> 12345 Inexact Rounded
+radx192  add 12345  0.499     -> 12345 Inexact Rounded
+radx193  add 12345  0.49999   -> 12345 Inexact Rounded
+radx194  add 12345  0.5       -> 12346 Inexact Rounded
+radx195  add 12345  0.50001   -> 12346 Inexact Rounded
+radx196  add 12345  0.5001    -> 12346 Inexact Rounded
+radx197  add 12345  0.501     -> 12346 Inexact Rounded
+radx198  add 12345  0.51      -> 12346 Inexact Rounded
+radx199  add 12345  0.6       -> 12346 Inexact Rounded
+
+rounding: half_up
+
+radx200  add 12345 -0.1       -> 12345 Inexact Rounded
+radx201  add 12345 -0.01      -> 12345 Inexact Rounded
+radx202  add 12345 -0.001     -> 12345 Inexact Rounded
+radx203  add 12345 -0.00001   -> 12345 Inexact Rounded
+radx204  add 12345 -0.000001  -> 12345 Inexact Rounded
+radx205  add 12345 -0.0000001 -> 12345 Inexact Rounded
+radx206  add 12345  0         -> 12345
+radx207  add 12345  0.0000001 -> 12345 Inexact Rounded
+radx208  add 12345  0.000001  -> 12345 Inexact Rounded
+radx209  add 12345  0.00001   -> 12345 Inexact Rounded
+radx210  add 12345  0.0001    -> 12345 Inexact Rounded
+radx211  add 12345  0.001     -> 12345 Inexact Rounded
+radx212  add 12345  0.01      -> 12345 Inexact Rounded
+radx213  add 12345  0.1       -> 12345 Inexact Rounded
+
+radx215  add 12346  0.49999   -> 12346 Inexact Rounded
+radx216  add 12346  0.5       -> 12347 Inexact Rounded
+radx217  add 12346  0.50001   -> 12347 Inexact Rounded
+
+radx220  add 12345  0.4       -> 12345 Inexact Rounded
+radx221  add 12345  0.49      -> 12345 Inexact Rounded
+radx222  add 12345  0.499     -> 12345 Inexact Rounded
+radx223  add 12345  0.49999   -> 12345 Inexact Rounded
+radx224  add 12345  0.5       -> 12346 Inexact Rounded
+radx225  add 12345  0.50001   -> 12346 Inexact Rounded
+radx226  add 12345  0.5001    -> 12346 Inexact Rounded
+radx227  add 12345  0.501     -> 12346 Inexact Rounded
+radx228  add 12345  0.51      -> 12346 Inexact Rounded
+radx229  add 12345  0.6       -> 12346 Inexact Rounded
+
+rounding: up
+
+radx230  add 12345 -0.1       -> 12345 Inexact Rounded
+radx231  add 12345 -0.01      -> 12345 Inexact Rounded
+radx232  add 12345 -0.001     -> 12345 Inexact Rounded
+radx233  add 12345 -0.00001   -> 12345 Inexact Rounded
+radx234  add 12345 -0.000001  -> 12345 Inexact Rounded
+radx235  add 12345 -0.0000001 -> 12345 Inexact Rounded
+radx236  add 12345  0         -> 12345
+radx237  add 12345  0.0000001 -> 12346 Inexact Rounded
+radx238  add 12345  0.000001  -> 12346 Inexact Rounded
+radx239  add 12345  0.00001   -> 12346 Inexact Rounded
+radx240  add 12345  0.0001    -> 12346 Inexact Rounded
+radx241  add 12345  0.001     -> 12346 Inexact Rounded
+radx242  add 12345  0.01      -> 12346 Inexact Rounded
+radx243  add 12345  0.1       -> 12346 Inexact Rounded
+
+radx245  add 12346  0.49999   -> 12347 Inexact Rounded
+radx246  add 12346  0.5       -> 12347 Inexact Rounded
+radx247  add 12346  0.50001   -> 12347 Inexact Rounded
+
+radx250  add 12345  0.4       -> 12346 Inexact Rounded
+radx251  add 12345  0.49      -> 12346 Inexact Rounded
+radx252  add 12345  0.499     -> 12346 Inexact Rounded
+radx253  add 12345  0.49999   -> 12346 Inexact Rounded
+radx254  add 12345  0.5       -> 12346 Inexact Rounded
+radx255  add 12345  0.50001   -> 12346 Inexact Rounded
+radx256  add 12345  0.5001    -> 12346 Inexact Rounded
+radx257  add 12345  0.501     -> 12346 Inexact Rounded
+radx258  add 12345  0.51      -> 12346 Inexact Rounded
+radx259  add 12345  0.6       -> 12346 Inexact Rounded
+
+rounding: floor
+
+radx300  add 12345 -0.1       -> 12344 Inexact Rounded
+radx301  add 12345 -0.01      -> 12344 Inexact Rounded
+radx302  add 12345 -0.001     -> 12344 Inexact Rounded
+radx303  add 12345 -0.00001   -> 12344 Inexact Rounded
+radx304  add 12345 -0.000001  -> 12344 Inexact Rounded
+radx305  add 12345 -0.0000001 -> 12344 Inexact Rounded
+radx306  add 12345  0         -> 12345
+radx307  add 12345  0.0000001 -> 12345 Inexact Rounded
+radx308  add 12345  0.000001  -> 12345 Inexact Rounded
+radx309  add 12345  0.00001   -> 12345 Inexact Rounded
+radx310  add 12345  0.0001    -> 12345 Inexact Rounded
+radx311  add 12345  0.001     -> 12345 Inexact Rounded
+radx312  add 12345  0.01      -> 12345 Inexact Rounded
+radx313  add 12345  0.1       -> 12345 Inexact Rounded
+
+radx315  add 12346  0.49999   -> 12346 Inexact Rounded
+radx316  add 12346  0.5       -> 12346 Inexact Rounded
+radx317  add 12346  0.50001   -> 12346 Inexact Rounded
+
+radx320  add 12345  0.4       -> 12345 Inexact Rounded
+radx321  add 12345  0.49      -> 12345 Inexact Rounded
+radx322  add 12345  0.499     -> 12345 Inexact Rounded
+radx323  add 12345  0.49999   -> 12345 Inexact Rounded
+radx324  add 12345  0.5       -> 12345 Inexact Rounded
+radx325  add 12345  0.50001   -> 12345 Inexact Rounded
+radx326  add 12345  0.5001    -> 12345 Inexact Rounded
+radx327  add 12345  0.501     -> 12345 Inexact Rounded
+radx328  add 12345  0.51      -> 12345 Inexact Rounded
+radx329  add 12345  0.6       -> 12345 Inexact Rounded
+
+rounding: ceiling
+
+radx330  add 12345 -0.1       -> 12345 Inexact Rounded
+radx331  add 12345 -0.01      -> 12345 Inexact Rounded
+radx332  add 12345 -0.001     -> 12345 Inexact Rounded
+radx333  add 12345 -0.00001   -> 12345 Inexact Rounded
+radx334  add 12345 -0.000001  -> 12345 Inexact Rounded
+radx335  add 12345 -0.0000001 -> 12345 Inexact Rounded
+radx336  add 12345  0         -> 12345
+radx337  add 12345  0.0000001 -> 12346 Inexact Rounded
+radx338  add 12345  0.000001  -> 12346 Inexact Rounded
+radx339  add 12345  0.00001   -> 12346 Inexact Rounded
+radx340  add 12345  0.0001    -> 12346 Inexact Rounded
+radx341  add 12345  0.001     -> 12346 Inexact Rounded
+radx342  add 12345  0.01      -> 12346 Inexact Rounded
+radx343  add 12345  0.1       -> 12346 Inexact Rounded
+
+radx345  add 12346  0.49999   -> 12347 Inexact Rounded
+radx346  add 12346  0.5       -> 12347 Inexact Rounded
+radx347  add 12346  0.50001   -> 12347 Inexact Rounded
+
+radx350  add 12345  0.4       -> 12346 Inexact Rounded
+radx351  add 12345  0.49      -> 12346 Inexact Rounded
+radx352  add 12345  0.499     -> 12346 Inexact Rounded
+radx353  add 12345  0.49999   -> 12346 Inexact Rounded
+radx354  add 12345  0.5       -> 12346 Inexact Rounded
+radx355  add 12345  0.50001   -> 12346 Inexact Rounded
+radx356  add 12345  0.5001    -> 12346 Inexact Rounded
+radx357  add 12345  0.501     -> 12346 Inexact Rounded
+radx358  add 12345  0.51      -> 12346 Inexact Rounded
+radx359  add 12345  0.6       -> 12346 Inexact Rounded
+
+-- negatives...
+
+rounding: down
+
+rsux100  add -12345 -0.1       -> -12345 Inexact Rounded
+rsux101  add -12345 -0.01      -> -12345 Inexact Rounded
+rsux102  add -12345 -0.001     -> -12345 Inexact Rounded
+rsux103  add -12345 -0.00001   -> -12345 Inexact Rounded
+rsux104  add -12345 -0.000001  -> -12345 Inexact Rounded
+rsux105  add -12345 -0.0000001 -> -12345 Inexact Rounded
+rsux106  add -12345  0         -> -12345
+rsux107  add -12345  0.0000001 -> -12344 Inexact Rounded
+rsux108  add -12345  0.000001  -> -12344 Inexact Rounded
+rsux109  add -12345  0.00001   -> -12344 Inexact Rounded
+rsux110  add -12345  0.0001    -> -12344 Inexact Rounded
+rsux111  add -12345  0.001     -> -12344 Inexact Rounded
+rsux112  add -12345  0.01      -> -12344 Inexact Rounded
+rsux113  add -12345  0.1       -> -12344 Inexact Rounded
+
+rsux115  add -12346  0.49999   -> -12345 Inexact Rounded
+rsux116  add -12346  0.5       -> -12345 Inexact Rounded
+rsux117  add -12346  0.50001   -> -12345 Inexact Rounded
+
+rsux120  add -12345  0.4       -> -12344 Inexact Rounded
+rsux121  add -12345  0.49      -> -12344 Inexact Rounded
+rsux122  add -12345  0.499     -> -12344 Inexact Rounded
+rsux123  add -12345  0.49999   -> -12344 Inexact Rounded
+rsux124  add -12345  0.5       -> -12344 Inexact Rounded
+rsux125  add -12345  0.50001   -> -12344 Inexact Rounded
+rsux126  add -12345  0.5001    -> -12344 Inexact Rounded
+rsux127  add -12345  0.501     -> -12344 Inexact Rounded
+rsux128  add -12345  0.51      -> -12344 Inexact Rounded
+rsux129  add -12345  0.6       -> -12344 Inexact Rounded
+
+rounding: half_down
+
+rsux140  add -12345 -0.1       -> -12345 Inexact Rounded
+rsux141  add -12345 -0.01      -> -12345 Inexact Rounded
+rsux142  add -12345 -0.001     -> -12345 Inexact Rounded
+rsux143  add -12345 -0.00001   -> -12345 Inexact Rounded
+rsux144  add -12345 -0.000001  -> -12345 Inexact Rounded
+rsux145  add -12345 -0.0000001 -> -12345 Inexact Rounded
+rsux146  add -12345  0         -> -12345
+rsux147  add -12345  0.0000001 -> -12345 Inexact Rounded
+rsux148  add -12345  0.000001  -> -12345 Inexact Rounded
+rsux149  add -12345  0.00001   -> -12345 Inexact Rounded
+rsux150  add -12345  0.0001    -> -12345 Inexact Rounded
+rsux151  add -12345  0.001     -> -12345 Inexact Rounded
+rsux152  add -12345  0.01      -> -12345 Inexact Rounded
+rsux153  add -12345  0.1       -> -12345 Inexact Rounded
+
+rsux155  add -12346  0.49999   -> -12346 Inexact Rounded
+rsux156  add -12346  0.5       -> -12345 Inexact Rounded
+rsux157  add -12346  0.50001   -> -12345 Inexact Rounded
+
+rsux160  add -12345  0.4       -> -12345 Inexact Rounded
+rsux161  add -12345  0.49      -> -12345 Inexact Rounded
+rsux162  add -12345  0.499     -> -12345 Inexact Rounded
+rsux163  add -12345  0.49999   -> -12345 Inexact Rounded
+rsux164  add -12345  0.5       -> -12344 Inexact Rounded
+rsux165  add -12345  0.50001   -> -12344 Inexact Rounded
+rsux166  add -12345  0.5001    -> -12344 Inexact Rounded
+rsux167  add -12345  0.501     -> -12344 Inexact Rounded
+rsux168  add -12345  0.51      -> -12344 Inexact Rounded
+rsux169  add -12345  0.6       -> -12344 Inexact Rounded
+
+rounding: half_even
+
+rsux170  add -12345 -0.1       -> -12345 Inexact Rounded
+rsux171  add -12345 -0.01      -> -12345 Inexact Rounded
+rsux172  add -12345 -0.001     -> -12345 Inexact Rounded
+rsux173  add -12345 -0.00001   -> -12345 Inexact Rounded
+rsux174  add -12345 -0.000001  -> -12345 Inexact Rounded
+rsux175  add -12345 -0.0000001 -> -12345 Inexact Rounded
+rsux176  add -12345  0         -> -12345
+rsux177  add -12345  0.0000001 -> -12345 Inexact Rounded
+rsux178  add -12345  0.000001  -> -12345 Inexact Rounded
+rsux179  add -12345  0.00001   -> -12345 Inexact Rounded
+rsux180  add -12345  0.0001    -> -12345 Inexact Rounded
+rsux181  add -12345  0.001     -> -12345 Inexact Rounded
+rsux182  add -12345  0.01      -> -12345 Inexact Rounded
+rsux183  add -12345  0.1       -> -12345 Inexact Rounded
+
+rsux185  add -12346  0.49999   -> -12346 Inexact Rounded
+rsux186  add -12346  0.5       -> -12346 Inexact Rounded
+rsux187  add -12346  0.50001   -> -12345 Inexact Rounded
+
+rsux190  add -12345  0.4       -> -12345 Inexact Rounded
+rsux191  add -12345  0.49      -> -12345 Inexact Rounded
+rsux192  add -12345  0.499     -> -12345 Inexact Rounded
+rsux193  add -12345  0.49999   -> -12345 Inexact Rounded
+rsux194  add -12345  0.5       -> -12344 Inexact Rounded
+rsux195  add -12345  0.50001   -> -12344 Inexact Rounded
+rsux196  add -12345  0.5001    -> -12344 Inexact Rounded
+rsux197  add -12345  0.501     -> -12344 Inexact Rounded
+rsux198  add -12345  0.51      -> -12344 Inexact Rounded
+rsux199  add -12345  0.6       -> -12344 Inexact Rounded
+
+rounding: half_up
+
+rsux200  add -12345 -0.1       -> -12345 Inexact Rounded
+rsux201  add -12345 -0.01      -> -12345 Inexact Rounded
+rsux202  add -12345 -0.001     -> -12345 Inexact Rounded
+rsux203  add -12345 -0.00001   -> -12345 Inexact Rounded
+rsux204  add -12345 -0.000001  -> -12345 Inexact Rounded
+rsux205  add -12345 -0.0000001 -> -12345 Inexact Rounded
+rsux206  add -12345  0         -> -12345
+rsux207  add -12345  0.0000001 -> -12345 Inexact Rounded
+rsux208  add -12345  0.000001  -> -12345 Inexact Rounded
+rsux209  add -12345  0.00001   -> -12345 Inexact Rounded
+rsux210  add -12345  0.0001    -> -12345 Inexact Rounded
+rsux211  add -12345  0.001     -> -12345 Inexact Rounded
+rsux212  add -12345  0.01      -> -12345 Inexact Rounded
+rsux213  add -12345  0.1       -> -12345 Inexact Rounded
+
+rsux215  add -12346  0.49999   -> -12346 Inexact Rounded
+rsux216  add -12346  0.5       -> -12346 Inexact Rounded
+rsux217  add -12346  0.50001   -> -12345 Inexact Rounded
+
+rsux220  add -12345  0.4       -> -12345 Inexact Rounded
+rsux221  add -12345  0.49      -> -12345 Inexact Rounded
+rsux222  add -12345  0.499     -> -12345 Inexact Rounded
+rsux223  add -12345  0.49999   -> -12345 Inexact Rounded
+rsux224  add -12345  0.5       -> -12345 Inexact Rounded
+rsux225  add -12345  0.50001   -> -12344 Inexact Rounded
+rsux226  add -12345  0.5001    -> -12344 Inexact Rounded
+rsux227  add -12345  0.501     -> -12344 Inexact Rounded
+rsux228  add -12345  0.51      -> -12344 Inexact Rounded
+rsux229  add -12345  0.6       -> -12344 Inexact Rounded
+
+rounding: up
+
+rsux230  add -12345 -0.1       -> -12346 Inexact Rounded
+rsux231  add -12345 -0.01      -> -12346 Inexact Rounded
+rsux232  add -12345 -0.001     -> -12346 Inexact Rounded
+rsux233  add -12345 -0.00001   -> -12346 Inexact Rounded
+rsux234  add -12345 -0.000001  -> -12346 Inexact Rounded
+rsux235  add -12345 -0.0000001 -> -12346 Inexact Rounded
+rsux236  add -12345  0         -> -12345
+rsux237  add -12345  0.0000001 -> -12345 Inexact Rounded
+rsux238  add -12345  0.000001  -> -12345 Inexact Rounded
+rsux239  add -12345  0.00001   -> -12345 Inexact Rounded
+rsux240  add -12345  0.0001    -> -12345 Inexact Rounded
+rsux241  add -12345  0.001     -> -12345 Inexact Rounded
+rsux242  add -12345  0.01      -> -12345 Inexact Rounded
+rsux243  add -12345  0.1       -> -12345 Inexact Rounded
+
+rsux245  add -12346  0.49999   -> -12346 Inexact Rounded
+rsux246  add -12346  0.5       -> -12346 Inexact Rounded
+rsux247  add -12346  0.50001   -> -12346 Inexact Rounded
+
+rsux250  add -12345  0.4       -> -12345 Inexact Rounded
+rsux251  add -12345  0.49      -> -12345 Inexact Rounded
+rsux252  add -12345  0.499     -> -12345 Inexact Rounded
+rsux253  add -12345  0.49999   -> -12345 Inexact Rounded
+rsux254  add -12345  0.5       -> -12345 Inexact Rounded
+rsux255  add -12345  0.50001   -> -12345 Inexact Rounded
+rsux256  add -12345  0.5001    -> -12345 Inexact Rounded
+rsux257  add -12345  0.501     -> -12345 Inexact Rounded
+rsux258  add -12345  0.51      -> -12345 Inexact Rounded
+rsux259  add -12345  0.6       -> -12345 Inexact Rounded
+
+rounding: floor
+
+rsux300  add -12345 -0.1       -> -12346 Inexact Rounded
+rsux301  add -12345 -0.01      -> -12346 Inexact Rounded
+rsux302  add -12345 -0.001     -> -12346 Inexact Rounded
+rsux303  add -12345 -0.00001   -> -12346 Inexact Rounded
+rsux304  add -12345 -0.000001  -> -12346 Inexact Rounded
+rsux305  add -12345 -0.0000001 -> -12346 Inexact Rounded
+rsux306  add -12345  0         -> -12345
+rsux307  add -12345  0.0000001 -> -12345 Inexact Rounded
+rsux308  add -12345  0.000001  -> -12345 Inexact Rounded
+rsux309  add -12345  0.00001   -> -12345 Inexact Rounded
+rsux310  add -12345  0.0001    -> -12345 Inexact Rounded
+rsux311  add -12345  0.001     -> -12345 Inexact Rounded
+rsux312  add -12345  0.01      -> -12345 Inexact Rounded
+rsux313  add -12345  0.1       -> -12345 Inexact Rounded
+
+rsux315  add -12346  0.49999   -> -12346 Inexact Rounded
+rsux316  add -12346  0.5       -> -12346 Inexact Rounded
+rsux317  add -12346  0.50001   -> -12346 Inexact Rounded
+
+rsux320  add -12345  0.4       -> -12345 Inexact Rounded
+rsux321  add -12345  0.49      -> -12345 Inexact Rounded
+rsux322  add -12345  0.499     -> -12345 Inexact Rounded
+rsux323  add -12345  0.49999   -> -12345 Inexact Rounded
+rsux324  add -12345  0.5       -> -12345 Inexact Rounded
+rsux325  add -12345  0.50001   -> -12345 Inexact Rounded
+rsux326  add -12345  0.5001    -> -12345 Inexact Rounded
+rsux327  add -12345  0.501     -> -12345 Inexact Rounded
+rsux328  add -12345  0.51      -> -12345 Inexact Rounded
+rsux329  add -12345  0.6       -> -12345 Inexact Rounded
+
+rounding: ceiling
+
+rsux330  add -12345 -0.1       -> -12345 Inexact Rounded
+rsux331  add -12345 -0.01      -> -12345 Inexact Rounded
+rsux332  add -12345 -0.001     -> -12345 Inexact Rounded
+rsux333  add -12345 -0.00001   -> -12345 Inexact Rounded
+rsux334  add -12345 -0.000001  -> -12345 Inexact Rounded
+rsux335  add -12345 -0.0000001 -> -12345 Inexact Rounded
+rsux336  add -12345  0         -> -12345
+rsux337  add -12345  0.0000001 -> -12344 Inexact Rounded
+rsux338  add -12345  0.000001  -> -12344 Inexact Rounded
+rsux339  add -12345  0.00001   -> -12344 Inexact Rounded
+rsux340  add -12345  0.0001    -> -12344 Inexact Rounded
+rsux341  add -12345  0.001     -> -12344 Inexact Rounded
+rsux342  add -12345  0.01      -> -12344 Inexact Rounded
+rsux343  add -12345  0.1       -> -12344 Inexact Rounded
+
+rsux345  add -12346  0.49999   -> -12345 Inexact Rounded
+rsux346  add -12346  0.5       -> -12345 Inexact Rounded
+rsux347  add -12346  0.50001   -> -12345 Inexact Rounded
+
+rsux350  add -12345  0.4       -> -12344 Inexact Rounded
+rsux351  add -12345  0.49      -> -12344 Inexact Rounded
+rsux352  add -12345  0.499     -> -12344 Inexact Rounded
+rsux353  add -12345  0.49999   -> -12344 Inexact Rounded
+rsux354  add -12345  0.5       -> -12344 Inexact Rounded
+rsux355  add -12345  0.50001   -> -12344 Inexact Rounded
+rsux356  add -12345  0.5001    -> -12344 Inexact Rounded
+rsux357  add -12345  0.501     -> -12344 Inexact Rounded
+rsux358  add -12345  0.51      -> -12344 Inexact Rounded
+rsux359  add -12345  0.6       -> -12344 Inexact Rounded
+
+-- Check cancellation subtractions
+-- (The IEEE 854 'curious rule' in $6.3)
+
+rounding: down
+rzex001  add  0    0    ->  0
+rzex002  add  0   -0    ->  0
+rzex003  add -0    0    ->  0
+rzex004  add -0   -0    -> -0
+rzex005  add  1   -1    ->  0
+rzex006  add -1    1    ->  0
+rzex007  add  1.5 -1.5  ->  0.0
+rzex008  add -1.5  1.5  ->  0.0
+rzex009  add  2   -2    ->  0
+rzex010  add -2    2    ->  0
+
+rounding: up
+rzex011  add  0    0    ->  0
+rzex012  add  0   -0    ->  0
+rzex013  add -0    0    ->  0
+rzex014  add -0   -0    -> -0
+rzex015  add  1   -1    ->  0
+rzex016  add -1    1    ->  0
+rzex017  add  1.5 -1.5  ->  0.0
+rzex018  add -1.5  1.5  ->  0.0
+rzex019  add  2   -2    ->  0
+rzex020  add -2    2    ->  0
+
+rounding: half_up
+rzex021  add  0    0    ->  0
+rzex022  add  0   -0    ->  0
+rzex023  add -0    0    ->  0
+rzex024  add -0   -0    -> -0
+rzex025  add  1   -1    ->  0
+rzex026  add -1    1    ->  0
+rzex027  add  1.5 -1.5  ->  0.0
+rzex028  add -1.5  1.5  ->  0.0
+rzex029  add  2   -2    ->  0
+rzex030  add -2    2    ->  0
+
+rounding: half_down
+rzex031  add  0    0    ->  0
+rzex032  add  0   -0    ->  0
+rzex033  add -0    0    ->  0
+rzex034  add -0   -0    -> -0
+rzex035  add  1   -1    ->  0
+rzex036  add -1    1    ->  0
+rzex037  add  1.5 -1.5  ->  0.0
+rzex038  add -1.5  1.5  ->  0.0
+rzex039  add  2   -2    ->  0
+rzex040  add -2    2    ->  0
+
+rounding: half_even
+rzex041  add  0    0    ->  0
+rzex042  add  0   -0    ->  0
+rzex043  add -0    0    ->  0
+rzex044  add -0   -0    -> -0
+rzex045  add  1   -1    ->  0
+rzex046  add -1    1    ->  0
+rzex047  add  1.5 -1.5  ->  0.0
+rzex048  add -1.5  1.5  ->  0.0
+rzex049  add  2   -2    ->  0
+rzex050  add -2    2    ->  0
+
+rounding: floor
+rzex051  add  0    0    ->  0
+rzex052  add  0   -0    -> -0    -- here are two 'curious'
+rzex053  add -0    0    -> -0    --
+rzex054  add -0   -0    -> -0
+rzex055  add  1   -1    -> -0    -- here are the rest
+rzex056  add -1    1    -> -0    -- ..
+rzex057  add  1.5 -1.5  -> -0.0  -- ..
+rzex058  add -1.5  1.5  -> -0.0  -- ..
+rzex059  add  2   -2    -> -0    -- ..
+rzex060  add -2    2    -> -0    -- ..
+
+rounding: ceiling
+rzex061  add  0    0    ->  0
+rzex062  add  0   -0    ->  0
+rzex063  add -0    0    ->  0
+rzex064  add -0   -0    -> -0
+rzex065  add  1   -1    ->  0
+rzex066  add -1    1    ->  0
+rzex067  add  1.5 -1.5  ->  0.0
+rzex068  add -1.5  1.5  ->  0.0
+rzex069  add  2   -2    ->  0
+rzex070  add -2    2    ->  0
+
+
+-- Division operators -------------------------------------------------
+
+rounding: down
+rdvx101  divide 12345  1         ->  12345
+rdvx102  divide 12345  1.0001    ->  12343 Inexact Rounded
+rdvx103  divide 12345  1.001     ->  12332 Inexact Rounded
+rdvx104  divide 12345  1.01      ->  12222 Inexact Rounded
+rdvx105  divide 12345  1.1       ->  11222 Inexact Rounded
+rdvx106  divide 12355  4         ->   3088.7 Inexact Rounded
+rdvx107  divide 12345  4         ->   3086.2 Inexact Rounded
+rdvx108  divide 12355  4.0001    ->   3088.6 Inexact Rounded
+rdvx109  divide 12345  4.0001    ->   3086.1 Inexact Rounded
+rdvx110  divide 12345  4.9       ->   2519.3 Inexact Rounded
+rdvx111  divide 12345  4.99      ->   2473.9 Inexact Rounded
+rdvx112  divide 12345  4.999     ->   2469.4 Inexact Rounded
+rdvx113  divide 12345  4.9999    ->   2469.0 Inexact Rounded
+rdvx114  divide 12345  5         ->   2469
+rdvx115  divide 12345  5.0001    ->  2468.9 Inexact Rounded
+rdvx116  divide 12345  5.001     ->  2468.5 Inexact Rounded
+rdvx117  divide 12345  5.01      ->  2464.0 Inexact Rounded
+rdvx118  divide 12345  5.1       ->  2420.5 Inexact Rounded
+
+rounding: half_down
+rdvx201  divide 12345  1         ->  12345
+rdvx202  divide 12345  1.0001    ->  12344 Inexact Rounded
+rdvx203  divide 12345  1.001     ->  12333 Inexact Rounded
+rdvx204  divide 12345  1.01      ->  12223 Inexact Rounded
+rdvx205  divide 12345  1.1       ->  11223 Inexact Rounded
+rdvx206  divide 12355  4         ->   3088.7 Inexact Rounded
+rdvx207  divide 12345  4         ->   3086.2 Inexact Rounded
+rdvx208  divide 12355  4.0001    ->   3088.7 Inexact Rounded
+rdvx209  divide 12345  4.0001    ->   3086.2 Inexact Rounded
+rdvx210  divide 12345  4.9       ->   2519.4 Inexact Rounded
+rdvx211  divide 12345  4.99      ->   2473.9 Inexact Rounded
+rdvx212  divide 12345  4.999     ->   2469.5 Inexact Rounded
+rdvx213  divide 12345  4.9999    ->   2469.0 Inexact Rounded
+rdvx214  divide 12345  5         ->   2469
+rdvx215  divide 12345  5.0001    ->  2469.0 Inexact Rounded
+rdvx216  divide 12345  5.001     ->  2468.5 Inexact Rounded
+rdvx217  divide 12345  5.01      ->  2464.1 Inexact Rounded
+rdvx218  divide 12345  5.1       ->  2420.6 Inexact Rounded
+
+rounding: half_even
+rdvx301  divide 12345  1         ->  12345
+rdvx302  divide 12345  1.0001    ->  12344 Inexact Rounded
+rdvx303  divide 12345  1.001     ->  12333 Inexact Rounded
+rdvx304  divide 12345  1.01      ->  12223 Inexact Rounded
+rdvx305  divide 12345  1.1       ->  11223 Inexact Rounded
+rdvx306  divide 12355  4         ->   3088.8 Inexact Rounded
+rdvx307  divide 12345  4         ->   3086.2 Inexact Rounded
+rdvx308  divide 12355  4.0001    ->   3088.7 Inexact Rounded
+rdvx309  divide 12345  4.0001    ->   3086.2 Inexact Rounded
+rdvx310  divide 12345  4.9       ->   2519.4 Inexact Rounded
+rdvx311  divide 12345  4.99      ->   2473.9 Inexact Rounded
+rdvx312  divide 12345  4.999     ->   2469.5 Inexact Rounded
+rdvx313  divide 12345  4.9999    ->   2469.0 Inexact Rounded
+rdvx314  divide 12345  5         ->   2469
+rdvx315  divide 12345  5.0001    ->  2469.0 Inexact Rounded
+rdvx316  divide 12345  5.001     ->  2468.5 Inexact Rounded
+rdvx317  divide 12345  5.01      ->  2464.1 Inexact Rounded
+rdvx318  divide 12345  5.1       ->  2420.6 Inexact Rounded
+
+rounding: half_up
+rdvx401  divide 12345  1         ->  12345
+rdvx402  divide 12345  1.0001    ->  12344 Inexact Rounded
+rdvx403  divide 12345  1.001     ->  12333 Inexact Rounded
+rdvx404  divide 12345  1.01      ->  12223 Inexact Rounded
+rdvx405  divide 12345  1.1       ->  11223 Inexact Rounded
+rdvx406  divide 12355  4         ->   3088.8 Inexact Rounded
+rdvx407  divide 12345  4         ->   3086.3 Inexact Rounded
+rdvx408  divide 12355  4.0001    ->   3088.7 Inexact Rounded
+rdvx409  divide 12345  4.0001    ->   3086.2 Inexact Rounded
+rdvx410  divide 12345  4.9       ->   2519.4 Inexact Rounded
+rdvx411  divide 12345  4.99      ->   2473.9 Inexact Rounded
+rdvx412  divide 12345  4.999     ->   2469.5 Inexact Rounded
+rdvx413  divide 12345  4.9999    ->   2469.0 Inexact Rounded
+rdvx414  divide 12345  5         ->   2469
+rdvx415  divide 12345  5.0001    ->  2469.0 Inexact Rounded
+rdvx416  divide 12345  5.001     ->  2468.5 Inexact Rounded
+rdvx417  divide 12345  5.01      ->  2464.1 Inexact Rounded
+rdvx418  divide 12345  5.1       ->  2420.6 Inexact Rounded
+
+rounding: up
+rdvx501  divide 12345  1         ->  12345
+rdvx502  divide 12345  1.0001    ->  12344 Inexact Rounded
+rdvx503  divide 12345  1.001     ->  12333 Inexact Rounded
+rdvx504  divide 12345  1.01      ->  12223 Inexact Rounded
+rdvx505  divide 12345  1.1       ->  11223 Inexact Rounded
+rdvx506  divide 12355  4         ->   3088.8 Inexact Rounded
+rdvx507  divide 12345  4         ->   3086.3 Inexact Rounded
+rdvx508  divide 12355  4.0001    ->   3088.7 Inexact Rounded
+rdvx509  divide 12345  4.0001    ->   3086.2 Inexact Rounded
+rdvx510  divide 12345  4.9       ->   2519.4 Inexact Rounded
+rdvx511  divide 12345  4.99      ->   2474.0 Inexact Rounded
+rdvx512  divide 12345  4.999     ->   2469.5 Inexact Rounded
+rdvx513  divide 12345  4.9999    ->   2469.1 Inexact Rounded
+rdvx514  divide 12345  5         ->   2469
+rdvx515  divide 12345  5.0001    ->  2469.0 Inexact Rounded
+rdvx516  divide 12345  5.001     ->  2468.6 Inexact Rounded
+rdvx517  divide 12345  5.01      ->  2464.1 Inexact Rounded
+rdvx518  divide 12345  5.1       ->  2420.6 Inexact Rounded
+
+rounding: floor
+rdvx601  divide 12345  1         ->  12345
+rdvx602  divide 12345  1.0001    ->  12343 Inexact Rounded
+rdvx603  divide 12345  1.001     ->  12332 Inexact Rounded
+rdvx604  divide 12345  1.01      ->  12222 Inexact Rounded
+rdvx605  divide 12345  1.1       ->  11222 Inexact Rounded
+rdvx606  divide 12355  4         ->   3088.7 Inexact Rounded
+rdvx607  divide 12345  4         ->   3086.2 Inexact Rounded
+rdvx608  divide 12355  4.0001    ->   3088.6 Inexact Rounded
+rdvx609  divide 12345  4.0001    ->   3086.1 Inexact Rounded
+rdvx610  divide 12345  4.9       ->   2519.3 Inexact Rounded
+rdvx611  divide 12345  4.99      ->   2473.9 Inexact Rounded
+rdvx612  divide 12345  4.999     ->   2469.4 Inexact Rounded
+rdvx613  divide 12345  4.9999    ->   2469.0 Inexact Rounded
+rdvx614  divide 12345  5         ->   2469
+rdvx615  divide 12345  5.0001    ->  2468.9 Inexact Rounded
+rdvx616  divide 12345  5.001     ->  2468.5 Inexact Rounded
+rdvx617  divide 12345  5.01      ->  2464.0 Inexact Rounded
+rdvx618  divide 12345  5.1       ->  2420.5 Inexact Rounded
+
+rounding: ceiling
+rdvx701  divide 12345  1         ->  12345
+rdvx702  divide 12345  1.0001    ->  12344 Inexact Rounded
+rdvx703  divide 12345  1.001     ->  12333 Inexact Rounded
+rdvx704  divide 12345  1.01      ->  12223 Inexact Rounded
+rdvx705  divide 12345  1.1       ->  11223 Inexact Rounded
+rdvx706  divide 12355  4         ->   3088.8 Inexact Rounded
+rdvx707  divide 12345  4         ->   3086.3 Inexact Rounded
+rdvx708  divide 12355  4.0001    ->   3088.7 Inexact Rounded
+rdvx709  divide 12345  4.0001    ->   3086.2 Inexact Rounded
+rdvx710  divide 12345  4.9       ->   2519.4 Inexact Rounded
+rdvx711  divide 12345  4.99      ->   2474.0 Inexact Rounded
+rdvx712  divide 12345  4.999     ->   2469.5 Inexact Rounded
+rdvx713  divide 12345  4.9999    ->   2469.1 Inexact Rounded
+rdvx714  divide 12345  5         ->   2469
+rdvx715  divide 12345  5.0001    ->  2469.0 Inexact Rounded
+rdvx716  divide 12345  5.001     ->  2468.6 Inexact Rounded
+rdvx717  divide 12345  5.01      ->  2464.1 Inexact Rounded
+rdvx718  divide 12345  5.1       ->  2420.6 Inexact Rounded
+
+-- [divideInteger and remainder unaffected]
+
+-- Multiplication operator --------------------------------------------
+
+rounding: down
+rmux101  multiply 12345  1         ->  12345
+rmux102  multiply 12345  1.0001    ->  12346 Inexact Rounded
+rmux103  multiply 12345  1.001     ->  12357 Inexact Rounded
+rmux104  multiply 12345  1.01      ->  12468 Inexact Rounded
+rmux105  multiply 12345  1.1       ->  13579 Inexact Rounded
+rmux106  multiply 12345  4         ->  49380
+rmux107  multiply 12345  4.0001    ->  49381 Inexact Rounded
+rmux108  multiply 12345  4.9       ->  60490 Inexact Rounded
+rmux109  multiply 12345  4.99      ->  61601 Inexact Rounded
+rmux110  multiply 12345  4.999     ->  61712 Inexact Rounded
+rmux111  multiply 12345  4.9999    ->  61723 Inexact Rounded
+rmux112  multiply 12345  5         ->  61725
+rmux113  multiply 12345  5.0001    ->  61726 Inexact Rounded
+rmux114  multiply 12345  5.001     ->  61737 Inexact Rounded
+rmux115  multiply 12345  5.01      ->  61848 Inexact Rounded
+rmux116  multiply 12345  12        ->  1.4814E+5 Rounded
+rmux117  multiply 12345  13        ->  1.6048E+5 Inexact Rounded
+rmux118  multiply 12355  12        ->  1.4826E+5 Rounded
+rmux119  multiply 12355  13        ->  1.6061E+5 Inexact Rounded
+
+rounding: half_down
+rmux201  multiply 12345  1         ->  12345
+rmux202  multiply 12345  1.0001    ->  12346 Inexact Rounded
+rmux203  multiply 12345  1.001     ->  12357 Inexact Rounded
+rmux204  multiply 12345  1.01      ->  12468 Inexact Rounded
+rmux205  multiply 12345  1.1       ->  13579 Inexact Rounded
+rmux206  multiply 12345  4         ->  49380
+rmux207  multiply 12345  4.0001    ->  49381 Inexact Rounded
+rmux208  multiply 12345  4.9       ->  60490 Inexact Rounded
+rmux209  multiply 12345  4.99      ->  61602 Inexact Rounded
+rmux210  multiply 12345  4.999     ->  61713 Inexact Rounded
+rmux211  multiply 12345  4.9999    ->  61724 Inexact Rounded
+rmux212  multiply 12345  5         ->  61725
+rmux213  multiply 12345  5.0001    ->  61726 Inexact Rounded
+rmux214  multiply 12345  5.001     ->  61737 Inexact Rounded
+rmux215  multiply 12345  5.01      ->  61848 Inexact Rounded
+rmux216  multiply 12345  12        ->  1.4814E+5 Rounded
+rmux217  multiply 12345  13        ->  1.6048E+5 Inexact Rounded
+rmux218  multiply 12355  12        ->  1.4826E+5 Rounded
+rmux219  multiply 12355  13        ->  1.6061E+5 Inexact Rounded
+
+rounding: half_even
+rmux301  multiply 12345  1         ->  12345
+rmux302  multiply 12345  1.0001    ->  12346 Inexact Rounded
+rmux303  multiply 12345  1.001     ->  12357 Inexact Rounded
+rmux304  multiply 12345  1.01      ->  12468 Inexact Rounded
+rmux305  multiply 12345  1.1       ->  13580 Inexact Rounded
+rmux306  multiply 12345  4         ->  49380
+rmux307  multiply 12345  4.0001    ->  49381 Inexact Rounded
+rmux308  multiply 12345  4.9       ->  60490 Inexact Rounded
+rmux309  multiply 12345  4.99      ->  61602 Inexact Rounded
+rmux310  multiply 12345  4.999     ->  61713 Inexact Rounded
+rmux311  multiply 12345  4.9999    ->  61724 Inexact Rounded
+rmux312  multiply 12345  5         ->  61725
+rmux313  multiply 12345  5.0001    ->  61726 Inexact Rounded
+rmux314  multiply 12345  5.001     ->  61737 Inexact Rounded
+rmux315  multiply 12345  5.01      ->  61848 Inexact Rounded
+rmux316  multiply 12345  12        ->  1.4814E+5 Rounded
+rmux317  multiply 12345  13        ->  1.6048E+5 Inexact Rounded
+rmux318  multiply 12355  12        ->  1.4826E+5 Rounded
+rmux319  multiply 12355  13        ->  1.6062E+5 Inexact Rounded
+
+rounding: half_up
+rmux401  multiply 12345  1         ->  12345
+rmux402  multiply 12345  1.0001    ->  12346 Inexact Rounded
+rmux403  multiply 12345  1.001     ->  12357 Inexact Rounded
+rmux404  multiply 12345  1.01      ->  12468 Inexact Rounded
+rmux405  multiply 12345  1.1       ->  13580 Inexact Rounded
+rmux406  multiply 12345  4         ->  49380
+rmux407  multiply 12345  4.0001    ->  49381 Inexact Rounded
+rmux408  multiply 12345  4.9       ->  60491 Inexact Rounded
+rmux409  multiply 12345  4.99      ->  61602 Inexact Rounded
+rmux410  multiply 12345  4.999     ->  61713 Inexact Rounded
+rmux411  multiply 12345  4.9999    ->  61724 Inexact Rounded
+rmux412  multiply 12345  5         ->  61725
+rmux413  multiply 12345  5.0001    ->  61726 Inexact Rounded
+rmux414  multiply 12345  5.001     ->  61737 Inexact Rounded
+rmux415  multiply 12345  5.01      ->  61848 Inexact Rounded
+rmux416  multiply 12345  12        ->  1.4814E+5 Rounded
+rmux417  multiply 12345  13        ->  1.6049E+5 Inexact Rounded
+rmux418  multiply 12355  12        ->  1.4826E+5 Rounded
+rmux419  multiply 12355  13        ->  1.6062E+5 Inexact Rounded
+
+rounding: up
+rmux501  multiply 12345  1         ->  12345
+rmux502  multiply 12345  1.0001    ->  12347 Inexact Rounded
+rmux503  multiply 12345  1.001     ->  12358 Inexact Rounded
+rmux504  multiply 12345  1.01      ->  12469 Inexact Rounded
+rmux505  multiply 12345  1.1       ->  13580 Inexact Rounded
+rmux506  multiply 12345  4         ->  49380
+rmux507  multiply 12345  4.0001    ->  49382 Inexact Rounded
+rmux508  multiply 12345  4.9       ->  60491 Inexact Rounded
+rmux509  multiply 12345  4.99      ->  61602 Inexact Rounded
+rmux510  multiply 12345  4.999     ->  61713 Inexact Rounded
+rmux511  multiply 12345  4.9999    ->  61724 Inexact Rounded
+rmux512  multiply 12345  5         ->  61725
+rmux513  multiply 12345  5.0001    ->  61727 Inexact Rounded
+rmux514  multiply 12345  5.001     ->  61738 Inexact Rounded
+rmux515  multiply 12345  5.01      ->  61849 Inexact Rounded
+rmux516  multiply 12345  12        ->  1.4814E+5 Rounded
+rmux517  multiply 12345  13        ->  1.6049E+5 Inexact Rounded
+rmux518  multiply 12355  12        ->  1.4826E+5 Rounded
+rmux519  multiply 12355  13        ->  1.6062E+5 Inexact Rounded
+-- [rmux516 & rmux518] can surprise
+
+rounding: floor
+rmux601  multiply 12345  1         ->  12345
+rmux602  multiply 12345  1.0001    ->  12346 Inexact Rounded
+rmux603  multiply 12345  1.001     ->  12357 Inexact Rounded
+rmux604  multiply 12345  1.01      ->  12468 Inexact Rounded
+rmux605  multiply 12345  1.1       ->  13579 Inexact Rounded
+rmux606  multiply 12345  4         ->  49380
+rmux607  multiply 12345  4.0001    ->  49381 Inexact Rounded
+rmux608  multiply 12345  4.9       ->  60490 Inexact Rounded
+rmux609  multiply 12345  4.99      ->  61601 Inexact Rounded
+rmux610  multiply 12345  4.999     ->  61712 Inexact Rounded
+rmux611  multiply 12345  4.9999    ->  61723 Inexact Rounded
+rmux612  multiply 12345  5         ->  61725
+rmux613  multiply 12345  5.0001    ->  61726 Inexact Rounded
+rmux614  multiply 12345  5.001     ->  61737 Inexact Rounded
+rmux615  multiply 12345  5.01      ->  61848 Inexact Rounded
+rmux616  multiply 12345  12        ->  1.4814E+5 Rounded
+rmux617  multiply 12345  13        ->  1.6048E+5 Inexact Rounded
+rmux618  multiply 12355  12        ->  1.4826E+5 Rounded
+rmux619  multiply 12355  13        ->  1.6061E+5 Inexact Rounded
+
+rounding: ceiling
+rmux701  multiply 12345  1         ->  12345
+rmux702  multiply 12345  1.0001    ->  12347 Inexact Rounded
+rmux703  multiply 12345  1.001     ->  12358 Inexact Rounded
+rmux704  multiply 12345  1.01      ->  12469 Inexact Rounded
+rmux705  multiply 12345  1.1       ->  13580 Inexact Rounded
+rmux706  multiply 12345  4         ->  49380
+rmux707  multiply 12345  4.0001    ->  49382 Inexact Rounded
+rmux708  multiply 12345  4.9       ->  60491 Inexact Rounded
+rmux709  multiply 12345  4.99      ->  61602 Inexact Rounded
+rmux710  multiply 12345  4.999     ->  61713 Inexact Rounded
+rmux711  multiply 12345  4.9999    ->  61724 Inexact Rounded
+rmux712  multiply 12345  5         ->  61725
+rmux713  multiply 12345  5.0001    ->  61727 Inexact Rounded
+rmux714  multiply 12345  5.001     ->  61738 Inexact Rounded
+rmux715  multiply 12345  5.01      ->  61849 Inexact Rounded
+rmux716  multiply 12345  12        ->  1.4814E+5 Rounded
+rmux717  multiply 12345  13        ->  1.6049E+5 Inexact Rounded
+rmux718  multiply 12355  12        ->  1.4826E+5 Rounded
+rmux719  multiply 12355  13        ->  1.6062E+5 Inexact Rounded
+
+-- Power operator -----------------------------------------------------
+
+rounding: down
+rpox101  power 12345  -5        ->  3.4877E-21 Inexact Rounded
+rpox102  power 12345  -4        ->  4.3056E-17 Inexact Rounded
+rpox103  power 12345  -3        ->  5.3152E-13 Inexact Rounded
+rpox104  power 12345  -2        ->  6.5617E-9 Inexact Rounded
+rpox105  power 12345  -1        ->  0.000081004 Inexact Rounded
+rpox106  power 12345  0         ->  1
+rpox107  power 12345  1         ->  12345
+rpox108  power 12345  2         ->  1.5239E+8 Inexact Rounded
+rpox109  power 12345  3         ->  1.8813E+12 Inexact Rounded
+rpox110  power 12345  4         ->  2.3225E+16 Inexact Rounded
+rpox111  power 12345  5         ->  2.8671E+20 Inexact Rounded
+rpox112  power   415  2         ->  1.7222E+5 Inexact Rounded
+rpox113  power    75  3         ->  4.2187E+5 Inexact Rounded
+
+rounding: half_down
+rpox201  power 12345  -5        ->  3.4877E-21 Inexact Rounded
+rpox202  power 12345  -4        ->  4.3056E-17 Inexact Rounded
+rpox203  power 12345  -3        ->  5.3153E-13 Inexact Rounded
+rpox204  power 12345  -2        ->  6.5617E-9 Inexact Rounded
+rpox205  power 12345  -1        ->  0.000081004 Inexact Rounded
+rpox206  power 12345  0         ->  1
+rpox207  power 12345  1         ->  12345
+rpox208  power 12345  2         ->  1.5240E+8 Inexact Rounded
+rpox209  power 12345  3         ->  1.8814E+12 Inexact Rounded
+rpox210  power 12345  4         ->  2.3225E+16 Inexact Rounded
+rpox211  power 12345  5         ->  2.8672E+20 Inexact Rounded
+rpox212  power   415  2         ->  1.7222E+5 Inexact Rounded
+rpox213  power    75  3         ->  4.2187E+5 Inexact Rounded
+
+rounding: half_even
+rpox301  power 12345  -5        ->  3.4877E-21 Inexact Rounded
+rpox302  power 12345  -4        ->  4.3056E-17 Inexact Rounded
+rpox303  power 12345  -3        ->  5.3153E-13 Inexact Rounded
+rpox304  power 12345  -2        ->  6.5617E-9 Inexact Rounded
+rpox305  power 12345  -1        ->  0.000081004 Inexact Rounded
+rpox306  power 12345  0         ->  1
+rpox307  power 12345  1         ->  12345
+rpox308  power 12345  2         ->  1.5240E+8 Inexact Rounded
+rpox309  power 12345  3         ->  1.8814E+12 Inexact Rounded
+rpox310  power 12345  4         ->  2.3225E+16 Inexact Rounded
+rpox311  power 12345  5         ->  2.8672E+20 Inexact Rounded
+rpox312  power   415  2         ->  1.7222E+5 Inexact Rounded
+rpox313  power    75  3         ->  4.2188E+5 Inexact Rounded
+
+rounding: half_up
+rpox401  power 12345  -5        ->  3.4877E-21 Inexact Rounded
+rpox402  power 12345  -4        ->  4.3056E-17 Inexact Rounded
+rpox403  power 12345  -3        ->  5.3153E-13 Inexact Rounded
+rpox404  power 12345  -2        ->  6.5617E-9 Inexact Rounded
+rpox405  power 12345  -1        ->  0.000081004 Inexact Rounded
+rpox406  power 12345  0         ->  1
+rpox407  power 12345  1         ->  12345
+rpox408  power 12345  2         ->  1.5240E+8 Inexact Rounded
+rpox409  power 12345  3         ->  1.8814E+12 Inexact Rounded
+rpox410  power 12345  4         ->  2.3225E+16 Inexact Rounded
+rpox411  power 12345  5         ->  2.8672E+20 Inexact Rounded
+rpox412  power   415  2         ->  1.7223E+5 Inexact Rounded
+rpox413  power    75  3         ->  4.2188E+5 Inexact Rounded
+
+rounding: up
+rpox501  power 12345  -5        ->  3.4878E-21 Inexact Rounded
+rpox502  power 12345  -4        ->  4.3057E-17 Inexact Rounded
+rpox503  power 12345  -3        ->  5.3153E-13 Inexact Rounded
+rpox504  power 12345  -2        ->  6.5618E-9 Inexact Rounded
+rpox505  power 12345  -1        ->  0.000081005 Inexact Rounded
+rpox506  power 12345  0         ->  1
+rpox507  power 12345  1         ->  12345
+rpox508  power 12345  2         ->  1.5240E+8 Inexact Rounded
+rpox509  power 12345  3         ->  1.8814E+12 Inexact Rounded
+rpox510  power 12345  4         ->  2.3226E+16 Inexact Rounded
+rpox511  power 12345  5         ->  2.8672E+20 Inexact Rounded
+rpox512  power   415  2         ->  1.7223E+5 Inexact Rounded
+rpox513  power    75  3         ->  4.2188E+5 Inexact Rounded
+
+rounding: floor
+rpox601  power 12345  -5        ->  3.4877E-21 Inexact Rounded
+rpox602  power 12345  -4        ->  4.3056E-17 Inexact Rounded
+rpox603  power 12345  -3        ->  5.3152E-13 Inexact Rounded
+rpox604  power 12345  -2        ->  6.5617E-9 Inexact Rounded
+rpox605  power 12345  -1        ->  0.000081004 Inexact Rounded
+rpox606  power 12345  0         ->  1
+rpox607  power 12345  1         ->  12345
+rpox608  power 12345  2         ->  1.5239E+8 Inexact Rounded
+rpox609  power 12345  3         ->  1.8813E+12 Inexact Rounded
+rpox610  power 12345  4         ->  2.3225E+16 Inexact Rounded
+rpox611  power 12345  5         ->  2.8671E+20 Inexact Rounded
+rpox612  power   415  2         ->  1.7222E+5 Inexact Rounded
+rpox613  power    75  3         ->  4.2187E+5 Inexact Rounded
+
+rounding: ceiling
+rpox701  power 12345  -5        ->  3.4878E-21 Inexact Rounded
+rpox702  power 12345  -4        ->  4.3057E-17 Inexact Rounded
+rpox703  power 12345  -3        ->  5.3153E-13 Inexact Rounded
+rpox704  power 12345  -2        ->  6.5618E-9 Inexact Rounded
+rpox705  power 12345  -1        ->  0.000081005 Inexact Rounded
+rpox706  power 12345  0         ->  1
+rpox707  power 12345  1         ->  12345
+rpox708  power 12345  2         ->  1.5240E+8 Inexact Rounded
+rpox709  power 12345  3         ->  1.8814E+12 Inexact Rounded
+rpox710  power 12345  4         ->  2.3226E+16 Inexact Rounded
+rpox711  power 12345  5         ->  2.8672E+20 Inexact Rounded
+rpox712  power   415  2         ->  1.7223E+5 Inexact Rounded
+rpox713  power    75  3         ->  4.2188E+5 Inexact Rounded
+
+-- Underflow Subnormal and overflow values vary with rounding mode and sign
+maxexponent: 999999999
+minexponent: -999999999
+rounding: down
+rovx100  multiply   10    9E+999999999 ->  9.9999E+999999999 Overflow Inexact Rounded
+rovx101  multiply  -10    9E+999999999 -> -9.9999E+999999999 Overflow Inexact Rounded
+rovx102  divide     1E-9  9E+999999999 ->  0E-1000000003 Underflow Subnormal Inexact Rounded
+rovx104  divide    -1E-9  9E+999999999 -> -0E-1000000003 Underflow Subnormal Inexact Rounded
+
+rounding: up
+rovx110  multiply   10    9E+999999999 ->  Infinity Overflow Inexact Rounded
+rovx111  multiply  -10    9E+999999999 -> -Infinity Overflow Inexact Rounded
+rovx112  divide     1E-9  9E+999999999 ->  1E-1000000003 Underflow Subnormal Inexact Rounded
+rovx114  divide    -1E-9  9E+999999999 -> -1E-1000000003 Underflow Subnormal Inexact Rounded
+
+rounding: ceiling
+rovx120  multiply   10    9E+999999999 ->  Infinity Overflow Inexact Rounded
+rovx121  multiply  -10    9E+999999999 -> -9.9999E+999999999 Overflow Inexact Rounded
+rovx122  divide     1E-9  9E+999999999 ->  1E-1000000003 Underflow Subnormal Inexact Rounded
+rovx124  divide    -1E-9  9E+999999999 -> -0E-1000000003 Underflow Subnormal Inexact Rounded
+
+rounding: floor
+rovx130  multiply   10    9E+999999999 ->  9.9999E+999999999 Overflow Inexact Rounded
+rovx131  multiply  -10    9E+999999999 -> -Infinity Overflow Inexact Rounded
+rovx132  divide     1E-9  9E+999999999 ->  0E-1000000003 Underflow Subnormal Inexact Rounded
+rovx134  divide    -1E-9  9E+999999999 -> -1E-1000000003 Underflow Subnormal Inexact Rounded
+
+rounding: half_up
+rovx140  multiply   10    9E+999999999 ->  Infinity Overflow Inexact Rounded
+rovx141  multiply  -10    9E+999999999 -> -Infinity Overflow Inexact Rounded
+rovx142  divide     1E-9  9E+999999999 ->  0E-1000000003 Underflow Subnormal Inexact Rounded
+rovx144  divide    -1E-9  9E+999999999 -> -0E-1000000003 Underflow Subnormal Inexact Rounded
+
+rounding: half_even
+rovx150  multiply   10    9E+999999999 ->  Infinity Overflow Inexact Rounded
+rovx151  multiply  -10    9E+999999999 -> -Infinity Overflow Inexact Rounded
+rovx152  divide     1E-9  9E+999999999 ->  0E-1000000003 Underflow Subnormal Inexact Rounded
+rovx154  divide    -1E-9  9E+999999999 -> -0E-1000000003 Underflow Subnormal Inexact Rounded
+
+rounding: half_down
+rovx160  multiply   10    9E+999999999 ->  Infinity Overflow Inexact Rounded
+rovx161  multiply  -10    9E+999999999 -> -Infinity Overflow Inexact Rounded
+rovx162  divide     1E-9  9E+999999999 ->  0E-1000000003 Underflow Subnormal Inexact Rounded
+rovx164  divide    -1E-9  9E+999999999 -> -0E-1000000003 Underflow Subnormal Inexact Rounded
+
+-- check maximum finite value over a range of precisions
+rounding: down
+precision: 1
+rovx200  multiply   10    9E+999999999 ->  9E+999999999 Overflow Inexact Rounded
+rovx201  multiply  -10    9E+999999999 -> -9E+999999999 Overflow Inexact Rounded
+precision: 2
+rovx210  multiply   10    9E+999999999 ->  9.9E+999999999 Overflow Inexact Rounded
+rovx211  multiply  -10    9E+999999999 -> -9.9E+999999999 Overflow Inexact Rounded
+precision: 3
+rovx220  multiply   10    9E+999999999 ->  9.99E+999999999 Overflow Inexact Rounded
+rovx221  multiply  -10    9E+999999999 -> -9.99E+999999999 Overflow Inexact Rounded
+precision: 4
+rovx230  multiply   10    9E+999999999 ->  9.999E+999999999 Overflow Inexact Rounded
+rovx231  multiply  -10    9E+999999999 -> -9.999E+999999999 Overflow Inexact Rounded
+precision: 5
+rovx240  multiply   10    9E+999999999 ->  9.9999E+999999999 Overflow Inexact Rounded
+rovx241  multiply  -10    9E+999999999 -> -9.9999E+999999999 Overflow Inexact Rounded
+precision: 6
+rovx250  multiply   10    9E+999999999 ->  9.99999E+999999999 Overflow Inexact Rounded
+rovx251  multiply  -10    9E+999999999 -> -9.99999E+999999999 Overflow Inexact Rounded
+precision: 7
+rovx260  multiply   10    9E+999999999 ->  9.999999E+999999999 Overflow Inexact Rounded
+rovx261  multiply  -10    9E+999999999 -> -9.999999E+999999999 Overflow Inexact Rounded
+precision: 8
+rovx270  multiply   10    9E+999999999 ->  9.9999999E+999999999 Overflow Inexact Rounded
+rovx271  multiply  -10    9E+999999999 -> -9.9999999E+999999999 Overflow Inexact Rounded
+precision: 9
+rovx280  multiply   10    9E+999999999 ->  9.99999999E+999999999 Overflow Inexact Rounded
+rovx281  multiply  -10    9E+999999999 -> -9.99999999E+999999999 Overflow Inexact Rounded
+precision: 10
+rovx290  multiply   10    9E+999999999 ->  9.999999999E+999999999 Overflow Inexact Rounded
+rovx291  multiply  -10    9E+999999999 -> -9.999999999E+999999999 Overflow Inexact Rounded
+
+-- reprise rounding mode effect (using multiplies so precision directive used)
+precision: 9
+maxexponent: 999999999
+rounding: half_up
+rmex400 multiply -9.999E+999999999 10 -> -Infinity Overflow Inexact Rounded
+rmex401 multiply  9.999E+999999999 10 ->  Infinity Overflow Inexact Rounded
+rounding: half_down
+rmex402 multiply -9.999E+999999999 10 -> -Infinity Overflow Inexact Rounded
+rmex403 multiply  9.999E+999999999 10 ->  Infinity Overflow Inexact Rounded
+rounding: half_even
+rmex404 multiply -9.999E+999999999 10 -> -Infinity Overflow Inexact Rounded
+rmex405 multiply  9.999E+999999999 10 ->  Infinity Overflow Inexact Rounded
+rounding: floor
+rmex406 multiply -9.999E+999999999 10 -> -Infinity Overflow Inexact Rounded
+rmex407 multiply  9.999E+999999999 10 ->  9.99999999E+999999999 Overflow Inexact Rounded
+rounding: ceiling
+rmex408 multiply -9.999E+999999999 10 -> -9.99999999E+999999999 Overflow Inexact Rounded
+rmex409 multiply  9.999E+999999999 10 ->  Infinity Overflow Inexact Rounded
+rounding: up
+rmex410 multiply -9.999E+999999999 10 -> -Infinity Overflow Inexact Rounded
+rmex411 multiply  9.999E+999999999 10 ->  Infinity Overflow Inexact Rounded
+rounding: down
+rmex412 multiply -9.999E+999999999 10 -> -9.99999999E+999999999 Overflow Inexact Rounded
+rmex413 multiply  9.999E+999999999 10 ->  9.99999999E+999999999 Overflow Inexact Rounded
+

Added: vendor/Python/current/Lib/test/decimaltestdata/samequantum.decTest
===================================================================
--- vendor/Python/current/Lib/test/decimaltestdata/samequantum.decTest	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/decimaltestdata/samequantum.decTest	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,353 @@
+------------------------------------------------------------------------
+-- samequantum.decTest -- check quantums match                        --
+-- Copyright (c) IBM Corporation, 2001, 2003.  All rights reserved.   --
+------------------------------------------------------------------------
+-- Please see the document "General Decimal Arithmetic Testcases"     --
+-- at http://www2.hursley.ibm.com/decimal for the description of      --
+-- these testcases.                                                   --
+--                                                                    --
+-- These testcases are experimental ('beta' versions), and they       --
+-- may contain errors.  They are offered on an as-is basis.  In       --
+-- particular, achieving the same results as the tests here is not    --
+-- a guarantee that an implementation complies with any Standard      --
+-- or specification.  The tests are not exhaustive.                   --
+--                                                                    --
+-- Please send comments, suggestions, and corrections to the author:  --
+--   Mike Cowlishaw, IBM Fellow                                       --
+--   IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK         --
+--   mfc at uk.ibm.com                                                   --
+------------------------------------------------------------------------
+version: 2.39
+
+extended:    1
+precision:   9
+rounding:    half_up
+maxExponent: 999
+minExponent: -999
+
+samq001 samequantum  0      0      ->  1
+samq002 samequantum  0      1      ->  1
+samq003 samequantum  1      0      ->  1
+samq004 samequantum  1      1      ->  1
+
+samq011 samequantum  10     1E+1   -> 0
+samq012 samequantum  10E+1  10E+1  -> 1
+samq013 samequantum  100    10E+1  -> 0
+samq014 samequantum  100    1E+2   -> 0
+samq015 samequantum  0.1    1E-2   -> 0
+samq016 samequantum  0.1    1E-1   -> 1
+samq017 samequantum  0.1    1E-0   -> 0
+samq018 samequantum  999    999    -> 1
+samq019 samequantum  999E-1 99.9   -> 1
+samq020 samequantum  111E-1 22.2   -> 1
+samq021 samequantum  111E-1 1234.2 -> 1
+
+-- zeros
+samq030 samequantum  0.0    1.1    -> 1
+samq031 samequantum  0.0    1.11   -> 0
+samq032 samequantum  0.0    0      -> 0
+samq033 samequantum  0.0    0.0    -> 1
+samq034 samequantum  0.0    0.00   -> 0
+samq035 samequantum  0E+1   0E+0   -> 0
+samq036 samequantum  0E+1   0E+1   -> 1
+samq037 samequantum  0E+1   0E+2   -> 0
+samq038 samequantum  0E-17  0E-16  -> 0
+samq039 samequantum  0E-17  0E-17  -> 1
+samq040 samequantum  0E-17  0E-18  -> 0
+samq041 samequantum  0E-17  0.0E-15 -> 0
+samq042 samequantum  0E-17  0.0E-16 -> 1
+samq043 samequantum  0E-17  0.0E-17 -> 0
+samq044 samequantum -0E-17  0.0E-16 -> 1
+samq045 samequantum  0E-17 -0.0E-17 -> 0
+samq046 samequantum  0E-17 -0.0E-16 -> 1
+samq047 samequantum -0E-17  0.0E-17 -> 0
+samq048 samequantum -0E-17 -0.0E-16 -> 1
+samq049 samequantum -0E-17 -0.0E-17 -> 0
+
+-- specials & combinations
+
+samq0110 samequantum  -Inf    -Inf   -> 1
+samq0111 samequantum  -Inf     Inf   -> 1
+samq0112 samequantum  -Inf     NaN   -> 0
+samq0113 samequantum  -Inf    -7E+3  -> 0
+samq0114 samequantum  -Inf    -7     -> 0
+samq0115 samequantum  -Inf    -7E-3  -> 0
+samq0116 samequantum  -Inf    -0E-3  -> 0
+samq0117 samequantum  -Inf    -0     -> 0
+samq0118 samequantum  -Inf    -0E+3  -> 0
+samq0119 samequantum  -Inf     0E-3  -> 0
+samq0120 samequantum  -Inf     0     -> 0
+samq0121 samequantum  -Inf     0E+3  -> 0
+samq0122 samequantum  -Inf     7E-3  -> 0
+samq0123 samequantum  -Inf     7     -> 0
+samq0124 samequantum  -Inf     7E+3  -> 0
+samq0125 samequantum  -Inf     sNaN  -> 0
+
+samq0210 samequantum   Inf    -Inf   -> 1
+samq0211 samequantum   Inf     Inf   -> 1
+samq0212 samequantum   Inf     NaN   -> 0
+samq0213 samequantum   Inf    -7E+3  -> 0
+samq0214 samequantum   Inf    -7     -> 0
+samq0215 samequantum   Inf    -7E-3  -> 0
+samq0216 samequantum   Inf    -0E-3  -> 0
+samq0217 samequantum   Inf    -0     -> 0
+samq0218 samequantum   Inf    -0E+3  -> 0
+samq0219 samequantum   Inf     0E-3  -> 0
+samq0220 samequantum   Inf     0     -> 0
+samq0221 samequantum   Inf     0E+3  -> 0
+samq0222 samequantum   Inf     7E-3  -> 0
+samq0223 samequantum   Inf     7     -> 0
+samq0224 samequantum   Inf     7E+3  -> 0
+samq0225 samequantum   Inf     sNaN  -> 0
+
+samq0310 samequantum   NaN    -Inf   -> 0
+samq0311 samequantum   NaN     Inf   -> 0
+samq0312 samequantum   NaN     NaN   -> 1
+samq0313 samequantum   NaN    -7E+3  -> 0
+samq0314 samequantum   NaN    -7     -> 0
+samq0315 samequantum   NaN    -7E-3  -> 0
+samq0316 samequantum   NaN    -0E-3  -> 0
+samq0317 samequantum   NaN    -0     -> 0
+samq0318 samequantum   NaN    -0E+3  -> 0
+samq0319 samequantum   NaN     0E-3  -> 0
+samq0320 samequantum   NaN     0     -> 0
+samq0321 samequantum   NaN     0E+3  -> 0
+samq0322 samequantum   NaN     7E-3  -> 0
+samq0323 samequantum   NaN     7     -> 0
+samq0324 samequantum   NaN     7E+3  -> 0
+samq0325 samequantum   NaN     sNaN  -> 1
+
+samq0410 samequantum  -7E+3    -Inf   -> 0
+samq0411 samequantum  -7E+3     Inf   -> 0
+samq0412 samequantum  -7E+3     NaN   -> 0
+samq0413 samequantum  -7E+3    -7E+3  -> 1
+samq0414 samequantum  -7E+3    -7     -> 0
+samq0415 samequantum  -7E+3    -7E-3  -> 0
+samq0416 samequantum  -7E+3    -0E-3  -> 0
+samq0417 samequantum  -7E+3    -0     -> 0
+samq0418 samequantum  -7E+3    -0E+3  -> 1
+samq0419 samequantum  -7E+3     0E-3  -> 0
+samq0420 samequantum  -7E+3     0     -> 0
+samq0421 samequantum  -7E+3     0E+3  -> 1
+samq0422 samequantum  -7E+3     7E-3  -> 0
+samq0423 samequantum  -7E+3     7     -> 0
+samq0424 samequantum  -7E+3     7E+3  -> 1
+samq0425 samequantum  -7E+3     sNaN  -> 0
+
+samq0510 samequantum  -7      -Inf   -> 0
+samq0511 samequantum  -7       Inf   -> 0
+samq0512 samequantum  -7       NaN   -> 0
+samq0513 samequantum  -7      -7E+3  -> 0
+samq0514 samequantum  -7      -7     -> 1
+samq0515 samequantum  -7      -7E-3  -> 0
+samq0516 samequantum  -7      -0E-3  -> 0
+samq0517 samequantum  -7      -0     -> 1
+samq0518 samequantum  -7      -0E+3  -> 0
+samq0519 samequantum  -7       0E-3  -> 0
+samq0520 samequantum  -7       0     -> 1
+samq0521 samequantum  -7       0E+3  -> 0
+samq0522 samequantum  -7       7E-3  -> 0
+samq0523 samequantum  -7       7     -> 1
+samq0524 samequantum  -7       7E+3  -> 0
+samq0525 samequantum  -7       sNaN  -> 0
+
+samq0610 samequantum  -7E-3    -Inf   -> 0
+samq0611 samequantum  -7E-3     Inf   -> 0
+samq0612 samequantum  -7E-3     NaN   -> 0
+samq0613 samequantum  -7E-3    -7E+3  -> 0
+samq0614 samequantum  -7E-3    -7     -> 0
+samq0615 samequantum  -7E-3    -7E-3  -> 1
+samq0616 samequantum  -7E-3    -0E-3  -> 1
+samq0617 samequantum  -7E-3    -0     -> 0
+samq0618 samequantum  -7E-3    -0E+3  -> 0
+samq0619 samequantum  -7E-3     0E-3  -> 1
+samq0620 samequantum  -7E-3     0     -> 0
+samq0621 samequantum  -7E-3     0E+3  -> 0
+samq0622 samequantum  -7E-3     7E-3  -> 1
+samq0623 samequantum  -7E-3     7     -> 0
+samq0624 samequantum  -7E-3     7E+3  -> 0
+samq0625 samequantum  -7E-3     sNaN  -> 0
+
+samq0710 samequantum  -0E-3    -Inf   -> 0
+samq0711 samequantum  -0E-3     Inf   -> 0
+samq0712 samequantum  -0E-3     NaN   -> 0
+samq0713 samequantum  -0E-3    -7E+3  -> 0
+samq0714 samequantum  -0E-3    -7     -> 0
+samq0715 samequantum  -0E-3    -7E-3  -> 1
+samq0716 samequantum  -0E-3    -0E-3  -> 1
+samq0717 samequantum  -0E-3    -0     -> 0
+samq0718 samequantum  -0E-3    -0E+3  -> 0
+samq0719 samequantum  -0E-3     0E-3  -> 1
+samq0720 samequantum  -0E-3     0     -> 0
+samq0721 samequantum  -0E-3     0E+3  -> 0
+samq0722 samequantum  -0E-3     7E-3  -> 1
+samq0723 samequantum  -0E-3     7     -> 0
+samq0724 samequantum  -0E-3     7E+3  -> 0
+samq0725 samequantum  -0E-3     sNaN  -> 0
+
+samq0810 samequantum  -0      -Inf   -> 0
+samq0811 samequantum  -0       Inf   -> 0
+samq0812 samequantum  -0       NaN   -> 0
+samq0813 samequantum  -0      -7E+3  -> 0
+samq0814 samequantum  -0      -7     -> 1
+samq0815 samequantum  -0      -7E-3  -> 0
+samq0816 samequantum  -0      -0E-3  -> 0
+samq0817 samequantum  -0      -0     -> 1
+samq0818 samequantum  -0      -0E+3  -> 0
+samq0819 samequantum  -0       0E-3  -> 0
+samq0820 samequantum  -0       0     -> 1
+samq0821 samequantum  -0       0E+3  -> 0
+samq0822 samequantum  -0       7E-3  -> 0
+samq0823 samequantum  -0       7     -> 1
+samq0824 samequantum  -0       7E+3  -> 0
+samq0825 samequantum  -0       sNaN  -> 0
+
+samq0910 samequantum  -0E+3    -Inf   -> 0
+samq0911 samequantum  -0E+3     Inf   -> 0
+samq0912 samequantum  -0E+3     NaN   -> 0
+samq0913 samequantum  -0E+3    -7E+3  -> 1
+samq0914 samequantum  -0E+3    -7     -> 0
+samq0915 samequantum  -0E+3    -7E-3  -> 0
+samq0916 samequantum  -0E+3    -0E-3  -> 0
+samq0917 samequantum  -0E+3    -0     -> 0
+samq0918 samequantum  -0E+3    -0E+3  -> 1
+samq0919 samequantum  -0E+3     0E-3  -> 0
+samq0920 samequantum  -0E+3     0     -> 0
+samq0921 samequantum  -0E+3     0E+3  -> 1
+samq0922 samequantum  -0E+3     7E-3  -> 0
+samq0923 samequantum  -0E+3     7     -> 0
+samq0924 samequantum  -0E+3     7E+3  -> 1
+samq0925 samequantum  -0E+3     sNaN  -> 0
+
+samq1110 samequantum  0E-3    -Inf   -> 0
+samq1111 samequantum  0E-3     Inf   -> 0
+samq1112 samequantum  0E-3     NaN   -> 0
+samq1113 samequantum  0E-3    -7E+3  -> 0
+samq1114 samequantum  0E-3    -7     -> 0
+samq1115 samequantum  0E-3    -7E-3  -> 1
+samq1116 samequantum  0E-3    -0E-3  -> 1
+samq1117 samequantum  0E-3    -0     -> 0
+samq1118 samequantum  0E-3    -0E+3  -> 0
+samq1119 samequantum  0E-3     0E-3  -> 1
+samq1120 samequantum  0E-3     0     -> 0
+samq1121 samequantum  0E-3     0E+3  -> 0
+samq1122 samequantum  0E-3     7E-3  -> 1
+samq1123 samequantum  0E-3     7     -> 0
+samq1124 samequantum  0E-3     7E+3  -> 0
+samq1125 samequantum  0E-3     sNaN  -> 0
+
+samq1210 samequantum  0       -Inf   -> 0
+samq1211 samequantum  0        Inf   -> 0
+samq1212 samequantum  0        NaN   -> 0
+samq1213 samequantum  0       -7E+3  -> 0
+samq1214 samequantum  0       -7     -> 1
+samq1215 samequantum  0       -7E-3  -> 0
+samq1216 samequantum  0       -0E-3  -> 0
+samq1217 samequantum  0       -0     -> 1
+samq1218 samequantum  0       -0E+3  -> 0
+samq1219 samequantum  0        0E-3  -> 0
+samq1220 samequantum  0        0     -> 1
+samq1221 samequantum  0        0E+3  -> 0
+samq1222 samequantum  0        7E-3  -> 0
+samq1223 samequantum  0        7     -> 1
+samq1224 samequantum  0        7E+3  -> 0
+samq1225 samequantum  0        sNaN  -> 0
+
+samq1310 samequantum  0E+3    -Inf   -> 0
+samq1311 samequantum  0E+3     Inf   -> 0
+samq1312 samequantum  0E+3     NaN   -> 0
+samq1313 samequantum  0E+3    -7E+3  -> 1
+samq1314 samequantum  0E+3    -7     -> 0
+samq1315 samequantum  0E+3    -7E-3  -> 0
+samq1316 samequantum  0E+3    -0E-3  -> 0
+samq1317 samequantum  0E+3    -0     -> 0
+samq1318 samequantum  0E+3    -0E+3  -> 1
+samq1319 samequantum  0E+3     0E-3  -> 0
+samq1320 samequantum  0E+3     0     -> 0
+samq1321 samequantum  0E+3     0E+3  -> 1
+samq1322 samequantum  0E+3     7E-3  -> 0
+samq1323 samequantum  0E+3     7     -> 0
+samq1324 samequantum  0E+3     7E+3  -> 1
+samq1325 samequantum  0E+3     sNaN  -> 0
+
+samq1410 samequantum  7E-3    -Inf   -> 0
+samq1411 samequantum  7E-3     Inf   -> 0
+samq1412 samequantum  7E-3     NaN   -> 0
+samq1413 samequantum  7E-3    -7E+3  -> 0
+samq1414 samequantum  7E-3    -7     -> 0
+samq1415 samequantum  7E-3    -7E-3  -> 1
+samq1416 samequantum  7E-3    -0E-3  -> 1
+samq1417 samequantum  7E-3    -0     -> 0
+samq1418 samequantum  7E-3    -0E+3  -> 0
+samq1419 samequantum  7E-3     0E-3  -> 1
+samq1420 samequantum  7E-3     0     -> 0
+samq1421 samequantum  7E-3     0E+3  -> 0
+samq1422 samequantum  7E-3     7E-3  -> 1
+samq1423 samequantum  7E-3     7     -> 0
+samq1424 samequantum  7E-3     7E+3  -> 0
+samq1425 samequantum  7E-3     sNaN  -> 0
+
+samq1510 samequantum  7      -Inf   -> 0
+samq1511 samequantum  7       Inf   -> 0
+samq1512 samequantum  7       NaN   -> 0
+samq1513 samequantum  7      -7E+3  -> 0
+samq1514 samequantum  7      -7     -> 1
+samq1515 samequantum  7      -7E-3  -> 0
+samq1516 samequantum  7      -0E-3  -> 0
+samq1517 samequantum  7      -0     -> 1
+samq1518 samequantum  7      -0E+3  -> 0
+samq1519 samequantum  7       0E-3  -> 0
+samq1520 samequantum  7       0     -> 1
+samq1521 samequantum  7       0E+3  -> 0
+samq1522 samequantum  7       7E-3  -> 0
+samq1523 samequantum  7       7     -> 1
+samq1524 samequantum  7       7E+3  -> 0
+samq1525 samequantum  7       sNaN  -> 0
+
+samq1610 samequantum  7E+3    -Inf   -> 0
+samq1611 samequantum  7E+3     Inf   -> 0
+samq1612 samequantum  7E+3     NaN   -> 0
+samq1613 samequantum  7E+3    -7E+3  -> 1
+samq1614 samequantum  7E+3    -7     -> 0
+samq1615 samequantum  7E+3    -7E-3  -> 0
+samq1616 samequantum  7E+3    -0E-3  -> 0
+samq1617 samequantum  7E+3    -0     -> 0
+samq1618 samequantum  7E+3    -0E+3  -> 1
+samq1619 samequantum  7E+3     0E-3  -> 0
+samq1620 samequantum  7E+3     0     -> 0
+samq1621 samequantum  7E+3     0E+3  -> 1
+samq1622 samequantum  7E+3     7E-3  -> 0
+samq1623 samequantum  7E+3     7     -> 0
+samq1624 samequantum  7E+3     7E+3  -> 1
+samq1625 samequantum  7E+3     sNaN  -> 0
+
+samq1710 samequantum  sNaN    -Inf   -> 0
+samq1711 samequantum  sNaN     Inf   -> 0
+samq1712 samequantum  sNaN     NaN   -> 1
+samq1713 samequantum  sNaN    -7E+3  -> 0
+samq1714 samequantum  sNaN    -7     -> 0
+samq1715 samequantum  sNaN    -7E-3  -> 0
+samq1716 samequantum  sNaN    -0E-3  -> 0
+samq1717 samequantum  sNaN    -0     -> 0
+samq1718 samequantum  sNaN    -0E+3  -> 0
+samq1719 samequantum  sNaN     0E-3  -> 0
+samq1720 samequantum  sNaN     0     -> 0
+samq1721 samequantum  sNaN     0E+3  -> 0
+samq1722 samequantum  sNaN     7E-3  -> 0
+samq1723 samequantum  sNaN     7     -> 0
+samq1724 samequantum  sNaN     7E+3  -> 0
+samq1725 samequantum  sNaN     sNaN  -> 1
+-- noisy NaNs
+samq1730 samequantum  sNaN3    sNaN3 -> 1
+samq1731 samequantum  sNaN3    sNaN4 -> 1
+samq1732 samequantum   NaN3     NaN3 -> 1
+samq1733 samequantum   NaN3     NaN4 -> 1
+samq1734 samequantum  sNaN3     3    -> 0
+samq1735 samequantum   NaN3     3    -> 0
+samq1736 samequantum      4    sNaN4 -> 0
+samq1737 samequantum      3     NaN3 -> 0
+samq1738 samequantum    Inf    sNaN4 -> 0
+samq1739 samequantum   -Inf     NaN3 -> 0
+
+
+

Added: vendor/Python/current/Lib/test/decimaltestdata/squareroot.decTest
===================================================================
--- vendor/Python/current/Lib/test/decimaltestdata/squareroot.decTest	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/decimaltestdata/squareroot.decTest	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2958 @@
+------------------------------------------------------------------------
+-- squareroot.decTest -- decimal square root                          --
+-- Copyright (c) IBM Corporation, 2004.  All rights reserved.         --
+------------------------------------------------------------------------
+-- Please see the document "General Decimal Arithmetic Testcases"     --
+-- at http://www2.hursley.ibm.com/decimal for the description of      --
+-- these testcases.                                                   --
+--                                                                    --
+-- These testcases are experimental ('beta' versions), and they       --
+-- may contain errors.  They are offered on an as-is basis.  In       --
+-- particular, achieving the same results as the tests here is not    --
+-- a guarantee that an implementation complies with any Standard      --
+-- or specification.  The tests are not exhaustive.                   --
+--                                                                    --
+-- Please send comments, suggestions, and corrections to the author:  --
+--   Mike Cowlishaw, IBM Fellow                                       --
+--   IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK         --
+--   mfc at uk.ibm.com                                                   --
+------------------------------------------------------------------------
+version: 2.39
+
+extended:    1
+precision:   9
+rounding:    half_up
+maxExponent: 384
+minexponent: -383
+
+-- basics
+sqtx001 squareroot 1       -> 1
+sqtx002 squareroot -1      -> NaN Invalid_operation
+sqtx003 squareroot 1.00    -> 1.0
+sqtx004 squareroot -1.00   -> NaN Invalid_operation
+sqtx005 squareroot 0       -> 0
+sqtx006 squareroot 00.0    -> 0.0
+sqtx007 squareroot 0.00    -> 0.0
+sqtx008 squareroot 00.00   -> 0.0
+sqtx009 squareroot 00.000  -> 0.00
+sqtx010 squareroot 00.0000 -> 0.00
+sqtx011 squareroot 00      -> 0
+
+sqtx012 squareroot -2      -> NaN Invalid_operation
+sqtx013 squareroot 2       -> 1.41421356 Inexact Rounded
+sqtx014 squareroot -2.00   -> NaN Invalid_operation
+sqtx015 squareroot 2.00    -> 1.41421356 Inexact Rounded
+sqtx016 squareroot -0      -> -0
+sqtx017 squareroot -0.0    -> -0.0
+sqtx018 squareroot -00.00  -> -0.0
+sqtx019 squareroot -00.000 -> -0.00
+sqtx020 squareroot -0.0000 -> -0.00
+sqtx021 squareroot -0E+9   -> -0E+4
+sqtx022 squareroot -0E+10  -> -0E+5
+sqtx023 squareroot -0E+11  -> -0E+5
+sqtx024 squareroot -0E+12  -> -0E+6
+sqtx025 squareroot -00     -> -0
+sqtx026 squareroot 0E+5    -> 0E+2
+sqtx027 squareroot 4.0     -> 2.0
+sqtx028 squareroot 4.00    -> 2.0
+
+sqtx030 squareroot +0.1            -> 0.316227766 Inexact Rounded
+sqtx031 squareroot -0.1            -> NaN Invalid_operation
+sqtx032 squareroot +0.01           -> 0.1
+sqtx033 squareroot -0.01           -> NaN Invalid_operation
+sqtx034 squareroot +0.001          -> 0.0316227766 Inexact Rounded
+sqtx035 squareroot -0.001          -> NaN Invalid_operation
+sqtx036 squareroot +0.000001       -> 0.001
+sqtx037 squareroot -0.000001       -> NaN Invalid_operation
+sqtx038 squareroot +0.000000000001 -> 0.000001
+sqtx039 squareroot -0.000000000001 -> NaN Invalid_operation
+
+sqtx041 squareroot 1.1        -> 1.04880885 Inexact Rounded
+sqtx042 squareroot 1.10       -> 1.04880885 Inexact Rounded
+sqtx043 squareroot 1.100      -> 1.04880885 Inexact Rounded
+sqtx044 squareroot 1.110      -> 1.05356538 Inexact Rounded
+sqtx045 squareroot -1.1       -> NaN Invalid_operation
+sqtx046 squareroot -1.10      -> NaN Invalid_operation
+sqtx047 squareroot -1.100     -> NaN Invalid_operation
+sqtx048 squareroot -1.110     -> NaN Invalid_operation
+sqtx049 squareroot 9.9        -> 3.14642654 Inexact Rounded
+sqtx050 squareroot 9.90       -> 3.14642654 Inexact Rounded
+sqtx051 squareroot 9.900      -> 3.14642654 Inexact Rounded
+sqtx052 squareroot 9.990      -> 3.16069613 Inexact Rounded
+sqtx053 squareroot -9.9       -> NaN Invalid_operation
+sqtx054 squareroot -9.90      -> NaN Invalid_operation
+sqtx055 squareroot -9.900     -> NaN Invalid_operation
+sqtx056 squareroot -9.990     -> NaN Invalid_operation
+
+sqtx060 squareroot  1           -> 1
+sqtx061 squareroot  1.0         -> 1.0
+sqtx062 squareroot  1.00        -> 1.0
+sqtx063 squareroot  10.0        -> 3.16227766 Inexact Rounded
+sqtx064 squareroot  10.0        -> 3.16227766 Inexact Rounded
+sqtx065 squareroot  10.0        -> 3.16227766 Inexact Rounded
+sqtx066 squareroot  10.00       -> 3.16227766 Inexact Rounded
+sqtx067 squareroot  100         -> 10
+sqtx068 squareroot  100.0       -> 10.0
+sqtx069 squareroot  100.00      -> 10.0
+sqtx070 squareroot  1.1000E+3   -> 33.1662479 Inexact Rounded
+sqtx071 squareroot  1.10000E+3  -> 33.1662479 Inexact Rounded
+sqtx072 squareroot -10.0        -> NaN Invalid_operation
+sqtx073 squareroot -10.00       -> NaN Invalid_operation
+sqtx074 squareroot -100.0       -> NaN Invalid_operation
+sqtx075 squareroot -100.00      -> NaN Invalid_operation
+sqtx076 squareroot -1.1000E+3   -> NaN Invalid_operation
+sqtx077 squareroot -1.10000E+3  -> NaN Invalid_operation
+
+-- famous squares
+sqtx080 squareroot     1  -> 1
+sqtx081 squareroot     4  -> 2
+sqtx082 squareroot     9  -> 3
+sqtx083 squareroot    16  -> 4
+sqtx084 squareroot    25  -> 5
+sqtx085 squareroot    36  -> 6
+sqtx086 squareroot    49  -> 7
+sqtx087 squareroot    64  -> 8
+sqtx088 squareroot    81  -> 9
+sqtx089 squareroot   100  -> 10
+sqtx090 squareroot   121  -> 11
+sqtx091 squareroot   144  -> 12
+sqtx092 squareroot   169  -> 13
+sqtx093 squareroot   256  -> 16
+sqtx094 squareroot  1024  -> 32
+sqtx095 squareroot  4096  -> 64
+sqtx100 squareroot   0.01 -> 0.1
+sqtx101 squareroot   0.04 -> 0.2
+sqtx102 squareroot   0.09 -> 0.3
+sqtx103 squareroot   0.16 -> 0.4
+sqtx104 squareroot   0.25 -> 0.5
+sqtx105 squareroot   0.36 -> 0.6
+sqtx106 squareroot   0.49 -> 0.7
+sqtx107 squareroot   0.64 -> 0.8
+sqtx108 squareroot   0.81 -> 0.9
+sqtx109 squareroot   1.00 -> 1.0
+sqtx110 squareroot   1.21 -> 1.1
+sqtx111 squareroot   1.44 -> 1.2
+sqtx112 squareroot   1.69 -> 1.3
+sqtx113 squareroot   2.56 -> 1.6
+sqtx114 squareroot  10.24 -> 3.2
+sqtx115 squareroot  40.96 -> 6.4
+
+-- Precision 1 squareroot tests [exhaustive, plus exponent adjusts]
+rounding:    half_even
+maxExponent: 999
+minexponent: -999
+precision:   1
+sqtx1201 squareroot 0.1 -> 0.3  Inexact Rounded
+sqtx1202 squareroot 0.01 -> 0.1
+sqtx1203 squareroot 1.0E-1 -> 0.3  Inexact Rounded
+sqtx1204 squareroot 1.00E-2 -> 0.1  Rounded
+sqtx1205 squareroot 1E-3 -> 0.03  Inexact Rounded
+sqtx1206 squareroot 1E+1 -> 3  Inexact Rounded
+sqtx1207 squareroot 1E+2 -> 1E+1
+sqtx1208 squareroot 1E+3 -> 3E+1  Inexact Rounded
+sqtx1209 squareroot 0.2 -> 0.4  Inexact Rounded
+sqtx1210 squareroot 0.02 -> 0.1  Inexact Rounded
+sqtx1211 squareroot 2.0E-1 -> 0.4  Inexact Rounded
+sqtx1212 squareroot 2.00E-2 -> 0.1  Inexact Rounded
+sqtx1213 squareroot 2E-3 -> 0.04  Inexact Rounded
+sqtx1214 squareroot 2E+1 -> 4  Inexact Rounded
+sqtx1215 squareroot 2E+2 -> 1E+1  Inexact Rounded
+sqtx1216 squareroot 2E+3 -> 4E+1  Inexact Rounded
+sqtx1217 squareroot 0.3 -> 0.5  Inexact Rounded
+sqtx1218 squareroot 0.03 -> 0.2  Inexact Rounded
+sqtx1219 squareroot 3.0E-1 -> 0.5  Inexact Rounded
+sqtx1220 squareroot 3.00E-2 -> 0.2  Inexact Rounded
+sqtx1221 squareroot 3E-3 -> 0.05  Inexact Rounded
+sqtx1222 squareroot 3E+1 -> 5  Inexact Rounded
+sqtx1223 squareroot 3E+2 -> 2E+1  Inexact Rounded
+sqtx1224 squareroot 3E+3 -> 5E+1  Inexact Rounded
+sqtx1225 squareroot 0.4 -> 0.6  Inexact Rounded
+sqtx1226 squareroot 0.04 -> 0.2
+sqtx1227 squareroot 4.0E-1 -> 0.6  Inexact Rounded
+sqtx1228 squareroot 4.00E-2 -> 0.2  Rounded
+sqtx1229 squareroot 4E-3 -> 0.06  Inexact Rounded
+sqtx1230 squareroot 4E+1 -> 6  Inexact Rounded
+sqtx1231 squareroot 4E+2 -> 2E+1
+sqtx1232 squareroot 4E+3 -> 6E+1  Inexact Rounded
+sqtx1233 squareroot 0.5 -> 0.7  Inexact Rounded
+sqtx1234 squareroot 0.05 -> 0.2  Inexact Rounded
+sqtx1235 squareroot 5.0E-1 -> 0.7  Inexact Rounded
+sqtx1236 squareroot 5.00E-2 -> 0.2  Inexact Rounded
+sqtx1237 squareroot 5E-3 -> 0.07  Inexact Rounded
+sqtx1238 squareroot 5E+1 -> 7  Inexact Rounded
+sqtx1239 squareroot 5E+2 -> 2E+1  Inexact Rounded
+sqtx1240 squareroot 5E+3 -> 7E+1  Inexact Rounded
+sqtx1241 squareroot 0.6 -> 0.8  Inexact Rounded
+sqtx1242 squareroot 0.06 -> 0.2  Inexact Rounded
+sqtx1243 squareroot 6.0E-1 -> 0.8  Inexact Rounded
+sqtx1244 squareroot 6.00E-2 -> 0.2  Inexact Rounded
+sqtx1245 squareroot 6E-3 -> 0.08  Inexact Rounded
+sqtx1246 squareroot 6E+1 -> 8  Inexact Rounded
+sqtx1247 squareroot 6E+2 -> 2E+1  Inexact Rounded
+sqtx1248 squareroot 6E+3 -> 8E+1  Inexact Rounded
+sqtx1249 squareroot 0.7 -> 0.8  Inexact Rounded
+sqtx1250 squareroot 0.07 -> 0.3  Inexact Rounded
+sqtx1251 squareroot 7.0E-1 -> 0.8  Inexact Rounded
+sqtx1252 squareroot 7.00E-2 -> 0.3  Inexact Rounded
+sqtx1253 squareroot 7E-3 -> 0.08  Inexact Rounded
+sqtx1254 squareroot 7E+1 -> 8  Inexact Rounded
+sqtx1255 squareroot 7E+2 -> 3E+1  Inexact Rounded
+sqtx1256 squareroot 7E+3 -> 8E+1  Inexact Rounded
+sqtx1257 squareroot 0.8 -> 0.9  Inexact Rounded
+sqtx1258 squareroot 0.08 -> 0.3  Inexact Rounded
+sqtx1259 squareroot 8.0E-1 -> 0.9  Inexact Rounded
+sqtx1260 squareroot 8.00E-2 -> 0.3  Inexact Rounded
+sqtx1261 squareroot 8E-3 -> 0.09  Inexact Rounded
+sqtx1262 squareroot 8E+1 -> 9  Inexact Rounded
+sqtx1263 squareroot 8E+2 -> 3E+1  Inexact Rounded
+sqtx1264 squareroot 8E+3 -> 9E+1  Inexact Rounded
+sqtx1265 squareroot 0.9 -> 0.9  Inexact Rounded
+sqtx1266 squareroot 0.09 -> 0.3
+sqtx1267 squareroot 9.0E-1 -> 0.9  Inexact Rounded
+sqtx1268 squareroot 9.00E-2 -> 0.3  Rounded
+sqtx1269 squareroot 9E-3 -> 0.09  Inexact Rounded
+sqtx1270 squareroot 9E+1 -> 9  Inexact Rounded
+sqtx1271 squareroot 9E+2 -> 3E+1
+sqtx1272 squareroot 9E+3 -> 9E+1  Inexact Rounded
+
+-- Precision 2 squareroot tests [exhaustive, plus exponent adjusts]
+rounding:    half_even
+maxExponent: 999
+minexponent: -999
+precision:   2
+sqtx2201 squareroot 0.1 -> 0.32  Inexact Rounded
+sqtx2202 squareroot 0.01 -> 0.1
+sqtx2203 squareroot 1.0E-1 -> 0.32  Inexact Rounded
+sqtx2204 squareroot 1.00E-2 -> 0.10
+sqtx2205 squareroot 1E-3 -> 0.032  Inexact Rounded
+sqtx2206 squareroot 1E+1 -> 3.2  Inexact Rounded
+sqtx2207 squareroot 1E+2 -> 1E+1
+sqtx2208 squareroot 1E+3 -> 32  Inexact Rounded
+sqtx2209 squareroot 0.2 -> 0.45  Inexact Rounded
+sqtx2210 squareroot 0.02 -> 0.14  Inexact Rounded
+sqtx2211 squareroot 2.0E-1 -> 0.45  Inexact Rounded
+sqtx2212 squareroot 2.00E-2 -> 0.14  Inexact Rounded
+sqtx2213 squareroot 2E-3 -> 0.045  Inexact Rounded
+sqtx2214 squareroot 2E+1 -> 4.5  Inexact Rounded
+sqtx2215 squareroot 2E+2 -> 14  Inexact Rounded
+sqtx2216 squareroot 2E+3 -> 45  Inexact Rounded
+sqtx2217 squareroot 0.3 -> 0.55  Inexact Rounded
+sqtx2218 squareroot 0.03 -> 0.17  Inexact Rounded
+sqtx2219 squareroot 3.0E-1 -> 0.55  Inexact Rounded
+sqtx2220 squareroot 3.00E-2 -> 0.17  Inexact Rounded
+sqtx2221 squareroot 3E-3 -> 0.055  Inexact Rounded
+sqtx2222 squareroot 3E+1 -> 5.5  Inexact Rounded
+sqtx2223 squareroot 3E+2 -> 17  Inexact Rounded
+sqtx2224 squareroot 3E+3 -> 55  Inexact Rounded
+sqtx2225 squareroot 0.4 -> 0.63  Inexact Rounded
+sqtx2226 squareroot 0.04 -> 0.2
+sqtx2227 squareroot 4.0E-1 -> 0.63  Inexact Rounded
+sqtx2228 squareroot 4.00E-2 -> 0.20
+sqtx2229 squareroot 4E-3 -> 0.063  Inexact Rounded
+sqtx2230 squareroot 4E+1 -> 6.3  Inexact Rounded
+sqtx2231 squareroot 4E+2 -> 2E+1
+sqtx2232 squareroot 4E+3 -> 63  Inexact Rounded
+sqtx2233 squareroot 0.5 -> 0.71  Inexact Rounded
+sqtx2234 squareroot 0.05 -> 0.22  Inexact Rounded
+sqtx2235 squareroot 5.0E-1 -> 0.71  Inexact Rounded
+sqtx2236 squareroot 5.00E-2 -> 0.22  Inexact Rounded
+sqtx2237 squareroot 5E-3 -> 0.071  Inexact Rounded
+sqtx2238 squareroot 5E+1 -> 7.1  Inexact Rounded
+sqtx2239 squareroot 5E+2 -> 22  Inexact Rounded
+sqtx2240 squareroot 5E+3 -> 71  Inexact Rounded
+sqtx2241 squareroot 0.6 -> 0.77  Inexact Rounded
+sqtx2242 squareroot 0.06 -> 0.24  Inexact Rounded
+sqtx2243 squareroot 6.0E-1 -> 0.77  Inexact Rounded
+sqtx2244 squareroot 6.00E-2 -> 0.24  Inexact Rounded
+sqtx2245 squareroot 6E-3 -> 0.077  Inexact Rounded
+sqtx2246 squareroot 6E+1 -> 7.7  Inexact Rounded
+sqtx2247 squareroot 6E+2 -> 24  Inexact Rounded
+sqtx2248 squareroot 6E+3 -> 77  Inexact Rounded
+sqtx2249 squareroot 0.7 -> 0.84  Inexact Rounded
+sqtx2250 squareroot 0.07 -> 0.26  Inexact Rounded
+sqtx2251 squareroot 7.0E-1 -> 0.84  Inexact Rounded
+sqtx2252 squareroot 7.00E-2 -> 0.26  Inexact Rounded
+sqtx2253 squareroot 7E-3 -> 0.084  Inexact Rounded
+sqtx2254 squareroot 7E+1 -> 8.4  Inexact Rounded
+sqtx2255 squareroot 7E+2 -> 26  Inexact Rounded
+sqtx2256 squareroot 7E+3 -> 84  Inexact Rounded
+sqtx2257 squareroot 0.8 -> 0.89  Inexact Rounded
+sqtx2258 squareroot 0.08 -> 0.28  Inexact Rounded
+sqtx2259 squareroot 8.0E-1 -> 0.89  Inexact Rounded
+sqtx2260 squareroot 8.00E-2 -> 0.28  Inexact Rounded
+sqtx2261 squareroot 8E-3 -> 0.089  Inexact Rounded
+sqtx2262 squareroot 8E+1 -> 8.9  Inexact Rounded
+sqtx2263 squareroot 8E+2 -> 28  Inexact Rounded
+sqtx2264 squareroot 8E+3 -> 89  Inexact Rounded
+sqtx2265 squareroot 0.9 -> 0.95  Inexact Rounded
+sqtx2266 squareroot 0.09 -> 0.3
+sqtx2267 squareroot 9.0E-1 -> 0.95  Inexact Rounded
+sqtx2268 squareroot 9.00E-2 -> 0.30
+sqtx2269 squareroot 9E-3 -> 0.095  Inexact Rounded
+sqtx2270 squareroot 9E+1 -> 9.5  Inexact Rounded
+sqtx2271 squareroot 9E+2 -> 3E+1
+sqtx2272 squareroot 9E+3 -> 95  Inexact Rounded
+sqtx2273 squareroot 0.10 -> 0.32  Inexact Rounded
+sqtx2274 squareroot 0.010 -> 0.10
+sqtx2275 squareroot 10.0E-1 -> 1.0
+sqtx2276 squareroot 10.00E-2 -> 0.32  Inexact Rounded
+sqtx2277 squareroot 10E-3 -> 0.10
+sqtx2278 squareroot 10E+1 -> 10
+sqtx2279 squareroot 10E+2 -> 32  Inexact Rounded
+sqtx2280 squareroot 10E+3 -> 1.0E+2
+sqtx2281 squareroot 0.11 -> 0.33  Inexact Rounded
+sqtx2282 squareroot 0.011 -> 0.10  Inexact Rounded
+sqtx2283 squareroot 11.0E-1 -> 1.0  Inexact Rounded
+sqtx2284 squareroot 11.00E-2 -> 0.33  Inexact Rounded
+sqtx2285 squareroot 11E-3 -> 0.10  Inexact Rounded
+sqtx2286 squareroot 11E+1 -> 10  Inexact Rounded
+sqtx2287 squareroot 11E+2 -> 33  Inexact Rounded
+sqtx2288 squareroot 11E+3 -> 1.0E+2  Inexact Rounded
+sqtx2289 squareroot 0.12 -> 0.35  Inexact Rounded
+sqtx2290 squareroot 0.012 -> 0.11  Inexact Rounded
+sqtx2291 squareroot 12.0E-1 -> 1.1  Inexact Rounded
+sqtx2292 squareroot 12.00E-2 -> 0.35  Inexact Rounded
+sqtx2293 squareroot 12E-3 -> 0.11  Inexact Rounded
+sqtx2294 squareroot 12E+1 -> 11  Inexact Rounded
+sqtx2295 squareroot 12E+2 -> 35  Inexact Rounded
+sqtx2296 squareroot 12E+3 -> 1.1E+2  Inexact Rounded
+sqtx2297 squareroot 0.13 -> 0.36  Inexact Rounded
+sqtx2298 squareroot 0.013 -> 0.11  Inexact Rounded
+sqtx2299 squareroot 13.0E-1 -> 1.1  Inexact Rounded
+sqtx2300 squareroot 13.00E-2 -> 0.36  Inexact Rounded
+sqtx2301 squareroot 13E-3 -> 0.11  Inexact Rounded
+sqtx2302 squareroot 13E+1 -> 11  Inexact Rounded
+sqtx2303 squareroot 13E+2 -> 36  Inexact Rounded
+sqtx2304 squareroot 13E+3 -> 1.1E+2  Inexact Rounded
+sqtx2305 squareroot 0.14 -> 0.37  Inexact Rounded
+sqtx2306 squareroot 0.014 -> 0.12  Inexact Rounded
+sqtx2307 squareroot 14.0E-1 -> 1.2  Inexact Rounded
+sqtx2308 squareroot 14.00E-2 -> 0.37  Inexact Rounded
+sqtx2309 squareroot 14E-3 -> 0.12  Inexact Rounded
+sqtx2310 squareroot 14E+1 -> 12  Inexact Rounded
+sqtx2311 squareroot 14E+2 -> 37  Inexact Rounded
+sqtx2312 squareroot 14E+3 -> 1.2E+2  Inexact Rounded
+sqtx2313 squareroot 0.15 -> 0.39  Inexact Rounded
+sqtx2314 squareroot 0.015 -> 0.12  Inexact Rounded
+sqtx2315 squareroot 15.0E-1 -> 1.2  Inexact Rounded
+sqtx2316 squareroot 15.00E-2 -> 0.39  Inexact Rounded
+sqtx2317 squareroot 15E-3 -> 0.12  Inexact Rounded
+sqtx2318 squareroot 15E+1 -> 12  Inexact Rounded
+sqtx2319 squareroot 15E+2 -> 39  Inexact Rounded
+sqtx2320 squareroot 15E+3 -> 1.2E+2  Inexact Rounded
+sqtx2321 squareroot 0.16 -> 0.4
+sqtx2322 squareroot 0.016 -> 0.13  Inexact Rounded
+sqtx2323 squareroot 16.0E-1 -> 1.3  Inexact Rounded
+sqtx2324 squareroot 16.00E-2 -> 0.40
+sqtx2325 squareroot 16E-3 -> 0.13  Inexact Rounded
+sqtx2326 squareroot 16E+1 -> 13  Inexact Rounded
+sqtx2327 squareroot 16E+2 -> 4E+1
+sqtx2328 squareroot 16E+3 -> 1.3E+2  Inexact Rounded
+sqtx2329 squareroot 0.17 -> 0.41  Inexact Rounded
+sqtx2330 squareroot 0.017 -> 0.13  Inexact Rounded
+sqtx2331 squareroot 17.0E-1 -> 1.3  Inexact Rounded
+sqtx2332 squareroot 17.00E-2 -> 0.41  Inexact Rounded
+sqtx2333 squareroot 17E-3 -> 0.13  Inexact Rounded
+sqtx2334 squareroot 17E+1 -> 13  Inexact Rounded
+sqtx2335 squareroot 17E+2 -> 41  Inexact Rounded
+sqtx2336 squareroot 17E+3 -> 1.3E+2  Inexact Rounded
+sqtx2337 squareroot 0.18 -> 0.42  Inexact Rounded
+sqtx2338 squareroot 0.018 -> 0.13  Inexact Rounded
+sqtx2339 squareroot 18.0E-1 -> 1.3  Inexact Rounded
+sqtx2340 squareroot 18.00E-2 -> 0.42  Inexact Rounded
+sqtx2341 squareroot 18E-3 -> 0.13  Inexact Rounded
+sqtx2342 squareroot 18E+1 -> 13  Inexact Rounded
+sqtx2343 squareroot 18E+2 -> 42  Inexact Rounded
+sqtx2344 squareroot 18E+3 -> 1.3E+2  Inexact Rounded
+sqtx2345 squareroot 0.19 -> 0.44  Inexact Rounded
+sqtx2346 squareroot 0.019 -> 0.14  Inexact Rounded
+sqtx2347 squareroot 19.0E-1 -> 1.4  Inexact Rounded
+sqtx2348 squareroot 19.00E-2 -> 0.44  Inexact Rounded
+sqtx2349 squareroot 19E-3 -> 0.14  Inexact Rounded
+sqtx2350 squareroot 19E+1 -> 14  Inexact Rounded
+sqtx2351 squareroot 19E+2 -> 44  Inexact Rounded
+sqtx2352 squareroot 19E+3 -> 1.4E+2  Inexact Rounded
+sqtx2353 squareroot 0.20 -> 0.45  Inexact Rounded
+sqtx2354 squareroot 0.020 -> 0.14  Inexact Rounded
+sqtx2355 squareroot 20.0E-1 -> 1.4  Inexact Rounded
+sqtx2356 squareroot 20.00E-2 -> 0.45  Inexact Rounded
+sqtx2357 squareroot 20E-3 -> 0.14  Inexact Rounded
+sqtx2358 squareroot 20E+1 -> 14  Inexact Rounded
+sqtx2359 squareroot 20E+2 -> 45  Inexact Rounded
+sqtx2360 squareroot 20E+3 -> 1.4E+2  Inexact Rounded
+sqtx2361 squareroot 0.21 -> 0.46  Inexact Rounded
+sqtx2362 squareroot 0.021 -> 0.14  Inexact Rounded
+sqtx2363 squareroot 21.0E-1 -> 1.4  Inexact Rounded
+sqtx2364 squareroot 21.00E-2 -> 0.46  Inexact Rounded
+sqtx2365 squareroot 21E-3 -> 0.14  Inexact Rounded
+sqtx2366 squareroot 21E+1 -> 14  Inexact Rounded
+sqtx2367 squareroot 21E+2 -> 46  Inexact Rounded
+sqtx2368 squareroot 21E+3 -> 1.4E+2  Inexact Rounded
+sqtx2369 squareroot 0.22 -> 0.47  Inexact Rounded
+sqtx2370 squareroot 0.022 -> 0.15  Inexact Rounded
+sqtx2371 squareroot 22.0E-1 -> 1.5  Inexact Rounded
+sqtx2372 squareroot 22.00E-2 -> 0.47  Inexact Rounded
+sqtx2373 squareroot 22E-3 -> 0.15  Inexact Rounded
+sqtx2374 squareroot 22E+1 -> 15  Inexact Rounded
+sqtx2375 squareroot 22E+2 -> 47  Inexact Rounded
+sqtx2376 squareroot 22E+3 -> 1.5E+2  Inexact Rounded
+sqtx2377 squareroot 0.23 -> 0.48  Inexact Rounded
+sqtx2378 squareroot 0.023 -> 0.15  Inexact Rounded
+sqtx2379 squareroot 23.0E-1 -> 1.5  Inexact Rounded
+sqtx2380 squareroot 23.00E-2 -> 0.48  Inexact Rounded
+sqtx2381 squareroot 23E-3 -> 0.15  Inexact Rounded
+sqtx2382 squareroot 23E+1 -> 15  Inexact Rounded
+sqtx2383 squareroot 23E+2 -> 48  Inexact Rounded
+sqtx2384 squareroot 23E+3 -> 1.5E+2  Inexact Rounded
+sqtx2385 squareroot 0.24 -> 0.49  Inexact Rounded
+sqtx2386 squareroot 0.024 -> 0.15  Inexact Rounded
+sqtx2387 squareroot 24.0E-1 -> 1.5  Inexact Rounded
+sqtx2388 squareroot 24.00E-2 -> 0.49  Inexact Rounded
+sqtx2389 squareroot 24E-3 -> 0.15  Inexact Rounded
+sqtx2390 squareroot 24E+1 -> 15  Inexact Rounded
+sqtx2391 squareroot 24E+2 -> 49  Inexact Rounded
+sqtx2392 squareroot 24E+3 -> 1.5E+2  Inexact Rounded
+sqtx2393 squareroot 0.25 -> 0.5
+sqtx2394 squareroot 0.025 -> 0.16  Inexact Rounded
+sqtx2395 squareroot 25.0E-1 -> 1.6  Inexact Rounded
+sqtx2396 squareroot 25.00E-2 -> 0.50
+sqtx2397 squareroot 25E-3 -> 0.16  Inexact Rounded
+sqtx2398 squareroot 25E+1 -> 16  Inexact Rounded
+sqtx2399 squareroot 25E+2 -> 5E+1
+sqtx2400 squareroot 25E+3 -> 1.6E+2  Inexact Rounded
+sqtx2401 squareroot 0.26 -> 0.51  Inexact Rounded
+sqtx2402 squareroot 0.026 -> 0.16  Inexact Rounded
+sqtx2403 squareroot 26.0E-1 -> 1.6  Inexact Rounded
+sqtx2404 squareroot 26.00E-2 -> 0.51  Inexact Rounded
+sqtx2405 squareroot 26E-3 -> 0.16  Inexact Rounded
+sqtx2406 squareroot 26E+1 -> 16  Inexact Rounded
+sqtx2407 squareroot 26E+2 -> 51  Inexact Rounded
+sqtx2408 squareroot 26E+3 -> 1.6E+2  Inexact Rounded
+sqtx2409 squareroot 0.27 -> 0.52  Inexact Rounded
+sqtx2410 squareroot 0.027 -> 0.16  Inexact Rounded
+sqtx2411 squareroot 27.0E-1 -> 1.6  Inexact Rounded
+sqtx2412 squareroot 27.00E-2 -> 0.52  Inexact Rounded
+sqtx2413 squareroot 27E-3 -> 0.16  Inexact Rounded
+sqtx2414 squareroot 27E+1 -> 16  Inexact Rounded
+sqtx2415 squareroot 27E+2 -> 52  Inexact Rounded
+sqtx2416 squareroot 27E+3 -> 1.6E+2  Inexact Rounded
+sqtx2417 squareroot 0.28 -> 0.53  Inexact Rounded
+sqtx2418 squareroot 0.028 -> 0.17  Inexact Rounded
+sqtx2419 squareroot 28.0E-1 -> 1.7  Inexact Rounded
+sqtx2420 squareroot 28.00E-2 -> 0.53  Inexact Rounded
+sqtx2421 squareroot 28E-3 -> 0.17  Inexact Rounded
+sqtx2422 squareroot 28E+1 -> 17  Inexact Rounded
+sqtx2423 squareroot 28E+2 -> 53  Inexact Rounded
+sqtx2424 squareroot 28E+3 -> 1.7E+2  Inexact Rounded
+sqtx2425 squareroot 0.29 -> 0.54  Inexact Rounded
+sqtx2426 squareroot 0.029 -> 0.17  Inexact Rounded
+sqtx2427 squareroot 29.0E-1 -> 1.7  Inexact Rounded
+sqtx2428 squareroot 29.00E-2 -> 0.54  Inexact Rounded
+sqtx2429 squareroot 29E-3 -> 0.17  Inexact Rounded
+sqtx2430 squareroot 29E+1 -> 17  Inexact Rounded
+sqtx2431 squareroot 29E+2 -> 54  Inexact Rounded
+sqtx2432 squareroot 29E+3 -> 1.7E+2  Inexact Rounded
+sqtx2433 squareroot 0.30 -> 0.55  Inexact Rounded
+sqtx2434 squareroot 0.030 -> 0.17  Inexact Rounded
+sqtx2435 squareroot 30.0E-1 -> 1.7  Inexact Rounded
+sqtx2436 squareroot 30.00E-2 -> 0.55  Inexact Rounded
+sqtx2437 squareroot 30E-3 -> 0.17  Inexact Rounded
+sqtx2438 squareroot 30E+1 -> 17  Inexact Rounded
+sqtx2439 squareroot 30E+2 -> 55  Inexact Rounded
+sqtx2440 squareroot 30E+3 -> 1.7E+2  Inexact Rounded
+sqtx2441 squareroot 0.31 -> 0.56  Inexact Rounded
+sqtx2442 squareroot 0.031 -> 0.18  Inexact Rounded
+sqtx2443 squareroot 31.0E-1 -> 1.8  Inexact Rounded
+sqtx2444 squareroot 31.00E-2 -> 0.56  Inexact Rounded
+sqtx2445 squareroot 31E-3 -> 0.18  Inexact Rounded
+sqtx2446 squareroot 31E+1 -> 18  Inexact Rounded
+sqtx2447 squareroot 31E+2 -> 56  Inexact Rounded
+sqtx2448 squareroot 31E+3 -> 1.8E+2  Inexact Rounded
+sqtx2449 squareroot 0.32 -> 0.57  Inexact Rounded
+sqtx2450 squareroot 0.032 -> 0.18  Inexact Rounded
+sqtx2451 squareroot 32.0E-1 -> 1.8  Inexact Rounded
+sqtx2452 squareroot 32.00E-2 -> 0.57  Inexact Rounded
+sqtx2453 squareroot 32E-3 -> 0.18  Inexact Rounded
+sqtx2454 squareroot 32E+1 -> 18  Inexact Rounded
+sqtx2455 squareroot 32E+2 -> 57  Inexact Rounded
+sqtx2456 squareroot 32E+3 -> 1.8E+2  Inexact Rounded
+sqtx2457 squareroot 0.33 -> 0.57  Inexact Rounded
+sqtx2458 squareroot 0.033 -> 0.18  Inexact Rounded
+sqtx2459 squareroot 33.0E-1 -> 1.8  Inexact Rounded
+sqtx2460 squareroot 33.00E-2 -> 0.57  Inexact Rounded
+sqtx2461 squareroot 33E-3 -> 0.18  Inexact Rounded
+sqtx2462 squareroot 33E+1 -> 18  Inexact Rounded
+sqtx2463 squareroot 33E+2 -> 57  Inexact Rounded
+sqtx2464 squareroot 33E+3 -> 1.8E+2  Inexact Rounded
+sqtx2465 squareroot 0.34 -> 0.58  Inexact Rounded
+sqtx2466 squareroot 0.034 -> 0.18  Inexact Rounded
+sqtx2467 squareroot 34.0E-1 -> 1.8  Inexact Rounded
+sqtx2468 squareroot 34.00E-2 -> 0.58  Inexact Rounded
+sqtx2469 squareroot 34E-3 -> 0.18  Inexact Rounded
+sqtx2470 squareroot 34E+1 -> 18  Inexact Rounded
+sqtx2471 squareroot 34E+2 -> 58  Inexact Rounded
+sqtx2472 squareroot 34E+3 -> 1.8E+2  Inexact Rounded
+sqtx2473 squareroot 0.35 -> 0.59  Inexact Rounded
+sqtx2474 squareroot 0.035 -> 0.19  Inexact Rounded
+sqtx2475 squareroot 35.0E-1 -> 1.9  Inexact Rounded
+sqtx2476 squareroot 35.00E-2 -> 0.59  Inexact Rounded
+sqtx2477 squareroot 35E-3 -> 0.19  Inexact Rounded
+sqtx2478 squareroot 35E+1 -> 19  Inexact Rounded
+sqtx2479 squareroot 35E+2 -> 59  Inexact Rounded
+sqtx2480 squareroot 35E+3 -> 1.9E+2  Inexact Rounded
+sqtx2481 squareroot 0.36 -> 0.6
+sqtx2482 squareroot 0.036 -> 0.19  Inexact Rounded
+sqtx2483 squareroot 36.0E-1 -> 1.9  Inexact Rounded
+sqtx2484 squareroot 36.00E-2 -> 0.60
+sqtx2485 squareroot 36E-3 -> 0.19  Inexact Rounded
+sqtx2486 squareroot 36E+1 -> 19  Inexact Rounded
+sqtx2487 squareroot 36E+2 -> 6E+1
+sqtx2488 squareroot 36E+3 -> 1.9E+2  Inexact Rounded
+sqtx2489 squareroot 0.37 -> 0.61  Inexact Rounded
+sqtx2490 squareroot 0.037 -> 0.19  Inexact Rounded
+sqtx2491 squareroot 37.0E-1 -> 1.9  Inexact Rounded
+sqtx2492 squareroot 37.00E-2 -> 0.61  Inexact Rounded
+sqtx2493 squareroot 37E-3 -> 0.19  Inexact Rounded
+sqtx2494 squareroot 37E+1 -> 19  Inexact Rounded
+sqtx2495 squareroot 37E+2 -> 61  Inexact Rounded
+sqtx2496 squareroot 37E+3 -> 1.9E+2  Inexact Rounded
+sqtx2497 squareroot 0.38 -> 0.62  Inexact Rounded
+sqtx2498 squareroot 0.038 -> 0.19  Inexact Rounded
+sqtx2499 squareroot 38.0E-1 -> 1.9  Inexact Rounded
+sqtx2500 squareroot 38.00E-2 -> 0.62  Inexact Rounded
+sqtx2501 squareroot 38E-3 -> 0.19  Inexact Rounded
+sqtx2502 squareroot 38E+1 -> 19  Inexact Rounded
+sqtx2503 squareroot 38E+2 -> 62  Inexact Rounded
+sqtx2504 squareroot 38E+3 -> 1.9E+2  Inexact Rounded
+sqtx2505 squareroot 0.39 -> 0.62  Inexact Rounded
+sqtx2506 squareroot 0.039 -> 0.20  Inexact Rounded
+sqtx2507 squareroot 39.0E-1 -> 2.0  Inexact Rounded
+sqtx2508 squareroot 39.00E-2 -> 0.62  Inexact Rounded
+sqtx2509 squareroot 39E-3 -> 0.20  Inexact Rounded
+sqtx2510 squareroot 39E+1 -> 20  Inexact Rounded
+sqtx2511 squareroot 39E+2 -> 62  Inexact Rounded
+sqtx2512 squareroot 39E+3 -> 2.0E+2  Inexact Rounded
+sqtx2513 squareroot 0.40 -> 0.63  Inexact Rounded
+sqtx2514 squareroot 0.040 -> 0.20
+sqtx2515 squareroot 40.0E-1 -> 2.0
+sqtx2516 squareroot 40.00E-2 -> 0.63  Inexact Rounded
+sqtx2517 squareroot 40E-3 -> 0.20
+sqtx2518 squareroot 40E+1 -> 20
+sqtx2519 squareroot 40E+2 -> 63  Inexact Rounded
+sqtx2520 squareroot 40E+3 -> 2.0E+2
+sqtx2521 squareroot 0.41 -> 0.64  Inexact Rounded
+sqtx2522 squareroot 0.041 -> 0.20  Inexact Rounded
+sqtx2523 squareroot 41.0E-1 -> 2.0  Inexact Rounded
+sqtx2524 squareroot 41.00E-2 -> 0.64  Inexact Rounded
+sqtx2525 squareroot 41E-3 -> 0.20  Inexact Rounded
+sqtx2526 squareroot 41E+1 -> 20  Inexact Rounded
+sqtx2527 squareroot 41E+2 -> 64  Inexact Rounded
+sqtx2528 squareroot 41E+3 -> 2.0E+2  Inexact Rounded
+sqtx2529 squareroot 0.42 -> 0.65  Inexact Rounded
+sqtx2530 squareroot 0.042 -> 0.20  Inexact Rounded
+sqtx2531 squareroot 42.0E-1 -> 2.0  Inexact Rounded
+sqtx2532 squareroot 42.00E-2 -> 0.65  Inexact Rounded
+sqtx2533 squareroot 42E-3 -> 0.20  Inexact Rounded
+sqtx2534 squareroot 42E+1 -> 20  Inexact Rounded
+sqtx2535 squareroot 42E+2 -> 65  Inexact Rounded
+sqtx2536 squareroot 42E+3 -> 2.0E+2  Inexact Rounded
+sqtx2537 squareroot 0.43 -> 0.66  Inexact Rounded
+sqtx2538 squareroot 0.043 -> 0.21  Inexact Rounded
+sqtx2539 squareroot 43.0E-1 -> 2.1  Inexact Rounded
+sqtx2540 squareroot 43.00E-2 -> 0.66  Inexact Rounded
+sqtx2541 squareroot 43E-3 -> 0.21  Inexact Rounded
+sqtx2542 squareroot 43E+1 -> 21  Inexact Rounded
+sqtx2543 squareroot 43E+2 -> 66  Inexact Rounded
+sqtx2544 squareroot 43E+3 -> 2.1E+2  Inexact Rounded
+sqtx2545 squareroot 0.44 -> 0.66  Inexact Rounded
+sqtx2546 squareroot 0.044 -> 0.21  Inexact Rounded
+sqtx2547 squareroot 44.0E-1 -> 2.1  Inexact Rounded
+sqtx2548 squareroot 44.00E-2 -> 0.66  Inexact Rounded
+sqtx2549 squareroot 44E-3 -> 0.21  Inexact Rounded
+sqtx2550 squareroot 44E+1 -> 21  Inexact Rounded
+sqtx2551 squareroot 44E+2 -> 66  Inexact Rounded
+sqtx2552 squareroot 44E+3 -> 2.1E+2  Inexact Rounded
+sqtx2553 squareroot 0.45 -> 0.67  Inexact Rounded
+sqtx2554 squareroot 0.045 -> 0.21  Inexact Rounded
+sqtx2555 squareroot 45.0E-1 -> 2.1  Inexact Rounded
+sqtx2556 squareroot 45.00E-2 -> 0.67  Inexact Rounded
+sqtx2557 squareroot 45E-3 -> 0.21  Inexact Rounded
+sqtx2558 squareroot 45E+1 -> 21  Inexact Rounded
+sqtx2559 squareroot 45E+2 -> 67  Inexact Rounded
+sqtx2560 squareroot 45E+3 -> 2.1E+2  Inexact Rounded
+sqtx2561 squareroot 0.46 -> 0.68  Inexact Rounded
+sqtx2562 squareroot 0.046 -> 0.21  Inexact Rounded
+sqtx2563 squareroot 46.0E-1 -> 2.1  Inexact Rounded
+sqtx2564 squareroot 46.00E-2 -> 0.68  Inexact Rounded
+sqtx2565 squareroot 46E-3 -> 0.21  Inexact Rounded
+sqtx2566 squareroot 46E+1 -> 21  Inexact Rounded
+sqtx2567 squareroot 46E+2 -> 68  Inexact Rounded
+sqtx2568 squareroot 46E+3 -> 2.1E+2  Inexact Rounded
+sqtx2569 squareroot 0.47 -> 0.69  Inexact Rounded
+sqtx2570 squareroot 0.047 -> 0.22  Inexact Rounded
+sqtx2571 squareroot 47.0E-1 -> 2.2  Inexact Rounded
+sqtx2572 squareroot 47.00E-2 -> 0.69  Inexact Rounded
+sqtx2573 squareroot 47E-3 -> 0.22  Inexact Rounded
+sqtx2574 squareroot 47E+1 -> 22  Inexact Rounded
+sqtx2575 squareroot 47E+2 -> 69  Inexact Rounded
+sqtx2576 squareroot 47E+3 -> 2.2E+2  Inexact Rounded
+sqtx2577 squareroot 0.48 -> 0.69  Inexact Rounded
+sqtx2578 squareroot 0.048 -> 0.22  Inexact Rounded
+sqtx2579 squareroot 48.0E-1 -> 2.2  Inexact Rounded
+sqtx2580 squareroot 48.00E-2 -> 0.69  Inexact Rounded
+sqtx2581 squareroot 48E-3 -> 0.22  Inexact Rounded
+sqtx2582 squareroot 48E+1 -> 22  Inexact Rounded
+sqtx2583 squareroot 48E+2 -> 69  Inexact Rounded
+sqtx2584 squareroot 48E+3 -> 2.2E+2  Inexact Rounded
+sqtx2585 squareroot 0.49 -> 0.7
+sqtx2586 squareroot 0.049 -> 0.22  Inexact Rounded
+sqtx2587 squareroot 49.0E-1 -> 2.2  Inexact Rounded
+sqtx2588 squareroot 49.00E-2 -> 0.70
+sqtx2589 squareroot 49E-3 -> 0.22  Inexact Rounded
+sqtx2590 squareroot 49E+1 -> 22  Inexact Rounded
+sqtx2591 squareroot 49E+2 -> 7E+1
+sqtx2592 squareroot 49E+3 -> 2.2E+2  Inexact Rounded
+sqtx2593 squareroot 0.50 -> 0.71  Inexact Rounded
+sqtx2594 squareroot 0.050 -> 0.22  Inexact Rounded
+sqtx2595 squareroot 50.0E-1 -> 2.2  Inexact Rounded
+sqtx2596 squareroot 50.00E-2 -> 0.71  Inexact Rounded
+sqtx2597 squareroot 50E-3 -> 0.22  Inexact Rounded
+sqtx2598 squareroot 50E+1 -> 22  Inexact Rounded
+sqtx2599 squareroot 50E+2 -> 71  Inexact Rounded
+sqtx2600 squareroot 50E+3 -> 2.2E+2  Inexact Rounded
+sqtx2601 squareroot 0.51 -> 0.71  Inexact Rounded
+sqtx2602 squareroot 0.051 -> 0.23  Inexact Rounded
+sqtx2603 squareroot 51.0E-1 -> 2.3  Inexact Rounded
+sqtx2604 squareroot 51.00E-2 -> 0.71  Inexact Rounded
+sqtx2605 squareroot 51E-3 -> 0.23  Inexact Rounded
+sqtx2606 squareroot 51E+1 -> 23  Inexact Rounded
+sqtx2607 squareroot 51E+2 -> 71  Inexact Rounded
+sqtx2608 squareroot 51E+3 -> 2.3E+2  Inexact Rounded
+sqtx2609 squareroot 0.52 -> 0.72  Inexact Rounded
+sqtx2610 squareroot 0.052 -> 0.23  Inexact Rounded
+sqtx2611 squareroot 52.0E-1 -> 2.3  Inexact Rounded
+sqtx2612 squareroot 52.00E-2 -> 0.72  Inexact Rounded
+sqtx2613 squareroot 52E-3 -> 0.23  Inexact Rounded
+sqtx2614 squareroot 52E+1 -> 23  Inexact Rounded
+sqtx2615 squareroot 52E+2 -> 72  Inexact Rounded
+sqtx2616 squareroot 52E+3 -> 2.3E+2  Inexact Rounded
+sqtx2617 squareroot 0.53 -> 0.73  Inexact Rounded
+sqtx2618 squareroot 0.053 -> 0.23  Inexact Rounded
+sqtx2619 squareroot 53.0E-1 -> 2.3  Inexact Rounded
+sqtx2620 squareroot 53.00E-2 -> 0.73  Inexact Rounded
+sqtx2621 squareroot 53E-3 -> 0.23  Inexact Rounded
+sqtx2622 squareroot 53E+1 -> 23  Inexact Rounded
+sqtx2623 squareroot 53E+2 -> 73  Inexact Rounded
+sqtx2624 squareroot 53E+3 -> 2.3E+2  Inexact Rounded
+sqtx2625 squareroot 0.54 -> 0.73  Inexact Rounded
+sqtx2626 squareroot 0.054 -> 0.23  Inexact Rounded
+sqtx2627 squareroot 54.0E-1 -> 2.3  Inexact Rounded
+sqtx2628 squareroot 54.00E-2 -> 0.73  Inexact Rounded
+sqtx2629 squareroot 54E-3 -> 0.23  Inexact Rounded
+sqtx2630 squareroot 54E+1 -> 23  Inexact Rounded
+sqtx2631 squareroot 54E+2 -> 73  Inexact Rounded
+sqtx2632 squareroot 54E+3 -> 2.3E+2  Inexact Rounded
+sqtx2633 squareroot 0.55 -> 0.74  Inexact Rounded
+sqtx2634 squareroot 0.055 -> 0.23  Inexact Rounded
+sqtx2635 squareroot 55.0E-1 -> 2.3  Inexact Rounded
+sqtx2636 squareroot 55.00E-2 -> 0.74  Inexact Rounded
+sqtx2637 squareroot 55E-3 -> 0.23  Inexact Rounded
+sqtx2638 squareroot 55E+1 -> 23  Inexact Rounded
+sqtx2639 squareroot 55E+2 -> 74  Inexact Rounded
+sqtx2640 squareroot 55E+3 -> 2.3E+2  Inexact Rounded
+sqtx2641 squareroot 0.56 -> 0.75  Inexact Rounded
+sqtx2642 squareroot 0.056 -> 0.24  Inexact Rounded
+sqtx2643 squareroot 56.0E-1 -> 2.4  Inexact Rounded
+sqtx2644 squareroot 56.00E-2 -> 0.75  Inexact Rounded
+sqtx2645 squareroot 56E-3 -> 0.24  Inexact Rounded
+sqtx2646 squareroot 56E+1 -> 24  Inexact Rounded
+sqtx2647 squareroot 56E+2 -> 75  Inexact Rounded
+sqtx2648 squareroot 56E+3 -> 2.4E+2  Inexact Rounded
+sqtx2649 squareroot 0.57 -> 0.75  Inexact Rounded
+sqtx2650 squareroot 0.057 -> 0.24  Inexact Rounded
+sqtx2651 squareroot 57.0E-1 -> 2.4  Inexact Rounded
+sqtx2652 squareroot 57.00E-2 -> 0.75  Inexact Rounded
+sqtx2653 squareroot 57E-3 -> 0.24  Inexact Rounded
+sqtx2654 squareroot 57E+1 -> 24  Inexact Rounded
+sqtx2655 squareroot 57E+2 -> 75  Inexact Rounded
+sqtx2656 squareroot 57E+3 -> 2.4E+2  Inexact Rounded
+sqtx2657 squareroot 0.58 -> 0.76  Inexact Rounded
+sqtx2658 squareroot 0.058 -> 0.24  Inexact Rounded
+sqtx2659 squareroot 58.0E-1 -> 2.4  Inexact Rounded
+sqtx2660 squareroot 58.00E-2 -> 0.76  Inexact Rounded
+sqtx2661 squareroot 58E-3 -> 0.24  Inexact Rounded
+sqtx2662 squareroot 58E+1 -> 24  Inexact Rounded
+sqtx2663 squareroot 58E+2 -> 76  Inexact Rounded
+sqtx2664 squareroot 58E+3 -> 2.4E+2  Inexact Rounded
+sqtx2665 squareroot 0.59 -> 0.77  Inexact Rounded
+sqtx2666 squareroot 0.059 -> 0.24  Inexact Rounded
+sqtx2667 squareroot 59.0E-1 -> 2.4  Inexact Rounded
+sqtx2668 squareroot 59.00E-2 -> 0.77  Inexact Rounded
+sqtx2669 squareroot 59E-3 -> 0.24  Inexact Rounded
+sqtx2670 squareroot 59E+1 -> 24  Inexact Rounded
+sqtx2671 squareroot 59E+2 -> 77  Inexact Rounded
+sqtx2672 squareroot 59E+3 -> 2.4E+2  Inexact Rounded
+sqtx2673 squareroot 0.60 -> 0.77  Inexact Rounded
+sqtx2674 squareroot 0.060 -> 0.24  Inexact Rounded
+sqtx2675 squareroot 60.0E-1 -> 2.4  Inexact Rounded
+sqtx2676 squareroot 60.00E-2 -> 0.77  Inexact Rounded
+sqtx2677 squareroot 60E-3 -> 0.24  Inexact Rounded
+sqtx2678 squareroot 60E+1 -> 24  Inexact Rounded
+sqtx2679 squareroot 60E+2 -> 77  Inexact Rounded
+sqtx2680 squareroot 60E+3 -> 2.4E+2  Inexact Rounded
+sqtx2681 squareroot 0.61 -> 0.78  Inexact Rounded
+sqtx2682 squareroot 0.061 -> 0.25  Inexact Rounded
+sqtx2683 squareroot 61.0E-1 -> 2.5  Inexact Rounded
+sqtx2684 squareroot 61.00E-2 -> 0.78  Inexact Rounded
+sqtx2685 squareroot 61E-3 -> 0.25  Inexact Rounded
+sqtx2686 squareroot 61E+1 -> 25  Inexact Rounded
+sqtx2687 squareroot 61E+2 -> 78  Inexact Rounded
+sqtx2688 squareroot 61E+3 -> 2.5E+2  Inexact Rounded
+sqtx2689 squareroot 0.62 -> 0.79  Inexact Rounded
+sqtx2690 squareroot 0.062 -> 0.25  Inexact Rounded
+sqtx2691 squareroot 62.0E-1 -> 2.5  Inexact Rounded
+sqtx2692 squareroot 62.00E-2 -> 0.79  Inexact Rounded
+sqtx2693 squareroot 62E-3 -> 0.25  Inexact Rounded
+sqtx2694 squareroot 62E+1 -> 25  Inexact Rounded
+sqtx2695 squareroot 62E+2 -> 79  Inexact Rounded
+sqtx2696 squareroot 62E+3 -> 2.5E+2  Inexact Rounded
+sqtx2697 squareroot 0.63 -> 0.79  Inexact Rounded
+sqtx2698 squareroot 0.063 -> 0.25  Inexact Rounded
+sqtx2699 squareroot 63.0E-1 -> 2.5  Inexact Rounded
+sqtx2700 squareroot 63.00E-2 -> 0.79  Inexact Rounded
+sqtx2701 squareroot 63E-3 -> 0.25  Inexact Rounded
+sqtx2702 squareroot 63E+1 -> 25  Inexact Rounded
+sqtx2703 squareroot 63E+2 -> 79  Inexact Rounded
+sqtx2704 squareroot 63E+3 -> 2.5E+2  Inexact Rounded
+sqtx2705 squareroot 0.64 -> 0.8
+sqtx2706 squareroot 0.064 -> 0.25  Inexact Rounded
+sqtx2707 squareroot 64.0E-1 -> 2.5  Inexact Rounded
+sqtx2708 squareroot 64.00E-2 -> 0.80
+sqtx2709 squareroot 64E-3 -> 0.25  Inexact Rounded
+sqtx2710 squareroot 64E+1 -> 25  Inexact Rounded
+sqtx2711 squareroot 64E+2 -> 8E+1
+sqtx2712 squareroot 64E+3 -> 2.5E+2  Inexact Rounded
+sqtx2713 squareroot 0.65 -> 0.81  Inexact Rounded
+sqtx2714 squareroot 0.065 -> 0.25  Inexact Rounded
+sqtx2715 squareroot 65.0E-1 -> 2.5  Inexact Rounded
+sqtx2716 squareroot 65.00E-2 -> 0.81  Inexact Rounded
+sqtx2717 squareroot 65E-3 -> 0.25  Inexact Rounded
+sqtx2718 squareroot 65E+1 -> 25  Inexact Rounded
+sqtx2719 squareroot 65E+2 -> 81  Inexact Rounded
+sqtx2720 squareroot 65E+3 -> 2.5E+2  Inexact Rounded
+sqtx2721 squareroot 0.66 -> 0.81  Inexact Rounded
+sqtx2722 squareroot 0.066 -> 0.26  Inexact Rounded
+sqtx2723 squareroot 66.0E-1 -> 2.6  Inexact Rounded
+sqtx2724 squareroot 66.00E-2 -> 0.81  Inexact Rounded
+sqtx2725 squareroot 66E-3 -> 0.26  Inexact Rounded
+sqtx2726 squareroot 66E+1 -> 26  Inexact Rounded
+sqtx2727 squareroot 66E+2 -> 81  Inexact Rounded
+sqtx2728 squareroot 66E+3 -> 2.6E+2  Inexact Rounded
+sqtx2729 squareroot 0.67 -> 0.82  Inexact Rounded
+sqtx2730 squareroot 0.067 -> 0.26  Inexact Rounded
+sqtx2731 squareroot 67.0E-1 -> 2.6  Inexact Rounded
+sqtx2732 squareroot 67.00E-2 -> 0.82  Inexact Rounded
+sqtx2733 squareroot 67E-3 -> 0.26  Inexact Rounded
+sqtx2734 squareroot 67E+1 -> 26  Inexact Rounded
+sqtx2735 squareroot 67E+2 -> 82  Inexact Rounded
+sqtx2736 squareroot 67E+3 -> 2.6E+2  Inexact Rounded
+sqtx2737 squareroot 0.68 -> 0.82  Inexact Rounded
+sqtx2738 squareroot 0.068 -> 0.26  Inexact Rounded
+sqtx2739 squareroot 68.0E-1 -> 2.6  Inexact Rounded
+sqtx2740 squareroot 68.00E-2 -> 0.82  Inexact Rounded
+sqtx2741 squareroot 68E-3 -> 0.26  Inexact Rounded
+sqtx2742 squareroot 68E+1 -> 26  Inexact Rounded
+sqtx2743 squareroot 68E+2 -> 82  Inexact Rounded
+sqtx2744 squareroot 68E+3 -> 2.6E+2  Inexact Rounded
+sqtx2745 squareroot 0.69 -> 0.83  Inexact Rounded
+sqtx2746 squareroot 0.069 -> 0.26  Inexact Rounded
+sqtx2747 squareroot 69.0E-1 -> 2.6  Inexact Rounded
+sqtx2748 squareroot 69.00E-2 -> 0.83  Inexact Rounded
+sqtx2749 squareroot 69E-3 -> 0.26  Inexact Rounded
+sqtx2750 squareroot 69E+1 -> 26  Inexact Rounded
+sqtx2751 squareroot 69E+2 -> 83  Inexact Rounded
+sqtx2752 squareroot 69E+3 -> 2.6E+2  Inexact Rounded
+sqtx2753 squareroot 0.70 -> 0.84  Inexact Rounded
+sqtx2754 squareroot 0.070 -> 0.26  Inexact Rounded
+sqtx2755 squareroot 70.0E-1 -> 2.6  Inexact Rounded
+sqtx2756 squareroot 70.00E-2 -> 0.84  Inexact Rounded
+sqtx2757 squareroot 70E-3 -> 0.26  Inexact Rounded
+sqtx2758 squareroot 70E+1 -> 26  Inexact Rounded
+sqtx2759 squareroot 70E+2 -> 84  Inexact Rounded
+sqtx2760 squareroot 70E+3 -> 2.6E+2  Inexact Rounded
+sqtx2761 squareroot 0.71 -> 0.84  Inexact Rounded
+sqtx2762 squareroot 0.071 -> 0.27  Inexact Rounded
+sqtx2763 squareroot 71.0E-1 -> 2.7  Inexact Rounded
+sqtx2764 squareroot 71.00E-2 -> 0.84  Inexact Rounded
+sqtx2765 squareroot 71E-3 -> 0.27  Inexact Rounded
+sqtx2766 squareroot 71E+1 -> 27  Inexact Rounded
+sqtx2767 squareroot 71E+2 -> 84  Inexact Rounded
+sqtx2768 squareroot 71E+3 -> 2.7E+2  Inexact Rounded
+sqtx2769 squareroot 0.72 -> 0.85  Inexact Rounded
+sqtx2770 squareroot 0.072 -> 0.27  Inexact Rounded
+sqtx2771 squareroot 72.0E-1 -> 2.7  Inexact Rounded
+sqtx2772 squareroot 72.00E-2 -> 0.85  Inexact Rounded
+sqtx2773 squareroot 72E-3 -> 0.27  Inexact Rounded
+sqtx2774 squareroot 72E+1 -> 27  Inexact Rounded
+sqtx2775 squareroot 72E+2 -> 85  Inexact Rounded
+sqtx2776 squareroot 72E+3 -> 2.7E+2  Inexact Rounded
+sqtx2777 squareroot 0.73 -> 0.85  Inexact Rounded
+sqtx2778 squareroot 0.073 -> 0.27  Inexact Rounded
+sqtx2779 squareroot 73.0E-1 -> 2.7  Inexact Rounded
+sqtx2780 squareroot 73.00E-2 -> 0.85  Inexact Rounded
+sqtx2781 squareroot 73E-3 -> 0.27  Inexact Rounded
+sqtx2782 squareroot 73E+1 -> 27  Inexact Rounded
+sqtx2783 squareroot 73E+2 -> 85  Inexact Rounded
+sqtx2784 squareroot 73E+3 -> 2.7E+2  Inexact Rounded
+sqtx2785 squareroot 0.74 -> 0.86  Inexact Rounded
+sqtx2786 squareroot 0.074 -> 0.27  Inexact Rounded
+sqtx2787 squareroot 74.0E-1 -> 2.7  Inexact Rounded
+sqtx2788 squareroot 74.00E-2 -> 0.86  Inexact Rounded
+sqtx2789 squareroot 74E-3 -> 0.27  Inexact Rounded
+sqtx2790 squareroot 74E+1 -> 27  Inexact Rounded
+sqtx2791 squareroot 74E+2 -> 86  Inexact Rounded
+sqtx2792 squareroot 74E+3 -> 2.7E+2  Inexact Rounded
+sqtx2793 squareroot 0.75 -> 0.87  Inexact Rounded
+sqtx2794 squareroot 0.075 -> 0.27  Inexact Rounded
+sqtx2795 squareroot 75.0E-1 -> 2.7  Inexact Rounded
+sqtx2796 squareroot 75.00E-2 -> 0.87  Inexact Rounded
+sqtx2797 squareroot 75E-3 -> 0.27  Inexact Rounded
+sqtx2798 squareroot 75E+1 -> 27  Inexact Rounded
+sqtx2799 squareroot 75E+2 -> 87  Inexact Rounded
+sqtx2800 squareroot 75E+3 -> 2.7E+2  Inexact Rounded
+sqtx2801 squareroot 0.76 -> 0.87  Inexact Rounded
+sqtx2802 squareroot 0.076 -> 0.28  Inexact Rounded
+sqtx2803 squareroot 76.0E-1 -> 2.8  Inexact Rounded
+sqtx2804 squareroot 76.00E-2 -> 0.87  Inexact Rounded
+sqtx2805 squareroot 76E-3 -> 0.28  Inexact Rounded
+sqtx2806 squareroot 76E+1 -> 28  Inexact Rounded
+sqtx2807 squareroot 76E+2 -> 87  Inexact Rounded
+sqtx2808 squareroot 76E+3 -> 2.8E+2  Inexact Rounded
+sqtx2809 squareroot 0.77 -> 0.88  Inexact Rounded
+sqtx2810 squareroot 0.077 -> 0.28  Inexact Rounded
+sqtx2811 squareroot 77.0E-1 -> 2.8  Inexact Rounded
+sqtx2812 squareroot 77.00E-2 -> 0.88  Inexact Rounded
+sqtx2813 squareroot 77E-3 -> 0.28  Inexact Rounded
+sqtx2814 squareroot 77E+1 -> 28  Inexact Rounded
+sqtx2815 squareroot 77E+2 -> 88  Inexact Rounded
+sqtx2816 squareroot 77E+3 -> 2.8E+2  Inexact Rounded
+sqtx2817 squareroot 0.78 -> 0.88  Inexact Rounded
+sqtx2818 squareroot 0.078 -> 0.28  Inexact Rounded
+sqtx2819 squareroot 78.0E-1 -> 2.8  Inexact Rounded
+sqtx2820 squareroot 78.00E-2 -> 0.88  Inexact Rounded
+sqtx2821 squareroot 78E-3 -> 0.28  Inexact Rounded
+sqtx2822 squareroot 78E+1 -> 28  Inexact Rounded
+sqtx2823 squareroot 78E+2 -> 88  Inexact Rounded
+sqtx2824 squareroot 78E+3 -> 2.8E+2  Inexact Rounded
+sqtx2825 squareroot 0.79 -> 0.89  Inexact Rounded
+sqtx2826 squareroot 0.079 -> 0.28  Inexact Rounded
+sqtx2827 squareroot 79.0E-1 -> 2.8  Inexact Rounded
+sqtx2828 squareroot 79.00E-2 -> 0.89  Inexact Rounded
+sqtx2829 squareroot 79E-3 -> 0.28  Inexact Rounded
+sqtx2830 squareroot 79E+1 -> 28  Inexact Rounded
+sqtx2831 squareroot 79E+2 -> 89  Inexact Rounded
+sqtx2832 squareroot 79E+3 -> 2.8E+2  Inexact Rounded
+sqtx2833 squareroot 0.80 -> 0.89  Inexact Rounded
+sqtx2834 squareroot 0.080 -> 0.28  Inexact Rounded
+sqtx2835 squareroot 80.0E-1 -> 2.8  Inexact Rounded
+sqtx2836 squareroot 80.00E-2 -> 0.89  Inexact Rounded
+sqtx2837 squareroot 80E-3 -> 0.28  Inexact Rounded
+sqtx2838 squareroot 80E+1 -> 28  Inexact Rounded
+sqtx2839 squareroot 80E+2 -> 89  Inexact Rounded
+sqtx2840 squareroot 80E+3 -> 2.8E+2  Inexact Rounded
+sqtx2841 squareroot 0.81 -> 0.9
+sqtx2842 squareroot 0.081 -> 0.28  Inexact Rounded
+sqtx2843 squareroot 81.0E-1 -> 2.8  Inexact Rounded
+sqtx2844 squareroot 81.00E-2 -> 0.90
+sqtx2845 squareroot 81E-3 -> 0.28  Inexact Rounded
+sqtx2846 squareroot 81E+1 -> 28  Inexact Rounded
+sqtx2847 squareroot 81E+2 -> 9E+1
+sqtx2848 squareroot 81E+3 -> 2.8E+2  Inexact Rounded
+sqtx2849 squareroot 0.82 -> 0.91  Inexact Rounded
+sqtx2850 squareroot 0.082 -> 0.29  Inexact Rounded
+sqtx2851 squareroot 82.0E-1 -> 2.9  Inexact Rounded
+sqtx2852 squareroot 82.00E-2 -> 0.91  Inexact Rounded
+sqtx2853 squareroot 82E-3 -> 0.29  Inexact Rounded
+sqtx2854 squareroot 82E+1 -> 29  Inexact Rounded
+sqtx2855 squareroot 82E+2 -> 91  Inexact Rounded
+sqtx2856 squareroot 82E+3 -> 2.9E+2  Inexact Rounded
+sqtx2857 squareroot 0.83 -> 0.91  Inexact Rounded
+sqtx2858 squareroot 0.083 -> 0.29  Inexact Rounded
+sqtx2859 squareroot 83.0E-1 -> 2.9  Inexact Rounded
+sqtx2860 squareroot 83.00E-2 -> 0.91  Inexact Rounded
+sqtx2861 squareroot 83E-3 -> 0.29  Inexact Rounded
+sqtx2862 squareroot 83E+1 -> 29  Inexact Rounded
+sqtx2863 squareroot 83E+2 -> 91  Inexact Rounded
+sqtx2864 squareroot 83E+3 -> 2.9E+2  Inexact Rounded
+sqtx2865 squareroot 0.84 -> 0.92  Inexact Rounded
+sqtx2866 squareroot 0.084 -> 0.29  Inexact Rounded
+sqtx2867 squareroot 84.0E-1 -> 2.9  Inexact Rounded
+sqtx2868 squareroot 84.00E-2 -> 0.92  Inexact Rounded
+sqtx2869 squareroot 84E-3 -> 0.29  Inexact Rounded
+sqtx2870 squareroot 84E+1 -> 29  Inexact Rounded
+sqtx2871 squareroot 84E+2 -> 92  Inexact Rounded
+sqtx2872 squareroot 84E+3 -> 2.9E+2  Inexact Rounded
+sqtx2873 squareroot 0.85 -> 0.92  Inexact Rounded
+sqtx2874 squareroot 0.085 -> 0.29  Inexact Rounded
+sqtx2875 squareroot 85.0E-1 -> 2.9  Inexact Rounded
+sqtx2876 squareroot 85.00E-2 -> 0.92  Inexact Rounded
+sqtx2877 squareroot 85E-3 -> 0.29  Inexact Rounded
+sqtx2878 squareroot 85E+1 -> 29  Inexact Rounded
+sqtx2879 squareroot 85E+2 -> 92  Inexact Rounded
+sqtx2880 squareroot 85E+3 -> 2.9E+2  Inexact Rounded
+sqtx2881 squareroot 0.86 -> 0.93  Inexact Rounded
+sqtx2882 squareroot 0.086 -> 0.29  Inexact Rounded
+sqtx2883 squareroot 86.0E-1 -> 2.9  Inexact Rounded
+sqtx2884 squareroot 86.00E-2 -> 0.93  Inexact Rounded
+sqtx2885 squareroot 86E-3 -> 0.29  Inexact Rounded
+sqtx2886 squareroot 86E+1 -> 29  Inexact Rounded
+sqtx2887 squareroot 86E+2 -> 93  Inexact Rounded
+sqtx2888 squareroot 86E+3 -> 2.9E+2  Inexact Rounded
+sqtx2889 squareroot 0.87 -> 0.93  Inexact Rounded
+sqtx2890 squareroot 0.087 -> 0.29  Inexact Rounded
+sqtx2891 squareroot 87.0E-1 -> 2.9  Inexact Rounded
+sqtx2892 squareroot 87.00E-2 -> 0.93  Inexact Rounded
+sqtx2893 squareroot 87E-3 -> 0.29  Inexact Rounded
+sqtx2894 squareroot 87E+1 -> 29  Inexact Rounded
+sqtx2895 squareroot 87E+2 -> 93  Inexact Rounded
+sqtx2896 squareroot 87E+3 -> 2.9E+2  Inexact Rounded
+sqtx2897 squareroot 0.88 -> 0.94  Inexact Rounded
+sqtx2898 squareroot 0.088 -> 0.30  Inexact Rounded
+sqtx2899 squareroot 88.0E-1 -> 3.0  Inexact Rounded
+sqtx2900 squareroot 88.00E-2 -> 0.94  Inexact Rounded
+sqtx2901 squareroot 88E-3 -> 0.30  Inexact Rounded
+sqtx2902 squareroot 88E+1 -> 30  Inexact Rounded
+sqtx2903 squareroot 88E+2 -> 94  Inexact Rounded
+sqtx2904 squareroot 88E+3 -> 3.0E+2  Inexact Rounded
+sqtx2905 squareroot 0.89 -> 0.94  Inexact Rounded
+sqtx2906 squareroot 0.089 -> 0.30  Inexact Rounded
+sqtx2907 squareroot 89.0E-1 -> 3.0  Inexact Rounded
+sqtx2908 squareroot 89.00E-2 -> 0.94  Inexact Rounded
+sqtx2909 squareroot 89E-3 -> 0.30  Inexact Rounded
+sqtx2910 squareroot 89E+1 -> 30  Inexact Rounded
+sqtx2911 squareroot 89E+2 -> 94  Inexact Rounded
+sqtx2912 squareroot 89E+3 -> 3.0E+2  Inexact Rounded
+sqtx2913 squareroot 0.90 -> 0.95  Inexact Rounded
+sqtx2914 squareroot 0.090 -> 0.30
+sqtx2915 squareroot 90.0E-1 -> 3.0
+sqtx2916 squareroot 90.00E-2 -> 0.95  Inexact Rounded
+sqtx2917 squareroot 90E-3 -> 0.30
+sqtx2918 squareroot 90E+1 -> 30
+sqtx2919 squareroot 90E+2 -> 95  Inexact Rounded
+sqtx2920 squareroot 90E+3 -> 3.0E+2
+sqtx2921 squareroot 0.91 -> 0.95  Inexact Rounded
+sqtx2922 squareroot 0.091 -> 0.30  Inexact Rounded
+sqtx2923 squareroot 91.0E-1 -> 3.0  Inexact Rounded
+sqtx2924 squareroot 91.00E-2 -> 0.95  Inexact Rounded
+sqtx2925 squareroot 91E-3 -> 0.30  Inexact Rounded
+sqtx2926 squareroot 91E+1 -> 30  Inexact Rounded
+sqtx2927 squareroot 91E+2 -> 95  Inexact Rounded
+sqtx2928 squareroot 91E+3 -> 3.0E+2  Inexact Rounded
+sqtx2929 squareroot 0.92 -> 0.96  Inexact Rounded
+sqtx2930 squareroot 0.092 -> 0.30  Inexact Rounded
+sqtx2931 squareroot 92.0E-1 -> 3.0  Inexact Rounded
+sqtx2932 squareroot 92.00E-2 -> 0.96  Inexact Rounded
+sqtx2933 squareroot 92E-3 -> 0.30  Inexact Rounded
+sqtx2934 squareroot 92E+1 -> 30  Inexact Rounded
+sqtx2935 squareroot 92E+2 -> 96  Inexact Rounded
+sqtx2936 squareroot 92E+3 -> 3.0E+2  Inexact Rounded
+sqtx2937 squareroot 0.93 -> 0.96  Inexact Rounded
+sqtx2938 squareroot 0.093 -> 0.30  Inexact Rounded
+sqtx2939 squareroot 93.0E-1 -> 3.0  Inexact Rounded
+sqtx2940 squareroot 93.00E-2 -> 0.96  Inexact Rounded
+sqtx2941 squareroot 93E-3 -> 0.30  Inexact Rounded
+sqtx2942 squareroot 93E+1 -> 30  Inexact Rounded
+sqtx2943 squareroot 93E+2 -> 96  Inexact Rounded
+sqtx2944 squareroot 93E+3 -> 3.0E+2  Inexact Rounded
+sqtx2945 squareroot 0.94 -> 0.97  Inexact Rounded
+sqtx2946 squareroot 0.094 -> 0.31  Inexact Rounded
+sqtx2947 squareroot 94.0E-1 -> 3.1  Inexact Rounded
+sqtx2948 squareroot 94.00E-2 -> 0.97  Inexact Rounded
+sqtx2949 squareroot 94E-3 -> 0.31  Inexact Rounded
+sqtx2950 squareroot 94E+1 -> 31  Inexact Rounded
+sqtx2951 squareroot 94E+2 -> 97  Inexact Rounded
+sqtx2952 squareroot 94E+3 -> 3.1E+2  Inexact Rounded
+sqtx2953 squareroot 0.95 -> 0.97  Inexact Rounded
+sqtx2954 squareroot 0.095 -> 0.31  Inexact Rounded
+sqtx2955 squareroot 95.0E-1 -> 3.1  Inexact Rounded
+sqtx2956 squareroot 95.00E-2 -> 0.97  Inexact Rounded
+sqtx2957 squareroot 95E-3 -> 0.31  Inexact Rounded
+sqtx2958 squareroot 95E+1 -> 31  Inexact Rounded
+sqtx2959 squareroot 95E+2 -> 97  Inexact Rounded
+sqtx2960 squareroot 95E+3 -> 3.1E+2  Inexact Rounded
+sqtx2961 squareroot 0.96 -> 0.98  Inexact Rounded
+sqtx2962 squareroot 0.096 -> 0.31  Inexact Rounded
+sqtx2963 squareroot 96.0E-1 -> 3.1  Inexact Rounded
+sqtx2964 squareroot 96.00E-2 -> 0.98  Inexact Rounded
+sqtx2965 squareroot 96E-3 -> 0.31  Inexact Rounded
+sqtx2966 squareroot 96E+1 -> 31  Inexact Rounded
+sqtx2967 squareroot 96E+2 -> 98  Inexact Rounded
+sqtx2968 squareroot 96E+3 -> 3.1E+2  Inexact Rounded
+sqtx2969 squareroot 0.97 -> 0.98  Inexact Rounded
+sqtx2970 squareroot 0.097 -> 0.31  Inexact Rounded
+sqtx2971 squareroot 97.0E-1 -> 3.1  Inexact Rounded
+sqtx2972 squareroot 97.00E-2 -> 0.98  Inexact Rounded
+sqtx2973 squareroot 97E-3 -> 0.31  Inexact Rounded
+sqtx2974 squareroot 97E+1 -> 31  Inexact Rounded
+sqtx2975 squareroot 97E+2 -> 98  Inexact Rounded
+sqtx2976 squareroot 97E+3 -> 3.1E+2  Inexact Rounded
+sqtx2977 squareroot 0.98 -> 0.99  Inexact Rounded
+sqtx2978 squareroot 0.098 -> 0.31  Inexact Rounded
+sqtx2979 squareroot 98.0E-1 -> 3.1  Inexact Rounded
+sqtx2980 squareroot 98.00E-2 -> 0.99  Inexact Rounded
+sqtx2981 squareroot 98E-3 -> 0.31  Inexact Rounded
+sqtx2982 squareroot 98E+1 -> 31  Inexact Rounded
+sqtx2983 squareroot 98E+2 -> 99  Inexact Rounded
+sqtx2984 squareroot 98E+3 -> 3.1E+2  Inexact Rounded
+sqtx2985 squareroot 0.99 -> 0.99  Inexact Rounded
+sqtx2986 squareroot 0.099 -> 0.31  Inexact Rounded
+sqtx2987 squareroot 99.0E-1 -> 3.1  Inexact Rounded
+sqtx2988 squareroot 99.00E-2 -> 0.99  Inexact Rounded
+sqtx2989 squareroot 99E-3 -> 0.31  Inexact Rounded
+sqtx2990 squareroot 99E+1 -> 31  Inexact Rounded
+sqtx2991 squareroot 99E+2 -> 99  Inexact Rounded
+sqtx2992 squareroot 99E+3 -> 3.1E+2  Inexact Rounded
+
+-- Precision 3 squareroot tests [exhaustive, f and f/10]
+rounding:    half_even
+maxExponent: 999
+minexponent: -999
+precision:   3
+sqtx3001 squareroot 0.1 -> 0.316  Inexact Rounded
+sqtx3002 squareroot 0.01 -> 0.1
+sqtx3003 squareroot 0.2 -> 0.447  Inexact Rounded
+sqtx3004 squareroot 0.02 -> 0.141  Inexact Rounded
+sqtx3005 squareroot 0.3 -> 0.548  Inexact Rounded
+sqtx3006 squareroot 0.03 -> 0.173  Inexact Rounded
+sqtx3007 squareroot 0.4 -> 0.632  Inexact Rounded
+sqtx3008 squareroot 0.04 -> 0.2
+sqtx3009 squareroot 0.5 -> 0.707  Inexact Rounded
+sqtx3010 squareroot 0.05 -> 0.224  Inexact Rounded
+sqtx3011 squareroot 0.6 -> 0.775  Inexact Rounded
+sqtx3012 squareroot 0.06 -> 0.245  Inexact Rounded
+sqtx3013 squareroot 0.7 -> 0.837  Inexact Rounded
+sqtx3014 squareroot 0.07 -> 0.265  Inexact Rounded
+sqtx3015 squareroot 0.8 -> 0.894  Inexact Rounded
+sqtx3016 squareroot 0.08 -> 0.283  Inexact Rounded
+sqtx3017 squareroot 0.9 -> 0.949  Inexact Rounded
+sqtx3018 squareroot 0.09 -> 0.3
+sqtx3019 squareroot 0.11 -> 0.332  Inexact Rounded
+sqtx3020 squareroot 0.011 -> 0.105  Inexact Rounded
+sqtx3021 squareroot 0.12 -> 0.346  Inexact Rounded
+sqtx3022 squareroot 0.012 -> 0.110  Inexact Rounded
+sqtx3023 squareroot 0.13 -> 0.361  Inexact Rounded
+sqtx3024 squareroot 0.013 -> 0.114  Inexact Rounded
+sqtx3025 squareroot 0.14 -> 0.374  Inexact Rounded
+sqtx3026 squareroot 0.014 -> 0.118  Inexact Rounded
+sqtx3027 squareroot 0.15 -> 0.387  Inexact Rounded
+sqtx3028 squareroot 0.015 -> 0.122  Inexact Rounded
+sqtx3029 squareroot 0.16 -> 0.4
+sqtx3030 squareroot 0.016 -> 0.126  Inexact Rounded
+sqtx3031 squareroot 0.17 -> 0.412  Inexact Rounded
+sqtx3032 squareroot 0.017 -> 0.130  Inexact Rounded
+sqtx3033 squareroot 0.18 -> 0.424  Inexact Rounded
+sqtx3034 squareroot 0.018 -> 0.134  Inexact Rounded
+sqtx3035 squareroot 0.19 -> 0.436  Inexact Rounded
+sqtx3036 squareroot 0.019 -> 0.138  Inexact Rounded
+sqtx3037 squareroot 0.21 -> 0.458  Inexact Rounded
+sqtx3038 squareroot 0.021 -> 0.145  Inexact Rounded
+sqtx3039 squareroot 0.22 -> 0.469  Inexact Rounded
+sqtx3040 squareroot 0.022 -> 0.148  Inexact Rounded
+sqtx3041 squareroot 0.23 -> 0.480  Inexact Rounded
+sqtx3042 squareroot 0.023 -> 0.152  Inexact Rounded
+sqtx3043 squareroot 0.24 -> 0.490  Inexact Rounded
+sqtx3044 squareroot 0.024 -> 0.155  Inexact Rounded
+sqtx3045 squareroot 0.25 -> 0.5
+sqtx3046 squareroot 0.025 -> 0.158  Inexact Rounded
+sqtx3047 squareroot 0.26 -> 0.510  Inexact Rounded
+sqtx3048 squareroot 0.026 -> 0.161  Inexact Rounded
+sqtx3049 squareroot 0.27 -> 0.520  Inexact Rounded
+sqtx3050 squareroot 0.027 -> 0.164  Inexact Rounded
+sqtx3051 squareroot 0.28 -> 0.529  Inexact Rounded
+sqtx3052 squareroot 0.028 -> 0.167  Inexact Rounded
+sqtx3053 squareroot 0.29 -> 0.539  Inexact Rounded
+sqtx3054 squareroot 0.029 -> 0.170  Inexact Rounded
+sqtx3055 squareroot 0.31 -> 0.557  Inexact Rounded
+sqtx3056 squareroot 0.031 -> 0.176  Inexact Rounded
+sqtx3057 squareroot 0.32 -> 0.566  Inexact Rounded
+sqtx3058 squareroot 0.032 -> 0.179  Inexact Rounded
+sqtx3059 squareroot 0.33 -> 0.574  Inexact Rounded
+sqtx3060 squareroot 0.033 -> 0.182  Inexact Rounded
+sqtx3061 squareroot 0.34 -> 0.583  Inexact Rounded
+sqtx3062 squareroot 0.034 -> 0.184  Inexact Rounded
+sqtx3063 squareroot 0.35 -> 0.592  Inexact Rounded
+sqtx3064 squareroot 0.035 -> 0.187  Inexact Rounded
+sqtx3065 squareroot 0.36 -> 0.6
+sqtx3066 squareroot 0.036 -> 0.190  Inexact Rounded
+sqtx3067 squareroot 0.37 -> 0.608  Inexact Rounded
+sqtx3068 squareroot 0.037 -> 0.192  Inexact Rounded
+sqtx3069 squareroot 0.38 -> 0.616  Inexact Rounded
+sqtx3070 squareroot 0.038 -> 0.195  Inexact Rounded
+sqtx3071 squareroot 0.39 -> 0.624  Inexact Rounded
+sqtx3072 squareroot 0.039 -> 0.197  Inexact Rounded
+sqtx3073 squareroot 0.41 -> 0.640  Inexact Rounded
+sqtx3074 squareroot 0.041 -> 0.202  Inexact Rounded
+sqtx3075 squareroot 0.42 -> 0.648  Inexact Rounded
+sqtx3076 squareroot 0.042 -> 0.205  Inexact Rounded
+sqtx3077 squareroot 0.43 -> 0.656  Inexact Rounded
+sqtx3078 squareroot 0.043 -> 0.207  Inexact Rounded
+sqtx3079 squareroot 0.44 -> 0.663  Inexact Rounded
+sqtx3080 squareroot 0.044 -> 0.210  Inexact Rounded
+sqtx3081 squareroot 0.45 -> 0.671  Inexact Rounded
+sqtx3082 squareroot 0.045 -> 0.212  Inexact Rounded
+sqtx3083 squareroot 0.46 -> 0.678  Inexact Rounded
+sqtx3084 squareroot 0.046 -> 0.214  Inexact Rounded
+sqtx3085 squareroot 0.47 -> 0.686  Inexact Rounded
+sqtx3086 squareroot 0.047 -> 0.217  Inexact Rounded
+sqtx3087 squareroot 0.48 -> 0.693  Inexact Rounded
+sqtx3088 squareroot 0.048 -> 0.219  Inexact Rounded
+sqtx3089 squareroot 0.49 -> 0.7
+sqtx3090 squareroot 0.049 -> 0.221  Inexact Rounded
+sqtx3091 squareroot 0.51 -> 0.714  Inexact Rounded
+sqtx3092 squareroot 0.051 -> 0.226  Inexact Rounded
+sqtx3093 squareroot 0.52 -> 0.721  Inexact Rounded
+sqtx3094 squareroot 0.052 -> 0.228  Inexact Rounded
+sqtx3095 squareroot 0.53 -> 0.728  Inexact Rounded
+sqtx3096 squareroot 0.053 -> 0.230  Inexact Rounded
+sqtx3097 squareroot 0.54 -> 0.735  Inexact Rounded
+sqtx3098 squareroot 0.054 -> 0.232  Inexact Rounded
+sqtx3099 squareroot 0.55 -> 0.742  Inexact Rounded
+sqtx3100 squareroot 0.055 -> 0.235  Inexact Rounded
+sqtx3101 squareroot 0.56 -> 0.748  Inexact Rounded
+sqtx3102 squareroot 0.056 -> 0.237  Inexact Rounded
+sqtx3103 squareroot 0.57 -> 0.755  Inexact Rounded
+sqtx3104 squareroot 0.057 -> 0.239  Inexact Rounded
+sqtx3105 squareroot 0.58 -> 0.762  Inexact Rounded
+sqtx3106 squareroot 0.058 -> 0.241  Inexact Rounded
+sqtx3107 squareroot 0.59 -> 0.768  Inexact Rounded
+sqtx3108 squareroot 0.059 -> 0.243  Inexact Rounded
+sqtx3109 squareroot 0.61 -> 0.781  Inexact Rounded
+sqtx3110 squareroot 0.061 -> 0.247  Inexact Rounded
+sqtx3111 squareroot 0.62 -> 0.787  Inexact Rounded
+sqtx3112 squareroot 0.062 -> 0.249  Inexact Rounded
+sqtx3113 squareroot 0.63 -> 0.794  Inexact Rounded
+sqtx3114 squareroot 0.063 -> 0.251  Inexact Rounded
+sqtx3115 squareroot 0.64 -> 0.8
+sqtx3116 squareroot 0.064 -> 0.253  Inexact Rounded
+sqtx3117 squareroot 0.65 -> 0.806  Inexact Rounded
+sqtx3118 squareroot 0.065 -> 0.255  Inexact Rounded
+sqtx3119 squareroot 0.66 -> 0.812  Inexact Rounded
+sqtx3120 squareroot 0.066 -> 0.257  Inexact Rounded
+sqtx3121 squareroot 0.67 -> 0.819  Inexact Rounded
+sqtx3122 squareroot 0.067 -> 0.259  Inexact Rounded
+sqtx3123 squareroot 0.68 -> 0.825  Inexact Rounded
+sqtx3124 squareroot 0.068 -> 0.261  Inexact Rounded
+sqtx3125 squareroot 0.69 -> 0.831  Inexact Rounded
+sqtx3126 squareroot 0.069 -> 0.263  Inexact Rounded
+sqtx3127 squareroot 0.71 -> 0.843  Inexact Rounded
+sqtx3128 squareroot 0.071 -> 0.266  Inexact Rounded
+sqtx3129 squareroot 0.72 -> 0.849  Inexact Rounded
+sqtx3130 squareroot 0.072 -> 0.268  Inexact Rounded
+sqtx3131 squareroot 0.73 -> 0.854  Inexact Rounded
+sqtx3132 squareroot 0.073 -> 0.270  Inexact Rounded
+sqtx3133 squareroot 0.74 -> 0.860  Inexact Rounded
+sqtx3134 squareroot 0.074 -> 0.272  Inexact Rounded
+sqtx3135 squareroot 0.75 -> 0.866  Inexact Rounded
+sqtx3136 squareroot 0.075 -> 0.274  Inexact Rounded
+sqtx3137 squareroot 0.76 -> 0.872  Inexact Rounded
+sqtx3138 squareroot 0.076 -> 0.276  Inexact Rounded
+sqtx3139 squareroot 0.77 -> 0.877  Inexact Rounded
+sqtx3140 squareroot 0.077 -> 0.277  Inexact Rounded
+sqtx3141 squareroot 0.78 -> 0.883  Inexact Rounded
+sqtx3142 squareroot 0.078 -> 0.279  Inexact Rounded
+sqtx3143 squareroot 0.79 -> 0.889  Inexact Rounded
+sqtx3144 squareroot 0.079 -> 0.281  Inexact Rounded
+sqtx3145 squareroot 0.81 -> 0.9
+sqtx3146 squareroot 0.081 -> 0.285  Inexact Rounded
+sqtx3147 squareroot 0.82 -> 0.906  Inexact Rounded
+sqtx3148 squareroot 0.082 -> 0.286  Inexact Rounded
+sqtx3149 squareroot 0.83 -> 0.911  Inexact Rounded
+sqtx3150 squareroot 0.083 -> 0.288  Inexact Rounded
+sqtx3151 squareroot 0.84 -> 0.917  Inexact Rounded
+sqtx3152 squareroot 0.084 -> 0.290  Inexact Rounded
+sqtx3153 squareroot 0.85 -> 0.922  Inexact Rounded
+sqtx3154 squareroot 0.085 -> 0.292  Inexact Rounded
+sqtx3155 squareroot 0.86 -> 0.927  Inexact Rounded
+sqtx3156 squareroot 0.086 -> 0.293  Inexact Rounded
+sqtx3157 squareroot 0.87 -> 0.933  Inexact Rounded
+sqtx3158 squareroot 0.087 -> 0.295  Inexact Rounded
+sqtx3159 squareroot 0.88 -> 0.938  Inexact Rounded
+sqtx3160 squareroot 0.088 -> 0.297  Inexact Rounded
+sqtx3161 squareroot 0.89 -> 0.943  Inexact Rounded
+sqtx3162 squareroot 0.089 -> 0.298  Inexact Rounded
+sqtx3163 squareroot 0.91 -> 0.954  Inexact Rounded
+sqtx3164 squareroot 0.091 -> 0.302  Inexact Rounded
+sqtx3165 squareroot 0.92 -> 0.959  Inexact Rounded
+sqtx3166 squareroot 0.092 -> 0.303  Inexact Rounded
+sqtx3167 squareroot 0.93 -> 0.964  Inexact Rounded
+sqtx3168 squareroot 0.093 -> 0.305  Inexact Rounded
+sqtx3169 squareroot 0.94 -> 0.970  Inexact Rounded
+sqtx3170 squareroot 0.094 -> 0.307  Inexact Rounded
+sqtx3171 squareroot 0.95 -> 0.975  Inexact Rounded
+sqtx3172 squareroot 0.095 -> 0.308  Inexact Rounded
+sqtx3173 squareroot 0.96 -> 0.980  Inexact Rounded
+sqtx3174 squareroot 0.096 -> 0.310  Inexact Rounded
+sqtx3175 squareroot 0.97 -> 0.985  Inexact Rounded
+sqtx3176 squareroot 0.097 -> 0.311  Inexact Rounded
+sqtx3177 squareroot 0.98 -> 0.990  Inexact Rounded
+sqtx3178 squareroot 0.098 -> 0.313  Inexact Rounded
+sqtx3179 squareroot 0.99 -> 0.995  Inexact Rounded
+sqtx3180 squareroot 0.099 -> 0.315  Inexact Rounded
+sqtx3181 squareroot 0.101 -> 0.318  Inexact Rounded
+sqtx3182 squareroot 0.0101 -> 0.100  Inexact Rounded
+sqtx3183 squareroot 0.102 -> 0.319  Inexact Rounded
+sqtx3184 squareroot 0.0102 -> 0.101  Inexact Rounded
+sqtx3185 squareroot 0.103 -> 0.321  Inexact Rounded
+sqtx3186 squareroot 0.0103 -> 0.101  Inexact Rounded
+sqtx3187 squareroot 0.104 -> 0.322  Inexact Rounded
+sqtx3188 squareroot 0.0104 -> 0.102  Inexact Rounded
+sqtx3189 squareroot 0.105 -> 0.324  Inexact Rounded
+sqtx3190 squareroot 0.0105 -> 0.102  Inexact Rounded
+sqtx3191 squareroot 0.106 -> 0.326  Inexact Rounded
+sqtx3192 squareroot 0.0106 -> 0.103  Inexact Rounded
+sqtx3193 squareroot 0.107 -> 0.327  Inexact Rounded
+sqtx3194 squareroot 0.0107 -> 0.103  Inexact Rounded
+sqtx3195 squareroot 0.108 -> 0.329  Inexact Rounded
+sqtx3196 squareroot 0.0108 -> 0.104  Inexact Rounded
+sqtx3197 squareroot 0.109 -> 0.330  Inexact Rounded
+sqtx3198 squareroot 0.0109 -> 0.104  Inexact Rounded
+sqtx3199 squareroot 0.111 -> 0.333  Inexact Rounded
+sqtx3200 squareroot 0.0111 -> 0.105  Inexact Rounded
+sqtx3201 squareroot 0.112 -> 0.335  Inexact Rounded
+sqtx3202 squareroot 0.0112 -> 0.106  Inexact Rounded
+sqtx3203 squareroot 0.113 -> 0.336  Inexact Rounded
+sqtx3204 squareroot 0.0113 -> 0.106  Inexact Rounded
+sqtx3205 squareroot 0.114 -> 0.338  Inexact Rounded
+sqtx3206 squareroot 0.0114 -> 0.107  Inexact Rounded
+sqtx3207 squareroot 0.115 -> 0.339  Inexact Rounded
+sqtx3208 squareroot 0.0115 -> 0.107  Inexact Rounded
+sqtx3209 squareroot 0.116 -> 0.341  Inexact Rounded
+sqtx3210 squareroot 0.0116 -> 0.108  Inexact Rounded
+sqtx3211 squareroot 0.117 -> 0.342  Inexact Rounded
+sqtx3212 squareroot 0.0117 -> 0.108  Inexact Rounded
+sqtx3213 squareroot 0.118 -> 0.344  Inexact Rounded
+sqtx3214 squareroot 0.0118 -> 0.109  Inexact Rounded
+sqtx3215 squareroot 0.119 -> 0.345  Inexact Rounded
+sqtx3216 squareroot 0.0119 -> 0.109  Inexact Rounded
+sqtx3217 squareroot 0.121 -> 0.348  Inexact Rounded
+sqtx3218 squareroot 0.0121 -> 0.11
+sqtx3219 squareroot 0.122 -> 0.349  Inexact Rounded
+sqtx3220 squareroot 0.0122 -> 0.110  Inexact Rounded
+sqtx3221 squareroot 0.123 -> 0.351  Inexact Rounded
+sqtx3222 squareroot 0.0123 -> 0.111  Inexact Rounded
+sqtx3223 squareroot 0.124 -> 0.352  Inexact Rounded
+sqtx3224 squareroot 0.0124 -> 0.111  Inexact Rounded
+sqtx3225 squareroot 0.125 -> 0.354  Inexact Rounded
+sqtx3226 squareroot 0.0125 -> 0.112  Inexact Rounded
+sqtx3227 squareroot 0.126 -> 0.355  Inexact Rounded
+sqtx3228 squareroot 0.0126 -> 0.112  Inexact Rounded
+sqtx3229 squareroot 0.127 -> 0.356  Inexact Rounded
+sqtx3230 squareroot 0.0127 -> 0.113  Inexact Rounded
+sqtx3231 squareroot 0.128 -> 0.358  Inexact Rounded
+sqtx3232 squareroot 0.0128 -> 0.113  Inexact Rounded
+sqtx3233 squareroot 0.129 -> 0.359  Inexact Rounded
+sqtx3234 squareroot 0.0129 -> 0.114  Inexact Rounded
+sqtx3235 squareroot 0.131 -> 0.362  Inexact Rounded
+sqtx3236 squareroot 0.0131 -> 0.114  Inexact Rounded
+sqtx3237 squareroot 0.132 -> 0.363  Inexact Rounded
+sqtx3238 squareroot 0.0132 -> 0.115  Inexact Rounded
+sqtx3239 squareroot 0.133 -> 0.365  Inexact Rounded
+sqtx3240 squareroot 0.0133 -> 0.115  Inexact Rounded
+sqtx3241 squareroot 0.134 -> 0.366  Inexact Rounded
+sqtx3242 squareroot 0.0134 -> 0.116  Inexact Rounded
+sqtx3243 squareroot 0.135 -> 0.367  Inexact Rounded
+sqtx3244 squareroot 0.0135 -> 0.116  Inexact Rounded
+sqtx3245 squareroot 0.136 -> 0.369  Inexact Rounded
+sqtx3246 squareroot 0.0136 -> 0.117  Inexact Rounded
+sqtx3247 squareroot 0.137 -> 0.370  Inexact Rounded
+sqtx3248 squareroot 0.0137 -> 0.117  Inexact Rounded
+sqtx3249 squareroot 0.138 -> 0.371  Inexact Rounded
+sqtx3250 squareroot 0.0138 -> 0.117  Inexact Rounded
+sqtx3251 squareroot 0.139 -> 0.373  Inexact Rounded
+sqtx3252 squareroot 0.0139 -> 0.118  Inexact Rounded
+sqtx3253 squareroot 0.141 -> 0.375  Inexact Rounded
+sqtx3254 squareroot 0.0141 -> 0.119  Inexact Rounded
+sqtx3255 squareroot 0.142 -> 0.377  Inexact Rounded
+sqtx3256 squareroot 0.0142 -> 0.119  Inexact Rounded
+sqtx3257 squareroot 0.143 -> 0.378  Inexact Rounded
+sqtx3258 squareroot 0.0143 -> 0.120  Inexact Rounded
+sqtx3259 squareroot 0.144 -> 0.379  Inexact Rounded
+sqtx3260 squareroot 0.0144 -> 0.12
+sqtx3261 squareroot 0.145 -> 0.381  Inexact Rounded
+sqtx3262 squareroot 0.0145 -> 0.120  Inexact Rounded
+sqtx3263 squareroot 0.146 -> 0.382  Inexact Rounded
+sqtx3264 squareroot 0.0146 -> 0.121  Inexact Rounded
+sqtx3265 squareroot 0.147 -> 0.383  Inexact Rounded
+sqtx3266 squareroot 0.0147 -> 0.121  Inexact Rounded
+sqtx3267 squareroot 0.148 -> 0.385  Inexact Rounded
+sqtx3268 squareroot 0.0148 -> 0.122  Inexact Rounded
+sqtx3269 squareroot 0.149 -> 0.386  Inexact Rounded
+sqtx3270 squareroot 0.0149 -> 0.122  Inexact Rounded
+sqtx3271 squareroot 0.151 -> 0.389  Inexact Rounded
+sqtx3272 squareroot 0.0151 -> 0.123  Inexact Rounded
+sqtx3273 squareroot 0.152 -> 0.390  Inexact Rounded
+sqtx3274 squareroot 0.0152 -> 0.123  Inexact Rounded
+sqtx3275 squareroot 0.153 -> 0.391  Inexact Rounded
+sqtx3276 squareroot 0.0153 -> 0.124  Inexact Rounded
+sqtx3277 squareroot 0.154 -> 0.392  Inexact Rounded
+sqtx3278 squareroot 0.0154 -> 0.124  Inexact Rounded
+sqtx3279 squareroot 0.155 -> 0.394  Inexact Rounded
+sqtx3280 squareroot 0.0155 -> 0.124  Inexact Rounded
+sqtx3281 squareroot 0.156 -> 0.395  Inexact Rounded
+sqtx3282 squareroot 0.0156 -> 0.125  Inexact Rounded
+sqtx3283 squareroot 0.157 -> 0.396  Inexact Rounded
+sqtx3284 squareroot 0.0157 -> 0.125  Inexact Rounded
+sqtx3285 squareroot 0.158 -> 0.397  Inexact Rounded
+sqtx3286 squareroot 0.0158 -> 0.126  Inexact Rounded
+sqtx3287 squareroot 0.159 -> 0.399  Inexact Rounded
+sqtx3288 squareroot 0.0159 -> 0.126  Inexact Rounded
+sqtx3289 squareroot 0.161 -> 0.401  Inexact Rounded
+sqtx3290 squareroot 0.0161 -> 0.127  Inexact Rounded
+sqtx3291 squareroot 0.162 -> 0.402  Inexact Rounded
+sqtx3292 squareroot 0.0162 -> 0.127  Inexact Rounded
+sqtx3293 squareroot 0.163 -> 0.404  Inexact Rounded
+sqtx3294 squareroot 0.0163 -> 0.128  Inexact Rounded
+sqtx3295 squareroot 0.164 -> 0.405  Inexact Rounded
+sqtx3296 squareroot 0.0164 -> 0.128  Inexact Rounded
+sqtx3297 squareroot 0.165 -> 0.406  Inexact Rounded
+sqtx3298 squareroot 0.0165 -> 0.128  Inexact Rounded
+sqtx3299 squareroot 0.166 -> 0.407  Inexact Rounded
+sqtx3300 squareroot 0.0166 -> 0.129  Inexact Rounded
+sqtx3301 squareroot 0.167 -> 0.409  Inexact Rounded
+sqtx3302 squareroot 0.0167 -> 0.129  Inexact Rounded
+sqtx3303 squareroot 0.168 -> 0.410  Inexact Rounded
+sqtx3304 squareroot 0.0168 -> 0.130  Inexact Rounded
+sqtx3305 squareroot 0.169 -> 0.411  Inexact Rounded
+sqtx3306 squareroot 0.0169 -> 0.13
+sqtx3307 squareroot 0.171 -> 0.414  Inexact Rounded
+sqtx3308 squareroot 0.0171 -> 0.131  Inexact Rounded
+sqtx3309 squareroot 0.172 -> 0.415  Inexact Rounded
+sqtx3310 squareroot 0.0172 -> 0.131  Inexact Rounded
+sqtx3311 squareroot 0.173 -> 0.416  Inexact Rounded
+sqtx3312 squareroot 0.0173 -> 0.132  Inexact Rounded
+sqtx3313 squareroot 0.174 -> 0.417  Inexact Rounded
+sqtx3314 squareroot 0.0174 -> 0.132  Inexact Rounded
+sqtx3315 squareroot 0.175 -> 0.418  Inexact Rounded
+sqtx3316 squareroot 0.0175 -> 0.132  Inexact Rounded
+sqtx3317 squareroot 0.176 -> 0.420  Inexact Rounded
+sqtx3318 squareroot 0.0176 -> 0.133  Inexact Rounded
+sqtx3319 squareroot 0.177 -> 0.421  Inexact Rounded
+sqtx3320 squareroot 0.0177 -> 0.133  Inexact Rounded
+sqtx3321 squareroot 0.178 -> 0.422  Inexact Rounded
+sqtx3322 squareroot 0.0178 -> 0.133  Inexact Rounded
+sqtx3323 squareroot 0.179 -> 0.423  Inexact Rounded
+sqtx3324 squareroot 0.0179 -> 0.134  Inexact Rounded
+sqtx3325 squareroot 0.181 -> 0.425  Inexact Rounded
+sqtx3326 squareroot 0.0181 -> 0.135  Inexact Rounded
+sqtx3327 squareroot 0.182 -> 0.427  Inexact Rounded
+sqtx3328 squareroot 0.0182 -> 0.135  Inexact Rounded
+sqtx3329 squareroot 0.183 -> 0.428  Inexact Rounded
+sqtx3330 squareroot 0.0183 -> 0.135  Inexact Rounded
+sqtx3331 squareroot 0.184 -> 0.429  Inexact Rounded
+sqtx3332 squareroot 0.0184 -> 0.136  Inexact Rounded
+sqtx3333 squareroot 0.185 -> 0.430  Inexact Rounded
+sqtx3334 squareroot 0.0185 -> 0.136  Inexact Rounded
+sqtx3335 squareroot 0.186 -> 0.431  Inexact Rounded
+sqtx3336 squareroot 0.0186 -> 0.136  Inexact Rounded
+sqtx3337 squareroot 0.187 -> 0.432  Inexact Rounded
+sqtx3338 squareroot 0.0187 -> 0.137  Inexact Rounded
+sqtx3339 squareroot 0.188 -> 0.434  Inexact Rounded
+sqtx3340 squareroot 0.0188 -> 0.137  Inexact Rounded
+sqtx3341 squareroot 0.189 -> 0.435  Inexact Rounded
+sqtx3342 squareroot 0.0189 -> 0.137  Inexact Rounded
+sqtx3343 squareroot 0.191 -> 0.437  Inexact Rounded
+sqtx3344 squareroot 0.0191 -> 0.138  Inexact Rounded
+sqtx3345 squareroot 0.192 -> 0.438  Inexact Rounded
+sqtx3346 squareroot 0.0192 -> 0.139  Inexact Rounded
+sqtx3347 squareroot 0.193 -> 0.439  Inexact Rounded
+sqtx3348 squareroot 0.0193 -> 0.139  Inexact Rounded
+sqtx3349 squareroot 0.194 -> 0.440  Inexact Rounded
+sqtx3350 squareroot 0.0194 -> 0.139  Inexact Rounded
+sqtx3351 squareroot 0.195 -> 0.442  Inexact Rounded
+sqtx3352 squareroot 0.0195 -> 0.140  Inexact Rounded
+sqtx3353 squareroot 0.196 -> 0.443  Inexact Rounded
+sqtx3354 squareroot 0.0196 -> 0.14
+sqtx3355 squareroot 0.197 -> 0.444  Inexact Rounded
+sqtx3356 squareroot 0.0197 -> 0.140  Inexact Rounded
+sqtx3357 squareroot 0.198 -> 0.445  Inexact Rounded
+sqtx3358 squareroot 0.0198 -> 0.141  Inexact Rounded
+sqtx3359 squareroot 0.199 -> 0.446  Inexact Rounded
+sqtx3360 squareroot 0.0199 -> 0.141  Inexact Rounded
+sqtx3361 squareroot 0.201 -> 0.448  Inexact Rounded
+sqtx3362 squareroot 0.0201 -> 0.142  Inexact Rounded
+sqtx3363 squareroot 0.202 -> 0.449  Inexact Rounded
+sqtx3364 squareroot 0.0202 -> 0.142  Inexact Rounded
+sqtx3365 squareroot 0.203 -> 0.451  Inexact Rounded
+sqtx3366 squareroot 0.0203 -> 0.142  Inexact Rounded
+sqtx3367 squareroot 0.204 -> 0.452  Inexact Rounded
+sqtx3368 squareroot 0.0204 -> 0.143  Inexact Rounded
+sqtx3369 squareroot 0.205 -> 0.453  Inexact Rounded
+sqtx3370 squareroot 0.0205 -> 0.143  Inexact Rounded
+sqtx3371 squareroot 0.206 -> 0.454  Inexact Rounded
+sqtx3372 squareroot 0.0206 -> 0.144  Inexact Rounded
+sqtx3373 squareroot 0.207 -> 0.455  Inexact Rounded
+sqtx3374 squareroot 0.0207 -> 0.144  Inexact Rounded
+sqtx3375 squareroot 0.208 -> 0.456  Inexact Rounded
+sqtx3376 squareroot 0.0208 -> 0.144  Inexact Rounded
+sqtx3377 squareroot 0.209 -> 0.457  Inexact Rounded
+sqtx3378 squareroot 0.0209 -> 0.145  Inexact Rounded
+sqtx3379 squareroot 0.211 -> 0.459  Inexact Rounded
+sqtx3380 squareroot 0.0211 -> 0.145  Inexact Rounded
+sqtx3381 squareroot 0.212 -> 0.460  Inexact Rounded
+sqtx3382 squareroot 0.0212 -> 0.146  Inexact Rounded
+sqtx3383 squareroot 0.213 -> 0.462  Inexact Rounded
+sqtx3384 squareroot 0.0213 -> 0.146  Inexact Rounded
+sqtx3385 squareroot 0.214 -> 0.463  Inexact Rounded
+sqtx3386 squareroot 0.0214 -> 0.146  Inexact Rounded
+sqtx3387 squareroot 0.215 -> 0.464  Inexact Rounded
+sqtx3388 squareroot 0.0215 -> 0.147  Inexact Rounded
+sqtx3389 squareroot 0.216 -> 0.465  Inexact Rounded
+sqtx3390 squareroot 0.0216 -> 0.147  Inexact Rounded
+sqtx3391 squareroot 0.217 -> 0.466  Inexact Rounded
+sqtx3392 squareroot 0.0217 -> 0.147  Inexact Rounded
+sqtx3393 squareroot 0.218 -> 0.467  Inexact Rounded
+sqtx3394 squareroot 0.0218 -> 0.148  Inexact Rounded
+sqtx3395 squareroot 0.219 -> 0.468  Inexact Rounded
+sqtx3396 squareroot 0.0219 -> 0.148  Inexact Rounded
+sqtx3397 squareroot 0.221 -> 0.470  Inexact Rounded
+sqtx3398 squareroot 0.0221 -> 0.149  Inexact Rounded
+sqtx3399 squareroot 0.222 -> 0.471  Inexact Rounded
+sqtx3400 squareroot 0.0222 -> 0.149  Inexact Rounded
+sqtx3401 squareroot 0.223 -> 0.472  Inexact Rounded
+sqtx3402 squareroot 0.0223 -> 0.149  Inexact Rounded
+sqtx3403 squareroot 0.224 -> 0.473  Inexact Rounded
+sqtx3404 squareroot 0.0224 -> 0.150  Inexact Rounded
+sqtx3405 squareroot 0.225 -> 0.474  Inexact Rounded
+sqtx3406 squareroot 0.0225 -> 0.15
+sqtx3407 squareroot 0.226 -> 0.475  Inexact Rounded
+sqtx3408 squareroot 0.0226 -> 0.150  Inexact Rounded
+sqtx3409 squareroot 0.227 -> 0.476  Inexact Rounded
+sqtx3410 squareroot 0.0227 -> 0.151  Inexact Rounded
+sqtx3411 squareroot 0.228 -> 0.477  Inexact Rounded
+sqtx3412 squareroot 0.0228 -> 0.151  Inexact Rounded
+sqtx3413 squareroot 0.229 -> 0.479  Inexact Rounded
+sqtx3414 squareroot 0.0229 -> 0.151  Inexact Rounded
+sqtx3415 squareroot 0.231 -> 0.481  Inexact Rounded
+sqtx3416 squareroot 0.0231 -> 0.152  Inexact Rounded
+sqtx3417 squareroot 0.232 -> 0.482  Inexact Rounded
+sqtx3418 squareroot 0.0232 -> 0.152  Inexact Rounded
+sqtx3419 squareroot 0.233 -> 0.483  Inexact Rounded
+sqtx3420 squareroot 0.0233 -> 0.153  Inexact Rounded
+sqtx3421 squareroot 0.234 -> 0.484  Inexact Rounded
+sqtx3422 squareroot 0.0234 -> 0.153  Inexact Rounded
+sqtx3423 squareroot 0.235 -> 0.485  Inexact Rounded
+sqtx3424 squareroot 0.0235 -> 0.153  Inexact Rounded
+sqtx3425 squareroot 0.236 -> 0.486  Inexact Rounded
+sqtx3426 squareroot 0.0236 -> 0.154  Inexact Rounded
+sqtx3427 squareroot 0.237 -> 0.487  Inexact Rounded
+sqtx3428 squareroot 0.0237 -> 0.154  Inexact Rounded
+sqtx3429 squareroot 0.238 -> 0.488  Inexact Rounded
+sqtx3430 squareroot 0.0238 -> 0.154  Inexact Rounded
+sqtx3431 squareroot 0.239 -> 0.489  Inexact Rounded
+sqtx3432 squareroot 0.0239 -> 0.155  Inexact Rounded
+sqtx3433 squareroot 0.241 -> 0.491  Inexact Rounded
+sqtx3434 squareroot 0.0241 -> 0.155  Inexact Rounded
+sqtx3435 squareroot 0.242 -> 0.492  Inexact Rounded
+sqtx3436 squareroot 0.0242 -> 0.156  Inexact Rounded
+sqtx3437 squareroot 0.243 -> 0.493  Inexact Rounded
+sqtx3438 squareroot 0.0243 -> 0.156  Inexact Rounded
+sqtx3439 squareroot 0.244 -> 0.494  Inexact Rounded
+sqtx3440 squareroot 0.0244 -> 0.156  Inexact Rounded
+sqtx3441 squareroot 0.245 -> 0.495  Inexact Rounded
+sqtx3442 squareroot 0.0245 -> 0.157  Inexact Rounded
+sqtx3443 squareroot 0.246 -> 0.496  Inexact Rounded
+sqtx3444 squareroot 0.0246 -> 0.157  Inexact Rounded
+sqtx3445 squareroot 0.247 -> 0.497  Inexact Rounded
+sqtx3446 squareroot 0.0247 -> 0.157  Inexact Rounded
+sqtx3447 squareroot 0.248 -> 0.498  Inexact Rounded
+sqtx3448 squareroot 0.0248 -> 0.157  Inexact Rounded
+sqtx3449 squareroot 0.249 -> 0.499  Inexact Rounded
+sqtx3450 squareroot 0.0249 -> 0.158  Inexact Rounded
+sqtx3451 squareroot 0.251 -> 0.501  Inexact Rounded
+sqtx3452 squareroot 0.0251 -> 0.158  Inexact Rounded
+sqtx3453 squareroot 0.252 -> 0.502  Inexact Rounded
+sqtx3454 squareroot 0.0252 -> 0.159  Inexact Rounded
+sqtx3455 squareroot 0.253 -> 0.503  Inexact Rounded
+sqtx3456 squareroot 0.0253 -> 0.159  Inexact Rounded
+sqtx3457 squareroot 0.254 -> 0.504  Inexact Rounded
+sqtx3458 squareroot 0.0254 -> 0.159  Inexact Rounded
+sqtx3459 squareroot 0.255 -> 0.505  Inexact Rounded
+sqtx3460 squareroot 0.0255 -> 0.160  Inexact Rounded
+sqtx3461 squareroot 0.256 -> 0.506  Inexact Rounded
+sqtx3462 squareroot 0.0256 -> 0.16
+sqtx3463 squareroot 0.257 -> 0.507  Inexact Rounded
+sqtx3464 squareroot 0.0257 -> 0.160  Inexact Rounded
+sqtx3465 squareroot 0.258 -> 0.508  Inexact Rounded
+sqtx3466 squareroot 0.0258 -> 0.161  Inexact Rounded
+sqtx3467 squareroot 0.259 -> 0.509  Inexact Rounded
+sqtx3468 squareroot 0.0259 -> 0.161  Inexact Rounded
+sqtx3469 squareroot 0.261 -> 0.511  Inexact Rounded
+sqtx3470 squareroot 0.0261 -> 0.162  Inexact Rounded
+sqtx3471 squareroot 0.262 -> 0.512  Inexact Rounded
+sqtx3472 squareroot 0.0262 -> 0.162  Inexact Rounded
+sqtx3473 squareroot 0.263 -> 0.513  Inexact Rounded
+sqtx3474 squareroot 0.0263 -> 0.162  Inexact Rounded
+sqtx3475 squareroot 0.264 -> 0.514  Inexact Rounded
+sqtx3476 squareroot 0.0264 -> 0.162  Inexact Rounded
+sqtx3477 squareroot 0.265 -> 0.515  Inexact Rounded
+sqtx3478 squareroot 0.0265 -> 0.163  Inexact Rounded
+sqtx3479 squareroot 0.266 -> 0.516  Inexact Rounded
+sqtx3480 squareroot 0.0266 -> 0.163  Inexact Rounded
+sqtx3481 squareroot 0.267 -> 0.517  Inexact Rounded
+sqtx3482 squareroot 0.0267 -> 0.163  Inexact Rounded
+sqtx3483 squareroot 0.268 -> 0.518  Inexact Rounded
+sqtx3484 squareroot 0.0268 -> 0.164  Inexact Rounded
+sqtx3485 squareroot 0.269 -> 0.519  Inexact Rounded
+sqtx3486 squareroot 0.0269 -> 0.164  Inexact Rounded
+sqtx3487 squareroot 0.271 -> 0.521  Inexact Rounded
+sqtx3488 squareroot 0.0271 -> 0.165  Inexact Rounded
+sqtx3489 squareroot 0.272 -> 0.522  Inexact Rounded
+sqtx3490 squareroot 0.0272 -> 0.165  Inexact Rounded
+sqtx3491 squareroot 0.273 -> 0.522  Inexact Rounded
+sqtx3492 squareroot 0.0273 -> 0.165  Inexact Rounded
+sqtx3493 squareroot 0.274 -> 0.523  Inexact Rounded
+sqtx3494 squareroot 0.0274 -> 0.166  Inexact Rounded
+sqtx3495 squareroot 0.275 -> 0.524  Inexact Rounded
+sqtx3496 squareroot 0.0275 -> 0.166  Inexact Rounded
+sqtx3497 squareroot 0.276 -> 0.525  Inexact Rounded
+sqtx3498 squareroot 0.0276 -> 0.166  Inexact Rounded
+sqtx3499 squareroot 0.277 -> 0.526  Inexact Rounded
+sqtx3500 squareroot 0.0277 -> 0.166  Inexact Rounded
+sqtx3501 squareroot 0.278 -> 0.527  Inexact Rounded
+sqtx3502 squareroot 0.0278 -> 0.167  Inexact Rounded
+sqtx3503 squareroot 0.279 -> 0.528  Inexact Rounded
+sqtx3504 squareroot 0.0279 -> 0.167  Inexact Rounded
+sqtx3505 squareroot 0.281 -> 0.530  Inexact Rounded
+sqtx3506 squareroot 0.0281 -> 0.168  Inexact Rounded
+sqtx3507 squareroot 0.282 -> 0.531  Inexact Rounded
+sqtx3508 squareroot 0.0282 -> 0.168  Inexact Rounded
+sqtx3509 squareroot 0.283 -> 0.532  Inexact Rounded
+sqtx3510 squareroot 0.0283 -> 0.168  Inexact Rounded
+sqtx3511 squareroot 0.284 -> 0.533  Inexact Rounded
+sqtx3512 squareroot 0.0284 -> 0.169  Inexact Rounded
+sqtx3513 squareroot 0.285 -> 0.534  Inexact Rounded
+sqtx3514 squareroot 0.0285 -> 0.169  Inexact Rounded
+sqtx3515 squareroot 0.286 -> 0.535  Inexact Rounded
+sqtx3516 squareroot 0.0286 -> 0.169  Inexact Rounded
+sqtx3517 squareroot 0.287 -> 0.536  Inexact Rounded
+sqtx3518 squareroot 0.0287 -> 0.169  Inexact Rounded
+sqtx3519 squareroot 0.288 -> 0.537  Inexact Rounded
+sqtx3520 squareroot 0.0288 -> 0.170  Inexact Rounded
+sqtx3521 squareroot 0.289 -> 0.538  Inexact Rounded
+sqtx3522 squareroot 0.0289 -> 0.17
+sqtx3523 squareroot 0.291 -> 0.539  Inexact Rounded
+sqtx3524 squareroot 0.0291 -> 0.171  Inexact Rounded
+sqtx3525 squareroot 0.292 -> 0.540  Inexact Rounded
+sqtx3526 squareroot 0.0292 -> 0.171  Inexact Rounded
+sqtx3527 squareroot 0.293 -> 0.541  Inexact Rounded
+sqtx3528 squareroot 0.0293 -> 0.171  Inexact Rounded
+sqtx3529 squareroot 0.294 -> 0.542  Inexact Rounded
+sqtx3530 squareroot 0.0294 -> 0.171  Inexact Rounded
+sqtx3531 squareroot 0.295 -> 0.543  Inexact Rounded
+sqtx3532 squareroot 0.0295 -> 0.172  Inexact Rounded
+sqtx3533 squareroot 0.296 -> 0.544  Inexact Rounded
+sqtx3534 squareroot 0.0296 -> 0.172  Inexact Rounded
+sqtx3535 squareroot 0.297 -> 0.545  Inexact Rounded
+sqtx3536 squareroot 0.0297 -> 0.172  Inexact Rounded
+sqtx3537 squareroot 0.298 -> 0.546  Inexact Rounded
+sqtx3538 squareroot 0.0298 -> 0.173  Inexact Rounded
+sqtx3539 squareroot 0.299 -> 0.547  Inexact Rounded
+sqtx3540 squareroot 0.0299 -> 0.173  Inexact Rounded
+sqtx3541 squareroot 0.301 -> 0.549  Inexact Rounded
+sqtx3542 squareroot 0.0301 -> 0.173  Inexact Rounded
+sqtx3543 squareroot 0.302 -> 0.550  Inexact Rounded
+sqtx3544 squareroot 0.0302 -> 0.174  Inexact Rounded
+sqtx3545 squareroot 0.303 -> 0.550  Inexact Rounded
+sqtx3546 squareroot 0.0303 -> 0.174  Inexact Rounded
+sqtx3547 squareroot 0.304 -> 0.551  Inexact Rounded
+sqtx3548 squareroot 0.0304 -> 0.174  Inexact Rounded
+sqtx3549 squareroot 0.305 -> 0.552  Inexact Rounded
+sqtx3550 squareroot 0.0305 -> 0.175  Inexact Rounded
+sqtx3551 squareroot 0.306 -> 0.553  Inexact Rounded
+sqtx3552 squareroot 0.0306 -> 0.175  Inexact Rounded
+sqtx3553 squareroot 0.307 -> 0.554  Inexact Rounded
+sqtx3554 squareroot 0.0307 -> 0.175  Inexact Rounded
+sqtx3555 squareroot 0.308 -> 0.555  Inexact Rounded
+sqtx3556 squareroot 0.0308 -> 0.175  Inexact Rounded
+sqtx3557 squareroot 0.309 -> 0.556  Inexact Rounded
+sqtx3558 squareroot 0.0309 -> 0.176  Inexact Rounded
+sqtx3559 squareroot 0.311 -> 0.558  Inexact Rounded
+sqtx3560 squareroot 0.0311 -> 0.176  Inexact Rounded
+sqtx3561 squareroot 0.312 -> 0.559  Inexact Rounded
+sqtx3562 squareroot 0.0312 -> 0.177  Inexact Rounded
+sqtx3563 squareroot 0.313 -> 0.559  Inexact Rounded
+sqtx3564 squareroot 0.0313 -> 0.177  Inexact Rounded
+sqtx3565 squareroot 0.314 -> 0.560  Inexact Rounded
+sqtx3566 squareroot 0.0314 -> 0.177  Inexact Rounded
+sqtx3567 squareroot 0.315 -> 0.561  Inexact Rounded
+sqtx3568 squareroot 0.0315 -> 0.177  Inexact Rounded
+sqtx3569 squareroot 0.316 -> 0.562  Inexact Rounded
+sqtx3570 squareroot 0.0316 -> 0.178  Inexact Rounded
+sqtx3571 squareroot 0.317 -> 0.563  Inexact Rounded
+sqtx3572 squareroot 0.0317 -> 0.178  Inexact Rounded
+sqtx3573 squareroot 0.318 -> 0.564  Inexact Rounded
+sqtx3574 squareroot 0.0318 -> 0.178  Inexact Rounded
+sqtx3575 squareroot 0.319 -> 0.565  Inexact Rounded
+sqtx3576 squareroot 0.0319 -> 0.179  Inexact Rounded
+sqtx3577 squareroot 0.321 -> 0.567  Inexact Rounded
+sqtx3578 squareroot 0.0321 -> 0.179  Inexact Rounded
+sqtx3579 squareroot 0.322 -> 0.567  Inexact Rounded
+sqtx3580 squareroot 0.0322 -> 0.179  Inexact Rounded
+sqtx3581 squareroot 0.323 -> 0.568  Inexact Rounded
+sqtx3582 squareroot 0.0323 -> 0.180  Inexact Rounded
+sqtx3583 squareroot 0.324 -> 0.569  Inexact Rounded
+sqtx3584 squareroot 0.0324 -> 0.18
+sqtx3585 squareroot 0.325 -> 0.570  Inexact Rounded
+sqtx3586 squareroot 0.0325 -> 0.180  Inexact Rounded
+sqtx3587 squareroot 0.326 -> 0.571  Inexact Rounded
+sqtx3588 squareroot 0.0326 -> 0.181  Inexact Rounded
+sqtx3589 squareroot 0.327 -> 0.572  Inexact Rounded
+sqtx3590 squareroot 0.0327 -> 0.181  Inexact Rounded
+sqtx3591 squareroot 0.328 -> 0.573  Inexact Rounded
+sqtx3592 squareroot 0.0328 -> 0.181  Inexact Rounded
+sqtx3593 squareroot 0.329 -> 0.574  Inexact Rounded
+sqtx3594 squareroot 0.0329 -> 0.181  Inexact Rounded
+sqtx3595 squareroot 0.331 -> 0.575  Inexact Rounded
+sqtx3596 squareroot 0.0331 -> 0.182  Inexact Rounded
+sqtx3597 squareroot 0.332 -> 0.576  Inexact Rounded
+sqtx3598 squareroot 0.0332 -> 0.182  Inexact Rounded
+sqtx3599 squareroot 0.333 -> 0.577  Inexact Rounded
+sqtx3600 squareroot 0.0333 -> 0.182  Inexact Rounded
+sqtx3601 squareroot 0.334 -> 0.578  Inexact Rounded
+sqtx3602 squareroot 0.0334 -> 0.183  Inexact Rounded
+sqtx3603 squareroot 0.335 -> 0.579  Inexact Rounded
+sqtx3604 squareroot 0.0335 -> 0.183  Inexact Rounded
+sqtx3605 squareroot 0.336 -> 0.580  Inexact Rounded
+sqtx3606 squareroot 0.0336 -> 0.183  Inexact Rounded
+sqtx3607 squareroot 0.337 -> 0.581  Inexact Rounded
+sqtx3608 squareroot 0.0337 -> 0.184  Inexact Rounded
+sqtx3609 squareroot 0.338 -> 0.581  Inexact Rounded
+sqtx3610 squareroot 0.0338 -> 0.184  Inexact Rounded
+sqtx3611 squareroot 0.339 -> 0.582  Inexact Rounded
+sqtx3612 squareroot 0.0339 -> 0.184  Inexact Rounded
+sqtx3613 squareroot 0.341 -> 0.584  Inexact Rounded
+sqtx3614 squareroot 0.0341 -> 0.185  Inexact Rounded
+sqtx3615 squareroot 0.342 -> 0.585  Inexact Rounded
+sqtx3616 squareroot 0.0342 -> 0.185  Inexact Rounded
+sqtx3617 squareroot 0.343 -> 0.586  Inexact Rounded
+sqtx3618 squareroot 0.0343 -> 0.185  Inexact Rounded
+sqtx3619 squareroot 0.344 -> 0.587  Inexact Rounded
+sqtx3620 squareroot 0.0344 -> 0.185  Inexact Rounded
+sqtx3621 squareroot 0.345 -> 0.587  Inexact Rounded
+sqtx3622 squareroot 0.0345 -> 0.186  Inexact Rounded
+sqtx3623 squareroot 0.346 -> 0.588  Inexact Rounded
+sqtx3624 squareroot 0.0346 -> 0.186  Inexact Rounded
+sqtx3625 squareroot 0.347 -> 0.589  Inexact Rounded
+sqtx3626 squareroot 0.0347 -> 0.186  Inexact Rounded
+sqtx3627 squareroot 0.348 -> 0.590  Inexact Rounded
+sqtx3628 squareroot 0.0348 -> 0.187  Inexact Rounded
+sqtx3629 squareroot 0.349 -> 0.591  Inexact Rounded
+sqtx3630 squareroot 0.0349 -> 0.187  Inexact Rounded
+sqtx3631 squareroot 0.351 -> 0.592  Inexact Rounded
+sqtx3632 squareroot 0.0351 -> 0.187  Inexact Rounded
+sqtx3633 squareroot 0.352 -> 0.593  Inexact Rounded
+sqtx3634 squareroot 0.0352 -> 0.188  Inexact Rounded
+sqtx3635 squareroot 0.353 -> 0.594  Inexact Rounded
+sqtx3636 squareroot 0.0353 -> 0.188  Inexact Rounded
+sqtx3637 squareroot 0.354 -> 0.595  Inexact Rounded
+sqtx3638 squareroot 0.0354 -> 0.188  Inexact Rounded
+sqtx3639 squareroot 0.355 -> 0.596  Inexact Rounded
+sqtx3640 squareroot 0.0355 -> 0.188  Inexact Rounded
+sqtx3641 squareroot 0.356 -> 0.597  Inexact Rounded
+sqtx3642 squareroot 0.0356 -> 0.189  Inexact Rounded
+sqtx3643 squareroot 0.357 -> 0.597  Inexact Rounded
+sqtx3644 squareroot 0.0357 -> 0.189  Inexact Rounded
+sqtx3645 squareroot 0.358 -> 0.598  Inexact Rounded
+sqtx3646 squareroot 0.0358 -> 0.189  Inexact Rounded
+sqtx3647 squareroot 0.359 -> 0.599  Inexact Rounded
+sqtx3648 squareroot 0.0359 -> 0.189  Inexact Rounded
+sqtx3649 squareroot 0.361 -> 0.601  Inexact Rounded
+sqtx3650 squareroot 0.0361 -> 0.19
+sqtx3651 squareroot 0.362 -> 0.602  Inexact Rounded
+sqtx3652 squareroot 0.0362 -> 0.190  Inexact Rounded
+sqtx3653 squareroot 0.363 -> 0.602  Inexact Rounded
+sqtx3654 squareroot 0.0363 -> 0.191  Inexact Rounded
+sqtx3655 squareroot 0.364 -> 0.603  Inexact Rounded
+sqtx3656 squareroot 0.0364 -> 0.191  Inexact Rounded
+sqtx3657 squareroot 0.365 -> 0.604  Inexact Rounded
+sqtx3658 squareroot 0.0365 -> 0.191  Inexact Rounded
+sqtx3659 squareroot 0.366 -> 0.605  Inexact Rounded
+sqtx3660 squareroot 0.0366 -> 0.191  Inexact Rounded
+sqtx3661 squareroot 0.367 -> 0.606  Inexact Rounded
+sqtx3662 squareroot 0.0367 -> 0.192  Inexact Rounded
+sqtx3663 squareroot 0.368 -> 0.607  Inexact Rounded
+sqtx3664 squareroot 0.0368 -> 0.192  Inexact Rounded
+sqtx3665 squareroot 0.369 -> 0.607  Inexact Rounded
+sqtx3666 squareroot 0.0369 -> 0.192  Inexact Rounded
+sqtx3667 squareroot 0.371 -> 0.609  Inexact Rounded
+sqtx3668 squareroot 0.0371 -> 0.193  Inexact Rounded
+sqtx3669 squareroot 0.372 -> 0.610  Inexact Rounded
+sqtx3670 squareroot 0.0372 -> 0.193  Inexact Rounded
+sqtx3671 squareroot 0.373 -> 0.611  Inexact Rounded
+sqtx3672 squareroot 0.0373 -> 0.193  Inexact Rounded
+sqtx3673 squareroot 0.374 -> 0.612  Inexact Rounded
+sqtx3674 squareroot 0.0374 -> 0.193  Inexact Rounded
+sqtx3675 squareroot 0.375 -> 0.612  Inexact Rounded
+sqtx3676 squareroot 0.0375 -> 0.194  Inexact Rounded
+sqtx3677 squareroot 0.376 -> 0.613  Inexact Rounded
+sqtx3678 squareroot 0.0376 -> 0.194  Inexact Rounded
+sqtx3679 squareroot 0.377 -> 0.614  Inexact Rounded
+sqtx3680 squareroot 0.0377 -> 0.194  Inexact Rounded
+sqtx3681 squareroot 0.378 -> 0.615  Inexact Rounded
+sqtx3682 squareroot 0.0378 -> 0.194  Inexact Rounded
+sqtx3683 squareroot 0.379 -> 0.616  Inexact Rounded
+sqtx3684 squareroot 0.0379 -> 0.195  Inexact Rounded
+sqtx3685 squareroot 0.381 -> 0.617  Inexact Rounded
+sqtx3686 squareroot 0.0381 -> 0.195  Inexact Rounded
+sqtx3687 squareroot 0.382 -> 0.618  Inexact Rounded
+sqtx3688 squareroot 0.0382 -> 0.195  Inexact Rounded
+sqtx3689 squareroot 0.383 -> 0.619  Inexact Rounded
+sqtx3690 squareroot 0.0383 -> 0.196  Inexact Rounded
+sqtx3691 squareroot 0.384 -> 0.620  Inexact Rounded
+sqtx3692 squareroot 0.0384 -> 0.196  Inexact Rounded
+sqtx3693 squareroot 0.385 -> 0.620  Inexact Rounded
+sqtx3694 squareroot 0.0385 -> 0.196  Inexact Rounded
+sqtx3695 squareroot 0.386 -> 0.621  Inexact Rounded
+sqtx3696 squareroot 0.0386 -> 0.196  Inexact Rounded
+sqtx3697 squareroot 0.387 -> 0.622  Inexact Rounded
+sqtx3698 squareroot 0.0387 -> 0.197  Inexact Rounded
+sqtx3699 squareroot 0.388 -> 0.623  Inexact Rounded
+sqtx3700 squareroot 0.0388 -> 0.197  Inexact Rounded
+sqtx3701 squareroot 0.389 -> 0.624  Inexact Rounded
+sqtx3702 squareroot 0.0389 -> 0.197  Inexact Rounded
+sqtx3703 squareroot 0.391 -> 0.625  Inexact Rounded
+sqtx3704 squareroot 0.0391 -> 0.198  Inexact Rounded
+sqtx3705 squareroot 0.392 -> 0.626  Inexact Rounded
+sqtx3706 squareroot 0.0392 -> 0.198  Inexact Rounded
+sqtx3707 squareroot 0.393 -> 0.627  Inexact Rounded
+sqtx3708 squareroot 0.0393 -> 0.198  Inexact Rounded
+sqtx3709 squareroot 0.394 -> 0.628  Inexact Rounded
+sqtx3710 squareroot 0.0394 -> 0.198  Inexact Rounded
+sqtx3711 squareroot 0.395 -> 0.628  Inexact Rounded
+sqtx3712 squareroot 0.0395 -> 0.199  Inexact Rounded
+sqtx3713 squareroot 0.396 -> 0.629  Inexact Rounded
+sqtx3714 squareroot 0.0396 -> 0.199  Inexact Rounded
+sqtx3715 squareroot 0.397 -> 0.630  Inexact Rounded
+sqtx3716 squareroot 0.0397 -> 0.199  Inexact Rounded
+sqtx3717 squareroot 0.398 -> 0.631  Inexact Rounded
+sqtx3718 squareroot 0.0398 -> 0.199  Inexact Rounded
+sqtx3719 squareroot 0.399 -> 0.632  Inexact Rounded
+sqtx3720 squareroot 0.0399 -> 0.200  Inexact Rounded
+sqtx3721 squareroot 0.401 -> 0.633  Inexact Rounded
+sqtx3722 squareroot 0.0401 -> 0.200  Inexact Rounded
+sqtx3723 squareroot 0.402 -> 0.634  Inexact Rounded
+sqtx3724 squareroot 0.0402 -> 0.200  Inexact Rounded
+sqtx3725 squareroot 0.403 -> 0.635  Inexact Rounded
+sqtx3726 squareroot 0.0403 -> 0.201  Inexact Rounded
+sqtx3727 squareroot 0.404 -> 0.636  Inexact Rounded
+sqtx3728 squareroot 0.0404 -> 0.201  Inexact Rounded
+sqtx3729 squareroot 0.405 -> 0.636  Inexact Rounded
+sqtx3730 squareroot 0.0405 -> 0.201  Inexact Rounded
+sqtx3731 squareroot 0.406 -> 0.637  Inexact Rounded
+sqtx3732 squareroot 0.0406 -> 0.201  Inexact Rounded
+sqtx3733 squareroot 0.407 -> 0.638  Inexact Rounded
+sqtx3734 squareroot 0.0407 -> 0.202  Inexact Rounded
+sqtx3735 squareroot 0.408 -> 0.639  Inexact Rounded
+sqtx3736 squareroot 0.0408 -> 0.202  Inexact Rounded
+sqtx3737 squareroot 0.409 -> 0.640  Inexact Rounded
+sqtx3738 squareroot 0.0409 -> 0.202  Inexact Rounded
+sqtx3739 squareroot 0.411 -> 0.641  Inexact Rounded
+sqtx3740 squareroot 0.0411 -> 0.203  Inexact Rounded
+sqtx3741 squareroot 0.412 -> 0.642  Inexact Rounded
+sqtx3742 squareroot 0.0412 -> 0.203  Inexact Rounded
+sqtx3743 squareroot 0.413 -> 0.643  Inexact Rounded
+sqtx3744 squareroot 0.0413 -> 0.203  Inexact Rounded
+sqtx3745 squareroot 0.414 -> 0.643  Inexact Rounded
+sqtx3746 squareroot 0.0414 -> 0.203  Inexact Rounded
+sqtx3747 squareroot 0.415 -> 0.644  Inexact Rounded
+sqtx3748 squareroot 0.0415 -> 0.204  Inexact Rounded
+sqtx3749 squareroot 0.416 -> 0.645  Inexact Rounded
+sqtx3750 squareroot 0.0416 -> 0.204  Inexact Rounded
+sqtx3751 squareroot 0.417 -> 0.646  Inexact Rounded
+sqtx3752 squareroot 0.0417 -> 0.204  Inexact Rounded
+sqtx3753 squareroot 0.418 -> 0.647  Inexact Rounded
+sqtx3754 squareroot 0.0418 -> 0.204  Inexact Rounded
+sqtx3755 squareroot 0.419 -> 0.647  Inexact Rounded
+sqtx3756 squareroot 0.0419 -> 0.205  Inexact Rounded
+sqtx3757 squareroot 0.421 -> 0.649  Inexact Rounded
+sqtx3758 squareroot 0.0421 -> 0.205  Inexact Rounded
+sqtx3759 squareroot 0.422 -> 0.650  Inexact Rounded
+sqtx3760 squareroot 0.0422 -> 0.205  Inexact Rounded
+sqtx3761 squareroot 0.423 -> 0.650  Inexact Rounded
+sqtx3762 squareroot 0.0423 -> 0.206  Inexact Rounded
+sqtx3763 squareroot 0.424 -> 0.651  Inexact Rounded
+sqtx3764 squareroot 0.0424 -> 0.206  Inexact Rounded
+sqtx3765 squareroot 0.425 -> 0.652  Inexact Rounded
+sqtx3766 squareroot 0.0425 -> 0.206  Inexact Rounded
+sqtx3767 squareroot 0.426 -> 0.653  Inexact Rounded
+sqtx3768 squareroot 0.0426 -> 0.206  Inexact Rounded
+sqtx3769 squareroot 0.427 -> 0.653  Inexact Rounded
+sqtx3770 squareroot 0.0427 -> 0.207  Inexact Rounded
+sqtx3771 squareroot 0.428 -> 0.654  Inexact Rounded
+sqtx3772 squareroot 0.0428 -> 0.207  Inexact Rounded
+sqtx3773 squareroot 0.429 -> 0.655  Inexact Rounded
+sqtx3774 squareroot 0.0429 -> 0.207  Inexact Rounded
+sqtx3775 squareroot 0.431 -> 0.657  Inexact Rounded
+sqtx3776 squareroot 0.0431 -> 0.208  Inexact Rounded
+sqtx3777 squareroot 0.432 -> 0.657  Inexact Rounded
+sqtx3778 squareroot 0.0432 -> 0.208  Inexact Rounded
+sqtx3779 squareroot 0.433 -> 0.658  Inexact Rounded
+sqtx3780 squareroot 0.0433 -> 0.208  Inexact Rounded
+sqtx3781 squareroot 0.434 -> 0.659  Inexact Rounded
+sqtx3782 squareroot 0.0434 -> 0.208  Inexact Rounded
+sqtx3783 squareroot 0.435 -> 0.660  Inexact Rounded
+sqtx3784 squareroot 0.0435 -> 0.209  Inexact Rounded
+sqtx3785 squareroot 0.436 -> 0.660  Inexact Rounded
+sqtx3786 squareroot 0.0436 -> 0.209  Inexact Rounded
+sqtx3787 squareroot 0.437 -> 0.661  Inexact Rounded
+sqtx3788 squareroot 0.0437 -> 0.209  Inexact Rounded
+sqtx3789 squareroot 0.438 -> 0.662  Inexact Rounded
+sqtx3790 squareroot 0.0438 -> 0.209  Inexact Rounded
+sqtx3791 squareroot 0.439 -> 0.663  Inexact Rounded
+sqtx3792 squareroot 0.0439 -> 0.210  Inexact Rounded
+sqtx3793 squareroot 0.441 -> 0.664  Inexact Rounded
+sqtx3794 squareroot 0.0441 -> 0.21
+sqtx3795 squareroot 0.442 -> 0.665  Inexact Rounded
+sqtx3796 squareroot 0.0442 -> 0.210  Inexact Rounded
+sqtx3797 squareroot 0.443 -> 0.666  Inexact Rounded
+sqtx3798 squareroot 0.0443 -> 0.210  Inexact Rounded
+sqtx3799 squareroot 0.444 -> 0.666  Inexact Rounded
+sqtx3800 squareroot 0.0444 -> 0.211  Inexact Rounded
+sqtx3801 squareroot 0.445 -> 0.667  Inexact Rounded
+sqtx3802 squareroot 0.0445 -> 0.211  Inexact Rounded
+sqtx3803 squareroot 0.446 -> 0.668  Inexact Rounded
+sqtx3804 squareroot 0.0446 -> 0.211  Inexact Rounded
+sqtx3805 squareroot 0.447 -> 0.669  Inexact Rounded
+sqtx3806 squareroot 0.0447 -> 0.211  Inexact Rounded
+sqtx3807 squareroot 0.448 -> 0.669  Inexact Rounded
+sqtx3808 squareroot 0.0448 -> 0.212  Inexact Rounded
+sqtx3809 squareroot 0.449 -> 0.670  Inexact Rounded
+sqtx3810 squareroot 0.0449 -> 0.212  Inexact Rounded
+sqtx3811 squareroot 0.451 -> 0.672  Inexact Rounded
+sqtx3812 squareroot 0.0451 -> 0.212  Inexact Rounded
+sqtx3813 squareroot 0.452 -> 0.672  Inexact Rounded
+sqtx3814 squareroot 0.0452 -> 0.213  Inexact Rounded
+sqtx3815 squareroot 0.453 -> 0.673  Inexact Rounded
+sqtx3816 squareroot 0.0453 -> 0.213  Inexact Rounded
+sqtx3817 squareroot 0.454 -> 0.674  Inexact Rounded
+sqtx3818 squareroot 0.0454 -> 0.213  Inexact Rounded
+sqtx3819 squareroot 0.455 -> 0.675  Inexact Rounded
+sqtx3820 squareroot 0.0455 -> 0.213  Inexact Rounded
+sqtx3821 squareroot 0.456 -> 0.675  Inexact Rounded
+sqtx3822 squareroot 0.0456 -> 0.214  Inexact Rounded
+sqtx3823 squareroot 0.457 -> 0.676  Inexact Rounded
+sqtx3824 squareroot 0.0457 -> 0.214  Inexact Rounded
+sqtx3825 squareroot 0.458 -> 0.677  Inexact Rounded
+sqtx3826 squareroot 0.0458 -> 0.214  Inexact Rounded
+sqtx3827 squareroot 0.459 -> 0.677  Inexact Rounded
+sqtx3828 squareroot 0.0459 -> 0.214  Inexact Rounded
+sqtx3829 squareroot 0.461 -> 0.679  Inexact Rounded
+sqtx3830 squareroot 0.0461 -> 0.215  Inexact Rounded
+sqtx3831 squareroot 0.462 -> 0.680  Inexact Rounded
+sqtx3832 squareroot 0.0462 -> 0.215  Inexact Rounded
+sqtx3833 squareroot 0.463 -> 0.680  Inexact Rounded
+sqtx3834 squareroot 0.0463 -> 0.215  Inexact Rounded
+sqtx3835 squareroot 0.464 -> 0.681  Inexact Rounded
+sqtx3836 squareroot 0.0464 -> 0.215  Inexact Rounded
+sqtx3837 squareroot 0.465 -> 0.682  Inexact Rounded
+sqtx3838 squareroot 0.0465 -> 0.216  Inexact Rounded
+sqtx3839 squareroot 0.466 -> 0.683  Inexact Rounded
+sqtx3840 squareroot 0.0466 -> 0.216  Inexact Rounded
+sqtx3841 squareroot 0.467 -> 0.683  Inexact Rounded
+sqtx3842 squareroot 0.0467 -> 0.216  Inexact Rounded
+sqtx3843 squareroot 0.468 -> 0.684  Inexact Rounded
+sqtx3844 squareroot 0.0468 -> 0.216  Inexact Rounded
+sqtx3845 squareroot 0.469 -> 0.685  Inexact Rounded
+sqtx3846 squareroot 0.0469 -> 0.217  Inexact Rounded
+sqtx3847 squareroot 0.471 -> 0.686  Inexact Rounded
+sqtx3848 squareroot 0.0471 -> 0.217  Inexact Rounded
+sqtx3849 squareroot 0.472 -> 0.687  Inexact Rounded
+sqtx3850 squareroot 0.0472 -> 0.217  Inexact Rounded
+sqtx3851 squareroot 0.473 -> 0.688  Inexact Rounded
+sqtx3852 squareroot 0.0473 -> 0.217  Inexact Rounded
+sqtx3853 squareroot 0.474 -> 0.688  Inexact Rounded
+sqtx3854 squareroot 0.0474 -> 0.218  Inexact Rounded
+sqtx3855 squareroot 0.475 -> 0.689  Inexact Rounded
+sqtx3856 squareroot 0.0475 -> 0.218  Inexact Rounded
+sqtx3857 squareroot 0.476 -> 0.690  Inexact Rounded
+sqtx3858 squareroot 0.0476 -> 0.218  Inexact Rounded
+sqtx3859 squareroot 0.477 -> 0.691  Inexact Rounded
+sqtx3860 squareroot 0.0477 -> 0.218  Inexact Rounded
+sqtx3861 squareroot 0.478 -> 0.691  Inexact Rounded
+sqtx3862 squareroot 0.0478 -> 0.219  Inexact Rounded
+sqtx3863 squareroot 0.479 -> 0.692  Inexact Rounded
+sqtx3864 squareroot 0.0479 -> 0.219  Inexact Rounded
+sqtx3865 squareroot 0.481 -> 0.694  Inexact Rounded
+sqtx3866 squareroot 0.0481 -> 0.219  Inexact Rounded
+sqtx3867 squareroot 0.482 -> 0.694  Inexact Rounded
+sqtx3868 squareroot 0.0482 -> 0.220  Inexact Rounded
+sqtx3869 squareroot 0.483 -> 0.695  Inexact Rounded
+sqtx3870 squareroot 0.0483 -> 0.220  Inexact Rounded
+sqtx3871 squareroot 0.484 -> 0.696  Inexact Rounded
+sqtx3872 squareroot 0.0484 -> 0.22
+sqtx3873 squareroot 0.485 -> 0.696  Inexact Rounded
+sqtx3874 squareroot 0.0485 -> 0.220  Inexact Rounded
+sqtx3875 squareroot 0.486 -> 0.697  Inexact Rounded
+sqtx3876 squareroot 0.0486 -> 0.220  Inexact Rounded
+sqtx3877 squareroot 0.487 -> 0.698  Inexact Rounded
+sqtx3878 squareroot 0.0487 -> 0.221  Inexact Rounded
+sqtx3879 squareroot 0.488 -> 0.699  Inexact Rounded
+sqtx3880 squareroot 0.0488 -> 0.221  Inexact Rounded
+sqtx3881 squareroot 0.489 -> 0.699  Inexact Rounded
+sqtx3882 squareroot 0.0489 -> 0.221  Inexact Rounded
+sqtx3883 squareroot 0.491 -> 0.701  Inexact Rounded
+sqtx3884 squareroot 0.0491 -> 0.222  Inexact Rounded
+sqtx3885 squareroot 0.492 -> 0.701  Inexact Rounded
+sqtx3886 squareroot 0.0492 -> 0.222  Inexact Rounded
+sqtx3887 squareroot 0.493 -> 0.702  Inexact Rounded
+sqtx3888 squareroot 0.0493 -> 0.222  Inexact Rounded
+sqtx3889 squareroot 0.494 -> 0.703  Inexact Rounded
+sqtx3890 squareroot 0.0494 -> 0.222  Inexact Rounded
+sqtx3891 squareroot 0.495 -> 0.704  Inexact Rounded
+sqtx3892 squareroot 0.0495 -> 0.222  Inexact Rounded
+sqtx3893 squareroot 0.496 -> 0.704  Inexact Rounded
+sqtx3894 squareroot 0.0496 -> 0.223  Inexact Rounded
+sqtx3895 squareroot 0.497 -> 0.705  Inexact Rounded
+sqtx3896 squareroot 0.0497 -> 0.223  Inexact Rounded
+sqtx3897 squareroot 0.498 -> 0.706  Inexact Rounded
+sqtx3898 squareroot 0.0498 -> 0.223  Inexact Rounded
+sqtx3899 squareroot 0.499 -> 0.706  Inexact Rounded
+sqtx3900 squareroot 0.0499 -> 0.223  Inexact Rounded
+sqtx3901 squareroot 0.501 -> 0.708  Inexact Rounded
+sqtx3902 squareroot 0.0501 -> 0.224  Inexact Rounded
+sqtx3903 squareroot 0.502 -> 0.709  Inexact Rounded
+sqtx3904 squareroot 0.0502 -> 0.224  Inexact Rounded
+sqtx3905 squareroot 0.503 -> 0.709  Inexact Rounded
+sqtx3906 squareroot 0.0503 -> 0.224  Inexact Rounded
+sqtx3907 squareroot 0.504 -> 0.710  Inexact Rounded
+sqtx3908 squareroot 0.0504 -> 0.224  Inexact Rounded
+sqtx3909 squareroot 0.505 -> 0.711  Inexact Rounded
+sqtx3910 squareroot 0.0505 -> 0.225  Inexact Rounded
+sqtx3911 squareroot 0.506 -> 0.711  Inexact Rounded
+sqtx3912 squareroot 0.0506 -> 0.225  Inexact Rounded
+sqtx3913 squareroot 0.507 -> 0.712  Inexact Rounded
+sqtx3914 squareroot 0.0507 -> 0.225  Inexact Rounded
+sqtx3915 squareroot 0.508 -> 0.713  Inexact Rounded
+sqtx3916 squareroot 0.0508 -> 0.225  Inexact Rounded
+sqtx3917 squareroot 0.509 -> 0.713  Inexact Rounded
+sqtx3918 squareroot 0.0509 -> 0.226  Inexact Rounded
+sqtx3919 squareroot 0.511 -> 0.715  Inexact Rounded
+sqtx3920 squareroot 0.0511 -> 0.226  Inexact Rounded
+sqtx3921 squareroot 0.512 -> 0.716  Inexact Rounded
+sqtx3922 squareroot 0.0512 -> 0.226  Inexact Rounded
+sqtx3923 squareroot 0.513 -> 0.716  Inexact Rounded
+sqtx3924 squareroot 0.0513 -> 0.226  Inexact Rounded
+sqtx3925 squareroot 0.514 -> 0.717  Inexact Rounded
+sqtx3926 squareroot 0.0514 -> 0.227  Inexact Rounded
+sqtx3927 squareroot 0.515 -> 0.718  Inexact Rounded
+sqtx3928 squareroot 0.0515 -> 0.227  Inexact Rounded
+sqtx3929 squareroot 0.516 -> 0.718  Inexact Rounded
+sqtx3930 squareroot 0.0516 -> 0.227  Inexact Rounded
+sqtx3931 squareroot 0.517 -> 0.719  Inexact Rounded
+sqtx3932 squareroot 0.0517 -> 0.227  Inexact Rounded
+sqtx3933 squareroot 0.518 -> 0.720  Inexact Rounded
+sqtx3934 squareroot 0.0518 -> 0.228  Inexact Rounded
+sqtx3935 squareroot 0.519 -> 0.720  Inexact Rounded
+sqtx3936 squareroot 0.0519 -> 0.228  Inexact Rounded
+sqtx3937 squareroot 0.521 -> 0.722  Inexact Rounded
+sqtx3938 squareroot 0.0521 -> 0.228  Inexact Rounded
+sqtx3939 squareroot 0.522 -> 0.722  Inexact Rounded
+sqtx3940 squareroot 0.0522 -> 0.228  Inexact Rounded
+sqtx3941 squareroot 0.523 -> 0.723  Inexact Rounded
+sqtx3942 squareroot 0.0523 -> 0.229  Inexact Rounded
+sqtx3943 squareroot 0.524 -> 0.724  Inexact Rounded
+sqtx3944 squareroot 0.0524 -> 0.229  Inexact Rounded
+sqtx3945 squareroot 0.525 -> 0.725  Inexact Rounded
+sqtx3946 squareroot 0.0525 -> 0.229  Inexact Rounded
+sqtx3947 squareroot 0.526 -> 0.725  Inexact Rounded
+sqtx3948 squareroot 0.0526 -> 0.229  Inexact Rounded
+sqtx3949 squareroot 0.527 -> 0.726  Inexact Rounded
+sqtx3950 squareroot 0.0527 -> 0.230  Inexact Rounded
+sqtx3951 squareroot 0.528 -> 0.727  Inexact Rounded
+sqtx3952 squareroot 0.0528 -> 0.230  Inexact Rounded
+sqtx3953 squareroot 0.529 -> 0.727  Inexact Rounded
+sqtx3954 squareroot 0.0529 -> 0.23
+sqtx3955 squareroot 0.531 -> 0.729  Inexact Rounded
+sqtx3956 squareroot 0.0531 -> 0.230  Inexact Rounded
+sqtx3957 squareroot 0.532 -> 0.729  Inexact Rounded
+sqtx3958 squareroot 0.0532 -> 0.231  Inexact Rounded
+sqtx3959 squareroot 0.533 -> 0.730  Inexact Rounded
+sqtx3960 squareroot 0.0533 -> 0.231  Inexact Rounded
+sqtx3961 squareroot 0.534 -> 0.731  Inexact Rounded
+sqtx3962 squareroot 0.0534 -> 0.231  Inexact Rounded
+sqtx3963 squareroot 0.535 -> 0.731  Inexact Rounded
+sqtx3964 squareroot 0.0535 -> 0.231  Inexact Rounded
+sqtx3965 squareroot 0.536 -> 0.732  Inexact Rounded
+sqtx3966 squareroot 0.0536 -> 0.232  Inexact Rounded
+sqtx3967 squareroot 0.537 -> 0.733  Inexact Rounded
+sqtx3968 squareroot 0.0537 -> 0.232  Inexact Rounded
+sqtx3969 squareroot 0.538 -> 0.733  Inexact Rounded
+sqtx3970 squareroot 0.0538 -> 0.232  Inexact Rounded
+sqtx3971 squareroot 0.539 -> 0.734  Inexact Rounded
+sqtx3972 squareroot 0.0539 -> 0.232  Inexact Rounded
+sqtx3973 squareroot 0.541 -> 0.736  Inexact Rounded
+sqtx3974 squareroot 0.0541 -> 0.233  Inexact Rounded
+sqtx3975 squareroot 0.542 -> 0.736  Inexact Rounded
+sqtx3976 squareroot 0.0542 -> 0.233  Inexact Rounded
+sqtx3977 squareroot 0.543 -> 0.737  Inexact Rounded
+sqtx3978 squareroot 0.0543 -> 0.233  Inexact Rounded
+sqtx3979 squareroot 0.544 -> 0.738  Inexact Rounded
+sqtx3980 squareroot 0.0544 -> 0.233  Inexact Rounded
+sqtx3981 squareroot 0.545 -> 0.738  Inexact Rounded
+sqtx3982 squareroot 0.0545 -> 0.233  Inexact Rounded
+sqtx3983 squareroot 0.546 -> 0.739  Inexact Rounded
+sqtx3984 squareroot 0.0546 -> 0.234  Inexact Rounded
+sqtx3985 squareroot 0.547 -> 0.740  Inexact Rounded
+sqtx3986 squareroot 0.0547 -> 0.234  Inexact Rounded
+sqtx3987 squareroot 0.548 -> 0.740  Inexact Rounded
+sqtx3988 squareroot 0.0548 -> 0.234  Inexact Rounded
+sqtx3989 squareroot 0.549 -> 0.741  Inexact Rounded
+sqtx3990 squareroot 0.0549 -> 0.234  Inexact Rounded
+sqtx3991 squareroot 0.551 -> 0.742  Inexact Rounded
+sqtx3992 squareroot 0.0551 -> 0.235  Inexact Rounded
+sqtx3993 squareroot 0.552 -> 0.743  Inexact Rounded
+sqtx3994 squareroot 0.0552 -> 0.235  Inexact Rounded
+sqtx3995 squareroot 0.553 -> 0.744  Inexact Rounded
+sqtx3996 squareroot 0.0553 -> 0.235  Inexact Rounded
+sqtx3997 squareroot 0.554 -> 0.744  Inexact Rounded
+sqtx3998 squareroot 0.0554 -> 0.235  Inexact Rounded
+sqtx3999 squareroot 0.555 -> 0.745  Inexact Rounded
+sqtx4000 squareroot 0.0555 -> 0.236  Inexact Rounded
+sqtx4001 squareroot 0.556 -> 0.746  Inexact Rounded
+sqtx4002 squareroot 0.0556 -> 0.236  Inexact Rounded
+sqtx4003 squareroot 0.557 -> 0.746  Inexact Rounded
+sqtx4004 squareroot 0.0557 -> 0.236  Inexact Rounded
+sqtx4005 squareroot 0.558 -> 0.747  Inexact Rounded
+sqtx4006 squareroot 0.0558 -> 0.236  Inexact Rounded
+sqtx4007 squareroot 0.559 -> 0.748  Inexact Rounded
+sqtx4008 squareroot 0.0559 -> 0.236  Inexact Rounded
+sqtx4009 squareroot 0.561 -> 0.749  Inexact Rounded
+sqtx4010 squareroot 0.0561 -> 0.237  Inexact Rounded
+sqtx4011 squareroot 0.562 -> 0.750  Inexact Rounded
+sqtx4012 squareroot 0.0562 -> 0.237  Inexact Rounded
+sqtx4013 squareroot 0.563 -> 0.750  Inexact Rounded
+sqtx4014 squareroot 0.0563 -> 0.237  Inexact Rounded
+sqtx4015 squareroot 0.564 -> 0.751  Inexact Rounded
+sqtx4016 squareroot 0.0564 -> 0.237  Inexact Rounded
+sqtx4017 squareroot 0.565 -> 0.752  Inexact Rounded
+sqtx4018 squareroot 0.0565 -> 0.238  Inexact Rounded
+sqtx4019 squareroot 0.566 -> 0.752  Inexact Rounded
+sqtx4020 squareroot 0.0566 -> 0.238  Inexact Rounded
+sqtx4021 squareroot 0.567 -> 0.753  Inexact Rounded
+sqtx4022 squareroot 0.0567 -> 0.238  Inexact Rounded
+sqtx4023 squareroot 0.568 -> 0.754  Inexact Rounded
+sqtx4024 squareroot 0.0568 -> 0.238  Inexact Rounded
+sqtx4025 squareroot 0.569 -> 0.754  Inexact Rounded
+sqtx4026 squareroot 0.0569 -> 0.239  Inexact Rounded
+sqtx4027 squareroot 0.571 -> 0.756  Inexact Rounded
+sqtx4028 squareroot 0.0571 -> 0.239  Inexact Rounded
+sqtx4029 squareroot 0.572 -> 0.756  Inexact Rounded
+sqtx4030 squareroot 0.0572 -> 0.239  Inexact Rounded
+sqtx4031 squareroot 0.573 -> 0.757  Inexact Rounded
+sqtx4032 squareroot 0.0573 -> 0.239  Inexact Rounded
+sqtx4033 squareroot 0.574 -> 0.758  Inexact Rounded
+sqtx4034 squareroot 0.0574 -> 0.240  Inexact Rounded
+sqtx4035 squareroot 0.575 -> 0.758  Inexact Rounded
+sqtx4036 squareroot 0.0575 -> 0.240  Inexact Rounded
+sqtx4037 squareroot 0.576 -> 0.759  Inexact Rounded
+sqtx4038 squareroot 0.0576 -> 0.24
+sqtx4039 squareroot 0.577 -> 0.760  Inexact Rounded
+sqtx4040 squareroot 0.0577 -> 0.240  Inexact Rounded
+sqtx4041 squareroot 0.578 -> 0.760  Inexact Rounded
+sqtx4042 squareroot 0.0578 -> 0.240  Inexact Rounded
+sqtx4043 squareroot 0.579 -> 0.761  Inexact Rounded
+sqtx4044 squareroot 0.0579 -> 0.241  Inexact Rounded
+sqtx4045 squareroot 0.581 -> 0.762  Inexact Rounded
+sqtx4046 squareroot 0.0581 -> 0.241  Inexact Rounded
+sqtx4047 squareroot 0.582 -> 0.763  Inexact Rounded
+sqtx4048 squareroot 0.0582 -> 0.241  Inexact Rounded
+sqtx4049 squareroot 0.583 -> 0.764  Inexact Rounded
+sqtx4050 squareroot 0.0583 -> 0.241  Inexact Rounded
+sqtx4051 squareroot 0.584 -> 0.764  Inexact Rounded
+sqtx4052 squareroot 0.0584 -> 0.242  Inexact Rounded
+sqtx4053 squareroot 0.585 -> 0.765  Inexact Rounded
+sqtx4054 squareroot 0.0585 -> 0.242  Inexact Rounded
+sqtx4055 squareroot 0.586 -> 0.766  Inexact Rounded
+sqtx4056 squareroot 0.0586 -> 0.242  Inexact Rounded
+sqtx4057 squareroot 0.587 -> 0.766  Inexact Rounded
+sqtx4058 squareroot 0.0587 -> 0.242  Inexact Rounded
+sqtx4059 squareroot 0.588 -> 0.767  Inexact Rounded
+sqtx4060 squareroot 0.0588 -> 0.242  Inexact Rounded
+sqtx4061 squareroot 0.589 -> 0.767  Inexact Rounded
+sqtx4062 squareroot 0.0589 -> 0.243  Inexact Rounded
+sqtx4063 squareroot 0.591 -> 0.769  Inexact Rounded
+sqtx4064 squareroot 0.0591 -> 0.243  Inexact Rounded
+sqtx4065 squareroot 0.592 -> 0.769  Inexact Rounded
+sqtx4066 squareroot 0.0592 -> 0.243  Inexact Rounded
+sqtx4067 squareroot 0.593 -> 0.770  Inexact Rounded
+sqtx4068 squareroot 0.0593 -> 0.244  Inexact Rounded
+sqtx4069 squareroot 0.594 -> 0.771  Inexact Rounded
+sqtx4070 squareroot 0.0594 -> 0.244  Inexact Rounded
+sqtx4071 squareroot 0.595 -> 0.771  Inexact Rounded
+sqtx4072 squareroot 0.0595 -> 0.244  Inexact Rounded
+sqtx4073 squareroot 0.596 -> 0.772  Inexact Rounded
+sqtx4074 squareroot 0.0596 -> 0.244  Inexact Rounded
+sqtx4075 squareroot 0.597 -> 0.773  Inexact Rounded
+sqtx4076 squareroot 0.0597 -> 0.244  Inexact Rounded
+sqtx4077 squareroot 0.598 -> 0.773  Inexact Rounded
+sqtx4078 squareroot 0.0598 -> 0.245  Inexact Rounded
+sqtx4079 squareroot 0.599 -> 0.774  Inexact Rounded
+sqtx4080 squareroot 0.0599 -> 0.245  Inexact Rounded
+sqtx4081 squareroot 0.601 -> 0.775  Inexact Rounded
+sqtx4082 squareroot 0.0601 -> 0.245  Inexact Rounded
+sqtx4083 squareroot 0.602 -> 0.776  Inexact Rounded
+sqtx4084 squareroot 0.0602 -> 0.245  Inexact Rounded
+sqtx4085 squareroot 0.603 -> 0.777  Inexact Rounded
+sqtx4086 squareroot 0.0603 -> 0.246  Inexact Rounded
+sqtx4087 squareroot 0.604 -> 0.777  Inexact Rounded
+sqtx4088 squareroot 0.0604 -> 0.246  Inexact Rounded
+sqtx4089 squareroot 0.605 -> 0.778  Inexact Rounded
+sqtx4090 squareroot 0.0605 -> 0.246  Inexact Rounded
+sqtx4091 squareroot 0.606 -> 0.778  Inexact Rounded
+sqtx4092 squareroot 0.0606 -> 0.246  Inexact Rounded
+sqtx4093 squareroot 0.607 -> 0.779  Inexact Rounded
+sqtx4094 squareroot 0.0607 -> 0.246  Inexact Rounded
+sqtx4095 squareroot 0.608 -> 0.780  Inexact Rounded
+sqtx4096 squareroot 0.0608 -> 0.247  Inexact Rounded
+sqtx4097 squareroot 0.609 -> 0.780  Inexact Rounded
+sqtx4098 squareroot 0.0609 -> 0.247  Inexact Rounded
+sqtx4099 squareroot 0.611 -> 0.782  Inexact Rounded
+sqtx4100 squareroot 0.0611 -> 0.247  Inexact Rounded
+sqtx4101 squareroot 0.612 -> 0.782  Inexact Rounded
+sqtx4102 squareroot 0.0612 -> 0.247  Inexact Rounded
+sqtx4103 squareroot 0.613 -> 0.783  Inexact Rounded
+sqtx4104 squareroot 0.0613 -> 0.248  Inexact Rounded
+sqtx4105 squareroot 0.614 -> 0.784  Inexact Rounded
+sqtx4106 squareroot 0.0614 -> 0.248  Inexact Rounded
+sqtx4107 squareroot 0.615 -> 0.784  Inexact Rounded
+sqtx4108 squareroot 0.0615 -> 0.248  Inexact Rounded
+sqtx4109 squareroot 0.616 -> 0.785  Inexact Rounded
+sqtx4110 squareroot 0.0616 -> 0.248  Inexact Rounded
+sqtx4111 squareroot 0.617 -> 0.785  Inexact Rounded
+sqtx4112 squareroot 0.0617 -> 0.248  Inexact Rounded
+sqtx4113 squareroot 0.618 -> 0.786  Inexact Rounded
+sqtx4114 squareroot 0.0618 -> 0.249  Inexact Rounded
+sqtx4115 squareroot 0.619 -> 0.787  Inexact Rounded
+sqtx4116 squareroot 0.0619 -> 0.249  Inexact Rounded
+sqtx4117 squareroot 0.621 -> 0.788  Inexact Rounded
+sqtx4118 squareroot 0.0621 -> 0.249  Inexact Rounded
+sqtx4119 squareroot 0.622 -> 0.789  Inexact Rounded
+sqtx4120 squareroot 0.0622 -> 0.249  Inexact Rounded
+sqtx4121 squareroot 0.623 -> 0.789  Inexact Rounded
+sqtx4122 squareroot 0.0623 -> 0.250  Inexact Rounded
+sqtx4123 squareroot 0.624 -> 0.790  Inexact Rounded
+sqtx4124 squareroot 0.0624 -> 0.250  Inexact Rounded
+sqtx4125 squareroot 0.625 -> 0.791  Inexact Rounded
+sqtx4126 squareroot 0.0625 -> 0.25
+sqtx4127 squareroot 0.626 -> 0.791  Inexact Rounded
+sqtx4128 squareroot 0.0626 -> 0.250  Inexact Rounded
+sqtx4129 squareroot 0.627 -> 0.792  Inexact Rounded
+sqtx4130 squareroot 0.0627 -> 0.250  Inexact Rounded
+sqtx4131 squareroot 0.628 -> 0.792  Inexact Rounded
+sqtx4132 squareroot 0.0628 -> 0.251  Inexact Rounded
+sqtx4133 squareroot 0.629 -> 0.793  Inexact Rounded
+sqtx4134 squareroot 0.0629 -> 0.251  Inexact Rounded
+sqtx4135 squareroot 0.631 -> 0.794  Inexact Rounded
+sqtx4136 squareroot 0.0631 -> 0.251  Inexact Rounded
+sqtx4137 squareroot 0.632 -> 0.795  Inexact Rounded
+sqtx4138 squareroot 0.0632 -> 0.251  Inexact Rounded
+sqtx4139 squareroot 0.633 -> 0.796  Inexact Rounded
+sqtx4140 squareroot 0.0633 -> 0.252  Inexact Rounded
+sqtx4141 squareroot 0.634 -> 0.796  Inexact Rounded
+sqtx4142 squareroot 0.0634 -> 0.252  Inexact Rounded
+sqtx4143 squareroot 0.635 -> 0.797  Inexact Rounded
+sqtx4144 squareroot 0.0635 -> 0.252  Inexact Rounded
+sqtx4145 squareroot 0.636 -> 0.797  Inexact Rounded
+sqtx4146 squareroot 0.0636 -> 0.252  Inexact Rounded
+sqtx4147 squareroot 0.637 -> 0.798  Inexact Rounded
+sqtx4148 squareroot 0.0637 -> 0.252  Inexact Rounded
+sqtx4149 squareroot 0.638 -> 0.799  Inexact Rounded
+sqtx4150 squareroot 0.0638 -> 0.253  Inexact Rounded
+sqtx4151 squareroot 0.639 -> 0.799  Inexact Rounded
+sqtx4152 squareroot 0.0639 -> 0.253  Inexact Rounded
+sqtx4153 squareroot 0.641 -> 0.801  Inexact Rounded
+sqtx4154 squareroot 0.0641 -> 0.253  Inexact Rounded
+sqtx4155 squareroot 0.642 -> 0.801  Inexact Rounded
+sqtx4156 squareroot 0.0642 -> 0.253  Inexact Rounded
+sqtx4157 squareroot 0.643 -> 0.802  Inexact Rounded
+sqtx4158 squareroot 0.0643 -> 0.254  Inexact Rounded
+sqtx4159 squareroot 0.644 -> 0.802  Inexact Rounded
+sqtx4160 squareroot 0.0644 -> 0.254  Inexact Rounded
+sqtx4161 squareroot 0.645 -> 0.803  Inexact Rounded
+sqtx4162 squareroot 0.0645 -> 0.254  Inexact Rounded
+sqtx4163 squareroot 0.646 -> 0.804  Inexact Rounded
+sqtx4164 squareroot 0.0646 -> 0.254  Inexact Rounded
+sqtx4165 squareroot 0.647 -> 0.804  Inexact Rounded
+sqtx4166 squareroot 0.0647 -> 0.254  Inexact Rounded
+sqtx4167 squareroot 0.648 -> 0.805  Inexact Rounded
+sqtx4168 squareroot 0.0648 -> 0.255  Inexact Rounded
+sqtx4169 squareroot 0.649 -> 0.806  Inexact Rounded
+sqtx4170 squareroot 0.0649 -> 0.255  Inexact Rounded
+sqtx4171 squareroot 0.651 -> 0.807  Inexact Rounded
+sqtx4172 squareroot 0.0651 -> 0.255  Inexact Rounded
+sqtx4173 squareroot 0.652 -> 0.807  Inexact Rounded
+sqtx4174 squareroot 0.0652 -> 0.255  Inexact Rounded
+sqtx4175 squareroot 0.653 -> 0.808  Inexact Rounded
+sqtx4176 squareroot 0.0653 -> 0.256  Inexact Rounded
+sqtx4177 squareroot 0.654 -> 0.809  Inexact Rounded
+sqtx4178 squareroot 0.0654 -> 0.256  Inexact Rounded
+sqtx4179 squareroot 0.655 -> 0.809  Inexact Rounded
+sqtx4180 squareroot 0.0655 -> 0.256  Inexact Rounded
+sqtx4181 squareroot 0.656 -> 0.810  Inexact Rounded
+sqtx4182 squareroot 0.0656 -> 0.256  Inexact Rounded
+sqtx4183 squareroot 0.657 -> 0.811  Inexact Rounded
+sqtx4184 squareroot 0.0657 -> 0.256  Inexact Rounded
+sqtx4185 squareroot 0.658 -> 0.811  Inexact Rounded
+sqtx4186 squareroot 0.0658 -> 0.257  Inexact Rounded
+sqtx4187 squareroot 0.659 -> 0.812  Inexact Rounded
+sqtx4188 squareroot 0.0659 -> 0.257  Inexact Rounded
+sqtx4189 squareroot 0.661 -> 0.813  Inexact Rounded
+sqtx4190 squareroot 0.0661 -> 0.257  Inexact Rounded
+sqtx4191 squareroot 0.662 -> 0.814  Inexact Rounded
+sqtx4192 squareroot 0.0662 -> 0.257  Inexact Rounded
+sqtx4193 squareroot 0.663 -> 0.814  Inexact Rounded
+sqtx4194 squareroot 0.0663 -> 0.257  Inexact Rounded
+sqtx4195 squareroot 0.664 -> 0.815  Inexact Rounded
+sqtx4196 squareroot 0.0664 -> 0.258  Inexact Rounded
+sqtx4197 squareroot 0.665 -> 0.815  Inexact Rounded
+sqtx4198 squareroot 0.0665 -> 0.258  Inexact Rounded
+sqtx4199 squareroot 0.666 -> 0.816  Inexact Rounded
+sqtx4200 squareroot 0.0666 -> 0.258  Inexact Rounded
+sqtx4201 squareroot 0.667 -> 0.817  Inexact Rounded
+sqtx4202 squareroot 0.0667 -> 0.258  Inexact Rounded
+sqtx4203 squareroot 0.668 -> 0.817  Inexact Rounded
+sqtx4204 squareroot 0.0668 -> 0.258  Inexact Rounded
+sqtx4205 squareroot 0.669 -> 0.818  Inexact Rounded
+sqtx4206 squareroot 0.0669 -> 0.259  Inexact Rounded
+sqtx4207 squareroot 0.671 -> 0.819  Inexact Rounded
+sqtx4208 squareroot 0.0671 -> 0.259  Inexact Rounded
+sqtx4209 squareroot 0.672 -> 0.820  Inexact Rounded
+sqtx4210 squareroot 0.0672 -> 0.259  Inexact Rounded
+sqtx4211 squareroot 0.673 -> 0.820  Inexact Rounded
+sqtx4212 squareroot 0.0673 -> 0.259  Inexact Rounded
+sqtx4213 squareroot 0.674 -> 0.821  Inexact Rounded
+sqtx4214 squareroot 0.0674 -> 0.260  Inexact Rounded
+sqtx4215 squareroot 0.675 -> 0.822  Inexact Rounded
+sqtx4216 squareroot 0.0675 -> 0.260  Inexact Rounded
+sqtx4217 squareroot 0.676 -> 0.822  Inexact Rounded
+sqtx4218 squareroot 0.0676 -> 0.26
+sqtx4219 squareroot 0.677 -> 0.823  Inexact Rounded
+sqtx4220 squareroot 0.0677 -> 0.260  Inexact Rounded
+sqtx4221 squareroot 0.678 -> 0.823  Inexact Rounded
+sqtx4222 squareroot 0.0678 -> 0.260  Inexact Rounded
+sqtx4223 squareroot 0.679 -> 0.824  Inexact Rounded
+sqtx4224 squareroot 0.0679 -> 0.261  Inexact Rounded
+sqtx4225 squareroot 0.681 -> 0.825  Inexact Rounded
+sqtx4226 squareroot 0.0681 -> 0.261  Inexact Rounded
+sqtx4227 squareroot 0.682 -> 0.826  Inexact Rounded
+sqtx4228 squareroot 0.0682 -> 0.261  Inexact Rounded
+sqtx4229 squareroot 0.683 -> 0.826  Inexact Rounded
+sqtx4230 squareroot 0.0683 -> 0.261  Inexact Rounded
+sqtx4231 squareroot 0.684 -> 0.827  Inexact Rounded
+sqtx4232 squareroot 0.0684 -> 0.262  Inexact Rounded
+sqtx4233 squareroot 0.685 -> 0.828  Inexact Rounded
+sqtx4234 squareroot 0.0685 -> 0.262  Inexact Rounded
+sqtx4235 squareroot 0.686 -> 0.828  Inexact Rounded
+sqtx4236 squareroot 0.0686 -> 0.262  Inexact Rounded
+sqtx4237 squareroot 0.687 -> 0.829  Inexact Rounded
+sqtx4238 squareroot 0.0687 -> 0.262  Inexact Rounded
+sqtx4239 squareroot 0.688 -> 0.829  Inexact Rounded
+sqtx4240 squareroot 0.0688 -> 0.262  Inexact Rounded
+sqtx4241 squareroot 0.689 -> 0.830  Inexact Rounded
+sqtx4242 squareroot 0.0689 -> 0.262  Inexact Rounded
+sqtx4243 squareroot 0.691 -> 0.831  Inexact Rounded
+sqtx4244 squareroot 0.0691 -> 0.263  Inexact Rounded
+sqtx4245 squareroot 0.692 -> 0.832  Inexact Rounded
+sqtx4246 squareroot 0.0692 -> 0.263  Inexact Rounded
+sqtx4247 squareroot 0.693 -> 0.832  Inexact Rounded
+sqtx4248 squareroot 0.0693 -> 0.263  Inexact Rounded
+sqtx4249 squareroot 0.694 -> 0.833  Inexact Rounded
+sqtx4250 squareroot 0.0694 -> 0.263  Inexact Rounded
+sqtx4251 squareroot 0.695 -> 0.834  Inexact Rounded
+sqtx4252 squareroot 0.0695 -> 0.264  Inexact Rounded
+sqtx4253 squareroot 0.696 -> 0.834  Inexact Rounded
+sqtx4254 squareroot 0.0696 -> 0.264  Inexact Rounded
+sqtx4255 squareroot 0.697 -> 0.835  Inexact Rounded
+sqtx4256 squareroot 0.0697 -> 0.264  Inexact Rounded
+sqtx4257 squareroot 0.698 -> 0.835  Inexact Rounded
+sqtx4258 squareroot 0.0698 -> 0.264  Inexact Rounded
+sqtx4259 squareroot 0.699 -> 0.836  Inexact Rounded
+sqtx4260 squareroot 0.0699 -> 0.264  Inexact Rounded
+sqtx4261 squareroot 0.701 -> 0.837  Inexact Rounded
+sqtx4262 squareroot 0.0701 -> 0.265  Inexact Rounded
+sqtx4263 squareroot 0.702 -> 0.838  Inexact Rounded
+sqtx4264 squareroot 0.0702 -> 0.265  Inexact Rounded
+sqtx4265 squareroot 0.703 -> 0.838  Inexact Rounded
+sqtx4266 squareroot 0.0703 -> 0.265  Inexact Rounded
+sqtx4267 squareroot 0.704 -> 0.839  Inexact Rounded
+sqtx4268 squareroot 0.0704 -> 0.265  Inexact Rounded
+sqtx4269 squareroot 0.705 -> 0.840  Inexact Rounded
+sqtx4270 squareroot 0.0705 -> 0.266  Inexact Rounded
+sqtx4271 squareroot 0.706 -> 0.840  Inexact Rounded
+sqtx4272 squareroot 0.0706 -> 0.266  Inexact Rounded
+sqtx4273 squareroot 0.707 -> 0.841  Inexact Rounded
+sqtx4274 squareroot 0.0707 -> 0.266  Inexact Rounded
+sqtx4275 squareroot 0.708 -> 0.841  Inexact Rounded
+sqtx4276 squareroot 0.0708 -> 0.266  Inexact Rounded
+sqtx4277 squareroot 0.709 -> 0.842  Inexact Rounded
+sqtx4278 squareroot 0.0709 -> 0.266  Inexact Rounded
+sqtx4279 squareroot 0.711 -> 0.843  Inexact Rounded
+sqtx4280 squareroot 0.0711 -> 0.267  Inexact Rounded
+sqtx4281 squareroot 0.712 -> 0.844  Inexact Rounded
+sqtx4282 squareroot 0.0712 -> 0.267  Inexact Rounded
+sqtx4283 squareroot 0.713 -> 0.844  Inexact Rounded
+sqtx4284 squareroot 0.0713 -> 0.267  Inexact Rounded
+sqtx4285 squareroot 0.714 -> 0.845  Inexact Rounded
+sqtx4286 squareroot 0.0714 -> 0.267  Inexact Rounded
+sqtx4287 squareroot 0.715 -> 0.846  Inexact Rounded
+sqtx4288 squareroot 0.0715 -> 0.267  Inexact Rounded
+sqtx4289 squareroot 0.716 -> 0.846  Inexact Rounded
+sqtx4290 squareroot 0.0716 -> 0.268  Inexact Rounded
+sqtx4291 squareroot 0.717 -> 0.847  Inexact Rounded
+sqtx4292 squareroot 0.0717 -> 0.268  Inexact Rounded
+sqtx4293 squareroot 0.718 -> 0.847  Inexact Rounded
+sqtx4294 squareroot 0.0718 -> 0.268  Inexact Rounded
+sqtx4295 squareroot 0.719 -> 0.848  Inexact Rounded
+sqtx4296 squareroot 0.0719 -> 0.268  Inexact Rounded
+sqtx4297 squareroot 0.721 -> 0.849  Inexact Rounded
+sqtx4298 squareroot 0.0721 -> 0.269  Inexact Rounded
+sqtx4299 squareroot 0.722 -> 0.850  Inexact Rounded
+sqtx4300 squareroot 0.0722 -> 0.269  Inexact Rounded
+sqtx4301 squareroot 0.723 -> 0.850  Inexact Rounded
+sqtx4302 squareroot 0.0723 -> 0.269  Inexact Rounded
+sqtx4303 squareroot 0.724 -> 0.851  Inexact Rounded
+sqtx4304 squareroot 0.0724 -> 0.269  Inexact Rounded
+sqtx4305 squareroot 0.725 -> 0.851  Inexact Rounded
+sqtx4306 squareroot 0.0725 -> 0.269  Inexact Rounded
+sqtx4307 squareroot 0.726 -> 0.852  Inexact Rounded
+sqtx4308 squareroot 0.0726 -> 0.269  Inexact Rounded
+sqtx4309 squareroot 0.727 -> 0.853  Inexact Rounded
+sqtx4310 squareroot 0.0727 -> 0.270  Inexact Rounded
+sqtx4311 squareroot 0.728 -> 0.853  Inexact Rounded
+sqtx4312 squareroot 0.0728 -> 0.270  Inexact Rounded
+sqtx4313 squareroot 0.729 -> 0.854  Inexact Rounded
+sqtx4314 squareroot 0.0729 -> 0.27
+sqtx4315 squareroot 0.731 -> 0.855  Inexact Rounded
+sqtx4316 squareroot 0.0731 -> 0.270  Inexact Rounded
+sqtx4317 squareroot 0.732 -> 0.856  Inexact Rounded
+sqtx4318 squareroot 0.0732 -> 0.271  Inexact Rounded
+sqtx4319 squareroot 0.733 -> 0.856  Inexact Rounded
+sqtx4320 squareroot 0.0733 -> 0.271  Inexact Rounded
+sqtx4321 squareroot 0.734 -> 0.857  Inexact Rounded
+sqtx4322 squareroot 0.0734 -> 0.271  Inexact Rounded
+sqtx4323 squareroot 0.735 -> 0.857  Inexact Rounded
+sqtx4324 squareroot 0.0735 -> 0.271  Inexact Rounded
+sqtx4325 squareroot 0.736 -> 0.858  Inexact Rounded
+sqtx4326 squareroot 0.0736 -> 0.271  Inexact Rounded
+sqtx4327 squareroot 0.737 -> 0.858  Inexact Rounded
+sqtx4328 squareroot 0.0737 -> 0.271  Inexact Rounded
+sqtx4329 squareroot 0.738 -> 0.859  Inexact Rounded
+sqtx4330 squareroot 0.0738 -> 0.272  Inexact Rounded
+sqtx4331 squareroot 0.739 -> 0.860  Inexact Rounded
+sqtx4332 squareroot 0.0739 -> 0.272  Inexact Rounded
+sqtx4333 squareroot 0.741 -> 0.861  Inexact Rounded
+sqtx4334 squareroot 0.0741 -> 0.272  Inexact Rounded
+sqtx4335 squareroot 0.742 -> 0.861  Inexact Rounded
+sqtx4336 squareroot 0.0742 -> 0.272  Inexact Rounded
+sqtx4337 squareroot 0.743 -> 0.862  Inexact Rounded
+sqtx4338 squareroot 0.0743 -> 0.273  Inexact Rounded
+sqtx4339 squareroot 0.744 -> 0.863  Inexact Rounded
+sqtx4340 squareroot 0.0744 -> 0.273  Inexact Rounded
+sqtx4341 squareroot 0.745 -> 0.863  Inexact Rounded
+sqtx4342 squareroot 0.0745 -> 0.273  Inexact Rounded
+sqtx4343 squareroot 0.746 -> 0.864  Inexact Rounded
+sqtx4344 squareroot 0.0746 -> 0.273  Inexact Rounded
+sqtx4345 squareroot 0.747 -> 0.864  Inexact Rounded
+sqtx4346 squareroot 0.0747 -> 0.273  Inexact Rounded
+sqtx4347 squareroot 0.748 -> 0.865  Inexact Rounded
+sqtx4348 squareroot 0.0748 -> 0.273  Inexact Rounded
+sqtx4349 squareroot 0.749 -> 0.865  Inexact Rounded
+sqtx4350 squareroot 0.0749 -> 0.274  Inexact Rounded
+sqtx4351 squareroot 0.751 -> 0.867  Inexact Rounded
+sqtx4352 squareroot 0.0751 -> 0.274  Inexact Rounded
+sqtx4353 squareroot 0.752 -> 0.867  Inexact Rounded
+sqtx4354 squareroot 0.0752 -> 0.274  Inexact Rounded
+sqtx4355 squareroot 0.753 -> 0.868  Inexact Rounded
+sqtx4356 squareroot 0.0753 -> 0.274  Inexact Rounded
+sqtx4357 squareroot 0.754 -> 0.868  Inexact Rounded
+sqtx4358 squareroot 0.0754 -> 0.275  Inexact Rounded
+sqtx4359 squareroot 0.755 -> 0.869  Inexact Rounded
+sqtx4360 squareroot 0.0755 -> 0.275  Inexact Rounded
+sqtx4361 squareroot 0.756 -> 0.869  Inexact Rounded
+sqtx4362 squareroot 0.0756 -> 0.275  Inexact Rounded
+sqtx4363 squareroot 0.757 -> 0.870  Inexact Rounded
+sqtx4364 squareroot 0.0757 -> 0.275  Inexact Rounded
+sqtx4365 squareroot 0.758 -> 0.871  Inexact Rounded
+sqtx4366 squareroot 0.0758 -> 0.275  Inexact Rounded
+sqtx4367 squareroot 0.759 -> 0.871  Inexact Rounded
+sqtx4368 squareroot 0.0759 -> 0.275  Inexact Rounded
+sqtx4369 squareroot 0.761 -> 0.872  Inexact Rounded
+sqtx4370 squareroot 0.0761 -> 0.276  Inexact Rounded
+sqtx4371 squareroot 0.762 -> 0.873  Inexact Rounded
+sqtx4372 squareroot 0.0762 -> 0.276  Inexact Rounded
+sqtx4373 squareroot 0.763 -> 0.873  Inexact Rounded
+sqtx4374 squareroot 0.0763 -> 0.276  Inexact Rounded
+sqtx4375 squareroot 0.764 -> 0.874  Inexact Rounded
+sqtx4376 squareroot 0.0764 -> 0.276  Inexact Rounded
+sqtx4377 squareroot 0.765 -> 0.875  Inexact Rounded
+sqtx4378 squareroot 0.0765 -> 0.277  Inexact Rounded
+sqtx4379 squareroot 0.766 -> 0.875  Inexact Rounded
+sqtx4380 squareroot 0.0766 -> 0.277  Inexact Rounded
+sqtx4381 squareroot 0.767 -> 0.876  Inexact Rounded
+sqtx4382 squareroot 0.0767 -> 0.277  Inexact Rounded
+sqtx4383 squareroot 0.768 -> 0.876  Inexact Rounded
+sqtx4384 squareroot 0.0768 -> 0.277  Inexact Rounded
+sqtx4385 squareroot 0.769 -> 0.877  Inexact Rounded
+sqtx4386 squareroot 0.0769 -> 0.277  Inexact Rounded
+sqtx4387 squareroot 0.771 -> 0.878  Inexact Rounded
+sqtx4388 squareroot 0.0771 -> 0.278  Inexact Rounded
+sqtx4389 squareroot 0.772 -> 0.879  Inexact Rounded
+sqtx4390 squareroot 0.0772 -> 0.278  Inexact Rounded
+sqtx4391 squareroot 0.773 -> 0.879  Inexact Rounded
+sqtx4392 squareroot 0.0773 -> 0.278  Inexact Rounded
+sqtx4393 squareroot 0.774 -> 0.880  Inexact Rounded
+sqtx4394 squareroot 0.0774 -> 0.278  Inexact Rounded
+sqtx4395 squareroot 0.775 -> 0.880  Inexact Rounded
+sqtx4396 squareroot 0.0775 -> 0.278  Inexact Rounded
+sqtx4397 squareroot 0.776 -> 0.881  Inexact Rounded
+sqtx4398 squareroot 0.0776 -> 0.279  Inexact Rounded
+sqtx4399 squareroot 0.777 -> 0.881  Inexact Rounded
+sqtx4400 squareroot 0.0777 -> 0.279  Inexact Rounded
+sqtx4401 squareroot 0.778 -> 0.882  Inexact Rounded
+sqtx4402 squareroot 0.0778 -> 0.279  Inexact Rounded
+sqtx4403 squareroot 0.779 -> 0.883  Inexact Rounded
+sqtx4404 squareroot 0.0779 -> 0.279  Inexact Rounded
+sqtx4405 squareroot 0.781 -> 0.884  Inexact Rounded
+sqtx4406 squareroot 0.0781 -> 0.279  Inexact Rounded
+sqtx4407 squareroot 0.782 -> 0.884  Inexact Rounded
+sqtx4408 squareroot 0.0782 -> 0.280  Inexact Rounded
+sqtx4409 squareroot 0.783 -> 0.885  Inexact Rounded
+sqtx4410 squareroot 0.0783 -> 0.280  Inexact Rounded
+sqtx4411 squareroot 0.784 -> 0.885  Inexact Rounded
+sqtx4412 squareroot 0.0784 -> 0.28
+sqtx4413 squareroot 0.785 -> 0.886  Inexact Rounded
+sqtx4414 squareroot 0.0785 -> 0.280  Inexact Rounded
+sqtx4415 squareroot 0.786 -> 0.887  Inexact Rounded
+sqtx4416 squareroot 0.0786 -> 0.280  Inexact Rounded
+sqtx4417 squareroot 0.787 -> 0.887  Inexact Rounded
+sqtx4418 squareroot 0.0787 -> 0.281  Inexact Rounded
+sqtx4419 squareroot 0.788 -> 0.888  Inexact Rounded
+sqtx4420 squareroot 0.0788 -> 0.281  Inexact Rounded
+sqtx4421 squareroot 0.789 -> 0.888  Inexact Rounded
+sqtx4422 squareroot 0.0789 -> 0.281  Inexact Rounded
+sqtx4423 squareroot 0.791 -> 0.889  Inexact Rounded
+sqtx4424 squareroot 0.0791 -> 0.281  Inexact Rounded
+sqtx4425 squareroot 0.792 -> 0.890  Inexact Rounded
+sqtx4426 squareroot 0.0792 -> 0.281  Inexact Rounded
+sqtx4427 squareroot 0.793 -> 0.891  Inexact Rounded
+sqtx4428 squareroot 0.0793 -> 0.282  Inexact Rounded
+sqtx4429 squareroot 0.794 -> 0.891  Inexact Rounded
+sqtx4430 squareroot 0.0794 -> 0.282  Inexact Rounded
+sqtx4431 squareroot 0.795 -> 0.892  Inexact Rounded
+sqtx4432 squareroot 0.0795 -> 0.282  Inexact Rounded
+sqtx4433 squareroot 0.796 -> 0.892  Inexact Rounded
+sqtx4434 squareroot 0.0796 -> 0.282  Inexact Rounded
+sqtx4435 squareroot 0.797 -> 0.893  Inexact Rounded
+sqtx4436 squareroot 0.0797 -> 0.282  Inexact Rounded
+sqtx4437 squareroot 0.798 -> 0.893  Inexact Rounded
+sqtx4438 squareroot 0.0798 -> 0.282  Inexact Rounded
+sqtx4439 squareroot 0.799 -> 0.894  Inexact Rounded
+sqtx4440 squareroot 0.0799 -> 0.283  Inexact Rounded
+sqtx4441 squareroot 0.801 -> 0.895  Inexact Rounded
+sqtx4442 squareroot 0.0801 -> 0.283  Inexact Rounded
+sqtx4443 squareroot 0.802 -> 0.896  Inexact Rounded
+sqtx4444 squareroot 0.0802 -> 0.283  Inexact Rounded
+sqtx4445 squareroot 0.803 -> 0.896  Inexact Rounded
+sqtx4446 squareroot 0.0803 -> 0.283  Inexact Rounded
+sqtx4447 squareroot 0.804 -> 0.897  Inexact Rounded
+sqtx4448 squareroot 0.0804 -> 0.284  Inexact Rounded
+sqtx4449 squareroot 0.805 -> 0.897  Inexact Rounded
+sqtx4450 squareroot 0.0805 -> 0.284  Inexact Rounded
+sqtx4451 squareroot 0.806 -> 0.898  Inexact Rounded
+sqtx4452 squareroot 0.0806 -> 0.284  Inexact Rounded
+sqtx4453 squareroot 0.807 -> 0.898  Inexact Rounded
+sqtx4454 squareroot 0.0807 -> 0.284  Inexact Rounded
+sqtx4455 squareroot 0.808 -> 0.899  Inexact Rounded
+sqtx4456 squareroot 0.0808 -> 0.284  Inexact Rounded
+sqtx4457 squareroot 0.809 -> 0.899  Inexact Rounded
+sqtx4458 squareroot 0.0809 -> 0.284  Inexact Rounded
+sqtx4459 squareroot 0.811 -> 0.901  Inexact Rounded
+sqtx4460 squareroot 0.0811 -> 0.285  Inexact Rounded
+sqtx4461 squareroot 0.812 -> 0.901  Inexact Rounded
+sqtx4462 squareroot 0.0812 -> 0.285  Inexact Rounded
+sqtx4463 squareroot 0.813 -> 0.902  Inexact Rounded
+sqtx4464 squareroot 0.0813 -> 0.285  Inexact Rounded
+sqtx4465 squareroot 0.814 -> 0.902  Inexact Rounded
+sqtx4466 squareroot 0.0814 -> 0.285  Inexact Rounded
+sqtx4467 squareroot 0.815 -> 0.903  Inexact Rounded
+sqtx4468 squareroot 0.0815 -> 0.285  Inexact Rounded
+sqtx4469 squareroot 0.816 -> 0.903  Inexact Rounded
+sqtx4470 squareroot 0.0816 -> 0.286  Inexact Rounded
+sqtx4471 squareroot 0.817 -> 0.904  Inexact Rounded
+sqtx4472 squareroot 0.0817 -> 0.286  Inexact Rounded
+sqtx4473 squareroot 0.818 -> 0.904  Inexact Rounded
+sqtx4474 squareroot 0.0818 -> 0.286  Inexact Rounded
+sqtx4475 squareroot 0.819 -> 0.905  Inexact Rounded
+sqtx4476 squareroot 0.0819 -> 0.286  Inexact Rounded
+sqtx4477 squareroot 0.821 -> 0.906  Inexact Rounded
+sqtx4478 squareroot 0.0821 -> 0.287  Inexact Rounded
+sqtx4479 squareroot 0.822 -> 0.907  Inexact Rounded
+sqtx4480 squareroot 0.0822 -> 0.287  Inexact Rounded
+sqtx4481 squareroot 0.823 -> 0.907  Inexact Rounded
+sqtx4482 squareroot 0.0823 -> 0.287  Inexact Rounded
+sqtx4483 squareroot 0.824 -> 0.908  Inexact Rounded
+sqtx4484 squareroot 0.0824 -> 0.287  Inexact Rounded
+sqtx4485 squareroot 0.825 -> 0.908  Inexact Rounded
+sqtx4486 squareroot 0.0825 -> 0.287  Inexact Rounded
+sqtx4487 squareroot 0.826 -> 0.909  Inexact Rounded
+sqtx4488 squareroot 0.0826 -> 0.287  Inexact Rounded
+sqtx4489 squareroot 0.827 -> 0.909  Inexact Rounded
+sqtx4490 squareroot 0.0827 -> 0.288  Inexact Rounded
+sqtx4491 squareroot 0.828 -> 0.910  Inexact Rounded
+sqtx4492 squareroot 0.0828 -> 0.288  Inexact Rounded
+sqtx4493 squareroot 0.829 -> 0.910  Inexact Rounded
+sqtx4494 squareroot 0.0829 -> 0.288  Inexact Rounded
+sqtx4495 squareroot 0.831 -> 0.912  Inexact Rounded
+sqtx4496 squareroot 0.0831 -> 0.288  Inexact Rounded
+sqtx4497 squareroot 0.832 -> 0.912  Inexact Rounded
+sqtx4498 squareroot 0.0832 -> 0.288  Inexact Rounded
+sqtx4499 squareroot 0.833 -> 0.913  Inexact Rounded
+sqtx4500 squareroot 0.0833 -> 0.289  Inexact Rounded
+sqtx4501 squareroot 0.834 -> 0.913  Inexact Rounded
+sqtx4502 squareroot 0.0834 -> 0.289  Inexact Rounded
+sqtx4503 squareroot 0.835 -> 0.914  Inexact Rounded
+sqtx4504 squareroot 0.0835 -> 0.289  Inexact Rounded
+sqtx4505 squareroot 0.836 -> 0.914  Inexact Rounded
+sqtx4506 squareroot 0.0836 -> 0.289  Inexact Rounded
+sqtx4507 squareroot 0.837 -> 0.915  Inexact Rounded
+sqtx4508 squareroot 0.0837 -> 0.289  Inexact Rounded
+sqtx4509 squareroot 0.838 -> 0.915  Inexact Rounded
+sqtx4510 squareroot 0.0838 -> 0.289  Inexact Rounded
+sqtx4511 squareroot 0.839 -> 0.916  Inexact Rounded
+sqtx4512 squareroot 0.0839 -> 0.290  Inexact Rounded
+sqtx4513 squareroot 0.841 -> 0.917  Inexact Rounded
+sqtx4514 squareroot 0.0841 -> 0.29
+sqtx4515 squareroot 0.842 -> 0.918  Inexact Rounded
+sqtx4516 squareroot 0.0842 -> 0.290  Inexact Rounded
+sqtx4517 squareroot 0.843 -> 0.918  Inexact Rounded
+sqtx4518 squareroot 0.0843 -> 0.290  Inexact Rounded
+sqtx4519 squareroot 0.844 -> 0.919  Inexact Rounded
+sqtx4520 squareroot 0.0844 -> 0.291  Inexact Rounded
+sqtx4521 squareroot 0.845 -> 0.919  Inexact Rounded
+sqtx4522 squareroot 0.0845 -> 0.291  Inexact Rounded
+sqtx4523 squareroot 0.846 -> 0.920  Inexact Rounded
+sqtx4524 squareroot 0.0846 -> 0.291  Inexact Rounded
+sqtx4525 squareroot 0.847 -> 0.920  Inexact Rounded
+sqtx4526 squareroot 0.0847 -> 0.291  Inexact Rounded
+sqtx4527 squareroot 0.848 -> 0.921  Inexact Rounded
+sqtx4528 squareroot 0.0848 -> 0.291  Inexact Rounded
+sqtx4529 squareroot 0.849 -> 0.921  Inexact Rounded
+sqtx4530 squareroot 0.0849 -> 0.291  Inexact Rounded
+sqtx4531 squareroot 0.851 -> 0.922  Inexact Rounded
+sqtx4532 squareroot 0.0851 -> 0.292  Inexact Rounded
+sqtx4533 squareroot 0.852 -> 0.923  Inexact Rounded
+sqtx4534 squareroot 0.0852 -> 0.292  Inexact Rounded
+sqtx4535 squareroot 0.853 -> 0.924  Inexact Rounded
+sqtx4536 squareroot 0.0853 -> 0.292  Inexact Rounded
+sqtx4537 squareroot 0.854 -> 0.924  Inexact Rounded
+sqtx4538 squareroot 0.0854 -> 0.292  Inexact Rounded
+sqtx4539 squareroot 0.855 -> 0.925  Inexact Rounded
+sqtx4540 squareroot 0.0855 -> 0.292  Inexact Rounded
+sqtx4541 squareroot 0.856 -> 0.925  Inexact Rounded
+sqtx4542 squareroot 0.0856 -> 0.293  Inexact Rounded
+sqtx4543 squareroot 0.857 -> 0.926  Inexact Rounded
+sqtx4544 squareroot 0.0857 -> 0.293  Inexact Rounded
+sqtx4545 squareroot 0.858 -> 0.926  Inexact Rounded
+sqtx4546 squareroot 0.0858 -> 0.293  Inexact Rounded
+sqtx4547 squareroot 0.859 -> 0.927  Inexact Rounded
+sqtx4548 squareroot 0.0859 -> 0.293  Inexact Rounded
+sqtx4549 squareroot 0.861 -> 0.928  Inexact Rounded
+sqtx4550 squareroot 0.0861 -> 0.293  Inexact Rounded
+sqtx4551 squareroot 0.862 -> 0.928  Inexact Rounded
+sqtx4552 squareroot 0.0862 -> 0.294  Inexact Rounded
+sqtx4553 squareroot 0.863 -> 0.929  Inexact Rounded
+sqtx4554 squareroot 0.0863 -> 0.294  Inexact Rounded
+sqtx4555 squareroot 0.864 -> 0.930  Inexact Rounded
+sqtx4556 squareroot 0.0864 -> 0.294  Inexact Rounded
+sqtx4557 squareroot 0.865 -> 0.930  Inexact Rounded
+sqtx4558 squareroot 0.0865 -> 0.294  Inexact Rounded
+sqtx4559 squareroot 0.866 -> 0.931  Inexact Rounded
+sqtx4560 squareroot 0.0866 -> 0.294  Inexact Rounded
+sqtx4561 squareroot 0.867 -> 0.931  Inexact Rounded
+sqtx4562 squareroot 0.0867 -> 0.294  Inexact Rounded
+sqtx4563 squareroot 0.868 -> 0.932  Inexact Rounded
+sqtx4564 squareroot 0.0868 -> 0.295  Inexact Rounded
+sqtx4565 squareroot 0.869 -> 0.932  Inexact Rounded
+sqtx4566 squareroot 0.0869 -> 0.295  Inexact Rounded
+sqtx4567 squareroot 0.871 -> 0.933  Inexact Rounded
+sqtx4568 squareroot 0.0871 -> 0.295  Inexact Rounded
+sqtx4569 squareroot 0.872 -> 0.934  Inexact Rounded
+sqtx4570 squareroot 0.0872 -> 0.295  Inexact Rounded
+sqtx4571 squareroot 0.873 -> 0.934  Inexact Rounded
+sqtx4572 squareroot 0.0873 -> 0.295  Inexact Rounded
+sqtx4573 squareroot 0.874 -> 0.935  Inexact Rounded
+sqtx4574 squareroot 0.0874 -> 0.296  Inexact Rounded
+sqtx4575 squareroot 0.875 -> 0.935  Inexact Rounded
+sqtx4576 squareroot 0.0875 -> 0.296  Inexact Rounded
+sqtx4577 squareroot 0.876 -> 0.936  Inexact Rounded
+sqtx4578 squareroot 0.0876 -> 0.296  Inexact Rounded
+sqtx4579 squareroot 0.877 -> 0.936  Inexact Rounded
+sqtx4580 squareroot 0.0877 -> 0.296  Inexact Rounded
+sqtx4581 squareroot 0.878 -> 0.937  Inexact Rounded
+sqtx4582 squareroot 0.0878 -> 0.296  Inexact Rounded
+sqtx4583 squareroot 0.879 -> 0.938  Inexact Rounded
+sqtx4584 squareroot 0.0879 -> 0.296  Inexact Rounded
+sqtx4585 squareroot 0.881 -> 0.939  Inexact Rounded
+sqtx4586 squareroot 0.0881 -> 0.297  Inexact Rounded
+sqtx4587 squareroot 0.882 -> 0.939  Inexact Rounded
+sqtx4588 squareroot 0.0882 -> 0.297  Inexact Rounded
+sqtx4589 squareroot 0.883 -> 0.940  Inexact Rounded
+sqtx4590 squareroot 0.0883 -> 0.297  Inexact Rounded
+sqtx4591 squareroot 0.884 -> 0.940  Inexact Rounded
+sqtx4592 squareroot 0.0884 -> 0.297  Inexact Rounded
+sqtx4593 squareroot 0.885 -> 0.941  Inexact Rounded
+sqtx4594 squareroot 0.0885 -> 0.297  Inexact Rounded
+sqtx4595 squareroot 0.886 -> 0.941  Inexact Rounded
+sqtx4596 squareroot 0.0886 -> 0.298  Inexact Rounded
+sqtx4597 squareroot 0.887 -> 0.942  Inexact Rounded
+sqtx4598 squareroot 0.0887 -> 0.298  Inexact Rounded
+sqtx4599 squareroot 0.888 -> 0.942  Inexact Rounded
+sqtx4600 squareroot 0.0888 -> 0.298  Inexact Rounded
+sqtx4601 squareroot 0.889 -> 0.943  Inexact Rounded
+sqtx4602 squareroot 0.0889 -> 0.298  Inexact Rounded
+sqtx4603 squareroot 0.891 -> 0.944  Inexact Rounded
+sqtx4604 squareroot 0.0891 -> 0.298  Inexact Rounded
+sqtx4605 squareroot 0.892 -> 0.944  Inexact Rounded
+sqtx4606 squareroot 0.0892 -> 0.299  Inexact Rounded
+sqtx4607 squareroot 0.893 -> 0.945  Inexact Rounded
+sqtx4608 squareroot 0.0893 -> 0.299  Inexact Rounded
+sqtx4609 squareroot 0.894 -> 0.946  Inexact Rounded
+sqtx4610 squareroot 0.0894 -> 0.299  Inexact Rounded
+sqtx4611 squareroot 0.895 -> 0.946  Inexact Rounded
+sqtx4612 squareroot 0.0895 -> 0.299  Inexact Rounded
+sqtx4613 squareroot 0.896 -> 0.947  Inexact Rounded
+sqtx4614 squareroot 0.0896 -> 0.299  Inexact Rounded
+sqtx4615 squareroot 0.897 -> 0.947  Inexact Rounded
+sqtx4616 squareroot 0.0897 -> 0.299  Inexact Rounded
+sqtx4617 squareroot 0.898 -> 0.948  Inexact Rounded
+sqtx4618 squareroot 0.0898 -> 0.300  Inexact Rounded
+sqtx4619 squareroot 0.899 -> 0.948  Inexact Rounded
+sqtx4620 squareroot 0.0899 -> 0.300  Inexact Rounded
+sqtx4621 squareroot 0.901 -> 0.949  Inexact Rounded
+sqtx4622 squareroot 0.0901 -> 0.300  Inexact Rounded
+sqtx4623 squareroot 0.902 -> 0.950  Inexact Rounded
+sqtx4624 squareroot 0.0902 -> 0.300  Inexact Rounded
+sqtx4625 squareroot 0.903 -> 0.950  Inexact Rounded
+sqtx4626 squareroot 0.0903 -> 0.300  Inexact Rounded
+sqtx4627 squareroot 0.904 -> 0.951  Inexact Rounded
+sqtx4628 squareroot 0.0904 -> 0.301  Inexact Rounded
+sqtx4629 squareroot 0.905 -> 0.951  Inexact Rounded
+sqtx4630 squareroot 0.0905 -> 0.301  Inexact Rounded
+sqtx4631 squareroot 0.906 -> 0.952  Inexact Rounded
+sqtx4632 squareroot 0.0906 -> 0.301  Inexact Rounded
+sqtx4633 squareroot 0.907 -> 0.952  Inexact Rounded
+sqtx4634 squareroot 0.0907 -> 0.301  Inexact Rounded
+sqtx4635 squareroot 0.908 -> 0.953  Inexact Rounded
+sqtx4636 squareroot 0.0908 -> 0.301  Inexact Rounded
+sqtx4637 squareroot 0.909 -> 0.953  Inexact Rounded
+sqtx4638 squareroot 0.0909 -> 0.301  Inexact Rounded
+sqtx4639 squareroot 0.911 -> 0.954  Inexact Rounded
+sqtx4640 squareroot 0.0911 -> 0.302  Inexact Rounded
+sqtx4641 squareroot 0.912 -> 0.955  Inexact Rounded
+sqtx4642 squareroot 0.0912 -> 0.302  Inexact Rounded
+sqtx4643 squareroot 0.913 -> 0.956  Inexact Rounded
+sqtx4644 squareroot 0.0913 -> 0.302  Inexact Rounded
+sqtx4645 squareroot 0.914 -> 0.956  Inexact Rounded
+sqtx4646 squareroot 0.0914 -> 0.302  Inexact Rounded
+sqtx4647 squareroot 0.915 -> 0.957  Inexact Rounded
+sqtx4648 squareroot 0.0915 -> 0.302  Inexact Rounded
+sqtx4649 squareroot 0.916 -> 0.957  Inexact Rounded
+sqtx4650 squareroot 0.0916 -> 0.303  Inexact Rounded
+sqtx4651 squareroot 0.917 -> 0.958  Inexact Rounded
+sqtx4652 squareroot 0.0917 -> 0.303  Inexact Rounded
+sqtx4653 squareroot 0.918 -> 0.958  Inexact Rounded
+sqtx4654 squareroot 0.0918 -> 0.303  Inexact Rounded
+sqtx4655 squareroot 0.919 -> 0.959  Inexact Rounded
+sqtx4656 squareroot 0.0919 -> 0.303  Inexact Rounded
+sqtx4657 squareroot 0.921 -> 0.960  Inexact Rounded
+sqtx4658 squareroot 0.0921 -> 0.303  Inexact Rounded
+sqtx4659 squareroot 0.922 -> 0.960  Inexact Rounded
+sqtx4660 squareroot 0.0922 -> 0.304  Inexact Rounded
+sqtx4661 squareroot 0.923 -> 0.961  Inexact Rounded
+sqtx4662 squareroot 0.0923 -> 0.304  Inexact Rounded
+sqtx4663 squareroot 0.924 -> 0.961  Inexact Rounded
+sqtx4664 squareroot 0.0924 -> 0.304  Inexact Rounded
+sqtx4665 squareroot 0.925 -> 0.962  Inexact Rounded
+sqtx4666 squareroot 0.0925 -> 0.304  Inexact Rounded
+sqtx4667 squareroot 0.926 -> 0.962  Inexact Rounded
+sqtx4668 squareroot 0.0926 -> 0.304  Inexact Rounded
+sqtx4669 squareroot 0.927 -> 0.963  Inexact Rounded
+sqtx4670 squareroot 0.0927 -> 0.304  Inexact Rounded
+sqtx4671 squareroot 0.928 -> 0.963  Inexact Rounded
+sqtx4672 squareroot 0.0928 -> 0.305  Inexact Rounded
+sqtx4673 squareroot 0.929 -> 0.964  Inexact Rounded
+sqtx4674 squareroot 0.0929 -> 0.305  Inexact Rounded
+sqtx4675 squareroot 0.931 -> 0.965  Inexact Rounded
+sqtx4676 squareroot 0.0931 -> 0.305  Inexact Rounded
+sqtx4677 squareroot 0.932 -> 0.965  Inexact Rounded
+sqtx4678 squareroot 0.0932 -> 0.305  Inexact Rounded
+sqtx4679 squareroot 0.933 -> 0.966  Inexact Rounded
+sqtx4680 squareroot 0.0933 -> 0.305  Inexact Rounded
+sqtx4681 squareroot 0.934 -> 0.966  Inexact Rounded
+sqtx4682 squareroot 0.0934 -> 0.306  Inexact Rounded
+sqtx4683 squareroot 0.935 -> 0.967  Inexact Rounded
+sqtx4684 squareroot 0.0935 -> 0.306  Inexact Rounded
+sqtx4685 squareroot 0.936 -> 0.967  Inexact Rounded
+sqtx4686 squareroot 0.0936 -> 0.306  Inexact Rounded
+sqtx4687 squareroot 0.937 -> 0.968  Inexact Rounded
+sqtx4688 squareroot 0.0937 -> 0.306  Inexact Rounded
+sqtx4689 squareroot 0.938 -> 0.969  Inexact Rounded
+sqtx4690 squareroot 0.0938 -> 0.306  Inexact Rounded
+sqtx4691 squareroot 0.939 -> 0.969  Inexact Rounded
+sqtx4692 squareroot 0.0939 -> 0.306  Inexact Rounded
+sqtx4693 squareroot 0.941 -> 0.970  Inexact Rounded
+sqtx4694 squareroot 0.0941 -> 0.307  Inexact Rounded
+sqtx4695 squareroot 0.942 -> 0.971  Inexact Rounded
+sqtx4696 squareroot 0.0942 -> 0.307  Inexact Rounded
+sqtx4697 squareroot 0.943 -> 0.971  Inexact Rounded
+sqtx4698 squareroot 0.0943 -> 0.307  Inexact Rounded
+sqtx4699 squareroot 0.944 -> 0.972  Inexact Rounded
+sqtx4700 squareroot 0.0944 -> 0.307  Inexact Rounded
+sqtx4701 squareroot 0.945 -> 0.972  Inexact Rounded
+sqtx4702 squareroot 0.0945 -> 0.307  Inexact Rounded
+sqtx4703 squareroot 0.946 -> 0.973  Inexact Rounded
+sqtx4704 squareroot 0.0946 -> 0.308  Inexact Rounded
+sqtx4705 squareroot 0.947 -> 0.973  Inexact Rounded
+sqtx4706 squareroot 0.0947 -> 0.308  Inexact Rounded
+sqtx4707 squareroot 0.948 -> 0.974  Inexact Rounded
+sqtx4708 squareroot 0.0948 -> 0.308  Inexact Rounded
+sqtx4709 squareroot 0.949 -> 0.974  Inexact Rounded
+sqtx4710 squareroot 0.0949 -> 0.308  Inexact Rounded
+sqtx4711 squareroot 0.951 -> 0.975  Inexact Rounded
+sqtx4712 squareroot 0.0951 -> 0.308  Inexact Rounded
+sqtx4713 squareroot 0.952 -> 0.976  Inexact Rounded
+sqtx4714 squareroot 0.0952 -> 0.309  Inexact Rounded
+sqtx4715 squareroot 0.953 -> 0.976  Inexact Rounded
+sqtx4716 squareroot 0.0953 -> 0.309  Inexact Rounded
+sqtx4717 squareroot 0.954 -> 0.977  Inexact Rounded
+sqtx4718 squareroot 0.0954 -> 0.309  Inexact Rounded
+sqtx4719 squareroot 0.955 -> 0.977  Inexact Rounded
+sqtx4720 squareroot 0.0955 -> 0.309  Inexact Rounded
+sqtx4721 squareroot 0.956 -> 0.978  Inexact Rounded
+sqtx4722 squareroot 0.0956 -> 0.309  Inexact Rounded
+sqtx4723 squareroot 0.957 -> 0.978  Inexact Rounded
+sqtx4724 squareroot 0.0957 -> 0.309  Inexact Rounded
+sqtx4725 squareroot 0.958 -> 0.979  Inexact Rounded
+sqtx4726 squareroot 0.0958 -> 0.310  Inexact Rounded
+sqtx4727 squareroot 0.959 -> 0.979  Inexact Rounded
+sqtx4728 squareroot 0.0959 -> 0.310  Inexact Rounded
+sqtx4729 squareroot 0.961 -> 0.980  Inexact Rounded
+sqtx4730 squareroot 0.0961 -> 0.31
+sqtx4731 squareroot 0.962 -> 0.981  Inexact Rounded
+sqtx4732 squareroot 0.0962 -> 0.310  Inexact Rounded
+sqtx4733 squareroot 0.963 -> 0.981  Inexact Rounded
+sqtx4734 squareroot 0.0963 -> 0.310  Inexact Rounded
+sqtx4735 squareroot 0.964 -> 0.982  Inexact Rounded
+sqtx4736 squareroot 0.0964 -> 0.310  Inexact Rounded
+sqtx4737 squareroot 0.965 -> 0.982  Inexact Rounded
+sqtx4738 squareroot 0.0965 -> 0.311  Inexact Rounded
+sqtx4739 squareroot 0.966 -> 0.983  Inexact Rounded
+sqtx4740 squareroot 0.0966 -> 0.311  Inexact Rounded
+sqtx4741 squareroot 0.967 -> 0.983  Inexact Rounded
+sqtx4742 squareroot 0.0967 -> 0.311  Inexact Rounded
+sqtx4743 squareroot 0.968 -> 0.984  Inexact Rounded
+sqtx4744 squareroot 0.0968 -> 0.311  Inexact Rounded
+sqtx4745 squareroot 0.969 -> 0.984  Inexact Rounded
+sqtx4746 squareroot 0.0969 -> 0.311  Inexact Rounded
+sqtx4747 squareroot 0.971 -> 0.985  Inexact Rounded
+sqtx4748 squareroot 0.0971 -> 0.312  Inexact Rounded
+sqtx4749 squareroot 0.972 -> 0.986  Inexact Rounded
+sqtx4750 squareroot 0.0972 -> 0.312  Inexact Rounded
+sqtx4751 squareroot 0.973 -> 0.986  Inexact Rounded
+sqtx4752 squareroot 0.0973 -> 0.312  Inexact Rounded
+sqtx4753 squareroot 0.974 -> 0.987  Inexact Rounded
+sqtx4754 squareroot 0.0974 -> 0.312  Inexact Rounded
+sqtx4755 squareroot 0.975 -> 0.987  Inexact Rounded
+sqtx4756 squareroot 0.0975 -> 0.312  Inexact Rounded
+sqtx4757 squareroot 0.976 -> 0.988  Inexact Rounded
+sqtx4758 squareroot 0.0976 -> 0.312  Inexact Rounded
+sqtx4759 squareroot 0.977 -> 0.988  Inexact Rounded
+sqtx4760 squareroot 0.0977 -> 0.313  Inexact Rounded
+sqtx4761 squareroot 0.978 -> 0.989  Inexact Rounded
+sqtx4762 squareroot 0.0978 -> 0.313  Inexact Rounded
+sqtx4763 squareroot 0.979 -> 0.989  Inexact Rounded
+sqtx4764 squareroot 0.0979 -> 0.313  Inexact Rounded
+sqtx4765 squareroot 0.981 -> 0.990  Inexact Rounded
+sqtx4766 squareroot 0.0981 -> 0.313  Inexact Rounded
+sqtx4767 squareroot 0.982 -> 0.991  Inexact Rounded
+sqtx4768 squareroot 0.0982 -> 0.313  Inexact Rounded
+sqtx4769 squareroot 0.983 -> 0.991  Inexact Rounded
+sqtx4770 squareroot 0.0983 -> 0.314  Inexact Rounded
+sqtx4771 squareroot 0.984 -> 0.992  Inexact Rounded
+sqtx4772 squareroot 0.0984 -> 0.314  Inexact Rounded
+sqtx4773 squareroot 0.985 -> 0.992  Inexact Rounded
+sqtx4774 squareroot 0.0985 -> 0.314  Inexact Rounded
+sqtx4775 squareroot 0.986 -> 0.993  Inexact Rounded
+sqtx4776 squareroot 0.0986 -> 0.314  Inexact Rounded
+sqtx4777 squareroot 0.987 -> 0.993  Inexact Rounded
+sqtx4778 squareroot 0.0987 -> 0.314  Inexact Rounded
+sqtx4779 squareroot 0.988 -> 0.994  Inexact Rounded
+sqtx4780 squareroot 0.0988 -> 0.314  Inexact Rounded
+sqtx4781 squareroot 0.989 -> 0.994  Inexact Rounded
+sqtx4782 squareroot 0.0989 -> 0.314  Inexact Rounded
+sqtx4783 squareroot 0.991 -> 0.995  Inexact Rounded
+sqtx4784 squareroot 0.0991 -> 0.315  Inexact Rounded
+sqtx4785 squareroot 0.992 -> 0.996  Inexact Rounded
+sqtx4786 squareroot 0.0992 -> 0.315  Inexact Rounded
+sqtx4787 squareroot 0.993 -> 0.996  Inexact Rounded
+sqtx4788 squareroot 0.0993 -> 0.315  Inexact Rounded
+sqtx4789 squareroot 0.994 -> 0.997  Inexact Rounded
+sqtx4790 squareroot 0.0994 -> 0.315  Inexact Rounded
+sqtx4791 squareroot 0.995 -> 0.997  Inexact Rounded
+sqtx4792 squareroot 0.0995 -> 0.315  Inexact Rounded
+sqtx4793 squareroot 0.996 -> 0.998  Inexact Rounded
+sqtx4794 squareroot 0.0996 -> 0.316  Inexact Rounded
+sqtx4795 squareroot 0.997 -> 0.998  Inexact Rounded
+sqtx4796 squareroot 0.0997 -> 0.316  Inexact Rounded
+sqtx4797 squareroot 0.998 -> 0.999  Inexact Rounded
+sqtx4798 squareroot 0.0998 -> 0.316  Inexact Rounded
+sqtx4799 squareroot 0.999 -> 0.999  Inexact Rounded
+sqtx4800 squareroot 0.0999 -> 0.316  Inexact Rounded
+
+-- A group of precision 4 tests where Hull & Abrham adjustments are
+-- needed in some cases (both up and down) [see Hull1985b]
+rounding:    half_even
+maxExponent: 999
+minexponent: -999
+precision:   4
+sqtx5001 squareroot 0.0118  -> 0.1086  Inexact Rounded
+sqtx5002 squareroot 0.119   -> 0.3450  Inexact Rounded
+sqtx5003 squareroot 0.0119  -> 0.1091  Inexact Rounded
+sqtx5004 squareroot 0.121   -> 0.3479  Inexact Rounded
+sqtx5005 squareroot 0.0121  -> 0.11
+sqtx5006 squareroot 0.122   -> 0.3493  Inexact Rounded
+sqtx5007 squareroot 0.0122  -> 0.1105  Inexact Rounded
+sqtx5008 squareroot 0.123   -> 0.3507  Inexact Rounded
+sqtx5009 squareroot 0.494   -> 0.7029  Inexact Rounded
+sqtx5010 squareroot 0.0669  -> 0.2587  Inexact Rounded
+sqtx5011 squareroot 0.9558  -> 0.9777  Inexact Rounded
+sqtx5012 squareroot 0.9348  -> 0.9669  Inexact Rounded
+sqtx5013 squareroot 0.9345  -> 0.9667  Inexact Rounded
+sqtx5014 squareroot 0.09345 -> 0.3057  Inexact Rounded
+sqtx5015 squareroot 0.9346  -> 0.9667  Inexact Rounded
+sqtx5016 squareroot 0.09346 -> 0.3057  Inexact Rounded
+sqtx5017 squareroot 0.9347  -> 0.9668  Inexact Rounded
+
+-- examples from decArith
+precision: 9
+sqtx700 squareroot  0       -> '0'
+sqtx701 squareroot  -0      -> '-0'
+sqtx702 squareroot  0.39    -> 0.624499800    Inexact Rounded
+sqtx703 squareroot  100     -> '10'
+sqtx704 squareroot  1.00    -> '1.0'
+sqtx705 squareroot  7       -> '2.64575131'   Inexact Rounded
+sqtx706 squareroot  10      -> 3.16227766     Inexact Rounded
+
+-- some one-offs
+precision: 9
+sqtx711 squareroot  0.1     -> 0.316227766    Inexact Rounded
+sqtx712 squareroot  0.2     -> 0.447213595    Inexact Rounded
+sqtx713 squareroot  0.3     -> 0.547722558    Inexact Rounded
+sqtx714 squareroot  0.4     -> 0.632455532    Inexact Rounded
+sqtx715 squareroot  0.5     -> 0.707106781    Inexact Rounded
+sqtx716 squareroot  0.6     -> 0.774596669    Inexact Rounded
+sqtx717 squareroot  0.7     -> 0.836660027    Inexact Rounded
+sqtx718 squareroot  0.8     -> 0.894427191    Inexact Rounded
+sqtx719 squareroot  0.9     -> 0.948683298    Inexact Rounded
+precision: 10               -- note no normalizatoin here
+sqtx720 squareroot +0.1     -> 0.3162277660   Inexact Rounded
+precision: 11
+sqtx721 squareroot +0.1     -> 0.31622776602  Inexact Rounded
+precision: 12
+sqtx722 squareroot +0.1     -> 0.316227766017 Inexact Rounded
+precision: 9
+sqtx723 squareroot  0.39    -> 0.624499800    Inexact Rounded
+precision: 15
+sqtx724 squareroot  0.39    -> 0.624499799839840 Inexact Rounded
+
+-- discussion cases
+precision: 7
+sqtx731 squareroot     9   ->   3
+sqtx732 squareroot   100   ->  10
+sqtx733 squareroot   123   ->  11.09054  Inexact Rounded
+sqtx734 squareroot   144   ->  12
+sqtx735 squareroot   156   ->  12.49000  Inexact Rounded
+sqtx736 squareroot 10000   -> 100
+
+-- values close to overflow (if there were input rounding)
+maxexponent: 99
+minexponent: -99
+precision: 5
+sqtx760 squareroot  9.9997E+99   -> 9.9998E+49 Inexact Rounded
+sqtx761 squareroot  9.9998E+99   -> 9.9999E+49 Inexact Rounded
+sqtx762 squareroot  9.9999E+99   -> 9.9999E+49 Inexact Rounded
+sqtx763 squareroot  9.99991E+99  -> 1.0000E+50 Inexact Rounded
+sqtx764 squareroot  9.99994E+99  -> 1.0000E+50 Inexact Rounded
+sqtx765 squareroot  9.99995E+99  -> 1.0000E+50 Inexact Rounded
+sqtx766 squareroot  9.99999E+99  -> 1.0000E+50 Inexact Rounded
+precision: 9
+sqtx770 squareroot  9.9997E+99   -> 9.99985000E+49  Inexact Rounded
+sqtx771 squareroot  9.9998E+99   -> 9.99990000E+49  Inexact Rounded
+sqtx772 squareroot  9.9999E+99   -> 9.99995000E+49  Inexact Rounded
+sqtx773 squareroot  9.99991E+99  -> 9.99995500E+49  Inexact Rounded
+sqtx774 squareroot  9.99994E+99  -> 9.99997000E+49  Inexact Rounded
+sqtx775 squareroot  9.99995E+99  -> 9.99997500E+49  Inexact Rounded
+sqtx776 squareroot  9.99999E+99  -> 9.99999500E+49  Inexact Rounded
+precision: 20
+sqtx780 squareroot  9.9997E+99   -> '9.9998499988749831247E+49' Inexact Rounded
+sqtx781 squareroot  9.9998E+99   -> '9.9998999994999949999E+49' Inexact Rounded
+sqtx782 squareroot  9.9999E+99   -> '9.9999499998749993750E+49' Inexact Rounded
+sqtx783 squareroot  9.99991E+99  -> '9.9999549998987495444E+49' Inexact Rounded
+sqtx784 squareroot  9.99994E+99  -> '9.9999699999549998650E+49' Inexact Rounded
+sqtx785 squareroot  9.99995E+99  -> '9.9999749999687499219E+49' Inexact Rounded
+sqtx786 squareroot  9.99999E+99  -> '9.9999949999987499994E+49' Inexact Rounded
+
+-- subnormals and underflows [these can only result when eMax is < digits+1]
+-- Etiny = -(Emax + (precision-1))
+-- start with subnormal operands and normal results
+maxexponent: 9
+minexponent: -9
+precision: 9                -- Etiny=-17
+sqtx800 squareroot  1E-17   -> 3.16227766E-9 Inexact Rounded
+sqtx801 squareroot 10E-17   -> 1.0E-8
+precision: 10               -- Etiny=-18
+sqtx802 squareroot 10E-18   -> 3.162277660E-9 Inexact Rounded
+sqtx803 squareroot  1E-18   -> 1E-9
+
+precision: 11               -- Etiny=-19
+sqtx804 squareroot  1E-19   -> 3.162277660E-10 Underflow Subnormal Inexact Rounded
+sqtx805 squareroot 10E-19   -> 1.0E-9
+precision: 12               -- Etiny=-20
+sqtx806 squareroot 10E-20   -> 3.1622776602E-10 Underflow Subnormal Inexact Rounded
+sqtx807 squareroot  1E-20   -> 1E-10 Subnormal   -- Exact Subnormal case
+
+precision: 13               -- Etiny=-21
+sqtx808 squareroot  1E-21   -> 3.1622776602E-11 Underflow Subnormal Inexact Rounded
+sqtx809 squareroot 10E-21   -> 1.0E-10 Subnormal
+precision: 14               -- Etiny=-22
+sqtx810 squareroot  1E-21   -> 3.16227766017E-11 Underflow Subnormal Inexact Rounded
+sqtx811 squareroot 10E-22   -> 3.16227766017E-11 Underflow Subnormal Inexact Rounded
+sqtx812 squareroot  1E-22   -> 1E-11 Subnormal   -- Exact Subnormal case
+
+
+-- special values
+maxexponent: 999
+minexponent: -999
+sqtx820 squareroot   Inf    -> Infinity
+sqtx821 squareroot  -Inf    -> NaN Invalid_operation
+sqtx822 squareroot   NaN    -> NaN
+sqtx823 squareroot  sNaN    -> NaN Invalid_operation
+-- propagating NaNs
+sqtx824 squareroot  sNaN123 ->  NaN123 Invalid_operation
+sqtx825 squareroot -sNaN321 -> -NaN321 Invalid_operation
+sqtx826 squareroot   NaN456 ->  NaN456
+sqtx827 squareroot  -NaN654 -> -NaN654
+sqtx828 squareroot   NaN1   ->  NaN1
+
+-- Null test
+sqtx900 squareroot  # -> NaN Invalid_operation

Added: vendor/Python/current/Lib/test/decimaltestdata/subtract.decTest
===================================================================
--- vendor/Python/current/Lib/test/decimaltestdata/subtract.decTest	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/decimaltestdata/subtract.decTest	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,863 @@
+------------------------------------------------------------------------
+-- subtract.decTest -- decimal subtraction                            --
+-- Copyright (c) IBM Corporation, 1981, 2004.  All rights reserved.   --
+------------------------------------------------------------------------
+-- Please see the document "General Decimal Arithmetic Testcases"     --
+-- at http://www2.hursley.ibm.com/decimal for the description of      --
+-- these testcases.                                                   --
+--                                                                    --
+-- These testcases are experimental ('beta' versions), and they       --
+-- may contain errors.  They are offered on an as-is basis.  In       --
+-- particular, achieving the same results as the tests here is not    --
+-- a guarantee that an implementation complies with any Standard      --
+-- or specification.  The tests are not exhaustive.                   --
+--                                                                    --
+-- Please send comments, suggestions, and corrections to the author:  --
+--   Mike Cowlishaw, IBM Fellow                                       --
+--   IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK         --
+--   mfc at uk.ibm.com                                                   --
+------------------------------------------------------------------------
+version: 2.39
+
+extended:    1
+precision:   9
+rounding:    half_up
+maxExponent: 384
+minexponent: -383
+
+-- [first group are 'quick confidence check']
+subx001 subtract  0   0  -> '0'
+subx002 subtract  1   1  -> '0'
+subx003 subtract  1   2  -> '-1'
+subx004 subtract  2   1  -> '1'
+subx005 subtract  2   2  -> '0'
+subx006 subtract  3   2  -> '1'
+subx007 subtract  2   3  -> '-1'
+
+subx011 subtract -0   0  -> '-0'
+subx012 subtract -1   1  -> '-2'
+subx013 subtract -1   2  -> '-3'
+subx014 subtract -2   1  -> '-3'
+subx015 subtract -2   2  -> '-4'
+subx016 subtract -3   2  -> '-5'
+subx017 subtract -2   3  -> '-5'
+
+subx021 subtract  0  -0  -> '0'
+subx022 subtract  1  -1  -> '2'
+subx023 subtract  1  -2  -> '3'
+subx024 subtract  2  -1  -> '3'
+subx025 subtract  2  -2  -> '4'
+subx026 subtract  3  -2  -> '5'
+subx027 subtract  2  -3  -> '5'
+
+subx030 subtract  11  1  -> 10
+subx031 subtract  10  1  ->  9
+subx032 subtract  9   1  ->  8
+subx033 subtract  1   1  ->  0
+subx034 subtract  0   1  -> -1
+subx035 subtract -1   1  -> -2
+subx036 subtract -9   1  -> -10
+subx037 subtract -10  1  -> -11
+subx038 subtract -11  1  -> -12
+
+subx040 subtract '5.75' '3.3'  -> '2.45'
+subx041 subtract '5'    '-3'   -> '8'
+subx042 subtract '-5'   '-3'   -> '-2'
+subx043 subtract '-7'   '2.5'  -> '-9.5'
+subx044 subtract '0.7'  '0.3'  -> '0.4'
+subx045 subtract '1.3'  '0.3'  -> '1.0'
+subx046 subtract '1.25' '1.25' -> '0.00'
+
+subx050 subtract '1.23456789'    '1.00000000' -> '0.23456789'
+subx051 subtract '1.23456789'    '1.00000089' -> '0.23456700'
+subx052 subtract '0.5555555559'    '0.0000000001' -> '0.555555556' Inexact Rounded
+subx053 subtract '0.5555555559'    '0.0000000005' -> '0.555555555' Inexact Rounded
+subx054 subtract '0.4444444444'    '0.1111111111' -> '0.333333333' Inexact Rounded
+subx055 subtract '1.0000000000'    '0.00000001' -> '0.999999990' Rounded
+subx056 subtract '0.4444444444999'    '0' -> '0.444444444' Inexact Rounded
+subx057 subtract '0.4444444445000'    '0' -> '0.444444445' Inexact Rounded
+
+subx060 subtract '70'    '10000e+9' -> '-1.00000000E+13' Inexact Rounded
+subx061 subtract '700'    '10000e+9' -> '-1.00000000E+13' Inexact Rounded
+subx062 subtract '7000'    '10000e+9' -> '-9.99999999E+12' Inexact Rounded
+subx063 subtract '70000'    '10000e+9' -> '-9.99999993E+12' Rounded
+subx064 subtract '700000'    '10000e+9' -> '-9.99999930E+12' Rounded
+  -- symmetry:
+subx065 subtract '10000e+9'    '70' -> '1.00000000E+13' Inexact Rounded
+subx066 subtract '10000e+9'    '700' -> '1.00000000E+13' Inexact Rounded
+subx067 subtract '10000e+9'    '7000' -> '9.99999999E+12' Inexact Rounded
+subx068 subtract '10000e+9'    '70000' -> '9.99999993E+12' Rounded
+subx069 subtract '10000e+9'    '700000' -> '9.99999930E+12' Rounded
+
+  -- change precision
+subx080 subtract '10000e+9'    '70000' -> '9.99999993E+12' Rounded
+precision: 6
+subx081 subtract '10000e+9'    '70000' -> '1.00000E+13' Inexact Rounded
+precision: 9
+
+  -- some of the next group are really constructor tests
+subx090 subtract '00.0'    '0.0'  -> '0.0'
+subx091 subtract '00.0'    '0.00' -> '0.00'
+subx092 subtract '0.00'    '00.0' -> '0.00'
+subx093 subtract '00.0'    '0.00' -> '0.00'
+subx094 subtract '0.00'    '00.0' -> '0.00'
+subx095 subtract '3'    '.3'   -> '2.7'
+subx096 subtract '3.'   '.3'   -> '2.7'
+subx097 subtract '3.0'  '.3'   -> '2.7'
+subx098 subtract '3.00' '.3'   -> '2.70'
+subx099 subtract '3'    '3'    -> '0'
+subx100 subtract '3'    '+3'   -> '0'
+subx101 subtract '3'    '-3'   -> '6'
+subx102 subtract '3'    '0.3'  -> '2.7'
+subx103 subtract '3.'   '0.3'  -> '2.7'
+subx104 subtract '3.0'  '0.3'  -> '2.7'
+subx105 subtract '3.00' '0.3'  -> '2.70'
+subx106 subtract '3'    '3.0'  -> '0.0'
+subx107 subtract '3'    '+3.0' -> '0.0'
+subx108 subtract '3'    '-3.0' -> '6.0'
+
+-- the above all from add; massaged and extended.  Now some new ones...
+-- [particularly important for comparisons]
+-- NB: -xE-8 below were non-exponents pre-ANSI X3-274, and -1E-7 or 0E-7
+-- with input rounding.
+subx120 subtract  '10.23456784'    '10.23456789'  -> '-5E-8'
+subx121 subtract  '10.23456785'    '10.23456789'  -> '-4E-8'
+subx122 subtract  '10.23456786'    '10.23456789'  -> '-3E-8'
+subx123 subtract  '10.23456787'    '10.23456789'  -> '-2E-8'
+subx124 subtract  '10.23456788'    '10.23456789'  -> '-1E-8'
+subx125 subtract  '10.23456789'    '10.23456789'  -> '0E-8'
+subx126 subtract  '10.23456790'    '10.23456789'  -> '1E-8'
+subx127 subtract  '10.23456791'    '10.23456789'  -> '2E-8'
+subx128 subtract  '10.23456792'    '10.23456789'  -> '3E-8'
+subx129 subtract  '10.23456793'    '10.23456789'  -> '4E-8'
+subx130 subtract  '10.23456794'    '10.23456789'  -> '5E-8'
+subx131 subtract  '10.23456781'    '10.23456786'  -> '-5E-8'
+subx132 subtract  '10.23456782'    '10.23456786'  -> '-4E-8'
+subx133 subtract  '10.23456783'    '10.23456786'  -> '-3E-8'
+subx134 subtract  '10.23456784'    '10.23456786'  -> '-2E-8'
+subx135 subtract  '10.23456785'    '10.23456786'  -> '-1E-8'
+subx136 subtract  '10.23456786'    '10.23456786'  -> '0E-8'
+subx137 subtract  '10.23456787'    '10.23456786'  -> '1E-8'
+subx138 subtract  '10.23456788'    '10.23456786'  -> '2E-8'
+subx139 subtract  '10.23456789'    '10.23456786'  -> '3E-8'
+subx140 subtract  '10.23456790'    '10.23456786'  -> '4E-8'
+subx141 subtract  '10.23456791'    '10.23456786'  -> '5E-8'
+subx142 subtract  '1'              '0.999999999'  -> '1E-9'
+subx143 subtract  '0.999999999'    '1'            -> '-1E-9'
+subx144 subtract  '-10.23456780'   '-10.23456786' -> '6E-8'
+subx145 subtract  '-10.23456790'   '-10.23456786' -> '-4E-8'
+subx146 subtract  '-10.23456791'   '-10.23456786' -> '-5E-8'
+
+precision: 3
+subx150 subtract '12345678900000' '9999999999999'  -> 2.35E+12 Inexact Rounded
+subx151 subtract '9999999999999'  '12345678900000' -> -2.35E+12 Inexact Rounded
+precision: 6
+subx152 subtract '12345678900000' '9999999999999'  -> 2.34568E+12 Inexact Rounded
+subx153 subtract '9999999999999'  '12345678900000' -> -2.34568E+12 Inexact Rounded
+precision: 9
+subx154 subtract '12345678900000' '9999999999999'  -> 2.34567890E+12 Inexact Rounded
+subx155 subtract '9999999999999'  '12345678900000' -> -2.34567890E+12 Inexact Rounded
+precision: 12
+subx156 subtract '12345678900000' '9999999999999'  -> 2.34567890000E+12 Inexact Rounded
+subx157 subtract '9999999999999'  '12345678900000' -> -2.34567890000E+12 Inexact Rounded
+precision: 15
+subx158 subtract '12345678900000' '9999999999999'  -> 2345678900001
+subx159 subtract '9999999999999'  '12345678900000' -> -2345678900001
+precision: 9
+
+-- additional scaled arithmetic tests [0.97 problem]
+subx160 subtract '0'     '.1'      -> '-0.1'
+subx161 subtract '00'    '.97983'  -> '-0.97983'
+subx162 subtract '0'     '.9'      -> '-0.9'
+subx163 subtract '0'     '0.102'   -> '-0.102'
+subx164 subtract '0'     '.4'      -> '-0.4'
+subx165 subtract '0'     '.307'    -> '-0.307'
+subx166 subtract '0'     '.43822'  -> '-0.43822'
+subx167 subtract '0'     '.911'    -> '-0.911'
+subx168 subtract '.0'    '.02'     -> '-0.02'
+subx169 subtract '00'    '.392'    -> '-0.392'
+subx170 subtract '0'     '.26'     -> '-0.26'
+subx171 subtract '0'     '0.51'    -> '-0.51'
+subx172 subtract '0'     '.2234'   -> '-0.2234'
+subx173 subtract '0'     '.2'      -> '-0.2'
+subx174 subtract '.0'    '.0008'   -> '-0.0008'
+-- 0. on left
+subx180 subtract '0.0'     '-.1'      -> '0.1'
+subx181 subtract '0.00'    '-.97983'  -> '0.97983'
+subx182 subtract '0.0'     '-.9'      -> '0.9'
+subx183 subtract '0.0'     '-0.102'   -> '0.102'
+subx184 subtract '0.0'     '-.4'      -> '0.4'
+subx185 subtract '0.0'     '-.307'    -> '0.307'
+subx186 subtract '0.0'     '-.43822'  -> '0.43822'
+subx187 subtract '0.0'     '-.911'    -> '0.911'
+subx188 subtract '0.0'     '-.02'     -> '0.02'
+subx189 subtract '0.00'    '-.392'    -> '0.392'
+subx190 subtract '0.0'     '-.26'     -> '0.26'
+subx191 subtract '0.0'     '-0.51'    -> '0.51'
+subx192 subtract '0.0'     '-.2234'   -> '0.2234'
+subx193 subtract '0.0'     '-.2'      -> '0.2'
+subx194 subtract '0.0'     '-.0008'   -> '0.0008'
+-- negatives of same
+subx200 subtract '0'     '-.1'      -> '0.1'
+subx201 subtract '00'    '-.97983'  -> '0.97983'
+subx202 subtract '0'     '-.9'      -> '0.9'
+subx203 subtract '0'     '-0.102'   -> '0.102'
+subx204 subtract '0'     '-.4'      -> '0.4'
+subx205 subtract '0'     '-.307'    -> '0.307'
+subx206 subtract '0'     '-.43822'  -> '0.43822'
+subx207 subtract '0'     '-.911'    -> '0.911'
+subx208 subtract '.0'    '-.02'     -> '0.02'
+subx209 subtract '00'    '-.392'    -> '0.392'
+subx210 subtract '0'     '-.26'     -> '0.26'
+subx211 subtract '0'     '-0.51'    -> '0.51'
+subx212 subtract '0'     '-.2234'   -> '0.2234'
+subx213 subtract '0'     '-.2'      -> '0.2'
+subx214 subtract '.0'    '-.0008'   -> '0.0008'
+
+-- more fixed, LHS swaps [really the same as testcases under add]
+subx220 subtract '-56267E-12' 0  -> '-5.6267E-8'
+subx221 subtract '-56267E-11' 0  -> '-5.6267E-7'
+subx222 subtract '-56267E-10' 0  -> '-0.0000056267'
+subx223 subtract '-56267E-9'  0  -> '-0.000056267'
+subx224 subtract '-56267E-8'  0  -> '-0.00056267'
+subx225 subtract '-56267E-7'  0  -> '-0.0056267'
+subx226 subtract '-56267E-6'  0  -> '-0.056267'
+subx227 subtract '-56267E-5'  0  -> '-0.56267'
+subx228 subtract '-56267E-2'  0  -> '-562.67'
+subx229 subtract '-56267E-1'  0  -> '-5626.7'
+subx230 subtract '-56267E-0'  0  -> '-56267'
+-- symmetry ...
+subx240 subtract 0 '-56267E-12'  -> '5.6267E-8'
+subx241 subtract 0 '-56267E-11'  -> '5.6267E-7'
+subx242 subtract 0 '-56267E-10'  -> '0.0000056267'
+subx243 subtract 0 '-56267E-9'   -> '0.000056267'
+subx244 subtract 0 '-56267E-8'   -> '0.00056267'
+subx245 subtract 0 '-56267E-7'   -> '0.0056267'
+subx246 subtract 0 '-56267E-6'   -> '0.056267'
+subx247 subtract 0 '-56267E-5'   -> '0.56267'
+subx248 subtract 0 '-56267E-2'   -> '562.67'
+subx249 subtract 0 '-56267E-1'   -> '5626.7'
+subx250 subtract 0 '-56267E-0'   -> '56267'
+
+-- now some more from the 'new' add
+precision: 9
+subx301 subtract '1.23456789'  '1.00000000' -> '0.23456789'
+subx302 subtract '1.23456789'  '1.00000011' -> '0.23456778'
+
+subx311 subtract '0.4444444444'  '0.5555555555' -> '-0.111111111' Inexact Rounded
+subx312 subtract '0.4444444440'  '0.5555555555' -> '-0.111111112' Inexact Rounded
+subx313 subtract '0.4444444444'  '0.5555555550' -> '-0.111111111' Inexact Rounded
+subx314 subtract '0.44444444449'    '0' -> '0.444444444' Inexact Rounded
+subx315 subtract '0.444444444499'   '0' -> '0.444444444' Inexact Rounded
+subx316 subtract '0.4444444444999'  '0' -> '0.444444444' Inexact Rounded
+subx317 subtract '0.4444444445000'  '0' -> '0.444444445' Inexact Rounded
+subx318 subtract '0.4444444445001'  '0' -> '0.444444445' Inexact Rounded
+subx319 subtract '0.444444444501'   '0' -> '0.444444445' Inexact Rounded
+subx320 subtract '0.44444444451'    '0' -> '0.444444445' Inexact Rounded
+
+-- some carrying effects
+subx321 subtract '0.9998'  '0.0000' -> '0.9998'
+subx322 subtract '0.9998'  '0.0001' -> '0.9997'
+subx323 subtract '0.9998'  '0.0002' -> '0.9996'
+subx324 subtract '0.9998'  '0.0003' -> '0.9995'
+subx325 subtract '0.9998'  '-0.0000' -> '0.9998'
+subx326 subtract '0.9998'  '-0.0001' -> '0.9999'
+subx327 subtract '0.9998'  '-0.0002' -> '1.0000'
+subx328 subtract '0.9998'  '-0.0003' -> '1.0001'
+
+subx330 subtract '70'  '10000e+9' -> '-1.00000000E+13' Inexact Rounded
+subx331 subtract '700'  '10000e+9' -> '-1.00000000E+13' Inexact Rounded
+subx332 subtract '7000'  '10000e+9' -> '-9.99999999E+12' Inexact Rounded
+subx333 subtract '70000'  '10000e+9' -> '-9.99999993E+12' Rounded
+subx334 subtract '700000'  '10000e+9' -> '-9.99999930E+12' Rounded
+subx335 subtract '7000000'  '10000e+9' -> '-9.99999300E+12' Rounded
+-- symmetry:
+subx340 subtract '10000e+9'  '70' -> '1.00000000E+13' Inexact Rounded
+subx341 subtract '10000e+9'  '700' -> '1.00000000E+13' Inexact Rounded
+subx342 subtract '10000e+9'  '7000' -> '9.99999999E+12' Inexact Rounded
+subx343 subtract '10000e+9'  '70000' -> '9.99999993E+12' Rounded
+subx344 subtract '10000e+9'  '700000' -> '9.99999930E+12' Rounded
+subx345 subtract '10000e+9'  '7000000' -> '9.99999300E+12' Rounded
+
+-- same, higher precision
+precision: 15
+subx346 subtract '10000e+9'  '7'   -> '9999999999993'
+subx347 subtract '10000e+9'  '70'   -> '9999999999930'
+subx348 subtract '10000e+9'  '700'   -> '9999999999300'
+subx349 subtract '10000e+9'  '7000'   -> '9999999993000'
+subx350 subtract '10000e+9'  '70000'   -> '9999999930000'
+subx351 subtract '10000e+9'  '700000'   -> '9999999300000'
+subx352 subtract '7' '10000e+9'   -> '-9999999999993'
+subx353 subtract '70' '10000e+9'   -> '-9999999999930'
+subx354 subtract '700' '10000e+9'   -> '-9999999999300'
+subx355 subtract '7000' '10000e+9'   -> '-9999999993000'
+subx356 subtract '70000' '10000e+9'   -> '-9999999930000'
+subx357 subtract '700000' '10000e+9'   -> '-9999999300000'
+
+-- zero preservation
+precision: 6
+subx360 subtract '10000e+9'  '70000' -> '1.00000E+13' Inexact Rounded
+subx361 subtract 1 '0.0001' -> '0.9999'
+subx362 subtract 1 '0.00001' -> '0.99999'
+subx363 subtract 1 '0.000001' -> '0.999999'
+subx364 subtract 1 '0.0000001' -> '1.00000' Inexact Rounded
+subx365 subtract 1 '0.00000001' -> '1.00000' Inexact Rounded
+
+-- some funny zeros [in case of bad signum]
+subx370 subtract 1  0  -> 1
+subx371 subtract 1 0.  -> 1
+subx372 subtract 1  .0 -> 1.0
+subx373 subtract 1 0.0 -> 1.0
+subx374 subtract  0  1 -> -1
+subx375 subtract 0.  1 -> -1
+subx376 subtract  .0 1 -> -1.0
+subx377 subtract 0.0 1 -> -1.0
+
+precision: 9
+
+-- leading 0 digit before round
+subx910 subtract -103519362 -51897955.3 -> -51621406.7
+subx911 subtract 159579.444 89827.5229 -> 69751.9211
+
+subx920 subtract 333.123456 33.1234566 -> 299.999999 Inexact Rounded
+subx921 subtract 333.123456 33.1234565 -> 300.000000 Inexact Rounded
+subx922 subtract 133.123456 33.1234565 ->  99.9999995
+subx923 subtract 133.123456 33.1234564 ->  99.9999996
+subx924 subtract 133.123456 33.1234540 -> 100.000002 Rounded
+subx925 subtract 133.123456 43.1234560 ->  90.0000000
+subx926 subtract 133.123456 43.1234561 ->  89.9999999
+subx927 subtract 133.123456 43.1234566 ->  89.9999994
+subx928 subtract 101.123456 91.1234566 ->   9.9999994
+subx929 subtract 101.123456 99.1234566 ->   1.9999994
+
+-- more of the same; probe for cluster boundary problems
+precision: 1
+subx930 subtract  11 2           -> 9
+precision: 2
+subx932 subtract 101 2           -> 99
+precision: 3
+subx934 subtract 101 2.1         -> 98.9
+subx935 subtract 101 92.01       ->  8.99
+precision: 4
+subx936 subtract 101 2.01        -> 98.99
+subx937 subtract 101 92.01       ->  8.99
+subx938 subtract 101 92.006      ->  8.994
+precision: 5
+subx939 subtract 101 2.001       -> 98.999
+subx940 subtract 101 92.001      ->  8.999
+subx941 subtract 101 92.0006     ->  8.9994
+precision: 6
+subx942 subtract 101 2.0001      -> 98.9999
+subx943 subtract 101 92.0001     ->  8.9999
+subx944 subtract 101 92.00006    ->  8.99994
+precision: 7
+subx945 subtract 101 2.00001     -> 98.99999
+subx946 subtract 101 92.00001    ->  8.99999
+subx947 subtract 101 92.000006   ->  8.999994
+precision: 8
+subx948 subtract 101 2.000001    -> 98.999999
+subx949 subtract 101 92.000001   ->  8.999999
+subx950 subtract 101 92.0000006  ->  8.9999994
+precision: 9
+subx951 subtract 101 2.0000001   -> 98.9999999
+subx952 subtract 101 92.0000001  ->  8.9999999
+subx953 subtract 101 92.00000006 ->  8.99999994
+
+precision: 9
+
+-- more LHS swaps [were fixed]
+subx390 subtract '-56267E-10'   0 ->  '-0.0000056267'
+subx391 subtract '-56267E-6'    0 ->  '-0.056267'
+subx392 subtract '-56267E-5'    0 ->  '-0.56267'
+subx393 subtract '-56267E-4'    0 ->  '-5.6267'
+subx394 subtract '-56267E-3'    0 ->  '-56.267'
+subx395 subtract '-56267E-2'    0 ->  '-562.67'
+subx396 subtract '-56267E-1'    0 ->  '-5626.7'
+subx397 subtract '-56267E-0'    0 ->  '-56267'
+subx398 subtract '-5E-10'       0 ->  '-5E-10'
+subx399 subtract '-5E-7'        0 ->  '-5E-7'
+subx400 subtract '-5E-6'        0 ->  '-0.000005'
+subx401 subtract '-5E-5'        0 ->  '-0.00005'
+subx402 subtract '-5E-4'        0 ->  '-0.0005'
+subx403 subtract '-5E-1'        0 ->  '-0.5'
+subx404 subtract '-5E0'         0 ->  '-5'
+subx405 subtract '-5E1'         0 ->  '-50'
+subx406 subtract '-5E5'         0 ->  '-500000'
+subx407 subtract '-5E8'         0 ->  '-500000000'
+subx408 subtract '-5E9'         0 ->  '-5.00000000E+9'   Rounded
+subx409 subtract '-5E10'        0 ->  '-5.00000000E+10'  Rounded
+subx410 subtract '-5E11'        0 ->  '-5.00000000E+11'  Rounded
+subx411 subtract '-5E100'       0 ->  '-5.00000000E+100' Rounded
+
+-- more RHS swaps [were fixed]
+subx420 subtract 0  '-56267E-10' ->  '0.0000056267'
+subx421 subtract 0  '-56267E-6'  ->  '0.056267'
+subx422 subtract 0  '-56267E-5'  ->  '0.56267'
+subx423 subtract 0  '-56267E-4'  ->  '5.6267'
+subx424 subtract 0  '-56267E-3'  ->  '56.267'
+subx425 subtract 0  '-56267E-2'  ->  '562.67'
+subx426 subtract 0  '-56267E-1'  ->  '5626.7'
+subx427 subtract 0  '-56267E-0'  ->  '56267'
+subx428 subtract 0  '-5E-10'     ->  '5E-10'
+subx429 subtract 0  '-5E-7'      ->  '5E-7'
+subx430 subtract 0  '-5E-6'      ->  '0.000005'
+subx431 subtract 0  '-5E-5'      ->  '0.00005'
+subx432 subtract 0  '-5E-4'      ->  '0.0005'
+subx433 subtract 0  '-5E-1'      ->  '0.5'
+subx434 subtract 0  '-5E0'       ->  '5'
+subx435 subtract 0  '-5E1'       ->  '50'
+subx436 subtract 0  '-5E5'       ->  '500000'
+subx437 subtract 0  '-5E8'       ->  '500000000'
+subx438 subtract 0  '-5E9'       ->  '5.00000000E+9'    Rounded
+subx439 subtract 0  '-5E10'      ->  '5.00000000E+10'   Rounded
+subx440 subtract 0  '-5E11'      ->  '5.00000000E+11'   Rounded
+subx441 subtract 0  '-5E100'     ->  '5.00000000E+100'  Rounded
+
+
+-- try borderline precision, with carries, etc.
+precision: 15
+subx461 subtract '1E+12' '1'       -> '999999999999'
+subx462 subtract '1E+12' '-1.11'   -> '1000000000001.11'
+subx463 subtract '1.11'  '-1E+12'  -> '1000000000001.11'
+subx464 subtract '-1'    '-1E+12'  -> '999999999999'
+subx465 subtract '7E+12' '1'       -> '6999999999999'
+subx466 subtract '7E+12' '-1.11'   -> '7000000000001.11'
+subx467 subtract '1.11'  '-7E+12'  -> '7000000000001.11'
+subx468 subtract '-1'    '-7E+12'  -> '6999999999999'
+
+--                 123456789012345       123456789012345      1 23456789012345
+subx470 subtract '0.444444444444444'  '-0.555555555555563' -> '1.00000000000001' Inexact Rounded
+subx471 subtract '0.444444444444444'  '-0.555555555555562' -> '1.00000000000001' Inexact Rounded
+subx472 subtract '0.444444444444444'  '-0.555555555555561' -> '1.00000000000001' Inexact Rounded
+subx473 subtract '0.444444444444444'  '-0.555555555555560' -> '1.00000000000000' Inexact Rounded
+subx474 subtract '0.444444444444444'  '-0.555555555555559' -> '1.00000000000000' Inexact Rounded
+subx475 subtract '0.444444444444444'  '-0.555555555555558' -> '1.00000000000000' Inexact Rounded
+subx476 subtract '0.444444444444444'  '-0.555555555555557' -> '1.00000000000000' Inexact Rounded
+subx477 subtract '0.444444444444444'  '-0.555555555555556' -> '1.00000000000000' Rounded
+subx478 subtract '0.444444444444444'  '-0.555555555555555' -> '0.999999999999999'
+subx479 subtract '0.444444444444444'  '-0.555555555555554' -> '0.999999999999998'
+subx480 subtract '0.444444444444444'  '-0.555555555555553' -> '0.999999999999997'
+subx481 subtract '0.444444444444444'  '-0.555555555555552' -> '0.999999999999996'
+subx482 subtract '0.444444444444444'  '-0.555555555555551' -> '0.999999999999995'
+subx483 subtract '0.444444444444444'  '-0.555555555555550' -> '0.999999999999994'
+
+-- and some more, including residue effects and different roundings
+precision: 9
+rounding: half_up
+subx500 subtract '123456789' 0             -> '123456789'
+subx501 subtract '123456789' 0.000000001   -> '123456789' Inexact Rounded
+subx502 subtract '123456789' 0.000001      -> '123456789' Inexact Rounded
+subx503 subtract '123456789' 0.1           -> '123456789' Inexact Rounded
+subx504 subtract '123456789' 0.4           -> '123456789' Inexact Rounded
+subx505 subtract '123456789' 0.49          -> '123456789' Inexact Rounded
+subx506 subtract '123456789' 0.499999      -> '123456789' Inexact Rounded
+subx507 subtract '123456789' 0.499999999   -> '123456789' Inexact Rounded
+subx508 subtract '123456789' 0.5           -> '123456789' Inexact Rounded
+subx509 subtract '123456789' 0.500000001   -> '123456788' Inexact Rounded
+subx510 subtract '123456789' 0.500001      -> '123456788' Inexact Rounded
+subx511 subtract '123456789' 0.51          -> '123456788' Inexact Rounded
+subx512 subtract '123456789' 0.6           -> '123456788' Inexact Rounded
+subx513 subtract '123456789' 0.9           -> '123456788' Inexact Rounded
+subx514 subtract '123456789' 0.99999       -> '123456788' Inexact Rounded
+subx515 subtract '123456789' 0.999999999   -> '123456788' Inexact Rounded
+subx516 subtract '123456789' 1             -> '123456788'
+subx517 subtract '123456789' 1.000000001   -> '123456788' Inexact Rounded
+subx518 subtract '123456789' 1.00001       -> '123456788' Inexact Rounded
+subx519 subtract '123456789' 1.1           -> '123456788' Inexact Rounded
+
+rounding: half_even
+subx520 subtract '123456789' 0             -> '123456789'
+subx521 subtract '123456789' 0.000000001   -> '123456789' Inexact Rounded
+subx522 subtract '123456789' 0.000001      -> '123456789' Inexact Rounded
+subx523 subtract '123456789' 0.1           -> '123456789' Inexact Rounded
+subx524 subtract '123456789' 0.4           -> '123456789' Inexact Rounded
+subx525 subtract '123456789' 0.49          -> '123456789' Inexact Rounded
+subx526 subtract '123456789' 0.499999      -> '123456789' Inexact Rounded
+subx527 subtract '123456789' 0.499999999   -> '123456789' Inexact Rounded
+subx528 subtract '123456789' 0.5           -> '123456788' Inexact Rounded
+subx529 subtract '123456789' 0.500000001   -> '123456788' Inexact Rounded
+subx530 subtract '123456789' 0.500001      -> '123456788' Inexact Rounded
+subx531 subtract '123456789' 0.51          -> '123456788' Inexact Rounded
+subx532 subtract '123456789' 0.6           -> '123456788' Inexact Rounded
+subx533 subtract '123456789' 0.9           -> '123456788' Inexact Rounded
+subx534 subtract '123456789' 0.99999       -> '123456788' Inexact Rounded
+subx535 subtract '123456789' 0.999999999   -> '123456788' Inexact Rounded
+subx536 subtract '123456789' 1             -> '123456788'
+subx537 subtract '123456789' 1.00000001    -> '123456788' Inexact Rounded
+subx538 subtract '123456789' 1.00001       -> '123456788' Inexact Rounded
+subx539 subtract '123456789' 1.1           -> '123456788' Inexact Rounded
+-- critical few with even bottom digit...
+subx540 subtract '123456788' 0.499999999   -> '123456788' Inexact Rounded
+subx541 subtract '123456788' 0.5           -> '123456788' Inexact Rounded
+subx542 subtract '123456788' 0.500000001   -> '123456787' Inexact Rounded
+
+rounding: down
+subx550 subtract '123456789' 0             -> '123456789'
+subx551 subtract '123456789' 0.000000001   -> '123456788' Inexact Rounded
+subx552 subtract '123456789' 0.000001      -> '123456788' Inexact Rounded
+subx553 subtract '123456789' 0.1           -> '123456788' Inexact Rounded
+subx554 subtract '123456789' 0.4           -> '123456788' Inexact Rounded
+subx555 subtract '123456789' 0.49          -> '123456788' Inexact Rounded
+subx556 subtract '123456789' 0.499999      -> '123456788' Inexact Rounded
+subx557 subtract '123456789' 0.499999999   -> '123456788' Inexact Rounded
+subx558 subtract '123456789' 0.5           -> '123456788' Inexact Rounded
+subx559 subtract '123456789' 0.500000001   -> '123456788' Inexact Rounded
+subx560 subtract '123456789' 0.500001      -> '123456788' Inexact Rounded
+subx561 subtract '123456789' 0.51          -> '123456788' Inexact Rounded
+subx562 subtract '123456789' 0.6           -> '123456788' Inexact Rounded
+subx563 subtract '123456789' 0.9           -> '123456788' Inexact Rounded
+subx564 subtract '123456789' 0.99999       -> '123456788' Inexact Rounded
+subx565 subtract '123456789' 0.999999999   -> '123456788' Inexact Rounded
+subx566 subtract '123456789' 1             -> '123456788'
+subx567 subtract '123456789' 1.00000001    -> '123456787' Inexact Rounded
+subx568 subtract '123456789' 1.00001       -> '123456787' Inexact Rounded
+subx569 subtract '123456789' 1.1           -> '123456787' Inexact Rounded
+
+-- symmetry...
+rounding: half_up
+subx600 subtract 0             '123456789' -> '-123456789'
+subx601 subtract 0.000000001   '123456789' -> '-123456789' Inexact Rounded
+subx602 subtract 0.000001      '123456789' -> '-123456789' Inexact Rounded
+subx603 subtract 0.1           '123456789' -> '-123456789' Inexact Rounded
+subx604 subtract 0.4           '123456789' -> '-123456789' Inexact Rounded
+subx605 subtract 0.49          '123456789' -> '-123456789' Inexact Rounded
+subx606 subtract 0.499999      '123456789' -> '-123456789' Inexact Rounded
+subx607 subtract 0.499999999   '123456789' -> '-123456789' Inexact Rounded
+subx608 subtract 0.5           '123456789' -> '-123456789' Inexact Rounded
+subx609 subtract 0.500000001   '123456789' -> '-123456788' Inexact Rounded
+subx610 subtract 0.500001      '123456789' -> '-123456788' Inexact Rounded
+subx611 subtract 0.51          '123456789' -> '-123456788' Inexact Rounded
+subx612 subtract 0.6           '123456789' -> '-123456788' Inexact Rounded
+subx613 subtract 0.9           '123456789' -> '-123456788' Inexact Rounded
+subx614 subtract 0.99999       '123456789' -> '-123456788' Inexact Rounded
+subx615 subtract 0.999999999   '123456789' -> '-123456788' Inexact Rounded
+subx616 subtract 1             '123456789' -> '-123456788'
+subx617 subtract 1.000000001   '123456789' -> '-123456788' Inexact Rounded
+subx618 subtract 1.00001       '123456789' -> '-123456788' Inexact Rounded
+subx619 subtract 1.1           '123456789' -> '-123456788' Inexact Rounded
+
+rounding: half_even
+subx620 subtract 0             '123456789' -> '-123456789'
+subx621 subtract 0.000000001   '123456789' -> '-123456789' Inexact Rounded
+subx622 subtract 0.000001      '123456789' -> '-123456789' Inexact Rounded
+subx623 subtract 0.1           '123456789' -> '-123456789' Inexact Rounded
+subx624 subtract 0.4           '123456789' -> '-123456789' Inexact Rounded
+subx625 subtract 0.49          '123456789' -> '-123456789' Inexact Rounded
+subx626 subtract 0.499999      '123456789' -> '-123456789' Inexact Rounded
+subx627 subtract 0.499999999   '123456789' -> '-123456789' Inexact Rounded
+subx628 subtract 0.5           '123456789' -> '-123456788' Inexact Rounded
+subx629 subtract 0.500000001   '123456789' -> '-123456788' Inexact Rounded
+subx630 subtract 0.500001      '123456789' -> '-123456788' Inexact Rounded
+subx631 subtract 0.51          '123456789' -> '-123456788' Inexact Rounded
+subx632 subtract 0.6           '123456789' -> '-123456788' Inexact Rounded
+subx633 subtract 0.9           '123456789' -> '-123456788' Inexact Rounded
+subx634 subtract 0.99999       '123456789' -> '-123456788' Inexact Rounded
+subx635 subtract 0.999999999   '123456789' -> '-123456788' Inexact Rounded
+subx636 subtract 1             '123456789' -> '-123456788'
+subx637 subtract 1.00000001    '123456789' -> '-123456788' Inexact Rounded
+subx638 subtract 1.00001       '123456789' -> '-123456788' Inexact Rounded
+subx639 subtract 1.1           '123456789' -> '-123456788' Inexact Rounded
+-- critical few with even bottom digit...
+subx640 subtract 0.499999999   '123456788' -> '-123456788' Inexact Rounded
+subx641 subtract 0.5           '123456788' -> '-123456788' Inexact Rounded
+subx642 subtract 0.500000001   '123456788' -> '-123456787' Inexact Rounded
+
+rounding: down
+subx650 subtract 0             '123456789' -> '-123456789'
+subx651 subtract 0.000000001   '123456789' -> '-123456788' Inexact Rounded
+subx652 subtract 0.000001      '123456789' -> '-123456788' Inexact Rounded
+subx653 subtract 0.1           '123456789' -> '-123456788' Inexact Rounded
+subx654 subtract 0.4           '123456789' -> '-123456788' Inexact Rounded
+subx655 subtract 0.49          '123456789' -> '-123456788' Inexact Rounded
+subx656 subtract 0.499999      '123456789' -> '-123456788' Inexact Rounded
+subx657 subtract 0.499999999   '123456789' -> '-123456788' Inexact Rounded
+subx658 subtract 0.5           '123456789' -> '-123456788' Inexact Rounded
+subx659 subtract 0.500000001   '123456789' -> '-123456788' Inexact Rounded
+subx660 subtract 0.500001      '123456789' -> '-123456788' Inexact Rounded
+subx661 subtract 0.51          '123456789' -> '-123456788' Inexact Rounded
+subx662 subtract 0.6           '123456789' -> '-123456788' Inexact Rounded
+subx663 subtract 0.9           '123456789' -> '-123456788' Inexact Rounded
+subx664 subtract 0.99999       '123456789' -> '-123456788' Inexact Rounded
+subx665 subtract 0.999999999   '123456789' -> '-123456788' Inexact Rounded
+subx666 subtract 1             '123456789' -> '-123456788'
+subx667 subtract 1.00000001    '123456789' -> '-123456787' Inexact Rounded
+subx668 subtract 1.00001       '123456789' -> '-123456787' Inexact Rounded
+subx669 subtract 1.1           '123456789' -> '-123456787' Inexact Rounded
+
+
+-- lots of leading zeros in intermediate result, and showing effects of
+-- input rounding would have affected the following
+precision: 9
+rounding: half_up
+subx670 subtract '123456789' '123456788.1' -> 0.9
+subx671 subtract '123456789' '123456788.9' -> 0.1
+subx672 subtract '123456789' '123456789.1' -> -0.1
+subx673 subtract '123456789' '123456789.5' -> -0.5
+subx674 subtract '123456789' '123456789.9' -> -0.9
+
+rounding: half_even
+subx680 subtract '123456789' '123456788.1' -> 0.9
+subx681 subtract '123456789' '123456788.9' -> 0.1
+subx682 subtract '123456789' '123456789.1' -> -0.1
+subx683 subtract '123456789' '123456789.5' -> -0.5
+subx684 subtract '123456789' '123456789.9' -> -0.9
+
+subx685 subtract '123456788' '123456787.1' -> 0.9
+subx686 subtract '123456788' '123456787.9' -> 0.1
+subx687 subtract '123456788' '123456788.1' -> -0.1
+subx688 subtract '123456788' '123456788.5' -> -0.5
+subx689 subtract '123456788' '123456788.9' -> -0.9
+
+rounding: down
+subx690 subtract '123456789' '123456788.1' -> 0.9
+subx691 subtract '123456789' '123456788.9' -> 0.1
+subx692 subtract '123456789' '123456789.1' -> -0.1
+subx693 subtract '123456789' '123456789.5' -> -0.5
+subx694 subtract '123456789' '123456789.9' -> -0.9
+
+-- input preparation tests
+rounding: half_up
+precision: 3
+
+subx700 subtract '12345678900000'  -9999999999999 ->  '2.23E+13' Inexact Rounded
+subx701 subtract  '9999999999999' -12345678900000 ->  '2.23E+13' Inexact Rounded
+subx702 subtract '12E+3'  '-3456' ->  '1.55E+4' Inexact Rounded
+subx703 subtract '12E+3'  '-3446' ->  '1.54E+4' Inexact Rounded
+subx704 subtract '12E+3'  '-3454' ->  '1.55E+4' Inexact Rounded
+subx705 subtract '12E+3'  '-3444' ->  '1.54E+4' Inexact Rounded
+
+subx706 subtract '3456'  '-12E+3' ->  '1.55E+4' Inexact Rounded
+subx707 subtract '3446'  '-12E+3' ->  '1.54E+4' Inexact Rounded
+subx708 subtract '3454'  '-12E+3' ->  '1.55E+4' Inexact Rounded
+subx709 subtract '3444'  '-12E+3' ->  '1.54E+4' Inexact Rounded
+
+-- overflow and underflow tests [subnormals now possible]
+maxexponent: 999999999
+minexponent: -999999999
+precision: 9
+rounding: down
+subx710 subtract 1E+999999999    -9E+999999999   -> 9.99999999E+999999999 Overflow Inexact Rounded
+subx711 subtract 9E+999999999    -1E+999999999   -> 9.99999999E+999999999 Overflow Inexact Rounded
+rounding: half_up
+subx712 subtract 1E+999999999    -9E+999999999   -> Infinity Overflow Inexact Rounded
+subx713 subtract 9E+999999999    -1E+999999999   -> Infinity Overflow Inexact Rounded
+subx714 subtract -1.1E-999999999 -1E-999999999   -> -1E-1000000000 Subnormal
+subx715 subtract 1E-999999999    +1.1e-999999999 -> -1E-1000000000 Subnormal
+subx716 subtract -1E+999999999   +9E+999999999   -> -Infinity Overflow Inexact Rounded
+subx717 subtract -9E+999999999   +1E+999999999   -> -Infinity Overflow Inexact Rounded
+subx718 subtract +1.1E-999999999 +1E-999999999   -> 1E-1000000000 Subnormal
+subx719 subtract -1E-999999999   -1.1e-999999999 -> 1E-1000000000 Subnormal
+
+precision: 3
+subx720 subtract 1  9.999E+999999999   -> -Infinity Inexact Overflow Rounded
+subx721 subtract 1 -9.999E+999999999   ->  Infinity Inexact Overflow Rounded
+subx722 subtract    9.999E+999999999 1 ->  Infinity Inexact Overflow Rounded
+subx723 subtract   -9.999E+999999999 1 -> -Infinity Inexact Overflow Rounded
+subx724 subtract 1  9.999E+999999999   -> -Infinity Inexact Overflow Rounded
+subx725 subtract 1 -9.999E+999999999   ->  Infinity Inexact Overflow Rounded
+subx726 subtract    9.999E+999999999 1 ->  Infinity Inexact Overflow Rounded
+subx727 subtract   -9.999E+999999999 1 -> -Infinity Inexact Overflow Rounded
+
+-- [more below]
+
+-- long operand checks
+maxexponent: 999
+minexponent: -999
+precision: 9
+sub731 subtract 12345678000 0 ->  1.23456780E+10 Rounded
+sub732 subtract 0 12345678000 -> -1.23456780E+10 Rounded
+sub733 subtract 1234567800  0 ->  1.23456780E+9 Rounded
+sub734 subtract 0 1234567800  -> -1.23456780E+9 Rounded
+sub735 subtract 1234567890  0 ->  1.23456789E+9 Rounded
+sub736 subtract 0 1234567890  -> -1.23456789E+9 Rounded
+sub737 subtract 1234567891  0 ->  1.23456789E+9 Inexact Rounded
+sub738 subtract 0 1234567891  -> -1.23456789E+9 Inexact Rounded
+sub739 subtract 12345678901 0 ->  1.23456789E+10 Inexact Rounded
+sub740 subtract 0 12345678901 -> -1.23456789E+10 Inexact Rounded
+sub741 subtract 1234567896  0 ->  1.23456790E+9 Inexact Rounded
+sub742 subtract 0 1234567896  -> -1.23456790E+9 Inexact Rounded
+
+precision: 15
+sub751 subtract 12345678000 0 ->  12345678000
+sub752 subtract 0 12345678000 -> -12345678000
+sub753 subtract 1234567800  0 ->  1234567800
+sub754 subtract 0 1234567800  -> -1234567800
+sub755 subtract 1234567890  0 ->  1234567890
+sub756 subtract 0 1234567890  -> -1234567890
+sub757 subtract 1234567891  0 ->  1234567891
+sub758 subtract 0 1234567891  -> -1234567891
+sub759 subtract 12345678901 0 ->  12345678901
+sub760 subtract 0 12345678901 -> -12345678901
+sub761 subtract 1234567896  0 ->  1234567896
+sub762 subtract 0 1234567896  -> -1234567896
+
+-- Specials
+subx780 subtract -Inf   Inf   -> -Infinity
+subx781 subtract -Inf   1000  -> -Infinity
+subx782 subtract -Inf   1     -> -Infinity
+subx783 subtract -Inf  -0     -> -Infinity
+subx784 subtract -Inf  -1     -> -Infinity
+subx785 subtract -Inf  -1000  -> -Infinity
+subx787 subtract -1000  Inf   -> -Infinity
+subx788 subtract -Inf   Inf   -> -Infinity
+subx789 subtract -1     Inf   -> -Infinity
+subx790 subtract  0     Inf   -> -Infinity
+subx791 subtract  1     Inf   -> -Infinity
+subx792 subtract  1000  Inf   -> -Infinity
+
+subx800 subtract  Inf   Inf   ->  NaN  Invalid_operation
+subx801 subtract  Inf   1000  ->  Infinity
+subx802 subtract  Inf   1     ->  Infinity
+subx803 subtract  Inf   0     ->  Infinity
+subx804 subtract  Inf  -0     ->  Infinity
+subx805 subtract  Inf  -1     ->  Infinity
+subx806 subtract  Inf  -1000  ->  Infinity
+subx807 subtract  Inf  -Inf   ->  Infinity
+subx808 subtract -1000 -Inf   ->  Infinity
+subx809 subtract -Inf  -Inf   ->  NaN  Invalid_operation
+subx810 subtract -1    -Inf   ->  Infinity
+subx811 subtract -0    -Inf   ->  Infinity
+subx812 subtract  0    -Inf   ->  Infinity
+subx813 subtract  1    -Inf   ->  Infinity
+subx814 subtract  1000 -Inf   ->  Infinity
+subx815 subtract  Inf  -Inf   ->  Infinity
+
+subx821 subtract  NaN   Inf   ->  NaN
+subx822 subtract -NaN   1000  -> -NaN
+subx823 subtract  NaN   1     ->  NaN
+subx824 subtract  NaN   0     ->  NaN
+subx825 subtract  NaN  -0     ->  NaN
+subx826 subtract  NaN  -1     ->  NaN
+subx827 subtract  NaN  -1000  ->  NaN
+subx828 subtract  NaN  -Inf   ->  NaN
+subx829 subtract -NaN   NaN   -> -NaN
+subx830 subtract -Inf   NaN   ->  NaN
+subx831 subtract -1000  NaN   ->  NaN
+subx832 subtract -1     NaN   ->  NaN
+subx833 subtract -0     NaN   ->  NaN
+subx834 subtract  0     NaN   ->  NaN
+subx835 subtract  1     NaN   ->  NaN
+subx836 subtract  1000 -NaN   -> -NaN
+subx837 subtract  Inf   NaN   ->  NaN
+
+subx841 subtract  sNaN  Inf   ->  NaN  Invalid_operation
+subx842 subtract -sNaN  1000  -> -NaN  Invalid_operation
+subx843 subtract  sNaN  1     ->  NaN  Invalid_operation
+subx844 subtract  sNaN  0     ->  NaN  Invalid_operation
+subx845 subtract  sNaN -0     ->  NaN  Invalid_operation
+subx846 subtract  sNaN -1     ->  NaN  Invalid_operation
+subx847 subtract  sNaN -1000  ->  NaN  Invalid_operation
+subx848 subtract  sNaN  NaN   ->  NaN  Invalid_operation
+subx849 subtract  sNaN sNaN   ->  NaN  Invalid_operation
+subx850 subtract  NaN  sNaN   ->  NaN  Invalid_operation
+subx851 subtract -Inf -sNaN   -> -NaN  Invalid_operation
+subx852 subtract -1000 sNaN   ->  NaN  Invalid_operation
+subx853 subtract -1    sNaN   ->  NaN  Invalid_operation
+subx854 subtract -0    sNaN   ->  NaN  Invalid_operation
+subx855 subtract  0    sNaN   ->  NaN  Invalid_operation
+subx856 subtract  1    sNaN   ->  NaN  Invalid_operation
+subx857 subtract  1000 sNaN   ->  NaN  Invalid_operation
+subx858 subtract  Inf  sNaN   ->  NaN  Invalid_operation
+subx859 subtract  NaN  sNaN   ->  NaN  Invalid_operation
+
+-- propagating NaNs
+subx861 subtract  NaN01   -Inf     ->  NaN1
+subx862 subtract -NaN02   -1000    -> -NaN2
+subx863 subtract  NaN03    1000    ->  NaN3
+subx864 subtract  NaN04    Inf     ->  NaN4
+subx865 subtract  NaN05    NaN61   ->  NaN5
+subx866 subtract -Inf     -NaN71   -> -NaN71
+subx867 subtract -1000     NaN81   ->  NaN81
+subx868 subtract  1000     NaN91   ->  NaN91
+subx869 subtract  Inf      NaN101  ->  NaN101
+subx871 subtract  sNaN011  -Inf    ->  NaN11  Invalid_operation
+subx872 subtract  sNaN012  -1000   ->  NaN12  Invalid_operation
+subx873 subtract -sNaN013   1000   -> -NaN13  Invalid_operation
+subx874 subtract  sNaN014   NaN171 ->  NaN14  Invalid_operation
+subx875 subtract  sNaN015  sNaN181 ->  NaN15  Invalid_operation
+subx876 subtract  NaN016   sNaN191 ->  NaN191 Invalid_operation
+subx877 subtract -Inf      sNaN201 ->  NaN201 Invalid_operation
+subx878 subtract -1000     sNaN211 ->  NaN211 Invalid_operation
+subx879 subtract  1000    -sNaN221 -> -NaN221 Invalid_operation
+subx880 subtract  Inf      sNaN231 ->  NaN231 Invalid_operation
+subx881 subtract  NaN025   sNaN241 ->  NaN241 Invalid_operation
+
+-- edge case spills
+subx901 subtract  2.E-3  1.002  -> -1.000
+subx902 subtract  2.0E-3  1.002  -> -1.0000
+subx903 subtract  2.00E-3  1.0020  -> -1.00000
+subx904 subtract  2.000E-3  1.00200  -> -1.000000
+subx905 subtract  2.0000E-3  1.002000  -> -1.0000000
+subx906 subtract  2.00000E-3  1.0020000  -> -1.00000000
+subx907 subtract  2.000000E-3  1.00200000  -> -1.000000000
+subx908 subtract  2.0000000E-3  1.002000000  -> -1.0000000000
+
+-- subnormals and underflows
+precision: 3
+maxexponent: 999
+minexponent: -999
+subx1010 subtract  0  1.00E-999       ->  -1.00E-999
+subx1011 subtract  0  0.1E-999        ->  -1E-1000   Subnormal
+subx1012 subtract  0  0.10E-999       ->  -1.0E-1000 Subnormal
+subx1013 subtract  0  0.100E-999      ->  -1.0E-1000 Subnormal Rounded
+subx1014 subtract  0  0.01E-999       ->  -1E-1001   Subnormal
+-- next is rounded to Emin
+subx1015 subtract  0  0.999E-999      ->  -1.00E-999 Inexact Rounded Subnormal Underflow
+subx1016 subtract  0  0.099E-999      ->  -1.0E-1000 Inexact Rounded Subnormal Underflow
+subx1017 subtract  0  0.009E-999      ->  -1E-1001   Inexact Rounded Subnormal Underflow
+subx1018 subtract  0  0.001E-999      ->  -0E-1001   Inexact Rounded Subnormal Underflow
+subx1019 subtract  0  0.0009E-999     ->  -0E-1001   Inexact Rounded Subnormal Underflow
+subx1020 subtract  0  0.0001E-999     ->  -0E-1001   Inexact Rounded Subnormal Underflow
+
+subx1030 subtract  0 -1.00E-999       ->   1.00E-999
+subx1031 subtract  0 -0.1E-999        ->   1E-1000   Subnormal
+subx1032 subtract  0 -0.10E-999       ->   1.0E-1000 Subnormal
+subx1033 subtract  0 -0.100E-999      ->   1.0E-1000 Subnormal Rounded
+subx1034 subtract  0 -0.01E-999       ->   1E-1001   Subnormal
+-- next is rounded to Emin
+subx1035 subtract  0 -0.999E-999      ->   1.00E-999 Inexact Rounded Subnormal Underflow
+subx1036 subtract  0 -0.099E-999      ->   1.0E-1000 Inexact Rounded Subnormal Underflow
+subx1037 subtract  0 -0.009E-999      ->   1E-1001   Inexact Rounded Subnormal Underflow
+subx1038 subtract  0 -0.001E-999      ->   0E-1001   Inexact Rounded Subnormal Underflow
+subx1039 subtract  0 -0.0009E-999     ->   0E-1001   Inexact Rounded Subnormal Underflow
+subx1040 subtract  0 -0.0001E-999     ->   0E-1001   Inexact Rounded Subnormal Underflow
+
+-- some non-zero subnormal subtracts
+-- subx1056 is a tricky case
+rounding: half_up
+subx1050 subtract  1.00E-999   0.1E-999  ->   9.0E-1000  Subnormal
+subx1051 subtract  0.1E-999    0.1E-999  ->   0E-1000
+subx1052 subtract  0.10E-999   0.1E-999  ->   0E-1001
+subx1053 subtract  0.100E-999  0.1E-999  ->   0E-1001    Clamped
+subx1054 subtract  0.01E-999   0.1E-999  ->   -9E-1001   Subnormal
+subx1055 subtract  0.999E-999  0.1E-999  ->   9.0E-1000  Inexact Rounded Subnormal Underflow
+subx1056 subtract  0.099E-999  0.1E-999  ->   -0E-1001   Inexact Rounded Subnormal Underflow
+subx1057 subtract  0.009E-999  0.1E-999  ->   -9E-1001   Inexact Rounded Subnormal Underflow
+subx1058 subtract  0.001E-999  0.1E-999  ->   -1.0E-1000 Inexact Rounded Subnormal Underflow
+subx1059 subtract  0.0009E-999 0.1E-999  ->   -1.0E-1000 Inexact Rounded Subnormal Underflow
+subx1060 subtract  0.0001E-999 0.1E-999  ->   -1.0E-1000 Inexact Rounded Subnormal Underflow
+
+
+-- check for double-rounded subnormals
+precision:   5
+maxexponent: 79
+minexponent: -79
+subx1101 subtract  0 1.52444E-80 -> -1.524E-80 Inexact Rounded Subnormal Underflow
+subx1102 subtract  0 1.52445E-80 -> -1.524E-80 Inexact Rounded Subnormal Underflow
+subx1103 subtract  0 1.52446E-80 -> -1.524E-80 Inexact Rounded Subnormal Underflow
+subx1104 subtract  1.52444E-80 0 ->  1.524E-80 Inexact Rounded Subnormal Underflow
+subx1105 subtract  1.52445E-80 0 ->  1.524E-80 Inexact Rounded Subnormal Underflow
+subx1106 subtract  1.52446E-80 0 ->  1.524E-80 Inexact Rounded Subnormal Underflow
+
+subx1111 subtract  1.2345678E-80  1.2345671E-80 ->  0E-83 Inexact Rounded Subnormal Underflow
+subx1112 subtract  1.2345678E-80  1.2345618E-80 ->  0E-83 Inexact Rounded Subnormal Underflow
+subx1113 subtract  1.2345678E-80  1.2345178E-80 ->  0E-83 Inexact Rounded Subnormal Underflow
+subx1114 subtract  1.2345678E-80  1.2341678E-80 ->  0E-83 Inexact Rounded Subnormal Underflow
+subx1115 subtract  1.2345678E-80  1.2315678E-80 ->  3E-83         Rounded Subnormal
+subx1116 subtract  1.2345678E-80  1.2145678E-80 ->  2.0E-82       Rounded Subnormal
+subx1117 subtract  1.2345678E-80  1.1345678E-80 ->  1.00E-81      Rounded Subnormal
+subx1118 subtract  1.2345678E-80  0.2345678E-80 ->  1.000E-80     Rounded Subnormal
+
+-- Null tests
+subx9990 subtract 10  # -> NaN Invalid_operation
+subx9991 subtract  # 10 -> NaN Invalid_operation

Added: vendor/Python/current/Lib/test/decimaltestdata/testall.decTest
===================================================================
--- vendor/Python/current/Lib/test/decimaltestdata/testall.decTest	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/decimaltestdata/testall.decTest	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,58 @@
+------------------------------------------------------------------------
+-- testall.decTest -- run all general decimal arithmetic testcases    --
+-- Copyright (c) IBM Corporation, 1981, 2004.  All rights reserved.   --
+------------------------------------------------------------------------
+-- Please see the document "General Decimal Arithmetic Testcases"     --
+-- at http://www2.hursley.ibm.com/decimal for the description of      --
+-- these testcases.                                                   --
+--                                                                    --
+-- These testcases are experimental ('beta' versions), and they       --
+-- may contain errors.  They are offered on an as-is basis.  In       --
+-- particular, achieving the same results as the tests here is not    --
+-- a guarantee that an implementation complies with any Standard      --
+-- or specification.  The tests are not exhaustive.                   --
+--                                                                    --
+-- Please send comments, suggestions, and corrections to the author:  --
+--   Mike Cowlishaw, IBM Fellow                                       --
+--   IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK         --
+--   mfc at uk.ibm.com                                                   --
+------------------------------------------------------------------------
+version: 2.39
+
+-- core tests (using Extended: 1) --------------------------------------
+dectest: base
+dectest: abs
+dectest: add
+dectest: clamp
+dectest: compare
+dectest: divide
+dectest: divideint
+dectest: inexact
+dectest: max
+dectest: min
+dectest: minus
+dectest: multiply
+dectest: normalize
+dectest: plus
+dectest: power
+dectest: quantize
+dectest: randoms
+dectest: remainder
+dectest: remaindernear
+dectest: rescale              -- [obsolete]
+dectest: rounding
+dectest: samequantum
+dectest: squareroot
+dectest: subtract
+dectest: tointegral
+dectest: trim
+
+-- The next are for the Strawman 4d concrete representations
+dectest: decimal32
+dectest: decimal64
+dectest: decimal128
+
+
+-- General 31->33-digit boundary tests
+dectest: randombound32
+

Added: vendor/Python/current/Lib/test/decimaltestdata/tointegral.decTest
===================================================================
--- vendor/Python/current/Lib/test/decimaltestdata/tointegral.decTest	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/decimaltestdata/tointegral.decTest	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,176 @@
+------------------------------------------------------------------------
+-- tointegral.decTest -- round decimal to integral value              --
+-- Copyright (c) IBM Corporation, 2001, 2003.  All rights reserved.   --
+------------------------------------------------------------------------
+-- Please see the document "General Decimal Arithmetic Testcases"     --
+-- at http://www2.hursley.ibm.com/decimal for the description of      --
+-- these testcases.                                                   --
+--                                                                    --
+-- These testcases are experimental ('beta' versions), and they       --
+-- may contain errors.  They are offered on an as-is basis.  In       --
+-- particular, achieving the same results as the tests here is not    --
+-- a guarantee that an implementation complies with any Standard      --
+-- or specification.  The tests are not exhaustive.                   --
+--                                                                    --
+-- Please send comments, suggestions, and corrections to the author:  --
+--   Mike Cowlishaw, IBM Fellow                                       --
+--   IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK         --
+--   mfc at uk.ibm.com                                                   --
+------------------------------------------------------------------------
+version: 2.39
+
+-- This set of tests tests the extended specification 'round-to-integral
+-- value' operation (from IEEE 854, later modified in 754r).
+-- All non-zero results are defined as being those from either copy or
+-- quantize, so those are assumed to have been tested.
+-- Note that 754r requires that Inexact not be set, and we similarly
+-- assume Rounded is not set.
+
+extended:    1
+precision:   9
+rounding:    half_up
+maxExponent: 999
+minExponent: -999
+
+intx001 tointegral      0     ->  0
+intx002 tointegral      0.0   ->  0
+intx003 tointegral      0.1   ->  0
+intx004 tointegral      0.2   ->  0
+intx005 tointegral      0.3   ->  0
+intx006 tointegral      0.4   ->  0
+intx007 tointegral      0.5   ->  1
+intx008 tointegral      0.6   ->  1
+intx009 tointegral      0.7   ->  1
+intx010 tointegral      0.8   ->  1
+intx011 tointegral      0.9   ->  1
+intx012 tointegral      1     ->  1
+intx013 tointegral      1.0   ->  1
+intx014 tointegral      1.1   ->  1
+intx015 tointegral      1.2   ->  1
+intx016 tointegral      1.3   ->  1
+intx017 tointegral      1.4   ->  1
+intx018 tointegral      1.5   ->  2
+intx019 tointegral      1.6   ->  2
+intx020 tointegral      1.7   ->  2
+intx021 tointegral      1.8   ->  2
+intx022 tointegral      1.9   ->  2
+-- negatives
+intx031 tointegral     -0     -> -0
+intx032 tointegral     -0.0   -> -0
+intx033 tointegral     -0.1   -> -0
+intx034 tointegral     -0.2   -> -0
+intx035 tointegral     -0.3   -> -0
+intx036 tointegral     -0.4   -> -0
+intx037 tointegral     -0.5   -> -1
+intx038 tointegral     -0.6   -> -1
+intx039 tointegral     -0.7   -> -1
+intx040 tointegral     -0.8   -> -1
+intx041 tointegral     -0.9   -> -1
+intx042 tointegral     -1     -> -1
+intx043 tointegral     -1.0   -> -1
+intx044 tointegral     -1.1   -> -1
+intx045 tointegral     -1.2   -> -1
+intx046 tointegral     -1.3   -> -1
+intx047 tointegral     -1.4   -> -1
+intx048 tointegral     -1.5   -> -2
+intx049 tointegral     -1.6   -> -2
+intx050 tointegral     -1.7   -> -2
+intx051 tointegral     -1.8   -> -2
+intx052 tointegral     -1.9   -> -2
+-- next two would be NaN using quantize(x, 0)
+intx053 tointegral    10E+30  -> 1.0E+31
+intx054 tointegral   -10E+30  -> -1.0E+31
+
+-- numbers around precision
+precision: 9
+intx060 tointegral '56267E-10'   -> '0'
+intx061 tointegral '56267E-5'    -> '1'
+intx062 tointegral '56267E-2'    -> '563'
+intx063 tointegral '56267E-1'    -> '5627'
+intx065 tointegral '56267E-0'    -> '56267'
+intx066 tointegral '56267E+0'    -> '56267'
+intx067 tointegral '56267E+1'    -> '5.6267E+5'
+intx068 tointegral '56267E+2'    -> '5.6267E+6'
+intx069 tointegral '56267E+3'    -> '5.6267E+7'
+intx070 tointegral '56267E+4'    -> '5.6267E+8'
+intx071 tointegral '56267E+5'    -> '5.6267E+9'
+intx072 tointegral '56267E+6'    -> '5.6267E+10'
+intx073 tointegral '1.23E+96'    -> '1.23E+96'
+intx074 tointegral '1.23E+384'   -> '1.23E+384'
+intx075 tointegral '1.23E+999'   -> '1.23E+999'
+
+intx080 tointegral '-56267E-10'  -> '-0'
+intx081 tointegral '-56267E-5'   -> '-1'
+intx082 tointegral '-56267E-2'   -> '-563'
+intx083 tointegral '-56267E-1'   -> '-5627'
+intx085 tointegral '-56267E-0'   -> '-56267'
+intx086 tointegral '-56267E+0'   -> '-56267'
+intx087 tointegral '-56267E+1'   -> '-5.6267E+5'
+intx088 tointegral '-56267E+2'   -> '-5.6267E+6'
+intx089 tointegral '-56267E+3'   -> '-5.6267E+7'
+intx090 tointegral '-56267E+4'   -> '-5.6267E+8'
+intx091 tointegral '-56267E+5'   -> '-5.6267E+9'
+intx092 tointegral '-56267E+6'   -> '-5.6267E+10'
+intx093 tointegral '-1.23E+96'   -> '-1.23E+96'
+intx094 tointegral '-1.23E+384'  -> '-1.23E+384'
+intx095 tointegral '-1.23E+999'  -> '-1.23E+999'
+
+-- subnormal inputs
+intx100 tointegral        1E-999 -> 0
+intx101 tointegral      0.1E-999 -> 0
+intx102 tointegral     0.01E-999 -> 0
+intx103 tointegral        0E-999 -> 0
+
+-- specials and zeros
+intx120 tointegral 'Inf'       ->  Infinity
+intx121 tointegral '-Inf'      -> -Infinity
+intx122 tointegral   NaN       ->  NaN
+intx123 tointegral  sNaN       ->  NaN  Invalid_operation
+intx124 tointegral     0       ->  0
+intx125 tointegral    -0       -> -0
+intx126 tointegral     0.000   ->  0
+intx127 tointegral     0.00    ->  0
+intx128 tointegral     0.0     ->  0
+intx129 tointegral     0       ->  0
+intx130 tointegral     0E-3    ->  0
+intx131 tointegral     0E-2    ->  0
+intx132 tointegral     0E-1    ->  0
+intx133 tointegral     0E-0    ->  0
+intx134 tointegral     0E+1    ->  0E+1
+intx135 tointegral     0E+2    ->  0E+2
+intx136 tointegral     0E+3    ->  0E+3
+intx137 tointegral     0E+4    ->  0E+4
+intx138 tointegral     0E+5    ->  0E+5
+intx139 tointegral    -0.000   -> -0
+intx140 tointegral    -0.00    -> -0
+intx141 tointegral    -0.0     -> -0
+intx142 tointegral    -0       -> -0
+intx143 tointegral    -0E-3    -> -0
+intx144 tointegral    -0E-2    -> -0
+intx145 tointegral    -0E-1    -> -0
+intx146 tointegral    -0E-0    -> -0
+intx147 tointegral    -0E+1    -> -0E+1
+intx148 tointegral    -0E+2    -> -0E+2
+intx149 tointegral    -0E+3    -> -0E+3
+intx150 tointegral    -0E+4    -> -0E+4
+intx151 tointegral    -0E+5    -> -0E+5
+-- propagating NaNs
+intx152 tointegral   NaN808    ->  NaN808
+intx153 tointegral  sNaN080    ->  NaN80  Invalid_operation
+intx154 tointegral  -NaN808    -> -NaN808
+intx155 tointegral -sNaN080    -> -NaN80  Invalid_operation
+intx156 tointegral  -NaN       -> -NaN
+intx157 tointegral -sNaN       -> -NaN    Invalid_operation
+
+-- examples
+rounding:    half_up
+precision:   9
+intx200 tointegral     2.1    -> 2
+intx201 tointegral   100      -> 100
+intx202 tointegral   100.0    -> 100
+intx203 tointegral   101.5    -> 102
+intx204 tointegral  -101.5    -> -102
+intx205 tointegral   10E+5    -> 1.0E+6
+intx206 tointegral  7.89E+77  -> 7.89E+77
+intx207 tointegral   -Inf     -> -Infinity
+

Added: vendor/Python/current/Lib/test/doctest_aliases.py
===================================================================
--- vendor/Python/current/Lib/test/doctest_aliases.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/doctest_aliases.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,13 @@
+# Used by test_doctest.py.
+
+class TwoNames:
+    '''f() and g() are two names for the same method'''
+
+    def f(self):
+        '''
+        >>> print TwoNames().f()
+        f
+        '''
+        return 'f'
+
+        g = f # define an alias for f

Added: vendor/Python/current/Lib/test/double_const.py
===================================================================
--- vendor/Python/current/Lib/test/double_const.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/double_const.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,30 @@
+from test.test_support import TestFailed
+
+# A test for SF bug 422177:  manifest float constants varied way too much in
+# precision depending on whether Python was loading a module for the first
+# time, or reloading it from a precompiled .pyc.  The "expected" failure
+# mode is that when test_import imports this after all .pyc files have been
+# erased, it passes, but when test_import imports this from
+# double_const.pyc, it fails.  This indicates a woeful loss of precision in
+# the marshal format for doubles.  It's also possible that repr() doesn't
+# produce enough digits to get reasonable precision for this box.
+
+PI    = 3.14159265358979324
+TWOPI = 6.28318530717958648
+
+PI_str    = "3.14159265358979324"
+TWOPI_str = "6.28318530717958648"
+
+# Verify that the double x is within a few bits of eval(x_str).
+def check_ok(x, x_str):
+    assert x > 0.0
+    x2 = eval(x_str)
+    assert x2 > 0.0
+    diff = abs(x - x2)
+    # If diff is no larger than 3 ULP (wrt x2), then diff/8 is no larger
+    # than 0.375 ULP, so adding diff/8 to x2 should have no effect.
+    if x2 + (diff / 8.) != x2:
+        raise TestFailed("Manifest const %s lost too much precision " % x_str)
+
+check_ok(PI, PI_str)
+check_ok(TWOPI, TWOPI_str)

Added: vendor/Python/current/Lib/test/empty.vbs
===================================================================
--- vendor/Python/current/Lib/test/empty.vbs	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/empty.vbs	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1 @@
+'Empty VBS file, does nothing.  Helper for Lib\test\test_startfile.py.
\ No newline at end of file

Added: vendor/Python/current/Lib/test/exception_hierarchy.txt
===================================================================
--- vendor/Python/current/Lib/test/exception_hierarchy.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/exception_hierarchy.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,48 @@
+BaseException
+ +-- SystemExit
+ +-- KeyboardInterrupt
+ +-- Exception
+      +-- GeneratorExit
+      +-- StopIteration
+      +-- StandardError
+      |    +-- ArithmeticError
+      |    |    +-- FloatingPointError
+      |    |    +-- OverflowError
+      |    |    +-- ZeroDivisionError
+      |    +-- AssertionError
+      |    +-- AttributeError
+      |    +-- EnvironmentError
+      |    |    +-- IOError
+      |    |    +-- OSError
+      |    |         +-- WindowsError (Windows)
+      |    |         +-- VMSError (VMS)
+      |    +-- EOFError
+      |    +-- ImportError
+      |    +-- LookupError
+      |    |    +-- IndexError
+      |    |    +-- KeyError
+      |    +-- MemoryError
+      |    +-- NameError
+      |    |    +-- UnboundLocalError
+      |    +-- ReferenceError
+      |    +-- RuntimeError
+      |    |    +-- NotImplementedError
+      |    +-- SyntaxError
+      |    |    +-- IndentationError
+      |    |         +-- TabError
+      |    +-- SystemError
+      |    +-- TypeError
+      |    +-- ValueError
+      |    |    +-- UnicodeError
+      |    |         +-- UnicodeDecodeError
+      |    |         +-- UnicodeEncodeError
+      |    |         +-- UnicodeTranslateError
+      +-- Warning
+           +-- DeprecationWarning
+           +-- PendingDeprecationWarning
+           +-- RuntimeWarning
+           +-- SyntaxWarning
+           +-- UserWarning
+           +-- FutureWarning
+	   +-- ImportWarning
+	   +-- UnicodeWarning

Added: vendor/Python/current/Lib/test/fork_wait.py
===================================================================
--- vendor/Python/current/Lib/test/fork_wait.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/fork_wait.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,78 @@
+"""This test case provides support for checking forking and wait behavior.
+
+To test different wait behavior, overrise the wait_impl method.
+
+We want fork1() semantics -- only the forking thread survives in the
+child after a fork().
+
+On some systems (e.g. Solaris without posix threads) we find that all
+active threads survive in the child after a fork(); this is an error.
+
+While BeOS doesn't officially support fork and native threading in
+the same application, the present example should work just fine.  DC
+"""
+
+import os, sys, time, thread, unittest
+from test.test_support import TestSkipped
+
+LONGSLEEP = 2
+SHORTSLEEP = 0.5
+NUM_THREADS = 4
+
+class ForkWait(unittest.TestCase):
+
+    def setUp(self):
+        self.alive = {}
+        self.stop = 0
+
+    def f(self, id):
+        while not self.stop:
+            self.alive[id] = os.getpid()
+            try:
+                time.sleep(SHORTSLEEP)
+            except IOError:
+                pass
+
+    def wait_impl(self, cpid):
+        for i in range(10):
+            # waitpid() shouldn't hang, but some of the buildbots seem to hang
+            # in the forking tests.  This is an attempt to fix the problem.
+            spid, status = os.waitpid(cpid, os.WNOHANG)
+            if spid == cpid:
+                break
+            time.sleep(2 * SHORTSLEEP)
+
+        self.assertEquals(spid, cpid)
+        self.assertEquals(status, 0, "cause = %d, exit = %d" % (status&0xff, status>>8))
+
+    def test_wait(self):
+        for i in range(NUM_THREADS):
+            thread.start_new(self.f, (i,))
+
+        time.sleep(LONGSLEEP)
+
+        a = self.alive.keys()
+        a.sort()
+        self.assertEquals(a, range(NUM_THREADS))
+
+        prefork_lives = self.alive.copy()
+
+        if sys.platform in ['unixware7']:
+            cpid = os.fork1()
+        else:
+            cpid = os.fork()
+
+        if cpid == 0:
+            # Child
+            time.sleep(LONGSLEEP)
+            n = 0
+            for key in self.alive:
+                if self.alive[key] != prefork_lives[key]:
+                    n += 1
+            os._exit(n)
+        else:
+            # Parent
+            self.wait_impl(cpid)
+            # Tell threads to die
+            self.stop = 1
+            time.sleep(2*SHORTSLEEP) # Wait for threads to die

Added: vendor/Python/current/Lib/test/greyrgb.uue
===================================================================
--- vendor/Python/current/Lib/test/greyrgb.uue	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/greyrgb.uue	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1547 @@
+begin 644 greytest.rgb
+M =H! 0 " 0 !   !    "0   )(     ;F\@;F%M90                  
+M                                                            
+M                            !  "      #_                $ %-
+M\        0]<$ %%Z! !2>P                                     
+M                                                            
+M                                                            
+M                                                            
+M                                                            
+M                                                            
+M                                                            
+M                                                            
+M                          H    +!@  # L   T1   .%@  #QH  ! >
+M   1(P  $BD  !,O   4-   %3H  !8_   710  &$H  !E0   :50  &UD 
+M !Q?   =90  'FH  !]P   @=@  (7D  ")^   CA   )(D  "6/   FE   
+M)YH  "B>   II   *JH  "NP   LM0  +;D  "Z_   OQ   ,,@  #',   R
+MT   ,]4  #39   UWP  -N4  #?J   X\   .?0  #KX   [_   /0(  #X'
+M   _"@  0!   $$5  !"&P  0R$  $0G  !%+0  1C(  $<X  !(/@  24( 
+M $I(  !+3@  3%(  $U8  !.7@  3V0  %!J  !1<   4G4  %-Z  !4@   
+M588  %:,  !7D0  6)8  %F;  !:H   6Z0  %RH  !=K0  7K(  %^X  !@
+MO@  8<0  &+*  !CS0  9-(  &77  !FW   9^(  &CH  !I[@  :O0  &OZ
+M  !L_P  ;@,  &\)  !P#@  <1(  '(8  !S'@  =",  '4I  !V+P  =S, 
+M '@Y  !Y/P  >D0  'M*  !\4   ?58  'Y:  !_8   @&0  (%I  "";P  
+M at W4  (1[  "%?P  AH4  (>*  "(D   B98  (J<  "+H@  C*@  (VN  ".
+ML@  C[8  )"Z  "1OP  DL0  )/*  "4T   E=8  );<  "7X@  F.@  )GM
+M  ":\@  F_@  )S\  "> @  GP@  * .  "A$P  HA<  *,<  "D(0  I28 
+M *8K  "G,   J#8  *D[  "J00  JT<  *Q-  "M4P  KED  *]>  "P9   
+ML6H  +)P  "S=   M'H  +6   "VA@  MXL  +B/  "YDP  NI<  +N=  "\
+MHP  O:D  +ZN  "_M   P+H  ,'   #"Q@  P\P  ,31  #%UP  QMT  ,?C
+M  #(Z   R>T  ,KS  #+]P  S/P  ,X"  #/"   T T  -$2  #2&   TQX 
+M -0D  #5*@  UB\  -<U  #8.@  V3X  -I#  #;2   W$T  -U3  #>60  
+MWU\  .!E  #A:P  XG   .-T  #D>0  Y7T  .:#  #GB0  Z(\  .F4  #J
+MF0  ZY\  .RD  #MJ   [JX  .^T  #PN0  \;\  /+%  #SR@  ]-   /76
+M  #VVP  ]^   /CF  #YZP  ^O   /OU  #\^P  _@$  /\'  $ #  ! 1( 
+M 0(6  $#&P !!"$  04G  $&+  !!S(  0 at X  $)/  !"D(  0M'  $,3  !
+M#5$  0Y6   !!@   04   $&   !!0   00   $$   !!0   08   $&   !
+M!0   08   $%   !!@   04   $&   !!0   00   $&   !!@   04   $&
+M   !!@   0,   $%   !!@   04   $&   !!0   08   $$   !!@   08 
+M  $&   !!0   00   $&   !!0   00   $$   !!    04   $$   !!@  
+M 08   $%   !!@   00   $$   !!    08   $%   ! P   08   $%   !
+M!@   08   $&   !!@   04   $&   !!@   00   $&   !!@   00   $&
+M   !!@   08   $&   !!@   04   $%   !!@   08   $&   !!0   04 
+M  $%   !!0   00   $$   !!0   04   $&   !!@   08   $&   ! P  
+M 04   $%   !!0   08   $&   !!@   08   $&   !!0   00   $&   !
+M!0   00   $&   !!@   04   $&   !!@   00   $&   !!@   04   $&
+M   !!@   08   $$   !!@   00   $%   !!@   08   $&   !!    08 
+M  $%   !!@   08   $&   !!@   08   $&   !!    00   $$   !!0  
+M 04   $&   !!@   08   $&   !!@   08   $%   !!0   08   $$   !
+M!@   08   $&   !!0   00   $%   !!0   04   $%   !!0   08   $%
+M   !!@   08   $&   !!@   08   $%   !!@   08   $&   !!    08 
+M  $&   !!@   04   $$   !!    00   $&   !!@   08   $%   !!@  
+M 08   $&   !!@   08   $%   !!@   08   $&   !!0   04   $&   !
+M!    04   $&   !!@   04   $%   !!@   08   $&   !!@   04   $&
+M   !!0   00   $%   !!0   04   $&   !!@   08   $&   !!@   04 
+M  $$   !!0   00   $&   !!@   08   $%   !!0   08   $%   !!   
+M 08   $&   !!0   08   $&   !!0   08   $&   !!0   04   $&   !
+M!0   04   $%   !!@   08   $&   !!0   08   $$   !!0   08   $&
+M   !!0   08   $&   !!    08   $%   !!0   04   $%   !!OZ*@EA6
+M*3156$5:6TUF<DE8/R4M,C ^16:"=7UP2S]I<FM;6&-B13EO:$]$+59<<G=%
+M1%IR?7IQ:F%C6EIH245?9UA/<GT^65IB:G)N=HIM6C])6&]B:# .-GV&<F)A
+M9()@,B4M%3EZ8FAB8F!"24UC8VM8+2 =&SEU at WIMBDS^$@D5+6EJ6UHM)3(^
+M16)R<FE:8F=J<FM/6%QB8F-;6E9)6E9B:G-K6V-I8UA)/F%J9F)B;G5U?7IH
+M/SQ?8W-S:4E@?'-J8F E&$R(844^:6]B:%0I$E at I#A(M259?:'-Z;TAH8$1$
+M/F)O6%A%6V$_3X"*8"<V:VIT?'U at +3\Y at DQ6 44!:@"(>HII,#9$6%D#.?Y$
+M=W5H8%D_*1@@+3!0<F9K8E at _8W=B:V-B5BTE16%H7D4M,&]W2$Q:6W)\;5MR
+M:UI:8#!%:W=G16-Z*5A666QZ;FZ!8F-8'3!B8EH;#A5-;EI/8UQF=SXM/#(V
+M6C)H at FMK<FQ;8V)K:TE5.Q4 at 8HJ*=85R/!@.(FAN8F [$BOU6%5$:GUZ8TUC
+M:VMC7F)J;VM at 3V!J65E-1$AJ8S]87&A-/CY;8&!H8F)Z>7)U:EA%:5MK at 4\Y
+M8H-V>VE8-CQ;@W V+4QO3#=64!U)1# 5&#M$8'!C<G!83#Y$:%A-;EA8+39+
+M6%IZC'I+/FEJ;GV">$DV.TE@ 3D!1 #^<8)P-EAA8FI?+1LE<()F8V-?22DM
+M.RU-:F)B3#8M3W!B;W)8.3DG&SE at 6%@I'6)[:F- at 36IR6T]R:EII/B=8<GIK
+M6$]G/U9$6G)R;7)R4')H,BU8<E8M*SE5:&!'6FEB>U at V<&!:/QM)<G)Z at W):
+M9EMB<E9A1!(51'J*=75]_G0R#AA):FIW:" ;26AB<75N8D5$8G)J8E]0>G)@
+M17=[8FIH23Y at 9T5%8FE-.3Q-7V)K5B=B@')Z:FE;;$UF at TLV:H-N?7-825IW
+M>W!)24]K224V5D16:6$@&#(\16E-6SDM7VI:=WIZ:FM at -ALE+39F?'I836M:
+M9GV"@FI%/X)%:P$V 5@ \')M>F-;6V)V=RT.)6.(8F-P<F$V-F ^6FI?36X[
+M&RU;6H"":3XV/" R23961#9;<WAI7%]G8UE%<$U%:#XI16)R=VA)1U9,+UAG
+M:EM<:V-R9E at Y18!J5DEH:G!C8$E1;WIB25A))VY at -C)8=VMJ374#8OY)22T5
+M$BUB<FIJ=6U@,B V36)\=R4.&S9B>7)K9DU%3&MJ8FA%9GI,+6]W:G)K6C]9
+M:$U5:G)H8$0Y25M<224E8&MR9EM;<'-Z=TE9>H)N?'9 at 7EEJ<FY0>H* :D5;
+M23E):&\P)RE86%I at 8Q42,&A%<'IU>GIJ7"T@%25-:ER-339A:FIZ?()Z6UA@
+M<P%8 6D R')1:F)88UIM?EP;)59S1$UW?7 V.6A-3$Q627)H-C(V1'J"<E]5
+M53Y452 _8%A)6&-96F]R6DD_:$DY8VE>6F)M>F]),$PM(@-)Z5A)6')R9FE-
+M5G*#6DUB:FI$6E8M3'UZ24UN7EI--BU;?V)K6G)R:V))6#\R+39 at 6FAC9F9J
+M7#8V/V)U=RT@&!56<FUJ:E]8.5IA8F](2'4V&SE,:GMM:$E%8%8V37-J:6!)
+M6&IH/B 5+0-$QTU-;WI_8"T[7H)];FMB6UY::FQ;?8F*<EIC838P:5DB*1M)
+M8$56:R(I1#DV8VYRAX-]=U\V,CYJ>DPY(#9L<FU]=7=@36][ 7H!< "B at 6YB
+M44A at 66-R=S\T.5\M.6]]@&):<&]:14D^>7)@.RU?>@-R_G!F3&!N("5)8EI%
+M/S9%:H!B3#Y)6$E;>GIL<GIZ<E4V8$E$24D_/C8Y8%MB:E!B8H)Z7EEJ=3XY
+M61LI=GI%15Y[>G$_&S9Z8VMB=75R8D]/8VE63&);8V]F<F9914E86FIW7U4[
+M,F-R<F9Q:F-/6"]%;V)B:U0@(#9;>G)Q8:0M24DG16M<8VAB8WMR9S(8.UA$
+M-EA$871L/B4I,'6"8&-H168$:YMN@(9]9F-A/R5?7"4K("TY54UJ26QI+2U:
+M6EX#>HU]:UI)26*#83(8(EQZ V:%:F!-:W(!>@%W /Y[AG=@6#E-6F)S:%A5
+M16EO<GAY at GN"BG!)-!)B9F)0+5IS7E!M>V],67-5("U)8%@K%39@>G-R8#]8
+M36N";D1/<H)Z:UA-25I)+2TV6# V/TUJ8FMH:H)J6EMC8$E5,#QR:TU9/UIZ
+M at FT@2'-F=FIB8FUS8DUC<X-U:W!R646K>GIB44UG:%EJ at G)B6FIJ:VZ >VYK
+M:#LV7EEJ=V-$$B5J>G5N=TD@&RU?:@-:N45(>WMK+1A)<FI8:V-)84L;&"D_
+M>&U:9FDV37-S;&E;=7A]=G)K6UA-7#9$/S0;/V!B16IH+45;6 at -CEFMK=6M:
+M259B7C\M-F!L/TQK8UIB:FH!8@%$ /YG at GUS6#!$8&!:6#E$+6!K:VIR>G=D
+M?7=M3R5823DR+5EB:$UB>G!)37IO/S(R.TLE&"UA:G)W33YM36J":S8V46YU
+M>F],1%Q6,B4R7D0R-C!61%!@36IR:VEB8UMA259J64UB/S9K>FLE)5IK:V(Y
+M/F)R<EM:4'V*;6AJ6DG^<GMJ:V)Z<DQ$=7!F:%!;8F9V?7UU<F<^231C<F)$
+M%2EB=7)0>H [&SQ83%IH8#8G:GI@&PXM8FIK>W=I8#\8%14M<5I,8W!)/FEZ
+M<F]F4UR">'IL;G):6DE,65XE+55-=VIF>FI;:&!%/S\V/V ^)3Y,8VMB8E at R
+M+3EK;VAH at G)Z 7<!60#^:W5V?$T_24UA/S8V.QLV359:7&IR669B36AF6$D[
+M("4V/V!88G=O6DUR<FA$13P\*PX;26]B:DDV:%IC?EHP26U;4WUZ6D169$T\
+M+5A:26 ^/V9H:%E;8FMC14UJ:F-B:$186UA::G)A031%36)6+24O6FMR8D1B
+MA6)%3%I?_EQM:FUK;G=G67%Y<FLY5EQ<8F9Z=7QZ64(M6W):8#8M3&)H*5"#
+M:"TY138W8FH_*6AZ6B48)4U::G5Z:V=9*Q at .(%MP:%AK83]-<7IZ9F!-=75S
+M6WJ#8UMA6&!I/"DV57!<2')K<&MC6#]$/DEC6DD^+6-R:VE-*2TE17!C6X)B
+M=@&" 6D BF)B9GLV-EAJ:%H#2?X_25986%9:<G)O:41@<V-852DK-#9)6%EC
+M:F=R:VIK8%4^-C .#BUH:F)%3W)J<G\^&"5?84QR<EY)-CY663P^3&!R:"=@
+M>G)Z64QB:EX_5F]J:V=>24EB<G5Z=GIR8F!8650I&R4Y<F]G;X)H/C98=V)'
+M7U!:<F9P:F9R>FKS5$QB:V)<9EN"@G!:26]O3&A>259)6CY,>GII7UE%-CEC
+M23YB>F<[.T1965I636)J:$DE& D;2UA,6ED^/RU%:UMR>G9U:DQNBG=C6TQH
+M:U4[+5AN<UI:8W)N;G=C34UH:VMJ5B4Y:V-K6T1).RU?6DQ':P%] 6L _E]%
+M8( V+3EJ;4QA24E>8&-J:&!6<(!Z=T]8:WIJ8#8[,BU)9U],3&)[<6)G:5 at M
+M.SD@&!(_;VU)37)W at H)4(!@E25MF:F)9-CLP6$4Y15MV<B(P:G)O-BE/>GIJ
+M6$1B:%MC8%9<=7U]>W)S:F-I36A5.Q@;6FIU at H)J/BU>??YR658^+6I:7&Y;
+M3W%W:$1C=6YL63]R<F]B9')G.5IB;&]H3$1C at FYS>VA64TMC9UI?9F(P26%-
+M8UI:8&IR>FT\*Q at I5DU-25M%/DE83%9J>GIF/AU:DH)P84E:8DL^66EF?6XY
+M8')K4'MR6#9::X!]8S8P8VMF84Q(:&!?3T6"6EP!:@%P /YH/TU[-"4=4SXP
+M:#8V6FIJ8EM)+UN':G)R34V":F)@7#P at +6AW8DE:=WI;8&!8-D0_.S(I+6!J
+M6%1::H)]=U4T*S98:VIC<$DP26%))S]-<GH_)5IO7R(2/WI_<E8 at +41:8EIB
+M6G5]?7IJ7%IQ=DU,.3LG&#M9<H-\8BTE8FVN9FIB2#9:65EJ64E:<EPY3')P
+M<FH^6F)@6F)J21MA3%%K:F at Y-VUK9GIW;V!?6P-KSV!%&SM?/T5B8FIR?8EZ
+M8U @+6A8+2U at 24E%26!86FMK1"TE5I**@FA823\M-G!P6GIZ,#!0:D5:7&8E
+M+3EZBG)9.5!B65M--FER<$DP8F\!: %O /Y)25EI6%0[.QL;6#()3&IJ:V$V
+M&TU_:FU[8F)K33]J:T08%4AZ<%E:<GMJ;V-)-DQD/BTR-DA:35]83VIJ8F!%
+M.RTY66MB<F(M/V9 at -C9:>GMB,$E:/A at 2*6B":T4E"2U-641-8W6&?6YB.2E;
+M;EI8/BD8#A@@1'IZ5B([<G+^:7)J63]>7V)B3%QC:T\^27)Z<F at V.5M;7&IJ
+M6A5?6C]G8F- at .6!H66YU;FAC34U<<F@^&RU(/CY/8VYR<HEM8EDE&U9M("UM
+M138_-CY)6EAF*2!58GJ%DGI)-B 8)7)W:VIN8$M8:F-O:F@[*259=7IR6%9B
+M8EM%+4QO;68Y at FAQ 7<!20#S6$5 at 1&IW8&%%+3])-%]K:VA%1#!H:V-Z>FIK
+M:U]):&L[&!@^<FL_-DQR>W)O6C8R;V%%.SY66E9$6F)J;V!:6E9)238_<G5W
+M.39 at 63\_:'5R>F%0638K,#9(:'<M.Q at I8&A;/T1,;7IJ3242-F=-35DM*0,)
+M_AL^64DE3()R8G)H8%MB8%I;8G)Z<D0E27!R=G)>3UI;9WML:T1-9TQJ8UIJ
+M8W!H36J":F)W:4E/=V]:2U4[(C]836ER=81U<EM$-$EI("UH6DD[*PY-8E9)
+M$B!-8V)N at HIG*0X.%5""?6I9:&!-:F9U>FM at 255@65EZ:FAC<(I at -C9)7V)J
+M8FYT 7H!< #^6#Y)16=O3%EP83])-F)Z=V at P1$E)-C!Q at FIK:V-K@'=)("56
+M8EH_+2=CBFIJ6D0_36)/1#9-:&]%8&EJ<FA;:')R8S\M8G9Z6#E?.2U%8G)D
+M>H*"8CLR25A@:FIH, at D@6&IJ:4PY37)R9U4 at +6!@9UI852D.#B R,#PM3'5J
+M_D<Y2$5@<&I:35YU=7)-+3]K<G5J:V]V9UQR;UM816!B<FM964Q at 6EINBG)9
+M<GI-8'IZ8%AQ2!(E5C!):FEUAH)J64M$8#L\:6IB8#(.&UEB138_858V-EAN
+M8DP_.QT_=8)W6F-6-V)U;FYF;U]-8VQ/56IO6F-B-D15+2=@>H)Z@@%U 7  
+M_E8Y6556:$DP8G=I9S96<G)C25AC624 at 3'5R:&)J;GIM<$0E.3XY/T4M.7)>
+M8TD^245-1#DV/UEB9EA;<'=B35Z"BGIK/DE::FM$8#8;-DUB9VUXA6M$0C])
+M8&=:;QL)"45536]O6$5K<G)W2S9F7'IL8$E402 K,ALI*3]O:^I)+24V36MJ
+M8%IP?7!F8U168G)R8EIJ=W%;<')J14EC9G)R9TE$14U:9H)W6F-B1&)Z<EE8
+M<F E+3L_24U0:WU]7%E?6FAD26!;8F]4*39O>F)8/C8_4"T_<F<[+3M426IU
+M<F- at 14E:=75Z W*31%AP:2(Y8TE9:UI%1!L2,&)PB@%M 78 _F ^8%XG.50E
+M,$QF>E9::VM:36EL9BT;-G!R7%IF>G9K:VY+1"4 at -EA)36=6:4U6:&!/6F!)
+M6$U$:$E/8VI at +3EK=H6"84E-:F]'-TDI&S9)1W-R?7)98$D^1$E89S05#BU)
+M36MW;UIG66:"8S!@.69Z:D4P840M/#(V.S99<KE@/R V3V)B2$ARB'5F8F)@
+M6F)J6UA?;VI<<FMJ6DEK=W)B8$D_/DE:8FMO8FA-1%IR:456:W)H64D$6,-;
+M:VYB66IO;7IC85E-:G]?3VZ*>F]8(AM)6$EU<DDE-F!'8FM/9TDP:6MF<GI]
+M?69A6W)[)4%)'3EM:UX_,!@8+5EZ 6X!=0#^8E]K:"4E7%4G+41B;UQW<VM0
+M:6MK6" M8VPY33]<<&-;8%I8.14M13!C6"M at 8F)R@%!B;V-L83Y%8&E:16 ^
+M+38Y;H)B3%EK=V =2U at E*3\Y6G-U=5IB6D1)/U9 at 540@-DU98G)R9G)),&I@
+M'4 at V5GIZ8"U%841)6EI835EF_ED\,C]%6&M at 8G)V;G)N:W)K239 at 8V!88&%;
+M6E]C<G]Q:5 at V-CY;:V-C;GIJ2458:FM;:G)R:$1$:&MK8U at _66%@8G!C9FYR
+M85A98VM:6V9K8UMH+1 at B239F>G)/:&I,1%I$6E at M6&IJ9&UUBEQC9G*"14A8
+M*2)8:F):8$DI*8(^:P%F 6H _EIH<& M(#]N23\^1&IR>FMR6D]9:F0I)5I:
+M+5A%1%E?/S!(24DR.S8;.3X;/F)-<G])36]R=V$M)5A_;SE:;6$V)4]W:$18
+M:W)@)419,BD^24]K9F968F=)35A)6EA9/UE at 6$Q/:F9S8#!,8"5)/T50;G)8
+M16%M/F)K8U\Y3?YP6#8_.T5 at 9G)U=6-K8UYF<%026'!A15EA65A@:')]?8EA
+M.RDM16MJ8W)Z:T586E!P8%IP<F at _.6J&A7))/UYI3TAR<GI_>G)P8'!C23Y@
+M8DU/=UDK*38[6W.$=WIZ:$187#YG8E]B:F)3>H9:/V)Z=58P/BD8275B7&9@
+M/TN"/D4!<@%B ,PV6%@;/C\_8%I823Y8:GIR<6(_.5MI/C996"U89EA-6$DI
+M'39)6$DV+40[)2T_1&]V2S9:>HI>&!@P<H%+.5MR8UAC>G\G87)F:#8[ S^+
+M,#];6U8O1&!Q:%8#2?Y-36!P8VA96F]M;6M,5F(_26 R'4]W7SY-<D1>;G%;
+M+3ES<4LV-CYA:WQN<FAL<&EK=UX8.7]P/TEA:&!J;6I[=8IW5!LK+3E8<7J#
+M8D5/13]::$E-8VE9.6"#BFL_+5EK8$UB7&U\?7J#>&I9.3YA8TU-:F!)*24_
+M3%Z#>GJC at G)'5DDP8FUB65YK7&9U<U9%:WUJ150E#C9R8B(^1%IN at V$!- $@
+M /XR6&9;15A8259:6$DY6&IZ=5XV,$E666=K83M)5DU-6V!4+2U)6EA67$DV
+M-E4^6'=K63XP:HI)#@D517IP1#E::W=Z=7\P5G=Q:E8M)55H24EH338V3$1B
+M>FE)3T1%.5B$>G);:H*"9G)J65MC6V\[&SYB5DE)6CEQ<VQA1$O^=X)N/!LV
+M8&Z"=FYL9GJ =H!C&!M8:38P6H!O6FA:;V9]@W \+2T;)6."B%I'6V%%8&M)
+M,$5I83];>GYW7BU)8FAA6TQ?<FIJBHIO6DUF>G=-6G-H3SD5+5L_8F-;:W)B
+M8$DV6FIJ6EAN=5I9:&))6X)R:FA/%1):32DV.3]9 at GIR 8 !50#^2T]K<%AG
+M63X_6&)?23]-<G-K/C8_241;;FI8:&A)/EIK;TM8:$PY8%\P*2(V.7* 6T]5
+M*3]U8"<8("U,=VD_/UMZ>W)Z8#EJBG59( D@,#968DD=/F]R=6A-:W)N3S9-
+M>GYH+TQZ at FI:=W),9FUI7C]@34UN238Y>GIF6T]I_G-]>V$8%3=R>G-C34]]
+MAG9]<#PI.5]0)2]Z@&-C8FA@<G9V:%XV&!@_>H):/U!T6W=[8"TP85LV16MN
+M>G at _/TEI6DU).6)837:&;V-$4')U8VMR:T1L241U63Y$/CEC=WIR6&AJ8V9S
+M>GIB35A-.6.'9EQ98#8 at .4U$2T5)3()C9@&& 7( _FE%:WI;:F,^.6-B7U]8
+M36IU<6!)26!@6FMK:'-O54EA8F-)8')@+6!G-C(G$AM:@FA%/S]9;VM84%!)
+M6EQ?/C94:FYN>W)-1'UV3R 8#A at T8&]),#E,<F at Y25IR8S8V6$A:82U$>GUN
+M46IR7&)M6T]:<%DY9E\M&VMK8VE%6^=R:7IJ*QTM:FYK22<P=XI]?7MI7C9%
+M6"TG:FM@<%!$67AC5CE9;C0@/VMR.38Y:&B"BFTI-F9:/R5/6W)X238V84DY
+M.QTV-C!C@&UL1$UF:F-[>V-A<&YW?7(^+2DM6')Z<FIO<F-B W*6:V!)-BDY
+M>F)B6EA$.TEB.3]9<$0^3 *# /YR.4UZ;VIG.2M;8%]B<FIJ=75O5E9O:EM;
+M6DQF;TQ:8V- at 7UIN8CE?9T55+14;17EO-BU+8'=K25A at 6V-;64D_26-D:X%J
+M8D5R at GAG.Q@@1'=R8&EM3V9:&QLP<F(=+5]%-D])16^"=6A1:G)R6TLV/U]F
+M5DQ8-CE-8$Q8+3#G6V-W=BTT15MJ:T08*6N"=7U[9F at V/FE)26E-1'5I/D=K
+M;C0;/G]F/TUJ:#\V+3Y(>H=R/TMI8D4 at +45CA'!5-D4_2U4R-C!:<GV#9F-A
+M7T11>GUF7&-R at GIP2S8\,DEK:SDM:XAO30-;ED]9854V+4UZ7DE)1#Q$5CXM
+M/GQ?)24!<@&# /YK24UZ:G!,/CY at 85!:?V9J:W)O36)W:VEH9UH_66%:66)J
+M:V]P8UAB65A-7UY$3')W238V.6MH24E:8%]<8F]B1$U-7GIB:EQF=8)Z6QL2
+M+6]$1&J(>F9?*0X;66 ;+6A%7V@^&T2"B')B2&V*6EQ)0D1B:EI).SY/8%I,
+M+27^16-J:C<_9F-C:TL at +6MZ=G!W;%@I+V]P6FDV(F)Z;F];6"4K:(5W86!P
+M:F=5*S8_:G)<14UO:ELR&Q at Y?(1W/S _6& _+2D^669Z,CEB<4E%=GUU8&AZ
+M?()P1#Q926%R;%D^9WUZ;%I-23\_:68\&R)B;CM58&%I6DD\26M@@B4. 4P!
+M=0#*3#E:>DUW8#Y(6G!B37%M=VIJ8CE%<GMQ<W=K/C]66$U;:U%I6UM>:T]6
+M3&-O;VAF<F)51#9;:5EH8DT_15IZ=TDV)TUW<FI036(#<OY?.S]<)2UC?7UN
+M7U5!-F9B-C9H,%!R/A(E:()F3#Y:BFH^1&A08V];-C8_8&MS:4E)65YN>UI@
+M:VMQ8#8E+4]K>V-(:ED8%4R"<UDE&U9V<H)_51(E:W5S6TUL<FMB83YO;UY/
+M655;>&$R&!4[8GB*:3]/:6-)-#Q866-K-BFS/F9:1&IZ;F)K<GIZ8S\Y8%II
+M>&!/;G)U=GUR8%A$-G-X22DK24TP:6IJ>G(Y66-S:2T. 38!< #^)1U@>FER
+M9EI-6&]W26)RBH%Z<$4V6G)B:G-K34M81#Y$9SD_13]-;$U61$E;=WMH7&)@
+M63Y::5I_;T0M-D1J>FE$(#EJ at GMF6F-,6G%W:F-I)39B>G)J3&)J4')[8&!V
+M.5IH6#0K27)B241B at GI/26A68')8)25$<HAZ8EAI_FE13V)::FEC=W ^)398
+M37)Q3&)%'1 at V<FI)*39:6U%RBF88&#EB:6)C:VIC36DV7&I-8V8Y-EYI,A4E
+M6%!Z?7)C;'IJ<BT^:6]B:&%$.6]D34]O8D1 at 8EQF63PM5C]:=V%B<G9N<G5R
+M>G=)&V]W8#Y at 838E5F-;>H))/V)[=X)>( $; 3\ UQ at 5-EJ <F-$+V1O6B=:
+M<GR"@G-M35AB34AJ=T5)6$U at 8&))1#\V16AI:%@P+5ER=F!:6E at V16=9AWI8
+M+3]@8F9W839)8'5]<EMC23]9<F1B=S8V8GIR6 at -C_F)J=7IQ:2U)24UA25MF
+M3456:X6"9E]9+S9A52LE,FZ%=S\_36YQ22]%:EI;>WIO3V%A16-W7F at V(" _
+M<6M6-$EI-C!9>G=%(!LV3UIR<EY:3V]85FA87G-97EIO/Q at V:%IO4%QW;G=K
+M=3XV36],-UI-.6MJ3$1H<"U-33E-<*98+3\R,&)F<G5V8VEC6EQZ5!)9?5M%
+M6W%926MH2')S22 Y at HUZ7@$R 2  _BDK,CY]B&]$'3=@/" ^8G6"@&-:7')K
+M5CLY<&-86EAK<5 at W66 [-F)R>G=)+3E9<FM$138E/V!%>GUH26)Z=VMK=V)%
+M26MR<F)B8TDV8FM99F]-:W5<1&!18WMP3WJ";3\V-CE:6G=K1"U)8VEZ=7)B
+M," V.3Y5/W)]<DE86_Y<=7=8.6 P/G)M;6IZ:SE:=V--/RDI/F-:5"TY9D0I
+M16IJ=#0@)2TV:WM;1&MR<DQB<&%K<7!B<F<M/W=R8S8T:W-L<G)@6%MI225/
+M/TEC8D4E16 V5DD^.7-Q1"TV/F%K?&YR:&QP:6MW7A at Y?W _27%I3&IM16I:
+M-A(G8H*"BG<!20$R /Y97D5/:()];U9)/RDI8%IJ?()J6%IR:F)$,%IC8&EK
+M:W)@/UAH/B V;WIZ;UA836]P6#88%24_,'!R8D5<?7):6GJ 6D5C8FER:G)H
+M1%9J9F)H8EIN:4Q)+TU[<F)]DGH_.RT^36)R:#X;+4DR6X)R<E@@)R M7DES
+M?690<GO18EQK;TU8)2U%15!M@&\Y37)L6UD_+39$/S\M/FM8/TEP8FM>,B K
+M-FJ":4EK>G598'-L8VMI35!H3UES@&M$+4UR:VIR;W)Z>V)%6TDY26AO!#:K
+M5DUB2W>";CP;-F!N at G9N;&9Z@': 8Q@;6&DV,%J ;UIH35I9;C0;)V:"?0%H
+M 5D _H!B65Y88VY[>F))(!AJ<69N>F)K<%QJ:FE5.4U)6FIJ<F]925I$*1M,
+M<G5R8%A)<'IW1!@8&R ;;%])/UJ"<#0_<H)R6F)C6DA<<GI at 5F)K6TUH6$5-
+M/CPB-F]07GV, at E8^+41;;W)O12TR.R4V>FUK:"D5&" [6&AR1$%UBOZ 6S]:
+M8G!%-CPT26)F<EAL;FMA8&%+84E)5" =16)),')_:VE5*RU)8WIZ>'M[<$E-
+M<VMI44U9,#!8;W9[<FA5-T]A1&)D>H6#<EIC838P:5DB*39)341H:7-]>V$8
+M%3=R>G-C34]]AG9]<#PI.5]0)2]Z@&-C6V)A?8!>-D6"=W4!; %K /Z"33E@
+M15A,<'MK5" 28WIK:W=B:FE,6')Z:#XM)24^8G)W:F%//D0[25IJ<FH^,&*"
+M>F at _.24@(&AG1#]:>G(^.6-N<F!B:V V/UEK:$U9>F=%8EH^+1L@%39-+2=J
+M at GQ--BT[.6MK<G)624DI)7IR9FM5%14@,DE at 6C9A@X#^DG<P,#]K639%/UIO
+M3%EB>FY0:G%;8GIB8V0T'39O339O@&YC:4E$/U!C<G6"<EA)36M[:U at _53 E
+M6&YV<FIK6EAA12=84&Z AGUF8V$_)5]<)1LM=VA-6UMR:7IJ*QTM:FYK22<P
+M=XI]?7MI7C9%6"TG:FM@<&=0:WI]@&E/@EIB 7(!>@#^@TDG639).6EP8E4@
+M)5IZ>F)J:F)8+39B9'Y;-"D8($5C<F];2RU):6A@:7IZ1"=:@H)Z:$DE+45H
+M650V26AK35EB<G)H:69J6$E$14TY7W)Z.5E;8#(.#A at T22T;37J"62T[.QLY
+M36* :EE at +1MR<FMO:385&"U)6$DB8HAN_G2#8SLE8#\V56!I<F8_1'=K1%QI
+M+3!W?%M8-BM+=U at Y<WI>6EIH<4E%:7)N?7-%63E(?7-P83X@&TEZ at W);7T5;
+M>& Y6&);=7A]=G)K6UA-7#8;)5IR9EHP6V-W=BTT15MJ:T08*6N"=7U[9F at V
+M/FE)26E-1'6(:7=K<G)I/((;)P%F 8, PGM))4D\+1M-8#DV("58<H)O:F)6
+M.38V/C=R8U1$," M1&-H5BT8-F]P86-T at E@I1'*)@GMR+3!F<%I-54E)84]@
+M6 at -R_FE;:G)B7SXV+4]N at F)R:F->,A at R86A5*45K?&LP.3<I)2=->FMM;S\@
+M17!R:W)<*2 T56$V$CEJ>GV&<E at R8#\\7V-S<VE)8'QS:F)@)1A,B&%%(!LY
+MAV P:G)A6D5;@4\Y:W)SAX-B7S=)<&9P82D.#BUB>GIC8$5C at FM/8[MR9E-<
+M at GAZ;&YR6EI)54E88F]I)45C:FHW/V9C8VM+("UK>G9P=VQ8*2]O<%II-B)B
+MBGIK8&EK8#8.#@$P 6( _C9Z@&!9+2<V840I("E8<GIZ<D\_.5AF7D]U8E]8
+M1#(R,%9B8C\@+6AO659J>FHY+4UZ?7IZ/RU:>FM:8E at _241-/V)K<FAH8W)D
+M6V0_/$EF?$=K=69R21LR:H)O/C9B9(!F8$0_52)%<EQF at F,[+4EF<FMH-B5>
+M?6-9*SYCBOZ-BGML36)816E;:X%/.6*#=GMI6#8\6X-P-A at 8-H)K/V%H6DQ?
+M8VM8/VMJ9HJ/<FD_8&%(<6$I%1 at M36IK:V at Y37MP6$UJ9F!-=75S6WJ#8UMA
+M6VMS6F-I25E>;GM:8&MK<6 V)2U/:WMC2&I9&!5, at G-9)1M6=79G,B4@)3Z"
+M=U4"%0#^26I[@&YR:$5 at 1#LR+59B<G* 6U]H86QW:6=%:G=86$E$3V)J:%X_
+M8&E96FIZ=6A$/V)U:F9A15EV=FMC8V%-1#8M3V)N15MR@&)B3U9)6&MJ1$U-
+M7&HV%25,9&(V)6."@GU];6I5%39R9U!Z<EH_5F!J;U82%5J':'!926*#_H6&
+M?8%A6VE;;$UF at TLV:H-N?7-825IW>W!)*RE):VM;84U at 16)J:DDT8VA/>HUV
+M:#E,1#!I8T0@(#]I<TU(<V9%8W=),$Q;<GIV=6I,;HIW8UMB:W)@6F)I:5%/
+M8EIJ:6-W<#XE-EA-<G%,8D4=&#9R:DDI-EI<6V]).2<8+8)O;0$. 2D _DE9
+M9'=09H!B6$0R,D1)36]K:D10;V)9;W)@+6AR8U8_1%E:6598/T4_16!K<G=B
+M14]O<W!:64E-<G=B7FIO:$TV)4EO83DP:'MR7%]H6&M[>G)P36)J524M6%]$
+M&QM9>GV%?&IK/Q at I<'IF<W=B3VA?7&<Y& DG<FIN:6!-9H%Z WW\<F%;6W!S
+M>G=)67J";GQV8%Y9:G)N4%@\26):6E at Y6&%B9G!+'4UH.6:1 at F M+55)86MF
+M-B V8W<V)5IO6UMP6# ^5FIZ>F8^'5J2 at G!A5G!I245%36YQ22]%:EI;>WIO
+M3V%A16-W7F at V(" _<6M6-$EI3S9K,$1:)39W at P$M 2< L4E-6FE$2'IR:TDM
+M+4E>1&-W34E-6F)96W)P+5EW:U\V+4E?/SY)6%@R(E]C:WI;-DD#<LMH23XV
+M:W)G6F)R<F M&#=H24@;/FIB/V)J67*%?7:!:V)B:4E89W!)&!@V:69]@FI/
+M&PX;8()U=W)O6EI/8E at M.RD;16-B6U at _47,#?;!Z:D],;WI_8"T[7H)];FMB
+M6UY::FQ;8%I/6$E-8#X^6W)L9E45+5PY6H.*<"4;2W #=\EC/#=C>EDT/DU;
+M:6]A23966FMK1"TE5I**@FA)7&-)/DE;7'5W6#E@,#YR;6UJ>FLY6G=C33\I
+M*3YC6E0M.69A1&]%-CL;&TR" 6@!/@#^:$UC<$E%:W6'9R4I5%A%6G1$2&A;
+M7F!%7GU)37]R:EE$5DU).SY)8#\E86QZ>F(V/UQ[<FI8+1MC<G)K<GIU<$0M
+M/UP[5#8M23DM36);9(J$5'5R8FMK6F=W;TDE("U8669U>EDI#@X^@GUZ<E!,
+M.3!H8#(_5CXV6EDM-EA at EDU>=7V#=5M$871L/B4I,'6"8&-I168$:YEQ<FLY
+M/UAN/BT_6FM(530T/S9%9G!W)1M+ W+*:6%6.6.#@7!?/DUU>FI;*4E:6&8I
+M(%EJ?862>FEG9F)%6GMB7&MO35 at E+45%4&V ;SE-<FQ;63\M-D0_/RT^:W=8
+M9&=8.R ;+6@!=P%< +E:,#EH/CEG>H-W24E at 7T5-:%E9:&AC8$E/<FI,:VMC
+M8VAG7TT^/E9@/S!I<')J6$D^17)U<E at E&%@#:O=Z>G:#<E]?24E:;5\^+2U%
+M6D=B?8E:4&IR<FI,67)K6#8I-DE9:69J:3P8&"5B<G)K6E at M)5A?1#]F7C9$
+M+0X at 15@M,%MK?8)[8TEA2QL8*3]X;5IF;2U)<W-L:6MN;#8V27!8/S9%6D58
+M9FE$-D5B8TTE&S]S7 at -;R& V-F:$>W=A6W5[8UHM36)621(837)F=9**<FMN
+M>V%%BH!;/UIB<$4V/#1)8F9R6&QN:V%@84MA24E4(!U%>&)B7UA)-BDI.0%H
+M 5H W%8V+4DM+4ER at WI086%B8%E at 8&-R8FA at +2U;?W)H8$]88VIH6DE)6&]-
+M+45B<FA-24E-8VIH5"T.259B:W)Z>X*":V!)25IJ>E8V/TE%35IR>F ^5FIT
+M<DU8:FM: TG^7$];6EQH6#8R/CYB:F!)240^6%8^-E966%4T#ALM6$$E+3!K
+MBI)[86 _&!45+7%:3&9W23YI>G)O<EQC.RTV8VEN86-:/SE::ED_:7IW-B4I
+M/U$Y)S9C<$D@,')B9F]C;GI[=SYB;U8I%2!$<EE:>GUR:FZ%=S^ DG<P-DE@
+MH5 at V13]:;TQ98GIN4&IQ6V)Z8F-D-!TV=V]:34E%1#\V+0$_ 5@ _B='4$16
+M34U::GUZ:CE88FI:.6IU;E at I("UGBG9L:3XE/F]B5FAK<FI at 6%MM<FM;5EAA
+M=VM@/S8_8&!W>G5R<FE at 36!:6%IJ<FIO8$]-6VMR<EA-53]@<FYS6TD_8')O
+M62TI.5IU<FE;8VQK6#\V/TU;<%DK)6EA66A+-"M+:?YI/!@./X*- at G)G62L8
+M#B!;<&A8:V$_37%Z>H)[6T0R-EAJ;W!R<&%$8W)83W*&@#\V27%A-A@;8&Q$
+M(#)I8#]:3411;H,Y8G)C,B Y37IF86EN9T=RBG)5;G2#8S\Y6$D\56!I:V$_
+M36MK3%QI+3!H<&!8-BM):VD^-C(M/FJ";S8"/P#^6%A)-D1-36ER=7IK-CY8
+M45@^:GIF330\-T5Z>FYC,AL at 8UM%8FIJ;FQC;VUN;%E);W)J;EI)/SY)6G*"
+M at G5K<VM at 6F!B8&AM8W)R6T5C>WIR63E>56!S<G);)25@=G)C1" E26MZ=U!C
+M?75I1"D;-FAP:3\E16!8:V V+45R_H!5#@X_=7UU<6AF/RL8*4EF;UDY15@^
+M6F9R=HIP7C\V26)J<G-Z=UAJ:UIH8W6#3UE?>W1$*2U;:#\@,EIW6UM>-C!(
+M9EA::FQ/-D1)<W-B6FP^&T1]:EAZ?89R6#]82SQ?86EI63]8:6-B8F E+4UK
+M84L at -DUK:#\E*2DM3()C30%/ 6$ _F-C1#8V/TMH<F9H@%4M/C9$:&9U8B<E
+M86E86G5Z:#8@)SM8;G!J3UIB:WIN:FD^-G)R64<_6#LE*39:>GUU:FYK8EI@
+M8VIK:F)1>G0;27)R:G5%15IP<W9W8#0 at 6FY;3U at E&S]A6ULG1'IV<FD_&"EA
+M:%YG1#\_+8-L224P:_Y[/ X.5G5[;FQH<69$*2M88V-P)1U$24EB:%!N;&%)
+M/UE:8GAN>H=P;&Q/:&QW?EMA.5MW:4MA<'=9*39%<G)C:5Y526!P;UI-35IJ
+M6FIJ139//SM)8V=;<G)K3$]6:&YR;UA5-B ;/UA:8FA6/CY)25MJ<&M;6V R
+M)3M)8VB"9D\!5@%I +=C8EH^+2([<%YC6W9C,#8@&UAZ:SD5)6EM:D]/@&Y8
+M.S(M,&^">F)-24AZ>V!;)2!9:UA)/C\V R"(+5QR;FIJ;FH#8OYF>FUK8W)W
+M+4M:3U%V<&%@3VIF<F->/V%K14]I1#]B<G)F-CM0<G. ;#(E8%I8:&EI6#^#
+M:TD;/GAZ21 at 81&IZ:UA%8GA:.S]88V%K7E5+8&!(;U at _36$\*6EF7EIF at WUN
+M8W=J8EEK at F-F,C96:6F!<G)I25A+8H!L8V)I8W&[:VYS22=6>FI66T0E-F!I
+M:5]B8G)R;UE-6W)F9F],8#P8#BE)6&)O6V!)/SY-<G9R8D]K6B V36QR:F@!
+M:P%R /YK3&)M$A(V5DAA6V9W/BTI&"UN:24.)6AN7&MK>G)B22TM1%E]@G)?
+M6%9J>VM6.T19:%I-6%E)-CP\,CYB;UE<>FIK:V!-:DQ9>W=Z36!A345:;W)W
+M86E:6F)B;&MH6%EP84]B>G6 <FE%8EYN:F8_6F-I:VYS<&"":T0828/^BG%8
+M14E?>VQ$&S!S<%E+,%MW:VEQ8$UF24UH/S9$)2U965 at _6W)K:&%J>G P.7-W
+M<$LM.5A;9W)C3UMI/V)Z<EH^3%YR35""9R55=W!%65@\25AI<F)08FIR;UA-
+M:G)R:G!6:FT_'2!)6VYZ<F]I2418=W)R:UIC:$M51%MC at D50 7H!=0"T9T1J
+M at QL21$U$8FM<:V-85#0M8%\M(#9L<F)O=GIM8DDK(E8_8F)C65]U=G5J5CY)
+M/FEG301 at _FAI=5]/838R=V)/3%A%6#8^;G)R9FIW:DTV,&*"@G-915A><G):
+M24UR;%EC<F-R;75R=V-/6F9K<%M>:VMJ7F9_6T0I)V*(@X* 3TAR<#(2'5EJ
+M8UY$/F)B=V]625I8.4E at 83(@+5E8/S]88#9%9UIR<#PE1X-R<$LV6'!C8<AA
+M25!F/UIB5CDI*4];35MZ=S8G8&,P2U]96C9/<F=%/T=B;VA::W)Z<FMJ;W)@
+M/RU$6'%Z;UYK34EB6VYK:EIB4&)W8F%)&QT!: %F ,!B3&Z1)1A56UIH<F-1
+M8F):6$M$/S8Y3W)U<G)J;6I)+2L826!8.38P6G)]@VA%,"TM8W=I65M@:G*!
+M>VM/6#(M W+384U-6#X_:&-B;6MU>F(R%2]WB'I/.5I,;VMA13YI8UAH>FM:
+M2&IZ at W%%66MM<D]/6F]C3U%J6#9$*2=-<HJ*;%%J:RTG)38P25I$)24M;G)C
+M86,#6>5H=S(@-&!H8$E8/Q at E2UEP:U at E-G-S>W _5G)\:4U:344_:6 ^)14I
+M25@^1&IZ<D1).398:%I8/TEJ8TE$.41G:F-G:FMR<FMK<F)6/EA@:G)G35I@
+M36%)6G)G3VE)479]<F$I&P%9 6H B%HP6HI8,%AC!&O^85A035AH*1LI1&!J
+M;H)U<F-P1!LR)3YM6#0I*3Y99GI?/D0I(#YC>E!96UIN at G5B35@_27IZ at W!-
+M85M%/V!8.6)F>XAC)0D26H-W8#D^.V):84U/3T4^6GML8V-H>HIL,$AZ=7)%
+M/TEC8F-C:6$M1#8I-DUUBGI/4'-87EY5]"DM5#L8&RU9<FMZ at 6$_.6)0.RDV
+M26IR8V!$+3Q5:'=R7B4W:W)]<F%C6V9[8EL_+3!O;4DI&"5$22T;/FZ"?U0=
+M/$EB7&$\-C]:6F!H<69N at G!)17> <D]%35AB:W=W:EHP+V!;6C8Y6EHY<4]-
+M8GIU<F$V 6$!<@#^:#];;G)A36)R:E!C<G);24]?.1(2)4EC<HJ">FMH7CLV
+M86!H230T/%A98VM)+39;(!(V:%I86EMN>W);35 at V6&YUB&(T8W!824\^)3 _
+M@)%P*0X827)F:V$^/VA98VQA2T0V-V=A8&MZ=8-C-D5[@G=@/SE)87)Z6FDV
+M/SXM_C9-8G:"6TUL<%MA:5Q)83\R+39)6F-Z at G!826U-+3M$15IK<W)9/UA8
+M8W!S8S957GJ":UMQ6T1RB'IA/S9I:4DR*2T_82L@)6*%?6 at M-EMJ<DLW/$M9
+M1$1K<V)>>W=A6'*#=6$^/EA:;G=R:F I$C]/6#X_240G8VE86%!F>H)W30%:
+M 7, _FM;8VIZ:U9B>FM:8W)V>&!-3%48#@XI27J2A'5R:EA)28B#<DTR+3YI
+M;V)H5"D26"D.$BU)5E]H<WIR:&)B-CE%9H-@,&)R:VQH23()&VJ)>DDT+5AK
+M7G)S/DEP8F-K83]97CY915AB=UQZ<458<GMZ<T0M1%ER?75F8VA%19]@:V)>
+M11U,:G)P1!LE8GIB45A8/AU8844_,&-0.2U) V"K6V)R<FYK;&E5/"U-=7US
+M8VQS8UMB:6QV=6UC6CXV6&A at 35]J6ELY27R";0-RL'M$+55 at 7C\^8WIP6W)R
+M8V-K>W)B/UAA36IP<E!8,A at E26-H9U9$.UMF:F-$4')U8P%K 7( _F-06EY\
+M=T=B>FM88G)U>F]-8%@;"0X8-FN*BFU>338V1(J%@F]4+2U,;TPW5E =240P
+M%1@[1&!P8W)R;VMK6"T;/WAP.6)U9')R3#()&%F"=UM>6$5),&!O.5AA:6EB
+M6#!::#]A24U97$UR>%M98VQZ:D0I-C9C?7%;3V V/Z!Z;FAC624M25Z(;CLR
+M6W5R:V-O-BU)6$54/E at V(!M%6P-8PDQ-6V-C:6-926!Q:WIR7G)K6TE/86=R
+M=69A8#])=X-J9G!R6#8E/WN";G5R:F!>)4)@6$D_3'5N6F- at 1&MC<FIO8 -C
+MF'IS>FA at 230I6%IR;V!-:&EC:FQ$369J8P)[ /YF33M-=GU$35I,-&!J;7-U
+M4&IP,A4.'3QO at HUZ12TI+4EZ>()U<EY)3VM))3961%9I82 8,CQ%:4U;<F)B
+M7F @&"5-8UAN:D]F at ELV&"!@>G=$.7!I-A(V8#9/15AI340;/UXG/T1,9T1)
+M;')C22<_<FLP+40V/W=R6EMF+4G^=U1W>F8M("5:>WMH25IR:7> =V!%3UI)
+M8FAF+0X8/TU%/DU)-C]88%I:6$E@>F)K<G)N8DE%241)8V)-8V-88H*1<FR!
+M?&$I("UJ>G=Z6SXP8"DK/SX_-CEJ<TQ8:$]@86EI8F)H.4V">FIB8E8^1$DY
+M:6]$16)K6EQF8V%?@D11 7H!?0#^=7)816IZ:$E)+1@^54U[@%!,<D4P%2 R
+M3'IV>F$R(!LV:W9V:F9R>H* :D5;23E):&\P)RE86%I at 8VUJ6%M;1&YF)25B
+MBG(_:H5Z<#8M67I[8"4P<&T;-FA at 839/<F)>*3YQ52DM27!;64]B:FD\,DQB
+M239$2S9)8V-B<$D^]&E(<H)X7C E8VUK:#E-:4A9?8)R;EE/3VAK8S0.($E-
+M24E865IB6#8E/EI at 6V ^,&:#;G%I245$-EMF.4]I85IB at G)4;FYB+1LB36IJ
+M?&]F6T\R*T1+539)8W)%/F9W85A;<FMB/Q at E;W)H6$Q8/D1)(F!K UB)7&)(
+M,CEB<4E% 78!?0#^;GIZ:%MF;S V13DV1#ERBGI::E95+3QA8W)J;F V*2D\
+M3W!N;&)D?8F*<EIC838P:5DB*1M)8$56:VUB7UXV.7MB&Q4W=6]':&AU?4DM
+M35QV at 2T2+5@I&U9C9B=9>&IP/S!S;24V640P8G%F;GIJ6TE':&%82TE/245$
+M<F]/_F!H:VYS6SL^8W)K8SPY86%::WJ#>&A1<'=R9U45)4U:.4E;6V)V=RT@
+M-EA at 6E@^&T1K37* :6%@15AP64UB8UL_9H-K8V)P7C(R=$Q$8GMZ@&-5-D5A
+M85AA:7!5-EIK8UA%8W-O-A at E86]J8%I935]))6ES<6)89G%/-BD^9H):1 %J
+M 7H _F1F;FUR6U at E%2T\/SXY<(:(:UI:9CY$;GIJ:7)A/RT_845I7&IK4&Z 
+MAGUF8V$_)5]<)2L at +3E536IR:UY)&RUC- at D.'6IZ8W!$68A+/%M:<()A.2 E
+M/!@E6&85/G-'7UE)<G(M/VD[%2MP;G6*;F-P:VQO:$U'64DV,&MW6OY-:FQC
+M65XP-D=F<G!),%IC:6-K at H1N36)K<FMF1$EP:C(V6&-:;7Y<*3))6$U)9BTE
+M/SYC<W-L8DUH8UA8:F9 at +6J&<V-%:F)).VI,6&F">H->8FT^-D596VEK8$]C
+M:F)I/TEC<VE%1&-P:&]R:%IG6E5B<GIJ1&:"8V%$.6^"9$T!3P%O /YZ8EQ;
+M:VE6/A4@)54V/&A]?6I%2UA at 15F(6UEW:3\M6'!-8TQB@&);=7A]=G)K6UA-
+M7#9$/S0;/V!B<F]@2QL_:$0G'1MBBGU[85B"/S9A<'J*>F M+44@%2TV"25@
+M/C Y8&YZ6W!K530_6T]F at VM/>HA[;G)925E4)15-<F/^86MC:V-K64LV16)Z
+M6R4_:VMI8W.*?6M:3%MP8TQ6<FM81$Q at 66-R=S\_158_/F]M,B4_66-F<UQC
+M:#E$6&)N:"U,<G=J+4E65DE:7VAK<GJ(04UZ;BTM-D5I:4U8:6MS<DE46UYS
+M:U9(<$UP=W)K:F9C.3]N>UQB=5Q:33EK at FI, 40!:P#^@W)'6G%C8F$R%1 at V
+M/CYF?75K+2TV<&A-=UMI=V$_-DQB6E at P,G=R9E-<@GAZ;&YR6EI)3%E>)2U5
+M36!W6TP^8(" :R4)-GI]=G)B at UDP.6IZ?8IK/EEA-"DK%0X;8%@V+6!W=UIR
+M:&!@86M;6FYI,&.*AGIJ8#Y%/A at .+5]0_E!J9GAR<7=S8%59:U\M/V-<;W!F
+M?8)U<EI)8FL_1&QK6%A-.4U:8G-H3TE)6FB#AVDM/T5:9GIB8F<M(C8_=W)+
+M16)N<E at V1$1)16-O:DE>>UEM>FU;1#8_:%@M+3E<@H-,16%%8VE85EE)8&IR
+M=7)O8AL2.7IW;G)B3S])8X)B10$E 44 _GI[159C15IR;S\Y)2U$8W5H<BD5
+M&UAK;W)(9VQ%/F-I6CE)-D5J:F9 at 375U<UMZ at V-;85A@:3PI-E5$8EL^86QN
+M?'<\("U:>GIF8G=Q351L>W*">V-F:5Y)4$$@,EA at 1#9-9G)B35E96$UZ<EI:
+M82=:?8=Z9F-823\5"1 at _2ZDV-UIZ7&-[;F]@8%I-66%C6V-L:WUR>G9P6V)J
+M7E]Z:T]833E$8&!:6 ,_U&-RBGUR:5L_36-Z>EQ853(;)VMR7CE$8FMC2SY4
+M/R<V4&Q536(Y<HIF6UDV:8!5&Q at I-F:(:$]:15E at 14PY5E9;9GIZ<F ;%1M;
+M;F9M:EM):W!J/@$; 2< _H"*:F-96FER9EA at +2U%:WMR<C\I&#)(>G5B<F,Y
+M56:!=S8V8'=P3%MR>G9U:DQNBG=C6TQH:U4[+5AA34DB/V]R9G=/-DM-;8-R
+M9FUW33EI<FMC9G=O8F-96V8E55M)26!O<'=H-C\V+2=K<FQT<$1K?8I[8UMI
+M84DI"0XM1?X@&U9J/UJ!<FAB8%M)6F%C<5MA9G)R=G5R<F]D26^"<FA-23])
+M36$_-C8[+6IF at GIC:F-56UYNB6A86V8I&T5B<4E)2&A;8#DE+3P;-FEI:E at B
+M6H-L338E8H-O/" R539KB&]A25]H6DU%259(6G5Z=TE$,AM)<&-R9C]->H*"
+M:UX!1 %4 /Y]BGUL4&=R<EY9.39$-CEP;FMH:4LM,&N!8V9@)TE)2'(M'5IZ
+M6#E6:GIZ9CX=6I*"<&%)6F)+/EEI6G)R1"5B>W)R338_+2]J<EQ@<FQ@:%IC
+M6#E::5 at _/EII*4E4(")H>G)[<F-H51 at 826),8UQ:<X*%?6MH:G!B7C 8("G^
+M("!)8RTP=V):34E915IQ<EYC8%IK8DA]>VI_=S9K?75Z9C8V6&IH6DE)6#9J
+M;75[;T\V6&%P;'):/TEI:4L^6FM at 8%MA/VA4*2U@,B5M669Q26.#:UDV/%MZ
+M<V8\25 at V/WIN6V%H<&]H6%9 at 6$UJ?7!486DG+VA;7G-;3W*'@G!, 6@!:@#^
+M:X)\:F%::GIR:"<V=$0;-F-:<VYH/R5:>VMK9R4V5#]6&Q at P7T(M6%IK:T0M
+M)5:2BH)H6$D_+39P<#EHBF at 5/FI<;U@^52 @1%@Y6')Z>W)B;&)@7V-:-BU)
+M83])- at X5,$5,4&1U=7<I#B(^5#\G)UIZ=75F:VMN>FM>.R E_CPV6W$\)5A-
+M:$E$/"5+ at W]/.4UB<& G<G-C<G-%;'5R;V at V+3EJ;4Q>24EF8UQ0:F<^)3Y/
+M;&QC238V379W34UJ6G!@8U5B5C8M340R:$M%>W%L at W):24D^6G5Z<G%@1#]F
+M9D]A8W-S;&E68V Y4&IH7EA8539 at 345R<F)F=8*"8P)- /Y%:WIU:UM89()O
+M)2UQ:3LE245K:FM@,E9R8EMK24EA3TD^1#XY-AU)6EAF*2!9:GV%DGI)-B 8
+M)7)W6%N*=RD_84QK;5AA/#Q86#8P7'J*>GIW:W)W;V)+/"U%25A5.3(V*2(^
+M1%IN at V$T("5821L817=N:EY/:&9U;VE4.S;^23YA>F@[-DEW8#L@%2UO>UD@
+M+6!S:#]H:V)J:V%J7U!G5C0E'5,^/DD^-F!H5C1-23 \1%IS<F)653Y%:X-K
+M5F!%:VM/=6I5.R5%,#]Z2S]R>G)]<V-A.QLE:H)]@F-F;VM:7F%C<W5K8T1B
+M<$Q%6UE>/RT_-RTY:W!5.T]F at GR# 5L!.0#^+5AN>FUK8D]M<#\M8H!P/CY)
+M7UI9639-<V]<8DQC=$Q$8FM9+3PM36)621(837)F=9**9RD.#A50 at G)B=8!A
+M8ULO3VIK8SE8;& \&S!S at VYV>FQR>GIR:44E+41@<7!A/RTI-CD_67IR@%4R
+M6&9;1%EZ<FI9-EAO9&9O7E]+_E at Y37ER225$>V at R%1 at M86\\#AL^:W)W>W)J
+M8EYA:DDP:UA85#L[)2U$.S9-:U]%63\G,$E/;'- at -TE)2V.#@FIC86Y[6W)K
+M6D0 at 23(V=6);:6!J>GUQ:44K)4UR>G)C;'-C6V)I;'9U;6,G1')?6F%6338E
+M-S8K+4]Z=5HY8H)0>@%H 38 M1L_<&YF=7IB4& M%3!J@%])5$5%5CX^16)R
+M<E at P37),6&EZ9SLV/F)O5BD5($1R65IZ?7<T PZY-G)Q<GIK8G-C/CE:@&@M
+M3'=B1!@517-R64];<G5U at GA4)3(_86-O8%A$1$M%24QC9H9R2T]K<&IB W*R
+M838P:FA/:W-K85 at V1&MI11LM85A5/#1);V<I#A4R36)ZB7)J8EE>8DLP8$1J
+M=V!A1#8#/]588V=)2U0V-#9%6%!)&R4M/TQQ at FU<;&Y]<H!:860V83X_4&MG
+M=UQ,>FYK:6%$8&EJ;F-><FM;24]A9W)U9F%)8&)-36M at 6TLV7EY$+3EJ at VHE
+M6DEB 6,!+0#^(#!>:$UN at FIB6" .*4EN9$UH138^)TE81%QR8C9)8EIH:W)F
+M84DY8G)C,B Y37IF86EN<V8P#@XM:VUU at G)9:FI8-F%]:T1$@&])'14E3'IL
+M65E;:V9V=TD;("=@6FQ at 6$DV1%EP1#Y, at X-I16MZ<FMK9G=I539C8TMC>WIR
+M_FQ at 6&MP9C0I)2=8:4EC>FD@"1 at I/T1F?7I;34U at 3UA:245G;TQ9<%X_23]:
+M:6!664D_7DE88%]$+3(I-C9$;FI:<W)F=8!/86)6/EA61$E@<6A624E$8%IJ
+M359B6C\M6&AJ:$U%;WIJ=VE8:%])26):6EE):'!8,B58>G<R6();:P%/ 38 
+M_C]+8&Y;3WUR46 \%2U69FI;;F [(!4W7S]);' _1$5C;VI;4&- at 6%IJ;$\V
+M1$ES<V):;'IJ9BL2+6)Z;7EZ:VIO/R)@>EQ>,')J5C)!/"=J<F]H6EM19V(M
+M(" I/DQQ=VE)-BT^?%\E)7*#<CE->G5R:FV"<%XP6%A+:W)M??Z)<EEB>WMF
+M6!@8+4]A<'YP-BDM-EA at 8%!O:UA%6CE/;(-R6D5B:&MH64E,6EM)35HV+5IK
+M<&)B6#!$6%Y56&)98(" 6VIR16]J64E95F!-1&)Z:4E/1$U$<H!J65 at V(#Y8
+M8F]6.6ER8W)Z8EE:23E)/S=89FAR6"48/'-]83Z"3( !6P$V /XY.5EN>VIZ
+M<F)C6C8W/D5R?79K6"LM6&)626IP23<G-E!L6$588G!O6DU-6FI::FI%-D]Z
+M>FI5)3(Y:G]B8GIF;T0I/VIB5C]K>F$M1%8V8'-Z;6)-:')8*2]8;CLP8()Z
+M8$D\.7)C)0Y,=6M)37IZ<F9M at G-K/R4M8'-K6WK^DG=/8WJ"=6Y!&#(M2WIR
+M34E-6&!@8FM at -GIJ36$M-F-Z8TU88F)M>G-Z<&!8/DUF-A at V:WIR8U\^.6!X
+M<'1 at -BUU@G-K<&)R=V):23E6<$DT:G)R:E at M)VJ)@F)654$V/CEC<$U(:UMF
+M>FI6:&@[+4DE16%R>F at E#AUB;GLI at C!R 6,!/P#^*1L^;WR"@GIF:UMA64E%
+M8G6&=4\G/FMS:W!R<F-+/!LV:4TV2W!K;G-))U9Z:E9;1"4V<GU:5"TV6&J 
+M8EMN3UMB7DEK<EE/<GIK7B<P-D]Z at FY@16IZ:"DE19!6&RUR at DPY86A[:24.
+M-G!,.5IZ>W)C7&YL<F$@%3EC:T]J_HJ"6%9J at X-U<$M?7DEH:UA88&MK:&EF
+M:EAR=6MJ.R)%9U9;8FMJ:VMN?8)W:3\_8EX;-F!K=7=L83]/:DU%)3(I375[
+M;V)R at GIN<EXM,&AH-D59;8=6&Q4^@HIZ8F%?8#8B/EIC-%I@:')J66IF23)I
+M/"U)<GUP-!@;/EIN/X(_:P%K 58 _B4K66M]>WUM:&!$6EAC8FERAGU-("U;
+M=6YZ at H)S:F R)6TY%2UA35""9R55=W!%65@\27![;UXR)3EB at G!J9F)07FM)
+M6G5C8GIN8W<V/#(Y@'IC-C9:9G=5)3^";B ;28)P23]BBH%>(!L_)1U@>G=R
+M:V]U=G5F-"LM3VE%1/YZBFDP17Q[=G)I3&)R26%/6UIN<G)I6VIR<WMN8U4;
+M+5E/<GIC8UQ;:WN#?7!86&IF+2U836)X:6)-6FM@)1LV6%I<:F-6:GIR<GIJ
+M8E]B:T0I)4>"5B .&UEZ;6IH47=A/D1):%A63%!B8VEJ3UA8:V$E,&-U<FE5
+M/$UP>UF"87(!:@%$ .X@/VA;@G5]9EQ;3#XV3VE99GUZ6B(5.6)?;H.&@FM-
+M1#)H1!LM/D59>G<V)V!C,$M?65IS=6I:12TE+V9]<FUK3V)B8%IK<'=S7&MU
+M1%Y$,G*":"4;+3)J:5E);'-F)2EK;4D at .8*->EXI&Q45- at -:_F)K>G5Z<DM$
+M24MA65AQ at G V/F-F=6)@)T5P/TE$33]B:W)H:&-R>WUS8S\8&"TP8G)%34U/
+M8W)Z>W=J:G=>,CQ+.45P:UM@:7)P63]/>'-R:F)-7V]J:FM09']Z<E at V-DQN
+M8D(I("U at 3UEM1&-P6U at _67=I239)6&!@,"=A:8]I-"E/8V-K:%E$8W9K<'H!
+M<@%) *0I/VM/;GJ"<F-)/TP^,&-B:FYN3U @.SXV3WJ"AFM%,#]Z;S\#-LTW
+M:GIR1$DY-EAH6F-R<G=N63\M+6-N;F)C6VA:8W!J:G5K3UIH/FEX6F]Z5A at .
+M&#QC:VQ at 6VIW6#9@:C82)V*&C8(\(!TI,CY$/S\T:P-Z_E at P85E)26ER;7IC
+M:6E(9G-9-EEI84U$-BU/8FY%6V]Z=G5U<C88#A at V8W-6/T1::V]B36IW<G!$
+M/U]I-C9<:F)H:V)K=VA18W6$>F(_5FIB65],1W&">GIO:5MF:VA>/"U$.415
+M(C]P8E at V3WQZ<%A98EI@/S)8:W-5*2TY;8EL338;+69P=W0!<@%@ /XM)V)C
+M6FMU?(-K/EA6'3E,<X)N6V%)5DDI-F=UBG)),C9U>F])+1L2/FZ"?U0=/$UB
+M7G)K9GIZ<FQ+-F)N<DQ$-FE at 1&AN at GI064DM)VF(;G6":308&TMK;G)-14QR
+M:%9O=VXT&R=FA85I55]>14]>141$6VYZ@&(E3%I%27#^<E%J8FIX145R:V)K
+M=V]H338E26]A.3!H<FMJ8F)5(!4;26MZ:UD_16N!62DY7')H/S]9=UDV-EY%
+M34DM1&QR82M:?8)K*3]J:%9)245$:GI\@GIK:FIR=$LV-DE at 5!LE6%D^66-\
+M=6MB66]@6F%@:7)[:40@&V!P/Q4."2U;@D5' 7(!8@#^+41O<EE,6VV*<D5)
+M8#8V.6F">G=S<&I at 6%5;9GU[83X^4'I\<%0I&"5BA7UH+39,66-L=VQO<75Z
+M8EAH9F-@/R!%:#E%6H*"1#X\& E$>GI]@WIA)1@^8W)P/C!$<G=:3V)]@%XV
+M17=U;&N 8EE>7CM):&]F:WIR2V!%+3YW_H%N8E%:=V-86GIZ<G]R<F M&#=H
+M24@;/FII:$U%:6,@)6AZ?6L_-C):@F]$-D]O8$E))U]L/"T[254M&!TY:W E
+M-F9_<BTG36]A24E$(DAQ;8)Y;FIJ=WMP5"T_;VT_-DU at -C]C=75B14AC2$UI
+M6G)B8UI>-"!-;U42#A at M38(^)P%, 40 _BD^66MO8G)R>G)H5DU>7#!$@7UN
+M<G5R35MW<&)R=6I:1#]:9&1X83(E36U39VE)8%QK7&MS<G)N;EI0:EI)85XE
+M-FA at 15A[@F at V&R K,&)K>H)Z8S(@)3!@:V8V-FAR9CE$>GV :4]:8G)Z at DTY
+M8$DE&T5R<F9N9FMP11LE1/Y[AG=@6FMH242 @WJ&>G5P1"T_7#M4-BU-:&MA
+M2UIC.2UB at GUK,ALE6()Z:%A;=W-B52 V8$DR+6%U53PM-UMQ7C98:F-),CD^
+M23X^238Y7UEJ;F]H8G)]@&<[-F!G/S9?;U0P:G5R6C ^6$1,7SEH36%%8FE+
+M<7M@*2DR25B"6& !:0%> /Y</S8P.3]R at G)K6TDY8V])+5EZ9EYF:#8Y=8)C
+M36]H6VEA6$4_@'(V-G!C)TAO26MR8UQC7FYR:UI)66-I2V)O0BD^5C9$>H1R
+M1!M862<Y36:"?7)C7D$@/EM at +2)$23\E-FMN<FL\&R=F at X-))UE)*0XE9W)R
+M<&!K>&8[.UGH9X)]<V-:8"4;8']K<GIZ at W)?8$D_6FU?36-O8V%P61T;27)V
+M:3P5%3]W>FI816)P6FEF-EM6/" Y;UM%25AA<6@^-C!::&!4+39%.SE86&!B
+M9FI at 7EEM>H)B84E65BTM6'9G/G&">F(#/HE)8V V5F-?:T<#8HEA6$]@35IB
+M7VL!> &  /YW6TDR$AM@>FQC8#8E6W)P246 :$U08" ;6H)K3U9,37!_<$U/
+M?W<^-FAB25A at 16-K8EI;6VYZ<FI)/DQI8&E[:#LG/BTM<(J"22)-624M26%R
+M=7-R:V$_26%F-BT_/RD5+6)Z>V\M#@XP8GM))4E<,A4 at 6&ER=V-C:VE)3VGV
+M:W5V?'!?52 .+6)H8W-Z>H)R8TD_3VIZ7VMH36%K82D at 6')R:UDR&S9J>FUA
+M6&%;15ES65MH53L\340P+3YC<&M?/S9>8H!O,BDV/TE665IB<G%H6EEB9'EB
+M3$1)1#(M16=,6'*"@FM6+24V8FI:6F):<F-:6 at -BAVAF7$]I:V(!9@%U /Y[
+M<FE$"14V6F)<6CPM26MR<F*"<$Q:8"L2+6-W:& V.5N#>SDV:H!K36!(8&1,
+M8')<:FMC7F9Z<VI$(#EA.6)Z<F-)-B 83(^*<%E+84D_36-H7')Z<F=;66)K
+M6$M96#8I*45R?7<_(" M1&M>+3!>1"DO15M;>G)C8DE%6FOM8F)F>WAK7B 5
+M(%EO8G)R:6!-8%M86FIR:G):/DE18$1):VYK<4]$*39K>G%B8VYA/UAF:5YK
+M6DM88$DV(" _5F-R6V!H36IJ23(V24U624E-9W%Q<FAB6EIR9SDV23PV/TDV
+M36IZ?7)J/R V5 at -:D&)B:FI-6F),3']W:$588VH!8@%F /YR<FM>(!@R/D5:
+M6CXM6&-B:W*#>F%::%DI&#EO7%@[/TUK<BT;-F)R:F ^5F Y6H)J<VQF:T1C
+M;&$^&S]8)4QD;7)I22 .+7EU=G$Y17-P8F)G36)N<FYP;&-C6F%;:'!>,#9B
+M;G)H2UA9:&QH22TR.SQ)6UM,9G5O6$4^6'"\7T5@@()V9U at T,EER:W5K;&A@
+M6EA-3VAM8V-:-BTM-C)6@&)>=T0M("5@<FYI6F%A6%MC8W)Z8#8Y:6$_ R"7
+M,%I at 1&=K8"T8&#M;;G)L85A)245B<$D#/Z=%66A;6%AA85QZ<$]$:W5;3&-8
+M6"TI/EIC7T1$8$PV)UI><&E64&T!<@%B *]Q8EIB.Q@[6#!$22TE7FE/3'N"
+M>FI::W))("UO6C8^6&!03#LR)2]-6DUA8VE:3 1R_EQK36-K8%4R-EXM8%MB
+M:FQ)& XB6DU;51T_>GQF6FU at 8%QB<'A[8U])86%B>W)</TE-8V=H<F-R<FIB
+M52 5+6AI:%@_<FI+63\P;V at _37M]?7IR7D5+241B:UY::V8V)2E)<F)K:%0[
+M*14 at 17IF9HA@*Q@@6GI[<%M%245:<<U(:GIO+1L^6$LM*2LG640P6G)A-Q at 8
+M+6%]=FYP:5Y)-D5R<$LV/DDV-CX_6GAX8VMK7BTY;GMP8UE)/#1$86=8+3EB
+M240V+1U-?V)-9@&" 68 IH%H4&%$-DE8.3LR&"!)6CDG<(I\8EAR>FDV.6A:
+M+39C=V8^,$D[ R74+6%J<'MI36)N>W)L6FIZ:V _/UE)8&-K:VI)& DR7BTM
+M( D_<FU6.6)C8EPY:7=Z:UE5:7!P:EQZ:$0[2UIC>F9>>FIN<#D.)6)O:%D_
+M:V P22T2 TG^66EK=G)[=V)A/QLV36!?67<\(!@B8F)R>FA>*0X at 26QC:GIO
+M-B V:7N">FA:23\Y6V-A=W-5-#E8638V539+,A)%:V-%,!TE16MR8EA at 8F)R
+M<6UW8S8V52T5("4P:GUZ=6YW/AM,BHI[<%I865IN<F ^/F!-87!+("5B:#8Y
+M 7L!=@#)@G)B/UA;:&MI62T8-#E;5B)@B8IO6G*(=F!:6UDR+6F#>F _-DDT
+M'0X;24Q:>H5:/UZ#>G)B:WIU:TQ%541836!R>FA>,C]H)0,)_B)B?V Y7V)H
+M:$E89G)?,$EI8&-O4&]O/S1+6F^#:%MR:W)K.Q@@1&-I3UYC6# V(!@E&R(^
+M8VQH3W6)>UE$(!4M;FE;8EPG#@Y636=J4&M5&"!88%I-<F,M)55R<G5Z>W!A
+M84E%:G![B&]@6&!?-BU<6E at 8#B5 at 8FEA1#0G1(]J34U at 9FIR;VAN<UE>63D#
+M&*(I1&)B7&MS5!4G9&UV>W)K;VMN=FIB6D5$38!K5#)$7R(M 6(!;0#):V-R
+M7S]->GQS8EA$6#!$;"(P;8)Z8&-]9D5K>E at M($F"<G)P63XR#@D at 0B=);H6*
+M:W)]>F9B;'IF>GI@,"=;4QU->F!R;H!H( ,5_B V:X!C8$5%;G!%8'%8,DEC
+M6$QWB'IK1" M/V-[8#E::WIO/"D^6$589&-P6F!85#(T*2D2,&-,/DV"?VE5
+M( XE<(5P6V!>.Q at M66--,%A>&Q@\66)@=TLE(#MC8V)R>VM><FDP8F)R at GIR
+M9EIM,C9F85E$1#Q$6G)K:54E+9M-,#YB8VUR9F)8:VMP;$DG%0XT8$TY.5IB
+M530#+99%=W9N:6M><FY_<D14.VMW6V%R:T0V 4D!6P#^33Y'8SXY<G)C<&)@
+M:$U5:#]$6V):6WN"8SE@>EHV-DER;FYJ:50K"14G+15)6V: =85]<69F>W)9
+M:8)W/B!62"5):DAC6WIP,C \.RLE37MB63\^9F\^6'!H1%E at 8VAF@X):/CDE
+M.UAF6"TM17)S52 Y;T4_:FYZ36-P3SX__C\[*RU).S(\;FUP62<8+6:#=UI;
+M6&!!%3Y925EA:%4\1$UJ8F Y6#PT.45:<G-B37J 6$]:6EQ;;U\_6"TG6FMH
+M8%A>7DQS8W-4&Q at M239-:FYN8F958VAR<VDV(!(T;%L^6F-98V-5*Q@;5G)L
+M4&)L:VU]<DQC6$UJ6EQZ=H)I10$P 5L _EXM&UAB6W!-,&!J8EI,;')-3'I-
+M)S9K=6-$:')B6%E<<GIJ8EIF/!@G," .*38^35N(>F)<:W)R;VYR:V!83UMH
+M8FIB<&IJ7&T_/U at R($V :DU:36MI.S]@=5 at V,$UP2')[-B(V)2U)8$DT+55L
+M at 6]$27)9+4ELBD5%;5HV1?Y-3%Y$/TE$.6](:&!$1#YJ at X)L8F)R;#Q+6$1-
+M6UIO:FE::&@V&TE>+2 V6')P6SEF at VM@7&A%/UAH65A",C]C=T at Y3W M8F-O
+M51 at 2*5HM-F)Y;UYK3TU9:7-[6#0G-&%;.6J!;'-R9CP@%39R<UI<<G5[?6([
+M644[6UMC9G6"=7,!8 %9 /Y8.Q)$>F9B/C]$8&!,16-R3"EZ83(W26-/2W!K
+M8FIK:F]Z;6I/:$D8&" 8%2 V1!LM>WI96G!/9GQU63]B>UA-<UI::G*$>EIJ
+M53Y:/!LP<FIJ9TQ:8SXE.7=P/BU$8V. @U4I+3(B.6\^(!LY:X!B8GAZ9RTE
+M285?.6))*4G^6T=B9E5964]P6$P^1&A836YZ=VMJ<W=H35M)56!%8WIZ9F9I
+M-BE)6$0R.UAW8V%H<GMN<FIJ6$U:8FQC8#X_66I8-DE924]C6D4T("U:-B5%
+M at GIB8E5$.4]N at W!+23E8239BC8.#@G-A3R4V:W)G8FY[:X-G16D_/V)K9EY<
+M at E%R 7(!30#^/QL.+7)R6D1 at 669@2S9$<F])>FI%24E9-C!<:F-R:UIJ>GIK
+M8VU9/#)$1#0T25P2(&IW2&)]6F)Z<F@^068^1']H/TU9;8*";UQ)540K*6!:
+M9F]@:6A4,#):8E5886!>@HER/B4\*25C10X.%4E-+41Z>F<M%2=J:UIO824V
+M_F!@65I-24U+:G=@23EC=TDR/VMR9EYN=TA-63YA26%N at G!:63]A?4E+7C]H
+M=V)@9G*#>G: <V!@7TQF<G!?66%J85A+6%E96TDV-"4_8#8;+6I]<F)%6#LP
+M6GIZ:T\P23LE18R,AGUS8UHT,EA<9F)<:%9U9S]B.3E6=VIL:8)%6@%J 5L 
+MZE at I&"5B7&)-66-Q;'!--EJ"@WUK23\V23DI.6)C<W-K:GJ#8V)P8UE@:F]I
+M7VI6#B5?<DM'<F-C:FUS=UM8&RUW>F):7V)LC'I:6%A)1$EC<&]K8G!P8%59
+M9D1@:G);3'J2BF\\1$0P6C0##OX5%0XV>GIB1#1$:%E88W%)/D]I5EIO6$5)
+M1VYR6#]:>F\I%2U96#D_=E8^6"TV3VQJ>GIM/REB?TT_:3Y$<F)-6VZ#<F-Z
+M@&=-1"E,<WIK8&%;:6- at 6UA@6$D\+2U)6C8E*4QJ at VM%/C8@,&MV;FD_1"D@
+M+8*-A8-S8UI864^36FIF35IF:FIC9CX=)6MK<W=-3 )K *EB7C(R6#=913E8
+M6V!R<S\G8HI];EM/1#]$.S=A;FQR;69Z>F)%6DE%<@."GVMR;1L_3&)I.5 at Y
+M3V!B=8-S7 at D816YW8V-H3WIS14P#6/Y at 67)R7UER<F);:6 at V7WJ":4UZDI)Z
+M645927 V,#D@#@D.-H*":DE+<8-96&-J;V](83DY>'!%16A9:VEH:FUZ5"<@
+M+5I3/F)-154M%2U,6G)S;S8I8FDM,'%8+4D^-%]F<EM)46UW8S\E.6QZ>FM@
+M8%]O<&!88UDV-C(V8&*R/D1$-C)J8U at R,BLI369N<G!)$A(I;85U?7Y at 36MQ
+M2$U>8UI8:G5F at G5<+1LP47IS33D!:P%R (1U<FA$ UK^545$&RU:<F$B.7I\
+M;G=P8U4M)2 ^;UI at 9F:#9FA8+14E67IZ?7)D<B4M/UAB23LE)3M$6X)N7SDI
+M-G=N<EE)650E%4UK8F%K8VMC:UER6DD^85DR376%<EYNBH9U8%A827=:6GA5
+M(!4.*7!Z8T5)<H9H,#)@9GIK9RDE3%\G^2!W1#EGB8I]>W!F-C9;:T5H8EI@
+M-BLT+3Y68F \26!@)25B9BTG1$]F>H!R8$UB<G!9/$MB;7MR:EMA8F)C6&MA
+M,A@@-FAK8%MH2S(^6V<R-#PV/UA)16MN01T;3VM1>XIC16:">FMC8S P<GID
+M<F9I850V7V]:25@!8P%V +)Z>W=H9FI985 at M$B V26-$,&)M<GIN<& T%3))
+M6$U)67)U35A8%0X5,%A>9EH_7V8^- at -:_DDI%24M27IR6$L_6')Z:F ^13X8
+M#BU?4%!J9GAR<7=O:%XV-CPI-EMU;F-D?8)R:VMI16MM<G)Q64$P+6!F6TE;
+M=WUW239;8G5K;%A635 at M(%PV&SEZA7Q]>G=886QJ/V)O4&-%25LV24DW/S8V
+M3VE5-EA-+25):6YVB8)P3,M-8VA)/DUI:G=R8T]W:4]C:7IL11 at 5+6!B:')P
+M<%8^3&I/568\+3\W+3EL=U4[3TU9>HIP35QVA7UZ;#PE;()U=7-O8DE):G!)
+M/DT!7 %R /Y9=VIF>FI;:& M("D at -F ^)3Y,<WUN<F R%3Y@/DE826MJ2454
+M%0X at +4598F)6175S25AI8UE)-C9$6'=W6TE)6FYU:F-823\5"1 at _2S8W6GI<
+M8WMF:W=>-D0\)4QJ1UIJ;6)><G)H36MU=V-P<%A>7V!-6SY/>GUR<%A;;'K^
+M<F9R<FE:53)551LE6G5T;F9Z;&MR:D0W=W)C8VM86&!8-BTV+2U-:5EA-BU5
+M86IB4'J%>U8^65A)56%B66I_8TUP:V)B:X*#21 at .+5MC6V%KA7Y]@V9-24PV
+M)3<V*25/>WA:.2]B at WYU6EIJ<(9];6E)9W5M;7UZ63)I>FHV at C9? 6(!9P#^
+M17!<2')K<&MC5CY)-DEC6DD^+6-[;7!-*2!)9#X_7EIL3TE)8#\R4%Q;86)J
+M=TURBF)'<&YC:%9)6$QO=V)824]R=FM;:6%)*0D.+44@&U9J/UJ!:6)R6#!;
+M:#9$6D1$65L^-&MJ8&-[<6):;'!,6F- at 8%L[6'5[8')C15J!_G)13&U[:U@;
+M-E4[-DEH:FMC<VMD=6\^'5]R8VIS6EIR:TDE*3(;-E at _3S(V6X%_:UIF at X!-
+M-DE8/TU at 838R:EM$<&]B6V-Z>E at E'3Q at 8%I96WN&AXIW8V!;2S9>7D0M.6Z#
+M:B4;,GIR:V-H6UQ]?5QB6'=F:VY]>DPK8WEG+8(G60%J 5\ _DUN<UI:8W)N
+M;G=I359H:VMJ5B4Y:V-K6T0V5F]<26%I<FI at 6GIP3$EO7&-:87(^48)R2&IL
+M8VMF8G!:67IO6EA;=GIK:&IP8EXP&" I("!)8RTP=UA68U at M26IP8VAH8%E8
+M/C!;8T]C?6!%36)K8DE)/UIJ3%IM>6-B8#E9>_YK.2E%<G]F,C8^14DV.5M9
+M8W=B8G)J8#8V1$Q:8F-K=7)O53(I(#QF138E-C]H@()B6GJ"5ATP7&!).5E5
+M/UA5+7)R6DU1;61O83P^7T]-/CE-=8V*<EM96EE):'!8,B58>G<R&"EB3#E+
+M6F!;<H-Z6T58-V)S;G5J36)D83:"+4T!6@%$ /XV9GUN.6!R:U![<E at V6FN 
+M?6,V,&-K9F%,/TEB;VMB<FMM<EIR?6(P3TU88&MK-B=F<F!B8UYR>F)W6#!B
+M:%E:6FYU9FMK;GIK7CL@)3PV6W$\)5A)6&%C24EKBGIK>G]N:TDE2&-:8G5I
+M/SE,:FI6/RE$<EM88G)O8U at Y6H#^:SLE+5E[<EMB7F!@.R<[-CEJ:UIH/V)P
+M1"U)245;=W5C=WQ@/C(G6V!$)3(M+5QZ8TU/<E8;(%9K:# V6$M at 859Z<T5/
+M6FA$67-X85M8:%@T+5IZAGII/S=89FAR6"48/'-]84E5440E+3])3U!Z at EI5
+M-B4^7$=F>GAR5EA$@BUF 5@!'0#^+5IZ>C P4&I%6EQF)2TY>HIR63E08EE;
+M34L_1&)P7&=13W)B3VYR23\^/UER;UM)35QJ8$E(:G)N@&$V25M-5EIN:EY/
+M:&9U;VE4.S9)/F%Z:#LV6V-:8&!8:HAS3&*"@GII.S!89W)U:4DV,&!H:%4M
+M+V!;15MK:6);8W)Z_G)@/#Q/9W)J;FEI<F9$-B4E36QC24EP9SXV9EA$3VMS
+M8FYW3&%K,#EA6#]!("4^8&]I35E)(!4^=W=$+3 V6&-H<FD_26%825IM?7)R
+M87!C53=/:WUR:4DE16%R>F at E#AUB;GMZ>V-)/#9).6EI;'HY+3(R25I)16:"
+M at G=H-H(=6 %A 24 FEAK:FY at 2UAJ8V]J:#LI)5EU>G)85F)B6T5- V#^8F)K
+M3UAJ<F)J;DU6224P:'IO<FM9:FI-/T1$7'MZ:6MB23E)<FI9-EAO9&9O7E]+
+M6#E->7)))4UB7T])37*(<# Y<WJ"@VDV.6:"=7=)+3)834U at 6#XY345J:E9$
+M6FI_;75J84U86EMB<&-F=W=K1" 8*4]?1%A_<D0M8$DPXTLY8G)R8RD^=TDG
+M35 at _53(T1#Y:<&)H5BL.+7" :38E-#EB<&)?/S]824]C;FUQ<FEC8T]+66-N
+M8EQI/"U)<GUP-!@;/EIN?8IX8#]+/R);<VIK)0XM+4507SEB at H5]<C\@/P%J
+M 6$ \X)]:EEH8$UJ9G5Z:V!)56!967IJ:&-P8#8M8G)U9F)R:$E9;G)K:F)A
+M-A451')N=7I:8G> <$D\/W)U=7)D23\_<G)A-C!J:$]K<VMA6#9$:VE%&V)H
+M8%@_.5QZ<F!+8&)Z at VL_)3]U<GEH/BU8/RT_6TD#+==B@"TG7V!-3X!R6TUK
+M=V$Y:&]J<GIW6T0@'2U66FM_=FE8:44V53(V=W]9)QM@;4186T5F1$EH35!L
+M;VYB1"LT3'!P1"4T/%!W;FI$/TD_15IK:G)[>F,#6ZYI8FM836MA)3!C=7)I
+M53Q-<'N%C7AC145>/%MJ2"T.#CX\/SDM,&*"A7%R8U4_ 3D!:P#^=8)W6F-6
+M-V)U;FYF;U]-8VQ/56IO6F-B-AM$:FUK669Q5E]P:VA/:G [#@XE245G=TQ)
+M9H:(:%8Y:'IR>G(V/UYF=VE5-F-C2V-[>G)L8%AK<&8T1$U-26!@3&M9<GQG
+M36MK9&E:/TQF=75J6%M82UEH840E$CEJ/R Y1!LG_F]R.3!?@W _/UMB=7IZ
+M:F$T&" V36N <FMC:TDV/"DE:HIO.Q at P8&E]:3EJ;VEP6$]:6H)K13<V1&AW
+M82DM14ES>GII8TE$,"]65EQVBG)C:VMR;FI836EI-"E/8V-K:%E$8W:-DH!O
+M33E-6&-0.3D=#CY@=38)%3E[A6YB38)).P$= 3\ BVIU<F- at 14E:=75Z W+^
+M1%AP:2(Y8TE9:UH[6%EJ?V)J<E9'6VIP145K9RD=.SLE/U\G-FIZ>FD^&T5K
+M6W)M/C8_;8)P7C!86$MK<FU]B7)98GM[9DDY+25);UIP8FV(>F-K6C]R>FDV
+M/TUR at V]A8%MA8V]@/" M,F)$.3PK+5MW+1 at P<G5>,$E:<GIZ\G)R52 @&RU6
+M:VYM<W!9/SP;&T>%>EHT)2U);G V1&UO8#E)5B]R:UDT&RU$8F]5)2TG8G)U
+M?7I at 638@+3(V:XV#8F9N<FYZ8V%K<U4I+3EM;$TV&RUFAI*- at VH_-EIS84EA
+M00X;.6I<(!L_<H-U9S8E.P%4 4D WF)K3V=),&EK9G)Z?7UF85MR>R5!21TY
+M;6MH3T1/>GIY>FIF5FI[:3!;<DDM.4DR($DR&V%O6CXR($1 at 15IB340M;8)S
+M:S\E+6!S:UMZDG=/8WJ"=5H^( XE7U9-8&($<OYA.5MR:DDR(DAZ:V)K8DA:
+M<G=;3S\Y8& _3UXV7X!N1#9C<G M15EU<F):;FY$/#(K16!18W)O.2U>,CQB
+M?8)P/CD@)4UW23!?8CX;.6D_6V _-"<I-C9%9C08)4E?:GI]6V-8.RTE,F)U
+M at UQ9>W5N<T5;<GMI1" ;8' _%0Z>"2UL?'!]@F,V17AR34AF("4I,G1>&S!9
+M;75W21LV 6 !1P#^1%I$6E at M36IJ9&AUBEQC9G*"14A8*2)8:FA8.4UZ?'5]
+M at G);6X*(7UEC8F!68VXE/CP;.6I9/#(V9F))/DEB23]<;FQR82 5.6-K3VJ*
+M at EA6:H.#82TG%2UM/C!).2<^;WIP25A::F$_*39F8FMK:4U;<GIJ:FAC8UHB
+M,$0P_DUZ>F Y66MP-#]B=6MA6$]C8%9A-#9-24UH6"T8:5]I:VIR at T0R&Q@^
+M:EA6:&([&S9P6%A>-BT\1%4^.6%$)41$8&IR;EIP6S8I&S9 at 7&Y,2&YN:W M
+M.6)C6EXT($UO51()#B!,6T]4>G(Y+6M]6TUR1#8M-FAR62M86F9Z<H)/: %J
+M 4P _D187"]W8E]B:V)3>H9:/V)Z=58P/BD8275:/CE%>GM(4'MR8EIU at G)C
+M3V%B6&IR-DA$.SY9:F0I-G=R6TD^6#D_:W)S<F8T*RU/:45$>HII,$5\>U@;
+M*1 at E9#X^6#P8&V!Z>G!H6F)I2V9 at 7EIA8FEJ<GMZ<G)Q@&M)&!@;&_XY<F(Y
+M,#E?<%A):7]R:VMI8D5-<EXI.5A8:$DE(')Z<FA,4(AW1"D;26A?:H-J23Q@
+M<FIQ83\\.T]I23]-1!LM56AR<EHY:T\M&!4M341:15EL8V-P23]-845B:4MQ
+M>V @%2!5:5I8.6)R5#9C?6Q%:V$Y*5A6<G))6%E;<X2"=WH!>@%H /)'5DD;
+M<G5B65YK7&9U<U9%:WUJ150E#C9R=SDE,&M_23!B8F-R=7IR:DU-14EC8S9:
+M:&EI3V)W6#!J:UA%23XV/V)R=75P2T1)2V%96'&"<#8^8V9)*2 8*58V:6I)
+M("UG=7IN8VEA8#9@:F!,23E)66T#>OYM<H6"8S(=#A at _:V)$/CDY7V);9GIK
+M67&(=UI;:G!>2TE)84D@#FF$@G))-VN*:#LM26!@9GIJ3%MP>FZ!<TD[/T5I
+M2S!+/RLM6&EW@$U+84LT("M$2SDV.6!N:F-R:4]>84E:<&9Z?6@\-%B#>V-C
+M7E%R9SE1<G=;44TY)SZ+.4QH6&)H3%Z#>GH!@@%R /YB8$DE6FIJ6EAK<F)9
+M:&))6X)R:FA$&QM:>E\R&SEB/BU88&IM>G5F=7))16EP6S9$<FUW5C=K8V-R
+M:DD^/S995D5F<GIZ6#!A64E):7)M>F-I:4 at _9FLV-E@V8&!)+45R>H)G26-J
+M8SY$;TTM25XM+45N=6Y9;GB*<U at K("#^5G=B:&);65A-6V=K8DQF at H)U<G)F
+M9F)?6&-5& Y- at HIU7BU)@F\Y,C9)7W=R8$QJ<VYF:7)A-CPM6%@E,BTV7F8V
+M6GIP<FI9/C]>:6E>-C]C8D0Y=7=)6%I)6%IF at GUN6S9/BGM1;&M16V)>25MR
+M:U at _3$M97E8_.6N"6S]B at F-; 6L!<@#^<G)H6FAJ8V9R<G5F6%A-.6.'9EQ0
+M:#(@.6)17"4R/B451&IB47IZ8FQJ3$EP<&I$,F)N=U\^33]B<GIB6%A%:6-)
+M6VYZ@&(E3%I%27!R46IB:GA%*6* :#X_24U)/E1H<FUR5CQB<G)B35I$&RU8
+M1#8P6G%B3&!NB7MI238M_C]H8V-H359:-DAK<F%97FY]=6Z%>V9B6UM9/!@.
+M-GI]:FE83X)R138E.59J:U]6:FMC;UA9:$E$-EA at .RDR.TE?+39H;UMN:V!9
+M8VMR:5E)8$\;&V)R2$DW+3E%6FUP:U _17U[2&-R:V!<:&EH<G!-8#8Y;7)H
+M(B5CBG59/H)$/@$P 6, VW)Z:F)K<F-B;G)R:V!)+14Y>F)H8F)).S]-3VE)
+M/CPI(#9O:$5R at H)U:$E):VIJ:39$<H9R:V at P25YJ:V-82UMB:&]F:WIR2V!%
+M+3YW at 6YB45IW8S1A>H!J34T#28M8>GIR8S8I6&IR8P-8S40M+38V1&-C:EI:
+M8W5R:&!825Y:8&)K23 ^.RU$:FE866)Z:UQ]>F- at 6$D_+2 5(FMZ;VM)*7* 
+M:E\_/DU:6EA at 8V-I<E9,<&E886Q@ S_"24U8/$E96%EH<FYW:F)J:W!A32T=
+M&TUR13LK*S=88F-C6S\_36Y\6$5O6DEC:&)G;G%97!L;26%(#A)%@GUR/BTE
+M 24!5@#^:VM)-FN(;TU86UA+66E>-B56>EXV/SP[.S8V;G=C7FY5-DU@:G)<
+M3%AS6"TW65MJ8!LM:FYB:E!)/T]K:V _/V!%<G)F;F9K<$4;)41[AG=@6FMH
+M9FMP7S\I+45B:E]).4E:<W)H8%A)24UC>VM:36IK4&E:8V):65A:8V-8_F)0
+M8()K1%!88SL at -C(Y8G!K65IF855+23\V/T0K&!M?<3])2%A0>FMC9F-8:&-A
+M8%@_+5IR:W!J:5D_8%M:6EMC>FEA34Q;9FIR;FQ%46]H23M$8V-S:54M04E)
+M1&EL:3\V36-P22=-/S!::VIK8TU::6$V16M8+6!]>GIP2X(V/ $K 3\ _G)L
+M63YG?7IL6DE%-C]K:388(F)N.UE at 86%5)3YH141C;V=+36IZ8TU:>FDE+59A
+M:5@@)6N#BG=8*2U9=W)@24EH)6=R<G!@:WAF.SM99X)]<V-:8#E$:VDM#A at V
+M9G)C32U%64EB;7II23])8W5Z8F)J:DQI8EI/6F%)35IC;/YB23]J<F9O>')9
+M,BT\-C!R?6MJ9F-B6S\[/T]C1 X.-F-)/TM8369K:W)K8V-R:6-8,A at M3V-R
+M:V-/26MN8UYC9FYN:U at V+4QB:F!I/SYH:5 at V/X"">WMI-CEI22=%:VE)/T^#
+M=V%9:5D_36-G:T4G36Q[8V9J6UEL>GV"<$2"/%D!20%A /YX8$]N<G5V?7)@
+M6$0V<WA)*2M)33!I:F9[=#Q$/RT_9VYS:UIR at VLY.69]/T1>:VMA,"E?@HV 
+M51@@67)C:5E;:2!8:7)W8V-K:4E/:6MU=GQP7U5+/EIH/SE$25IC9F(I+38;
+M/FM]<UL_/V)]>EI,<FYC<GII145P83E)37KK@&,Y6F9>;7UZ:D<_52(;6G9R
+M<G-[>EL^2UM@:EDG#B!)23];:6%:9FYU<FMB9G)S;DDK&"5+;&-92UE\>F-/
+M6V)J;GIO/R4^6&)/144_86E%-D1ZAV]Z=ED^=W T/VE;15DY=7)86FMC:5 #
+M8)([&"U(?8!S=GIG8UIR>F,_.6 !6@%I /YW86)R=FYR=7)Z=TD;;W=@/F!A
+M-B568UMZ?W%C/QLE26MR9EMRAG V-EMR:UMJ<G)H1$1K at XZ#82M%7V)B:6-K
+M:S=%6UMZ<F-B245::V)B9GMX:UYI6&!S:W-K8$]L<V)91" .-G-V<F(Y/FA^
+M at DDP8WIS8V)T.R5H=TU/26G^A',_16->6VUZ6UM)3#=$8VYN=75]BF]%26-K
+M8UIN/!LR+3Q96VA@:7-F>H)K7&=R>VDY&!(\;&A86V%[@F,V5&%-8GM[8#))
+M65E$/$4_258I%2]Z?%MF<&-8>GMA66M/16M93TPY/F!:7U5-14EC*Q at E3WUM
+M;8)N8&!99ED\@BU6 3\!6@#^8F9R=79C:6-:7'I4$EE]6T5;<5E):VA(<GU]
+MB5DK%2E%:VIB=8-O1%I:4'!@6G!R:#\Y:H:&<D4W:6E/2')O<GI)6UM,9G5O
+M6$4^6'!?36)Z at G9G8V-K:F9R<F-)4&-$>W B#BUK<FYJ/BU,>H)-+41Z=UY:
+M9S8 at 16-'65AK_G)V:45,9FM:83),6$L_6FQJ;G5V=8)Z8UE;8V-8>F\M*1 at E
+M/SE-37!R6FMU=6MF:X!R+0X.+5I:16MK=7I:/EEA2TU]?5II<G!I/#99:6A$
+M& X237-%25E%8'9N<VMH6UER at W Y-C!86UDE+3P^8UY!*REB:F)H=69?.4UP
+M6((M/P$R 3  _F%K?&YR:&QP:6MW7A at Y?W _27%I3&IM16I[<))Z5!LK+3E8
+M<7J#8D5/13]::$E-8VE9.6"#BF,V)UEK8$UB7&U\:&EH6#]R:DM9/S!O9TE8
+M>GI]>DQ(:V]B7&IS8S8P)WMU/!@M;'IU9DT[.6=Z1#9)8FMC:V]<545835MG
+M>OYN:W!:24QW;&%+6&->*3E>:V-N=7)]@F]A/EI;8'*#63LE*2DM/DEJ:V-C
+M9G)K<W)Z<RD.%1 at V.RU;4%!K345C:6%9?75%:FYR:#8R6'J)51 at 5&TUS23 V
+M)59[<F-C<&MK;7V$638_65H_("4T15M0;V8T.6AK7FYQ6RTY<W&"1"T!-@$^
+M ,Q@;H)V;FQF>H!V@&,8&UAI-C!:@&]::$U:=U&&BG@\+2T;)6."B%I'6V%%
+M8&M),$5I83];>GYW7BU)8FAA6TQ?<F)O:%D_:V P22T2 TGB66EK=G)C6UYK
+M:$U0<G Y-S9R;FDM)5AZ at W-A3SE:>DP^54Q:;')F66$Y85I(:WIN<FM-/SEA
+M8W!J;VI,,B4Y;VMN<FY]BG)@-D5/37)U7EE)12LK/TM at 6G)Q3UIR at WMQ<#P#
+M(,HO-RU8,")$24U:8W%R?79;:VIJ8"TE.76*<#PT,DUW:308&#YR;F!B;VIR
+M:FV&=$M8:6$V-#0K+4DY3'-5-DQB<7-L841+=X)N/ $; 38 _C=R>G-C34]]
+MAG9]<#PI.5]0)2]Z@&-C6V)H6'IZ=FA>-A at 8/WJ"6C]0=%MW>V M,&%;-D5K
+M;GIX/S]):5I-23EB1&-I3UYC6# V+24I)24^8VQH3W5Z:U%B:%AI8CYA;VYF
+M:DDE/VN*@F-B3%YZ:EA)25YJ;G)>12)>8$QJ<OYF;7=;240V.6Q@:VI-52 ;
+M3&)B<VY\AW)6/S])16)U6VEC63P\65Y).7)W63]K at H9U7%98/RLR559-*1(I
+M-EE915IN?7MK<G)C6B .&TAZ=VEA84UR;%4@(#]B:VAC8F9W<W)U@%M:>W<^
+M/EE%-CX_26YX84E0>GIF6T]I<WV">V$!& $5 ,LM:FYK22<P=XI]?7MI7C9%
+M6"TG:FM@<&=01%EX8U8Y66XT(#]K<CDV.6AH at HIM*39F6C\E3UMR>$DV-F%)
+M.3L=-EA%6&1C<%I at 340$-OXE.6-,/FUU>DU%6T]A33E@<GIJ:F$_.4EU at F99
+M8WN#<DTO.V%T>H-[6"T_6$UR;EI9<FI(22TR86)B3TUP)0XB+31J>G5]>EI;
+M85 at V86M@:V-%239%83\;3&IH-DQR>'5;4&MF/"U/=4\M&!@W9E5%1%!U=FMR
+M<F)@,B K3V^Q:W)R;5M<:TU$/$E:66)H6UQK9V]K<DU%<H%86&QP6DEA:6I]
+M<3Y-<G)F:45;<FEZ:@$K 1T VD5;:FM$&"EK at G5]>V9H-CYI24EI341UB&D^
+M1VMN-!L^?V8_36IH/S8M/DAZAW(_2VEB12 M16.$<%4V13]57BTV,%9N<DUC
+M;T166T]%3&MB3')[359K3U at R+0-R_F%-35@^/VAC8FUK<G=B6'N*;DDE&S!B
+M?8:*:V%8141N>F<_6GI9.2T_5%MB6#EZ12L5%1M$;5Q;>F)>=V V8F!C:V))
+M5#\[65D@(DEI239;<G):36MP239%@$D=("E+;4]524QB<GIN<EY18%Y@:G!B
+M9G)Z8V%C.55 at 2U@^1*-66EEC3&)R:SDM8G-/8GN#:$5F at G)N<CY,8U]$8"TP
+M6V-W=@$M 30 _F9C8VM+("UK>G9P=VQ8*2]O<%II-B)BBGIN;UM8)2MHA7=A
+M8'!J9U4K-C]J<EQ%36]J6S(;&#E\A'<_,#=/838I+41:9CEC9V)J:V,V-EQB
+M26MR:UIB35 at _27IZ@W!-85M%/V!8.6)F>GIH27**=5I$)1LY9'6&>EIA845B
+MAOYZ341J:54V2U1-8&D[<GAF.R Y25M$)V)B47-O-F)P:6)::6E/2V-L-B!8
+M:FE)3V)T345>;D\_6H)6%14M8%8P26%;8%QF;'M-.5!F9FQR:EQ::FMI8#9-
+M=6--/SE%/DE@/TUN:$D[.T at P4'V#<T5:=7)V>V$_6V _3"TE16.":FH!-P$_
+M /YK:W%@-B4M3VM[8TAJ61 at 53()S624;5G5V<H)_51(E:W5S6TUL<FMB83YO
+M;UY/655;>&$R&!4[8GB*:3]/;&E%-#Q68&-I6F)G:G)K3UA<8EMK6EA86TU8
+M-EAN=8AB-&-P6$E//B4P1'J :TE:@G5523Y86%%F;V=%37=6*WW^?')O6D5A
+M84U:3'-R24QK<V-$6F--6%]:8FQJ:B=:;GI).6MS8UYS=$4;3()R3$5::DE+
+M<&Y at 65I]8!(.&#\[("5,:&- at 8%YZ:T\[16-R>G5C7UIC6TL_.75[:UI+6EE+
+M34],:6-I9BT@($5J=GMS8UI(>GUW36-R<VE)25E>@FY[ 5H!8 #^:6-W<#XE
+M-EA-<G%,8D4=&#9R:DDI-EI<6U%UC6X8&#EB:6)C:VIC36DV7&I-8V8Y-EYI
+M,A4E6%!Z?7)C;'IJ<BT^:6]B>F--8VMK8UYB:G)I8SD_6VAB8C8Y16:#8#!B
+M<FML:$DR"1MJB7)).75J/S!A8EE@>W)C3T]J21M<_G5T>V)A:&,_64AN=U at G
+M369 at 6&-;,#!C:G)Z=U8R16)W22U-:VYC;&L\#C9U:CE%6%\P.7)C66QJ<V,T
+M%25)254T26)A1%AL;6YZ8DE-:H:";%M;8TTP+2)B at G)F6%IC:5MA66!A;&(M
+M("!)35MF>W183':"@&-RB'IB6&EI48)/8@%: 6H _EI;>WIO3V%A16-W7F at V
+M(" _<6M6-$EI3S8G67UX12 ;-D]:<G)>6D]O6%9H6%YS65Y:;S\8-FA:;U!<
+M=VYW:W4^-DUO3&YB141B<FIB7U!Z>F ^/W=O:VM8+1L_>' Y8G5D<G),, at D8
+M68)W6SEC8CXV6G!:37IR345K>G!)1.I<=7A,35!P7UI;:W5:-D5 at 6%IJ8S8V
+M3VMU?7=)-C];<EE)25IJ9FI-&S!)<V at Y6&-C53]C13!:<H-S<3PV6#M+86)B
+M6"4B3&MZ at G)I.4A]?6]/6&M:,BTV8WUZ:$0Y8G%L8V9L:G)B+2TT!#^2;GI;
+M8X)V=F-NA7<_/TUN<4DO 44!:@#^,#YR;6UJ>FLY6G=C33\I*3YC6E0M.69A
+M1"DY:F9T-" E+39K>UM$:W)R3&)P86MQ<&)R9RT_=W)C-C1K<VQR<F!86VE)
+M:V9-14QK:F)H169Z3"TM;V)B7F @&"5-8UAN:D]F at ELV&"!@>G=$/UI/,$UI
+M;&A::$PG'5J"<VM)_EER;E at V-F-J8VAR@G _7EI$36MO/BU/=W)N>U at M-EMR
+M4%EC8V)C8408+5MZ=UE:6V-Q8V,_("=0?8-\8U9:.3]S:UI9, X;7'I]@&,_
+M.4AB>EI98&%)+3E1:G)L)QM$>H%J:VQJ=6 at _1%98,"TE16);9WMS9EYR?7))
+M6%M<=8)W6 $Y 6  _B4M1450;8!O.4UR;%M9/RTV1#\_+3YK=U at _27!B:UXR
+M("LV:H)I26MZ=5E@<VQC:VE-4&A/67. :T0M37)K:G)O<GI[8FIJ7U at Y6F%B
+M;TA(=38.&SEJ6%M;1&YF)25BBG(_:H5Z<#8M67I[8$5;8#8V1&)W<EXM%1 at Y
+M:UIC6^QR;FMB53]-:VIB<GIZ26-C1$]B324E27-R:WMP.R!):4188V1K8F%I
+M/"E-<WMP:V%B:W-S63PI+6N">VA18DLY8V%%3S<.#C9PBH9J6UXP57IK:&-P
+M83LP24106AL.'6*#>FI<:G5<26%I:40#/Y$Y.7!R>EM(<WUF4')[8EQK;P%-
+M 5@ _D4V/#1)8F9R6&QN:V%@84MA24E4(!U%>&)),')_:VE5*RU)8WIZ>'M[
+M<$E-<VMI44U9,#!8;W9[<FA5-T]A1&)D>H6#<F9Q:F-/6"]%;V)B:U0P("!B
+M7UXV.7MB&Q4W=6]':&AU?4DM35QV at 3E;:V-5+3=R at V,_1$196V!C:OYU:F);
+M8FM19FI:7G)]<G-C36QA'1 at 8-G%<4'IV4$EO=UA-86I<67)S8RU$9FYJ>X!R
+M8V9[<EA$15AN>UM/:&):8UI83S0@)R\Y=HEP<&D_3&M;:VM[@6D_24E+/A at .
+M&S]N<G)/8W9 at 26!K8F%A8VDR'45F=TU-<G)$076*@%N"/UH!8@%P /Y9-D4_
+M6F],66)Z;E!J<5MB>F)C9#0=-G=O339O@&YC:4E$/U!C<G6"<EA)36M[:U at _
+M53 E6&YV<FIK6EAA12=84&Z AGUN@'MN:V@[-EY9:G=C8402:UY)&RUC- at D.
+M'6IZ8W!$68A+/%M:<()93&Z"=U at R3'ER<&E)/CEA<&;^<$=B<5M<8V];1#]>
+M=89Z:S]F6 X5*S]J6D1K:UQ(>H)R8&]P.3)K<FI$,%AB6G:#>V-:>GIK85A8
+M7F(Y1&-J:F%6:VD^*418-DQK8VMO:6IA86Q1<H)Z:$UB:5 at T-#)):%I:6U%N
+M<&%:6$1-6VN!9C(I8W(Y17IH-F&#@))W at C P 3\!:P#^/S958&ER9C]$=VM$
+M7&DM,'=\6U at V*TN#=U at Y<WI>6EIH<4E%:7)N?7-%63E(?7-P83X@&TEZ at W);
+M7T5;>& Y6&);=7A]9G9]?75R9SY)-&-R8F%$%6]@2QL_:$0G'1MBBGU[85B"
+M/S9A<'J#22<R>HIN845<<G5W6CLE1'):_F,O3(!S8V)K6D0R,&9\;FIB8UDK
+M*4EP:VE98$EK6W9U>FMZ>TDY8UM)-BU)6$US?7UR:FIB7&E>?&Q9.45-67)6
+M.6)022U9:V9-3$5C8UXV:&M6159)+T5K:FM;655)3VMP.3\_2&ML6UD_+2(P
+M<GMA-CE)*3!R22)BB&YT at X)C.P$E 6  _C\\7V-S<VE)8'QS:F)@)1A,B&%%
+M(!LY>H=@,&IR85I%6X%/.6MR<X>#8E\W27!F<&$I#@XM8GIZ8V!%8X)K3V-R
+M9E-<@EQB9GIU?'I90BU;<EIH8#9W6TP^8(" :R4)-GI]=G)B at UDP.6IZ:S8;
+M)5YZ:F(V27MZ<DU+16!J1?Y8.3EZ?7)B33E)52U-=6IC6UE-+2U%6V-O8TDM
+M8VMV>GIJ;GM:67)C-BDP,D0_8W)]@G9S:UA at 47)R6#9$545R:$5-/CDM37)S
+M8T5$6TTP-EQP;%H_.39%<F]N6UM925A0=3XE-C9C:UI89BD.$CER=G%)/" M
+M:382.6IZ?8:"<E@!,@%@ /Y816E;:X%/.6*#=GMI6#8\6X-P-A at 8-GN-;#]A
+M:%I,7V-K6#]K:F:*CW)I/V!A2'%A*148+4UJ:VMH.4U[<%A-:F9 at 375K8EQF
+M6X*"<%I);V],36A>8EL^86QN?'<\("U:>GIF8G=Q351L<V at M&"!)66-)&RUI
+M=FM-6&-R:DW^;3D=4&UR<$D at +5@M-FIN<UM at 8#E>85I-7&A>+5AR;FV"9&9Z
+M8#EF<CXM,BTM.SE1>X9R<GIB8VEB8TDI67%/9W)L:TD_/SEB<FM-5F Y(#Y$
+M8UYB124_169U>F);639)6VMA-TMA<W=K7&D[&!4E6X.1;%88+6%9*SYCBHV*
+M at GML 4T!8@#^:5ML36:#2S9J at VY]<UA)6G=[<$DK*3]Z?6M;84U at 16)J:DDT
+M8VA/>HUV:#E,1#!I8T0@(#]I<TU(<V9%8W=),$Q;<GIV=6YK6DUR<F]B9')G
+M.5A:8DU)(C]O<F9W3S9+36V#<F9M=TTY:7)H/"D8,C]-/QLE66-;84UK<FI-
+M_F98-%919W-I54M-+25B;GIL8EHY:V-?241 at 824Y8G)U at EY0;F,M16))2S8T
+M("D;)V)]<F)U<VMR:T4V)6B"4$UB at W)A86-<6G)R6F-R7C]?6&MC6S\@+3];
+MAH9R3&-)16]R8S]/:V)K;FMK83P8&T5ZDH)A)2UH<%E)8H.%AH)]@0%A 5L 
+M_EM;<'-Z=TE9>H)N?'9 at 7EEJ<FY06#Q%8VM-6EHY6&%B9G!+'4UH.6:1 at F M
+M+55)86MF-B V8W<V)5IO6UMP6# ^5FIZ>G)F:F)-8F)@6F)J21M)84QR<D0E
+M8GMR<DTV/RTO:G)<8')L8&A:8V9F1"U)85\\+4E)15A(:V9>8_UB6EEK8&-F
+M<W)T:#8 at 3VQ[=6M-.6ID3S8M.6$_-#!9?8)N:W!C2TE;36%+1"TI("!-8&MH
+M:FQS>FLM%25C>FI)17-R8V-J:EEH9FMK<FI at 8EIK<VQ).RT=.8:"@EM;.2UG
+M;%D_3ULY.4UB:VM>&!(M7&YZ;#]):FYI8$UF>@-] 7(!80"O3TQO>G]@+3M>
+M at GUN:V);7EIJ;%M at 6D]86DE,8#X^6W)L9E45+5PY6H.*<"4;2W #=_YC/#=C
+M>EDT/DU;:6]A23966FMK1"TY6H**@FA823\M-G!P.6B*:!4^:EQO6#Y5("!$
+M6#E8<GI[<F)L:6II-CE-3S\[.3 V/D1L:UQW=FI;4$AH8F-L?6Y+("U@>GIJ
+M34]R<F@\("E86UDR.7*">G)P9F!-7UIK:4DM,CD_:6++8G)I6G)U:"TE16-F
+M>V%)36--6'!M6UI$:GMP3TUB:UMB<F!5630M?69J<G [&SYJ:UAB6S(R-CEB
+M:44@&"5)6')J14UC8EM8/U%S WT!>@%J )!;1&%T;#XE*3!U at F!C:45F!&N:
+M<7)K7#D_6&X^+3]::TA5-#0_-D5F<'<E&TL#<OYI858Y8X.!<%\^375Z:ELI
+M25I89BD at 66I]A9)Z238@&"5R=UA;BG<I/V%,:VU883P\6%@V,%QZBGIZ<F-K
+M:F-C6UDV/DD[-BT^8FM9@(:#=%@^6%I:<H)N8T0;28"";$5;;FYH12DI25YR
+M2S]P=G)N;&M:2$Q$8FM@/S9)6FN$8U!B; -BR&-4/FAB7GIW6#\[+4UW9G-K
+M3V=V@&!/9G)K6G)R36!A7X)8,EIB22 M:X)P9F<^+38=254E.40_64]P8C8P
+M6EDM-EA at 35YU?0&# 74 L'MC26%+&Q at I/WAM6F9M+4ES<VQI:VYL6C8V27!8
+M/S9%6D589FE$-D5B8U8@&S]S7 at -;_F V-F:$>W=A6W5[8UHM36)621(837)F
+M=9**9RD.#A50 at G)B=8!A8ULO3VIK8SE8;& \&S!S at VYV>FIK:V-J:V-8/UA8
+M53]5:$TO<H6&>F%913E$;'IU8DD2+6:":C]B<FY at .S(T/TA<33!C9FI:4&]%
+M-DE+84]:6#];8&!A5LU9:EM)35AB8VA:85IM=TD@%3EO.6)R9FEF<F-I;&MK
+M:G)S33]%<(IK-S8I(!4 at 37*"<FIF3U0[1$LW/TMA8UEB83\G1"T.($58+3!;
+M:P%] 8( SY)[86 _&!45+7%:3&9W23YI>G)O<EQC33LM-F-I;F%C6C\Y6FI9
+M/VV ARD8)3]1.2<V8W!)(#!R8F9O8VYZ>W<^8F]6*14 at 1')96GI]=S0##OXV
+M<G%R>FMB<V,^.5J :"U,=V)$&!5%<W)96UEK:U%$:U!)/CY58UI0;ELM:HA\
+M7EMJ6!LB7V!J8E at K($1Y;EM>>FMI23([.T1:6EA>6FI:,%@V*39%;U]$2TE-
+M34E,34]Q2RTV84UK8V-P/U%P+0X.+6 V.4QB:6E-16MH16VN;6IZ:SE:=V--
+M/RDI/F-:5"TY<FQR=8-X3TE823E;:5AA84E)7BL.&RU8024M, %K 8H _HV"
+M<F=9*Q at .(%MP:%AK83]-<7IZ at GM;6D0R-EAJ;W!R<&%$8W)83W**D#8T27%A
+M-A@;8&Q$(#)I8#]:3411;H,Y8G)C,B Y37IF86EN<V8P#@XM:VUU at G)9:FI8
+M-F%]:T1$@&])'14E3'IK6DUB:TTY;TPP)S)):VA(:FLV3?Z#=4U)6VLV-E]B
+M6TAC;38V:69K;GIB7&Y+/C9%8V9S;U" >F-N9BDV17)825MQ:$D^23XG7T0M
+M+4E%8FQC6EAP<40@'31>8%M;8EII-BU68#9%4&V ;SE-<FQ;63\M-D0_/RT^
+M8EYN=9"";G!I6#E/6$E;8#E)=U at K*TMI:3R"& X!/P&" /Y]=7%H9C\K&"E)
+M9F]9.458/EIF<G:*<&!>/S9)8FIR<WIW6&IK6FAC=8-/65][=$0I+5MH/R R
+M6G=;6UXV,$AF6%IJ;$\V1$ES<V):;'IJ9BL2+6)Z;7EZ:VIO/R)@>EQ>,')J
+M5C)!/"=B:V!-8&]:16I:+2 V3W=[:&!:)S#^<G!$25AC6EIR<FLW6WLV)U4Y
+M4%!J:UMK8DTV15I<<H!:9GUG;F at _-D5Z6C8W;H!P25E$,EA$-UE)1%EZ=T5%
+M8G):1#L_6%M:8W-:3#]$6&8M-$EB9FI;8VYK86!A2V%)250@'5A/:G"&A&MV
+MA&Q)65 at _14T_27IH-BU%<H!5@@X. 3\!=0#^>VYL:'%F1"DK6&-C<"4=1$E)
+M8FA0;FQJ84D_65IB>&YZAW!L;$]H;'=^6V$Y6W=I2V%P=UDI-D5R<F-I7E5)
+M8'!O6DU-6FI::FI%-D]Z>FI5)3(Y:G]B8GIF;T0I/VIB5C]K>F$M1%8^6FEC
+M35AZ8$UC32TI/TAQ at G=F8395_G)N/T1 at 6UA08F9R:&.#7BU)2UL_.7%R:UI9
+M6$U-.4V";EIF;EYC6$0G;F V,EAW:V)B6V!H3#YI83XT8FI:3TQJ345)/TU%
+M36!S<DQ6/DE;5C]:;UE:8G)K4&IQ6V)Z8F-D-!TY)TE>>H--4XJ"8F- at 23L_
+M26F#;$DE,&M[/((.#@%6 74 _GIK6$5B>%H[/UAC86M>54M at 8$AO6#]-<&$\
+M*6EF7EIF at WUN8W=J8EEK at F-F,C96:6F!<G)I25A+8H!L8V)I8W%K;G-))U9Z
+M:E9;1"4V<GU:5"TV6&J 8EMN3UMB7DEK<EE/<GIK7B<P-D]H8TE)>G)R:C8;
+M&S8V8HIZ7FEA8_Y_=T]@6F%835I>:G)DA75:6VEO1")$<7-:15E-839$>H)B
+M4$U at 6TUN7EI--BU;?V);645%6EDP2VQ>-CE$86A-35A+6$E8-C!):GIR:DL_
+M6%A@:7)A35IR:T1<:2TP=WQ;6#8K52 @5GIZ14U]>G)R;6DM545K at VM)&SYX
+M>DF"&!@!1 %J /Y[;$0;,'-P64LP6W=K:7%@369)36 at _-F%$)2U965 at _6W)K
+M:&%J>G P.7-W<$LM.5A;9W)C3UMI/V)Z<EH^3%YR35""9R55=W!%65@\27![
+M;UXR)3EB at G!J9F)07FM)6G5C8GIN8W<V/#9)<FM-5G)Z?7I>*R M.UIV at F9K
+M;E[^8D at P8TUC8%M/6F)J<FYZ;F)S<VQ)169[6DE$16I/:6IZ;F,Y26A%7GMZ
+M<3\;-GIC8%@[)3!H23!R>FE++3Y86#Y$538P<CXR-F%B;(!81#])8W-S:4M@
+M>'-J8EDM)4R(844@*40I&#ER<F9R>FM-7G-P&RTP8X)K1!A)@XIQ at EA% 4D!
+M7P#^<G R$AU9:F-A1#EB8G=O5DE:6#E)8&%>,A at M8%@^/UA at -D5G6G)P/"5'
+M at W)P2S98<&-A84E09C]:8E8Y*2E/6TU;>G<V)V!C,$M?65IS=6I:12TE+V9]
+M<FUK3V)B8%IK<'=S7&MU1%Y$16MR1$1F=76&8S\_.UEK<GUR;GUI_D0V-D]5
+M14U:8V)B:&!K<FI(<FYJ8$U:;FIP5CE)6W)R>G)A.4EO63]:>H)M($AS9D5B
+M<$4Y6%@[>XIZ:UY51$LM)2T2&V)@-AM$23]W8UE)/UMK at 5@^8H-V>VE8-CQA
+M=VD\("E4,B4M3VIF at 8-P.3YR>BL8&UM_6T0I)V*(@X*"@ %/ 4@ DFIK+2<E
+M-C!%8$D;&QUU=6-A8P-9_FAW:"D at -&-O8$18/!@E2UEP:U at E-G-S>W _5G)\
+M:4U:344_:6 ^)14I25@^1&IZ<D1).398:%IC<G)W;ED_+2UC;FYB8UMH6F-P
+M:FIU:T]::#YI>%IO>CXM8FI1=4PV6#8_8&YZ?6YX<D5+:6YA,$5/25]M>FMJ
+M<FIA:W)J8NM at 6"]$=8=8+4]U at GUZ6CY-<F(_-FMZ:R4E6F];6VM8.4E%67V-
+M>F)W<&)I1"D2(#Q9;U0;-FE;:VQC6#E-9H-+-FJ#;GUS64E8<'-K23(T854W
+M/$U96GJ$<S8 at 4'5$& XY:E at V1"DG4'*2D@%L 5$ BE!S6%Y>52DM6#L##OYJ
+M<FYZ at 6$_.6)08#LI+41J=V- at 1"T\56AW<EXE-VMR?7)A8UMF>V);/RTP<'55
+M& X;1$DM&SYN at G]4'3Q-8EYR:V9Z>G)L2S9B;G),1#9I8$1H;H)Z4%E)+2=I
+MB&YU at DD26G)>3"<E23LR14UF>VUN<CDM8G=8*2TV&SYK?7KS17-K8EQN<FAC
+M5BDM1WIR+4QM?7IR345;>F-+/V-U84$T/DU;:6]A23DG3W6*=EQV<F-S:54K
+M,E9B;V%$6'IR:5M-+1MS>G=)67)];GQV8%Y9:FYK6E@\<G=>16-B66Y[<$DI
+M.6A))PXV:6$M1#P5&T1]D@%[ 4\ _DUL<%MA:5Q)83\@'15C8F-Z at G!826U-
+M/RT\1"U(:W-R63]86%YS>V,V55YZ at FM;<5M$<HAZ83\M<H%8$@X5/F$K("5B
+MA7UH+39,66-L=VQO<75Z8EAH9F-@/R!%:#E%6H*"1#X\& E$>GI]@S8E6WIR
+M6"4 at 1%A6/CM:=5Q9?_Y+*45P+5E$( XV<W9R/VAP8EIK;F-96EY>36IB+6=W
+M>G5B1$UH:DU$86]R6E9P7SY-=7IJ6S8R/VI]?6MM<F)[<F8\-DE9:3\V6F)R
+M>G!)*R!Z?V P/UYU=6YK8EM>6FIL6V!:.6AN26)Z:V9Z>FA)/UE)*0XE6FDV
+M-CX5&"6"67T!@@%; /YC>G=A3V-O8VE%+3(8/SY0<H!S:VER:T0E/V8_.6!R
+M=G!96DU-8W)I87$_7'J 47)N/TAZA'!-176"81T.&"U)2S8V36U39VE)8%QK
+M7&MS<G)N;EI0:EI)85XE-FA at 15A[@F at V&R K,&)K>H(V-FN">F,[%399<%I)
+M87)C1'+>8S8^:#)[<"(.+6MR;F!H:UMC:VUI2#YC>G)@/B5B=7UR33)%<&L^
+M-F)Z>V!)>W=A6W5[8UHY9DE,;H)U:F)(:VY;65E;8%@V+3DP3&MR8UY5=&P^
+M)2U):G)J8VA%9 at 1KGG%R&T5H,#EZ=5QN?7)B24]))0X826$M(AL;.458;@&#
+M 7, _G)Z at GAH8W-S?&A81"D@/DU-;7IR>GIR6#=)<V$V6')V>G!@255%3$U-
+M<E at Y7(!W<G=))5!\<#D_=8-X1#1$-C]@/SYH8R=(;TEK<F-<8UYN<FM:25EC
+M:4MB;T(I/E8V1'J$<D0;6%DG.4UF at E4P8X)]:DD2&SY[;V%C<F]-6_Y;/DEH
+M9GMU/!@M;'IU:FQK8VAR9F)))TQ]>W V+6)V at GM6.T1B;T0V3')R:%AB9F]C
+M;GI[=R)86"U9=72!:UIK8C):8VIK6$E<6$M88$Q9<'AA2QL8*3]C:&)F;2U)
+M<W-L:6M at -C)F+1U9:EIB=G-I6%E4*1 at K87)A1" ;/VF"<FL!=@%W /YR=GI[
+M<F9R=H-R<G0[&#9)35MK<GJ#<F!+6&-9-CMB<GU[85E9-BTM,&);/SEB=UEI
+M5"!$<G-,/VJ">F%9>&99:$E%:&))6&!%8VMB6EM;;GIR:DD^3&E@:7MH.R<^
+M+2UPBH))(DU9)2U)87)B/F-]>FYH*14T8F9K;G5U:%O^8%98:7-R;FDM)5AZ
+M?5Q-:V: ?6I:239-:W)R251B:WV";VAK8VM-241K8EI)8#]:3411;H,[26$V
+M2V]J<F)8;&(P16)F<F--84U::5DG)UE[8#\8%14V86!-9G=)/FEZ<G)O6C8[
+M<%D_6'!H:7!K:UMI83PR/VAW:V-;&RUC at G)S 6P!8P#^67)J<W);:W=[9FV(
+M62 [-DU,36MN=FYL85M;3S\W16J*>D]-8E4R+55Q3S<I.6]@84L;)VM[<$EO
+M at FQ6-&-Q:W)H6%I(8&1,8')<:FMC7F9Z<VI$(#EA.6)Z<F-)-B 83(^*<%E+
+M84D_36-H6C]-<FIR<$DG.V9'66]Z=G5L_F-A9FEK;F9J225):W9:-D10=8)R
+M6TU98&-G<EMI8F!B?&EMB'IR6F-S:6%)-G=;6UXV,$AF:6AI;&IR;&M-3&)P
+M644Y1')W8F-%.5@^& X=1&=9*Q at .(%AO:%AK83]-:G9V<F,M*6MC3U%U=GM\
+M=W)K=V!%6&!98FA<;2T;28)J>@%O 4@ F4MB34QR8DAG<G![>FM5/!L@(#]A
+M2#E%<F,#6/X_,ATY:X!8,#]N83=C>D]$/TEC>WU9(!M:>G=-<HES8#8Y8VMB
+M;V):159 at .5J":G-L9FM$8VQA/AL_6"5,9&UR:4D@#BUY=79Q.45S<&)B9T5G
+M3UEB;7)926!R7CQ)6#E'>G)K<FQC<FIF841%6FMC/C ^8G%U8EE;3U9-8FSD
+M8F-:<'MK6VYP=3E, at F%8.5AR<F-I7E5-6UI%;GIV;G)B/RU)@')8.QLY?7)L
+M6DE9+2 G%1MH9C\K&"E)8FM at 2458/EIF<G)P*QM66"4;.5]R?(!K;G,_,&-R
+M6TL^,%@^+2T^:@%W 5@ R6]J245K<$U/:VMN:6!B9CPP&S]W32TP8$LV16MI
+M/R4E16]I2S!F>&EL=FE815MG>F]%.T1I<FM-<HI[8E at _/U at O35I-86-I6DP$
+M<OY<:TUC:V!5,C9>+6!;8FIL21 at .(EI-6U4=/WI\9EI at 6& Y+5IZ<EMA=WIC
+M6UY$(BE'8UIJ8TU85E9C8$U:8FM;.41H<G)J<&)91#Y9:V-:3&YU<FM%6G5N
+M8'5%-D5;8H!L8V)A8VE+/UI]>F-I6CLE27=U;VXV+6]K;%M0;42S)T0P&VAQ
+M9D0I*TEA8V!)/D5)26)C8F-$.UAC& D8+4UN?WIN8TE+9VI><%@\1$M5/"5%
+M 7(!8@#!<VM,87=L86%X<45%34]C2UM537IA-DE9+2 V at X%M530V6%E96')X
+M=VYK<%H_6UMM9RTM5G!R32=X>G=:3&AA338#+?YA:G![:4UB;GMR;%IJ>FM@
+M/S]926!C:VMJ21@),EXM+2 )/W)M6DU:6%@M&T5R9DUC<H)<2&@^("TY245/
+M3"U%8FYF6#8M-F)C238_3&-Z=7=C+1LV:&(E37=:8'<Y1&"#B6XV+6%C8GIR
+M6CY,6VI-/V.$@FM/138V6F9K=W*\.39P<F]I67IU2UY>.T5B>%H[/UA at 8V->
+M6$M at 8$AI6TU915EP.QT=(#),<HA\3TEW>G)R>FE5/SYI:#Y8 5@!4 #C<$4P
+M8X!B6GN*@UD^25AA15AA3&MI6%A$%0X;@8J"=V$_-BDV88B"=7)F:T\^83]-
+M<$DM/VIO-AMP at WA-.6ER6#8@&RE)3%IZA5H_7H-Z<F)K>G5K3$551%A-8')Z
+M:%XR/V at E PG^(F)_8$5835 at R*41J2%A:8H)O6EH^-C])24U/22DR3VMO8$0R
+M-$U-13P;&S]Z=7IR1!@@6V @17)@6F at Y16!V>V(E+6A96F)6.2DI3ULY6'"#
+MA8);26!88&!><V@^.6MK6UIP<GI\<G!?&S!S<%E+.5MK:VEQ8$UF24UH/VM)
+MFD5K7BDK)RTP6X-Z5EES;G)N at WM@/R=J<TE% 44!80#C<40;.7)I37*-BF]6
+M7$E::5E,6&!L<5M5)PX@>H:*@W=9*0X5.8*,A'UK8$M9639);&A987%O2R5O
+M>G-96&-F8#8@&"!")TENA8IK<GUZ9F)L>F9Z>F P)UM3'4UZ8')N@&@@ Q7^
+M(#9K@&- at 25E)-DE?1$M,68-P;&M)56%C8TD_:5P\1&-Z<F!)/S8R)2D.#B)0
+M>H)Z8$$[4& V8'=C6F V)UIU<ED;*59):6 ^)14I25 at M37=;9(A,/G-Z:&%1
+M:FE86FZ"8#E:;FMS9E\Y$AU9:F-A1#]/8')O5DE:6#E)8')LFF%J<3(I*38\
+M6WIR3&ER<&AB=HIZ6#9C=V _ 2T!7@#^<5@;(&)P.4^&CG),14M:=VE+14]I
+M:U9-/!@86G)U?8%F( D)(FN,A8-R8%EA8F!;8TU-;(*"8T5H8F)I<VMC6#08
+M%2<M%4E;9H!UA7UQ9F9[<EEI at G<^(%9()4EJ2&-;>G R,#P[*R5->V)86$E@
+M241-15E%18B*;F-(25MRX')@.5!I345H<G)B8ED^(!@5%1TR1%IZB%DV8&M-
+M6&N">FI98#9,;FMI/UYH37!U51 at .&T1)/EEJ,#=O/B)CBGQU8&-K13M$>G(V
+M27-K:UH_+2LE-C!%8$0E)39J=6-A8P-9G6AJ<G!S?6E!)2TY8WMR8&%9445%
+M6GV#:EAB<G!+ 2T!3P#^<VT;&$5H85ERBGI8/$E$:X)C,$]Q8TU)/S0R.5A>
+M9G-@& D))7"*?'UZ245C9FIJ:38M7H*&:T5)/TMF>FM:6#P8)S @#BDV/DU;
+MB'IB7&MR<F]N<FM at 6$];:&)J8G!J:EQM/S]8,B!-@&I-/S!85C8M/V Y)W**
+M>G)8.3]L]&UR;DE;645::FM[<FE)-#DP(#150D5RAT0B6'I%6FAN<GIM:FAC
+M8DAO15AT8'*!6!(.%3YA/V)F53E>1!4Y>H""<6-8+14;36\^88*"<V [*T19
+M52DM6#L@("U:<FYZ at 6$_.6);8V)R?75>,B =2'*">G-F S:)1')[:V-B8VQ%
+M 3P!3P#^:VI>03]97V. ?6YI85M84&II-DUI6DU$2UE925E:8G)N-C0@)6*#
+M at G)W6#Y/345:<"T;67U];TTR)39J at W=),DD8&" 8%2 V1!LM>WI96G!/9GQU
+M63]B>UA-<UI::G*$>EIJ53Y:/!LP<FIJ.R5$6"T;-FAA/EIR7'IH/C9-_D]J
+M<FMI6C\Y35Q[A7IB5EE$&R5).4MZB#D;26M-6DQ-3&I;<G:$:C]B/RU,<G6"
+M81T.&"U)-FUW:UI)6#8_8VU]?8-K*148-D158GQ]>V]$+5EA:%Q)83\I("E)
+M6V-Z at G!826UP33ENAVUB/SP at +41NAH-W8&$^-EEB15IO8X)@-@%) 6D _DUB
+M=W%)13YB>G5K<G=C:V)O:%E at 6SXM/%E-6C V8&%F<#]+1"5$<G)F=&EI6#\G
+M/EX;&#EJ<G!>540V8XB 83]9/#)$1#0T25P2(&IW2&)]6F)Z<F@^068^1']H
+M/TU9;8*";UQ)6$4@*6!:9CXI25@@$BE(;'!><DAQ<D5)6-0_3%EJ=V(_-CE-
+M9G5U9W!O:#0;-BU)=H9A*3Y;5F-;85MB3'=]AGM;6E@[.6IU at WA$-$0V/QM,
+M>G5O1%9%6'!H4%R*BF9%,B4E6&=M9G=V6#9;6V,#:*E)-#(I/CY0<H!S:VER
+M;V _7G]:6F!8654^36Z$<V=W8$MA6T]><FI-&P$^ 5H _CE%<G];/B))8E!:
+M<GIW<F9S8UIH8"T;+5E at 83XM.6EK;$M87C9):V$Y7'IU8EDV/E@\-C]-6EY9
+M8& P2&YR8G=C66!J;VE?:E8.)5]R2T=R8V-J;7-W6U@;+7=Z8EIB9FJ,>EI8
+M7DE526-P;S8\7F$T&"4B2&I-:U!G<E]B8OYA6#Y9<VD^-DEG3TAB7F]B:4DK
+M)2 V:G5R84E at 8&-;6UA,.7*"@G);8V-F6&E;:5]6854\*RDM3'IZ6E at M1')R
+M,#!R?')K8"4 at 6&IO4'*#<UAS:6EL<G-H6$0I(#Y-36UZ<GIZ8F-C;&]%.596
+M8VE;6$Q[<V. @5M98UIK>G*"62 !+0$^ /Y$-TQR840@)TDY.5IR:FUV>W)>
+M:VA5,BT_6FIA,B5-<VMA86E@:'A@(#")>F))6&!@:7%I24M;2V-H,$ER63)R
+M<EYJ:6-[8#9((B),<G):25MP.45;6FM:36-I8G)K<FI%.45B9W5;8H:":S\M
+M-F!;238[/$]:6FM$26)C:F+^:G)/16)C/R4V8T\V-D5?6F--1"D5,F)J7&A$
+M6G)J8D1823!J=7I[4%!C:&MK:FI?;W->/UYM.QU@?7<_&S9B9C8V<&9B6' V
+M(#E?9S9-<GYZ>W)F:W-[<G)T.Q at V24U;:W)Z at V)K;'-I538M6'!W<V%-<G-6
+M<H5K6V!,:VQG at FE5 38!.P#^;V),8V]@7CXV2UA96TUK=7Q[:VEJ<&E>26)<
+M8S8I-F!:8FAQ9FZ"<3LM at 8-R3T5,8&IZ=TU-;UMJ:4]:>F8M3&MC8G)R=6MA
+M7C0T-D]O:EI,=TPM36)B6E%B<TU%2&IR8#];6TUB1#EMBH!--RU/6$D^25MP
+M8V: :#\Y8X)8_EIF:VMJ8E$E-F)I22TV6&%H6%@T$BU86E9,-C!M<V\V-EA@
+M:F)R?69::$Q;8F9N:%MR:#!%<F88+6J(/Q4I25E98X%S:$A9/BDR25 at P16)F
+M;G-R7&MW>V9MB%D at .S9-3$UK;G9P:W)R8V$[(CEB=8-R6%A[:6]R:G=J:W!;
+M8()B8@%9 5H _G5Z:%QR7FA>,%N!>V$P6FYZ?6)/36N"=UMJ<DLW/%5>.41K
+M<V)>>W=A17*#=6$^/EA:;G=-36);9UM)269Q7D5(8EIB<FMB8%%?6$DY7')R
+M6FI8)3!B:&-I8VQ913!-7()N<D\V6$U$:W6":#<[65M)/CE)<&='>G-)'5N*
+M8OY$1V9Z;6MC+3]B<7)8-E5(6FMK5B R9FMH6"TI6WMW22U%:VA$8GIN;&)@
+M35I-8V]$4&\V-F]M&Q)$=4DR56!H5F-R>H)R6$DM/TU8-D5;3%!9<F-/9W)P
+M>WIK53P;(" _84 at Y8UMW>F)A52DM-F*%@VEB>G5V:UIC9G-P6VR":$0!80%C
+M /YB9FYR<EI821LY at X9K6&%J;FYB23Y:=WIR<GM$+55 at 7C\^8WIP6W)R8V-K
+M>W)B/UAA36IP36!;8&E;8&%>:V-A16!).4]R8U8^6&!%+45J=7)G6S\R1&MF
+M8F9N8E8^-D5]?79H14]C:WAR?7A)-FAP34E)1&EO.6IZ-QM)@EO^6D]-:DQ9
+M>S _:WQZ:S!>/B=:;7(M-FEM;VA)/$UZ@&D\/&%C24AK8UY$:6%)*V-G/D5O
+M24EK9AL8/W5;36EP;TA%.4=ZA7IO/TE6/S(Y6EMI36ML34]K:VYI8&)F/# ;
+M/W=-+3\V8W)-15E%*1 at P;H)L:WIN>G);6$QH:6%K at G V 3X!30"O6F-!8WQ-
+M-BD8,'* 9FMK=7)B9V%)65E<<FI at 7B5"8%A)/TQU;EIC8$1K8W)J;V #8_YZ
+M<V!C8VAC8W)[;FE-8FEA22TE<FM-)S]U6"TM3&YZ8EI-3S]96D5$;&)9/S8V
+M6FYF8EM,8FYN at GV":TUB<F):8%EB:#]/>U\G8')':F)%6#8^;CLP7(*";#!H
+M1!@E38!),&IR8EQ at 33]B<G!8/T1H8U!B:V at V26E>.5E;24G.:%IG<FM$-EIK
+M:6QC:G)B9BTB6FQ]>F!B6"TI-EIF>F-Q:V%A>'%%14U/8TM;54UZ838M)4E;
+M/S<_2S8.&$5B15MR9GIR:&);66%A8W)H 3X!- #^,#X8*W=C/" 8&U![8V)B
+M=7IK;VM-/S]86SXP8"DK/SX_-CEJ<TQ8:$]@86EI8F)H.4V">EE(8V]R<GIV
+M;7A:45E/640\@GI@)2=G8"T;-GJ"/SE)6%A::%8Y34QA6$1)1%A/1TDR3TQB
+M>F1N<EEC7&MC3&N#7"=)<G);<&A)_F)<35@^/V@[)41V?6-6=UD2&$1Z<EEB
+M;V-%658^.4QA8# =1&-J8G)W-CEC>&A)-DM at 6EIR>FQR84U83&=937)R<V0V
+M6$U0=75Z;SPR+45N<VAW8F)[BH-9/DE8845884QK:5 at V("U923]%13L8&$M:
+M+3!(15!K:UY;2&!N:X)R<P%W 3\ _C\@%2UK=UA$'0XG:W)I6F=W=75Z6CY)
+M:F]F6T\R*T1+539)8W)%/F9W85A;<FMB/Q at E;W(_)4UK:WR$<V!Z<EI)14E)
+M1&YZ;SDM1388%2E<?4DM25E?8V9C8UDP:7I:34UB:5M@/S\V3'-07%Q-13!-
+M.2=BBF(;-DQ-:VY-5OY-1V%;13]@/C);=6T^;WIJ*1(E4'J 8F-I/SE-8%E9
+M8FM$.S]::V)B<C\V2'MR21M$<%E%<GIF<FI/6$E56#E0>GIR:6):669Z>FI8
+M1"\V8W)@:&-1<HV*;U9<25II64Q88&QQ22 @/V!:8&8_&QM9:4D[24D^6V-:
+M6T5'9UR"<6<!>@%\ /YI/"LV86M95C(8)4]K:V%:8FY^@%I)2VY[>H!C539%
+M86%886EP539::V-816-S;S88)6%O/!4I/SEF at H-]<G-F6%A-3UAJ>GIK85@;
+M#B=<:W5H/EYB;W)K7F96&T1U=69/4%M%.4E-,$1J:4\Y22T5*1 at 5.75W-C\^
+M)T=01%;^34UC<%A)3SE88G);'6M];E at I("UGBG9L:38E-FA::')Z;V=86VUW
+M<F,_66%W<EXE-F-C8'J":V9H:6!-8&E/2')Z:WIR25MS>W5R6$E)-EMI6%MC
+M35F&CG),14M:=VE+14]I:VL[("5%6&)]62LE:7!+6#\V.6EH14Q%1$Q8 at FE;
+M 6,!@@"]>F at R+4U:6T]5-#0^:6]B6DU9<GM9,BUB at GJ#7F)M/C9%65MI:V!/
+M8VIB:3])8W-I141C<%XR&R4E.5IF>P-C UO^66!K?7UZ<V(I&"E::FI:1$5,
+M;H-Z:EM-1$]R?6YR83DP-CY6/E9::FA8654;'1T at +4QH24]A6%A)-D1-36)R
+M:VQH-CY845DM:GIF33]$/T5R<FMH)1 at E6$UB:F9R<F-O;7)R63]W<FIN8U4\
+M/DEB>HZ*=6MS<%M):'1,:&UCO7)[6REC at WIR63E>56!H6UM at 65ARBGI8/$E$
+M:X)C,$]Q8WII1"D;-FEW:3\E16!%:5D\-FAK5D5622]%:UH!1 %J /YJ;T5$
+M8%IB6&$\*R4V:&E;84]C:DD;$CER>HA!37IN+2TV16EI35AI:W-R251;7G-K
+M5DAP<6!!-#])3V)Q;%YC85M;8%ERA(1U<F(V+51P>G-B6EH^4(6*:D5;:F9N
+M=FZ#<F-)+2U+86QK<G!;2&DM(#M)8VAF3U9I8V-$-C;^/TMH<F9H@%4M/C9$
+M:&9U6F)K:V-;8%@_8"48'3MQ<FA/6F)K>FYJ:SXM<G)91S]8.QLE+6**AGUJ
+M<GIB+41R:VMJ8E%Z=!M)<G)J=45%6F]K:VE@/R!:;EM/6"4;/V%;6R=$>G9R
+M:3\8*6%H7F=$/S\M85M$-EQP;%H_.39%@G*  3D!/P#^:6M96VAL<6EO62TE
+M($5?8&-96F\V#@DE25Y[66UZ;5M$-C]H6"TM.5R"@TQ%845C:5A667=R6E19
+M65MR>GIP8V-;3UA/>HR$=6YC239@=7MZ6&-L:45J?6(Y3&IL9FMT:6"*>DLM
+M-D1N>G9R8$UH52DV36QR:FAK<F-B6CXM_B([<%YC6W9C,#8@&UAZ:VAI<G!K
+M6VEA26Y9/#(M;X)Z8DU)2'I[8%LE(%EK6$DR/C(.&!@M6W5U:FIS;U]A8F9Z
+M;6MC<G<M2UI/479P86!/:FIK8UX_86M%3VE$/V)R<F8V.U!R<X!L,B5 at 6EAH
+M:6E8/SE@;CY$8UYB124_18)F@@%9 4D _F!96F-/<HER=W)@-"5+16%L7T]P
+M6RDP/%5-8CERBF9;639I@%4;&"DV9HAH3UI%66!%3#E:;VM;6F%C:UY[<W)S
+M:%M826I]A'IF84LV3')Z;4]:9H!B8FM@/CY<;FMB<V9GA8!I/C8;27=U=6M9
+M6UA+541;8T50>G5K3&)M$OX2-E9(85MF=SXM*1 at M;FEV>WQW<FMW8$5R8DDM
+M+5E]@G)?6%9J>VM6.T19:%I-9F%+*30\,CYB;UE<>FIK:V!-:DQ9>W=Z36!A
+M345:;W)W86E:6F)B;&MH6%EP84]B>G6 <FE%8EYN:F8_6F-I:VYS<& ;/X!?
+M6&MC6S\@+3^"6X(!8@%; /X\'3EH6&.'>FYZ=6M88T5-:$U@:F(V54MI:E at B
+M6H-L338E8H-O/" R539KB&]A25]H6DU%/TUJ;TEC:V T8W)S@&];6%AB<G5Z
+M:UD_1#!$8D=I64=[<F-:7U0^,%MB2&IU?8: >F!)*3!;;FMJ8EM;8&-B84D;
+M'6AF9T1J at QNN$D1-1&)K7&MC6%0T+6!?7W)\@&MN<S\P;6))*R(_8F);65]U
+M=G5J5CY)/FEG.0-CSVEJ<75?3V$V,G=B3TQ815 at V/FYR<F9J=VI--C!B at H)S
+M64587G)R6DE-<FQ98W)C<FUU<G=C3UIF:W!;7FMK:EYF*3EK8EIK<VQ).RT=
+M.7 !8P%6 .T\(#9965MW>W)R=WIK:F-P:3]%6E at P/T199G%)8X-K638\6WIS
+M9CQ)6#8_>FY;86AP;VA8.3]<<FAJ;V G,$5C>FM at 6EA:6EQ]@VDY53\=+1MB
+M8CE>8UA:6$Q6-CY-+TUN?8J&?'=8-"4_4')C UO(7G9]<F$I&UEJ8DQND248
+M55M::')C46)B6EA+1#\M36Y_>FYC24MJ22TK&%Q8.38P6G)]@VA%,"TM8W=I
+M65M::GJ!>VM/6#(M W+#84U-6#X_:&-B;6MU>F(R%2]WB'I/.5I,;VMA13YI
+M8UAH>FM:2&IZ at W%%66MM<D]/6F]C3U%I8VIB:UMB<F!5630M8 %J 6  _DLP
+M7G!B3%QR:%MB>G):3'-Z8TM)6%E824M%>W%L at W):24D^6G5Z<G%@1#]F9D]A
+M8W-S;&E82V%X9UYC<%4T+4UP3UM at 6EI%,FN*=S8V+1 at K*T5O8$0^25I;6$DY
+M/TDM.6!J?8:#<EM5*24M6EI-6UM/8GIU<F$V87):,%J*6(,P6&,$:_EA6%!-
+M6&@I&R R3'*(?$])=W!$&S(E;5 at V*2D^669Z7SY$*2 ^8WI065M:;H)U8DU8
+M/TEZ>H-P36%;13]@6#EB9GN(8R4)$EJ#=V Y/CMB6F%-3T]%/EI[;&-C:'J*
+M;#!(>G5R13])8V)C8WJ#<V9R:UIR<DU at 85]I 5H!40#"/RE->G=,3'!@/SEO
+M<DDV6GIN6$5%8&]+2S]R>G)]<V-A.QLE:H)]@F-F;VM:7F%C<W5K8V$Y,&]W
+M6DAJ:$DV26E;!&"E22T_=8IQ2388.V%%;'-9-CE64&!924E8.SEA6V."@G-:
+M8$LR.P-)_EMC6%A09GIW35IS:#];;G)A36)R:E!C<G);24]?.1(G+3!;@WI6
+M67-H7CLV86A)-#0\6%EC:TDM-EL@$C9H6EA:6VY[<EM-6#98;G6(8C1C<%A)
+M3SXE,#^ D7 I#AA)<F9K83X_:%EC;&%+1#8W9V%@:WIU at V,V17N"=V _.9))
+M87)Z?7UN;&MK:G)S33]%<'<!;0%- /Y$&R5B>F)18VDM'5AA13\P8U M-C]A
+M=V9B6VE@:GI]<6E%*R5-=7US8VQS8UMB:6QV=6UC7RT;6H)H15],.3]%:6!C
+M:6!R;V Y6H*$:T at I/W!$37)P.3(O.5A at 6F%I23YB8VM[=69B6V%H9U9)15MB
+M:F-$4')U8VMR:UMC:GK^:U9B>FM:8W)V>&!-340@*38\6WIR3&ER:EA)5G)O
+M33(M/FEO8FA4*1)8*0X2+4E67VAS>G)H8F(V.45F at V P8G)K;&A), at D;:HEZ
+M230M6&M><G,^27!B8VMA/UE>/EE%6&)W7'IQ15AR>WIS1"U$67)]=69C:$5'
+M=W):7D4=@DQJ 7(!< #^;CLR6W5R:V-O-BU)6$54/E at V+4188VYR<F=W7$QZ
+M;FMI841@<6MZ<EYR:UM)3V%G<G5F86 _27>#:F9P22T[16%;6VMO;FMO:5!R
+M at VU8/SE:-CYK<DDV+39,8$E/>UY%14US=G)B8$E-<F]@36)C8VIL1$UF:F-[
+M>V-06EY\_G='8GIK6&)R=7IO6F!4*2DM.6-[<F!A64TV/DUW>FM4+2U,;TPW
+M5E =240P%1@[1&!P8W)R;VMK6"T;/WAP.6)U9')R3#()&%F"=UM>6$5),&!O
+M.5AA:6EB6#!::#]A24U97$UR>%M98VQZ:D0I-C9C?7%;3V V/WIN:&-9)8(M
+M20%> 8@ _GMH25IR:7> =V!%3UI)8FAF+2 V15IB9FYK<#XP8EIB8EDV6WIB
+M:W)R;F))14E$26-B36-C6&*"D7)L at 6@_1$5A9CE%=TA(:WIC8GYM3$DP-B4^
+M7')C6#8M.58G.7IN138I45I>:F V+6EO1$E at 8V)<9F-A7T11>GUF33M-=OY]
+M1$U:3#1@:FUS=5!B8SLR(!U(<H)Z<V8M*2U)<GIU<EY)3VM))3961%9I82 8
+M,CQ%:4U;<F)B7F @&"5-8UAN:D]F at ELV&"!@>G=$.7!I-A(V8#9/15AI340;
+M/UXG/T1,9T1);')C22<_<FLP+40V/W=R6EMF+4EW5'=Z9BV"("4!6@%[ .MK
+M:#E-:4A9?8)R;EE/3VAK8S0.#B4^34U<:G)955M865IA24QC/C!F at VYQ:4E%
+M1#9;9CE/:6%:8H)R5&YB:VE93UPE(&M)15IR65M[<UQ at 538\14QB8V-)-C8E
+M#B=B:DEB7C8=-EM>+1M@:P-:_F)B33(Y8G%)179]=7)816IZ:$E)+1@^54U[
+M@%!,<D4_/" M1&Z&@W<R(!LV:W9J9G)Z at H!J15M).4EH;S G*5A86F!C;6I8
+M6UM$;F8E)6**<C]JA7IP-BU9>GM@)3!P;1LV:&!9/UAR8EXI/G%5*2U)<%M9
+M3V)J:3PR3&))-I)$2S9)8V-B<$D^:4AR at GA>,"4!8P%M /YK8SPY86%::WJ#
+M>&A1<'=R9U50(!@V24]98F)-8VA923!9:%9 at -AM$:TUR@&EA8$58<%E-8F-;
+M/V:#:V-;:W-P83XE+6-H;VMN6EIZBG)K;%A@:6)B66IJ3&9%(")9839W>V$Y
+M/F!8/TEI<W%B6F)K3S8I/F9:1&IZ;GIZ:%O^9F\P-D4Y-D0Y<HIZ6FI68%A9
+M53Y-;H1S-BDI/$]N;&)D?8F*<EIC838P:5DB*1M)8$56:VUB7UXV.7MB&Q4W
+M=6]':&AU?4DM35QV at 2T2+5@I&U9B83Y9:VIP/S!S;24V640P8G%F;GIJ6TE'
+M:&%82TE/245$<F]/8&AK;G-;@CL^ 6,!<@#^<G!),%IC:6-K at H1N36)K<FMF
+M<D0I-DU/3'!O6%AF:UX\8& T168M)3\^8W-S;&)-:&-86&IF8"UJAG-C6G)Z
+M;&%+/#Q/<'* >F-:;HEZ7F-::')F8T]<:C!@8U at V.5@^7GIR6DE:/CE:8G)Z
+M:D1F at F-A1#EO9$U/;V1F;FUR_EM8)14M/#\^.7"&B&M:6F8^1&YZ:FER83\M
+M/V%%7&IK4&Z AGUF8V$_)5]<)2L at +3E536IR:UY)&RUC- at D.'6IZ8W!$68A+
+M/%M:<()A.2 E/!@E6'IZ231)<6$V&!M@;$0[%2MP;G6*;F-P:VQO:$U'64DV
+M,&MW6DUJ;&-97H(P-@%' 68 _F)Z6R4_:VMI8W.*?6M:3%MP8VI65#D_64U:
+M=W Y6G)A:7UP-C9O;3(E/UEC9G-<8V at Y1%AB;F at M3')W:E!R>F-/6&%527)J
+M=75N6UZ&@V)08F9J9G)K8W!)25!;/QM%84EC<UHP2RT_:#D_;GM<8G5<6DTY
+M:VI,1&MZ8EQ;:_YI5CX5("55-CQH?7UJ14M88$59B%M9=VD_+5AP34QB@&);
+M=7A]=G)K6UA-7#9$/S0;/V!B<F]@2QL_:$0G'1MBBGU[85B"/S9A<'J*>F M
+M+44@%2UU at T]97WMT1"DM6V at _530_6T]F at VM/>HA[;G)925E4)15-<F-A:V-K
+M8VN"64L!-@%% /Y9:U\M/V-<;W!F?8)U<EI)8FM at 66A@15E96FMP)TQN/V*"
+M at F)C at X=I+3]%6F9Z8F)G+2(V/W=R2T5B;G)C:G)K6$E%6&%R<VUJ;6I;=GUM
+M6UIN<F)R<FEL=VQA6#L2+3Y+8698,#(5,&$;$CEZ=VYR8D\_26-B125%@W)'
+M6G'^8V)A,A48-CX^9GUU:RTM-G!H37)B/S9K>C9,8EHP,G=R9E-<@GAZ;&YR
+M6EI)3%E>)2U536!W6TP^8(" :R4)-GI]=G)B at UDP.6IZ?8IK/EEA-"DK=WY;
+M83E;=VE+87!W66!@86M;6FYI,&.*AGIJ8#Y%/A at .+5]04&IF>')Q at G=S 6 !
+M50#^8%I-66%C6V-L:WUR>G9P6V)J6F%L:455/T]B:S]/7$1:<GIU;8I]<FE;
+M/TUC>GI<6%4R&R=K<EXY1&)K8DQB:VT[("U/369[=6MK9FYU;FM/<GUZ;FYK
+M9FII>&A+-RD;26]@/S [*S9$&Q4;6VYF;6I;26MP:CX;)WI[159C_D5:<F\_
+M.24M1&-U:'(I%1M8:UMZ8TL_8W5C:5HY-D5J:F9 at 375U<UMZ at V-;85A@:3PI
+M-E5$8EL^86QN?'<\("U:>GIF8G=Q351L>W*">V-F:5Y)4&N"8V8R-E9I:8%R
+M<FE96$UZ<EI:82=:?8=Z9F-823\5"1 at _2S8W6GI<8X)[;@%O 6  U6!;25IA
+M8W%;869R<G9U<G)O9&E;:F]-241%7VIB8%E>8FJ"<F:">F-J8U5;7FZ):%A;
+M9BD;16)Q24E(:%0G.5MI/"LK)1TV;W5R8VMP:FMC26)U?6<#:H%N W+^:V@\
+M$EE[8E at M)SEH8$0R&TEP8W)F/TUZ at FM>1%2 BFIC65II<F988"TM16M[<G(_
+M*1 at R2&AJ341A;W)J at 7<V8'=P3%MR>G9U:DQNBG=C6TQH:U4[+5AA34DB/V]R
+M9G=/-DM-;8-R9FUW33EI<FMC9G=O8F-96SES=W!++3E8I%MG<F-/-BTG:W)L
+M='!$:WV*>V-;:6%)*0D.+44@&U9J/UJ!<@%H 6( _DE915IQ<EYC8%IK8E!Z
+M>VI_=W!L<FI9-BTM/W!933E at 8$5K:FUU>V]/-EAA<&QR6C]):6E+/EIK8&!;
+M850M+4U82UE0+2DB-U%B3%!C<G)C35IK;F)945IF;G)Z>F at W%4UR6E!C84U1
+M8FMI)R]H6UYS6T]RAW!,:&I]BGUL4/YG<G)>63DV1#8Y<&YK:&E++3!P:TU%
+M8')R35I@/UIZ6#E6:GIZ9CX=6I*"<&%)6F)+/EEI6G)R1"5B>W)R338_+2]J
+M<EQ@<FQ@:%IC6#E::5 at _/EHE1X-R<$LV6'!C86%)51 at 826),8UQ:<X*%?6MH
+M:G!B7C 8("D@($EC+3""=V(!6@%- /Y$/"5+ at W]/.4UB:V P:W)B<GAR<HV*
+M;U9<25II64PM6&!86V-<4&IG/B4^3VQL8TDV-DUV=TU-:EIP8&-F6#]8.41@
+M85E)25\P24PO.6-R<F)B:&I:1#E%6G)B<F at _-FMZ6UH_9GQS8DU:8E4V8$U%
+M<G)B9G6"8TU-:X)\:F'^6FIZ<F at G-G1$&S9C6G-N:#\E6G)J8V ^/DE-238^
+M64(M6%IK:T0M)5:2BH)H6$D_+39P<#EHBF at 5/FI<;U@^52 @1%@Y6')Z>W)B
+M;&)@7V-:-BU))39S<WMP/U9R?&E-6G<I#B(^5#\G)UIZ=75F:VMN>FM>.R E
+M/#9;<3PE at EA- 6@!20#^.R 5+6][62 M8'-H2VAK7&9K:UR&CG),14M:=VE+
+M/TMC8VAI5C1-23 \1%IS<F)653Y%:X-K5F!%:VM/8VE;838G/T]/1V-R239)
+M)RU)6W)R:FMJ9U at _.4EP6WIC2T1C;EA:6W)U>G)@3UA)+59$.6AN:VMF?(-;
+M.45K>G5K_EM89()O)2UQ:3LE245K:FM@,E9N9F)J24EA5DD_/CDV'4E:6&8I
+M(%EJ?862>DDV(!@E<G=86XIW*3]A3&MM6&$\/%A8-C!<>HIZ>G=K<G=O8DL\
+M+24W:W)]<F%C6V9[8EN#830@)5A)&QA%=VYJ7D]H9G5O:50[-DD^87IH.X(V
+M20%W 6  O3(5&"UA;SP.&SYK<G=[<FIB8EM;<HIZ6#Q)1&N"8S8_6VMC:U]%
+M63\G,$E/;'- at -TE)2V.#@FIC86Y[6U #:?YA1#=%/TQF?7 Y1#8M/R]B>U!/
+M:FMQ9DE%;&AJ34Q@:&A)37*"?7IM8DU8.2U5/D5 at 9UIJ8E!Z:#8M6&YZ;6MB
+M3VUP/RUB@' ^/DE?6EE9-DUS;UQB3&-T3$1B62T\+4UB5DD2&$UR9G62BF<I
+M#@X54()R8G6 86-;+T]J:V/ .5AL8#P;,'.#;G9Z;')Z>G)I124V55YZ at FM;
+M<5M$<HAZ>G* 53)89EM$67IR:EDV6&]D9F]>7TM8.4UY<DDE1 %[ 6@ _E4\
+M-$EO9RD.%3)-8GJ)<FIB65HV6FY;3U at E&S]A6S(V16UI9F=)2U0V-#9%6%!)
+M&R4M/TQQ at FU<;&Y]<FMB8VQO<6-I1$Q->X):1#8M/"4Y9T0P1&-K;TTY8W!K
+M6$Q:8%@E17)@=8)F45A8/B=$,#Y@:$5$6DEB8RT;/W!N9J]U>F)08"T5,&J 
+M7TE41456/CY%8G)R6#!-<DQ8:6<[-CYB;U8I%2!$<EE:>GUW- ,.N39R<7)Z
+M:V)S8SXY6H!H+4QW8D08%45S<EE/6W)U=8)X5"5A<3]<>H!1<FX_2'J$8V:&
+M<DM/:W!J8 at -RDF$V,&IH3VMS:V%8-D1K:44;+0%A 5@ _EAI26-Z:2 )#B _
+M.6)]>EM-36!$86M%3VE$/V)R<C\R+5EK;&)664D_7DE88%]$+3(I-C9$;FI:
+M<W)F=7U at 1&-O9FYW6#\P:X)Z:#\M55Y$6U4V-DU;:D0V6GI]=6I))2 E56(O
+M67IB5EA<5BTV-D5:<%E)6%MK3S8@,%YH3?YN at FIB6" .*4EN9$UH138^)TE8
+M1%QR8C9)8EIH:V9A23EB<F,R(#E->F9A:6YS9C .#BUK;76"<EEJ:E at V87UK
+M1$2 ;TD=%25,>FQ965MK9G9W21M-<E at Y7(!W<G=))5!\/DR#@VE%:WIR:VMF
+M=VE5-F-C2V-[>G)L8%AK<&:"-"D!)0$G /XM3V%P?G R%0XE66!@4&]K6$5:
+M;&MH6%EP84]B>G5H64E$7UM)35HV+5IK<&)B6#!$6%Y56&)98(" 6VI]:CY,
+M6EYK;&%:14UR>G!A16)O6DUC63]-8FM%-D5:>GUK1" 8(%A:2W!R1TE816 M
+M*RTV3%MB2SY,@%LV/TM@;EO^3WUR46 \%2U69FI;;F [(!4W7S]);' _1$5C
+M;VI08V!86FIL3S9$27-S8EIL>FIF*Q(M8GIM>7IK:F\_(F!Z7%XP<FI6,D$\
+M)VIR;VA:6U%G8BT@,&);/SEB=UEI5"!$<B4E<H-R.4UZ=7)J;8)P7C!86$MK
+M<FU]B7)98GM[@F98 A@ Z#(M2W"">DDR(#9I>W<P3'IJ36%R<EI)37)L6V-R
+M8WIS>G!@6#Y-9C88-FMZ<F-?/CE@>'!T8#8M=8)S:VIB6EE:8VM:6G!)/V-F
+M8F-C<GM at -F-J6FEV>FD_.3E-<FDV&" R/S!(@'-8 TG^838B-B=)36%8*3!R
+M8S\Y.5EN>VIZ<F)C6C8W/D5R?79K6"LM6&)626IP23<V/EAG15AB<&]:34U:
+M:EIJ:D4V3WIZ:E4E,CEJ?V)B>F9O1"D_:F)6/VMZ82U$5C9@<WIM8DUH<E at I
+M+U5Q3S<I.6]H84D;+6,I#DQU:TE->GIRE69M at G-K/R4M8'-K6WJ2=T]C>H)U
+M;@%! 1@ _E]>24%<@#DV,CYR at W)96G)U:VIO:V%%/FEC6&-S:VMN?8)W:3\_
+M8EX;)6EK=7=L83]/:DU%)3(I375[;TU%6F-;:'IB6FYC54E%8V9::G)B/TUI
+M8W**AH)K:4D_6V _,D1>8#XM8X%R:5I-8&E<8$1%6%I8/S]K:U8I&SYO?/Z"
+M at GIF:UMA64E%8G6&=4\G/FMS:W!R<F-+/S8_23]+<&MN<TDG5GIJ5EM$)39R
+M?5I4+398:H!B6VY/6V)>26MR64]R>FM>)S V3WJ";F!%:GIH*25C>D]$/TEC
+M=W!5/SE/*1 at V<$PY6GI[<F-<;FQR82 5.6-K3VJ*@EA6:H."@W4!< %+ /Y,
+M8G(M-W G3&YR>G)>:W)S>VYC8EIA34]/145:<&Q;:WN#?7!86&IF(!MI.5IX
+M:6)-6FM@)1LV6%I<:FA)+3Y at 6VMZ<FIR<F-)17%S1TUB8UE-3U9;?7QU=H)O
+M5D589D5;:VI@/SEP;7)B5C]P:GIK5F!L85EA<FI$)2M9:WW^>WUM:&!$6EAC
+M8FERAGU-("U;=6YZ at H)S:E@[/U4M+6%-4()G)55W<$596#Q)<'MO7C(E.6*"
+M<&IF8E!>:TE:=6-B>FYC=S8\,CF >F,V-EIF=U4E/X)N(!M)@G!825IR<%@@
+M&S\E'6!Z=W)K;W5V=68T*RU/:45$>HII,$5\@GMV 7(!:0#^)T5P5#=K/T]<
+M<HI[8FIZ at X-Z:VA96V%92T0[/F)A3V-R>GMW:FIW7C(K625%<&M;8&ER<%D_
+M3WAS=VIH538M1&EL;FIB:G)B.3YL>D0G/V--6&%@669R=&YZ9E@^-D5A6F9N
+M9TD^7UEK;UM%8%!U:DQ%9F9K<'IR22 _:%N"Z'5]9EQ;3#XV3VE99GUZ6B(5
+M.6)?;H.&@FM-/SQ8&RT^15EZ=S8G8&,P2U]96G-U:EI%+24O9GUR;6M/8F)@
+M6FMP=W-<:W5$7D0R<H)H)1LM,FII64EL<V8E*6MM22!$=8-Z7BD;%14V UJ5
+M8FMZ=7IR2T1)2V%96'&"<#8^8V9U 6(!8 #^-EEI22UJ8F!9=86"8E!F=GU\
+M at X V&Q@@.V-L5D5$6FMO8DUJ=W)P1#]?:38V7&IB:&MB:W=H46-UA'IK6U at T
+M+6)Z>F]%6F90.6%S<TD;+40P36MR:E%B;75U7F!8.S]@6DUB8D1-:6MF8EI@
+M8T]K7EA:8F-P=W1R8"D_:T]NGGJ"<F-)/TP^,&-B:FYN3U @.SXV3WJ"AFM%
+M,#]Z/P,VS3=J>G)$23DV6&A:8W)R=VY9/RTM8VYN8F-;:%IC<&IJ=6M/6F@^
+M:7A:;WI6& X8/&-K;&!;:G=8-F!J-A(G8H:- at CP@'2DR/D0_/S1K WJ/6#!A
+M64E):7)M>F-I:4AF 7,!60#^8FMW/B!P64TY:WUZ<F ^8VM;:8!;*1@@26MZ
+M:UD_16N!62DY7')H/S]9=UDV-EY%34DM1&QR82M:A()N8EH_)TAU?7=9<ED^
+M*VR#?6@^550E3')[=F!;6VIU8E!I6%EB8D],34E8:W)F:TU68EIL8%A:3&-;
+M14=R8BTG8F-:_FMU?(-K/EA6'3E,<X)N6V%)5DDI-F=UBG)),C9U;TDM&Q(^
+M;H)_5!T\36)><FMF>GIR;$LV8FYR3$0V:6!$:&Z">E!922TG:8AN=8)I-!@;
+M2VMN<DU%3')H5F]W;C0;)V:%A6E57UY%3UY%1$1;;GJ 8B5,6D5)<')1:F)J
+M>()%10%R 6L _GIR?TD217!)+4QR>G%P-FEO/C!8<&,@)6AZ?6L_-C):@F]$
+M-D]O8$E))U]L/"T[254M&!TY:W E+6J"=FMC8#9%<H)]:HIC+2U@>H)O3&%)
+M&W!Z at X-R:V!98FA(6V-K<V))6$E)6FUZ<G)::5I,3$UF3T5:7SXG3$0M1&]R
+M6?Y,6VV*<D5)8#8V.6F">G=S<&I at 6%5;9GU[83X^4'QP5"D8)6*%?6 at M-DQ9
+M8VQW;&]Q=7IB6&AF8V _($5H.45:@H)$/CP8"41Z>GV#>F$E&#YC<G ^,$1R
+M=UI/8GV 7C9%=W5L:X!B65Y>.TEH;V9K>G)+8$4M/G>!;F)16G>"8U@!6@%Z
+M /Z#>H9P,#EO:#]%8WIF8C]H=V$\-EIC.2UB at GUK,ALE6()Z:%A;=W-B52 V
+M8$DR+6%U53PM-UMQ7C98:VMF8W!I8FU\@W-R8"D@/W)Z:C8V+0Y:<FEU>G)J
+M66)R6TU;9G5F.38V,%9R=7QR47!B23XI6%A$8UI:8&E>*3Y9:V_^8G)R>G)H
+M5DU>7#!$@7UN<G5R35MW<&)R=6I:1#]D9'AA,B5-;5-G:4E at 7&M<:W-R<FYN
+M6E!J6DEA7B4V:&!%6'N":#8;("LP8FMZ at GIC,B E,&!K9C8V:')F.41Z?8!I
+M3UIB<GJ"33E at 224;17)R9FYF:W!%&R5$>X9W8%IK at FA) 40!@ #^?VMN at V!;
+M<FI-6&IZ8DQ8:W=C:6EP61T;27)V:3P5%3]W>FI816)P6FEF-EM6/" Y;UM%
+M25AA<6@^-C!::%E/;W=F>GIR6C\8#BE::FI5&Q4526)/8FIM;4=,<GI087)P
+M;CDM*1LY<G)Z:T=B8V)@6$]C6F-J7VMX@%P_-C Y_C]R at G)K6TDY8V])+5EZ
+M9EYF:#8Y=8)C36]H6VEA13^ <C8V<&,G2&]):W)C7&->;G)K6DE98VE+8F]"
+M*3Y6-D1ZA')$&UA9)SE-9H)]<F->02 ^6V M(D1)/R4V:VYR:SP;)V:#@TDG
+M64DI#B5G<G)P8&MX9CL[66>"?7-C6H)@)0$; 6  [6)I7GII8H)R5FIZ>FM$
+M8W-K3&-W:V$I(%AR<FM9,ALV:GIM85AA6T59<UE;:%4[/$U$,"T^8W!K7S\V
+M7FA>-D=K7'I\<F,[#@X;6&IJ;3P at 06-I3&)B<G=81&):1%N =7)8-CPM/W-]
+M>G)C6ED#8OYH9EQ/:6MB9G5W6TDR$AM@>FQC8#8E6W)P246 :$U08" ;6H)K
+M3U9,37!W6%IK=SXV:&))6&!%8VMB6EM;;GIR:DD^3&E@:7MH.R<^+2UPBH))
+M(DU9)2U)87)U<W)K83])868V+3\_*14M8GI[;RT.#C!B>TDE25PR%2!8:7*0
+M=V-C:VE)3VEK=79\<%]5( $. 2T _EEO7G)B8WUS35QR<W))6G)?)T1C46!$
+M26MN:W%/1"DV:WIQ8F-N83]89FE>:UI+6&!)-B @/U9C<EM@:F)%+4EI8G)V
+M=W=I.RDV8&-::TDV27MR34U9>W5<:6,V+V-V at G5C/U5)6G5\9FMJ35MC24Q_
+M=VA%6&-J8F9[<FE$"?X5-EIB7%H\+4EK<G)B at G!,6F K$BUC=VA at -CY;8%A-
+M8F]K36!(8&1,8')<:FMC7F9Z<VI$(#EA.6)Z<F-)-B 83(^*<%E+84D_36-H
+M7')Z<F=;66)K6$M96#8I*45R?7<_(" M1&M>+3!>1"DO15M;>G)C8DE%6FMB
+M8F9[>&N"7B !%0$@ +-9<FMS;%MH=V V*45K:$QC7QL;,BTV,E: 8EYW1"T@
+M)6!R;FE:86%86V-C<GI at -CEI83\#(/XP6F _;WIK1#1):6IR=7)R@')98'=F
+M1%A)/TEO>DD^37)J6FMJ1#LY8H-M8D])36IL=5Q?1$1 at 3#8G6EYP:590;7)B
+M<G)K7B 8,CY%6EH^+5AC8FMR at WIA6FA9*1 at Y;UQ8/S]86DD^16)R:F ^5F Y
+M6H)J<VQF:T1C;&$^&S_*6"5,9&UR:4D@#BUY=79Q.45S<&)B9TUB;G)N<&QC
+M8UIA6VAP7C V8FYR:$M866AL:$DM,CL\25M;3&9U;UA%/EAP7T5@@()V9U@!
+M- $R /Y+241J<%I9<G I&"5-<EML<$DI)2D5($5Z:FJ 8"L8(%IZ>W!;14E%
+M6G%(:GIO+1L^6$LM*2LG640B8HIR6$188%EJ:VMB at WUC<H-R2$E%/T5Z>TE$
+M:&9C:EQC14DB6'IF65E%3&IF:VM8+3EB240V+1U-?V)-9H)F<6):8CNI&#M8
+M,$1)+25>:4],>X)Z:EIK<DD at +6]:-CY88%@_-B4O35I-86-I6DP$<M-<:TUC
+M:V!5,C9>+6!;8FIL21 at .(EI-6U4=/WI\9EIM8&!<8G!X>V-?26%A8GMR7#])
+M36-G:')C<G)J8E4@%2UH:6A8/W)J2UD_,&]H/TU[?7UZ<@%> 44 _F$_&S98
+M8EA9=SL.#B)B8G> :5Y5*0X at 26EC:G9I-B V:7N">FA:23\Y6V-A=W-5-#E8
+M638V539+,A)$?W);:'-K6EI;8SYS>F-F>G5C6E9)+7F*:UIB7&MK6EM).QM8
+M=7)-13]8;FEF<V ^/F!-87!+("5B:#8Y>W:!:%!A1* V25 at Y.S(8($E:.2=P
+MBGQB6')Z:38Y:%HM-F-P83Y).P,EU"UA:G![:4UB;GMR;%IJ>FM@/S]926!C
+M:VMJ21@),EXM+2 )/W)M5CEB8V)<.6EW>FM956EP<&I<>FA$.TM:8WIF7GIJ
+M;G Y#B5B;VA9/VM@,$DM$@-)AEEI:W9R>P%W 6( _EE$(!4M;FE;8EPG#@Y6
+M36=J4&MW51@@6&!:6G)C+255<G)U>GMP86%)16IP>XAO8%A at 7S8M7%I8& XE
+M8$E8:WI[:UI86$EC9VMN9D]G6F-)%5E\@G)<8V)J8F!)/C1);G9-)TEB:V=F
+M>FIB6D5$38!K5#)$7R(M8FV"<F(_6,-;:&MI62T8-#E;5B)@B8IO6G*(=F!:
+M6UDR+6%Z<DD^230=#AM)3%IZA5H_7H-Z<F)K>G5K3$551%A-8')Z:%XR/V at E
+M PFZ(F)_8#E?8FAH25AF<E\P26E at 8V]0;V\_-$M:;X-H6W)K<FL[&"!$8VE/
+M7F-8,#8@&"4;(CYC;&A/=0&) 7L _FE5( XE<(5P6V!>.Q at M66--,%AP7AL8
+M/%EB8'=+)2 [8V-B<GMK7G)I,&)B<H)Z<F9:;3(V9F%91$0\1!LP8FZ <EI6
+M24U;6F)U:FM$1&(P"3),9'%<8EQR<FM8)S9C:VY6)39$8%!9@&Y_<D14.VMW
+M6V%R:T0V25MK8W)?/\-->GQS8EA$6#!$;"(P;8)Z8&-]9D5K>E at M($EZ<FM9
+M/C(."2!")TENA8IK<GUZ9F)L>F9Z>F P)UM3'4UZ8')N@&@@ Q6Z(#9K@&-@
+M145N<$5@<5 at R26-83'>(>FM$("T_8WM at .5IK>F\\*3Y815AD8W!:8%A4,C0I
+M*1(P8TP^30&" 7\ _G!9)Q at M9H-W6EM88$$5/EE)66%A:%4\1$UJ8F Y6#PT
+M.45:<G-B37J 6$]:6EQ;;U\_6"TG6FMH8%A>7CP_8W)Z<EA83T]86VA91W=J
+M6F%5-$MK<FYB.45RBGU9+2)B:FMO7DE)6$QB<FU]<DQC6$UJ6EQZ=FE%,%M-
+M/D=C/OXY<G)C<&)@:$U5:#]$6V):6WN"8SE@>EHV-DER;FII5"L)%2<M%4E;
+M9H!UA7UQ9F9[<EEI at G<^(%9()4EJ2&-;>G R,#P[*R5->V)9/SYF;SY8<&A$
+M66!C:&:#@EH^.24[6&)8-BU%<G-5(#EO13]J;GI-8W!//C\_.RLM23N",CP!
+M;@%M /YH8$1$/FJ#@FQB8G)L/$M81$U;85IO:FE::&@V&TE>+2 V6')P6SEF
+M at VM@7&A%/UAH65A",C]C=T at Y3W!>16-K;G!)6%A)6%A at 33!><FQR<$1;<X*#
+M:!T;6HV*:C88)TU(:6);641-;V9[?6([644[6UMC9G5U<V!97BT;6&+^6W!-
+M,&!J8EI,;')-3'I-)S9K=6-$:')B6%E<<GIB6F8\&"<P( XI-CY-6XAZ8EQK
+M<G)O;G)K8%A/6VAB:F)P:FI<;3\_6#(@38!J35I-:VD[/V!U6#8P37!(<GLV
+M(C8E+4E:238M56R!;T1)<EDM26R*145M6C9%34Q>1#])@D0Y 6\!2 #^3#Y$
+M:%A-;GIW:VIS=VA-6TE58$U%8WIZ9F9I-BE)6$0R.UAW8V%H<GMN<FIJ6$U:
+M8FQC8#X_66I8+3!P83];<FMK3UI83UA-6& ^2%I(<GI66&9]A%\2#C9]DHI9
+M)2D_14U$65HP/T4W:X-G16D_/V)K9EY<47)R35@[$D1Z_F9B/C]$8&!,16-R
+M3"EZ83(W26-/2W!K8FIK:F]Z:D]H21 at 8(!@5(#9$&RU[>EE:<$]F?'59/V)[
+M6$US6EIJ<H1Z6FI5/EH\&S!R:FIG3%IC/B4Y=W ^+41C8X"#52DM,B(Y6#\E
+M&SEK@&)B>'IG+25)A5\Y8DDI25M'8F9568)93P%P 5@ _F!).6-W23(_:W)F
+M7FYW2$U9/F%)26%N at G!:63]A?4E+7C]H=V)@9G*#>G: <V!@7TQF<G!?66%J
+M9D0_8V!%87AQ:VE;84E95EEC:5D_)UAB5CE;@H)X01 at R:X:*=U at _66)@+3]A
+M23LB(E9U9S]B.3E6=VIL:45::EL_&PXM<OYR6D1 at 669@2S9$<F])>FI%24E9
+M-C!<:F-R:UIJ>FMC;5D\,D1$-#1)7!(@:G=(8GU:8GIR:#Y!9CY$?V at _35EM
+M at H)O7$E812 I8%IF;V!I:%0P,EIB55AA8%Z"B7(^)3PI-EA$%0X524TM1'IZ
+M9RT5)VIK6F]A)39 at 8%E:34F"34L!:@%W /YR6#]:>F\I%2U96#D_=E8^6"TV
+M-D]L:GIZ;3\I8G]-/VD^1')B35MN at W)C>H!G340I3'-Z:V!A6VEC:&->/UAO
+M:F-C65@^245837!P6UEH65 at E.6U]A' V2V-N at GIR3TQB6"=8<H!O23]F:FIC
+M9CX=)6MK<W=-3&MK6"D8)6+^7&)-66-Q;'!--EJ"@WUK23\V23DI.6)C<W-K
+M:GIF8G!C66!J;VE?:E8.)5]R2T=R8V-J;7-W6U@;+7=Z8EI?8FR,>EI87DE5
+M26-P;VMB<'!@55EF1&!J<EM,>I**;SP_1#]).Q at .#A45#C9Z>F)$-$1H65AC
+M<4D^3VE66F]8 at D5) 4<!;@#^:VEH:FUZ5"<@+5I3/F)-154M%1(M3%IR<V\V
+M*6)I+3!Q6"U)/C1?9G);25%M=V,_)3EL>GIK8&!?;W!?845:;FI at 6$D_35D_
+M2$E@>V=P;V9G13EH;7IR145-8G)U>G):;%@I16Z*@G5K:G5F at G5<+1LP47IS
+M33EK<F)>,C)8HS=913E86V!R<S\G8HI];EM/1#]$.S=A;FQR;6YR8DU8245R
+M X+::W)M&S],8FDY6#E/8&)U at W->"1A%;G=C8VA/>G-%3%A)5F!9<G)?67)R
+M8EMI:#9?>H)I37J2DGI;15A88#\T.2 ."0XV at H)J24MQ at UE88VIO;TAA.3EX
+M<$5% 6@!60#].6>)BGU[<&8V-EMK16AB6F V*RLT+3Y68F \26!@)25B9BTG
+M1$]F>H!R8$UB<G!9/$MB;7MR:EMA8F)I64U::W=L8%Y)8VEA/C9%6%IJ8DQ8
+M:4UI8EEB9F!)6$U;>X)::FA)5G*)>'5N<GID<F9I850V7V]:25AC=G5R:$0#
+M6OY5140;+5IR82(Y>GQN=W!C52TE(#YO6F!F:W)H22T5(%F">GUR9'(E+3]8
+M8DD[)24[1%N";E\Y*2U$5F!B:V)W<D1)/TMC:%M@<EE:<EI)/F%9,DUUA7)>
+M;HJ&=6!;6%AP6EIX52 5#BEP>F-%27*&:# R8&9Z:V<I)4Q?)R !=P%$ /X;
+M.7J%?'UZ=UAA;&H_8F]08T5)6%LV24DW/S8V3VE5-EA-+25):6YVB8)P3$UC
+M:$D^36EJ=W)C3W=K16- at .3!:>G!S<6%I<G);/UA,.4U%-C9 at 8&IK23E<8%E@
+M/CES<S]B8C Y<H5\<F)L at G5U<V]B24EJ<$D^35QR>GMW:&:L:EEA6"T2(#9)
+M8T0P8FUR>FYP8#05,DE834E9;G):6!4)"2=:669:/U]F/C8#6M$Y6G)J6"=9
+M86AK8VM-241K8EI)8#\_-DEK:#X_<&IB;VA>-C8\*39;=6YC9'V"<FMK:45K
+M;7)R<5E!,"U at 9EM)6W=]=TDV6V)U:VQ85DU8+2 !7 $V /X;)5IU=&YF>FQK
+M<FI$-W=R8V-K;UA88%@V+38M+4UI66$V+55A:F)0>H5[5CY96$E586)9:G]C
+M38%W36%C-A at G5DUR<E%W?79;66MP33E)23DP1%IK6CEB:%IC7S]@6C9P6"4E
+M375U;6AG=6UM?7I9,FEZ:C8V7V)G67=J9GK^:EMH8"T@*2 V8#XE/DQS?6YR
+M8#(5/F ^25A):VI%5!4.%2 ^66=B5D5U<TE8:&)-375S6S Y36J(>G):8W-I
+M84DV=UM8-CEK7QTE8FYJ9FMW7C9$/"5,:D=::FUB7G)R:$UK=7=C<'!87E]@
+M35L^3WI]<G!86VQZ<F9R<FE:@E4R E4 _CLV26AJ:V-S:V1U;SX=7W)C:G-[
+M6EIR:TDE*3(;-E at _3S(V6X%_:UIF at X!--DE8/TU at 838R:ELR at 7I,7V]5*1LM
+M.5QB37*%=5I;:VYH+4EH:3\_+45916)R:V-J8%\^'6A at -C8^66)'8W=F:VYU
+M<E K8WEG+2=9:E]%:V):<OYK:VAB6#Y)-DEC6DD^+6-[;7!-*2!)9#X_7EIC
+M7%9@/S)07F!C8FIW36MZ8EEK:F-C;G5R8%9,8FIN=3E, at F%8.5AR<G!9+6)@
+M*39J:F%I8G)8,%MH-D1:1$196SXT:VI at 8WMQ8EIL<$Q:8V!@6SM8=7M@<F-%
+M6H%R44QM>VN"6!L!-@%5 /Y%238Y6UEC=V)B<FI at -C9$3%IB<F-K=7)O53(I
+M(#QF138E-C]H@()B6GJ"5ATP7&!).5E5/UA5+7IZ1$UW<%X at +61B5DEF@G5:
+M6G-R6BT_:W)U9B4R6%]J;G)K9G)H/AMC8T5-340Y)3!8-V)N:FYH6F)D838M
+M35I$36-L6UO^8FIJ8VM at 24E8:FMJ5B4Y:V-K6T0V5F]<26%C:F)::W!,26]<
+M8UIA<DE;=V]:8FMB6FMK:FUR8F)-7')N8'5%-D5;8H!N<UA823Q)6DTP6%9C
+M6"U):G!C:&A at 65@^,%MC3V-]8$5-8FMB24D_6FI,6FUY8V)@.5E[:SDI17)_
+M at F8R 38!/@#^:7)F1#8E)4UL8TE)<&<^/V%81$U/:W-B;G=,86LP.6%8/T$@
+M)3Y@;VE-64DI(&!J:VIB47IT8VAR:3])>H!9-D1)/R4M8GV%:SE,:38;7GIR
+M:TTM1#Y:8EIQ at H)R4#XM<H**>F9I7S0@,C))6D]-9H*"=V at V'59@,BU:<G(P
+M_D5:8UIB8F ^-D5ZBG)9.5!B65M-2S]$8G!<8UM<8D]N<DD_/C]9<F];6%MB
+M:F!)+2E86$1$?8)C145@=GMB)2UH65IB169Z;V!+36!9-EMC6F!@6&J(<TQB
+M at H)Z:3LP6&=R=6E)-C!@:&A5+2]@6T5;:VEB6V-R>G)@/#Q/9X)R:@%N 6D 
+M_F9W=VM$(!@I3U]$6']P53Y823!)2SEB<G)C*3]O22=-6#]5,C1$/EIP8FA6
+M,B!89GIM:V-R=V)P8E\V+6J":DE)62T.$E9N?7I,/S\E&UB"=4U))38M24T^
+M66Z">TD;&UIMBGUR<G=I/RTM15!?.6*"A7UR/RD_8V%;:VIN8)5+6&IC;VIB
+M/S(E675Z<EA68F);14T#8+%B8FM/6')B:FY-5DDE,&AZ;W)K66IJ32 @7&%-
+M6W6%8#8G6G5R61LI5DEI8$EB;FMH V.T:TE-8E]/24URB' P.7-Z at H-I-CEF
+M at G5W22TR6$U-8%@^.4U%:FI61%IJ?VUU:F%-6%I;8@%P 6, _FIR>G=;1" =
+M+59::W]V:5MA13)%7C(V=W]9*2589DE86T5F1$EH35!L;VY at 1"U836I,67MW
+M>E!W;FI$-F. 9FA863PP)6-]A8EJ2S8@(#9R:C!-53L[8%M92T51>E at 5%3EK
+M>F9:3&)[:SX\/SDM,&*"A7%R8U4_/F>"?6I9:.U at 36IF=7IK8$E58%E9>FIH
+M8W!@-BUB<G5F8G)H26YR:VIB8385%41R;G5Z6F)W@"4 at 8VQF676*66 V3&YK
+M:3]>:$UP=7![6V)H1&)J:VEB:&!8/SE<>G)@2V!B>H-K/R4_=7)Y:#XM6#\M
+M/UM) RV08H M)U]@34^ <EM-:W=A.0%H 6\ _F)U>GIJ8308(#9-:X!R:6-L
+M224M/S(P:HIO.R P6FE]:3EJ;VEP6$]:6H)K23Q615 at V/FYR:UIK>GII8W)[
+M:& ^.6AM2X"*A'QR8U9454MJ8S\^6D]$8&)R:UDO658R,"=J=5Q$+3!P8CY@
+M=38)%3E[A6YB34D['3]U at G=:8_Y6-V)U;FYF;U]-8VQ/56IO6F-B-AM$:FUK
+M669Q5G!K:$]J<#L.#B5)16=W3$EFABT\8VMO1&J&;6IH8V)(;T58=&!R at 6]U
+M:%IG+3E::W!$34U)8&!,:UER?&=-:VMD:5H_3&9U=6I86UA+66AA1"42.6H_
+M(#E$&R=O<CDP7X."<#\!/P%; /Y:<GIZ<G)5(" ;+59K5C]+8UI)/C!;<FIP
+M35HT)2U);G V1&UO8#E)5D1R:UDT34U8/C]H8EHY7VMU?7I\=VA@/S9::V%F
+M?6YF:EIK:G)Z?6],7E9 at 24Q/?8-W7E98-UA)8GIW6C]58S ;.6I<(!L_<H-U
+M9S8E.U1):G5R8V"&14E:=75Z W+W1%AP:2(Y8TE9:UH[6%EJ?V)J<E9;:G!%
+M16MG*1T[.R4_7R<V:GHV5&MC63=,6UMR=H1J/V(_+4QR=8)O:VIK<E0M/FAX
+M23DM)4EH6G!B;8AZ8VM:/W)Z:38_37*#;V%@6V%C;V \("TR8D0Y/"LM6W<M
+M&#!R=5X!, %) /Y9=7)B6FYN1#PR*T5834U@:VMJ5BT_:V-K8V@^.2 E37=)
+M,%]B/BT^8$E:8#\T36%;13]@6#DR25IF?8*%@&),:'!I8F at Y241$3$1O:EQN
+M=7)(:')O:%A$:7AU8EIA2$5[@H9Z6T];<#LE*3)T7ALP66UU=TD;-F!'8FM/
+M9TG8,&EK9G)Z?7UF85MR>R5!21TY;6MH3T1/>GIY>FI6:GMI,%MR22TY23(@
+M23(;86]:5FIJ34E%)TQW?89[6UI8.SEJ=8-Z9EIK>F<V+5]X6CX@%2U?5DU@
+M8 at 1RI&$Y6W)J23(B2'IK8FMB2%IR=UM//SE at 8#]/7C9?@&Y$-F-R< $M 44 
+M_F)U:V%83V- at 5F$T-DU)/D]K@'UC-C!C:V-C<DTR&Q@^:EA6:&([&S]H8%A>
+M-BTT8W!824\^)41$:&-U=7=[:UIK>FIB8CDB+4E%-FA?6UI::TU;:D]J:TQJ
+M?75L8F-:.5YT?75L8UMC6#8M-FAR62M86F9Z<D]H:DQ$6D1:6/XM36IJ9&AU
+MBEQC9G*"14A8*2)8:FA8.4UZ?'5]@EM;@HA?66-B8%9C;B4^/!LY:G!B6VI;
+M6V V.7*"@G);8V-F6&E;:5E6/V-Z=UD_8'=A+2<5,F8_,$DY)SYO>G!)6%IJ
+M83\I-F9B:VMI35MR>FIJ:&-C6B(P1#!->GI at .5F":W !- $_ /YI?W)K:VEB
+M14UR7BDY82TM.7J*<EDY4&):8WIW1"D;26A?:H-J23Q@<FIQ83\\.5IK:VQH
+M23(R56ER=UI;<G!K;7IK65I)&QM<9UAI6FAH1%!J8F)%35HY7(IR;G)S8C]%
+M1T]R<FE>4$TY*5A6<G))6%E;<X1W>GIH1%A<+W?^8E]B:V)3>H9:/V)Z=58P
+M/BD8275:/CE%>GM(4'MB6G6"<F-/86)8:G(V2$0[/EF!<E!B:&!I6#!J=7I[
+M4%!C:&MK:FI$24E89X!8241B6!LI&"5D/CY8/!@;8'IZ<&A:8FE+9F!>6F%@
+M:&AR>WIR<G& :TD8&!L;.7)B.3 Y at E]P 5@!20##9GIK67&(=UI;:G!>2V@[
+M*259=7IR6%9B8EMKBF@[+4E at 8&9Z:DQ;<'IN at 7-)/S])8%@P23\M-EAI=X!-
+M1%EB:5!R;P-)_BTE+4UK;UI-8V!-:G!C65E)(D>";6YU9FI$/E9:8G5]<FA-
+M.2<^.4QH6&)H3%Z#>GJ"<D=621MR=6)97FM<9G5S5D5K?6I%5"4.-G)W.24P
+M:W]),&)C<G5Z<FI-345)8V,V6FAI:4^#?4Q::V-B<&!J8G)]9EIH3%MB9FY$
+M-J988$1H3UE96DDI(!@I5C9I:DD at +6=U>FYC:6%@-F!J8$Q)/DE9:@-ZD6UR
+MA8)C,AT.&#]K8D0^.3E? 6(!6P#^9VMB3&:"@G5R<F9F8FM at 255@65EZ:FAC
+M:V!8>F\Y,C9)7W=R8$QJ<VYF:7)A-CPY358M,BTV668V4()P33 P8$5(:$U-
+M6#LI)39I<EI:8V!86FIB6FEI*2=C>GUV8EY8*59K6V9]?6YB3$M97E8_.6N"
+M6S]B8UMK<F)@225:_FIJ6EAN=5I9:&))6X)R:FA/%1):>E\R&SEB/BU8:FUZ
+M=69U<DE%:7!;-D1R;7=6 at GPY25I?1W-K:$1B>FYL8F!-6DUC/R4Y84];:&MH
+M13]F:S8V6#9 at 8TDM17)Z at F=)8VIC/D1O32U)7#8P16YU;EEN>(IS7"D8(%9W
+M8FAB6X)96 %- 5L _FMR85E>;GUU;H5[9EYF;U]-8VE/5FIO8&- at 6X)R138E
+M.59J:U]-:FMC;UA9:$E$-EA8-B ;&U9?)2UK<G!5+45936MH6&!%)14E87!:
+M6&M964]J8UAJ<TDB.6N%@V]96#8^4&E;;H-B638Y;7)H(B5CBG59/D0^,&IZ
+M>G)8:/YJ8V9S>WI;35A-.6.'9EQ/;2T5.6)17"4R/B451&)1>GIB;&I,27!P
+M:D0R8FYW7WV%.24B/CEB86-)2&MC7D1I84DK8V!526%;6V->:38I8H!H/C])
+M544^5&AR;7)6/&)R>F at Y8C\;+5A$-C!:<6),8&Z)@&U0-BD_:&-C:$V"5EH!
+M-@%( (U$:FE866)Z:UQ]>F)J W+^1%MK8S8Y8TU:8BER@&I?.S!)6EI-:'!K
+M;VM83'!I6&%L8#L@%2 V53Q$64U;=V9)65MC:UAF21 at .%4E987%X6CER<EIC
+M>GUA&QM,=75J63D[*2=,6D=R8CD;&TEA2 X218)]<CXM)25-=8IU:F]R8V)U
+M?8=S8$DM%3EZ8FAB\&)@0DE-3VE)/CPI(#9H17*"@G5H24EK:FII-D1RAG)M
+MBDP2"14M:6I;6BTE,CY%8G)R:5IO:UIJ:W)K6V(V-&%Z@&IC8$@M+5AZ>G)C
+M-BE8;H6#6F!-/"TM-C9$8V-J6EIC>GQW:%Q)7EI at 8FM),#X!.P$M /X;/F=O
+M6EMF;V)M;F)B?7UF86!K;S8_22DY6C!;<G)W;C8P2S8V8FIB<G ^,%]U46MN
+M8D08)3PM-FY at 1"4Y:VA-85M$145J/R4K*40P.6N 1R>!:DQB;8)I*R5-<FIB
+M338I1$0M/DUI6TDI(#<V/AL8179M=CX;)3Q$37UZ66K^>W9N<F)M at W)H238_
+M6C)H at FMK<FQ;8W=P:$0V5#YJ25E\BG5 at 14EA8V9I,B)B?75UA7(\& XB:&YB
+M8#L2*UA51&I]>F-J<EIK;'MZ8TU526EW>W)R<#X;&$EZ?VY?)1 at E1X*":FA%
+M22TM-C]A=V9B6VE@:GI]<E at Y6F$_8W)9 at BTE 54!,@#^(!LY<G=;8GIR<FUI
+M:76"8F-F<GI)2%@M+44E/DQF>H- at +41+/%!P3&)H*14O:5IB:VM$($1N.QMP
+M;T0M/FEC3%]8238^8EA5-C9F+14^8AT.;V1;65%N339)<G5Z:E@\(&%K6#9@
+M=VE at 7DM$-DDW.UIM8F(M#B4M+1UB>41;_GUF7GIF66)F:VE86$4;27)R>H-R
+M6DUN>G5<.5I94$DO9X!:.5AI87!K6"TM6G)J=75]=#(.&$EJ:G=H(!M):&)Q
+M=6YB:FI%8&J"@F(^6%EK<FMK>H)8&!4R7G=B13 .%2UQ=7IP36 _+3]8:75]
+M<F=W7$QZ;G)?-C!)'3EO38(M-@%- 40 TRT8&TUJ6FEZ:F)J;&)H238V26EC
+M8G)O23E%-CLI8(*#<#<V2556:VAB:" @.UE96F)H,A at R8U4E:F])/DUK:$]8
+M8$E8240Y7S(;6DD;,C\M*5I0 W+^:SDB/WM\=6I,-"!I>FH_27IZ;V)A24MI
+M.4EJ>FY@*1TT/#(I7V(M7VQ:8GIZ9FY>8V!816Y at -C)8=VMJ34UK;75K36!J
+M7U at M27)?+4UP8V9X23(_8V-K:FIR;5\R(#9-8GQW)0X;-F)Y<FMF:&\V-EEU
+M at F))25A at 8TU9:W)BJD4T-DQB:4PT&#Q@<G)Z<F)@-ALV25IB9GIK<#XP8EI<
+M:V _.R4^8DDM, %; 68 _E4M-EY816)Z:$UB<FIW324 at -F!06G*(;UA)/S\E
+M27J":C\V.41C<'IR:$])7EI9:')I/" @241)=W!-/TUJ:UE)6$1-6TPV23XM
+M.6@[.4E98%A$<GR!>E4R+6MU=7)-(A5-;F@^+VN"<DQ))TEW,#9%>H9K23)%
+M:5Y)8#DE;^%J65IZ at U!-8%M-;EY:338M6W]B:TQ8:V)C:F9K:VIC539,6#Y%
+M<FI<>U at _16E:36)J9F9J5C8V/V)R;S8@&!56<FUJ:GJ&6C]B>G56,#XR*4EJ
+M7TE%6&%A64E-:&X[&TEB W*<9EQG.R 5)3E%1%QJ<EE56UA,7&MI6"U<:%A4
+M-@%% 6\ _E])6VYI86AR6D5J>G)_>#P5-&%>-C)J at F))+4EI6&Z#>G!A/CM@
+M46-C36)K=VI66G!W:$0M+2 ^@GIP8V-S:UM)2S\^8FIW8E at Y-EA8+45J8EE+
+M;H-]?4PV56IQ>GIB,#E64%DV%3YZ at FHM("UA1#85,GIK.4DP,$1H:#8;.?Y:
+M6$1:>F,Y26A%7GMZ<3\;-GIC;EI-3$U@:UQR<F)B.2 R)1 at M9DPT8FI@-UI<
+M-EIC9G)F645)6%IJ;UA$.S)C<G)F<69U<U9%:WUJ150M(#9R=TD^26)@63\V
+M6FM>/S]$6F-B7TUH9D0@(#9)3UEB8DUC:%E,6FIR6#!;33F"23X!+0%6 /Y9
+M6$5-8GI[=SX=27IF>H!$%1M$<#L2.7]W-A(G8F)L at WIR<%AA?6%6/RE/:WN(
+M;4E;<FMB840I+7)Z at G)F?8)H/S\V/V!:<FIH:%M;5ATE6EI%8&IQ=7UB,%9L
+M>G9V<DEB:$TW238Y9H6#8%5%66IH,BE-7S!$9CXM6FY@,BG6/UA)6G)A.4EO
+M63]:>H)M($AS9G9K238B.7!F>H-J;3XR,A4.$D1F14QR;T5);C\M/G)Z<F-?
+M239+8F)6)5IJ:EI8;G5:66AB25N"<FIH3R E5G5O:58#2:<_66MH1#Y):& _
+M*1LV:VM8/RDV5EA'<&]86&9K;VA>:V at V34DY.S\!50%/ /Y@:UDT1&]Z>DD[
+M-DQK;&M9,C)C>E4@)6)W/R!$2$UC>GIB8E at _:G)A52LE16:">W=?7&MC<&D_
+M+6)Z at GIF=HIW230M/V)B:V)J:F)Q:"(5,BT^:F)$8W-C/T1-<FYZ<V-U=6H^
+M22T^:X:)<F)56&)S8#P^8%IH>FA66G-K6BWH-F!B1%M:/DUR8C\V:WIK)25:
+M;W)R;UXM+4E';7AN?V P1$$8#BUH5DEM<FA)8G!4/V9<;8!K8#])>GIR6&AJ
+M8V9S=G5F35A-.6.'9EQ07S8E/F1F:V)<2U8Y37ER22U$>V$V&Q at M8&@#294Y
+M/UE-6G=P.5IR>W=H7G!@5EI5)S\!=0%; /Y/:FQ>26%<<E!I22E;<#\_/D]Z
+M>ED[,D]R;45H8$5/<GI,1V Y6F)?:F @)3EW?7IJ1UEB9FM)*4UM?7IR>GU[
+M:30T16)G;VIB;F]U>E\[/"5%<EE$:6%/6&!;:V9<8VYU at GI8+1(I:'V%@F))
+M16QK6U0Y33]B=6)0:'IK:27+)5AK.3]-15MZ8TL_8W5A030^35Q9;UQ%/U99
+M=VYB;7 P268I&"U,:%E::V--66IP3&)07'IU6CE6=8IU:F]R8V)N<GIK8$DM
+M%3EZ V*R6DD[/VA/:W-K8U at V1&MI11LM85A5/#1);V [5FA at 15E96FMP)TQN
+M?8)J7FMK8F!+)2<!@0%I /Y61&ML8VMI:%MC8#Y9<"T;+45W<EI6/S99:UMH
+M:%E8:GIF14P^23]$<(%<)2=B<EQB8#E0<&D_)4EH<G9N<GIZ<E at V26)J:VYF
+M9G**C()C:#]:@FM68TL_3W=N:F V26I]A85P*0X at 3&IUD'=$)6IB1&E88"\Y
+M2# G37=<83G^&S96.45$36AJ341A;W):5G!?/F),8F)814AK at W!B9G),36]+
+M-DAS9D5B<$4Y7UEH6FIO;6UZ:#!):VLY+6N(;TU86UA+66E>-B56<EY%240[
+M.V-+8WIV<FM at 6&MP9C0I)2=8:4EC>FD at 86QI154_3V)K/T]<<HI[8FIW;&-$
+M at AL; 6L!:@#^9#E-<5IBA7=O:G):8G<[&"5);VI:65Y$14U at 2%A)1&)M;V _
+M/#(@)6!U=U9"5EI%36 at Y.6):/!@R2VEO:VIN=7AB-C988&-N<EQJ?86"<EIH
+M4W5V<#XB("]J<FI$+55R<'J#?UX at .VE:/WJ/3!LE239,8G)J9%DE%25-6$18
+M_E0Y+256,D5P:SXV8GI[8$E[=V%R;V)06TD_:GQU:V)R;F)K;%XE6F];6VM8
+M.59@:VMR<G%B:G)9+7)L63YG?7IL6DE%-C]K:388(F)F/U5 at 8&%82VMR;7N#
+M<EEB>WMF6!@8+4]A<'YP,EMJ;TU)1$5?:F)@676%@F)0:F)B88(R)0%8 6@ 
+M_FM).6MG8(%N8FIR:U!K6#(M8VIC34UO;UMA:UI-/SE:8V)@/S8R$C)63W)R
+M:FM9/V%K63E)-CLR-D5C8VIF9G5W:#8V3TE;;X)-/W)R9G(_7&9B<H(^&!@M
+M6VI8+2)8?VYJ;7IW-C9@:"]- at G<\*4E),#]LB8-X64\_1%M84/YK6S9$6#M$
+M8F]$-DQR<FA88F9O:H)V8&!%/FMZ=&U;:G)Z>GMW-#Y-6VEO84E)36MW;FUR
+M6FMR?S]X8$]N<G5V?7)@6$0V<WA)*2M)33!C:FIP-F!S:UMZDG=/8WJ"=6Y!
+M&#(M2W"">DEL<FI9-BTM/W!933EK?7IR8$E$9W>":%4!+0%- +IA6#!6<GJ"
+M<FIK;G)C7TQ516)@6F!-<6U-37MZ:4(V8%Y?7UI>,A at I23Y::W)Z;TDY3&E@
+M63\R)4M: V+^:FYR>F(^/U at V-DU[:DUJ;U!S8F)R:FJ#<$E51#Y812TE17)]
+M:EE::TU).5E$)UEZ6C!-:F P1'J">FIK<&$Y6G)J6"=986AK8VM-241K8EI)
+M8#]:6X)R=8AK15IR<FQ8-C)B at GUZ<%\^375Z:EL[,&F(<F9O1$]B<FAW86)R
+MPW9N<G5R>G=)&V]W8#Y at 838E5F)B:RT^8VM/:HJ"6%9J at X-U<$M?7DE!8F],
+M:7IP8S\I,B5%<$DM3')Z<7 \)4QZ>G@!( $E /Y6.2T^:G5V<G=O6FQP6DU8
+M16EF14E;;VH^/W9U;U4V6FI02#E8,C(K+3984&)U>G!$/F)C:4\R&S]@:G)K
+M8FMN?W)A6EL_-C9J>F)N:C]J at FIZ<FIU<E!K6# [/C8I26Z"A6-::EI:24Q@
+M56%R6B(V66)?-EAZ=61F<G!$377^>ULG.4UMB'IR6F-S:6%)-G=;6SEK3V:%
+M<D]@>FYZ8" 2)UMR8GMW85MU>V-:&QM;@GUR<EE:;V9J8F9R=79C:6-:7'I4
+M$EE]6T5;<5E):V-:8C8T3VE%1'J*:3!%?'MV<FE,8G(_1%H^6E%C;V V1$0Y
+M;V at _16-Z9F)5+2UC at H)Z 38!,@#^:38M26-K7E-M8C!-8TT^245I8T5%7FQH
+M6$V#;EI8&SEK8TDV/BDM+1 at M8#Y%:WIR:%I?85%%22DV6&IN=6I>7FMR>V]B
+M:$DP3&)<8F1;:W5J<FYJ<FE-:V-)+2TI$B5-=(9U:V)(259$3$E(:F\V25A9
+M8D1$<FY>3UQN:V-U_GUZ8$\Y6VYP=3E, at F%8.5AR<F,P341J<DTP17=M?6L\
+M*RDY7SEB9F]C;GI[=PD2,&IZ=7IF8FIB8F%K?&YR:&QP:6MW7A at Y?W _27%I
+M3&IM36)$24MA65AQ at G V/F-F=6)@)T5P5#\\/%DP*V!H-C]I6W)J35AJ>F),
+M6#\M38)Z>@(^ --F5"5):&!,35Q at +3!,,B4[26-8/UAB:U]86GI]8E at I+6!P
+M65IF.3(@%2EB-CY?:'%O8FMI23 [*3!-6EMK?V]:3&)R:F)B53\V.TU$8G)R
+M9FIZ;P-K_F)B7E\R.R )"2UF<G6">C9%;UI$+2=/8D5K<F)K8D1K9F!-,$1B
+M6G=Z;'6 66M%6G5N8'5%-D5;8H!L23]$:VM$(")@;'IU<FA at 6$DV6#]:3411
+M;H,P("U6<G5U;7J :EA@;H)V;FQF>H!V@&,8&UAI-C!:@&]::$U:,&%92:I)
+M:7)M>F-I:4AF<UDV66E)+2D\:3XE6%HM+4UB at G)6:GIZ:T0Y24]B<G(!,@$M
+M /X^/AU%;VMC:&-I7D5F+2DR-DTM+6]_:$U,8GJ%>VA85EIJ65ER8$0T*TM@
+M-CY/87!P8G)_:#8E,#!I6SE:>G5J5EIB9G),6$DM)S8Y8&I:8EIR<EQ1:FYK
+M7E\V-CL."1LG-TA3@$4P66]A/BT^.3MS>F9C:EIP:FI,)38V,&+^6SEDC7]W
+M.41@@XEN-BUA8V)Z<EI))SY0;4LV7UE/<H)J;UH_-FA at 6UXV,$AF:&!@6FIB
+M3&2!BGI--W)Z<V--3WV&=GUP/"DY7U E+WJ 8V-;8B5,6D5)<')1:F)J>$5%
+M<FMB:W<^(!LV8E8_35 at R+3!C?7--9'V#<DD[37)O at F); 2D!&P#^/S(8-G=U
+M8VA;<F at _:"TM53LM$AM:BF]).5IK?8)Q9G1K<FI><FMI239M3S9%6VMJ;UI1
+M@'=8+3DI8V8V67IZ<F]B36N"3%@Y+3\_/EEB6%M-7&I),$1M;F)B24D^(# [
+M(!L;,')I2T1B6EM813(E8'IV:V),8X*":E9)*2!9_DDG1'V*:#E%8'9[8B4M
+M:%E:8E9-21L5/H%R:W)5(EEW4%EA-C9H<F-I7E5/6EIK<G!C.25,>H9[12UJ
+M;FM))S!WBGU]>VE>-D58+2=J:V!P9U!+8$4M/G>!;F)16G=C6%IZ>G)_21(.
+M&UII;G!?.QLB86YJ.T5U?7)).5AR at H)J3P%5 40 _F<V&!M9<DU)37%R7V([
+M)UA4)0D5,'IZ:$D^17)Z<F9R;&UN;FI/8V _<%0E+4EJ<FI6169B3S9$-V%?
+M.5ER9FYR8#EC>FEG*25)9EM;:DU::VIK5C8G8G)R:EIC8$EJ=V _1%]U>W!C
+M8TA-<DPI,$59;G]B+39W at FU_6" 58)EF35MUA6 V)UIU<ED;*59):6 ^630.
+M#B)B VKD21(M7T1,:$0;8H!L8V);8%LP16N :"4827)Z>F)%6VIK1!@I:X)U
+M?7MF:#8^:4E):4U$=8AI:W!%&R5$>X9W8%IK:$E$@(-ZAG P#A5$6WJ0;RT;
+M,DEW;S8P8%YB8$D^8(!J/P%; 7< _H!)*25)8DD_.4]Z@&9A14E?52 8(%9T
+M>FM$)4QL8EQ08V-F>FA$3UE-:%@I%1L_>G)F1$TY138V.TE8,%AB/UIJ7S9:
+M<EEL)0XE1%EB:CY- at GUW8D(I6&)R<DQ,2#!>?7IF:G)F:VIM=T0Y:EH@*41%
+M3'5C/REAAVUZ8"4 at 8_YL9EEUBEE@-DQN:VD_7FA-<'552QL)#B!)34P_7T19
+M7C8P6FTM8GIR6CY,6EHE%39J9QL88'I:6G)F8V-K2R M:WIV<'=L6"DO;W!:
+M:38B8HIZ:WAF.SM99X)]<V-:8"4;8']K;H-@(" V,FV2>C\I5$1:=SXM6#8P
+M65 at V,'*"<#X!+P%J /Y_<G1D:&)8-B4I:Y!R8V!)6FA6.Q@;/VUM7SPY8DP^
+M+4E82')I/S998&A8/"D at -FAR;&AH25]$)2DM1"TV238Y8&!B;VM)8$0@*TM-
+M8E8;+7J*>FI,+3LV8H!C2S V-D^&>F-U:59%6WI;36IP4 XM6&IJ7%I)6GIU
+M:U at M/&/^:V]$:H9M:FAC8DAO15AT8'*!6&8M&!A$<&]?8&MK>GI:.T5H5EIB
+M5CDI*4];.1LM6F at I(FN -B=Z:VMQ8#8E+4]K>V-(:ED8%4R"<UDE&U9U=F-K
+M:4E/:6MU=GMP7U4@#BUB:5YZ:3P\-C9K at G):.S8_.6E--EA$&SY?21L_ at F%>
+M 14!.0#^6EIW>G]R:#8;-%AU:UIW7TMH6TDI$BU:8E]F25]8-BU886)R;S8;
+M/VAP/S9>7D0Y6FMR=V!A6#PI(C8G*SPM-EA1:WIR<&E@,BE$8$PP#AMKC&UJ
+M8EA5-F"":TU-7B4=>FUQ>FU6-DUZ6T1F:V@@&$EZ<D\P6F)M<G!A-E1K_F-9
+M-TQ;6W)VA&H_8C\M3')U at F&(;SXE/VEH6FAK:G5Z<E],:&%H8#XE%2E)6& M
+M/FIB.R5R at S8.:VEC=W ^)39837)Q3&)%'1 at V<FI)*39:7%MC8DE%6FMB8F9S
+M<&A>(!4 at 66]><F),8#!><'MW8F=98&AK7SE$4S9):&@R+8(V80(M /XM-FEN
+M at GUO025$6$Q--G):/FAO669$/UMO:F-B8V \+5AC>X-Q5"LV8'$_.6)_:$59
+M469U>6M;8$M>6#\T*QLV6$QC>G5W8ED_/#=H1"TP(%B*;6)-8V=-8G)B/UI:
+M.RER=&UZ<%A%2']B/VIJ;S8;-GIZ6"U86V)06V%:5FK^:DU)12=,=WV&>UM:
+M6#LY:G6#>'5\8UE4/D5866I@:V=R8F)J;W!U51 at .&T1)8C\Y7S @&UIZ21M@
+M6EM[>F]/86%%8W=>:#8@(#]Q:U9-24AZ>V!;)2!9:UA)/D4[#A at 8-#)9<FMS
+M;%MH-F!O>GIK:$UA=7)R=%@M,%9R at F$_ at BM+ 4D!+0#^,BE):G6">E4M7FA$
+M33YB3S9:<$]B;TU-<H!K9F]J5C8Y37J%<FA95&AP24EC?'-8/SE(9GIR8F-:
+M:&M:9#P;+4E)3')W;6)$+T0Y:CXE,AL^<'-B16%L<'IU33!;6DL at 3'IU?7UP
+M3$EK;V-H6V@\)4EU=6A-7V)H13E(<&);HVI;6V V.7*"@G);8V-F6&E;:5]'
+M<FMF=TTB6$QB.5E-5D5: W+:@5 at 2#A4^8&]?24DE%1M8;UHV:C ^<FUM:GIK
+M.5IW8TT_*2D^8UI47UA6:GMK5CM$66A:369A2RDT/%Y%2TE$:G!:65568WUZ
+M:EI9/S]W=8J%22DV6GIO7CM6 5@!.P#^1!LT26-R<E at M66):7V-H-B5)8$Q/
+M8E at Y8H)Z:G!P7%LV,'*"<4UB6F)R63Y$=X%J6#LM8'!C:%I:2&-<<%0M+3Y)
+M269J:EI?/EE$6%8@%1M)/V- at +45B<GA]:TU?8V [,EER;GR'8$U96VMP3$PI
+M)6*#:V9B8FIJ33!9 at 7)0VF)H8&E8,&IU>GM04&-H:VMJ:E\P8G=B<$0V25I6
+M+3])+25):V-R>F$=#A at M27)R:V$_-%AK:U at E1"4M1450;8!O.4UR;%M9/RTV
+M1#\_65]U=G5J5CY)/FEG.0-CHVEJ<7=B83\;-EAB6$DV.7)Z8D4_)1M;?(:*
+M:$1$16EC8$E6 5\!60#8:6!8:TUK<$D=16A966-W6B _8$587T]+6GUZ9TUK
+M8V9$/UQU:CE%.5IK83\\37!P:%\_35M)869%7V!,6DT_-EAF3VEB;%!;6FJ 
+M>F=8,BU824U?-C]$9P-R_F-D<FI:23EA8VZ"<E5$16-S6C<I)4E]:F-B8G)Z
+M21U:@WU,6FMC8G!@:F)R?69::$Q;8F9N:#Y,9&IR7UE?6F!%1#L8#CYJ8&IK
+M9D$T1#8_>H6"<EE);WIJ52 ;138\-$EB9G)8;&YK86!A2V%)250P6G)]@VA%
+M,"TM8W=I6:5;6FIZ at 8E[640@%2UN:4D^,&)J:5XY(#!$:G6";EE-25MB8U9?
+M 4T!:P"O@&]98C]@:5HV16A98S]B:$E):6!86UAI7G)U6SE,8V),245J<F!$
+M/U9;5DEI:6,#8OYH;V!-6V I26]@23Y$&SEI4&-B=4]C15&*C()W239)6V-B
+M25Y916J">F)9<GI/22T_8DE;@G)J:$\5(DUO+4EF34E$.6^)8"U, at GPY25I?
+M1W-K:$1B>FYL8F!-6DUC;T1-6UM-4'!B6F--5C8@($5H:%8T,C(;*U1,:GA]
+M>EG.3'*"<F,_,EDV13]:;TQ98GIN4&IQ6V)Z8F-D*3Y99GI?/D0I(#YC>E!9
+M6UIN at H)_:54@#B5A<$E$25A$8&QI.RU6:&9]>V)).3E8:$U8 5D!=@#^BG=/
+M8R4V5E]%8&I,:U at V6$DY8&!8/T]R>GV":#\_8VI at 23];:F!6:&!8/S]K>G)K
+M3TUR at GIJ:VL_6FMK:$D\*3];8')R:E!B24EU?7V*;D])35IB3&%)&U"*BF9(
+M6GIW.2TV33ECAV9<3VTM%3Y?6%AB.2 8%3EP>F]F?84Y_B4B/CEB86-)2&MC
+M7D1I84DK8V=B:FMC+2UB8D]C8U at W24U:;W)H7E561#9)+3YJ;G):4&YZ=7IK
+M63\V56!I<F8_1'=K1%QI+3!W?%M8/%A98VM)+39;(!(V:%I86EMN>VYM<%DG
+A&#9B<$M)66 _,%I[<"TV6F)R at GIP5#!)6H)@6 %9 74 
+ 
+end

Added: vendor/Python/current/Lib/test/infinite_reload.py
===================================================================
--- vendor/Python/current/Lib/test/infinite_reload.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/infinite_reload.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,7 @@
+# For testing http://python.org/sf/742342, which reports that Python
+#  segfaults (infinite recursion in C) in the presence of infinite
+#  reload()ing. This module is imported by test_import.py:test_infinite_reload
+#  to make sure this doesn't happen any more.
+
+import infinite_reload
+reload(infinite_reload)

Added: vendor/Python/current/Lib/test/inspect_fodder.py
===================================================================
--- vendor/Python/current/Lib/test/inspect_fodder.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/inspect_fodder.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,56 @@
+# line 1
+'A module docstring.'
+
+import sys, inspect
+# line 5
+
+# line 7
+def spam(a, b, c, d=3, (e, (f,))=(4, (5,)), *g, **h):
+    eggs(b + d, c + f)
+
+# line 11
+def eggs(x, y):
+    "A docstring."
+    global fr, st
+    fr = inspect.currentframe()
+    st = inspect.stack()
+    p = x
+    q = y / 0
+
+# line 20
+class StupidGit:
+    """A longer,
+
+    indented
+
+    docstring."""
+# line 27
+
+    def abuse(self, a, b, c):
+        """Another
+
+\tdocstring
+
+        containing
+
+\ttabs
+\t
+        """
+        self.argue(a, b, c)
+# line 40
+    def argue(self, a, b, c):
+        try:
+            spam(a, b, c)
+        except:
+            self.ex = sys.exc_info()
+            self.tr = inspect.trace()
+
+# line 48
+class MalodorousPervert(StupidGit):
+    pass
+
+class ParrotDroppings:
+    pass
+
+class FesteringGob(MalodorousPervert, ParrotDroppings):
+    pass

Added: vendor/Python/current/Lib/test/inspect_fodder2.py
===================================================================
--- vendor/Python/current/Lib/test/inspect_fodder2.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/inspect_fodder2.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,99 @@
+# line 1
+def wrap(foo=None):
+    def wrapper(func):
+        return func
+    return wrapper
+
+# line 7
+def replace(func):
+    def insteadfunc():
+        print 'hello'
+    return insteadfunc
+
+# line 13
+ at wrap()
+ at wrap(wrap)
+def wrapped():
+    pass
+
+# line 19
+ at replace
+def gone():
+    pass
+
+# line 24
+oll = lambda m: m
+
+# line 27
+tll = lambda g: g and \
+g and \
+g
+
+# line 32
+tlli = lambda d: d and \
+    d
+
+# line 36
+def onelinefunc(): pass
+
+# line 39
+def manyargs(arg1, arg2,
+arg3, arg4): pass
+
+# line 43
+def twolinefunc(m): return m and \
+m
+
+# line 47
+a = [None,
+     lambda x: x,
+     None]
+
+# line 52
+def setfunc(func):
+    globals()["anonymous"] = func
+setfunc(lambda x, y: x*y)
+
+# line 57
+def with_comment():  # hello
+    world
+
+# line 61
+multiline_sig = [
+    lambda (x,
+            y): x+y,
+    None,
+    ]
+
+# line 68
+def func69():
+    class cls70:
+        def func71():
+            pass
+    return cls70
+extra74 = 74
+
+# line 76
+def func77(): pass
+(extra78, stuff78) = 'xy'
+extra79 = 'stop'
+
+# line 81
+class cls82:
+    def func83(): pass
+(extra84, stuff84) = 'xy'
+extra85 = 'stop'
+
+# line 87
+def func88():
+    # comment
+    return 90
+
+# line 92
+def f():
+    class X:
+        def g():
+            "doc"
+            return 42
+    return X
+method_in_dynamic_class = f().g.im_func

Added: vendor/Python/current/Lib/test/leakers/README.txt
===================================================================
--- vendor/Python/current/Lib/test/leakers/README.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/leakers/README.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,32 @@
+This directory contains test cases that are known to leak references.
+The idea is that you can import these modules while in the interpreter
+and call the leak function repeatedly.  This will only be helpful if
+the interpreter was built in debug mode.  If the total ref count
+doesn't increase, the bug has been fixed and the file should be removed
+from the repository.
+
+Note:  be careful to check for cyclic garbage.  Sometimes it may be helpful
+to define the leak function like:
+
+def leak():
+    def inner_leak():
+        # this is the function that leaks, but also creates cycles
+    inner_leak()
+    gc.collect() ; gc.collect() ; gc.collect()
+
+Here's an example interpreter session for test_gestalt which still leaks:
+
+>>> from test.leakers.test_gestalt import leak
+[24275 refs]
+>>> leak()
+[28936 refs]
+>>> leak()
+[28938 refs]
+>>> leak()
+[28940 refs]
+>>> 
+
+Once the leak is fixed, the test case should be moved into an appropriate
+test (even if it was originally from the test suite).  This ensures the
+regression doesn't happen again.  And if it does, it should be easier
+to track down.

Added: vendor/Python/current/Lib/test/leakers/__init__.py
===================================================================

Added: vendor/Python/current/Lib/test/leakers/test_ctypes.py
===================================================================
--- vendor/Python/current/Lib/test/leakers/test_ctypes.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/leakers/test_ctypes.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,16 @@
+
+# Taken from Lib/ctypes/test/test_keeprefs.py, PointerToStructure.test().
+# When this leak is fixed, remember to remove from Misc/build.sh LEAKY_TESTS.
+
+from ctypes import Structure, c_int, POINTER
+import gc
+
+def leak_inner():
+    class POINT(Structure):
+        _fields_ = [("x", c_int)]
+    class RECT(Structure):
+        _fields_ = [("a", POINTER(POINT))]
+
+def leak():
+    leak_inner()
+    gc.collect()

Added: vendor/Python/current/Lib/test/leakers/test_gestalt.py
===================================================================
--- vendor/Python/current/Lib/test/leakers/test_gestalt.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/leakers/test_gestalt.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,14 @@
+import sys
+
+if sys.platform != 'darwin':
+    raise ValueError, "This test only leaks on Mac OS X"
+
+def leak():
+    # taken from platform._mac_ver_lookup()
+    from gestalt import gestalt
+    import MacOS
+
+    try:
+        gestalt('sysu')
+    except MacOS.Error:
+        pass

Added: vendor/Python/current/Lib/test/leakers/test_selftype.py
===================================================================
--- vendor/Python/current/Lib/test/leakers/test_selftype.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/leakers/test_selftype.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,13 @@
+# Reference cycles involving only the ob_type field are rather uncommon
+# but possible.  Inspired by SF bug 1469629.
+
+import gc
+
+def leak():
+    class T(type):
+        pass
+    class U(type):
+        __metaclass__ = T
+    U.__class__ = U
+    del U
+    gc.collect(); gc.collect(); gc.collect()

Added: vendor/Python/current/Lib/test/list_tests.py
===================================================================
--- vendor/Python/current/Lib/test/list_tests.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/list_tests.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,522 @@
+"""
+Tests common to list and UserList.UserList
+"""
+
+import sys
+import os
+
+import unittest
+from test import test_support, seq_tests
+
+class CommonTest(seq_tests.CommonTest):
+
+    def test_init(self):
+        # Iterable arg is optional
+        self.assertEqual(self.type2test([]), self.type2test())
+
+        # Init clears previous values
+        a = self.type2test([1, 2, 3])
+        a.__init__()
+        self.assertEqual(a, self.type2test([]))
+
+        # Init overwrites previous values
+        a = self.type2test([1, 2, 3])
+        a.__init__([4, 5, 6])
+        self.assertEqual(a, self.type2test([4, 5, 6]))
+
+        # Mutables always return a new object
+        b = self.type2test(a)
+        self.assertNotEqual(id(a), id(b))
+        self.assertEqual(a, b)
+
+    def test_repr(self):
+        l0 = []
+        l2 = [0, 1, 2]
+        a0 = self.type2test(l0)
+        a2 = self.type2test(l2)
+
+        self.assertEqual(str(a0), str(l0))
+        self.assertEqual(repr(a0), repr(l0))
+        self.assertEqual(`a2`, `l2`)
+        self.assertEqual(str(a2), "[0, 1, 2]")
+        self.assertEqual(repr(a2), "[0, 1, 2]")
+
+        a2.append(a2)
+        a2.append(3)
+        self.assertEqual(str(a2), "[0, 1, 2, [...], 3]")
+        self.assertEqual(repr(a2), "[0, 1, 2, [...], 3]")
+
+    def test_print(self):
+        d = self.type2test(xrange(200))
+        d.append(d)
+        d.extend(xrange(200,400))
+        d.append(d)
+        d.append(400)
+        try:
+            fo = open(test_support.TESTFN, "wb")
+            print >> fo, d,
+            fo.close()
+            fo = open(test_support.TESTFN, "rb")
+            self.assertEqual(fo.read(), repr(d))
+        finally:
+            fo.close()
+            os.remove(test_support.TESTFN)
+
+    def test_set_subscript(self):
+        a = self.type2test(range(20))
+        self.assertRaises(ValueError, a.__setitem__, slice(0, 10, 0), [1,2,3])
+        self.assertRaises(TypeError, a.__setitem__, slice(0, 10), 1)
+        self.assertRaises(ValueError, a.__setitem__, slice(0, 10, 2), [1,2])
+        self.assertRaises(TypeError, a.__getitem__, 'x', 1)
+        a[slice(2,10,3)] = [1,2,3]
+        self.assertEqual(a, self.type2test([0, 1, 1, 3, 4, 2, 6, 7, 3,
+                                            9, 10, 11, 12, 13, 14, 15,
+                                            16, 17, 18, 19]))
+
+    def test_reversed(self):
+        a = self.type2test(range(20))
+        r = reversed(a)
+        self.assertEqual(list(r), self.type2test(range(19, -1, -1)))
+        self.assertRaises(StopIteration, r.next)
+        self.assertEqual(list(reversed(self.type2test())),
+                         self.type2test())
+
+    def test_setitem(self):
+        a = self.type2test([0, 1])
+        a[0] = 0
+        a[1] = 100
+        self.assertEqual(a, self.type2test([0, 100]))
+        a[-1] = 200
+        self.assertEqual(a, self.type2test([0, 200]))
+        a[-2] = 100
+        self.assertEqual(a, self.type2test([100, 200]))
+        self.assertRaises(IndexError, a.__setitem__, -3, 200)
+        self.assertRaises(IndexError, a.__setitem__, 2, 200)
+
+        a = self.type2test([])
+        self.assertRaises(IndexError, a.__setitem__, 0, 200)
+        self.assertRaises(IndexError, a.__setitem__, -1, 200)
+        self.assertRaises(TypeError, a.__setitem__)
+
+        a = self.type2test([0,1,2,3,4])
+        a[0L] = 1
+        a[1L] = 2
+        a[2L] = 3
+        self.assertEqual(a, self.type2test([1,2,3,3,4]))
+        a[0] = 5
+        a[1] = 6
+        a[2] = 7
+        self.assertEqual(a, self.type2test([5,6,7,3,4]))
+        a[-2L] = 88
+        a[-1L] = 99
+        self.assertEqual(a, self.type2test([5,6,7,88,99]))
+        a[-2] = 8
+        a[-1] = 9
+        self.assertEqual(a, self.type2test([5,6,7,8,9]))
+
+    def test_delitem(self):
+        a = self.type2test([0, 1])
+        del a[1]
+        self.assertEqual(a, [0])
+        del a[0]
+        self.assertEqual(a, [])
+
+        a = self.type2test([0, 1])
+        del a[-2]
+        self.assertEqual(a, [1])
+        del a[-1]
+        self.assertEqual(a, [])
+
+        a = self.type2test([0, 1])
+        self.assertRaises(IndexError, a.__delitem__, -3)
+        self.assertRaises(IndexError, a.__delitem__, 2)
+
+        a = self.type2test([])
+        self.assertRaises(IndexError, a.__delitem__, 0)
+
+        self.assertRaises(TypeError, a.__delitem__)
+
+    def test_setslice(self):
+        l = [0, 1]
+        a = self.type2test(l)
+
+        for i in range(-3, 4):
+            a[:i] = l[:i]
+            self.assertEqual(a, l)
+            a2 = a[:]
+            a2[:i] = a[:i]
+            self.assertEqual(a2, a)
+            a[i:] = l[i:]
+            self.assertEqual(a, l)
+            a2 = a[:]
+            a2[i:] = a[i:]
+            self.assertEqual(a2, a)
+            for j in range(-3, 4):
+                a[i:j] = l[i:j]
+                self.assertEqual(a, l)
+                a2 = a[:]
+                a2[i:j] = a[i:j]
+                self.assertEqual(a2, a)
+
+        aa2 = a2[:]
+        aa2[:0] = [-2, -1]
+        self.assertEqual(aa2, [-2, -1, 0, 1])
+        aa2[0:] = []
+        self.assertEqual(aa2, [])
+
+        a = self.type2test([1, 2, 3, 4, 5])
+        a[:-1] = a
+        self.assertEqual(a, self.type2test([1, 2, 3, 4, 5, 5]))
+        a = self.type2test([1, 2, 3, 4, 5])
+        a[1:] = a
+        self.assertEqual(a, self.type2test([1, 1, 2, 3, 4, 5]))
+        a = self.type2test([1, 2, 3, 4, 5])
+        a[1:-1] = a
+        self.assertEqual(a, self.type2test([1, 1, 2, 3, 4, 5, 5]))
+
+        a = self.type2test([])
+        a[:] = tuple(range(10))
+        self.assertEqual(a, self.type2test(range(10)))
+
+        self.assertRaises(TypeError, a.__setslice__, 0, 1, 5)
+
+        self.assertRaises(TypeError, a.__setslice__)
+
+    def test_delslice(self):
+        a = self.type2test([0, 1])
+        del a[1:2]
+        del a[0:1]
+        self.assertEqual(a, self.type2test([]))
+
+        a = self.type2test([0, 1])
+        del a[1L:2L]
+        del a[0L:1L]
+        self.assertEqual(a, self.type2test([]))
+
+        a = self.type2test([0, 1])
+        del a[-2:-1]
+        self.assertEqual(a, self.type2test([1]))
+
+        a = self.type2test([0, 1])
+        del a[-2L:-1L]
+        self.assertEqual(a, self.type2test([1]))
+
+        a = self.type2test([0, 1])
+        del a[1:]
+        del a[:1]
+        self.assertEqual(a, self.type2test([]))
+
+        a = self.type2test([0, 1])
+        del a[1L:]
+        del a[:1L]
+        self.assertEqual(a, self.type2test([]))
+
+        a = self.type2test([0, 1])
+        del a[-1:]
+        self.assertEqual(a, self.type2test([0]))
+
+        a = self.type2test([0, 1])
+        del a[-1L:]
+        self.assertEqual(a, self.type2test([0]))
+
+        a = self.type2test([0, 1])
+        del a[:]
+        self.assertEqual(a, self.type2test([]))
+
+    def test_append(self):
+        a = self.type2test([])
+        a.append(0)
+        a.append(1)
+        a.append(2)
+        self.assertEqual(a, self.type2test([0, 1, 2]))
+
+        self.assertRaises(TypeError, a.append)
+
+    def test_extend(self):
+        a1 = self.type2test([0])
+        a2 = self.type2test((0, 1))
+        a = a1[:]
+        a.extend(a2)
+        self.assertEqual(a, a1 + a2)
+
+        a.extend(self.type2test([]))
+        self.assertEqual(a, a1 + a2)
+
+        a.extend(a)
+        self.assertEqual(a, self.type2test([0, 0, 1, 0, 0, 1]))
+
+        a = self.type2test("spam")
+        a.extend("eggs")
+        self.assertEqual(a, list("spameggs"))
+
+        self.assertRaises(TypeError, a.extend, None)
+
+        self.assertRaises(TypeError, a.extend)
+
+    def test_insert(self):
+        a = self.type2test([0, 1, 2])
+        a.insert(0, -2)
+        a.insert(1, -1)
+        a.insert(2, 0)
+        self.assertEqual(a, [-2, -1, 0, 0, 1, 2])
+
+        b = a[:]
+        b.insert(-2, "foo")
+        b.insert(-200, "left")
+        b.insert(200, "right")
+        self.assertEqual(b, self.type2test(["left",-2,-1,0,0,"foo",1,2,"right"]))
+
+        self.assertRaises(TypeError, a.insert)
+
+    def test_pop(self):
+        a = self.type2test([-1, 0, 1])
+        a.pop()
+        self.assertEqual(a, [-1, 0])
+        a.pop(0)
+        self.assertEqual(a, [0])
+        self.assertRaises(IndexError, a.pop, 5)
+        a.pop(0)
+        self.assertEqual(a, [])
+        self.assertRaises(IndexError, a.pop)
+        self.assertRaises(TypeError, a.pop, 42, 42)
+        a = self.type2test([0, 10, 20, 30, 40])
+
+    def test_remove(self):
+        a = self.type2test([0, 0, 1])
+        a.remove(1)
+        self.assertEqual(a, [0, 0])
+        a.remove(0)
+        self.assertEqual(a, [0])
+        a.remove(0)
+        self.assertEqual(a, [])
+
+        self.assertRaises(ValueError, a.remove, 0)
+
+        self.assertRaises(TypeError, a.remove)
+
+        class BadExc(Exception):
+            pass
+
+        class BadCmp:
+            def __eq__(self, other):
+                if other == 2:
+                    raise BadExc()
+                return False
+
+        a = self.type2test([0, 1, 2, 3])
+        self.assertRaises(BadExc, a.remove, BadCmp())
+
+        class BadCmp2:
+            def __eq__(self, other):
+                raise BadExc()
+
+        d = self.type2test('abcdefghcij')
+        d.remove('c')
+        self.assertEqual(d, self.type2test('abdefghcij'))
+        d.remove('c')
+        self.assertEqual(d, self.type2test('abdefghij'))
+        self.assertRaises(ValueError, d.remove, 'c')
+        self.assertEqual(d, self.type2test('abdefghij'))
+
+        # Handle comparison errors
+        d = self.type2test(['a', 'b', BadCmp2(), 'c'])
+        e = self.type2test(d)
+        self.assertRaises(BadExc, d.remove, 'c')
+        for x, y in zip(d, e):
+            # verify that original order and values are retained.
+            self.assert_(x is y)
+
+    def test_count(self):
+        a = self.type2test([0, 1, 2])*3
+        self.assertEqual(a.count(0), 3)
+        self.assertEqual(a.count(1), 3)
+        self.assertEqual(a.count(3), 0)
+
+        self.assertRaises(TypeError, a.count)
+
+        class BadExc(Exception):
+            pass
+
+        class BadCmp:
+            def __eq__(self, other):
+                if other == 2:
+                    raise BadExc()
+                return False
+
+        self.assertRaises(BadExc, a.count, BadCmp())
+
+    def test_index(self):
+        u = self.type2test([0, 1])
+        self.assertEqual(u.index(0), 0)
+        self.assertEqual(u.index(1), 1)
+        self.assertRaises(ValueError, u.index, 2)
+
+        u = self.type2test([-2, -1, 0, 0, 1, 2])
+        self.assertEqual(u.count(0), 2)
+        self.assertEqual(u.index(0), 2)
+        self.assertEqual(u.index(0, 2), 2)
+        self.assertEqual(u.index(-2, -10), 0)
+        self.assertEqual(u.index(0, 3), 3)
+        self.assertEqual(u.index(0, 3, 4), 3)
+        self.assertRaises(ValueError, u.index, 2, 0, -10)
+
+        self.assertRaises(TypeError, u.index)
+
+        class BadExc(Exception):
+            pass
+
+        class BadCmp:
+            def __eq__(self, other):
+                if other == 2:
+                    raise BadExc()
+                return False
+
+        a = self.type2test([0, 1, 2, 3])
+        self.assertRaises(BadExc, a.index, BadCmp())
+
+        a = self.type2test([-2, -1, 0, 0, 1, 2])
+        self.assertEqual(a.index(0), 2)
+        self.assertEqual(a.index(0, 2), 2)
+        self.assertEqual(a.index(0, -4), 2)
+        self.assertEqual(a.index(-2, -10), 0)
+        self.assertEqual(a.index(0, 3), 3)
+        self.assertEqual(a.index(0, -3), 3)
+        self.assertEqual(a.index(0, 3, 4), 3)
+        self.assertEqual(a.index(0, -3, -2), 3)
+        self.assertEqual(a.index(0, -4*sys.maxint, 4*sys.maxint), 2)
+        self.assertRaises(ValueError, a.index, 0, 4*sys.maxint,-4*sys.maxint)
+        self.assertRaises(ValueError, a.index, 2, 0, -10)
+        a.remove(0)
+        self.assertRaises(ValueError, a.index, 2, 0, 4)
+        self.assertEqual(a, self.type2test([-2, -1, 0, 1, 2]))
+
+        # Test modifying the list during index's iteration
+        class EvilCmp:
+            def __init__(self, victim):
+                self.victim = victim
+            def __eq__(self, other):
+                del self.victim[:]
+                return False
+        a = self.type2test()
+        a[:] = [EvilCmp(a) for _ in xrange(100)]
+        # This used to seg fault before patch #1005778
+        self.assertRaises(ValueError, a.index, None)
+
+    def test_reverse(self):
+        u = self.type2test([-2, -1, 0, 1, 2])
+        u2 = u[:]
+        u.reverse()
+        self.assertEqual(u, [2, 1, 0, -1, -2])
+        u.reverse()
+        self.assertEqual(u, u2)
+
+        self.assertRaises(TypeError, u.reverse, 42)
+
+    def test_sort(self):
+        u = self.type2test([1, 0])
+        u.sort()
+        self.assertEqual(u, [0, 1])
+
+        u = self.type2test([2,1,0,-1,-2])
+        u.sort()
+        self.assertEqual(u, self.type2test([-2,-1,0,1,2]))
+
+        self.assertRaises(TypeError, u.sort, 42, 42)
+
+        def revcmp(a, b):
+            return cmp(b, a)
+        u.sort(revcmp)
+        self.assertEqual(u, self.type2test([2,1,0,-1,-2]))
+
+        # The following dumps core in unpatched Python 1.5:
+        def myComparison(x,y):
+            return cmp(x%3, y%7)
+        z = self.type2test(range(12))
+        z.sort(myComparison)
+
+        self.assertRaises(TypeError, z.sort, 2)
+
+        def selfmodifyingComparison(x,y):
+            z.append(1)
+            return cmp(x, y)
+        self.assertRaises(ValueError, z.sort, selfmodifyingComparison)
+
+        self.assertRaises(TypeError, z.sort, lambda x, y: 's')
+
+        self.assertRaises(TypeError, z.sort, 42, 42, 42, 42)
+
+    def test_slice(self):
+        u = self.type2test("spam")
+        u[:2] = "h"
+        self.assertEqual(u, list("ham"))
+
+    def test_iadd(self):
+        super(CommonTest, self).test_iadd()
+        u = self.type2test([0, 1])
+        u2 = u
+        u += [2, 3]
+        self.assert_(u is u2)
+
+        u = self.type2test("spam")
+        u += "eggs"
+        self.assertEqual(u, self.type2test("spameggs"))
+
+        self.assertRaises(TypeError, u.__iadd__, None)
+
+    def test_imul(self):
+        u = self.type2test([0, 1])
+        u *= 3
+        self.assertEqual(u, self.type2test([0, 1, 0, 1, 0, 1]))
+        u *= 0
+        self.assertEqual(u, self.type2test([]))
+        s = self.type2test([])
+        oldid = id(s)
+        s *= 10
+        self.assertEqual(id(s), oldid)
+
+    def test_extendedslicing(self):
+        #  subscript
+        a = self.type2test([0,1,2,3,4])
+
+        #  deletion
+        del a[::2]
+        self.assertEqual(a, self.type2test([1,3]))
+        a = self.type2test(range(5))
+        del a[1::2]
+        self.assertEqual(a, self.type2test([0,2,4]))
+        a = self.type2test(range(5))
+        del a[1::-2]
+        self.assertEqual(a, self.type2test([0,2,3,4]))
+        a = self.type2test(range(10))
+        del a[::1000]
+        self.assertEqual(a, self.type2test([1, 2, 3, 4, 5, 6, 7, 8, 9]))
+        #  assignment
+        a = self.type2test(range(10))
+        a[::2] = [-1]*5
+        self.assertEqual(a, self.type2test([-1, 1, -1, 3, -1, 5, -1, 7, -1, 9]))
+        a = self.type2test(range(10))
+        a[::-4] = [10]*3
+        self.assertEqual(a, self.type2test([0, 10, 2, 3, 4, 10, 6, 7, 8 ,10]))
+        a = self.type2test(range(4))
+        a[::-1] = a
+        self.assertEqual(a, self.type2test([3, 2, 1, 0]))
+        a = self.type2test(range(10))
+        b = a[:]
+        c = a[:]
+        a[2:3] = self.type2test(["two", "elements"])
+        b[slice(2,3)] = self.type2test(["two", "elements"])
+        c[2:3:] = self.type2test(["two", "elements"])
+        self.assertEqual(a, b)
+        self.assertEqual(a, c)
+        a = self.type2test(range(10))
+        a[::2] = tuple(range(5))
+        self.assertEqual(a, self.type2test([0, 1, 1, 3, 2, 5, 3, 7, 4, 9]))
+
+    def test_constructor_exception_handling(self):
+        # Bug #1242657
+        class F(object):
+            def __iter__(self):
+                yield 23
+            def __len__(self):
+                raise KeyboardInterrupt
+        self.assertRaises(KeyboardInterrupt, list, F())

Added: vendor/Python/current/Lib/test/mapping_tests.py
===================================================================
--- vendor/Python/current/Lib/test/mapping_tests.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/mapping_tests.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,672 @@
+# tests common to dict and UserDict
+import unittest
+import UserDict
+
+
+class BasicTestMappingProtocol(unittest.TestCase):
+    # This base class can be used to check that an object conforms to the
+    # mapping protocol
+
+    # Functions that can be useful to override to adapt to dictionary
+    # semantics
+    type2test = None # which class is being tested (overwrite in subclasses)
+
+    def _reference(self):
+        """Return a dictionary of values which are invariant by storage
+        in the object under test."""
+        return {1:2, "key1":"value1", "key2":(1,2,3)}
+    def _empty_mapping(self):
+        """Return an empty mapping object"""
+        return self.type2test()
+    def _full_mapping(self, data):
+        """Return a mapping object with the value contained in data
+        dictionary"""
+        x = self._empty_mapping()
+        for key, value in data.items():
+            x[key] = value
+        return x
+
+    def __init__(self, *args, **kw):
+        unittest.TestCase.__init__(self, *args, **kw)
+        self.reference = self._reference().copy()
+
+        # A (key, value) pair not in the mapping
+        key, value = self.reference.popitem()
+        self.other = {key:value}
+
+        # A (key, value) pair in the mapping
+        key, value = self.reference.popitem()
+        self.inmapping = {key:value}
+        self.reference[key] = value
+
+    def test_read(self):
+        # Test for read only operations on mapping
+        p = self._empty_mapping()
+        p1 = dict(p) #workaround for singleton objects
+        d = self._full_mapping(self.reference)
+        if d is p:
+            p = p1
+        #Indexing
+        for key, value in self.reference.items():
+            self.assertEqual(d[key], value)
+        knownkey = self.other.keys()[0]
+        self.failUnlessRaises(KeyError, lambda:d[knownkey])
+        #len
+        self.assertEqual(len(p), 0)
+        self.assertEqual(len(d), len(self.reference))
+        #has_key
+        for k in self.reference:
+            self.assert_(d.has_key(k))
+            self.assert_(k in d)
+        for k in self.other:
+            self.failIf(d.has_key(k))
+            self.failIf(k in d)
+        #cmp
+        self.assertEqual(cmp(p,p), 0)
+        self.assertEqual(cmp(d,d), 0)
+        self.assertEqual(cmp(p,d), -1)
+        self.assertEqual(cmp(d,p), 1)
+        #__non__zero__
+        if p: self.fail("Empty mapping must compare to False")
+        if not d: self.fail("Full mapping must compare to True")
+        # keys(), items(), iterkeys() ...
+        def check_iterandlist(iter, lst, ref):
+            self.assert_(hasattr(iter, 'next'))
+            self.assert_(hasattr(iter, '__iter__'))
+            x = list(iter)
+            self.assert_(set(x)==set(lst)==set(ref))
+        check_iterandlist(d.iterkeys(), d.keys(), self.reference.keys())
+        check_iterandlist(iter(d), d.keys(), self.reference.keys())
+        check_iterandlist(d.itervalues(), d.values(), self.reference.values())
+        check_iterandlist(d.iteritems(), d.items(), self.reference.items())
+        #get
+        key, value = d.iteritems().next()
+        knownkey, knownvalue = self.other.iteritems().next()
+        self.assertEqual(d.get(key, knownvalue), value)
+        self.assertEqual(d.get(knownkey, knownvalue), knownvalue)
+        self.failIf(knownkey in d)
+
+    def test_write(self):
+        # Test for write operations on mapping
+        p = self._empty_mapping()
+        #Indexing
+        for key, value in self.reference.items():
+            p[key] = value
+            self.assertEqual(p[key], value)
+        for key in self.reference.keys():
+            del p[key]
+            self.failUnlessRaises(KeyError, lambda:p[key])
+        p = self._empty_mapping()
+        #update
+        p.update(self.reference)
+        self.assertEqual(dict(p), self.reference)
+        items = p.items()
+        p = self._empty_mapping()
+        p.update(items)
+        self.assertEqual(dict(p), self.reference)
+        d = self._full_mapping(self.reference)
+        #setdefault
+        key, value = d.iteritems().next()
+        knownkey, knownvalue = self.other.iteritems().next()
+        self.assertEqual(d.setdefault(key, knownvalue), value)
+        self.assertEqual(d[key], value)
+        self.assertEqual(d.setdefault(knownkey, knownvalue), knownvalue)
+        self.assertEqual(d[knownkey], knownvalue)
+        #pop
+        self.assertEqual(d.pop(knownkey), knownvalue)
+        self.failIf(knownkey in d)
+        self.assertRaises(KeyError, d.pop, knownkey)
+        default = 909
+        d[knownkey] = knownvalue
+        self.assertEqual(d.pop(knownkey, default), knownvalue)
+        self.failIf(knownkey in d)
+        self.assertEqual(d.pop(knownkey, default), default)
+        #popitem
+        key, value = d.popitem()
+        self.failIf(key in d)
+        self.assertEqual(value, self.reference[key])
+        p=self._empty_mapping()
+        self.assertRaises(KeyError, p.popitem)
+
+    def test_constructor(self):
+        self.assertEqual(self._empty_mapping(), self._empty_mapping())
+
+    def test_bool(self):
+        self.assert_(not self._empty_mapping())
+        self.assert_(self.reference)
+        self.assert_(bool(self._empty_mapping()) is False)
+        self.assert_(bool(self.reference) is True)
+
+    def test_keys(self):
+        d = self._empty_mapping()
+        self.assertEqual(d.keys(), [])
+        d = self.reference
+        self.assert_(self.inmapping.keys()[0] in d.keys())
+        self.assert_(self.other.keys()[0] not in d.keys())
+        self.assertRaises(TypeError, d.keys, None)
+
+    def test_values(self):
+        d = self._empty_mapping()
+        self.assertEqual(d.values(), [])
+
+        self.assertRaises(TypeError, d.values, None)
+
+    def test_items(self):
+        d = self._empty_mapping()
+        self.assertEqual(d.items(), [])
+
+        self.assertRaises(TypeError, d.items, None)
+
+    def test_len(self):
+        d = self._empty_mapping()
+        self.assertEqual(len(d), 0)
+
+    def test_getitem(self):
+        d = self.reference
+        self.assertEqual(d[self.inmapping.keys()[0]], self.inmapping.values()[0])
+
+        self.assertRaises(TypeError, d.__getitem__)
+
+    def test_update(self):
+        # mapping argument
+        d = self._empty_mapping()
+        d.update(self.other)
+        self.assertEqual(d.items(), self.other.items())
+
+        # No argument
+        d = self._empty_mapping()
+        d.update()
+        self.assertEqual(d, self._empty_mapping())
+
+        # item sequence
+        d = self._empty_mapping()
+        d.update(self.other.items())
+        self.assertEqual(d.items(), self.other.items())
+
+        # Iterator
+        d = self._empty_mapping()
+        d.update(self.other.iteritems())
+        self.assertEqual(d.items(), self.other.items())
+
+        # FIXME: Doesn't work with UserDict
+        # self.assertRaises((TypeError, AttributeError), d.update, None)
+        self.assertRaises((TypeError, AttributeError), d.update, 42)
+
+        outerself = self
+        class SimpleUserDict:
+            def __init__(self):
+                self.d = outerself.reference
+            def keys(self):
+                return self.d.keys()
+            def __getitem__(self, i):
+                return self.d[i]
+        d.clear()
+        d.update(SimpleUserDict())
+        i1 = d.items()
+        i2 = self.reference.items()
+        i1.sort()
+        i2.sort()
+        self.assertEqual(i1, i2)
+
+        class Exc(Exception): pass
+
+        d = self._empty_mapping()
+        class FailingUserDict:
+            def keys(self):
+                raise Exc
+        self.assertRaises(Exc, d.update, FailingUserDict())
+
+        d.clear()
+
+        class FailingUserDict:
+            def keys(self):
+                class BogonIter:
+                    def __init__(self):
+                        self.i = 1
+                    def __iter__(self):
+                        return self
+                    def next(self):
+                        if self.i:
+                            self.i = 0
+                            return 'a'
+                        raise Exc
+                return BogonIter()
+            def __getitem__(self, key):
+                return key
+        self.assertRaises(Exc, d.update, FailingUserDict())
+
+        class FailingUserDict:
+            def keys(self):
+                class BogonIter:
+                    def __init__(self):
+                        self.i = ord('a')
+                    def __iter__(self):
+                        return self
+                    def next(self):
+                        if self.i <= ord('z'):
+                            rtn = chr(self.i)
+                            self.i += 1
+                            return rtn
+                        raise StopIteration
+                return BogonIter()
+            def __getitem__(self, key):
+                raise Exc
+        self.assertRaises(Exc, d.update, FailingUserDict())
+
+        d = self._empty_mapping()
+        class badseq(object):
+            def __iter__(self):
+                return self
+            def next(self):
+                raise Exc()
+
+        self.assertRaises(Exc, d.update, badseq())
+
+        self.assertRaises(ValueError, d.update, [(1, 2, 3)])
+
+    # no test_fromkeys or test_copy as both os.environ and selves don't support it
+
+    def test_get(self):
+        d = self._empty_mapping()
+        self.assert_(d.get(self.other.keys()[0]) is None)
+        self.assertEqual(d.get(self.other.keys()[0], 3), 3)
+        d = self.reference
+        self.assert_(d.get(self.other.keys()[0]) is None)
+        self.assertEqual(d.get(self.other.keys()[0], 3), 3)
+        self.assertEqual(d.get(self.inmapping.keys()[0]), self.inmapping.values()[0])
+        self.assertEqual(d.get(self.inmapping.keys()[0], 3), self.inmapping.values()[0])
+        self.assertRaises(TypeError, d.get)
+        self.assertRaises(TypeError, d.get, None, None, None)
+
+    def test_setdefault(self):
+        d = self._empty_mapping()
+        self.assertRaises(TypeError, d.setdefault)
+
+    def test_popitem(self):
+        d = self._empty_mapping()
+        self.assertRaises(KeyError, d.popitem)
+        self.assertRaises(TypeError, d.popitem, 42)
+
+    def test_pop(self):
+        d = self._empty_mapping()
+        k, v = self.inmapping.items()[0]
+        d[k] = v
+        self.assertRaises(KeyError, d.pop, self.other.keys()[0])
+
+        self.assertEqual(d.pop(k), v)
+        self.assertEqual(len(d), 0)
+
+        self.assertRaises(KeyError, d.pop, k)
+
+
+class TestMappingProtocol(BasicTestMappingProtocol):
+    def test_constructor(self):
+        BasicTestMappingProtocol.test_constructor(self)
+        self.assert_(self._empty_mapping() is not self._empty_mapping())
+        self.assertEqual(self.type2test(x=1, y=2), {"x": 1, "y": 2})
+
+    def test_bool(self):
+        BasicTestMappingProtocol.test_bool(self)
+        self.assert_(not self._empty_mapping())
+        self.assert_(self._full_mapping({"x": "y"}))
+        self.assert_(bool(self._empty_mapping()) is False)
+        self.assert_(bool(self._full_mapping({"x": "y"})) is True)
+
+    def test_keys(self):
+        BasicTestMappingProtocol.test_keys(self)
+        d = self._empty_mapping()
+        self.assertEqual(d.keys(), [])
+        d = self._full_mapping({'a': 1, 'b': 2})
+        k = d.keys()
+        self.assert_('a' in k)
+        self.assert_('b' in k)
+        self.assert_('c' not in k)
+
+    def test_values(self):
+        BasicTestMappingProtocol.test_values(self)
+        d = self._full_mapping({1:2})
+        self.assertEqual(d.values(), [2])
+
+    def test_items(self):
+        BasicTestMappingProtocol.test_items(self)
+
+        d = self._full_mapping({1:2})
+        self.assertEqual(d.items(), [(1, 2)])
+
+    def test_has_key(self):
+        d = self._empty_mapping()
+        self.assert_(not d.has_key('a'))
+        d = self._full_mapping({'a': 1, 'b': 2})
+        k = d.keys()
+        k.sort()
+        self.assertEqual(k, ['a', 'b'])
+
+        self.assertRaises(TypeError, d.has_key)
+
+    def test_contains(self):
+        d = self._empty_mapping()
+        self.assert_(not ('a' in d))
+        self.assert_('a' not in d)
+        d = self._full_mapping({'a': 1, 'b': 2})
+        self.assert_('a' in d)
+        self.assert_('b' in d)
+        self.assert_('c' not in d)
+
+        self.assertRaises(TypeError, d.__contains__)
+
+    def test_len(self):
+        BasicTestMappingProtocol.test_len(self)
+        d = self._full_mapping({'a': 1, 'b': 2})
+        self.assertEqual(len(d), 2)
+
+    def test_getitem(self):
+        BasicTestMappingProtocol.test_getitem(self)
+        d = self._full_mapping({'a': 1, 'b': 2})
+        self.assertEqual(d['a'], 1)
+        self.assertEqual(d['b'], 2)
+        d['c'] = 3
+        d['a'] = 4
+        self.assertEqual(d['c'], 3)
+        self.assertEqual(d['a'], 4)
+        del d['b']
+        self.assertEqual(d, {'a': 4, 'c': 3})
+
+        self.assertRaises(TypeError, d.__getitem__)
+
+    def test_clear(self):
+        d = self._full_mapping({1:1, 2:2, 3:3})
+        d.clear()
+        self.assertEqual(d, {})
+
+        self.assertRaises(TypeError, d.clear, None)
+
+    def test_update(self):
+        BasicTestMappingProtocol.test_update(self)
+        # mapping argument
+        d = self._empty_mapping()
+        d.update({1:100})
+        d.update({2:20})
+        d.update({1:1, 2:2, 3:3})
+        self.assertEqual(d, {1:1, 2:2, 3:3})
+
+        # no argument
+        d.update()
+        self.assertEqual(d, {1:1, 2:2, 3:3})
+
+        # keyword arguments
+        d = self._empty_mapping()
+        d.update(x=100)
+        d.update(y=20)
+        d.update(x=1, y=2, z=3)
+        self.assertEqual(d, {"x":1, "y":2, "z":3})
+
+        # item sequence
+        d = self._empty_mapping()
+        d.update([("x", 100), ("y", 20)])
+        self.assertEqual(d, {"x":100, "y":20})
+
+        # Both item sequence and keyword arguments
+        d = self._empty_mapping()
+        d.update([("x", 100), ("y", 20)], x=1, y=2)
+        self.assertEqual(d, {"x":1, "y":2})
+
+        # iterator
+        d = self._full_mapping({1:3, 2:4})
+        d.update(self._full_mapping({1:2, 3:4, 5:6}).iteritems())
+        self.assertEqual(d, {1:2, 2:4, 3:4, 5:6})
+
+        class SimpleUserDict:
+            def __init__(self):
+                self.d = {1:1, 2:2, 3:3}
+            def keys(self):
+                return self.d.keys()
+            def __getitem__(self, i):
+                return self.d[i]
+        d.clear()
+        d.update(SimpleUserDict())
+        self.assertEqual(d, {1:1, 2:2, 3:3})
+
+    def test_fromkeys(self):
+        self.assertEqual(self.type2test.fromkeys('abc'), {'a':None, 'b':None, 'c':None})
+        d = self._empty_mapping()
+        self.assert_(not(d.fromkeys('abc') is d))
+        self.assertEqual(d.fromkeys('abc'), {'a':None, 'b':None, 'c':None})
+        self.assertEqual(d.fromkeys((4,5),0), {4:0, 5:0})
+        self.assertEqual(d.fromkeys([]), {})
+        def g():
+            yield 1
+        self.assertEqual(d.fromkeys(g()), {1:None})
+        self.assertRaises(TypeError, {}.fromkeys, 3)
+        class dictlike(self.type2test): pass
+        self.assertEqual(dictlike.fromkeys('a'), {'a':None})
+        self.assertEqual(dictlike().fromkeys('a'), {'a':None})
+        self.assert_(dictlike.fromkeys('a').__class__ is dictlike)
+        self.assert_(dictlike().fromkeys('a').__class__ is dictlike)
+        # FIXME: the following won't work with UserDict, because it's an old style class
+        # self.assert_(type(dictlike.fromkeys('a')) is dictlike)
+        class mydict(self.type2test):
+            def __new__(cls):
+                return UserDict.UserDict()
+        ud = mydict.fromkeys('ab')
+        self.assertEqual(ud, {'a':None, 'b':None})
+        # FIXME: the following won't work with UserDict, because it's an old style class
+        # self.assert_(isinstance(ud, UserDict.UserDict))
+        self.assertRaises(TypeError, dict.fromkeys)
+
+        class Exc(Exception): pass
+
+        class baddict1(self.type2test):
+            def __init__(self):
+                raise Exc()
+
+        self.assertRaises(Exc, baddict1.fromkeys, [1])
+
+        class BadSeq(object):
+            def __iter__(self):
+                return self
+            def next(self):
+                raise Exc()
+
+        self.assertRaises(Exc, self.type2test.fromkeys, BadSeq())
+
+        class baddict2(self.type2test):
+            def __setitem__(self, key, value):
+                raise Exc()
+
+        self.assertRaises(Exc, baddict2.fromkeys, [1])
+
+    def test_copy(self):
+        d = self._full_mapping({1:1, 2:2, 3:3})
+        self.assertEqual(d.copy(), {1:1, 2:2, 3:3})
+        d = self._empty_mapping()
+        self.assertEqual(d.copy(), d)
+        self.assert_(isinstance(d.copy(), d.__class__))
+        self.assertRaises(TypeError, d.copy, None)
+
+    def test_get(self):
+        BasicTestMappingProtocol.test_get(self)
+        d = self._empty_mapping()
+        self.assert_(d.get('c') is None)
+        self.assertEqual(d.get('c', 3), 3)
+        d = self._full_mapping({'a' : 1, 'b' : 2})
+        self.assert_(d.get('c') is None)
+        self.assertEqual(d.get('c', 3), 3)
+        self.assertEqual(d.get('a'), 1)
+        self.assertEqual(d.get('a', 3), 1)
+
+    def test_setdefault(self):
+        BasicTestMappingProtocol.test_setdefault(self)
+        d = self._empty_mapping()
+        self.assert_(d.setdefault('key0') is None)
+        d.setdefault('key0', [])
+        self.assert_(d.setdefault('key0') is None)
+        d.setdefault('key', []).append(3)
+        self.assertEqual(d['key'][0], 3)
+        d.setdefault('key', []).append(4)
+        self.assertEqual(len(d['key']), 2)
+
+    def test_popitem(self):
+        BasicTestMappingProtocol.test_popitem(self)
+        for copymode in -1, +1:
+            # -1: b has same structure as a
+            # +1: b is a.copy()
+            for log2size in range(12):
+                size = 2**log2size
+                a = self._empty_mapping()
+                b = self._empty_mapping()
+                for i in range(size):
+                    a[repr(i)] = i
+                    if copymode < 0:
+                        b[repr(i)] = i
+                if copymode > 0:
+                    b = a.copy()
+                for i in range(size):
+                    ka, va = ta = a.popitem()
+                    self.assertEqual(va, int(ka))
+                    kb, vb = tb = b.popitem()
+                    self.assertEqual(vb, int(kb))
+                    self.assert_(not(copymode < 0 and ta != tb))
+                self.assert_(not a)
+                self.assert_(not b)
+
+    def test_pop(self):
+        BasicTestMappingProtocol.test_pop(self)
+
+        # Tests for pop with specified key
+        d = self._empty_mapping()
+        k, v = 'abc', 'def'
+
+        # verify longs/ints get same value when key > 32 bits (for 64-bit archs)
+        # see SF bug #689659
+        x = 4503599627370496L
+        y = 4503599627370496
+        h = self._full_mapping({x: 'anything', y: 'something else'})
+        self.assertEqual(h[x], h[y])
+
+        self.assertEqual(d.pop(k, v), v)
+        d[k] = v
+        self.assertEqual(d.pop(k, 1), v)
+
+
+class TestHashMappingProtocol(TestMappingProtocol):
+
+    def test_getitem(self):
+        TestMappingProtocol.test_getitem(self)
+        class Exc(Exception): pass
+
+        class BadEq(object):
+            def __eq__(self, other):
+                raise Exc()
+
+        d = self._empty_mapping()
+        d[BadEq()] = 42
+        self.assertRaises(KeyError, d.__getitem__, 23)
+
+        class BadHash(object):
+            fail = False
+            def __hash__(self):
+                if self.fail:
+                    raise Exc()
+                else:
+                    return 42
+
+        d = self._empty_mapping()
+        x = BadHash()
+        d[x] = 42
+        x.fail = True
+        self.assertRaises(Exc, d.__getitem__, x)
+
+    def test_fromkeys(self):
+        TestMappingProtocol.test_fromkeys(self)
+        class mydict(self.type2test):
+            def __new__(cls):
+                return UserDict.UserDict()
+        ud = mydict.fromkeys('ab')
+        self.assertEqual(ud, {'a':None, 'b':None})
+        self.assert_(isinstance(ud, UserDict.UserDict))
+
+    def test_pop(self):
+        TestMappingProtocol.test_pop(self)
+
+        class Exc(Exception): pass
+
+        class BadHash(object):
+            fail = False
+            def __hash__(self):
+                if self.fail:
+                    raise Exc()
+                else:
+                    return 42
+
+        d = self._empty_mapping()
+        x = BadHash()
+        d[x] = 42
+        x.fail = True
+        self.assertRaises(Exc, d.pop, x)
+
+    def test_mutatingiteration(self):
+        d = self._empty_mapping()
+        d[1] = 1
+        try:
+            for i in d:
+                d[i+1] = 1
+        except RuntimeError:
+            pass
+        else:
+            self.fail("changing dict size during iteration doesn't raise Error")
+
+    def test_repr(self):
+        d = self._empty_mapping()
+        self.assertEqual(repr(d), '{}')
+        d[1] = 2
+        self.assertEqual(repr(d), '{1: 2}')
+        d = self._empty_mapping()
+        d[1] = d
+        self.assertEqual(repr(d), '{1: {...}}')
+
+        class Exc(Exception): pass
+
+        class BadRepr(object):
+            def __repr__(self):
+                raise Exc()
+
+        d = self._full_mapping({1: BadRepr()})
+        self.assertRaises(Exc, repr, d)
+
+    def test_le(self):
+        self.assert_(not (self._empty_mapping() < self._empty_mapping()))
+        self.assert_(not (self._full_mapping({1: 2}) < self._full_mapping({1L: 2L})))
+
+        class Exc(Exception): pass
+
+        class BadCmp(object):
+            def __eq__(self, other):
+                raise Exc()
+
+        d1 = self._full_mapping({BadCmp(): 1})
+        d2 = self._full_mapping({1: 1})
+        try:
+            d1 < d2
+        except Exc:
+            pass
+        else:
+            self.fail("< didn't raise Exc")
+
+    def test_setdefault(self):
+        TestMappingProtocol.test_setdefault(self)
+
+        class Exc(Exception): pass
+
+        class BadHash(object):
+            fail = False
+            def __hash__(self):
+                if self.fail:
+                    raise Exc()
+                else:
+                    return 42
+
+        d = self._empty_mapping()
+        x = BadHash()
+        d[x] = 42
+        x.fail = True
+        self.assertRaises(Exc, d.setdefault, x, [])

Added: vendor/Python/current/Lib/test/output/test_MimeWriter
===================================================================
--- vendor/Python/current/Lib/test/output/test_MimeWriter	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/output/test_MimeWriter	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,110 @@
+test_MimeWriter
+From: bwarsaw at cnri.reston.va.us
+Date: Mon Feb 12 17:21:48 EST 1996
+To: kss-submit at cnri.reston.va.us
+MIME-Version: 1.0
+Content-Type: multipart/knowbot;
+    boundary="801spam999";
+    version="0.1"
+
+This is a multi-part message in MIME format.
+
+--801spam999
+Content-Type: multipart/knowbot-metadata;
+    boundary="802spam999"
+
+
+--802spam999
+Content-Type: message/rfc822
+KP-Metadata-Type: simple
+KP-Access: read-only
+
+KPMD-Interpreter: python
+KPMD-Interpreter-Version: 1.3
+KPMD-Owner-Name: Barry Warsaw
+KPMD-Owner-Rendezvous: bwarsaw at cnri.reston.va.us
+KPMD-Home-KSS: kss.cnri.reston.va.us
+KPMD-Identifier: hdl://cnri.kss/my_first_knowbot
+KPMD-Launch-Date: Mon Feb 12 16:39:03 EST 1996
+
+--802spam999
+Content-Type: text/isl
+KP-Metadata-Type: complex
+KP-Metadata-Key: connection
+KP-Access: read-only
+KP-Connection-Description: Barry's Big Bass Business
+KP-Connection-Id: B4
+KP-Connection-Direction: client
+
+INTERFACE Seller-1;
+
+TYPE Seller = OBJECT
+    DOCUMENTATION "A simple Seller interface to test ILU"
+    METHODS
+            price():INTEGER,
+    END;
+
+--802spam999
+Content-Type: message/external-body;
+    access-type="URL";
+    URL="hdl://cnri.kss/generic-knowbot"
+
+Content-Type: text/isl
+KP-Metadata-Type: complex
+KP-Metadata-Key: generic-interface
+KP-Access: read-only
+KP-Connection-Description: Generic Interface for All Knowbots
+KP-Connection-Id: generic-kp
+KP-Connection-Direction: client
+
+
+--802spam999--
+
+--801spam999
+Content-Type: multipart/knowbot-code;
+    boundary="803spam999"
+
+
+--803spam999
+Content-Type: text/plain
+KP-Module-Name: BuyerKP
+
+class Buyer:
+    def __setup__(self, maxprice):
+        self._maxprice = maxprice
+
+    def __main__(self, kos):
+        """Entry point upon arrival at a new KOS."""
+        broker = kos.broker()
+        # B4 == Barry's Big Bass Business :-)
+        seller = broker.lookup('Seller_1.Seller', 'B4')
+        if seller:
+            price = seller.price()
+            print 'Seller wants $', price, '... '
+            if price > self._maxprice:
+                print 'too much!'
+            else:
+                print "I'll take it!"
+        else:
+            print 'no seller found here'
+
+--803spam999--
+
+--801spam999
+Content-Type: multipart/knowbot-state;
+    boundary="804spam999"
+KP-Main-Module: main
+
+
+--804spam999
+Content-Type: text/plain
+KP-Module-Name: main
+
+# instantiate a buyer instance and put it in a magic place for the KOS
+# to find.
+__kp__ = Buyer()
+__kp__.__setup__(500)
+
+--804spam999--
+
+--801spam999--

Added: vendor/Python/current/Lib/test/output/test_cProfile
===================================================================
--- vendor/Python/current/Lib/test/output/test_cProfile	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/output/test_cProfile	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,79 @@
+test_cProfile
+         126 function calls (106 primitive calls) in 1.000 CPU seconds
+
+   Ordered by: standard name
+
+   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
+        1    0.000    0.000    1.000    1.000 <string>:1(<module>)
+        8    0.064    0.008    0.080    0.010 test_cProfile.py:103(subhelper)
+       28    0.028    0.001    0.028    0.001 test_cProfile.py:115(__getattr__)
+        1    0.270    0.270    1.000    1.000 test_cProfile.py:30(testfunc)
+     23/3    0.150    0.007    0.170    0.057 test_cProfile.py:40(factorial)
+       20    0.020    0.001    0.020    0.001 test_cProfile.py:53(mul)
+        2    0.040    0.020    0.600    0.300 test_cProfile.py:60(helper)
+        4    0.116    0.029    0.120    0.030 test_cProfile.py:78(helper1)
+        2    0.000    0.000    0.140    0.070 test_cProfile.py:89(helper2_indirect)
+        8    0.312    0.039    0.400    0.050 test_cProfile.py:93(helper2)
+       12    0.000    0.000    0.012    0.001 {hasattr}
+        4    0.000    0.000    0.000    0.000 {method 'append' of 'list' objects}
+        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
+        8    0.000    0.000    0.000    0.000 {range}
+        4    0.000    0.000    0.000    0.000 {sys.exc_info}
+
+
+   Ordered by: standard name
+
+Function                                          called...
+                                                      ncalls  tottime  cumtime
+<string>:1(<module>)                              ->       1    0.270    1.000  test_cProfile.py:30(testfunc)
+test_cProfile.py:103(subhelper)                   ->      16    0.016    0.016  test_cProfile.py:115(__getattr__)
+                                                           8    0.000    0.000  {range}
+test_cProfile.py:115(__getattr__)                 ->
+test_cProfile.py:30(testfunc)                     ->       1    0.014    0.130  test_cProfile.py:40(factorial)
+                                                           2    0.040    0.600  test_cProfile.py:60(helper)
+test_cProfile.py:40(factorial)                    ->    20/3    0.130    0.147  test_cProfile.py:40(factorial)
+                                                          20    0.020    0.020  test_cProfile.py:53(mul)
+test_cProfile.py:53(mul)                          ->
+test_cProfile.py:60(helper)                       ->       4    0.116    0.120  test_cProfile.py:78(helper1)
+                                                           2    0.000    0.140  test_cProfile.py:89(helper2_indirect)
+                                                           6    0.234    0.300  test_cProfile.py:93(helper2)
+test_cProfile.py:78(helper1)                      ->       4    0.000    0.004  {hasattr}
+                                                           4    0.000    0.000  {method 'append' of 'list' objects}
+                                                           4    0.000    0.000  {sys.exc_info}
+test_cProfile.py:89(helper2_indirect)             ->       2    0.006    0.040  test_cProfile.py:40(factorial)
+                                                           2    0.078    0.100  test_cProfile.py:93(helper2)
+test_cProfile.py:93(helper2)                      ->       8    0.064    0.080  test_cProfile.py:103(subhelper)
+                                                           8    0.000    0.008  {hasattr}
+{hasattr}                                         ->      12    0.012    0.012  test_cProfile.py:115(__getattr__)
+{method 'append' of 'list' objects}               ->
+{method 'disable' of '_lsprof.Profiler' objects}  ->
+{range}                                           ->
+{sys.exc_info}                                    ->
+
+
+   Ordered by: standard name
+
+Function                                          was called by...
+                                                      ncalls  tottime  cumtime
+<string>:1(<module>)                              <-
+test_cProfile.py:103(subhelper)                   <-       8    0.064    0.080  test_cProfile.py:93(helper2)
+test_cProfile.py:115(__getattr__)                 <-      16    0.016    0.016  test_cProfile.py:103(subhelper)
+                                                          12    0.012    0.012  {hasattr}
+test_cProfile.py:30(testfunc)                     <-       1    0.270    1.000  <string>:1(<module>)
+test_cProfile.py:40(factorial)                    <-       1    0.014    0.130  test_cProfile.py:30(testfunc)
+                                                        20/3    0.130    0.147  test_cProfile.py:40(factorial)
+                                                           2    0.006    0.040  test_cProfile.py:89(helper2_indirect)
+test_cProfile.py:53(mul)                          <-      20    0.020    0.020  test_cProfile.py:40(factorial)
+test_cProfile.py:60(helper)                       <-       2    0.040    0.600  test_cProfile.py:30(testfunc)
+test_cProfile.py:78(helper1)                      <-       4    0.116    0.120  test_cProfile.py:60(helper)
+test_cProfile.py:89(helper2_indirect)             <-       2    0.000    0.140  test_cProfile.py:60(helper)
+test_cProfile.py:93(helper2)                      <-       6    0.234    0.300  test_cProfile.py:60(helper)
+                                                           2    0.078    0.100  test_cProfile.py:89(helper2_indirect)
+{hasattr}                                         <-       4    0.000    0.004  test_cProfile.py:78(helper1)
+                                                           8    0.000    0.008  test_cProfile.py:93(helper2)
+{method 'append' of 'list' objects}               <-       4    0.000    0.000  test_cProfile.py:78(helper1)
+{method 'disable' of '_lsprof.Profiler' objects}  <-
+{range}                                           <-       8    0.000    0.000  test_cProfile.py:103(subhelper)
+{sys.exc_info}                                    <-       4    0.000    0.000  test_cProfile.py:78(helper1)
+
+

Added: vendor/Python/current/Lib/test/output/test_cgi
===================================================================
--- vendor/Python/current/Lib/test/output/test_cgi	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/output/test_cgi	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,42 @@
+test_cgi
+'' => []
+'&' => []
+'&&' => []
+'=' => [('', '')]
+'=a' => [('', 'a')]
+'a' => [('a', '')]
+'a=' => [('a', '')]
+'a=' => [('a', '')]
+'&a=b' => [('a', 'b')]
+'a=a+b&b=b+c' => [('a', 'a b'), ('b', 'b c')]
+'a=1&a=2' => [('a', '1'), ('a', '2')]
+''
+'&'
+'&&'
+';'
+';&;'
+'='
+'=&='
+'=;='
+'=a'
+'&=a'
+'=a&'
+'=&a'
+'b=a'
+'b+=a'
+'a=b=a'
+'a=+b=a'
+'&b=a'
+'b&=a'
+'a=a+b&b=b+c'
+'a=a+b&a=b+a'
+'x=1&y=2.0&z=2-3.%2b0'
+'x=1;y=2.0&z=2-3.%2b0'
+'x=1;y=2.0;z=2-3.%2b0'
+'Hbc5161168c542333633315dee1182227:key_store_seqid=400006&cuyer=r&view=bustomer&order_id=0bb2e248638833d48cb7fed300000f1b&expire=964546263&lobale=en-US&kid=130003.300038&ss=env'
+'group_id=5470&set=custom&_assigned_to=31392&_status=1&_category=100&SUBMIT=Browse'
+Testing log
+Testing initlog 1
+Testing log 2
+Test FieldStorage methods that use readline
+Test basic FieldStorage multipart parsing

Added: vendor/Python/current/Lib/test/output/test_class
===================================================================
--- vendor/Python/current/Lib/test/output/test_class	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/output/test_class	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,101 @@
+test_class
+__init__: ()
+__coerce__: (1,)
+__add__: (1,)
+__coerce__: (1,)
+__radd__: (1,)
+__coerce__: (1,)
+__sub__: (1,)
+__coerce__: (1,)
+__rsub__: (1,)
+__coerce__: (1,)
+__mul__: (1,)
+__coerce__: (1,)
+__rmul__: (1,)
+__coerce__: (1,)
+__div__: (1,)
+__coerce__: (1,)
+__rdiv__: (1,)
+__coerce__: (1,)
+__mod__: (1,)
+__coerce__: (1,)
+__rmod__: (1,)
+__coerce__: (1,)
+__divmod__: (1,)
+__coerce__: (1,)
+__rdivmod__: (1,)
+__coerce__: (1,)
+__pow__: (1,)
+__coerce__: (1,)
+__rpow__: (1,)
+__coerce__: (1,)
+__rshift__: (1,)
+__coerce__: (1,)
+__rrshift__: (1,)
+__coerce__: (1,)
+__lshift__: (1,)
+__coerce__: (1,)
+__rlshift__: (1,)
+__coerce__: (1,)
+__and__: (1,)
+__coerce__: (1,)
+__rand__: (1,)
+__coerce__: (1,)
+__or__: (1,)
+__coerce__: (1,)
+__ror__: (1,)
+__coerce__: (1,)
+__xor__: (1,)
+__coerce__: (1,)
+__rxor__: (1,)
+__contains__: (1,)
+__getitem__: (1,)
+__setitem__: (1, 1)
+__delitem__: (1,)
+__getslice__: (0, 42)
+__setslice__: (0, 42, 'The Answer')
+__delslice__: (0, 42)
+__getitem__: (slice(2, 1024, 10),)
+__setitem__: (slice(2, 1024, 10), 'A lot')
+__delitem__: (slice(2, 1024, 10),)
+__getitem__: ((slice(None, 42, None), Ellipsis, slice(None, 24, None), 24, 100),)
+__setitem__: ((slice(None, 42, None), Ellipsis, slice(None, 24, None), 24, 100), 'Strange')
+__delitem__: ((slice(None, 42, None), Ellipsis, slice(None, 24, None), 24, 100),)
+__getitem__: (slice(0, 42, None),)
+__setitem__: (slice(0, 42, None), 'The Answer')
+__delitem__: (slice(0, 42, None),)
+__neg__: ()
+__pos__: ()
+__abs__: ()
+__int__: ()
+__long__: ()
+__float__: ()
+__oct__: ()
+__hex__: ()
+__hash__: ()
+__repr__: ()
+__str__: ()
+__coerce__: (1,)
+__cmp__: (1,)
+__coerce__: (1,)
+__cmp__: (1,)
+__coerce__: (1,)
+__cmp__: (1,)
+__coerce__: (1,)
+__cmp__: (1,)
+__coerce__: (1,)
+__cmp__: (1,)
+__coerce__: (1,)
+__cmp__: (1,)
+__coerce__: (1,)
+__cmp__: (1,)
+__coerce__: (1,)
+__cmp__: (1,)
+__coerce__: (1,)
+__cmp__: (1,)
+__coerce__: (1,)
+__cmp__: (1,)
+__del__: ()
+__getattr__: ('spam',)
+__setattr__: ('eggs', 'spam, spam, spam and ham')
+__delattr__: ('cardinal',)

Added: vendor/Python/current/Lib/test/output/test_cookie
===================================================================
--- vendor/Python/current/Lib/test/output/test_cookie	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/output/test_cookie	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,32 @@
+test_cookie
+<SimpleCookie: chips='ahoy' vienna='finger'>
+Set-Cookie: chips=ahoy
+Set-Cookie: vienna=finger
+  chips 'ahoy' 'ahoy'
+Set-Cookie: chips=ahoy
+  vienna 'finger' 'finger'
+Set-Cookie: vienna=finger
+<SimpleCookie: keebler='E=mc2; L="Loves"; fudge=\n;'>
+Set-Cookie: keebler="E=mc2; L=\"Loves\"; fudge=\012;"
+  keebler 'E=mc2; L="Loves"; fudge=\n;' 'E=mc2; L="Loves"; fudge=\n;'
+Set-Cookie: keebler="E=mc2; L=\"Loves\"; fudge=\012;"
+<SimpleCookie: keebler='E=mc2'>
+Set-Cookie: keebler=E=mc2
+  keebler 'E=mc2' 'E=mc2'
+Set-Cookie: keebler=E=mc2
+Set-Cookie: Customer="WILE_E_COYOTE"; Path=/acme
+
+        <script type="text/javascript">
+        <!-- begin hiding
+        document.cookie = "Customer="WILE_E_COYOTE"; Path=/acme; Version=1";
+        // end hiding -->
+        </script>
+        
+
+        <script type="text/javascript">
+        <!-- begin hiding
+        document.cookie = "Customer="WILE_E_COYOTE"; Path=/acme";
+        // end hiding -->
+        </script>
+        
+If anything blows up after this line, it's from Cookie's doctest.

Added: vendor/Python/current/Lib/test/output/test_extcall
===================================================================
--- vendor/Python/current/Lib/test/output/test_extcall	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/output/test_extcall	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,112 @@
+test_extcall
+() {}
+(1,) {}
+(1, 2) {}
+(1, 2, 3) {}
+(1, 2, 3, 4, 5) {}
+(1, 2, 3, 4, 5) {}
+(1, 2, 3, 4, 5) {}
+(1, 2, 3) {'a': 4, 'b': 5}
+(1, 2, 3, 4, 5) {'a': 6, 'b': 7}
+(1, 2, 3, 6, 7) {'a': 8, 'b': 9, 'x': 4, 'y': 5}
+TypeError: g() takes at least 1 argument (0 given)
+TypeError: g() takes at least 1 argument (0 given)
+TypeError: g() takes at least 1 argument (0 given)
+1 () {}
+1 (2,) {}
+1 (2, 3) {}
+1 (2, 3, 4, 5) {}
+0 (1, 2) {}
+0 (1, 2, 3) {}
+1 () {'a': 1, 'b': 2, 'c': 3, 'd': 4}
+{'a': 1, 'b': 2, 'c': 3}
+{'a': 1, 'b': 2, 'c': 3}
+g() got multiple values for keyword argument 'x'
+g() got multiple values for keyword argument 'b'
+f() keywords must be strings
+h() got an unexpected keyword argument 'e'
+h() argument after * must be a sequence
+dir() argument after * must be a sequence
+NoneType object argument after * must be a sequence
+h() argument after ** must be a dictionary
+dir() argument after ** must be a dictionary
+NoneType object argument after ** must be a dictionary
+dir() got multiple values for keyword argument 'b'
+3 512 True
+3
+3
+za () {} -> za() takes exactly 1 argument (0 given)
+za () {'a': 'aa'} -> ok za aa B D E V a
+za () {'d': 'dd'} -> za() got an unexpected keyword argument 'd'
+za () {'a': 'aa', 'd': 'dd'} -> za() got an unexpected keyword argument 'd'
+za () {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> za() got an unexpected keyword argument 'b'
+za (1, 2) {} -> za() takes exactly 1 argument (2 given)
+za (1, 2) {'a': 'aa'} -> za() takes exactly 1 non-keyword argument (2 given)
+za (1, 2) {'d': 'dd'} -> za() takes exactly 1 non-keyword argument (2 given)
+za (1, 2) {'a': 'aa', 'd': 'dd'} -> za() takes exactly 1 non-keyword argument (2 given)
+za (1, 2) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> za() takes exactly 1 non-keyword argument (2 given)
+za (1, 2, 3, 4, 5) {} -> za() takes exactly 1 argument (5 given)
+za (1, 2, 3, 4, 5) {'a': 'aa'} -> za() takes exactly 1 non-keyword argument (5 given)
+za (1, 2, 3, 4, 5) {'d': 'dd'} -> za() takes exactly 1 non-keyword argument (5 given)
+za (1, 2, 3, 4, 5) {'a': 'aa', 'd': 'dd'} -> za() takes exactly 1 non-keyword argument (5 given)
+za (1, 2, 3, 4, 5) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> za() takes exactly 1 non-keyword argument (5 given)
+zade () {} -> zade() takes at least 1 argument (0 given)
+zade () {'a': 'aa'} -> ok zade aa B d e V a
+zade () {'d': 'dd'} -> zade() takes at least 1 non-keyword argument (0 given)
+zade () {'a': 'aa', 'd': 'dd'} -> ok zade aa B dd e V d
+zade () {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zade() got an unexpected keyword argument 'b'
+zade (1, 2) {} -> ok zade 1 B 2 e V e
+zade (1, 2) {'a': 'aa'} -> zade() got multiple values for keyword argument 'a'
+zade (1, 2) {'d': 'dd'} -> zade() got multiple values for keyword argument 'd'
+zade (1, 2) {'a': 'aa', 'd': 'dd'} -> zade() got multiple values for keyword argument 'a'
+zade (1, 2) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zade() got multiple values for keyword argument 'a'
+zade (1, 2, 3, 4, 5) {} -> zade() takes at most 3 arguments (5 given)
+zade (1, 2, 3, 4, 5) {'a': 'aa'} -> zade() takes at most 3 non-keyword arguments (5 given)
+zade (1, 2, 3, 4, 5) {'d': 'dd'} -> zade() takes at most 3 non-keyword arguments (5 given)
+zade (1, 2, 3, 4, 5) {'a': 'aa', 'd': 'dd'} -> zade() takes at most 3 non-keyword arguments (5 given)
+zade (1, 2, 3, 4, 5) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zade() takes at most 3 non-keyword arguments (5 given)
+zabk () {} -> zabk() takes exactly 2 arguments (0 given)
+zabk () {'a': 'aa'} -> zabk() takes exactly 2 non-keyword arguments (1 given)
+zabk () {'d': 'dd'} -> zabk() takes exactly 2 non-keyword arguments (0 given)
+zabk () {'a': 'aa', 'd': 'dd'} -> zabk() takes exactly 2 non-keyword arguments (1 given)
+zabk () {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> ok zabk aa bb D E V {'d': 'dd', 'e': 'ee'}
+zabk (1, 2) {} -> ok zabk 1 2 D E V {}
+zabk (1, 2) {'a': 'aa'} -> zabk() got multiple values for keyword argument 'a'
+zabk (1, 2) {'d': 'dd'} -> ok zabk 1 2 D E V {'d': 'dd'}
+zabk (1, 2) {'a': 'aa', 'd': 'dd'} -> zabk() got multiple values for keyword argument 'a'
+zabk (1, 2) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zabk() got multiple values for keyword argument 'a'
+zabk (1, 2, 3, 4, 5) {} -> zabk() takes exactly 2 arguments (5 given)
+zabk (1, 2, 3, 4, 5) {'a': 'aa'} -> zabk() takes exactly 2 non-keyword arguments (5 given)
+zabk (1, 2, 3, 4, 5) {'d': 'dd'} -> zabk() takes exactly 2 non-keyword arguments (5 given)
+zabk (1, 2, 3, 4, 5) {'a': 'aa', 'd': 'dd'} -> zabk() takes exactly 2 non-keyword arguments (5 given)
+zabk (1, 2, 3, 4, 5) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zabk() takes exactly 2 non-keyword arguments (5 given)
+zabdv () {} -> zabdv() takes at least 2 arguments (0 given)
+zabdv () {'a': 'aa'} -> zabdv() takes at least 2 non-keyword arguments (1 given)
+zabdv () {'d': 'dd'} -> zabdv() takes at least 2 non-keyword arguments (0 given)
+zabdv () {'a': 'aa', 'd': 'dd'} -> zabdv() takes at least 2 non-keyword arguments (1 given)
+zabdv () {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zabdv() got an unexpected keyword argument 'e'
+zabdv (1, 2) {} -> ok zabdv 1 2 d E () e
+zabdv (1, 2) {'a': 'aa'} -> zabdv() got multiple values for keyword argument 'a'
+zabdv (1, 2) {'d': 'dd'} -> ok zabdv 1 2 dd E () d
+zabdv (1, 2) {'a': 'aa', 'd': 'dd'} -> zabdv() got multiple values for keyword argument 'a'
+zabdv (1, 2) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zabdv() got multiple values for keyword argument 'a'
+zabdv (1, 2, 3, 4, 5) {} -> ok zabdv 1 2 3 E (4, 5) e
+zabdv (1, 2, 3, 4, 5) {'a': 'aa'} -> zabdv() got multiple values for keyword argument 'a'
+zabdv (1, 2, 3, 4, 5) {'d': 'dd'} -> zabdv() got multiple values for keyword argument 'd'
+zabdv (1, 2, 3, 4, 5) {'a': 'aa', 'd': 'dd'} -> zabdv() got multiple values for keyword argument 'a'
+zabdv (1, 2, 3, 4, 5) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zabdv() got multiple values for keyword argument 'a'
+zabdevk () {} -> zabdevk() takes at least 2 arguments (0 given)
+zabdevk () {'a': 'aa'} -> zabdevk() takes at least 2 non-keyword arguments (1 given)
+zabdevk () {'d': 'dd'} -> zabdevk() takes at least 2 non-keyword arguments (0 given)
+zabdevk () {'a': 'aa', 'd': 'dd'} -> zabdevk() takes at least 2 non-keyword arguments (1 given)
+zabdevk () {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> ok zabdevk aa bb dd ee () {}
+zabdevk (1, 2) {} -> ok zabdevk 1 2 d e () {}
+zabdevk (1, 2) {'a': 'aa'} -> zabdevk() got multiple values for keyword argument 'a'
+zabdevk (1, 2) {'d': 'dd'} -> ok zabdevk 1 2 dd e () {}
+zabdevk (1, 2) {'a': 'aa', 'd': 'dd'} -> zabdevk() got multiple values for keyword argument 'a'
+zabdevk (1, 2) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zabdevk() got multiple values for keyword argument 'a'
+zabdevk (1, 2, 3, 4, 5) {} -> ok zabdevk 1 2 3 4 (5,) {}
+zabdevk (1, 2, 3, 4, 5) {'a': 'aa'} -> zabdevk() got multiple values for keyword argument 'a'
+zabdevk (1, 2, 3, 4, 5) {'d': 'dd'} -> zabdevk() got multiple values for keyword argument 'd'
+zabdevk (1, 2, 3, 4, 5) {'a': 'aa', 'd': 'dd'} -> zabdevk() got multiple values for keyword argument 'a'
+zabdevk (1, 2, 3, 4, 5) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zabdevk() got multiple values for keyword argument 'a'

Added: vendor/Python/current/Lib/test/output/test_frozen
===================================================================
--- vendor/Python/current/Lib/test/output/test_frozen	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/output/test_frozen	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,4 @@
+test_frozen
+Hello world...
+Hello world...
+Hello world...

Added: vendor/Python/current/Lib/test/output/test_global
===================================================================
--- vendor/Python/current/Lib/test/output/test_global	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/output/test_global	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,5 @@
+test_global
+got SyntaxError as expected
+got SyntaxError as expected
+got SyntaxError as expected
+as expected, no SyntaxError

Added: vendor/Python/current/Lib/test/output/test_grammar
===================================================================
--- vendor/Python/current/Lib/test/output/test_grammar	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/output/test_grammar	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,69 @@
+test_grammar
+1. Parser
+1.1 Tokens
+1.1.1 Backslashes
+1.1.2 Numeric literals
+1.1.2.1 Plain integers
+1.1.2.2 Long integers
+1.1.2.3 Floating point
+1.1.3 String literals
+1.2 Grammar
+single_input
+file_input
+expr_input
+eval_input
+funcdef
+lambdef
+simple_stmt
+expr_stmt
+print_stmt
+1 2 3
+1 2 3
+1 1 1
+extended print_stmt
+1 2 3
+1 2 3
+1 1 1
+hello world
+del_stmt
+pass_stmt
+flow_stmt
+break_stmt
+continue_stmt
+continue + try/except ok
+continue + try/finally ok
+testing continue and break in try/except in loop
+return_stmt
+yield_stmt
+raise_stmt
+import_name
+import_from
+global_stmt
+exec_stmt
+assert_stmt
+if_stmt
+while_stmt
+for_stmt
+try_stmt
+suite
+test
+comparison
+binary mask ops
+shift ops
+additive ops
+multiplicative ops
+unary ops
+selectors
+
+[1, (1,), (1, 2), (1, 2, 3)]
+atoms
+classdef
+['Apple', 'Banana', 'Coco  nut']
+[3, 6, 9, 12, 15]
+[3, 4, 5]
+[(1, 'Apple'), (1, 'Banana'), (1, 'Coconut'), (2, 'Apple'), (2, 'Banana'), (2, 'Coconut'), (3, 'Apple'), (3, 'Banana'), (3, 'Coconut'), (4, 'Apple'), (4, 'Banana'), (4, 'Coconut'), (5, 'Apple'), (5, 'Banana'), (5, 'Coconut')]
+[(1, 'Banana'), (1, 'Coconut'), (2, 'Banana'), (2, 'Coconut'), (3, 'Banana'), (3, 'Coconut'), (4, 'Banana'), (4, 'Coconut'), (5, 'Banana'), (5, 'Coconut')]
+[[1], [1, 1], [1, 2, 4], [1, 3, 9, 27], [1, 4, 16, 64, 256]]
+[False, False, False]
+[[1, 2], [3, 4], [5, 6]]
+[('Boeing', 'Airliner'), ('Boeing', 'Engine'), ('Ford', 'Engine'), ('Macdonalds', 'Cheeseburger')]

Added: vendor/Python/current/Lib/test/output/test_httplib
===================================================================
--- vendor/Python/current/Lib/test/output/test_httplib	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/output/test_httplib	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,13 @@
+test_httplib
+reply: 'HTTP/1.1 200 Ok\r\n'
+Text
+reply: 'HTTP/1.1 400.100 Not Ok\r\n'
+BadStatusLine raised as expected
+InvalidURL raised as expected
+InvalidURL raised as expected
+reply: 'HTTP/1.1 200 OK\r\n'
+header: Set-Cookie: Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"
+header: Set-Cookie: Part_Number="Rocket_Launcher_0001"; Version="1"; Path="/acme"
+reply: 'HTTP/1.1 200 OK\r\n'
+header: Content-Length: 14432
+

Added: vendor/Python/current/Lib/test/output/test_linuxaudiodev
===================================================================
--- vendor/Python/current/Lib/test/output/test_linuxaudiodev	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/output/test_linuxaudiodev	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,7 @@
+test_linuxaudiodev
+expected rate >= 0, not -1
+expected sample size >= 0, not -2
+nchannels must be 1 or 2, not 3
+unknown audio encoding: 177
+for linear unsigned 16-bit little-endian audio, expected sample size 16, not 8
+for linear unsigned 8-bit audio, expected sample size 8, not 16

Added: vendor/Python/current/Lib/test/output/test_logging
===================================================================
--- vendor/Python/current/Lib/test/output/test_logging	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/output/test_logging	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,525 @@
+test_logging
+-- log_test0  begin  ---------------------------------------------------
+CRITICAL:ERR:Message 0
+ERROR:ERR:Message 1
+CRITICAL:INF:Message 2
+ERROR:INF:Message 3
+WARNING:INF:Message 4
+INFO:INF:Message 5
+CRITICAL:INF.UNDEF:Message 6
+ERROR:INF.UNDEF:Message 7
+WARNING:INF.UNDEF:Message 8
+INFO:INF.UNDEF:Message 9
+CRITICAL:INF.ERR:Message 10
+ERROR:INF.ERR:Message 11
+CRITICAL:INF.ERR.UNDEF:Message 12
+ERROR:INF.ERR.UNDEF:Message 13
+CRITICAL:DEB:Message 14
+ERROR:DEB:Message 15
+WARNING:DEB:Message 16
+INFO:DEB:Message 17
+DEBUG:DEB:Message 18
+CRITICAL:UNDEF:Message 19
+ERROR:UNDEF:Message 20
+WARNING:UNDEF:Message 21
+INFO:UNDEF:Message 22
+CRITICAL:INF.BADPARENT.UNDEF:Message 23
+CRITICAL:INF.BADPARENT:Message 24
+INFO:INF:Finish up, it's closing time. Messages should bear numbers 0 through 24.
+-- log_test0  end    ---------------------------------------------------
+-- log_test1  begin  ---------------------------------------------------
+-- setting logging level to 'Boring' -----
+Boring:root:This should only be seen at the 'Boring' logging level (or lower)
+Chatterbox:root:This should only be seen at the 'Chatterbox' logging level (or lower)
+Garrulous:root:This should only be seen at the 'Garrulous' logging level (or lower)
+Talkative:root:This should only be seen at the 'Talkative' logging level (or lower)
+Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
+Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
+Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
+Terse:root:This should only be seen at the 'Terse' logging level (or lower)
+Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
+Silent:root:This should only be seen at the 'Silent' logging level (or lower)
+-- setting logging level to 'Chatterbox' -----
+Chatterbox:root:This should only be seen at the 'Chatterbox' logging level (or lower)
+Garrulous:root:This should only be seen at the 'Garrulous' logging level (or lower)
+Talkative:root:This should only be seen at the 'Talkative' logging level (or lower)
+Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
+Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
+Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
+Terse:root:This should only be seen at the 'Terse' logging level (or lower)
+Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
+Silent:root:This should only be seen at the 'Silent' logging level (or lower)
+-- setting logging level to 'Garrulous' -----
+Garrulous:root:This should only be seen at the 'Garrulous' logging level (or lower)
+Talkative:root:This should only be seen at the 'Talkative' logging level (or lower)
+Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
+Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
+Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
+Terse:root:This should only be seen at the 'Terse' logging level (or lower)
+Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
+Silent:root:This should only be seen at the 'Silent' logging level (or lower)
+-- setting logging level to 'Talkative' -----
+Talkative:root:This should only be seen at the 'Talkative' logging level (or lower)
+Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
+Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
+Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
+Terse:root:This should only be seen at the 'Terse' logging level (or lower)
+Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
+Silent:root:This should only be seen at the 'Silent' logging level (or lower)
+-- setting logging level to 'Verbose' -----
+Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
+Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
+Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
+Terse:root:This should only be seen at the 'Terse' logging level (or lower)
+Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
+Silent:root:This should only be seen at the 'Silent' logging level (or lower)
+-- setting logging level to 'Sociable' -----
+Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
+Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
+Terse:root:This should only be seen at the 'Terse' logging level (or lower)
+Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
+Silent:root:This should only be seen at the 'Silent' logging level (or lower)
+-- setting logging level to 'Effusive' -----
+Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
+Terse:root:This should only be seen at the 'Terse' logging level (or lower)
+Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
+Silent:root:This should only be seen at the 'Silent' logging level (or lower)
+-- setting logging level to 'Terse' -----
+Terse:root:This should only be seen at the 'Terse' logging level (or lower)
+Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
+Silent:root:This should only be seen at the 'Silent' logging level (or lower)
+-- setting logging level to 'Taciturn' -----
+Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
+Silent:root:This should only be seen at the 'Silent' logging level (or lower)
+-- setting logging level to 'Silent' -----
+Silent:root:This should only be seen at the 'Silent' logging level (or lower)
+-- Filtering at handler level to SOCIABLE --
+-- setting logging level to 'Boring' -----
+Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
+Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
+Terse:root:This should only be seen at the 'Terse' logging level (or lower)
+Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
+Silent:root:This should only be seen at the 'Silent' logging level (or lower)
+-- setting logging level to 'Chatterbox' -----
+Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
+Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
+Terse:root:This should only be seen at the 'Terse' logging level (or lower)
+Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
+Silent:root:This should only be seen at the 'Silent' logging level (or lower)
+-- setting logging level to 'Garrulous' -----
+Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
+Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
+Terse:root:This should only be seen at the 'Terse' logging level (or lower)
+Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
+Silent:root:This should only be seen at the 'Silent' logging level (or lower)
+-- setting logging level to 'Talkative' -----
+Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
+Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
+Terse:root:This should only be seen at the 'Terse' logging level (or lower)
+Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
+Silent:root:This should only be seen at the 'Silent' logging level (or lower)
+-- setting logging level to 'Verbose' -----
+Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
+Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
+Terse:root:This should only be seen at the 'Terse' logging level (or lower)
+Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
+Silent:root:This should only be seen at the 'Silent' logging level (or lower)
+-- setting logging level to 'Sociable' -----
+Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
+Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
+Terse:root:This should only be seen at the 'Terse' logging level (or lower)
+Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
+Silent:root:This should only be seen at the 'Silent' logging level (or lower)
+-- setting logging level to 'Effusive' -----
+Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
+Terse:root:This should only be seen at the 'Terse' logging level (or lower)
+Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
+Silent:root:This should only be seen at the 'Silent' logging level (or lower)
+-- setting logging level to 'Terse' -----
+Terse:root:This should only be seen at the 'Terse' logging level (or lower)
+Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
+Silent:root:This should only be seen at the 'Silent' logging level (or lower)
+-- setting logging level to 'Taciturn' -----
+Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
+Silent:root:This should only be seen at the 'Silent' logging level (or lower)
+-- setting logging level to 'Silent' -----
+Silent:root:This should only be seen at the 'Silent' logging level (or lower)
+-- Filtering using GARRULOUS filter --
+-- setting logging level to 'Boring' -----
+Boring:root:This should only be seen at the 'Boring' logging level (or lower)
+Chatterbox:root:This should only be seen at the 'Chatterbox' logging level (or lower)
+Talkative:root:This should only be seen at the 'Talkative' logging level (or lower)
+Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
+Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
+Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
+Terse:root:This should only be seen at the 'Terse' logging level (or lower)
+Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
+Silent:root:This should only be seen at the 'Silent' logging level (or lower)
+-- setting logging level to 'Chatterbox' -----
+Chatterbox:root:This should only be seen at the 'Chatterbox' logging level (or lower)
+Talkative:root:This should only be seen at the 'Talkative' logging level (or lower)
+Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
+Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
+Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
+Terse:root:This should only be seen at the 'Terse' logging level (or lower)
+Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
+Silent:root:This should only be seen at the 'Silent' logging level (or lower)
+-- setting logging level to 'Garrulous' -----
+Talkative:root:This should only be seen at the 'Talkative' logging level (or lower)
+Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
+Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
+Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
+Terse:root:This should only be seen at the 'Terse' logging level (or lower)
+Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
+Silent:root:This should only be seen at the 'Silent' logging level (or lower)
+-- setting logging level to 'Talkative' -----
+Talkative:root:This should only be seen at the 'Talkative' logging level (or lower)
+Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
+Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
+Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
+Terse:root:This should only be seen at the 'Terse' logging level (or lower)
+Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
+Silent:root:This should only be seen at the 'Silent' logging level (or lower)
+-- setting logging level to 'Verbose' -----
+Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
+Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
+Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
+Terse:root:This should only be seen at the 'Terse' logging level (or lower)
+Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
+Silent:root:This should only be seen at the 'Silent' logging level (or lower)
+-- setting logging level to 'Sociable' -----
+Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
+Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
+Terse:root:This should only be seen at the 'Terse' logging level (or lower)
+Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
+Silent:root:This should only be seen at the 'Silent' logging level (or lower)
+-- setting logging level to 'Effusive' -----
+Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
+Terse:root:This should only be seen at the 'Terse' logging level (or lower)
+Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
+Silent:root:This should only be seen at the 'Silent' logging level (or lower)
+-- setting logging level to 'Terse' -----
+Terse:root:This should only be seen at the 'Terse' logging level (or lower)
+Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
+Silent:root:This should only be seen at the 'Silent' logging level (or lower)
+-- setting logging level to 'Taciturn' -----
+Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
+Silent:root:This should only be seen at the 'Silent' logging level (or lower)
+-- setting logging level to 'Silent' -----
+Silent:root:This should only be seen at the 'Silent' logging level (or lower)
+-- Filtering using specific filter for SOCIABLE, TACITURN --
+-- setting logging level to 'Boring' -----
+Boring:root:This should only be seen at the 'Boring' logging level (or lower)
+Chatterbox:root:This should only be seen at the 'Chatterbox' logging level (or lower)
+Talkative:root:This should only be seen at the 'Talkative' logging level (or lower)
+Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
+Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
+Terse:root:This should only be seen at the 'Terse' logging level (or lower)
+Silent:root:This should only be seen at the 'Silent' logging level (or lower)
+-- setting logging level to 'Chatterbox' -----
+Chatterbox:root:This should only be seen at the 'Chatterbox' logging level (or lower)
+Talkative:root:This should only be seen at the 'Talkative' logging level (or lower)
+Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
+Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
+Terse:root:This should only be seen at the 'Terse' logging level (or lower)
+Silent:root:This should only be seen at the 'Silent' logging level (or lower)
+-- setting logging level to 'Garrulous' -----
+Talkative:root:This should only be seen at the 'Talkative' logging level (or lower)
+Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
+Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
+Terse:root:This should only be seen at the 'Terse' logging level (or lower)
+Silent:root:This should only be seen at the 'Silent' logging level (or lower)
+-- setting logging level to 'Talkative' -----
+Talkative:root:This should only be seen at the 'Talkative' logging level (or lower)
+Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
+Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
+Terse:root:This should only be seen at the 'Terse' logging level (or lower)
+Silent:root:This should only be seen at the 'Silent' logging level (or lower)
+-- setting logging level to 'Verbose' -----
+Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
+Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
+Terse:root:This should only be seen at the 'Terse' logging level (or lower)
+Silent:root:This should only be seen at the 'Silent' logging level (or lower)
+-- setting logging level to 'Sociable' -----
+Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
+Terse:root:This should only be seen at the 'Terse' logging level (or lower)
+Silent:root:This should only be seen at the 'Silent' logging level (or lower)
+-- setting logging level to 'Effusive' -----
+Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
+Terse:root:This should only be seen at the 'Terse' logging level (or lower)
+Silent:root:This should only be seen at the 'Silent' logging level (or lower)
+-- setting logging level to 'Terse' -----
+Terse:root:This should only be seen at the 'Terse' logging level (or lower)
+Silent:root:This should only be seen at the 'Silent' logging level (or lower)
+-- setting logging level to 'Taciturn' -----
+Silent:root:This should only be seen at the 'Silent' logging level (or lower)
+-- setting logging level to 'Silent' -----
+Silent:root:This should only be seen at the 'Silent' logging level (or lower)
+-- log_test1  end    ---------------------------------------------------
+-- log_test2  begin  ---------------------------------------------------
+-- logging at DEBUG, nothing should be seen yet --
+-- logging at INFO, nothing should be seen yet --
+-- logging at WARNING, 3 messages should be seen --
+DEBUG:root:Debug message
+INFO:root:Info message
+WARNING:root:Warn message
+-- logging 0 at INFO, messages should be seen every 10 events --
+-- logging 1 at INFO, messages should be seen every 10 events --
+-- logging 2 at INFO, messages should be seen every 10 events --
+-- logging 3 at INFO, messages should be seen every 10 events --
+-- logging 4 at INFO, messages should be seen every 10 events --
+-- logging 5 at INFO, messages should be seen every 10 events --
+-- logging 6 at INFO, messages should be seen every 10 events --
+-- logging 7 at INFO, messages should be seen every 10 events --
+-- logging 8 at INFO, messages should be seen every 10 events --
+-- logging 9 at INFO, messages should be seen every 10 events --
+INFO:root:Info index = 0
+INFO:root:Info index = 1
+INFO:root:Info index = 2
+INFO:root:Info index = 3
+INFO:root:Info index = 4
+INFO:root:Info index = 5
+INFO:root:Info index = 6
+INFO:root:Info index = 7
+INFO:root:Info index = 8
+INFO:root:Info index = 9
+-- logging 10 at INFO, messages should be seen every 10 events --
+-- logging 11 at INFO, messages should be seen every 10 events --
+-- logging 12 at INFO, messages should be seen every 10 events --
+-- logging 13 at INFO, messages should be seen every 10 events --
+-- logging 14 at INFO, messages should be seen every 10 events --
+-- logging 15 at INFO, messages should be seen every 10 events --
+-- logging 16 at INFO, messages should be seen every 10 events --
+-- logging 17 at INFO, messages should be seen every 10 events --
+-- logging 18 at INFO, messages should be seen every 10 events --
+-- logging 19 at INFO, messages should be seen every 10 events --
+INFO:root:Info index = 10
+INFO:root:Info index = 11
+INFO:root:Info index = 12
+INFO:root:Info index = 13
+INFO:root:Info index = 14
+INFO:root:Info index = 15
+INFO:root:Info index = 16
+INFO:root:Info index = 17
+INFO:root:Info index = 18
+INFO:root:Info index = 19
+-- logging 20 at INFO, messages should be seen every 10 events --
+-- logging 21 at INFO, messages should be seen every 10 events --
+-- logging 22 at INFO, messages should be seen every 10 events --
+-- logging 23 at INFO, messages should be seen every 10 events --
+-- logging 24 at INFO, messages should be seen every 10 events --
+-- logging 25 at INFO, messages should be seen every 10 events --
+-- logging 26 at INFO, messages should be seen every 10 events --
+-- logging 27 at INFO, messages should be seen every 10 events --
+-- logging 28 at INFO, messages should be seen every 10 events --
+-- logging 29 at INFO, messages should be seen every 10 events --
+INFO:root:Info index = 20
+INFO:root:Info index = 21
+INFO:root:Info index = 22
+INFO:root:Info index = 23
+INFO:root:Info index = 24
+INFO:root:Info index = 25
+INFO:root:Info index = 26
+INFO:root:Info index = 27
+INFO:root:Info index = 28
+INFO:root:Info index = 29
+-- logging 30 at INFO, messages should be seen every 10 events --
+-- logging 31 at INFO, messages should be seen every 10 events --
+-- logging 32 at INFO, messages should be seen every 10 events --
+-- logging 33 at INFO, messages should be seen every 10 events --
+-- logging 34 at INFO, messages should be seen every 10 events --
+-- logging 35 at INFO, messages should be seen every 10 events --
+-- logging 36 at INFO, messages should be seen every 10 events --
+-- logging 37 at INFO, messages should be seen every 10 events --
+-- logging 38 at INFO, messages should be seen every 10 events --
+-- logging 39 at INFO, messages should be seen every 10 events --
+INFO:root:Info index = 30
+INFO:root:Info index = 31
+INFO:root:Info index = 32
+INFO:root:Info index = 33
+INFO:root:Info index = 34
+INFO:root:Info index = 35
+INFO:root:Info index = 36
+INFO:root:Info index = 37
+INFO:root:Info index = 38
+INFO:root:Info index = 39
+-- logging 40 at INFO, messages should be seen every 10 events --
+-- logging 41 at INFO, messages should be seen every 10 events --
+-- logging 42 at INFO, messages should be seen every 10 events --
+-- logging 43 at INFO, messages should be seen every 10 events --
+-- logging 44 at INFO, messages should be seen every 10 events --
+-- logging 45 at INFO, messages should be seen every 10 events --
+-- logging 46 at INFO, messages should be seen every 10 events --
+-- logging 47 at INFO, messages should be seen every 10 events --
+-- logging 48 at INFO, messages should be seen every 10 events --
+-- logging 49 at INFO, messages should be seen every 10 events --
+INFO:root:Info index = 40
+INFO:root:Info index = 41
+INFO:root:Info index = 42
+INFO:root:Info index = 43
+INFO:root:Info index = 44
+INFO:root:Info index = 45
+INFO:root:Info index = 46
+INFO:root:Info index = 47
+INFO:root:Info index = 48
+INFO:root:Info index = 49
+-- logging 50 at INFO, messages should be seen every 10 events --
+-- logging 51 at INFO, messages should be seen every 10 events --
+-- logging 52 at INFO, messages should be seen every 10 events --
+-- logging 53 at INFO, messages should be seen every 10 events --
+-- logging 54 at INFO, messages should be seen every 10 events --
+-- logging 55 at INFO, messages should be seen every 10 events --
+-- logging 56 at INFO, messages should be seen every 10 events --
+-- logging 57 at INFO, messages should be seen every 10 events --
+-- logging 58 at INFO, messages should be seen every 10 events --
+-- logging 59 at INFO, messages should be seen every 10 events --
+INFO:root:Info index = 50
+INFO:root:Info index = 51
+INFO:root:Info index = 52
+INFO:root:Info index = 53
+INFO:root:Info index = 54
+INFO:root:Info index = 55
+INFO:root:Info index = 56
+INFO:root:Info index = 57
+INFO:root:Info index = 58
+INFO:root:Info index = 59
+-- logging 60 at INFO, messages should be seen every 10 events --
+-- logging 61 at INFO, messages should be seen every 10 events --
+-- logging 62 at INFO, messages should be seen every 10 events --
+-- logging 63 at INFO, messages should be seen every 10 events --
+-- logging 64 at INFO, messages should be seen every 10 events --
+-- logging 65 at INFO, messages should be seen every 10 events --
+-- logging 66 at INFO, messages should be seen every 10 events --
+-- logging 67 at INFO, messages should be seen every 10 events --
+-- logging 68 at INFO, messages should be seen every 10 events --
+-- logging 69 at INFO, messages should be seen every 10 events --
+INFO:root:Info index = 60
+INFO:root:Info index = 61
+INFO:root:Info index = 62
+INFO:root:Info index = 63
+INFO:root:Info index = 64
+INFO:root:Info index = 65
+INFO:root:Info index = 66
+INFO:root:Info index = 67
+INFO:root:Info index = 68
+INFO:root:Info index = 69
+-- logging 70 at INFO, messages should be seen every 10 events --
+-- logging 71 at INFO, messages should be seen every 10 events --
+-- logging 72 at INFO, messages should be seen every 10 events --
+-- logging 73 at INFO, messages should be seen every 10 events --
+-- logging 74 at INFO, messages should be seen every 10 events --
+-- logging 75 at INFO, messages should be seen every 10 events --
+-- logging 76 at INFO, messages should be seen every 10 events --
+-- logging 77 at INFO, messages should be seen every 10 events --
+-- logging 78 at INFO, messages should be seen every 10 events --
+-- logging 79 at INFO, messages should be seen every 10 events --
+INFO:root:Info index = 70
+INFO:root:Info index = 71
+INFO:root:Info index = 72
+INFO:root:Info index = 73
+INFO:root:Info index = 74
+INFO:root:Info index = 75
+INFO:root:Info index = 76
+INFO:root:Info index = 77
+INFO:root:Info index = 78
+INFO:root:Info index = 79
+-- logging 80 at INFO, messages should be seen every 10 events --
+-- logging 81 at INFO, messages should be seen every 10 events --
+-- logging 82 at INFO, messages should be seen every 10 events --
+-- logging 83 at INFO, messages should be seen every 10 events --
+-- logging 84 at INFO, messages should be seen every 10 events --
+-- logging 85 at INFO, messages should be seen every 10 events --
+-- logging 86 at INFO, messages should be seen every 10 events --
+-- logging 87 at INFO, messages should be seen every 10 events --
+-- logging 88 at INFO, messages should be seen every 10 events --
+-- logging 89 at INFO, messages should be seen every 10 events --
+INFO:root:Info index = 80
+INFO:root:Info index = 81
+INFO:root:Info index = 82
+INFO:root:Info index = 83
+INFO:root:Info index = 84
+INFO:root:Info index = 85
+INFO:root:Info index = 86
+INFO:root:Info index = 87
+INFO:root:Info index = 88
+INFO:root:Info index = 89
+-- logging 90 at INFO, messages should be seen every 10 events --
+-- logging 91 at INFO, messages should be seen every 10 events --
+-- logging 92 at INFO, messages should be seen every 10 events --
+-- logging 93 at INFO, messages should be seen every 10 events --
+-- logging 94 at INFO, messages should be seen every 10 events --
+-- logging 95 at INFO, messages should be seen every 10 events --
+-- logging 96 at INFO, messages should be seen every 10 events --
+-- logging 97 at INFO, messages should be seen every 10 events --
+-- logging 98 at INFO, messages should be seen every 10 events --
+-- logging 99 at INFO, messages should be seen every 10 events --
+INFO:root:Info index = 90
+INFO:root:Info index = 91
+INFO:root:Info index = 92
+INFO:root:Info index = 93
+INFO:root:Info index = 94
+INFO:root:Info index = 95
+INFO:root:Info index = 96
+INFO:root:Info index = 97
+INFO:root:Info index = 98
+INFO:root:Info index = 99
+-- logging 100 at INFO, messages should be seen every 10 events --
+-- logging 101 at INFO, messages should be seen every 10 events --
+INFO:root:Info index = 100
+INFO:root:Info index = 101
+-- log_test2  end    ---------------------------------------------------
+-- log_test3  begin  ---------------------------------------------------
+Unfiltered...
+INFO:a:Info 1
+INFO:a.b:Info 2
+INFO:a.c:Info 3
+INFO:a.b.c:Info 4
+INFO:a.b.c.d:Info 5
+INFO:a.bb.c:Info 6
+INFO:b:Info 7
+INFO:b.a:Info 8
+INFO:c.a.b:Info 9
+INFO:a.bb:Info 10
+Filtered with 'a.b'...
+INFO:a.b:Info 2
+INFO:a.b.c:Info 4
+INFO:a.b.c.d:Info 5
+-- log_test3  end    ---------------------------------------------------
+-- log_test4  begin  ---------------------------------------------------
+config0: ok.
+config1: ok.
+config2: <type 'exceptions.AttributeError'>
+config3: <type 'exceptions.KeyError'>
+-- log_test4  end    ---------------------------------------------------
+-- log_test5  begin  ---------------------------------------------------
+ERROR:root:just testing
+<type 'exceptions.KeyError'>... Don't panic!
+-- log_test5  end    ---------------------------------------------------
+-- logrecv output begin  ---------------------------------------------------
+ERR -> CRITICAL: Message 0 (via logrecv.tcp.ERR)
+ERR -> ERROR: Message 1 (via logrecv.tcp.ERR)
+INF -> CRITICAL: Message 2 (via logrecv.tcp.INF)
+INF -> ERROR: Message 3 (via logrecv.tcp.INF)
+INF -> WARNING: Message 4 (via logrecv.tcp.INF)
+INF -> INFO: Message 5 (via logrecv.tcp.INF)
+INF.UNDEF -> CRITICAL: Message 6 (via logrecv.tcp.INF.UNDEF)
+INF.UNDEF -> ERROR: Message 7 (via logrecv.tcp.INF.UNDEF)
+INF.UNDEF -> WARNING: Message 8 (via logrecv.tcp.INF.UNDEF)
+INF.UNDEF -> INFO: Message 9 (via logrecv.tcp.INF.UNDEF)
+INF.ERR -> CRITICAL: Message 10 (via logrecv.tcp.INF.ERR)
+INF.ERR -> ERROR: Message 11 (via logrecv.tcp.INF.ERR)
+INF.ERR.UNDEF -> CRITICAL: Message 12 (via logrecv.tcp.INF.ERR.UNDEF)
+INF.ERR.UNDEF -> ERROR: Message 13 (via logrecv.tcp.INF.ERR.UNDEF)
+DEB -> CRITICAL: Message 14 (via logrecv.tcp.DEB)
+DEB -> ERROR: Message 15 (via logrecv.tcp.DEB)
+DEB -> WARNING: Message 16 (via logrecv.tcp.DEB)
+DEB -> INFO: Message 17 (via logrecv.tcp.DEB)
+DEB -> DEBUG: Message 18 (via logrecv.tcp.DEB)
+UNDEF -> CRITICAL: Message 19 (via logrecv.tcp.UNDEF)
+UNDEF -> ERROR: Message 20 (via logrecv.tcp.UNDEF)
+UNDEF -> WARNING: Message 21 (via logrecv.tcp.UNDEF)
+UNDEF -> INFO: Message 22 (via logrecv.tcp.UNDEF)
+INF.BADPARENT.UNDEF -> CRITICAL: Message 23 (via logrecv.tcp.INF.BADPARENT.UNDEF)
+INF.BADPARENT -> CRITICAL: Message 24 (via logrecv.tcp.INF.BADPARENT)
+INF -> INFO: Finish up, it's closing time. Messages should bear numbers 0 through 24. (via logrecv.tcp.INF)
+-- logrecv output end    ---------------------------------------------------

Added: vendor/Python/current/Lib/test/output/test_math
===================================================================
--- vendor/Python/current/Lib/test/output/test_math	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/output/test_math	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,28 @@
+test_math
+math module, testing with eps 1e-05
+constants
+acos
+asin
+atan
+atan2
+ceil
+cos
+cosh
+degrees
+exp
+fabs
+floor
+fmod
+frexp
+hypot
+ldexp
+log
+log10
+modf
+pow
+radians
+sin
+sinh
+sqrt
+tan
+tanh

Added: vendor/Python/current/Lib/test/output/test_mmap
===================================================================
--- vendor/Python/current/Lib/test/output/test_mmap	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/output/test_mmap	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,38 @@
+test_mmap
+<type 'mmap.mmap'>
+  Position of foo: 1.0 pages
+  Length of file: 2.0 pages
+  Contents of byte 0: '\x00'
+  Contents of first 3 bytes: '\x00\x00\x00'
+
+  Modifying file's content...
+  Contents of byte 0: '3'
+  Contents of first 3 bytes: '3\x00\x00'
+  Contents of second page: '\x00foobar\x00'
+  Regex match on mmap (page start, length of match): 1.0 6
+  Seek to zeroth byte
+  Seek to 42nd byte
+  Seek to last byte
+  Try to seek to negative position...
+  Try to seek beyond end of mmap...
+  Try to seek to negative position...
+  Attempting resize()
+  Creating 10 byte test data file.
+  Opening mmap with access=ACCESS_READ
+  Ensuring that readonly mmap can't be slice assigned.
+  Ensuring that readonly mmap can't be item assigned.
+  Ensuring that readonly mmap can't be write() to.
+  Ensuring that readonly mmap can't be write_byte() to.
+  Ensuring that readonly mmap can't be resized.
+  Opening mmap with size too big
+  Opening mmap with access=ACCESS_WRITE
+  Modifying write-through memory map.
+  Opening mmap with access=ACCESS_COPY
+  Modifying copy-on-write memory map.
+  Ensuring copy-on-write maps cannot be resized.
+  Ensuring invalid access parameter raises exception.
+  Try opening a bad file descriptor...
+  Ensuring that passing 0 as map length sets map size to current file size.
+  Ensuring that passing 0 as map length sets map size to current file size.
+  anonymous mmap.mmap(-1, PAGESIZE)...
+ Test passed

Added: vendor/Python/current/Lib/test/output/test_new
===================================================================
--- vendor/Python/current/Lib/test/output/test_new	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/output/test_new	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,7 @@
+test_new
+new.module()
+new.classobj()
+new.instance()
+new.instancemethod()
+new.function()
+new.code()

Added: vendor/Python/current/Lib/test/output/test_nis
===================================================================
--- vendor/Python/current/Lib/test/output/test_nis	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/output/test_nis	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2 @@
+test_nis
+nis.maps()

Added: vendor/Python/current/Lib/test/output/test_opcodes
===================================================================
--- vendor/Python/current/Lib/test/output/test_opcodes	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/output/test_opcodes	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,6 @@
+test_opcodes
+2. Opcodes
+XXX Not yet fully implemented
+2.1 try inside for loop
+2.2 raise class exceptions
+2.3 comparing function objects

Added: vendor/Python/current/Lib/test/output/test_openpty
===================================================================
--- vendor/Python/current/Lib/test/output/test_openpty	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/output/test_openpty	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2 @@
+test_openpty
+Ping!

Added: vendor/Python/current/Lib/test/output/test_operations
===================================================================
--- vendor/Python/current/Lib/test/output/test_operations	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/output/test_operations	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,21 @@
+test_operations
+3. Operations
+XXX Mostly not yet implemented
+3.1 Dictionary lookups fail if __cmp__() raises an exception
+raising error
+d[x2] = 2: caught the RuntimeError outside
+raising error
+z = d[x2]: caught the RuntimeError outside
+raising error
+x2 in d: caught the RuntimeError outside
+raising error
+d.has_key(x2): caught the RuntimeError outside
+raising error
+d.get(x2): caught the RuntimeError outside
+raising error
+d.setdefault(x2, 42): caught the RuntimeError outside
+raising error
+d.pop(x2): caught the RuntimeError outside
+raising error
+d.update({x2: 2}): caught the RuntimeError outside
+resize bugs not triggered.

Added: vendor/Python/current/Lib/test/output/test_ossaudiodev
===================================================================
--- vendor/Python/current/Lib/test/output/test_ossaudiodev	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/output/test_ossaudiodev	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2 @@
+test_ossaudiodev
+playing test sound file (expected running time: 2.93 sec)

Added: vendor/Python/current/Lib/test/output/test_pep277
===================================================================
--- vendor/Python/current/Lib/test/output/test_pep277	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/output/test_pep277	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,3 @@
+test_pep277
+u'\xdf-\u66e8\u66e9\u66eb'
+[u'Gr\xfc\xdf-Gott', u'abc', u'ascii', u'\u0393\u03b5\u03b9\u03ac-\u03c3\u03b1\u03c2', u'\u0417\u0434\u0440\u0430\u0432\u0441\u0442\u0432\u0443\u0439\u0442\u0435', u'\u05d4\u05e9\u05e7\u05e6\u05e5\u05e1', u'\u306b\u307d\u3093', u'\u66e8\u05e9\u3093\u0434\u0393\xdf', u'\u66e8\u66e9\u66eb']

Added: vendor/Python/current/Lib/test/output/test_pkg
===================================================================
--- vendor/Python/current/Lib/test/output/test_pkg	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/output/test_pkg	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,45 @@
+test_pkg
+running test t1
+running test t2
+t2 loading
+doc for t2
+t2.sub.subsub loading
+t2 t2.sub t2.sub.subsub
+['sub', 't2']
+t2.sub t2.sub.subsub
+t2.sub.subsub
+['spam', 'sub', 'subsub', 't2']
+t2 t2.sub t2.sub.subsub
+['spam', 'sub', 'subsub', 't2']
+running test t3
+t3 loading
+t3.sub.subsub loading
+t3 t3.sub t3.sub.subsub
+t3 loading
+t3.sub.subsub loading
+running test t4
+t4 loading
+t4.sub.subsub loading
+t4.sub.subsub.spam = 1
+running test t5
+t5.foo loading
+t5.string loading
+1
+['foo', 'string', 't5']
+['__doc__', '__file__', '__name__', '__path__', 'foo', 'string', 't5']
+['__doc__', '__file__', '__name__', 'string']
+['__doc__', '__file__', '__name__', 'spam']
+running test t6
+['__all__', '__doc__', '__file__', '__name__', '__path__']
+t6.spam loading
+t6.ham loading
+t6.eggs loading
+['__all__', '__doc__', '__file__', '__name__', '__path__', 'eggs', 'ham', 'spam']
+['eggs', 'ham', 'spam', 't6']
+running test t7
+t7 loading
+['__doc__', '__file__', '__name__', '__path__']
+['__doc__', '__file__', '__name__', '__path__']
+t7.sub.subsub loading
+['__doc__', '__file__', '__name__', '__path__', 'spam']
+t7.sub.subsub.spam = 1

Added: vendor/Python/current/Lib/test/output/test_poll
===================================================================
--- vendor/Python/current/Lib/test/output/test_poll	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/output/test_poll	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,19 @@
+test_poll
+Running poll test 1
+ This is a test.
+ This is a test.
+ This is a test.
+ This is a test.
+ This is a test.
+ This is a test.
+ This is a test.
+ This is a test.
+ This is a test.
+ This is a test.
+ This is a test.
+ This is a test.
+Poll test 1 complete
+Running poll test 2
+Poll test 2 complete
+Running poll test 3
+Poll test 3 complete

Added: vendor/Python/current/Lib/test/output/test_popen
===================================================================
--- vendor/Python/current/Lib/test/output/test_popen	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/output/test_popen	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,3 @@
+test_popen
+Test popen:
+popen seemed to process the command-line correctly

Added: vendor/Python/current/Lib/test/output/test_popen2
===================================================================
--- vendor/Python/current/Lib/test/output/test_popen2	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/output/test_popen2	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,9 @@
+test_popen2
+Test popen2 module:
+testing popen2...
+testing popen3...
+All OK
+Testing os module:
+testing popen2...
+testing popen3...
+All OK

Added: vendor/Python/current/Lib/test/output/test_profile
===================================================================
--- vendor/Python/current/Lib/test/output/test_profile	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/output/test_profile	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,84 @@
+test_profile
+         127 function calls (107 primitive calls) in 1.000 CPU seconds
+
+   Ordered by: standard name
+
+   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
+        4    0.000    0.000    0.000    0.000 :0(append)
+        4    0.000    0.000    0.000    0.000 :0(exc_info)
+       12    0.000    0.000    0.012    0.001 :0(hasattr)
+        8    0.000    0.000    0.000    0.000 :0(range)
+        1    0.000    0.000    0.000    0.000 :0(setprofile)
+        1    0.000    0.000    1.000    1.000 <string>:1(<module>)
+        0    0.000             0.000          profile:0(profiler)
+        1    0.000    0.000    1.000    1.000 profile:0(testfunc())
+        8    0.064    0.008    0.080    0.010 test_profile.py:103(subhelper)
+       28    0.028    0.001    0.028    0.001 test_profile.py:115(__getattr__)
+        1    0.270    0.270    1.000    1.000 test_profile.py:30(testfunc)
+     23/3    0.150    0.007    0.170    0.057 test_profile.py:40(factorial)
+       20    0.020    0.001    0.020    0.001 test_profile.py:53(mul)
+        2    0.040    0.020    0.600    0.300 test_profile.py:60(helper)
+        4    0.116    0.029    0.120    0.030 test_profile.py:78(helper1)
+        2    0.000    0.000    0.140    0.070 test_profile.py:89(helper2_indirect)
+        8    0.312    0.039    0.400    0.050 test_profile.py:93(helper2)
+
+
+   Ordered by: standard name
+
+Function                              called...
+:0(append)                            ->
+:0(exc_info)                          ->
+:0(hasattr)                           -> test_profile.py:115(__getattr__)(12)    0.028
+:0(range)                             ->
+:0(setprofile)                        ->
+<string>:1(<module>)                  -> test_profile.py:30(testfunc)(1)    1.000
+profile:0(profiler)                   -> profile:0(testfunc())(1)    1.000
+profile:0(testfunc())                 -> :0(setprofile)(1)    0.000
+                                         <string>:1(<module>)(1)    1.000
+test_profile.py:103(subhelper)        -> :0(range)(8)    0.000
+                                         test_profile.py:115(__getattr__)(16)    0.028
+test_profile.py:115(__getattr__)      ->
+test_profile.py:30(testfunc)          -> test_profile.py:40(factorial)(1)    0.170
+                                         test_profile.py:60(helper)(2)    0.600
+test_profile.py:40(factorial)         -> test_profile.py:40(factorial)(20)    0.170
+                                         test_profile.py:53(mul)(20)    0.020
+test_profile.py:53(mul)               ->
+test_profile.py:60(helper)            -> test_profile.py:78(helper1)(4)    0.120
+                                         test_profile.py:89(helper2_indirect)(2)    0.140
+                                         test_profile.py:93(helper2)(6)    0.400
+test_profile.py:78(helper1)           -> :0(append)(4)    0.000
+                                         :0(exc_info)(4)    0.000
+                                         :0(hasattr)(4)    0.012
+test_profile.py:89(helper2_indirect)  -> test_profile.py:40(factorial)(2)    0.170
+                                         test_profile.py:93(helper2)(2)    0.400
+test_profile.py:93(helper2)           -> :0(hasattr)(8)    0.012
+                                         test_profile.py:103(subhelper)(8)    0.080
+
+
+   Ordered by: standard name
+
+Function                              was called by...
+:0(append)                            <- test_profile.py:78(helper1)(4)    0.120
+:0(exc_info)                          <- test_profile.py:78(helper1)(4)    0.120
+:0(hasattr)                           <- test_profile.py:78(helper1)(4)    0.120
+                                         test_profile.py:93(helper2)(8)    0.400
+:0(range)                             <- test_profile.py:103(subhelper)(8)    0.080
+:0(setprofile)                        <- profile:0(testfunc())(1)    1.000
+<string>:1(<module>)                  <- profile:0(testfunc())(1)    1.000
+profile:0(profiler)                   <-
+profile:0(testfunc())                 <- profile:0(profiler)(1)    0.000
+test_profile.py:103(subhelper)        <- test_profile.py:93(helper2)(8)    0.400
+test_profile.py:115(__getattr__)      <- :0(hasattr)(12)    0.012
+                                         test_profile.py:103(subhelper)(16)    0.080
+test_profile.py:30(testfunc)          <- <string>:1(<module>)(1)    1.000
+test_profile.py:40(factorial)         <- test_profile.py:30(testfunc)(1)    1.000
+                                         test_profile.py:40(factorial)(20)    0.170
+                                         test_profile.py:89(helper2_indirect)(2)    0.140
+test_profile.py:53(mul)               <- test_profile.py:40(factorial)(20)    0.170
+test_profile.py:60(helper)            <- test_profile.py:30(testfunc)(2)    1.000
+test_profile.py:78(helper1)           <- test_profile.py:60(helper)(4)    0.600
+test_profile.py:89(helper2_indirect)  <- test_profile.py:60(helper)(2)    0.600
+test_profile.py:93(helper2)           <- test_profile.py:60(helper)(6)    0.600
+                                         test_profile.py:89(helper2_indirect)(2)    0.140
+
+

Added: vendor/Python/current/Lib/test/output/test_pty
===================================================================
--- vendor/Python/current/Lib/test/output/test_pty	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/output/test_pty	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,3 @@
+test_pty
+I wish to buy a fish license.
+For my pet fish, Eric.

Added: vendor/Python/current/Lib/test/output/test_pyexpat
===================================================================
--- vendor/Python/current/Lib/test/output/test_pyexpat	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/output/test_pyexpat	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,110 @@
+test_pyexpat
+OK.
+OK.
+OK.
+OK.
+OK.
+OK.
+OK.
+OK.
+OK.
+OK.
+OK.
+OK.
+PI:
+	'xml-stylesheet' 'href="stylesheet.css"'
+Comment:
+	' comment data '
+Notation declared: ('notation', None, 'notation.jpeg', None)
+Unparsed entity decl:
+	('unparsed_entity', None, 'entity.file', None, 'notation')
+Start element:
+	'root' {'attr1': 'value1', 'attr2': 'value2\xe1\xbd\x80'}
+NS decl:
+	'myns' 'http://www.python.org/namespace'
+Start element:
+	'http://www.python.org/namespace!subelement' {}
+Character data:
+	'Contents of subelements'
+End element:
+	'http://www.python.org/namespace!subelement'
+End of NS decl:
+	'myns'
+Start element:
+	'sub2' {}
+Start of CDATA section
+Character data:
+	'contents of CDATA section'
+End of CDATA section
+End element:
+	'sub2'
+External entity ref: (None, 'entity.file', None)
+End element:
+	'root'
+PI:
+	u'xml-stylesheet' u'href="stylesheet.css"'
+Comment:
+	u' comment data '
+Notation declared: (u'notation', None, u'notation.jpeg', None)
+Unparsed entity decl:
+	(u'unparsed_entity', None, u'entity.file', None, u'notation')
+Start element:
+	u'root' {u'attr1': u'value1', u'attr2': u'value2\u1f40'}
+NS decl:
+	u'myns' u'http://www.python.org/namespace'
+Start element:
+	u'http://www.python.org/namespace!subelement' {}
+Character data:
+	u'Contents of subelements'
+End element:
+	u'http://www.python.org/namespace!subelement'
+End of NS decl:
+	u'myns'
+Start element:
+	u'sub2' {}
+Start of CDATA section
+Character data:
+	u'contents of CDATA section'
+End of CDATA section
+End element:
+	u'sub2'
+External entity ref: (None, u'entity.file', None)
+End element:
+	u'root'
+PI:
+	u'xml-stylesheet' u'href="stylesheet.css"'
+Comment:
+	u' comment data '
+Notation declared: (u'notation', None, u'notation.jpeg', None)
+Unparsed entity decl:
+	(u'unparsed_entity', None, u'entity.file', None, u'notation')
+Start element:
+	u'root' {u'attr1': u'value1', u'attr2': u'value2\u1f40'}
+NS decl:
+	u'myns' u'http://www.python.org/namespace'
+Start element:
+	u'http://www.python.org/namespace!subelement' {}
+Character data:
+	u'Contents of subelements'
+End element:
+	u'http://www.python.org/namespace!subelement'
+End of NS decl:
+	u'myns'
+Start element:
+	u'sub2' {}
+Start of CDATA section
+Character data:
+	u'contents of CDATA section'
+End of CDATA section
+End element:
+	u'sub2'
+External entity ref: (None, u'entity.file', None)
+End element:
+	u'root'
+
+Testing constructor for proper handling of namespace_separator values:
+Legal values tested o.k.
+Caught expected TypeError:
+ParserCreate() argument 2 must be string or None, not int
+Caught expected ValueError:
+namespace_separator must be at most one character, omitted, or None

Added: vendor/Python/current/Lib/test/output/test_regex
===================================================================
--- vendor/Python/current/Lib/test/output/test_regex	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/output/test_regex	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,29 @@
+test_regex
+no match: -1
+successful search: 6
+caught expected exception
+failed awk syntax: -1
+successful awk syntax: 2
+failed awk syntax: -1
+matching with group names and compile()
+-1
+caught expected exception
+matching with group names and symcomp()
+7
+801 999
+801
+('801', '999')
+('801', '999')
+realpat: \([0-9]+\) *\([0-9]+\)
+groupindex: {'one': 1, 'two': 2}
+not case folded search: -1
+case folded search: 6
+__members__: ['last', 'regs', 'translate', 'groupindex', 'realpat', 'givenpat']
+regs: ((6, 11), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1))
+last: HELLO WORLD
+translate: 256
+givenpat: world
+match with pos: -1
+search with pos: 18
+bogus group: ('world', None, None)
+no name: caught expected exception

Added: vendor/Python/current/Lib/test/output/test_resource
===================================================================
--- vendor/Python/current/Lib/test/output/test_resource	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/output/test_resource	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2 @@
+test_resource
+True

Added: vendor/Python/current/Lib/test/output/test_rgbimg
===================================================================
--- vendor/Python/current/Lib/test/output/test_rgbimg	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/output/test_rgbimg	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2 @@
+test_rgbimg
+RGBimg test suite:

Added: vendor/Python/current/Lib/test/output/test_scope
===================================================================
--- vendor/Python/current/Lib/test/output/test_scope	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/output/test_scope	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,24 @@
+test_scope
+1. simple nesting
+2. extra nesting
+3. simple nesting + rebinding
+4. nesting with global but no free
+5. nesting through class
+6. nesting plus free ref to global
+7. nearest enclosing scope
+8. mixed freevars and cellvars
+9. free variable in method
+10. recursion
+11. unoptimized namespaces
+12. lambdas
+13. UnboundLocal
+14. complex definitions
+15. scope of global statements
+16. check leaks
+17. class and global
+18. verify that locals() works
+19. var is bound and free in class
+20. interaction with trace function
+20. eval and exec with free variables
+21. list comprehension with local variables
+22. eval with free variables

Added: vendor/Python/current/Lib/test/output/test_signal
===================================================================
--- vendor/Python/current/Lib/test/output/test_signal	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/output/test_signal	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2 @@
+test_signal
+starting pause() loop...

Added: vendor/Python/current/Lib/test/output/test_thread
===================================================================
--- vendor/Python/current/Lib/test/output/test_thread	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/output/test_thread	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,18 @@
+test_thread
+waiting for all tasks to complete
+all tasks done
+
+*** Barrier Test ***
+all tasks done
+
+*** Changing thread stack size ***
+caught expected ValueError setting stack_size(4096)
+successfully set stack_size(262144)
+successfully set stack_size(1048576)
+successfully set stack_size(0)
+trying stack_size = 262144
+waiting for all tasks to complete
+all tasks done
+trying stack_size = 1048576
+waiting for all tasks to complete
+all tasks done

Added: vendor/Python/current/Lib/test/output/test_threadedtempfile
===================================================================
--- vendor/Python/current/Lib/test/output/test_threadedtempfile	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/output/test_threadedtempfile	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,5 @@
+test_threadedtempfile
+Creating
+Starting
+Reaping
+Done: errors 0 ok 1000

Added: vendor/Python/current/Lib/test/output/test_tokenize
===================================================================
--- vendor/Python/current/Lib/test/output/test_tokenize	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/output/test_tokenize	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,659 @@
+test_tokenize
+1,0-1,35:	COMMENT	"# Tests for the 'tokenize' module.\n"
+2,0-2,43:	COMMENT	'# Large bits stolen from test_grammar.py. \n'
+3,0-3,1:	NL	'\n'
+4,0-4,11:	COMMENT	'# Comments\n'
+5,0-5,3:	STRING	'"#"'
+5,3-5,4:	NEWLINE	'\n'
+6,0-6,3:	COMMENT	"#'\n"
+7,0-7,3:	COMMENT	'#"\n'
+8,0-8,3:	COMMENT	'#\\\n'
+9,7-9,9:	COMMENT	'#\n'
+10,4-10,10:	COMMENT	'# abc\n'
+11,0-12,4:	STRING	"'''#\n#'''"
+12,4-12,5:	NEWLINE	'\n'
+13,0-13,1:	NL	'\n'
+14,0-14,1:	NAME	'x'
+14,2-14,3:	OP	'='
+14,4-14,5:	NUMBER	'1'
+14,7-14,8:	COMMENT	'#'
+14,8-14,9:	NEWLINE	'\n'
+15,0-15,1:	NL	'\n'
+16,0-16,25:	COMMENT	'# Balancing continuation\n'
+17,0-17,1:	NL	'\n'
+18,0-18,1:	NAME	'a'
+18,2-18,3:	OP	'='
+18,4-18,5:	OP	'('
+18,5-18,6:	NUMBER	'3'
+18,6-18,7:	OP	','
+18,8-18,9:	NUMBER	'4'
+18,9-18,10:	OP	','
+18,10-18,11:	NL	'\n'
+19,2-19,3:	NUMBER	'5'
+19,3-19,4:	OP	','
+19,5-19,6:	NUMBER	'6'
+19,6-19,7:	OP	')'
+19,7-19,8:	NEWLINE	'\n'
+20,0-20,1:	NAME	'y'
+20,2-20,3:	OP	'='
+20,4-20,5:	OP	'['
+20,5-20,6:	NUMBER	'3'
+20,6-20,7:	OP	','
+20,8-20,9:	NUMBER	'4'
+20,9-20,10:	OP	','
+20,10-20,11:	NL	'\n'
+21,2-21,3:	NUMBER	'5'
+21,3-21,4:	OP	']'
+21,4-21,5:	NEWLINE	'\n'
+22,0-22,1:	NAME	'z'
+22,2-22,3:	OP	'='
+22,4-22,5:	OP	'{'
+22,5-22,8:	STRING	"'a'"
+22,8-22,9:	OP	':'
+22,9-22,10:	NUMBER	'5'
+22,10-22,11:	OP	','
+22,11-22,12:	NL	'\n'
+23,2-23,5:	STRING	"'b'"
+23,5-23,6:	OP	':'
+23,6-23,7:	NUMBER	'6'
+23,7-23,8:	OP	'}'
+23,8-23,9:	NEWLINE	'\n'
+24,0-24,1:	NAME	'x'
+24,2-24,3:	OP	'='
+24,4-24,5:	OP	'('
+24,5-24,8:	NAME	'len'
+24,8-24,9:	OP	'('
+24,9-24,10:	OP	'`'
+24,10-24,11:	NAME	'y'
+24,11-24,12:	OP	'`'
+24,12-24,13:	OP	')'
+24,14-24,15:	OP	'+'
+24,16-24,17:	NUMBER	'5'
+24,17-24,18:	OP	'*'
+24,18-24,19:	NAME	'x'
+24,20-24,21:	OP	'-'
+24,22-24,23:	NAME	'a'
+24,23-24,24:	OP	'['
+24,24-24,25:	NL	'\n'
+25,3-25,4:	NUMBER	'3'
+25,5-25,6:	OP	']'
+25,6-25,7:	NL	'\n'
+26,3-26,4:	OP	'-'
+26,5-26,6:	NAME	'x'
+26,7-26,8:	OP	'+'
+26,9-26,12:	NAME	'len'
+26,12-26,13:	OP	'('
+26,13-26,14:	OP	'{'
+26,14-26,15:	NL	'\n'
+27,3-27,4:	OP	'}'
+27,4-27,5:	NL	'\n'
+28,4-28,5:	OP	')'
+28,5-28,6:	NL	'\n'
+29,2-29,3:	OP	')'
+29,3-29,4:	NEWLINE	'\n'
+30,0-30,1:	NL	'\n'
+31,0-31,37:	COMMENT	'# Backslash means line continuation:\n'
+32,0-32,1:	NAME	'x'
+32,2-32,3:	OP	'='
+32,4-32,5:	NUMBER	'1'
+33,0-33,1:	OP	'+'
+33,2-33,3:	NUMBER	'1'
+33,3-33,4:	NEWLINE	'\n'
+34,0-34,1:	NL	'\n'
+35,0-35,55:	COMMENT	'# Backslash does not means continuation in comments :\\\n'
+36,0-36,1:	NAME	'x'
+36,2-36,3:	OP	'='
+36,4-36,5:	NUMBER	'0'
+36,5-36,6:	NEWLINE	'\n'
+37,0-37,1:	NL	'\n'
+38,0-38,20:	COMMENT	'# Ordinary integers\n'
+39,0-39,4:	NUMBER	'0xff'
+39,5-39,7:	OP	'<>'
+39,8-39,11:	NUMBER	'255'
+39,11-39,12:	NEWLINE	'\n'
+40,0-40,4:	NUMBER	'0377'
+40,5-40,7:	OP	'<>'
+40,8-40,11:	NUMBER	'255'
+40,11-40,12:	NEWLINE	'\n'
+41,0-41,10:	NUMBER	'2147483647'
+41,13-41,15:	OP	'!='
+41,16-41,28:	NUMBER	'017777777777'
+41,28-41,29:	NEWLINE	'\n'
+42,0-42,1:	OP	'-'
+42,1-42,11:	NUMBER	'2147483647'
+42,11-42,12:	OP	'-'
+42,12-42,13:	NUMBER	'1'
+42,14-42,16:	OP	'!='
+42,17-42,29:	NUMBER	'020000000000'
+42,29-42,30:	NEWLINE	'\n'
+43,0-43,12:	NUMBER	'037777777777'
+43,13-43,15:	OP	'!='
+43,16-43,17:	OP	'-'
+43,17-43,18:	NUMBER	'1'
+43,18-43,19:	NEWLINE	'\n'
+44,0-44,10:	NUMBER	'0xffffffff'
+44,11-44,13:	OP	'!='
+44,14-44,15:	OP	'-'
+44,15-44,16:	NUMBER	'1'
+44,16-44,17:	NEWLINE	'\n'
+45,0-45,1:	NL	'\n'
+46,0-46,16:	COMMENT	'# Long integers\n'
+47,0-47,1:	NAME	'x'
+47,2-47,3:	OP	'='
+47,4-47,6:	NUMBER	'0L'
+47,6-47,7:	NEWLINE	'\n'
+48,0-48,1:	NAME	'x'
+48,2-48,3:	OP	'='
+48,4-48,6:	NUMBER	'0l'
+48,6-48,7:	NEWLINE	'\n'
+49,0-49,1:	NAME	'x'
+49,2-49,3:	OP	'='
+49,4-49,23:	NUMBER	'0xffffffffffffffffL'
+49,23-49,24:	NEWLINE	'\n'
+50,0-50,1:	NAME	'x'
+50,2-50,3:	OP	'='
+50,4-50,23:	NUMBER	'0xffffffffffffffffl'
+50,23-50,24:	NEWLINE	'\n'
+51,0-51,1:	NAME	'x'
+51,2-51,3:	OP	'='
+51,4-51,23:	NUMBER	'077777777777777777L'
+51,23-51,24:	NEWLINE	'\n'
+52,0-52,1:	NAME	'x'
+52,2-52,3:	OP	'='
+52,4-52,23:	NUMBER	'077777777777777777l'
+52,23-52,24:	NEWLINE	'\n'
+53,0-53,1:	NAME	'x'
+53,2-53,3:	OP	'='
+53,4-53,35:	NUMBER	'123456789012345678901234567890L'
+53,35-53,36:	NEWLINE	'\n'
+54,0-54,1:	NAME	'x'
+54,2-54,3:	OP	'='
+54,4-54,35:	NUMBER	'123456789012345678901234567890l'
+54,35-54,36:	NEWLINE	'\n'
+55,0-55,1:	NL	'\n'
+56,0-56,25:	COMMENT	'# Floating-point numbers\n'
+57,0-57,1:	NAME	'x'
+57,2-57,3:	OP	'='
+57,4-57,8:	NUMBER	'3.14'
+57,8-57,9:	NEWLINE	'\n'
+58,0-58,1:	NAME	'x'
+58,2-58,3:	OP	'='
+58,4-58,8:	NUMBER	'314.'
+58,8-58,9:	NEWLINE	'\n'
+59,0-59,1:	NAME	'x'
+59,2-59,3:	OP	'='
+59,4-59,9:	NUMBER	'0.314'
+59,9-59,10:	NEWLINE	'\n'
+60,0-60,18:	COMMENT	'# XXX x = 000.314\n'
+61,0-61,1:	NAME	'x'
+61,2-61,3:	OP	'='
+61,4-61,8:	NUMBER	'.314'
+61,8-61,9:	NEWLINE	'\n'
+62,0-62,1:	NAME	'x'
+62,2-62,3:	OP	'='
+62,4-62,8:	NUMBER	'3e14'
+62,8-62,9:	NEWLINE	'\n'
+63,0-63,1:	NAME	'x'
+63,2-63,3:	OP	'='
+63,4-63,8:	NUMBER	'3E14'
+63,8-63,9:	NEWLINE	'\n'
+64,0-64,1:	NAME	'x'
+64,2-64,3:	OP	'='
+64,4-64,9:	NUMBER	'3e-14'
+64,9-64,10:	NEWLINE	'\n'
+65,0-65,1:	NAME	'x'
+65,2-65,3:	OP	'='
+65,4-65,9:	NUMBER	'3e+14'
+65,9-65,10:	NEWLINE	'\n'
+66,0-66,1:	NAME	'x'
+66,2-66,3:	OP	'='
+66,4-66,9:	NUMBER	'3.e14'
+66,9-66,10:	NEWLINE	'\n'
+67,0-67,1:	NAME	'x'
+67,2-67,3:	OP	'='
+67,4-67,9:	NUMBER	'.3e14'
+67,9-67,10:	NEWLINE	'\n'
+68,0-68,1:	NAME	'x'
+68,2-68,3:	OP	'='
+68,4-68,9:	NUMBER	'3.1e4'
+68,9-68,10:	NEWLINE	'\n'
+69,0-69,1:	NL	'\n'
+70,0-70,18:	COMMENT	'# String literals\n'
+71,0-71,1:	NAME	'x'
+71,2-71,3:	OP	'='
+71,4-71,6:	STRING	"''"
+71,6-71,7:	OP	';'
+71,8-71,9:	NAME	'y'
+71,10-71,11:	OP	'='
+71,12-71,14:	STRING	'""'
+71,14-71,15:	OP	';'
+71,15-71,16:	NEWLINE	'\n'
+72,0-72,1:	NAME	'x'
+72,2-72,3:	OP	'='
+72,4-72,8:	STRING	"'\\''"
+72,8-72,9:	OP	';'
+72,10-72,11:	NAME	'y'
+72,12-72,13:	OP	'='
+72,14-72,17:	STRING	'"\'"'
+72,17-72,18:	OP	';'
+72,18-72,19:	NEWLINE	'\n'
+73,0-73,1:	NAME	'x'
+73,2-73,3:	OP	'='
+73,4-73,7:	STRING	'\'"\''
+73,7-73,8:	OP	';'
+73,9-73,10:	NAME	'y'
+73,11-73,12:	OP	'='
+73,13-73,17:	STRING	'"\\""'
+73,17-73,18:	OP	';'
+73,18-73,19:	NEWLINE	'\n'
+74,0-74,1:	NAME	'x'
+74,2-74,3:	OP	'='
+74,4-74,32:	STRING	'"doesn\'t \\"shrink\\" does it"'
+74,32-74,33:	NEWLINE	'\n'
+75,0-75,1:	NAME	'y'
+75,2-75,3:	OP	'='
+75,4-75,31:	STRING	'\'doesn\\\'t "shrink" does it\''
+75,31-75,32:	NEWLINE	'\n'
+76,0-76,1:	NAME	'x'
+76,2-76,3:	OP	'='
+76,4-76,32:	STRING	'"does \\"shrink\\" doesn\'t it"'
+76,32-76,33:	NEWLINE	'\n'
+77,0-77,1:	NAME	'y'
+77,2-77,3:	OP	'='
+77,4-77,31:	STRING	'\'does "shrink" doesn\\\'t it\''
+77,31-77,32:	NEWLINE	'\n'
+78,0-78,1:	NAME	'x'
+78,2-78,3:	OP	'='
+78,4-83,3:	STRING	'"""\nThe "quick"\nbrown fox\njumps over\nthe \'lazy\' dog.\n"""'
+83,3-83,4:	NEWLINE	'\n'
+84,0-84,1:	NAME	'y'
+84,2-84,3:	OP	'='
+84,4-84,63:	STRING	'\'\\nThe "quick"\\nbrown fox\\njumps over\\nthe \\\'lazy\\\' dog.\\n\''
+84,63-84,64:	NEWLINE	'\n'
+85,0-85,1:	NAME	'y'
+85,2-85,3:	OP	'='
+85,4-90,3:	STRING	'\'\'\'\nThe "quick"\nbrown fox\njumps over\nthe \'lazy\' dog.\n\'\'\''
+90,3-90,4:	OP	';'
+90,4-90,5:	NEWLINE	'\n'
+91,0-91,1:	NAME	'y'
+91,2-91,3:	OP	'='
+91,4-96,1:	STRING	'"\\n\\\nThe \\"quick\\"\\n\\\nbrown fox\\n\\\njumps over\\n\\\nthe \'lazy\' dog.\\n\\\n"'
+96,1-96,2:	OP	';'
+96,2-96,3:	NEWLINE	'\n'
+97,0-97,1:	NAME	'y'
+97,2-97,3:	OP	'='
+97,4-102,1:	STRING	'\'\\n\\\nThe \\"quick\\"\\n\\\nbrown fox\\n\\\njumps over\\n\\\nthe \\\'lazy\\\' dog.\\n\\\n\''
+102,1-102,2:	OP	';'
+102,2-102,3:	NEWLINE	'\n'
+103,0-103,1:	NAME	'x'
+103,2-103,3:	OP	'='
+103,4-103,9:	STRING	"r'\\\\'"
+103,10-103,11:	OP	'+'
+103,12-103,17:	STRING	"R'\\\\'"
+103,17-103,18:	NEWLINE	'\n'
+104,0-104,1:	NAME	'x'
+104,2-104,3:	OP	'='
+104,4-104,9:	STRING	"r'\\''"
+104,10-104,11:	OP	'+'
+104,12-104,14:	STRING	"''"
+104,14-104,15:	NEWLINE	'\n'
+105,0-105,1:	NAME	'y'
+105,2-105,3:	OP	'='
+105,4-107,6:	STRING	"r'''\nfoo bar \\\\\nbaz'''"
+107,7-107,8:	OP	'+'
+107,9-108,6:	STRING	"R'''\nfoo'''"
+108,6-108,7:	NEWLINE	'\n'
+109,0-109,1:	NAME	'y'
+109,2-109,3:	OP	'='
+109,4-111,3:	STRING	'r"""foo\nbar \\\\ baz\n"""'
+111,4-111,5:	OP	'+'
+111,6-112,3:	STRING	"R'''spam\n'''"
+112,3-112,4:	NEWLINE	'\n'
+113,0-113,1:	NAME	'x'
+113,2-113,3:	OP	'='
+113,4-113,10:	STRING	"u'abc'"
+113,11-113,12:	OP	'+'
+113,13-113,19:	STRING	"U'ABC'"
+113,19-113,20:	NEWLINE	'\n'
+114,0-114,1:	NAME	'y'
+114,2-114,3:	OP	'='
+114,4-114,10:	STRING	'u"abc"'
+114,11-114,12:	OP	'+'
+114,13-114,19:	STRING	'U"ABC"'
+114,19-114,20:	NEWLINE	'\n'
+115,0-115,1:	NAME	'x'
+115,2-115,3:	OP	'='
+115,4-115,11:	STRING	"ur'abc'"
+115,12-115,13:	OP	'+'
+115,14-115,21:	STRING	"Ur'ABC'"
+115,22-115,23:	OP	'+'
+115,24-115,31:	STRING	"uR'ABC'"
+115,32-115,33:	OP	'+'
+115,34-115,41:	STRING	"UR'ABC'"
+115,41-115,42:	NEWLINE	'\n'
+116,0-116,1:	NAME	'y'
+116,2-116,3:	OP	'='
+116,4-116,11:	STRING	'ur"abc"'
+116,12-116,13:	OP	'+'
+116,14-116,21:	STRING	'Ur"ABC"'
+116,22-116,23:	OP	'+'
+116,24-116,31:	STRING	'uR"ABC"'
+116,32-116,33:	OP	'+'
+116,34-116,41:	STRING	'UR"ABC"'
+116,41-116,42:	NEWLINE	'\n'
+117,0-117,1:	NAME	'x'
+117,2-117,3:	OP	'='
+117,4-117,10:	STRING	"ur'\\\\'"
+117,11-117,12:	OP	'+'
+117,13-117,19:	STRING	"UR'\\\\'"
+117,19-117,20:	NEWLINE	'\n'
+118,0-118,1:	NAME	'x'
+118,2-118,3:	OP	'='
+118,4-118,10:	STRING	"ur'\\''"
+118,11-118,12:	OP	'+'
+118,13-118,15:	STRING	"''"
+118,15-118,16:	NEWLINE	'\n'
+119,0-119,1:	NAME	'y'
+119,2-119,3:	OP	'='
+119,4-121,6:	STRING	"ur'''\nfoo bar \\\\\nbaz'''"
+121,7-121,8:	OP	'+'
+121,9-122,6:	STRING	"UR'''\nfoo'''"
+122,6-122,7:	NEWLINE	'\n'
+123,0-123,1:	NAME	'y'
+123,2-123,3:	OP	'='
+123,4-125,3:	STRING	'Ur"""foo\nbar \\\\ baz\n"""'
+125,4-125,5:	OP	'+'
+125,6-126,3:	STRING	"uR'''spam\n'''"
+126,3-126,4:	NEWLINE	'\n'
+127,0-127,1:	NL	'\n'
+128,0-128,14:	COMMENT	'# Indentation\n'
+129,0-129,2:	NAME	'if'
+129,3-129,4:	NUMBER	'1'
+129,4-129,5:	OP	':'
+129,5-129,6:	NEWLINE	'\n'
+130,0-130,4:	INDENT	'    '
+130,4-130,5:	NAME	'x'
+130,6-130,7:	OP	'='
+130,8-130,9:	NUMBER	'2'
+130,9-130,10:	NEWLINE	'\n'
+131,0-131,0:	DEDENT	''
+131,0-131,2:	NAME	'if'
+131,3-131,4:	NUMBER	'1'
+131,4-131,5:	OP	':'
+131,5-131,6:	NEWLINE	'\n'
+132,0-132,8:	INDENT	'        '
+132,8-132,9:	NAME	'x'
+132,10-132,11:	OP	'='
+132,12-132,13:	NUMBER	'2'
+132,13-132,14:	NEWLINE	'\n'
+133,0-133,0:	DEDENT	''
+133,0-133,2:	NAME	'if'
+133,3-133,4:	NUMBER	'1'
+133,4-133,5:	OP	':'
+133,5-133,6:	NEWLINE	'\n'
+134,0-134,4:	INDENT	'    '
+134,4-134,9:	NAME	'while'
+134,10-134,11:	NUMBER	'0'
+134,11-134,12:	OP	':'
+134,12-134,13:	NEWLINE	'\n'
+135,0-135,5:	INDENT	'     '
+135,5-135,7:	NAME	'if'
+135,8-135,9:	NUMBER	'0'
+135,9-135,10:	OP	':'
+135,10-135,11:	NEWLINE	'\n'
+136,0-136,11:	INDENT	'           '
+136,11-136,12:	NAME	'x'
+136,13-136,14:	OP	'='
+136,15-136,16:	NUMBER	'2'
+136,16-136,17:	NEWLINE	'\n'
+137,5-137,5:	DEDENT	''
+137,5-137,6:	NAME	'x'
+137,7-137,8:	OP	'='
+137,9-137,10:	NUMBER	'2'
+137,10-137,11:	NEWLINE	'\n'
+138,0-138,0:	DEDENT	''
+138,0-138,0:	DEDENT	''
+138,0-138,2:	NAME	'if'
+138,3-138,4:	NUMBER	'0'
+138,4-138,5:	OP	':'
+138,5-138,6:	NEWLINE	'\n'
+139,0-139,2:	INDENT	'  '
+139,2-139,4:	NAME	'if'
+139,5-139,6:	NUMBER	'2'
+139,6-139,7:	OP	':'
+139,7-139,8:	NEWLINE	'\n'
+140,0-140,3:	INDENT	'   '
+140,3-140,8:	NAME	'while'
+140,9-140,10:	NUMBER	'0'
+140,10-140,11:	OP	':'
+140,11-140,12:	NEWLINE	'\n'
+141,0-141,8:	INDENT	'        '
+141,8-141,10:	NAME	'if'
+141,11-141,12:	NUMBER	'1'
+141,12-141,13:	OP	':'
+141,13-141,14:	NEWLINE	'\n'
+142,0-142,10:	INDENT	'          '
+142,10-142,11:	NAME	'x'
+142,12-142,13:	OP	'='
+142,14-142,15:	NUMBER	'2'
+142,15-142,16:	NEWLINE	'\n'
+143,0-143,1:	NL	'\n'
+144,0-144,12:	COMMENT	'# Operators\n'
+145,0-145,1:	NL	'\n'
+146,0-146,0:	DEDENT	''
+146,0-146,0:	DEDENT	''
+146,0-146,0:	DEDENT	''
+146,0-146,0:	DEDENT	''
+146,0-146,3:	NAME	'def'
+146,4-146,7:	NAME	'd22'
+146,7-146,8:	OP	'('
+146,8-146,9:	NAME	'a'
+146,9-146,10:	OP	','
+146,11-146,12:	NAME	'b'
+146,12-146,13:	OP	','
+146,14-146,15:	NAME	'c'
+146,15-146,16:	OP	'='
+146,16-146,17:	NUMBER	'1'
+146,17-146,18:	OP	','
+146,19-146,20:	NAME	'd'
+146,20-146,21:	OP	'='
+146,21-146,22:	NUMBER	'2'
+146,22-146,23:	OP	')'
+146,23-146,24:	OP	':'
+146,25-146,29:	NAME	'pass'
+146,29-146,30:	NEWLINE	'\n'
+147,0-147,3:	NAME	'def'
+147,4-147,8:	NAME	'd01v'
+147,8-147,9:	OP	'('
+147,9-147,10:	NAME	'a'
+147,10-147,11:	OP	'='
+147,11-147,12:	NUMBER	'1'
+147,12-147,13:	OP	','
+147,14-147,15:	OP	'*'
+147,15-147,20:	NAME	'restt'
+147,20-147,21:	OP	','
+147,22-147,24:	OP	'**'
+147,24-147,29:	NAME	'restd'
+147,29-147,30:	OP	')'
+147,30-147,31:	OP	':'
+147,32-147,36:	NAME	'pass'
+147,36-147,37:	NEWLINE	'\n'
+148,0-148,1:	NL	'\n'
+149,0-149,1:	OP	'('
+149,1-149,2:	NAME	'x'
+149,2-149,3:	OP	','
+149,4-149,5:	NAME	'y'
+149,5-149,6:	OP	')'
+149,7-149,9:	OP	'<>'
+149,10-149,11:	OP	'('
+149,11-149,12:	OP	'{'
+149,12-149,15:	STRING	"'a'"
+149,15-149,16:	OP	':'
+149,16-149,17:	NUMBER	'1'
+149,17-149,18:	OP	'}'
+149,18-149,19:	OP	','
+149,20-149,21:	OP	'{'
+149,21-149,24:	STRING	"'b'"
+149,24-149,25:	OP	':'
+149,25-149,26:	NUMBER	'2'
+149,26-149,27:	OP	'}'
+149,27-149,28:	OP	')'
+149,28-149,29:	NEWLINE	'\n'
+150,0-150,1:	NL	'\n'
+151,0-151,13:	COMMENT	'# comparison\n'
+152,0-152,2:	NAME	'if'
+152,3-152,4:	NUMBER	'1'
+152,5-152,6:	OP	'<'
+152,7-152,8:	NUMBER	'1'
+152,9-152,10:	OP	'>'
+152,11-152,12:	NUMBER	'1'
+152,13-152,15:	OP	'=='
+152,16-152,17:	NUMBER	'1'
+152,18-152,20:	OP	'>='
+152,21-152,22:	NUMBER	'1'
+152,23-152,25:	OP	'<='
+152,26-152,27:	NUMBER	'1'
+152,28-152,30:	OP	'<>'
+152,31-152,32:	NUMBER	'1'
+152,33-152,35:	OP	'!='
+152,36-152,37:	NUMBER	'1'
+152,38-152,40:	NAME	'in'
+152,41-152,42:	NUMBER	'1'
+152,43-152,46:	NAME	'not'
+152,47-152,49:	NAME	'in'
+152,50-152,51:	NUMBER	'1'
+152,52-152,54:	NAME	'is'
+152,55-152,56:	NUMBER	'1'
+152,57-152,59:	NAME	'is'
+152,60-152,63:	NAME	'not'
+152,64-152,65:	NUMBER	'1'
+152,65-152,66:	OP	':'
+152,67-152,71:	NAME	'pass'
+152,71-152,72:	NEWLINE	'\n'
+153,0-153,1:	NL	'\n'
+154,0-154,9:	COMMENT	'# binary\n'
+155,0-155,1:	NAME	'x'
+155,2-155,3:	OP	'='
+155,4-155,5:	NUMBER	'1'
+155,6-155,7:	OP	'&'
+155,8-155,9:	NUMBER	'1'
+155,9-155,10:	NEWLINE	'\n'
+156,0-156,1:	NAME	'x'
+156,2-156,3:	OP	'='
+156,4-156,5:	NUMBER	'1'
+156,6-156,7:	OP	'^'
+156,8-156,9:	NUMBER	'1'
+156,9-156,10:	NEWLINE	'\n'
+157,0-157,1:	NAME	'x'
+157,2-157,3:	OP	'='
+157,4-157,5:	NUMBER	'1'
+157,6-157,7:	OP	'|'
+157,8-157,9:	NUMBER	'1'
+157,9-157,10:	NEWLINE	'\n'
+158,0-158,1:	NL	'\n'
+159,0-159,8:	COMMENT	'# shift\n'
+160,0-160,1:	NAME	'x'
+160,2-160,3:	OP	'='
+160,4-160,5:	NUMBER	'1'
+160,6-160,8:	OP	'<<'
+160,9-160,10:	NUMBER	'1'
+160,11-160,13:	OP	'>>'
+160,14-160,15:	NUMBER	'1'
+160,15-160,16:	NEWLINE	'\n'
+161,0-161,1:	NL	'\n'
+162,0-162,11:	COMMENT	'# additive\n'
+163,0-163,1:	NAME	'x'
+163,2-163,3:	OP	'='
+163,4-163,5:	NUMBER	'1'
+163,6-163,7:	OP	'-'
+163,8-163,9:	NUMBER	'1'
+163,10-163,11:	OP	'+'
+163,12-163,13:	NUMBER	'1'
+163,14-163,15:	OP	'-'
+163,16-163,17:	NUMBER	'1'
+163,18-163,19:	OP	'+'
+163,20-163,21:	NUMBER	'1'
+163,21-163,22:	NEWLINE	'\n'
+164,0-164,1:	NL	'\n'
+165,0-165,17:	COMMENT	'# multiplicative\n'
+166,0-166,1:	NAME	'x'
+166,2-166,3:	OP	'='
+166,4-166,5:	NUMBER	'1'
+166,6-166,7:	OP	'/'
+166,8-166,9:	NUMBER	'1'
+166,10-166,11:	OP	'*'
+166,12-166,13:	NUMBER	'1'
+166,14-166,15:	OP	'%'
+166,16-166,17:	NUMBER	'1'
+166,17-166,18:	NEWLINE	'\n'
+167,0-167,1:	NL	'\n'
+168,0-168,8:	COMMENT	'# unary\n'
+169,0-169,1:	NAME	'x'
+169,2-169,3:	OP	'='
+169,4-169,5:	OP	'~'
+169,5-169,6:	NUMBER	'1'
+169,7-169,8:	OP	'^'
+169,9-169,10:	NUMBER	'1'
+169,11-169,12:	OP	'&'
+169,13-169,14:	NUMBER	'1'
+169,15-169,16:	OP	'|'
+169,17-169,18:	NUMBER	'1'
+169,19-169,20:	OP	'&'
+169,21-169,22:	NUMBER	'1'
+169,23-169,24:	OP	'^'
+169,25-169,26:	OP	'-'
+169,26-169,27:	NUMBER	'1'
+169,27-169,28:	NEWLINE	'\n'
+170,0-170,1:	NAME	'x'
+170,2-170,3:	OP	'='
+170,4-170,5:	OP	'-'
+170,5-170,6:	NUMBER	'1'
+170,6-170,7:	OP	'*'
+170,7-170,8:	NUMBER	'1'
+170,8-170,9:	OP	'/'
+170,9-170,10:	NUMBER	'1'
+170,11-170,12:	OP	'+'
+170,13-170,14:	NUMBER	'1'
+170,14-170,15:	OP	'*'
+170,15-170,16:	NUMBER	'1'
+170,17-170,18:	OP	'-'
+170,19-170,20:	OP	'-'
+170,20-170,21:	OP	'-'
+170,21-170,22:	OP	'-'
+170,22-170,23:	NUMBER	'1'
+170,23-170,24:	OP	'*'
+170,24-170,25:	NUMBER	'1'
+170,25-170,26:	NEWLINE	'\n'
+171,0-171,1:	NL	'\n'
+172,0-172,11:	COMMENT	'# selector\n'
+173,0-173,6:	NAME	'import'
+173,7-173,10:	NAME	'sys'
+173,10-173,11:	OP	','
+173,12-173,16:	NAME	'time'
+173,16-173,17:	NEWLINE	'\n'
+174,0-174,1:	NAME	'x'
+174,2-174,3:	OP	'='
+174,4-174,7:	NAME	'sys'
+174,7-174,8:	OP	'.'
+174,8-174,15:	NAME	'modules'
+174,15-174,16:	OP	'['
+174,16-174,22:	STRING	"'time'"
+174,22-174,23:	OP	']'
+174,23-174,24:	OP	'.'
+174,24-174,28:	NAME	'time'
+174,28-174,29:	OP	'('
+174,29-174,30:	OP	')'
+174,30-174,31:	NEWLINE	'\n'
+175,0-175,1:	NL	'\n'
+176,0-176,1:	OP	'@'
+176,1-176,13:	NAME	'staticmethod'
+176,13-176,14:	NEWLINE	'\n'
+177,0-177,3:	NAME	'def'
+177,4-177,7:	NAME	'foo'
+177,7-177,8:	OP	'('
+177,8-177,9:	OP	')'
+177,9-177,10:	OP	':'
+177,11-177,15:	NAME	'pass'
+177,15-177,16:	NEWLINE	'\n'
+178,0-178,1:	NL	'\n'
+179,0-179,0:	ENDMARKER	''

Added: vendor/Python/current/Lib/test/output/test_types
===================================================================
--- vendor/Python/current/Lib/test/output/test_types	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/output/test_types	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,15 @@
+test_types
+6. Built-in types
+6.1 Truth value testing
+6.2 Boolean operations
+6.3 Comparisons
+6.4 Numeric types (mostly conversions)
+6.4.1 32-bit integers
+6.4.2 Long integers
+6.4.3 Floating point numbers
+6.5 Sequence types
+6.5.1 Strings
+6.5.2 Tuples [see test_tuple.py]
+6.5.3 Lists [see test_list.py]
+6.6 Mappings == Dictionaries [see test_dict.py]
+Buffers

Added: vendor/Python/current/Lib/test/output/test_winreg
===================================================================
--- vendor/Python/current/Lib/test/output/test_winreg	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/output/test_winreg	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,3 @@
+test_winreg
+Local registry tests worked
+Remote registry calls can be tested using 'test_winreg.py --remote \\machine_name'

Added: vendor/Python/current/Lib/test/output/test_xdrlib
===================================================================
--- vendor/Python/current/Lib/test/output/test_xdrlib	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/output/test_xdrlib	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,19 @@
+test_xdrlib
+pack test 0 succeeded
+pack test 1 succeeded
+pack test 2 succeeded
+pack test 3 succeeded
+pack test 4 succeeded
+pack test 5 succeeded
+pack test 6 succeeded
+pack test 7 succeeded
+pack test 8 succeeded
+unpack test 0 succeeded : 9
+unpack test 1 succeeded : True
+unpack test 2 succeeded : False
+unpack test 3 succeeded : 45
+unpack test 4 succeeded : 1.89999997616
+unpack test 5 succeeded : 1.9
+unpack test 6 succeeded : hello world
+unpack test 7 succeeded : [0, 1, 2, 3, 4]
+unpack test 8 succeeded : ['what', 'is', 'hapnin', 'doctor']

Added: vendor/Python/current/Lib/test/output/xmltests
===================================================================
--- vendor/Python/current/Lib/test/output/xmltests	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/output/xmltests	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,364 @@
+xmltests
+Passed testAAA
+Passed setAttribute() sets ownerDocument
+Passed setAttribute() sets ownerElement
+Test Succeeded testAAA
+Passed assertion: len(Node.allnodes) == 0
+Passed testAAB
+Test Succeeded testAAB
+Passed assertion: len(Node.allnodes) == 0
+Passed Test
+Passed Test
+Passed Test
+Passed Test
+Passed Test
+Passed Test
+Passed Test
+Passed Test
+Test Succeeded testAddAttr
+Passed assertion: len(Node.allnodes) == 0
+Passed Test
+Passed Test
+Test Succeeded testAppendChild
+Passed assertion: len(Node.allnodes) == 0
+Passed appendChild(<fragment>)
+Test Succeeded testAppendChildFragment
+Passed assertion: len(Node.allnodes) == 0
+Test Succeeded testAttrListItem
+Passed assertion: len(Node.allnodes) == 0
+Test Succeeded testAttrListItemNS
+Passed assertion: len(Node.allnodes) == 0
+Test Succeeded testAttrListItems
+Passed assertion: len(Node.allnodes) == 0
+Test Succeeded testAttrListKeys
+Passed assertion: len(Node.allnodes) == 0
+Test Succeeded testAttrListKeysNS
+Passed assertion: len(Node.allnodes) == 0
+Test Succeeded testAttrListLength
+Passed assertion: len(Node.allnodes) == 0
+Test Succeeded testAttrListValues
+Passed assertion: len(Node.allnodes) == 0
+Test Succeeded testAttrList__getitem__
+Passed assertion: len(Node.allnodes) == 0
+Test Succeeded testAttrList__setitem__
+Passed assertion: len(Node.allnodes) == 0
+Passed Test
+Passed Test
+Test Succeeded testAttributeRepr
+Passed assertion: len(Node.allnodes) == 0
+Passed Test
+Passed Test
+Passed Test
+Passed Test
+Passed Test
+Test Succeeded testChangeAttr
+Passed assertion: len(Node.allnodes) == 0
+Test Succeeded testChildNodes
+Passed assertion: len(Node.allnodes) == 0
+Test Succeeded testCloneAttributeDeep
+Passed assertion: len(Node.allnodes) == 0
+Test Succeeded testCloneAttributeShallow
+Passed assertion: len(Node.allnodes) == 0
+Test Succeeded testCloneDocumentDeep
+Passed assertion: len(Node.allnodes) == 0
+Test Succeeded testCloneDocumentShallow
+Passed assertion: len(Node.allnodes) == 0
+Passed clone of element has same attribute keys
+Passed clone of attribute node has proper attribute values
+Passed clone of attribute node correctly owned
+Passed testCloneElementDeep
+Test Succeeded testCloneElementDeep
+Passed assertion: len(Node.allnodes) == 0
+Passed clone of element has same attribute keys
+Passed clone of attribute node has proper attribute values
+Passed clone of attribute node correctly owned
+Passed testCloneElementShallow
+Test Succeeded testCloneElementShallow
+Passed assertion: len(Node.allnodes) == 0
+Test Succeeded testClonePIDeep
+Passed assertion: len(Node.allnodes) == 0
+Test Succeeded testClonePIShallow
+Passed assertion: len(Node.allnodes) == 0
+Test Succeeded testComment
+Passed assertion: len(Node.allnodes) == 0
+Test Succeeded testCreateAttributeNS
+Passed assertion: len(Node.allnodes) == 0
+Test Succeeded testCreateElementNS
+Passed assertion: len(Node.allnodes) == 0
+Passed Test
+Passed Test
+Passed Test
+Test Succeeded testDeleteAttr
+Passed assertion: len(Node.allnodes) == 0
+Test Succeeded testDocumentElement
+Passed assertion: len(Node.allnodes) == 0
+Passed Test
+Test Succeeded testElement
+Passed assertion: len(Node.allnodes) == 0
+Passed Test
+Test Succeeded testElementReprAndStr
+Passed assertion: len(Node.allnodes) == 0
+Test Succeeded testFirstChild
+Passed assertion: len(Node.allnodes) == 0
+Test Succeeded testGetAttrLength
+Passed assertion: len(Node.allnodes) == 0
+Test Succeeded testGetAttrList
+Passed assertion: len(Node.allnodes) == 0
+Test Succeeded testGetAttrValues
+Passed assertion: len(Node.allnodes) == 0
+Test Succeeded testGetAttribute
+Passed assertion: len(Node.allnodes) == 0
+Test Succeeded testGetAttributeNS
+Passed assertion: len(Node.allnodes) == 0
+Test Succeeded testGetAttributeNode
+Passed assertion: len(Node.allnodes) == 0
+Passed Test
+Test Succeeded testGetElementsByTagName
+Passed assertion: len(Node.allnodes) == 0
+Passed Test
+Test Succeeded testGetElementsByTagNameNS
+Passed assertion: len(Node.allnodes) == 0
+Test Succeeded testGetEmptyNodeListFromElementsByTagNameNS
+Passed assertion: len(Node.allnodes) == 0
+Test Succeeded testHasChildNodes
+Passed assertion: len(Node.allnodes) == 0
+Passed testInsertBefore -- node properly placed in tree
+Passed testInsertBefore -- node properly placed in tree
+Passed testInsertBefore -- node properly placed in tree
+Test Succeeded testInsertBefore
+Passed assertion: len(Node.allnodes) == 0
+Passed insertBefore(<fragment>, None)
+Passed insertBefore(<fragment>, orig)
+Test Succeeded testInsertBeforeFragment
+Passed assertion: len(Node.allnodes) == 0
+Test Succeeded testLegalChildren
+Passed assertion: len(Node.allnodes) == 0
+Passed NamedNodeMap.__setitem__() sets ownerDocument
+Passed NamedNodeMap.__setitem__() sets ownerElement
+Passed NamedNodeMap.__setitem__() sets value
+Passed NamedNodeMap.__setitem__() sets nodeValue
+Test Succeeded testNamedNodeMapSetItem
+Passed assertion: len(Node.allnodes) == 0
+Passed test NodeList.item()
+Test Succeeded testNodeListItem
+Passed assertion: len(Node.allnodes) == 0
+Passed Test
+Passed Test
+Test Succeeded testNonZero
+Passed assertion: len(Node.allnodes) == 0
+Passed testNormalize -- preparation
+Passed testNormalize -- result
+Passed testNormalize -- single empty node removed
+Test Succeeded testNormalize
+Passed assertion: len(Node.allnodes) == 0
+Passed testParents
+Test Succeeded testParents
+Passed assertion: len(Node.allnodes) == 0
+Test Succeeded testParse
+Passed assertion: len(Node.allnodes) == 0
+Test Succeeded testParseAttributeNamespaces
+Passed assertion: len(Node.allnodes) == 0
+Test Succeeded testParseAttributes
+Passed assertion: len(Node.allnodes) == 0
+Test Succeeded testParseElement
+Passed assertion: len(Node.allnodes) == 0
+Test Succeeded testParseElementNamespaces
+Passed assertion: len(Node.allnodes) == 0
+Passed Test
+Test Succeeded testParseFromFile
+Passed assertion: len(Node.allnodes) == 0
+Test Succeeded testParseProcessingInstructions
+Passed assertion: len(Node.allnodes) == 0
+Test Succeeded testParseString
+Passed assertion: len(Node.allnodes) == 0
+Test Succeeded testProcessingInstruction
+Passed assertion: len(Node.allnodes) == 0
+Test Succeeded testProcessingInstructionRepr
+Passed assertion: len(Node.allnodes) == 0
+Passed Test
+Passed Test
+Test Succeeded testRemoveAttr
+Passed assertion: len(Node.allnodes) == 0
+Passed Test
+Passed Test
+Test Succeeded testRemoveAttrNS
+Passed assertion: len(Node.allnodes) == 0
+Passed Test
+Passed Test
+Test Succeeded testRemoveAttributeNode
+Passed assertion: len(Node.allnodes) == 0
+Passed replaceChild(<fragment>)
+Test Succeeded testReplaceChildFragment
+Passed assertion: len(Node.allnodes) == 0
+Passed testSAX2DOM - siblings
+Passed testSAX2DOM - parents
+Test Succeeded testSAX2DOM
+Passed assertion: len(Node.allnodes) == 0
+Test Succeeded testSetAttrValueandNodeValue
+Passed assertion: len(Node.allnodes) == 0
+Passed testSiblings
+Test Succeeded testSiblings
+Passed assertion: len(Node.allnodes) == 0
+Test Succeeded testTextNodeRepr
+Passed assertion: len(Node.allnodes) == 0
+Test Succeeded testTextRepr
+Passed assertion: len(Node.allnodes) == 0
+Caught expected exception when adding extra document element.
+Test Succeeded testTooManyDocumentElements
+Passed assertion: len(Node.allnodes) == 0
+Test Succeeded testUnlink
+Passed assertion: len(Node.allnodes) == 0
+Test Succeeded testWriteText
+Passed assertion: len(Node.allnodes) == 0
+Passed Test
+Passed Test
+Test Succeeded testWriteXML
+Passed assertion: len(Node.allnodes) == 0
+All tests succeeded
+OK.
+OK.
+OK.
+OK.
+OK.
+OK.
+OK.
+OK.
+OK.
+OK.
+OK.
+OK.
+PI:
+	'xml-stylesheet' 'href="stylesheet.css"'
+Comment:
+	' comment data '
+Notation declared: ('notation', None, 'notation.jpeg', None)
+Unparsed entity decl:
+	('unparsed_entity', None, 'entity.file', None, 'notation')
+Start element:
+	'root' {'attr1': 'value1', 'attr2': 'value2\xe1\xbd\x80'}
+NS decl:
+	'myns' 'http://www.python.org/namespace'
+Start element:
+	'http://www.python.org/namespace!subelement' {}
+Character data:
+	'Contents of subelements'
+End element:
+	'http://www.python.org/namespace!subelement'
+End of NS decl:
+	'myns'
+Start element:
+	'sub2' {}
+Start of CDATA section
+Character data:
+	'contents of CDATA section'
+End of CDATA section
+End element:
+	'sub2'
+External entity ref: (None, 'entity.file', None)
+End element:
+	'root'
+PI:
+	u'xml-stylesheet' u'href="stylesheet.css"'
+Comment:
+	u' comment data '
+Notation declared: (u'notation', None, u'notation.jpeg', None)
+Unparsed entity decl:
+	(u'unparsed_entity', None, u'entity.file', None, u'notation')
+Start element:
+	u'root' {u'attr1': u'value1', u'attr2': u'value2\u1f40'}
+NS decl:
+	u'myns' u'http://www.python.org/namespace'
+Start element:
+	u'http://www.python.org/namespace!subelement' {}
+Character data:
+	u'Contents of subelements'
+End element:
+	u'http://www.python.org/namespace!subelement'
+End of NS decl:
+	u'myns'
+Start element:
+	u'sub2' {}
+Start of CDATA section
+Character data:
+	u'contents of CDATA section'
+End of CDATA section
+End element:
+	u'sub2'
+External entity ref: (None, u'entity.file', None)
+End element:
+	u'root'
+PI:
+	u'xml-stylesheet' u'href="stylesheet.css"'
+Comment:
+	u' comment data '
+Notation declared: (u'notation', None, u'notation.jpeg', None)
+Unparsed entity decl:
+	(u'unparsed_entity', None, u'entity.file', None, u'notation')
+Start element:
+	u'root' {u'attr1': u'value1', u'attr2': u'value2\u1f40'}
+NS decl:
+	u'myns' u'http://www.python.org/namespace'
+Start element:
+	u'http://www.python.org/namespace!subelement' {}
+Character data:
+	u'Contents of subelements'
+End element:
+	u'http://www.python.org/namespace!subelement'
+End of NS decl:
+	u'myns'
+Start element:
+	u'sub2' {}
+Start of CDATA section
+Character data:
+	u'contents of CDATA section'
+End of CDATA section
+End element:
+	u'sub2'
+External entity ref: (None, u'entity.file', None)
+End element:
+	u'root'
+
+Testing constructor for proper handling of namespace_separator values:
+Legal values tested o.k.
+Caught expected TypeError:
+ParserCreate() argument 2 must be string or None, not int
+Caught expected ValueError:
+namespace_separator must be at most one character, omitted, or None
+Passed test_attrs_empty
+Passed test_attrs_wattr
+Passed test_double_quoteattr
+Passed test_escape_all
+Passed test_escape_basic
+Passed test_escape_extra
+Passed test_expat_attrs_empty
+Passed test_expat_attrs_wattr
+Passed test_expat_dtdhandler
+Passed test_expat_entityresolver
+Passed test_expat_file
+Passed test_expat_incomplete
+Passed test_expat_incremental
+Passed test_expat_incremental_reset
+Passed test_expat_inpsource_filename
+Passed test_expat_inpsource_location
+Passed test_expat_inpsource_stream
+Passed test_expat_inpsource_sysid
+Passed test_expat_locator_noinfo
+Passed test_expat_locator_withinfo
+Passed test_expat_nsattrs_empty
+Passed test_expat_nsattrs_wattr
+Passed test_filter_basic
+Passed test_make_parser
+Passed test_make_parser2
+Passed test_nsattrs_empty
+Passed test_nsattrs_wattr
+Passed test_quoteattr_basic
+Passed test_single_double_quoteattr
+Passed test_single_quoteattr
+Passed test_xmlgen_attr_escape
+Passed test_xmlgen_basic
+Passed test_xmlgen_content
+Passed test_xmlgen_content_escape
+Passed test_xmlgen_ignorable
+Passed test_xmlgen_ns
+Passed test_xmlgen_pi
+37 tests, 0 failures

Added: vendor/Python/current/Lib/test/outstanding_bugs.py
===================================================================
--- vendor/Python/current/Lib/test/outstanding_bugs.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/outstanding_bugs.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,27 @@
+#
+# This file is for everybody to add tests for bugs that aren't
+# fixed yet. Please add a test case and appropriate bug description.
+#
+# When you fix one of the bugs, please move the test to the correct
+# test_ module.
+#
+
+import unittest
+from test import test_support
+
+class TestBug1385040(unittest.TestCase):
+    def testSyntaxError(self):
+        import compiler
+
+        # The following snippet gives a SyntaxError in the interpreter
+        #
+        # If you compile and exec it, the call foo(7) returns (7, 1)
+        self.assertRaises(SyntaxError, compiler.compile,
+                          "def foo(a=1, b): return a, b\n\n", "<string>", "exec")
+
+
+def test_main():
+    test_support.run_unittest(TestBug1385040)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/pickletester.py
===================================================================
--- vendor/Python/current/Lib/test/pickletester.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/pickletester.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1001 @@
+import unittest
+import pickle
+import cPickle
+import pickletools
+import copy_reg
+
+from test.test_support import TestFailed, have_unicode, TESTFN, \
+                              run_with_locale
+
+# Tests that try a number of pickle protocols should have a
+#     for proto in protocols:
+# kind of outer loop.
+assert pickle.HIGHEST_PROTOCOL == cPickle.HIGHEST_PROTOCOL == 2
+protocols = range(pickle.HIGHEST_PROTOCOL + 1)
+
+
+# Return True if opcode code appears in the pickle, else False.
+def opcode_in_pickle(code, pickle):
+    for op, dummy, dummy in pickletools.genops(pickle):
+        if op.code == code:
+            return True
+    return False
+
+# Return the number of times opcode code appears in pickle.
+def count_opcode(code, pickle):
+    n = 0
+    for op, dummy, dummy in pickletools.genops(pickle):
+        if op.code == code:
+            n += 1
+    return n
+
+# We can't very well test the extension registry without putting known stuff
+# in it, but we have to be careful to restore its original state.  Code
+# should do this:
+#
+#     e = ExtensionSaver(extension_code)
+#     try:
+#         fiddle w/ the extension registry's stuff for extension_code
+#     finally:
+#         e.restore()
+
+class ExtensionSaver:
+    # Remember current registration for code (if any), and remove it (if
+    # there is one).
+    def __init__(self, code):
+        self.code = code
+        if code in copy_reg._inverted_registry:
+            self.pair = copy_reg._inverted_registry[code]
+            copy_reg.remove_extension(self.pair[0], self.pair[1], code)
+        else:
+            self.pair = None
+
+    # Restore previous registration for code.
+    def restore(self):
+        code = self.code
+        curpair = copy_reg._inverted_registry.get(code)
+        if curpair is not None:
+            copy_reg.remove_extension(curpair[0], curpair[1], code)
+        pair = self.pair
+        if pair is not None:
+            copy_reg.add_extension(pair[0], pair[1], code)
+
+class C:
+    def __cmp__(self, other):
+        return cmp(self.__dict__, other.__dict__)
+
+import __main__
+__main__.C = C
+C.__module__ = "__main__"
+
+class myint(int):
+    def __init__(self, x):
+        self.str = str(x)
+
+class initarg(C):
+
+    def __init__(self, a, b):
+        self.a = a
+        self.b = b
+
+    def __getinitargs__(self):
+        return self.a, self.b
+
+class metaclass(type):
+    pass
+
+class use_metaclass(object):
+    __metaclass__ = metaclass
+
+# DATA0 .. DATA2 are the pickles we expect under the various protocols, for
+# the object returned by create_data().
+
+# break into multiple strings to avoid confusing font-lock-mode
+DATA0 = """(lp1
+I0
+aL1L
+aF2
+ac__builtin__
+complex
+p2
+""" + \
+"""(F3
+F0
+tRp3
+aI1
+aI-1
+aI255
+aI-255
+aI-256
+aI65535
+aI-65535
+aI-65536
+aI2147483647
+aI-2147483647
+aI-2147483648
+a""" + \
+"""(S'abc'
+p4
+g4
+""" + \
+"""(i__main__
+C
+p5
+""" + \
+"""(dp6
+S'foo'
+p7
+I1
+sS'bar'
+p8
+I2
+sbg5
+tp9
+ag9
+aI5
+a.
+"""
+
+# Disassembly of DATA0.
+DATA0_DIS = """\
+    0: (    MARK
+    1: l        LIST       (MARK at 0)
+    2: p    PUT        1
+    5: I    INT        0
+    8: a    APPEND
+    9: L    LONG       1L
+   13: a    APPEND
+   14: F    FLOAT      2.0
+   17: a    APPEND
+   18: c    GLOBAL     '__builtin__ complex'
+   39: p    PUT        2
+   42: (    MARK
+   43: F        FLOAT      3.0
+   46: F        FLOAT      0.0
+   49: t        TUPLE      (MARK at 42)
+   50: R    REDUCE
+   51: p    PUT        3
+   54: a    APPEND
+   55: I    INT        1
+   58: a    APPEND
+   59: I    INT        -1
+   63: a    APPEND
+   64: I    INT        255
+   69: a    APPEND
+   70: I    INT        -255
+   76: a    APPEND
+   77: I    INT        -256
+   83: a    APPEND
+   84: I    INT        65535
+   91: a    APPEND
+   92: I    INT        -65535
+  100: a    APPEND
+  101: I    INT        -65536
+  109: a    APPEND
+  110: I    INT        2147483647
+  122: a    APPEND
+  123: I    INT        -2147483647
+  136: a    APPEND
+  137: I    INT        -2147483648
+  150: a    APPEND
+  151: (    MARK
+  152: S        STRING     'abc'
+  159: p        PUT        4
+  162: g        GET        4
+  165: (        MARK
+  166: i            INST       '__main__ C' (MARK at 165)
+  178: p        PUT        5
+  181: (        MARK
+  182: d            DICT       (MARK at 181)
+  183: p        PUT        6
+  186: S        STRING     'foo'
+  193: p        PUT        7
+  196: I        INT        1
+  199: s        SETITEM
+  200: S        STRING     'bar'
+  207: p        PUT        8
+  210: I        INT        2
+  213: s        SETITEM
+  214: b        BUILD
+  215: g        GET        5
+  218: t        TUPLE      (MARK at 151)
+  219: p    PUT        9
+  222: a    APPEND
+  223: g    GET        9
+  226: a    APPEND
+  227: I    INT        5
+  230: a    APPEND
+  231: .    STOP
+highest protocol among opcodes = 0
+"""
+
+DATA1 = (']q\x01(K\x00L1L\nG@\x00\x00\x00\x00\x00\x00\x00'
+         'c__builtin__\ncomplex\nq\x02(G@\x08\x00\x00\x00\x00\x00'
+         '\x00G\x00\x00\x00\x00\x00\x00\x00\x00tRq\x03K\x01J\xff\xff'
+         '\xff\xffK\xffJ\x01\xff\xff\xffJ\x00\xff\xff\xffM\xff\xff'
+         'J\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff\xff\xff\x7fJ\x01\x00'
+         '\x00\x80J\x00\x00\x00\x80(U\x03abcq\x04h\x04(c__main__\n'
+         'C\nq\x05oq\x06}q\x07(U\x03fooq\x08K\x01U\x03barq\tK\x02ubh'
+         '\x06tq\nh\nK\x05e.'
+        )
+
+# Disassembly of DATA1.
+DATA1_DIS = """\
+    0: ]    EMPTY_LIST
+    1: q    BINPUT     1
+    3: (    MARK
+    4: K        BININT1    0
+    6: L        LONG       1L
+   10: G        BINFLOAT   2.0
+   19: c        GLOBAL     '__builtin__ complex'
+   40: q        BINPUT     2
+   42: (        MARK
+   43: G            BINFLOAT   3.0
+   52: G            BINFLOAT   0.0
+   61: t            TUPLE      (MARK at 42)
+   62: R        REDUCE
+   63: q        BINPUT     3
+   65: K        BININT1    1
+   67: J        BININT     -1
+   72: K        BININT1    255
+   74: J        BININT     -255
+   79: J        BININT     -256
+   84: M        BININT2    65535
+   87: J        BININT     -65535
+   92: J        BININT     -65536
+   97: J        BININT     2147483647
+  102: J        BININT     -2147483647
+  107: J        BININT     -2147483648
+  112: (        MARK
+  113: U            SHORT_BINSTRING 'abc'
+  118: q            BINPUT     4
+  120: h            BINGET     4
+  122: (            MARK
+  123: c                GLOBAL     '__main__ C'
+  135: q                BINPUT     5
+  137: o                OBJ        (MARK at 122)
+  138: q            BINPUT     6
+  140: }            EMPTY_DICT
+  141: q            BINPUT     7
+  143: (            MARK
+  144: U                SHORT_BINSTRING 'foo'
+  149: q                BINPUT     8
+  151: K                BININT1    1
+  153: U                SHORT_BINSTRING 'bar'
+  158: q                BINPUT     9
+  160: K                BININT1    2
+  162: u                SETITEMS   (MARK at 143)
+  163: b            BUILD
+  164: h            BINGET     6
+  166: t            TUPLE      (MARK at 112)
+  167: q        BINPUT     10
+  169: h        BINGET     10
+  171: K        BININT1    5
+  173: e        APPENDS    (MARK at 3)
+  174: .    STOP
+highest protocol among opcodes = 1
+"""
+
+DATA2 = ('\x80\x02]q\x01(K\x00\x8a\x01\x01G@\x00\x00\x00\x00\x00\x00\x00'
+         'c__builtin__\ncomplex\nq\x02G@\x08\x00\x00\x00\x00\x00\x00G\x00'
+         '\x00\x00\x00\x00\x00\x00\x00\x86Rq\x03K\x01J\xff\xff\xff\xffK'
+         '\xffJ\x01\xff\xff\xffJ\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xff'
+         'J\x00\x00\xff\xffJ\xff\xff\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00'
+         '\x80(U\x03abcq\x04h\x04(c__main__\nC\nq\x05oq\x06}q\x07(U\x03foo'
+         'q\x08K\x01U\x03barq\tK\x02ubh\x06tq\nh\nK\x05e.')
+
+# Disassembly of DATA2.
+DATA2_DIS = """\
+    0: \x80 PROTO      2
+    2: ]    EMPTY_LIST
+    3: q    BINPUT     1
+    5: (    MARK
+    6: K        BININT1    0
+    8: \x8a     LONG1      1L
+   11: G        BINFLOAT   2.0
+   20: c        GLOBAL     '__builtin__ complex'
+   41: q        BINPUT     2
+   43: G        BINFLOAT   3.0
+   52: G        BINFLOAT   0.0
+   61: \x86     TUPLE2
+   62: R        REDUCE
+   63: q        BINPUT     3
+   65: K        BININT1    1
+   67: J        BININT     -1
+   72: K        BININT1    255
+   74: J        BININT     -255
+   79: J        BININT     -256
+   84: M        BININT2    65535
+   87: J        BININT     -65535
+   92: J        BININT     -65536
+   97: J        BININT     2147483647
+  102: J        BININT     -2147483647
+  107: J        BININT     -2147483648
+  112: (        MARK
+  113: U            SHORT_BINSTRING 'abc'
+  118: q            BINPUT     4
+  120: h            BINGET     4
+  122: (            MARK
+  123: c                GLOBAL     '__main__ C'
+  135: q                BINPUT     5
+  137: o                OBJ        (MARK at 122)
+  138: q            BINPUT     6
+  140: }            EMPTY_DICT
+  141: q            BINPUT     7
+  143: (            MARK
+  144: U                SHORT_BINSTRING 'foo'
+  149: q                BINPUT     8
+  151: K                BININT1    1
+  153: U                SHORT_BINSTRING 'bar'
+  158: q                BINPUT     9
+  160: K                BININT1    2
+  162: u                SETITEMS   (MARK at 143)
+  163: b            BUILD
+  164: h            BINGET     6
+  166: t            TUPLE      (MARK at 112)
+  167: q        BINPUT     10
+  169: h        BINGET     10
+  171: K        BININT1    5
+  173: e        APPENDS    (MARK at 5)
+  174: .    STOP
+highest protocol among opcodes = 2
+"""
+
+def create_data():
+    c = C()
+    c.foo = 1
+    c.bar = 2
+    x = [0, 1L, 2.0, 3.0+0j]
+    # Append some integer test cases at cPickle.c's internal size
+    # cutoffs.
+    uint1max = 0xff
+    uint2max = 0xffff
+    int4max = 0x7fffffff
+    x.extend([1, -1,
+              uint1max, -uint1max, -uint1max-1,
+              uint2max, -uint2max, -uint2max-1,
+               int4max,  -int4max,  -int4max-1])
+    y = ('abc', 'abc', c, c)
+    x.append(y)
+    x.append(y)
+    x.append(5)
+    return x
+
+class AbstractPickleTests(unittest.TestCase):
+    # Subclass must define self.dumps, self.loads, self.error.
+
+    _testdata = create_data()
+
+    def setUp(self):
+        pass
+
+    def test_misc(self):
+        # test various datatypes not tested by testdata
+        for proto in protocols:
+            x = myint(4)
+            s = self.dumps(x, proto)
+            y = self.loads(s)
+            self.assertEqual(x, y)
+
+            x = (1, ())
+            s = self.dumps(x, proto)
+            y = self.loads(s)
+            self.assertEqual(x, y)
+
+            x = initarg(1, x)
+            s = self.dumps(x, proto)
+            y = self.loads(s)
+            self.assertEqual(x, y)
+
+        # XXX test __reduce__ protocol?
+
+    def test_roundtrip_equality(self):
+        expected = self._testdata
+        for proto in protocols:
+            s = self.dumps(expected, proto)
+            got = self.loads(s)
+            self.assertEqual(expected, got)
+
+    def test_load_from_canned_string(self):
+        expected = self._testdata
+        for canned in DATA0, DATA1, DATA2:
+            got = self.loads(canned)
+            self.assertEqual(expected, got)
+
+    # There are gratuitous differences between pickles produced by
+    # pickle and cPickle, largely because cPickle starts PUT indices at
+    # 1 and pickle starts them at 0.  See XXX comment in cPickle's put2() --
+    # there's a comment with an exclamation point there whose meaning
+    # is a mystery.  cPickle also suppresses PUT for objects with a refcount
+    # of 1.
+    def dont_test_disassembly(self):
+        from cStringIO import StringIO
+        from pickletools import dis
+
+        for proto, expected in (0, DATA0_DIS), (1, DATA1_DIS):
+            s = self.dumps(self._testdata, proto)
+            filelike = StringIO()
+            dis(s, out=filelike)
+            got = filelike.getvalue()
+            self.assertEqual(expected, got)
+
+    def test_recursive_list(self):
+        l = []
+        l.append(l)
+        for proto in protocols:
+            s = self.dumps(l, proto)
+            x = self.loads(s)
+            self.assertEqual(len(x), 1)
+            self.assert_(x is x[0])
+
+    def test_recursive_dict(self):
+        d = {}
+        d[1] = d
+        for proto in protocols:
+            s = self.dumps(d, proto)
+            x = self.loads(s)
+            self.assertEqual(x.keys(), [1])
+            self.assert_(x[1] is x)
+
+    def test_recursive_inst(self):
+        i = C()
+        i.attr = i
+        for proto in protocols:
+            s = self.dumps(i, 2)
+            x = self.loads(s)
+            self.assertEqual(dir(x), dir(i))
+            self.assert_(x.attr is x)
+
+    def test_recursive_multi(self):
+        l = []
+        d = {1:l}
+        i = C()
+        i.attr = d
+        l.append(i)
+        for proto in protocols:
+            s = self.dumps(l, proto)
+            x = self.loads(s)
+            self.assertEqual(len(x), 1)
+            self.assertEqual(dir(x[0]), dir(i))
+            self.assertEqual(x[0].attr.keys(), [1])
+            self.assert_(x[0].attr[1] is x)
+
+    def test_garyp(self):
+        self.assertRaises(self.error, self.loads, 'garyp')
+
+    def test_insecure_strings(self):
+        insecure = ["abc", "2 + 2", # not quoted
+                    #"'abc' + 'def'", # not a single quoted string
+                    "'abc", # quote is not closed
+                    "'abc\"", # open quote and close quote don't match
+                    "'abc'   ?", # junk after close quote
+                    "'\\'", # trailing backslash
+                    # some tests of the quoting rules
+                    #"'abc\"\''",
+                    #"'\\\\a\'\'\'\\\'\\\\\''",
+                    ]
+        for s in insecure:
+            buf = "S" + s + "\012p0\012."
+            self.assertRaises(ValueError, self.loads, buf)
+
+    if have_unicode:
+        def test_unicode(self):
+            endcases = [unicode(''), unicode('<\\u>'), unicode('<\\\u1234>'),
+                        unicode('<\n>'),  unicode('<\\>')]
+            for proto in protocols:
+                for u in endcases:
+                    p = self.dumps(u, proto)
+                    u2 = self.loads(p)
+                    self.assertEqual(u2, u)
+
+    def test_ints(self):
+        import sys
+        for proto in protocols:
+            n = sys.maxint
+            while n:
+                for expected in (-n, n):
+                    s = self.dumps(expected, proto)
+                    n2 = self.loads(s)
+                    self.assertEqual(expected, n2)
+                n = n >> 1
+
+    def test_maxint64(self):
+        maxint64 = (1L << 63) - 1
+        data = 'I' + str(maxint64) + '\n.'
+        got = self.loads(data)
+        self.assertEqual(got, maxint64)
+
+        # Try too with a bogus literal.
+        data = 'I' + str(maxint64) + 'JUNK\n.'
+        self.assertRaises(ValueError, self.loads, data)
+
+    def test_long(self):
+        for proto in protocols:
+            # 256 bytes is where LONG4 begins.
+            for nbits in 1, 8, 8*254, 8*255, 8*256, 8*257:
+                nbase = 1L << nbits
+                for npos in nbase-1, nbase, nbase+1:
+                    for n in npos, -npos:
+                        pickle = self.dumps(n, proto)
+                        got = self.loads(pickle)
+                        self.assertEqual(n, got)
+        # Try a monster.  This is quadratic-time in protos 0 & 1, so don't
+        # bother with those.
+        nbase = long("deadbeeffeedface", 16)
+        nbase += nbase << 1000000
+        for n in nbase, -nbase:
+            p = self.dumps(n, 2)
+            got = self.loads(p)
+            self.assertEqual(n, got)
+
+    @run_with_locale('LC_ALL', 'de_DE', 'fr_FR')
+    def test_float_format(self):
+        # make sure that floats are formatted locale independent
+        self.assertEqual(self.dumps(1.2)[0:3], 'F1.')
+
+    def test_reduce(self):
+        pass
+
+    def test_getinitargs(self):
+        pass
+
+    def test_metaclass(self):
+        a = use_metaclass()
+        for proto in protocols:
+            s = self.dumps(a, proto)
+            b = self.loads(s)
+            self.assertEqual(a.__class__, b.__class__)
+
+    def test_structseq(self):
+        import time
+        import os
+
+        t = time.localtime()
+        for proto in protocols:
+            s = self.dumps(t, proto)
+            u = self.loads(s)
+            self.assertEqual(t, u)
+            if hasattr(os, "stat"):
+                t = os.stat(os.curdir)
+                s = self.dumps(t, proto)
+                u = self.loads(s)
+                self.assertEqual(t, u)
+            if hasattr(os, "statvfs"):
+                t = os.statvfs(os.curdir)
+                s = self.dumps(t, proto)
+                u = self.loads(s)
+                self.assertEqual(t, u)
+
+    # Tests for protocol 2
+
+    def test_proto(self):
+        build_none = pickle.NONE + pickle.STOP
+        for proto in protocols:
+            expected = build_none
+            if proto >= 2:
+                expected = pickle.PROTO + chr(proto) + expected
+            p = self.dumps(None, proto)
+            self.assertEqual(p, expected)
+
+        oob = protocols[-1] + 1     # a future protocol
+        badpickle = pickle.PROTO + chr(oob) + build_none
+        try:
+            self.loads(badpickle)
+        except ValueError, detail:
+            self.failUnless(str(detail).startswith(
+                                            "unsupported pickle protocol"))
+        else:
+            self.fail("expected bad protocol number to raise ValueError")
+
+    def test_long1(self):
+        x = 12345678910111213141516178920L
+        for proto in protocols:
+            s = self.dumps(x, proto)
+            y = self.loads(s)
+            self.assertEqual(x, y)
+            self.assertEqual(opcode_in_pickle(pickle.LONG1, s), proto >= 2)
+
+    def test_long4(self):
+        x = 12345678910111213141516178920L << (256*8)
+        for proto in protocols:
+            s = self.dumps(x, proto)
+            y = self.loads(s)
+            self.assertEqual(x, y)
+            self.assertEqual(opcode_in_pickle(pickle.LONG4, s), proto >= 2)
+
+    def test_short_tuples(self):
+        # Map (proto, len(tuple)) to expected opcode.
+        expected_opcode = {(0, 0): pickle.TUPLE,
+                           (0, 1): pickle.TUPLE,
+                           (0, 2): pickle.TUPLE,
+                           (0, 3): pickle.TUPLE,
+                           (0, 4): pickle.TUPLE,
+
+                           (1, 0): pickle.EMPTY_TUPLE,
+                           (1, 1): pickle.TUPLE,
+                           (1, 2): pickle.TUPLE,
+                           (1, 3): pickle.TUPLE,
+                           (1, 4): pickle.TUPLE,
+
+                           (2, 0): pickle.EMPTY_TUPLE,
+                           (2, 1): pickle.TUPLE1,
+                           (2, 2): pickle.TUPLE2,
+                           (2, 3): pickle.TUPLE3,
+                           (2, 4): pickle.TUPLE,
+                          }
+        a = ()
+        b = (1,)
+        c = (1, 2)
+        d = (1, 2, 3)
+        e = (1, 2, 3, 4)
+        for proto in protocols:
+            for x in a, b, c, d, e:
+                s = self.dumps(x, proto)
+                y = self.loads(s)
+                self.assertEqual(x, y, (proto, x, s, y))
+                expected = expected_opcode[proto, len(x)]
+                self.assertEqual(opcode_in_pickle(expected, s), True)
+
+    def test_singletons(self):
+        # Map (proto, singleton) to expected opcode.
+        expected_opcode = {(0, None): pickle.NONE,
+                           (1, None): pickle.NONE,
+                           (2, None): pickle.NONE,
+
+                           (0, True): pickle.INT,
+                           (1, True): pickle.INT,
+                           (2, True): pickle.NEWTRUE,
+
+                           (0, False): pickle.INT,
+                           (1, False): pickle.INT,
+                           (2, False): pickle.NEWFALSE,
+                          }
+        for proto in protocols:
+            for x in None, False, True:
+                s = self.dumps(x, proto)
+                y = self.loads(s)
+                self.assert_(x is y, (proto, x, s, y))
+                expected = expected_opcode[proto, x]
+                self.assertEqual(opcode_in_pickle(expected, s), True)
+
+    def test_newobj_tuple(self):
+        x = MyTuple([1, 2, 3])
+        x.foo = 42
+        x.bar = "hello"
+        for proto in protocols:
+            s = self.dumps(x, proto)
+            y = self.loads(s)
+            self.assertEqual(tuple(x), tuple(y))
+            self.assertEqual(x.__dict__, y.__dict__)
+
+    def test_newobj_list(self):
+        x = MyList([1, 2, 3])
+        x.foo = 42
+        x.bar = "hello"
+        for proto in protocols:
+            s = self.dumps(x, proto)
+            y = self.loads(s)
+            self.assertEqual(list(x), list(y))
+            self.assertEqual(x.__dict__, y.__dict__)
+
+    def test_newobj_generic(self):
+        for proto in protocols:
+            for C in myclasses:
+                B = C.__base__
+                x = C(C.sample)
+                x.foo = 42
+                s = self.dumps(x, proto)
+                y = self.loads(s)
+                detail = (proto, C, B, x, y, type(y))
+                self.assertEqual(B(x), B(y), detail)
+                self.assertEqual(x.__dict__, y.__dict__, detail)
+
+    # Register a type with copy_reg, with extension code extcode.  Pickle
+    # an object of that type.  Check that the resulting pickle uses opcode
+    # (EXT[124]) under proto 2, and not in proto 1.
+
+    def produce_global_ext(self, extcode, opcode):
+        e = ExtensionSaver(extcode)
+        try:
+            copy_reg.add_extension(__name__, "MyList", extcode)
+            x = MyList([1, 2, 3])
+            x.foo = 42
+            x.bar = "hello"
+
+            # Dump using protocol 1 for comparison.
+            s1 = self.dumps(x, 1)
+            self.assert_(__name__ in s1)
+            self.assert_("MyList" in s1)
+            self.assertEqual(opcode_in_pickle(opcode, s1), False)
+
+            y = self.loads(s1)
+            self.assertEqual(list(x), list(y))
+            self.assertEqual(x.__dict__, y.__dict__)
+
+            # Dump using protocol 2 for test.
+            s2 = self.dumps(x, 2)
+            self.assert_(__name__ not in s2)
+            self.assert_("MyList" not in s2)
+            self.assertEqual(opcode_in_pickle(opcode, s2), True)
+
+            y = self.loads(s2)
+            self.assertEqual(list(x), list(y))
+            self.assertEqual(x.__dict__, y.__dict__)
+
+        finally:
+            e.restore()
+
+    def test_global_ext1(self):
+        self.produce_global_ext(0x00000001, pickle.EXT1)  # smallest EXT1 code
+        self.produce_global_ext(0x000000ff, pickle.EXT1)  # largest EXT1 code
+
+    def test_global_ext2(self):
+        self.produce_global_ext(0x00000100, pickle.EXT2)  # smallest EXT2 code
+        self.produce_global_ext(0x0000ffff, pickle.EXT2)  # largest EXT2 code
+        self.produce_global_ext(0x0000abcd, pickle.EXT2)  # check endianness
+
+    def test_global_ext4(self):
+        self.produce_global_ext(0x00010000, pickle.EXT4)  # smallest EXT4 code
+        self.produce_global_ext(0x7fffffff, pickle.EXT4)  # largest EXT4 code
+        self.produce_global_ext(0x12abcdef, pickle.EXT4)  # check endianness
+
+    def test_list_chunking(self):
+        n = 10  # too small to chunk
+        x = range(n)
+        for proto in protocols:
+            s = self.dumps(x, proto)
+            y = self.loads(s)
+            self.assertEqual(x, y)
+            num_appends = count_opcode(pickle.APPENDS, s)
+            self.assertEqual(num_appends, proto > 0)
+
+        n = 2500  # expect at least two chunks when proto > 0
+        x = range(n)
+        for proto in protocols:
+            s = self.dumps(x, proto)
+            y = self.loads(s)
+            self.assertEqual(x, y)
+            num_appends = count_opcode(pickle.APPENDS, s)
+            if proto == 0:
+                self.assertEqual(num_appends, 0)
+            else:
+                self.failUnless(num_appends >= 2)
+
+    def test_dict_chunking(self):
+        n = 10  # too small to chunk
+        x = dict.fromkeys(range(n))
+        for proto in protocols:
+            s = self.dumps(x, proto)
+            y = self.loads(s)
+            self.assertEqual(x, y)
+            num_setitems = count_opcode(pickle.SETITEMS, s)
+            self.assertEqual(num_setitems, proto > 0)
+
+        n = 2500  # expect at least two chunks when proto > 0
+        x = dict.fromkeys(range(n))
+        for proto in protocols:
+            s = self.dumps(x, proto)
+            y = self.loads(s)
+            self.assertEqual(x, y)
+            num_setitems = count_opcode(pickle.SETITEMS, s)
+            if proto == 0:
+                self.assertEqual(num_setitems, 0)
+            else:
+                self.failUnless(num_setitems >= 2)
+
+    def test_simple_newobj(self):
+        x = object.__new__(SimpleNewObj)  # avoid __init__
+        x.abc = 666
+        for proto in protocols:
+            s = self.dumps(x, proto)
+            self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s), proto >= 2)
+            y = self.loads(s)   # will raise TypeError if __init__ called
+            self.assertEqual(y.abc, 666)
+            self.assertEqual(x.__dict__, y.__dict__)
+
+    def test_newobj_list_slots(self):
+        x = SlotList([1, 2, 3])
+        x.foo = 42
+        x.bar = "hello"
+        s = self.dumps(x, 2)
+        y = self.loads(s)
+        self.assertEqual(list(x), list(y))
+        self.assertEqual(x.__dict__, y.__dict__)
+        self.assertEqual(x.foo, y.foo)
+        self.assertEqual(x.bar, y.bar)
+
+    def test_reduce_overrides_default_reduce_ex(self):
+        for proto in 0, 1, 2:
+            x = REX_one()
+            self.assertEqual(x._reduce_called, 0)
+            s = self.dumps(x, proto)
+            self.assertEqual(x._reduce_called, 1)
+            y = self.loads(s)
+            self.assertEqual(y._reduce_called, 0)
+
+    def test_reduce_ex_called(self):
+        for proto in 0, 1, 2:
+            x = REX_two()
+            self.assertEqual(x._proto, None)
+            s = self.dumps(x, proto)
+            self.assertEqual(x._proto, proto)
+            y = self.loads(s)
+            self.assertEqual(y._proto, None)
+
+    def test_reduce_ex_overrides_reduce(self):
+        for proto in 0, 1, 2:
+            x = REX_three()
+            self.assertEqual(x._proto, None)
+            s = self.dumps(x, proto)
+            self.assertEqual(x._proto, proto)
+            y = self.loads(s)
+            self.assertEqual(y._proto, None)
+
+    def test_reduce_ex_calls_base(self):
+        for proto in 0, 1, 2:
+            x = REX_four()
+            self.assertEqual(x._proto, None)
+            s = self.dumps(x, proto)
+            self.assertEqual(x._proto, proto)
+            y = self.loads(s)
+            self.assertEqual(y._proto, proto)
+
+    def test_reduce_calls_base(self):
+        for proto in 0, 1, 2:
+            x = REX_five()
+            self.assertEqual(x._reduce_called, 0)
+            s = self.dumps(x, proto)
+            self.assertEqual(x._reduce_called, 1)
+            y = self.loads(s)
+            self.assertEqual(y._reduce_called, 1)
+
+# Test classes for reduce_ex
+
+class REX_one(object):
+    _reduce_called = 0
+    def __reduce__(self):
+        self._reduce_called = 1
+        return REX_one, ()
+    # No __reduce_ex__ here, but inheriting it from object
+
+class REX_two(object):
+    _proto = None
+    def __reduce_ex__(self, proto):
+        self._proto = proto
+        return REX_two, ()
+    # No __reduce__ here, but inheriting it from object
+
+class REX_three(object):
+    _proto = None
+    def __reduce_ex__(self, proto):
+        self._proto = proto
+        return REX_two, ()
+    def __reduce__(self):
+        raise TestFailed, "This __reduce__ shouldn't be called"
+
+class REX_four(object):
+    _proto = None
+    def __reduce_ex__(self, proto):
+        self._proto = proto
+        return object.__reduce_ex__(self, proto)
+    # Calling base class method should succeed
+
+class REX_five(object):
+    _reduce_called = 0
+    def __reduce__(self):
+        self._reduce_called = 1
+        return object.__reduce__(self)
+    # This one used to fail with infinite recursion
+
+# Test classes for newobj
+
+class MyInt(int):
+    sample = 1
+
+class MyLong(long):
+    sample = 1L
+
+class MyFloat(float):
+    sample = 1.0
+
+class MyComplex(complex):
+    sample = 1.0 + 0.0j
+
+class MyStr(str):
+    sample = "hello"
+
+class MyUnicode(unicode):
+    sample = u"hello \u1234"
+
+class MyTuple(tuple):
+    sample = (1, 2, 3)
+
+class MyList(list):
+    sample = [1, 2, 3]
+
+class MyDict(dict):
+    sample = {"a": 1, "b": 2}
+
+myclasses = [MyInt, MyLong, MyFloat,
+             MyComplex,
+             MyStr, MyUnicode,
+             MyTuple, MyList, MyDict]
+
+
+class SlotList(MyList):
+    __slots__ = ["foo"]
+
+class SimpleNewObj(object):
+    def __init__(self, a, b, c):
+        # raise an error, to make sure this isn't called
+        raise TypeError("SimpleNewObj.__init__() didn't expect to get called")
+
+class AbstractPickleModuleTests(unittest.TestCase):
+
+    def test_dump_closed_file(self):
+        import os
+        f = open(TESTFN, "w")
+        try:
+            f.close()
+            self.assertRaises(ValueError, self.module.dump, 123, f)
+        finally:
+            os.remove(TESTFN)
+
+    def test_load_closed_file(self):
+        import os
+        f = open(TESTFN, "w")
+        try:
+            f.close()
+            self.assertRaises(ValueError, self.module.dump, 123, f)
+        finally:
+            os.remove(TESTFN)
+
+    def test_highest_protocol(self):
+        # Of course this needs to be changed when HIGHEST_PROTOCOL changes.
+        self.assertEqual(self.module.HIGHEST_PROTOCOL, 2)
+
+    def test_callapi(self):
+        from cStringIO import StringIO
+        f = StringIO()
+        # With and without keyword arguments
+        self.module.dump(123, f, -1)
+        self.module.dump(123, file=f, protocol=-1)
+        self.module.dumps(123, -1)
+        self.module.dumps(123, protocol=-1)
+        self.module.Pickler(f, -1)
+        self.module.Pickler(f, protocol=-1)
+
+class AbstractPersistentPicklerTests(unittest.TestCase):
+
+    # This class defines persistent_id() and persistent_load()
+    # functions that should be used by the pickler.  All even integers
+    # are pickled using persistent ids.
+
+    def persistent_id(self, object):
+        if isinstance(object, int) and object % 2 == 0:
+            self.id_count += 1
+            return str(object)
+        else:
+            return None
+
+    def persistent_load(self, oid):
+        self.load_count += 1
+        object = int(oid)
+        assert object % 2 == 0
+        return object
+
+    def test_persistence(self):
+        self.id_count = 0
+        self.load_count = 0
+        L = range(10)
+        self.assertEqual(self.loads(self.dumps(L)), L)
+        self.assertEqual(self.id_count, 5)
+        self.assertEqual(self.load_count, 5)
+
+    def test_bin_persistence(self):
+        self.id_count = 0
+        self.load_count = 0
+        L = range(10)
+        self.assertEqual(self.loads(self.dumps(L, 1)), L)
+        self.assertEqual(self.id_count, 5)
+        self.assertEqual(self.load_count, 5)

Added: vendor/Python/current/Lib/test/pyclbr_input.py
===================================================================
--- vendor/Python/current/Lib/test/pyclbr_input.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/pyclbr_input.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,33 @@
+"""Test cases for test_pyclbr.py"""
+
+def f(): pass
+
+class Other(object):
+    @classmethod
+    def foo(c): pass
+
+    def om(self): pass
+
+class B (object):
+    def bm(self): pass
+
+class C (B):
+    foo = Other().foo
+    om = Other.om
+
+    d = 10
+
+    # XXX: This causes test_pyclbr.py to fail, but only because the
+    #      introspection-based is_method() code in the test can't
+    #      distinguish between this and a geniune method function like m().
+    #      The pyclbr.py module gets this right as it parses the text.
+    #
+    #f = f
+
+    def m(self): pass
+
+    @staticmethod
+    def sm(self): pass
+
+    @classmethod
+    def cm(self): pass

Added: vendor/Python/current/Lib/test/pydocfodder.py
===================================================================
--- vendor/Python/current/Lib/test/pydocfodder.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/pydocfodder.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,210 @@
+"""Something just to look at via pydoc."""
+
+class A_classic:
+    "A classic class."
+    def A_method(self):
+        "Method defined in A."
+    def AB_method(self):
+        "Method defined in A and B."
+    def AC_method(self):
+        "Method defined in A and C."
+    def AD_method(self):
+        "Method defined in A and D."
+    def ABC_method(self):
+        "Method defined in A, B and C."
+    def ABD_method(self):
+        "Method defined in A, B and D."
+    def ACD_method(self):
+        "Method defined in A, C and D."
+    def ABCD_method(self):
+        "Method defined in A, B, C and D."
+
+
+class B_classic(A_classic):
+    "A classic class, derived from A_classic."
+    def AB_method(self):
+        "Method defined in A and B."
+    def ABC_method(self):
+        "Method defined in A, B and C."
+    def ABD_method(self):
+        "Method defined in A, B and D."
+    def ABCD_method(self):
+        "Method defined in A, B, C and D."
+    def B_method(self):
+        "Method defined in B."
+    def BC_method(self):
+        "Method defined in B and C."
+    def BD_method(self):
+        "Method defined in B and D."
+    def BCD_method(self):
+        "Method defined in B, C and D."
+
+class C_classic(A_classic):
+    "A classic class, derived from A_classic."
+    def AC_method(self):
+        "Method defined in A and C."
+    def ABC_method(self):
+        "Method defined in A, B and C."
+    def ACD_method(self):
+        "Method defined in A, C and D."
+    def ABCD_method(self):
+        "Method defined in A, B, C and D."
+    def BC_method(self):
+        "Method defined in B and C."
+    def BCD_method(self):
+        "Method defined in B, C and D."
+    def C_method(self):
+        "Method defined in C."
+    def CD_method(self):
+        "Method defined in C and D."
+
+class D_classic(B_classic, C_classic):
+    "A classic class, derived from B_classic and C_classic."
+    def AD_method(self):
+        "Method defined in A and D."
+    def ABD_method(self):
+        "Method defined in A, B and D."
+    def ACD_method(self):
+        "Method defined in A, C and D."
+    def ABCD_method(self):
+        "Method defined in A, B, C and D."
+    def BD_method(self):
+        "Method defined in B and D."
+    def BCD_method(self):
+        "Method defined in B, C and D."
+    def CD_method(self):
+        "Method defined in C and D."
+    def D_method(self):
+        "Method defined in D."
+
+
+class A_new(object):
+    "A new-style class."
+
+    def A_method(self):
+        "Method defined in A."
+    def AB_method(self):
+        "Method defined in A and B."
+    def AC_method(self):
+        "Method defined in A and C."
+    def AD_method(self):
+        "Method defined in A and D."
+    def ABC_method(self):
+        "Method defined in A, B and C."
+    def ABD_method(self):
+        "Method defined in A, B and D."
+    def ACD_method(self):
+        "Method defined in A, C and D."
+    def ABCD_method(self):
+        "Method defined in A, B, C and D."
+
+    def A_classmethod(cls, x):
+        "A class method defined in A."
+    A_classmethod = classmethod(A_classmethod)
+
+    def A_staticmethod():
+        "A static method defined in A."
+    A_staticmethod = staticmethod(A_staticmethod)
+
+    def _getx(self):
+        "A property getter function."
+    def _setx(self, value):
+        "A property setter function."
+    def _delx(self):
+        "A property deleter function."
+    A_property = property(fdel=_delx, fget=_getx, fset=_setx,
+                          doc="A sample property defined in A.")
+
+    A_int_alias = int
+
+class B_new(A_new):
+    "A new-style class, derived from A_new."
+
+    def AB_method(self):
+        "Method defined in A and B."
+    def ABC_method(self):
+        "Method defined in A, B and C."
+    def ABD_method(self):
+        "Method defined in A, B and D."
+    def ABCD_method(self):
+        "Method defined in A, B, C and D."
+    def B_method(self):
+        "Method defined in B."
+    def BC_method(self):
+        "Method defined in B and C."
+    def BD_method(self):
+        "Method defined in B and D."
+    def BCD_method(self):
+        "Method defined in B, C and D."
+
+class C_new(A_new):
+    "A new-style class, derived from A_new."
+
+    def AC_method(self):
+        "Method defined in A and C."
+    def ABC_method(self):
+        "Method defined in A, B and C."
+    def ACD_method(self):
+        "Method defined in A, C and D."
+    def ABCD_method(self):
+        "Method defined in A, B, C and D."
+    def BC_method(self):
+        "Method defined in B and C."
+    def BCD_method(self):
+        "Method defined in B, C and D."
+    def C_method(self):
+        "Method defined in C."
+    def CD_method(self):
+        "Method defined in C and D."
+
+class D_new(B_new, C_new):
+    """A new-style class, derived from B_new and C_new.
+    """
+
+    def AD_method(self):
+        "Method defined in A and D."
+    def ABD_method(self):
+        "Method defined in A, B and D."
+    def ACD_method(self):
+        "Method defined in A, C and D."
+    def ABCD_method(self):
+        "Method defined in A, B, C and D."
+    def BD_method(self):
+        "Method defined in B and D."
+    def BCD_method(self):
+        "Method defined in B, C and D."
+    def CD_method(self):
+        "Method defined in C and D."
+    def D_method(self):
+        "Method defined in D."
+
+class FunkyProperties(object):
+    """From SF bug 472347, by Roeland Rengelink.
+
+    Property getters etc may not be vanilla functions or methods,
+    and this used to make GUI pydoc blow up.
+    """
+
+    def __init__(self):
+        self.desc = {'x':0}
+
+    class get_desc:
+        def __init__(self, attr):
+            self.attr = attr
+        def __call__(self, inst):
+            print 'Get called', self, inst
+            return inst.desc[self.attr]
+    class set_desc:
+        def __init__(self, attr):
+            self.attr = attr
+        def __call__(self, inst, val):
+            print 'Set called', self, inst, val
+            inst.desc[self.attr] = val
+    class del_desc:
+        def __init__(self, attr):
+            self.attr = attr
+        def __call__(self, inst):
+            print 'Del called', self, inst
+            del inst.desc[self.attr]
+
+    x = property(get_desc('x'), set_desc('x'), del_desc('x'), 'prop x')

Added: vendor/Python/current/Lib/test/pystone.py
===================================================================
--- vendor/Python/current/Lib/test/pystone.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/pystone.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,266 @@
+#! /usr/bin/env python
+
+"""
+"PYSTONE" Benchmark Program
+
+Version:        Python/1.1 (corresponds to C/1.1 plus 2 Pystone fixes)
+
+Author:         Reinhold P. Weicker,  CACM Vol 27, No 10, 10/84 pg. 1013.
+
+                Translated from ADA to C by Rick Richardson.
+                Every method to preserve ADA-likeness has been used,
+                at the expense of C-ness.
+
+                Translated from C to Python by Guido van Rossum.
+
+Version History:
+
+                Version 1.1 corrects two bugs in version 1.0:
+
+                First, it leaked memory: in Proc1(), NextRecord ends
+                up having a pointer to itself.  I have corrected this
+                by zapping NextRecord.PtrComp at the end of Proc1().
+
+                Second, Proc3() used the operator != to compare a
+                record to None.  This is rather inefficient and not
+                true to the intention of the original benchmark (where
+                a pointer comparison to None is intended; the !=
+                operator attempts to find a method __cmp__ to do value
+                comparison of the record).  Version 1.1 runs 5-10
+                percent faster than version 1.0, so benchmark figures
+                of different versions can't be compared directly.
+
+"""
+
+LOOPS = 50000
+
+from time import clock
+
+__version__ = "1.1"
+
+[Ident1, Ident2, Ident3, Ident4, Ident5] = range(1, 6)
+
+class Record:
+
+    def __init__(self, PtrComp = None, Discr = 0, EnumComp = 0,
+                       IntComp = 0, StringComp = 0):
+        self.PtrComp = PtrComp
+        self.Discr = Discr
+        self.EnumComp = EnumComp
+        self.IntComp = IntComp
+        self.StringComp = StringComp
+
+    def copy(self):
+        return Record(self.PtrComp, self.Discr, self.EnumComp,
+                      self.IntComp, self.StringComp)
+
+TRUE = 1
+FALSE = 0
+
+def main(loops=LOOPS):
+    benchtime, stones = pystones(loops)
+    print "Pystone(%s) time for %d passes = %g" % \
+          (__version__, loops, benchtime)
+    print "This machine benchmarks at %g pystones/second" % stones
+
+
+def pystones(loops=LOOPS):
+    return Proc0(loops)
+
+IntGlob = 0
+BoolGlob = FALSE
+Char1Glob = '\0'
+Char2Glob = '\0'
+Array1Glob = [0]*51
+Array2Glob = map(lambda x: x[:], [Array1Glob]*51)
+PtrGlb = None
+PtrGlbNext = None
+
+def Proc0(loops=LOOPS):
+    global IntGlob
+    global BoolGlob
+    global Char1Glob
+    global Char2Glob
+    global Array1Glob
+    global Array2Glob
+    global PtrGlb
+    global PtrGlbNext
+
+    starttime = clock()
+    for i in range(loops):
+        pass
+    nulltime = clock() - starttime
+
+    PtrGlbNext = Record()
+    PtrGlb = Record()
+    PtrGlb.PtrComp = PtrGlbNext
+    PtrGlb.Discr = Ident1
+    PtrGlb.EnumComp = Ident3
+    PtrGlb.IntComp = 40
+    PtrGlb.StringComp = "DHRYSTONE PROGRAM, SOME STRING"
+    String1Loc = "DHRYSTONE PROGRAM, 1'ST STRING"
+    Array2Glob[8][7] = 10
+
+    starttime = clock()
+
+    for i in range(loops):
+        Proc5()
+        Proc4()
+        IntLoc1 = 2
+        IntLoc2 = 3
+        String2Loc = "DHRYSTONE PROGRAM, 2'ND STRING"
+        EnumLoc = Ident2
+        BoolGlob = not Func2(String1Loc, String2Loc)
+        while IntLoc1 < IntLoc2:
+            IntLoc3 = 5 * IntLoc1 - IntLoc2
+            IntLoc3 = Proc7(IntLoc1, IntLoc2)
+            IntLoc1 = IntLoc1 + 1
+        Proc8(Array1Glob, Array2Glob, IntLoc1, IntLoc3)
+        PtrGlb = Proc1(PtrGlb)
+        CharIndex = 'A'
+        while CharIndex <= Char2Glob:
+            if EnumLoc == Func1(CharIndex, 'C'):
+                EnumLoc = Proc6(Ident1)
+            CharIndex = chr(ord(CharIndex)+1)
+        IntLoc3 = IntLoc2 * IntLoc1
+        IntLoc2 = IntLoc3 / IntLoc1
+        IntLoc2 = 7 * (IntLoc3 - IntLoc2) - IntLoc1
+        IntLoc1 = Proc2(IntLoc1)
+
+    benchtime = clock() - starttime - nulltime
+    return benchtime, (loops / benchtime)
+
+def Proc1(PtrParIn):
+    PtrParIn.PtrComp = NextRecord = PtrGlb.copy()
+    PtrParIn.IntComp = 5
+    NextRecord.IntComp = PtrParIn.IntComp
+    NextRecord.PtrComp = PtrParIn.PtrComp
+    NextRecord.PtrComp = Proc3(NextRecord.PtrComp)
+    if NextRecord.Discr == Ident1:
+        NextRecord.IntComp = 6
+        NextRecord.EnumComp = Proc6(PtrParIn.EnumComp)
+        NextRecord.PtrComp = PtrGlb.PtrComp
+        NextRecord.IntComp = Proc7(NextRecord.IntComp, 10)
+    else:
+        PtrParIn = NextRecord.copy()
+    NextRecord.PtrComp = None
+    return PtrParIn
+
+def Proc2(IntParIO):
+    IntLoc = IntParIO + 10
+    while 1:
+        if Char1Glob == 'A':
+            IntLoc = IntLoc - 1
+            IntParIO = IntLoc - IntGlob
+            EnumLoc = Ident1
+        if EnumLoc == Ident1:
+            break
+    return IntParIO
+
+def Proc3(PtrParOut):
+    global IntGlob
+
+    if PtrGlb is not None:
+        PtrParOut = PtrGlb.PtrComp
+    else:
+        IntGlob = 100
+    PtrGlb.IntComp = Proc7(10, IntGlob)
+    return PtrParOut
+
+def Proc4():
+    global Char2Glob
+
+    BoolLoc = Char1Glob == 'A'
+    BoolLoc = BoolLoc or BoolGlob
+    Char2Glob = 'B'
+
+def Proc5():
+    global Char1Glob
+    global BoolGlob
+
+    Char1Glob = 'A'
+    BoolGlob = FALSE
+
+def Proc6(EnumParIn):
+    EnumParOut = EnumParIn
+    if not Func3(EnumParIn):
+        EnumParOut = Ident4
+    if EnumParIn == Ident1:
+        EnumParOut = Ident1
+    elif EnumParIn == Ident2:
+        if IntGlob > 100:
+            EnumParOut = Ident1
+        else:
+            EnumParOut = Ident4
+    elif EnumParIn == Ident3:
+        EnumParOut = Ident2
+    elif EnumParIn == Ident4:
+        pass
+    elif EnumParIn == Ident5:
+        EnumParOut = Ident3
+    return EnumParOut
+
+def Proc7(IntParI1, IntParI2):
+    IntLoc = IntParI1 + 2
+    IntParOut = IntParI2 + IntLoc
+    return IntParOut
+
+def Proc8(Array1Par, Array2Par, IntParI1, IntParI2):
+    global IntGlob
+
+    IntLoc = IntParI1 + 5
+    Array1Par[IntLoc] = IntParI2
+    Array1Par[IntLoc+1] = Array1Par[IntLoc]
+    Array1Par[IntLoc+30] = IntLoc
+    for IntIndex in range(IntLoc, IntLoc+2):
+        Array2Par[IntLoc][IntIndex] = IntLoc
+    Array2Par[IntLoc][IntLoc-1] = Array2Par[IntLoc][IntLoc-1] + 1
+    Array2Par[IntLoc+20][IntLoc] = Array1Par[IntLoc]
+    IntGlob = 5
+
+def Func1(CharPar1, CharPar2):
+    CharLoc1 = CharPar1
+    CharLoc2 = CharLoc1
+    if CharLoc2 != CharPar2:
+        return Ident1
+    else:
+        return Ident2
+
+def Func2(StrParI1, StrParI2):
+    IntLoc = 1
+    while IntLoc <= 1:
+        if Func1(StrParI1[IntLoc], StrParI2[IntLoc+1]) == Ident1:
+            CharLoc = 'A'
+            IntLoc = IntLoc + 1
+    if CharLoc >= 'W' and CharLoc <= 'Z':
+        IntLoc = 7
+    if CharLoc == 'X':
+        return TRUE
+    else:
+        if StrParI1 > StrParI2:
+            IntLoc = IntLoc + 7
+            return TRUE
+        else:
+            return FALSE
+
+def Func3(EnumParIn):
+    EnumLoc = EnumParIn
+    if EnumLoc == Ident3: return TRUE
+    return FALSE
+
+if __name__ == '__main__':
+    import sys
+    def error(msg):
+        print >>sys.stderr, msg,
+        print >>sys.stderr, "usage: %s [number_of_loops]" % sys.argv[0]
+        sys.exit(100)
+    nargs = len(sys.argv) - 1
+    if nargs > 1:
+        error("%d arguments are too many;" % nargs)
+    elif nargs == 1:
+        try: loops = int(sys.argv[1])
+        except ValueError:
+            error("Invalid argument %r;" % sys.argv[1])
+    else:
+        loops = LOOPS
+    main(loops)


Property changes on: vendor/Python/current/Lib/test/pystone.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/test/re_tests.py
===================================================================
--- vendor/Python/current/Lib/test/re_tests.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/re_tests.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,674 @@
+#!/usr/bin/env python
+# -*- mode: python -*-
+
+# Re test suite and benchmark suite v1.5
+
+# The 3 possible outcomes for each pattern
+[SUCCEED, FAIL, SYNTAX_ERROR] = range(3)
+
+# Benchmark suite (needs expansion)
+#
+# The benchmark suite does not test correctness, just speed.  The
+# first element of each tuple is the regex pattern; the second is a
+# string to match it against.  The benchmarking code will embed the
+# second string inside several sizes of padding, to test how regex
+# matching performs on large strings.
+
+benchmarks = [
+
+    # test common prefix
+    ('Python|Perl', 'Perl'),    # Alternation
+    ('(Python|Perl)', 'Perl'),  # Grouped alternation
+
+    ('Python|Perl|Tcl', 'Perl'),        # Alternation
+    ('(Python|Perl|Tcl)', 'Perl'),      # Grouped alternation
+
+    ('(Python)\\1', 'PythonPython'),    # Backreference
+    ('([0a-z][a-z0-9]*,)+', 'a5,b7,c9,'), # Disable the fastmap optimization
+    ('([a-z][a-z0-9]*,)+', 'a5,b7,c9,'), # A few sets
+
+    ('Python', 'Python'),               # Simple text literal
+    ('.*Python', 'Python'),             # Bad text literal
+    ('.*Python.*', 'Python'),           # Worse text literal
+    ('.*(Python)', 'Python'),           # Bad text literal with grouping
+
+]
+
+# Test suite (for verifying correctness)
+#
+# The test suite is a list of 5- or 3-tuples.  The 5 parts of a
+# complete tuple are:
+# element 0: a string containing the pattern
+#         1: the string to match against the pattern
+#         2: the expected result (SUCCEED, FAIL, SYNTAX_ERROR)
+#         3: a string that will be eval()'ed to produce a test string.
+#            This is an arbitrary Python expression; the available
+#            variables are "found" (the whole match), and "g1", "g2", ...
+#            up to "g99" contain the contents of each group, or the
+#            string 'None' if the group wasn't given a value, or the
+#            string 'Error' if the group index was out of range;
+#            also "groups", the return value of m.group() (a tuple).
+#         4: The expected result of evaluating the expression.
+#            If the two don't match, an error is reported.
+#
+# If the regex isn't expected to work, the latter two elements can be omitted.
+
+tests = [
+    # Test ?P< and ?P= extensions
+    ('(?P<foo_123', '', SYNTAX_ERROR),      # Unterminated group identifier
+    ('(?P<1>a)', '', SYNTAX_ERROR),         # Begins with a digit
+    ('(?P<!>a)', '', SYNTAX_ERROR),         # Begins with an illegal char
+    ('(?P<foo!>a)', '', SYNTAX_ERROR),      # Begins with an illegal char
+
+    # Same tests, for the ?P= form
+    ('(?P<foo_123>a)(?P=foo_123', 'aa', SYNTAX_ERROR),
+    ('(?P<foo_123>a)(?P=1)', 'aa', SYNTAX_ERROR),
+    ('(?P<foo_123>a)(?P=!)', 'aa', SYNTAX_ERROR),
+    ('(?P<foo_123>a)(?P=foo_124', 'aa', SYNTAX_ERROR),  # Backref to undefined group
+
+    ('(?P<foo_123>a)', 'a', SUCCEED, 'g1', 'a'),
+    ('(?P<foo_123>a)(?P=foo_123)', 'aa', SUCCEED, 'g1', 'a'),
+
+    # Test octal escapes
+    ('\\1', 'a', SYNTAX_ERROR),    # Backreference
+    ('[\\1]', '\1', SUCCEED, 'found', '\1'),  # Character
+    ('\\09', chr(0) + '9', SUCCEED, 'found', chr(0) + '9'),
+    ('\\141', 'a', SUCCEED, 'found', 'a'),
+    ('(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)(l)\\119', 'abcdefghijklk9', SUCCEED, 'found+"-"+g11', 'abcdefghijklk9-k'),
+
+    # Test \0 is handled everywhere
+    (r'\0', '\0', SUCCEED, 'found', '\0'),
+    (r'[\0a]', '\0', SUCCEED, 'found', '\0'),
+    (r'[a\0]', '\0', SUCCEED, 'found', '\0'),
+    (r'[^a\0]', '\0', FAIL),
+
+    # Test various letter escapes
+    (r'\a[\b]\f\n\r\t\v', '\a\b\f\n\r\t\v', SUCCEED, 'found', '\a\b\f\n\r\t\v'),
+    (r'[\a][\b][\f][\n][\r][\t][\v]', '\a\b\f\n\r\t\v', SUCCEED, 'found', '\a\b\f\n\r\t\v'),
+    # NOTE: not an error under PCRE/PRE:
+    # (r'\u', '', SYNTAX_ERROR),    # A Perl escape
+    (r'\c\e\g\h\i\j\k\m\o\p\q\y\z', 'ceghijkmopqyz', SUCCEED, 'found', 'ceghijkmopqyz'),
+    (r'\xff', '\377', SUCCEED, 'found', chr(255)),
+    # new \x semantics
+    (r'\x00ffffffffffffff', '\377', FAIL, 'found', chr(255)),
+    (r'\x00f', '\017', FAIL, 'found', chr(15)),
+    (r'\x00fe', '\376', FAIL, 'found', chr(254)),
+    # (r'\x00ffffffffffffff', '\377', SUCCEED, 'found', chr(255)),
+    # (r'\x00f', '\017', SUCCEED, 'found', chr(15)),
+    # (r'\x00fe', '\376', SUCCEED, 'found', chr(254)),
+
+    (r"^\w+=(\\[\000-\277]|[^\n\\])*", "SRC=eval.c g.c blah blah blah \\\\\n\tapes.c",
+     SUCCEED, 'found', "SRC=eval.c g.c blah blah blah \\\\"),
+
+    # Test that . only matches \n in DOTALL mode
+    ('a.b', 'acb', SUCCEED, 'found', 'acb'),
+    ('a.b', 'a\nb', FAIL),
+    ('a.*b', 'acc\nccb', FAIL),
+    ('a.{4,5}b', 'acc\nccb', FAIL),
+    ('a.b', 'a\rb', SUCCEED, 'found', 'a\rb'),
+    ('a.b(?s)', 'a\nb', SUCCEED, 'found', 'a\nb'),
+    ('a.*(?s)b', 'acc\nccb', SUCCEED, 'found', 'acc\nccb'),
+    ('(?s)a.{4,5}b', 'acc\nccb', SUCCEED, 'found', 'acc\nccb'),
+    ('(?s)a.b', 'a\nb', SUCCEED, 'found', 'a\nb'),
+
+    (')', '', SYNTAX_ERROR),           # Unmatched right bracket
+    ('', '', SUCCEED, 'found', ''),    # Empty pattern
+    ('abc', 'abc', SUCCEED, 'found', 'abc'),
+    ('abc', 'xbc', FAIL),
+    ('abc', 'axc', FAIL),
+    ('abc', 'abx', FAIL),
+    ('abc', 'xabcy', SUCCEED, 'found', 'abc'),
+    ('abc', 'ababc', SUCCEED, 'found', 'abc'),
+    ('ab*c', 'abc', SUCCEED, 'found', 'abc'),
+    ('ab*bc', 'abc', SUCCEED, 'found', 'abc'),
+    ('ab*bc', 'abbc', SUCCEED, 'found', 'abbc'),
+    ('ab*bc', 'abbbbc', SUCCEED, 'found', 'abbbbc'),
+    ('ab+bc', 'abbc', SUCCEED, 'found', 'abbc'),
+    ('ab+bc', 'abc', FAIL),
+    ('ab+bc', 'abq', FAIL),
+    ('ab+bc', 'abbbbc', SUCCEED, 'found', 'abbbbc'),
+    ('ab?bc', 'abbc', SUCCEED, 'found', 'abbc'),
+    ('ab?bc', 'abc', SUCCEED, 'found', 'abc'),
+    ('ab?bc', 'abbbbc', FAIL),
+    ('ab?c', 'abc', SUCCEED, 'found', 'abc'),
+    ('^abc$', 'abc', SUCCEED, 'found', 'abc'),
+    ('^abc$', 'abcc', FAIL),
+    ('^abc', 'abcc', SUCCEED, 'found', 'abc'),
+    ('^abc$', 'aabc', FAIL),
+    ('abc$', 'aabc', SUCCEED, 'found', 'abc'),
+    ('^', 'abc', SUCCEED, 'found+"-"', '-'),
+    ('$', 'abc', SUCCEED, 'found+"-"', '-'),
+    ('a.c', 'abc', SUCCEED, 'found', 'abc'),
+    ('a.c', 'axc', SUCCEED, 'found', 'axc'),
+    ('a.*c', 'axyzc', SUCCEED, 'found', 'axyzc'),
+    ('a.*c', 'axyzd', FAIL),
+    ('a[bc]d', 'abc', FAIL),
+    ('a[bc]d', 'abd', SUCCEED, 'found', 'abd'),
+    ('a[b-d]e', 'abd', FAIL),
+    ('a[b-d]e', 'ace', SUCCEED, 'found', 'ace'),
+    ('a[b-d]', 'aac', SUCCEED, 'found', 'ac'),
+    ('a[-b]', 'a-', SUCCEED, 'found', 'a-'),
+    ('a[\\-b]', 'a-', SUCCEED, 'found', 'a-'),
+    # NOTE: not an error under PCRE/PRE:
+    # ('a[b-]', 'a-', SYNTAX_ERROR),
+    ('a[]b', '-', SYNTAX_ERROR),
+    ('a[', '-', SYNTAX_ERROR),
+    ('a\\', '-', SYNTAX_ERROR),
+    ('abc)', '-', SYNTAX_ERROR),
+    ('(abc', '-', SYNTAX_ERROR),
+    ('a]', 'a]', SUCCEED, 'found', 'a]'),
+    ('a[]]b', 'a]b', SUCCEED, 'found', 'a]b'),
+    ('a[\]]b', 'a]b', SUCCEED, 'found', 'a]b'),
+    ('a[^bc]d', 'aed', SUCCEED, 'found', 'aed'),
+    ('a[^bc]d', 'abd', FAIL),
+    ('a[^-b]c', 'adc', SUCCEED, 'found', 'adc'),
+    ('a[^-b]c', 'a-c', FAIL),
+    ('a[^]b]c', 'a]c', FAIL),
+    ('a[^]b]c', 'adc', SUCCEED, 'found', 'adc'),
+    ('\\ba\\b', 'a-', SUCCEED, '"-"', '-'),
+    ('\\ba\\b', '-a', SUCCEED, '"-"', '-'),
+    ('\\ba\\b', '-a-', SUCCEED, '"-"', '-'),
+    ('\\by\\b', 'xy', FAIL),
+    ('\\by\\b', 'yz', FAIL),
+    ('\\by\\b', 'xyz', FAIL),
+    ('x\\b', 'xyz', FAIL),
+    ('x\\B', 'xyz', SUCCEED, '"-"', '-'),
+    ('\\Bz', 'xyz', SUCCEED, '"-"', '-'),
+    ('z\\B', 'xyz', FAIL),
+    ('\\Bx', 'xyz', FAIL),
+    ('\\Ba\\B', 'a-', FAIL, '"-"', '-'),
+    ('\\Ba\\B', '-a', FAIL, '"-"', '-'),
+    ('\\Ba\\B', '-a-', FAIL, '"-"', '-'),
+    ('\\By\\B', 'xy', FAIL),
+    ('\\By\\B', 'yz', FAIL),
+    ('\\By\\b', 'xy', SUCCEED, '"-"', '-'),
+    ('\\by\\B', 'yz', SUCCEED, '"-"', '-'),
+    ('\\By\\B', 'xyz', SUCCEED, '"-"', '-'),
+    ('ab|cd', 'abc', SUCCEED, 'found', 'ab'),
+    ('ab|cd', 'abcd', SUCCEED, 'found', 'ab'),
+    ('()ef', 'def', SUCCEED, 'found+"-"+g1', 'ef-'),
+    ('$b', 'b', FAIL),
+    ('a\\(b', 'a(b', SUCCEED, 'found+"-"+g1', 'a(b-Error'),
+    ('a\\(*b', 'ab', SUCCEED, 'found', 'ab'),
+    ('a\\(*b', 'a((b', SUCCEED, 'found', 'a((b'),
+    ('a\\\\b', 'a\\b', SUCCEED, 'found', 'a\\b'),
+    ('((a))', 'abc', SUCCEED, 'found+"-"+g1+"-"+g2', 'a-a-a'),
+    ('(a)b(c)', 'abc', SUCCEED, 'found+"-"+g1+"-"+g2', 'abc-a-c'),
+    ('a+b+c', 'aabbabc', SUCCEED, 'found', 'abc'),
+    ('(a+|b)*', 'ab', SUCCEED, 'found+"-"+g1', 'ab-b'),
+    ('(a+|b)+', 'ab', SUCCEED, 'found+"-"+g1', 'ab-b'),
+    ('(a+|b)?', 'ab', SUCCEED, 'found+"-"+g1', 'a-a'),
+    (')(', '-', SYNTAX_ERROR),
+    ('[^ab]*', 'cde', SUCCEED, 'found', 'cde'),
+    ('abc', '', FAIL),
+    ('a*', '', SUCCEED, 'found', ''),
+    ('a|b|c|d|e', 'e', SUCCEED, 'found', 'e'),
+    ('(a|b|c|d|e)f', 'ef', SUCCEED, 'found+"-"+g1', 'ef-e'),
+    ('abcd*efg', 'abcdefg', SUCCEED, 'found', 'abcdefg'),
+    ('ab*', 'xabyabbbz', SUCCEED, 'found', 'ab'),
+    ('ab*', 'xayabbbz', SUCCEED, 'found', 'a'),
+    ('(ab|cd)e', 'abcde', SUCCEED, 'found+"-"+g1', 'cde-cd'),
+    ('[abhgefdc]ij', 'hij', SUCCEED, 'found', 'hij'),
+    ('^(ab|cd)e', 'abcde', FAIL, 'xg1y', 'xy'),
+    ('(abc|)ef', 'abcdef', SUCCEED, 'found+"-"+g1', 'ef-'),
+    ('(a|b)c*d', 'abcd', SUCCEED, 'found+"-"+g1', 'bcd-b'),
+    ('(ab|ab*)bc', 'abc', SUCCEED, 'found+"-"+g1', 'abc-a'),
+    ('a([bc]*)c*', 'abc', SUCCEED, 'found+"-"+g1', 'abc-bc'),
+    ('a([bc]*)(c*d)', 'abcd', SUCCEED, 'found+"-"+g1+"-"+g2', 'abcd-bc-d'),
+    ('a([bc]+)(c*d)', 'abcd', SUCCEED, 'found+"-"+g1+"-"+g2', 'abcd-bc-d'),
+    ('a([bc]*)(c+d)', 'abcd', SUCCEED, 'found+"-"+g1+"-"+g2', 'abcd-b-cd'),
+    ('a[bcd]*dcdcde', 'adcdcde', SUCCEED, 'found', 'adcdcde'),
+    ('a[bcd]+dcdcde', 'adcdcde', FAIL),
+    ('(ab|a)b*c', 'abc', SUCCEED, 'found+"-"+g1', 'abc-ab'),
+    ('((a)(b)c)(d)', 'abcd', SUCCEED, 'g1+"-"+g2+"-"+g3+"-"+g4', 'abc-a-b-d'),
+    ('[a-zA-Z_][a-zA-Z0-9_]*', 'alpha', SUCCEED, 'found', 'alpha'),
+    ('^a(bc+|b[eh])g|.h$', 'abh', SUCCEED, 'found+"-"+g1', 'bh-None'),
+    ('(bc+d$|ef*g.|h?i(j|k))', 'effgz', SUCCEED, 'found+"-"+g1+"-"+g2', 'effgz-effgz-None'),
+    ('(bc+d$|ef*g.|h?i(j|k))', 'ij', SUCCEED, 'found+"-"+g1+"-"+g2', 'ij-ij-j'),
+    ('(bc+d$|ef*g.|h?i(j|k))', 'effg', FAIL),
+    ('(bc+d$|ef*g.|h?i(j|k))', 'bcdd', FAIL),
+    ('(bc+d$|ef*g.|h?i(j|k))', 'reffgz', SUCCEED, 'found+"-"+g1+"-"+g2', 'effgz-effgz-None'),
+    ('(((((((((a)))))))))', 'a', SUCCEED, 'found', 'a'),
+    ('multiple words of text', 'uh-uh', FAIL),
+    ('multiple words', 'multiple words, yeah', SUCCEED, 'found', 'multiple words'),
+    ('(.*)c(.*)', 'abcde', SUCCEED, 'found+"-"+g1+"-"+g2', 'abcde-ab-de'),
+    ('\\((.*), (.*)\\)', '(a, b)', SUCCEED, 'g2+"-"+g1', 'b-a'),
+    ('[k]', 'ab', FAIL),
+    ('a[-]?c', 'ac', SUCCEED, 'found', 'ac'),
+    ('(abc)\\1', 'abcabc', SUCCEED, 'g1', 'abc'),
+    ('([a-c]*)\\1', 'abcabc', SUCCEED, 'g1', 'abc'),
+    ('^(.+)?B', 'AB', SUCCEED, 'g1', 'A'),
+    ('(a+).\\1$', 'aaaaa', SUCCEED, 'found+"-"+g1', 'aaaaa-aa'),
+    ('^(a+).\\1$', 'aaaa', FAIL),
+    ('(abc)\\1', 'abcabc', SUCCEED, 'found+"-"+g1', 'abcabc-abc'),
+    ('([a-c]+)\\1', 'abcabc', SUCCEED, 'found+"-"+g1', 'abcabc-abc'),
+    ('(a)\\1', 'aa', SUCCEED, 'found+"-"+g1', 'aa-a'),
+    ('(a+)\\1', 'aa', SUCCEED, 'found+"-"+g1', 'aa-a'),
+    ('(a+)+\\1', 'aa', SUCCEED, 'found+"-"+g1', 'aa-a'),
+    ('(a).+\\1', 'aba', SUCCEED, 'found+"-"+g1', 'aba-a'),
+    ('(a)ba*\\1', 'aba', SUCCEED, 'found+"-"+g1', 'aba-a'),
+    ('(aa|a)a\\1$', 'aaa', SUCCEED, 'found+"-"+g1', 'aaa-a'),
+    ('(a|aa)a\\1$', 'aaa', SUCCEED, 'found+"-"+g1', 'aaa-a'),
+    ('(a+)a\\1$', 'aaa', SUCCEED, 'found+"-"+g1', 'aaa-a'),
+    ('([abc]*)\\1', 'abcabc', SUCCEED, 'found+"-"+g1', 'abcabc-abc'),
+    ('(a)(b)c|ab', 'ab', SUCCEED, 'found+"-"+g1+"-"+g2', 'ab-None-None'),
+    ('(a)+x', 'aaax', SUCCEED, 'found+"-"+g1', 'aaax-a'),
+    ('([ac])+x', 'aacx', SUCCEED, 'found+"-"+g1', 'aacx-c'),
+    ('([^/]*/)*sub1/', 'd:msgs/tdir/sub1/trial/away.cpp', SUCCEED, 'found+"-"+g1', 'd:msgs/tdir/sub1/-tdir/'),
+    ('([^.]*)\\.([^:]*):[T ]+(.*)', 'track1.title:TBlah blah blah', SUCCEED, 'found+"-"+g1+"-"+g2+"-"+g3', 'track1.title:TBlah blah blah-track1-title-Blah blah blah'),
+    ('([^N]*N)+', 'abNNxyzN', SUCCEED, 'found+"-"+g1', 'abNNxyzN-xyzN'),
+    ('([^N]*N)+', 'abNNxyz', SUCCEED, 'found+"-"+g1', 'abNN-N'),
+    ('([abc]*)x', 'abcx', SUCCEED, 'found+"-"+g1', 'abcx-abc'),
+    ('([abc]*)x', 'abc', FAIL),
+    ('([xyz]*)x', 'abcx', SUCCEED, 'found+"-"+g1', 'x-'),
+    ('(a)+b|aac', 'aac', SUCCEED, 'found+"-"+g1', 'aac-None'),
+
+    # Test symbolic groups
+
+    ('(?P<i d>aaa)a', 'aaaa', SYNTAX_ERROR),
+    ('(?P<id>aaa)a', 'aaaa', SUCCEED, 'found+"-"+id', 'aaaa-aaa'),
+    ('(?P<id>aa)(?P=id)', 'aaaa', SUCCEED, 'found+"-"+id', 'aaaa-aa'),
+    ('(?P<id>aa)(?P=xd)', 'aaaa', SYNTAX_ERROR),
+
+    # Test octal escapes/memory references
+
+    ('\\1', 'a', SYNTAX_ERROR),
+    ('\\09', chr(0) + '9', SUCCEED, 'found', chr(0) + '9'),
+    ('\\141', 'a', SUCCEED, 'found', 'a'),
+    ('(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)(l)\\119', 'abcdefghijklk9', SUCCEED, 'found+"-"+g11', 'abcdefghijklk9-k'),
+
+    # All tests from Perl
+
+    ('abc', 'abc', SUCCEED, 'found', 'abc'),
+    ('abc', 'xbc', FAIL),
+    ('abc', 'axc', FAIL),
+    ('abc', 'abx', FAIL),
+    ('abc', 'xabcy', SUCCEED, 'found', 'abc'),
+    ('abc', 'ababc', SUCCEED, 'found', 'abc'),
+    ('ab*c', 'abc', SUCCEED, 'found', 'abc'),
+    ('ab*bc', 'abc', SUCCEED, 'found', 'abc'),
+    ('ab*bc', 'abbc', SUCCEED, 'found', 'abbc'),
+    ('ab*bc', 'abbbbc', SUCCEED, 'found', 'abbbbc'),
+    ('ab{0,}bc', 'abbbbc', SUCCEED, 'found', 'abbbbc'),
+    ('ab+bc', 'abbc', SUCCEED, 'found', 'abbc'),
+    ('ab+bc', 'abc', FAIL),
+    ('ab+bc', 'abq', FAIL),
+    ('ab{1,}bc', 'abq', FAIL),
+    ('ab+bc', 'abbbbc', SUCCEED, 'found', 'abbbbc'),
+    ('ab{1,}bc', 'abbbbc', SUCCEED, 'found', 'abbbbc'),
+    ('ab{1,3}bc', 'abbbbc', SUCCEED, 'found', 'abbbbc'),
+    ('ab{3,4}bc', 'abbbbc', SUCCEED, 'found', 'abbbbc'),
+    ('ab{4,5}bc', 'abbbbc', FAIL),
+    ('ab?bc', 'abbc', SUCCEED, 'found', 'abbc'),
+    ('ab?bc', 'abc', SUCCEED, 'found', 'abc'),
+    ('ab{0,1}bc', 'abc', SUCCEED, 'found', 'abc'),
+    ('ab?bc', 'abbbbc', FAIL),
+    ('ab?c', 'abc', SUCCEED, 'found', 'abc'),
+    ('ab{0,1}c', 'abc', SUCCEED, 'found', 'abc'),
+    ('^abc$', 'abc', SUCCEED, 'found', 'abc'),
+    ('^abc$', 'abcc', FAIL),
+    ('^abc', 'abcc', SUCCEED, 'found', 'abc'),
+    ('^abc$', 'aabc', FAIL),
+    ('abc$', 'aabc', SUCCEED, 'found', 'abc'),
+    ('^', 'abc', SUCCEED, 'found', ''),
+    ('$', 'abc', SUCCEED, 'found', ''),
+    ('a.c', 'abc', SUCCEED, 'found', 'abc'),
+    ('a.c', 'axc', SUCCEED, 'found', 'axc'),
+    ('a.*c', 'axyzc', SUCCEED, 'found', 'axyzc'),
+    ('a.*c', 'axyzd', FAIL),
+    ('a[bc]d', 'abc', FAIL),
+    ('a[bc]d', 'abd', SUCCEED, 'found', 'abd'),
+    ('a[b-d]e', 'abd', FAIL),
+    ('a[b-d]e', 'ace', SUCCEED, 'found', 'ace'),
+    ('a[b-d]', 'aac', SUCCEED, 'found', 'ac'),
+    ('a[-b]', 'a-', SUCCEED, 'found', 'a-'),
+    ('a[b-]', 'a-', SUCCEED, 'found', 'a-'),
+    ('a[b-a]', '-', SYNTAX_ERROR),
+    ('a[]b', '-', SYNTAX_ERROR),
+    ('a[', '-', SYNTAX_ERROR),
+    ('a]', 'a]', SUCCEED, 'found', 'a]'),
+    ('a[]]b', 'a]b', SUCCEED, 'found', 'a]b'),
+    ('a[^bc]d', 'aed', SUCCEED, 'found', 'aed'),
+    ('a[^bc]d', 'abd', FAIL),
+    ('a[^-b]c', 'adc', SUCCEED, 'found', 'adc'),
+    ('a[^-b]c', 'a-c', FAIL),
+    ('a[^]b]c', 'a]c', FAIL),
+    ('a[^]b]c', 'adc', SUCCEED, 'found', 'adc'),
+    ('ab|cd', 'abc', SUCCEED, 'found', 'ab'),
+    ('ab|cd', 'abcd', SUCCEED, 'found', 'ab'),
+    ('()ef', 'def', SUCCEED, 'found+"-"+g1', 'ef-'),
+    ('*a', '-', SYNTAX_ERROR),
+    ('(*)b', '-', SYNTAX_ERROR),
+    ('$b', 'b', FAIL),
+    ('a\\', '-', SYNTAX_ERROR),
+    ('a\\(b', 'a(b', SUCCEED, 'found+"-"+g1', 'a(b-Error'),
+    ('a\\(*b', 'ab', SUCCEED, 'found', 'ab'),
+    ('a\\(*b', 'a((b', SUCCEED, 'found', 'a((b'),
+    ('a\\\\b', 'a\\b', SUCCEED, 'found', 'a\\b'),
+    ('abc)', '-', SYNTAX_ERROR),
+    ('(abc', '-', SYNTAX_ERROR),
+    ('((a))', 'abc', SUCCEED, 'found+"-"+g1+"-"+g2', 'a-a-a'),
+    ('(a)b(c)', 'abc', SUCCEED, 'found+"-"+g1+"-"+g2', 'abc-a-c'),
+    ('a+b+c', 'aabbabc', SUCCEED, 'found', 'abc'),
+    ('a{1,}b{1,}c', 'aabbabc', SUCCEED, 'found', 'abc'),
+    ('a**', '-', SYNTAX_ERROR),
+    ('a.+?c', 'abcabc', SUCCEED, 'found', 'abc'),
+    ('(a+|b)*', 'ab', SUCCEED, 'found+"-"+g1', 'ab-b'),
+    ('(a+|b){0,}', 'ab', SUCCEED, 'found+"-"+g1', 'ab-b'),
+    ('(a+|b)+', 'ab', SUCCEED, 'found+"-"+g1', 'ab-b'),
+    ('(a+|b){1,}', 'ab', SUCCEED, 'found+"-"+g1', 'ab-b'),
+    ('(a+|b)?', 'ab', SUCCEED, 'found+"-"+g1', 'a-a'),
+    ('(a+|b){0,1}', 'ab', SUCCEED, 'found+"-"+g1', 'a-a'),
+    (')(', '-', SYNTAX_ERROR),
+    ('[^ab]*', 'cde', SUCCEED, 'found', 'cde'),
+    ('abc', '', FAIL),
+    ('a*', '', SUCCEED, 'found', ''),
+    ('([abc])*d', 'abbbcd', SUCCEED, 'found+"-"+g1', 'abbbcd-c'),
+    ('([abc])*bcd', 'abcd', SUCCEED, 'found+"-"+g1', 'abcd-a'),
+    ('a|b|c|d|e', 'e', SUCCEED, 'found', 'e'),
+    ('(a|b|c|d|e)f', 'ef', SUCCEED, 'found+"-"+g1', 'ef-e'),
+    ('abcd*efg', 'abcdefg', SUCCEED, 'found', 'abcdefg'),
+    ('ab*', 'xabyabbbz', SUCCEED, 'found', 'ab'),
+    ('ab*', 'xayabbbz', SUCCEED, 'found', 'a'),
+    ('(ab|cd)e', 'abcde', SUCCEED, 'found+"-"+g1', 'cde-cd'),
+    ('[abhgefdc]ij', 'hij', SUCCEED, 'found', 'hij'),
+    ('^(ab|cd)e', 'abcde', FAIL),
+    ('(abc|)ef', 'abcdef', SUCCEED, 'found+"-"+g1', 'ef-'),
+    ('(a|b)c*d', 'abcd', SUCCEED, 'found+"-"+g1', 'bcd-b'),
+    ('(ab|ab*)bc', 'abc', SUCCEED, 'found+"-"+g1', 'abc-a'),
+    ('a([bc]*)c*', 'abc', SUCCEED, 'found+"-"+g1', 'abc-bc'),
+    ('a([bc]*)(c*d)', 'abcd', SUCCEED, 'found+"-"+g1+"-"+g2', 'abcd-bc-d'),
+    ('a([bc]+)(c*d)', 'abcd', SUCCEED, 'found+"-"+g1+"-"+g2', 'abcd-bc-d'),
+    ('a([bc]*)(c+d)', 'abcd', SUCCEED, 'found+"-"+g1+"-"+g2', 'abcd-b-cd'),
+    ('a[bcd]*dcdcde', 'adcdcde', SUCCEED, 'found', 'adcdcde'),
+    ('a[bcd]+dcdcde', 'adcdcde', FAIL),
+    ('(ab|a)b*c', 'abc', SUCCEED, 'found+"-"+g1', 'abc-ab'),
+    ('((a)(b)c)(d)', 'abcd', SUCCEED, 'g1+"-"+g2+"-"+g3+"-"+g4', 'abc-a-b-d'),
+    ('[a-zA-Z_][a-zA-Z0-9_]*', 'alpha', SUCCEED, 'found', 'alpha'),
+    ('^a(bc+|b[eh])g|.h$', 'abh', SUCCEED, 'found+"-"+g1', 'bh-None'),
+    ('(bc+d$|ef*g.|h?i(j|k))', 'effgz', SUCCEED, 'found+"-"+g1+"-"+g2', 'effgz-effgz-None'),
+    ('(bc+d$|ef*g.|h?i(j|k))', 'ij', SUCCEED, 'found+"-"+g1+"-"+g2', 'ij-ij-j'),
+    ('(bc+d$|ef*g.|h?i(j|k))', 'effg', FAIL),
+    ('(bc+d$|ef*g.|h?i(j|k))', 'bcdd', FAIL),
+    ('(bc+d$|ef*g.|h?i(j|k))', 'reffgz', SUCCEED, 'found+"-"+g1+"-"+g2', 'effgz-effgz-None'),
+    ('((((((((((a))))))))))', 'a', SUCCEED, 'g10', 'a'),
+    ('((((((((((a))))))))))\\10', 'aa', SUCCEED, 'found', 'aa'),
+# Python does not have the same rules for \\41 so this is a syntax error
+#    ('((((((((((a))))))))))\\41', 'aa', FAIL),
+#    ('((((((((((a))))))))))\\41', 'a!', SUCCEED, 'found', 'a!'),
+    ('((((((((((a))))))))))\\41', '', SYNTAX_ERROR),
+    ('(?i)((((((((((a))))))))))\\41', '', SYNTAX_ERROR),
+    ('(((((((((a)))))))))', 'a', SUCCEED, 'found', 'a'),
+    ('multiple words of text', 'uh-uh', FAIL),
+    ('multiple words', 'multiple words, yeah', SUCCEED, 'found', 'multiple words'),
+    ('(.*)c(.*)', 'abcde', SUCCEED, 'found+"-"+g1+"-"+g2', 'abcde-ab-de'),
+    ('\\((.*), (.*)\\)', '(a, b)', SUCCEED, 'g2+"-"+g1', 'b-a'),
+    ('[k]', 'ab', FAIL),
+    ('a[-]?c', 'ac', SUCCEED, 'found', 'ac'),
+    ('(abc)\\1', 'abcabc', SUCCEED, 'g1', 'abc'),
+    ('([a-c]*)\\1', 'abcabc', SUCCEED, 'g1', 'abc'),
+    ('(?i)abc', 'ABC', SUCCEED, 'found', 'ABC'),
+    ('(?i)abc', 'XBC', FAIL),
+    ('(?i)abc', 'AXC', FAIL),
+    ('(?i)abc', 'ABX', FAIL),
+    ('(?i)abc', 'XABCY', SUCCEED, 'found', 'ABC'),
+    ('(?i)abc', 'ABABC', SUCCEED, 'found', 'ABC'),
+    ('(?i)ab*c', 'ABC', SUCCEED, 'found', 'ABC'),
+    ('(?i)ab*bc', 'ABC', SUCCEED, 'found', 'ABC'),
+    ('(?i)ab*bc', 'ABBC', SUCCEED, 'found', 'ABBC'),
+    ('(?i)ab*?bc', 'ABBBBC', SUCCEED, 'found', 'ABBBBC'),
+    ('(?i)ab{0,}?bc', 'ABBBBC', SUCCEED, 'found', 'ABBBBC'),
+    ('(?i)ab+?bc', 'ABBC', SUCCEED, 'found', 'ABBC'),
+    ('(?i)ab+bc', 'ABC', FAIL),
+    ('(?i)ab+bc', 'ABQ', FAIL),
+    ('(?i)ab{1,}bc', 'ABQ', FAIL),
+    ('(?i)ab+bc', 'ABBBBC', SUCCEED, 'found', 'ABBBBC'),
+    ('(?i)ab{1,}?bc', 'ABBBBC', SUCCEED, 'found', 'ABBBBC'),
+    ('(?i)ab{1,3}?bc', 'ABBBBC', SUCCEED, 'found', 'ABBBBC'),
+    ('(?i)ab{3,4}?bc', 'ABBBBC', SUCCEED, 'found', 'ABBBBC'),
+    ('(?i)ab{4,5}?bc', 'ABBBBC', FAIL),
+    ('(?i)ab??bc', 'ABBC', SUCCEED, 'found', 'ABBC'),
+    ('(?i)ab??bc', 'ABC', SUCCEED, 'found', 'ABC'),
+    ('(?i)ab{0,1}?bc', 'ABC', SUCCEED, 'found', 'ABC'),
+    ('(?i)ab??bc', 'ABBBBC', FAIL),
+    ('(?i)ab??c', 'ABC', SUCCEED, 'found', 'ABC'),
+    ('(?i)ab{0,1}?c', 'ABC', SUCCEED, 'found', 'ABC'),
+    ('(?i)^abc$', 'ABC', SUCCEED, 'found', 'ABC'),
+    ('(?i)^abc$', 'ABCC', FAIL),
+    ('(?i)^abc', 'ABCC', SUCCEED, 'found', 'ABC'),
+    ('(?i)^abc$', 'AABC', FAIL),
+    ('(?i)abc$', 'AABC', SUCCEED, 'found', 'ABC'),
+    ('(?i)^', 'ABC', SUCCEED, 'found', ''),
+    ('(?i)$', 'ABC', SUCCEED, 'found', ''),
+    ('(?i)a.c', 'ABC', SUCCEED, 'found', 'ABC'),
+    ('(?i)a.c', 'AXC', SUCCEED, 'found', 'AXC'),
+    ('(?i)a.*?c', 'AXYZC', SUCCEED, 'found', 'AXYZC'),
+    ('(?i)a.*c', 'AXYZD', FAIL),
+    ('(?i)a[bc]d', 'ABC', FAIL),
+    ('(?i)a[bc]d', 'ABD', SUCCEED, 'found', 'ABD'),
+    ('(?i)a[b-d]e', 'ABD', FAIL),
+    ('(?i)a[b-d]e', 'ACE', SUCCEED, 'found', 'ACE'),
+    ('(?i)a[b-d]', 'AAC', SUCCEED, 'found', 'AC'),
+    ('(?i)a[-b]', 'A-', SUCCEED, 'found', 'A-'),
+    ('(?i)a[b-]', 'A-', SUCCEED, 'found', 'A-'),
+    ('(?i)a[b-a]', '-', SYNTAX_ERROR),
+    ('(?i)a[]b', '-', SYNTAX_ERROR),
+    ('(?i)a[', '-', SYNTAX_ERROR),
+    ('(?i)a]', 'A]', SUCCEED, 'found', 'A]'),
+    ('(?i)a[]]b', 'A]B', SUCCEED, 'found', 'A]B'),
+    ('(?i)a[^bc]d', 'AED', SUCCEED, 'found', 'AED'),
+    ('(?i)a[^bc]d', 'ABD', FAIL),
+    ('(?i)a[^-b]c', 'ADC', SUCCEED, 'found', 'ADC'),
+    ('(?i)a[^-b]c', 'A-C', FAIL),
+    ('(?i)a[^]b]c', 'A]C', FAIL),
+    ('(?i)a[^]b]c', 'ADC', SUCCEED, 'found', 'ADC'),
+    ('(?i)ab|cd', 'ABC', SUCCEED, 'found', 'AB'),
+    ('(?i)ab|cd', 'ABCD', SUCCEED, 'found', 'AB'),
+    ('(?i)()ef', 'DEF', SUCCEED, 'found+"-"+g1', 'EF-'),
+    ('(?i)*a', '-', SYNTAX_ERROR),
+    ('(?i)(*)b', '-', SYNTAX_ERROR),
+    ('(?i)$b', 'B', FAIL),
+    ('(?i)a\\', '-', SYNTAX_ERROR),
+    ('(?i)a\\(b', 'A(B', SUCCEED, 'found+"-"+g1', 'A(B-Error'),
+    ('(?i)a\\(*b', 'AB', SUCCEED, 'found', 'AB'),
+    ('(?i)a\\(*b', 'A((B', SUCCEED, 'found', 'A((B'),
+    ('(?i)a\\\\b', 'A\\B', SUCCEED, 'found', 'A\\B'),
+    ('(?i)abc)', '-', SYNTAX_ERROR),
+    ('(?i)(abc', '-', SYNTAX_ERROR),
+    ('(?i)((a))', 'ABC', SUCCEED, 'found+"-"+g1+"-"+g2', 'A-A-A'),
+    ('(?i)(a)b(c)', 'ABC', SUCCEED, 'found+"-"+g1+"-"+g2', 'ABC-A-C'),
+    ('(?i)a+b+c', 'AABBABC', SUCCEED, 'found', 'ABC'),
+    ('(?i)a{1,}b{1,}c', 'AABBABC', SUCCEED, 'found', 'ABC'),
+    ('(?i)a**', '-', SYNTAX_ERROR),
+    ('(?i)a.+?c', 'ABCABC', SUCCEED, 'found', 'ABC'),
+    ('(?i)a.*?c', 'ABCABC', SUCCEED, 'found', 'ABC'),
+    ('(?i)a.{0,5}?c', 'ABCABC', SUCCEED, 'found', 'ABC'),
+    ('(?i)(a+|b)*', 'AB', SUCCEED, 'found+"-"+g1', 'AB-B'),
+    ('(?i)(a+|b){0,}', 'AB', SUCCEED, 'found+"-"+g1', 'AB-B'),
+    ('(?i)(a+|b)+', 'AB', SUCCEED, 'found+"-"+g1', 'AB-B'),
+    ('(?i)(a+|b){1,}', 'AB', SUCCEED, 'found+"-"+g1', 'AB-B'),
+    ('(?i)(a+|b)?', 'AB', SUCCEED, 'found+"-"+g1', 'A-A'),
+    ('(?i)(a+|b){0,1}', 'AB', SUCCEED, 'found+"-"+g1', 'A-A'),
+    ('(?i)(a+|b){0,1}?', 'AB', SUCCEED, 'found+"-"+g1', '-None'),
+    ('(?i))(', '-', SYNTAX_ERROR),
+    ('(?i)[^ab]*', 'CDE', SUCCEED, 'found', 'CDE'),
+    ('(?i)abc', '', FAIL),
+    ('(?i)a*', '', SUCCEED, 'found', ''),
+    ('(?i)([abc])*d', 'ABBBCD', SUCCEED, 'found+"-"+g1', 'ABBBCD-C'),
+    ('(?i)([abc])*bcd', 'ABCD', SUCCEED, 'found+"-"+g1', 'ABCD-A'),
+    ('(?i)a|b|c|d|e', 'E', SUCCEED, 'found', 'E'),
+    ('(?i)(a|b|c|d|e)f', 'EF', SUCCEED, 'found+"-"+g1', 'EF-E'),
+    ('(?i)abcd*efg', 'ABCDEFG', SUCCEED, 'found', 'ABCDEFG'),
+    ('(?i)ab*', 'XABYABBBZ', SUCCEED, 'found', 'AB'),
+    ('(?i)ab*', 'XAYABBBZ', SUCCEED, 'found', 'A'),
+    ('(?i)(ab|cd)e', 'ABCDE', SUCCEED, 'found+"-"+g1', 'CDE-CD'),
+    ('(?i)[abhgefdc]ij', 'HIJ', SUCCEED, 'found', 'HIJ'),
+    ('(?i)^(ab|cd)e', 'ABCDE', FAIL),
+    ('(?i)(abc|)ef', 'ABCDEF', SUCCEED, 'found+"-"+g1', 'EF-'),
+    ('(?i)(a|b)c*d', 'ABCD', SUCCEED, 'found+"-"+g1', 'BCD-B'),
+    ('(?i)(ab|ab*)bc', 'ABC', SUCCEED, 'found+"-"+g1', 'ABC-A'),
+    ('(?i)a([bc]*)c*', 'ABC', SUCCEED, 'found+"-"+g1', 'ABC-BC'),
+    ('(?i)a([bc]*)(c*d)', 'ABCD', SUCCEED, 'found+"-"+g1+"-"+g2', 'ABCD-BC-D'),
+    ('(?i)a([bc]+)(c*d)', 'ABCD', SUCCEED, 'found+"-"+g1+"-"+g2', 'ABCD-BC-D'),
+    ('(?i)a([bc]*)(c+d)', 'ABCD', SUCCEED, 'found+"-"+g1+"-"+g2', 'ABCD-B-CD'),
+    ('(?i)a[bcd]*dcdcde', 'ADCDCDE', SUCCEED, 'found', 'ADCDCDE'),
+    ('(?i)a[bcd]+dcdcde', 'ADCDCDE', FAIL),
+    ('(?i)(ab|a)b*c', 'ABC', SUCCEED, 'found+"-"+g1', 'ABC-AB'),
+    ('(?i)((a)(b)c)(d)', 'ABCD', SUCCEED, 'g1+"-"+g2+"-"+g3+"-"+g4', 'ABC-A-B-D'),
+    ('(?i)[a-zA-Z_][a-zA-Z0-9_]*', 'ALPHA', SUCCEED, 'found', 'ALPHA'),
+    ('(?i)^a(bc+|b[eh])g|.h$', 'ABH', SUCCEED, 'found+"-"+g1', 'BH-None'),
+    ('(?i)(bc+d$|ef*g.|h?i(j|k))', 'EFFGZ', SUCCEED, 'found+"-"+g1+"-"+g2', 'EFFGZ-EFFGZ-None'),
+    ('(?i)(bc+d$|ef*g.|h?i(j|k))', 'IJ', SUCCEED, 'found+"-"+g1+"-"+g2', 'IJ-IJ-J'),
+    ('(?i)(bc+d$|ef*g.|h?i(j|k))', 'EFFG', FAIL),
+    ('(?i)(bc+d$|ef*g.|h?i(j|k))', 'BCDD', FAIL),
+    ('(?i)(bc+d$|ef*g.|h?i(j|k))', 'REFFGZ', SUCCEED, 'found+"-"+g1+"-"+g2', 'EFFGZ-EFFGZ-None'),
+    ('(?i)((((((((((a))))))))))', 'A', SUCCEED, 'g10', 'A'),
+    ('(?i)((((((((((a))))))))))\\10', 'AA', SUCCEED, 'found', 'AA'),
+    #('(?i)((((((((((a))))))))))\\41', 'AA', FAIL),
+    #('(?i)((((((((((a))))))))))\\41', 'A!', SUCCEED, 'found', 'A!'),
+    ('(?i)(((((((((a)))))))))', 'A', SUCCEED, 'found', 'A'),
+    ('(?i)(?:(?:(?:(?:(?:(?:(?:(?:(?:(a))))))))))', 'A', SUCCEED, 'g1', 'A'),
+    ('(?i)(?:(?:(?:(?:(?:(?:(?:(?:(?:(a|b|c))))))))))', 'C', SUCCEED, 'g1', 'C'),
+    ('(?i)multiple words of text', 'UH-UH', FAIL),
+    ('(?i)multiple words', 'MULTIPLE WORDS, YEAH', SUCCEED, 'found', 'MULTIPLE WORDS'),
+    ('(?i)(.*)c(.*)', 'ABCDE', SUCCEED, 'found+"-"+g1+"-"+g2', 'ABCDE-AB-DE'),
+    ('(?i)\\((.*), (.*)\\)', '(A, B)', SUCCEED, 'g2+"-"+g1', 'B-A'),
+    ('(?i)[k]', 'AB', FAIL),
+#    ('(?i)abcd', 'ABCD', SUCCEED, 'found+"-"+\\found+"-"+\\\\found', 'ABCD-$&-\\ABCD'),
+#    ('(?i)a(bc)d', 'ABCD', SUCCEED, 'g1+"-"+\\g1+"-"+\\\\g1', 'BC-$1-\\BC'),
+    ('(?i)a[-]?c', 'AC', SUCCEED, 'found', 'AC'),
+    ('(?i)(abc)\\1', 'ABCABC', SUCCEED, 'g1', 'ABC'),
+    ('(?i)([a-c]*)\\1', 'ABCABC', SUCCEED, 'g1', 'ABC'),
+    ('a(?!b).', 'abad', SUCCEED, 'found', 'ad'),
+    ('a(?=d).', 'abad', SUCCEED, 'found', 'ad'),
+    ('a(?=c|d).', 'abad', SUCCEED, 'found', 'ad'),
+    ('a(?:b|c|d)(.)', 'ace', SUCCEED, 'g1', 'e'),
+    ('a(?:b|c|d)*(.)', 'ace', SUCCEED, 'g1', 'e'),
+    ('a(?:b|c|d)+?(.)', 'ace', SUCCEED, 'g1', 'e'),
+    ('a(?:b|(c|e){1,2}?|d)+?(.)', 'ace', SUCCEED, 'g1 + g2', 'ce'),
+    ('^(.+)?B', 'AB', SUCCEED, 'g1', 'A'),
+
+    # lookbehind: split by : but not if it is escaped by -.
+    ('(?<!-):(.*?)(?<!-):', 'a:bc-:de:f', SUCCEED, 'g1', 'bc-:de' ),
+    # escaping with \ as we know it
+    ('(?<!\\\):(.*?)(?<!\\\):', 'a:bc\\:de:f', SUCCEED, 'g1', 'bc\\:de' ),
+    # terminating with ' and escaping with ? as in edifact
+    ("(?<!\\?)'(.*?)(?<!\\?)'", "a'bc?'de'f", SUCCEED, 'g1', "bc?'de" ),
+
+    # Comments using the (?#...) syntax
+
+    ('w(?# comment', 'w', SYNTAX_ERROR),
+    ('w(?# comment 1)xy(?# comment 2)z', 'wxyz', SUCCEED, 'found', 'wxyz'),
+
+    # Check odd placement of embedded pattern modifiers
+
+    # not an error under PCRE/PRE:
+    ('w(?i)', 'W', SUCCEED, 'found', 'W'),
+    # ('w(?i)', 'W', SYNTAX_ERROR),
+
+    # Comments using the x embedded pattern modifier
+
+    ("""(?x)w# comment 1
+        x y
+        # comment 2
+        z""", 'wxyz', SUCCEED, 'found', 'wxyz'),
+
+    # using the m embedded pattern modifier
+
+    ('^abc', """jkl
+abc
+xyz""", FAIL),
+    ('(?m)^abc', """jkl
+abc
+xyz""", SUCCEED, 'found', 'abc'),
+
+    ('(?m)abc$', """jkl
+xyzabc
+123""", SUCCEED, 'found', 'abc'),
+
+    # using the s embedded pattern modifier
+
+    ('a.b', 'a\nb', FAIL),
+    ('(?s)a.b', 'a\nb', SUCCEED, 'found', 'a\nb'),
+
+    # test \w, etc. both inside and outside character classes
+
+    ('\\w+', '--ab_cd0123--', SUCCEED, 'found', 'ab_cd0123'),
+    ('[\\w]+', '--ab_cd0123--', SUCCEED, 'found', 'ab_cd0123'),
+    ('\\D+', '1234abc5678', SUCCEED, 'found', 'abc'),
+    ('[\\D]+', '1234abc5678', SUCCEED, 'found', 'abc'),
+    ('[\\da-fA-F]+', '123abc', SUCCEED, 'found', '123abc'),
+    # not an error under PCRE/PRE:
+    # ('[\\d-x]', '-', SYNTAX_ERROR),
+    (r'([\s]*)([\S]*)([\s]*)', ' testing!1972', SUCCEED, 'g3+g2+g1', 'testing!1972 '),
+    (r'(\s*)(\S*)(\s*)', ' testing!1972', SUCCEED, 'g3+g2+g1', 'testing!1972 '),
+
+    (r'\xff', '\377', SUCCEED, 'found', chr(255)),
+    # new \x semantics
+    (r'\x00ff', '\377', FAIL),
+    # (r'\x00ff', '\377', SUCCEED, 'found', chr(255)),
+    (r'\t\n\v\r\f\a\g', '\t\n\v\r\f\ag', SUCCEED, 'found', '\t\n\v\r\f\ag'),
+    ('\t\n\v\r\f\a\g', '\t\n\v\r\f\ag', SUCCEED, 'found', '\t\n\v\r\f\ag'),
+    (r'\t\n\v\r\f\a', '\t\n\v\r\f\a', SUCCEED, 'found', chr(9)+chr(10)+chr(11)+chr(13)+chr(12)+chr(7)),
+    (r'[\t][\n][\v][\r][\f][\b]', '\t\n\v\r\f\b', SUCCEED, 'found', '\t\n\v\r\f\b'),
+
+    #
+    # post-1.5.2 additions
+
+    # xmllib problem
+    (r'(([a-z]+):)?([a-z]+)$', 'smil', SUCCEED, 'g1+"-"+g2+"-"+g3', 'None-None-smil'),
+    # bug 110866: reference to undefined group
+    (r'((.)\1+)', '', SYNTAX_ERROR),
+    # bug 111869: search (PRE/PCRE fails on this one, SRE doesn't)
+    (r'.*d', 'abc\nabd', SUCCEED, 'found', 'abd'),
+    # bug 112468: various expected syntax errors
+    (r'(', '', SYNTAX_ERROR),
+    (r'[\41]', '!', SUCCEED, 'found', '!'),
+    # bug 114033: nothing to repeat
+    (r'(x?)?', 'x', SUCCEED, 'found', 'x'),
+    # bug 115040: rescan if flags are modified inside pattern
+    (r' (?x)foo ', 'foo', SUCCEED, 'found', 'foo'),
+    # bug 115618: negative lookahead
+    (r'(?<!abc)(d.f)', 'abcdefdof', SUCCEED, 'found', 'dof'),
+    # bug 116251: character class bug
+    (r'[\w-]+', 'laser_beam', SUCCEED, 'found', 'laser_beam'),
+    # bug 123769+127259: non-greedy backtracking bug
+    (r'.*?\S *:', 'xx:', SUCCEED, 'found', 'xx:'),
+    (r'a[ ]*?\ (\d+).*', 'a   10', SUCCEED, 'found', 'a   10'),
+    (r'a[ ]*?\ (\d+).*', 'a    10', SUCCEED, 'found', 'a    10'),
+    # bug 127259: \Z shouldn't depend on multiline mode
+    (r'(?ms).*?x\s*\Z(.*)','xx\nx\n', SUCCEED, 'g1', ''),
+    # bug 128899: uppercase literals under the ignorecase flag
+    (r'(?i)M+', 'MMM', SUCCEED, 'found', 'MMM'),
+    (r'(?i)m+', 'MMM', SUCCEED, 'found', 'MMM'),
+    (r'(?i)[M]+', 'MMM', SUCCEED, 'found', 'MMM'),
+    (r'(?i)[m]+', 'MMM', SUCCEED, 'found', 'MMM'),
+    # bug 130748: ^* should be an error (nothing to repeat)
+    (r'^*', '', SYNTAX_ERROR),
+    # bug 133283: minimizing repeat problem
+    (r'"(?:\\"|[^"])*?"', r'"\""', SUCCEED, 'found', r'"\""'),
+    # bug 477728: minimizing repeat problem
+    (r'^.*?$', 'one\ntwo\nthree\n', FAIL),
+    # bug 483789: minimizing repeat problem
+    (r'a[^>]*?b', 'a>b', FAIL),
+    # bug 490573: minimizing repeat problem
+    (r'^a*?$', 'foo', FAIL),
+    # bug 470582: nested groups problem
+    (r'^((a)c)?(ab)$', 'ab', SUCCEED, 'g1+"-"+g2+"-"+g3', 'None-None-ab'),
+    # another minimizing repeat problem (capturing groups in assertions)
+    ('^([ab]*?)(?=(b)?)c', 'abc', SUCCEED, 'g1+"-"+g2', 'ab-None'),
+    ('^([ab]*?)(?!(b))c', 'abc', SUCCEED, 'g1+"-"+g2', 'ab-None'),
+    ('^([ab]*?)(?<!(a))c', 'abc', SUCCEED, 'g1+"-"+g2', 'ab-None'),
+]
+
+try:
+    u = eval("u'\N{LATIN CAPITAL LETTER A WITH DIAERESIS}'")
+except SyntaxError:
+    pass
+else:
+    tests.extend([
+    # bug 410271: \b broken under locales
+    (r'\b.\b', 'a', SUCCEED, 'found', 'a'),
+    (r'(?u)\b.\b', u, SUCCEED, 'found', u),
+    (r'(?u)\w', u, SUCCEED, 'found', u),
+    ])


Property changes on: vendor/Python/current/Lib/test/re_tests.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/test/regex_tests.py
===================================================================
--- vendor/Python/current/Lib/test/regex_tests.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/regex_tests.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,287 @@
+# Regex test suite and benchmark suite v1.5a2
+# Due to the use of r"aw" strings, this file will
+# only work with Python 1.5 or higher.
+
+# The 3 possible outcomes for each pattern
+[SUCCEED, FAIL, SYNTAX_ERROR] = range(3)
+
+# Benchmark suite (needs expansion)
+#
+# The benchmark suite does not test correctness, just speed.  The
+# first element of each tuple is the regex pattern; the second is a
+# string to match it against.  The benchmarking code will embed the
+# second string inside several sizes of padding, to test how regex
+# matching performs on large strings.
+
+benchmarks = [
+        ('Python', 'Python'),                     # Simple text literal
+        ('.*Python', 'Python'),                   # Bad text literal
+        ('.*Python.*', 'Python'),                 # Worse text literal
+        ('.*\\(Python\\)', 'Python'),             # Bad text literal with grouping
+
+        ('(Python\\|Perl\\|Tcl', 'Perl'),          # Alternation
+        ('\\(Python\\|Perl\\|Tcl\\)', 'Perl'),     # Grouped alternation
+        ('\\(Python\\)\\1', 'PythonPython'),       # Backreference
+#       ('\\([0a-z][a-z]*,\\)+', 'a5,b7,c9,'),     # Disable the fastmap optimization
+        ('\\([a-z][a-z0-9]*,\\)+', 'a5,b7,c9,')    # A few sets
+]
+
+# Test suite (for verifying correctness)
+#
+# The test suite is a list of 5- or 3-tuples.  The 5 parts of a
+# complete tuple are:
+# element 0: a string containing the pattern
+#         1: the string to match against the pattern
+#         2: the expected result (SUCCEED, FAIL, SYNTAX_ERROR)
+#         3: a string that will be eval()'ed to produce a test string.
+#            This is an arbitrary Python expression; the available
+#            variables are "found" (the whole match), and "g1", "g2", ...
+#            up to "g10" contain the contents of each group, or the
+#            string 'None' if the group wasn't given a value.
+#         4: The expected result of evaluating the expression.
+#            If the two don't match, an error is reported.
+#
+# If the regex isn't expected to work, the latter two elements can be omitted.
+
+tests = [
+('abc', 'abc', SUCCEED,
+ 'found', 'abc'),
+('abc', 'xbc', FAIL),
+('abc', 'axc', FAIL),
+('abc', 'abx', FAIL),
+('abc', 'xabcy', SUCCEED,
+ 'found', 'abc'),
+('abc', 'ababc', SUCCEED,
+ 'found', 'abc'),
+('ab*c', 'abc', SUCCEED,
+ 'found', 'abc'),
+('ab*bc', 'abc', SUCCEED,
+ 'found', 'abc'),
+('ab*bc', 'abbc', SUCCEED,
+ 'found', 'abbc'),
+('ab*bc', 'abbbbc', SUCCEED,
+ 'found', 'abbbbc'),
+('ab+bc', 'abbc', SUCCEED,
+ 'found', 'abbc'),
+('ab+bc', 'abc', FAIL),
+('ab+bc', 'abq', FAIL),
+('ab+bc', 'abbbbc', SUCCEED,
+ 'found', 'abbbbc'),
+('ab?bc', 'abbc', SUCCEED,
+ 'found', 'abbc'),
+('ab?bc', 'abc', SUCCEED,
+ 'found', 'abc'),
+('ab?bc', 'abbbbc', FAIL),
+('ab?c', 'abc', SUCCEED,
+ 'found', 'abc'),
+('^abc$', 'abc', SUCCEED,
+ 'found', 'abc'),
+('^abc$', 'abcc', FAIL),
+('^abc', 'abcc', SUCCEED,
+ 'found', 'abc'),
+('^abc$', 'aabc', FAIL),
+('abc$', 'aabc', SUCCEED,
+ 'found', 'abc'),
+('^', 'abc', SUCCEED,
+ 'found+"-"', '-'),
+('$', 'abc', SUCCEED,
+ 'found+"-"', '-'),
+('a.c', 'abc', SUCCEED,
+ 'found', 'abc'),
+('a.c', 'axc', SUCCEED,
+ 'found', 'axc'),
+('a.*c', 'axyzc', SUCCEED,
+ 'found', 'axyzc'),
+('a.*c', 'axyzd', FAIL),
+('a[bc]d', 'abc', FAIL),
+('a[bc]d', 'abd', SUCCEED,
+ 'found', 'abd'),
+('a[b-d]e', 'abd', FAIL),
+('a[b-d]e', 'ace', SUCCEED,
+ 'found', 'ace'),
+('a[b-d]', 'aac', SUCCEED,
+ 'found', 'ac'),
+('a[-b]', 'a-', SUCCEED,
+ 'found', 'a-'),
+('a[b-]', 'a-', SUCCEED,
+ 'found', 'a-'),
+('a[]b', '-', SYNTAX_ERROR),
+('a[', '-', SYNTAX_ERROR),
+('a\\', '-', SYNTAX_ERROR),
+('abc\\)', '-', SYNTAX_ERROR),
+('\\(abc', '-', SYNTAX_ERROR),
+('a]', 'a]', SUCCEED,
+ 'found', 'a]'),
+('a[]]b', 'a]b', SUCCEED,
+ 'found', 'a]b'),
+('a[^bc]d', 'aed', SUCCEED,
+ 'found', 'aed'),
+('a[^bc]d', 'abd', FAIL),
+('a[^-b]c', 'adc', SUCCEED,
+ 'found', 'adc'),
+('a[^-b]c', 'a-c', FAIL),
+('a[^]b]c', 'a]c', FAIL),
+('a[^]b]c', 'adc', SUCCEED,
+ 'found', 'adc'),
+('\\ba\\b', 'a-', SUCCEED,
+ '"-"', '-'),
+('\\ba\\b', '-a', SUCCEED,
+ '"-"', '-'),
+('\\ba\\b', '-a-', SUCCEED,
+ '"-"', '-'),
+('\\by\\b', 'xy', FAIL),
+('\\by\\b', 'yz', FAIL),
+('\\by\\b', 'xyz', FAIL),
+('ab\\|cd', 'abc', SUCCEED,
+ 'found', 'ab'),
+('ab\\|cd', 'abcd', SUCCEED,
+ 'found', 'ab'),
+('\\(\\)ef', 'def', SUCCEED,
+ 'found+"-"+g1', 'ef-'),
+('$b', 'b', FAIL),
+('a(b', 'a(b', SUCCEED,
+ 'found+"-"+g1', 'a(b-None'),
+('a(*b', 'ab', SUCCEED,
+ 'found', 'ab'),
+('a(*b', 'a((b', SUCCEED,
+ 'found', 'a((b'),
+('a\\\\b', 'a\\b', SUCCEED,
+ 'found', 'a\\b'),
+('\\(\\(a\\)\\)', 'abc', SUCCEED,
+ 'found+"-"+g1+"-"+g2', 'a-a-a'),
+('\\(a\\)b\\(c\\)', 'abc', SUCCEED,
+ 'found+"-"+g1+"-"+g2', 'abc-a-c'),
+('a+b+c', 'aabbabc', SUCCEED,
+ 'found', 'abc'),
+('\\(a+\\|b\\)*', 'ab', SUCCEED,
+ 'found+"-"+g1', 'ab-b'),
+('\\(a+\\|b\\)+', 'ab', SUCCEED,
+ 'found+"-"+g1', 'ab-b'),
+('\\(a+\\|b\\)?', 'ab', SUCCEED,
+ 'found+"-"+g1', 'a-a'),
+('\\)\\(', '-', SYNTAX_ERROR),
+('[^ab]*', 'cde', SUCCEED,
+ 'found', 'cde'),
+('abc', '', FAIL),
+('a*', '', SUCCEED,
+ 'found', ''),
+('a\\|b\\|c\\|d\\|e', 'e', SUCCEED,
+ 'found', 'e'),
+('\\(a\\|b\\|c\\|d\\|e\\)f', 'ef', SUCCEED,
+ 'found+"-"+g1', 'ef-e'),
+('abcd*efg', 'abcdefg', SUCCEED,
+ 'found', 'abcdefg'),
+('ab*', 'xabyabbbz', SUCCEED,
+ 'found', 'ab'),
+('ab*', 'xayabbbz', SUCCEED,
+ 'found', 'a'),
+('\\(ab\\|cd\\)e', 'abcde', SUCCEED,
+ 'found+"-"+g1', 'cde-cd'),
+('[abhgefdc]ij', 'hij', SUCCEED,
+ 'found', 'hij'),
+('^\\(ab\\|cd\\)e', 'abcde', FAIL,
+ 'xg1y', 'xy'),
+('\\(abc\\|\\)ef', 'abcdef', SUCCEED,
+ 'found+"-"+g1', 'ef-'),
+('\\(a\\|b\\)c*d', 'abcd', SUCCEED,
+ 'found+"-"+g1', 'bcd-b'),
+('\\(ab\\|ab*\\)bc', 'abc', SUCCEED,
+ 'found+"-"+g1', 'abc-a'),
+('a\\([bc]*\\)c*', 'abc', SUCCEED,
+ 'found+"-"+g1', 'abc-bc'),
+('a\\([bc]*\\)\\(c*d\\)', 'abcd', SUCCEED,
+ 'found+"-"+g1+"-"+g2', 'abcd-bc-d'),
+('a\\([bc]+\\)\\(c*d\\)', 'abcd', SUCCEED,
+ 'found+"-"+g1+"-"+g2', 'abcd-bc-d'),
+('a\\([bc]*\\)\\(c+d\\)', 'abcd', SUCCEED,
+ 'found+"-"+g1+"-"+g2', 'abcd-b-cd'),
+('a[bcd]*dcdcde', 'adcdcde', SUCCEED,
+ 'found', 'adcdcde'),
+('a[bcd]+dcdcde', 'adcdcde', FAIL),
+('\\(ab\\|a\\)b*c', 'abc', SUCCEED,
+ 'found+"-"+g1', 'abc-ab'),
+('\\(\\(a\\)\\(b\\)c\\)\\(d\\)', 'abcd', SUCCEED,
+ 'g1+"-"+g2+"-"+g3+"-"+g4', 'abc-a-b-d'),
+('[a-zA-Z_][a-zA-Z0-9_]*', 'alpha', SUCCEED,
+ 'found', 'alpha'),
+('^a\\(bc+\\|b[eh]\\)g\\|.h$', 'abh', SUCCEED,
+ 'found+"-"+g1', 'bh-None'),
+('\\(bc+d$\\|ef*g.\\|h?i\\(j\\|k\\)\\)', 'effgz', SUCCEED,
+ 'found+"-"+g1+"-"+g2', 'effgz-effgz-None'),
+('\\(bc+d$\\|ef*g.\\|h?i\\(j\\|k\\)\\)', 'ij', SUCCEED,
+ 'found+"-"+g1+"-"+g2', 'ij-ij-j'),
+('\\(bc+d$\\|ef*g.\\|h?i\\(j\\|k\\)\\)', 'effg', FAIL),
+('\\(bc+d$\\|ef*g.\\|h?i\\(j\\|k\\)\\)', 'bcdd', FAIL),
+('\\(bc+d$\\|ef*g.\\|h?i\\(j\\|k\\)\\)', 'reffgz', SUCCEED,
+ 'found+"-"+g1+"-"+g2', 'effgz-effgz-None'),
+('\\(\\(\\(\\(\\(\\(\\(\\(\\(a\\)\\)\\)\\)\\)\\)\\)\\)\\)', 'a', SUCCEED,
+ 'found', 'a'),
+('multiple words of text', 'uh-uh', FAIL),
+('multiple words', 'multiple words, yeah', SUCCEED,
+ 'found', 'multiple words'),
+('\\(.*\\)c\\(.*\\)', 'abcde', SUCCEED,
+ 'found+"-"+g1+"-"+g2', 'abcde-ab-de'),
+('(\\(.*\\), \\(.*\\))', '(a, b)', SUCCEED,
+ 'g2+"-"+g1', 'b-a'),
+('[k]', 'ab', FAIL),
+('a[-]?c', 'ac', SUCCEED,
+ 'found', 'ac'),
+('\\(abc\\)\\1', 'abcabc', SUCCEED,
+ 'g1', 'abc'),
+('\\([a-c]*\\)\\1', 'abcabc', SUCCEED,
+ 'g1', 'abc'),
+('^\\(.+\\)?B', 'AB', SUCCEED,
+ 'g1', 'A'),
+('\\(a+\\).\\1$', 'aaaaa', SUCCEED,
+ 'found+"-"+g1', 'aaaaa-aa'),
+('^\\(a+\\).\\1$', 'aaaa', FAIL),
+('\\(abc\\)\\1', 'abcabc', SUCCEED,
+ 'found+"-"+g1', 'abcabc-abc'),
+('\\([a-c]+\\)\\1', 'abcabc', SUCCEED,
+ 'found+"-"+g1', 'abcabc-abc'),
+('\\(a\\)\\1', 'aa', SUCCEED,
+ 'found+"-"+g1', 'aa-a'),
+('\\(a+\\)\\1', 'aa', SUCCEED,
+ 'found+"-"+g1', 'aa-a'),
+('\\(a+\\)+\\1', 'aa', SUCCEED,
+ 'found+"-"+g1', 'aa-a'),
+('\\(a\\).+\\1', 'aba', SUCCEED,
+ 'found+"-"+g1', 'aba-a'),
+('\\(a\\)ba*\\1', 'aba', SUCCEED,
+ 'found+"-"+g1', 'aba-a'),
+('\\(aa\\|a\\)a\\1$', 'aaa', SUCCEED,
+ 'found+"-"+g1', 'aaa-a'),
+('\\(a\\|aa\\)a\\1$', 'aaa', SUCCEED,
+ 'found+"-"+g1', 'aaa-a'),
+('\\(a+\\)a\\1$', 'aaa', SUCCEED,
+ 'found+"-"+g1', 'aaa-a'),
+('\\([abc]*\\)\\1', 'abcabc', SUCCEED,
+ 'found+"-"+g1', 'abcabc-abc'),
+('\\(a\\)\\(b\\)c\\|ab', 'ab', SUCCEED,
+ 'found+"-"+g1+"-"+g2', 'ab-None-None'),
+('\\(a\\)+x', 'aaax', SUCCEED,
+ 'found+"-"+g1', 'aaax-a'),
+('\\([ac]\\)+x', 'aacx', SUCCEED,
+ 'found+"-"+g1', 'aacx-c'),
+('\\([^/]*/\\)*sub1/', 'd:msgs/tdir/sub1/trial/away.cpp', SUCCEED,
+ 'found+"-"+g1', 'd:msgs/tdir/sub1/-tdir/'),
+('\\([^.]*\\)\\.\\([^:]*\\):[T ]+\\(.*\\)', 'track1.title:TBlah blah blah', SUCCEED,
+ 'found+"-"+g1+"-"+g2+"-"+g3', 'track1.title:TBlah blah blah-track1-title-Blah blah blah'),
+('\\([^N]*N\\)+', 'abNNxyzN', SUCCEED,
+ 'found+"-"+g1', 'abNNxyzN-xyzN'),
+('\\([^N]*N\\)+', 'abNNxyz', SUCCEED,
+ 'found+"-"+g1', 'abNN-N'),
+('\\([abc]*\\)x', 'abcx', SUCCEED,
+ 'found+"-"+g1', 'abcx-abc'),
+('\\([abc]*\\)x', 'abc', FAIL),
+('\\([xyz]*\\)x', 'abcx', SUCCEED,
+ 'found+"-"+g1', 'x-'),
+('\\(a\\)+b\\|aac', 'aac', SUCCEED,
+ 'found+"-"+g1', 'aac-None'),
+('\<a', 'a', SUCCEED, 'found', 'a'),
+('\<a', '!', FAIL),
+('a\<b', 'ab', FAIL),
+('a\>', 'ab', FAIL),
+('a\>', 'a!', SUCCEED, 'found', 'a'),
+('a\>', 'a', SUCCEED, 'found', 'a'),
+]

Added: vendor/Python/current/Lib/test/regrtest.py
===================================================================
--- vendor/Python/current/Lib/test/regrtest.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/regrtest.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1384 @@
+#! /usr/bin/env python
+
+"""Regression test.
+
+This will find all modules whose name is "test_*" in the test
+directory, and run them.  Various command line options provide
+additional facilities.
+
+Command line options:
+
+-v: verbose    -- run tests in verbose mode with output to stdout
+-w: verbose2   -- re-run failed tests in verbose mode
+-q: quiet      -- don't print anything except if a test fails
+-g: generate   -- write the output file for a test instead of comparing it
+-x: exclude    -- arguments are tests to *exclude*
+-s: single     -- run only a single test (see below)
+-r: random     -- randomize test execution order
+-f: fromfile   -- read names of tests to run from a file (see below)
+-l: findleaks  -- if GC is available detect tests that leak memory
+-u: use        -- specify which special resource intensive tests to run
+-h: help       -- print this text and exit
+-t: threshold  -- call gc.set_threshold(N)
+-T: coverage   -- turn on code coverage using the trace module
+-D: coverdir   -- Directory where coverage files are put
+-N: nocoverdir -- Put coverage files alongside modules
+-L: runleaks   -- run the leaks(1) command just before exit
+-R: huntrleaks -- search for reference leaks (needs debug build, v. slow)
+-M: memlimit   -- run very large memory-consuming tests
+
+If non-option arguments are present, they are names for tests to run,
+unless -x is given, in which case they are names for tests not to run.
+If no test names are given, all tests are run.
+
+-v is incompatible with -g and does not compare test output files.
+
+-T turns on code coverage tracing with the trace module.
+
+-D specifies the directory where coverage files are put.
+
+-N Put coverage files alongside modules.
+
+-s means to run only a single test and exit.  This is useful when
+doing memory analysis on the Python interpreter (which tend to consume
+too many resources to run the full regression test non-stop).  The
+file /tmp/pynexttest is read to find the next test to run.  If this
+file is missing, the first test_*.py file in testdir or on the command
+line is used.  (actually tempfile.gettempdir() is used instead of
+/tmp).
+
+-f reads the names of tests from the file given as f's argument, one
+or more test names per line.  Whitespace is ignored.  Blank lines and
+lines beginning with '#' are ignored.  This is especially useful for
+whittling down failures involving interactions among tests.
+
+-L causes the leaks(1) command to be run just before exit if it exists.
+leaks(1) is available on Mac OS X and presumably on some other
+FreeBSD-derived systems.
+
+-R runs each test several times and examines sys.gettotalrefcount() to
+see if the test appears to be leaking references.  The argument should
+be of the form stab:run:fname where 'stab' is the number of times the
+test is run to let gettotalrefcount settle down, 'run' is the number
+of times further it is run and 'fname' is the name of the file the
+reports are written to.  These parameters all have defaults (5, 4 and
+"reflog.txt" respectively), so the minimal invocation is '-R ::'.
+
+-M runs tests that require an exorbitant amount of memory. These tests
+typically try to ascertain containers keep working when containing more than
+2 billion objects, which only works on 64-bit systems. There are also some
+tests that try to exhaust the address space of the process, which only makes
+sense on 32-bit systems with at least 2Gb of memory. The passed-in memlimit,
+which is a string in the form of '2.5Gb', determines howmuch memory the
+tests will limit themselves to (but they may go slightly over.) The number
+shouldn't be more memory than the machine has (including swap memory). You
+should also keep in mind that swap memory is generally much, much slower
+than RAM, and setting memlimit to all available RAM or higher will heavily
+tax the machine. On the other hand, it is no use running these tests with a
+limit of less than 2.5Gb, and many require more than 20Gb. Tests that expect
+to use more than memlimit memory will be skipped. The big-memory tests
+generally run very, very long.
+
+-u is used to specify which special resource intensive tests to run,
+such as those requiring large file support or network connectivity.
+The argument is a comma-separated list of words indicating the
+resources to test.  Currently only the following are defined:
+
+    all -       Enable all special resources.
+
+    audio -     Tests that use the audio device.  (There are known
+                cases of broken audio drivers that can crash Python or
+                even the Linux kernel.)
+
+    curses -    Tests that use curses and will modify the terminal's
+                state and output modes.
+
+    largefile - It is okay to run some test that may create huge
+                files.  These tests can take a long time and may
+                consume >2GB of disk space temporarily.
+
+    network -   It is okay to run tests that use external network
+                resource, e.g. testing SSL support for sockets.
+
+    bsddb -     It is okay to run the bsddb testsuite, which takes
+                a long time to complete.
+
+    decimal -   Test the decimal module against a large suite that
+                verifies compliance with standards.
+
+    compiler -  Test the compiler package by compiling all the source
+                in the standard library and test suite.  This takes
+                a long time.  Enabling this resource also allows
+                test_tokenize to verify round-trip lexing on every
+                file in the test library.
+
+    subprocess  Run all tests for the subprocess module.
+
+    urlfetch -  It is okay to download files required on testing.
+
+To enable all resources except one, use '-uall,-<resource>'.  For
+example, to run all the tests except for the bsddb tests, give the
+option '-uall,-bsddb'.
+"""
+
+import os
+import sys
+import getopt
+import random
+import warnings
+import re
+import cStringIO
+import traceback
+
+# I see no other way to suppress these warnings;
+# putting them in test_grammar.py has no effect:
+warnings.filterwarnings("ignore", "hex/oct constants", FutureWarning,
+                        ".*test.test_grammar$")
+if sys.maxint > 0x7fffffff:
+    # Also suppress them in <string>, because for 64-bit platforms,
+    # that's where test_grammar.py hides them.
+    warnings.filterwarnings("ignore", "hex/oct constants", FutureWarning,
+                            "<string>")
+
+# Ignore ImportWarnings that only occur in the source tree,
+# (because of modules with the same name as source-directories in Modules/)
+for mod in ("ctypes", "gzip", "zipfile", "tarfile", "encodings.zlib_codec",
+            "test.test_zipimport", "test.test_zlib", "test.test_zipfile",
+            "test.test_codecs", "test.string_tests"):
+    warnings.filterwarnings(module=".*%s$" % (mod,),
+                            action="ignore", category=ImportWarning)
+
+# MacOSX (a.k.a. Darwin) has a default stack size that is too small
+# for deeply recursive regular expressions.  We see this as crashes in
+# the Python test suite when running test_re.py and test_sre.py.  The
+# fix is to set the stack limit to 2048.
+# This approach may also be useful for other Unixy platforms that
+# suffer from small default stack limits.
+if sys.platform == 'darwin':
+    try:
+        import resource
+    except ImportError:
+        pass
+    else:
+        soft, hard = resource.getrlimit(resource.RLIMIT_STACK)
+        newsoft = min(hard, max(soft, 1024*2048))
+        resource.setrlimit(resource.RLIMIT_STACK, (newsoft, hard))
+
+from test import test_support
+
+RESOURCE_NAMES = ('audio', 'curses', 'largefile', 'network', 'bsddb',
+                  'decimal', 'compiler', 'subprocess', 'urlfetch')
+
+
+def usage(code, msg=''):
+    print __doc__
+    if msg: print msg
+    sys.exit(code)
+
+
+def main(tests=None, testdir=None, verbose=0, quiet=False, generate=False,
+         exclude=False, single=False, randomize=False, fromfile=None,
+         findleaks=False, use_resources=None, trace=False, coverdir='coverage',
+         runleaks=False, huntrleaks=False, verbose2=False):
+    """Execute a test suite.
+
+    This also parses command-line options and modifies its behavior
+    accordingly.
+
+    tests -- a list of strings containing test names (optional)
+    testdir -- the directory in which to look for tests (optional)
+
+    Users other than the Python test suite will certainly want to
+    specify testdir; if it's omitted, the directory containing the
+    Python test suite is searched for.
+
+    If the tests argument is omitted, the tests listed on the
+    command-line will be used.  If that's empty, too, then all *.py
+    files beginning with test_ will be used.
+
+    The other default arguments (verbose, quiet, generate, exclude, single,
+    randomize, findleaks, use_resources, trace and coverdir) allow programmers
+    calling main() directly to set the values that would normally be set by
+    flags on the command line.
+    """
+
+    test_support.record_original_stdout(sys.stdout)
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], 'hvgqxsrf:lu:t:TD:NLR:wM:',
+                                   ['help', 'verbose', 'quiet', 'generate',
+                                    'exclude', 'single', 'random', 'fromfile',
+                                    'findleaks', 'use=', 'threshold=', 'trace',
+                                    'coverdir=', 'nocoverdir', 'runleaks',
+                                    'huntrleaks=', 'verbose2', 'memlimit=',
+                                    ])
+    except getopt.error, msg:
+        usage(2, msg)
+
+    # Defaults
+    if use_resources is None:
+        use_resources = []
+    for o, a in opts:
+        if o in ('-h', '--help'):
+            usage(0)
+        elif o in ('-v', '--verbose'):
+            verbose += 1
+        elif o in ('-w', '--verbose2'):
+            verbose2 = True
+        elif o in ('-q', '--quiet'):
+            quiet = True;
+            verbose = 0
+        elif o in ('-g', '--generate'):
+            generate = True
+        elif o in ('-x', '--exclude'):
+            exclude = True
+        elif o in ('-s', '--single'):
+            single = True
+        elif o in ('-r', '--randomize'):
+            randomize = True
+        elif o in ('-f', '--fromfile'):
+            fromfile = a
+        elif o in ('-l', '--findleaks'):
+            findleaks = True
+        elif o in ('-L', '--runleaks'):
+            runleaks = True
+        elif o in ('-t', '--threshold'):
+            import gc
+            gc.set_threshold(int(a))
+        elif o in ('-T', '--coverage'):
+            trace = True
+        elif o in ('-D', '--coverdir'):
+            coverdir = os.path.join(os.getcwd(), a)
+        elif o in ('-N', '--nocoverdir'):
+            coverdir = None
+        elif o in ('-R', '--huntrleaks'):
+            huntrleaks = a.split(':')
+            if len(huntrleaks) != 3:
+                print a, huntrleaks
+                usage(2, '-R takes three colon-separated arguments')
+            if len(huntrleaks[0]) == 0:
+                huntrleaks[0] = 5
+            else:
+                huntrleaks[0] = int(huntrleaks[0])
+            if len(huntrleaks[1]) == 0:
+                huntrleaks[1] = 4
+            else:
+                huntrleaks[1] = int(huntrleaks[1])
+            if len(huntrleaks[2]) == 0:
+                huntrleaks[2] = "reflog.txt"
+        elif o in ('-M', '--memlimit'):
+            test_support.set_memlimit(a)
+        elif o in ('-u', '--use'):
+            u = [x.lower() for x in a.split(',')]
+            for r in u:
+                if r == 'all':
+                    use_resources[:] = RESOURCE_NAMES
+                    continue
+                remove = False
+                if r[0] == '-':
+                    remove = True
+                    r = r[1:]
+                if r not in RESOURCE_NAMES:
+                    usage(1, 'Invalid -u/--use option: ' + a)
+                if remove:
+                    if r in use_resources:
+                        use_resources.remove(r)
+                elif r not in use_resources:
+                    use_resources.append(r)
+    if generate and verbose:
+        usage(2, "-g and -v don't go together!")
+    if single and fromfile:
+        usage(2, "-s and -f don't go together!")
+
+    good = []
+    bad = []
+    skipped = []
+    resource_denieds = []
+
+    if findleaks:
+        try:
+            import gc
+        except ImportError:
+            print 'No GC available, disabling findleaks.'
+            findleaks = False
+        else:
+            # Uncomment the line below to report garbage that is not
+            # freeable by reference counting alone.  By default only
+            # garbage that is not collectable by the GC is reported.
+            #gc.set_debug(gc.DEBUG_SAVEALL)
+            found_garbage = []
+
+    if single:
+        from tempfile import gettempdir
+        filename = os.path.join(gettempdir(), 'pynexttest')
+        try:
+            fp = open(filename, 'r')
+            next = fp.read().strip()
+            tests = [next]
+            fp.close()
+        except IOError:
+            pass
+
+    if fromfile:
+        tests = []
+        fp = open(fromfile)
+        for line in fp:
+            guts = line.split() # assuming no test has whitespace in its name
+            if guts and not guts[0].startswith('#'):
+                tests.extend(guts)
+        fp.close()
+
+    # Strip .py extensions.
+    if args:
+        args = map(removepy, args)
+    if tests:
+        tests = map(removepy, tests)
+
+    stdtests = STDTESTS[:]
+    nottests = NOTTESTS[:]
+    if exclude:
+        for arg in args:
+            if arg in stdtests:
+                stdtests.remove(arg)
+        nottests[:0] = args
+        args = []
+    tests = tests or args or findtests(testdir, stdtests, nottests)
+    if single:
+        tests = tests[:1]
+    if randomize:
+        random.shuffle(tests)
+    if trace:
+        import trace
+        tracer = trace.Trace(ignoredirs=[sys.prefix, sys.exec_prefix],
+                             trace=False, count=True)
+    test_support.verbose = verbose      # Tell tests to be moderately quiet
+    test_support.use_resources = use_resources
+    save_modules = sys.modules.keys()
+    for test in tests:
+        if not quiet:
+            print test
+            sys.stdout.flush()
+        if trace:
+            # If we're tracing code coverage, then we don't exit with status
+            # if on a false return value from main.
+            tracer.runctx('runtest(test, generate, verbose, quiet, testdir)',
+                          globals=globals(), locals=vars())
+        else:
+            try:
+                ok = runtest(test, generate, verbose, quiet, testdir,
+                             huntrleaks)
+            except KeyboardInterrupt:
+                # print a newline separate from the ^C
+                print
+                break
+            except:
+                raise
+            if ok > 0:
+                good.append(test)
+            elif ok == 0:
+                bad.append(test)
+            else:
+                skipped.append(test)
+                if ok == -2:
+                    resource_denieds.append(test)
+        if findleaks:
+            gc.collect()
+            if gc.garbage:
+                print "Warning: test created", len(gc.garbage),
+                print "uncollectable object(s)."
+                # move the uncollectable objects somewhere so we don't see
+                # them again
+                found_garbage.extend(gc.garbage)
+                del gc.garbage[:]
+        # Unload the newly imported modules (best effort finalization)
+        for module in sys.modules.keys():
+            if module not in save_modules and module.startswith("test."):
+                test_support.unload(module)
+
+    # The lists won't be sorted if running with -r
+    good.sort()
+    bad.sort()
+    skipped.sort()
+
+    if good and not quiet:
+        if not bad and not skipped and len(good) > 1:
+            print "All",
+        print count(len(good), "test"), "OK."
+        if verbose:
+            print "CAUTION:  stdout isn't compared in verbose mode:"
+            print "a test that passes in verbose mode may fail without it."
+    if bad:
+        print count(len(bad), "test"), "failed:"
+        printlist(bad)
+    if skipped and not quiet:
+        print count(len(skipped), "test"), "skipped:"
+        printlist(skipped)
+
+        e = _ExpectedSkips()
+        plat = sys.platform
+        if e.isvalid():
+            surprise = set(skipped) - e.getexpected() - set(resource_denieds)
+            if surprise:
+                print count(len(surprise), "skip"), \
+                      "unexpected on", plat + ":"
+                printlist(surprise)
+            else:
+                print "Those skips are all expected on", plat + "."
+        else:
+            print "Ask someone to teach regrtest.py about which tests are"
+            print "expected to get skipped on", plat + "."
+
+    if verbose2 and bad:
+        print "Re-running failed tests in verbose mode"
+        for test in bad:
+            print "Re-running test %r in verbose mode" % test
+            sys.stdout.flush()
+            try:
+                test_support.verbose = 1
+                ok = runtest(test, generate, 1, quiet, testdir,
+                             huntrleaks)
+            except KeyboardInterrupt:
+                # print a newline separate from the ^C
+                print
+                break
+            except:
+                raise
+
+    if single:
+        alltests = findtests(testdir, stdtests, nottests)
+        for i in range(len(alltests)):
+            if tests[0] == alltests[i]:
+                if i == len(alltests) - 1:
+                    os.unlink(filename)
+                else:
+                    fp = open(filename, 'w')
+                    fp.write(alltests[i+1] + '\n')
+                    fp.close()
+                break
+        else:
+            os.unlink(filename)
+
+    if trace:
+        r = tracer.results()
+        r.write_results(show_missing=True, summary=True, coverdir=coverdir)
+
+    if runleaks:
+        os.system("leaks %d" % os.getpid())
+
+    sys.exit(len(bad) > 0)
+
+
+STDTESTS = [
+    'test_grammar',
+    'test_opcodes',
+    'test_operations',
+    'test_builtin',
+    'test_exceptions',
+    'test_types',
+    'test_unittest',
+    'test_doctest',
+    'test_doctest2',
+   ]
+
+NOTTESTS = [
+    'test_support',
+    'test_future1',
+    'test_future2',
+    'test_future3',
+    ]
+
+def findtests(testdir=None, stdtests=STDTESTS, nottests=NOTTESTS):
+    """Return a list of all applicable test modules."""
+    if not testdir: testdir = findtestdir()
+    names = os.listdir(testdir)
+    tests = []
+    for name in names:
+        if name[:5] == "test_" and name[-3:] == os.extsep+"py":
+            modname = name[:-3]
+            if modname not in stdtests and modname not in nottests:
+                tests.append(modname)
+    tests.sort()
+    return stdtests + tests
+
+def runtest(test, generate, verbose, quiet, testdir=None, huntrleaks=False):
+    """Run a single test.
+
+    test -- the name of the test
+    generate -- if true, generate output, instead of running the test
+                and comparing it to a previously created output file
+    verbose -- if true, print more messages
+    quiet -- if true, don't print 'skipped' messages (probably redundant)
+    testdir -- test directory
+    huntrleaks -- run multiple times to test for leaks; requires a debug
+                  build; a triple corresponding to -R's three arguments
+    Return:
+        -2  test skipped because resource denied
+        -1  test skipped for some other reason
+         0  test failed
+         1  test passed
+    """
+
+    try:
+        return runtest_inner(test, generate, verbose, quiet, testdir,
+                             huntrleaks)
+    finally:
+        cleanup_test_droppings(test, verbose)
+
+def runtest_inner(test, generate, verbose, quiet,
+                     testdir=None, huntrleaks=False):
+    test_support.unload(test)
+    if not testdir:
+        testdir = findtestdir()
+    outputdir = os.path.join(testdir, "output")
+    outputfile = os.path.join(outputdir, test)
+    if verbose:
+        cfp = None
+    else:
+        cfp = cStringIO.StringIO()
+
+    try:
+        save_stdout = sys.stdout
+        try:
+            if cfp:
+                sys.stdout = cfp
+                print test              # Output file starts with test name
+            if test.startswith('test.'):
+                abstest = test
+            else:
+                # Always import it from the test package
+                abstest = 'test.' + test
+            the_package = __import__(abstest, globals(), locals(), [])
+            the_module = getattr(the_package, test)
+            # Most tests run to completion simply as a side-effect of
+            # being imported.  For the benefit of tests that can't run
+            # that way (like test_threaded_import), explicitly invoke
+            # their test_main() function (if it exists).
+            indirect_test = getattr(the_module, "test_main", None)
+            if indirect_test is not None:
+                indirect_test()
+            if huntrleaks:
+                dash_R(the_module, test, indirect_test, huntrleaks)
+        finally:
+            sys.stdout = save_stdout
+    except test_support.ResourceDenied, msg:
+        if not quiet:
+            print test, "skipped --", msg
+            sys.stdout.flush()
+        return -2
+    except (ImportError, test_support.TestSkipped), msg:
+        if not quiet:
+            print test, "skipped --", msg
+            sys.stdout.flush()
+        return -1
+    except KeyboardInterrupt:
+        raise
+    except test_support.TestFailed, msg:
+        print "test", test, "failed --", msg
+        sys.stdout.flush()
+        return 0
+    except:
+        type, value = sys.exc_info()[:2]
+        print "test", test, "crashed --", str(type) + ":", value
+        sys.stdout.flush()
+        if verbose:
+            traceback.print_exc(file=sys.stdout)
+            sys.stdout.flush()
+        return 0
+    else:
+        if not cfp:
+            return 1
+        output = cfp.getvalue()
+        if generate:
+            if output == test + "\n":
+                if os.path.exists(outputfile):
+                    # Write it since it already exists (and the contents
+                    # may have changed), but let the user know it isn't
+                    # needed:
+                    print "output file", outputfile, \
+                          "is no longer needed; consider removing it"
+                else:
+                    # We don't need it, so don't create it.
+                    return 1
+            fp = open(outputfile, "w")
+            fp.write(output)
+            fp.close()
+            return 1
+        if os.path.exists(outputfile):
+            fp = open(outputfile, "r")
+            expected = fp.read()
+            fp.close()
+        else:
+            expected = test + "\n"
+        if output == expected or huntrleaks:
+            return 1
+        print "test", test, "produced unexpected output:"
+        sys.stdout.flush()
+        reportdiff(expected, output)
+        sys.stdout.flush()
+        return 0
+
+def cleanup_test_droppings(testname, verbose):
+    import shutil
+
+    # Try to clean up junk commonly left behind.  While tests shouldn't leave
+    # any files or directories behind, when a test fails that can be tedious
+    # for it to arrange.  The consequences can be especially nasty on Windows,
+    # since if a test leaves a file open, it cannot be deleted by name (while
+    # there's nothing we can do about that here either, we can display the
+    # name of the offending test, which is a real help).
+    for name in (test_support.TESTFN,
+                 "db_home",
+                ):
+        if not os.path.exists(name):
+            continue
+
+        if os.path.isdir(name):
+            kind, nuker = "directory", shutil.rmtree
+        elif os.path.isfile(name):
+            kind, nuker = "file", os.unlink
+        else:
+            raise SystemError("os.path says %r exists but is neither "
+                              "directory nor file" % name)
+
+        if verbose:
+            print "%r left behind %s %r" % (testname, kind, name)
+        try:
+            nuker(name)
+        except Exception, msg:
+            print >> sys.stderr, ("%r left behind %s %r and it couldn't be "
+                "removed: %s" % (testname, kind, name, msg))
+
+def dash_R(the_module, test, indirect_test, huntrleaks):
+    # This code is hackish and inelegant, but it seems to do the job.
+    import copy_reg
+
+    if not hasattr(sys, 'gettotalrefcount'):
+        raise Exception("Tracking reference leaks requires a debug build "
+                        "of Python")
+
+    # Save current values for dash_R_cleanup() to restore.
+    fs = warnings.filters[:]
+    ps = copy_reg.dispatch_table.copy()
+    pic = sys.path_importer_cache.copy()
+
+    if indirect_test:
+        def run_the_test():
+            indirect_test()
+    else:
+        def run_the_test():
+            reload(the_module)
+
+    deltas = []
+    nwarmup, ntracked, fname = huntrleaks
+    repcount = nwarmup + ntracked
+    print >> sys.stderr, "beginning", repcount, "repetitions"
+    print >> sys.stderr, ("1234567890"*(repcount//10 + 1))[:repcount]
+    dash_R_cleanup(fs, ps, pic)
+    for i in range(repcount):
+        rc = sys.gettotalrefcount()
+        run_the_test()
+        sys.stderr.write('.')
+        dash_R_cleanup(fs, ps, pic)
+        if i >= nwarmup:
+            deltas.append(sys.gettotalrefcount() - rc - 2)
+    print >> sys.stderr
+    if any(deltas):
+        print >> sys.stderr, test, 'leaked', deltas, 'references'
+        refrep = open(fname, "a")
+        print >> refrep, test, 'leaked', deltas, 'references'
+        refrep.close()
+
+def dash_R_cleanup(fs, ps, pic):
+    import gc, copy_reg
+    import _strptime, linecache, dircache
+    import urlparse, urllib, urllib2, mimetypes, doctest
+    import struct, filecmp
+    from distutils.dir_util import _path_created
+
+    # Restore some original values.
+    warnings.filters[:] = fs
+    copy_reg.dispatch_table.clear()
+    copy_reg.dispatch_table.update(ps)
+    sys.path_importer_cache.clear()
+    sys.path_importer_cache.update(pic)
+
+    # Clear assorted module caches.
+    _path_created.clear()
+    re.purge()
+    _strptime._regex_cache.clear()
+    urlparse.clear_cache()
+    urllib.urlcleanup()
+    urllib2.install_opener(None)
+    dircache.reset()
+    linecache.clearcache()
+    mimetypes._default_mime_types()
+    struct._cache.clear()
+    filecmp._cache.clear()
+    doctest.master = None
+
+    # Collect cyclic trash.
+    gc.collect()
+
+def reportdiff(expected, output):
+    import difflib
+    print "*" * 70
+    a = expected.splitlines(1)
+    b = output.splitlines(1)
+    sm = difflib.SequenceMatcher(a=a, b=b)
+    tuples = sm.get_opcodes()
+
+    def pair(x0, x1):
+        # x0:x1 are 0-based slice indices; convert to 1-based line indices.
+        x0 += 1
+        if x0 >= x1:
+            return "line " + str(x0)
+        else:
+            return "lines %d-%d" % (x0, x1)
+
+    for op, a0, a1, b0, b1 in tuples:
+        if op == 'equal':
+            pass
+
+        elif op == 'delete':
+            print "***", pair(a0, a1), "of expected output missing:"
+            for line in a[a0:a1]:
+                print "-", line,
+
+        elif op == 'replace':
+            print "*** mismatch between", pair(a0, a1), "of expected", \
+                  "output and", pair(b0, b1), "of actual output:"
+            for line in difflib.ndiff(a[a0:a1], b[b0:b1]):
+                print line,
+
+        elif op == 'insert':
+            print "***", pair(b0, b1), "of actual output doesn't appear", \
+                  "in expected output after line", str(a1)+":"
+            for line in b[b0:b1]:
+                print "+", line,
+
+        else:
+            print "get_opcodes() returned bad tuple?!?!", (op, a0, a1, b0, b1)
+
+    print "*" * 70
+
+def findtestdir():
+    if __name__ == '__main__':
+        file = sys.argv[0]
+    else:
+        file = __file__
+    testdir = os.path.dirname(file) or os.curdir
+    return testdir
+
+def removepy(name):
+    if name.endswith(os.extsep + "py"):
+        name = name[:-3]
+    return name
+
+def count(n, word):
+    if n == 1:
+        return "%d %s" % (n, word)
+    else:
+        return "%d %ss" % (n, word)
+
+def printlist(x, width=70, indent=4):
+    """Print the elements of iterable x to stdout.
+
+    Optional arg width (default 70) is the maximum line length.
+    Optional arg indent (default 4) is the number of blanks with which to
+    begin each line.
+    """
+
+    from textwrap import fill
+    blanks = ' ' * indent
+    print fill(' '.join(map(str, x)), width,
+               initial_indent=blanks, subsequent_indent=blanks)
+
+# Map sys.platform to a string containing the basenames of tests
+# expected to be skipped on that platform.
+#
+# Special cases:
+#     test_pep277
+#         The _ExpectedSkips constructor adds this to the set of expected
+#         skips if not os.path.supports_unicode_filenames.
+#     test_socket_ssl
+#         Controlled by test_socket_ssl.skip_expected.  Requires the network
+#         resource, and a socket module with ssl support.
+#     test_timeout
+#         Controlled by test_timeout.skip_expected.  Requires the network
+#         resource and a socket module.
+
+_expectations = {
+    'win32':
+        """
+        test__locale
+        test_applesingle
+        test_al
+        test_bsddb185
+        test_bsddb3
+        test_cd
+        test_cl
+        test_commands
+        test_crypt
+        test_curses
+        test_dbm
+        test_dl
+        test_fcntl
+        test_fork1
+        test_gdbm
+        test_gl
+        test_grp
+        test_imgfile
+        test_ioctl
+        test_largefile
+        test_linuxaudiodev
+        test_mhlib
+        test_nis
+        test_openpty
+        test_ossaudiodev
+        test_poll
+        test_posix
+        test_pty
+        test_pwd
+        test_resource
+        test_signal
+        test_sunaudiodev
+        test_threadsignals
+        test_timing
+        test_wait3
+        test_wait4
+        """,
+    'linux2':
+        """
+        test_al
+        test_applesingle
+        test_bsddb185
+        test_cd
+        test_cl
+        test_curses
+        test_dl
+        test_gl
+        test_imgfile
+        test_largefile
+        test_linuxaudiodev
+        test_nis
+        test_ntpath
+        test_ossaudiodev
+        test_sqlite
+        test_startfile
+        test_sunaudiodev
+        """,
+   'mac':
+        """
+        test_al
+        test_atexit
+        test_bsddb
+        test_bsddb185
+        test_bsddb3
+        test_bz2
+        test_cd
+        test_cl
+        test_commands
+        test_crypt
+        test_curses
+        test_dbm
+        test_dl
+        test_fcntl
+        test_fork1
+        test_gl
+        test_grp
+        test_ioctl
+        test_imgfile
+        test_largefile
+        test_linuxaudiodev
+        test_locale
+        test_mmap
+        test_nis
+        test_ntpath
+        test_openpty
+        test_ossaudiodev
+        test_poll
+        test_popen
+        test_popen2
+        test_posix
+        test_pty
+        test_pwd
+        test_resource
+        test_signal
+        test_sqlite
+        test_startfile
+        test_sunaudiodev
+        test_sundry
+        test_tarfile
+        test_timing
+        """,
+    'unixware7':
+        """
+        test_al
+        test_applesingle
+        test_bsddb
+        test_bsddb185
+        test_cd
+        test_cl
+        test_dl
+        test_gl
+        test_imgfile
+        test_largefile
+        test_linuxaudiodev
+        test_minidom
+        test_nis
+        test_ntpath
+        test_openpty
+        test_pyexpat
+        test_sax
+        test_startfile
+        test_sqlite
+        test_sunaudiodev
+        test_sundry
+        """,
+    'openunix8':
+        """
+        test_al
+        test_applesingle
+        test_bsddb
+        test_bsddb185
+        test_cd
+        test_cl
+        test_dl
+        test_gl
+        test_imgfile
+        test_largefile
+        test_linuxaudiodev
+        test_minidom
+        test_nis
+        test_ntpath
+        test_openpty
+        test_pyexpat
+        test_sax
+        test_sqlite
+        test_startfile
+        test_sunaudiodev
+        test_sundry
+        """,
+    'sco_sv3':
+        """
+        test_al
+        test_applesingle
+        test_asynchat
+        test_bsddb
+        test_bsddb185
+        test_cd
+        test_cl
+        test_dl
+        test_fork1
+        test_gettext
+        test_gl
+        test_imgfile
+        test_largefile
+        test_linuxaudiodev
+        test_locale
+        test_minidom
+        test_nis
+        test_ntpath
+        test_openpty
+        test_pyexpat
+        test_queue
+        test_sax
+        test_sqlite
+        test_startfile
+        test_sunaudiodev
+        test_sundry
+        test_thread
+        test_threaded_import
+        test_threadedtempfile
+        test_threading
+        """,
+    'riscos':
+        """
+        test_al
+        test_applesingle
+        test_asynchat
+        test_atexit
+        test_bsddb
+        test_bsddb185
+        test_bsddb3
+        test_cd
+        test_cl
+        test_commands
+        test_crypt
+        test_dbm
+        test_dl
+        test_fcntl
+        test_fork1
+        test_gdbm
+        test_gl
+        test_grp
+        test_imgfile
+        test_largefile
+        test_linuxaudiodev
+        test_locale
+        test_mmap
+        test_nis
+        test_ntpath
+        test_openpty
+        test_poll
+        test_popen2
+        test_pty
+        test_pwd
+        test_strop
+        test_sqlite
+        test_startfile
+        test_sunaudiodev
+        test_sundry
+        test_thread
+        test_threaded_import
+        test_threadedtempfile
+        test_threading
+        test_timing
+        """,
+    'darwin':
+        """
+        test__locale
+        test_al
+        test_bsddb
+        test_bsddb3
+        test_cd
+        test_cl
+        test_curses
+        test_gdbm
+        test_gl
+        test_imgfile
+        test_largefile
+        test_linuxaudiodev
+        test_locale
+        test_minidom
+        test_nis
+        test_ntpath
+        test_ossaudiodev
+        test_poll
+        test_sqlite
+        test_startfile
+        test_sunaudiodev
+        """,
+    'sunos5':
+        """
+        test_al
+        test_applesingle
+        test_bsddb
+        test_bsddb185
+        test_cd
+        test_cl
+        test_curses
+        test_dbm
+        test_gdbm
+        test_gl
+        test_gzip
+        test_imgfile
+        test_linuxaudiodev
+        test_openpty
+        test_sqlite
+        test_startfile
+        test_zipfile
+        test_zlib
+        """,
+    'hp-ux11':
+        """
+        test_al
+        test_applesingle
+        test_bsddb
+        test_bsddb185
+        test_cd
+        test_cl
+        test_curses
+        test_dl
+        test_gdbm
+        test_gl
+        test_gzip
+        test_imgfile
+        test_largefile
+        test_linuxaudiodev
+        test_locale
+        test_minidom
+        test_nis
+        test_ntpath
+        test_openpty
+        test_pyexpat
+        test_sax
+        test_sqlite
+        test_startfile
+        test_sunaudiodev
+        test_zipfile
+        test_zlib
+        """,
+    'atheos':
+        """
+        test_al
+        test_applesingle
+        test_bsddb185
+        test_cd
+        test_cl
+        test_curses
+        test_dl
+        test_gdbm
+        test_gl
+        test_imgfile
+        test_largefile
+        test_linuxaudiodev
+        test_locale
+        test_mhlib
+        test_mmap
+        test_nis
+        test_poll
+        test_popen2
+        test_resource
+        test_sqlite
+        test_startfile
+        test_sunaudiodev
+        """,
+    'cygwin':
+        """
+        test_al
+        test_applesingle
+        test_bsddb185
+        test_bsddb3
+        test_cd
+        test_cl
+        test_curses
+        test_dbm
+        test_gl
+        test_imgfile
+        test_ioctl
+        test_largefile
+        test_linuxaudiodev
+        test_locale
+        test_nis
+        test_ossaudiodev
+        test_socketserver
+        test_sqlite
+        test_sunaudiodev
+        """,
+    'os2emx':
+        """
+        test_al
+        test_applesingle
+        test_audioop
+        test_bsddb185
+        test_bsddb3
+        test_cd
+        test_cl
+        test_commands
+        test_curses
+        test_dl
+        test_gl
+        test_imgfile
+        test_largefile
+        test_linuxaudiodev
+        test_mhlib
+        test_mmap
+        test_nis
+        test_openpty
+        test_ossaudiodev
+        test_pty
+        test_resource
+        test_signal
+        test_sqlite
+        test_startfile
+        test_sunaudiodev
+        """,
+    'freebsd4':
+        """
+        test_aepack
+        test_al
+        test_applesingle
+        test_bsddb
+        test_bsddb3
+        test_cd
+        test_cl
+        test_gdbm
+        test_gl
+        test_imgfile
+        test_linuxaudiodev
+        test_locale
+        test_macfs
+        test_macostools
+        test_nis
+        test_ossaudiodev
+        test_pep277
+        test_plistlib
+        test_pty
+        test_scriptpackages
+        test_socket_ssl
+        test_socketserver
+        test_sqlite
+        test_startfile
+        test_sunaudiodev
+        test_tcl
+        test_timeout
+        test_unicode_file
+        test_urllibnet
+        test_winreg
+        test_winsound
+        """,
+    'aix5':
+        """
+        test_aepack
+        test_al
+        test_applesingle
+        test_bsddb
+        test_bsddb185
+        test_bsddb3
+        test_bz2
+        test_cd
+        test_cl
+        test_dl
+        test_gdbm
+        test_gl
+        test_gzip
+        test_imgfile
+        test_linuxaudiodev
+        test_macfs
+        test_macostools
+        test_nis
+        test_ossaudiodev
+        test_sqlite
+        test_startfile
+        test_sunaudiodev
+        test_tcl
+        test_winreg
+        test_winsound
+        test_zipimport
+        test_zlib
+        """,
+    'openbsd3':
+        """
+        test_aepack
+        test_al
+        test_applesingle
+        test_bsddb
+        test_bsddb3
+        test_cd
+        test_cl
+        test_ctypes
+        test_dl
+        test_gdbm
+        test_gl
+        test_imgfile
+        test_linuxaudiodev
+        test_locale
+        test_macfs
+        test_macostools
+        test_nis
+        test_normalization
+        test_ossaudiodev
+        test_pep277
+        test_plistlib
+        test_scriptpackages
+        test_tcl
+        test_sqlite
+        test_startfile
+        test_sunaudiodev
+        test_unicode_file
+        test_winreg
+        test_winsound
+        """,
+    'netbsd3':
+        """
+        test_aepack
+        test_al
+        test_applesingle
+        test_bsddb
+        test_bsddb185
+        test_bsddb3
+        test_cd
+        test_cl
+        test_ctypes
+        test_curses
+        test_dl
+        test_gdbm
+        test_gl
+        test_imgfile
+        test_linuxaudiodev
+        test_locale
+        test_macfs
+        test_macostools
+        test_nis
+        test_ossaudiodev
+        test_pep277
+        test_sqlite
+        test_startfile
+        test_sunaudiodev
+        test_tcl
+        test_unicode_file
+        test_winreg
+        test_winsound
+        """,
+}
+_expectations['freebsd5'] = _expectations['freebsd4']
+_expectations['freebsd6'] = _expectations['freebsd4']
+_expectations['freebsd7'] = _expectations['freebsd4']
+
+class _ExpectedSkips:
+    def __init__(self):
+        import os.path
+        from test import test_socket_ssl
+        from test import test_timeout
+
+        self.valid = False
+        if sys.platform in _expectations:
+            s = _expectations[sys.platform]
+            self.expected = set(s.split())
+
+            if not os.path.supports_unicode_filenames:
+                self.expected.add('test_pep277')
+
+            if test_socket_ssl.skip_expected:
+                self.expected.add('test_socket_ssl')
+
+            if test_timeout.skip_expected:
+                self.expected.add('test_timeout')
+
+            if sys.maxint == 9223372036854775807L:
+                self.expected.add('test_rgbimg')
+                self.expected.add('test_imageop')
+
+            if not sys.platform in ("mac", "darwin"):
+                MAC_ONLY = ["test_macostools", "test_macfs", "test_aepack",
+                            "test_plistlib", "test_scriptpackages"]
+                for skip in MAC_ONLY:
+                    self.expected.add(skip)
+
+            if sys.platform != "win32":
+                WIN_ONLY = ["test_unicode_file", "test_winreg",
+                            "test_winsound"]
+                for skip in WIN_ONLY:
+                    self.expected.add(skip)
+
+            self.valid = True
+
+    def isvalid(self):
+        "Return true iff _ExpectedSkips knows about the current platform."
+        return self.valid
+
+    def getexpected(self):
+        """Return set of test names we expect to skip on current platform.
+
+        self.isvalid() must be true.
+        """
+
+        assert self.isvalid()
+        return self.expected
+
+if __name__ == '__main__':
+    # Remove regrtest.py's own directory from the module search path.  This
+    # prevents relative imports from working, and relative imports will screw
+    # up the testing framework.  E.g. if both test.test_support and
+    # test_support are imported, they will not contain the same globals, and
+    # much of the testing framework relies on the globals in the
+    # test.test_support module.
+    mydir = os.path.abspath(os.path.normpath(os.path.dirname(sys.argv[0])))
+    i = pathlen = len(sys.path)
+    while i >= 0:
+        i -= 1
+        if os.path.abspath(os.path.normpath(sys.path[i])) == mydir:
+            del sys.path[i]
+    if len(sys.path) == pathlen:
+        print 'Could not find %r in sys.path to remove it' % mydir
+    main()


Property changes on: vendor/Python/current/Lib/test/regrtest.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/test/reperf.py
===================================================================
--- vendor/Python/current/Lib/test/reperf.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/reperf.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,23 @@
+import re
+import time
+
+def main():
+    s = "\13hello\14 \13world\14 " * 1000
+    p = re.compile(r"([\13\14])")
+    timefunc(10, p.sub, "", s)
+    timefunc(10, p.split, s)
+    timefunc(10, p.findall, s)
+
+def timefunc(n, func, *args, **kw):
+    t0 = time.clock()
+    try:
+        for i in range(n):
+            result = func(*args, **kw)
+        return result
+    finally:
+        t1 = time.clock()
+        if n > 1:
+            print n, "times",
+        print func.__name__, "%.3f" % (t1-t0), "CPU seconds"
+
+main()

Added: vendor/Python/current/Lib/test/sample_doctest.py
===================================================================
--- vendor/Python/current/Lib/test/sample_doctest.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/sample_doctest.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,76 @@
+"""This is a sample module that doesn't really test anything all that
+   interesting.
+
+It simply has a few tests, some of which succeed and some of which fail.
+
+It's important that the numbers remain constant as another test is
+testing the running of these tests.
+
+
+>>> 2+2
+4
+"""
+
+
+def foo():
+    """
+
+    >>> 2+2
+    5
+
+    >>> 2+2
+    4
+    """
+
+def bar():
+    """
+
+    >>> 2+2
+    4
+    """
+
+def test_silly_setup():
+    """
+
+    >>> import test.test_doctest
+    >>> test.test_doctest.sillySetup
+    True
+    """
+
+def w_blank():
+    """
+    >>> if 1:
+    ...    print 'a'
+    ...    print
+    ...    print 'b'
+    a
+    <BLANKLINE>
+    b
+    """
+
+x = 1
+def x_is_one():
+    """
+    >>> x
+    1
+    """
+
+def y_is_one():
+    """
+    >>> y
+    1
+    """
+
+__test__ = {'good': """
+                    >>> 42
+                    42
+                    """,
+            'bad':  """
+                    >>> 42
+                    666
+                    """,
+           }
+
+def test_suite():
+    import doctest
+    return doctest.DocTestSuite()

Added: vendor/Python/current/Lib/test/seq_tests.py
===================================================================
--- vendor/Python/current/Lib/test/seq_tests.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/seq_tests.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,323 @@
+"""
+Tests common to tuple, list and UserList.UserList
+"""
+
+import unittest
+from test import test_support
+
+# Various iterables
+# This is used for checking the constructor (here and in test_deque.py)
+def iterfunc(seqn):
+    'Regular generator'
+    for i in seqn:
+        yield i
+
+class Sequence:
+    'Sequence using __getitem__'
+    def __init__(self, seqn):
+        self.seqn = seqn
+    def __getitem__(self, i):
+        return self.seqn[i]
+
+class IterFunc:
+    'Sequence using iterator protocol'
+    def __init__(self, seqn):
+        self.seqn = seqn
+        self.i = 0
+    def __iter__(self):
+        return self
+    def next(self):
+        if self.i >= len(self.seqn): raise StopIteration
+        v = self.seqn[self.i]
+        self.i += 1
+        return v
+
+class IterGen:
+    'Sequence using iterator protocol defined with a generator'
+    def __init__(self, seqn):
+        self.seqn = seqn
+        self.i = 0
+    def __iter__(self):
+        for val in self.seqn:
+            yield val
+
+class IterNextOnly:
+    'Missing __getitem__ and __iter__'
+    def __init__(self, seqn):
+        self.seqn = seqn
+        self.i = 0
+    def next(self):
+        if self.i >= len(self.seqn): raise StopIteration
+        v = self.seqn[self.i]
+        self.i += 1
+        return v
+
+class IterNoNext:
+    'Iterator missing next()'
+    def __init__(self, seqn):
+        self.seqn = seqn
+        self.i = 0
+    def __iter__(self):
+        return self
+
+class IterGenExc:
+    'Test propagation of exceptions'
+    def __init__(self, seqn):
+        self.seqn = seqn
+        self.i = 0
+    def __iter__(self):
+        return self
+    def next(self):
+        3 // 0
+
+class IterFuncStop:
+    'Test immediate stop'
+    def __init__(self, seqn):
+        pass
+    def __iter__(self):
+        return self
+    def next(self):
+        raise StopIteration
+
+from itertools import chain, imap
+def itermulti(seqn):
+    'Test multiple tiers of iterators'
+    return chain(imap(lambda x:x, iterfunc(IterGen(Sequence(seqn)))))
+
+class CommonTest(unittest.TestCase):
+    # The type to be tested
+    type2test = None
+
+    def test_constructors(self):
+        l0 = []
+        l1 = [0]
+        l2 = [0, 1]
+
+        u = self.type2test()
+        u0 = self.type2test(l0)
+        u1 = self.type2test(l1)
+        u2 = self.type2test(l2)
+
+        uu = self.type2test(u)
+        uu0 = self.type2test(u0)
+        uu1 = self.type2test(u1)
+        uu2 = self.type2test(u2)
+
+        v = self.type2test(tuple(u))
+        class OtherSeq:
+            def __init__(self, initseq):
+                self.__data = initseq
+            def __len__(self):
+                return len(self.__data)
+            def __getitem__(self, i):
+                return self.__data[i]
+        s = OtherSeq(u0)
+        v0 = self.type2test(s)
+        self.assertEqual(len(v0), len(s))
+
+        s = "this is also a sequence"
+        vv = self.type2test(s)
+        self.assertEqual(len(vv), len(s))
+
+        # Create from various iteratables
+        for s in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5)):
+            for g in (Sequence, IterFunc, IterGen,
+                      itermulti, iterfunc):
+                self.assertEqual(self.type2test(g(s)), self.type2test(s))
+            self.assertEqual(self.type2test(IterFuncStop(s)), self.type2test())
+            self.assertEqual(self.type2test(c for c in "123"), self.type2test("123"))
+            self.assertRaises(TypeError, self.type2test, IterNextOnly(s))
+            self.assertRaises(TypeError, self.type2test, IterNoNext(s))
+            self.assertRaises(ZeroDivisionError, self.type2test, IterGenExc(s))
+
+    def test_truth(self):
+        self.assert_(not self.type2test())
+        self.assert_(self.type2test([42]))
+
+    def test_getitem(self):
+        u = self.type2test([0, 1, 2, 3, 4])
+        for i in xrange(len(u)):
+            self.assertEqual(u[i], i)
+            self.assertEqual(u[long(i)], i)
+        for i in xrange(-len(u), -1):
+            self.assertEqual(u[i], len(u)+i)
+            self.assertEqual(u[long(i)], len(u)+i)
+        self.assertRaises(IndexError, u.__getitem__, -len(u)-1)
+        self.assertRaises(IndexError, u.__getitem__, len(u))
+        self.assertRaises(ValueError, u.__getitem__, slice(0,10,0))
+
+        u = self.type2test()
+        self.assertRaises(IndexError, u.__getitem__, 0)
+        self.assertRaises(IndexError, u.__getitem__, -1)
+
+        self.assertRaises(TypeError, u.__getitem__)
+
+        a = self.type2test([10, 11])
+        self.assertEqual(a[0], 10)
+        self.assertEqual(a[1], 11)
+        self.assertEqual(a[-2], 10)
+        self.assertEqual(a[-1], 11)
+        self.assertRaises(IndexError, a.__getitem__, -3)
+        self.assertRaises(IndexError, a.__getitem__, 3)
+
+    def test_getslice(self):
+        l = [0, 1, 2, 3, 4]
+        u = self.type2test(l)
+
+        self.assertEqual(u[0:0], self.type2test())
+        self.assertEqual(u[1:2], self.type2test([1]))
+        self.assertEqual(u[-2:-1], self.type2test([3]))
+        self.assertEqual(u[-1000:1000], u)
+        self.assertEqual(u[1000:-1000], self.type2test([]))
+        self.assertEqual(u[:], u)
+        self.assertEqual(u[1:None], self.type2test([1, 2, 3, 4]))
+        self.assertEqual(u[None:3], self.type2test([0, 1, 2]))
+
+        # Extended slices
+        self.assertEqual(u[::], u)
+        self.assertEqual(u[::2], self.type2test([0, 2, 4]))
+        self.assertEqual(u[1::2], self.type2test([1, 3]))
+        self.assertEqual(u[::-1], self.type2test([4, 3, 2, 1, 0]))
+        self.assertEqual(u[::-2], self.type2test([4, 2, 0]))
+        self.assertEqual(u[3::-2], self.type2test([3, 1]))
+        self.assertEqual(u[3:3:-2], self.type2test([]))
+        self.assertEqual(u[3:2:-2], self.type2test([3]))
+        self.assertEqual(u[3:1:-2], self.type2test([3]))
+        self.assertEqual(u[3:0:-2], self.type2test([3, 1]))
+        self.assertEqual(u[::-100], self.type2test([4]))
+        self.assertEqual(u[100:-100:], self.type2test([]))
+        self.assertEqual(u[-100:100:], u)
+        self.assertEqual(u[100:-100:-1], u[::-1])
+        self.assertEqual(u[-100:100:-1], self.type2test([]))
+        self.assertEqual(u[-100L:100L:2L], self.type2test([0, 2, 4]))
+
+        # Test extreme cases with long ints
+        a = self.type2test([0,1,2,3,4])
+        self.assertEqual(a[ -pow(2,128L): 3 ], self.type2test([0,1,2]))
+        self.assertEqual(a[ 3: pow(2,145L) ], self.type2test([3,4]))
+
+        self.assertRaises(TypeError, u.__getslice__)
+
+    def test_contains(self):
+        u = self.type2test([0, 1, 2])
+        for i in u:
+            self.assert_(i in u)
+        for i in min(u)-1, max(u)+1:
+            self.assert_(i not in u)
+
+        self.assertRaises(TypeError, u.__contains__)
+
+    def test_contains_fake(self):
+        class AllEq:
+            # Sequences must use rich comparison against each item
+            # (unless "is" is true, or an earlier item answered)
+            # So instances of AllEq must be found in all non-empty sequences.
+            def __eq__(self, other):
+                return True
+            def __hash__(self):
+                raise NotImplemented
+        self.assert_(AllEq() not in self.type2test([]))
+        self.assert_(AllEq() in self.type2test([1]))
+
+    def test_contains_order(self):
+        # Sequences must test in-order.  If a rich comparison has side
+        # effects, these will be visible to tests against later members.
+        # In this test, the "side effect" is a short-circuiting raise.
+        class DoNotTestEq(Exception):
+            pass
+        class StopCompares:
+            def __eq__(self, other):
+                raise DoNotTestEq
+
+        checkfirst = self.type2test([1, StopCompares()])
+        self.assert_(1 in checkfirst)
+        checklast = self.type2test([StopCompares(), 1])
+        self.assertRaises(DoNotTestEq, checklast.__contains__, 1)
+
+    def test_len(self):
+        self.assertEqual(len(self.type2test()), 0)
+        self.assertEqual(len(self.type2test([])), 0)
+        self.assertEqual(len(self.type2test([0])), 1)
+        self.assertEqual(len(self.type2test([0, 1, 2])), 3)
+
+    def test_minmax(self):
+        u = self.type2test([0, 1, 2])
+        self.assertEqual(min(u), 0)
+        self.assertEqual(max(u), 2)
+
+    def test_addmul(self):
+        u1 = self.type2test([0])
+        u2 = self.type2test([0, 1])
+        self.assertEqual(u1, u1 + self.type2test())
+        self.assertEqual(u1, self.type2test() + u1)
+        self.assertEqual(u1 + self.type2test([1]), u2)
+        self.assertEqual(self.type2test([-1]) + u1, self.type2test([-1, 0]))
+        self.assertEqual(self.type2test(), u2*0)
+        self.assertEqual(self.type2test(), 0*u2)
+        self.assertEqual(self.type2test(), u2*0L)
+        self.assertEqual(self.type2test(), 0L*u2)
+        self.assertEqual(u2, u2*1)
+        self.assertEqual(u2, 1*u2)
+        self.assertEqual(u2, u2*1L)
+        self.assertEqual(u2, 1L*u2)
+        self.assertEqual(u2+u2, u2*2)
+        self.assertEqual(u2+u2, 2*u2)
+        self.assertEqual(u2+u2, u2*2L)
+        self.assertEqual(u2+u2, 2L*u2)
+        self.assertEqual(u2+u2+u2, u2*3)
+        self.assertEqual(u2+u2+u2, 3*u2)
+
+        class subclass(self.type2test):
+            pass
+        u3 = subclass([0, 1])
+        self.assertEqual(u3, u3*1)
+        self.assert_(u3 is not u3*1)
+
+    def test_iadd(self):
+        u = self.type2test([0, 1])
+        u += self.type2test()
+        self.assertEqual(u, self.type2test([0, 1]))
+        u += self.type2test([2, 3])
+        self.assertEqual(u, self.type2test([0, 1, 2, 3]))
+        u += self.type2test([4, 5])
+        self.assertEqual(u, self.type2test([0, 1, 2, 3, 4, 5]))
+
+        u = self.type2test("spam")
+        u += self.type2test("eggs")
+        self.assertEqual(u, self.type2test("spameggs"))
+
+    def test_imul(self):
+        u = self.type2test([0, 1])
+        u *= 3
+        self.assertEqual(u, self.type2test([0, 1, 0, 1, 0, 1]))
+
+    def test_getitemoverwriteiter(self):
+        # Verify that __getitem__ overrides are not recognized by __iter__
+        class T(self.type2test):
+            def __getitem__(self, key):
+                return str(key) + '!!!'
+        self.assertEqual(iter(T((1,2))).next(), 1)
+
+    def test_repeat(self):
+        for m in xrange(4):
+            s = tuple(range(m))
+            for n in xrange(-3, 5):
+                self.assertEqual(self.type2test(s*n), self.type2test(s)*n)
+            self.assertEqual(self.type2test(s)*(-4), self.type2test([]))
+            self.assertEqual(id(s), id(s*1))
+
+    def test_subscript(self):
+        a = self.type2test([10, 11])
+        self.assertEqual(a.__getitem__(0L), 10)
+        self.assertEqual(a.__getitem__(1L), 11)
+        self.assertEqual(a.__getitem__(-2L), 10)
+        self.assertEqual(a.__getitem__(-1L), 11)
+        self.assertRaises(IndexError, a.__getitem__, -3)
+        self.assertRaises(IndexError, a.__getitem__, 3)
+        self.assertEqual(a.__getitem__(slice(0,1)), self.type2test([10]))
+        self.assertEqual(a.__getitem__(slice(1,2)), self.type2test([11]))
+        self.assertEqual(a.__getitem__(slice(0,2)), self.type2test([10, 11]))
+        self.assertEqual(a.__getitem__(slice(0,3)), self.type2test([10, 11]))
+        self.assertEqual(a.__getitem__(slice(3,5)), self.type2test([]))
+        self.assertRaises(ValueError, a.__getitem__, slice(0, 10, 0))
+        self.assertRaises(TypeError, a.__getitem__, 'x')

Added: vendor/Python/current/Lib/test/sgml_input.html
===================================================================
--- vendor/Python/current/Lib/test/sgml_input.html	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/sgml_input.html	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,212 @@
+<html>
+ <head>
+  <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
+  <link rel="stylesheet" type="text/css" href="http://ogame182.de/epicblue/formate.css">
+  <script language="JavaScript" src="js/flotten.js"></script>
+ </head>
+ <body>
+    <script language=JavaScript> if (parent.frames.length == 0) { top.location.href = "http://es.ogame.org/"; } </script> <script language="JavaScript">
+function haha(z1) {
+  eval("location='"+z1.options[z1.selectedIndex].value+"'");
+}
+</script>
+<center>
+<table>
+ <tr>
+  <td></td>
+  <td>
+   <center>
+   <table>
+    <tr>
+     <td><img src="http://ogame182.de/epicblue/planeten/small/s_dschjungelplanet04.jpg" width="50" height="50"></td>
+     <td>
+      <table border="1">
+       <select size="1" onchange="haha(this)">
+                                   <option value="/game/flotten1.php?session=8912ae912fec&cp=33875341&mode=Flotte&gid=&messageziel=&re=0" selected>Alien sex friend    [2:250:6]</option> 
+                                   <option value="/game/flotten1.php?session=8912ae912fec&cp=33905100&mode=Flotte&gid=&messageziel=&re=0" >1989    [2:248:14]</option> 
+                                   <option value="/game/flotten1.php?session=8912ae912fec&cp=34570808&mode=Flotte&gid=&messageziel=&re=0" >1990    [2:248:6]</option> 
+                                   <option value="/game/flotten1.php?session=8912ae912fec&cp=34570858&mode=Flotte&gid=&messageziel=&re=0" >1991    [2:254:6]</option> 
+                                   <option value="/game/flotten1.php?session=8912ae912fec&cp=34572929&mode=Flotte&gid=&messageziel=&re=0" >Colonia    [2:253:12]</option> 
+               </select>
+      </table>
+     </td>
+    </tr>
+  </table>
+  </center>
+  </td>
+  <td>
+   <table border="0" width="100%" cellspacing="0" cellpadding="0">
+    <tr>
+     <td align="center"></td>
+     <td align="center" width="85">
+      <img border="0" src="http://ogame182.de/epicblue/images/metall.gif" width="42" height="22">
+     </td>
+     <td align="center" width="85">
+      <img border="0" src="http://ogame182.de/epicblue/images/kristall.gif" width="42" height="22">
+     </td>
+     <td align="center" width="85">
+      <img border="0" src="http://ogame182.de/epicblue/images/deuterium.gif" width="42" height="22">
+     </td>
+     <td align="center" width="85">
+      <img border="0" src="http://ogame182.de/epicblue/images/energie.gif" width="42" height="22">
+     </td>
+     <td align="center"></td>
+    </tr>
+    <tr>
+     <td align="center"><i><b>&nbsp;&nbsp;</b></i></td>
+     <td align="center" width="85"><i><b><font color="#ffffff">Metal</font></b></i></td>
+     <td align="center" width="85"><i><b><font color="#ffffff">Cristal</font></b></i></td>
+     <td align="center" width="85"><i><b><font color="#ffffff">Deuterio</font></b></i></td>
+     <td align="center" width="85"><i><b><font color="#ffffff">Energía</font></b></i></td>
+     <td align="center"><i><b>&nbsp;&nbsp;</b></i></td>
+    </tr>
+    <tr>
+     <td align="center"></td>
+     <td align="center" width="85">160.636</td>
+     <td align="center" width="85">3.406</td>
+     <td align="center" width="85">39.230</td>
+     <td align="center" width="85"><font color=#ff0000>-80</font>/3.965</td>
+     <td align="center"></td>
+    </tr>
+   </table>
+  </tr>
+ </table>
+  </center>
+<br />
+  <script language="JavaScript">
+  <!--
+     function link_to_gamepay() {
+    self.location = "https://www.gamepay.de/?lang=es&serverID=8&userID=129360&gameID=ogame&gui=v2&chksum=a9751afa9e37e6b1b826356bcca45675";
+  }
+//-->
+  </script>
+<center>
+  <table width="519" border="0" cellpadding="0" cellspacing="1">
+   <tr height="20">
+  <td colspan="8" class="c">Flotas (max. 9)</td>
+   </tr>
+     <tr height="20">
+    <th>Num.</th>
+    <th>Misión</th>
+    <th>Cantidad</th>
+    <th>Comienzo</th>
+    <th>Salida</th>
+    <th>Objetivo</th>
+    <th>Llegada</th>
+    <th>Orden</th>   
+   </tr>
+     <tr height="20">
+    <th>1</th>
+    <th>  
+      <a title="">Espionaje</a>
+      <a title="Flota en el planeta">(F)</a>
+    </th>
+    <th> <a title="Sonda de espionaje: 3 
+">3</a></th>
+    <th>[2:250:6]</th>
+    <th>Wed Aug 9 18:00:02</th>
+    <th>[2:242:5]</th>
+    <th>Wed Aug 9 18:01:02</th>
+    <th>
+         <form action="flotten1.php?session=8912ae912fec" method="POST">
+	<input type="hidden" name="order_return" value="25054490" />
+        <input type="submit" value="Enviar de regreso" />
+     </form>
+            </th>
+   </tr>
+   <tr height="20">
+    <th>2</th>
+    <th>  
+      <a title="">Espionaje</a>
+      <a title="Volver al planeta">(V)</a>
+    </th>
+    <th> <a title="Sonda de espionaje: 3 
+">3</a></th>
+    <th>[2:250:6]</th>
+    <th>Wed Aug 9 17:59:55</th>
+    <th>[2:242:1]</th>
+    <th>Wed Aug 9 18:01:55</th>
+    <th>
+            </th>
+   </tr>
+  </table>
+
+
+  
+<form action="flotten2.php?session=8912ae912fec" method="POST">
+  <table width="519" border="0" cellpadding="0" cellspacing="1">
+       <tr height="20">
+  <td colspan="4" class="c">Nueva misión: elegir naves</td>
+   </tr>
+   <tr height="20">
+  <th>Naves</th>
+  <th>Disponibles</th>
+<!--    <th>Gesch.</th> -->
+    <th>-</th>
+    <th>-</th>
+   </tr>
+   <tr height="20">
+    <th><a title="Velocidad: 8500">Nave pequeña de carga</a></th> 
+    <th>10<input type="hidden" name="maxship202" value="10"/></th>
+<!--    <th>8500 -->
+     <input type="hidden" name="consumption202" value="10"/>
+     <input type="hidden" name="speed202" value="8500" /></th>
+     <input type="hidden" name="capacity202" value="5000" /></th>
+     <th><a href="javascript:maxShip('ship202');" >máx</a> </th>
+     <th><input name="ship202" size="10" value="0" alt="Nave pequeña de carga 10"/></th>
+   </tr>
+   <tr height="20">
+    <th><a title="Velocidad: 12750">Nave grande de carga</a></th> 
+    <th>19<input type="hidden" name="maxship203" value="19"/></th>
+<!--    <th>12750 -->
+     <input type="hidden" name="consumption203" value="50"/>
+     <input type="hidden" name="speed203" value="12750" /></th>
+     <input type="hidden" name="capacity203" value="25000" /></th>
+     <th><a href="javascript:maxShip('ship203');" >máx</a> </th>
+     <th><input name="ship203" size="10" value="0" alt="Nave grande de carga 19"/></th>
+   </tr>
+   <tr height="20">
+    <th><a title="Velocidad: 27000">Crucero</a></th> 
+    <th>6<input type="hidden" name="maxship206" value="6"/></th>
+<!--    <th>27000 -->
+     <input type="hidden" name="consumption206" value="300"/>
+     <input type="hidden" name="speed206" value="27000" /></th>
+     <input type="hidden" name="capacity206" value="800" /></th>
+     <th><a href="javascript:maxShip('ship206');" >máx</a> </th>
+     <th><input name="ship206" size="10" value="0" alt="Crucero 6"/></th>
+   </tr>
+   <tr height="20">
+    <th><a title="Velocidad: 3400">Reciclador</a></th> 
+    <th>1<input type="hidden" name="maxship209" value="1"/></th>
+<!--    <th>3400 -->
+     <input type="hidden" name="consumption209" value="300"/>
+     <input type="hidden" name="speed209" value="3400" /></th>
+     <input type="hidden" name="capacity209" value="20000" /></th>
+     <th><a href="javascript:maxShip('ship209');" >máx</a> </th>
+     <th><input name="ship209" size="10" value="0" alt="Reciclador 1"/></th>
+   </tr>
+   <tr height="20">
+    <th><a title="Velocidad: 170000000">Sonda de espionaje</a></th> 
+    <th>139<input type="hidden" name="maxship210" value="139"/></th>
+<!--    <th>170000000 -->
+     <input type="hidden" name="consumption210" value="1"/>
+     <input type="hidden" name="speed210" value="170000000" /></th>
+     <input type="hidden" name="capacity210" value="5" /></th>
+     <th><a href="javascript:maxShip('ship210');" >máx</a> </th>
+     <th><input name="ship210" size="10" value="0" alt="Sonda de espionaje 139"/></th>
+   </tr>
+   <tr height="20">
+  <th colspan="2"><a href="javascript:noShips();" >Ninguna nave</a></th>
+  <th colspan="2"><a href="javascript:maxShips();" >Todas las naves</a></th>
+   </tr>
+    <tr height="20">
+    <th colspan="4"><input type="submit" value="Continuar" /></th>
+   </tr>
+<tr><th colspan=4>
+<iframe id='a44fb522' name='a44fb522' src='http://ads.gameforgeads.de/adframe.php?n=a44fb522&amp;what=zone:578' framespacing='0' frameborder='no' scrolling='no' width='468' height='60'></iframe>
+<br><center></center></br>
+</th></tr>
+</form>
+</table>
+ </body>
+</html>

Added: vendor/Python/current/Lib/test/sortperf.py
===================================================================
--- vendor/Python/current/Lib/test/sortperf.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/sortperf.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,169 @@
+"""Sort performance test.
+
+See main() for command line syntax.
+See tabulate() for output format.
+
+"""
+
+import sys
+import time
+import random
+import marshal
+import tempfile
+import os
+
+td = tempfile.gettempdir()
+
+def randfloats(n):
+    """Return a list of n random floats in [0, 1)."""
+    # Generating floats is expensive, so this writes them out to a file in
+    # a temp directory.  If the file already exists, it just reads them
+    # back in and shuffles them a bit.
+    fn = os.path.join(td, "rr%06d" % n)
+    try:
+        fp = open(fn, "rb")
+    except IOError:
+        r = random.random
+        result = [r() for i in xrange(n)]
+        try:
+            try:
+                fp = open(fn, "wb")
+                marshal.dump(result, fp)
+                fp.close()
+                fp = None
+            finally:
+                if fp:
+                    try:
+                        os.unlink(fn)
+                    except os.error:
+                        pass
+        except IOError, msg:
+            print "can't write", fn, ":", msg
+    else:
+        result = marshal.load(fp)
+        fp.close()
+        # Shuffle it a bit...
+        for i in range(10):
+            i = random.randrange(n)
+            temp = result[:i]
+            del result[:i]
+            temp.reverse()
+            result.extend(temp)
+            del temp
+    assert len(result) == n
+    return result
+
+def flush():
+    sys.stdout.flush()
+
+def doit(L):
+    t0 = time.clock()
+    L.sort()
+    t1 = time.clock()
+    print "%6.2f" % (t1-t0),
+    flush()
+
+def tabulate(r):
+    """Tabulate sort speed for lists of various sizes.
+
+    The sizes are 2**i for i in r (the argument, a list).
+
+    The output displays i, 2**i, and the time to sort arrays of 2**i
+    floating point numbers with the following properties:
+
+    *sort: random data
+    \sort: descending data
+    /sort: ascending data
+    3sort: ascending, then 3 random exchanges
+    +sort: ascending, then 10 random at the end
+    %sort: ascending, then randomly replace 1% of the elements w/ random values
+    ~sort: many duplicates
+    =sort: all equal
+    !sort: worst case scenario
+
+    """
+    cases = tuple([ch + "sort" for ch in r"*\/3+%~=!"])
+    fmt = ("%2s %7s" + " %6s"*len(cases))
+    print fmt % (("i", "2**i") + cases)
+    for i in r:
+        n = 1 << i
+        L = randfloats(n)
+        print "%2d %7d" % (i, n),
+        flush()
+        doit(L) # *sort
+        L.reverse()
+        doit(L) # \sort
+        doit(L) # /sort
+
+        # Do 3 random exchanges.
+        for dummy in range(3):
+            i1 = random.randrange(n)
+            i2 = random.randrange(n)
+            L[i1], L[i2] = L[i2], L[i1]
+        doit(L) # 3sort
+
+        # Replace the last 10 with random floats.
+        if n >= 10:
+            L[-10:] = [random.random() for dummy in range(10)]
+        doit(L) # +sort
+
+        # Replace 1% of the elements at random.
+        for dummy in xrange(n // 100):
+            L[random.randrange(n)] = random.random()
+        doit(L) # %sort
+
+        # Arrange for lots of duplicates.
+        if n > 4:
+            del L[4:]
+            L = L * (n // 4)
+            # Force the elements to be distinct objects, else timings can be
+            # artificially low.
+            L = map(lambda x: --x, L)
+        doit(L) # ~sort
+        del L
+
+        # All equal.  Again, force the elements to be distinct objects.
+        L = map(abs, [-0.5] * n)
+        doit(L) # =sort
+        del L
+
+        # This one looks like [3, 2, 1, 0, 0, 1, 2, 3].  It was a bad case
+        # for an older implementation of quicksort, which used the median
+        # of the first, last and middle elements as the pivot.
+        half = n // 2
+        L = range(half - 1, -1, -1)
+        L.extend(range(half))
+        # Force to float, so that the timings are comparable.  This is
+        # significantly faster if we leave tham as ints.
+        L = map(float, L)
+        doit(L) # !sort
+        print
+
+def main():
+    """Main program when invoked as a script.
+
+    One argument: tabulate a single row.
+    Two arguments: tabulate a range (inclusive).
+    Extra arguments are used to seed the random generator.
+
+    """
+    # default range (inclusive)
+    k1 = 15
+    k2 = 20
+    if sys.argv[1:]:
+        # one argument: single point
+        k1 = k2 = int(sys.argv[1])
+        if sys.argv[2:]:
+            # two arguments: specify range
+            k2 = int(sys.argv[2])
+            if sys.argv[3:]:
+                # derive random seed from remaining arguments
+                x = 1
+                for a in sys.argv[3:]:
+                    x = 69069 * x + hash(a)
+                random.seed(x)
+    r = range(k1, k2+1)                 # include the end point
+    tabulate(r)
+
+if __name__ == '__main__':
+    main()

Added: vendor/Python/current/Lib/test/string_tests.py
===================================================================
--- vendor/Python/current/Lib/test/string_tests.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/string_tests.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1173 @@
+"""
+Common tests shared by test_str, test_unicode, test_userstring and test_string.
+"""
+
+import unittest, string, sys
+from test import test_support
+from UserList import UserList
+
+class Sequence:
+    def __init__(self, seq='wxyz'): self.seq = seq
+    def __len__(self): return len(self.seq)
+    def __getitem__(self, i): return self.seq[i]
+
+class BadSeq1(Sequence):
+    def __init__(self): self.seq = [7, 'hello', 123L]
+
+class BadSeq2(Sequence):
+    def __init__(self): self.seq = ['a', 'b', 'c']
+    def __len__(self): return 8
+
+class CommonTest(unittest.TestCase):
+    # This testcase contains test that can be used in all
+    # stringlike classes. Currently this is str, unicode
+    # UserString and the string module.
+
+    # The type to be tested
+    # Change in subclasses to change the behaviour of fixtesttype()
+    type2test = None
+
+    # All tests pass their arguments to the testing methods
+    # as str objects. fixtesttype() can be used to propagate
+    # these arguments to the appropriate type
+    def fixtype(self, obj):
+        if isinstance(obj, str):
+            return self.__class__.type2test(obj)
+        elif isinstance(obj, list):
+            return [self.fixtype(x) for x in obj]
+        elif isinstance(obj, tuple):
+            return tuple([self.fixtype(x) for x in obj])
+        elif isinstance(obj, dict):
+            return dict([
+               (self.fixtype(key), self.fixtype(value))
+               for (key, value) in obj.iteritems()
+            ])
+        else:
+            return obj
+
+    # check that object.method(*args) returns result
+    def checkequal(self, result, object, methodname, *args):
+        result = self.fixtype(result)
+        object = self.fixtype(object)
+        args = self.fixtype(args)
+        realresult = getattr(object, methodname)(*args)
+        self.assertEqual(
+            result,
+            realresult
+        )
+        # if the original is returned make sure that
+        # this doesn't happen with subclasses
+        if object == realresult:
+            class subtype(self.__class__.type2test):
+                pass
+            object = subtype(object)
+            realresult = getattr(object, methodname)(*args)
+            self.assert_(object is not realresult)
+
+    # check that object.method(*args) raises exc
+    def checkraises(self, exc, object, methodname, *args):
+        object = self.fixtype(object)
+        args = self.fixtype(args)
+        self.assertRaises(
+            exc,
+            getattr(object, methodname),
+            *args
+        )
+
+    # call object.method(*args) without any checks
+    def checkcall(self, object, methodname, *args):
+        object = self.fixtype(object)
+        args = self.fixtype(args)
+        getattr(object, methodname)(*args)
+
+    def test_hash(self):
+        # SF bug 1054139:  += optimization was not invalidating cached hash value
+        a = self.type2test('DNSSEC')
+        b = self.type2test('')
+        for c in a:
+            b += c
+            hash(b)
+        self.assertEqual(hash(a), hash(b))
+
+    def test_capitalize(self):
+        self.checkequal(' hello ', ' hello ', 'capitalize')
+        self.checkequal('Hello ', 'Hello ','capitalize')
+        self.checkequal('Hello ', 'hello ','capitalize')
+        self.checkequal('Aaaa', 'aaaa', 'capitalize')
+        self.checkequal('Aaaa', 'AaAa', 'capitalize')
+
+        self.checkraises(TypeError, 'hello', 'capitalize', 42)
+
+    def test_count(self):
+        self.checkequal(3, 'aaa', 'count', 'a')
+        self.checkequal(0, 'aaa', 'count', 'b')
+        self.checkequal(3, 'aaa', 'count', 'a')
+        self.checkequal(0, 'aaa', 'count', 'b')
+        self.checkequal(3, 'aaa', 'count', 'a')
+        self.checkequal(0, 'aaa', 'count', 'b')
+        self.checkequal(0, 'aaa', 'count', 'b')
+        self.checkequal(2, 'aaa', 'count', 'a', 1)
+        self.checkequal(0, 'aaa', 'count', 'a', 10)
+        self.checkequal(1, 'aaa', 'count', 'a', -1)
+        self.checkequal(3, 'aaa', 'count', 'a', -10)
+        self.checkequal(1, 'aaa', 'count', 'a', 0, 1)
+        self.checkequal(3, 'aaa', 'count', 'a', 0, 10)
+        self.checkequal(2, 'aaa', 'count', 'a', 0, -1)
+        self.checkequal(0, 'aaa', 'count', 'a', 0, -10)
+        self.checkequal(3, 'aaa', 'count', '', 1)
+        self.checkequal(1, 'aaa', 'count', '', 3)
+        self.checkequal(0, 'aaa', 'count', '', 10)
+        self.checkequal(2, 'aaa', 'count', '', -1)
+        self.checkequal(4, 'aaa', 'count', '', -10)
+
+        self.checkraises(TypeError, 'hello', 'count')
+        self.checkraises(TypeError, 'hello', 'count', 42)
+
+        # For a variety of combinations,
+        #    verify that str.count() matches an equivalent function
+        #    replacing all occurrences and then differencing the string lengths
+        charset = ['', 'a', 'b']
+        digits = 7
+        base = len(charset)
+        teststrings = set()
+        for i in xrange(base ** digits):
+            entry = []
+            for j in xrange(digits):
+                i, m = divmod(i, base)
+                entry.append(charset[m])
+            teststrings.add(''.join(entry))
+        teststrings = list(teststrings)
+        for i in teststrings:
+            i = self.fixtype(i)
+            n = len(i)
+            for j in teststrings:
+                r1 = i.count(j)
+                if j:
+                    r2, rem = divmod(n - len(i.replace(j, '')), len(j))
+                else:
+                    r2, rem = len(i)+1, 0
+                if rem or r1 != r2:
+                    self.assertEqual(rem, 0, '%s != 0 for %s' % (rem, i))
+                    self.assertEqual(r1, r2, '%s != %s for %s' % (r1, r2, i))
+
+    def test_find(self):
+        self.checkequal(0, 'abcdefghiabc', 'find', 'abc')
+        self.checkequal(9, 'abcdefghiabc', 'find', 'abc', 1)
+        self.checkequal(-1, 'abcdefghiabc', 'find', 'def', 4)
+
+        self.checkequal(0, 'abc', 'find', '', 0)
+        self.checkequal(3, 'abc', 'find', '', 3)
+        self.checkequal(-1, 'abc', 'find', '', 4)
+
+        self.checkraises(TypeError, 'hello', 'find')
+        self.checkraises(TypeError, 'hello', 'find', 42)
+
+        # For a variety of combinations,
+        #    verify that str.find() matches __contains__
+        #    and that the found substring is really at that location
+        charset = ['', 'a', 'b', 'c']
+        digits = 5
+        base = len(charset)
+        teststrings = set()
+        for i in xrange(base ** digits):
+            entry = []
+            for j in xrange(digits):
+                i, m = divmod(i, base)
+                entry.append(charset[m])
+            teststrings.add(''.join(entry))
+        teststrings = list(teststrings)
+        for i in teststrings:
+            i = self.fixtype(i)
+            for j in teststrings:
+                loc = i.find(j)
+                r1 = (loc != -1)
+                r2 = j in i
+                if r1 != r2:
+                    self.assertEqual(r1, r2)
+                if loc != -1:
+                    self.assertEqual(i[loc:loc+len(j)], j)
+
+    def test_rfind(self):
+        self.checkequal(9,  'abcdefghiabc', 'rfind', 'abc')
+        self.checkequal(12, 'abcdefghiabc', 'rfind', '')
+        self.checkequal(0, 'abcdefghiabc', 'rfind', 'abcd')
+        self.checkequal(-1, 'abcdefghiabc', 'rfind', 'abcz')
+
+        self.checkequal(3, 'abc', 'rfind', '', 0)
+        self.checkequal(3, 'abc', 'rfind', '', 3)
+        self.checkequal(-1, 'abc', 'rfind', '', 4)
+
+        self.checkraises(TypeError, 'hello', 'rfind')
+        self.checkraises(TypeError, 'hello', 'rfind', 42)
+
+    def test_index(self):
+        self.checkequal(0, 'abcdefghiabc', 'index', '')
+        self.checkequal(3, 'abcdefghiabc', 'index', 'def')
+        self.checkequal(0, 'abcdefghiabc', 'index', 'abc')
+        self.checkequal(9, 'abcdefghiabc', 'index', 'abc', 1)
+
+        self.checkraises(ValueError, 'abcdefghiabc', 'index', 'hib')
+        self.checkraises(ValueError, 'abcdefghiab', 'index', 'abc', 1)
+        self.checkraises(ValueError, 'abcdefghi', 'index', 'ghi', 8)
+        self.checkraises(ValueError, 'abcdefghi', 'index', 'ghi', -1)
+
+        self.checkraises(TypeError, 'hello', 'index')
+        self.checkraises(TypeError, 'hello', 'index', 42)
+
+    def test_rindex(self):
+        self.checkequal(12, 'abcdefghiabc', 'rindex', '')
+        self.checkequal(3,  'abcdefghiabc', 'rindex', 'def')
+        self.checkequal(9,  'abcdefghiabc', 'rindex', 'abc')
+        self.checkequal(0,  'abcdefghiabc', 'rindex', 'abc', 0, -1)
+
+        self.checkraises(ValueError, 'abcdefghiabc', 'rindex', 'hib')
+        self.checkraises(ValueError, 'defghiabc', 'rindex', 'def', 1)
+        self.checkraises(ValueError, 'defghiabc', 'rindex', 'abc', 0, -1)
+        self.checkraises(ValueError, 'abcdefghi', 'rindex', 'ghi', 0, 8)
+        self.checkraises(ValueError, 'abcdefghi', 'rindex', 'ghi', 0, -1)
+
+        self.checkraises(TypeError, 'hello', 'rindex')
+        self.checkraises(TypeError, 'hello', 'rindex', 42)
+
+    def test_lower(self):
+        self.checkequal('hello', 'HeLLo', 'lower')
+        self.checkequal('hello', 'hello', 'lower')
+        self.checkraises(TypeError, 'hello', 'lower', 42)
+
+    def test_upper(self):
+        self.checkequal('HELLO', 'HeLLo', 'upper')
+        self.checkequal('HELLO', 'HELLO', 'upper')
+        self.checkraises(TypeError, 'hello', 'upper', 42)
+
+    def test_expandtabs(self):
+        self.checkequal('abc\rab      def\ng       hi', 'abc\rab\tdef\ng\thi', 'expandtabs')
+        self.checkequal('abc\rab      def\ng       hi', 'abc\rab\tdef\ng\thi', 'expandtabs', 8)
+        self.checkequal('abc\rab  def\ng   hi', 'abc\rab\tdef\ng\thi', 'expandtabs', 4)
+        self.checkequal('abc\r\nab  def\ng   hi', 'abc\r\nab\tdef\ng\thi', 'expandtabs', 4)
+        self.checkequal('abc\rab      def\ng       hi', 'abc\rab\tdef\ng\thi', 'expandtabs')
+        self.checkequal('abc\rab      def\ng       hi', 'abc\rab\tdef\ng\thi', 'expandtabs', 8)
+        self.checkequal('abc\r\nab\r\ndef\ng\r\nhi', 'abc\r\nab\r\ndef\ng\r\nhi', 'expandtabs', 4)
+
+        self.checkraises(TypeError, 'hello', 'expandtabs', 42, 42)
+
+    def test_split(self):
+        self.checkequal(['this', 'is', 'the', 'split', 'function'],
+            'this is the split function', 'split')
+
+        # by whitespace
+        self.checkequal(['a', 'b', 'c', 'd'], 'a b c d ', 'split')
+        self.checkequal(['a', 'b c d'], 'a b c d', 'split', None, 1)
+        self.checkequal(['a', 'b', 'c d'], 'a b c d', 'split', None, 2)
+        self.checkequal(['a', 'b', 'c', 'd'], 'a b c d', 'split', None, 3)
+        self.checkequal(['a', 'b', 'c', 'd'], 'a b c d', 'split', None, 4)
+        self.checkequal(['a', 'b', 'c', 'd'], 'a b c d', 'split', None,
+                        sys.maxint-1)
+        self.checkequal(['a b c d'], 'a b c d', 'split', None, 0)
+        self.checkequal(['a b c d'], '  a b c d', 'split', None, 0)
+        self.checkequal(['a', 'b', 'c  d'], 'a  b  c  d', 'split', None, 2)
+
+        self.checkequal([], '         ', 'split')
+        self.checkequal(['a'], '  a    ', 'split')
+        self.checkequal(['a', 'b'], '  a    b   ', 'split')
+        self.checkequal(['a', 'b   '], '  a    b   ', 'split', None, 1)
+        self.checkequal(['a', 'b   c   '], '  a    b   c   ', 'split', None, 1)
+        self.checkequal(['a', 'b', 'c   '], '  a    b   c   ', 'split', None, 2)
+        self.checkequal(['a', 'b'], '\n\ta \t\r b \v ', 'split')
+        aaa = ' a '*20
+        self.checkequal(['a']*20, aaa, 'split')
+        self.checkequal(['a'] + [aaa[4:]], aaa, 'split', None, 1)
+        self.checkequal(['a']*19 + ['a '], aaa, 'split', None, 19)
+
+        # by a char
+        self.checkequal(['a', 'b', 'c', 'd'], 'a|b|c|d', 'split', '|')
+        self.checkequal(['a|b|c|d'], 'a|b|c|d', 'split', '|', 0)
+        self.checkequal(['a', 'b|c|d'], 'a|b|c|d', 'split', '|', 1)
+        self.checkequal(['a', 'b', 'c|d'], 'a|b|c|d', 'split', '|', 2)
+        self.checkequal(['a', 'b', 'c', 'd'], 'a|b|c|d', 'split', '|', 3)
+        self.checkequal(['a', 'b', 'c', 'd'], 'a|b|c|d', 'split', '|', 4)
+        self.checkequal(['a', 'b', 'c', 'd'], 'a|b|c|d', 'split', '|',
+                        sys.maxint-2)
+        self.checkequal(['a|b|c|d'], 'a|b|c|d', 'split', '|', 0)
+        self.checkequal(['a', '', 'b||c||d'], 'a||b||c||d', 'split', '|', 2)
+        self.checkequal(['endcase ', ''], 'endcase |', 'split', '|')
+        self.checkequal(['', ' startcase'], '| startcase', 'split', '|')
+        self.checkequal(['', 'bothcase', ''], '|bothcase|', 'split', '|')
+        self.checkequal(['a', '', 'b\x00c\x00d'], 'a\x00\x00b\x00c\x00d', 'split', '\x00', 2)
+
+        self.checkequal(['a']*20, ('a|'*20)[:-1], 'split', '|')
+        self.checkequal(['a']*15 +['a|a|a|a|a'],
+                                   ('a|'*20)[:-1], 'split', '|', 15)
+
+        # by string
+        self.checkequal(['a', 'b', 'c', 'd'], 'a//b//c//d', 'split', '//')
+        self.checkequal(['a', 'b//c//d'], 'a//b//c//d', 'split', '//', 1)
+        self.checkequal(['a', 'b', 'c//d'], 'a//b//c//d', 'split', '//', 2)
+        self.checkequal(['a', 'b', 'c', 'd'], 'a//b//c//d', 'split', '//', 3)
+        self.checkequal(['a', 'b', 'c', 'd'], 'a//b//c//d', 'split', '//', 4)
+        self.checkequal(['a', 'b', 'c', 'd'], 'a//b//c//d', 'split', '//',
+                        sys.maxint-10)
+        self.checkequal(['a//b//c//d'], 'a//b//c//d', 'split', '//', 0)
+        self.checkequal(['a', '', 'b////c////d'], 'a////b////c////d', 'split', '//', 2)
+        self.checkequal(['endcase ', ''], 'endcase test', 'split', 'test')
+        self.checkequal(['', ' begincase'], 'test begincase', 'split', 'test')
+        self.checkequal(['', ' bothcase ', ''], 'test bothcase test',
+                        'split', 'test')
+        self.checkequal(['a', 'bc'], 'abbbc', 'split', 'bb')
+        self.checkequal(['', ''], 'aaa', 'split', 'aaa')
+        self.checkequal(['aaa'], 'aaa', 'split', 'aaa', 0)
+        self.checkequal(['ab', 'ab'], 'abbaab', 'split', 'ba')
+        self.checkequal(['aaaa'], 'aaaa', 'split', 'aab')
+        self.checkequal([''], '', 'split', 'aaa')
+        self.checkequal(['aa'], 'aa', 'split', 'aaa')
+        self.checkequal(['A', 'bobb'], 'Abbobbbobb', 'split', 'bbobb')
+        self.checkequal(['A', 'B', ''], 'AbbobbBbbobb', 'split', 'bbobb')
+
+        self.checkequal(['a']*20, ('aBLAH'*20)[:-4], 'split', 'BLAH')
+        self.checkequal(['a']*20, ('aBLAH'*20)[:-4], 'split', 'BLAH', 19)
+        self.checkequal(['a']*18 + ['aBLAHa'], ('aBLAH'*20)[:-4],
+                        'split', 'BLAH', 18)
+
+        # mixed use of str and unicode
+        self.checkequal([u'a', u'b', u'c d'], 'a b c d', 'split', u' ', 2)
+
+        # argument type
+        self.checkraises(TypeError, 'hello', 'split', 42, 42, 42)
+
+        # null case
+        self.checkraises(ValueError, 'hello', 'split', '')
+        self.checkraises(ValueError, 'hello', 'split', '', 0)
+
+    def test_rsplit(self):
+        self.checkequal(['this', 'is', 'the', 'rsplit', 'function'],
+                         'this is the rsplit function', 'rsplit')
+
+        # by whitespace
+        self.checkequal(['a', 'b', 'c', 'd'], 'a b c d ', 'rsplit')
+        self.checkequal(['a b c', 'd'], 'a b c d', 'rsplit', None, 1)
+        self.checkequal(['a b', 'c', 'd'], 'a b c d', 'rsplit', None, 2)
+        self.checkequal(['a', 'b', 'c', 'd'], 'a b c d', 'rsplit', None, 3)
+        self.checkequal(['a', 'b', 'c', 'd'], 'a b c d', 'rsplit', None, 4)
+        self.checkequal(['a', 'b', 'c', 'd'], 'a b c d', 'rsplit', None,
+                        sys.maxint-20)
+        self.checkequal(['a b c d'], 'a b c d', 'rsplit', None, 0)
+        self.checkequal(['a b c d'], 'a b c d  ', 'rsplit', None, 0)
+        self.checkequal(['a  b', 'c', 'd'], 'a  b  c  d', 'rsplit', None, 2)
+
+        self.checkequal([], '         ', 'rsplit')
+        self.checkequal(['a'], '  a    ', 'rsplit')
+        self.checkequal(['a', 'b'], '  a    b   ', 'rsplit')
+        self.checkequal(['  a', 'b'], '  a    b   ', 'rsplit', None, 1)
+        self.checkequal(['  a    b','c'], '  a    b   c   ', 'rsplit',
+                        None, 1)
+        self.checkequal(['  a', 'b', 'c'], '  a    b   c   ', 'rsplit',
+                        None, 2)
+        self.checkequal(['a', 'b'], '\n\ta \t\r b \v ', 'rsplit', None, 88)
+        aaa = ' a '*20
+        self.checkequal(['a']*20, aaa, 'rsplit')
+        self.checkequal([aaa[:-4]] + ['a'], aaa, 'rsplit', None, 1)
+        self.checkequal([' a  a'] + ['a']*18, aaa, 'rsplit', None, 18)
+
+
+        # by a char
+        self.checkequal(['a', 'b', 'c', 'd'], 'a|b|c|d', 'rsplit', '|')
+        self.checkequal(['a|b|c', 'd'], 'a|b|c|d', 'rsplit', '|', 1)
+        self.checkequal(['a|b', 'c', 'd'], 'a|b|c|d', 'rsplit', '|', 2)
+        self.checkequal(['a', 'b', 'c', 'd'], 'a|b|c|d', 'rsplit', '|', 3)
+        self.checkequal(['a', 'b', 'c', 'd'], 'a|b|c|d', 'rsplit', '|', 4)
+        self.checkequal(['a', 'b', 'c', 'd'], 'a|b|c|d', 'rsplit', '|',
+                        sys.maxint-100)
+        self.checkequal(['a|b|c|d'], 'a|b|c|d', 'rsplit', '|', 0)
+        self.checkequal(['a||b||c', '', 'd'], 'a||b||c||d', 'rsplit', '|', 2)
+        self.checkequal(['', ' begincase'], '| begincase', 'rsplit', '|')
+        self.checkequal(['endcase ', ''], 'endcase |', 'rsplit', '|')
+        self.checkequal(['', 'bothcase', ''], '|bothcase|', 'rsplit', '|')
+
+        self.checkequal(['a\x00\x00b', 'c', 'd'], 'a\x00\x00b\x00c\x00d', 'rsplit', '\x00', 2)
+
+        self.checkequal(['a']*20, ('a|'*20)[:-1], 'rsplit', '|')
+        self.checkequal(['a|a|a|a|a']+['a']*15,
+                        ('a|'*20)[:-1], 'rsplit', '|', 15)
+
+        # by string
+        self.checkequal(['a', 'b', 'c', 'd'], 'a//b//c//d', 'rsplit', '//')
+        self.checkequal(['a//b//c', 'd'], 'a//b//c//d', 'rsplit', '//', 1)
+        self.checkequal(['a//b', 'c', 'd'], 'a//b//c//d', 'rsplit', '//', 2)
+        self.checkequal(['a', 'b', 'c', 'd'], 'a//b//c//d', 'rsplit', '//', 3)
+        self.checkequal(['a', 'b', 'c', 'd'], 'a//b//c//d', 'rsplit', '//', 4)
+        self.checkequal(['a', 'b', 'c', 'd'], 'a//b//c//d', 'rsplit', '//',
+                        sys.maxint-5)
+        self.checkequal(['a//b//c//d'], 'a//b//c//d', 'rsplit', '//', 0)
+        self.checkequal(['a////b////c', '', 'd'], 'a////b////c////d', 'rsplit', '//', 2)
+        self.checkequal(['', ' begincase'], 'test begincase', 'rsplit', 'test')
+        self.checkequal(['endcase ', ''], 'endcase test', 'rsplit', 'test')
+        self.checkequal(['', ' bothcase ', ''], 'test bothcase test',
+                        'rsplit', 'test')
+        self.checkequal(['ab', 'c'], 'abbbc', 'rsplit', 'bb')
+        self.checkequal(['', ''], 'aaa', 'rsplit', 'aaa')
+        self.checkequal(['aaa'], 'aaa', 'rsplit', 'aaa', 0)
+        self.checkequal(['ab', 'ab'], 'abbaab', 'rsplit', 'ba')
+        self.checkequal(['aaaa'], 'aaaa', 'rsplit', 'aab')
+        self.checkequal([''], '', 'rsplit', 'aaa')
+        self.checkequal(['aa'], 'aa', 'rsplit', 'aaa')
+        self.checkequal(['bbob', 'A'], 'bbobbbobbA', 'rsplit', 'bbobb')
+        self.checkequal(['', 'B', 'A'], 'bbobbBbbobbA', 'rsplit', 'bbobb')
+
+        self.checkequal(['a']*20, ('aBLAH'*20)[:-4], 'rsplit', 'BLAH')
+        self.checkequal(['a']*20, ('aBLAH'*20)[:-4], 'rsplit', 'BLAH', 19)
+        self.checkequal(['aBLAHa'] + ['a']*18, ('aBLAH'*20)[:-4],
+                        'rsplit', 'BLAH', 18)
+
+        # mixed use of str and unicode
+        self.checkequal([u'a b', u'c', u'd'], 'a b c d', 'rsplit', u' ', 2)
+
+        # argument type
+        self.checkraises(TypeError, 'hello', 'rsplit', 42, 42, 42)
+
+        # null case
+        self.checkraises(ValueError, 'hello', 'rsplit', '')
+        self.checkraises(ValueError, 'hello', 'rsplit', '', 0)
+
+    def test_strip(self):
+        self.checkequal('hello', '   hello   ', 'strip')
+        self.checkequal('hello   ', '   hello   ', 'lstrip')
+        self.checkequal('   hello', '   hello   ', 'rstrip')
+        self.checkequal('hello', 'hello', 'strip')
+
+        # strip/lstrip/rstrip with None arg
+        self.checkequal('hello', '   hello   ', 'strip', None)
+        self.checkequal('hello   ', '   hello   ', 'lstrip', None)
+        self.checkequal('   hello', '   hello   ', 'rstrip', None)
+        self.checkequal('hello', 'hello', 'strip', None)
+
+        # strip/lstrip/rstrip with str arg
+        self.checkequal('hello', 'xyzzyhelloxyzzy', 'strip', 'xyz')
+        self.checkequal('helloxyzzy', 'xyzzyhelloxyzzy', 'lstrip', 'xyz')
+        self.checkequal('xyzzyhello', 'xyzzyhelloxyzzy', 'rstrip', 'xyz')
+        self.checkequal('hello', 'hello', 'strip', 'xyz')
+
+        # strip/lstrip/rstrip with unicode arg
+        if test_support.have_unicode:
+            self.checkequal(unicode('hello', 'ascii'), 'xyzzyhelloxyzzy',
+                 'strip', unicode('xyz', 'ascii'))
+            self.checkequal(unicode('helloxyzzy', 'ascii'), 'xyzzyhelloxyzzy',
+                 'lstrip', unicode('xyz', 'ascii'))
+            self.checkequal(unicode('xyzzyhello', 'ascii'), 'xyzzyhelloxyzzy',
+                 'rstrip', unicode('xyz', 'ascii'))
+            self.checkequal(unicode('hello', 'ascii'), 'hello',
+                 'strip', unicode('xyz', 'ascii'))
+
+        self.checkraises(TypeError, 'hello', 'strip', 42, 42)
+        self.checkraises(TypeError, 'hello', 'lstrip', 42, 42)
+        self.checkraises(TypeError, 'hello', 'rstrip', 42, 42)
+
+    def test_ljust(self):
+        self.checkequal('abc       ', 'abc', 'ljust', 10)
+        self.checkequal('abc   ', 'abc', 'ljust', 6)
+        self.checkequal('abc', 'abc', 'ljust', 3)
+        self.checkequal('abc', 'abc', 'ljust', 2)
+        self.checkequal('abc*******', 'abc', 'ljust', 10, '*')
+        self.checkraises(TypeError, 'abc', 'ljust')
+
+    def test_rjust(self):
+        self.checkequal('       abc', 'abc', 'rjust', 10)
+        self.checkequal('   abc', 'abc', 'rjust', 6)
+        self.checkequal('abc', 'abc', 'rjust', 3)
+        self.checkequal('abc', 'abc', 'rjust', 2)
+        self.checkequal('*******abc', 'abc', 'rjust', 10, '*')
+        self.checkraises(TypeError, 'abc', 'rjust')
+
+    def test_center(self):
+        self.checkequal('   abc    ', 'abc', 'center', 10)
+        self.checkequal(' abc  ', 'abc', 'center', 6)
+        self.checkequal('abc', 'abc', 'center', 3)
+        self.checkequal('abc', 'abc', 'center', 2)
+        self.checkequal('***abc****', 'abc', 'center', 10, '*')
+        self.checkraises(TypeError, 'abc', 'center')
+
+    def test_swapcase(self):
+        self.checkequal('hEllO CoMPuTErS', 'HeLLo cOmpUteRs', 'swapcase')
+
+        self.checkraises(TypeError, 'hello', 'swapcase', 42)
+
+    def test_replace(self):
+        EQ = self.checkequal
+
+        # Operations on the empty string
+        EQ("", "", "replace", "", "")
+        EQ("A", "", "replace", "", "A")
+        EQ("", "", "replace", "A", "")
+        EQ("", "", "replace", "A", "A")
+        EQ("", "", "replace", "", "", 100)
+        EQ("", "", "replace", "", "", sys.maxint)
+
+        # interleave (from=="", 'to' gets inserted everywhere)
+        EQ("A", "A", "replace", "", "")
+        EQ("*A*", "A", "replace", "", "*")
+        EQ("*1A*1", "A", "replace", "", "*1")
+        EQ("*-#A*-#", "A", "replace", "", "*-#")
+        EQ("*-A*-A*-", "AA", "replace", "", "*-")
+        EQ("*-A*-A*-", "AA", "replace", "", "*-", -1)
+        EQ("*-A*-A*-", "AA", "replace", "", "*-", sys.maxint)
+        EQ("*-A*-A*-", "AA", "replace", "", "*-", 4)
+        EQ("*-A*-A*-", "AA", "replace", "", "*-", 3)
+        EQ("*-A*-A", "AA", "replace", "", "*-", 2)
+        EQ("*-AA", "AA", "replace", "", "*-", 1)
+        EQ("AA", "AA", "replace", "", "*-", 0)
+
+        # single character deletion (from=="A", to=="")
+        EQ("", "A", "replace", "A", "")
+        EQ("", "AAA", "replace", "A", "")
+        EQ("", "AAA", "replace", "A", "", -1)
+        EQ("", "AAA", "replace", "A", "", sys.maxint)
+        EQ("", "AAA", "replace", "A", "", 4)
+        EQ("", "AAA", "replace", "A", "", 3)
+        EQ("A", "AAA", "replace", "A", "", 2)
+        EQ("AA", "AAA", "replace", "A", "", 1)
+        EQ("AAA", "AAA", "replace", "A", "", 0)
+        EQ("", "AAAAAAAAAA", "replace", "A", "")
+        EQ("BCD", "ABACADA", "replace", "A", "")
+        EQ("BCD", "ABACADA", "replace", "A", "", -1)
+        EQ("BCD", "ABACADA", "replace", "A", "", sys.maxint)
+        EQ("BCD", "ABACADA", "replace", "A", "", 5)
+        EQ("BCD", "ABACADA", "replace", "A", "", 4)
+        EQ("BCDA", "ABACADA", "replace", "A", "", 3)
+        EQ("BCADA", "ABACADA", "replace", "A", "", 2)
+        EQ("BACADA", "ABACADA", "replace", "A", "", 1)
+        EQ("ABACADA", "ABACADA", "replace", "A", "", 0)
+        EQ("BCD", "ABCAD", "replace", "A", "")
+        EQ("BCD", "ABCADAA", "replace", "A", "")
+        EQ("BCD", "BCD", "replace", "A", "")
+        EQ("*************", "*************", "replace", "A", "")
+        EQ("^A^", "^"+"A"*1000+"^", "replace", "A", "", 999)
+
+        # substring deletion (from=="the", to=="")
+        EQ("", "the", "replace", "the", "")
+        EQ("ater", "theater", "replace", "the", "")
+        EQ("", "thethe", "replace", "the", "")
+        EQ("", "thethethethe", "replace", "the", "")
+        EQ("aaaa", "theatheatheathea", "replace", "the", "")
+        EQ("that", "that", "replace", "the", "")
+        EQ("thaet", "thaet", "replace", "the", "")
+        EQ("here and re", "here and there", "replace", "the", "")
+        EQ("here and re and re", "here and there and there",
+           "replace", "the", "", sys.maxint)
+        EQ("here and re and re", "here and there and there",
+           "replace", "the", "", -1)
+        EQ("here and re and re", "here and there and there",
+           "replace", "the", "", 3)
+        EQ("here and re and re", "here and there and there",
+           "replace", "the", "", 2)
+        EQ("here and re and there", "here and there and there",
+           "replace", "the", "", 1)
+        EQ("here and there and there", "here and there and there",
+           "replace", "the", "", 0)
+        EQ("here and re and re", "here and there and there", "replace", "the", "")
+
+        EQ("abc", "abc", "replace", "the", "")
+        EQ("abcdefg", "abcdefg", "replace", "the", "")
+
+        # substring deletion (from=="bob", to=="")
+        EQ("bob", "bbobob", "replace", "bob", "")
+        EQ("bobXbob", "bbobobXbbobob", "replace", "bob", "")
+        EQ("aaaaaaa", "aaaaaaabob", "replace", "bob", "")
+        EQ("aaaaaaa", "aaaaaaa", "replace", "bob", "")
+
+        # single character replace in place (len(from)==len(to)==1)
+        EQ("Who goes there?", "Who goes there?", "replace", "o", "o")
+        EQ("WhO gOes there?", "Who goes there?", "replace", "o", "O")
+        EQ("WhO gOes there?", "Who goes there?", "replace", "o", "O", sys.maxint)
+        EQ("WhO gOes there?", "Who goes there?", "replace", "o", "O", -1)
+        EQ("WhO gOes there?", "Who goes there?", "replace", "o", "O", 3)
+        EQ("WhO gOes there?", "Who goes there?", "replace", "o", "O", 2)
+        EQ("WhO goes there?", "Who goes there?", "replace", "o", "O", 1)
+        EQ("Who goes there?", "Who goes there?", "replace", "o", "O", 0)
+
+        EQ("Who goes there?", "Who goes there?", "replace", "a", "q")
+        EQ("who goes there?", "Who goes there?", "replace", "W", "w")
+        EQ("wwho goes there?ww", "WWho goes there?WW", "replace", "W", "w")
+        EQ("Who goes there!", "Who goes there?", "replace", "?", "!")
+        EQ("Who goes there!!", "Who goes there??", "replace", "?", "!")
+
+        EQ("Who goes there?", "Who goes there?", "replace", ".", "!")
+
+        # substring replace in place (len(from)==len(to) > 1)
+        EQ("Th** ** a t**sue", "This is a tissue", "replace", "is", "**")
+        EQ("Th** ** a t**sue", "This is a tissue", "replace", "is", "**", sys.maxint)
+        EQ("Th** ** a t**sue", "This is a tissue", "replace", "is", "**", -1)
+        EQ("Th** ** a t**sue", "This is a tissue", "replace", "is", "**", 4)
+        EQ("Th** ** a t**sue", "This is a tissue", "replace", "is", "**", 3)
+        EQ("Th** ** a tissue", "This is a tissue", "replace", "is", "**", 2)
+        EQ("Th** is a tissue", "This is a tissue", "replace", "is", "**", 1)
+        EQ("This is a tissue", "This is a tissue", "replace", "is", "**", 0)
+        EQ("cobob", "bobob", "replace", "bob", "cob")
+        EQ("cobobXcobocob", "bobobXbobobob", "replace", "bob", "cob")
+        EQ("bobob", "bobob", "replace", "bot", "bot")
+
+        # replace single character (len(from)==1, len(to)>1)
+        EQ("ReyKKjaviKK", "Reykjavik", "replace", "k", "KK")
+        EQ("ReyKKjaviKK", "Reykjavik", "replace", "k", "KK", -1)
+        EQ("ReyKKjaviKK", "Reykjavik", "replace", "k", "KK", sys.maxint)
+        EQ("ReyKKjaviKK", "Reykjavik", "replace", "k", "KK", 2)
+        EQ("ReyKKjavik", "Reykjavik", "replace", "k", "KK", 1)
+        EQ("Reykjavik", "Reykjavik", "replace", "k", "KK", 0)
+        EQ("A----B----C----", "A.B.C.", "replace", ".", "----")
+
+        EQ("Reykjavik", "Reykjavik", "replace", "q", "KK")
+
+        # replace substring (len(from)>1, len(to)!=len(from))
+        EQ("ham, ham, eggs and ham", "spam, spam, eggs and spam",
+           "replace", "spam", "ham")
+        EQ("ham, ham, eggs and ham", "spam, spam, eggs and spam",
+           "replace", "spam", "ham", sys.maxint)
+        EQ("ham, ham, eggs and ham", "spam, spam, eggs and spam",
+           "replace", "spam", "ham", -1)
+        EQ("ham, ham, eggs and ham", "spam, spam, eggs and spam",
+           "replace", "spam", "ham", 4)
+        EQ("ham, ham, eggs and ham", "spam, spam, eggs and spam",
+           "replace", "spam", "ham", 3)
+        EQ("ham, ham, eggs and spam", "spam, spam, eggs and spam",
+           "replace", "spam", "ham", 2)
+        EQ("ham, spam, eggs and spam", "spam, spam, eggs and spam",
+           "replace", "spam", "ham", 1)
+        EQ("spam, spam, eggs and spam", "spam, spam, eggs and spam",
+           "replace", "spam", "ham", 0)
+
+        EQ("bobob", "bobobob", "replace", "bobob", "bob")
+        EQ("bobobXbobob", "bobobobXbobobob", "replace", "bobob", "bob")
+        EQ("BOBOBOB", "BOBOBOB", "replace", "bob", "bobby")
+
+        ba = buffer('a')
+        bb = buffer('b')
+        EQ("bbc", "abc", "replace", ba, bb)
+        EQ("aac", "abc", "replace", bb, ba)
+
+        #
+        self.checkequal('one at two!three!', 'one!two!three!', 'replace', '!', '@', 1)
+        self.checkequal('onetwothree', 'one!two!three!', 'replace', '!', '')
+        self.checkequal('one at two@three!', 'one!two!three!', 'replace', '!', '@', 2)
+        self.checkequal('one at two@three@', 'one!two!three!', 'replace', '!', '@', 3)
+        self.checkequal('one at two@three@', 'one!two!three!', 'replace', '!', '@', 4)
+        self.checkequal('one!two!three!', 'one!two!three!', 'replace', '!', '@', 0)
+        self.checkequal('one at two@three@', 'one!two!three!', 'replace', '!', '@')
+        self.checkequal('one!two!three!', 'one!two!three!', 'replace', 'x', '@')
+        self.checkequal('one!two!three!', 'one!two!three!', 'replace', 'x', '@', 2)
+        self.checkequal('-a-b-c-', 'abc', 'replace', '', '-')
+        self.checkequal('-a-b-c', 'abc', 'replace', '', '-', 3)
+        self.checkequal('abc', 'abc', 'replace', '', '-', 0)
+        self.checkequal('', '', 'replace', '', '')
+        self.checkequal('abc', 'abc', 'replace', 'ab', '--', 0)
+        self.checkequal('abc', 'abc', 'replace', 'xy', '--')
+        # Next three for SF bug 422088: [OSF1 alpha] string.replace(); died with
+        # MemoryError due to empty result (platform malloc issue when requesting
+        # 0 bytes).
+        self.checkequal('', '123', 'replace', '123', '')
+        self.checkequal('', '123123', 'replace', '123', '')
+        self.checkequal('x', '123x123', 'replace', '123', '')
+
+        self.checkraises(TypeError, 'hello', 'replace')
+        self.checkraises(TypeError, 'hello', 'replace', 42)
+        self.checkraises(TypeError, 'hello', 'replace', 42, 'h')
+        self.checkraises(TypeError, 'hello', 'replace', 'h', 42)
+
+    def test_replace_overflow(self):
+        # Check for overflow checking on 32 bit machines
+        if sys.maxint != 2147483647:
+            return
+        A2_16 = "A" * (2**16)
+        self.checkraises(OverflowError, A2_16, "replace", "", A2_16)
+        self.checkraises(OverflowError, A2_16, "replace", "A", A2_16)
+        self.checkraises(OverflowError, A2_16, "replace", "AA", A2_16+A2_16)
+
+    def test_zfill(self):
+        self.checkequal('123', '123', 'zfill', 2)
+        self.checkequal('123', '123', 'zfill', 3)
+        self.checkequal('0123', '123', 'zfill', 4)
+        self.checkequal('+123', '+123', 'zfill', 3)
+        self.checkequal('+123', '+123', 'zfill', 4)
+        self.checkequal('+0123', '+123', 'zfill', 5)
+        self.checkequal('-123', '-123', 'zfill', 3)
+        self.checkequal('-123', '-123', 'zfill', 4)
+        self.checkequal('-0123', '-123', 'zfill', 5)
+        self.checkequal('000', '', 'zfill', 3)
+        self.checkequal('34', '34', 'zfill', 1)
+        self.checkequal('0034', '34', 'zfill', 4)
+
+        self.checkraises(TypeError, '123', 'zfill')
+
+class MixinStrUnicodeUserStringTest:
+    # additional tests that only work for
+    # stringlike objects, i.e. str, unicode, UserString
+    # (but not the string module)
+
+    def test_islower(self):
+        self.checkequal(False, '', 'islower')
+        self.checkequal(True, 'a', 'islower')
+        self.checkequal(False, 'A', 'islower')
+        self.checkequal(False, '\n', 'islower')
+        self.checkequal(True, 'abc', 'islower')
+        self.checkequal(False, 'aBc', 'islower')
+        self.checkequal(True, 'abc\n', 'islower')
+        self.checkraises(TypeError, 'abc', 'islower', 42)
+
+    def test_isupper(self):
+        self.checkequal(False, '', 'isupper')
+        self.checkequal(False, 'a', 'isupper')
+        self.checkequal(True, 'A', 'isupper')
+        self.checkequal(False, '\n', 'isupper')
+        self.checkequal(True, 'ABC', 'isupper')
+        self.checkequal(False, 'AbC', 'isupper')
+        self.checkequal(True, 'ABC\n', 'isupper')
+        self.checkraises(TypeError, 'abc', 'isupper', 42)
+
+    def test_istitle(self):
+        self.checkequal(False, '', 'istitle')
+        self.checkequal(False, 'a', 'istitle')
+        self.checkequal(True, 'A', 'istitle')
+        self.checkequal(False, '\n', 'istitle')
+        self.checkequal(True, 'A Titlecased Line', 'istitle')
+        self.checkequal(True, 'A\nTitlecased Line', 'istitle')
+        self.checkequal(True, 'A Titlecased, Line', 'istitle')
+        self.checkequal(False, 'Not a capitalized String', 'istitle')
+        self.checkequal(False, 'Not\ta Titlecase String', 'istitle')
+        self.checkequal(False, 'Not--a Titlecase String', 'istitle')
+        self.checkequal(False, 'NOT', 'istitle')
+        self.checkraises(TypeError, 'abc', 'istitle', 42)
+
+    def test_isspace(self):
+        self.checkequal(False, '', 'isspace')
+        self.checkequal(False, 'a', 'isspace')
+        self.checkequal(True, ' ', 'isspace')
+        self.checkequal(True, '\t', 'isspace')
+        self.checkequal(True, '\r', 'isspace')
+        self.checkequal(True, '\n', 'isspace')
+        self.checkequal(True, ' \t\r\n', 'isspace')
+        self.checkequal(False, ' \t\r\na', 'isspace')
+        self.checkraises(TypeError, 'abc', 'isspace', 42)
+
+    def test_isalpha(self):
+        self.checkequal(False, '', 'isalpha')
+        self.checkequal(True, 'a', 'isalpha')
+        self.checkequal(True, 'A', 'isalpha')
+        self.checkequal(False, '\n', 'isalpha')
+        self.checkequal(True, 'abc', 'isalpha')
+        self.checkequal(False, 'aBc123', 'isalpha')
+        self.checkequal(False, 'abc\n', 'isalpha')
+        self.checkraises(TypeError, 'abc', 'isalpha', 42)
+
+    def test_isalnum(self):
+        self.checkequal(False, '', 'isalnum')
+        self.checkequal(True, 'a', 'isalnum')
+        self.checkequal(True, 'A', 'isalnum')
+        self.checkequal(False, '\n', 'isalnum')
+        self.checkequal(True, '123abc456', 'isalnum')
+        self.checkequal(True, 'a1b3c', 'isalnum')
+        self.checkequal(False, 'aBc000 ', 'isalnum')
+        self.checkequal(False, 'abc\n', 'isalnum')
+        self.checkraises(TypeError, 'abc', 'isalnum', 42)
+
+    def test_isdigit(self):
+        self.checkequal(False, '', 'isdigit')
+        self.checkequal(False, 'a', 'isdigit')
+        self.checkequal(True, '0', 'isdigit')
+        self.checkequal(True, '0123456789', 'isdigit')
+        self.checkequal(False, '0123456789a', 'isdigit')
+
+        self.checkraises(TypeError, 'abc', 'isdigit', 42)
+
+    def test_title(self):
+        self.checkequal(' Hello ', ' hello ', 'title')
+        self.checkequal('Hello ', 'hello ', 'title')
+        self.checkequal('Hello ', 'Hello ', 'title')
+        self.checkequal('Format This As Title String', "fOrMaT thIs aS titLe String", 'title')
+        self.checkequal('Format,This-As*Title;String', "fOrMaT,thIs-aS*titLe;String", 'title', )
+        self.checkequal('Getint', "getInt", 'title')
+        self.checkraises(TypeError, 'hello', 'title', 42)
+
+    def test_splitlines(self):
+        self.checkequal(['abc', 'def', '', 'ghi'], "abc\ndef\n\rghi", 'splitlines')
+        self.checkequal(['abc', 'def', '', 'ghi'], "abc\ndef\n\r\nghi", 'splitlines')
+        self.checkequal(['abc', 'def', 'ghi'], "abc\ndef\r\nghi", 'splitlines')
+        self.checkequal(['abc', 'def', 'ghi'], "abc\ndef\r\nghi\n", 'splitlines')
+        self.checkequal(['abc', 'def', 'ghi', ''], "abc\ndef\r\nghi\n\r", 'splitlines')
+        self.checkequal(['', 'abc', 'def', 'ghi', ''], "\nabc\ndef\r\nghi\n\r", 'splitlines')
+        self.checkequal(['\n', 'abc\n', 'def\r\n', 'ghi\n', '\r'], "\nabc\ndef\r\nghi\n\r", 'splitlines', 1)
+
+        self.checkraises(TypeError, 'abc', 'splitlines', 42, 42)
+
+    def test_startswith(self):
+        self.checkequal(True, 'hello', 'startswith', 'he')
+        self.checkequal(True, 'hello', 'startswith', 'hello')
+        self.checkequal(False, 'hello', 'startswith', 'hello world')
+        self.checkequal(True, 'hello', 'startswith', '')
+        self.checkequal(False, 'hello', 'startswith', 'ello')
+        self.checkequal(True, 'hello', 'startswith', 'ello', 1)
+        self.checkequal(True, 'hello', 'startswith', 'o', 4)
+        self.checkequal(False, 'hello', 'startswith', 'o', 5)
+        self.checkequal(True, 'hello', 'startswith', '', 5)
+        self.checkequal(False, 'hello', 'startswith', 'lo', 6)
+        self.checkequal(True, 'helloworld', 'startswith', 'lowo', 3)
+        self.checkequal(True, 'helloworld', 'startswith', 'lowo', 3, 7)
+        self.checkequal(False, 'helloworld', 'startswith', 'lowo', 3, 6)
+
+        # test negative indices
+        self.checkequal(True, 'hello', 'startswith', 'he', 0, -1)
+        self.checkequal(True, 'hello', 'startswith', 'he', -53, -1)
+        self.checkequal(False, 'hello', 'startswith', 'hello', 0, -1)
+        self.checkequal(False, 'hello', 'startswith', 'hello world', -1, -10)
+        self.checkequal(False, 'hello', 'startswith', 'ello', -5)
+        self.checkequal(True, 'hello', 'startswith', 'ello', -4)
+        self.checkequal(False, 'hello', 'startswith', 'o', -2)
+        self.checkequal(True, 'hello', 'startswith', 'o', -1)
+        self.checkequal(True, 'hello', 'startswith', '', -3, -3)
+        self.checkequal(False, 'hello', 'startswith', 'lo', -9)
+
+        self.checkraises(TypeError, 'hello', 'startswith')
+        self.checkraises(TypeError, 'hello', 'startswith', 42)
+
+        # test tuple arguments
+        self.checkequal(True, 'hello', 'startswith', ('he', 'ha'))
+        self.checkequal(False, 'hello', 'startswith', ('lo', 'llo'))
+        self.checkequal(True, 'hello', 'startswith', ('hellox', 'hello'))
+        self.checkequal(False, 'hello', 'startswith', ())
+        self.checkequal(True, 'helloworld', 'startswith', ('hellowo',
+                                                           'rld', 'lowo'), 3)
+        self.checkequal(False, 'helloworld', 'startswith', ('hellowo', 'ello',
+                                                            'rld'), 3)
+        self.checkequal(True, 'hello', 'startswith', ('lo', 'he'), 0, -1)
+        self.checkequal(False, 'hello', 'startswith', ('he', 'hel'), 0, 1)
+        self.checkequal(True, 'hello', 'startswith', ('he', 'hel'), 0, 2)
+
+        self.checkraises(TypeError, 'hello', 'startswith', (42,))
+
+    def test_endswith(self):
+        self.checkequal(True, 'hello', 'endswith', 'lo')
+        self.checkequal(False, 'hello', 'endswith', 'he')
+        self.checkequal(True, 'hello', 'endswith', '')
+        self.checkequal(False, 'hello', 'endswith', 'hello world')
+        self.checkequal(False, 'helloworld', 'endswith', 'worl')
+        self.checkequal(True, 'helloworld', 'endswith', 'worl', 3, 9)
+        self.checkequal(True, 'helloworld', 'endswith', 'world', 3, 12)
+        self.checkequal(True, 'helloworld', 'endswith', 'lowo', 1, 7)
+        self.checkequal(True, 'helloworld', 'endswith', 'lowo', 2, 7)
+        self.checkequal(True, 'helloworld', 'endswith', 'lowo', 3, 7)
+        self.checkequal(False, 'helloworld', 'endswith', 'lowo', 4, 7)
+        self.checkequal(False, 'helloworld', 'endswith', 'lowo', 3, 8)
+        self.checkequal(False, 'ab', 'endswith', 'ab', 0, 1)
+        self.checkequal(False, 'ab', 'endswith', 'ab', 0, 0)
+
+        # test negative indices
+        self.checkequal(True, 'hello', 'endswith', 'lo', -2)
+        self.checkequal(False, 'hello', 'endswith', 'he', -2)
+        self.checkequal(True, 'hello', 'endswith', '', -3, -3)
+        self.checkequal(False, 'hello', 'endswith', 'hello world', -10, -2)
+        self.checkequal(False, 'helloworld', 'endswith', 'worl', -6)
+        self.checkequal(True, 'helloworld', 'endswith', 'worl', -5, -1)
+        self.checkequal(True, 'helloworld', 'endswith', 'worl', -5, 9)
+        self.checkequal(True, 'helloworld', 'endswith', 'world', -7, 12)
+        self.checkequal(True, 'helloworld', 'endswith', 'lowo', -99, -3)
+        self.checkequal(True, 'helloworld', 'endswith', 'lowo', -8, -3)
+        self.checkequal(True, 'helloworld', 'endswith', 'lowo', -7, -3)
+        self.checkequal(False, 'helloworld', 'endswith', 'lowo', 3, -4)
+        self.checkequal(False, 'helloworld', 'endswith', 'lowo', -8, -2)
+
+        self.checkraises(TypeError, 'hello', 'endswith')
+        self.checkraises(TypeError, 'hello', 'endswith', 42)
+
+        # test tuple arguments
+        self.checkequal(False, 'hello', 'endswith', ('he', 'ha'))
+        self.checkequal(True, 'hello', 'endswith', ('lo', 'llo'))
+        self.checkequal(True, 'hello', 'endswith', ('hellox', 'hello'))
+        self.checkequal(False, 'hello', 'endswith', ())
+        self.checkequal(True, 'helloworld', 'endswith', ('hellowo',
+                                                           'rld', 'lowo'), 3)
+        self.checkequal(False, 'helloworld', 'endswith', ('hellowo', 'ello',
+                                                            'rld'), 3, -1)
+        self.checkequal(True, 'hello', 'endswith', ('hell', 'ell'), 0, -1)
+        self.checkequal(False, 'hello', 'endswith', ('he', 'hel'), 0, 1)
+        self.checkequal(True, 'hello', 'endswith', ('he', 'hell'), 0, 4)
+
+        self.checkraises(TypeError, 'hello', 'endswith', (42,))
+
+    def test___contains__(self):
+        self.checkequal(True, '', '__contains__', '')         # vereq('' in '', True)
+        self.checkequal(True, 'abc', '__contains__', '')      # vereq('' in 'abc', True)
+        self.checkequal(False, 'abc', '__contains__', '\0')   # vereq('\0' in 'abc', False)
+        self.checkequal(True, '\0abc', '__contains__', '\0')  # vereq('\0' in '\0abc', True)
+        self.checkequal(True, 'abc\0', '__contains__', '\0')  # vereq('\0' in 'abc\0', True)
+        self.checkequal(True, '\0abc', '__contains__', 'a')   # vereq('a' in '\0abc', True)
+        self.checkequal(True, 'asdf', '__contains__', 'asdf') # vereq('asdf' in 'asdf', True)
+        self.checkequal(False, 'asd', '__contains__', 'asdf') # vereq('asdf' in 'asd', False)
+        self.checkequal(False, '', '__contains__', 'asdf')    # vereq('asdf' in '', False)
+
+    def test_subscript(self):
+        self.checkequal(u'a', 'abc', '__getitem__', 0)
+        self.checkequal(u'c', 'abc', '__getitem__', -1)
+        self.checkequal(u'a', 'abc', '__getitem__', 0L)
+        self.checkequal(u'abc', 'abc', '__getitem__', slice(0, 3))
+        self.checkequal(u'abc', 'abc', '__getitem__', slice(0, 1000))
+        self.checkequal(u'a', 'abc', '__getitem__', slice(0, 1))
+        self.checkequal(u'', 'abc', '__getitem__', slice(0, 0))
+        # FIXME What about negative indices? This is handled differently by [] and __getitem__(slice)
+
+        self.checkraises(TypeError, 'abc', '__getitem__', 'def')
+
+    def test_slice(self):
+        self.checkequal('abc', 'abc', '__getslice__', 0, 1000)
+        self.checkequal('abc', 'abc', '__getslice__', 0, 3)
+        self.checkequal('ab', 'abc', '__getslice__', 0, 2)
+        self.checkequal('bc', 'abc', '__getslice__', 1, 3)
+        self.checkequal('b', 'abc', '__getslice__', 1, 2)
+        self.checkequal('', 'abc', '__getslice__', 2, 2)
+        self.checkequal('', 'abc', '__getslice__', 1000, 1000)
+        self.checkequal('', 'abc', '__getslice__', 2000, 1000)
+        self.checkequal('', 'abc', '__getslice__', 2, 1)
+        # FIXME What about negative indizes? This is handled differently by [] and __getslice__
+
+        self.checkraises(TypeError, 'abc', '__getslice__', 'def')
+
+    def test_mul(self):
+        self.checkequal('', 'abc', '__mul__', -1)
+        self.checkequal('', 'abc', '__mul__', 0)
+        self.checkequal('abc', 'abc', '__mul__', 1)
+        self.checkequal('abcabcabc', 'abc', '__mul__', 3)
+        self.checkraises(TypeError, 'abc', '__mul__')
+        self.checkraises(TypeError, 'abc', '__mul__', '')
+        # XXX: on a 64-bit system, this doesn't raise an overflow error,
+        # but either raises a MemoryError, or succeeds (if you have 54TiB)
+        #self.checkraises(OverflowError, 10000*'abc', '__mul__', 2000000000)
+
+    def test_join(self):
+        # join now works with any sequence type
+        # moved here, because the argument order is
+        # different in string.join (see the test in
+        # test.test_string.StringTest.test_join)
+        self.checkequal('a b c d', ' ', 'join', ['a', 'b', 'c', 'd'])
+        self.checkequal('abcd', '', 'join', ('a', 'b', 'c', 'd'))
+        self.checkequal('bd', '', 'join', ('', 'b', '', 'd'))
+        self.checkequal('ac', '', 'join', ('a', '', 'c', ''))
+        self.checkequal('w x y z', ' ', 'join', Sequence())
+        self.checkequal('abc', 'a', 'join', ('abc',))
+        self.checkequal('z', 'a', 'join', UserList(['z']))
+        if test_support.have_unicode:
+            self.checkequal(unicode('a.b.c'), unicode('.'), 'join', ['a', 'b', 'c'])
+            self.checkequal(unicode('a.b.c'), '.', 'join', [unicode('a'), 'b', 'c'])
+            self.checkequal(unicode('a.b.c'), '.', 'join', ['a', unicode('b'), 'c'])
+            self.checkequal(unicode('a.b.c'), '.', 'join', ['a', 'b', unicode('c')])
+            self.checkraises(TypeError, '.', 'join', ['a', unicode('b'), 3])
+        for i in [5, 25, 125]:
+            self.checkequal(((('a' * i) + '-') * i)[:-1], '-', 'join',
+                 ['a' * i] * i)
+            self.checkequal(((('a' * i) + '-') * i)[:-1], '-', 'join',
+                 ('a' * i,) * i)
+
+        self.checkraises(TypeError, ' ', 'join', BadSeq1())
+        self.checkequal('a b c', ' ', 'join', BadSeq2())
+
+        self.checkraises(TypeError, ' ', 'join')
+        self.checkraises(TypeError, ' ', 'join', 7)
+        self.checkraises(TypeError, ' ', 'join', Sequence([7, 'hello', 123L]))
+        try:
+            def f():
+                yield 4 + ""
+            self.fixtype(' ').join(f())
+        except TypeError, e:
+            if '+' not in str(e):
+                self.fail('join() ate exception message')
+        else:
+            self.fail('exception not raised')
+
+    def test_formatting(self):
+        self.checkequal('+hello+', '+%s+', '__mod__', 'hello')
+        self.checkequal('+10+', '+%d+', '__mod__', 10)
+        self.checkequal('a', "%c", '__mod__', "a")
+        self.checkequal('a', "%c", '__mod__', "a")
+        self.checkequal('"', "%c", '__mod__', 34)
+        self.checkequal('$', "%c", '__mod__', 36)
+        self.checkequal('10', "%d", '__mod__', 10)
+        self.checkequal('\x7f', "%c", '__mod__', 0x7f)
+
+        for ordinal in (-100, 0x200000):
+            # unicode raises ValueError, str raises OverflowError
+            self.checkraises((ValueError, OverflowError), '%c', '__mod__', ordinal)
+
+        self.checkequal(' 42', '%3ld', '__mod__', 42)
+        self.checkequal('0042.00', '%07.2f', '__mod__', 42)
+        self.checkequal('0042.00', '%07.2F', '__mod__', 42)
+
+        self.checkraises(TypeError, 'abc', '__mod__')
+        self.checkraises(TypeError, '%(foo)s', '__mod__', 42)
+        self.checkraises(TypeError, '%s%s', '__mod__', (42,))
+        self.checkraises(TypeError, '%c', '__mod__', (None,))
+        self.checkraises(ValueError, '%(foo', '__mod__', {})
+        self.checkraises(TypeError, '%(foo)s %(bar)s', '__mod__', ('foo', 42))
+
+        # argument names with properly nested brackets are supported
+        self.checkequal('bar', '%((foo))s', '__mod__', {'(foo)': 'bar'})
+
+        # 100 is a magic number in PyUnicode_Format, this forces a resize
+        self.checkequal(103*'a'+'x', '%sx', '__mod__', 103*'a')
+
+        self.checkraises(TypeError, '%*s', '__mod__', ('foo', 'bar'))
+        self.checkraises(TypeError, '%10.*f', '__mod__', ('foo', 42.))
+        self.checkraises(ValueError, '%10', '__mod__', (42,))
+
+    def test_floatformatting(self):
+        # float formatting
+        for prec in xrange(100):
+            format = '%%.%if' % prec
+            value = 0.01
+            for x in xrange(60):
+                value = value * 3.141592655 / 3.0 * 10.0
+                # The formatfloat() code in stringobject.c and
+                # unicodeobject.c uses a 120 byte buffer and switches from
+                # 'f' formatting to 'g' at precision 50, so we expect
+                # OverflowErrors for the ranges x < 50 and prec >= 67.
+                if x < 50 and prec >= 67:
+                    self.checkraises(OverflowError, format, "__mod__", value)
+                else:
+                    self.checkcall(format, "__mod__", value)
+
+    def test_inplace_rewrites(self):
+        # Check that strings don't copy and modify cached single-character strings
+        self.checkequal('a', 'A', 'lower')
+        self.checkequal(True, 'A', 'isupper')
+        self.checkequal('A', 'a', 'upper')
+        self.checkequal(True, 'a', 'islower')
+
+        self.checkequal('a', 'A', 'replace', 'A', 'a')
+        self.checkequal(True, 'A', 'isupper')
+
+        self.checkequal('A', 'a', 'capitalize')
+        self.checkequal(True, 'a', 'islower')
+
+        self.checkequal('A', 'a', 'swapcase')
+        self.checkequal(True, 'a', 'islower')
+
+        self.checkequal('A', 'a', 'title')
+        self.checkequal(True, 'a', 'islower')
+
+    def test_partition(self):
+
+        self.checkequal(('this is the par', 'ti', 'tion method'),
+            'this is the partition method', 'partition', 'ti')
+
+        # from raymond's original specification
+        S = 'http://www.python.org'
+        self.checkequal(('http', '://', 'www.python.org'), S, 'partition', '://')
+        self.checkequal(('http://www.python.org', '', ''), S, 'partition', '?')
+        self.checkequal(('', 'http://', 'www.python.org'), S, 'partition', 'http://')
+        self.checkequal(('http://www.python.', 'org', ''), S, 'partition', 'org')
+
+        self.checkraises(ValueError, S, 'partition', '')
+        self.checkraises(TypeError, S, 'partition', None)
+
+    def test_rpartition(self):
+
+        self.checkequal(('this is the rparti', 'ti', 'on method'),
+            'this is the rpartition method', 'rpartition', 'ti')
+
+        # from raymond's original specification
+        S = 'http://www.python.org'
+        self.checkequal(('http', '://', 'www.python.org'), S, 'rpartition', '://')
+        self.checkequal(('', '', 'http://www.python.org'), S, 'rpartition', '?')
+        self.checkequal(('', 'http://', 'www.python.org'), S, 'rpartition', 'http://')
+        self.checkequal(('http://www.python.', 'org', ''), S, 'rpartition', 'org')
+
+        self.checkraises(ValueError, S, 'rpartition', '')
+        self.checkraises(TypeError, S, 'rpartition', None)
+
+
+class MixinStrStringUserStringTest:
+    # Additional tests for 8bit strings, i.e. str, UserString and
+    # the string module
+
+    def test_maketrans(self):
+        self.assertEqual(
+           ''.join(map(chr, xrange(256))).replace('abc', 'xyz'),
+           string.maketrans('abc', 'xyz')
+        )
+        self.assertRaises(ValueError, string.maketrans, 'abc', 'xyzw')
+
+    def test_translate(self):
+        table = string.maketrans('abc', 'xyz')
+        self.checkequal('xyzxyz', 'xyzabcdef', 'translate', table, 'def')
+
+        table = string.maketrans('a', 'A')
+        self.checkequal('Abc', 'abc', 'translate', table)
+        self.checkequal('xyz', 'xyz', 'translate', table)
+        self.checkequal('yz', 'xyz', 'translate', table, 'x')
+        self.checkraises(ValueError, 'xyz', 'translate', 'too short', 'strip')
+        self.checkraises(ValueError, 'xyz', 'translate', 'too short')
+
+
+class MixinStrUserStringTest:
+    # Additional tests that only work with
+    # 8bit compatible object, i.e. str and UserString
+
+    if test_support.have_unicode:
+        def test_encoding_decoding(self):
+            codecs = [('rot13', 'uryyb jbeyq'),
+                      ('base64', 'aGVsbG8gd29ybGQ=\n'),
+                      ('hex', '68656c6c6f20776f726c64'),
+                      ('uu', 'begin 666 <data>\n+:&5L;&\\@=V]R;&0 \n \nend\n')]
+            for encoding, data in codecs:
+                self.checkequal(data, 'hello world', 'encode', encoding)
+                self.checkequal('hello world', data, 'decode', encoding)
+            # zlib is optional, so we make the test optional too...
+            try:
+                import zlib
+            except ImportError:
+                pass
+            else:
+                data = 'x\x9c\xcbH\xcd\xc9\xc9W(\xcf/\xcaI\x01\x00\x1a\x0b\x04]'
+                self.checkequal(data, 'hello world', 'encode', 'zlib')
+                self.checkequal('hello world', data, 'decode', 'zlib')
+
+            self.checkraises(TypeError, 'xyz', 'decode', 42)
+            self.checkraises(TypeError, 'xyz', 'encode', 42)
+
+
+class MixinStrUnicodeTest:
+    # Additional tests that only work with str and unicode.
+
+    def test_bug1001011(self):
+        # Make sure join returns a NEW object for single item sequences
+        # involving a subclass.
+        # Make sure that it is of the appropriate type.
+        # Check the optimisation still occurs for standard objects.
+        t = self.type2test
+        class subclass(t):
+            pass
+        s1 = subclass("abcd")
+        s2 = t().join([s1])
+        self.assert_(s1 is not s2)
+        self.assert_(type(s2) is t)
+
+        s1 = t("abcd")
+        s2 = t().join([s1])
+        self.assert_(s1 is s2)
+
+        # Should also test mixed-type join.
+        if t is unicode:
+            s1 = subclass("abcd")
+            s2 = "".join([s1])
+            self.assert_(s1 is not s2)
+            self.assert_(type(s2) is t)
+
+            s1 = t("abcd")
+            s2 = "".join([s1])
+            self.assert_(s1 is s2)
+
+        elif t is str:
+            s1 = subclass("abcd")
+            s2 = u"".join([s1])
+            self.assert_(s1 is not s2)
+            self.assert_(type(s2) is unicode) # promotes!
+
+            s1 = t("abcd")
+            s2 = u"".join([s1])
+            self.assert_(s1 is not s2)
+            self.assert_(type(s2) is unicode) # promotes!
+
+        else:
+            self.fail("unexpected type for MixinStrUnicodeTest %r" % t)

Added: vendor/Python/current/Lib/test/test.xml
===================================================================
--- vendor/Python/current/Lib/test/test.xml	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test.xml	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,115 @@
+<?xml version="1.0"?>
+<HTML xmlns:pp="http://www.isogen.com/paul/post-processor">
+<TITLE>Introduction to XSL</TITLE>
+<H1>Introduction to XSL</H1>
+	
+
+	
+		<HR/>
+		<H2>Overview
+</H2>
+		<UL>
+		
+	<LI>1.Intro</LI>
+
+	<LI>2.History</LI>
+
+	<LI>3.XSL Basics</LI>
+
+	<LI>Lunch</LI>
+
+	<LI>4.An XML Data Model</LI>
+
+	<LI>5.XSL Patterns</LI>
+
+	<LI>6.XSL Templates</LI>
+
+	<LI>7.XSL Formatting Model
+</LI>
+
+		</UL>
+	
+
+
+	
+
+	
+		<HR/>
+		<H2>Intro</H2>
+		<UL>
+		
+	<LI>Who am I?</LI>
+
+	<LI>Who are you?</LI>
+
+	<LI>Why are we here?
+</LI>
+
+		</UL>
+	
+
+
+	
+
+	
+		<HR/>
+		<H2>History: XML and SGML</H2>
+		<UL>
+		
+	<LI>XML is a subset of SGML.</LI>
+
+	<LI>SGML allows the separation of abstract content from formatting.</LI>
+
+	<LI>Also one of XML's primary virtues (in the doc publishing domain).
+</LI>
+
+		</UL>
+	
+
+
+	
+
+	
+		<HR/>
+		<H2>History: What are stylesheets?</H2>
+		<UL>
+		
+	<LI>Stylesheets specify the formatting of SGML/XML documents.</LI>
+
+	<LI>Stylesheets put the &quot;style&quot; back into documents.</LI>
+
+	<LI>New York Times content+NYT Stylesheet = NYT paper
+</LI>
+
+		</UL>
+	
+
+
+	
+
+	
+		<HR/>
+		<H2>History: FOSI</H2>
+		<UL>
+		
+	<LI>FOSI: &quot;Formatted Output Specification Instance&quot;
+<UL>
+	<LI>MIL-STD-28001
+	</LI>
+
+	<LI>FOSI's are SGML documents
+	</LI>
+
+	<LI>A stylesheet for another document
+	</LI>
+</UL></LI>
+
+	<LI>Obsolete but implemented...
+</LI>
+
+		</UL>
+	
+
+
+	
+</HTML>

Added: vendor/Python/current/Lib/test/test.xml.out
===================================================================
--- vendor/Python/current/Lib/test/test.xml.out	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test.xml.out	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<HTML xmlns:pp="http://www.isogen.com/paul/post-processor">
+<TITLE>Introduction to XSL</TITLE>
+<H1>Introduction to XSL</H1>
+	
+
+	
+		<HR></HR>
+		<H2>Overview
+</H2>
+		<UL>
+		
+	<LI>1.Intro</LI>
+
+	<LI>2.History</LI>
+
+	<LI>3.XSL Basics</LI>
+
+	<LI>Lunch</LI>
+
+	<LI>4.An XML Data Model</LI>
+
+	<LI>5.XSL Patterns</LI>
+
+	<LI>6.XSL Templates</LI>
+
+	<LI>7.XSL Formatting Model
+</LI>
+
+		</UL>
+	
+
+
+	
+
+	
+		<HR></HR>
+		<H2>Intro</H2>
+		<UL>
+		
+	<LI>Who am I?</LI>
+
+	<LI>Who are you?</LI>
+
+	<LI>Why are we here?
+</LI>
+
+		</UL>
+	
+
+
+	
+
+	
+		<HR></HR>
+		<H2>History: XML and SGML</H2>
+		<UL>
+		
+	<LI>XML is a subset of SGML.</LI>
+
+	<LI>SGML allows the separation of abstract content from formatting.</LI>
+
+	<LI>Also one of XML's primary virtues (in the doc publishing domain).
+</LI>
+
+		</UL>
+	
+
+
+	
+
+	
+		<HR></HR>
+		<H2>History: What are stylesheets?</H2>
+		<UL>
+		
+	<LI>Stylesheets specify the formatting of SGML/XML documents.</LI>
+
+	<LI>Stylesheets put the "style" back into documents.</LI>
+
+	<LI>New York Times content+NYT Stylesheet = NYT paper
+</LI>
+
+		</UL>
+	
+
+
+	
+
+	
+		<HR></HR>
+		<H2>History: FOSI</H2>
+		<UL>
+		
+	<LI>FOSI: "Formatted Output Specification Instance"
+<UL>
+	<LI>MIL-STD-28001
+	</LI>
+
+	<LI>FOSI's are SGML documents
+	</LI>
+
+	<LI>A stylesheet for another document
+	</LI>
+</UL></LI>
+
+	<LI>Obsolete but implemented...
+</LI>
+
+		</UL>
+	
+
+
+	
+</HTML>
\ No newline at end of file

Added: vendor/Python/current/Lib/test/test_MimeWriter.py
===================================================================
--- vendor/Python/current/Lib/test/test_MimeWriter.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_MimeWriter.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,170 @@
+"""Test program for MimeWriter module.
+
+The test program was too big to comfortably fit in the MimeWriter
+class, so it's here in its own file.
+
+This should generate Barry's example, modulo some quotes and newlines.
+
+"""
+
+
+from MimeWriter import MimeWriter
+
+SELLER = '''\
+INTERFACE Seller-1;
+
+TYPE Seller = OBJECT
+    DOCUMENTATION "A simple Seller interface to test ILU"
+    METHODS
+            price():INTEGER,
+    END;
+'''
+
+BUYER = '''\
+class Buyer:
+    def __setup__(self, maxprice):
+        self._maxprice = maxprice
+
+    def __main__(self, kos):
+        """Entry point upon arrival at a new KOS."""
+        broker = kos.broker()
+        # B4 == Barry's Big Bass Business :-)
+        seller = broker.lookup('Seller_1.Seller', 'B4')
+        if seller:
+            price = seller.price()
+            print 'Seller wants $', price, '... '
+            if price > self._maxprice:
+                print 'too much!'
+            else:
+                print "I'll take it!"
+        else:
+            print 'no seller found here'
+'''                                     # Don't ask why this comment is here
+
+STATE = '''\
+# instantiate a buyer instance and put it in a magic place for the KOS
+# to find.
+__kp__ = Buyer()
+__kp__.__setup__(500)
+'''
+
+SIMPLE_METADATA = [
+        ("Interpreter", "python"),
+        ("Interpreter-Version", "1.3"),
+        ("Owner-Name", "Barry Warsaw"),
+        ("Owner-Rendezvous", "bwarsaw at cnri.reston.va.us"),
+        ("Home-KSS", "kss.cnri.reston.va.us"),
+        ("Identifier", "hdl://cnri.kss/my_first_knowbot"),
+        ("Launch-Date", "Mon Feb 12 16:39:03 EST 1996"),
+        ]
+
+COMPLEX_METADATA = [
+        ("Metadata-Type", "complex"),
+        ("Metadata-Key", "connection"),
+        ("Access", "read-only"),
+        ("Connection-Description", "Barry's Big Bass Business"),
+        ("Connection-Id", "B4"),
+        ("Connection-Direction", "client"),
+        ]
+
+EXTERNAL_METADATA = [
+        ("Metadata-Type", "complex"),
+        ("Metadata-Key", "generic-interface"),
+        ("Access", "read-only"),
+        ("Connection-Description", "Generic Interface for All Knowbots"),
+        ("Connection-Id", "generic-kp"),
+        ("Connection-Direction", "client"),
+        ]
+
+
+def main():
+    import sys
+
+    # Toplevel headers
+
+    toplevel = MimeWriter(sys.stdout)
+    toplevel.addheader("From", "bwarsaw at cnri.reston.va.us")
+    toplevel.addheader("Date", "Mon Feb 12 17:21:48 EST 1996")
+    toplevel.addheader("To", "kss-submit at cnri.reston.va.us")
+    toplevel.addheader("MIME-Version", "1.0")
+
+    # Toplevel body parts
+
+    f = toplevel.startmultipartbody("knowbot", "801spam999",
+                                    [("version", "0.1")], prefix=0)
+    f.write("This is a multi-part message in MIME format.\n")
+
+    # First toplevel body part: metadata
+
+    md = toplevel.nextpart()
+    md.startmultipartbody("knowbot-metadata", "802spam999")
+
+    # Metadata part 1
+
+    md1 = md.nextpart()
+    md1.addheader("KP-Metadata-Type", "simple")
+    md1.addheader("KP-Access", "read-only")
+    m = MimeWriter(md1.startbody("message/rfc822"))
+    for key, value in SIMPLE_METADATA:
+        m.addheader("KPMD-" + key, value)
+    m.flushheaders()
+    del md1
+
+    # Metadata part 2
+
+    md2 = md.nextpart()
+    for key, value in COMPLEX_METADATA:
+        md2.addheader("KP-" + key, value)
+    f = md2.startbody("text/isl")
+    f.write(SELLER)
+    del md2
+
+    # Metadata part 3
+
+    md3 = md.nextpart()
+    f = md3.startbody("message/external-body",
+                      [("access-type", "URL"),
+                       ("URL", "hdl://cnri.kss/generic-knowbot")])
+    m = MimeWriter(f)
+    for key, value in EXTERNAL_METADATA:
+        md3.addheader("KP-" + key, value)
+    md3.startbody("text/isl")
+    # Phantom body doesn't need to be written
+
+    md.lastpart()
+
+    # Second toplevel body part: code
+
+    code = toplevel.nextpart()
+    code.startmultipartbody("knowbot-code", "803spam999")
+
+    # Code: buyer program source
+
+    buyer = code.nextpart()
+    buyer.addheader("KP-Module-Name", "BuyerKP")
+    f = buyer.startbody("text/plain")
+    f.write(BUYER)
+
+    code.lastpart()
+
+    # Third toplevel body part: state
+
+    state = toplevel.nextpart()
+    state.addheader("KP-Main-Module", "main")
+    state.startmultipartbody("knowbot-state", "804spam999")
+
+    # State: a bunch of assignments
+
+    st = state.nextpart()
+    st.addheader("KP-Module-Name", "main")
+    f = st.startbody("text/plain")
+    f.write(STATE)
+
+    state.lastpart()
+
+    # End toplevel body parts
+
+    toplevel.lastpart()
+
+
+main()

Added: vendor/Python/current/Lib/test/test_StringIO.py
===================================================================
--- vendor/Python/current/Lib/test/test_StringIO.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_StringIO.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,167 @@
+# Tests StringIO and cStringIO
+
+import unittest
+import StringIO
+import cStringIO
+import types
+from test import test_support
+
+
+class TestGenericStringIO(unittest.TestCase):
+    # use a class variable MODULE to define which module is being tested
+
+    # Line of data to test as string
+    _line = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!'
+
+    # Constructor to use for the test data (._line is passed to this
+    # constructor)
+    constructor = str
+
+    def setUp(self):
+        self._line = self.constructor(self._line)
+        self._lines = self.constructor((self._line + '\n') * 5)
+        self._fp = self.MODULE.StringIO(self._lines)
+
+    def test_reads(self):
+        eq = self.assertEqual
+        self.assertRaises(TypeError, self._fp.seek)
+        eq(self._fp.read(10), self._line[:10])
+        eq(self._fp.readline(), self._line[10:] + '\n')
+        eq(len(self._fp.readlines(60)), 2)
+
+    def test_writes(self):
+        f = self.MODULE.StringIO()
+        self.assertRaises(TypeError, f.seek)
+        f.write(self._line[:6])
+        f.seek(3)
+        f.write(self._line[20:26])
+        f.write(self._line[52])
+        self.assertEqual(f.getvalue(), 'abcuvwxyz!')
+
+    def test_writelines(self):
+        f = self.MODULE.StringIO()
+        f.writelines([self._line[0], self._line[1], self._line[2]])
+        f.seek(0)
+        self.assertEqual(f.getvalue(), 'abc')
+
+    def test_writelines_error(self):
+        def errorGen():
+            yield 'a'
+            raise KeyboardInterrupt()
+        f = self.MODULE.StringIO()
+        self.assertRaises(KeyboardInterrupt, f.writelines, errorGen())
+
+    def test_truncate(self):
+        eq = self.assertEqual
+        f = self.MODULE.StringIO()
+        f.write(self._lines)
+        f.seek(10)
+        f.truncate()
+        eq(f.getvalue(), 'abcdefghij')
+        f.truncate(5)
+        eq(f.getvalue(), 'abcde')
+        f.write('xyz')
+        eq(f.getvalue(), 'abcdexyz')
+        f.close()
+        self.assertRaises(ValueError, f.write, 'frobnitz')
+
+    def test_closed_flag(self):
+        f = self.MODULE.StringIO()
+        self.assertEqual(f.closed, False)
+        f.close()
+        self.assertEqual(f.closed, True)
+        f = self.MODULE.StringIO("abc")
+        self.assertEqual(f.closed, False)
+        f.close()
+        self.assertEqual(f.closed, True)
+
+    def test_isatty(self):
+        f = self.MODULE.StringIO()
+        self.assertRaises(TypeError, f.isatty, None)
+        self.assertEqual(f.isatty(), False)
+        f.close()
+        self.assertRaises(ValueError, f.isatty)
+
+    def test_iterator(self):
+        eq = self.assertEqual
+        unless = self.failUnless
+        eq(iter(self._fp), self._fp)
+        # Does this object support the iteration protocol?
+        unless(hasattr(self._fp, '__iter__'))
+        unless(hasattr(self._fp, 'next'))
+        i = 0
+        for line in self._fp:
+            eq(line, self._line + '\n')
+            i += 1
+        eq(i, 5)
+        self._fp.close()
+        self.assertRaises(ValueError, self._fp.next)
+
+class TestStringIO(TestGenericStringIO):
+    MODULE = StringIO
+
+    def test_unicode(self):
+
+        if not test_support.have_unicode: return
+
+        # The StringIO module also supports concatenating Unicode
+        # snippets to larger Unicode strings. This is tested by this
+        # method. Note that cStringIO does not support this extension.
+
+        f = self.MODULE.StringIO()
+        f.write(self._line[:6])
+        f.seek(3)
+        f.write(unicode(self._line[20:26]))
+        f.write(unicode(self._line[52]))
+        s = f.getvalue()
+        self.assertEqual(s, unicode('abcuvwxyz!'))
+        self.assertEqual(type(s), types.UnicodeType)
+
+class TestcStringIO(TestGenericStringIO):
+    MODULE = cStringIO
+
+    def test_unicode(self):
+
+        if not test_support.have_unicode: return
+
+        # The cStringIO module converts Unicode strings to character
+        # strings when writing them to cStringIO objects.
+        # Check that this works.
+
+        f = self.MODULE.StringIO()
+        f.write(unicode(self._line[:5]))
+        s = f.getvalue()
+        self.assertEqual(s, 'abcde')
+        self.assertEqual(type(s), types.StringType)
+
+        f = self.MODULE.StringIO(unicode(self._line[:5]))
+        s = f.getvalue()
+        self.assertEqual(s, 'abcde')
+        self.assertEqual(type(s), types.StringType)
+
+        self.assertRaises(UnicodeEncodeError, self.MODULE.StringIO,
+                          unicode('\xf4', 'latin-1'))
+
+import sys
+if sys.platform.startswith('java'):
+    # Jython doesn't have a buffer object, so we just do a useless
+    # fake of the buffer tests.
+    buffer = str
+
+class TestBufferStringIO(TestStringIO):
+    constructor = buffer
+
+class TestBuffercStringIO(TestcStringIO):
+    constructor = buffer
+
+
+def test_main():
+    test_support.run_unittest(
+        TestStringIO,
+        TestcStringIO,
+        TestBufferStringIO,
+        TestBuffercStringIO
+    )
+
+if __name__ == '__main__':
+    test_main()

Added: vendor/Python/current/Lib/test/test___all__.py
===================================================================
--- vendor/Python/current/Lib/test/test___all__.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test___all__.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,185 @@
+import unittest
+from test import test_support
+
+from test.test_support import verify, verbose
+import sys
+import warnings
+
+warnings.filterwarnings("ignore",
+                        "the gopherlib module is deprecated",
+                        DeprecationWarning,
+                        "<string>")
+
+class AllTest(unittest.TestCase):
+
+    def check_all(self, modname):
+        names = {}
+        try:
+            exec "import %s" % modname in names
+        except ImportError:
+            # Silent fail here seems the best route since some modules
+            # may not be available in all environments.
+            return
+        verify(hasattr(sys.modules[modname], "__all__"),
+               "%s has no __all__ attribute" % modname)
+        names = {}
+        exec "from %s import *" % modname in names
+        if names.has_key("__builtins__"):
+            del names["__builtins__"]
+        keys = set(names)
+        all = set(sys.modules[modname].__all__)
+        verify(keys==all, "%s != %s" % (keys, all))
+
+    def test_all(self):
+        if not sys.platform.startswith('java'):
+            # In case _socket fails to build, make this test fail more gracefully
+            # than an AttributeError somewhere deep in CGIHTTPServer.
+            import _socket
+
+        self.check_all("BaseHTTPServer")
+        self.check_all("Bastion")
+        self.check_all("CGIHTTPServer")
+        self.check_all("ConfigParser")
+        self.check_all("Cookie")
+        self.check_all("MimeWriter")
+        self.check_all("Queue")
+        self.check_all("SimpleHTTPServer")
+        self.check_all("SocketServer")
+        self.check_all("StringIO")
+        self.check_all("UserString")
+        self.check_all("aifc")
+        self.check_all("atexit")
+        self.check_all("audiodev")
+        self.check_all("base64")
+        self.check_all("bdb")
+        self.check_all("binhex")
+        self.check_all("calendar")
+        self.check_all("cgi")
+        self.check_all("cmd")
+        self.check_all("code")
+        self.check_all("codecs")
+        self.check_all("codeop")
+        self.check_all("colorsys")
+        self.check_all("commands")
+        self.check_all("compileall")
+        self.check_all("copy")
+        self.check_all("copy_reg")
+        self.check_all("csv")
+        self.check_all("dbhash")
+        self.check_all("decimal")
+        self.check_all("difflib")
+        self.check_all("dircache")
+        self.check_all("dis")
+        self.check_all("doctest")
+        self.check_all("dummy_thread")
+        self.check_all("dummy_threading")
+        self.check_all("filecmp")
+        self.check_all("fileinput")
+        self.check_all("fnmatch")
+        self.check_all("fpformat")
+        self.check_all("ftplib")
+        self.check_all("getopt")
+        self.check_all("getpass")
+        self.check_all("gettext")
+        self.check_all("glob")
+        self.check_all("gopherlib")
+        self.check_all("gzip")
+        self.check_all("heapq")
+        self.check_all("htmllib")
+        self.check_all("httplib")
+        self.check_all("ihooks")
+        self.check_all("imaplib")
+        self.check_all("imghdr")
+        self.check_all("imputil")
+        self.check_all("keyword")
+        self.check_all("linecache")
+        self.check_all("locale")
+        self.check_all("macpath")
+        self.check_all("macurl2path")
+        self.check_all("mailbox")
+        self.check_all("mailcap")
+        self.check_all("mhlib")
+        self.check_all("mimetools")
+        self.check_all("mimetypes")
+        self.check_all("mimify")
+        self.check_all("multifile")
+        self.check_all("netrc")
+        self.check_all("nntplib")
+        self.check_all("ntpath")
+        self.check_all("opcode")
+        self.check_all("optparse")
+        self.check_all("os")
+        self.check_all("os2emxpath")
+        self.check_all("pdb")
+        self.check_all("pickle")
+        self.check_all("pickletools")
+        self.check_all("pipes")
+        self.check_all("popen2")
+        self.check_all("poplib")
+        self.check_all("posixpath")
+        self.check_all("pprint")
+        self.check_all("profile")
+        self.check_all("pstats")
+        self.check_all("pty")
+        self.check_all("py_compile")
+        self.check_all("pyclbr")
+        self.check_all("quopri")
+        self.check_all("random")
+        self.check_all("re")
+        self.check_all("repr")
+        self.check_all("rexec")
+        self.check_all("rfc822")
+        self.check_all("rlcompleter")
+        self.check_all("robotparser")
+        self.check_all("sched")
+        self.check_all("sets")
+        self.check_all("sgmllib")
+        self.check_all("shelve")
+        self.check_all("shlex")
+        self.check_all("shutil")
+        self.check_all("smtpd")
+        self.check_all("smtplib")
+        self.check_all("sndhdr")
+        self.check_all("socket")
+        self.check_all("_strptime")
+        self.check_all("symtable")
+        self.check_all("tabnanny")
+        self.check_all("tarfile")
+        self.check_all("telnetlib")
+        self.check_all("tempfile")
+        self.check_all("textwrap")
+        self.check_all("threading")
+        self.check_all("timeit")
+        self.check_all("toaiff")
+        self.check_all("tokenize")
+        self.check_all("traceback")
+        self.check_all("tty")
+        self.check_all("unittest")
+        self.check_all("urllib")
+        self.check_all("urlparse")
+        self.check_all("uu")
+        self.check_all("warnings")
+        self.check_all("wave")
+        self.check_all("weakref")
+        self.check_all("webbrowser")
+        self.check_all("xdrlib")
+        self.check_all("zipfile")
+
+        # rlcompleter needs special consideration; it import readline which
+        # initializes GNU readline which calls setlocale(LC_CTYPE, "")... :-(
+        try:
+            self.check_all("rlcompleter")
+        finally:
+            try:
+                import locale
+            except ImportError:
+                pass
+            else:
+                locale.setlocale(locale.LC_CTYPE, 'C')
+
+
+def test_main():
+    test_support.run_unittest(AllTest)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test___future__.py
===================================================================
--- vendor/Python/current/Lib/test/test___future__.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test___future__.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,59 @@
+#! /usr/bin/env python
+from test.test_support import verbose, verify
+from types import TupleType, StringType, IntType
+import __future__
+
+GOOD_SERIALS = ("alpha", "beta", "candidate", "final")
+
+features = __future__.all_feature_names
+
+# Verify that all_feature_names appears correct.
+given_feature_names = features[:]
+for name in dir(__future__):
+    obj = getattr(__future__, name, None)
+    if obj is not None and isinstance(obj, __future__._Feature):
+        verify(name in given_feature_names,
+               "%r should have been in all_feature_names" % name)
+        given_feature_names.remove(name)
+verify(len(given_feature_names) == 0,
+       "all_feature_names has too much: %r" % given_feature_names)
+del given_feature_names
+
+for feature in features:
+    value = getattr(__future__, feature)
+    if verbose:
+        print "Checking __future__ ", feature, "value", value
+
+    optional = value.getOptionalRelease()
+    mandatory = value.getMandatoryRelease()
+
+    verify(type(optional) is TupleType, "optional isn't tuple")
+    verify(len(optional) == 5, "optional isn't 5-tuple")
+    major, minor, micro, level, serial = optional
+    verify(type(major) is IntType, "optional major isn't int")
+    verify(type(minor) is IntType, "optional minor isn't int")
+    verify(type(micro) is IntType, "optional micro isn't int")
+    verify(isinstance(level, basestring), "optional level isn't string")
+    verify(level in GOOD_SERIALS,
+           "optional level string has unknown value")
+    verify(type(serial) is IntType, "optional serial isn't int")
+
+    verify(type(mandatory) is TupleType or
+           mandatory is None, "mandatory isn't tuple or None")
+    if mandatory is not None:
+        verify(len(mandatory) == 5, "mandatory isn't 5-tuple")
+        major, minor, micro, level, serial = mandatory
+        verify(type(major) is IntType, "mandatory major isn't int")
+        verify(type(minor) is IntType, "mandatory minor isn't int")
+        verify(type(micro) is IntType, "mandatory micro isn't int")
+        verify(isinstance(level, basestring), "mandatory level isn't string")
+        verify(level in GOOD_SERIALS,
+               "mandatory serial string has unknown value")
+        verify(type(serial) is IntType, "mandatory serial isn't int")
+        verify(optional < mandatory,
+               "optional not less than mandatory, and mandatory not None")
+
+    verify(hasattr(value, "compiler_flag"),
+           "feature is missing a .compiler_flag attr")
+    verify(type(getattr(value, "compiler_flag")) is IntType,
+           ".compiler_flag isn't int")

Added: vendor/Python/current/Lib/test/test__locale.py
===================================================================
--- vendor/Python/current/Lib/test/test__locale.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test__locale.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,124 @@
+from test.test_support import verbose, TestSkipped, run_unittest
+from _locale import (setlocale, LC_NUMERIC, RADIXCHAR, THOUSEP, nl_langinfo,
+                    localeconv, Error)
+import unittest
+from platform import uname
+
+if uname()[0] == "Darwin":
+    maj, min, mic = [int(part) for part in uname()[2].split(".")]
+    if (maj, min, mic) < (8, 0, 0):
+        raise TestSkipped("locale support broken for OS X < 10.4")
+
+candidate_locales = ['es_UY', 'fr_FR', 'fi_FI', 'es_CO', 'pt_PT', 'it_IT',
+    'et_EE', 'es_PY', 'no_NO', 'nl_NL', 'lv_LV', 'el_GR', 'be_BY', 'fr_BE',
+    'ro_RO', 'ru_UA', 'ru_RU', 'es_VE', 'ca_ES', 'se_NO', 'es_EC', 'id_ID',
+    'ka_GE', 'es_CL', 'hu_HU', 'wa_BE', 'lt_LT', 'sl_SI', 'hr_HR', 'es_AR',
+    'es_ES', 'oc_FR', 'gl_ES', 'bg_BG', 'is_IS', 'mk_MK', 'de_AT', 'pt_BR',
+    'da_DK', 'nn_NO', 'cs_CZ', 'de_LU', 'es_BO', 'sq_AL', 'sk_SK', 'fr_CH',
+    'de_DE', 'sr_YU', 'br_FR', 'nl_BE', 'sv_FI', 'pl_PL', 'fr_CA', 'fo_FO',
+    'bs_BA', 'fr_LU', 'kl_GL', 'fa_IR', 'de_BE', 'sv_SE', 'it_CH', 'uk_UA',
+    'eu_ES', 'vi_VN', 'af_ZA', 'nb_NO', 'en_DK', 'tg_TJ', 'en_US',
+    'es_ES.ISO8859-1', 'fr_FR.ISO8859-15', 'ru_RU.KOI8-R', 'ko_KR.eucKR']
+
+# List known locale values to test against when available.
+# Dict formatted as ``<locale> : (<decimal_point>, <thousands_sep>)``.  If a
+# value is not known, use '' .
+known_numerics = {'fr_FR' : (',', ''), 'en_US':('.', ',')}
+
+class _LocaleTests(unittest.TestCase):
+
+    def setUp(self):
+        self.oldlocale = setlocale(LC_NUMERIC)
+
+    def tearDown(self):
+        setlocale(LC_NUMERIC, self.oldlocale)
+
+    # Want to know what value was calculated, what it was compared against,
+    # what function was used for the calculation, what type of data was used,
+    # the locale that was supposedly set, and the actual locale that is set.
+    lc_numeric_err_msg = "%s != %s (%s for %s; set to %s, using %s)"
+
+    def numeric_tester(self, calc_type, calc_value, data_type, used_locale):
+        """Compare calculation against known value, if available"""
+        try:
+            set_locale = setlocale(LC_NUMERIC)
+        except Error:
+            set_locale = "<not able to determine>"
+        known_value = known_numerics.get(used_locale,
+                                    ('', ''))[data_type is 'thousands_sep']
+        if known_value and calc_value:
+            self.assertEquals(calc_value, known_value,
+                                self.lc_numeric_err_msg % (
+                                    calc_value, known_value,
+                                    calc_type, data_type, set_locale,
+                                    used_locale))
+
+    def test_lc_numeric_nl_langinfo(self):
+        # Test nl_langinfo against known values
+        for loc in candidate_locales:
+            try:
+                setlocale(LC_NUMERIC, loc)
+            except Error:
+                continue
+            for li, lc in ((RADIXCHAR, "decimal_point"),
+                            (THOUSEP, "thousands_sep")):
+                self.numeric_tester('nl_langinfo', nl_langinfo(li), lc, loc)
+
+    def test_lc_numeric_localeconv(self):
+        # Test localeconv against known values
+        for loc in candidate_locales:
+            try:
+                setlocale(LC_NUMERIC, loc)
+            except Error:
+                continue
+            for li, lc in ((RADIXCHAR, "decimal_point"),
+                            (THOUSEP, "thousands_sep")):
+                self.numeric_tester('localeconv', localeconv()[lc], lc, loc)
+
+    def test_lc_numeric_basic(self):
+        # Test nl_langinfo against localeconv
+        for loc in candidate_locales:
+            try:
+                setlocale(LC_NUMERIC, loc)
+            except Error:
+                continue
+            for li, lc in ((RADIXCHAR, "decimal_point"),
+                            (THOUSEP, "thousands_sep")):
+                nl_radixchar = nl_langinfo(li)
+                li_radixchar = localeconv()[lc]
+                try:
+                    set_locale = setlocale(LC_NUMERIC)
+                except Error:
+                    set_locale = "<not able to determine>"
+                self.assertEquals(nl_radixchar, li_radixchar,
+                                "%s (nl_langinfo) != %s (localeconv) "
+                                "(set to %s, using %s)" % (
+                                                nl_radixchar, li_radixchar,
+                                                loc, set_locale))
+
+    def test_float_parsing(self):
+        # Bug #1391872: Test whether float parsing is okay on European
+        # locales.
+        for loc in candidate_locales:
+            try:
+                setlocale(LC_NUMERIC, loc)
+            except Error:
+                continue
+
+            # Ignore buggy locale databases. (Mac OS 10.4 and some other BSDs)
+            if loc == 'eu_ES' and localeconv()['decimal_point'] == "' ":
+                continue
+
+            self.assertEquals(int(eval('3.14') * 100), 314,
+                                "using eval('3.14') failed for %s" % loc)
+            self.assertEquals(int(float('3.14') * 100), 314,
+                                "using float('3.14') failed for %s" % loc)
+            if localeconv()['decimal_point'] != '.':
+                self.assertRaises(ValueError, float,
+                                  localeconv()['decimal_point'].join(['1', '23']))
+
+def test_main():
+    run_unittest(_LocaleTests)
+
+if __name__ == '__main__':
+    test_main()

Added: vendor/Python/current/Lib/test/test_aepack.py
===================================================================
--- vendor/Python/current/Lib/test/test_aepack.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_aepack.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,84 @@
+# Copyright (C) 2003 Python Software Foundation
+
+import unittest
+import aepack
+import aetypes
+import os
+from test import test_support
+
+class TestAepack(unittest.TestCase):
+    OBJECTS = [
+        aetypes.Enum('enum'),
+        aetypes.Type('type'),
+        aetypes.Keyword('kwrd'),
+        aetypes.Range(1, 10),
+        aetypes.Comparison(1, '<   ', 10),
+        aetypes.Logical('not ', 1),
+        aetypes.IntlText(0, 0, 'international text'),
+        aetypes.IntlWritingCode(0,0),
+        aetypes.QDPoint(50,100),
+        aetypes.QDRectangle(50,100,150,200),
+        aetypes.RGBColor(0x7000, 0x6000, 0x5000),
+        aetypes.Unknown('xxxx', 'unknown type data'),
+        aetypes.Character(1),
+        aetypes.Character(2, aetypes.Line(2)),
+    ]
+
+    def test_roundtrip_string(self):
+        o = 'a string'
+        packed = aepack.pack(o)
+        unpacked = aepack.unpack(packed)
+        self.assertEqual(o, unpacked)
+
+    def test_roundtrip_int(self):
+        o = 12
+        packed = aepack.pack(o)
+        unpacked = aepack.unpack(packed)
+        self.assertEqual(o, unpacked)
+
+    def test_roundtrip_float(self):
+        o = 12.1
+        packed = aepack.pack(o)
+        unpacked = aepack.unpack(packed)
+        self.assertEqual(o, unpacked)
+
+    def test_roundtrip_None(self):
+        o = None
+        packed = aepack.pack(o)
+        unpacked = aepack.unpack(packed)
+        self.assertEqual(o, unpacked)
+
+    def test_roundtrip_aeobjects(self):
+        for o in self.OBJECTS:
+            packed = aepack.pack(o)
+            unpacked = aepack.unpack(packed)
+            self.assertEqual(repr(o), repr(unpacked))
+
+    def test_roundtrip_FSSpec(self):
+        try:
+            import Carbon.File
+        except:
+            return
+        o = Carbon.File.FSSpec(os.curdir)
+        packed = aepack.pack(o)
+        unpacked = aepack.unpack(packed)
+        self.assertEqual(o.as_pathname(), unpacked.as_pathname())
+
+    def test_roundtrip_Alias(self):
+        try:
+            import Carbon.File
+        except:
+            return
+        o = Carbon.File.FSSpec(os.curdir).NewAliasMinimal()
+        packed = aepack.pack(o)
+        unpacked = aepack.unpack(packed)
+        self.assertEqual(o.FSResolveAlias(None)[0].as_pathname(),
+            unpacked.FSResolveAlias(None)[0].as_pathname())
+
+
+def test_main():
+    test_support.run_unittest(TestAepack)
+
+
+if __name__ == '__main__':
+    test_main()


Property changes on: vendor/Python/current/Lib/test/test_aepack.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/test/test_al.py
===================================================================
--- vendor/Python/current/Lib/test/test_al.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_al.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,23 @@
+#! /usr/bin/env python
+"""Whimpy test script for the al module
+   Roger E. Masse
+"""
+import al
+from test.test_support import verbose
+
+alattrs = ['__doc__', '__name__', 'getdefault', 'getminmax', 'getname', 'getparams',
+           'newconfig', 'openport', 'queryparams', 'setparams']
+
+# This is a very unobtrusive test for the existence of the al module and all its
+# attributes.  More comprehensive examples can be found in Demo/al
+
+def main():
+    # touch all the attributes of al without doing anything
+    if verbose:
+        print 'Touching al module attributes...'
+    for attr in alattrs:
+        if verbose:
+            print 'touching: ', attr
+        getattr(al, attr)
+
+main()


Property changes on: vendor/Python/current/Lib/test/test_al.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/test/test_anydbm.py
===================================================================
--- vendor/Python/current/Lib/test/test_anydbm.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_anydbm.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,95 @@
+#! /usr/bin/env python
+"""Test script for the anydbm module
+   based on testdumbdbm.py
+"""
+
+import os
+import unittest
+import anydbm
+import glob
+from test import test_support
+
+_fname = test_support.TESTFN
+
+def _delete_files():
+    # we don't know the precise name the underlying database uses
+    # so we use glob to locate all names
+    for f in glob.glob(_fname + "*"):
+        try:
+            os.unlink(f)
+        except OSError:
+            pass
+
+class AnyDBMTestCase(unittest.TestCase):
+    _dict = {'0': '',
+             'a': 'Python:',
+             'b': 'Programming',
+             'c': 'the',
+             'd': 'way',
+             'f': 'Guido',
+             'g': 'intended'
+             }
+
+    def __init__(self, *args):
+        unittest.TestCase.__init__(self, *args)
+
+    def test_anydbm_creation(self):
+        f = anydbm.open(_fname, 'c')
+        self.assertEqual(f.keys(), [])
+        for key in self._dict:
+            f[key] = self._dict[key]
+        self.read_helper(f)
+        f.close()
+
+    def test_anydbm_modification(self):
+        self.init_db()
+        f = anydbm.open(_fname, 'c')
+        self._dict['g'] = f['g'] = "indented"
+        self.read_helper(f)
+        f.close()
+
+    def test_anydbm_read(self):
+        self.init_db()
+        f = anydbm.open(_fname, 'r')
+        self.read_helper(f)
+        f.close()
+
+    def test_anydbm_keys(self):
+        self.init_db()
+        f = anydbm.open(_fname, 'r')
+        keys = self.keys_helper(f)
+        f.close()
+
+    def read_helper(self, f):
+        keys = self.keys_helper(f)
+        for key in self._dict:
+            self.assertEqual(self._dict[key], f[key])
+
+    def init_db(self):
+        f = anydbm.open(_fname, 'n')
+        for k in self._dict:
+            f[k] = self._dict[k]
+        f.close()
+
+    def keys_helper(self, f):
+        keys = f.keys()
+        keys.sort()
+        dkeys = self._dict.keys()
+        dkeys.sort()
+        self.assertEqual(keys, dkeys)
+        return keys
+
+    def tearDown(self):
+        _delete_files()
+
+    def setUp(self):
+        _delete_files()
+
+def test_main():
+    try:
+        test_support.run_unittest(AnyDBMTestCase)
+    finally:
+        _delete_files()
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_applesingle.py
===================================================================
--- vendor/Python/current/Lib/test/test_applesingle.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_applesingle.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,72 @@
+# Copyright (C) 2003 Python Software Foundation
+
+import unittest
+import macostools
+import Carbon.File
+import MacOS
+import os
+import sys
+from test import test_support
+import struct
+import applesingle
+
+AS_MAGIC=0x00051600
+AS_VERSION=0x00020000
+dataforkdata = 'hello\r\0world\n'
+resourceforkdata = 'goodbye\ncruel\0world\r'
+
+applesingledata = struct.pack(">ll16sh", AS_MAGIC, AS_VERSION, "foo", 2) + \
+    struct.pack(">llllll", 1, 50, len(dataforkdata),
+        2, 50+len(dataforkdata), len(resourceforkdata)) + \
+    dataforkdata + \
+    resourceforkdata
+TESTFN2 = test_support.TESTFN + '2'
+
+class TestApplesingle(unittest.TestCase):
+
+    def setUp(self):
+        fp = open(test_support.TESTFN, 'w')
+        fp.write(applesingledata)
+        fp.close()
+
+    def tearDown(self):
+        try:
+            os.unlink(test_support.TESTFN)
+        except:
+            pass
+        try:
+            os.unlink(TESTFN2)
+        except:
+            pass
+
+    def compareData(self, isrf, data):
+        if isrf:
+            fp = MacOS.openrf(TESTFN2, '*rb')
+        else:
+            fp = open(TESTFN2, 'rb')
+        filedata = fp.read(1000)
+        self.assertEqual(data, filedata)
+
+    def test_applesingle(self):
+        try:
+            os.unlink(TESTFN2)
+        except:
+            pass
+        applesingle.decode(test_support.TESTFN, TESTFN2)
+        self.compareData(False, dataforkdata)
+        self.compareData(True, resourceforkdata)
+
+    def test_applesingle_resonly(self):
+        try:
+            os.unlink(TESTFN2)
+        except:
+            pass
+        applesingle.decode(test_support.TESTFN, TESTFN2, resonly=True)
+        self.compareData(False, resourceforkdata)
+
+def test_main():
+    test_support.run_unittest(TestApplesingle)
+
+
+if __name__ == '__main__':
+    test_main()

Added: vendor/Python/current/Lib/test/test_array.py
===================================================================
--- vendor/Python/current/Lib/test/test_array.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_array.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,996 @@
+#! /usr/bin/env python
+"""Test the arraymodule.
+   Roger E. Masse
+"""
+
+import unittest
+from test import test_support
+from weakref import proxy
+import array, cStringIO, math
+from cPickle import loads, dumps
+
+class ArraySubclass(array.array):
+    pass
+
+class ArraySubclassWithKwargs(array.array):
+    def __init__(self, typecode, newarg=None):
+        array.array.__init__(typecode)
+
+tests = [] # list to accumulate all tests
+typecodes = "cubBhHiIlLfd"
+
+class BadConstructorTest(unittest.TestCase):
+
+    def test_constructor(self):
+        self.assertRaises(TypeError, array.array)
+        self.assertRaises(TypeError, array.array, spam=42)
+        self.assertRaises(TypeError, array.array, 'xx')
+        self.assertRaises(ValueError, array.array, 'x')
+
+tests.append(BadConstructorTest)
+
+class BaseTest(unittest.TestCase):
+    # Required class attributes (provided by subclasses
+    # typecode: the typecode to test
+    # example: an initializer usable in the constructor for this type
+    # smallerexample: the same length as example, but smaller
+    # biggerexample: the same length as example, but bigger
+    # outside: An entry that is not in example
+    # minitemsize: the minimum guaranteed itemsize
+
+    def assertEntryEqual(self, entry1, entry2):
+        self.assertEqual(entry1, entry2)
+
+    def badtypecode(self):
+        # Return a typecode that is different from our own
+        return typecodes[(typecodes.index(self.typecode)+1) % len(typecodes)]
+
+    def test_constructor(self):
+        a = array.array(self.typecode)
+        self.assertEqual(a.typecode, self.typecode)
+        self.assert_(a.itemsize>=self.minitemsize)
+        self.assertRaises(TypeError, array.array, self.typecode, None)
+
+    def test_len(self):
+        a = array.array(self.typecode)
+        a.append(self.example[0])
+        self.assertEqual(len(a), 1)
+
+        a = array.array(self.typecode, self.example)
+        self.assertEqual(len(a), len(self.example))
+
+    def test_buffer_info(self):
+        a = array.array(self.typecode, self.example)
+        self.assertRaises(TypeError, a.buffer_info, 42)
+        bi = a.buffer_info()
+        self.assert_(isinstance(bi, tuple))
+        self.assertEqual(len(bi), 2)
+        self.assert_(isinstance(bi[0], (int, long)))
+        self.assert_(isinstance(bi[1], int))
+        self.assertEqual(bi[1], len(a))
+
+    def test_byteswap(self):
+        a = array.array(self.typecode, self.example)
+        self.assertRaises(TypeError, a.byteswap, 42)
+        if a.itemsize in (1, 2, 4, 8):
+            b = array.array(self.typecode, self.example)
+            b.byteswap()
+            if a.itemsize==1:
+                self.assertEqual(a, b)
+            else:
+                self.assertNotEqual(a, b)
+            b.byteswap()
+            self.assertEqual(a, b)
+
+    def test_copy(self):
+        import copy
+        a = array.array(self.typecode, self.example)
+        b = copy.copy(a)
+        self.assertNotEqual(id(a), id(b))
+        self.assertEqual(a, b)
+
+    def test_deepcopy(self):
+        import copy
+        a = array.array(self.typecode, self.example)
+        b = copy.deepcopy(a)
+        self.assertNotEqual(id(a), id(b))
+        self.assertEqual(a, b)
+
+    def test_pickle(self):
+        for protocol in (0, 1, 2):
+            a = array.array(self.typecode, self.example)
+            b = loads(dumps(a, protocol))
+            self.assertNotEqual(id(a), id(b))
+            self.assertEqual(a, b)
+
+            a = ArraySubclass(self.typecode, self.example)
+            a.x = 10
+            b = loads(dumps(a, protocol))
+            self.assertNotEqual(id(a), id(b))
+            self.assertEqual(a, b)
+            self.assertEqual(a.x, b.x)
+            self.assertEqual(type(a), type(b))
+
+    def test_pickle_for_empty_array(self):
+        for protocol in (0, 1, 2):
+            a = array.array(self.typecode)
+            b = loads(dumps(a, protocol))
+            self.assertNotEqual(id(a), id(b))
+            self.assertEqual(a, b)
+
+            a = ArraySubclass(self.typecode)
+            a.x = 10
+            b = loads(dumps(a, protocol))
+            self.assertNotEqual(id(a), id(b))
+            self.assertEqual(a, b)
+            self.assertEqual(a.x, b.x)
+            self.assertEqual(type(a), type(b))
+
+    def test_insert(self):
+        a = array.array(self.typecode, self.example)
+        a.insert(0, self.example[0])
+        self.assertEqual(len(a), 1+len(self.example))
+        self.assertEqual(a[0], a[1])
+        self.assertRaises(TypeError, a.insert)
+        self.assertRaises(TypeError, a.insert, None)
+        self.assertRaises(TypeError, a.insert, 0, None)
+
+        a = array.array(self.typecode, self.example)
+        a.insert(-1, self.example[0])
+        self.assertEqual(
+            a,
+            array.array(
+                self.typecode,
+                self.example[:-1] + self.example[:1] + self.example[-1:]
+            )
+        )
+
+        a = array.array(self.typecode, self.example)
+        a.insert(-1000, self.example[0])
+        self.assertEqual(
+            a,
+            array.array(self.typecode, self.example[:1] + self.example)
+        )
+
+        a = array.array(self.typecode, self.example)
+        a.insert(1000, self.example[0])
+        self.assertEqual(
+            a,
+            array.array(self.typecode, self.example + self.example[:1])
+        )
+
+    def test_tofromfile(self):
+        a = array.array(self.typecode, 2*self.example)
+        self.assertRaises(TypeError, a.tofile)
+        self.assertRaises(TypeError, a.tofile, cStringIO.StringIO())
+        f = open(test_support.TESTFN, 'wb')
+        try:
+            a.tofile(f)
+            f.close()
+            b = array.array(self.typecode)
+            f = open(test_support.TESTFN, 'rb')
+            self.assertRaises(TypeError, b.fromfile)
+            self.assertRaises(
+                TypeError,
+                b.fromfile,
+                cStringIO.StringIO(), len(self.example)
+            )
+            b.fromfile(f, len(self.example))
+            self.assertEqual(b, array.array(self.typecode, self.example))
+            self.assertNotEqual(a, b)
+            b.fromfile(f, len(self.example))
+            self.assertEqual(a, b)
+            self.assertRaises(EOFError, b.fromfile, f, 1)
+            f.close()
+        finally:
+            if not f.closed:
+                f.close()
+            test_support.unlink(test_support.TESTFN)
+
+    def test_tofromlist(self):
+        a = array.array(self.typecode, 2*self.example)
+        b = array.array(self.typecode)
+        self.assertRaises(TypeError, a.tolist, 42)
+        self.assertRaises(TypeError, b.fromlist)
+        self.assertRaises(TypeError, b.fromlist, 42)
+        self.assertRaises(TypeError, b.fromlist, [None])
+        b.fromlist(a.tolist())
+        self.assertEqual(a, b)
+
+    def test_tofromstring(self):
+        a = array.array(self.typecode, 2*self.example)
+        b = array.array(self.typecode)
+        self.assertRaises(TypeError, a.tostring, 42)
+        self.assertRaises(TypeError, b.fromstring)
+        self.assertRaises(TypeError, b.fromstring, 42)
+        b.fromstring(a.tostring())
+        self.assertEqual(a, b)
+        if a.itemsize>1:
+            self.assertRaises(ValueError, b.fromstring, "x")
+
+    def test_repr(self):
+        a = array.array(self.typecode, 2*self.example)
+        self.assertEqual(a, eval(repr(a), {"array": array.array}))
+
+        a = array.array(self.typecode)
+        self.assertEqual(repr(a), "array('%s')" % self.typecode)
+
+    def test_str(self):
+        a = array.array(self.typecode, 2*self.example)
+        str(a)
+
+    def test_cmp(self):
+        a = array.array(self.typecode, self.example)
+        self.assert_((a == 42) is False)
+        self.assert_((a != 42) is True)
+
+        self.assert_((a == a) is True)
+        self.assert_((a != a) is False)
+        self.assert_((a < a) is False)
+        self.assert_((a <= a) is True)
+        self.assert_((a > a) is False)
+        self.assert_((a >= a) is True)
+
+        al = array.array(self.typecode, self.smallerexample)
+        ab = array.array(self.typecode, self.biggerexample)
+
+        self.assert_((a == 2*a) is False)
+        self.assert_((a != 2*a) is True)
+        self.assert_((a < 2*a) is True)
+        self.assert_((a <= 2*a) is True)
+        self.assert_((a > 2*a) is False)
+        self.assert_((a >= 2*a) is False)
+
+        self.assert_((a == al) is False)
+        self.assert_((a != al) is True)
+        self.assert_((a < al) is False)
+        self.assert_((a <= al) is False)
+        self.assert_((a > al) is True)
+        self.assert_((a >= al) is True)
+
+        self.assert_((a == ab) is False)
+        self.assert_((a != ab) is True)
+        self.assert_((a < ab) is True)
+        self.assert_((a <= ab) is True)
+        self.assert_((a > ab) is False)
+        self.assert_((a >= ab) is False)
+
+    def test_add(self):
+        a = array.array(self.typecode, self.example) \
+            + array.array(self.typecode, self.example[::-1])
+        self.assertEqual(
+            a,
+            array.array(self.typecode, self.example + self.example[::-1])
+        )
+
+        b = array.array(self.badtypecode())
+        self.assertRaises(TypeError, a.__add__, b)
+
+        self.assertRaises(TypeError, a.__add__, "bad")
+
+    def test_iadd(self):
+        a = array.array(self.typecode, self.example[::-1])
+        b = a
+        a += array.array(self.typecode, 2*self.example)
+        self.assert_(a is b)
+        self.assertEqual(
+            a,
+            array.array(self.typecode, self.example[::-1]+2*self.example)
+        )
+
+        b = array.array(self.badtypecode())
+        self.assertRaises(TypeError, a.__add__, b)
+
+        self.assertRaises(TypeError, a.__iadd__, "bad")
+
+    def test_mul(self):
+        a = 5*array.array(self.typecode, self.example)
+        self.assertEqual(
+            a,
+            array.array(self.typecode, 5*self.example)
+        )
+
+        a = array.array(self.typecode, self.example)*5
+        self.assertEqual(
+            a,
+            array.array(self.typecode, self.example*5)
+        )
+
+        a = 0*array.array(self.typecode, self.example)
+        self.assertEqual(
+            a,
+            array.array(self.typecode)
+        )
+
+        a = (-1)*array.array(self.typecode, self.example)
+        self.assertEqual(
+            a,
+            array.array(self.typecode)
+        )
+
+        self.assertRaises(TypeError, a.__mul__, "bad")
+
+    def test_imul(self):
+        a = array.array(self.typecode, self.example)
+        b = a
+
+        a *= 5
+        self.assert_(a is b)
+        self.assertEqual(
+            a,
+            array.array(self.typecode, 5*self.example)
+        )
+
+        a *= 0
+        self.assert_(a is b)
+        self.assertEqual(a, array.array(self.typecode))
+
+        a *= 1000
+        self.assert_(a is b)
+        self.assertEqual(a, array.array(self.typecode))
+
+        a *= -1
+        self.assert_(a is b)
+        self.assertEqual(a, array.array(self.typecode))
+
+        a = array.array(self.typecode, self.example)
+        a *= -1
+        self.assertEqual(a, array.array(self.typecode))
+
+        self.assertRaises(TypeError, a.__imul__, "bad")
+
+    def test_getitem(self):
+        a = array.array(self.typecode, self.example)
+        self.assertEntryEqual(a[0], self.example[0])
+        self.assertEntryEqual(a[0L], self.example[0])
+        self.assertEntryEqual(a[-1], self.example[-1])
+        self.assertEntryEqual(a[-1L], self.example[-1])
+        self.assertEntryEqual(a[len(self.example)-1], self.example[-1])
+        self.assertEntryEqual(a[-len(self.example)], self.example[0])
+        self.assertRaises(TypeError, a.__getitem__)
+        self.assertRaises(IndexError, a.__getitem__, len(self.example))
+        self.assertRaises(IndexError, a.__getitem__, -len(self.example)-1)
+
+    def test_setitem(self):
+        a = array.array(self.typecode, self.example)
+        a[0] = a[-1]
+        self.assertEntryEqual(a[0], a[-1])
+
+        a = array.array(self.typecode, self.example)
+        a[0L] = a[-1]
+        self.assertEntryEqual(a[0], a[-1])
+
+        a = array.array(self.typecode, self.example)
+        a[-1] = a[0]
+        self.assertEntryEqual(a[0], a[-1])
+
+        a = array.array(self.typecode, self.example)
+        a[-1L] = a[0]
+        self.assertEntryEqual(a[0], a[-1])
+
+        a = array.array(self.typecode, self.example)
+        a[len(self.example)-1] = a[0]
+        self.assertEntryEqual(a[0], a[-1])
+
+        a = array.array(self.typecode, self.example)
+        a[-len(self.example)] = a[-1]
+        self.assertEntryEqual(a[0], a[-1])
+
+        self.assertRaises(TypeError, a.__setitem__)
+        self.assertRaises(TypeError, a.__setitem__, None)
+        self.assertRaises(TypeError, a.__setitem__, 0, None)
+        self.assertRaises(
+            IndexError,
+            a.__setitem__,
+            len(self.example), self.example[0]
+        )
+        self.assertRaises(
+            IndexError,
+            a.__setitem__,
+            -len(self.example)-1, self.example[0]
+        )
+
+    def test_delitem(self):
+        a = array.array(self.typecode, self.example)
+        del a[0]
+        self.assertEqual(
+            a,
+            array.array(self.typecode, self.example[1:])
+        )
+
+        a = array.array(self.typecode, self.example)
+        del a[-1]
+        self.assertEqual(
+            a,
+            array.array(self.typecode, self.example[:-1])
+        )
+
+        a = array.array(self.typecode, self.example)
+        del a[len(self.example)-1]
+        self.assertEqual(
+            a,
+            array.array(self.typecode, self.example[:-1])
+        )
+
+        a = array.array(self.typecode, self.example)
+        del a[-len(self.example)]
+        self.assertEqual(
+            a,
+            array.array(self.typecode, self.example[1:])
+        )
+
+        self.assertRaises(TypeError, a.__delitem__)
+        self.assertRaises(TypeError, a.__delitem__, None)
+        self.assertRaises(IndexError, a.__delitem__, len(self.example))
+        self.assertRaises(IndexError, a.__delitem__, -len(self.example)-1)
+
+    def test_getslice(self):
+        a = array.array(self.typecode, self.example)
+        self.assertEqual(a[:], a)
+
+        self.assertEqual(
+            a[1:],
+            array.array(self.typecode, self.example[1:])
+        )
+
+        self.assertEqual(
+            a[:1],
+            array.array(self.typecode, self.example[:1])
+        )
+
+        self.assertEqual(
+            a[:-1],
+            array.array(self.typecode, self.example[:-1])
+        )
+
+        self.assertEqual(
+            a[-1:],
+            array.array(self.typecode, self.example[-1:])
+        )
+
+        self.assertEqual(
+            a[-1:-1],
+            array.array(self.typecode)
+        )
+
+        self.assertEqual(
+            a[2:1],
+            array.array(self.typecode)
+        )
+
+        self.assertEqual(
+            a[1000:],
+            array.array(self.typecode)
+        )
+        self.assertEqual(a[-1000:], a)
+        self.assertEqual(a[:1000], a)
+        self.assertEqual(
+            a[:-1000],
+            array.array(self.typecode)
+        )
+        self.assertEqual(a[-1000:1000], a)
+        self.assertEqual(
+            a[2000:1000],
+            array.array(self.typecode)
+        )
+
+    def test_setslice(self):
+        a = array.array(self.typecode, self.example)
+        a[:1] = a
+        self.assertEqual(
+            a,
+            array.array(self.typecode, self.example + self.example[1:])
+        )
+
+        a = array.array(self.typecode, self.example)
+        a[:-1] = a
+        self.assertEqual(
+            a,
+            array.array(self.typecode, self.example + self.example[-1:])
+        )
+
+        a = array.array(self.typecode, self.example)
+        a[-1:] = a
+        self.assertEqual(
+            a,
+            array.array(self.typecode, self.example[:-1] + self.example)
+        )
+
+        a = array.array(self.typecode, self.example)
+        a[1:] = a
+        self.assertEqual(
+            a,
+            array.array(self.typecode, self.example[:1] + self.example)
+        )
+
+        a = array.array(self.typecode, self.example)
+        a[1:-1] = a
+        self.assertEqual(
+            a,
+            array.array(
+                self.typecode,
+                self.example[:1] + self.example + self.example[-1:]
+            )
+        )
+
+        a = array.array(self.typecode, self.example)
+        a[1000:] = a
+        self.assertEqual(
+            a,
+            array.array(self.typecode, 2*self.example)
+        )
+
+        a = array.array(self.typecode, self.example)
+        a[-1000:] = a
+        self.assertEqual(
+            a,
+            array.array(self.typecode, self.example)
+        )
+
+        a = array.array(self.typecode, self.example)
+        a[:1000] = a
+        self.assertEqual(
+            a,
+            array.array(self.typecode, self.example)
+        )
+
+        a = array.array(self.typecode, self.example)
+        a[:-1000] = a
+        self.assertEqual(
+            a,
+            array.array(self.typecode, 2*self.example)
+        )
+
+        a = array.array(self.typecode, self.example)
+        a[1:0] = a
+        self.assertEqual(
+            a,
+            array.array(self.typecode, self.example[:1] + self.example + self.example[1:])
+        )
+
+        a = array.array(self.typecode, self.example)
+        a[2000:1000] = a
+        self.assertEqual(
+            a,
+            array.array(self.typecode, 2*self.example)
+        )
+
+        a = array.array(self.typecode, self.example)
+        self.assertRaises(TypeError, a.__setslice__, 0, 0, None)
+        self.assertRaises(TypeError, a.__setitem__, slice(0, 1), None)
+
+        b = array.array(self.badtypecode())
+        self.assertRaises(TypeError, a.__setslice__, 0, 0, b)
+        self.assertRaises(TypeError, a.__setitem__, slice(0, 1), b)
+
+    def test_index(self):
+        example = 2*self.example
+        a = array.array(self.typecode, example)
+        self.assertRaises(TypeError, a.index)
+        for x in example:
+            self.assertEqual(a.index(x), example.index(x))
+        self.assertRaises(ValueError, a.index, None)
+        self.assertRaises(ValueError, a.index, self.outside)
+
+    def test_count(self):
+        example = 2*self.example
+        a = array.array(self.typecode, example)
+        self.assertRaises(TypeError, a.count)
+        for x in example:
+            self.assertEqual(a.count(x), example.count(x))
+        self.assertEqual(a.count(self.outside), 0)
+        self.assertEqual(a.count(None), 0)
+
+    def test_remove(self):
+        for x in self.example:
+            example = 2*self.example
+            a = array.array(self.typecode, example)
+            pos = example.index(x)
+            example2 = example[:pos] + example[pos+1:]
+            a.remove(x)
+            self.assertEqual(a, array.array(self.typecode, example2))
+
+        a = array.array(self.typecode, self.example)
+        self.assertRaises(ValueError, a.remove, self.outside)
+
+        self.assertRaises(ValueError, a.remove, None)
+
+    def test_pop(self):
+        a = array.array(self.typecode)
+        self.assertRaises(IndexError, a.pop)
+
+        a = array.array(self.typecode, 2*self.example)
+        self.assertRaises(TypeError, a.pop, 42, 42)
+        self.assertRaises(TypeError, a.pop, None)
+        self.assertRaises(IndexError, a.pop, len(a))
+        self.assertRaises(IndexError, a.pop, -len(a)-1)
+
+        self.assertEntryEqual(a.pop(0), self.example[0])
+        self.assertEqual(
+            a,
+            array.array(self.typecode, self.example[1:]+self.example)
+        )
+        self.assertEntryEqual(a.pop(1), self.example[2])
+        self.assertEqual(
+            a,
+            array.array(self.typecode, self.example[1:2]+self.example[3:]+self.example)
+        )
+        self.assertEntryEqual(a.pop(0), self.example[1])
+        self.assertEntryEqual(a.pop(), self.example[-1])
+        self.assertEqual(
+            a,
+            array.array(self.typecode, self.example[3:]+self.example[:-1])
+        )
+
+    def test_reverse(self):
+        a = array.array(self.typecode, self.example)
+        self.assertRaises(TypeError, a.reverse, 42)
+        a.reverse()
+        self.assertEqual(
+            a,
+            array.array(self.typecode, self.example[::-1])
+        )
+
+    def test_extend(self):
+        a = array.array(self.typecode, self.example)
+        self.assertRaises(TypeError, a.extend)
+        a.extend(array.array(self.typecode, self.example[::-1]))
+        self.assertEqual(
+            a,
+            array.array(self.typecode, self.example+self.example[::-1])
+        )
+
+        b = array.array(self.badtypecode())
+        self.assertRaises(TypeError, a.extend, b)
+
+        a = array.array(self.typecode, self.example)
+        a.extend(self.example[::-1])
+        self.assertEqual(
+            a,
+            array.array(self.typecode, self.example+self.example[::-1])
+        )
+
+    def test_constructor_with_iterable_argument(self):
+        a = array.array(self.typecode, iter(self.example))
+        b = array.array(self.typecode, self.example)
+        self.assertEqual(a, b)
+
+        # non-iterable argument
+        self.assertRaises(TypeError, array.array, self.typecode, 10)
+
+        # pass through errors raised in __iter__
+        class A:
+            def __iter__(self):
+                raise UnicodeError
+        self.assertRaises(UnicodeError, array.array, self.typecode, A())
+
+        # pass through errors raised in next()
+        def B():
+            raise UnicodeError
+            yield None
+        self.assertRaises(UnicodeError, array.array, self.typecode, B())
+
+    def test_coveritertraverse(self):
+        try:
+            import gc
+        except ImportError:
+            return
+        a = array.array(self.typecode)
+        l = [iter(a)]
+        l.append(l)
+        gc.collect()
+
+    def test_buffer(self):
+        a = array.array(self.typecode, self.example)
+        b = buffer(a)
+        self.assertEqual(b[0], a.tostring()[0])
+
+    def test_weakref(self):
+        s = array.array(self.typecode, self.example)
+        p = proxy(s)
+        self.assertEqual(p.tostring(), s.tostring())
+        s = None
+        self.assertRaises(ReferenceError, len, p)
+
+    def test_bug_782369(self):
+        import sys
+        if hasattr(sys, "getrefcount"):
+            for i in range(10):
+                b = array.array('B', range(64))
+            rc = sys.getrefcount(10)
+            for i in range(10):
+                b = array.array('B', range(64))
+            self.assertEqual(rc, sys.getrefcount(10))
+
+    def test_subclass_with_kwargs(self):
+        # SF bug #1486663 -- this used to erroneously raise a TypeError
+        ArraySubclassWithKwargs('b', newarg=1)
+
+
+class StringTest(BaseTest):
+
+    def test_setitem(self):
+        super(StringTest, self).test_setitem()
+        a = array.array(self.typecode, self.example)
+        self.assertRaises(TypeError, a.__setitem__, 0, self.example[:2])
+
+class CharacterTest(StringTest):
+    typecode = 'c'
+    example = '\x01azAZ\x00\xfe'
+    smallerexample = '\x01azAY\x00\xfe'
+    biggerexample = '\x01azAZ\x00\xff'
+    outside = '\x33'
+    minitemsize = 1
+
+    def test_subbclassing(self):
+        class EditableString(array.array):
+            def __new__(cls, s, *args, **kwargs):
+                return array.array.__new__(cls, 'c', s)
+
+            def __init__(self, s, color='blue'):
+                array.array.__init__(self, 'c', s)
+                self.color = color
+
+            def strip(self):
+                self[:] = array.array('c', self.tostring().strip())
+
+            def __repr__(self):
+                return 'EditableString(%r)' % self.tostring()
+
+        s = EditableString("\ttest\r\n")
+        s.strip()
+        self.assertEqual(s.tostring(), "test")
+
+        self.assertEqual(s.color, "blue")
+        s.color = "red"
+        self.assertEqual(s.color, "red")
+        self.assertEqual(s.__dict__.keys(), ["color"])
+
+    def test_nounicode(self):
+        a = array.array(self.typecode, self.example)
+        self.assertRaises(ValueError, a.fromunicode, unicode(''))
+        self.assertRaises(ValueError, a.tounicode)
+
+tests.append(CharacterTest)
+
+if test_support.have_unicode:
+    class UnicodeTest(StringTest):
+        typecode = 'u'
+        example = unicode(r'\x01\u263a\x00\ufeff', 'unicode-escape')
+        smallerexample = unicode(r'\x01\u263a\x00\ufefe', 'unicode-escape')
+        biggerexample = unicode(r'\x01\u263a\x01\ufeff', 'unicode-escape')
+        outside = unicode('\x33')
+        minitemsize = 2
+
+        def test_unicode(self):
+            self.assertRaises(TypeError, array.array, 'b', unicode('foo', 'ascii'))
+
+            a = array.array('u', unicode(r'\xa0\xc2\u1234', 'unicode-escape'))
+            a.fromunicode(unicode(' ', 'ascii'))
+            a.fromunicode(unicode('', 'ascii'))
+            a.fromunicode(unicode('', 'ascii'))
+            a.fromunicode(unicode(r'\x11abc\xff\u1234', 'unicode-escape'))
+            s = a.tounicode()
+            self.assertEqual(
+                s,
+                unicode(r'\xa0\xc2\u1234 \x11abc\xff\u1234', 'unicode-escape')
+            )
+
+            s = unicode(r'\x00="\'a\\b\x80\xff\u0000\u0001\u1234', 'unicode-escape')
+            a = array.array('u', s)
+            self.assertEqual(
+                repr(a),
+                r"""array('u', u'\x00="\'a\\b\x80\xff\x00\x01\u1234')"""
+            )
+
+            self.assertRaises(TypeError, a.fromunicode)
+
+    tests.append(UnicodeTest)
+
+class NumberTest(BaseTest):
+
+    def test_extslice(self):
+        a = array.array(self.typecode, range(5))
+        self.assertEqual(a[::], a)
+        self.assertEqual(a[::2], array.array(self.typecode, [0,2,4]))
+        self.assertEqual(a[1::2], array.array(self.typecode, [1,3]))
+        self.assertEqual(a[::-1], array.array(self.typecode, [4,3,2,1,0]))
+        self.assertEqual(a[::-2], array.array(self.typecode, [4,2,0]))
+        self.assertEqual(a[3::-2], array.array(self.typecode, [3,1]))
+        self.assertEqual(a[-100:100:], a)
+        self.assertEqual(a[100:-100:-1], a[::-1])
+        self.assertEqual(a[-100L:100L:2L], array.array(self.typecode, [0,2,4]))
+        self.assertEqual(a[1000:2000:2], array.array(self.typecode, []))
+        self.assertEqual(a[-1000:-2000:-2], array.array(self.typecode, []))
+
+    def test_delslice(self):
+        a = array.array(self.typecode, range(5))
+        del a[::2]
+        self.assertEqual(a, array.array(self.typecode, [1,3]))
+        a = array.array(self.typecode, range(5))
+        del a[1::2]
+        self.assertEqual(a, array.array(self.typecode, [0,2,4]))
+        a = array.array(self.typecode, range(5))
+        del a[1::-2]
+        self.assertEqual(a, array.array(self.typecode, [0,2,3,4]))
+        a = array.array(self.typecode, range(10))
+        del a[::1000]
+        self.assertEqual(a, array.array(self.typecode, [1,2,3,4,5,6,7,8,9]))
+
+    def test_assignment(self):
+        a = array.array(self.typecode, range(10))
+        a[::2] = array.array(self.typecode, [42]*5)
+        self.assertEqual(a, array.array(self.typecode, [42, 1, 42, 3, 42, 5, 42, 7, 42, 9]))
+        a = array.array(self.typecode, range(10))
+        a[::-4] = array.array(self.typecode, [10]*3)
+        self.assertEqual(a, array.array(self.typecode, [0, 10, 2, 3, 4, 10, 6, 7, 8 ,10]))
+        a = array.array(self.typecode, range(4))
+        a[::-1] = a
+        self.assertEqual(a, array.array(self.typecode, [3, 2, 1, 0]))
+        a = array.array(self.typecode, range(10))
+        b = a[:]
+        c = a[:]
+        ins = array.array(self.typecode, range(2))
+        a[2:3] = ins
+        b[slice(2,3)] = ins
+        c[2:3:] = ins
+
+    def test_iterationcontains(self):
+        a = array.array(self.typecode, range(10))
+        self.assertEqual(list(a), range(10))
+        b = array.array(self.typecode, [20])
+        self.assertEqual(a[-1] in a, True)
+        self.assertEqual(b[0] not in a, True)
+
+    def check_overflow(self, lower, upper):
+        # method to be used by subclasses
+
+        # should not overflow assigning lower limit
+        a = array.array(self.typecode, [lower])
+        a[0] = lower
+        # should overflow assigning less than lower limit
+        self.assertRaises(OverflowError, array.array, self.typecode, [lower-1])
+        self.assertRaises(OverflowError, a.__setitem__, 0, lower-1)
+        # should not overflow assigning upper limit
+        a = array.array(self.typecode, [upper])
+        a[0] = upper
+        # should overflow assigning more than upper limit
+        self.assertRaises(OverflowError, array.array, self.typecode, [upper+1])
+        self.assertRaises(OverflowError, a.__setitem__, 0, upper+1)
+
+    def test_subclassing(self):
+        typecode = self.typecode
+        class ExaggeratingArray(array.array):
+            __slots__ = ['offset']
+
+            def __new__(cls, typecode, data, offset):
+                return array.array.__new__(cls, typecode, data)
+
+            def __init__(self, typecode, data, offset):
+                self.offset = offset
+
+            def __getitem__(self, i):
+                return array.array.__getitem__(self, i) + self.offset
+
+        a = ExaggeratingArray(self.typecode, [3, 6, 7, 11], 4)
+        self.assertEntryEqual(a[0], 7)
+
+        self.assertRaises(AttributeError, setattr, a, "color", "blue")
+
+class SignedNumberTest(NumberTest):
+    example = [-1, 0, 1, 42, 0x7f]
+    smallerexample = [-1, 0, 1, 42, 0x7e]
+    biggerexample = [-1, 0, 1, 43, 0x7f]
+    outside = 23
+
+    def test_overflow(self):
+        a = array.array(self.typecode)
+        lower = -1 * long(pow(2, a.itemsize * 8 - 1))
+        upper = long(pow(2, a.itemsize * 8 - 1)) - 1L
+        self.check_overflow(lower, upper)
+
+class UnsignedNumberTest(NumberTest):
+    example = [0, 1, 17, 23, 42, 0xff]
+    smallerexample = [0, 1, 17, 23, 42, 0xfe]
+    biggerexample = [0, 1, 17, 23, 43, 0xff]
+    outside = 0xaa
+
+    def test_overflow(self):
+        a = array.array(self.typecode)
+        lower = 0
+        upper = long(pow(2, a.itemsize * 8)) - 1L
+        self.check_overflow(lower, upper)
+
+
+class ByteTest(SignedNumberTest):
+    typecode = 'b'
+    minitemsize = 1
+tests.append(ByteTest)
+
+class UnsignedByteTest(UnsignedNumberTest):
+    typecode = 'B'
+    minitemsize = 1
+tests.append(UnsignedByteTest)
+
+class ShortTest(SignedNumberTest):
+    typecode = 'h'
+    minitemsize = 2
+tests.append(ShortTest)
+
+class UnsignedShortTest(UnsignedNumberTest):
+    typecode = 'H'
+    minitemsize = 2
+tests.append(UnsignedShortTest)
+
+class IntTest(SignedNumberTest):
+    typecode = 'i'
+    minitemsize = 2
+tests.append(IntTest)
+
+class UnsignedIntTest(UnsignedNumberTest):
+    typecode = 'I'
+    minitemsize = 2
+tests.append(UnsignedIntTest)
+
+class LongTest(SignedNumberTest):
+    typecode = 'l'
+    minitemsize = 4
+tests.append(LongTest)
+
+class UnsignedLongTest(UnsignedNumberTest):
+    typecode = 'L'
+    minitemsize = 4
+tests.append(UnsignedLongTest)
+
+class FPTest(NumberTest):
+    example = [-42.0, 0, 42, 1e5, -1e10]
+    smallerexample = [-42.0, 0, 42, 1e5, -2e10]
+    biggerexample = [-42.0, 0, 42, 1e5, 1e10]
+    outside = 23
+
+    def assertEntryEqual(self, entry1, entry2):
+        self.assertAlmostEqual(entry1, entry2)
+
+    def test_byteswap(self):
+        a = array.array(self.typecode, self.example)
+        self.assertRaises(TypeError, a.byteswap, 42)
+        if a.itemsize in (1, 2, 4, 8):
+            b = array.array(self.typecode, self.example)
+            b.byteswap()
+            if a.itemsize==1:
+                self.assertEqual(a, b)
+            else:
+                # On alphas treating the byte swapped bit patters as
+                # floats/doubles results in floating point exceptions
+                # => compare the 8bit string values instead
+                self.assertNotEqual(a.tostring(), b.tostring())
+            b.byteswap()
+            self.assertEqual(a, b)
+
+class FloatTest(FPTest):
+    typecode = 'f'
+    minitemsize = 4
+tests.append(FloatTest)
+
+class DoubleTest(FPTest):
+    typecode = 'd'
+    minitemsize = 8
+tests.append(DoubleTest)
+
+def test_main(verbose=None):
+    import sys
+
+    test_support.run_unittest(*tests)
+
+    # verify reference counting
+    if verbose and hasattr(sys, "gettotalrefcount"):
+        import gc
+        counts = [None] * 5
+        for i in xrange(len(counts)):
+            test_support.run_unittest(*tests)
+            gc.collect()
+            counts[i] = sys.gettotalrefcount()
+        print counts
+
+if __name__ == "__main__":
+    test_main(verbose=True)


Property changes on: vendor/Python/current/Lib/test/test_array.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/test/test_ast.py
===================================================================
--- vendor/Python/current/Lib/test/test_ast.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_ast.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,204 @@
+import sys, itertools
+import _ast
+
+def to_tuple(t):
+    if t is None or isinstance(t, (basestring, int, long, complex)):
+        return t
+    elif isinstance(t, list):
+        return [to_tuple(e) for e in t]
+    result = [t.__class__.__name__]
+    if hasattr(t, 'lineno') and hasattr(t, 'col_offset'):
+        result.append((t.lineno, t.col_offset))
+    if t._fields is None:
+        return tuple(result)
+    for f in t._fields:
+        result.append(to_tuple(getattr(t, f)))
+    return tuple(result)
+
+# These tests are compiled through "exec"
+# There should be atleast one test per statement
+exec_tests = [
+    # FunctionDef
+    "def f(): pass",
+    # ClassDef
+    "class C:pass",
+    # Return
+    "def f():return 1",
+    # Delete
+    "del v",
+    # Assign
+    "v = 1",
+    # AugAssign
+    "v += 1",
+    # Print
+    "print >>f, 1, ",
+    # For
+    "for v in v:pass",
+    # While
+    "while v:pass",
+    # If
+    "if v:pass",
+    # Raise
+    "raise Exception, 'string'",
+    # TryExcept
+    "try:\n  pass\nexcept Exception:\n  pass",
+    # TryFinally
+    "try:\n  pass\nfinally:\n  pass",
+    # Assert
+    "assert v",
+    # Import
+    "import sys",
+    # ImportFrom
+    "from sys import v",
+    # Exec
+    "exec 'v'",
+    # Global
+    "global v",
+    # Expr
+    "1",
+    # Pass,
+    "pass",
+    # Break
+    "break",
+    # Continue
+    "continue",
+]
+
+# These are compiled through "single"
+# because of overlap with "eval", it just tests what
+# can't be tested with "eval"
+single_tests = [
+    "1+2"
+]
+
+# These are compiled through "eval"
+# It should test all expressions
+eval_tests = [
+  # BoolOp
+  "a and b",
+  # BinOp
+  "a + b",
+  # UnaryOp
+  "not v",
+  # Lambda
+  "lambda:None",
+  # Dict
+  "{ 1:2 }",
+  # ListComp
+  "[a for b in c if d]",
+  # GeneratorExp
+  "(a for b in c if d)",
+  # Yield - yield expressions can't work outside a function
+  #
+  # Compare
+  "1 < 2 < 3",
+  # Call
+  "f(1,2,c=3,*d,**e)",
+  # Repr
+  "`v`",
+  # Num
+  "10L",
+  # Str
+  "'string'",
+  # Attribute
+  "a.b",
+  # Subscript
+  "a[b:c]",
+  # Name
+  "v",
+  # List
+  "[1,2,3]",
+  # Tuple
+  "1,2,3",
+  # Combination
+  "a.b.c.d(a.b[1:2])",
+
+]
+
+# TODO: expr_context, slice, boolop, operator, unaryop, cmpop, comprehension
+# excepthandler, arguments, keywords, alias
+
+if __name__=='__main__' and sys.argv[1:] == ['-g']:
+    for statements, kind in ((exec_tests, "exec"), (single_tests, "single"),
+                             (eval_tests, "eval")):
+        print kind+"_results = ["
+        for s in statements:
+            print repr(to_tuple(compile(s, "?", kind, 0x400)))+","
+        print "]"
+    print "run_tests()"
+    raise SystemExit
+
+def test_order(ast_node, parent_pos):
+
+    if not isinstance(ast_node, _ast.AST) or ast_node._fields == None:
+        return
+    if isinstance(ast_node, (_ast.expr, _ast.stmt, _ast.excepthandler)):
+        node_pos = (ast_node.lineno, ast_node.col_offset)
+        assert node_pos >= parent_pos, (node_pos, parent_pos)
+        parent_pos = (ast_node.lineno, ast_node.col_offset)
+    for name in ast_node._fields:
+        value = getattr(ast_node, name)
+        if isinstance(value, list):
+            for child in value:
+                test_order(child, parent_pos)
+        elif value != None:
+            test_order(value, parent_pos)
+
+def run_tests():
+    for input, output, kind in ((exec_tests, exec_results, "exec"),
+                                (single_tests, single_results, "single"),
+                                (eval_tests, eval_results, "eval")):
+        for i, o in itertools.izip(input, output):
+            ast_tree = compile(i, "?", kind, 0x400)
+            assert to_tuple(ast_tree) == o
+            test_order(ast_tree, (0, 0))
+
+#### EVERYTHING BELOW IS GENERATED #####
+exec_results = [
+('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, None, []), [('Pass', (1, 9))], [])]),
+('Module', [('ClassDef', (1, 0), 'C', [], [('Pass', (1, 8))])]),
+('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, None, []), [('Return', (1, 8), ('Num', (1, 15), 1))], [])]),
+('Module', [('Delete', (1, 0), [('Name', (1, 4), 'v', ('Del',))])]),
+('Module', [('Assign', (1, 0), [('Name', (1, 0), 'v', ('Store',))], ('Num', (1, 4), 1))]),
+('Module', [('AugAssign', (1, 0), ('Name', (1, 0), 'v', ('Store',)), ('Add',), ('Num', (1, 5), 1))]),
+('Module', [('Print', (1, 0), ('Name', (1, 8), 'f', ('Load',)), [('Num', (1, 11), 1)], False)]),
+('Module', [('For', (1, 0), ('Name', (1, 4), 'v', ('Store',)), ('Name', (1, 9), 'v', ('Load',)), [('Pass', (1, 11))], [])]),
+('Module', [('While', (1, 0), ('Name', (1, 6), 'v', ('Load',)), [('Pass', (1, 8))], [])]),
+('Module', [('If', (1, 0), ('Name', (1, 3), 'v', ('Load',)), [('Pass', (1, 5))], [])]),
+('Module', [('Raise', (1, 0), ('Name', (1, 6), 'Exception', ('Load',)), ('Str', (1, 17), 'string'), None)]),
+('Module', [('TryExcept', (1, 0), [('Pass', (2, 2))], [('excepthandler', (3, 0), ('Name', (3, 7), 'Exception', ('Load',)), None, [('Pass', (4, 2))], 3, 0)], [])]),
+('Module', [('TryFinally', (1, 0), [('Pass', (2, 2))], [('Pass', (4, 2))])]),
+('Module', [('Assert', (1, 0), ('Name', (1, 7), 'v', ('Load',)), None)]),
+('Module', [('Import', (1, 0), [('alias', 'sys', None)])]),
+('Module', [('ImportFrom', (1, 0), 'sys', [('alias', 'v', None)], 0)]),
+('Module', [('Exec', (1, 0), ('Str', (1, 5), 'v'), None, None)]),
+('Module', [('Global', (1, 0), ['v'])]),
+('Module', [('Expr', (1, 0), ('Num', (1, 0), 1))]),
+('Module', [('Pass', (1, 0))]),
+('Module', [('Break', (1, 0))]),
+('Module', [('Continue', (1, 0))]),
+]
+single_results = [
+('Interactive', [('Expr', (1, 0), ('BinOp', (1, 0), ('Num', (1, 0), 1), ('Add',), ('Num', (1, 2), 2)))]),
+]
+eval_results = [
+('Expression', ('BoolOp', (1, 0), ('And',), [('Name', (1, 0), 'a', ('Load',)), ('Name', (1, 6), 'b', ('Load',))])),
+('Expression', ('BinOp', (1, 0), ('Name', (1, 0), 'a', ('Load',)), ('Add',), ('Name', (1, 4), 'b', ('Load',)))),
+('Expression', ('UnaryOp', (1, 0), ('Not',), ('Name', (1, 4), 'v', ('Load',)))),
+('Expression', ('Lambda', (1, 0), ('arguments', [], None, None, []), ('Name', (1, 7), 'None', ('Load',)))),
+('Expression', ('Dict', (1, 0), [('Num', (1, 2), 1)], [('Num', (1, 4), 2)])),
+('Expression', ('ListComp', (1, 1), ('Name', (1, 1), 'a', ('Load',)), [('comprehension', ('Name', (1, 7), 'b', ('Store',)), ('Name', (1, 12), 'c', ('Load',)), [('Name', (1, 17), 'd', ('Load',))])])),
+('Expression', ('GeneratorExp', (1, 1), ('Name', (1, 1), 'a', ('Load',)), [('comprehension', ('Name', (1, 7), 'b', ('Store',)), ('Name', (1, 12), 'c', ('Load',)), [('Name', (1, 17), 'd', ('Load',))])])),
+('Expression', ('Compare', (1, 0), ('Num', (1, 0), 1), [('Lt',), ('Lt',)], [('Num', (1, 4), 2), ('Num', (1, 8), 3)])),
+('Expression', ('Call', (1, 0), ('Name', (1, 0), 'f', ('Load',)), [('Num', (1, 2), 1), ('Num', (1, 4), 2)], [('keyword', 'c', ('Num', (1, 8), 3))], ('Name', (1, 11), 'd', ('Load',)), ('Name', (1, 15), 'e', ('Load',)))),
+('Expression', ('Repr', (1, 0), ('Name', (1, 1), 'v', ('Load',)))),
+('Expression', ('Num', (1, 0), 10L)),
+('Expression', ('Str', (1, 0), 'string')),
+('Expression', ('Attribute', (1, 0), ('Name', (1, 0), 'a', ('Load',)), 'b', ('Load',))),
+('Expression', ('Subscript', (1, 0), ('Name', (1, 0), 'a', ('Load',)), ('Slice', ('Name', (1, 2), 'b', ('Load',)), ('Name', (1, 4), 'c', ('Load',)), None), ('Load',))),
+('Expression', ('Name', (1, 0), 'v', ('Load',))),
+('Expression', ('List', (1, 0), [('Num', (1, 1), 1), ('Num', (1, 3), 2), ('Num', (1, 5), 3)], ('Load',))),
+('Expression', ('Tuple', (1, 0), [('Num', (1, 0), 1), ('Num', (1, 2), 2), ('Num', (1, 4), 3)], ('Load',))),
+('Expression', ('Call', (1, 0), ('Attribute', (1, 0), ('Attribute', (1, 0), ('Attribute', (1, 0), ('Name', (1, 0), 'a', ('Load',)), 'b', ('Load',)), 'c', ('Load',)), 'd', ('Load',)), [('Subscript', (1, 8), ('Attribute', (1, 8), ('Name', (1, 8), 'a', ('Load',)), 'b', ('Load',)), ('Slice', ('Num', (1, 12), 1), ('Num', (1, 14), 2), None), ('Load',))], [], None, None)),
+]
+run_tests()

Added: vendor/Python/current/Lib/test/test_asynchat.py
===================================================================
--- vendor/Python/current/Lib/test/test_asynchat.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_asynchat.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,93 @@
+# test asynchat -- requires threading
+
+import thread # If this fails, we can't test this module
+import asyncore, asynchat, socket, threading, time
+import unittest
+from test import test_support
+
+HOST = "127.0.0.1"
+PORT = 54322
+
+class echo_server(threading.Thread):
+
+    def run(self):
+        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+        global PORT
+        PORT = test_support.bind_port(sock, HOST, PORT)
+        sock.listen(1)
+        conn, client = sock.accept()
+        buffer = ""
+        while "\n" not in buffer:
+            data = conn.recv(1)
+            if not data:
+                break
+            buffer = buffer + data
+        while buffer:
+            n = conn.send(buffer)
+            buffer = buffer[n:]
+        conn.close()
+        sock.close()
+
+class echo_client(asynchat.async_chat):
+
+    def __init__(self, terminator):
+        asynchat.async_chat.__init__(self)
+        self.contents = None
+        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
+        self.connect((HOST, PORT))
+        self.set_terminator(terminator)
+        self.buffer = ""
+
+    def handle_connect(self):
+        pass
+        ##print "Connected"
+
+    def collect_incoming_data(self, data):
+        self.buffer = self.buffer + data
+
+    def found_terminator(self):
+        #print "Received:", repr(self.buffer)
+        self.contents = self.buffer
+        self.buffer = ""
+        self.close()
+
+
+class TestAsynchat(unittest.TestCase):
+    def setUp (self):
+        pass
+
+    def tearDown (self):
+        pass
+
+    def test_line_terminator(self):
+        s = echo_server()
+        s.start()
+        time.sleep(1) # Give server time to initialize
+        c = echo_client('\n')
+        c.push("hello ")
+        c.push("world\n")
+        asyncore.loop()
+        s.join()
+
+        self.assertEqual(c.contents, 'hello world')
+
+    def test_numeric_terminator(self):
+        # Try reading a fixed number of bytes
+        s = echo_server()
+        s.start()
+        time.sleep(1) # Give server time to initialize
+        c = echo_client(6L)
+        c.push("hello ")
+        c.push("world\n")
+        asyncore.loop()
+        s.join()
+
+        self.assertEqual(c.contents, 'hello ')
+
+
+def test_main(verbose=None):
+    test_support.run_unittest(TestAsynchat)
+
+if __name__ == "__main__":
+    test_main(verbose=True)

Added: vendor/Python/current/Lib/test/test_atexit.py
===================================================================
--- vendor/Python/current/Lib/test/test_atexit.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_atexit.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,100 @@
+import sys
+import unittest
+import StringIO
+import atexit
+from test import test_support
+
+class TestCase(unittest.TestCase):
+    def test_args(self):
+        # be sure args are handled properly
+        s = StringIO.StringIO()
+        sys.stdout = sys.stderr = s
+        save_handlers = atexit._exithandlers
+        atexit._exithandlers = []
+        try:
+            atexit.register(self.h1)
+            atexit.register(self.h4)
+            atexit.register(self.h4, 4, kw="abc")
+            atexit._run_exitfuncs()
+        finally:
+            sys.stdout = sys.__stdout__
+            sys.stderr = sys.__stderr__
+            atexit._exithandlers = save_handlers
+        self.assertEqual(s.getvalue(), "h4 (4,) {'kw': 'abc'}\nh4 () {}\nh1\n")
+
+    def test_order(self):
+        # be sure handlers are executed in reverse order
+        s = StringIO.StringIO()
+        sys.stdout = sys.stderr = s
+        save_handlers = atexit._exithandlers
+        atexit._exithandlers = []
+        try:
+            atexit.register(self.h1)
+            atexit.register(self.h2)
+            atexit.register(self.h3)
+            atexit._run_exitfuncs()
+        finally:
+            sys.stdout = sys.__stdout__
+            sys.stderr = sys.__stderr__
+            atexit._exithandlers = save_handlers
+        self.assertEqual(s.getvalue(), "h3\nh2\nh1\n")
+
+    def test_sys_override(self):
+        # be sure a preset sys.exitfunc is handled properly
+        s = StringIO.StringIO()
+        sys.stdout = sys.stderr = s
+        save_handlers = atexit._exithandlers
+        atexit._exithandlers = []
+        exfunc = sys.exitfunc
+        sys.exitfunc = self.h1
+        reload(atexit)
+        try:
+            atexit.register(self.h2)
+            atexit._run_exitfuncs()
+        finally:
+            sys.stdout = sys.__stdout__
+            sys.stderr = sys.__stderr__
+            atexit._exithandlers = save_handlers
+            sys.exitfunc = exfunc
+        self.assertEqual(s.getvalue(), "h2\nh1\n")
+
+    def test_raise(self):
+        # be sure raises are handled properly
+        s = StringIO.StringIO()
+        sys.stdout = sys.stderr = s
+        save_handlers = atexit._exithandlers
+        atexit._exithandlers = []
+        try:
+            atexit.register(self.raise1)
+            atexit.register(self.raise2)
+            self.assertRaises(TypeError, atexit._run_exitfuncs)
+        finally:
+            sys.stdout = sys.__stdout__
+            sys.stderr = sys.__stderr__
+            atexit._exithandlers = save_handlers
+
+    ### helpers
+    def h1(self):
+        print "h1"
+
+    def h2(self):
+        print "h2"
+
+    def h3(self):
+        print "h3"
+
+    def h4(self, *args, **kwargs):
+        print "h4", args, kwargs
+
+    def raise1(self):
+        raise TypeError
+
+    def raise2(self):
+        raise SystemError
+
+def test_main():
+    test_support.run_unittest(TestCase)
+
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_audioop.py
===================================================================
--- vendor/Python/current/Lib/test/test_audioop.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_audioop.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,282 @@
+# Test audioop.
+import audioop
+from test.test_support import verbose
+
+def gendata1():
+    return '\0\1\2'
+
+def gendata2():
+    if verbose:
+        print 'getsample'
+    if audioop.getsample('\0\1', 2, 0) == 1:
+        return '\0\0\0\1\0\2'
+    else:
+        return '\0\0\1\0\2\0'
+
+def gendata4():
+    if verbose:
+        print 'getsample'
+    if audioop.getsample('\0\0\0\1', 4, 0) == 1:
+        return '\0\0\0\0\0\0\0\1\0\0\0\2'
+    else:
+        return '\0\0\0\0\1\0\0\0\2\0\0\0'
+
+def testmax(data):
+    if verbose:
+        print 'max'
+    if audioop.max(data[0], 1) != 2 or \
+              audioop.max(data[1], 2) != 2 or \
+              audioop.max(data[2], 4) != 2:
+        return 0
+    return 1
+
+def testminmax(data):
+    if verbose:
+        print 'minmax'
+    if audioop.minmax(data[0], 1) != (0, 2) or \
+              audioop.minmax(data[1], 2) != (0, 2) or \
+              audioop.minmax(data[2], 4) != (0, 2):
+        return 0
+    return 1
+
+def testmaxpp(data):
+    if verbose:
+        print 'maxpp'
+    if audioop.maxpp(data[0], 1) != 0 or \
+              audioop.maxpp(data[1], 2) != 0 or \
+              audioop.maxpp(data[2], 4) != 0:
+        return 0
+    return 1
+
+def testavg(data):
+    if verbose:
+        print 'avg'
+    if audioop.avg(data[0], 1) != 1 or \
+              audioop.avg(data[1], 2) != 1 or \
+              audioop.avg(data[2], 4) != 1:
+        return 0
+    return 1
+
+def testavgpp(data):
+    if verbose:
+        print 'avgpp'
+    if audioop.avgpp(data[0], 1) != 0 or \
+              audioop.avgpp(data[1], 2) != 0 or \
+              audioop.avgpp(data[2], 4) != 0:
+        return 0
+    return 1
+
+def testrms(data):
+    if audioop.rms(data[0], 1) != 1 or \
+              audioop.rms(data[1], 2) != 1 or \
+              audioop.rms(data[2], 4) != 1:
+        return 0
+    return 1
+
+def testcross(data):
+    if verbose:
+        print 'cross'
+    if audioop.cross(data[0], 1) != 0 or \
+              audioop.cross(data[1], 2) != 0 or \
+              audioop.cross(data[2], 4) != 0:
+        return 0
+    return 1
+
+def testadd(data):
+    if verbose:
+        print 'add'
+    data2 = []
+    for d in data:
+        str = ''
+        for s in d:
+            str = str + chr(ord(s)*2)
+        data2.append(str)
+    if audioop.add(data[0], data[0], 1) != data2[0] or \
+              audioop.add(data[1], data[1], 2) != data2[1] or \
+              audioop.add(data[2], data[2], 4) != data2[2]:
+        return 0
+    return 1
+
+def testbias(data):
+    if verbose:
+        print 'bias'
+    # Note: this test assumes that avg() works
+    d1 = audioop.bias(data[0], 1, 100)
+    d2 = audioop.bias(data[1], 2, 100)
+    d4 = audioop.bias(data[2], 4, 100)
+    if audioop.avg(d1, 1) != 101 or \
+              audioop.avg(d2, 2) != 101 or \
+              audioop.avg(d4, 4) != 101:
+        return 0
+    return 1
+
+def testlin2lin(data):
+    if verbose:
+        print 'lin2lin'
+    # too simple: we test only the size
+    for d1 in data:
+        for d2 in data:
+            got = len(d1)//3
+            wtd = len(d2)//3
+            if len(audioop.lin2lin(d1, got, wtd)) != len(d2):
+                return 0
+    return 1
+
+def testadpcm2lin(data):
+    # Very cursory test
+    if audioop.adpcm2lin('\0\0', 1, None) != ('\0\0\0\0', (0,0)):
+        return 0
+    return 1
+
+def testlin2adpcm(data):
+    if verbose:
+        print 'lin2adpcm'
+    # Very cursory test
+    if audioop.lin2adpcm('\0\0\0\0', 1, None) != ('\0\0', (0,0)):
+        return 0
+    return 1
+
+def testlin2alaw(data):
+    if verbose:
+        print 'lin2alaw'
+    if audioop.lin2alaw(data[0], 1) != '\xd5\xc5\xf5' or \
+              audioop.lin2alaw(data[1], 2) != '\xd5\xd5\xd5' or \
+              audioop.lin2alaw(data[2], 4) != '\xd5\xd5\xd5':
+        return 0
+    return 1
+
+def testalaw2lin(data):
+    if verbose:
+        print 'alaw2lin'
+    # Cursory
+    d = audioop.lin2alaw(data[0], 1)
+    if audioop.alaw2lin(d, 1) != data[0]:
+        return 0
+    return 1
+
+def testlin2ulaw(data):
+    if verbose:
+        print 'lin2ulaw'
+    if audioop.lin2ulaw(data[0], 1) != '\xff\xe7\xdb' or \
+              audioop.lin2ulaw(data[1], 2) != '\xff\xff\xff' or \
+              audioop.lin2ulaw(data[2], 4) != '\xff\xff\xff':
+        return 0
+    return 1
+
+def testulaw2lin(data):
+    if verbose:
+        print 'ulaw2lin'
+    # Cursory
+    d = audioop.lin2ulaw(data[0], 1)
+    if audioop.ulaw2lin(d, 1) != data[0]:
+        return 0
+    return 1
+
+def testmul(data):
+    if verbose:
+        print 'mul'
+    data2 = []
+    for d in data:
+        str = ''
+        for s in d:
+            str = str + chr(ord(s)*2)
+        data2.append(str)
+    if audioop.mul(data[0], 1, 2) != data2[0] or \
+              audioop.mul(data[1],2, 2) != data2[1] or \
+              audioop.mul(data[2], 4, 2) != data2[2]:
+        return 0
+    return 1
+
+def testratecv(data):
+    if verbose:
+        print 'ratecv'
+    state = None
+    d1, state = audioop.ratecv(data[0], 1, 1, 8000, 16000, state)
+    d2, state = audioop.ratecv(data[0], 1, 1, 8000, 16000, state)
+    if d1 + d2 != '\000\000\001\001\002\001\000\000\001\001\002':
+        return 0
+    return 1
+
+def testreverse(data):
+    if verbose:
+        print 'reverse'
+    if audioop.reverse(data[0], 1) != '\2\1\0':
+        return 0
+    return 1
+
+def testtomono(data):
+    if verbose:
+        print 'tomono'
+    data2 = ''
+    for d in data[0]:
+        data2 = data2 + d + d
+    if audioop.tomono(data2, 1, 0.5, 0.5) != data[0]:
+        return 0
+    return 1
+
+def testtostereo(data):
+    if verbose:
+        print 'tostereo'
+    data2 = ''
+    for d in data[0]:
+        data2 = data2 + d + d
+    if audioop.tostereo(data[0], 1, 1, 1) != data2:
+        return 0
+    return 1
+
+def testfindfactor(data):
+    if verbose:
+        print 'findfactor'
+    if audioop.findfactor(data[1], data[1]) != 1.0:
+        return 0
+    return 1
+
+def testfindfit(data):
+    if verbose:
+        print 'findfit'
+    if audioop.findfit(data[1], data[1]) != (0, 1.0):
+        return 0
+    return 1
+
+def testfindmax(data):
+    if verbose:
+        print 'findmax'
+    if audioop.findmax(data[1], 1) != 2:
+        return 0
+    return 1
+
+def testgetsample(data):
+    if verbose:
+        print 'getsample'
+    for i in range(3):
+        if audioop.getsample(data[0], 1, i) != i or \
+                  audioop.getsample(data[1], 2, i) != i or \
+                  audioop.getsample(data[2], 4, i) != i:
+            return 0
+    return 1
+
+def testone(name, data):
+    try:
+        func = eval('test'+name)
+    except NameError:
+        print 'No test found for audioop.'+name+'()'
+        return
+    try:
+        rv = func(data)
+    except 'xx':
+        print 'Test FAILED for audioop.'+name+'() (with an exception)'
+        return
+    if not rv:
+        print 'Test FAILED for audioop.'+name+'()'
+
+def testall():
+    data = [gendata1(), gendata2(), gendata4()]
+    names = dir(audioop)
+    # We know there is a routine 'add'
+    routines = []
+    for n in names:
+        if type(eval('audioop.'+n)) == type(audioop.add):
+            routines.append(n)
+    for n in routines:
+        testone(n, data)
+testall()

Added: vendor/Python/current/Lib/test/test_augassign.py
===================================================================
--- vendor/Python/current/Lib/test/test_augassign.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_augassign.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,327 @@
+# Augmented assignment test.
+
+from test.test_support import run_unittest
+import unittest
+
+
+class AugAssignTest(unittest.TestCase):
+    def testBasic(self):
+        x = 2
+        x += 1
+        x *= 2
+        x **= 2
+        x -= 8
+        x //= 5
+        x %= 3
+        x &= 2
+        x |= 5
+        x ^= 1
+        x /= 2
+        if 1/2 == 0:
+            # classic division
+            self.assertEquals(x, 3)
+        else:
+            # new-style division (with -Qnew)
+            self.assertEquals(x, 3.0)
+
+    def testInList(self):
+        x = [2]
+        x[0] += 1
+        x[0] *= 2
+        x[0] **= 2
+        x[0] -= 8
+        x[0] //= 5
+        x[0] %= 3
+        x[0] &= 2
+        x[0] |= 5
+        x[0] ^= 1
+        x[0] /= 2
+        if 1/2 == 0:
+            self.assertEquals(x[0], 3)
+        else:
+            self.assertEquals(x[0], 3.0)
+
+    def testInDict(self):
+        x = {0: 2}
+        x[0] += 1
+        x[0] *= 2
+        x[0] **= 2
+        x[0] -= 8
+        x[0] //= 5
+        x[0] %= 3
+        x[0] &= 2
+        x[0] |= 5
+        x[0] ^= 1
+        x[0] /= 2
+        if 1/2 == 0:
+            self.assertEquals(x[0], 3)
+        else:
+            self.assertEquals(x[0], 3.0)
+
+    def testSequences(self):
+        x = [1,2]
+        x += [3,4]
+        x *= 2
+
+        self.assertEquals(x, [1, 2, 3, 4, 1, 2, 3, 4])
+
+        x = [1, 2, 3]
+        y = x
+        x[1:2] *= 2
+        y[1:2] += [1]
+
+        self.assertEquals(x, [1, 2, 1, 2, 3])
+        self.assert_(x is y)
+
+    def testCustomMethods1(self):
+
+        class aug_test:
+            def __init__(self, value):
+                self.val = value
+            def __radd__(self, val):
+                return self.val + val
+            def __add__(self, val):
+                return aug_test(self.val + val)
+
+        class aug_test2(aug_test):
+            def __iadd__(self, val):
+                self.val = self.val + val
+                return self
+
+        class aug_test3(aug_test):
+            def __iadd__(self, val):
+                return aug_test3(self.val + val)
+
+        x = aug_test(1)
+        y = x
+        x += 10
+
+        self.assert_(isinstance(x, aug_test))
+        self.assert_(y is not x)
+        self.assertEquals(x.val, 11)
+
+        x = aug_test2(2)
+        y = x
+        x += 10
+
+        self.assert_(y is x)
+        self.assertEquals(x.val, 12)
+
+        x = aug_test3(3)
+        y = x
+        x += 10
+
+        self.assert_(isinstance(x, aug_test3))
+        self.assert_(y is not x)
+        self.assertEquals(x.val, 13)
+
+
+    def testCustomMethods2(test_self):
+        output = []
+
+        class testall:
+            def __add__(self, val):
+                output.append("__add__ called")
+            def __radd__(self, val):
+                output.append("__radd__ called")
+            def __iadd__(self, val):
+                output.append("__iadd__ called")
+                return self
+
+            def __sub__(self, val):
+                output.append("__sub__ called")
+            def __rsub__(self, val):
+                output.append("__rsub__ called")
+            def __isub__(self, val):
+                output.append("__isub__ called")
+                return self
+
+            def __mul__(self, val):
+                output.append("__mul__ called")
+            def __rmul__(self, val):
+                output.append("__rmul__ called")
+            def __imul__(self, val):
+                output.append("__imul__ called")
+                return self
+
+            def __div__(self, val):
+                output.append("__div__ called")
+            def __rdiv__(self, val):
+                output.append("__rdiv__ called")
+            def __idiv__(self, val):
+                output.append("__idiv__ called")
+                return self
+
+            def __floordiv__(self, val):
+                output.append("__floordiv__ called")
+                return self
+            def __ifloordiv__(self, val):
+                output.append("__ifloordiv__ called")
+                return self
+            def __rfloordiv__(self, val):
+                output.append("__rfloordiv__ called")
+                return self
+
+            def __truediv__(self, val):
+                output.append("__truediv__ called")
+                return self
+            def __itruediv__(self, val):
+                output.append("__itruediv__ called")
+                return self
+
+            def __mod__(self, val):
+                output.append("__mod__ called")
+            def __rmod__(self, val):
+                output.append("__rmod__ called")
+            def __imod__(self, val):
+                output.append("__imod__ called")
+                return self
+
+            def __pow__(self, val):
+                output.append("__pow__ called")
+            def __rpow__(self, val):
+                output.append("__rpow__ called")
+            def __ipow__(self, val):
+                output.append("__ipow__ called")
+                return self
+
+            def __or__(self, val):
+                output.append("__or__ called")
+            def __ror__(self, val):
+                output.append("__ror__ called")
+            def __ior__(self, val):
+                output.append("__ior__ called")
+                return self
+
+            def __and__(self, val):
+                output.append("__and__ called")
+            def __rand__(self, val):
+                output.append("__rand__ called")
+            def __iand__(self, val):
+                output.append("__iand__ called")
+                return self
+
+            def __xor__(self, val):
+                output.append("__xor__ called")
+            def __rxor__(self, val):
+                output.append("__rxor__ called")
+            def __ixor__(self, val):
+                output.append("__ixor__ called")
+                return self
+
+            def __rshift__(self, val):
+                output.append("__rshift__ called")
+            def __rrshift__(self, val):
+                output.append("__rrshift__ called")
+            def __irshift__(self, val):
+                output.append("__irshift__ called")
+                return self
+
+            def __lshift__(self, val):
+                output.append("__lshift__ called")
+            def __rlshift__(self, val):
+                output.append("__rlshift__ called")
+            def __ilshift__(self, val):
+                output.append("__ilshift__ called")
+                return self
+
+        x = testall()
+        x + 1
+        1 + x
+        x += 1
+
+        x - 1
+        1 - x
+        x -= 1
+
+        x * 1
+        1 * x
+        x *= 1
+
+        if 1/2 == 0:
+            x / 1
+            1 / x
+            x /= 1
+        else:
+            # True division is in effect, so "/" doesn't map to __div__ etc;
+            # but the canned expected-output file requires that those get called.
+            x.__div__(1)
+            x.__rdiv__(1)
+            x.__idiv__(1)
+
+        x // 1
+        1 // x
+        x //= 1
+
+        x % 1
+        1 % x
+        x %= 1
+
+        x ** 1
+        1 ** x
+        x **= 1
+
+        x | 1
+        1 | x
+        x |= 1
+
+        x & 1
+        1 & x
+        x &= 1
+
+        x ^ 1
+        1 ^ x
+        x ^= 1
+
+        x >> 1
+        1 >> x
+        x >>= 1
+
+        x << 1
+        1 << x
+        x <<= 1
+
+        test_self.assertEquals(output, '''\
+__add__ called
+__radd__ called
+__iadd__ called
+__sub__ called
+__rsub__ called
+__isub__ called
+__mul__ called
+__rmul__ called
+__imul__ called
+__div__ called
+__rdiv__ called
+__idiv__ called
+__floordiv__ called
+__rfloordiv__ called
+__ifloordiv__ called
+__mod__ called
+__rmod__ called
+__imod__ called
+__pow__ called
+__rpow__ called
+__ipow__ called
+__or__ called
+__ror__ called
+__ior__ called
+__and__ called
+__rand__ called
+__iand__ called
+__xor__ called
+__rxor__ called
+__ixor__ called
+__rshift__ called
+__rrshift__ called
+__irshift__ called
+__lshift__ called
+__rlshift__ called
+__ilshift__ called
+'''.splitlines())
+
+def test_main():
+    run_unittest(AugAssignTest)
+
+if __name__ == '__main__':
+    test_main()

Added: vendor/Python/current/Lib/test/test_base64.py
===================================================================
--- vendor/Python/current/Lib/test/test_base64.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_base64.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,198 @@
+import unittest
+from test import test_support
+import base64
+
+
+
+class LegacyBase64TestCase(unittest.TestCase):
+    def test_encodestring(self):
+        eq = self.assertEqual
+        eq(base64.encodestring("www.python.org"), "d3d3LnB5dGhvbi5vcmc=\n")
+        eq(base64.encodestring("a"), "YQ==\n")
+        eq(base64.encodestring("ab"), "YWI=\n")
+        eq(base64.encodestring("abc"), "YWJj\n")
+        eq(base64.encodestring(""), "")
+        eq(base64.encodestring("abcdefghijklmnopqrstuvwxyz"
+                               "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+                               "0123456789!@#0^&*();:<>,. []{}"),
+           "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNE"
+           "RUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0\nNT"
+           "Y3ODkhQCMwXiYqKCk7Ojw+LC4gW117fQ==\n")
+
+    def test_decodestring(self):
+        eq = self.assertEqual
+        eq(base64.decodestring("d3d3LnB5dGhvbi5vcmc=\n"), "www.python.org")
+        eq(base64.decodestring("YQ==\n"), "a")
+        eq(base64.decodestring("YWI=\n"), "ab")
+        eq(base64.decodestring("YWJj\n"), "abc")
+        eq(base64.decodestring("YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNE"
+                               "RUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0\nNT"
+                               "Y3ODkhQCMwXiYqKCk7Ojw+LC4gW117fQ==\n"),
+           "abcdefghijklmnopqrstuvwxyz"
+           "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+           "0123456789!@#0^&*();:<>,. []{}")
+        eq(base64.decodestring(''), '')
+
+    def test_encode(self):
+        eq = self.assertEqual
+        from cStringIO import StringIO
+        infp = StringIO('abcdefghijklmnopqrstuvwxyz'
+                        'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+                        '0123456789!@#0^&*();:<>,. []{}')
+        outfp = StringIO()
+        base64.encode(infp, outfp)
+        eq(outfp.getvalue(),
+           'YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNE'
+           'RUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0\nNT'
+           'Y3ODkhQCMwXiYqKCk7Ojw+LC4gW117fQ==\n')
+
+    def test_decode(self):
+        from cStringIO import StringIO
+        infp = StringIO('d3d3LnB5dGhvbi5vcmc=')
+        outfp = StringIO()
+        base64.decode(infp, outfp)
+        self.assertEqual(outfp.getvalue(), 'www.python.org')
+
+
+
+class BaseXYTestCase(unittest.TestCase):
+    def test_b64encode(self):
+        eq = self.assertEqual
+        # Test default alphabet
+        eq(base64.b64encode("www.python.org"), "d3d3LnB5dGhvbi5vcmc=")
+        eq(base64.b64encode('\x00'), 'AA==')
+        eq(base64.b64encode("a"), "YQ==")
+        eq(base64.b64encode("ab"), "YWI=")
+        eq(base64.b64encode("abc"), "YWJj")
+        eq(base64.b64encode(""), "")
+        eq(base64.b64encode("abcdefghijklmnopqrstuvwxyz"
+                            "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+                            "0123456789!@#0^&*();:<>,. []{}"),
+           "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNE"
+           "RUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0NT"
+           "Y3ODkhQCMwXiYqKCk7Ojw+LC4gW117fQ==")
+        # Test with arbitrary alternative characters
+        eq(base64.b64encode('\xd3V\xbeo\xf7\x1d', altchars='*$'), '01a*b$cd')
+        # Test standard alphabet
+        eq(base64.standard_b64encode("www.python.org"), "d3d3LnB5dGhvbi5vcmc=")
+        eq(base64.standard_b64encode("a"), "YQ==")
+        eq(base64.standard_b64encode("ab"), "YWI=")
+        eq(base64.standard_b64encode("abc"), "YWJj")
+        eq(base64.standard_b64encode(""), "")
+        eq(base64.standard_b64encode("abcdefghijklmnopqrstuvwxyz"
+                                     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+                                     "0123456789!@#0^&*();:<>,. []{}"),
+           "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNE"
+           "RUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0NT"
+           "Y3ODkhQCMwXiYqKCk7Ojw+LC4gW117fQ==")
+        # Test with 'URL safe' alternative characters
+        eq(base64.urlsafe_b64encode('\xd3V\xbeo\xf7\x1d'), '01a-b_cd')
+
+    def test_b64decode(self):
+        eq = self.assertEqual
+        eq(base64.b64decode("d3d3LnB5dGhvbi5vcmc="), "www.python.org")
+        eq(base64.b64decode('AA=='), '\x00')
+        eq(base64.b64decode("YQ=="), "a")
+        eq(base64.b64decode("YWI="), "ab")
+        eq(base64.b64decode("YWJj"), "abc")
+        eq(base64.b64decode("YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNE"
+                            "RUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0\nNT"
+                            "Y3ODkhQCMwXiYqKCk7Ojw+LC4gW117fQ=="),
+           "abcdefghijklmnopqrstuvwxyz"
+           "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+           "0123456789!@#0^&*();:<>,. []{}")
+        eq(base64.b64decode(''), '')
+        # Test with arbitrary alternative characters
+        eq(base64.b64decode('01a*b$cd', altchars='*$'), '\xd3V\xbeo\xf7\x1d')
+        # Test standard alphabet
+        eq(base64.standard_b64decode("d3d3LnB5dGhvbi5vcmc="), "www.python.org")
+        eq(base64.standard_b64decode("YQ=="), "a")
+        eq(base64.standard_b64decode("YWI="), "ab")
+        eq(base64.standard_b64decode("YWJj"), "abc")
+        eq(base64.standard_b64decode(""), "")
+        eq(base64.standard_b64decode("YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNE"
+                                     "RUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0NT"
+                                     "Y3ODkhQCMwXiYqKCk7Ojw+LC4gW117fQ=="),
+           "abcdefghijklmnopqrstuvwxyz"
+           "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+           "0123456789!@#0^&*();:<>,. []{}")
+        # Test with 'URL safe' alternative characters
+        eq(base64.urlsafe_b64decode('01a-b_cd'), '\xd3V\xbeo\xf7\x1d')
+
+    def test_b64decode_error(self):
+        self.assertRaises(TypeError, base64.b64decode, 'abc')
+
+    def test_b32encode(self):
+        eq = self.assertEqual
+        eq(base64.b32encode(''), '')
+        eq(base64.b32encode('\x00'), 'AA======')
+        eq(base64.b32encode('a'), 'ME======')
+        eq(base64.b32encode('ab'), 'MFRA====')
+        eq(base64.b32encode('abc'), 'MFRGG===')
+        eq(base64.b32encode('abcd'), 'MFRGGZA=')
+        eq(base64.b32encode('abcde'), 'MFRGGZDF')
+
+    def test_b32decode(self):
+        eq = self.assertEqual
+        eq(base64.b32decode(''), '')
+        eq(base64.b32decode('AA======'), '\x00')
+        eq(base64.b32decode('ME======'), 'a')
+        eq(base64.b32decode('MFRA===='), 'ab')
+        eq(base64.b32decode('MFRGG==='), 'abc')
+        eq(base64.b32decode('MFRGGZA='), 'abcd')
+        eq(base64.b32decode('MFRGGZDF'), 'abcde')
+
+    def test_b32decode_casefold(self):
+        eq = self.assertEqual
+        eq(base64.b32decode('', True), '')
+        eq(base64.b32decode('ME======', True), 'a')
+        eq(base64.b32decode('MFRA====', True), 'ab')
+        eq(base64.b32decode('MFRGG===', True), 'abc')
+        eq(base64.b32decode('MFRGGZA=', True), 'abcd')
+        eq(base64.b32decode('MFRGGZDF', True), 'abcde')
+        # Lower cases
+        eq(base64.b32decode('me======', True), 'a')
+        eq(base64.b32decode('mfra====', True), 'ab')
+        eq(base64.b32decode('mfrgg===', True), 'abc')
+        eq(base64.b32decode('mfrggza=', True), 'abcd')
+        eq(base64.b32decode('mfrggzdf', True), 'abcde')
+        # Expected exceptions
+        self.assertRaises(TypeError, base64.b32decode, 'me======')
+        # Mapping zero and one
+        eq(base64.b32decode('MLO23456'), 'b\xdd\xad\xf3\xbe')
+        eq(base64.b32decode('M1023456', map01='L'), 'b\xdd\xad\xf3\xbe')
+        eq(base64.b32decode('M1023456', map01='I'), 'b\x1d\xad\xf3\xbe')
+
+    def test_b32decode_error(self):
+        self.assertRaises(TypeError, base64.b32decode, 'abc')
+        self.assertRaises(TypeError, base64.b32decode, 'ABCDEF==')
+
+    def test_b16encode(self):
+        eq = self.assertEqual
+        eq(base64.b16encode('\x01\x02\xab\xcd\xef'), '0102ABCDEF')
+        eq(base64.b16encode('\x00'), '00')
+
+    def test_b16decode(self):
+        eq = self.assertEqual
+        eq(base64.b16decode('0102ABCDEF'), '\x01\x02\xab\xcd\xef')
+        eq(base64.b16decode('00'), '\x00')
+        # Lower case is not allowed without a flag
+        self.assertRaises(TypeError, base64.b16decode, '0102abcdef')
+        # Case fold
+        eq(base64.b16decode('0102abcdef', True), '\x01\x02\xab\xcd\xef')
+
+
+
+def suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(LegacyBase64TestCase))
+    suite.addTest(unittest.makeSuite(BaseXYTestCase))
+    return suite
+
+
+def test_main():
+    test_support.run_suite(suite())
+
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='suite')

Added: vendor/Python/current/Lib/test/test_bastion.py
===================================================================
--- vendor/Python/current/Lib/test/test_bastion.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_bastion.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,3 @@
+##import Bastion
+##
+##Bastion._test()

Added: vendor/Python/current/Lib/test/test_bigaddrspace.py
===================================================================
--- vendor/Python/current/Lib/test/test_bigaddrspace.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_bigaddrspace.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,46 @@
+from test import test_support
+from test.test_support import bigaddrspacetest, MAX_Py_ssize_t
+
+import unittest
+import operator
+import sys
+
+
+class StrTest(unittest.TestCase):
+
+    @bigaddrspacetest
+    def test_concat(self):
+        s1 = 'x' * MAX_Py_ssize_t
+        self.assertRaises(OverflowError, operator.add, s1, '?')
+
+    @bigaddrspacetest
+    def test_optimized_concat(self):
+        x = 'x' * MAX_Py_ssize_t
+        try:
+            x = x + '?'     # this statement uses a fast path in ceval.c
+        except OverflowError:
+            pass
+        else:
+            self.fail("should have raised OverflowError")
+        try:
+            x += '?'        # this statement uses a fast path in ceval.c
+        except OverflowError:
+            pass
+        else:
+            self.fail("should have raised OverflowError")
+        self.assertEquals(len(x), MAX_Py_ssize_t)
+
+    ### the following test is pending a patch
+    #   (http://mail.python.org/pipermail/python-dev/2006-July/067774.html)
+    #@bigaddrspacetest
+    #def test_repeat(self):
+    #    self.assertRaises(OverflowError, operator.mul, 'x', MAX_Py_ssize_t + 1)
+
+
+def test_main():
+    test_support.run_unittest(StrTest)
+
+if __name__ == '__main__':
+    if len(sys.argv) > 1:
+        test_support.set_memlimit(sys.argv[1])
+    test_main()

Added: vendor/Python/current/Lib/test/test_bigmem.py
===================================================================
--- vendor/Python/current/Lib/test/test_bigmem.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_bigmem.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,964 @@
+from test import test_support
+from test.test_support import bigmemtest, _1G, _2G
+
+import unittest
+import operator
+import string
+import sys
+
+# Bigmem testing houserules:
+#
+#  - Try not to allocate too many large objects. It's okay to rely on
+#    refcounting semantics, but don't forget that 's = create_largestring()'
+#    doesn't release the old 's' (if it exists) until well after its new
+#    value has been created. Use 'del s' before the create_largestring call.
+#
+#  - Do *not* compare large objects using assertEquals or similar. It's a
+#    lengty operation and the errormessage will be utterly useless due to
+#    its size. To make sure whether a result has the right contents, better
+#    to use the strip or count methods, or compare meaningful slices.
+#
+#  - Don't forget to test for large indices, offsets and results and such,
+#    in addition to large sizes.
+#
+#  - When repeating an object (say, a substring, or a small list) to create
+#    a large object, make the subobject of a length that is not a power of
+#    2. That way, int-wrapping problems are more easily detected.
+#
+#  - While the bigmemtest decorator speaks of 'minsize', all tests will
+#    actually be called with a much smaller number too, in the normal
+#    test run (5Kb currently.) This is so the tests themselves get frequent
+#    testing. Consequently, always make all large allocations based on the
+#    passed-in 'size', and don't rely on the size being very large. Also,
+#    memuse-per-size should remain sane (less than a few thousand); if your
+#    test uses more, adjust 'size' upward, instead.
+
+class StrTest(unittest.TestCase):
+    @bigmemtest(minsize=_2G, memuse=2)
+    def test_capitalize(self, size):
+        SUBSTR = ' abc def ghi'
+        s = '-' * size + SUBSTR
+        caps = s.capitalize()
+        self.assertEquals(caps[-len(SUBSTR):],
+                         SUBSTR.capitalize())
+        self.assertEquals(caps.lstrip('-'), SUBSTR)
+
+    @bigmemtest(minsize=_2G + 10, memuse=1)
+    def test_center(self, size):
+        SUBSTR = ' abc def ghi'
+        s = SUBSTR.center(size)
+        self.assertEquals(len(s), size)
+        lpadsize = rpadsize = (len(s) - len(SUBSTR)) // 2
+        if len(s) % 2:
+            lpadsize += 1
+        self.assertEquals(s[lpadsize:-rpadsize], SUBSTR)
+        self.assertEquals(s.strip(), SUBSTR.strip())
+
+    @bigmemtest(minsize=_2G, memuse=2)
+    def test_count(self, size):
+        SUBSTR = ' abc def ghi'
+        s = '.' * size + SUBSTR
+        self.assertEquals(s.count('.'), size)
+        s += '.'
+        self.assertEquals(s.count('.'), size + 1)
+        self.assertEquals(s.count(' '), 3)
+        self.assertEquals(s.count('i'), 1)
+        self.assertEquals(s.count('j'), 0)
+
+    @bigmemtest(minsize=0, memuse=1)
+    def test_decode(self, size):
+        pass
+
+    @bigmemtest(minsize=0, memuse=1)
+    def test_encode(self, size):
+        pass
+
+    @bigmemtest(minsize=_2G, memuse=2)
+    def test_endswith(self, size):
+        SUBSTR = ' abc def ghi'
+        s = '-' * size + SUBSTR
+        self.failUnless(s.endswith(SUBSTR))
+        self.failUnless(s.endswith(s))
+        s2 = '...' + s
+        self.failUnless(s2.endswith(s))
+        self.failIf(s.endswith('a' + SUBSTR))
+        self.failIf(SUBSTR.endswith(s))
+
+    @bigmemtest(minsize=_2G + 10, memuse=2)
+    def test_expandtabs(self, size):
+        s = '-' * size
+        tabsize = 8
+        self.assertEquals(s.expandtabs(), s)
+        del s
+        slen, remainder = divmod(size, tabsize)
+        s = '       \t' * slen
+        s = s.expandtabs(tabsize)
+        self.assertEquals(len(s), size - remainder)
+        self.assertEquals(len(s.strip(' ')), 0)
+
+    @bigmemtest(minsize=_2G, memuse=2)
+    def test_find(self, size):
+        SUBSTR = ' abc def ghi'
+        sublen = len(SUBSTR)
+        s = ''.join([SUBSTR, '-' * size, SUBSTR])
+        self.assertEquals(s.find(' '), 0)
+        self.assertEquals(s.find(SUBSTR), 0)
+        self.assertEquals(s.find(' ', sublen), sublen + size)
+        self.assertEquals(s.find(SUBSTR, len(SUBSTR)), sublen + size)
+        self.assertEquals(s.find('i'), SUBSTR.find('i'))
+        self.assertEquals(s.find('i', sublen),
+                         sublen + size + SUBSTR.find('i'))
+        self.assertEquals(s.find('i', size),
+                         sublen + size + SUBSTR.find('i'))
+        self.assertEquals(s.find('j'), -1)
+
+    @bigmemtest(minsize=_2G, memuse=2)
+    def test_index(self, size):
+        SUBSTR = ' abc def ghi'
+        sublen = len(SUBSTR)
+        s = ''.join([SUBSTR, '-' * size, SUBSTR])
+        self.assertEquals(s.index(' '), 0)
+        self.assertEquals(s.index(SUBSTR), 0)
+        self.assertEquals(s.index(' ', sublen), sublen + size)
+        self.assertEquals(s.index(SUBSTR, sublen), sublen + size)
+        self.assertEquals(s.index('i'), SUBSTR.index('i'))
+        self.assertEquals(s.index('i', sublen),
+                         sublen + size + SUBSTR.index('i'))
+        self.assertEquals(s.index('i', size),
+                         sublen + size + SUBSTR.index('i'))
+        self.assertRaises(ValueError, s.index, 'j')
+
+    @bigmemtest(minsize=_2G, memuse=2)
+    def test_isalnum(self, size):
+        SUBSTR = '123456'
+        s = 'a' * size + SUBSTR
+        self.failUnless(s.isalnum())
+        s += '.'
+        self.failIf(s.isalnum())
+
+    @bigmemtest(minsize=_2G, memuse=2)
+    def test_isalpha(self, size):
+        SUBSTR = 'zzzzzzz'
+        s = 'a' * size + SUBSTR
+        self.failUnless(s.isalpha())
+        s += '.'
+        self.failIf(s.isalpha())
+
+    @bigmemtest(minsize=_2G, memuse=2)
+    def test_isdigit(self, size):
+        SUBSTR = '123456'
+        s = '9' * size + SUBSTR
+        self.failUnless(s.isdigit())
+        s += 'z'
+        self.failIf(s.isdigit())
+
+    @bigmemtest(minsize=_2G, memuse=2)
+    def test_islower(self, size):
+        chars = ''.join([ chr(c) for c in range(255) if not chr(c).isupper() ])
+        repeats = size // len(chars) + 2
+        s = chars * repeats
+        self.failUnless(s.islower())
+        s += 'A'
+        self.failIf(s.islower())
+
+    @bigmemtest(minsize=_2G, memuse=2)
+    def test_isspace(self, size):
+        whitespace = ' \f\n\r\t\v'
+        repeats = size // len(whitespace) + 2
+        s = whitespace * repeats
+        self.failUnless(s.isspace())
+        s += 'j'
+        self.failIf(s.isspace())
+
+    @bigmemtest(minsize=_2G, memuse=2)
+    def test_istitle(self, size):
+        SUBSTR = '123456'
+        s = ''.join(['A', 'a' * size, SUBSTR])
+        self.failUnless(s.istitle())
+        s += 'A'
+        self.failUnless(s.istitle())
+        s += 'aA'
+        self.failIf(s.istitle())
+
+    @bigmemtest(minsize=_2G, memuse=2)
+    def test_isupper(self, size):
+        chars = ''.join([ chr(c) for c in range(255) if not chr(c).islower() ])
+        repeats = size // len(chars) + 2
+        s = chars * repeats
+        self.failUnless(s.isupper())
+        s += 'a'
+        self.failIf(s.isupper())
+
+    @bigmemtest(minsize=_2G, memuse=2)
+    def test_join(self, size):
+        s = 'A' * size
+        x = s.join(['aaaaa', 'bbbbb'])
+        self.assertEquals(x.count('a'), 5)
+        self.assertEquals(x.count('b'), 5)
+        self.failUnless(x.startswith('aaaaaA'))
+        self.failUnless(x.endswith('Abbbbb'))
+
+    @bigmemtest(minsize=_2G + 10, memuse=1)
+    def test_ljust(self, size):
+        SUBSTR = ' abc def ghi'
+        s = SUBSTR.ljust(size)
+        self.failUnless(s.startswith(SUBSTR + '  '))
+        self.assertEquals(len(s), size)
+        self.assertEquals(s.strip(), SUBSTR.strip())
+
+    @bigmemtest(minsize=_2G + 10, memuse=2)
+    def test_lower(self, size):
+        s = 'A' * size
+        s = s.lower()
+        self.assertEquals(len(s), size)
+        self.assertEquals(s.count('a'), size)
+
+    @bigmemtest(minsize=_2G + 10, memuse=1)
+    def test_lstrip(self, size):
+        SUBSTR = 'abc def ghi'
+        s = SUBSTR.rjust(size)
+        self.assertEquals(len(s), size)
+        self.assertEquals(s.lstrip(), SUBSTR.lstrip())
+        del s
+        s = SUBSTR.ljust(size)
+        self.assertEquals(len(s), size)
+        stripped = s.lstrip()
+        self.failUnless(stripped is s)
+
+    @bigmemtest(minsize=_2G + 10, memuse=2)
+    def test_replace(self, size):
+        replacement = 'a'
+        s = ' ' * size
+        s = s.replace(' ', replacement)
+        self.assertEquals(len(s), size)
+        self.assertEquals(s.count(replacement), size)
+        s = s.replace(replacement, ' ', size - 4)
+        self.assertEquals(len(s), size)
+        self.assertEquals(s.count(replacement), 4)
+        self.assertEquals(s[-10:], '      aaaa')
+
+    @bigmemtest(minsize=_2G, memuse=2)
+    def test_rfind(self, size):
+        SUBSTR = ' abc def ghi'
+        sublen = len(SUBSTR)
+        s = ''.join([SUBSTR, '-' * size, SUBSTR])
+        self.assertEquals(s.rfind(' '), sublen + size + SUBSTR.rfind(' '))
+        self.assertEquals(s.rfind(SUBSTR), sublen + size)
+        self.assertEquals(s.rfind(' ', 0, size), SUBSTR.rfind(' '))
+        self.assertEquals(s.rfind(SUBSTR, 0, sublen + size), 0)
+        self.assertEquals(s.rfind('i'), sublen + size + SUBSTR.rfind('i'))
+        self.assertEquals(s.rfind('i', 0, sublen), SUBSTR.rfind('i'))
+        self.assertEquals(s.rfind('i', 0, sublen + size),
+                          SUBSTR.rfind('i'))
+        self.assertEquals(s.rfind('j'), -1)
+
+    @bigmemtest(minsize=_2G, memuse=2)
+    def test_rindex(self, size):
+        SUBSTR = ' abc def ghi'
+        sublen = len(SUBSTR)
+        s = ''.join([SUBSTR, '-' * size, SUBSTR])
+        self.assertEquals(s.rindex(' '),
+                          sublen + size + SUBSTR.rindex(' '))
+        self.assertEquals(s.rindex(SUBSTR), sublen + size)
+        self.assertEquals(s.rindex(' ', 0, sublen + size - 1),
+                          SUBSTR.rindex(' '))
+        self.assertEquals(s.rindex(SUBSTR, 0, sublen + size), 0)
+        self.assertEquals(s.rindex('i'),
+                          sublen + size + SUBSTR.rindex('i'))
+        self.assertEquals(s.rindex('i', 0, sublen), SUBSTR.rindex('i'))
+        self.assertEquals(s.rindex('i', 0, sublen + size),
+                          SUBSTR.rindex('i'))
+        self.assertRaises(ValueError, s.rindex, 'j')
+
+    @bigmemtest(minsize=_2G + 10, memuse=1)
+    def test_rjust(self, size):
+        SUBSTR = ' abc def ghi'
+        s = SUBSTR.ljust(size)
+        self.failUnless(s.startswith(SUBSTR + '  '))
+        self.assertEquals(len(s), size)
+        self.assertEquals(s.strip(), SUBSTR.strip())
+
+    @bigmemtest(minsize=_2G + 10, memuse=1)
+    def test_rstrip(self, size):
+        SUBSTR = ' abc def ghi'
+        s = SUBSTR.ljust(size)
+        self.assertEquals(len(s), size)
+        self.assertEquals(s.rstrip(), SUBSTR.rstrip())
+        del s
+        s = SUBSTR.rjust(size)
+        self.assertEquals(len(s), size)
+        stripped = s.rstrip()
+        self.failUnless(stripped is s)
+
+    # The test takes about size bytes to build a string, and then about
+    # sqrt(size) substrings of sqrt(size) in size and a list to
+    # hold sqrt(size) items. It's close but just over 2x size.
+    @bigmemtest(minsize=_2G, memuse=2.1)
+    def test_split_small(self, size):
+        # Crudely calculate an estimate so that the result of s.split won't
+        # take up an inordinate amount of memory
+        chunksize = int(size ** 0.5 + 2)
+        SUBSTR = 'a' + ' ' * chunksize
+        s = SUBSTR * chunksize
+        l = s.split()
+        self.assertEquals(len(l), chunksize)
+        self.assertEquals(set(l), set(['a']))
+        del l
+        l = s.split('a')
+        self.assertEquals(len(l), chunksize + 1)
+        self.assertEquals(set(l), set(['', ' ' * chunksize]))
+
+    # Allocates a string of twice size (and briefly two) and a list of
+    # size.  Because of internal affairs, the s.split() call produces a
+    # list of size times the same one-character string, so we only
+    # suffer for the list size. (Otherwise, it'd cost another 48 times
+    # size in bytes!) Nevertheless, a list of size takes
+    # 8*size bytes.
+    @bigmemtest(minsize=_2G + 5, memuse=10)
+    def test_split_large(self, size):
+        s = ' a' * size + ' '
+        l = s.split()
+        self.assertEquals(len(l), size)
+        self.assertEquals(set(l), set(['a']))
+        del l
+        l = s.split('a')
+        self.assertEquals(len(l), size + 1)
+        self.assertEquals(set(l), set([' ']))
+
+    @bigmemtest(minsize=_2G, memuse=2.1)
+    def test_splitlines(self, size):
+        # Crudely calculate an estimate so that the result of s.split won't
+        # take up an inordinate amount of memory
+        chunksize = int(size ** 0.5 + 2) // 2
+        SUBSTR = ' ' * chunksize + '\n' + ' ' * chunksize + '\r\n'
+        s = SUBSTR * chunksize
+        l = s.splitlines()
+        self.assertEquals(len(l), chunksize * 2)
+        self.assertEquals(set(l), set([' ' * chunksize]))
+
+    @bigmemtest(minsize=_2G, memuse=2)
+    def test_startswith(self, size):
+        SUBSTR = ' abc def ghi'
+        s = '-' * size + SUBSTR
+        self.failUnless(s.startswith(s))
+        self.failUnless(s.startswith('-' * size))
+        self.failIf(s.startswith(SUBSTR))
+
+    @bigmemtest(minsize=_2G, memuse=1)
+    def test_strip(self, size):
+        SUBSTR = '   abc def ghi   '
+        s = SUBSTR.rjust(size)
+        self.assertEquals(len(s), size)
+        self.assertEquals(s.strip(), SUBSTR.strip())
+        del s
+        s = SUBSTR.ljust(size)
+        self.assertEquals(len(s), size)
+        self.assertEquals(s.strip(), SUBSTR.strip())
+
+    @bigmemtest(minsize=_2G, memuse=2)
+    def test_swapcase(self, size):
+        SUBSTR = "aBcDeFG12.'\xa9\x00"
+        sublen = len(SUBSTR)
+        repeats = size // sublen + 2
+        s = SUBSTR * repeats
+        s = s.swapcase()
+        self.assertEquals(len(s), sublen * repeats)
+        self.assertEquals(s[:sublen * 3], SUBSTR.swapcase() * 3)
+        self.assertEquals(s[-sublen * 3:], SUBSTR.swapcase() * 3)
+
+    @bigmemtest(minsize=_2G, memuse=2)
+    def test_title(self, size):
+        SUBSTR = 'SpaaHAaaAaham'
+        s = SUBSTR * (size // len(SUBSTR) + 2)
+        s = s.title()
+        self.failUnless(s.startswith((SUBSTR * 3).title()))
+        self.failUnless(s.endswith(SUBSTR.lower() * 3))
+
+    @bigmemtest(minsize=_2G, memuse=2)
+    def test_translate(self, size):
+        trans = string.maketrans('.aZ', '-!$')
+        SUBSTR = 'aZz.z.Aaz.'
+        sublen = len(SUBSTR)
+        repeats = size // sublen + 2
+        s = SUBSTR * repeats
+        s = s.translate(trans)
+        self.assertEquals(len(s), repeats * sublen)
+        self.assertEquals(s[:sublen], SUBSTR.translate(trans))
+        self.assertEquals(s[-sublen:], SUBSTR.translate(trans))
+        self.assertEquals(s.count('.'), 0)
+        self.assertEquals(s.count('!'), repeats * 2)
+        self.assertEquals(s.count('z'), repeats * 3)
+
+    @bigmemtest(minsize=_2G + 5, memuse=2)
+    def test_upper(self, size):
+        s = 'a' * size
+        s = s.upper()
+        self.assertEquals(len(s), size)
+        self.assertEquals(s.count('A'), size)
+
+    @bigmemtest(minsize=_2G + 20, memuse=1)
+    def test_zfill(self, size):
+        SUBSTR = '-568324723598234'
+        s = SUBSTR.zfill(size)
+        self.failUnless(s.endswith('0' + SUBSTR[1:]))
+        self.failUnless(s.startswith('-0'))
+        self.assertEquals(len(s), size)
+        self.assertEquals(s.count('0'), size - len(SUBSTR))
+
+    @bigmemtest(minsize=_2G + 10, memuse=2)
+    def test_format(self, size):
+        s = '-' * size
+        sf = '%s' % (s,)
+        self.failUnless(s == sf)
+        del sf
+        sf = '..%s..' % (s,)
+        self.assertEquals(len(sf), len(s) + 4)
+        self.failUnless(sf.startswith('..-'))
+        self.failUnless(sf.endswith('-..'))
+        del s, sf
+
+        size //= 2
+        edge = '-' * size
+        s = ''.join([edge, '%s', edge])
+        del edge
+        s = s % '...'
+        self.assertEquals(len(s), size * 2 + 3)
+        self.assertEquals(s.count('.'), 3)
+        self.assertEquals(s.count('-'), size * 2)
+
+    @bigmemtest(minsize=_2G + 10, memuse=2)
+    def test_repr_small(self, size):
+        s = '-' * size
+        s = repr(s)
+        self.assertEquals(len(s), size + 2)
+        self.assertEquals(s[0], "'")
+        self.assertEquals(s[-1], "'")
+        self.assertEquals(s.count('-'), size)
+        del s
+        # repr() will create a string four times as large as this 'binary
+        # string', but we don't want to allocate much more than twice
+        # size in total.  (We do extra testing in test_repr_large())
+        size = size // 5 * 2
+        s = '\x00' * size
+        s = repr(s)
+        self.assertEquals(len(s), size * 4 + 2)
+        self.assertEquals(s[0], "'")
+        self.assertEquals(s[-1], "'")
+        self.assertEquals(s.count('\\'), size)
+        self.assertEquals(s.count('0'), size * 2)
+
+    @bigmemtest(minsize=_2G + 10, memuse=5)
+    def test_repr_large(self, size):
+        s = '\x00' * size
+        s = repr(s)
+        self.assertEquals(len(s), size * 4 + 2)
+        self.assertEquals(s[0], "'")
+        self.assertEquals(s[-1], "'")
+        self.assertEquals(s.count('\\'), size)
+        self.assertEquals(s.count('0'), size * 2)
+
+    # This test is meaningful even with size < 2G, as long as the
+    # doubled string is > 2G (but it tests more if both are > 2G :)
+    @bigmemtest(minsize=_1G + 2, memuse=3)
+    def test_concat(self, size):
+        s = '.' * size
+        self.assertEquals(len(s), size)
+        s = s + s
+        self.assertEquals(len(s), size * 2)
+        self.assertEquals(s.count('.'), size * 2)
+
+    # This test is meaningful even with size < 2G, as long as the
+    # repeated string is > 2G (but it tests more if both are > 2G :)
+    @bigmemtest(minsize=_1G + 2, memuse=3)
+    def test_repeat(self, size):
+        s = '.' * size
+        self.assertEquals(len(s), size)
+        s = s * 2
+        self.assertEquals(len(s), size * 2)
+        self.assertEquals(s.count('.'), size * 2)
+
+    @bigmemtest(minsize=_2G + 20, memuse=1)
+    def test_slice_and_getitem(self, size):
+        SUBSTR = '0123456789'
+        sublen = len(SUBSTR)
+        s = SUBSTR * (size // sublen)
+        stepsize = len(s) // 100
+        stepsize = stepsize - (stepsize % sublen)
+        for i in range(0, len(s) - stepsize, stepsize):
+            self.assertEquals(s[i], SUBSTR[0])
+            self.assertEquals(s[i:i + sublen], SUBSTR)
+            self.assertEquals(s[i:i + sublen:2], SUBSTR[::2])
+            if i > 0:
+                self.assertEquals(s[i + sublen - 1:i - 1:-3],
+                                  SUBSTR[sublen::-3])
+        # Make sure we do some slicing and indexing near the end of the
+        # string, too.
+        self.assertEquals(s[len(s) - 1], SUBSTR[-1])
+        self.assertEquals(s[-1], SUBSTR[-1])
+        self.assertEquals(s[len(s) - 10], SUBSTR[0])
+        self.assertEquals(s[-sublen], SUBSTR[0])
+        self.assertEquals(s[len(s):], '')
+        self.assertEquals(s[len(s) - 1:], SUBSTR[-1])
+        self.assertEquals(s[-1:], SUBSTR[-1])
+        self.assertEquals(s[len(s) - sublen:], SUBSTR)
+        self.assertEquals(s[-sublen:], SUBSTR)
+        self.assertEquals(len(s[:]), len(s))
+        self.assertEquals(len(s[:len(s) - 5]), len(s) - 5)
+        self.assertEquals(len(s[5:-5]), len(s) - 10)
+
+        self.assertRaises(IndexError, operator.getitem, s, len(s))
+        self.assertRaises(IndexError, operator.getitem, s, len(s) + 1)
+        self.assertRaises(IndexError, operator.getitem, s, len(s) + 1<<31)
+
+    @bigmemtest(minsize=_2G, memuse=2)
+    def test_contains(self, size):
+        SUBSTR = '0123456789'
+        edge = '-' * (size // 2)
+        s = ''.join([edge, SUBSTR, edge])
+        del edge
+        self.failUnless(SUBSTR in s)
+        self.failIf(SUBSTR * 2 in s)
+        self.failUnless('-' in s)
+        self.failIf('a' in s)
+        s += 'a'
+        self.failUnless('a' in s)
+
+    @bigmemtest(minsize=_2G + 10, memuse=2)
+    def test_compare(self, size):
+        s1 = '-' * size
+        s2 = '-' * size
+        self.failUnless(s1 == s2)
+        del s2
+        s2 = s1 + 'a'
+        self.failIf(s1 == s2)
+        del s2
+        s2 = '.' * size
+        self.failIf(s1 == s2)
+
+    @bigmemtest(minsize=_2G + 10, memuse=1)
+    def test_hash(self, size):
+        # Not sure if we can do any meaningful tests here...  Even if we
+        # start relying on the exact algorithm used, the result will be
+        # different depending on the size of the C 'long int'.  Even this
+        # test is dodgy (there's no *guarantee* that the two things should
+        # have a different hash, even if they, in the current
+        # implementation, almost always do.)
+        s = '\x00' * size
+        h1 = hash(s)
+        del s
+        s = '\x00' * (size + 1)
+        self.failIf(h1 == hash(s))
+
+class TupleTest(unittest.TestCase):
+
+    # Tuples have a small, fixed-sized head and an array of pointers to
+    # data.  Since we're testing 64-bit addressing, we can assume that the
+    # pointers are 8 bytes, and that thus that the tuples take up 8 bytes
+    # per size.
+
+    # As a side-effect of testing long tuples, these tests happen to test
+    # having more than 2<<31 references to any given object. Hence the
+    # use of different types of objects as contents in different tests.
+
+    @bigmemtest(minsize=_2G + 2, memuse=16)
+    def test_compare(self, size):
+        t1 = (u'',) * size
+        t2 = (u'',) * size
+        self.failUnless(t1 == t2)
+        del t2
+        t2 = (u'',) * (size + 1)
+        self.failIf(t1 == t2)
+        del t2
+        t2 = (1,) * size
+        self.failIf(t1 == t2)
+
+    # Test concatenating into a single tuple of more than 2G in length,
+    # and concatenating a tuple of more than 2G in length separately, so
+    # the smaller test still gets run even if there isn't memory for the
+    # larger test (but we still let the tester know the larger test is
+    # skipped, in verbose mode.)
+    def basic_concat_test(self, size):
+        t = ((),) * size
+        self.assertEquals(len(t), size)
+        t = t + t
+        self.assertEquals(len(t), size * 2)
+
+    @bigmemtest(minsize=_2G // 2 + 2, memuse=24)
+    def test_concat_small(self, size):
+        return self.basic_concat_test(size)
+
+    @bigmemtest(minsize=_2G + 2, memuse=24)
+    def test_concat_large(self, size):
+        return self.basic_concat_test(size)
+
+    @bigmemtest(minsize=_2G // 5 + 10, memuse=8 * 5)
+    def test_contains(self, size):
+        t = (1, 2, 3, 4, 5) * size
+        self.assertEquals(len(t), size * 5)
+        self.failUnless(5 in t)
+        self.failIf((1, 2, 3, 4, 5) in t)
+        self.failIf(0 in t)
+
+    @bigmemtest(minsize=_2G + 10, memuse=8)
+    def test_hash(self, size):
+        t1 = (0,) * size
+        h1 = hash(t1)
+        del t1
+        t2 = (0,) * (size + 1)
+        self.failIf(h1 == hash(t2))
+
+    @bigmemtest(minsize=_2G + 10, memuse=8)
+    def test_index_and_slice(self, size):
+        t = (None,) * size
+        self.assertEquals(len(t), size)
+        self.assertEquals(t[-1], None)
+        self.assertEquals(t[5], None)
+        self.assertEquals(t[size - 1], None)
+        self.assertRaises(IndexError, operator.getitem, t, size)
+        self.assertEquals(t[:5], (None,) * 5)
+        self.assertEquals(t[-5:], (None,) * 5)
+        self.assertEquals(t[20:25], (None,) * 5)
+        self.assertEquals(t[-25:-20], (None,) * 5)
+        self.assertEquals(t[size - 5:], (None,) * 5)
+        self.assertEquals(t[size - 5:size], (None,) * 5)
+        self.assertEquals(t[size - 6:size - 2], (None,) * 4)
+        self.assertEquals(t[size:size], ())
+        self.assertEquals(t[size:size+5], ())
+
+    # Like test_concat, split in two.
+    def basic_test_repeat(self, size):
+        t = ('',) * size
+        self.assertEquals(len(t), size)
+        t = t * 2
+        self.assertEquals(len(t), size * 2)
+
+    @bigmemtest(minsize=_2G // 2 + 2, memuse=24)
+    def test_repeat_small(self, size):
+        return self.basic_test_repeat(size)
+
+    @bigmemtest(minsize=_2G + 2, memuse=24)
+    def test_repeat_large(self, size):
+        return self.basic_test_repeat(size)
+
+    # Like test_concat, split in two.
+    def basic_test_repr(self, size):
+        t = (0,) * size
+        s = repr(t)
+        # The repr of a tuple of 0's is exactly three times the tuple length.
+        self.assertEquals(len(s), size * 3)
+        self.assertEquals(s[:5], '(0, 0')
+        self.assertEquals(s[-5:], '0, 0)')
+        self.assertEquals(s.count('0'), size)
+
+    @bigmemtest(minsize=_2G // 3 + 2, memuse=8 + 3)
+    def test_repr_small(self, size):
+        return self.basic_test_repr(size)
+
+    @bigmemtest(minsize=_2G + 2, memuse=8 + 3)
+    def test_repr_large(self, size):
+        return self.basic_test_repr(size)
+
+class ListTest(unittest.TestCase):
+
+    # Like tuples, lists have a small, fixed-sized head and an array of
+    # pointers to data, so 8 bytes per size. Also like tuples, we make the
+    # lists hold references to various objects to test their refcount
+    # limits.
+
+    @bigmemtest(minsize=_2G + 2, memuse=16)
+    def test_compare(self, size):
+        l1 = [u''] * size
+        l2 = [u''] * size
+        self.failUnless(l1 == l2)
+        del l2
+        l2 = [u''] * (size + 1)
+        self.failIf(l1 == l2)
+        del l2
+        l2 = [2] * size
+        self.failIf(l1 == l2)
+
+    # Test concatenating into a single list of more than 2G in length,
+    # and concatenating a list of more than 2G in length separately, so
+    # the smaller test still gets run even if there isn't memory for the
+    # larger test (but we still let the tester know the larger test is
+    # skipped, in verbose mode.)
+    def basic_test_concat(self, size):
+        l = [[]] * size
+        self.assertEquals(len(l), size)
+        l = l + l
+        self.assertEquals(len(l), size * 2)
+
+    @bigmemtest(minsize=_2G // 2 + 2, memuse=24)
+    def test_concat_small(self, size):
+        return self.basic_test_concat(size)
+
+    @bigmemtest(minsize=_2G + 2, memuse=24)
+    def test_concat_large(self, size):
+        return self.basic_test_concat(size)
+
+    def basic_test_inplace_concat(self, size):
+        l = [sys.stdout] * size
+        l += l
+        self.assertEquals(len(l), size * 2)
+        self.failUnless(l[0] is l[-1])
+        self.failUnless(l[size - 1] is l[size + 1])
+
+    @bigmemtest(minsize=_2G // 2 + 2, memuse=24)
+    def test_inplace_concat_small(self, size):
+        return self.basic_test_inplace_concat(size)
+
+    @bigmemtest(minsize=_2G + 2, memuse=24)
+    def test_inplace_concat_large(self, size):
+        return self.basic_test_inplace_concat(size)
+
+    @bigmemtest(minsize=_2G // 5 + 10, memuse=8 * 5)
+    def test_contains(self, size):
+        l = [1, 2, 3, 4, 5] * size
+        self.assertEquals(len(l), size * 5)
+        self.failUnless(5 in l)
+        self.failIf([1, 2, 3, 4, 5] in l)
+        self.failIf(0 in l)
+
+    @bigmemtest(minsize=_2G + 10, memuse=8)
+    def test_hash(self, size):
+        l = [0] * size
+        self.failUnlessRaises(TypeError, hash, l)
+
+    @bigmemtest(minsize=_2G + 10, memuse=8)
+    def test_index_and_slice(self, size):
+        l = [None] * size
+        self.assertEquals(len(l), size)
+        self.assertEquals(l[-1], None)
+        self.assertEquals(l[5], None)
+        self.assertEquals(l[size - 1], None)
+        self.assertRaises(IndexError, operator.getitem, l, size)
+        self.assertEquals(l[:5], [None] * 5)
+        self.assertEquals(l[-5:], [None] * 5)
+        self.assertEquals(l[20:25], [None] * 5)
+        self.assertEquals(l[-25:-20], [None] * 5)
+        self.assertEquals(l[size - 5:], [None] * 5)
+        self.assertEquals(l[size - 5:size], [None] * 5)
+        self.assertEquals(l[size - 6:size - 2], [None] * 4)
+        self.assertEquals(l[size:size], [])
+        self.assertEquals(l[size:size+5], [])
+
+        l[size - 2] = 5
+        self.assertEquals(len(l), size)
+        self.assertEquals(l[-3:], [None, 5, None])
+        self.assertEquals(l.count(5), 1)
+        self.assertRaises(IndexError, operator.setitem, l, size, 6)
+        self.assertEquals(len(l), size)
+
+        l[size - 7:] = [1, 2, 3, 4, 5]
+        size -= 2
+        self.assertEquals(len(l), size)
+        self.assertEquals(l[-7:], [None, None, 1, 2, 3, 4, 5])
+
+        l[:7] = [1, 2, 3, 4, 5]
+        size -= 2
+        self.assertEquals(len(l), size)
+        self.assertEquals(l[:7], [1, 2, 3, 4, 5, None, None])
+
+        del l[size - 1]
+        size -= 1
+        self.assertEquals(len(l), size)
+        self.assertEquals(l[-1], 4)
+
+        del l[-2:]
+        size -= 2
+        self.assertEquals(len(l), size)
+        self.assertEquals(l[-1], 2)
+
+        del l[0]
+        size -= 1
+        self.assertEquals(len(l), size)
+        self.assertEquals(l[0], 2)
+
+        del l[:2]
+        size -= 2
+        self.assertEquals(len(l), size)
+        self.assertEquals(l[0], 4)
+
+    # Like test_concat, split in two.
+    def basic_test_repeat(self, size):
+        l = [] * size
+        self.failIf(l)
+        l = [''] * size
+        self.assertEquals(len(l), size)
+        l = l * 2
+        self.assertEquals(len(l), size * 2)
+
+    @bigmemtest(minsize=_2G // 2 + 2, memuse=24)
+    def test_repeat_small(self, size):
+        return self.basic_test_repeat(size)
+
+    @bigmemtest(minsize=_2G + 2, memuse=24)
+    def test_repeat_large(self, size):
+        return self.basic_test_repeat(size)
+
+    def basic_test_inplace_repeat(self, size):
+        l = ['']
+        l *= size
+        self.assertEquals(len(l), size)
+        self.failUnless(l[0] is l[-1])
+        del l
+
+        l = [''] * size
+        l *= 2
+        self.assertEquals(len(l), size * 2)
+        self.failUnless(l[size - 1] is l[-1])
+
+    @bigmemtest(minsize=_2G // 2 + 2, memuse=16)
+    def test_inplace_repeat_small(self, size):
+        return self.basic_test_inplace_repeat(size)
+
+    @bigmemtest(minsize=_2G + 2, memuse=16)
+    def test_inplace_repeat_large(self, size):
+        return self.basic_test_inplace_repeat(size)
+
+    def basic_test_repr(self, size):
+        l = [0] * size
+        s = repr(l)
+        # The repr of a list of 0's is exactly three times the list length.
+        self.assertEquals(len(s), size * 3)
+        self.assertEquals(s[:5], '[0, 0')
+        self.assertEquals(s[-5:], '0, 0]')
+        self.assertEquals(s.count('0'), size)
+
+    @bigmemtest(minsize=_2G // 3 + 2, memuse=8 + 3)
+    def test_repr_small(self, size):
+        return self.basic_test_repr(size)
+
+    @bigmemtest(minsize=_2G + 2, memuse=8 + 3)
+    def test_repr_large(self, size):
+        return self.basic_test_repr(size)
+
+    # list overallocates ~1/8th of the total size (on first expansion) so
+    # the single list.append call puts memuse at 9 bytes per size.
+    @bigmemtest(minsize=_2G, memuse=9)
+    def test_append(self, size):
+        l = [object()] * size
+        l.append(object())
+        self.assertEquals(len(l), size+1)
+        self.failUnless(l[-3] is l[-2])
+        self.failIf(l[-2] is l[-1])
+
+    @bigmemtest(minsize=_2G // 5 + 2, memuse=8 * 5)
+    def test_count(self, size):
+        l = [1, 2, 3, 4, 5] * size
+        self.assertEquals(l.count(1), size)
+        self.assertEquals(l.count("1"), 0)
+
+    def basic_test_extend(self, size):
+        l = [file] * size
+        l.extend(l)
+        self.assertEquals(len(l), size * 2)
+        self.failUnless(l[0] is l[-1])
+        self.failUnless(l[size - 1] is l[size + 1])
+
+    @bigmemtest(minsize=_2G // 2 + 2, memuse=16)
+    def test_extend_small(self, size):
+        return self.basic_test_extend(size)
+
+    @bigmemtest(minsize=_2G + 2, memuse=16)
+    def test_extend_large(self, size):
+        return self.basic_test_extend(size)
+
+    @bigmemtest(minsize=_2G // 5 + 2, memuse=8 * 5)
+    def test_index(self, size):
+        l = [1L, 2L, 3L, 4L, 5L] * size
+        size *= 5
+        self.assertEquals(l.index(1), 0)
+        self.assertEquals(l.index(5, size - 5), size - 1)
+        self.assertEquals(l.index(5, size - 5, size), size - 1)
+        self.assertRaises(ValueError, l.index, 1, size - 4, size)
+        self.assertRaises(ValueError, l.index, 6L)
+
+    # This tests suffers from overallocation, just like test_append.
+    @bigmemtest(minsize=_2G + 10, memuse=9)
+    def test_insert(self, size):
+        l = [1.0] * size
+        l.insert(size - 1, "A")
+        size += 1
+        self.assertEquals(len(l), size)
+        self.assertEquals(l[-3:], [1.0, "A", 1.0])
+
+        l.insert(size + 1, "B")
+        size += 1
+        self.assertEquals(len(l), size)
+        self.assertEquals(l[-3:], ["A", 1.0, "B"])
+
+        l.insert(1, "C")
+        size += 1
+        self.assertEquals(len(l), size)
+        self.assertEquals(l[:3], [1.0, "C", 1.0])
+        self.assertEquals(l[size - 3:], ["A", 1.0, "B"])
+
+    @bigmemtest(minsize=_2G // 5 + 4, memuse=8 * 5)
+    def test_pop(self, size):
+        l = [u"a", u"b", u"c", u"d", u"e"] * size
+        size *= 5
+        self.assertEquals(len(l), size)
+
+        item = l.pop()
+        size -= 1
+        self.assertEquals(len(l), size)
+        self.assertEquals(item, u"e")
+        self.assertEquals(l[-2:], [u"c", u"d"])
+
+        item = l.pop(0)
+        size -= 1
+        self.assertEquals(len(l), size)
+        self.assertEquals(item, u"a")
+        self.assertEquals(l[:2], [u"b", u"c"])
+
+        item = l.pop(size - 2)
+        size -= 1
+        self.assertEquals(len(l), size)
+        self.assertEquals(item, u"c")
+        self.assertEquals(l[-2:], [u"b", u"d"])
+
+    @bigmemtest(minsize=_2G + 10, memuse=8)
+    def test_remove(self, size):
+        l = [10] * size
+        self.assertEquals(len(l), size)
+
+        l.remove(10)
+        size -= 1
+        self.assertEquals(len(l), size)
+
+        # Because of the earlier l.remove(), this append doesn't trigger
+        # a resize.
+        l.append(5)
+        size += 1
+        self.assertEquals(len(l), size)
+        self.assertEquals(l[-2:], [10, 5])
+        l.remove(5)
+        size -= 1
+        self.assertEquals(len(l), size)
+        self.assertEquals(l[-2:], [10, 10])
+
+    @bigmemtest(minsize=_2G // 5 + 2, memuse=8 * 5)
+    def test_reverse(self, size):
+        l = [1, 2, 3, 4, 5] * size
+        l.reverse()
+        self.assertEquals(len(l), size * 5)
+        self.assertEquals(l[-5:], [5, 4, 3, 2, 1])
+        self.assertEquals(l[:5], [5, 4, 3, 2, 1])
+
+    @bigmemtest(minsize=_2G // 5 + 2, memuse=8 * 5)
+    def test_sort(self, size):
+        l = [1, 2, 3, 4, 5] * size
+        l.sort()
+        self.assertEquals(len(l), size * 5)
+        self.assertEquals(l.count(1), size)
+        self.assertEquals(l[:10], [1] * 10)
+        self.assertEquals(l[-10:], [5] * 10)
+
+def test_main():
+    test_support.run_unittest(StrTest, TupleTest, ListTest)
+
+if __name__ == '__main__':
+    if len(sys.argv) > 1:
+        test_support.set_memlimit(sys.argv[1])
+    test_main()

Added: vendor/Python/current/Lib/test/test_binascii.py
===================================================================
--- vendor/Python/current/Lib/test/test_binascii.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_binascii.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,165 @@
+"""Test the binascii C module."""
+
+from test import test_support
+import unittest
+import binascii
+
+class BinASCIITest(unittest.TestCase):
+
+    # Create binary test data
+    data = "The quick brown fox jumps over the lazy dog.\r\n"
+    # Be slow so we don't depend on other modules
+    data += "".join(map(chr, xrange(256)))
+    data += "\r\nHello world.\n"
+
+    def test_exceptions(self):
+        # Check module exceptions
+        self.assert_(issubclass(binascii.Error, Exception))
+        self.assert_(issubclass(binascii.Incomplete, Exception))
+
+    def test_functions(self):
+        # Check presence of all functions
+        funcs = []
+        for suffix in "base64", "hqx", "uu", "hex":
+            prefixes = ["a2b_", "b2a_"]
+            if suffix == "hqx":
+                prefixes.extend(["crc_", "rlecode_", "rledecode_"])
+            for prefix in prefixes:
+                name = prefix + suffix
+                self.assert_(callable(getattr(binascii, name)))
+                self.assertRaises(TypeError, getattr(binascii, name))
+        for name in ("hexlify", "unhexlify"):
+            self.assert_(callable(getattr(binascii, name)))
+            self.assertRaises(TypeError, getattr(binascii, name))
+
+    def test_base64valid(self):
+        # Test base64 with valid data
+        MAX_BASE64 = 57
+        lines = []
+        for i in range(0, len(self.data), MAX_BASE64):
+            b = self.data[i:i+MAX_BASE64]
+            a = binascii.b2a_base64(b)
+            lines.append(a)
+        res = ""
+        for line in lines:
+            b = binascii.a2b_base64(line)
+            res = res + b
+        self.assertEqual(res, self.data)
+
+    def test_base64invalid(self):
+        # Test base64 with random invalid characters sprinkled throughout
+        # (This requires a new version of binascii.)
+        MAX_BASE64 = 57
+        lines = []
+        for i in range(0, len(self.data), MAX_BASE64):
+            b = self.data[i:i+MAX_BASE64]
+            a = binascii.b2a_base64(b)
+            lines.append(a)
+
+        fillers = ""
+        valid = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/"
+        for i in xrange(256):
+            c = chr(i)
+            if c not in valid:
+                fillers += c
+        def addnoise(line):
+            noise = fillers
+            ratio = len(line) // len(noise)
+            res = ""
+            while line and noise:
+                if len(line) // len(noise) > ratio:
+                    c, line = line[0], line[1:]
+                else:
+                    c, noise = noise[0], noise[1:]
+                res += c
+            return res + noise + line
+        res = ""
+        for line in map(addnoise, lines):
+            b = binascii.a2b_base64(line)
+            res += b
+        self.assertEqual(res, self.data)
+
+        # Test base64 with just invalid characters, which should return
+        # empty strings. TBD: shouldn't it raise an exception instead ?
+        self.assertEqual(binascii.a2b_base64(fillers), '')
+
+    def test_uu(self):
+        MAX_UU = 45
+        lines = []
+        for i in range(0, len(self.data), MAX_UU):
+            b = self.data[i:i+MAX_UU]
+            a = binascii.b2a_uu(b)
+            lines.append(a)
+        res = ""
+        for line in lines:
+            b = binascii.a2b_uu(line)
+            res += b
+        self.assertEqual(res, self.data)
+
+        self.assertEqual(binascii.a2b_uu("\x7f"), "\x00"*31)
+        self.assertEqual(binascii.a2b_uu("\x80"), "\x00"*32)
+        self.assertEqual(binascii.a2b_uu("\xff"), "\x00"*31)
+        self.assertRaises(binascii.Error, binascii.a2b_uu, "\xff\x00")
+        self.assertRaises(binascii.Error, binascii.a2b_uu, "!!!!")
+
+        self.assertRaises(binascii.Error, binascii.b2a_uu, 46*"!")
+
+    def test_crc32(self):
+        crc = binascii.crc32("Test the CRC-32 of")
+        crc = binascii.crc32(" this string.", crc)
+        self.assertEqual(crc, 1571220330)
+
+        self.assertRaises(TypeError, binascii.crc32)
+
+    # The hqx test is in test_binhex.py
+
+    def test_hex(self):
+        # test hexlification
+        s = '{s\005\000\000\000worldi\002\000\000\000s\005\000\000\000helloi\001\000\000\0000'
+        t = binascii.b2a_hex(s)
+        u = binascii.a2b_hex(t)
+        self.assertEqual(s, u)
+        self.assertRaises(TypeError, binascii.a2b_hex, t[:-1])
+        self.assertRaises(TypeError, binascii.a2b_hex, t[:-1] + 'q')
+
+        # Verify the treatment of Unicode strings
+        if test_support.have_unicode:
+            self.assertEqual(binascii.hexlify(unicode('a', 'ascii')), '61')
+
+    def test_qp(self):
+        # A test for SF bug 534347 (segfaults without the proper fix)
+        try:
+            binascii.a2b_qp("", **{1:1})
+        except TypeError:
+            pass
+        else:
+            self.fail("binascii.a2b_qp(**{1:1}) didn't raise TypeError")
+        self.assertEqual(binascii.a2b_qp("= "), "= ")
+        self.assertEqual(binascii.a2b_qp("=="), "=")
+        self.assertEqual(binascii.a2b_qp("=AX"), "=AX")
+        self.assertRaises(TypeError, binascii.b2a_qp, foo="bar")
+        self.assertEqual(binascii.a2b_qp("=00\r\n=00"), "\x00\r\n\x00")
+        self.assertEqual(
+            binascii.b2a_qp("\xff\r\n\xff\n\xff"),
+            "=FF\r\n=FF\r\n=FF"
+        )
+        self.assertEqual(
+            binascii.b2a_qp("0"*75+"\xff\r\n\xff\r\n\xff"),
+            "0"*75+"=\r\n=FF\r\n=FF\r\n=FF"
+        )
+
+    def test_empty_string(self):
+        # A test for SF bug #1022953.  Make sure SystemError is not raised.
+        for n in ['b2a_qp', 'a2b_hex', 'b2a_base64', 'a2b_uu', 'a2b_qp',
+                  'b2a_hex', 'unhexlify', 'hexlify', 'crc32', 'b2a_hqx',
+                  'a2b_hqx', 'a2b_base64', 'rlecode_hqx', 'b2a_uu',
+                  'rledecode_hqx']:
+            f = getattr(binascii, n)
+            f('')
+        binascii.crc_hqx('', 0)
+
+def test_main():
+    test_support.run_unittest(BinASCIITest)
+
+if __name__ == "__main__":
+    test_main()


Property changes on: vendor/Python/current/Lib/test/test_binascii.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/test/test_binhex.py
===================================================================
--- vendor/Python/current/Lib/test/test_binhex.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_binhex.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,49 @@
+#! /usr/bin/env python
+"""Test script for the binhex C module
+
+   Uses the mechanism of the python binhex module
+   Based on an original test by Roger E. Masse.
+"""
+import binhex
+import os
+import unittest
+from test import test_support
+
+
+class BinHexTestCase(unittest.TestCase):
+
+    def setUp(self):
+        self.fname1 = test_support.TESTFN + "1"
+        self.fname2 = test_support.TESTFN + "2"
+
+    def tearDown(self):
+        try: os.unlink(self.fname1)
+        except OSError: pass
+
+        try: os.unlink(self.fname2)
+        except OSError: pass
+
+    DATA = 'Jack is my hero'
+
+    def test_binhex(self):
+        f = open(self.fname1, 'w')
+        f.write(self.DATA)
+        f.close()
+
+        binhex.binhex(self.fname1, self.fname2)
+
+        binhex.hexbin(self.fname2, self.fname1)
+
+        f = open(self.fname1, 'r')
+        finish = f.readline()
+        f.close()
+
+        self.assertEqual(self.DATA, finish)
+
+
+def test_main():
+    test_support.run_unittest(BinHexTestCase)
+
+
+if __name__ == "__main__":
+    test_main()


Property changes on: vendor/Python/current/Lib/test/test_binhex.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/test/test_binop.py
===================================================================
--- vendor/Python/current/Lib/test/test_binop.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_binop.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,328 @@
+"""Tests for binary operators on subtypes of built-in types."""
+
+import unittest
+from test import test_support
+
+def gcd(a, b):
+    """Greatest common divisor using Euclid's algorithm."""
+    while a:
+        a, b = b%a, a
+    return b
+
+def isint(x):
+    """Test whether an object is an instance of int or long."""
+    return isinstance(x, int) or isinstance(x, long)
+
+def isnum(x):
+    """Test whether an object is an instance of a built-in numeric type."""
+    for T in int, long, float, complex:
+        if isinstance(x, T):
+            return 1
+    return 0
+
+def isRat(x):
+    """Test wheter an object is an instance of the Rat class."""
+    return isinstance(x, Rat)
+
+class Rat(object):
+
+    """Rational number implemented as a normalized pair of longs."""
+
+    __slots__ = ['_Rat__num', '_Rat__den']
+
+    def __init__(self, num=0L, den=1L):
+        """Constructor: Rat([num[, den]]).
+
+        The arguments must be ints or longs, and default to (0, 1)."""
+        if not isint(num):
+            raise TypeError, "Rat numerator must be int or long (%r)" % num
+        if not isint(den):
+            raise TypeError, "Rat denominator must be int or long (%r)" % den
+        # But the zero is always on
+        if den == 0:
+            raise ZeroDivisionError, "zero denominator"
+        g = gcd(den, num)
+        self.__num = long(num//g)
+        self.__den = long(den//g)
+
+    def _get_num(self):
+        """Accessor function for read-only 'num' attribute of Rat."""
+        return self.__num
+    num = property(_get_num, None)
+
+    def _get_den(self):
+        """Accessor function for read-only 'den' attribute of Rat."""
+        return self.__den
+    den = property(_get_den, None)
+
+    def __repr__(self):
+        """Convert a Rat to an string resembling a Rat constructor call."""
+        return "Rat(%d, %d)" % (self.__num, self.__den)
+
+    def __str__(self):
+        """Convert a Rat to a string resembling a decimal numeric value."""
+        return str(float(self))
+
+    def __float__(self):
+        """Convert a Rat to a float."""
+        return self.__num*1.0/self.__den
+
+    def __int__(self):
+        """Convert a Rat to an int; self.den must be 1."""
+        if self.__den == 1:
+            try:
+                return int(self.__num)
+            except OverflowError:
+                raise OverflowError, ("%s too large to convert to int" %
+                                      repr(self))
+        raise ValueError, "can't convert %s to int" % repr(self)
+
+    def __long__(self):
+        """Convert a Rat to an long; self.den must be 1."""
+        if self.__den == 1:
+            return long(self.__num)
+        raise ValueError, "can't convert %s to long" % repr(self)
+
+    def __add__(self, other):
+        """Add two Rats, or a Rat and a number."""
+        if isint(other):
+            other = Rat(other)
+        if isRat(other):
+            return Rat(self.__num*other.__den + other.__num*self.__den,
+                       self.__den*other.__den)
+        if isnum(other):
+            return float(self) + other
+        return NotImplemented
+
+    __radd__ = __add__
+
+    def __sub__(self, other):
+        """Subtract two Rats, or a Rat and a number."""
+        if isint(other):
+            other = Rat(other)
+        if isRat(other):
+            return Rat(self.__num*other.__den - other.__num*self.__den,
+                       self.__den*other.__den)
+        if isnum(other):
+            return float(self) - other
+        return NotImplemented
+
+    def __rsub__(self, other):
+        """Subtract two Rats, or a Rat and a number (reversed args)."""
+        if isint(other):
+            other = Rat(other)
+        if isRat(other):
+            return Rat(other.__num*self.__den - self.__num*other.__den,
+                       self.__den*other.__den)
+        if isnum(other):
+            return other - float(self)
+        return NotImplemented
+
+    def __mul__(self, other):
+        """Multiply two Rats, or a Rat and a number."""
+        if isRat(other):
+            return Rat(self.__num*other.__num, self.__den*other.__den)
+        if isint(other):
+            return Rat(self.__num*other, self.__den)
+        if isnum(other):
+            return float(self)*other
+        return NotImplemented
+
+    __rmul__ = __mul__
+
+    def __truediv__(self, other):
+        """Divide two Rats, or a Rat and a number."""
+        if isRat(other):
+            return Rat(self.__num*other.__den, self.__den*other.__num)
+        if isint(other):
+            return Rat(self.__num, self.__den*other)
+        if isnum(other):
+            return float(self) / other
+        return NotImplemented
+
+    __div__ = __truediv__
+
+    def __rtruediv__(self, other):
+        """Divide two Rats, or a Rat and a number (reversed args)."""
+        if isRat(other):
+            return Rat(other.__num*self.__den, other.__den*self.__num)
+        if isint(other):
+            return Rat(other*self.__den, self.__num)
+        if isnum(other):
+            return other / float(self)
+        return NotImplemented
+
+    __rdiv__ = __rtruediv__
+
+    def __floordiv__(self, other):
+        """Divide two Rats, returning the floored result."""
+        if isint(other):
+            other = Rat(other)
+        elif not isRat(other):
+            return NotImplemented
+        x = self/other
+        return x.__num // x.__den
+
+    def __rfloordiv__(self, other):
+        """Divide two Rats, returning the floored result (reversed args)."""
+        x = other/self
+        return x.__num // x.__den
+
+    def __divmod__(self, other):
+        """Divide two Rats, returning quotient and remainder."""
+        if isint(other):
+            other = Rat(other)
+        elif not isRat(other):
+            return NotImplemented
+        x = self//other
+        return (x, self - other * x)
+
+    def __rdivmod__(self, other):
+        """Divide two Rats, returning quotient and remainder (reversed args)."""
+        if isint(other):
+            other = Rat(other)
+        elif not isRat(other):
+            return NotImplemented
+        return divmod(other, self)
+
+    def __mod__(self, other):
+        """Take one Rat modulo another."""
+        return divmod(self, other)[1]
+
+    def __rmod__(self, other):
+        """Take one Rat modulo another (reversed args)."""
+        return divmod(other, self)[1]
+
+    def __eq__(self, other):
+        """Compare two Rats for equality."""
+        if isint(other):
+            return self.__den == 1 and self.__num == other
+        if isRat(other):
+            return self.__num == other.__num and self.__den == other.__den
+        if isnum(other):
+            return float(self) == other
+        return NotImplemented
+
+    def __ne__(self, other):
+        """Compare two Rats for inequality."""
+        return not self == other
+
+class RatTestCase(unittest.TestCase):
+    """Unit tests for Rat class and its support utilities."""
+
+    def test_gcd(self):
+        self.assertEqual(gcd(10, 12), 2)
+        self.assertEqual(gcd(10, 15), 5)
+        self.assertEqual(gcd(10, 11), 1)
+        self.assertEqual(gcd(100, 15), 5)
+        self.assertEqual(gcd(-10, 2), -2)
+        self.assertEqual(gcd(10, -2), 2)
+        self.assertEqual(gcd(-10, -2), -2)
+        for i in range(1, 20):
+            for j in range(1, 20):
+                self.assert_(gcd(i, j) > 0)
+                self.assert_(gcd(-i, j) < 0)
+                self.assert_(gcd(i, -j) > 0)
+                self.assert_(gcd(-i, -j) < 0)
+
+    def test_constructor(self):
+        a = Rat(10, 15)
+        self.assertEqual(a.num, 2)
+        self.assertEqual(a.den, 3)
+        a = Rat(10L, 15L)
+        self.assertEqual(a.num, 2)
+        self.assertEqual(a.den, 3)
+        a = Rat(10, -15)
+        self.assertEqual(a.num, -2)
+        self.assertEqual(a.den, 3)
+        a = Rat(-10, 15)
+        self.assertEqual(a.num, -2)
+        self.assertEqual(a.den, 3)
+        a = Rat(-10, -15)
+        self.assertEqual(a.num, 2)
+        self.assertEqual(a.den, 3)
+        a = Rat(7)
+        self.assertEqual(a.num, 7)
+        self.assertEqual(a.den, 1)
+        try:
+            a = Rat(1, 0)
+        except ZeroDivisionError:
+            pass
+        else:
+            self.fail("Rat(1, 0) didn't raise ZeroDivisionError")
+        for bad in "0", 0.0, 0j, (), [], {}, None, Rat, unittest:
+            try:
+                a = Rat(bad)
+            except TypeError:
+                pass
+            else:
+                self.fail("Rat(%r) didn't raise TypeError" % bad)
+            try:
+                a = Rat(1, bad)
+            except TypeError:
+                pass
+            else:
+                self.fail("Rat(1, %r) didn't raise TypeError" % bad)
+
+    def test_add(self):
+        self.assertEqual(Rat(2, 3) + Rat(1, 3), 1)
+        self.assertEqual(Rat(2, 3) + 1, Rat(5, 3))
+        self.assertEqual(1 + Rat(2, 3), Rat(5, 3))
+        self.assertEqual(1.0 + Rat(1, 2), 1.5)
+        self.assertEqual(Rat(1, 2) + 1.0, 1.5)
+
+    def test_sub(self):
+        self.assertEqual(Rat(7, 2) - Rat(7, 5), Rat(21, 10))
+        self.assertEqual(Rat(7, 5) - 1, Rat(2, 5))
+        self.assertEqual(1 - Rat(3, 5), Rat(2, 5))
+        self.assertEqual(Rat(3, 2) - 1.0, 0.5)
+        self.assertEqual(1.0 - Rat(1, 2), 0.5)
+
+    def test_mul(self):
+        self.assertEqual(Rat(2, 3) * Rat(5, 7), Rat(10, 21))
+        self.assertEqual(Rat(10, 3) * 3, 10)
+        self.assertEqual(3 * Rat(10, 3), 10)
+        self.assertEqual(Rat(10, 5) * 0.5, 1.0)
+        self.assertEqual(0.5 * Rat(10, 5), 1.0)
+
+    def test_div(self):
+        self.assertEqual(Rat(10, 3) / Rat(5, 7), Rat(14, 3))
+        self.assertEqual(Rat(10, 3) / 3, Rat(10, 9))
+        self.assertEqual(2 / Rat(5), Rat(2, 5))
+        self.assertEqual(3.0 * Rat(1, 2), 1.5)
+        self.assertEqual(Rat(1, 2) * 3.0, 1.5)
+
+    def test_floordiv(self):
+        self.assertEqual(Rat(10) // Rat(4), 2)
+        self.assertEqual(Rat(10, 3) // Rat(4, 3), 2)
+        self.assertEqual(Rat(10) // 4, 2)
+        self.assertEqual(10 // Rat(4), 2)
+
+    def test_eq(self):
+        self.assertEqual(Rat(10), Rat(20, 2))
+        self.assertEqual(Rat(10), 10)
+        self.assertEqual(10, Rat(10))
+        self.assertEqual(Rat(10), 10.0)
+        self.assertEqual(10.0, Rat(10))
+
+    def test_future_div(self):
+        exec future_test
+
+    # XXX Ran out of steam; TO DO: divmod, div, future division
+
+future_test = """
+from __future__ import division
+self.assertEqual(Rat(10, 3) / Rat(5, 7), Rat(14, 3))
+self.assertEqual(Rat(10, 3) / 3, Rat(10, 9))
+self.assertEqual(2 / Rat(5), Rat(2, 5))
+self.assertEqual(3.0 * Rat(1, 2), 1.5)
+self.assertEqual(Rat(1, 2) * 3.0, 1.5)
+self.assertEqual(eval('1/2'), 0.5)
+"""
+
+def test_main():
+    test_support.run_unittest(RatTestCase)
+
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_bisect.py
===================================================================
--- vendor/Python/current/Lib/test/test_bisect.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_bisect.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,253 @@
+import unittest
+from test import test_support
+from bisect import bisect_right, bisect_left, insort_left, insort_right, insort, bisect
+from UserList import UserList
+
+class TestBisect(unittest.TestCase):
+
+    precomputedCases = [
+        (bisect_right, [], 1, 0),
+        (bisect_right, [1], 0, 0),
+        (bisect_right, [1], 1, 1),
+        (bisect_right, [1], 2, 1),
+        (bisect_right, [1, 1], 0, 0),
+        (bisect_right, [1, 1], 1, 2),
+        (bisect_right, [1, 1], 2, 2),
+        (bisect_right, [1, 1, 1], 0, 0),
+        (bisect_right, [1, 1, 1], 1, 3),
+        (bisect_right, [1, 1, 1], 2, 3),
+        (bisect_right, [1, 1, 1, 1], 0, 0),
+        (bisect_right, [1, 1, 1, 1], 1, 4),
+        (bisect_right, [1, 1, 1, 1], 2, 4),
+        (bisect_right, [1, 2], 0, 0),
+        (bisect_right, [1, 2], 1, 1),
+        (bisect_right, [1, 2], 1.5, 1),
+        (bisect_right, [1, 2], 2, 2),
+        (bisect_right, [1, 2], 3, 2),
+        (bisect_right, [1, 1, 2, 2], 0, 0),
+        (bisect_right, [1, 1, 2, 2], 1, 2),
+        (bisect_right, [1, 1, 2, 2], 1.5, 2),
+        (bisect_right, [1, 1, 2, 2], 2, 4),
+        (bisect_right, [1, 1, 2, 2], 3, 4),
+        (bisect_right, [1, 2, 3], 0, 0),
+        (bisect_right, [1, 2, 3], 1, 1),
+        (bisect_right, [1, 2, 3], 1.5, 1),
+        (bisect_right, [1, 2, 3], 2, 2),
+        (bisect_right, [1, 2, 3], 2.5, 2),
+        (bisect_right, [1, 2, 3], 3, 3),
+        (bisect_right, [1, 2, 3], 4, 3),
+        (bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 0, 0),
+        (bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 1, 1),
+        (bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 1.5, 1),
+        (bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 2, 3),
+        (bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 2.5, 3),
+        (bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 3, 6),
+        (bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 3.5, 6),
+        (bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 4, 10),
+        (bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 5, 10),
+
+        (bisect_left, [], 1, 0),
+        (bisect_left, [1], 0, 0),
+        (bisect_left, [1], 1, 0),
+        (bisect_left, [1], 2, 1),
+        (bisect_left, [1, 1], 0, 0),
+        (bisect_left, [1, 1], 1, 0),
+        (bisect_left, [1, 1], 2, 2),
+        (bisect_left, [1, 1, 1], 0, 0),
+        (bisect_left, [1, 1, 1], 1, 0),
+        (bisect_left, [1, 1, 1], 2, 3),
+        (bisect_left, [1, 1, 1, 1], 0, 0),
+        (bisect_left, [1, 1, 1, 1], 1, 0),
+        (bisect_left, [1, 1, 1, 1], 2, 4),
+        (bisect_left, [1, 2], 0, 0),
+        (bisect_left, [1, 2], 1, 0),
+        (bisect_left, [1, 2], 1.5, 1),
+        (bisect_left, [1, 2], 2, 1),
+        (bisect_left, [1, 2], 3, 2),
+        (bisect_left, [1, 1, 2, 2], 0, 0),
+        (bisect_left, [1, 1, 2, 2], 1, 0),
+        (bisect_left, [1, 1, 2, 2], 1.5, 2),
+        (bisect_left, [1, 1, 2, 2], 2, 2),
+        (bisect_left, [1, 1, 2, 2], 3, 4),
+        (bisect_left, [1, 2, 3], 0, 0),
+        (bisect_left, [1, 2, 3], 1, 0),
+        (bisect_left, [1, 2, 3], 1.5, 1),
+        (bisect_left, [1, 2, 3], 2, 1),
+        (bisect_left, [1, 2, 3], 2.5, 2),
+        (bisect_left, [1, 2, 3], 3, 2),
+        (bisect_left, [1, 2, 3], 4, 3),
+        (bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 0, 0),
+        (bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 1, 0),
+        (bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 1.5, 1),
+        (bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 2, 1),
+        (bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 2.5, 3),
+        (bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 3, 3),
+        (bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 3.5, 6),
+        (bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 4, 6),
+        (bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 5, 10)
+    ]
+
+    def test_precomputed(self):
+        for func, data, elem, expected in self.precomputedCases:
+            self.assertEqual(func(data, elem), expected)
+            self.assertEqual(func(UserList(data), elem), expected)
+
+    def test_random(self, n=25):
+        from random import randrange
+        for i in xrange(n):
+            data = [randrange(0, n, 2) for j in xrange(i)]
+            data.sort()
+            elem = randrange(-1, n+1)
+            ip = bisect_left(data, elem)
+            if ip < len(data):
+                self.failUnless(elem <= data[ip])
+            if ip > 0:
+                self.failUnless(data[ip-1] < elem)
+            ip = bisect_right(data, elem)
+            if ip < len(data):
+                self.failUnless(elem < data[ip])
+            if ip > 0:
+                self.failUnless(data[ip-1] <= elem)
+
+    def test_optionalSlicing(self):
+        for func, data, elem, expected in self.precomputedCases:
+            for lo in xrange(4):
+                lo = min(len(data), lo)
+                for hi in xrange(3,8):
+                    hi = min(len(data), hi)
+                    ip = func(data, elem, lo, hi)
+                    self.failUnless(lo <= ip <= hi)
+                    if func is bisect_left and ip < hi:
+                        self.failUnless(elem <= data[ip])
+                    if func is bisect_left and ip > lo:
+                        self.failUnless(data[ip-1] < elem)
+                    if func is bisect_right and ip < hi:
+                        self.failUnless(elem < data[ip])
+                    if func is bisect_right and ip > lo:
+                        self.failUnless(data[ip-1] <= elem)
+                    self.assertEqual(ip, max(lo, min(hi, expected)))
+
+    def test_backcompatibility(self):
+        self.assertEqual(bisect, bisect_right)
+
+    def test_keyword_args(self):
+        data = [10, 20, 30, 40, 50]
+        self.assertEqual(bisect_left(a=data, x=25, lo=1, hi=3), 2)
+        self.assertEqual(bisect_right(a=data, x=25, lo=1, hi=3), 2)
+        self.assertEqual(bisect(a=data, x=25, lo=1, hi=3), 2)
+        insort_left(a=data, x=25, lo=1, hi=3)
+        insort_right(a=data, x=25, lo=1, hi=3)
+        insort(a=data, x=25, lo=1, hi=3)
+        self.assertEqual(data, [10, 20, 25, 25, 25, 30, 40, 50])
+
+#==============================================================================
+
+class TestInsort(unittest.TestCase):
+
+    def test_vsBuiltinSort(self, n=500):
+        from random import choice
+        for insorted in (list(), UserList()):
+            for i in xrange(n):
+                digit = choice("0123456789")
+                if digit in "02468":
+                    f = insort_left
+                else:
+                    f = insort_right
+                f(insorted, digit)
+        self.assertEqual(sorted(insorted), insorted)
+
+    def test_backcompatibility(self):
+        self.assertEqual(insort, insort_right)
+
+#==============================================================================
+
+
+class LenOnly:
+    "Dummy sequence class defining __len__ but not __getitem__."
+    def __len__(self):
+        return 10
+
+class GetOnly:
+    "Dummy sequence class defining __getitem__ but not __len__."
+    def __getitem__(self, ndx):
+        return 10
+
+class CmpErr:
+    "Dummy element that always raises an error during comparison"
+    def __cmp__(self, other):
+        raise ZeroDivisionError
+
+class TestErrorHandling(unittest.TestCase):
+
+    def test_non_sequence(self):
+        for f in (bisect_left, bisect_right, insort_left, insort_right):
+            self.assertRaises(TypeError, f, 10, 10)
+
+    def test_len_only(self):
+        for f in (bisect_left, bisect_right, insort_left, insort_right):
+            self.assertRaises(AttributeError, f, LenOnly(), 10)
+
+    def test_get_only(self):
+        for f in (bisect_left, bisect_right, insort_left, insort_right):
+            self.assertRaises(AttributeError, f, GetOnly(), 10)
+
+    def test_cmp_err(self):
+        seq = [CmpErr(), CmpErr(), CmpErr()]
+        for f in (bisect_left, bisect_right, insort_left, insort_right):
+            self.assertRaises(ZeroDivisionError, f, seq, 10)
+
+    def test_arg_parsing(self):
+        for f in (bisect_left, bisect_right, insort_left, insort_right):
+            self.assertRaises(TypeError, f, 10)
+
+#==============================================================================
+
+libreftest = """
+Example from the Library Reference:  Doc/lib/libbisect.tex
+
+The bisect() function is generally useful for categorizing numeric data.
+This example uses bisect() to look up a letter grade for an exam total
+(say) based on a set of ordered numeric breakpoints: 85 and up is an `A',
+75..84 is a `B', etc.
+
+    >>> grades = "FEDCBA"
+    >>> breakpoints = [30, 44, 66, 75, 85]
+    >>> from bisect import bisect
+    >>> def grade(total):
+    ...           return grades[bisect(breakpoints, total)]
+    ...
+    >>> grade(66)
+    'C'
+    >>> map(grade, [33, 99, 77, 44, 12, 88])
+    ['E', 'A', 'B', 'D', 'F', 'A']
+
+"""
+
+#------------------------------------------------------------------------------
+
+__test__ = {'libreftest' : libreftest}
+
+def test_main(verbose=None):
+    from test import test_bisect
+    from types import BuiltinFunctionType
+    import sys
+
+    test_classes = [TestBisect, TestInsort]
+    if isinstance(bisect_left, BuiltinFunctionType):
+        test_classes.append(TestErrorHandling)
+
+    test_support.run_unittest(*test_classes)
+    test_support.run_doctest(test_bisect, verbose)
+
+    # verify reference counting
+    if verbose and hasattr(sys, "gettotalrefcount"):
+        import gc
+        counts = [None] * 5
+        for i in xrange(len(counts)):
+            test_support.run_unittest(*test_classes)
+            gc.collect()
+            counts[i] = sys.gettotalrefcount()
+        print counts
+
+if __name__ == "__main__":
+    test_main(verbose=True)

Added: vendor/Python/current/Lib/test/test_bool.py
===================================================================
--- vendor/Python/current/Lib/test/test_bool.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_bool.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,348 @@
+# Test properties of bool promised by PEP 285
+
+import unittest
+from test import test_support
+
+import os
+
+class BoolTest(unittest.TestCase):
+
+    def assertIs(self, a, b):
+        self.assert_(a is b)
+
+    def assertIsNot(self, a, b):
+        self.assert_(a is not b)
+
+    def test_subclass(self):
+        try:
+            class C(bool):
+                pass
+        except TypeError:
+            pass
+        else:
+            self.fail("bool should not be subclassable")
+
+        self.assertRaises(TypeError, int.__new__, bool, 0)
+
+    def test_print(self):
+        try:
+            fo = open(test_support.TESTFN, "wb")
+            print >> fo, False, True
+            fo.close()
+            fo = open(test_support.TESTFN, "rb")
+            self.assertEqual(fo.read(), 'False True\n')
+        finally:
+            fo.close()
+            os.remove(test_support.TESTFN)
+
+    def test_repr(self):
+        self.assertEqual(repr(False), 'False')
+        self.assertEqual(repr(True), 'True')
+        self.assertEqual(eval(repr(False)), False)
+        self.assertEqual(eval(repr(True)), True)
+
+    def test_str(self):
+        self.assertEqual(str(False), 'False')
+        self.assertEqual(str(True), 'True')
+
+    def test_int(self):
+        self.assertEqual(int(False), 0)
+        self.assertIsNot(int(False), False)
+        self.assertEqual(int(True), 1)
+        self.assertIsNot(int(True), True)
+
+    def test_math(self):
+        self.assertEqual(+False, 0)
+        self.assertIsNot(+False, False)
+        self.assertEqual(-False, 0)
+        self.assertIsNot(-False, False)
+        self.assertEqual(abs(False), 0)
+        self.assertIsNot(abs(False), False)
+        self.assertEqual(+True, 1)
+        self.assertIsNot(+True, True)
+        self.assertEqual(-True, -1)
+        self.assertEqual(abs(True), 1)
+        self.assertIsNot(abs(True), True)
+        self.assertEqual(~False, -1)
+        self.assertEqual(~True, -2)
+
+        self.assertEqual(False+2, 2)
+        self.assertEqual(True+2, 3)
+        self.assertEqual(2+False, 2)
+        self.assertEqual(2+True, 3)
+
+        self.assertEqual(False+False, 0)
+        self.assertIsNot(False+False, False)
+        self.assertEqual(False+True, 1)
+        self.assertIsNot(False+True, True)
+        self.assertEqual(True+False, 1)
+        self.assertIsNot(True+False, True)
+        self.assertEqual(True+True, 2)
+
+        self.assertEqual(True-True, 0)
+        self.assertIsNot(True-True, False)
+        self.assertEqual(False-False, 0)
+        self.assertIsNot(False-False, False)
+        self.assertEqual(True-False, 1)
+        self.assertIsNot(True-False, True)
+        self.assertEqual(False-True, -1)
+
+        self.assertEqual(True*1, 1)
+        self.assertEqual(False*1, 0)
+        self.assertIsNot(False*1, False)
+
+        self.assertEqual(True/1, 1)
+        self.assertIsNot(True/1, True)
+        self.assertEqual(False/1, 0)
+        self.assertIsNot(False/1, False)
+
+        for b in False, True:
+            for i in 0, 1, 2:
+                self.assertEqual(b**i, int(b)**i)
+                self.assertIsNot(b**i, bool(int(b)**i))
+
+        for a in False, True:
+            for b in False, True:
+                self.assertIs(a&b, bool(int(a)&int(b)))
+                self.assertIs(a|b, bool(int(a)|int(b)))
+                self.assertIs(a^b, bool(int(a)^int(b)))
+                self.assertEqual(a&int(b), int(a)&int(b))
+                self.assertIsNot(a&int(b), bool(int(a)&int(b)))
+                self.assertEqual(a|int(b), int(a)|int(b))
+                self.assertIsNot(a|int(b), bool(int(a)|int(b)))
+                self.assertEqual(a^int(b), int(a)^int(b))
+                self.assertIsNot(a^int(b), bool(int(a)^int(b)))
+                self.assertEqual(int(a)&b, int(a)&int(b))
+                self.assertIsNot(int(a)&b, bool(int(a)&int(b)))
+                self.assertEqual(int(a)|b, int(a)|int(b))
+                self.assertIsNot(int(a)|b, bool(int(a)|int(b)))
+                self.assertEqual(int(a)^b, int(a)^int(b))
+                self.assertIsNot(int(a)^b, bool(int(a)^int(b)))
+
+        self.assertIs(1==1, True)
+        self.assertIs(1==0, False)
+        self.assertIs(0<1, True)
+        self.assertIs(1<0, False)
+        self.assertIs(0<=0, True)
+        self.assertIs(1<=0, False)
+        self.assertIs(1>0, True)
+        self.assertIs(1>1, False)
+        self.assertIs(1>=1, True)
+        self.assertIs(0>=1, False)
+        self.assertIs(0!=1, True)
+        self.assertIs(0!=0, False)
+
+        x = [1]
+        self.assertIs(x is x, True)
+        self.assertIs(x is not x, False)
+
+        self.assertIs(1 in x, True)
+        self.assertIs(0 in x, False)
+        self.assertIs(1 not in x, False)
+        self.assertIs(0 not in x, True)
+
+        x = {1: 2}
+        self.assertIs(x is x, True)
+        self.assertIs(x is not x, False)
+
+        self.assertIs(1 in x, True)
+        self.assertIs(0 in x, False)
+        self.assertIs(1 not in x, False)
+        self.assertIs(0 not in x, True)
+
+        self.assertIs(not True, False)
+        self.assertIs(not False, True)
+
+    def test_convert(self):
+        self.assertRaises(TypeError, bool, 42, 42)
+        self.assertIs(bool(10), True)
+        self.assertIs(bool(1), True)
+        self.assertIs(bool(-1), True)
+        self.assertIs(bool(0), False)
+        self.assertIs(bool("hello"), True)
+        self.assertIs(bool(""), False)
+        self.assertIs(bool(), False)
+
+    def test_hasattr(self):
+        self.assertIs(hasattr([], "append"), True)
+        self.assertIs(hasattr([], "wobble"), False)
+
+    def test_callable(self):
+        self.assertIs(callable(len), True)
+        self.assertIs(callable(1), False)
+
+    def test_isinstance(self):
+        self.assertIs(isinstance(True, bool), True)
+        self.assertIs(isinstance(False, bool), True)
+        self.assertIs(isinstance(True, int), True)
+        self.assertIs(isinstance(False, int), True)
+        self.assertIs(isinstance(1, bool), False)
+        self.assertIs(isinstance(0, bool), False)
+
+    def test_issubclass(self):
+        self.assertIs(issubclass(bool, int), True)
+        self.assertIs(issubclass(int, bool), False)
+
+    def test_haskey(self):
+        self.assertIs({}.has_key(1), False)
+        self.assertIs({1:1}.has_key(1), True)
+
+    def test_string(self):
+        self.assertIs("xyz".endswith("z"), True)
+        self.assertIs("xyz".endswith("x"), False)
+        self.assertIs("xyz0123".isalnum(), True)
+        self.assertIs("@#$%".isalnum(), False)
+        self.assertIs("xyz".isalpha(), True)
+        self.assertIs("@#$%".isalpha(), False)
+        self.assertIs("0123".isdigit(), True)
+        self.assertIs("xyz".isdigit(), False)
+        self.assertIs("xyz".islower(), True)
+        self.assertIs("XYZ".islower(), False)
+        self.assertIs(" ".isspace(), True)
+        self.assertIs("XYZ".isspace(), False)
+        self.assertIs("X".istitle(), True)
+        self.assertIs("x".istitle(), False)
+        self.assertIs("XYZ".isupper(), True)
+        self.assertIs("xyz".isupper(), False)
+        self.assertIs("xyz".startswith("x"), True)
+        self.assertIs("xyz".startswith("z"), False)
+
+        if test_support.have_unicode:
+            self.assertIs(unicode("xyz", 'ascii').endswith(unicode("z", 'ascii')), True)
+            self.assertIs(unicode("xyz", 'ascii').endswith(unicode("x", 'ascii')), False)
+            self.assertIs(unicode("xyz0123", 'ascii').isalnum(), True)
+            self.assertIs(unicode("@#$%", 'ascii').isalnum(), False)
+            self.assertIs(unicode("xyz", 'ascii').isalpha(), True)
+            self.assertIs(unicode("@#$%", 'ascii').isalpha(), False)
+            self.assertIs(unicode("0123", 'ascii').isdecimal(), True)
+            self.assertIs(unicode("xyz", 'ascii').isdecimal(), False)
+            self.assertIs(unicode("0123", 'ascii').isdigit(), True)
+            self.assertIs(unicode("xyz", 'ascii').isdigit(), False)
+            self.assertIs(unicode("xyz", 'ascii').islower(), True)
+            self.assertIs(unicode("XYZ", 'ascii').islower(), False)
+            self.assertIs(unicode("0123", 'ascii').isnumeric(), True)
+            self.assertIs(unicode("xyz", 'ascii').isnumeric(), False)
+            self.assertIs(unicode(" ", 'ascii').isspace(), True)
+            self.assertIs(unicode("XYZ", 'ascii').isspace(), False)
+            self.assertIs(unicode("X", 'ascii').istitle(), True)
+            self.assertIs(unicode("x", 'ascii').istitle(), False)
+            self.assertIs(unicode("XYZ", 'ascii').isupper(), True)
+            self.assertIs(unicode("xyz", 'ascii').isupper(), False)
+            self.assertIs(unicode("xyz", 'ascii').startswith(unicode("x", 'ascii')), True)
+            self.assertIs(unicode("xyz", 'ascii').startswith(unicode("z", 'ascii')), False)
+
+    def test_boolean(self):
+        self.assertEqual(True & 1, 1)
+        self.assert_(not isinstance(True & 1, bool))
+        self.assertIs(True & True, True)
+
+        self.assertEqual(True | 1, 1)
+        self.assert_(not isinstance(True | 1, bool))
+        self.assertIs(True | True, True)
+
+        self.assertEqual(True ^ 1, 0)
+        self.assert_(not isinstance(True ^ 1, bool))
+        self.assertIs(True ^ True, False)
+
+    def test_fileclosed(self):
+        try:
+            f = file(test_support.TESTFN, "w")
+            self.assertIs(f.closed, False)
+            f.close()
+            self.assertIs(f.closed, True)
+        finally:
+            os.remove(test_support.TESTFN)
+
+    def test_operator(self):
+        import operator
+        self.assertIs(operator.truth(0), False)
+        self.assertIs(operator.truth(1), True)
+        self.assertIs(operator.isCallable(0), False)
+        self.assertIs(operator.isCallable(len), True)
+        self.assertIs(operator.isNumberType(None), False)
+        self.assertIs(operator.isNumberType(0), True)
+        self.assertIs(operator.not_(1), False)
+        self.assertIs(operator.not_(0), True)
+        self.assertIs(operator.isSequenceType(0), False)
+        self.assertIs(operator.isSequenceType([]), True)
+        self.assertIs(operator.contains([], 1), False)
+        self.assertIs(operator.contains([1], 1), True)
+        self.assertIs(operator.isMappingType(1), False)
+        self.assertIs(operator.isMappingType({}), True)
+        self.assertIs(operator.lt(0, 0), False)
+        self.assertIs(operator.lt(0, 1), True)
+        self.assertIs(operator.is_(True, True), True)
+        self.assertIs(operator.is_(True, False), False)
+        self.assertIs(operator.is_not(True, True), False)
+        self.assertIs(operator.is_not(True, False), True)
+
+    def test_marshal(self):
+        import marshal
+        self.assertIs(marshal.loads(marshal.dumps(True)), True)
+        self.assertIs(marshal.loads(marshal.dumps(False)), False)
+
+    def test_pickle(self):
+        import pickle
+        self.assertIs(pickle.loads(pickle.dumps(True)), True)
+        self.assertIs(pickle.loads(pickle.dumps(False)), False)
+        self.assertIs(pickle.loads(pickle.dumps(True, True)), True)
+        self.assertIs(pickle.loads(pickle.dumps(False, True)), False)
+
+    def test_cpickle(self):
+        import cPickle
+        self.assertIs(cPickle.loads(cPickle.dumps(True)), True)
+        self.assertIs(cPickle.loads(cPickle.dumps(False)), False)
+        self.assertIs(cPickle.loads(cPickle.dumps(True, True)), True)
+        self.assertIs(cPickle.loads(cPickle.dumps(False, True)), False)
+
+    def test_mixedpickle(self):
+        import pickle, cPickle
+        self.assertIs(pickle.loads(cPickle.dumps(True)), True)
+        self.assertIs(pickle.loads(cPickle.dumps(False)), False)
+        self.assertIs(pickle.loads(cPickle.dumps(True, True)), True)
+        self.assertIs(pickle.loads(cPickle.dumps(False, True)), False)
+
+        self.assertIs(cPickle.loads(pickle.dumps(True)), True)
+        self.assertIs(cPickle.loads(pickle.dumps(False)), False)
+        self.assertIs(cPickle.loads(pickle.dumps(True, True)), True)
+        self.assertIs(cPickle.loads(pickle.dumps(False, True)), False)
+
+    def test_picklevalues(self):
+        import pickle, cPickle
+
+        # Test for specific backwards-compatible pickle values
+        self.assertEqual(pickle.dumps(True), "I01\n.")
+        self.assertEqual(pickle.dumps(False), "I00\n.")
+        self.assertEqual(cPickle.dumps(True), "I01\n.")
+        self.assertEqual(cPickle.dumps(False), "I00\n.")
+        self.assertEqual(pickle.dumps(True, True), "I01\n.")
+        self.assertEqual(pickle.dumps(False, True), "I00\n.")
+        self.assertEqual(cPickle.dumps(True, True), "I01\n.")
+        self.assertEqual(cPickle.dumps(False, True), "I00\n.")
+
+    def test_convert_to_bool(self):
+        # Verify that TypeError occurs when bad things are returned
+        # from __nonzero__().  This isn't really a bool test, but
+        # it's related.
+        check = lambda o: self.assertRaises(TypeError, bool, o)
+        class Foo(object):
+            def __nonzero__(self):
+                return self
+        check(Foo())
+
+        class Bar(object):
+            def __nonzero__(self):
+                return "Yes"
+        check(Bar())
+
+        class Baz(int):
+            def __nonzero__(self):
+                return self
+        check(Baz())
+
+
+def test_main():
+    test_support.run_unittest(BoolTest)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_bsddb.py
===================================================================
--- vendor/Python/current/Lib/test/test_bsddb.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_bsddb.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,297 @@
+#! /usr/bin/env python
+"""Test script for the bsddb C module by Roger E. Masse
+   Adapted to unittest format and expanded scope by Raymond Hettinger
+"""
+import os, sys
+import copy
+import bsddb
+import dbhash # Just so we know it's imported
+import unittest
+from test import test_support
+
+class TestBSDDB(unittest.TestCase):
+    openflag = 'c'
+
+    def setUp(self):
+        self.f = self.openmethod[0](self.fname, self.openflag, cachesize=32768)
+        self.d = dict(q='Guido', w='van', e='Rossum', r='invented', t='Python', y='')
+        for k, v in self.d.iteritems():
+            self.f[k] = v
+
+    def tearDown(self):
+        self.f.sync()
+        self.f.close()
+        if self.fname is None:
+            return
+        try:
+            os.remove(self.fname)
+        except os.error:
+            pass
+
+    def test_getitem(self):
+        for k, v in self.d.iteritems():
+            self.assertEqual(self.f[k], v)
+
+    def test_len(self):
+        self.assertEqual(len(self.f), len(self.d))
+
+    def test_change(self):
+        self.f['r'] = 'discovered'
+        self.assertEqual(self.f['r'], 'discovered')
+        self.assert_('r' in self.f.keys())
+        self.assert_('discovered' in self.f.values())
+
+    def test_close_and_reopen(self):
+        if self.fname is None:
+            # if we're using an in-memory only db, we can't reopen it
+            # so finish here.
+            return
+        self.f.close()
+        self.f = self.openmethod[0](self.fname, 'w')
+        for k, v in self.d.iteritems():
+            self.assertEqual(self.f[k], v)
+
+    def assertSetEquals(self, seqn1, seqn2):
+        self.assertEqual(set(seqn1), set(seqn2))
+
+    def test_mapping_iteration_methods(self):
+        f = self.f
+        d = self.d
+        self.assertSetEquals(d, f)
+        self.assertSetEquals(d.keys(), f.keys())
+        self.assertSetEquals(d.values(), f.values())
+        self.assertSetEquals(d.items(), f.items())
+        self.assertSetEquals(d.iterkeys(), f.iterkeys())
+        self.assertSetEquals(d.itervalues(), f.itervalues())
+        self.assertSetEquals(d.iteritems(), f.iteritems())
+
+    def test_iter_while_modifying_values(self):
+        if not hasattr(self.f, '__iter__'):
+            return
+
+        di = iter(self.d)
+        while 1:
+            try:
+                key = di.next()
+                self.d[key] = 'modified '+key
+            except StopIteration:
+                break
+
+        # it should behave the same as a dict.  modifying values
+        # of existing keys should not break iteration.  (adding
+        # or removing keys should)
+        fi = iter(self.f)
+        while 1:
+            try:
+                key = fi.next()
+                self.f[key] = 'modified '+key
+            except StopIteration:
+                break
+
+        self.test_mapping_iteration_methods()
+
+    def test_iteritems_while_modifying_values(self):
+        if not hasattr(self.f, 'iteritems'):
+            return
+
+        di = self.d.iteritems()
+        while 1:
+            try:
+                k, v = di.next()
+                self.d[k] = 'modified '+v
+            except StopIteration:
+                break
+
+        # it should behave the same as a dict.  modifying values
+        # of existing keys should not break iteration.  (adding
+        # or removing keys should)
+        fi = self.f.iteritems()
+        while 1:
+            try:
+                k, v = fi.next()
+                self.f[k] = 'modified '+v
+            except StopIteration:
+                break
+
+        self.test_mapping_iteration_methods()
+
+    def test_first_next_looping(self):
+        items = [self.f.first()]
+        for i in xrange(1, len(self.f)):
+            items.append(self.f.next())
+        self.assertSetEquals(items, self.d.items())
+
+    def test_previous_last_looping(self):
+        items = [self.f.last()]
+        for i in xrange(1, len(self.f)):
+            items.append(self.f.previous())
+        self.assertSetEquals(items, self.d.items())
+
+    def test_set_location(self):
+        self.assertEqual(self.f.set_location('e'), ('e', self.d['e']))
+
+    def test_contains(self):
+        for k in self.d:
+            self.assert_(k in self.f)
+        self.assert_('not here' not in self.f)
+
+    def test_has_key(self):
+        for k in self.d:
+            self.assert_(self.f.has_key(k))
+        self.assert_(not self.f.has_key('not here'))
+
+    def test_clear(self):
+        self.f.clear()
+        self.assertEqual(len(self.f), 0)
+
+    def test__no_deadlock_first(self, debug=0):
+        # do this so that testers can see what function we're in in
+        # verbose mode when we deadlock.
+        sys.stdout.flush()
+
+        # in pybsddb's _DBWithCursor this causes an internal DBCursor
+        # object is created.  Other test_ methods in this class could
+        # inadvertently cause the deadlock but an explicit test is needed.
+        if debug: print "A"
+        k,v = self.f.first()
+        if debug: print "B", k
+        self.f[k] = "deadlock.  do not pass go.  do not collect $200."
+        if debug: print "C"
+        # if the bsddb implementation leaves the DBCursor open during
+        # the database write and locking+threading support is enabled
+        # the cursor's read lock will deadlock the write lock request..
+
+        # test the iterator interface (if present)
+        if hasattr(self.f, 'iteritems'):
+            if debug: print "D"
+            i = self.f.iteritems()
+            k,v = i.next()
+            if debug: print "E"
+            self.f[k] = "please don't deadlock"
+            if debug: print "F"
+            while 1:
+                try:
+                    k,v = i.next()
+                except StopIteration:
+                    break
+            if debug: print "F2"
+
+            i = iter(self.f)
+            if debug: print "G"
+            while i:
+                try:
+                    if debug: print "H"
+                    k = i.next()
+                    if debug: print "I"
+                    self.f[k] = "deadlocks-r-us"
+                    if debug: print "J"
+                except StopIteration:
+                    i = None
+            if debug: print "K"
+
+        # test the legacy cursor interface mixed with writes
+        self.assert_(self.f.first()[0] in self.d)
+        k = self.f.next()[0]
+        self.assert_(k in self.d)
+        self.f[k] = "be gone with ye deadlocks"
+        self.assert_(self.f[k], "be gone with ye deadlocks")
+
+    def test_for_cursor_memleak(self):
+        if not hasattr(self.f, 'iteritems'):
+            return
+
+        # do the bsddb._DBWithCursor _iter_mixin internals leak cursors?
+        nc1 = len(self.f._cursor_refs)
+        # create iterator
+        i = self.f.iteritems()
+        nc2 = len(self.f._cursor_refs)
+        # use the iterator (should run to the first yeild, creating the cursor)
+        k, v = i.next()
+        nc3 = len(self.f._cursor_refs)
+        # destroy the iterator; this should cause the weakref callback
+        # to remove the cursor object from self.f._cursor_refs
+        del i
+        nc4 = len(self.f._cursor_refs)
+
+        self.assertEqual(nc1, nc2)
+        self.assertEqual(nc1, nc4)
+        self.assert_(nc3 == nc1+1)
+
+    def test_popitem(self):
+        k, v = self.f.popitem()
+        self.assert_(k in self.d)
+        self.assert_(v in self.d.values())
+        self.assert_(k not in self.f)
+        self.assertEqual(len(self.d)-1, len(self.f))
+
+    def test_pop(self):
+        k = 'w'
+        v = self.f.pop(k)
+        self.assertEqual(v, self.d[k])
+        self.assert_(k not in self.f)
+        self.assert_(v not in self.f.values())
+        self.assertEqual(len(self.d)-1, len(self.f))
+
+    def test_get(self):
+        self.assertEqual(self.f.get('NotHere'), None)
+        self.assertEqual(self.f.get('NotHere', 'Default'), 'Default')
+        self.assertEqual(self.f.get('q', 'Default'), self.d['q'])
+
+    def test_setdefault(self):
+        self.assertEqual(self.f.setdefault('new', 'dog'), 'dog')
+        self.assertEqual(self.f.setdefault('r', 'cat'), self.d['r'])
+
+    def test_update(self):
+        new = dict(y='life', u='of', i='brian')
+        self.f.update(new)
+        self.d.update(new)
+        for k, v in self.d.iteritems():
+            self.assertEqual(self.f[k], v)
+
+    def test_keyordering(self):
+        if self.openmethod[0] is not bsddb.btopen:
+            return
+        keys = self.d.keys()
+        keys.sort()
+        self.assertEqual(self.f.first()[0], keys[0])
+        self.assertEqual(self.f.next()[0], keys[1])
+        self.assertEqual(self.f.last()[0], keys[-1])
+        self.assertEqual(self.f.previous()[0], keys[-2])
+        self.assertEqual(list(self.f), keys)
+
+class TestBTree(TestBSDDB):
+    fname = test_support.TESTFN
+    openmethod = [bsddb.btopen]
+
+class TestBTree_InMemory(TestBSDDB):
+    fname = None
+    openmethod = [bsddb.btopen]
+
+class TestBTree_InMemory_Truncate(TestBSDDB):
+    fname = None
+    openflag = 'n'
+    openmethod = [bsddb.btopen]
+
+class TestHashTable(TestBSDDB):
+    fname = test_support.TESTFN
+    openmethod = [bsddb.hashopen]
+
+class TestHashTable_InMemory(TestBSDDB):
+    fname = None
+    openmethod = [bsddb.hashopen]
+
+##         # (bsddb.rnopen,'Record Numbers'), 'put' for RECNO for bsddb 1.85
+##         #                                   appears broken... at least on
+##         #                                   Solaris Intel - rmasse 1/97
+
+def test_main(verbose=None):
+    test_support.run_unittest(
+        TestBTree,
+        TestHashTable,
+        TestBTree_InMemory,
+        TestHashTable_InMemory,
+        TestBTree_InMemory_Truncate,
+    )
+
+if __name__ == "__main__":
+    test_main(verbose=True)


Property changes on: vendor/Python/current/Lib/test/test_bsddb.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/test/test_bsddb185.py
===================================================================
--- vendor/Python/current/Lib/test/test_bsddb185.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_bsddb185.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,43 @@
+"""Tests for the bsddb185 module.
+
+The file 185test.db found in Lib/test/ is for testing purposes with this
+testing suite.
+
+"""
+from test.test_support import verbose, run_unittest, findfile
+import unittest
+import bsddb185
+import anydbm
+import whichdb
+import os
+import tempfile
+import shutil
+
+class Bsddb185Tests(unittest.TestCase):
+
+    def test_open_existing_hash(self):
+        # Verify we can open a file known to be a hash v2 file
+        db = bsddb185.hashopen(findfile("185test.db"))
+        self.assertEqual(db["1"], "1")
+        db.close()
+
+    def test_whichdb(self):
+        # Verify that whichdb correctly sniffs the known hash v2 file
+        self.assertEqual(whichdb.whichdb(findfile("185test.db")), "bsddb185")
+
+    def test_anydbm_create(self):
+        # Verify that anydbm.open does *not* create a bsddb185 file
+        tmpdir = tempfile.mkdtemp()
+        try:
+            dbfile = os.path.join(tmpdir, "foo.db")
+            anydbm.open(dbfile, "c").close()
+            ftype = whichdb.whichdb(dbfile)
+            self.assertNotEqual(ftype, "bsddb185")
+        finally:
+            shutil.rmtree(tmpdir)
+
+def test_main():
+    run_unittest(Bsddb185Tests)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_bsddb3.py
===================================================================
--- vendor/Python/current/Lib/test/test_bsddb3.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_bsddb3.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,76 @@
+# Test driver for bsddb package.
+"""
+Run all test cases.
+"""
+import sys
+import unittest
+from test.test_support import requires, verbose, run_suite, unlink
+
+# When running as a script instead of within the regrtest framework, skip the
+# requires test, since it's obvious we want to run them.
+if __name__ <> '__main__':
+    requires('bsddb')
+
+verbose = False
+if 'verbose' in sys.argv:
+    verbose = True
+    sys.argv.remove('verbose')
+
+if 'silent' in sys.argv:  # take care of old flag, just in case
+    verbose = False
+    sys.argv.remove('silent')
+
+
+def suite():
+    try:
+        # this is special, it used to segfault the interpreter
+        import bsddb.test.test_1413192
+    except:
+        for f in ['__db.001', '__db.002', '__db.003', 'log.0000000001']:
+            unlink(f)
+
+    test_modules = [
+        'test_associate',
+        'test_basics',
+        'test_compat',
+        'test_dbobj',
+        'test_dbshelve',
+        'test_dbtables',
+        'test_env_close',
+        'test_get_none',
+        'test_join',
+        'test_lock',
+        'test_misc',
+        'test_queue',
+        'test_recno',
+        'test_thread',
+        'test_sequence',
+        'test_cursor_pget_bug',
+        ]
+
+    alltests = unittest.TestSuite()
+    for name in test_modules:
+        module = __import__("bsddb.test."+name, globals(), locals(), name)
+        #print module,name
+        alltests.addTest(module.test_suite())
+    return alltests
+
+
+# For invocation through regrtest
+def test_main():
+    tests = suite()
+    run_suite(tests)
+
+
+# For invocation as a script
+if __name__ == '__main__':
+    from bsddb import db
+    print '-=' * 38
+    print db.DB_VERSION_STRING
+    print 'bsddb.db.version():   %s' % (db.version(),)
+    print 'bsddb.db.__version__: %s' % db.__version__
+    print 'bsddb.db.cvsid:       %s' % db.cvsid
+    print 'python version:        %s' % sys.version
+    print '-=' * 38
+
+    unittest.main(defaultTest='suite')

Added: vendor/Python/current/Lib/test/test_bufio.py
===================================================================
--- vendor/Python/current/Lib/test/test_bufio.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_bufio.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,60 @@
+from test.test_support import verify, TestFailed, TESTFN
+
+# Simple test to ensure that optimizations in fileobject.c deliver
+# the expected results.  For best testing, run this under a debug-build
+# Python too (to exercise asserts in the C code).
+
+# Repeat string 'pattern' as often as needed to reach total length
+# 'length'.  Then call try_one with that string, a string one larger
+# than that, and a string one smaller than that.  The main driver
+# feeds this all small sizes and various powers of 2, so we exercise
+# all likely stdio buffer sizes, and "off by one" errors on both
+# sides.
+def drive_one(pattern, length):
+    q, r = divmod(length, len(pattern))
+    teststring = pattern * q + pattern[:r]
+    verify(len(teststring) == length)
+    try_one(teststring)
+    try_one(teststring + "x")
+    try_one(teststring[:-1])
+
+# Write s + "\n" + s to file, then open it and ensure that successive
+# .readline()s deliver what we wrote.
+def try_one(s):
+    # Since C doesn't guarantee we can write/read arbitrary bytes in text
+    # files, use binary mode.
+    f = open(TESTFN, "wb")
+    # write once with \n and once without
+    f.write(s)
+    f.write("\n")
+    f.write(s)
+    f.close()
+    f = open(TESTFN, "rb")
+    line = f.readline()
+    if line != s + "\n":
+        raise TestFailed("Expected %r got %r" % (s + "\n", line))
+    line = f.readline()
+    if line != s:
+        raise TestFailed("Expected %r got %r" % (s, line))
+    line = f.readline()
+    if line:
+        raise TestFailed("Expected EOF but got %r" % line)
+    f.close()
+
+# A pattern with prime length, to avoid simple relationships with
+# stdio buffer sizes.
+primepat = "1234567890\00\01\02\03\04\05\06"
+
+nullpat = "\0" * 1000
+
+try:
+    for size in range(1, 257) + [512, 1000, 1024, 2048, 4096, 8192, 10000,
+                      16384, 32768, 65536, 1000000]:
+        drive_one(primepat, size)
+        drive_one(nullpat, size)
+finally:
+    try:
+        import os
+        os.unlink(TESTFN)
+    except:
+        pass

Added: vendor/Python/current/Lib/test/test_builtin.py
===================================================================
--- vendor/Python/current/Lib/test/test_builtin.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_builtin.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1783 @@
+# Python test set -- built-in functions
+
+import test.test_support, unittest
+from test.test_support import fcmp, have_unicode, TESTFN, unlink, \
+                              run_unittest, run_with_locale
+from operator import neg
+
+import sys, warnings, cStringIO, random, UserDict
+warnings.filterwarnings("ignore", "hex../oct.. of negative int",
+                        FutureWarning, __name__)
+warnings.filterwarnings("ignore", "integer argument expected",
+                        DeprecationWarning, "unittest")
+
+# count the number of test runs.
+# used to skip running test_execfile() multiple times
+numruns = 0
+
+class Squares:
+
+    def __init__(self, max):
+        self.max = max
+        self.sofar = []
+
+    def __len__(self): return len(self.sofar)
+
+    def __getitem__(self, i):
+        if not 0 <= i < self.max: raise IndexError
+        n = len(self.sofar)
+        while n <= i:
+            self.sofar.append(n*n)
+            n += 1
+        return self.sofar[i]
+
+class StrSquares:
+
+    def __init__(self, max):
+        self.max = max
+        self.sofar = []
+
+    def __len__(self):
+        return len(self.sofar)
+
+    def __getitem__(self, i):
+        if not 0 <= i < self.max:
+            raise IndexError
+        n = len(self.sofar)
+        while n <= i:
+            self.sofar.append(str(n*n))
+            n += 1
+        return self.sofar[i]
+
+class BitBucket:
+    def write(self, line):
+        pass
+
+L = [
+        ('0', 0),
+        ('1', 1),
+        ('9', 9),
+        ('10', 10),
+        ('99', 99),
+        ('100', 100),
+        ('314', 314),
+        (' 314', 314),
+        ('314 ', 314),
+        ('  \t\t  314  \t\t  ', 314),
+        (repr(sys.maxint), sys.maxint),
+        ('  1x', ValueError),
+        ('  1  ', 1),
+        ('  1\02  ', ValueError),
+        ('', ValueError),
+        (' ', ValueError),
+        ('  \t\t  ', ValueError)
+]
+if have_unicode:
+    L += [
+        (unicode('0'), 0),
+        (unicode('1'), 1),
+        (unicode('9'), 9),
+        (unicode('10'), 10),
+        (unicode('99'), 99),
+        (unicode('100'), 100),
+        (unicode('314'), 314),
+        (unicode(' 314'), 314),
+        (unicode('\u0663\u0661\u0664 ','raw-unicode-escape'), 314),
+        (unicode('  \t\t  314  \t\t  '), 314),
+        (unicode('  1x'), ValueError),
+        (unicode('  1  '), 1),
+        (unicode('  1\02  '), ValueError),
+        (unicode(''), ValueError),
+        (unicode(' '), ValueError),
+        (unicode('  \t\t  '), ValueError),
+        (unichr(0x200), ValueError),
+]
+
+class TestFailingBool:
+    def __nonzero__(self):
+        raise RuntimeError
+
+class TestFailingIter:
+    def __iter__(self):
+        raise RuntimeError
+
+class BuiltinTest(unittest.TestCase):
+
+    def test_import(self):
+        __import__('sys')
+        __import__('time')
+        __import__('string')
+        self.assertRaises(ImportError, __import__, 'spamspam')
+        self.assertRaises(TypeError, __import__, 1, 2, 3, 4)
+        self.assertRaises(ValueError, __import__, '')
+
+    def test_abs(self):
+        # int
+        self.assertEqual(abs(0), 0)
+        self.assertEqual(abs(1234), 1234)
+        self.assertEqual(abs(-1234), 1234)
+        self.assertTrue(abs(-sys.maxint-1) > 0)
+        # float
+        self.assertEqual(abs(0.0), 0.0)
+        self.assertEqual(abs(3.14), 3.14)
+        self.assertEqual(abs(-3.14), 3.14)
+        # long
+        self.assertEqual(abs(0L), 0L)
+        self.assertEqual(abs(1234L), 1234L)
+        self.assertEqual(abs(-1234L), 1234L)
+        # str
+        self.assertRaises(TypeError, abs, 'a')
+
+    def test_all(self):
+        self.assertEqual(all([2, 4, 6]), True)
+        self.assertEqual(all([2, None, 6]), False)
+        self.assertRaises(RuntimeError, all, [2, TestFailingBool(), 6])
+        self.assertRaises(RuntimeError, all, TestFailingIter())
+        self.assertRaises(TypeError, all, 10)               # Non-iterable
+        self.assertRaises(TypeError, all)                   # No args
+        self.assertRaises(TypeError, all, [2, 4, 6], [])    # Too many args
+        self.assertEqual(all([]), True)                     # Empty iterator
+        S = [50, 60]
+        self.assertEqual(all(x > 42 for x in S), True)
+        S = [50, 40, 60]
+        self.assertEqual(all(x > 42 for x in S), False)
+
+    def test_any(self):
+        self.assertEqual(any([None, None, None]), False)
+        self.assertEqual(any([None, 4, None]), True)
+        self.assertRaises(RuntimeError, any, [None, TestFailingBool(), 6])
+        self.assertRaises(RuntimeError, all, TestFailingIter())
+        self.assertRaises(TypeError, any, 10)               # Non-iterable
+        self.assertRaises(TypeError, any)                   # No args
+        self.assertRaises(TypeError, any, [2, 4, 6], [])    # Too many args
+        self.assertEqual(any([]), False)                    # Empty iterator
+        S = [40, 60, 30]
+        self.assertEqual(any(x > 42 for x in S), True)
+        S = [10, 20, 30]
+        self.assertEqual(any(x > 42 for x in S), False)
+
+    def test_neg(self):
+        x = -sys.maxint-1
+        self.assert_(isinstance(x, int))
+        self.assertEqual(-x, sys.maxint+1)
+
+    def test_apply(self):
+        def f0(*args):
+            self.assertEqual(args, ())
+        def f1(a1):
+            self.assertEqual(a1, 1)
+        def f2(a1, a2):
+            self.assertEqual(a1, 1)
+            self.assertEqual(a2, 2)
+        def f3(a1, a2, a3):
+            self.assertEqual(a1, 1)
+            self.assertEqual(a2, 2)
+            self.assertEqual(a3, 3)
+        apply(f0, ())
+        apply(f1, (1,))
+        apply(f2, (1, 2))
+        apply(f3, (1, 2, 3))
+
+        # A PyCFunction that takes only positional parameters should allow an
+        # empty keyword dictionary to pass without a complaint, but raise a
+        # TypeError if the dictionary is non-empty.
+        apply(id, (1,), {})
+        self.assertRaises(TypeError, apply, id, (1,), {"foo": 1})
+        self.assertRaises(TypeError, apply)
+        self.assertRaises(TypeError, apply, id, 42)
+        self.assertRaises(TypeError, apply, id, (42,), 42)
+
+    def test_callable(self):
+        self.assert_(callable(len))
+        def f(): pass
+        self.assert_(callable(f))
+        class C:
+            def meth(self): pass
+        self.assert_(callable(C))
+        x = C()
+        self.assert_(callable(x.meth))
+        self.assert_(not callable(x))
+        class D(C):
+            def __call__(self): pass
+        y = D()
+        self.assert_(callable(y))
+        y()
+
+    def test_chr(self):
+        self.assertEqual(chr(32), ' ')
+        self.assertEqual(chr(65), 'A')
+        self.assertEqual(chr(97), 'a')
+        self.assertEqual(chr(0xff), '\xff')
+        self.assertRaises(ValueError, chr, 256)
+        self.assertRaises(TypeError, chr)
+
+    def test_cmp(self):
+        self.assertEqual(cmp(-1, 1), -1)
+        self.assertEqual(cmp(1, -1), 1)
+        self.assertEqual(cmp(1, 1), 0)
+        # verify that circular objects are not handled
+        a = []; a.append(a)
+        b = []; b.append(b)
+        from UserList import UserList
+        c = UserList(); c.append(c)
+        self.assertRaises(RuntimeError, cmp, a, b)
+        self.assertRaises(RuntimeError, cmp, b, c)
+        self.assertRaises(RuntimeError, cmp, c, a)
+        self.assertRaises(RuntimeError, cmp, a, c)
+       # okay, now break the cycles
+        a.pop(); b.pop(); c.pop()
+        self.assertRaises(TypeError, cmp)
+
+    def test_coerce(self):
+        self.assert_(not fcmp(coerce(1, 1.1), (1.0, 1.1)))
+        self.assertEqual(coerce(1, 1L), (1L, 1L))
+        self.assert_(not fcmp(coerce(1L, 1.1), (1.0, 1.1)))
+        self.assertRaises(TypeError, coerce)
+        class BadNumber:
+            def __coerce__(self, other):
+                raise ValueError
+        self.assertRaises(ValueError, coerce, 42, BadNumber())
+        self.assertRaises(OverflowError, coerce, 0.5, int("12345" * 1000))
+
+    def test_compile(self):
+        compile('print 1\n', '', 'exec')
+        bom = '\xef\xbb\xbf'
+        compile(bom + 'print 1\n', '', 'exec')
+        self.assertRaises(TypeError, compile)
+        self.assertRaises(ValueError, compile, 'print 42\n', '<string>', 'badmode')
+        self.assertRaises(ValueError, compile, 'print 42\n', '<string>', 'single', 0xff)
+        self.assertRaises(TypeError, compile, chr(0), 'f', 'exec')
+        if have_unicode:
+            compile(unicode('print u"\xc3\xa5"\n', 'utf8'), '', 'exec')
+            self.assertRaises(TypeError, compile, unichr(0), 'f', 'exec')
+            self.assertRaises(ValueError, compile, unicode('a = 1'), 'f', 'bad')
+
+    def test_delattr(self):
+        import sys
+        sys.spam = 1
+        delattr(sys, 'spam')
+        self.assertRaises(TypeError, delattr)
+
+    def test_dir(self):
+        x = 1
+        self.assert_('x' in dir())
+        import sys
+        self.assert_('modules' in dir(sys))
+        self.assertRaises(TypeError, dir, 42, 42)
+
+    def test_divmod(self):
+        self.assertEqual(divmod(12, 7), (1, 5))
+        self.assertEqual(divmod(-12, 7), (-2, 2))
+        self.assertEqual(divmod(12, -7), (-2, -2))
+        self.assertEqual(divmod(-12, -7), (1, -5))
+
+        self.assertEqual(divmod(12L, 7L), (1L, 5L))
+        self.assertEqual(divmod(-12L, 7L), (-2L, 2L))
+        self.assertEqual(divmod(12L, -7L), (-2L, -2L))
+        self.assertEqual(divmod(-12L, -7L), (1L, -5L))
+
+        self.assertEqual(divmod(12, 7L), (1, 5L))
+        self.assertEqual(divmod(-12, 7L), (-2, 2L))
+        self.assertEqual(divmod(12L, -7), (-2L, -2))
+        self.assertEqual(divmod(-12L, -7), (1L, -5))
+
+        self.assertEqual(divmod(-sys.maxint-1, -1),
+                         (sys.maxint+1, 0))
+
+        self.assert_(not fcmp(divmod(3.25, 1.0), (3.0, 0.25)))
+        self.assert_(not fcmp(divmod(-3.25, 1.0), (-4.0, 0.75)))
+        self.assert_(not fcmp(divmod(3.25, -1.0), (-4.0, -0.75)))
+        self.assert_(not fcmp(divmod(-3.25, -1.0), (3.0, -0.25)))
+
+        self.assertRaises(TypeError, divmod)
+
+    def test_eval(self):
+        self.assertEqual(eval('1+1'), 2)
+        self.assertEqual(eval(' 1+1\n'), 2)
+        globals = {'a': 1, 'b': 2}
+        locals = {'b': 200, 'c': 300}
+        self.assertEqual(eval('a', globals) , 1)
+        self.assertEqual(eval('a', globals, locals), 1)
+        self.assertEqual(eval('b', globals, locals), 200)
+        self.assertEqual(eval('c', globals, locals), 300)
+        if have_unicode:
+            self.assertEqual(eval(unicode('1+1')), 2)
+            self.assertEqual(eval(unicode(' 1+1\n')), 2)
+        globals = {'a': 1, 'b': 2}
+        locals = {'b': 200, 'c': 300}
+        if have_unicode:
+            self.assertEqual(eval(unicode('a'), globals), 1)
+            self.assertEqual(eval(unicode('a'), globals, locals), 1)
+            self.assertEqual(eval(unicode('b'), globals, locals), 200)
+            self.assertEqual(eval(unicode('c'), globals, locals), 300)
+            bom = '\xef\xbb\xbf'
+            self.assertEqual(eval(bom + 'a', globals, locals), 1)
+            self.assertEqual(eval(unicode('u"\xc3\xa5"', 'utf8'), globals),
+                             unicode('\xc3\xa5', 'utf8'))
+        self.assertRaises(TypeError, eval)
+        self.assertRaises(TypeError, eval, ())
+
+    def test_general_eval(self):
+        # Tests that general mappings can be used for the locals argument
+
+        class M:
+            "Test mapping interface versus possible calls from eval()."
+            def __getitem__(self, key):
+                if key == 'a':
+                    return 12
+                raise KeyError
+            def keys(self):
+                return list('xyz')
+
+        m = M()
+        g = globals()
+        self.assertEqual(eval('a', g, m), 12)
+        self.assertRaises(NameError, eval, 'b', g, m)
+        self.assertEqual(eval('dir()', g, m), list('xyz'))
+        self.assertEqual(eval('globals()', g, m), g)
+        self.assertEqual(eval('locals()', g, m), m)
+        self.assertRaises(TypeError, eval, 'a', m)
+        class A:
+            "Non-mapping"
+            pass
+        m = A()
+        self.assertRaises(TypeError, eval, 'a', g, m)
+
+        # Verify that dict subclasses work as well
+        class D(dict):
+            def __getitem__(self, key):
+                if key == 'a':
+                    return 12
+                return dict.__getitem__(self, key)
+            def keys(self):
+                return list('xyz')
+
+        d = D()
+        self.assertEqual(eval('a', g, d), 12)
+        self.assertRaises(NameError, eval, 'b', g, d)
+        self.assertEqual(eval('dir()', g, d), list('xyz'))
+        self.assertEqual(eval('globals()', g, d), g)
+        self.assertEqual(eval('locals()', g, d), d)
+
+        # Verify locals stores (used by list comps)
+        eval('[locals() for i in (2,3)]', g, d)
+        eval('[locals() for i in (2,3)]', g, UserDict.UserDict())
+
+        class SpreadSheet:
+            "Sample application showing nested, calculated lookups."
+            _cells = {}
+            def __setitem__(self, key, formula):
+                self._cells[key] = formula
+            def __getitem__(self, key):
+                return eval(self._cells[key], globals(), self)
+
+        ss = SpreadSheet()
+        ss['a1'] = '5'
+        ss['a2'] = 'a1*6'
+        ss['a3'] = 'a2*7'
+        self.assertEqual(ss['a3'], 210)
+
+        # Verify that dir() catches a non-list returned by eval
+        # SF bug #1004669
+        class C:
+            def __getitem__(self, item):
+                raise KeyError(item)
+            def keys(self):
+                return 'a'
+        self.assertRaises(TypeError, eval, 'dir()', globals(), C())
+
+    # Done outside of the method test_z to get the correct scope
+    z = 0
+    f = open(TESTFN, 'w')
+    f.write('z = z+1\n')
+    f.write('z = z*2\n')
+    f.close()
+    execfile(TESTFN)
+
+    def test_execfile(self):
+        global numruns
+        if numruns:
+            return
+        numruns += 1
+
+        globals = {'a': 1, 'b': 2}
+        locals = {'b': 200, 'c': 300}
+
+        self.assertEqual(self.__class__.z, 2)
+        globals['z'] = 0
+        execfile(TESTFN, globals)
+        self.assertEqual(globals['z'], 2)
+        locals['z'] = 0
+        execfile(TESTFN, globals, locals)
+        self.assertEqual(locals['z'], 2)
+
+        class M:
+            "Test mapping interface versus possible calls from execfile()."
+            def __init__(self):
+                self.z = 10
+            def __getitem__(self, key):
+                if key == 'z':
+                    return self.z
+                raise KeyError
+            def __setitem__(self, key, value):
+                if key == 'z':
+                    self.z = value
+                    return
+                raise KeyError
+
+        locals = M()
+        locals['z'] = 0
+        execfile(TESTFN, globals, locals)
+        self.assertEqual(locals['z'], 2)
+
+        unlink(TESTFN)
+        self.assertRaises(TypeError, execfile)
+        self.assertRaises(TypeError, execfile, TESTFN, {}, ())
+        import os
+        self.assertRaises(IOError, execfile, os.curdir)
+        self.assertRaises(IOError, execfile, "I_dont_exist")
+
+    def test_filter(self):
+        self.assertEqual(filter(lambda c: 'a' <= c <= 'z', 'Hello World'), 'elloorld')
+        self.assertEqual(filter(None, [1, 'hello', [], [3], '', None, 9, 0]), [1, 'hello', [3], 9])
+        self.assertEqual(filter(lambda x: x > 0, [1, -3, 9, 0, 2]), [1, 9, 2])
+        self.assertEqual(filter(None, Squares(10)), [1, 4, 9, 16, 25, 36, 49, 64, 81])
+        self.assertEqual(filter(lambda x: x%2, Squares(10)), [1, 9, 25, 49, 81])
+        def identity(item):
+            return 1
+        filter(identity, Squares(5))
+        self.assertRaises(TypeError, filter)
+        class BadSeq(object):
+            def __getitem__(self, index):
+                if index<4:
+                    return 42
+                raise ValueError
+        self.assertRaises(ValueError, filter, lambda x: x, BadSeq())
+        def badfunc():
+            pass
+        self.assertRaises(TypeError, filter, badfunc, range(5))
+
+        # test bltinmodule.c::filtertuple()
+        self.assertEqual(filter(None, (1, 2)), (1, 2))
+        self.assertEqual(filter(lambda x: x>=3, (1, 2, 3, 4)), (3, 4))
+        self.assertRaises(TypeError, filter, 42, (1, 2))
+
+        # test bltinmodule.c::filterstring()
+        self.assertEqual(filter(None, "12"), "12")
+        self.assertEqual(filter(lambda x: x>="3", "1234"), "34")
+        self.assertRaises(TypeError, filter, 42, "12")
+        class badstr(str):
+            def __getitem__(self, index):
+                raise ValueError
+        self.assertRaises(ValueError, filter, lambda x: x >="3", badstr("1234"))
+
+        class badstr2(str):
+            def __getitem__(self, index):
+                return 42
+        self.assertRaises(TypeError, filter, lambda x: x >=42, badstr2("1234"))
+
+        class weirdstr(str):
+            def __getitem__(self, index):
+                return weirdstr(2*str.__getitem__(self, index))
+        self.assertEqual(filter(lambda x: x>="33", weirdstr("1234")), "3344")
+
+        class shiftstr(str):
+            def __getitem__(self, index):
+                return chr(ord(str.__getitem__(self, index))+1)
+        self.assertEqual(filter(lambda x: x>="3", shiftstr("1234")), "345")
+
+        if have_unicode:
+            # test bltinmodule.c::filterunicode()
+            self.assertEqual(filter(None, unicode("12")), unicode("12"))
+            self.assertEqual(filter(lambda x: x>="3", unicode("1234")), unicode("34"))
+            self.assertRaises(TypeError, filter, 42, unicode("12"))
+            self.assertRaises(ValueError, filter, lambda x: x >="3", badstr(unicode("1234")))
+
+            class badunicode(unicode):
+                def __getitem__(self, index):
+                    return 42
+            self.assertRaises(TypeError, filter, lambda x: x >=42, badunicode("1234"))
+
+            class weirdunicode(unicode):
+                def __getitem__(self, index):
+                    return weirdunicode(2*unicode.__getitem__(self, index))
+            self.assertEqual(
+                filter(lambda x: x>=unicode("33"), weirdunicode("1234")), unicode("3344"))
+
+            class shiftunicode(unicode):
+                def __getitem__(self, index):
+                    return unichr(ord(unicode.__getitem__(self, index))+1)
+            self.assertEqual(
+                filter(lambda x: x>=unicode("3"), shiftunicode("1234")),
+                unicode("345")
+            )
+
+    def test_filter_subclasses(self):
+        # test that filter() never returns tuple, str or unicode subclasses
+        # and that the result always goes through __getitem__
+        funcs = (None, bool, lambda x: True)
+        class tuple2(tuple):
+            def __getitem__(self, index):
+                return 2*tuple.__getitem__(self, index)
+        class str2(str):
+            def __getitem__(self, index):
+                return 2*str.__getitem__(self, index)
+        inputs = {
+            tuple2: {(): (), (1, 2, 3): (2, 4, 6)},
+            str2:   {"": "", "123": "112233"}
+        }
+        if have_unicode:
+            class unicode2(unicode):
+                def __getitem__(self, index):
+                    return 2*unicode.__getitem__(self, index)
+            inputs[unicode2] = {
+                unicode(): unicode(),
+                unicode("123"): unicode("112233")
+            }
+
+        for (cls, inps) in inputs.iteritems():
+            for (inp, exp) in inps.iteritems():
+                # make sure the output goes through __getitem__
+                # even if func is None
+                self.assertEqual(
+                    filter(funcs[0], cls(inp)),
+                    filter(funcs[1], cls(inp))
+                )
+                for func in funcs:
+                    outp = filter(func, cls(inp))
+                    self.assertEqual(outp, exp)
+                    self.assert_(not isinstance(outp, cls))
+
+    def test_float(self):
+        self.assertEqual(float(3.14), 3.14)
+        self.assertEqual(float(314), 314.0)
+        self.assertEqual(float(314L), 314.0)
+        self.assertEqual(float("  3.14  "), 3.14)
+        self.assertRaises(ValueError, float, "  0x3.1  ")
+        self.assertRaises(ValueError, float, "  -0x3.p-1  ")
+        if have_unicode:
+            self.assertEqual(float(unicode("  3.14  ")), 3.14)
+            self.assertEqual(float(unicode("  \u0663.\u0661\u0664  ",'raw-unicode-escape')), 3.14)
+            # Implementation limitation in PyFloat_FromString()
+            self.assertRaises(ValueError, float, unicode("1"*10000))
+
+    @run_with_locale('LC_NUMERIC', 'fr_FR', 'de_DE')
+    def test_float_with_comma(self):
+        # set locale to something that doesn't use '.' for the decimal point
+        # float must not accept the locale specific decimal point but
+        # it still has to accept the normal python syntac
+        import locale
+        if not locale.localeconv()['decimal_point'] == ',':
+            return
+
+        self.assertEqual(float("  3.14  "), 3.14)
+        self.assertEqual(float("+3.14  "), 3.14)
+        self.assertEqual(float("-3.14  "), -3.14)
+        self.assertEqual(float(".14  "), .14)
+        self.assertEqual(float("3.  "), 3.0)
+        self.assertEqual(float("3.e3  "), 3000.0)
+        self.assertEqual(float("3.2e3  "), 3200.0)
+        self.assertEqual(float("2.5e-1  "), 0.25)
+        self.assertEqual(float("5e-1"), 0.5)
+        self.assertRaises(ValueError, float, "  3,14  ")
+        self.assertRaises(ValueError, float, "  +3,14  ")
+        self.assertRaises(ValueError, float, "  -3,14  ")
+        self.assertRaises(ValueError, float, "  0x3.1  ")
+        self.assertRaises(ValueError, float, "  -0x3.p-1  ")
+        self.assertEqual(float("  25.e-1  "), 2.5)
+        self.assertEqual(fcmp(float("  .25e-1  "), .025), 0)
+
+    def test_floatconversion(self):
+        # Make sure that calls to __float__() work properly
+        class Foo0:
+            def __float__(self):
+                return 42.
+
+        class Foo1(object):
+            def __float__(self):
+                return 42.
+
+        class Foo2(float):
+            def __float__(self):
+                return 42.
+
+        class Foo3(float):
+            def __new__(cls, value=0.):
+                return float.__new__(cls, 2*value)
+
+            def __float__(self):
+                return self
+
+        class Foo4(float):
+            def __float__(self):
+                return 42
+
+        self.assertAlmostEqual(float(Foo0()), 42.)
+        self.assertAlmostEqual(float(Foo1()), 42.)
+        self.assertAlmostEqual(float(Foo2()), 42.)
+        self.assertAlmostEqual(float(Foo3(21)), 42.)
+        self.assertRaises(TypeError, float, Foo4(42))
+
+    def test_getattr(self):
+        import sys
+        self.assert_(getattr(sys, 'stdout') is sys.stdout)
+        self.assertRaises(TypeError, getattr, sys, 1)
+        self.assertRaises(TypeError, getattr, sys, 1, "foo")
+        self.assertRaises(TypeError, getattr)
+        if have_unicode:
+            self.assertRaises(UnicodeError, getattr, sys, unichr(sys.maxunicode))
+
+    def test_hasattr(self):
+        import sys
+        self.assert_(hasattr(sys, 'stdout'))
+        self.assertRaises(TypeError, hasattr, sys, 1)
+        self.assertRaises(TypeError, hasattr)
+        if have_unicode:
+            self.assertRaises(UnicodeError, hasattr, sys, unichr(sys.maxunicode))
+
+    def test_hash(self):
+        hash(None)
+        self.assertEqual(hash(1), hash(1L))
+        self.assertEqual(hash(1), hash(1.0))
+        hash('spam')
+        if have_unicode:
+            self.assertEqual(hash('spam'), hash(unicode('spam')))
+        hash((0,1,2,3))
+        def f(): pass
+        self.assertRaises(TypeError, hash, [])
+        self.assertRaises(TypeError, hash, {})
+        # Bug 1536021: Allow hash to return long objects
+        class X:
+            def __hash__(self):
+                return 2**100
+        self.assertEquals(type(hash(X())), int)
+        class Y(object):
+            def __hash__(self):
+                return 2**100
+        self.assertEquals(type(hash(Y())), int)
+        class Z(long):
+            def __hash__(self):
+                return self
+        self.assertEquals(hash(Z(42)), hash(42L))
+
+    def test_hex(self):
+        self.assertEqual(hex(16), '0x10')
+        self.assertEqual(hex(16L), '0x10L')
+        self.assertEqual(hex(-16), '-0x10')
+        self.assertEqual(hex(-16L), '-0x10L')
+        self.assertRaises(TypeError, hex, {})
+
+    def test_id(self):
+        id(None)
+        id(1)
+        id(1L)
+        id(1.0)
+        id('spam')
+        id((0,1,2,3))
+        id([0,1,2,3])
+        id({'spam': 1, 'eggs': 2, 'ham': 3})
+
+    # Test input() later, together with raw_input
+
+    def test_int(self):
+        self.assertEqual(int(314), 314)
+        self.assertEqual(int(3.14), 3)
+        self.assertEqual(int(314L), 314)
+        # Check that conversion from float truncates towards zero
+        self.assertEqual(int(-3.14), -3)
+        self.assertEqual(int(3.9), 3)
+        self.assertEqual(int(-3.9), -3)
+        self.assertEqual(int(3.5), 3)
+        self.assertEqual(int(-3.5), -3)
+        # Different base:
+        self.assertEqual(int("10",16), 16L)
+        if have_unicode:
+            self.assertEqual(int(unicode("10"),16), 16L)
+        # Test conversion from strings and various anomalies
+        for s, v in L:
+            for sign in "", "+", "-":
+                for prefix in "", " ", "\t", "  \t\t  ":
+                    ss = prefix + sign + s
+                    vv = v
+                    if sign == "-" and v is not ValueError:
+                        vv = -v
+                    try:
+                        self.assertEqual(int(ss), vv)
+                    except v:
+                        pass
+
+        s = repr(-1-sys.maxint)
+        x = int(s)
+        self.assertEqual(x+1, -sys.maxint)
+        self.assert_(isinstance(x, int))
+        # should return long
+        self.assertEqual(int(s[1:]), sys.maxint+1)
+
+        # should return long
+        x = int(1e100)
+        self.assert_(isinstance(x, long))
+        x = int(-1e100)
+        self.assert_(isinstance(x, long))
+
+
+        # SF bug 434186:  0x80000000/2 != 0x80000000>>1.
+        # Worked by accident in Windows release build, but failed in debug build.
+        # Failed in all Linux builds.
+        x = -1-sys.maxint
+        self.assertEqual(x >> 1, x//2)
+
+        self.assertRaises(ValueError, int, '123\0')
+        self.assertRaises(ValueError, int, '53', 40)
+
+        # SF bug 1545497: embedded NULs were not detected with
+        # explicit base
+        self.assertRaises(ValueError, int, '123\0', 10)
+        self.assertRaises(ValueError, int, '123\x00 245', 20)
+
+        x = int('1' * 600)
+        self.assert_(isinstance(x, long))
+
+        if have_unicode:
+            x = int(unichr(0x661) * 600)
+            self.assert_(isinstance(x, long))
+
+        self.assertRaises(TypeError, int, 1, 12)
+
+        self.assertEqual(int('0123', 0), 83)
+        self.assertEqual(int('0x123', 16), 291)
+
+        # SF bug 1334662: int(string, base) wrong answers
+        # Various representations of 2**32 evaluated to 0
+        # rather than 2**32 in previous versions
+
+        self.assertEqual(int('100000000000000000000000000000000', 2), 4294967296L)
+        self.assertEqual(int('102002022201221111211', 3), 4294967296L)
+        self.assertEqual(int('10000000000000000', 4), 4294967296L)
+        self.assertEqual(int('32244002423141', 5), 4294967296L)
+        self.assertEqual(int('1550104015504', 6), 4294967296L)
+        self.assertEqual(int('211301422354', 7), 4294967296L)
+        self.assertEqual(int('40000000000', 8), 4294967296L)
+        self.assertEqual(int('12068657454', 9), 4294967296L)
+        self.assertEqual(int('4294967296', 10), 4294967296L)
+        self.assertEqual(int('1904440554', 11), 4294967296L)
+        self.assertEqual(int('9ba461594', 12), 4294967296L)
+        self.assertEqual(int('535a79889', 13), 4294967296L)
+        self.assertEqual(int('2ca5b7464', 14), 4294967296L)
+        self.assertEqual(int('1a20dcd81', 15), 4294967296L)
+        self.assertEqual(int('100000000', 16), 4294967296L)
+        self.assertEqual(int('a7ffda91', 17), 4294967296L)
+        self.assertEqual(int('704he7g4', 18), 4294967296L)
+        self.assertEqual(int('4f5aff66', 19), 4294967296L)
+        self.assertEqual(int('3723ai4g', 20), 4294967296L)
+        self.assertEqual(int('281d55i4', 21), 4294967296L)
+        self.assertEqual(int('1fj8b184', 22), 4294967296L)
+        self.assertEqual(int('1606k7ic', 23), 4294967296L)
+        self.assertEqual(int('mb994ag', 24), 4294967296L)
+        self.assertEqual(int('hek2mgl', 25), 4294967296L)
+        self.assertEqual(int('dnchbnm', 26), 4294967296L)
+        self.assertEqual(int('b28jpdm', 27), 4294967296L)
+        self.assertEqual(int('8pfgih4', 28), 4294967296L)
+        self.assertEqual(int('76beigg', 29), 4294967296L)
+        self.assertEqual(int('5qmcpqg', 30), 4294967296L)
+        self.assertEqual(int('4q0jto4', 31), 4294967296L)
+        self.assertEqual(int('4000000', 32), 4294967296L)
+        self.assertEqual(int('3aokq94', 33), 4294967296L)
+        self.assertEqual(int('2qhxjli', 34), 4294967296L)
+        self.assertEqual(int('2br45qb', 35), 4294967296L)
+        self.assertEqual(int('1z141z4', 36), 4294967296L)
+
+        # SF bug 1334662: int(string, base) wrong answers
+        # Checks for proper evaluation of 2**32 + 1
+        self.assertEqual(int('100000000000000000000000000000001', 2), 4294967297L)
+        self.assertEqual(int('102002022201221111212', 3), 4294967297L)
+        self.assertEqual(int('10000000000000001', 4), 4294967297L)
+        self.assertEqual(int('32244002423142', 5), 4294967297L)
+        self.assertEqual(int('1550104015505', 6), 4294967297L)
+        self.assertEqual(int('211301422355', 7), 4294967297L)
+        self.assertEqual(int('40000000001', 8), 4294967297L)
+        self.assertEqual(int('12068657455', 9), 4294967297L)
+        self.assertEqual(int('4294967297', 10), 4294967297L)
+        self.assertEqual(int('1904440555', 11), 4294967297L)
+        self.assertEqual(int('9ba461595', 12), 4294967297L)
+        self.assertEqual(int('535a7988a', 13), 4294967297L)
+        self.assertEqual(int('2ca5b7465', 14), 4294967297L)
+        self.assertEqual(int('1a20dcd82', 15), 4294967297L)
+        self.assertEqual(int('100000001', 16), 4294967297L)
+        self.assertEqual(int('a7ffda92', 17), 4294967297L)
+        self.assertEqual(int('704he7g5', 18), 4294967297L)
+        self.assertEqual(int('4f5aff67', 19), 4294967297L)
+        self.assertEqual(int('3723ai4h', 20), 4294967297L)
+        self.assertEqual(int('281d55i5', 21), 4294967297L)
+        self.assertEqual(int('1fj8b185', 22), 4294967297L)
+        self.assertEqual(int('1606k7id', 23), 4294967297L)
+        self.assertEqual(int('mb994ah', 24), 4294967297L)
+        self.assertEqual(int('hek2mgm', 25), 4294967297L)
+        self.assertEqual(int('dnchbnn', 26), 4294967297L)
+        self.assertEqual(int('b28jpdn', 27), 4294967297L)
+        self.assertEqual(int('8pfgih5', 28), 4294967297L)
+        self.assertEqual(int('76beigh', 29), 4294967297L)
+        self.assertEqual(int('5qmcpqh', 30), 4294967297L)
+        self.assertEqual(int('4q0jto5', 31), 4294967297L)
+        self.assertEqual(int('4000001', 32), 4294967297L)
+        self.assertEqual(int('3aokq95', 33), 4294967297L)
+        self.assertEqual(int('2qhxjlj', 34), 4294967297L)
+        self.assertEqual(int('2br45qc', 35), 4294967297L)
+        self.assertEqual(int('1z141z5', 36), 4294967297L)
+
+    def test_intconversion(self):
+        # Test __int__()
+        class Foo0:
+            def __int__(self):
+                return 42
+
+        class Foo1(object):
+            def __int__(self):
+                return 42
+
+        class Foo2(int):
+            def __int__(self):
+                return 42
+
+        class Foo3(int):
+            def __int__(self):
+                return self
+
+        class Foo4(int):
+            def __int__(self):
+                return 42L
+
+        class Foo5(int):
+            def __int__(self):
+                return 42.
+
+        self.assertEqual(int(Foo0()), 42)
+        self.assertEqual(int(Foo1()), 42)
+        self.assertEqual(int(Foo2()), 42)
+        self.assertEqual(int(Foo3()), 0)
+        self.assertEqual(int(Foo4()), 42L)
+        self.assertRaises(TypeError, int, Foo5())
+
+    def test_intern(self):
+        self.assertRaises(TypeError, intern)
+        s = "never interned before"
+        self.assert_(intern(s) is s)
+        s2 = s.swapcase().swapcase()
+        self.assert_(intern(s2) is s)
+
+        # Subclasses of string can't be interned, because they
+        # provide too much opportunity for insane things to happen.
+        # We don't want them in the interned dict and if they aren't
+        # actually interned, we don't want to create the appearance
+        # that they are by allowing intern() to succeeed.
+        class S(str):
+            def __hash__(self):
+                return 123
+
+        self.assertRaises(TypeError, intern, S("abc"))
+
+        # It's still safe to pass these strings to routines that
+        # call intern internally, e.g. PyObject_SetAttr().
+        s = S("abc")
+        setattr(s, s, s)
+        self.assertEqual(getattr(s, s), s)
+
+    def test_iter(self):
+        self.assertRaises(TypeError, iter)
+        self.assertRaises(TypeError, iter, 42, 42)
+        lists = [("1", "2"), ["1", "2"], "12"]
+        if have_unicode:
+            lists.append(unicode("12"))
+        for l in lists:
+            i = iter(l)
+            self.assertEqual(i.next(), '1')
+            self.assertEqual(i.next(), '2')
+            self.assertRaises(StopIteration, i.next)
+
+    def test_isinstance(self):
+        class C:
+            pass
+        class D(C):
+            pass
+        class E:
+            pass
+        c = C()
+        d = D()
+        e = E()
+        self.assert_(isinstance(c, C))
+        self.assert_(isinstance(d, C))
+        self.assert_(not isinstance(e, C))
+        self.assert_(not isinstance(c, D))
+        self.assert_(not isinstance('foo', E))
+        self.assertRaises(TypeError, isinstance, E, 'foo')
+        self.assertRaises(TypeError, isinstance)
+
+    def test_issubclass(self):
+        class C:
+            pass
+        class D(C):
+            pass
+        class E:
+            pass
+        c = C()
+        d = D()
+        e = E()
+        self.assert_(issubclass(D, C))
+        self.assert_(issubclass(C, C))
+        self.assert_(not issubclass(C, D))
+        self.assertRaises(TypeError, issubclass, 'foo', E)
+        self.assertRaises(TypeError, issubclass, E, 'foo')
+        self.assertRaises(TypeError, issubclass)
+
+    def test_len(self):
+        self.assertEqual(len('123'), 3)
+        self.assertEqual(len(()), 0)
+        self.assertEqual(len((1, 2, 3, 4)), 4)
+        self.assertEqual(len([1, 2, 3, 4]), 4)
+        self.assertEqual(len({}), 0)
+        self.assertEqual(len({'a':1, 'b': 2}), 2)
+        class BadSeq:
+            def __len__(self):
+                raise ValueError
+        self.assertRaises(ValueError, len, BadSeq())
+
+    def test_list(self):
+        self.assertEqual(list([]), [])
+        l0_3 = [0, 1, 2, 3]
+        l0_3_bis = list(l0_3)
+        self.assertEqual(l0_3, l0_3_bis)
+        self.assert_(l0_3 is not l0_3_bis)
+        self.assertEqual(list(()), [])
+        self.assertEqual(list((0, 1, 2, 3)), [0, 1, 2, 3])
+        self.assertEqual(list(''), [])
+        self.assertEqual(list('spam'), ['s', 'p', 'a', 'm'])
+
+        if sys.maxint == 0x7fffffff:
+            # This test can currently only work on 32-bit machines.
+            # XXX If/when PySequence_Length() returns a ssize_t, it should be
+            # XXX re-enabled.
+            # Verify clearing of bug #556025.
+            # This assumes that the max data size (sys.maxint) == max
+            # address size this also assumes that the address size is at
+            # least 4 bytes with 8 byte addresses, the bug is not well
+            # tested
+            #
+            # Note: This test is expected to SEGV under Cygwin 1.3.12 or
+            # earlier due to a newlib bug.  See the following mailing list
+            # thread for the details:
+
+            #     http://sources.redhat.com/ml/newlib/2002/msg00369.html
+            self.assertRaises(MemoryError, list, xrange(sys.maxint // 2))
+
+        # This code used to segfault in Py2.4a3
+        x = []
+        x.extend(-y for y in x)
+        self.assertEqual(x, [])
+
+    def test_long(self):
+        self.assertEqual(long(314), 314L)
+        self.assertEqual(long(3.14), 3L)
+        self.assertEqual(long(314L), 314L)
+        # Check that conversion from float truncates towards zero
+        self.assertEqual(long(-3.14), -3L)
+        self.assertEqual(long(3.9), 3L)
+        self.assertEqual(long(-3.9), -3L)
+        self.assertEqual(long(3.5), 3L)
+        self.assertEqual(long(-3.5), -3L)
+        self.assertEqual(long("-3"), -3L)
+        if have_unicode:
+            self.assertEqual(long(unicode("-3")), -3L)
+        # Different base:
+        self.assertEqual(long("10",16), 16L)
+        if have_unicode:
+            self.assertEqual(long(unicode("10"),16), 16L)
+        # Check conversions from string (same test set as for int(), and then some)
+        LL = [
+                ('1' + '0'*20, 10L**20),
+                ('1' + '0'*100, 10L**100)
+        ]
+        L2 = L[:]
+        if have_unicode:
+            L2 += [
+                (unicode('1') + unicode('0')*20, 10L**20),
+                (unicode('1') + unicode('0')*100, 10L**100),
+        ]
+        for s, v in L2 + LL:
+            for sign in "", "+", "-":
+                for prefix in "", " ", "\t", "  \t\t  ":
+                    ss = prefix + sign + s
+                    vv = v
+                    if sign == "-" and v is not ValueError:
+                        vv = -v
+                    try:
+                        self.assertEqual(long(ss), long(vv))
+                    except v:
+                        pass
+
+        self.assertRaises(ValueError, long, '123\0')
+        self.assertRaises(ValueError, long, '53', 40)
+        self.assertRaises(TypeError, long, 1, 12)
+
+        # SF patch #1638879: embedded NULs were not detected with
+        # explicit base
+        self.assertRaises(ValueError, long, '123\0', 10)
+        self.assertRaises(ValueError, long, '123\x00 245', 20)
+
+        self.assertEqual(long('100000000000000000000000000000000', 2),
+                         4294967296)
+        self.assertEqual(long('102002022201221111211', 3), 4294967296)
+        self.assertEqual(long('10000000000000000', 4), 4294967296)
+        self.assertEqual(long('32244002423141', 5), 4294967296)
+        self.assertEqual(long('1550104015504', 6), 4294967296)
+        self.assertEqual(long('211301422354', 7), 4294967296)
+        self.assertEqual(long('40000000000', 8), 4294967296)
+        self.assertEqual(long('12068657454', 9), 4294967296)
+        self.assertEqual(long('4294967296', 10), 4294967296)
+        self.assertEqual(long('1904440554', 11), 4294967296)
+        self.assertEqual(long('9ba461594', 12), 4294967296)
+        self.assertEqual(long('535a79889', 13), 4294967296)
+        self.assertEqual(long('2ca5b7464', 14), 4294967296)
+        self.assertEqual(long('1a20dcd81', 15), 4294967296)
+        self.assertEqual(long('100000000', 16), 4294967296)
+        self.assertEqual(long('a7ffda91', 17), 4294967296)
+        self.assertEqual(long('704he7g4', 18), 4294967296)
+        self.assertEqual(long('4f5aff66', 19), 4294967296)
+        self.assertEqual(long('3723ai4g', 20), 4294967296)
+        self.assertEqual(long('281d55i4', 21), 4294967296)
+        self.assertEqual(long('1fj8b184', 22), 4294967296)
+        self.assertEqual(long('1606k7ic', 23), 4294967296)
+        self.assertEqual(long('mb994ag', 24), 4294967296)
+        self.assertEqual(long('hek2mgl', 25), 4294967296)
+        self.assertEqual(long('dnchbnm', 26), 4294967296)
+        self.assertEqual(long('b28jpdm', 27), 4294967296)
+        self.assertEqual(long('8pfgih4', 28), 4294967296)
+        self.assertEqual(long('76beigg', 29), 4294967296)
+        self.assertEqual(long('5qmcpqg', 30), 4294967296)
+        self.assertEqual(long('4q0jto4', 31), 4294967296)
+        self.assertEqual(long('4000000', 32), 4294967296)
+        self.assertEqual(long('3aokq94', 33), 4294967296)
+        self.assertEqual(long('2qhxjli', 34), 4294967296)
+        self.assertEqual(long('2br45qb', 35), 4294967296)
+        self.assertEqual(long('1z141z4', 36), 4294967296)
+
+        self.assertEqual(long('100000000000000000000000000000001', 2),
+                         4294967297)
+        self.assertEqual(long('102002022201221111212', 3), 4294967297)
+        self.assertEqual(long('10000000000000001', 4), 4294967297)
+        self.assertEqual(long('32244002423142', 5), 4294967297)
+        self.assertEqual(long('1550104015505', 6), 4294967297)
+        self.assertEqual(long('211301422355', 7), 4294967297)
+        self.assertEqual(long('40000000001', 8), 4294967297)
+        self.assertEqual(long('12068657455', 9), 4294967297)
+        self.assertEqual(long('4294967297', 10), 4294967297)
+        self.assertEqual(long('1904440555', 11), 4294967297)
+        self.assertEqual(long('9ba461595', 12), 4294967297)
+        self.assertEqual(long('535a7988a', 13), 4294967297)
+        self.assertEqual(long('2ca5b7465', 14), 4294967297)
+        self.assertEqual(long('1a20dcd82', 15), 4294967297)
+        self.assertEqual(long('100000001', 16), 4294967297)
+        self.assertEqual(long('a7ffda92', 17), 4294967297)
+        self.assertEqual(long('704he7g5', 18), 4294967297)
+        self.assertEqual(long('4f5aff67', 19), 4294967297)
+        self.assertEqual(long('3723ai4h', 20), 4294967297)
+        self.assertEqual(long('281d55i5', 21), 4294967297)
+        self.assertEqual(long('1fj8b185', 22), 4294967297)
+        self.assertEqual(long('1606k7id', 23), 4294967297)
+        self.assertEqual(long('mb994ah', 24), 4294967297)
+        self.assertEqual(long('hek2mgm', 25), 4294967297)
+        self.assertEqual(long('dnchbnn', 26), 4294967297)
+        self.assertEqual(long('b28jpdn', 27), 4294967297)
+        self.assertEqual(long('8pfgih5', 28), 4294967297)
+        self.assertEqual(long('76beigh', 29), 4294967297)
+        self.assertEqual(long('5qmcpqh', 30), 4294967297)
+        self.assertEqual(long('4q0jto5', 31), 4294967297)
+        self.assertEqual(long('4000001', 32), 4294967297)
+        self.assertEqual(long('3aokq95', 33), 4294967297)
+        self.assertEqual(long('2qhxjlj', 34), 4294967297)
+        self.assertEqual(long('2br45qc', 35), 4294967297)
+        self.assertEqual(long('1z141z5', 36), 4294967297)
+
+
+    def test_longconversion(self):
+        # Test __long__()
+        class Foo0:
+            def __long__(self):
+                return 42L
+
+        class Foo1(object):
+            def __long__(self):
+                return 42L
+
+        class Foo2(long):
+            def __long__(self):
+                return 42L
+
+        class Foo3(long):
+            def __long__(self):
+                return self
+
+        class Foo4(long):
+            def __long__(self):
+                return 42
+
+        class Foo5(long):
+            def __long__(self):
+                return 42.
+
+        self.assertEqual(long(Foo0()), 42L)
+        self.assertEqual(long(Foo1()), 42L)
+        self.assertEqual(long(Foo2()), 42L)
+        self.assertEqual(long(Foo3()), 0)
+        self.assertEqual(long(Foo4()), 42)
+        self.assertRaises(TypeError, long, Foo5())
+
+    def test_map(self):
+        self.assertEqual(
+            map(None, 'hello world'),
+            ['h','e','l','l','o',' ','w','o','r','l','d']
+        )
+        self.assertEqual(
+            map(None, 'abcd', 'efg'),
+            [('a', 'e'), ('b', 'f'), ('c', 'g'), ('d', None)]
+        )
+        self.assertEqual(
+            map(None, range(10)),
+            [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+        )
+        self.assertEqual(
+            map(lambda x: x*x, range(1,4)),
+            [1, 4, 9]
+        )
+        try:
+            from math import sqrt
+        except ImportError:
+            def sqrt(x):
+                return pow(x, 0.5)
+        self.assertEqual(
+            map(lambda x: map(sqrt,x), [[16, 4], [81, 9]]),
+            [[4.0, 2.0], [9.0, 3.0]]
+        )
+        self.assertEqual(
+            map(lambda x, y: x+y, [1,3,2], [9,1,4]),
+            [10, 4, 6]
+        )
+
+        def plus(*v):
+            accu = 0
+            for i in v: accu = accu + i
+            return accu
+        self.assertEqual(
+            map(plus, [1, 3, 7]),
+            [1, 3, 7]
+        )
+        self.assertEqual(
+            map(plus, [1, 3, 7], [4, 9, 2]),
+            [1+4, 3+9, 7+2]
+        )
+        self.assertEqual(
+            map(plus, [1, 3, 7], [4, 9, 2], [1, 1, 0]),
+            [1+4+1, 3+9+1, 7+2+0]
+        )
+        self.assertEqual(
+            map(None, Squares(10)),
+            [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
+        )
+        self.assertEqual(
+            map(int, Squares(10)),
+            [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
+        )
+        self.assertEqual(
+            map(None, Squares(3), Squares(2)),
+            [(0,0), (1,1), (4,None)]
+        )
+        self.assertEqual(
+            map(max, Squares(3), Squares(2)),
+            [0, 1, 4]
+        )
+        self.assertRaises(TypeError, map)
+        self.assertRaises(TypeError, map, lambda x: x, 42)
+        self.assertEqual(map(None, [42]), [42])
+        class BadSeq:
+            def __getitem__(self, index):
+                raise ValueError
+        self.assertRaises(ValueError, map, lambda x: x, BadSeq())
+        def badfunc(x):
+            raise RuntimeError
+        self.assertRaises(RuntimeError, map, badfunc, range(5))
+
+    def test_max(self):
+        self.assertEqual(max('123123'), '3')
+        self.assertEqual(max(1, 2, 3), 3)
+        self.assertEqual(max((1, 2, 3, 1, 2, 3)), 3)
+        self.assertEqual(max([1, 2, 3, 1, 2, 3]), 3)
+
+        self.assertEqual(max(1, 2L, 3.0), 3.0)
+        self.assertEqual(max(1L, 2.0, 3), 3)
+        self.assertEqual(max(1.0, 2, 3L), 3L)
+
+        for stmt in (
+            "max(key=int)",                 # no args
+            "max(1, key=int)",              # single arg not iterable
+            "max(1, 2, keystone=int)",      # wrong keyword
+            "max(1, 2, key=int, abc=int)",  # two many keywords
+            "max(1, 2, key=1)",             # keyfunc is not callable
+            ):
+            try:
+                exec(stmt) in globals()
+            except TypeError:
+                pass
+            else:
+                self.fail(stmt)
+
+        self.assertEqual(max((1,), key=neg), 1)     # one elem iterable
+        self.assertEqual(max((1,2), key=neg), 1)    # two elem iterable
+        self.assertEqual(max(1, 2, key=neg), 1)     # two elems
+
+        data = [random.randrange(200) for i in range(100)]
+        keys = dict((elem, random.randrange(50)) for elem in data)
+        f = keys.__getitem__
+        self.assertEqual(max(data, key=f),
+                         sorted(reversed(data), key=f)[-1])
+
+    def test_min(self):
+        self.assertEqual(min('123123'), '1')
+        self.assertEqual(min(1, 2, 3), 1)
+        self.assertEqual(min((1, 2, 3, 1, 2, 3)), 1)
+        self.assertEqual(min([1, 2, 3, 1, 2, 3]), 1)
+
+        self.assertEqual(min(1, 2L, 3.0), 1)
+        self.assertEqual(min(1L, 2.0, 3), 1L)
+        self.assertEqual(min(1.0, 2, 3L), 1.0)
+
+        self.assertRaises(TypeError, min)
+        self.assertRaises(TypeError, min, 42)
+        self.assertRaises(ValueError, min, ())
+        class BadSeq:
+            def __getitem__(self, index):
+                raise ValueError
+        self.assertRaises(ValueError, min, BadSeq())
+        class BadNumber:
+            def __cmp__(self, other):
+                raise ValueError
+        self.assertRaises(ValueError, min, (42, BadNumber()))
+
+        for stmt in (
+            "min(key=int)",                 # no args
+            "min(1, key=int)",              # single arg not iterable
+            "min(1, 2, keystone=int)",      # wrong keyword
+            "min(1, 2, key=int, abc=int)",  # two many keywords
+            "min(1, 2, key=1)",             # keyfunc is not callable
+            ):
+            try:
+                exec(stmt) in globals()
+            except TypeError:
+                pass
+            else:
+                self.fail(stmt)
+
+        self.assertEqual(min((1,), key=neg), 1)     # one elem iterable
+        self.assertEqual(min((1,2), key=neg), 2)    # two elem iterable
+        self.assertEqual(min(1, 2, key=neg), 2)     # two elems
+
+        data = [random.randrange(200) for i in range(100)]
+        keys = dict((elem, random.randrange(50)) for elem in data)
+        f = keys.__getitem__
+        self.assertEqual(min(data, key=f),
+                         sorted(data, key=f)[0])
+
+    def test_oct(self):
+        self.assertEqual(oct(100), '0144')
+        self.assertEqual(oct(100L), '0144L')
+        self.assertEqual(oct(-100), '-0144')
+        self.assertEqual(oct(-100L), '-0144L')
+        self.assertRaises(TypeError, oct, ())
+
+    def write_testfile(self):
+        # NB the first 4 lines are also used to test input and raw_input, below
+        fp = open(TESTFN, 'w')
+        try:
+            fp.write('1+1\n')
+            fp.write('1+1\n')
+            fp.write('The quick brown fox jumps over the lazy dog')
+            fp.write('.\n')
+            fp.write('Dear John\n')
+            fp.write('XXX'*100)
+            fp.write('YYY'*100)
+        finally:
+            fp.close()
+
+    def test_open(self):
+        self.write_testfile()
+        fp = open(TESTFN, 'r')
+        try:
+            self.assertEqual(fp.readline(4), '1+1\n')
+            self.assertEqual(fp.readline(4), '1+1\n')
+            self.assertEqual(fp.readline(), 'The quick brown fox jumps over the lazy dog.\n')
+            self.assertEqual(fp.readline(4), 'Dear')
+            self.assertEqual(fp.readline(100), ' John\n')
+            self.assertEqual(fp.read(300), 'XXX'*100)
+            self.assertEqual(fp.read(1000), 'YYY'*100)
+        finally:
+            fp.close()
+        unlink(TESTFN)
+
+    def test_ord(self):
+        self.assertEqual(ord(' '), 32)
+        self.assertEqual(ord('A'), 65)
+        self.assertEqual(ord('a'), 97)
+        if have_unicode:
+            self.assertEqual(ord(unichr(sys.maxunicode)), sys.maxunicode)
+        self.assertRaises(TypeError, ord, 42)
+        if have_unicode:
+            self.assertRaises(TypeError, ord, unicode("12"))
+
+    def test_pow(self):
+        self.assertEqual(pow(0,0), 1)
+        self.assertEqual(pow(0,1), 0)
+        self.assertEqual(pow(1,0), 1)
+        self.assertEqual(pow(1,1), 1)
+
+        self.assertEqual(pow(2,0), 1)
+        self.assertEqual(pow(2,10), 1024)
+        self.assertEqual(pow(2,20), 1024*1024)
+        self.assertEqual(pow(2,30), 1024*1024*1024)
+
+        self.assertEqual(pow(-2,0), 1)
+        self.assertEqual(pow(-2,1), -2)
+        self.assertEqual(pow(-2,2), 4)
+        self.assertEqual(pow(-2,3), -8)
+
+        self.assertEqual(pow(0L,0), 1)
+        self.assertEqual(pow(0L,1), 0)
+        self.assertEqual(pow(1L,0), 1)
+        self.assertEqual(pow(1L,1), 1)
+
+        self.assertEqual(pow(2L,0), 1)
+        self.assertEqual(pow(2L,10), 1024)
+        self.assertEqual(pow(2L,20), 1024*1024)
+        self.assertEqual(pow(2L,30), 1024*1024*1024)
+
+        self.assertEqual(pow(-2L,0), 1)
+        self.assertEqual(pow(-2L,1), -2)
+        self.assertEqual(pow(-2L,2), 4)
+        self.assertEqual(pow(-2L,3), -8)
+
+        self.assertAlmostEqual(pow(0.,0), 1.)
+        self.assertAlmostEqual(pow(0.,1), 0.)
+        self.assertAlmostEqual(pow(1.,0), 1.)
+        self.assertAlmostEqual(pow(1.,1), 1.)
+
+        self.assertAlmostEqual(pow(2.,0), 1.)
+        self.assertAlmostEqual(pow(2.,10), 1024.)
+        self.assertAlmostEqual(pow(2.,20), 1024.*1024.)
+        self.assertAlmostEqual(pow(2.,30), 1024.*1024.*1024.)
+
+        self.assertAlmostEqual(pow(-2.,0), 1.)
+        self.assertAlmostEqual(pow(-2.,1), -2.)
+        self.assertAlmostEqual(pow(-2.,2), 4.)
+        self.assertAlmostEqual(pow(-2.,3), -8.)
+
+        for x in 2, 2L, 2.0:
+            for y in 10, 10L, 10.0:
+                for z in 1000, 1000L, 1000.0:
+                    if isinstance(x, float) or \
+                       isinstance(y, float) or \
+                       isinstance(z, float):
+                        self.assertRaises(TypeError, pow, x, y, z)
+                    else:
+                        self.assertAlmostEqual(pow(x, y, z), 24.0)
+
+        self.assertRaises(TypeError, pow, -1, -2, 3)
+        self.assertRaises(ValueError, pow, 1, 2, 0)
+        self.assertRaises(TypeError, pow, -1L, -2L, 3L)
+        self.assertRaises(ValueError, pow, 1L, 2L, 0L)
+        self.assertRaises(ValueError, pow, -342.43, 0.234)
+
+        self.assertRaises(TypeError, pow)
+
+    def test_range(self):
+        self.assertEqual(range(3), [0, 1, 2])
+        self.assertEqual(range(1, 5), [1, 2, 3, 4])
+        self.assertEqual(range(0), [])
+        self.assertEqual(range(-3), [])
+        self.assertEqual(range(1, 10, 3), [1, 4, 7])
+        self.assertEqual(range(5, -5, -3), [5, 2, -1, -4])
+
+        # Now test range() with longs
+        self.assertEqual(range(-2**100), [])
+        self.assertEqual(range(0, -2**100), [])
+        self.assertEqual(range(0, 2**100, -1), [])
+        self.assertEqual(range(0, 2**100, -1), [])
+
+        a = long(10 * sys.maxint)
+        b = long(100 * sys.maxint)
+        c = long(50 * sys.maxint)
+
+        self.assertEqual(range(a, a+2), [a, a+1])
+        self.assertEqual(range(a+2, a, -1L), [a+2, a+1])
+        self.assertEqual(range(a+4, a, -2), [a+4, a+2])
+
+        seq = range(a, b, c)
+        self.assert_(a in seq)
+        self.assert_(b not in seq)
+        self.assertEqual(len(seq), 2)
+
+        seq = range(b, a, -c)
+        self.assert_(b in seq)
+        self.assert_(a not in seq)
+        self.assertEqual(len(seq), 2)
+
+        seq = range(-a, -b, -c)
+        self.assert_(-a in seq)
+        self.assert_(-b not in seq)
+        self.assertEqual(len(seq), 2)
+
+        self.assertRaises(TypeError, range)
+        self.assertRaises(TypeError, range, 1, 2, 3, 4)
+        self.assertRaises(ValueError, range, 1, 2, 0)
+        self.assertRaises(ValueError, range, a, a + 1, long(0))
+
+        class badzero(int):
+            def __cmp__(self, other):
+                raise RuntimeError
+        self.assertRaises(RuntimeError, range, a, a + 1, badzero(1))
+
+        # Reject floats when it would require PyLongs to represent.
+        # (smaller floats still accepted, but deprecated)
+        self.assertRaises(TypeError, range, 1e100, 1e101, 1e101)
+
+        self.assertRaises(TypeError, range, 0, "spam")
+        self.assertRaises(TypeError, range, 0, 42, "spam")
+
+        self.assertRaises(OverflowError, range, -sys.maxint, sys.maxint)
+        self.assertRaises(OverflowError, range, 0, 2*sys.maxint)
+
+    def test_input_and_raw_input(self):
+        self.write_testfile()
+        fp = open(TESTFN, 'r')
+        savestdin = sys.stdin
+        savestdout = sys.stdout # Eats the echo
+        try:
+            sys.stdin = fp
+            sys.stdout = BitBucket()
+            self.assertEqual(input(), 2)
+            self.assertEqual(input('testing\n'), 2)
+            self.assertEqual(raw_input(), 'The quick brown fox jumps over the lazy dog.')
+            self.assertEqual(raw_input('testing\n'), 'Dear John')
+
+            # SF 1535165: don't segfault on closed stdin
+            # sys.stdout must be a regular file for triggering
+            sys.stdout = savestdout
+            sys.stdin.close()
+            self.assertRaises(ValueError, input)
+
+            sys.stdout = BitBucket()
+            sys.stdin = cStringIO.StringIO("NULL\0")
+            self.assertRaises(TypeError, input, 42, 42)
+            sys.stdin = cStringIO.StringIO("    'whitespace'")
+            self.assertEqual(input(), 'whitespace')
+            sys.stdin = cStringIO.StringIO()
+            self.assertRaises(EOFError, input)
+
+            # SF 876178: make sure input() respect future options.
+            sys.stdin = cStringIO.StringIO('1/2')
+            sys.stdout = cStringIO.StringIO()
+            exec compile('print input()', 'test_builtin_tmp', 'exec')
+            sys.stdin.seek(0, 0)
+            exec compile('from __future__ import division;print input()',
+                         'test_builtin_tmp', 'exec')
+            sys.stdin.seek(0, 0)
+            exec compile('print input()', 'test_builtin_tmp', 'exec')
+            # The result we expect depends on whether new division semantics
+            # are already in effect.
+            if 1/2 == 0:
+                # This test was compiled with old semantics.
+                expected = ['0', '0.5', '0']
+            else:
+                # This test was compiled with new semantics (e.g., -Qnew
+                # was given on the command line.
+                expected = ['0.5', '0.5', '0.5']
+            self.assertEqual(sys.stdout.getvalue().splitlines(), expected)
+
+            del sys.stdout
+            self.assertRaises(RuntimeError, input, 'prompt')
+            del sys.stdin
+            self.assertRaises(RuntimeError, input, 'prompt')
+        finally:
+            sys.stdin = savestdin
+            sys.stdout = savestdout
+            fp.close()
+            unlink(TESTFN)
+
+    def test_reduce(self):
+        self.assertEqual(reduce(lambda x, y: x+y, ['a', 'b', 'c'], ''), 'abc')
+        self.assertEqual(
+            reduce(lambda x, y: x+y, [['a', 'c'], [], ['d', 'w']], []),
+            ['a','c','d','w']
+        )
+        self.assertEqual(reduce(lambda x, y: x*y, range(2,8), 1), 5040)
+        self.assertEqual(
+            reduce(lambda x, y: x*y, range(2,21), 1L),
+            2432902008176640000L
+        )
+        self.assertEqual(reduce(lambda x, y: x+y, Squares(10)), 285)
+        self.assertEqual(reduce(lambda x, y: x+y, Squares(10), 0), 285)
+        self.assertEqual(reduce(lambda x, y: x+y, Squares(0), 0), 0)
+        self.assertRaises(TypeError, reduce)
+        self.assertRaises(TypeError, reduce, 42, 42)
+        self.assertRaises(TypeError, reduce, 42, 42, 42)
+        self.assertEqual(reduce(42, "1"), "1") # func is never called with one item
+        self.assertEqual(reduce(42, "", "1"), "1") # func is never called with one item
+        self.assertRaises(TypeError, reduce, 42, (42, 42))
+
+        class BadSeq:
+            def __getitem__(self, index):
+                raise ValueError
+        self.assertRaises(ValueError, reduce, 42, BadSeq())
+
+    def test_reload(self):
+        import marshal
+        reload(marshal)
+        import string
+        reload(string)
+        ## import sys
+        ## self.assertRaises(ImportError, reload, sys)
+
+    def test_repr(self):
+        self.assertEqual(repr(''), '\'\'')
+        self.assertEqual(repr(0), '0')
+        self.assertEqual(repr(0L), '0L')
+        self.assertEqual(repr(()), '()')
+        self.assertEqual(repr([]), '[]')
+        self.assertEqual(repr({}), '{}')
+        a = []
+        a.append(a)
+        self.assertEqual(repr(a), '[[...]]')
+        a = {}
+        a[0] = a
+        self.assertEqual(repr(a), '{0: {...}}')
+
+    def test_round(self):
+        self.assertEqual(round(0.0), 0.0)
+        self.assertEqual(round(1.0), 1.0)
+        self.assertEqual(round(10.0), 10.0)
+        self.assertEqual(round(1000000000.0), 1000000000.0)
+        self.assertEqual(round(1e20), 1e20)
+
+        self.assertEqual(round(-1.0), -1.0)
+        self.assertEqual(round(-10.0), -10.0)
+        self.assertEqual(round(-1000000000.0), -1000000000.0)
+        self.assertEqual(round(-1e20), -1e20)
+
+        self.assertEqual(round(0.1), 0.0)
+        self.assertEqual(round(1.1), 1.0)
+        self.assertEqual(round(10.1), 10.0)
+        self.assertEqual(round(1000000000.1), 1000000000.0)
+
+        self.assertEqual(round(-1.1), -1.0)
+        self.assertEqual(round(-10.1), -10.0)
+        self.assertEqual(round(-1000000000.1), -1000000000.0)
+
+        self.assertEqual(round(0.9), 1.0)
+        self.assertEqual(round(9.9), 10.0)
+        self.assertEqual(round(999999999.9), 1000000000.0)
+
+        self.assertEqual(round(-0.9), -1.0)
+        self.assertEqual(round(-9.9), -10.0)
+        self.assertEqual(round(-999999999.9), -1000000000.0)
+
+        self.assertEqual(round(-8.0, -1), -10.0)
+
+        # test new kwargs
+        self.assertEqual(round(number=-8.0, ndigits=-1), -10.0)
+
+        self.assertRaises(TypeError, round)
+
+    def test_setattr(self):
+        setattr(sys, 'spam', 1)
+        self.assertEqual(sys.spam, 1)
+        self.assertRaises(TypeError, setattr, sys, 1, 'spam')
+        self.assertRaises(TypeError, setattr)
+
+    def test_str(self):
+        self.assertEqual(str(''), '')
+        self.assertEqual(str(0), '0')
+        self.assertEqual(str(0L), '0')
+        self.assertEqual(str(()), '()')
+        self.assertEqual(str([]), '[]')
+        self.assertEqual(str({}), '{}')
+        a = []
+        a.append(a)
+        self.assertEqual(str(a), '[[...]]')
+        a = {}
+        a[0] = a
+        self.assertEqual(str(a), '{0: {...}}')
+
+    def test_sum(self):
+        self.assertEqual(sum([]), 0)
+        self.assertEqual(sum(range(2,8)), 27)
+        self.assertEqual(sum(iter(range(2,8))), 27)
+        self.assertEqual(sum(Squares(10)), 285)
+        self.assertEqual(sum(iter(Squares(10))), 285)
+        self.assertEqual(sum([[1], [2], [3]], []), [1, 2, 3])
+
+        self.assertRaises(TypeError, sum)
+        self.assertRaises(TypeError, sum, 42)
+        self.assertRaises(TypeError, sum, ['a', 'b', 'c'])
+        self.assertRaises(TypeError, sum, ['a', 'b', 'c'], '')
+        self.assertRaises(TypeError, sum, [[1], [2], [3]])
+        self.assertRaises(TypeError, sum, [{2:3}])
+        self.assertRaises(TypeError, sum, [{2:3}]*2, {2:3})
+
+        class BadSeq:
+            def __getitem__(self, index):
+                raise ValueError
+        self.assertRaises(ValueError, sum, BadSeq())
+
+    def test_tuple(self):
+        self.assertEqual(tuple(()), ())
+        t0_3 = (0, 1, 2, 3)
+        t0_3_bis = tuple(t0_3)
+        self.assert_(t0_3 is t0_3_bis)
+        self.assertEqual(tuple([]), ())
+        self.assertEqual(tuple([0, 1, 2, 3]), (0, 1, 2, 3))
+        self.assertEqual(tuple(''), ())
+        self.assertEqual(tuple('spam'), ('s', 'p', 'a', 'm'))
+
+    def test_type(self):
+        self.assertEqual(type(''),  type('123'))
+        self.assertNotEqual(type(''), type(()))
+
+    def test_unichr(self):
+        if have_unicode:
+            self.assertEqual(unichr(32), unicode(' '))
+            self.assertEqual(unichr(65), unicode('A'))
+            self.assertEqual(unichr(97), unicode('a'))
+            self.assertEqual(
+                unichr(sys.maxunicode),
+                unicode('\\U%08x' % (sys.maxunicode), 'unicode-escape')
+            )
+            self.assertRaises(ValueError, unichr, sys.maxunicode+1)
+            self.assertRaises(TypeError, unichr)
+
+    # We don't want self in vars(), so these are static methods
+
+    @staticmethod
+    def get_vars_f0():
+        return vars()
+
+    @staticmethod
+    def get_vars_f2():
+        BuiltinTest.get_vars_f0()
+        a = 1
+        b = 2
+        return vars()
+
+    def test_vars(self):
+        self.assertEqual(set(vars()), set(dir()))
+        import sys
+        self.assertEqual(set(vars(sys)), set(dir(sys)))
+        self.assertEqual(self.get_vars_f0(), {})
+        self.assertEqual(self.get_vars_f2(), {'a': 1, 'b': 2})
+        self.assertRaises(TypeError, vars, 42, 42)
+        self.assertRaises(TypeError, vars, 42)
+
+    def test_zip(self):
+        a = (1, 2, 3)
+        b = (4, 5, 6)
+        t = [(1, 4), (2, 5), (3, 6)]
+        self.assertEqual(zip(a, b), t)
+        b = [4, 5, 6]
+        self.assertEqual(zip(a, b), t)
+        b = (4, 5, 6, 7)
+        self.assertEqual(zip(a, b), t)
+        class I:
+            def __getitem__(self, i):
+                if i < 0 or i > 2: raise IndexError
+                return i + 4
+        self.assertEqual(zip(a, I()), t)
+        self.assertEqual(zip(), [])
+        self.assertEqual(zip(*[]), [])
+        self.assertRaises(TypeError, zip, None)
+        class G:
+            pass
+        self.assertRaises(TypeError, zip, a, G())
+
+        # Make sure zip doesn't try to allocate a billion elements for the
+        # result list when one of its arguments doesn't say how long it is.
+        # A MemoryError is the most likely failure mode.
+        class SequenceWithoutALength:
+            def __getitem__(self, i):
+                if i == 5:
+                    raise IndexError
+                else:
+                    return i
+        self.assertEqual(
+            zip(SequenceWithoutALength(), xrange(2**30)),
+            list(enumerate(range(5)))
+        )
+
+        class BadSeq:
+            def __getitem__(self, i):
+                if i == 5:
+                    raise ValueError
+                else:
+                    return i
+        self.assertRaises(ValueError, zip, BadSeq(), BadSeq())
+
+class TestSorted(unittest.TestCase):
+
+    def test_basic(self):
+        data = range(100)
+        copy = data[:]
+        random.shuffle(copy)
+        self.assertEqual(data, sorted(copy))
+        self.assertNotEqual(data, copy)
+
+        data.reverse()
+        random.shuffle(copy)
+        self.assertEqual(data, sorted(copy, cmp=lambda x, y: cmp(y,x)))
+        self.assertNotEqual(data, copy)
+        random.shuffle(copy)
+        self.assertEqual(data, sorted(copy, key=lambda x: -x))
+        self.assertNotEqual(data, copy)
+        random.shuffle(copy)
+        self.assertEqual(data, sorted(copy, reverse=1))
+        self.assertNotEqual(data, copy)
+
+    def test_inputtypes(self):
+        s = 'abracadabra'
+        types = [list, tuple]
+        if have_unicode:
+            types.insert(0, unicode)
+        for T in types:
+            self.assertEqual(sorted(s), sorted(T(s)))
+
+        s = ''.join(dict.fromkeys(s).keys())  # unique letters only
+        types = [set, frozenset, list, tuple, dict.fromkeys]
+        if have_unicode:
+            types.insert(0, unicode)
+        for T in types:
+            self.assertEqual(sorted(s), sorted(T(s)))
+
+    def test_baddecorator(self):
+        data = 'The quick Brown fox Jumped over The lazy Dog'.split()
+        self.assertRaises(TypeError, sorted, data, None, lambda x,y: 0)
+
+def test_main(verbose=None):
+    test_classes = (BuiltinTest, TestSorted)
+
+    run_unittest(*test_classes)
+
+    # verify reference counting
+    if verbose and hasattr(sys, "gettotalrefcount"):
+        import gc
+        counts = [None] * 5
+        for i in xrange(len(counts)):
+            run_unittest(*test_classes)
+            gc.collect()
+            counts[i] = sys.gettotalrefcount()
+        print counts
+
+
+if __name__ == "__main__":
+    test_main(verbose=True)

Added: vendor/Python/current/Lib/test/test_bz2.py
===================================================================
--- vendor/Python/current/Lib/test/test_bz2.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_bz2.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,371 @@
+#!/usr/bin/python
+from test import test_support
+from test.test_support import TESTFN
+
+import unittest
+from cStringIO import StringIO
+import os
+import popen2
+import sys
+
+import bz2
+from bz2 import BZ2File, BZ2Compressor, BZ2Decompressor
+
+has_cmdline_bunzip2 = sys.platform not in ("win32", "os2emx", "riscos")
+
+class BaseTest(unittest.TestCase):
+    "Base for other testcases."
+    TEXT = 'root:x:0:0:root:/root:/bin/bash\nbin:x:1:1:bin:/bin:\ndaemon:x:2:2:daemon:/sbin:\nadm:x:3:4:adm:/var/adm:\nlp:x:4:7:lp:/var/spool/lpd:\nsync:x:5:0:sync:/sbin:/bin/sync\nshutdown:x:6:0:shutdown:/sbin:/sbin/shutdown\nhalt:x:7:0:halt:/sbin:/sbin/halt\nmail:x:8:12:mail:/var/spool/mail:\nnews:x:9:13:news:/var/spool/news:\nuucp:x:10:14:uucp:/var/spool/uucp:\noperator:x:11:0:operator:/root:\ngames:x:12:100:games:/usr/games:\ngopher:x:13:30:gopher:/usr/lib/gopher-data:\nftp:x:14:50:FTP User:/var/ftp:/bin/bash\nnobody:x:65534:65534:Nobody:/home:\npostfix:x:100:101:postfix:/var/spool/postfix:\nniemeyer:x:500:500::/home/niemeyer:/bin/bash\npostgres:x:101:102:PostgreSQL Server:/var/lib/pgsql:/bin/bash\nmysql:x:102:103:MySQL server:/var/lib/mysql:/bin/bash\nwww:x:103:104::/var/www:/bin/false\n'
+    DATA = 'BZh91AY&SY.\xc8N\x18\x00\x01>_\x80\x00\x10@\x02\xff\xf0\x01\x07n\x00?\xe7\xff\xe00\x01\x99\xaa\x00\xc0\x03F\x86\x8c#&\x83F\x9a\x03\x06\xa6\xd0\xa6\x93M\x0fQ\xa7\xa8\x06\x804hh\x12$\x11\xa4i4\xf14S\xd2<Q\xb5\x0fH\xd3\xd4\xdd\xd5\x87\xbb\xf8\x94\r\x8f\xafI\x12\xe1\xc9\xf8/E\x00pu\x89\x12]\xc9\xbbDL\nQ\x0e\t1\x12\xdf\xa0\xc0\x97\xac2O9\x89\x13\x94\x0e\x1c7\x0ed\x95I\x0c\xaaJ\xa4\x18L\x10\x05#\x9c\xaf\xba\xbc/\x97\x8a#C\xc8\xe1\x8cW\xf9\xe2\xd0\xd6M\xa7\x8bXa<e\x84t\xcbL\xb3\xa7\xd9\xcd\xd1\xcb\x84.\xaf\xb3\xab\xab\xad`n}\xa0lh\tE,\x8eZ\x15\x17VH>\x88\xe5\xcd9gd6\x0b\n\xe9\x9b\xd5\x8a\x99\xf7\x08.K\x8ev\xfb\xf7xw\xbb\xdf\xa1\x92\xf1\xdd|/";\xa2\xba\x9f\xd5\xb1#A\xb6\xf6\xb3o\xc9\xc5y\\\xebO\xe7\x85\x9a\xbc\xb6f8\x952\xd5\xd7"%\x89>V,\xf7\xa6z\xe2\x9f\xa3\xdf\x11\x11"\xd6E)I\xa9\x13^\xca\xf3r\xd0\x03U\x922\xf26\xec\xb6\xed\x8b\xc3U\x13\x9d\xc5\x170\xa4\xfa^\x92\xacDF\x8a\x97\xd6\x19\xfe\xdd\xb8\xbd\x1a\x9a\x19\xa3\x80ankR\x8b\xe5\xd83]\xa9\xc6\x08\x82f\xf6\xb9"6l$\xb8j@\xc0\x8a\xb0l1..\xbak\x83ls\x15\xbc\xf4\xc1\x13\xbe\xf8E\xb8\x9d\r\xa8\x9dk\x84\xd3n\xfa\xacQ\x07\xb1%y\xaav\xb4\x08\xe0z\x1b\x16\xf5\x04\xe9\xcc\xb9\x08z\x1en7.G\xfc]\xc9\x14\xe1B@\xbb!8`'
+    DATA_CRLF = 'BZh91AY&SY\xaez\xbbN\x00\x01H\xdf\x80\x00\x12@\x02\xff\xf0\x01\x07n\x00?\xe7\xff\xe0@\x01\xbc\xc6`\x86*\x8d=M\xa9\x9a\x86\xd0L@\x0fI\xa6!\xa1\x13\xc8\x88jdi\x8d@\x03@\x1a\x1a\x0c\x0c\x83 \x00\xc4h2\x19\x01\x82D\x84e\t\xe8\x99\x89\x19\x1ah\x00\r\x1a\x11\xaf\x9b\x0fG\xf5(\x1b\x1f?\t\x12\xcf\xb5\xfc\x95E\x00ps\x89\x12^\xa4\xdd\xa2&\x05(\x87\x04\x98\x89u\xe40%\xb6\x19\'\x8c\xc4\x89\xca\x07\x0e\x1b!\x91UIFU%C\x994!DI\xd2\xfa\xf0\xf1N8W\xde\x13A\xf5\x9cr%?\x9f3;I45A\xd1\x8bT\xb1<l\xba\xcb_\xc00xY\x17r\x17\x88\x08\x08@\xa0\ry@\x10\x04$)`\xf2\xce\x89z\xb0s\xec\x9b.iW\x9d\x81\xb5-+t\x9f\x1a\'\x97dB\xf5x\xb5\xbe.[.\xd7\x0e\x81\xe7\x08\x1cN`\x88\x10\xca\x87\xc3!"\x80\x92R\xa1/\xd1\xc0\xe6mf\xac\xbd\x99\xcca\xb3\x8780>\xa4\xc7\x8d\x1a\\"\xad\xa1\xabyBg\x15\xb9l\x88\x88\x91k"\x94\xa4\xd4\x89\xae*\xa6\x0b\x10\x0c\xd6\xd4m\xe86\xec\xb5j\x8a\x86j\';\xca.\x01I\xf2\xaaJ\xe8\x88\x8cU+t3\xfb\x0c\n\xa33\x13r2\r\x16\xe0\xb3(\xbf\x1d\x83r\xe7M\xf0D\x1365\xd8\x88\xd3\xa4\x92\xcb2\x06\x04\\\xc1\xb0\xea//\xbek&\xd8\xe6+t\xe5\xa1\x13\xada\x16\xder5"w]\xa2i\xb7[\x97R \xe2IT\xcd;Z\x04dk4\xad\x8a\t\xd3\x81z\x10\xf1:^`\xab\x1f\xc5\xdc\x91N\x14$+\x9e\xae\xd3\x80'
+
+    if has_cmdline_bunzip2:
+        def decompress(self, data):
+            pop = popen2.Popen3("bunzip2", capturestderr=1)
+            pop.tochild.write(data)
+            pop.tochild.close()
+            ret = pop.fromchild.read()
+            pop.fromchild.close()
+            if pop.wait() != 0:
+                ret = bz2.decompress(data)
+            return ret
+
+    else:
+        # popen2.Popen3 doesn't exist on Windows, and even if it did, bunzip2
+        # isn't available to run.
+        def decompress(self, data):
+            return bz2.decompress(data)
+
+class BZ2FileTest(BaseTest):
+    "Test BZ2File type miscellaneous methods."
+
+    def setUp(self):
+        self.filename = TESTFN
+
+    def tearDown(self):
+        if os.path.isfile(self.filename):
+            os.unlink(self.filename)
+
+    def createTempFile(self, crlf=0):
+        f = open(self.filename, "wb")
+        if crlf:
+            data = self.DATA_CRLF
+        else:
+            data = self.DATA
+        f.write(data)
+        f.close()
+
+    def testRead(self):
+        # "Test BZ2File.read()"
+        self.createTempFile()
+        bz2f = BZ2File(self.filename)
+        self.assertRaises(TypeError, bz2f.read, None)
+        self.assertEqual(bz2f.read(), self.TEXT)
+        bz2f.close()
+
+    def testReadChunk10(self):
+        # "Test BZ2File.read() in chunks of 10 bytes"
+        self.createTempFile()
+        bz2f = BZ2File(self.filename)
+        text = ''
+        while 1:
+            str = bz2f.read(10)
+            if not str:
+                break
+            text += str
+        self.assertEqual(text, text)
+        bz2f.close()
+
+    def testRead100(self):
+        # "Test BZ2File.read(100)"
+        self.createTempFile()
+        bz2f = BZ2File(self.filename)
+        self.assertEqual(bz2f.read(100), self.TEXT[:100])
+        bz2f.close()
+
+    def testReadLine(self):
+        # "Test BZ2File.readline()"
+        self.createTempFile()
+        bz2f = BZ2File(self.filename)
+        self.assertRaises(TypeError, bz2f.readline, None)
+        sio = StringIO(self.TEXT)
+        for line in sio.readlines():
+            self.assertEqual(bz2f.readline(), line)
+        bz2f.close()
+
+    def testReadLines(self):
+        # "Test BZ2File.readlines()"
+        self.createTempFile()
+        bz2f = BZ2File(self.filename)
+        self.assertRaises(TypeError, bz2f.readlines, None)
+        sio = StringIO(self.TEXT)
+        self.assertEqual(bz2f.readlines(), sio.readlines())
+        bz2f.close()
+
+    def testIterator(self):
+        # "Test iter(BZ2File)"
+        self.createTempFile()
+        bz2f = BZ2File(self.filename)
+        sio = StringIO(self.TEXT)
+        self.assertEqual(list(iter(bz2f)), sio.readlines())
+        bz2f.close()
+
+    def testXReadLines(self):
+        # "Test BZ2File.xreadlines()"
+        self.createTempFile()
+        bz2f = BZ2File(self.filename)
+        sio = StringIO(self.TEXT)
+        self.assertEqual(list(bz2f.xreadlines()), sio.readlines())
+        bz2f.close()
+
+    def testUniversalNewlinesLF(self):
+        # "Test BZ2File.read() with universal newlines (\\n)"
+        self.createTempFile()
+        bz2f = BZ2File(self.filename, "rU")
+        self.assertEqual(bz2f.read(), self.TEXT)
+        self.assertEqual(bz2f.newlines, "\n")
+        bz2f.close()
+
+    def testUniversalNewlinesCRLF(self):
+        # "Test BZ2File.read() with universal newlines (\\r\\n)"
+        self.createTempFile(crlf=1)
+        bz2f = BZ2File(self.filename, "rU")
+        self.assertEqual(bz2f.read(), self.TEXT)
+        self.assertEqual(bz2f.newlines, "\r\n")
+        bz2f.close()
+
+    def testWrite(self):
+        # "Test BZ2File.write()"
+        bz2f = BZ2File(self.filename, "w")
+        self.assertRaises(TypeError, bz2f.write)
+        bz2f.write(self.TEXT)
+        bz2f.close()
+        f = open(self.filename, 'rb')
+        self.assertEqual(self.decompress(f.read()), self.TEXT)
+        f.close()
+
+    def testWriteChunks10(self):
+        # "Test BZ2File.write() with chunks of 10 bytes"
+        bz2f = BZ2File(self.filename, "w")
+        n = 0
+        while 1:
+            str = self.TEXT[n*10:(n+1)*10]
+            if not str:
+                break
+            bz2f.write(str)
+            n += 1
+        bz2f.close()
+        f = open(self.filename, 'rb')
+        self.assertEqual(self.decompress(f.read()), self.TEXT)
+        f.close()
+
+    def testWriteLines(self):
+        # "Test BZ2File.writelines()"
+        bz2f = BZ2File(self.filename, "w")
+        self.assertRaises(TypeError, bz2f.writelines)
+        sio = StringIO(self.TEXT)
+        bz2f.writelines(sio.readlines())
+        bz2f.close()
+        # patch #1535500
+        self.assertRaises(ValueError, bz2f.writelines, ["a"])
+        f = open(self.filename, 'rb')
+        self.assertEqual(self.decompress(f.read()), self.TEXT)
+        f.close()
+
+    def testWriteMethodsOnReadOnlyFile(self):
+        bz2f = BZ2File(self.filename, "w")
+        bz2f.write("abc")
+        bz2f.close()
+
+        bz2f = BZ2File(self.filename, "r")
+        self.assertRaises(IOError, bz2f.write, "a")
+        self.assertRaises(IOError, bz2f.writelines, ["a"])
+
+    def testSeekForward(self):
+        # "Test BZ2File.seek(150, 0)"
+        self.createTempFile()
+        bz2f = BZ2File(self.filename)
+        self.assertRaises(TypeError, bz2f.seek)
+        bz2f.seek(150)
+        self.assertEqual(bz2f.read(), self.TEXT[150:])
+        bz2f.close()
+
+    def testSeekBackwards(self):
+        # "Test BZ2File.seek(-150, 1)"
+        self.createTempFile()
+        bz2f = BZ2File(self.filename)
+        bz2f.read(500)
+        bz2f.seek(-150, 1)
+        self.assertEqual(bz2f.read(), self.TEXT[500-150:])
+        bz2f.close()
+
+    def testSeekBackwardsFromEnd(self):
+        # "Test BZ2File.seek(-150, 2)"
+        self.createTempFile()
+        bz2f = BZ2File(self.filename)
+        bz2f.seek(-150, 2)
+        self.assertEqual(bz2f.read(), self.TEXT[len(self.TEXT)-150:])
+        bz2f.close()
+
+    def testSeekPostEnd(self):
+        # "Test BZ2File.seek(150000)"
+        self.createTempFile()
+        bz2f = BZ2File(self.filename)
+        bz2f.seek(150000)
+        self.assertEqual(bz2f.tell(), len(self.TEXT))
+        self.assertEqual(bz2f.read(), "")
+        bz2f.close()
+
+    def testSeekPostEndTwice(self):
+        # "Test BZ2File.seek(150000) twice"
+        self.createTempFile()
+        bz2f = BZ2File(self.filename)
+        bz2f.seek(150000)
+        bz2f.seek(150000)
+        self.assertEqual(bz2f.tell(), len(self.TEXT))
+        self.assertEqual(bz2f.read(), "")
+        bz2f.close()
+
+    def testSeekPreStart(self):
+        # "Test BZ2File.seek(-150, 0)"
+        self.createTempFile()
+        bz2f = BZ2File(self.filename)
+        bz2f.seek(-150)
+        self.assertEqual(bz2f.tell(), 0)
+        self.assertEqual(bz2f.read(), self.TEXT)
+        bz2f.close()
+
+    def testOpenDel(self):
+        # "Test opening and deleting a file many times"
+        self.createTempFile()
+        for i in xrange(10000):
+            o = BZ2File(self.filename)
+            del o
+
+    def testOpenNonexistent(self):
+        # "Test opening a nonexistent file"
+        self.assertRaises(IOError, BZ2File, "/non/existent")
+
+    def testModeU(self):
+        # Bug #1194181: bz2.BZ2File opened for write with mode "U"
+        self.createTempFile()
+        bz2f = BZ2File(self.filename, "U")
+        bz2f.close()
+        f = file(self.filename)
+        f.seek(0, 2)
+        self.assertEqual(f.tell(), len(self.DATA))
+        f.close()
+
+    def testBug1191043(self):
+        # readlines() for files containing no newline
+        data = 'BZh91AY&SY\xd9b\x89]\x00\x00\x00\x03\x80\x04\x00\x02\x00\x0c\x00 \x00!\x9ah3M\x13<]\xc9\x14\xe1BCe\x8a%t'
+        f = open(self.filename, "wb")
+        f.write(data)
+        f.close()
+        bz2f = BZ2File(self.filename)
+        lines = bz2f.readlines()
+        bz2f.close()
+        self.assertEqual(lines, ['Test'])
+        bz2f = BZ2File(self.filename)
+        xlines = list(bz2f.xreadlines())
+        bz2f.close()
+        self.assertEqual(xlines, ['Test'])
+
+
+class BZ2CompressorTest(BaseTest):
+    def testCompress(self):
+        # "Test BZ2Compressor.compress()/flush()"
+        bz2c = BZ2Compressor()
+        self.assertRaises(TypeError, bz2c.compress)
+        data = bz2c.compress(self.TEXT)
+        data += bz2c.flush()
+        self.assertEqual(self.decompress(data), self.TEXT)
+
+    def testCompressChunks10(self):
+        # "Test BZ2Compressor.compress()/flush() with chunks of 10 bytes"
+        bz2c = BZ2Compressor()
+        n = 0
+        data = ''
+        while 1:
+            str = self.TEXT[n*10:(n+1)*10]
+            if not str:
+                break
+            data += bz2c.compress(str)
+            n += 1
+        data += bz2c.flush()
+        self.assertEqual(self.decompress(data), self.TEXT)
+
+class BZ2DecompressorTest(BaseTest):
+    def test_Constructor(self):
+        self.assertRaises(TypeError, BZ2Decompressor, 42)
+
+    def testDecompress(self):
+        # "Test BZ2Decompressor.decompress()"
+        bz2d = BZ2Decompressor()
+        self.assertRaises(TypeError, bz2d.decompress)
+        text = bz2d.decompress(self.DATA)
+        self.assertEqual(text, self.TEXT)
+
+    def testDecompressChunks10(self):
+        # "Test BZ2Decompressor.decompress() with chunks of 10 bytes"
+        bz2d = BZ2Decompressor()
+        text = ''
+        n = 0
+        while 1:
+            str = self.DATA[n*10:(n+1)*10]
+            if not str:
+                break
+            text += bz2d.decompress(str)
+            n += 1
+        self.assertEqual(text, self.TEXT)
+
+    def testDecompressUnusedData(self):
+        # "Test BZ2Decompressor.decompress() with unused data"
+        bz2d = BZ2Decompressor()
+        unused_data = "this is unused data"
+        text = bz2d.decompress(self.DATA+unused_data)
+        self.assertEqual(text, self.TEXT)
+        self.assertEqual(bz2d.unused_data, unused_data)
+
+    def testEOFError(self):
+        # "Calling BZ2Decompressor.decompress() after EOS must raise EOFError"
+        bz2d = BZ2Decompressor()
+        text = bz2d.decompress(self.DATA)
+        self.assertRaises(EOFError, bz2d.decompress, "anything")
+
+
+class FuncTest(BaseTest):
+    "Test module functions"
+
+    def testCompress(self):
+        # "Test compress() function"
+        data = bz2.compress(self.TEXT)
+        self.assertEqual(self.decompress(data), self.TEXT)
+
+    def testDecompress(self):
+        # "Test decompress() function"
+        text = bz2.decompress(self.DATA)
+        self.assertEqual(text, self.TEXT)
+
+    def testDecompressEmpty(self):
+        # "Test decompress() function with empty string"
+        text = bz2.decompress("")
+        self.assertEqual(text, "")
+
+    def testDecompressIncomplete(self):
+        # "Test decompress() function with incomplete data"
+        self.assertRaises(ValueError, bz2.decompress, self.DATA[:-10])
+
+def test_main():
+    test_support.run_unittest(
+        BZ2FileTest,
+        BZ2CompressorTest,
+        BZ2DecompressorTest,
+        FuncTest
+    )
+    test_support.reap_children()
+
+if __name__ == '__main__':
+    test_main()
+
+# vim:ts=4:sw=4

Added: vendor/Python/current/Lib/test/test_cProfile.py
===================================================================
--- vendor/Python/current/Lib/test/test_cProfile.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_cProfile.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,123 @@
+"""Test suite for the cProfile module."""
+
+import cProfile, pstats, sys
+
+# In order to have reproducible time, we simulate a timer in the global
+# variable 'ticks', which represents simulated time in milliseconds.
+# (We can't use a helper function increment the timer since it would be
+# included in the profile and would appear to consume all the time.)
+ticks = 0
+
+# IMPORTANT: this is an output test.  *ALL* NUMBERS in the expected
+# output are relevant.  If you change the formatting of pstats,
+# please don't just regenerate output/test_cProfile without checking
+# very carefully that not a single number has changed.
+
+def test_main():
+    global ticks
+    ticks = 42000
+    prof = cProfile.Profile(timer, 0.001)
+    prof.runctx("testfunc()", globals(), locals())
+    assert ticks == 43000, ticks
+    st = pstats.Stats(prof)
+    st.strip_dirs().sort_stats('stdname').print_stats()
+    st.print_callees()
+    st.print_callers()
+
+def timer():
+    return ticks
+
+def testfunc():
+    # 1 call
+    # 1000 ticks total: 270 ticks local, 730 ticks in subfunctions
+    global ticks
+    ticks += 99
+    helper()                            # 300
+    helper()                            # 300
+    ticks += 171
+    factorial(14)                       # 130
+
+def factorial(n):
+    # 23 calls total
+    # 170 ticks total, 150 ticks local
+    # 3 primitive calls, 130, 20 and 20 ticks total
+    # including 116, 17, 17 ticks local
+    global ticks
+    if n > 0:
+        ticks += n
+        return mul(n, factorial(n-1))
+    else:
+        ticks += 11
+        return 1
+
+def mul(a, b):
+    # 20 calls
+    # 1 tick, local
+    global ticks
+    ticks += 1
+    return a * b
+
+def helper():
+    # 2 calls
+    # 300 ticks total: 20 ticks local, 260 ticks in subfunctions
+    global ticks
+    ticks += 1
+    helper1()                           # 30
+    ticks += 2
+    helper1()                           # 30
+    ticks += 6
+    helper2()                           # 50
+    ticks += 3
+    helper2()                           # 50
+    ticks += 2
+    helper2()                           # 50
+    ticks += 5
+    helper2_indirect()                  # 70
+    ticks += 1
+
+def helper1():
+    # 4 calls
+    # 30 ticks total: 29 ticks local, 1 tick in subfunctions
+    global ticks
+    ticks += 10
+    hasattr(C(), "foo")                 # 1
+    ticks += 19
+    lst = []
+    lst.append(42)                      # 0
+    sys.exc_info()                      # 0
+
+def helper2_indirect():
+    helper2()                           # 50
+    factorial(3)                        # 20
+
+def helper2():
+    # 8 calls
+    # 50 ticks local: 39 ticks local, 11 ticks in subfunctions
+    global ticks
+    ticks += 11
+    hasattr(C(), "bar")                 # 1
+    ticks += 13
+    subhelper()                         # 10
+    ticks += 15
+
+def subhelper():
+    # 8 calls
+    # 10 ticks total: 8 ticks local, 2 ticks in subfunctions
+    global ticks
+    ticks += 2
+    for i in range(2):                  # 0
+        try:
+            C().foo                     # 1 x 2
+        except AttributeError:
+            ticks += 3                  # 3 x 2
+
+class C:
+    def __getattr__(self, name):
+        # 28 calls
+        # 1 tick, local
+        global ticks
+        ticks += 1
+        raise AttributeError
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_calendar.py
===================================================================
--- vendor/Python/current/Lib/test/test_calendar.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_calendar.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,393 @@
+import calendar
+import unittest
+
+from test import test_support
+
+
+result_2004_text = """
+                                  2004
+
+      January                   February                   March
+Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su
+          1  2  3  4                         1       1  2  3  4  5  6  7
+ 5  6  7  8  9 10 11       2  3  4  5  6  7  8       8  9 10 11 12 13 14
+12 13 14 15 16 17 18       9 10 11 12 13 14 15      15 16 17 18 19 20 21
+19 20 21 22 23 24 25      16 17 18 19 20 21 22      22 23 24 25 26 27 28
+26 27 28 29 30 31         23 24 25 26 27 28 29      29 30 31
+
+       April                      May                       June
+Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su
+          1  2  3  4                      1  2          1  2  3  4  5  6
+ 5  6  7  8  9 10 11       3  4  5  6  7  8  9       7  8  9 10 11 12 13
+12 13 14 15 16 17 18      10 11 12 13 14 15 16      14 15 16 17 18 19 20
+19 20 21 22 23 24 25      17 18 19 20 21 22 23      21 22 23 24 25 26 27
+26 27 28 29 30            24 25 26 27 28 29 30      28 29 30
+                          31
+
+        July                     August                  September
+Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su
+          1  2  3  4                         1             1  2  3  4  5
+ 5  6  7  8  9 10 11       2  3  4  5  6  7  8       6  7  8  9 10 11 12
+12 13 14 15 16 17 18       9 10 11 12 13 14 15      13 14 15 16 17 18 19
+19 20 21 22 23 24 25      16 17 18 19 20 21 22      20 21 22 23 24 25 26
+26 27 28 29 30 31         23 24 25 26 27 28 29      27 28 29 30
+                          30 31
+
+      October                   November                  December
+Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su
+             1  2  3       1  2  3  4  5  6  7             1  2  3  4  5
+ 4  5  6  7  8  9 10       8  9 10 11 12 13 14       6  7  8  9 10 11 12
+11 12 13 14 15 16 17      15 16 17 18 19 20 21      13 14 15 16 17 18 19
+18 19 20 21 22 23 24      22 23 24 25 26 27 28      20 21 22 23 24 25 26
+25 26 27 28 29 30 31      29 30                     27 28 29 30 31
+"""
+
+result_2004_html = """
+<?xml version="1.0" encoding="ascii"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ascii" />
+<link rel="stylesheet" type="text/css" href="calendar.css" />
+<title>Calendar for 2004</title
+</head>
+<body>
+<table border="0" cellpadding="0" cellspacing="0" class="year">
+<tr><th colspan="3" class="year">2004</th></tr><tr><td><table border="0" cellpadding="0" cellspacing="0" class="month">
+<tr><th colspan="7" class="month">January</th></tr>
+<tr><th class="mon">Mon</th><th class="tue">Tue</th><th class="wed">Wed</th><th class="thu">Thu</th><th class="fri">Fri</th><th class="sat">Sat</th><th class="sun">Sun</th></tr>
+<tr><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="thu">1</td><td class="fri">2</td><td class="sat">3</td><td class="sun">4</td></tr>
+<tr><td class="mon">5</td><td class="tue">6</td><td class="wed">7</td><td class="thu">8</td><td class="fri">9</td><td class="sat">10</td><td class="sun">11</td></tr>
+<tr><td class="mon">12</td><td class="tue">13</td><td class="wed">14</td><td class="thu">15</td><td class="fri">16</td><td class="sat">17</td><td class="sun">18</td></tr>
+<tr><td class="mon">19</td><td class="tue">20</td><td class="wed">21</td><td class="thu">22</td><td class="fri">23</td><td class="sat">24</td><td class="sun">25</td></tr>
+<tr><td class="mon">26</td><td class="tue">27</td><td class="wed">28</td><td class="thu">29</td><td class="fri">30</td><td class="sat">31</td><td class="noday">&nbsp;</td></tr>
+</table>
+</td><td><table border="0" cellpadding="0" cellspacing="0" class="month">
+<tr><th colspan="7" class="month">February</th></tr>
+<tr><th class="mon">Mon</th><th class="tue">Tue</th><th class="wed">Wed</th><th class="thu">Thu</th><th class="fri">Fri</th><th class="sat">Sat</th><th class="sun">Sun</th></tr>
+<tr><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="sun">1</td></tr>
+<tr><td class="mon">2</td><td class="tue">3</td><td class="wed">4</td><td class="thu">5</td><td class="fri">6</td><td class="sat">7</td><td class="sun">8</td></tr>
+<tr><td class="mon">9</td><td class="tue">10</td><td class="wed">11</td><td class="thu">12</td><td class="fri">13</td><td class="sat">14</td><td class="sun">15</td></tr>
+<tr><td class="mon">16</td><td class="tue">17</td><td class="wed">18</td><td class="thu">19</td><td class="fri">20</td><td class="sat">21</td><td class="sun">22</td></tr>
+<tr><td class="mon">23</td><td class="tue">24</td><td class="wed">25</td><td class="thu">26</td><td class="fri">27</td><td class="sat">28</td><td class="sun">29</td></tr>
+</table>
+</td><td><table border="0" cellpadding="0" cellspacing="0" class="month">
+<tr><th colspan="7" class="month">March</th></tr>
+<tr><th class="mon">Mon</th><th class="tue">Tue</th><th class="wed">Wed</th><th class="thu">Thu</th><th class="fri">Fri</th><th class="sat">Sat</th><th class="sun">Sun</th></tr>
+<tr><td class="mon">1</td><td class="tue">2</td><td class="wed">3</td><td class="thu">4</td><td class="fri">5</td><td class="sat">6</td><td class="sun">7</td></tr>
+<tr><td class="mon">8</td><td class="tue">9</td><td class="wed">10</td><td class="thu">11</td><td class="fri">12</td><td class="sat">13</td><td class="sun">14</td></tr>
+<tr><td class="mon">15</td><td class="tue">16</td><td class="wed">17</td><td class="thu">18</td><td class="fri">19</td><td class="sat">20</td><td class="sun">21</td></tr>
+<tr><td class="mon">22</td><td class="tue">23</td><td class="wed">24</td><td class="thu">25</td><td class="fri">26</td><td class="sat">27</td><td class="sun">28</td></tr>
+<tr><td class="mon">29</td><td class="tue">30</td><td class="wed">31</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td></tr>
+</table>
+</td></tr><tr><td><table border="0" cellpadding="0" cellspacing="0" class="month">
+<tr><th colspan="7" class="month">April</th></tr>
+<tr><th class="mon">Mon</th><th class="tue">Tue</th><th class="wed">Wed</th><th class="thu">Thu</th><th class="fri">Fri</th><th class="sat">Sat</th><th class="sun">Sun</th></tr>
+<tr><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="thu">1</td><td class="fri">2</td><td class="sat">3</td><td class="sun">4</td></tr>
+<tr><td class="mon">5</td><td class="tue">6</td><td class="wed">7</td><td class="thu">8</td><td class="fri">9</td><td class="sat">10</td><td class="sun">11</td></tr>
+<tr><td class="mon">12</td><td class="tue">13</td><td class="wed">14</td><td class="thu">15</td><td class="fri">16</td><td class="sat">17</td><td class="sun">18</td></tr>
+<tr><td class="mon">19</td><td class="tue">20</td><td class="wed">21</td><td class="thu">22</td><td class="fri">23</td><td class="sat">24</td><td class="sun">25</td></tr>
+<tr><td class="mon">26</td><td class="tue">27</td><td class="wed">28</td><td class="thu">29</td><td class="fri">30</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td></tr>
+</table>
+</td><td><table border="0" cellpadding="0" cellspacing="0" class="month">
+<tr><th colspan="7" class="month">May</th></tr>
+<tr><th class="mon">Mon</th><th class="tue">Tue</th><th class="wed">Wed</th><th class="thu">Thu</th><th class="fri">Fri</th><th class="sat">Sat</th><th class="sun">Sun</th></tr>
+<tr><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="sat">1</td><td class="sun">2</td></tr>
+<tr><td class="mon">3</td><td class="tue">4</td><td class="wed">5</td><td class="thu">6</td><td class="fri">7</td><td class="sat">8</td><td class="sun">9</td></tr>
+<tr><td class="mon">10</td><td class="tue">11</td><td class="wed">12</td><td class="thu">13</td><td class="fri">14</td><td class="sat">15</td><td class="sun">16</td></tr>
+<tr><td class="mon">17</td><td class="tue">18</td><td class="wed">19</td><td class="thu">20</td><td class="fri">21</td><td class="sat">22</td><td class="sun">23</td></tr>
+<tr><td class="mon">24</td><td class="tue">25</td><td class="wed">26</td><td class="thu">27</td><td class="fri">28</td><td class="sat">29</td><td class="sun">30</td></tr>
+<tr><td class="mon">31</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td></tr>
+</table>
+</td><td><table border="0" cellpadding="0" cellspacing="0" class="month">
+<tr><th colspan="7" class="month">June</th></tr>
+<tr><th class="mon">Mon</th><th class="tue">Tue</th><th class="wed">Wed</th><th class="thu">Thu</th><th class="fri">Fri</th><th class="sat">Sat</th><th class="sun">Sun</th></tr>
+<tr><td class="noday">&nbsp;</td><td class="tue">1</td><td class="wed">2</td><td class="thu">3</td><td class="fri">4</td><td class="sat">5</td><td class="sun">6</td></tr>
+<tr><td class="mon">7</td><td class="tue">8</td><td class="wed">9</td><td class="thu">10</td><td class="fri">11</td><td class="sat">12</td><td class="sun">13</td></tr>
+<tr><td class="mon">14</td><td class="tue">15</td><td class="wed">16</td><td class="thu">17</td><td class="fri">18</td><td class="sat">19</td><td class="sun">20</td></tr>
+<tr><td class="mon">21</td><td class="tue">22</td><td class="wed">23</td><td class="thu">24</td><td class="fri">25</td><td class="sat">26</td><td class="sun">27</td></tr>
+<tr><td class="mon">28</td><td class="tue">29</td><td class="wed">30</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td></tr>
+</table>
+</td></tr><tr><td><table border="0" cellpadding="0" cellspacing="0" class="month">
+<tr><th colspan="7" class="month">July</th></tr>
+<tr><th class="mon">Mon</th><th class="tue">Tue</th><th class="wed">Wed</th><th class="thu">Thu</th><th class="fri">Fri</th><th class="sat">Sat</th><th class="sun">Sun</th></tr>
+<tr><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="thu">1</td><td class="fri">2</td><td class="sat">3</td><td class="sun">4</td></tr>
+<tr><td class="mon">5</td><td class="tue">6</td><td class="wed">7</td><td class="thu">8</td><td class="fri">9</td><td class="sat">10</td><td class="sun">11</td></tr>
+<tr><td class="mon">12</td><td class="tue">13</td><td class="wed">14</td><td class="thu">15</td><td class="fri">16</td><td class="sat">17</td><td class="sun">18</td></tr>
+<tr><td class="mon">19</td><td class="tue">20</td><td class="wed">21</td><td class="thu">22</td><td class="fri">23</td><td class="sat">24</td><td class="sun">25</td></tr>
+<tr><td class="mon">26</td><td class="tue">27</td><td class="wed">28</td><td class="thu">29</td><td class="fri">30</td><td class="sat">31</td><td class="noday">&nbsp;</td></tr>
+</table>
+</td><td><table border="0" cellpadding="0" cellspacing="0" class="month">
+<tr><th colspan="7" class="month">August</th></tr>
+<tr><th class="mon">Mon</th><th class="tue">Tue</th><th class="wed">Wed</th><th class="thu">Thu</th><th class="fri">Fri</th><th class="sat">Sat</th><th class="sun">Sun</th></tr>
+<tr><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="sun">1</td></tr>
+<tr><td class="mon">2</td><td class="tue">3</td><td class="wed">4</td><td class="thu">5</td><td class="fri">6</td><td class="sat">7</td><td class="sun">8</td></tr>
+<tr><td class="mon">9</td><td class="tue">10</td><td class="wed">11</td><td class="thu">12</td><td class="fri">13</td><td class="sat">14</td><td class="sun">15</td></tr>
+<tr><td class="mon">16</td><td class="tue">17</td><td class="wed">18</td><td class="thu">19</td><td class="fri">20</td><td class="sat">21</td><td class="sun">22</td></tr>
+<tr><td class="mon">23</td><td class="tue">24</td><td class="wed">25</td><td class="thu">26</td><td class="fri">27</td><td class="sat">28</td><td class="sun">29</td></tr>
+<tr><td class="mon">30</td><td class="tue">31</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td></tr>
+</table>
+</td><td><table border="0" cellpadding="0" cellspacing="0" class="month">
+<tr><th colspan="7" class="month">September</th></tr>
+<tr><th class="mon">Mon</th><th class="tue">Tue</th><th class="wed">Wed</th><th class="thu">Thu</th><th class="fri">Fri</th><th class="sat">Sat</th><th class="sun">Sun</th></tr>
+<tr><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="wed">1</td><td class="thu">2</td><td class="fri">3</td><td class="sat">4</td><td class="sun">5</td></tr>
+<tr><td class="mon">6</td><td class="tue">7</td><td class="wed">8</td><td class="thu">9</td><td class="fri">10</td><td class="sat">11</td><td class="sun">12</td></tr>
+<tr><td class="mon">13</td><td class="tue">14</td><td class="wed">15</td><td class="thu">16</td><td class="fri">17</td><td class="sat">18</td><td class="sun">19</td></tr>
+<tr><td class="mon">20</td><td class="tue">21</td><td class="wed">22</td><td class="thu">23</td><td class="fri">24</td><td class="sat">25</td><td class="sun">26</td></tr>
+<tr><td class="mon">27</td><td class="tue">28</td><td class="wed">29</td><td class="thu">30</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td></tr>
+</table>
+</td></tr><tr><td><table border="0" cellpadding="0" cellspacing="0" class="month">
+<tr><th colspan="7" class="month">October</th></tr>
+<tr><th class="mon">Mon</th><th class="tue">Tue</th><th class="wed">Wed</th><th class="thu">Thu</th><th class="fri">Fri</th><th class="sat">Sat</th><th class="sun">Sun</th></tr>
+<tr><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="fri">1</td><td class="sat">2</td><td class="sun">3</td></tr>
+<tr><td class="mon">4</td><td class="tue">5</td><td class="wed">6</td><td class="thu">7</td><td class="fri">8</td><td class="sat">9</td><td class="sun">10</td></tr>
+<tr><td class="mon">11</td><td class="tue">12</td><td class="wed">13</td><td class="thu">14</td><td class="fri">15</td><td class="sat">16</td><td class="sun">17</td></tr>
+<tr><td class="mon">18</td><td class="tue">19</td><td class="wed">20</td><td class="thu">21</td><td class="fri">22</td><td class="sat">23</td><td class="sun">24</td></tr>
+<tr><td class="mon">25</td><td class="tue">26</td><td class="wed">27</td><td class="thu">28</td><td class="fri">29</td><td class="sat">30</td><td class="sun">31</td></tr>
+</table>
+</td><td><table border="0" cellpadding="0" cellspacing="0" class="month">
+<tr><th colspan="7" class="month">November</th></tr>
+<tr><th class="mon">Mon</th><th class="tue">Tue</th><th class="wed">Wed</th><th class="thu">Thu</th><th class="fri">Fri</th><th class="sat">Sat</th><th class="sun">Sun</th></tr>
+<tr><td class="mon">1</td><td class="tue">2</td><td class="wed">3</td><td class="thu">4</td><td class="fri">5</td><td class="sat">6</td><td class="sun">7</td></tr>
+<tr><td class="mon">8</td><td class="tue">9</td><td class="wed">10</td><td class="thu">11</td><td class="fri">12</td><td class="sat">13</td><td class="sun">14</td></tr>
+<tr><td class="mon">15</td><td class="tue">16</td><td class="wed">17</td><td class="thu">18</td><td class="fri">19</td><td class="sat">20</td><td class="sun">21</td></tr>
+<tr><td class="mon">22</td><td class="tue">23</td><td class="wed">24</td><td class="thu">25</td><td class="fri">26</td><td class="sat">27</td><td class="sun">28</td></tr>
+<tr><td class="mon">29</td><td class="tue">30</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td></tr>
+</table>
+</td><td><table border="0" cellpadding="0" cellspacing="0" class="month">
+<tr><th colspan="7" class="month">December</th></tr>
+<tr><th class="mon">Mon</th><th class="tue">Tue</th><th class="wed">Wed</th><th class="thu">Thu</th><th class="fri">Fri</th><th class="sat">Sat</th><th class="sun">Sun</th></tr>
+<tr><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="wed">1</td><td class="thu">2</td><td class="fri">3</td><td class="sat">4</td><td class="sun">5</td></tr>
+<tr><td class="mon">6</td><td class="tue">7</td><td class="wed">8</td><td class="thu">9</td><td class="fri">10</td><td class="sat">11</td><td class="sun">12</td></tr>
+<tr><td class="mon">13</td><td class="tue">14</td><td class="wed">15</td><td class="thu">16</td><td class="fri">17</td><td class="sat">18</td><td class="sun">19</td></tr>
+<tr><td class="mon">20</td><td class="tue">21</td><td class="wed">22</td><td class="thu">23</td><td class="fri">24</td><td class="sat">25</td><td class="sun">26</td></tr>
+<tr><td class="mon">27</td><td class="tue">28</td><td class="wed">29</td><td class="thu">30</td><td class="fri">31</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td></tr>
+</table>
+</td></tr></table></body>
+</html>
+"""
+
+
+class OutputTestCase(unittest.TestCase):
+    def normalize_calendar(self, s):
+        # Filters out locale dependant strings
+        def neitherspacenordigit(c):
+            return not c.isspace() and not c.isdigit()
+
+        lines = []
+        for line in s.splitlines(False):
+            # Drop texts, as they are locale dependent
+            if line and not filter(neitherspacenordigit, line):
+                lines.append(line)
+        return lines
+
+    def test_output(self):
+        self.assertEqual(
+            self.normalize_calendar(calendar.calendar(2004)),
+            self.normalize_calendar(result_2004_text)
+        )
+
+    def test_output_textcalendar(self):
+        self.assertEqual(
+            calendar.TextCalendar().formatyear(2004).strip(),
+            result_2004_text.strip()
+        )
+
+    def test_output_htmlcalendar(self):
+        self.assertEqual(
+            calendar.HTMLCalendar().formatyearpage(2004).strip(),
+            result_2004_html.strip()
+        )
+
+
+class CalendarTestCase(unittest.TestCase):
+    def test_isleap(self):
+        # Make sure that the return is right for a few years, and
+        # ensure that the return values are 1 or 0, not just true or
+        # false (see SF bug #485794).  Specific additional tests may
+        # be appropriate; this tests a single "cycle".
+        self.assertEqual(calendar.isleap(2000), 1)
+        self.assertEqual(calendar.isleap(2001), 0)
+        self.assertEqual(calendar.isleap(2002), 0)
+        self.assertEqual(calendar.isleap(2003), 0)
+
+    def test_setfirstweekday(self):
+        self.assertRaises(ValueError, calendar.setfirstweekday, 'flabber')
+        self.assertRaises(ValueError, calendar.setfirstweekday, -1)
+        self.assertRaises(ValueError, calendar.setfirstweekday, 200)
+        orig = calendar.firstweekday()
+        calendar.setfirstweekday(calendar.SUNDAY)
+        self.assertEqual(calendar.firstweekday(), calendar.SUNDAY)
+        calendar.setfirstweekday(calendar.MONDAY)
+        self.assertEqual(calendar.firstweekday(), calendar.MONDAY)
+        calendar.setfirstweekday(orig)
+
+    def test_enumerateweekdays(self):
+        self.assertRaises(IndexError, calendar.day_abbr.__getitem__, -10)
+        self.assertRaises(IndexError, calendar.day_name.__getitem__, 10)
+        self.assertEqual(len([d for d in calendar.day_abbr]), 7)
+
+    def test_days(self):
+        for attr in "day_name", "day_abbr":
+            value = getattr(calendar, attr)
+            self.assertEqual(len(value), 7)
+            self.assertEqual(len(value[:]), 7)
+            # ensure they're all unique
+            self.assertEqual(len(set(value)), 7)
+            # verify it "acts like a sequence" in two forms of iteration
+            self.assertEqual(value[::-1], list(reversed(value)))
+
+    def test_months(self):
+        for attr in "month_name", "month_abbr":
+            value = getattr(calendar, attr)
+            self.assertEqual(len(value), 13)
+            self.assertEqual(len(value[:]), 13)
+            self.assertEqual(value[0], "")
+            # ensure they're all unique
+            self.assertEqual(len(set(value)), 13)
+            # verify it "acts like a sequence" in two forms of iteration
+            self.assertEqual(value[::-1], list(reversed(value)))
+
+
+class MonthCalendarTestCase(unittest.TestCase):
+    def setUp(self):
+        self.oldfirstweekday = calendar.firstweekday()
+        calendar.setfirstweekday(self.firstweekday)
+
+    def tearDown(self):
+        calendar.setfirstweekday(self.oldfirstweekday)
+
+    def check_weeks(self, year, month, weeks):
+        cal = calendar.monthcalendar(year, month)
+        self.assertEqual(len(cal), len(weeks))
+        for i in xrange(len(weeks)):
+            self.assertEqual(weeks[i], sum(day != 0 for day in cal[i]))
+
+
+class MondayTestCase(MonthCalendarTestCase):
+    firstweekday = calendar.MONDAY
+
+    def test_february(self):
+        # A 28-day february starting on monday (7+7+7+7 days)
+        self.check_weeks(1999, 2, (7, 7, 7, 7))
+
+        # A 28-day february starting on tuesday (6+7+7+7+1 days)
+        self.check_weeks(2005, 2, (6, 7, 7, 7, 1))
+
+        # A 28-day february starting on sunday (1+7+7+7+6 days)
+        self.check_weeks(1987, 2, (1, 7, 7, 7, 6))
+
+        # A 29-day february starting on monday (7+7+7+7+1 days)
+        self.check_weeks(1988, 2, (7, 7, 7, 7, 1))
+
+        # A 29-day february starting on tuesday (6+7+7+7+2 days)
+        self.check_weeks(1972, 2, (6, 7, 7, 7, 2))
+
+        # A 29-day february starting on sunday (1+7+7+7+7 days)
+        self.check_weeks(2004, 2, (1, 7, 7, 7, 7))
+
+    def test_april(self):
+        # A 30-day april starting on monday (7+7+7+7+2 days)
+        self.check_weeks(1935, 4, (7, 7, 7, 7, 2))
+
+        # A 30-day april starting on tuesday (6+7+7+7+3 days)
+        self.check_weeks(1975, 4, (6, 7, 7, 7, 3))
+
+        # A 30-day april starting on sunday (1+7+7+7+7+1 days)
+        self.check_weeks(1945, 4, (1, 7, 7, 7, 7, 1))
+
+        # A 30-day april starting on saturday (2+7+7+7+7 days)
+        self.check_weeks(1995, 4, (2, 7, 7, 7, 7))
+
+        # A 30-day april starting on friday (3+7+7+7+6 days)
+        self.check_weeks(1994, 4, (3, 7, 7, 7, 6))
+
+    def test_december(self):
+        # A 31-day december starting on monday (7+7+7+7+3 days)
+        self.check_weeks(1980, 12, (7, 7, 7, 7, 3))
+
+        # A 31-day december starting on tuesday (6+7+7+7+4 days)
+        self.check_weeks(1987, 12, (6, 7, 7, 7, 4))
+
+        # A 31-day december starting on sunday (1+7+7+7+7+2 days)
+        self.check_weeks(1968, 12, (1, 7, 7, 7, 7, 2))
+
+        # A 31-day december starting on thursday (4+7+7+7+6 days)
+        self.check_weeks(1988, 12, (4, 7, 7, 7, 6))
+
+        # A 31-day december starting on friday (3+7+7+7+7 days)
+        self.check_weeks(2017, 12, (3, 7, 7, 7, 7))
+
+        # A 31-day december starting on saturday (2+7+7+7+7+1 days)
+        self.check_weeks(2068, 12, (2, 7, 7, 7, 7, 1))
+
+
+class SundayTestCase(MonthCalendarTestCase):
+    firstweekday = calendar.SUNDAY
+
+    def test_february(self):
+        # A 28-day february starting on sunday (7+7+7+7 days)
+        self.check_weeks(2009, 2, (7, 7, 7, 7))
+
+        # A 28-day february starting on monday (6+7+7+7+1 days)
+        self.check_weeks(1999, 2, (6, 7, 7, 7, 1))
+
+        # A 28-day february starting on saturday (1+7+7+7+6 days)
+        self.check_weeks(1997, 2, (1, 7, 7, 7, 6))
+
+        # A 29-day february starting on sunday (7+7+7+7+1 days)
+        self.check_weeks(2004, 2, (7, 7, 7, 7, 1))
+
+        # A 29-day february starting on monday (6+7+7+7+2 days)
+        self.check_weeks(1960, 2, (6, 7, 7, 7, 2))
+
+        # A 29-day february starting on saturday (1+7+7+7+7 days)
+        self.check_weeks(1964, 2, (1, 7, 7, 7, 7))
+
+    def test_april(self):
+        # A 30-day april starting on sunday (7+7+7+7+2 days)
+        self.check_weeks(1923, 4, (7, 7, 7, 7, 2))
+
+        # A 30-day april starting on monday (6+7+7+7+3 days)
+        self.check_weeks(1918, 4, (6, 7, 7, 7, 3))
+
+        # A 30-day april starting on saturday (1+7+7+7+7+1 days)
+        self.check_weeks(1950, 4, (1, 7, 7, 7, 7, 1))
+
+        # A 30-day april starting on friday (2+7+7+7+7 days)
+        self.check_weeks(1960, 4, (2, 7, 7, 7, 7))
+
+        # A 30-day april starting on thursday (3+7+7+7+6 days)
+        self.check_weeks(1909, 4, (3, 7, 7, 7, 6))
+
+    def test_december(self):
+        # A 31-day december starting on sunday (7+7+7+7+3 days)
+        self.check_weeks(2080, 12, (7, 7, 7, 7, 3))
+
+        # A 31-day december starting on monday (6+7+7+7+4 days)
+        self.check_weeks(1941, 12, (6, 7, 7, 7, 4))
+
+        # A 31-day december starting on saturday (1+7+7+7+7+2 days)
+        self.check_weeks(1923, 12, (1, 7, 7, 7, 7, 2))
+
+        # A 31-day december starting on wednesday (4+7+7+7+6 days)
+        self.check_weeks(1948, 12, (4, 7, 7, 7, 6))
+
+        # A 31-day december starting on thursday (3+7+7+7+7 days)
+        self.check_weeks(1927, 12, (3, 7, 7, 7, 7))
+
+        # A 31-day december starting on friday (2+7+7+7+7+1 days)
+        self.check_weeks(1995, 12, (2, 7, 7, 7, 7, 1))
+
+
+def test_main():
+    test_support.run_unittest(
+        OutputTestCase,
+        CalendarTestCase,
+        MondayTestCase,
+        SundayTestCase
+    )
+
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_call.py
===================================================================
--- vendor/Python/current/Lib/test/test_call.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_call.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,131 @@
+import unittest
+from test import test_support
+
+# The test cases here cover several paths through the function calling
+# code.  They depend on the METH_XXX flag that is used to define a C
+# function, which can't be verified from Python.  If the METH_XXX decl
+# for a C function changes, these tests may not cover the right paths.
+
+class CFunctionCalls(unittest.TestCase):
+
+    def test_varargs0(self):
+        self.assertRaises(TypeError, {}.has_key)
+
+    def test_varargs1(self):
+        {}.has_key(0)
+
+    def test_varargs2(self):
+        self.assertRaises(TypeError, {}.has_key, 0, 1)
+
+    def test_varargs0_ext(self):
+        try:
+            {}.has_key(*())
+        except TypeError:
+            pass
+
+    def test_varargs1_ext(self):
+        {}.has_key(*(0,))
+
+    def test_varargs2_ext(self):
+        try:
+            {}.has_key(*(1, 2))
+        except TypeError:
+            pass
+        else:
+            raise RuntimeError
+
+    def test_varargs0_kw(self):
+        self.assertRaises(TypeError, {}.has_key, x=2)
+
+    def test_varargs1_kw(self):
+        self.assertRaises(TypeError, {}.has_key, x=2)
+
+    def test_varargs2_kw(self):
+        self.assertRaises(TypeError, {}.has_key, x=2, y=2)
+
+    def test_oldargs0_0(self):
+        {}.keys()
+
+    def test_oldargs0_1(self):
+        self.assertRaises(TypeError, {}.keys, 0)
+
+    def test_oldargs0_2(self):
+        self.assertRaises(TypeError, {}.keys, 0, 1)
+
+    def test_oldargs0_0_ext(self):
+        {}.keys(*())
+
+    def test_oldargs0_1_ext(self):
+        try:
+            {}.keys(*(0,))
+        except TypeError:
+            pass
+        else:
+            raise RuntimeError
+
+    def test_oldargs0_2_ext(self):
+        try:
+            {}.keys(*(1, 2))
+        except TypeError:
+            pass
+        else:
+            raise RuntimeError
+
+    def test_oldargs0_0_kw(self):
+        try:
+            {}.keys(x=2)
+        except TypeError:
+            pass
+        else:
+            raise RuntimeError
+
+    def test_oldargs0_1_kw(self):
+        self.assertRaises(TypeError, {}.keys, x=2)
+
+    def test_oldargs0_2_kw(self):
+        self.assertRaises(TypeError, {}.keys, x=2, y=2)
+
+    def test_oldargs1_0(self):
+        self.assertRaises(TypeError, [].count)
+
+    def test_oldargs1_1(self):
+        [].count(1)
+
+    def test_oldargs1_2(self):
+        self.assertRaises(TypeError, [].count, 1, 2)
+
+    def test_oldargs1_0_ext(self):
+        try:
+            [].count(*())
+        except TypeError:
+            pass
+        else:
+            raise RuntimeError
+
+    def test_oldargs1_1_ext(self):
+        [].count(*(1,))
+
+    def test_oldargs1_2_ext(self):
+        try:
+            [].count(*(1, 2))
+        except TypeError:
+            pass
+        else:
+            raise RuntimeError
+
+    def test_oldargs1_0_kw(self):
+        self.assertRaises(TypeError, [].count, x=2)
+
+    def test_oldargs1_1_kw(self):
+        self.assertRaises(TypeError, [].count, {}, x=2)
+
+    def test_oldargs1_2_kw(self):
+        self.assertRaises(TypeError, [].count, x=2, y=2)
+
+
+def test_main():
+    test_support.run_unittest(CFunctionCalls)
+
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_capi.py
===================================================================
--- vendor/Python/current/Lib/test/test_capi.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_capi.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,55 @@
+# Run the _testcapi module tests (tests for the Python/C API):  by defn,
+# these are all functions _testcapi exports whose name begins with 'test_'.
+
+import sys
+from test import test_support
+import _testcapi
+
+def test_main():
+
+    for name in dir(_testcapi):
+        if name.startswith('test_'):
+            test = getattr(_testcapi, name)
+            if test_support.verbose:
+                print "internal", name
+            try:
+                test()
+            except _testcapi.error:
+                raise test_support.TestFailed, sys.exc_info()[1]
+
+    # some extra thread-state tests driven via _testcapi
+    def TestThreadState():
+        import thread
+        import time
+
+        if test_support.verbose:
+            print "auto-thread-state"
+
+        idents = []
+
+        def callback():
+            idents.append(thread.get_ident())
+
+        _testcapi._test_thread_state(callback)
+        a = b = callback
+        time.sleep(1)
+        # Check our main thread is in the list exactly 3 times.
+        if idents.count(thread.get_ident()) != 3:
+            raise test_support.TestFailed, \
+                  "Couldn't find main thread correctly in the list"
+
+    try:
+        _testcapi._test_thread_state
+        have_thread_state = True
+    except AttributeError:
+        have_thread_state = False
+
+    if have_thread_state:
+        TestThreadState()
+        import threading
+        t=threading.Thread(target=TestThreadState)
+        t.start()
+        t.join()
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_cd.py
===================================================================
--- vendor/Python/current/Lib/test/test_cd.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_cd.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,26 @@
+#! /usr/bin/env python
+"""Whimpy test script for the cd module
+   Roger E. Masse
+"""
+import cd
+from test.test_support import verbose
+
+cdattrs = ['BLOCKSIZE', 'CDROM', 'DATASIZE', 'ERROR', 'NODISC', 'PAUSED', 'PLAYING', 'READY',
+           'STILL', '__doc__', '__name__', 'atime', 'audio', 'catalog', 'control', 'createparser', 'error',
+           'ident', 'index', 'msftoframe', 'open', 'pnum', 'ptime']
+
+
+# This is a very inobtrusive test for the existence of the cd module and all its
+# attributes.  More comprehensive examples can be found in Demo/cd and
+# require that you have a CD and a CD ROM drive
+
+def main():
+    # touch all the attributes of cd without doing anything
+    if verbose:
+        print 'Touching cd module attributes...'
+    for attr in cdattrs:
+        if verbose:
+            print 'touching: ', attr
+        getattr(cd, attr)
+
+main()


Property changes on: vendor/Python/current/Lib/test/test_cd.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/test/test_cfgparser.py
===================================================================
--- vendor/Python/current/Lib/test/test_cfgparser.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_cfgparser.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,426 @@
+import ConfigParser
+import StringIO
+import unittest
+
+from test import test_support
+
+
+class TestCaseBase(unittest.TestCase):
+    def newconfig(self, defaults=None):
+        if defaults is None:
+            self.cf = self.config_class()
+        else:
+            self.cf = self.config_class(defaults)
+        return self.cf
+
+    def fromstring(self, string, defaults=None):
+        cf = self.newconfig(defaults)
+        sio = StringIO.StringIO(string)
+        cf.readfp(sio)
+        return cf
+
+    def test_basic(self):
+        cf = self.fromstring(
+            "[Foo Bar]\n"
+            "foo=bar\n"
+            "[Spacey Bar]\n"
+            "foo = bar\n"
+            "[Commented Bar]\n"
+            "foo: bar ; comment\n"
+            "[Long Line]\n"
+            "foo: this line is much, much longer than my editor\n"
+            "   likes it.\n"
+            "[Section\\with$weird%characters[\t]\n"
+            "[Internationalized Stuff]\n"
+            "foo[bg]: Bulgarian\n"
+            "foo=Default\n"
+            "foo[en]=English\n"
+            "foo[de]=Deutsch\n"
+            "[Spaces]\n"
+            "key with spaces : value\n"
+            "another with spaces = splat!\n"
+            )
+        L = cf.sections()
+        L.sort()
+        eq = self.assertEqual
+        eq(L, [r'Commented Bar',
+               r'Foo Bar',
+               r'Internationalized Stuff',
+               r'Long Line',
+               r'Section\with$weird%characters[' '\t',
+               r'Spaces',
+               r'Spacey Bar',
+               ])
+
+        # The use of spaces in the section names serves as a
+        # regression test for SourceForge bug #583248:
+        # http://www.python.org/sf/583248
+        eq(cf.get('Foo Bar', 'foo'), 'bar')
+        eq(cf.get('Spacey Bar', 'foo'), 'bar')
+        eq(cf.get('Commented Bar', 'foo'), 'bar')
+        eq(cf.get('Spaces', 'key with spaces'), 'value')
+        eq(cf.get('Spaces', 'another with spaces'), 'splat!')
+
+        self.failIf('__name__' in cf.options("Foo Bar"),
+                    '__name__ "option" should not be exposed by the API!')
+
+        # Make sure the right things happen for remove_option();
+        # added to include check for SourceForge bug #123324:
+        self.failUnless(cf.remove_option('Foo Bar', 'foo'),
+                        "remove_option() failed to report existance of option")
+        self.failIf(cf.has_option('Foo Bar', 'foo'),
+                    "remove_option() failed to remove option")
+        self.failIf(cf.remove_option('Foo Bar', 'foo'),
+                    "remove_option() failed to report non-existance of option"
+                    " that was removed")
+
+        self.assertRaises(ConfigParser.NoSectionError,
+                          cf.remove_option, 'No Such Section', 'foo')
+
+        eq(cf.get('Long Line', 'foo'),
+           'this line is much, much longer than my editor\nlikes it.')
+
+    def test_case_sensitivity(self):
+        cf = self.newconfig()
+        cf.add_section("A")
+        cf.add_section("a")
+        L = cf.sections()
+        L.sort()
+        eq = self.assertEqual
+        eq(L, ["A", "a"])
+        cf.set("a", "B", "value")
+        eq(cf.options("a"), ["b"])
+        eq(cf.get("a", "b"), "value",
+           "could not locate option, expecting case-insensitive option names")
+        self.failUnless(cf.has_option("a", "b"))
+        cf.set("A", "A-B", "A-B value")
+        for opt in ("a-b", "A-b", "a-B", "A-B"):
+            self.failUnless(
+                cf.has_option("A", opt),
+                "has_option() returned false for option which should exist")
+        eq(cf.options("A"), ["a-b"])
+        eq(cf.options("a"), ["b"])
+        cf.remove_option("a", "B")
+        eq(cf.options("a"), [])
+
+        # SF bug #432369:
+        cf = self.fromstring(
+            "[MySection]\nOption: first line\n\tsecond line\n")
+        eq(cf.options("MySection"), ["option"])
+        eq(cf.get("MySection", "Option"), "first line\nsecond line")
+
+        # SF bug #561822:
+        cf = self.fromstring("[section]\nnekey=nevalue\n",
+                             defaults={"key":"value"})
+        self.failUnless(cf.has_option("section", "Key"))
+
+
+    def test_default_case_sensitivity(self):
+        cf = self.newconfig({"foo": "Bar"})
+        self.assertEqual(
+            cf.get("DEFAULT", "Foo"), "Bar",
+            "could not locate option, expecting case-insensitive option names")
+        cf = self.newconfig({"Foo": "Bar"})
+        self.assertEqual(
+            cf.get("DEFAULT", "Foo"), "Bar",
+            "could not locate option, expecting case-insensitive defaults")
+
+    def test_parse_errors(self):
+        self.newconfig()
+        self.parse_error(ConfigParser.ParsingError,
+                         "[Foo]\n  extra-spaces: splat\n")
+        self.parse_error(ConfigParser.ParsingError,
+                         "[Foo]\n  extra-spaces= splat\n")
+        self.parse_error(ConfigParser.ParsingError,
+                         "[Foo]\noption-without-value\n")
+        self.parse_error(ConfigParser.ParsingError,
+                         "[Foo]\n:value-without-option-name\n")
+        self.parse_error(ConfigParser.ParsingError,
+                         "[Foo]\n=value-without-option-name\n")
+        self.parse_error(ConfigParser.MissingSectionHeaderError,
+                         "No Section!\n")
+
+    def parse_error(self, exc, src):
+        sio = StringIO.StringIO(src)
+        self.assertRaises(exc, self.cf.readfp, sio)
+
+    def test_query_errors(self):
+        cf = self.newconfig()
+        self.assertEqual(cf.sections(), [],
+                         "new ConfigParser should have no defined sections")
+        self.failIf(cf.has_section("Foo"),
+                    "new ConfigParser should have no acknowledged sections")
+        self.assertRaises(ConfigParser.NoSectionError,
+                          cf.options, "Foo")
+        self.assertRaises(ConfigParser.NoSectionError,
+                          cf.set, "foo", "bar", "value")
+        self.get_error(ConfigParser.NoSectionError, "foo", "bar")
+        cf.add_section("foo")
+        self.get_error(ConfigParser.NoOptionError, "foo", "bar")
+
+    def get_error(self, exc, section, option):
+        try:
+            self.cf.get(section, option)
+        except exc, e:
+            return e
+        else:
+            self.fail("expected exception type %s.%s"
+                      % (exc.__module__, exc.__name__))
+
+    def test_boolean(self):
+        cf = self.fromstring(
+            "[BOOLTEST]\n"
+            "T1=1\n"
+            "T2=TRUE\n"
+            "T3=True\n"
+            "T4=oN\n"
+            "T5=yes\n"
+            "F1=0\n"
+            "F2=FALSE\n"
+            "F3=False\n"
+            "F4=oFF\n"
+            "F5=nO\n"
+            "E1=2\n"
+            "E2=foo\n"
+            "E3=-1\n"
+            "E4=0.1\n"
+            "E5=FALSE AND MORE"
+            )
+        for x in range(1, 5):
+            self.failUnless(cf.getboolean('BOOLTEST', 't%d' % x))
+            self.failIf(cf.getboolean('BOOLTEST', 'f%d' % x))
+            self.assertRaises(ValueError,
+                              cf.getboolean, 'BOOLTEST', 'e%d' % x)
+
+    def test_weird_errors(self):
+        cf = self.newconfig()
+        cf.add_section("Foo")
+        self.assertRaises(ConfigParser.DuplicateSectionError,
+                          cf.add_section, "Foo")
+
+    def test_write(self):
+        cf = self.fromstring(
+            "[Long Line]\n"
+            "foo: this line is much, much longer than my editor\n"
+            "   likes it.\n"
+            "[DEFAULT]\n"
+            "foo: another very\n"
+            " long line"
+            )
+        output = StringIO.StringIO()
+        cf.write(output)
+        self.assertEqual(
+            output.getvalue(),
+            "[DEFAULT]\n"
+            "foo = another very\n"
+            "\tlong line\n"
+            "\n"
+            "[Long Line]\n"
+            "foo = this line is much, much longer than my editor\n"
+            "\tlikes it.\n"
+            "\n"
+            )
+
+    def test_set_string_types(self):
+        cf = self.fromstring("[sect]\n"
+                             "option1=foo\n")
+        # Check that we don't get an exception when setting values in
+        # an existing section using strings:
+        class mystr(str):
+            pass
+        cf.set("sect", "option1", "splat")
+        cf.set("sect", "option1", mystr("splat"))
+        cf.set("sect", "option2", "splat")
+        cf.set("sect", "option2", mystr("splat"))
+        try:
+            unicode
+        except NameError:
+            pass
+        else:
+            cf.set("sect", "option1", unicode("splat"))
+            cf.set("sect", "option2", unicode("splat"))
+
+    def test_read_returns_file_list(self):
+        file1 = test_support.findfile("cfgparser.1")
+        # check when we pass a mix of readable and non-readable files:
+        cf = self.newconfig()
+        parsed_files = cf.read([file1, "nonexistant-file"])
+        self.assertEqual(parsed_files, [file1])
+        self.assertEqual(cf.get("Foo Bar", "foo"), "newbar")
+        # check when we pass only a filename:
+        cf = self.newconfig()
+        parsed_files = cf.read(file1)
+        self.assertEqual(parsed_files, [file1])
+        self.assertEqual(cf.get("Foo Bar", "foo"), "newbar")
+        # check when we pass only missing files:
+        cf = self.newconfig()
+        parsed_files = cf.read(["nonexistant-file"])
+        self.assertEqual(parsed_files, [])
+        # check when we pass no files:
+        cf = self.newconfig()
+        parsed_files = cf.read([])
+        self.assertEqual(parsed_files, [])
+
+    # shared by subclasses
+    def get_interpolation_config(self):
+        return self.fromstring(
+            "[Foo]\n"
+            "bar=something %(with1)s interpolation (1 step)\n"
+            "bar9=something %(with9)s lots of interpolation (9 steps)\n"
+            "bar10=something %(with10)s lots of interpolation (10 steps)\n"
+            "bar11=something %(with11)s lots of interpolation (11 steps)\n"
+            "with11=%(with10)s\n"
+            "with10=%(with9)s\n"
+            "with9=%(with8)s\n"
+            "with8=%(With7)s\n"
+            "with7=%(WITH6)s\n"
+            "with6=%(with5)s\n"
+            "With5=%(with4)s\n"
+            "WITH4=%(with3)s\n"
+            "with3=%(with2)s\n"
+            "with2=%(with1)s\n"
+            "with1=with\n"
+            "\n"
+            "[Mutual Recursion]\n"
+            "foo=%(bar)s\n"
+            "bar=%(foo)s\n"
+            "\n"
+            "[Interpolation Error]\n"
+            "name=%(reference)s\n",
+            # no definition for 'reference'
+            defaults={"getname": "%(__name__)s"})
+
+    def check_items_config(self, expected):
+        cf = self.fromstring(
+            "[section]\n"
+            "name = value\n"
+            "key: |%(name)s| \n"
+            "getdefault: |%(default)s|\n"
+            "getname: |%(__name__)s|",
+            defaults={"default": "<default>"})
+        L = list(cf.items("section"))
+        L.sort()
+        self.assertEqual(L, expected)
+
+
+class ConfigParserTestCase(TestCaseBase):
+    config_class = ConfigParser.ConfigParser
+
+    def test_interpolation(self):
+        cf = self.get_interpolation_config()
+        eq = self.assertEqual
+        eq(cf.get("Foo", "getname"), "Foo")
+        eq(cf.get("Foo", "bar"), "something with interpolation (1 step)")
+        eq(cf.get("Foo", "bar9"),
+           "something with lots of interpolation (9 steps)")
+        eq(cf.get("Foo", "bar10"),
+           "something with lots of interpolation (10 steps)")
+        self.get_error(ConfigParser.InterpolationDepthError, "Foo", "bar11")
+
+    def test_interpolation_missing_value(self):
+        cf = self.get_interpolation_config()
+        e = self.get_error(ConfigParser.InterpolationError,
+                           "Interpolation Error", "name")
+        self.assertEqual(e.reference, "reference")
+        self.assertEqual(e.section, "Interpolation Error")
+        self.assertEqual(e.option, "name")
+
+    def test_items(self):
+        self.check_items_config([('default', '<default>'),
+                                 ('getdefault', '|<default>|'),
+                                 ('getname', '|section|'),
+                                 ('key', '|value|'),
+                                 ('name', 'value')])
+
+    def test_set_nonstring_types(self):
+        cf = self.newconfig()
+        cf.add_section('non-string')
+        cf.set('non-string', 'int', 1)
+        cf.set('non-string', 'list', [0, 1, 1, 2, 3, 5, 8, 13, '%('])
+        cf.set('non-string', 'dict', {'pi': 3.14159, '%(': 1,
+                                      '%(list)': '%(list)'})
+        cf.set('non-string', 'string_with_interpolation', '%(list)s')
+        self.assertEqual(cf.get('non-string', 'int', raw=True), 1)
+        self.assertRaises(TypeError, cf.get, 'non-string', 'int')
+        self.assertEqual(cf.get('non-string', 'list', raw=True),
+                         [0, 1, 1, 2, 3, 5, 8, 13, '%('])
+        self.assertRaises(TypeError, cf.get, 'non-string', 'list')
+        self.assertEqual(cf.get('non-string', 'dict', raw=True),
+                         {'pi': 3.14159, '%(': 1, '%(list)': '%(list)'})
+        self.assertRaises(TypeError, cf.get, 'non-string', 'dict')
+        self.assertEqual(cf.get('non-string', 'string_with_interpolation',
+                                raw=True), '%(list)s')
+        self.assertRaises(ValueError, cf.get, 'non-string',
+                          'string_with_interpolation', raw=False)
+
+
+class RawConfigParserTestCase(TestCaseBase):
+    config_class = ConfigParser.RawConfigParser
+
+    def test_interpolation(self):
+        cf = self.get_interpolation_config()
+        eq = self.assertEqual
+        eq(cf.get("Foo", "getname"), "%(__name__)s")
+        eq(cf.get("Foo", "bar"),
+           "something %(with1)s interpolation (1 step)")
+        eq(cf.get("Foo", "bar9"),
+           "something %(with9)s lots of interpolation (9 steps)")
+        eq(cf.get("Foo", "bar10"),
+           "something %(with10)s lots of interpolation (10 steps)")
+        eq(cf.get("Foo", "bar11"),
+           "something %(with11)s lots of interpolation (11 steps)")
+
+    def test_items(self):
+        self.check_items_config([('default', '<default>'),
+                                 ('getdefault', '|%(default)s|'),
+                                 ('getname', '|%(__name__)s|'),
+                                 ('key', '|%(name)s|'),
+                                 ('name', 'value')])
+
+    def test_set_nonstring_types(self):
+        cf = self.newconfig()
+        cf.add_section('non-string')
+        cf.set('non-string', 'int', 1)
+        cf.set('non-string', 'list', [0, 1, 1, 2, 3, 5, 8, 13])
+        cf.set('non-string', 'dict', {'pi': 3.14159})
+        self.assertEqual(cf.get('non-string', 'int'), 1)
+        self.assertEqual(cf.get('non-string', 'list'),
+                         [0, 1, 1, 2, 3, 5, 8, 13])
+        self.assertEqual(cf.get('non-string', 'dict'), {'pi': 3.14159})
+
+
+class SafeConfigParserTestCase(ConfigParserTestCase):
+    config_class = ConfigParser.SafeConfigParser
+
+    def test_safe_interpolation(self):
+        # See http://www.python.org/sf/511737
+        cf = self.fromstring("[section]\n"
+                             "option1=xxx\n"
+                             "option2=%(option1)s/xxx\n"
+                             "ok=%(option1)s/%%s\n"
+                             "not_ok=%(option2)s/%%s")
+        self.assertEqual(cf.get("section", "ok"), "xxx/%s")
+        self.assertEqual(cf.get("section", "not_ok"), "xxx/xxx/%s")
+
+    def test_set_nonstring_types(self):
+        cf = self.fromstring("[sect]\n"
+                             "option1=foo\n")
+        # Check that we get a TypeError when setting non-string values
+        # in an existing section:
+        self.assertRaises(TypeError, cf.set, "sect", "option1", 1)
+        self.assertRaises(TypeError, cf.set, "sect", "option1", 1.0)
+        self.assertRaises(TypeError, cf.set, "sect", "option1", object())
+        self.assertRaises(TypeError, cf.set, "sect", "option2", 1)
+        self.assertRaises(TypeError, cf.set, "sect", "option2", 1.0)
+        self.assertRaises(TypeError, cf.set, "sect", "option2", object())
+
+
+def test_main():
+    test_support.run_unittest(
+        ConfigParserTestCase,
+        RawConfigParserTestCase,
+        SafeConfigParserTestCase
+    )
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_cgi.py
===================================================================
--- vendor/Python/current/Lib/test/test_cgi.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_cgi.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,275 @@
+from test.test_support import verify, verbose
+import cgi
+import os
+import sys
+import tempfile
+from StringIO import StringIO
+
+class HackedSysModule:
+    # The regression test will have real values in sys.argv, which
+    # will completely confuse the test of the cgi module
+    argv = []
+    stdin = sys.stdin
+
+cgi.sys = HackedSysModule()
+
+try:
+    from cStringIO import StringIO
+except ImportError:
+    from StringIO import StringIO
+
+class ComparableException:
+    def __init__(self, err):
+        self.err = err
+
+    def __str__(self):
+        return str(self.err)
+
+    def __cmp__(self, anExc):
+        if not isinstance(anExc, Exception):
+            return -1
+        x = cmp(self.err.__class__, anExc.__class__)
+        if x != 0:
+            return x
+        return cmp(self.err.args, anExc.args)
+
+    def __getattr__(self, attr):
+        return getattr(self.err, attr)
+
+def do_test(buf, method):
+    env = {}
+    if method == "GET":
+        fp = None
+        env['REQUEST_METHOD'] = 'GET'
+        env['QUERY_STRING'] = buf
+    elif method == "POST":
+        fp = StringIO(buf)
+        env['REQUEST_METHOD'] = 'POST'
+        env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded'
+        env['CONTENT_LENGTH'] = str(len(buf))
+    else:
+        raise ValueError, "unknown method: %s" % method
+    try:
+        return cgi.parse(fp, env, strict_parsing=1)
+    except StandardError, err:
+        return ComparableException(err)
+
+# A list of test cases.  Each test case is a a two-tuple that contains
+# a string with the query and a dictionary with the expected result.
+
+parse_qsl_test_cases = [
+    ("", []),
+    ("&", []),
+    ("&&", []),
+    ("=", [('', '')]),
+    ("=a", [('', 'a')]),
+    ("a", [('a', '')]),
+    ("a=", [('a', '')]),
+    ("a=", [('a', '')]),
+    ("&a=b", [('a', 'b')]),
+    ("a=a+b&b=b+c", [('a', 'a b'), ('b', 'b c')]),
+    ("a=1&a=2", [('a', '1'), ('a', '2')]),
+]
+
+parse_strict_test_cases = [
+    ("", ValueError("bad query field: ''")),
+    ("&", ValueError("bad query field: ''")),
+    ("&&", ValueError("bad query field: ''")),
+    (";", ValueError("bad query field: ''")),
+    (";&;", ValueError("bad query field: ''")),
+    # Should the next few really be valid?
+    ("=", {}),
+    ("=&=", {}),
+    ("=;=", {}),
+    # This rest seem to make sense
+    ("=a", {'': ['a']}),
+    ("&=a", ValueError("bad query field: ''")),
+    ("=a&", ValueError("bad query field: ''")),
+    ("=&a", ValueError("bad query field: 'a'")),
+    ("b=a", {'b': ['a']}),
+    ("b+=a", {'b ': ['a']}),
+    ("a=b=a", {'a': ['b=a']}),
+    ("a=+b=a", {'a': [' b=a']}),
+    ("&b=a", ValueError("bad query field: ''")),
+    ("b&=a", ValueError("bad query field: 'b'")),
+    ("a=a+b&b=b+c", {'a': ['a b'], 'b': ['b c']}),
+    ("a=a+b&a=b+a", {'a': ['a b', 'b a']}),
+    ("x=1&y=2.0&z=2-3.%2b0", {'x': ['1'], 'y': ['2.0'], 'z': ['2-3.+0']}),
+    ("x=1;y=2.0&z=2-3.%2b0", {'x': ['1'], 'y': ['2.0'], 'z': ['2-3.+0']}),
+    ("x=1;y=2.0;z=2-3.%2b0", {'x': ['1'], 'y': ['2.0'], 'z': ['2-3.+0']}),
+    ("Hbc5161168c542333633315dee1182227:key_store_seqid=400006&cuyer=r&view=bustomer&order_id=0bb2e248638833d48cb7fed300000f1b&expire=964546263&lobale=en-US&kid=130003.300038&ss=env",
+     {'Hbc5161168c542333633315dee1182227:key_store_seqid': ['400006'],
+      'cuyer': ['r'],
+      'expire': ['964546263'],
+      'kid': ['130003.300038'],
+      'lobale': ['en-US'],
+      'order_id': ['0bb2e248638833d48cb7fed300000f1b'],
+      'ss': ['env'],
+      'view': ['bustomer'],
+      }),
+
+    ("group_id=5470&set=custom&_assigned_to=31392&_status=1&_category=100&SUBMIT=Browse",
+     {'SUBMIT': ['Browse'],
+      '_assigned_to': ['31392'],
+      '_category': ['100'],
+      '_status': ['1'],
+      'group_id': ['5470'],
+      'set': ['custom'],
+      })
+    ]
+
+def norm(list):
+    if type(list) == type([]):
+        list.sort()
+    return list
+
+def first_elts(list):
+    return map(lambda x:x[0], list)
+
+def first_second_elts(list):
+    return map(lambda p:(p[0], p[1][0]), list)
+
+def main():
+    for orig, expect in parse_qsl_test_cases:
+        result = cgi.parse_qsl(orig, keep_blank_values=True)
+        print repr(orig), '=>', result
+        verify(result == expect, "Error parsing %s" % repr(orig))
+
+    for orig, expect in parse_strict_test_cases:
+        # Test basic parsing
+        print repr(orig)
+        d = do_test(orig, "GET")
+        verify(d == expect, "Error parsing %s" % repr(orig))
+        d = do_test(orig, "POST")
+        verify(d == expect, "Error parsing %s" % repr(orig))
+
+        env = {'QUERY_STRING': orig}
+        fcd = cgi.FormContentDict(env)
+        sd = cgi.SvFormContentDict(env)
+        fs = cgi.FieldStorage(environ=env)
+        if type(expect) == type({}):
+            # test dict interface
+            verify(len(expect) == len(fcd))
+            verify(norm(expect.keys()) == norm(fcd.keys()))
+            verify(norm(expect.values()) == norm(fcd.values()))
+            verify(norm(expect.items()) == norm(fcd.items()))
+            verify(fcd.get("nonexistent field", "default") == "default")
+            verify(len(sd) == len(fs))
+            verify(norm(sd.keys()) == norm(fs.keys()))
+            verify(fs.getvalue("nonexistent field", "default") == "default")
+            # test individual fields
+            for key in expect.keys():
+                expect_val = expect[key]
+                verify(fcd.has_key(key))
+                verify(norm(fcd[key]) == norm(expect[key]))
+                verify(fcd.get(key, "default") == fcd[key])
+                verify(fs.has_key(key))
+                if len(expect_val) > 1:
+                    single_value = 0
+                else:
+                    single_value = 1
+                try:
+                    val = sd[key]
+                except IndexError:
+                    verify(not single_value)
+                    verify(fs.getvalue(key) == expect_val)
+                else:
+                    verify(single_value)
+                    verify(val == expect_val[0])
+                    verify(fs.getvalue(key) == expect_val[0])
+                verify(norm(sd.getlist(key)) == norm(expect_val))
+                if single_value:
+                    verify(norm(sd.values()) == \
+                           first_elts(norm(expect.values())))
+                    verify(norm(sd.items()) == \
+                           first_second_elts(norm(expect.items())))
+
+    # Test the weird FormContentDict classes
+    env = {'QUERY_STRING': "x=1&y=2.0&z=2-3.%2b0&1=1abc"}
+    expect = {'x': 1, 'y': 2.0, 'z': '2-3.+0', '1': '1abc'}
+    d = cgi.InterpFormContentDict(env)
+    for k, v in expect.items():
+        verify(d[k] == v)
+    for k, v in d.items():
+        verify(expect[k] == v)
+    verify(norm(expect.values()) == norm(d.values()))
+
+    print "Testing log"
+    cgi.log("Testing")
+    cgi.logfp = sys.stdout
+    cgi.initlog("%s", "Testing initlog 1")
+    cgi.log("%s", "Testing log 2")
+    if os.path.exists("/dev/null"):
+        cgi.logfp = None
+        cgi.logfile = "/dev/null"
+        cgi.initlog("%s", "Testing log 3")
+        cgi.log("Testing log 4")
+
+    print "Test FieldStorage methods that use readline"
+    # FieldStorage uses readline, which has the capacity to read all
+    # contents of the input file into memory; we use readline's size argument
+    # to prevent that for files that do not contain any newlines in
+    # non-GET/HEAD requests
+    class TestReadlineFile:
+        def __init__(self, file):
+            self.file = file
+            self.numcalls = 0
+
+        def readline(self, size=None):
+            self.numcalls += 1
+            if size:
+                return self.file.readline(size)
+            else:
+                return self.file.readline()
+
+        def __getattr__(self, name):
+            file = self.__dict__['file']
+            a = getattr(file, name)
+            if not isinstance(a, int):
+                setattr(self, name, a)
+            return a
+
+    f = TestReadlineFile(tempfile.TemporaryFile())
+    f.write('x' * 256 * 1024)
+    f.seek(0)
+    env = {'REQUEST_METHOD':'PUT'}
+    fs = cgi.FieldStorage(fp=f, environ=env)
+    # if we're not chunking properly, readline is only called twice
+    # (by read_binary); if we are chunking properly, it will be called 5 times
+    # as long as the chunksize is 1 << 16.
+    verify(f.numcalls > 2)
+
+    print "Test basic FieldStorage multipart parsing"
+    env = {'REQUEST_METHOD':'POST', 'CONTENT_TYPE':'multipart/form-data; boundary=---------------------------721837373350705526688164684', 'CONTENT_LENGTH':'558'}
+    postdata = """-----------------------------721837373350705526688164684
+Content-Disposition: form-data; name="id"
+
+1234
+-----------------------------721837373350705526688164684
+Content-Disposition: form-data; name="title"
+
+
+-----------------------------721837373350705526688164684
+Content-Disposition: form-data; name="file"; filename="test.txt"
+Content-Type: text/plain
+
+Testing 123.
+
+-----------------------------721837373350705526688164684
+Content-Disposition: form-data; name="submit"
+
+ Add\x20
+-----------------------------721837373350705526688164684--
+"""
+    fs = cgi.FieldStorage(fp=StringIO(postdata), environ=env)
+    verify(len(fs.list) == 4)
+    expect = [{'name':'id', 'filename':None, 'value':'1234'},
+              {'name':'title', 'filename':None, 'value':''},
+              {'name':'file', 'filename':'test.txt','value':'Testing 123.\n'},
+              {'name':'submit', 'filename':None, 'value':' Add '}]
+    for x in range(len(fs.list)):
+        for k, exp in expect[x].items():
+            got = getattr(fs.list[x], k)
+            verify(got == exp)
+
+main()

Added: vendor/Python/current/Lib/test/test_charmapcodec.py
===================================================================
--- vendor/Python/current/Lib/test/test_charmapcodec.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_charmapcodec.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,56 @@
+""" Python character mapping codec test
+
+This uses the test codec in testcodec.py and thus also tests the
+encodings package lookup scheme.
+
+Written by Marc-Andre Lemburg (mal at lemburg.com).
+
+(c) Copyright 2000 Guido van Rossum.
+
+"""#"
+
+import test.test_support, unittest
+
+import codecs
+
+# Register a search function which knows about our codec
+def codec_search_function(encoding):
+    if encoding == 'testcodec':
+        from test import testcodec
+        return tuple(testcodec.getregentry())
+    return None
+
+codecs.register(codec_search_function)
+
+# test codec's name (see test/testcodec.py)
+codecname = 'testcodec'
+
+class CharmapCodecTest(unittest.TestCase):
+    def test_constructorx(self):
+        self.assertEquals(unicode('abc', codecname), u'abc')
+        self.assertEquals(unicode('xdef', codecname), u'abcdef')
+        self.assertEquals(unicode('defx', codecname), u'defabc')
+        self.assertEquals(unicode('dxf', codecname), u'dabcf')
+        self.assertEquals(unicode('dxfx', codecname), u'dabcfabc')
+
+    def test_encodex(self):
+        self.assertEquals(u'abc'.encode(codecname), 'abc')
+        self.assertEquals(u'xdef'.encode(codecname), 'abcdef')
+        self.assertEquals(u'defx'.encode(codecname), 'defabc')
+        self.assertEquals(u'dxf'.encode(codecname), 'dabcf')
+        self.assertEquals(u'dxfx'.encode(codecname), 'dabcfabc')
+
+    def test_constructory(self):
+        self.assertEquals(unicode('ydef', codecname), u'def')
+        self.assertEquals(unicode('defy', codecname), u'def')
+        self.assertEquals(unicode('dyf', codecname), u'df')
+        self.assertEquals(unicode('dyfy', codecname), u'df')
+
+    def test_maptoundefined(self):
+        self.assertRaises(UnicodeError, unicode, 'abc\001', codecname)
+
+def test_main():
+    test.test_support.run_unittest(CharmapCodecTest)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_cl.py
===================================================================
--- vendor/Python/current/Lib/test/test_cl.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_cl.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,78 @@
+#! /usr/bin/env python
+"""Whimpy test script for the cl module
+   Roger E. Masse
+"""
+import cl
+from test.test_support import verbose
+
+clattrs = ['ADDED_ALGORITHM_ERROR', 'ALAW', 'ALGORITHM_ID',
+'ALGORITHM_VERSION', 'AUDIO', 'AWARE_ERROR', 'AWARE_MPEG_AUDIO',
+'AWARE_MULTIRATE', 'AWCMP_CONST_QUAL', 'AWCMP_FIXED_RATE',
+'AWCMP_INDEPENDENT', 'AWCMP_JOINT_STEREO', 'AWCMP_LOSSLESS',
+'AWCMP_MPEG_LAYER_I', 'AWCMP_MPEG_LAYER_II', 'AWCMP_STEREO',
+'Algorithm', 'AlgorithmNumber', 'AlgorithmType', 'AudioFormatName',
+'BAD_ALGORITHM_NAME', 'BAD_ALGORITHM_TYPE', 'BAD_BLOCK_SIZE',
+'BAD_BOARD', 'BAD_BUFFERING', 'BAD_BUFFERLENGTH_NEG',
+'BAD_BUFFERLENGTH_ODD', 'BAD_BUFFER_EXISTS', 'BAD_BUFFER_HANDLE',
+'BAD_BUFFER_POINTER', 'BAD_BUFFER_QUERY_SIZE', 'BAD_BUFFER_SIZE',
+'BAD_BUFFER_SIZE_POINTER', 'BAD_BUFFER_TYPE',
+'BAD_COMPRESSION_SCHEME', 'BAD_COMPRESSOR_HANDLE',
+'BAD_COMPRESSOR_HANDLE_POINTER', 'BAD_FRAME_SIZE',
+'BAD_FUNCTIONALITY', 'BAD_FUNCTION_POINTER', 'BAD_HEADER_SIZE',
+'BAD_INITIAL_VALUE', 'BAD_INTERNAL_FORMAT', 'BAD_LICENSE',
+'BAD_MIN_GT_MAX', 'BAD_NO_BUFFERSPACE', 'BAD_NUMBER_OF_BLOCKS',
+'BAD_PARAM', 'BAD_PARAM_ID_POINTER', 'BAD_PARAM_TYPE', 'BAD_POINTER',
+'BAD_PVBUFFER', 'BAD_SCHEME_POINTER', 'BAD_STREAM_HEADER',
+'BAD_STRING_POINTER', 'BAD_TEXT_STRING_PTR', 'BEST_FIT',
+'BIDIRECTIONAL', 'BITRATE_POLICY', 'BITRATE_TARGET',
+'BITS_PER_COMPONENT', 'BLENDING', 'BLOCK_SIZE', 'BOTTOM_UP',
+'BUFFER_NOT_CREATED', 'BUF_DATA', 'BUF_FRAME', 'BytesPerPixel',
+'BytesPerSample', 'CHANNEL_POLICY', 'CHROMA_THRESHOLD', 'CODEC',
+'COMPONENTS', 'COMPRESSED_BUFFER_SIZE', 'COMPRESSION_RATIO',
+'COMPRESSOR', 'CONTINUOUS_BLOCK', 'CONTINUOUS_NONBLOCK',
+'CompressImage', 'DATA', 'DECOMPRESSOR', 'DecompressImage',
+'EDGE_THRESHOLD', 'ENABLE_IMAGEINFO', 'END_OF_SEQUENCE', 'ENUM_VALUE',
+'EXACT_COMPRESSION_RATIO', 'EXTERNAL_DEVICE', 'FLOATING_ENUM_VALUE',
+'FLOATING_RANGE_VALUE', 'FRAME', 'FRAME_BUFFER_SIZE',
+'FRAME_BUFFER_SIZE_ZERO', 'FRAME_RATE', 'FRAME_TYPE', 'G711_ALAW',
+'G711_ULAW', 'GRAYSCALE', 'GetAlgorithmName', 'HDCC',
+'HDCC_SAMPLES_PER_TILE', 'HDCC_TILE_THRESHOLD', 'HEADER_START_CODE',
+'IMAGE_HEIGHT', 'IMAGE_WIDTH', 'INTERNAL_FORMAT',
+'INTERNAL_IMAGE_HEIGHT', 'INTERNAL_IMAGE_WIDTH', 'INTRA', 'JPEG',
+'JPEG_ERROR', 'JPEG_NUM_PARAMS', 'JPEG_QUALITY_FACTOR',
+'JPEG_QUANTIZATION_TABLES', 'JPEG_SOFTWARE', 'JPEG_STREAM_HEADERS',
+'KEYFRAME', 'LAST_FRAME_INDEX', 'LAYER', 'LUMA_THRESHOLD',
+'MAX_NUMBER_OF_AUDIO_ALGORITHMS', 'MAX_NUMBER_OF_ORIGINAL_FORMATS',
+'MAX_NUMBER_OF_PARAMS', 'MAX_NUMBER_OF_VIDEO_ALGORITHMS', 'MONO',
+'MPEG_VIDEO', 'MVC1', 'MVC2', 'MVC2_BLENDING', 'MVC2_BLENDING_OFF',
+'MVC2_BLENDING_ON', 'MVC2_CHROMA_THRESHOLD', 'MVC2_EDGE_THRESHOLD',
+'MVC2_ERROR', 'MVC2_LUMA_THRESHOLD', 'NEXT_NOT_AVAILABLE',
+'NOISE_MARGIN', 'NONE', 'NUMBER_OF_FRAMES', 'NUMBER_OF_PARAMS',
+'ORIENTATION', 'ORIGINAL_FORMAT', 'OpenCompressor',
+'OpenDecompressor', 'PARAM_OUT_OF_RANGE', 'PREDICTED', 'PREROLL',
+'ParamID', 'ParamNumber', 'ParamType', 'QUALITY_FACTOR',
+'QUALITY_LEVEL', 'QueryAlgorithms', 'QueryMaxHeaderSize',
+'QueryScheme', 'QuerySchemeFromName', 'RANGE_VALUE', 'RGB', 'RGB332',
+'RGB8', 'RGBA', 'RGBX', 'RLE', 'RLE24', 'RTR', 'RTR1',
+'RTR_QUALITY_LEVEL', 'SAMPLES_PER_TILE', 'SCHEME_BUSY',
+'SCHEME_NOT_AVAILABLE', 'SPEED', 'STEREO_INTERLEAVED',
+'STREAM_HEADERS', 'SetDefault', 'SetMax', 'SetMin', 'TILE_THRESHOLD',
+'TOP_DOWN', 'ULAW', 'UNCOMPRESSED', 'UNCOMPRESSED_AUDIO',
+'UNCOMPRESSED_VIDEO', 'UNKNOWN_SCHEME', 'VIDEO', 'VideoFormatName',
+'Y', 'YCbCr', 'YCbCr422', 'YCbCr422DC', 'YCbCr422HC', 'YUV', 'YUV422',
+'YUV422DC', 'YUV422HC', '__doc__', '__name__', 'cvt_type', 'error']
+
+
+# This is a very inobtrusive test for the existence of the cl
+# module and all its attributes.
+
+def main():
+    # touch all the attributes of al without doing anything
+    if verbose:
+        print 'Touching cl module attributes...'
+    for attr in clattrs:
+        if verbose:
+            print 'touching: ', attr
+        getattr(cl, attr)
+
+main()


Property changes on: vendor/Python/current/Lib/test/test_cl.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/test/test_class.py
===================================================================
--- vendor/Python/current/Lib/test/test_class.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_class.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,412 @@
+"Test the functionality of Python classes implementing operators."
+
+from test.test_support import TestFailed
+
+testmeths = [
+
+# Binary operations
+    "add",
+    "radd",
+    "sub",
+    "rsub",
+    "mul",
+    "rmul",
+    "div",
+    "rdiv",
+    "mod",
+    "rmod",
+    "divmod",
+    "rdivmod",
+    "pow",
+    "rpow",
+    "rshift",
+    "rrshift",
+    "lshift",
+    "rlshift",
+    "and",
+    "rand",
+    "or",
+    "ror",
+    "xor",
+    "rxor",
+
+# List/dict operations
+    "contains",
+    "getitem",
+    "getslice",
+    "setitem",
+    "setslice",
+    "delitem",
+    "delslice",
+
+# Unary operations
+    "neg",
+    "pos",
+    "abs",
+
+# generic operations
+    "init",
+    ]
+
+# These need to return something other than None
+#    "coerce",
+#    "hash",
+#    "str",
+#    "repr",
+#    "int",
+#    "long",
+#    "float",
+#    "oct",
+#    "hex",
+
+# These are separate because they can influence the test of other methods.
+#    "getattr",
+#    "setattr",
+#    "delattr",
+
+class AllTests:
+    def __coerce__(self, *args):
+        print "__coerce__:", args
+        return (self,) + args
+
+    def __hash__(self, *args):
+        print "__hash__:", args
+        return hash(id(self))
+
+    def __str__(self, *args):
+        print "__str__:", args
+        return "AllTests"
+
+    def __repr__(self, *args):
+        print "__repr__:", args
+        return "AllTests"
+
+    def __int__(self, *args):
+        print "__int__:", args
+        return 1
+
+    def __float__(self, *args):
+        print "__float__:", args
+        return 1.0
+
+    def __long__(self, *args):
+        print "__long__:", args
+        return 1L
+
+    def __oct__(self, *args):
+        print "__oct__:", args
+        return '01'
+
+    def __hex__(self, *args):
+        print "__hex__:", args
+        return '0x1'
+
+    def __cmp__(self, *args):
+        print "__cmp__:", args
+        return 0
+
+    def __del__(self, *args):
+        print "__del__:", args
+
+# Synthesize AllTests methods from the names in testmeths.
+
+method_template = """\
+def __%(method)s__(self, *args):
+    print "__%(method)s__:", args
+"""
+
+for method in testmeths:
+    exec method_template % locals() in AllTests.__dict__
+
+del method, method_template
+
+# this also tests __init__ of course.
+testme = AllTests()
+
+# Binary operations
+
+testme + 1
+1 + testme
+
+testme - 1
+1 - testme
+
+testme * 1
+1 * testme
+
+if 1/2 == 0:
+    testme / 1
+    1 / testme
+else:
+    # True division is in effect, so "/" doesn't map to __div__ etc; but
+    # the canned expected-output file requires that __div__ etc get called.
+    testme.__coerce__(1)
+    testme.__div__(1)
+    testme.__coerce__(1)
+    testme.__rdiv__(1)
+
+testme % 1
+1 % testme
+
+divmod(testme,1)
+divmod(1, testme)
+
+testme ** 1
+1 ** testme
+
+testme >> 1
+1 >> testme
+
+testme << 1
+1 << testme
+
+testme & 1
+1 & testme
+
+testme | 1
+1 | testme
+
+testme ^ 1
+1 ^ testme
+
+
+# List/dict operations
+
+class Empty: pass
+
+try:
+    1 in Empty()
+    print 'failed, should have raised TypeError'
+except TypeError:
+    pass
+
+1 in testme
+
+testme[1]
+testme[1] = 1
+del testme[1]
+
+testme[:42]
+testme[:42] = "The Answer"
+del testme[:42]
+
+testme[2:1024:10]
+testme[2:1024:10] = "A lot"
+del testme[2:1024:10]
+
+testme[:42, ..., :24:, 24, 100]
+testme[:42, ..., :24:, 24, 100] = "Strange"
+del testme[:42, ..., :24:, 24, 100]
+
+
+# Now remove the slice hooks to see if converting normal slices to slice
+# object works.
+
+del AllTests.__getslice__
+del AllTests.__setslice__
+del AllTests.__delslice__
+
+import sys
+if sys.platform[:4] != 'java':
+    testme[:42]
+    testme[:42] = "The Answer"
+    del testme[:42]
+else:
+    # This works under Jython, but the actual slice values are
+    # different.
+    print "__getitem__: (slice(0, 42, None),)"
+    print "__setitem__: (slice(0, 42, None), 'The Answer')"
+    print "__delitem__: (slice(0, 42, None),)"
+
+# Unary operations
+
+-testme
++testme
+abs(testme)
+int(testme)
+long(testme)
+float(testme)
+oct(testme)
+hex(testme)
+
+# And the rest...
+
+hash(testme)
+repr(testme)
+str(testme)
+
+testme == 1
+testme < 1
+testme > 1
+testme <> 1
+testme != 1
+1 == testme
+1 < testme
+1 > testme
+1 <> testme
+1 != testme
+
+# This test has to be last (duh.)
+
+del testme
+if sys.platform[:4] == 'java':
+    import java
+    java.lang.System.gc()
+
+# Interfering tests
+
+class ExtraTests:
+    def __getattr__(self, *args):
+        print "__getattr__:", args
+        return "SomeVal"
+
+    def __setattr__(self, *args):
+        print "__setattr__:", args
+
+    def __delattr__(self, *args):
+        print "__delattr__:", args
+
+testme = ExtraTests()
+testme.spam
+testme.eggs = "spam, spam, spam and ham"
+del testme.cardinal
+
+
+# return values of some method are type-checked
+class BadTypeClass:
+    def __int__(self):
+        return None
+    __float__ = __int__
+    __long__ = __int__
+    __str__ = __int__
+    __repr__ = __int__
+    __oct__ = __int__
+    __hex__ = __int__
+
+def check_exc(stmt, exception):
+    """Raise TestFailed if executing 'stmt' does not raise 'exception'
+    """
+    try:
+        exec stmt
+    except exception:
+        pass
+    else:
+        raise TestFailed, "%s should raise %s" % (stmt, exception)
+
+check_exc("int(BadTypeClass())", TypeError)
+check_exc("float(BadTypeClass())", TypeError)
+check_exc("long(BadTypeClass())", TypeError)
+check_exc("str(BadTypeClass())", TypeError)
+check_exc("repr(BadTypeClass())", TypeError)
+check_exc("oct(BadTypeClass())", TypeError)
+check_exc("hex(BadTypeClass())", TypeError)
+
+# mixing up ints and longs is okay
+class IntLongMixClass:
+    def __int__(self):
+        return 0L
+
+    def __long__(self):
+        return 0
+
+try:
+    int(IntLongMixClass())
+except TypeError:
+    raise TestFailed, "TypeError should not be raised"
+
+try:
+    long(IntLongMixClass())
+except TypeError:
+    raise TestFailed, "TypeError should not be raised"
+
+
+# Test correct errors from hash() on objects with comparisons but no __hash__
+
+class C0:
+    pass
+
+hash(C0()) # This should work; the next two should raise TypeError
+
+class C1:
+    def __cmp__(self, other): return 0
+
+check_exc("hash(C1())", TypeError)
+
+class C2:
+    def __eq__(self, other): return 1
+
+check_exc("hash(C2())", TypeError)
+
+# Test for SF bug 532646
+
+class A:
+    pass
+A.__call__ = A()
+a = A()
+try:
+    a() # This should not segfault
+except RuntimeError:
+    pass
+else:
+    raise TestFailed, "how could this not have overflowed the stack?"
+
+
+# Tests for exceptions raised in instance_getattr2().
+
+def booh(self):
+    raise AttributeError, "booh"
+
+class A:
+    a = property(booh)
+try:
+    A().a # Raised AttributeError: A instance has no attribute 'a'
+except AttributeError, x:
+    if str(x) != "booh":
+        print "attribute error for A().a got masked:", str(x)
+
+class E:
+    __eq__ = property(booh)
+E() == E() # In debug mode, caused a C-level assert() to fail
+
+class I:
+    __init__ = property(booh)
+try:
+    I() # In debug mode, printed XXX undetected error and raises AttributeError
+except AttributeError, x:
+    pass
+else:
+    print "attribute error for I.__init__ got masked"
+
+
+# Test comparison and hash of methods
+class A:
+    def __init__(self, x):
+        self.x = x
+    def f(self):
+        pass
+    def g(self):
+        pass
+    def __eq__(self, other):
+        return self.x == other.x
+    def __hash__(self):
+        return self.x
+class B(A):
+    pass
+
+a1 = A(1)
+a2 = A(2)
+assert a1.f == a1.f
+assert a1.f != a2.f
+assert a1.f != a1.g
+assert a1.f == A(1).f
+assert hash(a1.f) == hash(a1.f)
+assert hash(a1.f) == hash(A(1).f)
+
+assert A.f != a1.f
+assert A.f != A.g
+assert B.f == A.f
+assert hash(B.f) == hash(A.f)
+
+# the following triggers a SystemError in 2.4
+a = A(hash(A.f.im_func)^(-1))
+hash(a.f)

Added: vendor/Python/current/Lib/test/test_cmath.py
===================================================================
--- vendor/Python/current/Lib/test/test_cmath.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_cmath.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,52 @@
+#! /usr/bin/env python
+""" Simple test script for cmathmodule.c
+    Roger E. Masse
+"""
+import cmath, math
+from test.test_support import verbose, verify, TestFailed
+
+verify(abs(cmath.log(10) - math.log(10)) < 1e-9)
+verify(abs(cmath.log(10,2) - math.log(10,2)) < 1e-9)
+try:
+    cmath.log('a')
+except TypeError:
+    pass
+else:
+    raise TestFailed
+
+try:
+    cmath.log(10, 'a')
+except TypeError:
+    pass
+else:
+    raise TestFailed
+
+
+testdict = {'acos' : 1.0,
+            'acosh' : 1.0,
+            'asin' : 1.0,
+            'asinh' : 1.0,
+            'atan' : 0.2,
+            'atanh' : 0.2,
+            'cos' : 1.0,
+            'cosh' : 1.0,
+            'exp' : 1.0,
+            'log' : 1.0,
+            'log10' : 1.0,
+            'sin' : 1.0,
+            'sinh' : 1.0,
+            'sqrt' : 1.0,
+            'tan' : 1.0,
+            'tanh' : 1.0}
+
+for func in testdict.keys():
+    f = getattr(cmath, func)
+    r = f(testdict[func])
+    if verbose:
+        print 'Calling %s(%f) = %f' % (func, testdict[func], abs(r))
+
+p = cmath.pi
+e = cmath.e
+if verbose:
+    print 'PI = ', abs(p)
+    print 'E = ', abs(e)


Property changes on: vendor/Python/current/Lib/test/test_cmath.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/test/test_cmd_line.py
===================================================================
--- vendor/Python/current/Lib/test/test_cmd_line.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_cmd_line.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,93 @@
+
+import test.test_support, unittest
+import sys
+import popen2
+import subprocess
+
+class CmdLineTest(unittest.TestCase):
+    def start_python(self, cmd_line):
+        outfp, infp = popen2.popen4('"%s" %s' % (sys.executable, cmd_line))
+        infp.close()
+        data = outfp.read()
+        outfp.close()
+        # try to cleanup the child so we don't appear to leak when running
+        # with regrtest -R.  This should be a no-op on Windows.
+        popen2._cleanup()
+        return data
+
+    def exit_code(self, *args):
+        cmd_line = [sys.executable]
+        cmd_line.extend(args)
+        return subprocess.call(cmd_line, stdout=subprocess.PIPE,
+                                         stderr=subprocess.PIPE)
+
+    def test_directories(self):
+        self.assertNotEqual(self.exit_code('.'), 0)
+        self.assertNotEqual(self.exit_code('< .'), 0)
+
+    def verify_valid_flag(self, cmd_line):
+        data = self.start_python(cmd_line)
+        self.assertTrue(data == '' or data.endswith('\n'))
+        self.assertTrue('Traceback' not in data)
+
+    def test_environment(self):
+        self.verify_valid_flag('-E')
+
+    def test_optimize(self):
+        self.verify_valid_flag('-O')
+        self.verify_valid_flag('-OO')
+
+    def test_q(self):
+        self.verify_valid_flag('-Qold')
+        self.verify_valid_flag('-Qnew')
+        self.verify_valid_flag('-Qwarn')
+        self.verify_valid_flag('-Qwarnall')
+
+    def test_site_flag(self):
+        self.verify_valid_flag('-S')
+
+    def test_usage(self):
+        self.assertTrue('usage' in self.start_python('-h'))
+
+    def test_version(self):
+        version = 'Python %d.%d' % sys.version_info[:2]
+        self.assertTrue(self.start_python('-V').startswith(version))
+
+    def test_run_module(self):
+        # Test expected operation of the '-m' switch
+        # Switch needs an argument
+        self.assertNotEqual(self.exit_code('-m'), 0)
+        # Check we get an error for a nonexistent module
+        self.assertNotEqual(
+            self.exit_code('-m', 'fnord43520xyz'),
+            0)
+        # Check the runpy module also gives an error for
+        # a nonexistent module
+        self.assertNotEqual(
+            self.exit_code('-m', 'runpy', 'fnord43520xyz'),
+            0)
+        # All good if module is located and run successfully
+        self.assertEqual(
+            self.exit_code('-m', 'timeit', '-n', '1'),
+            0)
+
+    def test_run_code(self):
+        # Test expected operation of the '-c' switch
+        # Switch needs an argument
+        self.assertNotEqual(self.exit_code('-c'), 0)
+        # Check we get an error for an uncaught exception
+        self.assertNotEqual(
+            self.exit_code('-c', 'raise Exception'),
+            0)
+        # All good if execution is successful
+        self.assertEqual(
+            self.exit_code('-c', 'pass'),
+            0)
+
+
+def test_main():
+    test.test_support.run_unittest(CmdLineTest)
+    test.test_support.reap_children()
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_code.py
===================================================================
--- vendor/Python/current/Lib/test/test_code.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_code.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,102 @@
+"""This module includes tests of the code object representation.
+
+>>> def f(x):
+...     def g(y):
+...         return x + y
+...     return g
+...
+
+>>> dump(f.func_code)
+name: f
+argcount: 1
+names: ()
+varnames: ('x', 'g')
+cellvars: ('x',)
+freevars: ()
+nlocals: 2
+flags: 3
+consts: ('None', '<code object g>')
+
+>>> dump(f(4).func_code)
+name: g
+argcount: 1
+names: ()
+varnames: ('y',)
+cellvars: ()
+freevars: ('x',)
+nlocals: 1
+flags: 19
+consts: ('None',)
+
+>>> def h(x, y):
+...     a = x + y
+...     b = x - y
+...     c = a * b
+...     return c
+...
+>>> dump(h.func_code)
+name: h
+argcount: 2
+names: ()
+varnames: ('x', 'y', 'a', 'b', 'c')
+cellvars: ()
+freevars: ()
+nlocals: 5
+flags: 67
+consts: ('None',)
+
+>>> def attrs(obj):
+...     print obj.attr1
+...     print obj.attr2
+...     print obj.attr3
+
+>>> dump(attrs.func_code)
+name: attrs
+argcount: 1
+names: ('attr1', 'attr2', 'attr3')
+varnames: ('obj',)
+cellvars: ()
+freevars: ()
+nlocals: 1
+flags: 67
+consts: ('None',)
+
+>>> def optimize_away():
+...     'doc string'
+...     'not a docstring'
+...     53
+...     53L
+
+>>> dump(optimize_away.func_code)
+name: optimize_away
+argcount: 0
+names: ()
+varnames: ()
+cellvars: ()
+freevars: ()
+nlocals: 0
+flags: 67
+consts: ("'doc string'", 'None')
+
+"""
+
+def consts(t):
+    """Yield a doctest-safe sequence of object reprs."""
+    for elt in t:
+        r = repr(elt)
+        if r.startswith("<code object"):
+            yield "<code object %s>" % elt.co_name
+        else:
+            yield r
+
+def dump(co):
+    """Print out a text representation of a code object."""
+    for attr in ["name", "argcount", "names", "varnames", "cellvars",
+                 "freevars", "nlocals", "flags"]:
+        print "%s: %s" % (attr, getattr(co, "co_" + attr))
+    print "consts:", tuple(consts(co.co_consts))
+
+def test_main(verbose=None):
+    from test.test_support import run_doctest
+    from test import test_code
+    run_doctest(test_code, verbose)

Added: vendor/Python/current/Lib/test/test_codeccallbacks.py
===================================================================
--- vendor/Python/current/Lib/test/test_codeccallbacks.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_codeccallbacks.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,800 @@
+import test.test_support, unittest
+import sys, codecs, htmlentitydefs, unicodedata
+
+class PosReturn:
+    # this can be used for configurable callbacks
+
+    def __init__(self):
+        self.pos = 0
+
+    def handle(self, exc):
+        oldpos = self.pos
+        realpos = oldpos
+        if realpos<0:
+            realpos = len(exc.object) + realpos
+        # if we don't advance this time, terminate on the next call
+        # otherwise we'd get an endless loop
+        if realpos <= exc.start:
+            self.pos = len(exc.object)
+        return (u"<?>", oldpos)
+
+# A UnicodeEncodeError object with a bad start attribute
+class BadStartUnicodeEncodeError(UnicodeEncodeError):
+    def __init__(self):
+        UnicodeEncodeError.__init__(self, "ascii", u"", 0, 1, "bad")
+        self.start = []
+
+# A UnicodeEncodeError object with a bad object attribute
+class BadObjectUnicodeEncodeError(UnicodeEncodeError):
+    def __init__(self):
+        UnicodeEncodeError.__init__(self, "ascii", u"", 0, 1, "bad")
+        self.object = []
+
+# A UnicodeDecodeError object without an end attribute
+class NoEndUnicodeDecodeError(UnicodeDecodeError):
+    def __init__(self):
+        UnicodeDecodeError.__init__(self, "ascii", "", 0, 1, "bad")
+        del self.end
+
+# A UnicodeDecodeError object with a bad object attribute
+class BadObjectUnicodeDecodeError(UnicodeDecodeError):
+    def __init__(self):
+        UnicodeDecodeError.__init__(self, "ascii", "", 0, 1, "bad")
+        self.object = []
+
+# A UnicodeTranslateError object without a start attribute
+class NoStartUnicodeTranslateError(UnicodeTranslateError):
+    def __init__(self):
+        UnicodeTranslateError.__init__(self, u"", 0, 1, "bad")
+        del self.start
+
+# A UnicodeTranslateError object without an end attribute
+class NoEndUnicodeTranslateError(UnicodeTranslateError):
+    def __init__(self):
+        UnicodeTranslateError.__init__(self,  u"", 0, 1, "bad")
+        del self.end
+
+# A UnicodeTranslateError object without an object attribute
+class NoObjectUnicodeTranslateError(UnicodeTranslateError):
+    def __init__(self):
+        UnicodeTranslateError.__init__(self, u"", 0, 1, "bad")
+        del self.object
+
+class CodecCallbackTest(unittest.TestCase):
+
+    def test_xmlcharrefreplace(self):
+        # replace unencodable characters which numeric character entities.
+        # For ascii, latin-1 and charmaps this is completely implemented
+        # in C and should be reasonably fast.
+        s = u"\u30b9\u30d1\u30e2 \xe4nd eggs"
+        self.assertEqual(
+            s.encode("ascii", "xmlcharrefreplace"),
+            "&#12473;&#12497;&#12514; &#228;nd eggs"
+        )
+        self.assertEqual(
+            s.encode("latin-1", "xmlcharrefreplace"),
+            "&#12473;&#12497;&#12514; \xe4nd eggs"
+        )
+
+    def test_xmlcharnamereplace(self):
+        # This time use a named character entity for unencodable
+        # characters, if one is available.
+
+        def xmlcharnamereplace(exc):
+            if not isinstance(exc, UnicodeEncodeError):
+                raise TypeError("don't know how to handle %r" % exc)
+            l = []
+            for c in exc.object[exc.start:exc.end]:
+                try:
+                    l.append(u"&%s;" % htmlentitydefs.codepoint2name[ord(c)])
+                except KeyError:
+                    l.append(u"&#%d;" % ord(c))
+            return (u"".join(l), exc.end)
+
+        codecs.register_error(
+            "test.xmlcharnamereplace", xmlcharnamereplace)
+
+        sin = u"\xab\u211c\xbb = \u2329\u1234\u20ac\u232a"
+        sout = "&laquo;&real;&raquo; = &lang;&#4660;&euro;&rang;"
+        self.assertEqual(sin.encode("ascii", "test.xmlcharnamereplace"), sout)
+        sout = "\xab&real;\xbb = &lang;&#4660;&euro;&rang;"
+        self.assertEqual(sin.encode("latin-1", "test.xmlcharnamereplace"), sout)
+        sout = "\xab&real;\xbb = &lang;&#4660;\xa4&rang;"
+        self.assertEqual(sin.encode("iso-8859-15", "test.xmlcharnamereplace"), sout)
+
+    def test_uninamereplace(self):
+        # We're using the names from the unicode database this time,
+        # and we're doing "syntax highlighting" here, i.e. we include
+        # the replaced text in ANSI escape sequences. For this it is
+        # useful that the error handler is not called for every single
+        # unencodable character, but for a complete sequence of
+        # unencodable characters, otherwise we would output many
+        # unneccessary escape sequences.
+
+        def uninamereplace(exc):
+            if not isinstance(exc, UnicodeEncodeError):
+                raise TypeError("don't know how to handle %r" % exc)
+            l = []
+            for c in exc.object[exc.start:exc.end]:
+                l.append(unicodedata.name(c, u"0x%x" % ord(c)))
+            return (u"\033[1m%s\033[0m" % u", ".join(l), exc.end)
+
+        codecs.register_error(
+            "test.uninamereplace", uninamereplace)
+
+        sin = u"\xac\u1234\u20ac\u8000"
+        sout = "\033[1mNOT SIGN, ETHIOPIC SYLLABLE SEE, EURO SIGN, CJK UNIFIED IDEOGRAPH-8000\033[0m"
+        self.assertEqual(sin.encode("ascii", "test.uninamereplace"), sout)
+
+        sout = "\xac\033[1mETHIOPIC SYLLABLE SEE, EURO SIGN, CJK UNIFIED IDEOGRAPH-8000\033[0m"
+        self.assertEqual(sin.encode("latin-1", "test.uninamereplace"), sout)
+
+        sout = "\xac\033[1mETHIOPIC SYLLABLE SEE\033[0m\xa4\033[1mCJK UNIFIED IDEOGRAPH-8000\033[0m"
+        self.assertEqual(sin.encode("iso-8859-15", "test.uninamereplace"), sout)
+
+    def test_backslashescape(self):
+        # Does the same as the "unicode-escape" encoding, but with different
+        # base encodings.
+        sin = u"a\xac\u1234\u20ac\u8000"
+        if sys.maxunicode > 0xffff:
+            sin += unichr(sys.maxunicode)
+        sout = "a\\xac\\u1234\\u20ac\\u8000"
+        if sys.maxunicode > 0xffff:
+            sout += "\\U%08x" % sys.maxunicode
+        self.assertEqual(sin.encode("ascii", "backslashreplace"), sout)
+
+        sout = "a\xac\\u1234\\u20ac\\u8000"
+        if sys.maxunicode > 0xffff:
+            sout += "\\U%08x" % sys.maxunicode
+        self.assertEqual(sin.encode("latin-1", "backslashreplace"), sout)
+
+        sout = "a\xac\\u1234\xa4\\u8000"
+        if sys.maxunicode > 0xffff:
+            sout += "\\U%08x" % sys.maxunicode
+        self.assertEqual(sin.encode("iso-8859-15", "backslashreplace"), sout)
+
+    def test_decoderelaxedutf8(self):
+        # This is the test for a decoding callback handler,
+        # that relaxes the UTF-8 minimal encoding restriction.
+        # A null byte that is encoded as "\xc0\x80" will be
+        # decoded as a null byte. All other illegal sequences
+        # will be handled strictly.
+        def relaxedutf8(exc):
+            if not isinstance(exc, UnicodeDecodeError):
+                raise TypeError("don't know how to handle %r" % exc)
+            if exc.object[exc.start:exc.end].startswith("\xc0\x80"):
+                return (u"\x00", exc.start+2) # retry after two bytes
+            else:
+                raise exc
+
+        codecs.register_error(
+            "test.relaxedutf8", relaxedutf8)
+
+        sin = "a\x00b\xc0\x80c\xc3\xbc\xc0\x80\xc0\x80"
+        sout = u"a\x00b\x00c\xfc\x00\x00"
+        self.assertEqual(sin.decode("utf-8", "test.relaxedutf8"), sout)
+        sin = "\xc0\x80\xc0\x81"
+        self.assertRaises(UnicodeError, sin.decode, "utf-8", "test.relaxedutf8")
+
+    def test_charmapencode(self):
+        # For charmap encodings the replacement string will be
+        # mapped through the encoding again. This means, that
+        # to be able to use e.g. the "replace" handler, the
+        # charmap has to have a mapping for "?".
+        charmap = dict([ (ord(c), 2*c.upper()) for c in "abcdefgh"])
+        sin = u"abc"
+        sout = "AABBCC"
+        self.assertEquals(codecs.charmap_encode(sin, "strict", charmap)[0], sout)
+
+        sin = u"abcA"
+        self.assertRaises(UnicodeError, codecs.charmap_encode, sin, "strict", charmap)
+
+        charmap[ord("?")] = "XYZ"
+        sin = u"abcDEF"
+        sout = "AABBCCXYZXYZXYZ"
+        self.assertEquals(codecs.charmap_encode(sin, "replace", charmap)[0], sout)
+
+        charmap[ord("?")] = u"XYZ"
+        self.assertRaises(TypeError, codecs.charmap_encode, sin, "replace", charmap)
+
+        charmap[ord("?")] = u"XYZ"
+        self.assertRaises(TypeError, codecs.charmap_encode, sin, "replace", charmap)
+
+    def test_decodeunicodeinternal(self):
+        self.assertRaises(
+            UnicodeDecodeError,
+            "\x00\x00\x00\x00\x00".decode,
+            "unicode-internal",
+        )
+        if sys.maxunicode > 0xffff:
+            def handler_unicodeinternal(exc):
+                if not isinstance(exc, UnicodeDecodeError):
+                    raise TypeError("don't know how to handle %r" % exc)
+                return (u"\x01", 1)
+
+            self.assertEqual(
+                "\x00\x00\x00\x00\x00".decode("unicode-internal", "ignore"),
+                u"\u0000"
+            )
+
+            self.assertEqual(
+                "\x00\x00\x00\x00\x00".decode("unicode-internal", "replace"),
+                u"\u0000\ufffd"
+            )
+
+            codecs.register_error("test.hui", handler_unicodeinternal)
+
+            self.assertEqual(
+                "\x00\x00\x00\x00\x00".decode("unicode-internal", "test.hui"),
+                u"\u0000\u0001\u0000"
+            )
+
+    def test_callbacks(self):
+        def handler1(exc):
+            if not isinstance(exc, UnicodeEncodeError) \
+               and not isinstance(exc, UnicodeDecodeError):
+                raise TypeError("don't know how to handle %r" % exc)
+            l = [u"<%d>" % ord(exc.object[pos]) for pos in xrange(exc.start, exc.end)]
+            return (u"[%s]" % u"".join(l), exc.end)
+
+        codecs.register_error("test.handler1", handler1)
+
+        def handler2(exc):
+            if not isinstance(exc, UnicodeDecodeError):
+                raise TypeError("don't know how to handle %r" % exc)
+            l = [u"<%d>" % ord(exc.object[pos]) for pos in xrange(exc.start, exc.end)]
+            return (u"[%s]" % u"".join(l), exc.end+1) # skip one character
+
+        codecs.register_error("test.handler2", handler2)
+
+        s = "\x00\x81\x7f\x80\xff"
+
+        self.assertEqual(
+            s.decode("ascii", "test.handler1"),
+            u"\x00[<129>]\x7f[<128>][<255>]"
+        )
+        self.assertEqual(
+            s.decode("ascii", "test.handler2"),
+            u"\x00[<129>][<128>]"
+        )
+
+        self.assertEqual(
+            "\\u3042\u3xxx".decode("unicode-escape", "test.handler1"),
+            u"\u3042[<92><117><51><120>]xx"
+        )
+
+        self.assertEqual(
+            "\\u3042\u3xx".decode("unicode-escape", "test.handler1"),
+            u"\u3042[<92><117><51><120><120>]"
+        )
+
+        self.assertEqual(
+            codecs.charmap_decode("abc", "test.handler1", {ord("a"): u"z"})[0],
+            u"z[<98>][<99>]"
+        )
+
+        self.assertEqual(
+            u"g\xfc\xdfrk".encode("ascii", "test.handler1"),
+            u"g[<252><223>]rk"
+        )
+
+        self.assertEqual(
+            u"g\xfc\xdf".encode("ascii", "test.handler1"),
+            u"g[<252><223>]"
+        )
+
+    def test_longstrings(self):
+        # test long strings to check for memory overflow problems
+        errors = [ "strict", "ignore", "replace", "xmlcharrefreplace", "backslashreplace"]
+        # register the handlers under different names,
+        # to prevent the codec from recognizing the name
+        for err in errors:
+            codecs.register_error("test." + err, codecs.lookup_error(err))
+        l = 1000
+        errors += [ "test." + err for err in errors ]
+        for uni in [ s*l for s in (u"x", u"\u3042", u"a\xe4") ]:
+            for enc in ("ascii", "latin-1", "iso-8859-1", "iso-8859-15", "utf-8", "utf-7", "utf-16"):
+                for err in errors:
+                    try:
+                        uni.encode(enc, err)
+                    except UnicodeError:
+                        pass
+
+    def check_exceptionobjectargs(self, exctype, args, msg):
+        # Test UnicodeError subclasses: construction, attribute assignment and __str__ conversion
+        # check with one missing argument
+        self.assertRaises(TypeError, exctype, *args[:-1])
+        # check with one argument too much
+        self.assertRaises(TypeError, exctype, *(args + ["too much"]))
+        # check with one argument of the wrong type
+        wrongargs = [ "spam", u"eggs", 42, 1.0, None ]
+        for i in xrange(len(args)):
+            for wrongarg in wrongargs:
+                if type(wrongarg) is type(args[i]):
+                    continue
+                # build argument array
+                callargs = []
+                for j in xrange(len(args)):
+                    if i==j:
+                        callargs.append(wrongarg)
+                    else:
+                        callargs.append(args[i])
+                self.assertRaises(TypeError, exctype, *callargs)
+
+        # check with the correct number and type of arguments
+        exc = exctype(*args)
+        self.assertEquals(str(exc), msg)
+
+    def test_unicodeencodeerror(self):
+        self.check_exceptionobjectargs(
+            UnicodeEncodeError,
+            ["ascii", u"g\xfcrk", 1, 2, "ouch"],
+            "'ascii' codec can't encode character u'\\xfc' in position 1: ouch"
+        )
+        self.check_exceptionobjectargs(
+            UnicodeEncodeError,
+            ["ascii", u"g\xfcrk", 1, 4, "ouch"],
+            "'ascii' codec can't encode characters in position 1-3: ouch"
+        )
+        self.check_exceptionobjectargs(
+            UnicodeEncodeError,
+            ["ascii", u"\xfcx", 0, 1, "ouch"],
+            "'ascii' codec can't encode character u'\\xfc' in position 0: ouch"
+        )
+        self.check_exceptionobjectargs(
+            UnicodeEncodeError,
+            ["ascii", u"\u0100x", 0, 1, "ouch"],
+            "'ascii' codec can't encode character u'\\u0100' in position 0: ouch"
+        )
+        self.check_exceptionobjectargs(
+            UnicodeEncodeError,
+            ["ascii", u"\uffffx", 0, 1, "ouch"],
+            "'ascii' codec can't encode character u'\\uffff' in position 0: ouch"
+        )
+        if sys.maxunicode > 0xffff:
+            self.check_exceptionobjectargs(
+                UnicodeEncodeError,
+                ["ascii", u"\U00010000x", 0, 1, "ouch"],
+                "'ascii' codec can't encode character u'\\U00010000' in position 0: ouch"
+            )
+
+    def test_unicodedecodeerror(self):
+        self.check_exceptionobjectargs(
+            UnicodeDecodeError,
+            ["ascii", "g\xfcrk", 1, 2, "ouch"],
+            "'ascii' codec can't decode byte 0xfc in position 1: ouch"
+        )
+        self.check_exceptionobjectargs(
+            UnicodeDecodeError,
+            ["ascii", "g\xfcrk", 1, 3, "ouch"],
+            "'ascii' codec can't decode bytes in position 1-2: ouch"
+        )
+
+    def test_unicodetranslateerror(self):
+        self.check_exceptionobjectargs(
+            UnicodeTranslateError,
+            [u"g\xfcrk", 1, 2, "ouch"],
+            "can't translate character u'\\xfc' in position 1: ouch"
+        )
+        self.check_exceptionobjectargs(
+            UnicodeTranslateError,
+            [u"g\u0100rk", 1, 2, "ouch"],
+            "can't translate character u'\\u0100' in position 1: ouch"
+        )
+        self.check_exceptionobjectargs(
+            UnicodeTranslateError,
+            [u"g\uffffrk", 1, 2, "ouch"],
+            "can't translate character u'\\uffff' in position 1: ouch"
+        )
+        if sys.maxunicode > 0xffff:
+            self.check_exceptionobjectargs(
+                UnicodeTranslateError,
+                [u"g\U00010000rk", 1, 2, "ouch"],
+                "can't translate character u'\\U00010000' in position 1: ouch"
+            )
+        self.check_exceptionobjectargs(
+            UnicodeTranslateError,
+            [u"g\xfcrk", 1, 3, "ouch"],
+            "can't translate characters in position 1-2: ouch"
+        )
+
+    def test_badandgoodstrictexceptions(self):
+        # "strict" complains about a non-exception passed in
+        self.assertRaises(
+            TypeError,
+            codecs.strict_errors,
+            42
+        )
+        # "strict" complains about the wrong exception type
+        self.assertRaises(
+            Exception,
+            codecs.strict_errors,
+            Exception("ouch")
+        )
+
+        # If the correct exception is passed in, "strict" raises it
+        self.assertRaises(
+            UnicodeEncodeError,
+            codecs.strict_errors,
+            UnicodeEncodeError("ascii", u"\u3042", 0, 1, "ouch")
+        )
+
+    def test_badandgoodignoreexceptions(self):
+        # "ignore" complains about a non-exception passed in
+        self.assertRaises(
+           TypeError,
+           codecs.ignore_errors,
+           42
+        )
+        # "ignore" complains about the wrong exception type
+        self.assertRaises(
+           TypeError,
+           codecs.ignore_errors,
+           UnicodeError("ouch")
+        )
+        # If the correct exception is passed in, "ignore" returns an empty replacement
+        self.assertEquals(
+            codecs.ignore_errors(UnicodeEncodeError("ascii", u"\u3042", 0, 1, "ouch")),
+            (u"", 1)
+        )
+        self.assertEquals(
+            codecs.ignore_errors(UnicodeDecodeError("ascii", "\xff", 0, 1, "ouch")),
+            (u"", 1)
+        )
+        self.assertEquals(
+            codecs.ignore_errors(UnicodeTranslateError(u"\u3042", 0, 1, "ouch")),
+            (u"", 1)
+        )
+
+    def test_badandgoodreplaceexceptions(self):
+        # "replace" complains about a non-exception passed in
+        self.assertRaises(
+           TypeError,
+           codecs.replace_errors,
+           42
+        )
+        # "replace" complains about the wrong exception type
+        self.assertRaises(
+           TypeError,
+           codecs.replace_errors,
+           UnicodeError("ouch")
+        )
+        self.assertRaises(
+            TypeError,
+            codecs.replace_errors,
+            BadObjectUnicodeEncodeError()
+        )
+        self.assertRaises(
+            TypeError,
+            codecs.replace_errors,
+            BadObjectUnicodeDecodeError()
+        )
+        # With the correct exception, "replace" returns an "?" or u"\ufffd" replacement
+        self.assertEquals(
+            codecs.replace_errors(UnicodeEncodeError("ascii", u"\u3042", 0, 1, "ouch")),
+            (u"?", 1)
+        )
+        self.assertEquals(
+            codecs.replace_errors(UnicodeDecodeError("ascii", "\xff", 0, 1, "ouch")),
+            (u"\ufffd", 1)
+        )
+        self.assertEquals(
+            codecs.replace_errors(UnicodeTranslateError(u"\u3042", 0, 1, "ouch")),
+            (u"\ufffd", 1)
+        )
+
+    def test_badandgoodxmlcharrefreplaceexceptions(self):
+        # "xmlcharrefreplace" complains about a non-exception passed in
+        self.assertRaises(
+           TypeError,
+           codecs.xmlcharrefreplace_errors,
+           42
+        )
+        # "xmlcharrefreplace" complains about the wrong exception types
+        self.assertRaises(
+           TypeError,
+           codecs.xmlcharrefreplace_errors,
+           UnicodeError("ouch")
+        )
+        # "xmlcharrefreplace" can only be used for encoding
+        self.assertRaises(
+            TypeError,
+            codecs.xmlcharrefreplace_errors,
+            UnicodeDecodeError("ascii", "\xff", 0, 1, "ouch")
+        )
+        self.assertRaises(
+            TypeError,
+            codecs.xmlcharrefreplace_errors,
+            UnicodeTranslateError(u"\u3042", 0, 1, "ouch")
+        )
+        # Use the correct exception
+        cs = (0, 1, 9, 10, 99, 100, 999, 1000, 9999, 10000, 0x3042)
+        s = "".join(unichr(c) for c in cs)
+        self.assertEquals(
+            codecs.xmlcharrefreplace_errors(
+                UnicodeEncodeError("ascii", s, 0, len(s), "ouch")
+            ),
+            (u"".join(u"&#%d;" % ord(c) for c in s), len(s))
+        )
+
+    def test_badandgoodbackslashreplaceexceptions(self):
+        # "backslashreplace" complains about a non-exception passed in
+        self.assertRaises(
+           TypeError,
+           codecs.backslashreplace_errors,
+           42
+        )
+        # "backslashreplace" complains about the wrong exception types
+        self.assertRaises(
+           TypeError,
+           codecs.backslashreplace_errors,
+           UnicodeError("ouch")
+        )
+        # "backslashreplace" can only be used for encoding
+        self.assertRaises(
+            TypeError,
+            codecs.backslashreplace_errors,
+            UnicodeDecodeError("ascii", "\xff", 0, 1, "ouch")
+        )
+        self.assertRaises(
+            TypeError,
+            codecs.backslashreplace_errors,
+            UnicodeTranslateError(u"\u3042", 0, 1, "ouch")
+        )
+        # Use the correct exception
+        self.assertEquals(
+            codecs.backslashreplace_errors(UnicodeEncodeError("ascii", u"\u3042", 0, 1, "ouch")),
+            (u"\\u3042", 1)
+        )
+        self.assertEquals(
+            codecs.backslashreplace_errors(UnicodeEncodeError("ascii", u"\x00", 0, 1, "ouch")),
+            (u"\\x00", 1)
+        )
+        self.assertEquals(
+            codecs.backslashreplace_errors(UnicodeEncodeError("ascii", u"\xff", 0, 1, "ouch")),
+            (u"\\xff", 1)
+        )
+        self.assertEquals(
+            codecs.backslashreplace_errors(UnicodeEncodeError("ascii", u"\u0100", 0, 1, "ouch")),
+            (u"\\u0100", 1)
+        )
+        self.assertEquals(
+            codecs.backslashreplace_errors(UnicodeEncodeError("ascii", u"\uffff", 0, 1, "ouch")),
+            (u"\\uffff", 1)
+        )
+        if sys.maxunicode>0xffff:
+            self.assertEquals(
+                codecs.backslashreplace_errors(UnicodeEncodeError("ascii", u"\U00010000", 0, 1, "ouch")),
+                (u"\\U00010000", 1)
+            )
+            self.assertEquals(
+                codecs.backslashreplace_errors(UnicodeEncodeError("ascii", u"\U0010ffff", 0, 1, "ouch")),
+                (u"\\U0010ffff", 1)
+            )
+
+    def test_badhandlerresults(self):
+        results = ( 42, u"foo", (1,2,3), (u"foo", 1, 3), (u"foo", None), (u"foo",), ("foo", 1, 3), ("foo", None), ("foo",) )
+        encs = ("ascii", "latin-1", "iso-8859-1", "iso-8859-15")
+
+        for res in results:
+            codecs.register_error("test.badhandler", lambda: res)
+            for enc in encs:
+                self.assertRaises(
+                    TypeError,
+                    u"\u3042".encode,
+                    enc,
+                    "test.badhandler"
+                )
+            for (enc, bytes) in (
+                ("ascii", "\xff"),
+                ("utf-8", "\xff"),
+                ("utf-7", "+x-"),
+                ("unicode-internal", "\x00"),
+            ):
+                self.assertRaises(
+                    TypeError,
+                    bytes.decode,
+                    enc,
+                    "test.badhandler"
+                )
+
+    def test_lookup(self):
+        self.assertEquals(codecs.strict_errors, codecs.lookup_error("strict"))
+        self.assertEquals(codecs.ignore_errors, codecs.lookup_error("ignore"))
+        self.assertEquals(codecs.strict_errors, codecs.lookup_error("strict"))
+        self.assertEquals(
+            codecs.xmlcharrefreplace_errors,
+            codecs.lookup_error("xmlcharrefreplace")
+        )
+        self.assertEquals(
+            codecs.backslashreplace_errors,
+            codecs.lookup_error("backslashreplace")
+        )
+
+    def test_unencodablereplacement(self):
+        def unencrepl(exc):
+            if isinstance(exc, UnicodeEncodeError):
+                return (u"\u4242", exc.end)
+            else:
+                raise TypeError("don't know how to handle %r" % exc)
+        codecs.register_error("test.unencreplhandler", unencrepl)
+        for enc in ("ascii", "iso-8859-1", "iso-8859-15"):
+            self.assertRaises(
+                UnicodeEncodeError,
+                u"\u4242".encode,
+                enc,
+                "test.unencreplhandler"
+            )
+
+    def test_badregistercall(self):
+        # enhance coverage of:
+        # Modules/_codecsmodule.c::register_error()
+        # Python/codecs.c::PyCodec_RegisterError()
+        self.assertRaises(TypeError, codecs.register_error, 42)
+        self.assertRaises(TypeError, codecs.register_error, "test.dummy", 42)
+
+    def test_badlookupcall(self):
+        # enhance coverage of:
+        # Modules/_codecsmodule.c::lookup_error()
+        self.assertRaises(TypeError, codecs.lookup_error)
+
+    def test_unknownhandler(self):
+        # enhance coverage of:
+        # Modules/_codecsmodule.c::lookup_error()
+        self.assertRaises(LookupError, codecs.lookup_error, "test.unknown")
+
+    def test_xmlcharrefvalues(self):
+        # enhance coverage of:
+        # Python/codecs.c::PyCodec_XMLCharRefReplaceErrors()
+        # and inline implementations
+        v = (1, 5, 10, 50, 100, 500, 1000, 5000, 10000, 50000)
+        if sys.maxunicode>=100000:
+            v += (100000, 500000, 1000000)
+        s = u"".join([unichr(x) for x in v])
+        codecs.register_error("test.xmlcharrefreplace", codecs.xmlcharrefreplace_errors)
+        for enc in ("ascii", "iso-8859-15"):
+            for err in ("xmlcharrefreplace", "test.xmlcharrefreplace"):
+                s.encode(enc, err)
+
+    def test_decodehelper(self):
+        # enhance coverage of:
+        # Objects/unicodeobject.c::unicode_decode_call_errorhandler()
+        # and callers
+        self.assertRaises(LookupError, "\xff".decode, "ascii", "test.unknown")
+
+        def baddecodereturn1(exc):
+            return 42
+        codecs.register_error("test.baddecodereturn1", baddecodereturn1)
+        self.assertRaises(TypeError, "\xff".decode, "ascii", "test.baddecodereturn1")
+        self.assertRaises(TypeError, "\\".decode, "unicode-escape", "test.baddecodereturn1")
+        self.assertRaises(TypeError, "\\x0".decode, "unicode-escape", "test.baddecodereturn1")
+        self.assertRaises(TypeError, "\\x0y".decode, "unicode-escape", "test.baddecodereturn1")
+        self.assertRaises(TypeError, "\\Uffffeeee".decode, "unicode-escape", "test.baddecodereturn1")
+        self.assertRaises(TypeError, "\\uyyyy".decode, "raw-unicode-escape", "test.baddecodereturn1")
+
+        def baddecodereturn2(exc):
+            return (u"?", None)
+        codecs.register_error("test.baddecodereturn2", baddecodereturn2)
+        self.assertRaises(TypeError, "\xff".decode, "ascii", "test.baddecodereturn2")
+
+        handler = PosReturn()
+        codecs.register_error("test.posreturn", handler.handle)
+
+        # Valid negative position
+        handler.pos = -1
+        self.assertEquals("\xff0".decode("ascii", "test.posreturn"), u"<?>0")
+
+        # Valid negative position
+        handler.pos = -2
+        self.assertEquals("\xff0".decode("ascii", "test.posreturn"), u"<?><?>")
+
+        # Negative position out of bounds
+        handler.pos = -3
+        self.assertRaises(IndexError, "\xff0".decode, "ascii", "test.posreturn")
+
+        # Valid positive position
+        handler.pos = 1
+        self.assertEquals("\xff0".decode("ascii", "test.posreturn"), u"<?>0")
+
+        # Largest valid positive position (one beyond end of input)
+        handler.pos = 2
+        self.assertEquals("\xff0".decode("ascii", "test.posreturn"), u"<?>")
+
+        # Invalid positive position
+        handler.pos = 3
+        self.assertRaises(IndexError, "\xff0".decode, "ascii", "test.posreturn")
+
+        # Restart at the "0"
+        handler.pos = 6
+        self.assertEquals("\\uyyyy0".decode("raw-unicode-escape", "test.posreturn"), u"<?>0")
+
+        class D(dict):
+            def __getitem__(self, key):
+                raise ValueError
+        self.assertRaises(UnicodeError, codecs.charmap_decode, "\xff", "strict", {0xff: None})
+        self.assertRaises(ValueError, codecs.charmap_decode, "\xff", "strict", D())
+        self.assertRaises(TypeError, codecs.charmap_decode, "\xff", "strict", {0xff: sys.maxunicode+1})
+
+    def test_encodehelper(self):
+        # enhance coverage of:
+        # Objects/unicodeobject.c::unicode_encode_call_errorhandler()
+        # and callers
+        self.assertRaises(LookupError, u"\xff".encode, "ascii", "test.unknown")
+
+        def badencodereturn1(exc):
+            return 42
+        codecs.register_error("test.badencodereturn1", badencodereturn1)
+        self.assertRaises(TypeError, u"\xff".encode, "ascii", "test.badencodereturn1")
+
+        def badencodereturn2(exc):
+            return (u"?", None)
+        codecs.register_error("test.badencodereturn2", badencodereturn2)
+        self.assertRaises(TypeError, u"\xff".encode, "ascii", "test.badencodereturn2")
+
+        handler = PosReturn()
+        codecs.register_error("test.posreturn", handler.handle)
+
+        # Valid negative position
+        handler.pos = -1
+        self.assertEquals(u"\xff0".encode("ascii", "test.posreturn"), "<?>0")
+
+        # Valid negative position
+        handler.pos = -2
+        self.assertEquals(u"\xff0".encode("ascii", "test.posreturn"), "<?><?>")
+
+        # Negative position out of bounds
+        handler.pos = -3
+        self.assertRaises(IndexError, u"\xff0".encode, "ascii", "test.posreturn")
+
+        # Valid positive position
+        handler.pos = 1
+        self.assertEquals(u"\xff0".encode("ascii", "test.posreturn"), "<?>0")
+
+        # Largest valid positive position (one beyond end of input
+        handler.pos = 2
+        self.assertEquals(u"\xff0".encode("ascii", "test.posreturn"), "<?>")
+
+        # Invalid positive position
+        handler.pos = 3
+        self.assertRaises(IndexError, u"\xff0".encode, "ascii", "test.posreturn")
+
+        handler.pos = 0
+
+        class D(dict):
+            def __getitem__(self, key):
+                raise ValueError
+        for err in ("strict", "replace", "xmlcharrefreplace", "backslashreplace", "test.posreturn"):
+            self.assertRaises(UnicodeError, codecs.charmap_encode, u"\xff", err, {0xff: None})
+            self.assertRaises(ValueError, codecs.charmap_encode, u"\xff", err, D())
+            self.assertRaises(TypeError, codecs.charmap_encode, u"\xff", err, {0xff: 300})
+
+    def test_translatehelper(self):
+        # enhance coverage of:
+        # Objects/unicodeobject.c::unicode_encode_call_errorhandler()
+        # and callers
+        # (Unfortunately the errors argument is not directly accessible
+        # from Python, so we can't test that much)
+        class D(dict):
+            def __getitem__(self, key):
+                raise ValueError
+        self.assertRaises(ValueError, u"\xff".translate, D())
+        self.assertRaises(TypeError, u"\xff".translate, {0xff: sys.maxunicode+1})
+        self.assertRaises(TypeError, u"\xff".translate, {0xff: ()})
+
+    def test_bug828737(self):
+        charmap = {
+            ord("&"): u"&amp;",
+            ord("<"): u"&lt;",
+            ord(">"): u"&gt;",
+            ord('"'): u"&quot;",
+        }
+
+        for n in (1, 10, 100, 1000):
+            text = u'abc<def>ghi'*n
+            text.translate(charmap)
+
+def test_main():
+    test.test_support.run_unittest(CodecCallbackTest)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_codecencodings_cn.py
===================================================================
--- vendor/Python/current/Lib/test/test_codecencodings_cn.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_codecencodings_cn.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,61 @@
+#!/usr/bin/env python
+#
+# test_codecencodings_cn.py
+#   Codec encoding tests for PRC encodings.
+#
+
+from test import test_support
+from test import test_multibytecodec_support
+import unittest
+
+class Test_GB2312(test_multibytecodec_support.TestBase, unittest.TestCase):
+    encoding = 'gb2312'
+    tstring = test_multibytecodec_support.load_teststring('gb2312')
+    codectests = (
+        # invalid bytes
+        ("abc\x81\x81\xc1\xc4", "strict",  None),
+        ("abc\xc8", "strict",  None),
+        ("abc\x81\x81\xc1\xc4", "replace", u"abc\ufffd\u804a"),
+        ("abc\x81\x81\xc1\xc4\xc8", "replace", u"abc\ufffd\u804a\ufffd"),
+        ("abc\x81\x81\xc1\xc4", "ignore",  u"abc\u804a"),
+        ("\xc1\x64", "strict", None),
+    )
+
+class Test_GBK(test_multibytecodec_support.TestBase, unittest.TestCase):
+    encoding = 'gbk'
+    tstring = test_multibytecodec_support.load_teststring('gbk')
+    codectests = (
+        # invalid bytes
+        ("abc\x80\x80\xc1\xc4", "strict",  None),
+        ("abc\xc8", "strict",  None),
+        ("abc\x80\x80\xc1\xc4", "replace", u"abc\ufffd\u804a"),
+        ("abc\x80\x80\xc1\xc4\xc8", "replace", u"abc\ufffd\u804a\ufffd"),
+        ("abc\x80\x80\xc1\xc4", "ignore",  u"abc\u804a"),
+        ("\x83\x34\x83\x31", "strict", None),
+        (u"\u30fb", "strict", None),
+    )
+
+class Test_GB18030(test_multibytecodec_support.TestBase, unittest.TestCase):
+    encoding = 'gb18030'
+    tstring = test_multibytecodec_support.load_teststring('gb18030')
+    codectests = (
+        # invalid bytes
+        ("abc\x80\x80\xc1\xc4", "strict",  None),
+        ("abc\xc8", "strict",  None),
+        ("abc\x80\x80\xc1\xc4", "replace", u"abc\ufffd\u804a"),
+        ("abc\x80\x80\xc1\xc4\xc8", "replace", u"abc\ufffd\u804a\ufffd"),
+        ("abc\x80\x80\xc1\xc4", "ignore",  u"abc\u804a"),
+        ("abc\x84\x39\x84\x39\xc1\xc4", "replace", u"abc\ufffd\u804a"),
+        (u"\u30fb", "strict", "\x819\xa79"),
+    )
+    has_iso10646 = True
+
+def test_main():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(Test_GB2312))
+    suite.addTest(unittest.makeSuite(Test_GBK))
+    suite.addTest(unittest.makeSuite(Test_GB18030))
+    test_support.run_suite(suite)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_codecencodings_hk.py
===================================================================
--- vendor/Python/current/Lib/test/test_codecencodings_hk.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_codecencodings_hk.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,29 @@
+#!/usr/bin/env python
+#
+# test_codecencodings_hk.py
+#   Codec encoding tests for HongKong encodings.
+#
+
+from test import test_support
+from test import test_multibytecodec_support
+import unittest
+
+class Test_Big5HKSCS(test_multibytecodec_support.TestBase, unittest.TestCase):
+    encoding = 'big5hkscs'
+    tstring = test_multibytecodec_support.load_teststring('big5hkscs')
+    codectests = (
+        # invalid bytes
+        ("abc\x80\x80\xc1\xc4", "strict",  None),
+        ("abc\xc8", "strict",  None),
+        ("abc\x80\x80\xc1\xc4", "replace", u"abc\ufffd\u8b10"),
+        ("abc\x80\x80\xc1\xc4\xc8", "replace", u"abc\ufffd\u8b10\ufffd"),
+        ("abc\x80\x80\xc1\xc4", "ignore",  u"abc\u8b10"),
+    )
+
+def test_main():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(Test_Big5HKSCS))
+    test_support.run_suite(suite)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_codecencodings_jp.py
===================================================================
--- vendor/Python/current/Lib/test/test_codecencodings_jp.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_codecencodings_jp.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,111 @@
+#!/usr/bin/env python
+#
+# test_codecencodings_jp.py
+#   Codec encoding tests for Japanese encodings.
+#
+
+from test import test_support
+from test import test_multibytecodec_support
+import unittest
+
+class Test_CP932(test_multibytecodec_support.TestBase, unittest.TestCase):
+    encoding = 'cp932'
+    tstring = test_multibytecodec_support.load_teststring('shift_jis')
+    codectests = (
+        # invalid bytes
+        ("abc\x81\x00\x81\x00\x82\x84", "strict",  None),
+        ("abc\xf8", "strict",  None),
+        ("abc\x81\x00\x82\x84", "replace", u"abc\ufffd\uff44"),
+        ("abc\x81\x00\x82\x84\x88", "replace", u"abc\ufffd\uff44\ufffd"),
+        ("abc\x81\x00\x82\x84", "ignore",  u"abc\uff44"),
+        # sjis vs cp932
+        ("\\\x7e", "replace", u"\\\x7e"),
+        ("\x81\x5f\x81\x61\x81\x7c", "replace", u"\uff3c\u2225\uff0d"),
+    )
+
+class Test_EUC_JISX0213(test_multibytecodec_support.TestBase,
+                        unittest.TestCase):
+    encoding = 'euc_jisx0213'
+    tstring = test_multibytecodec_support.load_teststring('euc_jisx0213')
+    codectests = (
+        # invalid bytes
+        ("abc\x80\x80\xc1\xc4", "strict",  None),
+        ("abc\xc8", "strict",  None),
+        ("abc\x80\x80\xc1\xc4", "replace", u"abc\ufffd\u7956"),
+        ("abc\x80\x80\xc1\xc4\xc8", "replace", u"abc\ufffd\u7956\ufffd"),
+        ("abc\x80\x80\xc1\xc4", "ignore",  u"abc\u7956"),
+        ("abc\x8f\x83\x83", "replace", u"abc\ufffd"),
+        ("\xc1\x64", "strict", None),
+        ("\xa1\xc0", "strict", u"\uff3c"),
+    )
+    xmlcharnametest = (
+        u"\xab\u211c\xbb = \u2329\u1234\u232a",
+        "\xa9\xa8&real;\xa9\xb2 = &lang;&#4660;&rang;"
+    )
+
+eucjp_commontests = (
+    ("abc\x80\x80\xc1\xc4", "strict",  None),
+    ("abc\xc8", "strict",  None),
+    ("abc\x80\x80\xc1\xc4", "replace", u"abc\ufffd\u7956"),
+    ("abc\x80\x80\xc1\xc4\xc8", "replace", u"abc\ufffd\u7956\ufffd"),
+    ("abc\x80\x80\xc1\xc4", "ignore",  u"abc\u7956"),
+    ("abc\x8f\x83\x83", "replace", u"abc\ufffd"),
+    ("\xc1\x64", "strict", None),
+)
+
+class Test_EUC_JP_COMPAT(test_multibytecodec_support.TestBase,
+                         unittest.TestCase):
+    encoding = 'euc_jp'
+    tstring = test_multibytecodec_support.load_teststring('euc_jp')
+    codectests = eucjp_commontests + (
+        ("\xa1\xc0\\", "strict", u"\uff3c\\"),
+        (u"\xa5", "strict", "\x5c"),
+        (u"\u203e", "strict", "\x7e"),
+    )
+
+shiftjis_commonenctests = (
+    ("abc\x80\x80\x82\x84", "strict",  None),
+    ("abc\xf8", "strict",  None),
+    ("abc\x80\x80\x82\x84", "replace", u"abc\ufffd\uff44"),
+    ("abc\x80\x80\x82\x84\x88", "replace", u"abc\ufffd\uff44\ufffd"),
+    ("abc\x80\x80\x82\x84def", "ignore",  u"abc\uff44def"),
+)
+
+class Test_SJIS_COMPAT(test_multibytecodec_support.TestBase, unittest.TestCase):
+    encoding = 'shift_jis'
+    tstring = test_multibytecodec_support.load_teststring('shift_jis')
+    codectests = shiftjis_commonenctests + (
+        ("\\\x7e", "strict", u"\\\x7e"),
+        ("\x81\x5f\x81\x61\x81\x7c", "strict", u"\uff3c\u2016\u2212"),
+    )
+
+class Test_SJISX0213(test_multibytecodec_support.TestBase, unittest.TestCase):
+    encoding = 'shift_jisx0213'
+    tstring = test_multibytecodec_support.load_teststring('shift_jisx0213')
+    codectests = (
+        # invalid bytes
+        ("abc\x80\x80\x82\x84", "strict",  None),
+        ("abc\xf8", "strict",  None),
+        ("abc\x80\x80\x82\x84", "replace", u"abc\ufffd\uff44"),
+        ("abc\x80\x80\x82\x84\x88", "replace", u"abc\ufffd\uff44\ufffd"),
+        ("abc\x80\x80\x82\x84def", "ignore",  u"abc\uff44def"),
+        # sjis vs cp932
+        ("\\\x7e", "replace", u"\xa5\u203e"),
+        ("\x81\x5f\x81\x61\x81\x7c", "replace", u"\x5c\u2016\u2212"),
+    )
+    xmlcharnametest = (
+        u"\xab\u211c\xbb = \u2329\u1234\u232a",
+        "\x85G&real;\x85Q = &lang;&#4660;&rang;"
+    )
+
+def test_main():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(Test_CP932))
+    suite.addTest(unittest.makeSuite(Test_EUC_JISX0213))
+    suite.addTest(unittest.makeSuite(Test_EUC_JP_COMPAT))
+    suite.addTest(unittest.makeSuite(Test_SJIS_COMPAT))
+    suite.addTest(unittest.makeSuite(Test_SJISX0213))
+    test_support.run_suite(suite)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_codecencodings_kr.py
===================================================================
--- vendor/Python/current/Lib/test/test_codecencodings_kr.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_codecencodings_kr.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,55 @@
+#!/usr/bin/env python
+#
+# test_codecencodings_kr.py
+#   Codec encoding tests for ROK encodings.
+#
+
+from test import test_support
+from test import test_multibytecodec_support
+import unittest
+
+class Test_CP949(test_multibytecodec_support.TestBase, unittest.TestCase):
+    encoding = 'cp949'
+    tstring = test_multibytecodec_support.load_teststring('cp949')
+    codectests = (
+        # invalid bytes
+        ("abc\x80\x80\xc1\xc4", "strict",  None),
+        ("abc\xc8", "strict",  None),
+        ("abc\x80\x80\xc1\xc4", "replace", u"abc\ufffd\uc894"),
+        ("abc\x80\x80\xc1\xc4\xc8", "replace", u"abc\ufffd\uc894\ufffd"),
+        ("abc\x80\x80\xc1\xc4", "ignore",  u"abc\uc894"),
+    )
+
+class Test_EUCKR(test_multibytecodec_support.TestBase, unittest.TestCase):
+    encoding = 'euc_kr'
+    tstring = test_multibytecodec_support.load_teststring('euc_kr')
+    codectests = (
+        # invalid bytes
+        ("abc\x80\x80\xc1\xc4", "strict",  None),
+        ("abc\xc8", "strict",  None),
+        ("abc\x80\x80\xc1\xc4", "replace", u"abc\ufffd\uc894"),
+        ("abc\x80\x80\xc1\xc4\xc8", "replace", u"abc\ufffd\uc894\ufffd"),
+        ("abc\x80\x80\xc1\xc4", "ignore",  u"abc\uc894"),
+    )
+
+class Test_JOHAB(test_multibytecodec_support.TestBase, unittest.TestCase):
+    encoding = 'johab'
+    tstring = test_multibytecodec_support.load_teststring('johab')
+    codectests = (
+        # invalid bytes
+        ("abc\x80\x80\xc1\xc4", "strict",  None),
+        ("abc\xc8", "strict",  None),
+        ("abc\x80\x80\xc1\xc4", "replace", u"abc\ufffd\ucd27"),
+        ("abc\x80\x80\xc1\xc4\xc8", "replace", u"abc\ufffd\ucd27\ufffd"),
+        ("abc\x80\x80\xc1\xc4", "ignore",  u"abc\ucd27"),
+    )
+
+def test_main():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(Test_CP949))
+    suite.addTest(unittest.makeSuite(Test_EUCKR))
+    suite.addTest(unittest.makeSuite(Test_JOHAB))
+    test_support.run_suite(suite)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_codecencodings_tw.py
===================================================================
--- vendor/Python/current/Lib/test/test_codecencodings_tw.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_codecencodings_tw.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,29 @@
+#!/usr/bin/env python
+#
+# test_codecencodings_tw.py
+#   Codec encoding tests for ROC encodings.
+#
+
+from test import test_support
+from test import test_multibytecodec_support
+import unittest
+
+class Test_Big5(test_multibytecodec_support.TestBase, unittest.TestCase):
+    encoding = 'big5'
+    tstring = test_multibytecodec_support.load_teststring('big5')
+    codectests = (
+        # invalid bytes
+        ("abc\x80\x80\xc1\xc4", "strict",  None),
+        ("abc\xc8", "strict",  None),
+        ("abc\x80\x80\xc1\xc4", "replace", u"abc\ufffd\u8b10"),
+        ("abc\x80\x80\xc1\xc4\xc8", "replace", u"abc\ufffd\u8b10\ufffd"),
+        ("abc\x80\x80\xc1\xc4", "ignore",  u"abc\u8b10"),
+    )
+
+def test_main():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(Test_Big5))
+    test_support.run_suite(suite)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_codecmaps_cn.py
===================================================================
--- vendor/Python/current/Lib/test/test_codecmaps_cn.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_codecmaps_cn.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,29 @@
+#!/usr/bin/env python
+#
+# test_codecmaps_cn.py
+#   Codec mapping tests for PRC encodings
+#
+
+from test import test_support
+from test import test_multibytecodec_support
+import unittest
+
+class TestGB2312Map(test_multibytecodec_support.TestBase_Mapping,
+                   unittest.TestCase):
+    encoding = 'gb2312'
+    mapfileurl = 'http://people.freebsd.org/~perky/i18n/EUC-CN.TXT'
+
+class TestGBKMap(test_multibytecodec_support.TestBase_Mapping,
+                   unittest.TestCase):
+    encoding = 'gbk'
+    mapfileurl = 'http://www.unicode.org/Public/MAPPINGS/VENDORS/' \
+                 'MICSFT/WINDOWS/CP936.TXT'
+
+def test_main():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(TestGB2312Map))
+    suite.addTest(unittest.makeSuite(TestGBKMap))
+    test_support.run_suite(suite)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_codecmaps_hk.py
===================================================================
--- vendor/Python/current/Lib/test/test_codecmaps_hk.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_codecmaps_hk.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,22 @@
+#!/usr/bin/env python
+#
+# test_codecmaps_hk.py
+#   Codec mapping tests for HongKong encodings
+#
+
+from test import test_support
+from test import test_multibytecodec_support
+import unittest
+
+class TestBig5HKSCSMap(test_multibytecodec_support.TestBase_Mapping,
+                       unittest.TestCase):
+    encoding = 'big5hkscs'
+    mapfileurl = 'http://people.freebsd.org/~perky/i18n/BIG5HKSCS.TXT'
+
+def test_main():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(TestBig5HKSCSMap))
+    test_support.run_suite(suite)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_codecmaps_jp.py
===================================================================
--- vendor/Python/current/Lib/test/test_codecmaps_jp.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_codecmaps_jp.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,73 @@
+#!/usr/bin/env python
+#
+# test_codecmaps_jp.py
+#   Codec mapping tests for Japanese encodings
+#
+
+from test import test_support
+from test import test_multibytecodec_support
+import unittest
+
+class TestCP932Map(test_multibytecodec_support.TestBase_Mapping,
+                   unittest.TestCase):
+    encoding = 'cp932'
+    mapfileurl = 'http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/' \
+                 'WINDOWS/CP932.TXT'
+    supmaps = [
+        ('\x80', u'\u0080'),
+        ('\xa0', u'\uf8f0'),
+        ('\xfd', u'\uf8f1'),
+        ('\xfe', u'\uf8f2'),
+        ('\xff', u'\uf8f3'),
+    ]
+    for i in range(0xa1, 0xe0):
+        supmaps.append((chr(i), unichr(i+0xfec0)))
+
+
+class TestEUCJPCOMPATMap(test_multibytecodec_support.TestBase_Mapping,
+                         unittest.TestCase):
+    encoding = 'euc_jp'
+    mapfilename = 'EUC-JP.TXT'
+    mapfileurl = 'http://people.freebsd.org/~perky/i18n/EUC-JP.TXT'
+
+
+class TestSJISCOMPATMap(test_multibytecodec_support.TestBase_Mapping,
+                        unittest.TestCase):
+    encoding = 'shift_jis'
+    mapfilename = 'SHIFTJIS.TXT'
+    mapfileurl = 'http://www.unicode.org/Public/MAPPINGS/OBSOLETE' \
+                 '/EASTASIA/JIS/SHIFTJIS.TXT'
+    pass_enctest = [
+        ('\x81_', u'\\'),
+    ]
+    pass_dectest = [
+        ('\\', u'\xa5'),
+        ('~', u'\u203e'),
+        ('\x81_', u'\\'),
+    ]
+
+class TestEUCJISX0213Map(test_multibytecodec_support.TestBase_Mapping,
+                         unittest.TestCase):
+    encoding = 'euc_jisx0213'
+    mapfilename = 'EUC-JISX0213.TXT'
+    mapfileurl = 'http://people.freebsd.org/~perky/i18n/EUC-JISX0213.TXT'
+
+
+class TestSJISX0213Map(test_multibytecodec_support.TestBase_Mapping,
+                       unittest.TestCase):
+    encoding = 'shift_jisx0213'
+    mapfilename = 'SHIFT_JISX0213.TXT'
+    mapfileurl = 'http://people.freebsd.org/~perky/i18n/SHIFT_JISX0213.TXT'
+
+
+def test_main():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(TestCP932Map))
+    suite.addTest(unittest.makeSuite(TestEUCJPCOMPATMap))
+    suite.addTest(unittest.makeSuite(TestSJISCOMPATMap))
+    suite.addTest(unittest.makeSuite(TestEUCJISX0213Map))
+    suite.addTest(unittest.makeSuite(TestSJISX0213Map))
+    test_support.run_suite(suite)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_codecmaps_kr.py
===================================================================
--- vendor/Python/current/Lib/test/test_codecmaps_kr.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_codecmaps_kr.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,44 @@
+#!/usr/bin/env python
+#
+# test_codecmaps_kr.py
+#   Codec mapping tests for ROK encodings
+#
+
+from test import test_support
+from test import test_multibytecodec_support
+import unittest
+
+class TestCP949Map(test_multibytecodec_support.TestBase_Mapping,
+                   unittest.TestCase):
+    encoding = 'cp949'
+    mapfileurl = 'http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT' \
+                 '/WINDOWS/CP949.TXT'
+
+
+class TestEUCKRMap(test_multibytecodec_support.TestBase_Mapping,
+                   unittest.TestCase):
+    encoding = 'euc_kr'
+    mapfileurl = 'http://people.freebsd.org/~perky/i18n/EUC-KR.TXT'
+
+
+class TestJOHABMap(test_multibytecodec_support.TestBase_Mapping,
+                   unittest.TestCase):
+    encoding = 'johab'
+    mapfileurl = 'http://www.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/' \
+                 'KSC/JOHAB.TXT'
+    # KS X 1001 standard assigned 0x5c as WON SIGN.
+    # but, in early 90s that is the only era used johab widely,
+    # the most softwares implements it as REVERSE SOLIDUS.
+    # So, we ignore the standard here.
+    pass_enctest = [('\\', u'\u20a9')]
+    pass_dectest = [('\\', u'\u20a9')]
+
+def test_main():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(TestCP949Map))
+    suite.addTest(unittest.makeSuite(TestEUCKRMap))
+    suite.addTest(unittest.makeSuite(TestJOHABMap))
+    test_support.run_suite(suite)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_codecmaps_tw.py
===================================================================
--- vendor/Python/current/Lib/test/test_codecmaps_tw.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_codecmaps_tw.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,34 @@
+#!/usr/bin/env python
+#
+# test_codecmaps_tw.py
+#   Codec mapping tests for ROC encodings
+#
+
+from test import test_support
+from test import test_multibytecodec_support
+import unittest
+
+class TestBIG5Map(test_multibytecodec_support.TestBase_Mapping,
+                  unittest.TestCase):
+    encoding = 'big5'
+    mapfileurl = 'http://www.unicode.org/Public/MAPPINGS/OBSOLETE/' \
+                 'EASTASIA/OTHER/BIG5.TXT'
+
+class TestCP950Map(test_multibytecodec_support.TestBase_Mapping,
+                   unittest.TestCase):
+    encoding = 'cp950'
+    mapfileurl = 'http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/' \
+                 'WINDOWS/CP950.TXT'
+    pass_enctest = [
+        ('\xa2\xcc', u'\u5341'),
+        ('\xa2\xce', u'\u5345'),
+    ]
+
+def test_main():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(TestBIG5Map))
+    suite.addTest(unittest.makeSuite(TestCP950Map))
+    test_support.run_suite(suite)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_codecs.py
===================================================================
--- vendor/Python/current/Lib/test/test_codecs.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_codecs.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1279 @@
+from __future__ import with_statement
+from test import test_support
+import unittest
+import codecs
+import sys, StringIO, _testcapi
+
+class Queue(object):
+    """
+    queue: write bytes at one end, read bytes from the other end
+    """
+    def __init__(self):
+        self._buffer = ""
+
+    def write(self, chars):
+        self._buffer += chars
+
+    def read(self, size=-1):
+        if size<0:
+            s = self._buffer
+            self._buffer = ""
+            return s
+        else:
+            s = self._buffer[:size]
+            self._buffer = self._buffer[size:]
+            return s
+
+class ReadTest(unittest.TestCase):
+    def check_partial(self, input, partialresults):
+        # get a StreamReader for the encoding and feed the bytestring version
+        # of input to the reader byte by byte. Read every available from
+        # the StreamReader and check that the results equal the appropriate
+        # entries from partialresults.
+        q = Queue()
+        r = codecs.getreader(self.encoding)(q)
+        result = u""
+        for (c, partialresult) in zip(input.encode(self.encoding), partialresults):
+            q.write(c)
+            result += r.read()
+            self.assertEqual(result, partialresult)
+        # check that there's nothing left in the buffers
+        self.assertEqual(r.read(), u"")
+        self.assertEqual(r.bytebuffer, "")
+        self.assertEqual(r.charbuffer, u"")
+
+        # do the check again, this time using a incremental decoder
+        d = codecs.getincrementaldecoder(self.encoding)()
+        result = u""
+        for (c, partialresult) in zip(input.encode(self.encoding), partialresults):
+            result += d.decode(c)
+            self.assertEqual(result, partialresult)
+        # check that there's nothing left in the buffers
+        self.assertEqual(d.decode("", True), u"")
+        self.assertEqual(d.buffer, "")
+
+        # Check whether the rest method works properly
+        d.reset()
+        result = u""
+        for (c, partialresult) in zip(input.encode(self.encoding), partialresults):
+            result += d.decode(c)
+            self.assertEqual(result, partialresult)
+        # check that there's nothing left in the buffers
+        self.assertEqual(d.decode("", True), u"")
+        self.assertEqual(d.buffer, "")
+
+        # check iterdecode()
+        encoded = input.encode(self.encoding)
+        self.assertEqual(
+            input,
+            u"".join(codecs.iterdecode(encoded, self.encoding))
+        )
+
+    def test_readline(self):
+        def getreader(input):
+            stream = StringIO.StringIO(input.encode(self.encoding))
+            return codecs.getreader(self.encoding)(stream)
+
+        def readalllines(input, keepends=True, size=None):
+            reader = getreader(input)
+            lines = []
+            while True:
+                line = reader.readline(size=size, keepends=keepends)
+                if not line:
+                    break
+                lines.append(line)
+            return "|".join(lines)
+
+        s = u"foo\nbar\r\nbaz\rspam\u2028eggs"
+        sexpected = u"foo\n|bar\r\n|baz\r|spam\u2028|eggs"
+        sexpectednoends = u"foo|bar|baz|spam|eggs"
+        self.assertEqual(readalllines(s, True), sexpected)
+        self.assertEqual(readalllines(s, False), sexpectednoends)
+        self.assertEqual(readalllines(s, True, 10), sexpected)
+        self.assertEqual(readalllines(s, False, 10), sexpectednoends)
+
+        # Test long lines (multiple calls to read() in readline())
+        vw = []
+        vwo = []
+        for (i, lineend) in enumerate(u"\n \r\n \r \u2028".split()):
+            vw.append((i*200)*u"\3042" + lineend)
+            vwo.append((i*200)*u"\3042")
+        self.assertEqual(readalllines("".join(vw), True), "".join(vw))
+        self.assertEqual(readalllines("".join(vw), False),"".join(vwo))
+
+        # Test lines where the first read might end with \r, so the
+        # reader has to look ahead whether this is a lone \r or a \r\n
+        for size in xrange(80):
+            for lineend in u"\n \r\n \r \u2028".split():
+                s = 10*(size*u"a" + lineend + u"xxx\n")
+                reader = getreader(s)
+                for i in xrange(10):
+                    self.assertEqual(
+                        reader.readline(keepends=True),
+                        size*u"a" + lineend,
+                    )
+                reader = getreader(s)
+                for i in xrange(10):
+                    self.assertEqual(
+                        reader.readline(keepends=False),
+                        size*u"a",
+                    )
+
+    def test_bug1175396(self):
+        s = [
+            '<%!--===================================================\r\n',
+            '    BLOG index page: show recent articles,\r\n',
+            '    today\'s articles, or articles of a specific date.\r\n',
+            '========================================================--%>\r\n',
+            '<%@inputencoding="ISO-8859-1"%>\r\n',
+            '<%@pagetemplate=TEMPLATE.y%>\r\n',
+            '<%@import=import frog.util, frog%>\r\n',
+            '<%@import=import frog.objects%>\r\n',
+            '<%@import=from frog.storageerrors import StorageError%>\r\n',
+            '<%\r\n',
+            '\r\n',
+            'import logging\r\n',
+            'log=logging.getLogger("Snakelets.logger")\r\n',
+            '\r\n',
+            '\r\n',
+            'user=self.SessionCtx.user\r\n',
+            'storageEngine=self.SessionCtx.storageEngine\r\n',
+            '\r\n',
+            '\r\n',
+            'def readArticlesFromDate(date, count=None):\r\n',
+            '    entryids=storageEngine.listBlogEntries(date)\r\n',
+            '    entryids.reverse() # descending\r\n',
+            '    if count:\r\n',
+            '        entryids=entryids[:count]\r\n',
+            '    try:\r\n',
+            '        return [ frog.objects.BlogEntry.load(storageEngine, date, Id) for Id in entryids ]\r\n',
+            '    except StorageError,x:\r\n',
+            '        log.error("Error loading articles: "+str(x))\r\n',
+            '        self.abort("cannot load articles")\r\n',
+            '\r\n',
+            'showdate=None\r\n',
+            '\r\n',
+            'arg=self.Request.getArg()\r\n',
+            'if arg=="today":\r\n',
+            '    #-------------------- TODAY\'S ARTICLES\r\n',
+            '    self.write("<h2>Today\'s articles</h2>")\r\n',
+            '    showdate = frog.util.isodatestr() \r\n',
+            '    entries = readArticlesFromDate(showdate)\r\n',
+            'elif arg=="active":\r\n',
+            '    #-------------------- ACTIVE ARTICLES redirect\r\n',
+            '    self.Yredirect("active.y")\r\n',
+            'elif arg=="login":\r\n',
+            '    #-------------------- LOGIN PAGE redirect\r\n',
+            '    self.Yredirect("login.y")\r\n',
+            'elif arg=="date":\r\n',
+            '    #-------------------- ARTICLES OF A SPECIFIC DATE\r\n',
+            '    showdate = self.Request.getParameter("date")\r\n',
+            '    self.write("<h2>Articles written on %s</h2>"% frog.util.mediumdatestr(showdate))\r\n',
+            '    entries = readArticlesFromDate(showdate)\r\n',
+            'else:\r\n',
+            '    #-------------------- RECENT ARTICLES\r\n',
+            '    self.write("<h2>Recent articles</h2>")\r\n',
+            '    dates=storageEngine.listBlogEntryDates()\r\n',
+            '    if dates:\r\n',
+            '        entries=[]\r\n',
+            '        SHOWAMOUNT=10\r\n',
+            '        for showdate in dates:\r\n',
+            '            entries.extend( readArticlesFromDate(showdate, SHOWAMOUNT-len(entries)) )\r\n',
+            '            if len(entries)>=SHOWAMOUNT:\r\n',
+            '                break\r\n',
+            '                \r\n',
+        ]
+        stream = StringIO.StringIO("".join(s).encode(self.encoding))
+        reader = codecs.getreader(self.encoding)(stream)
+        for (i, line) in enumerate(reader):
+            self.assertEqual(line, s[i])
+
+    def test_readlinequeue(self):
+        q = Queue()
+        writer = codecs.getwriter(self.encoding)(q)
+        reader = codecs.getreader(self.encoding)(q)
+
+        # No lineends
+        writer.write(u"foo\r")
+        self.assertEqual(reader.readline(keepends=False), u"foo")
+        writer.write(u"\nbar\r")
+        self.assertEqual(reader.readline(keepends=False), u"")
+        self.assertEqual(reader.readline(keepends=False), u"bar")
+        writer.write(u"baz")
+        self.assertEqual(reader.readline(keepends=False), u"baz")
+        self.assertEqual(reader.readline(keepends=False), u"")
+
+        # Lineends
+        writer.write(u"foo\r")
+        self.assertEqual(reader.readline(keepends=True), u"foo\r")
+        writer.write(u"\nbar\r")
+        self.assertEqual(reader.readline(keepends=True), u"\n")
+        self.assertEqual(reader.readline(keepends=True), u"bar\r")
+        writer.write(u"baz")
+        self.assertEqual(reader.readline(keepends=True), u"baz")
+        self.assertEqual(reader.readline(keepends=True), u"")
+        writer.write(u"foo\r\n")
+        self.assertEqual(reader.readline(keepends=True), u"foo\r\n")
+
+    def test_bug1098990_a(self):
+        s1 = u"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy\r\n"
+        s2 = u"offending line: ladfj askldfj klasdj fskla dfzaskdj fasklfj laskd fjasklfzzzzaa%whereisthis!!!\r\n"
+        s3 = u"next line.\r\n"
+
+        s = (s1+s2+s3).encode(self.encoding)
+        stream = StringIO.StringIO(s)
+        reader = codecs.getreader(self.encoding)(stream)
+        self.assertEqual(reader.readline(), s1)
+        self.assertEqual(reader.readline(), s2)
+        self.assertEqual(reader.readline(), s3)
+        self.assertEqual(reader.readline(), u"")
+
+    def test_bug1098990_b(self):
+        s1 = u"aaaaaaaaaaaaaaaaaaaaaaaa\r\n"
+        s2 = u"bbbbbbbbbbbbbbbbbbbbbbbb\r\n"
+        s3 = u"stillokay:bbbbxx\r\n"
+        s4 = u"broken!!!!badbad\r\n"
+        s5 = u"againokay.\r\n"
+
+        s = (s1+s2+s3+s4+s5).encode(self.encoding)
+        stream = StringIO.StringIO(s)
+        reader = codecs.getreader(self.encoding)(stream)
+        self.assertEqual(reader.readline(), s1)
+        self.assertEqual(reader.readline(), s2)
+        self.assertEqual(reader.readline(), s3)
+        self.assertEqual(reader.readline(), s4)
+        self.assertEqual(reader.readline(), s5)
+        self.assertEqual(reader.readline(), u"")
+
+class UTF16Test(ReadTest):
+    encoding = "utf-16"
+
+    spamle = '\xff\xfes\x00p\x00a\x00m\x00s\x00p\x00a\x00m\x00'
+    spambe = '\xfe\xff\x00s\x00p\x00a\x00m\x00s\x00p\x00a\x00m'
+
+    def test_only_one_bom(self):
+        _,_,reader,writer = codecs.lookup(self.encoding)
+        # encode some stream
+        s = StringIO.StringIO()
+        f = writer(s)
+        f.write(u"spam")
+        f.write(u"spam")
+        d = s.getvalue()
+        # check whether there is exactly one BOM in it
+        self.assert_(d == self.spamle or d == self.spambe)
+        # try to read it back
+        s = StringIO.StringIO(d)
+        f = reader(s)
+        self.assertEquals(f.read(), u"spamspam")
+
+    def test_badbom(self):
+        s = StringIO.StringIO("\xff\xff")
+        f = codecs.getreader(self.encoding)(s)
+        self.assertRaises(UnicodeError, f.read)
+
+        s = StringIO.StringIO("\xff\xff\xff\xff")
+        f = codecs.getreader(self.encoding)(s)
+        self.assertRaises(UnicodeError, f.read)
+
+    def test_partial(self):
+        self.check_partial(
+            u"\x00\xff\u0100\uffff",
+            [
+                u"", # first byte of BOM read
+                u"", # second byte of BOM read => byteorder known
+                u"",
+                u"\x00",
+                u"\x00",
+                u"\x00\xff",
+                u"\x00\xff",
+                u"\x00\xff\u0100",
+                u"\x00\xff\u0100",
+                u"\x00\xff\u0100\uffff",
+            ]
+        )
+
+    def test_errors(self):
+        self.assertRaises(UnicodeDecodeError, codecs.utf_16_decode, "\xff", "strict", True)
+
+class UTF16LETest(ReadTest):
+    encoding = "utf-16-le"
+
+    def test_partial(self):
+        self.check_partial(
+            u"\x00\xff\u0100\uffff",
+            [
+                u"",
+                u"\x00",
+                u"\x00",
+                u"\x00\xff",
+                u"\x00\xff",
+                u"\x00\xff\u0100",
+                u"\x00\xff\u0100",
+                u"\x00\xff\u0100\uffff",
+            ]
+        )
+
+    def test_errors(self):
+        self.assertRaises(UnicodeDecodeError, codecs.utf_16_le_decode, "\xff", "strict", True)
+
+class UTF16BETest(ReadTest):
+    encoding = "utf-16-be"
+
+    def test_partial(self):
+        self.check_partial(
+            u"\x00\xff\u0100\uffff",
+            [
+                u"",
+                u"\x00",
+                u"\x00",
+                u"\x00\xff",
+                u"\x00\xff",
+                u"\x00\xff\u0100",
+                u"\x00\xff\u0100",
+                u"\x00\xff\u0100\uffff",
+            ]
+        )
+
+    def test_errors(self):
+        self.assertRaises(UnicodeDecodeError, codecs.utf_16_be_decode, "\xff", "strict", True)
+
+class UTF8Test(ReadTest):
+    encoding = "utf-8"
+
+    def test_partial(self):
+        self.check_partial(
+            u"\x00\xff\u07ff\u0800\uffff",
+            [
+                u"\x00",
+                u"\x00",
+                u"\x00\xff",
+                u"\x00\xff",
+                u"\x00\xff\u07ff",
+                u"\x00\xff\u07ff",
+                u"\x00\xff\u07ff",
+                u"\x00\xff\u07ff\u0800",
+                u"\x00\xff\u07ff\u0800",
+                u"\x00\xff\u07ff\u0800",
+                u"\x00\xff\u07ff\u0800\uffff",
+            ]
+        )
+
+class UTF7Test(ReadTest):
+    encoding = "utf-7"
+
+    # No test_partial() yet, because UTF-7 doesn't support it.
+
+class UTF16ExTest(unittest.TestCase):
+
+    def test_errors(self):
+        self.assertRaises(UnicodeDecodeError, codecs.utf_16_ex_decode, "\xff", "strict", 0, True)
+
+    def test_bad_args(self):
+        self.assertRaises(TypeError, codecs.utf_16_ex_decode)
+
+class ReadBufferTest(unittest.TestCase):
+
+    def test_array(self):
+        import array
+        self.assertEqual(
+            codecs.readbuffer_encode(array.array("c", "spam")),
+            ("spam", 4)
+        )
+
+    def test_empty(self):
+        self.assertEqual(codecs.readbuffer_encode(""), ("", 0))
+
+    def test_bad_args(self):
+        self.assertRaises(TypeError, codecs.readbuffer_encode)
+        self.assertRaises(TypeError, codecs.readbuffer_encode, 42)
+
+class CharBufferTest(unittest.TestCase):
+
+    def test_string(self):
+        self.assertEqual(codecs.charbuffer_encode("spam"), ("spam", 4))
+
+    def test_empty(self):
+        self.assertEqual(codecs.charbuffer_encode(""), ("", 0))
+
+    def test_bad_args(self):
+        self.assertRaises(TypeError, codecs.charbuffer_encode)
+        self.assertRaises(TypeError, codecs.charbuffer_encode, 42)
+
+class UTF8SigTest(ReadTest):
+    encoding = "utf-8-sig"
+
+    def test_partial(self):
+        self.check_partial(
+            u"\ufeff\x00\xff\u07ff\u0800\uffff",
+            [
+                u"",
+                u"",
+                u"", # First BOM has been read and skipped
+                u"",
+                u"",
+                u"\ufeff", # Second BOM has been read and emitted
+                u"\ufeff\x00", # "\x00" read and emitted
+                u"\ufeff\x00", # First byte of encoded u"\xff" read
+                u"\ufeff\x00\xff", # Second byte of encoded u"\xff" read
+                u"\ufeff\x00\xff", # First byte of encoded u"\u07ff" read
+                u"\ufeff\x00\xff\u07ff", # Second byte of encoded u"\u07ff" read
+                u"\ufeff\x00\xff\u07ff",
+                u"\ufeff\x00\xff\u07ff",
+                u"\ufeff\x00\xff\u07ff\u0800",
+                u"\ufeff\x00\xff\u07ff\u0800",
+                u"\ufeff\x00\xff\u07ff\u0800",
+                u"\ufeff\x00\xff\u07ff\u0800\uffff",
+            ]
+        )
+
+    def test_bug1601501(self):
+        # SF bug #1601501: check that the codec works with a buffer
+        unicode("\xef\xbb\xbf", "utf-8-sig")
+
+class EscapeDecodeTest(unittest.TestCase):
+    def test_empty(self):
+        self.assertEquals(codecs.escape_decode(""), ("", 0))
+
+class RecodingTest(unittest.TestCase):
+    def test_recoding(self):
+        f = StringIO.StringIO()
+        f2 = codecs.EncodedFile(f, "unicode_internal", "utf-8")
+        f2.write(u"a")
+        f2.close()
+        # Python used to crash on this at exit because of a refcount
+        # bug in _codecsmodule.c
+
+# From RFC 3492
+punycode_testcases = [
+    # A Arabic (Egyptian):
+    (u"\u0644\u064A\u0647\u0645\u0627\u0628\u062A\u0643\u0644"
+     u"\u0645\u0648\u0634\u0639\u0631\u0628\u064A\u061F",
+     "egbpdaj6bu4bxfgehfvwxn"),
+    # B Chinese (simplified):
+    (u"\u4ED6\u4EEC\u4E3A\u4EC0\u4E48\u4E0D\u8BF4\u4E2D\u6587",
+     "ihqwcrb4cv8a8dqg056pqjye"),
+    # C Chinese (traditional):
+    (u"\u4ED6\u5011\u7232\u4EC0\u9EBD\u4E0D\u8AAA\u4E2D\u6587",
+     "ihqwctvzc91f659drss3x8bo0yb"),
+    # D Czech: Pro<ccaron>prost<ecaron>nemluv<iacute><ccaron>esky
+    (u"\u0050\u0072\u006F\u010D\u0070\u0072\u006F\u0073\u0074"
+     u"\u011B\u006E\u0065\u006D\u006C\u0075\u0076\u00ED\u010D"
+     u"\u0065\u0073\u006B\u0079",
+     "Proprostnemluvesky-uyb24dma41a"),
+    # E Hebrew:
+    (u"\u05DC\u05DE\u05D4\u05D4\u05DD\u05E4\u05E9\u05D5\u05D8"
+     u"\u05DC\u05D0\u05DE\u05D3\u05D1\u05E8\u05D9\u05DD\u05E2"
+     u"\u05D1\u05E8\u05D9\u05EA",
+     "4dbcagdahymbxekheh6e0a7fei0b"),
+    # F Hindi (Devanagari):
+    (u"\u092F\u0939\u0932\u094B\u0917\u0939\u093F\u0928\u094D"
+    u"\u0926\u0940\u0915\u094D\u092F\u094B\u0902\u0928\u0939"
+    u"\u0940\u0902\u092C\u094B\u0932\u0938\u0915\u0924\u0947"
+    u"\u0939\u0948\u0902",
+    "i1baa7eci9glrd9b2ae1bj0hfcgg6iyaf8o0a1dig0cd"),
+
+    #(G) Japanese (kanji and hiragana):
+    (u"\u306A\u305C\u307F\u3093\u306A\u65E5\u672C\u8A9E\u3092"
+    u"\u8A71\u3057\u3066\u304F\u308C\u306A\u3044\u306E\u304B",
+     "n8jok5ay5dzabd5bym9f0cm5685rrjetr6pdxa"),
+
+    # (H) Korean (Hangul syllables):
+    (u"\uC138\uACC4\uC758\uBAA8\uB4E0\uC0AC\uB78C\uB4E4\uC774"
+     u"\uD55C\uAD6D\uC5B4\uB97C\uC774\uD574\uD55C\uB2E4\uBA74"
+     u"\uC5BC\uB9C8\uB098\uC88B\uC744\uAE4C",
+     "989aomsvi5e83db1d2a355cv1e0vak1dwrv93d5xbh15a0dt30a5j"
+     "psd879ccm6fea98c"),
+
+    # (I) Russian (Cyrillic):
+    (u"\u043F\u043E\u0447\u0435\u043C\u0443\u0436\u0435\u043E"
+     u"\u043D\u0438\u043D\u0435\u0433\u043E\u0432\u043E\u0440"
+     u"\u044F\u0442\u043F\u043E\u0440\u0443\u0441\u0441\u043A"
+     u"\u0438",
+     "b1abfaaepdrnnbgefbaDotcwatmq2g4l"),
+
+    # (J) Spanish: Porqu<eacute>nopuedensimplementehablarenEspa<ntilde>ol
+    (u"\u0050\u006F\u0072\u0071\u0075\u00E9\u006E\u006F\u0070"
+     u"\u0075\u0065\u0064\u0065\u006E\u0073\u0069\u006D\u0070"
+     u"\u006C\u0065\u006D\u0065\u006E\u0074\u0065\u0068\u0061"
+     u"\u0062\u006C\u0061\u0072\u0065\u006E\u0045\u0073\u0070"
+     u"\u0061\u00F1\u006F\u006C",
+     "PorqunopuedensimplementehablarenEspaol-fmd56a"),
+
+    # (K) Vietnamese:
+    #  T<adotbelow>isaoh<odotbelow>kh<ocirc>ngth<ecirchookabove>ch\
+    #   <ihookabove>n<oacute>iti<ecircacute>ngVi<ecircdotbelow>t
+    (u"\u0054\u1EA1\u0069\u0073\u0061\u006F\u0068\u1ECD\u006B"
+     u"\u0068\u00F4\u006E\u0067\u0074\u0068\u1EC3\u0063\u0068"
+     u"\u1EC9\u006E\u00F3\u0069\u0074\u0069\u1EBF\u006E\u0067"
+     u"\u0056\u0069\u1EC7\u0074",
+     "TisaohkhngthchnitingVit-kjcr8268qyxafd2f1b9g"),
+
+    #(L) 3<nen>B<gumi><kinpachi><sensei>
+    (u"\u0033\u5E74\u0042\u7D44\u91D1\u516B\u5148\u751F",
+     "3B-ww4c5e180e575a65lsy2b"),
+
+    # (M) <amuro><namie>-with-SUPER-MONKEYS
+    (u"\u5B89\u5BA4\u5948\u7F8E\u6075\u002D\u0077\u0069\u0074"
+     u"\u0068\u002D\u0053\u0055\u0050\u0045\u0052\u002D\u004D"
+     u"\u004F\u004E\u004B\u0045\u0059\u0053",
+     "-with-SUPER-MONKEYS-pc58ag80a8qai00g7n9n"),
+
+    # (N) Hello-Another-Way-<sorezore><no><basho>
+    (u"\u0048\u0065\u006C\u006C\u006F\u002D\u0041\u006E\u006F"
+     u"\u0074\u0068\u0065\u0072\u002D\u0057\u0061\u0079\u002D"
+     u"\u305D\u308C\u305E\u308C\u306E\u5834\u6240",
+     "Hello-Another-Way--fc4qua05auwb3674vfr0b"),
+
+    # (O) <hitotsu><yane><no><shita>2
+    (u"\u3072\u3068\u3064\u5C4B\u6839\u306E\u4E0B\u0032",
+     "2-u9tlzr9756bt3uc0v"),
+
+    # (P) Maji<de>Koi<suru>5<byou><mae>
+    (u"\u004D\u0061\u006A\u0069\u3067\u004B\u006F\u0069\u3059"
+     u"\u308B\u0035\u79D2\u524D",
+     "MajiKoi5-783gue6qz075azm5e"),
+
+     # (Q) <pafii>de<runba>
+    (u"\u30D1\u30D5\u30A3\u30FC\u0064\u0065\u30EB\u30F3\u30D0",
+     "de-jg4avhby1noc0d"),
+
+    # (R) <sono><supiido><de>
+    (u"\u305D\u306E\u30B9\u30D4\u30FC\u30C9\u3067",
+     "d9juau41awczczp"),
+
+    # (S) -> $1.00 <-
+    (u"\u002D\u003E\u0020\u0024\u0031\u002E\u0030\u0030\u0020"
+     u"\u003C\u002D",
+     "-> $1.00 <--")
+    ]
+
+for i in punycode_testcases:
+    if len(i)!=2:
+        print repr(i)
+
+class PunycodeTest(unittest.TestCase):
+    def test_encode(self):
+        for uni, puny in punycode_testcases:
+            # Need to convert both strings to lower case, since
+            # some of the extended encodings use upper case, but our
+            # code produces only lower case. Converting just puny to
+            # lower is also insufficient, since some of the input characters
+            # are upper case.
+            self.assertEquals(uni.encode("punycode").lower(), puny.lower())
+
+    def test_decode(self):
+        for uni, puny in punycode_testcases:
+            self.assertEquals(uni, puny.decode("punycode"))
+
+class UnicodeInternalTest(unittest.TestCase):
+    def test_bug1251300(self):
+        # Decoding with unicode_internal used to not correctly handle "code
+        # points" above 0x10ffff on UCS-4 builds.
+        if sys.maxunicode > 0xffff:
+            ok = [
+                ("\x00\x10\xff\xff", u"\U0010ffff"),
+                ("\x00\x00\x01\x01", u"\U00000101"),
+                ("", u""),
+            ]
+            not_ok = [
+                "\x7f\xff\xff\xff",
+                "\x80\x00\x00\x00",
+                "\x81\x00\x00\x00",
+                "\x00",
+                "\x00\x00\x00\x00\x00",
+            ]
+            for internal, uni in ok:
+                if sys.byteorder == "little":
+                    internal = "".join(reversed(internal))
+                self.assertEquals(uni, internal.decode("unicode_internal"))
+            for internal in not_ok:
+                if sys.byteorder == "little":
+                    internal = "".join(reversed(internal))
+                self.assertRaises(UnicodeDecodeError, internal.decode,
+                    "unicode_internal")
+
+    def test_decode_error_attributes(self):
+        if sys.maxunicode > 0xffff:
+            try:
+                "\x00\x00\x00\x00\x00\x11\x11\x00".decode("unicode_internal")
+            except UnicodeDecodeError, ex:
+                self.assertEquals("unicode_internal", ex.encoding)
+                self.assertEquals("\x00\x00\x00\x00\x00\x11\x11\x00", ex.object)
+                self.assertEquals(4, ex.start)
+                self.assertEquals(8, ex.end)
+            else:
+                self.fail()
+
+    def test_decode_callback(self):
+        if sys.maxunicode > 0xffff:
+            codecs.register_error("UnicodeInternalTest", codecs.ignore_errors)
+            decoder = codecs.getdecoder("unicode_internal")
+            ab = u"ab".encode("unicode_internal")
+            ignored = decoder("%s\x22\x22\x22\x22%s" % (ab[:4], ab[4:]),
+                "UnicodeInternalTest")
+            self.assertEquals((u"ab", 12), ignored)
+
+# From http://www.gnu.org/software/libidn/draft-josefsson-idn-test-vectors.html
+nameprep_tests = [
+    # 3.1 Map to nothing.
+    ('foo\xc2\xad\xcd\x8f\xe1\xa0\x86\xe1\xa0\x8bbar'
+     '\xe2\x80\x8b\xe2\x81\xa0baz\xef\xb8\x80\xef\xb8\x88\xef'
+     '\xb8\x8f\xef\xbb\xbf',
+     'foobarbaz'),
+    # 3.2 Case folding ASCII U+0043 U+0041 U+0046 U+0045.
+    ('CAFE',
+     'cafe'),
+    # 3.3 Case folding 8bit U+00DF (german sharp s).
+    # The original test case is bogus; it says \xc3\xdf
+    ('\xc3\x9f',
+     'ss'),
+    # 3.4 Case folding U+0130 (turkish capital I with dot).
+    ('\xc4\xb0',
+     'i\xcc\x87'),
+    # 3.5 Case folding multibyte U+0143 U+037A.
+    ('\xc5\x83\xcd\xba',
+     '\xc5\x84 \xce\xb9'),
+    # 3.6 Case folding U+2121 U+33C6 U+1D7BB.
+    # XXX: skip this as it fails in UCS-2 mode
+    #('\xe2\x84\xa1\xe3\x8f\x86\xf0\x9d\x9e\xbb',
+    # 'telc\xe2\x88\x95kg\xcf\x83'),
+    (None, None),
+    # 3.7 Normalization of U+006a U+030c U+00A0 U+00AA.
+    ('j\xcc\x8c\xc2\xa0\xc2\xaa',
+     '\xc7\xb0 a'),
+    # 3.8 Case folding U+1FB7 and normalization.
+    ('\xe1\xbe\xb7',
+     '\xe1\xbe\xb6\xce\xb9'),
+    # 3.9 Self-reverting case folding U+01F0 and normalization.
+    # The original test case is bogus, it says `\xc7\xf0'
+    ('\xc7\xb0',
+     '\xc7\xb0'),
+    # 3.10 Self-reverting case folding U+0390 and normalization.
+    ('\xce\x90',
+     '\xce\x90'),
+    # 3.11 Self-reverting case folding U+03B0 and normalization.
+    ('\xce\xb0',
+     '\xce\xb0'),
+    # 3.12 Self-reverting case folding U+1E96 and normalization.
+    ('\xe1\xba\x96',
+     '\xe1\xba\x96'),
+    # 3.13 Self-reverting case folding U+1F56 and normalization.
+    ('\xe1\xbd\x96',
+     '\xe1\xbd\x96'),
+    # 3.14 ASCII space character U+0020.
+    (' ',
+     ' '),
+    # 3.15 Non-ASCII 8bit space character U+00A0.
+    ('\xc2\xa0',
+     ' '),
+    # 3.16 Non-ASCII multibyte space character U+1680.
+    ('\xe1\x9a\x80',
+     None),
+    # 3.17 Non-ASCII multibyte space character U+2000.
+    ('\xe2\x80\x80',
+     ' '),
+    # 3.18 Zero Width Space U+200b.
+    ('\xe2\x80\x8b',
+     ''),
+    # 3.19 Non-ASCII multibyte space character U+3000.
+    ('\xe3\x80\x80',
+     ' '),
+    # 3.20 ASCII control characters U+0010 U+007F.
+    ('\x10\x7f',
+     '\x10\x7f'),
+    # 3.21 Non-ASCII 8bit control character U+0085.
+    ('\xc2\x85',
+     None),
+    # 3.22 Non-ASCII multibyte control character U+180E.
+    ('\xe1\xa0\x8e',
+     None),
+    # 3.23 Zero Width No-Break Space U+FEFF.
+    ('\xef\xbb\xbf',
+     ''),
+    # 3.24 Non-ASCII control character U+1D175.
+    ('\xf0\x9d\x85\xb5',
+     None),
+    # 3.25 Plane 0 private use character U+F123.
+    ('\xef\x84\xa3',
+     None),
+    # 3.26 Plane 15 private use character U+F1234.
+    ('\xf3\xb1\x88\xb4',
+     None),
+    # 3.27 Plane 16 private use character U+10F234.
+    ('\xf4\x8f\x88\xb4',
+     None),
+    # 3.28 Non-character code point U+8FFFE.
+    ('\xf2\x8f\xbf\xbe',
+     None),
+    # 3.29 Non-character code point U+10FFFF.
+    ('\xf4\x8f\xbf\xbf',
+     None),
+    # 3.30 Surrogate code U+DF42.
+    ('\xed\xbd\x82',
+     None),
+    # 3.31 Non-plain text character U+FFFD.
+    ('\xef\xbf\xbd',
+     None),
+    # 3.32 Ideographic description character U+2FF5.
+    ('\xe2\xbf\xb5',
+     None),
+    # 3.33 Display property character U+0341.
+    ('\xcd\x81',
+     '\xcc\x81'),
+    # 3.34 Left-to-right mark U+200E.
+    ('\xe2\x80\x8e',
+     None),
+    # 3.35 Deprecated U+202A.
+    ('\xe2\x80\xaa',
+     None),
+    # 3.36 Language tagging character U+E0001.
+    ('\xf3\xa0\x80\x81',
+     None),
+    # 3.37 Language tagging character U+E0042.
+    ('\xf3\xa0\x81\x82',
+     None),
+    # 3.38 Bidi: RandALCat character U+05BE and LCat characters.
+    ('foo\xd6\xbebar',
+     None),
+    # 3.39 Bidi: RandALCat character U+FD50 and LCat characters.
+    ('foo\xef\xb5\x90bar',
+     None),
+    # 3.40 Bidi: RandALCat character U+FB38 and LCat characters.
+    ('foo\xef\xb9\xb6bar',
+     'foo \xd9\x8ebar'),
+    # 3.41 Bidi: RandALCat without trailing RandALCat U+0627 U+0031.
+    ('\xd8\xa71',
+     None),
+    # 3.42 Bidi: RandALCat character U+0627 U+0031 U+0628.
+    ('\xd8\xa71\xd8\xa8',
+     '\xd8\xa71\xd8\xa8'),
+    # 3.43 Unassigned code point U+E0002.
+    # Skip this test as we allow unassigned
+    #('\xf3\xa0\x80\x82',
+    # None),
+    (None, None),
+    # 3.44 Larger test (shrinking).
+    # Original test case reads \xc3\xdf
+    ('X\xc2\xad\xc3\x9f\xc4\xb0\xe2\x84\xa1j\xcc\x8c\xc2\xa0\xc2'
+     '\xaa\xce\xb0\xe2\x80\x80',
+     'xssi\xcc\x87tel\xc7\xb0 a\xce\xb0 '),
+    # 3.45 Larger test (expanding).
+    # Original test case reads \xc3\x9f
+    ('X\xc3\x9f\xe3\x8c\x96\xc4\xb0\xe2\x84\xa1\xe2\x92\x9f\xe3\x8c'
+     '\x80',
+     'xss\xe3\x82\xad\xe3\x83\xad\xe3\x83\xa1\xe3\x83\xbc\xe3'
+     '\x83\x88\xe3\x83\xabi\xcc\x87tel\x28d\x29\xe3\x82'
+     '\xa2\xe3\x83\x91\xe3\x83\xbc\xe3\x83\x88')
+    ]
+
+
+class NameprepTest(unittest.TestCase):
+    def test_nameprep(self):
+        from encodings.idna import nameprep
+        for pos, (orig, prepped) in enumerate(nameprep_tests):
+            if orig is None:
+                # Skipped
+                continue
+            # The Unicode strings are given in UTF-8
+            orig = unicode(orig, "utf-8")
+            if prepped is None:
+                # Input contains prohibited characters
+                self.assertRaises(UnicodeError, nameprep, orig)
+            else:
+                prepped = unicode(prepped, "utf-8")
+                try:
+                    self.assertEquals(nameprep(orig), prepped)
+                except Exception,e:
+                    raise test_support.TestFailed("Test 3.%d: %s" % (pos+1, str(e)))
+
+class IDNACodecTest(unittest.TestCase):
+    def test_builtin_decode(self):
+        self.assertEquals(unicode("python.org", "idna"), u"python.org")
+        self.assertEquals(unicode("python.org.", "idna"), u"python.org.")
+        self.assertEquals(unicode("xn--pythn-mua.org", "idna"), u"pyth\xf6n.org")
+        self.assertEquals(unicode("xn--pythn-mua.org.", "idna"), u"pyth\xf6n.org.")
+
+    def test_builtin_encode(self):
+        self.assertEquals(u"python.org".encode("idna"), "python.org")
+        self.assertEquals("python.org.".encode("idna"), "python.org.")
+        self.assertEquals(u"pyth\xf6n.org".encode("idna"), "xn--pythn-mua.org")
+        self.assertEquals(u"pyth\xf6n.org.".encode("idna"), "xn--pythn-mua.org.")
+
+    def test_stream(self):
+        import StringIO
+        r = codecs.getreader("idna")(StringIO.StringIO("abc"))
+        r.read(3)
+        self.assertEquals(r.read(), u"")
+
+    def test_incremental_decode(self):
+        self.assertEquals(
+            "".join(codecs.iterdecode("python.org", "idna")),
+            u"python.org"
+        )
+        self.assertEquals(
+            "".join(codecs.iterdecode("python.org.", "idna")),
+            u"python.org."
+        )
+        self.assertEquals(
+            "".join(codecs.iterdecode("xn--pythn-mua.org.", "idna")),
+            u"pyth\xf6n.org."
+        )
+        self.assertEquals(
+            "".join(codecs.iterdecode("xn--pythn-mua.org.", "idna")),
+            u"pyth\xf6n.org."
+        )
+
+        decoder = codecs.getincrementaldecoder("idna")()
+        self.assertEquals(decoder.decode("xn--xam", ), u"")
+        self.assertEquals(decoder.decode("ple-9ta.o", ), u"\xe4xample.")
+        self.assertEquals(decoder.decode(u"rg"), u"")
+        self.assertEquals(decoder.decode(u"", True), u"org")
+
+        decoder.reset()
+        self.assertEquals(decoder.decode("xn--xam", ), u"")
+        self.assertEquals(decoder.decode("ple-9ta.o", ), u"\xe4xample.")
+        self.assertEquals(decoder.decode("rg."), u"org.")
+        self.assertEquals(decoder.decode("", True), u"")
+
+    def test_incremental_encode(self):
+        self.assertEquals(
+            "".join(codecs.iterencode(u"python.org", "idna")),
+            "python.org"
+        )
+        self.assertEquals(
+            "".join(codecs.iterencode(u"python.org.", "idna")),
+            "python.org."
+        )
+        self.assertEquals(
+            "".join(codecs.iterencode(u"pyth\xf6n.org.", "idna")),
+            "xn--pythn-mua.org."
+        )
+        self.assertEquals(
+            "".join(codecs.iterencode(u"pyth\xf6n.org.", "idna")),
+            "xn--pythn-mua.org."
+        )
+
+        encoder = codecs.getincrementalencoder("idna")()
+        self.assertEquals(encoder.encode(u"\xe4x"), "")
+        self.assertEquals(encoder.encode(u"ample.org"), "xn--xample-9ta.")
+        self.assertEquals(encoder.encode(u"", True), "org")
+
+        encoder.reset()
+        self.assertEquals(encoder.encode(u"\xe4x"), "")
+        self.assertEquals(encoder.encode(u"ample.org."), "xn--xample-9ta.org.")
+        self.assertEquals(encoder.encode(u"", True), "")
+
+class CodecsModuleTest(unittest.TestCase):
+
+    def test_decode(self):
+        self.assertEquals(codecs.decode('\xe4\xf6\xfc', 'latin-1'),
+                          u'\xe4\xf6\xfc')
+        self.assertRaises(TypeError, codecs.decode)
+        self.assertEquals(codecs.decode('abc'), u'abc')
+        self.assertRaises(UnicodeDecodeError, codecs.decode, '\xff', 'ascii')
+
+    def test_encode(self):
+        self.assertEquals(codecs.encode(u'\xe4\xf6\xfc', 'latin-1'),
+                          '\xe4\xf6\xfc')
+        self.assertRaises(TypeError, codecs.encode)
+        self.assertRaises(LookupError, codecs.encode, "foo", "__spam__")
+        self.assertEquals(codecs.encode(u'abc'), 'abc')
+        self.assertRaises(UnicodeEncodeError, codecs.encode, u'\xffff', 'ascii')
+
+    def test_register(self):
+        self.assertRaises(TypeError, codecs.register)
+        self.assertRaises(TypeError, codecs.register, 42)
+
+    def test_lookup(self):
+        self.assertRaises(TypeError, codecs.lookup)
+        self.assertRaises(LookupError, codecs.lookup, "__spam__")
+        self.assertRaises(LookupError, codecs.lookup, " ")
+
+    def test_getencoder(self):
+        self.assertRaises(TypeError, codecs.getencoder)
+        self.assertRaises(LookupError, codecs.getencoder, "__spam__")
+
+    def test_getdecoder(self):
+        self.assertRaises(TypeError, codecs.getdecoder)
+        self.assertRaises(LookupError, codecs.getdecoder, "__spam__")
+
+    def test_getreader(self):
+        self.assertRaises(TypeError, codecs.getreader)
+        self.assertRaises(LookupError, codecs.getreader, "__spam__")
+
+    def test_getwriter(self):
+        self.assertRaises(TypeError, codecs.getwriter)
+        self.assertRaises(LookupError, codecs.getwriter, "__spam__")
+
+class StreamReaderTest(unittest.TestCase):
+
+    def setUp(self):
+        self.reader = codecs.getreader('utf-8')
+        self.stream = StringIO.StringIO('\xed\x95\x9c\n\xea\xb8\x80')
+
+    def test_readlines(self):
+        f = self.reader(self.stream)
+        self.assertEquals(f.readlines(), [u'\ud55c\n', u'\uae00'])
+
+class EncodedFileTest(unittest.TestCase):
+    
+    def test_basic(self):
+        f = StringIO.StringIO('\xed\x95\x9c\n\xea\xb8\x80')
+        ef = codecs.EncodedFile(f, 'utf-16-le', 'utf-8')
+        self.assertEquals(ef.read(), '\\\xd5\n\x00\x00\xae')
+
+        f = StringIO.StringIO()
+        ef = codecs.EncodedFile(f, 'utf-8', 'latin1')
+        ef.write('\xc3\xbc')
+        self.assertEquals(f.getvalue(), '\xfc')
+
+class Str2StrTest(unittest.TestCase):
+
+    def test_read(self):
+        sin = "\x80".encode("base64_codec")
+        reader = codecs.getreader("base64_codec")(StringIO.StringIO(sin))
+        sout = reader.read()
+        self.assertEqual(sout, "\x80")
+        self.assert_(isinstance(sout, str))
+
+    def test_readline(self):
+        sin = "\x80".encode("base64_codec")
+        reader = codecs.getreader("base64_codec")(StringIO.StringIO(sin))
+        sout = reader.readline()
+        self.assertEqual(sout, "\x80")
+        self.assert_(isinstance(sout, str))
+
+all_unicode_encodings = [
+    "ascii",
+    "base64_codec",
+    "big5",
+    "big5hkscs",
+    "charmap",
+    "cp037",
+    "cp1006",
+    "cp1026",
+    "cp1140",
+    "cp1250",
+    "cp1251",
+    "cp1252",
+    "cp1253",
+    "cp1254",
+    "cp1255",
+    "cp1256",
+    "cp1257",
+    "cp1258",
+    "cp424",
+    "cp437",
+    "cp500",
+    "cp737",
+    "cp775",
+    "cp850",
+    "cp852",
+    "cp855",
+    "cp856",
+    "cp857",
+    "cp860",
+    "cp861",
+    "cp862",
+    "cp863",
+    "cp864",
+    "cp865",
+    "cp866",
+    "cp869",
+    "cp874",
+    "cp875",
+    "cp932",
+    "cp949",
+    "cp950",
+    "euc_jis_2004",
+    "euc_jisx0213",
+    "euc_jp",
+    "euc_kr",
+    "gb18030",
+    "gb2312",
+    "gbk",
+    "hex_codec",
+    "hp_roman8",
+    "hz",
+    "idna",
+    "iso2022_jp",
+    "iso2022_jp_1",
+    "iso2022_jp_2",
+    "iso2022_jp_2004",
+    "iso2022_jp_3",
+    "iso2022_jp_ext",
+    "iso2022_kr",
+    "iso8859_1",
+    "iso8859_10",
+    "iso8859_11",
+    "iso8859_13",
+    "iso8859_14",
+    "iso8859_15",
+    "iso8859_16",
+    "iso8859_2",
+    "iso8859_3",
+    "iso8859_4",
+    "iso8859_5",
+    "iso8859_6",
+    "iso8859_7",
+    "iso8859_8",
+    "iso8859_9",
+    "johab",
+    "koi8_r",
+    "koi8_u",
+    "latin_1",
+    "mac_cyrillic",
+    "mac_greek",
+    "mac_iceland",
+    "mac_latin2",
+    "mac_roman",
+    "mac_turkish",
+    "palmos",
+    "ptcp154",
+    "punycode",
+    "raw_unicode_escape",
+    "rot_13",
+    "shift_jis",
+    "shift_jis_2004",
+    "shift_jisx0213",
+    "tis_620",
+    "unicode_escape",
+    "unicode_internal",
+    "utf_16",
+    "utf_16_be",
+    "utf_16_le",
+    "utf_7",
+    "utf_8",
+]
+
+if hasattr(codecs, "mbcs_encode"):
+    all_unicode_encodings.append("mbcs")
+
+# The following encodings work only with str, not unicode
+all_string_encodings = [
+    "quopri_codec",
+    "string_escape",
+    "uu_codec",
+]
+
+# The following encoding is not tested, because it's not supposed
+# to work:
+#    "undefined"
+
+# The following encodings don't work in stateful mode
+broken_unicode_with_streams = [
+    "base64_codec",
+    "hex_codec",
+    "punycode",
+    "unicode_internal"
+]
+broken_incremental_coders = broken_unicode_with_streams[:]
+
+try:
+    import bz2
+except ImportError:
+    pass
+else:
+    all_unicode_encodings.append("bz2_codec")
+    broken_unicode_with_streams.append("bz2_codec")
+
+try:
+    import zlib
+except ImportError:
+    pass
+else:
+    all_unicode_encodings.append("zlib_codec")
+    broken_unicode_with_streams.append("zlib_codec")
+
+class BasicUnicodeTest(unittest.TestCase):
+    def test_basics(self):
+        s = u"abc123" # all codecs should be able to encode these
+        for encoding in all_unicode_encodings:
+            name = codecs.lookup(encoding).name
+            if encoding.endswith("_codec"):
+                name += "_codec"
+            elif encoding == "latin_1":
+                name = "latin_1"
+            self.assertEqual(encoding.replace("_", "-"), name.replace("_", "-"))
+            (bytes, size) = codecs.getencoder(encoding)(s)
+            if encoding != "unicode_internal":
+                self.assertEqual(size, len(s), "%r != %r (encoding=%r)" % (size, len(s), encoding))
+            (chars, size) = codecs.getdecoder(encoding)(bytes)
+            self.assertEqual(chars, s, "%r != %r (encoding=%r)" % (chars, s, encoding))
+
+            if encoding not in broken_unicode_with_streams:
+                # check stream reader/writer
+                q = Queue()
+                writer = codecs.getwriter(encoding)(q)
+                encodedresult = ""
+                for c in s:
+                    writer.write(c)
+                    encodedresult += q.read()
+                q = Queue()
+                reader = codecs.getreader(encoding)(q)
+                decodedresult = u""
+                for c in encodedresult:
+                    q.write(c)
+                    decodedresult += reader.read()
+                self.assertEqual(decodedresult, s, "%r != %r (encoding=%r)" % (decodedresult, s, encoding))
+
+            if encoding not in broken_incremental_coders:
+                # check incremental decoder/encoder (fetched via the Python
+                # and C API) and iterencode()/iterdecode()
+                try:
+                    encoder = codecs.getincrementalencoder(encoding)()
+                    cencoder = _testcapi.codec_incrementalencoder(encoding)
+                except LookupError: # no IncrementalEncoder
+                    pass
+                else:
+                    # check incremental decoder/encoder
+                    encodedresult = ""
+                    for c in s:
+                        encodedresult += encoder.encode(c)
+                    encodedresult += encoder.encode(u"", True)
+                    decoder = codecs.getincrementaldecoder(encoding)()
+                    decodedresult = u""
+                    for c in encodedresult:
+                        decodedresult += decoder.decode(c)
+                    decodedresult += decoder.decode("", True)
+                    self.assertEqual(decodedresult, s, "%r != %r (encoding=%r)" % (decodedresult, s, encoding))
+
+                    # check C API
+                    encodedresult = ""
+                    for c in s:
+                        encodedresult += cencoder.encode(c)
+                    encodedresult += cencoder.encode(u"", True)
+                    cdecoder = _testcapi.codec_incrementaldecoder(encoding)
+                    decodedresult = u""
+                    for c in encodedresult:
+                        decodedresult += cdecoder.decode(c)
+                    decodedresult += cdecoder.decode("", True)
+                    self.assertEqual(decodedresult, s, "%r != %r (encoding=%r)" % (decodedresult, s, encoding))
+
+                    # check iterencode()/iterdecode()
+                    result = u"".join(codecs.iterdecode(codecs.iterencode(s, encoding), encoding))
+                    self.assertEqual(result, s, "%r != %r (encoding=%r)" % (result, s, encoding))
+
+                    # check iterencode()/iterdecode() with empty string
+                    result = u"".join(codecs.iterdecode(codecs.iterencode(u"", encoding), encoding))
+                    self.assertEqual(result, u"")
+
+    def test_seek(self):
+        # all codecs should be able to encode these
+        s = u"%s\n%s\n" % (100*u"abc123", 100*u"def456")
+        for encoding in all_unicode_encodings:
+            if encoding == "idna": # FIXME: See SF bug #1163178
+                continue
+            if encoding in broken_unicode_with_streams:
+                continue
+            reader = codecs.getreader(encoding)(StringIO.StringIO(s.encode(encoding)))
+            for t in xrange(5):
+                # Test that calling seek resets the internal codec state and buffers
+                reader.seek(0, 0)
+                line = reader.readline()
+                self.assertEqual(s[:len(line)], line)
+
+    def test_bad_decode_args(self):
+        for encoding in all_unicode_encodings:
+            decoder = codecs.getdecoder(encoding)
+            self.assertRaises(TypeError, decoder)
+            if encoding not in ("idna", "punycode"):
+                self.assertRaises(TypeError, decoder, 42)
+
+    def test_bad_encode_args(self):
+        for encoding in all_unicode_encodings:
+            encoder = codecs.getencoder(encoding)
+            self.assertRaises(TypeError, encoder)
+
+    def test_encoding_map_type_initialized(self):
+        from encodings import cp1140
+        # This used to crash, we are only verifying there's no crash.
+        table_type = type(cp1140.encoding_table)
+        self.assertEqual(table_type, table_type)
+
+class BasicStrTest(unittest.TestCase):
+    def test_basics(self):
+        s = "abc123"
+        for encoding in all_string_encodings:
+            (bytes, size) = codecs.getencoder(encoding)(s)
+            self.assertEqual(size, len(s))
+            (chars, size) = codecs.getdecoder(encoding)(bytes)
+            self.assertEqual(chars, s, "%r != %r (encoding=%r)" % (chars, s, encoding))
+
+class CharmapTest(unittest.TestCase):
+    def test_decode_with_string_map(self):
+        self.assertEquals(
+            codecs.charmap_decode("\x00\x01\x02", "strict", u"abc"),
+            (u"abc", 3)
+        )
+
+        self.assertEquals(
+            codecs.charmap_decode("\x00\x01\x02", "replace", u"ab"),
+            (u"ab\ufffd", 3)
+        )
+
+        self.assertEquals(
+            codecs.charmap_decode("\x00\x01\x02", "replace", u"ab\ufffe"),
+            (u"ab\ufffd", 3)
+        )
+
+        self.assertEquals(
+            codecs.charmap_decode("\x00\x01\x02", "ignore", u"ab"),
+            (u"ab", 3)
+        )
+
+        self.assertEquals(
+            codecs.charmap_decode("\x00\x01\x02", "ignore", u"ab\ufffe"),
+            (u"ab", 3)
+        )
+
+        allbytes = "".join(chr(i) for i in xrange(256))
+        self.assertEquals(
+            codecs.charmap_decode(allbytes, "ignore", u""),
+            (u"", len(allbytes))
+        )
+
+class WithStmtTest(unittest.TestCase):
+    def test_encodedfile(self):
+        f = StringIO.StringIO("\xc3\xbc")
+        with codecs.EncodedFile(f, "latin-1", "utf-8") as ef:
+            self.assertEquals(ef.read(), "\xfc")
+
+    def test_streamreaderwriter(self):
+        f = StringIO.StringIO("\xc3\xbc")
+        info = codecs.lookup("utf-8")
+        with codecs.StreamReaderWriter(f, info.streamreader,
+                                       info.streamwriter, 'strict') as srw:
+            self.assertEquals(srw.read(), u"\xfc")
+
+
+def test_main():
+    test_support.run_unittest(
+        UTF16Test,
+        UTF16LETest,
+        UTF16BETest,
+        UTF8Test,
+        UTF8SigTest,
+        UTF7Test,
+        UTF16ExTest,
+        ReadBufferTest,
+        CharBufferTest,
+        EscapeDecodeTest,
+        RecodingTest,
+        PunycodeTest,
+        UnicodeInternalTest,
+        NameprepTest,
+        IDNACodecTest,
+        CodecsModuleTest,
+        StreamReaderTest,
+        EncodedFileTest,
+        Str2StrTest,
+        BasicUnicodeTest,
+        BasicStrTest,
+        CharmapTest,
+        WithStmtTest,
+    )
+
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_codeop.py
===================================================================
--- vendor/Python/current/Lib/test/test_codeop.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_codeop.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,192 @@
+"""
+   Test cases for codeop.py
+   Nick Mathewson
+"""
+import unittest
+from test.test_support import run_unittest, is_jython
+
+from codeop import compile_command, PyCF_DONT_IMPLY_DEDENT
+
+if is_jython:
+    import sys
+    import cStringIO
+
+    def unify_callables(d):
+        for n,v in d.items():
+            if callable(v):
+                d[n] = callable
+        return d
+
+class CodeopTests(unittest.TestCase):
+
+    def assertValid(self, str, symbol='single'):
+        '''succeed iff str is a valid piece of code'''
+        if is_jython:
+            code = compile_command(str, "<input>", symbol)
+            self.assert_(code)
+            if symbol == "single":
+                d,r = {},{}
+                saved_stdout = sys.stdout
+                sys.stdout = cStringIO.StringIO()
+                try:
+                    exec code in d
+                    exec compile(str,"<input>","single") in r
+                finally:
+                    sys.stdout = saved_stdout
+            elif symbol == 'eval':
+                ctx = {'a': 2}
+                d = { 'value': eval(code,ctx) }
+                r = { 'value': eval(str,ctx) }
+            self.assertEquals(unify_callables(r),unify_callables(d))
+        else:
+            expected = compile(str, "<input>", symbol, PyCF_DONT_IMPLY_DEDENT)
+            self.assertEquals( compile_command(str, "<input>", symbol), expected)
+
+    def assertIncomplete(self, str, symbol='single'):
+        '''succeed iff str is the start of a valid piece of code'''
+        self.assertEquals( compile_command(str, symbol=symbol), None)
+
+    def assertInvalid(self, str, symbol='single', is_syntax=1):
+        '''succeed iff str is the start of an invalid piece of code'''
+        try:
+            compile_command(str,symbol=symbol)
+            self.fail("No exception thrown for invalid code")
+        except SyntaxError:
+            self.assert_(is_syntax)
+        except OverflowError:
+            self.assert_(not is_syntax)
+
+    def test_valid(self):
+        av = self.assertValid
+
+        # special case
+        if not is_jython:
+            self.assertEquals(compile_command(""),
+                            compile("pass", "<input>", 'single',
+                                    PyCF_DONT_IMPLY_DEDENT))
+            self.assertEquals(compile_command("\n"),
+                            compile("pass", "<input>", 'single',
+                                    PyCF_DONT_IMPLY_DEDENT))
+        else:
+            av("")
+            av("\n")
+
+        av("a = 1")
+        av("\na = 1")
+        av("a = 1\n")
+        av("a = 1\n\n")
+        av("\n\na = 1\n\n")
+
+        av("def x():\n  pass\n")
+        av("if 1:\n pass\n")
+
+        av("\n\nif 1: pass\n")
+        av("\n\nif 1: pass\n\n")
+
+        av("def x():\n\n pass\n")
+        av("def x():\n  pass\n  \n")
+        av("def x():\n  pass\n \n")
+
+        av("pass\n")
+        av("3**3\n")
+
+        av("if 9==3:\n   pass\nelse:\n   pass\n")
+        av("if 1:\n pass\n if 1:\n  pass\n else:\n  pass\n")
+
+        av("#a\n#b\na = 3\n")
+        av("#a\n\n   \na=3\n")
+        av("a=3\n\n")
+        av("a = 9+ \\\n3")
+
+        av("3**3","eval")
+        av("(lambda z: \n z**3)","eval")
+
+        av("9+ \\\n3","eval")
+        av("9+ \\\n3\n","eval")
+
+        av("\n\na**3","eval")
+        av("\n \na**3","eval")
+        av("#a\n#b\na**3","eval")
+
+    def test_incomplete(self):
+        ai = self.assertIncomplete
+
+        ai("(a **")
+        ai("(a,b,")
+        ai("(a,b,(")
+        ai("(a,b,(")
+        ai("a = (")
+        ai("a = {")
+        ai("b + {")
+
+        ai("if 9==3:\n   pass\nelse:")
+        ai("if 9==3:\n   pass\nelse:\n")
+        ai("if 9==3:\n   pass\nelse:\n   pass")
+        ai("if 1:")
+        ai("if 1:\n")
+        ai("if 1:\n pass\n if 1:\n  pass\n else:")
+        ai("if 1:\n pass\n if 1:\n  pass\n else:\n")
+        ai("if 1:\n pass\n if 1:\n  pass\n else:\n  pass")
+
+        ai("def x():")
+        ai("def x():\n")
+        ai("def x():\n\n")
+
+        ai("def x():\n  pass")
+        ai("def x():\n  pass\n ")
+        ai("def x():\n  pass\n  ")
+        ai("\n\ndef x():\n  pass")
+
+        ai("a = 9+ \\")
+        ai("a = 'a\\")
+        ai("a = '''xy")
+
+        ai("","eval")
+        ai("\n","eval")
+        ai("(","eval")
+        ai("(\n\n\n","eval")
+        ai("(9+","eval")
+        ai("9+ \\","eval")
+        ai("lambda z: \\","eval")
+
+    def test_invalid(self):
+        ai = self.assertInvalid
+        ai("a b")
+
+        ai("a @")
+        ai("a b @")
+        ai("a ** @")
+
+        ai("a = ")
+        ai("a = 9 +")
+
+        ai("def x():\n\npass\n")
+
+        ai("\n\n if 1: pass\n\npass")
+
+        ai("a = 9+ \\\n")
+        ai("a = 'a\\ ")
+        ai("a = 'a\\\n")
+
+        ai("a = 1","eval")
+        ai("a = (","eval")
+        ai("]","eval")
+        ai("())","eval")
+        ai("[}","eval")
+        ai("9+","eval")
+        ai("lambda z:","eval")
+        ai("a b","eval")
+
+    def test_filename(self):
+        self.assertEquals(compile_command("a = 1\n", "abc").co_filename,
+                          compile("a = 1\n", "abc", 'single').co_filename)
+        self.assertNotEquals(compile_command("a = 1\n", "abc").co_filename,
+                             compile("a = 1\n", "def", 'single').co_filename)
+
+
+def test_main():
+    run_unittest(CodeopTests)
+
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_coding.py
===================================================================
--- vendor/Python/current/Lib/test/test_coding.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_coding.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,28 @@
+
+import test.test_support, unittest
+import os
+
+class CodingTest(unittest.TestCase):
+    def test_bad_coding(self):
+        module_name = 'bad_coding'
+        self.verify_bad_module(module_name)
+
+    def test_bad_coding2(self):
+        module_name = 'bad_coding2'
+        self.verify_bad_module(module_name)
+
+    def verify_bad_module(self, module_name):
+        self.assertRaises(SyntaxError, __import__, 'test.' + module_name)
+
+        path = os.path.dirname(__file__)
+        filename = os.path.join(path, module_name + '.py')
+        fp = open(filename)
+        text = fp.read()
+        fp.close()
+        self.assertRaises(SyntaxError, compile, text, filename, 'exec')
+
+def test_main():
+    test.test_support.run_unittest(CodingTest)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_coercion.py
===================================================================
--- vendor/Python/current/Lib/test/test_coercion.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_coercion.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,347 @@
+import copy
+import sys
+import warnings
+import unittest
+from test.test_support import run_unittest, TestFailed
+
+# Fake a number that implements numeric methods through __coerce__
+class CoerceNumber:
+    def __init__(self, arg):
+        self.arg = arg
+
+    def __repr__(self):
+        return '<CoerceNumber %s>' % repr(self.arg)
+
+    def __coerce__(self, other):
+        if isinstance(other, CoerceNumber):
+            return self.arg, other.arg
+        else:
+            return (self.arg, other)
+
+# New-style class version of CoerceNumber
+class CoerceTo(object):
+    def __init__(self, arg):
+        self.arg = arg
+    def __coerce__(self, other):
+        if isinstance(other, CoerceTo):
+            return self.arg, other.arg
+        else:
+            return self.arg, other
+
+
+# Fake a number that implements numeric ops through methods.
+class MethodNumber:
+    def __init__(self,arg):
+        self.arg = arg
+
+    def __repr__(self):
+        return '<MethodNumber %s>' % repr(self.arg)
+
+    def __add__(self,other):
+        return self.arg + other
+
+    def __radd__(self,other):
+        return other + self.arg
+
+    def __sub__(self,other):
+        return self.arg - other
+
+    def __rsub__(self,other):
+        return other - self.arg
+
+    def __mul__(self,other):
+        return self.arg * other
+
+    def __rmul__(self,other):
+        return other * self.arg
+
+    def __div__(self,other):
+        return self.arg / other
+
+    def __rdiv__(self,other):
+        return other / self.arg
+
+    def __truediv__(self,other):
+        return self.arg / other
+
+    def __rtruediv__(self,other):
+        return other / self.arg
+
+    def __floordiv__(self,other):
+        return self.arg // other
+
+    def __rfloordiv__(self,other):
+        return other // self.arg
+
+    def __pow__(self,other):
+        return self.arg ** other
+
+    def __rpow__(self,other):
+        return other ** self.arg
+
+    def __mod__(self,other):
+        return self.arg % other
+
+    def __rmod__(self,other):
+        return other % self.arg
+
+    def __cmp__(self, other):
+        return cmp(self.arg, other)
+
+
+candidates = [2, 2L, 4.0, 2+0j, [1], (2,), None,
+              MethodNumber(2), CoerceNumber(2)]
+
+infix_binops = [ '+', '-', '*', '**', '%', '//', '/' ]
+
+TE = TypeError
+# b = both normal and augmented give same result list
+# s = single result lists for normal and augmented
+# e = equals other results
+# result lists: ['+', '-', '*', '**', '%', '//', ('classic /', 'new /')]
+#                                                ^^^^^^^^^^^^^^^^^^^^^^
+#                                               2-tuple if results differ
+#                                                 else only one value
+infix_results = {
+    # 2
+    (0,0): ('b', [4, 0, 4, 4, 0, 1, (1, 1.0)]),
+    (0,1): ('e', (0,0)),
+    (0,2): ('b', [6.0, -2.0, 8.0, 16.0, 2.0, 0.0, 0.5]),
+    (0,3): ('b', [4+0j, 0+0j, 4+0j, 4+0j, 0+0j, 1+0j, 1+0j]),
+    (0,4): ('b', [TE, TE, [1, 1], TE, TE, TE, TE]),
+    (0,5): ('b', [TE, TE, (2, 2), TE, TE, TE, TE]),
+    (0,6): ('b', [TE, TE, TE, TE, TE, TE, TE]),
+    (0,7): ('e', (0,0)),
+    (0,8): ('e', (0,0)),
+
+    # 2L
+    (1,0): ('e', (0,0)),
+    (1,1): ('e', (0,1)),
+    (1,2): ('e', (0,2)),
+    (1,3): ('e', (0,3)),
+    (1,4): ('e', (0,4)),
+    (1,5): ('e', (0,5)),
+    (1,6): ('e', (0,6)),
+    (1,7): ('e', (0,7)),
+    (1,8): ('e', (0,8)),
+
+    # 4.0
+    (2,0): ('b', [6.0, 2.0, 8.0, 16.0, 0.0, 2.0, 2.0]),
+    (2,1): ('e', (2,0)),
+    (2,2): ('b', [8.0, 0.0, 16.0, 256.0, 0.0, 1.0, 1.0]),
+    (2,3): ('b', [6+0j, 2+0j, 8+0j, 16+0j, 0+0j, 2+0j, 2+0j]),
+    (2,4): ('b', [TE, TE, TE, TE, TE, TE, TE]),
+    (2,5): ('e', (2,4)),
+    (2,6): ('e', (2,4)),
+    (2,7): ('e', (2,0)),
+    (2,8): ('e', (2,0)),
+
+    # (2+0j)
+    (3,0): ('b', [4+0j, 0+0j, 4+0j, 4+0j, 0+0j, 1+0j, 1+0j]),
+    (3,1): ('e', (3,0)),
+    (3,2): ('b', [6+0j, -2+0j, 8+0j, 16+0j, 2+0j, 0+0j, 0.5+0j]),
+    (3,3): ('b', [4+0j, 0+0j, 4+0j, 4+0j, 0+0j, 1+0j, 1+0j]),
+    (3,4): ('b', [TE, TE, TE, TE, TE, TE, TE]),
+    (3,5): ('e', (3,4)),
+    (3,6): ('e', (3,4)),
+    (3,7): ('e', (3,0)),
+    (3,8): ('e', (3,0)),
+
+    # [1]
+    (4,0): ('b', [TE, TE, [1, 1], TE, TE, TE, TE]),
+    (4,1): ('e', (4,0)),
+    (4,2): ('b', [TE, TE, TE, TE, TE, TE, TE]),
+    (4,3): ('b', [TE, TE, TE, TE, TE, TE, TE]),
+    (4,4): ('b', [[1, 1], TE, TE, TE, TE, TE, TE]),
+    (4,5): ('s', [TE, TE, TE, TE, TE, TE, TE], [[1, 2], TE, TE, TE, TE, TE, TE]),
+    (4,6): ('b', [TE, TE, TE, TE, TE, TE, TE]),
+    (4,7): ('e', (4,0)),
+    (4,8): ('e', (4,0)),
+
+    # (2,)
+    (5,0): ('b', [TE, TE, (2, 2), TE, TE, TE, TE]),
+    (5,1): ('e', (5,0)),
+    (5,2): ('b', [TE, TE, TE, TE, TE, TE, TE]),
+    (5,3): ('e', (5,2)),
+    (5,4): ('e', (5,2)),
+    (5,5): ('b', [(2, 2), TE, TE, TE, TE, TE, TE]),
+    (5,6): ('b', [TE, TE, TE, TE, TE, TE, TE]),
+    (5,7): ('e', (5,0)),
+    (5,8): ('e', (5,0)),
+
+    # None
+    (6,0): ('b', [TE, TE, TE, TE, TE, TE, TE]),
+    (6,1): ('e', (6,0)),
+    (6,2): ('e', (6,0)),
+    (6,3): ('e', (6,0)),
+    (6,4): ('e', (6,0)),
+    (6,5): ('e', (6,0)),
+    (6,6): ('e', (6,0)),
+    (6,7): ('e', (6,0)),
+    (6,8): ('e', (6,0)),
+
+    # MethodNumber(2)
+    (7,0): ('e', (0,0)),
+    (7,1): ('e', (0,1)),
+    (7,2): ('e', (0,2)),
+    (7,3): ('e', (0,3)),
+    (7,4): ('e', (0,4)),
+    (7,5): ('e', (0,5)),
+    (7,6): ('e', (0,6)),
+    (7,7): ('e', (0,7)),
+    (7,8): ('e', (0,8)),
+
+    # CoerceNumber(2)
+    (8,0): ('e', (0,0)),
+    (8,1): ('e', (0,1)),
+    (8,2): ('e', (0,2)),
+    (8,3): ('e', (0,3)),
+    (8,4): ('e', (0,4)),
+    (8,5): ('e', (0,5)),
+    (8,6): ('e', (0,6)),
+    (8,7): ('e', (0,7)),
+    (8,8): ('e', (0,8)),
+}
+
+def process_infix_results():
+    for key in sorted(infix_results):
+        val = infix_results[key]
+        if val[0] == 'e':
+            infix_results[key] = infix_results[val[1]]
+        else:
+            if val[0] == 's':
+                res = (val[1], val[2])
+            elif val[0] == 'b':
+                res = (val[1], val[1])
+            for i in range(1):
+                if isinstance(res[i][6], tuple):
+                    if 1/2 == 0:
+                        # testing with classic (floor) division
+                        res[i][6] = res[i][6][0]
+                    else:
+                        # testing with -Qnew
+                        res[i][6] = res[i][6][1]
+            infix_results[key] = res
+
+
+
+process_infix_results()
+# now infix_results has two lists of results for every pairing.
+
+prefix_binops = [ 'divmod' ]
+prefix_results = [
+    [(1,0), (1L,0L), (0.0,2.0), ((1+0j),0j), TE, TE, TE, TE, (1,0)],
+    [(1L,0L), (1L,0L), (0.0,2.0), ((1+0j),0j), TE, TE, TE, TE, (1L,0L)],
+    [(2.0,0.0), (2.0,0.0), (1.0,0.0), ((2+0j),0j), TE, TE, TE, TE, (2.0,0.0)],
+    [((1+0j),0j), ((1+0j),0j), (0j,(2+0j)), ((1+0j),0j), TE, TE, TE, TE, ((1+0j),0j)],
+    [TE, TE, TE, TE, TE, TE, TE, TE, TE],
+    [TE, TE, TE, TE, TE, TE, TE, TE, TE],
+    [TE, TE, TE, TE, TE, TE, TE, TE, TE],
+    [TE, TE, TE, TE, TE, TE, TE, TE, TE],
+    [(1,0), (1L,0L), (0.0,2.0), ((1+0j),0j), TE, TE, TE, TE, (1,0)]
+]
+
+def format_float(value):
+    if abs(value) < 0.01:
+        return '0.0'
+    else:
+        return '%.1f' % value
+
+# avoid testing platform fp quirks
+def format_result(value):
+    if isinstance(value, complex):
+        return '(%s + %sj)' % (format_float(value.real),
+                               format_float(value.imag))
+    elif isinstance(value, float):
+        return format_float(value)
+    return str(value)
+
+class CoercionTest(unittest.TestCase):
+    def test_infix_binops(self):
+        for ia, a in enumerate(candidates):
+            for ib, b in enumerate(candidates):
+                results = infix_results[(ia, ib)]
+                for op, res, ires in zip(infix_binops, results[0], results[1]):
+                    if res is TE:
+                        self.assertRaises(TypeError, eval,
+                                          'a %s b' % op, {'a': a, 'b': b})
+                    else:
+                        self.assertEquals(format_result(res),
+                                          format_result(eval('a %s b' % op)),
+                                          '%s %s %s == %s failed' % (a, op, b, res))
+                    try:
+                        z = copy.copy(a)
+                    except copy.Error:
+                        z = a # assume it has no inplace ops
+                    if ires is TE:
+                        try:
+                            exec 'z %s= b' % op
+                        except TypeError:
+                            pass
+                        else:
+                            self.fail("TypeError not raised")
+                    else:
+                        exec('z %s= b' % op)
+                        self.assertEquals(ires, z)
+
+    def test_prefix_binops(self):
+        for ia, a in enumerate(candidates):
+            for ib, b in enumerate(candidates):
+                for op in prefix_binops:
+                    res = prefix_results[ia][ib]
+                    if res is TE:
+                        self.assertRaises(TypeError, eval,
+                                          '%s(a, b)' % op, {'a': a, 'b': b})
+                    else:
+                        self.assertEquals(format_result(res),
+                                          format_result(eval('%s(a, b)' % op)),
+                                          '%s(%s, %s) == %s failed' % (op, a, b, res))
+
+    def test_cmptypes(self):
+        # Built-in tp_compare slots expect their arguments to have the
+        # same type, but a user-defined __coerce__ doesn't have to obey.
+        # SF #980352
+        evil_coercer = CoerceTo(42)
+        # Make sure these don't crash any more
+        self.assertNotEquals(cmp(u'fish', evil_coercer), 0)
+        self.assertNotEquals(cmp(slice(1), evil_coercer), 0)
+        # ...but that this still works
+        class WackyComparer(object):
+            def __cmp__(slf, other):
+                self.assert_(other == 42, 'expected evil_coercer, got %r' % other)
+                return 0
+        self.assertEquals(cmp(WackyComparer(), evil_coercer), 0)
+        # ...and classic classes too, since that code path is a little different
+        class ClassicWackyComparer:
+            def __cmp__(slf, other):
+                self.assert_(other == 42, 'expected evil_coercer, got %r' % other)
+                return 0
+        self.assertEquals(cmp(ClassicWackyComparer(), evil_coercer), 0)
+
+    def test_infinite_rec_classic_classes(self):
+        # if __coerce__() returns its arguments reversed it causes an infinite
+        # recursion for classic classes.
+        class Tester:
+            def __coerce__(self, other):
+                return other, self
+
+        exc = TestFailed("__coerce__() returning its arguments reverse "
+                                "should raise RuntimeError")
+        try:
+            Tester() + 1
+        except (RuntimeError, TypeError):
+            return
+        except:
+            raise exc
+        else:
+            raise exc
+
+def test_main():
+    warnings.filterwarnings("ignore",
+                            r'complex divmod\(\), // and % are deprecated',
+                            DeprecationWarning,
+                            r'test.test_coercion$')
+    run_unittest(CoercionTest)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_colorsys.py
===================================================================
--- vendor/Python/current/Lib/test/test_colorsys.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_colorsys.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,76 @@
+import unittest, test.test_support
+import colorsys
+
+def frange(start, stop, step):
+    while start <= stop:
+        yield start
+        start += step
+
+class ColorsysTest(unittest.TestCase):
+
+    def assertTripleEqual(self, tr1, tr2):
+        self.assertEqual(len(tr1), 3)
+        self.assertEqual(len(tr2), 3)
+        self.assertAlmostEqual(tr1[0], tr2[0])
+        self.assertAlmostEqual(tr1[1], tr2[1])
+        self.assertAlmostEqual(tr1[2], tr2[2])
+
+    def test_hsv_roundtrip(self):
+        for r in frange(0.0, 1.0, 0.2):
+            for g in frange(0.0, 1.0, 0.2):
+                for b in frange(0.0, 1.0, 0.2):
+                    rgb = (r, g, b)
+                    self.assertTripleEqual(
+                        rgb,
+                        colorsys.hsv_to_rgb(*colorsys.rgb_to_hsv(*rgb))
+                    )
+
+    def test_hsv_values(self):
+        values = [
+            # rgb, hsv
+            ((0.0, 0.0, 0.0), (  0  , 0.0, 0.0)), # black
+            ((0.0, 0.0, 1.0), (4./6., 1.0, 1.0)), # blue
+            ((0.0, 1.0, 0.0), (2./6., 1.0, 1.0)), # green
+            ((0.0, 1.0, 1.0), (3./6., 1.0, 1.0)), # cyan
+            ((1.0, 0.0, 0.0), (  0  , 1.0, 1.0)), # red
+            ((1.0, 0.0, 1.0), (5./6., 1.0, 1.0)), # purple
+            ((1.0, 1.0, 0.0), (1./6., 1.0, 1.0)), # yellow
+            ((1.0, 1.0, 1.0), (  0  , 0.0, 1.0)), # white
+            ((0.5, 0.5, 0.5), (  0  , 0.0, 0.5)), # grey
+        ]
+        for (rgb, hsv) in values:
+            self.assertTripleEqual(hsv, colorsys.rgb_to_hsv(*rgb))
+            self.assertTripleEqual(rgb, colorsys.hsv_to_rgb(*hsv))
+
+    def test_hls_roundtrip(self):
+        for r in frange(0.0, 1.0, 0.2):
+            for g in frange(0.0, 1.0, 0.2):
+                for b in frange(0.0, 1.0, 0.2):
+                    rgb = (r, g, b)
+                    self.assertTripleEqual(
+                        rgb,
+                        colorsys.hls_to_rgb(*colorsys.rgb_to_hls(*rgb))
+                    )
+
+    def test_hls_values(self):
+        values = [
+            # rgb, hls
+            ((0.0, 0.0, 0.0), (  0  , 0.0, 0.0)), # black
+            ((0.0, 0.0, 1.0), (4./6., 0.5, 1.0)), # blue
+            ((0.0, 1.0, 0.0), (2./6., 0.5, 1.0)), # green
+            ((0.0, 1.0, 1.0), (3./6., 0.5, 1.0)), # cyan
+            ((1.0, 0.0, 0.0), (  0  , 0.5, 1.0)), # red
+            ((1.0, 0.0, 1.0), (5./6., 0.5, 1.0)), # purple
+            ((1.0, 1.0, 0.0), (1./6., 0.5, 1.0)), # yellow
+            ((1.0, 1.0, 1.0), (  0  , 1.0, 0.0)), # white
+            ((0.5, 0.5, 0.5), (  0  , 0.5, 0.0)), # grey
+        ]
+        for (rgb, hls) in values:
+            self.assertTripleEqual(hls, colorsys.rgb_to_hls(*rgb))
+            self.assertTripleEqual(rgb, colorsys.hls_to_rgb(*hls))
+
+def test_main():
+    test.test_support.run_unittest(ColorsysTest)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_commands.py
===================================================================
--- vendor/Python/current/Lib/test/test_commands.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_commands.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,65 @@
+'''
+   Tests for commands module
+   Nick Mathewson
+'''
+import unittest
+import os, tempfile, re
+
+from test.test_support import TestSkipped, run_unittest, reap_children
+from commands import *
+
+# The module says:
+#   "NB This only works (and is only relevant) for UNIX."
+#
+# Actually, getoutput should work on any platform with an os.popen, but
+# I'll take the comment as given, and skip this suite.
+
+if os.name != 'posix':
+    raise TestSkipped('Not posix; skipping test_commands')
+
+
+class CommandTests(unittest.TestCase):
+
+    def test_getoutput(self):
+        self.assertEquals(getoutput('echo xyzzy'), 'xyzzy')
+        self.assertEquals(getstatusoutput('echo xyzzy'), (0, 'xyzzy'))
+
+        # we use mkdtemp in the next line to create an empty directory
+        # under our exclusive control; from that, we can invent a pathname
+        # that we _know_ won't exist.  This is guaranteed to fail.
+        dir = None
+        try:
+            dir = tempfile.mkdtemp()
+            name = os.path.join(dir, "foo")
+
+            status, output = getstatusoutput('cat ' + name)
+            self.assertNotEquals(status, 0)
+        finally:
+            if dir is not None:
+                os.rmdir(dir)
+
+    def test_getstatus(self):
+        # This pattern should match 'ls -ld /.' on any posix
+        # system, however perversely configured.  Even on systems
+        # (e.g., Cygwin) where user and group names can have spaces:
+        #     drwxr-xr-x   15 Administ Domain U     4096 Aug 12 12:50 /
+        #     drwxr-xr-x   15 Joe User My Group     4096 Aug 12 12:50 /
+        # Note that the first case above has a space in the group name
+        # while the second one has a space in both names.
+        pat = r'''d.........   # It is a directory.
+                  \+?          # It may have ACLs.
+                  \s+\d+       # It has some number of links.
+                  [^/]*        # Skip user, group, size, and date.
+                  /\.          # and end with the name of the file.
+               '''
+
+        self.assert_(re.match(pat, getstatus("/."), re.VERBOSE))
+
+
+def test_main():
+    run_unittest(CommandTests)
+    reap_children()
+
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_compare.py
===================================================================
--- vendor/Python/current/Lib/test/test_compare.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_compare.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,59 @@
+import sys
+import unittest
+from test import test_support
+
+class Empty:
+    def __repr__(self):
+        return '<Empty>'
+
+class Coerce:
+    def __init__(self, arg):
+        self.arg = arg
+
+    def __repr__(self):
+        return '<Coerce %s>' % self.arg
+
+    def __coerce__(self, other):
+        if isinstance(other, Coerce):
+            return self.arg, other.arg
+        else:
+            return self.arg, other
+
+class Cmp:
+    def __init__(self,arg):
+        self.arg = arg
+
+    def __repr__(self):
+        return '<Cmp %s>' % self.arg
+
+    def __cmp__(self, other):
+        return cmp(self.arg, other)
+
+class ComparisonTest(unittest.TestCase):
+    set1 = [2, 2.0, 2L, 2+0j, Coerce(2), Cmp(2.0)]
+    set2 = [[1], (3,), None, Empty()]
+    candidates = set1 + set2
+
+    def test_comparisons(self):
+        for a in self.candidates:
+            for b in self.candidates:
+                if ((a in self.set1) and (b in self.set1)) or a is b:
+                    self.assertEqual(a, b)
+                else:
+                    self.assertNotEqual(a, b)
+
+    def test_id_comparisons(self):
+        # Ensure default comparison compares id() of args
+        L = []
+        for i in range(10):
+            L.insert(len(L)//2, Empty())
+        for a in L:
+            for b in L:
+                self.assertEqual(cmp(a, b), cmp(id(a), id(b)),
+                                 'a=%r, b=%r' % (a, b))
+
+def test_main():
+    test_support.run_unittest(ComparisonTest)
+
+if __name__ == '__main__':
+    test_main()

Added: vendor/Python/current/Lib/test/test_compile.py
===================================================================
--- vendor/Python/current/Lib/test/test_compile.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_compile.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,402 @@
+import unittest
+import warnings
+import sys
+from test import test_support
+
+class TestSpecifics(unittest.TestCase):
+
+    def test_debug_assignment(self):
+        # catch assignments to __debug__
+        self.assertRaises(SyntaxError, compile, '__debug__ = 1', '?', 'single')
+        import __builtin__
+        prev = __builtin__.__debug__
+        setattr(__builtin__, '__debug__', 'sure')
+        setattr(__builtin__, '__debug__', prev)
+
+    def test_argument_handling(self):
+        # detect duplicate positional and keyword arguments
+        self.assertRaises(SyntaxError, eval, 'lambda a,a:0')
+        self.assertRaises(SyntaxError, eval, 'lambda a,a=1:0')
+        self.assertRaises(SyntaxError, eval, 'lambda a=1,a=1:0')
+        try:
+            exec 'def f(a, a): pass'
+            self.fail("duplicate arguments")
+        except SyntaxError:
+            pass
+        try:
+            exec 'def f(a = 0, a = 1): pass'
+            self.fail("duplicate keyword arguments")
+        except SyntaxError:
+            pass
+        try:
+            exec 'def f(a): global a; a = 1'
+            self.fail("variable is global and local")
+        except SyntaxError:
+            pass
+
+    def test_syntax_error(self):
+        self.assertRaises(SyntaxError, compile, "1+*3", "filename", "exec")
+
+    def test_duplicate_global_local(self):
+        try:
+            exec 'def f(a): global a; a = 1'
+            self.fail("variable is global and local")
+        except SyntaxError:
+            pass
+
+    def test_exec_with_general_mapping_for_locals(self):
+
+        class M:
+            "Test mapping interface versus possible calls from eval()."
+            def __getitem__(self, key):
+                if key == 'a':
+                    return 12
+                raise KeyError
+            def __setitem__(self, key, value):
+                self.results = (key, value)
+            def keys(self):
+                return list('xyz')
+
+        m = M()
+        g = globals()
+        exec 'z = a' in g, m
+        self.assertEqual(m.results, ('z', 12))
+        try:
+            exec 'z = b' in g, m
+        except NameError:
+            pass
+        else:
+            self.fail('Did not detect a KeyError')
+        exec 'z = dir()' in g, m
+        self.assertEqual(m.results, ('z', list('xyz')))
+        exec 'z = globals()' in g, m
+        self.assertEqual(m.results, ('z', g))
+        exec 'z = locals()' in g, m
+        self.assertEqual(m.results, ('z', m))
+        try:
+            exec 'z = b' in m
+        except TypeError:
+            pass
+        else:
+            self.fail('Did not validate globals as a real dict')
+
+        class A:
+            "Non-mapping"
+            pass
+        m = A()
+        try:
+            exec 'z = a' in g, m
+        except TypeError:
+            pass
+        else:
+            self.fail('Did not validate locals as a mapping')
+
+        # Verify that dict subclasses work as well
+        class D(dict):
+            def __getitem__(self, key):
+                if key == 'a':
+                    return 12
+                return dict.__getitem__(self, key)
+        d = D()
+        exec 'z = a' in g, d
+        self.assertEqual(d['z'], 12)
+
+    def test_extended_arg(self):
+        longexpr = 'x = x or ' + '-x' * 2500
+        code = '''
+def f(x):
+    %s
+    %s
+    %s
+    %s
+    %s
+    %s
+    %s
+    %s
+    %s
+    %s
+    # the expressions above have no effect, x == argument
+    while x:
+        x -= 1
+        # EXTENDED_ARG/JUMP_ABSOLUTE here
+    return x
+''' % ((longexpr,)*10)
+        exec code
+        self.assertEqual(f(5), 0)
+
+    def test_complex_args(self):
+
+        def comp_args((a, b)):
+            return a,b
+        self.assertEqual(comp_args((1, 2)), (1, 2))
+
+        def comp_args((a, b)=(3, 4)):
+            return a, b
+        self.assertEqual(comp_args((1, 2)), (1, 2))
+        self.assertEqual(comp_args(), (3, 4))
+
+        def comp_args(a, (b, c)):
+            return a, b, c
+        self.assertEqual(comp_args(1, (2, 3)), (1, 2, 3))
+
+        def comp_args(a=2, (b, c)=(3, 4)):
+            return a, b, c
+        self.assertEqual(comp_args(1, (2, 3)), (1, 2, 3))
+        self.assertEqual(comp_args(), (2, 3, 4))
+
+    def test_argument_order(self):
+        try:
+            exec 'def f(a=1, (b, c)): pass'
+            self.fail("non-default args after default")
+        except SyntaxError:
+            pass
+
+    def test_float_literals(self):
+        # testing bad float literals
+        self.assertRaises(SyntaxError, eval, "2e")
+        self.assertRaises(SyntaxError, eval, "2.0e+")
+        self.assertRaises(SyntaxError, eval, "1e-")
+        self.assertRaises(SyntaxError, eval, "3-4e/21")
+
+    def test_indentation(self):
+        # testing compile() of indented block w/o trailing newline"
+        s = """
+if 1:
+    if 2:
+        pass"""
+        compile(s, "<string>", "exec")
+
+    # This test is probably specific to CPython and may not generalize
+    # to other implementations.  We are trying to ensure that when
+    # the first line of code starts after 256, correct line numbers
+    # in tracebacks are still produced.
+    def test_leading_newlines(self):
+        s256 = "".join(["\n"] * 256 + ["spam"])
+        co = compile(s256, 'fn', 'exec')
+        self.assertEqual(co.co_firstlineno, 257)
+        self.assertEqual(co.co_lnotab, '')
+
+    def test_literals_with_leading_zeroes(self):
+        for arg in ["077787", "0xj", "0x.", "0e",  "090000000000000",
+                    "080000000000000", "000000000000009", "000000000000008"]:
+            self.assertRaises(SyntaxError, eval, arg)
+
+        self.assertEqual(eval("0777"), 511)
+        self.assertEqual(eval("0777L"), 511)
+        self.assertEqual(eval("000777"), 511)
+        self.assertEqual(eval("0xff"), 255)
+        self.assertEqual(eval("0xffL"), 255)
+        self.assertEqual(eval("0XfF"), 255)
+        self.assertEqual(eval("0777."), 777)
+        self.assertEqual(eval("0777.0"), 777)
+        self.assertEqual(eval("000000000000000000000000000000000000000000000000000777e0"), 777)
+        self.assertEqual(eval("0777e1"), 7770)
+        self.assertEqual(eval("0e0"), 0)
+        self.assertEqual(eval("0000E-012"), 0)
+        self.assertEqual(eval("09.5"), 9.5)
+        self.assertEqual(eval("0777j"), 777j)
+        self.assertEqual(eval("00j"), 0j)
+        self.assertEqual(eval("00.0"), 0)
+        self.assertEqual(eval("0e3"), 0)
+        self.assertEqual(eval("090000000000000."), 90000000000000.)
+        self.assertEqual(eval("090000000000000.0000000000000000000000"), 90000000000000.)
+        self.assertEqual(eval("090000000000000e0"), 90000000000000.)
+        self.assertEqual(eval("090000000000000e-0"), 90000000000000.)
+        self.assertEqual(eval("090000000000000j"), 90000000000000j)
+        self.assertEqual(eval("000000000000007"), 7)
+        self.assertEqual(eval("000000000000008."), 8.)
+        self.assertEqual(eval("000000000000009."), 9.)
+
+    def test_unary_minus(self):
+        # Verify treatment of unary minus on negative numbers SF bug #660455
+        if sys.maxint == 2147483647:
+            # 32-bit machine
+            all_one_bits = '0xffffffff'
+            self.assertEqual(eval(all_one_bits), 4294967295L)
+            self.assertEqual(eval("-" + all_one_bits), -4294967295L)
+        elif sys.maxint == 9223372036854775807:
+            # 64-bit machine
+            all_one_bits = '0xffffffffffffffff'
+            self.assertEqual(eval(all_one_bits), 18446744073709551615L)
+            self.assertEqual(eval("-" + all_one_bits), -18446744073709551615L)
+        else:
+            self.fail("How many bits *does* this machine have???")
+        # Verify treatment of contant folding on -(sys.maxint+1)
+        # i.e. -2147483648 on 32 bit platforms.  Should return int, not long.
+        self.assertTrue(isinstance(eval("%s" % (-sys.maxint - 1)), int))
+        self.assertTrue(isinstance(eval("%s" % (-sys.maxint - 2)), long))
+
+    if sys.maxint == 9223372036854775807:
+        def test_32_63_bit_values(self):
+            a = +4294967296  # 1 << 32
+            b = -4294967296  # 1 << 32
+            c = +281474976710656  # 1 << 48
+            d = -281474976710656  # 1 << 48
+            e = +4611686018427387904  # 1 << 62
+            f = -4611686018427387904  # 1 << 62
+            g = +9223372036854775807  # 1 << 63 - 1
+            h = -9223372036854775807  # 1 << 63 - 1
+
+            for variable in self.test_32_63_bit_values.func_code.co_consts:
+                if variable is not None:
+                    self.assertTrue(isinstance(variable, int))
+
+    def test_sequence_unpacking_error(self):
+        # Verify sequence packing/unpacking with "or".  SF bug #757818
+        i,j = (1, -1) or (-1, 1)
+        self.assertEqual(i, 1)
+        self.assertEqual(j, -1)
+
+    def test_none_assignment(self):
+        stmts = [
+            'None = 0',
+            'None += 0',
+            '__builtins__.None = 0',
+            'def None(): pass',
+            'class None: pass',
+            '(a, None) = 0, 0',
+            'for None in range(10): pass',
+            'def f(None): pass',
+        ]
+        for stmt in stmts:
+            stmt += "\n"
+            self.assertRaises(SyntaxError, compile, stmt, 'tmp', 'single')
+            self.assertRaises(SyntaxError, compile, stmt, 'tmp', 'exec')
+
+    def test_import(self):
+        succeed = [
+            'import sys',
+            'import os, sys',
+            'import os as bar',
+            'import os.path as bar',
+            'from __future__ import nested_scopes, generators',
+            'from __future__ import (nested_scopes,\ngenerators)',
+            'from __future__ import (nested_scopes,\ngenerators,)',
+            'from sys import stdin, stderr, stdout',
+            'from sys import (stdin, stderr,\nstdout)',
+            'from sys import (stdin, stderr,\nstdout,)',
+            'from sys import (stdin\n, stderr, stdout)',
+            'from sys import (stdin\n, stderr, stdout,)',
+            'from sys import stdin as si, stdout as so, stderr as se',
+            'from sys import (stdin as si, stdout as so, stderr as se)',
+            'from sys import (stdin as si, stdout as so, stderr as se,)',
+            ]
+        fail = [
+            'import (os, sys)',
+            'import (os), (sys)',
+            'import ((os), (sys))',
+            'import (sys',
+            'import sys)',
+            'import (os,)',
+            'import os As bar',
+            'import os.path a bar',
+            'from sys import stdin As stdout',
+            'from sys import stdin a stdout',
+            'from (sys) import stdin',
+            'from __future__ import (nested_scopes',
+            'from __future__ import nested_scopes)',
+            'from __future__ import nested_scopes,\ngenerators',
+            'from sys import (stdin',
+            'from sys import stdin)',
+            'from sys import stdin, stdout,\nstderr',
+            'from sys import stdin si',
+            'from sys import stdin,'
+            'from sys import (*)',
+            'from sys import (stdin,, stdout, stderr)',
+            'from sys import (stdin, stdout),',
+            ]
+        for stmt in succeed:
+            compile(stmt, 'tmp', 'exec')
+        for stmt in fail:
+            self.assertRaises(SyntaxError, compile, stmt, 'tmp', 'exec')
+
+    def test_for_distinct_code_objects(self):
+        # SF bug 1048870
+        def f():
+            f1 = lambda x=1: x
+            f2 = lambda x=2: x
+            return f1, f2
+        f1, f2 = f()
+        self.assertNotEqual(id(f1.func_code), id(f2.func_code))
+
+    def test_unicode_encoding(self):
+        code = u"# -*- coding: utf-8 -*-\npass\n"
+        self.assertRaises(SyntaxError, compile, code, "tmp", "exec")
+
+    def test_subscripts(self):
+        # SF bug 1448804
+        # Class to make testing subscript results easy
+        class str_map(object):
+            def __init__(self):
+                self.data = {}
+            def __getitem__(self, key):
+                return self.data[str(key)]
+            def __setitem__(self, key, value):
+                self.data[str(key)] = value
+            def __delitem__(self, key):
+                del self.data[str(key)]
+            def __contains__(self, key):
+                return str(key) in self.data
+        d = str_map()
+        # Index
+        d[1] = 1
+        self.assertEqual(d[1], 1)
+        d[1] += 1
+        self.assertEqual(d[1], 2)
+        del d[1]
+        self.assertEqual(1 in d, False)
+        # Tuple of indices
+        d[1, 1] = 1
+        self.assertEqual(d[1, 1], 1)
+        d[1, 1] += 1
+        self.assertEqual(d[1, 1], 2)
+        del d[1, 1]
+        self.assertEqual((1, 1) in d, False)
+        # Simple slice
+        d[1:2] = 1
+        self.assertEqual(d[1:2], 1)
+        d[1:2] += 1
+        self.assertEqual(d[1:2], 2)
+        del d[1:2]
+        self.assertEqual(slice(1, 2) in d, False)
+        # Tuple of simple slices
+        d[1:2, 1:2] = 1
+        self.assertEqual(d[1:2, 1:2], 1)
+        d[1:2, 1:2] += 1
+        self.assertEqual(d[1:2, 1:2], 2)
+        del d[1:2, 1:2]
+        self.assertEqual((slice(1, 2), slice(1, 2)) in d, False)
+        # Extended slice
+        d[1:2:3] = 1
+        self.assertEqual(d[1:2:3], 1)
+        d[1:2:3] += 1
+        self.assertEqual(d[1:2:3], 2)
+        del d[1:2:3]
+        self.assertEqual(slice(1, 2, 3) in d, False)
+        # Tuple of extended slices
+        d[1:2:3, 1:2:3] = 1
+        self.assertEqual(d[1:2:3, 1:2:3], 1)
+        d[1:2:3, 1:2:3] += 1
+        self.assertEqual(d[1:2:3, 1:2:3], 2)
+        del d[1:2:3, 1:2:3]
+        self.assertEqual((slice(1, 2, 3), slice(1, 2, 3)) in d, False)
+        # Ellipsis
+        d[...] = 1
+        self.assertEqual(d[...], 1)
+        d[...] += 1
+        self.assertEqual(d[...], 2)
+        del d[...]
+        self.assertEqual(Ellipsis in d, False)
+        # Tuple of Ellipses
+        d[..., ...] = 1
+        self.assertEqual(d[..., ...], 1)
+        d[..., ...] += 1
+        self.assertEqual(d[..., ...], 2)
+        del d[..., ...]
+        self.assertEqual((Ellipsis, Ellipsis) in d, False)
+
+def test_main():
+    test_support.run_unittest(TestSpecifics)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_compiler.py
===================================================================
--- vendor/Python/current/Lib/test/test_compiler.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_compiler.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,207 @@
+import compiler
+from compiler.ast import flatten
+import os, sys, time, unittest
+import test.test_support
+from random import random
+
+# How much time in seconds can pass before we print a 'Still working' message.
+_PRINT_WORKING_MSG_INTERVAL = 5 * 60
+
+class TrivialContext(object):
+    def __enter__(self):
+        return self
+    def __exit__(self, *exc_info):
+        pass
+
+class CompilerTest(unittest.TestCase):
+
+    def testCompileLibrary(self):
+        # A simple but large test.  Compile all the code in the
+        # standard library and its test suite.  This doesn't verify
+        # that any of the code is correct, merely the compiler is able
+        # to generate some kind of code for it.
+
+        next_time = time.time() + _PRINT_WORKING_MSG_INTERVAL
+        libdir = os.path.dirname(unittest.__file__)
+        testdir = os.path.dirname(test.test_support.__file__)
+
+        for dir in [libdir, testdir]:
+            for basename in os.listdir(dir):
+                # Print still working message since this test can be really slow
+                if next_time <= time.time():
+                    next_time = time.time() + _PRINT_WORKING_MSG_INTERVAL
+                    print >>sys.__stdout__, \
+                       '  testCompileLibrary still working, be patient...'
+                    sys.__stdout__.flush()
+
+                if not basename.endswith(".py"):
+                    continue
+                if not TEST_ALL and random() < 0.98:
+                    continue
+                path = os.path.join(dir, basename)
+                if test.test_support.verbose:
+                    print "compiling", path
+                f = open(path, "U")
+                buf = f.read()
+                f.close()
+                if "badsyntax" in basename or "bad_coding" in basename:
+                    self.assertRaises(SyntaxError, compiler.compile,
+                                      buf, basename, "exec")
+                else:
+                    try:
+                        compiler.compile(buf, basename, "exec")
+                    except Exception, e:
+                        args = list(e.args)
+                        args[0] += "[in file %s]" % basename
+                        e.args = tuple(args)
+                        raise
+
+    def testNewClassSyntax(self):
+        compiler.compile("class foo():pass\n\n","<string>","exec")
+
+    def testYieldExpr(self):
+        compiler.compile("def g(): yield\n\n", "<string>", "exec")
+
+    def testTryExceptFinally(self):
+        # Test that except and finally clauses in one try stmt are recognized
+        c = compiler.compile("try:\n 1/0\nexcept:\n e = 1\nfinally:\n f = 1",
+                             "<string>", "exec")
+        dct = {}
+        exec c in dct
+        self.assertEquals(dct.get('e'), 1)
+        self.assertEquals(dct.get('f'), 1)
+
+    def testDefaultArgs(self):
+        self.assertRaises(SyntaxError, compiler.parse, "def foo(a=1, b): pass")
+
+    def testDocstrings(self):
+        c = compiler.compile('"doc"', '<string>', 'exec')
+        self.assert_('__doc__' in c.co_names)
+        c = compiler.compile('def f():\n "doc"', '<string>', 'exec')
+        g = {}
+        exec c in g
+        self.assertEquals(g['f'].__doc__, "doc")
+
+    def testLineNo(self):
+        # Test that all nodes except Module have a correct lineno attribute.
+        filename = __file__
+        if filename.endswith((".pyc", ".pyo")):
+            filename = filename[:-1]
+        tree = compiler.parseFile(filename)
+        self.check_lineno(tree)
+
+    def check_lineno(self, node):
+        try:
+            self._check_lineno(node)
+        except AssertionError:
+            print node.__class__, node.lineno
+            raise
+
+    def _check_lineno(self, node):
+        if not node.__class__ in NOLINENO:
+            self.assert_(isinstance(node.lineno, int),
+                "lineno=%s on %s" % (node.lineno, node.__class__))
+            self.assert_(node.lineno > 0,
+                "lineno=%s on %s" % (node.lineno, node.__class__))
+        for child in node.getChildNodes():
+            self.check_lineno(child)
+
+    def testFlatten(self):
+        self.assertEquals(flatten([1, [2]]), [1, 2])
+        self.assertEquals(flatten((1, (2,))), [1, 2])
+
+    def testNestedScope(self):
+        c = compiler.compile('def g():\n'
+                             '    a = 1\n'
+                             '    def f(): return a + 2\n'
+                             '    return f()\n'
+                             'result = g()',
+                             '<string>',
+                             'exec')
+        dct = {}
+        exec c in dct
+        self.assertEquals(dct.get('result'), 3)
+
+    def testGenExp(self):
+        c = compiler.compile('list((i,j) for i in range(3) if i < 3'
+                             '           for j in range(4) if j > 2)',
+                             '<string>',
+                             'eval')
+        self.assertEquals(eval(c), [(0, 3), (1, 3), (2, 3)])
+
+    def testWith(self):
+        # SF bug 1638243
+        c = compiler.compile('from __future__ import with_statement\n'
+                             'def f():\n'
+                             '    with TrivialContext():\n'
+                             '        return 1\n'
+                             'result = f()',
+                             '<string>',
+                             'exec' )
+        dct = {'TrivialContext': TrivialContext}
+        exec c in dct
+        self.assertEquals(dct.get('result'), 1)
+
+    def testWithAss(self):
+        c = compiler.compile('from __future__ import with_statement\n'
+                             'def f():\n'
+                             '    with TrivialContext() as tc:\n'
+                             '        return 1\n'
+                             'result = f()',
+                             '<string>',
+                             'exec' )
+        dct = {'TrivialContext': TrivialContext}
+        exec c in dct
+        self.assertEquals(dct.get('result'), 1)
+
+
+NOLINENO = (compiler.ast.Module, compiler.ast.Stmt, compiler.ast.Discard)
+
+###############################################################################
+# code below is just used to trigger some possible errors, for the benefit of
+# testLineNo
+###############################################################################
+
+class Toto:
+    """docstring"""
+    pass
+
+a, b = 2, 3
+[c, d] = 5, 6
+l = [(x, y) for x, y in zip(range(5), range(5,10))]
+l[0]
+l[3:4]
+d = {'a': 2}
+d = {}
+t = ()
+t = (1, 2)
+l = []
+l = [1, 2]
+if l:
+    pass
+else:
+    a, b = b, a
+
+try:
+    print yo
+except:
+    yo = 3
+else:
+    yo += 3
+
+try:
+    a += b
+finally:
+    b = 0
+
+from math import *
+
+###############################################################################
+
+def test_main():
+    global TEST_ALL
+    TEST_ALL = test.test_support.is_resource_enabled("compiler")
+    test.test_support.run_unittest(CompilerTest)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_complex.py
===================================================================
--- vendor/Python/current/Lib/test/test_complex.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_complex.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,341 @@
+import unittest, os
+from test import test_support
+
+import warnings
+warnings.filterwarnings(
+    "ignore",
+    category=DeprecationWarning,
+    message=".*complex divmod.*are deprecated"
+)
+
+from random import random
+
+# These tests ensure that complex math does the right thing
+
+class ComplexTest(unittest.TestCase):
+
+    def assertAlmostEqual(self, a, b):
+        if isinstance(a, complex):
+            if isinstance(b, complex):
+                unittest.TestCase.assertAlmostEqual(self, a.real, b.real)
+                unittest.TestCase.assertAlmostEqual(self, a.imag, b.imag)
+            else:
+                unittest.TestCase.assertAlmostEqual(self, a.real, b)
+                unittest.TestCase.assertAlmostEqual(self, a.imag, 0.)
+        else:
+            if isinstance(b, complex):
+                unittest.TestCase.assertAlmostEqual(self, a, b.real)
+                unittest.TestCase.assertAlmostEqual(self, 0., b.imag)
+            else:
+                unittest.TestCase.assertAlmostEqual(self, a, b)
+
+    def assertCloseAbs(self, x, y, eps=1e-9):
+        """Return true iff floats x and y "are close\""""
+        # put the one with larger magnitude second
+        if abs(x) > abs(y):
+            x, y = y, x
+        if y == 0:
+            return abs(x) < eps
+        if x == 0:
+            return abs(y) < eps
+        # check that relative difference < eps
+        self.assert_(abs((x-y)/y) < eps)
+
+    def assertClose(self, x, y, eps=1e-9):
+        """Return true iff complexes x and y "are close\""""
+        self.assertCloseAbs(x.real, y.real, eps)
+        self.assertCloseAbs(x.imag, y.imag, eps)
+
+    def assertIs(self, a, b):
+        self.assert_(a is b)
+
+    def check_div(self, x, y):
+        """Compute complex z=x*y, and check that z/x==y and z/y==x."""
+        z = x * y
+        if x != 0:
+            q = z / x
+            self.assertClose(q, y)
+            q = z.__div__(x)
+            self.assertClose(q, y)
+            q = z.__truediv__(x)
+            self.assertClose(q, y)
+        if y != 0:
+            q = z / y
+            self.assertClose(q, x)
+            q = z.__div__(y)
+            self.assertClose(q, x)
+            q = z.__truediv__(y)
+            self.assertClose(q, x)
+
+    def test_div(self):
+        simple_real = [float(i) for i in xrange(-5, 6)]
+        simple_complex = [complex(x, y) for x in simple_real for y in simple_real]
+        for x in simple_complex:
+            for y in simple_complex:
+                self.check_div(x, y)
+
+        # A naive complex division algorithm (such as in 2.0) is very prone to
+        # nonsense errors for these (overflows and underflows).
+        self.check_div(complex(1e200, 1e200), 1+0j)
+        self.check_div(complex(1e-200, 1e-200), 1+0j)
+
+        # Just for fun.
+        for i in xrange(100):
+            self.check_div(complex(random(), random()),
+                           complex(random(), random()))
+
+        self.assertRaises(ZeroDivisionError, complex.__div__, 1+1j, 0+0j)
+        # FIXME: The following currently crashes on Alpha
+        # self.assertRaises(OverflowError, pow, 1e200+1j, 1e200+1j)
+
+    def test_truediv(self):
+        self.assertAlmostEqual(complex.__truediv__(2+0j, 1+1j), 1-1j)
+        self.assertRaises(ZeroDivisionError, complex.__truediv__, 1+1j, 0+0j)
+
+    def test_floordiv(self):
+        self.assertAlmostEqual(complex.__floordiv__(3+0j, 1.5+0j), 2)
+        self.assertRaises(ZeroDivisionError, complex.__floordiv__, 3+0j, 0+0j)
+
+    def test_coerce(self):
+        self.assertRaises(OverflowError, complex.__coerce__, 1+1j, 1L<<10000)
+
+    def test_richcompare(self):
+        self.assertRaises(OverflowError, complex.__eq__, 1+1j, 1L<<10000)
+        self.assertEqual(complex.__lt__(1+1j, None), NotImplemented)
+        self.assertIs(complex.__eq__(1+1j, 1+1j), True)
+        self.assertIs(complex.__eq__(1+1j, 2+2j), False)
+        self.assertIs(complex.__ne__(1+1j, 1+1j), False)
+        self.assertIs(complex.__ne__(1+1j, 2+2j), True)
+        self.assertRaises(TypeError, complex.__lt__, 1+1j, 2+2j)
+        self.assertRaises(TypeError, complex.__le__, 1+1j, 2+2j)
+        self.assertRaises(TypeError, complex.__gt__, 1+1j, 2+2j)
+        self.assertRaises(TypeError, complex.__ge__, 1+1j, 2+2j)
+
+    def test_mod(self):
+        self.assertRaises(ZeroDivisionError, (1+1j).__mod__, 0+0j)
+
+        a = 3.33+4.43j
+        try:
+            a % 0
+        except ZeroDivisionError:
+            pass
+        else:
+            self.fail("modulo parama can't be 0")
+
+    def test_divmod(self):
+        self.assertRaises(ZeroDivisionError, divmod, 1+1j, 0+0j)
+
+    def test_pow(self):
+        self.assertAlmostEqual(pow(1+1j, 0+0j), 1.0)
+        self.assertAlmostEqual(pow(0+0j, 2+0j), 0.0)
+        self.assertRaises(ZeroDivisionError, pow, 0+0j, 1j)
+        self.assertAlmostEqual(pow(1j, -1), 1/1j)
+        self.assertAlmostEqual(pow(1j, 200), 1)
+        self.assertRaises(ValueError, pow, 1+1j, 1+1j, 1+1j)
+
+        a = 3.33+4.43j
+        self.assertEqual(a ** 0j, 1)
+        self.assertEqual(a ** 0.+0.j, 1)
+
+        self.assertEqual(3j ** 0j, 1)
+        self.assertEqual(3j ** 0, 1)
+
+        try:
+            0j ** a
+        except ZeroDivisionError:
+            pass
+        else:
+            self.fail("should fail 0.0 to negative or complex power")
+
+        try:
+            0j ** (3-2j)
+        except ZeroDivisionError:
+            pass
+        else:
+            self.fail("should fail 0.0 to negative or complex power")
+
+        # The following is used to exercise certain code paths
+        self.assertEqual(a ** 105, a ** 105)
+        self.assertEqual(a ** -105, a ** -105)
+        self.assertEqual(a ** -30, a ** -30)
+
+        self.assertEqual(0.0j ** 0, 1)
+
+        b = 5.1+2.3j
+        self.assertRaises(ValueError, pow, a, b, 0)
+
+    def test_boolcontext(self):
+        for i in xrange(100):
+            self.assert_(complex(random() + 1e-6, random() + 1e-6))
+        self.assert_(not complex(0.0, 0.0))
+
+    def test_conjugate(self):
+        self.assertClose(complex(5.3, 9.8).conjugate(), 5.3-9.8j)
+
+    def test_constructor(self):
+        class OS:
+            def __init__(self, value): self.value = value
+            def __complex__(self): return self.value
+        class NS(object):
+            def __init__(self, value): self.value = value
+            def __complex__(self): return self.value
+        self.assertEqual(complex(OS(1+10j)), 1+10j)
+        self.assertEqual(complex(NS(1+10j)), 1+10j)
+        self.assertRaises(TypeError, complex, OS(None))
+        self.assertRaises(TypeError, complex, NS(None))
+
+        self.assertAlmostEqual(complex("1+10j"), 1+10j)
+        self.assertAlmostEqual(complex(10), 10+0j)
+        self.assertAlmostEqual(complex(10.0), 10+0j)
+        self.assertAlmostEqual(complex(10L), 10+0j)
+        self.assertAlmostEqual(complex(10+0j), 10+0j)
+        self.assertAlmostEqual(complex(1,10), 1+10j)
+        self.assertAlmostEqual(complex(1,10L), 1+10j)
+        self.assertAlmostEqual(complex(1,10.0), 1+10j)
+        self.assertAlmostEqual(complex(1L,10), 1+10j)
+        self.assertAlmostEqual(complex(1L,10L), 1+10j)
+        self.assertAlmostEqual(complex(1L,10.0), 1+10j)
+        self.assertAlmostEqual(complex(1.0,10), 1+10j)
+        self.assertAlmostEqual(complex(1.0,10L), 1+10j)
+        self.assertAlmostEqual(complex(1.0,10.0), 1+10j)
+        self.assertAlmostEqual(complex(3.14+0j), 3.14+0j)
+        self.assertAlmostEqual(complex(3.14), 3.14+0j)
+        self.assertAlmostEqual(complex(314), 314.0+0j)
+        self.assertAlmostEqual(complex(314L), 314.0+0j)
+        self.assertAlmostEqual(complex(3.14+0j, 0j), 3.14+0j)
+        self.assertAlmostEqual(complex(3.14, 0.0), 3.14+0j)
+        self.assertAlmostEqual(complex(314, 0), 314.0+0j)
+        self.assertAlmostEqual(complex(314L, 0L), 314.0+0j)
+        self.assertAlmostEqual(complex(0j, 3.14j), -3.14+0j)
+        self.assertAlmostEqual(complex(0.0, 3.14j), -3.14+0j)
+        self.assertAlmostEqual(complex(0j, 3.14), 3.14j)
+        self.assertAlmostEqual(complex(0.0, 3.14), 3.14j)
+        self.assertAlmostEqual(complex("1"), 1+0j)
+        self.assertAlmostEqual(complex("1j"), 1j)
+        self.assertAlmostEqual(complex(),  0)
+        self.assertAlmostEqual(complex("-1"), -1)
+        self.assertAlmostEqual(complex("+1"), +1)
+
+        class complex2(complex): pass
+        self.assertAlmostEqual(complex(complex2(1+1j)), 1+1j)
+        self.assertAlmostEqual(complex(real=17, imag=23), 17+23j)
+        self.assertAlmostEqual(complex(real=17+23j), 17+23j)
+        self.assertAlmostEqual(complex(real=17+23j, imag=23), 17+46j)
+        self.assertAlmostEqual(complex(real=1+2j, imag=3+4j), -3+5j)
+
+        c = 3.14 + 1j
+        self.assert_(complex(c) is c)
+        del c
+
+        self.assertRaises(TypeError, complex, "1", "1")
+        self.assertRaises(TypeError, complex, 1, "1")
+
+        self.assertEqual(complex("  3.14+J  "), 3.14+1j)
+        if test_support.have_unicode:
+            self.assertEqual(complex(unicode("  3.14+J  ")), 3.14+1j)
+
+        # SF bug 543840:  complex(string) accepts strings with \0
+        # Fixed in 2.3.
+        self.assertRaises(ValueError, complex, '1+1j\0j')
+
+        self.assertRaises(TypeError, int, 5+3j)
+        self.assertRaises(TypeError, long, 5+3j)
+        self.assertRaises(TypeError, float, 5+3j)
+        self.assertRaises(ValueError, complex, "")
+        self.assertRaises(TypeError, complex, None)
+        self.assertRaises(ValueError, complex, "\0")
+        self.assertRaises(TypeError, complex, "1", "2")
+        self.assertRaises(TypeError, complex, "1", 42)
+        self.assertRaises(TypeError, complex, 1, "2")
+        self.assertRaises(ValueError, complex, "1+")
+        self.assertRaises(ValueError, complex, "1+1j+1j")
+        self.assertRaises(ValueError, complex, "--")
+        if test_support.have_unicode:
+            self.assertRaises(ValueError, complex, unicode("1"*500))
+            self.assertRaises(ValueError, complex, unicode("x"))
+
+        class EvilExc(Exception):
+            pass
+
+        class evilcomplex:
+            def __complex__(self):
+                raise EvilExc
+
+        self.assertRaises(EvilExc, complex, evilcomplex())
+
+        class float2:
+            def __init__(self, value):
+                self.value = value
+            def __float__(self):
+                return self.value
+
+        self.assertAlmostEqual(complex(float2(42.)), 42)
+        self.assertAlmostEqual(complex(real=float2(17.), imag=float2(23.)), 17+23j)
+        self.assertRaises(TypeError, complex, float2(None))
+
+        class complex0(complex):
+            """Test usage of __complex__() when inheriting from 'complex'"""
+            def __complex__(self):
+                return 42j
+
+        class complex1(complex):
+            """Test usage of __complex__() with a __new__() method"""
+            def __new__(self, value=0j):
+                return complex.__new__(self, 2*value)
+            def __complex__(self):
+                return self
+
+        class complex2(complex):
+            """Make sure that __complex__() calls fail if anything other than a
+            complex is returned"""
+            def __complex__(self):
+                return None
+
+        self.assertAlmostEqual(complex(complex0(1j)), 42j)
+        self.assertAlmostEqual(complex(complex1(1j)), 2j)
+        self.assertRaises(TypeError, complex, complex2(1j))
+
+    def test_hash(self):
+        for x in xrange(-30, 30):
+            self.assertEqual(hash(x), hash(complex(x, 0)))
+            x /= 3.0    # now check against floating point
+            self.assertEqual(hash(x), hash(complex(x, 0.)))
+
+    def test_abs(self):
+        nums = [complex(x/3., y/7.) for x in xrange(-9,9) for y in xrange(-9,9)]
+        for num in nums:
+            self.assertAlmostEqual((num.real**2 + num.imag**2)  ** 0.5, abs(num))
+
+    def test_repr(self):
+        self.assertEqual(repr(1+6j), '(1+6j)')
+        self.assertEqual(repr(1-6j), '(1-6j)')
+
+        self.assertNotEqual(repr(-(1+0j)), '(-1+-0j)')
+
+    def test_neg(self):
+        self.assertEqual(-(1+6j), -1-6j)
+
+    def test_file(self):
+        a = 3.33+4.43j
+        b = 5.1+2.3j
+
+        fo = None
+        try:
+            fo = open(test_support.TESTFN, "wb")
+            print >>fo, a, b
+            fo.close()
+            fo = open(test_support.TESTFN, "rb")
+            self.assertEqual(fo.read(), "%s %s\n" % (a, b))
+        finally:
+            if (fo is not None) and (not fo.closed):
+                fo.close()
+            try:
+                os.remove(test_support.TESTFN)
+            except (OSError, IOError):
+                pass
+
+def test_main():
+    test_support.run_unittest(ComplexTest)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_complex_args.py
===================================================================
--- vendor/Python/current/Lib/test/test_complex_args.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_complex_args.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,91 @@
+
+import unittest
+from test import test_support
+
+class ComplexArgsTestCase(unittest.TestCase):
+
+    def check(self, func, expected, *args):
+        self.assertEqual(func(*args), expected)
+
+    # These functions are tested below as lambdas too.  If you add a function test,
+    # also add a similar lambda test.
+
+    def test_func_parens_no_unpacking(self):
+        def f(((((x))))): return x
+        self.check(f, 1, 1)
+        # Inner parens are elided, same as: f(x,)
+        def f(((x)),): return x
+        self.check(f, 2, 2)
+
+    def test_func_1(self):
+        def f(((((x),)))): return x
+        self.check(f, 3, (3,))
+        def f(((((x)),))): return x
+        self.check(f, 4, (4,))
+        def f(((((x))),)): return x
+        self.check(f, 5, (5,))
+        def f(((x),)): return x
+        self.check(f, 6, (6,))
+
+    def test_func_2(self):
+        def f(((((x)),),)): return x
+        self.check(f, 2, ((2,),))
+
+    def test_func_3(self):
+        def f((((((x)),),),)): return x
+        self.check(f, 3, (((3,),),))
+
+    def test_func_complex(self):
+        def f((((((x)),),),), a, b, c): return x, a, b, c
+        self.check(f, (3, 9, 8, 7), (((3,),),), 9, 8, 7)
+
+        def f(((((((x)),)),),), a, b, c): return x, a, b, c
+        self.check(f, (3, 9, 8, 7), (((3,),),), 9, 8, 7)
+
+        def f(a, b, c, ((((((x)),)),),)): return a, b, c, x
+        self.check(f, (9, 8, 7, 3), 9, 8, 7, (((3,),),))
+
+    # Duplicate the tests above, but for lambda.  If you add a lambda test,
+    # also add a similar function test above.
+
+    def test_lambda_parens_no_unpacking(self):
+        f = lambda (((((x))))): x
+        self.check(f, 1, 1)
+        # Inner parens are elided, same as: f(x,)
+        f = lambda ((x)),: x
+        self.check(f, 2, 2)
+
+    def test_lambda_1(self):
+        f = lambda (((((x),)))): x
+        self.check(f, 3, (3,))
+        f = lambda (((((x)),))): x
+        self.check(f, 4, (4,))
+        f = lambda (((((x))),)): x
+        self.check(f, 5, (5,))
+        f = lambda (((x),)): x
+        self.check(f, 6, (6,))
+
+    def test_lambda_2(self):
+        f = lambda (((((x)),),)): x
+        self.check(f, 2, ((2,),))
+
+    def test_lambda_3(self):
+        f = lambda ((((((x)),),),)): x
+        self.check(f, 3, (((3,),),))
+
+    def test_lambda_complex(self):
+        f = lambda (((((x)),),),), a, b, c: (x, a, b, c)
+        self.check(f, (3, 9, 8, 7), (((3,),),), 9, 8, 7)
+
+        f = lambda ((((((x)),)),),), a, b, c: (x, a, b, c)
+        self.check(f, (3, 9, 8, 7), (((3,),),), 9, 8, 7)
+
+        f = lambda a, b, c, ((((((x)),)),),): (a, b, c, x)
+        self.check(f, (9, 8, 7, 3), 9, 8, 7, (((3,),),))
+
+
+def test_main():
+    test_support.run_unittest(ComplexArgsTestCase)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_contains.py
===================================================================
--- vendor/Python/current/Lib/test/test_contains.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_contains.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,133 @@
+from test.test_support import TestFailed, have_unicode
+
+class base_set:
+
+    def __init__(self, el):
+        self.el = el
+
+class set(base_set):
+
+    def __contains__(self, el):
+        return self.el == el
+
+class seq(base_set):
+
+    def __getitem__(self, n):
+        return [self.el][n]
+
+def check(ok, *args):
+    if not ok:
+        raise TestFailed, " ".join(map(str, args))
+
+a = base_set(1)
+b = set(1)
+c = seq(1)
+
+check(1 in b, "1 not in set(1)")
+check(0 not in b, "0 in set(1)")
+check(1 in c, "1 not in seq(1)")
+check(0 not in c, "0 in seq(1)")
+
+try:
+    1 in a
+    check(0, "in base_set did not raise error")
+except TypeError:
+    pass
+
+try:
+    1 not in a
+    check(0, "not in base_set did not raise error")
+except TypeError:
+    pass
+
+# Test char in string
+
+check('c' in 'abc', "'c' not in 'abc'")
+check('d' not in 'abc', "'d' in 'abc'")
+
+check('' in '', "'' not in ''")
+check('' in 'abc', "'' not in 'abc'")
+
+try:
+    None in 'abc'
+    check(0, "None in 'abc' did not raise error")
+except TypeError:
+    pass
+
+
+if have_unicode:
+
+    # Test char in Unicode
+
+    check('c' in unicode('abc'), "'c' not in u'abc'")
+    check('d' not in unicode('abc'), "'d' in u'abc'")
+
+    check('' in unicode(''), "'' not in u''")
+    check(unicode('') in '', "u'' not in ''")
+    check(unicode('') in unicode(''), "u'' not in u''")
+    check('' in unicode('abc'), "'' not in u'abc'")
+    check(unicode('') in 'abc', "u'' not in 'abc'")
+    check(unicode('') in unicode('abc'), "u'' not in u'abc'")
+
+    try:
+        None in unicode('abc')
+        check(0, "None in u'abc' did not raise error")
+    except TypeError:
+        pass
+
+    # Test Unicode char in Unicode
+
+    check(unicode('c') in unicode('abc'), "u'c' not in u'abc'")
+    check(unicode('d') not in unicode('abc'), "u'd' in u'abc'")
+
+    # Test Unicode char in string
+
+    check(unicode('c') in 'abc', "u'c' not in 'abc'")
+    check(unicode('d') not in 'abc', "u'd' in 'abc'")
+
+# A collection of tests on builtin sequence types
+a = range(10)
+for i in a:
+    check(i in a, "%r not in %r" % (i, a))
+check(16 not in a, "16 not in %r" % (a,))
+check(a not in a, "%s not in %r" % (a, a))
+
+a = tuple(a)
+for i in a:
+    check(i in a, "%r not in %r" % (i, a))
+check(16 not in a, "16 not in %r" % (a,))
+check(a not in a, "%r not in %r" % (a, a))
+
+class Deviant1:
+    """Behaves strangely when compared
+
+    This class is designed to make sure that the contains code
+    works when the list is modified during the check.
+    """
+
+    aList = range(15)
+
+    def __cmp__(self, other):
+        if other == 12:
+            self.aList.remove(12)
+            self.aList.remove(13)
+            self.aList.remove(14)
+        return 1
+
+check(Deviant1() not in Deviant1.aList, "Deviant1 failed")
+
+class Deviant2:
+    """Behaves strangely when compared
+
+    This class raises an exception during comparison.  That in
+    turn causes the comparison to fail with a TypeError.
+    """
+
+    def __cmp__(self, other):
+        if other == 4:
+            raise RuntimeError, "gotcha"
+
+try:
+    check(Deviant2() not in a, "oops")
+except TypeError:
+    pass

Added: vendor/Python/current/Lib/test/test_contextlib.py
===================================================================
--- vendor/Python/current/Lib/test/test_contextlib.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_contextlib.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,340 @@
+"""Unit tests for contextlib.py, and other context managers."""
+
+from __future__ import with_statement
+
+import sys
+import os
+import decimal
+import tempfile
+import unittest
+import threading
+from contextlib import *  # Tests __all__
+from test.test_support import run_suite
+
+class ContextManagerTestCase(unittest.TestCase):
+
+    def test_contextmanager_plain(self):
+        state = []
+        @contextmanager
+        def woohoo():
+            state.append(1)
+            yield 42
+            state.append(999)
+        with woohoo() as x:
+            self.assertEqual(state, [1])
+            self.assertEqual(x, 42)
+            state.append(x)
+        self.assertEqual(state, [1, 42, 999])
+
+    def test_contextmanager_finally(self):
+        state = []
+        @contextmanager
+        def woohoo():
+            state.append(1)
+            try:
+                yield 42
+            finally:
+                state.append(999)
+        try:
+            with woohoo() as x:
+                self.assertEqual(state, [1])
+                self.assertEqual(x, 42)
+                state.append(x)
+                raise ZeroDivisionError()
+        except ZeroDivisionError:
+            pass
+        else:
+            self.fail("Expected ZeroDivisionError")
+        self.assertEqual(state, [1, 42, 999])
+
+    def test_contextmanager_no_reraise(self):
+        @contextmanager
+        def whee():
+            yield
+        ctx = whee()
+        ctx.__enter__()
+        # Calling __exit__ should not result in an exception
+        self.failIf(ctx.__exit__(TypeError, TypeError("foo"), None))
+
+    def test_contextmanager_trap_yield_after_throw(self):
+        @contextmanager
+        def whoo():
+            try:
+                yield
+            except:
+                yield
+        ctx = whoo()
+        ctx.__enter__()
+        self.assertRaises(
+            RuntimeError, ctx.__exit__, TypeError, TypeError("foo"), None
+        )
+
+    def test_contextmanager_except(self):
+        state = []
+        @contextmanager
+        def woohoo():
+            state.append(1)
+            try:
+                yield 42
+            except ZeroDivisionError, e:
+                state.append(e.args[0])
+                self.assertEqual(state, [1, 42, 999])
+        with woohoo() as x:
+            self.assertEqual(state, [1])
+            self.assertEqual(x, 42)
+            state.append(x)
+            raise ZeroDivisionError(999)
+        self.assertEqual(state, [1, 42, 999])
+
+    def test_contextmanager_attribs(self):
+        def attribs(**kw):
+            def decorate(func):
+                for k,v in kw.items():
+                    setattr(func,k,v)
+                return func
+            return decorate
+        @contextmanager
+        @attribs(foo='bar')
+        def baz(spam):
+            """Whee!"""
+        self.assertEqual(baz.__name__,'baz')
+        self.assertEqual(baz.foo, 'bar')
+        self.assertEqual(baz.__doc__, "Whee!")
+
+class NestedTestCase(unittest.TestCase):
+
+    # XXX This needs more work
+
+    def test_nested(self):
+        @contextmanager
+        def a():
+            yield 1
+        @contextmanager
+        def b():
+            yield 2
+        @contextmanager
+        def c():
+            yield 3
+        with nested(a(), b(), c()) as (x, y, z):
+            self.assertEqual(x, 1)
+            self.assertEqual(y, 2)
+            self.assertEqual(z, 3)
+
+    def test_nested_cleanup(self):
+        state = []
+        @contextmanager
+        def a():
+            state.append(1)
+            try:
+                yield 2
+            finally:
+                state.append(3)
+        @contextmanager
+        def b():
+            state.append(4)
+            try:
+                yield 5
+            finally:
+                state.append(6)
+        try:
+            with nested(a(), b()) as (x, y):
+                state.append(x)
+                state.append(y)
+                1/0
+        except ZeroDivisionError:
+            self.assertEqual(state, [1, 4, 2, 5, 6, 3])
+        else:
+            self.fail("Didn't raise ZeroDivisionError")
+
+    def test_nested_right_exception(self):
+        state = []
+        @contextmanager
+        def a():
+            yield 1
+        class b(object):
+            def __enter__(self):
+                return 2
+            def __exit__(self, *exc_info):
+                try:
+                    raise Exception()
+                except:
+                    pass
+        try:
+            with nested(a(), b()) as (x, y):
+                1/0
+        except ZeroDivisionError:
+            self.assertEqual((x, y), (1, 2))
+        except Exception:
+            self.fail("Reraised wrong exception")
+        else:
+            self.fail("Didn't raise ZeroDivisionError")
+
+    def test_nested_b_swallows(self):
+        @contextmanager
+        def a():
+            yield
+        @contextmanager
+        def b():
+            try:
+                yield
+            except:
+                # Swallow the exception
+                pass
+        try:
+            with nested(a(), b()):
+                1/0
+        except ZeroDivisionError:
+            self.fail("Didn't swallow ZeroDivisionError")
+
+    def test_nested_break(self):
+        @contextmanager
+        def a():
+            yield
+        state = 0
+        while True:
+            state += 1
+            with nested(a(), a()):
+                break
+            state += 10
+        self.assertEqual(state, 1)
+
+    def test_nested_continue(self):
+        @contextmanager
+        def a():
+            yield
+        state = 0
+        while state < 3:
+            state += 1
+            with nested(a(), a()):
+                continue
+            state += 10
+        self.assertEqual(state, 3)
+
+    def test_nested_return(self):
+        @contextmanager
+        def a():
+            try:
+                yield
+            except:
+                pass
+        def foo():
+            with nested(a(), a()):
+                return 1
+            return 10
+        self.assertEqual(foo(), 1)
+
+class ClosingTestCase(unittest.TestCase):
+
+    # XXX This needs more work
+
+    def test_closing(self):
+        state = []
+        class C:
+            def close(self):
+                state.append(1)
+        x = C()
+        self.assertEqual(state, [])
+        with closing(x) as y:
+            self.assertEqual(x, y)
+        self.assertEqual(state, [1])
+
+    def test_closing_error(self):
+        state = []
+        class C:
+            def close(self):
+                state.append(1)
+        x = C()
+        self.assertEqual(state, [])
+        try:
+            with closing(x) as y:
+                self.assertEqual(x, y)
+                1/0
+        except ZeroDivisionError:
+            self.assertEqual(state, [1])
+        else:
+            self.fail("Didn't raise ZeroDivisionError")
+
+class FileContextTestCase(unittest.TestCase):
+
+    def testWithOpen(self):
+        tfn = tempfile.mktemp()
+        try:
+            f = None
+            with open(tfn, "w") as f:
+                self.failIf(f.closed)
+                f.write("Booh\n")
+            self.failUnless(f.closed)
+            f = None
+            try:
+                with open(tfn, "r") as f:
+                    self.failIf(f.closed)
+                    self.assertEqual(f.read(), "Booh\n")
+                    1/0
+            except ZeroDivisionError:
+                self.failUnless(f.closed)
+            else:
+                self.fail("Didn't raise ZeroDivisionError")
+        finally:
+            try:
+                os.remove(tfn)
+            except os.error:
+                pass
+
+class LockContextTestCase(unittest.TestCase):
+
+    def boilerPlate(self, lock, locked):
+        self.failIf(locked())
+        with lock:
+            self.failUnless(locked())
+        self.failIf(locked())
+        try:
+            with lock:
+                self.failUnless(locked())
+                1/0
+        except ZeroDivisionError:
+            self.failIf(locked())
+        else:
+            self.fail("Didn't raise ZeroDivisionError")
+
+    def testWithLock(self):
+        lock = threading.Lock()
+        self.boilerPlate(lock, lock.locked)
+
+    def testWithRLock(self):
+        lock = threading.RLock()
+        self.boilerPlate(lock, lock._is_owned)
+
+    def testWithCondition(self):
+        lock = threading.Condition()
+        def locked():
+            return lock._is_owned()
+        self.boilerPlate(lock, locked)
+
+    def testWithSemaphore(self):
+        lock = threading.Semaphore()
+        def locked():
+            if lock.acquire(False):
+                lock.release()
+                return False
+            else:
+                return True
+        self.boilerPlate(lock, locked)
+
+    def testWithBoundedSemaphore(self):
+        lock = threading.BoundedSemaphore()
+        def locked():
+            if lock.acquire(False):
+                lock.release()
+                return False
+            else:
+                return True
+        self.boilerPlate(lock, locked)
+
+# This is needed to make the test actually run under regrtest.py!
+def test_main():
+    run_suite(
+        unittest.defaultTestLoader.loadTestsFromModule(sys.modules[__name__])
+    )
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_cookie.py
===================================================================
--- vendor/Python/current/Lib/test/test_cookie.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_cookie.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,50 @@
+# Simple test suite for Cookie.py
+
+from test.test_support import verify, verbose, run_doctest
+import Cookie
+
+import warnings
+warnings.filterwarnings("ignore",
+                        ".* class is insecure.*",
+                        DeprecationWarning)
+
+# Currently this only tests SimpleCookie
+
+cases = [
+    ('chips=ahoy; vienna=finger', {'chips':'ahoy', 'vienna':'finger'}),
+    ('keebler="E=mc2; L=\\"Loves\\"; fudge=\\012;"',
+     {'keebler' : 'E=mc2; L="Loves"; fudge=\012;'}),
+
+    # Check illegal cookies that have an '=' char in an unquoted value
+    ('keebler=E=mc2', {'keebler' : 'E=mc2'})
+    ]
+
+for data, dict in cases:
+    C = Cookie.SimpleCookie() ; C.load(data)
+    print repr(C)
+    print C.output(sep='\n')
+    for k, v in sorted(dict.iteritems()):
+        print ' ', k, repr( C[k].value ), repr(v)
+        verify(C[k].value == v)
+        print C[k]
+
+C = Cookie.SimpleCookie()
+C.load('Customer="WILE_E_COYOTE"; Version=1; Path=/acme')
+
+verify(C['Customer'].value == 'WILE_E_COYOTE')
+verify(C['Customer']['version'] == '1')
+verify(C['Customer']['path'] == '/acme')
+
+print C.output(['path'])
+print C.js_output()
+print C.js_output(['path'])
+
+# Try cookie with quoted meta-data
+C = Cookie.SimpleCookie()
+C.load('Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"')
+verify(C['Customer'].value == 'WILE_E_COYOTE')
+verify(C['Customer']['version'] == '1')
+verify(C['Customer']['path'] == '/acme')
+
+print "If anything blows up after this line, it's from Cookie's doctest."
+run_doctest(Cookie)

Added: vendor/Python/current/Lib/test/test_cookielib.py
===================================================================
--- vendor/Python/current/Lib/test/test_cookielib.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_cookielib.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1736 @@
+# -*- coding: utf-8 -*-
+"""Tests for cookielib.py."""
+
+import re, os, time
+from unittest import TestCase
+
+from test import test_support
+
+class DateTimeTests(TestCase):
+
+    def test_time2isoz(self):
+        from cookielib import time2isoz
+
+        base = 1019227000
+        day = 24*3600
+        self.assertEquals(time2isoz(base), "2002-04-19 14:36:40Z")
+        self.assertEquals(time2isoz(base+day), "2002-04-20 14:36:40Z")
+        self.assertEquals(time2isoz(base+2*day), "2002-04-21 14:36:40Z")
+        self.assertEquals(time2isoz(base+3*day), "2002-04-22 14:36:40Z")
+
+        az = time2isoz()
+        bz = time2isoz(500000)
+        for text in (az, bz):
+            self.assert_(re.search(r"^\d{4}-\d\d-\d\d \d\d:\d\d:\d\dZ$", text),
+                         "bad time2isoz format: %s %s" % (az, bz))
+
+    def test_http2time(self):
+        from cookielib import http2time
+
+        def parse_date(text):
+            return time.gmtime(http2time(text))[:6]
+
+        self.assertEquals(parse_date("01 Jan 2001"), (2001, 1, 1, 0, 0, 0.0))
+
+        # this test will break around year 2070
+        self.assertEquals(parse_date("03-Feb-20"), (2020, 2, 3, 0, 0, 0.0))
+
+        # this test will break around year 2048
+        self.assertEquals(parse_date("03-Feb-98"), (1998, 2, 3, 0, 0, 0.0))
+
+    def test_http2time_formats(self):
+        from cookielib import http2time, time2isoz
+
+        # test http2time for supported dates.  Test cases with 2 digit year
+        # will probably break in year 2044.
+        tests = [
+         'Thu, 03 Feb 1994 00:00:00 GMT',  # proposed new HTTP format
+         'Thursday, 03-Feb-94 00:00:00 GMT',  # old rfc850 HTTP format
+         'Thursday, 03-Feb-1994 00:00:00 GMT',  # broken rfc850 HTTP format
+
+         '03 Feb 1994 00:00:00 GMT',  # HTTP format (no weekday)
+         '03-Feb-94 00:00:00 GMT',  # old rfc850 (no weekday)
+         '03-Feb-1994 00:00:00 GMT',  # broken rfc850 (no weekday)
+         '03-Feb-1994 00:00 GMT',  # broken rfc850 (no weekday, no seconds)
+         '03-Feb-1994 00:00',  # broken rfc850 (no weekday, no seconds, no tz)
+
+         '03-Feb-94',  # old rfc850 HTTP format (no weekday, no time)
+         '03-Feb-1994',  # broken rfc850 HTTP format (no weekday, no time)
+         '03 Feb 1994',  # proposed new HTTP format (no weekday, no time)
+
+         # A few tests with extra space at various places
+         '  03   Feb   1994  0:00  ',
+         '  03-Feb-1994  ',
+        ]
+
+        test_t = 760233600  # assume broken POSIX counting of seconds
+        result = time2isoz(test_t)
+        expected = "1994-02-03 00:00:00Z"
+        self.assertEquals(result, expected,
+                          "%s  =>  '%s' (%s)" % (test_t, result, expected))
+
+        for s in tests:
+            t = http2time(s)
+            t2 = http2time(s.lower())
+            t3 = http2time(s.upper())
+
+            self.assert_(t == t2 == t3 == test_t,
+                         "'%s'  =>  %s, %s, %s (%s)" % (s, t, t2, t3, test_t))
+
+    def test_http2time_garbage(self):
+        from cookielib import http2time
+
+        for test in [
+            '',
+            'Garbage',
+            'Mandag 16. September 1996',
+            '01-00-1980',
+            '01-13-1980',
+            '00-01-1980',
+            '32-01-1980',
+            '01-01-1980 25:00:00',
+            '01-01-1980 00:61:00',
+            '01-01-1980 00:00:62',
+            ]:
+            self.assert_(http2time(test) is None,
+                         "http2time(%s) is not None\n"
+                         "http2time(test) %s" % (test, http2time(test))
+                         )
+
+
+class HeaderTests(TestCase):
+    def test_parse_ns_headers(self):
+        from cookielib import parse_ns_headers
+
+        # quotes should be stripped
+        expected = [[('foo', 'bar'), ('expires', 2209069412L), ('version', '0')]]
+        for hdr in [
+            'foo=bar; expires=01 Jan 2040 22:23:32 GMT',
+            'foo=bar; expires="01 Jan 2040 22:23:32 GMT"',
+            ]:
+            self.assertEquals(parse_ns_headers([hdr]), expected)
+
+    def test_parse_ns_headers_special_names(self):
+        # names such as 'expires' are not special in first name=value pair
+        # of Set-Cookie: header
+        from cookielib import parse_ns_headers
+
+        # Cookie with name 'expires'
+        hdr = 'expires=01 Jan 2040 22:23:32 GMT'
+        expected = [[("expires", "01 Jan 2040 22:23:32 GMT"), ("version", "0")]]
+        self.assertEquals(parse_ns_headers([hdr]), expected)
+
+    def test_join_header_words(self):
+        from cookielib import join_header_words
+
+        joined = join_header_words([[("foo", None), ("bar", "baz")]])
+        self.assertEquals(joined, "foo; bar=baz")
+
+        self.assertEquals(join_header_words([[]]), "")
+
+    def test_split_header_words(self):
+        from cookielib import split_header_words
+
+        tests = [
+            ("foo", [[("foo", None)]]),
+            ("foo=bar", [[("foo", "bar")]]),
+            ("   foo   ", [[("foo", None)]]),
+            ("   foo=   ", [[("foo", "")]]),
+            ("   foo=", [[("foo", "")]]),
+            ("   foo=   ; ", [[("foo", "")]]),
+            ("   foo=   ; bar= baz ", [[("foo", ""), ("bar", "baz")]]),
+            ("foo=bar bar=baz", [[("foo", "bar"), ("bar", "baz")]]),
+            # doesn't really matter if this next fails, but it works ATM
+            ("foo= bar=baz", [[("foo", "bar=baz")]]),
+            ("foo=bar;bar=baz", [[("foo", "bar"), ("bar", "baz")]]),
+            ('foo bar baz', [[("foo", None), ("bar", None), ("baz", None)]]),
+            ("a, b, c", [[("a", None)], [("b", None)], [("c", None)]]),
+            (r'foo; bar=baz, spam=, foo="\,\;\"", bar= ',
+             [[("foo", None), ("bar", "baz")],
+              [("spam", "")], [("foo", ',;"')], [("bar", "")]]),
+            ]
+
+        for arg, expect in tests:
+            try:
+                result = split_header_words([arg])
+            except:
+                import traceback, StringIO
+                f = StringIO.StringIO()
+                traceback.print_exc(None, f)
+                result = "(error -- traceback follows)\n\n%s" % f.getvalue()
+            self.assertEquals(result,  expect, """
+When parsing: '%s'
+Expected:     '%s'
+Got:          '%s'
+""" % (arg, expect, result))
+
+    def test_roundtrip(self):
+        from cookielib import split_header_words, join_header_words
+
+        tests = [
+            ("foo", "foo"),
+            ("foo=bar", "foo=bar"),
+            ("   foo   ", "foo"),
+            ("foo=", 'foo=""'),
+            ("foo=bar bar=baz", "foo=bar; bar=baz"),
+            ("foo=bar;bar=baz", "foo=bar; bar=baz"),
+            ('foo bar baz', "foo; bar; baz"),
+            (r'foo="\"" bar="\\"', r'foo="\""; bar="\\"'),
+            ('foo,,,bar', 'foo, bar'),
+            ('foo=bar,bar=baz', 'foo=bar, bar=baz'),
+
+            ('text/html; charset=iso-8859-1',
+             'text/html; charset="iso-8859-1"'),
+
+            ('foo="bar"; port="80,81"; discard, bar=baz',
+             'foo=bar; port="80,81"; discard, bar=baz'),
+
+            (r'Basic realm="\"foo\\\\bar\""',
+             r'Basic; realm="\"foo\\\\bar\""')
+            ]
+
+        for arg, expect in tests:
+            input = split_header_words([arg])
+            res = join_header_words(input)
+            self.assertEquals(res, expect, """
+When parsing: '%s'
+Expected:     '%s'
+Got:          '%s'
+Input was:    '%s'
+""" % (arg, expect, res, input))
+
+
+class FakeResponse:
+    def __init__(self, headers=[], url=None):
+        """
+        headers: list of RFC822-style 'Key: value' strings
+        """
+        import mimetools, StringIO
+        f = StringIO.StringIO("\n".join(headers))
+        self._headers = mimetools.Message(f)
+        self._url = url
+    def info(self): return self._headers
+
+def interact_2965(cookiejar, url, *set_cookie_hdrs):
+    return _interact(cookiejar, url, set_cookie_hdrs, "Set-Cookie2")
+
+def interact_netscape(cookiejar, url, *set_cookie_hdrs):
+    return _interact(cookiejar, url, set_cookie_hdrs, "Set-Cookie")
+
+def _interact(cookiejar, url, set_cookie_hdrs, hdr_name):
+    """Perform a single request / response cycle, returning Cookie: header."""
+    from urllib2 import Request
+    req = Request(url)
+    cookiejar.add_cookie_header(req)
+    cookie_hdr = req.get_header("Cookie", "")
+    headers = []
+    for hdr in set_cookie_hdrs:
+        headers.append("%s: %s" % (hdr_name, hdr))
+    res = FakeResponse(headers, url)
+    cookiejar.extract_cookies(res, req)
+    return cookie_hdr
+
+
+class FileCookieJarTests(TestCase):
+    def test_lwp_valueless_cookie(self):
+        # cookies with no value should be saved and loaded consistently
+        from cookielib import LWPCookieJar
+        filename = test_support.TESTFN
+        c = LWPCookieJar()
+        interact_netscape(c, "http://www.acme.com/", 'boo')
+        self.assertEqual(c._cookies["www.acme.com"]["/"]["boo"].value, None)
+        try:
+            c.save(filename, ignore_discard=True)
+            c = LWPCookieJar()
+            c.load(filename, ignore_discard=True)
+        finally:
+            try: os.unlink(filename)
+            except OSError: pass
+        self.assertEqual(c._cookies["www.acme.com"]["/"]["boo"].value, None)
+
+    def test_bad_magic(self):
+        from cookielib import LWPCookieJar, MozillaCookieJar, LoadError
+        # IOErrors (eg. file doesn't exist) are allowed to propagate
+        filename = test_support.TESTFN
+        for cookiejar_class in LWPCookieJar, MozillaCookieJar:
+            c = cookiejar_class()
+            try:
+                c.load(filename="for this test to work, a file with this "
+                                "filename should not exist")
+            except IOError, exc:
+                # exactly IOError, not LoadError
+                self.assertEqual(exc.__class__, IOError)
+            else:
+                self.fail("expected IOError for invalid filename")
+        # Invalid contents of cookies file (eg. bad magic string)
+        # causes a LoadError.
+        try:
+            f = open(filename, "w")
+            f.write("oops\n")
+            for cookiejar_class in LWPCookieJar, MozillaCookieJar:
+                c = cookiejar_class()
+                self.assertRaises(LoadError, c.load, filename)
+        finally:
+            try: os.unlink(filename)
+            except OSError: pass
+
+class CookieTests(TestCase):
+    # XXX
+    # Get rid of string comparisons where not actually testing str / repr.
+    # .clear() etc.
+    # IP addresses like 50 (single number, no dot) and domain-matching
+    #  functions (and is_HDN)?  See draft RFC 2965 errata.
+    # Strictness switches
+    # is_third_party()
+    # unverifiability / third-party blocking
+    # Netscape cookies work the same as RFC 2965 with regard to port.
+    # Set-Cookie with negative max age.
+    # If turn RFC 2965 handling off, Set-Cookie2 cookies should not clobber
+    #  Set-Cookie cookies.
+    # Cookie2 should be sent if *any* cookies are not V1 (ie. V0 OR V2 etc.).
+    # Cookies (V1 and V0) with no expiry date should be set to be discarded.
+    # RFC 2965 Quoting:
+    #  Should accept unquoted cookie-attribute values?  check errata draft.
+    #   Which are required on the way in and out?
+    #  Should always return quoted cookie-attribute values?
+    # Proper testing of when RFC 2965 clobbers Netscape (waiting for errata).
+    # Path-match on return (same for V0 and V1).
+    # RFC 2965 acceptance and returning rules
+    #  Set-Cookie2 without version attribute is rejected.
+
+    # Netscape peculiarities list from Ronald Tschalar.
+    # The first two still need tests, the rest are covered.
+## - Quoting: only quotes around the expires value are recognized as such
+##   (and yes, some folks quote the expires value); quotes around any other
+##   value are treated as part of the value.
+## - White space: white space around names and values is ignored
+## - Default path: if no path parameter is given, the path defaults to the
+##   path in the request-uri up to, but not including, the last '/'. Note
+##   that this is entirely different from what the spec says.
+## - Commas and other delimiters: Netscape just parses until the next ';'.
+##   This means it will allow commas etc inside values (and yes, both
+##   commas and equals are commonly appear in the cookie value). This also
+##   means that if you fold multiple Set-Cookie header fields into one,
+##   comma-separated list, it'll be a headache to parse (at least my head
+##   starts hurting everytime I think of that code).
+## - Expires: You'll get all sorts of date formats in the expires,
+##   including emtpy expires attributes ("expires="). Be as flexible as you
+##   can, and certainly don't expect the weekday to be there; if you can't
+##   parse it, just ignore it and pretend it's a session cookie.
+## - Domain-matching: Netscape uses the 2-dot rule for _all_ domains, not
+##   just the 7 special TLD's listed in their spec. And folks rely on
+##   that...
+
+    def test_domain_return_ok(self):
+        # test optimization: .domain_return_ok() should filter out most
+        # domains in the CookieJar before we try to access them (because that
+        # may require disk access -- in particular, with MSIECookieJar)
+        # This is only a rough check for performance reasons, so it's not too
+        # critical as long as it's sufficiently liberal.
+        import cookielib, urllib2
+        pol = cookielib.DefaultCookiePolicy()
+        for url, domain, ok in [
+            ("http://foo.bar.com/", "blah.com", False),
+            ("http://foo.bar.com/", "rhubarb.blah.com", False),
+            ("http://foo.bar.com/", "rhubarb.foo.bar.com", False),
+            ("http://foo.bar.com/", ".foo.bar.com", True),
+            ("http://foo.bar.com/", "foo.bar.com", True),
+            ("http://foo.bar.com/", ".bar.com", True),
+            ("http://foo.bar.com/", "com", True),
+            ("http://foo.com/", "rhubarb.foo.com", False),
+            ("http://foo.com/", ".foo.com", True),
+            ("http://foo.com/", "foo.com", True),
+            ("http://foo.com/", "com", True),
+            ("http://foo/", "rhubarb.foo", False),
+            ("http://foo/", ".foo", True),
+            ("http://foo/", "foo", True),
+            ("http://foo/", "foo.local", True),
+            ("http://foo/", ".local", True),
+            ]:
+            request = urllib2.Request(url)
+            r = pol.domain_return_ok(domain, request)
+            if ok: self.assert_(r)
+            else: self.assert_(not r)
+
+    def test_missing_value(self):
+        from cookielib import MozillaCookieJar, lwp_cookie_str
+
+        # missing = sign in Cookie: header is regarded by Mozilla as a missing
+        # name, and by cookielib as a missing value
+        filename = test_support.TESTFN
+        c = MozillaCookieJar(filename)
+        interact_netscape(c, "http://www.acme.com/", 'eggs')
+        interact_netscape(c, "http://www.acme.com/", '"spam"; path=/foo/')
+        cookie = c._cookies["www.acme.com"]["/"]["eggs"]
+        self.assert_(cookie.value is None)
+        self.assertEquals(cookie.name, "eggs")
+        cookie = c._cookies["www.acme.com"]['/foo/']['"spam"']
+        self.assert_(cookie.value is None)
+        self.assertEquals(cookie.name, '"spam"')
+        self.assertEquals(lwp_cookie_str(cookie), (
+            r'"spam"; path="/foo/"; domain="www.acme.com"; '
+            'path_spec; discard; version=0'))
+        old_str = repr(c)
+        c.save(ignore_expires=True, ignore_discard=True)
+        try:
+            c = MozillaCookieJar(filename)
+            c.revert(ignore_expires=True, ignore_discard=True)
+        finally:
+            os.unlink(c.filename)
+        # cookies unchanged apart from lost info re. whether path was specified
+        self.assertEquals(
+            repr(c),
+            re.sub("path_specified=%s" % True, "path_specified=%s" % False,
+                   old_str)
+            )
+        self.assertEquals(interact_netscape(c, "http://www.acme.com/foo/"),
+                          '"spam"; eggs')
+
+    def test_rfc2109_handling(self):
+        # RFC 2109 cookies are handled as RFC 2965 or Netscape cookies,
+        # dependent on policy settings
+        from cookielib import CookieJar, DefaultCookiePolicy
+
+        for rfc2109_as_netscape, rfc2965, version in [
+            # default according to rfc2965 if not explicitly specified
+            (None, False, 0),
+            (None, True, 1),
+            # explicit rfc2109_as_netscape
+            (False, False, None),  # version None here means no cookie stored
+            (False, True, 1),
+            (True, False, 0),
+            (True, True, 0),
+            ]:
+            policy = DefaultCookiePolicy(
+                rfc2109_as_netscape=rfc2109_as_netscape,
+                rfc2965=rfc2965)
+            c = CookieJar(policy)
+            interact_netscape(c, "http://www.example.com/", "ni=ni; Version=1")
+            try:
+                cookie = c._cookies["www.example.com"]["/"]["ni"]
+            except KeyError:
+                self.assert_(version is None)  # didn't expect a stored cookie
+            else:
+                self.assertEqual(cookie.version, version)
+                # 2965 cookies are unaffected
+                interact_2965(c, "http://www.example.com/",
+                              "foo=bar; Version=1")
+                if rfc2965:
+                    cookie2965 = c._cookies["www.example.com"]["/"]["foo"]
+                    self.assertEqual(cookie2965.version, 1)
+
+    def test_ns_parser(self):
+        from cookielib import CookieJar, DEFAULT_HTTP_PORT
+
+        c = CookieJar()
+        interact_netscape(c, "http://www.acme.com/",
+                          'spam=eggs; DoMain=.acme.com; port; blArgh="feep"')
+        interact_netscape(c, "http://www.acme.com/", 'ni=ni; port=80,8080')
+        interact_netscape(c, "http://www.acme.com:80/", 'nini=ni')
+        interact_netscape(c, "http://www.acme.com:80/", 'foo=bar; expires=')
+        interact_netscape(c, "http://www.acme.com:80/", 'spam=eggs; '
+                          'expires="Foo Bar 25 33:22:11 3022"')
+
+        cookie = c._cookies[".acme.com"]["/"]["spam"]
+        self.assertEquals(cookie.domain, ".acme.com")
+        self.assert_(cookie.domain_specified)
+        self.assertEquals(cookie.port, DEFAULT_HTTP_PORT)
+        self.assert_(not cookie.port_specified)
+        # case is preserved
+        self.assert_(cookie.has_nonstandard_attr("blArgh") and
+                     not cookie.has_nonstandard_attr("blargh"))
+
+        cookie = c._cookies["www.acme.com"]["/"]["ni"]
+        self.assertEquals(cookie.domain, "www.acme.com")
+        self.assert_(not cookie.domain_specified)
+        self.assertEquals(cookie.port, "80,8080")
+        self.assert_(cookie.port_specified)
+
+        cookie = c._cookies["www.acme.com"]["/"]["nini"]
+        self.assert_(cookie.port is None)
+        self.assert_(not cookie.port_specified)
+
+        # invalid expires should not cause cookie to be dropped
+        foo = c._cookies["www.acme.com"]["/"]["foo"]
+        spam = c._cookies["www.acme.com"]["/"]["foo"]
+        self.assert_(foo.expires is None)
+        self.assert_(spam.expires is None)
+
+    def test_ns_parser_special_names(self):
+        # names such as 'expires' are not special in first name=value pair
+        # of Set-Cookie: header
+        from cookielib import CookieJar
+
+        c = CookieJar()
+        interact_netscape(c, "http://www.acme.com/", 'expires=eggs')
+        interact_netscape(c, "http://www.acme.com/", 'version=eggs; spam=eggs')
+
+        cookies = c._cookies["www.acme.com"]["/"]
+        self.assert_('expires' in cookies)
+        self.assert_('version' in cookies)
+
+    def test_expires(self):
+        from cookielib import time2netscape, CookieJar
+
+        # if expires is in future, keep cookie...
+        c = CookieJar()
+        future = time2netscape(time.time()+3600)
+        interact_netscape(c, "http://www.acme.com/", 'spam="bar"; expires=%s' %
+                          future)
+        self.assertEquals(len(c), 1)
+        now = time2netscape(time.time()-1)
+        # ... and if in past or present, discard it
+        interact_netscape(c, "http://www.acme.com/", 'foo="eggs"; expires=%s' %
+                          now)
+        h = interact_netscape(c, "http://www.acme.com/")
+        self.assertEquals(len(c), 1)
+        self.assert_('spam="bar"' in h and "foo" not in h)
+
+        # max-age takes precedence over expires, and zero max-age is request to
+        # delete both new cookie and any old matching cookie
+        interact_netscape(c, "http://www.acme.com/", 'eggs="bar"; expires=%s' %
+                          future)
+        interact_netscape(c, "http://www.acme.com/", 'bar="bar"; expires=%s' %
+                          future)
+        self.assertEquals(len(c), 3)
+        interact_netscape(c, "http://www.acme.com/", 'eggs="bar"; '
+                          'expires=%s; max-age=0' % future)
+        interact_netscape(c, "http://www.acme.com/", 'bar="bar"; '
+                          'max-age=0; expires=%s' % future)
+        h = interact_netscape(c, "http://www.acme.com/")
+        self.assertEquals(len(c), 1)
+
+        # test expiry at end of session for cookies with no expires attribute
+        interact_netscape(c, "http://www.rhubarb.net/", 'whum="fizz"')
+        self.assertEquals(len(c), 2)
+        c.clear_session_cookies()
+        self.assertEquals(len(c), 1)
+        self.assert_('spam="bar"' in h)
+
+        # XXX RFC 2965 expiry rules (some apply to V0 too)
+
+    def test_default_path(self):
+        from cookielib import CookieJar, DefaultCookiePolicy
+
+        # RFC 2965
+        pol = DefaultCookiePolicy(rfc2965=True)
+
+        c = CookieJar(pol)
+        interact_2965(c, "http://www.acme.com/", 'spam="bar"; Version="1"')
+        self.assert_("/" in c._cookies["www.acme.com"])
+
+        c = CookieJar(pol)
+        interact_2965(c, "http://www.acme.com/blah", 'eggs="bar"; Version="1"')
+        self.assert_("/" in c._cookies["www.acme.com"])
+
+        c = CookieJar(pol)
+        interact_2965(c, "http://www.acme.com/blah/rhubarb",
+                      'eggs="bar"; Version="1"')
+        self.assert_("/blah/" in c._cookies["www.acme.com"])
+
+        c = CookieJar(pol)
+        interact_2965(c, "http://www.acme.com/blah/rhubarb/",
+                      'eggs="bar"; Version="1"')
+        self.assert_("/blah/rhubarb/" in c._cookies["www.acme.com"])
+
+        # Netscape
+
+        c = CookieJar()
+        interact_netscape(c, "http://www.acme.com/", 'spam="bar"')
+        self.assert_("/" in c._cookies["www.acme.com"])
+
+        c = CookieJar()
+        interact_netscape(c, "http://www.acme.com/blah", 'eggs="bar"')
+        self.assert_("/" in c._cookies["www.acme.com"])
+
+        c = CookieJar()
+        interact_netscape(c, "http://www.acme.com/blah/rhubarb", 'eggs="bar"')
+        self.assert_("/blah" in c._cookies["www.acme.com"])
+
+        c = CookieJar()
+        interact_netscape(c, "http://www.acme.com/blah/rhubarb/", 'eggs="bar"')
+        self.assert_("/blah/rhubarb" in c._cookies["www.acme.com"])
+
+    def test_escape_path(self):
+        from cookielib import escape_path
+        cases = [
+            # quoted safe
+            ("/foo%2f/bar", "/foo%2F/bar"),
+            ("/foo%2F/bar", "/foo%2F/bar"),
+            # quoted %
+            ("/foo%%/bar", "/foo%%/bar"),
+            # quoted unsafe
+            ("/fo%19o/bar", "/fo%19o/bar"),
+            ("/fo%7do/bar", "/fo%7Do/bar"),
+            # unquoted safe
+            ("/foo/bar&", "/foo/bar&"),
+            ("/foo//bar", "/foo//bar"),
+            ("\176/foo/bar", "\176/foo/bar"),
+            # unquoted unsafe
+            ("/foo\031/bar", "/foo%19/bar"),
+            ("/\175foo/bar", "/%7Dfoo/bar"),
+            # unicode
+            (u"/foo/bar\uabcd", "/foo/bar%EA%AF%8D"),  # UTF-8 encoded
+            ]
+        for arg, result in cases:
+            self.assertEquals(escape_path(arg), result)
+
+    def test_request_path(self):
+        from urllib2 import Request
+        from cookielib import request_path
+        # with parameters
+        req = Request("http://www.example.com/rheum/rhaponicum;"
+                      "foo=bar;sing=song?apples=pears&spam=eggs#ni")
+        self.assertEquals(request_path(req), "/rheum/rhaponicum;"
+                     "foo=bar;sing=song?apples=pears&spam=eggs#ni")
+        # without parameters
+        req = Request("http://www.example.com/rheum/rhaponicum?"
+                      "apples=pears&spam=eggs#ni")
+        self.assertEquals(request_path(req), "/rheum/rhaponicum?"
+                     "apples=pears&spam=eggs#ni")
+        # missing final slash
+        req = Request("http://www.example.com")
+        self.assertEquals(request_path(req), "/")
+
+    def test_request_port(self):
+        from urllib2 import Request
+        from cookielib import request_port, DEFAULT_HTTP_PORT
+        req = Request("http://www.acme.com:1234/",
+                      headers={"Host": "www.acme.com:4321"})
+        self.assertEquals(request_port(req), "1234")
+        req = Request("http://www.acme.com/",
+                      headers={"Host": "www.acme.com:4321"})
+        self.assertEquals(request_port(req), DEFAULT_HTTP_PORT)
+
+    def test_request_host(self):
+        from urllib2 import Request
+        from cookielib import request_host
+        # this request is illegal (RFC2616, 14.2.3)
+        req = Request("http://1.1.1.1/",
+                      headers={"Host": "www.acme.com:80"})
+        # libwww-perl wants this response, but that seems wrong (RFC 2616,
+        # section 5.2, point 1., and RFC 2965 section 1, paragraph 3)
+        #self.assertEquals(request_host(req), "www.acme.com")
+        self.assertEquals(request_host(req), "1.1.1.1")
+        req = Request("http://www.acme.com/",
+                      headers={"Host": "irrelevant.com"})
+        self.assertEquals(request_host(req), "www.acme.com")
+        # not actually sure this one is valid Request object, so maybe should
+        # remove test for no host in url in request_host function?
+        req = Request("/resource.html",
+                      headers={"Host": "www.acme.com"})
+        self.assertEquals(request_host(req), "www.acme.com")
+        # port shouldn't be in request-host
+        req = Request("http://www.acme.com:2345/resource.html",
+                      headers={"Host": "www.acme.com:5432"})
+        self.assertEquals(request_host(req), "www.acme.com")
+
+    def test_is_HDN(self):
+        from cookielib import is_HDN
+        self.assert_(is_HDN("foo.bar.com"))
+        self.assert_(is_HDN("1foo2.3bar4.5com"))
+        self.assert_(not is_HDN("192.168.1.1"))
+        self.assert_(not is_HDN(""))
+        self.assert_(not is_HDN("."))
+        self.assert_(not is_HDN(".foo.bar.com"))
+        self.assert_(not is_HDN("..foo"))
+        self.assert_(not is_HDN("foo."))
+
+    def test_reach(self):
+        from cookielib import reach
+        self.assertEquals(reach("www.acme.com"), ".acme.com")
+        self.assertEquals(reach("acme.com"), "acme.com")
+        self.assertEquals(reach("acme.local"), ".local")
+        self.assertEquals(reach(".local"), ".local")
+        self.assertEquals(reach(".com"), ".com")
+        self.assertEquals(reach("."), ".")
+        self.assertEquals(reach(""), "")
+        self.assertEquals(reach("192.168.0.1"), "192.168.0.1")
+
+    def test_domain_match(self):
+        from cookielib import domain_match, user_domain_match
+        self.assert_(domain_match("192.168.1.1", "192.168.1.1"))
+        self.assert_(not domain_match("192.168.1.1", ".168.1.1"))
+        self.assert_(domain_match("x.y.com", "x.Y.com"))
+        self.assert_(domain_match("x.y.com", ".Y.com"))
+        self.assert_(not domain_match("x.y.com", "Y.com"))
+        self.assert_(domain_match("a.b.c.com", ".c.com"))
+        self.assert_(not domain_match(".c.com", "a.b.c.com"))
+        self.assert_(domain_match("example.local", ".local"))
+        self.assert_(not domain_match("blah.blah", ""))
+        self.assert_(not domain_match("", ".rhubarb.rhubarb"))
+        self.assert_(domain_match("", ""))
+
+        self.assert_(user_domain_match("acme.com", "acme.com"))
+        self.assert_(not user_domain_match("acme.com", ".acme.com"))
+        self.assert_(user_domain_match("rhubarb.acme.com", ".acme.com"))
+        self.assert_(user_domain_match("www.rhubarb.acme.com", ".acme.com"))
+        self.assert_(user_domain_match("x.y.com", "x.Y.com"))
+        self.assert_(user_domain_match("x.y.com", ".Y.com"))
+        self.assert_(not user_domain_match("x.y.com", "Y.com"))
+        self.assert_(user_domain_match("y.com", "Y.com"))
+        self.assert_(not user_domain_match(".y.com", "Y.com"))
+        self.assert_(user_domain_match(".y.com", ".Y.com"))
+        self.assert_(user_domain_match("x.y.com", ".com"))
+        self.assert_(not user_domain_match("x.y.com", "com"))
+        self.assert_(not user_domain_match("x.y.com", "m"))
+        self.assert_(not user_domain_match("x.y.com", ".m"))
+        self.assert_(not user_domain_match("x.y.com", ""))
+        self.assert_(not user_domain_match("x.y.com", "."))
+        self.assert_(user_domain_match("192.168.1.1", "192.168.1.1"))
+        # not both HDNs, so must string-compare equal to match
+        self.assert_(not user_domain_match("192.168.1.1", ".168.1.1"))
+        self.assert_(not user_domain_match("192.168.1.1", "."))
+        # empty string is a special case
+        self.assert_(not user_domain_match("192.168.1.1", ""))
+
+    def test_wrong_domain(self):
+        # Cookies whose effective request-host name does not domain-match the
+        # domain are rejected.
+
+        # XXX far from complete
+        from cookielib import CookieJar
+        c = CookieJar()
+        interact_2965(c, "http://www.nasty.com/",
+                      'foo=bar; domain=friendly.org; Version="1"')
+        self.assertEquals(len(c), 0)
+
+    def test_strict_domain(self):
+        # Cookies whose domain is a country-code tld like .co.uk should
+        # not be set if CookiePolicy.strict_domain is true.
+        from cookielib import CookieJar, DefaultCookiePolicy
+
+        cp = DefaultCookiePolicy(strict_domain=True)
+        cj = CookieJar(policy=cp)
+        interact_netscape(cj, "http://example.co.uk/", 'no=problemo')
+        interact_netscape(cj, "http://example.co.uk/",
+                          'okey=dokey; Domain=.example.co.uk')
+        self.assertEquals(len(cj), 2)
+        for pseudo_tld in [".co.uk", ".org.za", ".tx.us", ".name.us"]:
+            interact_netscape(cj, "http://example.%s/" % pseudo_tld,
+                              'spam=eggs; Domain=.co.uk')
+            self.assertEquals(len(cj), 2)
+
+    def test_two_component_domain_ns(self):
+        # Netscape: .www.bar.com, www.bar.com, .bar.com, bar.com, no domain
+        # should all get accepted, as should .acme.com, acme.com and no domain
+        # for 2-component domains like acme.com.
+        from cookielib import CookieJar, DefaultCookiePolicy
+
+        c = CookieJar()
+
+        # two-component V0 domain is OK
+        interact_netscape(c, "http://foo.net/", 'ns=bar')
+        self.assertEquals(len(c), 1)
+        self.assertEquals(c._cookies["foo.net"]["/"]["ns"].value, "bar")
+        self.assertEquals(interact_netscape(c, "http://foo.net/"), "ns=bar")
+        # *will* be returned to any other domain (unlike RFC 2965)...
+        self.assertEquals(interact_netscape(c, "http://www.foo.net/"),
+                          "ns=bar")
+        # ...unless requested otherwise
+        pol = DefaultCookiePolicy(
+            strict_ns_domain=DefaultCookiePolicy.DomainStrictNonDomain)
+        c.set_policy(pol)
+        self.assertEquals(interact_netscape(c, "http://www.foo.net/"), "")
+
+        # unlike RFC 2965, even explicit two-component domain is OK,
+        # because .foo.net matches foo.net
+        interact_netscape(c, "http://foo.net/foo/",
+                          'spam1=eggs; domain=foo.net')
+        # even if starts with a dot -- in NS rules, .foo.net matches foo.net!
+        interact_netscape(c, "http://foo.net/foo/bar/",
+                          'spam2=eggs; domain=.foo.net')
+        self.assertEquals(len(c), 3)
+        self.assertEquals(c._cookies[".foo.net"]["/foo"]["spam1"].value,
+                          "eggs")
+        self.assertEquals(c._cookies[".foo.net"]["/foo/bar"]["spam2"].value,
+                          "eggs")
+        self.assertEquals(interact_netscape(c, "http://foo.net/foo/bar/"),
+                          "spam2=eggs; spam1=eggs; ns=bar")
+
+        # top-level domain is too general
+        interact_netscape(c, "http://foo.net/", 'nini="ni"; domain=.net')
+        self.assertEquals(len(c), 3)
+
+##         # Netscape protocol doesn't allow non-special top level domains (such
+##         # as co.uk) in the domain attribute unless there are at least three
+##         # dots in it.
+        # Oh yes it does!  Real implementations don't check this, and real
+        # cookies (of course) rely on that behaviour.
+        interact_netscape(c, "http://foo.co.uk", 'nasty=trick; domain=.co.uk')
+##         self.assertEquals(len(c), 2)
+        self.assertEquals(len(c), 4)
+
+    def test_two_component_domain_rfc2965(self):
+        from cookielib import CookieJar, DefaultCookiePolicy
+
+        pol = DefaultCookiePolicy(rfc2965=True)
+        c = CookieJar(pol)
+
+        # two-component V1 domain is OK
+        interact_2965(c, "http://foo.net/", 'foo=bar; Version="1"')
+        self.assertEquals(len(c), 1)
+        self.assertEquals(c._cookies["foo.net"]["/"]["foo"].value, "bar")
+        self.assertEquals(interact_2965(c, "http://foo.net/"),
+                          "$Version=1; foo=bar")
+        # won't be returned to any other domain (because domain was implied)
+        self.assertEquals(interact_2965(c, "http://www.foo.net/"), "")
+
+        # unless domain is given explicitly, because then it must be
+        # rewritten to start with a dot: foo.net --> .foo.net, which does
+        # not domain-match foo.net
+        interact_2965(c, "http://foo.net/foo",
+                      'spam=eggs; domain=foo.net; path=/foo; Version="1"')
+        self.assertEquals(len(c), 1)
+        self.assertEquals(interact_2965(c, "http://foo.net/foo"),
+                          "$Version=1; foo=bar")
+
+        # explicit foo.net from three-component domain www.foo.net *does* get
+        # set, because .foo.net domain-matches .foo.net
+        interact_2965(c, "http://www.foo.net/foo/",
+                      'spam=eggs; domain=foo.net; Version="1"')
+        self.assertEquals(c._cookies[".foo.net"]["/foo/"]["spam"].value,
+                          "eggs")
+        self.assertEquals(len(c), 2)
+        self.assertEquals(interact_2965(c, "http://foo.net/foo/"),
+                          "$Version=1; foo=bar")
+        self.assertEquals(interact_2965(c, "http://www.foo.net/foo/"),
+                          '$Version=1; spam=eggs; $Domain="foo.net"')
+
+        # top-level domain is too general
+        interact_2965(c, "http://foo.net/",
+                      'ni="ni"; domain=".net"; Version="1"')
+        self.assertEquals(len(c), 2)
+
+        # RFC 2965 doesn't require blocking this
+        interact_2965(c, "http://foo.co.uk/",
+                      'nasty=trick; domain=.co.uk; Version="1"')
+        self.assertEquals(len(c), 3)
+
+    def test_domain_allow(self):
+        from cookielib import CookieJar, DefaultCookiePolicy
+        from urllib2 import Request
+
+        c = CookieJar(policy=DefaultCookiePolicy(
+            blocked_domains=["acme.com"],
+            allowed_domains=["www.acme.com"]))
+
+        req = Request("http://acme.com/")
+        headers = ["Set-Cookie: CUSTOMER=WILE_E_COYOTE; path=/"]
+        res = FakeResponse(headers, "http://acme.com/")
+        c.extract_cookies(res, req)
+        self.assertEquals(len(c), 0)
+
+        req = Request("http://www.acme.com/")
+        res = FakeResponse(headers, "http://www.acme.com/")
+        c.extract_cookies(res, req)
+        self.assertEquals(len(c), 1)
+
+        req = Request("http://www.coyote.com/")
+        res = FakeResponse(headers, "http://www.coyote.com/")
+        c.extract_cookies(res, req)
+        self.assertEquals(len(c), 1)
+
+        # set a cookie with non-allowed domain...
+        req = Request("http://www.coyote.com/")
+        res = FakeResponse(headers, "http://www.coyote.com/")
+        cookies = c.make_cookies(res, req)
+        c.set_cookie(cookies[0])
+        self.assertEquals(len(c), 2)
+        # ... and check is doesn't get returned
+        c.add_cookie_header(req)
+        self.assert_(not req.has_header("Cookie"))
+
+    def test_domain_block(self):
+        from cookielib import CookieJar, DefaultCookiePolicy
+        from urllib2 import Request
+
+        pol = DefaultCookiePolicy(
+            rfc2965=True, blocked_domains=[".acme.com"])
+        c = CookieJar(policy=pol)
+        headers = ["Set-Cookie: CUSTOMER=WILE_E_COYOTE; path=/"]
+
+        req = Request("http://www.acme.com/")
+        res = FakeResponse(headers, "http://www.acme.com/")
+        c.extract_cookies(res, req)
+        self.assertEquals(len(c), 0)
+
+        p = pol.set_blocked_domains(["acme.com"])
+        c.extract_cookies(res, req)
+        self.assertEquals(len(c), 1)
+
+        c.clear()
+        req = Request("http://www.roadrunner.net/")
+        res = FakeResponse(headers, "http://www.roadrunner.net/")
+        c.extract_cookies(res, req)
+        self.assertEquals(len(c), 1)
+        req = Request("http://www.roadrunner.net/")
+        c.add_cookie_header(req)
+        self.assert_((req.has_header("Cookie") and
+                      req.has_header("Cookie2")))
+
+        c.clear()
+        pol.set_blocked_domains([".acme.com"])
+        c.extract_cookies(res, req)
+        self.assertEquals(len(c), 1)
+
+        # set a cookie with blocked domain...
+        req = Request("http://www.acme.com/")
+        res = FakeResponse(headers, "http://www.acme.com/")
+        cookies = c.make_cookies(res, req)
+        c.set_cookie(cookies[0])
+        self.assertEquals(len(c), 2)
+        # ... and check is doesn't get returned
+        c.add_cookie_header(req)
+        self.assert_(not req.has_header("Cookie"))
+
+    def test_secure(self):
+        from cookielib import CookieJar, DefaultCookiePolicy
+
+        for ns in True, False:
+            for whitespace in " ", "":
+                c = CookieJar()
+                if ns:
+                    pol = DefaultCookiePolicy(rfc2965=False)
+                    int = interact_netscape
+                    vs = ""
+                else:
+                    pol = DefaultCookiePolicy(rfc2965=True)
+                    int = interact_2965
+                    vs = "; Version=1"
+                c.set_policy(pol)
+                url = "http://www.acme.com/"
+                int(c, url, "foo1=bar%s%s" % (vs, whitespace))
+                int(c, url, "foo2=bar%s; secure%s" %  (vs, whitespace))
+                self.assert_(
+                    not c._cookies["www.acme.com"]["/"]["foo1"].secure,
+                    "non-secure cookie registered secure")
+                self.assert_(
+                    c._cookies["www.acme.com"]["/"]["foo2"].secure,
+                    "secure cookie registered non-secure")
+
+    def test_quote_cookie_value(self):
+        from cookielib import CookieJar, DefaultCookiePolicy
+        c = CookieJar(policy=DefaultCookiePolicy(rfc2965=True))
+        interact_2965(c, "http://www.acme.com/", r'foo=\b"a"r; Version=1')
+        h = interact_2965(c, "http://www.acme.com/")
+        self.assertEquals(h, r'$Version=1; foo=\\b\"a\"r')
+
+    def test_missing_final_slash(self):
+        # Missing slash from request URL's abs_path should be assumed present.
+        from cookielib import CookieJar, DefaultCookiePolicy
+        from urllib2 import Request
+        url = "http://www.acme.com"
+        c = CookieJar(DefaultCookiePolicy(rfc2965=True))
+        interact_2965(c, url, "foo=bar; Version=1")
+        req = Request(url)
+        self.assertEquals(len(c), 1)
+        c.add_cookie_header(req)
+        self.assert_(req.has_header("Cookie"))
+
+    def test_domain_mirror(self):
+        from cookielib import CookieJar, DefaultCookiePolicy
+
+        pol = DefaultCookiePolicy(rfc2965=True)
+
+        c = CookieJar(pol)
+        url = "http://foo.bar.com/"
+        interact_2965(c, url, "spam=eggs; Version=1")
+        h = interact_2965(c, url)
+        self.assert_("Domain" not in h,
+                     "absent domain returned with domain present")
+
+        c = CookieJar(pol)
+        url = "http://foo.bar.com/"
+        interact_2965(c, url, 'spam=eggs; Version=1; Domain=.bar.com')
+        h = interact_2965(c, url)
+        self.assert_('$Domain=".bar.com"' in h, "domain not returned")
+
+        c = CookieJar(pol)
+        url = "http://foo.bar.com/"
+        # note missing initial dot in Domain
+        interact_2965(c, url, 'spam=eggs; Version=1; Domain=bar.com')
+        h = interact_2965(c, url)
+        self.assert_('$Domain="bar.com"' in h, "domain not returned")
+
+    def test_path_mirror(self):
+        from cookielib import CookieJar, DefaultCookiePolicy
+
+        pol = DefaultCookiePolicy(rfc2965=True)
+
+        c = CookieJar(pol)
+        url = "http://foo.bar.com/"
+        interact_2965(c, url, "spam=eggs; Version=1")
+        h = interact_2965(c, url)
+        self.assert_("Path" not in h,
+                     "absent path returned with path present")
+
+        c = CookieJar(pol)
+        url = "http://foo.bar.com/"
+        interact_2965(c, url, 'spam=eggs; Version=1; Path=/')
+        h = interact_2965(c, url)
+        self.assert_('$Path="/"' in h, "path not returned")
+
+    def test_port_mirror(self):
+        from cookielib import CookieJar, DefaultCookiePolicy
+
+        pol = DefaultCookiePolicy(rfc2965=True)
+
+        c = CookieJar(pol)
+        url = "http://foo.bar.com/"
+        interact_2965(c, url, "spam=eggs; Version=1")
+        h = interact_2965(c, url)
+        self.assert_("Port" not in h,
+                     "absent port returned with port present")
+
+        c = CookieJar(pol)
+        url = "http://foo.bar.com/"
+        interact_2965(c, url, "spam=eggs; Version=1; Port")
+        h = interact_2965(c, url)
+        self.assert_(re.search("\$Port([^=]|$)", h),
+                     "port with no value not returned with no value")
+
+        c = CookieJar(pol)
+        url = "http://foo.bar.com/"
+        interact_2965(c, url, 'spam=eggs; Version=1; Port="80"')
+        h = interact_2965(c, url)
+        self.assert_('$Port="80"' in h,
+                     "port with single value not returned with single value")
+
+        c = CookieJar(pol)
+        url = "http://foo.bar.com/"
+        interact_2965(c, url, 'spam=eggs; Version=1; Port="80,8080"')
+        h = interact_2965(c, url)
+        self.assert_('$Port="80,8080"' in h,
+                     "port with multiple values not returned with multiple "
+                     "values")
+
+    def test_no_return_comment(self):
+        from cookielib import CookieJar, DefaultCookiePolicy
+
+        c = CookieJar(DefaultCookiePolicy(rfc2965=True))
+        url = "http://foo.bar.com/"
+        interact_2965(c, url, 'spam=eggs; Version=1; '
+                      'Comment="does anybody read these?"; '
+                      'CommentURL="http://foo.bar.net/comment.html"')
+        h = interact_2965(c, url)
+        self.assert_(
+            "Comment" not in h,
+            "Comment or CommentURL cookie-attributes returned to server")
+
+    def test_Cookie_iterator(self):
+        from cookielib import CookieJar, Cookie, DefaultCookiePolicy
+
+        cs = CookieJar(DefaultCookiePolicy(rfc2965=True))
+        # add some random cookies
+        interact_2965(cs, "http://blah.spam.org/", 'foo=eggs; Version=1; '
+                      'Comment="does anybody read these?"; '
+                      'CommentURL="http://foo.bar.net/comment.html"')
+        interact_netscape(cs, "http://www.acme.com/blah/", "spam=bar; secure")
+        interact_2965(cs, "http://www.acme.com/blah/",
+                      "foo=bar; secure; Version=1")
+        interact_2965(cs, "http://www.acme.com/blah/",
+                      "foo=bar; path=/; Version=1")
+        interact_2965(cs, "http://www.sol.no",
+                      r'bang=wallop; version=1; domain=".sol.no"; '
+                      r'port="90,100, 80,8080"; '
+                      r'max-age=100; Comment = "Just kidding! (\"|\\\\) "')
+
+        versions = [1, 1, 1, 0, 1]
+        names = ["bang", "foo", "foo", "spam", "foo"]
+        domains = [".sol.no", "blah.spam.org", "www.acme.com",
+                   "www.acme.com", "www.acme.com"]
+        paths = ["/", "/", "/", "/blah", "/blah/"]
+
+        for i in range(4):
+            i = 0
+            for c in cs:
+                self.assert_(isinstance(c, Cookie))
+                self.assertEquals(c.version, versions[i])
+                self.assertEquals(c.name, names[i])
+                self.assertEquals(c.domain, domains[i])
+                self.assertEquals(c.path, paths[i])
+                i = i + 1
+
+    def test_parse_ns_headers(self):
+        from cookielib import parse_ns_headers
+
+        # missing domain value (invalid cookie)
+        self.assertEquals(
+            parse_ns_headers(["foo=bar; path=/; domain"]),
+            [[("foo", "bar"),
+              ("path", "/"), ("domain", None), ("version", "0")]]
+            )
+        # invalid expires value
+        self.assertEquals(
+            parse_ns_headers(["foo=bar; expires=Foo Bar 12 33:22:11 2000"]),
+            [[("foo", "bar"), ("expires", None), ("version", "0")]]
+            )
+        # missing cookie value (valid cookie)
+        self.assertEquals(
+            parse_ns_headers(["foo"]),
+            [[("foo", None), ("version", "0")]]
+            )
+        # shouldn't add version if header is empty
+        self.assertEquals(parse_ns_headers([""]), [])
+
+    def test_bad_cookie_header(self):
+
+        def cookiejar_from_cookie_headers(headers):
+            from cookielib import CookieJar
+            from urllib2 import Request
+            c = CookieJar()
+            req = Request("http://www.example.com/")
+            r = FakeResponse(headers, "http://www.example.com/")
+            c.extract_cookies(r, req)
+            return c
+
+        # none of these bad headers should cause an exception to be raised
+        for headers in [
+            ["Set-Cookie: "],  # actually, nothing wrong with this
+            ["Set-Cookie2: "],  # ditto
+            # missing domain value
+            ["Set-Cookie2: a=foo; path=/; Version=1; domain"],
+            # bad max-age
+            ["Set-Cookie: b=foo; max-age=oops"],
+            ]:
+            c = cookiejar_from_cookie_headers(headers)
+            # these bad cookies shouldn't be set
+            self.assertEquals(len(c), 0)
+
+        # cookie with invalid expires is treated as session cookie
+        headers = ["Set-Cookie: c=foo; expires=Foo Bar 12 33:22:11 2000"]
+        c = cookiejar_from_cookie_headers(headers)
+        cookie = c._cookies["www.example.com"]["/"]["c"]
+        self.assert_(cookie.expires is None)
+
+
+class LWPCookieTests(TestCase):
+    # Tests taken from libwww-perl, with a few modifications and additions.
+
+    def test_netscape_example_1(self):
+        from cookielib import CookieJar, DefaultCookiePolicy
+        from urllib2 import Request
+
+        #-------------------------------------------------------------------
+        # First we check that it works for the original example at
+        # http://www.netscape.com/newsref/std/cookie_spec.html
+
+        # Client requests a document, and receives in the response:
+        #
+        #       Set-Cookie: CUSTOMER=WILE_E_COYOTE; path=/; expires=Wednesday, 09-Nov-99 23:12:40 GMT
+        #
+        # When client requests a URL in path "/" on this server, it sends:
+        #
+        #       Cookie: CUSTOMER=WILE_E_COYOTE
+        #
+        # Client requests a document, and receives in the response:
+        #
+        #       Set-Cookie: PART_NUMBER=ROCKET_LAUNCHER_0001; path=/
+        #
+        # When client requests a URL in path "/" on this server, it sends:
+        #
+        #       Cookie: CUSTOMER=WILE_E_COYOTE; PART_NUMBER=ROCKET_LAUNCHER_0001
+        #
+        # Client receives:
+        #
+        #       Set-Cookie: SHIPPING=FEDEX; path=/fo
+        #
+        # When client requests a URL in path "/" on this server, it sends:
+        #
+        #       Cookie: CUSTOMER=WILE_E_COYOTE; PART_NUMBER=ROCKET_LAUNCHER_0001
+        #
+        # When client requests a URL in path "/foo" on this server, it sends:
+        #
+        #       Cookie: CUSTOMER=WILE_E_COYOTE; PART_NUMBER=ROCKET_LAUNCHER_0001; SHIPPING=FEDEX
+        #
+        # The last Cookie is buggy, because both specifications say that the
+        # most specific cookie must be sent first.  SHIPPING=FEDEX is the
+        # most specific and should thus be first.
+
+        year_plus_one = time.localtime()[0] + 1
+
+        headers = []
+
+        c = CookieJar(DefaultCookiePolicy(rfc2965 = True))
+
+        #req = Request("http://1.1.1.1/",
+        #              headers={"Host": "www.acme.com:80"})
+        req = Request("http://www.acme.com:80/",
+                      headers={"Host": "www.acme.com:80"})
+
+        headers.append(
+            "Set-Cookie: CUSTOMER=WILE_E_COYOTE; path=/ ; "
+            "expires=Wednesday, 09-Nov-%d 23:12:40 GMT" % year_plus_one)
+        res = FakeResponse(headers, "http://www.acme.com/")
+        c.extract_cookies(res, req)
+
+        req = Request("http://www.acme.com/")
+        c.add_cookie_header(req)
+
+        self.assertEqual(req.get_header("Cookie"), "CUSTOMER=WILE_E_COYOTE")
+        self.assertEqual(req.get_header("Cookie2"), '$Version="1"')
+
+        headers.append("Set-Cookie: PART_NUMBER=ROCKET_LAUNCHER_0001; path=/")
+        res = FakeResponse(headers, "http://www.acme.com/")
+        c.extract_cookies(res, req)
+
+        req = Request("http://www.acme.com/foo/bar")
+        c.add_cookie_header(req)
+
+        h = req.get_header("Cookie")
+        self.assert_("PART_NUMBER=ROCKET_LAUNCHER_0001" in h and
+                     "CUSTOMER=WILE_E_COYOTE" in h)
+
+        headers.append('Set-Cookie: SHIPPING=FEDEX; path=/foo')
+        res = FakeResponse(headers, "http://www.acme.com")
+        c.extract_cookies(res, req)
+
+        req = Request("http://www.acme.com/")
+        c.add_cookie_header(req)
+
+        h = req.get_header("Cookie")
+        self.assert_("PART_NUMBER=ROCKET_LAUNCHER_0001" in h and
+                     "CUSTOMER=WILE_E_COYOTE" in h and
+                     "SHIPPING=FEDEX" not in h)
+
+        req = Request("http://www.acme.com/foo/")
+        c.add_cookie_header(req)
+
+        h = req.get_header("Cookie")
+        self.assert_(("PART_NUMBER=ROCKET_LAUNCHER_0001" in h and
+                      "CUSTOMER=WILE_E_COYOTE" in h and
+                      h.startswith("SHIPPING=FEDEX;")))
+
+    def test_netscape_example_2(self):
+        from cookielib import CookieJar
+        from urllib2 import Request
+
+        # Second Example transaction sequence:
+        #
+        # Assume all mappings from above have been cleared.
+        #
+        # Client receives:
+        #
+        #       Set-Cookie: PART_NUMBER=ROCKET_LAUNCHER_0001; path=/
+        #
+        # When client requests a URL in path "/" on this server, it sends:
+        #
+        #       Cookie: PART_NUMBER=ROCKET_LAUNCHER_0001
+        #
+        # Client receives:
+        #
+        #       Set-Cookie: PART_NUMBER=RIDING_ROCKET_0023; path=/ammo
+        #
+        # When client requests a URL in path "/ammo" on this server, it sends:
+        #
+        #       Cookie: PART_NUMBER=RIDING_ROCKET_0023; PART_NUMBER=ROCKET_LAUNCHER_0001
+        #
+        #       NOTE: There are two name/value pairs named "PART_NUMBER" due to
+        #       the inheritance of the "/" mapping in addition to the "/ammo" mapping.
+
+        c = CookieJar()
+        headers = []
+
+        req = Request("http://www.acme.com/")
+        headers.append("Set-Cookie: PART_NUMBER=ROCKET_LAUNCHER_0001; path=/")
+        res = FakeResponse(headers, "http://www.acme.com/")
+
+        c.extract_cookies(res, req)
+
+        req = Request("http://www.acme.com/")
+        c.add_cookie_header(req)
+
+        self.assertEquals(req.get_header("Cookie"),
+                          "PART_NUMBER=ROCKET_LAUNCHER_0001")
+
+        headers.append(
+            "Set-Cookie: PART_NUMBER=RIDING_ROCKET_0023; path=/ammo")
+        res = FakeResponse(headers, "http://www.acme.com/")
+        c.extract_cookies(res, req)
+
+        req = Request("http://www.acme.com/ammo")
+        c.add_cookie_header(req)
+
+        self.assert_(re.search(r"PART_NUMBER=RIDING_ROCKET_0023;\s*"
+                               "PART_NUMBER=ROCKET_LAUNCHER_0001",
+                               req.get_header("Cookie")))
+
+    def test_ietf_example_1(self):
+        from cookielib import CookieJar, DefaultCookiePolicy
+        #-------------------------------------------------------------------
+        # Then we test with the examples from draft-ietf-http-state-man-mec-03.txt
+        #
+        # 5.  EXAMPLES
+
+        c = CookieJar(DefaultCookiePolicy(rfc2965=True))
+
+        #
+        # 5.1  Example 1
+        #
+        # Most detail of request and response headers has been omitted.  Assume
+        # the user agent has no stored cookies.
+        #
+        #   1.  User Agent -> Server
+        #
+        #       POST /acme/login HTTP/1.1
+        #       [form data]
+        #
+        #       User identifies self via a form.
+        #
+        #   2.  Server -> User Agent
+        #
+        #       HTTP/1.1 200 OK
+        #       Set-Cookie2: Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"
+        #
+        #       Cookie reflects user's identity.
+
+        cookie = interact_2965(
+            c, 'http://www.acme.com/acme/login',
+            'Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"')
+        self.assert_(not cookie)
+
+        #
+        #   3.  User Agent -> Server
+        #
+        #       POST /acme/pickitem HTTP/1.1
+        #       Cookie: $Version="1"; Customer="WILE_E_COYOTE"; $Path="/acme"
+        #       [form data]
+        #
+        #       User selects an item for ``shopping basket.''
+        #
+        #   4.  Server -> User Agent
+        #
+        #       HTTP/1.1 200 OK
+        #       Set-Cookie2: Part_Number="Rocket_Launcher_0001"; Version="1";
+        #               Path="/acme"
+        #
+        #       Shopping basket contains an item.
+
+        cookie = interact_2965(c, 'http://www.acme.com/acme/pickitem',
+                               'Part_Number="Rocket_Launcher_0001"; '
+                               'Version="1"; Path="/acme"');
+        self.assert_(re.search(
+            r'^\$Version="?1"?; Customer="?WILE_E_COYOTE"?; \$Path="/acme"$',
+            cookie))
+
+        #
+        #   5.  User Agent -> Server
+        #
+        #       POST /acme/shipping HTTP/1.1
+        #       Cookie: $Version="1";
+        #               Customer="WILE_E_COYOTE"; $Path="/acme";
+        #               Part_Number="Rocket_Launcher_0001"; $Path="/acme"
+        #       [form data]
+        #
+        #       User selects shipping method from form.
+        #
+        #   6.  Server -> User Agent
+        #
+        #       HTTP/1.1 200 OK
+        #       Set-Cookie2: Shipping="FedEx"; Version="1"; Path="/acme"
+        #
+        #       New cookie reflects shipping method.
+
+        cookie = interact_2965(c, "http://www.acme.com/acme/shipping",
+                               'Shipping="FedEx"; Version="1"; Path="/acme"')
+
+        self.assert_(re.search(r'^\$Version="?1"?;', cookie))
+        self.assert_(re.search(r'Part_Number="?Rocket_Launcher_0001"?;'
+                               '\s*\$Path="\/acme"', cookie))
+        self.assert_(re.search(r'Customer="?WILE_E_COYOTE"?;\s*\$Path="\/acme"',
+                               cookie))
+
+        #
+        #   7.  User Agent -> Server
+        #
+        #       POST /acme/process HTTP/1.1
+        #       Cookie: $Version="1";
+        #               Customer="WILE_E_COYOTE"; $Path="/acme";
+        #               Part_Number="Rocket_Launcher_0001"; $Path="/acme";
+        #               Shipping="FedEx"; $Path="/acme"
+        #       [form data]
+        #
+        #       User chooses to process order.
+        #
+        #   8.  Server -> User Agent
+        #
+        #       HTTP/1.1 200 OK
+        #
+        #       Transaction is complete.
+
+        cookie = interact_2965(c, "http://www.acme.com/acme/process")
+        self.assert_(
+            re.search(r'Shipping="?FedEx"?;\s*\$Path="\/acme"', cookie) and
+            "WILE_E_COYOTE" in cookie)
+
+        #
+        # The user agent makes a series of requests on the origin server, after
+        # each of which it receives a new cookie.  All the cookies have the same
+        # Path attribute and (default) domain.  Because the request URLs all have
+        # /acme as a prefix, and that matches the Path attribute, each request
+        # contains all the cookies received so far.
+
+    def test_ietf_example_2(self):
+        from cookielib import CookieJar, DefaultCookiePolicy
+
+        # 5.2  Example 2
+        #
+        # This example illustrates the effect of the Path attribute.  All detail
+        # of request and response headers has been omitted.  Assume the user agent
+        # has no stored cookies.
+
+        c = CookieJar(DefaultCookiePolicy(rfc2965=True))
+
+        # Imagine the user agent has received, in response to earlier requests,
+        # the response headers
+        #
+        # Set-Cookie2: Part_Number="Rocket_Launcher_0001"; Version="1";
+        #         Path="/acme"
+        #
+        # and
+        #
+        # Set-Cookie2: Part_Number="Riding_Rocket_0023"; Version="1";
+        #         Path="/acme/ammo"
+
+        interact_2965(
+            c, "http://www.acme.com/acme/ammo/specific",
+            'Part_Number="Rocket_Launcher_0001"; Version="1"; Path="/acme"',
+            'Part_Number="Riding_Rocket_0023"; Version="1"; Path="/acme/ammo"')
+
+        # A subsequent request by the user agent to the (same) server for URLs of
+        # the form /acme/ammo/...  would include the following request header:
+        #
+        # Cookie: $Version="1";
+        #         Part_Number="Riding_Rocket_0023"; $Path="/acme/ammo";
+        #         Part_Number="Rocket_Launcher_0001"; $Path="/acme"
+        #
+        # Note that the NAME=VALUE pair for the cookie with the more specific Path
+        # attribute, /acme/ammo, comes before the one with the less specific Path
+        # attribute, /acme.  Further note that the same cookie name appears more
+        # than once.
+
+        cookie = interact_2965(c, "http://www.acme.com/acme/ammo/...")
+        self.assert_(
+            re.search(r"Riding_Rocket_0023.*Rocket_Launcher_0001", cookie))
+
+        # A subsequent request by the user agent to the (same) server for a URL of
+        # the form /acme/parts/ would include the following request header:
+        #
+        # Cookie: $Version="1"; Part_Number="Rocket_Launcher_0001"; $Path="/acme"
+        #
+        # Here, the second cookie's Path attribute /acme/ammo is not a prefix of
+        # the request URL, /acme/parts/, so the cookie does not get forwarded to
+        # the server.
+
+        cookie = interact_2965(c, "http://www.acme.com/acme/parts/")
+        self.assert_("Rocket_Launcher_0001" in cookie and
+                     "Riding_Rocket_0023" not in cookie)
+
+    def test_rejection(self):
+        # Test rejection of Set-Cookie2 responses based on domain, path, port.
+        from cookielib import DefaultCookiePolicy, LWPCookieJar
+
+        pol = DefaultCookiePolicy(rfc2965=True)
+
+        c = LWPCookieJar(policy=pol)
+
+        max_age = "max-age=3600"
+
+        # illegal domain (no embedded dots)
+        cookie = interact_2965(c, "http://www.acme.com",
+                               'foo=bar; domain=".com"; version=1')
+        self.assert_(not c)
+
+        # legal domain
+        cookie = interact_2965(c, "http://www.acme.com",
+                               'ping=pong; domain="acme.com"; version=1')
+        self.assertEquals(len(c), 1)
+
+        # illegal domain (host prefix "www.a" contains a dot)
+        cookie = interact_2965(c, "http://www.a.acme.com",
+                               'whiz=bang; domain="acme.com"; version=1')
+        self.assertEquals(len(c), 1)
+
+        # legal domain
+        cookie = interact_2965(c, "http://www.a.acme.com",
+                               'wow=flutter; domain=".a.acme.com"; version=1')
+        self.assertEquals(len(c), 2)
+
+        # can't partially match an IP-address
+        cookie = interact_2965(c, "http://125.125.125.125",
+                               'zzzz=ping; domain="125.125.125"; version=1')
+        self.assertEquals(len(c), 2)
+
+        # illegal path (must be prefix of request path)
+        cookie = interact_2965(c, "http://www.sol.no",
+                               'blah=rhubarb; domain=".sol.no"; path="/foo"; '
+                               'version=1')
+        self.assertEquals(len(c), 2)
+
+        # legal path
+        cookie = interact_2965(c, "http://www.sol.no/foo/bar",
+                               'bing=bong; domain=".sol.no"; path="/foo"; '
+                               'version=1')
+        self.assertEquals(len(c), 3)
+
+        # illegal port (request-port not in list)
+        cookie = interact_2965(c, "http://www.sol.no",
+                               'whiz=ffft; domain=".sol.no"; port="90,100"; '
+                               'version=1')
+        self.assertEquals(len(c), 3)
+
+        # legal port
+        cookie = interact_2965(
+            c, "http://www.sol.no",
+            r'bang=wallop; version=1; domain=".sol.no"; '
+            r'port="90,100, 80,8080"; '
+            r'max-age=100; Comment = "Just kidding! (\"|\\\\) "')
+        self.assertEquals(len(c), 4)
+
+        # port attribute without any value (current port)
+        cookie = interact_2965(c, "http://www.sol.no",
+                               'foo9=bar; version=1; domain=".sol.no"; port; '
+                               'max-age=100;')
+        self.assertEquals(len(c), 5)
+
+        # encoded path
+        # LWP has this test, but unescaping allowed path characters seems
+        # like a bad idea, so I think this should fail:
+##         cookie = interact_2965(c, "http://www.sol.no/foo/",
+##                           r'foo8=bar; version=1; path="/%66oo"')
+        # but this is OK, because '<' is not an allowed HTTP URL path
+        # character:
+        cookie = interact_2965(c, "http://www.sol.no/<oo/",
+                               r'foo8=bar; version=1; path="/%3coo"')
+        self.assertEquals(len(c), 6)
+
+        # save and restore
+        filename = test_support.TESTFN
+
+        try:
+            c.save(filename, ignore_discard=True)
+            old = repr(c)
+
+            c = LWPCookieJar(policy=pol)
+            c.load(filename, ignore_discard=True)
+        finally:
+            try: os.unlink(filename)
+            except OSError: pass
+
+        self.assertEquals(old, repr(c))
+
+    def test_url_encoding(self):
+        # Try some URL encodings of the PATHs.
+        # (the behaviour here has changed from libwww-perl)
+        from cookielib import CookieJar, DefaultCookiePolicy
+
+        c = CookieJar(DefaultCookiePolicy(rfc2965=True))
+        interact_2965(c, "http://www.acme.com/foo%2f%25/%3c%3c%0Anew%E5/%E5",
+                      "foo  =   bar; version    =   1")
+
+        cookie = interact_2965(
+            c, "http://www.acme.com/foo%2f%25/<<%0anewå/æøå",
+            'bar=baz; path="/foo/"; version=1');
+        version_re = re.compile(r'^\$version=\"?1\"?', re.I)
+        self.assert_("foo=bar" in cookie and version_re.search(cookie))
+
+        cookie = interact_2965(
+            c, "http://www.acme.com/foo/%25/<<%0anewå/æøå")
+        self.assert_(not cookie)
+
+        # unicode URL doesn't raise exception
+        cookie = interact_2965(c, u"http://www.acme.com/\xfc")
+
+    def test_mozilla(self):
+        # Save / load Mozilla/Netscape cookie file format.
+        from cookielib import MozillaCookieJar, DefaultCookiePolicy
+
+        year_plus_one = time.localtime()[0] + 1
+
+        filename = test_support.TESTFN
+
+        c = MozillaCookieJar(filename,
+                             policy=DefaultCookiePolicy(rfc2965=True))
+        interact_2965(c, "http://www.acme.com/",
+                      "foo1=bar; max-age=100; Version=1")
+        interact_2965(c, "http://www.acme.com/",
+                      'foo2=bar; port="80"; max-age=100; Discard; Version=1')
+        interact_2965(c, "http://www.acme.com/", "foo3=bar; secure; Version=1")
+
+        expires = "expires=09-Nov-%d 23:12:40 GMT" % (year_plus_one,)
+        interact_netscape(c, "http://www.foo.com/",
+                          "fooa=bar; %s" % expires)
+        interact_netscape(c, "http://www.foo.com/",
+                          "foob=bar; Domain=.foo.com; %s" % expires)
+        interact_netscape(c, "http://www.foo.com/",
+                          "fooc=bar; Domain=www.foo.com; %s" % expires)
+
+        def save_and_restore(cj, ignore_discard):
+            try:
+                cj.save(ignore_discard=ignore_discard)
+                new_c = MozillaCookieJar(filename,
+                                         DefaultCookiePolicy(rfc2965=True))
+                new_c.load(ignore_discard=ignore_discard)
+            finally:
+                try: os.unlink(filename)
+                except OSError: pass
+            return new_c
+
+        new_c = save_and_restore(c, True)
+        self.assertEquals(len(new_c), 6)  # none discarded
+        self.assert_("name='foo1', value='bar'" in repr(new_c))
+
+        new_c = save_and_restore(c, False)
+        self.assertEquals(len(new_c), 4)  # 2 of them discarded on save
+        self.assert_("name='foo1', value='bar'" in repr(new_c))
+
+    def test_netscape_misc(self):
+        # Some additional Netscape cookies tests.
+        from cookielib import CookieJar
+        from urllib2 import Request
+
+        c = CookieJar()
+        headers = []
+        req = Request("http://foo.bar.acme.com/foo")
+
+        # Netscape allows a host part that contains dots
+        headers.append("Set-Cookie: Customer=WILE_E_COYOTE; domain=.acme.com")
+        res = FakeResponse(headers, "http://www.acme.com/foo")
+        c.extract_cookies(res, req)
+
+        # and that the domain is the same as the host without adding a leading
+        # dot to the domain.  Should not quote even if strange chars are used
+        # in the cookie value.
+        headers.append("Set-Cookie: PART_NUMBER=3,4; domain=foo.bar.acme.com")
+        res = FakeResponse(headers, "http://www.acme.com/foo")
+        c.extract_cookies(res, req)
+
+        req = Request("http://foo.bar.acme.com/foo")
+        c.add_cookie_header(req)
+        self.assert_(
+            "PART_NUMBER=3,4" in req.get_header("Cookie") and
+            "Customer=WILE_E_COYOTE" in req.get_header("Cookie"))
+
+    def test_intranet_domains_2965(self):
+        # Test handling of local intranet hostnames without a dot.
+        from cookielib import CookieJar, DefaultCookiePolicy
+
+        c = CookieJar(DefaultCookiePolicy(rfc2965=True))
+        interact_2965(c, "http://example/",
+                      "foo1=bar; PORT; Discard; Version=1;")
+        cookie = interact_2965(c, "http://example/",
+                               'foo2=bar; domain=".local"; Version=1')
+        self.assert_("foo1=bar" in cookie)
+
+        interact_2965(c, "http://example/", 'foo3=bar; Version=1')
+        cookie = interact_2965(c, "http://example/")
+        self.assert_("foo2=bar" in cookie and len(c) == 3)
+
+    def test_intranet_domains_ns(self):
+        from cookielib import CookieJar, DefaultCookiePolicy
+
+        c = CookieJar(DefaultCookiePolicy(rfc2965 = False))
+        interact_netscape(c, "http://example/", "foo1=bar")
+        cookie = interact_netscape(c, "http://example/",
+                                   'foo2=bar; domain=.local')
+        self.assertEquals(len(c), 2)
+        self.assert_("foo1=bar" in cookie)
+
+        cookie = interact_netscape(c, "http://example/")
+        self.assert_("foo2=bar" in cookie)
+        self.assertEquals(len(c), 2)
+
+    def test_empty_path(self):
+        from cookielib import CookieJar, DefaultCookiePolicy
+        from urllib2 import Request
+
+        # Test for empty path
+        # Broken web-server ORION/1.3.38 returns to the client response like
+        #
+        #       Set-Cookie: JSESSIONID=ABCDERANDOM123; Path=
+        #
+        # ie. with Path set to nothing.
+        # In this case, extract_cookies() must set cookie to / (root)
+        c = CookieJar(DefaultCookiePolicy(rfc2965 = True))
+        headers = []
+
+        req = Request("http://www.ants.com/")
+        headers.append("Set-Cookie: JSESSIONID=ABCDERANDOM123; Path=")
+        res = FakeResponse(headers, "http://www.ants.com/")
+        c.extract_cookies(res, req)
+
+        req = Request("http://www.ants.com/")
+        c.add_cookie_header(req)
+
+        self.assertEquals(req.get_header("Cookie"),
+                          "JSESSIONID=ABCDERANDOM123")
+        self.assertEquals(req.get_header("Cookie2"), '$Version="1"')
+
+        # missing path in the request URI
+        req = Request("http://www.ants.com:8080")
+        c.add_cookie_header(req)
+
+        self.assertEquals(req.get_header("Cookie"),
+                          "JSESSIONID=ABCDERANDOM123")
+        self.assertEquals(req.get_header("Cookie2"), '$Version="1"')
+
+    def test_session_cookies(self):
+        from cookielib import CookieJar
+        from urllib2 import Request
+
+        year_plus_one = time.localtime()[0] + 1
+
+        # Check session cookies are deleted properly by
+        # CookieJar.clear_session_cookies method
+
+        req = Request('http://www.perlmeister.com/scripts')
+        headers = []
+        headers.append("Set-Cookie: s1=session;Path=/scripts")
+        headers.append("Set-Cookie: p1=perm; Domain=.perlmeister.com;"
+                       "Path=/;expires=Fri, 02-Feb-%d 23:24:20 GMT" %
+                       year_plus_one)
+        headers.append("Set-Cookie: p2=perm;Path=/;expires=Fri, "
+                       "02-Feb-%d 23:24:20 GMT" % year_plus_one)
+        headers.append("Set-Cookie: s2=session;Path=/scripts;"
+                       "Domain=.perlmeister.com")
+        headers.append('Set-Cookie2: s3=session;Version=1;Discard;Path="/"')
+        res = FakeResponse(headers, 'http://www.perlmeister.com/scripts')
+
+        c = CookieJar()
+        c.extract_cookies(res, req)
+        # How many session/permanent cookies do we have?
+        counter = {"session_after": 0,
+                   "perm_after": 0,
+                   "session_before": 0,
+                   "perm_before": 0}
+        for cookie in c:
+            key = "%s_before" % cookie.value
+            counter[key] = counter[key] + 1
+        c.clear_session_cookies()
+        # How many now?
+        for cookie in c:
+            key = "%s_after" % cookie.value
+            counter[key] = counter[key] + 1
+
+        self.assert_(not (
+            # a permanent cookie got lost accidently
+            counter["perm_after"] != counter["perm_before"] or
+            # a session cookie hasn't been cleared
+            counter["session_after"] != 0 or
+            # we didn't have session cookies in the first place
+            counter["session_before"] == 0))
+
+
+def test_main(verbose=None):
+    from test import test_sets
+    test_support.run_unittest(
+        DateTimeTests,
+        HeaderTests,
+        CookieTests,
+        FileCookieJarTests,
+        LWPCookieTests,
+        )
+
+if __name__ == "__main__":
+    test_main(verbose=True)

Added: vendor/Python/current/Lib/test/test_copy.py
===================================================================
--- vendor/Python/current/Lib/test/test_copy.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_copy.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,591 @@
+"""Unit tests for the copy module."""
+
+import sys
+import copy
+import copy_reg
+
+import unittest
+from test import test_support
+
+class TestCopy(unittest.TestCase):
+
+    # Attempt full line coverage of copy.py from top to bottom
+
+    def test_exceptions(self):
+        self.assert_(copy.Error is copy.error)
+        self.assert_(issubclass(copy.Error, Exception))
+
+    # The copy() method
+
+    def test_copy_basic(self):
+        x = 42
+        y = copy.copy(x)
+        self.assertEqual(x, y)
+
+    def test_copy_copy(self):
+        class C(object):
+            def __init__(self, foo):
+                self.foo = foo
+            def __copy__(self):
+                return C(self.foo)
+        x = C(42)
+        y = copy.copy(x)
+        self.assertEqual(y.__class__, x.__class__)
+        self.assertEqual(y.foo, x.foo)
+
+    def test_copy_registry(self):
+        class C(object):
+            def __new__(cls, foo):
+                obj = object.__new__(cls)
+                obj.foo = foo
+                return obj
+        def pickle_C(obj):
+            return (C, (obj.foo,))
+        x = C(42)
+        self.assertRaises(TypeError, copy.copy, x)
+        copy_reg.pickle(C, pickle_C, C)
+        y = copy.copy(x)
+
+    def test_copy_reduce_ex(self):
+        class C(object):
+            def __reduce_ex__(self, proto):
+                return ""
+            def __reduce__(self):
+                raise test_support.TestFailed, "shouldn't call this"
+        x = C()
+        y = copy.copy(x)
+        self.assert_(y is x)
+
+    def test_copy_reduce(self):
+        class C(object):
+            def __reduce__(self):
+                return ""
+        x = C()
+        y = copy.copy(x)
+        self.assert_(y is x)
+
+    def test_copy_cant(self):
+        class C(object):
+            def __getattribute__(self, name):
+                if name.startswith("__reduce"):
+                    raise AttributeError, name
+                return object.__getattribute__(self, name)
+        x = C()
+        self.assertRaises(copy.Error, copy.copy, x)
+
+    # Type-specific _copy_xxx() methods
+
+    def test_copy_atomic(self):
+        class Classic:
+            pass
+        class NewStyle(object):
+            pass
+        def f():
+            pass
+        tests = [None, 42, 2L**100, 3.14, True, False, 1j,
+                 "hello", u"hello\u1234", f.func_code,
+                 NewStyle, xrange(10), Classic, max]
+        for x in tests:
+            self.assert_(copy.copy(x) is x, repr(x))
+
+    def test_copy_list(self):
+        x = [1, 2, 3]
+        self.assertEqual(copy.copy(x), x)
+
+    def test_copy_tuple(self):
+        x = (1, 2, 3)
+        self.assertEqual(copy.copy(x), x)
+
+    def test_copy_dict(self):
+        x = {"foo": 1, "bar": 2}
+        self.assertEqual(copy.copy(x), x)
+
+    def test_copy_inst_vanilla(self):
+        class C:
+            def __init__(self, foo):
+                self.foo = foo
+            def __cmp__(self, other):
+                return cmp(self.foo, other.foo)
+        x = C(42)
+        self.assertEqual(copy.copy(x), x)
+
+    def test_copy_inst_copy(self):
+        class C:
+            def __init__(self, foo):
+                self.foo = foo
+            def __copy__(self):
+                return C(self.foo)
+            def __cmp__(self, other):
+                return cmp(self.foo, other.foo)
+        x = C(42)
+        self.assertEqual(copy.copy(x), x)
+
+    def test_copy_inst_getinitargs(self):
+        class C:
+            def __init__(self, foo):
+                self.foo = foo
+            def __getinitargs__(self):
+                return (self.foo,)
+            def __cmp__(self, other):
+                return cmp(self.foo, other.foo)
+        x = C(42)
+        self.assertEqual(copy.copy(x), x)
+
+    def test_copy_inst_getstate(self):
+        class C:
+            def __init__(self, foo):
+                self.foo = foo
+            def __getstate__(self):
+                return {"foo": self.foo}
+            def __cmp__(self, other):
+                return cmp(self.foo, other.foo)
+        x = C(42)
+        self.assertEqual(copy.copy(x), x)
+
+    def test_copy_inst_setstate(self):
+        class C:
+            def __init__(self, foo):
+                self.foo = foo
+            def __setstate__(self, state):
+                self.foo = state["foo"]
+            def __cmp__(self, other):
+                return cmp(self.foo, other.foo)
+        x = C(42)
+        self.assertEqual(copy.copy(x), x)
+
+    def test_copy_inst_getstate_setstate(self):
+        class C:
+            def __init__(self, foo):
+                self.foo = foo
+            def __getstate__(self):
+                return self.foo
+            def __setstate__(self, state):
+                self.foo = state
+            def __cmp__(self, other):
+                return cmp(self.foo, other.foo)
+        x = C(42)
+        self.assertEqual(copy.copy(x), x)
+
+    # The deepcopy() method
+
+    def test_deepcopy_basic(self):
+        x = 42
+        y = copy.deepcopy(x)
+        self.assertEqual(y, x)
+
+    def test_deepcopy_memo(self):
+        # Tests of reflexive objects are under type-specific sections below.
+        # This tests only repetitions of objects.
+        x = []
+        x = [x, x]
+        y = copy.deepcopy(x)
+        self.assertEqual(y, x)
+        self.assert_(y is not x)
+        self.assert_(y[0] is not x[0])
+        self.assert_(y[0] is y[1])
+
+    def test_deepcopy_issubclass(self):
+        # XXX Note: there's no way to test the TypeError coming out of
+        # issubclass() -- this can only happen when an extension
+        # module defines a "type" that doesn't formally inherit from
+        # type.
+        class Meta(type):
+            pass
+        class C:
+            __metaclass__ = Meta
+        self.assertEqual(copy.deepcopy(C), C)
+
+    def test_deepcopy_deepcopy(self):
+        class C(object):
+            def __init__(self, foo):
+                self.foo = foo
+            def __deepcopy__(self, memo=None):
+                return C(self.foo)
+        x = C(42)
+        y = copy.deepcopy(x)
+        self.assertEqual(y.__class__, x.__class__)
+        self.assertEqual(y.foo, x.foo)
+
+    def test_deepcopy_registry(self):
+        class C(object):
+            def __new__(cls, foo):
+                obj = object.__new__(cls)
+                obj.foo = foo
+                return obj
+        def pickle_C(obj):
+            return (C, (obj.foo,))
+        x = C(42)
+        self.assertRaises(TypeError, copy.deepcopy, x)
+        copy_reg.pickle(C, pickle_C, C)
+        y = copy.deepcopy(x)
+
+    def test_deepcopy_reduce_ex(self):
+        class C(object):
+            def __reduce_ex__(self, proto):
+                return ""
+            def __reduce__(self):
+                raise test_support.TestFailed, "shouldn't call this"
+        x = C()
+        y = copy.deepcopy(x)
+        self.assert_(y is x)
+
+    def test_deepcopy_reduce(self):
+        class C(object):
+            def __reduce__(self):
+                return ""
+        x = C()
+        y = copy.deepcopy(x)
+        self.assert_(y is x)
+
+    def test_deepcopy_cant(self):
+        class C(object):
+            def __getattribute__(self, name):
+                if name.startswith("__reduce"):
+                    raise AttributeError, name
+                return object.__getattribute__(self, name)
+        x = C()
+        self.assertRaises(copy.Error, copy.deepcopy, x)
+
+    # Type-specific _deepcopy_xxx() methods
+
+    def test_deepcopy_atomic(self):
+        class Classic:
+            pass
+        class NewStyle(object):
+            pass
+        def f():
+            pass
+        tests = [None, 42, 2L**100, 3.14, True, False, 1j,
+                 "hello", u"hello\u1234", f.func_code,
+                 NewStyle, xrange(10), Classic, max]
+        for x in tests:
+            self.assert_(copy.deepcopy(x) is x, repr(x))
+
+    def test_deepcopy_list(self):
+        x = [[1, 2], 3]
+        y = copy.deepcopy(x)
+        self.assertEqual(y, x)
+        self.assert_(x is not y)
+        self.assert_(x[0] is not y[0])
+
+    def test_deepcopy_reflexive_list(self):
+        x = []
+        x.append(x)
+        y = copy.deepcopy(x)
+        self.assertRaises(RuntimeError, cmp, y, x)
+        self.assert_(y is not x)
+        self.assert_(y[0] is y)
+        self.assertEqual(len(y), 1)
+
+    def test_deepcopy_tuple(self):
+        x = ([1, 2], 3)
+        y = copy.deepcopy(x)
+        self.assertEqual(y, x)
+        self.assert_(x is not y)
+        self.assert_(x[0] is not y[0])
+
+    def test_deepcopy_reflexive_tuple(self):
+        x = ([],)
+        x[0].append(x)
+        y = copy.deepcopy(x)
+        self.assertRaises(RuntimeError, cmp, y, x)
+        self.assert_(y is not x)
+        self.assert_(y[0] is not x[0])
+        self.assert_(y[0][0] is y)
+
+    def test_deepcopy_dict(self):
+        x = {"foo": [1, 2], "bar": 3}
+        y = copy.deepcopy(x)
+        self.assertEqual(y, x)
+        self.assert_(x is not y)
+        self.assert_(x["foo"] is not y["foo"])
+
+    def test_deepcopy_reflexive_dict(self):
+        x = {}
+        x['foo'] = x
+        y = copy.deepcopy(x)
+        self.assertRaises(RuntimeError, cmp, y, x)
+        self.assert_(y is not x)
+        self.assert_(y['foo'] is y)
+        self.assertEqual(len(y), 1)
+
+    def test_deepcopy_keepalive(self):
+        memo = {}
+        x = 42
+        y = copy.deepcopy(x, memo)
+        self.assert_(memo[id(x)] is x)
+
+    def test_deepcopy_inst_vanilla(self):
+        class C:
+            def __init__(self, foo):
+                self.foo = foo
+            def __cmp__(self, other):
+                return cmp(self.foo, other.foo)
+        x = C([42])
+        y = copy.deepcopy(x)
+        self.assertEqual(y, x)
+        self.assert_(y.foo is not x.foo)
+
+    def test_deepcopy_inst_deepcopy(self):
+        class C:
+            def __init__(self, foo):
+                self.foo = foo
+            def __deepcopy__(self, memo):
+                return C(copy.deepcopy(self.foo, memo))
+            def __cmp__(self, other):
+                return cmp(self.foo, other.foo)
+        x = C([42])
+        y = copy.deepcopy(x)
+        self.assertEqual(y, x)
+        self.assert_(y is not x)
+        self.assert_(y.foo is not x.foo)
+
+    def test_deepcopy_inst_getinitargs(self):
+        class C:
+            def __init__(self, foo):
+                self.foo = foo
+            def __getinitargs__(self):
+                return (self.foo,)
+            def __cmp__(self, other):
+                return cmp(self.foo, other.foo)
+        x = C([42])
+        y = copy.deepcopy(x)
+        self.assertEqual(y, x)
+        self.assert_(y is not x)
+        self.assert_(y.foo is not x.foo)
+
+    def test_deepcopy_inst_getstate(self):
+        class C:
+            def __init__(self, foo):
+                self.foo = foo
+            def __getstate__(self):
+                return {"foo": self.foo}
+            def __cmp__(self, other):
+                return cmp(self.foo, other.foo)
+        x = C([42])
+        y = copy.deepcopy(x)
+        self.assertEqual(y, x)
+        self.assert_(y is not x)
+        self.assert_(y.foo is not x.foo)
+
+    def test_deepcopy_inst_setstate(self):
+        class C:
+            def __init__(self, foo):
+                self.foo = foo
+            def __setstate__(self, state):
+                self.foo = state["foo"]
+            def __cmp__(self, other):
+                return cmp(self.foo, other.foo)
+        x = C([42])
+        y = copy.deepcopy(x)
+        self.assertEqual(y, x)
+        self.assert_(y is not x)
+        self.assert_(y.foo is not x.foo)
+
+    def test_deepcopy_inst_getstate_setstate(self):
+        class C:
+            def __init__(self, foo):
+                self.foo = foo
+            def __getstate__(self):
+                return self.foo
+            def __setstate__(self, state):
+                self.foo = state
+            def __cmp__(self, other):
+                return cmp(self.foo, other.foo)
+        x = C([42])
+        y = copy.deepcopy(x)
+        self.assertEqual(y, x)
+        self.assert_(y is not x)
+        self.assert_(y.foo is not x.foo)
+
+    def test_deepcopy_reflexive_inst(self):
+        class C:
+            pass
+        x = C()
+        x.foo = x
+        y = copy.deepcopy(x)
+        self.assert_(y is not x)
+        self.assert_(y.foo is y)
+
+    # _reconstruct()
+
+    def test_reconstruct_string(self):
+        class C(object):
+            def __reduce__(self):
+                return ""
+        x = C()
+        y = copy.copy(x)
+        self.assert_(y is x)
+        y = copy.deepcopy(x)
+        self.assert_(y is x)
+
+    def test_reconstruct_nostate(self):
+        class C(object):
+            def __reduce__(self):
+                return (C, ())
+        x = C()
+        x.foo = 42
+        y = copy.copy(x)
+        self.assert_(y.__class__ is x.__class__)
+        y = copy.deepcopy(x)
+        self.assert_(y.__class__ is x.__class__)
+
+    def test_reconstruct_state(self):
+        class C(object):
+            def __reduce__(self):
+                return (C, (), self.__dict__)
+            def __cmp__(self, other):
+                return cmp(self.__dict__, other.__dict__)
+        x = C()
+        x.foo = [42]
+        y = copy.copy(x)
+        self.assertEqual(y, x)
+        y = copy.deepcopy(x)
+        self.assertEqual(y, x)
+        self.assert_(y.foo is not x.foo)
+
+    def test_reconstruct_state_setstate(self):
+        class C(object):
+            def __reduce__(self):
+                return (C, (), self.__dict__)
+            def __setstate__(self, state):
+                self.__dict__.update(state)
+            def __cmp__(self, other):
+                return cmp(self.__dict__, other.__dict__)
+        x = C()
+        x.foo = [42]
+        y = copy.copy(x)
+        self.assertEqual(y, x)
+        y = copy.deepcopy(x)
+        self.assertEqual(y, x)
+        self.assert_(y.foo is not x.foo)
+
+    def test_reconstruct_reflexive(self):
+        class C(object):
+            pass
+        x = C()
+        x.foo = x
+        y = copy.deepcopy(x)
+        self.assert_(y is not x)
+        self.assert_(y.foo is y)
+
+    # Additions for Python 2.3 and pickle protocol 2
+
+    def test_reduce_4tuple(self):
+        class C(list):
+            def __reduce__(self):
+                return (C, (), self.__dict__, iter(self))
+            def __cmp__(self, other):
+                return (cmp(list(self), list(other)) or
+                        cmp(self.__dict__, other.__dict__))
+        x = C([[1, 2], 3])
+        y = copy.copy(x)
+        self.assertEqual(x, y)
+        self.assert_(x is not y)
+        self.assert_(x[0] is y[0])
+        y = copy.deepcopy(x)
+        self.assertEqual(x, y)
+        self.assert_(x is not y)
+        self.assert_(x[0] is not y[0])
+
+    def test_reduce_5tuple(self):
+        class C(dict):
+            def __reduce__(self):
+                return (C, (), self.__dict__, None, self.iteritems())
+            def __cmp__(self, other):
+                return (cmp(dict(self), list(dict)) or
+                        cmp(self.__dict__, other.__dict__))
+        x = C([("foo", [1, 2]), ("bar", 3)])
+        y = copy.copy(x)
+        self.assertEqual(x, y)
+        self.assert_(x is not y)
+        self.assert_(x["foo"] is y["foo"])
+        y = copy.deepcopy(x)
+        self.assertEqual(x, y)
+        self.assert_(x is not y)
+        self.assert_(x["foo"] is not y["foo"])
+
+    def test_copy_slots(self):
+        class C(object):
+            __slots__ = ["foo"]
+        x = C()
+        x.foo = [42]
+        y = copy.copy(x)
+        self.assert_(x.foo is y.foo)
+
+    def test_deepcopy_slots(self):
+        class C(object):
+            __slots__ = ["foo"]
+        x = C()
+        x.foo = [42]
+        y = copy.deepcopy(x)
+        self.assertEqual(x.foo, y.foo)
+        self.assert_(x.foo is not y.foo)
+
+    def test_copy_list_subclass(self):
+        class C(list):
+            pass
+        x = C([[1, 2], 3])
+        x.foo = [4, 5]
+        y = copy.copy(x)
+        self.assertEqual(list(x), list(y))
+        self.assertEqual(x.foo, y.foo)
+        self.assert_(x[0] is y[0])
+        self.assert_(x.foo is y.foo)
+
+    def test_deepcopy_list_subclass(self):
+        class C(list):
+            pass
+        x = C([[1, 2], 3])
+        x.foo = [4, 5]
+        y = copy.deepcopy(x)
+        self.assertEqual(list(x), list(y))
+        self.assertEqual(x.foo, y.foo)
+        self.assert_(x[0] is not y[0])
+        self.assert_(x.foo is not y.foo)
+
+    def test_copy_tuple_subclass(self):
+        class C(tuple):
+            pass
+        x = C([1, 2, 3])
+        self.assertEqual(tuple(x), (1, 2, 3))
+        y = copy.copy(x)
+        self.assertEqual(tuple(y), (1, 2, 3))
+
+    def test_deepcopy_tuple_subclass(self):
+        class C(tuple):
+            pass
+        x = C([[1, 2], 3])
+        self.assertEqual(tuple(x), ([1, 2], 3))
+        y = copy.deepcopy(x)
+        self.assertEqual(tuple(y), ([1, 2], 3))
+        self.assert_(x is not y)
+        self.assert_(x[0] is not y[0])
+
+    def test_getstate_exc(self):
+        class EvilState(object):
+            def __getstate__(self):
+                raise ValueError, "ain't got no stickin' state"
+        self.assertRaises(ValueError, copy.copy, EvilState())
+
+    def test_copy_function(self):
+        self.assertEqual(copy.copy(global_foo), global_foo)
+        def foo(x, y): return x+y
+        self.assertEqual(copy.copy(foo), foo)
+        bar = lambda: None
+        self.assertEqual(copy.copy(bar), bar)
+
+    def test_deepcopy_function(self):
+        self.assertEqual(copy.deepcopy(global_foo), global_foo)
+        def foo(x, y): return x+y
+        self.assertEqual(copy.deepcopy(foo), foo)
+        bar = lambda: None
+        self.assertEqual(copy.deepcopy(bar), bar)
+
+def global_foo(x, y): return x+y
+
+def test_main():
+    test_support.run_unittest(TestCopy)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_copy_reg.py
===================================================================
--- vendor/Python/current/Lib/test/test_copy_reg.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_copy_reg.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,121 @@
+import copy_reg
+import unittest
+
+from test import test_support
+from test.pickletester import ExtensionSaver
+
+class C:
+    pass
+
+
+class WithoutSlots(object):
+    pass
+
+class WithWeakref(object):
+    __slots__ = ('__weakref__',)
+
+class WithPrivate(object):
+    __slots__ = ('__spam',)
+
+class WithSingleString(object):
+    __slots__ = 'spam'
+
+class WithInherited(WithSingleString):
+    __slots__ = ('eggs',)
+
+
+class CopyRegTestCase(unittest.TestCase):
+
+    def test_class(self):
+        self.assertRaises(TypeError, copy_reg.pickle,
+                          C, None, None)
+
+    def test_noncallable_reduce(self):
+        self.assertRaises(TypeError, copy_reg.pickle,
+                          type(1), "not a callable")
+
+    def test_noncallable_constructor(self):
+        self.assertRaises(TypeError, copy_reg.pickle,
+                          type(1), int, "not a callable")
+
+    def test_bool(self):
+        import copy
+        self.assertEquals(True, copy.copy(True))
+
+    def test_extension_registry(self):
+        mod, func, code = 'junk1 ', ' junk2', 0xabcd
+        e = ExtensionSaver(code)
+        try:
+            # Shouldn't be in registry now.
+            self.assertRaises(ValueError, copy_reg.remove_extension,
+                              mod, func, code)
+            copy_reg.add_extension(mod, func, code)
+            # Should be in the registry.
+            self.assert_(copy_reg._extension_registry[mod, func] == code)
+            self.assert_(copy_reg._inverted_registry[code] == (mod, func))
+            # Shouldn't be in the cache.
+            self.assert_(code not in copy_reg._extension_cache)
+            # Redundant registration should be OK.
+            copy_reg.add_extension(mod, func, code)  # shouldn't blow up
+            # Conflicting code.
+            self.assertRaises(ValueError, copy_reg.add_extension,
+                              mod, func, code + 1)
+            self.assertRaises(ValueError, copy_reg.remove_extension,
+                              mod, func, code + 1)
+            # Conflicting module name.
+            self.assertRaises(ValueError, copy_reg.add_extension,
+                              mod[1:], func, code )
+            self.assertRaises(ValueError, copy_reg.remove_extension,
+                              mod[1:], func, code )
+            # Conflicting function name.
+            self.assertRaises(ValueError, copy_reg.add_extension,
+                              mod, func[1:], code)
+            self.assertRaises(ValueError, copy_reg.remove_extension,
+                              mod, func[1:], code)
+            # Can't remove one that isn't registered at all.
+            if code + 1 not in copy_reg._inverted_registry:
+                self.assertRaises(ValueError, copy_reg.remove_extension,
+                                  mod[1:], func[1:], code + 1)
+
+        finally:
+            e.restore()
+
+        # Shouldn't be there anymore.
+        self.assert_((mod, func) not in copy_reg._extension_registry)
+        # The code *may* be in copy_reg._extension_registry, though, if
+        # we happened to pick on a registered code.  So don't check for
+        # that.
+
+        # Check valid codes at the limits.
+        for code in 1, 0x7fffffff:
+            e = ExtensionSaver(code)
+            try:
+                copy_reg.add_extension(mod, func, code)
+                copy_reg.remove_extension(mod, func, code)
+            finally:
+                e.restore()
+
+        # Ensure invalid codes blow up.
+        for code in -1, 0, 0x80000000L:
+            self.assertRaises(ValueError, copy_reg.add_extension,
+                              mod, func, code)
+
+    def test_slotnames(self):
+        self.assertEquals(copy_reg._slotnames(WithoutSlots), [])
+        self.assertEquals(copy_reg._slotnames(WithWeakref), [])
+        expected = ['_WithPrivate__spam']
+        self.assertEquals(copy_reg._slotnames(WithPrivate), expected)
+        self.assertEquals(copy_reg._slotnames(WithSingleString), ['spam'])
+        expected = ['eggs', 'spam']
+        expected.sort()
+        result = copy_reg._slotnames(WithInherited)
+        result.sort()
+        self.assertEquals(result, expected)
+
+
+def test_main():
+    test_support.run_unittest(CopyRegTestCase)
+
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_cpickle.py
===================================================================
--- vendor/Python/current/Lib/test/test_cpickle.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_cpickle.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,103 @@
+import cPickle
+import unittest
+from cStringIO import StringIO
+from test.pickletester import AbstractPickleTests, AbstractPickleModuleTests
+from test import test_support
+
+class cPickleTests(AbstractPickleTests, AbstractPickleModuleTests):
+
+    def setUp(self):
+        self.dumps = cPickle.dumps
+        self.loads = cPickle.loads
+
+    error = cPickle.BadPickleGet
+    module = cPickle
+
+class cPicklePicklerTests(AbstractPickleTests):
+
+    def dumps(self, arg, proto=0):
+        f = StringIO()
+        p = cPickle.Pickler(f, proto)
+        p.dump(arg)
+        f.seek(0)
+        return f.read()
+
+    def loads(self, buf):
+        f = StringIO(buf)
+        p = cPickle.Unpickler(f)
+        return p.load()
+
+    error = cPickle.BadPickleGet
+
+class cPickleListPicklerTests(AbstractPickleTests):
+
+    def dumps(self, arg, proto=0):
+        p = cPickle.Pickler(proto)
+        p.dump(arg)
+        return p.getvalue()
+
+    def loads(self, *args):
+        f = StringIO(args[0])
+        p = cPickle.Unpickler(f)
+        return p.load()
+
+    error = cPickle.BadPickleGet
+
+class cPickleFastPicklerTests(AbstractPickleTests):
+
+    def dumps(self, arg, proto=0):
+        f = StringIO()
+        p = cPickle.Pickler(f, proto)
+        p.fast = 1
+        p.dump(arg)
+        f.seek(0)
+        return f.read()
+
+    def loads(self, *args):
+        f = StringIO(args[0])
+        p = cPickle.Unpickler(f)
+        return p.load()
+
+    error = cPickle.BadPickleGet
+
+    def test_recursive_list(self):
+        self.assertRaises(ValueError,
+                          AbstractPickleTests.test_recursive_list,
+                          self)
+
+    def test_recursive_inst(self):
+        self.assertRaises(ValueError,
+                          AbstractPickleTests.test_recursive_inst,
+                          self)
+
+    def test_recursive_dict(self):
+        self.assertRaises(ValueError,
+                          AbstractPickleTests.test_recursive_dict,
+                          self)
+
+    def test_recursive_multi(self):
+        self.assertRaises(ValueError,
+                          AbstractPickleTests.test_recursive_multi,
+                          self)
+
+    def test_nonrecursive_deep(self):
+        # If it's not cyclic, it should pickle OK even if the nesting
+        # depth exceeds PY_CPICKLE_FAST_LIMIT.  That happens to be
+        # 50 today.  Jack Jansen reported stack overflow on Mac OS 9
+        # at 64.
+        a = []
+        for i in range(60):
+            a = [a]
+        b = self.loads(self.dumps(a))
+        self.assertEqual(a, b)
+
+def test_main():
+    test_support.run_unittest(
+        cPickleTests,
+        cPicklePicklerTests,
+        cPickleListPicklerTests,
+        cPickleFastPicklerTests
+    )
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_crypt.py
===================================================================
--- vendor/Python/current/Lib/test/test_crypt.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_crypt.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,11 @@
+#! /usr/bin/env python
+"""Simple test script for cryptmodule.c
+   Roger E. Masse
+"""
+
+from test.test_support import verify, verbose
+import crypt
+
+c = crypt.crypt('mypassword', 'ab')
+if verbose:
+    print 'Test encryption: ', c


Property changes on: vendor/Python/current/Lib/test/test_crypt.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/test/test_csv.py
===================================================================
--- vendor/Python/current/Lib/test/test_csv.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_csv.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,991 @@
+# -*- coding: iso-8859-1 -*-
+# Copyright (C) 2001,2002 Python Software Foundation
+# csv package unit tests
+
+import sys
+import os
+import unittest
+from StringIO import StringIO
+import tempfile
+import csv
+import gc
+from test import test_support
+
+class Test_Csv(unittest.TestCase):
+    """
+    Test the underlying C csv parser in ways that are not appropriate
+    from the high level interface. Further tests of this nature are done
+    in TestDialectRegistry.
+    """
+    def _test_arg_valid(self, ctor, arg):
+        self.assertRaises(TypeError, ctor)
+        self.assertRaises(TypeError, ctor, None)
+        self.assertRaises(TypeError, ctor, arg, bad_attr = 0)
+        self.assertRaises(TypeError, ctor, arg, delimiter = 0)
+        self.assertRaises(TypeError, ctor, arg, delimiter = 'XX')
+        self.assertRaises(csv.Error, ctor, arg, 'foo')
+        self.assertRaises(TypeError, ctor, arg, delimiter=None)
+        self.assertRaises(TypeError, ctor, arg, delimiter=1)
+        self.assertRaises(TypeError, ctor, arg, quotechar=1)
+        self.assertRaises(TypeError, ctor, arg, lineterminator=None)
+        self.assertRaises(TypeError, ctor, arg, lineterminator=1)
+        self.assertRaises(TypeError, ctor, arg, quoting=None)
+        self.assertRaises(TypeError, ctor, arg,
+                          quoting=csv.QUOTE_ALL, quotechar='')
+        self.assertRaises(TypeError, ctor, arg,
+                          quoting=csv.QUOTE_ALL, quotechar=None)
+
+    def test_reader_arg_valid(self):
+        self._test_arg_valid(csv.reader, [])
+
+    def test_writer_arg_valid(self):
+        self._test_arg_valid(csv.writer, StringIO())
+
+    def _test_default_attrs(self, ctor, *args):
+        obj = ctor(*args)
+        # Check defaults
+        self.assertEqual(obj.dialect.delimiter, ',')
+        self.assertEqual(obj.dialect.doublequote, True)
+        self.assertEqual(obj.dialect.escapechar, None)
+        self.assertEqual(obj.dialect.lineterminator, "\r\n")
+        self.assertEqual(obj.dialect.quotechar, '"')
+        self.assertEqual(obj.dialect.quoting, csv.QUOTE_MINIMAL)
+        self.assertEqual(obj.dialect.skipinitialspace, False)
+        self.assertEqual(obj.dialect.strict, False)
+        # Try deleting or changing attributes (they are read-only)
+        self.assertRaises(TypeError, delattr, obj.dialect, 'delimiter')
+        self.assertRaises(TypeError, setattr, obj.dialect, 'delimiter', ':')
+        self.assertRaises(AttributeError, delattr, obj.dialect, 'quoting')
+        self.assertRaises(AttributeError, setattr, obj.dialect,
+                          'quoting', None)
+
+    def test_reader_attrs(self):
+        self._test_default_attrs(csv.reader, [])
+
+    def test_writer_attrs(self):
+        self._test_default_attrs(csv.writer, StringIO())
+
+    def _test_kw_attrs(self, ctor, *args):
+        # Now try with alternate options
+        kwargs = dict(delimiter=':', doublequote=False, escapechar='\\',
+                      lineterminator='\r', quotechar='*',
+                      quoting=csv.QUOTE_NONE, skipinitialspace=True,
+                      strict=True)
+        obj = ctor(*args, **kwargs)
+        self.assertEqual(obj.dialect.delimiter, ':')
+        self.assertEqual(obj.dialect.doublequote, False)
+        self.assertEqual(obj.dialect.escapechar, '\\')
+        self.assertEqual(obj.dialect.lineterminator, "\r")
+        self.assertEqual(obj.dialect.quotechar, '*')
+        self.assertEqual(obj.dialect.quoting, csv.QUOTE_NONE)
+        self.assertEqual(obj.dialect.skipinitialspace, True)
+        self.assertEqual(obj.dialect.strict, True)
+
+    def test_reader_kw_attrs(self):
+        self._test_kw_attrs(csv.reader, [])
+
+    def test_writer_kw_attrs(self):
+        self._test_kw_attrs(csv.writer, StringIO())
+
+    def _test_dialect_attrs(self, ctor, *args):
+        # Now try with dialect-derived options
+        class dialect:
+            delimiter='-'
+            doublequote=False
+            escapechar='^'
+            lineterminator='$'
+            quotechar='#'
+            quoting=csv.QUOTE_ALL
+            skipinitialspace=True
+            strict=False
+        args = args + (dialect,)
+        obj = ctor(*args)
+        self.assertEqual(obj.dialect.delimiter, '-')
+        self.assertEqual(obj.dialect.doublequote, False)
+        self.assertEqual(obj.dialect.escapechar, '^')
+        self.assertEqual(obj.dialect.lineterminator, "$")
+        self.assertEqual(obj.dialect.quotechar, '#')
+        self.assertEqual(obj.dialect.quoting, csv.QUOTE_ALL)
+        self.assertEqual(obj.dialect.skipinitialspace, True)
+        self.assertEqual(obj.dialect.strict, False)
+
+    def test_reader_dialect_attrs(self):
+        self._test_dialect_attrs(csv.reader, [])
+
+    def test_writer_dialect_attrs(self):
+        self._test_dialect_attrs(csv.writer, StringIO())
+
+
+    def _write_test(self, fields, expect, **kwargs):
+        fd, name = tempfile.mkstemp()
+        fileobj = os.fdopen(fd, "w+b")
+        try:
+            writer = csv.writer(fileobj, **kwargs)
+            writer.writerow(fields)
+            fileobj.seek(0)
+            self.assertEqual(fileobj.read(),
+                             expect + writer.dialect.lineterminator)
+        finally:
+            fileobj.close()
+            os.unlink(name)
+
+    def test_write_arg_valid(self):
+        self.assertRaises(csv.Error, self._write_test, None, '')
+        self._write_test((), '')
+        self._write_test([None], '""')
+        self.assertRaises(csv.Error, self._write_test,
+                          [None], None, quoting = csv.QUOTE_NONE)
+        # Check that exceptions are passed up the chain
+        class BadList:
+            def __len__(self):
+                return 10;
+            def __getitem__(self, i):
+                if i > 2:
+                    raise IOError
+        self.assertRaises(IOError, self._write_test, BadList(), '')
+        class BadItem:
+            def __str__(self):
+                raise IOError
+        self.assertRaises(IOError, self._write_test, [BadItem()], '')
+
+    def test_write_bigfield(self):
+        # This exercises the buffer realloc functionality
+        bigstring = 'X' * 50000
+        self._write_test([bigstring,bigstring], '%s,%s' % \
+                         (bigstring, bigstring))
+
+    def test_write_quoting(self):
+        self._write_test(['a',1,'p,q'], 'a,1,"p,q"')
+        self.assertRaises(csv.Error,
+                          self._write_test,
+                          ['a',1,'p,q'], 'a,1,p,q',
+                          quoting = csv.QUOTE_NONE)
+        self._write_test(['a',1,'p,q'], 'a,1,"p,q"',
+                         quoting = csv.QUOTE_MINIMAL)
+        self._write_test(['a',1,'p,q'], '"a",1,"p,q"',
+                         quoting = csv.QUOTE_NONNUMERIC)
+        self._write_test(['a',1,'p,q'], '"a","1","p,q"',
+                         quoting = csv.QUOTE_ALL)
+
+    def test_write_escape(self):
+        self._write_test(['a',1,'p,q'], 'a,1,"p,q"',
+                         escapechar='\\')
+        self.assertRaises(csv.Error,
+                          self._write_test,
+                          ['a',1,'p,"q"'], 'a,1,"p,\\"q\\""',
+                          escapechar=None, doublequote=False)
+        self._write_test(['a',1,'p,"q"'], 'a,1,"p,\\"q\\""',
+                         escapechar='\\', doublequote = False)
+        self._write_test(['"'], '""""',
+                         escapechar='\\', quoting = csv.QUOTE_MINIMAL)
+        self._write_test(['"'], '\\"',
+                         escapechar='\\', quoting = csv.QUOTE_MINIMAL,
+                         doublequote = False)
+        self._write_test(['"'], '\\"',
+                         escapechar='\\', quoting = csv.QUOTE_NONE)
+        self._write_test(['a',1,'p,q'], 'a,1,p\\,q',
+                         escapechar='\\', quoting = csv.QUOTE_NONE)
+
+    def test_writerows(self):
+        class BrokenFile:
+            def write(self, buf):
+                raise IOError
+        writer = csv.writer(BrokenFile())
+        self.assertRaises(IOError, writer.writerows, [['a']])
+        fd, name = tempfile.mkstemp()
+        fileobj = os.fdopen(fd, "w+b")
+        try:
+            writer = csv.writer(fileobj)
+            self.assertRaises(TypeError, writer.writerows, None)
+            writer.writerows([['a','b'],['c','d']])
+            fileobj.seek(0)
+            self.assertEqual(fileobj.read(), "a,b\r\nc,d\r\n")
+        finally:
+            fileobj.close()
+            os.unlink(name)
+
+    def _read_test(self, input, expect, **kwargs):
+        reader = csv.reader(input, **kwargs)
+        result = list(reader)
+        self.assertEqual(result, expect)
+
+    def test_read_oddinputs(self):
+        self._read_test([], [])
+        self._read_test([''], [[]])
+        self.assertRaises(csv.Error, self._read_test,
+                          ['"ab"c'], None, strict = 1)
+        # cannot handle null bytes for the moment
+        self.assertRaises(csv.Error, self._read_test,
+                          ['ab\0c'], None, strict = 1)
+        self._read_test(['"ab"c'], [['abc']], doublequote = 0)
+
+    def test_read_eol(self):
+        self._read_test(['a,b'], [['a','b']])
+        self._read_test(['a,b\n'], [['a','b']])
+        self._read_test(['a,b\r\n'], [['a','b']])
+        self._read_test(['a,b\r'], [['a','b']])
+        self.assertRaises(csv.Error, self._read_test, ['a,b\rc,d'], [])
+        self.assertRaises(csv.Error, self._read_test, ['a,b\nc,d'], [])
+        self.assertRaises(csv.Error, self._read_test, ['a,b\r\nc,d'], [])
+
+    def test_read_escape(self):
+        self._read_test(['a,\\b,c'], [['a', 'b', 'c']], escapechar='\\')
+        self._read_test(['a,b\\,c'], [['a', 'b,c']], escapechar='\\')
+        self._read_test(['a,"b\\,c"'], [['a', 'b,c']], escapechar='\\')
+        self._read_test(['a,"b,\\c"'], [['a', 'b,c']], escapechar='\\')
+        self._read_test(['a,"b,c\\""'], [['a', 'b,c"']], escapechar='\\')
+        self._read_test(['a,"b,c"\\'], [['a', 'b,c\\']], escapechar='\\')
+
+    def test_read_quoting(self):
+        self._read_test(['1,",3,",5'], [['1', ',3,', '5']])
+        self._read_test(['1,",3,",5'], [['1', '"', '3', '"', '5']],
+                        quotechar=None, escapechar='\\')
+        self._read_test(['1,",3,",5'], [['1', '"', '3', '"', '5']],
+                        quoting=csv.QUOTE_NONE, escapechar='\\')
+        # will this fail where locale uses comma for decimals?
+        self._read_test([',3,"5",7.3, 9'], [['', 3, '5', 7.3, 9]],
+                        quoting=csv.QUOTE_NONNUMERIC)
+        self.assertRaises(ValueError, self._read_test,
+                          ['abc,3'], [[]],
+                          quoting=csv.QUOTE_NONNUMERIC)
+
+    def test_read_bigfield(self):
+        # This exercises the buffer realloc functionality and field size
+        # limits.
+        limit = csv.field_size_limit()
+        try:
+            size = 50000
+            bigstring = 'X' * size
+            bigline = '%s,%s' % (bigstring, bigstring)
+            self._read_test([bigline], [[bigstring, bigstring]])
+            csv.field_size_limit(size)
+            self._read_test([bigline], [[bigstring, bigstring]])
+            self.assertEqual(csv.field_size_limit(), size)
+            csv.field_size_limit(size-1)
+            self.assertRaises(csv.Error, self._read_test, [bigline], [])
+            self.assertRaises(TypeError, csv.field_size_limit, None)
+            self.assertRaises(TypeError, csv.field_size_limit, 1, None)
+        finally:
+            csv.field_size_limit(limit)
+
+    def test_read_linenum(self):
+        r = csv.reader(['line,1', 'line,2', 'line,3'])
+        self.assertEqual(r.line_num, 0)
+        r.next()
+        self.assertEqual(r.line_num, 1)
+        r.next()
+        self.assertEqual(r.line_num, 2)
+        r.next()
+        self.assertEqual(r.line_num, 3)
+        self.assertRaises(StopIteration, r.next)
+        self.assertEqual(r.line_num, 3)
+
+class TestDialectRegistry(unittest.TestCase):
+    def test_registry_badargs(self):
+        self.assertRaises(TypeError, csv.list_dialects, None)
+        self.assertRaises(TypeError, csv.get_dialect)
+        self.assertRaises(csv.Error, csv.get_dialect, None)
+        self.assertRaises(csv.Error, csv.get_dialect, "nonesuch")
+        self.assertRaises(TypeError, csv.unregister_dialect)
+        self.assertRaises(csv.Error, csv.unregister_dialect, None)
+        self.assertRaises(csv.Error, csv.unregister_dialect, "nonesuch")
+        self.assertRaises(TypeError, csv.register_dialect, None)
+        self.assertRaises(TypeError, csv.register_dialect, None, None)
+        self.assertRaises(TypeError, csv.register_dialect, "nonesuch", 0, 0)
+        self.assertRaises(TypeError, csv.register_dialect, "nonesuch",
+                          badargument=None)
+        self.assertRaises(TypeError, csv.register_dialect, "nonesuch",
+                          quoting=None)
+        self.assertRaises(TypeError, csv.register_dialect, [])
+
+    def test_registry(self):
+        class myexceltsv(csv.excel):
+            delimiter = "\t"
+        name = "myexceltsv"
+        expected_dialects = csv.list_dialects() + [name]
+        expected_dialects.sort()
+        csv.register_dialect(name, myexceltsv)
+        try:
+            self.failUnless(csv.get_dialect(name).delimiter, '\t')
+            got_dialects = csv.list_dialects()
+            got_dialects.sort()
+            self.assertEqual(expected_dialects, got_dialects)
+        finally:
+            csv.unregister_dialect(name)
+
+    def test_register_kwargs(self):
+        name = 'fedcba'
+        csv.register_dialect(name, delimiter=';')
+        try:
+            self.failUnless(csv.get_dialect(name).delimiter, '\t')
+            self.failUnless(list(csv.reader('X;Y;Z', name)), ['X', 'Y', 'Z'])
+        finally:
+            csv.unregister_dialect(name)
+
+    def test_incomplete_dialect(self):
+        class myexceltsv(csv.Dialect):
+            delimiter = "\t"
+        self.assertRaises(csv.Error, myexceltsv)
+
+    def test_space_dialect(self):
+        class space(csv.excel):
+            delimiter = " "
+            quoting = csv.QUOTE_NONE
+            escapechar = "\\"
+
+        fd, name = tempfile.mkstemp()
+        fileobj = os.fdopen(fd, "w+b")
+        try:
+            fileobj.write("abc def\nc1ccccc1 benzene\n")
+            fileobj.seek(0)
+            rdr = csv.reader(fileobj, dialect=space())
+            self.assertEqual(rdr.next(), ["abc", "def"])
+            self.assertEqual(rdr.next(), ["c1ccccc1", "benzene"])
+        finally:
+            fileobj.close()
+            os.unlink(name)
+
+    def test_dialect_apply(self):
+        class testA(csv.excel):
+            delimiter = "\t"
+        class testB(csv.excel):
+            delimiter = ":"
+        class testC(csv.excel):
+            delimiter = "|"
+
+        csv.register_dialect('testC', testC)
+        try:
+            fd, name = tempfile.mkstemp()
+            fileobj = os.fdopen(fd, "w+b")
+            try:
+                writer = csv.writer(fileobj)
+                writer.writerow([1,2,3])
+                fileobj.seek(0)
+                self.assertEqual(fileobj.read(), "1,2,3\r\n")
+            finally:
+                fileobj.close()
+                os.unlink(name)
+
+            fd, name = tempfile.mkstemp()
+            fileobj = os.fdopen(fd, "w+b")
+            try:
+                writer = csv.writer(fileobj, testA)
+                writer.writerow([1,2,3])
+                fileobj.seek(0)
+                self.assertEqual(fileobj.read(), "1\t2\t3\r\n")
+            finally:
+                fileobj.close()
+                os.unlink(name)
+
+            fd, name = tempfile.mkstemp()
+            fileobj = os.fdopen(fd, "w+b")
+            try:
+                writer = csv.writer(fileobj, dialect=testB())
+                writer.writerow([1,2,3])
+                fileobj.seek(0)
+                self.assertEqual(fileobj.read(), "1:2:3\r\n")
+            finally:
+                fileobj.close()
+                os.unlink(name)
+
+            fd, name = tempfile.mkstemp()
+            fileobj = os.fdopen(fd, "w+b")
+            try:
+                writer = csv.writer(fileobj, dialect='testC')
+                writer.writerow([1,2,3])
+                fileobj.seek(0)
+                self.assertEqual(fileobj.read(), "1|2|3\r\n")
+            finally:
+                fileobj.close()
+                os.unlink(name)
+
+            fd, name = tempfile.mkstemp()
+            fileobj = os.fdopen(fd, "w+b")
+            try:
+                writer = csv.writer(fileobj, dialect=testA, delimiter=';')
+                writer.writerow([1,2,3])
+                fileobj.seek(0)
+                self.assertEqual(fileobj.read(), "1;2;3\r\n")
+            finally:
+                fileobj.close()
+                os.unlink(name)
+
+        finally:
+            csv.unregister_dialect('testC')
+
+    def test_bad_dialect(self):
+        # Unknown parameter
+        self.assertRaises(TypeError, csv.reader, [], bad_attr = 0)
+        # Bad values
+        self.assertRaises(TypeError, csv.reader, [], delimiter = None)
+        self.assertRaises(TypeError, csv.reader, [], quoting = -1)
+        self.assertRaises(TypeError, csv.reader, [], quoting = 100)
+
+class TestCsvBase(unittest.TestCase):
+    def readerAssertEqual(self, input, expected_result):
+        fd, name = tempfile.mkstemp()
+        fileobj = os.fdopen(fd, "w+b")
+        try:
+            fileobj.write(input)
+            fileobj.seek(0)
+            reader = csv.reader(fileobj, dialect = self.dialect)
+            fields = list(reader)
+            self.assertEqual(fields, expected_result)
+        finally:
+            fileobj.close()
+            os.unlink(name)
+
+    def writerAssertEqual(self, input, expected_result):
+        fd, name = tempfile.mkstemp()
+        fileobj = os.fdopen(fd, "w+b")
+        try:
+            writer = csv.writer(fileobj, dialect = self.dialect)
+            writer.writerows(input)
+            fileobj.seek(0)
+            self.assertEqual(fileobj.read(), expected_result)
+        finally:
+            fileobj.close()
+            os.unlink(name)
+
+class TestDialectExcel(TestCsvBase):
+    dialect = 'excel'
+
+    def test_single(self):
+        self.readerAssertEqual('abc', [['abc']])
+
+    def test_simple(self):
+        self.readerAssertEqual('1,2,3,4,5', [['1','2','3','4','5']])
+
+    def test_blankline(self):
+        self.readerAssertEqual('', [])
+
+    def test_empty_fields(self):
+        self.readerAssertEqual(',', [['', '']])
+
+    def test_singlequoted(self):
+        self.readerAssertEqual('""', [['']])
+
+    def test_singlequoted_left_empty(self):
+        self.readerAssertEqual('"",', [['','']])
+
+    def test_singlequoted_right_empty(self):
+        self.readerAssertEqual(',""', [['','']])
+
+    def test_single_quoted_quote(self):
+        self.readerAssertEqual('""""', [['"']])
+
+    def test_quoted_quotes(self):
+        self.readerAssertEqual('""""""', [['""']])
+
+    def test_inline_quote(self):
+        self.readerAssertEqual('a""b', [['a""b']])
+
+    def test_inline_quotes(self):
+        self.readerAssertEqual('a"b"c', [['a"b"c']])
+
+    def test_quotes_and_more(self):
+        self.readerAssertEqual('"a"b', [['ab']])
+
+    def test_lone_quote(self):
+        self.readerAssertEqual('a"b', [['a"b']])
+
+    def test_quote_and_quote(self):
+        self.readerAssertEqual('"a" "b"', [['a "b"']])
+
+    def test_space_and_quote(self):
+        self.readerAssertEqual(' "a"', [[' "a"']])
+
+    def test_quoted(self):
+        self.readerAssertEqual('1,2,3,"I think, therefore I am",5,6',
+                               [['1', '2', '3',
+                                 'I think, therefore I am',
+                                 '5', '6']])
+
+    def test_quoted_quote(self):
+        self.readerAssertEqual('1,2,3,"""I see,"" said the blind man","as he picked up his hammer and saw"',
+                               [['1', '2', '3',
+                                 '"I see," said the blind man',
+                                 'as he picked up his hammer and saw']])
+
+    def test_quoted_nl(self):
+        input = '''\
+1,2,3,"""I see,""
+said the blind man","as he picked up his
+hammer and saw"
+9,8,7,6'''
+        self.readerAssertEqual(input,
+                               [['1', '2', '3',
+                                   '"I see,"\nsaid the blind man',
+                                   'as he picked up his\nhammer and saw'],
+                                ['9','8','7','6']])
+
+    def test_dubious_quote(self):
+        self.readerAssertEqual('12,12,1",', [['12', '12', '1"', '']])
+
+    def test_null(self):
+        self.writerAssertEqual([], '')
+
+    def test_single(self):
+        self.writerAssertEqual([['abc']], 'abc\r\n')
+
+    def test_simple(self):
+        self.writerAssertEqual([[1, 2, 'abc', 3, 4]], '1,2,abc,3,4\r\n')
+
+    def test_quotes(self):
+        self.writerAssertEqual([[1, 2, 'a"bc"', 3, 4]], '1,2,"a""bc""",3,4\r\n')
+
+    def test_quote_fieldsep(self):
+        self.writerAssertEqual([['abc,def']], '"abc,def"\r\n')
+
+    def test_newlines(self):
+        self.writerAssertEqual([[1, 2, 'a\nbc', 3, 4]], '1,2,"a\nbc",3,4\r\n')
+
+class EscapedExcel(csv.excel):
+    quoting = csv.QUOTE_NONE
+    escapechar = '\\'
+
+class TestEscapedExcel(TestCsvBase):
+    dialect = EscapedExcel()
+
+    def test_escape_fieldsep(self):
+        self.writerAssertEqual([['abc,def']], 'abc\\,def\r\n')
+
+    def test_read_escape_fieldsep(self):
+        self.readerAssertEqual('abc\\,def\r\n', [['abc,def']])
+
+class QuotedEscapedExcel(csv.excel):
+    quoting = csv.QUOTE_NONNUMERIC
+    escapechar = '\\'
+
+class TestQuotedEscapedExcel(TestCsvBase):
+    dialect = QuotedEscapedExcel()
+
+    def test_write_escape_fieldsep(self):
+        self.writerAssertEqual([['abc,def']], '"abc,def"\r\n')
+
+    def test_read_escape_fieldsep(self):
+        self.readerAssertEqual('"abc\\,def"\r\n', [['abc,def']])
+
+class TestDictFields(unittest.TestCase):
+    ### "long" means the row is longer than the number of fieldnames
+    ### "short" means there are fewer elements in the row than fieldnames
+    def test_write_simple_dict(self):
+        fd, name = tempfile.mkstemp()
+        fileobj = os.fdopen(fd, "w+b")
+        try:
+            writer = csv.DictWriter(fileobj, fieldnames = ["f1", "f2", "f3"])
+            writer.writerow({"f1": 10, "f3": "abc"})
+            fileobj.seek(0)
+            self.assertEqual(fileobj.read(), "10,,abc\r\n")
+        finally:
+            fileobj.close()
+            os.unlink(name)
+
+    def test_write_no_fields(self):
+        fileobj = StringIO()
+        self.assertRaises(TypeError, csv.DictWriter, fileobj)
+
+    def test_read_dict_fields(self):
+        fd, name = tempfile.mkstemp()
+        fileobj = os.fdopen(fd, "w+b")
+        try:
+            fileobj.write("1,2,abc\r\n")
+            fileobj.seek(0)
+            reader = csv.DictReader(fileobj,
+                                    fieldnames=["f1", "f2", "f3"])
+            self.assertEqual(reader.next(), {"f1": '1', "f2": '2', "f3": 'abc'})
+        finally:
+            fileobj.close()
+            os.unlink(name)
+
+    def test_read_dict_no_fieldnames(self):
+        fd, name = tempfile.mkstemp()
+        fileobj = os.fdopen(fd, "w+b")
+        try:
+            fileobj.write("f1,f2,f3\r\n1,2,abc\r\n")
+            fileobj.seek(0)
+            reader = csv.DictReader(fileobj)
+            self.assertEqual(reader.next(), {"f1": '1', "f2": '2', "f3": 'abc'})
+        finally:
+            fileobj.close()
+            os.unlink(name)
+
+    def test_read_long(self):
+        fd, name = tempfile.mkstemp()
+        fileobj = os.fdopen(fd, "w+b")
+        try:
+            fileobj.write("1,2,abc,4,5,6\r\n")
+            fileobj.seek(0)
+            reader = csv.DictReader(fileobj,
+                                    fieldnames=["f1", "f2"])
+            self.assertEqual(reader.next(), {"f1": '1', "f2": '2',
+                                             None: ["abc", "4", "5", "6"]})
+        finally:
+            fileobj.close()
+            os.unlink(name)
+
+    def test_read_long_with_rest(self):
+        fd, name = tempfile.mkstemp()
+        fileobj = os.fdopen(fd, "w+b")
+        try:
+            fileobj.write("1,2,abc,4,5,6\r\n")
+            fileobj.seek(0)
+            reader = csv.DictReader(fileobj,
+                                    fieldnames=["f1", "f2"], restkey="_rest")
+            self.assertEqual(reader.next(), {"f1": '1', "f2": '2',
+                                             "_rest": ["abc", "4", "5", "6"]})
+        finally:
+            fileobj.close()
+            os.unlink(name)
+
+    def test_read_long_with_rest_no_fieldnames(self):
+        fd, name = tempfile.mkstemp()
+        fileobj = os.fdopen(fd, "w+b")
+        try:
+            fileobj.write("f1,f2\r\n1,2,abc,4,5,6\r\n")
+            fileobj.seek(0)
+            reader = csv.DictReader(fileobj, restkey="_rest")
+            self.assertEqual(reader.next(), {"f1": '1', "f2": '2',
+                                             "_rest": ["abc", "4", "5", "6"]})
+        finally:
+            fileobj.close()
+            os.unlink(name)
+
+    def test_read_short(self):
+        fd, name = tempfile.mkstemp()
+        fileobj = os.fdopen(fd, "w+b")
+        try:
+            fileobj.write("1,2,abc,4,5,6\r\n1,2,abc\r\n")
+            fileobj.seek(0)
+            reader = csv.DictReader(fileobj,
+                                    fieldnames="1 2 3 4 5 6".split(),
+                                    restval="DEFAULT")
+            self.assertEqual(reader.next(), {"1": '1', "2": '2', "3": 'abc',
+                                             "4": '4', "5": '5', "6": '6'})
+            self.assertEqual(reader.next(), {"1": '1', "2": '2', "3": 'abc',
+                                             "4": 'DEFAULT', "5": 'DEFAULT',
+                                             "6": 'DEFAULT'})
+        finally:
+            fileobj.close()
+            os.unlink(name)
+
+    def test_read_multi(self):
+        sample = [
+            '2147483648,43.0e12,17,abc,def\r\n',
+            '147483648,43.0e2,17,abc,def\r\n',
+            '47483648,43.0,170,abc,def\r\n'
+            ]
+
+        reader = csv.DictReader(sample,
+                                fieldnames="i1 float i2 s1 s2".split())
+        self.assertEqual(reader.next(), {"i1": '2147483648',
+                                         "float": '43.0e12',
+                                         "i2": '17',
+                                         "s1": 'abc',
+                                         "s2": 'def'})
+
+    def test_read_with_blanks(self):
+        reader = csv.DictReader(["1,2,abc,4,5,6\r\n","\r\n",
+                                 "1,2,abc,4,5,6\r\n"],
+                                fieldnames="1 2 3 4 5 6".split())
+        self.assertEqual(reader.next(), {"1": '1', "2": '2', "3": 'abc',
+                                         "4": '4', "5": '5', "6": '6'})
+        self.assertEqual(reader.next(), {"1": '1', "2": '2', "3": 'abc',
+                                         "4": '4', "5": '5', "6": '6'})
+
+    def test_read_semi_sep(self):
+        reader = csv.DictReader(["1;2;abc;4;5;6\r\n"],
+                                fieldnames="1 2 3 4 5 6".split(),
+                                delimiter=';')
+        self.assertEqual(reader.next(), {"1": '1', "2": '2', "3": 'abc',
+                                         "4": '4', "5": '5', "6": '6'})
+
+class TestArrayWrites(unittest.TestCase):
+    def test_int_write(self):
+        import array
+        contents = [(20-i) for i in range(20)]
+        a = array.array('i', contents)
+
+        fd, name = tempfile.mkstemp()
+        fileobj = os.fdopen(fd, "w+b")
+        try:
+            writer = csv.writer(fileobj, dialect="excel")
+            writer.writerow(a)
+            expected = ",".join([str(i) for i in a])+"\r\n"
+            fileobj.seek(0)
+            self.assertEqual(fileobj.read(), expected)
+        finally:
+            fileobj.close()
+            os.unlink(name)
+
+    def test_double_write(self):
+        import array
+        contents = [(20-i)*0.1 for i in range(20)]
+        a = array.array('d', contents)
+        fd, name = tempfile.mkstemp()
+        fileobj = os.fdopen(fd, "w+b")
+        try:
+            writer = csv.writer(fileobj, dialect="excel")
+            writer.writerow(a)
+            expected = ",".join([str(i) for i in a])+"\r\n"
+            fileobj.seek(0)
+            self.assertEqual(fileobj.read(), expected)
+        finally:
+            fileobj.close()
+            os.unlink(name)
+
+    def test_float_write(self):
+        import array
+        contents = [(20-i)*0.1 for i in range(20)]
+        a = array.array('f', contents)
+        fd, name = tempfile.mkstemp()
+        fileobj = os.fdopen(fd, "w+b")
+        try:
+            writer = csv.writer(fileobj, dialect="excel")
+            writer.writerow(a)
+            expected = ",".join([str(i) for i in a])+"\r\n"
+            fileobj.seek(0)
+            self.assertEqual(fileobj.read(), expected)
+        finally:
+            fileobj.close()
+            os.unlink(name)
+
+    def test_char_write(self):
+        import array, string
+        a = array.array('c', string.letters)
+        fd, name = tempfile.mkstemp()
+        fileobj = os.fdopen(fd, "w+b")
+        try:
+            writer = csv.writer(fileobj, dialect="excel")
+            writer.writerow(a)
+            expected = ",".join(a)+"\r\n"
+            fileobj.seek(0)
+            self.assertEqual(fileobj.read(), expected)
+        finally:
+            fileobj.close()
+            os.unlink(name)
+
+class TestDialectValidity(unittest.TestCase):
+    def test_quoting(self):
+        class mydialect(csv.Dialect):
+            delimiter = ";"
+            escapechar = '\\'
+            doublequote = False
+            skipinitialspace = True
+            lineterminator = '\r\n'
+            quoting = csv.QUOTE_NONE
+        d = mydialect()
+
+        mydialect.quoting = None
+        self.assertRaises(csv.Error, mydialect)
+
+        mydialect.doublequote = True
+        mydialect.quoting = csv.QUOTE_ALL
+        mydialect.quotechar = '"'
+        d = mydialect()
+
+        mydialect.quotechar = "''"
+        self.assertRaises(csv.Error, mydialect)
+
+        mydialect.quotechar = 4
+        self.assertRaises(csv.Error, mydialect)
+
+    def test_delimiter(self):
+        class mydialect(csv.Dialect):
+            delimiter = ";"
+            escapechar = '\\'
+            doublequote = False
+            skipinitialspace = True
+            lineterminator = '\r\n'
+            quoting = csv.QUOTE_NONE
+        d = mydialect()
+
+        mydialect.delimiter = ":::"
+        self.assertRaises(csv.Error, mydialect)
+
+        mydialect.delimiter = 4
+        self.assertRaises(csv.Error, mydialect)
+
+    def test_lineterminator(self):
+        class mydialect(csv.Dialect):
+            delimiter = ";"
+            escapechar = '\\'
+            doublequote = False
+            skipinitialspace = True
+            lineterminator = '\r\n'
+            quoting = csv.QUOTE_NONE
+        d = mydialect()
+
+        mydialect.lineterminator = ":::"
+        d = mydialect()
+
+        mydialect.lineterminator = 4
+        self.assertRaises(csv.Error, mydialect)
+
+
+class TestSniffer(unittest.TestCase):
+    sample1 = """\
+Harry's, Arlington Heights, IL, 2/1/03, Kimi Hayes
+Shark City, Glendale Heights, IL, 12/28/02, Prezence
+Tommy's Place, Blue Island, IL, 12/28/02, Blue Sunday/White Crow
+Stonecutters Seafood and Chop House, Lemont, IL, 12/19/02, Week Back
+"""
+    sample2 = """\
+'Harry''s':'Arlington Heights':'IL':'2/1/03':'Kimi Hayes'
+'Shark City':'Glendale Heights':'IL':'12/28/02':'Prezence'
+'Tommy''s Place':'Blue Island':'IL':'12/28/02':'Blue Sunday/White Crow'
+'Stonecutters Seafood and Chop House':'Lemont':'IL':'12/19/02':'Week Back'
+"""
+    header = '''\
+"venue","city","state","date","performers"
+'''
+    sample3 = '''\
+05/05/03?05/05/03?05/05/03?05/05/03?05/05/03?05/05/03
+05/05/03?05/05/03?05/05/03?05/05/03?05/05/03?05/05/03
+05/05/03?05/05/03?05/05/03?05/05/03?05/05/03?05/05/03
+'''
+
+    sample4 = '''\
+2147483648;43.0e12;17;abc;def
+147483648;43.0e2;17;abc;def
+47483648;43.0;170;abc;def
+'''
+
+    sample5 = "aaa\tbbb\r\nAAA\t\r\nBBB\t\r\n"
+    sample6 = "a|b|c\r\nd|e|f\r\n"
+    sample7 = "'a'|'b'|'c'\r\n'd'|e|f\r\n"
+
+    def test_has_header(self):
+        sniffer = csv.Sniffer()
+        self.assertEqual(sniffer.has_header(self.sample1), False)
+        self.assertEqual(sniffer.has_header(self.header+self.sample1), True)
+
+    def test_sniff(self):
+        sniffer = csv.Sniffer()
+        dialect = sniffer.sniff(self.sample1)
+        self.assertEqual(dialect.delimiter, ",")
+        self.assertEqual(dialect.quotechar, '"')
+        self.assertEqual(dialect.skipinitialspace, True)
+
+        dialect = sniffer.sniff(self.sample2)
+        self.assertEqual(dialect.delimiter, ":")
+        self.assertEqual(dialect.quotechar, "'")
+        self.assertEqual(dialect.skipinitialspace, False)
+
+    def test_delimiters(self):
+        sniffer = csv.Sniffer()
+        dialect = sniffer.sniff(self.sample3)
+        # given that all three lines in sample3 are equal,
+        # I think that any character could have been 'guessed' as the
+        # delimiter, depending on dictionary order
+        self.assert_(dialect.delimiter in self.sample3)
+        dialect = sniffer.sniff(self.sample3, delimiters="?,")
+        self.assertEqual(dialect.delimiter, "?")
+        dialect = sniffer.sniff(self.sample3, delimiters="/,")
+        self.assertEqual(dialect.delimiter, "/")
+        dialect = sniffer.sniff(self.sample4)
+        self.assertEqual(dialect.delimiter, ";")
+        dialect = sniffer.sniff(self.sample5)
+        self.assertEqual(dialect.delimiter, "\t")
+        dialect = sniffer.sniff(self.sample6)
+        self.assertEqual(dialect.delimiter, "|")
+        dialect = sniffer.sniff(self.sample7)
+        self.assertEqual(dialect.delimiter, "|")
+        self.assertEqual(dialect.quotechar, "'")
+
+if not hasattr(sys, "gettotalrefcount"):
+    if test_support.verbose: print "*** skipping leakage tests ***"
+else:
+    class NUL:
+        def write(s, *args):
+            pass
+        writelines = write
+
+    class TestLeaks(unittest.TestCase):
+        def test_create_read(self):
+            delta = 0
+            lastrc = sys.gettotalrefcount()
+            for i in xrange(20):
+                gc.collect()
+                self.assertEqual(gc.garbage, [])
+                rc = sys.gettotalrefcount()
+                csv.reader(["a,b,c\r\n"])
+                csv.reader(["a,b,c\r\n"])
+                csv.reader(["a,b,c\r\n"])
+                delta = rc-lastrc
+                lastrc = rc
+            # if csv.reader() leaks, last delta should be 3 or more
+            self.assertEqual(delta < 3, True)
+
+        def test_create_write(self):
+            delta = 0
+            lastrc = sys.gettotalrefcount()
+            s = NUL()
+            for i in xrange(20):
+                gc.collect()
+                self.assertEqual(gc.garbage, [])
+                rc = sys.gettotalrefcount()
+                csv.writer(s)
+                csv.writer(s)
+                csv.writer(s)
+                delta = rc-lastrc
+                lastrc = rc
+            # if csv.writer() leaks, last delta should be 3 or more
+            self.assertEqual(delta < 3, True)
+
+        def test_read(self):
+            delta = 0
+            rows = ["a,b,c\r\n"]*5
+            lastrc = sys.gettotalrefcount()
+            for i in xrange(20):
+                gc.collect()
+                self.assertEqual(gc.garbage, [])
+                rc = sys.gettotalrefcount()
+                rdr = csv.reader(rows)
+                for row in rdr:
+                    pass
+                delta = rc-lastrc
+                lastrc = rc
+            # if reader leaks during read, delta should be 5 or more
+            self.assertEqual(delta < 5, True)
+
+        def test_write(self):
+            delta = 0
+            rows = [[1,2,3]]*5
+            s = NUL()
+            lastrc = sys.gettotalrefcount()
+            for i in xrange(20):
+                gc.collect()
+                self.assertEqual(gc.garbage, [])
+                rc = sys.gettotalrefcount()
+                writer = csv.writer(s)
+                for row in rows:
+                    writer.writerow(row)
+                delta = rc-lastrc
+                lastrc = rc
+            # if writer leaks during write, last delta should be 5 or more
+            self.assertEqual(delta < 5, True)
+
+# commented out for now - csv module doesn't yet support Unicode
+## class TestUnicode(unittest.TestCase):
+##     def test_unicode_read(self):
+##         import codecs
+##         f = codecs.EncodedFile(StringIO("Martin von Löwis,"
+##                                         "Marc André Lemburg,"
+##                                         "Guido van Rossum,"
+##                                         "François Pinard\r\n"),
+##                                data_encoding='iso-8859-1')
+##         reader = csv.reader(f)
+##         self.assertEqual(list(reader), [[u"Martin von Löwis",
+##                                          u"Marc André Lemburg",
+##                                          u"Guido van Rossum",
+##                                          u"François Pinardn"]])
+
+def test_main():
+    mod = sys.modules[__name__]
+    test_support.run_unittest(
+        *[getattr(mod, name) for name in dir(mod) if name.startswith('Test')]
+    )
+
+if __name__ == '__main__':
+    test_main()

Added: vendor/Python/current/Lib/test/test_ctypes.py
===================================================================
--- vendor/Python/current/Lib/test/test_ctypes.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_ctypes.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,12 @@
+import unittest
+
+from test.test_support import run_suite
+import ctypes.test
+
+def test_main():
+    skipped, testcases = ctypes.test.get_tests(ctypes.test, "test_*.py", verbosity=0)
+    suites = [unittest.makeSuite(t) for t in testcases]
+    run_suite(unittest.TestSuite(suites))
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_curses.py
===================================================================
--- vendor/Python/current/Lib/test/test_curses.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_curses.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,275 @@
+#
+# Test script for the curses module
+#
+# This script doesn't actually display anything very coherent. but it
+# does call every method and function.
+#
+# Functions not tested: {def,reset}_{shell,prog}_mode, getch(), getstr(),
+# init_color()
+# Only called, not tested: getmouse(), ungetmouse()
+#
+
+import curses, sys, tempfile, os
+import curses.panel
+
+# Optionally test curses module.  This currently requires that the
+# 'curses' resource be given on the regrtest command line using the -u
+# option.  If not available, nothing after this line will be executed.
+
+from test.test_support import requires, TestSkipped
+requires('curses')
+
+# XXX: if newterm was supported we could use it instead of initscr and not exit
+term = os.environ.get('TERM')
+if not term or term == 'unknown':
+    raise TestSkipped, "$TERM=%r, calling initscr() may cause exit" % term
+
+if sys.platform == "cygwin":
+    raise TestSkipped("cygwin's curses mostly just hangs")
+
+def window_funcs(stdscr):
+    "Test the methods of windows"
+    win = curses.newwin(10,10)
+    win = curses.newwin(5,5, 5,5)
+    win2 = curses.newwin(15,15, 5,5)
+
+    for meth in [stdscr.addch, stdscr.addstr]:
+        for args in [('a'), ('a', curses.A_BOLD),
+                     (4,4, 'a'), (5,5, 'a', curses.A_BOLD)]:
+            meth(*args)
+
+    for meth in [stdscr.box, stdscr.clear, stdscr.clrtobot,
+                 stdscr.clrtoeol, stdscr.cursyncup, stdscr.delch,
+                 stdscr.deleteln, stdscr.erase, stdscr.getbegyx,
+                 stdscr.getbkgd, stdscr.getkey, stdscr.getmaxyx,
+                 stdscr.getparyx, stdscr.getyx, stdscr.inch,
+                 stdscr.insertln, stdscr.instr, stdscr.is_wintouched,
+                 win.noutrefresh, stdscr.redrawwin, stdscr.refresh,
+                 stdscr.standout, stdscr.standend, stdscr.syncdown,
+                 stdscr.syncup, stdscr.touchwin, stdscr.untouchwin]:
+        meth()
+
+    stdscr.addnstr('1234', 3)
+    stdscr.addnstr('1234', 3, curses.A_BOLD)
+    stdscr.addnstr(4,4, '1234', 3)
+    stdscr.addnstr(5,5, '1234', 3, curses.A_BOLD)
+
+    stdscr.attron(curses.A_BOLD)
+    stdscr.attroff(curses.A_BOLD)
+    stdscr.attrset(curses.A_BOLD)
+    stdscr.bkgd(' ')
+    stdscr.bkgd(' ', curses.A_REVERSE)
+    stdscr.bkgdset(' ')
+    stdscr.bkgdset(' ', curses.A_REVERSE)
+
+    win.border(65, 66, 67, 68,
+               69, 70, 71, 72)
+    win.border('|', '!', '-', '_',
+               '+', '\\', '#', '/')
+    try:
+        win.border(65, 66, 67, 68,
+                   69, [], 71, 72)
+    except TypeError:
+        pass
+    else:
+        raise RuntimeError, "Expected win.border() to raise TypeError"
+
+    stdscr.clearok(1)
+
+    win4 = stdscr.derwin(2,2)
+    win4 = stdscr.derwin(1,1, 5,5)
+    win4.mvderwin(9,9)
+
+    stdscr.echochar('a')
+    stdscr.echochar('a', curses.A_BOLD)
+    stdscr.hline('-', 5)
+    stdscr.hline('-', 5, curses.A_BOLD)
+    stdscr.hline(1,1,'-', 5)
+    stdscr.hline(1,1,'-', 5, curses.A_BOLD)
+
+    stdscr.idcok(1)
+    stdscr.idlok(1)
+    stdscr.immedok(1)
+    stdscr.insch('c')
+    stdscr.insdelln(1)
+    stdscr.insnstr('abc', 3)
+    stdscr.insnstr('abc', 3, curses.A_BOLD)
+    stdscr.insnstr(5, 5, 'abc', 3)
+    stdscr.insnstr(5, 5, 'abc', 3, curses.A_BOLD)
+
+    stdscr.insstr('def')
+    stdscr.insstr('def', curses.A_BOLD)
+    stdscr.insstr(5, 5, 'def')
+    stdscr.insstr(5, 5, 'def', curses.A_BOLD)
+    stdscr.is_linetouched(0)
+    stdscr.keypad(1)
+    stdscr.leaveok(1)
+    stdscr.move(3,3)
+    win.mvwin(2,2)
+    stdscr.nodelay(1)
+    stdscr.notimeout(1)
+    win2.overlay(win)
+    win2.overwrite(win)
+    win2.overlay(win, 1, 2, 3, 3, 2, 1)
+    win2.overwrite(win, 1, 2, 3, 3, 2, 1)
+    stdscr.redrawln(1,2)
+
+    stdscr.scrollok(1)
+    stdscr.scroll()
+    stdscr.scroll(2)
+    stdscr.scroll(-3)
+
+    stdscr.move(12, 2)
+    stdscr.setscrreg(10,15)
+    win3 = stdscr.subwin(10,10)
+    win3 = stdscr.subwin(10,10, 5,5)
+    stdscr.syncok(1)
+    stdscr.timeout(5)
+    stdscr.touchline(5,5)
+    stdscr.touchline(5,5,0)
+    stdscr.vline('a', 3)
+    stdscr.vline('a', 3, curses.A_STANDOUT)
+    stdscr.vline(1,1, 'a', 3)
+    stdscr.vline(1,1, 'a', 3, curses.A_STANDOUT)
+
+    if hasattr(curses, 'resize'):
+        stdscr.resize()
+    if hasattr(curses, 'enclose'):
+        stdscr.enclose()
+
+
+def module_funcs(stdscr):
+    "Test module-level functions"
+
+    for func in [curses.baudrate, curses.beep, curses.can_change_color,
+                 curses.cbreak, curses.def_prog_mode, curses.doupdate,
+                 curses.filter, curses.flash, curses.flushinp,
+                 curses.has_colors, curses.has_ic, curses.has_il,
+                 curses.isendwin, curses.killchar, curses.longname,
+                 curses.nocbreak, curses.noecho, curses.nonl,
+                 curses.noqiflush, curses.noraw,
+                 curses.reset_prog_mode, curses.termattrs,
+                 curses.termname, curses.erasechar, curses.getsyx]:
+        func()
+
+    # Functions that actually need arguments
+    if curses.tigetstr("cnorm"):
+        curses.curs_set(1)
+    curses.delay_output(1)
+    curses.echo() ; curses.echo(1)
+
+    f = tempfile.TemporaryFile()
+    stdscr.putwin(f)
+    f.seek(0)
+    curses.getwin(f)
+    f.close()
+
+    curses.halfdelay(1)
+    curses.intrflush(1)
+    curses.meta(1)
+    curses.napms(100)
+    curses.newpad(50,50)
+    win = curses.newwin(5,5)
+    win = curses.newwin(5,5, 1,1)
+    curses.nl() ; curses.nl(1)
+    curses.putp('abc')
+    curses.qiflush()
+    curses.raw() ; curses.raw(1)
+    curses.setsyx(5,5)
+    curses.tigetflag('hc')
+    curses.tigetnum('co')
+    curses.tigetstr('cr')
+    curses.tparm('cr')
+    curses.typeahead(sys.__stdin__.fileno())
+    curses.unctrl('a')
+    curses.ungetch('a')
+    curses.use_env(1)
+
+    # Functions only available on a few platforms
+    if curses.has_colors():
+        curses.start_color()
+        curses.init_pair(2, 1,1)
+        curses.color_content(1)
+        curses.color_pair(2)
+        curses.pair_content(curses.COLOR_PAIRS - 1)
+        curses.pair_number(0)
+
+        if hasattr(curses, 'use_default_colors'):
+            curses.use_default_colors()
+
+    if hasattr(curses, 'keyname'):
+        curses.keyname(13)
+
+    if hasattr(curses, 'has_key'):
+        curses.has_key(13)
+
+    if hasattr(curses, 'getmouse'):
+        (availmask, oldmask) = curses.mousemask(curses.BUTTON1_PRESSED)
+        # availmask indicates that mouse stuff not available.
+        if availmask != 0:
+            curses.mouseinterval(10)
+            # just verify these don't cause errors
+            m = curses.getmouse()
+            curses.ungetmouse(*m)
+
+    if hasattr(curses, 'is_term_resized'):
+        curses.is_term_resized(*stdscr.getmaxyx())
+    if hasattr(curses, 'resizeterm'):
+        curses.resizeterm(*stdscr.getmaxyx())
+    if hasattr(curses, 'resize_term'):
+        curses.resize_term(*stdscr.getmaxyx())
+
+def unit_tests():
+    from curses import ascii
+    for ch, expected in [('a', 'a'), ('A', 'A'),
+                         (';', ';'), (' ', ' '),
+                         ('\x7f', '^?'), ('\n', '^J'), ('\0', '^@'),
+                         # Meta-bit characters
+                         ('\x8a', '!^J'), ('\xc1', '!A'),
+                         ]:
+        if ascii.unctrl(ch) != expected:
+            print 'curses.unctrl fails on character', repr(ch)
+
+
+def test_userptr_without_set(stdscr):
+    w = curses.newwin(10, 10)
+    p = curses.panel.new_panel(w)
+    # try to access userptr() before calling set_userptr() -- segfaults
+    try:
+        p.userptr()
+        raise RuntimeError, 'userptr should fail since not set'
+    except curses.panel.error:
+        pass
+
+def test_resize_term(stdscr):
+    if hasattr(curses, 'resizeterm'):
+        lines, cols = curses.LINES, curses.COLS
+        curses.resizeterm(lines - 1, cols + 1)
+        
+        if curses.LINES != lines - 1 or curses.COLS != cols + 1:
+            raise RuntimeError, "Expected resizeterm to update LINES and COLS"
+
+def main(stdscr):
+    curses.savetty()
+    try:
+        module_funcs(stdscr)
+        window_funcs(stdscr)
+        test_userptr_without_set(stdscr)
+        test_resize_term(stdscr)
+    finally:
+        curses.resetty()
+
+if __name__ == '__main__':
+    curses.wrapper(main)
+    unit_tests()
+else:
+    try:
+        # testing setupterm() inside initscr/endwin
+        # causes terminal breakage
+        curses.setupterm(fd=sys.__stdout__.fileno())
+        stdscr = curses.initscr()
+        main(stdscr)
+    finally:
+        curses.endwin()
+
+    unit_tests()

Added: vendor/Python/current/Lib/test/test_datetime.py
===================================================================
--- vendor/Python/current/Lib/test/test_datetime.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_datetime.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,3287 @@
+"""Test date/time type.
+
+See http://www.zope.org/Members/fdrake/DateTimeWiki/TestCases
+"""
+
+import os
+import sys
+import pickle
+import cPickle
+import unittest
+
+from test import test_support
+
+from datetime import MINYEAR, MAXYEAR
+from datetime import timedelta
+from datetime import tzinfo
+from datetime import time
+from datetime import date, datetime
+
+pickle_choices = [(pickler, unpickler, proto)
+                  for pickler in pickle, cPickle
+                  for unpickler in pickle, cPickle
+                  for proto in range(3)]
+assert len(pickle_choices) == 2*2*3
+
+# An arbitrary collection of objects of non-datetime types, for testing
+# mixed-type comparisons.
+OTHERSTUFF = (10, 10L, 34.5, "abc", {}, [], ())
+
+
+#############################################################################
+# module tests
+
+class TestModule(unittest.TestCase):
+
+    def test_constants(self):
+        import datetime
+        self.assertEqual(datetime.MINYEAR, 1)
+        self.assertEqual(datetime.MAXYEAR, 9999)
+
+#############################################################################
+# tzinfo tests
+
+class FixedOffset(tzinfo):
+    def __init__(self, offset, name, dstoffset=42):
+        if isinstance(offset, int):
+            offset = timedelta(minutes=offset)
+        if isinstance(dstoffset, int):
+            dstoffset = timedelta(minutes=dstoffset)
+        self.__offset = offset
+        self.__name = name
+        self.__dstoffset = dstoffset
+    def __repr__(self):
+        return self.__name.lower()
+    def utcoffset(self, dt):
+        return self.__offset
+    def tzname(self, dt):
+        return self.__name
+    def dst(self, dt):
+        return self.__dstoffset
+
+class PicklableFixedOffset(FixedOffset):
+    def __init__(self, offset=None, name=None, dstoffset=None):
+        FixedOffset.__init__(self, offset, name, dstoffset)
+
+class TestTZInfo(unittest.TestCase):
+
+    def test_non_abstractness(self):
+        # In order to allow subclasses to get pickled, the C implementation
+        # wasn't able to get away with having __init__ raise
+        # NotImplementedError.
+        useless = tzinfo()
+        dt = datetime.max
+        self.assertRaises(NotImplementedError, useless.tzname, dt)
+        self.assertRaises(NotImplementedError, useless.utcoffset, dt)
+        self.assertRaises(NotImplementedError, useless.dst, dt)
+
+    def test_subclass_must_override(self):
+        class NotEnough(tzinfo):
+            def __init__(self, offset, name):
+                self.__offset = offset
+                self.__name = name
+        self.failUnless(issubclass(NotEnough, tzinfo))
+        ne = NotEnough(3, "NotByALongShot")
+        self.failUnless(isinstance(ne, tzinfo))
+
+        dt = datetime.now()
+        self.assertRaises(NotImplementedError, ne.tzname, dt)
+        self.assertRaises(NotImplementedError, ne.utcoffset, dt)
+        self.assertRaises(NotImplementedError, ne.dst, dt)
+
+    def test_normal(self):
+        fo = FixedOffset(3, "Three")
+        self.failUnless(isinstance(fo, tzinfo))
+        for dt in datetime.now(), None:
+            self.assertEqual(fo.utcoffset(dt), timedelta(minutes=3))
+            self.assertEqual(fo.tzname(dt), "Three")
+            self.assertEqual(fo.dst(dt), timedelta(minutes=42))
+
+    def test_pickling_base(self):
+        # There's no point to pickling tzinfo objects on their own (they
+        # carry no data), but they need to be picklable anyway else
+        # concrete subclasses can't be pickled.
+        orig = tzinfo.__new__(tzinfo)
+        self.failUnless(type(orig) is tzinfo)
+        for pickler, unpickler, proto in pickle_choices:
+            green = pickler.dumps(orig, proto)
+            derived = unpickler.loads(green)
+            self.failUnless(type(derived) is tzinfo)
+
+    def test_pickling_subclass(self):
+        # Make sure we can pickle/unpickle an instance of a subclass.
+        offset = timedelta(minutes=-300)
+        orig = PicklableFixedOffset(offset, 'cookie')
+        self.failUnless(isinstance(orig, tzinfo))
+        self.failUnless(type(orig) is PicklableFixedOffset)
+        self.assertEqual(orig.utcoffset(None), offset)
+        self.assertEqual(orig.tzname(None), 'cookie')
+        for pickler, unpickler, proto in pickle_choices:
+            green = pickler.dumps(orig, proto)
+            derived = unpickler.loads(green)
+            self.failUnless(isinstance(derived, tzinfo))
+            self.failUnless(type(derived) is PicklableFixedOffset)
+            self.assertEqual(derived.utcoffset(None), offset)
+            self.assertEqual(derived.tzname(None), 'cookie')
+
+#############################################################################
+# Base clase for testing a particular aspect of timedelta, time, date and
+# datetime comparisons.
+
+class HarmlessMixedComparison(unittest.TestCase):
+    # Test that __eq__ and __ne__ don't complain for mixed-type comparisons.
+
+    # Subclasses must define 'theclass', and theclass(1, 1, 1) must be a
+    # legit constructor.
+
+    def test_harmless_mixed_comparison(self):
+        me = self.theclass(1, 1, 1)
+
+        self.failIf(me == ())
+        self.failUnless(me != ())
+        self.failIf(() == me)
+        self.failUnless(() != me)
+
+        self.failUnless(me in [1, 20L, [], me])
+        self.failIf(me not in [1, 20L, [], me])
+
+        self.failUnless([] in [me, 1, 20L, []])
+        self.failIf([] not in [me, 1, 20L, []])
+
+    def test_harmful_mixed_comparison(self):
+        me = self.theclass(1, 1, 1)
+
+        self.assertRaises(TypeError, lambda: me < ())
+        self.assertRaises(TypeError, lambda: me <= ())
+        self.assertRaises(TypeError, lambda: me > ())
+        self.assertRaises(TypeError, lambda: me >= ())
+
+        self.assertRaises(TypeError, lambda: () < me)
+        self.assertRaises(TypeError, lambda: () <= me)
+        self.assertRaises(TypeError, lambda: () > me)
+        self.assertRaises(TypeError, lambda: () >= me)
+
+        self.assertRaises(TypeError, cmp, (), me)
+        self.assertRaises(TypeError, cmp, me, ())
+
+#############################################################################
+# timedelta tests
+
+class TestTimeDelta(HarmlessMixedComparison):
+
+    theclass = timedelta
+
+    def test_constructor(self):
+        eq = self.assertEqual
+        td = timedelta
+
+        # Check keyword args to constructor
+        eq(td(), td(weeks=0, days=0, hours=0, minutes=0, seconds=0,
+                    milliseconds=0, microseconds=0))
+        eq(td(1), td(days=1))
+        eq(td(0, 1), td(seconds=1))
+        eq(td(0, 0, 1), td(microseconds=1))
+        eq(td(weeks=1), td(days=7))
+        eq(td(days=1), td(hours=24))
+        eq(td(hours=1), td(minutes=60))
+        eq(td(minutes=1), td(seconds=60))
+        eq(td(seconds=1), td(milliseconds=1000))
+        eq(td(milliseconds=1), td(microseconds=1000))
+
+        # Check float args to constructor
+        eq(td(weeks=1.0/7), td(days=1))
+        eq(td(days=1.0/24), td(hours=1))
+        eq(td(hours=1.0/60), td(minutes=1))
+        eq(td(minutes=1.0/60), td(seconds=1))
+        eq(td(seconds=0.001), td(milliseconds=1))
+        eq(td(milliseconds=0.001), td(microseconds=1))
+
+    def test_computations(self):
+        eq = self.assertEqual
+        td = timedelta
+
+        a = td(7) # One week
+        b = td(0, 60) # One minute
+        c = td(0, 0, 1000) # One millisecond
+        eq(a+b+c, td(7, 60, 1000))
+        eq(a-b, td(6, 24*3600 - 60))
+        eq(-a, td(-7))
+        eq(+a, td(7))
+        eq(-b, td(-1, 24*3600 - 60))
+        eq(-c, td(-1, 24*3600 - 1, 999000))
+        eq(abs(a), a)
+        eq(abs(-a), a)
+        eq(td(6, 24*3600), a)
+        eq(td(0, 0, 60*1000000), b)
+        eq(a*10, td(70))
+        eq(a*10, 10*a)
+        eq(a*10L, 10*a)
+        eq(b*10, td(0, 600))
+        eq(10*b, td(0, 600))
+        eq(b*10L, td(0, 600))
+        eq(c*10, td(0, 0, 10000))
+        eq(10*c, td(0, 0, 10000))
+        eq(c*10L, td(0, 0, 10000))
+        eq(a*-1, -a)
+        eq(b*-2, -b-b)
+        eq(c*-2, -c+-c)
+        eq(b*(60*24), (b*60)*24)
+        eq(b*(60*24), (60*b)*24)
+        eq(c*1000, td(0, 1))
+        eq(1000*c, td(0, 1))
+        eq(a//7, td(1))
+        eq(b//10, td(0, 6))
+        eq(c//1000, td(0, 0, 1))
+        eq(a//10, td(0, 7*24*360))
+        eq(a//3600000, td(0, 0, 7*24*1000))
+
+    def test_disallowed_computations(self):
+        a = timedelta(42)
+
+        # Add/sub ints, longs, floats should be illegal
+        for i in 1, 1L, 1.0:
+            self.assertRaises(TypeError, lambda: a+i)
+            self.assertRaises(TypeError, lambda: a-i)
+            self.assertRaises(TypeError, lambda: i+a)
+            self.assertRaises(TypeError, lambda: i-a)
+
+        # Mul/div by float isn't supported.
+        x = 2.3
+        self.assertRaises(TypeError, lambda: a*x)
+        self.assertRaises(TypeError, lambda: x*a)
+        self.assertRaises(TypeError, lambda: a/x)
+        self.assertRaises(TypeError, lambda: x/a)
+        self.assertRaises(TypeError, lambda: a // x)
+        self.assertRaises(TypeError, lambda: x // a)
+
+        # Divison of int by timedelta doesn't make sense.
+        # Division by zero doesn't make sense.
+        for zero in 0, 0L:
+            self.assertRaises(TypeError, lambda: zero // a)
+            self.assertRaises(ZeroDivisionError, lambda: a // zero)
+
+    def test_basic_attributes(self):
+        days, seconds, us = 1, 7, 31
+        td = timedelta(days, seconds, us)
+        self.assertEqual(td.days, days)
+        self.assertEqual(td.seconds, seconds)
+        self.assertEqual(td.microseconds, us)
+
+    def test_carries(self):
+        t1 = timedelta(days=100,
+                       weeks=-7,
+                       hours=-24*(100-49),
+                       minutes=-3,
+                       seconds=12,
+                       microseconds=(3*60 - 12) * 1e6 + 1)
+        t2 = timedelta(microseconds=1)
+        self.assertEqual(t1, t2)
+
+    def test_hash_equality(self):
+        t1 = timedelta(days=100,
+                       weeks=-7,
+                       hours=-24*(100-49),
+                       minutes=-3,
+                       seconds=12,
+                       microseconds=(3*60 - 12) * 1000000)
+        t2 = timedelta()
+        self.assertEqual(hash(t1), hash(t2))
+
+        t1 += timedelta(weeks=7)
+        t2 += timedelta(days=7*7)
+        self.assertEqual(t1, t2)
+        self.assertEqual(hash(t1), hash(t2))
+
+        d = {t1: 1}
+        d[t2] = 2
+        self.assertEqual(len(d), 1)
+        self.assertEqual(d[t1], 2)
+
+    def test_pickling(self):
+        args = 12, 34, 56
+        orig = timedelta(*args)
+        for pickler, unpickler, proto in pickle_choices:
+            green = pickler.dumps(orig, proto)
+            derived = unpickler.loads(green)
+            self.assertEqual(orig, derived)
+
+    def test_compare(self):
+        t1 = timedelta(2, 3, 4)
+        t2 = timedelta(2, 3, 4)
+        self.failUnless(t1 == t2)
+        self.failUnless(t1 <= t2)
+        self.failUnless(t1 >= t2)
+        self.failUnless(not t1 != t2)
+        self.failUnless(not t1 < t2)
+        self.failUnless(not t1 > t2)
+        self.assertEqual(cmp(t1, t2), 0)
+        self.assertEqual(cmp(t2, t1), 0)
+
+        for args in (3, 3, 3), (2, 4, 4), (2, 3, 5):
+            t2 = timedelta(*args)   # this is larger than t1
+            self.failUnless(t1 < t2)
+            self.failUnless(t2 > t1)
+            self.failUnless(t1 <= t2)
+            self.failUnless(t2 >= t1)
+            self.failUnless(t1 != t2)
+            self.failUnless(t2 != t1)
+            self.failUnless(not t1 == t2)
+            self.failUnless(not t2 == t1)
+            self.failUnless(not t1 > t2)
+            self.failUnless(not t2 < t1)
+            self.failUnless(not t1 >= t2)
+            self.failUnless(not t2 <= t1)
+            self.assertEqual(cmp(t1, t2), -1)
+            self.assertEqual(cmp(t2, t1), 1)
+
+        for badarg in OTHERSTUFF:
+            self.assertEqual(t1 == badarg, False)
+            self.assertEqual(t1 != badarg, True)
+            self.assertEqual(badarg == t1, False)
+            self.assertEqual(badarg != t1, True)
+
+            self.assertRaises(TypeError, lambda: t1 <= badarg)
+            self.assertRaises(TypeError, lambda: t1 < badarg)
+            self.assertRaises(TypeError, lambda: t1 > badarg)
+            self.assertRaises(TypeError, lambda: t1 >= badarg)
+            self.assertRaises(TypeError, lambda: badarg <= t1)
+            self.assertRaises(TypeError, lambda: badarg < t1)
+            self.assertRaises(TypeError, lambda: badarg > t1)
+            self.assertRaises(TypeError, lambda: badarg >= t1)
+
+    def test_str(self):
+        td = timedelta
+        eq = self.assertEqual
+
+        eq(str(td(1)), "1 day, 0:00:00")
+        eq(str(td(-1)), "-1 day, 0:00:00")
+        eq(str(td(2)), "2 days, 0:00:00")
+        eq(str(td(-2)), "-2 days, 0:00:00")
+
+        eq(str(td(hours=12, minutes=58, seconds=59)), "12:58:59")
+        eq(str(td(hours=2, minutes=3, seconds=4)), "2:03:04")
+        eq(str(td(weeks=-30, hours=23, minutes=12, seconds=34)),
+           "-210 days, 23:12:34")
+
+        eq(str(td(milliseconds=1)), "0:00:00.001000")
+        eq(str(td(microseconds=3)), "0:00:00.000003")
+
+        eq(str(td(days=999999999, hours=23, minutes=59, seconds=59,
+                   microseconds=999999)),
+           "999999999 days, 23:59:59.999999")
+
+    def test_roundtrip(self):
+        for td in (timedelta(days=999999999, hours=23, minutes=59,
+                             seconds=59, microseconds=999999),
+                   timedelta(days=-999999999),
+                   timedelta(days=1, seconds=2, microseconds=3)):
+
+            # Verify td -> string -> td identity.
+            s = repr(td)
+            self.failUnless(s.startswith('datetime.'))
+            s = s[9:]
+            td2 = eval(s)
+            self.assertEqual(td, td2)
+
+            # Verify identity via reconstructing from pieces.
+            td2 = timedelta(td.days, td.seconds, td.microseconds)
+            self.assertEqual(td, td2)
+
+    def test_resolution_info(self):
+        self.assert_(isinstance(timedelta.min, timedelta))
+        self.assert_(isinstance(timedelta.max, timedelta))
+        self.assert_(isinstance(timedelta.resolution, timedelta))
+        self.assert_(timedelta.max > timedelta.min)
+        self.assertEqual(timedelta.min, timedelta(-999999999))
+        self.assertEqual(timedelta.max, timedelta(999999999, 24*3600-1, 1e6-1))
+        self.assertEqual(timedelta.resolution, timedelta(0, 0, 1))
+
+    def test_overflow(self):
+        tiny = timedelta.resolution
+
+        td = timedelta.min + tiny
+        td -= tiny  # no problem
+        self.assertRaises(OverflowError, td.__sub__, tiny)
+        self.assertRaises(OverflowError, td.__add__, -tiny)
+
+        td = timedelta.max - tiny
+        td += tiny  # no problem
+        self.assertRaises(OverflowError, td.__add__, tiny)
+        self.assertRaises(OverflowError, td.__sub__, -tiny)
+
+        self.assertRaises(OverflowError, lambda: -timedelta.max)
+
+    def test_microsecond_rounding(self):
+        td = timedelta
+        eq = self.assertEqual
+
+        # Single-field rounding.
+        eq(td(milliseconds=0.4/1000), td(0))    # rounds to 0
+        eq(td(milliseconds=-0.4/1000), td(0))    # rounds to 0
+        eq(td(milliseconds=0.6/1000), td(microseconds=1))
+        eq(td(milliseconds=-0.6/1000), td(microseconds=-1))
+
+        # Rounding due to contributions from more than one field.
+        us_per_hour = 3600e6
+        us_per_day = us_per_hour * 24
+        eq(td(days=.4/us_per_day), td(0))
+        eq(td(hours=.2/us_per_hour), td(0))
+        eq(td(days=.4/us_per_day, hours=.2/us_per_hour), td(microseconds=1))
+
+        eq(td(days=-.4/us_per_day), td(0))
+        eq(td(hours=-.2/us_per_hour), td(0))
+        eq(td(days=-.4/us_per_day, hours=-.2/us_per_hour), td(microseconds=-1))
+
+    def test_massive_normalization(self):
+        td = timedelta(microseconds=-1)
+        self.assertEqual((td.days, td.seconds, td.microseconds),
+                         (-1, 24*3600-1, 999999))
+
+    def test_bool(self):
+        self.failUnless(timedelta(1))
+        self.failUnless(timedelta(0, 1))
+        self.failUnless(timedelta(0, 0, 1))
+        self.failUnless(timedelta(microseconds=1))
+        self.failUnless(not timedelta(0))
+
+    def test_subclass_timedelta(self):
+
+        class T(timedelta):
+            @staticmethod
+            def from_td(td):
+                return T(td.days, td.seconds, td.microseconds)
+
+            def as_hours(self):
+                sum = (self.days * 24 +
+                       self.seconds / 3600.0 +
+                       self.microseconds / 3600e6)
+                return round(sum)
+
+        t1 = T(days=1)
+        self.assert_(type(t1) is T)
+        self.assertEqual(t1.as_hours(), 24)
+
+        t2 = T(days=-1, seconds=-3600)
+        self.assert_(type(t2) is T)
+        self.assertEqual(t2.as_hours(), -25)
+
+        t3 = t1 + t2
+        self.assert_(type(t3) is timedelta)
+        t4 = T.from_td(t3)
+        self.assert_(type(t4) is T)
+        self.assertEqual(t3.days, t4.days)
+        self.assertEqual(t3.seconds, t4.seconds)
+        self.assertEqual(t3.microseconds, t4.microseconds)
+        self.assertEqual(str(t3), str(t4))
+        self.assertEqual(t4.as_hours(), -1)
+
+#############################################################################
+# date tests
+
+class TestDateOnly(unittest.TestCase):
+    # Tests here won't pass if also run on datetime objects, so don't
+    # subclass this to test datetimes too.
+
+    def test_delta_non_days_ignored(self):
+        dt = date(2000, 1, 2)
+        delta = timedelta(days=1, hours=2, minutes=3, seconds=4,
+                          microseconds=5)
+        days = timedelta(delta.days)
+        self.assertEqual(days, timedelta(1))
+
+        dt2 = dt + delta
+        self.assertEqual(dt2, dt + days)
+
+        dt2 = delta + dt
+        self.assertEqual(dt2, dt + days)
+
+        dt2 = dt - delta
+        self.assertEqual(dt2, dt - days)
+
+        delta = -delta
+        days = timedelta(delta.days)
+        self.assertEqual(days, timedelta(-2))
+
+        dt2 = dt + delta
+        self.assertEqual(dt2, dt + days)
+
+        dt2 = delta + dt
+        self.assertEqual(dt2, dt + days)
+
+        dt2 = dt - delta
+        self.assertEqual(dt2, dt - days)
+
+class SubclassDate(date):
+    sub_var = 1
+
+class TestDate(HarmlessMixedComparison):
+    # Tests here should pass for both dates and datetimes, except for a
+    # few tests that TestDateTime overrides.
+
+    theclass = date
+
+    def test_basic_attributes(self):
+        dt = self.theclass(2002, 3, 1)
+        self.assertEqual(dt.year, 2002)
+        self.assertEqual(dt.month, 3)
+        self.assertEqual(dt.day, 1)
+
+    def test_roundtrip(self):
+        for dt in (self.theclass(1, 2, 3),
+                   self.theclass.today()):
+            # Verify dt -> string -> date identity.
+            s = repr(dt)
+            self.failUnless(s.startswith('datetime.'))
+            s = s[9:]
+            dt2 = eval(s)
+            self.assertEqual(dt, dt2)
+
+            # Verify identity via reconstructing from pieces.
+            dt2 = self.theclass(dt.year, dt.month, dt.day)
+            self.assertEqual(dt, dt2)
+
+    def test_ordinal_conversions(self):
+        # Check some fixed values.
+        for y, m, d, n in [(1, 1, 1, 1),      # calendar origin
+                           (1, 12, 31, 365),
+                           (2, 1, 1, 366),
+                           # first example from "Calendrical Calculations"
+                           (1945, 11, 12, 710347)]:
+            d = self.theclass(y, m, d)
+            self.assertEqual(n, d.toordinal())
+            fromord = self.theclass.fromordinal(n)
+            self.assertEqual(d, fromord)
+            if hasattr(fromord, "hour"):
+            # if we're checking something fancier than a date, verify
+            # the extra fields have been zeroed out
+                self.assertEqual(fromord.hour, 0)
+                self.assertEqual(fromord.minute, 0)
+                self.assertEqual(fromord.second, 0)
+                self.assertEqual(fromord.microsecond, 0)
+
+        # Check first and last days of year spottily across the whole
+        # range of years supported.
+        for year in xrange(MINYEAR, MAXYEAR+1, 7):
+            # Verify (year, 1, 1) -> ordinal -> y, m, d is identity.
+            d = self.theclass(year, 1, 1)
+            n = d.toordinal()
+            d2 = self.theclass.fromordinal(n)
+            self.assertEqual(d, d2)
+            # Verify that moving back a day gets to the end of year-1.
+            if year > 1:
+                d = self.theclass.fromordinal(n-1)
+                d2 = self.theclass(year-1, 12, 31)
+                self.assertEqual(d, d2)
+                self.assertEqual(d2.toordinal(), n-1)
+
+        # Test every day in a leap-year and a non-leap year.
+        dim = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
+        for year, isleap in (2000, True), (2002, False):
+            n = self.theclass(year, 1, 1).toordinal()
+            for month, maxday in zip(range(1, 13), dim):
+                if month == 2 and isleap:
+                    maxday += 1
+                for day in range(1, maxday+1):
+                    d = self.theclass(year, month, day)
+                    self.assertEqual(d.toordinal(), n)
+                    self.assertEqual(d, self.theclass.fromordinal(n))
+                    n += 1
+
+    def test_extreme_ordinals(self):
+        a = self.theclass.min
+        a = self.theclass(a.year, a.month, a.day)  # get rid of time parts
+        aord = a.toordinal()
+        b = a.fromordinal(aord)
+        self.assertEqual(a, b)
+
+        self.assertRaises(ValueError, lambda: a.fromordinal(aord - 1))
+
+        b = a + timedelta(days=1)
+        self.assertEqual(b.toordinal(), aord + 1)
+        self.assertEqual(b, self.theclass.fromordinal(aord + 1))
+
+        a = self.theclass.max
+        a = self.theclass(a.year, a.month, a.day)  # get rid of time parts
+        aord = a.toordinal()
+        b = a.fromordinal(aord)
+        self.assertEqual(a, b)
+
+        self.assertRaises(ValueError, lambda: a.fromordinal(aord + 1))
+
+        b = a - timedelta(days=1)
+        self.assertEqual(b.toordinal(), aord - 1)
+        self.assertEqual(b, self.theclass.fromordinal(aord - 1))
+
+    def test_bad_constructor_arguments(self):
+        # bad years
+        self.theclass(MINYEAR, 1, 1)  # no exception
+        self.theclass(MAXYEAR, 1, 1)  # no exception
+        self.assertRaises(ValueError, self.theclass, MINYEAR-1, 1, 1)
+        self.assertRaises(ValueError, self.theclass, MAXYEAR+1, 1, 1)
+        # bad months
+        self.theclass(2000, 1, 1)    # no exception
+        self.theclass(2000, 12, 1)   # no exception
+        self.assertRaises(ValueError, self.theclass, 2000, 0, 1)
+        self.assertRaises(ValueError, self.theclass, 2000, 13, 1)
+        # bad days
+        self.theclass(2000, 2, 29)   # no exception
+        self.theclass(2004, 2, 29)   # no exception
+        self.theclass(2400, 2, 29)   # no exception
+        self.assertRaises(ValueError, self.theclass, 2000, 2, 30)
+        self.assertRaises(ValueError, self.theclass, 2001, 2, 29)
+        self.assertRaises(ValueError, self.theclass, 2100, 2, 29)
+        self.assertRaises(ValueError, self.theclass, 1900, 2, 29)
+        self.assertRaises(ValueError, self.theclass, 2000, 1, 0)
+        self.assertRaises(ValueError, self.theclass, 2000, 1, 32)
+
+    def test_hash_equality(self):
+        d = self.theclass(2000, 12, 31)
+        # same thing
+        e = self.theclass(2000, 12, 31)
+        self.assertEqual(d, e)
+        self.assertEqual(hash(d), hash(e))
+
+        dic = {d: 1}
+        dic[e] = 2
+        self.assertEqual(len(dic), 1)
+        self.assertEqual(dic[d], 2)
+        self.assertEqual(dic[e], 2)
+
+        d = self.theclass(2001,  1,  1)
+        # same thing
+        e = self.theclass(2001,  1,  1)
+        self.assertEqual(d, e)
+        self.assertEqual(hash(d), hash(e))
+
+        dic = {d: 1}
+        dic[e] = 2
+        self.assertEqual(len(dic), 1)
+        self.assertEqual(dic[d], 2)
+        self.assertEqual(dic[e], 2)
+
+    def test_computations(self):
+        a = self.theclass(2002, 1, 31)
+        b = self.theclass(1956, 1, 31)
+
+        diff = a-b
+        self.assertEqual(diff.days, 46*365 + len(range(1956, 2002, 4)))
+        self.assertEqual(diff.seconds, 0)
+        self.assertEqual(diff.microseconds, 0)
+
+        day = timedelta(1)
+        week = timedelta(7)
+        a = self.theclass(2002, 3, 2)
+        self.assertEqual(a + day, self.theclass(2002, 3, 3))
+        self.assertEqual(day + a, self.theclass(2002, 3, 3))
+        self.assertEqual(a - day, self.theclass(2002, 3, 1))
+        self.assertEqual(-day + a, self.theclass(2002, 3, 1))
+        self.assertEqual(a + week, self.theclass(2002, 3, 9))
+        self.assertEqual(a - week, self.theclass(2002, 2, 23))
+        self.assertEqual(a + 52*week, self.theclass(2003, 3, 1))
+        self.assertEqual(a - 52*week, self.theclass(2001, 3, 3))
+        self.assertEqual((a + week) - a, week)
+        self.assertEqual((a + day) - a, day)
+        self.assertEqual((a - week) - a, -week)
+        self.assertEqual((a - day) - a, -day)
+        self.assertEqual(a - (a + week), -week)
+        self.assertEqual(a - (a + day), -day)
+        self.assertEqual(a - (a - week), week)
+        self.assertEqual(a - (a - day), day)
+
+        # Add/sub ints, longs, floats should be illegal
+        for i in 1, 1L, 1.0:
+            self.assertRaises(TypeError, lambda: a+i)
+            self.assertRaises(TypeError, lambda: a-i)
+            self.assertRaises(TypeError, lambda: i+a)
+            self.assertRaises(TypeError, lambda: i-a)
+
+        # delta - date is senseless.
+        self.assertRaises(TypeError, lambda: day - a)
+        # mixing date and (delta or date) via * or // is senseless
+        self.assertRaises(TypeError, lambda: day * a)
+        self.assertRaises(TypeError, lambda: a * day)
+        self.assertRaises(TypeError, lambda: day // a)
+        self.assertRaises(TypeError, lambda: a // day)
+        self.assertRaises(TypeError, lambda: a * a)
+        self.assertRaises(TypeError, lambda: a // a)
+        # date + date is senseless
+        self.assertRaises(TypeError, lambda: a + a)
+
+    def test_overflow(self):
+        tiny = self.theclass.resolution
+
+        dt = self.theclass.min + tiny
+        dt -= tiny  # no problem
+        self.assertRaises(OverflowError, dt.__sub__, tiny)
+        self.assertRaises(OverflowError, dt.__add__, -tiny)
+
+        dt = self.theclass.max - tiny
+        dt += tiny  # no problem
+        self.assertRaises(OverflowError, dt.__add__, tiny)
+        self.assertRaises(OverflowError, dt.__sub__, -tiny)
+
+    def test_fromtimestamp(self):
+        import time
+
+        # Try an arbitrary fixed value.
+        year, month, day = 1999, 9, 19
+        ts = time.mktime((year, month, day, 0, 0, 0, 0, 0, -1))
+        d = self.theclass.fromtimestamp(ts)
+        self.assertEqual(d.year, year)
+        self.assertEqual(d.month, month)
+        self.assertEqual(d.day, day)
+
+    def test_insane_fromtimestamp(self):
+        # It's possible that some platform maps time_t to double,
+        # and that this test will fail there.  This test should
+        # exempt such platforms (provided they return reasonable
+        # results!).
+        for insane in -1e200, 1e200:
+            self.assertRaises(ValueError, self.theclass.fromtimestamp,
+                              insane)
+
+    def test_today(self):
+        import time
+
+        # We claim that today() is like fromtimestamp(time.time()), so
+        # prove it.
+        for dummy in range(3):
+            today = self.theclass.today()
+            ts = time.time()
+            todayagain = self.theclass.fromtimestamp(ts)
+            if today == todayagain:
+                break
+            # There are several legit reasons that could fail:
+            # 1. It recently became midnight, between the today() and the
+            #    time() calls.
+            # 2. The platform time() has such fine resolution that we'll
+            #    never get the same value twice.
+            # 3. The platform time() has poor resolution, and we just
+            #    happened to call today() right before a resolution quantum
+            #    boundary.
+            # 4. The system clock got fiddled between calls.
+            # In any case, wait a little while and try again.
+            time.sleep(0.1)
+
+        # It worked or it didn't.  If it didn't, assume it's reason #2, and
+        # let the test pass if they're within half a second of each other.
+        self.failUnless(today == todayagain or
+                        abs(todayagain - today) < timedelta(seconds=0.5))
+
+    def test_weekday(self):
+        for i in range(7):
+            # March 4, 2002 is a Monday
+            self.assertEqual(self.theclass(2002, 3, 4+i).weekday(), i)
+            self.assertEqual(self.theclass(2002, 3, 4+i).isoweekday(), i+1)
+            # January 2, 1956 is a Monday
+            self.assertEqual(self.theclass(1956, 1, 2+i).weekday(), i)
+            self.assertEqual(self.theclass(1956, 1, 2+i).isoweekday(), i+1)
+
+    def test_isocalendar(self):
+        # Check examples from
+        # http://www.phys.uu.nl/~vgent/calendar/isocalendar.htm
+        for i in range(7):
+            d = self.theclass(2003, 12, 22+i)
+            self.assertEqual(d.isocalendar(), (2003, 52, i+1))
+            d = self.theclass(2003, 12, 29) + timedelta(i)
+            self.assertEqual(d.isocalendar(), (2004, 1, i+1))
+            d = self.theclass(2004, 1, 5+i)
+            self.assertEqual(d.isocalendar(), (2004, 2, i+1))
+            d = self.theclass(2009, 12, 21+i)
+            self.assertEqual(d.isocalendar(), (2009, 52, i+1))
+            d = self.theclass(2009, 12, 28) + timedelta(i)
+            self.assertEqual(d.isocalendar(), (2009, 53, i+1))
+            d = self.theclass(2010, 1, 4+i)
+            self.assertEqual(d.isocalendar(), (2010, 1, i+1))
+
+    def test_iso_long_years(self):
+        # Calculate long ISO years and compare to table from
+        # http://www.phys.uu.nl/~vgent/calendar/isocalendar.htm
+        ISO_LONG_YEARS_TABLE = """
+              4   32   60   88
+              9   37   65   93
+             15   43   71   99
+             20   48   76
+             26   54   82
+
+            105  133  161  189
+            111  139  167  195
+            116  144  172
+            122  150  178
+            128  156  184
+
+            201  229  257  285
+            207  235  263  291
+            212  240  268  296
+            218  246  274
+            224  252  280
+
+            303  331  359  387
+            308  336  364  392
+            314  342  370  398
+            320  348  376
+            325  353  381
+        """
+        iso_long_years = map(int, ISO_LONG_YEARS_TABLE.split())
+        iso_long_years.sort()
+        L = []
+        for i in range(400):
+            d = self.theclass(2000+i, 12, 31)
+            d1 = self.theclass(1600+i, 12, 31)
+            self.assertEqual(d.isocalendar()[1:], d1.isocalendar()[1:])
+            if d.isocalendar()[1] == 53:
+                L.append(i)
+        self.assertEqual(L, iso_long_years)
+
+    def test_isoformat(self):
+        t = self.theclass(2, 3, 2)
+        self.assertEqual(t.isoformat(), "0002-03-02")
+
+    def test_ctime(self):
+        t = self.theclass(2002, 3, 2)
+        self.assertEqual(t.ctime(), "Sat Mar  2 00:00:00 2002")
+
+    def test_strftime(self):
+        t = self.theclass(2005, 3, 2)
+        self.assertEqual(t.strftime("m:%m d:%d y:%y"), "m:03 d:02 y:05")
+        self.assertEqual(t.strftime(""), "") # SF bug #761337
+        self.assertEqual(t.strftime('x'*1000), 'x'*1000) # SF bug #1556784
+
+        self.assertRaises(TypeError, t.strftime) # needs an arg
+        self.assertRaises(TypeError, t.strftime, "one", "two") # too many args
+        self.assertRaises(TypeError, t.strftime, 42) # arg wrong type
+
+        # A naive object replaces %z and %Z w/ empty strings.
+        self.assertEqual(t.strftime("'%z' '%Z'"), "'' ''")
+
+    def test_resolution_info(self):
+        self.assert_(isinstance(self.theclass.min, self.theclass))
+        self.assert_(isinstance(self.theclass.max, self.theclass))
+        self.assert_(isinstance(self.theclass.resolution, timedelta))
+        self.assert_(self.theclass.max > self.theclass.min)
+
+    def test_extreme_timedelta(self):
+        big = self.theclass.max - self.theclass.min
+        # 3652058 days, 23 hours, 59 minutes, 59 seconds, 999999 microseconds
+        n = (big.days*24*3600 + big.seconds)*1000000 + big.microseconds
+        # n == 315537897599999999 ~= 2**58.13
+        justasbig = timedelta(0, 0, n)
+        self.assertEqual(big, justasbig)
+        self.assertEqual(self.theclass.min + big, self.theclass.max)
+        self.assertEqual(self.theclass.max - big, self.theclass.min)
+
+    def test_timetuple(self):
+        for i in range(7):
+            # January 2, 1956 is a Monday (0)
+            d = self.theclass(1956, 1, 2+i)
+            t = d.timetuple()
+            self.assertEqual(t, (1956, 1, 2+i, 0, 0, 0, i, 2+i, -1))
+            # February 1, 1956 is a Wednesday (2)
+            d = self.theclass(1956, 2, 1+i)
+            t = d.timetuple()
+            self.assertEqual(t, (1956, 2, 1+i, 0, 0, 0, (2+i)%7, 32+i, -1))
+            # March 1, 1956 is a Thursday (3), and is the 31+29+1 = 61st day
+            # of the year.
+            d = self.theclass(1956, 3, 1+i)
+            t = d.timetuple()
+            self.assertEqual(t, (1956, 3, 1+i, 0, 0, 0, (3+i)%7, 61+i, -1))
+            self.assertEqual(t.tm_year, 1956)
+            self.assertEqual(t.tm_mon, 3)
+            self.assertEqual(t.tm_mday, 1+i)
+            self.assertEqual(t.tm_hour, 0)
+            self.assertEqual(t.tm_min, 0)
+            self.assertEqual(t.tm_sec, 0)
+            self.assertEqual(t.tm_wday, (3+i)%7)
+            self.assertEqual(t.tm_yday, 61+i)
+            self.assertEqual(t.tm_isdst, -1)
+
+    def test_pickling(self):
+        args = 6, 7, 23
+        orig = self.theclass(*args)
+        for pickler, unpickler, proto in pickle_choices:
+            green = pickler.dumps(orig, proto)
+            derived = unpickler.loads(green)
+            self.assertEqual(orig, derived)
+
+    def test_compare(self):
+        t1 = self.theclass(2, 3, 4)
+        t2 = self.theclass(2, 3, 4)
+        self.failUnless(t1 == t2)
+        self.failUnless(t1 <= t2)
+        self.failUnless(t1 >= t2)
+        self.failUnless(not t1 != t2)
+        self.failUnless(not t1 < t2)
+        self.failUnless(not t1 > t2)
+        self.assertEqual(cmp(t1, t2), 0)
+        self.assertEqual(cmp(t2, t1), 0)
+
+        for args in (3, 3, 3), (2, 4, 4), (2, 3, 5):
+            t2 = self.theclass(*args)   # this is larger than t1
+            self.failUnless(t1 < t2)
+            self.failUnless(t2 > t1)
+            self.failUnless(t1 <= t2)
+            self.failUnless(t2 >= t1)
+            self.failUnless(t1 != t2)
+            self.failUnless(t2 != t1)
+            self.failUnless(not t1 == t2)
+            self.failUnless(not t2 == t1)
+            self.failUnless(not t1 > t2)
+            self.failUnless(not t2 < t1)
+            self.failUnless(not t1 >= t2)
+            self.failUnless(not t2 <= t1)
+            self.assertEqual(cmp(t1, t2), -1)
+            self.assertEqual(cmp(t2, t1), 1)
+
+        for badarg in OTHERSTUFF:
+            self.assertEqual(t1 == badarg, False)
+            self.assertEqual(t1 != badarg, True)
+            self.assertEqual(badarg == t1, False)
+            self.assertEqual(badarg != t1, True)
+
+            self.assertRaises(TypeError, lambda: t1 < badarg)
+            self.assertRaises(TypeError, lambda: t1 > badarg)
+            self.assertRaises(TypeError, lambda: t1 >= badarg)
+            self.assertRaises(TypeError, lambda: badarg <= t1)
+            self.assertRaises(TypeError, lambda: badarg < t1)
+            self.assertRaises(TypeError, lambda: badarg > t1)
+            self.assertRaises(TypeError, lambda: badarg >= t1)
+
+    def test_mixed_compare(self):
+        our = self.theclass(2000, 4, 5)
+        self.assertRaises(TypeError, cmp, our, 1)
+        self.assertRaises(TypeError, cmp, 1, our)
+
+        class AnotherDateTimeClass(object):
+            def __cmp__(self, other):
+                # Return "equal" so calling this can't be confused with
+                # compare-by-address (which never says "equal" for distinct
+                # objects).
+                return 0
+
+        # This still errors, because date and datetime comparison raise
+        # TypeError instead of NotImplemented when they don't know what to
+        # do, in order to stop comparison from falling back to the default
+        # compare-by-address.
+        their = AnotherDateTimeClass()
+        self.assertRaises(TypeError, cmp, our, their)
+        # Oops:  The next stab raises TypeError in the C implementation,
+        # but not in the Python implementation of datetime.  The difference
+        # is due to that the Python implementation defines __cmp__ but
+        # the C implementation defines tp_richcompare.  This is more pain
+        # to fix than it's worth, so commenting out the test.
+        # self.assertEqual(cmp(their, our), 0)
+
+        # But date and datetime comparison return NotImplemented instead if the
+        # other object has a timetuple attr.  This gives the other object a
+        # chance to do the comparison.
+        class Comparable(AnotherDateTimeClass):
+            def timetuple(self):
+                return ()
+
+        their = Comparable()
+        self.assertEqual(cmp(our, their), 0)
+        self.assertEqual(cmp(their, our), 0)
+        self.failUnless(our == their)
+        self.failUnless(their == our)
+
+    def test_bool(self):
+        # All dates are considered true.
+        self.failUnless(self.theclass.min)
+        self.failUnless(self.theclass.max)
+
+    def test_srftime_out_of_range(self):
+        # For nasty technical reasons, we can't handle years before 1900.
+        cls = self.theclass
+        self.assertEqual(cls(1900, 1, 1).strftime("%Y"), "1900")
+        for y in 1, 49, 51, 99, 100, 1000, 1899:
+            self.assertRaises(ValueError, cls(y, 1, 1).strftime, "%Y")
+
+    def test_replace(self):
+        cls = self.theclass
+        args = [1, 2, 3]
+        base = cls(*args)
+        self.assertEqual(base, base.replace())
+
+        i = 0
+        for name, newval in (("year", 2),
+                             ("month", 3),
+                             ("day", 4)):
+            newargs = args[:]
+            newargs[i] = newval
+            expected = cls(*newargs)
+            got = base.replace(**{name: newval})
+            self.assertEqual(expected, got)
+            i += 1
+
+        # Out of bounds.
+        base = cls(2000, 2, 29)
+        self.assertRaises(ValueError, base.replace, year=2001)
+
+    def test_subclass_date(self):
+
+        class C(self.theclass):
+            theAnswer = 42
+
+            def __new__(cls, *args, **kws):
+                temp = kws.copy()
+                extra = temp.pop('extra')
+                result = self.theclass.__new__(cls, *args, **temp)
+                result.extra = extra
+                return result
+
+            def newmeth(self, start):
+                return start + self.year + self.month
+
+        args = 2003, 4, 14
+
+        dt1 = self.theclass(*args)
+        dt2 = C(*args, **{'extra': 7})
+
+        self.assertEqual(dt2.__class__, C)
+        self.assertEqual(dt2.theAnswer, 42)
+        self.assertEqual(dt2.extra, 7)
+        self.assertEqual(dt1.toordinal(), dt2.toordinal())
+        self.assertEqual(dt2.newmeth(-7), dt1.year + dt1.month - 7)
+
+    def test_pickling_subclass_date(self):
+
+        args = 6, 7, 23
+        orig = SubclassDate(*args)
+        for pickler, unpickler, proto in pickle_choices:
+            green = pickler.dumps(orig, proto)
+            derived = unpickler.loads(green)
+            self.assertEqual(orig, derived)
+
+    def test_backdoor_resistance(self):
+        # For fast unpickling, the constructor accepts a pickle string.
+        # This is a low-overhead backdoor.  A user can (by intent or
+        # mistake) pass a string directly, which (if it's the right length)
+        # will get treated like a pickle, and bypass the normal sanity
+        # checks in the constructor.  This can create insane objects.
+        # The constructor doesn't want to burn the time to validate all
+        # fields, but does check the month field.  This stops, e.g.,
+        # datetime.datetime('1995-03-25') from yielding an insane object.
+        base = '1995-03-25'
+        if not issubclass(self.theclass, datetime):
+            base = base[:4]
+        for month_byte in '9', chr(0), chr(13), '\xff':
+            self.assertRaises(TypeError, self.theclass,
+                                         base[:2] + month_byte + base[3:])
+        for ord_byte in range(1, 13):
+            # This shouldn't blow up because of the month byte alone.  If
+            # the implementation changes to do more-careful checking, it may
+            # blow up because other fields are insane.
+            self.theclass(base[:2] + chr(ord_byte) + base[3:])
+
+#############################################################################
+# datetime tests
+
+class SubclassDatetime(datetime):
+    sub_var = 1
+
+class TestDateTime(TestDate):
+
+    theclass = datetime
+
+    def test_basic_attributes(self):
+        dt = self.theclass(2002, 3, 1, 12, 0)
+        self.assertEqual(dt.year, 2002)
+        self.assertEqual(dt.month, 3)
+        self.assertEqual(dt.day, 1)
+        self.assertEqual(dt.hour, 12)
+        self.assertEqual(dt.minute, 0)
+        self.assertEqual(dt.second, 0)
+        self.assertEqual(dt.microsecond, 0)
+
+    def test_basic_attributes_nonzero(self):
+        # Make sure all attributes are non-zero so bugs in
+        # bit-shifting access show up.
+        dt = self.theclass(2002, 3, 1, 12, 59, 59, 8000)
+        self.assertEqual(dt.year, 2002)
+        self.assertEqual(dt.month, 3)
+        self.assertEqual(dt.day, 1)
+        self.assertEqual(dt.hour, 12)
+        self.assertEqual(dt.minute, 59)
+        self.assertEqual(dt.second, 59)
+        self.assertEqual(dt.microsecond, 8000)
+
+    def test_roundtrip(self):
+        for dt in (self.theclass(1, 2, 3, 4, 5, 6, 7),
+                   self.theclass.now()):
+            # Verify dt -> string -> datetime identity.
+            s = repr(dt)
+            self.failUnless(s.startswith('datetime.'))
+            s = s[9:]
+            dt2 = eval(s)
+            self.assertEqual(dt, dt2)
+
+            # Verify identity via reconstructing from pieces.
+            dt2 = self.theclass(dt.year, dt.month, dt.day,
+                                dt.hour, dt.minute, dt.second,
+                                dt.microsecond)
+            self.assertEqual(dt, dt2)
+
+    def test_isoformat(self):
+        t = self.theclass(2, 3, 2, 4, 5, 1, 123)
+        self.assertEqual(t.isoformat(),    "0002-03-02T04:05:01.000123")
+        self.assertEqual(t.isoformat('T'), "0002-03-02T04:05:01.000123")
+        self.assertEqual(t.isoformat(' '), "0002-03-02 04:05:01.000123")
+        # str is ISO format with the separator forced to a blank.
+        self.assertEqual(str(t), "0002-03-02 04:05:01.000123")
+
+        t = self.theclass(2, 3, 2)
+        self.assertEqual(t.isoformat(),    "0002-03-02T00:00:00")
+        self.assertEqual(t.isoformat('T'), "0002-03-02T00:00:00")
+        self.assertEqual(t.isoformat(' '), "0002-03-02 00:00:00")
+        # str is ISO format with the separator forced to a blank.
+        self.assertEqual(str(t), "0002-03-02 00:00:00")
+
+    def test_more_ctime(self):
+        # Test fields that TestDate doesn't touch.
+        import time
+
+        t = self.theclass(2002, 3, 2, 18, 3, 5, 123)
+        self.assertEqual(t.ctime(), "Sat Mar  2 18:03:05 2002")
+        # Oops!  The next line fails on Win2K under MSVC 6, so it's commented
+        # out.  The difference is that t.ctime() produces " 2" for the day,
+        # but platform ctime() produces "02" for the day.  According to
+        # C99, t.ctime() is correct here.
+        # self.assertEqual(t.ctime(), time.ctime(time.mktime(t.timetuple())))
+
+        # So test a case where that difference doesn't matter.
+        t = self.theclass(2002, 3, 22, 18, 3, 5, 123)
+        self.assertEqual(t.ctime(), time.ctime(time.mktime(t.timetuple())))
+
+    def test_tz_independent_comparing(self):
+        dt1 = self.theclass(2002, 3, 1, 9, 0, 0)
+        dt2 = self.theclass(2002, 3, 1, 10, 0, 0)
+        dt3 = self.theclass(2002, 3, 1, 9, 0, 0)
+        self.assertEqual(dt1, dt3)
+        self.assert_(dt2 > dt3)
+
+        # Make sure comparison doesn't forget microseconds, and isn't done
+        # via comparing a float timestamp (an IEEE double doesn't have enough
+        # precision to span microsecond resolution across years 1 thru 9999,
+        # so comparing via timestamp necessarily calls some distinct values
+        # equal).
+        dt1 = self.theclass(MAXYEAR, 12, 31, 23, 59, 59, 999998)
+        us = timedelta(microseconds=1)
+        dt2 = dt1 + us
+        self.assertEqual(dt2 - dt1, us)
+        self.assert_(dt1 < dt2)
+
+    def test_strftime_with_bad_tzname_replace(self):
+        # verify ok if tzinfo.tzname().replace() returns a non-string
+        class MyTzInfo(FixedOffset):
+            def tzname(self, dt):
+                class MyStr(str):
+                    def replace(self, *args):
+                        return None
+                return MyStr('name')
+        t = self.theclass(2005, 3, 2, 0, 0, 0, 0, MyTzInfo(3, 'name'))
+        self.assertRaises(TypeError, t.strftime, '%Z')
+
+    def test_bad_constructor_arguments(self):
+        # bad years
+        self.theclass(MINYEAR, 1, 1)  # no exception
+        self.theclass(MAXYEAR, 1, 1)  # no exception
+        self.assertRaises(ValueError, self.theclass, MINYEAR-1, 1, 1)
+        self.assertRaises(ValueError, self.theclass, MAXYEAR+1, 1, 1)
+        # bad months
+        self.theclass(2000, 1, 1)    # no exception
+        self.theclass(2000, 12, 1)   # no exception
+        self.assertRaises(ValueError, self.theclass, 2000, 0, 1)
+        self.assertRaises(ValueError, self.theclass, 2000, 13, 1)
+        # bad days
+        self.theclass(2000, 2, 29)   # no exception
+        self.theclass(2004, 2, 29)   # no exception
+        self.theclass(2400, 2, 29)   # no exception
+        self.assertRaises(ValueError, self.theclass, 2000, 2, 30)
+        self.assertRaises(ValueError, self.theclass, 2001, 2, 29)
+        self.assertRaises(ValueError, self.theclass, 2100, 2, 29)
+        self.assertRaises(ValueError, self.theclass, 1900, 2, 29)
+        self.assertRaises(ValueError, self.theclass, 2000, 1, 0)
+        self.assertRaises(ValueError, self.theclass, 2000, 1, 32)
+        # bad hours
+        self.theclass(2000, 1, 31, 0)    # no exception
+        self.theclass(2000, 1, 31, 23)   # no exception
+        self.assertRaises(ValueError, self.theclass, 2000, 1, 31, -1)
+        self.assertRaises(ValueError, self.theclass, 2000, 1, 31, 24)
+        # bad minutes
+        self.theclass(2000, 1, 31, 23, 0)    # no exception
+        self.theclass(2000, 1, 31, 23, 59)   # no exception
+        self.assertRaises(ValueError, self.theclass, 2000, 1, 31, 23, -1)
+        self.assertRaises(ValueError, self.theclass, 2000, 1, 31, 23, 60)
+        # bad seconds
+        self.theclass(2000, 1, 31, 23, 59, 0)    # no exception
+        self.theclass(2000, 1, 31, 23, 59, 59)   # no exception
+        self.assertRaises(ValueError, self.theclass, 2000, 1, 31, 23, 59, -1)
+        self.assertRaises(ValueError, self.theclass, 2000, 1, 31, 23, 59, 60)
+        # bad microseconds
+        self.theclass(2000, 1, 31, 23, 59, 59, 0)    # no exception
+        self.theclass(2000, 1, 31, 23, 59, 59, 999999)   # no exception
+        self.assertRaises(ValueError, self.theclass,
+                          2000, 1, 31, 23, 59, 59, -1)
+        self.assertRaises(ValueError, self.theclass,
+                          2000, 1, 31, 23, 59, 59,
+                          1000000)
+
+    def test_hash_equality(self):
+        d = self.theclass(2000, 12, 31, 23, 30, 17)
+        e = self.theclass(2000, 12, 31, 23, 30, 17)
+        self.assertEqual(d, e)
+        self.assertEqual(hash(d), hash(e))
+
+        dic = {d: 1}
+        dic[e] = 2
+        self.assertEqual(len(dic), 1)
+        self.assertEqual(dic[d], 2)
+        self.assertEqual(dic[e], 2)
+
+        d = self.theclass(2001,  1,  1,  0,  5, 17)
+        e = self.theclass(2001,  1,  1,  0,  5, 17)
+        self.assertEqual(d, e)
+        self.assertEqual(hash(d), hash(e))
+
+        dic = {d: 1}
+        dic[e] = 2
+        self.assertEqual(len(dic), 1)
+        self.assertEqual(dic[d], 2)
+        self.assertEqual(dic[e], 2)
+
+    def test_computations(self):
+        a = self.theclass(2002, 1, 31)
+        b = self.theclass(1956, 1, 31)
+        diff = a-b
+        self.assertEqual(diff.days, 46*365 + len(range(1956, 2002, 4)))
+        self.assertEqual(diff.seconds, 0)
+        self.assertEqual(diff.microseconds, 0)
+        a = self.theclass(2002, 3, 2, 17, 6)
+        millisec = timedelta(0, 0, 1000)
+        hour = timedelta(0, 3600)
+        day = timedelta(1)
+        week = timedelta(7)
+        self.assertEqual(a + hour, self.theclass(2002, 3, 2, 18, 6))
+        self.assertEqual(hour + a, self.theclass(2002, 3, 2, 18, 6))
+        self.assertEqual(a + 10*hour, self.theclass(2002, 3, 3, 3, 6))
+        self.assertEqual(a - hour, self.theclass(2002, 3, 2, 16, 6))
+        self.assertEqual(-hour + a, self.theclass(2002, 3, 2, 16, 6))
+        self.assertEqual(a - hour, a + -hour)
+        self.assertEqual(a - 20*hour, self.theclass(2002, 3, 1, 21, 6))
+        self.assertEqual(a + day, self.theclass(2002, 3, 3, 17, 6))
+        self.assertEqual(a - day, self.theclass(2002, 3, 1, 17, 6))
+        self.assertEqual(a + week, self.theclass(2002, 3, 9, 17, 6))
+        self.assertEqual(a - week, self.theclass(2002, 2, 23, 17, 6))
+        self.assertEqual(a + 52*week, self.theclass(2003, 3, 1, 17, 6))
+        self.assertEqual(a - 52*week, self.theclass(2001, 3, 3, 17, 6))
+        self.assertEqual((a + week) - a, week)
+        self.assertEqual((a + day) - a, day)
+        self.assertEqual((a + hour) - a, hour)
+        self.assertEqual((a + millisec) - a, millisec)
+        self.assertEqual((a - week) - a, -week)
+        self.assertEqual((a - day) - a, -day)
+        self.assertEqual((a - hour) - a, -hour)
+        self.assertEqual((a - millisec) - a, -millisec)
+        self.assertEqual(a - (a + week), -week)
+        self.assertEqual(a - (a + day), -day)
+        self.assertEqual(a - (a + hour), -hour)
+        self.assertEqual(a - (a + millisec), -millisec)
+        self.assertEqual(a - (a - week), week)
+        self.assertEqual(a - (a - day), day)
+        self.assertEqual(a - (a - hour), hour)
+        self.assertEqual(a - (a - millisec), millisec)
+        self.assertEqual(a + (week + day + hour + millisec),
+                         self.theclass(2002, 3, 10, 18, 6, 0, 1000))
+        self.assertEqual(a + (week + day + hour + millisec),
+                         (((a + week) + day) + hour) + millisec)
+        self.assertEqual(a - (week + day + hour + millisec),
+                         self.theclass(2002, 2, 22, 16, 5, 59, 999000))
+        self.assertEqual(a - (week + day + hour + millisec),
+                         (((a - week) - day) - hour) - millisec)
+        # Add/sub ints, longs, floats should be illegal
+        for i in 1, 1L, 1.0:
+            self.assertRaises(TypeError, lambda: a+i)
+            self.assertRaises(TypeError, lambda: a-i)
+            self.assertRaises(TypeError, lambda: i+a)
+            self.assertRaises(TypeError, lambda: i-a)
+
+        # delta - datetime is senseless.
+        self.assertRaises(TypeError, lambda: day - a)
+        # mixing datetime and (delta or datetime) via * or // is senseless
+        self.assertRaises(TypeError, lambda: day * a)
+        self.assertRaises(TypeError, lambda: a * day)
+        self.assertRaises(TypeError, lambda: day // a)
+        self.assertRaises(TypeError, lambda: a // day)
+        self.assertRaises(TypeError, lambda: a * a)
+        self.assertRaises(TypeError, lambda: a // a)
+        # datetime + datetime is senseless
+        self.assertRaises(TypeError, lambda: a + a)
+
+    def test_pickling(self):
+        args = 6, 7, 23, 20, 59, 1, 64**2
+        orig = self.theclass(*args)
+        for pickler, unpickler, proto in pickle_choices:
+            green = pickler.dumps(orig, proto)
+            derived = unpickler.loads(green)
+            self.assertEqual(orig, derived)
+
+    def test_more_pickling(self):
+        a = self.theclass(2003, 2, 7, 16, 48, 37, 444116)
+        s = pickle.dumps(a)
+        b = pickle.loads(s)
+        self.assertEqual(b.year, 2003)
+        self.assertEqual(b.month, 2)
+        self.assertEqual(b.day, 7)
+
+    def test_pickling_subclass_datetime(self):
+        args = 6, 7, 23, 20, 59, 1, 64**2
+        orig = SubclassDatetime(*args)
+        for pickler, unpickler, proto in pickle_choices:
+            green = pickler.dumps(orig, proto)
+            derived = unpickler.loads(green)
+            self.assertEqual(orig, derived)
+
+    def test_more_compare(self):
+        # The test_compare() inherited from TestDate covers the error cases.
+        # We just want to test lexicographic ordering on the members datetime
+        # has that date lacks.
+        args = [2000, 11, 29, 20, 58, 16, 999998]
+        t1 = self.theclass(*args)
+        t2 = self.theclass(*args)
+        self.failUnless(t1 == t2)
+        self.failUnless(t1 <= t2)
+        self.failUnless(t1 >= t2)
+        self.failUnless(not t1 != t2)
+        self.failUnless(not t1 < t2)
+        self.failUnless(not t1 > t2)
+        self.assertEqual(cmp(t1, t2), 0)
+        self.assertEqual(cmp(t2, t1), 0)
+
+        for i in range(len(args)):
+            newargs = args[:]
+            newargs[i] = args[i] + 1
+            t2 = self.theclass(*newargs)   # this is larger than t1
+            self.failUnless(t1 < t2)
+            self.failUnless(t2 > t1)
+            self.failUnless(t1 <= t2)
+            self.failUnless(t2 >= t1)
+            self.failUnless(t1 != t2)
+            self.failUnless(t2 != t1)
+            self.failUnless(not t1 == t2)
+            self.failUnless(not t2 == t1)
+            self.failUnless(not t1 > t2)
+            self.failUnless(not t2 < t1)
+            self.failUnless(not t1 >= t2)
+            self.failUnless(not t2 <= t1)
+            self.assertEqual(cmp(t1, t2), -1)
+            self.assertEqual(cmp(t2, t1), 1)
+
+
+    # A helper for timestamp constructor tests.
+    def verify_field_equality(self, expected, got):
+        self.assertEqual(expected.tm_year, got.year)
+        self.assertEqual(expected.tm_mon, got.month)
+        self.assertEqual(expected.tm_mday, got.day)
+        self.assertEqual(expected.tm_hour, got.hour)
+        self.assertEqual(expected.tm_min, got.minute)
+        self.assertEqual(expected.tm_sec, got.second)
+
+    def test_fromtimestamp(self):
+        import time
+
+        ts = time.time()
+        expected = time.localtime(ts)
+        got = self.theclass.fromtimestamp(ts)
+        self.verify_field_equality(expected, got)
+
+    def test_utcfromtimestamp(self):
+        import time
+
+        ts = time.time()
+        expected = time.gmtime(ts)
+        got = self.theclass.utcfromtimestamp(ts)
+        self.verify_field_equality(expected, got)
+
+    def test_microsecond_rounding(self):
+        # Test whether fromtimestamp "rounds up" floats that are less
+        # than one microsecond smaller than an integer.
+        self.assertEquals(self.theclass.fromtimestamp(0.9999999),
+                          self.theclass.fromtimestamp(1))
+
+    def test_insane_fromtimestamp(self):
+        # It's possible that some platform maps time_t to double,
+        # and that this test will fail there.  This test should
+        # exempt such platforms (provided they return reasonable
+        # results!).
+        for insane in -1e200, 1e200:
+            self.assertRaises(ValueError, self.theclass.fromtimestamp,
+                              insane)
+
+    def test_insane_utcfromtimestamp(self):
+        # It's possible that some platform maps time_t to double,
+        # and that this test will fail there.  This test should
+        # exempt such platforms (provided they return reasonable
+        # results!).
+        for insane in -1e200, 1e200:
+            self.assertRaises(ValueError, self.theclass.utcfromtimestamp,
+                              insane)
+
+    def test_negative_float_fromtimestamp(self):
+        # Windows doesn't accept negative timestamps
+        if os.name == "nt":
+            return
+        # The result is tz-dependent; at least test that this doesn't
+        # fail (like it did before bug 1646728 was fixed).
+        self.theclass.fromtimestamp(-1.05)
+
+    def test_negative_float_utcfromtimestamp(self):
+        # Windows doesn't accept negative timestamps
+        if os.name == "nt":
+            return
+        d = self.theclass.utcfromtimestamp(-1.05)
+        self.assertEquals(d, self.theclass(1969, 12, 31, 23, 59, 58, 950000))
+
+    def test_utcnow(self):
+        import time
+
+        # Call it a success if utcnow() and utcfromtimestamp() are within
+        # a second of each other.
+        tolerance = timedelta(seconds=1)
+        for dummy in range(3):
+            from_now = self.theclass.utcnow()
+            from_timestamp = self.theclass.utcfromtimestamp(time.time())
+            if abs(from_timestamp - from_now) <= tolerance:
+                break
+            # Else try again a few times.
+        self.failUnless(abs(from_timestamp - from_now) <= tolerance)
+
+    def test_strptime(self):
+        import time
+
+        string = '2004-12-01 13:02:47'
+        format = '%Y-%m-%d %H:%M:%S'
+        expected = self.theclass(*(time.strptime(string, format)[0:6]))
+        got = self.theclass.strptime(string, format)
+        self.assertEqual(expected, got)
+
+    def test_more_timetuple(self):
+        # This tests fields beyond those tested by the TestDate.test_timetuple.
+        t = self.theclass(2004, 12, 31, 6, 22, 33)
+        self.assertEqual(t.timetuple(), (2004, 12, 31, 6, 22, 33, 4, 366, -1))
+        self.assertEqual(t.timetuple(),
+                         (t.year, t.month, t.day,
+                          t.hour, t.minute, t.second,
+                          t.weekday(),
+                          t.toordinal() - date(t.year, 1, 1).toordinal() + 1,
+                          -1))
+        tt = t.timetuple()
+        self.assertEqual(tt.tm_year, t.year)
+        self.assertEqual(tt.tm_mon, t.month)
+        self.assertEqual(tt.tm_mday, t.day)
+        self.assertEqual(tt.tm_hour, t.hour)
+        self.assertEqual(tt.tm_min, t.minute)
+        self.assertEqual(tt.tm_sec, t.second)
+        self.assertEqual(tt.tm_wday, t.weekday())
+        self.assertEqual(tt.tm_yday, t.toordinal() -
+                                     date(t.year, 1, 1).toordinal() + 1)
+        self.assertEqual(tt.tm_isdst, -1)
+
+    def test_more_strftime(self):
+        # This tests fields beyond those tested by the TestDate.test_strftime.
+        t = self.theclass(2004, 12, 31, 6, 22, 33)
+        self.assertEqual(t.strftime("%m %d %y %S %M %H %j"),
+                                    "12 31 04 33 22 06 366")
+
+    def test_extract(self):
+        dt = self.theclass(2002, 3, 4, 18, 45, 3, 1234)
+        self.assertEqual(dt.date(), date(2002, 3, 4))
+        self.assertEqual(dt.time(), time(18, 45, 3, 1234))
+
+    def test_combine(self):
+        d = date(2002, 3, 4)
+        t = time(18, 45, 3, 1234)
+        expected = self.theclass(2002, 3, 4, 18, 45, 3, 1234)
+        combine = self.theclass.combine
+        dt = combine(d, t)
+        self.assertEqual(dt, expected)
+
+        dt = combine(time=t, date=d)
+        self.assertEqual(dt, expected)
+
+        self.assertEqual(d, dt.date())
+        self.assertEqual(t, dt.time())
+        self.assertEqual(dt, combine(dt.date(), dt.time()))
+
+        self.assertRaises(TypeError, combine) # need an arg
+        self.assertRaises(TypeError, combine, d) # need two args
+        self.assertRaises(TypeError, combine, t, d) # args reversed
+        self.assertRaises(TypeError, combine, d, t, 1) # too many args
+        self.assertRaises(TypeError, combine, "date", "time") # wrong types
+
+    def test_replace(self):
+        cls = self.theclass
+        args = [1, 2, 3, 4, 5, 6, 7]
+        base = cls(*args)
+        self.assertEqual(base, base.replace())
+
+        i = 0
+        for name, newval in (("year", 2),
+                             ("month", 3),
+                             ("day", 4),
+                             ("hour", 5),
+                             ("minute", 6),
+                             ("second", 7),
+                             ("microsecond", 8)):
+            newargs = args[:]
+            newargs[i] = newval
+            expected = cls(*newargs)
+            got = base.replace(**{name: newval})
+            self.assertEqual(expected, got)
+            i += 1
+
+        # Out of bounds.
+        base = cls(2000, 2, 29)
+        self.assertRaises(ValueError, base.replace, year=2001)
+
+    def test_astimezone(self):
+        # Pretty boring!  The TZ test is more interesting here.  astimezone()
+        # simply can't be applied to a naive object.
+        dt = self.theclass.now()
+        f = FixedOffset(44, "")
+        self.assertRaises(TypeError, dt.astimezone) # not enough args
+        self.assertRaises(TypeError, dt.astimezone, f, f) # too many args
+        self.assertRaises(TypeError, dt.astimezone, dt) # arg wrong type
+        self.assertRaises(ValueError, dt.astimezone, f) # naive
+        self.assertRaises(ValueError, dt.astimezone, tz=f)  # naive
+
+        class Bogus(tzinfo):
+            def utcoffset(self, dt): return None
+            def dst(self, dt): return timedelta(0)
+        bog = Bogus()
+        self.assertRaises(ValueError, dt.astimezone, bog)   # naive
+
+        class AlsoBogus(tzinfo):
+            def utcoffset(self, dt): return timedelta(0)
+            def dst(self, dt): return None
+        alsobog = AlsoBogus()
+        self.assertRaises(ValueError, dt.astimezone, alsobog) # also naive
+
+    def test_subclass_datetime(self):
+
+        class C(self.theclass):
+            theAnswer = 42
+
+            def __new__(cls, *args, **kws):
+                temp = kws.copy()
+                extra = temp.pop('extra')
+                result = self.theclass.__new__(cls, *args, **temp)
+                result.extra = extra
+                return result
+
+            def newmeth(self, start):
+                return start + self.year + self.month + self.second
+
+        args = 2003, 4, 14, 12, 13, 41
+
+        dt1 = self.theclass(*args)
+        dt2 = C(*args, **{'extra': 7})
+
+        self.assertEqual(dt2.__class__, C)
+        self.assertEqual(dt2.theAnswer, 42)
+        self.assertEqual(dt2.extra, 7)
+        self.assertEqual(dt1.toordinal(), dt2.toordinal())
+        self.assertEqual(dt2.newmeth(-7), dt1.year + dt1.month +
+                                          dt1.second - 7)
+
+class SubclassTime(time):
+    sub_var = 1
+
+class TestTime(HarmlessMixedComparison):
+
+    theclass = time
+
+    def test_basic_attributes(self):
+        t = self.theclass(12, 0)
+        self.assertEqual(t.hour, 12)
+        self.assertEqual(t.minute, 0)
+        self.assertEqual(t.second, 0)
+        self.assertEqual(t.microsecond, 0)
+
+    def test_basic_attributes_nonzero(self):
+        # Make sure all attributes are non-zero so bugs in
+        # bit-shifting access show up.
+        t = self.theclass(12, 59, 59, 8000)
+        self.assertEqual(t.hour, 12)
+        self.assertEqual(t.minute, 59)
+        self.assertEqual(t.second, 59)
+        self.assertEqual(t.microsecond, 8000)
+
+    def test_roundtrip(self):
+        t = self.theclass(1, 2, 3, 4)
+
+        # Verify t -> string -> time identity.
+        s = repr(t)
+        self.failUnless(s.startswith('datetime.'))
+        s = s[9:]
+        t2 = eval(s)
+        self.assertEqual(t, t2)
+
+        # Verify identity via reconstructing from pieces.
+        t2 = self.theclass(t.hour, t.minute, t.second,
+                           t.microsecond)
+        self.assertEqual(t, t2)
+
+    def test_comparing(self):
+        args = [1, 2, 3, 4]
+        t1 = self.theclass(*args)
+        t2 = self.theclass(*args)
+        self.failUnless(t1 == t2)
+        self.failUnless(t1 <= t2)
+        self.failUnless(t1 >= t2)
+        self.failUnless(not t1 != t2)
+        self.failUnless(not t1 < t2)
+        self.failUnless(not t1 > t2)
+        self.assertEqual(cmp(t1, t2), 0)
+        self.assertEqual(cmp(t2, t1), 0)
+
+        for i in range(len(args)):
+            newargs = args[:]
+            newargs[i] = args[i] + 1
+            t2 = self.theclass(*newargs)   # this is larger than t1
+            self.failUnless(t1 < t2)
+            self.failUnless(t2 > t1)
+            self.failUnless(t1 <= t2)
+            self.failUnless(t2 >= t1)
+            self.failUnless(t1 != t2)
+            self.failUnless(t2 != t1)
+            self.failUnless(not t1 == t2)
+            self.failUnless(not t2 == t1)
+            self.failUnless(not t1 > t2)
+            self.failUnless(not t2 < t1)
+            self.failUnless(not t1 >= t2)
+            self.failUnless(not t2 <= t1)
+            self.assertEqual(cmp(t1, t2), -1)
+            self.assertEqual(cmp(t2, t1), 1)
+
+        for badarg in OTHERSTUFF:
+            self.assertEqual(t1 == badarg, False)
+            self.assertEqual(t1 != badarg, True)
+            self.assertEqual(badarg == t1, False)
+            self.assertEqual(badarg != t1, True)
+
+            self.assertRaises(TypeError, lambda: t1 <= badarg)
+            self.assertRaises(TypeError, lambda: t1 < badarg)
+            self.assertRaises(TypeError, lambda: t1 > badarg)
+            self.assertRaises(TypeError, lambda: t1 >= badarg)
+            self.assertRaises(TypeError, lambda: badarg <= t1)
+            self.assertRaises(TypeError, lambda: badarg < t1)
+            self.assertRaises(TypeError, lambda: badarg > t1)
+            self.assertRaises(TypeError, lambda: badarg >= t1)
+
+    def test_bad_constructor_arguments(self):
+        # bad hours
+        self.theclass(0, 0)    # no exception
+        self.theclass(23, 0)   # no exception
+        self.assertRaises(ValueError, self.theclass, -1, 0)
+        self.assertRaises(ValueError, self.theclass, 24, 0)
+        # bad minutes
+        self.theclass(23, 0)    # no exception
+        self.theclass(23, 59)   # no exception
+        self.assertRaises(ValueError, self.theclass, 23, -1)
+        self.assertRaises(ValueError, self.theclass, 23, 60)
+        # bad seconds
+        self.theclass(23, 59, 0)    # no exception
+        self.theclass(23, 59, 59)   # no exception
+        self.assertRaises(ValueError, self.theclass, 23, 59, -1)
+        self.assertRaises(ValueError, self.theclass, 23, 59, 60)
+        # bad microseconds
+        self.theclass(23, 59, 59, 0)        # no exception
+        self.theclass(23, 59, 59, 999999)   # no exception
+        self.assertRaises(ValueError, self.theclass, 23, 59, 59, -1)
+        self.assertRaises(ValueError, self.theclass, 23, 59, 59, 1000000)
+
+    def test_hash_equality(self):
+        d = self.theclass(23, 30, 17)
+        e = self.theclass(23, 30, 17)
+        self.assertEqual(d, e)
+        self.assertEqual(hash(d), hash(e))
+
+        dic = {d: 1}
+        dic[e] = 2
+        self.assertEqual(len(dic), 1)
+        self.assertEqual(dic[d], 2)
+        self.assertEqual(dic[e], 2)
+
+        d = self.theclass(0,  5, 17)
+        e = self.theclass(0,  5, 17)
+        self.assertEqual(d, e)
+        self.assertEqual(hash(d), hash(e))
+
+        dic = {d: 1}
+        dic[e] = 2
+        self.assertEqual(len(dic), 1)
+        self.assertEqual(dic[d], 2)
+        self.assertEqual(dic[e], 2)
+
+    def test_isoformat(self):
+        t = self.theclass(4, 5, 1, 123)
+        self.assertEqual(t.isoformat(), "04:05:01.000123")
+        self.assertEqual(t.isoformat(), str(t))
+
+        t = self.theclass()
+        self.assertEqual(t.isoformat(), "00:00:00")
+        self.assertEqual(t.isoformat(), str(t))
+
+        t = self.theclass(microsecond=1)
+        self.assertEqual(t.isoformat(), "00:00:00.000001")
+        self.assertEqual(t.isoformat(), str(t))
+
+        t = self.theclass(microsecond=10)
+        self.assertEqual(t.isoformat(), "00:00:00.000010")
+        self.assertEqual(t.isoformat(), str(t))
+
+        t = self.theclass(microsecond=100)
+        self.assertEqual(t.isoformat(), "00:00:00.000100")
+        self.assertEqual(t.isoformat(), str(t))
+
+        t = self.theclass(microsecond=1000)
+        self.assertEqual(t.isoformat(), "00:00:00.001000")
+        self.assertEqual(t.isoformat(), str(t))
+
+        t = self.theclass(microsecond=10000)
+        self.assertEqual(t.isoformat(), "00:00:00.010000")
+        self.assertEqual(t.isoformat(), str(t))
+
+        t = self.theclass(microsecond=100000)
+        self.assertEqual(t.isoformat(), "00:00:00.100000")
+        self.assertEqual(t.isoformat(), str(t))
+
+    def test_strftime(self):
+        t = self.theclass(1, 2, 3, 4)
+        self.assertEqual(t.strftime('%H %M %S'), "01 02 03")
+        # A naive object replaces %z and %Z with empty strings.
+        self.assertEqual(t.strftime("'%z' '%Z'"), "'' ''")
+
+    def test_str(self):
+        self.assertEqual(str(self.theclass(1, 2, 3, 4)), "01:02:03.000004")
+        self.assertEqual(str(self.theclass(10, 2, 3, 4000)), "10:02:03.004000")
+        self.assertEqual(str(self.theclass(0, 2, 3, 400000)), "00:02:03.400000")
+        self.assertEqual(str(self.theclass(12, 2, 3, 0)), "12:02:03")
+        self.assertEqual(str(self.theclass(23, 15, 0, 0)), "23:15:00")
+
+    def test_repr(self):
+        name = 'datetime.' + self.theclass.__name__
+        self.assertEqual(repr(self.theclass(1, 2, 3, 4)),
+                         "%s(1, 2, 3, 4)" % name)
+        self.assertEqual(repr(self.theclass(10, 2, 3, 4000)),
+                         "%s(10, 2, 3, 4000)" % name)
+        self.assertEqual(repr(self.theclass(0, 2, 3, 400000)),
+                         "%s(0, 2, 3, 400000)" % name)
+        self.assertEqual(repr(self.theclass(12, 2, 3, 0)),
+                         "%s(12, 2, 3)" % name)
+        self.assertEqual(repr(self.theclass(23, 15, 0, 0)),
+                         "%s(23, 15)" % name)
+
+    def test_resolution_info(self):
+        self.assert_(isinstance(self.theclass.min, self.theclass))
+        self.assert_(isinstance(self.theclass.max, self.theclass))
+        self.assert_(isinstance(self.theclass.resolution, timedelta))
+        self.assert_(self.theclass.max > self.theclass.min)
+
+    def test_pickling(self):
+        args = 20, 59, 16, 64**2
+        orig = self.theclass(*args)
+        for pickler, unpickler, proto in pickle_choices:
+            green = pickler.dumps(orig, proto)
+            derived = unpickler.loads(green)
+            self.assertEqual(orig, derived)
+
+    def test_pickling_subclass_time(self):
+        args = 20, 59, 16, 64**2
+        orig = SubclassTime(*args)
+        for pickler, unpickler, proto in pickle_choices:
+            green = pickler.dumps(orig, proto)
+            derived = unpickler.loads(green)
+            self.assertEqual(orig, derived)
+
+    def test_bool(self):
+        cls = self.theclass
+        self.failUnless(cls(1))
+        self.failUnless(cls(0, 1))
+        self.failUnless(cls(0, 0, 1))
+        self.failUnless(cls(0, 0, 0, 1))
+        self.failUnless(not cls(0))
+        self.failUnless(not cls())
+
+    def test_replace(self):
+        cls = self.theclass
+        args = [1, 2, 3, 4]
+        base = cls(*args)
+        self.assertEqual(base, base.replace())
+
+        i = 0
+        for name, newval in (("hour", 5),
+                             ("minute", 6),
+                             ("second", 7),
+                             ("microsecond", 8)):
+            newargs = args[:]
+            newargs[i] = newval
+            expected = cls(*newargs)
+            got = base.replace(**{name: newval})
+            self.assertEqual(expected, got)
+            i += 1
+
+        # Out of bounds.
+        base = cls(1)
+        self.assertRaises(ValueError, base.replace, hour=24)
+        self.assertRaises(ValueError, base.replace, minute=-1)
+        self.assertRaises(ValueError, base.replace, second=100)
+        self.assertRaises(ValueError, base.replace, microsecond=1000000)
+
+    def test_subclass_time(self):
+
+        class C(self.theclass):
+            theAnswer = 42
+
+            def __new__(cls, *args, **kws):
+                temp = kws.copy()
+                extra = temp.pop('extra')
+                result = self.theclass.__new__(cls, *args, **temp)
+                result.extra = extra
+                return result
+
+            def newmeth(self, start):
+                return start + self.hour + self.second
+
+        args = 4, 5, 6
+
+        dt1 = self.theclass(*args)
+        dt2 = C(*args, **{'extra': 7})
+
+        self.assertEqual(dt2.__class__, C)
+        self.assertEqual(dt2.theAnswer, 42)
+        self.assertEqual(dt2.extra, 7)
+        self.assertEqual(dt1.isoformat(), dt2.isoformat())
+        self.assertEqual(dt2.newmeth(-7), dt1.hour + dt1.second - 7)
+
+    def test_backdoor_resistance(self):
+        # see TestDate.test_backdoor_resistance().
+        base = '2:59.0'
+        for hour_byte in ' ', '9', chr(24), '\xff':
+            self.assertRaises(TypeError, self.theclass,
+                                         hour_byte + base[1:])
+
+# A mixin for classes with a tzinfo= argument.  Subclasses must define
+# theclass as a class atribute, and theclass(1, 1, 1, tzinfo=whatever)
+# must be legit (which is true for time and datetime).
+class TZInfoBase(unittest.TestCase):
+
+    def test_argument_passing(self):
+        cls = self.theclass
+        # A datetime passes itself on, a time passes None.
+        class introspective(tzinfo):
+            def tzname(self, dt):    return dt and "real" or "none"
+            def utcoffset(self, dt):
+                return timedelta(minutes = dt and 42 or -42)
+            dst = utcoffset
+
+        obj = cls(1, 2, 3, tzinfo=introspective())
+
+        expected = cls is time and "none" or "real"
+        self.assertEqual(obj.tzname(), expected)
+
+        expected = timedelta(minutes=(cls is time and -42 or 42))
+        self.assertEqual(obj.utcoffset(), expected)
+        self.assertEqual(obj.dst(), expected)
+
+    def test_bad_tzinfo_classes(self):
+        cls = self.theclass
+        self.assertRaises(TypeError, cls, 1, 1, 1, tzinfo=12)
+
+        class NiceTry(object):
+            def __init__(self): pass
+            def utcoffset(self, dt): pass
+        self.assertRaises(TypeError, cls, 1, 1, 1, tzinfo=NiceTry)
+
+        class BetterTry(tzinfo):
+            def __init__(self): pass
+            def utcoffset(self, dt): pass
+        b = BetterTry()
+        t = cls(1, 1, 1, tzinfo=b)
+        self.failUnless(t.tzinfo is b)
+
+    def test_utc_offset_out_of_bounds(self):
+        class Edgy(tzinfo):
+            def __init__(self, offset):
+                self.offset = timedelta(minutes=offset)
+            def utcoffset(self, dt):
+                return self.offset
+
+        cls = self.theclass
+        for offset, legit in ((-1440, False),
+                              (-1439, True),
+                              (1439, True),
+                              (1440, False)):
+            if cls is time:
+                t = cls(1, 2, 3, tzinfo=Edgy(offset))
+            elif cls is datetime:
+                t = cls(6, 6, 6, 1, 2, 3, tzinfo=Edgy(offset))
+            else:
+                assert 0, "impossible"
+            if legit:
+                aofs = abs(offset)
+                h, m = divmod(aofs, 60)
+                tag = "%c%02d:%02d" % (offset < 0 and '-' or '+', h, m)
+                if isinstance(t, datetime):
+                    t = t.timetz()
+                self.assertEqual(str(t), "01:02:03" + tag)
+            else:
+                self.assertRaises(ValueError, str, t)
+
+    def test_tzinfo_classes(self):
+        cls = self.theclass
+        class C1(tzinfo):
+            def utcoffset(self, dt): return None
+            def dst(self, dt): return None
+            def tzname(self, dt): return None
+        for t in (cls(1, 1, 1),
+                  cls(1, 1, 1, tzinfo=None),
+                  cls(1, 1, 1, tzinfo=C1())):
+            self.failUnless(t.utcoffset() is None)
+            self.failUnless(t.dst() is None)
+            self.failUnless(t.tzname() is None)
+
+        class C3(tzinfo):
+            def utcoffset(self, dt): return timedelta(minutes=-1439)
+            def dst(self, dt): return timedelta(minutes=1439)
+            def tzname(self, dt): return "aname"
+        t = cls(1, 1, 1, tzinfo=C3())
+        self.assertEqual(t.utcoffset(), timedelta(minutes=-1439))
+        self.assertEqual(t.dst(), timedelta(minutes=1439))
+        self.assertEqual(t.tzname(), "aname")
+
+        # Wrong types.
+        class C4(tzinfo):
+            def utcoffset(self, dt): return "aname"
+            def dst(self, dt): return 7
+            def tzname(self, dt): return 0
+        t = cls(1, 1, 1, tzinfo=C4())
+        self.assertRaises(TypeError, t.utcoffset)
+        self.assertRaises(TypeError, t.dst)
+        self.assertRaises(TypeError, t.tzname)
+
+        # Offset out of range.
+        class C6(tzinfo):
+            def utcoffset(self, dt): return timedelta(hours=-24)
+            def dst(self, dt): return timedelta(hours=24)
+        t = cls(1, 1, 1, tzinfo=C6())
+        self.assertRaises(ValueError, t.utcoffset)
+        self.assertRaises(ValueError, t.dst)
+
+        # Not a whole number of minutes.
+        class C7(tzinfo):
+            def utcoffset(self, dt): return timedelta(seconds=61)
+            def dst(self, dt): return timedelta(microseconds=-81)
+        t = cls(1, 1, 1, tzinfo=C7())
+        self.assertRaises(ValueError, t.utcoffset)
+        self.assertRaises(ValueError, t.dst)
+
+    def test_aware_compare(self):
+        cls = self.theclass
+
+        # Ensure that utcoffset() gets ignored if the comparands have
+        # the same tzinfo member.
+        class OperandDependentOffset(tzinfo):
+            def utcoffset(self, t):
+                if t.minute < 10:
+                    # d0 and d1 equal after adjustment
+                    return timedelta(minutes=t.minute)
+                else:
+                    # d2 off in the weeds
+                    return timedelta(minutes=59)
+
+        base = cls(8, 9, 10, tzinfo=OperandDependentOffset())
+        d0 = base.replace(minute=3)
+        d1 = base.replace(minute=9)
+        d2 = base.replace(minute=11)
+        for x in d0, d1, d2:
+            for y in d0, d1, d2:
+                got = cmp(x, y)
+                expected = cmp(x.minute, y.minute)
+                self.assertEqual(got, expected)
+
+        # However, if they're different members, uctoffset is not ignored.
+        # Note that a time can't actually have an operand-depedent offset,
+        # though (and time.utcoffset() passes None to tzinfo.utcoffset()),
+        # so skip this test for time.
+        if cls is not time:
+            d0 = base.replace(minute=3, tzinfo=OperandDependentOffset())
+            d1 = base.replace(minute=9, tzinfo=OperandDependentOffset())
+            d2 = base.replace(minute=11, tzinfo=OperandDependentOffset())
+            for x in d0, d1, d2:
+                for y in d0, d1, d2:
+                    got = cmp(x, y)
+                    if (x is d0 or x is d1) and (y is d0 or y is d1):
+                        expected = 0
+                    elif x is y is d2:
+                        expected = 0
+                    elif x is d2:
+                        expected = -1
+                    else:
+                        assert y is d2
+                        expected = 1
+                    self.assertEqual(got, expected)
+
+
+# Testing time objects with a non-None tzinfo.
+class TestTimeTZ(TestTime, TZInfoBase):
+    theclass = time
+
+    def test_empty(self):
+        t = self.theclass()
+        self.assertEqual(t.hour, 0)
+        self.assertEqual(t.minute, 0)
+        self.assertEqual(t.second, 0)
+        self.assertEqual(t.microsecond, 0)
+        self.failUnless(t.tzinfo is None)
+
+    def test_zones(self):
+        est = FixedOffset(-300, "EST", 1)
+        utc = FixedOffset(0, "UTC", -2)
+        met = FixedOffset(60, "MET", 3)
+        t1 = time( 7, 47, tzinfo=est)
+        t2 = time(12, 47, tzinfo=utc)
+        t3 = time(13, 47, tzinfo=met)
+        t4 = time(microsecond=40)
+        t5 = time(microsecond=40, tzinfo=utc)
+
+        self.assertEqual(t1.tzinfo, est)
+        self.assertEqual(t2.tzinfo, utc)
+        self.assertEqual(t3.tzinfo, met)
+        self.failUnless(t4.tzinfo is None)
+        self.assertEqual(t5.tzinfo, utc)
+
+        self.assertEqual(t1.utcoffset(), timedelta(minutes=-300))
+        self.assertEqual(t2.utcoffset(), timedelta(minutes=0))
+        self.assertEqual(t3.utcoffset(), timedelta(minutes=60))
+        self.failUnless(t4.utcoffset() is None)
+        self.assertRaises(TypeError, t1.utcoffset, "no args")
+
+        self.assertEqual(t1.tzname(), "EST")
+        self.assertEqual(t2.tzname(), "UTC")
+        self.assertEqual(t3.tzname(), "MET")
+        self.failUnless(t4.tzname() is None)
+        self.assertRaises(TypeError, t1.tzname, "no args")
+
+        self.assertEqual(t1.dst(), timedelta(minutes=1))
+        self.assertEqual(t2.dst(), timedelta(minutes=-2))
+        self.assertEqual(t3.dst(), timedelta(minutes=3))
+        self.failUnless(t4.dst() is None)
+        self.assertRaises(TypeError, t1.dst, "no args")
+
+        self.assertEqual(hash(t1), hash(t2))
+        self.assertEqual(hash(t1), hash(t3))
+        self.assertEqual(hash(t2), hash(t3))
+
+        self.assertEqual(t1, t2)
+        self.assertEqual(t1, t3)
+        self.assertEqual(t2, t3)
+        self.assertRaises(TypeError, lambda: t4 == t5) # mixed tz-aware & naive
+        self.assertRaises(TypeError, lambda: t4 < t5) # mixed tz-aware & naive
+        self.assertRaises(TypeError, lambda: t5 < t4) # mixed tz-aware & naive
+
+        self.assertEqual(str(t1), "07:47:00-05:00")
+        self.assertEqual(str(t2), "12:47:00+00:00")
+        self.assertEqual(str(t3), "13:47:00+01:00")
+        self.assertEqual(str(t4), "00:00:00.000040")
+        self.assertEqual(str(t5), "00:00:00.000040+00:00")
+
+        self.assertEqual(t1.isoformat(), "07:47:00-05:00")
+        self.assertEqual(t2.isoformat(), "12:47:00+00:00")
+        self.assertEqual(t3.isoformat(), "13:47:00+01:00")
+        self.assertEqual(t4.isoformat(), "00:00:00.000040")
+        self.assertEqual(t5.isoformat(), "00:00:00.000040+00:00")
+
+        d = 'datetime.time'
+        self.assertEqual(repr(t1), d + "(7, 47, tzinfo=est)")
+        self.assertEqual(repr(t2), d + "(12, 47, tzinfo=utc)")
+        self.assertEqual(repr(t3), d + "(13, 47, tzinfo=met)")
+        self.assertEqual(repr(t4), d + "(0, 0, 0, 40)")
+        self.assertEqual(repr(t5), d + "(0, 0, 0, 40, tzinfo=utc)")
+
+        self.assertEqual(t1.strftime("%H:%M:%S %%Z=%Z %%z=%z"),
+                                     "07:47:00 %Z=EST %z=-0500")
+        self.assertEqual(t2.strftime("%H:%M:%S %Z %z"), "12:47:00 UTC +0000")
+        self.assertEqual(t3.strftime("%H:%M:%S %Z %z"), "13:47:00 MET +0100")
+
+        yuck = FixedOffset(-1439, "%z %Z %%z%%Z")
+        t1 = time(23, 59, tzinfo=yuck)
+        self.assertEqual(t1.strftime("%H:%M %%Z='%Z' %%z='%z'"),
+                                     "23:59 %Z='%z %Z %%z%%Z' %z='-2359'")
+
+        # Check that an invalid tzname result raises an exception.
+        class Badtzname(tzinfo):
+            def tzname(self, dt): return 42
+        t = time(2, 3, 4, tzinfo=Badtzname())
+        self.assertEqual(t.strftime("%H:%M:%S"), "02:03:04")
+        self.assertRaises(TypeError, t.strftime, "%Z")
+
+    def test_hash_edge_cases(self):
+        # Offsets that overflow a basic time.
+        t1 = self.theclass(0, 1, 2, 3, tzinfo=FixedOffset(1439, ""))
+        t2 = self.theclass(0, 0, 2, 3, tzinfo=FixedOffset(1438, ""))
+        self.assertEqual(hash(t1), hash(t2))
+
+        t1 = self.theclass(23, 58, 6, 100, tzinfo=FixedOffset(-1000, ""))
+        t2 = self.theclass(23, 48, 6, 100, tzinfo=FixedOffset(-1010, ""))
+        self.assertEqual(hash(t1), hash(t2))
+
+    def test_pickling(self):
+        # Try one without a tzinfo.
+        args = 20, 59, 16, 64**2
+        orig = self.theclass(*args)
+        for pickler, unpickler, proto in pickle_choices:
+            green = pickler.dumps(orig, proto)
+            derived = unpickler.loads(green)
+            self.assertEqual(orig, derived)
+
+        # Try one with a tzinfo.
+        tinfo = PicklableFixedOffset(-300, 'cookie')
+        orig = self.theclass(5, 6, 7, tzinfo=tinfo)
+        for pickler, unpickler, proto in pickle_choices:
+            green = pickler.dumps(orig, proto)
+            derived = unpickler.loads(green)
+            self.assertEqual(orig, derived)
+            self.failUnless(isinstance(derived.tzinfo, PicklableFixedOffset))
+            self.assertEqual(derived.utcoffset(), timedelta(minutes=-300))
+            self.assertEqual(derived.tzname(), 'cookie')
+
+    def test_more_bool(self):
+        # Test cases with non-None tzinfo.
+        cls = self.theclass
+
+        t = cls(0, tzinfo=FixedOffset(-300, ""))
+        self.failUnless(t)
+
+        t = cls(5, tzinfo=FixedOffset(-300, ""))
+        self.failUnless(t)
+
+        t = cls(5, tzinfo=FixedOffset(300, ""))
+        self.failUnless(not t)
+
+        t = cls(23, 59, tzinfo=FixedOffset(23*60 + 59, ""))
+        self.failUnless(not t)
+
+        # Mostly ensuring this doesn't overflow internally.
+        t = cls(0, tzinfo=FixedOffset(23*60 + 59, ""))
+        self.failUnless(t)
+
+        # But this should yield a value error -- the utcoffset is bogus.
+        t = cls(0, tzinfo=FixedOffset(24*60, ""))
+        self.assertRaises(ValueError, lambda: bool(t))
+
+        # Likewise.
+        t = cls(0, tzinfo=FixedOffset(-24*60, ""))
+        self.assertRaises(ValueError, lambda: bool(t))
+
+    def test_replace(self):
+        cls = self.theclass
+        z100 = FixedOffset(100, "+100")
+        zm200 = FixedOffset(timedelta(minutes=-200), "-200")
+        args = [1, 2, 3, 4, z100]
+        base = cls(*args)
+        self.assertEqual(base, base.replace())
+
+        i = 0
+        for name, newval in (("hour", 5),
+                             ("minute", 6),
+                             ("second", 7),
+                             ("microsecond", 8),
+                             ("tzinfo", zm200)):
+            newargs = args[:]
+            newargs[i] = newval
+            expected = cls(*newargs)
+            got = base.replace(**{name: newval})
+            self.assertEqual(expected, got)
+            i += 1
+
+        # Ensure we can get rid of a tzinfo.
+        self.assertEqual(base.tzname(), "+100")
+        base2 = base.replace(tzinfo=None)
+        self.failUnless(base2.tzinfo is None)
+        self.failUnless(base2.tzname() is None)
+
+        # Ensure we can add one.
+        base3 = base2.replace(tzinfo=z100)
+        self.assertEqual(base, base3)
+        self.failUnless(base.tzinfo is base3.tzinfo)
+
+        # Out of bounds.
+        base = cls(1)
+        self.assertRaises(ValueError, base.replace, hour=24)
+        self.assertRaises(ValueError, base.replace, minute=-1)
+        self.assertRaises(ValueError, base.replace, second=100)
+        self.assertRaises(ValueError, base.replace, microsecond=1000000)
+
+    def test_mixed_compare(self):
+        t1 = time(1, 2, 3)
+        t2 = time(1, 2, 3)
+        self.assertEqual(t1, t2)
+        t2 = t2.replace(tzinfo=None)
+        self.assertEqual(t1, t2)
+        t2 = t2.replace(tzinfo=FixedOffset(None, ""))
+        self.assertEqual(t1, t2)
+        t2 = t2.replace(tzinfo=FixedOffset(0, ""))
+        self.assertRaises(TypeError, lambda: t1 == t2)
+
+        # In time w/ identical tzinfo objects, utcoffset is ignored.
+        class Varies(tzinfo):
+            def __init__(self):
+                self.offset = timedelta(minutes=22)
+            def utcoffset(self, t):
+                self.offset += timedelta(minutes=1)
+                return self.offset
+
+        v = Varies()
+        t1 = t2.replace(tzinfo=v)
+        t2 = t2.replace(tzinfo=v)
+        self.assertEqual(t1.utcoffset(), timedelta(minutes=23))
+        self.assertEqual(t2.utcoffset(), timedelta(minutes=24))
+        self.assertEqual(t1, t2)
+
+        # But if they're not identical, it isn't ignored.
+        t2 = t2.replace(tzinfo=Varies())
+        self.failUnless(t1 < t2)  # t1's offset counter still going up
+
+    def test_subclass_timetz(self):
+
+        class C(self.theclass):
+            theAnswer = 42
+
+            def __new__(cls, *args, **kws):
+                temp = kws.copy()
+                extra = temp.pop('extra')
+                result = self.theclass.__new__(cls, *args, **temp)
+                result.extra = extra
+                return result
+
+            def newmeth(self, start):
+                return start + self.hour + self.second
+
+        args = 4, 5, 6, 500, FixedOffset(-300, "EST", 1)
+
+        dt1 = self.theclass(*args)
+        dt2 = C(*args, **{'extra': 7})
+
+        self.assertEqual(dt2.__class__, C)
+        self.assertEqual(dt2.theAnswer, 42)
+        self.assertEqual(dt2.extra, 7)
+        self.assertEqual(dt1.utcoffset(), dt2.utcoffset())
+        self.assertEqual(dt2.newmeth(-7), dt1.hour + dt1.second - 7)
+
+
+# Testing datetime objects with a non-None tzinfo.
+
+class TestDateTimeTZ(TestDateTime, TZInfoBase):
+    theclass = datetime
+
+    def test_trivial(self):
+        dt = self.theclass(1, 2, 3, 4, 5, 6, 7)
+        self.assertEqual(dt.year, 1)
+        self.assertEqual(dt.month, 2)
+        self.assertEqual(dt.day, 3)
+        self.assertEqual(dt.hour, 4)
+        self.assertEqual(dt.minute, 5)
+        self.assertEqual(dt.second, 6)
+        self.assertEqual(dt.microsecond, 7)
+        self.assertEqual(dt.tzinfo, None)
+
+    def test_even_more_compare(self):
+        # The test_compare() and test_more_compare() inherited from TestDate
+        # and TestDateTime covered non-tzinfo cases.
+
+        # Smallest possible after UTC adjustment.
+        t1 = self.theclass(1, 1, 1, tzinfo=FixedOffset(1439, ""))
+        # Largest possible after UTC adjustment.
+        t2 = self.theclass(MAXYEAR, 12, 31, 23, 59, 59, 999999,
+                           tzinfo=FixedOffset(-1439, ""))
+
+        # Make sure those compare correctly, and w/o overflow.
+        self.failUnless(t1 < t2)
+        self.failUnless(t1 != t2)
+        self.failUnless(t2 > t1)
+
+        self.failUnless(t1 == t1)
+        self.failUnless(t2 == t2)
+
+        # Equal afer adjustment.
+        t1 = self.theclass(1, 12, 31, 23, 59, tzinfo=FixedOffset(1, ""))
+        t2 = self.theclass(2, 1, 1, 3, 13, tzinfo=FixedOffset(3*60+13+2, ""))
+        self.assertEqual(t1, t2)
+
+        # Change t1 not to subtract a minute, and t1 should be larger.
+        t1 = self.theclass(1, 12, 31, 23, 59, tzinfo=FixedOffset(0, ""))
+        self.failUnless(t1 > t2)
+
+        # Change t1 to subtract 2 minutes, and t1 should be smaller.
+        t1 = self.theclass(1, 12, 31, 23, 59, tzinfo=FixedOffset(2, ""))
+        self.failUnless(t1 < t2)
+
+        # Back to the original t1, but make seconds resolve it.
+        t1 = self.theclass(1, 12, 31, 23, 59, tzinfo=FixedOffset(1, ""),
+                           second=1)
+        self.failUnless(t1 > t2)
+
+        # Likewise, but make microseconds resolve it.
+        t1 = self.theclass(1, 12, 31, 23, 59, tzinfo=FixedOffset(1, ""),
+                           microsecond=1)
+        self.failUnless(t1 > t2)
+
+        # Make t2 naive and it should fail.
+        t2 = self.theclass.min
+        self.assertRaises(TypeError, lambda: t1 == t2)
+        self.assertEqual(t2, t2)
+
+        # It's also naive if it has tzinfo but tzinfo.utcoffset() is None.
+        class Naive(tzinfo):
+            def utcoffset(self, dt): return None
+        t2 = self.theclass(5, 6, 7, tzinfo=Naive())
+        self.assertRaises(TypeError, lambda: t1 == t2)
+        self.assertEqual(t2, t2)
+
+        # OTOH, it's OK to compare two of these mixing the two ways of being
+        # naive.
+        t1 = self.theclass(5, 6, 7)
+        self.assertEqual(t1, t2)
+
+        # Try a bogus uctoffset.
+        class Bogus(tzinfo):
+            def utcoffset(self, dt):
+                return timedelta(minutes=1440) # out of bounds
+        t1 = self.theclass(2, 2, 2, tzinfo=Bogus())
+        t2 = self.theclass(2, 2, 2, tzinfo=FixedOffset(0, ""))
+        self.assertRaises(ValueError, lambda: t1 == t2)
+
+    def test_pickling(self):
+        # Try one without a tzinfo.
+        args = 6, 7, 23, 20, 59, 1, 64**2
+        orig = self.theclass(*args)
+        for pickler, unpickler, proto in pickle_choices:
+            green = pickler.dumps(orig, proto)
+            derived = unpickler.loads(green)
+            self.assertEqual(orig, derived)
+
+        # Try one with a tzinfo.
+        tinfo = PicklableFixedOffset(-300, 'cookie')
+        orig = self.theclass(*args, **{'tzinfo': tinfo})
+        derived = self.theclass(1, 1, 1, tzinfo=FixedOffset(0, "", 0))
+        for pickler, unpickler, proto in pickle_choices:
+            green = pickler.dumps(orig, proto)
+            derived = unpickler.loads(green)
+            self.assertEqual(orig, derived)
+            self.failUnless(isinstance(derived.tzinfo,
+                            PicklableFixedOffset))
+            self.assertEqual(derived.utcoffset(), timedelta(minutes=-300))
+            self.assertEqual(derived.tzname(), 'cookie')
+
+    def test_extreme_hashes(self):
+        # If an attempt is made to hash these via subtracting the offset
+        # then hashing a datetime object, OverflowError results.  The
+        # Python implementation used to blow up here.
+        t = self.theclass(1, 1, 1, tzinfo=FixedOffset(1439, ""))
+        hash(t)
+        t = self.theclass(MAXYEAR, 12, 31, 23, 59, 59, 999999,
+                          tzinfo=FixedOffset(-1439, ""))
+        hash(t)
+
+        # OTOH, an OOB offset should blow up.
+        t = self.theclass(5, 5, 5, tzinfo=FixedOffset(-1440, ""))
+        self.assertRaises(ValueError, hash, t)
+
+    def test_zones(self):
+        est = FixedOffset(-300, "EST")
+        utc = FixedOffset(0, "UTC")
+        met = FixedOffset(60, "MET")
+        t1 = datetime(2002, 3, 19,  7, 47, tzinfo=est)
+        t2 = datetime(2002, 3, 19, 12, 47, tzinfo=utc)
+        t3 = datetime(2002, 3, 19, 13, 47, tzinfo=met)
+        self.assertEqual(t1.tzinfo, est)
+        self.assertEqual(t2.tzinfo, utc)
+        self.assertEqual(t3.tzinfo, met)
+        self.assertEqual(t1.utcoffset(), timedelta(minutes=-300))
+        self.assertEqual(t2.utcoffset(), timedelta(minutes=0))
+        self.assertEqual(t3.utcoffset(), timedelta(minutes=60))
+        self.assertEqual(t1.tzname(), "EST")
+        self.assertEqual(t2.tzname(), "UTC")
+        self.assertEqual(t3.tzname(), "MET")
+        self.assertEqual(hash(t1), hash(t2))
+        self.assertEqual(hash(t1), hash(t3))
+        self.assertEqual(hash(t2), hash(t3))
+        self.assertEqual(t1, t2)
+        self.assertEqual(t1, t3)
+        self.assertEqual(t2, t3)
+        self.assertEqual(str(t1), "2002-03-19 07:47:00-05:00")
+        self.assertEqual(str(t2), "2002-03-19 12:47:00+00:00")
+        self.assertEqual(str(t3), "2002-03-19 13:47:00+01:00")
+        d = 'datetime.datetime(2002, 3, 19, '
+        self.assertEqual(repr(t1), d + "7, 47, tzinfo=est)")
+        self.assertEqual(repr(t2), d + "12, 47, tzinfo=utc)")
+        self.assertEqual(repr(t3), d + "13, 47, tzinfo=met)")
+
+    def test_combine(self):
+        met = FixedOffset(60, "MET")
+        d = date(2002, 3, 4)
+        tz = time(18, 45, 3, 1234, tzinfo=met)
+        dt = datetime.combine(d, tz)
+        self.assertEqual(dt, datetime(2002, 3, 4, 18, 45, 3, 1234,
+                                        tzinfo=met))
+
+    def test_extract(self):
+        met = FixedOffset(60, "MET")
+        dt = self.theclass(2002, 3, 4, 18, 45, 3, 1234, tzinfo=met)
+        self.assertEqual(dt.date(), date(2002, 3, 4))
+        self.assertEqual(dt.time(), time(18, 45, 3, 1234))
+        self.assertEqual(dt.timetz(), time(18, 45, 3, 1234, tzinfo=met))
+
+    def test_tz_aware_arithmetic(self):
+        import random
+
+        now = self.theclass.now()
+        tz55 = FixedOffset(-330, "west 5:30")
+        timeaware = now.time().replace(tzinfo=tz55)
+        nowaware = self.theclass.combine(now.date(), timeaware)
+        self.failUnless(nowaware.tzinfo is tz55)
+        self.assertEqual(nowaware.timetz(), timeaware)
+
+        # Can't mix aware and non-aware.
+        self.assertRaises(TypeError, lambda: now - nowaware)
+        self.assertRaises(TypeError, lambda: nowaware - now)
+
+        # And adding datetime's doesn't make sense, aware or not.
+        self.assertRaises(TypeError, lambda: now + nowaware)
+        self.assertRaises(TypeError, lambda: nowaware + now)
+        self.assertRaises(TypeError, lambda: nowaware + nowaware)
+
+        # Subtracting should yield 0.
+        self.assertEqual(now - now, timedelta(0))
+        self.assertEqual(nowaware - nowaware, timedelta(0))
+
+        # Adding a delta should preserve tzinfo.
+        delta = timedelta(weeks=1, minutes=12, microseconds=5678)
+        nowawareplus = nowaware + delta
+        self.failUnless(nowaware.tzinfo is tz55)
+        nowawareplus2 = delta + nowaware
+        self.failUnless(nowawareplus2.tzinfo is tz55)
+        self.assertEqual(nowawareplus, nowawareplus2)
+
+        # that - delta should be what we started with, and that - what we
+        # started with should be delta.
+        diff = nowawareplus - delta
+        self.failUnless(diff.tzinfo is tz55)
+        self.assertEqual(nowaware, diff)
+        self.assertRaises(TypeError, lambda: delta - nowawareplus)
+        self.assertEqual(nowawareplus - nowaware, delta)
+
+        # Make up a random timezone.
+        tzr = FixedOffset(random.randrange(-1439, 1440), "randomtimezone")
+        # Attach it to nowawareplus.
+        nowawareplus = nowawareplus.replace(tzinfo=tzr)
+        self.failUnless(nowawareplus.tzinfo is tzr)
+        # Make sure the difference takes the timezone adjustments into account.
+        got = nowaware - nowawareplus
+        # Expected:  (nowaware base - nowaware offset) -
+        #            (nowawareplus base - nowawareplus offset) =
+        #            (nowaware base - nowawareplus base) +
+        #            (nowawareplus offset - nowaware offset) =
+        #            -delta + nowawareplus offset - nowaware offset
+        expected = nowawareplus.utcoffset() - nowaware.utcoffset() - delta
+        self.assertEqual(got, expected)
+
+        # Try max possible difference.
+        min = self.theclass(1, 1, 1, tzinfo=FixedOffset(1439, "min"))
+        max = self.theclass(MAXYEAR, 12, 31, 23, 59, 59, 999999,
+                            tzinfo=FixedOffset(-1439, "max"))
+        maxdiff = max - min
+        self.assertEqual(maxdiff, self.theclass.max - self.theclass.min +
+                                  timedelta(minutes=2*1439))
+
+    def test_tzinfo_now(self):
+        meth = self.theclass.now
+        # Ensure it doesn't require tzinfo (i.e., that this doesn't blow up).
+        base = meth()
+        # Try with and without naming the keyword.
+        off42 = FixedOffset(42, "42")
+        another = meth(off42)
+        again = meth(tz=off42)
+        self.failUnless(another.tzinfo is again.tzinfo)
+        self.assertEqual(another.utcoffset(), timedelta(minutes=42))
+        # Bad argument with and w/o naming the keyword.
+        self.assertRaises(TypeError, meth, 16)
+        self.assertRaises(TypeError, meth, tzinfo=16)
+        # Bad keyword name.
+        self.assertRaises(TypeError, meth, tinfo=off42)
+        # Too many args.
+        self.assertRaises(TypeError, meth, off42, off42)
+
+        # We don't know which time zone we're in, and don't have a tzinfo
+        # class to represent it, so seeing whether a tz argument actually
+        # does a conversion is tricky.
+        weirdtz = FixedOffset(timedelta(hours=15, minutes=58), "weirdtz", 0)
+        utc = FixedOffset(0, "utc", 0)
+        for dummy in range(3):
+            now = datetime.now(weirdtz)
+            self.failUnless(now.tzinfo is weirdtz)
+            utcnow = datetime.utcnow().replace(tzinfo=utc)
+            now2 = utcnow.astimezone(weirdtz)
+            if abs(now - now2) < timedelta(seconds=30):
+                break
+            # Else the code is broken, or more than 30 seconds passed between
+            # calls; assuming the latter, just try again.
+        else:
+            # Three strikes and we're out.
+            self.fail("utcnow(), now(tz), or astimezone() may be broken")
+
+    def test_tzinfo_fromtimestamp(self):
+        import time
+        meth = self.theclass.fromtimestamp
+        ts = time.time()
+        # Ensure it doesn't require tzinfo (i.e., that this doesn't blow up).
+        base = meth(ts)
+        # Try with and without naming the keyword.
+        off42 = FixedOffset(42, "42")
+        another = meth(ts, off42)
+        again = meth(ts, tz=off42)
+        self.failUnless(another.tzinfo is again.tzinfo)
+        self.assertEqual(another.utcoffset(), timedelta(minutes=42))
+        # Bad argument with and w/o naming the keyword.
+        self.assertRaises(TypeError, meth, ts, 16)
+        self.assertRaises(TypeError, meth, ts, tzinfo=16)
+        # Bad keyword name.
+        self.assertRaises(TypeError, meth, ts, tinfo=off42)
+        # Too many args.
+        self.assertRaises(TypeError, meth, ts, off42, off42)
+        # Too few args.
+        self.assertRaises(TypeError, meth)
+
+        # Try to make sure tz= actually does some conversion.
+        timestamp = 1000000000
+        utcdatetime = datetime.utcfromtimestamp(timestamp)
+        # In POSIX (epoch 1970), that's 2001-09-09 01:46:40 UTC, give or take.
+        # But on some flavor of Mac, it's nowhere near that.  So we can't have
+        # any idea here what time that actually is, we can only test that
+        # relative changes match.
+        utcoffset = timedelta(hours=-15, minutes=39) # arbitrary, but not zero
+        tz = FixedOffset(utcoffset, "tz", 0)
+        expected = utcdatetime + utcoffset
+        got = datetime.fromtimestamp(timestamp, tz)
+        self.assertEqual(expected, got.replace(tzinfo=None))
+
+    def test_tzinfo_utcnow(self):
+        meth = self.theclass.utcnow
+        # Ensure it doesn't require tzinfo (i.e., that this doesn't blow up).
+        base = meth()
+        # Try with and without naming the keyword; for whatever reason,
+        # utcnow() doesn't accept a tzinfo argument.
+        off42 = FixedOffset(42, "42")
+        self.assertRaises(TypeError, meth, off42)
+        self.assertRaises(TypeError, meth, tzinfo=off42)
+
+    def test_tzinfo_utcfromtimestamp(self):
+        import time
+        meth = self.theclass.utcfromtimestamp
+        ts = time.time()
+        # Ensure it doesn't require tzinfo (i.e., that this doesn't blow up).
+        base = meth(ts)
+        # Try with and without naming the keyword; for whatever reason,
+        # utcfromtimestamp() doesn't accept a tzinfo argument.
+        off42 = FixedOffset(42, "42")
+        self.assertRaises(TypeError, meth, ts, off42)
+        self.assertRaises(TypeError, meth, ts, tzinfo=off42)
+
+    def test_tzinfo_timetuple(self):
+        # TestDateTime tested most of this.  datetime adds a twist to the
+        # DST flag.
+        class DST(tzinfo):
+            def __init__(self, dstvalue):
+                if isinstance(dstvalue, int):
+                    dstvalue = timedelta(minutes=dstvalue)
+                self.dstvalue = dstvalue
+            def dst(self, dt):
+                return self.dstvalue
+
+        cls = self.theclass
+        for dstvalue, flag in (-33, 1), (33, 1), (0, 0), (None, -1):
+            d = cls(1, 1, 1, 10, 20, 30, 40, tzinfo=DST(dstvalue))
+            t = d.timetuple()
+            self.assertEqual(1, t.tm_year)
+            self.assertEqual(1, t.tm_mon)
+            self.assertEqual(1, t.tm_mday)
+            self.assertEqual(10, t.tm_hour)
+            self.assertEqual(20, t.tm_min)
+            self.assertEqual(30, t.tm_sec)
+            self.assertEqual(0, t.tm_wday)
+            self.assertEqual(1, t.tm_yday)
+            self.assertEqual(flag, t.tm_isdst)
+
+        # dst() returns wrong type.
+        self.assertRaises(TypeError, cls(1, 1, 1, tzinfo=DST("x")).timetuple)
+
+        # dst() at the edge.
+        self.assertEqual(cls(1,1,1, tzinfo=DST(1439)).timetuple().tm_isdst, 1)
+        self.assertEqual(cls(1,1,1, tzinfo=DST(-1439)).timetuple().tm_isdst, 1)
+
+        # dst() out of range.
+        self.assertRaises(ValueError, cls(1,1,1, tzinfo=DST(1440)).timetuple)
+        self.assertRaises(ValueError, cls(1,1,1, tzinfo=DST(-1440)).timetuple)
+
+    def test_utctimetuple(self):
+        class DST(tzinfo):
+            def __init__(self, dstvalue):
+                if isinstance(dstvalue, int):
+                    dstvalue = timedelta(minutes=dstvalue)
+                self.dstvalue = dstvalue
+            def dst(self, dt):
+                return self.dstvalue
+
+        cls = self.theclass
+        # This can't work:  DST didn't implement utcoffset.
+        self.assertRaises(NotImplementedError,
+                          cls(1, 1, 1, tzinfo=DST(0)).utcoffset)
+
+        class UOFS(DST):
+            def __init__(self, uofs, dofs=None):
+                DST.__init__(self, dofs)
+                self.uofs = timedelta(minutes=uofs)
+            def utcoffset(self, dt):
+                return self.uofs
+
+        # Ensure tm_isdst is 0 regardless of what dst() says:  DST is never
+        # in effect for a UTC time.
+        for dstvalue in -33, 33, 0, None:
+            d = cls(1, 2, 3, 10, 20, 30, 40, tzinfo=UOFS(-53, dstvalue))
+            t = d.utctimetuple()
+            self.assertEqual(d.year, t.tm_year)
+            self.assertEqual(d.month, t.tm_mon)
+            self.assertEqual(d.day, t.tm_mday)
+            self.assertEqual(11, t.tm_hour) # 20mm + 53mm = 1hn + 13mm
+            self.assertEqual(13, t.tm_min)
+            self.assertEqual(d.second, t.tm_sec)
+            self.assertEqual(d.weekday(), t.tm_wday)
+            self.assertEqual(d.toordinal() - date(1, 1, 1).toordinal() + 1,
+                             t.tm_yday)
+            self.assertEqual(0, t.tm_isdst)
+
+        # At the edges, UTC adjustment can normalize into years out-of-range
+        # for a datetime object.  Ensure that a correct timetuple is
+        # created anyway.
+        tiny = cls(MINYEAR, 1, 1, 0, 0, 37, tzinfo=UOFS(1439))
+        # That goes back 1 minute less than a full day.
+        t = tiny.utctimetuple()
+        self.assertEqual(t.tm_year, MINYEAR-1)
+        self.assertEqual(t.tm_mon, 12)
+        self.assertEqual(t.tm_mday, 31)
+        self.assertEqual(t.tm_hour, 0)
+        self.assertEqual(t.tm_min, 1)
+        self.assertEqual(t.tm_sec, 37)
+        self.assertEqual(t.tm_yday, 366)    # "year 0" is a leap year
+        self.assertEqual(t.tm_isdst, 0)
+
+        huge = cls(MAXYEAR, 12, 31, 23, 59, 37, 999999, tzinfo=UOFS(-1439))
+        # That goes forward 1 minute less than a full day.
+        t = huge.utctimetuple()
+        self.assertEqual(t.tm_year, MAXYEAR+1)
+        self.assertEqual(t.tm_mon, 1)
+        self.assertEqual(t.tm_mday, 1)
+        self.assertEqual(t.tm_hour, 23)
+        self.assertEqual(t.tm_min, 58)
+        self.assertEqual(t.tm_sec, 37)
+        self.assertEqual(t.tm_yday, 1)
+        self.assertEqual(t.tm_isdst, 0)
+
+    def test_tzinfo_isoformat(self):
+        zero = FixedOffset(0, "+00:00")
+        plus = FixedOffset(220, "+03:40")
+        minus = FixedOffset(-231, "-03:51")
+        unknown = FixedOffset(None, "")
+
+        cls = self.theclass
+        datestr = '0001-02-03'
+        for ofs in None, zero, plus, minus, unknown:
+            for us in 0, 987001:
+                d = cls(1, 2, 3, 4, 5, 59, us, tzinfo=ofs)
+                timestr = '04:05:59' + (us and '.987001' or '')
+                ofsstr = ofs is not None and d.tzname() or ''
+                tailstr = timestr + ofsstr
+                iso = d.isoformat()
+                self.assertEqual(iso, datestr + 'T' + tailstr)
+                self.assertEqual(iso, d.isoformat('T'))
+                self.assertEqual(d.isoformat('k'), datestr + 'k' + tailstr)
+                self.assertEqual(str(d), datestr + ' ' + tailstr)
+
+    def test_replace(self):
+        cls = self.theclass
+        z100 = FixedOffset(100, "+100")
+        zm200 = FixedOffset(timedelta(minutes=-200), "-200")
+        args = [1, 2, 3, 4, 5, 6, 7, z100]
+        base = cls(*args)
+        self.assertEqual(base, base.replace())
+
+        i = 0
+        for name, newval in (("year", 2),
+                             ("month", 3),
+                             ("day", 4),
+                             ("hour", 5),
+                             ("minute", 6),
+                             ("second", 7),
+                             ("microsecond", 8),
+                             ("tzinfo", zm200)):
+            newargs = args[:]
+            newargs[i] = newval
+            expected = cls(*newargs)
+            got = base.replace(**{name: newval})
+            self.assertEqual(expected, got)
+            i += 1
+
+        # Ensure we can get rid of a tzinfo.
+        self.assertEqual(base.tzname(), "+100")
+        base2 = base.replace(tzinfo=None)
+        self.failUnless(base2.tzinfo is None)
+        self.failUnless(base2.tzname() is None)
+
+        # Ensure we can add one.
+        base3 = base2.replace(tzinfo=z100)
+        self.assertEqual(base, base3)
+        self.failUnless(base.tzinfo is base3.tzinfo)
+
+        # Out of bounds.
+        base = cls(2000, 2, 29)
+        self.assertRaises(ValueError, base.replace, year=2001)
+
+    def test_more_astimezone(self):
+        # The inherited test_astimezone covered some trivial and error cases.
+        fnone = FixedOffset(None, "None")
+        f44m = FixedOffset(44, "44")
+        fm5h = FixedOffset(-timedelta(hours=5), "m300")
+
+        dt = self.theclass.now(tz=f44m)
+        self.failUnless(dt.tzinfo is f44m)
+        # Replacing with degenerate tzinfo raises an exception.
+        self.assertRaises(ValueError, dt.astimezone, fnone)
+        # Ditto with None tz.
+        self.assertRaises(TypeError, dt.astimezone, None)
+        # Replacing with same tzinfo makes no change.
+        x = dt.astimezone(dt.tzinfo)
+        self.failUnless(x.tzinfo is f44m)
+        self.assertEqual(x.date(), dt.date())
+        self.assertEqual(x.time(), dt.time())
+
+        # Replacing with different tzinfo does adjust.
+        got = dt.astimezone(fm5h)
+        self.failUnless(got.tzinfo is fm5h)
+        self.assertEqual(got.utcoffset(), timedelta(hours=-5))
+        expected = dt - dt.utcoffset()  # in effect, convert to UTC
+        expected += fm5h.utcoffset(dt)  # and from there to local time
+        expected = expected.replace(tzinfo=fm5h) # and attach new tzinfo
+        self.assertEqual(got.date(), expected.date())
+        self.assertEqual(got.time(), expected.time())
+        self.assertEqual(got.timetz(), expected.timetz())
+        self.failUnless(got.tzinfo is expected.tzinfo)
+        self.assertEqual(got, expected)
+
+    def test_aware_subtract(self):
+        cls = self.theclass
+
+        # Ensure that utcoffset() is ignored when the operands have the
+        # same tzinfo member.
+        class OperandDependentOffset(tzinfo):
+            def utcoffset(self, t):
+                if t.minute < 10:
+                    # d0 and d1 equal after adjustment
+                    return timedelta(minutes=t.minute)
+                else:
+                    # d2 off in the weeds
+                    return timedelta(minutes=59)
+
+        base = cls(8, 9, 10, 11, 12, 13, 14, tzinfo=OperandDependentOffset())
+        d0 = base.replace(minute=3)
+        d1 = base.replace(minute=9)
+        d2 = base.replace(minute=11)
+        for x in d0, d1, d2:
+            for y in d0, d1, d2:
+                got = x - y
+                expected = timedelta(minutes=x.minute - y.minute)
+                self.assertEqual(got, expected)
+
+        # OTOH, if the tzinfo members are distinct, utcoffsets aren't
+        # ignored.
+        base = cls(8, 9, 10, 11, 12, 13, 14)
+        d0 = base.replace(minute=3, tzinfo=OperandDependentOffset())
+        d1 = base.replace(minute=9, tzinfo=OperandDependentOffset())
+        d2 = base.replace(minute=11, tzinfo=OperandDependentOffset())
+        for x in d0, d1, d2:
+            for y in d0, d1, d2:
+                got = x - y
+                if (x is d0 or x is d1) and (y is d0 or y is d1):
+                    expected = timedelta(0)
+                elif x is y is d2:
+                    expected = timedelta(0)
+                elif x is d2:
+                    expected = timedelta(minutes=(11-59)-0)
+                else:
+                    assert y is d2
+                    expected = timedelta(minutes=0-(11-59))
+                self.assertEqual(got, expected)
+
+    def test_mixed_compare(self):
+        t1 = datetime(1, 2, 3, 4, 5, 6, 7)
+        t2 = datetime(1, 2, 3, 4, 5, 6, 7)
+        self.assertEqual(t1, t2)
+        t2 = t2.replace(tzinfo=None)
+        self.assertEqual(t1, t2)
+        t2 = t2.replace(tzinfo=FixedOffset(None, ""))
+        self.assertEqual(t1, t2)
+        t2 = t2.replace(tzinfo=FixedOffset(0, ""))
+        self.assertRaises(TypeError, lambda: t1 == t2)
+
+        # In datetime w/ identical tzinfo objects, utcoffset is ignored.
+        class Varies(tzinfo):
+            def __init__(self):
+                self.offset = timedelta(minutes=22)
+            def utcoffset(self, t):
+                self.offset += timedelta(minutes=1)
+                return self.offset
+
+        v = Varies()
+        t1 = t2.replace(tzinfo=v)
+        t2 = t2.replace(tzinfo=v)
+        self.assertEqual(t1.utcoffset(), timedelta(minutes=23))
+        self.assertEqual(t2.utcoffset(), timedelta(minutes=24))
+        self.assertEqual(t1, t2)
+
+        # But if they're not identical, it isn't ignored.
+        t2 = t2.replace(tzinfo=Varies())
+        self.failUnless(t1 < t2)  # t1's offset counter still going up
+
+    def test_subclass_datetimetz(self):
+
+        class C(self.theclass):
+            theAnswer = 42
+
+            def __new__(cls, *args, **kws):
+                temp = kws.copy()
+                extra = temp.pop('extra')
+                result = self.theclass.__new__(cls, *args, **temp)
+                result.extra = extra
+                return result
+
+            def newmeth(self, start):
+                return start + self.hour + self.year
+
+        args = 2002, 12, 31, 4, 5, 6, 500, FixedOffset(-300, "EST", 1)
+
+        dt1 = self.theclass(*args)
+        dt2 = C(*args, **{'extra': 7})
+
+        self.assertEqual(dt2.__class__, C)
+        self.assertEqual(dt2.theAnswer, 42)
+        self.assertEqual(dt2.extra, 7)
+        self.assertEqual(dt1.utcoffset(), dt2.utcoffset())
+        self.assertEqual(dt2.newmeth(-7), dt1.hour + dt1.year - 7)
+
+# Pain to set up DST-aware tzinfo classes.
+
+def first_sunday_on_or_after(dt):
+    days_to_go = 6 - dt.weekday()
+    if days_to_go:
+        dt += timedelta(days_to_go)
+    return dt
+
+ZERO = timedelta(0)
+HOUR = timedelta(hours=1)
+DAY = timedelta(days=1)
+# In the US, DST starts at 2am (standard time) on the first Sunday in April.
+DSTSTART = datetime(1, 4, 1, 2)
+# and ends at 2am (DST time; 1am standard time) on the last Sunday of Oct,
+# which is the first Sunday on or after Oct 25.  Because we view 1:MM as
+# being standard time on that day, there is no spelling in local time of
+# the last hour of DST (that's 1:MM DST, but 1:MM is taken as standard time).
+DSTEND = datetime(1, 10, 25, 1)
+
+class USTimeZone(tzinfo):
+
+    def __init__(self, hours, reprname, stdname, dstname):
+        self.stdoffset = timedelta(hours=hours)
+        self.reprname = reprname
+        self.stdname = stdname
+        self.dstname = dstname
+
+    def __repr__(self):
+        return self.reprname
+
+    def tzname(self, dt):
+        if self.dst(dt):
+            return self.dstname
+        else:
+            return self.stdname
+
+    def utcoffset(self, dt):
+        return self.stdoffset + self.dst(dt)
+
+    def dst(self, dt):
+        if dt is None or dt.tzinfo is None:
+            # An exception instead may be sensible here, in one or more of
+            # the cases.
+            return ZERO
+        assert dt.tzinfo is self
+
+        # Find first Sunday in April.
+        start = first_sunday_on_or_after(DSTSTART.replace(year=dt.year))
+        assert start.weekday() == 6 and start.month == 4 and start.day <= 7
+
+        # Find last Sunday in October.
+        end = first_sunday_on_or_after(DSTEND.replace(year=dt.year))
+        assert end.weekday() == 6 and end.month == 10 and end.day >= 25
+
+        # Can't compare naive to aware objects, so strip the timezone from
+        # dt first.
+        if start <= dt.replace(tzinfo=None) < end:
+            return HOUR
+        else:
+            return ZERO
+
+Eastern  = USTimeZone(-5, "Eastern",  "EST", "EDT")
+Central  = USTimeZone(-6, "Central",  "CST", "CDT")
+Mountain = USTimeZone(-7, "Mountain", "MST", "MDT")
+Pacific  = USTimeZone(-8, "Pacific",  "PST", "PDT")
+utc_real = FixedOffset(0, "UTC", 0)
+# For better test coverage, we want another flavor of UTC that's west of
+# the Eastern and Pacific timezones.
+utc_fake = FixedOffset(-12*60, "UTCfake", 0)
+
+class TestTimezoneConversions(unittest.TestCase):
+    # The DST switch times for 2002, in std time.
+    dston = datetime(2002, 4, 7, 2)
+    dstoff = datetime(2002, 10, 27, 1)
+
+    theclass = datetime
+
+    # Check a time that's inside DST.
+    def checkinside(self, dt, tz, utc, dston, dstoff):
+        self.assertEqual(dt.dst(), HOUR)
+
+        # Conversion to our own timezone is always an identity.
+        self.assertEqual(dt.astimezone(tz), dt)
+
+        asutc = dt.astimezone(utc)
+        there_and_back = asutc.astimezone(tz)
+
+        # Conversion to UTC and back isn't always an identity here,
+        # because there are redundant spellings (in local time) of
+        # UTC time when DST begins:  the clock jumps from 1:59:59
+        # to 3:00:00, and a local time of 2:MM:SS doesn't really
+        # make sense then.  The classes above treat 2:MM:SS as
+        # daylight time then (it's "after 2am"), really an alias
+        # for 1:MM:SS standard time.  The latter form is what
+        # conversion back from UTC produces.
+        if dt.date() == dston.date() and dt.hour == 2:
+            # We're in the redundant hour, and coming back from
+            # UTC gives the 1:MM:SS standard-time spelling.
+            self.assertEqual(there_and_back + HOUR, dt)
+            # Although during was considered to be in daylight
+            # time, there_and_back is not.
+            self.assertEqual(there_and_back.dst(), ZERO)
+            # They're the same times in UTC.
+            self.assertEqual(there_and_back.astimezone(utc),
+                             dt.astimezone(utc))
+        else:
+            # We're not in the redundant hour.
+            self.assertEqual(dt, there_and_back)
+
+        # Because we have a redundant spelling when DST begins, there is
+        # (unforunately) an hour when DST ends that can't be spelled at all in
+        # local time.  When DST ends, the clock jumps from 1:59 back to 1:00
+        # again.  The hour 1:MM DST has no spelling then:  1:MM is taken to be
+        # standard time.  1:MM DST == 0:MM EST, but 0:MM is taken to be
+        # daylight time.  The hour 1:MM daylight == 0:MM standard can't be
+        # expressed in local time.  Nevertheless, we want conversion back
+        # from UTC to mimic the local clock's "repeat an hour" behavior.
+        nexthour_utc = asutc + HOUR
+        nexthour_tz = nexthour_utc.astimezone(tz)
+        if dt.date() == dstoff.date() and dt.hour == 0:
+            # We're in the hour before the last DST hour.  The last DST hour
+            # is ineffable.  We want the conversion back to repeat 1:MM.
+            self.assertEqual(nexthour_tz, dt.replace(hour=1))
+            nexthour_utc += HOUR
+            nexthour_tz = nexthour_utc.astimezone(tz)
+            self.assertEqual(nexthour_tz, dt.replace(hour=1))
+        else:
+            self.assertEqual(nexthour_tz - dt, HOUR)
+
+    # Check a time that's outside DST.
+    def checkoutside(self, dt, tz, utc):
+        self.assertEqual(dt.dst(), ZERO)
+
+        # Conversion to our own timezone is always an identity.
+        self.assertEqual(dt.astimezone(tz), dt)
+
+        # Converting to UTC and back is an identity too.
+        asutc = dt.astimezone(utc)
+        there_and_back = asutc.astimezone(tz)
+        self.assertEqual(dt, there_and_back)
+
+    def convert_between_tz_and_utc(self, tz, utc):
+        dston = self.dston.replace(tzinfo=tz)
+        # Because 1:MM on the day DST ends is taken as being standard time,
+        # there is no spelling in tz for the last hour of daylight time.
+        # For purposes of the test, the last hour of DST is 0:MM, which is
+        # taken as being daylight time (and 1:MM is taken as being standard
+        # time).
+        dstoff = self.dstoff.replace(tzinfo=tz)
+        for delta in (timedelta(weeks=13),
+                      DAY,
+                      HOUR,
+                      timedelta(minutes=1),
+                      timedelta(microseconds=1)):
+
+            self.checkinside(dston, tz, utc, dston, dstoff)
+            for during in dston + delta, dstoff - delta:
+                self.checkinside(during, tz, utc, dston, dstoff)
+
+            self.checkoutside(dstoff, tz, utc)
+            for outside in dston - delta, dstoff + delta:
+                self.checkoutside(outside, tz, utc)
+
+    def test_easy(self):
+        # Despite the name of this test, the endcases are excruciating.
+        self.convert_between_tz_and_utc(Eastern, utc_real)
+        self.convert_between_tz_and_utc(Pacific, utc_real)
+        self.convert_between_tz_and_utc(Eastern, utc_fake)
+        self.convert_between_tz_and_utc(Pacific, utc_fake)
+        # The next is really dancing near the edge.  It works because
+        # Pacific and Eastern are far enough apart that their "problem
+        # hours" don't overlap.
+        self.convert_between_tz_and_utc(Eastern, Pacific)
+        self.convert_between_tz_and_utc(Pacific, Eastern)
+        # OTOH, these fail!  Don't enable them.  The difficulty is that
+        # the edge case tests assume that every hour is representable in
+        # the "utc" class.  This is always true for a fixed-offset tzinfo
+        # class (lke utc_real and utc_fake), but not for Eastern or Central.
+        # For these adjacent DST-aware time zones, the range of time offsets
+        # tested ends up creating hours in the one that aren't representable
+        # in the other.  For the same reason, we would see failures in the
+        # Eastern vs Pacific tests too if we added 3*HOUR to the list of
+        # offset deltas in convert_between_tz_and_utc().
+        #
+        # self.convert_between_tz_and_utc(Eastern, Central)  # can't work
+        # self.convert_between_tz_and_utc(Central, Eastern)  # can't work
+
+    def test_tricky(self):
+        # 22:00 on day before daylight starts.
+        fourback = self.dston - timedelta(hours=4)
+        ninewest = FixedOffset(-9*60, "-0900", 0)
+        fourback = fourback.replace(tzinfo=ninewest)
+        # 22:00-0900 is 7:00 UTC == 2:00 EST == 3:00 DST.  Since it's "after
+        # 2", we should get the 3 spelling.
+        # If we plug 22:00 the day before into Eastern, it "looks like std
+        # time", so its offset is returned as -5, and -5 - -9 = 4.  Adding 4
+        # to 22:00 lands on 2:00, which makes no sense in local time (the
+        # local clock jumps from 1 to 3).  The point here is to make sure we
+        # get the 3 spelling.
+        expected = self.dston.replace(hour=3)
+        got = fourback.astimezone(Eastern).replace(tzinfo=None)
+        self.assertEqual(expected, got)
+
+        # Similar, but map to 6:00 UTC == 1:00 EST == 2:00 DST.  In that
+        # case we want the 1:00 spelling.
+        sixutc = self.dston.replace(hour=6, tzinfo=utc_real)
+        # Now 6:00 "looks like daylight", so the offset wrt Eastern is -4,
+        # and adding -4-0 == -4 gives the 2:00 spelling.  We want the 1:00 EST
+        # spelling.
+        expected = self.dston.replace(hour=1)
+        got = sixutc.astimezone(Eastern).replace(tzinfo=None)
+        self.assertEqual(expected, got)
+
+        # Now on the day DST ends, we want "repeat an hour" behavior.
+        #  UTC  4:MM  5:MM  6:MM  7:MM  checking these
+        #  EST 23:MM  0:MM  1:MM  2:MM
+        #  EDT  0:MM  1:MM  2:MM  3:MM
+        # wall  0:MM  1:MM  1:MM  2:MM  against these
+        for utc in utc_real, utc_fake:
+            for tz in Eastern, Pacific:
+                first_std_hour = self.dstoff - timedelta(hours=2) # 23:MM
+                # Convert that to UTC.
+                first_std_hour -= tz.utcoffset(None)
+                # Adjust for possibly fake UTC.
+                asutc = first_std_hour + utc.utcoffset(None)
+                # First UTC hour to convert; this is 4:00 when utc=utc_real &
+                # tz=Eastern.
+                asutcbase = asutc.replace(tzinfo=utc)
+                for tzhour in (0, 1, 1, 2):
+                    expectedbase = self.dstoff.replace(hour=tzhour)
+                    for minute in 0, 30, 59:
+                        expected = expectedbase.replace(minute=minute)
+                        asutc = asutcbase.replace(minute=minute)
+                        astz = asutc.astimezone(tz)
+                        self.assertEqual(astz.replace(tzinfo=None), expected)
+                    asutcbase += HOUR
+
+
+    def test_bogus_dst(self):
+        class ok(tzinfo):
+            def utcoffset(self, dt): return HOUR
+            def dst(self, dt): return HOUR
+
+        now = self.theclass.now().replace(tzinfo=utc_real)
+        # Doesn't blow up.
+        now.astimezone(ok())
+
+        # Does blow up.
+        class notok(ok):
+            def dst(self, dt): return None
+        self.assertRaises(ValueError, now.astimezone, notok())
+
+    def test_fromutc(self):
+        self.assertRaises(TypeError, Eastern.fromutc)   # not enough args
+        now = datetime.utcnow().replace(tzinfo=utc_real)
+        self.assertRaises(ValueError, Eastern.fromutc, now) # wrong tzinfo
+        now = now.replace(tzinfo=Eastern)   # insert correct tzinfo
+        enow = Eastern.fromutc(now)         # doesn't blow up
+        self.assertEqual(enow.tzinfo, Eastern) # has right tzinfo member
+        self.assertRaises(TypeError, Eastern.fromutc, now, now) # too many args
+        self.assertRaises(TypeError, Eastern.fromutc, date.today()) # wrong type
+
+        # Always converts UTC to standard time.
+        class FauxUSTimeZone(USTimeZone):
+            def fromutc(self, dt):
+                return dt + self.stdoffset
+        FEastern  = FauxUSTimeZone(-5, "FEastern",  "FEST", "FEDT")
+
+        #  UTC  4:MM  5:MM  6:MM  7:MM  8:MM  9:MM
+        #  EST 23:MM  0:MM  1:MM  2:MM  3:MM  4:MM
+        #  EDT  0:MM  1:MM  2:MM  3:MM  4:MM  5:MM
+
+        # Check around DST start.
+        start = self.dston.replace(hour=4, tzinfo=Eastern)
+        fstart = start.replace(tzinfo=FEastern)
+        for wall in 23, 0, 1, 3, 4, 5:
+            expected = start.replace(hour=wall)
+            if wall == 23:
+                expected -= timedelta(days=1)
+            got = Eastern.fromutc(start)
+            self.assertEqual(expected, got)
+
+            expected = fstart + FEastern.stdoffset
+            got = FEastern.fromutc(fstart)
+            self.assertEqual(expected, got)
+
+            # Ensure astimezone() calls fromutc() too.
+            got = fstart.replace(tzinfo=utc_real).astimezone(FEastern)
+            self.assertEqual(expected, got)
+
+            start += HOUR
+            fstart += HOUR
+
+        # Check around DST end.
+        start = self.dstoff.replace(hour=4, tzinfo=Eastern)
+        fstart = start.replace(tzinfo=FEastern)
+        for wall in 0, 1, 1, 2, 3, 4:
+            expected = start.replace(hour=wall)
+            got = Eastern.fromutc(start)
+            self.assertEqual(expected, got)
+
+            expected = fstart + FEastern.stdoffset
+            got = FEastern.fromutc(fstart)
+            self.assertEqual(expected, got)
+
+            # Ensure astimezone() calls fromutc() too.
+            got = fstart.replace(tzinfo=utc_real).astimezone(FEastern)
+            self.assertEqual(expected, got)
+
+            start += HOUR
+            fstart += HOUR
+
+
+#############################################################################
+# oddballs
+
+class Oddballs(unittest.TestCase):
+
+    def test_bug_1028306(self):
+        # Trying to compare a date to a datetime should act like a mixed-
+        # type comparison, despite that datetime is a subclass of date.
+        as_date = date.today()
+        as_datetime = datetime.combine(as_date, time())
+        self.assert_(as_date != as_datetime)
+        self.assert_(as_datetime != as_date)
+        self.assert_(not as_date == as_datetime)
+        self.assert_(not as_datetime == as_date)
+        self.assertRaises(TypeError, lambda: as_date < as_datetime)
+        self.assertRaises(TypeError, lambda: as_datetime < as_date)
+        self.assertRaises(TypeError, lambda: as_date <= as_datetime)
+        self.assertRaises(TypeError, lambda: as_datetime <= as_date)
+        self.assertRaises(TypeError, lambda: as_date > as_datetime)
+        self.assertRaises(TypeError, lambda: as_datetime > as_date)
+        self.assertRaises(TypeError, lambda: as_date >= as_datetime)
+        self.assertRaises(TypeError, lambda: as_datetime >= as_date)
+
+        # Neverthelss, comparison should work with the base-class (date)
+        # projection if use of a date method is forced.
+        self.assert_(as_date.__eq__(as_datetime))
+        different_day = (as_date.day + 1) % 20 + 1
+        self.assert_(not as_date.__eq__(as_datetime.replace(day=
+                                                     different_day)))
+
+        # And date should compare with other subclasses of date.  If a
+        # subclass wants to stop this, it's up to the subclass to do so.
+        date_sc = SubclassDate(as_date.year, as_date.month, as_date.day)
+        self.assertEqual(as_date, date_sc)
+        self.assertEqual(date_sc, as_date)
+
+        # Ditto for datetimes.
+        datetime_sc = SubclassDatetime(as_datetime.year, as_datetime.month,
+                                       as_date.day, 0, 0, 0)
+        self.assertEqual(as_datetime, datetime_sc)
+        self.assertEqual(datetime_sc, as_datetime)
+
+def test_suite():
+    allsuites = [unittest.makeSuite(klass, 'test')
+                 for klass in (TestModule,
+                               TestTZInfo,
+                               TestTimeDelta,
+                               TestDateOnly,
+                               TestDate,
+                               TestDateTime,
+                               TestTime,
+                               TestTimeTZ,
+                               TestDateTimeTZ,
+                               TestTimezoneConversions,
+                               Oddballs,
+                              )
+                ]
+    return unittest.TestSuite(allsuites)
+
+def test_main():
+    import gc
+    import sys
+
+    thesuite = test_suite()
+    lastrc = None
+    while True:
+        test_support.run_suite(thesuite)
+        if 1:       # change to 0, under a debug build, for some leak detection
+            break
+        gc.collect()
+        if gc.garbage:
+            raise SystemError("gc.garbage not empty after test run: %r" %
+                              gc.garbage)
+        if hasattr(sys, 'gettotalrefcount'):
+            thisrc = sys.gettotalrefcount()
+            print >> sys.stderr, '*' * 10, 'total refs:', thisrc,
+            if lastrc:
+                print >> sys.stderr, 'delta:', thisrc - lastrc
+            else:
+                print >> sys.stderr
+            lastrc = thisrc
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_dbm.py
===================================================================
--- vendor/Python/current/Lib/test/test_dbm.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_dbm.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,55 @@
+#! /usr/bin/env python
+"""Test script for the dbm module
+   Roger E. Masse
+"""
+import os
+import random
+import dbm
+from dbm import error
+from test.test_support import verbose, verify, TestSkipped, TESTFN
+
+# make filename unique to allow multiple concurrent tests
+# and to minimize the likelihood of a problem from an old file
+filename = TESTFN
+
+def cleanup():
+    for suffix in ['', '.pag', '.dir', '.db']:
+        try:
+            os.unlink(filename + suffix)
+        except OSError, (errno, strerror):
+            # if we can't delete the file because of permissions,
+            # nothing will work, so skip the test
+            if errno == 1:
+                raise TestSkipped, 'unable to remove: ' + filename + suffix
+
+def test_keys():
+    d = dbm.open(filename, 'c')
+    verify(d.keys() == [])
+    d['a'] = 'b'
+    d['12345678910'] = '019237410982340912840198242'
+    d.keys()
+    if d.has_key('a'):
+        if verbose:
+            print 'Test dbm keys: ', d.keys()
+
+    d.close()
+
+def test_modes():
+    d = dbm.open(filename, 'r')
+    d.close()
+    d = dbm.open(filename, 'rw')
+    d.close()
+    d = dbm.open(filename, 'w')
+    d.close()
+    d = dbm.open(filename, 'n')
+    d.close()
+
+cleanup()
+try:
+    test_keys()
+    test_modes()
+except:
+    cleanup()
+    raise
+
+cleanup()


Property changes on: vendor/Python/current/Lib/test/test_dbm.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/test/test_decimal.py
===================================================================
--- vendor/Python/current/Lib/test/test_decimal.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_decimal.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1133 @@
+# Copyright (c) 2004 Python Software Foundation.
+# All rights reserved.
+
+# Written by Eric Price <eprice at tjhsst.edu>
+#    and Facundo Batista <facundo at taniquetil.com.ar>
+#    and Raymond Hettinger <python at rcn.com>
+#    and Aahz (aahz at pobox.com)
+#    and Tim Peters
+
+"""
+These are the test cases for the Decimal module.
+
+There are two groups of tests, Arithmetic and Behaviour. The former test
+the Decimal arithmetic using the tests provided by Mike Cowlishaw. The latter
+test the pythonic behaviour according to PEP 327.
+
+Cowlishaw's tests can be downloaded from:
+
+   www2.hursley.ibm.com/decimal/dectest.zip
+
+This test module can be called from command line with one parameter (Arithmetic
+or Behaviour) to test each part, or without parameter to test both parts. If
+you're working through IDLE, you can import this test module and call test_main()
+with the corresponding argument.
+"""
+from __future__ import with_statement
+
+import unittest
+import glob
+import os, sys
+import pickle, copy
+from decimal import *
+from test.test_support import (TestSkipped, run_unittest, run_doctest,
+                               is_resource_enabled)
+import random
+try:
+    import threading
+except ImportError:
+    threading = None
+
+# Useful Test Constant
+Signals = getcontext().flags.keys()
+
+# Tests are built around these assumed context defaults.
+# test_main() restores the original context.
+def init():
+    global ORIGINAL_CONTEXT
+    ORIGINAL_CONTEXT = getcontext().copy()
+    DefaultContext.prec = 9
+    DefaultContext.rounding = ROUND_HALF_EVEN
+    DefaultContext.traps = dict.fromkeys(Signals, 0)
+    setcontext(DefaultContext)
+
+TESTDATADIR = 'decimaltestdata'
+if __name__ == '__main__':
+    file = sys.argv[0]
+else:
+    file = __file__
+testdir = os.path.dirname(file) or os.curdir
+directory = testdir + os.sep + TESTDATADIR + os.sep
+
+skip_expected = not os.path.isdir(directory)
+
+# Make sure it actually raises errors when not expected and caught in flags
+# Slower, since it runs some things several times.
+EXTENDEDERRORTEST = False
+
+
+#Map the test cases' error names to the actual errors
+
+ErrorNames = {'clamped' : Clamped,
+              'conversion_syntax' : InvalidOperation,
+              'division_by_zero' : DivisionByZero,
+              'division_impossible' : InvalidOperation,
+              'division_undefined' : InvalidOperation,
+              'inexact' : Inexact,
+              'invalid_context' : InvalidOperation,
+              'invalid_operation' : InvalidOperation,
+              'overflow' : Overflow,
+              'rounded' : Rounded,
+              'subnormal' : Subnormal,
+              'underflow' : Underflow}
+
+
+def Nonfunction(*args):
+    """Doesn't do anything."""
+    return None
+
+RoundingDict = {'ceiling' : ROUND_CEILING, #Maps test-case names to roundings.
+                'down' : ROUND_DOWN,
+                'floor' : ROUND_FLOOR,
+                'half_down' : ROUND_HALF_DOWN,
+                'half_even' : ROUND_HALF_EVEN,
+                'half_up' : ROUND_HALF_UP,
+                'up' : ROUND_UP}
+
+# Name adapter to be able to change the Decimal and Context
+# interface without changing the test files from Cowlishaw
+nameAdapter = {'toeng':'to_eng_string',
+               'tosci':'to_sci_string',
+               'samequantum':'same_quantum',
+               'tointegral':'to_integral',
+               'remaindernear':'remainder_near',
+               'divideint':'divide_int',
+               'squareroot':'sqrt',
+               'apply':'_apply',
+              }
+
+class DecimalTest(unittest.TestCase):
+    """Class which tests the Decimal class against the test cases.
+
+    Changed for unittest.
+    """
+    def setUp(self):
+        self.context = Context()
+        for key in DefaultContext.traps.keys():
+            DefaultContext.traps[key] = 1
+        self.ignore_list = ['#']
+        # Basically, a # means return NaN InvalidOperation.
+        # Different from a sNaN in trim
+
+        self.ChangeDict = {'precision' : self.change_precision,
+                      'rounding' : self.change_rounding_method,
+                      'maxexponent' : self.change_max_exponent,
+                      'minexponent' : self.change_min_exponent,
+                      'clamp' : self.change_clamp}
+
+    def tearDown(self):
+        """Cleaning up enviroment."""
+        # leaving context in original state
+        for key in DefaultContext.traps.keys():
+            DefaultContext.traps[key] = 0
+        return
+
+    def eval_file(self, file):
+        global skip_expected
+        if skip_expected:
+            raise TestSkipped
+            return
+        for line in open(file).xreadlines():
+            line = line.replace('\r\n', '').replace('\n', '')
+            #print line
+            try:
+                t = self.eval_line(line)
+            except InvalidOperation:
+                print 'Error in test cases:'
+                print line
+                continue
+            except DecimalException, exception:
+                #Exception raised where there shoudn't have been one.
+                self.fail('Exception "'+exception.__class__.__name__ + '" raised on line '+line)
+
+        return
+
+    def eval_line(self, s):
+        if s.find(' -> ') >= 0 and s[:2] != '--' and not s.startswith('  --'):
+            s = (s.split('->')[0] + '->' +
+                 s.split('->')[1].split('--')[0]).strip()
+        else:
+            s = s.split('--')[0].strip()
+
+        for ignore in self.ignore_list:
+            if s.find(ignore) >= 0:
+                #print s.split()[0], 'NotImplemented--', ignore
+                return
+        if not s:
+            return
+        elif ':' in s:
+            return self.eval_directive(s)
+        else:
+            return self.eval_equation(s)
+
+    def eval_directive(self, s):
+        funct, value = map(lambda x: x.strip().lower(), s.split(':'))
+        if funct == 'rounding':
+            value = RoundingDict[value]
+        else:
+            try:
+                value = int(value)
+            except ValueError:
+                pass
+
+        funct = self.ChangeDict.get(funct, Nonfunction)
+        funct(value)
+
+    def eval_equation(self, s):
+        #global DEFAULT_PRECISION
+        #print DEFAULT_PRECISION
+
+        if not TEST_ALL and random.random() < 0.90:
+            return
+
+        try:
+            Sides = s.split('->')
+            L = Sides[0].strip().split()
+            id = L[0]
+#            print id,
+            funct = L[1].lower()
+            valstemp = L[2:]
+            L = Sides[1].strip().split()
+            ans = L[0]
+            exceptions = L[1:]
+        except (TypeError, AttributeError, IndexError):
+            raise InvalidOperation
+        def FixQuotes(val):
+            val = val.replace("''", 'SingleQuote').replace('""', 'DoubleQuote')
+            val = val.replace("'", '').replace('"', '')
+            val = val.replace('SingleQuote', "'").replace('DoubleQuote', '"')
+            return val
+        fname = nameAdapter.get(funct, funct)
+        if fname == 'rescale':
+            return
+        funct = getattr(self.context, fname)
+        vals = []
+        conglomerate = ''
+        quote = 0
+        theirexceptions = [ErrorNames[x.lower()] for x in exceptions]
+
+        for exception in Signals:
+            self.context.traps[exception] = 1 #Catch these bugs...
+        for exception in theirexceptions:
+            self.context.traps[exception] = 0
+        for i, val in enumerate(valstemp):
+            if val.count("'") % 2 == 1:
+                quote = 1 - quote
+            if quote:
+                conglomerate = conglomerate + ' ' + val
+                continue
+            else:
+                val = conglomerate + val
+                conglomerate = ''
+            v = FixQuotes(val)
+            if fname in ('to_sci_string', 'to_eng_string'):
+                if EXTENDEDERRORTEST:
+                    for error in theirexceptions:
+                        self.context.traps[error] = 1
+                        try:
+                            funct(self.context.create_decimal(v))
+                        except error:
+                            pass
+                        except Signals, e:
+                            self.fail("Raised %s in %s when %s disabled" % \
+                                      (e, s, error))
+                        else:
+                            self.fail("Did not raise %s in %s" % (error, s))
+                        self.context.traps[error] = 0
+                v = self.context.create_decimal(v)
+            else:
+                v = Decimal(v)
+            vals.append(v)
+
+        ans = FixQuotes(ans)
+
+        if EXTENDEDERRORTEST and fname not in ('to_sci_string', 'to_eng_string'):
+            for error in theirexceptions:
+                self.context.traps[error] = 1
+                try:
+                    funct(*vals)
+                except error:
+                    pass
+                except Signals, e:
+                    self.fail("Raised %s in %s when %s disabled" % \
+                              (e, s, error))
+                else:
+                    self.fail("Did not raise %s in %s" % (error, s))
+                self.context.traps[error] = 0
+        try:
+            result = str(funct(*vals))
+            if fname == 'same_quantum':
+                result = str(int(eval(result))) # 'True', 'False' -> '1', '0'
+        except Signals, error:
+            self.fail("Raised %s in %s" % (error, s))
+        except: #Catch any error long enough to state the test case.
+            print "ERROR:", s
+            raise
+
+        myexceptions = self.getexceptions()
+        self.context.clear_flags()
+
+        myexceptions.sort()
+        theirexceptions.sort()
+
+        self.assertEqual(result, ans,
+                         'Incorrect answer for ' + s + ' -- got ' + result)
+        self.assertEqual(myexceptions, theirexceptions,
+                         'Incorrect flags set in ' + s + ' -- got ' \
+                         + str(myexceptions))
+        return
+
+    def getexceptions(self):
+        return [e for e in Signals if self.context.flags[e]]
+
+    def change_precision(self, prec):
+        self.context.prec = prec
+    def change_rounding_method(self, rounding):
+        self.context.rounding = rounding
+    def change_min_exponent(self, exp):
+        self.context.Emin = exp
+    def change_max_exponent(self, exp):
+        self.context.Emax = exp
+    def change_clamp(self, clamp):
+        self.context._clamp = clamp
+
+# Dynamically build custom test definition for each file in the test
+# directory and add the definitions to the DecimalTest class.  This
+# procedure insures that new files do not get skipped.
+for filename in os.listdir(directory):
+    if '.decTest' not in filename:
+        continue
+    head, tail = filename.split('.')
+    tester = lambda self, f=filename: self.eval_file(directory + f)
+    setattr(DecimalTest, 'test_' + head, tester)
+    del filename, head, tail, tester
+
+
+
+# The following classes test the behaviour of Decimal according to PEP 327
+
+class DecimalExplicitConstructionTest(unittest.TestCase):
+    '''Unit tests for Explicit Construction cases of Decimal.'''
+
+    def test_explicit_empty(self):
+        self.assertEqual(Decimal(), Decimal("0"))
+
+    def test_explicit_from_None(self):
+        self.assertRaises(TypeError, Decimal, None)
+
+    def test_explicit_from_int(self):
+
+        #positive
+        d = Decimal(45)
+        self.assertEqual(str(d), '45')
+
+        #very large positive
+        d = Decimal(500000123)
+        self.assertEqual(str(d), '500000123')
+
+        #negative
+        d = Decimal(-45)
+        self.assertEqual(str(d), '-45')
+
+        #zero
+        d = Decimal(0)
+        self.assertEqual(str(d), '0')
+
+    def test_explicit_from_string(self):
+
+        #empty
+        self.assertEqual(str(Decimal('')), 'NaN')
+
+        #int
+        self.assertEqual(str(Decimal('45')), '45')
+
+        #float
+        self.assertEqual(str(Decimal('45.34')), '45.34')
+
+        #engineer notation
+        self.assertEqual(str(Decimal('45e2')), '4.5E+3')
+
+        #just not a number
+        self.assertEqual(str(Decimal('ugly')), 'NaN')
+
+    def test_explicit_from_tuples(self):
+
+        #zero
+        d = Decimal( (0, (0,), 0) )
+        self.assertEqual(str(d), '0')
+
+        #int
+        d = Decimal( (1, (4, 5), 0) )
+        self.assertEqual(str(d), '-45')
+
+        #float
+        d = Decimal( (0, (4, 5, 3, 4), -2) )
+        self.assertEqual(str(d), '45.34')
+
+        #weird
+        d = Decimal( (1, (4, 3, 4, 9, 1, 3, 5, 3, 4), -25) )
+        self.assertEqual(str(d), '-4.34913534E-17')
+
+        #wrong number of items
+        self.assertRaises(ValueError, Decimal, (1, (4, 3, 4, 9, 1)) )
+
+        #bad sign
+        self.assertRaises(ValueError, Decimal, (8, (4, 3, 4, 9, 1), 2) )
+
+        #bad exp
+        self.assertRaises(ValueError, Decimal, (1, (4, 3, 4, 9, 1), 'wrong!') )
+
+        #bad coefficients
+        self.assertRaises(ValueError, Decimal, (1, (4, 3, 4, None, 1), 2) )
+        self.assertRaises(ValueError, Decimal, (1, (4, -3, 4, 9, 1), 2) )
+
+    def test_explicit_from_Decimal(self):
+
+        #positive
+        d = Decimal(45)
+        e = Decimal(d)
+        self.assertEqual(str(e), '45')
+        self.assertNotEqual(id(d), id(e))
+
+        #very large positive
+        d = Decimal(500000123)
+        e = Decimal(d)
+        self.assertEqual(str(e), '500000123')
+        self.assertNotEqual(id(d), id(e))
+
+        #negative
+        d = Decimal(-45)
+        e = Decimal(d)
+        self.assertEqual(str(e), '-45')
+        self.assertNotEqual(id(d), id(e))
+
+        #zero
+        d = Decimal(0)
+        e = Decimal(d)
+        self.assertEqual(str(e), '0')
+        self.assertNotEqual(id(d), id(e))
+
+    def test_explicit_context_create_decimal(self):
+
+        nc = copy.copy(getcontext())
+        nc.prec = 3
+
+        # empty
+        d = Decimal()
+        self.assertEqual(str(d), '0')
+        d = nc.create_decimal()
+        self.assertEqual(str(d), '0')
+
+        # from None
+        self.assertRaises(TypeError, nc.create_decimal, None)
+
+        # from int
+        d = nc.create_decimal(456)
+        self.failUnless(isinstance(d, Decimal))
+        self.assertEqual(nc.create_decimal(45678),
+                         nc.create_decimal('457E+2'))
+
+        # from string
+        d = Decimal('456789')
+        self.assertEqual(str(d), '456789')
+        d = nc.create_decimal('456789')
+        self.assertEqual(str(d), '4.57E+5')
+
+        # from tuples
+        d = Decimal( (1, (4, 3, 4, 9, 1, 3, 5, 3, 4), -25) )
+        self.assertEqual(str(d), '-4.34913534E-17')
+        d = nc.create_decimal( (1, (4, 3, 4, 9, 1, 3, 5, 3, 4), -25) )
+        self.assertEqual(str(d), '-4.35E-17')
+
+        # from Decimal
+        prevdec = Decimal(500000123)
+        d = Decimal(prevdec)
+        self.assertEqual(str(d), '500000123')
+        d = nc.create_decimal(prevdec)
+        self.assertEqual(str(d), '5.00E+8')
+
+
+class DecimalImplicitConstructionTest(unittest.TestCase):
+    '''Unit tests for Implicit Construction cases of Decimal.'''
+
+    def test_implicit_from_None(self):
+        self.assertRaises(TypeError, eval, 'Decimal(5) + None', globals())
+
+    def test_implicit_from_int(self):
+        #normal
+        self.assertEqual(str(Decimal(5) + 45), '50')
+        #exceeding precision
+        self.assertEqual(Decimal(5) + 123456789000, Decimal(123456789000))
+
+    def test_implicit_from_string(self):
+        self.assertRaises(TypeError, eval, 'Decimal(5) + "3"', globals())
+
+    def test_implicit_from_float(self):
+        self.assertRaises(TypeError, eval, 'Decimal(5) + 2.2', globals())
+
+    def test_implicit_from_Decimal(self):
+        self.assertEqual(Decimal(5) + Decimal(45), Decimal(50))
+
+    def test_rop(self):
+        # Allow other classes to be trained to interact with Decimals
+        class E:
+            def __divmod__(self, other):
+                return 'divmod ' + str(other)
+            def __rdivmod__(self, other):
+                return str(other) + ' rdivmod'
+            def __lt__(self, other):
+                return 'lt ' + str(other)
+            def __gt__(self, other):
+                return 'gt ' + str(other)
+            def __le__(self, other):
+                return 'le ' + str(other)
+            def __ge__(self, other):
+                return 'ge ' + str(other)
+            def __eq__(self, other):
+                return 'eq ' + str(other)
+            def __ne__(self, other):
+                return 'ne ' + str(other)
+
+        self.assertEqual(divmod(E(), Decimal(10)), 'divmod 10')
+        self.assertEqual(divmod(Decimal(10), E()), '10 rdivmod')
+        self.assertEqual(eval('Decimal(10) < E()'), 'gt 10')
+        self.assertEqual(eval('Decimal(10) > E()'), 'lt 10')
+        self.assertEqual(eval('Decimal(10) <= E()'), 'ge 10')
+        self.assertEqual(eval('Decimal(10) >= E()'), 'le 10')
+        self.assertEqual(eval('Decimal(10) == E()'), 'eq 10')
+        self.assertEqual(eval('Decimal(10) != E()'), 'ne 10')
+
+        # insert operator methods and then exercise them
+        oplist = [
+            ('+', '__add__', '__radd__'),
+            ('-', '__sub__', '__rsub__'),
+            ('*', '__mul__', '__rmul__'),
+            ('%', '__mod__', '__rmod__'),
+            ('//', '__floordiv__', '__rfloordiv__'),
+            ('**', '__pow__', '__rpow__')
+        ]
+        if 1/2 == 0:
+            # testing with classic division, so add __div__
+            oplist.append(('/', '__div__', '__rdiv__'))
+        else:
+            # testing with -Qnew, so add __truediv__
+            oplist.append(('/', '__truediv__', '__rtruediv__'))
+
+        for sym, lop, rop in oplist:
+            setattr(E, lop, lambda self, other: 'str' + lop + str(other))
+            setattr(E, rop, lambda self, other: str(other) + rop + 'str')
+            self.assertEqual(eval('E()' + sym + 'Decimal(10)'),
+                             'str' + lop + '10')
+            self.assertEqual(eval('Decimal(10)' + sym + 'E()'),
+                             '10' + rop + 'str')
+
+class DecimalArithmeticOperatorsTest(unittest.TestCase):
+    '''Unit tests for all arithmetic operators, binary and unary.'''
+
+    def test_addition(self):
+
+        d1 = Decimal('-11.1')
+        d2 = Decimal('22.2')
+
+        #two Decimals
+        self.assertEqual(d1+d2, Decimal('11.1'))
+        self.assertEqual(d2+d1, Decimal('11.1'))
+
+        #with other type, left
+        c = d1 + 5
+        self.assertEqual(c, Decimal('-6.1'))
+        self.assertEqual(type(c), type(d1))
+
+        #with other type, right
+        c = 5 + d1
+        self.assertEqual(c, Decimal('-6.1'))
+        self.assertEqual(type(c), type(d1))
+
+        #inline with decimal
+        d1 += d2
+        self.assertEqual(d1, Decimal('11.1'))
+
+        #inline with other type
+        d1 += 5
+        self.assertEqual(d1, Decimal('16.1'))
+
+    def test_subtraction(self):
+
+        d1 = Decimal('-11.1')
+        d2 = Decimal('22.2')
+
+        #two Decimals
+        self.assertEqual(d1-d2, Decimal('-33.3'))
+        self.assertEqual(d2-d1, Decimal('33.3'))
+
+        #with other type, left
+        c = d1 - 5
+        self.assertEqual(c, Decimal('-16.1'))
+        self.assertEqual(type(c), type(d1))
+
+        #with other type, right
+        c = 5 - d1
+        self.assertEqual(c, Decimal('16.1'))
+        self.assertEqual(type(c), type(d1))
+
+        #inline with decimal
+        d1 -= d2
+        self.assertEqual(d1, Decimal('-33.3'))
+
+        #inline with other type
+        d1 -= 5
+        self.assertEqual(d1, Decimal('-38.3'))
+
+    def test_multiplication(self):
+
+        d1 = Decimal('-5')
+        d2 = Decimal('3')
+
+        #two Decimals
+        self.assertEqual(d1*d2, Decimal('-15'))
+        self.assertEqual(d2*d1, Decimal('-15'))
+
+        #with other type, left
+        c = d1 * 5
+        self.assertEqual(c, Decimal('-25'))
+        self.assertEqual(type(c), type(d1))
+
+        #with other type, right
+        c = 5 * d1
+        self.assertEqual(c, Decimal('-25'))
+        self.assertEqual(type(c), type(d1))
+
+        #inline with decimal
+        d1 *= d2
+        self.assertEqual(d1, Decimal('-15'))
+
+        #inline with other type
+        d1 *= 5
+        self.assertEqual(d1, Decimal('-75'))
+
+    def test_division(self):
+
+        d1 = Decimal('-5')
+        d2 = Decimal('2')
+
+        #two Decimals
+        self.assertEqual(d1/d2, Decimal('-2.5'))
+        self.assertEqual(d2/d1, Decimal('-0.4'))
+
+        #with other type, left
+        c = d1 / 4
+        self.assertEqual(c, Decimal('-1.25'))
+        self.assertEqual(type(c), type(d1))
+
+        #with other type, right
+        c = 4 / d1
+        self.assertEqual(c, Decimal('-0.8'))
+        self.assertEqual(type(c), type(d1))
+
+        #inline with decimal
+        d1 /= d2
+        self.assertEqual(d1, Decimal('-2.5'))
+
+        #inline with other type
+        d1 /= 4
+        self.assertEqual(d1, Decimal('-0.625'))
+
+    def test_floor_division(self):
+
+        d1 = Decimal('5')
+        d2 = Decimal('2')
+
+        #two Decimals
+        self.assertEqual(d1//d2, Decimal('2'))
+        self.assertEqual(d2//d1, Decimal('0'))
+
+        #with other type, left
+        c = d1 // 4
+        self.assertEqual(c, Decimal('1'))
+        self.assertEqual(type(c), type(d1))
+
+        #with other type, right
+        c = 7 // d1
+        self.assertEqual(c, Decimal('1'))
+        self.assertEqual(type(c), type(d1))
+
+        #inline with decimal
+        d1 //= d2
+        self.assertEqual(d1, Decimal('2'))
+
+        #inline with other type
+        d1 //= 2
+        self.assertEqual(d1, Decimal('1'))
+
+    def test_powering(self):
+
+        d1 = Decimal('5')
+        d2 = Decimal('2')
+
+        #two Decimals
+        self.assertEqual(d1**d2, Decimal('25'))
+        self.assertEqual(d2**d1, Decimal('32'))
+
+        #with other type, left
+        c = d1 ** 4
+        self.assertEqual(c, Decimal('625'))
+        self.assertEqual(type(c), type(d1))
+
+        #with other type, right
+        c = 7 ** d1
+        self.assertEqual(c, Decimal('16807'))
+        self.assertEqual(type(c), type(d1))
+
+        #inline with decimal
+        d1 **= d2
+        self.assertEqual(d1, Decimal('25'))
+
+        #inline with other type
+        d1 **= 4
+        self.assertEqual(d1, Decimal('390625'))
+
+    def test_module(self):
+
+        d1 = Decimal('5')
+        d2 = Decimal('2')
+
+        #two Decimals
+        self.assertEqual(d1%d2, Decimal('1'))
+        self.assertEqual(d2%d1, Decimal('2'))
+
+        #with other type, left
+        c = d1 % 4
+        self.assertEqual(c, Decimal('1'))
+        self.assertEqual(type(c), type(d1))
+
+        #with other type, right
+        c = 7 % d1
+        self.assertEqual(c, Decimal('2'))
+        self.assertEqual(type(c), type(d1))
+
+        #inline with decimal
+        d1 %= d2
+        self.assertEqual(d1, Decimal('1'))
+
+        #inline with other type
+        d1 %= 4
+        self.assertEqual(d1, Decimal('1'))
+
+    def test_floor_div_module(self):
+
+        d1 = Decimal('5')
+        d2 = Decimal('2')
+
+        #two Decimals
+        (p, q) = divmod(d1, d2)
+        self.assertEqual(p, Decimal('2'))
+        self.assertEqual(q, Decimal('1'))
+        self.assertEqual(type(p), type(d1))
+        self.assertEqual(type(q), type(d1))
+
+        #with other type, left
+        (p, q) = divmod(d1, 4)
+        self.assertEqual(p, Decimal('1'))
+        self.assertEqual(q, Decimal('1'))
+        self.assertEqual(type(p), type(d1))
+        self.assertEqual(type(q), type(d1))
+
+        #with other type, right
+        (p, q) = divmod(7, d1)
+        self.assertEqual(p, Decimal('1'))
+        self.assertEqual(q, Decimal('2'))
+        self.assertEqual(type(p), type(d1))
+        self.assertEqual(type(q), type(d1))
+
+    def test_unary_operators(self):
+        self.assertEqual(+Decimal(45), Decimal(+45))           #  +
+        self.assertEqual(-Decimal(45), Decimal(-45))           #  -
+        self.assertEqual(abs(Decimal(45)), abs(Decimal(-45)))  # abs
+
+
+# The following are two functions used to test threading in the next class
+
+def thfunc1(cls):
+    d1 = Decimal(1)
+    d3 = Decimal(3)
+    cls.assertEqual(d1/d3, Decimal('0.333333333'))
+    cls.synchro.wait()
+    cls.assertEqual(d1/d3, Decimal('0.333333333'))
+    cls.finish1.set()
+    return
+
+def thfunc2(cls):
+    d1 = Decimal(1)
+    d3 = Decimal(3)
+    cls.assertEqual(d1/d3, Decimal('0.333333333'))
+    thiscontext = getcontext()
+    thiscontext.prec = 18
+    cls.assertEqual(d1/d3, Decimal('0.333333333333333333'))
+    cls.synchro.set()
+    cls.finish2.set()
+    return
+
+
+class DecimalUseOfContextTest(unittest.TestCase):
+    '''Unit tests for Use of Context cases in Decimal.'''
+
+    try:
+        import threading
+    except ImportError:
+        threading = None
+
+    # Take care executing this test from IDLE, there's an issue in threading
+    # that hangs IDLE and I couldn't find it
+
+    def test_threading(self):
+        #Test the "threading isolation" of a Context.
+
+        self.synchro = threading.Event()
+        self.finish1 = threading.Event()
+        self.finish2 = threading.Event()
+
+        th1 = threading.Thread(target=thfunc1, args=(self,))
+        th2 = threading.Thread(target=thfunc2, args=(self,))
+
+        th1.start()
+        th2.start()
+
+        self.finish1.wait()
+        self.finish1.wait()
+        return
+
+    if threading is None:
+        del test_threading
+
+
+class DecimalUsabilityTest(unittest.TestCase):
+    '''Unit tests for Usability cases of Decimal.'''
+
+    def test_comparison_operators(self):
+
+        da = Decimal('23.42')
+        db = Decimal('23.42')
+        dc = Decimal('45')
+
+        #two Decimals
+        self.failUnless(dc > da)
+        self.failUnless(dc >= da)
+        self.failUnless(da < dc)
+        self.failUnless(da <= dc)
+        self.failUnless(da == db)
+        self.failUnless(da != dc)
+        self.failUnless(da <= db)
+        self.failUnless(da >= db)
+        self.assertEqual(cmp(dc,da), 1)
+        self.assertEqual(cmp(da,dc), -1)
+        self.assertEqual(cmp(da,db), 0)
+
+        #a Decimal and an int
+        self.failUnless(dc > 23)
+        self.failUnless(23 < dc)
+        self.failUnless(dc == 45)
+        self.assertEqual(cmp(dc,23), 1)
+        self.assertEqual(cmp(23,dc), -1)
+        self.assertEqual(cmp(dc,45), 0)
+
+        #a Decimal and uncomparable
+        self.assertNotEqual(da, 'ugly')
+        self.assertNotEqual(da, 32.7)
+        self.assertNotEqual(da, object())
+        self.assertNotEqual(da, object)
+
+        # sortable
+        a = map(Decimal, xrange(100))
+        b =  a[:]
+        random.shuffle(a)
+        a.sort()
+        self.assertEqual(a, b)
+
+    def test_copy_and_deepcopy_methods(self):
+        d = Decimal('43.24')
+        c = copy.copy(d)
+        self.assertEqual(id(c), id(d))
+        dc = copy.deepcopy(d)
+        self.assertEqual(id(dc), id(d))
+
+    def test_hash_method(self):
+        #just that it's hashable
+        hash(Decimal(23))
+        #the same hash that to an int
+        self.assertEqual(hash(Decimal(23)), hash(23))
+        self.assertRaises(TypeError, hash, Decimal('NaN'))
+        self.assert_(hash(Decimal('Inf')))
+        self.assert_(hash(Decimal('-Inf')))
+
+    def test_min_and_max_methods(self):
+
+        d1 = Decimal('15.32')
+        d2 = Decimal('28.5')
+        l1 = 15
+        l2 = 28
+
+        #between Decimals
+        self.failUnless(min(d1,d2) is d1)
+        self.failUnless(min(d2,d1) is d1)
+        self.failUnless(max(d1,d2) is d2)
+        self.failUnless(max(d2,d1) is d2)
+
+        #between Decimal and long
+        self.failUnless(min(d1,l2) is d1)
+        self.failUnless(min(l2,d1) is d1)
+        self.failUnless(max(l1,d2) is d2)
+        self.failUnless(max(d2,l1) is d2)
+
+    def test_as_nonzero(self):
+        #as false
+        self.failIf(Decimal(0))
+        #as true
+        self.failUnless(Decimal('0.372'))
+
+    def test_tostring_methods(self):
+        #Test str and repr methods.
+
+        d = Decimal('15.32')
+        self.assertEqual(str(d), '15.32')               # str
+        self.assertEqual(repr(d), 'Decimal("15.32")')   # repr
+
+    def test_tonum_methods(self):
+        #Test float, int and long methods.
+
+        d1 = Decimal('66')
+        d2 = Decimal('15.32')
+
+        #int
+        self.assertEqual(int(d1), 66)
+        self.assertEqual(int(d2), 15)
+
+        #long
+        self.assertEqual(long(d1), 66)
+        self.assertEqual(long(d2), 15)
+
+        #float
+        self.assertEqual(float(d1), 66)
+        self.assertEqual(float(d2), 15.32)
+
+    def test_eval_round_trip(self):
+
+        #with zero
+        d = Decimal( (0, (0,), 0) )
+        self.assertEqual(d, eval(repr(d)))
+
+        #int
+        d = Decimal( (1, (4, 5), 0) )
+        self.assertEqual(d, eval(repr(d)))
+
+        #float
+        d = Decimal( (0, (4, 5, 3, 4), -2) )
+        self.assertEqual(d, eval(repr(d)))
+
+        #weird
+        d = Decimal( (1, (4, 3, 4, 9, 1, 3, 5, 3, 4), -25) )
+        self.assertEqual(d, eval(repr(d)))
+
+    def test_as_tuple(self):
+
+        #with zero
+        d = Decimal(0)
+        self.assertEqual(d.as_tuple(), (0, (0,), 0) )
+
+        #int
+        d = Decimal(-45)
+        self.assertEqual(d.as_tuple(), (1, (4, 5), 0) )
+
+        #complicated string
+        d = Decimal("-4.34913534E-17")
+        self.assertEqual(d.as_tuple(), (1, (4, 3, 4, 9, 1, 3, 5, 3, 4), -25) )
+
+        #inf
+        d = Decimal("Infinity")
+        self.assertEqual(d.as_tuple(), (0, (0,), 'F') )
+
+    def test_immutability_operations(self):
+        # Do operations and check that it didn't change change internal objects.
+
+        d1 = Decimal('-25e55')
+        b1 = Decimal('-25e55')
+        d2 = Decimal('33e-33')
+        b2 = Decimal('33e-33')
+
+        def checkSameDec(operation, useOther=False):
+            if useOther:
+                eval("d1." + operation + "(d2)")
+                self.assertEqual(d1._sign, b1._sign)
+                self.assertEqual(d1._int, b1._int)
+                self.assertEqual(d1._exp, b1._exp)
+                self.assertEqual(d2._sign, b2._sign)
+                self.assertEqual(d2._int, b2._int)
+                self.assertEqual(d2._exp, b2._exp)
+            else:
+                eval("d1." + operation + "()")
+                self.assertEqual(d1._sign, b1._sign)
+                self.assertEqual(d1._int, b1._int)
+                self.assertEqual(d1._exp, b1._exp)
+            return
+
+        Decimal(d1)
+        self.assertEqual(d1._sign, b1._sign)
+        self.assertEqual(d1._int, b1._int)
+        self.assertEqual(d1._exp, b1._exp)
+
+        checkSameDec("__abs__")
+        checkSameDec("__add__", True)
+        checkSameDec("__div__", True)
+        checkSameDec("__divmod__", True)
+        checkSameDec("__cmp__", True)
+        checkSameDec("__float__")
+        checkSameDec("__floordiv__", True)
+        checkSameDec("__hash__")
+        checkSameDec("__int__")
+        checkSameDec("__long__")
+        checkSameDec("__mod__", True)
+        checkSameDec("__mul__", True)
+        checkSameDec("__neg__")
+        checkSameDec("__nonzero__")
+        checkSameDec("__pos__")
+        checkSameDec("__pow__", True)
+        checkSameDec("__radd__", True)
+        checkSameDec("__rdiv__", True)
+        checkSameDec("__rdivmod__", True)
+        checkSameDec("__repr__")
+        checkSameDec("__rfloordiv__", True)
+        checkSameDec("__rmod__", True)
+        checkSameDec("__rmul__", True)
+        checkSameDec("__rpow__", True)
+        checkSameDec("__rsub__", True)
+        checkSameDec("__str__")
+        checkSameDec("__sub__", True)
+        checkSameDec("__truediv__", True)
+        checkSameDec("adjusted")
+        checkSameDec("as_tuple")
+        checkSameDec("compare", True)
+        checkSameDec("max", True)
+        checkSameDec("min", True)
+        checkSameDec("normalize")
+        checkSameDec("quantize", True)
+        checkSameDec("remainder_near", True)
+        checkSameDec("same_quantum", True)
+        checkSameDec("sqrt")
+        checkSameDec("to_eng_string")
+        checkSameDec("to_integral")
+
+class DecimalPythonAPItests(unittest.TestCase):
+
+    def test_pickle(self):
+        d = Decimal('-3.141590000')
+        p = pickle.dumps(d)
+        e = pickle.loads(p)
+        self.assertEqual(d, e)
+
+    def test_int(self):
+        for x in range(-250, 250):
+            s = '%0.2f' % (x / 100.0)
+            # should work the same as for floats
+            self.assertEqual(int(Decimal(s)), int(float(s)))
+            # should work the same as to_integral in the ROUND_DOWN mode
+            d = Decimal(s)
+            r = d.to_integral(ROUND_DOWN)
+            self.assertEqual(Decimal(int(d)), r)
+
+class ContextAPItests(unittest.TestCase):
+
+    def test_pickle(self):
+        c = Context()
+        e = pickle.loads(pickle.dumps(c))
+        for k in vars(c):
+            v1 = vars(c)[k]
+            v2 = vars(e)[k]
+            self.assertEqual(v1, v2)
+
+    def test_equality_with_other_types(self):
+        self.assert_(Decimal(10) in ['a', 1.0, Decimal(10), (1,2), {}])
+        self.assert_(Decimal(10) not in ['a', 1.0, (1,2), {}])
+
+    def test_copy(self):
+        # All copies should be deep
+        c = Context()
+        d = c.copy()
+        self.assertNotEqual(id(c), id(d))
+        self.assertNotEqual(id(c.flags), id(d.flags))
+        self.assertNotEqual(id(c.traps), id(d.traps))
+
+class WithStatementTest(unittest.TestCase):
+    # Can't do these as docstrings until Python 2.6
+    # as doctest can't handle __future__ statements
+
+    def test_localcontext(self):
+        # Use a copy of the current context in the block
+        orig_ctx = getcontext()
+        with localcontext() as enter_ctx:
+            set_ctx = getcontext()
+        final_ctx = getcontext()
+        self.assert_(orig_ctx is final_ctx, 'did not restore context correctly')
+        self.assert_(orig_ctx is not set_ctx, 'did not copy the context')
+        self.assert_(set_ctx is enter_ctx, '__enter__ returned wrong context')
+
+    def test_localcontextarg(self):
+        # Use a copy of the supplied context in the block
+        orig_ctx = getcontext()
+        new_ctx = Context(prec=42)
+        with localcontext(new_ctx) as enter_ctx:
+            set_ctx = getcontext()
+        final_ctx = getcontext()
+        self.assert_(orig_ctx is final_ctx, 'did not restore context correctly')
+        self.assert_(set_ctx.prec == new_ctx.prec, 'did not set correct context')
+        self.assert_(new_ctx is not set_ctx, 'did not copy the context')
+        self.assert_(set_ctx is enter_ctx, '__enter__ returned wrong context')
+
+def test_main(arith=False, verbose=None):
+    """ Execute the tests.
+
+    Runs all arithmetic tests if arith is True or if the "decimal" resource
+    is enabled in regrtest.py
+    """
+
+    init()
+    global TEST_ALL
+    TEST_ALL = arith or is_resource_enabled('decimal')
+
+    test_classes = [
+        DecimalExplicitConstructionTest,
+        DecimalImplicitConstructionTest,
+        DecimalArithmeticOperatorsTest,
+        DecimalUseOfContextTest,
+        DecimalUsabilityTest,
+        DecimalPythonAPItests,
+        ContextAPItests,
+        DecimalTest,
+        WithStatementTest,
+    ]
+
+    try:
+        run_unittest(*test_classes)
+        import decimal as DecimalModule
+        run_doctest(DecimalModule, verbose)
+    finally:
+        setcontext(ORIGINAL_CONTEXT)
+
+if __name__ == '__main__':
+    # Calling with no arguments runs all tests.
+    # Calling with "Skip" will skip over 90% of the arithmetic tests.
+    if len(sys.argv) == 1:
+        test_main(arith=True, verbose=True)
+    elif len(sys.argv) == 2:
+        arith = sys.argv[1].lower() != 'skip'
+        test_main(arith=arith, verbose=True)
+    else:
+        raise ValueError("test called with wrong arguments, use test_Decimal [Skip]")

Added: vendor/Python/current/Lib/test/test_decorators.py
===================================================================
--- vendor/Python/current/Lib/test/test_decorators.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_decorators.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,273 @@
+import unittest
+from test import test_support
+
+def funcattrs(**kwds):
+    def decorate(func):
+        func.__dict__.update(kwds)
+        return func
+    return decorate
+
+class MiscDecorators (object):
+    @staticmethod
+    def author(name):
+        def decorate(func):
+            func.__dict__['author'] = name
+            return func
+        return decorate
+
+# -----------------------------------------------
+
+class DbcheckError (Exception):
+    def __init__(self, exprstr, func, args, kwds):
+        # A real version of this would set attributes here
+        Exception.__init__(self, "dbcheck %r failed (func=%s args=%s kwds=%s)" %
+                           (exprstr, func, args, kwds))
+
+
+def dbcheck(exprstr, globals=None, locals=None):
+    "Decorator to implement debugging assertions"
+    def decorate(func):
+        expr = compile(exprstr, "dbcheck-%s" % func.func_name, "eval")
+        def check(*args, **kwds):
+            if not eval(expr, globals, locals):
+                raise DbcheckError(exprstr, func, args, kwds)
+            return func(*args, **kwds)
+        return check
+    return decorate
+
+# -----------------------------------------------
+
+def countcalls(counts):
+    "Decorator to count calls to a function"
+    def decorate(func):
+        func_name = func.func_name
+        counts[func_name] = 0
+        def call(*args, **kwds):
+            counts[func_name] += 1
+            return func(*args, **kwds)
+        call.func_name = func_name
+        return call
+    return decorate
+
+# -----------------------------------------------
+
+def memoize(func):
+    saved = {}
+    def call(*args):
+        try:
+            return saved[args]
+        except KeyError:
+            res = func(*args)
+            saved[args] = res
+            return res
+        except TypeError:
+            # Unhashable argument
+            return func(*args)
+    call.func_name = func.func_name
+    return call
+
+# -----------------------------------------------
+
+class TestDecorators(unittest.TestCase):
+
+    def test_single(self):
+        class C(object):
+            @staticmethod
+            def foo(): return 42
+        self.assertEqual(C.foo(), 42)
+        self.assertEqual(C().foo(), 42)
+
+    def test_staticmethod_function(self):
+        @staticmethod
+        def notamethod(x):
+            return x
+        self.assertRaises(TypeError, notamethod, 1)
+
+    def test_dotted(self):
+        decorators = MiscDecorators()
+        @decorators.author('Cleese')
+        def foo(): return 42
+        self.assertEqual(foo(), 42)
+        self.assertEqual(foo.author, 'Cleese')
+
+    def test_argforms(self):
+        # A few tests of argument passing, as we use restricted form
+        # of expressions for decorators.
+
+        def noteargs(*args, **kwds):
+            def decorate(func):
+                setattr(func, 'dbval', (args, kwds))
+                return func
+            return decorate
+
+        args = ( 'Now', 'is', 'the', 'time' )
+        kwds = dict(one=1, two=2)
+        @noteargs(*args, **kwds)
+        def f1(): return 42
+        self.assertEqual(f1(), 42)
+        self.assertEqual(f1.dbval, (args, kwds))
+
+        @noteargs('terry', 'gilliam', eric='idle', john='cleese')
+        def f2(): return 84
+        self.assertEqual(f2(), 84)
+        self.assertEqual(f2.dbval, (('terry', 'gilliam'),
+                                     dict(eric='idle', john='cleese')))
+
+        @noteargs(1, 2,)
+        def f3(): pass
+        self.assertEqual(f3.dbval, ((1, 2), {}))
+
+    def test_dbcheck(self):
+        @dbcheck('args[1] is not None')
+        def f(a, b):
+            return a + b
+        self.assertEqual(f(1, 2), 3)
+        self.assertRaises(DbcheckError, f, 1, None)
+
+    def test_memoize(self):
+        counts = {}
+
+        @memoize
+        @countcalls(counts)
+        def double(x):
+            return x * 2
+        self.assertEqual(double.func_name, 'double')
+
+        self.assertEqual(counts, dict(double=0))
+
+        # Only the first call with a given argument bumps the call count:
+        #
+        self.assertEqual(double(2), 4)
+        self.assertEqual(counts['double'], 1)
+        self.assertEqual(double(2), 4)
+        self.assertEqual(counts['double'], 1)
+        self.assertEqual(double(3), 6)
+        self.assertEqual(counts['double'], 2)
+
+        # Unhashable arguments do not get memoized:
+        #
+        self.assertEqual(double([10]), [10, 10])
+        self.assertEqual(counts['double'], 3)
+        self.assertEqual(double([10]), [10, 10])
+        self.assertEqual(counts['double'], 4)
+
+    def test_errors(self):
+        # Test syntax restrictions - these are all compile-time errors:
+        #
+        for expr in [ "1+2", "x[3]", "(1, 2)" ]:
+            # Sanity check: is expr is a valid expression by itself?
+            compile(expr, "testexpr", "exec")
+
+            codestr = "@%s\ndef f(): pass" % expr
+            self.assertRaises(SyntaxError, compile, codestr, "test", "exec")
+
+        # You can't put multiple decorators on a single line:
+        #
+        self.assertRaises(SyntaxError, compile,
+                          "@f1 @f2\ndef f(): pass", "test", "exec")
+
+        # Test runtime errors
+
+        def unimp(func):
+            raise NotImplementedError
+        context = dict(nullval=None, unimp=unimp)
+
+        for expr, exc in [ ("undef", NameError),
+                           ("nullval", TypeError),
+                           ("nullval.attr", AttributeError),
+                           ("unimp", NotImplementedError)]:
+            codestr = "@%s\ndef f(): pass\nassert f() is None" % expr
+            code = compile(codestr, "test", "exec")
+            self.assertRaises(exc, eval, code, context)
+
+    def test_double(self):
+        class C(object):
+            @funcattrs(abc=1, xyz="haha")
+            @funcattrs(booh=42)
+            def foo(self): return 42
+        self.assertEqual(C().foo(), 42)
+        self.assertEqual(C.foo.abc, 1)
+        self.assertEqual(C.foo.xyz, "haha")
+        self.assertEqual(C.foo.booh, 42)
+
+    def test_order(self):
+        # Test that decorators are applied in the proper order to the function
+        # they are decorating.
+        def callnum(num):
+            """Decorator factory that returns a decorator that replaces the
+            passed-in function with one that returns the value of 'num'"""
+            def deco(func):
+                return lambda: num
+            return deco
+        @callnum(2)
+        @callnum(1)
+        def foo(): return 42
+        self.assertEqual(foo(), 2,
+                            "Application order of decorators is incorrect")
+
+    def test_eval_order(self):
+        # Evaluating a decorated function involves four steps for each
+        # decorator-maker (the function that returns a decorator):
+        #
+        #    1: Evaluate the decorator-maker name
+        #    2: Evaluate the decorator-maker arguments (if any)
+        #    3: Call the decorator-maker to make a decorator
+        #    4: Call the decorator
+        #
+        # When there are multiple decorators, these steps should be
+        # performed in the above order for each decorator, but we should
+        # iterate through the decorators in the reverse of the order they
+        # appear in the source.
+
+        actions = []
+
+        def make_decorator(tag):
+            actions.append('makedec' + tag)
+            def decorate(func):
+                actions.append('calldec' + tag)
+                return func
+            return decorate
+
+        class NameLookupTracer (object):
+            def __init__(self, index):
+                self.index = index
+
+            def __getattr__(self, fname):
+                if fname == 'make_decorator':
+                    opname, res = ('evalname', make_decorator)
+                elif fname == 'arg':
+                    opname, res = ('evalargs', str(self.index))
+                else:
+                    assert False, "Unknown attrname %s" % fname
+                actions.append('%s%d' % (opname, self.index))
+                return res
+
+        c1, c2, c3 = map(NameLookupTracer, [ 1, 2, 3 ])
+
+        expected_actions = [ 'evalname1', 'evalargs1', 'makedec1',
+                             'evalname2', 'evalargs2', 'makedec2',
+                             'evalname3', 'evalargs3', 'makedec3',
+                             'calldec3', 'calldec2', 'calldec1' ]
+
+        actions = []
+        @c1.make_decorator(c1.arg)
+        @c2.make_decorator(c2.arg)
+        @c3.make_decorator(c3.arg)
+        def foo(): return 42
+        self.assertEqual(foo(), 42)
+
+        self.assertEqual(actions, expected_actions)
+
+        # Test the equivalence claim in chapter 7 of the reference manual.
+        #
+        actions = []
+        def bar(): return 42
+        bar = c1.make_decorator(c1.arg)(c2.make_decorator(c2.arg)(c3.make_decorator(c3.arg)(bar)))
+        self.assertEqual(bar(), 42)
+        self.assertEqual(actions, expected_actions)
+
+def test_main():
+    test_support.run_unittest(TestDecorators)
+
+if __name__=="__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_defaultdict.py
===================================================================
--- vendor/Python/current/Lib/test/test_defaultdict.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_defaultdict.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,149 @@
+"""Unit tests for collections.defaultdict."""
+
+import os
+import copy
+import tempfile
+import unittest
+from test import test_support
+
+from collections import defaultdict
+
+def foobar():
+    return list
+
+class TestDefaultDict(unittest.TestCase):
+
+    def test_basic(self):
+        d1 = defaultdict()
+        self.assertEqual(d1.default_factory, None)
+        d1.default_factory = list
+        d1[12].append(42)
+        self.assertEqual(d1, {12: [42]})
+        d1[12].append(24)
+        self.assertEqual(d1, {12: [42, 24]})
+        d1[13]
+        d1[14]
+        self.assertEqual(d1, {12: [42, 24], 13: [], 14: []})
+        self.assert_(d1[12] is not d1[13] is not d1[14])
+        d2 = defaultdict(list, foo=1, bar=2)
+        self.assertEqual(d2.default_factory, list)
+        self.assertEqual(d2, {"foo": 1, "bar": 2})
+        self.assertEqual(d2["foo"], 1)
+        self.assertEqual(d2["bar"], 2)
+        self.assertEqual(d2[42], [])
+        self.assert_("foo" in d2)
+        self.assert_("foo" in d2.keys())
+        self.assert_("bar" in d2)
+        self.assert_("bar" in d2.keys())
+        self.assert_(42 in d2)
+        self.assert_(42 in d2.keys())
+        self.assert_(12 not in d2)
+        self.assert_(12 not in d2.keys())
+        d2.default_factory = None
+        self.assertEqual(d2.default_factory, None)
+        try:
+            d2[15]
+        except KeyError, err:
+            self.assertEqual(err.args, (15,))
+        else:
+            self.fail("d2[15] didn't raise KeyError")
+        self.assertRaises(TypeError, defaultdict, 1)
+
+    def test_missing(self):
+        d1 = defaultdict()
+        self.assertRaises(KeyError, d1.__missing__, 42)
+        d1.default_factory = list
+        self.assertEqual(d1.__missing__(42), [])
+
+    def test_repr(self):
+        d1 = defaultdict()
+        self.assertEqual(d1.default_factory, None)
+        self.assertEqual(repr(d1), "defaultdict(None, {})")
+        d1[11] = 41
+        self.assertEqual(repr(d1), "defaultdict(None, {11: 41})")
+        d2 = defaultdict(int)
+        self.assertEqual(d2.default_factory, int)
+        d2[12] = 42
+        self.assertEqual(repr(d2), "defaultdict(<type 'int'>, {12: 42})")
+        def foo(): return 43
+        d3 = defaultdict(foo)
+        self.assert_(d3.default_factory is foo)
+        d3[13]
+        self.assertEqual(repr(d3), "defaultdict(%s, {13: 43})" % repr(foo))
+
+    def test_print(self):
+        d1 = defaultdict()
+        def foo(): return 42
+        d2 = defaultdict(foo, {1: 2})
+        # NOTE: We can't use tempfile.[Named]TemporaryFile since this
+        # code must exercise the tp_print C code, which only gets
+        # invoked for *real* files.
+        tfn = tempfile.mktemp()
+        try:
+            f = open(tfn, "w+")
+            try:
+                print >>f, d1
+                print >>f, d2
+                f.seek(0)
+                self.assertEqual(f.readline(), repr(d1) + "\n")
+                self.assertEqual(f.readline(), repr(d2) + "\n")
+            finally:
+                f.close()
+        finally:
+            os.remove(tfn)
+
+    def test_copy(self):
+        d1 = defaultdict()
+        d2 = d1.copy()
+        self.assertEqual(type(d2), defaultdict)
+        self.assertEqual(d2.default_factory, None)
+        self.assertEqual(d2, {})
+        d1.default_factory = list
+        d3 = d1.copy()
+        self.assertEqual(type(d3), defaultdict)
+        self.assertEqual(d3.default_factory, list)
+        self.assertEqual(d3, {})
+        d1[42]
+        d4 = d1.copy()
+        self.assertEqual(type(d4), defaultdict)
+        self.assertEqual(d4.default_factory, list)
+        self.assertEqual(d4, {42: []})
+        d4[12]
+        self.assertEqual(d4, {42: [], 12: []})
+
+    def test_shallow_copy(self):
+        d1 = defaultdict(foobar, {1: 1})
+        d2 = copy.copy(d1)
+        self.assertEqual(d2.default_factory, foobar)
+        self.assertEqual(d2, d1)
+        d1.default_factory = list
+        d2 = copy.copy(d1)
+        self.assertEqual(d2.default_factory, list)
+        self.assertEqual(d2, d1)
+
+    def test_deep_copy(self):
+        d1 = defaultdict(foobar, {1: [1]})
+        d2 = copy.deepcopy(d1)
+        self.assertEqual(d2.default_factory, foobar)
+        self.assertEqual(d2, d1)
+        self.assert_(d1[1] is not d2[1])
+        d1.default_factory = list
+        d2 = copy.deepcopy(d1)
+        self.assertEqual(d2.default_factory, list)
+        self.assertEqual(d2, d1)
+
+    def test_keyerror_without_factory(self):
+        d1 = defaultdict()
+        try:
+            d1[(1,)]
+        except KeyError, err:
+            self.assertEqual(err.message, (1,))
+        else:
+            self.fail("expected KeyError")
+
+
+def test_main():
+    test_support.run_unittest(TestDefaultDict)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_deque.py
===================================================================
--- vendor/Python/current/Lib/test/test_deque.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_deque.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,632 @@
+from collections import deque
+import unittest
+from test import test_support, seq_tests
+from weakref import proxy
+import copy
+import cPickle as pickle
+from cStringIO import StringIO
+import random
+import os
+
+BIG = 100000
+
+def fail():
+    raise SyntaxError
+    yield 1
+
+class BadCmp:
+    def __eq__(self, other):
+        raise RuntimeError
+
+class MutateCmp:
+    def __init__(self, deque, result):
+        self.deque = deque
+        self.result = result
+    def __eq__(self, other):
+        self.deque.clear()
+        return self.result
+
+class TestBasic(unittest.TestCase):
+
+    def test_basics(self):
+        d = deque(xrange(100))
+        d.__init__(xrange(100, 200))
+        for i in xrange(200, 400):
+            d.append(i)
+        for i in reversed(xrange(-200, 0)):
+            d.appendleft(i)
+        self.assertEqual(list(d), range(-200, 400))
+        self.assertEqual(len(d), 600)
+
+        left = [d.popleft() for i in xrange(250)]
+        self.assertEqual(left, range(-200, 50))
+        self.assertEqual(list(d), range(50, 400))
+
+        right = [d.pop() for i in xrange(250)]
+        right.reverse()
+        self.assertEqual(right, range(150, 400))
+        self.assertEqual(list(d), range(50, 150))
+
+    def test_comparisons(self):
+        d = deque('xabc'); d.popleft()
+        for e in [d, deque('abc'), deque('ab'), deque(), list(d)]:
+            self.assertEqual(d==e, type(d)==type(e) and list(d)==list(e))
+            self.assertEqual(d!=e, not(type(d)==type(e) and list(d)==list(e)))
+
+        args = map(deque, ('', 'a', 'b', 'ab', 'ba', 'abc', 'xba', 'xabc', 'cba'))
+        for x in args:
+            for y in args:
+                self.assertEqual(x == y, list(x) == list(y), (x,y))
+                self.assertEqual(x != y, list(x) != list(y), (x,y))
+                self.assertEqual(x <  y, list(x) <  list(y), (x,y))
+                self.assertEqual(x <= y, list(x) <= list(y), (x,y))
+                self.assertEqual(x >  y, list(x) >  list(y), (x,y))
+                self.assertEqual(x >= y, list(x) >= list(y), (x,y))
+                self.assertEqual(cmp(x,y), cmp(list(x),list(y)), (x,y))
+
+    def test_extend(self):
+        d = deque('a')
+        self.assertRaises(TypeError, d.extend, 1)
+        d.extend('bcd')
+        self.assertEqual(list(d), list('abcd'))
+
+    def test_extendleft(self):
+        d = deque('a')
+        self.assertRaises(TypeError, d.extendleft, 1)
+        d.extendleft('bcd')
+        self.assertEqual(list(d), list(reversed('abcd')))
+        d = deque()
+        d.extendleft(range(1000))
+        self.assertEqual(list(d), list(reversed(range(1000))))
+        self.assertRaises(SyntaxError, d.extendleft, fail())
+
+    def test_getitem(self):
+        n = 200
+        d = deque(xrange(n))
+        l = range(n)
+        for i in xrange(n):
+            d.popleft()
+            l.pop(0)
+            if random.random() < 0.5:
+                d.append(i)
+                l.append(i)
+            for j in xrange(1-len(l), len(l)):
+                assert d[j] == l[j]
+
+        d = deque('superman')
+        self.assertEqual(d[0], 's')
+        self.assertEqual(d[-1], 'n')
+        d = deque()
+        self.assertRaises(IndexError, d.__getitem__, 0)
+        self.assertRaises(IndexError, d.__getitem__, -1)
+
+    def test_setitem(self):
+        n = 200
+        d = deque(xrange(n))
+        for i in xrange(n):
+            d[i] = 10 * i
+        self.assertEqual(list(d), [10*i for i in xrange(n)])
+        l = list(d)
+        for i in xrange(1-n, 0, -1):
+            d[i] = 7*i
+            l[i] = 7*i
+        self.assertEqual(list(d), l)
+
+    def test_delitem(self):
+        n = 500         # O(n**2) test, don't make this too big
+        d = deque(xrange(n))
+        self.assertRaises(IndexError, d.__delitem__, -n-1)
+        self.assertRaises(IndexError, d.__delitem__, n)
+        for i in xrange(n):
+            self.assertEqual(len(d), n-i)
+            j = random.randrange(-len(d), len(d))
+            val = d[j]
+            self.assert_(val in d)
+            del d[j]
+            self.assert_(val not in d)
+        self.assertEqual(len(d), 0)
+
+    def test_rotate(self):
+        s = tuple('abcde')
+        n = len(s)
+
+        d = deque(s)
+        d.rotate(1)             # verify rot(1)
+        self.assertEqual(''.join(d), 'eabcd')
+
+        d = deque(s)
+        d.rotate(-1)            # verify rot(-1)
+        self.assertEqual(''.join(d), 'bcdea')
+        d.rotate()              # check default to 1
+        self.assertEqual(tuple(d), s)
+
+        for i in xrange(n*3):
+            d = deque(s)
+            e = deque(d)
+            d.rotate(i)         # check vs. rot(1) n times
+            for j in xrange(i):
+                e.rotate(1)
+            self.assertEqual(tuple(d), tuple(e))
+            d.rotate(-i)        # check that it works in reverse
+            self.assertEqual(tuple(d), s)
+            e.rotate(n-i)       # check that it wraps forward
+            self.assertEqual(tuple(e), s)
+
+        for i in xrange(n*3):
+            d = deque(s)
+            e = deque(d)
+            d.rotate(-i)
+            for j in xrange(i):
+                e.rotate(-1)    # check vs. rot(-1) n times
+            self.assertEqual(tuple(d), tuple(e))
+            d.rotate(i)         # check that it works in reverse
+            self.assertEqual(tuple(d), s)
+            e.rotate(i-n)       # check that it wraps backaround
+            self.assertEqual(tuple(e), s)
+
+        d = deque(s)
+        e = deque(s)
+        e.rotate(BIG+17)        # verify on long series of rotates
+        dr = d.rotate
+        for i in xrange(BIG+17):
+            dr()
+        self.assertEqual(tuple(d), tuple(e))
+
+        self.assertRaises(TypeError, d.rotate, 'x')   # Wrong arg type
+        self.assertRaises(TypeError, d.rotate, 1, 10) # Too many args
+
+        d = deque()
+        d.rotate()              # rotate an empty deque
+        self.assertEqual(d, deque())
+
+    def test_len(self):
+        d = deque('ab')
+        self.assertEqual(len(d), 2)
+        d.popleft()
+        self.assertEqual(len(d), 1)
+        d.pop()
+        self.assertEqual(len(d), 0)
+        self.assertRaises(IndexError, d.pop)
+        self.assertEqual(len(d), 0)
+        d.append('c')
+        self.assertEqual(len(d), 1)
+        d.appendleft('d')
+        self.assertEqual(len(d), 2)
+        d.clear()
+        self.assertEqual(len(d), 0)
+
+    def test_underflow(self):
+        d = deque()
+        self.assertRaises(IndexError, d.pop)
+        self.assertRaises(IndexError, d.popleft)
+
+    def test_clear(self):
+        d = deque(xrange(100))
+        self.assertEqual(len(d), 100)
+        d.clear()
+        self.assertEqual(len(d), 0)
+        self.assertEqual(list(d), [])
+        d.clear()               # clear an emtpy deque
+        self.assertEqual(list(d), [])
+
+    def test_remove(self):
+        d = deque('abcdefghcij')
+        d.remove('c')
+        self.assertEqual(d, deque('abdefghcij'))
+        d.remove('c')
+        self.assertEqual(d, deque('abdefghij'))
+        self.assertRaises(ValueError, d.remove, 'c')
+        self.assertEqual(d, deque('abdefghij'))
+
+        # Handle comparison errors
+        d = deque(['a', 'b', BadCmp(), 'c'])
+        e = deque(d)
+        self.assertRaises(RuntimeError, d.remove, 'c')
+        for x, y in zip(d, e):
+            # verify that original order and values are retained.
+            self.assert_(x is y)
+
+        # Handle evil mutator
+        for match in (True, False):
+            d = deque(['ab'])
+            d.extend([MutateCmp(d, match), 'c'])
+            self.assertRaises(IndexError, d.remove, 'c')
+            self.assertEqual(d, deque())
+
+    def test_repr(self):
+        d = deque(xrange(200))
+        e = eval(repr(d))
+        self.assertEqual(list(d), list(e))
+        d.append(d)
+        self.assert_('...' in repr(d))
+
+    def test_print(self):
+        d = deque(xrange(200))
+        d.append(d)
+        try:
+            fo = open(test_support.TESTFN, "wb")
+            print >> fo, d,
+            fo.close()
+            fo = open(test_support.TESTFN, "rb")
+            self.assertEqual(fo.read(), repr(d))
+        finally:
+            fo.close()
+            os.remove(test_support.TESTFN)
+
+    def test_init(self):
+        self.assertRaises(TypeError, deque, 'abc', 2);
+        self.assertRaises(TypeError, deque, 1);
+
+    def test_hash(self):
+        self.assertRaises(TypeError, hash, deque('abc'))
+
+    def test_long_steadystate_queue_popleft(self):
+        for size in (0, 1, 2, 100, 1000):
+            d = deque(xrange(size))
+            append, pop = d.append, d.popleft
+            for i in xrange(size, BIG):
+                append(i)
+                x = pop()
+                if x != i - size:
+                    self.assertEqual(x, i-size)
+            self.assertEqual(list(d), range(BIG-size, BIG))
+
+    def test_long_steadystate_queue_popright(self):
+        for size in (0, 1, 2, 100, 1000):
+            d = deque(reversed(xrange(size)))
+            append, pop = d.appendleft, d.pop
+            for i in xrange(size, BIG):
+                append(i)
+                x = pop()
+                if x != i - size:
+                    self.assertEqual(x, i-size)
+            self.assertEqual(list(reversed(list(d))), range(BIG-size, BIG))
+
+    def test_big_queue_popleft(self):
+        pass
+        d = deque()
+        append, pop = d.append, d.popleft
+        for i in xrange(BIG):
+            append(i)
+        for i in xrange(BIG):
+            x = pop()
+            if x != i:
+                self.assertEqual(x, i)
+
+    def test_big_queue_popright(self):
+        d = deque()
+        append, pop = d.appendleft, d.pop
+        for i in xrange(BIG):
+            append(i)
+        for i in xrange(BIG):
+            x = pop()
+            if x != i:
+                self.assertEqual(x, i)
+
+    def test_big_stack_right(self):
+        d = deque()
+        append, pop = d.append, d.pop
+        for i in xrange(BIG):
+            append(i)
+        for i in reversed(xrange(BIG)):
+            x = pop()
+            if x != i:
+                self.assertEqual(x, i)
+        self.assertEqual(len(d), 0)
+
+    def test_big_stack_left(self):
+        d = deque()
+        append, pop = d.appendleft, d.popleft
+        for i in xrange(BIG):
+            append(i)
+        for i in reversed(xrange(BIG)):
+            x = pop()
+            if x != i:
+                self.assertEqual(x, i)
+        self.assertEqual(len(d), 0)
+
+    def test_roundtrip_iter_init(self):
+        d = deque(xrange(200))
+        e = deque(d)
+        self.assertNotEqual(id(d), id(e))
+        self.assertEqual(list(d), list(e))
+
+    def test_pickle(self):
+        d = deque(xrange(200))
+        for i in (0, 1, 2):
+            s = pickle.dumps(d, i)
+            e = pickle.loads(s)
+            self.assertNotEqual(id(d), id(e))
+            self.assertEqual(list(d), list(e))
+
+    def test_pickle_recursive(self):
+        d = deque('abc')
+        d.append(d)
+        for i in (0, 1, 2):
+            e = pickle.loads(pickle.dumps(d, i))
+            self.assertNotEqual(id(d), id(e))
+            self.assertEqual(id(e), id(e[-1]))
+
+    def test_deepcopy(self):
+        mut = [10]
+        d = deque([mut])
+        e = copy.deepcopy(d)
+        self.assertEqual(list(d), list(e))
+        mut[0] = 11
+        self.assertNotEqual(id(d), id(e))
+        self.assertNotEqual(list(d), list(e))
+
+    def test_copy(self):
+        mut = [10]
+        d = deque([mut])
+        e = copy.copy(d)
+        self.assertEqual(list(d), list(e))
+        mut[0] = 11
+        self.assertNotEqual(id(d), id(e))
+        self.assertEqual(list(d), list(e))
+
+    def test_reversed(self):
+        for s in ('abcd', xrange(2000)):
+            self.assertEqual(list(reversed(deque(s))), list(reversed(s)))
+
+    def test_gc_doesnt_blowup(self):
+        import gc
+        # This used to assert-fail in deque_traverse() under a debug
+        # build, or run wild with a NULL pointer in a release build.
+        d = deque()
+        for i in xrange(100):
+            d.append(1)
+            gc.collect()
+
+class TestVariousIteratorArgs(unittest.TestCase):
+
+    def test_constructor(self):
+        for s in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5)):
+            for g in (seq_tests.Sequence, seq_tests.IterFunc,
+                      seq_tests.IterGen, seq_tests.IterFuncStop,
+                      seq_tests.itermulti, seq_tests.iterfunc):
+                self.assertEqual(list(deque(g(s))), list(g(s)))
+            self.assertRaises(TypeError, deque, seq_tests.IterNextOnly(s))
+            self.assertRaises(TypeError, deque, seq_tests.IterNoNext(s))
+            self.assertRaises(ZeroDivisionError, deque, seq_tests.IterGenExc(s))
+
+    def test_iter_with_altered_data(self):
+        d = deque('abcdefg')
+        it = iter(d)
+        d.pop()
+        self.assertRaises(RuntimeError, it.next)
+
+    def test_runtime_error_on_empty_deque(self):
+        d = deque()
+        it = iter(d)
+        d.append(10)
+        self.assertRaises(RuntimeError, it.next)
+
+class Deque(deque):
+    pass
+
+class DequeWithBadIter(deque):
+    def __iter__(self):
+        raise TypeError
+
+class TestSubclass(unittest.TestCase):
+
+    def test_basics(self):
+        d = Deque(xrange(100))
+        d.__init__(xrange(100, 200))
+        for i in xrange(200, 400):
+            d.append(i)
+        for i in reversed(xrange(-200, 0)):
+            d.appendleft(i)
+        self.assertEqual(list(d), range(-200, 400))
+        self.assertEqual(len(d), 600)
+
+        left = [d.popleft() for i in xrange(250)]
+        self.assertEqual(left, range(-200, 50))
+        self.assertEqual(list(d), range(50, 400))
+
+        right = [d.pop() for i in xrange(250)]
+        right.reverse()
+        self.assertEqual(right, range(150, 400))
+        self.assertEqual(list(d), range(50, 150))
+
+        d.clear()
+        self.assertEqual(len(d), 0)
+
+    def test_copy_pickle(self):
+
+        d = Deque('abc')
+
+        e = d.__copy__()
+        self.assertEqual(type(d), type(e))
+        self.assertEqual(list(d), list(e))
+
+        e = Deque(d)
+        self.assertEqual(type(d), type(e))
+        self.assertEqual(list(d), list(e))
+
+        s = pickle.dumps(d)
+        e = pickle.loads(s)
+        self.assertNotEqual(id(d), id(e))
+        self.assertEqual(type(d), type(e))
+        self.assertEqual(list(d), list(e))
+
+    def test_pickle(self):
+        d = Deque('abc')
+        d.append(d)
+
+        e = pickle.loads(pickle.dumps(d))
+        self.assertNotEqual(id(d), id(e))
+        self.assertEqual(type(d), type(e))
+        dd = d.pop()
+        ee = e.pop()
+        self.assertEqual(id(e), id(ee))
+        self.assertEqual(d, e)
+
+        d.x = d
+        e = pickle.loads(pickle.dumps(d))
+        self.assertEqual(id(e), id(e.x))
+
+        d = DequeWithBadIter('abc')
+        self.assertRaises(TypeError, pickle.dumps, d)
+
+    def test_weakref(self):
+        d = deque('gallahad')
+        p = proxy(d)
+        self.assertEqual(str(p), str(d))
+        d = None
+        self.assertRaises(ReferenceError, str, p)
+
+    def test_strange_subclass(self):
+        class X(deque):
+            def __iter__(self):
+                return iter([])
+        d1 = X([1,2,3])
+        d2 = X([4,5,6])
+        d1 == d2   # not clear if this is supposed to be True or False,
+                   # but it used to give a SystemError
+
+
+class SubclassWithKwargs(deque):
+    def __init__(self, newarg=1):
+        deque.__init__(self)
+
+class TestSubclassWithKwargs(unittest.TestCase):
+    def test_subclass_with_kwargs(self):
+        # SF bug #1486663 -- this used to erroneously raise a TypeError
+        SubclassWithKwargs(newarg=1)
+
+#==============================================================================
+
+libreftest = """
+Example from the Library Reference:  Doc/lib/libcollections.tex
+
+>>> from collections import deque
+>>> d = deque('ghi')                 # make a new deque with three items
+>>> for elem in d:                   # iterate over the deque's elements
+...     print elem.upper()
+G
+H
+I
+>>> d.append('j')                    # add a new entry to the right side
+>>> d.appendleft('f')                # add a new entry to the left side
+>>> d                                # show the representation of the deque
+deque(['f', 'g', 'h', 'i', 'j'])
+>>> d.pop()                          # return and remove the rightmost item
+'j'
+>>> d.popleft()                      # return and remove the leftmost item
+'f'
+>>> list(d)                          # list the contents of the deque
+['g', 'h', 'i']
+>>> d[0]                             # peek at leftmost item
+'g'
+>>> d[-1]                            # peek at rightmost item
+'i'
+>>> list(reversed(d))                # list the contents of a deque in reverse
+['i', 'h', 'g']
+>>> 'h' in d                         # search the deque
+True
+>>> d.extend('jkl')                  # add multiple elements at once
+>>> d
+deque(['g', 'h', 'i', 'j', 'k', 'l'])
+>>> d.rotate(1)                      # right rotation
+>>> d
+deque(['l', 'g', 'h', 'i', 'j', 'k'])
+>>> d.rotate(-1)                     # left rotation
+>>> d
+deque(['g', 'h', 'i', 'j', 'k', 'l'])
+>>> deque(reversed(d))               # make a new deque in reverse order
+deque(['l', 'k', 'j', 'i', 'h', 'g'])
+>>> d.clear()                        # empty the deque
+>>> d.pop()                          # cannot pop from an empty deque
+Traceback (most recent call last):
+  File "<pyshell#6>", line 1, in -toplevel-
+    d.pop()
+IndexError: pop from an empty deque
+
+>>> d.extendleft('abc')              # extendleft() reverses the input order
+>>> d
+deque(['c', 'b', 'a'])
+
+
+
+>>> def delete_nth(d, n):
+...     d.rotate(-n)
+...     d.popleft()
+...     d.rotate(n)
+...
+>>> d = deque('abcdef')
+>>> delete_nth(d, 2)   # remove the entry at d[2]
+>>> d
+deque(['a', 'b', 'd', 'e', 'f'])
+
+
+
+>>> def roundrobin(*iterables):
+...     pending = deque(iter(i) for i in iterables)
+...     while pending:
+...         task = pending.popleft()
+...         try:
+...             yield task.next()
+...         except StopIteration:
+...             continue
+...         pending.append(task)
+...
+
+>>> for value in roundrobin('abc', 'd', 'efgh'):
+...     print value
+...
+a
+d
+e
+b
+f
+c
+g
+h
+
+
+>>> def maketree(iterable):
+...     d = deque(iterable)
+...     while len(d) > 1:
+...         pair = [d.popleft(), d.popleft()]
+...         d.append(pair)
+...     return list(d)
+...
+>>> print maketree('abcdefgh')
+[[[['a', 'b'], ['c', 'd']], [['e', 'f'], ['g', 'h']]]]
+
+"""
+
+
+#==============================================================================
+
+__test__ = {'libreftest' : libreftest}
+
+def test_main(verbose=None):
+    import sys
+    test_classes = (
+        TestBasic,
+        TestVariousIteratorArgs,
+        TestSubclass,
+        TestSubclassWithKwargs,
+    )
+
+    test_support.run_unittest(*test_classes)
+
+    # verify reference counting
+    if verbose and hasattr(sys, "gettotalrefcount"):
+        import gc
+        counts = [None] * 5
+        for i in xrange(len(counts)):
+            test_support.run_unittest(*test_classes)
+            gc.collect()
+            counts[i] = sys.gettotalrefcount()
+        print counts
+
+    # doctests
+    from test import test_deque
+    test_support.run_doctest(test_deque, verbose)
+
+if __name__ == "__main__":
+    test_main(verbose=True)

Added: vendor/Python/current/Lib/test/test_descr.py
===================================================================
--- vendor/Python/current/Lib/test/test_descr.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_descr.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,4283 @@
+# Test enhancements related to descriptors and new-style classes
+
+from test.test_support import verify, vereq, verbose, TestFailed, TESTFN, get_original_stdout
+from copy import deepcopy
+import warnings
+
+warnings.filterwarnings("ignore",
+         r'complex divmod\(\), // and % are deprecated$',
+         DeprecationWarning, r'(<string>|%s)$' % __name__)
+
+def veris(a, b):
+    if a is not b:
+        raise TestFailed, "%r is %r" % (a, b)
+
+def testunop(a, res, expr="len(a)", meth="__len__"):
+    if verbose: print "checking", expr
+    dict = {'a': a}
+    vereq(eval(expr, dict), res)
+    t = type(a)
+    m = getattr(t, meth)
+    while meth not in t.__dict__:
+        t = t.__bases__[0]
+    vereq(m, t.__dict__[meth])
+    vereq(m(a), res)
+    bm = getattr(a, meth)
+    vereq(bm(), res)
+
+def testbinop(a, b, res, expr="a+b", meth="__add__"):
+    if verbose: print "checking", expr
+    dict = {'a': a, 'b': b}
+
+    # XXX Hack so this passes before 2.3 when -Qnew is specified.
+    if meth == "__div__" and 1/2 == 0.5:
+        meth = "__truediv__"
+
+    vereq(eval(expr, dict), res)
+    t = type(a)
+    m = getattr(t, meth)
+    while meth not in t.__dict__:
+        t = t.__bases__[0]
+    vereq(m, t.__dict__[meth])
+    vereq(m(a, b), res)
+    bm = getattr(a, meth)
+    vereq(bm(b), res)
+
+def testternop(a, b, c, res, expr="a[b:c]", meth="__getslice__"):
+    if verbose: print "checking", expr
+    dict = {'a': a, 'b': b, 'c': c}
+    vereq(eval(expr, dict), res)
+    t = type(a)
+    m = getattr(t, meth)
+    while meth not in t.__dict__:
+        t = t.__bases__[0]
+    vereq(m, t.__dict__[meth])
+    vereq(m(a, b, c), res)
+    bm = getattr(a, meth)
+    vereq(bm(b, c), res)
+
+def testsetop(a, b, res, stmt="a+=b", meth="__iadd__"):
+    if verbose: print "checking", stmt
+    dict = {'a': deepcopy(a), 'b': b}
+    exec stmt in dict
+    vereq(dict['a'], res)
+    t = type(a)
+    m = getattr(t, meth)
+    while meth not in t.__dict__:
+        t = t.__bases__[0]
+    vereq(m, t.__dict__[meth])
+    dict['a'] = deepcopy(a)
+    m(dict['a'], b)
+    vereq(dict['a'], res)
+    dict['a'] = deepcopy(a)
+    bm = getattr(dict['a'], meth)
+    bm(b)
+    vereq(dict['a'], res)
+
+def testset2op(a, b, c, res, stmt="a[b]=c", meth="__setitem__"):
+    if verbose: print "checking", stmt
+    dict = {'a': deepcopy(a), 'b': b, 'c': c}
+    exec stmt in dict
+    vereq(dict['a'], res)
+    t = type(a)
+    m = getattr(t, meth)
+    while meth not in t.__dict__:
+        t = t.__bases__[0]
+    vereq(m, t.__dict__[meth])
+    dict['a'] = deepcopy(a)
+    m(dict['a'], b, c)
+    vereq(dict['a'], res)
+    dict['a'] = deepcopy(a)
+    bm = getattr(dict['a'], meth)
+    bm(b, c)
+    vereq(dict['a'], res)
+
+def testset3op(a, b, c, d, res, stmt="a[b:c]=d", meth="__setslice__"):
+    if verbose: print "checking", stmt
+    dict = {'a': deepcopy(a), 'b': b, 'c': c, 'd': d}
+    exec stmt in dict
+    vereq(dict['a'], res)
+    t = type(a)
+    while meth not in t.__dict__:
+        t = t.__bases__[0]
+    m = getattr(t, meth)
+    vereq(m, t.__dict__[meth])
+    dict['a'] = deepcopy(a)
+    m(dict['a'], b, c, d)
+    vereq(dict['a'], res)
+    dict['a'] = deepcopy(a)
+    bm = getattr(dict['a'], meth)
+    bm(b, c, d)
+    vereq(dict['a'], res)
+
+def class_docstrings():
+    class Classic:
+        "A classic docstring."
+    vereq(Classic.__doc__, "A classic docstring.")
+    vereq(Classic.__dict__['__doc__'], "A classic docstring.")
+
+    class Classic2:
+        pass
+    verify(Classic2.__doc__ is None)
+
+    class NewStatic(object):
+        "Another docstring."
+    vereq(NewStatic.__doc__, "Another docstring.")
+    vereq(NewStatic.__dict__['__doc__'], "Another docstring.")
+
+    class NewStatic2(object):
+        pass
+    verify(NewStatic2.__doc__ is None)
+
+    class NewDynamic(object):
+        "Another docstring."
+    vereq(NewDynamic.__doc__, "Another docstring.")
+    vereq(NewDynamic.__dict__['__doc__'], "Another docstring.")
+
+    class NewDynamic2(object):
+        pass
+    verify(NewDynamic2.__doc__ is None)
+
+def lists():
+    if verbose: print "Testing list operations..."
+    testbinop([1], [2], [1,2], "a+b", "__add__")
+    testbinop([1,2,3], 2, 1, "b in a", "__contains__")
+    testbinop([1,2,3], 4, 0, "b in a", "__contains__")
+    testbinop([1,2,3], 1, 2, "a[b]", "__getitem__")
+    testternop([1,2,3], 0, 2, [1,2], "a[b:c]", "__getslice__")
+    testsetop([1], [2], [1,2], "a+=b", "__iadd__")
+    testsetop([1,2], 3, [1,2,1,2,1,2], "a*=b", "__imul__")
+    testunop([1,2,3], 3, "len(a)", "__len__")
+    testbinop([1,2], 3, [1,2,1,2,1,2], "a*b", "__mul__")
+    testbinop([1,2], 3, [1,2,1,2,1,2], "b*a", "__rmul__")
+    testset2op([1,2], 1, 3, [1,3], "a[b]=c", "__setitem__")
+    testset3op([1,2,3,4], 1, 3, [5,6], [1,5,6,4], "a[b:c]=d", "__setslice__")
+
+def dicts():
+    if verbose: print "Testing dict operations..."
+    testbinop({1:2}, {2:1}, -1, "cmp(a,b)", "__cmp__")
+    testbinop({1:2,3:4}, 1, 1, "b in a", "__contains__")
+    testbinop({1:2,3:4}, 2, 0, "b in a", "__contains__")
+    testbinop({1:2,3:4}, 1, 2, "a[b]", "__getitem__")
+    d = {1:2,3:4}
+    l1 = []
+    for i in d.keys(): l1.append(i)
+    l = []
+    for i in iter(d): l.append(i)
+    vereq(l, l1)
+    l = []
+    for i in d.__iter__(): l.append(i)
+    vereq(l, l1)
+    l = []
+    for i in dict.__iter__(d): l.append(i)
+    vereq(l, l1)
+    d = {1:2, 3:4}
+    testunop(d, 2, "len(a)", "__len__")
+    vereq(eval(repr(d), {}), d)
+    vereq(eval(d.__repr__(), {}), d)
+    testset2op({1:2,3:4}, 2, 3, {1:2,2:3,3:4}, "a[b]=c", "__setitem__")
+
+def dict_constructor():
+    if verbose:
+        print "Testing dict constructor ..."
+    d = dict()
+    vereq(d, {})
+    d = dict({})
+    vereq(d, {})
+    d = dict({1: 2, 'a': 'b'})
+    vereq(d, {1: 2, 'a': 'b'})
+    vereq(d, dict(d.items()))
+    vereq(d, dict(d.iteritems()))
+    d = dict({'one':1, 'two':2})
+    vereq(d, dict(one=1, two=2))
+    vereq(d, dict(**d))
+    vereq(d, dict({"one": 1}, two=2))
+    vereq(d, dict([("two", 2)], one=1))
+    vereq(d, dict([("one", 100), ("two", 200)], **d))
+    verify(d is not dict(**d))
+    for badarg in 0, 0L, 0j, "0", [0], (0,):
+        try:
+            dict(badarg)
+        except TypeError:
+            pass
+        except ValueError:
+            if badarg == "0":
+                # It's a sequence, and its elements are also sequences (gotta
+                # love strings <wink>), but they aren't of length 2, so this
+                # one seemed better as a ValueError than a TypeError.
+                pass
+            else:
+                raise TestFailed("no TypeError from dict(%r)" % badarg)
+        else:
+            raise TestFailed("no TypeError from dict(%r)" % badarg)
+
+    try:
+        dict({}, {})
+    except TypeError:
+        pass
+    else:
+        raise TestFailed("no TypeError from dict({}, {})")
+
+    class Mapping:
+        # Lacks a .keys() method; will be added later.
+        dict = {1:2, 3:4, 'a':1j}
+
+    try:
+        dict(Mapping())
+    except TypeError:
+        pass
+    else:
+        raise TestFailed("no TypeError from dict(incomplete mapping)")
+
+    Mapping.keys = lambda self: self.dict.keys()
+    Mapping.__getitem__ = lambda self, i: self.dict[i]
+    d = dict(Mapping())
+    vereq(d, Mapping.dict)
+
+    # Init from sequence of iterable objects, each producing a 2-sequence.
+    class AddressBookEntry:
+        def __init__(self, first, last):
+            self.first = first
+            self.last = last
+        def __iter__(self):
+            return iter([self.first, self.last])
+
+    d = dict([AddressBookEntry('Tim', 'Warsaw'),
+              AddressBookEntry('Barry', 'Peters'),
+              AddressBookEntry('Tim', 'Peters'),
+              AddressBookEntry('Barry', 'Warsaw')])
+    vereq(d, {'Barry': 'Warsaw', 'Tim': 'Peters'})
+
+    d = dict(zip(range(4), range(1, 5)))
+    vereq(d, dict([(i, i+1) for i in range(4)]))
+
+    # Bad sequence lengths.
+    for bad in [('tooshort',)], [('too', 'long', 'by 1')]:
+        try:
+            dict(bad)
+        except ValueError:
+            pass
+        else:
+            raise TestFailed("no ValueError from dict(%r)" % bad)
+
+def test_dir():
+    if verbose:
+        print "Testing dir() ..."
+    junk = 12
+    vereq(dir(), ['junk'])
+    del junk
+
+    # Just make sure these don't blow up!
+    for arg in 2, 2L, 2j, 2e0, [2], "2", u"2", (2,), {2:2}, type, test_dir:
+        dir(arg)
+
+    # Try classic classes.
+    class C:
+        Cdata = 1
+        def Cmethod(self): pass
+
+    cstuff = ['Cdata', 'Cmethod', '__doc__', '__module__']
+    vereq(dir(C), cstuff)
+    verify('im_self' in dir(C.Cmethod))
+
+    c = C()  # c.__doc__ is an odd thing to see here; ditto c.__module__.
+    vereq(dir(c), cstuff)
+
+    c.cdata = 2
+    c.cmethod = lambda self: 0
+    vereq(dir(c), cstuff + ['cdata', 'cmethod'])
+    verify('im_self' in dir(c.Cmethod))
+
+    class A(C):
+        Adata = 1
+        def Amethod(self): pass
+
+    astuff = ['Adata', 'Amethod'] + cstuff
+    vereq(dir(A), astuff)
+    verify('im_self' in dir(A.Amethod))
+    a = A()
+    vereq(dir(a), astuff)
+    verify('im_self' in dir(a.Amethod))
+    a.adata = 42
+    a.amethod = lambda self: 3
+    vereq(dir(a), astuff + ['adata', 'amethod'])
+
+    # The same, but with new-style classes.  Since these have object as a
+    # base class, a lot more gets sucked in.
+    def interesting(strings):
+        return [s for s in strings if not s.startswith('_')]
+
+    class C(object):
+        Cdata = 1
+        def Cmethod(self): pass
+
+    cstuff = ['Cdata', 'Cmethod']
+    vereq(interesting(dir(C)), cstuff)
+
+    c = C()
+    vereq(interesting(dir(c)), cstuff)
+    verify('im_self' in dir(C.Cmethod))
+
+    c.cdata = 2
+    c.cmethod = lambda self: 0
+    vereq(interesting(dir(c)), cstuff + ['cdata', 'cmethod'])
+    verify('im_self' in dir(c.Cmethod))
+
+    class A(C):
+        Adata = 1
+        def Amethod(self): pass
+
+    astuff = ['Adata', 'Amethod'] + cstuff
+    vereq(interesting(dir(A)), astuff)
+    verify('im_self' in dir(A.Amethod))
+    a = A()
+    vereq(interesting(dir(a)), astuff)
+    a.adata = 42
+    a.amethod = lambda self: 3
+    vereq(interesting(dir(a)), astuff + ['adata', 'amethod'])
+    verify('im_self' in dir(a.Amethod))
+
+    # Try a module subclass.
+    import sys
+    class M(type(sys)):
+        pass
+    minstance = M("m")
+    minstance.b = 2
+    minstance.a = 1
+    names = [x for x in dir(minstance) if x not in ["__name__", "__doc__"]]
+    vereq(names, ['a', 'b'])
+
+    class M2(M):
+        def getdict(self):
+            return "Not a dict!"
+        __dict__ = property(getdict)
+
+    m2instance = M2("m2")
+    m2instance.b = 2
+    m2instance.a = 1
+    vereq(m2instance.__dict__, "Not a dict!")
+    try:
+        dir(m2instance)
+    except TypeError:
+        pass
+
+    # Two essentially featureless objects, just inheriting stuff from
+    # object.
+    vereq(dir(None), dir(Ellipsis))
+
+    # Nasty test case for proxied objects
+    class Wrapper(object):
+        def __init__(self, obj):
+            self.__obj = obj
+        def __repr__(self):
+            return "Wrapper(%s)" % repr(self.__obj)
+        def __getitem__(self, key):
+            return Wrapper(self.__obj[key])
+        def __len__(self):
+            return len(self.__obj)
+        def __getattr__(self, name):
+            return Wrapper(getattr(self.__obj, name))
+
+    class C(object):
+        def __getclass(self):
+            return Wrapper(type(self))
+        __class__ = property(__getclass)
+
+    dir(C()) # This used to segfault
+
+binops = {
+    'add': '+',
+    'sub': '-',
+    'mul': '*',
+    'div': '/',
+    'mod': '%',
+    'divmod': 'divmod',
+    'pow': '**',
+    'lshift': '<<',
+    'rshift': '>>',
+    'and': '&',
+    'xor': '^',
+    'or': '|',
+    'cmp': 'cmp',
+    'lt': '<',
+    'le': '<=',
+    'eq': '==',
+    'ne': '!=',
+    'gt': '>',
+    'ge': '>=',
+    }
+
+for name, expr in binops.items():
+    if expr.islower():
+        expr = expr + "(a, b)"
+    else:
+        expr = 'a %s b' % expr
+    binops[name] = expr
+
+unops = {
+    'pos': '+',
+    'neg': '-',
+    'abs': 'abs',
+    'invert': '~',
+    'int': 'int',
+    'long': 'long',
+    'float': 'float',
+    'oct': 'oct',
+    'hex': 'hex',
+    }
+
+for name, expr in unops.items():
+    if expr.islower():
+        expr = expr + "(a)"
+    else:
+        expr = '%s a' % expr
+    unops[name] = expr
+
+def numops(a, b, skip=[]):
+    dict = {'a': a, 'b': b}
+    for name, expr in binops.items():
+        if name not in skip:
+            name = "__%s__" % name
+            if hasattr(a, name):
+                res = eval(expr, dict)
+                testbinop(a, b, res, expr, name)
+    for name, expr in unops.items():
+        if name not in skip:
+            name = "__%s__" % name
+            if hasattr(a, name):
+                res = eval(expr, dict)
+                testunop(a, res, expr, name)
+
+def ints():
+    if verbose: print "Testing int operations..."
+    numops(100, 3)
+    # The following crashes in Python 2.2
+    vereq((1).__nonzero__(), 1)
+    vereq((0).__nonzero__(), 0)
+    # This returns 'NotImplemented' in Python 2.2
+    class C(int):
+        def __add__(self, other):
+            return NotImplemented
+    vereq(C(5L), 5)
+    try:
+        C() + ""
+    except TypeError:
+        pass
+    else:
+        raise TestFailed, "NotImplemented should have caused TypeError"
+    import sys
+    try:
+        C(sys.maxint+1)
+    except OverflowError:
+        pass
+    else:
+        raise TestFailed, "should have raised OverflowError"
+
+def longs():
+    if verbose: print "Testing long operations..."
+    numops(100L, 3L)
+
+def floats():
+    if verbose: print "Testing float operations..."
+    numops(100.0, 3.0)
+
+def complexes():
+    if verbose: print "Testing complex operations..."
+    numops(100.0j, 3.0j, skip=['lt', 'le', 'gt', 'ge', 'int', 'long', 'float'])
+    class Number(complex):
+        __slots__ = ['prec']
+        def __new__(cls, *args, **kwds):
+            result = complex.__new__(cls, *args)
+            result.prec = kwds.get('prec', 12)
+            return result
+        def __repr__(self):
+            prec = self.prec
+            if self.imag == 0.0:
+                return "%.*g" % (prec, self.real)
+            if self.real == 0.0:
+                return "%.*gj" % (prec, self.imag)
+            return "(%.*g+%.*gj)" % (prec, self.real, prec, self.imag)
+        __str__ = __repr__
+
+    a = Number(3.14, prec=6)
+    vereq(repr(a), "3.14")
+    vereq(a.prec, 6)
+
+    a = Number(a, prec=2)
+    vereq(repr(a), "3.1")
+    vereq(a.prec, 2)
+
+    a = Number(234.5)
+    vereq(repr(a), "234.5")
+    vereq(a.prec, 12)
+
+def spamlists():
+    if verbose: print "Testing spamlist operations..."
+    import copy, xxsubtype as spam
+    def spamlist(l, memo=None):
+        import xxsubtype as spam
+        return spam.spamlist(l)
+    # This is an ugly hack:
+    copy._deepcopy_dispatch[spam.spamlist] = spamlist
+
+    testbinop(spamlist([1]), spamlist([2]), spamlist([1,2]), "a+b", "__add__")
+    testbinop(spamlist([1,2,3]), 2, 1, "b in a", "__contains__")
+    testbinop(spamlist([1,2,3]), 4, 0, "b in a", "__contains__")
+    testbinop(spamlist([1,2,3]), 1, 2, "a[b]", "__getitem__")
+    testternop(spamlist([1,2,3]), 0, 2, spamlist([1,2]),
+               "a[b:c]", "__getslice__")
+    testsetop(spamlist([1]), spamlist([2]), spamlist([1,2]),
+              "a+=b", "__iadd__")
+    testsetop(spamlist([1,2]), 3, spamlist([1,2,1,2,1,2]), "a*=b", "__imul__")
+    testunop(spamlist([1,2,3]), 3, "len(a)", "__len__")
+    testbinop(spamlist([1,2]), 3, spamlist([1,2,1,2,1,2]), "a*b", "__mul__")
+    testbinop(spamlist([1,2]), 3, spamlist([1,2,1,2,1,2]), "b*a", "__rmul__")
+    testset2op(spamlist([1,2]), 1, 3, spamlist([1,3]), "a[b]=c", "__setitem__")
+    testset3op(spamlist([1,2,3,4]), 1, 3, spamlist([5,6]),
+               spamlist([1,5,6,4]), "a[b:c]=d", "__setslice__")
+    # Test subclassing
+    class C(spam.spamlist):
+        def foo(self): return 1
+    a = C()
+    vereq(a, [])
+    vereq(a.foo(), 1)
+    a.append(100)
+    vereq(a, [100])
+    vereq(a.getstate(), 0)
+    a.setstate(42)
+    vereq(a.getstate(), 42)
+
+def spamdicts():
+    if verbose: print "Testing spamdict operations..."
+    import copy, xxsubtype as spam
+    def spamdict(d, memo=None):
+        import xxsubtype as spam
+        sd = spam.spamdict()
+        for k, v in d.items(): sd[k] = v
+        return sd
+    # This is an ugly hack:
+    copy._deepcopy_dispatch[spam.spamdict] = spamdict
+
+    testbinop(spamdict({1:2}), spamdict({2:1}), -1, "cmp(a,b)", "__cmp__")
+    testbinop(spamdict({1:2,3:4}), 1, 1, "b in a", "__contains__")
+    testbinop(spamdict({1:2,3:4}), 2, 0, "b in a", "__contains__")
+    testbinop(spamdict({1:2,3:4}), 1, 2, "a[b]", "__getitem__")
+    d = spamdict({1:2,3:4})
+    l1 = []
+    for i in d.keys(): l1.append(i)
+    l = []
+    for i in iter(d): l.append(i)
+    vereq(l, l1)
+    l = []
+    for i in d.__iter__(): l.append(i)
+    vereq(l, l1)
+    l = []
+    for i in type(spamdict({})).__iter__(d): l.append(i)
+    vereq(l, l1)
+    straightd = {1:2, 3:4}
+    spamd = spamdict(straightd)
+    testunop(spamd, 2, "len(a)", "__len__")
+    testunop(spamd, repr(straightd), "repr(a)", "__repr__")
+    testset2op(spamdict({1:2,3:4}), 2, 3, spamdict({1:2,2:3,3:4}),
+               "a[b]=c", "__setitem__")
+    # Test subclassing
+    class C(spam.spamdict):
+        def foo(self): return 1
+    a = C()
+    vereq(a.items(), [])
+    vereq(a.foo(), 1)
+    a['foo'] = 'bar'
+    vereq(a.items(), [('foo', 'bar')])
+    vereq(a.getstate(), 0)
+    a.setstate(100)
+    vereq(a.getstate(), 100)
+
+def pydicts():
+    if verbose: print "Testing Python subclass of dict..."
+    verify(issubclass(dict, dict))
+    verify(isinstance({}, dict))
+    d = dict()
+    vereq(d, {})
+    verify(d.__class__ is dict)
+    verify(isinstance(d, dict))
+    class C(dict):
+        state = -1
+        def __init__(self, *a, **kw):
+            if a:
+                vereq(len(a), 1)
+                self.state = a[0]
+            if kw:
+                for k, v in kw.items(): self[v] = k
+        def __getitem__(self, key):
+            return self.get(key, 0)
+        def __setitem__(self, key, value):
+            verify(isinstance(key, type(0)))
+            dict.__setitem__(self, key, value)
+        def setstate(self, state):
+            self.state = state
+        def getstate(self):
+            return self.state
+    verify(issubclass(C, dict))
+    a1 = C(12)
+    vereq(a1.state, 12)
+    a2 = C(foo=1, bar=2)
+    vereq(a2[1] == 'foo' and a2[2], 'bar')
+    a = C()
+    vereq(a.state, -1)
+    vereq(a.getstate(), -1)
+    a.setstate(0)
+    vereq(a.state, 0)
+    vereq(a.getstate(), 0)
+    a.setstate(10)
+    vereq(a.state, 10)
+    vereq(a.getstate(), 10)
+    vereq(a[42], 0)
+    a[42] = 24
+    vereq(a[42], 24)
+    if verbose: print "pydict stress test ..."
+    N = 50
+    for i in range(N):
+        a[i] = C()
+        for j in range(N):
+            a[i][j] = i*j
+    for i in range(N):
+        for j in range(N):
+            vereq(a[i][j], i*j)
+
+def pylists():
+    if verbose: print "Testing Python subclass of list..."
+    class C(list):
+        def __getitem__(self, i):
+            return list.__getitem__(self, i) + 100
+        def __getslice__(self, i, j):
+            return (i, j)
+    a = C()
+    a.extend([0,1,2])
+    vereq(a[0], 100)
+    vereq(a[1], 101)
+    vereq(a[2], 102)
+    vereq(a[100:200], (100,200))
+
+def metaclass():
+    if verbose: print "Testing __metaclass__..."
+    class C:
+        __metaclass__ = type
+        def __init__(self):
+            self.__state = 0
+        def getstate(self):
+            return self.__state
+        def setstate(self, state):
+            self.__state = state
+    a = C()
+    vereq(a.getstate(), 0)
+    a.setstate(10)
+    vereq(a.getstate(), 10)
+    class D:
+        class __metaclass__(type):
+            def myself(cls): return cls
+    vereq(D.myself(), D)
+    d = D()
+    verify(d.__class__ is D)
+    class M1(type):
+        def __new__(cls, name, bases, dict):
+            dict['__spam__'] = 1
+            return type.__new__(cls, name, bases, dict)
+    class C:
+        __metaclass__ = M1
+    vereq(C.__spam__, 1)
+    c = C()
+    vereq(c.__spam__, 1)
+
+    class _instance(object):
+        pass
+    class M2(object):
+        @staticmethod
+        def __new__(cls, name, bases, dict):
+            self = object.__new__(cls)
+            self.name = name
+            self.bases = bases
+            self.dict = dict
+            return self
+        def __call__(self):
+            it = _instance()
+            # Early binding of methods
+            for key in self.dict:
+                if key.startswith("__"):
+                    continue
+                setattr(it, key, self.dict[key].__get__(it, self))
+            return it
+    class C:
+        __metaclass__ = M2
+        def spam(self):
+            return 42
+    vereq(C.name, 'C')
+    vereq(C.bases, ())
+    verify('spam' in C.dict)
+    c = C()
+    vereq(c.spam(), 42)
+
+    # More metaclass examples
+
+    class autosuper(type):
+        # Automatically add __super to the class
+        # This trick only works for dynamic classes
+        def __new__(metaclass, name, bases, dict):
+            cls = super(autosuper, metaclass).__new__(metaclass,
+                                                      name, bases, dict)
+            # Name mangling for __super removes leading underscores
+            while name[:1] == "_":
+                name = name[1:]
+            if name:
+                name = "_%s__super" % name
+            else:
+                name = "__super"
+            setattr(cls, name, super(cls))
+            return cls
+    class A:
+        __metaclass__ = autosuper
+        def meth(self):
+            return "A"
+    class B(A):
+        def meth(self):
+            return "B" + self.__super.meth()
+    class C(A):
+        def meth(self):
+            return "C" + self.__super.meth()
+    class D(C, B):
+        def meth(self):
+            return "D" + self.__super.meth()
+    vereq(D().meth(), "DCBA")
+    class E(B, C):
+        def meth(self):
+            return "E" + self.__super.meth()
+    vereq(E().meth(), "EBCA")
+
+    class autoproperty(type):
+        # Automatically create property attributes when methods
+        # named _get_x and/or _set_x are found
+        def __new__(metaclass, name, bases, dict):
+            hits = {}
+            for key, val in dict.iteritems():
+                if key.startswith("_get_"):
+                    key = key[5:]
+                    get, set = hits.get(key, (None, None))
+                    get = val
+                    hits[key] = get, set
+                elif key.startswith("_set_"):
+                    key = key[5:]
+                    get, set = hits.get(key, (None, None))
+                    set = val
+                    hits[key] = get, set
+            for key, (get, set) in hits.iteritems():
+                dict[key] = property(get, set)
+            return super(autoproperty, metaclass).__new__(metaclass,
+                                                        name, bases, dict)
+    class A:
+        __metaclass__ = autoproperty
+        def _get_x(self):
+            return -self.__x
+        def _set_x(self, x):
+            self.__x = -x
+    a = A()
+    verify(not hasattr(a, "x"))
+    a.x = 12
+    vereq(a.x, 12)
+    vereq(a._A__x, -12)
+
+    class multimetaclass(autoproperty, autosuper):
+        # Merge of multiple cooperating metaclasses
+        pass
+    class A:
+        __metaclass__ = multimetaclass
+        def _get_x(self):
+            return "A"
+    class B(A):
+        def _get_x(self):
+            return "B" + self.__super._get_x()
+    class C(A):
+        def _get_x(self):
+            return "C" + self.__super._get_x()
+    class D(C, B):
+        def _get_x(self):
+            return "D" + self.__super._get_x()
+    vereq(D().x, "DCBA")
+
+    # Make sure type(x) doesn't call x.__class__.__init__
+    class T(type):
+        counter = 0
+        def __init__(self, *args):
+            T.counter += 1
+    class C:
+        __metaclass__ = T
+    vereq(T.counter, 1)
+    a = C()
+    vereq(type(a), C)
+    vereq(T.counter, 1)
+
+    class C(object): pass
+    c = C()
+    try: c()
+    except TypeError: pass
+    else: raise TestFailed, "calling object w/o call method should raise TypeError"
+
+def pymods():
+    if verbose: print "Testing Python subclass of module..."
+    log = []
+    import sys
+    MT = type(sys)
+    class MM(MT):
+        def __init__(self, name):
+            MT.__init__(self, name)
+        def __getattribute__(self, name):
+            log.append(("getattr", name))
+            return MT.__getattribute__(self, name)
+        def __setattr__(self, name, value):
+            log.append(("setattr", name, value))
+            MT.__setattr__(self, name, value)
+        def __delattr__(self, name):
+            log.append(("delattr", name))
+            MT.__delattr__(self, name)
+    a = MM("a")
+    a.foo = 12
+    x = a.foo
+    del a.foo
+    vereq(log, [("setattr", "foo", 12),
+                ("getattr", "foo"),
+                ("delattr", "foo")])
+
+def multi():
+    if verbose: print "Testing multiple inheritance..."
+    class C(object):
+        def __init__(self):
+            self.__state = 0
+        def getstate(self):
+            return self.__state
+        def setstate(self, state):
+            self.__state = state
+    a = C()
+    vereq(a.getstate(), 0)
+    a.setstate(10)
+    vereq(a.getstate(), 10)
+    class D(dict, C):
+        def __init__(self):
+            type({}).__init__(self)
+            C.__init__(self)
+    d = D()
+    vereq(d.keys(), [])
+    d["hello"] = "world"
+    vereq(d.items(), [("hello", "world")])
+    vereq(d["hello"], "world")
+    vereq(d.getstate(), 0)
+    d.setstate(10)
+    vereq(d.getstate(), 10)
+    vereq(D.__mro__, (D, dict, C, object))
+
+    # SF bug #442833
+    class Node(object):
+        def __int__(self):
+            return int(self.foo())
+        def foo(self):
+            return "23"
+    class Frag(Node, list):
+        def foo(self):
+            return "42"
+    vereq(Node().__int__(), 23)
+    vereq(int(Node()), 23)
+    vereq(Frag().__int__(), 42)
+    vereq(int(Frag()), 42)
+
+    # MI mixing classic and new-style classes.
+
+    class A:
+        x = 1
+
+    class B(A):
+        pass
+
+    class C(A):
+        x = 2
+
+    class D(B, C):
+        pass
+    vereq(D.x, 1)
+
+    # Classic MRO is preserved for a classic base class.
+    class E(D, object):
+        pass
+    vereq(E.__mro__, (E, D, B, A, C, object))
+    vereq(E.x, 1)
+
+    # But with a mix of classic bases, their MROs are combined using
+    # new-style MRO.
+    class F(B, C, object):
+        pass
+    vereq(F.__mro__, (F, B, C, A, object))
+    vereq(F.x, 2)
+
+    # Try something else.
+    class C:
+        def cmethod(self):
+            return "C a"
+        def all_method(self):
+            return "C b"
+
+    class M1(C, object):
+        def m1method(self):
+            return "M1 a"
+        def all_method(self):
+            return "M1 b"
+
+    vereq(M1.__mro__, (M1, C, object))
+    m = M1()
+    vereq(m.cmethod(), "C a")
+    vereq(m.m1method(), "M1 a")
+    vereq(m.all_method(), "M1 b")
+
+    class D(C):
+        def dmethod(self):
+            return "D a"
+        def all_method(self):
+            return "D b"
+
+    class M2(D, object):
+        def m2method(self):
+            return "M2 a"
+        def all_method(self):
+            return "M2 b"
+
+    vereq(M2.__mro__, (M2, D, C, object))
+    m = M2()
+    vereq(m.cmethod(), "C a")
+    vereq(m.dmethod(), "D a")
+    vereq(m.m2method(), "M2 a")
+    vereq(m.all_method(), "M2 b")
+
+    class M3(M1, M2, object):
+        def m3method(self):
+            return "M3 a"
+        def all_method(self):
+            return "M3 b"
+    vereq(M3.__mro__, (M3, M1, M2, D, C, object))
+    m = M3()
+    vereq(m.cmethod(), "C a")
+    vereq(m.dmethod(), "D a")
+    vereq(m.m1method(), "M1 a")
+    vereq(m.m2method(), "M2 a")
+    vereq(m.m3method(), "M3 a")
+    vereq(m.all_method(), "M3 b")
+
+    class Classic:
+        pass
+    try:
+        class New(Classic):
+            __metaclass__ = type
+    except TypeError:
+        pass
+    else:
+        raise TestFailed, "new class with only classic bases - shouldn't be"
+
+def diamond():
+    if verbose: print "Testing multiple inheritance special cases..."
+    class A(object):
+        def spam(self): return "A"
+    vereq(A().spam(), "A")
+    class B(A):
+        def boo(self): return "B"
+        def spam(self): return "B"
+    vereq(B().spam(), "B")
+    vereq(B().boo(), "B")
+    class C(A):
+        def boo(self): return "C"
+    vereq(C().spam(), "A")
+    vereq(C().boo(), "C")
+    class D(B, C): pass
+    vereq(D().spam(), "B")
+    vereq(D().boo(), "B")
+    vereq(D.__mro__, (D, B, C, A, object))
+    class E(C, B): pass
+    vereq(E().spam(), "B")
+    vereq(E().boo(), "C")
+    vereq(E.__mro__, (E, C, B, A, object))
+    # MRO order disagreement
+    try:
+        class F(D, E): pass
+    except TypeError:
+        pass
+    else:
+        raise TestFailed, "expected MRO order disagreement (F)"
+    try:
+        class G(E, D): pass
+    except TypeError:
+        pass
+    else:
+        raise TestFailed, "expected MRO order disagreement (G)"
+
+
+# see thread python-dev/2002-October/029035.html
+def ex5():
+    if verbose: print "Testing ex5 from C3 switch discussion..."
+    class A(object): pass
+    class B(object): pass
+    class C(object): pass
+    class X(A): pass
+    class Y(A): pass
+    class Z(X,B,Y,C): pass
+    vereq(Z.__mro__, (Z, X, B, Y, A, C, object))
+
+# see "A Monotonic Superclass Linearization for Dylan",
+# by Kim Barrett et al. (OOPSLA 1996)
+def monotonicity():
+    if verbose: print "Testing MRO monotonicity..."
+    class Boat(object): pass
+    class DayBoat(Boat): pass
+    class WheelBoat(Boat): pass
+    class EngineLess(DayBoat): pass
+    class SmallMultihull(DayBoat): pass
+    class PedalWheelBoat(EngineLess,WheelBoat): pass
+    class SmallCatamaran(SmallMultihull): pass
+    class Pedalo(PedalWheelBoat,SmallCatamaran): pass
+
+    vereq(PedalWheelBoat.__mro__,
+          (PedalWheelBoat, EngineLess, DayBoat, WheelBoat, Boat,
+           object))
+    vereq(SmallCatamaran.__mro__,
+          (SmallCatamaran, SmallMultihull, DayBoat, Boat, object))
+
+    vereq(Pedalo.__mro__,
+          (Pedalo, PedalWheelBoat, EngineLess, SmallCatamaran,
+           SmallMultihull, DayBoat, WheelBoat, Boat, object))
+
+# see "A Monotonic Superclass Linearization for Dylan",
+# by Kim Barrett et al. (OOPSLA 1996)
+def consistency_with_epg():
+    if verbose: print "Testing consistentcy with EPG..."
+    class Pane(object): pass
+    class ScrollingMixin(object): pass
+    class EditingMixin(object): pass
+    class ScrollablePane(Pane,ScrollingMixin): pass
+    class EditablePane(Pane,EditingMixin): pass
+    class EditableScrollablePane(ScrollablePane,EditablePane): pass
+
+    vereq(EditableScrollablePane.__mro__,
+          (EditableScrollablePane, ScrollablePane, EditablePane,
+           Pane, ScrollingMixin, EditingMixin, object))
+
+mro_err_msg = """Cannot create a consistent method resolution
+order (MRO) for bases """
+
+def mro_disagreement():
+    if verbose: print "Testing error messages for MRO disagreement..."
+    def raises(exc, expected, callable, *args):
+        try:
+            callable(*args)
+        except exc, msg:
+            if not str(msg).startswith(expected):
+                raise TestFailed, "Message %r, expected %r" % (str(msg),
+                                                               expected)
+        else:
+            raise TestFailed, "Expected %s" % exc
+    class A(object): pass
+    class B(A): pass
+    class C(object): pass
+    # Test some very simple errors
+    raises(TypeError, "duplicate base class A",
+           type, "X", (A, A), {})
+    raises(TypeError, mro_err_msg,
+           type, "X", (A, B), {})
+    raises(TypeError, mro_err_msg,
+           type, "X", (A, C, B), {})
+    # Test a slightly more complex error
+    class GridLayout(object): pass
+    class HorizontalGrid(GridLayout): pass
+    class VerticalGrid(GridLayout): pass
+    class HVGrid(HorizontalGrid, VerticalGrid): pass
+    class VHGrid(VerticalGrid, HorizontalGrid): pass
+    raises(TypeError, mro_err_msg,
+           type, "ConfusedGrid", (HVGrid, VHGrid), {})
+
+def objects():
+    if verbose: print "Testing object class..."
+    a = object()
+    vereq(a.__class__, object)
+    vereq(type(a), object)
+    b = object()
+    verify(a is not b)
+    verify(not hasattr(a, "foo"))
+    try:
+        a.foo = 12
+    except (AttributeError, TypeError):
+        pass
+    else:
+        verify(0, "object() should not allow setting a foo attribute")
+    verify(not hasattr(object(), "__dict__"))
+
+    class Cdict(object):
+        pass
+    x = Cdict()
+    vereq(x.__dict__, {})
+    x.foo = 1
+    vereq(x.foo, 1)
+    vereq(x.__dict__, {'foo': 1})
+
+def slots():
+    if verbose: print "Testing __slots__..."
+    class C0(object):
+        __slots__ = []
+    x = C0()
+    verify(not hasattr(x, "__dict__"))
+    verify(not hasattr(x, "foo"))
+
+    class C1(object):
+        __slots__ = ['a']
+    x = C1()
+    verify(not hasattr(x, "__dict__"))
+    verify(not hasattr(x, "a"))
+    x.a = 1
+    vereq(x.a, 1)
+    x.a = None
+    veris(x.a, None)
+    del x.a
+    verify(not hasattr(x, "a"))
+
+    class C3(object):
+        __slots__ = ['a', 'b', 'c']
+    x = C3()
+    verify(not hasattr(x, "__dict__"))
+    verify(not hasattr(x, 'a'))
+    verify(not hasattr(x, 'b'))
+    verify(not hasattr(x, 'c'))
+    x.a = 1
+    x.b = 2
+    x.c = 3
+    vereq(x.a, 1)
+    vereq(x.b, 2)
+    vereq(x.c, 3)
+
+    class C4(object):
+        """Validate name mangling"""
+        __slots__ = ['__a']
+        def __init__(self, value):
+            self.__a = value
+        def get(self):
+            return self.__a
+    x = C4(5)
+    verify(not hasattr(x, '__dict__'))
+    verify(not hasattr(x, '__a'))
+    vereq(x.get(), 5)
+    try:
+        x.__a = 6
+    except AttributeError:
+        pass
+    else:
+        raise TestFailed, "Double underscored names not mangled"
+
+    # Make sure slot names are proper identifiers
+    try:
+        class C(object):
+            __slots__ = [None]
+    except TypeError:
+        pass
+    else:
+        raise TestFailed, "[None] slots not caught"
+    try:
+        class C(object):
+            __slots__ = ["foo bar"]
+    except TypeError:
+        pass
+    else:
+        raise TestFailed, "['foo bar'] slots not caught"
+    try:
+        class C(object):
+            __slots__ = ["foo\0bar"]
+    except TypeError:
+        pass
+    else:
+        raise TestFailed, "['foo\\0bar'] slots not caught"
+    try:
+        class C(object):
+            __slots__ = ["1"]
+    except TypeError:
+        pass
+    else:
+        raise TestFailed, "['1'] slots not caught"
+    try:
+        class C(object):
+            __slots__ = [""]
+    except TypeError:
+        pass
+    else:
+        raise TestFailed, "[''] slots not caught"
+    class C(object):
+        __slots__ = ["a", "a_b", "_a", "A0123456789Z"]
+
+    # Test unicode slot names
+    try:
+        unichr
+    except NameError:
+        pass
+    else:
+        # _unicode_to_string used to modify slots in certain circumstances 
+        slots = (unicode("foo"), unicode("bar"))
+        class C(object):
+            __slots__ = slots
+        x = C()
+        x.foo = 5
+        vereq(x.foo, 5)
+        veris(type(slots[0]), unicode)
+        # this used to leak references
+        try:
+            class C(object):
+                __slots__ = [unichr(128)]
+        except (TypeError, UnicodeEncodeError):
+            pass
+        else:
+            raise TestFailed, "[unichr(128)] slots not caught" 
+
+    # Test leaks
+    class Counted(object):
+        counter = 0    # counts the number of instances alive
+        def __init__(self):
+            Counted.counter += 1
+        def __del__(self):
+            Counted.counter -= 1
+    class C(object):
+        __slots__ = ['a', 'b', 'c']
+    x = C()
+    x.a = Counted()
+    x.b = Counted()
+    x.c = Counted()
+    vereq(Counted.counter, 3)
+    del x
+    vereq(Counted.counter, 0)
+    class D(C):
+        pass
+    x = D()
+    x.a = Counted()
+    x.z = Counted()
+    vereq(Counted.counter, 2)
+    del x
+    vereq(Counted.counter, 0)
+    class E(D):
+        __slots__ = ['e']
+    x = E()
+    x.a = Counted()
+    x.z = Counted()
+    x.e = Counted()
+    vereq(Counted.counter, 3)
+    del x
+    vereq(Counted.counter, 0)
+
+    # Test cyclical leaks [SF bug 519621]
+    class F(object):
+        __slots__ = ['a', 'b']
+    log = []
+    s = F()
+    s.a = [Counted(), s]
+    vereq(Counted.counter, 1)
+    s = None
+    import gc
+    gc.collect()
+    vereq(Counted.counter, 0)
+
+    # Test lookup leaks [SF bug 572567]
+    import sys,gc
+    class G(object):
+        def __cmp__(self, other):
+            return 0
+    g = G()
+    orig_objects = len(gc.get_objects())
+    for i in xrange(10):
+        g==g
+    new_objects = len(gc.get_objects())
+    vereq(orig_objects, new_objects)
+    class H(object):
+        __slots__ = ['a', 'b']
+        def __init__(self):
+            self.a = 1
+            self.b = 2
+        def __del__(self):
+            assert self.a == 1
+            assert self.b == 2
+
+    save_stderr = sys.stderr
+    sys.stderr = sys.stdout
+    h = H()
+    try:
+        del h
+    finally:
+        sys.stderr = save_stderr
+
+def slotspecials():
+    if verbose: print "Testing __dict__ and __weakref__ in __slots__..."
+
+    class D(object):
+        __slots__ = ["__dict__"]
+    a = D()
+    verify(hasattr(a, "__dict__"))
+    verify(not hasattr(a, "__weakref__"))
+    a.foo = 42
+    vereq(a.__dict__, {"foo": 42})
+
+    class W(object):
+        __slots__ = ["__weakref__"]
+    a = W()
+    verify(hasattr(a, "__weakref__"))
+    verify(not hasattr(a, "__dict__"))
+    try:
+        a.foo = 42
+    except AttributeError:
+        pass
+    else:
+        raise TestFailed, "shouldn't be allowed to set a.foo"
+
+    class C1(W, D):
+        __slots__ = []
+    a = C1()
+    verify(hasattr(a, "__dict__"))
+    verify(hasattr(a, "__weakref__"))
+    a.foo = 42
+    vereq(a.__dict__, {"foo": 42})
+
+    class C2(D, W):
+        __slots__ = []
+    a = C2()
+    verify(hasattr(a, "__dict__"))
+    verify(hasattr(a, "__weakref__"))
+    a.foo = 42
+    vereq(a.__dict__, {"foo": 42})
+
+# MRO order disagreement
+#
+#    class C3(C1, C2):
+#        __slots__ = []
+#
+#    class C4(C2, C1):
+#        __slots__ = []
+
+def dynamics():
+    if verbose: print "Testing class attribute propagation..."
+    class D(object):
+        pass
+    class E(D):
+        pass
+    class F(D):
+        pass
+    D.foo = 1
+    vereq(D.foo, 1)
+    # Test that dynamic attributes are inherited
+    vereq(E.foo, 1)
+    vereq(F.foo, 1)
+    # Test dynamic instances
+    class C(object):
+        pass
+    a = C()
+    verify(not hasattr(a, "foobar"))
+    C.foobar = 2
+    vereq(a.foobar, 2)
+    C.method = lambda self: 42
+    vereq(a.method(), 42)
+    C.__repr__ = lambda self: "C()"
+    vereq(repr(a), "C()")
+    C.__int__ = lambda self: 100
+    vereq(int(a), 100)
+    vereq(a.foobar, 2)
+    verify(not hasattr(a, "spam"))
+    def mygetattr(self, name):
+        if name == "spam":
+            return "spam"
+        raise AttributeError
+    C.__getattr__ = mygetattr
+    vereq(a.spam, "spam")
+    a.new = 12
+    vereq(a.new, 12)
+    def mysetattr(self, name, value):
+        if name == "spam":
+            raise AttributeError
+        return object.__setattr__(self, name, value)
+    C.__setattr__ = mysetattr
+    try:
+        a.spam = "not spam"
+    except AttributeError:
+        pass
+    else:
+        verify(0, "expected AttributeError")
+    vereq(a.spam, "spam")
+    class D(C):
+        pass
+    d = D()
+    d.foo = 1
+    vereq(d.foo, 1)
+
+    # Test handling of int*seq and seq*int
+    class I(int):
+        pass
+    vereq("a"*I(2), "aa")
+    vereq(I(2)*"a", "aa")
+    vereq(2*I(3), 6)
+    vereq(I(3)*2, 6)
+    vereq(I(3)*I(2), 6)
+
+    # Test handling of long*seq and seq*long
+    class L(long):
+        pass
+    vereq("a"*L(2L), "aa")
+    vereq(L(2L)*"a", "aa")
+    vereq(2*L(3), 6)
+    vereq(L(3)*2, 6)
+    vereq(L(3)*L(2), 6)
+
+    # Test comparison of classes with dynamic metaclasses
+    class dynamicmetaclass(type):
+        pass
+    class someclass:
+        __metaclass__ = dynamicmetaclass
+    verify(someclass != object)
+
+def errors():
+    if verbose: print "Testing errors..."
+
+    try:
+        class C(list, dict):
+            pass
+    except TypeError:
+        pass
+    else:
+        verify(0, "inheritance from both list and dict should be illegal")
+
+    try:
+        class C(object, None):
+            pass
+    except TypeError:
+        pass
+    else:
+        verify(0, "inheritance from non-type should be illegal")
+    class Classic:
+        pass
+
+    try:
+        class C(type(len)):
+            pass
+    except TypeError:
+        pass
+    else:
+        verify(0, "inheritance from CFunction should be illegal")
+
+    try:
+        class C(object):
+            __slots__ = 1
+    except TypeError:
+        pass
+    else:
+        verify(0, "__slots__ = 1 should be illegal")
+
+    try:
+        class C(object):
+            __slots__ = [1]
+    except TypeError:
+        pass
+    else:
+        verify(0, "__slots__ = [1] should be illegal")
+
+def classmethods():
+    if verbose: print "Testing class methods..."
+    class C(object):
+        def foo(*a): return a
+        goo = classmethod(foo)
+    c = C()
+    vereq(C.goo(1), (C, 1))
+    vereq(c.goo(1), (C, 1))
+    vereq(c.foo(1), (c, 1))
+    class D(C):
+        pass
+    d = D()
+    vereq(D.goo(1), (D, 1))
+    vereq(d.goo(1), (D, 1))
+    vereq(d.foo(1), (d, 1))
+    vereq(D.foo(d, 1), (d, 1))
+    # Test for a specific crash (SF bug 528132)
+    def f(cls, arg): return (cls, arg)
+    ff = classmethod(f)
+    vereq(ff.__get__(0, int)(42), (int, 42))
+    vereq(ff.__get__(0)(42), (int, 42))
+
+    # Test super() with classmethods (SF bug 535444)
+    veris(C.goo.im_self, C)
+    veris(D.goo.im_self, D)
+    veris(super(D,D).goo.im_self, D)
+    veris(super(D,d).goo.im_self, D)
+    vereq(super(D,D).goo(), (D,))
+    vereq(super(D,d).goo(), (D,))
+
+    # Verify that argument is checked for callability (SF bug 753451)
+    try:
+        classmethod(1).__get__(1)
+    except TypeError:
+        pass
+    else:
+        raise TestFailed, "classmethod should check for callability"
+
+    # Verify that classmethod() doesn't allow keyword args
+    try:
+        classmethod(f, kw=1)
+    except TypeError:
+        pass
+    else:
+        raise TestFailed, "classmethod shouldn't accept keyword args"
+
+def classmethods_in_c():
+    if verbose: print "Testing C-based class methods..."
+    import xxsubtype as spam
+    a = (1, 2, 3)
+    d = {'abc': 123}
+    x, a1, d1 = spam.spamlist.classmeth(*a, **d)
+    veris(x, spam.spamlist)
+    vereq(a, a1)
+    vereq(d, d1)
+    x, a1, d1 = spam.spamlist().classmeth(*a, **d)
+    veris(x, spam.spamlist)
+    vereq(a, a1)
+    vereq(d, d1)
+
+def staticmethods():
+    if verbose: print "Testing static methods..."
+    class C(object):
+        def foo(*a): return a
+        goo = staticmethod(foo)
+    c = C()
+    vereq(C.goo(1), (1,))
+    vereq(c.goo(1), (1,))
+    vereq(c.foo(1), (c, 1,))
+    class D(C):
+        pass
+    d = D()
+    vereq(D.goo(1), (1,))
+    vereq(d.goo(1), (1,))
+    vereq(d.foo(1), (d, 1))
+    vereq(D.foo(d, 1), (d, 1))
+
+def staticmethods_in_c():
+    if verbose: print "Testing C-based static methods..."
+    import xxsubtype as spam
+    a = (1, 2, 3)
+    d = {"abc": 123}
+    x, a1, d1 = spam.spamlist.staticmeth(*a, **d)
+    veris(x, None)
+    vereq(a, a1)
+    vereq(d, d1)
+    x, a1, d2 = spam.spamlist().staticmeth(*a, **d)
+    veris(x, None)
+    vereq(a, a1)
+    vereq(d, d1)
+
+def classic():
+    if verbose: print "Testing classic classes..."
+    class C:
+        def foo(*a): return a
+        goo = classmethod(foo)
+    c = C()
+    vereq(C.goo(1), (C, 1))
+    vereq(c.goo(1), (C, 1))
+    vereq(c.foo(1), (c, 1))
+    class D(C):
+        pass
+    d = D()
+    vereq(D.goo(1), (D, 1))
+    vereq(d.goo(1), (D, 1))
+    vereq(d.foo(1), (d, 1))
+    vereq(D.foo(d, 1), (d, 1))
+    class E: # *not* subclassing from C
+        foo = C.foo
+    vereq(E().foo, C.foo) # i.e., unbound
+    verify(repr(C.foo.__get__(C())).startswith("<bound method "))
+
+def compattr():
+    if verbose: print "Testing computed attributes..."
+    class C(object):
+        class computed_attribute(object):
+            def __init__(self, get, set=None, delete=None):
+                self.__get = get
+                self.__set = set
+                self.__delete = delete
+            def __get__(self, obj, type=None):
+                return self.__get(obj)
+            def __set__(self, obj, value):
+                return self.__set(obj, value)
+            def __delete__(self, obj):
+                return self.__delete(obj)
+        def __init__(self):
+            self.__x = 0
+        def __get_x(self):
+            x = self.__x
+            self.__x = x+1
+            return x
+        def __set_x(self, x):
+            self.__x = x
+        def __delete_x(self):
+            del self.__x
+        x = computed_attribute(__get_x, __set_x, __delete_x)
+    a = C()
+    vereq(a.x, 0)
+    vereq(a.x, 1)
+    a.x = 10
+    vereq(a.x, 10)
+    vereq(a.x, 11)
+    del a.x
+    vereq(hasattr(a, 'x'), 0)
+
+def newslot():
+    if verbose: print "Testing __new__ slot override..."
+    class C(list):
+        def __new__(cls):
+            self = list.__new__(cls)
+            self.foo = 1
+            return self
+        def __init__(self):
+            self.foo = self.foo + 2
+    a = C()
+    vereq(a.foo, 3)
+    verify(a.__class__ is C)
+    class D(C):
+        pass
+    b = D()
+    vereq(b.foo, 3)
+    verify(b.__class__ is D)
+
+def altmro():
+    if verbose: print "Testing mro() and overriding it..."
+    class A(object):
+        def f(self): return "A"
+    class B(A):
+        pass
+    class C(A):
+        def f(self): return "C"
+    class D(B, C):
+        pass
+    vereq(D.mro(), [D, B, C, A, object])
+    vereq(D.__mro__, (D, B, C, A, object))
+    vereq(D().f(), "C")
+
+    class PerverseMetaType(type):
+        def mro(cls):
+            L = type.mro(cls)
+            L.reverse()
+            return L
+    class X(D,B,C,A):
+        __metaclass__ = PerverseMetaType
+    vereq(X.__mro__, (object, A, C, B, D, X))
+    vereq(X().f(), "A")
+
+    try:
+        class X(object):
+            class __metaclass__(type):
+                def mro(self):
+                    return [self, dict, object]
+    except TypeError:
+        pass
+    else:
+        raise TestFailed, "devious mro() return not caught"
+
+    try:
+        class X(object):
+            class __metaclass__(type):
+                def mro(self):
+                    return [1]
+    except TypeError:
+        pass
+    else:
+        raise TestFailed, "non-class mro() return not caught"
+
+    try:
+        class X(object):
+            class __metaclass__(type):
+                def mro(self):
+                    return 1
+    except TypeError:
+        pass
+    else:
+        raise TestFailed, "non-sequence mro() return not caught"
+
+
+def overloading():
+    if verbose: print "Testing operator overloading..."
+
+    class B(object):
+        "Intermediate class because object doesn't have a __setattr__"
+
+    class C(B):
+
+        def __getattr__(self, name):
+            if name == "foo":
+                return ("getattr", name)
+            else:
+                raise AttributeError
+        def __setattr__(self, name, value):
+            if name == "foo":
+                self.setattr = (name, value)
+            else:
+                return B.__setattr__(self, name, value)
+        def __delattr__(self, name):
+            if name == "foo":
+                self.delattr = name
+            else:
+                return B.__delattr__(self, name)
+
+        def __getitem__(self, key):
+            return ("getitem", key)
+        def __setitem__(self, key, value):
+            self.setitem = (key, value)
+        def __delitem__(self, key):
+            self.delitem = key
+
+        def __getslice__(self, i, j):
+            return ("getslice", i, j)
+        def __setslice__(self, i, j, value):
+            self.setslice = (i, j, value)
+        def __delslice__(self, i, j):
+            self.delslice = (i, j)
+
+    a = C()
+    vereq(a.foo, ("getattr", "foo"))
+    a.foo = 12
+    vereq(a.setattr, ("foo", 12))
+    del a.foo
+    vereq(a.delattr, "foo")
+
+    vereq(a[12], ("getitem", 12))
+    a[12] = 21
+    vereq(a.setitem, (12, 21))
+    del a[12]
+    vereq(a.delitem, 12)
+
+    vereq(a[0:10], ("getslice", 0, 10))
+    a[0:10] = "foo"
+    vereq(a.setslice, (0, 10, "foo"))
+    del a[0:10]
+    vereq(a.delslice, (0, 10))
+
+def methods():
+    if verbose: print "Testing methods..."
+    class C(object):
+        def __init__(self, x):
+            self.x = x
+        def foo(self):
+            return self.x
+    c1 = C(1)
+    vereq(c1.foo(), 1)
+    class D(C):
+        boo = C.foo
+        goo = c1.foo
+    d2 = D(2)
+    vereq(d2.foo(), 2)
+    vereq(d2.boo(), 2)
+    vereq(d2.goo(), 1)
+    class E(object):
+        foo = C.foo
+    vereq(E().foo, C.foo) # i.e., unbound
+    verify(repr(C.foo.__get__(C(1))).startswith("<bound method "))
+
+def specials():
+    # Test operators like __hash__ for which a built-in default exists
+    if verbose: print "Testing special operators..."
+    # Test the default behavior for static classes
+    class C(object):
+        def __getitem__(self, i):
+            if 0 <= i < 10: return i
+            raise IndexError
+    c1 = C()
+    c2 = C()
+    verify(not not c1)
+    verify(id(c1) != id(c2))
+    hash(c1)
+    hash(c2)
+    vereq(cmp(c1, c2), cmp(id(c1), id(c2)))
+    vereq(c1, c1)
+    verify(c1 != c2)
+    verify(not c1 != c1)
+    verify(not c1 == c2)
+    # Note that the module name appears in str/repr, and that varies
+    # depending on whether this test is run standalone or from a framework.
+    verify(str(c1).find('C object at ') >= 0)
+    vereq(str(c1), repr(c1))
+    verify(-1 not in c1)
+    for i in range(10):
+        verify(i in c1)
+    verify(10 not in c1)
+    # Test the default behavior for dynamic classes
+    class D(object):
+        def __getitem__(self, i):
+            if 0 <= i < 10: return i
+            raise IndexError
+    d1 = D()
+    d2 = D()
+    verify(not not d1)
+    verify(id(d1) != id(d2))
+    hash(d1)
+    hash(d2)
+    vereq(cmp(d1, d2), cmp(id(d1), id(d2)))
+    vereq(d1, d1)
+    verify(d1 != d2)
+    verify(not d1 != d1)
+    verify(not d1 == d2)
+    # Note that the module name appears in str/repr, and that varies
+    # depending on whether this test is run standalone or from a framework.
+    verify(str(d1).find('D object at ') >= 0)
+    vereq(str(d1), repr(d1))
+    verify(-1 not in d1)
+    for i in range(10):
+        verify(i in d1)
+    verify(10 not in d1)
+    # Test overridden behavior for static classes
+    class Proxy(object):
+        def __init__(self, x):
+            self.x = x
+        def __nonzero__(self):
+            return not not self.x
+        def __hash__(self):
+            return hash(self.x)
+        def __eq__(self, other):
+            return self.x == other
+        def __ne__(self, other):
+            return self.x != other
+        def __cmp__(self, other):
+            return cmp(self.x, other.x)
+        def __str__(self):
+            return "Proxy:%s" % self.x
+        def __repr__(self):
+            return "Proxy(%r)" % self.x
+        def __contains__(self, value):
+            return value in self.x
+    p0 = Proxy(0)
+    p1 = Proxy(1)
+    p_1 = Proxy(-1)
+    verify(not p0)
+    verify(not not p1)
+    vereq(hash(p0), hash(0))
+    vereq(p0, p0)
+    verify(p0 != p1)
+    verify(not p0 != p0)
+    vereq(not p0, p1)
+    vereq(cmp(p0, p1), -1)
+    vereq(cmp(p0, p0), 0)
+    vereq(cmp(p0, p_1), 1)
+    vereq(str(p0), "Proxy:0")
+    vereq(repr(p0), "Proxy(0)")
+    p10 = Proxy(range(10))
+    verify(-1 not in p10)
+    for i in range(10):
+        verify(i in p10)
+    verify(10 not in p10)
+    # Test overridden behavior for dynamic classes
+    class DProxy(object):
+        def __init__(self, x):
+            self.x = x
+        def __nonzero__(self):
+            return not not self.x
+        def __hash__(self):
+            return hash(self.x)
+        def __eq__(self, other):
+            return self.x == other
+        def __ne__(self, other):
+            return self.x != other
+        def __cmp__(self, other):
+            return cmp(self.x, other.x)
+        def __str__(self):
+            return "DProxy:%s" % self.x
+        def __repr__(self):
+            return "DProxy(%r)" % self.x
+        def __contains__(self, value):
+            return value in self.x
+    p0 = DProxy(0)
+    p1 = DProxy(1)
+    p_1 = DProxy(-1)
+    verify(not p0)
+    verify(not not p1)
+    vereq(hash(p0), hash(0))
+    vereq(p0, p0)
+    verify(p0 != p1)
+    verify(not p0 != p0)
+    vereq(not p0, p1)
+    vereq(cmp(p0, p1), -1)
+    vereq(cmp(p0, p0), 0)
+    vereq(cmp(p0, p_1), 1)
+    vereq(str(p0), "DProxy:0")
+    vereq(repr(p0), "DProxy(0)")
+    p10 = DProxy(range(10))
+    verify(-1 not in p10)
+    for i in range(10):
+        verify(i in p10)
+    verify(10 not in p10)
+    # Safety test for __cmp__
+    def unsafecmp(a, b):
+        try:
+            a.__class__.__cmp__(a, b)
+        except TypeError:
+            pass
+        else:
+            raise TestFailed, "shouldn't allow %s.__cmp__(%r, %r)" % (
+                a.__class__, a, b)
+    unsafecmp(u"123", "123")
+    unsafecmp("123", u"123")
+    unsafecmp(1, 1.0)
+    unsafecmp(1.0, 1)
+    unsafecmp(1, 1L)
+    unsafecmp(1L, 1)
+
+    class Letter(str):
+        def __new__(cls, letter):
+            if letter == 'EPS':
+                return str.__new__(cls)
+            return str.__new__(cls, letter)
+        def __str__(self):
+            if not self:
+                return 'EPS'
+            return self
+
+    # sys.stdout needs to be the original to trigger the recursion bug
+    import sys
+    test_stdout = sys.stdout
+    sys.stdout = get_original_stdout()
+    try:
+        # nothing should actually be printed, this should raise an exception
+        print Letter('w')
+    except RuntimeError:
+        pass
+    else:
+        raise TestFailed, "expected a RuntimeError for print recursion"
+    sys.stdout = test_stdout
+
+def weakrefs():
+    if verbose: print "Testing weak references..."
+    import weakref
+    class C(object):
+        pass
+    c = C()
+    r = weakref.ref(c)
+    verify(r() is c)
+    del c
+    verify(r() is None)
+    del r
+    class NoWeak(object):
+        __slots__ = ['foo']
+    no = NoWeak()
+    try:
+        weakref.ref(no)
+    except TypeError, msg:
+        verify(str(msg).find("weak reference") >= 0)
+    else:
+        verify(0, "weakref.ref(no) should be illegal")
+    class Weak(object):
+        __slots__ = ['foo', '__weakref__']
+    yes = Weak()
+    r = weakref.ref(yes)
+    verify(r() is yes)
+    del yes
+    verify(r() is None)
+    del r
+
+def properties():
+    if verbose: print "Testing property..."
+    class C(object):
+        def getx(self):
+            return self.__x
+        def setx(self, value):
+            self.__x = value
+        def delx(self):
+            del self.__x
+        x = property(getx, setx, delx, doc="I'm the x property.")
+    a = C()
+    verify(not hasattr(a, "x"))
+    a.x = 42
+    vereq(a._C__x, 42)
+    vereq(a.x, 42)
+    del a.x
+    verify(not hasattr(a, "x"))
+    verify(not hasattr(a, "_C__x"))
+    C.x.__set__(a, 100)
+    vereq(C.x.__get__(a), 100)
+    C.x.__delete__(a)
+    verify(not hasattr(a, "x"))
+
+    raw = C.__dict__['x']
+    verify(isinstance(raw, property))
+
+    attrs = dir(raw)
+    verify("__doc__" in attrs)
+    verify("fget" in attrs)
+    verify("fset" in attrs)
+    verify("fdel" in attrs)
+
+    vereq(raw.__doc__, "I'm the x property.")
+    verify(raw.fget is C.__dict__['getx'])
+    verify(raw.fset is C.__dict__['setx'])
+    verify(raw.fdel is C.__dict__['delx'])
+
+    for attr in "__doc__", "fget", "fset", "fdel":
+        try:
+            setattr(raw, attr, 42)
+        except TypeError, msg:
+            if str(msg).find('readonly') < 0:
+                raise TestFailed("when setting readonly attr %r on a "
+                                 "property, got unexpected TypeError "
+                                 "msg %r" % (attr, str(msg)))
+        else:
+            raise TestFailed("expected TypeError from trying to set "
+                             "readonly %r attr on a property" % attr)
+
+    class D(object):
+        __getitem__ = property(lambda s: 1/0)
+
+    d = D()
+    try:
+        for i in d:
+            str(i)
+    except ZeroDivisionError:
+        pass
+    else:
+        raise TestFailed, "expected ZeroDivisionError from bad property"
+
+    class E(object):
+        def getter(self):
+            "getter method"
+            return 0
+        def setter(self, value):
+            "setter method"
+            pass
+        prop = property(getter)
+        vereq(prop.__doc__, "getter method")
+        prop2 = property(fset=setter)
+        vereq(prop2.__doc__, None)
+
+    # this segfaulted in 2.5b2
+    try:
+        import _testcapi
+    except ImportError:
+        pass
+    else:
+        class X(object):
+            p = property(_testcapi.test_with_docstring)
+
+
+def supers():
+    if verbose: print "Testing super..."
+
+    class A(object):
+        def meth(self, a):
+            return "A(%r)" % a
+
+    vereq(A().meth(1), "A(1)")
+
+    class B(A):
+        def __init__(self):
+            self.__super = super(B, self)
+        def meth(self, a):
+            return "B(%r)" % a + self.__super.meth(a)
+
+    vereq(B().meth(2), "B(2)A(2)")
+
+    class C(A):
+        def meth(self, a):
+            return "C(%r)" % a + self.__super.meth(a)
+    C._C__super = super(C)
+
+    vereq(C().meth(3), "C(3)A(3)")
+
+    class D(C, B):
+        def meth(self, a):
+            return "D(%r)" % a + super(D, self).meth(a)
+
+    vereq(D().meth(4), "D(4)C(4)B(4)A(4)")
+
+    # Test for subclassing super
+
+    class mysuper(super):
+        def __init__(self, *args):
+            return super(mysuper, self).__init__(*args)
+
+    class E(D):
+        def meth(self, a):
+            return "E(%r)" % a + mysuper(E, self).meth(a)
+
+    vereq(E().meth(5), "E(5)D(5)C(5)B(5)A(5)")
+
+    class F(E):
+        def meth(self, a):
+            s = self.__super # == mysuper(F, self)
+            return "F(%r)[%s]" % (a, s.__class__.__name__) + s.meth(a)
+    F._F__super = mysuper(F)
+
+    vereq(F().meth(6), "F(6)[mysuper]E(6)D(6)C(6)B(6)A(6)")
+
+    # Make sure certain errors are raised
+
+    try:
+        super(D, 42)
+    except TypeError:
+        pass
+    else:
+        raise TestFailed, "shouldn't allow super(D, 42)"
+
+    try:
+        super(D, C())
+    except TypeError:
+        pass
+    else:
+        raise TestFailed, "shouldn't allow super(D, C())"
+
+    try:
+        super(D).__get__(12)
+    except TypeError:
+        pass
+    else:
+        raise TestFailed, "shouldn't allow super(D).__get__(12)"
+
+    try:
+        super(D).__get__(C())
+    except TypeError:
+        pass
+    else:
+        raise TestFailed, "shouldn't allow super(D).__get__(C())"
+
+    # Make sure data descriptors can be overridden and accessed via super
+    # (new feature in Python 2.3)
+
+    class DDbase(object):
+        def getx(self): return 42
+        x = property(getx)
+
+    class DDsub(DDbase):
+        def getx(self): return "hello"
+        x = property(getx)
+
+    dd = DDsub()
+    vereq(dd.x, "hello")
+    vereq(super(DDsub, dd).x, 42)
+
+    # Ensure that super() lookup of descriptor from classmethod
+    # works (SF ID# 743627)
+
+    class Base(object):
+        aProp = property(lambda self: "foo")
+
+    class Sub(Base):
+        @classmethod
+        def test(klass):
+            return super(Sub,klass).aProp
+
+    veris(Sub.test(), Base.aProp)
+
+    # Verify that super() doesn't allow keyword args
+    try:
+        super(Base, kw=1)
+    except TypeError:
+        pass
+    else:
+        raise TestFailed, "super shouldn't accept keyword args"
+
+def inherits():
+    if verbose: print "Testing inheritance from basic types..."
+
+    class hexint(int):
+        def __repr__(self):
+            return hex(self)
+        def __add__(self, other):
+            return hexint(int.__add__(self, other))
+        # (Note that overriding __radd__ doesn't work,
+        # because the int type gets first dibs.)
+    vereq(repr(hexint(7) + 9), "0x10")
+    vereq(repr(hexint(1000) + 7), "0x3ef")
+    a = hexint(12345)
+    vereq(a, 12345)
+    vereq(int(a), 12345)
+    verify(int(a).__class__ is int)
+    vereq(hash(a), hash(12345))
+    verify((+a).__class__ is int)
+    verify((a >> 0).__class__ is int)
+    verify((a << 0).__class__ is int)
+    verify((hexint(0) << 12).__class__ is int)
+    verify((hexint(0) >> 12).__class__ is int)
+
+    class octlong(long):
+        __slots__ = []
+        def __str__(self):
+            s = oct(self)
+            if s[-1] == 'L':
+                s = s[:-1]
+            return s
+        def __add__(self, other):
+            return self.__class__(super(octlong, self).__add__(other))
+        __radd__ = __add__
+    vereq(str(octlong(3) + 5), "010")
+    # (Note that overriding __radd__ here only seems to work
+    # because the example uses a short int left argument.)
+    vereq(str(5 + octlong(3000)), "05675")
+    a = octlong(12345)
+    vereq(a, 12345L)
+    vereq(long(a), 12345L)
+    vereq(hash(a), hash(12345L))
+    verify(long(a).__class__ is long)
+    verify((+a).__class__ is long)
+    verify((-a).__class__ is long)
+    verify((-octlong(0)).__class__ is long)
+    verify((a >> 0).__class__ is long)
+    verify((a << 0).__class__ is long)
+    verify((a - 0).__class__ is long)
+    verify((a * 1).__class__ is long)
+    verify((a ** 1).__class__ is long)
+    verify((a // 1).__class__ is long)
+    verify((1 * a).__class__ is long)
+    verify((a | 0).__class__ is long)
+    verify((a ^ 0).__class__ is long)
+    verify((a & -1L).__class__ is long)
+    verify((octlong(0) << 12).__class__ is long)
+    verify((octlong(0) >> 12).__class__ is long)
+    verify(abs(octlong(0)).__class__ is long)
+
+    # Because octlong overrides __add__, we can't check the absence of +0
+    # optimizations using octlong.
+    class longclone(long):
+        pass
+    a = longclone(1)
+    verify((a + 0).__class__ is long)
+    verify((0 + a).__class__ is long)
+
+    # Check that negative clones don't segfault
+    a = longclone(-1)
+    vereq(a.__dict__, {})
+    vereq(long(a), -1)  # verify PyNumber_Long() copies the sign bit
+
+    class precfloat(float):
+        __slots__ = ['prec']
+        def __init__(self, value=0.0, prec=12):
+            self.prec = int(prec)
+            float.__init__(value)
+        def __repr__(self):
+            return "%.*g" % (self.prec, self)
+    vereq(repr(precfloat(1.1)), "1.1")
+    a = precfloat(12345)
+    vereq(a, 12345.0)
+    vereq(float(a), 12345.0)
+    verify(float(a).__class__ is float)
+    vereq(hash(a), hash(12345.0))
+    verify((+a).__class__ is float)
+
+    class madcomplex(complex):
+        def __repr__(self):
+            return "%.17gj%+.17g" % (self.imag, self.real)
+    a = madcomplex(-3, 4)
+    vereq(repr(a), "4j-3")
+    base = complex(-3, 4)
+    veris(base.__class__, complex)
+    vereq(a, base)
+    vereq(complex(a), base)
+    veris(complex(a).__class__, complex)
+    a = madcomplex(a)  # just trying another form of the constructor
+    vereq(repr(a), "4j-3")
+    vereq(a, base)
+    vereq(complex(a), base)
+    veris(complex(a).__class__, complex)
+    vereq(hash(a), hash(base))
+    veris((+a).__class__, complex)
+    veris((a + 0).__class__, complex)
+    vereq(a + 0, base)
+    veris((a - 0).__class__, complex)
+    vereq(a - 0, base)
+    veris((a * 1).__class__, complex)
+    vereq(a * 1, base)
+    veris((a / 1).__class__, complex)
+    vereq(a / 1, base)
+
+    class madtuple(tuple):
+        _rev = None
+        def rev(self):
+            if self._rev is not None:
+                return self._rev
+            L = list(self)
+            L.reverse()
+            self._rev = self.__class__(L)
+            return self._rev
+    a = madtuple((1,2,3,4,5,6,7,8,9,0))
+    vereq(a, (1,2,3,4,5,6,7,8,9,0))
+    vereq(a.rev(), madtuple((0,9,8,7,6,5,4,3,2,1)))
+    vereq(a.rev().rev(), madtuple((1,2,3,4,5,6,7,8,9,0)))
+    for i in range(512):
+        t = madtuple(range(i))
+        u = t.rev()
+        v = u.rev()
+        vereq(v, t)
+    a = madtuple((1,2,3,4,5))
+    vereq(tuple(a), (1,2,3,4,5))
+    verify(tuple(a).__class__ is tuple)
+    vereq(hash(a), hash((1,2,3,4,5)))
+    verify(a[:].__class__ is tuple)
+    verify((a * 1).__class__ is tuple)
+    verify((a * 0).__class__ is tuple)
+    verify((a + ()).__class__ is tuple)
+    a = madtuple(())
+    vereq(tuple(a), ())
+    verify(tuple(a).__class__ is tuple)
+    verify((a + a).__class__ is tuple)
+    verify((a * 0).__class__ is tuple)
+    verify((a * 1).__class__ is tuple)
+    verify((a * 2).__class__ is tuple)
+    verify(a[:].__class__ is tuple)
+
+    class madstring(str):
+        _rev = None
+        def rev(self):
+            if self._rev is not None:
+                return self._rev
+            L = list(self)
+            L.reverse()
+            self._rev = self.__class__("".join(L))
+            return self._rev
+    s = madstring("abcdefghijklmnopqrstuvwxyz")
+    vereq(s, "abcdefghijklmnopqrstuvwxyz")
+    vereq(s.rev(), madstring("zyxwvutsrqponmlkjihgfedcba"))
+    vereq(s.rev().rev(), madstring("abcdefghijklmnopqrstuvwxyz"))
+    for i in range(256):
+        s = madstring("".join(map(chr, range(i))))
+        t = s.rev()
+        u = t.rev()
+        vereq(u, s)
+    s = madstring("12345")
+    vereq(str(s), "12345")
+    verify(str(s).__class__ is str)
+
+    base = "\x00" * 5
+    s = madstring(base)
+    vereq(s, base)
+    vereq(str(s), base)
+    verify(str(s).__class__ is str)
+    vereq(hash(s), hash(base))
+    vereq({s: 1}[base], 1)
+    vereq({base: 1}[s], 1)
+    verify((s + "").__class__ is str)
+    vereq(s + "", base)
+    verify(("" + s).__class__ is str)
+    vereq("" + s, base)
+    verify((s * 0).__class__ is str)
+    vereq(s * 0, "")
+    verify((s * 1).__class__ is str)
+    vereq(s * 1, base)
+    verify((s * 2).__class__ is str)
+    vereq(s * 2, base + base)
+    verify(s[:].__class__ is str)
+    vereq(s[:], base)
+    verify(s[0:0].__class__ is str)
+    vereq(s[0:0], "")
+    verify(s.strip().__class__ is str)
+    vereq(s.strip(), base)
+    verify(s.lstrip().__class__ is str)
+    vereq(s.lstrip(), base)
+    verify(s.rstrip().__class__ is str)
+    vereq(s.rstrip(), base)
+    identitytab = ''.join([chr(i) for i in range(256)])
+    verify(s.translate(identitytab).__class__ is str)
+    vereq(s.translate(identitytab), base)
+    verify(s.translate(identitytab, "x").__class__ is str)
+    vereq(s.translate(identitytab, "x"), base)
+    vereq(s.translate(identitytab, "\x00"), "")
+    verify(s.replace("x", "x").__class__ is str)
+    vereq(s.replace("x", "x"), base)
+    verify(s.ljust(len(s)).__class__ is str)
+    vereq(s.ljust(len(s)), base)
+    verify(s.rjust(len(s)).__class__ is str)
+    vereq(s.rjust(len(s)), base)
+    verify(s.center(len(s)).__class__ is str)
+    vereq(s.center(len(s)), base)
+    verify(s.lower().__class__ is str)
+    vereq(s.lower(), base)
+
+    class madunicode(unicode):
+        _rev = None
+        def rev(self):
+            if self._rev is not None:
+                return self._rev
+            L = list(self)
+            L.reverse()
+            self._rev = self.__class__(u"".join(L))
+            return self._rev
+    u = madunicode("ABCDEF")
+    vereq(u, u"ABCDEF")
+    vereq(u.rev(), madunicode(u"FEDCBA"))
+    vereq(u.rev().rev(), madunicode(u"ABCDEF"))
+    base = u"12345"
+    u = madunicode(base)
+    vereq(unicode(u), base)
+    verify(unicode(u).__class__ is unicode)
+    vereq(hash(u), hash(base))
+    vereq({u: 1}[base], 1)
+    vereq({base: 1}[u], 1)
+    verify(u.strip().__class__ is unicode)
+    vereq(u.strip(), base)
+    verify(u.lstrip().__class__ is unicode)
+    vereq(u.lstrip(), base)
+    verify(u.rstrip().__class__ is unicode)
+    vereq(u.rstrip(), base)
+    verify(u.replace(u"x", u"x").__class__ is unicode)
+    vereq(u.replace(u"x", u"x"), base)
+    verify(u.replace(u"xy", u"xy").__class__ is unicode)
+    vereq(u.replace(u"xy", u"xy"), base)
+    verify(u.center(len(u)).__class__ is unicode)
+    vereq(u.center(len(u)), base)
+    verify(u.ljust(len(u)).__class__ is unicode)
+    vereq(u.ljust(len(u)), base)
+    verify(u.rjust(len(u)).__class__ is unicode)
+    vereq(u.rjust(len(u)), base)
+    verify(u.lower().__class__ is unicode)
+    vereq(u.lower(), base)
+    verify(u.upper().__class__ is unicode)
+    vereq(u.upper(), base)
+    verify(u.capitalize().__class__ is unicode)
+    vereq(u.capitalize(), base)
+    verify(u.title().__class__ is unicode)
+    vereq(u.title(), base)
+    verify((u + u"").__class__ is unicode)
+    vereq(u + u"", base)
+    verify((u"" + u).__class__ is unicode)
+    vereq(u"" + u, base)
+    verify((u * 0).__class__ is unicode)
+    vereq(u * 0, u"")
+    verify((u * 1).__class__ is unicode)
+    vereq(u * 1, base)
+    verify((u * 2).__class__ is unicode)
+    vereq(u * 2, base + base)
+    verify(u[:].__class__ is unicode)
+    vereq(u[:], base)
+    verify(u[0:0].__class__ is unicode)
+    vereq(u[0:0], u"")
+
+    class sublist(list):
+        pass
+    a = sublist(range(5))
+    vereq(a, range(5))
+    a.append("hello")
+    vereq(a, range(5) + ["hello"])
+    a[5] = 5
+    vereq(a, range(6))
+    a.extend(range(6, 20))
+    vereq(a, range(20))
+    a[-5:] = []
+    vereq(a, range(15))
+    del a[10:15]
+    vereq(len(a), 10)
+    vereq(a, range(10))
+    vereq(list(a), range(10))
+    vereq(a[0], 0)
+    vereq(a[9], 9)
+    vereq(a[-10], 0)
+    vereq(a[-1], 9)
+    vereq(a[:5], range(5))
+
+    class CountedInput(file):
+        """Counts lines read by self.readline().
+
+        self.lineno is the 0-based ordinal of the last line read, up to
+        a maximum of one greater than the number of lines in the file.
+
+        self.ateof is true if and only if the final "" line has been read,
+        at which point self.lineno stops incrementing, and further calls
+        to readline() continue to return "".
+        """
+
+        lineno = 0
+        ateof = 0
+        def readline(self):
+            if self.ateof:
+                return ""
+            s = file.readline(self)
+            # Next line works too.
+            # s = super(CountedInput, self).readline()
+            self.lineno += 1
+            if s == "":
+                self.ateof = 1
+            return s
+
+    f = file(name=TESTFN, mode='w')
+    lines = ['a\n', 'b\n', 'c\n']
+    try:
+        f.writelines(lines)
+        f.close()
+        f = CountedInput(TESTFN)
+        for (i, expected) in zip(range(1, 5) + [4], lines + 2 * [""]):
+            got = f.readline()
+            vereq(expected, got)
+            vereq(f.lineno, i)
+            vereq(f.ateof, (i > len(lines)))
+        f.close()
+    finally:
+        try:
+            f.close()
+        except:
+            pass
+        try:
+            import os
+            os.unlink(TESTFN)
+        except:
+            pass
+
+def keywords():
+    if verbose:
+        print "Testing keyword args to basic type constructors ..."
+    vereq(int(x=1), 1)
+    vereq(float(x=2), 2.0)
+    vereq(long(x=3), 3L)
+    vereq(complex(imag=42, real=666), complex(666, 42))
+    vereq(str(object=500), '500')
+    vereq(unicode(string='abc', errors='strict'), u'abc')
+    vereq(tuple(sequence=range(3)), (0, 1, 2))
+    vereq(list(sequence=(0, 1, 2)), range(3))
+    # note: as of Python 2.3, dict() no longer has an "items" keyword arg
+
+    for constructor in (int, float, long, complex, str, unicode,
+                        tuple, list, file):
+        try:
+            constructor(bogus_keyword_arg=1)
+        except TypeError:
+            pass
+        else:
+            raise TestFailed("expected TypeError from bogus keyword "
+                             "argument to %r" % constructor)
+
+def restricted():
+    # XXX This test is disabled because rexec is not deemed safe
+    return
+    import rexec
+    if verbose:
+        print "Testing interaction with restricted execution ..."
+
+    sandbox = rexec.RExec()
+
+    code1 = """f = open(%r, 'w')""" % TESTFN
+    code2 = """f = file(%r, 'w')""" % TESTFN
+    code3 = """\
+f = open(%r)
+t = type(f)  # a sneaky way to get the file() constructor
+f.close()
+f = t(%r, 'w')  # rexec can't catch this by itself
+""" % (TESTFN, TESTFN)
+
+    f = open(TESTFN, 'w')  # Create the file so code3 can find it.
+    f.close()
+
+    try:
+        for code in code1, code2, code3:
+            try:
+                sandbox.r_exec(code)
+            except IOError, msg:
+                if str(msg).find("restricted") >= 0:
+                    outcome = "OK"
+                else:
+                    outcome = "got an exception, but not an expected one"
+            else:
+                outcome = "expected a restricted-execution exception"
+
+            if outcome != "OK":
+                raise TestFailed("%s, in %r" % (outcome, code))
+
+    finally:
+        try:
+            import os
+            os.unlink(TESTFN)
+        except:
+            pass
+
+def str_subclass_as_dict_key():
+    if verbose:
+        print "Testing a str subclass used as dict key .."
+
+    class cistr(str):
+        """Sublcass of str that computes __eq__ case-insensitively.
+
+        Also computes a hash code of the string in canonical form.
+        """
+
+        def __init__(self, value):
+            self.canonical = value.lower()
+            self.hashcode = hash(self.canonical)
+
+        def __eq__(self, other):
+            if not isinstance(other, cistr):
+                other = cistr(other)
+            return self.canonical == other.canonical
+
+        def __hash__(self):
+            return self.hashcode
+
+    vereq(cistr('ABC'), 'abc')
+    vereq('aBc', cistr('ABC'))
+    vereq(str(cistr('ABC')), 'ABC')
+
+    d = {cistr('one'): 1, cistr('two'): 2, cistr('tHree'): 3}
+    vereq(d[cistr('one')], 1)
+    vereq(d[cistr('tWo')], 2)
+    vereq(d[cistr('THrEE')], 3)
+    verify(cistr('ONe') in d)
+    vereq(d.get(cistr('thrEE')), 3)
+
+def classic_comparisons():
+    if verbose: print "Testing classic comparisons..."
+    class classic:
+        pass
+    for base in (classic, int, object):
+        if verbose: print "        (base = %s)" % base
+        class C(base):
+            def __init__(self, value):
+                self.value = int(value)
+            def __cmp__(self, other):
+                if isinstance(other, C):
+                    return cmp(self.value, other.value)
+                if isinstance(other, int) or isinstance(other, long):
+                    return cmp(self.value, other)
+                return NotImplemented
+        c1 = C(1)
+        c2 = C(2)
+        c3 = C(3)
+        vereq(c1, 1)
+        c = {1: c1, 2: c2, 3: c3}
+        for x in 1, 2, 3:
+            for y in 1, 2, 3:
+                verify(cmp(c[x], c[y]) == cmp(x, y), "x=%d, y=%d" % (x, y))
+                for op in "<", "<=", "==", "!=", ">", ">=":
+                    verify(eval("c[x] %s c[y]" % op) == eval("x %s y" % op),
+                           "x=%d, y=%d" % (x, y))
+                verify(cmp(c[x], y) == cmp(x, y), "x=%d, y=%d" % (x, y))
+                verify(cmp(x, c[y]) == cmp(x, y), "x=%d, y=%d" % (x, y))
+
+def rich_comparisons():
+    if verbose:
+        print "Testing rich comparisons..."
+    class Z(complex):
+        pass
+    z = Z(1)
+    vereq(z, 1+0j)
+    vereq(1+0j, z)
+    class ZZ(complex):
+        def __eq__(self, other):
+            try:
+                return abs(self - other) <= 1e-6
+            except:
+                return NotImplemented
+    zz = ZZ(1.0000003)
+    vereq(zz, 1+0j)
+    vereq(1+0j, zz)
+
+    class classic:
+        pass
+    for base in (classic, int, object, list):
+        if verbose: print "        (base = %s)" % base
+        class C(base):
+            def __init__(self, value):
+                self.value = int(value)
+            def __cmp__(self, other):
+                raise TestFailed, "shouldn't call __cmp__"
+            def __eq__(self, other):
+                if isinstance(other, C):
+                    return self.value == other.value
+                if isinstance(other, int) or isinstance(other, long):
+                    return self.value == other
+                return NotImplemented
+            def __ne__(self, other):
+                if isinstance(other, C):
+                    return self.value != other.value
+                if isinstance(other, int) or isinstance(other, long):
+                    return self.value != other
+                return NotImplemented
+            def __lt__(self, other):
+                if isinstance(other, C):
+                    return self.value < other.value
+                if isinstance(other, int) or isinstance(other, long):
+                    return self.value < other
+                return NotImplemented
+            def __le__(self, other):
+                if isinstance(other, C):
+                    return self.value <= other.value
+                if isinstance(other, int) or isinstance(other, long):
+                    return self.value <= other
+                return NotImplemented
+            def __gt__(self, other):
+                if isinstance(other, C):
+                    return self.value > other.value
+                if isinstance(other, int) or isinstance(other, long):
+                    return self.value > other
+                return NotImplemented
+            def __ge__(self, other):
+                if isinstance(other, C):
+                    return self.value >= other.value
+                if isinstance(other, int) or isinstance(other, long):
+                    return self.value >= other
+                return NotImplemented
+        c1 = C(1)
+        c2 = C(2)
+        c3 = C(3)
+        vereq(c1, 1)
+        c = {1: c1, 2: c2, 3: c3}
+        for x in 1, 2, 3:
+            for y in 1, 2, 3:
+                for op in "<", "<=", "==", "!=", ">", ">=":
+                    verify(eval("c[x] %s c[y]" % op) == eval("x %s y" % op),
+                           "x=%d, y=%d" % (x, y))
+                    verify(eval("c[x] %s y" % op) == eval("x %s y" % op),
+                           "x=%d, y=%d" % (x, y))
+                    verify(eval("x %s c[y]" % op) == eval("x %s y" % op),
+                           "x=%d, y=%d" % (x, y))
+
+def coercions():
+    if verbose: print "Testing coercions..."
+    class I(int): pass
+    coerce(I(0), 0)
+    coerce(0, I(0))
+    class L(long): pass
+    coerce(L(0), 0)
+    coerce(L(0), 0L)
+    coerce(0, L(0))
+    coerce(0L, L(0))
+    class F(float): pass
+    coerce(F(0), 0)
+    coerce(F(0), 0L)
+    coerce(F(0), 0.)
+    coerce(0, F(0))
+    coerce(0L, F(0))
+    coerce(0., F(0))
+    class C(complex): pass
+    coerce(C(0), 0)
+    coerce(C(0), 0L)
+    coerce(C(0), 0.)
+    coerce(C(0), 0j)
+    coerce(0, C(0))
+    coerce(0L, C(0))
+    coerce(0., C(0))
+    coerce(0j, C(0))
+
+def descrdoc():
+    if verbose: print "Testing descriptor doc strings..."
+    def check(descr, what):
+        vereq(descr.__doc__, what)
+    check(file.closed, "True if the file is closed") # getset descriptor
+    check(file.name, "file name") # member descriptor
+
+def setclass():
+    if verbose: print "Testing __class__ assignment..."
+    class C(object): pass
+    class D(object): pass
+    class E(object): pass
+    class F(D, E): pass
+    for cls in C, D, E, F:
+        for cls2 in C, D, E, F:
+            x = cls()
+            x.__class__ = cls2
+            verify(x.__class__ is cls2)
+            x.__class__ = cls
+            verify(x.__class__ is cls)
+    def cant(x, C):
+        try:
+            x.__class__ = C
+        except TypeError:
+            pass
+        else:
+            raise TestFailed, "shouldn't allow %r.__class__ = %r" % (x, C)
+        try:
+            delattr(x, "__class__")
+        except TypeError:
+            pass
+        else:
+            raise TestFailed, "shouldn't allow del %r.__class__" % x
+    cant(C(), list)
+    cant(list(), C)
+    cant(C(), 1)
+    cant(C(), object)
+    cant(object(), list)
+    cant(list(), object)
+    class Int(int): __slots__ = []
+    cant(2, Int)
+    cant(Int(), int)
+    cant(True, int)
+    cant(2, bool)
+    o = object()
+    cant(o, type(1))
+    cant(o, type(None))
+    del o
+
+def setdict():
+    if verbose: print "Testing __dict__ assignment..."
+    class C(object): pass
+    a = C()
+    a.__dict__ = {'b': 1}
+    vereq(a.b, 1)
+    def cant(x, dict):
+        try:
+            x.__dict__ = dict
+        except (AttributeError, TypeError):
+            pass
+        else:
+            raise TestFailed, "shouldn't allow %r.__dict__ = %r" % (x, dict)
+    cant(a, None)
+    cant(a, [])
+    cant(a, 1)
+    del a.__dict__ # Deleting __dict__ is allowed
+    # Classes don't allow __dict__ assignment
+    cant(C, {})
+
+def pickles():
+    if verbose:
+        print "Testing pickling and copying new-style classes and objects..."
+    import pickle, cPickle
+
+    def sorteditems(d):
+        L = d.items()
+        L.sort()
+        return L
+
+    global C
+    class C(object):
+        def __init__(self, a, b):
+            super(C, self).__init__()
+            self.a = a
+            self.b = b
+        def __repr__(self):
+            return "C(%r, %r)" % (self.a, self.b)
+
+    global C1
+    class C1(list):
+        def __new__(cls, a, b):
+            return super(C1, cls).__new__(cls)
+        def __getnewargs__(self):
+            return (self.a, self.b)
+        def __init__(self, a, b):
+            self.a = a
+            self.b = b
+        def __repr__(self):
+            return "C1(%r, %r)<%r>" % (self.a, self.b, list(self))
+
+    global C2
+    class C2(int):
+        def __new__(cls, a, b, val=0):
+            return super(C2, cls).__new__(cls, val)
+        def __getnewargs__(self):
+            return (self.a, self.b, int(self))
+        def __init__(self, a, b, val=0):
+            self.a = a
+            self.b = b
+        def __repr__(self):
+            return "C2(%r, %r)<%r>" % (self.a, self.b, int(self))
+
+    global C3
+    class C3(object):
+        def __init__(self, foo):
+            self.foo = foo
+        def __getstate__(self):
+            return self.foo
+        def __setstate__(self, foo):
+            self.foo = foo
+
+    global C4classic, C4
+    class C4classic: # classic
+        pass
+    class C4(C4classic, object): # mixed inheritance
+        pass
+
+    for p in pickle, cPickle:
+        for bin in 0, 1:
+            if verbose:
+                print p.__name__, ["text", "binary"][bin]
+
+            for cls in C, C1, C2:
+                s = p.dumps(cls, bin)
+                cls2 = p.loads(s)
+                verify(cls2 is cls)
+
+            a = C1(1, 2); a.append(42); a.append(24)
+            b = C2("hello", "world", 42)
+            s = p.dumps((a, b), bin)
+            x, y = p.loads(s)
+            vereq(x.__class__, a.__class__)
+            vereq(sorteditems(x.__dict__), sorteditems(a.__dict__))
+            vereq(y.__class__, b.__class__)
+            vereq(sorteditems(y.__dict__), sorteditems(b.__dict__))
+            vereq(repr(x), repr(a))
+            vereq(repr(y), repr(b))
+            if verbose:
+                print "a = x =", a
+                print "b = y =", b
+            # Test for __getstate__ and __setstate__ on new style class
+            u = C3(42)
+            s = p.dumps(u, bin)
+            v = p.loads(s)
+            veris(u.__class__, v.__class__)
+            vereq(u.foo, v.foo)
+            # Test for picklability of hybrid class
+            u = C4()
+            u.foo = 42
+            s = p.dumps(u, bin)
+            v = p.loads(s)
+            veris(u.__class__, v.__class__)
+            vereq(u.foo, v.foo)
+
+    # Testing copy.deepcopy()
+    if verbose:
+        print "deepcopy"
+    import copy
+    for cls in C, C1, C2:
+        cls2 = copy.deepcopy(cls)
+        verify(cls2 is cls)
+
+    a = C1(1, 2); a.append(42); a.append(24)
+    b = C2("hello", "world", 42)
+    x, y = copy.deepcopy((a, b))
+    vereq(x.__class__, a.__class__)
+    vereq(sorteditems(x.__dict__), sorteditems(a.__dict__))
+    vereq(y.__class__, b.__class__)
+    vereq(sorteditems(y.__dict__), sorteditems(b.__dict__))
+    vereq(repr(x), repr(a))
+    vereq(repr(y), repr(b))
+    if verbose:
+        print "a = x =", a
+        print "b = y =", b
+
+def pickleslots():
+    if verbose: print "Testing pickling of classes with __slots__ ..."
+    import pickle, cPickle
+    # Pickling of classes with __slots__ but without __getstate__ should fail
+    global B, C, D, E
+    class B(object):
+        pass
+    for base in [object, B]:
+        class C(base):
+            __slots__ = ['a']
+        class D(C):
+            pass
+        try:
+            pickle.dumps(C())
+        except TypeError:
+            pass
+        else:
+            raise TestFailed, "should fail: pickle C instance - %s" % base
+        try:
+            cPickle.dumps(C())
+        except TypeError:
+            pass
+        else:
+            raise TestFailed, "should fail: cPickle C instance - %s" % base
+        try:
+            pickle.dumps(C())
+        except TypeError:
+            pass
+        else:
+            raise TestFailed, "should fail: pickle D instance - %s" % base
+        try:
+            cPickle.dumps(D())
+        except TypeError:
+            pass
+        else:
+            raise TestFailed, "should fail: cPickle D instance - %s" % base
+        # Give C a nice generic __getstate__ and __setstate__
+        class C(base):
+            __slots__ = ['a']
+            def __getstate__(self):
+                try:
+                    d = self.__dict__.copy()
+                except AttributeError:
+                    d = {}
+                for cls in self.__class__.__mro__:
+                    for sn in cls.__dict__.get('__slots__', ()):
+                        try:
+                            d[sn] = getattr(self, sn)
+                        except AttributeError:
+                            pass
+                return d
+            def __setstate__(self, d):
+                for k, v in d.items():
+                    setattr(self, k, v)
+        class D(C):
+            pass
+        # Now it should work
+        x = C()
+        y = pickle.loads(pickle.dumps(x))
+        vereq(hasattr(y, 'a'), 0)
+        y = cPickle.loads(cPickle.dumps(x))
+        vereq(hasattr(y, 'a'), 0)
+        x.a = 42
+        y = pickle.loads(pickle.dumps(x))
+        vereq(y.a, 42)
+        y = cPickle.loads(cPickle.dumps(x))
+        vereq(y.a, 42)
+        x = D()
+        x.a = 42
+        x.b = 100
+        y = pickle.loads(pickle.dumps(x))
+        vereq(y.a + y.b, 142)
+        y = cPickle.loads(cPickle.dumps(x))
+        vereq(y.a + y.b, 142)
+        # A subclass that adds a slot should also work
+        class E(C):
+            __slots__ = ['b']
+        x = E()
+        x.a = 42
+        x.b = "foo"
+        y = pickle.loads(pickle.dumps(x))
+        vereq(y.a, x.a)
+        vereq(y.b, x.b)
+        y = cPickle.loads(cPickle.dumps(x))
+        vereq(y.a, x.a)
+        vereq(y.b, x.b)
+
+def copies():
+    if verbose: print "Testing copy.copy() and copy.deepcopy()..."
+    import copy
+    class C(object):
+        pass
+
+    a = C()
+    a.foo = 12
+    b = copy.copy(a)
+    vereq(b.__dict__, a.__dict__)
+
+    a.bar = [1,2,3]
+    c = copy.copy(a)
+    vereq(c.bar, a.bar)
+    verify(c.bar is a.bar)
+
+    d = copy.deepcopy(a)
+    vereq(d.__dict__, a.__dict__)
+    a.bar.append(4)
+    vereq(d.bar, [1,2,3])
+
+def binopoverride():
+    if verbose: print "Testing overrides of binary operations..."
+    class I(int):
+        def __repr__(self):
+            return "I(%r)" % int(self)
+        def __add__(self, other):
+            return I(int(self) + int(other))
+        __radd__ = __add__
+        def __pow__(self, other, mod=None):
+            if mod is None:
+                return I(pow(int(self), int(other)))
+            else:
+                return I(pow(int(self), int(other), int(mod)))
+        def __rpow__(self, other, mod=None):
+            if mod is None:
+                return I(pow(int(other), int(self), mod))
+            else:
+                return I(pow(int(other), int(self), int(mod)))
+
+    vereq(repr(I(1) + I(2)), "I(3)")
+    vereq(repr(I(1) + 2), "I(3)")
+    vereq(repr(1 + I(2)), "I(3)")
+    vereq(repr(I(2) ** I(3)), "I(8)")
+    vereq(repr(2 ** I(3)), "I(8)")
+    vereq(repr(I(2) ** 3), "I(8)")
+    vereq(repr(pow(I(2), I(3), I(5))), "I(3)")
+    class S(str):
+        def __eq__(self, other):
+            return self.lower() == other.lower()
+
+def subclasspropagation():
+    if verbose: print "Testing propagation of slot functions to subclasses..."
+    class A(object):
+        pass
+    class B(A):
+        pass
+    class C(A):
+        pass
+    class D(B, C):
+        pass
+    d = D()
+    orig_hash = hash(d) # related to id(d) in platform-dependent ways
+    A.__hash__ = lambda self: 42
+    vereq(hash(d), 42)
+    C.__hash__ = lambda self: 314
+    vereq(hash(d), 314)
+    B.__hash__ = lambda self: 144
+    vereq(hash(d), 144)
+    D.__hash__ = lambda self: 100
+    vereq(hash(d), 100)
+    del D.__hash__
+    vereq(hash(d), 144)
+    del B.__hash__
+    vereq(hash(d), 314)
+    del C.__hash__
+    vereq(hash(d), 42)
+    del A.__hash__
+    vereq(hash(d), orig_hash)
+    d.foo = 42
+    d.bar = 42
+    vereq(d.foo, 42)
+    vereq(d.bar, 42)
+    def __getattribute__(self, name):
+        if name == "foo":
+            return 24
+        return object.__getattribute__(self, name)
+    A.__getattribute__ = __getattribute__
+    vereq(d.foo, 24)
+    vereq(d.bar, 42)
+    def __getattr__(self, name):
+        if name in ("spam", "foo", "bar"):
+            return "hello"
+        raise AttributeError, name
+    B.__getattr__ = __getattr__
+    vereq(d.spam, "hello")
+    vereq(d.foo, 24)
+    vereq(d.bar, 42)
+    del A.__getattribute__
+    vereq(d.foo, 42)
+    del d.foo
+    vereq(d.foo, "hello")
+    vereq(d.bar, 42)
+    del B.__getattr__
+    try:
+        d.foo
+    except AttributeError:
+        pass
+    else:
+        raise TestFailed, "d.foo should be undefined now"
+
+    # Test a nasty bug in recurse_down_subclasses()
+    import gc
+    class A(object):
+        pass
+    class B(A):
+        pass
+    del B
+    gc.collect()
+    A.__setitem__ = lambda *a: None # crash
+
+def buffer_inherit():
+    import binascii
+    # SF bug [#470040] ParseTuple t# vs subclasses.
+    if verbose:
+        print "Testing that buffer interface is inherited ..."
+
+    class MyStr(str):
+        pass
+    base = 'abc'
+    m = MyStr(base)
+    # b2a_hex uses the buffer interface to get its argument's value, via
+    # PyArg_ParseTuple 't#' code.
+    vereq(binascii.b2a_hex(m), binascii.b2a_hex(base))
+
+    # It's not clear that unicode will continue to support the character
+    # buffer interface, and this test will fail if that's taken away.
+    class MyUni(unicode):
+        pass
+    base = u'abc'
+    m = MyUni(base)
+    vereq(binascii.b2a_hex(m), binascii.b2a_hex(base))
+
+    class MyInt(int):
+        pass
+    m = MyInt(42)
+    try:
+        binascii.b2a_hex(m)
+        raise TestFailed('subclass of int should not have a buffer interface')
+    except TypeError:
+        pass
+
+def str_of_str_subclass():
+    import binascii
+    import cStringIO
+
+    if verbose:
+        print "Testing __str__ defined in subclass of str ..."
+
+    class octetstring(str):
+        def __str__(self):
+            return binascii.b2a_hex(self)
+        def __repr__(self):
+            return self + " repr"
+
+    o = octetstring('A')
+    vereq(type(o), octetstring)
+    vereq(type(str(o)), str)
+    vereq(type(repr(o)), str)
+    vereq(ord(o), 0x41)
+    vereq(str(o), '41')
+    vereq(repr(o), 'A repr')
+    vereq(o.__str__(), '41')
+    vereq(o.__repr__(), 'A repr')
+
+    capture = cStringIO.StringIO()
+    # Calling str() or not exercises different internal paths.
+    print >> capture, o
+    print >> capture, str(o)
+    vereq(capture.getvalue(), '41\n41\n')
+    capture.close()
+
+def kwdargs():
+    if verbose: print "Testing keyword arguments to __init__, __call__..."
+    def f(a): return a
+    vereq(f.__call__(a=42), 42)
+    a = []
+    list.__init__(a, sequence=[0, 1, 2])
+    vereq(a, [0, 1, 2])
+
+def recursive__call__():
+    if verbose: print ("Testing recursive __call__() by setting to instance of "
+                        "class ...")
+    class A(object):
+        pass
+
+    A.__call__ = A()
+    try:
+        A()()
+    except RuntimeError:
+        pass
+    else:
+        raise TestFailed("Recursion limit should have been reached for "
+                         "__call__()")
+
+def delhook():
+    if verbose: print "Testing __del__ hook..."
+    log = []
+    class C(object):
+        def __del__(self):
+            log.append(1)
+    c = C()
+    vereq(log, [])
+    del c
+    vereq(log, [1])
+
+    class D(object): pass
+    d = D()
+    try: del d[0]
+    except TypeError: pass
+    else: raise TestFailed, "invalid del() didn't raise TypeError"
+
+def hashinherit():
+    if verbose: print "Testing hash of mutable subclasses..."
+
+    class mydict(dict):
+        pass
+    d = mydict()
+    try:
+        hash(d)
+    except TypeError:
+        pass
+    else:
+        raise TestFailed, "hash() of dict subclass should fail"
+
+    class mylist(list):
+        pass
+    d = mylist()
+    try:
+        hash(d)
+    except TypeError:
+        pass
+    else:
+        raise TestFailed, "hash() of list subclass should fail"
+
+def strops():
+    try: 'a' + 5
+    except TypeError: pass
+    else: raise TestFailed, "'' + 5 doesn't raise TypeError"
+
+    try: ''.split('')
+    except ValueError: pass
+    else: raise TestFailed, "''.split('') doesn't raise ValueError"
+
+    try: ''.join([0])
+    except TypeError: pass
+    else: raise TestFailed, "''.join([0]) doesn't raise TypeError"
+
+    try: ''.rindex('5')
+    except ValueError: pass
+    else: raise TestFailed, "''.rindex('5') doesn't raise ValueError"
+
+    try: '%(n)s' % None
+    except TypeError: pass
+    else: raise TestFailed, "'%(n)s' % None doesn't raise TypeError"
+
+    try: '%(n' % {}
+    except ValueError: pass
+    else: raise TestFailed, "'%(n' % {} '' doesn't raise ValueError"
+
+    try: '%*s' % ('abc')
+    except TypeError: pass
+    else: raise TestFailed, "'%*s' % ('abc') doesn't raise TypeError"
+
+    try: '%*.*s' % ('abc', 5)
+    except TypeError: pass
+    else: raise TestFailed, "'%*.*s' % ('abc', 5) doesn't raise TypeError"
+
+    try: '%s' % (1, 2)
+    except TypeError: pass
+    else: raise TestFailed, "'%s' % (1, 2) doesn't raise TypeError"
+
+    try: '%' % None
+    except ValueError: pass
+    else: raise TestFailed, "'%' % None doesn't raise ValueError"
+
+    vereq('534253'.isdigit(), 1)
+    vereq('534253x'.isdigit(), 0)
+    vereq('%c' % 5, '\x05')
+    vereq('%c' % '5', '5')
+
+def deepcopyrecursive():
+    if verbose: print "Testing deepcopy of recursive objects..."
+    class Node:
+        pass
+    a = Node()
+    b = Node()
+    a.b = b
+    b.a = a
+    z = deepcopy(a) # This blew up before
+
+def modules():
+    if verbose: print "Testing uninitialized module objects..."
+    from types import ModuleType as M
+    m = M.__new__(M)
+    str(m)
+    vereq(hasattr(m, "__name__"), 0)
+    vereq(hasattr(m, "__file__"), 0)
+    vereq(hasattr(m, "foo"), 0)
+    vereq(m.__dict__, None)
+    m.foo = 1
+    vereq(m.__dict__, {"foo": 1})
+
+def dictproxyiterkeys():
+    class C(object):
+        def meth(self):
+            pass
+    if verbose: print "Testing dict-proxy iterkeys..."
+    keys = [ key for key in C.__dict__.iterkeys() ]
+    keys.sort()
+    vereq(keys, ['__dict__', '__doc__', '__module__', '__weakref__', 'meth'])
+
+def dictproxyitervalues():
+    class C(object):
+        def meth(self):
+            pass
+    if verbose: print "Testing dict-proxy itervalues..."
+    values = [ values for values in C.__dict__.itervalues() ]
+    vereq(len(values), 5)
+
+def dictproxyiteritems():
+    class C(object):
+        def meth(self):
+            pass
+    if verbose: print "Testing dict-proxy iteritems..."
+    keys = [ key for (key, value) in C.__dict__.iteritems() ]
+    keys.sort()
+    vereq(keys, ['__dict__', '__doc__', '__module__', '__weakref__', 'meth'])
+
+def funnynew():
+    if verbose: print "Testing __new__ returning something unexpected..."
+    class C(object):
+        def __new__(cls, arg):
+            if isinstance(arg, str): return [1, 2, 3]
+            elif isinstance(arg, int): return object.__new__(D)
+            else: return object.__new__(cls)
+    class D(C):
+        def __init__(self, arg):
+            self.foo = arg
+    vereq(C("1"), [1, 2, 3])
+    vereq(D("1"), [1, 2, 3])
+    d = D(None)
+    veris(d.foo, None)
+    d = C(1)
+    vereq(isinstance(d, D), True)
+    vereq(d.foo, 1)
+    d = D(1)
+    vereq(isinstance(d, D), True)
+    vereq(d.foo, 1)
+
+def imulbug():
+    # SF bug 544647
+    if verbose: print "Testing for __imul__ problems..."
+    class C(object):
+        def __imul__(self, other):
+            return (self, other)
+    x = C()
+    y = x
+    y *= 1.0
+    vereq(y, (x, 1.0))
+    y = x
+    y *= 2
+    vereq(y, (x, 2))
+    y = x
+    y *= 3L
+    vereq(y, (x, 3L))
+    y = x
+    y *= 1L<<100
+    vereq(y, (x, 1L<<100))
+    y = x
+    y *= None
+    vereq(y, (x, None))
+    y = x
+    y *= "foo"
+    vereq(y, (x, "foo"))
+
+def docdescriptor():
+    # SF bug 542984
+    if verbose: print "Testing __doc__ descriptor..."
+    class DocDescr(object):
+        def __get__(self, object, otype):
+            if object:
+                object = object.__class__.__name__ + ' instance'
+            if otype:
+                otype = otype.__name__
+            return 'object=%s; type=%s' % (object, otype)
+    class OldClass:
+        __doc__ = DocDescr()
+    class NewClass(object):
+        __doc__ = DocDescr()
+    vereq(OldClass.__doc__, 'object=None; type=OldClass')
+    vereq(OldClass().__doc__, 'object=OldClass instance; type=OldClass')
+    vereq(NewClass.__doc__, 'object=None; type=NewClass')
+    vereq(NewClass().__doc__, 'object=NewClass instance; type=NewClass')
+
+def copy_setstate():
+    if verbose:
+        print "Testing that copy.*copy() correctly uses __setstate__..."
+    import copy
+    class C(object):
+        def __init__(self, foo=None):
+            self.foo = foo
+            self.__foo = foo
+        def setfoo(self, foo=None):
+            self.foo = foo
+        def getfoo(self):
+            return self.__foo
+        def __getstate__(self):
+            return [self.foo]
+        def __setstate__(self, lst):
+            assert len(lst) == 1
+            self.__foo = self.foo = lst[0]
+    a = C(42)
+    a.setfoo(24)
+    vereq(a.foo, 24)
+    vereq(a.getfoo(), 42)
+    b = copy.copy(a)
+    vereq(b.foo, 24)
+    vereq(b.getfoo(), 24)
+    b = copy.deepcopy(a)
+    vereq(b.foo, 24)
+    vereq(b.getfoo(), 24)
+
+def slices():
+    if verbose:
+        print "Testing cases with slices and overridden __getitem__ ..."
+    # Strings
+    vereq("hello"[:4], "hell")
+    vereq("hello"[slice(4)], "hell")
+    vereq(str.__getitem__("hello", slice(4)), "hell")
+    class S(str):
+        def __getitem__(self, x):
+            return str.__getitem__(self, x)
+    vereq(S("hello")[:4], "hell")
+    vereq(S("hello")[slice(4)], "hell")
+    vereq(S("hello").__getitem__(slice(4)), "hell")
+    # Tuples
+    vereq((1,2,3)[:2], (1,2))
+    vereq((1,2,3)[slice(2)], (1,2))
+    vereq(tuple.__getitem__((1,2,3), slice(2)), (1,2))
+    class T(tuple):
+        def __getitem__(self, x):
+            return tuple.__getitem__(self, x)
+    vereq(T((1,2,3))[:2], (1,2))
+    vereq(T((1,2,3))[slice(2)], (1,2))
+    vereq(T((1,2,3)).__getitem__(slice(2)), (1,2))
+    # Lists
+    vereq([1,2,3][:2], [1,2])
+    vereq([1,2,3][slice(2)], [1,2])
+    vereq(list.__getitem__([1,2,3], slice(2)), [1,2])
+    class L(list):
+        def __getitem__(self, x):
+            return list.__getitem__(self, x)
+    vereq(L([1,2,3])[:2], [1,2])
+    vereq(L([1,2,3])[slice(2)], [1,2])
+    vereq(L([1,2,3]).__getitem__(slice(2)), [1,2])
+    # Now do lists and __setitem__
+    a = L([1,2,3])
+    a[slice(1, 3)] = [3,2]
+    vereq(a, [1,3,2])
+    a[slice(0, 2, 1)] = [3,1]
+    vereq(a, [3,1,2])
+    a.__setitem__(slice(1, 3), [2,1])
+    vereq(a, [3,2,1])
+    a.__setitem__(slice(0, 2, 1), [2,3])
+    vereq(a, [2,3,1])
+
+def subtype_resurrection():
+    if verbose:
+        print "Testing resurrection of new-style instance..."
+
+    class C(object):
+        container = []
+
+        def __del__(self):
+            # resurrect the instance
+            C.container.append(self)
+
+    c = C()
+    c.attr = 42
+    # The most interesting thing here is whether this blows up, due to flawed
+    #  GC tracking logic in typeobject.c's call_finalizer() (a 2.2.1 bug).
+    del c
+
+    # If that didn't blow up, it's also interesting to see whether clearing
+    # the last container slot works:  that will attempt to delete c again,
+    # which will cause c to get appended back to the container again "during"
+    # the del.
+    del C.container[-1]
+    vereq(len(C.container), 1)
+    vereq(C.container[-1].attr, 42)
+
+    # Make c mortal again, so that the test framework with -l doesn't report
+    # it as a leak.
+    del C.__del__
+
+def slottrash():
+    # Deallocating deeply nested slotted trash caused stack overflows
+    if verbose:
+        print "Testing slot trash..."
+    class trash(object):
+        __slots__ = ['x']
+        def __init__(self, x):
+            self.x = x
+    o = None
+    for i in xrange(50000):
+        o = trash(o)
+    del o
+
+def slotmultipleinheritance():
+    # SF bug 575229, multiple inheritance w/ slots dumps core
+    class A(object):
+        __slots__=()
+    class B(object):
+        pass
+    class C(A,B) :
+        __slots__=()
+    vereq(C.__basicsize__, B.__basicsize__)
+    verify(hasattr(C, '__dict__'))
+    verify(hasattr(C, '__weakref__'))
+    C().x = 2
+
+def testrmul():
+    # SF patch 592646
+    if verbose:
+        print "Testing correct invocation of __rmul__..."
+    class C(object):
+        def __mul__(self, other):
+            return "mul"
+        def __rmul__(self, other):
+            return "rmul"
+    a = C()
+    vereq(a*2, "mul")
+    vereq(a*2.2, "mul")
+    vereq(2*a, "rmul")
+    vereq(2.2*a, "rmul")
+
+def testipow():
+    # [SF bug 620179]
+    if verbose:
+        print "Testing correct invocation of __ipow__..."
+    class C(object):
+        def __ipow__(self, other):
+            pass
+    a = C()
+    a **= 2
+
+def do_this_first():
+    if verbose:
+        print "Testing SF bug 551412 ..."
+    # This dumps core when SF bug 551412 isn't fixed --
+    # but only when test_descr.py is run separately.
+    # (That can't be helped -- as soon as PyType_Ready()
+    # is called for PyLong_Type, the bug is gone.)
+    class UserLong(object):
+        def __pow__(self, *args):
+            pass
+    try:
+        pow(0L, UserLong(), 0L)
+    except:
+        pass
+
+    if verbose:
+        print "Testing SF bug 570483..."
+    # Another segfault only when run early
+    # (before PyType_Ready(tuple) is called)
+    type.mro(tuple)
+
+def test_mutable_bases():
+    if verbose:
+        print "Testing mutable bases..."
+    # stuff that should work:
+    class C(object):
+        pass
+    class C2(object):
+        def __getattribute__(self, attr):
+            if attr == 'a':
+                return 2
+            else:
+                return super(C2, self).__getattribute__(attr)
+        def meth(self):
+            return 1
+    class D(C):
+        pass
+    class E(D):
+        pass
+    d = D()
+    e = E()
+    D.__bases__ = (C,)
+    D.__bases__ = (C2,)
+    vereq(d.meth(), 1)
+    vereq(e.meth(), 1)
+    vereq(d.a, 2)
+    vereq(e.a, 2)
+    vereq(C2.__subclasses__(), [D])
+
+    # stuff that shouldn't:
+    class L(list):
+        pass
+
+    try:
+        L.__bases__ = (dict,)
+    except TypeError:
+        pass
+    else:
+        raise TestFailed, "shouldn't turn list subclass into dict subclass"
+
+    try:
+        list.__bases__ = (dict,)
+    except TypeError:
+        pass
+    else:
+        raise TestFailed, "shouldn't be able to assign to list.__bases__"
+
+    try:
+        del D.__bases__
+    except TypeError:
+        pass
+    else:
+        raise TestFailed, "shouldn't be able to delete .__bases__"
+
+    try:
+        D.__bases__ = ()
+    except TypeError, msg:
+        if str(msg) == "a new-style class can't have only classic bases":
+            raise TestFailed, "wrong error message for .__bases__ = ()"
+    else:
+        raise TestFailed, "shouldn't be able to set .__bases__ to ()"
+
+    try:
+        D.__bases__ = (D,)
+    except TypeError:
+        pass
+    else:
+        # actually, we'll have crashed by here...
+        raise TestFailed, "shouldn't be able to create inheritance cycles"
+
+    try:
+        D.__bases__ = (C, C)
+    except TypeError:
+        pass
+    else:
+        raise TestFailed, "didn't detect repeated base classes"
+
+    try:
+        D.__bases__ = (E,)
+    except TypeError:
+        pass
+    else:
+        raise TestFailed, "shouldn't be able to create inheritance cycles"
+
+    # let's throw a classic class into the mix:
+    class Classic:
+        def meth2(self):
+            return 3
+
+    D.__bases__ = (C, Classic)
+
+    vereq(d.meth2(), 3)
+    vereq(e.meth2(), 3)
+    try:
+        d.a
+    except AttributeError:
+        pass
+    else:
+        raise TestFailed, "attribute should have vanished"
+
+    try:
+        D.__bases__ = (Classic,)
+    except TypeError:
+        pass
+    else:
+        raise TestFailed, "new-style class must have a new-style base"
+
+def test_mutable_bases_with_failing_mro():
+    if verbose:
+        print "Testing mutable bases with failing mro..."
+    class WorkOnce(type):
+        def __new__(self, name, bases, ns):
+            self.flag = 0
+            return super(WorkOnce, self).__new__(WorkOnce, name, bases, ns)
+        def mro(self):
+            if self.flag > 0:
+                raise RuntimeError, "bozo"
+            else:
+                self.flag += 1
+                return type.mro(self)
+
+    class WorkAlways(type):
+        def mro(self):
+            # this is here to make sure that .mro()s aren't called
+            # with an exception set (which was possible at one point).
+            # An error message will be printed in a debug build.
+            # What's a good way to test for this?
+            return type.mro(self)
+
+    class C(object):
+        pass
+
+    class C2(object):
+        pass
+
+    class D(C):
+        pass
+
+    class E(D):
+        pass
+
+    class F(D):
+        __metaclass__ = WorkOnce
+
+    class G(D):
+        __metaclass__ = WorkAlways
+
+    # Immediate subclasses have their mro's adjusted in alphabetical
+    # order, so E's will get adjusted before adjusting F's fails.  We
+    # check here that E's gets restored.
+
+    E_mro_before = E.__mro__
+    D_mro_before = D.__mro__
+
+    try:
+        D.__bases__ = (C2,)
+    except RuntimeError:
+        vereq(E.__mro__, E_mro_before)
+        vereq(D.__mro__, D_mro_before)
+    else:
+        raise TestFailed, "exception not propagated"
+
+def test_mutable_bases_catch_mro_conflict():
+    if verbose:
+        print "Testing mutable bases catch mro conflict..."
+    class A(object):
+        pass
+
+    class B(object):
+        pass
+
+    class C(A, B):
+        pass
+
+    class D(A, B):
+        pass
+
+    class E(C, D):
+        pass
+
+    try:
+        C.__bases__ = (B, A)
+    except TypeError:
+        pass
+    else:
+        raise TestFailed, "didn't catch MRO conflict"
+
+def mutable_names():
+    if verbose:
+        print "Testing mutable names..."
+    class C(object):
+        pass
+
+    # C.__module__ could be 'test_descr' or '__main__'
+    mod = C.__module__
+
+    C.__name__ = 'D'
+    vereq((C.__module__, C.__name__), (mod, 'D'))
+
+    C.__name__ = 'D.E'
+    vereq((C.__module__, C.__name__), (mod, 'D.E'))
+
+def subclass_right_op():
+    if verbose:
+        print "Testing correct dispatch of subclass overloading __r<op>__..."
+
+    # This code tests various cases where right-dispatch of a subclass
+    # should be preferred over left-dispatch of a base class.
+
+    # Case 1: subclass of int; this tests code in abstract.c::binary_op1()
+
+    class B(int):
+        def __floordiv__(self, other):
+            return "B.__floordiv__"
+        def __rfloordiv__(self, other):
+            return "B.__rfloordiv__"
+
+    vereq(B(1) // 1, "B.__floordiv__")
+    vereq(1 // B(1), "B.__rfloordiv__")
+
+    # Case 2: subclass of object; this is just the baseline for case 3
+
+    class C(object):
+        def __floordiv__(self, other):
+            return "C.__floordiv__"
+        def __rfloordiv__(self, other):
+            return "C.__rfloordiv__"
+
+    vereq(C() // 1, "C.__floordiv__")
+    vereq(1 // C(), "C.__rfloordiv__")
+
+    # Case 3: subclass of new-style class; here it gets interesting
+
+    class D(C):
+        def __floordiv__(self, other):
+            return "D.__floordiv__"
+        def __rfloordiv__(self, other):
+            return "D.__rfloordiv__"
+
+    vereq(D() // C(), "D.__floordiv__")
+    vereq(C() // D(), "D.__rfloordiv__")
+
+    # Case 4: this didn't work right in 2.2.2 and 2.3a1
+
+    class E(C):
+        pass
+
+    vereq(E.__rfloordiv__, C.__rfloordiv__)
+
+    vereq(E() // 1, "C.__floordiv__")
+    vereq(1 // E(), "C.__rfloordiv__")
+    vereq(E() // C(), "C.__floordiv__")
+    vereq(C() // E(), "C.__floordiv__") # This one would fail
+
+def dict_type_with_metaclass():
+    if verbose:
+        print "Testing type of __dict__ when __metaclass__ set..."
+
+    class B(object):
+        pass
+    class M(type):
+        pass
+    class C:
+        # In 2.3a1, C.__dict__ was a real dict rather than a dict proxy
+        __metaclass__ = M
+    veris(type(C.__dict__), type(B.__dict__))
+
+def meth_class_get():
+    # Full coverage of descrobject.c::classmethod_get()
+    if verbose:
+        print "Testing __get__ method of METH_CLASS C methods..."
+    # Baseline
+    arg = [1, 2, 3]
+    res = {1: None, 2: None, 3: None}
+    vereq(dict.fromkeys(arg), res)
+    vereq({}.fromkeys(arg), res)
+    # Now get the descriptor
+    descr = dict.__dict__["fromkeys"]
+    # More baseline using the descriptor directly
+    vereq(descr.__get__(None, dict)(arg), res)
+    vereq(descr.__get__({})(arg), res)
+    # Now check various error cases
+    try:
+        descr.__get__(None, None)
+    except TypeError:
+        pass
+    else:
+        raise TestFailed, "shouldn't have allowed descr.__get__(None, None)"
+    try:
+        descr.__get__(42)
+    except TypeError:
+        pass
+    else:
+        raise TestFailed, "shouldn't have allowed descr.__get__(42)"
+    try:
+        descr.__get__(None, 42)
+    except TypeError:
+        pass
+    else:
+        raise TestFailed, "shouldn't have allowed descr.__get__(None, 42)"
+    try:
+        descr.__get__(None, int)
+    except TypeError:
+        pass
+    else:
+        raise TestFailed, "shouldn't have allowed descr.__get__(None, int)"
+
+def isinst_isclass():
+    if verbose:
+        print "Testing proxy isinstance() and isclass()..."
+    class Proxy(object):
+        def __init__(self, obj):
+            self.__obj = obj
+        def __getattribute__(self, name):
+            if name.startswith("_Proxy__"):
+                return object.__getattribute__(self, name)
+            else:
+                return getattr(self.__obj, name)
+    # Test with a classic class
+    class C:
+        pass
+    a = C()
+    pa = Proxy(a)
+    verify(isinstance(a, C))  # Baseline
+    verify(isinstance(pa, C)) # Test
+    # Test with a classic subclass
+    class D(C):
+        pass
+    a = D()
+    pa = Proxy(a)
+    verify(isinstance(a, C))  # Baseline
+    verify(isinstance(pa, C)) # Test
+    # Test with a new-style class
+    class C(object):
+        pass
+    a = C()
+    pa = Proxy(a)
+    verify(isinstance(a, C))  # Baseline
+    verify(isinstance(pa, C)) # Test
+    # Test with a new-style subclass
+    class D(C):
+        pass
+    a = D()
+    pa = Proxy(a)
+    verify(isinstance(a, C))  # Baseline
+    verify(isinstance(pa, C)) # Test
+
+def proxysuper():
+    if verbose:
+        print "Testing super() for a proxy object..."
+    class Proxy(object):
+        def __init__(self, obj):
+            self.__obj = obj
+        def __getattribute__(self, name):
+            if name.startswith("_Proxy__"):
+                return object.__getattribute__(self, name)
+            else:
+                return getattr(self.__obj, name)
+
+    class B(object):
+        def f(self):
+            return "B.f"
+
+    class C(B):
+        def f(self):
+            return super(C, self).f() + "->C.f"
+
+    obj = C()
+    p = Proxy(obj)
+    vereq(C.__dict__["f"](p), "B.f->C.f")
+
+def carloverre():
+    if verbose:
+        print "Testing prohibition of Carlo Verre's hack..."
+    try:
+        object.__setattr__(str, "foo", 42)
+    except TypeError:
+        pass
+    else:
+        raise TestFailed, "Carlo Verre __setattr__ suceeded!"
+    try:
+        object.__delattr__(str, "lower")
+    except TypeError:
+        pass
+    else:
+        raise TestFailed, "Carlo Verre __delattr__ succeeded!"
+
+def weakref_segfault():
+    # SF 742911
+    if verbose:
+        print "Testing weakref segfault..."
+
+    import weakref
+
+    class Provoker:
+        def __init__(self, referrent):
+            self.ref = weakref.ref(referrent)
+
+        def __del__(self):
+            x = self.ref()
+
+    class Oops(object):
+        pass
+
+    o = Oops()
+    o.whatever = Provoker(o)
+    del o
+
+def wrapper_segfault():
+    # SF 927248: deeply nested wrappers could cause stack overflow
+    f = lambda:None
+    for i in xrange(1000000):
+        f = f.__call__
+    f = None
+
+# Fix SF #762455, segfault when sys.stdout is changed in getattr
+def filefault():
+    if verbose:
+        print "Testing sys.stdout is changed in getattr..."
+    import sys
+    class StdoutGuard:
+        def __getattr__(self, attr):
+            sys.stdout = sys.__stdout__
+            raise RuntimeError("Premature access to sys.stdout.%s" % attr)
+    sys.stdout = StdoutGuard()
+    try:
+        print "Oops!"
+    except RuntimeError:
+        pass
+
+def vicious_descriptor_nonsense():
+    # A potential segfault spotted by Thomas Wouters in mail to
+    # python-dev 2003-04-17, turned into an example & fixed by Michael
+    # Hudson just less than four months later...
+    if verbose:
+        print "Testing vicious_descriptor_nonsense..."
+
+    class Evil(object):
+        def __hash__(self):
+            return hash('attr')
+        def __eq__(self, other):
+            del C.attr
+            return 0
+
+    class Descr(object):
+        def __get__(self, ob, type=None):
+            return 1
+
+    class C(object):
+        attr = Descr()
+
+    c = C()
+    c.__dict__[Evil()] = 0
+
+    vereq(c.attr, 1)
+    # this makes a crash more likely:
+    import gc; gc.collect()
+    vereq(hasattr(c, 'attr'), False)
+
+def test_init():
+    # SF 1155938
+    class Foo(object):
+        def __init__(self):
+            return 10
+    try:
+        Foo()
+    except TypeError:
+        pass
+    else:
+        raise TestFailed, "did not test __init__() for None return"
+
+def methodwrapper():
+    # <type 'method-wrapper'> did not support any reflection before 2.5
+    if verbose:
+        print "Testing method-wrapper objects..."
+
+    l = []
+    vereq(l.__add__, l.__add__)
+    vereq(l.__add__, [].__add__)
+    verify(l.__add__ != [5].__add__)
+    verify(l.__add__ != l.__mul__)
+    verify(l.__add__.__name__ == '__add__')
+    verify(l.__add__.__self__ is l)
+    verify(l.__add__.__objclass__ is list)
+    vereq(l.__add__.__doc__, list.__add__.__doc__)
+    try:
+        hash(l.__add__)
+    except TypeError:
+        pass
+    else:
+        raise TestFailed("no TypeError from hash([].__add__)")
+
+    t = ()
+    t += (7,)
+    vereq(t.__add__, (7,).__add__)
+    vereq(hash(t.__add__), hash((7,).__add__))
+
+def notimplemented():
+    # all binary methods should be able to return a NotImplemented
+    if verbose:
+        print "Testing NotImplemented..."
+
+    import sys
+    import types
+    import operator
+
+    def specialmethod(self, other):
+        return NotImplemented
+
+    def check(expr, x, y):
+        try:
+            exec expr in {'x': x, 'y': y, 'operator': operator}
+        except TypeError:
+            pass
+        else:
+            raise TestFailed("no TypeError from %r" % (expr,))
+
+    N1 = sys.maxint + 1L    # might trigger OverflowErrors instead of TypeErrors
+    N2 = sys.maxint         # if sizeof(int) < sizeof(long), might trigger
+                            #   ValueErrors instead of TypeErrors
+    for metaclass in [type, types.ClassType]:
+        for name, expr, iexpr in [
+                ('__add__',      'x + y',                   'x += y'),
+                ('__sub__',      'x - y',                   'x -= y'),
+                ('__mul__',      'x * y',                   'x *= y'),
+                ('__truediv__',  'operator.truediv(x, y)',  None),
+                ('__floordiv__', 'operator.floordiv(x, y)', None),
+                ('__div__',      'x / y',                   'x /= y'),
+                ('__mod__',      'x % y',                   'x %= y'),
+                ('__divmod__',   'divmod(x, y)',            None),
+                ('__pow__',      'x ** y',                  'x **= y'),
+                ('__lshift__',   'x << y',                  'x <<= y'),
+                ('__rshift__',   'x >> y',                  'x >>= y'),
+                ('__and__',      'x & y',                   'x &= y'),
+                ('__or__',       'x | y',                   'x |= y'),
+                ('__xor__',      'x ^ y',                   'x ^= y'),
+                ('__coerce__',   'coerce(x, y)',            None)]:
+            if name == '__coerce__':
+                rname = name
+            else:
+                rname = '__r' + name[2:]
+            A = metaclass('A', (), {name: specialmethod})
+            B = metaclass('B', (), {rname: specialmethod})
+            a = A()
+            b = B()
+            check(expr, a, a)
+            check(expr, a, b)
+            check(expr, b, a)
+            check(expr, b, b)
+            check(expr, a, N1)
+            check(expr, a, N2)
+            check(expr, N1, b)
+            check(expr, N2, b)
+            if iexpr:
+                check(iexpr, a, a)
+                check(iexpr, a, b)
+                check(iexpr, b, a)
+                check(iexpr, b, b)
+                check(iexpr, a, N1)
+                check(iexpr, a, N2)
+                iname = '__i' + name[2:]
+                C = metaclass('C', (), {iname: specialmethod})
+                c = C()
+                check(iexpr, c, a)
+                check(iexpr, c, b)
+                check(iexpr, c, N1)
+                check(iexpr, c, N2)
+
+def test_assign_slice():
+    # ceval.c's assign_slice used to check for
+    # tp->tp_as_sequence->sq_slice instead of
+    # tp->tp_as_sequence->sq_ass_slice
+
+    class C(object):
+        def __setslice__(self, start, stop, value):
+            self.value = value
+
+    c = C()
+    c[1:2] = 3
+    vereq(c.value, 3)
+
+def test_main():
+    weakref_segfault() # Must be first, somehow
+    wrapper_segfault()
+    do_this_first()
+    class_docstrings()
+    lists()
+    dicts()
+    dict_constructor()
+    test_dir()
+    ints()
+    longs()
+    floats()
+    complexes()
+    spamlists()
+    spamdicts()
+    pydicts()
+    pylists()
+    metaclass()
+    pymods()
+    multi()
+    mro_disagreement()
+    diamond()
+    ex5()
+    monotonicity()
+    consistency_with_epg()
+    objects()
+    slots()
+    slotspecials()
+    dynamics()
+    errors()
+    classmethods()
+    classmethods_in_c()
+    staticmethods()
+    staticmethods_in_c()
+    classic()
+    compattr()
+    newslot()
+    altmro()
+    overloading()
+    methods()
+    specials()
+    weakrefs()
+    properties()
+    supers()
+    inherits()
+    keywords()
+    restricted()
+    str_subclass_as_dict_key()
+    classic_comparisons()
+    rich_comparisons()
+    coercions()
+    descrdoc()
+    setclass()
+    setdict()
+    pickles()
+    copies()
+    binopoverride()
+    subclasspropagation()
+    buffer_inherit()
+    str_of_str_subclass()
+    kwdargs()
+    recursive__call__()
+    delhook()
+    hashinherit()
+    strops()
+    deepcopyrecursive()
+    modules()
+    dictproxyiterkeys()
+    dictproxyitervalues()
+    dictproxyiteritems()
+    pickleslots()
+    funnynew()
+    imulbug()
+    docdescriptor()
+    copy_setstate()
+    slices()
+    subtype_resurrection()
+    slottrash()
+    slotmultipleinheritance()
+    testrmul()
+    testipow()
+    test_mutable_bases()
+    test_mutable_bases_with_failing_mro()
+    test_mutable_bases_catch_mro_conflict()
+    mutable_names()
+    subclass_right_op()
+    dict_type_with_metaclass()
+    meth_class_get()
+    isinst_isclass()
+    proxysuper()
+    carloverre()
+    filefault()
+    vicious_descriptor_nonsense()
+    test_init()
+    methodwrapper()
+    notimplemented()
+    test_assign_slice()
+
+    if verbose: print "All OK"
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_descrtut.py
===================================================================
--- vendor/Python/current/Lib/test/test_descrtut.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_descrtut.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,494 @@
+# This contains most of the executable examples from Guido's descr
+# tutorial, once at
+#
+#     http://www.python.org/2.2/descrintro.html
+#
+# A few examples left implicit in the writeup were fleshed out, a few were
+# skipped due to lack of interest (e.g., faking super() by hand isn't
+# of much interest anymore), and a few were fiddled to make the output
+# deterministic.
+
+from test.test_support import sortdict
+import pprint
+
+class defaultdict(dict):
+    def __init__(self, default=None):
+        dict.__init__(self)
+        self.default = default
+
+    def __getitem__(self, key):
+        try:
+            return dict.__getitem__(self, key)
+        except KeyError:
+            return self.default
+
+    def get(self, key, *args):
+        if not args:
+            args = (self.default,)
+        return dict.get(self, key, *args)
+
+    def merge(self, other):
+        for key in other:
+            if key not in self:
+                self[key] = other[key]
+
+test_1 = """
+
+Here's the new type at work:
+
+    >>> print defaultdict               # show our type
+    <class 'test.test_descrtut.defaultdict'>
+    >>> print type(defaultdict)         # its metatype
+    <type 'type'>
+    >>> a = defaultdict(default=0.0)    # create an instance
+    >>> print a                         # show the instance
+    {}
+    >>> print type(a)                   # show its type
+    <class 'test.test_descrtut.defaultdict'>
+    >>> print a.__class__               # show its class
+    <class 'test.test_descrtut.defaultdict'>
+    >>> print type(a) is a.__class__    # its type is its class
+    True
+    >>> a[1] = 3.25                     # modify the instance
+    >>> print a                         # show the new value
+    {1: 3.25}
+    >>> print a[1]                      # show the new item
+    3.25
+    >>> print a[0]                      # a non-existant item
+    0.0
+    >>> a.merge({1:100, 2:200})         # use a dict method
+    >>> print sortdict(a)               # show the result
+    {1: 3.25, 2: 200}
+    >>>
+
+We can also use the new type in contexts where classic only allows "real"
+dictionaries, such as the locals/globals dictionaries for the exec
+statement or the built-in function eval():
+
+    >>> def sorted(seq):
+    ...     seq.sort()
+    ...     return seq
+    >>> print sorted(a.keys())
+    [1, 2]
+    >>> exec "x = 3; print x" in a
+    3
+    >>> print sorted(a.keys())
+    [1, 2, '__builtins__', 'x']
+    >>> print a['x']
+    3
+    >>>
+
+Now I'll show that defaultdict instances have dynamic instance variables,
+just like classic classes:
+
+    >>> a.default = -1
+    >>> print a["noway"]
+    -1
+    >>> a.default = -1000
+    >>> print a["noway"]
+    -1000
+    >>> 'default' in dir(a)
+    True
+    >>> a.x1 = 100
+    >>> a.x2 = 200
+    >>> print a.x1
+    100
+    >>> d = dir(a)
+    >>> 'default' in d and 'x1' in d and 'x2' in d
+    True
+    >>> print sortdict(a.__dict__)
+    {'default': -1000, 'x1': 100, 'x2': 200}
+    >>>
+"""
+
+class defaultdict2(dict):
+    __slots__ = ['default']
+
+    def __init__(self, default=None):
+        dict.__init__(self)
+        self.default = default
+
+    def __getitem__(self, key):
+        try:
+            return dict.__getitem__(self, key)
+        except KeyError:
+            return self.default
+
+    def get(self, key, *args):
+        if not args:
+            args = (self.default,)
+        return dict.get(self, key, *args)
+
+    def merge(self, other):
+        for key in other:
+            if key not in self:
+                self[key] = other[key]
+
+test_2 = """
+
+The __slots__ declaration takes a list of instance variables, and reserves
+space for exactly these in the instance. When __slots__ is used, other
+instance variables cannot be assigned to:
+
+    >>> a = defaultdict2(default=0.0)
+    >>> a[1]
+    0.0
+    >>> a.default = -1
+    >>> a[1]
+    -1
+    >>> a.x1 = 1
+    Traceback (most recent call last):
+      File "<stdin>", line 1, in ?
+    AttributeError: 'defaultdict2' object has no attribute 'x1'
+    >>>
+
+"""
+
+test_3 = """
+
+Introspecting instances of built-in types
+
+For instance of built-in types, x.__class__ is now the same as type(x):
+
+    >>> type([])
+    <type 'list'>
+    >>> [].__class__
+    <type 'list'>
+    >>> list
+    <type 'list'>
+    >>> isinstance([], list)
+    True
+    >>> isinstance([], dict)
+    False
+    >>> isinstance([], object)
+    True
+    >>>
+
+Under the new proposal, the __methods__ attribute no longer exists:
+
+    >>> [].__methods__
+    Traceback (most recent call last):
+      File "<stdin>", line 1, in ?
+    AttributeError: 'list' object has no attribute '__methods__'
+    >>>
+
+Instead, you can get the same information from the list type:
+
+    >>> pprint.pprint(dir(list))    # like list.__dict__.keys(), but sorted
+    ['__add__',
+     '__class__',
+     '__contains__',
+     '__delattr__',
+     '__delitem__',
+     '__delslice__',
+     '__doc__',
+     '__eq__',
+     '__ge__',
+     '__getattribute__',
+     '__getitem__',
+     '__getslice__',
+     '__gt__',
+     '__hash__',
+     '__iadd__',
+     '__imul__',
+     '__init__',
+     '__iter__',
+     '__le__',
+     '__len__',
+     '__lt__',
+     '__mul__',
+     '__ne__',
+     '__new__',
+     '__reduce__',
+     '__reduce_ex__',
+     '__repr__',
+     '__reversed__',
+     '__rmul__',
+     '__setattr__',
+     '__setitem__',
+     '__setslice__',
+     '__str__',
+     'append',
+     'count',
+     'extend',
+     'index',
+     'insert',
+     'pop',
+     'remove',
+     'reverse',
+     'sort']
+
+The new introspection API gives more information than the old one:  in
+addition to the regular methods, it also shows the methods that are
+normally invoked through special notations, e.g. __iadd__ (+=), __len__
+(len), __ne__ (!=). You can invoke any method from this list directly:
+
+    >>> a = ['tic', 'tac']
+    >>> list.__len__(a)          # same as len(a)
+    2
+    >>> a.__len__()              # ditto
+    2
+    >>> list.append(a, 'toe')    # same as a.append('toe')
+    >>> a
+    ['tic', 'tac', 'toe']
+    >>>
+
+This is just like it is for user-defined classes.
+"""
+
+test_4 = """
+
+Static methods and class methods
+
+The new introspection API makes it possible to add static methods and class
+methods. Static methods are easy to describe: they behave pretty much like
+static methods in C++ or Java. Here's an example:
+
+    >>> class C:
+    ...
+    ...     @staticmethod
+    ...     def foo(x, y):
+    ...         print "staticmethod", x, y
+
+    >>> C.foo(1, 2)
+    staticmethod 1 2
+    >>> c = C()
+    >>> c.foo(1, 2)
+    staticmethod 1 2
+
+Class methods use a similar pattern to declare methods that receive an
+implicit first argument that is the *class* for which they are invoked.
+
+    >>> class C:
+    ...     @classmethod
+    ...     def foo(cls, y):
+    ...         print "classmethod", cls, y
+
+    >>> C.foo(1)
+    classmethod test.test_descrtut.C 1
+    >>> c = C()
+    >>> c.foo(1)
+    classmethod test.test_descrtut.C 1
+
+    >>> class D(C):
+    ...     pass
+
+    >>> D.foo(1)
+    classmethod test.test_descrtut.D 1
+    >>> d = D()
+    >>> d.foo(1)
+    classmethod test.test_descrtut.D 1
+
+This prints "classmethod __main__.D 1" both times; in other words, the
+class passed as the first argument of foo() is the class involved in the
+call, not the class involved in the definition of foo().
+
+But notice this:
+
+    >>> class E(C):
+    ...     @classmethod
+    ...     def foo(cls, y): # override C.foo
+    ...         print "E.foo() called"
+    ...         C.foo(y)
+
+    >>> E.foo(1)
+    E.foo() called
+    classmethod test.test_descrtut.C 1
+    >>> e = E()
+    >>> e.foo(1)
+    E.foo() called
+    classmethod test.test_descrtut.C 1
+
+In this example, the call to C.foo() from E.foo() will see class C as its
+first argument, not class E. This is to be expected, since the call
+specifies the class C. But it stresses the difference between these class
+methods and methods defined in metaclasses (where an upcall to a metamethod
+would pass the target class as an explicit first argument).
+"""
+
+test_5 = """
+
+Attributes defined by get/set methods
+
+
+    >>> class property(object):
+    ...
+    ...     def __init__(self, get, set=None):
+    ...         self.__get = get
+    ...         self.__set = set
+    ...
+    ...     def __get__(self, inst, type=None):
+    ...         return self.__get(inst)
+    ...
+    ...     def __set__(self, inst, value):
+    ...         if self.__set is None:
+    ...             raise AttributeError, "this attribute is read-only"
+    ...         return self.__set(inst, value)
+
+Now let's define a class with an attribute x defined by a pair of methods,
+getx() and and setx():
+
+    >>> class C(object):
+    ...
+    ...     def __init__(self):
+    ...         self.__x = 0
+    ...
+    ...     def getx(self):
+    ...         return self.__x
+    ...
+    ...     def setx(self, x):
+    ...         if x < 0: x = 0
+    ...         self.__x = x
+    ...
+    ...     x = property(getx, setx)
+
+Here's a small demonstration:
+
+    >>> a = C()
+    >>> a.x = 10
+    >>> print a.x
+    10
+    >>> a.x = -10
+    >>> print a.x
+    0
+    >>>
+
+Hmm -- property is builtin now, so let's try it that way too.
+
+    >>> del property  # unmask the builtin
+    >>> property
+    <type 'property'>
+
+    >>> class C(object):
+    ...     def __init__(self):
+    ...         self.__x = 0
+    ...     def getx(self):
+    ...         return self.__x
+    ...     def setx(self, x):
+    ...         if x < 0: x = 0
+    ...         self.__x = x
+    ...     x = property(getx, setx)
+
+
+    >>> a = C()
+    >>> a.x = 10
+    >>> print a.x
+    10
+    >>> a.x = -10
+    >>> print a.x
+    0
+    >>>
+"""
+
+test_6 = """
+
+Method resolution order
+
+This example is implicit in the writeup.
+
+>>> class A:    # classic class
+...     def save(self):
+...         print "called A.save()"
+>>> class B(A):
+...     pass
+>>> class C(A):
+...     def save(self):
+...         print "called C.save()"
+>>> class D(B, C):
+...     pass
+
+>>> D().save()
+called A.save()
+
+>>> class A(object):  # new class
+...     def save(self):
+...         print "called A.save()"
+>>> class B(A):
+...     pass
+>>> class C(A):
+...     def save(self):
+...         print "called C.save()"
+>>> class D(B, C):
+...     pass
+
+>>> D().save()
+called C.save()
+"""
+
+class A(object):
+    def m(self):
+        return "A"
+
+class B(A):
+    def m(self):
+        return "B" + super(B, self).m()
+
+class C(A):
+    def m(self):
+        return "C" + super(C, self).m()
+
+class D(C, B):
+    def m(self):
+        return "D" + super(D, self).m()
+
+
+test_7 = """
+
+Cooperative methods and "super"
+
+>>> print D().m() # "DCBA"
+DCBA
+"""
+
+test_8 = """
+
+Backwards incompatibilities
+
+>>> class A:
+...     def foo(self):
+...         print "called A.foo()"
+
+>>> class B(A):
+...     pass
+
+>>> class C(A):
+...     def foo(self):
+...         B.foo(self)
+
+>>> C().foo()
+Traceback (most recent call last):
+ ...
+TypeError: unbound method foo() must be called with B instance as first argument (got C instance instead)
+
+>>> class C(A):
+...     def foo(self):
+...         A.foo(self)
+>>> C().foo()
+called A.foo()
+"""
+
+__test__ = {"tut1": test_1,
+            "tut2": test_2,
+            "tut3": test_3,
+            "tut4": test_4,
+            "tut5": test_5,
+            "tut6": test_6,
+            "tut7": test_7,
+            "tut8": test_8}
+
+# Magic test name that regrtest.py invokes *after* importing this module.
+# This worms around a bootstrap problem.
+# Note that doctest and regrtest both look in sys.argv for a "-v" argument,
+# so this works as expected in both ways of running regrtest.
+def test_main(verbose=None):
+    # Obscure:  import this module as test.test_descrtut instead of as
+    # plain test_descrtut because the name of this module works its way
+    # into the doctest examples, and unless the full test.test_descrtut
+    # business is used the name can change depending on how the test is
+    # invoked.
+    from test import test_support, test_descrtut
+    test_support.run_doctest(test_descrtut, verbose)
+
+# This part isn't needed for regrtest, but for running the test directly.
+if __name__ == "__main__":
+    test_main(1)

Added: vendor/Python/current/Lib/test/test_dict.py
===================================================================
--- vendor/Python/current/Lib/test/test_dict.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_dict.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,477 @@
+import unittest
+from test import test_support
+
+import sys, UserDict, cStringIO
+
+
+class DictTest(unittest.TestCase):
+    def test_constructor(self):
+        # calling built-in types without argument must return empty
+        self.assertEqual(dict(), {})
+        self.assert_(dict() is not {})
+
+    def test_bool(self):
+        self.assert_(not {})
+        self.assert_({1: 2})
+        self.assert_(bool({}) is False)
+        self.assert_(bool({1: 2}) is True)
+
+    def test_keys(self):
+        d = {}
+        self.assertEqual(d.keys(), [])
+        d = {'a': 1, 'b': 2}
+        k = d.keys()
+        self.assert_(d.has_key('a'))
+        self.assert_(d.has_key('b'))
+
+        self.assertRaises(TypeError, d.keys, None)
+
+    def test_values(self):
+        d = {}
+        self.assertEqual(d.values(), [])
+        d = {1:2}
+        self.assertEqual(d.values(), [2])
+
+        self.assertRaises(TypeError, d.values, None)
+
+    def test_items(self):
+        d = {}
+        self.assertEqual(d.items(), [])
+
+        d = {1:2}
+        self.assertEqual(d.items(), [(1, 2)])
+
+        self.assertRaises(TypeError, d.items, None)
+
+    def test_has_key(self):
+        d = {}
+        self.assert_(not d.has_key('a'))
+        d = {'a': 1, 'b': 2}
+        k = d.keys()
+        k.sort()
+        self.assertEqual(k, ['a', 'b'])
+
+        self.assertRaises(TypeError, d.has_key)
+
+    def test_contains(self):
+        d = {}
+        self.assert_(not ('a' in d))
+        self.assert_('a' not in d)
+        d = {'a': 1, 'b': 2}
+        self.assert_('a' in d)
+        self.assert_('b' in d)
+        self.assert_('c' not in d)
+
+        self.assertRaises(TypeError, d.__contains__)
+
+    def test_len(self):
+        d = {}
+        self.assertEqual(len(d), 0)
+        d = {'a': 1, 'b': 2}
+        self.assertEqual(len(d), 2)
+
+    def test_getitem(self):
+        d = {'a': 1, 'b': 2}
+        self.assertEqual(d['a'], 1)
+        self.assertEqual(d['b'], 2)
+        d['c'] = 3
+        d['a'] = 4
+        self.assertEqual(d['c'], 3)
+        self.assertEqual(d['a'], 4)
+        del d['b']
+        self.assertEqual(d, {'a': 4, 'c': 3})
+
+        self.assertRaises(TypeError, d.__getitem__)
+
+        class BadEq(object):
+            def __eq__(self, other):
+                raise Exc()
+
+        d = {}
+        d[BadEq()] = 42
+        self.assertRaises(KeyError, d.__getitem__, 23)
+
+        class Exc(Exception): pass
+
+        class BadHash(object):
+            fail = False
+            def __hash__(self):
+                if self.fail:
+                    raise Exc()
+                else:
+                    return 42
+
+        x = BadHash()
+        d[x] = 42
+        x.fail = True
+        self.assertRaises(Exc, d.__getitem__, x)
+
+    def test_clear(self):
+        d = {1:1, 2:2, 3:3}
+        d.clear()
+        self.assertEqual(d, {})
+
+        self.assertRaises(TypeError, d.clear, None)
+
+    def test_update(self):
+        d = {}
+        d.update({1:100})
+        d.update({2:20})
+        d.update({1:1, 2:2, 3:3})
+        self.assertEqual(d, {1:1, 2:2, 3:3})
+
+        d.update()
+        self.assertEqual(d, {1:1, 2:2, 3:3})
+
+        self.assertRaises((TypeError, AttributeError), d.update, None)
+
+        class SimpleUserDict:
+            def __init__(self):
+                self.d = {1:1, 2:2, 3:3}
+            def keys(self):
+                return self.d.keys()
+            def __getitem__(self, i):
+                return self.d[i]
+        d.clear()
+        d.update(SimpleUserDict())
+        self.assertEqual(d, {1:1, 2:2, 3:3})
+
+        class Exc(Exception): pass
+
+        d.clear()
+        class FailingUserDict:
+            def keys(self):
+                raise Exc
+        self.assertRaises(Exc, d.update, FailingUserDict())
+
+        class FailingUserDict:
+            def keys(self):
+                class BogonIter:
+                    def __init__(self):
+                        self.i = 1
+                    def __iter__(self):
+                        return self
+                    def next(self):
+                        if self.i:
+                            self.i = 0
+                            return 'a'
+                        raise Exc
+                return BogonIter()
+            def __getitem__(self, key):
+                return key
+        self.assertRaises(Exc, d.update, FailingUserDict())
+
+        class FailingUserDict:
+            def keys(self):
+                class BogonIter:
+                    def __init__(self):
+                        self.i = ord('a')
+                    def __iter__(self):
+                        return self
+                    def next(self):
+                        if self.i <= ord('z'):
+                            rtn = chr(self.i)
+                            self.i += 1
+                            return rtn
+                        raise StopIteration
+                return BogonIter()
+            def __getitem__(self, key):
+                raise Exc
+        self.assertRaises(Exc, d.update, FailingUserDict())
+
+        class badseq(object):
+            def __iter__(self):
+                return self
+            def next(self):
+                raise Exc()
+
+        self.assertRaises(Exc, {}.update, badseq())
+
+        self.assertRaises(ValueError, {}.update, [(1, 2, 3)])
+
+    def test_fromkeys(self):
+        self.assertEqual(dict.fromkeys('abc'), {'a':None, 'b':None, 'c':None})
+        d = {}
+        self.assert_(not(d.fromkeys('abc') is d))
+        self.assertEqual(d.fromkeys('abc'), {'a':None, 'b':None, 'c':None})
+        self.assertEqual(d.fromkeys((4,5),0), {4:0, 5:0})
+        self.assertEqual(d.fromkeys([]), {})
+        def g():
+            yield 1
+        self.assertEqual(d.fromkeys(g()), {1:None})
+        self.assertRaises(TypeError, {}.fromkeys, 3)
+        class dictlike(dict): pass
+        self.assertEqual(dictlike.fromkeys('a'), {'a':None})
+        self.assertEqual(dictlike().fromkeys('a'), {'a':None})
+        self.assert_(type(dictlike.fromkeys('a')) is dictlike)
+        self.assert_(type(dictlike().fromkeys('a')) is dictlike)
+        class mydict(dict):
+            def __new__(cls):
+                return UserDict.UserDict()
+        ud = mydict.fromkeys('ab')
+        self.assertEqual(ud, {'a':None, 'b':None})
+        self.assert_(isinstance(ud, UserDict.UserDict))
+        self.assertRaises(TypeError, dict.fromkeys)
+
+        class Exc(Exception): pass
+
+        class baddict1(dict):
+            def __init__(self):
+                raise Exc()
+
+        self.assertRaises(Exc, baddict1.fromkeys, [1])
+
+        class BadSeq(object):
+            def __iter__(self):
+                return self
+            def next(self):
+                raise Exc()
+
+        self.assertRaises(Exc, dict.fromkeys, BadSeq())
+
+        class baddict2(dict):
+            def __setitem__(self, key, value):
+                raise Exc()
+
+        self.assertRaises(Exc, baddict2.fromkeys, [1])
+
+    def test_copy(self):
+        d = {1:1, 2:2, 3:3}
+        self.assertEqual(d.copy(), {1:1, 2:2, 3:3})
+        self.assertEqual({}.copy(), {})
+        self.assertRaises(TypeError, d.copy, None)
+
+    def test_get(self):
+        d = {}
+        self.assert_(d.get('c') is None)
+        self.assertEqual(d.get('c', 3), 3)
+        d = {'a' : 1, 'b' : 2}
+        self.assert_(d.get('c') is None)
+        self.assertEqual(d.get('c', 3), 3)
+        self.assertEqual(d.get('a'), 1)
+        self.assertEqual(d.get('a', 3), 1)
+        self.assertRaises(TypeError, d.get)
+        self.assertRaises(TypeError, d.get, None, None, None)
+
+    def test_setdefault(self):
+        # dict.setdefault()
+        d = {}
+        self.assert_(d.setdefault('key0') is None)
+        d.setdefault('key0', [])
+        self.assert_(d.setdefault('key0') is None)
+        d.setdefault('key', []).append(3)
+        self.assertEqual(d['key'][0], 3)
+        d.setdefault('key', []).append(4)
+        self.assertEqual(len(d['key']), 2)
+        self.assertRaises(TypeError, d.setdefault)
+
+        class Exc(Exception): pass
+
+        class BadHash(object):
+            fail = False
+            def __hash__(self):
+                if self.fail:
+                    raise Exc()
+                else:
+                    return 42
+
+        x = BadHash()
+        d[x] = 42
+        x.fail = True
+        self.assertRaises(Exc, d.setdefault, x, [])
+
+    def test_popitem(self):
+        # dict.popitem()
+        for copymode in -1, +1:
+            # -1: b has same structure as a
+            # +1: b is a.copy()
+            for log2size in range(12):
+                size = 2**log2size
+                a = {}
+                b = {}
+                for i in range(size):
+                    a[repr(i)] = i
+                    if copymode < 0:
+                        b[repr(i)] = i
+                if copymode > 0:
+                    b = a.copy()
+                for i in range(size):
+                    ka, va = ta = a.popitem()
+                    self.assertEqual(va, int(ka))
+                    kb, vb = tb = b.popitem()
+                    self.assertEqual(vb, int(kb))
+                    self.assert_(not(copymode < 0 and ta != tb))
+                self.assert_(not a)
+                self.assert_(not b)
+
+        d = {}
+        self.assertRaises(KeyError, d.popitem)
+
+    def test_pop(self):
+        # Tests for pop with specified key
+        d = {}
+        k, v = 'abc', 'def'
+        d[k] = v
+        self.assertRaises(KeyError, d.pop, 'ghi')
+
+        self.assertEqual(d.pop(k), v)
+        self.assertEqual(len(d), 0)
+
+        self.assertRaises(KeyError, d.pop, k)
+
+        # verify longs/ints get same value when key > 32 bits (for 64-bit archs)
+        # see SF bug #689659
+        x = 4503599627370496L
+        y = 4503599627370496
+        h = {x: 'anything', y: 'something else'}
+        self.assertEqual(h[x], h[y])
+
+        self.assertEqual(d.pop(k, v), v)
+        d[k] = v
+        self.assertEqual(d.pop(k, 1), v)
+
+        self.assertRaises(TypeError, d.pop)
+
+        class Exc(Exception): pass
+
+        class BadHash(object):
+            fail = False
+            def __hash__(self):
+                if self.fail:
+                    raise Exc()
+                else:
+                    return 42
+
+        x = BadHash()
+        d[x] = 42
+        x.fail = True
+        self.assertRaises(Exc, d.pop, x)
+
+    def test_mutatingiteration(self):
+        d = {}
+        d[1] = 1
+        try:
+            for i in d:
+                d[i+1] = 1
+        except RuntimeError:
+            pass
+        else:
+            self.fail("changing dict size during iteration doesn't raise Error")
+
+    def test_repr(self):
+        d = {}
+        self.assertEqual(repr(d), '{}')
+        d[1] = 2
+        self.assertEqual(repr(d), '{1: 2}')
+        d = {}
+        d[1] = d
+        self.assertEqual(repr(d), '{1: {...}}')
+
+        class Exc(Exception): pass
+
+        class BadRepr(object):
+            def __repr__(self):
+                raise Exc()
+
+        d = {1: BadRepr()}
+        self.assertRaises(Exc, repr, d)
+
+    def test_le(self):
+        self.assert_(not ({} < {}))
+        self.assert_(not ({1: 2} < {1L: 2L}))
+
+        class Exc(Exception): pass
+
+        class BadCmp(object):
+            def __eq__(self, other):
+                raise Exc()
+
+        d1 = {BadCmp(): 1}
+        d2 = {1: 1}
+        try:
+            d1 < d2
+        except Exc:
+            pass
+        else:
+            self.fail("< didn't raise Exc")
+
+    def test_missing(self):
+        # Make sure dict doesn't have a __missing__ method
+        self.assertEqual(hasattr(dict, "__missing__"), False)
+        self.assertEqual(hasattr({}, "__missing__"), False)
+        # Test several cases:
+        # (D) subclass defines __missing__ method returning a value
+        # (E) subclass defines __missing__ method raising RuntimeError
+        # (F) subclass sets __missing__ instance variable (no effect)
+        # (G) subclass doesn't define __missing__ at a all
+        class D(dict):
+            def __missing__(self, key):
+                return 42
+        d = D({1: 2, 3: 4})
+        self.assertEqual(d[1], 2)
+        self.assertEqual(d[3], 4)
+        self.assert_(2 not in d)
+        self.assert_(2 not in d.keys())
+        self.assertEqual(d[2], 42)
+        class E(dict):
+            def __missing__(self, key):
+                raise RuntimeError(key)
+        e = E()
+        try:
+            e[42]
+        except RuntimeError, err:
+            self.assertEqual(err.args, (42,))
+        else:
+            self.fail("e[42] didn't raise RuntimeError")
+        class F(dict):
+            def __init__(self):
+                # An instance variable __missing__ should have no effect
+                self.__missing__ = lambda key: None
+        f = F()
+        try:
+            f[42]
+        except KeyError, err:
+            self.assertEqual(err.args, (42,))
+        else:
+            self.fail("f[42] didn't raise KeyError")
+        class G(dict):
+            pass
+        g = G()
+        try:
+            g[42]
+        except KeyError, err:
+            self.assertEqual(err.args, (42,))
+        else:
+            self.fail("g[42] didn't raise KeyError")
+
+    def test_tuple_keyerror(self):
+        # SF #1576657
+        d = {}
+        try:
+            d[(1,)]
+        except KeyError, e:
+            self.assertEqual(e.args, ((1,),))
+        else:
+            self.fail("missing KeyError")
+
+
+from test import mapping_tests
+
+class GeneralMappingTests(mapping_tests.BasicTestMappingProtocol):
+    type2test = dict
+
+class Dict(dict):
+    pass
+
+class SubclassMappingTests(mapping_tests.BasicTestMappingProtocol):
+    type2test = Dict
+
+def test_main():
+    test_support.run_unittest(
+        DictTest,
+        GeneralMappingTests,
+        SubclassMappingTests,
+    )
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_difflib.py
===================================================================
--- vendor/Python/current/Lib/test/test_difflib.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_difflib.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,161 @@
+import difflib
+from test.test_support import run_unittest, findfile
+import unittest
+import doctest
+import sys
+
+class TestSFbugs(unittest.TestCase):
+
+    def test_ratio_for_null_seqn(self):
+        # Check clearing of SF bug 763023
+        s = difflib.SequenceMatcher(None, [], [])
+        self.assertEqual(s.ratio(), 1)
+        self.assertEqual(s.quick_ratio(), 1)
+        self.assertEqual(s.real_quick_ratio(), 1)
+
+    def test_comparing_empty_lists(self):
+        # Check fix for bug #979794
+        group_gen = difflib.SequenceMatcher(None, [], []).get_grouped_opcodes()
+        self.assertRaises(StopIteration, group_gen.next)
+        diff_gen = difflib.unified_diff([], [])
+        self.assertRaises(StopIteration, diff_gen.next)
+
+patch914575_from1 = """
+   1. Beautiful is beTTer than ugly.
+   2. Explicit is better than implicit.
+   3. Simple is better than complex.
+   4. Complex is better than complicated.
+"""
+
+patch914575_to1 = """
+   1. Beautiful is better than ugly.
+   3.   Simple is better than complex.
+   4. Complicated is better than complex.
+   5. Flat is better than nested.
+"""
+
+patch914575_from2 = """
+\t\tLine 1: preceeded by from:[tt] to:[ssss]
+  \t\tLine 2: preceeded by from:[sstt] to:[sssst]
+  \t \tLine 3: preceeded by from:[sstst] to:[ssssss]
+Line 4:  \thas from:[sst] to:[sss] after :
+Line 5: has from:[t] to:[ss] at end\t
+"""
+
+patch914575_to2 = """
+    Line 1: preceeded by from:[tt] to:[ssss]
+    \tLine 2: preceeded by from:[sstt] to:[sssst]
+      Line 3: preceeded by from:[sstst] to:[ssssss]
+Line 4:   has from:[sst] to:[sss] after :
+Line 5: has from:[t] to:[ss] at end
+"""
+
+patch914575_from3 = """line 0
+1234567890123456789012345689012345
+line 1
+line 2
+line 3
+line 4   changed
+line 5   changed
+line 6   changed
+line 7
+line 8  subtracted
+line 9
+1234567890123456789012345689012345
+short line
+just fits in!!
+just fits in two lines yup!!
+the end"""
+
+patch914575_to3 = """line 0
+1234567890123456789012345689012345
+line 1
+line 2    added
+line 3
+line 4   chanGEd
+line 5a  chanGed
+line 6a  changEd
+line 7
+line 8
+line 9
+1234567890
+another long line that needs to be wrapped
+just fitS in!!
+just fits in two lineS yup!!
+the end"""
+
+class TestSFpatches(unittest.TestCase):
+
+    def test_html_diff(self):
+        # Check SF patch 914575 for generating HTML differences
+        f1a = ((patch914575_from1 + '123\n'*10)*3)
+        t1a = (patch914575_to1 + '123\n'*10)*3
+        f1b = '456\n'*10 + f1a
+        t1b = '456\n'*10 + t1a
+        f1a = f1a.splitlines()
+        t1a = t1a.splitlines()
+        f1b = f1b.splitlines()
+        t1b = t1b.splitlines()
+        f2 = patch914575_from2.splitlines()
+        t2 = patch914575_to2.splitlines()
+        f3 = patch914575_from3
+        t3 = patch914575_to3
+        i = difflib.HtmlDiff()
+        j = difflib.HtmlDiff(tabsize=2)
+        k = difflib.HtmlDiff(wrapcolumn=14)
+
+        full = i.make_file(f1a,t1a,'from','to',context=False,numlines=5)
+        tables = '\n'.join(
+            [
+             '<h2>Context (first diff within numlines=5(default))</h2>',
+             i.make_table(f1a,t1a,'from','to',context=True),
+             '<h2>Context (first diff after numlines=5(default))</h2>',
+             i.make_table(f1b,t1b,'from','to',context=True),
+             '<h2>Context (numlines=6)</h2>',
+             i.make_table(f1a,t1a,'from','to',context=True,numlines=6),
+             '<h2>Context (numlines=0)</h2>',
+             i.make_table(f1a,t1a,'from','to',context=True,numlines=0),
+             '<h2>Same Context</h2>',
+             i.make_table(f1a,f1a,'from','to',context=True),
+             '<h2>Same Full</h2>',
+             i.make_table(f1a,f1a,'from','to',context=False),
+             '<h2>Empty Context</h2>',
+             i.make_table([],[],'from','to',context=True),
+             '<h2>Empty Full</h2>',
+             i.make_table([],[],'from','to',context=False),
+             '<h2>tabsize=2</h2>',
+             j.make_table(f2,t2),
+             '<h2>tabsize=default</h2>',
+             i.make_table(f2,t2),
+             '<h2>Context (wrapcolumn=14,numlines=0)</h2>',
+             k.make_table(f3.splitlines(),t3.splitlines(),context=True,numlines=0),
+             '<h2>wrapcolumn=14,splitlines()</h2>',
+             k.make_table(f3.splitlines(),t3.splitlines()),
+             '<h2>wrapcolumn=14,splitlines(True)</h2>',
+             k.make_table(f3.splitlines(True),t3.splitlines(True)),
+             ])
+        actual = full.replace('</body>','\n%s\n</body>' % tables)
+        # temporarily uncomment next three lines to baseline this test
+        #f = open('test_difflib_expect.html','w')
+        #f.write(actual)
+        #f.close()
+        expect = open(findfile('test_difflib_expect.html')).read()
+
+
+        self.assertEqual(actual,expect)
+
+    def test_recursion_limit(self):
+        # Check if the problem described in patch #1413711 exists.
+        limit = sys.getrecursionlimit()
+        old = [(i%2 and "K:%d" or "V:A:%d") % i for i in range(limit*2)]
+        new = [(i%2 and "K:%d" or "V:B:%d") % i for i in range(limit*2)]
+        difflib.SequenceMatcher(None, old, new).get_opcodes()
+
+
+def test_main():
+    difflib.HtmlDiff._default_prefix = 0
+    Doctests = doctest.DocTestSuite(difflib)
+    run_unittest(TestSFpatches, TestSFbugs, Doctests)
+
+if __name__ == '__main__':
+    test_main()

Added: vendor/Python/current/Lib/test/test_difflib_expect.html
===================================================================
--- vendor/Python/current/Lib/test/test_difflib_expect.html	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_difflib_expect.html	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,526 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html>
+
+<head>
+    <meta http-equiv="Content-Type"
+          content="text/html; charset=ISO-8859-1" />
+    <title></title>
+    <style type="text/css">
+        table.diff {font-family:Courier; border:medium;}
+        .diff_header {background-color:#e0e0e0}
+        td.diff_header {text-align:right}
+        .diff_next {background-color:#c0c0c0}
+        .diff_add {background-color:#aaffaa}
+        .diff_chg {background-color:#ffff77}
+        .diff_sub {background-color:#ffaaaa}
+    </style>
+</head>
+
+<body>
+    
+    <table class="diff" id="difflib_chg_to0__top"
+           cellspacing="0" cellpadding="0" rules="groups" >
+        <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup>
+        <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup>
+        <thead><tr><th class="diff_next"><br /></th><th colspan="2" class="diff_header">from</th><th class="diff_next"><br /></th><th colspan="2" class="diff_header">to</th></tr></thead>
+        <tbody>
+            <tr><td class="diff_next" id="difflib_chg_to0__0"><a href="#difflib_chg_to0__0">f</a></td><td class="diff_header" id="from0_1">1</td><td nowrap="nowrap"></td><td class="diff_next"><a href="#difflib_chg_to0__0">f</a></td><td class="diff_header" id="to0_1">1</td><td nowrap="nowrap"></td></tr>
+            <tr><td class="diff_next"><a href="#difflib_chg_to0__1">n</a></td><td class="diff_header" id="from0_2">2</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;1.&nbsp;Beautiful&nbsp;is&nbsp;be<span class="diff_chg">TT</span>er&nbsp;than&nbsp;ugly.</td><td class="diff_next"><a href="#difflib_chg_to0__1">n</a></td><td class="diff_header" id="to0_2">2</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;1.&nbsp;Beautiful&nbsp;is&nbsp;be<span class="diff_chg">tt</span>er&nbsp;than&nbsp;ugly.</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from0_3">3</td><td nowrap="nowrap"><span class="diff_sub">&nbsp;&nbsp;&nbsp;2.&nbsp;Explicit&nbsp;is&nbsp;better&nbsp;than&nbsp;implicit.</span></td><td class="diff_next"></td><td class="diff_header"></td><td nowrap="nowrap"></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from0_4">4</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;3.&nbsp;Simple&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</td><td class="diff_next"></td><td class="diff_header" id="to0_3">3</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;3.<span class="diff_add">&nbsp;&nbsp;</span>&nbsp;Simple&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from0_5">5</td><td nowrap="nowrap"><span class="diff_sub">&nbsp;&nbsp;&nbsp;4.&nbsp;Complex&nbsp;is&nbsp;better&nbsp;than&nbsp;complicated.</span></td><td class="diff_next"></td><td class="diff_header" id="to0_4">4</td><td nowrap="nowrap"><span class="diff_add">&nbsp;&nbsp;&nbsp;4.&nbsp;Complicated&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header"></td><td nowrap="nowrap"></td><td class="diff_next"></td><td class="diff_header" id="to0_5">5</td><td nowrap="nowrap"><span class="diff_add">&nbsp;&nbsp;&nbsp;5.&nbsp;Flat&nbsp;is&nbsp;better&nbsp;than&nbsp;nested.</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from0_6">6</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to0_6">6</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from0_7">7</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to0_7">7</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from0_8">8</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to0_8">8</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from0_9">9</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to0_9">9</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from0_10">10</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to0_10">10</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from0_11">11</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to0_11">11</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next" id="difflib_chg_to0__1"></td><td class="diff_header" id="from0_12">12</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to0_12">12</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from0_13">13</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to0_13">13</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from0_14">14</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to0_14">14</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from0_15">15</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to0_15">15</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from0_16">16</td><td nowrap="nowrap"></td><td class="diff_next"></td><td class="diff_header" id="to0_16">16</td><td nowrap="nowrap"></td></tr>
+            <tr><td class="diff_next"><a href="#difflib_chg_to0__2">n</a></td><td class="diff_header" id="from0_17">17</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;1.&nbsp;Beautiful&nbsp;is&nbsp;be<span class="diff_chg">TT</span>er&nbsp;than&nbsp;ugly.</td><td class="diff_next"><a href="#difflib_chg_to0__2">n</a></td><td class="diff_header" id="to0_17">17</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;1.&nbsp;Beautiful&nbsp;is&nbsp;be<span class="diff_chg">tt</span>er&nbsp;than&nbsp;ugly.</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from0_18">18</td><td nowrap="nowrap"><span class="diff_sub">&nbsp;&nbsp;&nbsp;2.&nbsp;Explicit&nbsp;is&nbsp;better&nbsp;than&nbsp;implicit.</span></td><td class="diff_next"></td><td class="diff_header"></td><td nowrap="nowrap"></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from0_19">19</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;3.&nbsp;Simple&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</td><td class="diff_next"></td><td class="diff_header" id="to0_18">18</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;3.<span class="diff_add">&nbsp;&nbsp;</span>&nbsp;Simple&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from0_20">20</td><td nowrap="nowrap"><span class="diff_sub">&nbsp;&nbsp;&nbsp;4.&nbsp;Complex&nbsp;is&nbsp;better&nbsp;than&nbsp;complicated.</span></td><td class="diff_next"></td><td class="diff_header" id="to0_19">19</td><td nowrap="nowrap"><span class="diff_add">&nbsp;&nbsp;&nbsp;4.&nbsp;Complicated&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header"></td><td nowrap="nowrap"></td><td class="diff_next"></td><td class="diff_header" id="to0_20">20</td><td nowrap="nowrap"><span class="diff_add">&nbsp;&nbsp;&nbsp;5.&nbsp;Flat&nbsp;is&nbsp;better&nbsp;than&nbsp;nested.</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from0_21">21</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to0_21">21</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from0_22">22</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to0_22">22</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from0_23">23</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to0_23">23</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from0_24">24</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to0_24">24</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from0_25">25</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to0_25">25</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from0_26">26</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to0_26">26</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next" id="difflib_chg_to0__2"></td><td class="diff_header" id="from0_27">27</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to0_27">27</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from0_28">28</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to0_28">28</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from0_29">29</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to0_29">29</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from0_30">30</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to0_30">30</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from0_31">31</td><td nowrap="nowrap"></td><td class="diff_next"></td><td class="diff_header" id="to0_31">31</td><td nowrap="nowrap"></td></tr>
+            <tr><td class="diff_next"><a href="#difflib_chg_to0__top">t</a></td><td class="diff_header" id="from0_32">32</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;1.&nbsp;Beautiful&nbsp;is&nbsp;be<span class="diff_chg">TT</span>er&nbsp;than&nbsp;ugly.</td><td class="diff_next"><a href="#difflib_chg_to0__top">t</a></td><td class="diff_header" id="to0_32">32</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;1.&nbsp;Beautiful&nbsp;is&nbsp;be<span class="diff_chg">tt</span>er&nbsp;than&nbsp;ugly.</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from0_33">33</td><td nowrap="nowrap"><span class="diff_sub">&nbsp;&nbsp;&nbsp;2.&nbsp;Explicit&nbsp;is&nbsp;better&nbsp;than&nbsp;implicit.</span></td><td class="diff_next"></td><td class="diff_header"></td><td nowrap="nowrap"></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from0_34">34</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;3.&nbsp;Simple&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</td><td class="diff_next"></td><td class="diff_header" id="to0_33">33</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;3.<span class="diff_add">&nbsp;&nbsp;</span>&nbsp;Simple&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from0_35">35</td><td nowrap="nowrap"><span class="diff_sub">&nbsp;&nbsp;&nbsp;4.&nbsp;Complex&nbsp;is&nbsp;better&nbsp;than&nbsp;complicated.</span></td><td class="diff_next"></td><td class="diff_header" id="to0_34">34</td><td nowrap="nowrap"><span class="diff_add">&nbsp;&nbsp;&nbsp;4.&nbsp;Complicated&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header"></td><td nowrap="nowrap"></td><td class="diff_next"></td><td class="diff_header" id="to0_35">35</td><td nowrap="nowrap"><span class="diff_add">&nbsp;&nbsp;&nbsp;5.&nbsp;Flat&nbsp;is&nbsp;better&nbsp;than&nbsp;nested.</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from0_36">36</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to0_36">36</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from0_37">37</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to0_37">37</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from0_38">38</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to0_38">38</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from0_39">39</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to0_39">39</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from0_40">40</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to0_40">40</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from0_41">41</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to0_41">41</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from0_42">42</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to0_42">42</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from0_43">43</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to0_43">43</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from0_44">44</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to0_44">44</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from0_45">45</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to0_45">45</td><td nowrap="nowrap">123</td></tr>
+        </tbody>
+    </table>
+    <table class="diff" summary="Legends">
+        <tr> <th colspan="2"> Legends </th> </tr>
+        <tr> <td> <table border="" summary="Colors">
+                      <tr><th> Colors </th> </tr>
+                      <tr><td class="diff_add">&nbsp;Added&nbsp;</td></tr>
+                      <tr><td class="diff_chg">Changed</td> </tr>
+                      <tr><td class="diff_sub">Deleted</td> </tr>
+                  </table></td>
+             <td> <table border="" summary="Links">
+                      <tr><th colspan="2"> Links </th> </tr>
+                      <tr><td>(f)irst change</td> </tr>
+                      <tr><td>(n)ext change</td> </tr>
+                      <tr><td>(t)op</td> </tr>
+                  </table></td> </tr>
+    </table>
+
+<h2>Context (first diff within numlines=5(default))</h2>
+
+    <table class="diff" id="difflib_chg_to1__top"
+           cellspacing="0" cellpadding="0" rules="groups" >
+        <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup>
+        <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup>
+        <thead><tr><th class="diff_next"><br /></th><th colspan="2" class="diff_header">from</th><th class="diff_next"><br /></th><th colspan="2" class="diff_header">to</th></tr></thead>
+        <tbody>
+            <tr><td class="diff_next" id="difflib_chg_to1__0"><a href="#difflib_chg_to1__0">f</a></td><td class="diff_header" id="from1_1">1</td><td nowrap="nowrap"></td><td class="diff_next"><a href="#difflib_chg_to1__0">f</a></td><td class="diff_header" id="to1_1">1</td><td nowrap="nowrap"></td></tr>
+            <tr><td class="diff_next"><a href="#difflib_chg_to1__1">n</a></td><td class="diff_header" id="from1_2">2</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;1.&nbsp;Beautiful&nbsp;is&nbsp;be<span class="diff_chg">TT</span>er&nbsp;than&nbsp;ugly.</td><td class="diff_next"><a href="#difflib_chg_to1__1">n</a></td><td class="diff_header" id="to1_2">2</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;1.&nbsp;Beautiful&nbsp;is&nbsp;be<span class="diff_chg">tt</span>er&nbsp;than&nbsp;ugly.</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from1_3">3</td><td nowrap="nowrap"><span class="diff_sub">&nbsp;&nbsp;&nbsp;2.&nbsp;Explicit&nbsp;is&nbsp;better&nbsp;than&nbsp;implicit.</span></td><td class="diff_next"></td><td class="diff_header"></td><td nowrap="nowrap"></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from1_4">4</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;3.&nbsp;Simple&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</td><td class="diff_next"></td><td class="diff_header" id="to1_3">3</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;3.<span class="diff_add">&nbsp;&nbsp;</span>&nbsp;Simple&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from1_5">5</td><td nowrap="nowrap"><span class="diff_sub">&nbsp;&nbsp;&nbsp;4.&nbsp;Complex&nbsp;is&nbsp;better&nbsp;than&nbsp;complicated.</span></td><td class="diff_next"></td><td class="diff_header" id="to1_4">4</td><td nowrap="nowrap"><span class="diff_add">&nbsp;&nbsp;&nbsp;4.&nbsp;Complicated&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header"></td><td nowrap="nowrap"></td><td class="diff_next"></td><td class="diff_header" id="to1_5">5</td><td nowrap="nowrap"><span class="diff_add">&nbsp;&nbsp;&nbsp;5.&nbsp;Flat&nbsp;is&nbsp;better&nbsp;than&nbsp;nested.</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from1_6">6</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to1_6">6</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from1_7">7</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to1_7">7</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from1_8">8</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to1_8">8</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from1_9">9</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to1_9">9</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from1_10">10</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to1_10">10</td><td nowrap="nowrap">123</td></tr>
+        </tbody>        
+        <tbody>
+            <tr><td class="diff_next" id="difflib_chg_to1__1"></td><td class="diff_header" id="from1_12">12</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to1_12">12</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from1_13">13</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to1_13">13</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from1_14">14</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to1_14">14</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from1_15">15</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to1_15">15</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from1_16">16</td><td nowrap="nowrap"></td><td class="diff_next"></td><td class="diff_header" id="to1_16">16</td><td nowrap="nowrap"></td></tr>
+            <tr><td class="diff_next"><a href="#difflib_chg_to1__2">n</a></td><td class="diff_header" id="from1_17">17</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;1.&nbsp;Beautiful&nbsp;is&nbsp;be<span class="diff_chg">TT</span>er&nbsp;than&nbsp;ugly.</td><td class="diff_next"><a href="#difflib_chg_to1__2">n</a></td><td class="diff_header" id="to1_17">17</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;1.&nbsp;Beautiful&nbsp;is&nbsp;be<span class="diff_chg">tt</span>er&nbsp;than&nbsp;ugly.</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from1_18">18</td><td nowrap="nowrap"><span class="diff_sub">&nbsp;&nbsp;&nbsp;2.&nbsp;Explicit&nbsp;is&nbsp;better&nbsp;than&nbsp;implicit.</span></td><td class="diff_next"></td><td class="diff_header"></td><td nowrap="nowrap"></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from1_19">19</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;3.&nbsp;Simple&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</td><td class="diff_next"></td><td class="diff_header" id="to1_18">18</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;3.<span class="diff_add">&nbsp;&nbsp;</span>&nbsp;Simple&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from1_20">20</td><td nowrap="nowrap"><span class="diff_sub">&nbsp;&nbsp;&nbsp;4.&nbsp;Complex&nbsp;is&nbsp;better&nbsp;than&nbsp;complicated.</span></td><td class="diff_next"></td><td class="diff_header" id="to1_19">19</td><td nowrap="nowrap"><span class="diff_add">&nbsp;&nbsp;&nbsp;4.&nbsp;Complicated&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header"></td><td nowrap="nowrap"></td><td class="diff_next"></td><td class="diff_header" id="to1_20">20</td><td nowrap="nowrap"><span class="diff_add">&nbsp;&nbsp;&nbsp;5.&nbsp;Flat&nbsp;is&nbsp;better&nbsp;than&nbsp;nested.</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from1_21">21</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to1_21">21</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from1_22">22</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to1_22">22</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from1_23">23</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to1_23">23</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from1_24">24</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to1_24">24</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from1_25">25</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to1_25">25</td><td nowrap="nowrap">123</td></tr>
+        </tbody>        
+        <tbody>
+            <tr><td class="diff_next" id="difflib_chg_to1__2"></td><td class="diff_header" id="from1_27">27</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to1_27">27</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from1_28">28</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to1_28">28</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from1_29">29</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to1_29">29</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from1_30">30</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to1_30">30</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from1_31">31</td><td nowrap="nowrap"></td><td class="diff_next"></td><td class="diff_header" id="to1_31">31</td><td nowrap="nowrap"></td></tr>
+            <tr><td class="diff_next"><a href="#difflib_chg_to1__top">t</a></td><td class="diff_header" id="from1_32">32</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;1.&nbsp;Beautiful&nbsp;is&nbsp;be<span class="diff_chg">TT</span>er&nbsp;than&nbsp;ugly.</td><td class="diff_next"><a href="#difflib_chg_to1__top">t</a></td><td class="diff_header" id="to1_32">32</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;1.&nbsp;Beautiful&nbsp;is&nbsp;be<span class="diff_chg">tt</span>er&nbsp;than&nbsp;ugly.</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from1_33">33</td><td nowrap="nowrap"><span class="diff_sub">&nbsp;&nbsp;&nbsp;2.&nbsp;Explicit&nbsp;is&nbsp;better&nbsp;than&nbsp;implicit.</span></td><td class="diff_next"></td><td class="diff_header"></td><td nowrap="nowrap"></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from1_34">34</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;3.&nbsp;Simple&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</td><td class="diff_next"></td><td class="diff_header" id="to1_33">33</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;3.<span class="diff_add">&nbsp;&nbsp;</span>&nbsp;Simple&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from1_35">35</td><td nowrap="nowrap"><span class="diff_sub">&nbsp;&nbsp;&nbsp;4.&nbsp;Complex&nbsp;is&nbsp;better&nbsp;than&nbsp;complicated.</span></td><td class="diff_next"></td><td class="diff_header" id="to1_34">34</td><td nowrap="nowrap"><span class="diff_add">&nbsp;&nbsp;&nbsp;4.&nbsp;Complicated&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header"></td><td nowrap="nowrap"></td><td class="diff_next"></td><td class="diff_header" id="to1_35">35</td><td nowrap="nowrap"><span class="diff_add">&nbsp;&nbsp;&nbsp;5.&nbsp;Flat&nbsp;is&nbsp;better&nbsp;than&nbsp;nested.</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from1_36">36</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to1_36">36</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from1_37">37</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to1_37">37</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from1_38">38</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to1_38">38</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from1_39">39</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to1_39">39</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from1_40">40</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to1_40">40</td><td nowrap="nowrap">123</td></tr>
+        </tbody>
+    </table>
+<h2>Context (first diff after numlines=5(default))</h2>
+
+    <table class="diff" id="difflib_chg_to2__top"
+           cellspacing="0" cellpadding="0" rules="groups" >
+        <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup>
+        <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup>
+        <thead><tr><th class="diff_next"><br /></th><th colspan="2" class="diff_header">from</th><th class="diff_next"><br /></th><th colspan="2" class="diff_header">to</th></tr></thead>
+        <tbody>
+            <tr><td class="diff_next" id="difflib_chg_to2__0"></td><td class="diff_header" id="from2_7">7</td><td nowrap="nowrap">456</td><td class="diff_next"></td><td class="diff_header" id="to2_7">7</td><td nowrap="nowrap">456</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from2_8">8</td><td nowrap="nowrap">456</td><td class="diff_next"></td><td class="diff_header" id="to2_8">8</td><td nowrap="nowrap">456</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from2_9">9</td><td nowrap="nowrap">456</td><td class="diff_next"></td><td class="diff_header" id="to2_9">9</td><td nowrap="nowrap">456</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from2_10">10</td><td nowrap="nowrap">456</td><td class="diff_next"></td><td class="diff_header" id="to2_10">10</td><td nowrap="nowrap">456</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from2_11">11</td><td nowrap="nowrap"></td><td class="diff_next"></td><td class="diff_header" id="to2_11">11</td><td nowrap="nowrap"></td></tr>
+            <tr><td class="diff_next"><a href="#difflib_chg_to2__1">n</a></td><td class="diff_header" id="from2_12">12</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;1.&nbsp;Beautiful&nbsp;is&nbsp;be<span class="diff_chg">TT</span>er&nbsp;than&nbsp;ugly.</td><td class="diff_next"><a href="#difflib_chg_to2__1">n</a></td><td class="diff_header" id="to2_12">12</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;1.&nbsp;Beautiful&nbsp;is&nbsp;be<span class="diff_chg">tt</span>er&nbsp;than&nbsp;ugly.</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from2_13">13</td><td nowrap="nowrap"><span class="diff_sub">&nbsp;&nbsp;&nbsp;2.&nbsp;Explicit&nbsp;is&nbsp;better&nbsp;than&nbsp;implicit.</span></td><td class="diff_next"></td><td class="diff_header"></td><td nowrap="nowrap"></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from2_14">14</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;3.&nbsp;Simple&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</td><td class="diff_next"></td><td class="diff_header" id="to2_13">13</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;3.<span class="diff_add">&nbsp;&nbsp;</span>&nbsp;Simple&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from2_15">15</td><td nowrap="nowrap"><span class="diff_sub">&nbsp;&nbsp;&nbsp;4.&nbsp;Complex&nbsp;is&nbsp;better&nbsp;than&nbsp;complicated.</span></td><td class="diff_next"></td><td class="diff_header" id="to2_14">14</td><td nowrap="nowrap"><span class="diff_add">&nbsp;&nbsp;&nbsp;4.&nbsp;Complicated&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header"></td><td nowrap="nowrap"></td><td class="diff_next"></td><td class="diff_header" id="to2_15">15</td><td nowrap="nowrap"><span class="diff_add">&nbsp;&nbsp;&nbsp;5.&nbsp;Flat&nbsp;is&nbsp;better&nbsp;than&nbsp;nested.</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from2_16">16</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to2_16">16</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from2_17">17</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to2_17">17</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from2_18">18</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to2_18">18</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from2_19">19</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to2_19">19</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from2_20">20</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to2_20">20</td><td nowrap="nowrap">123</td></tr>
+        </tbody>        
+        <tbody>
+            <tr><td class="diff_next" id="difflib_chg_to2__1"></td><td class="diff_header" id="from2_22">22</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to2_22">22</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from2_23">23</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to2_23">23</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from2_24">24</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to2_24">24</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from2_25">25</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to2_25">25</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from2_26">26</td><td nowrap="nowrap"></td><td class="diff_next"></td><td class="diff_header" id="to2_26">26</td><td nowrap="nowrap"></td></tr>
+            <tr><td class="diff_next"><a href="#difflib_chg_to2__2">n</a></td><td class="diff_header" id="from2_27">27</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;1.&nbsp;Beautiful&nbsp;is&nbsp;be<span class="diff_chg">TT</span>er&nbsp;than&nbsp;ugly.</td><td class="diff_next"><a href="#difflib_chg_to2__2">n</a></td><td class="diff_header" id="to2_27">27</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;1.&nbsp;Beautiful&nbsp;is&nbsp;be<span class="diff_chg">tt</span>er&nbsp;than&nbsp;ugly.</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from2_28">28</td><td nowrap="nowrap"><span class="diff_sub">&nbsp;&nbsp;&nbsp;2.&nbsp;Explicit&nbsp;is&nbsp;better&nbsp;than&nbsp;implicit.</span></td><td class="diff_next"></td><td class="diff_header"></td><td nowrap="nowrap"></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from2_29">29</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;3.&nbsp;Simple&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</td><td class="diff_next"></td><td class="diff_header" id="to2_28">28</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;3.<span class="diff_add">&nbsp;&nbsp;</span>&nbsp;Simple&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from2_30">30</td><td nowrap="nowrap"><span class="diff_sub">&nbsp;&nbsp;&nbsp;4.&nbsp;Complex&nbsp;is&nbsp;better&nbsp;than&nbsp;complicated.</span></td><td class="diff_next"></td><td class="diff_header" id="to2_29">29</td><td nowrap="nowrap"><span class="diff_add">&nbsp;&nbsp;&nbsp;4.&nbsp;Complicated&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header"></td><td nowrap="nowrap"></td><td class="diff_next"></td><td class="diff_header" id="to2_30">30</td><td nowrap="nowrap"><span class="diff_add">&nbsp;&nbsp;&nbsp;5.&nbsp;Flat&nbsp;is&nbsp;better&nbsp;than&nbsp;nested.</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from2_31">31</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to2_31">31</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from2_32">32</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to2_32">32</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from2_33">33</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to2_33">33</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from2_34">34</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to2_34">34</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from2_35">35</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to2_35">35</td><td nowrap="nowrap">123</td></tr>
+        </tbody>        
+        <tbody>
+            <tr><td class="diff_next" id="difflib_chg_to2__2"></td><td class="diff_header" id="from2_37">37</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to2_37">37</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from2_38">38</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to2_38">38</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from2_39">39</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to2_39">39</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from2_40">40</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to2_40">40</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from2_41">41</td><td nowrap="nowrap"></td><td class="diff_next"></td><td class="diff_header" id="to2_41">41</td><td nowrap="nowrap"></td></tr>
+            <tr><td class="diff_next"><a href="#difflib_chg_to2__top">t</a></td><td class="diff_header" id="from2_42">42</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;1.&nbsp;Beautiful&nbsp;is&nbsp;be<span class="diff_chg">TT</span>er&nbsp;than&nbsp;ugly.</td><td class="diff_next"><a href="#difflib_chg_to2__top">t</a></td><td class="diff_header" id="to2_42">42</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;1.&nbsp;Beautiful&nbsp;is&nbsp;be<span class="diff_chg">tt</span>er&nbsp;than&nbsp;ugly.</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from2_43">43</td><td nowrap="nowrap"><span class="diff_sub">&nbsp;&nbsp;&nbsp;2.&nbsp;Explicit&nbsp;is&nbsp;better&nbsp;than&nbsp;implicit.</span></td><td class="diff_next"></td><td class="diff_header"></td><td nowrap="nowrap"></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from2_44">44</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;3.&nbsp;Simple&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</td><td class="diff_next"></td><td class="diff_header" id="to2_43">43</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;3.<span class="diff_add">&nbsp;&nbsp;</span>&nbsp;Simple&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from2_45">45</td><td nowrap="nowrap"><span class="diff_sub">&nbsp;&nbsp;&nbsp;4.&nbsp;Complex&nbsp;is&nbsp;better&nbsp;than&nbsp;complicated.</span></td><td class="diff_next"></td><td class="diff_header" id="to2_44">44</td><td nowrap="nowrap"><span class="diff_add">&nbsp;&nbsp;&nbsp;4.&nbsp;Complicated&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header"></td><td nowrap="nowrap"></td><td class="diff_next"></td><td class="diff_header" id="to2_45">45</td><td nowrap="nowrap"><span class="diff_add">&nbsp;&nbsp;&nbsp;5.&nbsp;Flat&nbsp;is&nbsp;better&nbsp;than&nbsp;nested.</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from2_46">46</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to2_46">46</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from2_47">47</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to2_47">47</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from2_48">48</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to2_48">48</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from2_49">49</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to2_49">49</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from2_50">50</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to2_50">50</td><td nowrap="nowrap">123</td></tr>
+        </tbody>
+    </table>
+<h2>Context (numlines=6)</h2>
+
+    <table class="diff" id="difflib_chg_to3__top"
+           cellspacing="0" cellpadding="0" rules="groups" >
+        <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup>
+        <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup>
+        <thead><tr><th class="diff_next"><br /></th><th colspan="2" class="diff_header">from</th><th class="diff_next"><br /></th><th colspan="2" class="diff_header">to</th></tr></thead>
+        <tbody>
+            <tr><td class="diff_next" id="difflib_chg_to3__0"><a href="#difflib_chg_to3__0">f</a></td><td class="diff_header" id="from3_1">1</td><td nowrap="nowrap"></td><td class="diff_next"><a href="#difflib_chg_to3__0">f</a></td><td class="diff_header" id="to3_1">1</td><td nowrap="nowrap"></td></tr>
+            <tr><td class="diff_next"><a href="#difflib_chg_to3__1">n</a></td><td class="diff_header" id="from3_2">2</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;1.&nbsp;Beautiful&nbsp;is&nbsp;be<span class="diff_chg">TT</span>er&nbsp;than&nbsp;ugly.</td><td class="diff_next"><a href="#difflib_chg_to3__1">n</a></td><td class="diff_header" id="to3_2">2</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;1.&nbsp;Beautiful&nbsp;is&nbsp;be<span class="diff_chg">tt</span>er&nbsp;than&nbsp;ugly.</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from3_3">3</td><td nowrap="nowrap"><span class="diff_sub">&nbsp;&nbsp;&nbsp;2.&nbsp;Explicit&nbsp;is&nbsp;better&nbsp;than&nbsp;implicit.</span></td><td class="diff_next"></td><td class="diff_header"></td><td nowrap="nowrap"></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from3_4">4</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;3.&nbsp;Simple&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</td><td class="diff_next"></td><td class="diff_header" id="to3_3">3</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;3.<span class="diff_add">&nbsp;&nbsp;</span>&nbsp;Simple&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from3_5">5</td><td nowrap="nowrap"><span class="diff_sub">&nbsp;&nbsp;&nbsp;4.&nbsp;Complex&nbsp;is&nbsp;better&nbsp;than&nbsp;complicated.</span></td><td class="diff_next"></td><td class="diff_header" id="to3_4">4</td><td nowrap="nowrap"><span class="diff_add">&nbsp;&nbsp;&nbsp;4.&nbsp;Complicated&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header"></td><td nowrap="nowrap"></td><td class="diff_next"></td><td class="diff_header" id="to3_5">5</td><td nowrap="nowrap"><span class="diff_add">&nbsp;&nbsp;&nbsp;5.&nbsp;Flat&nbsp;is&nbsp;better&nbsp;than&nbsp;nested.</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from3_6">6</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to3_6">6</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from3_7">7</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to3_7">7</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from3_8">8</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to3_8">8</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from3_9">9</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to3_9">9</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from3_10">10</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to3_10">10</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next" id="difflib_chg_to3__1"></td><td class="diff_header" id="from3_11">11</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to3_11">11</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from3_12">12</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to3_12">12</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from3_13">13</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to3_13">13</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from3_14">14</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to3_14">14</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from3_15">15</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to3_15">15</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from3_16">16</td><td nowrap="nowrap"></td><td class="diff_next"></td><td class="diff_header" id="to3_16">16</td><td nowrap="nowrap"></td></tr>
+            <tr><td class="diff_next"><a href="#difflib_chg_to3__2">n</a></td><td class="diff_header" id="from3_17">17</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;1.&nbsp;Beautiful&nbsp;is&nbsp;be<span class="diff_chg">TT</span>er&nbsp;than&nbsp;ugly.</td><td class="diff_next"><a href="#difflib_chg_to3__2">n</a></td><td class="diff_header" id="to3_17">17</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;1.&nbsp;Beautiful&nbsp;is&nbsp;be<span class="diff_chg">tt</span>er&nbsp;than&nbsp;ugly.</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from3_18">18</td><td nowrap="nowrap"><span class="diff_sub">&nbsp;&nbsp;&nbsp;2.&nbsp;Explicit&nbsp;is&nbsp;better&nbsp;than&nbsp;implicit.</span></td><td class="diff_next"></td><td class="diff_header"></td><td nowrap="nowrap"></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from3_19">19</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;3.&nbsp;Simple&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</td><td class="diff_next"></td><td class="diff_header" id="to3_18">18</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;3.<span class="diff_add">&nbsp;&nbsp;</span>&nbsp;Simple&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from3_20">20</td><td nowrap="nowrap"><span class="diff_sub">&nbsp;&nbsp;&nbsp;4.&nbsp;Complex&nbsp;is&nbsp;better&nbsp;than&nbsp;complicated.</span></td><td class="diff_next"></td><td class="diff_header" id="to3_19">19</td><td nowrap="nowrap"><span class="diff_add">&nbsp;&nbsp;&nbsp;4.&nbsp;Complicated&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header"></td><td nowrap="nowrap"></td><td class="diff_next"></td><td class="diff_header" id="to3_20">20</td><td nowrap="nowrap"><span class="diff_add">&nbsp;&nbsp;&nbsp;5.&nbsp;Flat&nbsp;is&nbsp;better&nbsp;than&nbsp;nested.</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from3_21">21</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to3_21">21</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from3_22">22</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to3_22">22</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from3_23">23</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to3_23">23</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from3_24">24</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to3_24">24</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from3_25">25</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to3_25">25</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next" id="difflib_chg_to3__2"></td><td class="diff_header" id="from3_26">26</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to3_26">26</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from3_27">27</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to3_27">27</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from3_28">28</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to3_28">28</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from3_29">29</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to3_29">29</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from3_30">30</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to3_30">30</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from3_31">31</td><td nowrap="nowrap"></td><td class="diff_next"></td><td class="diff_header" id="to3_31">31</td><td nowrap="nowrap"></td></tr>
+            <tr><td class="diff_next"><a href="#difflib_chg_to3__top">t</a></td><td class="diff_header" id="from3_32">32</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;1.&nbsp;Beautiful&nbsp;is&nbsp;be<span class="diff_chg">TT</span>er&nbsp;than&nbsp;ugly.</td><td class="diff_next"><a href="#difflib_chg_to3__top">t</a></td><td class="diff_header" id="to3_32">32</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;1.&nbsp;Beautiful&nbsp;is&nbsp;be<span class="diff_chg">tt</span>er&nbsp;than&nbsp;ugly.</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from3_33">33</td><td nowrap="nowrap"><span class="diff_sub">&nbsp;&nbsp;&nbsp;2.&nbsp;Explicit&nbsp;is&nbsp;better&nbsp;than&nbsp;implicit.</span></td><td class="diff_next"></td><td class="diff_header"></td><td nowrap="nowrap"></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from3_34">34</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;3.&nbsp;Simple&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</td><td class="diff_next"></td><td class="diff_header" id="to3_33">33</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;3.<span class="diff_add">&nbsp;&nbsp;</span>&nbsp;Simple&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from3_35">35</td><td nowrap="nowrap"><span class="diff_sub">&nbsp;&nbsp;&nbsp;4.&nbsp;Complex&nbsp;is&nbsp;better&nbsp;than&nbsp;complicated.</span></td><td class="diff_next"></td><td class="diff_header" id="to3_34">34</td><td nowrap="nowrap"><span class="diff_add">&nbsp;&nbsp;&nbsp;4.&nbsp;Complicated&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header"></td><td nowrap="nowrap"></td><td class="diff_next"></td><td class="diff_header" id="to3_35">35</td><td nowrap="nowrap"><span class="diff_add">&nbsp;&nbsp;&nbsp;5.&nbsp;Flat&nbsp;is&nbsp;better&nbsp;than&nbsp;nested.</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from3_36">36</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to3_36">36</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from3_37">37</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to3_37">37</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from3_38">38</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to3_38">38</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from3_39">39</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to3_39">39</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from3_40">40</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to3_40">40</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from3_41">41</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to3_41">41</td><td nowrap="nowrap">123</td></tr>
+        </tbody>
+    </table>
+<h2>Context (numlines=0)</h2>
+
+    <table class="diff" id="difflib_chg_to4__top"
+           cellspacing="0" cellpadding="0" rules="groups" >
+        <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup>
+        <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup>
+        <thead><tr><th class="diff_next"><br /></th><th colspan="2" class="diff_header">from</th><th class="diff_next"><br /></th><th colspan="2" class="diff_header">to</th></tr></thead>
+        <tbody>
+            <tr><td class="diff_next" id="difflib_chg_to4__0"><a href="#difflib_chg_to4__1">n</a></td><td class="diff_header" id="from4_2">2</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;1.&nbsp;Beautiful&nbsp;is&nbsp;be<span class="diff_chg">TT</span>er&nbsp;than&nbsp;ugly.</td><td class="diff_next"><a href="#difflib_chg_to4__1">n</a></td><td class="diff_header" id="to4_2">2</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;1.&nbsp;Beautiful&nbsp;is&nbsp;be<span class="diff_chg">tt</span>er&nbsp;than&nbsp;ugly.</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from4_3">3</td><td nowrap="nowrap"><span class="diff_sub">&nbsp;&nbsp;&nbsp;2.&nbsp;Explicit&nbsp;is&nbsp;better&nbsp;than&nbsp;implicit.</span></td><td class="diff_next"></td><td class="diff_header"></td><td nowrap="nowrap"></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from4_4">4</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;3.&nbsp;Simple&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</td><td class="diff_next"></td><td class="diff_header" id="to4_3">3</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;3.<span class="diff_add">&nbsp;&nbsp;</span>&nbsp;Simple&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from4_5">5</td><td nowrap="nowrap"><span class="diff_sub">&nbsp;&nbsp;&nbsp;4.&nbsp;Complex&nbsp;is&nbsp;better&nbsp;than&nbsp;complicated.</span></td><td class="diff_next"></td><td class="diff_header" id="to4_4">4</td><td nowrap="nowrap"><span class="diff_add">&nbsp;&nbsp;&nbsp;4.&nbsp;Complicated&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header"></td><td nowrap="nowrap"></td><td class="diff_next"></td><td class="diff_header" id="to4_5">5</td><td nowrap="nowrap"><span class="diff_add">&nbsp;&nbsp;&nbsp;5.&nbsp;Flat&nbsp;is&nbsp;better&nbsp;than&nbsp;nested.</span></td></tr>
+        </tbody>        
+        <tbody>
+            <tr><td class="diff_next" id="difflib_chg_to4__1"><a href="#difflib_chg_to4__2">n</a></td><td class="diff_header" id="from4_17">17</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;1.&nbsp;Beautiful&nbsp;is&nbsp;be<span class="diff_chg">TT</span>er&nbsp;than&nbsp;ugly.</td><td class="diff_next"><a href="#difflib_chg_to4__2">n</a></td><td class="diff_header" id="to4_17">17</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;1.&nbsp;Beautiful&nbsp;is&nbsp;be<span class="diff_chg">tt</span>er&nbsp;than&nbsp;ugly.</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from4_18">18</td><td nowrap="nowrap"><span class="diff_sub">&nbsp;&nbsp;&nbsp;2.&nbsp;Explicit&nbsp;is&nbsp;better&nbsp;than&nbsp;implicit.</span></td><td class="diff_next"></td><td class="diff_header"></td><td nowrap="nowrap"></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from4_19">19</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;3.&nbsp;Simple&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</td><td class="diff_next"></td><td class="diff_header" id="to4_18">18</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;3.<span class="diff_add">&nbsp;&nbsp;</span>&nbsp;Simple&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from4_20">20</td><td nowrap="nowrap"><span class="diff_sub">&nbsp;&nbsp;&nbsp;4.&nbsp;Complex&nbsp;is&nbsp;better&nbsp;than&nbsp;complicated.</span></td><td class="diff_next"></td><td class="diff_header" id="to4_19">19</td><td nowrap="nowrap"><span class="diff_add">&nbsp;&nbsp;&nbsp;4.&nbsp;Complicated&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header"></td><td nowrap="nowrap"></td><td class="diff_next"></td><td class="diff_header" id="to4_20">20</td><td nowrap="nowrap"><span class="diff_add">&nbsp;&nbsp;&nbsp;5.&nbsp;Flat&nbsp;is&nbsp;better&nbsp;than&nbsp;nested.</span></td></tr>
+        </tbody>        
+        <tbody>
+            <tr><td class="diff_next" id="difflib_chg_to4__2"><a href="#difflib_chg_to4__top">t</a></td><td class="diff_header" id="from4_32">32</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;1.&nbsp;Beautiful&nbsp;is&nbsp;be<span class="diff_chg">TT</span>er&nbsp;than&nbsp;ugly.</td><td class="diff_next"><a href="#difflib_chg_to4__top">t</a></td><td class="diff_header" id="to4_32">32</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;1.&nbsp;Beautiful&nbsp;is&nbsp;be<span class="diff_chg">tt</span>er&nbsp;than&nbsp;ugly.</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from4_33">33</td><td nowrap="nowrap"><span class="diff_sub">&nbsp;&nbsp;&nbsp;2.&nbsp;Explicit&nbsp;is&nbsp;better&nbsp;than&nbsp;implicit.</span></td><td class="diff_next"></td><td class="diff_header"></td><td nowrap="nowrap"></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from4_34">34</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;3.&nbsp;Simple&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</td><td class="diff_next"></td><td class="diff_header" id="to4_33">33</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;3.<span class="diff_add">&nbsp;&nbsp;</span>&nbsp;Simple&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from4_35">35</td><td nowrap="nowrap"><span class="diff_sub">&nbsp;&nbsp;&nbsp;4.&nbsp;Complex&nbsp;is&nbsp;better&nbsp;than&nbsp;complicated.</span></td><td class="diff_next"></td><td class="diff_header" id="to4_34">34</td><td nowrap="nowrap"><span class="diff_add">&nbsp;&nbsp;&nbsp;4.&nbsp;Complicated&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header"></td><td nowrap="nowrap"></td><td class="diff_next"></td><td class="diff_header" id="to4_35">35</td><td nowrap="nowrap"><span class="diff_add">&nbsp;&nbsp;&nbsp;5.&nbsp;Flat&nbsp;is&nbsp;better&nbsp;than&nbsp;nested.</span></td></tr>
+        </tbody>
+    </table>
+<h2>Same Context</h2>
+
+    <table class="diff" id="difflib_chg_to5__top"
+           cellspacing="0" cellpadding="0" rules="groups" >
+        <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup>
+        <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup>
+        <thead><tr><th class="diff_next"><br /></th><th colspan="2" class="diff_header">from</th><th class="diff_next"><br /></th><th colspan="2" class="diff_header">to</th></tr></thead>
+        <tbody>
+            <tr><td class="diff_next"><a href="#difflib_chg_to5__top">t</a></td><td></td><td>&nbsp;No Differences Found&nbsp;</td><td class="diff_next"><a href="#difflib_chg_to5__top">t</a></td><td></td><td>&nbsp;No Differences Found&nbsp;</td></tr>
+        </tbody>
+    </table>
+<h2>Same Full</h2>
+
+    <table class="diff" id="difflib_chg_to6__top"
+           cellspacing="0" cellpadding="0" rules="groups" >
+        <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup>
+        <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup>
+        <thead><tr><th class="diff_next"><br /></th><th colspan="2" class="diff_header">from</th><th class="diff_next"><br /></th><th colspan="2" class="diff_header">to</th></tr></thead>
+        <tbody>
+            <tr><td class="diff_next"><a href="#difflib_chg_to6__top">t</a></td><td class="diff_header" id="from6_1">1</td><td nowrap="nowrap"></td><td class="diff_next"><a href="#difflib_chg_to6__top">t</a></td><td class="diff_header" id="to6_1">1</td><td nowrap="nowrap"></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from6_2">2</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;1.&nbsp;Beautiful&nbsp;is&nbsp;beTTer&nbsp;than&nbsp;ugly.</td><td class="diff_next"></td><td class="diff_header" id="to6_2">2</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;1.&nbsp;Beautiful&nbsp;is&nbsp;beTTer&nbsp;than&nbsp;ugly.</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from6_3">3</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;2.&nbsp;Explicit&nbsp;is&nbsp;better&nbsp;than&nbsp;implicit.</td><td class="diff_next"></td><td class="diff_header" id="to6_3">3</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;2.&nbsp;Explicit&nbsp;is&nbsp;better&nbsp;than&nbsp;implicit.</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from6_4">4</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;3.&nbsp;Simple&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</td><td class="diff_next"></td><td class="diff_header" id="to6_4">4</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;3.&nbsp;Simple&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from6_5">5</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;4.&nbsp;Complex&nbsp;is&nbsp;better&nbsp;than&nbsp;complicated.</td><td class="diff_next"></td><td class="diff_header" id="to6_5">5</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;4.&nbsp;Complex&nbsp;is&nbsp;better&nbsp;than&nbsp;complicated.</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from6_6">6</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to6_6">6</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from6_7">7</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to6_7">7</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from6_8">8</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to6_8">8</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from6_9">9</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to6_9">9</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from6_10">10</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to6_10">10</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from6_11">11</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to6_11">11</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from6_12">12</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to6_12">12</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from6_13">13</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to6_13">13</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from6_14">14</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to6_14">14</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from6_15">15</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to6_15">15</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from6_16">16</td><td nowrap="nowrap"></td><td class="diff_next"></td><td class="diff_header" id="to6_16">16</td><td nowrap="nowrap"></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from6_17">17</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;1.&nbsp;Beautiful&nbsp;is&nbsp;beTTer&nbsp;than&nbsp;ugly.</td><td class="diff_next"></td><td class="diff_header" id="to6_17">17</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;1.&nbsp;Beautiful&nbsp;is&nbsp;beTTer&nbsp;than&nbsp;ugly.</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from6_18">18</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;2.&nbsp;Explicit&nbsp;is&nbsp;better&nbsp;than&nbsp;implicit.</td><td class="diff_next"></td><td class="diff_header" id="to6_18">18</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;2.&nbsp;Explicit&nbsp;is&nbsp;better&nbsp;than&nbsp;implicit.</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from6_19">19</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;3.&nbsp;Simple&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</td><td class="diff_next"></td><td class="diff_header" id="to6_19">19</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;3.&nbsp;Simple&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from6_20">20</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;4.&nbsp;Complex&nbsp;is&nbsp;better&nbsp;than&nbsp;complicated.</td><td class="diff_next"></td><td class="diff_header" id="to6_20">20</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;4.&nbsp;Complex&nbsp;is&nbsp;better&nbsp;than&nbsp;complicated.</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from6_21">21</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to6_21">21</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from6_22">22</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to6_22">22</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from6_23">23</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to6_23">23</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from6_24">24</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to6_24">24</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from6_25">25</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to6_25">25</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from6_26">26</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to6_26">26</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from6_27">27</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to6_27">27</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from6_28">28</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to6_28">28</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from6_29">29</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to6_29">29</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from6_30">30</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to6_30">30</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from6_31">31</td><td nowrap="nowrap"></td><td class="diff_next"></td><td class="diff_header" id="to6_31">31</td><td nowrap="nowrap"></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from6_32">32</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;1.&nbsp;Beautiful&nbsp;is&nbsp;beTTer&nbsp;than&nbsp;ugly.</td><td class="diff_next"></td><td class="diff_header" id="to6_32">32</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;1.&nbsp;Beautiful&nbsp;is&nbsp;beTTer&nbsp;than&nbsp;ugly.</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from6_33">33</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;2.&nbsp;Explicit&nbsp;is&nbsp;better&nbsp;than&nbsp;implicit.</td><td class="diff_next"></td><td class="diff_header" id="to6_33">33</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;2.&nbsp;Explicit&nbsp;is&nbsp;better&nbsp;than&nbsp;implicit.</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from6_34">34</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;3.&nbsp;Simple&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</td><td class="diff_next"></td><td class="diff_header" id="to6_34">34</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;3.&nbsp;Simple&nbsp;is&nbsp;better&nbsp;than&nbsp;complex.</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from6_35">35</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;4.&nbsp;Complex&nbsp;is&nbsp;better&nbsp;than&nbsp;complicated.</td><td class="diff_next"></td><td class="diff_header" id="to6_35">35</td><td nowrap="nowrap">&nbsp;&nbsp;&nbsp;4.&nbsp;Complex&nbsp;is&nbsp;better&nbsp;than&nbsp;complicated.</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from6_36">36</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to6_36">36</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from6_37">37</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to6_37">37</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from6_38">38</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to6_38">38</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from6_39">39</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to6_39">39</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from6_40">40</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to6_40">40</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from6_41">41</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to6_41">41</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from6_42">42</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to6_42">42</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from6_43">43</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to6_43">43</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from6_44">44</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to6_44">44</td><td nowrap="nowrap">123</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from6_45">45</td><td nowrap="nowrap">123</td><td class="diff_next"></td><td class="diff_header" id="to6_45">45</td><td nowrap="nowrap">123</td></tr>
+        </tbody>
+    </table>
+<h2>Empty Context</h2>
+
+    <table class="diff" id="difflib_chg_to7__top"
+           cellspacing="0" cellpadding="0" rules="groups" >
+        <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup>
+        <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup>
+        <thead><tr><th class="diff_next"><br /></th><th colspan="2" class="diff_header">from</th><th class="diff_next"><br /></th><th colspan="2" class="diff_header">to</th></tr></thead>
+        <tbody>
+            <tr><td class="diff_next"><a href="#difflib_chg_to7__top">t</a></td><td></td><td>&nbsp;No Differences Found&nbsp;</td><td class="diff_next"><a href="#difflib_chg_to7__top">t</a></td><td></td><td>&nbsp;No Differences Found&nbsp;</td></tr>
+        </tbody>
+    </table>
+<h2>Empty Full</h2>
+
+    <table class="diff" id="difflib_chg_to8__top"
+           cellspacing="0" cellpadding="0" rules="groups" >
+        <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup>
+        <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup>
+        <thead><tr><th class="diff_next"><br /></th><th colspan="2" class="diff_header">from</th><th class="diff_next"><br /></th><th colspan="2" class="diff_header">to</th></tr></thead>
+        <tbody>
+            <tr><td class="diff_next"><a href="#difflib_chg_to8__top">t</a></td><td></td><td>&nbsp;Empty File&nbsp;</td><td class="diff_next"><a href="#difflib_chg_to8__top">t</a></td><td></td><td>&nbsp;Empty File&nbsp;</td></tr>
+        </tbody>
+    </table>
+<h2>tabsize=2</h2>
+
+    <table class="diff" id="difflib_chg_to9__top"
+           cellspacing="0" cellpadding="0" rules="groups" >
+        <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup>
+        <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup>
+        
+        <tbody>
+            <tr><td class="diff_next" id="difflib_chg_to9__0"><a href="#difflib_chg_to9__0">f</a></td><td class="diff_header" id="from9_1">1</td><td nowrap="nowrap"></td><td class="diff_next"><a href="#difflib_chg_to9__0">f</a></td><td class="diff_header" id="to9_1">1</td><td nowrap="nowrap"></td></tr>
+            <tr><td class="diff_next"><a href="#difflib_chg_to9__top">t</a></td><td class="diff_header" id="from9_2">2</td><td nowrap="nowrap"><span class="diff_chg">&nbsp;&nbsp;&nbsp;&nbsp;</span>Line&nbsp;1:&nbsp;preceeded&nbsp;by&nbsp;from:[tt]&nbsp;to:[ssss]</td><td class="diff_next"><a href="#difflib_chg_to9__top">t</a></td><td class="diff_header" id="to9_2">2</td><td nowrap="nowrap"><span class="diff_chg">&nbsp;&nbsp;&nbsp;&nbsp;</span>Line&nbsp;1:&nbsp;preceeded&nbsp;by&nbsp;from:[tt]&nbsp;to:[ssss]</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from9_3">3</td><td nowrap="nowrap">&nbsp;&nbsp;<span class="diff_chg">&nbsp;&nbsp;</span>&nbsp;&nbsp;Line&nbsp;2:&nbsp;preceeded&nbsp;by&nbsp;from:[sstt]&nbsp;to:[sssst]</td><td class="diff_next"></td><td class="diff_header" id="to9_3">3</td><td nowrap="nowrap">&nbsp;&nbsp;<span class="diff_chg">&nbsp;&nbsp;</span>&nbsp;&nbsp;Line&nbsp;2:&nbsp;preceeded&nbsp;by&nbsp;from:[sstt]&nbsp;to:[sssst]</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from9_4">4</td><td nowrap="nowrap">&nbsp;&nbsp;<span class="diff_chg">&nbsp;&nbsp;&nbsp;&nbsp;</span>Line&nbsp;3:&nbsp;preceeded&nbsp;by&nbsp;from:[sstst]&nbsp;to:[ssssss]</td><td class="diff_next"></td><td class="diff_header" id="to9_4">4</td><td nowrap="nowrap">&nbsp;&nbsp;<span class="diff_chg">&nbsp;&nbsp;&nbsp;&nbsp;</span>Line&nbsp;3:&nbsp;preceeded&nbsp;by&nbsp;from:[sstst]&nbsp;to:[ssssss]</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from9_5">5</td><td nowrap="nowrap">Line&nbsp;4:&nbsp;&nbsp;<span class="diff_chg">&nbsp;</span>has&nbsp;from:[sst]&nbsp;to:[sss]&nbsp;after&nbsp;:</td><td class="diff_next"></td><td class="diff_header" id="to9_5">5</td><td nowrap="nowrap">Line&nbsp;4:&nbsp;&nbsp;<span class="diff_chg">&nbsp;</span>has&nbsp;from:[sst]&nbsp;to:[sss]&nbsp;after&nbsp;:</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from9_6">6</td><td nowrap="nowrap">Line&nbsp;5:&nbsp;has&nbsp;from:[t]&nbsp;to:[ss]&nbsp;at&nbsp;end<span class="diff_sub">&nbsp;</span></td><td class="diff_next"></td><td class="diff_header" id="to9_6">6</td><td nowrap="nowrap">Line&nbsp;5:&nbsp;has&nbsp;from:[t]&nbsp;to:[ss]&nbsp;at&nbsp;end</td></tr>
+        </tbody>
+    </table>
+<h2>tabsize=default</h2>
+
+    <table class="diff" id="difflib_chg_to10__top"
+           cellspacing="0" cellpadding="0" rules="groups" >
+        <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup>
+        <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup>
+        
+        <tbody>
+            <tr><td class="diff_next" id="difflib_chg_to10__0"><a href="#difflib_chg_to10__0">f</a></td><td class="diff_header" id="from10_1">1</td><td nowrap="nowrap"></td><td class="diff_next"><a href="#difflib_chg_to10__0">f</a></td><td class="diff_header" id="to10_1">1</td><td nowrap="nowrap"></td></tr>
+            <tr><td class="diff_next"><a href="#difflib_chg_to10__top">t</a></td><td class="diff_header" id="from10_2">2</td><td nowrap="nowrap"><span class="diff_chg">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>Line&nbsp;1:&nbsp;preceeded&nbsp;by&nbsp;from:[tt]&nbsp;to:[ssss]</td><td class="diff_next"><a href="#difflib_chg_to10__top">t</a></td><td class="diff_header" id="to10_2">2</td><td nowrap="nowrap"><span class="diff_chg">&nbsp;&nbsp;&nbsp;&nbsp;</span>Line&nbsp;1:&nbsp;preceeded&nbsp;by&nbsp;from:[tt]&nbsp;to:[ssss]</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from10_3">3</td><td nowrap="nowrap">&nbsp;&nbsp;<span class="diff_chg">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>&nbsp;&nbsp;&nbsp;&nbsp;Line&nbsp;2:&nbsp;preceeded&nbsp;by&nbsp;from:[sstt]&nbsp;to:[sssst]</td><td class="diff_next"></td><td class="diff_header" id="to10_3">3</td><td nowrap="nowrap">&nbsp;&nbsp;<span class="diff_chg">&nbsp;&nbsp;</span>&nbsp;&nbsp;&nbsp;&nbsp;Line&nbsp;2:&nbsp;preceeded&nbsp;by&nbsp;from:[sstt]&nbsp;to:[sssst]</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from10_4">4</td><td nowrap="nowrap">&nbsp;&nbsp;<span class="diff_chg">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>Line&nbsp;3:&nbsp;preceeded&nbsp;by&nbsp;from:[sstst]&nbsp;to:[ssssss]</td><td class="diff_next"></td><td class="diff_header" id="to10_4">4</td><td nowrap="nowrap">&nbsp;&nbsp;<span class="diff_chg">&nbsp;&nbsp;&nbsp;&nbsp;</span>Line&nbsp;3:&nbsp;preceeded&nbsp;by&nbsp;from:[sstst]&nbsp;to:[ssssss]</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from10_5">5</td><td nowrap="nowrap">Line&nbsp;4:&nbsp;&nbsp;<span class="diff_chg">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>has&nbsp;from:[sst]&nbsp;to:[sss]&nbsp;after&nbsp;:</td><td class="diff_next"></td><td class="diff_header" id="to10_5">5</td><td nowrap="nowrap">Line&nbsp;4:&nbsp;&nbsp;<span class="diff_chg">&nbsp;</span>has&nbsp;from:[sst]&nbsp;to:[sss]&nbsp;after&nbsp;:</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from10_6">6</td><td nowrap="nowrap">Line&nbsp;5:&nbsp;has&nbsp;from:[t]&nbsp;to:[ss]&nbsp;at&nbsp;end<span class="diff_sub">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></td><td class="diff_next"></td><td class="diff_header" id="to10_6">6</td><td nowrap="nowrap">Line&nbsp;5:&nbsp;has&nbsp;from:[t]&nbsp;to:[ss]&nbsp;at&nbsp;end</td></tr>
+        </tbody>
+    </table>
+<h2>Context (wrapcolumn=14,numlines=0)</h2>
+
+    <table class="diff" id="difflib_chg_to11__top"
+           cellspacing="0" cellpadding="0" rules="groups" >
+        <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup>
+        <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup>
+        
+        <tbody>
+            <tr><td class="diff_next" id="difflib_chg_to11__0"><a href="#difflib_chg_to11__1">n</a></td><td class="diff_header" id="from11_4">4</td><td nowrap="nowrap"><span class="diff_sub">line&nbsp;2</span></td><td class="diff_next"><a href="#difflib_chg_to11__1">n</a></td><td class="diff_header" id="to11_4">4</td><td nowrap="nowrap"><span class="diff_add">line&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;adde</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header"></td><td nowrap="nowrap">&nbsp;</td><td class="diff_next"></td><td class="diff_header">></td><td nowrap="nowrap"><span class="diff_add">d</span></td></tr>
+        </tbody>        
+        <tbody>
+            <tr><td class="diff_next" id="difflib_chg_to11__1"><a href="#difflib_chg_to11__2">n</a></td><td class="diff_header" id="from11_6">6</td><td nowrap="nowrap">line&nbsp;4&nbsp;&nbsp;&nbsp;chan<span class="diff_chg">g</span></td><td class="diff_next"><a href="#difflib_chg_to11__2">n</a></td><td class="diff_header" id="to11_6">6</td><td nowrap="nowrap">line&nbsp;4&nbsp;&nbsp;&nbsp;chan<span class="diff_chg">G</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header">></td><td nowrap="nowrap"><span class="diff_chg">e</span>d</td><td class="diff_next"></td><td class="diff_header">></td><td nowrap="nowrap"><span class="diff_chg">E</span>d</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from11_7">7</td><td nowrap="nowrap">line&nbsp;5<span class="diff_chg">&nbsp;</span>&nbsp;&nbsp;chan<span class="diff_chg">g</span></td><td class="diff_next"></td><td class="diff_header" id="to11_7">7</td><td nowrap="nowrap">line&nbsp;5<span class="diff_chg">a</span>&nbsp;&nbsp;chan<span class="diff_chg">G</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header">></td><td nowrap="nowrap"><span class="diff_chg"></span>ed</td><td class="diff_next"></td><td class="diff_header">></td><td nowrap="nowrap"><span class="diff_chg"></span>ed</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from11_8">8</td><td nowrap="nowrap">line&nbsp;6<span class="diff_chg">&nbsp;</span>&nbsp;&nbsp;chang</td><td class="diff_next"></td><td class="diff_header" id="to11_8">8</td><td nowrap="nowrap">line&nbsp;6<span class="diff_chg">a</span>&nbsp;&nbsp;chang</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header">></td><td nowrap="nowrap"><span class="diff_chg">e</span>d</td><td class="diff_next"></td><td class="diff_header">></td><td nowrap="nowrap"><span class="diff_chg">E</span>d</td></tr>
+        </tbody>        
+        <tbody>
+            <tr><td class="diff_next" id="difflib_chg_to11__2"><a href="#difflib_chg_to11__3">n</a></td><td class="diff_header" id="from11_10">10</td><td nowrap="nowrap"><span class="diff_sub">line&nbsp;8&nbsp;&nbsp;subtra</span></td><td class="diff_next"><a href="#difflib_chg_to11__3">n</a></td><td class="diff_header" id="to11_10">10</td><td nowrap="nowrap"><span class="diff_add">line&nbsp;8</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header">></td><td nowrap="nowrap"><span class="diff_sub">cted</span></td><td class="diff_next"></td><td class="diff_header"></td><td nowrap="nowrap">&nbsp;</td></tr>
+        </tbody>        
+        <tbody>
+            <tr><td class="diff_next" id="difflib_chg_to11__3"><a href="#difflib_chg_to11__top">t</a></td><td class="diff_header" id="from11_12">12</td><td nowrap="nowrap"><span class="diff_sub">12345678901234</span></td><td class="diff_next"><a href="#difflib_chg_to11__top">t</a></td><td class="diff_header" id="to11_12">12</td><td nowrap="nowrap"><span class="diff_add">1234567890</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header">></td><td nowrap="nowrap"><span class="diff_sub">56789012345689</span></td><td class="diff_next"></td><td class="diff_header"></td><td nowrap="nowrap">&nbsp;</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header">></td><td nowrap="nowrap"><span class="diff_sub">012345</span></td><td class="diff_next"></td><td class="diff_header"></td><td nowrap="nowrap">&nbsp;</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from11_13">13</td><td nowrap="nowrap"><span class="diff_sub">short&nbsp;line</span></td><td class="diff_next"></td><td class="diff_header" id="to11_13">13</td><td nowrap="nowrap"><span class="diff_add">another&nbsp;long&nbsp;l</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header"></td><td nowrap="nowrap">&nbsp;</td><td class="diff_next"></td><td class="diff_header">></td><td nowrap="nowrap"><span class="diff_add">ine&nbsp;that&nbsp;needs</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header"></td><td nowrap="nowrap">&nbsp;</td><td class="diff_next"></td><td class="diff_header">></td><td nowrap="nowrap"><span class="diff_add">&nbsp;to&nbsp;be&nbsp;wrapped</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from11_14">14</td><td nowrap="nowrap">just&nbsp;fit<span class="diff_chg">s</span>&nbsp;in!!</td><td class="diff_next"></td><td class="diff_header" id="to11_14">14</td><td nowrap="nowrap">just&nbsp;fit<span class="diff_chg">S</span>&nbsp;in!!</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from11_15">15</td><td nowrap="nowrap">just&nbsp;fits&nbsp;in&nbsp;t</td><td class="diff_next"></td><td class="diff_header" id="to11_15">15</td><td nowrap="nowrap">just&nbsp;fits&nbsp;in&nbsp;t</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header">></td><td nowrap="nowrap">wo&nbsp;line<span class="diff_chg">s</span>&nbsp;yup!!</td><td class="diff_next"></td><td class="diff_header">></td><td nowrap="nowrap">wo&nbsp;line<span class="diff_chg">S</span>&nbsp;yup!!</td></tr>
+        </tbody>
+    </table>
+<h2>wrapcolumn=14,splitlines()</h2>
+
+    <table class="diff" id="difflib_chg_to12__top"
+           cellspacing="0" cellpadding="0" rules="groups" >
+        <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup>
+        <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup>
+        
+        <tbody>
+            <tr><td class="diff_next" id="difflib_chg_to12__0"><a href="#difflib_chg_to12__0">f</a></td><td class="diff_header" id="from12_1">1</td><td nowrap="nowrap">line&nbsp;0</td><td class="diff_next"><a href="#difflib_chg_to12__0">f</a></td><td class="diff_header" id="to12_1">1</td><td nowrap="nowrap">line&nbsp;0</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from12_2">2</td><td nowrap="nowrap">12345678901234</td><td class="diff_next"></td><td class="diff_header" id="to12_2">2</td><td nowrap="nowrap">12345678901234</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header">></td><td nowrap="nowrap">56789012345689</td><td class="diff_next"></td><td class="diff_header">></td><td nowrap="nowrap">56789012345689</td></tr>
+            <tr><td class="diff_next" id="difflib_chg_to12__1"></td><td class="diff_header">></td><td nowrap="nowrap">012345</td><td class="diff_next"></td><td class="diff_header">></td><td nowrap="nowrap">012345</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from12_3">3</td><td nowrap="nowrap">line&nbsp;1</td><td class="diff_next"></td><td class="diff_header" id="to12_3">3</td><td nowrap="nowrap">line&nbsp;1</td></tr>
+            <tr><td class="diff_next"><a href="#difflib_chg_to12__1">n</a></td><td class="diff_header" id="from12_4">4</td><td nowrap="nowrap"><span class="diff_sub">line&nbsp;2</span></td><td class="diff_next"><a href="#difflib_chg_to12__1">n</a></td><td class="diff_header" id="to12_4">4</td><td nowrap="nowrap"><span class="diff_add">line&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;adde</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header"></td><td nowrap="nowrap">&nbsp;</td><td class="diff_next"></td><td class="diff_header">></td><td nowrap="nowrap"><span class="diff_add">d</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from12_5">5</td><td nowrap="nowrap">line&nbsp;3</td><td class="diff_next"></td><td class="diff_header" id="to12_5">5</td><td nowrap="nowrap">line&nbsp;3</td></tr>
+            <tr><td class="diff_next"><a href="#difflib_chg_to12__2">n</a></td><td class="diff_header" id="from12_6">6</td><td nowrap="nowrap">line&nbsp;4&nbsp;&nbsp;&nbsp;chan<span class="diff_chg">g</span></td><td class="diff_next"><a href="#difflib_chg_to12__2">n</a></td><td class="diff_header" id="to12_6">6</td><td nowrap="nowrap">line&nbsp;4&nbsp;&nbsp;&nbsp;chan<span class="diff_chg">G</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header">></td><td nowrap="nowrap"><span class="diff_chg">e</span>d</td><td class="diff_next"></td><td class="diff_header">></td><td nowrap="nowrap"><span class="diff_chg">E</span>d</td></tr>
+            <tr><td class="diff_next" id="difflib_chg_to12__2"></td><td class="diff_header" id="from12_7">7</td><td nowrap="nowrap">line&nbsp;5<span class="diff_chg">&nbsp;</span>&nbsp;&nbsp;chan<span class="diff_chg">g</span></td><td class="diff_next"></td><td class="diff_header" id="to12_7">7</td><td nowrap="nowrap">line&nbsp;5<span class="diff_chg">a</span>&nbsp;&nbsp;chan<span class="diff_chg">G</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header">></td><td nowrap="nowrap"><span class="diff_chg"></span>ed</td><td class="diff_next"></td><td class="diff_header">></td><td nowrap="nowrap"><span class="diff_chg"></span>ed</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from12_8">8</td><td nowrap="nowrap">line&nbsp;6<span class="diff_chg">&nbsp;</span>&nbsp;&nbsp;chang</td><td class="diff_next"></td><td class="diff_header" id="to12_8">8</td><td nowrap="nowrap">line&nbsp;6<span class="diff_chg">a</span>&nbsp;&nbsp;chang</td></tr>
+            <tr><td class="diff_next" id="difflib_chg_to12__3"></td><td class="diff_header">></td><td nowrap="nowrap"><span class="diff_chg">e</span>d</td><td class="diff_next"></td><td class="diff_header">></td><td nowrap="nowrap"><span class="diff_chg">E</span>d</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from12_9">9</td><td nowrap="nowrap">line&nbsp;7</td><td class="diff_next"></td><td class="diff_header" id="to12_9">9</td><td nowrap="nowrap">line&nbsp;7</td></tr>
+            <tr><td class="diff_next"><a href="#difflib_chg_to12__3">n</a></td><td class="diff_header" id="from12_10">10</td><td nowrap="nowrap"><span class="diff_sub">line&nbsp;8&nbsp;&nbsp;subtra</span></td><td class="diff_next"><a href="#difflib_chg_to12__3">n</a></td><td class="diff_header" id="to12_10">10</td><td nowrap="nowrap"><span class="diff_add">line&nbsp;8</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header">></td><td nowrap="nowrap"><span class="diff_sub">cted</span></td><td class="diff_next"></td><td class="diff_header"></td><td nowrap="nowrap">&nbsp;</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from12_11">11</td><td nowrap="nowrap">line&nbsp;9</td><td class="diff_next"></td><td class="diff_header" id="to12_11">11</td><td nowrap="nowrap">line&nbsp;9</td></tr>
+            <tr><td class="diff_next"><a href="#difflib_chg_to12__top">t</a></td><td class="diff_header" id="from12_12">12</td><td nowrap="nowrap"><span class="diff_sub">12345678901234</span></td><td class="diff_next"><a href="#difflib_chg_to12__top">t</a></td><td class="diff_header" id="to12_12">12</td><td nowrap="nowrap"><span class="diff_add">1234567890</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header">></td><td nowrap="nowrap"><span class="diff_sub">56789012345689</span></td><td class="diff_next"></td><td class="diff_header"></td><td nowrap="nowrap">&nbsp;</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header">></td><td nowrap="nowrap"><span class="diff_sub">012345</span></td><td class="diff_next"></td><td class="diff_header"></td><td nowrap="nowrap">&nbsp;</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from12_13">13</td><td nowrap="nowrap"><span class="diff_sub">short&nbsp;line</span></td><td class="diff_next"></td><td class="diff_header" id="to12_13">13</td><td nowrap="nowrap"><span class="diff_add">another&nbsp;long&nbsp;l</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header"></td><td nowrap="nowrap">&nbsp;</td><td class="diff_next"></td><td class="diff_header">></td><td nowrap="nowrap"><span class="diff_add">ine&nbsp;that&nbsp;needs</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header"></td><td nowrap="nowrap">&nbsp;</td><td class="diff_next"></td><td class="diff_header">></td><td nowrap="nowrap"><span class="diff_add">&nbsp;to&nbsp;be&nbsp;wrapped</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from12_14">14</td><td nowrap="nowrap">just&nbsp;fit<span class="diff_chg">s</span>&nbsp;in!!</td><td class="diff_next"></td><td class="diff_header" id="to12_14">14</td><td nowrap="nowrap">just&nbsp;fit<span class="diff_chg">S</span>&nbsp;in!!</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from12_15">15</td><td nowrap="nowrap">just&nbsp;fits&nbsp;in&nbsp;t</td><td class="diff_next"></td><td class="diff_header" id="to12_15">15</td><td nowrap="nowrap">just&nbsp;fits&nbsp;in&nbsp;t</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header">></td><td nowrap="nowrap">wo&nbsp;line<span class="diff_chg">s</span>&nbsp;yup!!</td><td class="diff_next"></td><td class="diff_header">></td><td nowrap="nowrap">wo&nbsp;line<span class="diff_chg">S</span>&nbsp;yup!!</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from12_16">16</td><td nowrap="nowrap">the&nbsp;end</td><td class="diff_next"></td><td class="diff_header" id="to12_16">16</td><td nowrap="nowrap">the&nbsp;end</td></tr>
+        </tbody>
+    </table>
+<h2>wrapcolumn=14,splitlines(True)</h2>
+
+    <table class="diff" id="difflib_chg_to13__top"
+           cellspacing="0" cellpadding="0" rules="groups" >
+        <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup>
+        <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup>
+        
+        <tbody>
+            <tr><td class="diff_next" id="difflib_chg_to13__0"><a href="#difflib_chg_to13__0">f</a></td><td class="diff_header" id="from13_1">1</td><td nowrap="nowrap">line&nbsp;0</td><td class="diff_next"><a href="#difflib_chg_to13__0">f</a></td><td class="diff_header" id="to13_1">1</td><td nowrap="nowrap">line&nbsp;0</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from13_2">2</td><td nowrap="nowrap">12345678901234</td><td class="diff_next"></td><td class="diff_header" id="to13_2">2</td><td nowrap="nowrap">12345678901234</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header">></td><td nowrap="nowrap">56789012345689</td><td class="diff_next"></td><td class="diff_header">></td><td nowrap="nowrap">56789012345689</td></tr>
+            <tr><td class="diff_next" id="difflib_chg_to13__1"></td><td class="diff_header">></td><td nowrap="nowrap">012345</td><td class="diff_next"></td><td class="diff_header">></td><td nowrap="nowrap">012345</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from13_3">3</td><td nowrap="nowrap">line&nbsp;1</td><td class="diff_next"></td><td class="diff_header" id="to13_3">3</td><td nowrap="nowrap">line&nbsp;1</td></tr>
+            <tr><td class="diff_next"><a href="#difflib_chg_to13__1">n</a></td><td class="diff_header" id="from13_4">4</td><td nowrap="nowrap"><span class="diff_sub">line&nbsp;2</span></td><td class="diff_next"><a href="#difflib_chg_to13__1">n</a></td><td class="diff_header" id="to13_4">4</td><td nowrap="nowrap"><span class="diff_add">line&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;adde</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header"></td><td nowrap="nowrap">&nbsp;</td><td class="diff_next"></td><td class="diff_header">></td><td nowrap="nowrap"><span class="diff_add">d</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from13_5">5</td><td nowrap="nowrap">line&nbsp;3</td><td class="diff_next"></td><td class="diff_header" id="to13_5">5</td><td nowrap="nowrap">line&nbsp;3</td></tr>
+            <tr><td class="diff_next"><a href="#difflib_chg_to13__2">n</a></td><td class="diff_header" id="from13_6">6</td><td nowrap="nowrap">line&nbsp;4&nbsp;&nbsp;&nbsp;chan<span class="diff_chg">g</span></td><td class="diff_next"><a href="#difflib_chg_to13__2">n</a></td><td class="diff_header" id="to13_6">6</td><td nowrap="nowrap">line&nbsp;4&nbsp;&nbsp;&nbsp;chan<span class="diff_chg">G</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header">></td><td nowrap="nowrap"><span class="diff_chg">e</span>d</td><td class="diff_next"></td><td class="diff_header">></td><td nowrap="nowrap"><span class="diff_chg">E</span>d</td></tr>
+            <tr><td class="diff_next" id="difflib_chg_to13__2"></td><td class="diff_header" id="from13_7">7</td><td nowrap="nowrap">line&nbsp;5<span class="diff_chg">&nbsp;</span>&nbsp;&nbsp;chan<span class="diff_chg">g</span></td><td class="diff_next"></td><td class="diff_header" id="to13_7">7</td><td nowrap="nowrap">line&nbsp;5<span class="diff_chg">a</span>&nbsp;&nbsp;chan<span class="diff_chg">G</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header">></td><td nowrap="nowrap"><span class="diff_chg"></span>ed</td><td class="diff_next"></td><td class="diff_header">></td><td nowrap="nowrap"><span class="diff_chg"></span>ed</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from13_8">8</td><td nowrap="nowrap">line&nbsp;6<span class="diff_chg">&nbsp;</span>&nbsp;&nbsp;chang</td><td class="diff_next"></td><td class="diff_header" id="to13_8">8</td><td nowrap="nowrap">line&nbsp;6<span class="diff_chg">a</span>&nbsp;&nbsp;chang</td></tr>
+            <tr><td class="diff_next" id="difflib_chg_to13__3"></td><td class="diff_header">></td><td nowrap="nowrap"><span class="diff_chg">e</span>d</td><td class="diff_next"></td><td class="diff_header">></td><td nowrap="nowrap"><span class="diff_chg">E</span>d</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from13_9">9</td><td nowrap="nowrap">line&nbsp;7</td><td class="diff_next"></td><td class="diff_header" id="to13_9">9</td><td nowrap="nowrap">line&nbsp;7</td></tr>
+            <tr><td class="diff_next"><a href="#difflib_chg_to13__3">n</a></td><td class="diff_header" id="from13_10">10</td><td nowrap="nowrap"><span class="diff_sub">line&nbsp;8&nbsp;&nbsp;subtra</span></td><td class="diff_next"><a href="#difflib_chg_to13__3">n</a></td><td class="diff_header" id="to13_10">10</td><td nowrap="nowrap"><span class="diff_add">line&nbsp;8</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header">></td><td nowrap="nowrap"><span class="diff_sub">cted</span></td><td class="diff_next"></td><td class="diff_header"></td><td nowrap="nowrap">&nbsp;</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from13_11">11</td><td nowrap="nowrap">line&nbsp;9</td><td class="diff_next"></td><td class="diff_header" id="to13_11">11</td><td nowrap="nowrap">line&nbsp;9</td></tr>
+            <tr><td class="diff_next"><a href="#difflib_chg_to13__top">t</a></td><td class="diff_header" id="from13_12">12</td><td nowrap="nowrap"><span class="diff_sub">12345678901234</span></td><td class="diff_next"><a href="#difflib_chg_to13__top">t</a></td><td class="diff_header" id="to13_12">12</td><td nowrap="nowrap"><span class="diff_add">1234567890</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header">></td><td nowrap="nowrap"><span class="diff_sub">56789012345689</span></td><td class="diff_next"></td><td class="diff_header"></td><td nowrap="nowrap">&nbsp;</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header">></td><td nowrap="nowrap"><span class="diff_sub">012345</span></td><td class="diff_next"></td><td class="diff_header"></td><td nowrap="nowrap">&nbsp;</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from13_13">13</td><td nowrap="nowrap"><span class="diff_sub">short&nbsp;line</span></td><td class="diff_next"></td><td class="diff_header" id="to13_13">13</td><td nowrap="nowrap"><span class="diff_add">another&nbsp;long&nbsp;l</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header"></td><td nowrap="nowrap">&nbsp;</td><td class="diff_next"></td><td class="diff_header">></td><td nowrap="nowrap"><span class="diff_add">ine&nbsp;that&nbsp;needs</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header"></td><td nowrap="nowrap">&nbsp;</td><td class="diff_next"></td><td class="diff_header">></td><td nowrap="nowrap"><span class="diff_add">&nbsp;to&nbsp;be&nbsp;wrapped</span></td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from13_14">14</td><td nowrap="nowrap">just&nbsp;fit<span class="diff_chg">s</span>&nbsp;in!!</td><td class="diff_next"></td><td class="diff_header" id="to13_14">14</td><td nowrap="nowrap">just&nbsp;fit<span class="diff_chg">S</span>&nbsp;in!!</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from13_15">15</td><td nowrap="nowrap">just&nbsp;fits&nbsp;in&nbsp;t</td><td class="diff_next"></td><td class="diff_header" id="to13_15">15</td><td nowrap="nowrap">just&nbsp;fits&nbsp;in&nbsp;t</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header">></td><td nowrap="nowrap">wo&nbsp;line<span class="diff_chg">s</span>&nbsp;yup!!</td><td class="diff_next"></td><td class="diff_header">></td><td nowrap="nowrap">wo&nbsp;line<span class="diff_chg">S</span>&nbsp;yup!!</td></tr>
+            <tr><td class="diff_next"></td><td class="diff_header" id="from13_16">16</td><td nowrap="nowrap">the&nbsp;end</td><td class="diff_next"></td><td class="diff_header" id="to13_16">16</td><td nowrap="nowrap">the&nbsp;end</td></tr>
+        </tbody>
+    </table>
+</body>
+
+</html>
\ No newline at end of file

Added: vendor/Python/current/Lib/test/test_dircache.py
===================================================================
--- vendor/Python/current/Lib/test/test_dircache.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_dircache.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,73 @@
+"""
+  Test cases for the dircache module
+  Nick Mathewson
+"""
+
+import unittest
+from test.test_support import run_unittest, TESTFN
+import dircache, os, time, sys, tempfile
+
+
+class DircacheTests(unittest.TestCase):
+    def setUp(self):
+        self.tempdir = tempfile.mkdtemp()
+
+    def tearDown(self):
+        for fname in os.listdir(self.tempdir):
+            self.delTemp(fname)
+        os.rmdir(self.tempdir)
+
+    def writeTemp(self, fname):
+        f = open(os.path.join(self.tempdir, fname), 'w')
+        f.close()
+
+    def mkdirTemp(self, fname):
+        os.mkdir(os.path.join(self.tempdir, fname))
+
+    def delTemp(self, fname):
+        fname = os.path.join(self.tempdir, fname)
+        if os.path.isdir(fname):
+            os.rmdir(fname)
+        else:
+            os.unlink(fname)
+
+    def test_listdir(self):
+        ## SUCCESSFUL CASES
+        entries = dircache.listdir(self.tempdir)
+        self.assertEquals(entries, [])
+
+        # Check that cache is actually caching, not just passing through.
+        self.assert_(dircache.listdir(self.tempdir) is entries)
+
+        # Directories aren't "files" on Windows, and directory mtime has
+        # nothing to do with when files under a directory get created.
+        # That is, this test can't possibly work under Windows -- dircache
+        # is only good for capturing a one-shot snapshot there.
+
+        if sys.platform[:3] not in ('win', 'os2'):
+            # Sadly, dircache has the same granularity as stat.mtime, and so
+            # can't notice any changes that occurred within 1 sec of the last
+            # time it examined a directory.
+            time.sleep(1)
+            self.writeTemp("test1")
+            entries = dircache.listdir(self.tempdir)
+            self.assertEquals(entries, ['test1'])
+            self.assert_(dircache.listdir(self.tempdir) is entries)
+
+        ## UNSUCCESSFUL CASES
+        self.assertRaises(OSError, dircache.listdir, self.tempdir+"_nonexistent")
+
+    def test_annotate(self):
+        self.writeTemp("test2")
+        self.mkdirTemp("A")
+        lst = ['A', 'test2', 'test_nonexistent']
+        dircache.annotate(self.tempdir, lst)
+        self.assertEquals(lst, ['A/', 'test2', 'test_nonexistent'])
+
+
+def test_main():
+    run_unittest(DircacheTests)
+
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_dis.py
===================================================================
--- vendor/Python/current/Lib/test/test_dis.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_dis.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,156 @@
+from test.test_support import verify, verbose, TestFailed, run_unittest
+import sys
+import dis
+import StringIO
+
+# Minimal tests for dis module
+
+import unittest
+
+def _f(a):
+    print a
+    return 1
+
+dis_f = """\
+ %-4d         0 LOAD_FAST                0 (a)
+              3 PRINT_ITEM
+              4 PRINT_NEWLINE
+
+ %-4d         5 LOAD_CONST               1 (1)
+              8 RETURN_VALUE
+"""%(_f.func_code.co_firstlineno + 1,
+     _f.func_code.co_firstlineno + 2)
+
+
+def bug708901():
+    for res in range(1,
+                     10):
+        pass
+
+dis_bug708901 = """\
+ %-4d         0 SETUP_LOOP              23 (to 26)
+              3 LOAD_GLOBAL              0 (range)
+              6 LOAD_CONST               1 (1)
+
+ %-4d         9 LOAD_CONST               2 (10)
+             12 CALL_FUNCTION            2
+             15 GET_ITER
+        >>   16 FOR_ITER                 6 (to 25)
+             19 STORE_FAST               0 (res)
+
+ %-4d        22 JUMP_ABSOLUTE           16
+        >>   25 POP_BLOCK
+        >>   26 LOAD_CONST               0 (None)
+             29 RETURN_VALUE
+"""%(bug708901.func_code.co_firstlineno + 1,
+     bug708901.func_code.co_firstlineno + 2,
+     bug708901.func_code.co_firstlineno + 3)
+
+
+def bug1333982(x=[]):
+    assert 0, ([s for s in x] +
+              1)
+    pass
+
+dis_bug1333982 = """\
+ %-4d         0 LOAD_CONST               1 (0)
+              3 JUMP_IF_TRUE            41 (to 47)
+              6 POP_TOP
+              7 LOAD_GLOBAL              0 (AssertionError)
+             10 BUILD_LIST               0
+             13 DUP_TOP
+             14 STORE_FAST               1 (_[1])
+             17 LOAD_FAST                0 (x)
+             20 GET_ITER
+        >>   21 FOR_ITER                13 (to 37)
+             24 STORE_FAST               2 (s)
+             27 LOAD_FAST                1 (_[1])
+             30 LOAD_FAST                2 (s)
+             33 LIST_APPEND
+             34 JUMP_ABSOLUTE           21
+        >>   37 DELETE_FAST              1 (_[1])
+
+ %-4d        40 LOAD_CONST               2 (1)
+             43 BINARY_ADD
+             44 RAISE_VARARGS            2
+        >>   47 POP_TOP
+
+ %-4d        48 LOAD_CONST               0 (None)
+             51 RETURN_VALUE
+"""%(bug1333982.func_code.co_firstlineno + 1,
+     bug1333982.func_code.co_firstlineno + 2,
+     bug1333982.func_code.co_firstlineno + 3)
+
+_BIG_LINENO_FORMAT = """\
+%3d           0 LOAD_GLOBAL              0 (spam)
+              3 POP_TOP
+              4 LOAD_CONST               0 (None)
+              7 RETURN_VALUE
+"""
+
+class DisTests(unittest.TestCase):
+    def do_disassembly_test(self, func, expected):
+        s = StringIO.StringIO()
+        save_stdout = sys.stdout
+        sys.stdout = s
+        dis.dis(func)
+        sys.stdout = save_stdout
+        got = s.getvalue()
+        # Trim trailing blanks (if any).
+        lines = got.split('\n')
+        lines = [line.rstrip() for line in lines]
+        expected = expected.split("\n")
+        import difflib
+        if expected != lines:
+            self.fail(
+                "events did not match expectation:\n" +
+                "\n".join(difflib.ndiff(expected,
+                                        lines)))
+
+    def test_opmap(self):
+        self.assertEqual(dis.opmap["STOP_CODE"], 0)
+        self.assertEqual(dis.opmap["LOAD_CONST"] in dis.hasconst, True)
+        self.assertEqual(dis.opmap["STORE_NAME"] in dis.hasname, True)
+
+    def test_opname(self):
+        self.assertEqual(dis.opname[dis.opmap["LOAD_FAST"]], "LOAD_FAST")
+
+    def test_boundaries(self):
+        self.assertEqual(dis.opmap["EXTENDED_ARG"], dis.EXTENDED_ARG)
+        self.assertEqual(dis.opmap["STORE_NAME"], dis.HAVE_ARGUMENT)
+
+    def test_dis(self):
+        self.do_disassembly_test(_f, dis_f)
+
+    def test_bug_708901(self):
+        self.do_disassembly_test(bug708901, dis_bug708901)
+
+    def test_bug_1333982(self):
+        # This one is checking bytecodes generated for an `assert` statement,
+        # so fails if the tests are run with -O.  Skip this test then.
+        if __debug__:
+            self.do_disassembly_test(bug1333982, dis_bug1333982)
+
+    def test_big_linenos(self):
+        def func(count):
+            namespace = {}
+            func = "def foo():\n " + "".join(["\n "] * count + ["spam\n"])
+            exec func in namespace
+            return namespace['foo']
+
+        # Test all small ranges
+        for i in xrange(1, 300):
+            expected = _BIG_LINENO_FORMAT % (i + 2)
+            self.do_disassembly_test(func(i), expected)
+
+        # Test some larger ranges too
+        for i in xrange(300, 5000, 10):
+            expected = _BIG_LINENO_FORMAT % (i + 2)
+            self.do_disassembly_test(func(i), expected)
+
+def test_main():
+    run_unittest(DisTests)
+
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_distutils.py
===================================================================
--- vendor/Python/current/Lib/test/test_distutils.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_distutils.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,17 @@
+"""Tests for distutils.
+
+The tests for distutils are defined in the distutils.tests package;
+the test_suite() function there returns a test suite that's ready to
+be run.
+"""
+
+import distutils.tests
+import test.test_support
+
+
+def test_main():
+    test.test_support.run_unittest(distutils.tests.test_suite())
+
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_dl.py
===================================================================
--- vendor/Python/current/Lib/test/test_dl.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_dl.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,34 @@
+#! /usr/bin/env python
+"""Test dlmodule.c
+   Roger E. Masse  revised strategy by Barry Warsaw
+"""
+
+import dl
+from test.test_support import verbose,TestSkipped
+
+sharedlibs = [
+    ('/usr/lib/libc.so', 'getpid'),
+    ('/lib/libc.so.6', 'getpid'),
+    ('/usr/bin/cygwin1.dll', 'getpid'),
+    ('/usr/lib/libc.dylib', 'getpid'),
+    ]
+
+for s, func in sharedlibs:
+    try:
+        if verbose:
+            print 'trying to open:', s,
+        l = dl.open(s)
+    except dl.error, err:
+        if verbose:
+            print 'failed', repr(str(err))
+        pass
+    else:
+        if verbose:
+            print 'succeeded...',
+        l.call(func)
+        l.close()
+        if verbose:
+            print 'worked!'
+        break
+else:
+    raise TestSkipped, 'Could not open any shared libraries'


Property changes on: vendor/Python/current/Lib/test/test_dl.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/test/test_doctest.py
===================================================================
--- vendor/Python/current/Lib/test/test_doctest.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_doctest.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2418 @@
+"""
+Test script for doctest.
+"""
+
+from test import test_support
+import doctest
+import warnings
+
+######################################################################
+## Sample Objects (used by test cases)
+######################################################################
+
+def sample_func(v):
+    """
+    Blah blah
+
+    >>> print sample_func(22)
+    44
+
+    Yee ha!
+    """
+    return v+v
+
+class SampleClass:
+    """
+    >>> print 1
+    1
+
+    >>> # comments get ignored.  so are empty PS1 and PS2 prompts:
+    >>>
+    ...
+
+    Multiline example:
+    >>> sc = SampleClass(3)
+    >>> for i in range(10):
+    ...     sc = sc.double()
+    ...     print sc.get(),
+    6 12 24 48 96 192 384 768 1536 3072
+    """
+    def __init__(self, val):
+        """
+        >>> print SampleClass(12).get()
+        12
+        """
+        self.val = val
+
+    def double(self):
+        """
+        >>> print SampleClass(12).double().get()
+        24
+        """
+        return SampleClass(self.val + self.val)
+
+    def get(self):
+        """
+        >>> print SampleClass(-5).get()
+        -5
+        """
+        return self.val
+
+    def a_staticmethod(v):
+        """
+        >>> print SampleClass.a_staticmethod(10)
+        11
+        """
+        return v+1
+    a_staticmethod = staticmethod(a_staticmethod)
+
+    def a_classmethod(cls, v):
+        """
+        >>> print SampleClass.a_classmethod(10)
+        12
+        >>> print SampleClass(0).a_classmethod(10)
+        12
+        """
+        return v+2
+    a_classmethod = classmethod(a_classmethod)
+
+    a_property = property(get, doc="""
+        >>> print SampleClass(22).a_property
+        22
+        """)
+
+    class NestedClass:
+        """
+        >>> x = SampleClass.NestedClass(5)
+        >>> y = x.square()
+        >>> print y.get()
+        25
+        """
+        def __init__(self, val=0):
+            """
+            >>> print SampleClass.NestedClass().get()
+            0
+            """
+            self.val = val
+        def square(self):
+            return SampleClass.NestedClass(self.val*self.val)
+        def get(self):
+            return self.val
+
+class SampleNewStyleClass(object):
+    r"""
+    >>> print '1\n2\n3'
+    1
+    2
+    3
+    """
+    def __init__(self, val):
+        """
+        >>> print SampleNewStyleClass(12).get()
+        12
+        """
+        self.val = val
+
+    def double(self):
+        """
+        >>> print SampleNewStyleClass(12).double().get()
+        24
+        """
+        return SampleNewStyleClass(self.val + self.val)
+
+    def get(self):
+        """
+        >>> print SampleNewStyleClass(-5).get()
+        -5
+        """
+        return self.val
+
+######################################################################
+## Fake stdin (for testing interactive debugging)
+######################################################################
+
+class _FakeInput:
+    """
+    A fake input stream for pdb's interactive debugger.  Whenever a
+    line is read, print it (to simulate the user typing it), and then
+    return it.  The set of lines to return is specified in the
+    constructor; they should not have trailing newlines.
+    """
+    def __init__(self, lines):
+        self.lines = lines
+
+    def readline(self):
+        line = self.lines.pop(0)
+        print line
+        return line+'\n'
+
+######################################################################
+## Test Cases
+######################################################################
+
+def test_Example(): r"""
+Unit tests for the `Example` class.
+
+Example is a simple container class that holds:
+  - `source`: A source string.
+  - `want`: An expected output string.
+  - `exc_msg`: An expected exception message string (or None if no
+    exception is expected).
+  - `lineno`: A line number (within the docstring).
+  - `indent`: The example's indentation in the input string.
+  - `options`: An option dictionary, mapping option flags to True or
+    False.
+
+These attributes are set by the constructor.  `source` and `want` are
+required; the other attributes all have default values:
+
+    >>> example = doctest.Example('print 1', '1\n')
+    >>> (example.source, example.want, example.exc_msg,
+    ...  example.lineno, example.indent, example.options)
+    ('print 1\n', '1\n', None, 0, 0, {})
+
+The first three attributes (`source`, `want`, and `exc_msg`) may be
+specified positionally; the remaining arguments should be specified as
+keyword arguments:
+
+    >>> exc_msg = 'IndexError: pop from an empty list'
+    >>> example = doctest.Example('[].pop()', '', exc_msg,
+    ...                           lineno=5, indent=4,
+    ...                           options={doctest.ELLIPSIS: True})
+    >>> (example.source, example.want, example.exc_msg,
+    ...  example.lineno, example.indent, example.options)
+    ('[].pop()\n', '', 'IndexError: pop from an empty list\n', 5, 4, {8: True})
+
+The constructor normalizes the `source` string to end in a newline:
+
+    Source spans a single line: no terminating newline.
+    >>> e = doctest.Example('print 1', '1\n')
+    >>> e.source, e.want
+    ('print 1\n', '1\n')
+
+    >>> e = doctest.Example('print 1\n', '1\n')
+    >>> e.source, e.want
+    ('print 1\n', '1\n')
+
+    Source spans multiple lines: require terminating newline.
+    >>> e = doctest.Example('print 1;\nprint 2\n', '1\n2\n')
+    >>> e.source, e.want
+    ('print 1;\nprint 2\n', '1\n2\n')
+
+    >>> e = doctest.Example('print 1;\nprint 2', '1\n2\n')
+    >>> e.source, e.want
+    ('print 1;\nprint 2\n', '1\n2\n')
+
+    Empty source string (which should never appear in real examples)
+    >>> e = doctest.Example('', '')
+    >>> e.source, e.want
+    ('\n', '')
+
+The constructor normalizes the `want` string to end in a newline,
+unless it's the empty string:
+
+    >>> e = doctest.Example('print 1', '1\n')
+    >>> e.source, e.want
+    ('print 1\n', '1\n')
+
+    >>> e = doctest.Example('print 1', '1')
+    >>> e.source, e.want
+    ('print 1\n', '1\n')
+
+    >>> e = doctest.Example('print', '')
+    >>> e.source, e.want
+    ('print\n', '')
+
+The constructor normalizes the `exc_msg` string to end in a newline,
+unless it's `None`:
+
+    Message spans one line
+    >>> exc_msg = 'IndexError: pop from an empty list'
+    >>> e = doctest.Example('[].pop()', '', exc_msg)
+    >>> e.exc_msg
+    'IndexError: pop from an empty list\n'
+
+    >>> exc_msg = 'IndexError: pop from an empty list\n'
+    >>> e = doctest.Example('[].pop()', '', exc_msg)
+    >>> e.exc_msg
+    'IndexError: pop from an empty list\n'
+
+    Message spans multiple lines
+    >>> exc_msg = 'ValueError: 1\n  2'
+    >>> e = doctest.Example('raise ValueError("1\n  2")', '', exc_msg)
+    >>> e.exc_msg
+    'ValueError: 1\n  2\n'
+
+    >>> exc_msg = 'ValueError: 1\n  2\n'
+    >>> e = doctest.Example('raise ValueError("1\n  2")', '', exc_msg)
+    >>> e.exc_msg
+    'ValueError: 1\n  2\n'
+
+    Empty (but non-None) exception message (which should never appear
+    in real examples)
+    >>> exc_msg = ''
+    >>> e = doctest.Example('raise X()', '', exc_msg)
+    >>> e.exc_msg
+    '\n'
+"""
+
+def test_DocTest(): r"""
+Unit tests for the `DocTest` class.
+
+DocTest is a collection of examples, extracted from a docstring, along
+with information about where the docstring comes from (a name,
+filename, and line number).  The docstring is parsed by the `DocTest`
+constructor:
+
+    >>> docstring = '''
+    ...     >>> print 12
+    ...     12
+    ...
+    ... Non-example text.
+    ...
+    ...     >>> print 'another\example'
+    ...     another
+    ...     example
+    ... '''
+    >>> globs = {} # globals to run the test in.
+    >>> parser = doctest.DocTestParser()
+    >>> test = parser.get_doctest(docstring, globs, 'some_test',
+    ...                           'some_file', 20)
+    >>> print test
+    <DocTest some_test from some_file:20 (2 examples)>
+    >>> len(test.examples)
+    2
+    >>> e1, e2 = test.examples
+    >>> (e1.source, e1.want, e1.lineno)
+    ('print 12\n', '12\n', 1)
+    >>> (e2.source, e2.want, e2.lineno)
+    ("print 'another\\example'\n", 'another\nexample\n', 6)
+
+Source information (name, filename, and line number) is available as
+attributes on the doctest object:
+
+    >>> (test.name, test.filename, test.lineno)
+    ('some_test', 'some_file', 20)
+
+The line number of an example within its containing file is found by
+adding the line number of the example and the line number of its
+containing test:
+
+    >>> test.lineno + e1.lineno
+    21
+    >>> test.lineno + e2.lineno
+    26
+
+If the docstring contains inconsistant leading whitespace in the
+expected output of an example, then `DocTest` will raise a ValueError:
+
+    >>> docstring = r'''
+    ...       >>> print 'bad\nindentation'
+    ...       bad
+    ...     indentation
+    ...     '''
+    >>> parser.get_doctest(docstring, globs, 'some_test', 'filename', 0)
+    Traceback (most recent call last):
+    ValueError: line 4 of the docstring for some_test has inconsistent leading whitespace: 'indentation'
+
+If the docstring contains inconsistent leading whitespace on
+continuation lines, then `DocTest` will raise a ValueError:
+
+    >>> docstring = r'''
+    ...       >>> print ('bad indentation',
+    ...     ...          2)
+    ...       ('bad', 'indentation')
+    ...     '''
+    >>> parser.get_doctest(docstring, globs, 'some_test', 'filename', 0)
+    Traceback (most recent call last):
+    ValueError: line 2 of the docstring for some_test has inconsistent leading whitespace: '...          2)'
+
+If there's no blank space after a PS1 prompt ('>>>'), then `DocTest`
+will raise a ValueError:
+
+    >>> docstring = '>>>print 1\n1'
+    >>> parser.get_doctest(docstring, globs, 'some_test', 'filename', 0)
+    Traceback (most recent call last):
+    ValueError: line 1 of the docstring for some_test lacks blank after >>>: '>>>print 1'
+
+If there's no blank space after a PS2 prompt ('...'), then `DocTest`
+will raise a ValueError:
+
+    >>> docstring = '>>> if 1:\n...print 1\n1'
+    >>> parser.get_doctest(docstring, globs, 'some_test', 'filename', 0)
+    Traceback (most recent call last):
+    ValueError: line 2 of the docstring for some_test lacks blank after ...: '...print 1'
+
+"""
+
+def test_DocTestFinder(): r"""
+Unit tests for the `DocTestFinder` class.
+
+DocTestFinder is used to extract DocTests from an object's docstring
+and the docstrings of its contained objects.  It can be used with
+modules, functions, classes, methods, staticmethods, classmethods, and
+properties.
+
+Finding Tests in Functions
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+For a function whose docstring contains examples, DocTestFinder.find()
+will return a single test (for that function's docstring):
+
+    >>> finder = doctest.DocTestFinder()
+
+We'll simulate a __file__ attr that ends in pyc:
+
+    >>> import test.test_doctest
+    >>> old = test.test_doctest.__file__
+    >>> test.test_doctest.__file__ = 'test_doctest.pyc'
+
+    >>> tests = finder.find(sample_func)
+
+    >>> print tests  # doctest: +ELLIPSIS
+    [<DocTest sample_func from ...:13 (1 example)>]
+
+The exact name depends on how test_doctest was invoked, so allow for
+leading path components.
+
+    >>> tests[0].filename # doctest: +ELLIPSIS
+    '...test_doctest.py'
+
+    >>> test.test_doctest.__file__ = old
+
+
+    >>> e = tests[0].examples[0]
+    >>> (e.source, e.want, e.lineno)
+    ('print sample_func(22)\n', '44\n', 3)
+
+By default, tests are created for objects with no docstring:
+
+    >>> def no_docstring(v):
+    ...     pass
+    >>> finder.find(no_docstring)
+    []
+
+However, the optional argument `exclude_empty` to the DocTestFinder
+constructor can be used to exclude tests for objects with empty
+docstrings:
+
+    >>> def no_docstring(v):
+    ...     pass
+    >>> excl_empty_finder = doctest.DocTestFinder(exclude_empty=True)
+    >>> excl_empty_finder.find(no_docstring)
+    []
+
+If the function has a docstring with no examples, then a test with no
+examples is returned.  (This lets `DocTestRunner` collect statistics
+about which functions have no tests -- but is that useful?  And should
+an empty test also be created when there's no docstring?)
+
+    >>> def no_examples(v):
+    ...     ''' no doctest examples '''
+    >>> finder.find(no_examples) # doctest: +ELLIPSIS
+    [<DocTest no_examples from ...:1 (no examples)>]
+
+Finding Tests in Classes
+~~~~~~~~~~~~~~~~~~~~~~~~
+For a class, DocTestFinder will create a test for the class's
+docstring, and will recursively explore its contents, including
+methods, classmethods, staticmethods, properties, and nested classes.
+
+    >>> finder = doctest.DocTestFinder()
+    >>> tests = finder.find(SampleClass)
+    >>> for t in tests:
+    ...     print '%2s  %s' % (len(t.examples), t.name)
+     3  SampleClass
+     3  SampleClass.NestedClass
+     1  SampleClass.NestedClass.__init__
+     1  SampleClass.__init__
+     2  SampleClass.a_classmethod
+     1  SampleClass.a_property
+     1  SampleClass.a_staticmethod
+     1  SampleClass.double
+     1  SampleClass.get
+
+New-style classes are also supported:
+
+    >>> tests = finder.find(SampleNewStyleClass)
+    >>> for t in tests:
+    ...     print '%2s  %s' % (len(t.examples), t.name)
+     1  SampleNewStyleClass
+     1  SampleNewStyleClass.__init__
+     1  SampleNewStyleClass.double
+     1  SampleNewStyleClass.get
+
+Finding Tests in Modules
+~~~~~~~~~~~~~~~~~~~~~~~~
+For a module, DocTestFinder will create a test for the class's
+docstring, and will recursively explore its contents, including
+functions, classes, and the `__test__` dictionary, if it exists:
+
+    >>> # A module
+    >>> import new
+    >>> m = new.module('some_module')
+    >>> def triple(val):
+    ...     '''
+    ...     >>> print triple(11)
+    ...     33
+    ...     '''
+    ...     return val*3
+    >>> m.__dict__.update({
+    ...     'sample_func': sample_func,
+    ...     'SampleClass': SampleClass,
+    ...     '__doc__': '''
+    ...         Module docstring.
+    ...             >>> print 'module'
+    ...             module
+    ...         ''',
+    ...     '__test__': {
+    ...         'd': '>>> print 6\n6\n>>> print 7\n7\n',
+    ...         'c': triple}})
+
+    >>> finder = doctest.DocTestFinder()
+    >>> # Use module=test.test_doctest, to prevent doctest from
+    >>> # ignoring the objects since they weren't defined in m.
+    >>> import test.test_doctest
+    >>> tests = finder.find(m, module=test.test_doctest)
+    >>> for t in tests:
+    ...     print '%2s  %s' % (len(t.examples), t.name)
+     1  some_module
+     3  some_module.SampleClass
+     3  some_module.SampleClass.NestedClass
+     1  some_module.SampleClass.NestedClass.__init__
+     1  some_module.SampleClass.__init__
+     2  some_module.SampleClass.a_classmethod
+     1  some_module.SampleClass.a_property
+     1  some_module.SampleClass.a_staticmethod
+     1  some_module.SampleClass.double
+     1  some_module.SampleClass.get
+     1  some_module.__test__.c
+     2  some_module.__test__.d
+     1  some_module.sample_func
+
+Duplicate Removal
+~~~~~~~~~~~~~~~~~
+If a single object is listed twice (under different names), then tests
+will only be generated for it once:
+
+    >>> from test import doctest_aliases
+    >>> tests = excl_empty_finder.find(doctest_aliases)
+    >>> print len(tests)
+    2
+    >>> print tests[0].name
+    test.doctest_aliases.TwoNames
+
+    TwoNames.f and TwoNames.g are bound to the same object.
+    We can't guess which will be found in doctest's traversal of
+    TwoNames.__dict__ first, so we have to allow for either.
+
+    >>> tests[1].name.split('.')[-1] in ['f', 'g']
+    True
+
+Empty Tests
+~~~~~~~~~~~
+By default, an object with no doctests doesn't create any tests:
+
+    >>> tests = doctest.DocTestFinder().find(SampleClass)
+    >>> for t in tests:
+    ...     print '%2s  %s' % (len(t.examples), t.name)
+     3  SampleClass
+     3  SampleClass.NestedClass
+     1  SampleClass.NestedClass.__init__
+     1  SampleClass.__init__
+     2  SampleClass.a_classmethod
+     1  SampleClass.a_property
+     1  SampleClass.a_staticmethod
+     1  SampleClass.double
+     1  SampleClass.get
+
+By default, that excluded objects with no doctests.  exclude_empty=False
+tells it to include (empty) tests for objects with no doctests.  This feature
+is really to support backward compatibility in what doctest.master.summarize()
+displays.
+
+    >>> tests = doctest.DocTestFinder(exclude_empty=False).find(SampleClass)
+    >>> for t in tests:
+    ...     print '%2s  %s' % (len(t.examples), t.name)
+     3  SampleClass
+     3  SampleClass.NestedClass
+     1  SampleClass.NestedClass.__init__
+     0  SampleClass.NestedClass.get
+     0  SampleClass.NestedClass.square
+     1  SampleClass.__init__
+     2  SampleClass.a_classmethod
+     1  SampleClass.a_property
+     1  SampleClass.a_staticmethod
+     1  SampleClass.double
+     1  SampleClass.get
+
+Turning off Recursion
+~~~~~~~~~~~~~~~~~~~~~
+DocTestFinder can be told not to look for tests in contained objects
+using the `recurse` flag:
+
+    >>> tests = doctest.DocTestFinder(recurse=False).find(SampleClass)
+    >>> for t in tests:
+    ...     print '%2s  %s' % (len(t.examples), t.name)
+     3  SampleClass
+
+Line numbers
+~~~~~~~~~~~~
+DocTestFinder finds the line number of each example:
+
+    >>> def f(x):
+    ...     '''
+    ...     >>> x = 12
+    ...
+    ...     some text
+    ...
+    ...     >>> # examples are not created for comments & bare prompts.
+    ...     >>>
+    ...     ...
+    ...
+    ...     >>> for x in range(10):
+    ...     ...     print x,
+    ...     0 1 2 3 4 5 6 7 8 9
+    ...     >>> x//2
+    ...     6
+    ...     '''
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> [e.lineno for e in test.examples]
+    [1, 9, 12]
+"""
+
+def test_DocTestParser(): r"""
+Unit tests for the `DocTestParser` class.
+
+DocTestParser is used to parse docstrings containing doctest examples.
+
+The `parse` method divides a docstring into examples and intervening
+text:
+
+    >>> s = '''
+    ...     >>> x, y = 2, 3  # no output expected
+    ...     >>> if 1:
+    ...     ...     print x
+    ...     ...     print y
+    ...     2
+    ...     3
+    ...
+    ...     Some text.
+    ...     >>> x+y
+    ...     5
+    ...     '''
+    >>> parser = doctest.DocTestParser()
+    >>> for piece in parser.parse(s):
+    ...     if isinstance(piece, doctest.Example):
+    ...         print 'Example:', (piece.source, piece.want, piece.lineno)
+    ...     else:
+    ...         print '   Text:', `piece`
+       Text: '\n'
+    Example: ('x, y = 2, 3  # no output expected\n', '', 1)
+       Text: ''
+    Example: ('if 1:\n    print x\n    print y\n', '2\n3\n', 2)
+       Text: '\nSome text.\n'
+    Example: ('x+y\n', '5\n', 9)
+       Text: ''
+
+The `get_examples` method returns just the examples:
+
+    >>> for piece in parser.get_examples(s):
+    ...     print (piece.source, piece.want, piece.lineno)
+    ('x, y = 2, 3  # no output expected\n', '', 1)
+    ('if 1:\n    print x\n    print y\n', '2\n3\n', 2)
+    ('x+y\n', '5\n', 9)
+
+The `get_doctest` method creates a Test from the examples, along with the
+given arguments:
+
+    >>> test = parser.get_doctest(s, {}, 'name', 'filename', lineno=5)
+    >>> (test.name, test.filename, test.lineno)
+    ('name', 'filename', 5)
+    >>> for piece in test.examples:
+    ...     print (piece.source, piece.want, piece.lineno)
+    ('x, y = 2, 3  # no output expected\n', '', 1)
+    ('if 1:\n    print x\n    print y\n', '2\n3\n', 2)
+    ('x+y\n', '5\n', 9)
+"""
+
+class test_DocTestRunner:
+    def basics(): r"""
+Unit tests for the `DocTestRunner` class.
+
+DocTestRunner is used to run DocTest test cases, and to accumulate
+statistics.  Here's a simple DocTest case we can use:
+
+    >>> def f(x):
+    ...     '''
+    ...     >>> x = 12
+    ...     >>> print x
+    ...     12
+    ...     >>> x//2
+    ...     6
+    ...     '''
+    >>> test = doctest.DocTestFinder().find(f)[0]
+
+The main DocTestRunner interface is the `run` method, which runs a
+given DocTest case in a given namespace (globs).  It returns a tuple
+`(f,t)`, where `f` is the number of failed tests and `t` is the number
+of tried tests.
+
+    >>> doctest.DocTestRunner(verbose=False).run(test)
+    (0, 3)
+
+If any example produces incorrect output, then the test runner reports
+the failure and proceeds to the next example:
+
+    >>> def f(x):
+    ...     '''
+    ...     >>> x = 12
+    ...     >>> print x
+    ...     14
+    ...     >>> x//2
+    ...     6
+    ...     '''
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> doctest.DocTestRunner(verbose=True).run(test)
+    ... # doctest: +ELLIPSIS
+    Trying:
+        x = 12
+    Expecting nothing
+    ok
+    Trying:
+        print x
+    Expecting:
+        14
+    **********************************************************************
+    File ..., line 4, in f
+    Failed example:
+        print x
+    Expected:
+        14
+    Got:
+        12
+    Trying:
+        x//2
+    Expecting:
+        6
+    ok
+    (1, 3)
+"""
+    def verbose_flag(): r"""
+The `verbose` flag makes the test runner generate more detailed
+output:
+
+    >>> def f(x):
+    ...     '''
+    ...     >>> x = 12
+    ...     >>> print x
+    ...     12
+    ...     >>> x//2
+    ...     6
+    ...     '''
+    >>> test = doctest.DocTestFinder().find(f)[0]
+
+    >>> doctest.DocTestRunner(verbose=True).run(test)
+    Trying:
+        x = 12
+    Expecting nothing
+    ok
+    Trying:
+        print x
+    Expecting:
+        12
+    ok
+    Trying:
+        x//2
+    Expecting:
+        6
+    ok
+    (0, 3)
+
+If the `verbose` flag is unspecified, then the output will be verbose
+iff `-v` appears in sys.argv:
+
+    >>> # Save the real sys.argv list.
+    >>> old_argv = sys.argv
+
+    >>> # If -v does not appear in sys.argv, then output isn't verbose.
+    >>> sys.argv = ['test']
+    >>> doctest.DocTestRunner().run(test)
+    (0, 3)
+
+    >>> # If -v does appear in sys.argv, then output is verbose.
+    >>> sys.argv = ['test', '-v']
+    >>> doctest.DocTestRunner().run(test)
+    Trying:
+        x = 12
+    Expecting nothing
+    ok
+    Trying:
+        print x
+    Expecting:
+        12
+    ok
+    Trying:
+        x//2
+    Expecting:
+        6
+    ok
+    (0, 3)
+
+    >>> # Restore sys.argv
+    >>> sys.argv = old_argv
+
+In the remaining examples, the test runner's verbosity will be
+explicitly set, to ensure that the test behavior is consistent.
+    """
+    def exceptions(): r"""
+Tests of `DocTestRunner`'s exception handling.
+
+An expected exception is specified with a traceback message.  The
+lines between the first line and the type/value may be omitted or
+replaced with any other string:
+
+    >>> def f(x):
+    ...     '''
+    ...     >>> x = 12
+    ...     >>> print x//0
+    ...     Traceback (most recent call last):
+    ...     ZeroDivisionError: integer division or modulo by zero
+    ...     '''
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> doctest.DocTestRunner(verbose=False).run(test)
+    (0, 2)
+
+An example may not generate output before it raises an exception; if
+it does, then the traceback message will not be recognized as
+signaling an expected exception, so the example will be reported as an
+unexpected exception:
+
+    >>> def f(x):
+    ...     '''
+    ...     >>> x = 12
+    ...     >>> print 'pre-exception output', x//0
+    ...     pre-exception output
+    ...     Traceback (most recent call last):
+    ...     ZeroDivisionError: integer division or modulo by zero
+    ...     '''
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> doctest.DocTestRunner(verbose=False).run(test)
+    ... # doctest: +ELLIPSIS
+    **********************************************************************
+    File ..., line 4, in f
+    Failed example:
+        print 'pre-exception output', x//0
+    Exception raised:
+        ...
+        ZeroDivisionError: integer division or modulo by zero
+    (1, 2)
+
+Exception messages may contain newlines:
+
+    >>> def f(x):
+    ...     r'''
+    ...     >>> raise ValueError, 'multi\nline\nmessage'
+    ...     Traceback (most recent call last):
+    ...     ValueError: multi
+    ...     line
+    ...     message
+    ...     '''
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> doctest.DocTestRunner(verbose=False).run(test)
+    (0, 1)
+
+If an exception is expected, but an exception with the wrong type or
+message is raised, then it is reported as a failure:
+
+    >>> def f(x):
+    ...     r'''
+    ...     >>> raise ValueError, 'message'
+    ...     Traceback (most recent call last):
+    ...     ValueError: wrong message
+    ...     '''
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> doctest.DocTestRunner(verbose=False).run(test)
+    ... # doctest: +ELLIPSIS
+    **********************************************************************
+    File ..., line 3, in f
+    Failed example:
+        raise ValueError, 'message'
+    Expected:
+        Traceback (most recent call last):
+        ValueError: wrong message
+    Got:
+        Traceback (most recent call last):
+        ...
+        ValueError: message
+    (1, 1)
+
+However, IGNORE_EXCEPTION_DETAIL can be used to allow a mismatch in the
+detail:
+
+    >>> def f(x):
+    ...     r'''
+    ...     >>> raise ValueError, 'message' #doctest: +IGNORE_EXCEPTION_DETAIL
+    ...     Traceback (most recent call last):
+    ...     ValueError: wrong message
+    ...     '''
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> doctest.DocTestRunner(verbose=False).run(test)
+    (0, 1)
+
+But IGNORE_EXCEPTION_DETAIL does not allow a mismatch in the exception type:
+
+    >>> def f(x):
+    ...     r'''
+    ...     >>> raise ValueError, 'message' #doctest: +IGNORE_EXCEPTION_DETAIL
+    ...     Traceback (most recent call last):
+    ...     TypeError: wrong type
+    ...     '''
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> doctest.DocTestRunner(verbose=False).run(test)
+    ... # doctest: +ELLIPSIS
+    **********************************************************************
+    File ..., line 3, in f
+    Failed example:
+        raise ValueError, 'message' #doctest: +IGNORE_EXCEPTION_DETAIL
+    Expected:
+        Traceback (most recent call last):
+        TypeError: wrong type
+    Got:
+        Traceback (most recent call last):
+        ...
+        ValueError: message
+    (1, 1)
+
+If an exception is raised but not expected, then it is reported as an
+unexpected exception:
+
+    >>> def f(x):
+    ...     r'''
+    ...     >>> 1//0
+    ...     0
+    ...     '''
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> doctest.DocTestRunner(verbose=False).run(test)
+    ... # doctest: +ELLIPSIS
+    **********************************************************************
+    File ..., line 3, in f
+    Failed example:
+        1//0
+    Exception raised:
+        Traceback (most recent call last):
+        ...
+        ZeroDivisionError: integer division or modulo by zero
+    (1, 1)
+"""
+    def optionflags(): r"""
+Tests of `DocTestRunner`'s option flag handling.
+
+Several option flags can be used to customize the behavior of the test
+runner.  These are defined as module constants in doctest, and passed
+to the DocTestRunner constructor (multiple constants should be or-ed
+together).
+
+The DONT_ACCEPT_TRUE_FOR_1 flag disables matches between True/False
+and 1/0:
+
+    >>> def f(x):
+    ...     '>>> True\n1\n'
+
+    >>> # Without the flag:
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> doctest.DocTestRunner(verbose=False).run(test)
+    (0, 1)
+
+    >>> # With the flag:
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> flags = doctest.DONT_ACCEPT_TRUE_FOR_1
+    >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test)
+    ... # doctest: +ELLIPSIS
+    **********************************************************************
+    File ..., line 2, in f
+    Failed example:
+        True
+    Expected:
+        1
+    Got:
+        True
+    (1, 1)
+
+The DONT_ACCEPT_BLANKLINE flag disables the match between blank lines
+and the '<BLANKLINE>' marker:
+
+    >>> def f(x):
+    ...     '>>> print "a\\n\\nb"\na\n<BLANKLINE>\nb\n'
+
+    >>> # Without the flag:
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> doctest.DocTestRunner(verbose=False).run(test)
+    (0, 1)
+
+    >>> # With the flag:
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> flags = doctest.DONT_ACCEPT_BLANKLINE
+    >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test)
+    ... # doctest: +ELLIPSIS
+    **********************************************************************
+    File ..., line 2, in f
+    Failed example:
+        print "a\n\nb"
+    Expected:
+        a
+        <BLANKLINE>
+        b
+    Got:
+        a
+    <BLANKLINE>
+        b
+    (1, 1)
+
+The NORMALIZE_WHITESPACE flag causes all sequences of whitespace to be
+treated as equal:
+
+    >>> def f(x):
+    ...     '>>> print 1, 2, 3\n  1   2\n 3'
+
+    >>> # Without the flag:
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> doctest.DocTestRunner(verbose=False).run(test)
+    ... # doctest: +ELLIPSIS
+    **********************************************************************
+    File ..., line 2, in f
+    Failed example:
+        print 1, 2, 3
+    Expected:
+          1   2
+         3
+    Got:
+        1 2 3
+    (1, 1)
+
+    >>> # With the flag:
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> flags = doctest.NORMALIZE_WHITESPACE
+    >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test)
+    (0, 1)
+
+    An example from the docs:
+    >>> print range(20) #doctest: +NORMALIZE_WHITESPACE
+    [0,   1,  2,  3,  4,  5,  6,  7,  8,  9,
+    10,  11, 12, 13, 14, 15, 16, 17, 18, 19]
+
+The ELLIPSIS flag causes ellipsis marker ("...") in the expected
+output to match any substring in the actual output:
+
+    >>> def f(x):
+    ...     '>>> print range(15)\n[0, 1, 2, ..., 14]\n'
+
+    >>> # Without the flag:
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> doctest.DocTestRunner(verbose=False).run(test)
+    ... # doctest: +ELLIPSIS
+    **********************************************************************
+    File ..., line 2, in f
+    Failed example:
+        print range(15)
+    Expected:
+        [0, 1, 2, ..., 14]
+    Got:
+        [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
+    (1, 1)
+
+    >>> # With the flag:
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> flags = doctest.ELLIPSIS
+    >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test)
+    (0, 1)
+
+    ... also matches nothing:
+
+    >>> for i in range(100):
+    ...     print i**2, #doctest: +ELLIPSIS
+    0 1...4...9 16 ... 36 49 64 ... 9801
+
+    ... can be surprising; e.g., this test passes:
+
+    >>> for i in range(21): #doctest: +ELLIPSIS
+    ...     print i,
+    0 1 2 ...1...2...0
+
+    Examples from the docs:
+
+    >>> print range(20) # doctest:+ELLIPSIS
+    [0, 1, ..., 18, 19]
+
+    >>> print range(20) # doctest: +ELLIPSIS
+    ...                 # doctest: +NORMALIZE_WHITESPACE
+    [0,    1, ...,   18,    19]
+
+The SKIP flag causes an example to be skipped entirely.  I.e., the
+example is not run.  It can be useful in contexts where doctest
+examples serve as both documentation and test cases, and an example
+should be included for documentation purposes, but should not be
+checked (e.g., because its output is random, or depends on resources
+which would be unavailable.)  The SKIP flag can also be used for
+'commenting out' broken examples.
+
+    >>> import unavailable_resource           # doctest: +SKIP
+    >>> unavailable_resource.do_something()   # doctest: +SKIP
+    >>> unavailable_resource.blow_up()        # doctest: +SKIP
+    Traceback (most recent call last):
+        ...
+    UncheckedBlowUpError:  Nobody checks me.
+
+    >>> import random
+    >>> print random.random() # doctest: +SKIP
+    0.721216923889
+
+The REPORT_UDIFF flag causes failures that involve multi-line expected
+and actual outputs to be displayed using a unified diff:
+
+    >>> def f(x):
+    ...     r'''
+    ...     >>> print '\n'.join('abcdefg')
+    ...     a
+    ...     B
+    ...     c
+    ...     d
+    ...     f
+    ...     g
+    ...     h
+    ...     '''
+
+    >>> # Without the flag:
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> doctest.DocTestRunner(verbose=False).run(test)
+    ... # doctest: +ELLIPSIS
+    **********************************************************************
+    File ..., line 3, in f
+    Failed example:
+        print '\n'.join('abcdefg')
+    Expected:
+        a
+        B
+        c
+        d
+        f
+        g
+        h
+    Got:
+        a
+        b
+        c
+        d
+        e
+        f
+        g
+    (1, 1)
+
+    >>> # With the flag:
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> flags = doctest.REPORT_UDIFF
+    >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test)
+    ... # doctest: +ELLIPSIS
+    **********************************************************************
+    File ..., line 3, in f
+    Failed example:
+        print '\n'.join('abcdefg')
+    Differences (unified diff with -expected +actual):
+        @@ -1,7 +1,7 @@
+         a
+        -B
+        +b
+         c
+         d
+        +e
+         f
+         g
+        -h
+    (1, 1)
+
+The REPORT_CDIFF flag causes failures that involve multi-line expected
+and actual outputs to be displayed using a context diff:
+
+    >>> # Reuse f() from the REPORT_UDIFF example, above.
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> flags = doctest.REPORT_CDIFF
+    >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test)
+    ... # doctest: +ELLIPSIS
+    **********************************************************************
+    File ..., line 3, in f
+    Failed example:
+        print '\n'.join('abcdefg')
+    Differences (context diff with expected followed by actual):
+        ***************
+        *** 1,7 ****
+          a
+        ! B
+          c
+          d
+          f
+          g
+        - h
+        --- 1,7 ----
+          a
+        ! b
+          c
+          d
+        + e
+          f
+          g
+    (1, 1)
+
+
+The REPORT_NDIFF flag causes failures to use the difflib.Differ algorithm
+used by the popular ndiff.py utility.  This does intraline difference
+marking, as well as interline differences.
+
+    >>> def f(x):
+    ...     r'''
+    ...     >>> print "a b  c d e f g h i   j k l m"
+    ...     a b c d e f g h i j k 1 m
+    ...     '''
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> flags = doctest.REPORT_NDIFF
+    >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test)
+    ... # doctest: +ELLIPSIS
+    **********************************************************************
+    File ..., line 3, in f
+    Failed example:
+        print "a b  c d e f g h i   j k l m"
+    Differences (ndiff with -expected +actual):
+        - a b c d e f g h i j k 1 m
+        ?                       ^
+        + a b  c d e f g h i   j k l m
+        ?     +              ++    ^
+    (1, 1)
+
+The REPORT_ONLY_FIRST_FAILURE supresses result output after the first
+failing example:
+
+    >>> def f(x):
+    ...     r'''
+    ...     >>> print 1 # first success
+    ...     1
+    ...     >>> print 2 # first failure
+    ...     200
+    ...     >>> print 3 # second failure
+    ...     300
+    ...     >>> print 4 # second success
+    ...     4
+    ...     >>> print 5 # third failure
+    ...     500
+    ...     '''
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> flags = doctest.REPORT_ONLY_FIRST_FAILURE
+    >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test)
+    ... # doctest: +ELLIPSIS
+    **********************************************************************
+    File ..., line 5, in f
+    Failed example:
+        print 2 # first failure
+    Expected:
+        200
+    Got:
+        2
+    (3, 5)
+
+However, output from `report_start` is not supressed:
+
+    >>> doctest.DocTestRunner(verbose=True, optionflags=flags).run(test)
+    ... # doctest: +ELLIPSIS
+    Trying:
+        print 1 # first success
+    Expecting:
+        1
+    ok
+    Trying:
+        print 2 # first failure
+    Expecting:
+        200
+    **********************************************************************
+    File ..., line 5, in f
+    Failed example:
+        print 2 # first failure
+    Expected:
+        200
+    Got:
+        2
+    (3, 5)
+
+For the purposes of REPORT_ONLY_FIRST_FAILURE, unexpected exceptions
+count as failures:
+
+    >>> def f(x):
+    ...     r'''
+    ...     >>> print 1 # first success
+    ...     1
+    ...     >>> raise ValueError(2) # first failure
+    ...     200
+    ...     >>> print 3 # second failure
+    ...     300
+    ...     >>> print 4 # second success
+    ...     4
+    ...     >>> print 5 # third failure
+    ...     500
+    ...     '''
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> flags = doctest.REPORT_ONLY_FIRST_FAILURE
+    >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test)
+    ... # doctest: +ELLIPSIS
+    **********************************************************************
+    File ..., line 5, in f
+    Failed example:
+        raise ValueError(2) # first failure
+    Exception raised:
+        ...
+        ValueError: 2
+    (3, 5)
+
+New option flags can also be registered, via register_optionflag().  Here
+we reach into doctest's internals a bit.
+
+    >>> unlikely = "UNLIKELY_OPTION_NAME"
+    >>> unlikely in doctest.OPTIONFLAGS_BY_NAME
+    False
+    >>> new_flag_value = doctest.register_optionflag(unlikely)
+    >>> unlikely in doctest.OPTIONFLAGS_BY_NAME
+    True
+
+Before 2.4.4/2.5, registering a name more than once erroneously created
+more than one flag value.  Here we verify that's fixed:
+
+    >>> redundant_flag_value = doctest.register_optionflag(unlikely)
+    >>> redundant_flag_value == new_flag_value
+    True
+
+Clean up.
+    >>> del doctest.OPTIONFLAGS_BY_NAME[unlikely]
+
+    """
+
+    def option_directives(): r"""
+Tests of `DocTestRunner`'s option directive mechanism.
+
+Option directives can be used to turn option flags on or off for a
+single example.  To turn an option on for an example, follow that
+example with a comment of the form ``# doctest: +OPTION``:
+
+    >>> def f(x): r'''
+    ...     >>> print range(10)       # should fail: no ellipsis
+    ...     [0, 1, ..., 9]
+    ...
+    ...     >>> print range(10)       # doctest: +ELLIPSIS
+    ...     [0, 1, ..., 9]
+    ...     '''
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> doctest.DocTestRunner(verbose=False).run(test)
+    ... # doctest: +ELLIPSIS
+    **********************************************************************
+    File ..., line 2, in f
+    Failed example:
+        print range(10)       # should fail: no ellipsis
+    Expected:
+        [0, 1, ..., 9]
+    Got:
+        [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+    (1, 2)
+
+To turn an option off for an example, follow that example with a
+comment of the form ``# doctest: -OPTION``:
+
+    >>> def f(x): r'''
+    ...     >>> print range(10)
+    ...     [0, 1, ..., 9]
+    ...
+    ...     >>> # should fail: no ellipsis
+    ...     >>> print range(10)       # doctest: -ELLIPSIS
+    ...     [0, 1, ..., 9]
+    ...     '''
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> doctest.DocTestRunner(verbose=False,
+    ...                       optionflags=doctest.ELLIPSIS).run(test)
+    ... # doctest: +ELLIPSIS
+    **********************************************************************
+    File ..., line 6, in f
+    Failed example:
+        print range(10)       # doctest: -ELLIPSIS
+    Expected:
+        [0, 1, ..., 9]
+    Got:
+        [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+    (1, 2)
+
+Option directives affect only the example that they appear with; they
+do not change the options for surrounding examples:
+
+    >>> def f(x): r'''
+    ...     >>> print range(10)       # Should fail: no ellipsis
+    ...     [0, 1, ..., 9]
+    ...
+    ...     >>> print range(10)       # doctest: +ELLIPSIS
+    ...     [0, 1, ..., 9]
+    ...
+    ...     >>> print range(10)       # Should fail: no ellipsis
+    ...     [0, 1, ..., 9]
+    ...     '''
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> doctest.DocTestRunner(verbose=False).run(test)
+    ... # doctest: +ELLIPSIS
+    **********************************************************************
+    File ..., line 2, in f
+    Failed example:
+        print range(10)       # Should fail: no ellipsis
+    Expected:
+        [0, 1, ..., 9]
+    Got:
+        [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+    **********************************************************************
+    File ..., line 8, in f
+    Failed example:
+        print range(10)       # Should fail: no ellipsis
+    Expected:
+        [0, 1, ..., 9]
+    Got:
+        [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+    (2, 3)
+
+Multiple options may be modified by a single option directive.  They
+may be separated by whitespace, commas, or both:
+
+    >>> def f(x): r'''
+    ...     >>> print range(10)       # Should fail
+    ...     [0, 1,  ...,   9]
+    ...     >>> print range(10)       # Should succeed
+    ...     ... # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
+    ...     [0, 1,  ...,   9]
+    ...     '''
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> doctest.DocTestRunner(verbose=False).run(test)
+    ... # doctest: +ELLIPSIS
+    **********************************************************************
+    File ..., line 2, in f
+    Failed example:
+        print range(10)       # Should fail
+    Expected:
+        [0, 1,  ...,   9]
+    Got:
+        [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+    (1, 2)
+
+    >>> def f(x): r'''
+    ...     >>> print range(10)       # Should fail
+    ...     [0, 1,  ...,   9]
+    ...     >>> print range(10)       # Should succeed
+    ...     ... # doctest: +ELLIPSIS,+NORMALIZE_WHITESPACE
+    ...     [0, 1,  ...,   9]
+    ...     '''
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> doctest.DocTestRunner(verbose=False).run(test)
+    ... # doctest: +ELLIPSIS
+    **********************************************************************
+    File ..., line 2, in f
+    Failed example:
+        print range(10)       # Should fail
+    Expected:
+        [0, 1,  ...,   9]
+    Got:
+        [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+    (1, 2)
+
+    >>> def f(x): r'''
+    ...     >>> print range(10)       # Should fail
+    ...     [0, 1,  ...,   9]
+    ...     >>> print range(10)       # Should succeed
+    ...     ... # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
+    ...     [0, 1,  ...,   9]
+    ...     '''
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> doctest.DocTestRunner(verbose=False).run(test)
+    ... # doctest: +ELLIPSIS
+    **********************************************************************
+    File ..., line 2, in f
+    Failed example:
+        print range(10)       # Should fail
+    Expected:
+        [0, 1,  ...,   9]
+    Got:
+        [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+    (1, 2)
+
+The option directive may be put on the line following the source, as
+long as a continuation prompt is used:
+
+    >>> def f(x): r'''
+    ...     >>> print range(10)
+    ...     ... # doctest: +ELLIPSIS
+    ...     [0, 1, ..., 9]
+    ...     '''
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> doctest.DocTestRunner(verbose=False).run(test)
+    (0, 1)
+
+For examples with multi-line source, the option directive may appear
+at the end of any line:
+
+    >>> def f(x): r'''
+    ...     >>> for x in range(10): # doctest: +ELLIPSIS
+    ...     ...     print x,
+    ...     0 1 2 ... 9
+    ...
+    ...     >>> for x in range(10):
+    ...     ...     print x,        # doctest: +ELLIPSIS
+    ...     0 1 2 ... 9
+    ...     '''
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> doctest.DocTestRunner(verbose=False).run(test)
+    (0, 2)
+
+If more than one line of an example with multi-line source has an
+option directive, then they are combined:
+
+    >>> def f(x): r'''
+    ...     Should fail (option directive not on the last line):
+    ...         >>> for x in range(10): # doctest: +ELLIPSIS
+    ...         ...     print x,        # doctest: +NORMALIZE_WHITESPACE
+    ...         0  1    2...9
+    ...     '''
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> doctest.DocTestRunner(verbose=False).run(test)
+    (0, 1)
+
+It is an error to have a comment of the form ``# doctest:`` that is
+*not* followed by words of the form ``+OPTION`` or ``-OPTION``, where
+``OPTION`` is an option that has been registered with
+`register_option`:
+
+    >>> # Error: Option not registered
+    >>> s = '>>> print 12   #doctest: +BADOPTION'
+    >>> test = doctest.DocTestParser().get_doctest(s, {}, 's', 's.py', 0)
+    Traceback (most recent call last):
+    ValueError: line 1 of the doctest for s has an invalid option: '+BADOPTION'
+
+    >>> # Error: No + or - prefix
+    >>> s = '>>> print 12   #doctest: ELLIPSIS'
+    >>> test = doctest.DocTestParser().get_doctest(s, {}, 's', 's.py', 0)
+    Traceback (most recent call last):
+    ValueError: line 1 of the doctest for s has an invalid option: 'ELLIPSIS'
+
+It is an error to use an option directive on a line that contains no
+source:
+
+    >>> s = '>>> # doctest: +ELLIPSIS'
+    >>> test = doctest.DocTestParser().get_doctest(s, {}, 's', 's.py', 0)
+    Traceback (most recent call last):
+    ValueError: line 0 of the doctest for s has an option directive on a line with no example: '# doctest: +ELLIPSIS'
+"""
+
+def test_testsource(): r"""
+Unit tests for `testsource()`.
+
+The testsource() function takes a module and a name, finds the (first)
+test with that name in that module, and converts it to a script. The
+example code is converted to regular Python code.  The surrounding
+words and expected output are converted to comments:
+
+    >>> import test.test_doctest
+    >>> name = 'test.test_doctest.sample_func'
+    >>> print doctest.testsource(test.test_doctest, name)
+    # Blah blah
+    #
+    print sample_func(22)
+    # Expected:
+    ## 44
+    #
+    # Yee ha!
+    <BLANKLINE>
+
+    >>> name = 'test.test_doctest.SampleNewStyleClass'
+    >>> print doctest.testsource(test.test_doctest, name)
+    print '1\n2\n3'
+    # Expected:
+    ## 1
+    ## 2
+    ## 3
+    <BLANKLINE>
+
+    >>> name = 'test.test_doctest.SampleClass.a_classmethod'
+    >>> print doctest.testsource(test.test_doctest, name)
+    print SampleClass.a_classmethod(10)
+    # Expected:
+    ## 12
+    print SampleClass(0).a_classmethod(10)
+    # Expected:
+    ## 12
+    <BLANKLINE>
+"""
+
+def test_debug(): r"""
+
+Create a docstring that we want to debug:
+
+    >>> s = '''
+    ...     >>> x = 12
+    ...     >>> print x
+    ...     12
+    ...     '''
+
+Create some fake stdin input, to feed to the debugger:
+
+    >>> import tempfile
+    >>> real_stdin = sys.stdin
+    >>> sys.stdin = _FakeInput(['next', 'print x', 'continue'])
+
+Run the debugger on the docstring, and then restore sys.stdin.
+
+    >>> try: doctest.debug_src(s)
+    ... finally: sys.stdin = real_stdin
+    > <string>(1)<module>()
+    (Pdb) next
+    12
+    --Return--
+    > <string>(1)<module>()->None
+    (Pdb) print x
+    12
+    (Pdb) continue
+
+"""
+
+def test_pdb_set_trace():
+    """Using pdb.set_trace from a doctest.
+
+    You can use pdb.set_trace from a doctest.  To do so, you must
+    retrieve the set_trace function from the pdb module at the time
+    you use it.  The doctest module changes sys.stdout so that it can
+    capture program output.  It also temporarily replaces pdb.set_trace
+    with a version that restores stdout.  This is necessary for you to
+    see debugger output.
+
+      >>> doc = '''
+      ... >>> x = 42
+      ... >>> import pdb; pdb.set_trace()
+      ... '''
+      >>> parser = doctest.DocTestParser()
+      >>> test = parser.get_doctest(doc, {}, "foo", "foo.py", 0)
+      >>> runner = doctest.DocTestRunner(verbose=False)
+
+    To demonstrate this, we'll create a fake standard input that
+    captures our debugger input:
+
+      >>> import tempfile
+      >>> real_stdin = sys.stdin
+      >>> sys.stdin = _FakeInput([
+      ...    'print x',  # print data defined by the example
+      ...    'continue', # stop debugging
+      ...    ''])
+
+      >>> try: runner.run(test)
+      ... finally: sys.stdin = real_stdin
+      --Return--
+      > <doctest foo[1]>(1)<module>()->None
+      -> import pdb; pdb.set_trace()
+      (Pdb) print x
+      42
+      (Pdb) continue
+      (0, 2)
+
+      You can also put pdb.set_trace in a function called from a test:
+
+      >>> def calls_set_trace():
+      ...    y=2
+      ...    import pdb; pdb.set_trace()
+
+      >>> doc = '''
+      ... >>> x=1
+      ... >>> calls_set_trace()
+      ... '''
+      >>> test = parser.get_doctest(doc, globals(), "foo", "foo.py", 0)
+      >>> real_stdin = sys.stdin
+      >>> sys.stdin = _FakeInput([
+      ...    'print y',  # print data defined in the function
+      ...    'up',       # out of function
+      ...    'print x',  # print data defined by the example
+      ...    'continue', # stop debugging
+      ...    ''])
+
+      >>> try:
+      ...     runner.run(test)
+      ... finally:
+      ...     sys.stdin = real_stdin
+      --Return--
+      > <doctest test.test_doctest.test_pdb_set_trace[8]>(3)calls_set_trace()->None
+      -> import pdb; pdb.set_trace()
+      (Pdb) print y
+      2
+      (Pdb) up
+      > <doctest foo[1]>(1)<module>()
+      -> calls_set_trace()
+      (Pdb) print x
+      1
+      (Pdb) continue
+      (0, 2)
+
+    During interactive debugging, source code is shown, even for
+    doctest examples:
+
+      >>> doc = '''
+      ... >>> def f(x):
+      ... ...     g(x*2)
+      ... >>> def g(x):
+      ... ...     print x+3
+      ... ...     import pdb; pdb.set_trace()
+      ... >>> f(3)
+      ... '''
+      >>> test = parser.get_doctest(doc, globals(), "foo", "foo.py", 0)
+      >>> real_stdin = sys.stdin
+      >>> sys.stdin = _FakeInput([
+      ...    'list',     # list source from example 2
+      ...    'next',     # return from g()
+      ...    'list',     # list source from example 1
+      ...    'next',     # return from f()
+      ...    'list',     # list source from example 3
+      ...    'continue', # stop debugging
+      ...    ''])
+      >>> try: runner.run(test)
+      ... finally: sys.stdin = real_stdin
+      ... # doctest: +NORMALIZE_WHITESPACE
+      --Return--
+      > <doctest foo[1]>(3)g()->None
+      -> import pdb; pdb.set_trace()
+      (Pdb) list
+        1     def g(x):
+        2         print x+3
+        3  ->     import pdb; pdb.set_trace()
+      [EOF]
+      (Pdb) next
+      --Return--
+      > <doctest foo[0]>(2)f()->None
+      -> g(x*2)
+      (Pdb) list
+        1     def f(x):
+        2  ->     g(x*2)
+      [EOF]
+      (Pdb) next
+      --Return--
+      > <doctest foo[2]>(1)<module>()->None
+      -> f(3)
+      (Pdb) list
+        1  -> f(3)
+      [EOF]
+      (Pdb) continue
+      **********************************************************************
+      File "foo.py", line 7, in foo
+      Failed example:
+          f(3)
+      Expected nothing
+      Got:
+          9
+      (1, 3)
+      """
+
+def test_pdb_set_trace_nested():
+    """This illustrates more-demanding use of set_trace with nested functions.
+
+    >>> class C(object):
+    ...     def calls_set_trace(self):
+    ...         y = 1
+    ...         import pdb; pdb.set_trace()
+    ...         self.f1()
+    ...         y = 2
+    ...     def f1(self):
+    ...         x = 1
+    ...         self.f2()
+    ...         x = 2
+    ...     def f2(self):
+    ...         z = 1
+    ...         z = 2
+
+    >>> calls_set_trace = C().calls_set_trace
+
+    >>> doc = '''
+    ... >>> a = 1
+    ... >>> calls_set_trace()
+    ... '''
+    >>> parser = doctest.DocTestParser()
+    >>> runner = doctest.DocTestRunner(verbose=False)
+    >>> test = parser.get_doctest(doc, globals(), "foo", "foo.py", 0)
+    >>> real_stdin = sys.stdin
+    >>> sys.stdin = _FakeInput([
+    ...    'print y',  # print data defined in the function
+    ...    'step', 'step', 'step', 'step', 'step', 'step', 'print z',
+    ...    'up', 'print x',
+    ...    'up', 'print y',
+    ...    'up', 'print foo',
+    ...    'continue', # stop debugging
+    ...    ''])
+
+    >>> try:
+    ...     runner.run(test)
+    ... finally:
+    ...     sys.stdin = real_stdin
+    > <doctest test.test_doctest.test_pdb_set_trace_nested[0]>(5)calls_set_trace()
+    -> self.f1()
+    (Pdb) print y
+    1
+    (Pdb) step
+    --Call--
+    > <doctest test.test_doctest.test_pdb_set_trace_nested[0]>(7)f1()
+    -> def f1(self):
+    (Pdb) step
+    > <doctest test.test_doctest.test_pdb_set_trace_nested[0]>(8)f1()
+    -> x = 1
+    (Pdb) step
+    > <doctest test.test_doctest.test_pdb_set_trace_nested[0]>(9)f1()
+    -> self.f2()
+    (Pdb) step
+    --Call--
+    > <doctest test.test_doctest.test_pdb_set_trace_nested[0]>(11)f2()
+    -> def f2(self):
+    (Pdb) step
+    > <doctest test.test_doctest.test_pdb_set_trace_nested[0]>(12)f2()
+    -> z = 1
+    (Pdb) step
+    > <doctest test.test_doctest.test_pdb_set_trace_nested[0]>(13)f2()
+    -> z = 2
+    (Pdb) print z
+    1
+    (Pdb) up
+    > <doctest test.test_doctest.test_pdb_set_trace_nested[0]>(9)f1()
+    -> self.f2()
+    (Pdb) print x
+    1
+    (Pdb) up
+    > <doctest test.test_doctest.test_pdb_set_trace_nested[0]>(5)calls_set_trace()
+    -> self.f1()
+    (Pdb) print y
+    1
+    (Pdb) up
+    > <doctest foo[1]>(1)<module>()
+    -> calls_set_trace()
+    (Pdb) print foo
+    *** NameError: name 'foo' is not defined
+    (Pdb) continue
+    (0, 2)
+"""
+
+def test_DocTestSuite():
+    """DocTestSuite creates a unittest test suite from a doctest.
+
+       We create a Suite by providing a module.  A module can be provided
+       by passing a module object:
+
+         >>> import unittest
+         >>> import test.sample_doctest
+         >>> suite = doctest.DocTestSuite(test.sample_doctest)
+         >>> suite.run(unittest.TestResult())
+         <unittest.TestResult run=9 errors=0 failures=4>
+
+       We can also supply the module by name:
+
+         >>> suite = doctest.DocTestSuite('test.sample_doctest')
+         >>> suite.run(unittest.TestResult())
+         <unittest.TestResult run=9 errors=0 failures=4>
+
+       We can use the current module:
+
+         >>> suite = test.sample_doctest.test_suite()
+         >>> suite.run(unittest.TestResult())
+         <unittest.TestResult run=9 errors=0 failures=4>
+
+       We can supply global variables.  If we pass globs, they will be
+       used instead of the module globals.  Here we'll pass an empty
+       globals, triggering an extra error:
+
+         >>> suite = doctest.DocTestSuite('test.sample_doctest', globs={})
+         >>> suite.run(unittest.TestResult())
+         <unittest.TestResult run=9 errors=0 failures=5>
+
+       Alternatively, we can provide extra globals.  Here we'll make an
+       error go away by providing an extra global variable:
+
+         >>> suite = doctest.DocTestSuite('test.sample_doctest',
+         ...                              extraglobs={'y': 1})
+         >>> suite.run(unittest.TestResult())
+         <unittest.TestResult run=9 errors=0 failures=3>
+
+       You can pass option flags.  Here we'll cause an extra error
+       by disabling the blank-line feature:
+
+         >>> suite = doctest.DocTestSuite('test.sample_doctest',
+         ...                      optionflags=doctest.DONT_ACCEPT_BLANKLINE)
+         >>> suite.run(unittest.TestResult())
+         <unittest.TestResult run=9 errors=0 failures=5>
+
+       You can supply setUp and tearDown functions:
+
+         >>> def setUp(t):
+         ...     import test.test_doctest
+         ...     test.test_doctest.sillySetup = True
+
+         >>> def tearDown(t):
+         ...     import test.test_doctest
+         ...     del test.test_doctest.sillySetup
+
+       Here, we installed a silly variable that the test expects:
+
+         >>> suite = doctest.DocTestSuite('test.sample_doctest',
+         ...      setUp=setUp, tearDown=tearDown)
+         >>> suite.run(unittest.TestResult())
+         <unittest.TestResult run=9 errors=0 failures=3>
+
+       But the tearDown restores sanity:
+
+         >>> import test.test_doctest
+         >>> test.test_doctest.sillySetup
+         Traceback (most recent call last):
+         ...
+         AttributeError: 'module' object has no attribute 'sillySetup'
+
+       The setUp and tearDown funtions are passed test objects. Here
+       we'll use the setUp function to supply the missing variable y:
+
+         >>> def setUp(test):
+         ...     test.globs['y'] = 1
+
+         >>> suite = doctest.DocTestSuite('test.sample_doctest', setUp=setUp)
+         >>> suite.run(unittest.TestResult())
+         <unittest.TestResult run=9 errors=0 failures=3>
+
+       Here, we didn't need to use a tearDown function because we
+       modified the test globals, which are a copy of the
+       sample_doctest module dictionary.  The test globals are
+       automatically cleared for us after a test.
+       """
+
+def test_DocFileSuite():
+    """We can test tests found in text files using a DocFileSuite.
+
+       We create a suite by providing the names of one or more text
+       files that include examples:
+
+         >>> import unittest
+         >>> suite = doctest.DocFileSuite('test_doctest.txt',
+         ...                              'test_doctest2.txt',
+         ...                              'test_doctest4.txt')
+         >>> suite.run(unittest.TestResult())
+         <unittest.TestResult run=3 errors=0 failures=3>
+
+       The test files are looked for in the directory containing the
+       calling module.  A package keyword argument can be provided to
+       specify a different relative location.
+
+         >>> import unittest
+         >>> suite = doctest.DocFileSuite('test_doctest.txt',
+         ...                              'test_doctest2.txt',
+         ...                              'test_doctest4.txt',
+         ...                              package='test')
+         >>> suite.run(unittest.TestResult())
+         <unittest.TestResult run=3 errors=0 failures=3>
+
+       '/' should be used as a path separator.  It will be converted
+       to a native separator at run time:
+
+         >>> suite = doctest.DocFileSuite('../test/test_doctest.txt')
+         >>> suite.run(unittest.TestResult())
+         <unittest.TestResult run=1 errors=0 failures=1>
+
+       If DocFileSuite is used from an interactive session, then files
+       are resolved relative to the directory of sys.argv[0]:
+
+         >>> import new, os.path, test.test_doctest
+         >>> save_argv = sys.argv
+         >>> sys.argv = [test.test_doctest.__file__]
+         >>> suite = doctest.DocFileSuite('test_doctest.txt',
+         ...                              package=new.module('__main__'))
+         >>> sys.argv = save_argv
+
+       By setting `module_relative=False`, os-specific paths may be
+       used (including absolute paths and paths relative to the
+       working directory):
+
+         >>> # Get the absolute path of the test package.
+         >>> test_doctest_path = os.path.abspath(test.test_doctest.__file__)
+         >>> test_pkg_path = os.path.split(test_doctest_path)[0]
+
+         >>> # Use it to find the absolute path of test_doctest.txt.
+         >>> test_file = os.path.join(test_pkg_path, 'test_doctest.txt')
+
+         >>> suite = doctest.DocFileSuite(test_file, module_relative=False)
+         >>> suite.run(unittest.TestResult())
+         <unittest.TestResult run=1 errors=0 failures=1>
+
+       It is an error to specify `package` when `module_relative=False`:
+
+         >>> suite = doctest.DocFileSuite(test_file, module_relative=False,
+         ...                              package='test')
+         Traceback (most recent call last):
+         ValueError: Package may only be specified for module-relative paths.
+
+       You can specify initial global variables:
+
+         >>> suite = doctest.DocFileSuite('test_doctest.txt',
+         ...                              'test_doctest2.txt',
+         ...                              'test_doctest4.txt',
+         ...                              globs={'favorite_color': 'blue'})
+         >>> suite.run(unittest.TestResult())
+         <unittest.TestResult run=3 errors=0 failures=2>
+
+       In this case, we supplied a missing favorite color. You can
+       provide doctest options:
+
+         >>> suite = doctest.DocFileSuite('test_doctest.txt',
+         ...                              'test_doctest2.txt',
+         ...                              'test_doctest4.txt',
+         ...                         optionflags=doctest.DONT_ACCEPT_BLANKLINE,
+         ...                              globs={'favorite_color': 'blue'})
+         >>> suite.run(unittest.TestResult())
+         <unittest.TestResult run=3 errors=0 failures=3>
+
+       And, you can provide setUp and tearDown functions:
+
+       You can supply setUp and teatDoen functions:
+
+         >>> def setUp(t):
+         ...     import test.test_doctest
+         ...     test.test_doctest.sillySetup = True
+
+         >>> def tearDown(t):
+         ...     import test.test_doctest
+         ...     del test.test_doctest.sillySetup
+
+       Here, we installed a silly variable that the test expects:
+
+         >>> suite = doctest.DocFileSuite('test_doctest.txt',
+         ...                              'test_doctest2.txt',
+         ...                              'test_doctest4.txt',
+         ...                              setUp=setUp, tearDown=tearDown)
+         >>> suite.run(unittest.TestResult())
+         <unittest.TestResult run=3 errors=0 failures=2>
+
+       But the tearDown restores sanity:
+
+         >>> import test.test_doctest
+         >>> test.test_doctest.sillySetup
+         Traceback (most recent call last):
+         ...
+         AttributeError: 'module' object has no attribute 'sillySetup'
+
+       The setUp and tearDown funtions are passed test objects.
+       Here, we'll use a setUp function to set the favorite color in
+       test_doctest.txt:
+
+         >>> def setUp(test):
+         ...     test.globs['favorite_color'] = 'blue'
+
+         >>> suite = doctest.DocFileSuite('test_doctest.txt', setUp=setUp)
+         >>> suite.run(unittest.TestResult())
+         <unittest.TestResult run=1 errors=0 failures=0>
+
+       Here, we didn't need to use a tearDown function because we
+       modified the test globals.  The test globals are
+       automatically cleared for us after a test.
+
+       Tests in a file run using `DocFileSuite` can also access the
+       `__file__` global, which is set to the name of the file
+       containing the tests:
+
+         >>> suite = doctest.DocFileSuite('test_doctest3.txt')
+         >>> suite.run(unittest.TestResult())
+         <unittest.TestResult run=1 errors=0 failures=0>
+
+       If the tests contain non-ASCII characters, we have to specify which
+       encoding the file is encoded with. We do so by using the `encoding`
+       parameter:
+
+         >>> suite = doctest.DocFileSuite('test_doctest.txt',
+         ...                              'test_doctest2.txt',
+         ...                              'test_doctest4.txt',
+         ...                              encoding='utf-8')
+         >>> suite.run(unittest.TestResult())
+         <unittest.TestResult run=3 errors=0 failures=2>
+
+       """
+
+def test_trailing_space_in_test():
+    """
+    Trailing spaces in expected output are significant:
+
+      >>> x, y = 'foo', ''
+      >>> print x, y
+      foo \n
+    """
+
+
+def test_unittest_reportflags():
+    """Default unittest reporting flags can be set to control reporting
+
+    Here, we'll set the REPORT_ONLY_FIRST_FAILURE option so we see
+    only the first failure of each test.  First, we'll look at the
+    output without the flag.  The file test_doctest.txt file has two
+    tests. They both fail if blank lines are disabled:
+
+      >>> suite = doctest.DocFileSuite('test_doctest.txt',
+      ...                          optionflags=doctest.DONT_ACCEPT_BLANKLINE)
+      >>> import unittest
+      >>> result = suite.run(unittest.TestResult())
+      >>> print result.failures[0][1] # doctest: +ELLIPSIS
+      Traceback ...
+      Failed example:
+          favorite_color
+      ...
+      Failed example:
+          if 1:
+      ...
+
+    Note that we see both failures displayed.
+
+      >>> old = doctest.set_unittest_reportflags(
+      ...    doctest.REPORT_ONLY_FIRST_FAILURE)
+
+    Now, when we run the test:
+
+      >>> result = suite.run(unittest.TestResult())
+      >>> print result.failures[0][1] # doctest: +ELLIPSIS
+      Traceback ...
+      Failed example:
+          favorite_color
+      Exception raised:
+          ...
+          NameError: name 'favorite_color' is not defined
+      <BLANKLINE>
+      <BLANKLINE>
+
+    We get only the first failure.
+
+    If we give any reporting options when we set up the tests,
+    however:
+
+      >>> suite = doctest.DocFileSuite('test_doctest.txt',
+      ...     optionflags=doctest.DONT_ACCEPT_BLANKLINE | doctest.REPORT_NDIFF)
+
+    Then the default eporting options are ignored:
+
+      >>> result = suite.run(unittest.TestResult())
+      >>> print result.failures[0][1] # doctest: +ELLIPSIS
+      Traceback ...
+      Failed example:
+          favorite_color
+      ...
+      Failed example:
+          if 1:
+             print 'a'
+             print
+             print 'b'
+      Differences (ndiff with -expected +actual):
+            a
+          - <BLANKLINE>
+          +
+            b
+      <BLANKLINE>
+      <BLANKLINE>
+
+
+    Test runners can restore the formatting flags after they run:
+
+      >>> ignored = doctest.set_unittest_reportflags(old)
+
+    """
+
+def test_testfile(): r"""
+Tests for the `testfile()` function.  This function runs all the
+doctest examples in a given file.  In its simple invokation, it is
+called with the name of a file, which is taken to be relative to the
+calling module.  The return value is (#failures, #tests).
+
+    >>> doctest.testfile('test_doctest.txt') # doctest: +ELLIPSIS
+    **********************************************************************
+    File "...", line 6, in test_doctest.txt
+    Failed example:
+        favorite_color
+    Exception raised:
+        ...
+        NameError: name 'favorite_color' is not defined
+    **********************************************************************
+    1 items had failures:
+       1 of   2 in test_doctest.txt
+    ***Test Failed*** 1 failures.
+    (1, 2)
+    >>> doctest.master = None  # Reset master.
+
+(Note: we'll be clearing doctest.master after each call to
+`doctest.testfile`, to supress warnings about multiple tests with the
+same name.)
+
+Globals may be specified with the `globs` and `extraglobs` parameters:
+
+    >>> globs = {'favorite_color': 'blue'}
+    >>> doctest.testfile('test_doctest.txt', globs=globs)
+    (0, 2)
+    >>> doctest.master = None  # Reset master.
+
+    >>> extraglobs = {'favorite_color': 'red'}
+    >>> doctest.testfile('test_doctest.txt', globs=globs,
+    ...                  extraglobs=extraglobs) # doctest: +ELLIPSIS
+    **********************************************************************
+    File "...", line 6, in test_doctest.txt
+    Failed example:
+        favorite_color
+    Expected:
+        'blue'
+    Got:
+        'red'
+    **********************************************************************
+    1 items had failures:
+       1 of   2 in test_doctest.txt
+    ***Test Failed*** 1 failures.
+    (1, 2)
+    >>> doctest.master = None  # Reset master.
+
+The file may be made relative to a given module or package, using the
+optional `module_relative` parameter:
+
+    >>> doctest.testfile('test_doctest.txt', globs=globs,
+    ...                  module_relative='test')
+    (0, 2)
+    >>> doctest.master = None  # Reset master.
+
+Verbosity can be increased with the optional `verbose` paremter:
+
+    >>> doctest.testfile('test_doctest.txt', globs=globs, verbose=True)
+    Trying:
+        favorite_color
+    Expecting:
+        'blue'
+    ok
+    Trying:
+        if 1:
+           print 'a'
+           print
+           print 'b'
+    Expecting:
+        a
+        <BLANKLINE>
+        b
+    ok
+    1 items passed all tests:
+       2 tests in test_doctest.txt
+    2 tests in 1 items.
+    2 passed and 0 failed.
+    Test passed.
+    (0, 2)
+    >>> doctest.master = None  # Reset master.
+
+The name of the test may be specified with the optional `name`
+parameter:
+
+    >>> doctest.testfile('test_doctest.txt', name='newname')
+    ... # doctest: +ELLIPSIS
+    **********************************************************************
+    File "...", line 6, in newname
+    ...
+    (1, 2)
+    >>> doctest.master = None  # Reset master.
+
+The summary report may be supressed with the optional `report`
+parameter:
+
+    >>> doctest.testfile('test_doctest.txt', report=False)
+    ... # doctest: +ELLIPSIS
+    **********************************************************************
+    File "...", line 6, in test_doctest.txt
+    Failed example:
+        favorite_color
+    Exception raised:
+        ...
+        NameError: name 'favorite_color' is not defined
+    (1, 2)
+    >>> doctest.master = None  # Reset master.
+
+The optional keyword argument `raise_on_error` can be used to raise an
+exception on the first error (which may be useful for postmortem
+debugging):
+
+    >>> doctest.testfile('test_doctest.txt', raise_on_error=True)
+    ... # doctest: +ELLIPSIS
+    Traceback (most recent call last):
+    UnexpectedException: ...
+    >>> doctest.master = None  # Reset master.
+
+If the tests contain non-ASCII characters, the tests might fail, since
+it's unknown which encoding is used. The encoding can be specified
+using the optional keyword argument `encoding`:
+
+    >>> doctest.testfile('test_doctest4.txt') # doctest: +ELLIPSIS
+    **********************************************************************
+    File "...", line 7, in test_doctest4.txt
+    Failed example:
+        u'...'
+    Expected:
+        u'f\xf6\xf6'
+    Got:
+        u'f\xc3\xb6\xc3\xb6'
+    **********************************************************************
+    ...
+    **********************************************************************
+    1 items had failures:
+       2 of   4 in test_doctest4.txt
+    ***Test Failed*** 2 failures.
+    (2, 4)
+    >>> doctest.master = None  # Reset master.
+
+    >>> doctest.testfile('test_doctest4.txt', encoding='utf-8')
+    (0, 4)
+    >>> doctest.master = None  # Reset master.
+"""
+
+# old_test1, ... used to live in doctest.py, but cluttered it.  Note
+# that these use the deprecated doctest.Tester, so should go away (or
+# be rewritten) someday.
+
+# Ignore all warnings about the use of class Tester in this module.
+# Note that the name of this module may differ depending on how it's
+# imported, so the use of __name__ is important.
+warnings.filterwarnings("ignore", "class Tester", DeprecationWarning,
+                        __name__, 0)
+
+def old_test1(): r"""
+>>> from doctest import Tester
+>>> t = Tester(globs={'x': 42}, verbose=0)
+>>> t.runstring(r'''
+...      >>> x = x * 2
+...      >>> print x
+...      42
+... ''', 'XYZ')
+**********************************************************************
+Line 3, in XYZ
+Failed example:
+    print x
+Expected:
+    42
+Got:
+    84
+(1, 2)
+>>> t.runstring(">>> x = x * 2\n>>> print x\n84\n", 'example2')
+(0, 2)
+>>> t.summarize()
+**********************************************************************
+1 items had failures:
+   1 of   2 in XYZ
+***Test Failed*** 1 failures.
+(1, 4)
+>>> t.summarize(verbose=1)
+1 items passed all tests:
+   2 tests in example2
+**********************************************************************
+1 items had failures:
+   1 of   2 in XYZ
+4 tests in 2 items.
+3 passed and 1 failed.
+***Test Failed*** 1 failures.
+(1, 4)
+"""
+
+def old_test2(): r"""
+        >>> from doctest import Tester
+        >>> t = Tester(globs={}, verbose=1)
+        >>> test = r'''
+        ...    # just an example
+        ...    >>> x = 1 + 2
+        ...    >>> x
+        ...    3
+        ... '''
+        >>> t.runstring(test, "Example")
+        Running string Example
+        Trying:
+            x = 1 + 2
+        Expecting nothing
+        ok
+        Trying:
+            x
+        Expecting:
+            3
+        ok
+        0 of 2 examples failed in string Example
+        (0, 2)
+"""
+
+def old_test3(): r"""
+        >>> from doctest import Tester
+        >>> t = Tester(globs={}, verbose=0)
+        >>> def _f():
+        ...     '''Trivial docstring example.
+        ...     >>> assert 2 == 2
+        ...     '''
+        ...     return 32
+        ...
+        >>> t.rundoc(_f)  # expect 0 failures in 1 example
+        (0, 1)
+"""
+
+def old_test4(): """
+        >>> import new
+        >>> m1 = new.module('_m1')
+        >>> m2 = new.module('_m2')
+        >>> test_data = \"""
+        ... def _f():
+        ...     '''>>> assert 1 == 1
+        ...     '''
+        ... def g():
+        ...    '''>>> assert 2 != 1
+        ...    '''
+        ... class H:
+        ...    '''>>> assert 2 > 1
+        ...    '''
+        ...    def bar(self):
+        ...        '''>>> assert 1 < 2
+        ...        '''
+        ... \"""
+        >>> exec test_data in m1.__dict__
+        >>> exec test_data in m2.__dict__
+        >>> m1.__dict__.update({"f2": m2._f, "g2": m2.g, "h2": m2.H})
+
+        Tests that objects outside m1 are excluded:
+
+        >>> from doctest import Tester
+        >>> t = Tester(globs={}, verbose=0)
+        >>> t.rundict(m1.__dict__, "rundict_test", m1)  # f2 and g2 and h2 skipped
+        (0, 4)
+
+        Once more, not excluding stuff outside m1:
+
+        >>> t = Tester(globs={}, verbose=0)
+        >>> t.rundict(m1.__dict__, "rundict_test_pvt")  # None are skipped.
+        (0, 8)
+
+        The exclusion of objects from outside the designated module is
+        meant to be invoked automagically by testmod.
+
+        >>> doctest.testmod(m1, verbose=False)
+        (0, 4)
+"""
+
+######################################################################
+## Main
+######################################################################
+
+def test_main():
+    # Check the doctest cases in doctest itself:
+    test_support.run_doctest(doctest, verbosity=True)
+    # Check the doctest cases defined here:
+    from test import test_doctest
+    test_support.run_doctest(test_doctest, verbosity=True)
+
+import trace, sys, re, StringIO
+def test_coverage(coverdir):
+    tracer = trace.Trace(ignoredirs=[sys.prefix, sys.exec_prefix,],
+                         trace=0, count=1)
+    tracer.run('reload(doctest); test_main()')
+    r = tracer.results()
+    print 'Writing coverage results...'
+    r.write_results(show_missing=True, summary=True,
+                    coverdir=coverdir)
+
+if __name__ == '__main__':
+    if '-c' in sys.argv:
+        test_coverage('/tmp/doctest.cover')
+    else:
+        test_main()

Added: vendor/Python/current/Lib/test/test_doctest.txt
===================================================================
--- vendor/Python/current/Lib/test/test_doctest.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_doctest.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,17 @@
+This is a sample doctest in a text file.
+
+In this example, we'll rely on a global variable being set for us
+already:
+
+  >>> favorite_color
+  'blue'
+
+We can make this fail by disabling the blank-line feature.
+
+  >>> if 1:
+  ...    print 'a'
+  ...    print
+  ...    print 'b'
+  a
+  <BLANKLINE>
+  b

Added: vendor/Python/current/Lib/test/test_doctest2.py
===================================================================
--- vendor/Python/current/Lib/test/test_doctest2.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_doctest2.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,120 @@
+# -*- coding: utf-8 -*-
+u"""A module to test whether doctest recognizes some 2.2 features,
+like static and class methods.
+
+>>> print 'yup'  # 1
+yup
+
+We include some (random) encoded (utf-8) text in the text surrounding
+the example.  It should be ignored:
+
+ЉЊЈЁЂ
+
+"""
+
+from test import test_support
+
+class C(object):
+    u"""Class C.
+
+    >>> print C()  # 2
+    42
+
+
+    We include some (random) encoded (utf-8) text in the text surrounding
+    the example.  It should be ignored:
+
+        ЉЊЈЁЂ
+
+    """
+
+    def __init__(self):
+        """C.__init__.
+
+        >>> print C() # 3
+        42
+        """
+
+    def __str__(self):
+        """
+        >>> print C() # 4
+        42
+        """
+        return "42"
+
+    class D(object):
+        """A nested D class.
+
+        >>> print "In D!"   # 5
+        In D!
+        """
+
+        def nested(self):
+            """
+            >>> print 3 # 6
+            3
+            """
+
+    def getx(self):
+        """
+        >>> c = C()    # 7
+        >>> c.x = 12   # 8
+        >>> print c.x  # 9
+        -12
+        """
+        return -self._x
+
+    def setx(self, value):
+        """
+        >>> c = C()     # 10
+        >>> c.x = 12    # 11
+        >>> print c.x   # 12
+        -12
+        """
+        self._x = value
+
+    x = property(getx, setx, doc="""\
+        >>> c = C()    # 13
+        >>> c.x = 12   # 14
+        >>> print c.x  # 15
+        -12
+        """)
+
+    @staticmethod
+    def statm():
+        """
+        A static method.
+
+        >>> print C.statm()    # 16
+        666
+        >>> print C().statm()  # 17
+        666
+        """
+        return 666
+
+    @classmethod
+    def clsm(cls, val):
+        """
+        A class method.
+
+        >>> print C.clsm(22)    # 18
+        22
+        >>> print C().clsm(23)  # 19
+        23
+        """
+        return val
+
+def test_main():
+    from test import test_doctest2
+    EXPECTED = 19
+    f, t = test_support.run_doctest(test_doctest2)
+    if t != EXPECTED:
+        raise test_support.TestFailed("expected %d tests to run, not %d" %
+                                      (EXPECTED, t))
+
+# Pollute the namespace with a bunch of imported functions and classes,
+# to make sure they don't get tested.
+from doctest import *
+
+if __name__ == '__main__':
+    test_main()

Added: vendor/Python/current/Lib/test/test_doctest2.txt
===================================================================
--- vendor/Python/current/Lib/test/test_doctest2.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_doctest2.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,14 @@
+This is a sample doctest in a text file.
+
+In this example, we'll rely on some silly setup:
+
+  >>> import test.test_doctest
+  >>> test.test_doctest.sillySetup
+  True
+
+This test also has some (random) encoded (utf-8) unicode text:
+
+  ЉЊЈЁЂ
+
+This doesn't cause a problem in the tect surrounding the examples, but
+we include it here (in this test text file) to make sure. :)

Added: vendor/Python/current/Lib/test/test_doctest3.txt
===================================================================
--- vendor/Python/current/Lib/test/test_doctest3.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_doctest3.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,5 @@
+
+Here we check that `__file__` is provided:
+
+  >>> type(__file__)
+  <type 'str'>

Added: vendor/Python/current/Lib/test/test_doctest4.txt
===================================================================
--- vendor/Python/current/Lib/test/test_doctest4.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_doctest4.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,17 @@
+This is a sample doctest in a text file that contains non-ASCII characters.
+This file is encoded using UTF-8.
+
+In order to get this test to pass, we have to manually specify the
+encoding.
+
+  >>> u'föö'
+  u'f\xf6\xf6'
+
+  >>> u'bÄ…r'
+  u'b\u0105r'
+
+  >>> 'föö'
+  'f\xc3\xb6\xc3\xb6'
+
+  >>> 'bÄ…r'
+  'b\xc4\x85r'

Added: vendor/Python/current/Lib/test/test_dumbdbm.py
===================================================================
--- vendor/Python/current/Lib/test/test_dumbdbm.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_dumbdbm.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,155 @@
+#! /usr/bin/env python
+"""Test script for the dumbdbm module
+   Original by Roger E. Masse
+"""
+
+import os
+import unittest
+import dumbdbm
+from test import test_support
+
+_fname = test_support.TESTFN
+
+def _delete_files():
+    for ext in [".dir", ".dat", ".bak"]:
+        try:
+            os.unlink(_fname + ext)
+        except OSError:
+            pass
+
+class DumbDBMTestCase(unittest.TestCase):
+    _dict = {'0': '',
+             'a': 'Python:',
+             'b': 'Programming',
+             'c': 'the',
+             'd': 'way',
+             'f': 'Guido',
+             'g': 'intended'
+             }
+
+    def __init__(self, *args):
+        unittest.TestCase.__init__(self, *args)
+
+    def test_dumbdbm_creation(self):
+        f = dumbdbm.open(_fname, 'c')
+        self.assertEqual(f.keys(), [])
+        for key in self._dict:
+            f[key] = self._dict[key]
+        self.read_helper(f)
+        f.close()
+
+    def test_close_twice(self):
+        f = dumbdbm.open(_fname)
+        f['a'] = 'b'
+        self.assertEqual(f['a'], 'b')
+        f.close()
+        f.close()
+
+    def test_dumbdbm_modification(self):
+        self.init_db()
+        f = dumbdbm.open(_fname, 'w')
+        self._dict['g'] = f['g'] = "indented"
+        self.read_helper(f)
+        f.close()
+
+    def test_dumbdbm_read(self):
+        self.init_db()
+        f = dumbdbm.open(_fname, 'r')
+        self.read_helper(f)
+        f.close()
+
+    def test_dumbdbm_keys(self):
+        self.init_db()
+        f = dumbdbm.open(_fname)
+        keys = self.keys_helper(f)
+        f.close()
+
+    def test_write_write_read(self):
+        # test for bug #482460
+        f = dumbdbm.open(_fname)
+        f['1'] = 'hello'
+        f['1'] = 'hello2'
+        f.close()
+        f = dumbdbm.open(_fname)
+        self.assertEqual(f['1'], 'hello2')
+        f.close()
+
+    def test_line_endings(self):
+        # test for bug #1172763: dumbdbm would die if the line endings
+        # weren't what was expected.
+        f = dumbdbm.open(_fname)
+        f['1'] = 'hello'
+        f['2'] = 'hello2'
+        f.close()
+
+        # Mangle the file by adding \r before each newline
+        data = open(_fname + '.dir').read()
+        data = data.replace('\n', '\r\n')
+        open(_fname + '.dir', 'wb').write(data)
+
+        f = dumbdbm.open(_fname)
+        self.assertEqual(f['1'], 'hello')
+        self.assertEqual(f['2'], 'hello2')
+
+
+    def read_helper(self, f):
+        keys = self.keys_helper(f)
+        for key in self._dict:
+            self.assertEqual(self._dict[key], f[key])
+
+    def init_db(self):
+        f = dumbdbm.open(_fname, 'w')
+        for k in self._dict:
+            f[k] = self._dict[k]
+        f.close()
+
+    def keys_helper(self, f):
+        keys = f.keys()
+        keys.sort()
+        dkeys = self._dict.keys()
+        dkeys.sort()
+        self.assertEqual(keys, dkeys)
+        return keys
+
+    # Perform randomized operations.  This doesn't make assumptions about
+    # what *might* fail.
+    def test_random(self):
+        import random
+        d = {}  # mirror the database
+        for dummy in range(5):
+            f = dumbdbm.open(_fname)
+            for dummy in range(100):
+                k = random.choice('abcdefghijklm')
+                if random.random() < 0.2:
+                    if k in d:
+                        del d[k]
+                        del f[k]
+                else:
+                    v = random.choice('abc') * random.randrange(10000)
+                    d[k] = v
+                    f[k] = v
+                    self.assertEqual(f[k], v)
+            f.close()
+
+            f = dumbdbm.open(_fname)
+            expected = d.items()
+            expected.sort()
+            got = f.items()
+            got.sort()
+            self.assertEqual(expected, got)
+            f.close()
+
+    def tearDown(self):
+        _delete_files()
+
+    def setUp(self):
+        _delete_files()
+
+def test_main():
+    try:
+        test_support.run_unittest(DumbDBMTestCase)
+    finally:
+        _delete_files()
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_dummy_thread.py
===================================================================
--- vendor/Python/current/Lib/test/test_dummy_thread.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_dummy_thread.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,181 @@
+"""Generic thread tests.
+
+Meant to be used by dummy_thread and thread.  To allow for different modules
+to be used, test_main() can be called with the module to use as the thread
+implementation as its sole argument.
+
+"""
+import dummy_thread as _thread
+import time
+import Queue
+import random
+import unittest
+from test import test_support
+
+DELAY = 0 # Set > 0 when testing a module other than dummy_thread, such as
+          # the 'thread' module.
+
+class LockTests(unittest.TestCase):
+    """Test lock objects."""
+
+    def setUp(self):
+        # Create a lock
+        self.lock = _thread.allocate_lock()
+
+    def test_initlock(self):
+        #Make sure locks start locked
+        self.failUnless(not self.lock.locked(),
+                        "Lock object is not initialized unlocked.")
+
+    def test_release(self):
+        # Test self.lock.release()
+        self.lock.acquire()
+        self.lock.release()
+        self.failUnless(not self.lock.locked(),
+                        "Lock object did not release properly.")
+
+    def test_improper_release(self):
+        #Make sure release of an unlocked thread raises _thread.error
+        self.failUnlessRaises(_thread.error, self.lock.release)
+
+    def test_cond_acquire_success(self):
+        #Make sure the conditional acquiring of the lock works.
+        self.failUnless(self.lock.acquire(0),
+                        "Conditional acquiring of the lock failed.")
+
+    def test_cond_acquire_fail(self):
+        #Test acquiring locked lock returns False
+        self.lock.acquire(0)
+        self.failUnless(not self.lock.acquire(0),
+                        "Conditional acquiring of a locked lock incorrectly "
+                         "succeeded.")
+
+    def test_uncond_acquire_success(self):
+        #Make sure unconditional acquiring of a lock works.
+        self.lock.acquire()
+        self.failUnless(self.lock.locked(),
+                        "Uncondional locking failed.")
+
+    def test_uncond_acquire_return_val(self):
+        #Make sure that an unconditional locking returns True.
+        self.failUnless(self.lock.acquire(1) is True,
+                        "Unconditional locking did not return True.")
+
+    def test_uncond_acquire_blocking(self):
+        #Make sure that unconditional acquiring of a locked lock blocks.
+        def delay_unlock(to_unlock, delay):
+            """Hold on to lock for a set amount of time before unlocking."""
+            time.sleep(delay)
+            to_unlock.release()
+
+        self.lock.acquire()
+        start_time = int(time.time())
+        _thread.start_new_thread(delay_unlock,(self.lock, DELAY))
+        if test_support.verbose:
+            print
+            print "*** Waiting for thread to release the lock "\
+            "(approx. %s sec.) ***" % DELAY
+        self.lock.acquire()
+        end_time = int(time.time())
+        if test_support.verbose:
+            print "done"
+        self.failUnless((end_time - start_time) >= DELAY,
+                        "Blocking by unconditional acquiring failed.")
+
+class MiscTests(unittest.TestCase):
+    """Miscellaneous tests."""
+
+    def test_exit(self):
+        #Make sure _thread.exit() raises SystemExit
+        self.failUnlessRaises(SystemExit, _thread.exit)
+
+    def test_ident(self):
+        #Test sanity of _thread.get_ident()
+        self.failUnless(isinstance(_thread.get_ident(), int),
+                        "_thread.get_ident() returned a non-integer")
+        self.failUnless(_thread.get_ident() != 0,
+                        "_thread.get_ident() returned 0")
+
+    def test_LockType(self):
+        #Make sure _thread.LockType is the same type as _thread.allocate_locke()
+        self.failUnless(isinstance(_thread.allocate_lock(), _thread.LockType),
+                        "_thread.LockType is not an instance of what is "
+                         "returned by _thread.allocate_lock()")
+
+    def test_interrupt_main(self):
+        #Calling start_new_thread with a function that executes interrupt_main
+        # should raise KeyboardInterrupt upon completion.
+        def call_interrupt():
+            _thread.interrupt_main()
+        self.failUnlessRaises(KeyboardInterrupt, _thread.start_new_thread,
+                              call_interrupt, tuple())
+
+    def test_interrupt_in_main(self):
+        # Make sure that if interrupt_main is called in main threat that
+        # KeyboardInterrupt is raised instantly.
+        self.failUnlessRaises(KeyboardInterrupt, _thread.interrupt_main)
+
+class ThreadTests(unittest.TestCase):
+    """Test thread creation."""
+
+    def test_arg_passing(self):
+        #Make sure that parameter passing works.
+        def arg_tester(queue, arg1=False, arg2=False):
+            """Use to test _thread.start_new_thread() passes args properly."""
+            queue.put((arg1, arg2))
+
+        testing_queue = Queue.Queue(1)
+        _thread.start_new_thread(arg_tester, (testing_queue, True, True))
+        result = testing_queue.get()
+        self.failUnless(result[0] and result[1],
+                        "Argument passing for thread creation using tuple failed")
+        _thread.start_new_thread(arg_tester, tuple(), {'queue':testing_queue,
+                                                       'arg1':True, 'arg2':True})
+        result = testing_queue.get()
+        self.failUnless(result[0] and result[1],
+                        "Argument passing for thread creation using kwargs failed")
+        _thread.start_new_thread(arg_tester, (testing_queue, True), {'arg2':True})
+        result = testing_queue.get()
+        self.failUnless(result[0] and result[1],
+                        "Argument passing for thread creation using both tuple"
+                        " and kwargs failed")
+
+    def test_multi_creation(self):
+        #Make sure multiple threads can be created.
+        def queue_mark(queue, delay):
+            """Wait for ``delay`` seconds and then put something into ``queue``"""
+            time.sleep(delay)
+            queue.put(_thread.get_ident())
+
+        thread_count = 5
+        testing_queue = Queue.Queue(thread_count)
+        if test_support.verbose:
+            print
+            print "*** Testing multiple thread creation "\
+            "(will take approx. %s to %s sec.) ***" % (DELAY, thread_count)
+        for count in xrange(thread_count):
+            if DELAY:
+                local_delay = round(random.random(), 1)
+            else:
+                local_delay = 0
+            _thread.start_new_thread(queue_mark,
+                                     (testing_queue, local_delay))
+        time.sleep(DELAY)
+        if test_support.verbose:
+            print 'done'
+        self.failUnless(testing_queue.qsize() == thread_count,
+                        "Not all %s threads executed properly after %s sec." %
+                        (thread_count, DELAY))
+
+def test_main(imported_module=None):
+    global _thread, DELAY
+    if imported_module:
+        _thread = imported_module
+        DELAY = 2
+    if test_support.verbose:
+        print
+        print "*** Using %s as _thread module ***" % _thread
+    test_support.run_unittest(LockTests, MiscTests, ThreadTests)
+
+if __name__ == '__main__':
+    test_main()

Added: vendor/Python/current/Lib/test/test_dummy_threading.py
===================================================================
--- vendor/Python/current/Lib/test/test_dummy_threading.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_dummy_threading.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,73 @@
+# Very rudimentary test of threading module
+
+# Create a bunch of threads, let each do some work, wait until all are done
+
+from test.test_support import verbose
+import random
+import dummy_threading as _threading
+import time
+
+
+class TestThread(_threading.Thread):
+
+    def run(self):
+        global running
+        # Uncomment if testing another module, such as the real 'threading'
+        # module.
+        #delay = random.random() * 2
+        delay = 0
+        if verbose:
+            print 'task', self.getName(), 'will run for', delay, 'sec'
+        sema.acquire()
+        mutex.acquire()
+        running = running + 1
+        if verbose:
+            print running, 'tasks are running'
+        mutex.release()
+        time.sleep(delay)
+        if verbose:
+            print 'task', self.getName(), 'done'
+        mutex.acquire()
+        running = running - 1
+        if verbose:
+            print self.getName(), 'is finished.', running, 'tasks are running'
+        mutex.release()
+        sema.release()
+
+def starttasks():
+    for i in range(numtasks):
+        t = TestThread(name="<thread %d>"%i)
+        threads.append(t)
+        t.start()
+
+
+def test_main():
+    # This takes about n/3 seconds to run (about n/3 clumps of tasks, times
+    # about 1 second per clump).
+    global numtasks
+    numtasks = 10
+
+    # no more than 3 of the 10 can run at once
+    global sema
+    sema = _threading.BoundedSemaphore(value=3)
+    global mutex
+    mutex = _threading.RLock()
+    global running
+    running = 0
+
+    global threads
+    threads = []
+
+    starttasks()
+
+    if verbose:
+        print 'waiting for all tasks to complete'
+    for t in threads:
+        t.join()
+    if verbose:
+        print 'all tasks done'
+
+
+
+if __name__ == '__main__':
+    test_main()

Added: vendor/Python/current/Lib/test/test_email.py
===================================================================
--- vendor/Python/current/Lib/test/test_email.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_email.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,13 @@
+# Copyright (C) 2001,2002 Python Software Foundation
+# email package unit tests
+
+import unittest
+# The specific tests now live in Lib/email/test
+from email.test.test_email import suite
+from test.test_support import run_suite
+
+def test_main():
+    run_suite(suite())
+
+if __name__ == '__main__':
+    test_main()

Added: vendor/Python/current/Lib/test/test_email_codecs.py
===================================================================
--- vendor/Python/current/Lib/test/test_email_codecs.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_email_codecs.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,15 @@
+# Copyright (C) 2002 Python Software Foundation
+# email package unit tests for (optional) Asian codecs
+
+# The specific tests now live in Lib/email/test
+from email.test import test_email_codecs
+from email.test import test_email_codecs_renamed
+from test import test_support
+
+def test_main():
+    suite = test_email_codecs.suite()
+    suite.addTest(test_email_codecs_renamed.suite())
+    test_support.run_suite(suite)
+
+if __name__ == '__main__':
+    test_main()

Added: vendor/Python/current/Lib/test/test_email_renamed.py
===================================================================
--- vendor/Python/current/Lib/test/test_email_renamed.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_email_renamed.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,13 @@
+# Copyright (C) 2001-2006 Python Software Foundation
+# email package unit tests
+
+import unittest
+# The specific tests now live in Lib/email/test
+from email.test.test_email_renamed import suite
+from test.test_support import run_suite
+
+def test_main():
+    run_suite(suite())
+
+if __name__ == '__main__':
+    test_main()

Added: vendor/Python/current/Lib/test/test_enumerate.py
===================================================================
--- vendor/Python/current/Lib/test/test_enumerate.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_enumerate.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,214 @@
+import unittest
+import sys
+
+from test import test_support
+
+class G:
+    'Sequence using __getitem__'
+    def __init__(self, seqn):
+        self.seqn = seqn
+    def __getitem__(self, i):
+        return self.seqn[i]
+
+class I:
+    'Sequence using iterator protocol'
+    def __init__(self, seqn):
+        self.seqn = seqn
+        self.i = 0
+    def __iter__(self):
+        return self
+    def next(self):
+        if self.i >= len(self.seqn): raise StopIteration
+        v = self.seqn[self.i]
+        self.i += 1
+        return v
+
+class Ig:
+    'Sequence using iterator protocol defined with a generator'
+    def __init__(self, seqn):
+        self.seqn = seqn
+        self.i = 0
+    def __iter__(self):
+        for val in self.seqn:
+            yield val
+
+class X:
+    'Missing __getitem__ and __iter__'
+    def __init__(self, seqn):
+        self.seqn = seqn
+        self.i = 0
+    def next(self):
+        if self.i >= len(self.seqn): raise StopIteration
+        v = self.seqn[self.i]
+        self.i += 1
+        return v
+
+class E:
+    'Test propagation of exceptions'
+    def __init__(self, seqn):
+        self.seqn = seqn
+        self.i = 0
+    def __iter__(self):
+        return self
+    def next(self):
+        3 // 0
+
+class N:
+    'Iterator missing next()'
+    def __init__(self, seqn):
+        self.seqn = seqn
+        self.i = 0
+    def __iter__(self):
+        return self
+
+class EnumerateTestCase(unittest.TestCase):
+
+    enum = enumerate
+    seq, res = 'abc', [(0,'a'), (1,'b'), (2,'c')]
+
+    def test_basicfunction(self):
+        self.assertEqual(type(self.enum(self.seq)), self.enum)
+        e = self.enum(self.seq)
+        self.assertEqual(iter(e), e)
+        self.assertEqual(list(self.enum(self.seq)), self.res)
+        self.enum.__doc__
+
+    def test_getitemseqn(self):
+        self.assertEqual(list(self.enum(G(self.seq))), self.res)
+        e = self.enum(G(''))
+        self.assertRaises(StopIteration, e.next)
+
+    def test_iteratorseqn(self):
+        self.assertEqual(list(self.enum(I(self.seq))), self.res)
+        e = self.enum(I(''))
+        self.assertRaises(StopIteration, e.next)
+
+    def test_iteratorgenerator(self):
+        self.assertEqual(list(self.enum(Ig(self.seq))), self.res)
+        e = self.enum(Ig(''))
+        self.assertRaises(StopIteration, e.next)
+
+    def test_noniterable(self):
+        self.assertRaises(TypeError, self.enum, X(self.seq))
+
+    def test_illformediterable(self):
+        self.assertRaises(TypeError, list, self.enum(N(self.seq)))
+
+    def test_exception_propagation(self):
+        self.assertRaises(ZeroDivisionError, list, self.enum(E(self.seq)))
+
+    def test_argumentcheck(self):
+        self.assertRaises(TypeError, self.enum) # no arguments
+        self.assertRaises(TypeError, self.enum, 1) # wrong type (not iterable)
+        self.assertRaises(TypeError, self.enum, 'abc', 2) # too many arguments
+
+    def test_tuple_reuse(self):
+        # Tests an implementation detail where tuple is reused
+        # whenever nothing else holds a reference to it
+        self.assertEqual(len(set(map(id, list(enumerate(self.seq))))), len(self.seq))
+        self.assertEqual(len(set(map(id, enumerate(self.seq)))), min(1,len(self.seq)))
+
+class MyEnum(enumerate):
+    pass
+
+class SubclassTestCase(EnumerateTestCase):
+
+    enum = MyEnum
+
+class TestEmpty(EnumerateTestCase):
+
+    seq, res = '', []
+
+class TestBig(EnumerateTestCase):
+
+    seq = range(10,20000,2)
+    res = zip(range(20000), seq)
+
+class TestReversed(unittest.TestCase):
+
+    def test_simple(self):
+        class A:
+            def __getitem__(self, i):
+                if i < 5:
+                    return str(i)
+                raise StopIteration
+            def __len__(self):
+                return 5
+        for data in 'abc', range(5), tuple(enumerate('abc')), A(), xrange(1,17,5):
+            self.assertEqual(list(data)[::-1], list(reversed(data)))
+        self.assertRaises(TypeError, reversed, {})
+
+    def test_xrange_optimization(self):
+        x = xrange(1)
+        self.assertEqual(type(reversed(x)), type(iter(x)))
+
+    def test_len(self):
+        # This is an implementation detail, not an interface requirement
+        from test.test_iterlen import len
+        for s in ('hello', tuple('hello'), list('hello'), xrange(5)):
+            self.assertEqual(len(reversed(s)), len(s))
+            r = reversed(s)
+            list(r)
+            self.assertEqual(len(r), 0)
+        class SeqWithWeirdLen:
+            called = False
+            def __len__(self):
+                if not self.called:
+                    self.called = True
+                    return 10
+                raise ZeroDivisionError
+            def __getitem__(self, index):
+                return index
+        r = reversed(SeqWithWeirdLen())
+        self.assertRaises(ZeroDivisionError, len, r)
+
+
+    def test_gc(self):
+        class Seq:
+            def __len__(self):
+                return 10
+            def __getitem__(self, index):
+                return index
+        s = Seq()
+        r = reversed(s)
+        s.r = r
+
+    def test_args(self):
+        self.assertRaises(TypeError, reversed)
+        self.assertRaises(TypeError, reversed, [], 'extra')
+
+    def test_bug1229429(self):
+        # this bug was never in reversed, it was in
+        # PyObject_CallMethod, and reversed_new calls that sometimes.
+        if not hasattr(sys, "getrefcount"):
+            return
+        def f():
+            pass
+        r = f.__reversed__ = object()
+        rc = sys.getrefcount(r)
+        for i in range(10):
+            try:
+                reversed(f)
+            except TypeError:
+                pass
+            else:
+                self.fail("non-callable __reversed__ didn't raise!")
+        self.assertEqual(rc, sys.getrefcount(r))
+
+
+def test_main(verbose=None):
+    testclasses = (EnumerateTestCase, SubclassTestCase, TestEmpty, TestBig,
+                   TestReversed)
+    test_support.run_unittest(*testclasses)
+
+    # verify reference counting
+    import sys
+    if verbose and hasattr(sys, "gettotalrefcount"):
+        counts = [None] * 5
+        for i in xrange(len(counts)):
+            test_support.run_unittest(*testclasses)
+            counts[i] = sys.gettotalrefcount()
+        print counts
+
+if __name__ == "__main__":
+    test_main(verbose=True)

Added: vendor/Python/current/Lib/test/test_eof.py
===================================================================
--- vendor/Python/current/Lib/test/test_eof.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_eof.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,32 @@
+#! /usr/bin/env python
+"""test script for a few new invalid token catches"""
+
+import os
+import unittest
+from test import test_support
+
+class EOFTestCase(unittest.TestCase):
+    def test_EOFC(self):
+        expect = "EOL while scanning single-quoted string (<string>, line 1)"
+        try:
+            eval("""'this is a test\
+            """)
+        except SyntaxError, msg:
+            self.assertEqual(str(msg), expect)
+        else:
+            raise test_support.TestFailed
+
+    def test_EOFS(self):
+        expect = "EOF while scanning triple-quoted string (<string>, line 1)"
+        try:
+            eval("""'''this is a test""")
+        except SyntaxError, msg:
+            self.assertEqual(str(msg), expect)
+        else:
+            raise test_support.TestFailed
+
+def test_main():
+    test_support.run_unittest(EOFTestCase)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_errno.py
===================================================================
--- vendor/Python/current/Lib/test/test_errno.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_errno.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,49 @@
+#! /usr/bin/env python
+"""Test the errno module
+   Roger E. Masse
+"""
+
+import errno
+from test.test_support import verbose
+
+errors = ['E2BIG', 'EACCES', 'EADDRINUSE', 'EADDRNOTAVAIL', 'EADV',
+          'EAFNOSUPPORT', 'EAGAIN', 'EALREADY', 'EBADE', 'EBADF',
+          'EBADFD', 'EBADMSG', 'EBADR', 'EBADRQC', 'EBADSLT',
+          'EBFONT', 'EBUSY', 'ECHILD', 'ECHRNG', 'ECOMM',
+          'ECONNABORTED', 'ECONNREFUSED', 'ECONNRESET',
+          'EDEADLK', 'EDEADLOCK', 'EDESTADDRREQ', 'EDOM',
+          'EDQUOT', 'EEXIST', 'EFAULT', 'EFBIG', 'EHOSTDOWN',
+          'EHOSTUNREACH', 'EIDRM', 'EILSEQ', 'EINPROGRESS',
+          'EINTR', 'EINVAL', 'EIO', 'EISCONN', 'EISDIR',
+          'EL2HLT', 'EL2NSYNC', 'EL3HLT', 'EL3RST', 'ELIBACC',
+          'ELIBBAD', 'ELIBEXEC', 'ELIBMAX', 'ELIBSCN', 'ELNRNG',
+          'ELOOP', 'EMFILE', 'EMLINK', 'EMSGSIZE', 'EMULTIHOP',
+          'ENAMETOOLONG', 'ENETDOWN', 'ENETRESET', 'ENETUNREACH',
+          'ENFILE', 'ENOANO', 'ENOBUFS', 'ENOCSI', 'ENODATA',
+          'ENODEV', 'ENOENT', 'ENOEXEC', 'ENOLCK', 'ENOLINK',
+          'ENOMEM', 'ENOMSG', 'ENONET', 'ENOPKG', 'ENOPROTOOPT',
+          'ENOSPC', 'ENOSR', 'ENOSTR', 'ENOSYS', 'ENOTBLK',
+          'ENOTCONN', 'ENOTDIR', 'ENOTEMPTY', 'ENOTOBACCO', 'ENOTSOCK',
+          'ENOTTY', 'ENOTUNIQ', 'ENXIO', 'EOPNOTSUPP',
+          'EOVERFLOW', 'EPERM', 'EPFNOSUPPORT', 'EPIPE',
+          'EPROTO', 'EPROTONOSUPPORT', 'EPROTOTYPE',
+          'ERANGE', 'EREMCHG', 'EREMOTE', 'ERESTART',
+          'EROFS', 'ESHUTDOWN', 'ESOCKTNOSUPPORT', 'ESPIPE',
+          'ESRCH', 'ESRMNT', 'ESTALE', 'ESTRPIPE', 'ETIME',
+          'ETIMEDOUT', 'ETOOMANYREFS', 'ETXTBSY', 'EUNATCH',
+          'EUSERS', 'EWOULDBLOCK', 'EXDEV', 'EXFULL']
+
+#
+# This is a wee bit bogus since the module only conditionally adds
+# errno constants if they have been defined by errno.h  However, this
+# test seems to work on SGI, Sparc & intel Solaris, and linux.
+#
+for error in errors:
+    try:
+        a = getattr(errno, error)
+    except AttributeError:
+        if verbose:
+            print '%s: not found' % error
+    else:
+        if verbose:
+            print '%s: %d' % (error, a)


Property changes on: vendor/Python/current/Lib/test/test_errno.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/test/test_exception_variations.py
===================================================================
--- vendor/Python/current/Lib/test/test_exception_variations.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_exception_variations.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,180 @@
+
+from test.test_support import run_unittest
+import unittest
+
+class ExceptionTestCase(unittest.TestCase):
+    def test_try_except_else_finally(self):
+        hit_except = False
+        hit_else = False
+        hit_finally = False
+
+        try:
+            raise Exception, 'nyaa!'
+        except:
+            hit_except = True
+        else:
+            hit_else = True
+        finally:
+            hit_finally = True
+
+        self.assertTrue(hit_except)
+        self.assertTrue(hit_finally)
+        self.assertFalse(hit_else)
+
+    def test_try_except_else_finally_no_exception(self):
+        hit_except = False
+        hit_else = False
+        hit_finally = False
+
+        try:
+            pass
+        except:
+            hit_except = True
+        else:
+            hit_else = True
+        finally:
+            hit_finally = True
+
+        self.assertFalse(hit_except)
+        self.assertTrue(hit_finally)
+        self.assertTrue(hit_else)
+
+    def test_try_except_finally(self):
+        hit_except = False
+        hit_finally = False
+
+        try:
+            raise Exception, 'yarr!'
+        except:
+            hit_except = True
+        finally:
+            hit_finally = True
+
+        self.assertTrue(hit_except)
+        self.assertTrue(hit_finally)
+
+    def test_try_except_finally_no_exception(self):
+        hit_except = False
+        hit_finally = False
+
+        try:
+            pass
+        except:
+            hit_except = True
+        finally:
+            hit_finally = True
+
+        self.assertFalse(hit_except)
+        self.assertTrue(hit_finally)
+
+    def test_try_except(self):
+        hit_except = False
+
+        try:
+            raise Exception, 'ahoy!'
+        except:
+            hit_except = True
+
+        self.assertTrue(hit_except)
+
+    def test_try_except_no_exception(self):
+        hit_except = False
+
+        try:
+            pass
+        except:
+            hit_except = True
+
+        self.assertFalse(hit_except)
+
+    def test_try_except_else(self):
+        hit_except = False
+        hit_else = False
+
+        try:
+            raise Exception, 'foo!'
+        except:
+            hit_except = True
+        else:
+            hit_else = True
+
+        self.assertFalse(hit_else)
+        self.assertTrue(hit_except)
+
+    def test_try_except_else_no_exception(self):
+        hit_except = False
+        hit_else = False
+
+        try:
+            pass
+        except:
+            hit_except = True
+        else:
+            hit_else = True
+
+        self.assertFalse(hit_except)
+        self.assertTrue(hit_else)
+
+    def test_try_finally_no_exception(self):
+        hit_finally = False
+
+        try:
+            pass
+        finally:
+            hit_finally = True
+
+        self.assertTrue(hit_finally)
+
+    def test_nested(self):
+        hit_finally = False
+        hit_inner_except = False
+        hit_inner_finally = False
+
+        try:
+            try:
+                raise Exception, 'inner exception'
+            except:
+                hit_inner_except = True
+            finally:
+                hit_inner_finally = True
+        finally:
+            hit_finally = True
+
+        self.assertTrue(hit_inner_except)
+        self.assertTrue(hit_inner_finally)
+        self.assertTrue(hit_finally)
+
+    def test_nested_else(self):
+        hit_else = False
+        hit_finally = False
+        hit_except = False
+        hit_inner_except = False
+        hit_inner_else = False
+
+        try:
+            try:
+                pass
+            except:
+                hit_inner_except = True
+            else:
+                hit_inner_else = True
+
+            raise Exception, 'outer exception'
+        except:
+            hit_except = True
+        else:
+            hit_else = True
+        finally:
+            hit_finally = True
+
+        self.assertFalse(hit_inner_except)
+        self.assertTrue(hit_inner_else)
+        self.assertFalse(hit_else)
+        self.assertTrue(hit_finally)
+        self.assertTrue(hit_except)
+
+def test_main():
+    run_unittest(ExceptionTestCase)
+
+if __name__ == '__main__':
+    test_main()

Added: vendor/Python/current/Lib/test/test_exceptions.py
===================================================================
--- vendor/Python/current/Lib/test/test_exceptions.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_exceptions.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,345 @@
+# Python test set -- part 5, built-in exceptions
+
+import os
+import sys
+import unittest
+import warnings
+import pickle, cPickle
+
+from test.test_support import TESTFN, unlink, run_unittest
+
+# XXX This is not really enough, each *operation* should be tested!
+
+class ExceptionTests(unittest.TestCase):
+
+    def testReload(self):
+        # Reloading the built-in exceptions module failed prior to Py2.2, while it
+        # should act the same as reloading built-in sys.
+        try:
+            import exceptions
+            reload(exceptions)
+        except ImportError, e:
+            self.fail("reloading exceptions: %s" % e)
+
+    def raise_catch(self, exc, excname):
+        try:
+            raise exc, "spam"
+        except exc, err:
+            buf1 = str(err)
+        try:
+            raise exc("spam")
+        except exc, err:
+            buf2 = str(err)
+        self.assertEquals(buf1, buf2)
+        self.assertEquals(exc.__name__, excname)
+
+    def testRaising(self):
+        self.raise_catch(AttributeError, "AttributeError")
+        self.assertRaises(AttributeError, getattr, sys, "undefined_attribute")
+
+        self.raise_catch(EOFError, "EOFError")
+        fp = open(TESTFN, 'w')
+        fp.close()
+        fp = open(TESTFN, 'r')
+        savestdin = sys.stdin
+        try:
+            try:
+                sys.stdin = fp
+                x = raw_input()
+            except EOFError:
+                pass
+        finally:
+            sys.stdin = savestdin
+            fp.close()
+            unlink(TESTFN)
+
+        self.raise_catch(IOError, "IOError")
+        self.assertRaises(IOError, open, 'this file does not exist', 'r')
+
+        self.raise_catch(ImportError, "ImportError")
+        self.assertRaises(ImportError, __import__, "undefined_module")
+
+        self.raise_catch(IndexError, "IndexError")
+        x = []
+        self.assertRaises(IndexError, x.__getitem__, 10)
+
+        self.raise_catch(KeyError, "KeyError")
+        x = {}
+        self.assertRaises(KeyError, x.__getitem__, 'key')
+
+        self.raise_catch(KeyboardInterrupt, "KeyboardInterrupt")
+
+        self.raise_catch(MemoryError, "MemoryError")
+
+        self.raise_catch(NameError, "NameError")
+        try: x = undefined_variable
+        except NameError: pass
+
+        self.raise_catch(OverflowError, "OverflowError")
+        x = 1
+        for dummy in range(128):
+            x += x  # this simply shouldn't blow up
+
+        self.raise_catch(RuntimeError, "RuntimeError")
+
+        self.raise_catch(SyntaxError, "SyntaxError")
+        try: exec '/\n'
+        except SyntaxError: pass
+
+        self.raise_catch(IndentationError, "IndentationError")
+
+        self.raise_catch(TabError, "TabError")
+        # can only be tested under -tt, and is the only test for -tt
+        #try: compile("try:\n\t1/0\n    \t1/0\nfinally:\n pass\n", '<string>', 'exec')
+        #except TabError: pass
+        #else: self.fail("TabError not raised")
+
+        self.raise_catch(SystemError, "SystemError")
+
+        self.raise_catch(SystemExit, "SystemExit")
+        self.assertRaises(SystemExit, sys.exit, 0)
+
+        self.raise_catch(TypeError, "TypeError")
+        try: [] + ()
+        except TypeError: pass
+
+        self.raise_catch(ValueError, "ValueError")
+        self.assertRaises(ValueError, chr, 10000)
+
+        self.raise_catch(ZeroDivisionError, "ZeroDivisionError")
+        try: x = 1/0
+        except ZeroDivisionError: pass
+
+        self.raise_catch(Exception, "Exception")
+        try: x = 1/0
+        except Exception, e: pass
+
+    def testSyntaxErrorMessage(self):
+        # make sure the right exception message is raised for each of
+        # these code fragments
+
+        def ckmsg(src, msg):
+            try:
+                compile(src, '<fragment>', 'exec')
+            except SyntaxError, e:
+                if e.msg != msg:
+                    self.fail("expected %s, got %s" % (msg, e.msg))
+            else:
+                self.fail("failed to get expected SyntaxError")
+
+        s = '''while 1:
+            try:
+                pass
+            finally:
+                continue'''
+
+        if not sys.platform.startswith('java'):
+            ckmsg(s, "'continue' not supported inside 'finally' clause")
+
+        s = '''if 1:
+        try:
+            continue
+        except:
+            pass'''
+
+        ckmsg(s, "'continue' not properly in loop")
+        ckmsg("continue\n", "'continue' not properly in loop")
+
+    def testSettingException(self):
+        # test that setting an exception at the C level works even if the
+        # exception object can't be constructed.
+
+        class BadException:
+            def __init__(self_):
+                raise RuntimeError, "can't instantiate BadException"
+
+        def test_capi1():
+            import _testcapi
+            try:
+                _testcapi.raise_exception(BadException, 1)
+            except TypeError, err:
+                exc, err, tb = sys.exc_info()
+                co = tb.tb_frame.f_code
+                self.assertEquals(co.co_name, "test_capi1")
+                self.assert_(co.co_filename.endswith('test_exceptions'+os.extsep+'py'))
+            else:
+                self.fail("Expected exception")
+
+        def test_capi2():
+            import _testcapi
+            try:
+                _testcapi.raise_exception(BadException, 0)
+            except RuntimeError, err:
+                exc, err, tb = sys.exc_info()
+                co = tb.tb_frame.f_code
+                self.assertEquals(co.co_name, "__init__")
+                self.assert_(co.co_filename.endswith('test_exceptions'+os.extsep+'py'))
+                co2 = tb.tb_frame.f_back.f_code
+                self.assertEquals(co2.co_name, "test_capi2")
+            else:
+                self.fail("Expected exception")
+
+        if not sys.platform.startswith('java'):
+            test_capi1()
+            test_capi2()
+
+    def test_WindowsError(self):
+        try:
+            WindowsError
+        except NameError:
+            pass
+        else:
+            self.failUnlessEqual(str(WindowsError(1001)),
+                                 "1001")
+            self.failUnlessEqual(str(WindowsError(1001, "message")),
+                                 "[Error 1001] message")
+            self.failUnlessEqual(WindowsError(1001, "message").errno, 22)
+            self.failUnlessEqual(WindowsError(1001, "message").winerror, 1001)
+
+    def testAttributes(self):
+        # test that exception attributes are happy
+
+        exceptionList = [
+            (BaseException, (), {'message' : '', 'args' : ()}),
+            (BaseException, (1, ), {'message' : 1, 'args' : (1,)}),
+            (BaseException, ('foo',),
+                {'message' : 'foo', 'args' : ('foo',)}),
+            (BaseException, ('foo', 1),
+                {'message' : '', 'args' : ('foo', 1)}),
+            (SystemExit, ('foo',),
+                {'message' : 'foo', 'args' : ('foo',), 'code' : 'foo'}),
+            (IOError, ('foo',),
+                {'message' : 'foo', 'args' : ('foo',), 'filename' : None,
+                 'errno' : None, 'strerror' : None}),
+            (IOError, ('foo', 'bar'),
+                {'message' : '', 'args' : ('foo', 'bar'), 'filename' : None,
+                 'errno' : 'foo', 'strerror' : 'bar'}),
+            (IOError, ('foo', 'bar', 'baz'),
+                {'message' : '', 'args' : ('foo', 'bar'), 'filename' : 'baz',
+                 'errno' : 'foo', 'strerror' : 'bar'}),
+            (IOError, ('foo', 'bar', 'baz', 'quux'),
+                {'message' : '', 'args' : ('foo', 'bar', 'baz', 'quux')}),
+            (EnvironmentError, ('errnoStr', 'strErrorStr', 'filenameStr'),
+                {'message' : '', 'args' : ('errnoStr', 'strErrorStr'),
+                 'strerror' : 'strErrorStr', 'errno' : 'errnoStr',
+                 'filename' : 'filenameStr'}),
+            (EnvironmentError, (1, 'strErrorStr', 'filenameStr'),
+                {'message' : '', 'args' : (1, 'strErrorStr'), 'errno' : 1,
+                 'strerror' : 'strErrorStr', 'filename' : 'filenameStr'}),
+            (SyntaxError, ('msgStr',),
+                {'message' : 'msgStr', 'args' : ('msgStr',), 'text' : None,
+                 'print_file_and_line' : None, 'msg' : 'msgStr',
+                 'filename' : None, 'lineno' : None, 'offset' : None}),
+            (SyntaxError, ('msgStr', ('filenameStr', 'linenoStr', 'offsetStr',
+                           'textStr')),
+                {'message' : '', 'offset' : 'offsetStr', 'text' : 'textStr',
+                 'args' : ('msgStr', ('filenameStr', 'linenoStr',
+                                      'offsetStr', 'textStr')),
+                 'print_file_and_line' : None, 'msg' : 'msgStr',
+                 'filename' : 'filenameStr', 'lineno' : 'linenoStr'}),
+            (SyntaxError, ('msgStr', 'filenameStr', 'linenoStr', 'offsetStr',
+                           'textStr', 'print_file_and_lineStr'),
+                {'message' : '', 'text' : None,
+                 'args' : ('msgStr', 'filenameStr', 'linenoStr', 'offsetStr',
+                           'textStr', 'print_file_and_lineStr'),
+                 'print_file_and_line' : None, 'msg' : 'msgStr',
+                 'filename' : None, 'lineno' : None, 'offset' : None}),
+            (UnicodeError, (), {'message' : '', 'args' : (),}),
+            (UnicodeEncodeError, ('ascii', u'a', 0, 1, 'ordinal not in range'),
+                {'message' : '', 'args' : ('ascii', u'a', 0, 1,
+                                           'ordinal not in range'),
+                 'encoding' : 'ascii', 'object' : u'a',
+                 'start' : 0, 'reason' : 'ordinal not in range'}),
+            (UnicodeDecodeError, ('ascii', '\xff', 0, 1, 'ordinal not in range'),
+                {'message' : '', 'args' : ('ascii', '\xff', 0, 1,
+                                           'ordinal not in range'),
+                 'encoding' : 'ascii', 'object' : '\xff',
+                 'start' : 0, 'reason' : 'ordinal not in range'}),
+            (UnicodeTranslateError, (u"\u3042", 0, 1, "ouch"),
+                {'message' : '', 'args' : (u'\u3042', 0, 1, 'ouch'),
+                 'object' : u'\u3042', 'reason' : 'ouch',
+                 'start' : 0, 'end' : 1}),
+        ]
+        try:
+            exceptionList.append(
+                (WindowsError, (1, 'strErrorStr', 'filenameStr'),
+                    {'message' : '', 'args' : (1, 'strErrorStr'),
+                     'strerror' : 'strErrorStr', 'winerror' : 1,
+                     'errno' : 22, 'filename' : 'filenameStr'})
+            )
+        except NameError:
+            pass
+
+        for exc, args, expected in exceptionList:
+            try:
+                raise exc(*args)
+            except BaseException, e:
+                if type(e) is not exc:
+                    raise
+                # Verify module name
+                self.assertEquals(type(e).__module__, 'exceptions')
+                # Verify no ref leaks in Exc_str()
+                s = str(e)
+                for checkArgName in expected:
+                    self.assertEquals(repr(getattr(e, checkArgName)),
+                                      repr(expected[checkArgName]),
+                                      'exception "%s", attribute "%s"' %
+                                       (repr(e), checkArgName))
+
+                # test for pickling support
+                for p in pickle, cPickle:
+                    for protocol in range(p.HIGHEST_PROTOCOL + 1):
+                        new = p.loads(p.dumps(e, protocol))
+                        for checkArgName in expected:
+                            got = repr(getattr(new, checkArgName))
+                            want = repr(expected[checkArgName])
+                            self.assertEquals(got, want,
+                                              'pickled "%r", attribute "%s' %
+                                              (e, checkArgName))
+
+    def testSlicing(self):
+        # Test that you can slice an exception directly instead of requiring
+        # going through the 'args' attribute.
+        args = (1, 2, 3)
+        exc = BaseException(*args)
+        self.failUnlessEqual(exc[:], args)
+
+    def testKeywordArgs(self):
+        # test that builtin exception don't take keyword args,
+        # but user-defined subclasses can if they want
+        self.assertRaises(TypeError, BaseException, a=1)
+
+        class DerivedException(BaseException):
+            def __init__(self, fancy_arg):
+                BaseException.__init__(self)
+                self.fancy_arg = fancy_arg
+
+        x = DerivedException(fancy_arg=42)
+        self.assertEquals(x.fancy_arg, 42)
+
+    def testInfiniteRecursion(self):
+        def f():
+            return f()
+        self.assertRaises(RuntimeError, f)
+
+        def g():
+            try:
+                return g()
+            except ValueError:
+                return -1
+        self.assertRaises(RuntimeError, g)
+
+    def testUnicodeStrUsage(self):
+        # Make sure both instances and classes have a str and unicode
+        # representation.
+        self.failUnless(str(Exception))
+        self.failUnless(unicode(Exception))
+        self.failUnless(str(Exception('a')))
+        self.failUnless(unicode(Exception(u'a')))
+
+
+def test_main():
+    run_unittest(ExceptionTests)
+
+if __name__ == '__main__':
+    test_main()

Added: vendor/Python/current/Lib/test/test_extcall.py
===================================================================
--- vendor/Python/current/Lib/test/test_extcall.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_extcall.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,279 @@
+from test.test_support import verify, verbose, TestFailed, sortdict
+from UserList import UserList
+
+def e(a, b):
+    print a, b
+
+def f(*a, **k):
+    print a, sortdict(k)
+
+def g(x, *y, **z):
+    print x, y, sortdict(z)
+
+def h(j=1, a=2, h=3):
+    print j, a, h
+
+f()
+f(1)
+f(1, 2)
+f(1, 2, 3)
+
+f(1, 2, 3, *(4, 5))
+f(1, 2, 3, *[4, 5])
+f(1, 2, 3, *UserList([4, 5]))
+f(1, 2, 3, **{'a':4, 'b':5})
+f(1, 2, 3, *(4, 5), **{'a':6, 'b':7})
+f(1, 2, 3, x=4, y=5, *(6, 7), **{'a':8, 'b':9})
+
+# Verify clearing of SF bug #733667
+try:
+    e(c=3)
+except TypeError:
+    pass
+else:
+    print "should raise TypeError: e() got an unexpected keyword argument 'c'"
+
+try:
+    g()
+except TypeError, err:
+    print "TypeError:", err
+else:
+    print "should raise TypeError: not enough arguments; expected 1, got 0"
+
+try:
+    g(*())
+except TypeError, err:
+    print "TypeError:", err
+else:
+    print "should raise TypeError: not enough arguments; expected 1, got 0"
+
+try:
+    g(*(), **{})
+except TypeError, err:
+    print "TypeError:", err
+else:
+    print "should raise TypeError: not enough arguments; expected 1, got 0"
+
+g(1)
+g(1, 2)
+g(1, 2, 3)
+g(1, 2, 3, *(4, 5))
+class Nothing: pass
+try:
+    g(*Nothing())
+except TypeError, attr:
+    pass
+else:
+    print "should raise TypeError"
+
+class Nothing:
+    def __len__(self):
+        return 5
+try:
+    g(*Nothing())
+except TypeError, attr:
+    pass
+else:
+    print "should raise TypeError"
+
+class Nothing:
+    def __len__(self):
+        return 5
+    def __getitem__(self, i):
+        if i < 3:
+            return i
+        else:
+            raise IndexError, i
+g(*Nothing())
+
+class Nothing:
+    def __init__(self):
+        self.c = 0
+    def __iter__(self):
+        return self
+try:
+    g(*Nothing())
+except TypeError, attr:
+    pass
+else:
+    print "should raise TypeError"
+
+class Nothing:
+    def __init__(self):
+        self.c = 0
+    def __iter__(self):
+        return self
+    def next(self):
+        if self.c == 4:
+            raise StopIteration
+        c = self.c
+        self.c += 1
+        return c
+g(*Nothing())
+
+# make sure the function call doesn't stomp on the dictionary?
+d = {'a': 1, 'b': 2, 'c': 3}
+d2 = d.copy()
+verify(d == d2)
+g(1, d=4, **d)
+print sortdict(d)
+print sortdict(d2)
+verify(d == d2, "function call modified dictionary")
+
+# what about willful misconduct?
+def saboteur(**kw):
+    kw['x'] = locals() # yields a cyclic kw
+    return kw
+d = {}
+kw = saboteur(a=1, **d)
+verify(d == {})
+# break the cycle
+del kw['x']
+
+try:
+    g(1, 2, 3, **{'x':4, 'y':5})
+except TypeError, err:
+    print err
+else:
+    print "should raise TypeError: keyword parameter redefined"
+
+try:
+    g(1, 2, 3, a=4, b=5, *(6, 7), **{'a':8, 'b':9})
+except TypeError, err:
+    print err
+else:
+    print "should raise TypeError: keyword parameter redefined"
+
+try:
+    f(**{1:2})
+except TypeError, err:
+    print err
+else:
+    print "should raise TypeError: keywords must be strings"
+
+try:
+    h(**{'e': 2})
+except TypeError, err:
+    print err
+else:
+    print "should raise TypeError: unexpected keyword argument: e"
+
+try:
+    h(*h)
+except TypeError, err:
+    print err
+else:
+    print "should raise TypeError: * argument must be a tuple"
+
+try:
+    dir(*h)
+except TypeError, err:
+    print err
+else:
+    print "should raise TypeError: * argument must be a tuple"
+
+try:
+    None(*h)
+except TypeError, err:
+    print err
+else:
+    print "should raise TypeError: * argument must be a tuple"
+
+try:
+    h(**h)
+except TypeError, err:
+    print err
+else:
+    print "should raise TypeError: ** argument must be a dictionary"
+
+try:
+    dir(**h)
+except TypeError, err:
+    print err
+else:
+    print "should raise TypeError: ** argument must be a dictionary"
+
+try:
+    None(**h)
+except TypeError, err:
+    print err
+else:
+    print "should raise TypeError: ** argument must be a dictionary"
+
+try:
+    dir(b=1,**{'b':1})
+except TypeError, err:
+    print err
+else:
+    print "should raise TypeError: dir() got multiple values for keyword argument 'b'"
+
+def f2(*a, **b):
+    return a, b
+
+d = {}
+for i in range(512):
+    key = 'k%d' % i
+    d[key] = i
+a, b = f2(1, *(2, 3), **d)
+print len(a), len(b), b == d
+
+class Foo:
+    def method(self, arg1, arg2):
+        return arg1 + arg2
+
+x = Foo()
+print Foo.method(*(x, 1, 2))
+print Foo.method(x, *(1, 2))
+try:
+    print Foo.method(*(1, 2, 3))
+except TypeError, err:
+    pass
+else:
+    print 'expected a TypeError for unbound method call'
+try:
+    print Foo.method(1, *(2, 3))
+except TypeError, err:
+    pass
+else:
+    print 'expected a TypeError for unbound method call'
+
+# A PyCFunction that takes only positional parameters should allow an
+# empty keyword dictionary to pass without a complaint, but raise a
+# TypeError if the dictionary is non-empty.
+id(1, **{})
+try:
+    id(1, **{"foo": 1})
+except TypeError:
+    pass
+else:
+    raise TestFailed, 'expected TypeError; no exception raised'
+
+a, b, d, e, v, k = 'A', 'B', 'D', 'E', 'V', 'K'
+funcs = []
+maxargs = {}
+for args in ['', 'a', 'ab']:
+    for defargs in ['', 'd', 'de']:
+        for vararg in ['', 'v']:
+            for kwarg in ['', 'k']:
+                name = 'z' + args + defargs + vararg + kwarg
+                arglist = list(args) + map(
+                    lambda x: '%s="%s"' % (x, x), defargs)
+                if vararg: arglist.append('*' + vararg)
+                if kwarg: arglist.append('**' + kwarg)
+                decl = (('def %s(%s): print "ok %s", a, b, d, e, v, ' +
+                         'type(k) is type ("") and k or sortdict(k)')
+                         % (name, ', '.join(arglist), name))
+                exec(decl)
+                func = eval(name)
+                funcs.append(func)
+                maxargs[func] = len(args + defargs)
+
+for name in ['za', 'zade', 'zabk', 'zabdv', 'zabdevk']:
+    func = eval(name)
+    for args in [(), (1, 2), (1, 2, 3, 4, 5)]:
+        for kwargs in ['', 'a', 'd', 'ad', 'abde']:
+            kwdict = {}
+            for k in kwargs: kwdict[k] = k + k
+            print func.func_name, args, sortdict(kwdict), '->',
+            try: func(*args, **kwdict)
+            except TypeError, err: print err

Added: vendor/Python/current/Lib/test/test_fcntl.py
===================================================================
--- vendor/Python/current/Lib/test/test_fcntl.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_fcntl.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,69 @@
+#! /usr/bin/env python
+"""Test program for the fcntl C module.
+   OS/2+EMX doesn't support the file locking operations.
+   Roger E. Masse
+"""
+import struct
+import fcntl
+import os, sys
+from test.test_support import verbose, TESTFN
+
+filename = TESTFN
+
+try:
+    os.O_LARGEFILE
+except AttributeError:
+    start_len = "ll"
+else:
+    start_len = "qq"
+
+if sys.platform.startswith('atheos'):
+    start_len = "qq"
+
+if sys.platform in ('netbsd1', 'netbsd2', 'netbsd3',
+                    'Darwin1.2', 'darwin',
+                    'freebsd2', 'freebsd3', 'freebsd4', 'freebsd5',
+                    'freebsd6', 'freebsd7',
+                    'bsdos2', 'bsdos3', 'bsdos4',
+                    'openbsd', 'openbsd2', 'openbsd3', 'openbsd4'):
+    if struct.calcsize('l') == 8:
+        off_t = 'l'
+        pid_t = 'i'
+    else:
+        off_t = 'lxxxx'
+        pid_t = 'l'
+    lockdata = struct.pack(off_t+off_t+pid_t+'hh', 0, 0, 0, fcntl.F_WRLCK, 0)
+elif sys.platform in ['aix3', 'aix4', 'hp-uxB', 'unixware7']:
+    lockdata = struct.pack('hhlllii', fcntl.F_WRLCK, 0, 0, 0, 0, 0, 0)
+elif sys.platform in ['os2emx']:
+    lockdata = None
+else:
+    lockdata = struct.pack('hh'+start_len+'hh', fcntl.F_WRLCK, 0, 0, 0, 0, 0)
+if lockdata:
+    if verbose:
+        print 'struct.pack: ', repr(lockdata)
+
+# the example from the library docs
+f = open(filename, 'w')
+rv = fcntl.fcntl(f.fileno(), fcntl.F_SETFL, os.O_NONBLOCK)
+if verbose:
+    print 'Status from fcntl with O_NONBLOCK: ', rv
+
+if sys.platform not in ['os2emx']:
+    rv = fcntl.fcntl(f.fileno(), fcntl.F_SETLKW, lockdata)
+    if verbose:
+        print 'String from fcntl with F_SETLKW: ', repr(rv)
+
+f.close()
+os.unlink(filename)
+
+
+# Again, but pass the file rather than numeric descriptor:
+f = open(filename, 'w')
+rv = fcntl.fcntl(f, fcntl.F_SETFL, os.O_NONBLOCK)
+
+if sys.platform not in ['os2emx']:
+    rv = fcntl.fcntl(f, fcntl.F_SETLKW, lockdata)
+
+f.close()
+os.unlink(filename)


Property changes on: vendor/Python/current/Lib/test/test_fcntl.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/test/test_file.py
===================================================================
--- vendor/Python/current/Lib/test/test_file.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_file.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,336 @@
+import sys
+import os
+import unittest
+from array import array
+from weakref import proxy
+
+from test.test_support import TESTFN, findfile, run_unittest
+from UserList import UserList
+
+class AutoFileTests(unittest.TestCase):
+    # file tests for which a test file is automatically set up
+
+    def setUp(self):
+        self.f = open(TESTFN, 'wb')
+
+    def tearDown(self):
+        if self.f:
+            self.f.close()
+        os.remove(TESTFN)
+
+    def testWeakRefs(self):
+        # verify weak references
+        p = proxy(self.f)
+        p.write('teststring')
+        self.assertEquals(self.f.tell(), p.tell())
+        self.f.close()
+        self.f = None
+        self.assertRaises(ReferenceError, getattr, p, 'tell')
+
+    def testAttributes(self):
+        # verify expected attributes exist
+        f = self.f
+        softspace = f.softspace
+        f.name     # merely shouldn't blow up
+        f.mode     # ditto
+        f.closed   # ditto
+
+        # verify softspace is writable
+        f.softspace = softspace    # merely shouldn't blow up
+
+        # verify the others aren't
+        for attr in 'name', 'mode', 'closed':
+            self.assertRaises((AttributeError, TypeError), setattr, f, attr, 'oops')
+
+    def testReadinto(self):
+        # verify readinto
+        self.f.write('12')
+        self.f.close()
+        a = array('c', 'x'*10)
+        self.f = open(TESTFN, 'rb')
+        n = self.f.readinto(a)
+        self.assertEquals('12', a.tostring()[:n])
+
+    def testWritelinesUserList(self):
+        # verify writelines with instance sequence
+        l = UserList(['1', '2'])
+        self.f.writelines(l)
+        self.f.close()
+        self.f = open(TESTFN, 'rb')
+        buf = self.f.read()
+        self.assertEquals(buf, '12')
+
+    def testWritelinesIntegers(self):
+        # verify writelines with integers
+        self.assertRaises(TypeError, self.f.writelines, [1, 2, 3])
+
+    def testWritelinesIntegersUserList(self):
+        # verify writelines with integers in UserList
+        l = UserList([1,2,3])
+        self.assertRaises(TypeError, self.f.writelines, l)
+
+    def testWritelinesNonString(self):
+        # verify writelines with non-string object
+        class NonString:
+            pass
+
+        self.assertRaises(TypeError, self.f.writelines,
+                          [NonString(), NonString()])
+
+    def testRepr(self):
+        # verify repr works
+        self.assert_(repr(self.f).startswith("<open file '" + TESTFN))
+
+    def testErrors(self):
+        f = self.f
+        self.assertEquals(f.name, TESTFN)
+        self.assert_(not f.isatty())
+        self.assert_(not f.closed)
+
+        self.assertRaises(TypeError, f.readinto, "")
+        f.close()
+        self.assert_(f.closed)
+
+    def testMethods(self):
+        methods = ['fileno', 'flush', 'isatty', 'next', 'read', 'readinto',
+                   'readline', 'readlines', 'seek', 'tell', 'truncate',
+                   'write', 'xreadlines', '__iter__']
+        if sys.platform.startswith('atheos'):
+            methods.remove('truncate')
+
+        # __exit__ should close the file
+        self.f.__exit__(None, None, None)
+        self.assert_(self.f.closed)
+
+        for methodname in methods:
+            method = getattr(self.f, methodname)
+            # should raise on closed file
+            self.assertRaises(ValueError, method)
+        self.assertRaises(ValueError, self.f.writelines, [])
+
+        # file is closed, __exit__ shouldn't do anything
+        self.assertEquals(self.f.__exit__(None, None, None), None)
+        # it must also return None if an exception was given
+        try:
+            1/0
+        except:
+            self.assertEquals(self.f.__exit__(*sys.exc_info()), None)
+
+
+class OtherFileTests(unittest.TestCase):
+
+    def testModeStrings(self):
+        # check invalid mode strings
+        for mode in ("", "aU", "wU+"):
+            try:
+                f = open(TESTFN, mode)
+            except ValueError:
+                pass
+            else:
+                f.close()
+                self.fail('%r is an invalid file mode' % mode)
+
+    def testStdin(self):
+        # This causes the interpreter to exit on OSF1 v5.1.
+        if sys.platform != 'osf1V5':
+            self.assertRaises(IOError, sys.stdin.seek, -1)
+        else:
+            print >>sys.__stdout__, (
+                '  Skipping sys.stdin.seek(-1), it may crash the interpreter.'
+                ' Test manually.')
+        self.assertRaises(IOError, sys.stdin.truncate)
+
+    def testUnicodeOpen(self):
+        # verify repr works for unicode too
+        f = open(unicode(TESTFN), "w")
+        self.assert_(repr(f).startswith("<open file u'" + TESTFN))
+        f.close()
+        os.unlink(TESTFN)
+
+    def testBadModeArgument(self):
+        # verify that we get a sensible error message for bad mode argument
+        bad_mode = "qwerty"
+        try:
+            f = open(TESTFN, bad_mode)
+        except ValueError, msg:
+            if msg[0] != 0:
+                s = str(msg)
+                if s.find(TESTFN) != -1 or s.find(bad_mode) == -1:
+                    self.fail("bad error message for invalid mode: %s" % s)
+            # if msg[0] == 0, we're probably on Windows where there may be
+            # no obvious way to discover why open() failed.
+        else:
+            f.close()
+            self.fail("no error for invalid mode: %s" % bad_mode)
+
+    def testSetBufferSize(self):
+        # make sure that explicitly setting the buffer size doesn't cause
+        # misbehaviour especially with repeated close() calls
+        for s in (-1, 0, 1, 512):
+            try:
+                f = open(TESTFN, 'w', s)
+                f.write(str(s))
+                f.close()
+                f.close()
+                f = open(TESTFN, 'r', s)
+                d = int(f.read())
+                f.close()
+                f.close()
+            except IOError, msg:
+                self.fail('error setting buffer size %d: %s' % (s, str(msg)))
+            self.assertEquals(d, s)
+
+    def testTruncateOnWindows(self):
+        os.unlink(TESTFN)
+
+        def bug801631():
+            # SF bug <http://www.python.org/sf/801631>
+            # "file.truncate fault on windows"
+            f = open(TESTFN, 'wb')
+            f.write('12345678901')   # 11 bytes
+            f.close()
+
+            f = open(TESTFN,'rb+')
+            data = f.read(5)
+            if data != '12345':
+                self.fail("Read on file opened for update failed %r" % data)
+            if f.tell() != 5:
+                self.fail("File pos after read wrong %d" % f.tell())
+
+            f.truncate()
+            if f.tell() != 5:
+                self.fail("File pos after ftruncate wrong %d" % f.tell())
+
+            f.close()
+            size = os.path.getsize(TESTFN)
+            if size != 5:
+                self.fail("File size after ftruncate wrong %d" % size)
+
+        try:
+            bug801631()
+        finally:
+            os.unlink(TESTFN)
+
+    def testIteration(self):
+        # Test the complex interaction when mixing file-iteration and the
+        # various read* methods. Ostensibly, the mixture could just be tested
+        # to work when it should work according to the Python language,
+        # instead of fail when it should fail according to the current CPython
+        # implementation.  People don't always program Python the way they
+        # should, though, and the implemenation might change in subtle ways,
+        # so we explicitly test for errors, too; the test will just have to
+        # be updated when the implementation changes.
+        dataoffset = 16384
+        filler = "ham\n"
+        assert not dataoffset % len(filler), \
+            "dataoffset must be multiple of len(filler)"
+        nchunks = dataoffset // len(filler)
+        testlines = [
+            "spam, spam and eggs\n",
+            "eggs, spam, ham and spam\n",
+            "saussages, spam, spam and eggs\n",
+            "spam, ham, spam and eggs\n",
+            "spam, spam, spam, spam, spam, ham, spam\n",
+            "wonderful spaaaaaam.\n"
+        ]
+        methods = [("readline", ()), ("read", ()), ("readlines", ()),
+                   ("readinto", (array("c", " "*100),))]
+
+        try:
+            # Prepare the testfile
+            bag = open(TESTFN, "w")
+            bag.write(filler * nchunks)
+            bag.writelines(testlines)
+            bag.close()
+            # Test for appropriate errors mixing read* and iteration
+            for methodname, args in methods:
+                f = open(TESTFN)
+                if f.next() != filler:
+                    self.fail, "Broken testfile"
+                meth = getattr(f, methodname)
+                try:
+                    meth(*args)
+                except ValueError:
+                    pass
+                else:
+                    self.fail("%s%r after next() didn't raise ValueError" %
+                                     (methodname, args))
+                f.close()
+
+            # Test to see if harmless (by accident) mixing of read* and
+            # iteration still works. This depends on the size of the internal
+            # iteration buffer (currently 8192,) but we can test it in a
+            # flexible manner.  Each line in the bag o' ham is 4 bytes
+            # ("h", "a", "m", "\n"), so 4096 lines of that should get us
+            # exactly on the buffer boundary for any power-of-2 buffersize
+            # between 4 and 16384 (inclusive).
+            f = open(TESTFN)
+            for i in range(nchunks):
+                f.next()
+            testline = testlines.pop(0)
+            try:
+                line = f.readline()
+            except ValueError:
+                self.fail("readline() after next() with supposedly empty "
+                          "iteration-buffer failed anyway")
+            if line != testline:
+                self.fail("readline() after next() with empty buffer "
+                          "failed. Got %r, expected %r" % (line, testline))
+            testline = testlines.pop(0)
+            buf = array("c", "\x00" * len(testline))
+            try:
+                f.readinto(buf)
+            except ValueError:
+                self.fail("readinto() after next() with supposedly empty "
+                          "iteration-buffer failed anyway")
+            line = buf.tostring()
+            if line != testline:
+                self.fail("readinto() after next() with empty buffer "
+                          "failed. Got %r, expected %r" % (line, testline))
+
+            testline = testlines.pop(0)
+            try:
+                line = f.read(len(testline))
+            except ValueError:
+                self.fail("read() after next() with supposedly empty "
+                          "iteration-buffer failed anyway")
+            if line != testline:
+                self.fail("read() after next() with empty buffer "
+                          "failed. Got %r, expected %r" % (line, testline))
+            try:
+                lines = f.readlines()
+            except ValueError:
+                self.fail("readlines() after next() with supposedly empty "
+                          "iteration-buffer failed anyway")
+            if lines != testlines:
+                self.fail("readlines() after next() with empty buffer "
+                          "failed. Got %r, expected %r" % (line, testline))
+            # Reading after iteration hit EOF shouldn't hurt either
+            f = open(TESTFN)
+            try:
+                for line in f:
+                    pass
+                try:
+                    f.readline()
+                    f.readinto(buf)
+                    f.read()
+                    f.readlines()
+                except ValueError:
+                    self.fail("read* failed after next() consumed file")
+            finally:
+                f.close()
+        finally:
+            os.unlink(TESTFN)
+
+
+def test_main():
+    # Historically, these tests have been sloppy about removing TESTFN.
+    # So get rid of it no matter what.
+    try:
+        run_unittest(AutoFileTests, OtherFileTests)
+    finally:
+        if os.path.exists(TESTFN):
+            os.unlink(TESTFN)
+
+if __name__ == '__main__':
+    test_main()

Added: vendor/Python/current/Lib/test/test_filecmp.py
===================================================================
--- vendor/Python/current/Lib/test/test_filecmp.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_filecmp.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,134 @@
+
+import os, filecmp, shutil, tempfile, shutil
+import unittest
+from test import test_support
+
+class FileCompareTestCase(unittest.TestCase):
+    def setUp(self):
+        self.name = test_support.TESTFN
+        self.name_same = test_support.TESTFN + '-same'
+        self.name_diff = test_support.TESTFN + '-diff'
+        data = 'Contents of file go here.\n'
+        for name in [self.name, self.name_same, self.name_diff]:
+            output = open(name, 'w')
+            output.write(data)
+            output.close()
+
+        output = open(self.name_diff, 'a+')
+        output.write('An extra line.\n')
+        output.close()
+        self.dir = tempfile.gettempdir()
+
+    def tearDown(self):
+        os.unlink(self.name)
+        os.unlink(self.name_same)
+        os.unlink(self.name_diff)
+
+    def test_matching(self):
+        self.failUnless(filecmp.cmp(self.name, self.name_same),
+                        "Comparing file to itself fails")
+        self.failUnless(filecmp.cmp(self.name, self.name_same, shallow=False),
+                        "Comparing file to itself fails")
+        self.failUnless(filecmp.cmp(self.name, self.name, shallow=False),
+                        "Comparing file to identical file fails")
+        self.failUnless(filecmp.cmp(self.name, self.name),
+                        "Comparing file to identical file fails")
+
+    def test_different(self):
+        self.failIf(filecmp.cmp(self.name, self.name_diff),
+                    "Mismatched files compare as equal")
+        self.failIf(filecmp.cmp(self.name, self.dir),
+                    "File and directory compare as equal")
+
+class DirCompareTestCase(unittest.TestCase):
+    def setUp(self):
+        tmpdir = tempfile.gettempdir()
+        self.dir = os.path.join(tmpdir, 'dir')
+        self.dir_same = os.path.join(tmpdir, 'dir-same')
+        self.dir_diff = os.path.join(tmpdir, 'dir-diff')
+        self.caseinsensitive = os.path.normcase('A') == os.path.normcase('a')
+        data = 'Contents of file go here.\n'
+        for dir in [self.dir, self.dir_same, self.dir_diff]:
+            shutil.rmtree(dir, True)
+            os.mkdir(dir)
+            if self.caseinsensitive and dir is self.dir_same:
+                fn = 'FiLe'     # Verify case-insensitive comparison
+            else:
+                fn = 'file'
+            output = open(os.path.join(dir, fn), 'w')
+            output.write(data)
+            output.close()
+
+        output = open(os.path.join(self.dir_diff, 'file2'), 'w')
+        output.write('An extra file.\n')
+        output.close()
+
+    def tearDown(self):
+        shutil.rmtree(self.dir)
+        shutil.rmtree(self.dir_same)
+        shutil.rmtree(self.dir_diff)
+
+    def test_cmpfiles(self):
+        self.failUnless(filecmp.cmpfiles(self.dir, self.dir, ['file']) ==
+                        (['file'], [], []),
+                        "Comparing directory to itself fails")
+        self.failUnless(filecmp.cmpfiles(self.dir, self.dir_same, ['file']) ==
+                        (['file'], [], []),
+                        "Comparing directory to same fails")
+
+        # Try it with shallow=False
+        self.failUnless(filecmp.cmpfiles(self.dir, self.dir, ['file'],
+                                         shallow=False) ==
+                        (['file'], [], []),
+                        "Comparing directory to itself fails")
+        self.failUnless(filecmp.cmpfiles(self.dir, self.dir_same, ['file'],
+                                         shallow=False),
+                        "Comparing directory to same fails")
+
+        # Add different file2
+        output = open(os.path.join(self.dir, 'file2'), 'w')
+        output.write('Different contents.\n')
+        output.close()
+
+        self.failIf(filecmp.cmpfiles(self.dir, self.dir_same,
+                                     ['file', 'file2']) ==
+                    (['file'], ['file2'], []),
+                    "Comparing mismatched directories fails")
+
+
+    def test_dircmp(self):
+        # Check attributes for comparison of two identical directories
+        d = filecmp.dircmp(self.dir, self.dir_same)
+        if self.caseinsensitive:
+            self.assertEqual([d.left_list, d.right_list],[['file'], ['FiLe']])
+        else:
+            self.assertEqual([d.left_list, d.right_list],[['file'], ['file']])
+        self.failUnless(d.common == ['file'])
+        self.failUnless(d.left_only == d.right_only == [])
+        self.failUnless(d.same_files == ['file'])
+        self.failUnless(d.diff_files == [])
+
+        # Check attributes for comparison of two different directories
+        d = filecmp.dircmp(self.dir, self.dir_diff)
+        self.failUnless(d.left_list == ['file'])
+        self.failUnless(d.right_list == ['file', 'file2'])
+        self.failUnless(d.common == ['file'])
+        self.failUnless(d.left_only == [])
+        self.failUnless(d.right_only == ['file2'])
+        self.failUnless(d.same_files == ['file'])
+        self.failUnless(d.diff_files == [])
+
+        # Add different file2
+        output = open(os.path.join(self.dir, 'file2'), 'w')
+        output.write('Different contents.\n')
+        output.close()
+        d = filecmp.dircmp(self.dir, self.dir_diff)
+        self.failUnless(d.same_files == ['file'])
+        self.failUnless(d.diff_files == ['file2'])
+
+
+def test_main():
+    test_support.run_unittest(FileCompareTestCase, DirCompareTestCase)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_fileinput.py
===================================================================
--- vendor/Python/current/Lib/test/test_fileinput.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_fileinput.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,227 @@
+'''
+Tests for fileinput module.
+Nick Mathewson
+'''
+
+from test.test_support import verify, verbose, TESTFN, TestFailed
+import sys, os, re
+from StringIO import StringIO
+from fileinput import FileInput, hook_encoded
+
+# The fileinput module has 2 interfaces: the FileInput class which does
+# all the work, and a few functions (input, etc.) that use a global _state
+# variable.  We only test the FileInput class, since the other functions
+# only provide a thin facade over FileInput.
+
+# Write lines (a list of lines) to temp file number i, and return the
+# temp file's name.
+def writeTmp(i, lines, mode='w'):  # opening in text mode is the default
+    name = TESTFN + str(i)
+    f = open(name, mode)
+    f.writelines(lines)
+    f.close()
+    return name
+
+pat = re.compile(r'LINE (\d+) OF FILE (\d+)')
+
+def remove_tempfiles(*names):
+    for name in names:
+        try:
+            os.unlink(name)
+        except:
+            pass
+
+def runTests(t1, t2, t3, t4, bs=0, round=0):
+    start = 1 + round*6
+    if verbose:
+        print '%s. Simple iteration (bs=%s)' % (start+0, bs)
+    fi = FileInput(files=(t1, t2, t3, t4), bufsize=bs)
+    lines = list(fi)
+    fi.close()
+    verify(len(lines) == 31)
+    verify(lines[4] == 'Line 5 of file 1\n')
+    verify(lines[30] == 'Line 1 of file 4\n')
+    verify(fi.lineno() == 31)
+    verify(fi.filename() == t4)
+
+    if verbose:
+        print '%s. Status variables (bs=%s)' % (start+1, bs)
+    fi = FileInput(files=(t1, t2, t3, t4), bufsize=bs)
+    s = "x"
+    while s and s != 'Line 6 of file 2\n':
+        s = fi.readline()
+    verify(fi.filename() == t2)
+    verify(fi.lineno() == 21)
+    verify(fi.filelineno() == 6)
+    verify(not fi.isfirstline())
+    verify(not fi.isstdin())
+
+    if verbose:
+        print '%s. Nextfile (bs=%s)' % (start+2, bs)
+    fi.nextfile()
+    verify(fi.readline() == 'Line 1 of file 3\n')
+    verify(fi.lineno() == 22)
+    fi.close()
+
+    if verbose:
+        print '%s. Stdin (bs=%s)' % (start+3, bs)
+    fi = FileInput(files=(t1, t2, t3, t4, '-'), bufsize=bs)
+    savestdin = sys.stdin
+    try:
+        sys.stdin = StringIO("Line 1 of stdin\nLine 2 of stdin\n")
+        lines = list(fi)
+        verify(len(lines) == 33)
+        verify(lines[32] == 'Line 2 of stdin\n')
+        verify(fi.filename() == '<stdin>')
+        fi.nextfile()
+    finally:
+        sys.stdin = savestdin
+
+    if verbose:
+        print '%s. Boundary conditions (bs=%s)' % (start+4, bs)
+    fi = FileInput(files=(t1, t2, t3, t4), bufsize=bs)
+    verify(fi.lineno() == 0)
+    verify(fi.filename() == None)
+    fi.nextfile()
+    verify(fi.lineno() == 0)
+    verify(fi.filename() == None)
+
+    if verbose:
+        print '%s. Inplace (bs=%s)' % (start+5, bs)
+    savestdout = sys.stdout
+    try:
+        fi = FileInput(files=(t1, t2, t3, t4), inplace=1, bufsize=bs)
+        for line in fi:
+            line = line[:-1].upper()
+            print line
+        fi.close()
+    finally:
+        sys.stdout = savestdout
+
+    fi = FileInput(files=(t1, t2, t3, t4), bufsize=bs)
+    for line in fi:
+        verify(line[-1] == '\n')
+        m = pat.match(line[:-1])
+        verify(m != None)
+        verify(int(m.group(1)) == fi.filelineno())
+    fi.close()
+
+
+def writeFiles():
+    global t1, t2, t3, t4
+    t1 = writeTmp(1, ["Line %s of file 1\n" % (i+1) for i in range(15)])
+    t2 = writeTmp(2, ["Line %s of file 2\n" % (i+1) for i in range(10)])
+    t3 = writeTmp(3, ["Line %s of file 3\n" % (i+1) for i in range(5)])
+    t4 = writeTmp(4, ["Line %s of file 4\n" % (i+1) for i in range(1)])
+
+# First, run the tests with default and teeny buffer size.
+for round, bs in (0, 0), (1, 30):
+    try:
+        writeFiles()
+        runTests(t1, t2, t3, t4, bs, round)
+    finally:
+        remove_tempfiles(t1, t2, t3, t4)
+
+# Next, check for proper behavior with 0-byte files.
+if verbose:
+    print "13. 0-byte files"
+try:
+    t1 = writeTmp(1, [""])
+    t2 = writeTmp(2, [""])
+    t3 = writeTmp(3, ["The only line there is.\n"])
+    t4 = writeTmp(4, [""])
+    fi = FileInput(files=(t1, t2, t3, t4))
+    line = fi.readline()
+    verify(line == 'The only line there is.\n')
+    verify(fi.lineno() == 1)
+    verify(fi.filelineno() == 1)
+    verify(fi.filename() == t3)
+    line = fi.readline()
+    verify(not line)
+    verify(fi.lineno() == 1)
+    verify(fi.filelineno() == 0)
+    verify(fi.filename() == t4)
+    fi.close()
+finally:
+    remove_tempfiles(t1, t2, t3, t4)
+
+if verbose:
+    print "14. Files that don't end with newline"
+try:
+    t1 = writeTmp(1, ["A\nB\nC"])
+    t2 = writeTmp(2, ["D\nE\nF"])
+    fi = FileInput(files=(t1, t2))
+    lines = list(fi)
+    verify(lines == ["A\n", "B\n", "C", "D\n", "E\n", "F"])
+    verify(fi.filelineno() == 3)
+    verify(fi.lineno() == 6)
+finally:
+    remove_tempfiles(t1, t2)
+
+if verbose:
+    print "15. Unicode filenames"
+try:
+    t1 = writeTmp(1, ["A\nB"])
+    encoding = sys.getfilesystemencoding()
+    if encoding is None:
+        encoding = 'ascii'
+    fi = FileInput(files=unicode(t1, encoding))
+    lines = list(fi)
+    verify(lines == ["A\n", "B"])
+finally:
+    remove_tempfiles(t1)
+
+if verbose:
+    print "16. fileno()"
+try:
+    t1 = writeTmp(1, ["A\nB"])
+    t2 = writeTmp(2, ["C\nD"])
+    fi = FileInput(files=(t1, t2))
+    verify(fi.fileno() == -1)
+    line = fi.next()
+    verify(fi.fileno() != -1)
+    fi.nextfile()
+    verify(fi.fileno() == -1)
+    line = list(fi)
+    verify(fi.fileno() == -1)
+finally:
+    remove_tempfiles(t1, t2)
+
+if verbose:
+    print "17. Specify opening mode"
+try:
+    # invalid mode, should raise ValueError
+    fi = FileInput(mode="w")
+    raise TestFailed("FileInput should reject invalid mode argument")
+except ValueError:
+    pass
+try:
+    # try opening in universal newline mode
+    t1 = writeTmp(1, ["A\nB\r\nC\rD"], mode="wb")
+    fi = FileInput(files=t1, mode="U")
+    lines = list(fi)
+    verify(lines == ["A\n", "B\n", "C\n", "D"])
+finally:
+    remove_tempfiles(t1)
+
+if verbose:
+    print "18. Test file opening hook"
+try:
+    # cannot use openhook and inplace mode
+    fi = FileInput(inplace=1, openhook=lambda f,m: None)
+    raise TestFailed("FileInput should raise if both inplace "
+                     "and openhook arguments are given")
+except ValueError:
+    pass
+try:
+    fi = FileInput(openhook=1)
+    raise TestFailed("FileInput should check openhook for being callable")
+except ValueError:
+    pass
+try:
+    t1 = writeTmp(1, ["A\nB"], mode="wb")
+    fi = FileInput(files=t1, openhook=hook_encoded("rot13"))
+    lines = list(fi)
+    verify(lines == ["N\n", "O"])
+finally:
+    remove_tempfiles(t1)

Added: vendor/Python/current/Lib/test/test_float.py
===================================================================
--- vendor/Python/current/Lib/test/test_float.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_float.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,110 @@
+
+import unittest, struct
+from test import test_support
+
+class FormatFunctionsTestCase(unittest.TestCase):
+
+    def setUp(self):
+        self.save_formats = {'double':float.__getformat__('double'),
+                             'float':float.__getformat__('float')}
+
+    def tearDown(self):
+        float.__setformat__('double', self.save_formats['double'])
+        float.__setformat__('float', self.save_formats['float'])
+
+    def test_getformat(self):
+        self.assert_(float.__getformat__('double') in
+                     ['unknown', 'IEEE, big-endian', 'IEEE, little-endian'])
+        self.assert_(float.__getformat__('float') in
+                     ['unknown', 'IEEE, big-endian', 'IEEE, little-endian'])
+        self.assertRaises(ValueError, float.__getformat__, 'chicken')
+        self.assertRaises(TypeError, float.__getformat__, 1)
+
+    def test_setformat(self):
+        for t in 'double', 'float':
+            float.__setformat__(t, 'unknown')
+            if self.save_formats[t] == 'IEEE, big-endian':
+                self.assertRaises(ValueError, float.__setformat__,
+                                  t, 'IEEE, little-endian')
+            elif self.save_formats[t] == 'IEEE, little-endian':
+                self.assertRaises(ValueError, float.__setformat__,
+                                  t, 'IEEE, big-endian')
+            else:
+                self.assertRaises(ValueError, float.__setformat__,
+                                  t, 'IEEE, big-endian')
+                self.assertRaises(ValueError, float.__setformat__,
+                                  t, 'IEEE, little-endian')
+            self.assertRaises(ValueError, float.__setformat__,
+                              t, 'chicken')
+        self.assertRaises(ValueError, float.__setformat__,
+                          'chicken', 'unknown')
+
+BE_DOUBLE_INF = '\x7f\xf0\x00\x00\x00\x00\x00\x00'
+LE_DOUBLE_INF = ''.join(reversed(BE_DOUBLE_INF))
+BE_DOUBLE_NAN = '\x7f\xf8\x00\x00\x00\x00\x00\x00'
+LE_DOUBLE_NAN = ''.join(reversed(BE_DOUBLE_NAN))
+
+BE_FLOAT_INF = '\x7f\x80\x00\x00'
+LE_FLOAT_INF = ''.join(reversed(BE_FLOAT_INF))
+BE_FLOAT_NAN = '\x7f\xc0\x00\x00'
+LE_FLOAT_NAN = ''.join(reversed(BE_FLOAT_NAN))
+
+# on non-IEEE platforms, attempting to unpack a bit pattern
+# representing an infinity or a NaN should raise an exception.
+
+class UnknownFormatTestCase(unittest.TestCase):
+    def setUp(self):
+        self.save_formats = {'double':float.__getformat__('double'),
+                             'float':float.__getformat__('float')}
+        float.__setformat__('double', 'unknown')
+        float.__setformat__('float', 'unknown')
+
+    def tearDown(self):
+        float.__setformat__('double', self.save_formats['double'])
+        float.__setformat__('float', self.save_formats['float'])
+
+    def test_double_specials_dont_unpack(self):
+        for fmt, data in [('>d', BE_DOUBLE_INF),
+                          ('>d', BE_DOUBLE_NAN),
+                          ('<d', LE_DOUBLE_INF),
+                          ('<d', LE_DOUBLE_NAN)]:
+            self.assertRaises(ValueError, struct.unpack, fmt, data)
+
+    def test_float_specials_dont_unpack(self):
+        for fmt, data in [('>f', BE_FLOAT_INF),
+                          ('>f', BE_FLOAT_NAN),
+                          ('<f', LE_FLOAT_INF),
+                          ('<f', LE_FLOAT_NAN)]:
+            self.assertRaises(ValueError, struct.unpack, fmt, data)
+
+
+# on an IEEE platform, all we guarantee is that bit patterns
+# representing infinities or NaNs do not raise an exception; all else
+# is accident (today).
+
+class IEEEFormatTestCase(unittest.TestCase):
+    if float.__getformat__("double").startswith("IEEE"):
+        def test_double_specials_do_unpack(self):
+            for fmt, data in [('>d', BE_DOUBLE_INF),
+                              ('>d', BE_DOUBLE_NAN),
+                              ('<d', LE_DOUBLE_INF),
+                              ('<d', LE_DOUBLE_NAN)]:
+                struct.unpack(fmt, data)
+
+    if float.__getformat__("float").startswith("IEEE"):
+        def test_float_specials_do_unpack(self):
+            for fmt, data in [('>f', BE_FLOAT_INF),
+                              ('>f', BE_FLOAT_NAN),
+                              ('<f', LE_FLOAT_INF),
+                              ('<f', LE_FLOAT_NAN)]:
+                struct.unpack(fmt, data)
+
+
+def test_main():
+    test_support.run_unittest(
+        FormatFunctionsTestCase,
+        UnknownFormatTestCase,
+        IEEEFormatTestCase)
+
+if __name__ == '__main__':
+    test_main()

Added: vendor/Python/current/Lib/test/test_fnmatch.py
===================================================================
--- vendor/Python/current/Lib/test/test_fnmatch.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_fnmatch.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,46 @@
+"""Test cases for the fnmatch module."""
+
+from test import test_support
+import unittest
+
+from fnmatch import fnmatch, fnmatchcase
+
+
+class FnmatchTestCase(unittest.TestCase):
+    def check_match(self, filename, pattern, should_match=1):
+        if should_match:
+            self.assert_(fnmatch(filename, pattern),
+                         "expected %r to match pattern %r"
+                         % (filename, pattern))
+        else:
+            self.assert_(not fnmatch(filename, pattern),
+                         "expected %r not to match pattern %r"
+                         % (filename, pattern))
+
+    def test_fnmatch(self):
+        check = self.check_match
+        check('abc', 'abc')
+        check('abc', '?*?')
+        check('abc', '???*')
+        check('abc', '*???')
+        check('abc', '???')
+        check('abc', '*')
+        check('abc', 'ab[cd]')
+        check('abc', 'ab[!de]')
+        check('abc', 'ab[de]', 0)
+        check('a', '??', 0)
+        check('a', 'b', 0)
+
+        # these test that '\' is handled correctly in character sets;
+        # see SF bug #???
+        check('\\', r'[\]')
+        check('a', r'[!\]')
+        check('\\', r'[!\]', 0)
+
+
+def test_main():
+    test_support.run_unittest(FnmatchTestCase)
+
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_fork1.py
===================================================================
--- vendor/Python/current/Lib/test/test_fork1.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_fork1.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,32 @@
+"""This test checks for correct fork() behavior.
+"""
+
+import os
+import time
+from test.fork_wait import ForkWait
+from test.test_support import TestSkipped, run_unittest, reap_children
+
+try:
+    os.fork
+except AttributeError:
+    raise TestSkipped, "os.fork not defined -- skipping test_fork1"
+
+class ForkTest(ForkWait):
+    def wait_impl(self, cpid):
+        for i in range(10):
+            # waitpid() shouldn't hang, but some of the buildbots seem to hang
+            # in the forking tests.  This is an attempt to fix the problem.
+            spid, status = os.waitpid(cpid, os.WNOHANG)
+            if spid == cpid:
+                break
+            time.sleep(1.0)
+
+        self.assertEqual(spid, cpid)
+        self.assertEqual(status, 0, "cause = %d, exit = %d" % (status&0xff, status>>8))
+
+def test_main():
+    run_unittest(ForkTest)
+    reap_children()
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_format.py
===================================================================
--- vendor/Python/current/Lib/test/test_format.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_format.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,248 @@
+from test.test_support import verbose, have_unicode, TestFailed
+import sys
+
+# test string formatting operator (I am not sure if this is being tested
+# elsewhere but, surely, some of the given cases are *not* tested because
+# they crash python)
+# test on unicode strings as well
+
+overflowok = 1
+
+def testformat(formatstr, args, output=None):
+    if verbose:
+        if output:
+            print "%s %% %s =? %s ..." %\
+                (repr(formatstr), repr(args), repr(output)),
+        else:
+            print "%s %% %s works? ..." % (repr(formatstr), repr(args)),
+    try:
+        result = formatstr % args
+    except OverflowError:
+        if not overflowok:
+            raise
+        if verbose:
+            print 'overflow (this is fine)'
+    else:
+        if output and result != output:
+            if verbose:
+                print 'no'
+            print "%s %% %s == %s != %s" %\
+                (repr(formatstr), repr(args), repr(result), repr(output))
+        else:
+            if verbose:
+                print 'yes'
+
+def testboth(formatstr, *args):
+    testformat(formatstr, *args)
+    if have_unicode:
+        testformat(unicode(formatstr), *args)
+
+
+testboth("%.1d", (1,), "1")
+testboth("%.*d", (sys.maxint,1))  # expect overflow
+testboth("%.100d", (1,), '0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001')
+testboth("%#.117x", (1,), '0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001')
+testboth("%#.118x", (1,), '0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001')
+
+testboth("%f", (1.0,), "1.000000")
+# these are trying to test the limits of the internal magic-number-length
+# formatting buffer, if that number changes then these tests are less
+# effective
+testboth("%#.*g", (109, -1.e+49/3.))
+testboth("%#.*g", (110, -1.e+49/3.))
+testboth("%#.*g", (110, -1.e+100/3.))
+
+# test some ridiculously large precision, expect overflow
+testboth('%12.*f', (123456, 1.0))
+
+# Formatting of long integers. Overflow is not ok
+overflowok = 0
+testboth("%x", 10L, "a")
+testboth("%x", 100000000000L, "174876e800")
+testboth("%o", 10L, "12")
+testboth("%o", 100000000000L, "1351035564000")
+testboth("%d", 10L, "10")
+testboth("%d", 100000000000L, "100000000000")
+
+big = 123456789012345678901234567890L
+testboth("%d", big, "123456789012345678901234567890")
+testboth("%d", -big, "-123456789012345678901234567890")
+testboth("%5d", -big, "-123456789012345678901234567890")
+testboth("%31d", -big, "-123456789012345678901234567890")
+testboth("%32d", -big, " -123456789012345678901234567890")
+testboth("%-32d", -big, "-123456789012345678901234567890 ")
+testboth("%032d", -big, "-0123456789012345678901234567890")
+testboth("%-032d", -big, "-123456789012345678901234567890 ")
+testboth("%034d", -big, "-000123456789012345678901234567890")
+testboth("%034d", big, "0000123456789012345678901234567890")
+testboth("%0+34d", big, "+000123456789012345678901234567890")
+testboth("%+34d", big, "   +123456789012345678901234567890")
+testboth("%34d", big, "    123456789012345678901234567890")
+testboth("%.2d", big, "123456789012345678901234567890")
+testboth("%.30d", big, "123456789012345678901234567890")
+testboth("%.31d", big, "0123456789012345678901234567890")
+testboth("%32.31d", big, " 0123456789012345678901234567890")
+
+big = 0x1234567890abcdef12345L  # 21 hex digits
+testboth("%x", big, "1234567890abcdef12345")
+testboth("%x", -big, "-1234567890abcdef12345")
+testboth("%5x", -big, "-1234567890abcdef12345")
+testboth("%22x", -big, "-1234567890abcdef12345")
+testboth("%23x", -big, " -1234567890abcdef12345")
+testboth("%-23x", -big, "-1234567890abcdef12345 ")
+testboth("%023x", -big, "-01234567890abcdef12345")
+testboth("%-023x", -big, "-1234567890abcdef12345 ")
+testboth("%025x", -big, "-0001234567890abcdef12345")
+testboth("%025x", big, "00001234567890abcdef12345")
+testboth("%0+25x", big, "+0001234567890abcdef12345")
+testboth("%+25x", big, "   +1234567890abcdef12345")
+testboth("%25x", big, "    1234567890abcdef12345")
+testboth("%.2x", big, "1234567890abcdef12345")
+testboth("%.21x", big, "1234567890abcdef12345")
+testboth("%.22x", big, "01234567890abcdef12345")
+testboth("%23.22x", big, " 01234567890abcdef12345")
+testboth("%-23.22x", big, "01234567890abcdef12345 ")
+testboth("%X", big, "1234567890ABCDEF12345")
+testboth("%#X", big, "0X1234567890ABCDEF12345")
+testboth("%#x", big, "0x1234567890abcdef12345")
+testboth("%#x", -big, "-0x1234567890abcdef12345")
+testboth("%#.23x", -big, "-0x001234567890abcdef12345")
+testboth("%#+.23x", big, "+0x001234567890abcdef12345")
+testboth("%# .23x", big, " 0x001234567890abcdef12345")
+testboth("%#+.23X", big, "+0X001234567890ABCDEF12345")
+testboth("%#-+.23X", big, "+0X001234567890ABCDEF12345")
+testboth("%#-+26.23X", big, "+0X001234567890ABCDEF12345")
+testboth("%#-+27.23X", big, "+0X001234567890ABCDEF12345 ")
+testboth("%#+27.23X", big, " +0X001234567890ABCDEF12345")
+# next one gets two leading zeroes from precision, and another from the
+# 0 flag and the width
+testboth("%#+027.23X", big, "+0X0001234567890ABCDEF12345")
+# same, except no 0 flag
+testboth("%#+27.23X", big, " +0X001234567890ABCDEF12345")
+
+big = 012345670123456701234567012345670L  # 32 octal digits
+testboth("%o", big, "12345670123456701234567012345670")
+testboth("%o", -big, "-12345670123456701234567012345670")
+testboth("%5o", -big, "-12345670123456701234567012345670")
+testboth("%33o", -big, "-12345670123456701234567012345670")
+testboth("%34o", -big, " -12345670123456701234567012345670")
+testboth("%-34o", -big, "-12345670123456701234567012345670 ")
+testboth("%034o", -big, "-012345670123456701234567012345670")
+testboth("%-034o", -big, "-12345670123456701234567012345670 ")
+testboth("%036o", -big, "-00012345670123456701234567012345670")
+testboth("%036o", big, "000012345670123456701234567012345670")
+testboth("%0+36o", big, "+00012345670123456701234567012345670")
+testboth("%+36o", big, "   +12345670123456701234567012345670")
+testboth("%36o", big, "    12345670123456701234567012345670")
+testboth("%.2o", big, "12345670123456701234567012345670")
+testboth("%.32o", big, "12345670123456701234567012345670")
+testboth("%.33o", big, "012345670123456701234567012345670")
+testboth("%34.33o", big, " 012345670123456701234567012345670")
+testboth("%-34.33o", big, "012345670123456701234567012345670 ")
+testboth("%o", big, "12345670123456701234567012345670")
+testboth("%#o", big, "012345670123456701234567012345670")
+testboth("%#o", -big, "-012345670123456701234567012345670")
+testboth("%#.34o", -big, "-0012345670123456701234567012345670")
+testboth("%#+.34o", big, "+0012345670123456701234567012345670")
+testboth("%# .34o", big, " 0012345670123456701234567012345670")
+testboth("%#+.34o", big, "+0012345670123456701234567012345670")
+testboth("%#-+.34o", big, "+0012345670123456701234567012345670")
+testboth("%#-+37.34o", big, "+0012345670123456701234567012345670  ")
+testboth("%#+37.34o", big, "  +0012345670123456701234567012345670")
+# next one gets one leading zero from precision
+testboth("%.33o", big, "012345670123456701234567012345670")
+# base marker shouldn't change that, since "0" is redundant
+testboth("%#.33o", big, "012345670123456701234567012345670")
+# but reduce precision, and base marker should add a zero
+testboth("%#.32o", big, "012345670123456701234567012345670")
+# one leading zero from precision, and another from "0" flag & width
+testboth("%034.33o", big, "0012345670123456701234567012345670")
+# base marker shouldn't change that
+testboth("%0#34.33o", big, "0012345670123456701234567012345670")
+
+# Some small ints, in both Python int and long flavors).
+testboth("%d", 42, "42")
+testboth("%d", -42, "-42")
+testboth("%d", 42L, "42")
+testboth("%d", -42L, "-42")
+testboth("%#x", 1, "0x1")
+testboth("%#x", 1L, "0x1")
+testboth("%#X", 1, "0X1")
+testboth("%#X", 1L, "0X1")
+testboth("%#o", 1, "01")
+testboth("%#o", 1L, "01")
+testboth("%#o", 0, "0")
+testboth("%#o", 0L, "0")
+testboth("%o", 0, "0")
+testboth("%o", 0L, "0")
+testboth("%d", 0, "0")
+testboth("%d", 0L, "0")
+testboth("%#x", 0, "0x0")
+testboth("%#x", 0L, "0x0")
+testboth("%#X", 0, "0X0")
+testboth("%#X", 0L, "0X0")
+
+testboth("%x", 0x42, "42")
+testboth("%x", -0x42, "-42")
+testboth("%x", 0x42L, "42")
+testboth("%x", -0x42L, "-42")
+
+testboth("%o", 042, "42")
+testboth("%o", -042, "-42")
+testboth("%o", 042L, "42")
+testboth("%o", -042L, "-42")
+
+# Test exception for unknown format characters
+if verbose:
+    print 'Testing exceptions'
+
+def test_exc(formatstr, args, exception, excmsg):
+    try:
+        testformat(formatstr, args)
+    except exception, exc:
+        if str(exc) == excmsg:
+            if verbose:
+                print "yes"
+        else:
+            if verbose: print 'no'
+            print 'Unexpected ', exception, ':', repr(str(exc))
+    except:
+        if verbose: print 'no'
+        print 'Unexpected exception'
+        raise
+    else:
+        raise TestFailed, 'did not get expected exception: %s' % excmsg
+
+test_exc('abc %a', 1, ValueError,
+         "unsupported format character 'a' (0x61) at index 5")
+if have_unicode:
+    test_exc(unicode('abc %\u3000','raw-unicode-escape'), 1, ValueError,
+             "unsupported format character '?' (0x3000) at index 5")
+
+test_exc('%d', '1', TypeError, "int argument required")
+test_exc('%g', '1', TypeError, "float argument required")
+test_exc('no format', '1', TypeError,
+         "not all arguments converted during string formatting")
+test_exc('no format', u'1', TypeError,
+         "not all arguments converted during string formatting")
+test_exc(u'no format', '1', TypeError,
+         "not all arguments converted during string formatting")
+test_exc(u'no format', u'1', TypeError,
+         "not all arguments converted during string formatting")
+
+class Foobar(long):
+    def __oct__(self):
+        # Returning a non-string should not blow up.
+        return self + 1
+
+test_exc('%o', Foobar(), TypeError,
+         "expected string or Unicode object, long found")
+
+if sys.maxint == 2**31-1:
+    # crashes 2.2.1 and earlier:
+    try:
+        "%*d"%(sys.maxint, -127)
+    except MemoryError:
+        pass
+    else:
+        raise TestFailed, '"%*d"%(sys.maxint, -127) should fail'

Added: vendor/Python/current/Lib/test/test_fpformat.py
===================================================================
--- vendor/Python/current/Lib/test/test_fpformat.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_fpformat.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,75 @@
+'''
+   Tests for fpformat module
+   Nick Mathewson
+'''
+from test.test_support import run_unittest
+import unittest
+from fpformat import fix, sci, NotANumber
+
+StringType = type('')
+
+# Test the old and obsolescent fpformat module.
+#
+# (It's obsolescent because fix(n,d) == "%.*f"%(d,n) and
+#                           sci(n,d) == "%.*e"%(d,n)
+#  for all reasonable numeric n and d, except that sci gives 3 exponent
+#  digits instead of 2.
+#
+# Differences only occur for unreasonable n and d.    <.2 wink>)
+
+class FpformatTest(unittest.TestCase):
+
+    def checkFix(self, n, digits):
+        result = fix(n, digits)
+        if isinstance(n, StringType):
+            n = repr(n)
+        expected = "%.*f" % (digits, float(n))
+
+        self.assertEquals(result, expected)
+
+    def checkSci(self, n, digits):
+        result = sci(n, digits)
+        if isinstance(n, StringType):
+            n = repr(n)
+        expected = "%.*e" % (digits, float(n))
+        # add the extra 0 if needed
+        num, exp = expected.split("e")
+        if len(exp) < 4:
+            exp = exp[0] + "0" + exp[1:]
+        expected = "%se%s" % (num, exp)
+
+        self.assertEquals(result, expected)
+
+    def test_basic_cases(self):
+        self.assertEquals(fix(100.0/3, 3), '33.333')
+        self.assertEquals(sci(100.0/3, 3), '3.333e+001')
+
+    def test_reasonable_values(self):
+        for d in range(7):
+            for val in (1000.0/3, 1000, 1000.0, .002, 1.0/3, 1e10):
+                for realVal in (val, 1.0/val, -val, -1.0/val):
+                    self.checkFix(realVal, d)
+                    self.checkSci(realVal, d)
+
+    def test_failing_values(self):
+        # Now for 'unreasonable n and d'
+        self.assertEquals(fix(1.0, 1000), '1.'+('0'*1000))
+        self.assertEquals(sci("1"+('0'*1000), 0), '1e+1000')
+
+        # This behavior is inconsistent.  sci raises an exception; fix doesn't.
+        yacht = "Throatwobbler Mangrove"
+        self.assertEquals(fix(yacht, 10), yacht)
+        try:
+            sci(yacht, 10)
+        except NotANumber:
+            pass
+        else:
+            self.fail("No exception on non-numeric sci")
+
+
+def test_main():
+    run_unittest(FpformatTest)
+
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_frozen.py
===================================================================
--- vendor/Python/current/Lib/test/test_frozen.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_frozen.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,27 @@
+# Test the frozen module defined in frozen.c.
+
+from test.test_support import TestFailed
+import sys, os
+
+try:
+    import __hello__
+except ImportError, x:
+    raise TestFailed, "import __hello__ failed:" + str(x)
+
+try:
+    import __phello__
+except ImportError, x:
+    raise TestFailed, "import __phello__ failed:" + str(x)
+
+try:
+    import __phello__.spam
+except ImportError, x:
+    raise TestFailed, "import __phello__.spam failed:" + str(x)
+
+if sys.platform != "mac":  # On the Mac this import does succeed.
+    try:
+        import __phello__.foo
+    except ImportError:
+        pass
+    else:
+        raise TestFailed, "import __phello__.foo should have failed"

Added: vendor/Python/current/Lib/test/test_funcattrs.py
===================================================================
--- vendor/Python/current/Lib/test/test_funcattrs.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_funcattrs.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,402 @@
+from test.test_support import verbose, TestFailed, verify
+import types
+
+class F:
+    def a(self):
+        pass
+
+def b():
+    'my docstring'
+    pass
+
+# __module__ is a special attribute
+verify(b.__module__ == __name__)
+verify(verify.__module__ == "test.test_support")
+
+# setting attributes on functions
+try:
+    b.publish
+except AttributeError: pass
+else: raise TestFailed, 'expected AttributeError'
+
+if b.__dict__ <> {}:
+    raise TestFailed, 'expected unassigned func.__dict__ to be {}'
+
+b.publish = 1
+if b.publish <> 1:
+    raise TestFailed, 'function attribute not set to expected value'
+
+docstring = 'its docstring'
+b.__doc__ = docstring
+if b.__doc__ <> docstring:
+    raise TestFailed, 'problem with setting __doc__ attribute'
+
+if 'publish' not in dir(b):
+    raise TestFailed, 'attribute not in dir()'
+
+try:
+    del b.__dict__
+except TypeError: pass
+else: raise TestFailed, 'del func.__dict__ expected TypeError'
+
+b.publish = 1
+try:
+    b.__dict__ = None
+except TypeError: pass
+else: raise TestFailed, 'func.__dict__ = None expected TypeError'
+
+d = {'hello': 'world'}
+b.__dict__ = d
+if b.func_dict is not d:
+    raise TestFailed, 'func.__dict__ assignment to dictionary failed'
+if b.hello <> 'world':
+    raise TestFailed, 'attribute after func.__dict__ assignment failed'
+
+f1 = F()
+f2 = F()
+
+try:
+    F.a.publish
+except AttributeError: pass
+else: raise TestFailed, 'expected AttributeError'
+
+try:
+    f1.a.publish
+except AttributeError: pass
+else: raise TestFailed, 'expected AttributeError'
+
+# In Python 2.1 beta 1, we disallowed setting attributes on unbound methods
+# (it was already disallowed on bound methods).  See the PEP for details.
+try:
+    F.a.publish = 1
+except (AttributeError, TypeError): pass
+else: raise TestFailed, 'expected AttributeError or TypeError'
+
+# But setting it explicitly on the underlying function object is okay.
+F.a.im_func.publish = 1
+
+if F.a.publish <> 1:
+    raise TestFailed, 'unbound method attribute not set to expected value'
+
+if f1.a.publish <> 1:
+    raise TestFailed, 'bound method attribute access did not work'
+
+if f2.a.publish <> 1:
+    raise TestFailed, 'bound method attribute access did not work'
+
+if 'publish' not in dir(F.a):
+    raise TestFailed, 'attribute not in dir()'
+
+try:
+    f1.a.publish = 0
+except (AttributeError, TypeError): pass
+else: raise TestFailed, 'expected AttributeError or TypeError'
+
+# See the comment above about the change in semantics for Python 2.1b1
+try:
+    F.a.myclass = F
+except (AttributeError, TypeError): pass
+else: raise TestFailed, 'expected AttributeError or TypeError'
+
+F.a.im_func.myclass = F
+
+f1.a.myclass
+f2.a.myclass
+f1.a.myclass
+F.a.myclass
+
+if f1.a.myclass is not f2.a.myclass or \
+       f1.a.myclass is not F.a.myclass:
+    raise TestFailed, 'attributes were not the same'
+
+# try setting __dict__
+try:
+    F.a.__dict__ = (1, 2, 3)
+except (AttributeError, TypeError): pass
+else: raise TestFailed, 'expected TypeError or AttributeError'
+
+F.a.im_func.__dict__ = {'one': 11, 'two': 22, 'three': 33}
+
+if f1.a.two <> 22:
+    raise TestFailed, 'setting __dict__'
+
+from UserDict import UserDict
+d = UserDict({'four': 44, 'five': 55})
+
+try:
+    F.a.__dict__ = d
+except (AttributeError, TypeError): pass
+else: raise TestFailed
+
+if f2.a.one <> f1.a.one <> F.a.one <> 11:
+    raise TestFailed
+
+# im_func may not be a Python method!
+import new
+F.id = new.instancemethod(id, None, F)
+
+eff = F()
+if eff.id() <> id(eff):
+    raise TestFailed
+
+try:
+    F.id.foo
+except AttributeError: pass
+else: raise TestFailed
+
+try:
+    F.id.foo = 12
+except (AttributeError, TypeError): pass
+else: raise TestFailed
+
+try:
+    F.id.foo
+except AttributeError: pass
+else: raise TestFailed
+
+try:
+    eff.id.foo
+except AttributeError: pass
+else: raise TestFailed
+
+try:
+    eff.id.foo = 12
+except (AttributeError, TypeError): pass
+else: raise TestFailed
+
+try:
+    eff.id.foo
+except AttributeError: pass
+else: raise TestFailed
+
+# Regression test for a crash in pre-2.1a1
+def another():
+    pass
+
+try:
+    del another.__dict__
+except TypeError: pass
+else: raise TestFailed
+
+try:
+    del another.func_dict
+except TypeError: pass
+else: raise TestFailed
+
+try:
+    another.func_dict = None
+except TypeError: pass
+else: raise TestFailed
+
+try:
+    del another.bar
+except AttributeError: pass
+else: raise TestFailed
+
+# This isn't specifically related to function attributes, but it does test a
+# core dump regression in funcobject.c
+del another.func_defaults
+
+def foo():
+    pass
+
+def bar():
+    pass
+
+def temp():
+    print 1
+
+if foo==bar:
+    raise TestFailed
+
+d={}
+d[foo] = 1
+
+foo.func_code = temp.func_code
+
+d[foo]
+
+# Test all predefined function attributes systematically
+
+def cantset(obj, name, value, exception=(AttributeError, TypeError)):
+    verify(hasattr(obj, name)) # Otherwise it's probably a typo
+    try:
+        setattr(obj, name, value)
+    except exception:
+        pass
+    else:
+        raise TestFailed, "shouldn't be able to set %s to %r" % (name, value)
+    try:
+        delattr(obj, name)
+    except (AttributeError, TypeError):
+        pass
+    else:
+        raise TestFailed, "shouldn't be able to del %s" % name
+
+def test_func_closure():
+    a = 12
+    def f(): print a
+    c = f.func_closure
+    verify(isinstance(c, tuple))
+    verify(len(c) == 1)
+    verify(c[0].__class__.__name__ == "cell") # don't have a type object handy
+    cantset(f, "func_closure", c)
+
+def test_func_doc():
+    def f(): pass
+    verify(f.__doc__ is None)
+    verify(f.func_doc is None)
+    f.__doc__ = "hello"
+    verify(f.__doc__ == "hello")
+    verify(f.func_doc == "hello")
+    del f.__doc__
+    verify(f.__doc__ is None)
+    verify(f.func_doc is None)
+    f.func_doc = "world"
+    verify(f.__doc__ == "world")
+    verify(f.func_doc == "world")
+    del f.func_doc
+    verify(f.func_doc is None)
+    verify(f.__doc__ is None)
+
+def test_func_globals():
+    def f(): pass
+    verify(f.func_globals is globals())
+    cantset(f, "func_globals", globals())
+
+def test_func_name():
+    def f(): pass
+    verify(f.__name__ == "f")
+    verify(f.func_name == "f")
+    f.__name__ = "g"
+    verify(f.__name__ == "g")
+    verify(f.func_name == "g")
+    f.func_name = "h"
+    verify(f.__name__ == "h")
+    verify(f.func_name == "h")
+    cantset(f, "func_globals", 1)
+    cantset(f, "__name__", 1)
+    # test that you can access func.__name__ in restricted mode
+    s = """def f(): pass\nf.__name__"""
+    exec s in {'__builtins__':{}}
+
+
+def test_func_code():
+    a = b = 24
+    def f(): pass
+    def g(): print 12
+    def f1(): print a
+    def g1(): print b
+    def f2(): print a, b
+    verify(type(f.func_code) is types.CodeType)
+    f.func_code = g.func_code
+    cantset(f, "func_code", None)
+    # can't change the number of free vars
+    cantset(f,  "func_code", f1.func_code, exception=ValueError)
+    cantset(f1, "func_code",  f.func_code, exception=ValueError)
+    cantset(f1, "func_code", f2.func_code, exception=ValueError)
+    f1.func_code = g1.func_code
+
+def test_func_defaults():
+    def f(a, b): return (a, b)
+    verify(f.func_defaults is None)
+    f.func_defaults = (1, 2)
+    verify(f.func_defaults == (1, 2))
+    verify(f(10) == (10, 2))
+    def g(a=1, b=2): return (a, b)
+    verify(g.func_defaults == (1, 2))
+    del g.func_defaults
+    verify(g.func_defaults is None)
+    try:
+        g()
+    except TypeError:
+        pass
+    else:
+        raise TestFailed, "shouldn't be allowed to call g() w/o defaults"
+
+def test_func_dict():
+    def f(): pass
+    a = f.__dict__
+    b = f.func_dict
+    verify(a == {})
+    verify(a is b)
+    f.hello = 'world'
+    verify(a == {'hello': 'world'})
+    verify(f.func_dict is a is f.__dict__)
+    f.func_dict = {}
+    verify(not hasattr(f, "hello"))
+    f.__dict__ = {'world': 'hello'}
+    verify(f.world == "hello")
+    verify(f.__dict__ is f.func_dict == {'world': 'hello'})
+    cantset(f, "func_dict", None)
+    cantset(f, "__dict__", None)
+
+def test_im_class():
+    class C:
+        def foo(self): pass
+    verify(C.foo.im_class is C)
+    verify(C().foo.im_class is C)
+    cantset(C.foo, "im_class", C)
+    cantset(C().foo, "im_class", C)
+
+def test_im_func():
+    def foo(self): pass
+    class C:
+        pass
+    C.foo = foo
+    verify(C.foo.im_func is foo)
+    verify(C().foo.im_func is foo)
+    cantset(C.foo, "im_func", foo)
+    cantset(C().foo, "im_func", foo)
+
+def test_im_self():
+    class C:
+        def foo(self): pass
+    verify(C.foo.im_self is None)
+    c = C()
+    verify(c.foo.im_self is c)
+    cantset(C.foo, "im_self", None)
+    cantset(c.foo, "im_self", c)
+
+def test_im_dict():
+    class C:
+        def foo(self): pass
+        foo.bar = 42
+    verify(C.foo.__dict__ == {'bar': 42})
+    verify(C().foo.__dict__ == {'bar': 42})
+    cantset(C.foo, "__dict__", C.foo.__dict__)
+    cantset(C().foo, "__dict__", C.foo.__dict__)
+
+def test_im_doc():
+    class C:
+        def foo(self): "hello"
+    verify(C.foo.__doc__ == "hello")
+    verify(C().foo.__doc__ == "hello")
+    cantset(C.foo, "__doc__", "hello")
+    cantset(C().foo, "__doc__", "hello")
+
+def test_im_name():
+    class C:
+        def foo(self): pass
+    verify(C.foo.__name__ == "foo")
+    verify(C().foo.__name__ == "foo")
+    cantset(C.foo, "__name__", "foo")
+    cantset(C().foo, "__name__", "foo")
+
+def testmore():
+    test_func_closure()
+    test_func_doc()
+    test_func_globals()
+    test_func_name()
+    test_func_code()
+    test_func_defaults()
+    test_func_dict()
+    # Tests for instance method attributes
+    test_im_class()
+    test_im_func()
+    test_im_self()
+    test_im_dict()
+    test_im_doc()
+    test_im_name()
+
+testmore()

Added: vendor/Python/current/Lib/test/test_functools.py
===================================================================
--- vendor/Python/current/Lib/test/test_functools.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_functools.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,293 @@
+import functools
+import unittest
+from test import test_support
+from weakref import proxy
+
+ at staticmethod
+def PythonPartial(func, *args, **keywords):
+    'Pure Python approximation of partial()'
+    def newfunc(*fargs, **fkeywords):
+        newkeywords = keywords.copy()
+        newkeywords.update(fkeywords)
+        return func(*(args + fargs), **newkeywords)
+    newfunc.func = func
+    newfunc.args = args
+    newfunc.keywords = keywords
+    return newfunc
+
+def capture(*args, **kw):
+    """capture all positional and keyword arguments"""
+    return args, kw
+
+class TestPartial(unittest.TestCase):
+
+    thetype = functools.partial
+
+    def test_basic_examples(self):
+        p = self.thetype(capture, 1, 2, a=10, b=20)
+        self.assertEqual(p(3, 4, b=30, c=40),
+                         ((1, 2, 3, 4), dict(a=10, b=30, c=40)))
+        p = self.thetype(map, lambda x: x*10)
+        self.assertEqual(p([1,2,3,4]), [10, 20, 30, 40])
+
+    def test_attributes(self):
+        p = self.thetype(capture, 1, 2, a=10, b=20)
+        # attributes should be readable
+        self.assertEqual(p.func, capture)
+        self.assertEqual(p.args, (1, 2))
+        self.assertEqual(p.keywords, dict(a=10, b=20))
+        # attributes should not be writable
+        if not isinstance(self.thetype, type):
+            return
+        self.assertRaises(TypeError, setattr, p, 'func', map)
+        self.assertRaises(TypeError, setattr, p, 'args', (1, 2))
+        self.assertRaises(TypeError, setattr, p, 'keywords', dict(a=1, b=2))
+
+    def test_argument_checking(self):
+        self.assertRaises(TypeError, self.thetype)     # need at least a func arg
+        try:
+            self.thetype(2)()
+        except TypeError:
+            pass
+        else:
+            self.fail('First arg not checked for callability')
+
+    def test_protection_of_callers_dict_argument(self):
+        # a caller's dictionary should not be altered by partial
+        def func(a=10, b=20):
+            return a
+        d = {'a':3}
+        p = self.thetype(func, a=5)
+        self.assertEqual(p(**d), 3)
+        self.assertEqual(d, {'a':3})
+        p(b=7)
+        self.assertEqual(d, {'a':3})
+
+    def test_arg_combinations(self):
+        # exercise special code paths for zero args in either partial
+        # object or the caller
+        p = self.thetype(capture)
+        self.assertEqual(p(), ((), {}))
+        self.assertEqual(p(1,2), ((1,2), {}))
+        p = self.thetype(capture, 1, 2)
+        self.assertEqual(p(), ((1,2), {}))
+        self.assertEqual(p(3,4), ((1,2,3,4), {}))
+
+    def test_kw_combinations(self):
+        # exercise special code paths for no keyword args in
+        # either the partial object or the caller
+        p = self.thetype(capture)
+        self.assertEqual(p(), ((), {}))
+        self.assertEqual(p(a=1), ((), {'a':1}))
+        p = self.thetype(capture, a=1)
+        self.assertEqual(p(), ((), {'a':1}))
+        self.assertEqual(p(b=2), ((), {'a':1, 'b':2}))
+        # keyword args in the call override those in the partial object
+        self.assertEqual(p(a=3, b=2), ((), {'a':3, 'b':2}))
+
+    def test_positional(self):
+        # make sure positional arguments are captured correctly
+        for args in [(), (0,), (0,1), (0,1,2), (0,1,2,3)]:
+            p = self.thetype(capture, *args)
+            expected = args + ('x',)
+            got, empty = p('x')
+            self.failUnless(expected == got and empty == {})
+
+    def test_keyword(self):
+        # make sure keyword arguments are captured correctly
+        for a in ['a', 0, None, 3.5]:
+            p = self.thetype(capture, a=a)
+            expected = {'a':a,'x':None}
+            empty, got = p(x=None)
+            self.failUnless(expected == got and empty == ())
+
+    def test_no_side_effects(self):
+        # make sure there are no side effects that affect subsequent calls
+        p = self.thetype(capture, 0, a=1)
+        args1, kw1 = p(1, b=2)
+        self.failUnless(args1 == (0,1) and kw1 == {'a':1,'b':2})
+        args2, kw2 = p()
+        self.failUnless(args2 == (0,) and kw2 == {'a':1})
+
+    def test_error_propagation(self):
+        def f(x, y):
+            x / y
+        self.assertRaises(ZeroDivisionError, self.thetype(f, 1, 0))
+        self.assertRaises(ZeroDivisionError, self.thetype(f, 1), 0)
+        self.assertRaises(ZeroDivisionError, self.thetype(f), 1, 0)
+        self.assertRaises(ZeroDivisionError, self.thetype(f, y=0), 1)
+
+    def test_attributes(self):
+        p = self.thetype(hex)
+        try:
+            del p.__dict__
+        except TypeError:
+            pass
+        else:
+            self.fail('partial object allowed __dict__ to be deleted')
+
+    def test_weakref(self):
+        f = self.thetype(int, base=16)
+        p = proxy(f)
+        self.assertEqual(f.func, p.func)
+        f = None
+        self.assertRaises(ReferenceError, getattr, p, 'func')
+
+    def test_with_bound_and_unbound_methods(self):
+        data = map(str, range(10))
+        join = self.thetype(str.join, '')
+        self.assertEqual(join(data), '0123456789')
+        join = self.thetype(''.join)
+        self.assertEqual(join(data), '0123456789')
+
+class PartialSubclass(functools.partial):
+    pass
+
+class TestPartialSubclass(TestPartial):
+
+    thetype = PartialSubclass
+
+
+class TestPythonPartial(TestPartial):
+
+    thetype = PythonPartial
+
+class TestUpdateWrapper(unittest.TestCase):
+
+    def check_wrapper(self, wrapper, wrapped,
+                      assigned=functools.WRAPPER_ASSIGNMENTS,
+                      updated=functools.WRAPPER_UPDATES):
+        # Check attributes were assigned
+        for name in assigned:
+            self.failUnless(getattr(wrapper, name) is getattr(wrapped, name))
+        # Check attributes were updated
+        for name in updated:
+            wrapper_attr = getattr(wrapper, name)
+            wrapped_attr = getattr(wrapped, name)
+            for key in wrapped_attr:
+                self.failUnless(wrapped_attr[key] is wrapper_attr[key])
+
+    def test_default_update(self):
+        def f():
+            """This is a test"""
+            pass
+        f.attr = 'This is also a test'
+        def wrapper():
+            pass
+        functools.update_wrapper(wrapper, f)
+        self.check_wrapper(wrapper, f)
+        self.assertEqual(wrapper.__name__, 'f')
+        self.assertEqual(wrapper.__doc__, 'This is a test')
+        self.assertEqual(wrapper.attr, 'This is also a test')
+
+    def test_no_update(self):
+        def f():
+            """This is a test"""
+            pass
+        f.attr = 'This is also a test'
+        def wrapper():
+            pass
+        functools.update_wrapper(wrapper, f, (), ())
+        self.check_wrapper(wrapper, f, (), ())
+        self.assertEqual(wrapper.__name__, 'wrapper')
+        self.assertEqual(wrapper.__doc__, None)
+        self.failIf(hasattr(wrapper, 'attr'))
+
+    def test_selective_update(self):
+        def f():
+            pass
+        f.attr = 'This is a different test'
+        f.dict_attr = dict(a=1, b=2, c=3)
+        def wrapper():
+            pass
+        wrapper.dict_attr = {}
+        assign = ('attr',)
+        update = ('dict_attr',)
+        functools.update_wrapper(wrapper, f, assign, update)
+        self.check_wrapper(wrapper, f, assign, update)
+        self.assertEqual(wrapper.__name__, 'wrapper')
+        self.assertEqual(wrapper.__doc__, None)
+        self.assertEqual(wrapper.attr, 'This is a different test')
+        self.assertEqual(wrapper.dict_attr, f.dict_attr)
+
+    def test_builtin_update(self):
+        # Test for bug #1576241
+        def wrapper():
+            pass
+        functools.update_wrapper(wrapper, max)
+        self.assertEqual(wrapper.__name__, 'max')
+        self.assert_(wrapper.__doc__.startswith('max('))
+
+class TestWraps(TestUpdateWrapper):
+
+    def test_default_update(self):
+        def f():
+            """This is a test"""
+            pass
+        f.attr = 'This is also a test'
+        @functools.wraps(f)
+        def wrapper():
+            pass
+        self.check_wrapper(wrapper, f)
+        self.assertEqual(wrapper.__name__, 'f')
+        self.assertEqual(wrapper.__doc__, 'This is a test')
+        self.assertEqual(wrapper.attr, 'This is also a test')
+
+    def test_no_update(self):
+        def f():
+            """This is a test"""
+            pass
+        f.attr = 'This is also a test'
+        @functools.wraps(f, (), ())
+        def wrapper():
+            pass
+        self.check_wrapper(wrapper, f, (), ())
+        self.assertEqual(wrapper.__name__, 'wrapper')
+        self.assertEqual(wrapper.__doc__, None)
+        self.failIf(hasattr(wrapper, 'attr'))
+
+    def test_selective_update(self):
+        def f():
+            pass
+        f.attr = 'This is a different test'
+        f.dict_attr = dict(a=1, b=2, c=3)
+        def add_dict_attr(f):
+            f.dict_attr = {}
+            return f
+        assign = ('attr',)
+        update = ('dict_attr',)
+        @functools.wraps(f, assign, update)
+        @add_dict_attr
+        def wrapper():
+            pass
+        self.check_wrapper(wrapper, f, assign, update)
+        self.assertEqual(wrapper.__name__, 'wrapper')
+        self.assertEqual(wrapper.__doc__, None)
+        self.assertEqual(wrapper.attr, 'This is a different test')
+        self.assertEqual(wrapper.dict_attr, f.dict_attr)
+
+
+
+def test_main(verbose=None):
+    import sys
+    test_classes = (
+        TestPartial,
+        TestPartialSubclass,
+        TestPythonPartial,
+        TestUpdateWrapper,
+        TestWraps
+    )
+    test_support.run_unittest(*test_classes)
+
+    # verify reference counting
+    if verbose and hasattr(sys, "gettotalrefcount"):
+        import gc
+        counts = [None] * 5
+        for i in xrange(len(counts)):
+            test_support.run_unittest(*test_classes)
+            gc.collect()
+            counts[i] = sys.gettotalrefcount()
+        print counts
+
+if __name__ == '__main__':
+    test_main(verbose=True)

Added: vendor/Python/current/Lib/test/test_future.py
===================================================================
--- vendor/Python/current/Lib/test/test_future.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_future.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,106 @@
+# Test various flavors of legal and illegal future statements
+
+import unittest
+from test import test_support
+import re
+
+rx = re.compile('\((\S+).py, line (\d+)')
+
+def get_error_location(msg):
+    mo = rx.search(str(msg))
+    return mo.group(1, 2)
+
+class FutureTest(unittest.TestCase):
+
+    def test_future1(self):
+        test_support.unload('test_future1')
+        from test import test_future1
+        self.assertEqual(test_future1.result, 6)
+
+    def test_future2(self):
+        test_support.unload('test_future2')
+        from test import test_future2
+        self.assertEqual(test_future2.result, 6)
+
+    def test_future3(self):
+        test_support.unload('test_future3')
+        from test import test_future3
+
+    def test_badfuture3(self):
+        try:
+            from test import badsyntax_future3
+        except SyntaxError, msg:
+            self.assertEqual(get_error_location(msg), ("badsyntax_future3", '3'))
+        else:
+            self.fail("expected exception didn't occur")
+
+    def test_badfuture4(self):
+        try:
+            from test import badsyntax_future4
+        except SyntaxError, msg:
+            self.assertEqual(get_error_location(msg), ("badsyntax_future4", '3'))
+        else:
+            self.fail("expected exception didn't occur")
+
+    def test_badfuture5(self):
+        try:
+            from test import badsyntax_future5
+        except SyntaxError, msg:
+            self.assertEqual(get_error_location(msg), ("badsyntax_future5", '4'))
+        else:
+            self.fail("expected exception didn't occur")
+
+    def test_badfuture6(self):
+        try:
+            from test import badsyntax_future6
+        except SyntaxError, msg:
+            self.assertEqual(get_error_location(msg), ("badsyntax_future6", '3'))
+        else:
+            self.fail("expected exception didn't occur")
+
+    def test_badfuture7(self):
+        try:
+            from test import badsyntax_future7
+        except SyntaxError, msg:
+            self.assertEqual(get_error_location(msg), ("badsyntax_future7", '3'))
+        else:
+            self.fail("expected exception didn't occur")
+
+    def test_badfuture8(self):
+        try:
+            from test import badsyntax_future8
+        except SyntaxError, msg:
+            self.assertEqual(get_error_location(msg), ("badsyntax_future8", '3'))
+        else:
+            self.fail("expected exception didn't occur")
+
+    def test_badfuture9(self):
+        try:
+            from test import badsyntax_future9
+        except SyntaxError, msg:
+            self.assertEqual(get_error_location(msg), ("badsyntax_future9", '3'))
+        else:
+            self.fail("expected exception didn't occur")
+
+    def test_parserhack(self):
+        # test that the parser.c::future_hack function works as expected
+        try:
+            exec "from __future__ import division, with_statement; with = 0"
+        except SyntaxError:
+            pass
+        else:
+            self.fail("syntax error didn't occur")
+
+        try:
+            exec "from __future__ import (with_statement, division); with = 0"
+        except SyntaxError:
+            pass
+        else:
+            self.fail("syntax error didn't occur")
+
+
+def test_main():
+    test_support.run_unittest(FutureTest)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_future1.py
===================================================================
--- vendor/Python/current/Lib/test/test_future1.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_future1.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,11 @@
+"""This is a test"""
+
+# Import the name nested_scopes twice to trigger SF bug #407394 (regression).
+from __future__ import nested_scopes, nested_scopes
+
+def f(x):
+    def g(y):
+        return x + y
+    return g
+
+result = f(2)(4)

Added: vendor/Python/current/Lib/test/test_future2.py
===================================================================
--- vendor/Python/current/Lib/test/test_future2.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_future2.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,10 @@
+"""This is a test"""
+
+from __future__ import nested_scopes; import string
+
+def f(x):
+    def g(y):
+        return x + y
+    return g
+
+result = f(2)(4)

Added: vendor/Python/current/Lib/test/test_future3.py
===================================================================
--- vendor/Python/current/Lib/test/test_future3.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_future3.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,30 @@
+from __future__ import nested_scopes
+from __future__ import division
+
+import unittest
+from test import test_support
+
+x = 2
+def nester():
+    x = 3
+    def inner():
+        return x
+    return inner()
+
+
+class TestFuture(unittest.TestCase):
+
+    def test_floor_div_operator(self):
+        self.assertEqual(7 // 2, 3)
+
+    def test_true_div_as_default(self):
+        self.assertAlmostEqual(7 / 2, 3.5)
+
+    def test_nested_scopes(self):
+        self.assertEqual(nester(), 3)
+
+def test_main():
+    test_support.run_unittest(TestFuture)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_gc.py
===================================================================
--- vendor/Python/current/Lib/test/test_gc.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_gc.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,636 @@
+from test.test_support import verify, verbose, TestFailed, vereq
+import sys
+import gc
+import weakref
+
+def expect(actual, expected, name):
+    if actual != expected:
+        raise TestFailed, "test_%s: actual %r, expected %r" % (
+            name, actual, expected)
+
+def expect_nonzero(actual, name):
+    if actual == 0:
+        raise TestFailed, "test_%s: unexpected zero" % name
+
+def run_test(name, thunk):
+    if verbose:
+        print "testing %s..." % name,
+    thunk()
+    if verbose:
+        print "ok"
+
+def test_list():
+    l = []
+    l.append(l)
+    gc.collect()
+    del l
+    expect(gc.collect(), 1, "list")
+
+def test_dict():
+    d = {}
+    d[1] = d
+    gc.collect()
+    del d
+    expect(gc.collect(), 1, "dict")
+
+def test_tuple():
+    # since tuples are immutable we close the loop with a list
+    l = []
+    t = (l,)
+    l.append(t)
+    gc.collect()
+    del t
+    del l
+    expect(gc.collect(), 2, "tuple")
+
+def test_class():
+    class A:
+        pass
+    A.a = A
+    gc.collect()
+    del A
+    expect_nonzero(gc.collect(), "class")
+
+def test_newstyleclass():
+    class A(object):
+        pass
+    gc.collect()
+    del A
+    expect_nonzero(gc.collect(), "staticclass")
+
+def test_instance():
+    class A:
+        pass
+    a = A()
+    a.a = a
+    gc.collect()
+    del a
+    expect_nonzero(gc.collect(), "instance")
+
+def test_newinstance():
+    class A(object):
+        pass
+    a = A()
+    a.a = a
+    gc.collect()
+    del a
+    expect_nonzero(gc.collect(), "newinstance")
+    class B(list):
+        pass
+    class C(B, A):
+        pass
+    a = C()
+    a.a = a
+    gc.collect()
+    del a
+    expect_nonzero(gc.collect(), "newinstance(2)")
+    del B, C
+    expect_nonzero(gc.collect(), "newinstance(3)")
+    A.a = A()
+    del A
+    expect_nonzero(gc.collect(), "newinstance(4)")
+    expect(gc.collect(), 0, "newinstance(5)")
+
+def test_method():
+    # Tricky: self.__init__ is a bound method, it references the instance.
+    class A:
+        def __init__(self):
+            self.init = self.__init__
+    a = A()
+    gc.collect()
+    del a
+    expect_nonzero(gc.collect(), "method")
+
+def test_finalizer():
+    # A() is uncollectable if it is part of a cycle, make sure it shows up
+    # in gc.garbage.
+    class A:
+        def __del__(self): pass
+    class B:
+        pass
+    a = A()
+    a.a = a
+    id_a = id(a)
+    b = B()
+    b.b = b
+    gc.collect()
+    del a
+    del b
+    expect_nonzero(gc.collect(), "finalizer")
+    for obj in gc.garbage:
+        if id(obj) == id_a:
+            del obj.a
+            break
+    else:
+        raise TestFailed, "didn't find obj in garbage (finalizer)"
+    gc.garbage.remove(obj)
+
+def test_finalizer_newclass():
+    # A() is uncollectable if it is part of a cycle, make sure it shows up
+    # in gc.garbage.
+    class A(object):
+        def __del__(self): pass
+    class B(object):
+        pass
+    a = A()
+    a.a = a
+    id_a = id(a)
+    b = B()
+    b.b = b
+    gc.collect()
+    del a
+    del b
+    expect_nonzero(gc.collect(), "finalizer")
+    for obj in gc.garbage:
+        if id(obj) == id_a:
+            del obj.a
+            break
+    else:
+        raise TestFailed, "didn't find obj in garbage (finalizer)"
+    gc.garbage.remove(obj)
+
+def test_function():
+    # Tricky: f -> d -> f, code should call d.clear() after the exec to
+    # break the cycle.
+    d = {}
+    exec("def f(): pass\n") in d
+    gc.collect()
+    del d
+    expect(gc.collect(), 2, "function")
+
+def test_frame():
+    def f():
+        frame = sys._getframe()
+    gc.collect()
+    f()
+    expect(gc.collect(), 1, "frame")
+
+
+def test_saveall():
+    # Verify that cyclic garbage like lists show up in gc.garbage if the
+    # SAVEALL option is enabled.
+
+    # First make sure we don't save away other stuff that just happens to
+    # be waiting for collection.
+    gc.collect()
+    vereq(gc.garbage, []) # if this fails, someone else created immortal trash
+
+    L = []
+    L.append(L)
+    id_L = id(L)
+
+    debug = gc.get_debug()
+    gc.set_debug(debug | gc.DEBUG_SAVEALL)
+    del L
+    gc.collect()
+    gc.set_debug(debug)
+
+    vereq(len(gc.garbage), 1)
+    obj = gc.garbage.pop()
+    vereq(id(obj), id_L)
+
+def test_del():
+    # __del__ methods can trigger collection, make this to happen
+    thresholds = gc.get_threshold()
+    gc.enable()
+    gc.set_threshold(1)
+
+    class A:
+        def __del__(self):
+            dir(self)
+    a = A()
+    del a
+
+    gc.disable()
+    gc.set_threshold(*thresholds)
+
+def test_del_newclass():
+    # __del__ methods can trigger collection, make this to happen
+    thresholds = gc.get_threshold()
+    gc.enable()
+    gc.set_threshold(1)
+
+    class A(object):
+        def __del__(self):
+            dir(self)
+    a = A()
+    del a
+
+    gc.disable()
+    gc.set_threshold(*thresholds)
+
+def test_get_count():
+    gc.collect()
+    expect(gc.get_count(), (0, 0, 0), "get_count()")
+    a = dict()
+    expect(gc.get_count(), (1, 0, 0), "get_count()")
+
+def test_collect_generations():
+    gc.collect()
+    a = dict()
+    gc.collect(0)
+    expect(gc.get_count(), (0, 1, 0), "collect(0)")
+    gc.collect(1)
+    expect(gc.get_count(), (0, 0, 1), "collect(1)")
+    gc.collect(2)
+    expect(gc.get_count(), (0, 0, 0), "collect(1)")
+
+class Ouch:
+    n = 0
+    def __del__(self):
+        Ouch.n = Ouch.n + 1
+        if Ouch.n % 17 == 0:
+            gc.collect()
+
+def test_trashcan():
+    # "trashcan" is a hack to prevent stack overflow when deallocating
+    # very deeply nested tuples etc.  It works in part by abusing the
+    # type pointer and refcount fields, and that can yield horrible
+    # problems when gc tries to traverse the structures.
+    # If this test fails (as it does in 2.0, 2.1 and 2.2), it will
+    # most likely die via segfault.
+
+    # Note:  In 2.3 the possibility for compiling without cyclic gc was
+    # removed, and that in turn allows the trashcan mechanism to work
+    # via much simpler means (e.g., it never abuses the type pointer or
+    # refcount fields anymore).  Since it's much less likely to cause a
+    # problem now, the various constants in this expensive (we force a lot
+    # of full collections) test are cut back from the 2.2 version.
+    gc.enable()
+    N = 150
+    for count in range(2):
+        t = []
+        for i in range(N):
+            t = [t, Ouch()]
+        u = []
+        for i in range(N):
+            u = [u, Ouch()]
+        v = {}
+        for i in range(N):
+            v = {1: v, 2: Ouch()}
+    gc.disable()
+
+class Boom:
+    def __getattr__(self, someattribute):
+        del self.attr
+        raise AttributeError
+
+def test_boom():
+    a = Boom()
+    b = Boom()
+    a.attr = b
+    b.attr = a
+
+    gc.collect()
+    garbagelen = len(gc.garbage)
+    del a, b
+    # a<->b are in a trash cycle now.  Collection will invoke Boom.__getattr__
+    # (to see whether a and b have __del__ methods), and __getattr__ deletes
+    # the internal "attr" attributes as a side effect.  That causes the
+    # trash cycle to get reclaimed via refcounts falling to 0, thus mutating
+    # the trash graph as a side effect of merely asking whether __del__
+    # exists.  This used to (before 2.3b1) crash Python.  Now __getattr__
+    # isn't called.
+    expect(gc.collect(), 4, "boom")
+    expect(len(gc.garbage), garbagelen, "boom")
+
+class Boom2:
+    def __init__(self):
+        self.x = 0
+
+    def __getattr__(self, someattribute):
+        self.x += 1
+        if self.x > 1:
+            del self.attr
+        raise AttributeError
+
+def test_boom2():
+    a = Boom2()
+    b = Boom2()
+    a.attr = b
+    b.attr = a
+
+    gc.collect()
+    garbagelen = len(gc.garbage)
+    del a, b
+    # Much like test_boom(), except that __getattr__ doesn't break the
+    # cycle until the second time gc checks for __del__.  As of 2.3b1,
+    # there isn't a second time, so this simply cleans up the trash cycle.
+    # We expect a, b, a.__dict__ and b.__dict__ (4 objects) to get reclaimed
+    # this way.
+    expect(gc.collect(), 4, "boom2")
+    expect(len(gc.garbage), garbagelen, "boom2")
+
+# boom__new and boom2_new are exactly like boom and boom2, except use
+# new-style classes.
+
+class Boom_New(object):
+    def __getattr__(self, someattribute):
+        del self.attr
+        raise AttributeError
+
+def test_boom_new():
+    a = Boom_New()
+    b = Boom_New()
+    a.attr = b
+    b.attr = a
+
+    gc.collect()
+    garbagelen = len(gc.garbage)
+    del a, b
+    expect(gc.collect(), 4, "boom_new")
+    expect(len(gc.garbage), garbagelen, "boom_new")
+
+class Boom2_New(object):
+    def __init__(self):
+        self.x = 0
+
+    def __getattr__(self, someattribute):
+        self.x += 1
+        if self.x > 1:
+            del self.attr
+        raise AttributeError
+
+def test_boom2_new():
+    a = Boom2_New()
+    b = Boom2_New()
+    a.attr = b
+    b.attr = a
+
+    gc.collect()
+    garbagelen = len(gc.garbage)
+    del a, b
+    expect(gc.collect(), 4, "boom2_new")
+    expect(len(gc.garbage), garbagelen, "boom2_new")
+
+def test_get_referents():
+    alist = [1, 3, 5]
+    got = gc.get_referents(alist)
+    got.sort()
+    expect(got, alist, "get_referents")
+
+    atuple = tuple(alist)
+    got = gc.get_referents(atuple)
+    got.sort()
+    expect(got, alist, "get_referents")
+
+    adict = {1: 3, 5: 7}
+    expected = [1, 3, 5, 7]
+    got = gc.get_referents(adict)
+    got.sort()
+    expect(got, expected, "get_referents")
+
+    got = gc.get_referents([1, 2], {3: 4}, (0, 0, 0))
+    got.sort()
+    expect(got, [0, 0] + range(5), "get_referents")
+
+    expect(gc.get_referents(1, 'a', 4j), [], "get_referents")
+
+# Bug 1055820 has several tests of longstanding bugs involving weakrefs and
+# cyclic gc.
+
+# An instance of C1055820 has a self-loop, so becomes cyclic trash when
+# unreachable.
+class C1055820(object):
+    def __init__(self, i):
+        self.i = i
+        self.loop = self
+
+class GC_Detector(object):
+    # Create an instance I.  Then gc hasn't happened again so long as
+    # I.gc_happened is false.
+
+    def __init__(self):
+        self.gc_happened = False
+
+        def it_happened(ignored):
+            self.gc_happened = True
+
+        # Create a piece of cyclic trash that triggers it_happened when
+        # gc collects it.
+        self.wr = weakref.ref(C1055820(666), it_happened)
+
+def test_bug1055820b():
+    # Corresponds to temp2b.py in the bug report.
+
+    ouch = []
+    def callback(ignored):
+        ouch[:] = [wr() for wr in WRs]
+
+    Cs = [C1055820(i) for i in range(2)]
+    WRs = [weakref.ref(c, callback) for c in Cs]
+    c = None
+
+    gc.collect()
+    expect(len(ouch), 0, "bug1055820b")
+    # Make the two instances trash, and collect again.  The bug was that
+    # the callback materialized a strong reference to an instance, but gc
+    # cleared the instance's dict anyway.
+    Cs = None
+    gc.collect()
+    expect(len(ouch), 2, "bug1055820b")  # else the callbacks didn't run
+    for x in ouch:
+        # If the callback resurrected one of these guys, the instance
+        # would be damaged, with an empty __dict__.
+        expect(x, None, "bug1055820b")
+
+def test_bug1055820c():
+    # Corresponds to temp2c.py in the bug report.  This is pretty elaborate.
+
+    c0 = C1055820(0)
+    # Move c0 into generation 2.
+    gc.collect()
+
+    c1 = C1055820(1)
+    c1.keep_c0_alive = c0
+    del c0.loop # now only c1 keeps c0 alive
+
+    c2 = C1055820(2)
+    c2wr = weakref.ref(c2) # no callback!
+
+    ouch = []
+    def callback(ignored):
+        ouch[:] = [c2wr()]
+
+    # The callback gets associated with a wr on an object in generation 2.
+    c0wr = weakref.ref(c0, callback)
+
+    c0 = c1 = c2 = None
+
+    # What we've set up:  c0, c1, and c2 are all trash now.  c0 is in
+    # generation 2.  The only thing keeping it alive is that c1 points to it.
+    # c1 and c2 are in generation 0, and are in self-loops.  There's a global
+    # weakref to c2 (c2wr), but that weakref has no callback.  There's also
+    # a global weakref to c0 (c0wr), and that does have a callback, and that
+    # callback references c2 via c2wr().
+    #
+    #               c0 has a wr with callback, which references c2wr
+    #               ^
+    #               |
+    #               |     Generation 2 above dots
+    #. . . . . . . .|. . . . . . . . . . . . . . . . . . . . . . . .
+    #               |     Generation 0 below dots
+    #               |
+    #               |
+    #            ^->c1   ^->c2 has a wr but no callback
+    #            |  |    |  |
+    #            <--v    <--v
+    #
+    # So this is the nightmare:  when generation 0 gets collected, we see that
+    # c2 has a callback-free weakref, and c1 doesn't even have a weakref.
+    # Collecting generation 0 doesn't see c0 at all, and c0 is the only object
+    # that has a weakref with a callback.  gc clears c1 and c2.  Clearing c1
+    # has the side effect of dropping the refcount on c0 to 0, so c0 goes
+    # away (despite that it's in an older generation) and c0's wr callback
+    # triggers.  That in turn materializes a reference to c2 via c2wr(), but
+    # c2 gets cleared anyway by gc.
+
+    # We want to let gc happen "naturally", to preserve the distinction
+    # between generations.
+    junk = []
+    i = 0
+    detector = GC_Detector()
+    while not detector.gc_happened:
+        i += 1
+        if i > 10000:
+            raise TestFailed("gc didn't happen after 10000 iterations")
+        expect(len(ouch), 0, "bug1055820c")
+        junk.append([])  # this will eventually trigger gc
+
+    expect(len(ouch), 1, "bug1055820c")  # else the callback wasn't invoked
+    for x in ouch:
+        # If the callback resurrected c2, the instance would be damaged,
+        # with an empty __dict__.
+        expect(x, None, "bug1055820c")
+
+def test_bug1055820d():
+    # Corresponds to temp2d.py in the bug report.  This is very much like
+    # test_bug1055820c, but uses a __del__ method instead of a weakref
+    # callback to sneak in a resurrection of cyclic trash.
+
+    ouch = []
+    class D(C1055820):
+        def __del__(self):
+            ouch[:] = [c2wr()]
+
+    d0 = D(0)
+    # Move all the above into generation 2.
+    gc.collect()
+
+    c1 = C1055820(1)
+    c1.keep_d0_alive = d0
+    del d0.loop # now only c1 keeps d0 alive
+
+    c2 = C1055820(2)
+    c2wr = weakref.ref(c2) # no callback!
+
+    d0 = c1 = c2 = None
+
+    # What we've set up:  d0, c1, and c2 are all trash now.  d0 is in
+    # generation 2.  The only thing keeping it alive is that c1 points to it.
+    # c1 and c2 are in generation 0, and are in self-loops.  There's a global
+    # weakref to c2 (c2wr), but that weakref has no callback.  There are no
+    # other weakrefs.
+    #
+    #               d0 has a __del__ method that references c2wr
+    #               ^
+    #               |
+    #               |     Generation 2 above dots
+    #. . . . . . . .|. . . . . . . . . . . . . . . . . . . . . . . .
+    #               |     Generation 0 below dots
+    #               |
+    #               |
+    #            ^->c1   ^->c2 has a wr but no callback
+    #            |  |    |  |
+    #            <--v    <--v
+    #
+    # So this is the nightmare:  when generation 0 gets collected, we see that
+    # c2 has a callback-free weakref, and c1 doesn't even have a weakref.
+    # Collecting generation 0 doesn't see d0 at all.  gc clears c1 and c2.
+    # Clearing c1 has the side effect of dropping the refcount on d0 to 0, so
+    # d0 goes away (despite that it's in an older generation) and d0's __del__
+    # triggers.  That in turn materializes a reference to c2 via c2wr(), but
+    # c2 gets cleared anyway by gc.
+
+    # We want to let gc happen "naturally", to preserve the distinction
+    # between generations.
+    detector = GC_Detector()
+    junk = []
+    i = 0
+    while not detector.gc_happened:
+        i += 1
+        if i > 10000:
+            raise TestFailed("gc didn't happen after 10000 iterations")
+        expect(len(ouch), 0, "bug1055820d")
+        junk.append([])  # this will eventually trigger gc
+
+    expect(len(ouch), 1, "bug1055820d")  # else __del__ wasn't invoked
+    for x in ouch:
+        # If __del__ resurrected c2, the instance would be damaged, with an
+        # empty __dict__.
+        expect(x, None, "bug1055820d")
+
+
+def test_all():
+    gc.collect() # Delete 2nd generation garbage
+    run_test("lists", test_list)
+    run_test("dicts", test_dict)
+    run_test("tuples", test_tuple)
+    run_test("classes", test_class)
+    run_test("new style classes", test_newstyleclass)
+    run_test("instances", test_instance)
+    run_test("new instances", test_newinstance)
+    run_test("methods", test_method)
+    run_test("functions", test_function)
+    run_test("frames", test_frame)
+    run_test("finalizers", test_finalizer)
+    run_test("finalizers (new class)", test_finalizer_newclass)
+    run_test("__del__", test_del)
+    run_test("__del__ (new class)", test_del_newclass)
+    run_test("get_count()", test_get_count)
+    run_test("collect(n)", test_collect_generations)
+    run_test("saveall", test_saveall)
+    run_test("trashcan", test_trashcan)
+    run_test("boom", test_boom)
+    run_test("boom2", test_boom2)
+    run_test("boom_new", test_boom_new)
+    run_test("boom2_new", test_boom2_new)
+    run_test("get_referents", test_get_referents)
+    run_test("bug1055820b", test_bug1055820b)
+
+    gc.enable()
+    try:
+        run_test("bug1055820c", test_bug1055820c)
+    finally:
+        gc.disable()
+
+    gc.enable()
+    try:
+        run_test("bug1055820d", test_bug1055820d)
+    finally:
+        gc.disable()
+
+def test():
+    if verbose:
+        print "disabling automatic collection"
+    enabled = gc.isenabled()
+    gc.disable()
+    verify(not gc.isenabled())
+    debug = gc.get_debug()
+    gc.set_debug(debug & ~gc.DEBUG_LEAK) # this test is supposed to leak
+
+    try:
+        test_all()
+    finally:
+        gc.set_debug(debug)
+        # test gc.enable() even if GC is disabled by default
+        if verbose:
+            print "restoring automatic collection"
+        # make sure to always test gc.enable()
+        gc.enable()
+        verify(gc.isenabled())
+        if not enabled:
+            gc.disable()
+
+
+test()

Added: vendor/Python/current/Lib/test/test_gdbm.py
===================================================================
--- vendor/Python/current/Lib/test/test_gdbm.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_gdbm.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,46 @@
+#! /usr/bin/env python
+"""Test script for the gdbm module
+   Roger E. Masse
+"""
+
+import gdbm
+from gdbm import error
+from test.test_support import verbose, verify, TestFailed, TESTFN
+
+filename = TESTFN
+
+g = gdbm.open(filename, 'c')
+verify(g.keys() == [])
+g['a'] = 'b'
+g['12345678910'] = '019237410982340912840198242'
+a = g.keys()
+if verbose:
+    print 'Test gdbm file keys: ', a
+
+g.has_key('a')
+g.close()
+try:
+    g['a']
+except error:
+    pass
+else:
+    raise TestFailed, "expected gdbm.error accessing closed database"
+g = gdbm.open(filename, 'r')
+g.close()
+g = gdbm.open(filename, 'w')
+g.close()
+g = gdbm.open(filename, 'n')
+g.close()
+try:
+    g = gdbm.open(filename, 'rx')
+    g.close()
+except error:
+    pass
+else:
+    raise TestFailed, "expected gdbm.error when passing invalid open flags"
+
+try:
+    import os
+    os.unlink(filename)
+except:
+    pass


Property changes on: vendor/Python/current/Lib/test/test_gdbm.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/test/test_generators.py
===================================================================
--- vendor/Python/current/Lib/test/test_generators.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_generators.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1839 @@
+tutorial_tests = """
+Let's try a simple generator:
+
+    >>> def f():
+    ...    yield 1
+    ...    yield 2
+
+    >>> for i in f():
+    ...     print i
+    1
+    2
+    >>> g = f()
+    >>> g.next()
+    1
+    >>> g.next()
+    2
+
+"Falling off the end" stops the generator:
+
+    >>> g.next()
+    Traceback (most recent call last):
+      File "<stdin>", line 1, in ?
+      File "<stdin>", line 2, in g
+    StopIteration
+
+"return" also stops the generator:
+
+    >>> def f():
+    ...     yield 1
+    ...     return
+    ...     yield 2 # never reached
+    ...
+    >>> g = f()
+    >>> g.next()
+    1
+    >>> g.next()
+    Traceback (most recent call last):
+      File "<stdin>", line 1, in ?
+      File "<stdin>", line 3, in f
+    StopIteration
+    >>> g.next() # once stopped, can't be resumed
+    Traceback (most recent call last):
+      File "<stdin>", line 1, in ?
+    StopIteration
+
+"raise StopIteration" stops the generator too:
+
+    >>> def f():
+    ...     yield 1
+    ...     raise StopIteration
+    ...     yield 2 # never reached
+    ...
+    >>> g = f()
+    >>> g.next()
+    1
+    >>> g.next()
+    Traceback (most recent call last):
+      File "<stdin>", line 1, in ?
+    StopIteration
+    >>> g.next()
+    Traceback (most recent call last):
+      File "<stdin>", line 1, in ?
+    StopIteration
+
+However, they are not exactly equivalent:
+
+    >>> def g1():
+    ...     try:
+    ...         return
+    ...     except:
+    ...         yield 1
+    ...
+    >>> list(g1())
+    []
+
+    >>> def g2():
+    ...     try:
+    ...         raise StopIteration
+    ...     except:
+    ...         yield 42
+    >>> print list(g2())
+    [42]
+
+This may be surprising at first:
+
+    >>> def g3():
+    ...     try:
+    ...         return
+    ...     finally:
+    ...         yield 1
+    ...
+    >>> list(g3())
+    [1]
+
+Let's create an alternate range() function implemented as a generator:
+
+    >>> def yrange(n):
+    ...     for i in range(n):
+    ...         yield i
+    ...
+    >>> list(yrange(5))
+    [0, 1, 2, 3, 4]
+
+Generators always return to the most recent caller:
+
+    >>> def creator():
+    ...     r = yrange(5)
+    ...     print "creator", r.next()
+    ...     return r
+    ...
+    >>> def caller():
+    ...     r = creator()
+    ...     for i in r:
+    ...             print "caller", i
+    ...
+    >>> caller()
+    creator 0
+    caller 1
+    caller 2
+    caller 3
+    caller 4
+
+Generators can call other generators:
+
+    >>> def zrange(n):
+    ...     for i in yrange(n):
+    ...         yield i
+    ...
+    >>> list(zrange(5))
+    [0, 1, 2, 3, 4]
+
+"""
+
+# The examples from PEP 255.
+
+pep_tests = """
+
+Specification:  Yield
+
+    Restriction:  A generator cannot be resumed while it is actively
+    running:
+
+    >>> def g():
+    ...     i = me.next()
+    ...     yield i
+    >>> me = g()
+    >>> me.next()
+    Traceback (most recent call last):
+     ...
+      File "<string>", line 2, in g
+    ValueError: generator already executing
+
+Specification: Return
+
+    Note that return isn't always equivalent to raising StopIteration:  the
+    difference lies in how enclosing try/except constructs are treated.
+    For example,
+
+        >>> def f1():
+        ...     try:
+        ...         return
+        ...     except:
+        ...        yield 1
+        >>> print list(f1())
+        []
+
+    because, as in any function, return simply exits, but
+
+        >>> def f2():
+        ...     try:
+        ...         raise StopIteration
+        ...     except:
+        ...         yield 42
+        >>> print list(f2())
+        [42]
+
+    because StopIteration is captured by a bare "except", as is any
+    exception.
+
+Specification: Generators and Exception Propagation
+
+    >>> def f():
+    ...     return 1//0
+    >>> def g():
+    ...     yield f()  # the zero division exception propagates
+    ...     yield 42   # and we'll never get here
+    >>> k = g()
+    >>> k.next()
+    Traceback (most recent call last):
+      File "<stdin>", line 1, in ?
+      File "<stdin>", line 2, in g
+      File "<stdin>", line 2, in f
+    ZeroDivisionError: integer division or modulo by zero
+    >>> k.next()  # and the generator cannot be resumed
+    Traceback (most recent call last):
+      File "<stdin>", line 1, in ?
+    StopIteration
+    >>>
+
+Specification: Try/Except/Finally
+
+    >>> def f():
+    ...     try:
+    ...         yield 1
+    ...         try:
+    ...             yield 2
+    ...             1//0
+    ...             yield 3  # never get here
+    ...         except ZeroDivisionError:
+    ...             yield 4
+    ...             yield 5
+    ...             raise
+    ...         except:
+    ...             yield 6
+    ...         yield 7     # the "raise" above stops this
+    ...     except:
+    ...         yield 8
+    ...     yield 9
+    ...     try:
+    ...         x = 12
+    ...     finally:
+    ...         yield 10
+    ...     yield 11
+    >>> print list(f())
+    [1, 2, 4, 5, 8, 9, 10, 11]
+    >>>
+
+Guido's binary tree example.
+
+    >>> # A binary tree class.
+    >>> class Tree:
+    ...
+    ...     def __init__(self, label, left=None, right=None):
+    ...         self.label = label
+    ...         self.left = left
+    ...         self.right = right
+    ...
+    ...     def __repr__(self, level=0, indent="    "):
+    ...         s = level*indent + repr(self.label)
+    ...         if self.left:
+    ...             s = s + "\\n" + self.left.__repr__(level+1, indent)
+    ...         if self.right:
+    ...             s = s + "\\n" + self.right.__repr__(level+1, indent)
+    ...         return s
+    ...
+    ...     def __iter__(self):
+    ...         return inorder(self)
+
+    >>> # Create a Tree from a list.
+    >>> def tree(list):
+    ...     n = len(list)
+    ...     if n == 0:
+    ...         return []
+    ...     i = n // 2
+    ...     return Tree(list[i], tree(list[:i]), tree(list[i+1:]))
+
+    >>> # Show it off: create a tree.
+    >>> t = tree("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
+
+    >>> # A recursive generator that generates Tree labels in in-order.
+    >>> def inorder(t):
+    ...     if t:
+    ...         for x in inorder(t.left):
+    ...             yield x
+    ...         yield t.label
+    ...         for x in inorder(t.right):
+    ...             yield x
+
+    >>> # Show it off: create a tree.
+    >>> t = tree("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
+    >>> # Print the nodes of the tree in in-order.
+    >>> for x in t:
+    ...     print x,
+    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
+
+    >>> # A non-recursive generator.
+    >>> def inorder(node):
+    ...     stack = []
+    ...     while node:
+    ...         while node.left:
+    ...             stack.append(node)
+    ...             node = node.left
+    ...         yield node.label
+    ...         while not node.right:
+    ...             try:
+    ...                 node = stack.pop()
+    ...             except IndexError:
+    ...                 return
+    ...             yield node.label
+    ...         node = node.right
+
+    >>> # Exercise the non-recursive generator.
+    >>> for x in t:
+    ...     print x,
+    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
+
+"""
+
+# Examples from Iterator-List and Python-Dev and c.l.py.
+
+email_tests = """
+
+The difference between yielding None and returning it.
+
+>>> def g():
+...     for i in range(3):
+...         yield None
+...     yield None
+...     return
+>>> list(g())
+[None, None, None, None]
+
+Ensure that explicitly raising StopIteration acts like any other exception
+in try/except, not like a return.
+
+>>> def g():
+...     yield 1
+...     try:
+...         raise StopIteration
+...     except:
+...         yield 2
+...     yield 3
+>>> list(g())
+[1, 2, 3]
+
+Next one was posted to c.l.py.
+
+>>> def gcomb(x, k):
+...     "Generate all combinations of k elements from list x."
+...
+...     if k > len(x):
+...         return
+...     if k == 0:
+...         yield []
+...     else:
+...         first, rest = x[0], x[1:]
+...         # A combination does or doesn't contain first.
+...         # If it does, the remainder is a k-1 comb of rest.
+...         for c in gcomb(rest, k-1):
+...             c.insert(0, first)
+...             yield c
+...         # If it doesn't contain first, it's a k comb of rest.
+...         for c in gcomb(rest, k):
+...             yield c
+
+>>> seq = range(1, 5)
+>>> for k in range(len(seq) + 2):
+...     print "%d-combs of %s:" % (k, seq)
+...     for c in gcomb(seq, k):
+...         print "   ", c
+0-combs of [1, 2, 3, 4]:
+    []
+1-combs of [1, 2, 3, 4]:
+    [1]
+    [2]
+    [3]
+    [4]
+2-combs of [1, 2, 3, 4]:
+    [1, 2]
+    [1, 3]
+    [1, 4]
+    [2, 3]
+    [2, 4]
+    [3, 4]
+3-combs of [1, 2, 3, 4]:
+    [1, 2, 3]
+    [1, 2, 4]
+    [1, 3, 4]
+    [2, 3, 4]
+4-combs of [1, 2, 3, 4]:
+    [1, 2, 3, 4]
+5-combs of [1, 2, 3, 4]:
+
+From the Iterators list, about the types of these things.
+
+>>> def g():
+...     yield 1
+...
+>>> type(g)
+<type 'function'>
+>>> i = g()
+>>> type(i)
+<type 'generator'>
+>>> [s for s in dir(i) if not s.startswith('_')]
+['close', 'gi_frame', 'gi_running', 'next', 'send', 'throw']
+>>> print i.next.__doc__
+x.next() -> the next value, or raise StopIteration
+>>> iter(i) is i
+True
+>>> import types
+>>> isinstance(i, types.GeneratorType)
+True
+
+And more, added later.
+
+>>> i.gi_running
+0
+>>> type(i.gi_frame)
+<type 'frame'>
+>>> i.gi_running = 42
+Traceback (most recent call last):
+  ...
+TypeError: readonly attribute
+>>> def g():
+...     yield me.gi_running
+>>> me = g()
+>>> me.gi_running
+0
+>>> me.next()
+1
+>>> me.gi_running
+0
+
+A clever union-find implementation from c.l.py, due to David Eppstein.
+Sent: Friday, June 29, 2001 12:16 PM
+To: python-list at python.org
+Subject: Re: PEP 255: Simple Generators
+
+>>> class disjointSet:
+...     def __init__(self, name):
+...         self.name = name
+...         self.parent = None
+...         self.generator = self.generate()
+...
+...     def generate(self):
+...         while not self.parent:
+...             yield self
+...         for x in self.parent.generator:
+...             yield x
+...
+...     def find(self):
+...         return self.generator.next()
+...
+...     def union(self, parent):
+...         if self.parent:
+...             raise ValueError("Sorry, I'm not a root!")
+...         self.parent = parent
+...
+...     def __str__(self):
+...         return self.name
+
+>>> names = "ABCDEFGHIJKLM"
+>>> sets = [disjointSet(name) for name in names]
+>>> roots = sets[:]
+
+>>> import random
+>>> gen = random.WichmannHill(42)
+>>> while 1:
+...     for s in sets:
+...         print "%s->%s" % (s, s.find()),
+...     print
+...     if len(roots) > 1:
+...         s1 = gen.choice(roots)
+...         roots.remove(s1)
+...         s2 = gen.choice(roots)
+...         s1.union(s2)
+...         print "merged", s1, "into", s2
+...     else:
+...         break
+A->A B->B C->C D->D E->E F->F G->G H->H I->I J->J K->K L->L M->M
+merged D into G
+A->A B->B C->C D->G E->E F->F G->G H->H I->I J->J K->K L->L M->M
+merged C into F
+A->A B->B C->F D->G E->E F->F G->G H->H I->I J->J K->K L->L M->M
+merged L into A
+A->A B->B C->F D->G E->E F->F G->G H->H I->I J->J K->K L->A M->M
+merged H into E
+A->A B->B C->F D->G E->E F->F G->G H->E I->I J->J K->K L->A M->M
+merged B into E
+A->A B->E C->F D->G E->E F->F G->G H->E I->I J->J K->K L->A M->M
+merged J into G
+A->A B->E C->F D->G E->E F->F G->G H->E I->I J->G K->K L->A M->M
+merged E into G
+A->A B->G C->F D->G E->G F->F G->G H->G I->I J->G K->K L->A M->M
+merged M into G
+A->A B->G C->F D->G E->G F->F G->G H->G I->I J->G K->K L->A M->G
+merged I into K
+A->A B->G C->F D->G E->G F->F G->G H->G I->K J->G K->K L->A M->G
+merged K into A
+A->A B->G C->F D->G E->G F->F G->G H->G I->A J->G K->A L->A M->G
+merged F into A
+A->A B->G C->A D->G E->G F->A G->G H->G I->A J->G K->A L->A M->G
+merged A into G
+A->G B->G C->G D->G E->G F->G G->G H->G I->G J->G K->G L->G M->G
+
+"""
+# Emacs turd '
+
+# Fun tests (for sufficiently warped notions of "fun").
+
+fun_tests = """
+
+Build up to a recursive Sieve of Eratosthenes generator.
+
+>>> def firstn(g, n):
+...     return [g.next() for i in range(n)]
+
+>>> def intsfrom(i):
+...     while 1:
+...         yield i
+...         i += 1
+
+>>> firstn(intsfrom(5), 7)
+[5, 6, 7, 8, 9, 10, 11]
+
+>>> def exclude_multiples(n, ints):
+...     for i in ints:
+...         if i % n:
+...             yield i
+
+>>> firstn(exclude_multiples(3, intsfrom(1)), 6)
+[1, 2, 4, 5, 7, 8]
+
+>>> def sieve(ints):
+...     prime = ints.next()
+...     yield prime
+...     not_divisible_by_prime = exclude_multiples(prime, ints)
+...     for p in sieve(not_divisible_by_prime):
+...         yield p
+
+>>> primes = sieve(intsfrom(2))
+>>> firstn(primes, 20)
+[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71]
+
+
+Another famous problem:  generate all integers of the form
+    2**i * 3**j  * 5**k
+in increasing order, where i,j,k >= 0.  Trickier than it may look at first!
+Try writing it without generators, and correctly, and without generating
+3 internal results for each result output.
+
+>>> def times(n, g):
+...     for i in g:
+...         yield n * i
+>>> firstn(times(10, intsfrom(1)), 10)
+[10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
+
+>>> def merge(g, h):
+...     ng = g.next()
+...     nh = h.next()
+...     while 1:
+...         if ng < nh:
+...             yield ng
+...             ng = g.next()
+...         elif ng > nh:
+...             yield nh
+...             nh = h.next()
+...         else:
+...             yield ng
+...             ng = g.next()
+...             nh = h.next()
+
+The following works, but is doing a whale of a lot of redundant work --
+it's not clear how to get the internal uses of m235 to share a single
+generator.  Note that me_times2 (etc) each need to see every element in the
+result sequence.  So this is an example where lazy lists are more natural
+(you can look at the head of a lazy list any number of times).
+
+>>> def m235():
+...     yield 1
+...     me_times2 = times(2, m235())
+...     me_times3 = times(3, m235())
+...     me_times5 = times(5, m235())
+...     for i in merge(merge(me_times2,
+...                          me_times3),
+...                    me_times5):
+...         yield i
+
+Don't print "too many" of these -- the implementation above is extremely
+inefficient:  each call of m235() leads to 3 recursive calls, and in
+turn each of those 3 more, and so on, and so on, until we've descended
+enough levels to satisfy the print stmts.  Very odd:  when I printed 5
+lines of results below, this managed to screw up Win98's malloc in "the
+usual" way, i.e. the heap grew over 4Mb so Win98 started fragmenting
+address space, and it *looked* like a very slow leak.
+
+>>> result = m235()
+>>> for i in range(3):
+...     print firstn(result, 15)
+[1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24]
+[25, 27, 30, 32, 36, 40, 45, 48, 50, 54, 60, 64, 72, 75, 80]
+[81, 90, 96, 100, 108, 120, 125, 128, 135, 144, 150, 160, 162, 180, 192]
+
+Heh.  Here's one way to get a shared list, complete with an excruciating
+namespace renaming trick.  The *pretty* part is that the times() and merge()
+functions can be reused as-is, because they only assume their stream
+arguments are iterable -- a LazyList is the same as a generator to times().
+
+>>> class LazyList:
+...     def __init__(self, g):
+...         self.sofar = []
+...         self.fetch = g.next
+...
+...     def __getitem__(self, i):
+...         sofar, fetch = self.sofar, self.fetch
+...         while i >= len(sofar):
+...             sofar.append(fetch())
+...         return sofar[i]
+
+>>> def m235():
+...     yield 1
+...     # Gack:  m235 below actually refers to a LazyList.
+...     me_times2 = times(2, m235)
+...     me_times3 = times(3, m235)
+...     me_times5 = times(5, m235)
+...     for i in merge(merge(me_times2,
+...                          me_times3),
+...                    me_times5):
+...         yield i
+
+Print as many of these as you like -- *this* implementation is memory-
+efficient.
+
+>>> m235 = LazyList(m235())
+>>> for i in range(5):
+...     print [m235[j] for j in range(15*i, 15*(i+1))]
+[1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24]
+[25, 27, 30, 32, 36, 40, 45, 48, 50, 54, 60, 64, 72, 75, 80]
+[81, 90, 96, 100, 108, 120, 125, 128, 135, 144, 150, 160, 162, 180, 192]
+[200, 216, 225, 240, 243, 250, 256, 270, 288, 300, 320, 324, 360, 375, 384]
+[400, 405, 432, 450, 480, 486, 500, 512, 540, 576, 600, 625, 640, 648, 675]
+
+Ye olde Fibonacci generator, LazyList style.
+
+>>> def fibgen(a, b):
+...
+...     def sum(g, h):
+...         while 1:
+...             yield g.next() + h.next()
+...
+...     def tail(g):
+...         g.next()    # throw first away
+...         for x in g:
+...             yield x
+...
+...     yield a
+...     yield b
+...     for s in sum(iter(fib),
+...                  tail(iter(fib))):
+...         yield s
+
+>>> fib = LazyList(fibgen(1, 2))
+>>> firstn(iter(fib), 17)
+[1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584]
+
+
+Running after your tail with itertools.tee (new in version 2.4)
+
+The algorithms "m235" (Hamming) and Fibonacci presented above are both
+examples of a whole family of FP (functional programming) algorithms
+where a function produces and returns a list while the production algorithm
+suppose the list as already produced by recursively calling itself.
+For these algorithms to work, they must:
+
+- produce at least a first element without presupposing the existence of
+  the rest of the list
+- produce their elements in a lazy manner
+
+To work efficiently, the beginning of the list must not be recomputed over
+and over again. This is ensured in most FP languages as a built-in feature.
+In python, we have to explicitly maintain a list of already computed results
+and abandon genuine recursivity.
+
+This is what had been attempted above with the LazyList class. One problem
+with that class is that it keeps a list of all of the generated results and
+therefore continually grows. This partially defeats the goal of the generator
+concept, viz. produce the results only as needed instead of producing them
+all and thereby wasting memory.
+
+Thanks to itertools.tee, it is now clear "how to get the internal uses of
+m235 to share a single generator".
+
+>>> from itertools import tee
+>>> def m235():
+...     def _m235():
+...         yield 1
+...         for n in merge(times(2, m2),
+...                        merge(times(3, m3),
+...                              times(5, m5))):
+...             yield n
+...     m1 = _m235()
+...     m2, m3, m5, mRes = tee(m1, 4)
+...     return mRes
+
+>>> it = m235()
+>>> for i in range(5):
+...     print firstn(it, 15)
+[1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24]
+[25, 27, 30, 32, 36, 40, 45, 48, 50, 54, 60, 64, 72, 75, 80]
+[81, 90, 96, 100, 108, 120, 125, 128, 135, 144, 150, 160, 162, 180, 192]
+[200, 216, 225, 240, 243, 250, 256, 270, 288, 300, 320, 324, 360, 375, 384]
+[400, 405, 432, 450, 480, 486, 500, 512, 540, 576, 600, 625, 640, 648, 675]
+
+The "tee" function does just what we want. It internally keeps a generated
+result for as long as it has not been "consumed" from all of the duplicated
+iterators, whereupon it is deleted. You can therefore print the hamming
+sequence during hours without increasing memory usage, or very little.
+
+The beauty of it is that recursive running-after-their-tail FP algorithms
+are quite straightforwardly expressed with this Python idiom.
+
+Ye olde Fibonacci generator, tee style.
+
+>>> def fib():
+...
+...     def _isum(g, h):
+...         while 1:
+...             yield g.next() + h.next()
+...
+...     def _fib():
+...         yield 1
+...         yield 2
+...         fibTail.next() # throw first away
+...         for res in _isum(fibHead, fibTail):
+...             yield res
+...
+...     realfib = _fib()
+...     fibHead, fibTail, fibRes = tee(realfib, 3)
+...     return fibRes
+
+>>> firstn(fib(), 17)
+[1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584]
+
+"""
+
+# syntax_tests mostly provokes SyntaxErrors.  Also fiddling with #if 0
+# hackery.
+
+syntax_tests = """
+
+>>> def f():
+...     return 22
+...     yield 1
+Traceback (most recent call last):
+  ..
+SyntaxError: 'return' with argument inside generator (<doctest test.test_generators.__test__.syntax[0]>, line 3)
+
+>>> def f():
+...     yield 1
+...     return 22
+Traceback (most recent call last):
+  ..
+SyntaxError: 'return' with argument inside generator (<doctest test.test_generators.__test__.syntax[1]>, line 3)
+
+"return None" is not the same as "return" in a generator:
+
+>>> def f():
+...     yield 1
+...     return None
+Traceback (most recent call last):
+  ..
+SyntaxError: 'return' with argument inside generator (<doctest test.test_generators.__test__.syntax[2]>, line 3)
+
+These are fine:
+
+>>> def f():
+...     yield 1
+...     return
+
+>>> def f():
+...     try:
+...         yield 1
+...     finally:
+...         pass
+
+>>> def f():
+...     try:
+...         try:
+...             1//0
+...         except ZeroDivisionError:
+...             yield 666
+...         except:
+...             pass
+...     finally:
+...         pass
+
+>>> def f():
+...     try:
+...         try:
+...             yield 12
+...             1//0
+...         except ZeroDivisionError:
+...             yield 666
+...         except:
+...             try:
+...                 x = 12
+...             finally:
+...                 yield 12
+...     except:
+...         return
+>>> list(f())
+[12, 666]
+
+>>> def f():
+...    yield
+>>> type(f())
+<type 'generator'>
+
+
+>>> def f():
+...    if 0:
+...        yield
+>>> type(f())
+<type 'generator'>
+
+
+>>> def f():
+...     if 0:
+...         yield 1
+>>> type(f())
+<type 'generator'>
+
+>>> def f():
+...    if "":
+...        yield None
+>>> type(f())
+<type 'generator'>
+
+>>> def f():
+...     return
+...     try:
+...         if x==4:
+...             pass
+...         elif 0:
+...             try:
+...                 1//0
+...             except SyntaxError:
+...                 pass
+...             else:
+...                 if 0:
+...                     while 12:
+...                         x += 1
+...                         yield 2 # don't blink
+...                         f(a, b, c, d, e)
+...         else:
+...             pass
+...     except:
+...         x = 1
+...     return
+>>> type(f())
+<type 'generator'>
+
+>>> def f():
+...     if 0:
+...         def g():
+...             yield 1
+...
+>>> type(f())
+<type 'NoneType'>
+
+>>> def f():
+...     if 0:
+...         class C:
+...             def __init__(self):
+...                 yield 1
+...             def f(self):
+...                 yield 2
+>>> type(f())
+<type 'NoneType'>
+
+>>> def f():
+...     if 0:
+...         return
+...     if 0:
+...         yield 2
+>>> type(f())
+<type 'generator'>
+
+
+>>> def f():
+...     if 0:
+...         lambda x:  x        # shouldn't trigger here
+...         return              # or here
+...         def f(i):
+...             return 2*i      # or here
+...         if 0:
+...             return 3        # but *this* sucks (line 8)
+...     if 0:
+...         yield 2             # because it's a generator (line 10)
+Traceback (most recent call last):
+SyntaxError: 'return' with argument inside generator (<doctest test.test_generators.__test__.syntax[24]>, line 10)
+
+This one caused a crash (see SF bug 567538):
+
+>>> def f():
+...     for i in range(3):
+...         try:
+...             continue
+...         finally:
+...             yield i
+...
+>>> g = f()
+>>> print g.next()
+0
+>>> print g.next()
+1
+>>> print g.next()
+2
+>>> print g.next()
+Traceback (most recent call last):
+StopIteration
+"""
+
+# conjoin is a simple backtracking generator, named in honor of Icon's
+# "conjunction" control structure.  Pass a list of no-argument functions
+# that return iterable objects.  Easiest to explain by example:  assume the
+# function list [x, y, z] is passed.  Then conjoin acts like:
+#
+# def g():
+#     values = [None] * 3
+#     for values[0] in x():
+#         for values[1] in y():
+#             for values[2] in z():
+#                 yield values
+#
+# So some 3-lists of values *may* be generated, each time we successfully
+# get into the innermost loop.  If an iterator fails (is exhausted) before
+# then, it "backtracks" to get the next value from the nearest enclosing
+# iterator (the one "to the left"), and starts all over again at the next
+# slot (pumps a fresh iterator).  Of course this is most useful when the
+# iterators have side-effects, so that which values *can* be generated at
+# each slot depend on the values iterated at previous slots.
+
+def conjoin(gs):
+
+    values = [None] * len(gs)
+
+    def gen(i, values=values):
+        if i >= len(gs):
+            yield values
+        else:
+            for values[i] in gs[i]():
+                for x in gen(i+1):
+                    yield x
+
+    for x in gen(0):
+        yield x
+
+# That works fine, but recursing a level and checking i against len(gs) for
+# each item produced is inefficient.  By doing manual loop unrolling across
+# generator boundaries, it's possible to eliminate most of that overhead.
+# This isn't worth the bother *in general* for generators, but conjoin() is
+# a core building block for some CPU-intensive generator applications.
+
+def conjoin(gs):
+
+    n = len(gs)
+    values = [None] * n
+
+    # Do one loop nest at time recursively, until the # of loop nests
+    # remaining is divisible by 3.
+
+    def gen(i, values=values):
+        if i >= n:
+            yield values
+
+        elif (n-i) % 3:
+            ip1 = i+1
+            for values[i] in gs[i]():
+                for x in gen(ip1):
+                    yield x
+
+        else:
+            for x in _gen3(i):
+                yield x
+
+    # Do three loop nests at a time, recursing only if at least three more
+    # remain.  Don't call directly:  this is an internal optimization for
+    # gen's use.
+
+    def _gen3(i, values=values):
+        assert i < n and (n-i) % 3 == 0
+        ip1, ip2, ip3 = i+1, i+2, i+3
+        g, g1, g2 = gs[i : ip3]
+
+        if ip3 >= n:
+            # These are the last three, so we can yield values directly.
+            for values[i] in g():
+                for values[ip1] in g1():
+                    for values[ip2] in g2():
+                        yield values
+
+        else:
+            # At least 6 loop nests remain; peel off 3 and recurse for the
+            # rest.
+            for values[i] in g():
+                for values[ip1] in g1():
+                    for values[ip2] in g2():
+                        for x in _gen3(ip3):
+                            yield x
+
+    for x in gen(0):
+        yield x
+
+# And one more approach:  For backtracking apps like the Knight's Tour
+# solver below, the number of backtracking levels can be enormous (one
+# level per square, for the Knight's Tour, so that e.g. a 100x100 board
+# needs 10,000 levels).  In such cases Python is likely to run out of
+# stack space due to recursion.  So here's a recursion-free version of
+# conjoin too.
+# NOTE WELL:  This allows large problems to be solved with only trivial
+# demands on stack space.  Without explicitly resumable generators, this is
+# much harder to achieve.  OTOH, this is much slower (up to a factor of 2)
+# than the fancy unrolled recursive conjoin.
+
+def flat_conjoin(gs):  # rename to conjoin to run tests with this instead
+    n = len(gs)
+    values = [None] * n
+    iters  = [None] * n
+    _StopIteration = StopIteration  # make local because caught a *lot*
+    i = 0
+    while 1:
+        # Descend.
+        try:
+            while i < n:
+                it = iters[i] = gs[i]().next
+                values[i] = it()
+                i += 1
+        except _StopIteration:
+            pass
+        else:
+            assert i == n
+            yield values
+
+        # Backtrack until an older iterator can be resumed.
+        i -= 1
+        while i >= 0:
+            try:
+                values[i] = iters[i]()
+                # Success!  Start fresh at next level.
+                i += 1
+                break
+            except _StopIteration:
+                # Continue backtracking.
+                i -= 1
+        else:
+            assert i < 0
+            break
+
+# A conjoin-based N-Queens solver.
+
+class Queens:
+    def __init__(self, n):
+        self.n = n
+        rangen = range(n)
+
+        # Assign a unique int to each column and diagonal.
+        # columns:  n of those, range(n).
+        # NW-SE diagonals: 2n-1 of these, i-j unique and invariant along
+        # each, smallest i-j is 0-(n-1) = 1-n, so add n-1 to shift to 0-
+        # based.
+        # NE-SW diagonals: 2n-1 of these, i+j unique and invariant along
+        # each, smallest i+j is 0, largest is 2n-2.
+
+        # For each square, compute a bit vector of the columns and
+        # diagonals it covers, and for each row compute a function that
+        # generates the possiblities for the columns in that row.
+        self.rowgenerators = []
+        for i in rangen:
+            rowuses = [(1L << j) |                  # column ordinal
+                       (1L << (n + i-j + n-1)) |    # NW-SE ordinal
+                       (1L << (n + 2*n-1 + i+j))    # NE-SW ordinal
+                            for j in rangen]
+
+            def rowgen(rowuses=rowuses):
+                for j in rangen:
+                    uses = rowuses[j]
+                    if uses & self.used == 0:
+                        self.used |= uses
+                        yield j
+                        self.used &= ~uses
+
+            self.rowgenerators.append(rowgen)
+
+    # Generate solutions.
+    def solve(self):
+        self.used = 0
+        for row2col in conjoin(self.rowgenerators):
+            yield row2col
+
+    def printsolution(self, row2col):
+        n = self.n
+        assert n == len(row2col)
+        sep = "+" + "-+" * n
+        print sep
+        for i in range(n):
+            squares = [" " for j in range(n)]
+            squares[row2col[i]] = "Q"
+            print "|" + "|".join(squares) + "|"
+            print sep
+
+# A conjoin-based Knight's Tour solver.  This is pretty sophisticated
+# (e.g., when used with flat_conjoin above, and passing hard=1 to the
+# constructor, a 200x200 Knight's Tour was found quickly -- note that we're
+# creating 10s of thousands of generators then!), and is lengthy.
+
+class Knights:
+    def __init__(self, m, n, hard=0):
+        self.m, self.n = m, n
+
+        # solve() will set up succs[i] to be a list of square #i's
+        # successors.
+        succs = self.succs = []
+
+        # Remove i0 from each of its successor's successor lists, i.e.
+        # successors can't go back to i0 again.  Return 0 if we can
+        # detect this makes a solution impossible, else return 1.
+
+        def remove_from_successors(i0, len=len):
+            # If we remove all exits from a free square, we're dead:
+            # even if we move to it next, we can't leave it again.
+            # If we create a square with one exit, we must visit it next;
+            # else somebody else will have to visit it, and since there's
+            # only one adjacent, there won't be a way to leave it again.
+            # Finelly, if we create more than one free square with a
+            # single exit, we can only move to one of them next, leaving
+            # the other one a dead end.
+            ne0 = ne1 = 0
+            for i in succs[i0]:
+                s = succs[i]
+                s.remove(i0)
+                e = len(s)
+                if e == 0:
+                    ne0 += 1
+                elif e == 1:
+                    ne1 += 1
+            return ne0 == 0 and ne1 < 2
+
+        # Put i0 back in each of its successor's successor lists.
+
+        def add_to_successors(i0):
+            for i in succs[i0]:
+                succs[i].append(i0)
+
+        # Generate the first move.
+        def first():
+            if m < 1 or n < 1:
+                return
+
+            # Since we're looking for a cycle, it doesn't matter where we
+            # start.  Starting in a corner makes the 2nd move easy.
+            corner = self.coords2index(0, 0)
+            remove_from_successors(corner)
+            self.lastij = corner
+            yield corner
+            add_to_successors(corner)
+
+        # Generate the second moves.
+        def second():
+            corner = self.coords2index(0, 0)
+            assert self.lastij == corner  # i.e., we started in the corner
+            if m < 3 or n < 3:
+                return
+            assert len(succs[corner]) == 2
+            assert self.coords2index(1, 2) in succs[corner]
+            assert self.coords2index(2, 1) in succs[corner]
+            # Only two choices.  Whichever we pick, the other must be the
+            # square picked on move m*n, as it's the only way to get back
+            # to (0, 0).  Save its index in self.final so that moves before
+            # the last know it must be kept free.
+            for i, j in (1, 2), (2, 1):
+                this  = self.coords2index(i, j)
+                final = self.coords2index(3-i, 3-j)
+                self.final = final
+
+                remove_from_successors(this)
+                succs[final].append(corner)
+                self.lastij = this
+                yield this
+                succs[final].remove(corner)
+                add_to_successors(this)
+
+        # Generate moves 3 thru m*n-1.
+        def advance(len=len):
+            # If some successor has only one exit, must take it.
+            # Else favor successors with fewer exits.
+            candidates = []
+            for i in succs[self.lastij]:
+                e = len(succs[i])
+                assert e > 0, "else remove_from_successors() pruning flawed"
+                if e == 1:
+                    candidates = [(e, i)]
+                    break
+                candidates.append((e, i))
+            else:
+                candidates.sort()
+
+            for e, i in candidates:
+                if i != self.final:
+                    if remove_from_successors(i):
+                        self.lastij = i
+                        yield i
+                    add_to_successors(i)
+
+        # Generate moves 3 thru m*n-1.  Alternative version using a
+        # stronger (but more expensive) heuristic to order successors.
+        # Since the # of backtracking levels is m*n, a poor move early on
+        # can take eons to undo.  Smallest square board for which this
+        # matters a lot is 52x52.
+        def advance_hard(vmid=(m-1)/2.0, hmid=(n-1)/2.0, len=len):
+            # If some successor has only one exit, must take it.
+            # Else favor successors with fewer exits.
+            # Break ties via max distance from board centerpoint (favor
+            # corners and edges whenever possible).
+            candidates = []
+            for i in succs[self.lastij]:
+                e = len(succs[i])
+                assert e > 0, "else remove_from_successors() pruning flawed"
+                if e == 1:
+                    candidates = [(e, 0, i)]
+                    break
+                i1, j1 = self.index2coords(i)
+                d = (i1 - vmid)**2 + (j1 - hmid)**2
+                candidates.append((e, -d, i))
+            else:
+                candidates.sort()
+
+            for e, d, i in candidates:
+                if i != self.final:
+                    if remove_from_successors(i):
+                        self.lastij = i
+                        yield i
+                    add_to_successors(i)
+
+        # Generate the last move.
+        def last():
+            assert self.final in succs[self.lastij]
+            yield self.final
+
+        if m*n < 4:
+            self.squaregenerators = [first]
+        else:
+            self.squaregenerators = [first, second] + \
+                [hard and advance_hard or advance] * (m*n - 3) + \
+                [last]
+
+    def coords2index(self, i, j):
+        assert 0 <= i < self.m
+        assert 0 <= j < self.n
+        return i * self.n + j
+
+    def index2coords(self, index):
+        assert 0 <= index < self.m * self.n
+        return divmod(index, self.n)
+
+    def _init_board(self):
+        succs = self.succs
+        del succs[:]
+        m, n = self.m, self.n
+        c2i = self.coords2index
+
+        offsets = [( 1,  2), ( 2,  1), ( 2, -1), ( 1, -2),
+                   (-1, -2), (-2, -1), (-2,  1), (-1,  2)]
+        rangen = range(n)
+        for i in range(m):
+            for j in rangen:
+                s = [c2i(i+io, j+jo) for io, jo in offsets
+                                     if 0 <= i+io < m and
+                                        0 <= j+jo < n]
+                succs.append(s)
+
+    # Generate solutions.
+    def solve(self):
+        self._init_board()
+        for x in conjoin(self.squaregenerators):
+            yield x
+
+    def printsolution(self, x):
+        m, n = self.m, self.n
+        assert len(x) == m*n
+        w = len(str(m*n))
+        format = "%" + str(w) + "d"
+
+        squares = [[None] * n for i in range(m)]
+        k = 1
+        for i in x:
+            i1, j1 = self.index2coords(i)
+            squares[i1][j1] = format % k
+            k += 1
+
+        sep = "+" + ("-" * w + "+") * n
+        print sep
+        for i in range(m):
+            row = squares[i]
+            print "|" + "|".join(row) + "|"
+            print sep
+
+conjoin_tests = """
+
+Generate the 3-bit binary numbers in order.  This illustrates dumbest-
+possible use of conjoin, just to generate the full cross-product.
+
+>>> for c in conjoin([lambda: iter((0, 1))] * 3):
+...     print c
+[0, 0, 0]
+[0, 0, 1]
+[0, 1, 0]
+[0, 1, 1]
+[1, 0, 0]
+[1, 0, 1]
+[1, 1, 0]
+[1, 1, 1]
+
+For efficiency in typical backtracking apps, conjoin() yields the same list
+object each time.  So if you want to save away a full account of its
+generated sequence, you need to copy its results.
+
+>>> def gencopy(iterator):
+...     for x in iterator:
+...         yield x[:]
+
+>>> for n in range(10):
+...     all = list(gencopy(conjoin([lambda: iter((0, 1))] * n)))
+...     print n, len(all), all[0] == [0] * n, all[-1] == [1] * n
+0 1 True True
+1 2 True True
+2 4 True True
+3 8 True True
+4 16 True True
+5 32 True True
+6 64 True True
+7 128 True True
+8 256 True True
+9 512 True True
+
+And run an 8-queens solver.
+
+>>> q = Queens(8)
+>>> LIMIT = 2
+>>> count = 0
+>>> for row2col in q.solve():
+...     count += 1
+...     if count <= LIMIT:
+...         print "Solution", count
+...         q.printsolution(row2col)
+Solution 1
++-+-+-+-+-+-+-+-+
+|Q| | | | | | | |
++-+-+-+-+-+-+-+-+
+| | | | |Q| | | |
++-+-+-+-+-+-+-+-+
+| | | | | | | |Q|
++-+-+-+-+-+-+-+-+
+| | | | | |Q| | |
++-+-+-+-+-+-+-+-+
+| | |Q| | | | | |
++-+-+-+-+-+-+-+-+
+| | | | | | |Q| |
++-+-+-+-+-+-+-+-+
+| |Q| | | | | | |
++-+-+-+-+-+-+-+-+
+| | | |Q| | | | |
++-+-+-+-+-+-+-+-+
+Solution 2
++-+-+-+-+-+-+-+-+
+|Q| | | | | | | |
++-+-+-+-+-+-+-+-+
+| | | | | |Q| | |
++-+-+-+-+-+-+-+-+
+| | | | | | | |Q|
++-+-+-+-+-+-+-+-+
+| | |Q| | | | | |
++-+-+-+-+-+-+-+-+
+| | | | | | |Q| |
++-+-+-+-+-+-+-+-+
+| | | |Q| | | | |
++-+-+-+-+-+-+-+-+
+| |Q| | | | | | |
++-+-+-+-+-+-+-+-+
+| | | | |Q| | | |
++-+-+-+-+-+-+-+-+
+
+>>> print count, "solutions in all."
+92 solutions in all.
+
+And run a Knight's Tour on a 10x10 board.  Note that there are about
+20,000 solutions even on a 6x6 board, so don't dare run this to exhaustion.
+
+>>> k = Knights(10, 10)
+>>> LIMIT = 2
+>>> count = 0
+>>> for x in k.solve():
+...     count += 1
+...     if count <= LIMIT:
+...         print "Solution", count
+...         k.printsolution(x)
+...     else:
+...         break
+Solution 1
++---+---+---+---+---+---+---+---+---+---+
+|  1| 58| 27| 34|  3| 40| 29| 10|  5|  8|
++---+---+---+---+---+---+---+---+---+---+
+| 26| 35|  2| 57| 28| 33|  4|  7| 30| 11|
++---+---+---+---+---+---+---+---+---+---+
+| 59|100| 73| 36| 41| 56| 39| 32|  9|  6|
++---+---+---+---+---+---+---+---+---+---+
+| 74| 25| 60| 55| 72| 37| 42| 49| 12| 31|
++---+---+---+---+---+---+---+---+---+---+
+| 61| 86| 99| 76| 63| 52| 47| 38| 43| 50|
++---+---+---+---+---+---+---+---+---+---+
+| 24| 75| 62| 85| 54| 71| 64| 51| 48| 13|
++---+---+---+---+---+---+---+---+---+---+
+| 87| 98| 91| 80| 77| 84| 53| 46| 65| 44|
++---+---+---+---+---+---+---+---+---+---+
+| 90| 23| 88| 95| 70| 79| 68| 83| 14| 17|
++---+---+---+---+---+---+---+---+---+---+
+| 97| 92| 21| 78| 81| 94| 19| 16| 45| 66|
++---+---+---+---+---+---+---+---+---+---+
+| 22| 89| 96| 93| 20| 69| 82| 67| 18| 15|
++---+---+---+---+---+---+---+---+---+---+
+Solution 2
++---+---+---+---+---+---+---+---+---+---+
+|  1| 58| 27| 34|  3| 40| 29| 10|  5|  8|
++---+---+---+---+---+---+---+---+---+---+
+| 26| 35|  2| 57| 28| 33|  4|  7| 30| 11|
++---+---+---+---+---+---+---+---+---+---+
+| 59|100| 73| 36| 41| 56| 39| 32|  9|  6|
++---+---+---+---+---+---+---+---+---+---+
+| 74| 25| 60| 55| 72| 37| 42| 49| 12| 31|
++---+---+---+---+---+---+---+---+---+---+
+| 61| 86| 99| 76| 63| 52| 47| 38| 43| 50|
++---+---+---+---+---+---+---+---+---+---+
+| 24| 75| 62| 85| 54| 71| 64| 51| 48| 13|
++---+---+---+---+---+---+---+---+---+---+
+| 87| 98| 89| 80| 77| 84| 53| 46| 65| 44|
++---+---+---+---+---+---+---+---+---+---+
+| 90| 23| 92| 95| 70| 79| 68| 83| 14| 17|
++---+---+---+---+---+---+---+---+---+---+
+| 97| 88| 21| 78| 81| 94| 19| 16| 45| 66|
++---+---+---+---+---+---+---+---+---+---+
+| 22| 91| 96| 93| 20| 69| 82| 67| 18| 15|
++---+---+---+---+---+---+---+---+---+---+
+"""
+
+weakref_tests = """\
+Generators are weakly referencable:
+
+>>> import weakref
+>>> def gen():
+...     yield 'foo!'
+...
+>>> wr = weakref.ref(gen)
+>>> wr() is gen
+True
+>>> p = weakref.proxy(gen)
+
+Generator-iterators are weakly referencable as well:
+
+>>> gi = gen()
+>>> wr = weakref.ref(gi)
+>>> wr() is gi
+True
+>>> p = weakref.proxy(gi)
+>>> list(p)
+['foo!']
+
+"""
+
+coroutine_tests = """\
+Sending a value into a started generator:
+
+>>> def f():
+...     print (yield 1)
+...     yield 2
+>>> g = f()
+>>> g.next()
+1
+>>> g.send(42)
+42
+2
+
+Sending a value into a new generator produces a TypeError:
+
+>>> f().send("foo")
+Traceback (most recent call last):
+...
+TypeError: can't send non-None value to a just-started generator
+
+
+Yield by itself yields None:
+
+>>> def f(): yield
+>>> list(f())
+[None]
+
+
+
+An obscene abuse of a yield expression within a generator expression:
+
+>>> list((yield 21) for i in range(4))
+[21, None, 21, None, 21, None, 21, None]
+
+And a more sane, but still weird usage:
+
+>>> def f(): list(i for i in [(yield 26)])
+>>> type(f())
+<type 'generator'>
+
+
+A yield expression with augmented assignment.
+
+>>> def coroutine(seq):
+...     count = 0
+...     while count < 200:
+...         count += yield
+...         seq.append(count)
+>>> seq = []
+>>> c = coroutine(seq)
+>>> c.next()
+>>> print seq
+[]
+>>> c.send(10)
+>>> print seq
+[10]
+>>> c.send(10)
+>>> print seq
+[10, 20]
+>>> c.send(10)
+>>> print seq
+[10, 20, 30]
+
+
+Check some syntax errors for yield expressions:
+
+>>> f=lambda: (yield 1),(yield 2)
+Traceback (most recent call last):
+  ...
+SyntaxError: 'yield' outside function (<doctest test.test_generators.__test__.coroutine[21]>, line 1)
+
+>>> def f(): return lambda x=(yield): 1
+Traceback (most recent call last):
+  ...
+SyntaxError: 'return' with argument inside generator (<doctest test.test_generators.__test__.coroutine[22]>, line 1)
+
+>>> def f(): x = yield = y
+Traceback (most recent call last):
+  ...
+SyntaxError: assignment to yield expression not possible (<doctest test.test_generators.__test__.coroutine[23]>, line 1)
+
+>>> def f(): (yield bar) = y
+Traceback (most recent call last):
+  ...
+SyntaxError: can't assign to yield expression (<doctest test.test_generators.__test__.coroutine[24]>, line 1)
+
+>>> def f(): (yield bar) += y
+Traceback (most recent call last):
+  ...
+SyntaxError: augmented assignment to yield expression not possible (<doctest test.test_generators.__test__.coroutine[25]>, line 1)
+
+
+Now check some throw() conditions:
+
+>>> def f():
+...     while True:
+...         try:
+...             print (yield)
+...         except ValueError,v:
+...             print "caught ValueError (%s)" % (v),
+>>> import sys
+>>> g = f()
+>>> g.next()
+
+>>> g.throw(ValueError) # type only
+caught ValueError ()
+
+>>> g.throw(ValueError("xyz"))  # value only
+caught ValueError (xyz)
+
+>>> g.throw(ValueError, ValueError(1))   # value+matching type
+caught ValueError (1)
+
+>>> g.throw(ValueError, TypeError(1))  # mismatched type, rewrapped
+caught ValueError (1)
+
+>>> g.throw(ValueError, ValueError(1), None)   # explicit None traceback
+caught ValueError (1)
+
+>>> g.throw(ValueError(1), "foo")       # bad args
+Traceback (most recent call last):
+  ...
+TypeError: instance exception may not have a separate value
+
+>>> g.throw(ValueError, "foo", 23)      # bad args
+Traceback (most recent call last):
+  ...
+TypeError: throw() third argument must be a traceback object
+
+>>> def throw(g,exc):
+...     try:
+...         raise exc
+...     except:
+...         g.throw(*sys.exc_info())
+>>> throw(g,ValueError) # do it with traceback included
+caught ValueError ()
+
+>>> g.send(1)
+1
+
+>>> throw(g,TypeError)  # terminate the generator
+Traceback (most recent call last):
+  ...
+TypeError
+
+>>> print g.gi_frame
+None
+
+>>> g.send(2)
+Traceback (most recent call last):
+  ...
+StopIteration
+
+>>> g.throw(ValueError,6)       # throw on closed generator
+Traceback (most recent call last):
+  ...
+ValueError: 6
+
+>>> f().throw(ValueError,7)     # throw on just-opened generator
+Traceback (most recent call last):
+  ...
+ValueError: 7
+
+>>> f().throw("abc")     # throw on just-opened generator
+Traceback (most recent call last):
+  ...
+abc
+
+Now let's try closing a generator:
+
+>>> def f():
+...     try: yield
+...     except GeneratorExit:
+...         print "exiting"
+
+>>> g = f()
+>>> g.next()
+>>> g.close()
+exiting
+>>> g.close()  # should be no-op now
+
+>>> f().close()  # close on just-opened generator should be fine
+
+>>> def f(): yield      # an even simpler generator
+>>> f().close()         # close before opening
+>>> g = f()
+>>> g.next()
+>>> g.close()           # close normally
+
+And finalization:
+
+>>> def f():
+...     try: yield
+...     finally:
+...         print "exiting"
+
+>>> g = f()
+>>> g.next()
+>>> del g
+exiting
+
+
+Now let's try some ill-behaved generators:
+
+>>> def f():
+...     try: yield
+...     except GeneratorExit:
+...         yield "foo!"
+>>> g = f()
+>>> g.next()
+>>> g.close()
+Traceback (most recent call last):
+  ...
+RuntimeError: generator ignored GeneratorExit
+>>> g.close()
+
+
+Our ill-behaved code should be invoked during GC:
+
+>>> import sys, StringIO
+>>> old, sys.stderr = sys.stderr, StringIO.StringIO()
+>>> g = f()
+>>> g.next()
+>>> del g
+>>> sys.stderr.getvalue().startswith(
+...     "Exception exceptions.RuntimeError: 'generator ignored GeneratorExit' in "
+... )
+True
+>>> sys.stderr = old
+
+
+And errors thrown during closing should propagate:
+
+>>> def f():
+...     try: yield
+...     except GeneratorExit:
+...         raise TypeError("fie!")
+>>> g = f()
+>>> g.next()
+>>> g.close()
+Traceback (most recent call last):
+  ...
+TypeError: fie!
+
+
+Ensure that various yield expression constructs make their
+enclosing function a generator:
+
+>>> def f(): x += yield
+>>> type(f())
+<type 'generator'>
+
+>>> def f(): x = yield
+>>> type(f())
+<type 'generator'>
+
+>>> def f(): lambda x=(yield): 1
+>>> type(f())
+<type 'generator'>
+
+>>> def f(): x=(i for i in (yield) if (yield))
+>>> type(f())
+<type 'generator'>
+
+>>> def f(d): d[(yield "a")] = d[(yield "b")] = 27
+>>> data = [1,2]
+>>> g = f(data)
+>>> type(g)
+<type 'generator'>
+>>> g.send(None)
+'a'
+>>> data
+[1, 2]
+>>> g.send(0)
+'b'
+>>> data
+[27, 2]
+>>> try: g.send(1)
+... except StopIteration: pass
+>>> data
+[27, 27]
+
+"""
+
+refleaks_tests = """
+Prior to adding cycle-GC support to itertools.tee, this code would leak
+references. We add it to the standard suite so the routine refleak-tests
+would trigger if it starts being uncleanable again.
+
+>>> import itertools
+>>> def leak():
+...     class gen:
+...         def __iter__(self):
+...             return self
+...         def next(self):
+...             return self.item
+...     g = gen()
+...     head, tail = itertools.tee(g)
+...     g.item = head
+...     return head
+>>> it = leak()
+
+Make sure to also test the involvement of the tee-internal teedataobject,
+which stores returned items.
+
+>>> item = it.next()
+
+
+
+This test leaked at one point due to generator finalization/destruction.
+It was copied from Lib/test/leakers/test_generator_cycle.py before the file
+was removed.
+
+>>> def leak():
+...    def gen():
+...        while True:
+...            yield g
+...    g = gen()
+
+>>> leak()
+
+
+
+This test isn't really generator related, but rather exception-in-cleanup
+related. The coroutine tests (above) just happen to cause an exception in
+the generator's __del__ (tp_del) method. We can also test for this
+explicitly, without generators. We do have to redirect stderr to avoid
+printing warnings and to doublecheck that we actually tested what we wanted
+to test.
+
+>>> import sys, StringIO
+>>> old = sys.stderr
+>>> try:
+...     sys.stderr = StringIO.StringIO()
+...     class Leaker:
+...         def __del__(self):
+...             raise RuntimeError
+...
+...     l = Leaker()
+...     del l
+...     err = sys.stderr.getvalue().strip()
+...     err.startswith(
+...         "Exception exceptions.RuntimeError: RuntimeError() in <"
+...     )
+...     err.endswith("> ignored")
+...     len(err.splitlines())
+... finally:
+...     sys.stderr = old
+True
+True
+1
+
+
+
+These refleak tests should perhaps be in a testfile of their own,
+test_generators just happened to be the test that drew these out.
+
+"""
+
+__test__ = {"tut":      tutorial_tests,
+            "pep":      pep_tests,
+            "email":    email_tests,
+            "fun":      fun_tests,
+            "syntax":   syntax_tests,
+            "conjoin":  conjoin_tests,
+            "weakref":  weakref_tests,
+            "coroutine":  coroutine_tests,
+            "refleaks": refleaks_tests,
+            }
+
+# Magic test name that regrtest.py invokes *after* importing this module.
+# This worms around a bootstrap problem.
+# Note that doctest and regrtest both look in sys.argv for a "-v" argument,
+# so this works as expected in both ways of running regrtest.
+def test_main(verbose=None):
+    from test import test_support, test_generators
+    test_support.run_doctest(test_generators, verbose)
+
+# This part isn't needed for regrtest, but for running the test directly.
+if __name__ == "__main__":
+    test_main(1)

Added: vendor/Python/current/Lib/test/test_genexps.py
===================================================================
--- vendor/Python/current/Lib/test/test_genexps.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_genexps.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,280 @@
+doctests = """
+
+Test simple loop with conditional
+
+    >>> sum(i*i for i in range(100) if i&1 == 1)
+    166650
+
+Test simple nesting
+
+    >>> list((i,j) for i in range(3) for j in range(4) )
+    [(0, 0), (0, 1), (0, 2), (0, 3), (1, 0), (1, 1), (1, 2), (1, 3), (2, 0), (2, 1), (2, 2), (2, 3)]
+
+Test nesting with the inner expression dependent on the outer
+
+    >>> list((i,j) for i in range(4) for j in range(i) )
+    [(1, 0), (2, 0), (2, 1), (3, 0), (3, 1), (3, 2)]
+
+Make sure the induction variable is not exposed
+
+    >>> i = 20
+    >>> sum(i*i for i in range(100))
+    328350
+    >>> i
+    20
+
+Test first class
+
+    >>> g = (i*i for i in range(4))
+    >>> type(g)
+    <type 'generator'>
+    >>> list(g)
+    [0, 1, 4, 9]
+
+Test direct calls to next()
+
+    >>> g = (i*i for i in range(3))
+    >>> g.next()
+    0
+    >>> g.next()
+    1
+    >>> g.next()
+    4
+    >>> g.next()
+    Traceback (most recent call last):
+      File "<pyshell#21>", line 1, in -toplevel-
+        g.next()
+    StopIteration
+
+Does it stay stopped?
+
+    >>> g.next()
+    Traceback (most recent call last):
+      File "<pyshell#21>", line 1, in -toplevel-
+        g.next()
+    StopIteration
+    >>> list(g)
+    []
+
+Test running gen when defining function is out of scope
+
+    >>> def f(n):
+    ...     return (i*i for i in xrange(n))
+    >>> list(f(10))
+    [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
+
+    >>> def f(n):
+    ...     return ((i,j) for i in xrange(3) for j in xrange(n))
+    >>> list(f(4))
+    [(0, 0), (0, 1), (0, 2), (0, 3), (1, 0), (1, 1), (1, 2), (1, 3), (2, 0), (2, 1), (2, 2), (2, 3)]
+    >>> def f(n):
+    ...     return ((i,j) for i in xrange(3) for j in xrange(4) if j in xrange(n))
+    >>> list(f(4))
+    [(0, 0), (0, 1), (0, 2), (0, 3), (1, 0), (1, 1), (1, 2), (1, 3), (2, 0), (2, 1), (2, 2), (2, 3)]
+    >>> list(f(2))
+    [(0, 0), (0, 1), (1, 0), (1, 1), (2, 0), (2, 1)]
+
+Verify that parenthesis are required in a statement
+
+    >>> def f(n):
+    ...     return i*i for i in xrange(n)
+    Traceback (most recent call last):
+       ...
+    SyntaxError: invalid syntax
+
+Verify that parenthesis are required when used as a keyword argument value
+
+    >>> dict(a = i for i in xrange(10))
+    Traceback (most recent call last):
+       ...
+    SyntaxError: invalid syntax
+
+Verify that parenthesis are required when used as a keyword argument value
+
+    >>> dict(a = (i for i in xrange(10))) #doctest: +ELLIPSIS
+    {'a': <generator object at ...>}
+
+Verify early binding for the outermost for-expression
+
+    >>> x=10
+    >>> g = (i*i for i in range(x))
+    >>> x = 5
+    >>> list(g)
+    [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
+
+Verify that the outermost for-expression makes an immediate check
+for iterability
+
+    >>> (i for i in 6)
+    Traceback (most recent call last):
+      File "<pyshell#4>", line 1, in -toplevel-
+        (i for i in 6)
+    TypeError: 'int' object is not iterable
+
+Verify late binding for the outermost if-expression
+
+    >>> include = (2,4,6,8)
+    >>> g = (i*i for i in range(10) if i in include)
+    >>> include = (1,3,5,7,9)
+    >>> list(g)
+    [1, 9, 25, 49, 81]
+
+Verify late binding for the innermost for-expression
+
+    >>> g = ((i,j) for i in range(3) for j in range(x))
+    >>> x = 4
+    >>> list(g)
+    [(0, 0), (0, 1), (0, 2), (0, 3), (1, 0), (1, 1), (1, 2), (1, 3), (2, 0), (2, 1), (2, 2), (2, 3)]
+
+Verify re-use of tuples (a side benefit of using genexps over listcomps)
+
+    >>> tupleids = map(id, ((i,i) for i in xrange(10)))
+    >>> int(max(tupleids) - min(tupleids))
+    0
+
+Verify that syntax error's are raised for genexps used as lvalues
+
+    >>> (y for y in (1,2)) = 10
+    Traceback (most recent call last):
+       ...
+    SyntaxError: can't assign to generator expression (<doctest test.test_genexps.__test__.doctests[40]>, line 1)
+
+    >>> (y for y in (1,2)) += 10
+    Traceback (most recent call last):
+       ...
+    SyntaxError: augmented assignment to generator expression not possible (<doctest test.test_genexps.__test__.doctests[41]>, line 1)
+
+
+########### Tests borrowed from or inspired by test_generators.py ############
+
+Make a generator that acts like range()
+
+    >>> yrange = lambda n:  (i for i in xrange(n))
+    >>> list(yrange(10))
+    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+
+Generators always return to the most recent caller:
+
+    >>> def creator():
+    ...     r = yrange(5)
+    ...     print "creator", r.next()
+    ...     return r
+    >>> def caller():
+    ...     r = creator()
+    ...     for i in r:
+    ...             print "caller", i
+    >>> caller()
+    creator 0
+    caller 1
+    caller 2
+    caller 3
+    caller 4
+
+Generators can call other generators:
+
+    >>> def zrange(n):
+    ...     for i in yrange(n):
+    ...         yield i
+    >>> list(zrange(5))
+    [0, 1, 2, 3, 4]
+
+
+Verify that a gen exp cannot be resumed while it is actively running:
+
+    >>> g = (me.next() for i in xrange(10))
+    >>> me = g
+    >>> me.next()
+    Traceback (most recent call last):
+      File "<pyshell#30>", line 1, in -toplevel-
+        me.next()
+      File "<pyshell#28>", line 1, in <generator expression>
+        g = (me.next() for i in xrange(10))
+    ValueError: generator already executing
+
+Verify exception propagation
+
+    >>> g = (10 // i for i in (5, 0, 2))
+    >>> g.next()
+    2
+    >>> g.next()
+    Traceback (most recent call last):
+      File "<pyshell#37>", line 1, in -toplevel-
+        g.next()
+      File "<pyshell#35>", line 1, in <generator expression>
+        g = (10 // i for i in (5, 0, 2))
+    ZeroDivisionError: integer division or modulo by zero
+    >>> g.next()
+    Traceback (most recent call last):
+      File "<pyshell#38>", line 1, in -toplevel-
+        g.next()
+    StopIteration
+
+Make sure that None is a valid return value
+
+    >>> list(None for i in xrange(10))
+    [None, None, None, None, None, None, None, None, None, None]
+
+Check that generator attributes are present
+
+    >>> g = (i*i for i in range(3))
+    >>> expected = set(['gi_frame', 'gi_running', 'next'])
+    >>> set(attr for attr in dir(g) if not attr.startswith('__')) >= expected
+    True
+
+    >>> print g.next.__doc__
+    x.next() -> the next value, or raise StopIteration
+    >>> import types
+    >>> isinstance(g, types.GeneratorType)
+    True
+
+Check the __iter__ slot is defined to return self
+
+    >>> iter(g) is g
+    True
+
+Verify that the running flag is set properly
+
+    >>> g = (me.gi_running for i in (0,1))
+    >>> me = g
+    >>> me.gi_running
+    0
+    >>> me.next()
+    1
+    >>> me.gi_running
+    0
+
+Verify that genexps are weakly referencable
+
+    >>> import weakref
+    >>> g = (i*i for i in range(4))
+    >>> wr = weakref.ref(g)
+    >>> wr() is g
+    True
+    >>> p = weakref.proxy(g)
+    >>> list(p)
+    [0, 1, 4, 9]
+
+
+"""
+
+
+__test__ = {'doctests' : doctests}
+
+def test_main(verbose=None):
+    import sys
+    from test import test_support
+    from test import test_genexps
+    test_support.run_doctest(test_genexps, verbose)
+
+    # verify reference counting
+    if verbose and hasattr(sys, "gettotalrefcount"):
+        import gc
+        counts = [None] * 5
+        for i in xrange(len(counts)):
+            test_support.run_doctest(test_genexps, verbose)
+            gc.collect()
+            counts[i] = sys.gettotalrefcount()
+        print counts
+
+if __name__ == "__main__":
+    test_main(verbose=True)

Added: vendor/Python/current/Lib/test/test_getargs.py
===================================================================
--- vendor/Python/current/Lib/test/test_getargs.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_getargs.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,24 @@
+"""Test the internal getargs.c implementation
+
+ PyArg_ParseTuple() is defined here.
+
+The test here is not intended to test all of the module, just the
+single case that failed between 2.1 and 2.2a2.
+"""
+
+# marshal.loads() uses PyArg_ParseTuple(args, "s#:loads")
+# The s code will cause a Unicode conversion to occur.  This test
+# verify that the error is propagated properly from the C code back to
+# Python.
+
+# XXX If the encoding succeeds using the current default encoding,
+# this test will fail because it does not test the right part of the
+# PyArg_ParseTuple() implementation.
+from test.test_support import have_unicode
+import marshal
+
+if have_unicode:
+    try:
+        marshal.loads(unicode(r"\222", 'unicode-escape'))
+    except UnicodeError:
+        pass

Added: vendor/Python/current/Lib/test/test_getargs2.py
===================================================================
--- vendor/Python/current/Lib/test/test_getargs2.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_getargs2.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,264 @@
+import unittest
+from test import test_support
+import sys
+
+import warnings, re
+warnings.filterwarnings("ignore",
+                        category=DeprecationWarning,
+                        message=".*integer argument expected, got float",
+                        module=__name__)
+warnings.filterwarnings("ignore",
+                        category=DeprecationWarning,
+                        message=".*integer argument expected, got float",
+                        module="unittest")
+
+"""
+> How about the following counterproposal. This also changes some of
+> the other format codes to be a little more regular.
+>
+> Code C type Range check
+>
+> b unsigned char 0..UCHAR_MAX
+> h signed short SHRT_MIN..SHRT_MAX
+> B unsigned char none **
+> H unsigned short none **
+> k * unsigned long none
+> I * unsigned int 0..UINT_MAX
+
+
+> i int INT_MIN..INT_MAX
+> l long LONG_MIN..LONG_MAX
+
+> K * unsigned long long none
+> L long long LLONG_MIN..LLONG_MAX
+
+> Notes:
+>
+> * New format codes.
+>
+> ** Changed from previous "range-and-a-half" to "none"; the
+> range-and-a-half checking wasn't particularly useful.
+
+Plus a C API or two, e.g. PyInt_AsLongMask() ->
+unsigned long and PyInt_AsLongLongMask() -> unsigned
+long long (if that exists).
+"""
+
+LARGE = 0x7FFFFFFF
+VERY_LARGE = 0xFF0000121212121212121242L
+
+from _testcapi import UCHAR_MAX, USHRT_MAX, UINT_MAX, ULONG_MAX, INT_MAX, \
+     INT_MIN, LONG_MIN, LONG_MAX, PY_SSIZE_T_MIN, PY_SSIZE_T_MAX
+
+# fake, they are not defined in Python's header files
+LLONG_MAX = 2**63-1
+LLONG_MIN = -2**63
+ULLONG_MAX = 2**64-1
+
+class Long:
+    def __int__(self):
+        return 99L
+
+class Int:
+    def __int__(self):
+        return 99
+
+class Unsigned_TestCase(unittest.TestCase):
+    def test_b(self):
+        from _testcapi import getargs_b
+        # b returns 'unsigned char', and does range checking (0 ... UCHAR_MAX)
+        self.failUnlessEqual(3, getargs_b(3.14))
+        self.failUnlessEqual(99, getargs_b(Long()))
+        self.failUnlessEqual(99, getargs_b(Int()))
+
+        self.assertRaises(OverflowError, getargs_b, -1)
+        self.failUnlessEqual(0, getargs_b(0))
+        self.failUnlessEqual(UCHAR_MAX, getargs_b(UCHAR_MAX))
+        self.assertRaises(OverflowError, getargs_b, UCHAR_MAX + 1)
+
+        self.failUnlessEqual(42, getargs_b(42))
+        self.failUnlessEqual(42, getargs_b(42L))
+        self.assertRaises(OverflowError, getargs_b, VERY_LARGE)
+
+    def test_B(self):
+        from _testcapi import getargs_B
+        # B returns 'unsigned char', no range checking
+        self.failUnlessEqual(3, getargs_B(3.14))
+        self.failUnlessEqual(99, getargs_B(Long()))
+        self.failUnlessEqual(99, getargs_B(Int()))
+
+        self.failUnlessEqual(UCHAR_MAX, getargs_B(-1))
+        self.failUnlessEqual(UCHAR_MAX, getargs_B(-1L))
+        self.failUnlessEqual(0, getargs_B(0))
+        self.failUnlessEqual(UCHAR_MAX, getargs_B(UCHAR_MAX))
+        self.failUnlessEqual(0, getargs_B(UCHAR_MAX+1))
+
+        self.failUnlessEqual(42, getargs_B(42))
+        self.failUnlessEqual(42, getargs_B(42L))
+        self.failUnlessEqual(UCHAR_MAX & VERY_LARGE, getargs_B(VERY_LARGE))
+
+    def test_H(self):
+        from _testcapi import getargs_H
+        # H returns 'unsigned short', no range checking
+        self.failUnlessEqual(3, getargs_H(3.14))
+        self.failUnlessEqual(99, getargs_H(Long()))
+        self.failUnlessEqual(99, getargs_H(Int()))
+
+        self.failUnlessEqual(USHRT_MAX, getargs_H(-1))
+        self.failUnlessEqual(0, getargs_H(0))
+        self.failUnlessEqual(USHRT_MAX, getargs_H(USHRT_MAX))
+        self.failUnlessEqual(0, getargs_H(USHRT_MAX+1))
+
+        self.failUnlessEqual(42, getargs_H(42))
+        self.failUnlessEqual(42, getargs_H(42L))
+
+        self.failUnlessEqual(VERY_LARGE & USHRT_MAX, getargs_H(VERY_LARGE))
+
+    def test_I(self):
+        from _testcapi import getargs_I
+        # I returns 'unsigned int', no range checking
+        self.failUnlessEqual(3, getargs_I(3.14))
+        self.failUnlessEqual(99, getargs_I(Long()))
+        self.failUnlessEqual(99, getargs_I(Int()))
+
+        self.failUnlessEqual(UINT_MAX, getargs_I(-1))
+        self.failUnlessEqual(0, getargs_I(0))
+        self.failUnlessEqual(UINT_MAX, getargs_I(UINT_MAX))
+        self.failUnlessEqual(0, getargs_I(UINT_MAX+1))
+
+        self.failUnlessEqual(42, getargs_I(42))
+        self.failUnlessEqual(42, getargs_I(42L))
+
+        self.failUnlessEqual(VERY_LARGE & UINT_MAX, getargs_I(VERY_LARGE))
+
+    def test_k(self):
+        from _testcapi import getargs_k
+        # k returns 'unsigned long', no range checking
+        # it does not accept float, or instances with __int__
+        self.assertRaises(TypeError, getargs_k, 3.14)
+        self.assertRaises(TypeError, getargs_k, Long())
+        self.assertRaises(TypeError, getargs_k, Int())
+
+        self.failUnlessEqual(ULONG_MAX, getargs_k(-1))
+        self.failUnlessEqual(0, getargs_k(0))
+        self.failUnlessEqual(ULONG_MAX, getargs_k(ULONG_MAX))
+        self.failUnlessEqual(0, getargs_k(ULONG_MAX+1))
+
+        self.failUnlessEqual(42, getargs_k(42))
+        self.failUnlessEqual(42, getargs_k(42L))
+
+        self.failUnlessEqual(VERY_LARGE & ULONG_MAX, getargs_k(VERY_LARGE))
+
+class Signed_TestCase(unittest.TestCase):
+    def test_i(self):
+        from _testcapi import getargs_i
+        # i returns 'int', and does range checking (INT_MIN ... INT_MAX)
+        self.failUnlessEqual(3, getargs_i(3.14))
+        self.failUnlessEqual(99, getargs_i(Long()))
+        self.failUnlessEqual(99, getargs_i(Int()))
+
+        self.assertRaises(OverflowError, getargs_i, INT_MIN-1)
+        self.failUnlessEqual(INT_MIN, getargs_i(INT_MIN))
+        self.failUnlessEqual(INT_MAX, getargs_i(INT_MAX))
+        self.assertRaises(OverflowError, getargs_i, INT_MAX+1)
+
+        self.failUnlessEqual(42, getargs_i(42))
+        self.failUnlessEqual(42, getargs_i(42L))
+        self.assertRaises(OverflowError, getargs_i, VERY_LARGE)
+
+    def test_l(self):
+        from _testcapi import getargs_l
+        # l returns 'long', and does range checking (LONG_MIN ... LONG_MAX)
+        self.failUnlessEqual(3, getargs_l(3.14))
+        self.failUnlessEqual(99, getargs_l(Long()))
+        self.failUnlessEqual(99, getargs_l(Int()))
+
+        self.assertRaises(OverflowError, getargs_l, LONG_MIN-1)
+        self.failUnlessEqual(LONG_MIN, getargs_l(LONG_MIN))
+        self.failUnlessEqual(LONG_MAX, getargs_l(LONG_MAX))
+        self.assertRaises(OverflowError, getargs_l, LONG_MAX+1)
+
+        self.failUnlessEqual(42, getargs_l(42))
+        self.failUnlessEqual(42, getargs_l(42L))
+        self.assertRaises(OverflowError, getargs_l, VERY_LARGE)
+
+    def test_n(self):
+        from _testcapi import getargs_n
+        # n returns 'Py_ssize_t', and does range checking
+        # (PY_SSIZE_T_MIN ... PY_SSIZE_T_MAX)
+        self.failUnlessEqual(3, getargs_n(3.14))
+        self.failUnlessEqual(99, getargs_n(Long()))
+        self.failUnlessEqual(99, getargs_n(Int()))
+
+        self.assertRaises(OverflowError, getargs_n, PY_SSIZE_T_MIN-1)
+        self.failUnlessEqual(PY_SSIZE_T_MIN, getargs_n(PY_SSIZE_T_MIN))
+        self.failUnlessEqual(PY_SSIZE_T_MAX, getargs_n(PY_SSIZE_T_MAX))
+        self.assertRaises(OverflowError, getargs_n, PY_SSIZE_T_MAX+1)
+
+        self.failUnlessEqual(42, getargs_n(42))
+        self.failUnlessEqual(42, getargs_n(42L))
+        self.assertRaises(OverflowError, getargs_n, VERY_LARGE)
+
+
+class LongLong_TestCase(unittest.TestCase):
+    def test_L(self):
+        from _testcapi import getargs_L
+        # L returns 'long long', and does range checking (LLONG_MIN ... LLONG_MAX)
+        self.failUnlessRaises(TypeError, getargs_L, "Hello")
+        self.failUnlessEqual(3, getargs_L(3.14))
+        self.failUnlessEqual(99, getargs_L(Long()))
+        self.failUnlessEqual(99, getargs_L(Int()))
+
+        self.assertRaises(OverflowError, getargs_L, LLONG_MIN-1)
+        self.failUnlessEqual(LLONG_MIN, getargs_L(LLONG_MIN))
+        self.failUnlessEqual(LLONG_MAX, getargs_L(LLONG_MAX))
+        self.assertRaises(OverflowError, getargs_L, LLONG_MAX+1)
+
+        self.failUnlessEqual(42, getargs_L(42))
+        self.failUnlessEqual(42, getargs_L(42L))
+        self.assertRaises(OverflowError, getargs_L, VERY_LARGE)
+
+    def test_K(self):
+        from _testcapi import getargs_K
+        # K return 'unsigned long long', no range checking
+        self.assertRaises(TypeError, getargs_K, 3.14)
+        self.assertRaises(TypeError, getargs_K, Long())
+        self.assertRaises(TypeError, getargs_K, Int())
+        self.failUnlessEqual(ULLONG_MAX, getargs_K(ULLONG_MAX))
+        self.failUnlessEqual(0, getargs_K(0))
+        self.failUnlessEqual(0, getargs_K(ULLONG_MAX+1))
+
+        self.failUnlessEqual(42, getargs_K(42))
+        self.failUnlessEqual(42, getargs_K(42L))
+
+        self.failUnlessEqual(VERY_LARGE & ULLONG_MAX, getargs_K(VERY_LARGE))
+
+
+class Tuple_TestCase(unittest.TestCase):
+    def test_tuple(self):
+        from _testcapi import getargs_tuple
+
+        ret = getargs_tuple(1, (2, 3))
+        self.assertEquals(ret, (1,2,3))
+
+        # make sure invalid tuple arguments are handled correctly
+        class seq:
+            def __len__(self):
+                return 2
+            def __getitem__(self, n):
+                raise ValueError
+        self.assertRaises(TypeError, getargs_tuple, 1, seq())
+
+
+def test_main():
+    tests = [Signed_TestCase, Unsigned_TestCase, Tuple_TestCase]
+    try:
+        from _testcapi import getargs_L, getargs_K
+    except ImportError:
+        pass # PY_LONG_LONG not available
+    else:
+        tests.append(LongLong_TestCase)
+    test_support.run_unittest(*tests)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_getopt.py
===================================================================
--- vendor/Python/current/Lib/test/test_getopt.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_getopt.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,180 @@
+# test_getopt.py
+# David Goodger <dgoodger at bigfoot.com> 2000-08-19
+
+import getopt
+from getopt import GetoptError
+from test.test_support import verify, verbose, run_doctest
+import os
+
+def expectException(teststr, expected, failure=AssertionError):
+    """Executes a statement passed in teststr, and raises an exception
+       (failure) if the expected exception is *not* raised."""
+    try:
+        exec teststr
+    except expected:
+        pass
+    else:
+        raise failure
+
+old_posixly_correct = os.environ.get("POSIXLY_CORRECT")
+if old_posixly_correct is not None:
+    del os.environ["POSIXLY_CORRECT"]
+
+if verbose:
+    print 'Running tests on getopt.short_has_arg'
+verify(getopt.short_has_arg('a', 'a:'))
+verify(not getopt.short_has_arg('a', 'a'))
+expectException("tmp = getopt.short_has_arg('a', 'b')", GetoptError)
+expectException("tmp = getopt.short_has_arg('a', '')", GetoptError)
+
+if verbose:
+    print 'Running tests on getopt.long_has_args'
+has_arg, option = getopt.long_has_args('abc', ['abc='])
+verify(has_arg)
+verify(option == 'abc')
+has_arg, option = getopt.long_has_args('abc', ['abc'])
+verify(not has_arg)
+verify(option == 'abc')
+has_arg, option = getopt.long_has_args('abc', ['abcd'])
+verify(not has_arg)
+verify(option == 'abcd')
+expectException("has_arg, option = getopt.long_has_args('abc', ['def'])",
+                GetoptError)
+expectException("has_arg, option = getopt.long_has_args('abc', [])",
+                GetoptError)
+expectException("has_arg, option = " + \
+                     "getopt.long_has_args('abc', ['abcd','abcde'])",
+                GetoptError)
+
+if verbose:
+    print 'Running tests on getopt.do_shorts'
+opts, args = getopt.do_shorts([], 'a', 'a', [])
+verify(opts == [('-a', '')])
+verify(args == [])
+opts, args = getopt.do_shorts([], 'a1', 'a:', [])
+verify(opts == [('-a', '1')])
+verify(args == [])
+#opts, args = getopt.do_shorts([], 'a=1', 'a:', [])
+#verify(opts == [('-a', '1')])
+#verify(args == [])
+opts, args = getopt.do_shorts([], 'a', 'a:', ['1'])
+verify(opts == [('-a', '1')])
+verify(args == [])
+opts, args = getopt.do_shorts([], 'a', 'a:', ['1', '2'])
+verify(opts == [('-a', '1')])
+verify(args == ['2'])
+expectException("opts, args = getopt.do_shorts([], 'a1', 'a', [])",
+                GetoptError)
+expectException("opts, args = getopt.do_shorts([], 'a', 'a:', [])",
+                GetoptError)
+
+if verbose:
+    print 'Running tests on getopt.do_longs'
+opts, args = getopt.do_longs([], 'abc', ['abc'], [])
+verify(opts == [('--abc', '')])
+verify(args == [])
+opts, args = getopt.do_longs([], 'abc=1', ['abc='], [])
+verify(opts == [('--abc', '1')])
+verify(args == [])
+opts, args = getopt.do_longs([], 'abc=1', ['abcd='], [])
+verify(opts == [('--abcd', '1')])
+verify(args == [])
+opts, args = getopt.do_longs([], 'abc', ['ab', 'abc', 'abcd'], [])
+verify(opts == [('--abc', '')])
+verify(args == [])
+# Much like the preceding, except with a non-alpha character ("-") in
+# option name that precedes "="; failed in
+# http://sourceforge.net/bugs/?func=detailbug&bug_id=126863&group_id=5470
+opts, args = getopt.do_longs([], 'foo=42', ['foo-bar', 'foo=',], [])
+verify(opts == [('--foo', '42')])
+verify(args == [])
+expectException("opts, args = getopt.do_longs([], 'abc=1', ['abc'], [])",
+                GetoptError)
+expectException("opts, args = getopt.do_longs([], 'abc', ['abc='], [])",
+                GetoptError)
+
+# note: the empty string between '-a' and '--beta' is significant:
+# it simulates an empty string option argument ('-a ""') on the command line.
+cmdline = ['-a', '1', '-b', '--alpha=2', '--beta', '-a', '3', '-a', '',
+           '--beta', 'arg1', 'arg2']
+
+if verbose:
+    print 'Running tests on getopt.getopt'
+opts, args = getopt.getopt(cmdline, 'a:b', ['alpha=', 'beta'])
+verify(opts == [('-a', '1'), ('-b', ''), ('--alpha', '2'), ('--beta', ''),
+                ('-a', '3'), ('-a', ''), ('--beta', '')] )
+# Note ambiguity of ('-b', '') and ('-a', '') above. This must be
+# accounted for in the code that calls getopt().
+verify(args == ['arg1', 'arg2'])
+
+expectException(
+    "opts, args = getopt.getopt(cmdline, 'a:b', ['alpha', 'beta'])",
+    GetoptError)
+
+# Test handling of GNU style scanning mode.
+if verbose:
+    print 'Running tests on getopt.gnu_getopt'
+cmdline = ['-a', 'arg1', '-b', '1', '--alpha', '--beta=2']
+# GNU style
+opts, args = getopt.gnu_getopt(cmdline, 'ab:', ['alpha', 'beta='])
+verify(opts == [('-a', ''), ('-b', '1'), ('--alpha', ''), ('--beta', '2')])
+verify(args == ['arg1'])
+# Posix style via +
+opts, args = getopt.gnu_getopt(cmdline, '+ab:', ['alpha', 'beta='])
+verify(opts == [('-a', '')])
+verify(args == ['arg1', '-b', '1', '--alpha', '--beta=2'])
+# Posix style via POSIXLY_CORRECT
+os.environ["POSIXLY_CORRECT"] = "1"
+opts, args = getopt.gnu_getopt(cmdline, 'ab:', ['alpha', 'beta='])
+verify(opts == [('-a', '')])
+verify(args == ['arg1', '-b', '1', '--alpha', '--beta=2'])
+
+
+if old_posixly_correct is None:
+    del os.environ["POSIXLY_CORRECT"]
+else:
+    os.environ["POSIXLY_CORRECT"] = old_posixly_correct
+
+#------------------------------------------------------------------------------
+
+libreftest = """
+Examples from the Library Reference:  Doc/lib/libgetopt.tex
+
+An example using only Unix style options:
+
+
+>>> import getopt
+>>> args = '-a -b -cfoo -d bar a1 a2'.split()
+>>> args
+['-a', '-b', '-cfoo', '-d', 'bar', 'a1', 'a2']
+>>> optlist, args = getopt.getopt(args, 'abc:d:')
+>>> optlist
+[('-a', ''), ('-b', ''), ('-c', 'foo'), ('-d', 'bar')]
+>>> args
+['a1', 'a2']
+
+Using long option names is equally easy:
+
+
+>>> s = '--condition=foo --testing --output-file abc.def -x a1 a2'
+>>> args = s.split()
+>>> args
+['--condition=foo', '--testing', '--output-file', 'abc.def', '-x', 'a1', 'a2']
+>>> optlist, args = getopt.getopt(args, 'x', [
+...     'condition=', 'output-file=', 'testing'])
+>>> optlist
+[('--condition', 'foo'), ('--testing', ''), ('--output-file', 'abc.def'), ('-x', '')]
+>>> args
+['a1', 'a2']
+
+"""
+
+__test__ = {'libreftest' : libreftest}
+
+import sys
+run_doctest(sys.modules[__name__], verbose)
+
+#------------------------------------------------------------------------------
+
+if verbose:
+    print "Module getopt: tests completed successfully."

Added: vendor/Python/current/Lib/test/test_gettext.py
===================================================================
--- vendor/Python/current/Lib/test/test_gettext.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_gettext.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,458 @@
+import os
+import base64
+import shutil
+import gettext
+import unittest
+
+from test.test_support import run_suite
+
+
+# TODO:
+#  - Add new tests, for example for "dgettext"
+#  - Remove dummy tests, for example testing for single and double quotes
+#    has no sense, it would have if we were testing a parser (i.e. pygettext)
+#  - Tests should have only one assert.
+
+GNU_MO_DATA = '''\
+3hIElQAAAAAGAAAAHAAAAEwAAAALAAAAfAAAAAAAAACoAAAAFQAAAKkAAAAjAAAAvwAAAKEAAADj
+AAAABwAAAIUBAAALAAAAjQEAAEUBAACZAQAAFgAAAN8CAAAeAAAA9gIAAKEAAAAVAwAABQAAALcD
+AAAJAAAAvQMAAAEAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABQAAAAYAAAACAAAAAFJh
+eW1vbmQgTHV4dXJ5IFlhY2gtdABUaGVyZSBpcyAlcyBmaWxlAFRoZXJlIGFyZSAlcyBmaWxlcwBU
+aGlzIG1vZHVsZSBwcm92aWRlcyBpbnRlcm5hdGlvbmFsaXphdGlvbiBhbmQgbG9jYWxpemF0aW9u
+CnN1cHBvcnQgZm9yIHlvdXIgUHl0aG9uIHByb2dyYW1zIGJ5IHByb3ZpZGluZyBhbiBpbnRlcmZh
+Y2UgdG8gdGhlIEdOVQpnZXR0ZXh0IG1lc3NhZ2UgY2F0YWxvZyBsaWJyYXJ5LgBtdWxsdXNrAG51
+ZGdlIG51ZGdlAFByb2plY3QtSWQtVmVyc2lvbjogMi4wClBPLVJldmlzaW9uLURhdGU6IDIwMDAt
+MDgtMjkgMTI6MTktMDQ6MDAKTGFzdC1UcmFuc2xhdG9yOiBKLiBEYXZpZCBJYsOhw7FleiA8ai1k
+YXZpZEBub29zLmZyPgpMYW5ndWFnZS1UZWFtOiBYWCA8cHl0aG9uLWRldkBweXRob24ub3JnPgpN
+SU1FLVZlcnNpb246IDEuMApDb250ZW50LVR5cGU6IHRleHQvcGxhaW47IGNoYXJzZXQ9aXNvLTg4
+NTktMQpDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBub25lCkdlbmVyYXRlZC1CeTogcHlnZXR0
+ZXh0LnB5IDEuMQpQbHVyYWwtRm9ybXM6IG5wbHVyYWxzPTI7IHBsdXJhbD1uIT0xOwoAVGhyb2F0
+d29iYmxlciBNYW5ncm92ZQBIYXkgJXMgZmljaGVybwBIYXkgJXMgZmljaGVyb3MAR3V2ZiB6YnFo
+eXIgY2ViaXZxcmYgdmFncmVhbmd2YmFueXZtbmd2YmEgbmFxIHlicG55dm1uZ3ZiYQpmaGNjYmVn
+IHNiZSBsYmhlIENsZ3ViYSBjZWJ0ZW56ZiBvbCBjZWJpdnF2YXQgbmEgdmFncmVzbnByIGdiIGd1
+ciBUQUgKdHJnZ3JrZyB6cmZmbnRyIHBuZ255YnQgeXZvZW5lbC4AYmFjb24Ad2luayB3aW5rAA==
+'''
+
+UMO_DATA = '''\
+3hIElQAAAAACAAAAHAAAACwAAAAFAAAAPAAAAAAAAABQAAAABAAAAFEAAAAPAQAAVgAAAAQAAABm
+AQAAAQAAAAIAAAAAAAAAAAAAAAAAAAAAYWLDngBQcm9qZWN0LUlkLVZlcnNpb246IDIuMApQTy1S
+ZXZpc2lvbi1EYXRlOiAyMDAzLTA0LTExIDEyOjQyLTA0MDAKTGFzdC1UcmFuc2xhdG9yOiBCYXJy
+eSBBLiBXQXJzYXcgPGJhcnJ5QHB5dGhvbi5vcmc+Ckxhbmd1YWdlLVRlYW06IFhYIDxweXRob24t
+ZGV2QHB5dGhvbi5vcmc+Ck1JTUUtVmVyc2lvbjogMS4wCkNvbnRlbnQtVHlwZTogdGV4dC9wbGFp
+bjsgY2hhcnNldD11dGYtOApDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiA3Yml0CkdlbmVyYXRl
+ZC1CeTogbWFudWFsbHkKAMKkeXoA
+'''
+
+MMO_DATA = '''\
+3hIElQAAAAABAAAAHAAAACQAAAADAAAALAAAAAAAAAA4AAAAeAEAADkAAAABAAAAAAAAAAAAAAAA
+UHJvamVjdC1JZC1WZXJzaW9uOiBObyBQcm9qZWN0IDAuMApQT1QtQ3JlYXRpb24tRGF0ZTogV2Vk
+IERlYyAxMSAwNzo0NDoxNSAyMDAyClBPLVJldmlzaW9uLURhdGU6IDIwMDItMDgtMTQgMDE6MTg6
+NTgrMDA6MDAKTGFzdC1UcmFuc2xhdG9yOiBKb2huIERvZSA8amRvZUBleGFtcGxlLmNvbT4KSmFu
+ZSBGb29iYXIgPGpmb29iYXJAZXhhbXBsZS5jb20+Ckxhbmd1YWdlLVRlYW06IHh4IDx4eEBleGFt
+cGxlLmNvbT4KTUlNRS1WZXJzaW9uOiAxLjAKQ29udGVudC1UeXBlOiB0ZXh0L3BsYWluOyBjaGFy
+c2V0PWlzby04ODU5LTE1CkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IHF1b3RlZC1wcmludGFi
+bGUKR2VuZXJhdGVkLUJ5OiBweWdldHRleHQucHkgMS4zCgA=
+'''
+
+LOCALEDIR = os.path.join('xx', 'LC_MESSAGES')
+MOFILE = os.path.join(LOCALEDIR, 'gettext.mo')
+UMOFILE = os.path.join(LOCALEDIR, 'ugettext.mo')
+MMOFILE = os.path.join(LOCALEDIR, 'metadata.mo')
+try:
+    LANG = os.environ['LANGUAGE']
+except:
+    LANG = 'en'
+
+
+class GettextBaseTest(unittest.TestCase):
+    def setUp(self):
+        if not os.path.isdir(LOCALEDIR):
+            os.makedirs(LOCALEDIR)
+        fp = open(MOFILE, 'wb')
+        fp.write(base64.decodestring(GNU_MO_DATA))
+        fp.close()
+        fp = open(UMOFILE, 'wb')
+        fp.write(base64.decodestring(UMO_DATA))
+        fp.close()
+        fp = open(MMOFILE, 'wb')
+        fp.write(base64.decodestring(MMO_DATA))
+        fp.close()
+        os.environ['LANGUAGE'] = 'xx'
+
+    def tearDown(self):
+        os.environ['LANGUAGE'] = LANG
+        shutil.rmtree(os.path.split(LOCALEDIR)[0])
+
+
+class GettextTestCase1(GettextBaseTest):
+    def setUp(self):
+        GettextBaseTest.setUp(self)
+        self.localedir = os.curdir
+        self.mofile = MOFILE
+        gettext.install('gettext', self.localedir)
+
+    def test_some_translations(self):
+        eq = self.assertEqual
+        # test some translations
+        eq(_('albatross'), 'albatross')
+        eq(_(u'mullusk'), 'bacon')
+        eq(_(r'Raymond Luxury Yach-t'), 'Throatwobbler Mangrove')
+        eq(_(ur'nudge nudge'), 'wink wink')
+
+    def test_double_quotes(self):
+        eq = self.assertEqual
+        # double quotes
+        eq(_("albatross"), 'albatross')
+        eq(_(u"mullusk"), 'bacon')
+        eq(_(r"Raymond Luxury Yach-t"), 'Throatwobbler Mangrove')
+        eq(_(ur"nudge nudge"), 'wink wink')
+
+    def test_triple_single_quotes(self):
+        eq = self.assertEqual
+        # triple single quotes
+        eq(_('''albatross'''), 'albatross')
+        eq(_(u'''mullusk'''), 'bacon')
+        eq(_(r'''Raymond Luxury Yach-t'''), 'Throatwobbler Mangrove')
+        eq(_(ur'''nudge nudge'''), 'wink wink')
+
+    def test_triple_double_quotes(self):
+        eq = self.assertEqual
+        # triple double quotes
+        eq(_("""albatross"""), 'albatross')
+        eq(_(u"""mullusk"""), 'bacon')
+        eq(_(r"""Raymond Luxury Yach-t"""), 'Throatwobbler Mangrove')
+        eq(_(ur"""nudge nudge"""), 'wink wink')
+
+    def test_multiline_strings(self):
+        eq = self.assertEqual
+        # multiline strings
+        eq(_('''This module provides internationalization and localization
+support for your Python programs by providing an interface to the GNU
+gettext message catalog library.'''),
+           '''Guvf zbqhyr cebivqrf vagreangvbanyvmngvba naq ybpnyvmngvba
+fhccbeg sbe lbhe Clguba cebtenzf ol cebivqvat na vagresnpr gb gur TAH
+trggrkg zrffntr pngnybt yvoenel.''')
+
+    def test_the_alternative_interface(self):
+        eq = self.assertEqual
+        # test the alternative interface
+        fp = open(self.mofile, 'rb')
+        t = gettext.GNUTranslations(fp)
+        fp.close()
+        # Install the translation object
+        t.install()
+        eq(_('nudge nudge'), 'wink wink')
+        # Try unicode return type
+        t.install(unicode=True)
+        eq(_('mullusk'), 'bacon')
+        # Test installation of other methods
+        import __builtin__
+        t.install(unicode=True, names=["gettext", "lgettext"])
+        eq(_, t.ugettext)
+        eq(__builtin__.gettext, t.ugettext)
+        eq(lgettext, t.lgettext)
+        del __builtin__.gettext
+        del __builtin__.lgettext
+
+
+class GettextTestCase2(GettextBaseTest):
+    def setUp(self):
+        GettextBaseTest.setUp(self)
+        self.localedir = os.curdir
+        # Set up the bindings
+        gettext.bindtextdomain('gettext', self.localedir)
+        gettext.textdomain('gettext')
+        # For convenience
+        self._ = gettext.gettext
+
+    def test_bindtextdomain(self):
+        self.assertEqual(gettext.bindtextdomain('gettext'), self.localedir)
+
+    def test_textdomain(self):
+        self.assertEqual(gettext.textdomain(), 'gettext')
+
+    def test_some_translations(self):
+        eq = self.assertEqual
+        # test some translations
+        eq(self._('albatross'), 'albatross')
+        eq(self._(u'mullusk'), 'bacon')
+        eq(self._(r'Raymond Luxury Yach-t'), 'Throatwobbler Mangrove')
+        eq(self._(ur'nudge nudge'), 'wink wink')
+
+    def test_double_quotes(self):
+        eq = self.assertEqual
+        # double quotes
+        eq(self._("albatross"), 'albatross')
+        eq(self._(u"mullusk"), 'bacon')
+        eq(self._(r"Raymond Luxury Yach-t"), 'Throatwobbler Mangrove')
+        eq(self._(ur"nudge nudge"), 'wink wink')
+
+    def test_triple_single_quotes(self):
+        eq = self.assertEqual
+        # triple single quotes
+        eq(self._('''albatross'''), 'albatross')
+        eq(self._(u'''mullusk'''), 'bacon')
+        eq(self._(r'''Raymond Luxury Yach-t'''), 'Throatwobbler Mangrove')
+        eq(self._(ur'''nudge nudge'''), 'wink wink')
+
+    def test_triple_double_quotes(self):
+        eq = self.assertEqual
+        # triple double quotes
+        eq(self._("""albatross"""), 'albatross')
+        eq(self._(u"""mullusk"""), 'bacon')
+        eq(self._(r"""Raymond Luxury Yach-t"""), 'Throatwobbler Mangrove')
+        eq(self._(ur"""nudge nudge"""), 'wink wink')
+
+    def test_multiline_strings(self):
+        eq = self.assertEqual
+        # multiline strings
+        eq(self._('''This module provides internationalization and localization
+support for your Python programs by providing an interface to the GNU
+gettext message catalog library.'''),
+           '''Guvf zbqhyr cebivqrf vagreangvbanyvmngvba naq ybpnyvmngvba
+fhccbeg sbe lbhe Clguba cebtenzf ol cebivqvat na vagresnpr gb gur TAH
+trggrkg zrffntr pngnybt yvoenel.''')
+
+
+class PluralFormsTestCase(GettextBaseTest):
+    def setUp(self):
+        GettextBaseTest.setUp(self)
+        self.mofile = MOFILE
+
+    def test_plural_forms1(self):
+        eq = self.assertEqual
+        x = gettext.ngettext('There is %s file', 'There are %s files', 1)
+        eq(x, 'Hay %s fichero')
+        x = gettext.ngettext('There is %s file', 'There are %s files', 2)
+        eq(x, 'Hay %s ficheros')
+
+    def test_plural_forms2(self):
+        eq = self.assertEqual
+        fp = open(self.mofile, 'rb')
+        t = gettext.GNUTranslations(fp)
+        fp.close()
+        x = t.ngettext('There is %s file', 'There are %s files', 1)
+        eq(x, 'Hay %s fichero')
+        x = t.ngettext('There is %s file', 'There are %s files', 2)
+        eq(x, 'Hay %s ficheros')
+
+    def test_hu(self):
+        eq = self.assertEqual
+        f = gettext.c2py('0')
+        s = ''.join([ str(f(x)) for x in range(200) ])
+        eq(s, "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
+
+    def test_de(self):
+        eq = self.assertEqual
+        f = gettext.c2py('n != 1')
+        s = ''.join([ str(f(x)) for x in range(200) ])
+        eq(s, "10111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111")
+
+    def test_fr(self):
+        eq = self.assertEqual
+        f = gettext.c2py('n>1')
+        s = ''.join([ str(f(x)) for x in range(200) ])
+        eq(s, "00111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111")
+
+    def test_gd(self):
+        eq = self.assertEqual
+        f = gettext.c2py('n==1 ? 0 : n==2 ? 1 : 2')
+        s = ''.join([ str(f(x)) for x in range(200) ])
+        eq(s, "20122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222")
+
+    def test_gd2(self):
+        eq = self.assertEqual
+        # Tests the combination of parentheses and "?:"
+        f = gettext.c2py('n==1 ? 0 : (n==2 ? 1 : 2)')
+        s = ''.join([ str(f(x)) for x in range(200) ])
+        eq(s, "20122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222")
+
+    def test_lt(self):
+        eq = self.assertEqual
+        f = gettext.c2py('n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2')
+        s = ''.join([ str(f(x)) for x in range(200) ])
+        eq(s, "20111111112222222222201111111120111111112011111111201111111120111111112011111111201111111120111111112011111111222222222220111111112011111111201111111120111111112011111111201111111120111111112011111111")
+
+    def test_ru(self):
+        eq = self.assertEqual
+        f = gettext.c2py('n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2')
+        s = ''.join([ str(f(x)) for x in range(200) ])
+        eq(s, "20111222222222222222201112222220111222222011122222201112222220111222222011122222201112222220111222222011122222222222222220111222222011122222201112222220111222222011122222201112222220111222222011122222")
+
+    def test_pl(self):
+        eq = self.assertEqual
+        f = gettext.c2py('n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2')
+        s = ''.join([ str(f(x)) for x in range(200) ])
+        eq(s, "20111222222222222222221112222222111222222211122222221112222222111222222211122222221112222222111222222211122222222222222222111222222211122222221112222222111222222211122222221112222222111222222211122222")
+
+    def test_sl(self):
+        eq = self.assertEqual
+        f = gettext.c2py('n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3')
+        s = ''.join([ str(f(x)) for x in range(200) ])
+        eq(s, "30122333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333012233333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333")
+
+    def test_security(self):
+        raises = self.assertRaises
+        # Test for a dangerous expression
+        raises(ValueError, gettext.c2py, "os.chmod('/etc/passwd',0777)")
+
+
+class UnicodeTranslationsTest(GettextBaseTest):
+    def setUp(self):
+        GettextBaseTest.setUp(self)
+        fp = open(UMOFILE, 'rb')
+        try:
+            self.t = gettext.GNUTranslations(fp)
+        finally:
+            fp.close()
+        self._ = self.t.ugettext
+
+    def test_unicode_msgid(self):
+        unless = self.failUnless
+        unless(isinstance(self._(''), unicode))
+        unless(isinstance(self._(u''), unicode))
+
+    def test_unicode_msgstr(self):
+        eq = self.assertEqual
+        eq(self._(u'ab\xde'), u'\xa4yz')
+
+
+class WeirdMetadataTest(GettextBaseTest):
+    def setUp(self):
+        GettextBaseTest.setUp(self)
+        fp = open(MMOFILE, 'rb')
+        try:
+            try:
+                self.t = gettext.GNUTranslations(fp)
+            except:
+                self.tearDown()
+                raise
+        finally:
+            fp.close()
+
+    def test_weird_metadata(self):
+        info = self.t.info()
+        self.assertEqual(info['last-translator'],
+           'John Doe <jdoe at example.com>\nJane Foobar <jfoobar at example.com>')
+
+
+def suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(GettextTestCase1))
+    suite.addTest(unittest.makeSuite(GettextTestCase2))
+    suite.addTest(unittest.makeSuite(PluralFormsTestCase))
+    suite.addTest(unittest.makeSuite(UnicodeTranslationsTest))
+    suite.addTest(unittest.makeSuite(WeirdMetadataTest))
+    return suite
+
+
+def test_main():
+    run_suite(suite())
+
+
+if __name__ == '__main__':
+    test_main()
+
+
+# For reference, here's the .po file used to created the GNU_MO_DATA above.
+#
+# The original version was automatically generated from the sources with
+# pygettext. Later it was manually modified to add plural forms support.
+
+'''
+# Dummy translation for the Python test_gettext.py module.
+# Copyright (C) 2001 Python Software Foundation
+# Barry Warsaw <barry at python.org>, 2000.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: 2.0\n"
+"PO-Revision-Date: 2003-04-11 14:32-0400\n"
+"Last-Translator: J. David Ibanez <j-david at noos.fr>\n"
+"Language-Team: XX <python-dev at python.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=iso-8859-1\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: pygettext.py 1.1\n"
+"Plural-Forms: nplurals=2; plural=n!=1;\n"
+
+#: test_gettext.py:19 test_gettext.py:25 test_gettext.py:31 test_gettext.py:37
+#: test_gettext.py:51 test_gettext.py:80 test_gettext.py:86 test_gettext.py:92
+#: test_gettext.py:98
+msgid "nudge nudge"
+msgstr "wink wink"
+
+#: test_gettext.py:16 test_gettext.py:22 test_gettext.py:28 test_gettext.py:34
+#: test_gettext.py:77 test_gettext.py:83 test_gettext.py:89 test_gettext.py:95
+msgid "albatross"
+msgstr ""
+
+#: test_gettext.py:18 test_gettext.py:24 test_gettext.py:30 test_gettext.py:36
+#: test_gettext.py:79 test_gettext.py:85 test_gettext.py:91 test_gettext.py:97
+msgid "Raymond Luxury Yach-t"
+msgstr "Throatwobbler Mangrove"
+
+#: test_gettext.py:17 test_gettext.py:23 test_gettext.py:29 test_gettext.py:35
+#: test_gettext.py:56 test_gettext.py:78 test_gettext.py:84 test_gettext.py:90
+#: test_gettext.py:96
+msgid "mullusk"
+msgstr "bacon"
+
+#: test_gettext.py:40 test_gettext.py:101
+msgid ""
+"This module provides internationalization and localization\n"
+"support for your Python programs by providing an interface to the GNU\n"
+"gettext message catalog library."
+msgstr ""
+"Guvf zbqhyr cebivqrf vagreangvbanyvmngvba naq ybpnyvmngvba\n"
+"fhccbeg sbe lbhe Clguba cebtenzf ol cebivqvat na vagresnpr gb gur TAH\n"
+"trggrkg zrffntr pngnybt yvoenel."
+
+# Manually added, as neither pygettext nor xgettext support plural forms
+# in Python.
+msgid "There is %s file"
+msgid_plural "There are %s files"
+msgstr[0] "Hay %s fichero"
+msgstr[1] "Hay %s ficheros"
+'''
+
+# Here's the second example po file example, used to generate the UMO_DATA
+# containing utf-8 encoded Unicode strings
+
+'''
+# Dummy translation for the Python test_gettext.py module.
+# Copyright (C) 2001 Python Software Foundation
+# Barry Warsaw <barry at python.org>, 2000.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: 2.0\n"
+"PO-Revision-Date: 2003-04-11 12:42-0400\n"
+"Last-Translator: Barry A. WArsaw <barry at python.org>\n"
+"Language-Team: XX <python-dev at python.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 7bit\n"
+"Generated-By: manually\n"
+
+#: nofile:0
+msgid "ab\xc3\x9e"
+msgstr "\xc2\xa4yz"
+'''
+
+# Here's the third example po file, used to generate MMO_DATA
+
+'''
+msgid ""
+msgstr ""
+"Project-Id-Version: No Project 0.0\n"
+"POT-Creation-Date: Wed Dec 11 07:44:15 2002\n"
+"PO-Revision-Date: 2002-08-14 01:18:58+00:00\n"
+"Last-Translator: John Doe <jdoe at example.com>\n"
+"Jane Foobar <jfoobar at example.com>\n"
+"Language-Team: xx <xx at example.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=iso-8859-15\n"
+"Content-Transfer-Encoding: quoted-printable\n"
+"Generated-By: pygettext.py 1.3\n"
+'''

Added: vendor/Python/current/Lib/test/test_gl.py
===================================================================
--- vendor/Python/current/Lib/test/test_gl.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_gl.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,150 @@
+#! /usr/bin/env python
+"""Very simple test script for the SGI gl library extension module
+    taken mostly from the documentation.
+    Roger E. Masse
+"""
+from test.test_support import verbose, TestSkipped
+import gl, GL, time
+
+glattrs = ['RGBcolor', 'RGBcursor', 'RGBmode', 'RGBrange', 'RGBwritemask',
+'__doc__', '__name__', 'addtopup', 'altgetmatrix', 'arc', 'arcf',
+'arcfi', 'arcfs', 'arci', 'arcs', 'attachcursor', 'backbuffer',
+'backface', 'bbox2', 'bbox2i', 'bbox2s', 'bgnclosedline', 'bgnline',
+'bgnpoint', 'bgnpolygon', 'bgnsurface', 'bgntmesh', 'bgntrim',
+'blankscreen', 'blanktime', 'blendfunction', 'blink', 'c3f', 'c3i',
+'c3s', 'c4f', 'c4i', 'c4s', 'callobj', 'charstr', 'chunksize', 'circ',
+'circf', 'circfi', 'circfs', 'circi', 'circs', 'clear',
+'clearhitcode', 'clkoff', 'clkon', 'closeobj', 'cmode', 'cmov',
+'cmov2', 'cmov2i', 'cmov2s', 'cmovi', 'cmovs', 'color', 'colorf',
+'compactify', 'concave', 'cpack', 'crv', 'crvn', 'curorigin',
+'cursoff', 'curson', 'curstype', 'curvebasis', 'curveit',
+'curveprecision', 'cyclemap', 'czclear', 'defbasis', 'defcursor',
+'deflinestyle', 'delobj', 'deltag', 'depthcue', 'devport', 'dglclose',
+'dglopen', 'dither', 'dopup', 'doublebuffer', 'draw', 'draw2',
+'draw2i', 'draw2s', 'drawi', 'drawmode', 'draws', 'editobj',
+'endclosedline', 'endfullscrn', 'endline', 'endpick', 'endpoint',
+'endpolygon', 'endpupmode', 'endselect', 'endsurface', 'endtmesh',
+'endtrim', 'finish', 'font', 'foreground', 'freepup', 'frontbuffer',
+'fudge', 'fullscrn', 'gRGBcolor', 'gRGBmask', 'gammaramp', 'gbegin',
+'gconfig', 'genobj', 'gentag', 'getbackface', 'getbuffer',
+'getbutton', 'getcmmode', 'getcolor', 'getcpos', 'getcursor',
+'getdcm', 'getdepth', 'getdescender', 'getdisplaymode', 'getdrawmode',
+'getfont', 'getgdesc', 'getgpos', 'getheight', 'gethitcode',
+'getlsbackup', 'getlsrepeat', 'getlstyle', 'getlwidth', 'getmap',
+'getmatrix', 'getmcolor', 'getmmode', 'getmonitor',
+'getnurbsproperty', 'getopenobj', 'getorigin', 'getothermonitor',
+'getpattern', 'getplanes', 'getport', 'getresetls', 'getscrmask',
+'getshade', 'getsize', 'getsm', 'gettp', 'getvaluator', 'getvideo',
+'getviewport', 'getwritemask', 'getzbuffer', 'gewrite', 'gflush',
+'ginit', 'glcompat', 'greset', 'gselect', 'gsync', 'gversion',
+'iconsize', 'icontitle', 'imakebackground', 'initnames', 'ismex',
+'isobj', 'isqueued', 'istag', 'keepaspect', 'lRGBrange', 'lampoff',
+'lampon', 'linesmooth', 'linewidth', 'lmbind', 'lmcolor', 'lmdef',
+'loadmatrix', 'loadname', 'logicop', 'lookat', 'lrectread',
+'lrectwrite', 'lsbackup', 'lsetdepth', 'lshaderange', 'lsrepeat',
+'makeobj', 'maketag', 'mapcolor', 'mapw', 'mapw2', 'maxsize',
+'minsize', 'mmode', 'move', 'move2', 'move2i', 'move2s', 'movei',
+'moves', 'multimap', 'multmatrix', 'n3f', 'newpup', 'newtag',
+'noborder', 'noise', 'noport', 'normal', 'nurbscurve', 'nurbssurface',
+'nvarray', 'objdelete', 'objinsert', 'objreplace', 'onemap', 'ortho',
+'ortho2', 'overlay', 'packrect', 'pagecolor', 'pagewritemask',
+'passthrough', 'patch', 'patchbasis', 'patchcurves', 'patchprecision',
+'pclos', 'pdr', 'pdr2', 'pdr2i', 'pdr2s', 'pdri', 'pdrs',
+'perspective', 'pick', 'picksize', 'pixmode', 'pmv', 'pmv2', 'pmv2i',
+'pmv2s', 'pmvi', 'pmvs', 'pnt', 'pnt2', 'pnt2i', 'pnt2s', 'pnti',
+'pnts', 'pntsmooth', 'polarview', 'polf', 'polf2', 'polf2i', 'polf2s',
+'polfi', 'polfs', 'poly', 'poly2', 'poly2i', 'poly2s', 'polyi',
+'polys', 'popattributes', 'popmatrix', 'popname', 'popviewport',
+'prefposition', 'prefsize', 'pupmode', 'pushattributes', 'pushmatrix',
+'pushname', 'pushviewport', 'pwlcurve', 'qdevice', 'qenter', 'qgetfd',
+'qread', 'qreset', 'qtest', 'rcrv', 'rcrvn', 'rdr', 'rdr2', 'rdr2i',
+'rdr2s', 'rdri', 'rdrs', 'readdisplay', 'readsource', 'rect',
+'rectcopy', 'rectf', 'rectfi', 'rectfs', 'recti', 'rects', 'rectzoom',
+'resetls', 'reshapeviewport', 'ringbell', 'rmv', 'rmv2', 'rmv2i',
+'rmv2s', 'rmvi', 'rmvs', 'rot', 'rotate', 'rpatch', 'rpdr', 'rpdr2',
+'rpdr2i', 'rpdr2s', 'rpdri', 'rpdrs', 'rpmv', 'rpmv2', 'rpmv2i',
+'rpmv2s', 'rpmvi', 'rpmvs', 'sbox', 'sboxf', 'sboxfi', 'sboxfs',
+'sboxi', 'sboxs', 'scale', 'screenspace', 'scrmask', 'setbell',
+'setcursor', 'setdepth', 'setlinestyle', 'setmap', 'setmonitor',
+'setnurbsproperty', 'setpattern', 'setpup', 'setshade', 'setvaluator',
+'setvideo', 'shademodel', 'shaderange', 'singlebuffer', 'smoothline',
+'spclos', 'splf', 'splf2', 'splf2i', 'splf2s', 'splfi', 'splfs',
+'stepunit', 'strwidth', 'subpixel', 'swapbuffers', 'swapinterval',
+'swaptmesh', 'swinopen', 'textcolor', 'textinit', 'textport',
+'textwritemask', 'tie', 'tpoff', 'tpon', 'translate', 'underlay',
+'unpackrect', 'unqdevice', 'v2d', 'v2f', 'v2i', 'v2s', 'v3d', 'v3f',
+'v3i', 'v3s', 'v4d', 'v4f', 'v4i', 'v4s', 'varray', 'videocmd',
+'viewport', 'vnarray', 'winattach', 'winclose', 'winconstraints',
+'windepth', 'window', 'winget', 'winmove', 'winopen', 'winpop',
+'winposition', 'winpush', 'winset', 'wintitle', 'wmpack', 'writemask',
+'writepixels', 'xfpt', 'xfpt2', 'xfpt2i', 'xfpt2s', 'xfpt4', 'xfpt4i',
+'xfpt4s', 'xfpti', 'xfpts', 'zbuffer', 'zclear', 'zdraw', 'zfunction',
+'zsource', 'zwritemask']
+
+def main():
+    # insure that we at least have an X display before continuing.
+    import os
+    try:
+        display = os.environ['DISPLAY']
+    except:
+        raise TestSkipped, "No $DISPLAY -- skipping gl test"
+
+    # touch all the attributes of gl without doing anything
+    if verbose:
+        print 'Touching gl module attributes...'
+    for attr in glattrs:
+        if verbose:
+            print 'touching: ', attr
+        getattr(gl, attr)
+
+    # create a small 'Crisscross' window
+    if verbose:
+        print 'Creating a small "CrissCross" window...'
+        print 'foreground'
+    gl.foreground()
+    if verbose:
+        print 'prefposition'
+    gl.prefposition(500, 900, 500, 900)
+    if verbose:
+        print 'winopen "CrissCross"'
+    w = gl.winopen('CrissCross')
+    if verbose:
+        print 'clear'
+    gl.clear()
+    if verbose:
+        print 'ortho2'
+    gl.ortho2(0.0, 400.0, 0.0, 400.0)
+    if verbose:
+        print 'color WHITE'
+    gl.color(GL.WHITE)
+    if verbose:
+        print 'color RED'
+    gl.color(GL.RED)
+    if verbose:
+        print 'bgnline'
+    gl.bgnline()
+    if verbose:
+        print 'v2f'
+    gl.v2f(0.0, 0.0)
+    gl.v2f(400.0, 400.0)
+    if verbose:
+        print 'endline'
+    gl.endline()
+    if verbose:
+        print 'bgnline'
+    gl.bgnline()
+    if verbose:
+        print 'v2i'
+    gl.v2i(400, 0)
+    gl.v2i(0, 400)
+    if verbose:
+        print 'endline'
+    gl.endline()
+    if verbose:
+        print 'Displaying window for 2 seconds...'
+    time.sleep(2)
+    if verbose:
+        print 'winclose'
+    gl.winclose(w)
+
+main()


Property changes on: vendor/Python/current/Lib/test/test_gl.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/test/test_glob.py
===================================================================
--- vendor/Python/current/Lib/test/test_glob.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_glob.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,104 @@
+import unittest
+from test.test_support import run_unittest, TESTFN
+import glob
+import os
+import shutil
+
+class GlobTests(unittest.TestCase):
+
+    def norm(self, *parts):
+        return os.path.normpath(os.path.join(self.tempdir, *parts))
+
+    def mktemp(self, *parts):
+        filename = self.norm(*parts)
+        base, file = os.path.split(filename)
+        if not os.path.exists(base):
+            os.makedirs(base)
+        f = open(filename, 'w')
+        f.close()
+
+    def setUp(self):
+        self.tempdir = TESTFN+"_dir"
+        self.mktemp('a', 'D')
+        self.mktemp('aab', 'F')
+        self.mktemp('aaa', 'zzzF')
+        self.mktemp('ZZZ')
+        self.mktemp('a', 'bcd', 'EF')
+        self.mktemp('a', 'bcd', 'efg', 'ha')
+        if hasattr(os, 'symlink'):
+            os.symlink(self.norm('broken'), self.norm('sym1'))
+            os.symlink(self.norm('broken'), self.norm('sym2'))
+
+    def tearDown(self):
+        shutil.rmtree(self.tempdir)
+
+    def glob(self, *parts):
+        if len(parts) == 1:
+            pattern = parts[0]
+        else:
+            pattern = os.path.join(*parts)
+        p = os.path.join(self.tempdir, pattern)
+        res = glob.glob(p)
+        self.assertEqual(list(glob.iglob(p)), res)
+        return res
+
+    def assertSequencesEqual_noorder(self, l1, l2):
+        self.assertEqual(set(l1), set(l2))
+
+    def test_glob_literal(self):
+        eq = self.assertSequencesEqual_noorder
+        eq(self.glob('a'), [self.norm('a')])
+        eq(self.glob('a', 'D'), [self.norm('a', 'D')])
+        eq(self.glob('aab'), [self.norm('aab')])
+        eq(self.glob('zymurgy'), [])
+
+    def test_glob_one_directory(self):
+        eq = self.assertSequencesEqual_noorder
+        eq(self.glob('a*'), map(self.norm, ['a', 'aab', 'aaa']))
+        eq(self.glob('*a'), map(self.norm, ['a', 'aaa']))
+        eq(self.glob('aa?'), map(self.norm, ['aaa', 'aab']))
+        eq(self.glob('aa[ab]'), map(self.norm, ['aaa', 'aab']))
+        eq(self.glob('*q'), [])
+
+    def test_glob_nested_directory(self):
+        eq = self.assertSequencesEqual_noorder
+        if os.path.normcase("abCD") == "abCD":
+            # case-sensitive filesystem
+            eq(self.glob('a', 'bcd', 'E*'), [self.norm('a', 'bcd', 'EF')])
+        else:
+            # case insensitive filesystem
+            eq(self.glob('a', 'bcd', 'E*'), [self.norm('a', 'bcd', 'EF'),
+                                             self.norm('a', 'bcd', 'efg')])
+        eq(self.glob('a', 'bcd', '*g'), [self.norm('a', 'bcd', 'efg')])
+
+    def test_glob_directory_names(self):
+        eq = self.assertSequencesEqual_noorder
+        eq(self.glob('*', 'D'), [self.norm('a', 'D')])
+        eq(self.glob('*', '*a'), [])
+        eq(self.glob('a', '*', '*', '*a'),
+           [self.norm('a', 'bcd', 'efg', 'ha')])
+        eq(self.glob('?a?', '*F'), map(self.norm, [os.path.join('aaa', 'zzzF'),
+                                                   os.path.join('aab', 'F')]))
+
+    def test_glob_directory_with_trailing_slash(self):
+        # We are verifying that when there is wildcard pattern which
+        # ends with os.sep doesn't blow up.
+        res = glob.glob(self.tempdir + '*' + os.sep)
+        self.assertEqual(len(res), 1)
+        # either of these results are reasonable
+        self.assertTrue(res[0] in [self.tempdir, self.tempdir + os.sep])
+
+    def test_glob_broken_symlinks(self):
+        if hasattr(os, 'symlink'):
+            eq = self.assertSequencesEqual_noorder
+            eq(self.glob('sym*'), [self.norm('sym1'), self.norm('sym2')])
+            eq(self.glob('sym1'), [self.norm('sym1')])
+            eq(self.glob('sym2'), [self.norm('sym2')])
+
+
+def test_main():
+    run_unittest(GlobTests)
+
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_global.py
===================================================================
--- vendor/Python/current/Lib/test/test_global.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_global.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,51 @@
+"""Verify that warnings are issued for global statements following use."""
+
+from test.test_support import check_syntax
+
+import warnings
+
+warnings.filterwarnings("error", module="<test code>")
+
+def compile_and_check(text, should_fail=1):
+    try:
+        compile(text, "<test code>", "exec")
+    except SyntaxError, msg:
+        if should_fail:
+            print "got SyntaxError as expected"
+        else:
+            print "raised unexpected SyntaxError:", text
+    else:
+        if should_fail:
+            print "should have raised SyntaxError:", text
+        else:
+            print "as expected, no SyntaxError"
+
+prog_text_1 = """
+def wrong1():
+    a = 1
+    b = 2
+    global a
+    global b
+"""
+compile_and_check(prog_text_1)
+
+prog_text_2 = """
+def wrong2():
+    print x
+    global x
+"""
+compile_and_check(prog_text_2)
+
+prog_text_3 = """
+def wrong3():
+    print x
+    x = 2
+    global x
+"""
+compile_and_check(prog_text_3)
+
+prog_text_4 = """
+global x
+x = 2
+"""
+compile_and_check(prog_text_4, 0)

Added: vendor/Python/current/Lib/test/test_grammar.py
===================================================================
--- vendor/Python/current/Lib/test/test_grammar.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_grammar.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,856 @@
+# Python test set -- part 1, grammar.
+# This just tests whether the parser accepts them all.
+
+# NOTE: When you run this test as a script from the command line, you
+# get warnings about certain hex/oct constants.  Since those are
+# issued by the parser, you can't suppress them by adding a
+# filterwarnings() call to this module.  Therefore, to shut up the
+# regression test, the filterwarnings() call has been added to
+# regrtest.py.
+
+from test.test_support import TestFailed, verify, vereq, check_syntax
+import sys
+
+print '1. Parser'
+
+print '1.1 Tokens'
+
+print '1.1.1 Backslashes'
+
+# Backslash means line continuation:
+x = 1 \
++ 1
+if x != 2: raise TestFailed, 'backslash for line continuation'
+
+# Backslash does not means continuation in comments :\
+x = 0
+if x != 0: raise TestFailed, 'backslash ending comment'
+
+print '1.1.2 Numeric literals'
+
+print '1.1.2.1 Plain integers'
+if 0xff != 255: raise TestFailed, 'hex int'
+if 0377 != 255: raise TestFailed, 'octal int'
+if  2147483647   != 017777777777: raise TestFailed, 'large positive int'
+try:
+    from sys import maxint
+except ImportError:
+    maxint = 2147483647
+if maxint == 2147483647:
+    # The following test will start to fail in Python 2.4;
+    # change the 020000000000 to -020000000000
+    if -2147483647-1 != -020000000000: raise TestFailed, 'max negative int'
+    # XXX -2147483648
+    if 037777777777 < 0: raise TestFailed, 'large oct'
+    if 0xffffffff < 0: raise TestFailed, 'large hex'
+    for s in '2147483648', '040000000000', '0x100000000':
+        try:
+            x = eval(s)
+        except OverflowError:
+            print "OverflowError on huge integer literal " + repr(s)
+elif eval('maxint == 9223372036854775807'):
+    if eval('-9223372036854775807-1 != -01000000000000000000000'):
+        raise TestFailed, 'max negative int'
+    if eval('01777777777777777777777') < 0: raise TestFailed, 'large oct'
+    if eval('0xffffffffffffffff') < 0: raise TestFailed, 'large hex'
+    for s in '9223372036854775808', '02000000000000000000000', \
+             '0x10000000000000000':
+        try:
+            x = eval(s)
+        except OverflowError:
+            print "OverflowError on huge integer literal " + repr(s)
+else:
+    print 'Weird maxint value', maxint
+
+print '1.1.2.2 Long integers'
+x = 0L
+x = 0l
+x = 0xffffffffffffffffL
+x = 0xffffffffffffffffl
+x = 077777777777777777L
+x = 077777777777777777l
+x = 123456789012345678901234567890L
+x = 123456789012345678901234567890l
+
+print '1.1.2.3 Floating point'
+x = 3.14
+x = 314.
+x = 0.314
+# XXX x = 000.314
+x = .314
+x = 3e14
+x = 3E14
+x = 3e-14
+x = 3e+14
+x = 3.e14
+x = .3e14
+x = 3.1e4
+
+print '1.1.3 String literals'
+
+x = ''; y = ""; verify(len(x) == 0 and x == y)
+x = '\''; y = "'"; verify(len(x) == 1 and x == y and ord(x) == 39)
+x = '"'; y = "\""; verify(len(x) == 1 and x == y and ord(x) == 34)
+x = "doesn't \"shrink\" does it"
+y = 'doesn\'t "shrink" does it'
+verify(len(x) == 24 and x == y)
+x = "does \"shrink\" doesn't it"
+y = 'does "shrink" doesn\'t it'
+verify(len(x) == 24 and x == y)
+x = """
+The "quick"
+brown fox
+jumps over
+the 'lazy' dog.
+"""
+y = '\nThe "quick"\nbrown fox\njumps over\nthe \'lazy\' dog.\n'
+verify(x == y)
+y = '''
+The "quick"
+brown fox
+jumps over
+the 'lazy' dog.
+'''; verify(x == y)
+y = "\n\
+The \"quick\"\n\
+brown fox\n\
+jumps over\n\
+the 'lazy' dog.\n\
+"; verify(x == y)
+y = '\n\
+The \"quick\"\n\
+brown fox\n\
+jumps over\n\
+the \'lazy\' dog.\n\
+'; verify(x == y)
+
+
+print '1.2 Grammar'
+
+print 'single_input' # NEWLINE | simple_stmt | compound_stmt NEWLINE
+# XXX can't test in a script -- this rule is only used when interactive
+
+print 'file_input' # (NEWLINE | stmt)* ENDMARKER
+# Being tested as this very moment this very module
+
+print 'expr_input' # testlist NEWLINE
+# XXX Hard to test -- used only in calls to input()
+
+print 'eval_input' # testlist ENDMARKER
+x = eval('1, 0 or 1')
+
+print 'funcdef'
+### 'def' NAME parameters ':' suite
+### parameters: '(' [varargslist] ')'
+### varargslist: (fpdef ['=' test] ',')* ('*' NAME [',' ('**'|'*' '*') NAME]
+###            | ('**'|'*' '*') NAME)
+###            | fpdef ['=' test] (',' fpdef ['=' test])* [',']
+### fpdef: NAME | '(' fplist ')'
+### fplist: fpdef (',' fpdef)* [',']
+### arglist: (argument ',')* (argument | *' test [',' '**' test] | '**' test)
+### argument: [test '='] test   # Really [keyword '='] test
+def f1(): pass
+f1()
+f1(*())
+f1(*(), **{})
+def f2(one_argument): pass
+def f3(two, arguments): pass
+def f4(two, (compound, (argument, list))): pass
+def f5((compound, first), two): pass
+vereq(f2.func_code.co_varnames, ('one_argument',))
+vereq(f3.func_code.co_varnames, ('two', 'arguments'))
+if sys.platform.startswith('java'):
+    vereq(f4.func_code.co_varnames,
+           ('two', '(compound, (argument, list))', 'compound', 'argument',
+                        'list',))
+    vereq(f5.func_code.co_varnames,
+           ('(compound, first)', 'two', 'compound', 'first'))
+else:
+    vereq(f4.func_code.co_varnames,
+          ('two', '.1', 'compound', 'argument',  'list'))
+    vereq(f5.func_code.co_varnames,
+          ('.0', 'two', 'compound', 'first'))
+def a1(one_arg,): pass
+def a2(two, args,): pass
+def v0(*rest): pass
+def v1(a, *rest): pass
+def v2(a, b, *rest): pass
+def v3(a, (b, c), *rest): return a, b, c, rest
+# ceval unpacks the formal arguments into the first argcount names;
+# thus, the names nested inside tuples must appear after these names.
+if sys.platform.startswith('java'):
+    verify(v3.func_code.co_varnames == ('a', '(b, c)', 'rest', 'b', 'c'))
+else:
+    vereq(v3.func_code.co_varnames, ('a', '.1', 'rest', 'b', 'c'))
+verify(v3(1, (2, 3), 4) == (1, 2, 3, (4,)))
+def d01(a=1): pass
+d01()
+d01(1)
+d01(*(1,))
+d01(**{'a':2})
+def d11(a, b=1): pass
+d11(1)
+d11(1, 2)
+d11(1, **{'b':2})
+def d21(a, b, c=1): pass
+d21(1, 2)
+d21(1, 2, 3)
+d21(*(1, 2, 3))
+d21(1, *(2, 3))
+d21(1, 2, *(3,))
+d21(1, 2, **{'c':3})
+def d02(a=1, b=2): pass
+d02()
+d02(1)
+d02(1, 2)
+d02(*(1, 2))
+d02(1, *(2,))
+d02(1, **{'b':2})
+d02(**{'a': 1, 'b': 2})
+def d12(a, b=1, c=2): pass
+d12(1)
+d12(1, 2)
+d12(1, 2, 3)
+def d22(a, b, c=1, d=2): pass
+d22(1, 2)
+d22(1, 2, 3)
+d22(1, 2, 3, 4)
+def d01v(a=1, *rest): pass
+d01v()
+d01v(1)
+d01v(1, 2)
+d01v(*(1, 2, 3, 4))
+d01v(*(1,))
+d01v(**{'a':2})
+def d11v(a, b=1, *rest): pass
+d11v(1)
+d11v(1, 2)
+d11v(1, 2, 3)
+def d21v(a, b, c=1, *rest): pass
+d21v(1, 2)
+d21v(1, 2, 3)
+d21v(1, 2, 3, 4)
+d21v(*(1, 2, 3, 4))
+d21v(1, 2, **{'c': 3})
+def d02v(a=1, b=2, *rest): pass
+d02v()
+d02v(1)
+d02v(1, 2)
+d02v(1, 2, 3)
+d02v(1, *(2, 3, 4))
+d02v(**{'a': 1, 'b': 2})
+def d12v(a, b=1, c=2, *rest): pass
+d12v(1)
+d12v(1, 2)
+d12v(1, 2, 3)
+d12v(1, 2, 3, 4)
+d12v(*(1, 2, 3, 4))
+d12v(1, 2, *(3, 4, 5))
+d12v(1, *(2,), **{'c': 3})
+def d22v(a, b, c=1, d=2, *rest): pass
+d22v(1, 2)
+d22v(1, 2, 3)
+d22v(1, 2, 3, 4)
+d22v(1, 2, 3, 4, 5)
+d22v(*(1, 2, 3, 4))
+d22v(1, 2, *(3, 4, 5))
+d22v(1, *(2, 3), **{'d': 4})
+def d31v((x)): pass
+d31v(1)
+def d32v((x,)): pass
+d32v((1,))
+
+### lambdef: 'lambda' [varargslist] ':' test
+print 'lambdef'
+l1 = lambda : 0
+verify(l1() == 0)
+l2 = lambda : a[d] # XXX just testing the expression
+l3 = lambda : [2 < x for x in [-1, 3, 0L]]
+verify(l3() == [0, 1, 0])
+l4 = lambda x = lambda y = lambda z=1 : z : y() : x()
+verify(l4() == 1)
+l5 = lambda x, y, z=2: x + y + z
+verify(l5(1, 2) == 5)
+verify(l5(1, 2, 3) == 6)
+check_syntax("lambda x: x = 2")
+
+### stmt: simple_stmt | compound_stmt
+# Tested below
+
+### simple_stmt: small_stmt (';' small_stmt)* [';']
+print 'simple_stmt'
+x = 1; pass; del x
+def foo():
+    # verify statments that end with semi-colons
+    x = 1; pass; del x;
+foo()
+
+### small_stmt: expr_stmt | print_stmt  | pass_stmt | del_stmt | flow_stmt | import_stmt | global_stmt | access_stmt | exec_stmt
+# Tested below
+
+print 'expr_stmt' # (exprlist '=')* exprlist
+1
+1, 2, 3
+x = 1
+x = 1, 2, 3
+x = y = z = 1, 2, 3
+x, y, z = 1, 2, 3
+abc = a, b, c = x, y, z = xyz = 1, 2, (3, 4)
+# NB these variables are deleted below
+
+check_syntax("x + 1 = 1")
+check_syntax("a + 1 = b + 2")
+
+print 'print_stmt' # 'print' (test ',')* [test]
+print 1, 2, 3
+print 1, 2, 3,
+print
+print 0 or 1, 0 or 1,
+print 0 or 1
+
+print 'extended print_stmt' # 'print' '>>' test ','
+import sys
+print >> sys.stdout, 1, 2, 3
+print >> sys.stdout, 1, 2, 3,
+print >> sys.stdout
+print >> sys.stdout, 0 or 1, 0 or 1,
+print >> sys.stdout, 0 or 1
+
+# test printing to an instance
+class Gulp:
+    def write(self, msg): pass
+
+gulp = Gulp()
+print >> gulp, 1, 2, 3
+print >> gulp, 1, 2, 3,
+print >> gulp
+print >> gulp, 0 or 1, 0 or 1,
+print >> gulp, 0 or 1
+
+# test print >> None
+def driver():
+    oldstdout = sys.stdout
+    sys.stdout = Gulp()
+    try:
+        tellme(Gulp())
+        tellme()
+    finally:
+        sys.stdout = oldstdout
+
+# we should see this once
+def tellme(file=sys.stdout):
+    print >> file, 'hello world'
+
+driver()
+
+# we should not see this at all
+def tellme(file=None):
+    print >> file, 'goodbye universe'
+
+driver()
+
+# syntax errors
+check_syntax('print ,')
+check_syntax('print >> x,')
+
+print 'del_stmt' # 'del' exprlist
+del abc
+del x, y, (z, xyz)
+
+print 'pass_stmt' # 'pass'
+pass
+
+print 'flow_stmt' # break_stmt | continue_stmt | return_stmt | raise_stmt
+# Tested below
+
+print 'break_stmt' # 'break'
+while 1: break
+
+print 'continue_stmt' # 'continue'
+i = 1
+while i: i = 0; continue
+
+msg = ""
+while not msg:
+    msg = "continue + try/except ok"
+    try:
+        continue
+        msg = "continue failed to continue inside try"
+    except:
+        msg = "continue inside try called except block"
+print msg
+
+msg = ""
+while not msg:
+    msg = "finally block not called"
+    try:
+        continue
+    finally:
+        msg = "continue + try/finally ok"
+print msg
+
+
+# This test warrants an explanation. It is a test specifically for SF bugs
+# #463359 and #462937. The bug is that a 'break' statement executed or
+# exception raised inside a try/except inside a loop, *after* a continue
+# statement has been executed in that loop, will cause the wrong number of
+# arguments to be popped off the stack and the instruction pointer reset to
+# a very small number (usually 0.) Because of this, the following test
+# *must* written as a function, and the tracking vars *must* be function
+# arguments with default values. Otherwise, the test will loop and loop.
+
+print "testing continue and break in try/except in loop"
+def test_break_continue_loop(extra_burning_oil = 1, count=0):
+    big_hippo = 2
+    while big_hippo:
+        count += 1
+        try:
+            if extra_burning_oil and big_hippo == 1:
+                extra_burning_oil -= 1
+                break
+            big_hippo -= 1
+            continue
+        except:
+            raise
+    if count > 2 or big_hippo <> 1:
+        print "continue then break in try/except in loop broken!"
+test_break_continue_loop()
+
+print 'return_stmt' # 'return' [testlist]
+def g1(): return
+def g2(): return 1
+g1()
+x = g2()
+check_syntax("class foo:return 1")
+
+print 'yield_stmt'
+check_syntax("class foo:yield 1")
+
+print 'raise_stmt' # 'raise' test [',' test]
+try: raise RuntimeError, 'just testing'
+except RuntimeError: pass
+try: raise KeyboardInterrupt
+except KeyboardInterrupt: pass
+
+print 'import_name' # 'import' dotted_as_names
+import sys
+import time, sys
+print 'import_from' # 'from' dotted_name 'import' ('*' | '(' import_as_names ')' | import_as_names)
+from time import time
+from time import (time)
+from sys import *
+from sys import path, argv
+from sys import (path, argv)
+from sys import (path, argv,)
+
+print 'global_stmt' # 'global' NAME (',' NAME)*
+def f():
+    global a
+    global a, b
+    global one, two, three, four, five, six, seven, eight, nine, ten
+
+print 'exec_stmt' # 'exec' expr ['in' expr [',' expr]]
+def f():
+    z = None
+    del z
+    exec 'z=1+1\n'
+    if z != 2: raise TestFailed, 'exec \'z=1+1\'\\n'
+    del z
+    exec 'z=1+1'
+    if z != 2: raise TestFailed, 'exec \'z=1+1\''
+    z = None
+    del z
+    import types
+    if hasattr(types, "UnicodeType"):
+        exec r"""if 1:
+    exec u'z=1+1\n'
+    if z != 2: raise TestFailed, 'exec u\'z=1+1\'\\n'
+    del z
+    exec u'z=1+1'
+    if z != 2: raise TestFailed, 'exec u\'z=1+1\''
+"""
+f()
+g = {}
+exec 'z = 1' in g
+if g.has_key('__builtins__'): del g['__builtins__']
+if g != {'z': 1}: raise TestFailed, 'exec \'z = 1\' in g'
+g = {}
+l = {}
+
+import warnings
+warnings.filterwarnings("ignore", "global statement", module="<string>")
+exec 'global a; a = 1; b = 2' in g, l
+if g.has_key('__builtins__'): del g['__builtins__']
+if l.has_key('__builtins__'): del l['__builtins__']
+if (g, l) != ({'a':1}, {'b':2}): raise TestFailed, 'exec ... in g (%s), l (%s)' %(g,l)
+
+
+print "assert_stmt" # assert_stmt: 'assert' test [',' test]
+assert 1
+assert 1, 1
+assert lambda x:x
+assert 1, lambda x:x+1
+
+### compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef
+# Tested below
+
+print 'if_stmt' # 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
+if 1: pass
+if 1: pass
+else: pass
+if 0: pass
+elif 0: pass
+if 0: pass
+elif 0: pass
+elif 0: pass
+elif 0: pass
+else: pass
+
+print 'while_stmt' # 'while' test ':' suite ['else' ':' suite]
+while 0: pass
+while 0: pass
+else: pass
+
+print 'for_stmt' # 'for' exprlist 'in' exprlist ':' suite ['else' ':' suite]
+for i in 1, 2, 3: pass
+for i, j, k in (): pass
+else: pass
+class Squares:
+    def __init__(self, max):
+        self.max = max
+        self.sofar = []
+    def __len__(self): return len(self.sofar)
+    def __getitem__(self, i):
+        if not 0 <= i < self.max: raise IndexError
+        n = len(self.sofar)
+        while n <= i:
+            self.sofar.append(n*n)
+            n = n+1
+        return self.sofar[i]
+n = 0
+for x in Squares(10): n = n+x
+if n != 285: raise TestFailed, 'for over growing sequence'
+
+result = []
+for x, in [(1,), (2,), (3,)]:
+    result.append(x)
+vereq(result, [1, 2, 3])
+
+print 'try_stmt'
+### try_stmt: 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite]
+###         | 'try' ':' suite 'finally' ':' suite
+### except_clause: 'except' [expr [',' expr]]
+try:
+    1/0
+except ZeroDivisionError:
+    pass
+else:
+    pass
+try: 1/0
+except EOFError: pass
+except TypeError, msg: pass
+except RuntimeError, msg: pass
+except: pass
+else: pass
+try: 1/0
+except (EOFError, TypeError, ZeroDivisionError): pass
+try: 1/0
+except (EOFError, TypeError, ZeroDivisionError), msg: pass
+try: pass
+finally: pass
+
+print 'suite' # simple_stmt | NEWLINE INDENT NEWLINE* (stmt NEWLINE*)+ DEDENT
+if 1: pass
+if 1:
+    pass
+if 1:
+    #
+    #
+    #
+    pass
+    pass
+    #
+    pass
+    #
+
+print 'test'
+### and_test ('or' and_test)*
+### and_test: not_test ('and' not_test)*
+### not_test: 'not' not_test | comparison
+if not 1: pass
+if 1 and 1: pass
+if 1 or 1: pass
+if not not not 1: pass
+if not 1 and 1 and 1: pass
+if 1 and 1 or 1 and 1 and 1 or not 1 and 1: pass
+
+print 'comparison'
+### comparison: expr (comp_op expr)*
+### comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not'
+if 1: pass
+x = (1 == 1)
+if 1 == 1: pass
+if 1 != 1: pass
+if 1 <> 1: pass
+if 1 < 1: pass
+if 1 > 1: pass
+if 1 <= 1: pass
+if 1 >= 1: pass
+if 1 is 1: pass
+if 1 is not 1: pass
+if 1 in (): pass
+if 1 not in (): pass
+if 1 < 1 > 1 == 1 >= 1 <= 1 <> 1 != 1 in 1 not in 1 is 1 is not 1: pass
+
+print 'binary mask ops'
+x = 1 & 1
+x = 1 ^ 1
+x = 1 | 1
+
+print 'shift ops'
+x = 1 << 1
+x = 1 >> 1
+x = 1 << 1 >> 1
+
+print 'additive ops'
+x = 1
+x = 1 + 1
+x = 1 - 1 - 1
+x = 1 - 1 + 1 - 1 + 1
+
+print 'multiplicative ops'
+x = 1 * 1
+x = 1 / 1
+x = 1 % 1
+x = 1 / 1 * 1 % 1
+
+print 'unary ops'
+x = +1
+x = -1
+x = ~1
+x = ~1 ^ 1 & 1 | 1 & 1 ^ -1
+x = -1*1/1 + 1*1 - ---1*1
+
+print 'selectors'
+### trailer: '(' [testlist] ')' | '[' subscript ']' | '.' NAME
+### subscript: expr | [expr] ':' [expr]
+f1()
+f2(1)
+f2(1,)
+f3(1, 2)
+f3(1, 2,)
+f4(1, (2, (3, 4)))
+v0()
+v0(1)
+v0(1,)
+v0(1,2)
+v0(1,2,3,4,5,6,7,8,9,0)
+v1(1)
+v1(1,)
+v1(1,2)
+v1(1,2,3)
+v1(1,2,3,4,5,6,7,8,9,0)
+v2(1,2)
+v2(1,2,3)
+v2(1,2,3,4)
+v2(1,2,3,4,5,6,7,8,9,0)
+v3(1,(2,3))
+v3(1,(2,3),4)
+v3(1,(2,3),4,5,6,7,8,9,0)
+print
+import sys, time
+c = sys.path[0]
+x = time.time()
+x = sys.modules['time'].time()
+a = '01234'
+c = a[0]
+c = a[-1]
+s = a[0:5]
+s = a[:5]
+s = a[0:]
+s = a[:]
+s = a[-5:]
+s = a[:-1]
+s = a[-4:-3]
+# A rough test of SF bug 1333982.  http://python.org/sf/1333982
+# The testing here is fairly incomplete.
+# Test cases should include: commas with 1 and 2 colons
+d = {}
+d[1] = 1
+d[1,] = 2
+d[1,2] = 3
+d[1,2,3] = 4
+L = list(d)
+L.sort()
+print L
+
+
+print 'atoms'
+### atom: '(' [testlist] ')' | '[' [testlist] ']' | '{' [dictmaker] '}' | '`' testlist '`' | NAME | NUMBER | STRING
+### dictmaker: test ':' test (',' test ':' test)* [',']
+
+x = (1)
+x = (1 or 2 or 3)
+x = (1 or 2 or 3, 2, 3)
+
+x = []
+x = [1]
+x = [1 or 2 or 3]
+x = [1 or 2 or 3, 2, 3]
+x = []
+
+x = {}
+x = {'one': 1}
+x = {'one': 1,}
+x = {'one' or 'two': 1 or 2}
+x = {'one': 1, 'two': 2}
+x = {'one': 1, 'two': 2,}
+x = {'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5, 'six': 6}
+
+x = `x`
+x = `1 or 2 or 3`
+x = `1,2`
+x = x
+x = 'x'
+x = 123
+
+### exprlist: expr (',' expr)* [',']
+### testlist: test (',' test)* [',']
+# These have been exercised enough above
+
+print 'classdef' # 'class' NAME ['(' [testlist] ')'] ':' suite
+class B: pass
+class B2(): pass
+class C1(B): pass
+class C2(B): pass
+class D(C1, C2, B): pass
+class C:
+    def meth1(self): pass
+    def meth2(self, arg): pass
+    def meth3(self, a1, a2): pass
+
+# list comprehension tests
+nums = [1, 2, 3, 4, 5]
+strs = ["Apple", "Banana", "Coconut"]
+spcs = ["  Apple", " Banana ", "Coco  nut  "]
+
+print [s.strip() for s in spcs]
+print [3 * x for x in nums]
+print [x for x in nums if x > 2]
+print [(i, s) for i in nums for s in strs]
+print [(i, s) for i in nums for s in [f for f in strs if "n" in f]]
+print [(lambda a:[a**i for i in range(a+1)])(j) for j in range(5)]
+
+def test_in_func(l):
+    return [None < x < 3 for x in l if x > 2]
+
+print test_in_func(nums)
+
+def test_nested_front():
+    print [[y for y in [x, x + 1]] for x in [1,3,5]]
+
+test_nested_front()
+
+check_syntax("[i, s for i in nums for s in strs]")
+check_syntax("[x if y]")
+
+suppliers = [
+  (1, "Boeing"),
+  (2, "Ford"),
+  (3, "Macdonalds")
+]
+
+parts = [
+  (10, "Airliner"),
+  (20, "Engine"),
+  (30, "Cheeseburger")
+]
+
+suppart = [
+  (1, 10), (1, 20), (2, 20), (3, 30)
+]
+
+print [
+  (sname, pname)
+    for (sno, sname) in suppliers
+      for (pno, pname) in parts
+        for (sp_sno, sp_pno) in suppart
+          if sno == sp_sno and pno == sp_pno
+]
+
+# generator expression tests
+g = ([x for x in range(10)] for x in range(1))
+verify(g.next() == [x for x in range(10)])
+try:
+    g.next()
+    raise TestFailed, 'should produce StopIteration exception'
+except StopIteration:
+    pass
+
+a = 1
+try:
+    g = (a for d in a)
+    g.next()
+    raise TestFailed, 'should produce TypeError'
+except TypeError:
+    pass
+
+verify(list((x, y) for x in 'abcd' for y in 'abcd') == [(x, y) for x in 'abcd' for y in 'abcd'])
+verify(list((x, y) for x in 'ab' for y in 'xy') == [(x, y) for x in 'ab' for y in 'xy'])
+
+a = [x for x in range(10)]
+b = (x for x in (y for y in a))
+verify(sum(b) == sum([x for x in range(10)]))
+
+verify(sum(x**2 for x in range(10)) == sum([x**2 for x in range(10)]))
+verify(sum(x*x for x in range(10) if x%2) == sum([x*x for x in range(10) if x%2]))
+verify(sum(x for x in (y for y in range(10))) == sum([x for x in range(10)]))
+verify(sum(x for x in (y for y in (z for z in range(10)))) == sum([x for x in range(10)]))
+verify(sum(x for x in [y for y in (z for z in range(10))]) == sum([x for x in range(10)]))
+verify(sum(x for x in (y for y in (z for z in range(10) if True)) if True) == sum([x for x in range(10)]))
+verify(sum(x for x in (y for y in (z for z in range(10) if True) if False) if True) == 0)
+check_syntax("foo(x for x in range(10), 100)")
+check_syntax("foo(100, x for x in range(10))")
+
+# test for outmost iterable precomputation
+x = 10; g = (i for i in range(x)); x = 5
+verify(len(list(g)) == 10)
+
+# This should hold, since we're only precomputing outmost iterable.
+x = 10; t = False; g = ((i,j) for i in range(x) if t for j in range(x))
+x = 5; t = True;
+verify([(i,j) for i in range(10) for j in range(5)] == list(g))
+
+# Grammar allows multiple adjacent 'if's in listcomps and genexps,
+# even though it's silly. Make sure it works (ifelse broke this.)
+verify([ x for x in range(10) if x % 2 if x % 3 ], [1, 5, 7])
+verify((x for x in range(10) if x % 2 if x % 3), [1, 5, 7])
+
+# Verify unpacking single element tuples in listcomp/genexp.
+vereq([x for x, in [(4,), (5,), (6,)]], [4, 5, 6])
+vereq(list(x for x, in [(7,), (8,), (9,)]), [7, 8, 9])
+
+# Test ifelse expressions in various cases
+def _checkeval(msg, ret):
+    "helper to check that evaluation of expressions is done correctly"
+    print x
+    return ret
+
+verify([ x() for x in lambda: True, lambda: False if x() ] == [True])
+verify([ x() for x in (lambda: True, lambda: False) if x() ] == [True])
+verify([ x(False) for x in (lambda x: False if x else True, lambda x: True if x else False) if x(False) ] == [True])
+verify((5 if 1 else _checkeval("check 1", 0)) == 5)
+verify((_checkeval("check 2", 0) if 0 else 5) == 5)
+verify((5 and 6 if 0 else 1) == 1)
+verify(((5 and 6) if 0 else 1) == 1)
+verify((5 and (6 if 1 else 1)) == 6)
+verify((0 or _checkeval("check 3", 2) if 0 else 3) == 3)
+verify((1 or _checkeval("check 4", 2) if 1 else _checkeval("check 5", 3)) == 1)
+verify((0 or 5 if 1 else _checkeval("check 6", 3)) == 5)
+verify((not 5 if 1 else 1) == False)
+verify((not 5 if 0 else 1) == 1)
+verify((6 + 1 if 1 else 2) == 7)
+verify((6 - 1 if 1 else 2) == 5)
+verify((6 * 2 if 1 else 4) == 12)
+verify((6 / 2 if 1 else 3) == 3)
+verify((6 < 4 if 0 else 2) == 2)

Added: vendor/Python/current/Lib/test/test_grp.py
===================================================================
--- vendor/Python/current/Lib/test/test_grp.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_grp.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,89 @@
+"""Test script for the grp module."""
+
+import grp
+import unittest
+from test import test_support
+
+class GroupDatabaseTestCase(unittest.TestCase):
+
+    def check_value(self, value):
+        # check that a grp tuple has the entries and
+        # attributes promised by the docs
+        self.assertEqual(len(value), 4)
+        self.assertEqual(value[0], value.gr_name)
+        self.assert_(isinstance(value.gr_name, basestring))
+        self.assertEqual(value[1], value.gr_passwd)
+        self.assert_(isinstance(value.gr_passwd, basestring))
+        self.assertEqual(value[2], value.gr_gid)
+        self.assert_(isinstance(value.gr_gid, int))
+        self.assertEqual(value[3], value.gr_mem)
+        self.assert_(isinstance(value.gr_mem, list))
+
+    def test_values(self):
+        entries = grp.getgrall()
+
+        for e in entries:
+            self.check_value(e)
+
+        for e in entries:
+            e2 = grp.getgrgid(e.gr_gid)
+            self.check_value(e2)
+            self.assertEqual(e2.gr_gid, e.gr_gid)
+            e2 = grp.getgrnam(e.gr_name)
+            self.check_value(e2)
+            # There are instances where getgrall() returns group names in
+            # lowercase while getgrgid() returns proper casing.
+            # Discovered on Ubuntu 5.04 (custom).
+            self.assertEqual(e2.gr_name.lower(), e.gr_name.lower())
+
+    def test_errors(self):
+        self.assertRaises(TypeError, grp.getgrgid)
+        self.assertRaises(TypeError, grp.getgrnam)
+        self.assertRaises(TypeError, grp.getgrall, 42)
+
+        # try to get some errors
+        bynames = {}
+        bygids = {}
+        for (n, p, g, mem) in grp.getgrall():
+            if not n or n == '+':
+                continue # skip NIS entries etc.
+            bynames[n] = g
+            bygids[g] = n
+
+        allnames = bynames.keys()
+        namei = 0
+        fakename = allnames[namei]
+        while fakename in bynames:
+            chars = map(None, fakename)
+            for i in xrange(len(chars)):
+                if chars[i] == 'z':
+                    chars[i] = 'A'
+                    break
+                elif chars[i] == 'Z':
+                    continue
+                else:
+                    chars[i] = chr(ord(chars[i]) + 1)
+                    break
+            else:
+                namei = namei + 1
+                try:
+                    fakename = allnames[namei]
+                except IndexError:
+                    # should never happen... if so, just forget it
+                    break
+            fakename = ''.join(map(None, chars))
+
+        self.assertRaises(KeyError, grp.getgrnam, fakename)
+
+        # Choose a non-existent gid.
+        fakegid = 4127
+        while fakegid in bygids:
+            fakegid = (fakegid * 3) % 0x10000
+
+        self.assertRaises(KeyError, grp.getgrgid, fakegid)
+
+def test_main():
+    test_support.run_unittest(GroupDatabaseTestCase)
+
+if __name__ == "__main__":
+    test_main()


Property changes on: vendor/Python/current/Lib/test/test_grp.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/test/test_gzip.py
===================================================================
--- vendor/Python/current/Lib/test/test_gzip.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_gzip.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,149 @@
+#! /usr/bin/env python
+"""Test script for the gzip module.
+"""
+
+import unittest
+from test import test_support
+import sys, os
+import gzip
+
+
+data1 = """  int length=DEFAULTALLOC, err = Z_OK;
+  PyObject *RetVal;
+  int flushmode = Z_FINISH;
+  unsigned long start_total_out;
+
+"""
+
+data2 = """/* zlibmodule.c -- gzip-compatible data compression */
+/* See http://www.gzip.org/zlib/
+/* See http://www.winimage.com/zLibDll for Windows */
+"""
+
+
+class TestGzip(unittest.TestCase):
+    filename = test_support.TESTFN
+
+    def setUp (self):
+        pass
+
+    def tearDown (self):
+        try:
+            os.unlink(self.filename)
+        except os.error:
+            pass
+
+
+    def test_write (self):
+        f = gzip.GzipFile(self.filename, 'wb') ; f.write(data1 * 50)
+
+        # Try flush and fileno.
+        f.flush()
+        f.fileno()
+        if hasattr(os, 'fsync'):
+            os.fsync(f.fileno())
+        f.close()
+
+    def test_read(self):
+        self.test_write()
+        # Try reading.
+        f = gzip.GzipFile(self.filename, 'r') ; d = f.read() ; f.close()
+        self.assertEqual(d, data1*50)
+
+    def test_append(self):
+        self.test_write()
+        # Append to the previous file
+        f = gzip.GzipFile(self.filename, 'ab') ; f.write(data2 * 15) ; f.close()
+
+        f = gzip.GzipFile(self.filename, 'rb') ; d = f.read() ; f.close()
+        self.assertEqual(d, (data1*50) + (data2*15))
+
+    def test_many_append(self):
+        # Bug #1074261 was triggered when reading a file that contained
+        # many, many members.  Create such a file and verify that reading it
+        # works.
+        f = gzip.open(self.filename, 'wb', 9)
+        f.write('a')
+        f.close()
+        for i in range(0,200):
+            f = gzip.open(self.filename, "ab", 9) # append
+            f.write('a')
+            f.close()
+
+        # Try reading the file
+        zgfile = gzip.open(self.filename, "rb")
+        contents = ""
+        while 1:
+            ztxt = zgfile.read(8192)
+            contents += ztxt
+            if not ztxt: break
+        zgfile.close()
+        self.assertEquals(contents, 'a'*201)
+
+
+    def test_readline(self):
+        self.test_write()
+        # Try .readline() with varying line lengths
+
+        f = gzip.GzipFile(self.filename, 'rb')
+        line_length = 0
+        while 1:
+            L = f.readline(line_length)
+            if L == "" and line_length != 0: break
+            self.assert_(len(L) <= line_length)
+            line_length = (line_length + 1) % 50
+        f.close()
+
+    def test_readlines(self):
+        self.test_write()
+        # Try .readlines()
+
+        f = gzip.GzipFile(self.filename, 'rb')
+        L = f.readlines()
+        f.close()
+
+        f = gzip.GzipFile(self.filename, 'rb')
+        while 1:
+            L = f.readlines(150)
+            if L == []: break
+        f.close()
+
+    def test_seek_read(self):
+        self.test_write()
+        # Try seek, read test
+
+        f = gzip.GzipFile(self.filename)
+        while 1:
+            oldpos = f.tell()
+            line1 = f.readline()
+            if not line1: break
+            newpos = f.tell()
+            f.seek(oldpos)  # negative seek
+            if len(line1)>10:
+                amount = 10
+            else:
+                amount = len(line1)
+            line2 = f.read(amount)
+            self.assertEqual(line1[:amount], line2)
+            f.seek(newpos)  # positive seek
+        f.close()
+
+    def test_seek_write(self):
+        # Try seek, write test
+        f = gzip.GzipFile(self.filename, 'w')
+        for pos in range(0, 256, 16):
+            f.seek(pos)
+            f.write('GZ\n')
+        f.close()
+
+    def test_mode(self):
+        self.test_write()
+        f = gzip.GzipFile(self.filename, 'r')
+        self.assertEqual(f.myfileobj.mode, 'rb')
+        f.close()
+
+def test_main(verbose=None):
+    test_support.run_unittest(TestGzip)
+
+if __name__ == "__main__":
+    test_main(verbose=True)

Added: vendor/Python/current/Lib/test/test_hash.py
===================================================================
--- vendor/Python/current/Lib/test/test_hash.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_hash.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,36 @@
+# test the invariant that
+#   iff a==b then hash(a)==hash(b)
+#
+
+import unittest
+from test import test_support
+
+
+class HashEqualityTestCase(unittest.TestCase):
+
+    def same_hash(self, *objlist):
+        # Hash each object given and fail if
+        # the hash values are not all the same.
+        hashed = map(hash, objlist)
+        for h in hashed[1:]:
+            if h != hashed[0]:
+                self.fail("hashed values differ: %r" % (objlist,))
+
+    def test_numeric_literals(self):
+        self.same_hash(1, 1L, 1.0, 1.0+0.0j)
+
+    def test_coerced_integers(self):
+        self.same_hash(int(1), long(1), float(1), complex(1),
+                       int('1'), float('1.0'))
+
+    def test_coerced_floats(self):
+        self.same_hash(long(1.23e300), float(1.23e300))
+        self.same_hash(float(0.5), complex(0.5, 0.0))
+
+
+def test_main():
+    test_support.run_unittest(HashEqualityTestCase)
+
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_hashlib.py
===================================================================
--- vendor/Python/current/Lib/test/test_hashlib.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_hashlib.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,191 @@
+# Test hashlib module
+#
+# $Id: test_hashlib.py 39316 2005-08-21 18:45:59Z greg $
+#
+#  Copyright (C) 2005   Gregory P. Smith (greg at electricrain.com)
+#  Licensed to PSF under a Contributor Agreement.
+#
+
+import hashlib
+import unittest
+from test import test_support
+
+
+def hexstr(s):
+    import string
+    h = string.hexdigits
+    r = ''
+    for c in s:
+        i = ord(c)
+        r = r + h[(i >> 4) & 0xF] + h[i & 0xF]
+    return r
+
+
+class HashLibTestCase(unittest.TestCase):
+    supported_hash_names = ( 'md5', 'MD5', 'sha1', 'SHA1',
+                             'sha224', 'SHA224', 'sha256', 'SHA256',
+                             'sha384', 'SHA384', 'sha512', 'SHA512' )
+
+    def test_unknown_hash(self):
+        try:
+            hashlib.new('spam spam spam spam spam')
+        except ValueError:
+            pass
+        else:
+            self.assert_(0 == "hashlib didn't reject bogus hash name")
+
+    def test_hexdigest(self):
+        for name in self.supported_hash_names:
+            h = hashlib.new(name)
+            self.assert_(hexstr(h.digest()) == h.hexdigest())
+
+
+    def test_large_update(self):
+        aas = 'a' * 128
+        bees = 'b' * 127
+        cees = 'c' * 126
+
+        for name in self.supported_hash_names:
+            m1 = hashlib.new(name)
+            m1.update(aas)
+            m1.update(bees)
+            m1.update(cees)
+
+            m2 = hashlib.new(name)
+            m2.update(aas + bees + cees)
+            self.assertEqual(m1.digest(), m2.digest())
+
+
+    def check(self, name, data, digest):
+        # test the direct constructors
+        computed = getattr(hashlib, name)(data).hexdigest()
+        self.assert_(computed == digest)
+        # test the general new() interface
+        computed = hashlib.new(name, data).hexdigest()
+        self.assert_(computed == digest)
+
+
+    def test_case_md5_0(self):
+        self.check('md5', '', 'd41d8cd98f00b204e9800998ecf8427e')
+
+    def test_case_md5_1(self):
+        self.check('md5', 'abc', '900150983cd24fb0d6963f7d28e17f72')
+
+    def test_case_md5_2(self):
+        self.check('md5', 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',
+                   'd174ab98d277d9f5a5611c2c9f419d9f')
+
+
+    # use the three examples from Federal Information Processing Standards
+    # Publication 180-1, Secure Hash Standard,  1995 April 17
+    # http://www.itl.nist.gov/div897/pubs/fip180-1.htm
+
+    def test_case_sha1_0(self):
+        self.check('sha1', "",
+                   "da39a3ee5e6b4b0d3255bfef95601890afd80709")
+
+    def test_case_sha1_1(self):
+        self.check('sha1', "abc",
+                   "a9993e364706816aba3e25717850c26c9cd0d89d")
+
+    def test_case_sha1_2(self):
+        self.check('sha1', "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+                   "84983e441c3bd26ebaae4aa1f95129e5e54670f1")
+
+    def test_case_sha1_3(self):
+        self.check('sha1', "a" * 1000000,
+                   "34aa973cd4c4daa4f61eeb2bdbad27316534016f")
+
+
+    # use the examples from Federal Information Processing Standards
+    # Publication 180-2, Secure Hash Standard,  2002 August 1
+    # http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
+
+    def test_case_sha224_0(self):
+        self.check('sha224', "",
+          "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f")
+
+    def test_case_sha224_1(self):
+        self.check('sha224', "abc",
+          "23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7")
+
+    def test_case_sha224_2(self):
+        self.check('sha224',
+          "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+          "75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525")
+
+    def test_case_sha224_3(self):
+        self.check('sha224', "a" * 1000000,
+          "20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67")
+
+
+    def test_case_sha256_0(self):
+        self.check('sha256', "",
+          "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
+
+    def test_case_sha256_1(self):
+        self.check('sha256', "abc",
+          "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad")
+
+    def test_case_sha256_2(self):
+        self.check('sha256',
+          "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+          "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1")
+
+    def test_case_sha256_3(self):
+        self.check('sha256', "a" * 1000000,
+          "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0")
+
+
+    def test_case_sha384_0(self):
+        self.check('sha384', "",
+          "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da"+
+          "274edebfe76f65fbd51ad2f14898b95b")
+
+    def test_case_sha384_1(self):
+        self.check('sha384', "abc",
+          "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed"+
+          "8086072ba1e7cc2358baeca134c825a7")
+
+    def test_case_sha384_2(self):
+        self.check('sha384',
+                   "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"+
+                   "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
+          "09330c33f71147e83d192fc782cd1b4753111b173b3b05d22fa08086e3b0f712"+
+          "fcc7c71a557e2db966c3e9fa91746039")
+
+    def test_case_sha384_3(self):
+        self.check('sha384', "a" * 1000000,
+          "9d0e1809716474cb086e834e310a4a1ced149e9c00f248527972cec5704c2a5b"+
+          "07b8b3dc38ecc4ebae97ddd87f3d8985")
+
+
+    def test_case_sha512_0(self):
+        self.check('sha512', "",
+          "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce"+
+          "47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e")
+
+    def test_case_sha512_1(self):
+        self.check('sha512', "abc",
+          "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a"+
+          "2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f")
+
+    def test_case_sha512_2(self):
+        self.check('sha512',
+                   "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"+
+                   "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
+          "8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018"+
+          "501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909")
+
+    def test_case_sha512_3(self):
+        self.check('sha512', "a" * 1000000,
+          "e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973eb"+
+          "de0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b")
+
+
+def test_main():
+    test_support.run_unittest(HashLibTestCase)
+
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_heapq.py
===================================================================
--- vendor/Python/current/Lib/test/test_heapq.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_heapq.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,286 @@
+"""Unittests for heapq."""
+
+from heapq import heappush, heappop, heapify, heapreplace, nlargest, nsmallest
+import random
+import unittest
+from test import test_support
+import sys
+
+
+def heapiter(heap):
+    # An iterator returning a heap's elements, smallest-first.
+    try:
+        while 1:
+            yield heappop(heap)
+    except IndexError:
+        pass
+
+class TestHeap(unittest.TestCase):
+
+    def test_push_pop(self):
+        # 1) Push 256 random numbers and pop them off, verifying all's OK.
+        heap = []
+        data = []
+        self.check_invariant(heap)
+        for i in range(256):
+            item = random.random()
+            data.append(item)
+            heappush(heap, item)
+            self.check_invariant(heap)
+        results = []
+        while heap:
+            item = heappop(heap)
+            self.check_invariant(heap)
+            results.append(item)
+        data_sorted = data[:]
+        data_sorted.sort()
+        self.assertEqual(data_sorted, results)
+        # 2) Check that the invariant holds for a sorted array
+        self.check_invariant(results)
+
+        self.assertRaises(TypeError, heappush, [])
+        try:
+            self.assertRaises(TypeError, heappush, None, None)
+            self.assertRaises(TypeError, heappop, None)
+        except AttributeError:
+            pass
+
+    def check_invariant(self, heap):
+        # Check the heap invariant.
+        for pos, item in enumerate(heap):
+            if pos: # pos 0 has no parent
+                parentpos = (pos-1) >> 1
+                self.assert_(heap[parentpos] <= item)
+
+    def test_heapify(self):
+        for size in range(30):
+            heap = [random.random() for dummy in range(size)]
+            heapify(heap)
+            self.check_invariant(heap)
+
+        self.assertRaises(TypeError, heapify, None)
+
+    def test_naive_nbest(self):
+        data = [random.randrange(2000) for i in range(1000)]
+        heap = []
+        for item in data:
+            heappush(heap, item)
+            if len(heap) > 10:
+                heappop(heap)
+        heap.sort()
+        self.assertEqual(heap, sorted(data)[-10:])
+
+    def test_nbest(self):
+        # Less-naive "N-best" algorithm, much faster (if len(data) is big
+        # enough <wink>) than sorting all of data.  However, if we had a max
+        # heap instead of a min heap, it could go faster still via
+        # heapify'ing all of data (linear time), then doing 10 heappops
+        # (10 log-time steps).
+        data = [random.randrange(2000) for i in range(1000)]
+        heap = data[:10]
+        heapify(heap)
+        for item in data[10:]:
+            if item > heap[0]:  # this gets rarer the longer we run
+                heapreplace(heap, item)
+        self.assertEqual(list(heapiter(heap)), sorted(data)[-10:])
+
+        self.assertRaises(TypeError, heapreplace, None)
+        self.assertRaises(TypeError, heapreplace, None, None)
+        self.assertRaises(IndexError, heapreplace, [], None)
+
+    def test_heapsort(self):
+        # Exercise everything with repeated heapsort checks
+        for trial in xrange(100):
+            size = random.randrange(50)
+            data = [random.randrange(25) for i in range(size)]
+            if trial & 1:     # Half of the time, use heapify
+                heap = data[:]
+                heapify(heap)
+            else:             # The rest of the time, use heappush
+                heap = []
+                for item in data:
+                    heappush(heap, item)
+            heap_sorted = [heappop(heap) for i in range(size)]
+            self.assertEqual(heap_sorted, sorted(data))
+
+    def test_nsmallest(self):
+        data = [(random.randrange(2000), i) for i in range(1000)]
+        for f in (None, lambda x:  x[0] * 547 % 2000):
+            for n in (0, 1, 2, 10, 100, 400, 999, 1000, 1100):
+                self.assertEqual(nsmallest(n, data), sorted(data)[:n])
+                self.assertEqual(nsmallest(n, data, key=f),
+                                 sorted(data, key=f)[:n])
+
+    def test_nlargest(self):
+        data = [(random.randrange(2000), i) for i in range(1000)]
+        for f in (None, lambda x:  x[0] * 547 % 2000):
+            for n in (0, 1, 2, 10, 100, 400, 999, 1000, 1100):
+                self.assertEqual(nlargest(n, data), sorted(data, reverse=True)[:n])
+                self.assertEqual(nlargest(n, data, key=f),
+                                 sorted(data, key=f, reverse=True)[:n])
+
+
+#==============================================================================
+
+class LenOnly:
+    "Dummy sequence class defining __len__ but not __getitem__."
+    def __len__(self):
+        return 10
+
+class GetOnly:
+    "Dummy sequence class defining __getitem__ but not __len__."
+    def __getitem__(self, ndx):
+        return 10
+
+class CmpErr:
+    "Dummy element that always raises an error during comparison"
+    def __cmp__(self, other):
+        raise ZeroDivisionError
+
+def R(seqn):
+    'Regular generator'
+    for i in seqn:
+        yield i
+
+class G:
+    'Sequence using __getitem__'
+    def __init__(self, seqn):
+        self.seqn = seqn
+    def __getitem__(self, i):
+        return self.seqn[i]
+
+class I:
+    'Sequence using iterator protocol'
+    def __init__(self, seqn):
+        self.seqn = seqn
+        self.i = 0
+    def __iter__(self):
+        return self
+    def next(self):
+        if self.i >= len(self.seqn): raise StopIteration
+        v = self.seqn[self.i]
+        self.i += 1
+        return v
+
+class Ig:
+    'Sequence using iterator protocol defined with a generator'
+    def __init__(self, seqn):
+        self.seqn = seqn
+        self.i = 0
+    def __iter__(self):
+        for val in self.seqn:
+            yield val
+
+class X:
+    'Missing __getitem__ and __iter__'
+    def __init__(self, seqn):
+        self.seqn = seqn
+        self.i = 0
+    def next(self):
+        if self.i >= len(self.seqn): raise StopIteration
+        v = self.seqn[self.i]
+        self.i += 1
+        return v
+
+class N:
+    'Iterator missing next()'
+    def __init__(self, seqn):
+        self.seqn = seqn
+        self.i = 0
+    def __iter__(self):
+        return self
+
+class E:
+    'Test propagation of exceptions'
+    def __init__(self, seqn):
+        self.seqn = seqn
+        self.i = 0
+    def __iter__(self):
+        return self
+    def next(self):
+        3 // 0
+
+class S:
+    'Test immediate stop'
+    def __init__(self, seqn):
+        pass
+    def __iter__(self):
+        return self
+    def next(self):
+        raise StopIteration
+
+from itertools import chain, imap
+def L(seqn):
+    'Test multiple tiers of iterators'
+    return chain(imap(lambda x:x, R(Ig(G(seqn)))))
+
+class TestErrorHandling(unittest.TestCase):
+
+    def test_non_sequence(self):
+        for f in (heapify, heappop):
+            self.assertRaises(TypeError, f, 10)
+        for f in (heappush, heapreplace, nlargest, nsmallest):
+            self.assertRaises(TypeError, f, 10, 10)
+
+    def test_len_only(self):
+        for f in (heapify, heappop):
+            self.assertRaises(TypeError, f, LenOnly())
+        for f in (heappush, heapreplace):
+            self.assertRaises(TypeError, f, LenOnly(), 10)
+        for f in (nlargest, nsmallest):
+            self.assertRaises(TypeError, f, 2, LenOnly())
+
+    def test_get_only(self):
+        for f in (heapify, heappop):
+            self.assertRaises(TypeError, f, GetOnly())
+        for f in (heappush, heapreplace):
+            self.assertRaises(TypeError, f, GetOnly(), 10)
+        for f in (nlargest, nsmallest):
+            self.assertRaises(TypeError, f, 2, GetOnly())
+
+    def test_get_only(self):
+        seq = [CmpErr(), CmpErr(), CmpErr()]
+        for f in (heapify, heappop):
+            self.assertRaises(ZeroDivisionError, f, seq)
+        for f in (heappush, heapreplace):
+            self.assertRaises(ZeroDivisionError, f, seq, 10)
+        for f in (nlargest, nsmallest):
+            self.assertRaises(ZeroDivisionError, f, 2, seq)
+
+    def test_arg_parsing(self):
+        for f in (heapify, heappop, heappush, heapreplace, nlargest, nsmallest):
+            self.assertRaises(TypeError, f, 10)
+
+    def test_iterable_args(self):
+        for f in  (nlargest, nsmallest):
+            for s in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5)):
+                for g in (G, I, Ig, L, R):
+                    self.assertEqual(f(2, g(s)), f(2,s))
+                self.assertEqual(f(2, S(s)), [])
+                self.assertRaises(TypeError, f, 2, X(s))
+                self.assertRaises(TypeError, f, 2, N(s))
+                self.assertRaises(ZeroDivisionError, f, 2, E(s))
+
+#==============================================================================
+
+
+def test_main(verbose=None):
+    from types import BuiltinFunctionType
+
+    test_classes = [TestHeap]
+    if isinstance(heapify, BuiltinFunctionType):
+        test_classes.append(TestErrorHandling)
+    test_support.run_unittest(*test_classes)
+
+    # verify reference counting
+    if verbose and hasattr(sys, "gettotalrefcount"):
+        import gc
+        counts = [None] * 5
+        for i in xrange(len(counts)):
+            test_support.run_unittest(*test_classes)
+            gc.collect()
+            counts[i] = sys.gettotalrefcount()
+        print counts
+
+if __name__ == "__main__":
+    test_main(verbose=True)

Added: vendor/Python/current/Lib/test/test_hexoct.py
===================================================================
--- vendor/Python/current/Lib/test/test_hexoct.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_hexoct.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,116 @@
+"""Test correct treatment of hex/oct constants.
+
+This is complex because of changes due to PEP 237.
+"""
+
+import sys
+platform_long_is_32_bits = sys.maxint == 2147483647
+
+import unittest
+from test import test_support
+
+import warnings
+warnings.filterwarnings("ignore", "hex/oct constants", FutureWarning,
+                        "<string>")
+
+class TextHexOct(unittest.TestCase):
+
+    def test_hex_baseline(self):
+        # Baseline tests
+        self.assertEqual(0x0, 0)
+        self.assertEqual(0x10, 16)
+        if platform_long_is_32_bits:
+            self.assertEqual(0x7fffffff, 2147483647)
+        else:
+            self.assertEqual(0x7fffffffffffffff, 9223372036854775807)
+        # Ditto with a minus sign and parentheses
+        self.assertEqual(-(0x0), 0)
+        self.assertEqual(-(0x10), -16)
+        if platform_long_is_32_bits:
+            self.assertEqual(-(0x7fffffff), -2147483647)
+        else:
+            self.assertEqual(-(0x7fffffffffffffff), -9223372036854775807)
+        # Ditto with a minus sign and NO parentheses
+        self.assertEqual(-0x0, 0)
+        self.assertEqual(-0x10, -16)
+        if platform_long_is_32_bits:
+            self.assertEqual(-0x7fffffff, -2147483647)
+        else:
+            self.assertEqual(-0x7fffffffffffffff, -9223372036854775807)
+
+    def test_hex_unsigned(self):
+        if platform_long_is_32_bits:
+            # Positive constants
+            self.assertEqual(0x80000000, 2147483648L)
+            self.assertEqual(0xffffffff, 4294967295L)
+            # Ditto with a minus sign and parentheses
+            self.assertEqual(-(0x80000000), -2147483648L)
+            self.assertEqual(-(0xffffffff), -4294967295L)
+            # Ditto with a minus sign and NO parentheses
+            # This failed in Python 2.2 through 2.2.2 and in 2.3a1
+            self.assertEqual(-0x80000000, -2147483648L)
+            self.assertEqual(-0xffffffff, -4294967295L)
+        else:
+            # Positive constants
+            self.assertEqual(0x8000000000000000, 9223372036854775808L)
+            self.assertEqual(0xffffffffffffffff, 18446744073709551615L)
+            # Ditto with a minus sign and parentheses
+            self.assertEqual(-(0x8000000000000000), -9223372036854775808L)
+            self.assertEqual(-(0xffffffffffffffff), -18446744073709551615L)
+            # Ditto with a minus sign and NO parentheses
+            # This failed in Python 2.2 through 2.2.2 and in 2.3a1
+            self.assertEqual(-0x8000000000000000, -9223372036854775808L)
+            self.assertEqual(-0xffffffffffffffff, -18446744073709551615L)
+
+    def test_oct_baseline(self):
+        # Baseline tests
+        self.assertEqual(00, 0)
+        self.assertEqual(020, 16)
+        if platform_long_is_32_bits:
+            self.assertEqual(017777777777, 2147483647)
+        else:
+            self.assertEqual(0777777777777777777777, 9223372036854775807)
+        # Ditto with a minus sign and parentheses
+        self.assertEqual(-(00), 0)
+        self.assertEqual(-(020), -16)
+        if platform_long_is_32_bits:
+            self.assertEqual(-(017777777777), -2147483647)
+        else:
+            self.assertEqual(-(0777777777777777777777), -9223372036854775807)
+        # Ditto with a minus sign and NO parentheses
+        self.assertEqual(-00, 0)
+        self.assertEqual(-020, -16)
+        if platform_long_is_32_bits:
+            self.assertEqual(-017777777777, -2147483647)
+        else:
+            self.assertEqual(-0777777777777777777777, -9223372036854775807)
+
+    def test_oct_unsigned(self):
+        if platform_long_is_32_bits:
+            # Positive constants
+            self.assertEqual(020000000000, 2147483648L)
+            self.assertEqual(037777777777, 4294967295L)
+            # Ditto with a minus sign and parentheses
+            self.assertEqual(-(020000000000), -2147483648L)
+            self.assertEqual(-(037777777777), -4294967295L)
+            # Ditto with a minus sign and NO parentheses
+            # This failed in Python 2.2 through 2.2.2 and in 2.3a1
+            self.assertEqual(-020000000000, -2147483648L)
+            self.assertEqual(-037777777777, -4294967295L)
+        else:
+            # Positive constants
+            self.assertEqual(01000000000000000000000, 9223372036854775808L)
+            self.assertEqual(01777777777777777777777, 18446744073709551615L)
+            # Ditto with a minus sign and parentheses
+            self.assertEqual(-(01000000000000000000000), -9223372036854775808L)
+            self.assertEqual(-(01777777777777777777777), -18446744073709551615L)
+            # Ditto with a minus sign and NO parentheses
+            # This failed in Python 2.2 through 2.2.2 and in 2.3a1
+            self.assertEqual(-01000000000000000000000, -9223372036854775808L)
+            self.assertEqual(-01777777777777777777777, -18446744073709551615L)
+
+def test_main():
+    test_support.run_unittest(TextHexOct)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_hmac.py
===================================================================
--- vendor/Python/current/Lib/test/test_hmac.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_hmac.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,168 @@
+import hmac
+import sha
+import unittest
+from test import test_support
+
+class TestVectorsTestCase(unittest.TestCase):
+
+    def test_md5_vectors(self):
+        # Test the HMAC module against test vectors from the RFC.
+
+        def md5test(key, data, digest):
+            h = hmac.HMAC(key, data)
+            self.assertEqual(h.hexdigest().upper(), digest.upper())
+
+        md5test(chr(0x0b) * 16,
+                "Hi There",
+                "9294727A3638BB1C13F48EF8158BFC9D")
+
+        md5test("Jefe",
+                "what do ya want for nothing?",
+                "750c783e6ab0b503eaa86e310a5db738")
+
+        md5test(chr(0xAA)*16,
+                chr(0xDD)*50,
+                "56be34521d144c88dbb8c733f0e8b3f6")
+
+        md5test("".join([chr(i) for i in range(1, 26)]),
+                chr(0xCD) * 50,
+                "697eaf0aca3a3aea3a75164746ffaa79")
+
+        md5test(chr(0x0C) * 16,
+                "Test With Truncation",
+                "56461ef2342edc00f9bab995690efd4c")
+
+        md5test(chr(0xAA) * 80,
+                "Test Using Larger Than Block-Size Key - Hash Key First",
+                "6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd")
+
+        md5test(chr(0xAA) * 80,
+                ("Test Using Larger Than Block-Size Key "
+                 "and Larger Than One Block-Size Data"),
+                "6f630fad67cda0ee1fb1f562db3aa53e")
+
+    def test_sha_vectors(self):
+        def shatest(key, data, digest):
+            h = hmac.HMAC(key, data, digestmod=sha)
+            self.assertEqual(h.hexdigest().upper(), digest.upper())
+
+        shatest(chr(0x0b) * 20,
+                "Hi There",
+                "b617318655057264e28bc0b6fb378c8ef146be00")
+
+        shatest("Jefe",
+                "what do ya want for nothing?",
+                "effcdf6ae5eb2fa2d27416d5f184df9c259a7c79")
+
+        shatest(chr(0xAA)*20,
+                chr(0xDD)*50,
+                "125d7342b9ac11cd91a39af48aa17b4f63f175d3")
+
+        shatest("".join([chr(i) for i in range(1, 26)]),
+                chr(0xCD) * 50,
+                "4c9007f4026250c6bc8414f9bf50c86c2d7235da")
+
+        shatest(chr(0x0C) * 20,
+                "Test With Truncation",
+                "4c1a03424b55e07fe7f27be1d58bb9324a9a5a04")
+
+        shatest(chr(0xAA) * 80,
+                "Test Using Larger Than Block-Size Key - Hash Key First",
+                "aa4ae5e15272d00e95705637ce8a3b55ed402112")
+
+        shatest(chr(0xAA) * 80,
+                ("Test Using Larger Than Block-Size Key "
+                 "and Larger Than One Block-Size Data"),
+                "e8e99d0f45237d786d6bbaa7965c7808bbff1a91")
+
+
+class ConstructorTestCase(unittest.TestCase):
+
+    def test_normal(self):
+        # Standard constructor call.
+        failed = 0
+        try:
+            h = hmac.HMAC("key")
+        except:
+            self.fail("Standard constructor call raised exception.")
+
+    def test_withtext(self):
+        # Constructor call with text.
+        try:
+            h = hmac.HMAC("key", "hash this!")
+        except:
+            self.fail("Constructor call with text argument raised exception.")
+
+    def test_withmodule(self):
+        # Constructor call with text and digest module.
+        import sha
+        try:
+            h = hmac.HMAC("key", "", sha)
+        except:
+            self.fail("Constructor call with sha module raised exception.")
+
+class SanityTestCase(unittest.TestCase):
+
+    def test_default_is_md5(self):
+        # Testing if HMAC defaults to MD5 algorithm.
+        # NOTE: this whitebox test depends on the hmac class internals
+        import hashlib
+        h = hmac.HMAC("key")
+        self.failUnless(h.digest_cons == hashlib.md5)
+
+    def test_exercise_all_methods(self):
+        # Exercising all methods once.
+        # This must not raise any exceptions
+        try:
+            h = hmac.HMAC("my secret key")
+            h.update("compute the hash of this text!")
+            dig = h.digest()
+            dig = h.hexdigest()
+            h2 = h.copy()
+        except:
+            self.fail("Exception raised during normal usage of HMAC class.")
+
+class CopyTestCase(unittest.TestCase):
+
+    def test_attributes(self):
+        # Testing if attributes are of same type.
+        h1 = hmac.HMAC("key")
+        h2 = h1.copy()
+        self.failUnless(h1.digest_cons == h2.digest_cons,
+            "digest constructors don't match.")
+        self.failUnless(type(h1.inner) == type(h2.inner),
+            "Types of inner don't match.")
+        self.failUnless(type(h1.outer) == type(h2.outer),
+            "Types of outer don't match.")
+
+    def test_realcopy(self):
+        # Testing if the copy method created a real copy.
+        h1 = hmac.HMAC("key")
+        h2 = h1.copy()
+        # Using id() in case somebody has overridden __cmp__.
+        self.failUnless(id(h1) != id(h2), "No real copy of the HMAC instance.")
+        self.failUnless(id(h1.inner) != id(h2.inner),
+            "No real copy of the attribute 'inner'.")
+        self.failUnless(id(h1.outer) != id(h2.outer),
+            "No real copy of the attribute 'outer'.")
+
+    def test_equality(self):
+        # Testing if the copy has the same digests.
+        h1 = hmac.HMAC("key")
+        h1.update("some random text")
+        h2 = h1.copy()
+        self.failUnless(h1.digest() == h2.digest(),
+            "Digest of copy doesn't match original digest.")
+        self.failUnless(h1.hexdigest() == h2.hexdigest(),
+            "Hexdigest of copy doesn't match original hexdigest.")
+
+def test_main():
+    test_support.run_unittest(
+        TestVectorsTestCase,
+        ConstructorTestCase,
+        SanityTestCase,
+        CopyTestCase
+    )
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_hotshot.py
===================================================================
--- vendor/Python/current/Lib/test/test_hotshot.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_hotshot.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,132 @@
+import hotshot
+import hotshot.log
+import os
+import pprint
+import unittest
+
+from test import test_support
+
+from hotshot.log import ENTER, EXIT, LINE
+
+
+def shortfilename(fn):
+    # We use a really shortened filename since an exact match is made,
+    # and the source may be either a Python source file or a
+    # pre-compiled bytecode file.
+    if fn:
+        return os.path.splitext(os.path.basename(fn))[0]
+    else:
+        return fn
+
+
+class UnlinkingLogReader(hotshot.log.LogReader):
+    """Extend the LogReader so the log file is unlinked when we're
+    done with it."""
+
+    def __init__(self, logfn):
+        self.__logfn = logfn
+        hotshot.log.LogReader.__init__(self, logfn)
+
+    def next(self, index=None):
+        try:
+            return hotshot.log.LogReader.next(self)
+        except StopIteration:
+            self.close()
+            os.unlink(self.__logfn)
+            raise
+
+
+class HotShotTestCase(unittest.TestCase):
+    def new_profiler(self, lineevents=0, linetimings=1):
+        self.logfn = test_support.TESTFN
+        return hotshot.Profile(self.logfn, lineevents, linetimings)
+
+    def get_logreader(self):
+        return UnlinkingLogReader(self.logfn)
+
+    def get_events_wotime(self):
+        L = []
+        for event in self.get_logreader():
+            what, (filename, lineno, funcname), tdelta = event
+            L.append((what, (shortfilename(filename), lineno, funcname)))
+        return L
+
+    def check_events(self, expected):
+        events = self.get_events_wotime()
+        if events != expected:
+            self.fail(
+                "events did not match expectation; got:\n%s\nexpected:\n%s"
+                % (pprint.pformat(events), pprint.pformat(expected)))
+
+    def run_test(self, callable, events, profiler=None):
+        if profiler is None:
+            profiler = self.new_profiler()
+        self.failUnless(not profiler._prof.closed)
+        profiler.runcall(callable)
+        self.failUnless(not profiler._prof.closed)
+        profiler.close()
+        self.failUnless(profiler._prof.closed)
+        self.check_events(events)
+
+    def test_addinfo(self):
+        def f(p):
+            p.addinfo("test-key", "test-value")
+        profiler = self.new_profiler()
+        profiler.runcall(f, profiler)
+        profiler.close()
+        log = self.get_logreader()
+        info = log._info
+        list(log)
+        self.failUnless(info["test-key"] == ["test-value"])
+
+    def test_line_numbers(self):
+        def f():
+            y = 2
+            x = 1
+        def g():
+            f()
+        f_lineno = f.func_code.co_firstlineno
+        g_lineno = g.func_code.co_firstlineno
+        events = [(ENTER, ("test_hotshot", g_lineno, "g")),
+                  (LINE,  ("test_hotshot", g_lineno+1, "g")),
+                  (ENTER, ("test_hotshot", f_lineno, "f")),
+                  (LINE,  ("test_hotshot", f_lineno+1, "f")),
+                  (LINE,  ("test_hotshot", f_lineno+2, "f")),
+                  (EXIT,  ("test_hotshot", f_lineno, "f")),
+                  (EXIT,  ("test_hotshot", g_lineno, "g")),
+                  ]
+        self.run_test(g, events, self.new_profiler(lineevents=1))
+
+    def test_start_stop(self):
+        # Make sure we don't return NULL in the start() and stop()
+        # methods when there isn't an error.  Bug in 2.2 noted by
+        # Anthony Baxter.
+        profiler = self.new_profiler()
+        profiler.start()
+        profiler.stop()
+        profiler.close()
+        os.unlink(self.logfn)
+
+    def test_bad_sys_path(self):
+        import sys
+        import os
+        orig_path = sys.path
+        coverage = hotshot._hotshot.coverage
+        try:
+            # verify we require a list for sys.path
+            sys.path = 'abc'
+            self.assertRaises(RuntimeError, coverage, test_support.TESTFN)
+            # verify that we require sys.path exists
+            del sys.path
+            self.assertRaises(RuntimeError, coverage, test_support.TESTFN)
+        finally:
+            sys.path = orig_path
+            if os.path.exists(test_support.TESTFN):
+                os.remove(test_support.TESTFN)
+
+def test_main():
+    test_support.run_unittest(HotShotTestCase)
+
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_htmllib.py
===================================================================
--- vendor/Python/current/Lib/test/test_htmllib.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_htmllib.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,69 @@
+import formatter
+import htmllib
+import unittest
+
+from test import test_support
+
+
+class AnchorCollector(htmllib.HTMLParser):
+    def __init__(self, *args, **kw):
+        self.__anchors = []
+        htmllib.HTMLParser.__init__(self, *args, **kw)
+
+    def get_anchor_info(self):
+        return self.__anchors
+
+    def anchor_bgn(self, *args):
+        self.__anchors.append(args)
+
+class DeclCollector(htmllib.HTMLParser):
+    def __init__(self, *args, **kw):
+        self.__decls = []
+        htmllib.HTMLParser.__init__(self, *args, **kw)
+
+    def get_decl_info(self):
+        return self.__decls
+
+    def unknown_decl(self, data):
+        self.__decls.append(data)
+
+
+class HTMLParserTestCase(unittest.TestCase):
+    def test_anchor_collection(self):
+        # See SF bug #467059.
+        parser = AnchorCollector(formatter.NullFormatter(), verbose=1)
+        parser.feed(
+            """<a href='http://foo.org/' name='splat'> </a>
+            <a href='http://www.python.org/'> </a>
+            <a name='frob'> </a>
+            """)
+        parser.close()
+        self.assertEquals(parser.get_anchor_info(),
+                          [('http://foo.org/', 'splat', ''),
+                           ('http://www.python.org/', '', ''),
+                           ('', 'frob', ''),
+                           ])
+
+    def test_decl_collection(self):
+        # See SF patch #545300
+        parser = DeclCollector(formatter.NullFormatter(), verbose=1)
+        parser.feed(
+            """<html>
+            <body>
+            hallo
+            <![if !supportEmptyParas]>&nbsp;<![endif]>
+            </body>
+            </html>
+            """)
+        parser.close()
+        self.assertEquals(parser.get_decl_info(),
+                          ["if !supportEmptyParas",
+                           "endif"
+                           ])
+
+def test_main():
+    test_support.run_unittest(HTMLParserTestCase)
+
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_htmlparser.py
===================================================================
--- vendor/Python/current/Lib/test/test_htmlparser.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_htmlparser.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,318 @@
+"""Tests for HTMLParser.py."""
+
+import HTMLParser
+import pprint
+import sys
+import unittest
+from test import test_support
+
+
+class EventCollector(HTMLParser.HTMLParser):
+
+    def __init__(self):
+        self.events = []
+        self.append = self.events.append
+        HTMLParser.HTMLParser.__init__(self)
+
+    def get_events(self):
+        # Normalize the list of events so that buffer artefacts don't
+        # separate runs of contiguous characters.
+        L = []
+        prevtype = None
+        for event in self.events:
+            type = event[0]
+            if type == prevtype == "data":
+                L[-1] = ("data", L[-1][1] + event[1])
+            else:
+                L.append(event)
+            prevtype = type
+        self.events = L
+        return L
+
+    # structure markup
+
+    def handle_starttag(self, tag, attrs):
+        self.append(("starttag", tag, attrs))
+
+    def handle_startendtag(self, tag, attrs):
+        self.append(("startendtag", tag, attrs))
+
+    def handle_endtag(self, tag):
+        self.append(("endtag", tag))
+
+    # all other markup
+
+    def handle_comment(self, data):
+        self.append(("comment", data))
+
+    def handle_charref(self, data):
+        self.append(("charref", data))
+
+    def handle_data(self, data):
+        self.append(("data", data))
+
+    def handle_decl(self, data):
+        self.append(("decl", data))
+
+    def handle_entityref(self, data):
+        self.append(("entityref", data))
+
+    def handle_pi(self, data):
+        self.append(("pi", data))
+
+    def unknown_decl(self, decl):
+        self.append(("unknown decl", decl))
+
+
+class EventCollectorExtra(EventCollector):
+
+    def handle_starttag(self, tag, attrs):
+        EventCollector.handle_starttag(self, tag, attrs)
+        self.append(("starttag_text", self.get_starttag_text()))
+
+
+class TestCaseBase(unittest.TestCase):
+
+    def _run_check(self, source, expected_events, collector=EventCollector):
+        parser = collector()
+        for s in source:
+            parser.feed(s)
+        parser.close()
+        events = parser.get_events()
+        if events != expected_events:
+            self.fail("received events did not match expected events\n"
+                      "Expected:\n" + pprint.pformat(expected_events) +
+                      "\nReceived:\n" + pprint.pformat(events))
+
+    def _run_check_extra(self, source, events):
+        self._run_check(source, events, EventCollectorExtra)
+
+    def _parse_error(self, source):
+        def parse(source=source):
+            parser = HTMLParser.HTMLParser()
+            parser.feed(source)
+            parser.close()
+        self.assertRaises(HTMLParser.HTMLParseError, parse)
+
+
+class HTMLParserTestCase(TestCaseBase):
+
+    def test_processing_instruction_only(self):
+        self._run_check("<?processing instruction>", [
+            ("pi", "processing instruction"),
+            ])
+        self._run_check("<?processing instruction ?>", [
+            ("pi", "processing instruction ?"),
+            ])
+
+    def test_simple_html(self):
+        self._run_check("""
+<!DOCTYPE html PUBLIC 'foo'>
+<HTML>&entity;&#32;
+<!--comment1a
+-></foo><bar>&lt;<?pi?></foo<bar
+comment1b-->
+<Img sRc='Bar' isMAP>sample
+text
+&#x201C;
+<!--comment2a-- --comment2b--><!>
+</Html>
+""", [
+    ("data", "\n"),
+    ("decl", "DOCTYPE html PUBLIC 'foo'"),
+    ("data", "\n"),
+    ("starttag", "html", []),
+    ("entityref", "entity"),
+    ("charref", "32"),
+    ("data", "\n"),
+    ("comment", "comment1a\n-></foo><bar>&lt;<?pi?></foo<bar\ncomment1b"),
+    ("data", "\n"),
+    ("starttag", "img", [("src", "Bar"), ("ismap", None)]),
+    ("data", "sample\ntext\n"),
+    ("charref", "x201C"),
+    ("data", "\n"),
+    ("comment", "comment2a-- --comment2b"),
+    ("data", "\n"),
+    ("endtag", "html"),
+    ("data", "\n"),
+    ])
+
+    def test_unclosed_entityref(self):
+        self._run_check("&entityref foo", [
+            ("entityref", "entityref"),
+            ("data", " foo"),
+            ])
+
+    def test_doctype_decl(self):
+        inside = """\
+DOCTYPE html [
+  <!ELEMENT html - O EMPTY>
+  <!ATTLIST html
+      version CDATA #IMPLIED
+      profile CDATA 'DublinCore'>
+  <!NOTATION datatype SYSTEM 'http://xml.python.org/notations/python-module'>
+  <!ENTITY myEntity 'internal parsed entity'>
+  <!ENTITY anEntity SYSTEM 'http://xml.python.org/entities/something.xml'>
+  <!ENTITY % paramEntity 'name|name|name'>
+  %paramEntity;
+  <!-- comment -->
+]"""
+        self._run_check("<!%s>" % inside, [
+            ("decl", inside),
+            ])
+
+    def test_bad_nesting(self):
+        # Strangely, this *is* supposed to test that overlapping
+        # elements are allowed.  HTMLParser is more geared toward
+        # lexing the input that parsing the structure.
+        self._run_check("<a><b></a></b>", [
+            ("starttag", "a", []),
+            ("starttag", "b", []),
+            ("endtag", "a"),
+            ("endtag", "b"),
+            ])
+
+    def test_bare_ampersands(self):
+        self._run_check("this text & contains & ampersands &", [
+            ("data", "this text & contains & ampersands &"),
+            ])
+
+    def test_bare_pointy_brackets(self):
+        self._run_check("this < text > contains < bare>pointy< brackets", [
+            ("data", "this < text > contains < bare>pointy< brackets"),
+            ])
+
+    def test_attr_syntax(self):
+        output = [
+          ("starttag", "a", [("b", "v"), ("c", "v"), ("d", "v"), ("e", None)])
+          ]
+        self._run_check("""<a b='v' c="v" d=v e>""", output)
+        self._run_check("""<a  b = 'v' c = "v" d = v e>""", output)
+        self._run_check("""<a\nb\n=\n'v'\nc\n=\n"v"\nd\n=\nv\ne>""", output)
+        self._run_check("""<a\tb\t=\t'v'\tc\t=\t"v"\td\t=\tv\te>""", output)
+
+    def test_attr_values(self):
+        self._run_check("""<a b='xxx\n\txxx' c="yyy\t\nyyy" d='\txyz\n'>""",
+                        [("starttag", "a", [("b", "xxx\n\txxx"),
+                                            ("c", "yyy\t\nyyy"),
+                                            ("d", "\txyz\n")])
+                         ])
+        self._run_check("""<a b='' c="">""", [
+            ("starttag", "a", [("b", ""), ("c", "")]),
+            ])
+        # Regression test for SF patch #669683.
+        self._run_check("<e a=rgb(1,2,3)>", [
+            ("starttag", "e", [("a", "rgb(1,2,3)")]),
+            ])
+        # Regression test for SF bug #921657.
+        self._run_check("<a href=mailto:xyz at example.com>", [
+            ("starttag", "a", [("href", "mailto:xyz at example.com")]),
+            ])
+
+    def test_attr_entity_replacement(self):
+        self._run_check("""<a b='&amp;&gt;&lt;&quot;&apos;'>""", [
+            ("starttag", "a", [("b", "&><\"'")]),
+            ])
+
+    def test_attr_funky_names(self):
+        self._run_check("""<a a.b='v' c:d=v e-f=v>""", [
+            ("starttag", "a", [("a.b", "v"), ("c:d", "v"), ("e-f", "v")]),
+            ])
+
+    def test_illegal_declarations(self):
+        self._parse_error('<!spacer type="block" height="25">')
+
+    def test_starttag_end_boundary(self):
+        self._run_check("""<a b='<'>""", [("starttag", "a", [("b", "<")])])
+        self._run_check("""<a b='>'>""", [("starttag", "a", [("b", ">")])])
+
+    def test_buffer_artefacts(self):
+        output = [("starttag", "a", [("b", "<")])]
+        self._run_check(["<a b='<'>"], output)
+        self._run_check(["<a ", "b='<'>"], output)
+        self._run_check(["<a b", "='<'>"], output)
+        self._run_check(["<a b=", "'<'>"], output)
+        self._run_check(["<a b='<", "'>"], output)
+        self._run_check(["<a b='<'", ">"], output)
+
+        output = [("starttag", "a", [("b", ">")])]
+        self._run_check(["<a b='>'>"], output)
+        self._run_check(["<a ", "b='>'>"], output)
+        self._run_check(["<a b", "='>'>"], output)
+        self._run_check(["<a b=", "'>'>"], output)
+        self._run_check(["<a b='>", "'>"], output)
+        self._run_check(["<a b='>'", ">"], output)
+
+        output = [("comment", "abc")]
+        self._run_check(["", "<!--abc-->"], output)
+        self._run_check(["<", "!--abc-->"], output)
+        self._run_check(["<!", "--abc-->"], output)
+        self._run_check(["<!-", "-abc-->"], output)
+        self._run_check(["<!--", "abc-->"], output)
+        self._run_check(["<!--a", "bc-->"], output)
+        self._run_check(["<!--ab", "c-->"], output)
+        self._run_check(["<!--abc", "-->"], output)
+        self._run_check(["<!--abc-", "->"], output)
+        self._run_check(["<!--abc--", ">"], output)
+        self._run_check(["<!--abc-->", ""], output)
+
+    def test_starttag_junk_chars(self):
+        self._parse_error("</>")
+        self._parse_error("</$>")
+        self._parse_error("</")
+        self._parse_error("</a")
+        self._parse_error("<a<a>")
+        self._parse_error("</a<a>")
+        self._parse_error("<!")
+        self._parse_error("<a $>")
+        self._parse_error("<a")
+        self._parse_error("<a foo='bar'")
+        self._parse_error("<a foo='bar")
+        self._parse_error("<a foo='>'")
+        self._parse_error("<a foo='>")
+        self._parse_error("<a foo=>")
+
+    def test_declaration_junk_chars(self):
+        self._parse_error("<!DOCTYPE foo $ >")
+
+    def test_startendtag(self):
+        self._run_check("<p/>", [
+            ("startendtag", "p", []),
+            ])
+        self._run_check("<p></p>", [
+            ("starttag", "p", []),
+            ("endtag", "p"),
+            ])
+        self._run_check("<p><img src='foo' /></p>", [
+            ("starttag", "p", []),
+            ("startendtag", "img", [("src", "foo")]),
+            ("endtag", "p"),
+            ])
+
+    def test_get_starttag_text(self):
+        s = """<foo:bar   \n   one="1"\ttwo=2   >"""
+        self._run_check_extra(s, [
+            ("starttag", "foo:bar", [("one", "1"), ("two", "2")]),
+            ("starttag_text", s)])
+
+    def test_cdata_content(self):
+        s = """<script> <!-- not a comment --> &not-an-entity-ref; </script>"""
+        self._run_check(s, [
+            ("starttag", "script", []),
+            ("data", " <!-- not a comment --> &not-an-entity-ref; "),
+            ("endtag", "script"),
+            ])
+        s = """<script> <not a='start tag'> </script>"""
+        self._run_check(s, [
+            ("starttag", "script", []),
+            ("data", " <not a='start tag'> "),
+            ("endtag", "script"),
+            ])
+
+
+def test_main():
+    test_support.run_unittest(HTMLParserTestCase)
+
+
+if __name__ == "__main__":
+    test_main()


Property changes on: vendor/Python/current/Lib/test/test_htmlparser.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/test/test_httplib.py
===================================================================
--- vendor/Python/current/Lib/test/test_httplib.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_httplib.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,172 @@
+import httplib
+import StringIO
+import sys
+
+from unittest import TestCase
+
+from test import test_support
+
+class FakeSocket:
+    def __init__(self, text, fileclass=StringIO.StringIO):
+        self.text = text
+        self.fileclass = fileclass
+
+    def sendall(self, data):
+        self.data = data
+
+    def makefile(self, mode, bufsize=None):
+        if mode != 'r' and mode != 'rb':
+            raise httplib.UnimplementedFileMode()
+        return self.fileclass(self.text)
+
+class NoEOFStringIO(StringIO.StringIO):
+    """Like StringIO, but raises AssertionError on EOF.
+
+    This is used below to test that httplib doesn't try to read
+    more from the underlying file than it should.
+    """
+    def read(self, n=-1):
+        data = StringIO.StringIO.read(self, n)
+        if data == '':
+            raise AssertionError('caller tried to read past EOF')
+        return data
+
+    def readline(self, length=None):
+        data = StringIO.StringIO.readline(self, length)
+        if data == '':
+            raise AssertionError('caller tried to read past EOF')
+        return data
+
+
+class HeaderTests(TestCase):
+    def test_auto_headers(self):
+        # Some headers are added automatically, but should not be added by
+        # .request() if they are explicitly set.
+
+        import httplib
+
+        class HeaderCountingBuffer(list):
+            def __init__(self):
+                self.count = {}
+            def append(self, item):
+                kv = item.split(':')
+                if len(kv) > 1:
+                    # item is a 'Key: Value' header string
+                    lcKey = kv[0].lower()
+                    self.count.setdefault(lcKey, 0)
+                    self.count[lcKey] += 1
+                list.append(self, item)
+
+        for explicit_header in True, False:
+            for header in 'Content-length', 'Host', 'Accept-encoding':
+                conn = httplib.HTTPConnection('example.com')
+                conn.sock = FakeSocket('blahblahblah')
+                conn._buffer = HeaderCountingBuffer()
+
+                body = 'spamspamspam'
+                headers = {}
+                if explicit_header:
+                    headers[header] = str(len(body))
+                conn.request('POST', '/', body, headers)
+                self.assertEqual(conn._buffer.count[header.lower()], 1)
+
+# Collect output to a buffer so that we don't have to cope with line-ending
+# issues across platforms.  Specifically, the headers will have \r\n pairs
+# and some platforms will strip them from the output file.
+
+def test():
+    buf = StringIO.StringIO()
+    _stdout = sys.stdout
+    try:
+        sys.stdout = buf
+        _test()
+    finally:
+        sys.stdout = _stdout
+
+    # print individual lines with endings stripped
+    s = buf.getvalue()
+    for line in s.split("\n"):
+        print line.strip()
+
+def _test():
+    # Test HTTP status lines
+
+    body = "HTTP/1.1 200 Ok\r\n\r\nText"
+    sock = FakeSocket(body)
+    resp = httplib.HTTPResponse(sock, 1)
+    resp.begin()
+    print resp.read()
+    resp.close()
+
+    body = "HTTP/1.1 400.100 Not Ok\r\n\r\nText"
+    sock = FakeSocket(body)
+    resp = httplib.HTTPResponse(sock, 1)
+    try:
+        resp.begin()
+    except httplib.BadStatusLine:
+        print "BadStatusLine raised as expected"
+    else:
+        print "Expect BadStatusLine"
+
+    # Check invalid host_port
+
+    for hp in ("www.python.org:abc", "www.python.org:"):
+        try:
+            h = httplib.HTTP(hp)
+        except httplib.InvalidURL:
+            print "InvalidURL raised as expected"
+        else:
+            print "Expect InvalidURL"
+
+    for hp,h,p in (("[fe80::207:e9ff:fe9b]:8000", "fe80::207:e9ff:fe9b", 8000),
+                   ("www.python.org:80", "www.python.org", 80),
+                   ("www.python.org", "www.python.org", 80),
+                   ("[fe80::207:e9ff:fe9b]", "fe80::207:e9ff:fe9b", 80)):
+        try:
+            http = httplib.HTTP(hp)
+        except httplib.InvalidURL:
+            print "InvalidURL raised erroneously"
+        c = http._conn
+        if h != c.host: raise AssertionError, ("Host incorrectly parsed", h, c.host)
+        if p != c.port: raise AssertionError, ("Port incorrectly parsed", p, c.host)
+
+    # test response with multiple message headers with the same field name.
+    text = ('HTTP/1.1 200 OK\r\n'
+            'Set-Cookie: Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"\r\n'
+            'Set-Cookie: Part_Number="Rocket_Launcher_0001"; Version="1";'
+            ' Path="/acme"\r\n'
+            '\r\n'
+            'No body\r\n')
+    hdr = ('Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"'
+           ', '
+           'Part_Number="Rocket_Launcher_0001"; Version="1"; Path="/acme"')
+    s = FakeSocket(text)
+    r = httplib.HTTPResponse(s, 1)
+    r.begin()
+    cookies = r.getheader("Set-Cookie")
+    if cookies != hdr:
+        raise AssertionError, "multiple headers not combined properly"
+
+    # Test that the library doesn't attempt to read any data
+    # from a HEAD request.  (Tickles SF bug #622042.)
+    sock = FakeSocket(
+        'HTTP/1.1 200 OK\r\n'
+        'Content-Length: 14432\r\n'
+        '\r\n',
+        NoEOFStringIO)
+    resp = httplib.HTTPResponse(sock, 1, method="HEAD")
+    resp.begin()
+    if resp.read() != "":
+        raise AssertionError, "Did not expect response from HEAD request"
+    resp.close()
+
+
+class OfflineTest(TestCase):
+    def test_responses(self):
+        self.assertEquals(httplib.responses[httplib.NOT_FOUND], "Not Found")
+
+def test_main(verbose=None):
+    tests = [HeaderTests,OfflineTest]
+    test_support.run_unittest(*tests)
+
+test()

Added: vendor/Python/current/Lib/test/test_imageop.py
===================================================================
--- vendor/Python/current/Lib/test/test_imageop.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_imageop.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,177 @@
+#! /usr/bin/env python
+
+"""Test script for the imageop module.  This has the side
+   effect of partially testing the imgfile module as well.
+   Roger E. Masse
+"""
+
+from test.test_support import verbose, unlink
+
+import imageop, uu, os
+
+import warnings
+warnings.filterwarnings("ignore",
+                        "the rgbimg module is deprecated",
+                        DeprecationWarning,
+                        ".*test_imageop")
+
+def main(use_rgbimg=1):
+
+    # Create binary test files
+    uu.decode(get_qualified_path('testrgb'+os.extsep+'uue'), 'test'+os.extsep+'rgb')
+
+    if use_rgbimg:
+        image, width, height = getrgbimage('test'+os.extsep+'rgb')
+    else:
+        image, width, height = getimage('test'+os.extsep+'rgb')
+
+    # Return the selected part of image, which should by width by height
+    # in size and consist of pixels of psize bytes.
+    if verbose:
+        print 'crop'
+    newimage = imageop.crop (image, 4, width, height, 0, 0, 1, 1)
+
+    # Return image scaled to size newwidth by newheight. No interpolation
+    # is done, scaling is done by simple-minded pixel duplication or removal.
+    # Therefore, computer-generated images or dithered images will
+    # not look nice after scaling.
+    if verbose:
+        print 'scale'
+    scaleimage = imageop.scale(image, 4, width, height, 1, 1)
+
+    # Run a vertical low-pass filter over an image. It does so by computing
+    # each destination pixel as the average of two vertically-aligned source
+    # pixels. The main use of this routine is to forestall excessive flicker
+    # if the image two vertically-aligned source pixels,  hence the name.
+    if verbose:
+        print 'tovideo'
+    videoimage = imageop.tovideo (image, 4, width, height)
+
+    # Convert an rgb image to an 8 bit rgb
+    if verbose:
+        print 'rgb2rgb8'
+    greyimage = imageop.rgb2rgb8(image, width, height)
+
+    # Convert an 8 bit rgb image to a 24 bit rgb image
+    if verbose:
+        print 'rgb82rgb'
+    image = imageop.rgb82rgb(greyimage, width, height)
+
+    # Convert an rgb image to an 8 bit greyscale image
+    if verbose:
+        print 'rgb2grey'
+    greyimage = imageop.rgb2grey(image, width, height)
+
+    # Convert an 8 bit greyscale image to a 24 bit rgb image
+    if verbose:
+        print 'grey2rgb'
+    image = imageop.grey2rgb(greyimage, width, height)
+
+    # Convert a 8-bit deep greyscale image to a 1-bit deep image by
+    # thresholding all the pixels. The resulting image is tightly packed
+    # and is probably only useful as an argument to mono2grey.
+    if verbose:
+        print 'grey2mono'
+    monoimage = imageop.grey2mono (greyimage, width, height, 0)
+
+    # monoimage, width, height = getimage('monotest.rgb')
+    # Convert a 1-bit monochrome image to an 8 bit greyscale or color image.
+    # All pixels that are zero-valued on input get value p0 on output and
+    # all one-value input pixels get value p1 on output. To convert a
+    # monochrome  black-and-white image to greyscale pass the values 0 and
+    # 255 respectively.
+    if verbose:
+        print 'mono2grey'
+    greyimage = imageop.mono2grey (monoimage, width, height, 0, 255)
+
+    # Convert an 8-bit greyscale image to a 1-bit monochrome image using a
+    # (simple-minded) dithering algorithm.
+    if verbose:
+        print 'dither2mono'
+    monoimage = imageop.dither2mono (greyimage, width, height)
+
+    # Convert an 8-bit greyscale image to a 4-bit greyscale image without
+    # dithering.
+    if verbose:
+        print 'grey2grey4'
+    grey4image = imageop.grey2grey4 (greyimage, width, height)
+
+    # Convert an 8-bit greyscale image to a 2-bit greyscale image without
+    # dithering.
+    if verbose:
+        print 'grey2grey2'
+    grey2image = imageop.grey2grey2 (greyimage, width, height)
+
+    # Convert an 8-bit greyscale image to a 2-bit greyscale image with
+    # dithering. As for dither2mono, the dithering algorithm is currently
+    # very simple.
+    if verbose:
+        print 'dither2grey2'
+    grey2image = imageop.dither2grey2 (greyimage, width, height)
+
+    # Convert a 4-bit greyscale image to an 8-bit greyscale image.
+    if verbose:
+        print 'grey42grey'
+    greyimage = imageop.grey42grey (grey4image, width, height)
+
+    # Convert a 2-bit greyscale image to an 8-bit greyscale image.
+    if verbose:
+        print 'grey22grey'
+    image = imageop.grey22grey (grey2image, width, height)
+
+    # Cleanup
+    unlink('test'+os.extsep+'rgb')
+
+def getrgbimage(name):
+    """return a tuple consisting of image (in 'imgfile' format but
+    using rgbimg instead) width and height"""
+
+    import rgbimg
+
+    try:
+        sizes = rgbimg.sizeofimage(name)
+    except rgbimg.error:
+        name = get_qualified_path(name)
+        sizes = rgbimg.sizeofimage(name)
+    if verbose:
+        print 'rgbimg opening test image: %s, sizes: %s' % (name, str(sizes))
+
+    image = rgbimg.longimagedata(name)
+    return (image, sizes[0], sizes[1])
+
+def getimage(name):
+    """return a tuple consisting of
+       image (in 'imgfile' format) width and height
+    """
+
+    import imgfile
+
+    try:
+        sizes = imgfile.getsizes(name)
+    except imgfile.error:
+        name = get_qualified_path(name)
+        sizes = imgfile.getsizes(name)
+    if verbose:
+        print 'imgfile opening test image: %s, sizes: %s' % (name, str(sizes))
+
+    image = imgfile.read(name)
+    return (image, sizes[0], sizes[1])
+
+def get_qualified_path(name):
+    """ return a more qualified path to name"""
+    import sys
+    import os
+    path = sys.path
+    try:
+        path = [os.path.dirname(__file__)] + path
+    except NameError:
+        pass
+    for dir in path:
+        fullname = os.path.join(dir, name)
+        if os.path.exists(fullname):
+            return fullname
+    return name
+
+# rgbimg (unlike imgfile) is portable to platforms other than SGI.
+# So we prefer to use it.
+main(use_rgbimg=1)


Property changes on: vendor/Python/current/Lib/test/test_imageop.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/test/test_imaplib.py
===================================================================
--- vendor/Python/current/Lib/test/test_imaplib.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_imaplib.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,12 @@
+import imaplib
+import time
+
+# We can check only that it successfully produces a result,
+# not the correctness of the result itself, since the result
+# depends on the timezone the machine is in.
+
+timevalues = [2000000000, 2000000000.0, time.localtime(2000000000),
+              '"18-May-2033 05:33:20 +0200"']
+
+for t in timevalues:
+    imaplib.Time2Internaldate(t)

Added: vendor/Python/current/Lib/test/test_imgfile.py
===================================================================
--- vendor/Python/current/Lib/test/test_imgfile.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_imgfile.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,116 @@
+#! /usr/bin/env python
+
+"""Simple test script for imgfile.c
+   Roger E. Masse
+"""
+
+from test.test_support import verbose, unlink, findfile
+
+import imgfile, uu, os
+
+
+def main():
+
+    uu.decode(findfile('testrgb.uue'), 'test.rgb')
+    uu.decode(findfile('greyrgb.uue'), 'greytest.rgb')
+
+    # Test a 3 byte color image
+    testimage('test.rgb')
+
+    # Test a 1 byte greyscale image
+    testimage('greytest.rgb')
+
+    unlink('test.rgb')
+    unlink('greytest.rgb')
+
+def testimage(name):
+    """Run through the imgfile's battery of possible methods
+       on the image passed in name.
+    """
+
+    import sys
+    import os
+
+    outputfile = '/tmp/deleteme'
+
+    # try opening the name directly
+    try:
+        # This function returns a tuple (x, y, z) where x and y are the size
+        # of the image in pixels and z is the number of bytes per pixel. Only
+        # 3 byte RGB pixels and 1 byte greyscale pixels are supported.
+        sizes = imgfile.getsizes(name)
+    except imgfile.error:
+        # get a more qualified path component of the script...
+        if __name__ == '__main__':
+            ourname = sys.argv[0]
+        else: # ...or the full path of the module
+            ourname = sys.modules[__name__].__file__
+
+        parts = ourname.split(os.sep)
+        parts[-1] = name
+        name = os.sep.join(parts)
+        sizes = imgfile.getsizes(name)
+    if verbose:
+        print 'Opening test image: %s, sizes: %s' % (name, str(sizes))
+    # This function reads and decodes the image on the specified file,
+    # and returns it as a python string. The string has either 1 byte
+    # greyscale pixels or 4 byte RGBA pixels. The bottom left pixel
+    # is the first in the string. This format is suitable to pass
+    # to gl.lrectwrite, for instance.
+    image = imgfile.read(name)
+
+    # This function writes the RGB or greyscale data in data to
+    # image file file. x and y give the size of the image, z is
+    # 1 for 1 byte greyscale images or 3 for RGB images (which
+    # are stored as 4 byte values of which only the lower three
+    # bytes are used). These are the formats returned by gl.lrectread.
+    if verbose:
+        print 'Writing output file'
+    imgfile.write (outputfile, image, sizes[0], sizes[1], sizes[2])
+
+
+    if verbose:
+        print 'Opening scaled test image: %s, sizes: %s' % (name, str(sizes))
+    # This function is identical to read but it returns an image that
+    # is scaled to the given x and y sizes. If the filter and blur
+    # parameters are omitted scaling is done by simply dropping
+    # or duplicating pixels, so the result will be less than perfect,
+    # especially for computer-generated images.  Alternatively,
+    # you can specify a filter to use to smoothen the image after
+    # scaling. The filter forms supported are 'impulse', 'box',
+    # 'triangle', 'quadratic' and 'gaussian'. If a filter is
+    # specified blur is an optional parameter specifying the
+    # blurriness of the filter. It defaults to 1.0.  readscaled
+    # makes no attempt to keep the aspect ratio correct, so that
+    # is the users' responsibility.
+    if verbose:
+        print 'Filtering with "impulse"'
+    simage = imgfile.readscaled (name, sizes[0]/2, sizes[1]/2, 'impulse', 2.0)
+
+    # This function sets a global flag which defines whether the
+    # scan lines of the image are read or written from bottom to
+    # top (flag is zero, compatible with SGI GL) or from top to
+    # bottom(flag is one, compatible with X). The default is zero.
+    if verbose:
+        print 'Switching to X compatibility'
+    imgfile.ttob (1)
+
+    if verbose:
+        print 'Filtering with "triangle"'
+    simage = imgfile.readscaled (name, sizes[0]/2, sizes[1]/2, 'triangle', 3.0)
+    if verbose:
+        print 'Switching back to SGI compatibility'
+    imgfile.ttob (0)
+
+    if verbose: print 'Filtering with "quadratic"'
+    simage = imgfile.readscaled (name, sizes[0]/2, sizes[1]/2, 'quadratic')
+    if verbose: print 'Filtering with "gaussian"'
+    simage = imgfile.readscaled (name, sizes[0]/2, sizes[1]/2, 'gaussian', 1.0)
+
+    if verbose:
+        print 'Writing output file'
+    imgfile.write (outputfile, simage, sizes[0]/2, sizes[1]/2, sizes[2])
+
+    os.unlink(outputfile)
+
+main()


Property changes on: vendor/Python/current/Lib/test/test_imgfile.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/test/test_imp.py
===================================================================
--- vendor/Python/current/Lib/test/test_imp.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_imp.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,43 @@
+import imp
+from test.test_support import TestFailed, TestSkipped
+try:
+    import thread
+except ImportError:
+    raise TestSkipped("test only valid when thread support is available")
+
+def verify_lock_state(expected):
+    if imp.lock_held() != expected:
+        raise TestFailed("expected imp.lock_held() to be %r" % expected)
+
+def testLock():
+    LOOPS = 50
+
+    # The import lock may already be held, e.g. if the test suite is run
+    # via "import test.autotest".
+    lock_held_at_start = imp.lock_held()
+    verify_lock_state(lock_held_at_start)
+
+    for i in range(LOOPS):
+        imp.acquire_lock()
+        verify_lock_state(True)
+
+    for i in range(LOOPS):
+        imp.release_lock()
+
+    # The original state should be restored now.
+    verify_lock_state(lock_held_at_start)
+
+    if not lock_held_at_start:
+        try:
+            imp.release_lock()
+        except RuntimeError:
+            pass
+        else:
+            raise TestFailed("release_lock() without lock should raise "
+                             "RuntimeError")
+
+def test_main():
+    testLock()
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_import.py
===================================================================
--- vendor/Python/current/Lib/test/test_import.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_import.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,236 @@
+from test.test_support import TESTFN, TestFailed
+
+import os
+import random
+import sys
+import py_compile
+
+# Brief digression to test that import is case-sensitive:  if we got this
+# far, we know for sure that "random" exists.
+try:
+    import RAnDoM
+except ImportError:
+    pass
+else:
+    raise TestFailed("import of RAnDoM should have failed (case mismatch)")
+
+# Another brief digression to test the accuracy of manifest float constants.
+from test import double_const  # don't blink -- that *was* the test
+
+def remove_files(name):
+    for f in (name + os.extsep + "py",
+              name + os.extsep + "pyc",
+              name + os.extsep + "pyo",
+              name + os.extsep + "pyw",
+              name + "$py.class"):
+        if os.path.exists(f):
+            os.remove(f)
+
+def test_with_extension(ext): # ext normally ".py"; perhaps ".pyw"
+    source = TESTFN + ext
+    pyo = TESTFN + os.extsep + "pyo"
+    if sys.platform.startswith('java'):
+        pyc = TESTFN + "$py.class"
+    else:
+        pyc = TESTFN + os.extsep + "pyc"
+
+    f = open(source, "w")
+    print >> f, "# This tests Python's ability to import a", ext, "file."
+    a = random.randrange(1000)
+    b = random.randrange(1000)
+    print >> f, "a =", a
+    print >> f, "b =", b
+    f.close()
+
+    try:
+        try:
+            mod = __import__(TESTFN)
+        except ImportError, err:
+            raise ValueError("import from %s failed: %s" % (ext, err))
+
+        if mod.a != a or mod.b != b:
+            print a, "!=", mod.a
+            print b, "!=", mod.b
+            raise ValueError("module loaded (%s) but contents invalid" % mod)
+    finally:
+        os.unlink(source)
+
+    try:
+        try:
+            reload(mod)
+        except ImportError, err:
+            raise ValueError("import from .pyc/.pyo failed: %s" % err)
+    finally:
+        try:
+            os.unlink(pyc)
+        except os.error:
+            pass
+        try:
+            os.unlink(pyo)
+        except os.error:
+            pass
+        del sys.modules[TESTFN]
+
+sys.path.insert(0, os.curdir)
+try:
+    test_with_extension(os.extsep + "py")
+    if sys.platform.startswith("win"):
+        for ext in ".PY", ".Py", ".pY", ".pyw", ".PYW", ".pYw":
+            test_with_extension(ext)
+finally:
+    del sys.path[0]
+
+# Verify that the imp module can correctly load and find .py files
+import imp
+x = imp.find_module("os")
+os = imp.load_module("os", *x)
+
+def test_module_with_large_stack(module):
+    # create module w/list of 65000 elements to test bug #561858
+    filename = module + os.extsep + 'py'
+
+    # create a file with a list of 65000 elements
+    f = open(filename, 'w+')
+    f.write('d = [\n')
+    for i in range(65000):
+        f.write('"",\n')
+    f.write(']')
+    f.close()
+
+    # compile & remove .py file, we only need .pyc (or .pyo)
+    f = open(filename, 'r')
+    py_compile.compile(filename)
+    f.close()
+    os.unlink(filename)
+
+    # need to be able to load from current dir
+    sys.path.append('')
+
+    # this used to crash
+    exec 'import ' + module
+
+    # cleanup
+    del sys.path[-1]
+    for ext in 'pyc', 'pyo':
+        fname = module + os.extsep + ext
+        if os.path.exists(fname):
+            os.unlink(fname)
+
+test_module_with_large_stack('longlist')
+
+def test_failing_import_sticks():
+    source = TESTFN + os.extsep + "py"
+    f = open(source, "w")
+    print >> f, "a = 1/0"
+    f.close()
+
+    # New in 2.4, we shouldn't be able to import that no matter how often
+    # we try.
+    sys.path.insert(0, os.curdir)
+    try:
+        for i in 1, 2, 3:
+            try:
+                mod = __import__(TESTFN)
+            except ZeroDivisionError:
+                if TESTFN in sys.modules:
+                    raise TestFailed("damaged module in sys.modules", i)
+            else:
+                raise TestFailed("was able to import a damaged module", i)
+    finally:
+        sys.path.pop(0)
+        remove_files(TESTFN)
+
+test_failing_import_sticks()
+
+def test_failing_reload():
+    # A failing reload should leave the module object in sys.modules.
+    source = TESTFN + os.extsep + "py"
+    f = open(source, "w")
+    print >> f, "a = 1"
+    print >> f, "b = 2"
+    f.close()
+
+    sys.path.insert(0, os.curdir)
+    try:
+        mod = __import__(TESTFN)
+        if TESTFN not in sys.modules:
+            raise TestFailed("expected module in sys.modules")
+        if mod.a != 1 or mod.b != 2:
+            raise TestFailed("module has wrong attribute values")
+
+        # On WinXP, just replacing the .py file wasn't enough to
+        # convince reload() to reparse it.  Maybe the timestamp didn't
+        # move enough.  We force it to get reparsed by removing the
+        # compiled file too.
+        remove_files(TESTFN)
+
+        # Now damage the module.
+        f = open(source, "w")
+        print >> f, "a = 10"
+        print >> f, "b = 20//0"
+        f.close()
+        try:
+            reload(mod)
+        except ZeroDivisionError:
+            pass
+        else:
+            raise TestFailed("was able to reload a damaged module")
+
+        # But we still expect the module to be in sys.modules.
+        mod = sys.modules.get(TESTFN)
+        if mod is None:
+            raise TestFailed("expected module to still be in sys.modules")
+        # We should have replaced a w/ 10, but the old b value should
+        # stick.
+        if mod.a != 10 or mod.b != 2:
+            raise TestFailed("module has wrong attribute values")
+
+    finally:
+        sys.path.pop(0)
+        remove_files(TESTFN)
+        if TESTFN in sys.modules:
+            del sys.modules[TESTFN]
+
+test_failing_reload()
+
+def test_import_name_binding():
+    # import x.y.z binds x in the current namespace
+    import test as x
+    import test.test_support
+    assert x is test, x.__name__
+    assert hasattr(test.test_support, "__file__")
+
+    # import x.y.z as w binds z as w
+    import test.test_support as y
+    assert y is test.test_support, y.__name__
+
+test_import_name_binding()
+
+def test_import_initless_directory_warning():
+    import warnings
+    oldfilters = warnings.filters[:]
+    warnings.simplefilter('error', ImportWarning);
+    try:
+        # Just a random non-package directory we always expect to be
+        # somewhere in sys.path...
+        __import__("site-packages")
+    except ImportWarning:
+        pass
+    else:
+        raise AssertionError
+    finally:
+        warnings.filters = oldfilters
+
+test_import_initless_directory_warning()
+
+def test_infinite_reload():
+     # Bug #742342 reports that Python segfaults (infinite recursion in C)
+     #  when faced with self-recursive reload()ing.
+
+     sys.path.insert(0, os.path.dirname(__file__))
+     try:
+         import infinite_reload
+     finally:
+         sys.path.pop(0)
+
+test_infinite_reload()

Added: vendor/Python/current/Lib/test/test_importhooks.py
===================================================================
--- vendor/Python/current/Lib/test/test_importhooks.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_importhooks.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,276 @@
+import sys
+import imp
+import os
+import unittest
+from test import test_support
+
+
+test_src = """\
+def get_name():
+    return __name__
+def get_file():
+    return __file__
+"""
+
+absimp = "import sub\n"
+relimp = "from . import sub\n"
+deeprelimp = "from .... import sub\n"
+futimp = "from __future__ import absolute_import\n"
+
+reload_src = test_src+"""\
+reloaded = True
+"""
+
+test_co = compile(test_src, "<???>", "exec")
+reload_co = compile(reload_src, "<???>", "exec")
+
+test2_oldabs_co = compile(absimp + test_src, "<???>", "exec")
+test2_newabs_co = compile(futimp + absimp + test_src, "<???>", "exec")
+test2_newrel_co = compile(relimp + test_src, "<???>", "exec")
+test2_deeprel_co = compile(deeprelimp + test_src, "<???>", "exec")
+test2_futrel_co = compile(futimp + relimp + test_src, "<???>", "exec")
+
+test_path = "!!!_test_!!!"
+
+
+class ImportTracker:
+    """Importer that only tracks attempted imports."""
+    def __init__(self):
+        self.imports = []
+    def find_module(self, fullname, path=None):
+        self.imports.append(fullname)
+        return None
+
+
+class TestImporter:
+
+    modules = {
+        "hooktestmodule": (False, test_co),
+        "hooktestpackage": (True, test_co),
+        "hooktestpackage.sub": (True, test_co),
+        "hooktestpackage.sub.subber": (True, test_co),
+        "hooktestpackage.oldabs": (False, test2_oldabs_co),
+        "hooktestpackage.newabs": (False, test2_newabs_co),
+        "hooktestpackage.newrel": (False, test2_newrel_co),
+        "hooktestpackage.sub.subber.subest": (True, test2_deeprel_co),
+        "hooktestpackage.futrel": (False, test2_futrel_co),
+        "sub": (False, test_co),
+        "reloadmodule": (False, test_co),
+    }
+
+    def __init__(self, path=test_path):
+        if path != test_path:
+            # if out class is on sys.path_hooks, we must raise
+            # ImportError for any path item that we can't handle.
+            raise ImportError
+        self.path = path
+
+    def _get__path__(self):
+        raise NotImplementedError
+
+    def find_module(self, fullname, path=None):
+        if fullname in self.modules:
+            return self
+        else:
+            return None
+
+    def load_module(self, fullname):
+        ispkg, code = self.modules[fullname]
+        mod = sys.modules.setdefault(fullname,imp.new_module(fullname))
+        mod.__file__ = "<%s>" % self.__class__.__name__
+        mod.__loader__ = self
+        if ispkg:
+            mod.__path__ = self._get__path__()
+        exec code in mod.__dict__
+        return mod
+
+
+class MetaImporter(TestImporter):
+    def _get__path__(self):
+        return []
+
+class PathImporter(TestImporter):
+    def _get__path__(self):
+        return [self.path]
+
+
+class ImportBlocker:
+    """Place an ImportBlocker instance on sys.meta_path and you
+    can be sure the modules you specified can't be imported, even
+    if it's a builtin."""
+    def __init__(self, *namestoblock):
+        self.namestoblock = dict.fromkeys(namestoblock)
+    def find_module(self, fullname, path=None):
+        if fullname in self.namestoblock:
+            return self
+        return None
+    def load_module(self, fullname):
+        raise ImportError, "I dare you"
+
+
+class ImpWrapper:
+
+    def __init__(self, path=None):
+        if path is not None and not os.path.isdir(path):
+            raise ImportError
+        self.path = path
+
+    def find_module(self, fullname, path=None):
+        subname = fullname.split(".")[-1]
+        if subname != fullname and self.path is None:
+            return None
+        if self.path is None:
+            path = None
+        else:
+            path = [self.path]
+        try:
+            file, filename, stuff = imp.find_module(subname, path)
+        except ImportError:
+            return None
+        return ImpLoader(file, filename, stuff)
+
+
+class ImpLoader:
+
+    def __init__(self, file, filename, stuff):
+        self.file = file
+        self.filename = filename
+        self.stuff = stuff
+
+    def load_module(self, fullname):
+        mod = imp.load_module(fullname, self.file, self.filename, self.stuff)
+        if self.file:
+            self.file.close()
+        mod.__loader__ = self  # for introspection
+        return mod
+
+
+class ImportHooksBaseTestCase(unittest.TestCase):
+
+    def setUp(self):
+        self.path = sys.path[:]
+        self.meta_path = sys.meta_path[:]
+        self.path_hooks = sys.path_hooks[:]
+        sys.path_importer_cache.clear()
+        self.tracker = ImportTracker()
+        sys.meta_path.insert(0, self.tracker)
+
+    def tearDown(self):
+        sys.path[:] = self.path
+        sys.meta_path[:] = self.meta_path
+        sys.path_hooks[:] = self.path_hooks
+        sys.path_importer_cache.clear()
+        for fullname in self.tracker.imports:
+            if fullname in sys.modules:
+                del sys.modules[fullname]
+
+
+class ImportHooksTestCase(ImportHooksBaseTestCase):
+
+    def doTestImports(self, importer=None):
+        import hooktestmodule
+        import hooktestpackage
+        import hooktestpackage.sub
+        import hooktestpackage.sub.subber
+        self.assertEqual(hooktestmodule.get_name(),
+                         "hooktestmodule")
+        self.assertEqual(hooktestpackage.get_name(),
+                         "hooktestpackage")
+        self.assertEqual(hooktestpackage.sub.get_name(),
+                         "hooktestpackage.sub")
+        self.assertEqual(hooktestpackage.sub.subber.get_name(),
+                         "hooktestpackage.sub.subber")
+        if importer:
+            self.assertEqual(hooktestmodule.__loader__, importer)
+            self.assertEqual(hooktestpackage.__loader__, importer)
+            self.assertEqual(hooktestpackage.sub.__loader__, importer)
+            self.assertEqual(hooktestpackage.sub.subber.__loader__, importer)
+
+        TestImporter.modules['reloadmodule'] = (False, test_co)
+        import reloadmodule
+        self.failIf(hasattr(reloadmodule,'reloaded'))
+
+        TestImporter.modules['reloadmodule'] = (False, reload_co)
+        reload(reloadmodule)
+        self.failUnless(hasattr(reloadmodule,'reloaded'))
+
+        import hooktestpackage.oldabs
+        self.assertEqual(hooktestpackage.oldabs.get_name(),
+                         "hooktestpackage.oldabs")
+        self.assertEqual(hooktestpackage.oldabs.sub,
+                         hooktestpackage.sub)
+
+        import hooktestpackage.newrel
+        self.assertEqual(hooktestpackage.newrel.get_name(),
+                         "hooktestpackage.newrel")
+        self.assertEqual(hooktestpackage.newrel.sub,
+                         hooktestpackage.sub)
+
+        import hooktestpackage.sub.subber.subest as subest
+        self.assertEqual(subest.get_name(),
+                         "hooktestpackage.sub.subber.subest")
+        self.assertEqual(subest.sub,
+                         hooktestpackage.sub)
+
+        import hooktestpackage.futrel
+        self.assertEqual(hooktestpackage.futrel.get_name(),
+                         "hooktestpackage.futrel")
+        self.assertEqual(hooktestpackage.futrel.sub,
+                         hooktestpackage.sub)
+
+        import sub
+        self.assertEqual(sub.get_name(), "sub")
+
+        import hooktestpackage.newabs
+        self.assertEqual(hooktestpackage.newabs.get_name(),
+                         "hooktestpackage.newabs")
+        self.assertEqual(hooktestpackage.newabs.sub, sub)
+
+    def testMetaPath(self):
+        i = MetaImporter()
+        sys.meta_path.append(i)
+        self.doTestImports(i)
+
+    def testPathHook(self):
+        sys.path_hooks.append(PathImporter)
+        sys.path.append(test_path)
+        self.doTestImports()
+
+    def testBlocker(self):
+        mname = "exceptions"  # an arbitrary harmless builtin module
+        if mname in sys.modules:
+            del sys.modules[mname]
+        sys.meta_path.append(ImportBlocker(mname))
+        try:
+            __import__(mname)
+        except ImportError:
+            pass
+        else:
+            self.fail("'%s' was not supposed to be importable" % mname)
+
+    def testImpWrapper(self):
+        i = ImpWrapper()
+        sys.meta_path.append(i)
+        sys.path_hooks.append(ImpWrapper)
+        mnames = ("colorsys", "urlparse", "distutils.core", "compiler.misc")
+        for mname in mnames:
+            parent = mname.split(".")[0]
+            for n in sys.modules.keys():
+                if n.startswith(parent):
+                    del sys.modules[n]
+        for mname in mnames:
+            m = __import__(mname, globals(), locals(), ["__dummy__"])
+            m.__loader__  # to make sure we actually handled the import
+        # Delete urllib from modules because urlparse was imported above.
+        # Without this hack, test_socket_ssl fails if run in this order:
+        # regrtest.py test_codecmaps_tw test_importhooks test_socket_ssl
+        try:
+            del sys.modules['urllib']
+        except KeyError:
+            pass
+
+def test_main():
+    test_support.run_unittest(ImportHooksTestCase)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_index.py
===================================================================
--- vendor/Python/current/Lib/test/test_index.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_index.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,223 @@
+import unittest
+from test import test_support
+import operator
+from sys import maxint
+
+class oldstyle:
+    def __index__(self):
+        return self.ind
+
+class newstyle(object):
+    def __index__(self):
+        return self.ind
+
+class TrapInt(int):
+    def __index__(self):
+        return self
+
+class TrapLong(long):
+    def __index__(self):
+        return self
+
+class BaseTestCase(unittest.TestCase):
+    def setUp(self):
+        self.o = oldstyle()
+        self.n = newstyle()
+
+    def test_basic(self):
+        self.o.ind = -2
+        self.n.ind = 2
+        self.assertEqual(operator.index(self.o), -2)
+        self.assertEqual(operator.index(self.n), 2)
+
+    def test_slice(self):
+        self.o.ind = 1
+        self.n.ind = 2
+        slc = slice(self.o, self.o, self.o)
+        check_slc = slice(1, 1, 1)
+        self.assertEqual(slc.indices(self.o), check_slc.indices(1))
+        slc = slice(self.n, self.n, self.n)
+        check_slc = slice(2, 2, 2)
+        self.assertEqual(slc.indices(self.n), check_slc.indices(2))
+
+    def test_wrappers(self):
+        self.o.ind = 4
+        self.n.ind = 5
+        self.assertEqual(6 .__index__(), 6)
+        self.assertEqual(-7L.__index__(), -7)
+        self.assertEqual(self.o.__index__(), 4)
+        self.assertEqual(self.n.__index__(), 5)
+
+    def test_subclasses(self):
+        r = range(10)
+        self.assertEqual(r[TrapInt(5):TrapInt(10)], r[5:10])
+        self.assertEqual(r[TrapLong(5):TrapLong(10)], r[5:10])
+        self.assertEqual(slice(TrapInt()).indices(0), (0,0,1))
+        self.assertEqual(slice(TrapLong(0)).indices(0), (0,0,1))
+
+    def test_error(self):
+        self.o.ind = 'dumb'
+        self.n.ind = 'bad'
+        self.failUnlessRaises(TypeError, operator.index, self.o)
+        self.failUnlessRaises(TypeError, operator.index, self.n)
+        self.failUnlessRaises(TypeError, slice(self.o).indices, 0)
+        self.failUnlessRaises(TypeError, slice(self.n).indices, 0)
+
+
+class SeqTestCase(unittest.TestCase):
+    # This test case isn't run directly. It just defines common tests
+    # to the different sequence types below
+    def setUp(self):
+        self.o = oldstyle()
+        self.n = newstyle()
+        self.o2 = oldstyle()
+        self.n2 = newstyle()
+
+    def test_index(self):
+        self.o.ind = -2
+        self.n.ind = 2
+        self.assertEqual(self.seq[self.n], self.seq[2])
+        self.assertEqual(self.seq[self.o], self.seq[-2])
+
+    def test_slice(self):
+        self.o.ind = 1
+        self.o2.ind = 3
+        self.n.ind = 2
+        self.n2.ind = 4
+        self.assertEqual(self.seq[self.o:self.o2], self.seq[1:3])
+        self.assertEqual(self.seq[self.n:self.n2], self.seq[2:4])
+
+    def test_repeat(self):
+        self.o.ind = 3
+        self.n.ind = 2
+        self.assertEqual(self.seq * self.o, self.seq * 3)
+        self.assertEqual(self.seq * self.n, self.seq * 2)
+        self.assertEqual(self.o * self.seq, self.seq * 3)
+        self.assertEqual(self.n * self.seq, self.seq * 2)
+
+    def test_wrappers(self):
+        self.o.ind = 4
+        self.n.ind = 5
+        self.assertEqual(self.seq.__getitem__(self.o), self.seq[4])
+        self.assertEqual(self.seq.__mul__(self.o), self.seq * 4)
+        self.assertEqual(self.seq.__rmul__(self.o), self.seq * 4)
+        self.assertEqual(self.seq.__getitem__(self.n), self.seq[5])
+        self.assertEqual(self.seq.__mul__(self.n), self.seq * 5)
+        self.assertEqual(self.seq.__rmul__(self.n), self.seq * 5)
+
+    def test_subclasses(self):
+        self.assertEqual(self.seq[TrapInt()], self.seq[0])
+        self.assertEqual(self.seq[TrapLong()], self.seq[0])
+
+    def test_error(self):
+        self.o.ind = 'dumb'
+        self.n.ind = 'bad'
+        indexobj = lambda x, obj: obj.seq[x]
+        self.failUnlessRaises(TypeError, indexobj, self.o, self)
+        self.failUnlessRaises(TypeError, indexobj, self.n, self)
+        sliceobj = lambda x, obj: obj.seq[x:]
+        self.failUnlessRaises(TypeError, sliceobj, self.o, self)
+        self.failUnlessRaises(TypeError, sliceobj, self.n, self)
+
+
+class ListTestCase(SeqTestCase):
+    seq = [0,10,20,30,40,50]
+
+    def test_setdelitem(self):
+        self.o.ind = -2
+        self.n.ind = 2
+        lst = list('ab!cdefghi!j')
+        del lst[self.o]
+        del lst[self.n]
+        lst[self.o] = 'X'
+        lst[self.n] = 'Y'
+        self.assertEqual(lst, list('abYdefghXj'))
+
+        lst = [5, 6, 7, 8, 9, 10, 11]
+        lst.__setitem__(self.n, "here")
+        self.assertEqual(lst, [5, 6, "here", 8, 9, 10, 11])
+        lst.__delitem__(self.n)
+        self.assertEqual(lst, [5, 6, 8, 9, 10, 11])
+
+    def test_inplace_repeat(self):
+        self.o.ind = 2
+        self.n.ind = 3
+        lst = [6, 4]
+        lst *= self.o
+        self.assertEqual(lst, [6, 4, 6, 4])
+        lst *= self.n
+        self.assertEqual(lst, [6, 4, 6, 4] * 3)
+
+        lst = [5, 6, 7, 8, 9, 11]
+        l2 = lst.__imul__(self.n)
+        self.assert_(l2 is lst)
+        self.assertEqual(lst, [5, 6, 7, 8, 9, 11] * 3)
+
+
+class TupleTestCase(SeqTestCase):
+    seq = (0,10,20,30,40,50)
+
+class StringTestCase(SeqTestCase):
+    seq = "this is a test"
+
+class UnicodeTestCase(SeqTestCase):
+    seq = u"this is a test"
+
+
+class XRangeTestCase(unittest.TestCase):
+
+    def test_xrange(self):
+        n = newstyle()
+        n.ind = 5
+        self.assertEqual(xrange(1, 20)[n], 6)
+        self.assertEqual(xrange(1, 20).__getitem__(n), 6)
+
+class OverflowTestCase(unittest.TestCase):
+
+    def setUp(self):
+        self.pos = 2**100
+        self.neg = -self.pos
+
+    def test_large_longs(self):
+        self.assertEqual(self.pos.__index__(), self.pos)
+        self.assertEqual(self.neg.__index__(), self.neg)
+
+    def _getitem_helper(self, base):
+        class GetItem(base):
+            def __len__(self):
+                return maxint
+            def __getitem__(self, key):
+                return key
+            def __getslice__(self, i, j):
+                return i, j
+        x = GetItem()
+        self.assertEqual(x[self.pos], self.pos)
+        self.assertEqual(x[self.neg], self.neg)
+        self.assertEqual(x[self.neg:self.pos], (-1, maxint))
+        self.assertEqual(x[self.neg:self.pos:1].indices(maxint), (0, maxint, 1))
+
+    def test_getitem(self):
+        self._getitem_helper(object)
+
+    def test_getitem_classic(self):
+        class Empty: pass
+        self._getitem_helper(Empty)
+
+    def test_sequence_repeat(self):
+        self.failUnlessRaises(OverflowError, lambda: "a" * self.pos)
+        self.failUnlessRaises(OverflowError, lambda: "a" * self.neg)
+
+
+def test_main():
+    test_support.run_unittest(
+        BaseTestCase,
+        ListTestCase,
+        TupleTestCase,
+        StringTestCase,
+        UnicodeTestCase,
+        XRangeTestCase,
+        OverflowTestCase,
+    )
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_inspect.py
===================================================================
--- vendor/Python/current/Lib/test/test_inspect.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_inspect.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,482 @@
+import sys
+import types
+import unittest
+import inspect
+import datetime
+
+from test.test_support import TESTFN, run_unittest
+
+from test import inspect_fodder as mod
+from test import inspect_fodder2 as mod2
+
+# Functions tested in this suite:
+# ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode,
+# isbuiltin, isroutine, getmembers, getdoc, getfile, getmodule,
+# getsourcefile, getcomments, getsource, getclasstree, getargspec,
+# getargvalues, formatargspec, formatargvalues, currentframe, stack, trace
+# isdatadescriptor
+
+modfile = mod.__file__
+if modfile.endswith(('c', 'o')):
+    modfile = modfile[:-1]
+
+import __builtin__
+
+try:
+    1/0
+except:
+    tb = sys.exc_traceback
+
+git = mod.StupidGit()
+
+class IsTestBase(unittest.TestCase):
+    predicates = set([inspect.isbuiltin, inspect.isclass, inspect.iscode,
+                      inspect.isframe, inspect.isfunction, inspect.ismethod,
+                      inspect.ismodule, inspect.istraceback])
+
+    def istest(self, predicate, exp):
+        obj = eval(exp)
+        self.failUnless(predicate(obj), '%s(%s)' % (predicate.__name__, exp))
+
+        for other in self.predicates - set([predicate]):
+            self.failIf(other(obj), 'not %s(%s)' % (other.__name__, exp))
+
+class TestPredicates(IsTestBase):
+    def test_thirteen(self):
+        count = len(filter(lambda x:x.startswith('is'), dir(inspect)))
+        # Doc/lib/libinspect.tex claims there are 13 such functions
+        expected = 13
+        err_msg = "There are %d (not %d) is* functions" % (count, expected)
+        self.assertEqual(count, expected, err_msg)
+
+    def test_excluding_predicates(self):
+        self.istest(inspect.isbuiltin, 'sys.exit')
+        self.istest(inspect.isbuiltin, '[].append')
+        self.istest(inspect.isclass, 'mod.StupidGit')
+        self.istest(inspect.iscode, 'mod.spam.func_code')
+        self.istest(inspect.isframe, 'tb.tb_frame')
+        self.istest(inspect.isfunction, 'mod.spam')
+        self.istest(inspect.ismethod, 'mod.StupidGit.abuse')
+        self.istest(inspect.ismethod, 'git.argue')
+        self.istest(inspect.ismodule, 'mod')
+        self.istest(inspect.istraceback, 'tb')
+        self.istest(inspect.isdatadescriptor, '__builtin__.file.closed')
+        self.istest(inspect.isdatadescriptor, '__builtin__.file.softspace')
+        if hasattr(types, 'GetSetDescriptorType'):
+            self.istest(inspect.isgetsetdescriptor,
+                        'type(tb.tb_frame).f_locals')
+        else:
+            self.failIf(inspect.isgetsetdescriptor(type(tb.tb_frame).f_locals))
+        if hasattr(types, 'MemberDescriptorType'):
+            self.istest(inspect.ismemberdescriptor, 'datetime.timedelta.days')
+        else:
+            self.failIf(inspect.ismemberdescriptor(datetime.timedelta.days))
+
+    def test_isroutine(self):
+        self.assert_(inspect.isroutine(mod.spam))
+        self.assert_(inspect.isroutine([].count))
+
+class TestInterpreterStack(IsTestBase):
+    def __init__(self, *args, **kwargs):
+        unittest.TestCase.__init__(self, *args, **kwargs)
+
+        git.abuse(7, 8, 9)
+
+    def test_abuse_done(self):
+        self.istest(inspect.istraceback, 'git.ex[2]')
+        self.istest(inspect.isframe, 'mod.fr')
+
+    def test_stack(self):
+        self.assert_(len(mod.st) >= 5)
+        self.assertEqual(mod.st[0][1:],
+             (modfile, 16, 'eggs', ['    st = inspect.stack()\n'], 0))
+        self.assertEqual(mod.st[1][1:],
+             (modfile, 9, 'spam', ['    eggs(b + d, c + f)\n'], 0))
+        self.assertEqual(mod.st[2][1:],
+             (modfile, 43, 'argue', ['            spam(a, b, c)\n'], 0))
+        self.assertEqual(mod.st[3][1:],
+             (modfile, 39, 'abuse', ['        self.argue(a, b, c)\n'], 0))
+
+    def test_trace(self):
+        self.assertEqual(len(git.tr), 3)
+        self.assertEqual(git.tr[0][1:], (modfile, 43, 'argue',
+                                         ['            spam(a, b, c)\n'], 0))
+        self.assertEqual(git.tr[1][1:], (modfile, 9, 'spam',
+                                         ['    eggs(b + d, c + f)\n'], 0))
+        self.assertEqual(git.tr[2][1:], (modfile, 18, 'eggs',
+                                         ['    q = y / 0\n'], 0))
+
+    def test_frame(self):
+        args, varargs, varkw, locals = inspect.getargvalues(mod.fr)
+        self.assertEqual(args, ['x', 'y'])
+        self.assertEqual(varargs, None)
+        self.assertEqual(varkw, None)
+        self.assertEqual(locals, {'x': 11, 'p': 11, 'y': 14})
+        self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
+                         '(x=11, y=14)')
+
+    def test_previous_frame(self):
+        args, varargs, varkw, locals = inspect.getargvalues(mod.fr.f_back)
+        self.assertEqual(args, ['a', 'b', 'c', 'd', ['e', ['f']]])
+        self.assertEqual(varargs, 'g')
+        self.assertEqual(varkw, 'h')
+        self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
+             '(a=7, b=8, c=9, d=3, (e=4, (f=5,)), *g=(), **h={})')
+
+class GetSourceBase(unittest.TestCase):
+    # Subclasses must override.
+    fodderFile = None
+
+    def __init__(self, *args, **kwargs):
+        unittest.TestCase.__init__(self, *args, **kwargs)
+
+        self.source = file(inspect.getsourcefile(self.fodderFile)).read()
+
+    def sourcerange(self, top, bottom):
+        lines = self.source.split("\n")
+        return "\n".join(lines[top-1:bottom]) + "\n"
+
+    def assertSourceEqual(self, obj, top, bottom):
+        self.assertEqual(inspect.getsource(obj),
+                         self.sourcerange(top, bottom))
+
+class TestRetrievingSourceCode(GetSourceBase):
+    fodderFile = mod
+
+    def test_getclasses(self):
+        classes = inspect.getmembers(mod, inspect.isclass)
+        self.assertEqual(classes,
+                         [('FesteringGob', mod.FesteringGob),
+                          ('MalodorousPervert', mod.MalodorousPervert),
+                          ('ParrotDroppings', mod.ParrotDroppings),
+                          ('StupidGit', mod.StupidGit)])
+        tree = inspect.getclasstree([cls[1] for cls in classes], 1)
+        self.assertEqual(tree,
+                         [(mod.ParrotDroppings, ()),
+                          (mod.StupidGit, ()),
+                          [(mod.MalodorousPervert, (mod.StupidGit,)),
+                           [(mod.FesteringGob, (mod.MalodorousPervert,
+                                                   mod.ParrotDroppings))
+                            ]
+                           ]
+                          ])
+
+    def test_getfunctions(self):
+        functions = inspect.getmembers(mod, inspect.isfunction)
+        self.assertEqual(functions, [('eggs', mod.eggs),
+                                     ('spam', mod.spam)])
+
+    def test_getdoc(self):
+        self.assertEqual(inspect.getdoc(mod), 'A module docstring.')
+        self.assertEqual(inspect.getdoc(mod.StupidGit),
+                         'A longer,\n\nindented\n\ndocstring.')
+        self.assertEqual(inspect.getdoc(git.abuse),
+                         'Another\n\ndocstring\n\ncontaining\n\ntabs')
+
+    def test_getcomments(self):
+        self.assertEqual(inspect.getcomments(mod), '# line 1\n')
+        self.assertEqual(inspect.getcomments(mod.StupidGit), '# line 20\n')
+
+    def test_getmodule(self):
+        # Check actual module
+        self.assertEqual(inspect.getmodule(mod), mod)
+        # Check class (uses __module__ attribute)
+        self.assertEqual(inspect.getmodule(mod.StupidGit), mod)
+        # Check a method (no __module__ attribute, falls back to filename)
+        self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
+        # Do it again (check the caching isn't broken)
+        self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
+        # Check a builtin
+        self.assertEqual(inspect.getmodule(str), sys.modules["__builtin__"])
+        # Check filename override
+        self.assertEqual(inspect.getmodule(None, modfile), mod)
+
+    def test_getsource(self):
+        self.assertSourceEqual(git.abuse, 29, 39)
+        self.assertSourceEqual(mod.StupidGit, 21, 46)
+
+    def test_getsourcefile(self):
+        self.assertEqual(inspect.getsourcefile(mod.spam), modfile)
+        self.assertEqual(inspect.getsourcefile(git.abuse), modfile)
+
+    def test_getfile(self):
+        self.assertEqual(inspect.getfile(mod.StupidGit), mod.__file__)
+
+    def test_getmodule_recursion(self):
+        from new import module
+        name = '__inspect_dummy'
+        m = sys.modules[name] = module(name)
+        m.__file__ = "<string>" # hopefully not a real filename...
+        m.__loader__ = "dummy"  # pretend the filename is understood by a loader
+        exec "def x(): pass" in m.__dict__
+        self.assertEqual(inspect.getsourcefile(m.x.func_code), '<string>')
+        del sys.modules[name]
+        inspect.getmodule(compile('a=10','','single'))
+
+class TestDecorators(GetSourceBase):
+    fodderFile = mod2
+
+    def test_wrapped_decorator(self):
+        self.assertSourceEqual(mod2.wrapped, 14, 17)
+
+    def test_replacing_decorator(self):
+        self.assertSourceEqual(mod2.gone, 9, 10)
+
+class TestOneliners(GetSourceBase):
+    fodderFile = mod2
+    def test_oneline_lambda(self):
+        # Test inspect.getsource with a one-line lambda function.
+        self.assertSourceEqual(mod2.oll, 25, 25)
+
+    def test_threeline_lambda(self):
+        # Test inspect.getsource with a three-line lambda function,
+        # where the second and third lines are _not_ indented.
+        self.assertSourceEqual(mod2.tll, 28, 30)
+
+    def test_twoline_indented_lambda(self):
+        # Test inspect.getsource with a two-line lambda function,
+        # where the second line _is_ indented.
+        self.assertSourceEqual(mod2.tlli, 33, 34)
+
+    def test_onelinefunc(self):
+        # Test inspect.getsource with a regular one-line function.
+        self.assertSourceEqual(mod2.onelinefunc, 37, 37)
+
+    def test_manyargs(self):
+        # Test inspect.getsource with a regular function where
+        # the arguments are on two lines and _not_ indented and
+        # the body on the second line with the last arguments.
+        self.assertSourceEqual(mod2.manyargs, 40, 41)
+
+    def test_twolinefunc(self):
+        # Test inspect.getsource with a regular function where
+        # the body is on two lines, following the argument list and
+        # continued on the next line by a \\.
+        self.assertSourceEqual(mod2.twolinefunc, 44, 45)
+
+    def test_lambda_in_list(self):
+        # Test inspect.getsource with a one-line lambda function
+        # defined in a list, indented.
+        self.assertSourceEqual(mod2.a[1], 49, 49)
+
+    def test_anonymous(self):
+        # Test inspect.getsource with a lambda function defined
+        # as argument to another function.
+        self.assertSourceEqual(mod2.anonymous, 55, 55)
+
+class TestBuggyCases(GetSourceBase):
+    fodderFile = mod2
+
+    def test_with_comment(self):
+        self.assertSourceEqual(mod2.with_comment, 58, 59)
+
+    def test_multiline_sig(self):
+        self.assertSourceEqual(mod2.multiline_sig[0], 63, 64)
+
+    def test_nested_class(self):
+        self.assertSourceEqual(mod2.func69().func71, 71, 72)
+
+    def test_one_liner_followed_by_non_name(self):
+        self.assertSourceEqual(mod2.func77, 77, 77)
+
+    def test_one_liner_dedent_non_name(self):
+        self.assertSourceEqual(mod2.cls82.func83, 83, 83)
+
+    def test_with_comment_instead_of_docstring(self):
+        self.assertSourceEqual(mod2.func88, 88, 90)
+
+    def test_method_in_dynamic_class(self):
+        self.assertSourceEqual(mod2.method_in_dynamic_class, 95, 97)
+
+# Helper for testing classify_class_attrs.
+def attrs_wo_objs(cls):
+    return [t[:3] for t in inspect.classify_class_attrs(cls)]
+
+class TestClassesAndFunctions(unittest.TestCase):
+    def test_classic_mro(self):
+        # Test classic-class method resolution order.
+        class A:    pass
+        class B(A): pass
+        class C(A): pass
+        class D(B, C): pass
+
+        expected = (D, B, A, C)
+        got = inspect.getmro(D)
+        self.assertEqual(expected, got)
+
+    def test_newstyle_mro(self):
+        # The same w/ new-class MRO.
+        class A(object):    pass
+        class B(A): pass
+        class C(A): pass
+        class D(B, C): pass
+
+        expected = (D, B, C, A, object)
+        got = inspect.getmro(D)
+        self.assertEqual(expected, got)
+
+    def assertArgSpecEquals(self, routine, args_e, varargs_e = None,
+                            varkw_e = None, defaults_e = None,
+                            formatted = None):
+        args, varargs, varkw, defaults = inspect.getargspec(routine)
+        self.assertEqual(args, args_e)
+        self.assertEqual(varargs, varargs_e)
+        self.assertEqual(varkw, varkw_e)
+        self.assertEqual(defaults, defaults_e)
+        if formatted is not None:
+            self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults),
+                             formatted)
+
+    def test_getargspec(self):
+        self.assertArgSpecEquals(mod.eggs, ['x', 'y'], formatted = '(x, y)')
+
+        self.assertArgSpecEquals(mod.spam,
+                                 ['a', 'b', 'c', 'd', ['e', ['f']]],
+                                 'g', 'h', (3, (4, (5,))),
+                                 '(a, b, c, d=3, (e, (f,))=(4, (5,)), *g, **h)')
+
+    def test_getargspec_method(self):
+        class A(object):
+            def m(self):
+                pass
+        self.assertArgSpecEquals(A.m, ['self'])
+
+    def test_getargspec_sublistofone(self):
+        def sublistOfOne((foo,)): return 1
+        self.assertArgSpecEquals(sublistOfOne, [['foo']])
+
+        def fakeSublistOfOne((foo)): return 1
+        self.assertArgSpecEquals(fakeSublistOfOne, ['foo'])
+
+    def test_classify_oldstyle(self):
+        class A:
+            def s(): pass
+            s = staticmethod(s)
+
+            def c(cls): pass
+            c = classmethod(c)
+
+            def getp(self): pass
+            p = property(getp)
+
+            def m(self): pass
+
+            def m1(self): pass
+
+            datablob = '1'
+
+        attrs = attrs_wo_objs(A)
+        self.assert_(('s', 'static method', A) in attrs, 'missing static method')
+        self.assert_(('c', 'class method', A) in attrs, 'missing class method')
+        self.assert_(('p', 'property', A) in attrs, 'missing property')
+        self.assert_(('m', 'method', A) in attrs, 'missing plain method')
+        self.assert_(('m1', 'method', A) in attrs, 'missing plain method')
+        self.assert_(('datablob', 'data', A) in attrs, 'missing data')
+
+        class B(A):
+            def m(self): pass
+
+        attrs = attrs_wo_objs(B)
+        self.assert_(('s', 'static method', A) in attrs, 'missing static method')
+        self.assert_(('c', 'class method', A) in attrs, 'missing class method')
+        self.assert_(('p', 'property', A) in attrs, 'missing property')
+        self.assert_(('m', 'method', B) in attrs, 'missing plain method')
+        self.assert_(('m1', 'method', A) in attrs, 'missing plain method')
+        self.assert_(('datablob', 'data', A) in attrs, 'missing data')
+
+
+        class C(A):
+            def m(self): pass
+            def c(self): pass
+
+        attrs = attrs_wo_objs(C)
+        self.assert_(('s', 'static method', A) in attrs, 'missing static method')
+        self.assert_(('c', 'method', C) in attrs, 'missing plain method')
+        self.assert_(('p', 'property', A) in attrs, 'missing property')
+        self.assert_(('m', 'method', C) in attrs, 'missing plain method')
+        self.assert_(('m1', 'method', A) in attrs, 'missing plain method')
+        self.assert_(('datablob', 'data', A) in attrs, 'missing data')
+
+        class D(B, C):
+            def m1(self): pass
+
+        attrs = attrs_wo_objs(D)
+        self.assert_(('s', 'static method', A) in attrs, 'missing static method')
+        self.assert_(('c', 'class method', A) in attrs, 'missing class method')
+        self.assert_(('p', 'property', A) in attrs, 'missing property')
+        self.assert_(('m', 'method', B) in attrs, 'missing plain method')
+        self.assert_(('m1', 'method', D) in attrs, 'missing plain method')
+        self.assert_(('datablob', 'data', A) in attrs, 'missing data')
+
+    # Repeat all that, but w/ new-style classes.
+    def test_classify_newstyle(self):
+        class A(object):
+
+            def s(): pass
+            s = staticmethod(s)
+
+            def c(cls): pass
+            c = classmethod(c)
+
+            def getp(self): pass
+            p = property(getp)
+
+            def m(self): pass
+
+            def m1(self): pass
+
+            datablob = '1'
+
+        attrs = attrs_wo_objs(A)
+        self.assert_(('s', 'static method', A) in attrs, 'missing static method')
+        self.assert_(('c', 'class method', A) in attrs, 'missing class method')
+        self.assert_(('p', 'property', A) in attrs, 'missing property')
+        self.assert_(('m', 'method', A) in attrs, 'missing plain method')
+        self.assert_(('m1', 'method', A) in attrs, 'missing plain method')
+        self.assert_(('datablob', 'data', A) in attrs, 'missing data')
+
+        class B(A):
+
+            def m(self): pass
+
+        attrs = attrs_wo_objs(B)
+        self.assert_(('s', 'static method', A) in attrs, 'missing static method')
+        self.assert_(('c', 'class method', A) in attrs, 'missing class method')
+        self.assert_(('p', 'property', A) in attrs, 'missing property')
+        self.assert_(('m', 'method', B) in attrs, 'missing plain method')
+        self.assert_(('m1', 'method', A) in attrs, 'missing plain method')
+        self.assert_(('datablob', 'data', A) in attrs, 'missing data')
+
+
+        class C(A):
+
+            def m(self): pass
+            def c(self): pass
+
+        attrs = attrs_wo_objs(C)
+        self.assert_(('s', 'static method', A) in attrs, 'missing static method')
+        self.assert_(('c', 'method', C) in attrs, 'missing plain method')
+        self.assert_(('p', 'property', A) in attrs, 'missing property')
+        self.assert_(('m', 'method', C) in attrs, 'missing plain method')
+        self.assert_(('m1', 'method', A) in attrs, 'missing plain method')
+        self.assert_(('datablob', 'data', A) in attrs, 'missing data')
+
+        class D(B, C):
+
+            def m1(self): pass
+
+        attrs = attrs_wo_objs(D)
+        self.assert_(('s', 'static method', A) in attrs, 'missing static method')
+        self.assert_(('c', 'method', C) in attrs, 'missing plain method')
+        self.assert_(('p', 'property', A) in attrs, 'missing property')
+        self.assert_(('m', 'method', B) in attrs, 'missing plain method')
+        self.assert_(('m1', 'method', D) in attrs, 'missing plain method')
+        self.assert_(('datablob', 'data', A) in attrs, 'missing data')
+
+def test_main():
+    run_unittest(TestDecorators, TestRetrievingSourceCode, TestOneliners,
+                 TestBuggyCases,
+                 TestInterpreterStack, TestClassesAndFunctions, TestPredicates)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_ioctl.py
===================================================================
--- vendor/Python/current/Lib/test/test_ioctl.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_ioctl.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,41 @@
+import unittest
+from test.test_support import TestSkipped, run_unittest
+import os, struct
+try:
+    import fcntl, termios
+except ImportError:
+    raise TestSkipped("No fcntl or termios module")
+if not hasattr(termios,'TIOCGPGRP'):
+    raise TestSkipped("termios module doesn't have TIOCGPGRP")
+
+try:
+    tty = open("/dev/tty", "r")
+    tty.close()
+except IOError:
+    raise TestSkipped("Unable to open /dev/tty")
+
+class IoctlTests(unittest.TestCase):
+    def test_ioctl(self):
+        # If this process has been put into the background, TIOCGPGRP returns
+        # the session ID instead of the process group id.
+        ids = (os.getpgrp(), os.getsid(0))
+        tty = open("/dev/tty", "r")
+        r = fcntl.ioctl(tty, termios.TIOCGPGRP, "    ")
+        rpgrp = struct.unpack("i", r)[0]
+        self.assert_(rpgrp in ids, "%s not in %s" % (rpgrp, ids))
+
+    def test_ioctl_mutate(self):
+        import array
+        buf = array.array('i', [0])
+        ids = (os.getpgrp(), os.getsid(0))
+        tty = open("/dev/tty", "r")
+        r = fcntl.ioctl(tty, termios.TIOCGPGRP, buf, 1)
+        rpgrp = buf[0]
+        self.assertEquals(r, 0)
+        self.assert_(rpgrp in ids, "%s not in %s" % (rpgrp, ids))
+
+def test_main():
+    run_unittest(IoctlTests)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_isinstance.py
===================================================================
--- vendor/Python/current/Lib/test/test_isinstance.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_isinstance.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,277 @@
+# Tests some corner cases with isinstance() and issubclass().  While these
+# tests use new style classes and properties, they actually do whitebox
+# testing of error conditions uncovered when using extension types.
+
+import unittest
+from test import test_support
+import sys
+
+
+
+class TestIsInstanceExceptions(unittest.TestCase):
+    # Test to make sure that an AttributeError when accessing the instance's
+    # class's bases is masked.  This was actually a bug in Python 2.2 and
+    # 2.2.1 where the exception wasn't caught but it also wasn't being cleared
+    # (leading to an "undetected error" in the debug build).  Set up is,
+    # isinstance(inst, cls) where:
+    #
+    # - inst isn't an InstanceType
+    # - cls isn't a ClassType, a TypeType, or a TupleType
+    # - cls has a __bases__ attribute
+    # - inst has a __class__ attribute
+    # - inst.__class__ as no __bases__ attribute
+    #
+    # Sounds complicated, I know, but this mimics a situation where an
+    # extension type raises an AttributeError when its __bases__ attribute is
+    # gotten.  In that case, isinstance() should return False.
+    def test_class_has_no_bases(self):
+        class I(object):
+            def getclass(self):
+                # This must return an object that has no __bases__ attribute
+                return None
+            __class__ = property(getclass)
+
+        class C(object):
+            def getbases(self):
+                return ()
+            __bases__ = property(getbases)
+
+        self.assertEqual(False, isinstance(I(), C()))
+
+    # Like above except that inst.__class__.__bases__ raises an exception
+    # other than AttributeError
+    def test_bases_raises_other_than_attribute_error(self):
+        class E(object):
+            def getbases(self):
+                raise RuntimeError
+            __bases__ = property(getbases)
+
+        class I(object):
+            def getclass(self):
+                return E()
+            __class__ = property(getclass)
+
+        class C(object):
+            def getbases(self):
+                return ()
+            __bases__ = property(getbases)
+
+        self.assertRaises(RuntimeError, isinstance, I(), C())
+
+    # Here's a situation where getattr(cls, '__bases__') raises an exception.
+    # If that exception is not AttributeError, it should not get masked
+    def test_dont_mask_non_attribute_error(self):
+        class I: pass
+
+        class C(object):
+            def getbases(self):
+                raise RuntimeError
+            __bases__ = property(getbases)
+
+        self.assertRaises(RuntimeError, isinstance, I(), C())
+
+    # Like above, except that getattr(cls, '__bases__') raises an
+    # AttributeError, which /should/ get masked as a TypeError
+    def test_mask_attribute_error(self):
+        class I: pass
+
+        class C(object):
+            def getbases(self):
+                raise AttributeError
+            __bases__ = property(getbases)
+
+        self.assertRaises(TypeError, isinstance, I(), C())
+
+
+
+# These tests are similar to above, but tickle certain code paths in
+# issubclass() instead of isinstance() -- really PyObject_IsSubclass()
+# vs. PyObject_IsInstance().
+class TestIsSubclassExceptions(unittest.TestCase):
+    def test_dont_mask_non_attribute_error(self):
+        class C(object):
+            def getbases(self):
+                raise RuntimeError
+            __bases__ = property(getbases)
+
+        class S(C): pass
+
+        self.assertRaises(RuntimeError, issubclass, C(), S())
+
+    def test_mask_attribute_error(self):
+        class C(object):
+            def getbases(self):
+                raise AttributeError
+            __bases__ = property(getbases)
+
+        class S(C): pass
+
+        self.assertRaises(TypeError, issubclass, C(), S())
+
+    # Like above, but test the second branch, where the __bases__ of the
+    # second arg (the cls arg) is tested.  This means the first arg must
+    # return a valid __bases__, and it's okay for it to be a normal --
+    # unrelated by inheritance -- class.
+    def test_dont_mask_non_attribute_error_in_cls_arg(self):
+        class B: pass
+
+        class C(object):
+            def getbases(self):
+                raise RuntimeError
+            __bases__ = property(getbases)
+
+        self.assertRaises(RuntimeError, issubclass, B, C())
+
+    def test_mask_attribute_error_in_cls_arg(self):
+        class B: pass
+
+        class C(object):
+            def getbases(self):
+                raise AttributeError
+            __bases__ = property(getbases)
+
+        self.assertRaises(TypeError, issubclass, B, C())
+
+
+
+# meta classes for creating abstract classes and instances
+class AbstractClass(object):
+    def __init__(self, bases):
+        self.bases = bases
+
+    def getbases(self):
+        return self.bases
+    __bases__ = property(getbases)
+
+    def __call__(self):
+        return AbstractInstance(self)
+
+class AbstractInstance(object):
+    def __init__(self, klass):
+        self.klass = klass
+
+    def getclass(self):
+        return self.klass
+    __class__ = property(getclass)
+
+# abstract classes
+AbstractSuper = AbstractClass(bases=())
+
+AbstractChild = AbstractClass(bases=(AbstractSuper,))
+
+# normal classes
+class Super:
+    pass
+
+class Child(Super):
+    pass
+
+# new-style classes
+class NewSuper(object):
+    pass
+
+class NewChild(NewSuper):
+    pass
+
+
+
+class TestIsInstanceIsSubclass(unittest.TestCase):
+    # Tests to ensure that isinstance and issubclass work on abstract
+    # classes and instances.  Before the 2.2 release, TypeErrors were
+    # raised when boolean values should have been returned.  The bug was
+    # triggered by mixing 'normal' classes and instances were with
+    # 'abstract' classes and instances.  This case tries to test all
+    # combinations.
+
+    def test_isinstance_normal(self):
+        # normal instances
+        self.assertEqual(True, isinstance(Super(), Super))
+        self.assertEqual(False, isinstance(Super(), Child))
+        self.assertEqual(False, isinstance(Super(), AbstractSuper))
+        self.assertEqual(False, isinstance(Super(), AbstractChild))
+
+        self.assertEqual(True, isinstance(Child(), Super))
+        self.assertEqual(False, isinstance(Child(), AbstractSuper))
+
+    def test_isinstance_abstract(self):
+        # abstract instances
+        self.assertEqual(True, isinstance(AbstractSuper(), AbstractSuper))
+        self.assertEqual(False, isinstance(AbstractSuper(), AbstractChild))
+        self.assertEqual(False, isinstance(AbstractSuper(), Super))
+        self.assertEqual(False, isinstance(AbstractSuper(), Child))
+
+        self.assertEqual(True, isinstance(AbstractChild(), AbstractChild))
+        self.assertEqual(True, isinstance(AbstractChild(), AbstractSuper))
+        self.assertEqual(False, isinstance(AbstractChild(), Super))
+        self.assertEqual(False, isinstance(AbstractChild(), Child))
+
+    def test_subclass_normal(self):
+        # normal classes
+        self.assertEqual(True, issubclass(Super, Super))
+        self.assertEqual(False, issubclass(Super, AbstractSuper))
+        self.assertEqual(False, issubclass(Super, Child))
+
+        self.assertEqual(True, issubclass(Child, Child))
+        self.assertEqual(True, issubclass(Child, Super))
+        self.assertEqual(False, issubclass(Child, AbstractSuper))
+
+    def test_subclass_abstract(self):
+        # abstract classes
+        self.assertEqual(True, issubclass(AbstractSuper, AbstractSuper))
+        self.assertEqual(False, issubclass(AbstractSuper, AbstractChild))
+        self.assertEqual(False, issubclass(AbstractSuper, Child))
+
+        self.assertEqual(True, issubclass(AbstractChild, AbstractChild))
+        self.assertEqual(True, issubclass(AbstractChild, AbstractSuper))
+        self.assertEqual(False, issubclass(AbstractChild, Super))
+        self.assertEqual(False, issubclass(AbstractChild, Child))
+
+    def test_subclass_tuple(self):
+        # test with a tuple as the second argument classes
+        self.assertEqual(True, issubclass(Child, (Child,)))
+        self.assertEqual(True, issubclass(Child, (Super,)))
+        self.assertEqual(False, issubclass(Super, (Child,)))
+        self.assertEqual(True, issubclass(Super, (Child, Super)))
+        self.assertEqual(False, issubclass(Child, ()))
+        self.assertEqual(True, issubclass(Super, (Child, (Super,))))
+
+        self.assertEqual(True, issubclass(NewChild, (NewChild,)))
+        self.assertEqual(True, issubclass(NewChild, (NewSuper,)))
+        self.assertEqual(False, issubclass(NewSuper, (NewChild,)))
+        self.assertEqual(True, issubclass(NewSuper, (NewChild, NewSuper)))
+        self.assertEqual(False, issubclass(NewChild, ()))
+        self.assertEqual(True, issubclass(NewSuper, (NewChild, (NewSuper,))))
+
+        self.assertEqual(True, issubclass(int, (long, (float, int))))
+        if test_support.have_unicode:
+            self.assertEqual(True, issubclass(str, (unicode, (Child, NewChild, basestring))))
+
+    def test_subclass_recursion_limit(self):
+        # make sure that issubclass raises RuntimeError before the C stack is
+        # blown
+        self.assertRaises(RuntimeError, blowstack, issubclass, str, str)
+
+    def test_isinstance_recursion_limit(self):
+        # make sure that issubclass raises RuntimeError before the C stack is
+        # blown
+        self.assertRaises(RuntimeError, blowstack, isinstance, '', str)
+
+def blowstack(fxn, arg, compare_to):
+    # Make sure that calling isinstance with a deeply nested tuple for its
+    # argument will raise RuntimeError eventually.
+    tuple_arg = (compare_to,)
+    for cnt in xrange(sys.getrecursionlimit()+5):
+        tuple_arg = (tuple_arg,)
+        fxn(arg, tuple_arg)
+
+
+def test_main():
+    test_support.run_unittest(
+        TestIsInstanceExceptions,
+        TestIsSubclassExceptions,
+        TestIsInstanceIsSubclass
+    )
+
+
+if __name__ == '__main__':
+    test_main()

Added: vendor/Python/current/Lib/test/test_iter.py
===================================================================
--- vendor/Python/current/Lib/test/test_iter.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_iter.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,886 @@
+# Test iterators.
+
+import unittest
+from test.test_support import run_unittest, TESTFN, unlink, have_unicode
+
+# Test result of triple loop (too big to inline)
+TRIPLETS = [(0, 0, 0), (0, 0, 1), (0, 0, 2),
+            (0, 1, 0), (0, 1, 1), (0, 1, 2),
+            (0, 2, 0), (0, 2, 1), (0, 2, 2),
+
+            (1, 0, 0), (1, 0, 1), (1, 0, 2),
+            (1, 1, 0), (1, 1, 1), (1, 1, 2),
+            (1, 2, 0), (1, 2, 1), (1, 2, 2),
+
+            (2, 0, 0), (2, 0, 1), (2, 0, 2),
+            (2, 1, 0), (2, 1, 1), (2, 1, 2),
+            (2, 2, 0), (2, 2, 1), (2, 2, 2)]
+
+# Helper classes
+
+class BasicIterClass:
+    def __init__(self, n):
+        self.n = n
+        self.i = 0
+    def next(self):
+        res = self.i
+        if res >= self.n:
+            raise StopIteration
+        self.i = res + 1
+        return res
+
+class IteratingSequenceClass:
+    def __init__(self, n):
+        self.n = n
+    def __iter__(self):
+        return BasicIterClass(self.n)
+
+class SequenceClass:
+    def __init__(self, n):
+        self.n = n
+    def __getitem__(self, i):
+        if 0 <= i < self.n:
+            return i
+        else:
+            raise IndexError
+
+# Main test suite
+
+class TestCase(unittest.TestCase):
+
+    # Helper to check that an iterator returns a given sequence
+    def check_iterator(self, it, seq):
+        res = []
+        while 1:
+            try:
+                val = it.next()
+            except StopIteration:
+                break
+            res.append(val)
+        self.assertEqual(res, seq)
+
+    # Helper to check that a for loop generates a given sequence
+    def check_for_loop(self, expr, seq):
+        res = []
+        for val in expr:
+            res.append(val)
+        self.assertEqual(res, seq)
+
+    # Test basic use of iter() function
+    def test_iter_basic(self):
+        self.check_iterator(iter(range(10)), range(10))
+
+    # Test that iter(iter(x)) is the same as iter(x)
+    def test_iter_idempotency(self):
+        seq = range(10)
+        it = iter(seq)
+        it2 = iter(it)
+        self.assert_(it is it2)
+
+    # Test that for loops over iterators work
+    def test_iter_for_loop(self):
+        self.check_for_loop(iter(range(10)), range(10))
+
+    # Test several independent iterators over the same list
+    def test_iter_independence(self):
+        seq = range(3)
+        res = []
+        for i in iter(seq):
+            for j in iter(seq):
+                for k in iter(seq):
+                    res.append((i, j, k))
+        self.assertEqual(res, TRIPLETS)
+
+    # Test triple list comprehension using iterators
+    def test_nested_comprehensions_iter(self):
+        seq = range(3)
+        res = [(i, j, k)
+               for i in iter(seq) for j in iter(seq) for k in iter(seq)]
+        self.assertEqual(res, TRIPLETS)
+
+    # Test triple list comprehension without iterators
+    def test_nested_comprehensions_for(self):
+        seq = range(3)
+        res = [(i, j, k) for i in seq for j in seq for k in seq]
+        self.assertEqual(res, TRIPLETS)
+
+    # Test a class with __iter__ in a for loop
+    def test_iter_class_for(self):
+        self.check_for_loop(IteratingSequenceClass(10), range(10))
+
+    # Test a class with __iter__ with explicit iter()
+    def test_iter_class_iter(self):
+        self.check_iterator(iter(IteratingSequenceClass(10)), range(10))
+
+    # Test for loop on a sequence class without __iter__
+    def test_seq_class_for(self):
+        self.check_for_loop(SequenceClass(10), range(10))
+
+    # Test iter() on a sequence class without __iter__
+    def test_seq_class_iter(self):
+        self.check_iterator(iter(SequenceClass(10)), range(10))
+
+    # Test two-argument iter() with callable instance
+    def test_iter_callable(self):
+        class C:
+            def __init__(self):
+                self.i = 0
+            def __call__(self):
+                i = self.i
+                self.i = i + 1
+                if i > 100:
+                    raise IndexError # Emergency stop
+                return i
+        self.check_iterator(iter(C(), 10), range(10))
+
+    # Test two-argument iter() with function
+    def test_iter_function(self):
+        def spam(state=[0]):
+            i = state[0]
+            state[0] = i+1
+            return i
+        self.check_iterator(iter(spam, 10), range(10))
+
+    # Test two-argument iter() with function that raises StopIteration
+    def test_iter_function_stop(self):
+        def spam(state=[0]):
+            i = state[0]
+            if i == 10:
+                raise StopIteration
+            state[0] = i+1
+            return i
+        self.check_iterator(iter(spam, 20), range(10))
+
+    # Test exception propagation through function iterator
+    def test_exception_function(self):
+        def spam(state=[0]):
+            i = state[0]
+            state[0] = i+1
+            if i == 10:
+                raise RuntimeError
+            return i
+        res = []
+        try:
+            for x in iter(spam, 20):
+                res.append(x)
+        except RuntimeError:
+            self.assertEqual(res, range(10))
+        else:
+            self.fail("should have raised RuntimeError")
+
+    # Test exception propagation through sequence iterator
+    def test_exception_sequence(self):
+        class MySequenceClass(SequenceClass):
+            def __getitem__(self, i):
+                if i == 10:
+                    raise RuntimeError
+                return SequenceClass.__getitem__(self, i)
+        res = []
+        try:
+            for x in MySequenceClass(20):
+                res.append(x)
+        except RuntimeError:
+            self.assertEqual(res, range(10))
+        else:
+            self.fail("should have raised RuntimeError")
+
+    # Test for StopIteration from __getitem__
+    def test_stop_sequence(self):
+        class MySequenceClass(SequenceClass):
+            def __getitem__(self, i):
+                if i == 10:
+                    raise StopIteration
+                return SequenceClass.__getitem__(self, i)
+        self.check_for_loop(MySequenceClass(20), range(10))
+
+    # Test a big range
+    def test_iter_big_range(self):
+        self.check_for_loop(iter(range(10000)), range(10000))
+
+    # Test an empty list
+    def test_iter_empty(self):
+        self.check_for_loop(iter([]), [])
+
+    # Test a tuple
+    def test_iter_tuple(self):
+        self.check_for_loop(iter((0,1,2,3,4,5,6,7,8,9)), range(10))
+
+    # Test an xrange
+    def test_iter_xrange(self):
+        self.check_for_loop(iter(xrange(10)), range(10))
+
+    # Test a string
+    def test_iter_string(self):
+        self.check_for_loop(iter("abcde"), ["a", "b", "c", "d", "e"])
+
+    # Test a Unicode string
+    if have_unicode:
+        def test_iter_unicode(self):
+            self.check_for_loop(iter(unicode("abcde")),
+                                [unicode("a"), unicode("b"), unicode("c"),
+                                 unicode("d"), unicode("e")])
+
+    # Test a directory
+    def test_iter_dict(self):
+        dict = {}
+        for i in range(10):
+            dict[i] = None
+        self.check_for_loop(dict, dict.keys())
+
+    # Test a file
+    def test_iter_file(self):
+        f = open(TESTFN, "w")
+        try:
+            for i in range(5):
+                f.write("%d\n" % i)
+        finally:
+            f.close()
+        f = open(TESTFN, "r")
+        try:
+            self.check_for_loop(f, ["0\n", "1\n", "2\n", "3\n", "4\n"])
+            self.check_for_loop(f, [])
+        finally:
+            f.close()
+            try:
+                unlink(TESTFN)
+            except OSError:
+                pass
+
+    # Test list()'s use of iterators.
+    def test_builtin_list(self):
+        self.assertEqual(list(SequenceClass(5)), range(5))
+        self.assertEqual(list(SequenceClass(0)), [])
+        self.assertEqual(list(()), [])
+        self.assertEqual(list(range(10, -1, -1)), range(10, -1, -1))
+
+        d = {"one": 1, "two": 2, "three": 3}
+        self.assertEqual(list(d), d.keys())
+
+        self.assertRaises(TypeError, list, list)
+        self.assertRaises(TypeError, list, 42)
+
+        f = open(TESTFN, "w")
+        try:
+            for i in range(5):
+                f.write("%d\n" % i)
+        finally:
+            f.close()
+        f = open(TESTFN, "r")
+        try:
+            self.assertEqual(list(f), ["0\n", "1\n", "2\n", "3\n", "4\n"])
+            f.seek(0, 0)
+            self.assertEqual(list(f),
+                             ["0\n", "1\n", "2\n", "3\n", "4\n"])
+        finally:
+            f.close()
+            try:
+                unlink(TESTFN)
+            except OSError:
+                pass
+
+    # Test tuples()'s use of iterators.
+    def test_builtin_tuple(self):
+        self.assertEqual(tuple(SequenceClass(5)), (0, 1, 2, 3, 4))
+        self.assertEqual(tuple(SequenceClass(0)), ())
+        self.assertEqual(tuple([]), ())
+        self.assertEqual(tuple(()), ())
+        self.assertEqual(tuple("abc"), ("a", "b", "c"))
+
+        d = {"one": 1, "two": 2, "three": 3}
+        self.assertEqual(tuple(d), tuple(d.keys()))
+
+        self.assertRaises(TypeError, tuple, list)
+        self.assertRaises(TypeError, tuple, 42)
+
+        f = open(TESTFN, "w")
+        try:
+            for i in range(5):
+                f.write("%d\n" % i)
+        finally:
+            f.close()
+        f = open(TESTFN, "r")
+        try:
+            self.assertEqual(tuple(f), ("0\n", "1\n", "2\n", "3\n", "4\n"))
+            f.seek(0, 0)
+            self.assertEqual(tuple(f),
+                             ("0\n", "1\n", "2\n", "3\n", "4\n"))
+        finally:
+            f.close()
+            try:
+                unlink(TESTFN)
+            except OSError:
+                pass
+
+    # Test filter()'s use of iterators.
+    def test_builtin_filter(self):
+        self.assertEqual(filter(None, SequenceClass(5)), range(1, 5))
+        self.assertEqual(filter(None, SequenceClass(0)), [])
+        self.assertEqual(filter(None, ()), ())
+        self.assertEqual(filter(None, "abc"), "abc")
+
+        d = {"one": 1, "two": 2, "three": 3}
+        self.assertEqual(filter(None, d), d.keys())
+
+        self.assertRaises(TypeError, filter, None, list)
+        self.assertRaises(TypeError, filter, None, 42)
+
+        class Boolean:
+            def __init__(self, truth):
+                self.truth = truth
+            def __nonzero__(self):
+                return self.truth
+        bTrue = Boolean(1)
+        bFalse = Boolean(0)
+
+        class Seq:
+            def __init__(self, *args):
+                self.vals = args
+            def __iter__(self):
+                class SeqIter:
+                    def __init__(self, vals):
+                        self.vals = vals
+                        self.i = 0
+                    def __iter__(self):
+                        return self
+                    def next(self):
+                        i = self.i
+                        self.i = i + 1
+                        if i < len(self.vals):
+                            return self.vals[i]
+                        else:
+                            raise StopIteration
+                return SeqIter(self.vals)
+
+        seq = Seq(*([bTrue, bFalse] * 25))
+        self.assertEqual(filter(lambda x: not x, seq), [bFalse]*25)
+        self.assertEqual(filter(lambda x: not x, iter(seq)), [bFalse]*25)
+
+    # Test max() and min()'s use of iterators.
+    def test_builtin_max_min(self):
+        self.assertEqual(max(SequenceClass(5)), 4)
+        self.assertEqual(min(SequenceClass(5)), 0)
+        self.assertEqual(max(8, -1), 8)
+        self.assertEqual(min(8, -1), -1)
+
+        d = {"one": 1, "two": 2, "three": 3}
+        self.assertEqual(max(d), "two")
+        self.assertEqual(min(d), "one")
+        self.assertEqual(max(d.itervalues()), 3)
+        self.assertEqual(min(iter(d.itervalues())), 1)
+
+        f = open(TESTFN, "w")
+        try:
+            f.write("medium line\n")
+            f.write("xtra large line\n")
+            f.write("itty-bitty line\n")
+        finally:
+            f.close()
+        f = open(TESTFN, "r")
+        try:
+            self.assertEqual(min(f), "itty-bitty line\n")
+            f.seek(0, 0)
+            self.assertEqual(max(f), "xtra large line\n")
+        finally:
+            f.close()
+            try:
+                unlink(TESTFN)
+            except OSError:
+                pass
+
+    # Test map()'s use of iterators.
+    def test_builtin_map(self):
+        self.assertEqual(map(None, SequenceClass(5)), range(5))
+        self.assertEqual(map(lambda x: x+1, SequenceClass(5)), range(1, 6))
+
+        d = {"one": 1, "two": 2, "three": 3}
+        self.assertEqual(map(None, d), d.keys())
+        self.assertEqual(map(lambda k, d=d: (k, d[k]), d), d.items())
+        dkeys = d.keys()
+        expected = [(i < len(d) and dkeys[i] or None,
+                     i,
+                     i < len(d) and dkeys[i] or None)
+                    for i in range(5)]
+        self.assertEqual(map(None, d,
+                                   SequenceClass(5),
+                                   iter(d.iterkeys())),
+                         expected)
+
+        f = open(TESTFN, "w")
+        try:
+            for i in range(10):
+                f.write("xy" * i + "\n") # line i has len 2*i+1
+        finally:
+            f.close()
+        f = open(TESTFN, "r")
+        try:
+            self.assertEqual(map(len, f), range(1, 21, 2))
+        finally:
+            f.close()
+            try:
+                unlink(TESTFN)
+            except OSError:
+                pass
+
+    # Test zip()'s use of iterators.
+    def test_builtin_zip(self):
+        self.assertEqual(zip(), [])
+        self.assertEqual(zip(*[]), [])
+        self.assertEqual(zip(*[(1, 2), 'ab']), [(1, 'a'), (2, 'b')])
+
+        self.assertRaises(TypeError, zip, None)
+        self.assertRaises(TypeError, zip, range(10), 42)
+        self.assertRaises(TypeError, zip, range(10), zip)
+
+        self.assertEqual(zip(IteratingSequenceClass(3)),
+                         [(0,), (1,), (2,)])
+        self.assertEqual(zip(SequenceClass(3)),
+                         [(0,), (1,), (2,)])
+
+        d = {"one": 1, "two": 2, "three": 3}
+        self.assertEqual(d.items(), zip(d, d.itervalues()))
+
+        # Generate all ints starting at constructor arg.
+        class IntsFrom:
+            def __init__(self, start):
+                self.i = start
+
+            def __iter__(self):
+                return self
+
+            def next(self):
+                i = self.i
+                self.i = i+1
+                return i
+
+        f = open(TESTFN, "w")
+        try:
+            f.write("a\n" "bbb\n" "cc\n")
+        finally:
+            f.close()
+        f = open(TESTFN, "r")
+        try:
+            self.assertEqual(zip(IntsFrom(0), f, IntsFrom(-100)),
+                             [(0, "a\n", -100),
+                              (1, "bbb\n", -99),
+                              (2, "cc\n", -98)])
+        finally:
+            f.close()
+            try:
+                unlink(TESTFN)
+            except OSError:
+                pass
+
+        self.assertEqual(zip(xrange(5)), [(i,) for i in range(5)])
+
+        # Classes that lie about their lengths.
+        class NoGuessLen5:
+            def __getitem__(self, i):
+                if i >= 5:
+                    raise IndexError
+                return i
+
+        class Guess3Len5(NoGuessLen5):
+            def __len__(self):
+                return 3
+
+        class Guess30Len5(NoGuessLen5):
+            def __len__(self):
+                return 30
+
+        self.assertEqual(len(Guess3Len5()), 3)
+        self.assertEqual(len(Guess30Len5()), 30)
+        self.assertEqual(zip(NoGuessLen5()), zip(range(5)))
+        self.assertEqual(zip(Guess3Len5()), zip(range(5)))
+        self.assertEqual(zip(Guess30Len5()), zip(range(5)))
+
+        expected = [(i, i) for i in range(5)]
+        for x in NoGuessLen5(), Guess3Len5(), Guess30Len5():
+            for y in NoGuessLen5(), Guess3Len5(), Guess30Len5():
+                self.assertEqual(zip(x, y), expected)
+
+    # Test reduces()'s use of iterators.
+    def test_builtin_reduce(self):
+        from operator import add
+        self.assertEqual(reduce(add, SequenceClass(5)), 10)
+        self.assertEqual(reduce(add, SequenceClass(5), 42), 52)
+        self.assertRaises(TypeError, reduce, add, SequenceClass(0))
+        self.assertEqual(reduce(add, SequenceClass(0), 42), 42)
+        self.assertEqual(reduce(add, SequenceClass(1)), 0)
+        self.assertEqual(reduce(add, SequenceClass(1), 42), 42)
+
+        d = {"one": 1, "two": 2, "three": 3}
+        self.assertEqual(reduce(add, d), "".join(d.keys()))
+
+    # This test case will be removed if we don't have Unicode
+    def test_unicode_join_endcase(self):
+
+        # This class inserts a Unicode object into its argument's natural
+        # iteration, in the 3rd position.
+        class OhPhooey:
+            def __init__(self, seq):
+                self.it = iter(seq)
+                self.i = 0
+
+            def __iter__(self):
+                return self
+
+            def next(self):
+                i = self.i
+                self.i = i+1
+                if i == 2:
+                    return unicode("fooled you!")
+                return self.it.next()
+
+        f = open(TESTFN, "w")
+        try:
+            f.write("a\n" + "b\n" + "c\n")
+        finally:
+            f.close()
+
+        f = open(TESTFN, "r")
+        # Nasty:  string.join(s) can't know whether unicode.join() is needed
+        # until it's seen all of s's elements.  But in this case, f's
+        # iterator cannot be restarted.  So what we're testing here is
+        # whether string.join() can manage to remember everything it's seen
+        # and pass that on to unicode.join().
+        try:
+            got = " - ".join(OhPhooey(f))
+            self.assertEqual(got, unicode("a\n - b\n - fooled you! - c\n"))
+        finally:
+            f.close()
+            try:
+                unlink(TESTFN)
+            except OSError:
+                pass
+    if not have_unicode:
+        def test_unicode_join_endcase(self): pass
+
+    # Test iterators with 'x in y' and 'x not in y'.
+    def test_in_and_not_in(self):
+        for sc5 in IteratingSequenceClass(5), SequenceClass(5):
+            for i in range(5):
+                self.assert_(i in sc5)
+            for i in "abc", -1, 5, 42.42, (3, 4), [], {1: 1}, 3-12j, sc5:
+                self.assert_(i not in sc5)
+
+        self.assertRaises(TypeError, lambda: 3 in 12)
+        self.assertRaises(TypeError, lambda: 3 not in map)
+
+        d = {"one": 1, "two": 2, "three": 3, 1j: 2j}
+        for k in d:
+            self.assert_(k in d)
+            self.assert_(k not in d.itervalues())
+        for v in d.values():
+            self.assert_(v in d.itervalues())
+            self.assert_(v not in d)
+        for k, v in d.iteritems():
+            self.assert_((k, v) in d.iteritems())
+            self.assert_((v, k) not in d.iteritems())
+
+        f = open(TESTFN, "w")
+        try:
+            f.write("a\n" "b\n" "c\n")
+        finally:
+            f.close()
+        f = open(TESTFN, "r")
+        try:
+            for chunk in "abc":
+                f.seek(0, 0)
+                self.assert_(chunk not in f)
+                f.seek(0, 0)
+                self.assert_((chunk + "\n") in f)
+        finally:
+            f.close()
+            try:
+                unlink(TESTFN)
+            except OSError:
+                pass
+
+    # Test iterators with operator.countOf (PySequence_Count).
+    def test_countOf(self):
+        from operator import countOf
+        self.assertEqual(countOf([1,2,2,3,2,5], 2), 3)
+        self.assertEqual(countOf((1,2,2,3,2,5), 2), 3)
+        self.assertEqual(countOf("122325", "2"), 3)
+        self.assertEqual(countOf("122325", "6"), 0)
+
+        self.assertRaises(TypeError, countOf, 42, 1)
+        self.assertRaises(TypeError, countOf, countOf, countOf)
+
+        d = {"one": 3, "two": 3, "three": 3, 1j: 2j}
+        for k in d:
+            self.assertEqual(countOf(d, k), 1)
+        self.assertEqual(countOf(d.itervalues(), 3), 3)
+        self.assertEqual(countOf(d.itervalues(), 2j), 1)
+        self.assertEqual(countOf(d.itervalues(), 1j), 0)
+
+        f = open(TESTFN, "w")
+        try:
+            f.write("a\n" "b\n" "c\n" "b\n")
+        finally:
+            f.close()
+        f = open(TESTFN, "r")
+        try:
+            for letter, count in ("a", 1), ("b", 2), ("c", 1), ("d", 0):
+                f.seek(0, 0)
+                self.assertEqual(countOf(f, letter + "\n"), count)
+        finally:
+            f.close()
+            try:
+                unlink(TESTFN)
+            except OSError:
+                pass
+
+    # Test iterators with operator.indexOf (PySequence_Index).
+    def test_indexOf(self):
+        from operator import indexOf
+        self.assertEqual(indexOf([1,2,2,3,2,5], 1), 0)
+        self.assertEqual(indexOf((1,2,2,3,2,5), 2), 1)
+        self.assertEqual(indexOf((1,2,2,3,2,5), 3), 3)
+        self.assertEqual(indexOf((1,2,2,3,2,5), 5), 5)
+        self.assertRaises(ValueError, indexOf, (1,2,2,3,2,5), 0)
+        self.assertRaises(ValueError, indexOf, (1,2,2,3,2,5), 6)
+
+        self.assertEqual(indexOf("122325", "2"), 1)
+        self.assertEqual(indexOf("122325", "5"), 5)
+        self.assertRaises(ValueError, indexOf, "122325", "6")
+
+        self.assertRaises(TypeError, indexOf, 42, 1)
+        self.assertRaises(TypeError, indexOf, indexOf, indexOf)
+
+        f = open(TESTFN, "w")
+        try:
+            f.write("a\n" "b\n" "c\n" "d\n" "e\n")
+        finally:
+            f.close()
+        f = open(TESTFN, "r")
+        try:
+            fiter = iter(f)
+            self.assertEqual(indexOf(fiter, "b\n"), 1)
+            self.assertEqual(indexOf(fiter, "d\n"), 1)
+            self.assertEqual(indexOf(fiter, "e\n"), 0)
+            self.assertRaises(ValueError, indexOf, fiter, "a\n")
+        finally:
+            f.close()
+            try:
+                unlink(TESTFN)
+            except OSError:
+                pass
+
+        iclass = IteratingSequenceClass(3)
+        for i in range(3):
+            self.assertEqual(indexOf(iclass, i), i)
+        self.assertRaises(ValueError, indexOf, iclass, -1)
+
+    # Test iterators with file.writelines().
+    def test_writelines(self):
+        f = file(TESTFN, "w")
+
+        try:
+            self.assertRaises(TypeError, f.writelines, None)
+            self.assertRaises(TypeError, f.writelines, 42)
+
+            f.writelines(["1\n", "2\n"])
+            f.writelines(("3\n", "4\n"))
+            f.writelines({'5\n': None})
+            f.writelines({})
+
+            # Try a big chunk too.
+            class Iterator:
+                def __init__(self, start, finish):
+                    self.start = start
+                    self.finish = finish
+                    self.i = self.start
+
+                def next(self):
+                    if self.i >= self.finish:
+                        raise StopIteration
+                    result = str(self.i) + '\n'
+                    self.i += 1
+                    return result
+
+                def __iter__(self):
+                    return self
+
+            class Whatever:
+                def __init__(self, start, finish):
+                    self.start = start
+                    self.finish = finish
+
+                def __iter__(self):
+                    return Iterator(self.start, self.finish)
+
+            f.writelines(Whatever(6, 6+2000))
+            f.close()
+
+            f = file(TESTFN)
+            expected = [str(i) + "\n" for i in range(1, 2006)]
+            self.assertEqual(list(f), expected)
+
+        finally:
+            f.close()
+            try:
+                unlink(TESTFN)
+            except OSError:
+                pass
+
+
+    # Test iterators on RHS of unpacking assignments.
+    def test_unpack_iter(self):
+        a, b = 1, 2
+        self.assertEqual((a, b), (1, 2))
+
+        a, b, c = IteratingSequenceClass(3)
+        self.assertEqual((a, b, c), (0, 1, 2))
+
+        try:    # too many values
+            a, b = IteratingSequenceClass(3)
+        except ValueError:
+            pass
+        else:
+            self.fail("should have raised ValueError")
+
+        try:    # not enough values
+            a, b, c = IteratingSequenceClass(2)
+        except ValueError:
+            pass
+        else:
+            self.fail("should have raised ValueError")
+
+        try:    # not iterable
+            a, b, c = len
+        except TypeError:
+            pass
+        else:
+            self.fail("should have raised TypeError")
+
+        a, b, c = {1: 42, 2: 42, 3: 42}.itervalues()
+        self.assertEqual((a, b, c), (42, 42, 42))
+
+        f = open(TESTFN, "w")
+        lines = ("a\n", "bb\n", "ccc\n")
+        try:
+            for line in lines:
+                f.write(line)
+        finally:
+            f.close()
+        f = open(TESTFN, "r")
+        try:
+            a, b, c = f
+            self.assertEqual((a, b, c), lines)
+        finally:
+            f.close()
+            try:
+                unlink(TESTFN)
+            except OSError:
+                pass
+
+        (a, b), (c,) = IteratingSequenceClass(2), {42: 24}
+        self.assertEqual((a, b, c), (0, 1, 42))
+
+        # Test reference count behavior
+
+        class C(object):
+            count = 0
+            def __new__(cls):
+                cls.count += 1
+                return object.__new__(cls)
+            def __del__(self):
+                cls = self.__class__
+                assert cls.count > 0
+                cls.count -= 1
+        x = C()
+        self.assertEqual(C.count, 1)
+        del x
+        self.assertEqual(C.count, 0)
+        l = [C(), C(), C()]
+        self.assertEqual(C.count, 3)
+        try:
+            a, b = iter(l)
+        except ValueError:
+            pass
+        del l
+        self.assertEqual(C.count, 0)
+
+
+    # Make sure StopIteration is a "sink state".
+    # This tests various things that weren't sink states in Python 2.2.1,
+    # plus various things that always were fine.
+
+    def test_sinkstate_list(self):
+        # This used to fail
+        a = range(5)
+        b = iter(a)
+        self.assertEqual(list(b), range(5))
+        a.extend(range(5, 10))
+        self.assertEqual(list(b), [])
+
+    def test_sinkstate_tuple(self):
+        a = (0, 1, 2, 3, 4)
+        b = iter(a)
+        self.assertEqual(list(b), range(5))
+        self.assertEqual(list(b), [])
+
+    def test_sinkstate_string(self):
+        a = "abcde"
+        b = iter(a)
+        self.assertEqual(list(b), ['a', 'b', 'c', 'd', 'e'])
+        self.assertEqual(list(b), [])
+
+    def test_sinkstate_sequence(self):
+        # This used to fail
+        a = SequenceClass(5)
+        b = iter(a)
+        self.assertEqual(list(b), range(5))
+        a.n = 10
+        self.assertEqual(list(b), [])
+
+    def test_sinkstate_callable(self):
+        # This used to fail
+        def spam(state=[0]):
+            i = state[0]
+            state[0] = i+1
+            if i == 10:
+                raise AssertionError, "shouldn't have gotten this far"
+            return i
+        b = iter(spam, 5)
+        self.assertEqual(list(b), range(5))
+        self.assertEqual(list(b), [])
+
+    def test_sinkstate_dict(self):
+        # XXX For a more thorough test, see towards the end of:
+        # http://mail.python.org/pipermail/python-dev/2002-July/026512.html
+        a = {1:1, 2:2, 0:0, 4:4, 3:3}
+        for b in iter(a), a.iterkeys(), a.iteritems(), a.itervalues():
+            b = iter(a)
+            self.assertEqual(len(list(b)), 5)
+            self.assertEqual(list(b), [])
+
+    def test_sinkstate_yield(self):
+        def gen():
+            for i in range(5):
+                yield i
+        b = gen()
+        self.assertEqual(list(b), range(5))
+        self.assertEqual(list(b), [])
+
+    def test_sinkstate_range(self):
+        a = xrange(5)
+        b = iter(a)
+        self.assertEqual(list(b), range(5))
+        self.assertEqual(list(b), [])
+
+    def test_sinkstate_enumerate(self):
+        a = range(5)
+        e = enumerate(a)
+        b = iter(e)
+        self.assertEqual(list(b), zip(range(5), range(5)))
+        self.assertEqual(list(b), [])
+
+
+def test_main():
+    run_unittest(TestCase)
+
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_iterlen.py
===================================================================
--- vendor/Python/current/Lib/test/test_iterlen.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_iterlen.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,258 @@
+""" Test Iterator Length Transparency
+
+Some functions or methods which accept general iterable arguments have
+optional, more efficient code paths if they know how many items to expect.
+For instance, map(func, iterable), will pre-allocate the exact amount of
+space required whenever the iterable can report its length.
+
+The desired invariant is:  len(it)==len(list(it)).
+
+A complication is that an iterable and iterator can be the same object. To
+maintain the invariant, an iterator needs to dynamically update its length.
+For instance, an iterable such as xrange(10) always reports its length as ten,
+but it=iter(xrange(10)) starts at ten, and then goes to nine after it.next().
+Having this capability means that map() can ignore the distinction between
+map(func, iterable) and map(func, iter(iterable)).
+
+When the iterable is immutable, the implementation can straight-forwardly
+report the original length minus the cumulative number of calls to next().
+This is the case for tuples, xrange objects, and itertools.repeat().
+
+Some containers become temporarily immutable during iteration.  This includes
+dicts, sets, and collections.deque.  Their implementation is equally simple
+though they need to permantently set their length to zero whenever there is
+an attempt to iterate after a length mutation.
+
+The situation slightly more involved whenever an object allows length mutation
+during iteration.  Lists and sequence iterators are dynanamically updatable.
+So, if a list is extended during iteration, the iterator will continue through
+the new items.  If it shrinks to a point before the most recent iteration,
+then no further items are available and the length is reported at zero.
+
+Reversed objects can also be wrapped around mutable objects; however, any
+appends after the current position are ignored.  Any other approach leads
+to confusion and possibly returning the same item more than once.
+
+The iterators not listed above, such as enumerate and the other itertools,
+are not length transparent because they have no way to distinguish between
+iterables that report static length and iterators whose length changes with
+each call (i.e. the difference between enumerate('abc') and
+enumerate(iter('abc')).
+
+"""
+
+import unittest
+from test import test_support
+from itertools import repeat
+from collections import deque
+from UserList import UserList
+from __builtin__ import len as _len
+
+n = 10
+
+def len(obj):
+    try:
+        return _len(obj)
+    except TypeError:
+        try:
+            # note: this is an internal undocumented API,
+            # don't rely on it in your own programs
+            return obj.__length_hint__()
+        except AttributeError:
+            raise TypeError
+
+class TestInvariantWithoutMutations(unittest.TestCase):
+
+    def test_invariant(self):
+        it = self.it
+        for i in reversed(xrange(1, n+1)):
+            self.assertEqual(len(it), i)
+            it.next()
+        self.assertEqual(len(it), 0)
+        self.assertRaises(StopIteration, it.next)
+        self.assertEqual(len(it), 0)
+
+class TestTemporarilyImmutable(TestInvariantWithoutMutations):
+
+    def test_immutable_during_iteration(self):
+        # objects such as deques, sets, and dictionaries enforce
+        # length immutability  during iteration
+
+        it = self.it
+        self.assertEqual(len(it), n)
+        it.next()
+        self.assertEqual(len(it), n-1)
+        self.mutate()
+        self.assertRaises(RuntimeError, it.next)
+        self.assertEqual(len(it), 0)
+
+## ------- Concrete Type Tests -------
+
+class TestRepeat(TestInvariantWithoutMutations):
+
+    def setUp(self):
+        self.it = repeat(None, n)
+
+    def test_no_len_for_infinite_repeat(self):
+        # The repeat() object can also be infinite
+        self.assertRaises(TypeError, len, repeat(None))
+
+class TestXrange(TestInvariantWithoutMutations):
+
+    def setUp(self):
+        self.it = iter(xrange(n))
+
+class TestXrangeCustomReversed(TestInvariantWithoutMutations):
+
+    def setUp(self):
+        self.it = reversed(xrange(n))
+
+class TestTuple(TestInvariantWithoutMutations):
+
+    def setUp(self):
+        self.it = iter(tuple(xrange(n)))
+
+## ------- Types that should not be mutated during iteration -------
+
+class TestDeque(TestTemporarilyImmutable):
+
+    def setUp(self):
+        d = deque(xrange(n))
+        self.it = iter(d)
+        self.mutate = d.pop
+
+class TestDequeReversed(TestTemporarilyImmutable):
+
+    def setUp(self):
+        d = deque(xrange(n))
+        self.it = reversed(d)
+        self.mutate = d.pop
+
+class TestDictKeys(TestTemporarilyImmutable):
+
+    def setUp(self):
+        d = dict.fromkeys(xrange(n))
+        self.it = iter(d)
+        self.mutate = d.popitem
+
+class TestDictItems(TestTemporarilyImmutable):
+
+    def setUp(self):
+        d = dict.fromkeys(xrange(n))
+        self.it = d.iteritems()
+        self.mutate = d.popitem
+
+class TestDictValues(TestTemporarilyImmutable):
+
+    def setUp(self):
+        d = dict.fromkeys(xrange(n))
+        self.it = d.itervalues()
+        self.mutate = d.popitem
+
+class TestSet(TestTemporarilyImmutable):
+
+    def setUp(self):
+        d = set(xrange(n))
+        self.it = iter(d)
+        self.mutate = d.pop
+
+## ------- Types that can mutate during iteration -------
+
+class TestList(TestInvariantWithoutMutations):
+
+    def setUp(self):
+        self.it = iter(range(n))
+
+    def test_mutation(self):
+        d = range(n)
+        it = iter(d)
+        it.next()
+        it.next()
+        self.assertEqual(len(it), n-2)
+        d.append(n)
+        self.assertEqual(len(it), n-1)  # grow with append
+        d[1:] = []
+        self.assertEqual(len(it), 0)
+        self.assertEqual(list(it), [])
+        d.extend(xrange(20))
+        self.assertEqual(len(it), 0)
+
+class TestListReversed(TestInvariantWithoutMutations):
+
+    def setUp(self):
+        self.it = reversed(range(n))
+
+    def test_mutation(self):
+        d = range(n)
+        it = reversed(d)
+        it.next()
+        it.next()
+        self.assertEqual(len(it), n-2)
+        d.append(n)
+        self.assertEqual(len(it), n-2)  # ignore append
+        d[1:] = []
+        self.assertEqual(len(it), 0)
+        self.assertEqual(list(it), [])  # confirm invariant
+        d.extend(xrange(20))
+        self.assertEqual(len(it), 0)
+
+class TestSeqIter(TestInvariantWithoutMutations):
+
+    def setUp(self):
+        self.it = iter(UserList(range(n)))
+
+    def test_mutation(self):
+        d = UserList(range(n))
+        it = iter(d)
+        it.next()
+        it.next()
+        self.assertEqual(len(it), n-2)
+        d.append(n)
+        self.assertEqual(len(it), n-1)  # grow with append
+        d[1:] = []
+        self.assertEqual(len(it), 0)
+        self.assertEqual(list(it), [])
+        d.extend(xrange(20))
+        self.assertEqual(len(it), 0)
+
+class TestSeqIterReversed(TestInvariantWithoutMutations):
+
+    def setUp(self):
+        self.it = reversed(UserList(range(n)))
+
+    def test_mutation(self):
+        d = UserList(range(n))
+        it = reversed(d)
+        it.next()
+        it.next()
+        self.assertEqual(len(it), n-2)
+        d.append(n)
+        self.assertEqual(len(it), n-2)  # ignore append
+        d[1:] = []
+        self.assertEqual(len(it), 0)
+        self.assertEqual(list(it), [])  # confirm invariant
+        d.extend(xrange(20))
+        self.assertEqual(len(it), 0)
+
+
+def test_main():
+    unittests = [
+        TestRepeat,
+        TestXrange,
+        TestXrangeCustomReversed,
+        TestTuple,
+        TestDeque,
+        TestDequeReversed,
+        TestDictKeys,
+        TestDictItems,
+        TestDictValues,
+        TestSet,
+        TestList,
+        TestListReversed,
+        TestSeqIter,
+        TestSeqIterReversed,
+    ]
+    test_support.run_unittest(*unittests)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_itertools.py
===================================================================
--- vendor/Python/current/Lib/test/test_itertools.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_itertools.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,969 @@
+import unittest
+from test import test_support
+from itertools import *
+from weakref import proxy
+import sys
+import operator
+import random
+
+def onearg(x):
+    'Test function of one argument'
+    return 2*x
+
+def errfunc(*args):
+    'Test function that raises an error'
+    raise ValueError
+
+def gen3():
+    'Non-restartable source sequence'
+    for i in (0, 1, 2):
+        yield i
+
+def isEven(x):
+    'Test predicate'
+    return x%2==0
+
+def isOdd(x):
+    'Test predicate'
+    return x%2==1
+
+class StopNow:
+    'Class emulating an empty iterable.'
+    def __iter__(self):
+        return self
+    def next(self):
+        raise StopIteration
+
+def take(n, seq):
+    'Convenience function for partially consuming a long of infinite iterable'
+    return list(islice(seq, n))
+
+class TestBasicOps(unittest.TestCase):
+    def test_chain(self):
+        self.assertEqual(list(chain('abc', 'def')), list('abcdef'))
+        self.assertEqual(list(chain('abc')), list('abc'))
+        self.assertEqual(list(chain('')), [])
+        self.assertEqual(take(4, chain('abc', 'def')), list('abcd'))
+        self.assertRaises(TypeError, chain, 2, 3)
+
+    def test_count(self):
+        self.assertEqual(zip('abc',count()), [('a', 0), ('b', 1), ('c', 2)])
+        self.assertEqual(zip('abc',count(3)), [('a', 3), ('b', 4), ('c', 5)])
+        self.assertEqual(take(2, zip('abc',count(3))), [('a', 3), ('b', 4)])
+        self.assertRaises(TypeError, count, 2, 3)
+        self.assertRaises(TypeError, count, 'a')
+        self.assertRaises(OverflowError, list, islice(count(sys.maxint-5), 10))
+        c = count(3)
+        self.assertEqual(repr(c), 'count(3)')
+        c.next()
+        self.assertEqual(repr(c), 'count(4)')
+        c = count(-9)
+        self.assertEqual(repr(c), 'count(-9)')
+        c.next()
+        self.assertEqual(c.next(), -8)
+
+    def test_cycle(self):
+        self.assertEqual(take(10, cycle('abc')), list('abcabcabca'))
+        self.assertEqual(list(cycle('')), [])
+        self.assertRaises(TypeError, cycle)
+        self.assertRaises(TypeError, cycle, 5)
+        self.assertEqual(list(islice(cycle(gen3()),10)), [0,1,2,0,1,2,0,1,2,0])
+
+    def test_groupby(self):
+        # Check whether it accepts arguments correctly
+        self.assertEqual([], list(groupby([])))
+        self.assertEqual([], list(groupby([], key=id)))
+        self.assertRaises(TypeError, list, groupby('abc', []))
+        self.assertRaises(TypeError, groupby, None)
+        self.assertRaises(TypeError, groupby, 'abc', lambda x:x, 10)
+
+        # Check normal input
+        s = [(0, 10, 20), (0, 11,21), (0,12,21), (1,13,21), (1,14,22),
+             (2,15,22), (3,16,23), (3,17,23)]
+        dup = []
+        for k, g in groupby(s, lambda r:r[0]):
+            for elem in g:
+                self.assertEqual(k, elem[0])
+                dup.append(elem)
+        self.assertEqual(s, dup)
+
+        # Check nested case
+        dup = []
+        for k, g in groupby(s, lambda r:r[0]):
+            for ik, ig in groupby(g, lambda r:r[2]):
+                for elem in ig:
+                    self.assertEqual(k, elem[0])
+                    self.assertEqual(ik, elem[2])
+                    dup.append(elem)
+        self.assertEqual(s, dup)
+
+        # Check case where inner iterator is not used
+        keys = [k for k, g in groupby(s, lambda r:r[0])]
+        expectedkeys = set([r[0] for r in s])
+        self.assertEqual(set(keys), expectedkeys)
+        self.assertEqual(len(keys), len(expectedkeys))
+
+        # Exercise pipes and filters style
+        s = 'abracadabra'
+        # sort s | uniq
+        r = [k for k, g in groupby(sorted(s))]
+        self.assertEqual(r, ['a', 'b', 'c', 'd', 'r'])
+        # sort s | uniq -d
+        r = [k for k, g in groupby(sorted(s)) if list(islice(g,1,2))]
+        self.assertEqual(r, ['a', 'b', 'r'])
+        # sort s | uniq -c
+        r = [(len(list(g)), k) for k, g in groupby(sorted(s))]
+        self.assertEqual(r, [(5, 'a'), (2, 'b'), (1, 'c'), (1, 'd'), (2, 'r')])
+        # sort s | uniq -c | sort -rn | head -3
+        r = sorted([(len(list(g)) , k) for k, g in groupby(sorted(s))], reverse=True)[:3]
+        self.assertEqual(r, [(5, 'a'), (2, 'r'), (2, 'b')])
+
+        # iter.next failure
+        class ExpectedError(Exception):
+            pass
+        def delayed_raise(n=0):
+            for i in range(n):
+                yield 'yo'
+            raise ExpectedError
+        def gulp(iterable, keyp=None, func=list):
+            return [func(g) for k, g in groupby(iterable, keyp)]
+
+        # iter.next failure on outer object
+        self.assertRaises(ExpectedError, gulp, delayed_raise(0))
+        # iter.next failure on inner object
+        self.assertRaises(ExpectedError, gulp, delayed_raise(1))
+
+        # __cmp__ failure
+        class DummyCmp:
+            def __cmp__(self, dst):
+                raise ExpectedError
+        s = [DummyCmp(), DummyCmp(), None]
+
+        # __cmp__ failure on outer object
+        self.assertRaises(ExpectedError, gulp, s, func=id)
+        # __cmp__ failure on inner object
+        self.assertRaises(ExpectedError, gulp, s)
+
+        # keyfunc failure
+        def keyfunc(obj):
+            if keyfunc.skip > 0:
+                keyfunc.skip -= 1
+                return obj
+            else:
+                raise ExpectedError
+
+        # keyfunc failure on outer object
+        keyfunc.skip = 0
+        self.assertRaises(ExpectedError, gulp, [None], keyfunc)
+        keyfunc.skip = 1
+        self.assertRaises(ExpectedError, gulp, [None, None], keyfunc)
+
+    def test_ifilter(self):
+        self.assertEqual(list(ifilter(isEven, range(6))), [0,2,4])
+        self.assertEqual(list(ifilter(None, [0,1,0,2,0])), [1,2])
+        self.assertEqual(take(4, ifilter(isEven, count())), [0,2,4,6])
+        self.assertRaises(TypeError, ifilter)
+        self.assertRaises(TypeError, ifilter, lambda x:x)
+        self.assertRaises(TypeError, ifilter, lambda x:x, range(6), 7)
+        self.assertRaises(TypeError, ifilter, isEven, 3)
+        self.assertRaises(TypeError, ifilter(range(6), range(6)).next)
+
+    def test_ifilterfalse(self):
+        self.assertEqual(list(ifilterfalse(isEven, range(6))), [1,3,5])
+        self.assertEqual(list(ifilterfalse(None, [0,1,0,2,0])), [0,0,0])
+        self.assertEqual(take(4, ifilterfalse(isEven, count())), [1,3,5,7])
+        self.assertRaises(TypeError, ifilterfalse)
+        self.assertRaises(TypeError, ifilterfalse, lambda x:x)
+        self.assertRaises(TypeError, ifilterfalse, lambda x:x, range(6), 7)
+        self.assertRaises(TypeError, ifilterfalse, isEven, 3)
+        self.assertRaises(TypeError, ifilterfalse(range(6), range(6)).next)
+
+    def test_izip(self):
+        ans = [(x,y) for x, y in izip('abc',count())]
+        self.assertEqual(ans, [('a', 0), ('b', 1), ('c', 2)])
+        self.assertEqual(list(izip('abc', range(6))), zip('abc', range(6)))
+        self.assertEqual(list(izip('abcdef', range(3))), zip('abcdef', range(3)))
+        self.assertEqual(take(3,izip('abcdef', count())), zip('abcdef', range(3)))
+        self.assertEqual(list(izip('abcdef')), zip('abcdef'))
+        self.assertEqual(list(izip()), zip())
+        self.assertRaises(TypeError, izip, 3)
+        self.assertRaises(TypeError, izip, range(3), 3)
+        # Check tuple re-use (implementation detail)
+        self.assertEqual([tuple(list(pair)) for pair in izip('abc', 'def')],
+                         zip('abc', 'def'))
+        self.assertEqual([pair for pair in izip('abc', 'def')],
+                         zip('abc', 'def'))
+        ids = map(id, izip('abc', 'def'))
+        self.assertEqual(min(ids), max(ids))
+        ids = map(id, list(izip('abc', 'def')))
+        self.assertEqual(len(dict.fromkeys(ids)), len(ids))
+
+    def test_repeat(self):
+        self.assertEqual(zip(xrange(3),repeat('a')),
+                         [(0, 'a'), (1, 'a'), (2, 'a')])
+        self.assertEqual(list(repeat('a', 3)), ['a', 'a', 'a'])
+        self.assertEqual(take(3, repeat('a')), ['a', 'a', 'a'])
+        self.assertEqual(list(repeat('a', 0)), [])
+        self.assertEqual(list(repeat('a', -3)), [])
+        self.assertRaises(TypeError, repeat)
+        self.assertRaises(TypeError, repeat, None, 3, 4)
+        self.assertRaises(TypeError, repeat, None, 'a')
+        r = repeat(1+0j)
+        self.assertEqual(repr(r), 'repeat((1+0j))')
+        r = repeat(1+0j, 5)
+        self.assertEqual(repr(r), 'repeat((1+0j), 5)')
+        list(r)
+        self.assertEqual(repr(r), 'repeat((1+0j), 0)')
+
+    def test_imap(self):
+        self.assertEqual(list(imap(operator.pow, range(3), range(1,7))),
+                         [0**1, 1**2, 2**3])
+        self.assertEqual(list(imap(None, 'abc', range(5))),
+                         [('a',0),('b',1),('c',2)])
+        self.assertEqual(list(imap(None, 'abc', count())),
+                         [('a',0),('b',1),('c',2)])
+        self.assertEqual(take(2,imap(None, 'abc', count())),
+                         [('a',0),('b',1)])
+        self.assertEqual(list(imap(operator.pow, [])), [])
+        self.assertRaises(TypeError, imap)
+        self.assertRaises(TypeError, imap, operator.neg)
+        self.assertRaises(TypeError, imap(10, range(5)).next)
+        self.assertRaises(ValueError, imap(errfunc, [4], [5]).next)
+        self.assertRaises(TypeError, imap(onearg, [4], [5]).next)
+
+    def test_starmap(self):
+        self.assertEqual(list(starmap(operator.pow, zip(range(3), range(1,7)))),
+                         [0**1, 1**2, 2**3])
+        self.assertEqual(take(3, starmap(operator.pow, izip(count(), count(1)))),
+                         [0**1, 1**2, 2**3])
+        self.assertEqual(list(starmap(operator.pow, [])), [])
+        self.assertRaises(TypeError, list, starmap(operator.pow, [[4,5]]))
+        self.assertRaises(TypeError, starmap)
+        self.assertRaises(TypeError, starmap, operator.pow, [(4,5)], 'extra')
+        self.assertRaises(TypeError, starmap(10, [(4,5)]).next)
+        self.assertRaises(ValueError, starmap(errfunc, [(4,5)]).next)
+        self.assertRaises(TypeError, starmap(onearg, [(4,5)]).next)
+
+    def test_islice(self):
+        for args in [          # islice(args) should agree with range(args)
+                (10, 20, 3),
+                (10, 3, 20),
+                (10, 20),
+                (10, 3),
+                (20,)
+                ]:
+            self.assertEqual(list(islice(xrange(100), *args)), range(*args))
+
+        for args, tgtargs in [  # Stop when seqn is exhausted
+                ((10, 110, 3), ((10, 100, 3))),
+                ((10, 110), ((10, 100))),
+                ((110,), (100,))
+                ]:
+            self.assertEqual(list(islice(xrange(100), *args)), range(*tgtargs))
+
+        # Test stop=None
+        self.assertEqual(list(islice(xrange(10), None)), range(10))
+        self.assertEqual(list(islice(xrange(10), None, None)), range(10))
+        self.assertEqual(list(islice(xrange(10), None, None, None)), range(10))
+        self.assertEqual(list(islice(xrange(10), 2, None)), range(2, 10))
+        self.assertEqual(list(islice(xrange(10), 1, None, 2)), range(1, 10, 2))
+
+        # Test number of items consumed     SF #1171417
+        it = iter(range(10))
+        self.assertEqual(list(islice(it, 3)), range(3))
+        self.assertEqual(list(it), range(3, 10))
+
+        # Test invalid arguments
+        self.assertRaises(TypeError, islice, xrange(10))
+        self.assertRaises(TypeError, islice, xrange(10), 1, 2, 3, 4)
+        self.assertRaises(ValueError, islice, xrange(10), -5, 10, 1)
+        self.assertRaises(ValueError, islice, xrange(10), 1, -5, -1)
+        self.assertRaises(ValueError, islice, xrange(10), 1, 10, -1)
+        self.assertRaises(ValueError, islice, xrange(10), 1, 10, 0)
+        self.assertRaises(ValueError, islice, xrange(10), 'a')
+        self.assertRaises(ValueError, islice, xrange(10), 'a', 1)
+        self.assertRaises(ValueError, islice, xrange(10), 1, 'a')
+        self.assertRaises(ValueError, islice, xrange(10), 'a', 1, 1)
+        self.assertRaises(ValueError, islice, xrange(10), 1, 'a', 1)
+        self.assertEqual(len(list(islice(count(), 1, 10, sys.maxint))), 1)
+
+    def test_takewhile(self):
+        data = [1, 3, 5, 20, 2, 4, 6, 8]
+        underten = lambda x: x<10
+        self.assertEqual(list(takewhile(underten, data)), [1, 3, 5])
+        self.assertEqual(list(takewhile(underten, [])), [])
+        self.assertRaises(TypeError, takewhile)
+        self.assertRaises(TypeError, takewhile, operator.pow)
+        self.assertRaises(TypeError, takewhile, operator.pow, [(4,5)], 'extra')
+        self.assertRaises(TypeError, takewhile(10, [(4,5)]).next)
+        self.assertRaises(ValueError, takewhile(errfunc, [(4,5)]).next)
+        t = takewhile(bool, [1, 1, 1, 0, 0, 0])
+        self.assertEqual(list(t), [1, 1, 1])
+        self.assertRaises(StopIteration, t.next)
+
+    def test_dropwhile(self):
+        data = [1, 3, 5, 20, 2, 4, 6, 8]
+        underten = lambda x: x<10
+        self.assertEqual(list(dropwhile(underten, data)), [20, 2, 4, 6, 8])
+        self.assertEqual(list(dropwhile(underten, [])), [])
+        self.assertRaises(TypeError, dropwhile)
+        self.assertRaises(TypeError, dropwhile, operator.pow)
+        self.assertRaises(TypeError, dropwhile, operator.pow, [(4,5)], 'extra')
+        self.assertRaises(TypeError, dropwhile(10, [(4,5)]).next)
+        self.assertRaises(ValueError, dropwhile(errfunc, [(4,5)]).next)
+
+    def test_tee(self):
+        n = 200
+        def irange(n):
+            for i in xrange(n):
+                yield i
+
+        a, b = tee([])        # test empty iterator
+        self.assertEqual(list(a), [])
+        self.assertEqual(list(b), [])
+
+        a, b = tee(irange(n)) # test 100% interleaved
+        self.assertEqual(zip(a,b), zip(range(n),range(n)))
+
+        a, b = tee(irange(n)) # test 0% interleaved
+        self.assertEqual(list(a), range(n))
+        self.assertEqual(list(b), range(n))
+
+        a, b = tee(irange(n)) # test dealloc of leading iterator
+        for i in xrange(100):
+            self.assertEqual(a.next(), i)
+        del a
+        self.assertEqual(list(b), range(n))
+
+        a, b = tee(irange(n)) # test dealloc of trailing iterator
+        for i in xrange(100):
+            self.assertEqual(a.next(), i)
+        del b
+        self.assertEqual(list(a), range(100, n))
+
+        for j in xrange(5):   # test randomly interleaved
+            order = [0]*n + [1]*n
+            random.shuffle(order)
+            lists = ([], [])
+            its = tee(irange(n))
+            for i in order:
+                value = its[i].next()
+                lists[i].append(value)
+            self.assertEqual(lists[0], range(n))
+            self.assertEqual(lists[1], range(n))
+
+        # test argument format checking
+        self.assertRaises(TypeError, tee)
+        self.assertRaises(TypeError, tee, 3)
+        self.assertRaises(TypeError, tee, [1,2], 'x')
+        self.assertRaises(TypeError, tee, [1,2], 3, 'x')
+
+        # tee object should be instantiable
+        a, b = tee('abc')
+        c = type(a)('def')
+        self.assertEqual(list(c), list('def'))
+
+        # test long-lagged and multi-way split
+        a, b, c = tee(xrange(2000), 3)
+        for i in xrange(100):
+            self.assertEqual(a.next(), i)
+        self.assertEqual(list(b), range(2000))
+        self.assertEqual([c.next(), c.next()], range(2))
+        self.assertEqual(list(a), range(100,2000))
+        self.assertEqual(list(c), range(2,2000))
+
+        # test values of n
+        self.assertRaises(TypeError, tee, 'abc', 'invalid')
+        self.assertRaises(ValueError, tee, [], -1)
+        for n in xrange(5):
+            result = tee('abc', n)
+            self.assertEqual(type(result), tuple)
+            self.assertEqual(len(result), n)
+            self.assertEqual(map(list, result), [list('abc')]*n)
+
+        # tee pass-through to copyable iterator
+        a, b = tee('abc')
+        c, d = tee(a)
+        self.assert_(a is c)
+
+        # test tee_new
+        t1, t2 = tee('abc')
+        tnew = type(t1)
+        self.assertRaises(TypeError, tnew)
+        self.assertRaises(TypeError, tnew, 10)
+        t3 = tnew(t1)
+        self.assert_(list(t1) == list(t2) == list(t3) == list('abc'))
+
+        # test that tee objects are weak referencable
+        a, b = tee(xrange(10))
+        p = proxy(a)
+        self.assertEqual(getattr(p, '__class__'), type(b))
+        del a
+        self.assertRaises(ReferenceError, getattr, p, '__class__')
+
+    def test_StopIteration(self):
+        self.assertRaises(StopIteration, izip().next)
+
+        for f in (chain, cycle, izip, groupby):
+            self.assertRaises(StopIteration, f([]).next)
+            self.assertRaises(StopIteration, f(StopNow()).next)
+
+        self.assertRaises(StopIteration, islice([], None).next)
+        self.assertRaises(StopIteration, islice(StopNow(), None).next)
+
+        p, q = tee([])
+        self.assertRaises(StopIteration, p.next)
+        self.assertRaises(StopIteration, q.next)
+        p, q = tee(StopNow())
+        self.assertRaises(StopIteration, p.next)
+        self.assertRaises(StopIteration, q.next)
+
+        self.assertRaises(StopIteration, repeat(None, 0).next)
+
+        for f in (ifilter, ifilterfalse, imap, takewhile, dropwhile, starmap):
+            self.assertRaises(StopIteration, f(lambda x:x, []).next)
+            self.assertRaises(StopIteration, f(lambda x:x, StopNow()).next)
+
+class TestGC(unittest.TestCase):
+
+    def makecycle(self, iterator, container):
+        container.append(iterator)
+        iterator.next()
+        del container, iterator
+
+    def test_chain(self):
+        a = []
+        self.makecycle(chain(a), a)
+
+    def test_cycle(self):
+        a = []
+        self.makecycle(cycle([a]*2), a)
+
+    def test_dropwhile(self):
+        a = []
+        self.makecycle(dropwhile(bool, [0, a, a]), a)
+
+    def test_groupby(self):
+        a = []
+        self.makecycle(groupby([a]*2, lambda x:x), a)
+
+    def test_ifilter(self):
+        a = []
+        self.makecycle(ifilter(lambda x:True, [a]*2), a)
+
+    def test_ifilterfalse(self):
+        a = []
+        self.makecycle(ifilterfalse(lambda x:False, a), a)
+
+    def test_izip(self):
+        a = []
+        self.makecycle(izip([a]*2, [a]*3), a)
+
+    def test_imap(self):
+        a = []
+        self.makecycle(imap(lambda x:x, [a]*2), a)
+
+    def test_islice(self):
+        a = []
+        self.makecycle(islice([a]*2, None), a)
+
+    def test_repeat(self):
+        a = []
+        self.makecycle(repeat(a), a)
+
+    def test_starmap(self):
+        a = []
+        self.makecycle(starmap(lambda *t: t, [(a,a)]*2), a)
+
+    def test_takewhile(self):
+        a = []
+        self.makecycle(takewhile(bool, [1, 0, a, a]), a)
+
+def R(seqn):
+    'Regular generator'
+    for i in seqn:
+        yield i
+
+class G:
+    'Sequence using __getitem__'
+    def __init__(self, seqn):
+        self.seqn = seqn
+    def __getitem__(self, i):
+        return self.seqn[i]
+
+class I:
+    'Sequence using iterator protocol'
+    def __init__(self, seqn):
+        self.seqn = seqn
+        self.i = 0
+    def __iter__(self):
+        return self
+    def next(self):
+        if self.i >= len(self.seqn): raise StopIteration
+        v = self.seqn[self.i]
+        self.i += 1
+        return v
+
+class Ig:
+    'Sequence using iterator protocol defined with a generator'
+    def __init__(self, seqn):
+        self.seqn = seqn
+        self.i = 0
+    def __iter__(self):
+        for val in self.seqn:
+            yield val
+
+class X:
+    'Missing __getitem__ and __iter__'
+    def __init__(self, seqn):
+        self.seqn = seqn
+        self.i = 0
+    def next(self):
+        if self.i >= len(self.seqn): raise StopIteration
+        v = self.seqn[self.i]
+        self.i += 1
+        return v
+
+class N:
+    'Iterator missing next()'
+    def __init__(self, seqn):
+        self.seqn = seqn
+        self.i = 0
+    def __iter__(self):
+        return self
+
+class E:
+    'Test propagation of exceptions'
+    def __init__(self, seqn):
+        self.seqn = seqn
+        self.i = 0
+    def __iter__(self):
+        return self
+    def next(self):
+        3 // 0
+
+class S:
+    'Test immediate stop'
+    def __init__(self, seqn):
+        pass
+    def __iter__(self):
+        return self
+    def next(self):
+        raise StopIteration
+
+def L(seqn):
+    'Test multiple tiers of iterators'
+    return chain(imap(lambda x:x, R(Ig(G(seqn)))))
+
+
+class TestVariousIteratorArgs(unittest.TestCase):
+
+    def test_chain(self):
+        for s in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5)):
+            for g in (G, I, Ig, S, L, R):
+                self.assertEqual(list(chain(g(s))), list(g(s)))
+                self.assertEqual(list(chain(g(s), g(s))), list(g(s))+list(g(s)))
+            self.assertRaises(TypeError, chain, X(s))
+            self.assertRaises(TypeError, list, chain(N(s)))
+            self.assertRaises(ZeroDivisionError, list, chain(E(s)))
+
+    def test_cycle(self):
+        for s in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5)):
+            for g in (G, I, Ig, S, L, R):
+                tgtlen = len(s) * 3
+                expected = list(g(s))*3
+                actual = list(islice(cycle(g(s)), tgtlen))
+                self.assertEqual(actual, expected)
+            self.assertRaises(TypeError, cycle, X(s))
+            self.assertRaises(TypeError, list, cycle(N(s)))
+            self.assertRaises(ZeroDivisionError, list, cycle(E(s)))
+
+    def test_groupby(self):
+        for s in (range(10), range(0), range(1000), (7,11), xrange(2000,2200,5)):
+            for g in (G, I, Ig, S, L, R):
+                self.assertEqual([k for k, sb in groupby(g(s))], list(g(s)))
+            self.assertRaises(TypeError, groupby, X(s))
+            self.assertRaises(TypeError, list, groupby(N(s)))
+            self.assertRaises(ZeroDivisionError, list, groupby(E(s)))
+
+    def test_ifilter(self):
+        for s in (range(10), range(0), range(1000), (7,11), xrange(2000,2200,5)):
+            for g in (G, I, Ig, S, L, R):
+                self.assertEqual(list(ifilter(isEven, g(s))), filter(isEven, g(s)))
+            self.assertRaises(TypeError, ifilter, isEven, X(s))
+            self.assertRaises(TypeError, list, ifilter(isEven, N(s)))
+            self.assertRaises(ZeroDivisionError, list, ifilter(isEven, E(s)))
+
+    def test_ifilterfalse(self):
+        for s in (range(10), range(0), range(1000), (7,11), xrange(2000,2200,5)):
+            for g in (G, I, Ig, S, L, R):
+                self.assertEqual(list(ifilterfalse(isEven, g(s))), filter(isOdd, g(s)))
+            self.assertRaises(TypeError, ifilterfalse, isEven, X(s))
+            self.assertRaises(TypeError, list, ifilterfalse(isEven, N(s)))
+            self.assertRaises(ZeroDivisionError, list, ifilterfalse(isEven, E(s)))
+
+    def test_izip(self):
+        for s in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5)):
+            for g in (G, I, Ig, S, L, R):
+                self.assertEqual(list(izip(g(s))), zip(g(s)))
+                self.assertEqual(list(izip(g(s), g(s))), zip(g(s), g(s)))
+            self.assertRaises(TypeError, izip, X(s))
+            self.assertRaises(TypeError, list, izip(N(s)))
+            self.assertRaises(ZeroDivisionError, list, izip(E(s)))
+
+    def test_imap(self):
+        for s in (range(10), range(0), range(100), (7,11), xrange(20,50,5)):
+            for g in (G, I, Ig, S, L, R):
+                self.assertEqual(list(imap(onearg, g(s))), map(onearg, g(s)))
+                self.assertEqual(list(imap(operator.pow, g(s), g(s))), map(operator.pow, g(s), g(s)))
+            self.assertRaises(TypeError, imap, onearg, X(s))
+            self.assertRaises(TypeError, list, imap(onearg, N(s)))
+            self.assertRaises(ZeroDivisionError, list, imap(onearg, E(s)))
+
+    def test_islice(self):
+        for s in ("12345", "", range(1000), ('do', 1.2), xrange(2000,2200,5)):
+            for g in (G, I, Ig, S, L, R):
+                self.assertEqual(list(islice(g(s),1,None,2)), list(g(s))[1::2])
+            self.assertRaises(TypeError, islice, X(s), 10)
+            self.assertRaises(TypeError, list, islice(N(s), 10))
+            self.assertRaises(ZeroDivisionError, list, islice(E(s), 10))
+
+    def test_starmap(self):
+        for s in (range(10), range(0), range(100), (7,11), xrange(20,50,5)):
+            for g in (G, I, Ig, S, L, R):
+                ss = zip(s, s)
+                self.assertEqual(list(starmap(operator.pow, g(ss))), map(operator.pow, g(s), g(s)))
+            self.assertRaises(TypeError, starmap, operator.pow, X(ss))
+            self.assertRaises(TypeError, list, starmap(operator.pow, N(ss)))
+            self.assertRaises(ZeroDivisionError, list, starmap(operator.pow, E(ss)))
+
+    def test_takewhile(self):
+        for s in (range(10), range(0), range(1000), (7,11), xrange(2000,2200,5)):
+            for g in (G, I, Ig, S, L, R):
+                tgt = []
+                for elem in g(s):
+                    if not isEven(elem): break
+                    tgt.append(elem)
+                self.assertEqual(list(takewhile(isEven, g(s))), tgt)
+            self.assertRaises(TypeError, takewhile, isEven, X(s))
+            self.assertRaises(TypeError, list, takewhile(isEven, N(s)))
+            self.assertRaises(ZeroDivisionError, list, takewhile(isEven, E(s)))
+
+    def test_dropwhile(self):
+        for s in (range(10), range(0), range(1000), (7,11), xrange(2000,2200,5)):
+            for g in (G, I, Ig, S, L, R):
+                tgt = []
+                for elem in g(s):
+                    if not tgt and isOdd(elem): continue
+                    tgt.append(elem)
+                self.assertEqual(list(dropwhile(isOdd, g(s))), tgt)
+            self.assertRaises(TypeError, dropwhile, isOdd, X(s))
+            self.assertRaises(TypeError, list, dropwhile(isOdd, N(s)))
+            self.assertRaises(ZeroDivisionError, list, dropwhile(isOdd, E(s)))
+
+    def test_tee(self):
+        for s in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5)):
+            for g in (G, I, Ig, S, L, R):
+                it1, it2 = tee(g(s))
+                self.assertEqual(list(it1), list(g(s)))
+                self.assertEqual(list(it2), list(g(s)))
+            self.assertRaises(TypeError, tee, X(s))
+            self.assertRaises(TypeError, list, tee(N(s))[0])
+            self.assertRaises(ZeroDivisionError, list, tee(E(s))[0])
+
+class LengthTransparency(unittest.TestCase):
+
+    def test_repeat(self):
+        from test.test_iterlen import len
+        self.assertEqual(len(repeat(None, 50)), 50)
+        self.assertRaises(TypeError, len, repeat(None))
+
+class RegressionTests(unittest.TestCase):
+
+    def test_sf_793826(self):
+        # Fix Armin Rigo's successful efforts to wreak havoc
+
+        def mutatingtuple(tuple1, f, tuple2):
+            # this builds a tuple t which is a copy of tuple1,
+            # then calls f(t), then mutates t to be equal to tuple2
+            # (needs len(tuple1) == len(tuple2)).
+            def g(value, first=[1]):
+                if first:
+                    del first[:]
+                    f(z.next())
+                return value
+            items = list(tuple2)
+            items[1:1] = list(tuple1)
+            gen = imap(g, items)
+            z = izip(*[gen]*len(tuple1))
+            z.next()
+
+        def f(t):
+            global T
+            T = t
+            first[:] = list(T)
+
+        first = []
+        mutatingtuple((1,2,3), f, (4,5,6))
+        second = list(T)
+        self.assertEqual(first, second)
+
+
+    def test_sf_950057(self):
+        # Make sure that chain() and cycle() catch exceptions immediately
+        # rather than when shifting between input sources
+
+        def gen1():
+            hist.append(0)
+            yield 1
+            hist.append(1)
+            raise AssertionError
+            hist.append(2)
+
+        def gen2(x):
+            hist.append(3)
+            yield 2
+            hist.append(4)
+            if x:
+                raise StopIteration
+
+        hist = []
+        self.assertRaises(AssertionError, list, chain(gen1(), gen2(False)))
+        self.assertEqual(hist, [0,1])
+
+        hist = []
+        self.assertRaises(AssertionError, list, chain(gen1(), gen2(True)))
+        self.assertEqual(hist, [0,1])
+
+        hist = []
+        self.assertRaises(AssertionError, list, cycle(gen1()))
+        self.assertEqual(hist, [0,1])
+
+class SubclassWithKwargsTest(unittest.TestCase):
+    def test_keywords_in_subclass(self):
+        # count is not subclassable...
+        for cls in (repeat, izip, ifilter, ifilterfalse, chain, imap,
+                    starmap, islice, takewhile, dropwhile, cycle):
+            class Subclass(cls):
+                def __init__(self, newarg=None, *args):
+                    cls.__init__(self, *args)
+            try:
+                Subclass(newarg=1)
+            except TypeError, err:
+                # we expect type errors because of wrong argument count
+                self.failIf("does not take keyword arguments" in err.args[0])
+
+
+libreftest = """ Doctest for examples in the library reference: libitertools.tex
+
+
+>>> amounts = [120.15, 764.05, 823.14]
+>>> for checknum, amount in izip(count(1200), amounts):
+...     print 'Check %d is for $%.2f' % (checknum, amount)
+...
+Check 1200 is for $120.15
+Check 1201 is for $764.05
+Check 1202 is for $823.14
+
+>>> import operator
+>>> for cube in imap(operator.pow, xrange(1,4), repeat(3)):
+...    print cube
+...
+1
+8
+27
+
+>>> reportlines = ['EuroPython', 'Roster', '', 'alex', '', 'laura', '', 'martin', '', 'walter', '', 'samuele']
+>>> for name in islice(reportlines, 3, None, 2):
+...    print name.title()
+...
+Alex
+Laura
+Martin
+Walter
+Samuele
+
+>>> from operator import itemgetter
+>>> d = dict(a=1, b=2, c=1, d=2, e=1, f=2, g=3)
+>>> di = sorted(sorted(d.iteritems()), key=itemgetter(1))
+>>> for k, g in groupby(di, itemgetter(1)):
+...     print k, map(itemgetter(0), g)
+...
+1 ['a', 'c', 'e']
+2 ['b', 'd', 'f']
+3 ['g']
+
+# Find runs of consecutive numbers using groupby.  The key to the solution
+# is differencing with a range so that consecutive numbers all appear in
+# same group.
+>>> data = [ 1,  4,5,6, 10, 15,16,17,18, 22, 25,26,27,28]
+>>> for k, g in groupby(enumerate(data), lambda (i,x):i-x):
+...     print map(operator.itemgetter(1), g)
+...
+[1]
+[4, 5, 6]
+[10]
+[15, 16, 17, 18]
+[22]
+[25, 26, 27, 28]
+
+>>> def take(n, seq):
+...     return list(islice(seq, n))
+
+>>> def enumerate(iterable):
+...     return izip(count(), iterable)
+
+>>> def tabulate(function):
+...     "Return function(0), function(1), ..."
+...     return imap(function, count())
+
+>>> def iteritems(mapping):
+...     return izip(mapping.iterkeys(), mapping.itervalues())
+
+>>> def nth(iterable, n):
+...     "Returns the nth item"
+...     return list(islice(iterable, n, n+1))
+
+>>> def all(seq, pred=None):
+...     "Returns True if pred(x) is true for every element in the iterable"
+...     for elem in ifilterfalse(pred, seq):
+...         return False
+...     return True
+
+>>> def any(seq, pred=None):
+...     "Returns True if pred(x) is true for at least one element in the iterable"
+...     for elem in ifilter(pred, seq):
+...         return True
+...     return False
+
+>>> def no(seq, pred=None):
+...     "Returns True if pred(x) is false for every element in the iterable"
+...     for elem in ifilter(pred, seq):
+...         return False
+...     return True
+
+>>> def quantify(seq, pred=None):
+...     "Count how many times the predicate is true in the sequence"
+...     return sum(imap(pred, seq))
+
+>>> def padnone(seq):
+...     "Returns the sequence elements and then returns None indefinitely"
+...     return chain(seq, repeat(None))
+
+>>> def ncycles(seq, n):
+...     "Returns the sequence elements n times"
+...     return chain(*repeat(seq, n))
+
+>>> def dotproduct(vec1, vec2):
+...     return sum(imap(operator.mul, vec1, vec2))
+
+>>> def flatten(listOfLists):
+...     return list(chain(*listOfLists))
+
+>>> def repeatfunc(func, times=None, *args):
+...     "Repeat calls to func with specified arguments."
+...     "   Example:  repeatfunc(random.random)"
+...     if times is None:
+...         return starmap(func, repeat(args))
+...     else:
+...         return starmap(func, repeat(args, times))
+
+>>> def pairwise(iterable):
+...     "s -> (s0,s1), (s1,s2), (s2, s3), ..."
+...     a, b = tee(iterable)
+...     try:
+...         b.next()
+...     except StopIteration:
+...         pass
+...     return izip(a, b)
+
+This is not part of the examples but it tests to make sure the definitions
+perform as purported.
+
+>>> take(10, count())
+[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+
+>>> list(enumerate('abc'))
+[(0, 'a'), (1, 'b'), (2, 'c')]
+
+>>> list(islice(tabulate(lambda x: 2*x), 4))
+[0, 2, 4, 6]
+
+>>> nth('abcde', 3)
+['d']
+
+>>> all([2, 4, 6, 8], lambda x: x%2==0)
+True
+
+>>> all([2, 3, 6, 8], lambda x: x%2==0)
+False
+
+>>> any([2, 4, 6, 8], lambda x: x%2==0)
+True
+
+>>> any([1, 3, 5, 9], lambda x: x%2==0,)
+False
+
+>>> no([1, 3, 5, 9], lambda x: x%2==0)
+True
+
+>>> no([1, 2, 5, 9], lambda x: x%2==0)
+False
+
+>>> quantify(xrange(99), lambda x: x%2==0)
+50
+
+>>> a = [[1, 2, 3], [4, 5, 6]]
+>>> flatten(a)
+[1, 2, 3, 4, 5, 6]
+
+>>> list(repeatfunc(pow, 5, 2, 3))
+[8, 8, 8, 8, 8]
+
+>>> import random
+>>> take(5, imap(int, repeatfunc(random.random)))
+[0, 0, 0, 0, 0]
+
+>>> list(pairwise('abcd'))
+[('a', 'b'), ('b', 'c'), ('c', 'd')]
+
+>>> list(pairwise([]))
+[]
+
+>>> list(pairwise('a'))
+[]
+
+>>> list(islice(padnone('abc'), 0, 6))
+['a', 'b', 'c', None, None, None]
+
+>>> list(ncycles('abc', 3))
+['a', 'b', 'c', 'a', 'b', 'c', 'a', 'b', 'c']
+
+>>> dotproduct([1,2,3], [4,5,6])
+32
+
+"""
+
+__test__ = {'libreftest' : libreftest}
+
+def test_main(verbose=None):
+    test_classes = (TestBasicOps, TestVariousIteratorArgs, TestGC,
+                    RegressionTests, LengthTransparency,
+                    SubclassWithKwargsTest)
+    test_support.run_unittest(*test_classes)
+
+    # verify reference counting
+    if verbose and hasattr(sys, "gettotalrefcount"):
+        import gc
+        counts = [None] * 5
+        for i in xrange(len(counts)):
+            test_support.run_unittest(*test_classes)
+            gc.collect()
+            counts[i] = sys.gettotalrefcount()
+        print counts
+
+    # doctest the examples in the library reference
+    test_support.run_doctest(sys.modules[__name__], verbose)
+
+if __name__ == "__main__":
+    test_main(verbose=True)

Added: vendor/Python/current/Lib/test/test_largefile.py
===================================================================
--- vendor/Python/current/Lib/test/test_largefile.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_largefile.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,170 @@
+#!python
+
+#----------------------------------------------------------------------
+# test largefile support on system where this makes sense
+#
+#----------------------------------------------------------------------
+
+from test import test_support
+import os, struct, stat, sys
+
+try:
+    import signal
+    # The default handler for SIGXFSZ is to abort the process.
+    # By ignoring it, system calls exceeding the file size resource
+    # limit will raise IOError instead of crashing the interpreter.
+    oldhandler = signal.signal(signal.SIGXFSZ, signal.SIG_IGN)
+except (ImportError, AttributeError):
+    pass
+
+
+# create >2GB file (2GB = 2147483648 bytes)
+size = 2500000000L
+name = test_support.TESTFN
+
+
+# On Windows and Mac OSX this test comsumes large resources; It takes
+# a long time to build the >2GB file and takes >2GB of disk space
+# therefore the resource must be enabled to run this test.  If not,
+# nothing after this line stanza will be executed.
+if sys.platform[:3] == 'win' or sys.platform == 'darwin':
+    test_support.requires(
+        'largefile',
+        'test requires %s bytes and a long time to run' % str(size))
+else:
+    # Only run if the current filesystem supports large files.
+    # (Skip this test on Windows, since we now always support large files.)
+    f = open(test_support.TESTFN, 'wb')
+    try:
+        # 2**31 == 2147483648
+        f.seek(2147483649L)
+        # Seeking is not enough of a test: you must write and flush, too!
+        f.write("x")
+        f.flush()
+    except (IOError, OverflowError):
+        f.close()
+        os.unlink(test_support.TESTFN)
+        raise test_support.TestSkipped, \
+              "filesystem does not have largefile support"
+    else:
+        f.close()
+
+
+def expect(got_this, expect_this):
+    if test_support.verbose:
+        print '%r =?= %r ...' % (got_this, expect_this),
+    if got_this != expect_this:
+        if test_support.verbose:
+            print 'no'
+        raise test_support.TestFailed, 'got %r, but expected %r' %\
+              (got_this, expect_this)
+    else:
+        if test_support.verbose:
+            print 'yes'
+
+
+# test that each file function works as expected for a large (i.e. >2GB, do
+# we have to check >4GB) files
+
+if test_support.verbose:
+    print 'create large file via seek (may be sparse file) ...'
+f = open(name, 'wb')
+try:
+    f.write('z')
+    f.seek(0)
+    f.seek(size)
+    f.write('a')
+    f.flush()
+    if test_support.verbose:
+        print 'check file size with os.fstat'
+    expect(os.fstat(f.fileno())[stat.ST_SIZE], size+1)
+finally:
+    f.close()
+if test_support.verbose:
+    print 'check file size with os.stat'
+expect(os.stat(name)[stat.ST_SIZE], size+1)
+
+if test_support.verbose:
+    print 'play around with seek() and read() with the built largefile'
+f = open(name, 'rb')
+try:
+    expect(f.tell(), 0)
+    expect(f.read(1), 'z')
+    expect(f.tell(), 1)
+    f.seek(0)
+    expect(f.tell(), 0)
+    f.seek(0, 0)
+    expect(f.tell(), 0)
+    f.seek(42)
+    expect(f.tell(), 42)
+    f.seek(42, 0)
+    expect(f.tell(), 42)
+    f.seek(42, 1)
+    expect(f.tell(), 84)
+    f.seek(0, 1)
+    expect(f.tell(), 84)
+    f.seek(0, 2) # seek from the end
+    expect(f.tell(), size + 1 + 0)
+    f.seek(-10, 2)
+    expect(f.tell(), size + 1 - 10)
+    f.seek(-size-1, 2)
+    expect(f.tell(), 0)
+    f.seek(size)
+    expect(f.tell(), size)
+    expect(f.read(1), 'a') # the 'a' that was written at the end of file above
+    f.seek(-size-1, 1)
+    expect(f.read(1), 'z')
+    expect(f.tell(), 1)
+finally:
+    f.close()
+
+if test_support.verbose:
+    print 'play around with os.lseek() with the built largefile'
+f = open(name, 'rb')
+try:
+    expect(os.lseek(f.fileno(), 0, 0), 0)
+    expect(os.lseek(f.fileno(), 42, 0), 42)
+    expect(os.lseek(f.fileno(), 42, 1), 84)
+    expect(os.lseek(f.fileno(), 0, 1), 84)
+    expect(os.lseek(f.fileno(), 0, 2), size+1+0)
+    expect(os.lseek(f.fileno(), -10, 2), size+1-10)
+    expect(os.lseek(f.fileno(), -size-1, 2), 0)
+    expect(os.lseek(f.fileno(), size, 0), size)
+    expect(f.read(1), 'a') # the 'a' that was written at the end of file above
+finally:
+    f.close()
+
+if hasattr(f, 'truncate'):
+    if test_support.verbose:
+        print 'try truncate'
+    f = open(name, 'r+b')
+    try:
+        f.seek(0, 2)
+        expect(f.tell(), size+1)    # else we've lost track of the true size
+        # Cut it back via seek + truncate with no argument.
+        newsize = size - 10
+        f.seek(newsize)
+        f.truncate()
+        expect(f.tell(), newsize)   # else pointer moved
+        f.seek(0, 2)
+        expect(f.tell(), newsize)   # else wasn't truncated
+        # Ensure that truncate(smaller than true size) shrinks the file.
+        newsize -= 1
+        f.seek(42)
+        f.truncate(newsize)
+        expect(f.tell(), 42)        # else pointer moved
+        f.seek(0, 2)
+        expect(f.tell(), newsize)   # else wasn't truncated
+
+        # XXX truncate(larger than true size) is ill-defined across platforms
+
+        # cut it waaaaay back
+        f.seek(0)
+        f.truncate(1)
+        expect(f.tell(), 0)         # else pointer moved
+        expect(len(f.read()), 1)    # else wasn't truncated
+
+    finally:
+        f.close()
+
+os.unlink(name)

Added: vendor/Python/current/Lib/test/test_linuxaudiodev.py
===================================================================
--- vendor/Python/current/Lib/test/test_linuxaudiodev.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_linuxaudiodev.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,92 @@
+from test import test_support
+test_support.requires('audio')
+
+from test.test_support import verbose, findfile, TestFailed, TestSkipped
+
+import errno
+import fcntl
+import linuxaudiodev
+import os
+import sys
+import select
+import sunaudio
+import time
+import audioop
+
+SND_FORMAT_MULAW_8 = 1
+
+def play_sound_file(path):
+    fp = open(path, 'r')
+    size, enc, rate, nchannels, extra = sunaudio.gethdr(fp)
+    data = fp.read()
+    fp.close()
+
+    if enc != SND_FORMAT_MULAW_8:
+        print "Expect .au file with 8-bit mu-law samples"
+        return
+
+    try:
+        a = linuxaudiodev.open('w')
+    except linuxaudiodev.error, msg:
+        if msg[0] in (errno.EACCES, errno.ENOENT, errno.ENODEV, errno.EBUSY):
+            raise TestSkipped, msg
+        raise TestFailed, msg
+
+    # convert the data to 16-bit signed
+    data = audioop.ulaw2lin(data, 2)
+
+    # set the data format
+    if sys.byteorder == 'little':
+        fmt = linuxaudiodev.AFMT_S16_LE
+    else:
+        fmt = linuxaudiodev.AFMT_S16_BE
+
+    # at least check that these methods can be invoked
+    a.bufsize()
+    a.obufcount()
+    a.obuffree()
+    a.getptr()
+    a.fileno()
+
+    # set parameters based on .au file headers
+    a.setparameters(rate, 16, nchannels, fmt)
+    a.write(data)
+    a.flush()
+    a.close()
+
+def test_errors():
+    a = linuxaudiodev.open("w")
+    size = 8
+    fmt = linuxaudiodev.AFMT_U8
+    rate = 8000
+    nchannels = 1
+    try:
+        a.setparameters(-1, size, nchannels, fmt)
+    except ValueError, msg:
+        print msg
+    try:
+        a.setparameters(rate, -2, nchannels, fmt)
+    except ValueError, msg:
+        print msg
+    try:
+        a.setparameters(rate, size, 3, fmt)
+    except ValueError, msg:
+        print msg
+    try:
+        a.setparameters(rate, size, nchannels, 177)
+    except ValueError, msg:
+        print msg
+    try:
+        a.setparameters(rate, size, nchannels, linuxaudiodev.AFMT_U16_LE)
+    except ValueError, msg:
+        print msg
+    try:
+        a.setparameters(rate, 16, nchannels, fmt)
+    except ValueError, msg:
+        print msg
+
+def test():
+    play_sound_file(findfile('audiotest.au'))
+    test_errors()
+
+test()

Added: vendor/Python/current/Lib/test/test_list.py
===================================================================
--- vendor/Python/current/Lib/test/test_list.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_list.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,37 @@
+import unittest
+from test import test_support, list_tests
+
+class ListTest(list_tests.CommonTest):
+    type2test = list
+
+    def test_truth(self):
+        super(ListTest, self).test_truth()
+        self.assert_(not [])
+        self.assert_([42])
+
+    def test_identity(self):
+        self.assert_([] is not [])
+
+    def test_len(self):
+        super(ListTest, self).test_len()
+        self.assertEqual(len([]), 0)
+        self.assertEqual(len([0]), 1)
+        self.assertEqual(len([0, 1, 2]), 3)
+
+def test_main(verbose=None):
+    test_support.run_unittest(ListTest)
+
+    # verify reference counting
+    import sys
+    if verbose and hasattr(sys, "gettotalrefcount"):
+        import gc
+        counts = [None] * 5
+        for i in xrange(len(counts)):
+            test_support.run_unittest(ListTest)
+            gc.collect()
+            counts[i] = sys.gettotalrefcount()
+        print counts
+
+
+if __name__ == "__main__":
+    test_main(verbose=True)

Added: vendor/Python/current/Lib/test/test_locale.py
===================================================================
--- vendor/Python/current/Lib/test/test_locale.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_locale.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,115 @@
+from test.test_support import verbose, TestSkipped
+import locale
+import sys
+
+if sys.platform == 'darwin':
+    raise TestSkipped("Locale support on MacOSX is minimal and cannot be tested")
+oldlocale = locale.setlocale(locale.LC_NUMERIC)
+
+if sys.platform.startswith("win"):
+    tlocs = ("en",)
+else:
+    tlocs = ("en_US.UTF-8", "en_US.US-ASCII", "en_US")
+
+for tloc in tlocs:
+    try:
+        locale.setlocale(locale.LC_NUMERIC, tloc)
+        break
+    except locale.Error:
+        continue
+else:
+    raise ImportError, "test locale not supported (tried %s)"%(', '.join(tlocs))
+
+def testformat(formatstr, value, grouping = 0, output=None, func=locale.format):
+    if verbose:
+        if output:
+            print "%s %% %s =? %s ..." %\
+                (repr(formatstr), repr(value), repr(output)),
+        else:
+            print "%s %% %s works? ..." % (repr(formatstr), repr(value)),
+    result = func(formatstr, value, grouping = grouping)
+    if output and result != output:
+        if verbose:
+            print 'no'
+        print "%s %% %s == %s != %s" %\
+              (repr(formatstr), repr(value), repr(result), repr(output))
+    else:
+        if verbose:
+            print "yes"
+
+try:
+    # On Solaris 10, the thousands_sep is the empty string
+    sep = locale.localeconv()['thousands_sep']
+    testformat("%f", 1024, grouping=1, output='1%s024.000000' % sep)
+    testformat("%f", 102, grouping=1, output='102.000000')
+    testformat("%f", -42, grouping=1, output='-42.000000')
+    testformat("%+f", -42, grouping=1, output='-42.000000')
+    testformat("%20.f", -42, grouping=1, output='                 -42')
+    testformat("%+10.f", -4200, grouping=1, output='    -4%s200' % sep)
+    testformat("%-10.f", 4200, grouping=1, output='4%s200     ' % sep)
+    # Invoke getpreferredencoding to make sure it does not cause exceptions,
+    locale.getpreferredencoding()
+
+    # === Test format() with more complex formatting strings
+    # test if grouping is independent from other characters in formatting string
+    testformat("One million is %i", 1000000, grouping=1,
+               output='One million is 1%s000%s000' % (sep, sep),
+               func=locale.format_string)
+    testformat("One  million is %i", 1000000, grouping=1,
+               output='One  million is 1%s000%s000' % (sep, sep),
+               func=locale.format_string)
+    # test dots in formatting string
+    testformat(".%f.", 1000.0, output='.1000.000000.', func=locale.format_string)
+    # test floats
+    testformat("--> %10.2f", 1000.0, grouping=1, output='-->   1%s000.00' % sep,
+               func=locale.format_string)
+    # test asterisk formats
+    testformat("%10.*f", (2, 1000.0), grouping=0, output='   1000.00',
+               func=locale.format_string)
+    testformat("%*.*f", (10, 2, 1000.0), grouping=1, output='  1%s000.00' % sep,
+               func=locale.format_string)
+    # test more-in-one
+    testformat("int %i float %.2f str %s", (1000, 1000.0, 'str'), grouping=1,
+               output='int 1%s000 float 1%s000.00 str str' % (sep, sep),
+               func=locale.format_string)
+
+finally:
+    locale.setlocale(locale.LC_NUMERIC, oldlocale)
+
+
+# Test BSD Rune locale's bug for isctype functions.
+def teststrop(s, method, output):
+    if verbose:
+        print "%s.%s() =? %s ..." % (repr(s), method, repr(output)),
+    result = getattr(s, method)()
+    if result != output:
+        if verbose:
+            print "no"
+        print "%s.%s() == %s != %s" % (repr(s), method, repr(result),
+                                       repr(output))
+    elif verbose:
+        print "yes"
+
+try:
+    if sys.platform == 'sunos5':
+        # On Solaris, in en_US.UTF-8, \xa0 is a space
+        raise locale.Error
+    oldlocale = locale.setlocale(locale.LC_CTYPE)
+    locale.setlocale(locale.LC_CTYPE, 'en_US.UTF-8')
+except locale.Error:
+    pass
+else:
+    try:
+        teststrop('\x20', 'isspace', True)
+        teststrop('\xa0', 'isspace', False)
+        teststrop('\xa1', 'isspace', False)
+        teststrop('\xc0', 'isalpha', False)
+        teststrop('\xc0', 'isalnum', False)
+        teststrop('\xc0', 'isupper', False)
+        teststrop('\xc0', 'islower', False)
+        teststrop('\xec\xa0\xbc', 'split', ['\xec\xa0\xbc'])
+        teststrop('\xed\x95\xa0', 'strip', '\xed\x95\xa0')
+        teststrop('\xcc\x85', 'lower', '\xcc\x85')
+        teststrop('\xed\x95\xa0', 'upper', '\xed\x95\xa0')
+    finally:
+        locale.setlocale(locale.LC_CTYPE, oldlocale)

Added: vendor/Python/current/Lib/test/test_logging.py
===================================================================
--- vendor/Python/current/Lib/test/test_logging.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_logging.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,685 @@
+#!/usr/bin/env python
+#
+# Copyright 2001-2004 by Vinay Sajip. All Rights Reserved.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose and without fee is hereby granted,
+# provided that the above copyright notice appear in all copies and that
+# both that copyright notice and this permission notice appear in
+# supporting documentation, and that the name of Vinay Sajip
+# not be used in advertising or publicity pertaining to distribution
+# of the software without specific, written prior permission.
+# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+# This file is part of the Python logging distribution. See
+# http://www.red-dove.com/python_logging.html
+#
+"""Test harness for the logging module. Run all tests.
+
+Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
+"""
+
+import select
+import os, sys, string, struct, types, cPickle, cStringIO
+import socket, tempfile, threading, time
+import logging, logging.handlers, logging.config
+from test.test_support import run_with_locale
+
+BANNER = "-- %-10s %-6s ---------------------------------------------------\n"
+
+FINISH_UP = "Finish up, it's closing time. Messages should bear numbers 0 through 24."
+
+#----------------------------------------------------------------------------
+# Log receiver
+#----------------------------------------------------------------------------
+
+TIMEOUT         = 10
+
+from SocketServer import ThreadingTCPServer, StreamRequestHandler
+
+class LogRecordStreamHandler(StreamRequestHandler):
+    """
+    Handler for a streaming logging request. It basically logs the record
+    using whatever logging policy is configured locally.
+    """
+
+    def handle(self):
+        """
+        Handle multiple requests - each expected to be a 4-byte length,
+        followed by the LogRecord in pickle format. Logs the record
+        according to whatever policy is configured locally.
+        """
+        while 1:
+            try:
+                chunk = self.connection.recv(4)
+                if len(chunk) < 4:
+                    break
+                slen = struct.unpack(">L", chunk)[0]
+                chunk = self.connection.recv(slen)
+                while len(chunk) < slen:
+                    chunk = chunk + self.connection.recv(slen - len(chunk))
+                obj = self.unPickle(chunk)
+                record = logging.makeLogRecord(obj)
+                self.handleLogRecord(record)
+            except:
+                raise
+
+    def unPickle(self, data):
+        return cPickle.loads(data)
+
+    def handleLogRecord(self, record):
+        logname = "logrecv.tcp." + record.name
+        #If the end-of-messages sentinel is seen, tell the server to terminate
+        if record.msg == FINISH_UP:
+            self.server.abort = 1
+        record.msg = record.msg + " (via " + logname + ")"
+        logger = logging.getLogger(logname)
+        logger.handle(record)
+
+# The server sets socketDataProcessed when it's done.
+socketDataProcessed = threading.Event()
+
+class LogRecordSocketReceiver(ThreadingTCPServer):
+    """
+    A simple-minded TCP socket-based logging receiver suitable for test
+    purposes.
+    """
+
+    allow_reuse_address = 1
+
+    def __init__(self, host='localhost',
+                             port=logging.handlers.DEFAULT_TCP_LOGGING_PORT,
+                     handler=LogRecordStreamHandler):
+        ThreadingTCPServer.__init__(self, (host, port), handler)
+        self.abort = 0
+        self.timeout = 1
+
+    def serve_until_stopped(self):
+        while not self.abort:
+            rd, wr, ex = select.select([self.socket.fileno()], [], [],
+                                       self.timeout)
+            if rd:
+                self.handle_request()
+        #notify the main thread that we're about to exit
+        socketDataProcessed.set()
+        # close the listen socket
+        self.server_close()
+
+    def process_request(self, request, client_address):
+        #import threading
+        t = threading.Thread(target = self.finish_request,
+                             args = (request, client_address))
+        t.start()
+
+def runTCP(tcpserver):
+    tcpserver.serve_until_stopped()
+
+#----------------------------------------------------------------------------
+# Test 0
+#----------------------------------------------------------------------------
+
+msgcount = 0
+
+def nextmessage():
+    global msgcount
+    rv = "Message %d" % msgcount
+    msgcount = msgcount + 1
+    return rv
+
+def test0():
+    ERR = logging.getLogger("ERR")
+    ERR.setLevel(logging.ERROR)
+    INF = logging.getLogger("INF")
+    INF.setLevel(logging.INFO)
+    INF_ERR  = logging.getLogger("INF.ERR")
+    INF_ERR.setLevel(logging.ERROR)
+    DEB = logging.getLogger("DEB")
+    DEB.setLevel(logging.DEBUG)
+
+    INF_UNDEF = logging.getLogger("INF.UNDEF")
+    INF_ERR_UNDEF = logging.getLogger("INF.ERR.UNDEF")
+    UNDEF = logging.getLogger("UNDEF")
+
+    GRANDCHILD = logging.getLogger("INF.BADPARENT.UNDEF")
+    CHILD = logging.getLogger("INF.BADPARENT")
+
+    #These should log
+    ERR.log(logging.FATAL, nextmessage())
+    ERR.error(nextmessage())
+
+    INF.log(logging.FATAL, nextmessage())
+    INF.error(nextmessage())
+    INF.warn(nextmessage())
+    INF.info(nextmessage())
+
+    INF_UNDEF.log(logging.FATAL, nextmessage())
+    INF_UNDEF.error(nextmessage())
+    INF_UNDEF.warn (nextmessage())
+    INF_UNDEF.info (nextmessage())
+
+    INF_ERR.log(logging.FATAL, nextmessage())
+    INF_ERR.error(nextmessage())
+
+    INF_ERR_UNDEF.log(logging.FATAL, nextmessage())
+    INF_ERR_UNDEF.error(nextmessage())
+
+    DEB.log(logging.FATAL, nextmessage())
+    DEB.error(nextmessage())
+    DEB.warn (nextmessage())
+    DEB.info (nextmessage())
+    DEB.debug(nextmessage())
+
+    UNDEF.log(logging.FATAL, nextmessage())
+    UNDEF.error(nextmessage())
+    UNDEF.warn (nextmessage())
+    UNDEF.info (nextmessage())
+
+    GRANDCHILD.log(logging.FATAL, nextmessage())
+    CHILD.log(logging.FATAL, nextmessage())
+
+    #These should not log
+    ERR.warn(nextmessage())
+    ERR.info(nextmessage())
+    ERR.debug(nextmessage())
+
+    INF.debug(nextmessage())
+    INF_UNDEF.debug(nextmessage())
+
+    INF_ERR.warn(nextmessage())
+    INF_ERR.info(nextmessage())
+    INF_ERR.debug(nextmessage())
+    INF_ERR_UNDEF.warn(nextmessage())
+    INF_ERR_UNDEF.info(nextmessage())
+    INF_ERR_UNDEF.debug(nextmessage())
+
+    INF.info(FINISH_UP)
+
+#----------------------------------------------------------------------------
+# Test 1
+#----------------------------------------------------------------------------
+
+#
+#   First, we define our levels. There can be as many as you want - the only
+#     limitations are that they should be integers, the lowest should be > 0 and
+#   larger values mean less information being logged. If you need specific
+#   level values which do not fit into these limitations, you can use a
+#   mapping dictionary to convert between your application levels and the
+#   logging system.
+#
+SILENT      = 10
+TACITURN    = 9
+TERSE       = 8
+EFFUSIVE    = 7
+SOCIABLE    = 6
+VERBOSE     = 5
+TALKATIVE   = 4
+GARRULOUS   = 3
+CHATTERBOX  = 2
+BORING      = 1
+
+LEVEL_RANGE = range(BORING, SILENT + 1)
+
+#
+#   Next, we define names for our levels. You don't need to do this - in which
+#   case the system will use "Level n" to denote the text for the level.
+#
+my_logging_levels = {
+    SILENT      : 'Silent',
+    TACITURN    : 'Taciturn',
+    TERSE       : 'Terse',
+    EFFUSIVE    : 'Effusive',
+    SOCIABLE    : 'Sociable',
+    VERBOSE     : 'Verbose',
+    TALKATIVE   : 'Talkative',
+    GARRULOUS   : 'Garrulous',
+    CHATTERBOX  : 'Chatterbox',
+    BORING      : 'Boring',
+}
+
+#
+#   Now, to demonstrate filtering: suppose for some perverse reason we only
+#   want to print out all except GARRULOUS messages. Let's create a filter for
+#   this purpose...
+#
+class SpecificLevelFilter(logging.Filter):
+    def __init__(self, lvl):
+        self.level = lvl
+
+    def filter(self, record):
+        return self.level != record.levelno
+
+class GarrulousFilter(SpecificLevelFilter):
+    def __init__(self):
+        SpecificLevelFilter.__init__(self, GARRULOUS)
+
+#
+#   Now, let's demonstrate filtering at the logger. This time, use a filter
+#   which excludes SOCIABLE and TACITURN messages. Note that GARRULOUS events
+#   are still excluded.
+#
+class VerySpecificFilter(logging.Filter):
+    def filter(self, record):
+        return record.levelno not in [SOCIABLE, TACITURN]
+
+def message(s):
+    sys.stdout.write("%s\n" % s)
+
+SHOULD1 = "This should only be seen at the '%s' logging level (or lower)"
+
+def test1():
+#
+#   Now, tell the logging system to associate names with our levels.
+#
+    for lvl in my_logging_levels.keys():
+        logging.addLevelName(lvl, my_logging_levels[lvl])
+
+#
+#   Now, define a test function which logs an event at each of our levels.
+#
+
+    def doLog(log):
+        for lvl in LEVEL_RANGE:
+            log.log(lvl, SHOULD1, logging.getLevelName(lvl))
+
+    log = logging.getLogger("")
+    hdlr = log.handlers[0]
+#
+#   Set the logging level to each different value and call the utility
+#   function to log events.
+#   In the output, you should see that each time round the loop, the number of
+#   logging events which are actually output decreases.
+#
+    for lvl in LEVEL_RANGE:
+        message("-- setting logging level to '%s' -----" %
+                        logging.getLevelName(lvl))
+        log.setLevel(lvl)
+        doLog(log)
+  #
+  #   Now, we demonstrate level filtering at the handler level. Tell the
+  #   handler defined above to filter at level 'SOCIABLE', and repeat the
+  #   above loop. Compare the output from the two runs.
+  #
+    hdlr.setLevel(SOCIABLE)
+    message("-- Filtering at handler level to SOCIABLE --")
+    for lvl in LEVEL_RANGE:
+        message("-- setting logging level to '%s' -----" %
+                      logging.getLevelName(lvl))
+        log.setLevel(lvl)
+        doLog(log)
+
+    hdlr.setLevel(0)    #turn off level filtering at the handler
+
+    garr = GarrulousFilter()
+    hdlr.addFilter(garr)
+    message("-- Filtering using GARRULOUS filter --")
+    for lvl in LEVEL_RANGE:
+        message("-- setting logging level to '%s' -----" %
+                        logging.getLevelName(lvl))
+        log.setLevel(lvl)
+        doLog(log)
+    spec = VerySpecificFilter()
+    log.addFilter(spec)
+    message("-- Filtering using specific filter for SOCIABLE, TACITURN --")
+    for lvl in LEVEL_RANGE:
+        message("-- setting logging level to '%s' -----" %
+                      logging.getLevelName(lvl))
+        log.setLevel(lvl)
+        doLog(log)
+
+    log.removeFilter(spec)
+    hdlr.removeFilter(garr)
+    #Undo the one level which clashes...for regression tests
+    logging.addLevelName(logging.DEBUG, "DEBUG")
+
+#----------------------------------------------------------------------------
+# Test 2
+#----------------------------------------------------------------------------
+
+MSG = "-- logging %d at INFO, messages should be seen every 10 events --"
+def test2():
+    logger = logging.getLogger("")
+    sh = logger.handlers[0]
+    sh.close()
+    logger.removeHandler(sh)
+    mh = logging.handlers.MemoryHandler(10,logging.WARNING, sh)
+    logger.setLevel(logging.DEBUG)
+    logger.addHandler(mh)
+    message("-- logging at DEBUG, nothing should be seen yet --")
+    logger.debug("Debug message")
+    message("-- logging at INFO, nothing should be seen yet --")
+    logger.info("Info message")
+    message("-- logging at WARNING, 3 messages should be seen --")
+    logger.warn("Warn message")
+    for i in xrange(102):
+        message(MSG % i)
+        logger.info("Info index = %d", i)
+    mh.close()
+    logger.removeHandler(mh)
+    logger.addHandler(sh)
+
+#----------------------------------------------------------------------------
+# Test 3
+#----------------------------------------------------------------------------
+
+FILTER = "a.b"
+
+def doLog3():
+    logging.getLogger("a").info("Info 1")
+    logging.getLogger("a.b").info("Info 2")
+    logging.getLogger("a.c").info("Info 3")
+    logging.getLogger("a.b.c").info("Info 4")
+    logging.getLogger("a.b.c.d").info("Info 5")
+    logging.getLogger("a.bb.c").info("Info 6")
+    logging.getLogger("b").info("Info 7")
+    logging.getLogger("b.a").info("Info 8")
+    logging.getLogger("c.a.b").info("Info 9")
+    logging.getLogger("a.bb").info("Info 10")
+
+def test3():
+    root = logging.getLogger()
+    root.setLevel(logging.DEBUG)
+    hand = root.handlers[0]
+    message("Unfiltered...")
+    doLog3()
+    message("Filtered with '%s'..." % FILTER)
+    filt = logging.Filter(FILTER)
+    hand.addFilter(filt)
+    doLog3()
+    hand.removeFilter(filt)
+
+#----------------------------------------------------------------------------
+# Test 4
+#----------------------------------------------------------------------------
+
+# config0 is a standard configuration.
+config0 = """
+[loggers]
+keys=root
+
+[handlers]
+keys=hand1
+
+[formatters]
+keys=form1
+
+[logger_root]
+level=NOTSET
+handlers=hand1
+
+[handler_hand1]
+class=StreamHandler
+level=NOTSET
+formatter=form1
+args=(sys.stdout,)
+
+[formatter_form1]
+format=%(levelname)s:%(name)s:%(message)s
+datefmt=
+"""
+
+# config1 adds a little to the standard configuration.
+config1 = """
+[loggers]
+keys=root,parser
+
+[handlers]
+keys=hand1
+
+[formatters]
+keys=form1
+
+[logger_root]
+level=NOTSET
+handlers=hand1
+
+[logger_parser]
+level=DEBUG
+handlers=hand1
+propagate=1
+qualname=compiler.parser
+
+[handler_hand1]
+class=StreamHandler
+level=NOTSET
+formatter=form1
+args=(sys.stdout,)
+
+[formatter_form1]
+format=%(levelname)s:%(name)s:%(message)s
+datefmt=
+"""
+
+# config2 has a subtle configuration error that should be reported
+config2 = string.replace(config1, "sys.stdout", "sys.stbout")
+
+# config3 has a less subtle configuration error
+config3 = string.replace(
+    config1, "formatter=form1", "formatter=misspelled_name")
+
+def test4():
+    for i in range(4):
+        conf = globals()['config%d' % i]
+        sys.stdout.write('config%d: ' % i)
+        loggerDict = logging.getLogger().manager.loggerDict
+        logging._acquireLock()
+        try:
+            saved_handlers = logging._handlers.copy()
+            saved_handler_list = logging._handlerList[:]
+            saved_loggers = loggerDict.copy()
+        finally:
+            logging._releaseLock()
+        try:
+            fn = tempfile.mktemp(".ini")
+            f = open(fn, "w")
+            f.write(conf)
+            f.close()
+            try:
+                logging.config.fileConfig(fn)
+                #call again to make sure cleanup is correct
+                logging.config.fileConfig(fn)
+            except:
+                t = sys.exc_info()[0]
+                message(str(t))
+            else:
+                message('ok.')
+            os.remove(fn)
+        finally:
+            logging._acquireLock()
+            try:
+                logging._handlers.clear()
+                logging._handlers.update(saved_handlers)
+                logging._handlerList[:] = saved_handler_list
+                loggerDict = logging.getLogger().manager.loggerDict
+                loggerDict.clear()
+                loggerDict.update(saved_loggers)
+            finally:
+                logging._releaseLock()
+
+#----------------------------------------------------------------------------
+# Test 5
+#----------------------------------------------------------------------------
+
+test5_config = """
+[loggers]
+keys=root
+
+[handlers]
+keys=hand1
+
+[formatters]
+keys=form1
+
+[logger_root]
+level=NOTSET
+handlers=hand1
+
+[handler_hand1]
+class=StreamHandler
+level=NOTSET
+formatter=form1
+args=(sys.stdout,)
+
+[formatter_form1]
+class=test.test_logging.FriendlyFormatter
+format=%(levelname)s:%(name)s:%(message)s
+datefmt=
+"""
+
+class FriendlyFormatter (logging.Formatter):
+    def formatException(self, ei):
+        return "%s... Don't panic!" % str(ei[0])
+
+
+def test5():
+    loggerDict = logging.getLogger().manager.loggerDict
+    logging._acquireLock()
+    try:
+        saved_handlers = logging._handlers.copy()
+        saved_handler_list = logging._handlerList[:]
+        saved_loggers = loggerDict.copy()
+    finally:
+        logging._releaseLock()
+    try:
+        fn = tempfile.mktemp(".ini")
+        f = open(fn, "w")
+        f.write(test5_config)
+        f.close()
+        logging.config.fileConfig(fn)
+        try:
+            raise KeyError
+        except KeyError:
+            logging.exception("just testing")
+        os.remove(fn)
+        hdlr = logging.getLogger().handlers[0]
+        logging.getLogger().handlers.remove(hdlr)
+    finally:
+        logging._acquireLock()
+        try:
+            logging._handlers.clear()
+            logging._handlers.update(saved_handlers)
+            logging._handlerList[:] = saved_handler_list
+            loggerDict = logging.getLogger().manager.loggerDict
+            loggerDict.clear()
+            loggerDict.update(saved_loggers)
+        finally:
+            logging._releaseLock()
+
+
+#----------------------------------------------------------------------------
+# Test Harness
+#----------------------------------------------------------------------------
+def banner(nm, typ):
+    sep = BANNER % (nm, typ)
+    sys.stdout.write(sep)
+    sys.stdout.flush()
+
+def test_main_inner():
+    rootLogger = logging.getLogger("")
+    rootLogger.setLevel(logging.DEBUG)
+    hdlr = logging.StreamHandler(sys.stdout)
+    fmt = logging.Formatter(logging.BASIC_FORMAT)
+    hdlr.setFormatter(fmt)
+    rootLogger.addHandler(hdlr)
+
+    # Find an unused port number
+    port = logging.handlers.DEFAULT_TCP_LOGGING_PORT
+    while port < logging.handlers.DEFAULT_TCP_LOGGING_PORT+100:
+        try:
+            tcpserver = LogRecordSocketReceiver(port=port)
+        except socket.error:
+            port += 1
+        else:
+            break
+    else:
+        raise ImportError, "Could not find unused port"
+
+
+    #Set up a handler such that all events are sent via a socket to the log
+    #receiver (logrecv).
+    #The handler will only be added to the rootLogger for some of the tests
+    shdlr = logging.handlers.SocketHandler('localhost', port)
+
+    #Configure the logger for logrecv so events do not propagate beyond it.
+    #The sockLogger output is buffered in memory until the end of the test,
+    #and printed at the end.
+    sockOut = cStringIO.StringIO()
+    sockLogger = logging.getLogger("logrecv")
+    sockLogger.setLevel(logging.DEBUG)
+    sockhdlr = logging.StreamHandler(sockOut)
+    sockhdlr.setFormatter(logging.Formatter(
+                                   "%(name)s -> %(levelname)s: %(message)s"))
+    sockLogger.addHandler(sockhdlr)
+    sockLogger.propagate = 0
+
+    #Set up servers
+    threads = []
+    #sys.stdout.write("About to start TCP server...\n")
+    threads.append(threading.Thread(target=runTCP, args=(tcpserver,)))
+
+    for thread in threads:
+        thread.start()
+    try:
+        banner("log_test0", "begin")
+
+        rootLogger.addHandler(shdlr)
+        test0()
+        # XXX(nnorwitz): Try to fix timing related test failures.
+        # This sleep gives us some extra time to read messages.
+        # The test generally only fails on Solaris without this sleep.
+        time.sleep(2.0)
+        shdlr.close()
+        rootLogger.removeHandler(shdlr)
+
+        banner("log_test0", "end")
+
+        for t in range(1,6):
+            banner("log_test%d" % t, "begin")
+            globals()['test%d' % t]()
+            banner("log_test%d" % t, "end")
+
+    finally:
+        #wait for TCP receiver to terminate
+        socketDataProcessed.wait()
+        # ensure the server dies
+        tcpserver.abort = 1
+        for thread in threads:
+            thread.join(2.0)
+        banner("logrecv output", "begin")
+        sys.stdout.write(sockOut.getvalue())
+        sockOut.close()
+        sockLogger.removeHandler(sockhdlr)
+        sockhdlr.close()
+        banner("logrecv output", "end")
+        sys.stdout.flush()
+        try:
+            hdlr.close()
+        except:
+            pass
+        rootLogger.removeHandler(hdlr)
+
+# Set the locale to the platform-dependent default.  I have no idea
+# why the test does this, but in any case we save the current locale
+# first and restore it at the end.
+ at run_with_locale('LC_ALL', '')
+def test_main():
+    # Save and restore the original root logger level across the tests.
+    # Otherwise, e.g., if any test using cookielib runs after test_logging,
+    # cookielib's debug-level logger tries to log messages, leading to
+    # confusing:
+    #    No handlers could be found for logger "cookielib"
+    # output while the tests are running.
+    root_logger = logging.getLogger("")
+    original_logging_level = root_logger.getEffectiveLevel()
+    try:
+        test_main_inner()
+    finally:
+        root_logger.setLevel(original_logging_level)
+
+if __name__ == "__main__":
+    sys.stdout.write("test_logging\n")
+    test_main()

Added: vendor/Python/current/Lib/test/test_long.py
===================================================================
--- vendor/Python/current/Lib/test/test_long.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_long.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,503 @@
+import unittest
+from test import test_support
+
+import random
+
+# Used for lazy formatting of failure messages
+class Frm(object):
+    def __init__(self, format, *args):
+        self.format = format
+        self.args = args
+
+    def __str__(self):
+        return self.format % self.args
+
+# SHIFT should match the value in longintrepr.h for best testing.
+SHIFT = 15
+BASE = 2 ** SHIFT
+MASK = BASE - 1
+KARATSUBA_CUTOFF = 70   # from longobject.c
+
+# Max number of base BASE digits to use in test cases.  Doubling
+# this will more than double the runtime.
+MAXDIGITS = 15
+
+# build some special values
+special = map(long, [0, 1, 2, BASE, BASE >> 1])
+special.append(0x5555555555555555L)
+special.append(0xaaaaaaaaaaaaaaaaL)
+#  some solid strings of one bits
+p2 = 4L  # 0 and 1 already added
+for i in range(2*SHIFT):
+    special.append(p2 - 1)
+    p2 = p2 << 1
+del p2
+# add complements & negations
+special = special + map(lambda x: ~x, special) + \
+                    map(lambda x: -x, special)
+
+
+class LongTest(unittest.TestCase):
+
+    # Get quasi-random long consisting of ndigits digits (in base BASE).
+    # quasi == the most-significant digit will not be 0, and the number
+    # is constructed to contain long strings of 0 and 1 bits.  These are
+    # more likely than random bits to provoke digit-boundary errors.
+    # The sign of the number is also random.
+
+    def getran(self, ndigits):
+        self.assert_(ndigits > 0)
+        nbits_hi = ndigits * SHIFT
+        nbits_lo = nbits_hi - SHIFT + 1
+        answer = 0L
+        nbits = 0
+        r = int(random.random() * (SHIFT * 2)) | 1  # force 1 bits to start
+        while nbits < nbits_lo:
+            bits = (r >> 1) + 1
+            bits = min(bits, nbits_hi - nbits)
+            self.assert_(1 <= bits <= SHIFT)
+            nbits = nbits + bits
+            answer = answer << bits
+            if r & 1:
+                answer = answer | ((1 << bits) - 1)
+            r = int(random.random() * (SHIFT * 2))
+        self.assert_(nbits_lo <= nbits <= nbits_hi)
+        if random.random() < 0.5:
+            answer = -answer
+        return answer
+
+    # Get random long consisting of ndigits random digits (relative to base
+    # BASE).  The sign bit is also random.
+
+    def getran2(ndigits):
+        answer = 0L
+        for i in xrange(ndigits):
+            answer = (answer << SHIFT) | random.randint(0, MASK)
+        if random.random() < 0.5:
+            answer = -answer
+        return answer
+
+    def check_division(self, x, y):
+        eq = self.assertEqual
+        q, r = divmod(x, y)
+        q2, r2 = x//y, x%y
+        pab, pba = x*y, y*x
+        eq(pab, pba, Frm("multiplication does not commute for %r and %r", x, y))
+        eq(q, q2, Frm("divmod returns different quotient than / for %r and %r", x, y))
+        eq(r, r2, Frm("divmod returns different mod than %% for %r and %r", x, y))
+        eq(x, q*y + r, Frm("x != q*y + r after divmod on x=%r, y=%r", x, y))
+        if y > 0:
+            self.assert_(0 <= r < y, Frm("bad mod from divmod on %r and %r", x, y))
+        else:
+            self.assert_(y < r <= 0, Frm("bad mod from divmod on %r and %r", x, y))
+
+    def test_division(self):
+        digits = range(1, MAXDIGITS+1) + range(KARATSUBA_CUTOFF,
+                                               KARATSUBA_CUTOFF + 14)
+        digits.append(KARATSUBA_CUTOFF * 3)
+        for lenx in digits:
+            x = self.getran(lenx)
+            for leny in digits:
+                y = self.getran(leny) or 1L
+                self.check_division(x, y)
+
+    def test_karatsuba(self):
+        digits = range(1, 5) + range(KARATSUBA_CUTOFF, KARATSUBA_CUTOFF + 10)
+        digits.extend([KARATSUBA_CUTOFF * 10, KARATSUBA_CUTOFF * 100])
+
+        bits = [digit * SHIFT for digit in digits]
+
+        # Test products of long strings of 1 bits -- (2**x-1)*(2**y-1) ==
+        # 2**(x+y) - 2**x - 2**y + 1, so the proper result is easy to check.
+        for abits in bits:
+            a = (1L << abits) - 1
+            for bbits in bits:
+                if bbits < abits:
+                    continue
+                b = (1L << bbits) - 1
+                x = a * b
+                y = ((1L << (abits + bbits)) -
+                     (1L << abits) -
+                     (1L << bbits) +
+                     1)
+                self.assertEqual(x, y,
+                    Frm("bad result for a*b: a=%r, b=%r, x=%r, y=%r", a, b, x, y))
+
+    def check_bitop_identities_1(self, x):
+        eq = self.assertEqual
+        eq(x & 0, 0, Frm("x & 0 != 0 for x=%r", x))
+        eq(x | 0, x, Frm("x | 0 != x for x=%r", x))
+        eq(x ^ 0, x, Frm("x ^ 0 != x for x=%r", x))
+        eq(x & -1, x, Frm("x & -1 != x for x=%r", x))
+        eq(x | -1, -1, Frm("x | -1 != -1 for x=%r", x))
+        eq(x ^ -1, ~x, Frm("x ^ -1 != ~x for x=%r", x))
+        eq(x, ~~x, Frm("x != ~~x for x=%r", x))
+        eq(x & x, x, Frm("x & x != x for x=%r", x))
+        eq(x | x, x, Frm("x | x != x for x=%r", x))
+        eq(x ^ x, 0, Frm("x ^ x != 0 for x=%r", x))
+        eq(x & ~x, 0, Frm("x & ~x != 0 for x=%r", x))
+        eq(x | ~x, -1, Frm("x | ~x != -1 for x=%r", x))
+        eq(x ^ ~x, -1, Frm("x ^ ~x != -1 for x=%r", x))
+        eq(-x, 1 + ~x, Frm("not -x == 1 + ~x for x=%r", x))
+        eq(-x, ~(x-1), Frm("not -x == ~(x-1) forx =%r", x))
+        for n in xrange(2*SHIFT):
+            p2 = 2L ** n
+            eq(x << n >> n, x,
+                Frm("x << n >> n != x for x=%r, n=%r", (x, n)))
+            eq(x // p2, x >> n,
+                Frm("x // p2 != x >> n for x=%r n=%r p2=%r", (x, n, p2)))
+            eq(x * p2, x << n,
+                Frm("x * p2 != x << n for x=%r n=%r p2=%r", (x, n, p2)))
+            eq(x & -p2, x >> n << n,
+                Frm("not x & -p2 == x >> n << n for x=%r n=%r p2=%r", (x, n, p2)))
+            eq(x & -p2, x & ~(p2 - 1),
+                Frm("not x & -p2 == x & ~(p2 - 1) for x=%r n=%r p2=%r", (x, n, p2)))
+
+    def check_bitop_identities_2(self, x, y):
+        eq = self.assertEqual
+        eq(x & y, y & x, Frm("x & y != y & x for x=%r, y=%r", (x, y)))
+        eq(x | y, y | x, Frm("x | y != y | x for x=%r, y=%r", (x, y)))
+        eq(x ^ y, y ^ x, Frm("x ^ y != y ^ x for x=%r, y=%r", (x, y)))
+        eq(x ^ y ^ x, y, Frm("x ^ y ^ x != y for x=%r, y=%r", (x, y)))
+        eq(x & y, ~(~x | ~y), Frm("x & y != ~(~x | ~y) for x=%r, y=%r", (x, y)))
+        eq(x | y, ~(~x & ~y), Frm("x | y != ~(~x & ~y) for x=%r, y=%r", (x, y)))
+        eq(x ^ y, (x | y) & ~(x & y),
+             Frm("x ^ y != (x | y) & ~(x & y) for x=%r, y=%r", (x, y)))
+        eq(x ^ y, (x & ~y) | (~x & y),
+             Frm("x ^ y == (x & ~y) | (~x & y) for x=%r, y=%r", (x, y)))
+        eq(x ^ y, (x | y) & (~x | ~y),
+             Frm("x ^ y == (x | y) & (~x | ~y) for x=%r, y=%r", (x, y)))
+
+    def check_bitop_identities_3(self, x, y, z):
+        eq = self.assertEqual
+        eq((x & y) & z, x & (y & z),
+             Frm("(x & y) & z != x & (y & z) for x=%r, y=%r, z=%r", (x, y, z)))
+        eq((x | y) | z, x | (y | z),
+             Frm("(x | y) | z != x | (y | z) for x=%r, y=%r, z=%r", (x, y, z)))
+        eq((x ^ y) ^ z, x ^ (y ^ z),
+             Frm("(x ^ y) ^ z != x ^ (y ^ z) for x=%r, y=%r, z=%r", (x, y, z)))
+        eq(x & (y | z), (x & y) | (x & z),
+             Frm("x & (y | z) != (x & y) | (x & z) for x=%r, y=%r, z=%r", (x, y, z)))
+        eq(x | (y & z), (x | y) & (x | z),
+             Frm("x | (y & z) != (x | y) & (x | z) for x=%r, y=%r, z=%r", (x, y, z)))
+
+    def test_bitop_identities(self):
+        for x in special:
+            self.check_bitop_identities_1(x)
+        digits = xrange(1, MAXDIGITS+1)
+        for lenx in digits:
+            x = self.getran(lenx)
+            self.check_bitop_identities_1(x)
+            for leny in digits:
+                y = self.getran(leny)
+                self.check_bitop_identities_2(x, y)
+                self.check_bitop_identities_3(x, y, self.getran((lenx + leny)//2))
+
+    def slow_format(self, x, base):
+        if (x, base) == (0, 8):
+            # this is an oddball!
+            return "0L"
+        digits = []
+        sign = 0
+        if x < 0:
+            sign, x = 1, -x
+        while x:
+            x, r = divmod(x, base)
+            digits.append(int(r))
+        digits.reverse()
+        digits = digits or [0]
+        return '-'[:sign] + \
+               {8: '0', 10: '', 16: '0x'}[base] + \
+               "".join(map(lambda i: "0123456789abcdef"[i], digits)) + "L"
+
+    def check_format_1(self, x):
+        for base, mapper in (8, oct), (10, repr), (16, hex):
+            got = mapper(x)
+            expected = self.slow_format(x, base)
+            msg = Frm("%s returned %r but expected %r for %r",
+                mapper.__name__, got, expected, x)
+            self.assertEqual(got, expected, msg)
+            self.assertEqual(long(got, 0), x, Frm('long("%s", 0) != %r', got, x))
+        # str() has to be checked a little differently since there's no
+        # trailing "L"
+        got = str(x)
+        expected = self.slow_format(x, 10)[:-1]
+        msg = Frm("%s returned %r but expected %r for %r",
+            mapper.__name__, got, expected, x)
+        self.assertEqual(got, expected, msg)
+
+    def test_format(self):
+        for x in special:
+            self.check_format_1(x)
+        for i in xrange(10):
+            for lenx in xrange(1, MAXDIGITS+1):
+                x = self.getran(lenx)
+                self.check_format_1(x)
+
+    def test_misc(self):
+        import sys
+
+        # check the extremes in int<->long conversion
+        hugepos = sys.maxint
+        hugeneg = -hugepos - 1
+        hugepos_aslong = long(hugepos)
+        hugeneg_aslong = long(hugeneg)
+        self.assertEqual(hugepos, hugepos_aslong, "long(sys.maxint) != sys.maxint")
+        self.assertEqual(hugeneg, hugeneg_aslong,
+            "long(-sys.maxint-1) != -sys.maxint-1")
+
+        # long -> int should not fail for hugepos_aslong or hugeneg_aslong
+        x = int(hugepos_aslong)
+        try:
+            self.assertEqual(x, hugepos,
+                  "converting sys.maxint to long and back to int fails")
+        except OverflowError:
+            self.fail("int(long(sys.maxint)) overflowed!")
+        if not isinstance(x, int):
+            raise TestFailed("int(long(sys.maxint)) should have returned int")
+        x = int(hugeneg_aslong)
+        try:
+            self.assertEqual(x, hugeneg,
+                  "converting -sys.maxint-1 to long and back to int fails")
+        except OverflowError:
+            self.fail("int(long(-sys.maxint-1)) overflowed!")
+        if not isinstance(x, int):
+            raise TestFailed("int(long(-sys.maxint-1)) should have "
+                             "returned int")
+        # but long -> int should overflow for hugepos+1 and hugeneg-1
+        x = hugepos_aslong + 1
+        try:
+            y = int(x)
+        except OverflowError:
+            self.fail("int(long(sys.maxint) + 1) mustn't overflow")
+        self.assert_(isinstance(y, long),
+            "int(long(sys.maxint) + 1) should have returned long")
+
+        x = hugeneg_aslong - 1
+        try:
+            y = int(x)
+        except OverflowError:
+            self.fail("int(long(-sys.maxint-1) - 1) mustn't overflow")
+        self.assert_(isinstance(y, long),
+               "int(long(-sys.maxint-1) - 1) should have returned long")
+
+        class long2(long):
+            pass
+        x = long2(1L<<100)
+        y = int(x)
+        self.assert_(type(y) is long,
+            "overflowing int conversion must return long not long subtype")
+
+        # long -> Py_ssize_t conversion
+        class X(object):
+            def __getslice__(self, i, j):
+                return i, j
+
+        self.assertEqual(X()[-5L:7L], (-5, 7))
+        # use the clamping effect to test the smallest and largest longs
+        # that fit a Py_ssize_t
+        slicemin, slicemax = X()[-2L**100:2L**100]
+        self.assertEqual(X()[slicemin:slicemax], (slicemin, slicemax))
+
+# ----------------------------------- tests of auto int->long conversion
+
+    def test_auto_overflow(self):
+        import math, sys
+
+        special = [0, 1, 2, 3, sys.maxint-1, sys.maxint, sys.maxint+1]
+        sqrt = int(math.sqrt(sys.maxint))
+        special.extend([sqrt-1, sqrt, sqrt+1])
+        special.extend([-i for i in special])
+
+        def checkit(*args):
+            # Heavy use of nested scopes here!
+            self.assertEqual(got, expected,
+                Frm("for %r expected %r got %r", args, expected, got))
+
+        for x in special:
+            longx = long(x)
+
+            expected = -longx
+            got = -x
+            checkit('-', x)
+
+            for y in special:
+                longy = long(y)
+
+                expected = longx + longy
+                got = x + y
+                checkit(x, '+', y)
+
+                expected = longx - longy
+                got = x - y
+                checkit(x, '-', y)
+
+                expected = longx * longy
+                got = x * y
+                checkit(x, '*', y)
+
+                if y:
+                    expected = longx / longy
+                    got = x / y
+                    checkit(x, '/', y)
+
+                    expected = longx // longy
+                    got = x // y
+                    checkit(x, '//', y)
+
+                    expected = divmod(longx, longy)
+                    got = divmod(longx, longy)
+                    checkit(x, 'divmod', y)
+
+                if abs(y) < 5 and not (x == 0 and y < 0):
+                    expected = longx ** longy
+                    got = x ** y
+                    checkit(x, '**', y)
+
+                    for z in special:
+                        if z != 0 :
+                            if y >= 0:
+                                expected = pow(longx, longy, long(z))
+                                got = pow(x, y, z)
+                                checkit('pow', x, y, '%', z)
+                            else:
+                                self.assertRaises(TypeError, pow,longx, longy, long(z))
+
+    def test_float_overflow(self):
+        import math
+
+        for x in -2.0, -1.0, 0.0, 1.0, 2.0:
+            self.assertEqual(float(long(x)), x)
+
+        shuge = '12345' * 120
+        huge = 1L << 30000
+        mhuge = -huge
+        namespace = {'huge': huge, 'mhuge': mhuge, 'shuge': shuge, 'math': math}
+        for test in ["float(huge)", "float(mhuge)",
+                     "complex(huge)", "complex(mhuge)",
+                     "complex(huge, 1)", "complex(mhuge, 1)",
+                     "complex(1, huge)", "complex(1, mhuge)",
+                     "1. + huge", "huge + 1.", "1. + mhuge", "mhuge + 1.",
+                     "1. - huge", "huge - 1.", "1. - mhuge", "mhuge - 1.",
+                     "1. * huge", "huge * 1.", "1. * mhuge", "mhuge * 1.",
+                     "1. // huge", "huge // 1.", "1. // mhuge", "mhuge // 1.",
+                     "1. / huge", "huge / 1.", "1. / mhuge", "mhuge / 1.",
+                     "1. ** huge", "huge ** 1.", "1. ** mhuge", "mhuge ** 1.",
+                     "math.sin(huge)", "math.sin(mhuge)",
+                     "math.sqrt(huge)", "math.sqrt(mhuge)", # should do better
+                     "math.floor(huge)", "math.floor(mhuge)"]:
+
+            self.assertRaises(OverflowError, eval, test, namespace)
+
+            # XXX Perhaps float(shuge) can raise OverflowError on some box?
+            # The comparison should not.
+            self.assertNotEqual(float(shuge), int(shuge),
+                "float(shuge) should not equal int(shuge)")
+
+    def test_logs(self):
+        import math
+
+        LOG10E = math.log10(math.e)
+
+        for exp in range(10) + [100, 1000, 10000]:
+            value = 10 ** exp
+            log10 = math.log10(value)
+            self.assertAlmostEqual(log10, exp)
+
+            # log10(value) == exp, so log(value) == log10(value)/log10(e) ==
+            # exp/LOG10E
+            expected = exp / LOG10E
+            log = math.log(value)
+            self.assertAlmostEqual(log, expected)
+
+        for bad in -(1L << 10000), -2L, 0L:
+            self.assertRaises(ValueError, math.log, bad)
+            self.assertRaises(ValueError, math.log10, bad)
+
+    def test_mixed_compares(self):
+        eq = self.assertEqual
+        import math
+        import sys
+
+        # We're mostly concerned with that mixing floats and longs does the
+        # right stuff, even when longs are too large to fit in a float.
+        # The safest way to check the results is to use an entirely different
+        # method, which we do here via a skeletal rational class (which
+        # represents all Python ints, longs and floats exactly).
+        class Rat:
+            def __init__(self, value):
+                if isinstance(value, (int, long)):
+                    self.n = value
+                    self.d = 1
+                elif isinstance(value, float):
+                    # Convert to exact rational equivalent.
+                    f, e = math.frexp(abs(value))
+                    assert f == 0 or 0.5 <= f < 1.0
+                    # |value| = f * 2**e exactly
+
+                    # Suck up CHUNK bits at a time; 28 is enough so that we suck
+                    # up all bits in 2 iterations for all known binary double-
+                    # precision formats, and small enough to fit in an int.
+                    CHUNK = 28
+                    top = 0
+                    # invariant: |value| = (top + f) * 2**e exactly
+                    while f:
+                        f = math.ldexp(f, CHUNK)
+                        digit = int(f)
+                        assert digit >> CHUNK == 0
+                        top = (top << CHUNK) | digit
+                        f -= digit
+                        assert 0.0 <= f < 1.0
+                        e -= CHUNK
+
+                    # Now |value| = top * 2**e exactly.
+                    if e >= 0:
+                        n = top << e
+                        d = 1
+                    else:
+                        n = top
+                        d = 1 << -e
+                    if value < 0:
+                        n = -n
+                    self.n = n
+                    self.d = d
+                    assert float(n) / float(d) == value
+                else:
+                    raise TypeError("can't deal with %r" % val)
+
+            def __cmp__(self, other):
+                if not isinstance(other, Rat):
+                    other = Rat(other)
+                return cmp(self.n * other.d, self.d * other.n)
+
+        cases = [0, 0.001, 0.99, 1.0, 1.5, 1e20, 1e200]
+        # 2**48 is an important boundary in the internals.  2**53 is an
+        # important boundary for IEEE double precision.
+        for t in 2.0**48, 2.0**50, 2.0**53:
+            cases.extend([t - 1.0, t - 0.3, t, t + 0.3, t + 1.0,
+                          long(t-1), long(t), long(t+1)])
+        cases.extend([0, 1, 2, sys.maxint, float(sys.maxint)])
+        # 1L<<20000 should exceed all double formats.  long(1e200) is to
+        # check that we get equality with 1e200 above.
+        t = long(1e200)
+        cases.extend([0L, 1L, 2L, 1L << 20000, t-1, t, t+1])
+        cases.extend([-x for x in cases])
+        for x in cases:
+            Rx = Rat(x)
+            for y in cases:
+                Ry = Rat(y)
+                Rcmp = cmp(Rx, Ry)
+                xycmp = cmp(x, y)
+                eq(Rcmp, xycmp, Frm("%r %r %d %d", x, y, Rcmp, xycmp))
+                eq(x == y, Rcmp == 0, Frm("%r == %r %d", x, y, Rcmp))
+                eq(x != y, Rcmp != 0, Frm("%r != %r %d", x, y, Rcmp))
+                eq(x < y, Rcmp < 0, Frm("%r < %r %d", x, y, Rcmp))
+                eq(x <= y, Rcmp <= 0, Frm("%r <= %r %d", x, y, Rcmp))
+                eq(x > y, Rcmp > 0, Frm("%r > %r %d", x, y, Rcmp))
+                eq(x >= y, Rcmp >= 0, Frm("%r >= %r %d", x, y, Rcmp))
+
+def test_main():
+    test_support.run_unittest(LongTest)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_long_future.py
===================================================================
--- vendor/Python/current/Lib/test/test_long_future.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_long_future.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,55 @@
+from __future__ import division
+# When true division is the default, get rid of this and add it to
+# test_long.py instead.  In the meantime, it's too obscure to try to
+# trick just part of test_long into using future division.
+
+from test.test_support import TestFailed, verify, verbose
+
+def test_true_division():
+    if verbose:
+        print "long true division"
+    huge = 1L << 40000
+    mhuge = -huge
+    verify(huge / huge == 1.0)
+    verify(mhuge / mhuge == 1.0)
+    verify(huge / mhuge == -1.0)
+    verify(mhuge / huge == -1.0)
+    verify(1 / huge == 0.0)
+    verify(1L / huge == 0.0)
+    verify(1 / mhuge == 0.0)
+    verify(1L / mhuge == 0.0)
+    verify((666 * huge + (huge >> 1)) / huge == 666.5)
+    verify((666 * mhuge + (mhuge >> 1)) / mhuge == 666.5)
+    verify((666 * huge + (huge >> 1)) / mhuge == -666.5)
+    verify((666 * mhuge + (mhuge >> 1)) / huge == -666.5)
+    verify(huge / (huge << 1) == 0.5)
+    verify((1000000 * huge) / huge == 1000000)
+
+    namespace = {'huge': huge, 'mhuge': mhuge}
+
+    for overflow in ["float(huge)", "float(mhuge)",
+                     "huge / 1", "huge / 2L", "huge / -1", "huge / -2L",
+                     "mhuge / 100", "mhuge / 100L"]:
+        try:
+            eval(overflow, namespace)
+        except OverflowError:
+            pass
+        else:
+            raise TestFailed("expected OverflowError from %r" % overflow)
+
+    for underflow in ["1 / huge", "2L / huge", "-1 / huge", "-2L / huge",
+                     "100 / mhuge", "100L / mhuge"]:
+        result = eval(underflow, namespace)
+        if result != 0.0:
+            raise TestFailed("expected underflow to 0 from %r" % underflow)
+
+    for zero in ["huge / 0", "huge / 0L",
+                 "mhuge / 0", "mhuge / 0L"]:
+        try:
+            eval(zero, namespace)
+        except ZeroDivisionError:
+            pass
+        else:
+            raise TestFailed("expected ZeroDivisionError from %r" % zero)
+
+test_true_division()

Added: vendor/Python/current/Lib/test/test_longexp.py
===================================================================
--- vendor/Python/current/Lib/test/test_longexp.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_longexp.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,14 @@
+import unittest
+from test import test_support
+
+class LongExpText(unittest.TestCase):
+    def test_longexp(self):
+        REPS = 65580
+        l = eval("[" + "2," * REPS + "]")
+        self.assertEqual(len(l), REPS)
+
+def test_main():
+    test_support.run_unittest(LongExpText)
+
+if __name__=="__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_macfs.py
===================================================================
--- vendor/Python/current/Lib/test/test_macfs.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_macfs.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,78 @@
+# Copyright (C) 2003 Python Software Foundation
+
+import unittest
+import warnings
+warnings.filterwarnings("ignore", "macfs.*", DeprecationWarning, __name__)
+import macfs
+import os
+import sys
+import tempfile
+from test import test_support
+
+class TestMacfs(unittest.TestCase):
+
+    def setUp(self):
+        fp = open(test_support.TESTFN, 'w')
+        fp.write('hello world\n')
+        fp.close()
+
+    def tearDown(self):
+        try:
+            os.unlink(test_support.TESTFN)
+        except:
+            pass
+
+    def test_fsspec(self):
+        fss = macfs.FSSpec(test_support.TESTFN)
+        self.assertEqual(os.path.realpath(test_support.TESTFN), fss.as_pathname())
+
+    def test_fsref(self):
+        fsr = macfs.FSRef(test_support.TESTFN)
+        self.assertEqual(os.path.realpath(test_support.TESTFN), fsr.as_pathname())
+
+    def test_fsref_unicode(self):
+        if sys.getfilesystemencoding():
+            testfn_unicode = unicode(test_support.TESTFN)
+            fsr = macfs.FSRef(testfn_unicode)
+            self.assertEqual(os.path.realpath(test_support.TESTFN), fsr.as_pathname())
+
+    def test_coercion(self):
+        fss = macfs.FSSpec(test_support.TESTFN)
+        fsr = macfs.FSRef(test_support.TESTFN)
+        fss2 = fsr.as_fsspec()
+        fsr2 = fss.as_fsref()
+        self.assertEqual(fss.as_pathname(), fss2.as_pathname())
+        self.assertEqual(fsr.as_pathname(), fsr2.as_pathname())
+
+    def test_dates(self):
+        import time
+        fss = macfs.FSSpec(test_support.TESTFN)
+        now = int(time.time())
+        fss.SetDates(now, now+1, now+2)
+        dates = fss.GetDates()
+        self.assertEqual(dates, (now, now+1, now+2))
+
+    def test_ctor_type(self):
+        fss = macfs.FSSpec(test_support.TESTFN)
+        fss.SetCreatorType('Pyth', 'TEXT')
+        filecr, filetp = fss.GetCreatorType()
+        self.assertEqual((filecr, filetp), ('Pyth', 'TEXT'))
+
+    def test_alias(self):
+        fss = macfs.FSSpec(test_support.TESTFN)
+        alias = fss.NewAlias()
+        fss2, changed = alias.Resolve()
+        self.assertEqual(changed, 0)
+        self.assertEqual(fss.as_pathname(), fss2.as_pathname())
+
+
+    def test_fss_alias(self):
+        fss = macfs.FSSpec(test_support.TESTFN)
+
+
+def test_main():
+    test_support.run_unittest(TestMacfs)
+
+
+if __name__ == '__main__':
+    test_main()

Added: vendor/Python/current/Lib/test/test_macostools.py
===================================================================
--- vendor/Python/current/Lib/test/test_macostools.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_macostools.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,94 @@
+# Copyright (C) 2003 Python Software Foundation
+
+import unittest
+import macostools
+import Carbon.File
+import MacOS
+import os
+import sys
+from test import test_support
+
+TESTFN2 = test_support.TESTFN + '2'
+
+class TestMacostools(unittest.TestCase):
+
+    def setUp(self):
+        fp = open(test_support.TESTFN, 'w')
+        fp.write('hello world\n')
+        fp.close()
+        rfp = MacOS.openrf(test_support.TESTFN, '*wb')
+        rfp.write('goodbye world\n')
+        rfp.close()
+
+    def tearDown(self):
+        try:
+            os.unlink(test_support.TESTFN)
+        except:
+            pass
+        try:
+            os.unlink(TESTFN2)
+        except:
+            pass
+
+    def compareData(self):
+        fp = open(test_support.TESTFN, 'r')
+        data1 = fp.read()
+        fp.close()
+        fp = open(TESTFN2, 'r')
+        data2 = fp.read()
+        fp.close()
+        if data1 != data2:
+            return 'Data forks differ'
+        rfp = MacOS.openrf(test_support.TESTFN, '*rb')
+        data1 = rfp.read(1000)
+        rfp.close()
+        rfp = MacOS.openrf(TESTFN2, '*rb')
+        data2 = rfp.read(1000)
+        rfp.close()
+        if data1 != data2:
+            return 'Resource forks differ'
+        return ''
+
+    def test_touched(self):
+        # This really only tests that nothing unforeseen happens.
+        macostools.touched(test_support.TESTFN)
+
+    def test_copy(self):
+        try:
+            os.unlink(TESTFN2)
+        except:
+            pass
+        macostools.copy(test_support.TESTFN, TESTFN2)
+        self.assertEqual(self.compareData(), '')
+
+    def test_mkalias(self):
+        try:
+            os.unlink(TESTFN2)
+        except:
+            pass
+        macostools.mkalias(test_support.TESTFN, TESTFN2)
+        fss, _, _ = Carbon.File.ResolveAliasFile(TESTFN2, 0)
+        self.assertEqual(fss.as_pathname(), os.path.realpath(test_support.TESTFN))
+
+    def test_mkalias_relative(self):
+        try:
+            os.unlink(TESTFN2)
+        except:
+            pass
+        # If the directory doesn't exist, then chances are this is a new
+        # install of Python so don't create it since the user might end up
+        # running ``sudo make install`` and creating the directory here won't
+        # leave it with the proper permissions.
+        if not os.path.exists(sys.prefix):
+            return
+        macostools.mkalias(test_support.TESTFN, TESTFN2, sys.prefix)
+        fss, _, _ = Carbon.File.ResolveAliasFile(TESTFN2, 0)
+        self.assertEqual(fss.as_pathname(), os.path.realpath(test_support.TESTFN))
+
+
+def test_main():
+    test_support.run_unittest(TestMacostools)
+
+
+if __name__ == '__main__':
+    test_main()

Added: vendor/Python/current/Lib/test/test_macpath.py
===================================================================
--- vendor/Python/current/Lib/test/test_macpath.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_macpath.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,63 @@
+import macpath
+from test import test_support
+import unittest
+
+
+class MacPathTestCase(unittest.TestCase):
+
+    def test_abspath(self):
+        self.assert_(macpath.abspath("xx:yy") == "xx:yy")
+
+    def test_isabs(self):
+        isabs = macpath.isabs
+        self.assert_(isabs("xx:yy"))
+        self.assert_(isabs("xx:yy:"))
+        self.assert_(isabs("xx:"))
+        self.failIf(isabs("foo"))
+        self.failIf(isabs(":foo"))
+        self.failIf(isabs(":foo:bar"))
+        self.failIf(isabs(":foo:bar:"))
+
+
+    def test_commonprefix(self):
+        commonprefix = macpath.commonprefix
+        self.assert_(commonprefix(["home:swenson:spam", "home:swen:spam"])
+                     == "home:swen")
+        self.assert_(commonprefix([":home:swen:spam", ":home:swen:eggs"])
+                     == ":home:swen:")
+        self.assert_(commonprefix([":home:swen:spam", ":home:swen:spam"])
+                     == ":home:swen:spam")
+
+    def test_split(self):
+        split = macpath.split
+        self.assertEquals(split("foo:bar"),
+                          ('foo:', 'bar'))
+        self.assertEquals(split("conky:mountpoint:foo:bar"),
+                          ('conky:mountpoint:foo', 'bar'))
+
+        self.assertEquals(split(":"), ('', ''))
+        self.assertEquals(split(":conky:mountpoint:"),
+                          (':conky:mountpoint', ''))
+
+    def test_splitdrive(self):
+        splitdrive = macpath.splitdrive
+        self.assertEquals(splitdrive("foo:bar"), ('', 'foo:bar'))
+        self.assertEquals(splitdrive(":foo:bar"), ('', ':foo:bar'))
+
+    def test_splitext(self):
+        splitext = macpath.splitext
+        self.assertEquals(splitext(":foo.ext"), (':foo', '.ext'))
+        self.assertEquals(splitext("foo:foo.ext"), ('foo:foo', '.ext'))
+        self.assertEquals(splitext(".ext"), ('', '.ext'))
+        self.assertEquals(splitext("foo.ext:foo"), ('foo.ext:foo', ''))
+        self.assertEquals(splitext(":foo.ext:"), (':foo.ext:', ''))
+        self.assertEquals(splitext(""), ('', ''))
+        self.assertEquals(splitext("foo.bar.ext"), ('foo.bar', '.ext'))
+
+
+def test_main():
+    test_support.run_unittest(MacPathTestCase)
+
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_mailbox.py
===================================================================
--- vendor/Python/current/Lib/test/test_mailbox.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_mailbox.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1848 @@
+import os
+import sys
+import time
+import stat
+import socket
+import email
+import email.Message
+import rfc822
+import re
+import StringIO
+from test import test_support
+import unittest
+import mailbox
+import glob
+try:
+    import fcntl
+except ImportError:
+    pass
+
+
+class TestBase(unittest.TestCase):
+
+    def _check_sample(self, msg):
+        # Inspect a mailbox.Message representation of the sample message
+        self.assert_(isinstance(msg, email.Message.Message))
+        self.assert_(isinstance(msg, mailbox.Message))
+        for key, value in _sample_headers.iteritems():
+            self.assert_(value in msg.get_all(key))
+        self.assert_(msg.is_multipart())
+        self.assert_(len(msg.get_payload()) == len(_sample_payloads))
+        for i, payload in enumerate(_sample_payloads):
+            part = msg.get_payload(i)
+            self.assert_(isinstance(part, email.Message.Message))
+            self.assert_(not isinstance(part, mailbox.Message))
+            self.assert_(part.get_payload() == payload)
+
+    def _delete_recursively(self, target):
+        # Delete a file or delete a directory recursively
+        if os.path.isdir(target):
+            for path, dirs, files in os.walk(target, topdown=False):
+                for name in files:
+                    os.remove(os.path.join(path, name))
+                for name in dirs:
+                    os.rmdir(os.path.join(path, name))
+            os.rmdir(target)
+        elif os.path.exists(target):
+            os.remove(target)
+
+
+class TestMailbox(TestBase):
+
+    _factory = None     # Overridden by subclasses to reuse tests
+    _template = 'From: foo\n\n%s'
+
+    def setUp(self):
+        self._path = test_support.TESTFN
+        self._box = self._factory(self._path)
+
+    def tearDown(self):
+        self._box.close()
+        self._delete_recursively(self._path)
+
+    def test_add(self):
+        # Add copies of a sample message
+        keys = []
+        keys.append(self._box.add(self._template % 0))
+        self.assert_(len(self._box) == 1)
+        keys.append(self._box.add(mailbox.Message(_sample_message)))
+        self.assert_(len(self._box) == 2)
+        keys.append(self._box.add(email.message_from_string(_sample_message)))
+        self.assert_(len(self._box) == 3)
+        keys.append(self._box.add(StringIO.StringIO(_sample_message)))
+        self.assert_(len(self._box) == 4)
+        keys.append(self._box.add(_sample_message))
+        self.assert_(len(self._box) == 5)
+        self.assert_(self._box.get_string(keys[0]) == self._template % 0)
+        for i in (1, 2, 3, 4):
+            self._check_sample(self._box[keys[i]])
+
+    def test_remove(self):
+        # Remove messages using remove()
+        self._test_remove_or_delitem(self._box.remove)
+
+    def test_delitem(self):
+        # Remove messages using __delitem__()
+        self._test_remove_or_delitem(self._box.__delitem__)
+
+    def _test_remove_or_delitem(self, method):
+        # (Used by test_remove() and test_delitem().)
+        key0 = self._box.add(self._template % 0)
+        key1 = self._box.add(self._template % 1)
+        self.assert_(len(self._box) == 2)
+        method(key0)
+        l = len(self._box)
+        self.assert_(l == 1, "actual l: %s" % l)
+        self.assertRaises(KeyError, lambda: self._box[key0])
+        self.assertRaises(KeyError, lambda: method(key0))
+        self.assert_(self._box.get_string(key1) == self._template % 1)
+        key2 = self._box.add(self._template % 2)
+        self.assert_(len(self._box) == 2)
+        method(key2)
+        l = len(self._box)
+        self.assert_(l == 1, "actual l: %s" % l)
+        self.assertRaises(KeyError, lambda: self._box[key2])
+        self.assertRaises(KeyError, lambda: method(key2))
+        self.assert_(self._box.get_string(key1) == self._template % 1)
+        method(key1)
+        self.assert_(len(self._box) == 0)
+        self.assertRaises(KeyError, lambda: self._box[key1])
+        self.assertRaises(KeyError, lambda: method(key1))
+
+    def test_discard(self, repetitions=10):
+        # Discard messages
+        key0 = self._box.add(self._template % 0)
+        key1 = self._box.add(self._template % 1)
+        self.assert_(len(self._box) == 2)
+        self._box.discard(key0)
+        self.assert_(len(self._box) == 1)
+        self.assertRaises(KeyError, lambda: self._box[key0])
+        self._box.discard(key0)
+        self.assert_(len(self._box) == 1)
+        self.assertRaises(KeyError, lambda: self._box[key0])
+
+    def test_get(self):
+        # Retrieve messages using get()
+        key0 = self._box.add(self._template % 0)
+        msg = self._box.get(key0)
+        self.assert_(msg['from'] == 'foo')
+        self.assert_(msg.get_payload() == '0')
+        self.assert_(self._box.get('foo') is None)
+        self.assert_(self._box.get('foo', False) is False)
+        self._box.close()
+        self._box = self._factory(self._path, factory=rfc822.Message)
+        key1 = self._box.add(self._template % 1)
+        msg = self._box.get(key1)
+        self.assert_(msg['from'] == 'foo')
+        self.assert_(msg.fp.read() == '1')
+
+    def test_getitem(self):
+        # Retrieve message using __getitem__()
+        key0 = self._box.add(self._template % 0)
+        msg = self._box[key0]
+        self.assert_(msg['from'] == 'foo')
+        self.assert_(msg.get_payload() == '0')
+        self.assertRaises(KeyError, lambda: self._box['foo'])
+        self._box.discard(key0)
+        self.assertRaises(KeyError, lambda: self._box[key0])
+
+    def test_get_message(self):
+        # Get Message representations of messages
+        key0 = self._box.add(self._template % 0)
+        key1 = self._box.add(_sample_message)
+        msg0 = self._box.get_message(key0)
+        self.assert_(isinstance(msg0, mailbox.Message))
+        self.assert_(msg0['from'] == 'foo')
+        self.assert_(msg0.get_payload() == '0')
+        self._check_sample(self._box.get_message(key1))
+
+    def test_get_string(self):
+        # Get string representations of messages
+        key0 = self._box.add(self._template % 0)
+        key1 = self._box.add(_sample_message)
+        self.assert_(self._box.get_string(key0) == self._template % 0)
+        self.assert_(self._box.get_string(key1) == _sample_message)
+
+    def test_get_file(self):
+        # Get file representations of messages
+        key0 = self._box.add(self._template % 0)
+        key1 = self._box.add(_sample_message)
+        self.assert_(self._box.get_file(key0).read().replace(os.linesep, '\n')
+                     == self._template % 0)
+        self.assert_(self._box.get_file(key1).read().replace(os.linesep, '\n')
+                     == _sample_message)
+
+    def test_iterkeys(self):
+        # Get keys using iterkeys()
+        self._check_iteration(self._box.iterkeys, do_keys=True, do_values=False)
+
+    def test_keys(self):
+        # Get keys using keys()
+        self._check_iteration(self._box.keys, do_keys=True, do_values=False)
+
+    def test_itervalues(self):
+        # Get values using itervalues()
+        self._check_iteration(self._box.itervalues, do_keys=False,
+                              do_values=True)
+
+    def test_iter(self):
+        # Get values using __iter__()
+        self._check_iteration(self._box.__iter__, do_keys=False,
+                              do_values=True)
+
+    def test_values(self):
+        # Get values using values()
+        self._check_iteration(self._box.values, do_keys=False, do_values=True)
+
+    def test_iteritems(self):
+        # Get keys and values using iteritems()
+        self._check_iteration(self._box.iteritems, do_keys=True,
+                              do_values=True)
+
+    def test_items(self):
+        # Get keys and values using items()
+        self._check_iteration(self._box.items, do_keys=True, do_values=True)
+
+    def _check_iteration(self, method, do_keys, do_values, repetitions=10):
+        for value in method():
+            self.fail("Not empty")
+        keys, values = [], []
+        for i in xrange(repetitions):
+            keys.append(self._box.add(self._template % i))
+            values.append(self._template % i)
+        if do_keys and not do_values:
+            returned_keys = list(method())
+        elif do_values and not do_keys:
+            returned_values = list(method())
+        else:
+            returned_keys, returned_values = [], []
+            for key, value in method():
+                returned_keys.append(key)
+                returned_values.append(value)
+        if do_keys:
+            self.assert_(len(keys) == len(returned_keys))
+            self.assert_(set(keys) == set(returned_keys))
+        if do_values:
+            count = 0
+            for value in returned_values:
+                self.assert_(value['from'] == 'foo')
+                self.assert_(int(value.get_payload()) < repetitions)
+                count += 1
+            self.assert_(len(values) == count)
+
+    def test_has_key(self):
+        # Check existence of keys using has_key()
+        self._test_has_key_or_contains(self._box.has_key)
+
+    def test_contains(self):
+        # Check existence of keys using __contains__()
+        self._test_has_key_or_contains(self._box.__contains__)
+
+    def _test_has_key_or_contains(self, method):
+        # (Used by test_has_key() and test_contains().)
+        self.assert_(not method('foo'))
+        key0 = self._box.add(self._template % 0)
+        self.assert_(method(key0))
+        self.assert_(not method('foo'))
+        key1 = self._box.add(self._template % 1)
+        self.assert_(method(key1))
+        self.assert_(method(key0))
+        self.assert_(not method('foo'))
+        self._box.remove(key0)
+        self.assert_(not method(key0))
+        self.assert_(method(key1))
+        self.assert_(not method('foo'))
+        self._box.remove(key1)
+        self.assert_(not method(key1))
+        self.assert_(not method(key0))
+        self.assert_(not method('foo'))
+
+    def test_len(self, repetitions=10):
+        # Get message count
+        keys = []
+        for i in xrange(repetitions):
+            self.assert_(len(self._box) == i)
+            keys.append(self._box.add(self._template % i))
+            self.assert_(len(self._box) == i + 1)
+        for i in xrange(repetitions):
+            self.assert_(len(self._box) == repetitions - i)
+            self._box.remove(keys[i])
+            self.assert_(len(self._box) == repetitions - i - 1)
+
+    def test_set_item(self):
+        # Modify messages using __setitem__()
+        key0 = self._box.add(self._template % 'original 0')
+        self.assert_(self._box.get_string(key0) == \
+                     self._template % 'original 0')
+        key1 = self._box.add(self._template % 'original 1')
+        self.assert_(self._box.get_string(key1) == \
+                     self._template % 'original 1')
+        self._box[key0] = self._template % 'changed 0'
+        self.assert_(self._box.get_string(key0) == \
+                     self._template % 'changed 0')
+        self._box[key1] = self._template % 'changed 1'
+        self.assert_(self._box.get_string(key1) == \
+                     self._template % 'changed 1')
+        self._box[key0] = _sample_message
+        self._check_sample(self._box[key0])
+        self._box[key1] = self._box[key0]
+        self._check_sample(self._box[key1])
+        self._box[key0] = self._template % 'original 0'
+        self.assert_(self._box.get_string(key0) ==
+                     self._template % 'original 0')
+        self._check_sample(self._box[key1])
+        self.assertRaises(KeyError,
+                          lambda: self._box.__setitem__('foo', 'bar'))
+        self.assertRaises(KeyError, lambda: self._box['foo'])
+        self.assert_(len(self._box) == 2)
+
+    def test_clear(self, iterations=10):
+        # Remove all messages using clear()
+        keys = []
+        for i in xrange(iterations):
+            self._box.add(self._template % i)
+        for i, key in enumerate(keys):
+            self.assert_(self._box.get_string(key) == self._template % i)
+        self._box.clear()
+        self.assert_(len(self._box) == 0)
+        for i, key in enumerate(keys):
+            self.assertRaises(KeyError, lambda: self._box.get_string(key))
+
+    def test_pop(self):
+        # Get and remove a message using pop()
+        key0 = self._box.add(self._template % 0)
+        self.assert_(key0 in self._box)
+        key1 = self._box.add(self._template % 1)
+        self.assert_(key1 in self._box)
+        self.assert_(self._box.pop(key0).get_payload() == '0')
+        self.assert_(key0 not in self._box)
+        self.assert_(key1 in self._box)
+        key2 = self._box.add(self._template % 2)
+        self.assert_(key2 in self._box)
+        self.assert_(self._box.pop(key2).get_payload() == '2')
+        self.assert_(key2 not in self._box)
+        self.assert_(key1 in self._box)
+        self.assert_(self._box.pop(key1).get_payload() == '1')
+        self.assert_(key1 not in self._box)
+        self.assert_(len(self._box) == 0)
+
+    def test_popitem(self, iterations=10):
+        # Get and remove an arbitrary (key, message) using popitem()
+        keys = []
+        for i in xrange(10):
+            keys.append(self._box.add(self._template % i))
+        seen = []
+        for i in xrange(10):
+            key, msg = self._box.popitem()
+            self.assert_(key in keys)
+            self.assert_(key not in seen)
+            seen.append(key)
+            self.assert_(int(msg.get_payload()) == keys.index(key))
+        self.assert_(len(self._box) == 0)
+        for key in keys:
+            self.assertRaises(KeyError, lambda: self._box[key])
+
+    def test_update(self):
+        # Modify multiple messages using update()
+        key0 = self._box.add(self._template % 'original 0')
+        key1 = self._box.add(self._template % 'original 1')
+        key2 = self._box.add(self._template % 'original 2')
+        self._box.update({key0: self._template % 'changed 0',
+                          key2: _sample_message})
+        self.assert_(len(self._box) == 3)
+        self.assert_(self._box.get_string(key0) ==
+                     self._template % 'changed 0')
+        self.assert_(self._box.get_string(key1) ==
+                     self._template % 'original 1')
+        self._check_sample(self._box[key2])
+        self._box.update([(key2, self._template % 'changed 2'),
+                    (key1, self._template % 'changed 1'),
+                    (key0, self._template % 'original 0')])
+        self.assert_(len(self._box) == 3)
+        self.assert_(self._box.get_string(key0) ==
+                     self._template % 'original 0')
+        self.assert_(self._box.get_string(key1) ==
+                     self._template % 'changed 1')
+        self.assert_(self._box.get_string(key2) ==
+                     self._template % 'changed 2')
+        self.assertRaises(KeyError,
+                          lambda: self._box.update({'foo': 'bar',
+                                          key0: self._template % "changed 0"}))
+        self.assert_(len(self._box) == 3)
+        self.assert_(self._box.get_string(key0) ==
+                     self._template % "changed 0")
+        self.assert_(self._box.get_string(key1) ==
+                     self._template % "changed 1")
+        self.assert_(self._box.get_string(key2) ==
+                     self._template % "changed 2")
+
+    def test_flush(self):
+        # Write changes to disk
+        self._test_flush_or_close(self._box.flush)
+
+    def test_lock_unlock(self):
+        # Lock and unlock the mailbox
+        self.assert_(not os.path.exists(self._get_lock_path()))
+        self._box.lock()
+        self.assert_(os.path.exists(self._get_lock_path()))
+        self._box.unlock()
+        self.assert_(not os.path.exists(self._get_lock_path()))
+
+    def test_close(self):
+        # Close mailbox and flush changes to disk
+        self._test_flush_or_close(self._box.close)
+
+    def _test_flush_or_close(self, method):
+        contents = [self._template % i for i in xrange(3)]
+        self._box.add(contents[0])
+        self._box.add(contents[1])
+        self._box.add(contents[2])
+        method()
+        self._box = self._factory(self._path)
+        keys = self._box.keys()
+        self.assert_(len(keys) == 3)
+        for key in keys:
+            self.assert_(self._box.get_string(key) in contents)
+
+    def test_dump_message(self):
+        # Write message representations to disk
+        for input in (email.message_from_string(_sample_message),
+                      _sample_message, StringIO.StringIO(_sample_message)):
+            output = StringIO.StringIO()
+            self._box._dump_message(input, output)
+            self.assert_(output.getvalue() ==
+                         _sample_message.replace('\n', os.linesep))
+        output = StringIO.StringIO()
+        self.assertRaises(TypeError,
+                          lambda: self._box._dump_message(None, output))
+
+    def _get_lock_path(self):
+        # Return the path of the dot lock file. May be overridden.
+        return self._path + '.lock'
+
+
+class TestMailboxSuperclass(TestBase):
+
+    def test_notimplemented(self):
+        # Test that all Mailbox methods raise NotImplementedException.
+        box = mailbox.Mailbox('path')
+        self.assertRaises(NotImplementedError, lambda: box.add(''))
+        self.assertRaises(NotImplementedError, lambda: box.remove(''))
+        self.assertRaises(NotImplementedError, lambda: box.__delitem__(''))
+        self.assertRaises(NotImplementedError, lambda: box.discard(''))
+        self.assertRaises(NotImplementedError, lambda: box.__setitem__('', ''))
+        self.assertRaises(NotImplementedError, lambda: box.iterkeys())
+        self.assertRaises(NotImplementedError, lambda: box.keys())
+        self.assertRaises(NotImplementedError, lambda: box.itervalues().next())
+        self.assertRaises(NotImplementedError, lambda: box.__iter__().next())
+        self.assertRaises(NotImplementedError, lambda: box.values())
+        self.assertRaises(NotImplementedError, lambda: box.iteritems().next())
+        self.assertRaises(NotImplementedError, lambda: box.items())
+        self.assertRaises(NotImplementedError, lambda: box.get(''))
+        self.assertRaises(NotImplementedError, lambda: box.__getitem__(''))
+        self.assertRaises(NotImplementedError, lambda: box.get_message(''))
+        self.assertRaises(NotImplementedError, lambda: box.get_string(''))
+        self.assertRaises(NotImplementedError, lambda: box.get_file(''))
+        self.assertRaises(NotImplementedError, lambda: box.has_key(''))
+        self.assertRaises(NotImplementedError, lambda: box.__contains__(''))
+        self.assertRaises(NotImplementedError, lambda: box.__len__())
+        self.assertRaises(NotImplementedError, lambda: box.clear())
+        self.assertRaises(NotImplementedError, lambda: box.pop(''))
+        self.assertRaises(NotImplementedError, lambda: box.popitem())
+        self.assertRaises(NotImplementedError, lambda: box.update((('', ''),)))
+        self.assertRaises(NotImplementedError, lambda: box.flush())
+        self.assertRaises(NotImplementedError, lambda: box.lock())
+        self.assertRaises(NotImplementedError, lambda: box.unlock())
+        self.assertRaises(NotImplementedError, lambda: box.close())
+
+
+class TestMaildir(TestMailbox):
+
+    _factory = lambda self, path, factory=None: mailbox.Maildir(path, factory)
+
+    def setUp(self):
+        TestMailbox.setUp(self)
+        if os.name in ('nt', 'os2') or sys.platform == 'cygwin':
+            self._box.colon = '!'
+
+    def test_add_MM(self):
+        # Add a MaildirMessage instance
+        msg = mailbox.MaildirMessage(self._template % 0)
+        msg.set_subdir('cur')
+        msg.set_info('foo')
+        key = self._box.add(msg)
+        self.assert_(os.path.exists(os.path.join(self._path, 'cur', '%s%sfoo' %
+                                                 (key, self._box.colon))))
+
+    def test_get_MM(self):
+        # Get a MaildirMessage instance
+        msg = mailbox.MaildirMessage(self._template % 0)
+        msg.set_subdir('cur')
+        msg.set_flags('RF')
+        key = self._box.add(msg)
+        msg_returned = self._box.get_message(key)
+        self.assert_(isinstance(msg_returned, mailbox.MaildirMessage))
+        self.assert_(msg_returned.get_subdir() == 'cur')
+        self.assert_(msg_returned.get_flags() == 'FR')
+
+    def test_set_MM(self):
+        # Set with a MaildirMessage instance
+        msg0 = mailbox.MaildirMessage(self._template % 0)
+        msg0.set_flags('TP')
+        key = self._box.add(msg0)
+        msg_returned = self._box.get_message(key)
+        self.assert_(msg_returned.get_subdir() == 'new')
+        self.assert_(msg_returned.get_flags() == 'PT')
+        msg1 = mailbox.MaildirMessage(self._template % 1)
+        self._box[key] = msg1
+        msg_returned = self._box.get_message(key)
+        self.assert_(msg_returned.get_subdir() == 'new')
+        self.assert_(msg_returned.get_flags() == '')
+        self.assert_(msg_returned.get_payload() == '1')
+        msg2 = mailbox.MaildirMessage(self._template % 2)
+        msg2.set_info('2,S')
+        self._box[key] = msg2
+        self._box[key] = self._template % 3
+        msg_returned = self._box.get_message(key)
+        self.assert_(msg_returned.get_subdir() == 'new')
+        self.assert_(msg_returned.get_flags() == 'S')
+        self.assert_(msg_returned.get_payload() == '3')
+
+    def test_initialize_new(self):
+        # Initialize a non-existent mailbox
+        self.tearDown()
+        self._box = mailbox.Maildir(self._path)
+        self._check_basics(factory=rfc822.Message)
+        self._delete_recursively(self._path)
+        self._box = self._factory(self._path, factory=None)
+        self._check_basics()
+
+    def test_initialize_existing(self):
+        # Initialize an existing mailbox
+        self.tearDown()
+        for subdir in '', 'tmp', 'new', 'cur':
+            os.mkdir(os.path.normpath(os.path.join(self._path, subdir)))
+        self._box = mailbox.Maildir(self._path)
+        self._check_basics(factory=rfc822.Message)
+        self._box = mailbox.Maildir(self._path, factory=None)
+        self._check_basics()
+
+    def _check_basics(self, factory=None):
+        # (Used by test_open_new() and test_open_existing().)
+        self.assertEqual(self._box._path, os.path.abspath(self._path))
+        self.assertEqual(self._box._factory, factory)
+        for subdir in '', 'tmp', 'new', 'cur':
+            path = os.path.join(self._path, subdir)
+            mode = os.stat(path)[stat.ST_MODE]
+            self.assert_(stat.S_ISDIR(mode), "Not a directory: '%s'" % path)
+
+    def test_list_folders(self):
+        # List folders
+        self._box.add_folder('one')
+        self._box.add_folder('two')
+        self._box.add_folder('three')
+        self.assert_(len(self._box.list_folders()) == 3)
+        self.assert_(set(self._box.list_folders()) ==
+                     set(('one', 'two', 'three')))
+
+    def test_get_folder(self):
+        # Open folders
+        self._box.add_folder('foo.bar')
+        folder0 = self._box.get_folder('foo.bar')
+        folder0.add(self._template % 'bar')
+        self.assert_(os.path.isdir(os.path.join(self._path, '.foo.bar')))
+        folder1 = self._box.get_folder('foo.bar')
+        self.assert_(folder1.get_string(folder1.keys()[0]) == \
+                     self._template % 'bar')
+
+    def test_add_and_remove_folders(self):
+        # Delete folders
+        self._box.add_folder('one')
+        self._box.add_folder('two')
+        self.assert_(len(self._box.list_folders()) == 2)
+        self.assert_(set(self._box.list_folders()) == set(('one', 'two')))
+        self._box.remove_folder('one')
+        self.assert_(len(self._box.list_folders()) == 1)
+        self.assert_(set(self._box.list_folders()) == set(('two',)))
+        self._box.add_folder('three')
+        self.assert_(len(self._box.list_folders()) == 2)
+        self.assert_(set(self._box.list_folders()) == set(('two', 'three')))
+        self._box.remove_folder('three')
+        self.assert_(len(self._box.list_folders()) == 1)
+        self.assert_(set(self._box.list_folders()) == set(('two',)))
+        self._box.remove_folder('two')
+        self.assert_(len(self._box.list_folders()) == 0)
+        self.assert_(self._box.list_folders() == [])
+
+    def test_clean(self):
+        # Remove old files from 'tmp'
+        foo_path = os.path.join(self._path, 'tmp', 'foo')
+        bar_path = os.path.join(self._path, 'tmp', 'bar')
+        f = open(foo_path, 'w')
+        f.write("@")
+        f.close()
+        f = open(bar_path, 'w')
+        f.write("@")
+        f.close()
+        self._box.clean()
+        self.assert_(os.path.exists(foo_path))
+        self.assert_(os.path.exists(bar_path))
+        foo_stat = os.stat(foo_path)
+        os.utime(foo_path, (time.time() - 129600 - 2,
+                            foo_stat.st_mtime))
+        self._box.clean()
+        self.assert_(not os.path.exists(foo_path))
+        self.assert_(os.path.exists(bar_path))
+
+    def test_create_tmp(self, repetitions=10):
+        # Create files in tmp directory
+        hostname = socket.gethostname()
+        if '/' in hostname:
+            hostname = hostname.replace('/', r'\057')
+        if ':' in hostname:
+            hostname = hostname.replace(':', r'\072')
+        pid = os.getpid()
+        pattern = re.compile(r"(?P<time>\d+)\.M(?P<M>\d{1,6})P(?P<P>\d+)"
+                             r"Q(?P<Q>\d+)\.(?P<host>[^:/]+)")
+        previous_groups = None
+        for x in xrange(repetitions):
+            tmp_file = self._box._create_tmp()
+            head, tail = os.path.split(tmp_file.name)
+            self.assertEqual(head, os.path.abspath(os.path.join(self._path,
+                                                                "tmp")),
+                             "File in wrong location: '%s'" % head)
+            match = pattern.match(tail)
+            self.assert_(match != None, "Invalid file name: '%s'" % tail)
+            groups = match.groups()
+            if previous_groups != None:
+                self.assert_(int(groups[0] >= previous_groups[0]),
+                             "Non-monotonic seconds: '%s' before '%s'" %
+                             (previous_groups[0], groups[0]))
+                self.assert_(int(groups[1] >= previous_groups[1]) or
+                             groups[0] != groups[1],
+                             "Non-monotonic milliseconds: '%s' before '%s'" %
+                             (previous_groups[1], groups[1]))
+                self.assert_(int(groups[2]) == pid,
+                             "Process ID mismatch: '%s' should be '%s'" %
+                             (groups[2], pid))
+                self.assert_(int(groups[3]) == int(previous_groups[3]) + 1,
+                             "Non-sequential counter: '%s' before '%s'" %
+                             (previous_groups[3], groups[3]))
+                self.assert_(groups[4] == hostname,
+                             "Host name mismatch: '%s' should be '%s'" %
+                             (groups[4], hostname))
+            previous_groups = groups
+            tmp_file.write(_sample_message)
+            tmp_file.seek(0)
+            self.assert_(tmp_file.read() == _sample_message)
+            tmp_file.close()
+        file_count = len(os.listdir(os.path.join(self._path, "tmp")))
+        self.assert_(file_count == repetitions,
+                     "Wrong file count: '%s' should be '%s'" %
+                     (file_count, repetitions))
+
+    def test_refresh(self):
+        # Update the table of contents
+        self.assert_(self._box._toc == {})
+        key0 = self._box.add(self._template % 0)
+        key1 = self._box.add(self._template % 1)
+        self.assert_(self._box._toc == {})
+        self._box._refresh()
+        self.assert_(self._box._toc == {key0: os.path.join('new', key0),
+                                        key1: os.path.join('new', key1)})
+        key2 = self._box.add(self._template % 2)
+        self.assert_(self._box._toc == {key0: os.path.join('new', key0),
+                                        key1: os.path.join('new', key1)})
+        self._box._refresh()
+        self.assert_(self._box._toc == {key0: os.path.join('new', key0),
+                                        key1: os.path.join('new', key1),
+                                        key2: os.path.join('new', key2)})
+
+    def test_lookup(self):
+        # Look up message subpaths in the TOC
+        self.assertRaises(KeyError, lambda: self._box._lookup('foo'))
+        key0 = self._box.add(self._template % 0)
+        self.assert_(self._box._lookup(key0) == os.path.join('new', key0))
+        os.remove(os.path.join(self._path, 'new', key0))
+        self.assert_(self._box._toc == {key0: os.path.join('new', key0)})
+        self.assertRaises(KeyError, lambda: self._box._lookup(key0))
+        self.assert_(self._box._toc == {})
+
+    def test_lock_unlock(self):
+        # Lock and unlock the mailbox. For Maildir, this does nothing.
+        self._box.lock()
+        self._box.unlock()
+
+    def test_folder (self):
+        # Test for bug #1569790: verify that folders returned by .get_folder()
+        # use the same factory function.
+        def dummy_factory (s):
+            return None
+        box = self._factory(self._path, factory=dummy_factory)
+        folder = box.add_folder('folder1')
+        self.assert_(folder._factory is dummy_factory)
+        
+        folder1_alias = box.get_folder('folder1')
+        self.assert_(folder1_alias._factory is dummy_factory)
+
+        
+
+class _TestMboxMMDF(TestMailbox):
+
+    def tearDown(self):
+        self._box.close()
+        self._delete_recursively(self._path)
+        for lock_remnant in glob.glob(self._path + '.*'):
+            os.remove(lock_remnant)
+
+    def test_add_from_string(self):
+        # Add a string starting with 'From ' to the mailbox
+        key = self._box.add('From foo at bar blah\nFrom: foo\n\n0')
+        self.assert_(self._box[key].get_from() == 'foo at bar blah')
+        self.assert_(self._box[key].get_payload() == '0')
+
+    def test_add_mbox_or_mmdf_message(self):
+        # Add an mboxMessage or MMDFMessage
+        for class_ in (mailbox.mboxMessage, mailbox.MMDFMessage):
+            msg = class_('From foo at bar blah\nFrom: foo\n\n0')
+            key = self._box.add(msg)
+
+    def test_open_close_open(self):
+        # Open and inspect previously-created mailbox
+        values = [self._template % i for i in xrange(3)]
+        for value in values:
+            self._box.add(value)
+        self._box.close()
+        mtime = os.path.getmtime(self._path)
+        self._box = self._factory(self._path)
+        self.assert_(len(self._box) == 3)
+        for key in self._box.iterkeys():
+            self.assert_(self._box.get_string(key) in values)
+        self._box.close()
+        self.assert_(mtime == os.path.getmtime(self._path))
+
+    def test_add_and_close(self):
+        # Verifying that closing a mailbox doesn't change added items
+        self._box.add(_sample_message)
+        for i in xrange(3):
+            self._box.add(self._template % i)
+        self._box.add(_sample_message)
+        self._box._file.flush()
+        self._box._file.seek(0)
+        contents = self._box._file.read()
+        self._box.close()
+        self.assert_(contents == open(self._path, 'rb').read())
+        self._box = self._factory(self._path)
+
+    def test_lock_conflict(self):
+        # Fork off a subprocess that will lock the file for 2 seconds,
+        # unlock it, and then exit.
+        if not hasattr(os, 'fork'):
+            return
+        pid = os.fork()
+        if pid == 0:
+            # In the child, lock the mailbox.
+            self._box.lock()
+            time.sleep(2)
+            self._box.unlock()
+            os._exit(0)
+
+        # In the parent, sleep a bit to give the child time to acquire
+        # the lock.
+        time.sleep(0.5)
+        try:
+            self.assertRaises(mailbox.ExternalClashError,
+                              self._box.lock)
+        finally:
+            # Wait for child to exit.  Locking should now succeed.
+            exited_pid, status = os.waitpid(pid, 0)
+
+        self._box.lock()
+        self._box.unlock()
+
+    def test_relock(self):
+        # Test case for bug #1575506: the mailbox class was locking the
+        # wrong file object in its flush() method.
+        msg = "Subject: sub\n\nbody\n"
+        key1 = self._box.add(msg)
+        self._box.flush()
+        self._box.close()
+        
+        self._box = self._factory(self._path)
+        self._box.lock()
+        key2 = self._box.add(msg)
+        self._box.flush()
+        self.assert_(self._box._locked)
+        self._box.close()
+        
+        
+
+class TestMbox(_TestMboxMMDF):
+
+    _factory = lambda self, path, factory=None: mailbox.mbox(path, factory)
+
+
+class TestMMDF(_TestMboxMMDF):
+
+    _factory = lambda self, path, factory=None: mailbox.MMDF(path, factory)
+
+
+class TestMH(TestMailbox):
+
+    _factory = lambda self, path, factory=None: mailbox.MH(path, factory)
+
+    def test_list_folders(self):
+        # List folders
+        self._box.add_folder('one')
+        self._box.add_folder('two')
+        self._box.add_folder('three')
+        self.assert_(len(self._box.list_folders()) == 3)
+        self.assert_(set(self._box.list_folders()) ==
+                     set(('one', 'two', 'three')))
+
+    def test_get_folder(self):
+        # Open folders
+        def dummy_factory (s):
+            return None
+        self._box = self._factory(self._path, dummy_factory)
+        
+        new_folder = self._box.add_folder('foo.bar')
+        folder0 = self._box.get_folder('foo.bar')
+        folder0.add(self._template % 'bar')
+        self.assert_(os.path.isdir(os.path.join(self._path, 'foo.bar')))
+        folder1 = self._box.get_folder('foo.bar')
+        self.assert_(folder1.get_string(folder1.keys()[0]) == \
+                     self._template % 'bar')
+
+        # Test for bug #1569790: verify that folders returned by .get_folder()
+        # use the same factory function.
+        self.assert_(new_folder._factory is self._box._factory)
+        self.assert_(folder0._factory is self._box._factory)
+
+    def test_add_and_remove_folders(self):
+        # Delete folders
+        self._box.add_folder('one')
+        self._box.add_folder('two')
+        self.assert_(len(self._box.list_folders()) == 2)
+        self.assert_(set(self._box.list_folders()) == set(('one', 'two')))
+        self._box.remove_folder('one')
+        self.assert_(len(self._box.list_folders()) == 1)
+        self.assert_(set(self._box.list_folders()) == set(('two',)))
+        self._box.add_folder('three')
+        self.assert_(len(self._box.list_folders()) == 2)
+        self.assert_(set(self._box.list_folders()) == set(('two', 'three')))
+        self._box.remove_folder('three')
+        self.assert_(len(self._box.list_folders()) == 1)
+        self.assert_(set(self._box.list_folders()) == set(('two',)))
+        self._box.remove_folder('two')
+        self.assert_(len(self._box.list_folders()) == 0)
+        self.assert_(self._box.list_folders() == [])
+
+    def test_sequences(self):
+        # Get and set sequences
+        self.assert_(self._box.get_sequences() == {})
+        msg0 = mailbox.MHMessage(self._template % 0)
+        msg0.add_sequence('foo')
+        key0 = self._box.add(msg0)
+        self.assert_(self._box.get_sequences() == {'foo':[key0]})
+        msg1 = mailbox.MHMessage(self._template % 1)
+        msg1.set_sequences(['bar', 'replied', 'foo'])
+        key1 = self._box.add(msg1)
+        self.assert_(self._box.get_sequences() ==
+                     {'foo':[key0, key1], 'bar':[key1], 'replied':[key1]})
+        msg0.set_sequences(['flagged'])
+        self._box[key0] = msg0
+        self.assert_(self._box.get_sequences() ==
+                     {'foo':[key1], 'bar':[key1], 'replied':[key1],
+                      'flagged':[key0]})
+        self._box.remove(key1)
+        self.assert_(self._box.get_sequences() == {'flagged':[key0]})
+
+    def test_pack(self):
+        # Pack the contents of the mailbox
+        msg0 = mailbox.MHMessage(self._template % 0)
+        msg1 = mailbox.MHMessage(self._template % 1)
+        msg2 = mailbox.MHMessage(self._template % 2)
+        msg3 = mailbox.MHMessage(self._template % 3)
+        msg0.set_sequences(['foo', 'unseen'])
+        msg1.set_sequences(['foo'])
+        msg2.set_sequences(['foo', 'flagged'])
+        msg3.set_sequences(['foo', 'bar', 'replied'])
+        key0 = self._box.add(msg0)
+        key1 = self._box.add(msg1)
+        key2 = self._box.add(msg2)
+        key3 = self._box.add(msg3)
+        self.assert_(self._box.get_sequences() ==
+                     {'foo':[key0,key1,key2,key3], 'unseen':[key0],
+                      'flagged':[key2], 'bar':[key3], 'replied':[key3]})
+        self._box.remove(key2)
+        self.assert_(self._box.get_sequences() ==
+                     {'foo':[key0,key1,key3], 'unseen':[key0], 'bar':[key3],
+                      'replied':[key3]})
+        self._box.pack()
+        self.assert_(self._box.keys() == [1, 2, 3])
+        key0 = key0
+        key1 = key0 + 1
+        key2 = key1 + 1
+        self.assert_(self._box.get_sequences() ==
+                     {'foo':[1, 2, 3], 'unseen':[1], 'bar':[3], 'replied':[3]})
+
+        # Test case for packing while holding the mailbox locked.
+        key0 = self._box.add(msg1)
+        key1 = self._box.add(msg1)
+        key2 = self._box.add(msg1)
+        key3 = self._box.add(msg1)
+
+        self._box.remove(key0)
+        self._box.remove(key2)
+        self._box.lock()
+        self._box.pack()
+        self._box.unlock()
+        self.assert_(self._box.get_sequences() ==
+                     {'foo':[1, 2, 3, 4, 5],
+                      'unseen':[1], 'bar':[3], 'replied':[3]})
+        
+    def _get_lock_path(self):
+        return os.path.join(self._path, '.mh_sequences.lock')
+
+
+class TestBabyl(TestMailbox):
+
+    _factory = lambda self, path, factory=None: mailbox.Babyl(path, factory)
+
+    def tearDown(self):
+        self._box.close()
+        self._delete_recursively(self._path)
+        for lock_remnant in glob.glob(self._path + '.*'):
+            os.remove(lock_remnant)
+
+    def test_labels(self):
+        # Get labels from the mailbox
+        self.assert_(self._box.get_labels() == [])
+        msg0 = mailbox.BabylMessage(self._template % 0)
+        msg0.add_label('foo')
+        key0 = self._box.add(msg0)
+        self.assert_(self._box.get_labels() == ['foo'])
+        msg1 = mailbox.BabylMessage(self._template % 1)
+        msg1.set_labels(['bar', 'answered', 'foo'])
+        key1 = self._box.add(msg1)
+        self.assert_(set(self._box.get_labels()) == set(['foo', 'bar']))
+        msg0.set_labels(['blah', 'filed'])
+        self._box[key0] = msg0
+        self.assert_(set(self._box.get_labels()) ==
+                     set(['foo', 'bar', 'blah']))
+        self._box.remove(key1)
+        self.assert_(set(self._box.get_labels()) == set(['blah']))
+
+
+class TestMessage(TestBase):
+
+    _factory = mailbox.Message      # Overridden by subclasses to reuse tests
+
+    def setUp(self):
+        self._path = test_support.TESTFN
+
+    def tearDown(self):
+        self._delete_recursively(self._path)
+
+    def test_initialize_with_eMM(self):
+        # Initialize based on email.Message.Message instance
+        eMM = email.message_from_string(_sample_message)
+        msg = self._factory(eMM)
+        self._post_initialize_hook(msg)
+        self._check_sample(msg)
+
+    def test_initialize_with_string(self):
+        # Initialize based on string
+        msg = self._factory(_sample_message)
+        self._post_initialize_hook(msg)
+        self._check_sample(msg)
+
+    def test_initialize_with_file(self):
+        # Initialize based on contents of file
+        f = open(self._path, 'w+')
+        f.write(_sample_message)
+        f.seek(0)
+        msg = self._factory(f)
+        self._post_initialize_hook(msg)
+        self._check_sample(msg)
+        f.close()
+
+    def test_initialize_with_nothing(self):
+        # Initialize without arguments
+        msg = self._factory()
+        self._post_initialize_hook(msg)
+        self.assert_(isinstance(msg, email.Message.Message))
+        self.assert_(isinstance(msg, mailbox.Message))
+        self.assert_(isinstance(msg, self._factory))
+        self.assert_(msg.keys() == [])
+        self.assert_(not msg.is_multipart())
+        self.assert_(msg.get_payload() == None)
+
+    def test_initialize_incorrectly(self):
+        # Initialize with invalid argument
+        self.assertRaises(TypeError, lambda: self._factory(object()))
+
+    def test_become_message(self):
+        # Take on the state of another message
+        eMM = email.message_from_string(_sample_message)
+        msg = self._factory()
+        msg._become_message(eMM)
+        self._check_sample(msg)
+
+    def test_explain_to(self):
+        # Copy self's format-specific data to other message formats.
+        # This test is superficial; better ones are in TestMessageConversion.
+        msg = self._factory()
+        for class_ in (mailbox.Message, mailbox.MaildirMessage,
+                       mailbox.mboxMessage, mailbox.MHMessage,
+                       mailbox.BabylMessage, mailbox.MMDFMessage):
+            other_msg = class_()
+            msg._explain_to(other_msg)
+        other_msg = email.Message.Message()
+        self.assertRaises(TypeError, lambda: msg._explain_to(other_msg))
+
+    def _post_initialize_hook(self, msg):
+        # Overridden by subclasses to check extra things after initialization
+        pass
+
+
+class TestMaildirMessage(TestMessage):
+
+    _factory = mailbox.MaildirMessage
+
+    def _post_initialize_hook(self, msg):
+        self.assert_(msg._subdir == 'new')
+        self.assert_(msg._info == '')
+
+    def test_subdir(self):
+        # Use get_subdir() and set_subdir()
+        msg = mailbox.MaildirMessage(_sample_message)
+        self.assert_(msg.get_subdir() == 'new')
+        msg.set_subdir('cur')
+        self.assert_(msg.get_subdir() == 'cur')
+        msg.set_subdir('new')
+        self.assert_(msg.get_subdir() == 'new')
+        self.assertRaises(ValueError, lambda: msg.set_subdir('tmp'))
+        self.assert_(msg.get_subdir() == 'new')
+        msg.set_subdir('new')
+        self.assert_(msg.get_subdir() == 'new')
+        self._check_sample(msg)
+
+    def test_flags(self):
+        # Use get_flags(), set_flags(), add_flag(), remove_flag()
+        msg = mailbox.MaildirMessage(_sample_message)
+        self.assert_(msg.get_flags() == '')
+        self.assert_(msg.get_subdir() == 'new')
+        msg.set_flags('F')
+        self.assert_(msg.get_subdir() == 'new')
+        self.assert_(msg.get_flags() == 'F')
+        msg.set_flags('SDTP')
+        self.assert_(msg.get_flags() == 'DPST')
+        msg.add_flag('FT')
+        self.assert_(msg.get_flags() == 'DFPST')
+        msg.remove_flag('TDRP')
+        self.assert_(msg.get_flags() == 'FS')
+        self.assert_(msg.get_subdir() == 'new')
+        self._check_sample(msg)
+
+    def test_date(self):
+        # Use get_date() and set_date()
+        msg = mailbox.MaildirMessage(_sample_message)
+        self.assert_(abs(msg.get_date() - time.time()) < 60)
+        msg.set_date(0.0)
+        self.assert_(msg.get_date() == 0.0)
+
+    def test_info(self):
+        # Use get_info() and set_info()
+        msg = mailbox.MaildirMessage(_sample_message)
+        self.assert_(msg.get_info() == '')
+        msg.set_info('1,foo=bar')
+        self.assert_(msg.get_info() == '1,foo=bar')
+        self.assertRaises(TypeError, lambda: msg.set_info(None))
+        self._check_sample(msg)
+
+    def test_info_and_flags(self):
+        # Test interaction of info and flag methods
+        msg = mailbox.MaildirMessage(_sample_message)
+        self.assert_(msg.get_info() == '')
+        msg.set_flags('SF')
+        self.assert_(msg.get_flags() == 'FS')
+        self.assert_(msg.get_info() == '2,FS')
+        msg.set_info('1,')
+        self.assert_(msg.get_flags() == '')
+        self.assert_(msg.get_info() == '1,')
+        msg.remove_flag('RPT')
+        self.assert_(msg.get_flags() == '')
+        self.assert_(msg.get_info() == '1,')
+        msg.add_flag('D')
+        self.assert_(msg.get_flags() == 'D')
+        self.assert_(msg.get_info() == '2,D')
+        self._check_sample(msg)
+
+
+class _TestMboxMMDFMessage(TestMessage):
+
+    _factory = mailbox._mboxMMDFMessage
+
+    def _post_initialize_hook(self, msg):
+        self._check_from(msg)
+
+    def test_initialize_with_unixfrom(self):
+        # Initialize with a message that already has a _unixfrom attribute
+        msg = mailbox.Message(_sample_message)
+        msg.set_unixfrom('From foo at bar blah')
+        msg = mailbox.mboxMessage(msg)
+        self.assert_(msg.get_from() == 'foo at bar blah', msg.get_from())
+
+    def test_from(self):
+        # Get and set "From " line
+        msg = mailbox.mboxMessage(_sample_message)
+        self._check_from(msg)
+        msg.set_from('foo bar')
+        self.assert_(msg.get_from() == 'foo bar')
+        msg.set_from('foo at bar', True)
+        self._check_from(msg, 'foo at bar')
+        msg.set_from('blah at temp', time.localtime())
+        self._check_from(msg, 'blah at temp')
+
+    def test_flags(self):
+        # Use get_flags(), set_flags(), add_flag(), remove_flag()
+        msg = mailbox.mboxMessage(_sample_message)
+        self.assert_(msg.get_flags() == '')
+        msg.set_flags('F')
+        self.assert_(msg.get_flags() == 'F')
+        msg.set_flags('XODR')
+        self.assert_(msg.get_flags() == 'RODX')
+        msg.add_flag('FA')
+        self.assert_(msg.get_flags() == 'RODFAX')
+        msg.remove_flag('FDXA')
+        self.assert_(msg.get_flags() == 'RO')
+        self._check_sample(msg)
+
+    def _check_from(self, msg, sender=None):
+        # Check contents of "From " line
+        if sender is None:
+            sender = "MAILER-DAEMON"
+        self.assert_(re.match(sender + r" \w{3} \w{3} [\d ]\d [\d ]\d:\d{2}:"
+                              r"\d{2} \d{4}", msg.get_from()) is not None)
+
+
+class TestMboxMessage(_TestMboxMMDFMessage):
+
+    _factory = mailbox.mboxMessage
+
+
+class TestMHMessage(TestMessage):
+
+    _factory = mailbox.MHMessage
+
+    def _post_initialize_hook(self, msg):
+        self.assert_(msg._sequences == [])
+
+    def test_sequences(self):
+        # Get, set, join, and leave sequences
+        msg = mailbox.MHMessage(_sample_message)
+        self.assert_(msg.get_sequences() == [])
+        msg.set_sequences(['foobar'])
+        self.assert_(msg.get_sequences() == ['foobar'])
+        msg.set_sequences([])
+        self.assert_(msg.get_sequences() == [])
+        msg.add_sequence('unseen')
+        self.assert_(msg.get_sequences() == ['unseen'])
+        msg.add_sequence('flagged')
+        self.assert_(msg.get_sequences() == ['unseen', 'flagged'])
+        msg.add_sequence('flagged')
+        self.assert_(msg.get_sequences() == ['unseen', 'flagged'])
+        msg.remove_sequence('unseen')
+        self.assert_(msg.get_sequences() == ['flagged'])
+        msg.add_sequence('foobar')
+        self.assert_(msg.get_sequences() == ['flagged', 'foobar'])
+        msg.remove_sequence('replied')
+        self.assert_(msg.get_sequences() == ['flagged', 'foobar'])
+        msg.set_sequences(['foobar', 'replied'])
+        self.assert_(msg.get_sequences() == ['foobar', 'replied'])
+
+
+class TestBabylMessage(TestMessage):
+
+    _factory = mailbox.BabylMessage
+
+    def _post_initialize_hook(self, msg):
+        self.assert_(msg._labels == [])
+
+    def test_labels(self):
+        # Get, set, join, and leave labels
+        msg = mailbox.BabylMessage(_sample_message)
+        self.assert_(msg.get_labels() == [])
+        msg.set_labels(['foobar'])
+        self.assert_(msg.get_labels() == ['foobar'])
+        msg.set_labels([])
+        self.assert_(msg.get_labels() == [])
+        msg.add_label('filed')
+        self.assert_(msg.get_labels() == ['filed'])
+        msg.add_label('resent')
+        self.assert_(msg.get_labels() == ['filed', 'resent'])
+        msg.add_label('resent')
+        self.assert_(msg.get_labels() == ['filed', 'resent'])
+        msg.remove_label('filed')
+        self.assert_(msg.get_labels() == ['resent'])
+        msg.add_label('foobar')
+        self.assert_(msg.get_labels() == ['resent', 'foobar'])
+        msg.remove_label('unseen')
+        self.assert_(msg.get_labels() == ['resent', 'foobar'])
+        msg.set_labels(['foobar', 'answered'])
+        self.assert_(msg.get_labels() == ['foobar', 'answered'])
+
+    def test_visible(self):
+        # Get, set, and update visible headers
+        msg = mailbox.BabylMessage(_sample_message)
+        visible = msg.get_visible()
+        self.assert_(visible.keys() == [])
+        self.assert_(visible.get_payload() is None)
+        visible['User-Agent'] = 'FooBar 1.0'
+        visible['X-Whatever'] = 'Blah'
+        self.assert_(msg.get_visible().keys() == [])
+        msg.set_visible(visible)
+        visible = msg.get_visible()
+        self.assert_(visible.keys() == ['User-Agent', 'X-Whatever'])
+        self.assert_(visible['User-Agent'] == 'FooBar 1.0')
+        self.assert_(visible['X-Whatever'] == 'Blah')
+        self.assert_(visible.get_payload() is None)
+        msg.update_visible()
+        self.assert_(visible.keys() == ['User-Agent', 'X-Whatever'])
+        self.assert_(visible.get_payload() is None)
+        visible = msg.get_visible()
+        self.assert_(visible.keys() == ['User-Agent', 'Date', 'From', 'To',
+                                        'Subject'])
+        for header in ('User-Agent', 'Date', 'From', 'To', 'Subject'):
+            self.assert_(visible[header] == msg[header])
+
+
+class TestMMDFMessage(_TestMboxMMDFMessage):
+
+    _factory = mailbox.MMDFMessage
+
+
+class TestMessageConversion(TestBase):
+
+    def test_plain_to_x(self):
+        # Convert Message to all formats
+        for class_ in (mailbox.Message, mailbox.MaildirMessage,
+                       mailbox.mboxMessage, mailbox.MHMessage,
+                       mailbox.BabylMessage, mailbox.MMDFMessage):
+            msg_plain = mailbox.Message(_sample_message)
+            msg = class_(msg_plain)
+            self._check_sample(msg)
+
+    def test_x_to_plain(self):
+        # Convert all formats to Message
+        for class_ in (mailbox.Message, mailbox.MaildirMessage,
+                       mailbox.mboxMessage, mailbox.MHMessage,
+                       mailbox.BabylMessage, mailbox.MMDFMessage):
+            msg = class_(_sample_message)
+            msg_plain = mailbox.Message(msg)
+            self._check_sample(msg_plain)
+
+    def test_x_to_invalid(self):
+        # Convert all formats to an invalid format
+        for class_ in (mailbox.Message, mailbox.MaildirMessage,
+                       mailbox.mboxMessage, mailbox.MHMessage,
+                       mailbox.BabylMessage, mailbox.MMDFMessage):
+            self.assertRaises(TypeError, lambda: class_(False))
+
+    def test_maildir_to_maildir(self):
+        # Convert MaildirMessage to MaildirMessage
+        msg_maildir = mailbox.MaildirMessage(_sample_message)
+        msg_maildir.set_flags('DFPRST')
+        msg_maildir.set_subdir('cur')
+        date = msg_maildir.get_date()
+        msg = mailbox.MaildirMessage(msg_maildir)
+        self._check_sample(msg)
+        self.assert_(msg.get_flags() == 'DFPRST')
+        self.assert_(msg.get_subdir() == 'cur')
+        self.assert_(msg.get_date() == date)
+
+    def test_maildir_to_mboxmmdf(self):
+        # Convert MaildirMessage to mboxmessage and MMDFMessage
+        pairs = (('D', ''), ('F', 'F'), ('P', ''), ('R', 'A'), ('S', 'R'),
+                 ('T', 'D'), ('DFPRST', 'RDFA'))
+        for class_ in (mailbox.mboxMessage, mailbox.MMDFMessage):
+            msg_maildir = mailbox.MaildirMessage(_sample_message)
+            msg_maildir.set_date(0.0)
+            for setting, result in pairs:
+                msg_maildir.set_flags(setting)
+                msg = class_(msg_maildir)
+                self.assert_(msg.get_flags() == result)
+                self.assert_(msg.get_from() == 'MAILER-DAEMON %s' %
+                             time.asctime(time.gmtime(0.0)))
+            msg_maildir.set_subdir('cur')
+            self.assert_(class_(msg_maildir).get_flags() == 'RODFA')
+
+    def test_maildir_to_mh(self):
+        # Convert MaildirMessage to MHMessage
+        msg_maildir = mailbox.MaildirMessage(_sample_message)
+        pairs = (('D', ['unseen']), ('F', ['unseen', 'flagged']),
+                 ('P', ['unseen']), ('R', ['unseen', 'replied']), ('S', []),
+                 ('T', ['unseen']), ('DFPRST', ['replied', 'flagged']))
+        for setting, result in pairs:
+            msg_maildir.set_flags(setting)
+            self.assert_(mailbox.MHMessage(msg_maildir).get_sequences() == \
+                         result)
+
+    def test_maildir_to_babyl(self):
+        # Convert MaildirMessage to Babyl
+        msg_maildir = mailbox.MaildirMessage(_sample_message)
+        pairs = (('D', ['unseen']), ('F', ['unseen']),
+                 ('P', ['unseen', 'forwarded']), ('R', ['unseen', 'answered']),
+                 ('S', []), ('T', ['unseen', 'deleted']),
+                 ('DFPRST', ['deleted', 'answered', 'forwarded']))
+        for setting, result in pairs:
+            msg_maildir.set_flags(setting)
+            self.assert_(mailbox.BabylMessage(msg_maildir).get_labels() == \
+                         result)
+
+    def test_mboxmmdf_to_maildir(self):
+        # Convert mboxMessage and MMDFMessage to MaildirMessage
+        for class_ in (mailbox.mboxMessage, mailbox.MMDFMessage):
+            msg_mboxMMDF = class_(_sample_message)
+            msg_mboxMMDF.set_from('foo at bar', time.gmtime(0.0))
+            pairs = (('R', 'S'), ('O', ''), ('D', 'T'), ('F', 'F'), ('A', 'R'),
+                     ('RODFA', 'FRST'))
+            for setting, result in pairs:
+                msg_mboxMMDF.set_flags(setting)
+                msg = mailbox.MaildirMessage(msg_mboxMMDF)
+                self.assert_(msg.get_flags() == result)
+                self.assert_(msg.get_date() == 0.0, msg.get_date())
+            msg_mboxMMDF.set_flags('O')
+            self.assert_(mailbox.MaildirMessage(msg_mboxMMDF).get_subdir() == \
+                         'cur')
+
+    def test_mboxmmdf_to_mboxmmdf(self):
+        # Convert mboxMessage and MMDFMessage to mboxMessage and MMDFMessage
+        for class_ in (mailbox.mboxMessage, mailbox.MMDFMessage):
+            msg_mboxMMDF = class_(_sample_message)
+            msg_mboxMMDF.set_flags('RODFA')
+            msg_mboxMMDF.set_from('foo at bar')
+            for class2_ in (mailbox.mboxMessage, mailbox.MMDFMessage):
+                msg2 = class2_(msg_mboxMMDF)
+                self.assert_(msg2.get_flags() == 'RODFA')
+                self.assert_(msg2.get_from() == 'foo at bar')
+
+    def test_mboxmmdf_to_mh(self):
+        # Convert mboxMessage and MMDFMessage to MHMessage
+        for class_ in (mailbox.mboxMessage, mailbox.MMDFMessage):
+            msg_mboxMMDF = class_(_sample_message)
+            pairs = (('R', []), ('O', ['unseen']), ('D', ['unseen']),
+                     ('F', ['unseen', 'flagged']),
+                     ('A', ['unseen', 'replied']),
+                     ('RODFA', ['replied', 'flagged']))
+            for setting, result in pairs:
+                msg_mboxMMDF.set_flags(setting)
+                self.assert_(mailbox.MHMessage(msg_mboxMMDF).get_sequences() \
+                             == result)
+
+    def test_mboxmmdf_to_babyl(self):
+        # Convert mboxMessage and MMDFMessage to BabylMessage
+        for class_ in (mailbox.mboxMessage, mailbox.MMDFMessage):
+            msg = class_(_sample_message)
+            pairs = (('R', []), ('O', ['unseen']),
+                     ('D', ['unseen', 'deleted']), ('F', ['unseen']),
+                     ('A', ['unseen', 'answered']),
+                     ('RODFA', ['deleted', 'answered']))
+            for setting, result in pairs:
+                msg.set_flags(setting)
+                self.assert_(mailbox.BabylMessage(msg).get_labels() == result)
+
+    def test_mh_to_maildir(self):
+        # Convert MHMessage to MaildirMessage
+        pairs = (('unseen', ''), ('replied', 'RS'), ('flagged', 'FS'))
+        for setting, result in pairs:
+            msg = mailbox.MHMessage(_sample_message)
+            msg.add_sequence(setting)
+            self.assert_(mailbox.MaildirMessage(msg).get_flags() == result)
+            self.assert_(mailbox.MaildirMessage(msg).get_subdir() == 'cur')
+        msg = mailbox.MHMessage(_sample_message)
+        msg.add_sequence('unseen')
+        msg.add_sequence('replied')
+        msg.add_sequence('flagged')
+        self.assert_(mailbox.MaildirMessage(msg).get_flags() == 'FR')
+        self.assert_(mailbox.MaildirMessage(msg).get_subdir() == 'cur')
+
+    def test_mh_to_mboxmmdf(self):
+        # Convert MHMessage to mboxMessage and MMDFMessage
+        pairs = (('unseen', 'O'), ('replied', 'ROA'), ('flagged', 'ROF'))
+        for setting, result in pairs:
+            msg = mailbox.MHMessage(_sample_message)
+            msg.add_sequence(setting)
+            for class_ in (mailbox.mboxMessage, mailbox.MMDFMessage):
+                self.assert_(class_(msg).get_flags() == result)
+        msg = mailbox.MHMessage(_sample_message)
+        msg.add_sequence('unseen')
+        msg.add_sequence('replied')
+        msg.add_sequence('flagged')
+        for class_ in (mailbox.mboxMessage, mailbox.MMDFMessage):
+            self.assert_(class_(msg).get_flags() == 'OFA')
+
+    def test_mh_to_mh(self):
+        # Convert MHMessage to MHMessage
+        msg = mailbox.MHMessage(_sample_message)
+        msg.add_sequence('unseen')
+        msg.add_sequence('replied')
+        msg.add_sequence('flagged')
+        self.assert_(mailbox.MHMessage(msg).get_sequences() == \
+                     ['unseen', 'replied', 'flagged'])
+
+    def test_mh_to_babyl(self):
+        # Convert MHMessage to BabylMessage
+        pairs = (('unseen', ['unseen']), ('replied', ['answered']),
+                 ('flagged', []))
+        for setting, result in pairs:
+            msg = mailbox.MHMessage(_sample_message)
+            msg.add_sequence(setting)
+            self.assert_(mailbox.BabylMessage(msg).get_labels() == result)
+        msg = mailbox.MHMessage(_sample_message)
+        msg.add_sequence('unseen')
+        msg.add_sequence('replied')
+        msg.add_sequence('flagged')
+        self.assert_(mailbox.BabylMessage(msg).get_labels() == \
+                     ['unseen', 'answered'])
+
+    def test_babyl_to_maildir(self):
+        # Convert BabylMessage to MaildirMessage
+        pairs = (('unseen', ''), ('deleted', 'ST'), ('filed', 'S'),
+                 ('answered', 'RS'), ('forwarded', 'PS'), ('edited', 'S'),
+                 ('resent', 'PS'))
+        for setting, result in pairs:
+            msg = mailbox.BabylMessage(_sample_message)
+            msg.add_label(setting)
+            self.assert_(mailbox.MaildirMessage(msg).get_flags() == result)
+            self.assert_(mailbox.MaildirMessage(msg).get_subdir() == 'cur')
+        msg = mailbox.BabylMessage(_sample_message)
+        for label in ('unseen', 'deleted', 'filed', 'answered', 'forwarded',
+                      'edited', 'resent'):
+            msg.add_label(label)
+        self.assert_(mailbox.MaildirMessage(msg).get_flags() == 'PRT')
+        self.assert_(mailbox.MaildirMessage(msg).get_subdir() == 'cur')
+
+    def test_babyl_to_mboxmmdf(self):
+        # Convert BabylMessage to mboxMessage and MMDFMessage
+        pairs = (('unseen', 'O'), ('deleted', 'ROD'), ('filed', 'RO'),
+                 ('answered', 'ROA'), ('forwarded', 'RO'), ('edited', 'RO'),
+                 ('resent', 'RO'))
+        for setting, result in pairs:
+            for class_ in (mailbox.mboxMessage, mailbox.MMDFMessage):
+                msg = mailbox.BabylMessage(_sample_message)
+                msg.add_label(setting)
+                self.assert_(class_(msg).get_flags() == result)
+        msg = mailbox.BabylMessage(_sample_message)
+        for label in ('unseen', 'deleted', 'filed', 'answered', 'forwarded',
+                      'edited', 'resent'):
+            msg.add_label(label)
+        for class_ in (mailbox.mboxMessage, mailbox.MMDFMessage):
+            self.assert_(class_(msg).get_flags() == 'ODA')
+
+    def test_babyl_to_mh(self):
+        # Convert BabylMessage to MHMessage
+        pairs = (('unseen', ['unseen']), ('deleted', []), ('filed', []),
+                 ('answered', ['replied']), ('forwarded', []), ('edited', []),
+                 ('resent', []))
+        for setting, result in pairs:
+            msg = mailbox.BabylMessage(_sample_message)
+            msg.add_label(setting)
+            self.assert_(mailbox.MHMessage(msg).get_sequences() == result)
+        msg = mailbox.BabylMessage(_sample_message)
+        for label in ('unseen', 'deleted', 'filed', 'answered', 'forwarded',
+                      'edited', 'resent'):
+            msg.add_label(label)
+        self.assert_(mailbox.MHMessage(msg).get_sequences() == \
+                     ['unseen', 'replied'])
+
+    def test_babyl_to_babyl(self):
+        # Convert BabylMessage to BabylMessage
+        msg = mailbox.BabylMessage(_sample_message)
+        msg.update_visible()
+        for label in ('unseen', 'deleted', 'filed', 'answered', 'forwarded',
+                      'edited', 'resent'):
+            msg.add_label(label)
+        msg2 = mailbox.BabylMessage(msg)
+        self.assert_(msg2.get_labels() == ['unseen', 'deleted', 'filed',
+                                           'answered', 'forwarded', 'edited',
+                                           'resent'])
+        self.assert_(msg.get_visible().keys() == msg2.get_visible().keys())
+        for key in msg.get_visible().keys():
+            self.assert_(msg.get_visible()[key] == msg2.get_visible()[key])
+
+
+class TestProxyFileBase(TestBase):
+
+    def _test_read(self, proxy):
+        # Read by byte
+        proxy.seek(0)
+        self.assert_(proxy.read() == 'bar')
+        proxy.seek(1)
+        self.assert_(proxy.read() == 'ar')
+        proxy.seek(0)
+        self.assert_(proxy.read(2) == 'ba')
+        proxy.seek(1)
+        self.assert_(proxy.read(-1) == 'ar')
+        proxy.seek(2)
+        self.assert_(proxy.read(1000) == 'r')
+
+    def _test_readline(self, proxy):
+        # Read by line
+        proxy.seek(0)
+        self.assert_(proxy.readline() == 'foo' + os.linesep)
+        self.assert_(proxy.readline() == 'bar' + os.linesep)
+        self.assert_(proxy.readline() == 'fred' + os.linesep)
+        self.assert_(proxy.readline() == 'bob')
+        proxy.seek(2)
+        self.assert_(proxy.readline() == 'o' + os.linesep)
+        proxy.seek(6 + 2 * len(os.linesep))
+        self.assert_(proxy.readline() == 'fred' + os.linesep)
+        proxy.seek(6 + 2 * len(os.linesep))
+        self.assert_(proxy.readline(2) == 'fr')
+        self.assert_(proxy.readline(-10) == 'ed' + os.linesep)
+
+    def _test_readlines(self, proxy):
+        # Read multiple lines
+        proxy.seek(0)
+        self.assert_(proxy.readlines() == ['foo' + os.linesep,
+                                           'bar' + os.linesep,
+                                           'fred' + os.linesep, 'bob'])
+        proxy.seek(0)
+        self.assert_(proxy.readlines(2) == ['foo' + os.linesep])
+        proxy.seek(3 + len(os.linesep))
+        self.assert_(proxy.readlines(4 + len(os.linesep)) ==
+                     ['bar' + os.linesep, 'fred' + os.linesep])
+        proxy.seek(3)
+        self.assert_(proxy.readlines(1000) == [os.linesep, 'bar' + os.linesep,
+                                               'fred' + os.linesep, 'bob'])
+
+    def _test_iteration(self, proxy):
+        # Iterate by line
+        proxy.seek(0)
+        iterator = iter(proxy)
+        self.assert_(iterator.next() == 'foo' + os.linesep)
+        self.assert_(iterator.next() == 'bar' + os.linesep)
+        self.assert_(iterator.next() == 'fred' + os.linesep)
+        self.assert_(iterator.next() == 'bob')
+        self.assertRaises(StopIteration, lambda: iterator.next())
+
+    def _test_seek_and_tell(self, proxy):
+        # Seek and use tell to check position
+        proxy.seek(3)
+        self.assert_(proxy.tell() == 3)
+        self.assert_(proxy.read(len(os.linesep)) == os.linesep)
+        proxy.seek(2, 1)
+        self.assert_(proxy.read(1 + len(os.linesep)) == 'r' + os.linesep)
+        proxy.seek(-3 - len(os.linesep), 2)
+        self.assert_(proxy.read(3) == 'bar')
+        proxy.seek(2, 0)
+        self.assert_(proxy.read() == 'o' + os.linesep + 'bar' + os.linesep)
+        proxy.seek(100)
+        self.assert_(proxy.read() == '')
+
+    def _test_close(self, proxy):
+        # Close a file
+        proxy.close()
+        self.assertRaises(AttributeError, lambda: proxy.close())
+
+
+class TestProxyFile(TestProxyFileBase):
+
+    def setUp(self):
+        self._path = test_support.TESTFN
+        self._file = open(self._path, 'wb+')
+
+    def tearDown(self):
+        self._file.close()
+        self._delete_recursively(self._path)
+
+    def test_initialize(self):
+        # Initialize and check position
+        self._file.write('foo')
+        pos = self._file.tell()
+        proxy0 = mailbox._ProxyFile(self._file)
+        self.assert_(proxy0.tell() == pos)
+        self.assert_(self._file.tell() == pos)
+        proxy1 = mailbox._ProxyFile(self._file, 0)
+        self.assert_(proxy1.tell() == 0)
+        self.assert_(self._file.tell() == pos)
+
+    def test_read(self):
+        self._file.write('bar')
+        self._test_read(mailbox._ProxyFile(self._file))
+
+    def test_readline(self):
+        self._file.write('foo%sbar%sfred%sbob' % (os.linesep, os.linesep,
+                                                  os.linesep))
+        self._test_readline(mailbox._ProxyFile(self._file))
+
+    def test_readlines(self):
+        self._file.write('foo%sbar%sfred%sbob' % (os.linesep, os.linesep,
+                                                  os.linesep))
+        self._test_readlines(mailbox._ProxyFile(self._file))
+
+    def test_iteration(self):
+        self._file.write('foo%sbar%sfred%sbob' % (os.linesep, os.linesep,
+                                                  os.linesep))
+        self._test_iteration(mailbox._ProxyFile(self._file))
+
+    def test_seek_and_tell(self):
+        self._file.write('foo%sbar%s' % (os.linesep, os.linesep))
+        self._test_seek_and_tell(mailbox._ProxyFile(self._file))
+
+    def test_close(self):
+        self._file.write('foo%sbar%s' % (os.linesep, os.linesep))
+        self._test_close(mailbox._ProxyFile(self._file))
+
+
+class TestPartialFile(TestProxyFileBase):
+
+    def setUp(self):
+        self._path = test_support.TESTFN
+        self._file = open(self._path, 'wb+')
+
+    def tearDown(self):
+        self._file.close()
+        self._delete_recursively(self._path)
+
+    def test_initialize(self):
+        # Initialize and check position
+        self._file.write('foo' + os.linesep + 'bar')
+        pos = self._file.tell()
+        proxy = mailbox._PartialFile(self._file, 2, 5)
+        self.assert_(proxy.tell() == 0)
+        self.assert_(self._file.tell() == pos)
+
+    def test_read(self):
+        self._file.write('***bar***')
+        self._test_read(mailbox._PartialFile(self._file, 3, 6))
+
+    def test_readline(self):
+        self._file.write('!!!!!foo%sbar%sfred%sbob!!!!!' %
+                         (os.linesep, os.linesep, os.linesep))
+        self._test_readline(mailbox._PartialFile(self._file, 5,
+                                                 18 + 3 * len(os.linesep)))
+
+    def test_readlines(self):
+        self._file.write('foo%sbar%sfred%sbob?????' %
+                         (os.linesep, os.linesep, os.linesep))
+        self._test_readlines(mailbox._PartialFile(self._file, 0,
+                                                  13 + 3 * len(os.linesep)))
+
+    def test_iteration(self):
+        self._file.write('____foo%sbar%sfred%sbob####' %
+                         (os.linesep, os.linesep, os.linesep))
+        self._test_iteration(mailbox._PartialFile(self._file, 4,
+                                                  17 + 3 * len(os.linesep)))
+
+    def test_seek_and_tell(self):
+        self._file.write('(((foo%sbar%s$$$' % (os.linesep, os.linesep))
+        self._test_seek_and_tell(mailbox._PartialFile(self._file, 3,
+                                                      9 + 2 * len(os.linesep)))
+
+    def test_close(self):
+        self._file.write('&foo%sbar%s^' % (os.linesep, os.linesep))
+        self._test_close(mailbox._PartialFile(self._file, 1,
+                                              6 + 3 * len(os.linesep)))
+
+
+## Start: tests from the original module (for backward compatibility).
+
+FROM_ = "From some.body at dummy.domain  Sat Jul 24 13:43:35 2004\n"
+DUMMY_MESSAGE = """\
+From: some.body at dummy.domain
+To: me at my.domain
+Subject: Simple Test
+
+This is a dummy message.
+"""
+
+class MaildirTestCase(unittest.TestCase):
+
+    def setUp(self):
+        # create a new maildir mailbox to work with:
+        self._dir = test_support.TESTFN
+        os.mkdir(self._dir)
+        os.mkdir(os.path.join(self._dir, "cur"))
+        os.mkdir(os.path.join(self._dir, "tmp"))
+        os.mkdir(os.path.join(self._dir, "new"))
+        self._counter = 1
+        self._msgfiles = []
+
+    def tearDown(self):
+        map(os.unlink, self._msgfiles)
+        os.rmdir(os.path.join(self._dir, "cur"))
+        os.rmdir(os.path.join(self._dir, "tmp"))
+        os.rmdir(os.path.join(self._dir, "new"))
+        os.rmdir(self._dir)
+
+    def createMessage(self, dir, mbox=False):
+        t = int(time.time() % 1000000)
+        pid = self._counter
+        self._counter += 1
+        filename = os.extsep.join((str(t), str(pid), "myhostname", "mydomain"))
+        tmpname = os.path.join(self._dir, "tmp", filename)
+        newname = os.path.join(self._dir, dir, filename)
+        fp = open(tmpname, "w")
+        self._msgfiles.append(tmpname)
+        if mbox:
+            fp.write(FROM_)
+        fp.write(DUMMY_MESSAGE)
+        fp.close()
+        if hasattr(os, "link"):
+            os.link(tmpname, newname)
+        else:
+            fp = open(newname, "w")
+            fp.write(DUMMY_MESSAGE)
+            fp.close()
+        self._msgfiles.append(newname)
+        return tmpname
+
+    def test_empty_maildir(self):
+        """Test an empty maildir mailbox"""
+        # Test for regression on bug #117490:
+        # Make sure the boxes attribute actually gets set.
+        self.mbox = mailbox.Maildir(test_support.TESTFN)
+        #self.assert_(hasattr(self.mbox, "boxes"))
+        #self.assert_(len(self.mbox.boxes) == 0)
+        self.assert_(self.mbox.next() is None)
+        self.assert_(self.mbox.next() is None)
+
+    def test_nonempty_maildir_cur(self):
+        self.createMessage("cur")
+        self.mbox = mailbox.Maildir(test_support.TESTFN)
+        #self.assert_(len(self.mbox.boxes) == 1)
+        self.assert_(self.mbox.next() is not None)
+        self.assert_(self.mbox.next() is None)
+        self.assert_(self.mbox.next() is None)
+
+    def test_nonempty_maildir_new(self):
+        self.createMessage("new")
+        self.mbox = mailbox.Maildir(test_support.TESTFN)
+        #self.assert_(len(self.mbox.boxes) == 1)
+        self.assert_(self.mbox.next() is not None)
+        self.assert_(self.mbox.next() is None)
+        self.assert_(self.mbox.next() is None)
+
+    def test_nonempty_maildir_both(self):
+        self.createMessage("cur")
+        self.createMessage("new")
+        self.mbox = mailbox.Maildir(test_support.TESTFN)
+        #self.assert_(len(self.mbox.boxes) == 2)
+        self.assert_(self.mbox.next() is not None)
+        self.assert_(self.mbox.next() is not None)
+        self.assert_(self.mbox.next() is None)
+        self.assert_(self.mbox.next() is None)
+
+    def test_unix_mbox(self):
+        ### should be better!
+        import email.Parser
+        fname = self.createMessage("cur", True)
+        n = 0
+        for msg in mailbox.PortableUnixMailbox(open(fname),
+                                               email.Parser.Parser().parse):
+            n += 1
+            self.assertEqual(msg["subject"], "Simple Test")
+            self.assertEqual(len(str(msg)), len(FROM_)+len(DUMMY_MESSAGE))
+        self.assertEqual(n, 1)
+
+## End: classes from the original module (for backward compatibility).
+
+
+_sample_message = """\
+Return-Path: <gkj at gregorykjohnson.com>
+X-Original-To: gkj+person at localhost
+Delivered-To: gkj+person at localhost
+Received: from localhost (localhost [127.0.0.1])
+        by andy.gregorykjohnson.com (Postfix) with ESMTP id 356ED9DD17
+        for <gkj+person at localhost>; Wed, 13 Jul 2005 17:23:16 -0400 (EDT)
+Delivered-To: gkj at sundance.gregorykjohnson.com
+Received: from localhost [127.0.0.1]
+        by localhost with POP3 (fetchmail-6.2.5)
+        for gkj+person at localhost (single-drop); Wed, 13 Jul 2005 17:23:16 -0400 (EDT)
+Received: from andy.gregorykjohnson.com (andy.gregorykjohnson.com [64.32.235.228])
+        by sundance.gregorykjohnson.com (Postfix) with ESMTP id 5B056316746
+        for <gkj at gregorykjohnson.com>; Wed, 13 Jul 2005 17:23:11 -0400 (EDT)
+Received: by andy.gregorykjohnson.com (Postfix, from userid 1000)
+        id 490CD9DD17; Wed, 13 Jul 2005 17:23:11 -0400 (EDT)
+Date: Wed, 13 Jul 2005 17:23:11 -0400
+From: "Gregory K. Johnson" <gkj at gregorykjohnson.com>
+To: gkj at gregorykjohnson.com
+Subject: Sample message
+Message-ID: <20050713212311.GC4701 at andy.gregorykjohnson.com>
+Mime-Version: 1.0
+Content-Type: multipart/mixed; boundary="NMuMz9nt05w80d4+"
+Content-Disposition: inline
+User-Agent: Mutt/1.5.9i
+
+
+--NMuMz9nt05w80d4+
+Content-Type: text/plain; charset=us-ascii
+Content-Disposition: inline
+
+This is a sample message.
+
+--
+Gregory K. Johnson
+
+--NMuMz9nt05w80d4+
+Content-Type: application/octet-stream
+Content-Disposition: attachment; filename="text.gz"
+Content-Transfer-Encoding: base64
+
+H4sICM2D1UIAA3RleHQAC8nILFYAokSFktSKEoW0zJxUPa7wzJIMhZLyfIWczLzUYj0uAHTs
+3FYlAAAA
+
+--NMuMz9nt05w80d4+--
+"""
+
+_sample_headers = {
+    "Return-Path":"<gkj at gregorykjohnson.com>",
+    "X-Original-To":"gkj+person at localhost",
+    "Delivered-To":"gkj+person at localhost",
+    "Received":"""from localhost (localhost [127.0.0.1])
+        by andy.gregorykjohnson.com (Postfix) with ESMTP id 356ED9DD17
+        for <gkj+person at localhost>; Wed, 13 Jul 2005 17:23:16 -0400 (EDT)""",
+    "Delivered-To":"gkj at sundance.gregorykjohnson.com",
+    "Received":"""from localhost [127.0.0.1]
+        by localhost with POP3 (fetchmail-6.2.5)
+        for gkj+person at localhost (single-drop); Wed, 13 Jul 2005 17:23:16 -0400 (EDT)""",
+    "Received":"""from andy.gregorykjohnson.com (andy.gregorykjohnson.com [64.32.235.228])
+        by sundance.gregorykjohnson.com (Postfix) with ESMTP id 5B056316746
+        for <gkj at gregorykjohnson.com>; Wed, 13 Jul 2005 17:23:11 -0400 (EDT)""",
+    "Received":"""by andy.gregorykjohnson.com (Postfix, from userid 1000)
+        id 490CD9DD17; Wed, 13 Jul 2005 17:23:11 -0400 (EDT)""",
+    "Date":"Wed, 13 Jul 2005 17:23:11 -0400",
+    "From":""""Gregory K. Johnson" <gkj at gregorykjohnson.com>""",
+    "To":"gkj at gregorykjohnson.com",
+    "Subject":"Sample message",
+    "Mime-Version":"1.0",
+    "Content-Type":"""multipart/mixed; boundary="NMuMz9nt05w80d4+\"""",
+    "Content-Disposition":"inline",
+    "User-Agent": "Mutt/1.5.9i" }
+
+_sample_payloads = ("""This is a sample message.
+
+--
+Gregory K. Johnson
+""",
+"""H4sICM2D1UIAA3RleHQAC8nILFYAokSFktSKEoW0zJxUPa7wzJIMhZLyfIWczLzUYj0uAHTs
+3FYlAAAA
+""")
+
+
+def test_main():
+    tests = (TestMailboxSuperclass, TestMaildir, TestMbox, TestMMDF, TestMH,
+             TestBabyl, TestMessage, TestMaildirMessage, TestMboxMessage,
+             TestMHMessage, TestBabylMessage, TestMMDFMessage,
+             TestMessageConversion, TestProxyFile, TestPartialFile,
+             MaildirTestCase)
+    test_support.run_unittest(*tests)
+    test_support.reap_children()
+
+
+if __name__ == '__main__':
+    test_main()

Added: vendor/Python/current/Lib/test/test_marshal.py
===================================================================
--- vendor/Python/current/Lib/test/test_marshal.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_marshal.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,233 @@
+#!/usr/bin/env python
+# -*- coding: iso-8859-1 -*-
+
+from test import test_support
+import marshal
+import sys
+import unittest
+import os
+
+class IntTestCase(unittest.TestCase):
+    def test_ints(self):
+        # Test the full range of Python ints.
+        n = sys.maxint
+        while n:
+            for expected in (-n, n):
+                s = marshal.dumps(expected)
+                got = marshal.loads(s)
+                self.assertEqual(expected, got)
+                marshal.dump(expected, file(test_support.TESTFN, "wb"))
+                got = marshal.load(file(test_support.TESTFN, "rb"))
+                self.assertEqual(expected, got)
+            n = n >> 1
+        os.unlink(test_support.TESTFN)
+
+    def test_int64(self):
+        # Simulate int marshaling on a 64-bit box.  This is most interesting if
+        # we're running the test on a 32-bit box, of course.
+
+        def to_little_endian_string(value, nbytes):
+            bytes = []
+            for i in range(nbytes):
+                bytes.append(chr(value & 0xff))
+                value >>= 8
+            return ''.join(bytes)
+
+        maxint64 = (1L << 63) - 1
+        minint64 = -maxint64-1
+
+        for base in maxint64, minint64, -maxint64, -(minint64 >> 1):
+            while base:
+                s = 'I' + to_little_endian_string(base, 8)
+                got = marshal.loads(s)
+                self.assertEqual(base, got)
+                if base == -1:  # a fixed-point for shifting right 1
+                    base = 0
+                else:
+                    base >>= 1
+
+    def test_bool(self):
+        for b in (True, False):
+            new = marshal.loads(marshal.dumps(b))
+            self.assertEqual(b, new)
+            self.assertEqual(type(b), type(new))
+            marshal.dump(b, file(test_support.TESTFN, "wb"))
+            new = marshal.load(file(test_support.TESTFN, "rb"))
+            self.assertEqual(b, new)
+            self.assertEqual(type(b), type(new))
+
+class FloatTestCase(unittest.TestCase):
+    def test_floats(self):
+        # Test a few floats
+        small = 1e-25
+        n = sys.maxint * 3.7e250
+        while n > small:
+            for expected in (-n, n):
+                f = float(expected)
+                s = marshal.dumps(f)
+                got = marshal.loads(s)
+                self.assertEqual(f, got)
+                marshal.dump(f, file(test_support.TESTFN, "wb"))
+                got = marshal.load(file(test_support.TESTFN, "rb"))
+                self.assertEqual(f, got)
+            n /= 123.4567
+
+        f = 0.0
+        s = marshal.dumps(f, 2)
+        got = marshal.loads(s)
+        self.assertEqual(f, got)
+        # and with version <= 1 (floats marshalled differently then)
+        s = marshal.dumps(f, 1)
+        got = marshal.loads(s)
+        self.assertEqual(f, got)
+
+        n = sys.maxint * 3.7e-250
+        while n < small:
+            for expected in (-n, n):
+                f = float(expected)
+
+                s = marshal.dumps(f)
+                got = marshal.loads(s)
+                self.assertEqual(f, got)
+
+                s = marshal.dumps(f, 1)
+                got = marshal.loads(s)
+                self.assertEqual(f, got)
+
+                marshal.dump(f, file(test_support.TESTFN, "wb"))
+                got = marshal.load(file(test_support.TESTFN, "rb"))
+                self.assertEqual(f, got)
+
+                marshal.dump(f, file(test_support.TESTFN, "wb"), 1)
+                got = marshal.load(file(test_support.TESTFN, "rb"))
+                self.assertEqual(f, got)
+            n *= 123.4567
+        os.unlink(test_support.TESTFN)
+
+class StringTestCase(unittest.TestCase):
+    def test_unicode(self):
+        for s in [u"", u"Andrè Previn", u"abc", u" "*10000]:
+            new = marshal.loads(marshal.dumps(s))
+            self.assertEqual(s, new)
+            self.assertEqual(type(s), type(new))
+            marshal.dump(s, file(test_support.TESTFN, "wb"))
+            new = marshal.load(file(test_support.TESTFN, "rb"))
+            self.assertEqual(s, new)
+            self.assertEqual(type(s), type(new))
+        os.unlink(test_support.TESTFN)
+
+    def test_string(self):
+        for s in ["", "Andrè Previn", "abc", " "*10000]:
+            new = marshal.loads(marshal.dumps(s))
+            self.assertEqual(s, new)
+            self.assertEqual(type(s), type(new))
+            marshal.dump(s, file(test_support.TESTFN, "wb"))
+            new = marshal.load(file(test_support.TESTFN, "rb"))
+            self.assertEqual(s, new)
+            self.assertEqual(type(s), type(new))
+        os.unlink(test_support.TESTFN)
+
+    def test_buffer(self):
+        for s in ["", "Andrè Previn", "abc", " "*10000]:
+            b = buffer(s)
+            new = marshal.loads(marshal.dumps(b))
+            self.assertEqual(s, new)
+            marshal.dump(b, file(test_support.TESTFN, "wb"))
+            new = marshal.load(file(test_support.TESTFN, "rb"))
+            self.assertEqual(s, new)
+        os.unlink(test_support.TESTFN)
+
+class ExceptionTestCase(unittest.TestCase):
+    def test_exceptions(self):
+        new = marshal.loads(marshal.dumps(StopIteration))
+        self.assertEqual(StopIteration, new)
+
+class CodeTestCase(unittest.TestCase):
+    def test_code(self):
+        co = ExceptionTestCase.test_exceptions.func_code
+        new = marshal.loads(marshal.dumps(co))
+        self.assertEqual(co, new)
+
+class ContainerTestCase(unittest.TestCase):
+    d = {'astring': 'foo at bar.baz.spam',
+         'afloat': 7283.43,
+         'anint': 2**20,
+         'ashortlong': 2L,
+         'alist': ['.zyx.41'],
+         'atuple': ('.zyx.41',)*10,
+         'aboolean': False,
+         'aunicode': u"Andrè Previn"
+         }
+    def test_dict(self):
+        new = marshal.loads(marshal.dumps(self.d))
+        self.assertEqual(self.d, new)
+        marshal.dump(self.d, file(test_support.TESTFN, "wb"))
+        new = marshal.load(file(test_support.TESTFN, "rb"))
+        self.assertEqual(self.d, new)
+        os.unlink(test_support.TESTFN)
+
+    def test_list(self):
+        lst = self.d.items()
+        new = marshal.loads(marshal.dumps(lst))
+        self.assertEqual(lst, new)
+        marshal.dump(lst, file(test_support.TESTFN, "wb"))
+        new = marshal.load(file(test_support.TESTFN, "rb"))
+        self.assertEqual(lst, new)
+        os.unlink(test_support.TESTFN)
+
+    def test_tuple(self):
+        t = tuple(self.d.keys())
+        new = marshal.loads(marshal.dumps(t))
+        self.assertEqual(t, new)
+        marshal.dump(t, file(test_support.TESTFN, "wb"))
+        new = marshal.load(file(test_support.TESTFN, "rb"))
+        self.assertEqual(t, new)
+        os.unlink(test_support.TESTFN)
+
+    def test_sets(self):
+        for constructor in (set, frozenset):
+            t = constructor(self.d.keys())
+            new = marshal.loads(marshal.dumps(t))
+            self.assertEqual(t, new)
+            self.assert_(isinstance(new, constructor))
+            self.assertNotEqual(id(t), id(new))
+            marshal.dump(t, file(test_support.TESTFN, "wb"))
+            new = marshal.load(file(test_support.TESTFN, "rb"))
+            self.assertEqual(t, new)
+            os.unlink(test_support.TESTFN)
+
+class BugsTestCase(unittest.TestCase):
+    def test_bug_5888452(self):
+        # Simple-minded check for SF 588452: Debug build crashes
+        marshal.dumps([128] * 1000)
+
+    def test_patch_873224(self):
+        self.assertRaises(Exception, marshal.loads, '0')
+        self.assertRaises(Exception, marshal.loads, 'f')
+        self.assertRaises(Exception, marshal.loads, marshal.dumps(5L)[:-1])
+
+    def test_version_argument(self):
+        # Python 2.4.0 crashes for any call to marshal.dumps(x, y)
+        self.assertEquals(marshal.loads(marshal.dumps(5, 0)), 5)
+        self.assertEquals(marshal.loads(marshal.dumps(5, 1)), 5)
+
+    def test_fuzz(self):
+        # simple test that it's at least not *totally* trivial to
+        # crash from bad marshal data
+        for c in [chr(i) for i in range(256)]:
+            try:
+                marshal.loads(c)
+            except Exception:
+                pass
+
+def test_main():
+    test_support.run_unittest(IntTestCase,
+                              FloatTestCase,
+                              StringTestCase,
+                              CodeTestCase,
+                              ContainerTestCase,
+                              ExceptionTestCase,
+                              BugsTestCase)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_math.py
===================================================================
--- vendor/Python/current/Lib/test/test_math.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_math.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,208 @@
+# Python test set -- math module
+# XXXX Should not do tests around zero only
+
+from test.test_support import TestFailed, verbose
+
+seps='1e-05'
+eps = eval(seps)
+print 'math module, testing with eps', seps
+import math
+
+def testit(name, value, expected):
+    if abs(value-expected) > eps:
+        raise TestFailed, '%s returned %f, expected %f'%\
+              (name, value, expected)
+
+print 'constants'
+testit('pi', math.pi, 3.1415926)
+testit('e', math.e, 2.7182818)
+
+print 'acos'
+testit('acos(-1)', math.acos(-1), math.pi)
+testit('acos(0)', math.acos(0), math.pi/2)
+testit('acos(1)', math.acos(1), 0)
+
+print 'asin'
+testit('asin(-1)', math.asin(-1), -math.pi/2)
+testit('asin(0)', math.asin(0), 0)
+testit('asin(1)', math.asin(1), math.pi/2)
+
+print 'atan'
+testit('atan(-1)', math.atan(-1), -math.pi/4)
+testit('atan(0)', math.atan(0), 0)
+testit('atan(1)', math.atan(1), math.pi/4)
+
+print 'atan2'
+testit('atan2(-1, 0)', math.atan2(-1, 0), -math.pi/2)
+testit('atan2(-1, 1)', math.atan2(-1, 1), -math.pi/4)
+testit('atan2(0, 1)', math.atan2(0, 1), 0)
+testit('atan2(1, 1)', math.atan2(1, 1), math.pi/4)
+testit('atan2(1, 0)', math.atan2(1, 0), math.pi/2)
+
+print 'ceil'
+testit('ceil(0.5)', math.ceil(0.5), 1)
+testit('ceil(1.0)', math.ceil(1.0), 1)
+testit('ceil(1.5)', math.ceil(1.5), 2)
+testit('ceil(-0.5)', math.ceil(-0.5), 0)
+testit('ceil(-1.0)', math.ceil(-1.0), -1)
+testit('ceil(-1.5)', math.ceil(-1.5), -1)
+
+print 'cos'
+testit('cos(-pi/2)', math.cos(-math.pi/2), 0)
+testit('cos(0)', math.cos(0), 1)
+testit('cos(pi/2)', math.cos(math.pi/2), 0)
+testit('cos(pi)', math.cos(math.pi), -1)
+
+print 'cosh'
+testit('cosh(0)', math.cosh(0), 1)
+testit('cosh(2)-2*cosh(1)**2', math.cosh(2)-2*math.cosh(1)**2, -1) # Thanks to Lambert
+
+print 'degrees'
+testit('degrees(pi)', math.degrees(math.pi), 180.0)
+testit('degrees(pi/2)', math.degrees(math.pi/2), 90.0)
+testit('degrees(-pi/4)', math.degrees(-math.pi/4), -45.0)
+
+print 'exp'
+testit('exp(-1)', math.exp(-1), 1/math.e)
+testit('exp(0)', math.exp(0), 1)
+testit('exp(1)', math.exp(1), math.e)
+
+print 'fabs'
+testit('fabs(-1)', math.fabs(-1), 1)
+testit('fabs(0)', math.fabs(0), 0)
+testit('fabs(1)', math.fabs(1), 1)
+
+print 'floor'
+testit('floor(0.5)', math.floor(0.5), 0)
+testit('floor(1.0)', math.floor(1.0), 1)
+testit('floor(1.5)', math.floor(1.5), 1)
+testit('floor(-0.5)', math.floor(-0.5), -1)
+testit('floor(-1.0)', math.floor(-1.0), -1)
+testit('floor(-1.5)', math.floor(-1.5), -2)
+
+print 'fmod'
+testit('fmod(10,1)', math.fmod(10,1), 0)
+testit('fmod(10,0.5)', math.fmod(10,0.5), 0)
+testit('fmod(10,1.5)', math.fmod(10,1.5), 1)
+testit('fmod(-10,1)', math.fmod(-10,1), 0)
+testit('fmod(-10,0.5)', math.fmod(-10,0.5), 0)
+testit('fmod(-10,1.5)', math.fmod(-10,1.5), -1)
+
+print 'frexp'
+def testfrexp(name, (mant, exp), (emant, eexp)):
+    if abs(mant-emant) > eps or exp != eexp:
+        raise TestFailed, '%s returned %r, expected %r'%\
+              (name, (mant, exp), (emant,eexp))
+
+testfrexp('frexp(-1)', math.frexp(-1), (-0.5, 1))
+testfrexp('frexp(0)', math.frexp(0), (0, 0))
+testfrexp('frexp(1)', math.frexp(1), (0.5, 1))
+testfrexp('frexp(2)', math.frexp(2), (0.5, 2))
+
+print 'hypot'
+testit('hypot(0,0)', math.hypot(0,0), 0)
+testit('hypot(3,4)', math.hypot(3,4), 5)
+
+print 'ldexp'
+testit('ldexp(0,1)', math.ldexp(0,1), 0)
+testit('ldexp(1,1)', math.ldexp(1,1), 2)
+testit('ldexp(1,-1)', math.ldexp(1,-1), 0.5)
+testit('ldexp(-1,1)', math.ldexp(-1,1), -2)
+
+print 'log'
+testit('log(1/e)', math.log(1/math.e), -1)
+testit('log(1)', math.log(1), 0)
+testit('log(e)', math.log(math.e), 1)
+testit('log(32,2)', math.log(32,2), 5)
+testit('log(10**40, 10)', math.log(10**40, 10), 40)
+testit('log(10**40, 10**20)', math.log(10**40, 10**20), 2)
+
+print 'log10'
+testit('log10(0.1)', math.log10(0.1), -1)
+testit('log10(1)', math.log10(1), 0)
+testit('log10(10)', math.log10(10), 1)
+
+print 'modf'
+def testmodf(name, (v1, v2), (e1, e2)):
+    if abs(v1-e1) > eps or abs(v2-e2):
+        raise TestFailed, '%s returned %r, expected %r'%\
+              (name, (v1,v2), (e1,e2))
+
+testmodf('modf(1.5)', math.modf(1.5), (0.5, 1.0))
+testmodf('modf(-1.5)', math.modf(-1.5), (-0.5, -1.0))
+
+print 'pow'
+testit('pow(0,1)', math.pow(0,1), 0)
+testit('pow(1,0)', math.pow(1,0), 1)
+testit('pow(2,1)', math.pow(2,1), 2)
+testit('pow(2,-1)', math.pow(2,-1), 0.5)
+
+print 'radians'
+testit('radians(180)', math.radians(180), math.pi)
+testit('radians(90)', math.radians(90), math.pi/2)
+testit('radians(-45)', math.radians(-45), -math.pi/4)
+
+print 'sin'
+testit('sin(0)', math.sin(0), 0)
+testit('sin(pi/2)', math.sin(math.pi/2), 1)
+testit('sin(-pi/2)', math.sin(-math.pi/2), -1)
+
+print 'sinh'
+testit('sinh(0)', math.sinh(0), 0)
+testit('sinh(1)**2-cosh(1)**2', math.sinh(1)**2-math.cosh(1)**2, -1)
+testit('sinh(1)+sinh(-1)', math.sinh(1)+math.sinh(-1), 0)
+
+print 'sqrt'
+testit('sqrt(0)', math.sqrt(0), 0)
+testit('sqrt(1)', math.sqrt(1), 1)
+testit('sqrt(4)', math.sqrt(4), 2)
+
+print 'tan'
+testit('tan(0)', math.tan(0), 0)
+testit('tan(pi/4)', math.tan(math.pi/4), 1)
+testit('tan(-pi/4)', math.tan(-math.pi/4), -1)
+
+print 'tanh'
+testit('tanh(0)', math.tanh(0), 0)
+testit('tanh(1)+tanh(-1)', math.tanh(1)+math.tanh(-1), 0)
+
+# RED_FLAG 16-Oct-2000 Tim
+# While 2.0 is more consistent about exceptions than previous releases, it
+# still fails this part of the test on some platforms.  For now, we only
+# *run* test_exceptions() in verbose mode, so that this isn't normally
+# tested.
+
+def test_exceptions():
+    print 'exceptions'
+    try:
+        x = math.exp(-1000000000)
+    except:
+        # mathmodule.c is failing to weed out underflows from libm, or
+        # we've got an fp format with huge dynamic range
+        raise TestFailed("underflowing exp() should not have raised "
+                         "an exception")
+    if x != 0:
+        raise TestFailed("underflowing exp() should have returned 0")
+
+    # If this fails, probably using a strict IEEE-754 conforming libm, and x
+    # is +Inf afterwards.  But Python wants overflows detected by default.
+    try:
+        x = math.exp(1000000000)
+    except OverflowError:
+        pass
+    else:
+        raise TestFailed("overflowing exp() didn't trigger OverflowError")
+
+    # If this fails, it could be a puzzle.  One odd possibility is that
+    # mathmodule.c's macros are getting confused while comparing
+    # Inf (HUGE_VAL) to a NaN, and artificially setting errno to ERANGE
+    # as a result (and so raising OverflowError instead).
+    try:
+        x = math.sqrt(-1.0)
+    except ValueError:
+        pass
+    else:
+        raise TestFailed("sqrt(-1) didn't raise ValueError")
+
+if verbose:
+    test_exceptions()

Added: vendor/Python/current/Lib/test/test_md5.py
===================================================================
--- vendor/Python/current/Lib/test/test_md5.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_md5.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,58 @@
+# Testing md5 module
+
+import unittest
+from md5 import md5
+from test import test_support
+
+def hexstr(s):
+    import string
+    h = string.hexdigits
+    r = ''
+    for c in s:
+        i = ord(c)
+        r = r + h[(i >> 4) & 0xF] + h[i & 0xF]
+    return r
+
+class MD5_Test(unittest.TestCase):
+
+    def md5test(self, s, expected):
+        self.assertEqual(hexstr(md5(s).digest()), expected)
+        self.assertEqual(md5(s).hexdigest(), expected)
+
+    def test_basics(self):
+        eq = self.md5test
+        eq('', 'd41d8cd98f00b204e9800998ecf8427e')
+        eq('a', '0cc175b9c0f1b6a831c399e269772661')
+        eq('abc', '900150983cd24fb0d6963f7d28e17f72')
+        eq('message digest', 'f96b697d7cb7938d525a2f31aaf161d0')
+        eq('abcdefghijklmnopqrstuvwxyz', 'c3fcd3d76192e4007dfb496cca67e13b')
+        eq('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',
+           'd174ab98d277d9f5a5611c2c9f419d9f')
+        eq('12345678901234567890123456789012345678901234567890123456789012345678901234567890',
+           '57edf4a22be3c955ac49da2e2107b67a')
+
+    def test_hexdigest(self):
+        # hexdigest is new with Python 2.0
+        m = md5('testing the hexdigest method')
+        h = m.hexdigest()
+        self.assertEqual(hexstr(m.digest()), h)
+
+    def test_large_update(self):
+        aas = 'a' * 64
+        bees = 'b' * 64
+        cees = 'c' * 64
+
+        m1 = md5()
+        m1.update(aas)
+        m1.update(bees)
+        m1.update(cees)
+
+        m2 = md5()
+        m2.update(aas + bees + cees)
+        self.assertEqual(m1.digest(), m2.digest())
+
+def test_main():
+    test_support.run_unittest(MD5_Test)
+
+if __name__ == '__main__':
+    test_main()

Added: vendor/Python/current/Lib/test/test_mhlib.py
===================================================================
--- vendor/Python/current/Lib/test/test_mhlib.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_mhlib.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,348 @@
+"""
+   Tests for the mhlib module
+   Nick Mathewson
+"""
+
+### BUG: This suite doesn't currently test the mime functionality of
+###      mhlib.  It should.
+
+import unittest
+from test.test_support import run_unittest, TESTFN, TestSkipped
+import os, StringIO
+import sys
+import mhlib
+
+if (sys.platform.startswith("win") or sys.platform=="riscos" or
+      sys.platform.startswith("atheos")):
+    # mhlib.updateline() renames a file to the name of a file that already
+    # exists.  That causes a reasonable OS <wink> to complain in test_sequence
+    # here, like the "OSError: [Errno 17] File exists" raised on Windows.
+    # mhlib's listsubfolders() and listallfolders() do something with
+    # link counts, and that causes test_listfolders() here to get back
+    # an empty list from its call of listallfolders().
+    # The other tests here pass on Windows.
+    raise TestSkipped("skipped on %s -- " % sys.platform +
+                      "too many Unix assumptions")
+
+_mhroot = TESTFN+"_MH"
+_mhpath = os.path.join(_mhroot, "MH")
+_mhprofile = os.path.join(_mhroot, ".mh_profile")
+
+def normF(f):
+    return os.path.join(*f.split('/'))
+
+def writeFile(fname, contents):
+    dir = os.path.split(fname)[0]
+    if dir and not os.path.exists(dir):
+        mkdirs(dir)
+    f = open(fname, 'w')
+    f.write(contents)
+    f.close()
+
+def readFile(fname):
+    f = open(fname)
+    r = f.read()
+    f.close()
+    return r
+
+def writeProfile(dict):
+    contents = [ "%s: %s\n" % (k, v) for k, v in dict.iteritems() ]
+    writeFile(_mhprofile, "".join(contents))
+
+def writeContext(folder):
+    folder = normF(folder)
+    writeFile(os.path.join(_mhpath, "context"),
+              "Current-Folder: %s\n" % folder)
+
+def writeCurMessage(folder, cur):
+    folder = normF(folder)
+    writeFile(os.path.join(_mhpath, folder, ".mh_sequences"),
+              "cur: %s\n"%cur)
+
+def writeMessage(folder, n, headers, body):
+    folder = normF(folder)
+    headers = "".join([ "%s: %s\n" % (k, v) for k, v in headers.iteritems() ])
+    contents = "%s\n%s\n" % (headers,body)
+    mkdirs(os.path.join(_mhpath, folder))
+    writeFile(os.path.join(_mhpath, folder, str(n)), contents)
+
+def getMH():
+    return mhlib.MH(os.path.abspath(_mhpath), _mhprofile)
+
+def sortLines(s):
+    lines = s.split("\n")
+    lines = [ line.strip() for line in lines if len(line) >= 2 ]
+    lines.sort()
+    return lines
+
+# These next 2 functions are copied from test_glob.py.
+def mkdirs(fname):
+    if os.path.exists(fname) or fname == '':
+        return
+    base, file = os.path.split(fname)
+    mkdirs(base)
+    os.mkdir(fname)
+
+def deltree(fname):
+    if not os.path.exists(fname):
+        return
+    for f in os.listdir(fname):
+        fullname = os.path.join(fname, f)
+        if os.path.isdir(fullname):
+            deltree(fullname)
+        else:
+            try:
+                os.unlink(fullname)
+            except:
+                pass
+    try:
+        os.rmdir(fname)
+    except:
+        pass
+
+class MhlibTests(unittest.TestCase):
+    def setUp(self):
+        deltree(_mhroot)
+        mkdirs(_mhpath)
+        writeProfile({'Path' : os.path.abspath(_mhpath),
+                      'Editor': 'emacs',
+                      'ignored-attribute': 'camping holiday'})
+        # Note: These headers aren't really conformant to RFC822, but
+        #  mhlib shouldn't care about that.
+
+        # An inbox with a couple of messages.
+        writeMessage('inbox', 1,
+                     {'From': 'Mrs. Premise',
+                      'To': 'Mrs. Conclusion',
+                      'Date': '18 July 2001'}, "Hullo, Mrs. Conclusion!\n")
+        writeMessage('inbox', 2,
+                     {'From': 'Mrs. Conclusion',
+                      'To': 'Mrs. Premise',
+                      'Date': '29 July 2001'}, "Hullo, Mrs. Premise!\n")
+
+        # A folder with many messages
+        for i in range(5, 101)+range(101, 201, 2):
+            writeMessage('wide', i,
+                         {'From': 'nowhere', 'Subject': 'message #%s' % i},
+                         "This is message number %s\n" % i)
+
+        # A deeply nested folder
+        def deep(folder, n):
+            writeMessage(folder, n,
+                         {'Subject': 'Message %s/%s' % (folder, n) },
+                         "This is message number %s in %s\n" % (n, folder) )
+        deep('deep/f1', 1)
+        deep('deep/f1', 2)
+        deep('deep/f1', 3)
+        deep('deep/f2', 4)
+        deep('deep/f2', 6)
+        deep('deep', 3)
+        deep('deep/f2/f3', 1)
+        deep('deep/f2/f3', 2)
+
+    def tearDown(self):
+        deltree(_mhroot)
+
+    def test_basic(self):
+        writeContext('inbox')
+        writeCurMessage('inbox', 2)
+        mh = getMH()
+
+        eq = self.assertEquals
+        eq(mh.getprofile('Editor'), 'emacs')
+        eq(mh.getprofile('not-set'), None)
+        eq(mh.getpath(), os.path.abspath(_mhpath))
+        eq(mh.getcontext(), 'inbox')
+
+        mh.setcontext('wide')
+        eq(mh.getcontext(), 'wide')
+        eq(readFile(os.path.join(_mhpath, 'context')),
+           "Current-Folder: wide\n")
+
+        mh.setcontext('inbox')
+
+        inbox = mh.openfolder('inbox')
+        eq(inbox.getfullname(),
+           os.path.join(os.path.abspath(_mhpath), 'inbox'))
+        eq(inbox.getsequencesfilename(),
+           os.path.join(os.path.abspath(_mhpath), 'inbox', '.mh_sequences'))
+        eq(inbox.getmessagefilename(1),
+           os.path.join(os.path.abspath(_mhpath), 'inbox', '1'))
+
+    def test_listfolders(self):
+        mh = getMH()
+        eq = self.assertEquals
+
+        folders = mh.listfolders()
+        folders.sort()
+        eq(folders, ['deep', 'inbox', 'wide'])
+
+        folders = mh.listallfolders()
+        folders.sort()
+        tfolders = map(normF, ['deep', 'deep/f1', 'deep/f2', 'deep/f2/f3',
+                                'inbox', 'wide'])
+        tfolders.sort()
+        eq(folders, tfolders)
+
+        folders = mh.listsubfolders('deep')
+        folders.sort()
+        eq(folders, map(normF, ['deep/f1', 'deep/f2']))
+
+        folders = mh.listallsubfolders('deep')
+        folders.sort()
+        eq(folders, map(normF, ['deep/f1', 'deep/f2', 'deep/f2/f3']))
+        eq(mh.listsubfolders(normF('deep/f2')), [normF('deep/f2/f3')])
+
+        eq(mh.listsubfolders('inbox'), [])
+        eq(mh.listallsubfolders('inbox'), [])
+
+    def test_sequence(self):
+        mh = getMH()
+        eq = self.assertEquals
+        writeCurMessage('wide', 55)
+
+        f = mh.openfolder('wide')
+        all = f.listmessages()
+        eq(all, range(5, 101)+range(101, 201, 2))
+        eq(f.getcurrent(), 55)
+        f.setcurrent(99)
+        eq(readFile(os.path.join(_mhpath, 'wide', '.mh_sequences')),
+           'cur: 99\n')
+
+        def seqeq(seq, val):
+            eq(f.parsesequence(seq), val)
+
+        seqeq('5-55', range(5, 56))
+        seqeq('90-108', range(90, 101)+range(101, 109, 2))
+        seqeq('90-108', range(90, 101)+range(101, 109, 2))
+
+        seqeq('10:10', range(10, 20))
+        seqeq('10:+10', range(10, 20))
+        seqeq('101:10', range(101, 121, 2))
+
+        seqeq('cur', [99])
+        seqeq('.', [99])
+        seqeq('prev', [98])
+        seqeq('next', [100])
+        seqeq('cur:-3', [97, 98, 99])
+        seqeq('first-cur', range(5, 100))
+        seqeq('150-last', range(151, 201, 2))
+        seqeq('prev-next', [98, 99, 100])
+
+        lowprimes = [5, 7, 11, 13, 17, 19, 23, 29]
+        lowcompos = [x for x in range(5, 31) if not x in lowprimes ]
+        f.putsequences({'cur': [5],
+                        'lowprime': lowprimes,
+                        'lowcompos': lowcompos})
+        seqs = readFile(os.path.join(_mhpath, 'wide', '.mh_sequences'))
+        seqs = sortLines(seqs)
+        eq(seqs, ["cur: 5",
+                  "lowcompos: 6 8-10 12 14-16 18 20-22 24-28 30",
+                  "lowprime: 5 7 11 13 17 19 23 29"])
+
+        seqeq('lowprime', lowprimes)
+        seqeq('lowprime:1', [5])
+        seqeq('lowprime:2', [5, 7])
+        seqeq('lowprime:-2', [23, 29])
+
+        ## Not supported
+        #seqeq('lowprime:first', [5])
+        #seqeq('lowprime:last', [29])
+        #seqeq('lowprime:prev', [29])
+        #seqeq('lowprime:next', [29])
+
+    def test_modify(self):
+        mh = getMH()
+        eq = self.assertEquals
+
+        mh.makefolder("dummy1")
+        self.assert_("dummy1" in mh.listfolders())
+        path = os.path.join(_mhpath, "dummy1")
+        self.assert_(os.path.exists(path))
+
+        f = mh.openfolder('dummy1')
+        def create(n):
+            msg = "From: foo\nSubject: %s\n\nDummy Message %s\n" % (n,n)
+            f.createmessage(n, StringIO.StringIO(msg))
+
+        create(7)
+        create(8)
+        create(9)
+
+        eq(readFile(f.getmessagefilename(9)),
+           "From: foo\nSubject: 9\n\nDummy Message 9\n")
+
+        eq(f.listmessages(), [7, 8, 9])
+        files = os.listdir(path)
+        files.sort()
+        eq(files, ['7', '8', '9'])
+
+        f.removemessages(['7', '8'])
+        files = os.listdir(path)
+        files.sort()
+        eq(files, [',7', ',8', '9'])
+        eq(f.listmessages(), [9])
+        create(10)
+        create(11)
+        create(12)
+
+        mh.makefolder("dummy2")
+        f2 = mh.openfolder("dummy2")
+        eq(f2.listmessages(), [])
+        f.movemessage(10, f2, 3)
+        f.movemessage(11, f2, 5)
+        eq(f.listmessages(), [9, 12])
+        eq(f2.listmessages(), [3, 5])
+        eq(readFile(f2.getmessagefilename(3)),
+           "From: foo\nSubject: 10\n\nDummy Message 10\n")
+
+        f.copymessage(9, f2, 4)
+        eq(f.listmessages(), [9, 12])
+        eq(readFile(f2.getmessagefilename(4)),
+           "From: foo\nSubject: 9\n\nDummy Message 9\n")
+
+        f.refilemessages([9, 12], f2)
+        eq(f.listmessages(), [])
+        eq(f2.listmessages(), [3, 4, 5, 6, 7])
+        eq(readFile(f2.getmessagefilename(7)),
+           "From: foo\nSubject: 12\n\nDummy Message 12\n")
+        # XXX This should check that _copysequences does the right thing.
+
+        mh.deletefolder('dummy1')
+        mh.deletefolder('dummy2')
+        self.assert_('dummy1' not in mh.listfolders())
+        self.assert_(not os.path.exists(path))
+
+    def test_read(self):
+        mh = getMH()
+        eq = self.assertEquals
+
+        f = mh.openfolder('inbox')
+        msg = f.openmessage(1)
+        # Check some basic stuff from rfc822
+        eq(msg.getheader('From'), "Mrs. Premise")
+        eq(msg.getheader('To'), "Mrs. Conclusion")
+
+        # Okay, we have the right message.  Let's check the stuff from
+        # mhlib.
+        lines = sortLines(msg.getheadertext())
+        eq(lines, ["Date: 18 July 2001",
+                   "From: Mrs. Premise",
+                   "To: Mrs. Conclusion"])
+        lines = sortLines(msg.getheadertext(lambda h: len(h)==4))
+        eq(lines, ["Date: 18 July 2001",
+                   "From: Mrs. Premise"])
+        eq(msg.getbodytext(), "Hullo, Mrs. Conclusion!\n\n")
+        eq(msg.getbodytext(0), "Hullo, Mrs. Conclusion!\n\n")
+
+        # XXXX there should be a better way to reclaim the file handle
+        msg.fp.close()
+        del msg
+
+
+def test_main():
+    run_unittest(MhlibTests)
+
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_mimetools.py
===================================================================
--- vendor/Python/current/Lib/test/test_mimetools.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_mimetools.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,50 @@
+import unittest
+from test import test_support
+
+import string, StringIO, mimetools
+
+msgtext1 = mimetools.Message(StringIO.StringIO(
+"""Content-Type: text/plain; charset=iso-8859-1; format=flowed
+Content-Transfer-Encoding: 8bit
+
+Foo!
+"""))
+
+class MimeToolsTest(unittest.TestCase):
+
+    def test_decodeencode(self):
+        start = string.ascii_letters + "=" + string.digits + "\n"
+        for enc in ['7bit','8bit','base64','quoted-printable',
+                    'uuencode', 'x-uuencode', 'uue', 'x-uue']:
+            i = StringIO.StringIO(start)
+            o = StringIO.StringIO()
+            mimetools.encode(i, o, enc)
+            i = StringIO.StringIO(o.getvalue())
+            o = StringIO.StringIO()
+            mimetools.decode(i, o, enc)
+            self.assertEqual(o.getvalue(), start)
+
+    def test_boundary(self):
+        s = set([""])
+        for i in xrange(100):
+            nb = mimetools.choose_boundary()
+            self.assert_(nb not in s)
+            s.add(nb)
+
+    def test_message(self):
+        msg = mimetools.Message(StringIO.StringIO(msgtext1))
+        self.assertEqual(msg.gettype(), "text/plain")
+        self.assertEqual(msg.getmaintype(), "text")
+        self.assertEqual(msg.getsubtype(), "plain")
+        self.assertEqual(msg.getplist(), ["charset=iso-8859-1", "format=flowed"])
+        self.assertEqual(msg.getparamnames(), ["charset", "format"])
+        self.assertEqual(msg.getparam("charset"), "iso-8859-1")
+        self.assertEqual(msg.getparam("format"), "flowed")
+        self.assertEqual(msg.getparam("spam"), None)
+        self.assertEqual(msg.getencoding(), "8bit")
+
+def test_main():
+    test_support.run_unittest(MimeToolsTest)
+
+if __name__=="__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_mimetypes.py
===================================================================
--- vendor/Python/current/Lib/test/test_mimetypes.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_mimetypes.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,70 @@
+import mimetypes
+import StringIO
+import unittest
+
+from test import test_support
+
+# Tell it we don't know about external files:
+mimetypes.knownfiles = []
+mimetypes.inited = False
+mimetypes._default_mime_types()
+
+
+class MimeTypesTestCase(unittest.TestCase):
+    def setUp(self):
+        self.db = mimetypes.MimeTypes()
+
+    def test_default_data(self):
+        eq = self.assertEqual
+        eq(self.db.guess_type("foo.html"), ("text/html", None))
+        eq(self.db.guess_type("foo.tgz"), ("application/x-tar", "gzip"))
+        eq(self.db.guess_type("foo.tar.gz"), ("application/x-tar", "gzip"))
+        eq(self.db.guess_type("foo.tar.Z"), ("application/x-tar", "compress"))
+
+    def test_data_urls(self):
+        eq = self.assertEqual
+        guess_type = self.db.guess_type
+        eq(guess_type("data:,thisIsTextPlain"), ("text/plain", None))
+        eq(guess_type("data:;base64,thisIsTextPlain"), ("text/plain", None))
+        eq(guess_type("data:text/x-foo,thisIsTextXFoo"), ("text/x-foo", None))
+
+    def test_file_parsing(self):
+        eq = self.assertEqual
+        sio = StringIO.StringIO("x-application/x-unittest pyunit\n")
+        self.db.readfp(sio)
+        eq(self.db.guess_type("foo.pyunit"),
+           ("x-application/x-unittest", None))
+        eq(self.db.guess_extension("x-application/x-unittest"), ".pyunit")
+
+    def test_non_standard_types(self):
+        eq = self.assertEqual
+        # First try strict
+        eq(self.db.guess_type('foo.xul', strict=True), (None, None))
+        eq(self.db.guess_extension('image/jpg', strict=True), None)
+        # And then non-strict
+        eq(self.db.guess_type('foo.xul', strict=False), ('text/xul', None))
+        eq(self.db.guess_extension('image/jpg', strict=False), '.jpg')
+
+    def test_guess_all_types(self):
+        eq = self.assertEqual
+        unless = self.failUnless
+        # First try strict.  Use a set here for testing the results because if
+        # test_urllib2 is run before test_mimetypes, global state is modified
+        # such that the 'all' set will have more items in it.
+        all = set(self.db.guess_all_extensions('text/plain', strict=True))
+        unless(all >= set(['.bat', '.c', '.h', '.ksh', '.pl', '.txt']))
+        # And now non-strict
+        all = self.db.guess_all_extensions('image/jpg', strict=False)
+        all.sort()
+        eq(all, ['.jpg'])
+        # And now for no hits
+        all = self.db.guess_all_extensions('image/jpg', strict=True)
+        eq(all, [])
+
+
+def test_main():
+    test_support.run_unittest(MimeTypesTestCase)
+
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_minidom.py
===================================================================
--- vendor/Python/current/Lib/test/test_minidom.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_minidom.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1397 @@
+# test for xml.dom.minidom
+
+import os
+import sys
+import pickle
+import traceback
+from StringIO import StringIO
+from test.test_support import verbose
+
+import xml.dom
+import xml.dom.minidom
+import xml.parsers.expat
+
+from xml.dom.minidom import parse, Node, Document, parseString
+from xml.dom.minidom import getDOMImplementation
+
+
+if __name__ == "__main__":
+    base = sys.argv[0]
+else:
+    base = __file__
+tstfile = os.path.join(os.path.dirname(base), "test"+os.extsep+"xml")
+del base
+
+def confirm(test, testname = "Test"):
+    if not test:
+        print "Failed " + testname
+        raise Exception
+
+def testParseFromFile():
+    dom = parse(StringIO(open(tstfile).read()))
+    dom.unlink()
+    confirm(isinstance(dom,Document))
+
+def testGetElementsByTagName():
+    dom = parse(tstfile)
+    confirm(dom.getElementsByTagName("LI") == \
+            dom.documentElement.getElementsByTagName("LI"))
+    dom.unlink()
+
+def testInsertBefore():
+    dom = parseString("<doc><foo/></doc>")
+    root = dom.documentElement
+    elem = root.childNodes[0]
+    nelem = dom.createElement("element")
+    root.insertBefore(nelem, elem)
+    confirm(len(root.childNodes) == 2
+            and root.childNodes.length == 2
+            and root.childNodes[0] is nelem
+            and root.childNodes.item(0) is nelem
+            and root.childNodes[1] is elem
+            and root.childNodes.item(1) is elem
+            and root.firstChild is nelem
+            and root.lastChild is elem
+            and root.toxml() == "<doc><element/><foo/></doc>"
+            , "testInsertBefore -- node properly placed in tree")
+    nelem = dom.createElement("element")
+    root.insertBefore(nelem, None)
+    confirm(len(root.childNodes) == 3
+            and root.childNodes.length == 3
+            and root.childNodes[1] is elem
+            and root.childNodes.item(1) is elem
+            and root.childNodes[2] is nelem
+            and root.childNodes.item(2) is nelem
+            and root.lastChild is nelem
+            and nelem.previousSibling is elem
+            and root.toxml() == "<doc><element/><foo/><element/></doc>"
+            , "testInsertBefore -- node properly placed in tree")
+    nelem2 = dom.createElement("bar")
+    root.insertBefore(nelem2, nelem)
+    confirm(len(root.childNodes) == 4
+            and root.childNodes.length == 4
+            and root.childNodes[2] is nelem2
+            and root.childNodes.item(2) is nelem2
+            and root.childNodes[3] is nelem
+            and root.childNodes.item(3) is nelem
+            and nelem2.nextSibling is nelem
+            and nelem.previousSibling is nelem2
+            and root.toxml() == "<doc><element/><foo/><bar/><element/></doc>"
+            , "testInsertBefore -- node properly placed in tree")
+    dom.unlink()
+
+def _create_fragment_test_nodes():
+    dom = parseString("<doc/>")
+    orig = dom.createTextNode("original")
+    c1 = dom.createTextNode("foo")
+    c2 = dom.createTextNode("bar")
+    c3 = dom.createTextNode("bat")
+    dom.documentElement.appendChild(orig)
+    frag = dom.createDocumentFragment()
+    frag.appendChild(c1)
+    frag.appendChild(c2)
+    frag.appendChild(c3)
+    return dom, orig, c1, c2, c3, frag
+
+def testInsertBeforeFragment():
+    dom, orig, c1, c2, c3, frag = _create_fragment_test_nodes()
+    dom.documentElement.insertBefore(frag, None)
+    confirm(tuple(dom.documentElement.childNodes) == (orig, c1, c2, c3),
+            "insertBefore(<fragment>, None)")
+    frag.unlink()
+    dom.unlink()
+    #
+    dom, orig, c1, c2, c3, frag = _create_fragment_test_nodes()
+    dom.documentElement.insertBefore(frag, orig)
+    confirm(tuple(dom.documentElement.childNodes) == (c1, c2, c3, orig),
+            "insertBefore(<fragment>, orig)")
+    frag.unlink()
+    dom.unlink()
+
+def testAppendChild():
+    dom = parse(tstfile)
+    dom.documentElement.appendChild(dom.createComment(u"Hello"))
+    confirm(dom.documentElement.childNodes[-1].nodeName == "#comment")
+    confirm(dom.documentElement.childNodes[-1].data == "Hello")
+    dom.unlink()
+
+def testAppendChildFragment():
+    dom, orig, c1, c2, c3, frag = _create_fragment_test_nodes()
+    dom.documentElement.appendChild(frag)
+    confirm(tuple(dom.documentElement.childNodes) == (orig, c1, c2, c3),
+            "appendChild(<fragment>)")
+    frag.unlink()
+    dom.unlink()
+
+def testReplaceChildFragment():
+    dom, orig, c1, c2, c3, frag = _create_fragment_test_nodes()
+    dom.documentElement.replaceChild(frag, orig)
+    orig.unlink()
+    confirm(tuple(dom.documentElement.childNodes) == (c1, c2, c3),
+            "replaceChild(<fragment>)")
+    frag.unlink()
+    dom.unlink()
+
+def testLegalChildren():
+    dom = Document()
+    elem = dom.createElement('element')
+    text = dom.createTextNode('text')
+
+    try: dom.appendChild(text)
+    except xml.dom.HierarchyRequestErr: pass
+    else:
+        print "dom.appendChild didn't raise HierarchyRequestErr"
+
+    dom.appendChild(elem)
+    try: dom.insertBefore(text, elem)
+    except xml.dom.HierarchyRequestErr: pass
+    else:
+        print "dom.appendChild didn't raise HierarchyRequestErr"
+
+    try: dom.replaceChild(text, elem)
+    except xml.dom.HierarchyRequestErr: pass
+    else:
+        print "dom.appendChild didn't raise HierarchyRequestErr"
+
+    nodemap = elem.attributes
+    try: nodemap.setNamedItem(text)
+    except xml.dom.HierarchyRequestErr: pass
+    else:
+        print "NamedNodeMap.setNamedItem didn't raise HierarchyRequestErr"
+
+    try: nodemap.setNamedItemNS(text)
+    except xml.dom.HierarchyRequestErr: pass
+    else:
+        print "NamedNodeMap.setNamedItemNS didn't raise HierarchyRequestErr"
+
+    elem.appendChild(text)
+    dom.unlink()
+
+def testNamedNodeMapSetItem():
+    dom = Document()
+    elem = dom.createElement('element')
+    attrs = elem.attributes
+    attrs["foo"] = "bar"
+    a = attrs.item(0)
+    confirm(a.ownerDocument is dom,
+            "NamedNodeMap.__setitem__() sets ownerDocument")
+    confirm(a.ownerElement is elem,
+            "NamedNodeMap.__setitem__() sets ownerElement")
+    confirm(a.value == "bar",
+            "NamedNodeMap.__setitem__() sets value")
+    confirm(a.nodeValue == "bar",
+            "NamedNodeMap.__setitem__() sets nodeValue")
+    elem.unlink()
+    dom.unlink()
+
+def testNonZero():
+    dom = parse(tstfile)
+    confirm(dom)# should not be zero
+    dom.appendChild(dom.createComment("foo"))
+    confirm(not dom.childNodes[-1].childNodes)
+    dom.unlink()
+
+def testUnlink():
+    dom = parse(tstfile)
+    dom.unlink()
+
+def testElement():
+    dom = Document()
+    dom.appendChild(dom.createElement("abc"))
+    confirm(dom.documentElement)
+    dom.unlink()
+
+def testAAA():
+    dom = parseString("<abc/>")
+    el = dom.documentElement
+    el.setAttribute("spam", "jam2")
+    confirm(el.toxml() == '<abc spam="jam2"/>', "testAAA")
+    a = el.getAttributeNode("spam")
+    confirm(a.ownerDocument is dom,
+            "setAttribute() sets ownerDocument")
+    confirm(a.ownerElement is dom.documentElement,
+            "setAttribute() sets ownerElement")
+    dom.unlink()
+
+def testAAB():
+    dom = parseString("<abc/>")
+    el = dom.documentElement
+    el.setAttribute("spam", "jam")
+    el.setAttribute("spam", "jam2")
+    confirm(el.toxml() == '<abc spam="jam2"/>', "testAAB")
+    dom.unlink()
+
+def testAddAttr():
+    dom = Document()
+    child = dom.appendChild(dom.createElement("abc"))
+
+    child.setAttribute("def", "ghi")
+    confirm(child.getAttribute("def") == "ghi")
+    confirm(child.attributes["def"].value == "ghi")
+
+    child.setAttribute("jkl", "mno")
+    confirm(child.getAttribute("jkl") == "mno")
+    confirm(child.attributes["jkl"].value == "mno")
+
+    confirm(len(child.attributes) == 2)
+
+    child.setAttribute("def", "newval")
+    confirm(child.getAttribute("def") == "newval")
+    confirm(child.attributes["def"].value == "newval")
+
+    confirm(len(child.attributes) == 2)
+    dom.unlink()
+
+def testDeleteAttr():
+    dom = Document()
+    child = dom.appendChild(dom.createElement("abc"))
+
+    confirm(len(child.attributes) == 0)
+    child.setAttribute("def", "ghi")
+    confirm(len(child.attributes) == 1)
+    del child.attributes["def"]
+    confirm(len(child.attributes) == 0)
+    dom.unlink()
+
+def testRemoveAttr():
+    dom = Document()
+    child = dom.appendChild(dom.createElement("abc"))
+
+    child.setAttribute("def", "ghi")
+    confirm(len(child.attributes) == 1)
+    child.removeAttribute("def")
+    confirm(len(child.attributes) == 0)
+
+    dom.unlink()
+
+def testRemoveAttrNS():
+    dom = Document()
+    child = dom.appendChild(
+            dom.createElementNS("http://www.python.org", "python:abc"))
+    child.setAttributeNS("http://www.w3.org", "xmlns:python",
+                                            "http://www.python.org")
+    child.setAttributeNS("http://www.python.org", "python:abcattr", "foo")
+    confirm(len(child.attributes) == 2)
+    child.removeAttributeNS("http://www.python.org", "abcattr")
+    confirm(len(child.attributes) == 1)
+
+    dom.unlink()
+
+def testRemoveAttributeNode():
+    dom = Document()
+    child = dom.appendChild(dom.createElement("foo"))
+    child.setAttribute("spam", "jam")
+    confirm(len(child.attributes) == 1)
+    node = child.getAttributeNode("spam")
+    child.removeAttributeNode(node)
+    confirm(len(child.attributes) == 0
+            and child.getAttributeNode("spam") is None)
+
+    dom.unlink()
+
+def testChangeAttr():
+    dom = parseString("<abc/>")
+    el = dom.documentElement
+    el.setAttribute("spam", "jam")
+    confirm(len(el.attributes) == 1)
+    el.setAttribute("spam", "bam")
+    # Set this attribute to be an ID and make sure that doesn't change
+    # when changing the value:
+    el.setIdAttribute("spam")
+    confirm(len(el.attributes) == 1
+            and el.attributes["spam"].value == "bam"
+            and el.attributes["spam"].nodeValue == "bam"
+            and el.getAttribute("spam") == "bam"
+            and el.getAttributeNode("spam").isId)
+    el.attributes["spam"] = "ham"
+    confirm(len(el.attributes) == 1
+            and el.attributes["spam"].value == "ham"
+            and el.attributes["spam"].nodeValue == "ham"
+            and el.getAttribute("spam") == "ham"
+            and el.attributes["spam"].isId)
+    el.setAttribute("spam2", "bam")
+    confirm(len(el.attributes) == 2
+            and el.attributes["spam"].value == "ham"
+            and el.attributes["spam"].nodeValue == "ham"
+            and el.getAttribute("spam") == "ham"
+            and el.attributes["spam2"].value == "bam"
+            and el.attributes["spam2"].nodeValue == "bam"
+            and el.getAttribute("spam2") == "bam")
+    el.attributes["spam2"] = "bam2"
+    confirm(len(el.attributes) == 2
+            and el.attributes["spam"].value == "ham"
+            and el.attributes["spam"].nodeValue == "ham"
+            and el.getAttribute("spam") == "ham"
+            and el.attributes["spam2"].value == "bam2"
+            and el.attributes["spam2"].nodeValue == "bam2"
+            and el.getAttribute("spam2") == "bam2")
+    dom.unlink()
+
+def testGetAttrList():
+    pass
+
+def testGetAttrValues(): pass
+
+def testGetAttrLength(): pass
+
+def testGetAttribute(): pass
+
+def testGetAttributeNS(): pass
+
+def testGetAttributeNode(): pass
+
+def testGetElementsByTagNameNS():
+    d="""<foo xmlns:minidom='http://pyxml.sf.net/minidom'>
+    <minidom:myelem/>
+    </foo>"""
+    dom = parseString(d)
+    elems = dom.getElementsByTagNameNS("http://pyxml.sf.net/minidom", "myelem")
+    confirm(len(elems) == 1
+            and elems[0].namespaceURI == "http://pyxml.sf.net/minidom"
+            and elems[0].localName == "myelem"
+            and elems[0].prefix == "minidom"
+            and elems[0].tagName == "minidom:myelem"
+            and elems[0].nodeName == "minidom:myelem")
+    dom.unlink()
+
+def get_empty_nodelist_from_elements_by_tagName_ns_helper(doc, nsuri, lname):
+    nodelist = doc.getElementsByTagNameNS(nsuri, lname)
+    confirm(len(nodelist) == 0)
+
+def testGetEmptyNodeListFromElementsByTagNameNS():
+    doc = parseString('<doc/>')
+    get_empty_nodelist_from_elements_by_tagName_ns_helper(
+        doc, 'http://xml.python.org/namespaces/a', 'localname')
+    get_empty_nodelist_from_elements_by_tagName_ns_helper(
+        doc, '*', 'splat')
+    get_empty_nodelist_from_elements_by_tagName_ns_helper(
+        doc, 'http://xml.python.org/namespaces/a', '*')
+
+    doc = parseString('<doc xmlns="http://xml.python.org/splat"><e/></doc>')
+    get_empty_nodelist_from_elements_by_tagName_ns_helper(
+        doc, "http://xml.python.org/splat", "not-there")
+    get_empty_nodelist_from_elements_by_tagName_ns_helper(
+        doc, "*", "not-there")
+    get_empty_nodelist_from_elements_by_tagName_ns_helper(
+        doc, "http://somewhere.else.net/not-there", "e")
+
+def testElementReprAndStr():
+    dom = Document()
+    el = dom.appendChild(dom.createElement("abc"))
+    string1 = repr(el)
+    string2 = str(el)
+    confirm(string1 == string2)
+    dom.unlink()
+
+# commented out until Fredrick's fix is checked in
+def _testElementReprAndStrUnicode():
+    dom = Document()
+    el = dom.appendChild(dom.createElement(u"abc"))
+    string1 = repr(el)
+    string2 = str(el)
+    confirm(string1 == string2)
+    dom.unlink()
+
+# commented out until Fredrick's fix is checked in
+def _testElementReprAndStrUnicodeNS():
+    dom = Document()
+    el = dom.appendChild(
+        dom.createElementNS(u"http://www.slashdot.org", u"slash:abc"))
+    string1 = repr(el)
+    string2 = str(el)
+    confirm(string1 == string2)
+    confirm(string1.find("slash:abc") != -1)
+    dom.unlink()
+
+def testAttributeRepr():
+    dom = Document()
+    el = dom.appendChild(dom.createElement(u"abc"))
+    node = el.setAttribute("abc", "def")
+    confirm(str(node) == repr(node))
+    dom.unlink()
+
+def testTextNodeRepr(): pass
+
+def testWriteXML():
+    str = '<?xml version="1.0" ?><a b="c"/>'
+    dom = parseString(str)
+    domstr = dom.toxml()
+    dom.unlink()
+    confirm(str == domstr)
+
+def testAltNewline():
+    str = '<?xml version="1.0" ?>\n<a b="c"/>\n'
+    dom = parseString(str)
+    domstr = dom.toprettyxml(newl="\r\n")
+    dom.unlink()
+    confirm(domstr == str.replace("\n", "\r\n"))
+
+def testProcessingInstruction():
+    dom = parseString('<e><?mypi \t\n data \t\n ?></e>')
+    pi = dom.documentElement.firstChild
+    confirm(pi.target == "mypi"
+            and pi.data == "data \t\n "
+            and pi.nodeName == "mypi"
+            and pi.nodeType == Node.PROCESSING_INSTRUCTION_NODE
+            and pi.attributes is None
+            and not pi.hasChildNodes()
+            and len(pi.childNodes) == 0
+            and pi.firstChild is None
+            and pi.lastChild is None
+            and pi.localName is None
+            and pi.namespaceURI == xml.dom.EMPTY_NAMESPACE)
+
+def testProcessingInstructionRepr(): pass
+
+def testTextRepr(): pass
+
+def testWriteText(): pass
+
+def testDocumentElement(): pass
+
+def testTooManyDocumentElements():
+    doc = parseString("<doc/>")
+    elem = doc.createElement("extra")
+    try:
+        doc.appendChild(elem)
+    except xml.dom.HierarchyRequestErr:
+        pass
+    else:
+        print "Failed to catch expected exception when" \
+              " adding extra document element."
+    elem.unlink()
+    doc.unlink()
+
+def testCreateElementNS(): pass
+
+def testCreateAttributeNS(): pass
+
+def testParse(): pass
+
+def testParseString(): pass
+
+def testComment(): pass
+
+def testAttrListItem(): pass
+
+def testAttrListItems(): pass
+
+def testAttrListItemNS(): pass
+
+def testAttrListKeys(): pass
+
+def testAttrListKeysNS(): pass
+
+def testRemoveNamedItem():
+    doc = parseString("<doc a=''/>")
+    e = doc.documentElement
+    attrs = e.attributes
+    a1 = e.getAttributeNode("a")
+    a2 = attrs.removeNamedItem("a")
+    confirm(a1.isSameNode(a2))
+    try:
+        attrs.removeNamedItem("a")
+    except xml.dom.NotFoundErr:
+        pass
+
+def testRemoveNamedItemNS():
+    doc = parseString("<doc xmlns:a='http://xml.python.org/' a:b=''/>")
+    e = doc.documentElement
+    attrs = e.attributes
+    a1 = e.getAttributeNodeNS("http://xml.python.org/", "b")
+    a2 = attrs.removeNamedItemNS("http://xml.python.org/", "b")
+    confirm(a1.isSameNode(a2))
+    try:
+        attrs.removeNamedItemNS("http://xml.python.org/", "b")
+    except xml.dom.NotFoundErr:
+        pass
+
+def testAttrListValues(): pass
+
+def testAttrListLength(): pass
+
+def testAttrList__getitem__(): pass
+
+def testAttrList__setitem__(): pass
+
+def testSetAttrValueandNodeValue(): pass
+
+def testParseElement(): pass
+
+def testParseAttributes(): pass
+
+def testParseElementNamespaces(): pass
+
+def testParseAttributeNamespaces(): pass
+
+def testParseProcessingInstructions(): pass
+
+def testChildNodes(): pass
+
+def testFirstChild(): pass
+
+def testHasChildNodes(): pass
+
+def testCloneElementShallow():
+    dom, clone = _setupCloneElement(0)
+    confirm(len(clone.childNodes) == 0
+            and clone.childNodes.length == 0
+            and clone.parentNode is None
+            and clone.toxml() == '<doc attr="value"/>'
+            , "testCloneElementShallow")
+    dom.unlink()
+
+def testCloneElementDeep():
+    dom, clone = _setupCloneElement(1)
+    confirm(len(clone.childNodes) == 1
+            and clone.childNodes.length == 1
+            and clone.parentNode is None
+            and clone.toxml() == '<doc attr="value"><foo/></doc>'
+            , "testCloneElementDeep")
+    dom.unlink()
+
+def _setupCloneElement(deep):
+    dom = parseString("<doc attr='value'><foo/></doc>")
+    root = dom.documentElement
+    clone = root.cloneNode(deep)
+    _testCloneElementCopiesAttributes(
+        root, clone, "testCloneElement" + (deep and "Deep" or "Shallow"))
+    # mutilate the original so shared data is detected
+    root.tagName = root.nodeName = "MODIFIED"
+    root.setAttribute("attr", "NEW VALUE")
+    root.setAttribute("added", "VALUE")
+    return dom, clone
+
+def _testCloneElementCopiesAttributes(e1, e2, test):
+    attrs1 = e1.attributes
+    attrs2 = e2.attributes
+    keys1 = attrs1.keys()
+    keys2 = attrs2.keys()
+    keys1.sort()
+    keys2.sort()
+    confirm(keys1 == keys2, "clone of element has same attribute keys")
+    for i in range(len(keys1)):
+        a1 = attrs1.item(i)
+        a2 = attrs2.item(i)
+        confirm(a1 is not a2
+                and a1.value == a2.value
+                and a1.nodeValue == a2.nodeValue
+                and a1.namespaceURI == a2.namespaceURI
+                and a1.localName == a2.localName
+                , "clone of attribute node has proper attribute values")
+        confirm(a2.ownerElement is e2,
+                "clone of attribute node correctly owned")
+
+def testCloneDocumentShallow():
+    doc = parseString("<?xml version='1.0'?>\n"
+                      "<!-- comment -->"
+                      "<!DOCTYPE doc [\n"
+                      "<!NOTATION notation SYSTEM 'http://xml.python.org/'>\n"
+                      "]>\n"
+                      "<doc attr='value'/>")
+    doc2 = doc.cloneNode(0)
+    confirm(doc2 is None,
+            "testCloneDocumentShallow:"
+            " shallow cloning of documents makes no sense!")
+
+def testCloneDocumentDeep():
+    doc = parseString("<?xml version='1.0'?>\n"
+                      "<!-- comment -->"
+                      "<!DOCTYPE doc [\n"
+                      "<!NOTATION notation SYSTEM 'http://xml.python.org/'>\n"
+                      "]>\n"
+                      "<doc attr='value'/>")
+    doc2 = doc.cloneNode(1)
+    confirm(not (doc.isSameNode(doc2) or doc2.isSameNode(doc)),
+            "testCloneDocumentDeep: document objects not distinct")
+    confirm(len(doc.childNodes) == len(doc2.childNodes),
+            "testCloneDocumentDeep: wrong number of Document children")
+    confirm(doc2.documentElement.nodeType == Node.ELEMENT_NODE,
+            "testCloneDocumentDeep: documentElement not an ELEMENT_NODE")
+    confirm(doc2.documentElement.ownerDocument.isSameNode(doc2),
+            "testCloneDocumentDeep: documentElement owner is not new document")
+    confirm(not doc.documentElement.isSameNode(doc2.documentElement),
+            "testCloneDocumentDeep: documentElement should not be shared")
+    if doc.doctype is not None:
+        # check the doctype iff the original DOM maintained it
+        confirm(doc2.doctype.nodeType == Node.DOCUMENT_TYPE_NODE,
+                "testCloneDocumentDeep: doctype not a DOCUMENT_TYPE_NODE")
+        confirm(doc2.doctype.ownerDocument.isSameNode(doc2))
+        confirm(not doc.doctype.isSameNode(doc2.doctype))
+
+def testCloneDocumentTypeDeepOk():
+    doctype = create_nonempty_doctype()
+    clone = doctype.cloneNode(1)
+    confirm(clone is not None
+            and clone.nodeName == doctype.nodeName
+            and clone.name == doctype.name
+            and clone.publicId == doctype.publicId
+            and clone.systemId == doctype.systemId
+            and len(clone.entities) == len(doctype.entities)
+            and clone.entities.item(len(clone.entities)) is None
+            and len(clone.notations) == len(doctype.notations)
+            and clone.notations.item(len(clone.notations)) is None
+            and len(clone.childNodes) == 0)
+    for i in range(len(doctype.entities)):
+        se = doctype.entities.item(i)
+        ce = clone.entities.item(i)
+        confirm((not se.isSameNode(ce))
+                and (not ce.isSameNode(se))
+                and ce.nodeName == se.nodeName
+                and ce.notationName == se.notationName
+                and ce.publicId == se.publicId
+                and ce.systemId == se.systemId
+                and ce.encoding == se.encoding
+                and ce.actualEncoding == se.actualEncoding
+                and ce.version == se.version)
+    for i in range(len(doctype.notations)):
+        sn = doctype.notations.item(i)
+        cn = clone.notations.item(i)
+        confirm((not sn.isSameNode(cn))
+                and (not cn.isSameNode(sn))
+                and cn.nodeName == sn.nodeName
+                and cn.publicId == sn.publicId
+                and cn.systemId == sn.systemId)
+
+def testCloneDocumentTypeDeepNotOk():
+    doc = create_doc_with_doctype()
+    clone = doc.doctype.cloneNode(1)
+    confirm(clone is None, "testCloneDocumentTypeDeepNotOk")
+
+def testCloneDocumentTypeShallowOk():
+    doctype = create_nonempty_doctype()
+    clone = doctype.cloneNode(0)
+    confirm(clone is not None
+            and clone.nodeName == doctype.nodeName
+            and clone.name == doctype.name
+            and clone.publicId == doctype.publicId
+            and clone.systemId == doctype.systemId
+            and len(clone.entities) == 0
+            and clone.entities.item(0) is None
+            and len(clone.notations) == 0
+            and clone.notations.item(0) is None
+            and len(clone.childNodes) == 0)
+
+def testCloneDocumentTypeShallowNotOk():
+    doc = create_doc_with_doctype()
+    clone = doc.doctype.cloneNode(0)
+    confirm(clone is None, "testCloneDocumentTypeShallowNotOk")
+
+def check_import_document(deep, testName):
+    doc1 = parseString("<doc/>")
+    doc2 = parseString("<doc/>")
+    try:
+        doc1.importNode(doc2, deep)
+    except xml.dom.NotSupportedErr:
+        pass
+    else:
+        raise Exception(testName +
+                        ": expected NotSupportedErr when importing a document")
+
+def testImportDocumentShallow():
+    check_import_document(0, "testImportDocumentShallow")
+
+def testImportDocumentDeep():
+    check_import_document(1, "testImportDocumentDeep")
+
+# The tests of DocumentType importing use these helpers to construct
+# the documents to work with, since not all DOM builders actually
+# create the DocumentType nodes.
+
+def create_doc_without_doctype(doctype=None):
+    return getDOMImplementation().createDocument(None, "doc", doctype)
+
+def create_nonempty_doctype():
+    doctype = getDOMImplementation().createDocumentType("doc", None, None)
+    doctype.entities._seq = []
+    doctype.notations._seq = []
+    notation = xml.dom.minidom.Notation("my-notation", None,
+                                        "http://xml.python.org/notations/my")
+    doctype.notations._seq.append(notation)
+    entity = xml.dom.minidom.Entity("my-entity", None,
+                                    "http://xml.python.org/entities/my",
+                                    "my-notation")
+    entity.version = "1.0"
+    entity.encoding = "utf-8"
+    entity.actualEncoding = "us-ascii"
+    doctype.entities._seq.append(entity)
+    return doctype
+
+def create_doc_with_doctype():
+    doctype = create_nonempty_doctype()
+    doc = create_doc_without_doctype(doctype)
+    doctype.entities.item(0).ownerDocument = doc
+    doctype.notations.item(0).ownerDocument = doc
+    return doc
+
+def testImportDocumentTypeShallow():
+    src = create_doc_with_doctype()
+    target = create_doc_without_doctype()
+    try:
+        imported = target.importNode(src.doctype, 0)
+    except xml.dom.NotSupportedErr:
+        pass
+    else:
+        raise Exception(
+            "testImportDocumentTypeShallow: expected NotSupportedErr")
+
+def testImportDocumentTypeDeep():
+    src = create_doc_with_doctype()
+    target = create_doc_without_doctype()
+    try:
+        imported = target.importNode(src.doctype, 1)
+    except xml.dom.NotSupportedErr:
+        pass
+    else:
+        raise Exception(
+            "testImportDocumentTypeDeep: expected NotSupportedErr")
+
+# Testing attribute clones uses a helper, and should always be deep,
+# even if the argument to cloneNode is false.
+def check_clone_attribute(deep, testName):
+    doc = parseString("<doc attr='value'/>")
+    attr = doc.documentElement.getAttributeNode("attr")
+    assert attr is not None
+    clone = attr.cloneNode(deep)
+    confirm(not clone.isSameNode(attr))
+    confirm(not attr.isSameNode(clone))
+    confirm(clone.ownerElement is None,
+            testName + ": ownerElement should be None")
+    confirm(clone.ownerDocument.isSameNode(attr.ownerDocument),
+            testName + ": ownerDocument does not match")
+    confirm(clone.specified,
+            testName + ": cloned attribute must have specified == True")
+
+def testCloneAttributeShallow():
+    check_clone_attribute(0, "testCloneAttributeShallow")
+
+def testCloneAttributeDeep():
+    check_clone_attribute(1, "testCloneAttributeDeep")
+
+def check_clone_pi(deep, testName):
+    doc = parseString("<?target data?><doc/>")
+    pi = doc.firstChild
+    assert pi.nodeType == Node.PROCESSING_INSTRUCTION_NODE
+    clone = pi.cloneNode(deep)
+    confirm(clone.target == pi.target
+            and clone.data == pi.data)
+
+def testClonePIShallow():
+    check_clone_pi(0, "testClonePIShallow")
+
+def testClonePIDeep():
+    check_clone_pi(1, "testClonePIDeep")
+
+def testNormalize():
+    doc = parseString("<doc/>")
+    root = doc.documentElement
+    root.appendChild(doc.createTextNode("first"))
+    root.appendChild(doc.createTextNode("second"))
+    confirm(len(root.childNodes) == 2
+            and root.childNodes.length == 2, "testNormalize -- preparation")
+    doc.normalize()
+    confirm(len(root.childNodes) == 1
+            and root.childNodes.length == 1
+            and root.firstChild is root.lastChild
+            and root.firstChild.data == "firstsecond"
+            , "testNormalize -- result")
+    doc.unlink()
+
+    doc = parseString("<doc/>")
+    root = doc.documentElement
+    root.appendChild(doc.createTextNode(""))
+    doc.normalize()
+    confirm(len(root.childNodes) == 0
+            and root.childNodes.length == 0,
+            "testNormalize -- single empty node removed")
+    doc.unlink()
+
+def testSiblings():
+    doc = parseString("<doc><?pi?>text?<elm/></doc>")
+    root = doc.documentElement
+    (pi, text, elm) = root.childNodes
+
+    confirm(pi.nextSibling is text and
+            pi.previousSibling is None and
+            text.nextSibling is elm and
+            text.previousSibling is pi and
+            elm.nextSibling is None and
+            elm.previousSibling is text, "testSiblings")
+
+    doc.unlink()
+
+def testParents():
+    doc = parseString("<doc><elm1><elm2/><elm2><elm3/></elm2></elm1></doc>")
+    root = doc.documentElement
+    elm1 = root.childNodes[0]
+    (elm2a, elm2b) = elm1.childNodes
+    elm3 = elm2b.childNodes[0]
+
+    confirm(root.parentNode is doc and
+            elm1.parentNode is root and
+            elm2a.parentNode is elm1 and
+            elm2b.parentNode is elm1 and
+            elm3.parentNode is elm2b, "testParents")
+
+    doc.unlink()
+
+def testNodeListItem():
+    doc = parseString("<doc><e/><e/></doc>")
+    children = doc.childNodes
+    docelem = children[0]
+    confirm(children[0] is children.item(0)
+            and children.item(1) is None
+            and docelem.childNodes.item(0) is docelem.childNodes[0]
+            and docelem.childNodes.item(1) is docelem.childNodes[1]
+            and docelem.childNodes.item(0).childNodes.item(0) is None,
+            "test NodeList.item()")
+    doc.unlink()
+
+def testSAX2DOM():
+    from xml.dom import pulldom
+
+    sax2dom = pulldom.SAX2DOM()
+    sax2dom.startDocument()
+    sax2dom.startElement("doc", {})
+    sax2dom.characters("text")
+    sax2dom.startElement("subelm", {})
+    sax2dom.characters("text")
+    sax2dom.endElement("subelm")
+    sax2dom.characters("text")
+    sax2dom.endElement("doc")
+    sax2dom.endDocument()
+
+    doc = sax2dom.document
+    root = doc.documentElement
+    (text1, elm1, text2) = root.childNodes
+    text3 = elm1.childNodes[0]
+
+    confirm(text1.previousSibling is None and
+            text1.nextSibling is elm1 and
+            elm1.previousSibling is text1 and
+            elm1.nextSibling is text2 and
+            text2.previousSibling is elm1 and
+            text2.nextSibling is None and
+            text3.previousSibling is None and
+            text3.nextSibling is None, "testSAX2DOM - siblings")
+
+    confirm(root.parentNode is doc and
+            text1.parentNode is root and
+            elm1.parentNode is root and
+            text2.parentNode is root and
+            text3.parentNode is elm1, "testSAX2DOM - parents")
+
+    doc.unlink()
+
+def testEncodings():
+    doc = parseString('<foo>&#x20ac;</foo>')
+    confirm(doc.toxml() == u'<?xml version="1.0" ?><foo>\u20ac</foo>'
+            and doc.toxml('utf-8') == '<?xml version="1.0" encoding="utf-8"?><foo>\xe2\x82\xac</foo>'
+            and doc.toxml('iso-8859-15') == '<?xml version="1.0" encoding="iso-8859-15"?><foo>\xa4</foo>',
+            "testEncodings - encoding EURO SIGN")
+
+    # Verify that character decoding errors throw exceptions instead of crashing
+    try:
+        doc = parseString('<fran\xe7ais>Comment \xe7a va ? Tr\xe8s bien ?</fran\xe7ais>')
+    except UnicodeDecodeError:
+        pass
+    else:
+        print 'parsing with bad encoding should raise a UnicodeDecodeError'
+
+    doc.unlink()
+
+class UserDataHandler:
+    called = 0
+    def handle(self, operation, key, data, src, dst):
+        dst.setUserData(key, data + 1, self)
+        src.setUserData(key, None, None)
+        self.called = 1
+
+def testUserData():
+    dom = Document()
+    n = dom.createElement('e')
+    confirm(n.getUserData("foo") is None)
+    n.setUserData("foo", None, None)
+    confirm(n.getUserData("foo") is None)
+    n.setUserData("foo", 12, 12)
+    n.setUserData("bar", 13, 13)
+    confirm(n.getUserData("foo") == 12)
+    confirm(n.getUserData("bar") == 13)
+    n.setUserData("foo", None, None)
+    confirm(n.getUserData("foo") is None)
+    confirm(n.getUserData("bar") == 13)
+
+    handler = UserDataHandler()
+    n.setUserData("bar", 12, handler)
+    c = n.cloneNode(1)
+    confirm(handler.called
+            and n.getUserData("bar") is None
+            and c.getUserData("bar") == 13)
+    n.unlink()
+    c.unlink()
+    dom.unlink()
+
+def testRenameAttribute():
+    doc = parseString("<doc a='v'/>")
+    elem = doc.documentElement
+    attrmap = elem.attributes
+    attr = elem.attributes['a']
+
+    # Simple renaming
+    attr = doc.renameNode(attr, xml.dom.EMPTY_NAMESPACE, "b")
+    confirm(attr.name == "b"
+            and attr.nodeName == "b"
+            and attr.localName is None
+            and attr.namespaceURI == xml.dom.EMPTY_NAMESPACE
+            and attr.prefix is None
+            and attr.value == "v"
+            and elem.getAttributeNode("a") is None
+            and elem.getAttributeNode("b").isSameNode(attr)
+            and attrmap["b"].isSameNode(attr)
+            and attr.ownerDocument.isSameNode(doc)
+            and attr.ownerElement.isSameNode(elem))
+
+    # Rename to have a namespace, no prefix
+    attr = doc.renameNode(attr, "http://xml.python.org/ns", "c")
+    confirm(attr.name == "c"
+            and attr.nodeName == "c"
+            and attr.localName == "c"
+            and attr.namespaceURI == "http://xml.python.org/ns"
+            and attr.prefix is None
+            and attr.value == "v"
+            and elem.getAttributeNode("a") is None
+            and elem.getAttributeNode("b") is None
+            and elem.getAttributeNode("c").isSameNode(attr)
+            and elem.getAttributeNodeNS(
+                "http://xml.python.org/ns", "c").isSameNode(attr)
+            and attrmap["c"].isSameNode(attr)
+            and attrmap[("http://xml.python.org/ns", "c")].isSameNode(attr))
+
+    # Rename to have a namespace, with prefix
+    attr = doc.renameNode(attr, "http://xml.python.org/ns2", "p:d")
+    confirm(attr.name == "p:d"
+            and attr.nodeName == "p:d"
+            and attr.localName == "d"
+            and attr.namespaceURI == "http://xml.python.org/ns2"
+            and attr.prefix == "p"
+            and attr.value == "v"
+            and elem.getAttributeNode("a") is None
+            and elem.getAttributeNode("b") is None
+            and elem.getAttributeNode("c") is None
+            and elem.getAttributeNodeNS(
+                "http://xml.python.org/ns", "c") is None
+            and elem.getAttributeNode("p:d").isSameNode(attr)
+            and elem.getAttributeNodeNS(
+                "http://xml.python.org/ns2", "d").isSameNode(attr)
+            and attrmap["p:d"].isSameNode(attr)
+            and attrmap[("http://xml.python.org/ns2", "d")].isSameNode(attr))
+
+    # Rename back to a simple non-NS node
+    attr = doc.renameNode(attr, xml.dom.EMPTY_NAMESPACE, "e")
+    confirm(attr.name == "e"
+            and attr.nodeName == "e"
+            and attr.localName is None
+            and attr.namespaceURI == xml.dom.EMPTY_NAMESPACE
+            and attr.prefix is None
+            and attr.value == "v"
+            and elem.getAttributeNode("a") is None
+            and elem.getAttributeNode("b") is None
+            and elem.getAttributeNode("c") is None
+            and elem.getAttributeNode("p:d") is None
+            and elem.getAttributeNodeNS(
+                "http://xml.python.org/ns", "c") is None
+            and elem.getAttributeNode("e").isSameNode(attr)
+            and attrmap["e"].isSameNode(attr))
+
+    try:
+        doc.renameNode(attr, "http://xml.python.org/ns", "xmlns")
+    except xml.dom.NamespaceErr:
+        pass
+    else:
+        print "expected NamespaceErr"
+
+    checkRenameNodeSharedConstraints(doc, attr)
+    doc.unlink()
+
+def testRenameElement():
+    doc = parseString("<doc/>")
+    elem = doc.documentElement
+
+    # Simple renaming
+    elem = doc.renameNode(elem, xml.dom.EMPTY_NAMESPACE, "a")
+    confirm(elem.tagName == "a"
+            and elem.nodeName == "a"
+            and elem.localName is None
+            and elem.namespaceURI == xml.dom.EMPTY_NAMESPACE
+            and elem.prefix is None
+            and elem.ownerDocument.isSameNode(doc))
+
+    # Rename to have a namespace, no prefix
+    elem = doc.renameNode(elem, "http://xml.python.org/ns", "b")
+    confirm(elem.tagName == "b"
+            and elem.nodeName == "b"
+            and elem.localName == "b"
+            and elem.namespaceURI == "http://xml.python.org/ns"
+            and elem.prefix is None
+            and elem.ownerDocument.isSameNode(doc))
+
+    # Rename to have a namespace, with prefix
+    elem = doc.renameNode(elem, "http://xml.python.org/ns2", "p:c")
+    confirm(elem.tagName == "p:c"
+            and elem.nodeName == "p:c"
+            and elem.localName == "c"
+            and elem.namespaceURI == "http://xml.python.org/ns2"
+            and elem.prefix == "p"
+            and elem.ownerDocument.isSameNode(doc))
+
+    # Rename back to a simple non-NS node
+    elem = doc.renameNode(elem, xml.dom.EMPTY_NAMESPACE, "d")
+    confirm(elem.tagName == "d"
+            and elem.nodeName == "d"
+            and elem.localName is None
+            and elem.namespaceURI == xml.dom.EMPTY_NAMESPACE
+            and elem.prefix is None
+            and elem.ownerDocument.isSameNode(doc))
+
+    checkRenameNodeSharedConstraints(doc, elem)
+    doc.unlink()
+
+def checkRenameNodeSharedConstraints(doc, node):
+    # Make sure illegal NS usage is detected:
+    try:
+        doc.renameNode(node, "http://xml.python.org/ns", "xmlns:foo")
+    except xml.dom.NamespaceErr:
+        pass
+    else:
+        print "expected NamespaceErr"
+
+    doc2 = parseString("<doc/>")
+    try:
+        doc2.renameNode(node, xml.dom.EMPTY_NAMESPACE, "foo")
+    except xml.dom.WrongDocumentErr:
+        pass
+    else:
+        print "expected WrongDocumentErr"
+
+def testRenameOther():
+    # We have to create a comment node explicitly since not all DOM
+    # builders used with minidom add comments to the DOM.
+    doc = xml.dom.minidom.getDOMImplementation().createDocument(
+        xml.dom.EMPTY_NAMESPACE, "e", None)
+    node = doc.createComment("comment")
+    try:
+        doc.renameNode(node, xml.dom.EMPTY_NAMESPACE, "foo")
+    except xml.dom.NotSupportedErr:
+        pass
+    else:
+        print "expected NotSupportedErr when renaming comment node"
+    doc.unlink()
+
+def checkWholeText(node, s):
+    t = node.wholeText
+    confirm(t == s, "looking for %s, found %s" % (repr(s), repr(t)))
+
+def testWholeText():
+    doc = parseString("<doc>a</doc>")
+    elem = doc.documentElement
+    text = elem.childNodes[0]
+    assert text.nodeType == Node.TEXT_NODE
+
+    checkWholeText(text, "a")
+    elem.appendChild(doc.createTextNode("b"))
+    checkWholeText(text, "ab")
+    elem.insertBefore(doc.createCDATASection("c"), text)
+    checkWholeText(text, "cab")
+
+    # make sure we don't cross other nodes
+    splitter = doc.createComment("comment")
+    elem.appendChild(splitter)
+    text2 = doc.createTextNode("d")
+    elem.appendChild(text2)
+    checkWholeText(text, "cab")
+    checkWholeText(text2, "d")
+
+    x = doc.createElement("x")
+    elem.replaceChild(x, splitter)
+    splitter = x
+    checkWholeText(text, "cab")
+    checkWholeText(text2, "d")
+
+    x = doc.createProcessingInstruction("y", "z")
+    elem.replaceChild(x, splitter)
+    splitter = x
+    checkWholeText(text, "cab")
+    checkWholeText(text2, "d")
+
+    elem.removeChild(splitter)
+    checkWholeText(text, "cabd")
+    checkWholeText(text2, "cabd")
+
+def testPatch1094164 ():
+    doc = parseString("<doc><e/></doc>")
+    elem = doc.documentElement
+    e = elem.firstChild
+    confirm(e.parentNode is elem, "Before replaceChild()")
+    # Check that replacing a child with itself leaves the tree unchanged
+    elem.replaceChild(e, e)
+    confirm(e.parentNode is elem, "After replaceChild()")
+
+
+
+def testReplaceWholeText():
+    def setup():
+        doc = parseString("<doc>a<e/>d</doc>")
+        elem = doc.documentElement
+        text1 = elem.firstChild
+        text2 = elem.lastChild
+        splitter = text1.nextSibling
+        elem.insertBefore(doc.createTextNode("b"), splitter)
+        elem.insertBefore(doc.createCDATASection("c"), text1)
+        return doc, elem, text1, splitter, text2
+
+    doc, elem, text1, splitter, text2 = setup()
+    text = text1.replaceWholeText("new content")
+    checkWholeText(text, "new content")
+    checkWholeText(text2, "d")
+    confirm(len(elem.childNodes) == 3)
+
+    doc, elem, text1, splitter, text2 = setup()
+    text = text2.replaceWholeText("new content")
+    checkWholeText(text, "new content")
+    checkWholeText(text1, "cab")
+    confirm(len(elem.childNodes) == 5)
+
+    doc, elem, text1, splitter, text2 = setup()
+    text = text1.replaceWholeText("")
+    checkWholeText(text2, "d")
+    confirm(text is None
+            and len(elem.childNodes) == 2)
+
+def testSchemaType():
+    doc = parseString(
+        "<!DOCTYPE doc [\n"
+        "  <!ENTITY e1 SYSTEM 'http://xml.python.org/e1'>\n"
+        "  <!ENTITY e2 SYSTEM 'http://xml.python.org/e2'>\n"
+        "  <!ATTLIST doc id   ID       #IMPLIED \n"
+        "                ref  IDREF    #IMPLIED \n"
+        "                refs IDREFS   #IMPLIED \n"
+        "                enum (a|b)    #IMPLIED \n"
+        "                ent  ENTITY   #IMPLIED \n"
+        "                ents ENTITIES #IMPLIED \n"
+        "                nm   NMTOKEN  #IMPLIED \n"
+        "                nms  NMTOKENS #IMPLIED \n"
+        "                text CDATA    #IMPLIED \n"
+        "    >\n"
+        "]><doc id='name' notid='name' text='splat!' enum='b'"
+        "       ref='name' refs='name name' ent='e1' ents='e1 e2'"
+        "       nm='123' nms='123 abc' />")
+    elem = doc.documentElement
+    # We don't want to rely on any specific loader at this point, so
+    # just make sure we can get to all the names, and that the
+    # DTD-based namespace is right.  The names can vary by loader
+    # since each supports a different level of DTD information.
+    t = elem.schemaType
+    confirm(t.name is None
+            and t.namespace == xml.dom.EMPTY_NAMESPACE)
+    names = "id notid text enum ref refs ent ents nm nms".split()
+    for name in names:
+        a = elem.getAttributeNode(name)
+        t = a.schemaType
+        confirm(hasattr(t, "name")
+                and t.namespace == xml.dom.EMPTY_NAMESPACE)
+
+def testSetIdAttribute():
+    doc = parseString("<doc a1='v' a2='w'/>")
+    e = doc.documentElement
+    a1 = e.getAttributeNode("a1")
+    a2 = e.getAttributeNode("a2")
+    confirm(doc.getElementById("v") is None
+            and not a1.isId
+            and not a2.isId)
+    e.setIdAttribute("a1")
+    confirm(e.isSameNode(doc.getElementById("v"))
+            and a1.isId
+            and not a2.isId)
+    e.setIdAttribute("a2")
+    confirm(e.isSameNode(doc.getElementById("v"))
+            and e.isSameNode(doc.getElementById("w"))
+            and a1.isId
+            and a2.isId)
+    # replace the a1 node; the new node should *not* be an ID
+    a3 = doc.createAttribute("a1")
+    a3.value = "v"
+    e.setAttributeNode(a3)
+    confirm(doc.getElementById("v") is None
+            and e.isSameNode(doc.getElementById("w"))
+            and not a1.isId
+            and a2.isId
+            and not a3.isId)
+    # renaming an attribute should not affect its ID-ness:
+    doc.renameNode(a2, xml.dom.EMPTY_NAMESPACE, "an")
+    confirm(e.isSameNode(doc.getElementById("w"))
+            and a2.isId)
+
+def testSetIdAttributeNS():
+    NS1 = "http://xml.python.org/ns1"
+    NS2 = "http://xml.python.org/ns2"
+    doc = parseString("<doc"
+                      " xmlns:ns1='" + NS1 + "'"
+                      " xmlns:ns2='" + NS2 + "'"
+                      " ns1:a1='v' ns2:a2='w'/>")
+    e = doc.documentElement
+    a1 = e.getAttributeNodeNS(NS1, "a1")
+    a2 = e.getAttributeNodeNS(NS2, "a2")
+    confirm(doc.getElementById("v") is None
+            and not a1.isId
+            and not a2.isId)
+    e.setIdAttributeNS(NS1, "a1")
+    confirm(e.isSameNode(doc.getElementById("v"))
+            and a1.isId
+            and not a2.isId)
+    e.setIdAttributeNS(NS2, "a2")
+    confirm(e.isSameNode(doc.getElementById("v"))
+            and e.isSameNode(doc.getElementById("w"))
+            and a1.isId
+            and a2.isId)
+    # replace the a1 node; the new node should *not* be an ID
+    a3 = doc.createAttributeNS(NS1, "a1")
+    a3.value = "v"
+    e.setAttributeNode(a3)
+    confirm(e.isSameNode(doc.getElementById("w")))
+    confirm(not a1.isId)
+    confirm(a2.isId)
+    confirm(not a3.isId)
+    confirm(doc.getElementById("v") is None)
+    # renaming an attribute should not affect its ID-ness:
+    doc.renameNode(a2, xml.dom.EMPTY_NAMESPACE, "an")
+    confirm(e.isSameNode(doc.getElementById("w"))
+            and a2.isId)
+
+def testSetIdAttributeNode():
+    NS1 = "http://xml.python.org/ns1"
+    NS2 = "http://xml.python.org/ns2"
+    doc = parseString("<doc"
+                      " xmlns:ns1='" + NS1 + "'"
+                      " xmlns:ns2='" + NS2 + "'"
+                      " ns1:a1='v' ns2:a2='w'/>")
+    e = doc.documentElement
+    a1 = e.getAttributeNodeNS(NS1, "a1")
+    a2 = e.getAttributeNodeNS(NS2, "a2")
+    confirm(doc.getElementById("v") is None
+            and not a1.isId
+            and not a2.isId)
+    e.setIdAttributeNode(a1)
+    confirm(e.isSameNode(doc.getElementById("v"))
+            and a1.isId
+            and not a2.isId)
+    e.setIdAttributeNode(a2)
+    confirm(e.isSameNode(doc.getElementById("v"))
+            and e.isSameNode(doc.getElementById("w"))
+            and a1.isId
+            and a2.isId)
+    # replace the a1 node; the new node should *not* be an ID
+    a3 = doc.createAttributeNS(NS1, "a1")
+    a3.value = "v"
+    e.setAttributeNode(a3)
+    confirm(e.isSameNode(doc.getElementById("w")))
+    confirm(not a1.isId)
+    confirm(a2.isId)
+    confirm(not a3.isId)
+    confirm(doc.getElementById("v") is None)
+    # renaming an attribute should not affect its ID-ness:
+    doc.renameNode(a2, xml.dom.EMPTY_NAMESPACE, "an")
+    confirm(e.isSameNode(doc.getElementById("w"))
+            and a2.isId)
+
+def testPickledDocument():
+    doc = parseString("<?xml version='1.0' encoding='us-ascii'?>\n"
+                      "<!DOCTYPE doc PUBLIC 'http://xml.python.org/public'"
+                      " 'http://xml.python.org/system' [\n"
+                      "  <!ELEMENT e EMPTY>\n"
+                      "  <!ENTITY ent SYSTEM 'http://xml.python.org/entity'>\n"
+                      "]><doc attr='value'> text\n"
+                      "<?pi sample?> <!-- comment --> <e/> </doc>")
+    s = pickle.dumps(doc)
+    doc2 = pickle.loads(s)
+    stack = [(doc, doc2)]
+    while stack:
+        n1, n2 = stack.pop()
+        confirm(n1.nodeType == n2.nodeType
+                and len(n1.childNodes) == len(n2.childNodes)
+                and n1.nodeName == n2.nodeName
+                and not n1.isSameNode(n2)
+                and not n2.isSameNode(n1))
+        if n1.nodeType == Node.DOCUMENT_TYPE_NODE:
+            len(n1.entities)
+            len(n2.entities)
+            len(n1.notations)
+            len(n2.notations)
+            confirm(len(n1.entities) == len(n2.entities)
+                    and len(n1.notations) == len(n2.notations))
+            for i in range(len(n1.notations)):
+                no1 = n1.notations.item(i)
+                no2 = n1.notations.item(i)
+                confirm(no1.name == no2.name
+                        and no1.publicId == no2.publicId
+                        and no1.systemId == no2.systemId)
+                statck.append((no1, no2))
+            for i in range(len(n1.entities)):
+                e1 = n1.entities.item(i)
+                e2 = n2.entities.item(i)
+                confirm(e1.notationName == e2.notationName
+                        and e1.publicId == e2.publicId
+                        and e1.systemId == e2.systemId)
+                stack.append((e1, e2))
+        if n1.nodeType != Node.DOCUMENT_NODE:
+            confirm(n1.ownerDocument.isSameNode(doc)
+                    and n2.ownerDocument.isSameNode(doc2))
+        for i in range(len(n1.childNodes)):
+            stack.append((n1.childNodes[i], n2.childNodes[i]))
+
+
+# --- MAIN PROGRAM
+
+names = globals().keys()
+names.sort()
+
+failed = []
+
+try:
+    Node.allnodes
+except AttributeError:
+    # We don't actually have the minidom from the standard library,
+    # but are picking up the PyXML version from site-packages.
+    def check_allnodes():
+        pass
+else:
+    def check_allnodes():
+        confirm(len(Node.allnodes) == 0,
+                "assertion: len(Node.allnodes) == 0")
+        if len(Node.allnodes):
+            print "Garbage left over:"
+            if verbose:
+                print Node.allnodes.items()[0:10]
+            else:
+                # Don't print specific nodes if repeatable results
+                # are needed
+                print len(Node.allnodes)
+        Node.allnodes = {}
+
+for name in names:
+    if name.startswith("test"):
+        func = globals()[name]
+        try:
+            func()
+            check_allnodes()
+        except:
+            failed.append(name)
+            print "Test Failed: ", name
+            sys.stdout.flush()
+            traceback.print_exception(*sys.exc_info())
+            print repr(sys.exc_info()[1])
+            Node.allnodes = {}
+
+if failed:
+    print "\n\n\n**** Check for failures in these tests:"
+    for name in failed:
+        print "  " + name

Added: vendor/Python/current/Lib/test/test_mmap.py
===================================================================
--- vendor/Python/current/Lib/test/test_mmap.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_mmap.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,395 @@
+from test.test_support import verify, vereq, TESTFN
+import mmap
+import os, re
+
+PAGESIZE = mmap.PAGESIZE
+
+def test_both():
+    "Test mmap module on Unix systems and Windows"
+
+    # Create a file to be mmap'ed.
+    if os.path.exists(TESTFN):
+        os.unlink(TESTFN)
+    f = open(TESTFN, 'w+')
+
+    try:    # unlink TESTFN no matter what
+        # Write 2 pages worth of data to the file
+        f.write('\0'* PAGESIZE)
+        f.write('foo')
+        f.write('\0'* (PAGESIZE-3) )
+        f.flush()
+        m = mmap.mmap(f.fileno(), 2 * PAGESIZE)
+        f.close()
+
+        # Simple sanity checks
+
+        print type(m)  # SF bug 128713:  segfaulted on Linux
+        print '  Position of foo:', m.find('foo') / float(PAGESIZE), 'pages'
+        vereq(m.find('foo'), PAGESIZE)
+
+        print '  Length of file:', len(m) / float(PAGESIZE), 'pages'
+        vereq(len(m), 2*PAGESIZE)
+
+        print '  Contents of byte 0:', repr(m[0])
+        vereq(m[0], '\0')
+        print '  Contents of first 3 bytes:', repr(m[0:3])
+        vereq(m[0:3], '\0\0\0')
+
+        # Modify the file's content
+        print "\n  Modifying file's content..."
+        m[0] = '3'
+        m[PAGESIZE +3: PAGESIZE +3+3] = 'bar'
+
+        # Check that the modification worked
+        print '  Contents of byte 0:', repr(m[0])
+        vereq(m[0], '3')
+        print '  Contents of first 3 bytes:', repr(m[0:3])
+        vereq(m[0:3], '3\0\0')
+        print '  Contents of second page:',  repr(m[PAGESIZE-1 : PAGESIZE + 7])
+        vereq(m[PAGESIZE-1 : PAGESIZE + 7], '\0foobar\0')
+
+        m.flush()
+
+        # Test doing a regular expression match in an mmap'ed file
+        match = re.search('[A-Za-z]+', m)
+        if match is None:
+            print '  ERROR: regex match on mmap failed!'
+        else:
+            start, end = match.span(0)
+            length = end - start
+
+            print '  Regex match on mmap (page start, length of match):',
+            print start / float(PAGESIZE), length
+
+            vereq(start, PAGESIZE)
+            vereq(end, PAGESIZE + 6)
+
+        # test seeking around (try to overflow the seek implementation)
+        m.seek(0,0)
+        print '  Seek to zeroth byte'
+        vereq(m.tell(), 0)
+        m.seek(42,1)
+        print '  Seek to 42nd byte'
+        vereq(m.tell(), 42)
+        m.seek(0,2)
+        print '  Seek to last byte'
+        vereq(m.tell(), len(m))
+
+        print '  Try to seek to negative position...'
+        try:
+            m.seek(-1)
+        except ValueError:
+            pass
+        else:
+            verify(0, 'expected a ValueError but did not get it')
+
+        print '  Try to seek beyond end of mmap...'
+        try:
+            m.seek(1,2)
+        except ValueError:
+            pass
+        else:
+            verify(0, 'expected a ValueError but did not get it')
+
+        print '  Try to seek to negative position...'
+        try:
+            m.seek(-len(m)-1,2)
+        except ValueError:
+            pass
+        else:
+            verify(0, 'expected a ValueError but did not get it')
+
+        # Try resizing map
+        print '  Attempting resize()'
+        try:
+            m.resize(512)
+        except SystemError:
+            # resize() not supported
+            # No messages are printed, since the output of this test suite
+            # would then be different across platforms.
+            pass
+        else:
+            # resize() is supported
+            verify(len(m) == 512,
+                    "len(m) is %d, but expecting 512" % (len(m),) )
+            # Check that we can no longer seek beyond the new size.
+            try:
+                m.seek(513,0)
+            except ValueError:
+                pass
+            else:
+                verify(0, 'Could seek beyond the new size')
+
+            # Check that the underlying file is truncated too
+            # (bug #728515)
+            f = open(TESTFN)
+            f.seek(0, 2)
+            verify(f.tell() == 512, 'Underlying file not truncated')
+            f.close()
+            verify(m.size() == 512, 'New size not reflected in file')
+
+        m.close()
+
+    finally:
+        try:
+            f.close()
+        except OSError:
+            pass
+        try:
+            os.unlink(TESTFN)
+        except OSError:
+            pass
+
+    # Test for "access" keyword parameter
+    try:
+        mapsize = 10
+        print "  Creating", mapsize, "byte test data file."
+        open(TESTFN, "wb").write("a"*mapsize)
+        print "  Opening mmap with access=ACCESS_READ"
+        f = open(TESTFN, "rb")
+        m = mmap.mmap(f.fileno(), mapsize, access=mmap.ACCESS_READ)
+        verify(m[:] == 'a'*mapsize, "Readonly memory map data incorrect.")
+
+        print "  Ensuring that readonly mmap can't be slice assigned."
+        try:
+            m[:] = 'b'*mapsize
+        except TypeError:
+            pass
+        else:
+            verify(0, "Able to write to readonly memory map")
+
+        print "  Ensuring that readonly mmap can't be item assigned."
+        try:
+            m[0] = 'b'
+        except TypeError:
+            pass
+        else:
+            verify(0, "Able to write to readonly memory map")
+
+        print "  Ensuring that readonly mmap can't be write() to."
+        try:
+            m.seek(0,0)
+            m.write('abc')
+        except TypeError:
+            pass
+        else:
+            verify(0, "Able to write to readonly memory map")
+
+        print "  Ensuring that readonly mmap can't be write_byte() to."
+        try:
+            m.seek(0,0)
+            m.write_byte('d')
+        except TypeError:
+            pass
+        else:
+            verify(0, "Able to write to readonly memory map")
+
+        print "  Ensuring that readonly mmap can't be resized."
+        try:
+            m.resize(2*mapsize)
+        except SystemError:   # resize is not universally supported
+            pass
+        except TypeError:
+            pass
+        else:
+            verify(0, "Able to resize readonly memory map")
+        del m, f
+        verify(open(TESTFN, "rb").read() == 'a'*mapsize,
+               "Readonly memory map data file was modified")
+
+        print "  Opening mmap with size too big"
+        import sys
+        f = open(TESTFN, "r+b")
+        try:
+            m = mmap.mmap(f.fileno(), mapsize+1)
+        except ValueError:
+            # we do not expect a ValueError on Windows
+            # CAUTION:  This also changes the size of the file on disk, and
+            # later tests assume that the length hasn't changed.  We need to
+            # repair that.
+            if sys.platform.startswith('win'):
+                verify(0, "Opening mmap with size+1 should work on Windows.")
+        else:
+            # we expect a ValueError on Unix, but not on Windows
+            if not sys.platform.startswith('win'):
+                verify(0, "Opening mmap with size+1 should raise ValueError.")
+            m.close()
+        f.close()
+        if sys.platform.startswith('win'):
+            # Repair damage from the resizing test.
+            f = open(TESTFN, 'r+b')
+            f.truncate(mapsize)
+            f.close()
+
+        print "  Opening mmap with access=ACCESS_WRITE"
+        f = open(TESTFN, "r+b")
+        m = mmap.mmap(f.fileno(), mapsize, access=mmap.ACCESS_WRITE)
+        print "  Modifying write-through memory map."
+        m[:] = 'c'*mapsize
+        verify(m[:] == 'c'*mapsize,
+               "Write-through memory map memory not updated properly.")
+        m.flush()
+        m.close()
+        f.close()
+        f = open(TESTFN, 'rb')
+        stuff = f.read()
+        f.close()
+        verify(stuff == 'c'*mapsize,
+               "Write-through memory map data file not updated properly.")
+
+        print "  Opening mmap with access=ACCESS_COPY"
+        f = open(TESTFN, "r+b")
+        m = mmap.mmap(f.fileno(), mapsize, access=mmap.ACCESS_COPY)
+        print "  Modifying copy-on-write memory map."
+        m[:] = 'd'*mapsize
+        verify(m[:] == 'd' * mapsize,
+               "Copy-on-write memory map data not written correctly.")
+        m.flush()
+        verify(open(TESTFN, "rb").read() == 'c'*mapsize,
+               "Copy-on-write test data file should not be modified.")
+        try:
+            print "  Ensuring copy-on-write maps cannot be resized."
+            m.resize(2*mapsize)
+        except TypeError:
+            pass
+        else:
+            verify(0, "Copy-on-write mmap resize did not raise exception.")
+        del m, f
+        try:
+            print "  Ensuring invalid access parameter raises exception."
+            f = open(TESTFN, "r+b")
+            m = mmap.mmap(f.fileno(), mapsize, access=4)
+        except ValueError:
+            pass
+        else:
+            verify(0, "Invalid access code should have raised exception.")
+
+        if os.name == "posix":
+            # Try incompatible flags, prot and access parameters.
+            f = open(TESTFN, "r+b")
+            try:
+                m = mmap.mmap(f.fileno(), mapsize, flags=mmap.MAP_PRIVATE,
+                              prot=mmap.PROT_READ, access=mmap.ACCESS_WRITE)
+            except ValueError:
+                pass
+            else:
+                verify(0, "Incompatible parameters should raise ValueError.")
+            f.close()
+    finally:
+        try:
+            os.unlink(TESTFN)
+        except OSError:
+            pass
+
+    print '  Try opening a bad file descriptor...'
+    try:
+        mmap.mmap(-2, 4096)
+    except mmap.error:
+        pass
+    else:
+        verify(0, 'expected a mmap.error but did not get it')
+
+    # Do a tougher .find() test.  SF bug 515943 pointed out that, in 2.2,
+    # searching for data with embedded \0 bytes didn't work.
+    f = open(TESTFN, 'w+')
+
+    try:    # unlink TESTFN no matter what
+        data = 'aabaac\x00deef\x00\x00aa\x00'
+        n = len(data)
+        f.write(data)
+        f.flush()
+        m = mmap.mmap(f.fileno(), n)
+        f.close()
+
+        for start in range(n+1):
+            for finish in range(start, n+1):
+                slice = data[start : finish]
+                vereq(m.find(slice), data.find(slice))
+                vereq(m.find(slice + 'x'), -1)
+        m.close()
+
+    finally:
+        os.unlink(TESTFN)
+
+    # make sure a double close doesn't crash on Solaris (Bug# 665913)
+    f = open(TESTFN, 'w+')
+
+    try:    # unlink TESTFN no matter what
+        f.write(2**16 * 'a') # Arbitrary character
+        f.close()
+
+        f = open(TESTFN)
+        mf = mmap.mmap(f.fileno(), 2**16, access=mmap.ACCESS_READ)
+        mf.close()
+        mf.close()
+        f.close()
+
+    finally:
+        os.unlink(TESTFN)
+
+    # test mapping of entire file by passing 0 for map length
+    if hasattr(os, "stat"):
+        print "  Ensuring that passing 0 as map length sets map size to current file size."
+        f = open(TESTFN, "w+")
+
+        try:
+            f.write(2**16 * 'm') # Arbitrary character
+            f.close()
+
+            f = open(TESTFN, "rb+")
+            mf = mmap.mmap(f.fileno(), 0)
+            verify(len(mf) == 2**16, "Map size should equal file size.")
+            vereq(mf.read(2**16), 2**16 * "m")
+            mf.close()
+            f.close()
+
+        finally:
+            os.unlink(TESTFN)
+
+    # test mapping of entire file by passing 0 for map length
+    if hasattr(os, "stat"):
+        print "  Ensuring that passing 0 as map length sets map size to current file size."
+        f = open(TESTFN, "w+")
+        try:
+            f.write(2**16 * 'm') # Arbitrary character
+            f.close()
+
+            f = open(TESTFN, "rb+")
+            mf = mmap.mmap(f.fileno(), 0)
+            verify(len(mf) == 2**16, "Map size should equal file size.")
+            vereq(mf.read(2**16), 2**16 * "m")
+            mf.close()
+            f.close()
+
+        finally:
+            os.unlink(TESTFN)
+
+    # make move works everywhere (64-bit format problem earlier)
+    f = open(TESTFN, 'w+')
+
+    try:    # unlink TESTFN no matter what
+        f.write("ABCDEabcde") # Arbitrary character
+        f.flush()
+
+        mf = mmap.mmap(f.fileno(), 10)
+        mf.move(5, 0, 5)
+        verify(mf[:] == "ABCDEABCDE", "Map move should have duplicated front 5")
+        mf.close()
+        f.close()
+
+    finally:
+        os.unlink(TESTFN)
+
+def test_anon():
+    print "  anonymous mmap.mmap(-1, PAGESIZE)..."
+    m = mmap.mmap(-1, PAGESIZE)
+    for x in xrange(PAGESIZE):
+        verify(m[x] == '\0', "anonymously mmap'ed contents should be zero")
+
+    for x in xrange(PAGESIZE):
+        m[x] = ch = chr(x & 255)
+        vereq(m[x], ch)
+
+test_both()
+test_anon()
+print ' Test passed'

Added: vendor/Python/current/Lib/test/test_module.py
===================================================================
--- vendor/Python/current/Lib/test/test_module.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_module.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,48 @@
+# Test the module type
+
+from test.test_support import verify, vereq, verbose, TestFailed
+
+import sys
+module = type(sys)
+
+# An uninitialized module has no __dict__ or __name__, and __doc__ is None
+foo = module.__new__(module)
+verify(foo.__dict__ is None)
+try:
+    s = foo.__name__
+except AttributeError:
+    pass
+else:
+    raise TestFailed, "__name__ = %s" % repr(s)
+vereq(foo.__doc__, module.__doc__)
+
+# Regularly initialized module, no docstring
+foo = module("foo")
+vereq(foo.__name__, "foo")
+vereq(foo.__doc__, None)
+vereq(foo.__dict__, {"__name__": "foo", "__doc__": None})
+
+# ASCII docstring
+foo = module("foo", "foodoc")
+vereq(foo.__name__, "foo")
+vereq(foo.__doc__, "foodoc")
+vereq(foo.__dict__, {"__name__": "foo", "__doc__": "foodoc"})
+
+# Unicode docstring
+foo = module("foo", u"foodoc\u1234")
+vereq(foo.__name__, "foo")
+vereq(foo.__doc__, u"foodoc\u1234")
+vereq(foo.__dict__, {"__name__": "foo", "__doc__": u"foodoc\u1234"})
+
+# Reinitialization should not replace the __dict__
+foo.bar = 42
+d = foo.__dict__
+foo.__init__("foo", "foodoc")
+vereq(foo.__name__, "foo")
+vereq(foo.__doc__, "foodoc")
+vereq(foo.bar, 42)
+vereq(foo.__dict__, {"__name__": "foo", "__doc__": "foodoc", "bar": 42})
+verify(foo.__dict__ is d)
+
+if verbose:
+    print "All OK"

Added: vendor/Python/current/Lib/test/test_multibytecodec.py
===================================================================
--- vendor/Python/current/Lib/test/test_multibytecodec.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_multibytecodec.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,231 @@
+#!/usr/bin/env python
+#
+# test_multibytecodec.py
+#   Unit test for multibytecodec itself
+#
+
+from test import test_support
+from test import test_multibytecodec_support
+from test.test_support import TESTFN
+import unittest, StringIO, codecs, sys, os
+
+ALL_CJKENCODINGS = [
+# _codecs_cn
+    'gb2312', 'gbk', 'gb18030', 'hz',
+# _codecs_hk
+    'big5hkscs',
+# _codecs_jp
+    'cp932', 'shift_jis', 'euc_jp', 'euc_jisx0213', 'shift_jisx0213',
+    'euc_jis_2004', 'shift_jis_2004',
+# _codecs_kr
+    'cp949', 'euc_kr', 'johab',
+# _codecs_tw
+    'big5', 'cp950',
+# _codecs_iso2022
+    'iso2022_jp', 'iso2022_jp_1', 'iso2022_jp_2', 'iso2022_jp_2004',
+    'iso2022_jp_3', 'iso2022_jp_ext', 'iso2022_kr',
+]
+
+class Test_MultibyteCodec(unittest.TestCase):
+
+    def test_nullcoding(self):
+        for enc in ALL_CJKENCODINGS:
+            self.assertEqual(''.decode(enc), u'')
+            self.assertEqual(unicode('', enc), u'')
+            self.assertEqual(u''.encode(enc), '')
+
+    def test_str_decode(self):
+        for enc in ALL_CJKENCODINGS:
+            self.assertEqual('abcd'.encode(enc), 'abcd')
+
+    def test_errorcallback_longindex(self):
+        dec = codecs.getdecoder('euc-kr')
+        myreplace  = lambda exc: (u'', sys.maxint+1)
+        codecs.register_error('test.cjktest', myreplace)
+        self.assertRaises(IndexError, dec,
+                          'apple\x92ham\x93spam', 'test.cjktest')
+
+    def test_codingspec(self):
+        try:
+            for enc in ALL_CJKENCODINGS:
+                print >> open(TESTFN, 'w'), '# coding:', enc
+                exec open(TESTFN)
+        finally:
+            os.unlink(TESTFN)
+
+class Test_IncrementalEncoder(unittest.TestCase):
+
+    def test_stateless(self):
+        # cp949 encoder isn't stateful at all.
+        encoder = codecs.getincrementalencoder('cp949')()
+        self.assertEqual(encoder.encode(u'\ud30c\uc774\uc36c \ub9c8\uc744'),
+                         '\xc6\xc4\xc0\xcc\xbd\xe3 \xb8\xb6\xc0\xbb')
+        self.assertEqual(encoder.reset(), None)
+        self.assertEqual(encoder.encode(u'\u2606\u223c\u2606', True),
+                         '\xa1\xd9\xa1\xad\xa1\xd9')
+        self.assertEqual(encoder.reset(), None)
+        self.assertEqual(encoder.encode(u'', True), '')
+        self.assertEqual(encoder.encode(u'', False), '')
+        self.assertEqual(encoder.reset(), None)
+
+    def test_stateful(self):
+        # jisx0213 encoder is stateful for a few codepoints. eg)
+        #   U+00E6 => A9DC
+        #   U+00E6 U+0300 => ABC4
+        #   U+0300 => ABDC
+
+        encoder = codecs.getincrementalencoder('jisx0213')()
+        self.assertEqual(encoder.encode(u'\u00e6\u0300'), '\xab\xc4')
+        self.assertEqual(encoder.encode(u'\u00e6'), '')
+        self.assertEqual(encoder.encode(u'\u0300'), '\xab\xc4')
+        self.assertEqual(encoder.encode(u'\u00e6', True), '\xa9\xdc')
+
+        self.assertEqual(encoder.reset(), None)
+        self.assertEqual(encoder.encode(u'\u0300'), '\xab\xdc')
+
+        self.assertEqual(encoder.encode(u'\u00e6'), '')
+        self.assertEqual(encoder.encode('', True), '\xa9\xdc')
+        self.assertEqual(encoder.encode('', True), '')
+
+    def test_stateful_keep_buffer(self):
+        encoder = codecs.getincrementalencoder('jisx0213')()
+        self.assertEqual(encoder.encode(u'\u00e6'), '')
+        self.assertRaises(UnicodeEncodeError, encoder.encode, u'\u0123')
+        self.assertEqual(encoder.encode(u'\u0300\u00e6'), '\xab\xc4')
+        self.assertRaises(UnicodeEncodeError, encoder.encode, u'\u0123')
+        self.assertEqual(encoder.reset(), None)
+        self.assertEqual(encoder.encode(u'\u0300'), '\xab\xdc')
+        self.assertEqual(encoder.encode(u'\u00e6'), '')
+        self.assertRaises(UnicodeEncodeError, encoder.encode, u'\u0123')
+        self.assertEqual(encoder.encode(u'', True), '\xa9\xdc')
+
+
+class Test_IncrementalDecoder(unittest.TestCase):
+
+    def test_dbcs(self):
+        # cp949 decoder is simple with only 1 or 2 bytes sequences.
+        decoder = codecs.getincrementaldecoder('cp949')()
+        self.assertEqual(decoder.decode('\xc6\xc4\xc0\xcc\xbd'),
+                         u'\ud30c\uc774')
+        self.assertEqual(decoder.decode('\xe3 \xb8\xb6\xc0\xbb'),
+                         u'\uc36c \ub9c8\uc744')
+        self.assertEqual(decoder.decode(''), u'')
+
+    def test_dbcs_keep_buffer(self):
+        decoder = codecs.getincrementaldecoder('cp949')()
+        self.assertEqual(decoder.decode('\xc6\xc4\xc0'), u'\ud30c')
+        self.assertRaises(UnicodeDecodeError, decoder.decode, '', True)
+        self.assertEqual(decoder.decode('\xcc'), u'\uc774')
+
+        self.assertEqual(decoder.decode('\xc6\xc4\xc0'), u'\ud30c')
+        self.assertRaises(UnicodeDecodeError, decoder.decode, '\xcc\xbd', True)
+        self.assertEqual(decoder.decode('\xcc'), u'\uc774')
+
+    def test_iso2022(self):
+        decoder = codecs.getincrementaldecoder('iso2022-jp')()
+        ESC = '\x1b'
+        self.assertEqual(decoder.decode(ESC + '('), u'')
+        self.assertEqual(decoder.decode('B', True), u'')
+        self.assertEqual(decoder.decode(ESC + '$'), u'')
+        self.assertEqual(decoder.decode('B@$'), u'\u4e16')
+        self.assertEqual(decoder.decode('@$@'), u'\u4e16')
+        self.assertEqual(decoder.decode('$', True), u'\u4e16')
+        self.assertEqual(decoder.reset(), None)
+        self.assertEqual(decoder.decode('@$'), u'@$')
+        self.assertEqual(decoder.decode(ESC + '$'), u'')
+        self.assertRaises(UnicodeDecodeError, decoder.decode, '', True)
+        self.assertEqual(decoder.decode('B@$'), u'\u4e16')
+
+
+class Test_StreamWriter(unittest.TestCase):
+    if len(u'\U00012345') == 2: # UCS2
+        def test_gb18030(self):
+            s= StringIO.StringIO()
+            c = codecs.getwriter('gb18030')(s)
+            c.write(u'123')
+            self.assertEqual(s.getvalue(), '123')
+            c.write(u'\U00012345')
+            self.assertEqual(s.getvalue(), '123\x907\x959')
+            c.write(u'\U00012345'[0])
+            self.assertEqual(s.getvalue(), '123\x907\x959')
+            c.write(u'\U00012345'[1] + u'\U00012345' + u'\uac00\u00ac')
+            self.assertEqual(s.getvalue(),
+                    '123\x907\x959\x907\x959\x907\x959\x827\xcf5\x810\x851')
+            c.write(u'\U00012345'[0])
+            self.assertEqual(s.getvalue(),
+                    '123\x907\x959\x907\x959\x907\x959\x827\xcf5\x810\x851')
+            self.assertRaises(UnicodeError, c.reset)
+            self.assertEqual(s.getvalue(),
+                    '123\x907\x959\x907\x959\x907\x959\x827\xcf5\x810\x851')
+
+        def test_utf_8(self):
+            s= StringIO.StringIO()
+            c = codecs.getwriter('utf-8')(s)
+            c.write(u'123')
+            self.assertEqual(s.getvalue(), '123')
+            c.write(u'\U00012345')
+            self.assertEqual(s.getvalue(), '123\xf0\x92\x8d\x85')
+
+            # Python utf-8 codec can't buffer surrogate pairs yet.
+            if 0:
+                c.write(u'\U00012345'[0])
+                self.assertEqual(s.getvalue(), '123\xf0\x92\x8d\x85')
+                c.write(u'\U00012345'[1] + u'\U00012345' + u'\uac00\u00ac')
+                self.assertEqual(s.getvalue(),
+                    '123\xf0\x92\x8d\x85\xf0\x92\x8d\x85\xf0\x92\x8d\x85'
+                    '\xea\xb0\x80\xc2\xac')
+                c.write(u'\U00012345'[0])
+                self.assertEqual(s.getvalue(),
+                    '123\xf0\x92\x8d\x85\xf0\x92\x8d\x85\xf0\x92\x8d\x85'
+                    '\xea\xb0\x80\xc2\xac')
+                c.reset()
+                self.assertEqual(s.getvalue(),
+                    '123\xf0\x92\x8d\x85\xf0\x92\x8d\x85\xf0\x92\x8d\x85'
+                    '\xea\xb0\x80\xc2\xac\xed\xa0\x88')
+                c.write(u'\U00012345'[1])
+                self.assertEqual(s.getvalue(),
+                    '123\xf0\x92\x8d\x85\xf0\x92\x8d\x85\xf0\x92\x8d\x85'
+                    '\xea\xb0\x80\xc2\xac\xed\xa0\x88\xed\xbd\x85')
+
+    else: # UCS4
+        pass
+
+    def test_streamwriter_strwrite(self):
+        s = StringIO.StringIO()
+        wr = codecs.getwriter('gb18030')(s)
+        wr.write('abcd')
+        self.assertEqual(s.getvalue(), 'abcd')
+
+class Test_ISO2022(unittest.TestCase):
+    def test_g2(self):
+        iso2022jp2 = '\x1b(B:hu4:unit\x1b.A\x1bNi de famille'
+        uni = u':hu4:unit\xe9 de famille'
+        self.assertEqual(iso2022jp2.decode('iso2022-jp-2'), uni)
+
+    def test_iso2022_jp_g0(self):
+        self.failIf('\x0e' in u'\N{SOFT HYPHEN}'.encode('iso-2022-jp-2'))
+        for encoding in ('iso-2022-jp-2004', 'iso-2022-jp-3'):
+            e = u'\u3406'.encode(encoding)
+            self.failIf(filter(lambda x: x >= '\x80', e))
+
+    def test_bug1572832(self):
+        if sys.maxunicode >= 0x10000:
+            myunichr = unichr
+        else:
+            myunichr = lambda x: unichr(0xD7C0+(x>>10)) + unichr(0xDC00+(x&0x3FF))
+
+        for x in xrange(0x10000, 0x110000):
+            # Any ISO 2022 codec will cause the segfault
+            myunichr(x).encode('iso_2022_jp', 'ignore')
+
+def test_main():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(Test_MultibyteCodec))
+    suite.addTest(unittest.makeSuite(Test_IncrementalEncoder))
+    suite.addTest(unittest.makeSuite(Test_IncrementalDecoder))
+    suite.addTest(unittest.makeSuite(Test_StreamWriter))
+    suite.addTest(unittest.makeSuite(Test_ISO2022))
+    test_support.run_suite(suite)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_multibytecodec_support.py
===================================================================
--- vendor/Python/current/Lib/test/test_multibytecodec_support.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_multibytecodec_support.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,318 @@
+#!/usr/bin/env python
+#
+# test_multibytecodec_support.py
+#   Common Unittest Routines for CJK codecs
+#
+
+import sys, codecs, os.path
+import unittest
+from test import test_support
+from StringIO import StringIO
+
+class TestBase:
+    encoding        = ''   # codec name
+    codec           = None # codec tuple (with 4 elements)
+    tstring         = ''   # string to test StreamReader
+
+    codectests      = None # must set. codec test tuple
+    roundtriptest   = 1    # set if roundtrip is possible with unicode
+    has_iso10646    = 0    # set if this encoding contains whole iso10646 map
+    xmlcharnametest = None # string to test xmlcharrefreplace
+    unmappedunicode = u'\udeee' # a unicode codepoint that is not mapped.
+
+    def setUp(self):
+        if self.codec is None:
+            self.codec = codecs.lookup(self.encoding)
+        self.encode = self.codec.encode
+        self.decode = self.codec.decode
+        self.reader = self.codec.streamreader
+        self.writer = self.codec.streamwriter
+        self.incrementalencoder = self.codec.incrementalencoder
+        self.incrementaldecoder = self.codec.incrementaldecoder
+
+    def test_chunkcoding(self):
+        for native, utf8 in zip(*[StringIO(f).readlines()
+                                  for f in self.tstring]):
+            u = self.decode(native)[0]
+            self.assertEqual(u, utf8.decode('utf-8'))
+            if self.roundtriptest:
+                self.assertEqual(native, self.encode(u)[0])
+
+    def test_errorhandle(self):
+        for source, scheme, expected in self.codectests:
+            if type(source) == type(''):
+                func = self.decode
+            else:
+                func = self.encode
+            if expected:
+                result = func(source, scheme)[0]
+                self.assertEqual(result, expected)
+            else:
+                self.assertRaises(UnicodeError, func, source, scheme)
+
+    def test_xmlcharrefreplace(self):
+        if self.has_iso10646:
+            return
+
+        s = u"\u0b13\u0b23\u0b60 nd eggs"
+        self.assertEqual(
+            self.encode(s, "xmlcharrefreplace")[0],
+            "&#2835;&#2851;&#2912; nd eggs"
+        )
+
+    def test_customreplace_encode(self):
+        if self.has_iso10646:
+            return
+
+        from htmlentitydefs import codepoint2name
+
+        def xmlcharnamereplace(exc):
+            if not isinstance(exc, UnicodeEncodeError):
+                raise TypeError("don't know how to handle %r" % exc)
+            l = []
+            for c in exc.object[exc.start:exc.end]:
+                if ord(c) in codepoint2name:
+                    l.append(u"&%s;" % codepoint2name[ord(c)])
+                else:
+                    l.append(u"&#%d;" % ord(c))
+            return (u"".join(l), exc.end)
+
+        codecs.register_error("test.xmlcharnamereplace", xmlcharnamereplace)
+
+        if self.xmlcharnametest:
+            sin, sout = self.xmlcharnametest
+        else:
+            sin = u"\xab\u211c\xbb = \u2329\u1234\u232a"
+            sout = "&laquo;&real;&raquo; = &lang;&#4660;&rang;"
+        self.assertEqual(self.encode(sin,
+                                    "test.xmlcharnamereplace")[0], sout)
+
+    def test_callback_wrong_objects(self):
+        def myreplace(exc):
+            return (ret, exc.end)
+        codecs.register_error("test.cjktest", myreplace)
+
+        for ret in ([1, 2, 3], [], None, object(), 'string', ''):
+            self.assertRaises(TypeError, self.encode, self.unmappedunicode,
+                              'test.cjktest')
+
+    def test_callback_long_index(self):
+        def myreplace(exc):
+            return (u'x', long(exc.end))
+        codecs.register_error("test.cjktest", myreplace)
+        self.assertEqual(self.encode(u'abcd' + self.unmappedunicode + u'efgh',
+                                     'test.cjktest'), ('abcdxefgh', 9))
+
+        def myreplace(exc):
+            return (u'x', sys.maxint + 1)
+        codecs.register_error("test.cjktest", myreplace)
+        self.assertRaises(IndexError, self.encode, self.unmappedunicode,
+                          'test.cjktest')
+
+    def test_callback_None_index(self):
+        def myreplace(exc):
+            return (u'x', None)
+        codecs.register_error("test.cjktest", myreplace)
+        self.assertRaises(TypeError, self.encode, self.unmappedunicode,
+                          'test.cjktest')
+
+    def test_callback_backward_index(self):
+        def myreplace(exc):
+            if myreplace.limit > 0:
+                myreplace.limit -= 1
+                return (u'REPLACED', 0)
+            else:
+                return (u'TERMINAL', exc.end)
+        myreplace.limit = 3
+        codecs.register_error("test.cjktest", myreplace)
+        self.assertEqual(self.encode(u'abcd' + self.unmappedunicode + u'efgh',
+                                     'test.cjktest'),
+                ('abcdREPLACEDabcdREPLACEDabcdREPLACEDabcdTERMINALefgh', 9))
+
+    def test_callback_forward_index(self):
+        def myreplace(exc):
+            return (u'REPLACED', exc.end + 2)
+        codecs.register_error("test.cjktest", myreplace)
+        self.assertEqual(self.encode(u'abcd' + self.unmappedunicode + u'efgh',
+                                     'test.cjktest'), ('abcdREPLACEDgh', 9))
+
+    def test_callback_index_outofbound(self):
+        def myreplace(exc):
+            return (u'TERM', 100)
+        codecs.register_error("test.cjktest", myreplace)
+        self.assertRaises(IndexError, self.encode, self.unmappedunicode,
+                          'test.cjktest')
+
+    def test_incrementalencoder(self):
+        UTF8Reader = codecs.getreader('utf-8')
+        for sizehint in [None] + range(1, 33) + \
+                        [64, 128, 256, 512, 1024]:
+            istream = UTF8Reader(StringIO(self.tstring[1]))
+            ostream = StringIO()
+            encoder = self.incrementalencoder()
+            while 1:
+                if sizehint is not None:
+                    data = istream.read(sizehint)
+                else:
+                    data = istream.read()
+
+                if not data:
+                    break
+                e = encoder.encode(data)
+                ostream.write(e)
+
+            self.assertEqual(ostream.getvalue(), self.tstring[0])
+
+    def test_incrementaldecoder(self):
+        UTF8Writer = codecs.getwriter('utf-8')
+        for sizehint in [None, -1] + range(1, 33) + \
+                        [64, 128, 256, 512, 1024]:
+            istream = StringIO(self.tstring[0])
+            ostream = UTF8Writer(StringIO())
+            decoder = self.incrementaldecoder()
+            while 1:
+                data = istream.read(sizehint)
+                if not data:
+                    break
+                else:
+                    u = decoder.decode(data)
+                    ostream.write(u)
+
+            self.assertEqual(ostream.getvalue(), self.tstring[1])
+
+    def test_incrementalencoder_error_callback(self):
+        inv = self.unmappedunicode
+
+        e = self.incrementalencoder()
+        self.assertRaises(UnicodeEncodeError, e.encode, inv, True)
+
+        e.errors = 'ignore'
+        self.assertEqual(e.encode(inv, True), '')
+
+        e.reset()
+        def tempreplace(exc):
+            return (u'called', exc.end)
+        codecs.register_error('test.incremental_error_callback', tempreplace)
+        e.errors = 'test.incremental_error_callback'
+        self.assertEqual(e.encode(inv, True), 'called')
+
+        # again
+        e.errors = 'ignore'
+        self.assertEqual(e.encode(inv, True), '')
+
+    def test_streamreader(self):
+        UTF8Writer = codecs.getwriter('utf-8')
+        for name in ["read", "readline", "readlines"]:
+            for sizehint in [None, -1] + range(1, 33) + \
+                            [64, 128, 256, 512, 1024]:
+                istream = self.reader(StringIO(self.tstring[0]))
+                ostream = UTF8Writer(StringIO())
+                func = getattr(istream, name)
+                while 1:
+                    data = func(sizehint)
+                    if not data:
+                        break
+                    if name == "readlines":
+                        ostream.writelines(data)
+                    else:
+                        ostream.write(data)
+
+                self.assertEqual(ostream.getvalue(), self.tstring[1])
+
+    def test_streamwriter(self):
+        readfuncs = ('read', 'readline', 'readlines')
+        UTF8Reader = codecs.getreader('utf-8')
+        for name in readfuncs:
+            for sizehint in [None] + range(1, 33) + \
+                            [64, 128, 256, 512, 1024]:
+                istream = UTF8Reader(StringIO(self.tstring[1]))
+                ostream = self.writer(StringIO())
+                func = getattr(istream, name)
+                while 1:
+                    if sizehint is not None:
+                        data = func(sizehint)
+                    else:
+                        data = func()
+
+                    if not data:
+                        break
+                    if name == "readlines":
+                        ostream.writelines(data)
+                    else:
+                        ostream.write(data)
+
+                self.assertEqual(ostream.getvalue(), self.tstring[0])
+
+if len(u'\U00012345') == 2: # ucs2 build
+    _unichr = unichr
+    def unichr(v):
+        if v >= 0x10000:
+            return _unichr(0xd800 + ((v - 0x10000) >> 10)) + \
+                   _unichr(0xdc00 + ((v - 0x10000) & 0x3ff))
+        else:
+            return _unichr(v)
+    _ord = ord
+    def ord(c):
+        if len(c) == 2:
+            return 0x10000 + ((_ord(c[0]) - 0xd800) << 10) + \
+                          (ord(c[1]) - 0xdc00)
+        else:
+            return _ord(c)
+
+class TestBase_Mapping(unittest.TestCase):
+    pass_enctest = []
+    pass_dectest = []
+    supmaps = []
+
+    def __init__(self, *args, **kw):
+        unittest.TestCase.__init__(self, *args, **kw)
+        self.open_mapping_file() # test it to report the error early
+
+    def open_mapping_file(self):
+        return test_support.open_urlresource(self.mapfileurl)
+
+    def test_mapping_file(self):
+        unichrs = lambda s: u''.join(map(unichr, map(eval, s.split('+'))))
+        urt_wa = {}
+
+        for line in self.open_mapping_file():
+            if not line:
+                break
+            data = line.split('#')[0].strip().split()
+            if len(data) != 2:
+                continue
+
+            csetval = eval(data[0])
+            if csetval <= 0x7F:
+                csetch = chr(csetval & 0xff)
+            elif csetval >= 0x1000000:
+                csetch = chr(csetval >> 24) + chr((csetval >> 16) & 0xff) + \
+                         chr((csetval >> 8) & 0xff) + chr(csetval & 0xff)
+            elif csetval >= 0x10000:
+                csetch = chr(csetval >> 16) + \
+                         chr((csetval >> 8) & 0xff) + chr(csetval & 0xff)
+            elif csetval >= 0x100:
+                csetch = chr(csetval >> 8) + chr(csetval & 0xff)
+            else:
+                continue
+
+            unich = unichrs(data[1])
+            if ord(unich) == 0xfffd or urt_wa.has_key(unich):
+                continue
+            urt_wa[unich] = csetch
+
+            self._testpoint(csetch, unich)
+
+    def test_mapping_supplemental(self):
+        for mapping in self.supmaps:
+            self._testpoint(*mapping)
+
+    def _testpoint(self, csetch, unich):
+        if (csetch, unich) not in self.pass_enctest:
+            self.assertEqual(unich.encode(self.encoding), csetch)
+        if (csetch, unich) not in self.pass_dectest:
+            self.assertEqual(unicode(csetch, self.encoding), unich)
+
+def load_teststring(encoding):
+    from test import cjkencodings_test
+    return cjkencodings_test.teststring[encoding]

Added: vendor/Python/current/Lib/test/test_multifile.py
===================================================================
--- vendor/Python/current/Lib/test/test_multifile.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_multifile.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,66 @@
+import mimetools
+import multifile
+import cStringIO
+
+msg = """Mime-Version: 1.0
+Content-Type: multipart/mixed;
+        boundary="=====================_590453667==_"
+X-OriginalArrivalTime: 05 Feb 2002 03:43:23.0310 (UTC) FILETIME=[42D88CE0:01C1ADF7]
+
+--=====================_590453667==_
+Content-Type: multipart/alternative;
+        boundary="=====================_590453677==_.ALT"
+
+--=====================_590453677==_.ALT
+Content-Type: text/plain; charset="us-ascii"; format=flowed
+
+test A
+--=====================_590453677==_.ALT
+Content-Type: text/html; charset="us-ascii"
+
+<html>
+<b>test B</font></b></html>
+
+--=====================_590453677==_.ALT--
+
+--=====================_590453667==_
+Content-Type: text/plain; charset="us-ascii"
+Content-Disposition: attachment; filename="att.txt"
+
+Attached Content.
+Attached Content.
+Attached Content.
+Attached Content.
+
+--=====================_590453667==_--
+
+"""
+
+def getMIMEMsg(mf):
+    global boundaries, linecount
+    msg = mimetools.Message(mf)
+
+    #print "TYPE: %s" % msg.gettype()
+    if msg.getmaintype() == 'multipart':
+        boundary = msg.getparam("boundary")
+        boundaries += 1
+
+        mf.push(boundary)
+        while mf.next():
+            getMIMEMsg(mf)
+        mf.pop()
+    else:
+        lines = mf.readlines()
+        linecount += len(lines)
+
+def test_main():
+    global boundaries, linecount
+    boundaries = 0
+    linecount = 0
+    f = cStringIO.StringIO(msg)
+    getMIMEMsg(multifile.MultiFile(f))
+    assert boundaries == 2
+    assert linecount == 9
+
+if __name__ == '__main__':
+    test_main()

Added: vendor/Python/current/Lib/test/test_mutants.py
===================================================================
--- vendor/Python/current/Lib/test/test_mutants.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_mutants.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,292 @@
+from test.test_support import verbose, TESTFN
+import random
+import os
+
+# From SF bug #422121:  Insecurities in dict comparison.
+
+# Safety of code doing comparisons has been an historical Python weak spot.
+# The problem is that comparison of structures written in C *naturally*
+# wants to hold on to things like the size of the container, or "the
+# biggest" containee so far, across a traversal of the container; but
+# code to do containee comparisons can call back into Python and mutate
+# the container in arbitrary ways while the C loop is in midstream.  If the
+# C code isn't extremely paranoid about digging things out of memory on
+# each trip, and artificially boosting refcounts for the duration, anything
+# from infinite loops to OS crashes can result (yes, I use Windows <wink>).
+#
+# The other problem is that code designed to provoke a weakness is usually
+# white-box code, and so catches only the particular vulnerabilities the
+# author knew to protect against.  For example, Python's list.sort() code
+# went thru many iterations as one "new" vulnerability after another was
+# discovered.
+#
+# So the dict comparison test here uses a black-box approach instead,
+# generating dicts of various sizes at random, and performing random
+# mutations on them at random times.  This proved very effective,
+# triggering at least six distinct failure modes the first 20 times I
+# ran it.  Indeed, at the start, the driver never got beyond 6 iterations
+# before the test died.
+
+# The dicts are global to make it easy to mutate tham from within functions.
+dict1 = {}
+dict2 = {}
+
+# The current set of keys in dict1 and dict2.  These are materialized as
+# lists to make it easy to pick a dict key at random.
+dict1keys = []
+dict2keys = []
+
+# Global flag telling maybe_mutate() whether to *consider* mutating.
+mutate = 0
+
+# If global mutate is true, consider mutating a dict.  May or may not
+# mutate a dict even if mutate is true.  If it does decide to mutate a
+# dict, it picks one of {dict1, dict2} at random, and deletes a random
+# entry from it; or, more rarely, adds a random element.
+
+def maybe_mutate():
+    global mutate
+    if not mutate:
+        return
+    if random.random() < 0.5:
+        return
+
+    if random.random() < 0.5:
+        target, keys = dict1, dict1keys
+    else:
+        target, keys = dict2, dict2keys
+
+    if random.random() < 0.2:
+        # Insert a new key.
+        mutate = 0   # disable mutation until key inserted
+        while 1:
+            newkey = Horrid(random.randrange(100))
+            if newkey not in target:
+                break
+        target[newkey] = Horrid(random.randrange(100))
+        keys.append(newkey)
+        mutate = 1
+
+    elif keys:
+        # Delete a key at random.
+        mutate = 0   # disable mutation until key deleted
+        i = random.randrange(len(keys))
+        key = keys[i]
+        del target[key]
+        del keys[i]
+        mutate = 1
+
+# A horrid class that triggers random mutations of dict1 and dict2 when
+# instances are compared.
+
+class Horrid:
+    def __init__(self, i):
+        # Comparison outcomes are determined by the value of i.
+        self.i = i
+
+        # An artificial hashcode is selected at random so that we don't
+        # have any systematic relationship between comparison outcomes
+        # (based on self.i and other.i) and relative position within the
+        # hash vector (based on hashcode).
+        self.hashcode = random.randrange(1000000000)
+
+    def __hash__(self):
+        return 42
+        return self.hashcode
+
+    def __cmp__(self, other):
+        maybe_mutate()   # The point of the test.
+        return cmp(self.i, other.i)
+
+    def __eq__(self, other):
+        maybe_mutate()   # The point of the test.
+        return self.i == other.i
+
+    def __repr__(self):
+        return "Horrid(%d)" % self.i
+
+# Fill dict d with numentries (Horrid(i), Horrid(j)) key-value pairs,
+# where i and j are selected at random from the candidates list.
+# Return d.keys() after filling.
+
+def fill_dict(d, candidates, numentries):
+    d.clear()
+    for i in xrange(numentries):
+        d[Horrid(random.choice(candidates))] = \
+            Horrid(random.choice(candidates))
+    return d.keys()
+
+# Test one pair of randomly generated dicts, each with n entries.
+# Note that dict comparison is trivial if they don't have the same number
+# of entires (then the "shorter" dict is instantly considered to be the
+# smaller one, without even looking at the entries).
+
+def test_one(n):
+    global mutate, dict1, dict2, dict1keys, dict2keys
+
+    # Fill the dicts without mutating them.
+    mutate = 0
+    dict1keys = fill_dict(dict1, range(n), n)
+    dict2keys = fill_dict(dict2, range(n), n)
+
+    # Enable mutation, then compare the dicts so long as they have the
+    # same size.
+    mutate = 1
+    if verbose:
+        print "trying w/ lengths", len(dict1), len(dict2),
+    while dict1 and len(dict1) == len(dict2):
+        if verbose:
+            print ".",
+        if random.random() < 0.5:
+            c = cmp(dict1, dict2)
+        else:
+            c = dict1 == dict2
+    if verbose:
+        print
+
+# Run test_one n times.  At the start (before the bugs were fixed), 20
+# consecutive runs of this test each blew up on or before the sixth time
+# test_one was run.  So n doesn't have to be large to get an interesting
+# test.
+# OTOH, calling with large n is also interesting, to ensure that the fixed
+# code doesn't hold on to refcounts *too* long (in which case memory would
+# leak).
+
+def test(n):
+    for i in xrange(n):
+        test_one(random.randrange(1, 100))
+
+# See last comment block for clues about good values for n.
+test(100)
+
+##########################################################################
+# Another segfault bug, distilled by Michael Hudson from a c.l.py post.
+
+class Child:
+    def __init__(self, parent):
+        self.__dict__['parent'] = parent
+    def __getattr__(self, attr):
+        self.parent.a = 1
+        self.parent.b = 1
+        self.parent.c = 1
+        self.parent.d = 1
+        self.parent.e = 1
+        self.parent.f = 1
+        self.parent.g = 1
+        self.parent.h = 1
+        self.parent.i = 1
+        return getattr(self.parent, attr)
+
+class Parent:
+    def __init__(self):
+        self.a = Child(self)
+
+# Hard to say what this will print!  May vary from time to time.  But
+# we're specifically trying to test the tp_print slot here, and this is
+# the clearest way to do it.  We print the result to a temp file so that
+# the expected-output file doesn't need to change.
+
+f = open(TESTFN, "w")
+print >> f, Parent().__dict__
+f.close()
+os.unlink(TESTFN)
+
+##########################################################################
+# And another core-dumper from Michael Hudson.
+
+dict = {}
+
+# Force dict to malloc its table.
+for i in range(1, 10):
+    dict[i] = i
+
+f = open(TESTFN, "w")
+
+class Machiavelli:
+    def __repr__(self):
+        dict.clear()
+
+        # Michael sez:  "doesn't crash without this.  don't know why."
+        # Tim sez:  "luck of the draw; crashes with or without for me."
+        print >> f
+
+        return `"machiavelli"`
+
+    def __hash__(self):
+        return 0
+
+dict[Machiavelli()] = Machiavelli()
+
+print >> f, str(dict)
+f.close()
+os.unlink(TESTFN)
+del f, dict
+
+
+##########################################################################
+# And another core-dumper from Michael Hudson.
+
+dict = {}
+
+# let's force dict to malloc its table
+for i in range(1, 10):
+    dict[i] = i
+
+class Machiavelli2:
+    def __eq__(self, other):
+        dict.clear()
+        return 1
+
+    def __hash__(self):
+        return 0
+
+dict[Machiavelli2()] = Machiavelli2()
+
+try:
+    dict[Machiavelli2()]
+except KeyError:
+    pass
+
+del dict
+
+##########################################################################
+# And another core-dumper from Michael Hudson.
+
+dict = {}
+
+# let's force dict to malloc its table
+for i in range(1, 10):
+    dict[i] = i
+
+class Machiavelli3:
+    def __init__(self, id):
+        self.id = id
+
+    def __eq__(self, other):
+        if self.id == other.id:
+            dict.clear()
+            return 1
+        else:
+            return 0
+
+    def __repr__(self):
+        return "%s(%s)"%(self.__class__.__name__, self.id)
+
+    def __hash__(self):
+        return 0
+
+dict[Machiavelli3(1)] = Machiavelli3(0)
+dict[Machiavelli3(2)] = Machiavelli3(0)
+
+f = open(TESTFN, "w")
+try:
+    try:
+        print >> f, dict[Machiavelli3(2)]
+    except KeyError:
+        pass
+finally:
+    f.close()
+    os.unlink(TESTFN)
+
+del dict
+del dict1, dict2, dict1keys, dict2keys

Added: vendor/Python/current/Lib/test/test_netrc.py
===================================================================
--- vendor/Python/current/Lib/test/test_netrc.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_netrc.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,48 @@
+
+import netrc, os, unittest, sys
+from test import test_support
+
+TEST_NETRC = """
+machine foo login log1 password pass1 account acct1
+
+macdef macro1
+line1
+line2
+
+macdef macro2
+line3
+line4
+
+default login log2 password pass2
+
+"""
+
+temp_filename = test_support.TESTFN
+
+class NetrcTestCase(unittest.TestCase):
+
+    def setUp (self):
+        mode = 'w'
+        if sys.platform not in ['cygwin']:
+            mode += 't'
+        fp = open(temp_filename, mode)
+        fp.write(TEST_NETRC)
+        fp.close()
+        self.netrc = netrc.netrc(temp_filename)
+
+    def tearDown (self):
+        del self.netrc
+        os.unlink(temp_filename)
+
+    def test_case_1(self):
+        self.assert_(self.netrc.macros == {'macro1':['line1\n', 'line2\n'],
+                                           'macro2':['line3\n', 'line4\n']}
+                                           )
+        self.assert_(self.netrc.hosts['foo'] == ('log1', 'acct1', 'pass1'))
+        self.assert_(self.netrc.hosts['default'] == ('log2', None, 'pass2'))
+
+def test_main():
+    test_support.run_unittest(NetrcTestCase)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_new.py
===================================================================
--- vendor/Python/current/Lib/test/test_new.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_new.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,183 @@
+from test.test_support import verbose, verify, TestFailed
+import sys
+import new
+
+class Eggs:
+    def get_yolks(self):
+        return self.yolks
+
+print 'new.module()'
+m = new.module('Spam')
+if verbose:
+    print m
+m.Eggs = Eggs
+sys.modules['Spam'] = m
+import Spam
+
+def get_more_yolks(self):
+    return self.yolks + 3
+
+print 'new.classobj()'
+C = new.classobj('Spam', (Spam.Eggs,), {'get_more_yolks': get_more_yolks})
+if verbose:
+    print C
+print 'new.instance()'
+c = new.instance(C, {'yolks': 3})
+if verbose:
+    print c
+o = new.instance(C)
+verify(o.__dict__ == {},
+       "new __dict__ should be empty")
+del o
+o = new.instance(C, None)
+verify(o.__dict__ == {},
+       "new __dict__ should be empty")
+del o
+
+def break_yolks(self):
+    self.yolks = self.yolks - 2
+print 'new.instancemethod()'
+im = new.instancemethod(break_yolks, c, C)
+if verbose:
+    print im
+
+verify(c.get_yolks() == 3 and c.get_more_yolks() == 6,
+       'Broken call of hand-crafted class instance')
+im()
+verify(c.get_yolks() == 1 and c.get_more_yolks() == 4,
+       'Broken call of hand-crafted instance method')
+
+im = new.instancemethod(break_yolks, c)
+im()
+verify(c.get_yolks() == -1)
+try:
+    new.instancemethod(break_yolks, None)
+except TypeError:
+    pass
+else:
+    raise TestFailed, "dangerous instance method creation allowed"
+
+# Verify that instancemethod() doesn't allow keyword args
+try:
+    new.instancemethod(break_yolks, c, kw=1)
+except TypeError:
+    pass
+else:
+    raise TestFailed, "instancemethod shouldn't accept keyword args"
+
+# It's unclear what the semantics should be for a code object compiled at
+# module scope, but bound and run in a function.  In CPython, `c' is global
+# (by accident?) while in Jython, `c' is local.  The intent of the test
+# clearly is to make `c' global, so let's be explicit about it.
+codestr = '''
+global c
+a = 1
+b = 2
+c = a + b
+'''
+
+ccode = compile(codestr, '<string>', 'exec')
+# Jython doesn't have a __builtins__, so use a portable alternative
+import __builtin__
+g = {'c': 0, '__builtins__': __builtin__}
+# this test could be more robust
+print 'new.function()'
+func = new.function(ccode, g)
+if verbose:
+    print func
+func()
+verify(g['c'] == 3,
+       'Could not create a proper function object')
+
+# test the various extended flavors of function.new
+def f(x):
+    def g(y):
+        return x + y
+    return g
+g = f(4)
+new.function(f.func_code, {}, "blah")
+g2 = new.function(g.func_code, {}, "blah", (2,), g.func_closure)
+verify(g2() == 6)
+g3 = new.function(g.func_code, {}, "blah", None, g.func_closure)
+verify(g3(5) == 9)
+def test_closure(func, closure, exc):
+    try:
+        new.function(func.func_code, {}, "", None, closure)
+    except exc:
+        pass
+    else:
+        print "corrupt closure accepted"
+
+test_closure(g, None, TypeError) # invalid closure
+test_closure(g, (1,), TypeError) # non-cell in closure
+test_closure(g, (1, 1), ValueError) # closure is wrong size
+test_closure(f, g.func_closure, ValueError) # no closure needed
+
+print 'new.code()'
+# bogus test of new.code()
+# Note: Jython will never have new.code()
+if hasattr(new, 'code'):
+    def f(a): pass
+
+    c = f.func_code
+    argcount = c.co_argcount
+    nlocals = c.co_nlocals
+    stacksize = c.co_stacksize
+    flags = c.co_flags
+    codestring = c.co_code
+    constants = c.co_consts
+    names = c.co_names
+    varnames = c.co_varnames
+    filename = c.co_filename
+    name = c.co_name
+    firstlineno = c.co_firstlineno
+    lnotab = c.co_lnotab
+    freevars = c.co_freevars
+    cellvars = c.co_cellvars
+
+    d = new.code(argcount, nlocals, stacksize, flags, codestring,
+                 constants, names, varnames, filename, name,
+                 firstlineno, lnotab, freevars, cellvars)
+
+    # test backwards-compatibility version with no freevars or cellvars
+    d = new.code(argcount, nlocals, stacksize, flags, codestring,
+                 constants, names, varnames, filename, name,
+                 firstlineno, lnotab)
+
+    try: # this used to trigger a SystemError
+        d = new.code(-argcount, nlocals, stacksize, flags, codestring,
+                     constants, names, varnames, filename, name,
+                     firstlineno, lnotab)
+    except ValueError:
+        pass
+    else:
+        raise TestFailed, "negative co_argcount didn't trigger an exception"
+
+    try: # this used to trigger a SystemError
+        d = new.code(argcount, -nlocals, stacksize, flags, codestring,
+                     constants, names, varnames, filename, name,
+                     firstlineno, lnotab)
+    except ValueError:
+        pass
+    else:
+        raise TestFailed, "negative co_nlocals didn't trigger an exception"
+
+    try: # this used to trigger a Py_FatalError!
+        d = new.code(argcount, nlocals, stacksize, flags, codestring,
+                     constants, (5,), varnames, filename, name,
+                     firstlineno, lnotab)
+    except TypeError:
+        pass
+    else:
+        raise TestFailed, "non-string co_name didn't trigger an exception"
+
+    # new.code used to be a way to mutate a tuple...
+    class S(str): pass
+    t = (S("ab"),)
+    d = new.code(argcount, nlocals, stacksize, flags, codestring,
+                 constants, t, varnames, filename, name,
+                 firstlineno, lnotab)
+    verify(type(t[0]) is S, "eek, tuple changed under us!")
+
+    if verbose:
+        print d

Added: vendor/Python/current/Lib/test/test_nis.py
===================================================================
--- vendor/Python/current/Lib/test/test_nis.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_nis.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,39 @@
+from test.test_support import verbose, TestFailed, TestSkipped
+import nis
+
+print 'nis.maps()'
+try:
+    maps = nis.maps()
+except nis.error, msg:
+    # NIS is probably not active, so this test isn't useful
+    if verbose:
+        raise TestFailed, msg
+    # only do this if running under the regression suite
+    raise TestSkipped, msg
+
+try:
+    # On some systems, this map is only accessible to the
+    # super user
+    maps.remove("passwd.adjunct.byname")
+except ValueError:
+    pass
+
+done = 0
+for nismap in maps:
+    if verbose:
+        print nismap
+    mapping = nis.cat(nismap)
+    for k, v in mapping.items():
+        if verbose:
+            print '    ', k, v
+        if not k:
+            continue
+        if nis.match(k, nismap) != v:
+            print "NIS match failed for key `%s' in map `%s'" % (k, nismap)
+        else:
+            # just test the one key, otherwise this test could take a
+            # very long time
+            done = 1
+            break
+    if done:
+        break

Added: vendor/Python/current/Lib/test/test_normalization.py
===================================================================
--- vendor/Python/current/Lib/test/test_normalization.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_normalization.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,88 @@
+from test.test_support import (verbose, TestFailed, TestSkipped, verify,
+                               open_urlresource)
+import sys
+import os
+from unicodedata import normalize
+
+TESTDATAFILE = "NormalizationTest" + os.extsep + "txt"
+TESTDATAURL = "http://www.unicode.org/Public/4.1.0/ucd/" + TESTDATAFILE
+
+class RangeError(Exception):
+    pass
+
+def NFC(str):
+    return normalize("NFC", str)
+
+def NFKC(str):
+    return normalize("NFKC", str)
+
+def NFD(str):
+    return normalize("NFD", str)
+
+def NFKD(str):
+    return normalize("NFKD", str)
+
+def unistr(data):
+    data = [int(x, 16) for x in data.split(" ")]
+    for x in data:
+        if x > sys.maxunicode:
+            raise RangeError
+    return u"".join([unichr(x) for x in data])
+
+def test_main():
+    part1_data = {}
+    for line in open_urlresource(TESTDATAURL):
+        if '#' in line:
+            line = line.split('#')[0]
+        line = line.strip()
+        if not line:
+            continue
+        if line.startswith("@Part"):
+            part = line.split()[0]
+            continue
+        if part == "@Part3":
+            # XXX we don't support PRI #29 yet, so skip these tests for now
+            continue
+        try:
+            c1,c2,c3,c4,c5 = [unistr(x) for x in line.split(';')[:-1]]
+        except RangeError:
+            # Skip unsupported characters;
+            # try atleast adding c1 if we are in part1
+            if part == "@Part1":
+                try:
+                    c1=unistr(line.split(';')[0])
+                except RangeError:
+                    pass
+                else:
+                    part1_data[c1] = 1
+            continue
+
+        if verbose:
+            print line
+
+        # Perform tests
+        verify(c2 ==  NFC(c1) ==  NFC(c2) ==  NFC(c3), line)
+        verify(c4 ==  NFC(c4) ==  NFC(c5), line)
+        verify(c3 ==  NFD(c1) ==  NFD(c2) ==  NFD(c3), line)
+        verify(c5 ==  NFD(c4) ==  NFD(c5), line)
+        verify(c4 == NFKC(c1) == NFKC(c2) == NFKC(c3) == NFKC(c4) == NFKC(c5),
+               line)
+        verify(c5 == NFKD(c1) == NFKD(c2) == NFKD(c3) == NFKD(c4) == NFKD(c5),
+               line)
+
+        # Record part 1 data
+        if part == "@Part1":
+            part1_data[c1] = 1
+
+    # Perform tests for all other data
+    for c in range(sys.maxunicode+1):
+        X = unichr(c)
+        if X in part1_data:
+            continue
+        assert X == NFC(X) == NFD(X) == NFKC(X) == NFKD(X), c
+
+    # Check for bug 834676
+    normalize('NFC',u'\ud55c\uae00')
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_ntpath.py
===================================================================
--- vendor/Python/current/Lib/test/test_ntpath.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_ntpath.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,133 @@
+import ntpath
+from test.test_support import verbose, TestFailed
+import os
+
+errors = 0
+
+def tester(fn, wantResult):
+    global errors
+    fn = fn.replace("\\", "\\\\")
+    gotResult = eval(fn)
+    if wantResult != gotResult:
+        print "error!"
+        print "evaluated: " + str(fn)
+        print "should be: " + str(wantResult)
+        print " returned: " + str(gotResult)
+        print ""
+        errors = errors + 1
+
+tester('ntpath.splitext("foo.ext")', ('foo', '.ext'))
+tester('ntpath.splitext("/foo/foo.ext")', ('/foo/foo', '.ext'))
+tester('ntpath.splitext(".ext")', ('', '.ext'))
+tester('ntpath.splitext("\\foo.ext\\foo")', ('\\foo.ext\\foo', ''))
+tester('ntpath.splitext("foo.ext\\")', ('foo.ext\\', ''))
+tester('ntpath.splitext("")', ('', ''))
+tester('ntpath.splitext("foo.bar.ext")', ('foo.bar', '.ext'))
+tester('ntpath.splitext("xx/foo.bar.ext")', ('xx/foo.bar', '.ext'))
+tester('ntpath.splitext("xx\\foo.bar.ext")', ('xx\\foo.bar', '.ext'))
+
+tester('ntpath.splitdrive("c:\\foo\\bar")',
+       ('c:', '\\foo\\bar'))
+tester('ntpath.splitunc("\\\\conky\\mountpoint\\foo\\bar")',
+       ('\\\\conky\\mountpoint', '\\foo\\bar'))
+tester('ntpath.splitdrive("c:/foo/bar")',
+       ('c:', '/foo/bar'))
+tester('ntpath.splitunc("//conky/mountpoint/foo/bar")',
+       ('//conky/mountpoint', '/foo/bar'))
+
+tester('ntpath.split("c:\\foo\\bar")', ('c:\\foo', 'bar'))
+tester('ntpath.split("\\\\conky\\mountpoint\\foo\\bar")',
+       ('\\\\conky\\mountpoint\\foo', 'bar'))
+
+tester('ntpath.split("c:\\")', ('c:\\', ''))
+tester('ntpath.split("\\\\conky\\mountpoint\\")',
+       ('\\\\conky\\mountpoint', ''))
+
+tester('ntpath.split("c:/")', ('c:/', ''))
+tester('ntpath.split("//conky/mountpoint/")', ('//conky/mountpoint', ''))
+
+tester('ntpath.isabs("c:\\")', 1)
+tester('ntpath.isabs("\\\\conky\\mountpoint\\")', 1)
+tester('ntpath.isabs("\\foo")', 1)
+tester('ntpath.isabs("\\foo\\bar")', 1)
+
+tester('ntpath.commonprefix(["/home/swenson/spam", "/home/swen/spam"])',
+       "/home/swen")
+tester('ntpath.commonprefix(["\\home\\swen\\spam", "\\home\\swen\\eggs"])',
+       "\\home\\swen\\")
+tester('ntpath.commonprefix(["/home/swen/spam", "/home/swen/spam"])',
+       "/home/swen/spam")
+
+tester('ntpath.join("")', '')
+tester('ntpath.join("", "", "")', '')
+tester('ntpath.join("a")', 'a')
+tester('ntpath.join("/a")', '/a')
+tester('ntpath.join("\\a")', '\\a')
+tester('ntpath.join("a:")', 'a:')
+tester('ntpath.join("a:", "b")', 'a:b')
+tester('ntpath.join("a:", "/b")', 'a:/b')
+tester('ntpath.join("a:", "\\b")', 'a:\\b')
+tester('ntpath.join("a", "/b")', '/b')
+tester('ntpath.join("a", "\\b")', '\\b')
+tester('ntpath.join("a", "b", "c")', 'a\\b\\c')
+tester('ntpath.join("a\\", "b", "c")', 'a\\b\\c')
+tester('ntpath.join("a", "b\\", "c")', 'a\\b\\c')
+tester('ntpath.join("a", "b", "\\c")', '\\c')
+tester('ntpath.join("d:\\", "\\pleep")', 'd:\\pleep')
+tester('ntpath.join("d:\\", "a", "b")', 'd:\\a\\b')
+tester("ntpath.join('c:', '/a')", 'c:/a')
+tester("ntpath.join('c:/', '/a')", 'c:/a')
+tester("ntpath.join('c:/a', '/b')", '/b')
+tester("ntpath.join('c:', 'd:/')", 'd:/')
+tester("ntpath.join('c:/', 'd:/')", 'd:/')
+tester("ntpath.join('c:/', 'd:/a/b')", 'd:/a/b')
+
+tester("ntpath.join('')", '')
+tester("ntpath.join('', '', '', '', '')", '')
+tester("ntpath.join('a')", 'a')
+tester("ntpath.join('', 'a')", 'a')
+tester("ntpath.join('', '', '', '', 'a')", 'a')
+tester("ntpath.join('a', '')", 'a\\')
+tester("ntpath.join('a', '', '', '', '')", 'a\\')
+tester("ntpath.join('a\\', '')", 'a\\')
+tester("ntpath.join('a\\', '', '', '', '')", 'a\\')
+
+tester("ntpath.normpath('A//////././//.//B')", r'A\B')
+tester("ntpath.normpath('A/./B')", r'A\B')
+tester("ntpath.normpath('A/foo/../B')", r'A\B')
+tester("ntpath.normpath('C:A//B')", r'C:A\B')
+tester("ntpath.normpath('D:A/./B')", r'D:A\B')
+tester("ntpath.normpath('e:A/foo/../B')", r'e:A\B')
+
+tester("ntpath.normpath('C:///A//B')", r'C:\A\B')
+tester("ntpath.normpath('D:///A/./B')", r'D:\A\B')
+tester("ntpath.normpath('e:///A/foo/../B')", r'e:\A\B')
+
+tester("ntpath.normpath('..')", r'..')
+tester("ntpath.normpath('.')", r'.')
+tester("ntpath.normpath('')", r'.')
+tester("ntpath.normpath('/')", '\\')
+tester("ntpath.normpath('c:/')", 'c:\\')
+tester("ntpath.normpath('/../.././..')", '\\')
+tester("ntpath.normpath('c:/../../..')", 'c:\\')
+tester("ntpath.normpath('../.././..')", r'..\..\..')
+tester("ntpath.normpath('K:../.././..')", r'K:..\..\..')
+tester("ntpath.normpath('C:////a/b')", r'C:\a\b')
+tester("ntpath.normpath('//machine/share//a/b')", r'\\machine\share\a\b')
+
+# ntpath.abspath() can only be used on a system with the "nt" module
+# (reasonably), so we protect this test with "import nt".  This allows
+# the rest of the tests for the ntpath module to be run to completion
+# on any platform, since most of the module is intended to be usable
+# from any platform.
+try:
+    import nt
+except ImportError:
+    pass
+else:
+    tester('ntpath.abspath("C:\\")', "C:\\")
+
+if errors:
+    raise TestFailed(str(errors) + " errors.")
+elif verbose:
+    print "No errors.  Thank your lucky stars."

Added: vendor/Python/current/Lib/test/test_old_mailbox.py
===================================================================
--- vendor/Python/current/Lib/test/test_old_mailbox.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_old_mailbox.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,153 @@
+# This set of tests exercises the backward-compatibility class
+# in mailbox.py (the ones without write support).
+
+import mailbox
+import os
+import time
+import unittest
+from test import test_support
+
+# cleanup earlier tests
+try:
+    os.unlink(test_support.TESTFN)
+except os.error:
+    pass
+
+FROM_ = "From some.body at dummy.domain  Sat Jul 24 13:43:35 2004\n"
+DUMMY_MESSAGE = """\
+From: some.body at dummy.domain
+To: me at my.domain
+Subject: Simple Test
+
+This is a dummy message.
+"""
+
+class MaildirTestCase(unittest.TestCase):
+
+    def setUp(self):
+        # create a new maildir mailbox to work with:
+        self._dir = test_support.TESTFN
+        os.mkdir(self._dir)
+        os.mkdir(os.path.join(self._dir, "cur"))
+        os.mkdir(os.path.join(self._dir, "tmp"))
+        os.mkdir(os.path.join(self._dir, "new"))
+        self._counter = 1
+        self._msgfiles = []
+
+    def tearDown(self):
+        map(os.unlink, self._msgfiles)
+        os.rmdir(os.path.join(self._dir, "cur"))
+        os.rmdir(os.path.join(self._dir, "tmp"))
+        os.rmdir(os.path.join(self._dir, "new"))
+        os.rmdir(self._dir)
+
+    def createMessage(self, dir, mbox=False):
+        t = int(time.time() % 1000000)
+        pid = self._counter
+        self._counter += 1
+        filename = os.extsep.join((str(t), str(pid), "myhostname", "mydomain"))
+        tmpname = os.path.join(self._dir, "tmp", filename)
+        newname = os.path.join(self._dir, dir, filename)
+        fp = open(tmpname, "w")
+        self._msgfiles.append(tmpname)
+        if mbox:
+            fp.write(FROM_)
+        fp.write(DUMMY_MESSAGE)
+        fp.close()
+        if hasattr(os, "link"):
+            os.link(tmpname, newname)
+        else:
+            fp = open(newname, "w")
+            fp.write(DUMMY_MESSAGE)
+            fp.close()
+        self._msgfiles.append(newname)
+        return tmpname
+
+    def test_empty_maildir(self):
+        """Test an empty maildir mailbox"""
+        # Test for regression on bug #117490:
+        self.mbox = mailbox.Maildir(test_support.TESTFN)
+        self.assert_(len(self.mbox) == 0)
+        self.assert_(self.mbox.next() is None)
+        self.assert_(self.mbox.next() is None)
+
+    def test_nonempty_maildir_cur(self):
+        self.createMessage("cur")
+        self.mbox = mailbox.Maildir(test_support.TESTFN)
+        self.assert_(len(self.mbox) == 1)
+        self.assert_(self.mbox.next() is not None)
+        self.assert_(self.mbox.next() is None)
+        self.assert_(self.mbox.next() is None)
+
+    def test_nonempty_maildir_new(self):
+        self.createMessage("new")
+        self.mbox = mailbox.Maildir(test_support.TESTFN)
+        self.assert_(len(self.mbox) == 1)
+        self.assert_(self.mbox.next() is not None)
+        self.assert_(self.mbox.next() is None)
+        self.assert_(self.mbox.next() is None)
+
+    def test_nonempty_maildir_both(self):
+        self.createMessage("cur")
+        self.createMessage("new")
+        self.mbox = mailbox.Maildir(test_support.TESTFN)
+        self.assert_(len(self.mbox) == 2)
+        self.assert_(self.mbox.next() is not None)
+        self.assert_(self.mbox.next() is not None)
+        self.assert_(self.mbox.next() is None)
+        self.assert_(self.mbox.next() is None)
+
+    def test_unix_mbox(self):
+        ### should be better!
+        import email.Parser
+        fname = self.createMessage("cur", True)
+        n = 0
+        for msg in mailbox.PortableUnixMailbox(open(fname),
+                                               email.Parser.Parser().parse):
+            n += 1
+            self.assertEqual(msg["subject"], "Simple Test")
+            self.assertEqual(len(str(msg)), len(FROM_)+len(DUMMY_MESSAGE))
+        self.assertEqual(n, 1)
+
+class MboxTestCase(unittest.TestCase):
+    def setUp(self):
+        # create a new maildir mailbox to work with:
+        self._path = test_support.TESTFN
+
+    def tearDown(self):
+        os.unlink(self._path)
+    
+    def test_from_regex (self):
+        # Testing new regex from bug #1633678
+        f = open(self._path, 'w')
+        f.write("""From fred at example.com Mon May 31 13:24:50 2004 +0200
+Subject: message 1
+
+body1
+From fred at example.com Mon May 31 13:24:50 2004 -0200
+Subject: message 2
+
+body2
+From fred at example.com Mon May 31 13:24:50 2004
+Subject: message 3
+
+body3
+From fred at example.com Mon May 31 13:24:50 2004
+Subject: message 4
+
+body4
+""")
+        f.close()
+        box = mailbox.UnixMailbox(open(self._path, 'r'))
+        self.assert_(len(list(iter(box))) == 4)
+
+
+    # XXX We still need more tests!
+
+
+def test_main():
+    test_support.run_unittest(MaildirTestCase, MboxTestCase)
+
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_opcodes.py
===================================================================
--- vendor/Python/current/Lib/test/test_opcodes.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_opcodes.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,101 @@
+# Python test set -- part 2, opcodes
+
+from test.test_support import TestFailed
+
+
+print '2. Opcodes'
+print 'XXX Not yet fully implemented'
+
+print '2.1 try inside for loop'
+n = 0
+for i in range(10):
+    n = n+i
+    try: 1/0
+    except NameError: pass
+    except ZeroDivisionError: pass
+    except TypeError: pass
+    try: pass
+    except: pass
+    try: pass
+    finally: pass
+    n = n+i
+if n != 90:
+    raise TestFailed, 'try inside for'
+
+
+print '2.2 raise class exceptions'
+
+class AClass: pass
+class BClass(AClass): pass
+class CClass: pass
+class DClass(AClass):
+    def __init__(self, ignore):
+        pass
+
+try: raise AClass()
+except: pass
+
+try: raise AClass()
+except AClass: pass
+
+try: raise BClass()
+except AClass: pass
+
+try: raise BClass()
+except CClass: raise TestFailed
+except: pass
+
+a = AClass()
+b = BClass()
+
+try: raise AClass, b
+except BClass, v:
+    if v != b: raise TestFailed, "v!=b"
+else: raise TestFailed, "no exception"
+
+try: raise b
+except AClass, v:
+    if v != b: raise TestFailed, "v!=b AClass"
+
+# not enough arguments
+try:  raise BClass, a
+except TypeError: pass
+
+try:  raise DClass, a
+except DClass, v:
+    if not isinstance(v, DClass):
+        raise TestFailed, "v not DClass"
+
+print '2.3 comparing function objects'
+
+f = eval('lambda: None')
+g = eval('lambda: None')
+if f == g: raise TestFailed, "functions should not be same"
+
+f = eval('lambda a: a')
+g = eval('lambda a: a')
+if f == g: raise TestFailed, "functions should not be same"
+
+f = eval('lambda a=1: a')
+g = eval('lambda a=1: a')
+if f == g: raise TestFailed, "functions should not be same"
+
+f = eval('lambda: 0')
+g = eval('lambda: 1')
+if f == g: raise TestFailed
+
+f = eval('lambda: None')
+g = eval('lambda a: None')
+if f == g: raise TestFailed
+
+f = eval('lambda a: None')
+g = eval('lambda b: None')
+if f == g: raise TestFailed
+
+f = eval('lambda a: None')
+g = eval('lambda a=None: None')
+if f == g: raise TestFailed
+
+f = eval('lambda a=0: None')
+g = eval('lambda a=1: None')
+if f == g: raise TestFailed

Added: vendor/Python/current/Lib/test/test_openpty.py
===================================================================
--- vendor/Python/current/Lib/test/test_openpty.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_openpty.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,19 @@
+# Test to see if openpty works. (But don't worry if it isn't available.)
+
+import os
+from test.test_support import verbose, TestFailed, TestSkipped
+
+try:
+    if verbose:
+        print "Calling os.openpty()"
+    master, slave = os.openpty()
+    if verbose:
+        print "(master, slave) = (%d, %d)"%(master, slave)
+except AttributeError:
+    raise TestSkipped, "No openpty() available."
+
+if not os.isatty(slave):
+    raise TestFailed, "Slave-end of pty is not a terminal."
+
+os.write(slave, 'Ping!')
+print os.read(master, 1024)

Added: vendor/Python/current/Lib/test/test_operations.py
===================================================================
--- vendor/Python/current/Lib/test/test_operations.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_operations.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,78 @@
+# Python test set -- part 3, built-in operations.
+
+
+print '3. Operations'
+print 'XXX Mostly not yet implemented'
+
+
+print '3.1 Dictionary lookups fail if __cmp__() raises an exception'
+
+class BadDictKey:
+
+    def __hash__(self):
+        return hash(self.__class__)
+
+    def __cmp__(self, other):
+        if isinstance(other, self.__class__):
+            print "raising error"
+            raise RuntimeError, "gotcha"
+        return other
+
+d = {}
+x1 = BadDictKey()
+x2 = BadDictKey()
+d[x1] = 1
+for stmt in ['d[x2] = 2',
+             'z = d[x2]',
+             'x2 in d',
+             'd.has_key(x2)',
+             'd.get(x2)',
+             'd.setdefault(x2, 42)',
+             'd.pop(x2)',
+             'd.update({x2: 2})']:
+    try:
+        exec stmt
+    except RuntimeError:
+        print "%s: caught the RuntimeError outside" % (stmt,)
+    else:
+        print "%s: No exception passed through!"     # old CPython behavior
+
+
+# Dict resizing bug, found by Jack Jansen in 2.2 CVS development.
+# This version got an assert failure in debug build, infinite loop in
+# release build.  Unfortunately, provoking this kind of stuff requires
+# a mix of inserts and deletes hitting exactly the right hash codes in
+# exactly the right order, and I can't think of a randomized approach
+# that would be *likely* to hit a failing case in reasonable time.
+
+d = {}
+for i in range(5):
+    d[i] = i
+for i in range(5):
+    del d[i]
+for i in range(5, 9):  # i==8 was the problem
+    d[i] = i
+
+
+# Another dict resizing bug (SF bug #1456209).
+# This caused Segmentation faults or Illegal instructions.
+
+class X(object):
+    def __hash__(self):
+        return 5
+    def __eq__(self, other):
+        if resizing:
+            d.clear()
+        return False
+d = {}
+resizing = False
+d[X()] = 1
+d[X()] = 2
+d[X()] = 3
+d[X()] = 4
+d[X()] = 5
+# now trigger a resize
+resizing = True
+d[9] = 6
+
+print 'resize bugs not triggered.'

Added: vendor/Python/current/Lib/test/test_operator.py
===================================================================
--- vendor/Python/current/Lib/test/test_operator.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_operator.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,490 @@
+import operator
+import unittest
+
+from test import test_support
+
+class Seq1:
+    def __init__(self, lst):
+        self.lst = lst
+    def __len__(self):
+        return len(self.lst)
+    def __getitem__(self, i):
+        return self.lst[i]
+    def __add__(self, other):
+        return self.lst + other.lst
+    def __mul__(self, other):
+        return self.lst * other
+    def __rmul__(self, other):
+        return other * self.lst
+
+class Seq2(object):
+    def __init__(self, lst):
+        self.lst = lst
+    def __len__(self):
+        return len(self.lst)
+    def __getitem__(self, i):
+        return self.lst[i]
+    def __add__(self, other):
+        return self.lst + other.lst
+    def __mul__(self, other):
+        return self.lst * other
+    def __rmul__(self, other):
+        return other * self.lst
+
+
+class OperatorTestCase(unittest.TestCase):
+    def test_lt(self):
+        self.failUnlessRaises(TypeError, operator.lt)
+        self.failUnlessRaises(TypeError, operator.lt, 1j, 2j)
+        self.failIf(operator.lt(1, 0))
+        self.failIf(operator.lt(1, 0.0))
+        self.failIf(operator.lt(1, 1))
+        self.failIf(operator.lt(1, 1.0))
+        self.failUnless(operator.lt(1, 2))
+        self.failUnless(operator.lt(1, 2.0))
+
+    def test_le(self):
+        self.failUnlessRaises(TypeError, operator.le)
+        self.failUnlessRaises(TypeError, operator.le, 1j, 2j)
+        self.failIf(operator.le(1, 0))
+        self.failIf(operator.le(1, 0.0))
+        self.failUnless(operator.le(1, 1))
+        self.failUnless(operator.le(1, 1.0))
+        self.failUnless(operator.le(1, 2))
+        self.failUnless(operator.le(1, 2.0))
+
+    def test_eq(self):
+        class C(object):
+            def __eq__(self, other):
+                raise SyntaxError
+        self.failUnlessRaises(TypeError, operator.eq)
+        self.failUnlessRaises(SyntaxError, operator.eq, C(), C())
+        self.failIf(operator.eq(1, 0))
+        self.failIf(operator.eq(1, 0.0))
+        self.failUnless(operator.eq(1, 1))
+        self.failUnless(operator.eq(1, 1.0))
+        self.failIf(operator.eq(1, 2))
+        self.failIf(operator.eq(1, 2.0))
+
+    def test_ne(self):
+        class C(object):
+            def __ne__(self, other):
+                raise SyntaxError
+        self.failUnlessRaises(TypeError, operator.ne)
+        self.failUnlessRaises(SyntaxError, operator.ne, C(), C())
+        self.failUnless(operator.ne(1, 0))
+        self.failUnless(operator.ne(1, 0.0))
+        self.failIf(operator.ne(1, 1))
+        self.failIf(operator.ne(1, 1.0))
+        self.failUnless(operator.ne(1, 2))
+        self.failUnless(operator.ne(1, 2.0))
+
+    def test_ge(self):
+        self.failUnlessRaises(TypeError, operator.ge)
+        self.failUnlessRaises(TypeError, operator.ge, 1j, 2j)
+        self.failUnless(operator.ge(1, 0))
+        self.failUnless(operator.ge(1, 0.0))
+        self.failUnless(operator.ge(1, 1))
+        self.failUnless(operator.ge(1, 1.0))
+        self.failIf(operator.ge(1, 2))
+        self.failIf(operator.ge(1, 2.0))
+
+    def test_gt(self):
+        self.failUnlessRaises(TypeError, operator.gt)
+        self.failUnlessRaises(TypeError, operator.gt, 1j, 2j)
+        self.failUnless(operator.gt(1, 0))
+        self.failUnless(operator.gt(1, 0.0))
+        self.failIf(operator.gt(1, 1))
+        self.failIf(operator.gt(1, 1.0))
+        self.failIf(operator.gt(1, 2))
+        self.failIf(operator.gt(1, 2.0))
+
+    def test_abs(self):
+        self.failUnlessRaises(TypeError, operator.abs)
+        self.failUnlessRaises(TypeError, operator.abs, None)
+        self.failUnless(operator.abs(-1) == 1)
+        self.failUnless(operator.abs(1) == 1)
+
+    def test_add(self):
+        self.failUnlessRaises(TypeError, operator.add)
+        self.failUnlessRaises(TypeError, operator.add, None, None)
+        self.failUnless(operator.add(3, 4) == 7)
+
+    def test_bitwise_and(self):
+        self.failUnlessRaises(TypeError, operator.and_)
+        self.failUnlessRaises(TypeError, operator.and_, None, None)
+        self.failUnless(operator.and_(0xf, 0xa) == 0xa)
+
+    def test_concat(self):
+        self.failUnlessRaises(TypeError, operator.concat)
+        self.failUnlessRaises(TypeError, operator.concat, None, None)
+        self.failUnless(operator.concat('py', 'thon') == 'python')
+        self.failUnless(operator.concat([1, 2], [3, 4]) == [1, 2, 3, 4])
+        self.failUnless(operator.concat(Seq1([5, 6]), Seq1([7])) == [5, 6, 7])
+        self.failUnless(operator.concat(Seq2([5, 6]), Seq2([7])) == [5, 6, 7])
+        self.failUnlessRaises(TypeError, operator.concat, 13, 29)
+
+    def test_countOf(self):
+        self.failUnlessRaises(TypeError, operator.countOf)
+        self.failUnlessRaises(TypeError, operator.countOf, None, None)
+        self.failUnless(operator.countOf([1, 2, 1, 3, 1, 4], 3) == 1)
+        self.failUnless(operator.countOf([1, 2, 1, 3, 1, 4], 5) == 0)
+
+    def test_delitem(self):
+        a = [4, 3, 2, 1]
+        self.failUnlessRaises(TypeError, operator.delitem, a)
+        self.failUnlessRaises(TypeError, operator.delitem, a, None)
+        self.failUnless(operator.delitem(a, 1) is None)
+        self.assert_(a == [4, 2, 1])
+
+    def test_delslice(self):
+        a = range(10)
+        self.failUnlessRaises(TypeError, operator.delslice, a)
+        self.failUnlessRaises(TypeError, operator.delslice, a, None, None)
+        self.failUnless(operator.delslice(a, 2, 8) is None)
+        self.assert_(a == [0, 1, 8, 9])
+        operator.delslice(a, 0, test_support.MAX_Py_ssize_t)
+        self.assert_(a == [])
+
+    def test_div(self):
+        self.failUnlessRaises(TypeError, operator.div, 5)
+        self.failUnlessRaises(TypeError, operator.div, None, None)
+        self.failUnless(operator.floordiv(5, 2) == 2)
+
+    def test_floordiv(self):
+        self.failUnlessRaises(TypeError, operator.floordiv, 5)
+        self.failUnlessRaises(TypeError, operator.floordiv, None, None)
+        self.failUnless(operator.floordiv(5, 2) == 2)
+
+    def test_truediv(self):
+        self.failUnlessRaises(TypeError, operator.truediv, 5)
+        self.failUnlessRaises(TypeError, operator.truediv, None, None)
+        self.failUnless(operator.truediv(5, 2) == 2.5)
+
+    def test_getitem(self):
+        a = range(10)
+        self.failUnlessRaises(TypeError, operator.getitem)
+        self.failUnlessRaises(TypeError, operator.getitem, a, None)
+        self.failUnless(operator.getitem(a, 2) == 2)
+
+    def test_getslice(self):
+        a = range(10)
+        self.failUnlessRaises(TypeError, operator.getslice)
+        self.failUnlessRaises(TypeError, operator.getslice, a, None, None)
+        self.failUnless(operator.getslice(a, 4, 6) == [4, 5])
+        b = operator.getslice(a, 0, test_support.MAX_Py_ssize_t)
+        self.assert_(b == a)
+
+    def test_indexOf(self):
+        self.failUnlessRaises(TypeError, operator.indexOf)
+        self.failUnlessRaises(TypeError, operator.indexOf, None, None)
+        self.failUnless(operator.indexOf([4, 3, 2, 1], 3) == 1)
+        self.assertRaises(ValueError, operator.indexOf, [4, 3, 2, 1], 0)
+
+    def test_invert(self):
+        self.failUnlessRaises(TypeError, operator.invert)
+        self.failUnlessRaises(TypeError, operator.invert, None)
+        self.failUnless(operator.inv(4) == -5)
+
+    def test_isCallable(self):
+        self.failUnlessRaises(TypeError, operator.isCallable)
+        class C:
+            pass
+        def check(self, o, v):
+            self.assert_(operator.isCallable(o) == callable(o) == v)
+        check(self, 4, 0)
+        check(self, operator.isCallable, 1)
+        check(self, C, 1)
+        check(self, C(), 0)
+
+    def test_isMappingType(self):
+        self.failUnlessRaises(TypeError, operator.isMappingType)
+        self.failIf(operator.isMappingType(1))
+        self.failIf(operator.isMappingType(operator.isMappingType))
+        self.failUnless(operator.isMappingType(operator.__dict__))
+        self.failUnless(operator.isMappingType({}))
+
+    def test_isNumberType(self):
+        self.failUnlessRaises(TypeError, operator.isNumberType)
+        self.failUnless(operator.isNumberType(8))
+        self.failUnless(operator.isNumberType(8j))
+        self.failUnless(operator.isNumberType(8L))
+        self.failUnless(operator.isNumberType(8.3))
+        self.failIf(operator.isNumberType(dir()))
+
+    def test_isSequenceType(self):
+        self.failUnlessRaises(TypeError, operator.isSequenceType)
+        self.failUnless(operator.isSequenceType(dir()))
+        self.failUnless(operator.isSequenceType(()))
+        self.failUnless(operator.isSequenceType(xrange(10)))
+        self.failUnless(operator.isSequenceType('yeahbuddy'))
+        self.failIf(operator.isSequenceType(3))
+        class Dict(dict): pass
+        self.failIf(operator.isSequenceType(Dict()))
+
+    def test_lshift(self):
+        self.failUnlessRaises(TypeError, operator.lshift)
+        self.failUnlessRaises(TypeError, operator.lshift, None, 42)
+        self.failUnless(operator.lshift(5, 1) == 10)
+        self.failUnless(operator.lshift(5, 0) == 5)
+        self.assertRaises(ValueError, operator.lshift, 2, -1)
+
+    def test_mod(self):
+        self.failUnlessRaises(TypeError, operator.mod)
+        self.failUnlessRaises(TypeError, operator.mod, None, 42)
+        self.failUnless(operator.mod(5, 2) == 1)
+
+    def test_mul(self):
+        self.failUnlessRaises(TypeError, operator.mul)
+        self.failUnlessRaises(TypeError, operator.mul, None, None)
+        self.failUnless(operator.mul(5, 2) == 10)
+
+    def test_neg(self):
+        self.failUnlessRaises(TypeError, operator.neg)
+        self.failUnlessRaises(TypeError, operator.neg, None)
+        self.failUnless(operator.neg(5) == -5)
+        self.failUnless(operator.neg(-5) == 5)
+        self.failUnless(operator.neg(0) == 0)
+        self.failUnless(operator.neg(-0) == 0)
+
+    def test_bitwise_or(self):
+        self.failUnlessRaises(TypeError, operator.or_)
+        self.failUnlessRaises(TypeError, operator.or_, None, None)
+        self.failUnless(operator.or_(0xa, 0x5) == 0xf)
+
+    def test_pos(self):
+        self.failUnlessRaises(TypeError, operator.pos)
+        self.failUnlessRaises(TypeError, operator.pos, None)
+        self.failUnless(operator.pos(5) == 5)
+        self.failUnless(operator.pos(-5) == -5)
+        self.failUnless(operator.pos(0) == 0)
+        self.failUnless(operator.pos(-0) == 0)
+
+    def test_pow(self):
+        self.failUnlessRaises(TypeError, operator.pow)
+        self.failUnlessRaises(TypeError, operator.pow, None, None)
+        self.failUnless(operator.pow(3,5) == 3**5)
+        self.failUnless(operator.__pow__(3,5) == 3**5)
+        self.assertRaises(TypeError, operator.pow, 1)
+        self.assertRaises(TypeError, operator.pow, 1, 2, 3)
+
+    def test_repeat(self):
+        a = range(3)
+        self.failUnlessRaises(TypeError, operator.repeat)
+        self.failUnlessRaises(TypeError, operator.repeat, a, None)
+        self.failUnless(operator.repeat(a, 2) == a+a)
+        self.failUnless(operator.repeat(a, 1) == a)
+        self.failUnless(operator.repeat(a, 0) == [])
+        a = (1, 2, 3)
+        self.failUnless(operator.repeat(a, 2) == a+a)
+        self.failUnless(operator.repeat(a, 1) == a)
+        self.failUnless(operator.repeat(a, 0) == ())
+        a = '123'
+        self.failUnless(operator.repeat(a, 2) == a+a)
+        self.failUnless(operator.repeat(a, 1) == a)
+        self.failUnless(operator.repeat(a, 0) == '')
+        a = Seq1([4, 5, 6])
+        self.failUnless(operator.repeat(a, 2) == [4, 5, 6, 4, 5, 6])
+        self.failUnless(operator.repeat(a, 1) == [4, 5, 6])
+        self.failUnless(operator.repeat(a, 0) == [])
+        a = Seq2([4, 5, 6])
+        self.failUnless(operator.repeat(a, 2) == [4, 5, 6, 4, 5, 6])
+        self.failUnless(operator.repeat(a, 1) == [4, 5, 6])
+        self.failUnless(operator.repeat(a, 0) == [])
+        self.failUnlessRaises(TypeError, operator.repeat, 6, 7)
+
+    def test_rshift(self):
+        self.failUnlessRaises(TypeError, operator.rshift)
+        self.failUnlessRaises(TypeError, operator.rshift, None, 42)
+        self.failUnless(operator.rshift(5, 1) == 2)
+        self.failUnless(operator.rshift(5, 0) == 5)
+        self.assertRaises(ValueError, operator.rshift, 2, -1)
+
+    def test_contains(self):
+        self.failUnlessRaises(TypeError, operator.contains)
+        self.failUnlessRaises(TypeError, operator.contains, None, None)
+        self.failUnless(operator.contains(range(4), 2))
+        self.failIf(operator.contains(range(4), 5))
+        self.failUnless(operator.sequenceIncludes(range(4), 2))
+        self.failIf(operator.sequenceIncludes(range(4), 5))
+
+    def test_setitem(self):
+        a = range(3)
+        self.failUnlessRaises(TypeError, operator.setitem, a)
+        self.failUnlessRaises(TypeError, operator.setitem, a, None, None)
+        self.failUnless(operator.setitem(a, 0, 2) is None)
+        self.assert_(a == [2, 1, 2])
+        self.assertRaises(IndexError, operator.setitem, a, 4, 2)
+
+    def test_setslice(self):
+        a = range(4)
+        self.failUnlessRaises(TypeError, operator.setslice, a)
+        self.failUnlessRaises(TypeError, operator.setslice, a, None, None, None)
+        self.failUnless(operator.setslice(a, 1, 3, [2, 1]) is None)
+        self.assert_(a == [0, 2, 1, 3])
+        operator.setslice(a, 0, test_support.MAX_Py_ssize_t, [])
+        self.assert_(a == [])
+
+    def test_sub(self):
+        self.failUnlessRaises(TypeError, operator.sub)
+        self.failUnlessRaises(TypeError, operator.sub, None, None)
+        self.failUnless(operator.sub(5, 2) == 3)
+
+    def test_truth(self):
+        class C(object):
+            def __nonzero__(self):
+                raise SyntaxError
+        self.failUnlessRaises(TypeError, operator.truth)
+        self.failUnlessRaises(SyntaxError, operator.truth, C())
+        self.failUnless(operator.truth(5))
+        self.failUnless(operator.truth([0]))
+        self.failIf(operator.truth(0))
+        self.failIf(operator.truth([]))
+
+    def test_bitwise_xor(self):
+        self.failUnlessRaises(TypeError, operator.xor)
+        self.failUnlessRaises(TypeError, operator.xor, None, None)
+        self.failUnless(operator.xor(0xb, 0xc) == 0x7)
+
+    def test_is(self):
+        a = b = 'xyzpdq'
+        c = a[:3] + b[3:]
+        self.failUnlessRaises(TypeError, operator.is_)
+        self.failUnless(operator.is_(a, b))
+        self.failIf(operator.is_(a,c))
+
+    def test_is_not(self):
+        a = b = 'xyzpdq'
+        c = a[:3] + b[3:]
+        self.failUnlessRaises(TypeError, operator.is_not)
+        self.failIf(operator.is_not(a, b))
+        self.failUnless(operator.is_not(a,c))
+
+    def test_attrgetter(self):
+        class A:
+            pass
+        a = A()
+        a.name = 'arthur'
+        f = operator.attrgetter('name')
+        self.assertEqual(f(a), 'arthur')
+        f = operator.attrgetter('rank')
+        self.assertRaises(AttributeError, f, a)
+        f = operator.attrgetter(2)
+        self.assertRaises(TypeError, f, a)
+        self.assertRaises(TypeError, operator.attrgetter)
+
+        # multiple gets
+        record = A()
+        record.x = 'X'
+        record.y = 'Y'
+        record.z = 'Z'
+        self.assertEqual(operator.attrgetter('x','z','y')(record), ('X', 'Z', 'Y'))
+        self.assertRaises(TypeError, operator.attrgetter('x', (), 'y'), record)
+
+        class C(object):
+            def __getattr(self, name):
+                raise SyntaxError
+        self.failUnlessRaises(AttributeError, operator.attrgetter('foo'), C())
+
+    def test_itemgetter(self):
+        a = 'ABCDE'
+        f = operator.itemgetter(2)
+        self.assertEqual(f(a), 'C')
+        f = operator.itemgetter(10)
+        self.assertRaises(IndexError, f, a)
+
+        class C(object):
+            def __getitem(self, name):
+                raise SyntaxError
+        self.failUnlessRaises(TypeError, operator.itemgetter(42), C())
+
+        f = operator.itemgetter('name')
+        self.assertRaises(TypeError, f, a)
+        self.assertRaises(TypeError, operator.itemgetter)
+
+        d = dict(key='val')
+        f = operator.itemgetter('key')
+        self.assertEqual(f(d), 'val')
+        f = operator.itemgetter('nonkey')
+        self.assertRaises(KeyError, f, d)
+
+        # example used in the docs
+        inventory = [('apple', 3), ('banana', 2), ('pear', 5), ('orange', 1)]
+        getcount = operator.itemgetter(1)
+        self.assertEqual(map(getcount, inventory), [3, 2, 5, 1])
+        self.assertEqual(sorted(inventory, key=getcount),
+            [('orange', 1), ('banana', 2), ('apple', 3), ('pear', 5)])
+
+        # multiple gets
+        data = map(str, range(20))
+        self.assertEqual(operator.itemgetter(2,10,5)(data), ('2', '10', '5'))
+        self.assertRaises(TypeError, operator.itemgetter(2, 'x', 5), data)
+
+    def test_inplace(self):
+        class C(object):
+            def __iadd__     (self, other): return "iadd"
+            def __iand__     (self, other): return "iand"
+            def __idiv__     (self, other): return "idiv"
+            def __ifloordiv__(self, other): return "ifloordiv"
+            def __ilshift__  (self, other): return "ilshift"
+            def __imod__     (self, other): return "imod"
+            def __imul__     (self, other): return "imul"
+            def __ior__      (self, other): return "ior"
+            def __ipow__     (self, other): return "ipow"
+            def __irshift__  (self, other): return "irshift"
+            def __isub__     (self, other): return "isub"
+            def __itruediv__ (self, other): return "itruediv"
+            def __ixor__     (self, other): return "ixor"
+            def __getitem__(self, other): return 5  # so that C is a sequence
+        c = C()
+        self.assertEqual(operator.iadd     (c, 5), "iadd")
+        self.assertEqual(operator.iand     (c, 5), "iand")
+        self.assertEqual(operator.idiv     (c, 5), "idiv")
+        self.assertEqual(operator.ifloordiv(c, 5), "ifloordiv")
+        self.assertEqual(operator.ilshift  (c, 5), "ilshift")
+        self.assertEqual(operator.imod     (c, 5), "imod")
+        self.assertEqual(operator.imul     (c, 5), "imul")
+        self.assertEqual(operator.ior      (c, 5), "ior")
+        self.assertEqual(operator.ipow     (c, 5), "ipow")
+        self.assertEqual(operator.irshift  (c, 5), "irshift")
+        self.assertEqual(operator.isub     (c, 5), "isub")
+        self.assertEqual(operator.itruediv (c, 5), "itruediv")
+        self.assertEqual(operator.ixor     (c, 5), "ixor")
+        self.assertEqual(operator.iconcat  (c, c), "iadd")
+        self.assertEqual(operator.irepeat  (c, 5), "imul")
+        self.assertEqual(operator.__iadd__     (c, 5), "iadd")
+        self.assertEqual(operator.__iand__     (c, 5), "iand")
+        self.assertEqual(operator.__idiv__     (c, 5), "idiv")
+        self.assertEqual(operator.__ifloordiv__(c, 5), "ifloordiv")
+        self.assertEqual(operator.__ilshift__  (c, 5), "ilshift")
+        self.assertEqual(operator.__imod__     (c, 5), "imod")
+        self.assertEqual(operator.__imul__     (c, 5), "imul")
+        self.assertEqual(operator.__ior__      (c, 5), "ior")
+        self.assertEqual(operator.__ipow__     (c, 5), "ipow")
+        self.assertEqual(operator.__irshift__  (c, 5), "irshift")
+        self.assertEqual(operator.__isub__     (c, 5), "isub")
+        self.assertEqual(operator.__itruediv__ (c, 5), "itruediv")
+        self.assertEqual(operator.__ixor__     (c, 5), "ixor")
+        self.assertEqual(operator.__iconcat__  (c, c), "iadd")
+        self.assertEqual(operator.__irepeat__  (c, 5), "imul")
+
+def test_main(verbose=None):
+    import sys
+    test_classes = (
+        OperatorTestCase,
+    )
+
+    test_support.run_unittest(*test_classes)
+
+    # verify reference counting
+    if verbose and hasattr(sys, "gettotalrefcount"):
+        import gc
+        counts = [None] * 5
+        for i in xrange(len(counts)):
+            test_support.run_unittest(*test_classes)
+            gc.collect()
+            counts[i] = sys.gettotalrefcount()
+        print counts
+
+if __name__ == "__main__":
+    test_main(verbose=True)

Added: vendor/Python/current/Lib/test/test_optparse.py
===================================================================
--- vendor/Python/current/Lib/test/test_optparse.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_optparse.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1640 @@
+#!/usr/bin/python
+
+#
+# Test suite for Optik.  Supplied by Johannes Gijsbers
+# (taradino at softhome.net) -- translated from the original Optik
+# test suite to this PyUnit-based version.
+#
+# $Id: test_optparse.py 50791 2006-07-23 16:05:51Z greg.ward $
+#
+
+import sys
+import os
+import re
+import copy
+import types
+import unittest
+
+from StringIO import StringIO
+from pprint import pprint
+from test import test_support
+
+
+from optparse import make_option, Option, IndentedHelpFormatter, \
+     TitledHelpFormatter, OptionParser, OptionContainer, OptionGroup, \
+     SUPPRESS_HELP, SUPPRESS_USAGE, OptionError, OptionConflictError, \
+     BadOptionError, OptionValueError, Values
+from optparse import _match_abbrev
+from optparse import _parse_num
+
+# Do the right thing with boolean values for all known Python versions.
+try:
+    True, False
+except NameError:
+    (True, False) = (1, 0)
+
+retype = type(re.compile(''))
+
+class InterceptedError(Exception):
+    def __init__(self,
+                 error_message=None,
+                 exit_status=None,
+                 exit_message=None):
+        self.error_message = error_message
+        self.exit_status = exit_status
+        self.exit_message = exit_message
+
+    def __str__(self):
+        return self.error_message or self.exit_message or "intercepted error"
+
+class InterceptingOptionParser(OptionParser):
+    def exit(self, status=0, msg=None):
+        raise InterceptedError(exit_status=status, exit_message=msg)
+
+    def error(self, msg):
+        raise InterceptedError(error_message=msg)
+
+
+class BaseTest(unittest.TestCase):
+    def assertParseOK(self, args, expected_opts, expected_positional_args):
+        """Assert the options are what we expected when parsing arguments.
+
+        Otherwise, fail with a nicely formatted message.
+
+        Keyword arguments:
+        args -- A list of arguments to parse with OptionParser.
+        expected_opts -- The options expected.
+        expected_positional_args -- The positional arguments expected.
+
+        Returns the options and positional args for further testing.
+        """
+
+        (options, positional_args) = self.parser.parse_args(args)
+        optdict = vars(options)
+
+        self.assertEqual(optdict, expected_opts,
+                         """
+Options are %(optdict)s.
+Should be %(expected_opts)s.
+Args were %(args)s.""" % locals())
+
+        self.assertEqual(positional_args, expected_positional_args,
+                         """
+Positional arguments are %(positional_args)s.
+Should be %(expected_positional_args)s.
+Args were %(args)s.""" % locals ())
+
+        return (options, positional_args)
+
+    def assertRaises(self,
+                     func,
+                     args,
+                     kwargs,
+                     expected_exception,
+                     expected_message):
+        """
+        Assert that the expected exception is raised when calling a
+        function, and that the right error message is included with
+        that exception.
+
+        Arguments:
+          func -- the function to call
+          args -- positional arguments to `func`
+          kwargs -- keyword arguments to `func`
+          expected_exception -- exception that should be raised
+          expected_message -- expected exception message (or pattern
+            if a compiled regex object)
+
+        Returns the exception raised for further testing.
+        """
+        if args is None:
+            args = ()
+        if kwargs is None:
+            kwargs = {}
+
+        try:
+            func(*args, **kwargs)
+        except expected_exception, err:
+            actual_message = str(err)
+            if isinstance(expected_message, retype):
+                self.assert_(expected_message.search(actual_message),
+                             """\
+expected exception message pattern:
+/%s/
+actual exception message:
+'''%s'''
+""" % (expected_message.pattern, actual_message))
+            else:
+                self.assertEqual(actual_message,
+                                 expected_message,
+                                 """\
+expected exception message:
+'''%s'''
+actual exception message:
+'''%s'''
+""" % (expected_message, actual_message))
+
+            return err
+        else:
+            self.fail("""expected exception %(expected_exception)s not raised
+called %(func)r
+with args %(args)r
+and kwargs %(kwargs)r
+""" % locals ())
+
+
+    # -- Assertions used in more than one class --------------------
+
+    def assertParseFail(self, cmdline_args, expected_output):
+        """
+        Assert the parser fails with the expected message.  Caller
+        must ensure that self.parser is an InterceptingOptionParser.
+        """
+        try:
+            self.parser.parse_args(cmdline_args)
+        except InterceptedError, err:
+            self.assertEqual(err.error_message, expected_output)
+        else:
+            self.assertFalse("expected parse failure")
+
+    def assertOutput(self,
+                     cmdline_args,
+                     expected_output,
+                     expected_status=0,
+                     expected_error=None):
+        """Assert the parser prints the expected output on stdout."""
+        save_stdout = sys.stdout
+        encoding = getattr(save_stdout, 'encoding', None)
+        try:
+            try:
+                sys.stdout = StringIO()
+                if encoding:
+                    sys.stdout.encoding = encoding
+                self.parser.parse_args(cmdline_args)
+            finally:
+                output = sys.stdout.getvalue()
+                sys.stdout = save_stdout
+
+        except InterceptedError, err:
+            self.assert_(
+                type(output) is types.StringType,
+                "expected output to be an ordinary string, not %r"
+                % type(output))
+
+            if output != expected_output:
+                self.fail("expected: \n'''\n" + expected_output +
+                          "'''\nbut got \n'''\n" + output + "'''")
+            self.assertEqual(err.exit_status, expected_status)
+            self.assertEqual(err.exit_message, expected_error)
+        else:
+            self.assertFalse("expected parser.exit()")
+
+    def assertTypeError(self, func, expected_message, *args):
+        """Assert that TypeError is raised when executing func."""
+        self.assertRaises(func, args, None, TypeError, expected_message)
+
+    def assertHelp(self, parser, expected_help):
+        actual_help = parser.format_help()
+        if actual_help != expected_help:
+            raise self.failureException(
+                'help text failure; expected:\n"' +
+                expected_help + '"; got:\n"' +
+                actual_help + '"\n')
+
+# -- Test make_option() aka Option -------------------------------------
+
+# It's not necessary to test correct options here.  All the tests in the
+# parser.parse_args() section deal with those, because they're needed
+# there.
+
+class TestOptionChecks(BaseTest):
+    def setUp(self):
+        self.parser = OptionParser(usage=SUPPRESS_USAGE)
+
+    def assertOptionError(self, expected_message, args=[], kwargs={}):
+        self.assertRaises(make_option, args, kwargs,
+                          OptionError, expected_message)
+
+    def test_opt_string_empty(self):
+        self.assertTypeError(make_option,
+                             "at least one option string must be supplied")
+
+    def test_opt_string_too_short(self):
+        self.assertOptionError(
+            "invalid option string 'b': must be at least two characters long",
+            ["b"])
+
+    def test_opt_string_short_invalid(self):
+        self.assertOptionError(
+            "invalid short option string '--': must be "
+            "of the form -x, (x any non-dash char)",
+            ["--"])
+
+    def test_opt_string_long_invalid(self):
+        self.assertOptionError(
+            "invalid long option string '---': "
+            "must start with --, followed by non-dash",
+            ["---"])
+
+    def test_attr_invalid(self):
+        self.assertOptionError(
+            "option -b: invalid keyword arguments: bar, foo",
+            ["-b"], {'foo': None, 'bar': None})
+
+    def test_action_invalid(self):
+        self.assertOptionError(
+            "option -b: invalid action: 'foo'",
+            ["-b"], {'action': 'foo'})
+
+    def test_type_invalid(self):
+        self.assertOptionError(
+            "option -b: invalid option type: 'foo'",
+            ["-b"], {'type': 'foo'})
+        self.assertOptionError(
+            "option -b: invalid option type: 'tuple'",
+            ["-b"], {'type': tuple})
+
+    def test_no_type_for_action(self):
+        self.assertOptionError(
+            "option -b: must not supply a type for action 'count'",
+            ["-b"], {'action': 'count', 'type': 'int'})
+
+    def test_no_choices_list(self):
+        self.assertOptionError(
+            "option -b/--bad: must supply a list of "
+            "choices for type 'choice'",
+            ["-b", "--bad"], {'type': "choice"})
+
+    def test_bad_choices_list(self):
+        typename = type('').__name__
+        self.assertOptionError(
+            "option -b/--bad: choices must be a list of "
+            "strings ('%s' supplied)" % typename,
+            ["-b", "--bad"],
+            {'type': "choice", 'choices':"bad choices"})
+
+    def test_no_choices_for_type(self):
+        self.assertOptionError(
+            "option -b: must not supply choices for type 'int'",
+            ["-b"], {'type': 'int', 'choices':"bad"})
+
+    def test_no_const_for_action(self):
+        self.assertOptionError(
+            "option -b: 'const' must not be supplied for action 'store'",
+            ["-b"], {'action': 'store', 'const': 1})
+
+    def test_no_nargs_for_action(self):
+        self.assertOptionError(
+            "option -b: 'nargs' must not be supplied for action 'count'",
+            ["-b"], {'action': 'count', 'nargs': 2})
+
+    def test_callback_not_callable(self):
+        self.assertOptionError(
+            "option -b: callback not callable: 'foo'",
+            ["-b"], {'action': 'callback',
+                     'callback': 'foo'})
+
+    def dummy(self):
+        pass
+
+    def test_callback_args_no_tuple(self):
+        self.assertOptionError(
+            "option -b: callback_args, if supplied, "
+            "must be a tuple: not 'foo'",
+            ["-b"], {'action': 'callback',
+                     'callback': self.dummy,
+                     'callback_args': 'foo'})
+
+    def test_callback_kwargs_no_dict(self):
+        self.assertOptionError(
+            "option -b: callback_kwargs, if supplied, "
+            "must be a dict: not 'foo'",
+            ["-b"], {'action': 'callback',
+                     'callback': self.dummy,
+                     'callback_kwargs': 'foo'})
+
+    def test_no_callback_for_action(self):
+        self.assertOptionError(
+            "option -b: callback supplied ('foo') for non-callback option",
+            ["-b"], {'action': 'store',
+                     'callback': 'foo'})
+
+    def test_no_callback_args_for_action(self):
+        self.assertOptionError(
+            "option -b: callback_args supplied for non-callback option",
+            ["-b"], {'action': 'store',
+                     'callback_args': 'foo'})
+
+    def test_no_callback_kwargs_for_action(self):
+        self.assertOptionError(
+            "option -b: callback_kwargs supplied for non-callback option",
+            ["-b"], {'action': 'store',
+                     'callback_kwargs': 'foo'})
+
+class TestOptionParser(BaseTest):
+    def setUp(self):
+        self.parser = OptionParser()
+        self.parser.add_option("-v", "--verbose", "-n", "--noisy",
+                          action="store_true", dest="verbose")
+        self.parser.add_option("-q", "--quiet", "--silent",
+                          action="store_false", dest="verbose")
+
+    def test_add_option_no_Option(self):
+        self.assertTypeError(self.parser.add_option,
+                             "not an Option instance: None", None)
+
+    def test_add_option_invalid_arguments(self):
+        self.assertTypeError(self.parser.add_option,
+                             "invalid arguments", None, None)
+
+    def test_get_option(self):
+        opt1 = self.parser.get_option("-v")
+        self.assert_(isinstance(opt1, Option))
+        self.assertEqual(opt1._short_opts, ["-v", "-n"])
+        self.assertEqual(opt1._long_opts, ["--verbose", "--noisy"])
+        self.assertEqual(opt1.action, "store_true")
+        self.assertEqual(opt1.dest, "verbose")
+
+    def test_get_option_equals(self):
+        opt1 = self.parser.get_option("-v")
+        opt2 = self.parser.get_option("--verbose")
+        opt3 = self.parser.get_option("-n")
+        opt4 = self.parser.get_option("--noisy")
+        self.assert_(opt1 is opt2 is opt3 is opt4)
+
+    def test_has_option(self):
+        self.assert_(self.parser.has_option("-v"))
+        self.assert_(self.parser.has_option("--verbose"))
+
+    def assert_removed(self):
+        self.assert_(self.parser.get_option("-v") is None)
+        self.assert_(self.parser.get_option("--verbose") is None)
+        self.assert_(self.parser.get_option("-n") is None)
+        self.assert_(self.parser.get_option("--noisy") is None)
+
+        self.failIf(self.parser.has_option("-v"))
+        self.failIf(self.parser.has_option("--verbose"))
+        self.failIf(self.parser.has_option("-n"))
+        self.failIf(self.parser.has_option("--noisy"))
+
+        self.assert_(self.parser.has_option("-q"))
+        self.assert_(self.parser.has_option("--silent"))
+
+    def test_remove_short_opt(self):
+        self.parser.remove_option("-n")
+        self.assert_removed()
+
+    def test_remove_long_opt(self):
+        self.parser.remove_option("--verbose")
+        self.assert_removed()
+
+    def test_remove_nonexistent(self):
+        self.assertRaises(self.parser.remove_option, ('foo',), None,
+                          ValueError, "no such option 'foo'")
+
+    def test_refleak(self):
+        # If an OptionParser is carrying around a reference to a large
+        # object, various cycles can prevent it from being GC'd in
+        # a timely fashion.  destroy() breaks the cycles to ensure stuff
+        # can be cleaned up.
+        big_thing = [42]
+        refcount = sys.getrefcount(big_thing)
+        parser = OptionParser()
+        parser.add_option("-a", "--aaarggh")
+        parser.big_thing = big_thing
+
+        parser.destroy()
+        #self.assertEqual(refcount, sys.getrefcount(big_thing))
+        del parser
+        self.assertEqual(refcount, sys.getrefcount(big_thing))
+
+
+class TestOptionValues(BaseTest):
+    def setUp(self):
+        pass
+
+    def test_basics(self):
+        values = Values()
+        self.assertEqual(vars(values), {})
+        self.assertEqual(values, {})
+        self.assertNotEqual(values, {"foo": "bar"})
+        self.assertNotEqual(values, "")
+
+        dict = {"foo": "bar", "baz": 42}
+        values = Values(defaults=dict)
+        self.assertEqual(vars(values), dict)
+        self.assertEqual(values, dict)
+        self.assertNotEqual(values, {"foo": "bar"})
+        self.assertNotEqual(values, {})
+        self.assertNotEqual(values, "")
+        self.assertNotEqual(values, [])
+
+
+class TestTypeAliases(BaseTest):
+    def setUp(self):
+        self.parser = OptionParser()
+
+    def test_str_aliases_string(self):
+        self.parser.add_option("-s", type="str")
+        self.assertEquals(self.parser.get_option("-s").type, "string")
+
+    def test_new_type_object(self):
+        self.parser.add_option("-s", type=str)
+        self.assertEquals(self.parser.get_option("-s").type, "string")
+        self.parser.add_option("-x", type=int)
+        self.assertEquals(self.parser.get_option("-x").type, "int")
+
+    def test_old_type_object(self):
+        self.parser.add_option("-s", type=types.StringType)
+        self.assertEquals(self.parser.get_option("-s").type, "string")
+        self.parser.add_option("-x", type=types.IntType)
+        self.assertEquals(self.parser.get_option("-x").type, "int")
+
+
+# Custom type for testing processing of default values.
+_time_units = { 's' : 1, 'm' : 60, 'h' : 60*60, 'd' : 60*60*24 }
+
+def _check_duration(option, opt, value):
+    try:
+        if value[-1].isdigit():
+            return int(value)
+        else:
+            return int(value[:-1]) * _time_units[value[-1]]
+    except ValueError, IndexError:
+        raise OptionValueError(
+            'option %s: invalid duration: %r' % (opt, value))
+
+class DurationOption(Option):
+    TYPES = Option.TYPES + ('duration',)
+    TYPE_CHECKER = copy.copy(Option.TYPE_CHECKER)
+    TYPE_CHECKER['duration'] = _check_duration
+
+class TestDefaultValues(BaseTest):
+    def setUp(self):
+        self.parser = OptionParser()
+        self.parser.add_option("-v", "--verbose", default=True)
+        self.parser.add_option("-q", "--quiet", dest='verbose')
+        self.parser.add_option("-n", type="int", default=37)
+        self.parser.add_option("-m", type="int")
+        self.parser.add_option("-s", default="foo")
+        self.parser.add_option("-t")
+        self.parser.add_option("-u", default=None)
+        self.expected = { 'verbose': True,
+                          'n': 37,
+                          'm': None,
+                          's': "foo",
+                          't': None,
+                          'u': None }
+
+    def test_basic_defaults(self):
+        self.assertEqual(self.parser.get_default_values(), self.expected)
+
+    def test_mixed_defaults_post(self):
+        self.parser.set_defaults(n=42, m=-100)
+        self.expected.update({'n': 42, 'm': -100})
+        self.assertEqual(self.parser.get_default_values(), self.expected)
+
+    def test_mixed_defaults_pre(self):
+        self.parser.set_defaults(x="barf", y="blah")
+        self.parser.add_option("-x", default="frob")
+        self.parser.add_option("-y")
+
+        self.expected.update({'x': "frob", 'y': "blah"})
+        self.assertEqual(self.parser.get_default_values(), self.expected)
+
+        self.parser.remove_option("-y")
+        self.parser.add_option("-y", default=None)
+        self.expected.update({'y': None})
+        self.assertEqual(self.parser.get_default_values(), self.expected)
+
+    def test_process_default(self):
+        self.parser.option_class = DurationOption
+        self.parser.add_option("-d", type="duration", default=300)
+        self.parser.add_option("-e", type="duration", default="6m")
+        self.parser.set_defaults(n="42")
+        self.expected.update({'d': 300, 'e': 360, 'n': 42})
+        self.assertEqual(self.parser.get_default_values(), self.expected)
+
+        self.parser.set_process_default_values(False)
+        self.expected.update({'d': 300, 'e': "6m", 'n': "42"})
+        self.assertEqual(self.parser.get_default_values(), self.expected)
+
+
+class TestProgName(BaseTest):
+    """
+    Test that %prog expands to the right thing in usage, version,
+    and help strings.
+    """
+
+    def assertUsage(self, parser, expected_usage):
+        self.assertEqual(parser.get_usage(), expected_usage)
+
+    def assertVersion(self, parser, expected_version):
+        self.assertEqual(parser.get_version(), expected_version)
+
+
+    def test_default_progname(self):
+        # Make sure that program name taken from sys.argv[0] by default.
+        save_argv = sys.argv[:]
+        try:
+            sys.argv[0] = os.path.join("foo", "bar", "baz.py")
+            parser = OptionParser("%prog ...", version="%prog 1.2")
+            expected_usage = "Usage: baz.py ...\n"
+            self.assertUsage(parser, expected_usage)
+            self.assertVersion(parser, "baz.py 1.2")
+            self.assertHelp(parser,
+                            expected_usage + "\n" +
+                            "Options:\n"
+                            "  --version   show program's version number and exit\n"
+                            "  -h, --help  show this help message and exit\n")
+        finally:
+            sys.argv[:] = save_argv
+
+    def test_custom_progname(self):
+        parser = OptionParser(prog="thingy",
+                              version="%prog 0.1",
+                              usage="%prog arg arg")
+        parser.remove_option("-h")
+        parser.remove_option("--version")
+        expected_usage = "Usage: thingy arg arg\n"
+        self.assertUsage(parser, expected_usage)
+        self.assertVersion(parser, "thingy 0.1")
+        self.assertHelp(parser, expected_usage + "\n")
+
+
+class TestExpandDefaults(BaseTest):
+    def setUp(self):
+        self.parser = OptionParser(prog="test")
+        self.help_prefix = """\
+Usage: test [options]
+
+Options:
+  -h, --help            show this help message and exit
+"""
+        self.file_help = "read from FILE [default: %default]"
+        self.expected_help_file = self.help_prefix + \
+            "  -f FILE, --file=FILE  read from FILE [default: foo.txt]\n"
+        self.expected_help_none = self.help_prefix + \
+            "  -f FILE, --file=FILE  read from FILE [default: none]\n"
+
+    def test_option_default(self):
+        self.parser.add_option("-f", "--file",
+                               default="foo.txt",
+                               help=self.file_help)
+        self.assertHelp(self.parser, self.expected_help_file)
+
+    def test_parser_default_1(self):
+        self.parser.add_option("-f", "--file",
+                               help=self.file_help)
+        self.parser.set_default('file', "foo.txt")
+        self.assertHelp(self.parser, self.expected_help_file)
+
+    def test_parser_default_2(self):
+        self.parser.add_option("-f", "--file",
+                               help=self.file_help)
+        self.parser.set_defaults(file="foo.txt")
+        self.assertHelp(self.parser, self.expected_help_file)
+
+    def test_no_default(self):
+        self.parser.add_option("-f", "--file",
+                               help=self.file_help)
+        self.assertHelp(self.parser, self.expected_help_none)
+
+    def test_default_none_1(self):
+        self.parser.add_option("-f", "--file",
+                               default=None,
+                               help=self.file_help)
+        self.assertHelp(self.parser, self.expected_help_none)
+
+    def test_default_none_2(self):
+        self.parser.add_option("-f", "--file",
+                               help=self.file_help)
+        self.parser.set_defaults(file=None)
+        self.assertHelp(self.parser, self.expected_help_none)
+
+    def test_float_default(self):
+        self.parser.add_option(
+            "-p", "--prob",
+            help="blow up with probability PROB [default: %default]")
+        self.parser.set_defaults(prob=0.43)
+        expected_help = self.help_prefix + \
+            "  -p PROB, --prob=PROB  blow up with probability PROB [default: 0.43]\n"
+        self.assertHelp(self.parser, expected_help)
+
+    def test_alt_expand(self):
+        self.parser.add_option("-f", "--file",
+                               default="foo.txt",
+                               help="read from FILE [default: *DEFAULT*]")
+        self.parser.formatter.default_tag = "*DEFAULT*"
+        self.assertHelp(self.parser, self.expected_help_file)
+
+    def test_no_expand(self):
+        self.parser.add_option("-f", "--file",
+                               default="foo.txt",
+                               help="read from %default file")
+        self.parser.formatter.default_tag = None
+        expected_help = self.help_prefix + \
+            "  -f FILE, --file=FILE  read from %default file\n"
+        self.assertHelp(self.parser, expected_help)
+
+
+# -- Test parser.parse_args() ------------------------------------------
+
+class TestStandard(BaseTest):
+    def setUp(self):
+        options = [make_option("-a", type="string"),
+                   make_option("-b", "--boo", type="int", dest='boo'),
+                   make_option("--foo", action="append")]
+
+        self.parser = InterceptingOptionParser(usage=SUPPRESS_USAGE,
+                                               option_list=options)
+
+    def test_required_value(self):
+        self.assertParseFail(["-a"], "-a option requires an argument")
+
+    def test_invalid_integer(self):
+        self.assertParseFail(["-b", "5x"],
+                             "option -b: invalid integer value: '5x'")
+
+    def test_no_such_option(self):
+        self.assertParseFail(["--boo13"], "no such option: --boo13")
+
+    def test_long_invalid_integer(self):
+        self.assertParseFail(["--boo=x5"],
+                             "option --boo: invalid integer value: 'x5'")
+
+    def test_empty(self):
+        self.assertParseOK([], {'a': None, 'boo': None, 'foo': None}, [])
+
+    def test_shortopt_empty_longopt_append(self):
+        self.assertParseOK(["-a", "", "--foo=blah", "--foo="],
+                           {'a': "", 'boo': None, 'foo': ["blah", ""]},
+                           [])
+
+    def test_long_option_append(self):
+        self.assertParseOK(["--foo", "bar", "--foo", "", "--foo=x"],
+                           {'a': None,
+                            'boo': None,
+                            'foo': ["bar", "", "x"]},
+                           [])
+
+    def test_option_argument_joined(self):
+        self.assertParseOK(["-abc"],
+                           {'a': "bc", 'boo': None, 'foo': None},
+                           [])
+
+    def test_option_argument_split(self):
+        self.assertParseOK(["-a", "34"],
+                           {'a': "34", 'boo': None, 'foo': None},
+                           [])
+
+    def test_option_argument_joined_integer(self):
+        self.assertParseOK(["-b34"],
+                           {'a': None, 'boo': 34, 'foo': None},
+                           [])
+
+    def test_option_argument_split_negative_integer(self):
+        self.assertParseOK(["-b", "-5"],
+                           {'a': None, 'boo': -5, 'foo': None},
+                           [])
+
+    def test_long_option_argument_joined(self):
+        self.assertParseOK(["--boo=13"],
+                           {'a': None, 'boo': 13, 'foo': None},
+                           [])
+
+    def test_long_option_argument_split(self):
+        self.assertParseOK(["--boo", "111"],
+                           {'a': None, 'boo': 111, 'foo': None},
+                           [])
+
+    def test_long_option_short_option(self):
+        self.assertParseOK(["--foo=bar", "-axyz"],
+                           {'a': 'xyz', 'boo': None, 'foo': ["bar"]},
+                           [])
+
+    def test_abbrev_long_option(self):
+        self.assertParseOK(["--f=bar", "-axyz"],
+                           {'a': 'xyz', 'boo': None, 'foo': ["bar"]},
+                           [])
+
+    def test_defaults(self):
+        (options, args) = self.parser.parse_args([])
+        defaults = self.parser.get_default_values()
+        self.assertEqual(vars(defaults), vars(options))
+
+    def test_ambiguous_option(self):
+        self.parser.add_option("--foz", action="store",
+                               type="string", dest="foo")
+        self.assertParseFail(["--f=bar"],
+                             "ambiguous option: --f (--foo, --foz?)")
+
+
+    def test_short_and_long_option_split(self):
+        self.assertParseOK(["-a", "xyz", "--foo", "bar"],
+                           {'a': 'xyz', 'boo': None, 'foo': ["bar"]},
+                           []),
+
+    def test_short_option_split_long_option_append(self):
+        self.assertParseOK(["--foo=bar", "-b", "123", "--foo", "baz"],
+                           {'a': None, 'boo': 123, 'foo': ["bar", "baz"]},
+                           [])
+
+    def test_short_option_split_one_positional_arg(self):
+        self.assertParseOK(["-a", "foo", "bar"],
+                           {'a': "foo", 'boo': None, 'foo': None},
+                           ["bar"]),
+
+    def test_short_option_consumes_separator(self):
+        self.assertParseOK(["-a", "--", "foo", "bar"],
+                           {'a': "--", 'boo': None, 'foo': None},
+                           ["foo", "bar"]),
+        self.assertParseOK(["-a", "--", "--foo", "bar"],
+                           {'a': "--", 'boo': None, 'foo': ["bar"]},
+                           []),
+
+    def test_short_option_joined_and_separator(self):
+        self.assertParseOK(["-ab", "--", "--foo", "bar"],
+                           {'a': "b", 'boo': None, 'foo': None},
+                           ["--foo", "bar"]),
+
+    def test_hyphen_becomes_positional_arg(self):
+        self.assertParseOK(["-ab", "-", "--foo", "bar"],
+                           {'a': "b", 'boo': None, 'foo': ["bar"]},
+                           ["-"])
+
+    def test_no_append_versus_append(self):
+        self.assertParseOK(["-b3", "-b", "5", "--foo=bar", "--foo", "baz"],
+                           {'a': None, 'boo': 5, 'foo': ["bar", "baz"]},
+                           [])
+
+    def test_option_consumes_optionlike_string(self):
+        self.assertParseOK(["-a", "-b3"],
+                           {'a': "-b3", 'boo': None, 'foo': None},
+                           [])
+
+class TestBool(BaseTest):
+    def setUp(self):
+        options = [make_option("-v",
+                               "--verbose",
+                               action="store_true",
+                               dest="verbose",
+                               default=''),
+                   make_option("-q",
+                               "--quiet",
+                               action="store_false",
+                               dest="verbose")]
+        self.parser = OptionParser(option_list = options)
+
+    def test_bool_default(self):
+        self.assertParseOK([],
+                           {'verbose': ''},
+                           [])
+
+    def test_bool_false(self):
+        (options, args) = self.assertParseOK(["-q"],
+                                             {'verbose': 0},
+                                             [])
+        if hasattr(__builtins__, 'False'):
+            self.failUnless(options.verbose is False)
+
+    def test_bool_true(self):
+        (options, args) = self.assertParseOK(["-v"],
+                                             {'verbose': 1},
+                                             [])
+        if hasattr(__builtins__, 'True'):
+            self.failUnless(options.verbose is True)
+
+    def test_bool_flicker_on_and_off(self):
+        self.assertParseOK(["-qvq", "-q", "-v"],
+                           {'verbose': 1},
+                           [])
+
+class TestChoice(BaseTest):
+    def setUp(self):
+        self.parser = InterceptingOptionParser(usage=SUPPRESS_USAGE)
+        self.parser.add_option("-c", action="store", type="choice",
+                               dest="choice", choices=["one", "two", "three"])
+
+    def test_valid_choice(self):
+        self.assertParseOK(["-c", "one", "xyz"],
+                           {'choice': 'one'},
+                           ["xyz"])
+
+    def test_invalid_choice(self):
+        self.assertParseFail(["-c", "four", "abc"],
+                             "option -c: invalid choice: 'four' "
+                             "(choose from 'one', 'two', 'three')")
+
+    def test_add_choice_option(self):
+        self.parser.add_option("-d", "--default",
+                               choices=["four", "five", "six"])
+        opt = self.parser.get_option("-d")
+        self.assertEqual(opt.type, "choice")
+        self.assertEqual(opt.action, "store")
+
+class TestCount(BaseTest):
+    def setUp(self):
+        self.parser = InterceptingOptionParser(usage=SUPPRESS_USAGE)
+        self.v_opt = make_option("-v", action="count", dest="verbose")
+        self.parser.add_option(self.v_opt)
+        self.parser.add_option("--verbose", type="int", dest="verbose")
+        self.parser.add_option("-q", "--quiet",
+                               action="store_const", dest="verbose", const=0)
+
+    def test_empty(self):
+        self.assertParseOK([], {'verbose': None}, [])
+
+    def test_count_one(self):
+        self.assertParseOK(["-v"], {'verbose': 1}, [])
+
+    def test_count_three(self):
+        self.assertParseOK(["-vvv"], {'verbose': 3}, [])
+
+    def test_count_three_apart(self):
+        self.assertParseOK(["-v", "-v", "-v"], {'verbose': 3}, [])
+
+    def test_count_override_amount(self):
+        self.assertParseOK(["-vvv", "--verbose=2"], {'verbose': 2}, [])
+
+    def test_count_override_quiet(self):
+        self.assertParseOK(["-vvv", "--verbose=2", "-q"], {'verbose': 0}, [])
+
+    def test_count_overriding(self):
+        self.assertParseOK(["-vvv", "--verbose=2", "-q", "-v"],
+                           {'verbose': 1}, [])
+
+    def test_count_interspersed_args(self):
+        self.assertParseOK(["--quiet", "3", "-v"],
+                           {'verbose': 1},
+                           ["3"])
+
+    def test_count_no_interspersed_args(self):
+        self.parser.disable_interspersed_args()
+        self.assertParseOK(["--quiet", "3", "-v"],
+                           {'verbose': 0},
+                           ["3", "-v"])
+
+    def test_count_no_such_option(self):
+        self.assertParseFail(["-q3", "-v"], "no such option: -3")
+
+    def test_count_option_no_value(self):
+        self.assertParseFail(["--quiet=3", "-v"],
+                             "--quiet option does not take a value")
+
+    def test_count_with_default(self):
+        self.parser.set_default('verbose', 0)
+        self.assertParseOK([], {'verbose':0}, [])
+
+    def test_count_overriding_default(self):
+        self.parser.set_default('verbose', 0)
+        self.assertParseOK(["-vvv", "--verbose=2", "-q", "-v"],
+                           {'verbose': 1}, [])
+
+class TestMultipleArgs(BaseTest):
+    def setUp(self):
+        self.parser = InterceptingOptionParser(usage=SUPPRESS_USAGE)
+        self.parser.add_option("-p", "--point",
+                               action="store", nargs=3, type="float", dest="point")
+
+    def test_nargs_with_positional_args(self):
+        self.assertParseOK(["foo", "-p", "1", "2.5", "-4.3", "xyz"],
+                           {'point': (1.0, 2.5, -4.3)},
+                           ["foo", "xyz"])
+
+    def test_nargs_long_opt(self):
+        self.assertParseOK(["--point", "-1", "2.5", "-0", "xyz"],
+                           {'point': (-1.0, 2.5, -0.0)},
+                           ["xyz"])
+
+    def test_nargs_invalid_float_value(self):
+        self.assertParseFail(["-p", "1.0", "2x", "3.5"],
+                             "option -p: "
+                             "invalid floating-point value: '2x'")
+
+    def test_nargs_required_values(self):
+        self.assertParseFail(["--point", "1.0", "3.5"],
+                             "--point option requires 3 arguments")
+
+class TestMultipleArgsAppend(BaseTest):
+    def setUp(self):
+        self.parser = InterceptingOptionParser(usage=SUPPRESS_USAGE)
+        self.parser.add_option("-p", "--point", action="store", nargs=3,
+                               type="float", dest="point")
+        self.parser.add_option("-f", "--foo", action="append", nargs=2,
+                               type="int", dest="foo")
+        self.parser.add_option("-z", "--zero", action="append_const",
+                               dest="foo", const=(0, 0))
+
+    def test_nargs_append(self):
+        self.assertParseOK(["-f", "4", "-3", "blah", "--foo", "1", "666"],
+                           {'point': None, 'foo': [(4, -3), (1, 666)]},
+                           ["blah"])
+
+    def test_nargs_append_required_values(self):
+        self.assertParseFail(["-f4,3"],
+                             "-f option requires 2 arguments")
+
+    def test_nargs_append_simple(self):
+        self.assertParseOK(["--foo=3", "4"],
+                           {'point': None, 'foo':[(3, 4)]},
+                           [])
+
+    def test_nargs_append_const(self):
+        self.assertParseOK(["--zero", "--foo", "3", "4", "-z"],
+                           {'point': None, 'foo':[(0, 0), (3, 4), (0, 0)]},
+                           [])
+
+class TestVersion(BaseTest):
+    def test_version(self):
+        self.parser = InterceptingOptionParser(usage=SUPPRESS_USAGE,
+                                               version="%prog 0.1")
+        save_argv = sys.argv[:]
+        try:
+            sys.argv[0] = os.path.join(os.curdir, "foo", "bar")
+            self.assertOutput(["--version"], "bar 0.1\n")
+        finally:
+            sys.argv[:] = save_argv
+
+    def test_no_version(self):
+        self.parser = InterceptingOptionParser(usage=SUPPRESS_USAGE)
+        self.assertParseFail(["--version"],
+                             "no such option: --version")
+
+# -- Test conflicting default values and parser.parse_args() -----------
+
+class TestConflictingDefaults(BaseTest):
+    """Conflicting default values: the last one should win."""
+    def setUp(self):
+        self.parser = OptionParser(option_list=[
+            make_option("-v", action="store_true", dest="verbose", default=1)])
+
+    def test_conflict_default(self):
+        self.parser.add_option("-q", action="store_false", dest="verbose",
+                               default=0)
+        self.assertParseOK([], {'verbose': 0}, [])
+
+    def test_conflict_default_none(self):
+        self.parser.add_option("-q", action="store_false", dest="verbose",
+                               default=None)
+        self.assertParseOK([], {'verbose': None}, [])
+
+class TestOptionGroup(BaseTest):
+    def setUp(self):
+        self.parser = OptionParser(usage=SUPPRESS_USAGE)
+
+    def test_option_group_create_instance(self):
+        group = OptionGroup(self.parser, "Spam")
+        self.parser.add_option_group(group)
+        group.add_option("--spam", action="store_true",
+                         help="spam spam spam spam")
+        self.assertParseOK(["--spam"], {'spam': 1}, [])
+
+    def test_add_group_no_group(self):
+        self.assertTypeError(self.parser.add_option_group,
+                             "not an OptionGroup instance: None", None)
+
+    def test_add_group_invalid_arguments(self):
+        self.assertTypeError(self.parser.add_option_group,
+                             "invalid arguments", None, None)
+
+    def test_add_group_wrong_parser(self):
+        group = OptionGroup(self.parser, "Spam")
+        group.parser = OptionParser()
+        self.assertRaises(self.parser.add_option_group, (group,), None,
+                          ValueError, "invalid OptionGroup (wrong parser)")
+
+    def test_group_manipulate(self):
+        group = self.parser.add_option_group("Group 2",
+                                             description="Some more options")
+        group.set_title("Bacon")
+        group.add_option("--bacon", type="int")
+        self.assert_(self.parser.get_option_group("--bacon"), group)
+
+# -- Test extending and parser.parse_args() ----------------------------
+
+class TestExtendAddTypes(BaseTest):
+    def setUp(self):
+        self.parser = InterceptingOptionParser(usage=SUPPRESS_USAGE,
+                                               option_class=self.MyOption)
+        self.parser.add_option("-a", None, type="string", dest="a")
+        self.parser.add_option("-f", "--file", type="file", dest="file")
+
+    def tearDown(self):
+        if os.path.isdir(test_support.TESTFN):
+            os.rmdir(test_support.TESTFN)
+        elif os.path.isfile(test_support.TESTFN):
+            os.unlink(test_support.TESTFN)
+
+    class MyOption (Option):
+        def check_file(option, opt, value):
+            if not os.path.exists(value):
+                raise OptionValueError("%s: file does not exist" % value)
+            elif not os.path.isfile(value):
+                raise OptionValueError("%s: not a regular file" % value)
+            return value
+
+        TYPES = Option.TYPES + ("file",)
+        TYPE_CHECKER = copy.copy(Option.TYPE_CHECKER)
+        TYPE_CHECKER["file"] = check_file
+
+    def test_filetype_ok(self):
+        open(test_support.TESTFN, "w").close()
+        self.assertParseOK(["--file", test_support.TESTFN, "-afoo"],
+                           {'file': test_support.TESTFN, 'a': 'foo'},
+                           [])
+
+    def test_filetype_noexist(self):
+        self.assertParseFail(["--file", test_support.TESTFN, "-afoo"],
+                             "%s: file does not exist" %
+                             test_support.TESTFN)
+
+    def test_filetype_notfile(self):
+        os.mkdir(test_support.TESTFN)
+        self.assertParseFail(["--file", test_support.TESTFN, "-afoo"],
+                             "%s: not a regular file" %
+                             test_support.TESTFN)
+
+
+class TestExtendAddActions(BaseTest):
+    def setUp(self):
+        options = [self.MyOption("-a", "--apple", action="extend",
+                                 type="string", dest="apple")]
+        self.parser = OptionParser(option_list=options)
+
+    class MyOption (Option):
+        ACTIONS = Option.ACTIONS + ("extend",)
+        STORE_ACTIONS = Option.STORE_ACTIONS + ("extend",)
+        TYPED_ACTIONS = Option.TYPED_ACTIONS + ("extend",)
+
+        def take_action(self, action, dest, opt, value, values, parser):
+            if action == "extend":
+                lvalue = value.split(",")
+                values.ensure_value(dest, []).extend(lvalue)
+            else:
+                Option.take_action(self, action, dest, opt, parser, value,
+                                   values)
+
+    def test_extend_add_action(self):
+        self.assertParseOK(["-afoo,bar", "--apple=blah"],
+                           {'apple': ["foo", "bar", "blah"]},
+                           [])
+
+    def test_extend_add_action_normal(self):
+        self.assertParseOK(["-a", "foo", "-abar", "--apple=x,y"],
+                           {'apple': ["foo", "bar", "x", "y"]},
+                           [])
+
+# -- Test callbacks and parser.parse_args() ----------------------------
+
+class TestCallback(BaseTest):
+    def setUp(self):
+        options = [make_option("-x",
+                               None,
+                               action="callback",
+                               callback=self.process_opt),
+                   make_option("-f",
+                               "--file",
+                               action="callback",
+                               callback=self.process_opt,
+                               type="string",
+                               dest="filename")]
+        self.parser = OptionParser(option_list=options)
+
+    def process_opt(self, option, opt, value, parser_):
+        if opt == "-x":
+            self.assertEqual(option._short_opts, ["-x"])
+            self.assertEqual(option._long_opts, [])
+            self.assert_(parser_ is self.parser)
+            self.assert_(value is None)
+            self.assertEqual(vars(parser_.values), {'filename': None})
+
+            parser_.values.x = 42
+        elif opt == "--file":
+            self.assertEqual(option._short_opts, ["-f"])
+            self.assertEqual(option._long_opts, ["--file"])
+            self.assert_(parser_ is self.parser)
+            self.assertEqual(value, "foo")
+            self.assertEqual(vars(parser_.values), {'filename': None, 'x': 42})
+
+            setattr(parser_.values, option.dest, value)
+        else:
+            self.fail("Unknown option %r in process_opt." % opt)
+
+    def test_callback(self):
+        self.assertParseOK(["-x", "--file=foo"],
+                           {'filename': "foo", 'x': 42},
+                           [])
+
+    def test_callback_help(self):
+        # This test was prompted by SF bug #960515 -- the point is
+        # not to inspect the help text, just to make sure that
+        # format_help() doesn't crash.
+        parser = OptionParser(usage=SUPPRESS_USAGE)
+        parser.remove_option("-h")
+        parser.add_option("-t", "--test", action="callback",
+                          callback=lambda: None, type="string",
+                          help="foo")
+
+        expected_help = ("Options:\n"
+                         "  -t TEST, --test=TEST  foo\n")
+        self.assertHelp(parser, expected_help)
+
+
+class TestCallbackExtraArgs(BaseTest):
+    def setUp(self):
+        options = [make_option("-p", "--point", action="callback",
+                               callback=self.process_tuple,
+                               callback_args=(3, int), type="string",
+                               dest="points", default=[])]
+        self.parser = OptionParser(option_list=options)
+
+    def process_tuple(self, option, opt, value, parser_, len, type):
+        self.assertEqual(len, 3)
+        self.assert_(type is int)
+
+        if opt == "-p":
+            self.assertEqual(value, "1,2,3")
+        elif opt == "--point":
+            self.assertEqual(value, "4,5,6")
+
+        value = tuple(map(type, value.split(",")))
+        getattr(parser_.values, option.dest).append(value)
+
+    def test_callback_extra_args(self):
+        self.assertParseOK(["-p1,2,3", "--point", "4,5,6"],
+                           {'points': [(1,2,3), (4,5,6)]},
+                           [])
+
+class TestCallbackMeddleArgs(BaseTest):
+    def setUp(self):
+        options = [make_option(str(x), action="callback",
+                               callback=self.process_n, dest='things')
+                   for x in range(-1, -6, -1)]
+        self.parser = OptionParser(option_list=options)
+
+    # Callback that meddles in rargs, largs
+    def process_n(self, option, opt, value, parser_):
+        # option is -3, -5, etc.
+        nargs = int(opt[1:])
+        rargs = parser_.rargs
+        if len(rargs) < nargs:
+            self.fail("Expected %d arguments for %s option." % (nargs, opt))
+        dest = parser_.values.ensure_value(option.dest, [])
+        dest.append(tuple(rargs[0:nargs]))
+        parser_.largs.append(nargs)
+        del rargs[0:nargs]
+
+    def test_callback_meddle_args(self):
+        self.assertParseOK(["-1", "foo", "-3", "bar", "baz", "qux"],
+                           {'things': [("foo",), ("bar", "baz", "qux")]},
+                           [1, 3])
+
+    def test_callback_meddle_args_separator(self):
+        self.assertParseOK(["-2", "foo", "--"],
+                           {'things': [('foo', '--')]},
+                           [2])
+
+class TestCallbackManyArgs(BaseTest):
+    def setUp(self):
+        options = [make_option("-a", "--apple", action="callback", nargs=2,
+                               callback=self.process_many, type="string"),
+                   make_option("-b", "--bob", action="callback", nargs=3,
+                               callback=self.process_many, type="int")]
+        self.parser = OptionParser(option_list=options)
+
+    def process_many(self, option, opt, value, parser_):
+        if opt == "-a":
+            self.assertEqual(value, ("foo", "bar"))
+        elif opt == "--apple":
+            self.assertEqual(value, ("ding", "dong"))
+        elif opt == "-b":
+            self.assertEqual(value, (1, 2, 3))
+        elif opt == "--bob":
+            self.assertEqual(value, (-666, 42, 0))
+
+    def test_many_args(self):
+        self.assertParseOK(["-a", "foo", "bar", "--apple", "ding", "dong",
+                            "-b", "1", "2", "3", "--bob", "-666", "42",
+                            "0"],
+                           {"apple": None, "bob": None},
+                           [])
+
+class TestCallbackCheckAbbrev(BaseTest):
+    def setUp(self):
+        self.parser = OptionParser()
+        self.parser.add_option("--foo-bar", action="callback",
+                               callback=self.check_abbrev)
+
+    def check_abbrev(self, option, opt, value, parser):
+        self.assertEqual(opt, "--foo-bar")
+
+    def test_abbrev_callback_expansion(self):
+        self.assertParseOK(["--foo"], {}, [])
+
+class TestCallbackVarArgs(BaseTest):
+    def setUp(self):
+        options = [make_option("-a", type="int", nargs=2, dest="a"),
+                   make_option("-b", action="store_true", dest="b"),
+                   make_option("-c", "--callback", action="callback",
+                               callback=self.variable_args, dest="c")]
+        self.parser = InterceptingOptionParser(usage=SUPPRESS_USAGE,
+                                               option_list=options)
+
+    def variable_args(self, option, opt, value, parser):
+        self.assert_(value is None)
+        done = 0
+        value = []
+        rargs = parser.rargs
+        while rargs:
+            arg = rargs[0]
+            if ((arg[:2] == "--" and len(arg) > 2) or
+                (arg[:1] == "-" and len(arg) > 1 and arg[1] != "-")):
+                break
+            else:
+                value.append(arg)
+                del rargs[0]
+        setattr(parser.values, option.dest, value)
+
+    def test_variable_args(self):
+        self.assertParseOK(["-a3", "-5", "--callback", "foo", "bar"],
+                           {'a': (3, -5), 'b': None, 'c': ["foo", "bar"]},
+                           [])
+
+    def test_consume_separator_stop_at_option(self):
+        self.assertParseOK(["-c", "37", "--", "xxx", "-b", "hello"],
+                           {'a': None,
+                            'b': True,
+                            'c': ["37", "--", "xxx"]},
+                           ["hello"])
+
+    def test_positional_arg_and_variable_args(self):
+        self.assertParseOK(["hello", "-c", "foo", "-", "bar"],
+                           {'a': None,
+                            'b': None,
+                            'c':["foo", "-", "bar"]},
+                           ["hello"])
+
+    def test_stop_at_option(self):
+        self.assertParseOK(["-c", "foo", "-b"],
+                           {'a': None, 'b': True, 'c': ["foo"]},
+                           [])
+
+    def test_stop_at_invalid_option(self):
+        self.assertParseFail(["-c", "3", "-5", "-a"], "no such option: -5")
+
+
+# -- Test conflict handling and parser.parse_args() --------------------
+
+class ConflictBase(BaseTest):
+    def setUp(self):
+        options = [make_option("-v", "--verbose", action="count",
+                               dest="verbose", help="increment verbosity")]
+        self.parser = InterceptingOptionParser(usage=SUPPRESS_USAGE,
+                                               option_list=options)
+
+    def show_version(self, option, opt, value, parser):
+        parser.values.show_version = 1
+
+class TestConflict(ConflictBase):
+    """Use the default conflict resolution for Optik 1.2: error."""
+    def assert_conflict_error(self, func):
+        err = self.assertRaises(
+            func, ("-v", "--version"), {'action' : "callback",
+                                        'callback' : self.show_version,
+                                        'help' : "show version"},
+            OptionConflictError,
+            "option -v/--version: conflicting option string(s): -v")
+
+        self.assertEqual(err.msg, "conflicting option string(s): -v")
+        self.assertEqual(err.option_id, "-v/--version")
+
+    def test_conflict_error(self):
+        self.assert_conflict_error(self.parser.add_option)
+
+    def test_conflict_error_group(self):
+        group = OptionGroup(self.parser, "Group 1")
+        self.assert_conflict_error(group.add_option)
+
+    def test_no_such_conflict_handler(self):
+        self.assertRaises(
+            self.parser.set_conflict_handler, ('foo',), None,
+            ValueError, "invalid conflict_resolution value 'foo'")
+
+
+class TestConflictResolve(ConflictBase):
+    def setUp(self):
+        ConflictBase.setUp(self)
+        self.parser.set_conflict_handler("resolve")
+        self.parser.add_option("-v", "--version", action="callback",
+                               callback=self.show_version, help="show version")
+
+    def test_conflict_resolve(self):
+        v_opt = self.parser.get_option("-v")
+        verbose_opt = self.parser.get_option("--verbose")
+        version_opt = self.parser.get_option("--version")
+
+        self.assert_(v_opt is version_opt)
+        self.assert_(v_opt is not verbose_opt)
+        self.assertEqual(v_opt._long_opts, ["--version"])
+        self.assertEqual(version_opt._short_opts, ["-v"])
+        self.assertEqual(version_opt._long_opts, ["--version"])
+        self.assertEqual(verbose_opt._short_opts, [])
+        self.assertEqual(verbose_opt._long_opts, ["--verbose"])
+
+    def test_conflict_resolve_help(self):
+        self.assertOutput(["-h"], """\
+Options:
+  --verbose      increment verbosity
+  -h, --help     show this help message and exit
+  -v, --version  show version
+""")
+
+    def test_conflict_resolve_short_opt(self):
+        self.assertParseOK(["-v"],
+                           {'verbose': None, 'show_version': 1},
+                           [])
+
+    def test_conflict_resolve_long_opt(self):
+        self.assertParseOK(["--verbose"],
+                           {'verbose': 1},
+                           [])
+
+    def test_conflict_resolve_long_opts(self):
+        self.assertParseOK(["--verbose", "--version"],
+                           {'verbose': 1, 'show_version': 1},
+                           [])
+
+class TestConflictOverride(BaseTest):
+    def setUp(self):
+        self.parser = InterceptingOptionParser(usage=SUPPRESS_USAGE)
+        self.parser.set_conflict_handler("resolve")
+        self.parser.add_option("-n", "--dry-run",
+                               action="store_true", dest="dry_run",
+                               help="don't do anything")
+        self.parser.add_option("--dry-run", "-n",
+                               action="store_const", const=42, dest="dry_run",
+                               help="dry run mode")
+
+    def test_conflict_override_opts(self):
+        opt = self.parser.get_option("--dry-run")
+        self.assertEqual(opt._short_opts, ["-n"])
+        self.assertEqual(opt._long_opts, ["--dry-run"])
+
+    def test_conflict_override_help(self):
+        self.assertOutput(["-h"], """\
+Options:
+  -h, --help     show this help message and exit
+  -n, --dry-run  dry run mode
+""")
+
+    def test_conflict_override_args(self):
+        self.assertParseOK(["-n"],
+                           {'dry_run': 42},
+                           [])
+
+# -- Other testing. ----------------------------------------------------
+
+_expected_help_basic = """\
+Usage: bar.py [options]
+
+Options:
+  -a APPLE           throw APPLEs at basket
+  -b NUM, --boo=NUM  shout "boo!" NUM times (in order to frighten away all the
+                     evil spirits that cause trouble and mayhem)
+  --foo=FOO          store FOO in the foo list for later fooing
+  -h, --help         show this help message and exit
+"""
+
+_expected_help_long_opts_first = """\
+Usage: bar.py [options]
+
+Options:
+  -a APPLE           throw APPLEs at basket
+  --boo=NUM, -b NUM  shout "boo!" NUM times (in order to frighten away all the
+                     evil spirits that cause trouble and mayhem)
+  --foo=FOO          store FOO in the foo list for later fooing
+  --help, -h         show this help message and exit
+"""
+
+_expected_help_title_formatter = """\
+Usage
+=====
+  bar.py [options]
+
+Options
+=======
+-a APPLE           throw APPLEs at basket
+--boo=NUM, -b NUM  shout "boo!" NUM times (in order to frighten away all the
+                   evil spirits that cause trouble and mayhem)
+--foo=FOO          store FOO in the foo list for later fooing
+--help, -h         show this help message and exit
+"""
+
+_expected_help_short_lines = """\
+Usage: bar.py [options]
+
+Options:
+  -a APPLE           throw APPLEs at basket
+  -b NUM, --boo=NUM  shout "boo!" NUM times (in order to
+                     frighten away all the evil spirits
+                     that cause trouble and mayhem)
+  --foo=FOO          store FOO in the foo list for later
+                     fooing
+  -h, --help         show this help message and exit
+"""
+
+class TestHelp(BaseTest):
+    def setUp(self):
+        self.parser = self.make_parser(80)
+
+    def make_parser(self, columns):
+        options = [
+            make_option("-a", type="string", dest='a',
+                        metavar="APPLE", help="throw APPLEs at basket"),
+            make_option("-b", "--boo", type="int", dest='boo',
+                        metavar="NUM",
+                        help=
+                        "shout \"boo!\" NUM times (in order to frighten away "
+                        "all the evil spirits that cause trouble and mayhem)"),
+            make_option("--foo", action="append", type="string", dest='foo',
+                        help="store FOO in the foo list for later fooing"),
+            ]
+
+        # We need to set COLUMNS for the OptionParser constructor, but
+        # we must restore its original value -- otherwise, this test
+        # screws things up for other tests when it's part of the Python
+        # test suite.
+        orig_columns = os.environ.get('COLUMNS')
+        os.environ['COLUMNS'] = str(columns)
+        try:
+            return InterceptingOptionParser(option_list=options)
+        finally:
+            if orig_columns is None:
+                del os.environ['COLUMNS']
+            else:
+                os.environ['COLUMNS'] = orig_columns
+
+    def assertHelpEquals(self, expected_output):
+        if type(expected_output) is types.UnicodeType:
+            encoding = self.parser._get_encoding(sys.stdout)
+            expected_output = expected_output.encode(encoding, "replace")
+
+        save_argv = sys.argv[:]
+        try:
+            # Make optparse believe bar.py is being executed.
+            sys.argv[0] = os.path.join("foo", "bar.py")
+            self.assertOutput(["-h"], expected_output)
+        finally:
+            sys.argv[:] = save_argv
+
+    def test_help(self):
+        self.assertHelpEquals(_expected_help_basic)
+
+    def test_help_old_usage(self):
+        self.parser.set_usage("Usage: %prog [options]")
+        self.assertHelpEquals(_expected_help_basic)
+
+    def test_help_long_opts_first(self):
+        self.parser.formatter.short_first = 0
+        self.assertHelpEquals(_expected_help_long_opts_first)
+
+    def test_help_title_formatter(self):
+        self.parser.formatter = TitledHelpFormatter()
+        self.assertHelpEquals(_expected_help_title_formatter)
+
+    def test_wrap_columns(self):
+        # Ensure that wrapping respects $COLUMNS environment variable.
+        # Need to reconstruct the parser, since that's the only time
+        # we look at $COLUMNS.
+        self.parser = self.make_parser(60)
+        self.assertHelpEquals(_expected_help_short_lines)
+
+    def test_help_unicode(self):
+        self.parser = InterceptingOptionParser(usage=SUPPRESS_USAGE)
+        self.parser.add_option("-a", action="store_true", help=u"ol\u00E9!")
+        expect = u"""\
+Options:
+  -h, --help  show this help message and exit
+  -a          ol\u00E9!
+"""
+        self.assertHelpEquals(expect)
+
+    def test_help_unicode_description(self):
+        self.parser = InterceptingOptionParser(usage=SUPPRESS_USAGE,
+                                               description=u"ol\u00E9!")
+        expect = u"""\
+ol\u00E9!
+
+Options:
+  -h, --help  show this help message and exit
+"""
+        self.assertHelpEquals(expect)
+
+    def test_help_description_groups(self):
+        self.parser.set_description(
+            "This is the program description for %prog.  %prog has "
+            "an option group as well as single options.")
+
+        group = OptionGroup(
+            self.parser, "Dangerous Options",
+            "Caution: use of these options is at your own risk.  "
+            "It is believed that some of them bite.")
+        group.add_option("-g", action="store_true", help="Group option.")
+        self.parser.add_option_group(group)
+
+        expect = """\
+Usage: bar.py [options]
+
+This is the program description for bar.py.  bar.py has an option group as
+well as single options.
+
+Options:
+  -a APPLE           throw APPLEs at basket
+  -b NUM, --boo=NUM  shout "boo!" NUM times (in order to frighten away all the
+                     evil spirits that cause trouble and mayhem)
+  --foo=FOO          store FOO in the foo list for later fooing
+  -h, --help         show this help message and exit
+
+  Dangerous Options:
+    Caution: use of these options is at your own risk.  It is believed
+    that some of them bite.
+
+    -g               Group option.
+"""
+
+        self.assertHelpEquals(expect)
+
+        self.parser.epilog = "Please report bugs to /dev/null."
+        self.assertHelpEquals(expect + "\nPlease report bugs to /dev/null.\n")
+
+
+class TestMatchAbbrev(BaseTest):
+    def test_match_abbrev(self):
+        self.assertEqual(_match_abbrev("--f",
+                                       {"--foz": None,
+                                        "--foo": None,
+                                        "--fie": None,
+                                        "--f": None}),
+                         "--f")
+
+    def test_match_abbrev_error(self):
+        s = "--f"
+        wordmap = {"--foz": None, "--foo": None, "--fie": None}
+        self.assertRaises(
+            _match_abbrev, (s, wordmap), None,
+            BadOptionError, "ambiguous option: --f (--fie, --foo, --foz?)")
+
+
+class TestParseNumber(BaseTest):
+    def setUp(self):
+        self.parser = InterceptingOptionParser()
+        self.parser.add_option("-n", type=int)
+        self.parser.add_option("-l", type=long)
+
+    def test_parse_num_fail(self):
+        self.assertRaises(
+            _parse_num, ("", int), {},
+            ValueError,
+            re.compile(r"invalid literal for int().*: '?'?"))
+        self.assertRaises(
+            _parse_num, ("0xOoops", long), {},
+            ValueError,
+            re.compile(r"invalid literal for long().*: '?0xOoops'?"))
+
+    def test_parse_num_ok(self):
+        self.assertEqual(_parse_num("0", int), 0)
+        self.assertEqual(_parse_num("0x10", int), 16)
+        self.assertEqual(_parse_num("0XA", long), 10L)
+        self.assertEqual(_parse_num("010", long), 8L)
+        self.assertEqual(_parse_num("0b11", int), 3)
+        self.assertEqual(_parse_num("0b", long), 0L)
+
+    def test_numeric_options(self):
+        self.assertParseOK(["-n", "42", "-l", "0x20"],
+                           { "n": 42, "l": 0x20 }, [])
+        self.assertParseOK(["-n", "0b0101", "-l010"],
+                           { "n": 5, "l": 8 }, [])
+        self.assertParseFail(["-n008"],
+                             "option -n: invalid integer value: '008'")
+        self.assertParseFail(["-l0b0123"],
+                             "option -l: invalid long integer value: '0b0123'")
+        self.assertParseFail(["-l", "0x12x"],
+                             "option -l: invalid long integer value: '0x12x'")
+
+
+def _testclasses():
+    mod = sys.modules[__name__]
+    return [getattr(mod, name) for name in dir(mod) if name.startswith('Test')]
+
+def suite():
+    suite = unittest.TestSuite()
+    for testclass in _testclasses():
+        suite.addTest(unittest.makeSuite(testclass))
+    return suite
+
+def test_main():
+    test_support.run_suite(suite())
+
+if __name__ == '__main__':
+    unittest.main()

Added: vendor/Python/current/Lib/test/test_os.py
===================================================================
--- vendor/Python/current/Lib/test/test_os.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_os.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,438 @@
+# As a test suite for the os module, this is woefully inadequate, but this
+# does add tests for a few functions which have been determined to be more
+# portable than they had been thought to be.
+
+import os
+import unittest
+import warnings
+import sys
+from test import test_support
+
+warnings.filterwarnings("ignore", "tempnam", RuntimeWarning, __name__)
+warnings.filterwarnings("ignore", "tmpnam", RuntimeWarning, __name__)
+
+# Tests creating TESTFN
+class FileTests(unittest.TestCase):
+    def setUp(self):
+        if os.path.exists(test_support.TESTFN):
+            os.unlink(test_support.TESTFN)
+    tearDown = setUp
+
+    def test_access(self):
+        f = os.open(test_support.TESTFN, os.O_CREAT|os.O_RDWR)
+        os.close(f)
+        self.assert_(os.access(test_support.TESTFN, os.W_OK))
+
+
+class TemporaryFileTests(unittest.TestCase):
+    def setUp(self):
+        self.files = []
+        os.mkdir(test_support.TESTFN)
+
+    def tearDown(self):
+        for name in self.files:
+            os.unlink(name)
+        os.rmdir(test_support.TESTFN)
+
+    def check_tempfile(self, name):
+        # make sure it doesn't already exist:
+        self.failIf(os.path.exists(name),
+                    "file already exists for temporary file")
+        # make sure we can create the file
+        open(name, "w")
+        self.files.append(name)
+
+    def test_tempnam(self):
+        if not hasattr(os, "tempnam"):
+            return
+        warnings.filterwarnings("ignore", "tempnam", RuntimeWarning,
+                                r"test_os$")
+        self.check_tempfile(os.tempnam())
+
+        name = os.tempnam(test_support.TESTFN)
+        self.check_tempfile(name)
+
+        name = os.tempnam(test_support.TESTFN, "pfx")
+        self.assert_(os.path.basename(name)[:3] == "pfx")
+        self.check_tempfile(name)
+
+    def test_tmpfile(self):
+        if not hasattr(os, "tmpfile"):
+            return
+        fp = os.tmpfile()
+        fp.write("foobar")
+        fp.seek(0,0)
+        s = fp.read()
+        fp.close()
+        self.assert_(s == "foobar")
+
+    def test_tmpnam(self):
+        import sys
+        if not hasattr(os, "tmpnam"):
+            return
+        warnings.filterwarnings("ignore", "tmpnam", RuntimeWarning,
+                                r"test_os$")
+        name = os.tmpnam()
+        if sys.platform in ("win32",):
+            # The Windows tmpnam() seems useless.  From the MS docs:
+            #
+            #     The character string that tmpnam creates consists of
+            #     the path prefix, defined by the entry P_tmpdir in the
+            #     file STDIO.H, followed by a sequence consisting of the
+            #     digit characters '0' through '9'; the numerical value
+            #     of this string is in the range 1 - 65,535.  Changing the
+            #     definitions of L_tmpnam or P_tmpdir in STDIO.H does not
+            #     change the operation of tmpnam.
+            #
+            # The really bizarre part is that, at least under MSVC6,
+            # P_tmpdir is "\\".  That is, the path returned refers to
+            # the root of the current drive.  That's a terrible place to
+            # put temp files, and, depending on privileges, the user
+            # may not even be able to open a file in the root directory.
+            self.failIf(os.path.exists(name),
+                        "file already exists for temporary file")
+        else:
+            self.check_tempfile(name)
+
+# Test attributes on return values from os.*stat* family.
+class StatAttributeTests(unittest.TestCase):
+    def setUp(self):
+        os.mkdir(test_support.TESTFN)
+        self.fname = os.path.join(test_support.TESTFN, "f1")
+        f = open(self.fname, 'wb')
+        f.write("ABC")
+        f.close()
+
+    def tearDown(self):
+        os.unlink(self.fname)
+        os.rmdir(test_support.TESTFN)
+
+    def test_stat_attributes(self):
+        if not hasattr(os, "stat"):
+            return
+
+        import stat
+        result = os.stat(self.fname)
+
+        # Make sure direct access works
+        self.assertEquals(result[stat.ST_SIZE], 3)
+        self.assertEquals(result.st_size, 3)
+
+        import sys
+
+        # Make sure all the attributes are there
+        members = dir(result)
+        for name in dir(stat):
+            if name[:3] == 'ST_':
+                attr = name.lower()
+                if name.endswith("TIME"):
+                    def trunc(x): return int(x)
+                else:
+                    def trunc(x): return x
+                self.assertEquals(trunc(getattr(result, attr)),
+                                  result[getattr(stat, name)])
+                self.assert_(attr in members)
+
+        try:
+            result[200]
+            self.fail("No exception thrown")
+        except IndexError:
+            pass
+
+        # Make sure that assignment fails
+        try:
+            result.st_mode = 1
+            self.fail("No exception thrown")
+        except TypeError:
+            pass
+
+        try:
+            result.st_rdev = 1
+            self.fail("No exception thrown")
+        except (AttributeError, TypeError):
+            pass
+
+        try:
+            result.parrot = 1
+            self.fail("No exception thrown")
+        except AttributeError:
+            pass
+
+        # Use the stat_result constructor with a too-short tuple.
+        try:
+            result2 = os.stat_result((10,))
+            self.fail("No exception thrown")
+        except TypeError:
+            pass
+
+        # Use the constructr with a too-long tuple.
+        try:
+            result2 = os.stat_result((0,1,2,3,4,5,6,7,8,9,10,11,12,13,14))
+        except TypeError:
+            pass
+
+
+    def test_statvfs_attributes(self):
+        if not hasattr(os, "statvfs"):
+            return
+
+        import statvfs
+        try:
+            result = os.statvfs(self.fname)
+        except OSError, e:
+            # On AtheOS, glibc always returns ENOSYS
+            import errno
+            if e.errno == errno.ENOSYS:
+                return
+
+        # Make sure direct access works
+        self.assertEquals(result.f_bfree, result[statvfs.F_BFREE])
+
+        # Make sure all the attributes are there
+        members = dir(result)
+        for name in dir(statvfs):
+            if name[:2] == 'F_':
+                attr = name.lower()
+                self.assertEquals(getattr(result, attr),
+                                  result[getattr(statvfs, name)])
+                self.assert_(attr in members)
+
+        # Make sure that assignment really fails
+        try:
+            result.f_bfree = 1
+            self.fail("No exception thrown")
+        except TypeError:
+            pass
+
+        try:
+            result.parrot = 1
+            self.fail("No exception thrown")
+        except AttributeError:
+            pass
+
+        # Use the constructor with a too-short tuple.
+        try:
+            result2 = os.statvfs_result((10,))
+            self.fail("No exception thrown")
+        except TypeError:
+            pass
+
+        # Use the constructr with a too-long tuple.
+        try:
+            result2 = os.statvfs_result((0,1,2,3,4,5,6,7,8,9,10,11,12,13,14))
+        except TypeError:
+            pass
+
+    # Restrict test to Win32, since there is no guarantee other
+    # systems support centiseconds
+    if sys.platform == 'win32':
+        def test_1565150(self):
+            t1 = 1159195039.25
+            os.utime(self.fname, (t1, t1))
+            self.assertEquals(os.stat(self.fname).st_mtime, t1)
+
+        def test_1686475(self):
+            # Verify that an open file can be stat'ed
+            try:
+                os.stat(r"c:\pagefile.sys")
+            except WindowsError, e:
+                if e == 2: # file does not exist; cannot run test
+                    return
+                self.fail("Could not stat pagefile.sys")
+
+from test import mapping_tests
+
+class EnvironTests(mapping_tests.BasicTestMappingProtocol):
+    """check that os.environ object conform to mapping protocol"""
+    type2test = None
+    def _reference(self):
+        return {"KEY1":"VALUE1", "KEY2":"VALUE2", "KEY3":"VALUE3"}
+    def _empty_mapping(self):
+        os.environ.clear()
+        return os.environ
+    def setUp(self):
+        self.__save = dict(os.environ)
+        os.environ.clear()
+    def tearDown(self):
+        os.environ.clear()
+        os.environ.update(self.__save)
+
+    # Bug 1110478
+    def test_update2(self):
+        if os.path.exists("/bin/sh"):
+            os.environ.update(HELLO="World")
+            value = os.popen("/bin/sh -c 'echo $HELLO'").read().strip()
+            self.assertEquals(value, "World")
+
+class WalkTests(unittest.TestCase):
+    """Tests for os.walk()."""
+
+    def test_traversal(self):
+        import os
+        from os.path import join
+
+        # Build:
+        #     TESTFN/               a file kid and two directory kids
+        #         tmp1
+        #         SUB1/             a file kid and a directory kid
+        #             tmp2
+        #             SUB11/        no kids
+        #         SUB2/             just a file kid
+        #             tmp3
+        sub1_path = join(test_support.TESTFN, "SUB1")
+        sub11_path = join(sub1_path, "SUB11")
+        sub2_path = join(test_support.TESTFN, "SUB2")
+        tmp1_path = join(test_support.TESTFN, "tmp1")
+        tmp2_path = join(sub1_path, "tmp2")
+        tmp3_path = join(sub2_path, "tmp3")
+
+        # Create stuff.
+        os.makedirs(sub11_path)
+        os.makedirs(sub2_path)
+        for path in tmp1_path, tmp2_path, tmp3_path:
+            f = file(path, "w")
+            f.write("I'm " + path + " and proud of it.  Blame test_os.\n")
+            f.close()
+
+        # Walk top-down.
+        all = list(os.walk(test_support.TESTFN))
+        self.assertEqual(len(all), 4)
+        # We can't know which order SUB1 and SUB2 will appear in.
+        # Not flipped:  TESTFN, SUB1, SUB11, SUB2
+        #     flipped:  TESTFN, SUB2, SUB1, SUB11
+        flipped = all[0][1][0] != "SUB1"
+        all[0][1].sort()
+        self.assertEqual(all[0], (test_support.TESTFN, ["SUB1", "SUB2"], ["tmp1"]))
+        self.assertEqual(all[1 + flipped], (sub1_path, ["SUB11"], ["tmp2"]))
+        self.assertEqual(all[2 + flipped], (sub11_path, [], []))
+        self.assertEqual(all[3 - 2 * flipped], (sub2_path, [], ["tmp3"]))
+
+        # Prune the search.
+        all = []
+        for root, dirs, files in os.walk(test_support.TESTFN):
+            all.append((root, dirs, files))
+            # Don't descend into SUB1.
+            if 'SUB1' in dirs:
+                # Note that this also mutates the dirs we appended to all!
+                dirs.remove('SUB1')
+        self.assertEqual(len(all), 2)
+        self.assertEqual(all[0], (test_support.TESTFN, ["SUB2"], ["tmp1"]))
+        self.assertEqual(all[1], (sub2_path, [], ["tmp3"]))
+
+        # Walk bottom-up.
+        all = list(os.walk(test_support.TESTFN, topdown=False))
+        self.assertEqual(len(all), 4)
+        # We can't know which order SUB1 and SUB2 will appear in.
+        # Not flipped:  SUB11, SUB1, SUB2, TESTFN
+        #     flipped:  SUB2, SUB11, SUB1, TESTFN
+        flipped = all[3][1][0] != "SUB1"
+        all[3][1].sort()
+        self.assertEqual(all[3], (test_support.TESTFN, ["SUB1", "SUB2"], ["tmp1"]))
+        self.assertEqual(all[flipped], (sub11_path, [], []))
+        self.assertEqual(all[flipped + 1], (sub1_path, ["SUB11"], ["tmp2"]))
+        self.assertEqual(all[2 - 2 * flipped], (sub2_path, [], ["tmp3"]))
+
+        # Tear everything down.  This is a decent use for bottom-up on
+        # Windows, which doesn't have a recursive delete command.  The
+        # (not so) subtlety is that rmdir will fail unless the dir's
+        # kids are removed first, so bottom up is essential.
+        for root, dirs, files in os.walk(test_support.TESTFN, topdown=False):
+            for name in files:
+                os.remove(join(root, name))
+            for name in dirs:
+                os.rmdir(join(root, name))
+        os.rmdir(test_support.TESTFN)
+
+class MakedirTests (unittest.TestCase):
+    def setUp(self):
+        os.mkdir(test_support.TESTFN)
+
+    def test_makedir(self):
+        base = test_support.TESTFN
+        path = os.path.join(base, 'dir1', 'dir2', 'dir3')
+        os.makedirs(path)             # Should work
+        path = os.path.join(base, 'dir1', 'dir2', 'dir3', 'dir4')
+        os.makedirs(path)
+
+        # Try paths with a '.' in them
+        self.failUnlessRaises(OSError, os.makedirs, os.curdir)
+        path = os.path.join(base, 'dir1', 'dir2', 'dir3', 'dir4', 'dir5', os.curdir)
+        os.makedirs(path)
+        path = os.path.join(base, 'dir1', os.curdir, 'dir2', 'dir3', 'dir4',
+                            'dir5', 'dir6')
+        os.makedirs(path)
+
+
+
+
+    def tearDown(self):
+        path = os.path.join(test_support.TESTFN, 'dir1', 'dir2', 'dir3',
+                            'dir4', 'dir5', 'dir6')
+        # If the tests failed, the bottom-most directory ('../dir6')
+        # may not have been created, so we look for the outermost directory
+        # that exists.
+        while not os.path.exists(path) and path != test_support.TESTFN:
+            path = os.path.dirname(path)
+
+        os.removedirs(path)
+
+class DevNullTests (unittest.TestCase):
+    def test_devnull(self):
+        f = file(os.devnull, 'w')
+        f.write('hello')
+        f.close()
+        f = file(os.devnull, 'r')
+        self.assertEqual(f.read(), '')
+        f.close()
+
+class URandomTests (unittest.TestCase):
+    def test_urandom(self):
+        try:
+            self.assertEqual(len(os.urandom(1)), 1)
+            self.assertEqual(len(os.urandom(10)), 10)
+            self.assertEqual(len(os.urandom(100)), 100)
+            self.assertEqual(len(os.urandom(1000)), 1000)
+        except NotImplementedError:
+            pass
+
+class Win32ErrorTests(unittest.TestCase):
+    def test_rename(self):
+        self.assertRaises(WindowsError, os.rename, test_support.TESTFN, test_support.TESTFN+".bak")
+
+    def test_remove(self):
+        self.assertRaises(WindowsError, os.remove, test_support.TESTFN)
+
+    def test_chdir(self):
+        self.assertRaises(WindowsError, os.chdir, test_support.TESTFN)
+
+    def test_mkdir(self):
+        self.assertRaises(WindowsError, os.chdir, test_support.TESTFN)
+
+    def test_utime(self):
+        self.assertRaises(WindowsError, os.utime, test_support.TESTFN, None)
+
+    def test_access(self):
+        self.assertRaises(WindowsError, os.utime, test_support.TESTFN, 0)
+
+    def test_chmod(self):
+        self.assertRaises(WindowsError, os.utime, test_support.TESTFN, 0)
+
+if sys.platform != 'win32':
+    class Win32ErrorTests(unittest.TestCase):
+        pass
+
+def test_main():
+    test_support.run_unittest(
+        FileTests,
+        TemporaryFileTests,
+        StatAttributeTests,
+        EnvironTests,
+        WalkTests,
+        MakedirTests,
+        DevNullTests,
+        URandomTests,
+        Win32ErrorTests
+    )
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_ossaudiodev.py
===================================================================
--- vendor/Python/current/Lib/test/test_ossaudiodev.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_ossaudiodev.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,163 @@
+from test import test_support
+test_support.requires('audio')
+
+from test.test_support import verbose, findfile, TestFailed, TestSkipped
+
+import errno
+import fcntl
+import ossaudiodev
+import os
+import sys
+import select
+import sunaudio
+import time
+import audioop
+
+# Arggh, AFMT_S16_NE not defined on all platforms -- seems to be a
+# fairly recent addition to OSS.
+try:
+    from ossaudiodev import AFMT_S16_NE
+except ImportError:
+    if sys.byteorder == "little":
+        AFMT_S16_NE = ossaudiodev.AFMT_S16_LE
+    else:
+        AFMT_S16_NE = ossaudiodev.AFMT_S16_BE
+
+
+SND_FORMAT_MULAW_8 = 1
+
+def read_sound_file(path):
+    fp = open(path, 'rb')
+    size, enc, rate, nchannels, extra = sunaudio.gethdr(fp)
+    data = fp.read()
+    fp.close()
+
+    if enc != SND_FORMAT_MULAW_8:
+        print "Expect .au file with 8-bit mu-law samples"
+        return
+
+    # Convert the data to 16-bit signed.
+    data = audioop.ulaw2lin(data, 2)
+    return (data, rate, 16, nchannels)
+
+# version of assert that still works with -O
+def _assert(expr, message=None):
+    if not expr:
+        raise AssertionError(message or "assertion failed")
+
+def play_sound_file(data, rate, ssize, nchannels):
+    try:
+        dsp = ossaudiodev.open('w')
+    except IOError, msg:
+        if msg[0] in (errno.EACCES, errno.ENOENT, errno.ENODEV, errno.EBUSY):
+            raise TestSkipped, msg
+        raise TestFailed, msg
+
+    # at least check that these methods can be invoked
+    dsp.bufsize()
+    dsp.obufcount()
+    dsp.obuffree()
+    dsp.getptr()
+    dsp.fileno()
+
+    # Make sure the read-only attributes work.
+    _assert(dsp.closed is False, "dsp.closed is not False")
+    _assert(dsp.name == "/dev/dsp")
+    _assert(dsp.mode == 'w', "bad dsp.mode: %r" % dsp.mode)
+
+    # And make sure they're really read-only.
+    for attr in ('closed', 'name', 'mode'):
+        try:
+            setattr(dsp, attr, 42)
+            raise RuntimeError("dsp.%s not read-only" % attr)
+        except TypeError:
+            pass
+
+    # Compute expected running time of sound sample (in seconds).
+    expected_time = float(len(data)) / (ssize/8) / nchannels / rate
+
+    # set parameters based on .au file headers
+    dsp.setparameters(AFMT_S16_NE, nchannels, rate)
+    print ("playing test sound file (expected running time: %.2f sec)"
+           % expected_time)
+    t1 = time.time()
+    dsp.write(data)
+    dsp.close()
+    t2 = time.time()
+    elapsed_time = t2 - t1
+
+    percent_diff = (abs(elapsed_time - expected_time) / expected_time) * 100
+    _assert(percent_diff <= 10.0, \
+            ("elapsed time (%.2f sec) > 10%% off of expected time (%.2f sec)"
+             % (elapsed_time, expected_time)))
+
+def test_setparameters(dsp):
+    # Two configurations for testing:
+    #   config1 (8-bit, mono, 8 kHz) should work on even the most
+    #      ancient and crufty sound card, but maybe not on special-
+    #      purpose high-end hardware
+    #   config2 (16-bit, stereo, 44.1kHz) should work on all but the
+    #      most ancient and crufty hardware
+    config1 = (ossaudiodev.AFMT_U8, 1, 8000)
+    config2 = (AFMT_S16_NE, 2, 44100)
+
+    for config in [config1, config2]:
+        (fmt, channels, rate) = config
+        if (dsp.setfmt(fmt) == fmt and
+            dsp.channels(channels) == channels and
+            dsp.speed(rate) == rate):
+            break
+    else:
+        raise RuntimeError("unable to set audio sampling parameters: "
+                           "you must have really weird audio hardware")
+
+    # setparameters() should be able to set this configuration in
+    # either strict or non-strict mode.
+    result = dsp.setparameters(fmt, channels, rate, False)
+    _assert(result == (fmt, channels, rate),
+            "setparameters%r: returned %r" % (config, result))
+    result = dsp.setparameters(fmt, channels, rate, True)
+    _assert(result == (fmt, channels, rate),
+            "setparameters%r: returned %r" % (config, result))
+
+def test_bad_setparameters(dsp):
+
+    # Now try some configurations that are presumably bogus: eg. 300
+    # channels currently exceeds even Hollywood's ambitions, and
+    # negative sampling rate is utter nonsense.  setparameters() should
+    # accept these in non-strict mode, returning something other than
+    # was requested, but should barf in strict mode.
+    fmt = AFMT_S16_NE
+    rate = 44100
+    channels = 2
+    for config in [(fmt, 300, rate),       # ridiculous nchannels
+                   (fmt, -5, rate),        # impossible nchannels
+                   (fmt, channels, -50),   # impossible rate
+                  ]:
+        (fmt, channels, rate) = config
+        result = dsp.setparameters(fmt, channels, rate, False)
+        _assert(result != config,
+                "setparameters: unexpectedly got requested configuration")
+
+        try:
+            result = dsp.setparameters(fmt, channels, rate, True)
+            raise AssertionError("setparameters: expected OSSAudioError")
+        except ossaudiodev.OSSAudioError, err:
+            print "setparameters: got OSSAudioError as expected"
+
+def test():
+    (data, rate, ssize, nchannels) = read_sound_file(findfile('audiotest.au'))
+    play_sound_file(data, rate, ssize, nchannels)
+
+    dsp = ossaudiodev.open("w")
+    try:
+        test_setparameters(dsp)
+
+        # Disabled because it fails under Linux 2.6 with ALSA's OSS
+        # emulation layer.
+        #test_bad_setparameters(dsp)
+    finally:
+        dsp.close()
+        _assert(dsp.closed is True, "dsp.closed is not True")
+
+test()

Added: vendor/Python/current/Lib/test/test_parser.py
===================================================================
--- vendor/Python/current/Lib/test/test_parser.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_parser.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,448 @@
+import parser
+import unittest
+from test import test_support
+
+#
+#  First, we test that we can generate trees from valid source fragments,
+#  and that these valid trees are indeed allowed by the tree-loading side
+#  of the parser module.
+#
+
+class RoundtripLegalSyntaxTestCase(unittest.TestCase):
+
+    def roundtrip(self, f, s):
+        st1 = f(s)
+        t = st1.totuple()
+        try:
+            st2 = parser.sequence2st(t)
+        except parser.ParserError, why:
+            self.fail("could not roundtrip %r: %s" % (s, why))
+
+        self.assertEquals(t, st2.totuple(),
+                          "could not re-generate syntax tree")
+
+    def check_expr(self, s):
+        self.roundtrip(parser.expr, s)
+
+    def check_suite(self, s):
+        self.roundtrip(parser.suite, s)
+
+    def test_yield_statement(self):
+        self.check_suite("def f(): yield 1")
+        self.check_suite("def f(): yield")
+        self.check_suite("def f(): x += yield")
+        self.check_suite("def f(): x = yield 1")
+        self.check_suite("def f(): x = y = yield 1")
+        self.check_suite("def f(): x = yield")
+        self.check_suite("def f(): x = y = yield")
+        self.check_suite("def f(): 1 + (yield)*2")
+        self.check_suite("def f(): (yield 1)*2")
+        self.check_suite("def f(): return; yield 1")
+        self.check_suite("def f(): yield 1; return")
+        self.check_suite("def f():\n"
+                         "    for x in range(30):\n"
+                         "        yield x\n")
+        self.check_suite("def f():\n"
+                         "    if (yield):\n"
+                         "        yield x\n")
+
+    def test_expressions(self):
+        self.check_expr("foo(1)")
+        self.check_expr("[1, 2, 3]")
+        self.check_expr("[x**3 for x in range(20)]")
+        self.check_expr("[x**3 for x in range(20) if x % 3]")
+        self.check_expr("[x**3 for x in range(20) if x % 2 if x % 3]")
+        self.check_expr("list(x**3 for x in range(20))")
+        self.check_expr("list(x**3 for x in range(20) if x % 3)")
+        self.check_expr("list(x**3 for x in range(20) if x % 2 if x % 3)")
+        self.check_expr("foo(*args)")
+        self.check_expr("foo(*args, **kw)")
+        self.check_expr("foo(**kw)")
+        self.check_expr("foo(key=value)")
+        self.check_expr("foo(key=value, *args)")
+        self.check_expr("foo(key=value, *args, **kw)")
+        self.check_expr("foo(key=value, **kw)")
+        self.check_expr("foo(a, b, c, *args)")
+        self.check_expr("foo(a, b, c, *args, **kw)")
+        self.check_expr("foo(a, b, c, **kw)")
+        self.check_expr("foo + bar")
+        self.check_expr("foo - bar")
+        self.check_expr("foo * bar")
+        self.check_expr("foo / bar")
+        self.check_expr("foo // bar")
+        self.check_expr("lambda: 0")
+        self.check_expr("lambda x: 0")
+        self.check_expr("lambda *y: 0")
+        self.check_expr("lambda *y, **z: 0")
+        self.check_expr("lambda **z: 0")
+        self.check_expr("lambda x, y: 0")
+        self.check_expr("lambda foo=bar: 0")
+        self.check_expr("lambda foo=bar, spaz=nifty+spit: 0")
+        self.check_expr("lambda foo=bar, **z: 0")
+        self.check_expr("lambda foo=bar, blaz=blat+2, **z: 0")
+        self.check_expr("lambda foo=bar, blaz=blat+2, *y, **z: 0")
+        self.check_expr("lambda x, *y, **z: 0")
+        self.check_expr("(x for x in range(10))")
+        self.check_expr("foo(x for x in range(10))")
+
+    def test_print(self):
+        self.check_suite("print")
+        self.check_suite("print 1")
+        self.check_suite("print 1,")
+        self.check_suite("print >>fp")
+        self.check_suite("print >>fp, 1")
+        self.check_suite("print >>fp, 1,")
+
+    def test_simple_expression(self):
+        # expr_stmt
+        self.check_suite("a")
+
+    def test_simple_assignments(self):
+        self.check_suite("a = b")
+        self.check_suite("a = b = c = d = e")
+
+    def test_simple_augmented_assignments(self):
+        self.check_suite("a += b")
+        self.check_suite("a -= b")
+        self.check_suite("a *= b")
+        self.check_suite("a /= b")
+        self.check_suite("a //= b")
+        self.check_suite("a %= b")
+        self.check_suite("a &= b")
+        self.check_suite("a |= b")
+        self.check_suite("a ^= b")
+        self.check_suite("a <<= b")
+        self.check_suite("a >>= b")
+        self.check_suite("a **= b")
+
+    def test_function_defs(self):
+        self.check_suite("def f(): pass")
+        self.check_suite("def f(*args): pass")
+        self.check_suite("def f(*args, **kw): pass")
+        self.check_suite("def f(**kw): pass")
+        self.check_suite("def f(foo=bar): pass")
+        self.check_suite("def f(foo=bar, *args): pass")
+        self.check_suite("def f(foo=bar, *args, **kw): pass")
+        self.check_suite("def f(foo=bar, **kw): pass")
+
+        self.check_suite("def f(a, b): pass")
+        self.check_suite("def f(a, b, *args): pass")
+        self.check_suite("def f(a, b, *args, **kw): pass")
+        self.check_suite("def f(a, b, **kw): pass")
+        self.check_suite("def f(a, b, foo=bar): pass")
+        self.check_suite("def f(a, b, foo=bar, *args): pass")
+        self.check_suite("def f(a, b, foo=bar, *args, **kw): pass")
+        self.check_suite("def f(a, b, foo=bar, **kw): pass")
+
+        self.check_suite("@staticmethod\n"
+                         "def f(): pass")
+        self.check_suite("@staticmethod\n"
+                         "@funcattrs(x, y)\n"
+                         "def f(): pass")
+        self.check_suite("@funcattrs()\n"
+                         "def f(): pass")
+
+    def test_class_defs(self):
+        self.check_suite("class foo():pass")
+
+    def test_import_from_statement(self):
+        self.check_suite("from sys.path import *")
+        self.check_suite("from sys.path import dirname")
+        self.check_suite("from sys.path import (dirname)")
+        self.check_suite("from sys.path import (dirname,)")
+        self.check_suite("from sys.path import dirname as my_dirname")
+        self.check_suite("from sys.path import (dirname as my_dirname)")
+        self.check_suite("from sys.path import (dirname as my_dirname,)")
+        self.check_suite("from sys.path import dirname, basename")
+        self.check_suite("from sys.path import (dirname, basename)")
+        self.check_suite("from sys.path import (dirname, basename,)")
+        self.check_suite(
+            "from sys.path import dirname as my_dirname, basename")
+        self.check_suite(
+            "from sys.path import (dirname as my_dirname, basename)")
+        self.check_suite(
+            "from sys.path import (dirname as my_dirname, basename,)")
+        self.check_suite(
+            "from sys.path import dirname, basename as my_basename")
+        self.check_suite(
+            "from sys.path import (dirname, basename as my_basename)")
+        self.check_suite(
+            "from sys.path import (dirname, basename as my_basename,)")
+
+    def test_basic_import_statement(self):
+        self.check_suite("import sys")
+        self.check_suite("import sys as system")
+        self.check_suite("import sys, math")
+        self.check_suite("import sys as system, math")
+        self.check_suite("import sys, math as my_math")
+
+    def test_pep263(self):
+        self.check_suite("# -*- coding: iso-8859-1 -*-\n"
+                         "pass\n")
+
+    def test_assert(self):
+        self.check_suite("assert alo < ahi and blo < bhi\n")
+
+#
+#  Second, we take *invalid* trees and make sure we get ParserError
+#  rejections for them.
+#
+
+class IllegalSyntaxTestCase(unittest.TestCase):
+
+    def check_bad_tree(self, tree, label):
+        try:
+            parser.sequence2st(tree)
+        except parser.ParserError:
+            pass
+        else:
+            self.fail("did not detect invalid tree for %r" % label)
+
+    def test_junk(self):
+        # not even remotely valid:
+        self.check_bad_tree((1, 2, 3), "<junk>")
+
+    def test_illegal_yield_1(self):
+        # Illegal yield statement: def f(): return 1; yield 1
+        tree = \
+        (257,
+         (264,
+          (285,
+           (259,
+            (1, 'def'),
+            (1, 'f'),
+            (260, (7, '('), (8, ')')),
+            (11, ':'),
+            (291,
+             (4, ''),
+             (5, ''),
+             (264,
+              (265,
+               (266,
+                (272,
+                 (275,
+                  (1, 'return'),
+                  (313,
+                   (292,
+                    (293,
+                     (294,
+                      (295,
+                       (297,
+                        (298,
+                         (299,
+                          (300,
+                           (301,
+                            (302, (303, (304, (305, (2, '1')))))))))))))))))),
+               (264,
+                (265,
+                 (266,
+                  (272,
+                   (276,
+                    (1, 'yield'),
+                    (313,
+                     (292,
+                      (293,
+                       (294,
+                        (295,
+                         (297,
+                          (298,
+                           (299,
+                            (300,
+                             (301,
+                              (302,
+                               (303, (304, (305, (2, '1')))))))))))))))))),
+                 (4, ''))),
+               (6, ''))))),
+           (4, ''),
+           (0, ''))))
+        self.check_bad_tree(tree, "def f():\n  return 1\n  yield 1")
+
+    def test_illegal_yield_2(self):
+        # Illegal return in generator: def f(): return 1; yield 1
+        tree = \
+        (257,
+         (264,
+          (265,
+           (266,
+            (278,
+             (1, 'from'),
+             (281, (1, '__future__')),
+             (1, 'import'),
+             (279, (1, 'generators')))),
+           (4, ''))),
+         (264,
+          (285,
+           (259,
+            (1, 'def'),
+            (1, 'f'),
+            (260, (7, '('), (8, ')')),
+            (11, ':'),
+            (291,
+             (4, ''),
+             (5, ''),
+             (264,
+              (265,
+               (266,
+                (272,
+                 (275,
+                  (1, 'return'),
+                  (313,
+                   (292,
+                    (293,
+                     (294,
+                      (295,
+                       (297,
+                        (298,
+                         (299,
+                          (300,
+                           (301,
+                            (302, (303, (304, (305, (2, '1')))))))))))))))))),
+               (264,
+                (265,
+                 (266,
+                  (272,
+                   (276,
+                    (1, 'yield'),
+                    (313,
+                     (292,
+                      (293,
+                       (294,
+                        (295,
+                         (297,
+                          (298,
+                           (299,
+                            (300,
+                             (301,
+                              (302,
+                               (303, (304, (305, (2, '1')))))))))))))))))),
+                 (4, ''))),
+               (6, ''))))),
+           (4, ''),
+           (0, ''))))
+        self.check_bad_tree(tree, "def f():\n  return 1\n  yield 1")
+
+    def test_print_chevron_comma(self):
+        # Illegal input: print >>fp,
+        tree = \
+        (257,
+         (264,
+          (265,
+           (266,
+            (268,
+             (1, 'print'),
+             (35, '>>'),
+             (290,
+              (291,
+               (292,
+                (293,
+                 (295,
+                  (296,
+                   (297,
+                    (298, (299, (300, (301, (302, (303, (1, 'fp')))))))))))))),
+             (12, ','))),
+           (4, ''))),
+         (0, ''))
+        self.check_bad_tree(tree, "print >>fp,")
+
+    def test_a_comma_comma_c(self):
+        # Illegal input: a,,c
+        tree = \
+        (258,
+         (311,
+          (290,
+           (291,
+            (292,
+             (293,
+              (295,
+               (296,
+                (297,
+                 (298, (299, (300, (301, (302, (303, (1, 'a')))))))))))))),
+          (12, ','),
+          (12, ','),
+          (290,
+           (291,
+            (292,
+             (293,
+              (295,
+               (296,
+                (297,
+                 (298, (299, (300, (301, (302, (303, (1, 'c'))))))))))))))),
+         (4, ''),
+         (0, ''))
+        self.check_bad_tree(tree, "a,,c")
+
+    def test_illegal_operator(self):
+        # Illegal input: a $= b
+        tree = \
+        (257,
+         (264,
+          (265,
+           (266,
+            (267,
+             (312,
+              (291,
+               (292,
+                (293,
+                 (294,
+                  (296,
+                   (297,
+                    (298,
+                     (299,
+                      (300, (301, (302, (303, (304, (1, 'a'))))))))))))))),
+             (268, (37, '$=')),
+             (312,
+              (291,
+               (292,
+                (293,
+                 (294,
+                  (296,
+                   (297,
+                    (298,
+                     (299,
+                      (300, (301, (302, (303, (304, (1, 'b'))))))))))))))))),
+           (4, ''))),
+         (0, ''))
+        self.check_bad_tree(tree, "a $= b")
+
+    def test_malformed_global(self):
+        #doesn't have global keyword in ast
+        tree = (257,
+                (264,
+                 (265,
+                  (266,
+                   (282, (1, 'foo'))), (4, ''))),
+                (4, ''),
+                (0, ''))
+        self.check_bad_tree(tree, "malformed global ast")
+
+
+class CompileTestCase(unittest.TestCase):
+
+    # These tests are very minimal. :-(
+
+    def test_compile_expr(self):
+        st = parser.expr('2 + 3')
+        code = parser.compilest(st)
+        self.assertEquals(eval(code), 5)
+
+    def test_compile_suite(self):
+        st = parser.suite('x = 2; y = x + 3')
+        code = parser.compilest(st)
+        globs = {}
+        exec code in globs
+        self.assertEquals(globs['y'], 5)
+
+    def test_compile_error(self):
+        st = parser.suite('1 = 3 + 4')
+        self.assertRaises(SyntaxError, parser.compilest, st)
+
+def test_main():
+    test_support.run_unittest(
+        RoundtripLegalSyntaxTestCase,
+        IllegalSyntaxTestCase,
+        CompileTestCase,
+    )
+
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_peepholer.py
===================================================================
--- vendor/Python/current/Lib/test/test_peepholer.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_peepholer.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,188 @@
+import dis
+import sys
+from cStringIO import StringIO
+import unittest
+
+def disassemble(func):
+    f = StringIO()
+    tmp = sys.stdout
+    sys.stdout = f
+    dis.dis(func)
+    sys.stdout = tmp
+    result = f.getvalue()
+    f.close()
+    return result
+
+def dis_single(line):
+    return disassemble(compile(line, '', 'single'))
+
+class TestTranforms(unittest.TestCase):
+
+    def test_unot(self):
+        # UNARY_NOT JUMP_IF_FALSE POP_TOP  -->  JUMP_IF_TRUE POP_TOP'
+        def unot(x):
+            if not x == 2:
+                del x
+        asm = disassemble(unot)
+        for elem in ('UNARY_NOT', 'JUMP_IF_FALSE'):
+            self.assert_(elem not in asm)
+        for elem in ('JUMP_IF_TRUE', 'POP_TOP'):
+            self.assert_(elem in asm)
+
+    def test_elim_inversion_of_is_or_in(self):
+        for line, elem in (
+            ('not a is b', '(is not)',),
+            ('not a in b', '(not in)',),
+            ('not a is not b', '(is)',),
+            ('not a not in b', '(in)',),
+            ):
+            asm = dis_single(line)
+            self.assert_(elem in asm)
+
+    def test_none_as_constant(self):
+        # LOAD_GLOBAL None  -->  LOAD_CONST None
+        def f(x):
+            None
+            return x
+        asm = disassemble(f)
+        for elem in ('LOAD_GLOBAL',):
+            self.assert_(elem not in asm)
+        for elem in ('LOAD_CONST', '(None)'):
+            self.assert_(elem in asm)
+        def f():
+            'Adding a docstring made this test fail in Py2.5.0'
+            return None
+        self.assert_('LOAD_CONST' in disassemble(f))
+        self.assert_('LOAD_GLOBAL' not in disassemble(f))
+
+    def test_while_one(self):
+        # Skip over:  LOAD_CONST trueconst  JUMP_IF_FALSE xx  POP_TOP
+        def f():
+            while 1:
+                pass
+            return list
+        asm = disassemble(f)
+        for elem in ('LOAD_CONST', 'JUMP_IF_FALSE'):
+            self.assert_(elem not in asm)
+        for elem in ('JUMP_ABSOLUTE',):
+            self.assert_(elem in asm)
+
+    def test_pack_unpack(self):
+        for line, elem in (
+            ('a, = a,', 'LOAD_CONST',),
+            ('a, b = a, b', 'ROT_TWO',),
+            ('a, b, c = a, b, c', 'ROT_THREE',),
+            ):
+            asm = dis_single(line)
+            self.assert_(elem in asm)
+            self.assert_('BUILD_TUPLE' not in asm)
+            self.assert_('UNPACK_TUPLE' not in asm)
+
+    def test_folding_of_tuples_of_constants(self):
+        for line, elem in (
+            ('a = 1,2,3', '((1, 2, 3))'),
+            ('("a","b","c")', "(('a', 'b', 'c'))"),
+            ('a,b,c = 1,2,3', '((1, 2, 3))'),
+            ('(None, 1, None)', '((None, 1, None))'),
+            ('((1, 2), 3, 4)', '(((1, 2), 3, 4))'),
+            ):
+            asm = dis_single(line)
+            self.assert_(elem in asm)
+            self.assert_('BUILD_TUPLE' not in asm)
+
+        # Bug 1053819:  Tuple of constants misidentified when presented with:
+        # . . . opcode_with_arg 100   unary_opcode   BUILD_TUPLE 1  . . .
+        # The following would segfault upon compilation
+        def crater():
+            (~[
+                0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+                0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+                0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+                0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+                0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+                0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+                0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+                0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+                0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+                0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+            ],)
+
+    def test_folding_of_binops_on_constants(self):
+        for line, elem in (
+            ('a = 2+3+4', '(9)'),                   # chained fold
+            ('"@"*4', "('@@@@')"),                  # check string ops
+            ('a="abc" + "def"', "('abcdef')"),      # check string ops
+            ('a = 3**4', '(81)'),                   # binary power
+            ('a = 3*4', '(12)'),                    # binary multiply
+            ('a = 13//4', '(3)'),                   # binary floor divide
+            ('a = 14%4', '(2)'),                    # binary modulo
+            ('a = 2+3', '(5)'),                     # binary add
+            ('a = 13-4', '(9)'),                    # binary subtract
+            ('a = (12,13)[1]', '(13)'),             # binary subscr
+            ('a = 13 << 2', '(52)'),                # binary lshift
+            ('a = 13 >> 2', '(3)'),                 # binary rshift
+            ('a = 13 & 7', '(5)'),                  # binary and
+            ('a = 13 ^ 7', '(10)'),                 # binary xor
+            ('a = 13 | 7', '(15)'),                 # binary or
+            ):
+            asm = dis_single(line)
+            self.assert_(elem in asm, asm)
+            self.assert_('BINARY_' not in asm)
+
+        # Verify that unfoldables are skipped
+        asm = dis_single('a=2+"b"')
+        self.assert_('(2)' in asm)
+        self.assert_("('b')" in asm)
+
+        # Verify that large sequences do not result from folding
+        asm = dis_single('a="x"*1000')
+        self.assert_('(1000)' in asm)
+
+    def test_folding_of_unaryops_on_constants(self):
+        for line, elem in (
+            ('`1`', "('1')"),                       # unary convert
+            ('-0.5', '(-0.5)'),                     # unary negative
+            ('~-2', '(1)'),                         # unary invert
+        ):
+            asm = dis_single(line)
+            self.assert_(elem in asm, asm)
+            self.assert_('UNARY_' not in asm)
+
+        # Verify that unfoldables are skipped
+        for line, elem in (
+            ('-"abc"', "('abc')"),                  # unary negative
+            ('~"abc"', "('abc')"),                  # unary invert
+        ):
+            asm = dis_single(line)
+            self.assert_(elem in asm, asm)
+            self.assert_('UNARY_' in asm)
+
+    def test_elim_extra_return(self):
+        # RETURN LOAD_CONST None RETURN  -->  RETURN
+        def f(x):
+            return x
+        asm = disassemble(f)
+        self.assert_('LOAD_CONST' not in asm)
+        self.assert_('(None)' not in asm)
+        self.assertEqual(asm.split().count('RETURN_VALUE'), 1)
+
+
+
+def test_main(verbose=None):
+    import sys
+    from test import test_support
+    test_classes = (TestTranforms,)
+    test_support.run_unittest(*test_classes)
+
+    # verify reference counting
+    if verbose and hasattr(sys, "gettotalrefcount"):
+        import gc
+        counts = [None] * 5
+        for i in xrange(len(counts)):
+            test_support.run_unittest(*test_classes)
+            gc.collect()
+            counts[i] = sys.gettotalrefcount()
+        print counts
+
+if __name__ == "__main__":
+    test_main(verbose=True)

Added: vendor/Python/current/Lib/test/test_pep247.py
===================================================================
--- vendor/Python/current/Lib/test/test_pep247.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_pep247.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,50 @@
+#
+# Test suite to check compliance with PEP 247, the standard API for
+# hashing algorithms.
+#
+
+import md5, sha, hmac
+
+def check_hash_module(module, key=None):
+    assert hasattr(module, 'digest_size'), "Must have digest_size"
+    assert (module.digest_size is None or
+            module.digest_size > 0), "digest_size must be None or positive"
+
+    if key is not None:
+        obj1 = module.new(key)
+        obj2 = module.new(key, "string")
+
+        h1 = module.new(key, "string").digest()
+        obj3 = module.new(key) ; obj3.update("string") ; h2 = obj3.digest()
+        assert h1 == h2, "Hashes must match"
+
+    else:
+        obj1 = module.new()
+        obj2 = module.new("string")
+
+        h1 = module.new("string").digest()
+        obj3 = module.new() ; obj3.update("string") ; h2 = obj3.digest()
+        assert h1 == h2, "Hashes must match"
+
+    assert hasattr(obj1, 'digest_size'), "Objects must have digest_size attr"
+    if module.digest_size is not None:
+        assert obj1.digest_size == module.digest_size, "digest_size must match"
+    assert obj1.digest_size == len(h1), "digest_size must match actual size"
+    obj1.update("string")
+    obj_copy = obj1.copy()
+    assert obj1.digest() == obj_copy.digest(), "Copied objects must match"
+    assert obj1.hexdigest() == obj_copy.hexdigest(), \
+           "Copied objects must match"
+    digest, hexdigest = obj1.digest(), obj1.hexdigest()
+    hd2 = ""
+    for byte in digest:
+        hd2 += "%02x" % ord(byte)
+    assert hd2 == hexdigest, "hexdigest doesn't appear correct"
+
+    print 'Module', module.__name__, 'seems to comply with PEP 247'
+
+
+if __name__ == '__main__':
+    check_hash_module(md5)
+    check_hash_module(sha)
+    check_hash_module(hmac, key='abc')

Added: vendor/Python/current/Lib/test/test_pep263.py
===================================================================
--- vendor/Python/current/Lib/test/test_pep263.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_pep263.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,23 @@
+#! -*- coding: koi8-r -*-
+# This file is marked as binary in the CVS, to prevent MacCVS from recoding it.
+
+import unittest
+from test import test_support
+
+class PEP263Test(unittest.TestCase):
+
+    def test_pep263(self):
+        self.assertEqual(
+            u"ðÉÔÏÎ".encode("utf-8"),
+            '\xd0\x9f\xd0\xb8\xd1\x82\xd0\xbe\xd0\xbd'
+        )
+        self.assertEqual(
+            u"\ð".encode("utf-8"),
+            '\\\xd0\x9f'
+        )
+
+def test_main():
+    test_support.run_unittest(PEP263Test)
+
+if __name__=="__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_pep277.py
===================================================================
--- vendor/Python/current/Lib/test/test_pep277.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_pep277.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,115 @@
+# Test the Unicode versions of normal file functions
+# open, os.open, os.stat. os.listdir, os.rename, os.remove, os.mkdir, os.chdir, os.rmdir
+import sys, os, unittest
+from test import test_support
+if not os.path.supports_unicode_filenames:
+    raise test_support.TestSkipped, "test works only on NT+"
+
+filenames = [
+    'abc',
+    u'ascii',
+    u'Gr\xfc\xdf-Gott',
+    u'\u0393\u03b5\u03b9\u03ac-\u03c3\u03b1\u03c2',
+    u'\u0417\u0434\u0440\u0430\u0432\u0441\u0442\u0432\u0443\u0439\u0442\u0435',
+    u'\u306b\u307d\u3093',
+    u'\u05d4\u05e9\u05e7\u05e6\u05e5\u05e1',
+    u'\u66e8\u66e9\u66eb',
+    u'\u66e8\u05e9\u3093\u0434\u0393\xdf',
+    ]
+
+# Destroy directory dirname and all files under it, to one level.
+def deltree(dirname):
+    # Don't hide legitimate errors:  if one of these suckers exists, it's
+    # an error if we can't remove it.
+    if os.path.exists(dirname):
+        # must pass unicode to os.listdir() so we get back unicode results.
+        for fname in os.listdir(unicode(dirname)):
+            os.unlink(os.path.join(dirname, fname))
+        os.rmdir(dirname)
+
+class UnicodeFileTests(unittest.TestCase):
+    files = [os.path.join(test_support.TESTFN, f) for f in filenames]
+
+    def setUp(self):
+        try:
+            os.mkdir(test_support.TESTFN)
+        except OSError:
+            pass
+        for name in self.files:
+            f = open(name, 'w')
+            f.write((name+'\n').encode("utf-8"))
+            f.close()
+            os.stat(name)
+
+    def tearDown(self):
+        deltree(test_support.TESTFN)
+
+    def _apply_failure(self, fn, filename, expected_exception,
+                       check_fn_in_exception = True):
+        try:
+            fn(filename)
+            raise test_support.TestFailed("Expected to fail calling '%s(%r)'"
+                             % (fn.__name__, filename))
+        except expected_exception, details:
+            if check_fn_in_exception and details.filename != filename:
+                raise test_support.TestFailed("Function '%s(%r) failed with "
+                                 "bad filename in the exception: %r"
+                                 % (fn.__name__, filename,
+                                    details.filename))
+
+    def test_failures(self):
+        # Pass non-existing Unicode filenames all over the place.
+        for name in self.files:
+            name = "not_" + name
+            self._apply_failure(open, name, IOError)
+            self._apply_failure(os.stat, name, OSError)
+            self._apply_failure(os.chdir, name, OSError)
+            self._apply_failure(os.rmdir, name, OSError)
+            self._apply_failure(os.remove, name, OSError)
+            # listdir may append a wildcard to the filename, so dont check
+            self._apply_failure(os.listdir, name, OSError, False)
+
+    def test_open(self):
+        for name in self.files:
+            f = open(name, 'w')
+            f.write((name+'\n').encode("utf-8"))
+            f.close()
+            os.stat(name)
+
+    def test_listdir(self):
+        f1 = os.listdir(test_support.TESTFN)
+        # Printing f1 is not appropriate, as specific filenames
+        # returned depend on the local encoding
+        f2 = os.listdir(unicode(test_support.TESTFN,
+                                sys.getfilesystemencoding()))
+        f2.sort()
+        print f2
+
+    def test_rename(self):
+        for name in self.files:
+            os.rename(name,"tmp")
+            os.rename("tmp",name)
+
+    def test_directory(self):
+        dirname = os.path.join(test_support.TESTFN,u'Gr\xfc\xdf-\u66e8\u66e9\u66eb')
+        filename = u'\xdf-\u66e8\u66e9\u66eb'
+        oldwd = os.getcwd()
+        os.mkdir(dirname)
+        os.chdir(dirname)
+        f = open(filename, 'w')
+        f.write((filename + '\n').encode("utf-8"))
+        f.close()
+        print repr(filename)
+        os.access(filename,os.R_OK)
+        os.remove(filename)
+        os.chdir(oldwd)
+        os.rmdir(dirname)
+
+def test_main():
+    try:
+        test_support.run_unittest(UnicodeFileTests)
+    finally:
+        deltree(test_support.TESTFN)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_pep292.py
===================================================================
--- vendor/Python/current/Lib/test/test_pep292.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_pep292.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,194 @@
+# Copyright (C) 2004 Python Software Foundation
+# Author: barry at python.org (Barry Warsaw)
+# License: http://www.opensource.org/licenses/PythonSoftFoundation.php
+
+import unittest
+from string import Template
+
+
+class Bag:
+    pass
+
+class Mapping:
+    def __getitem__(self, name):
+        obj = self
+        for part in name.split('.'):
+            try:
+                obj = getattr(obj, part)
+            except AttributeError:
+                raise KeyError(name)
+        return obj
+
+
+class TestTemplate(unittest.TestCase):
+    def test_regular_templates(self):
+        s = Template('$who likes to eat a bag of $what worth $$100')
+        self.assertEqual(s.substitute(dict(who='tim', what='ham')),
+                         'tim likes to eat a bag of ham worth $100')
+        self.assertRaises(KeyError, s.substitute, dict(who='tim'))
+
+    def test_regular_templates_with_braces(self):
+        s = Template('$who likes ${what} for ${meal}')
+        d = dict(who='tim', what='ham', meal='dinner')
+        self.assertEqual(s.substitute(d), 'tim likes ham for dinner')
+        self.assertRaises(KeyError, s.substitute,
+                          dict(who='tim', what='ham'))
+
+    def test_escapes(self):
+        eq = self.assertEqual
+        s = Template('$who likes to eat a bag of $$what worth $$100')
+        eq(s.substitute(dict(who='tim', what='ham')),
+           'tim likes to eat a bag of $what worth $100')
+        s = Template('$who likes $$')
+        eq(s.substitute(dict(who='tim', what='ham')), 'tim likes $')
+
+    def test_percents(self):
+        eq = self.assertEqual
+        s = Template('%(foo)s $foo ${foo}')
+        d = dict(foo='baz')
+        eq(s.substitute(d), '%(foo)s baz baz')
+        eq(s.safe_substitute(d), '%(foo)s baz baz')
+
+    def test_stringification(self):
+        eq = self.assertEqual
+        s = Template('tim has eaten $count bags of ham today')
+        d = dict(count=7)
+        eq(s.substitute(d), 'tim has eaten 7 bags of ham today')
+        eq(s.safe_substitute(d), 'tim has eaten 7 bags of ham today')
+        s = Template('tim has eaten ${count} bags of ham today')
+        eq(s.substitute(d), 'tim has eaten 7 bags of ham today')
+
+    def test_tupleargs(self):
+        eq = self.assertEqual
+        s = Template('$who ate ${meal}')
+        d = dict(who=('tim', 'fred'), meal=('ham', 'kung pao'))
+        eq(s.substitute(d), "('tim', 'fred') ate ('ham', 'kung pao')")
+        eq(s.safe_substitute(d), "('tim', 'fred') ate ('ham', 'kung pao')")
+
+    def test_SafeTemplate(self):
+        eq = self.assertEqual
+        s = Template('$who likes ${what} for ${meal}')
+        eq(s.safe_substitute(dict(who='tim')), 'tim likes ${what} for ${meal}')
+        eq(s.safe_substitute(dict(what='ham')), '$who likes ham for ${meal}')
+        eq(s.safe_substitute(dict(what='ham', meal='dinner')),
+           '$who likes ham for dinner')
+        eq(s.safe_substitute(dict(who='tim', what='ham')),
+           'tim likes ham for ${meal}')
+        eq(s.safe_substitute(dict(who='tim', what='ham', meal='dinner')),
+           'tim likes ham for dinner')
+
+    def test_invalid_placeholders(self):
+        raises = self.assertRaises
+        s = Template('$who likes $')
+        raises(ValueError, s.substitute, dict(who='tim'))
+        s = Template('$who likes ${what)')
+        raises(ValueError, s.substitute, dict(who='tim'))
+        s = Template('$who likes $100')
+        raises(ValueError, s.substitute, dict(who='tim'))
+
+    def test_delimiter_override(self):
+        class PieDelims(Template):
+            delimiter = '@'
+        s = PieDelims('@who likes to eat a bag of @{what} worth $100')
+        self.assertEqual(s.substitute(dict(who='tim', what='ham')),
+                         'tim likes to eat a bag of ham worth $100')
+
+    def test_idpattern_override(self):
+        class PathPattern(Template):
+            idpattern = r'[_a-z][._a-z0-9]*'
+        m = Mapping()
+        m.bag = Bag()
+        m.bag.foo = Bag()
+        m.bag.foo.who = 'tim'
+        m.bag.what = 'ham'
+        s = PathPattern('$bag.foo.who likes to eat a bag of $bag.what')
+        self.assertEqual(s.substitute(m), 'tim likes to eat a bag of ham')
+
+    def test_pattern_override(self):
+        class MyPattern(Template):
+            pattern = r"""
+            (?P<escaped>@{2})                   |
+            @(?P<named>[_a-z][._a-z0-9]*)       |
+            @{(?P<braced>[_a-z][._a-z0-9]*)}    |
+            (?P<invalid>@)
+            """
+        m = Mapping()
+        m.bag = Bag()
+        m.bag.foo = Bag()
+        m.bag.foo.who = 'tim'
+        m.bag.what = 'ham'
+        s = MyPattern('@bag.foo.who likes to eat a bag of @bag.what')
+        self.assertEqual(s.substitute(m), 'tim likes to eat a bag of ham')
+
+        class BadPattern(Template):
+            pattern = r"""
+            (?P<badname>.*)                     |
+            (?P<escaped>@{2})                   |
+            @(?P<named>[_a-z][._a-z0-9]*)       |
+            @{(?P<braced>[_a-z][._a-z0-9]*)}    |
+            (?P<invalid>@)                      |
+            """
+        s = BadPattern('@bag.foo.who likes to eat a bag of @bag.what')
+        self.assertRaises(ValueError, s.substitute, {})
+        self.assertRaises(ValueError, s.safe_substitute, {})
+
+    def test_unicode_values(self):
+        s = Template('$who likes $what')
+        d = dict(who=u't\xffm', what=u'f\xfe\fed')
+        self.assertEqual(s.substitute(d), u't\xffm likes f\xfe\x0ced')
+
+    def test_keyword_arguments(self):
+        eq = self.assertEqual
+        s = Template('$who likes $what')
+        eq(s.substitute(who='tim', what='ham'), 'tim likes ham')
+        eq(s.substitute(dict(who='tim'), what='ham'), 'tim likes ham')
+        eq(s.substitute(dict(who='fred', what='kung pao'),
+                        who='tim', what='ham'),
+           'tim likes ham')
+        s = Template('the mapping is $mapping')
+        eq(s.substitute(dict(foo='none'), mapping='bozo'),
+           'the mapping is bozo')
+        eq(s.substitute(dict(mapping='one'), mapping='two'),
+           'the mapping is two')
+
+    def test_keyword_arguments_safe(self):
+        eq = self.assertEqual
+        raises = self.assertRaises
+        s = Template('$who likes $what')
+        eq(s.safe_substitute(who='tim', what='ham'), 'tim likes ham')
+        eq(s.safe_substitute(dict(who='tim'), what='ham'), 'tim likes ham')
+        eq(s.safe_substitute(dict(who='fred', what='kung pao'),
+                        who='tim', what='ham'),
+           'tim likes ham')
+        s = Template('the mapping is $mapping')
+        eq(s.safe_substitute(dict(foo='none'), mapping='bozo'),
+           'the mapping is bozo')
+        eq(s.safe_substitute(dict(mapping='one'), mapping='two'),
+           'the mapping is two')
+        d = dict(mapping='one')
+        raises(TypeError, s.substitute, d, {})
+        raises(TypeError, s.safe_substitute, d, {})
+
+    def test_delimiter_override(self):
+        eq = self.assertEqual
+        raises = self.assertRaises
+        class AmpersandTemplate(Template):
+            delimiter = '&'
+        s = AmpersandTemplate('this &gift is for &{who} &&')
+        eq(s.substitute(gift='bud', who='you'), 'this bud is for you &')
+        raises(KeyError, s.substitute)
+        eq(s.safe_substitute(gift='bud', who='you'), 'this bud is for you &')
+        eq(s.safe_substitute(), 'this &gift is for &{who} &')
+        s = AmpersandTemplate('this &gift is for &{who} &')
+        raises(ValueError, s.substitute, dict(gift='bud', who='you'))
+        eq(s.safe_substitute(), 'this &gift is for &{who} &')
+
+
+def test_main():
+    from test import test_support
+    test_classes = [TestTemplate,]
+    test_support.run_unittest(*test_classes)
+
+
+if __name__ == '__main__':
+    test_main()

Added: vendor/Python/current/Lib/test/test_pep352.py
===================================================================
--- vendor/Python/current/Lib/test/test_pep352.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_pep352.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,182 @@
+import unittest
+import __builtin__
+import exceptions
+import warnings
+from test.test_support import run_unittest
+import os
+from platform import system as platform_system
+
+class ExceptionClassTests(unittest.TestCase):
+
+    """Tests for anything relating to exception objects themselves (e.g.,
+    inheritance hierarchy)"""
+
+    def test_builtins_new_style(self):
+        self.failUnless(issubclass(Exception, object))
+
+    def verify_instance_interface(self, ins):
+        for attr in ("args", "message", "__str__", "__repr__", "__getitem__"):
+            self.failUnless(hasattr(ins, attr), "%s missing %s attribute" %
+                    (ins.__class__.__name__, attr))
+
+    def test_inheritance(self):
+        # Make sure the inheritance hierarchy matches the documentation
+        exc_set = set(x for x in dir(exceptions) if not x.startswith('_'))
+        inheritance_tree = open(os.path.join(os.path.split(__file__)[0],
+                                                'exception_hierarchy.txt'))
+        try:
+            superclass_name = inheritance_tree.readline().rstrip()
+            try:
+                last_exc = getattr(__builtin__, superclass_name)
+            except AttributeError:
+                self.fail("base class %s not a built-in" % superclass_name)
+            self.failUnless(superclass_name in exc_set)
+            exc_set.discard(superclass_name)
+            superclasses = []  # Loop will insert base exception
+            last_depth = 0
+            for exc_line in inheritance_tree:
+                exc_line = exc_line.rstrip()
+                depth = exc_line.rindex('-')
+                exc_name = exc_line[depth+2:]  # Slice past space
+                if '(' in exc_name:
+                    paren_index = exc_name.index('(')
+                    platform_name = exc_name[paren_index+1:-1]
+                    exc_name = exc_name[:paren_index-1]  # Slice off space
+                    if platform_system() != platform_name:
+                        exc_set.discard(exc_name)
+                        continue
+                if '[' in exc_name:
+                    left_bracket = exc_name.index('[')
+                    exc_name = exc_name[:left_bracket-1]  # cover space
+                try:
+                    exc = getattr(__builtin__, exc_name)
+                except AttributeError:
+                    self.fail("%s not a built-in exception" % exc_name)
+                if last_depth < depth:
+                    superclasses.append((last_depth, last_exc))
+                elif last_depth > depth:
+                    while superclasses[-1][0] >= depth:
+                        superclasses.pop()
+                self.failUnless(issubclass(exc, superclasses[-1][1]),
+                "%s is not a subclass of %s" % (exc.__name__,
+                    superclasses[-1][1].__name__))
+                try:  # Some exceptions require arguments; just skip them
+                    self.verify_instance_interface(exc())
+                except TypeError:
+                    pass
+                self.failUnless(exc_name in exc_set)
+                exc_set.discard(exc_name)
+                last_exc = exc
+                last_depth = depth
+        finally:
+            inheritance_tree.close()
+        self.failUnlessEqual(len(exc_set), 0, "%s not accounted for" % exc_set)
+
+    interface_tests = ("length", "args", "message", "str", "unicode", "repr",
+            "indexing")
+
+    def interface_test_driver(self, results):
+        for test_name, (given, expected) in zip(self.interface_tests, results):
+            self.failUnlessEqual(given, expected, "%s: %s != %s" % (test_name,
+                given, expected))
+
+    def test_interface_single_arg(self):
+        # Make sure interface works properly when given a single argument
+        arg = "spam"
+        exc = Exception(arg)
+        results = ([len(exc.args), 1], [exc.args[0], arg], [exc.message, arg],
+                [str(exc), str(arg)], [unicode(exc), unicode(arg)],
+            [repr(exc), exc.__class__.__name__ + repr(exc.args)], [exc[0], arg])
+        self.interface_test_driver(results)
+
+    def test_interface_multi_arg(self):
+        # Make sure interface correct when multiple arguments given
+        arg_count = 3
+        args = tuple(range(arg_count))
+        exc = Exception(*args)
+        results = ([len(exc.args), arg_count], [exc.args, args],
+                [exc.message, ''], [str(exc), str(args)],
+                [unicode(exc), unicode(args)],
+                [repr(exc), exc.__class__.__name__ + repr(exc.args)],
+                [exc[-1], args[-1]])
+        self.interface_test_driver(results)
+
+    def test_interface_no_arg(self):
+        # Make sure that with no args that interface is correct
+        exc = Exception()
+        results = ([len(exc.args), 0], [exc.args, tuple()], [exc.message, ''],
+                [str(exc), ''], [unicode(exc), u''],
+                [repr(exc), exc.__class__.__name__ + '()'], [True, True])
+        self.interface_test_driver(results)
+
+class UsageTests(unittest.TestCase):
+
+    """Test usage of exceptions"""
+
+    def setUp(self):
+        self._filters = warnings.filters[:]
+
+    def tearDown(self):
+        warnings.filters = self._filters[:]
+
+    def test_raise_classic(self):
+        class ClassicClass:
+            pass
+        try:
+            raise ClassicClass
+        except ClassicClass:
+            pass
+        except:
+            self.fail("unable to raise classic class")
+        try:
+            raise ClassicClass()
+        except ClassicClass:
+            pass
+        except:
+            self.fail("unable to raise class class instance")
+
+    def test_raise_new_style_non_exception(self):
+        class NewStyleClass(object):
+            pass
+        try:
+            raise NewStyleClass
+        except TypeError:
+            pass
+        except:
+            self.fail("unable to raise new-style class")
+        try:
+            raise NewStyleClass()
+        except TypeError:
+            pass
+        except:
+            self.fail("unable to raise new-style class instance")
+
+    def test_raise_string(self):
+        warnings.resetwarnings()
+        warnings.filterwarnings("error")
+        try:
+            raise "spam"
+        except DeprecationWarning:
+            pass
+        except:
+            self.fail("raising a string did not cause a DeprecationWarning")
+
+    def test_catch_string(self):
+        # Test will be pertinent when catching exceptions raises a
+        #   DeprecationWarning
+        warnings.filterwarnings("ignore", "raising")
+        str_exc = "spam"
+        try:
+            raise str_exc
+        except str_exc:
+            pass
+        except:
+            self.fail("catching a string exception failed")
+
+def test_main():
+    run_unittest(ExceptionClassTests, UsageTests)
+
+
+
+if __name__ == '__main__':
+    test_main()

Added: vendor/Python/current/Lib/test/test_pickle.py
===================================================================
--- vendor/Python/current/Lib/test/test_pickle.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_pickle.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,73 @@
+import pickle
+import unittest
+from cStringIO import StringIO
+
+from test import test_support
+
+from test.pickletester import AbstractPickleTests
+from test.pickletester import AbstractPickleModuleTests
+from test.pickletester import AbstractPersistentPicklerTests
+
+class PickleTests(AbstractPickleTests, AbstractPickleModuleTests):
+
+    def dumps(self, arg, proto=0, fast=0):
+        # Ignore fast
+        return pickle.dumps(arg, proto)
+
+    def loads(self, buf):
+        # Ignore fast
+        return pickle.loads(buf)
+
+    module = pickle
+    error = KeyError
+
+class PicklerTests(AbstractPickleTests):
+
+    error = KeyError
+
+    def dumps(self, arg, proto=0, fast=0):
+        f = StringIO()
+        p = pickle.Pickler(f, proto)
+        if fast:
+            p.fast = fast
+        p.dump(arg)
+        f.seek(0)
+        return f.read()
+
+    def loads(self, buf):
+        f = StringIO(buf)
+        u = pickle.Unpickler(f)
+        return u.load()
+
+class PersPicklerTests(AbstractPersistentPicklerTests):
+
+    def dumps(self, arg, proto=0, fast=0):
+        class PersPickler(pickle.Pickler):
+            def persistent_id(subself, obj):
+                return self.persistent_id(obj)
+        f = StringIO()
+        p = PersPickler(f, proto)
+        if fast:
+            p.fast = fast
+        p.dump(arg)
+        f.seek(0)
+        return f.read()
+
+    def loads(self, buf):
+        class PersUnpickler(pickle.Unpickler):
+            def persistent_load(subself, obj):
+                return self.persistent_load(obj)
+        f = StringIO(buf)
+        u = PersUnpickler(f)
+        return u.load()
+
+def test_main():
+    test_support.run_unittest(
+        PickleTests,
+        PicklerTests,
+        PersPicklerTests
+    )
+    test_support.run_doctest(pickle)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_pickletools.py
===================================================================
--- vendor/Python/current/Lib/test/test_pickletools.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_pickletools.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,3 @@
+import pickletools
+from test import test_support
+test_support.run_doctest(pickletools)

Added: vendor/Python/current/Lib/test/test_pkg.py
===================================================================
--- vendor/Python/current/Lib/test/test_pkg.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_pkg.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,259 @@
+# Test packages (dotted-name import)
+
+import sys, os, tempfile, traceback
+from os import mkdir, rmdir, extsep          # Can't test if these fail
+del mkdir, rmdir
+from test.test_support import verify, verbose, TestFailed
+
+# Helpers to create and destroy hierarchies.
+
+def mkhier(root, descr):
+    if not os.path.isdir(root):
+        mkdir(root)
+    for name, contents in descr:
+        comps = name.split()
+        fullname = root
+        for c in comps:
+            fullname = os.path.join(fullname, c)
+        if contents is None:
+            mkdir(fullname)
+        else:
+            if verbose: print "write", fullname
+            f = open(fullname, "w")
+            f.write(contents)
+            if contents and contents[-1] != '\n':
+                f.write('\n')
+            f.close()
+
+def mkdir(x):
+    if verbose: print "mkdir", x
+    os.mkdir(x)
+
+def cleanout(root):
+    names = os.listdir(root)
+    for name in names:
+        fullname = os.path.join(root, name)
+        if os.path.isdir(fullname) and not os.path.islink(fullname):
+            cleanout(fullname)
+        else:
+            os.remove(fullname)
+    rmdir(root)
+
+def rmdir(x):
+    if verbose: print "rmdir", x
+    os.rmdir(x)
+
+def fixdir(lst):
+    try:
+        lst.remove('__builtins__')
+    except ValueError:
+        pass
+    return lst
+
+# Helper to run a test
+
+def runtest(hier, code):
+    root = tempfile.mkdtemp()
+    mkhier(root, hier)
+    savepath = sys.path[:]
+    fd, fname = tempfile.mkstemp(text=True)
+    os.write(fd, code)
+    os.close(fd)
+    try:
+        sys.path.insert(0, root)
+        if verbose: print "sys.path =", sys.path
+        try:
+            execfile(fname, globals(), {})
+        except:
+            traceback.print_exc(file=sys.stdout)
+    finally:
+        sys.path[:] = savepath
+        os.unlink(fname)
+        try:
+            cleanout(root)
+        except (os.error, IOError):
+            pass
+
+# Test descriptions
+
+tests = [
+    ("t1", [("t1", None), ("t1 __init__"+os.extsep+"py", "")], "import t1"),
+
+    ("t2", [
+    ("t2", None),
+    ("t2 __init__"+os.extsep+"py", "'doc for t2'; print __name__, 'loading'"),
+    ("t2 sub", None),
+    ("t2 sub __init__"+os.extsep+"py", ""),
+    ("t2 sub subsub", None),
+    ("t2 sub subsub __init__"+os.extsep+"py", "print __name__, 'loading'; spam = 1"),
+    ],
+"""
+import t2
+print t2.__doc__
+import t2.sub
+import t2.sub.subsub
+print t2.__name__, t2.sub.__name__, t2.sub.subsub.__name__
+import t2
+from t2 import *
+print dir()
+from t2 import sub
+from t2.sub import subsub
+from t2.sub.subsub import spam
+print sub.__name__, subsub.__name__
+print sub.subsub.__name__
+print dir()
+import t2.sub
+import t2.sub.subsub
+print t2.__name__, t2.sub.__name__, t2.sub.subsub.__name__
+from t2 import *
+print dir()
+"""),
+
+    ("t3", [
+    ("t3", None),
+    ("t3 __init__"+os.extsep+"py", "print __name__, 'loading'"),
+    ("t3 sub", None),
+    ("t3 sub __init__"+os.extsep+"py", ""),
+    ("t3 sub subsub", None),
+    ("t3 sub subsub __init__"+os.extsep+"py", "print __name__, 'loading'; spam = 1"),
+    ],
+"""
+import t3.sub.subsub
+print t3.__name__, t3.sub.__name__, t3.sub.subsub.__name__
+reload(t3)
+reload(t3.sub)
+reload(t3.sub.subsub)
+"""),
+
+    ("t4", [
+    ("t4"+os.extsep+"py", "print 'THIS SHOULD NOT BE PRINTED (t4"+os.extsep+"py)'"),
+    ("t4", None),
+    ("t4 __init__"+os.extsep+"py", "print __name__, 'loading'"),
+    ("t4 sub"+os.extsep+"py", "print 'THIS SHOULD NOT BE PRINTED (sub"+os.extsep+"py)'"),
+    ("t4 sub", None),
+    ("t4 sub __init__"+os.extsep+"py", ""),
+    ("t4 sub subsub"+os.extsep+"py", "print 'THIS SHOULD NOT BE PRINTED (subsub"+os.extsep+"py)'"),
+    ("t4 sub subsub", None),
+    ("t4 sub subsub __init__"+os.extsep+"py", "print __name__, 'loading'; spam = 1"),
+    ],
+"""
+from t4.sub.subsub import *
+print "t4.sub.subsub.spam =", spam
+"""),
+
+    ("t5", [
+    ("t5", None),
+    ("t5 __init__"+os.extsep+"py", "import t5.foo"),
+    ("t5 string"+os.extsep+"py", "print __name__, 'loading'; spam = 1"),
+    ("t5 foo"+os.extsep+"py",
+     "print __name__, 'loading'; import string; print string.spam"),
+     ],
+"""
+import t5
+from t5 import *
+print dir()
+import t5
+print fixdir(dir(t5))
+print fixdir(dir(t5.foo))
+print fixdir(dir(t5.string))
+"""),
+
+    ("t6", [
+    ("t6", None),
+    ("t6 __init__"+os.extsep+"py", "__all__ = ['spam', 'ham', 'eggs']"),
+    ("t6 spam"+os.extsep+"py", "print __name__, 'loading'"),
+    ("t6 ham"+os.extsep+"py", "print __name__, 'loading'"),
+    ("t6 eggs"+os.extsep+"py", "print __name__, 'loading'"),
+    ],
+"""
+import t6
+print fixdir(dir(t6))
+from t6 import *
+print fixdir(dir(t6))
+print dir()
+"""),
+
+    ("t7", [
+    ("t7"+os.extsep+"py", "print 'Importing t7"+os.extsep+"py'"),
+    ("t7", None),
+    ("t7 __init__"+os.extsep+"py", "print __name__, 'loading'"),
+    ("t7 sub"+os.extsep+"py", "print 'THIS SHOULD NOT BE PRINTED (sub"+os.extsep+"py)'"),
+    ("t7 sub", None),
+    ("t7 sub __init__"+os.extsep+"py", ""),
+    ("t7 sub subsub"+os.extsep+"py", "print 'THIS SHOULD NOT BE PRINTED (subsub"+os.extsep+"py)'"),
+    ("t7 sub subsub", None),
+    ("t7 sub subsub __init__"+os.extsep+"py", "print __name__, 'loading'; spam = 1"),
+    ],
+"""
+t7, sub, subsub = None, None, None
+import t7 as tas
+print fixdir(dir(tas))
+verify(not t7)
+from t7 import sub as subpar
+print fixdir(dir(subpar))
+verify(not t7 and not sub)
+from t7.sub import subsub as subsubsub
+print fixdir(dir(subsubsub))
+verify(not t7 and not sub and not subsub)
+from t7.sub.subsub import spam as ham
+print "t7.sub.subsub.spam =", ham
+verify(not t7 and not sub and not subsub)
+"""),
+
+]
+
+nontests = [
+    ("x5", [], ("import a" + ".a"*400)),
+    ("x6", [], ("import a" + ".a"*499)),
+    ("x7", [], ("import a" + ".a"*500)),
+    ("x8", [], ("import a" + ".a"*1100)),
+    ("x9", [], ("import " + "a"*400)),
+    ("x10", [], ("import " + "a"*500)),
+    ("x11", [], ("import " + "a"*998)),
+    ("x12", [], ("import " + "a"*999)),
+    ("x13", [], ("import " + "a"*999)),
+    ("x14", [], ("import " + "a"*2000)),
+]
+
+"""XXX Things to test
+
+import package without __init__
+import package with __init__
+__init__ importing submodule
+__init__ importing global module
+__init__ defining variables
+submodule importing other submodule
+submodule importing global module
+submodule import submodule via global name
+from package import submodule
+from package import subpackage
+from package import variable (defined in __init__)
+from package import * (defined in __init__)
+"""
+
+# Run the tests
+
+args = []
+if __name__ == '__main__':
+    args = sys.argv[1:]
+    if args and args[0] == '-q':
+        verbose = 0
+        del args[0]
+
+for name, hier, code in tests:
+    if args and name not in args:
+        print "skipping test", name
+        continue
+    print "running test", name
+    runtest(hier, code)
+
+# Test
+import sys
+import imp
+try:
+    import sys.imp
+except ImportError:
+    # This is what we expect
+    pass
+else:
+    raise TestFailed, "No ImportError exception on 'import sys.imp'"

Added: vendor/Python/current/Lib/test/test_pkgimport.py
===================================================================
--- vendor/Python/current/Lib/test/test_pkgimport.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_pkgimport.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,82 @@
+import os, sys, string, random, tempfile, unittest
+
+from test.test_support import run_unittest
+
+class TestImport(unittest.TestCase):
+
+    def __init__(self, *args, **kw):
+        self.package_name = 'PACKAGE_'
+        while sys.modules.has_key(self.package_name):
+            self.package_name += random.choose(string.letters)
+        self.module_name = self.package_name + '.foo'
+        unittest.TestCase.__init__(self, *args, **kw)
+
+    def remove_modules(self):
+        for module_name in (self.package_name, self.module_name):
+            if sys.modules.has_key(module_name):
+                del sys.modules[module_name]
+
+    def setUp(self):
+        self.test_dir = tempfile.mkdtemp()
+        sys.path.append(self.test_dir)
+        self.package_dir = os.path.join(self.test_dir,
+                                        self.package_name)
+        os.mkdir(self.package_dir)
+        open(os.path.join(self.package_dir, '__init__'+os.extsep+'py'), 'w')
+        self.module_path = os.path.join(self.package_dir, 'foo'+os.extsep+'py')
+
+    def tearDown(self):
+        for file in os.listdir(self.package_dir):
+            os.remove(os.path.join(self.package_dir, file))
+        os.rmdir(self.package_dir)
+        os.rmdir(self.test_dir)
+        self.assertNotEqual(sys.path.count(self.test_dir), 0)
+        sys.path.remove(self.test_dir)
+        self.remove_modules()
+
+    def rewrite_file(self, contents):
+        for extension in "co":
+            compiled_path = self.module_path + extension
+            if os.path.exists(compiled_path):
+                os.remove(compiled_path)
+        f = open(self.module_path, 'w')
+        f.write(contents)
+        f.close()
+
+    def test_package_import__semantics(self):
+
+        # Generate a couple of broken modules to try importing.
+
+        # ...try loading the module when there's a SyntaxError
+        self.rewrite_file('for')
+        try: __import__(self.module_name)
+        except SyntaxError: pass
+        else: raise RuntimeError, 'Failed to induce SyntaxError'
+        self.assert_(not sys.modules.has_key(self.module_name) and
+                     not hasattr(sys.modules[self.package_name], 'foo'))
+
+        # ...make up a variable name that isn't bound in __builtins__
+        var = 'a'
+        while var in dir(__builtins__):
+            var += random.choose(string.letters)
+
+        # ...make a module that just contains that
+        self.rewrite_file(var)
+
+        try: __import__(self.module_name)
+        except NameError: pass
+        else: raise RuntimeError, 'Failed to induce NameError.'
+
+        # ...now  change  the module  so  that  the NameError  doesn't
+        # happen
+        self.rewrite_file('%s = 1' % var)
+        module = __import__(self.module_name).foo
+        self.assertEqual(getattr(module, var), 1)
+
+
+def test_main():
+    run_unittest(TestImport)
+
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_platform.py
===================================================================
--- vendor/Python/current/Lib/test/test_platform.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_platform.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,79 @@
+import unittest
+from test import test_support
+import platform
+
+class PlatformTest(unittest.TestCase):
+    def test_architecture(self):
+        res = platform.architecture()
+
+    def test_machine(self):
+        res = platform.machine()
+
+    def test_node(self):
+        res = platform.node()
+
+    def test_platform(self):
+        for aliased in (False, True):
+            for terse in (False, True):
+                res = platform.platform(aliased, terse)
+
+    def test_processor(self):
+        res = platform.processor()
+
+    def test_python_build(self):
+        res = platform.python_build()
+
+    def test_python_compiler(self):
+        res = platform.python_compiler()
+
+    def test_version(self):
+        res1 = platform.version()
+        res2 = platform.version_tuple()
+        self.assertEqual(res1, ".".join(res2))
+
+    def test_release(self):
+        res = platform.release()
+
+    def test_system(self):
+        res = platform.system()
+
+    def test_version(self):
+        res = platform.version()
+
+    def test_system_alias(self):
+        res = platform.system_alias(
+            platform.system(),
+            platform.release(),
+            platform.version(),
+        )
+
+    def test_uname(self):
+        res = platform.uname()
+
+    def test_java_ver(self):
+        res = platform.java_ver()
+
+    def test_win32_ver(self):
+        res = platform.win32_ver()
+
+    def test_mac_ver(self):
+        res = platform.mac_ver()
+
+    def test_dist(self):
+        res = platform.dist()
+
+    def test_libc_ver(self):
+        from sys import executable
+        import os
+        if os.path.isdir(executable) and os.path.exists(executable+'.exe'):
+            # Cygwin horror
+            executable = executable + '.exe'
+        res = platform.libc_ver(executable)
+
+def test_main():
+    test_support.run_unittest(
+        PlatformTest
+    )
+
+if __name__ == '__main__':
+    test_main()

Added: vendor/Python/current/Lib/test/test_plistlib.py
===================================================================
--- vendor/Python/current/Lib/test/test_plistlib.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_plistlib.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,193 @@
+# Copyright (C) 2003 Python Software Foundation
+
+import unittest
+import plistlib
+import os
+import time
+import datetime
+from test import test_support
+
+
+# This test data was generated through Cocoa's NSDictionary class
+TESTDATA = """<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" \
+"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+        <key>aDate</key>
+        <date>2004-10-26T10:33:33Z</date>
+        <key>aDict</key>
+        <dict>
+                <key>aFalseValue</key>
+                <false/>
+                <key>aTrueValue</key>
+                <true/>
+                <key>aUnicodeValue</key>
+                <string>M\xc3\xa4ssig, Ma\xc3\x9f</string>
+                <key>anotherString</key>
+                <string>&lt;hello &amp; 'hi' there!&gt;</string>
+                <key>deeperDict</key>
+                <dict>
+                        <key>a</key>
+                        <integer>17</integer>
+                        <key>b</key>
+                        <real>32.5</real>
+                        <key>c</key>
+                        <array>
+                                <integer>1</integer>
+                                <integer>2</integer>
+                                <string>text</string>
+                        </array>
+                </dict>
+        </dict>
+        <key>aFloat</key>
+        <real>0.5</real>
+        <key>aList</key>
+        <array>
+                <string>A</string>
+                <string>B</string>
+                <integer>12</integer>
+                <real>32.5</real>
+                <array>
+                        <integer>1</integer>
+                        <integer>2</integer>
+                        <integer>3</integer>
+                </array>
+        </array>
+        <key>aString</key>
+        <string>Doodah</string>
+        <key>anInt</key>
+        <integer>728</integer>
+        <key>nestedData</key>
+        <array>
+                <data>
+                PGxvdHMgb2YgYmluYXJ5IGd1bms+AAECAzxsb3RzIG9mIGJpbmFyeSBndW5r
+                PgABAgM8bG90cyBvZiBiaW5hcnkgZ3Vuaz4AAQIDPGxvdHMgb2YgYmluYXJ5
+                IGd1bms+AAECAzxsb3RzIG9mIGJpbmFyeSBndW5rPgABAgM8bG90cyBvZiBi
+                aW5hcnkgZ3Vuaz4AAQIDPGxvdHMgb2YgYmluYXJ5IGd1bms+AAECAzxsb3Rz
+                IG9mIGJpbmFyeSBndW5rPgABAgM8bG90cyBvZiBiaW5hcnkgZ3Vuaz4AAQID
+                PGxvdHMgb2YgYmluYXJ5IGd1bms+AAECAw==
+                </data>
+        </array>
+        <key>someData</key>
+        <data>
+        PGJpbmFyeSBndW5rPg==
+        </data>
+        <key>someMoreData</key>
+        <data>
+        PGxvdHMgb2YgYmluYXJ5IGd1bms+AAECAzxsb3RzIG9mIGJpbmFyeSBndW5rPgABAgM8
+        bG90cyBvZiBiaW5hcnkgZ3Vuaz4AAQIDPGxvdHMgb2YgYmluYXJ5IGd1bms+AAECAzxs
+        b3RzIG9mIGJpbmFyeSBndW5rPgABAgM8bG90cyBvZiBiaW5hcnkgZ3Vuaz4AAQIDPGxv
+        dHMgb2YgYmluYXJ5IGd1bms+AAECAzxsb3RzIG9mIGJpbmFyeSBndW5rPgABAgM8bG90
+        cyBvZiBiaW5hcnkgZ3Vuaz4AAQIDPGxvdHMgb2YgYmluYXJ5IGd1bms+AAECAw==
+        </data>
+        <key>\xc3\x85benraa</key>
+        <string>That was a unicode key.</string>
+</dict>
+</plist>
+""".replace(" " * 8, "\t")  # Apple as well as plistlib.py output hard tabs
+
+
+class TestPlistlib(unittest.TestCase):
+
+    def tearDown(self):
+        try:
+            os.unlink(test_support.TESTFN)
+        except:
+            pass
+
+    def _create(self):
+        pl = dict(
+            aString="Doodah",
+            aList=["A", "B", 12, 32.5, [1, 2, 3]],
+            aFloat = 0.5,
+            anInt = 728,
+            aDict=dict(
+                anotherString="<hello & 'hi' there!>",
+                aUnicodeValue=u'M\xe4ssig, Ma\xdf',
+                aTrueValue=True,
+                aFalseValue=False,
+                deeperDict=dict(a=17, b=32.5, c=[1, 2, "text"]),
+            ),
+            someData = plistlib.Data("<binary gunk>"),
+            someMoreData = plistlib.Data("<lots of binary gunk>\0\1\2\3" * 10),
+            nestedData = [plistlib.Data("<lots of binary gunk>\0\1\2\3" * 10)],
+            aDate = datetime.datetime(2004, 10, 26, 10, 33, 33),
+        )
+        pl[u'\xc5benraa'] = "That was a unicode key."
+        return pl
+
+    def test_create(self):
+        pl = self._create()
+        self.assertEqual(pl["aString"], "Doodah")
+        self.assertEqual(pl["aDict"]["aFalseValue"], False)
+
+    def test_io(self):
+        pl = self._create()
+        plistlib.writePlist(pl, test_support.TESTFN)
+        pl2 = plistlib.readPlist(test_support.TESTFN)
+        self.assertEqual(dict(pl), dict(pl2))
+
+    def test_string(self):
+        pl = self._create()
+        data = plistlib.writePlistToString(pl)
+        pl2 = plistlib.readPlistFromString(data)
+        self.assertEqual(dict(pl), dict(pl2))
+        data2 = plistlib.writePlistToString(pl2)
+        self.assertEqual(data, data2)
+
+    def test_appleformatting(self):
+        pl = plistlib.readPlistFromString(TESTDATA)
+        data = plistlib.writePlistToString(pl)
+        self.assertEqual(data, TESTDATA,
+                         "generated data was not identical to Apple's output")
+
+    def test_appleformattingfromliteral(self):
+        pl = self._create()
+        pl2 = plistlib.readPlistFromString(TESTDATA)
+        self.assertEqual(dict(pl), dict(pl2),
+                         "generated data was not identical to Apple's output")
+
+    def test_stringio(self):
+        from StringIO import StringIO
+        f = StringIO()
+        pl = self._create()
+        plistlib.writePlist(pl, f)
+        pl2 = plistlib.readPlist(StringIO(f.getvalue()))
+        self.assertEqual(dict(pl), dict(pl2))
+
+    def test_cstringio(self):
+        from cStringIO import StringIO
+        f = StringIO()
+        pl = self._create()
+        plistlib.writePlist(pl, f)
+        pl2 = plistlib.readPlist(StringIO(f.getvalue()))
+        self.assertEqual(dict(pl), dict(pl2))
+
+    def test_controlcharacters(self):
+        for i in range(128):
+            c = chr(i)
+            testString = "string containing %s" % c
+            if i >= 32 or c in "\r\n\t":
+                # \r, \n and \t are the only legal control chars in XML
+                plistlib.writePlistToString(testString)
+            else:
+                self.assertRaises(ValueError,
+                                  plistlib.writePlistToString,
+                                  testString)
+
+    def test_nondictroot(self):
+        test1 = "abc"
+        test2 = [1, 2, 3, "abc"]
+        result1 = plistlib.readPlistFromString(plistlib.writePlistToString(test1))
+        result2 = plistlib.readPlistFromString(plistlib.writePlistToString(test2))
+        self.assertEqual(test1, result1)
+        self.assertEqual(test2, result2)
+
+
+def test_main():
+    test_support.run_unittest(TestPlistlib)
+
+
+if __name__ == '__main__':
+    test_main()

Added: vendor/Python/current/Lib/test/test_poll.py
===================================================================
--- vendor/Python/current/Lib/test/test_poll.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_poll.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,192 @@
+# Test case for the os.poll() function
+
+import sys, os, select, random
+from test.test_support import verify, verbose, TestSkipped, TESTFN
+
+try:
+    select.poll
+except AttributeError:
+    raise TestSkipped, "select.poll not defined -- skipping test_poll"
+
+
+def find_ready_matching(ready, flag):
+    match = []
+    for fd, mode in ready:
+        if mode & flag:
+            match.append(fd)
+    return match
+
+def test_poll1():
+    """Basic functional test of poll object
+
+    Create a bunch of pipe and test that poll works with them.
+    """
+    print 'Running poll test 1'
+    p = select.poll()
+
+    NUM_PIPES = 12
+    MSG = " This is a test."
+    MSG_LEN = len(MSG)
+    readers = []
+    writers = []
+    r2w = {}
+    w2r = {}
+
+    for i in range(NUM_PIPES):
+        rd, wr = os.pipe()
+        p.register(rd, select.POLLIN)
+        p.register(wr, select.POLLOUT)
+        readers.append(rd)
+        writers.append(wr)
+        r2w[rd] = wr
+        w2r[wr] = rd
+
+    while writers:
+        ready = p.poll()
+        ready_writers = find_ready_matching(ready, select.POLLOUT)
+        if not ready_writers:
+            raise RuntimeError, "no pipes ready for writing"
+        wr = random.choice(ready_writers)
+        os.write(wr, MSG)
+
+        ready = p.poll()
+        ready_readers = find_ready_matching(ready, select.POLLIN)
+        if not ready_readers:
+            raise RuntimeError, "no pipes ready for reading"
+        rd = random.choice(ready_readers)
+        buf = os.read(rd, MSG_LEN)
+        verify(len(buf) == MSG_LEN)
+        print buf
+        os.close(r2w[rd]) ; os.close( rd )
+        p.unregister( r2w[rd] )
+        p.unregister( rd )
+        writers.remove(r2w[rd])
+
+    poll_unit_tests()
+    print 'Poll test 1 complete'
+
+def poll_unit_tests():
+    # returns NVAL for invalid file descriptor
+    FD = 42
+    try:
+        os.close(FD)
+    except OSError:
+        pass
+    p = select.poll()
+    p.register(FD)
+    r = p.poll()
+    verify(r[0] == (FD, select.POLLNVAL))
+
+    f = open(TESTFN, 'w')
+    fd = f.fileno()
+    p = select.poll()
+    p.register(f)
+    r = p.poll()
+    verify(r[0][0] == fd)
+    f.close()
+    r = p.poll()
+    verify(r[0] == (fd, select.POLLNVAL))
+    os.unlink(TESTFN)
+
+    # type error for invalid arguments
+    p = select.poll()
+    try:
+        p.register(p)
+    except TypeError:
+        pass
+    else:
+        print "Bogus register call did not raise TypeError"
+    try:
+        p.unregister(p)
+    except TypeError:
+        pass
+    else:
+        print "Bogus unregister call did not raise TypeError"
+
+    # can't unregister non-existent object
+    p = select.poll()
+    try:
+        p.unregister(3)
+    except KeyError:
+        pass
+    else:
+        print "Bogus unregister call did not raise KeyError"
+
+    # Test error cases
+    pollster = select.poll()
+    class Nope:
+        pass
+
+    class Almost:
+        def fileno(self):
+            return 'fileno'
+
+    try:
+        pollster.register( Nope(), 0 )
+    except TypeError: pass
+    else: print 'expected TypeError exception, not raised'
+
+    try:
+        pollster.register( Almost(), 0 )
+    except TypeError: pass
+    else: print 'expected TypeError exception, not raised'
+
+
+# Another test case for poll().  This is copied from the test case for
+# select(), modified to use poll() instead.
+
+def test_poll2():
+    print 'Running poll test 2'
+    cmd = 'for i in 0 1 2 3 4 5 6 7 8 9; do echo testing...; sleep 1; done'
+    p = os.popen(cmd, 'r')
+    pollster = select.poll()
+    pollster.register( p, select.POLLIN )
+    for tout in (0, 1000, 2000, 4000, 8000, 16000) + (-1,)*10:
+        if verbose:
+            print 'timeout =', tout
+        fdlist = pollster.poll(tout)
+        if (fdlist == []):
+            continue
+        fd, flags = fdlist[0]
+        if flags & select.POLLHUP:
+            line = p.readline()
+            if line != "":
+                print 'error: pipe seems to be closed, but still returns data'
+            continue
+
+        elif flags & select.POLLIN:
+            line = p.readline()
+            if verbose:
+                print repr(line)
+            if not line:
+                if verbose:
+                    print 'EOF'
+                break
+            continue
+        else:
+            print 'Unexpected return value from select.poll:', fdlist
+    p.close()
+    print 'Poll test 2 complete'
+
+def test_poll3():
+    # test int overflow
+    print 'Running poll test 3'
+    pollster = select.poll()
+    pollster.register(1)
+
+    try:
+        pollster.poll(1L << 64)
+    except OverflowError:
+        pass
+    else:
+        print 'Expected OverflowError with excessive timeout'
+
+    x = 2 + 3
+    if x != 5:
+        print 'Overflow must have occurred'
+    print 'Poll test 3 complete'
+
+
+test_poll1()
+test_poll2()
+test_poll3()

Added: vendor/Python/current/Lib/test/test_popen.py
===================================================================
--- vendor/Python/current/Lib/test/test_popen.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_popen.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,40 @@
+#! /usr/bin/env python
+"""Basic tests for os.popen()
+
+  Particularly useful for platforms that fake popen.
+"""
+
+import os
+import sys
+from test.test_support import TestSkipped, reap_children
+from os import popen
+
+# Test that command-lines get down as we expect.
+# To do this we execute:
+#    python -c "import sys;print sys.argv" {rest_of_commandline}
+# This results in Python being spawned and printing the sys.argv list.
+# We can then eval() the result of this, and see what each argv was.
+python = sys.executable
+if ' ' in python:
+    python = '"' + python + '"'     # quote embedded space for cmdline
+def _do_test_commandline(cmdline, expected):
+    cmd = '%s -c "import sys;print sys.argv" %s' % (python, cmdline)
+    data = popen(cmd).read()
+    got = eval(data)[1:] # strip off argv[0]
+    if got != expected:
+        print "Error in popen commandline handling."
+        print " executed '%s', expected '%r', but got '%r'" \
+                                                    % (cmdline, expected, got)
+
+def _test_commandline():
+    _do_test_commandline("foo bar", ["foo", "bar"])
+    _do_test_commandline('foo "spam and eggs" "silly walk"', ["foo", "spam and eggs", "silly walk"])
+    _do_test_commandline('foo "a \\"quoted\\" arg" bar', ["foo", 'a "quoted" arg', "bar"])
+    print "popen seemed to process the command-line correctly"
+
+def main():
+    print "Test popen:"
+    _test_commandline()
+    reap_children()
+
+main()

Added: vendor/Python/current/Lib/test/test_popen2.py
===================================================================
--- vendor/Python/current/Lib/test/test_popen2.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_popen2.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,78 @@
+#! /usr/bin/env python
+"""Test script for popen2.py
+   Christian Tismer
+"""
+
+import os
+import sys
+from test.test_support import TestSkipped, reap_children
+
+# popen2 contains its own testing routine
+# which is especially useful to see if open files
+# like stdin can be read successfully by a forked
+# subprocess.
+
+def main():
+    print "Test popen2 module:"
+    if (sys.platform[:4] == 'beos' or sys.platform[:6] == 'atheos') \
+           and __name__ != '__main__':
+        #  Locks get messed up or something.  Generally we're supposed
+        #  to avoid mixing "posix" fork & exec with native threads, and
+        #  they may be right about that after all.
+        raise TestSkipped, "popen2() doesn't work during import on " + sys.platform
+    try:
+        from os import popen
+    except ImportError:
+        # if we don't have os.popen, check that
+        # we have os.fork.  if not, skip the test
+        # (by raising an ImportError)
+        from os import fork
+    import popen2
+    popen2._test()
+
+
+def _test():
+    # same test as popen2._test(), but using the os.popen*() API
+    print "Testing os module:"
+    import popen2
+    # When the test runs, there shouldn't be any open pipes
+    popen2._cleanup()
+    assert not popen2._active, "Active pipes when test starts " + repr([c.cmd for c in popen2._active])
+    cmd  = "cat"
+    teststr = "ab cd\n"
+    if os.name == "nt":
+        cmd = "more"
+    # "more" doesn't act the same way across Windows flavors,
+    # sometimes adding an extra newline at the start or the
+    # end.  So we strip whitespace off both ends for comparison.
+    expected = teststr.strip()
+    print "testing popen2..."
+    w, r = os.popen2(cmd)
+    w.write(teststr)
+    w.close()
+    got = r.read()
+    if got.strip() != expected:
+        raise ValueError("wrote %r read %r" % (teststr, got))
+    print "testing popen3..."
+    try:
+        w, r, e = os.popen3([cmd])
+    except:
+        w, r, e = os.popen3(cmd)
+    w.write(teststr)
+    w.close()
+    got = r.read()
+    if got.strip() != expected:
+        raise ValueError("wrote %r read %r" % (teststr, got))
+    got = e.read()
+    if got:
+        raise ValueError("unexpected %r on stderr" % (got,))
+    for inst in popen2._active[:]:
+        inst.wait()
+    popen2._cleanup()
+    if popen2._active:
+        raise ValueError("_active not empty")
+    print "All OK"
+
+main()
+_test()
+reap_children()

Added: vendor/Python/current/Lib/test/test_posix.py
===================================================================
--- vendor/Python/current/Lib/test/test_posix.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_posix.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,199 @@
+"Test posix functions"
+
+from test import test_support
+
+try:
+    import posix
+except ImportError:
+    raise test_support.TestSkipped, "posix is not available"
+
+import time
+import os
+import sys
+import unittest
+import warnings
+warnings.filterwarnings('ignore', '.* potential security risk .*',
+                        RuntimeWarning)
+
+class PosixTester(unittest.TestCase):
+
+    def setUp(self):
+        # create empty file
+        fp = open(test_support.TESTFN, 'w+')
+        fp.close()
+
+    def tearDown(self):
+        os.unlink(test_support.TESTFN)
+
+    def testNoArgFunctions(self):
+        # test posix functions which take no arguments and have
+        # no side-effects which we need to cleanup (e.g., fork, wait, abort)
+        NO_ARG_FUNCTIONS = [ "ctermid", "getcwd", "getcwdu", "uname",
+                             "times", "getloadavg", "tmpnam",
+                             "getegid", "geteuid", "getgid", "getgroups",
+                             "getpid", "getpgrp", "getppid", "getuid",
+                           ]
+
+        for name in NO_ARG_FUNCTIONS:
+            posix_func = getattr(posix, name, None)
+            if posix_func is not None:
+                posix_func()
+                self.assertRaises(TypeError, posix_func, 1)
+
+    def test_statvfs(self):
+        if hasattr(posix, 'statvfs'):
+            self.assert_(posix.statvfs(os.curdir))
+
+    def test_fstatvfs(self):
+        if hasattr(posix, 'fstatvfs'):
+            fp = open(test_support.TESTFN)
+            try:
+                self.assert_(posix.fstatvfs(fp.fileno()))
+            finally:
+                fp.close()
+
+    def test_ftruncate(self):
+        if hasattr(posix, 'ftruncate'):
+            fp = open(test_support.TESTFN, 'w+')
+            try:
+                # we need to have some data to truncate
+                fp.write('test')
+                fp.flush()
+                posix.ftruncate(fp.fileno(), 0)
+            finally:
+                fp.close()
+
+    def test_dup(self):
+        if hasattr(posix, 'dup'):
+            fp = open(test_support.TESTFN)
+            try:
+                fd = posix.dup(fp.fileno())
+                self.assert_(isinstance(fd, int))
+                os.close(fd)
+            finally:
+                fp.close()
+
+    def test_confstr(self):
+        if hasattr(posix, 'confstr'):
+            self.assertRaises(ValueError, posix.confstr, "CS_garbage")
+            self.assertEqual(len(posix.confstr("CS_PATH")) > 0, True)
+
+    def test_dup2(self):
+        if hasattr(posix, 'dup2'):
+            fp1 = open(test_support.TESTFN)
+            fp2 = open(test_support.TESTFN)
+            try:
+                posix.dup2(fp1.fileno(), fp2.fileno())
+            finally:
+                fp1.close()
+                fp2.close()
+
+    def fdopen_helper(self, *args):
+        fd = os.open(test_support.TESTFN, os.O_RDONLY)
+        fp2 = posix.fdopen(fd, *args)
+        fp2.close()
+
+    def test_fdopen(self):
+        if hasattr(posix, 'fdopen'):
+            self.fdopen_helper()
+            self.fdopen_helper('r')
+            self.fdopen_helper('r', 100)
+
+    def test_osexlock(self):
+        if hasattr(posix, "O_EXLOCK"):
+            fd = os.open(test_support.TESTFN,
+                         os.O_WRONLY|os.O_EXLOCK|os.O_CREAT)
+            self.assertRaises(OSError, os.open, test_support.TESTFN,
+                              os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
+            os.close(fd)
+
+            if hasattr(posix, "O_SHLOCK"):
+                fd = os.open(test_support.TESTFN,
+                             os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
+                self.assertRaises(OSError, os.open, test_support.TESTFN,
+                                  os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
+                os.close(fd)
+
+    def test_osshlock(self):
+        if hasattr(posix, "O_SHLOCK"):
+            fd1 = os.open(test_support.TESTFN,
+                         os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
+            fd2 = os.open(test_support.TESTFN,
+                          os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
+            os.close(fd2)
+            os.close(fd1)
+
+            if hasattr(posix, "O_EXLOCK"):
+                fd = os.open(test_support.TESTFN,
+                             os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
+                self.assertRaises(OSError, os.open, test_support.TESTFN,
+                                  os.O_RDONLY|os.O_EXLOCK|os.O_NONBLOCK)
+                os.close(fd)
+
+    def test_fstat(self):
+        if hasattr(posix, 'fstat'):
+            fp = open(test_support.TESTFN)
+            try:
+                self.assert_(posix.fstat(fp.fileno()))
+            finally:
+                fp.close()
+
+    def test_stat(self):
+        if hasattr(posix, 'stat'):
+            self.assert_(posix.stat(test_support.TESTFN))
+
+    def test_chdir(self):
+        if hasattr(posix, 'chdir'):
+            posix.chdir(os.curdir)
+            self.assertRaises(OSError, posix.chdir, test_support.TESTFN)
+
+    def test_lsdir(self):
+        if hasattr(posix, 'lsdir'):
+            self.assert_(test_support.TESTFN in posix.lsdir(os.curdir))
+
+    def test_access(self):
+        if hasattr(posix, 'access'):
+            self.assert_(posix.access(test_support.TESTFN, os.R_OK))
+
+    def test_umask(self):
+        if hasattr(posix, 'umask'):
+            old_mask = posix.umask(0)
+            self.assert_(isinstance(old_mask, int))
+            posix.umask(old_mask)
+
+    def test_strerror(self):
+        if hasattr(posix, 'strerror'):
+            self.assert_(posix.strerror(0))
+
+    def test_pipe(self):
+        if hasattr(posix, 'pipe'):
+            reader, writer = posix.pipe()
+            os.close(reader)
+            os.close(writer)
+
+    def test_tempnam(self):
+        if hasattr(posix, 'tempnam'):
+            self.assert_(posix.tempnam())
+            self.assert_(posix.tempnam(os.curdir))
+            self.assert_(posix.tempnam(os.curdir, 'blah'))
+
+    def test_tmpfile(self):
+        if hasattr(posix, 'tmpfile'):
+            fp = posix.tmpfile()
+            fp.close()
+
+    def test_utime(self):
+        if hasattr(posix, 'utime'):
+            now = time.time()
+            posix.utime(test_support.TESTFN, None)
+            self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (None, None))
+            self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (now, None))
+            self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (None, now))
+            posix.utime(test_support.TESTFN, (int(now), int(now)))
+            posix.utime(test_support.TESTFN, (now, now))
+
+def test_main():
+    test_support.run_unittest(PosixTester)
+
+if __name__ == '__main__':
+    test_main()

Added: vendor/Python/current/Lib/test/test_posixpath.py
===================================================================
--- vendor/Python/current/Lib/test/test_posixpath.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_posixpath.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,515 @@
+import unittest
+from test import test_support
+
+import posixpath, os
+from posixpath import realpath, abspath, join, dirname, basename
+
+# An absolute path to a temporary filename for testing. We can't rely on TESTFN
+# being an absolute path, so we need this.
+
+ABSTFN = abspath(test_support.TESTFN)
+
+class PosixPathTest(unittest.TestCase):
+
+    def assertIs(self, a, b):
+        self.assert_(a is b)
+
+    def test_normcase(self):
+        # Check that normcase() is idempotent
+        p = "FoO/./BaR"
+        p = posixpath.normcase(p)
+        self.assertEqual(p, posixpath.normcase(p))
+
+        self.assertRaises(TypeError, posixpath.normcase)
+
+    def test_join(self):
+        self.assertEqual(posixpath.join("/foo", "bar", "/bar", "baz"), "/bar/baz")
+        self.assertEqual(posixpath.join("/foo", "bar", "baz"), "/foo/bar/baz")
+        self.assertEqual(posixpath.join("/foo/", "bar/", "baz/"), "/foo/bar/baz/")
+
+        self.assertRaises(TypeError, posixpath.join)
+
+    def test_splitdrive(self):
+        self.assertEqual(posixpath.splitdrive("/foo/bar"), ("", "/foo/bar"))
+
+        self.assertRaises(TypeError, posixpath.splitdrive)
+
+    def test_split(self):
+        self.assertEqual(posixpath.split("/foo/bar"), ("/foo", "bar"))
+        self.assertEqual(posixpath.split("/"), ("/", ""))
+        self.assertEqual(posixpath.split("foo"), ("", "foo"))
+        self.assertEqual(posixpath.split("////foo"), ("////", "foo"))
+        self.assertEqual(posixpath.split("//foo//bar"), ("//foo", "bar"))
+
+        self.assertRaises(TypeError, posixpath.split)
+
+    def test_splitext(self):
+        self.assertEqual(posixpath.splitext("foo.ext"), ("foo", ".ext"))
+        self.assertEqual(posixpath.splitext("/foo/foo.ext"), ("/foo/foo", ".ext"))
+        self.assertEqual(posixpath.splitext(".ext"), ("", ".ext"))
+        self.assertEqual(posixpath.splitext("/foo.ext/foo"), ("/foo.ext/foo", ""))
+        self.assertEqual(posixpath.splitext("foo.ext/"), ("foo.ext/", ""))
+        self.assertEqual(posixpath.splitext(""), ("", ""))
+        self.assertEqual(posixpath.splitext("foo.bar.ext"), ("foo.bar", ".ext"))
+
+        self.assertRaises(TypeError, posixpath.splitext)
+
+    def test_isabs(self):
+        self.assertIs(posixpath.isabs(""), False)
+        self.assertIs(posixpath.isabs("/"), True)
+        self.assertIs(posixpath.isabs("/foo"), True)
+        self.assertIs(posixpath.isabs("/foo/bar"), True)
+        self.assertIs(posixpath.isabs("foo/bar"), False)
+
+        self.assertRaises(TypeError, posixpath.isabs)
+
+    def test_splitdrive(self):
+        self.assertEqual(posixpath.splitdrive("/foo/bar"), ("", "/foo/bar"))
+
+        self.assertRaises(TypeError, posixpath.splitdrive)
+
+    def test_basename(self):
+        self.assertEqual(posixpath.basename("/foo/bar"), "bar")
+        self.assertEqual(posixpath.basename("/"), "")
+        self.assertEqual(posixpath.basename("foo"), "foo")
+        self.assertEqual(posixpath.basename("////foo"), "foo")
+        self.assertEqual(posixpath.basename("//foo//bar"), "bar")
+
+        self.assertRaises(TypeError, posixpath.basename)
+
+    def test_dirname(self):
+        self.assertEqual(posixpath.dirname("/foo/bar"), "/foo")
+        self.assertEqual(posixpath.dirname("/"), "/")
+        self.assertEqual(posixpath.dirname("foo"), "")
+        self.assertEqual(posixpath.dirname("////foo"), "////")
+        self.assertEqual(posixpath.dirname("//foo//bar"), "//foo")
+
+        self.assertRaises(TypeError, posixpath.dirname)
+
+    def test_commonprefix(self):
+        self.assertEqual(
+            posixpath.commonprefix([]),
+            ""
+        )
+        self.assertEqual(
+            posixpath.commonprefix(["/home/swenson/spam", "/home/swen/spam"]),
+            "/home/swen"
+        )
+        self.assertEqual(
+            posixpath.commonprefix(["/home/swen/spam", "/home/swen/eggs"]),
+            "/home/swen/"
+        )
+        self.assertEqual(
+            posixpath.commonprefix(["/home/swen/spam", "/home/swen/spam"]),
+            "/home/swen/spam"
+        )
+
+    def test_getsize(self):
+        f = open(test_support.TESTFN, "wb")
+        try:
+            f.write("foo")
+            f.close()
+            self.assertEqual(posixpath.getsize(test_support.TESTFN), 3)
+        finally:
+            if not f.closed:
+                f.close()
+            os.remove(test_support.TESTFN)
+
+    def test_time(self):
+        f = open(test_support.TESTFN, "wb")
+        try:
+            f.write("foo")
+            f.close()
+            f = open(test_support.TESTFN, "ab")
+            f.write("bar")
+            f.close()
+            f = open(test_support.TESTFN, "rb")
+            d = f.read()
+            f.close()
+            self.assertEqual(d, "foobar")
+
+            self.assert_(
+                posixpath.getctime(test_support.TESTFN) <=
+                posixpath.getmtime(test_support.TESTFN)
+            )
+        finally:
+            if not f.closed:
+                f.close()
+            os.remove(test_support.TESTFN)
+
+    def test_islink(self):
+        self.assertIs(posixpath.islink(test_support.TESTFN + "1"), False)
+        f = open(test_support.TESTFN + "1", "wb")
+        try:
+            f.write("foo")
+            f.close()
+            self.assertIs(posixpath.islink(test_support.TESTFN + "1"), False)
+            if hasattr(os, "symlink"):
+                os.symlink(test_support.TESTFN + "1", test_support.TESTFN + "2")
+                self.assertIs(posixpath.islink(test_support.TESTFN + "2"), True)
+                os.remove(test_support.TESTFN + "1")
+                self.assertIs(posixpath.islink(test_support.TESTFN + "2"), True)
+                self.assertIs(posixpath.exists(test_support.TESTFN + "2"), False)
+                self.assertIs(posixpath.lexists(test_support.TESTFN + "2"), True)
+        finally:
+            if not f.close():
+                f.close()
+            try:
+                os.remove(test_support.TESTFN + "1")
+            except os.error:
+                pass
+            try:
+                os.remove(test_support.TESTFN + "2")
+            except os.error:
+                pass
+
+        self.assertRaises(TypeError, posixpath.islink)
+
+    def test_exists(self):
+        self.assertIs(posixpath.exists(test_support.TESTFN), False)
+        f = open(test_support.TESTFN, "wb")
+        try:
+            f.write("foo")
+            f.close()
+            self.assertIs(posixpath.exists(test_support.TESTFN), True)
+            self.assertIs(posixpath.lexists(test_support.TESTFN), True)
+        finally:
+            if not f.close():
+                f.close()
+            try:
+                os.remove(test_support.TESTFN)
+            except os.error:
+                pass
+
+        self.assertRaises(TypeError, posixpath.exists)
+
+    def test_isdir(self):
+        self.assertIs(posixpath.isdir(test_support.TESTFN), False)
+        f = open(test_support.TESTFN, "wb")
+        try:
+            f.write("foo")
+            f.close()
+            self.assertIs(posixpath.isdir(test_support.TESTFN), False)
+            os.remove(test_support.TESTFN)
+            os.mkdir(test_support.TESTFN)
+            self.assertIs(posixpath.isdir(test_support.TESTFN), True)
+            os.rmdir(test_support.TESTFN)
+        finally:
+            if not f.close():
+                f.close()
+            try:
+                os.remove(test_support.TESTFN)
+            except os.error:
+                pass
+            try:
+                os.rmdir(test_support.TESTFN)
+            except os.error:
+                pass
+
+        self.assertRaises(TypeError, posixpath.isdir)
+
+    def test_isfile(self):
+        self.assertIs(posixpath.isfile(test_support.TESTFN), False)
+        f = open(test_support.TESTFN, "wb")
+        try:
+            f.write("foo")
+            f.close()
+            self.assertIs(posixpath.isfile(test_support.TESTFN), True)
+            os.remove(test_support.TESTFN)
+            os.mkdir(test_support.TESTFN)
+            self.assertIs(posixpath.isfile(test_support.TESTFN), False)
+            os.rmdir(test_support.TESTFN)
+        finally:
+            if not f.close():
+                f.close()
+            try:
+                os.remove(test_support.TESTFN)
+            except os.error:
+                pass
+            try:
+                os.rmdir(test_support.TESTFN)
+            except os.error:
+                pass
+
+        self.assertRaises(TypeError, posixpath.isdir)
+
+        def test_samefile(self):
+            f = open(test_support.TESTFN + "1", "wb")
+            try:
+                f.write("foo")
+                f.close()
+                self.assertIs(
+                    posixpath.samefile(
+                        test_support.TESTFN + "1",
+                        test_support.TESTFN + "1"
+                    ),
+                    True
+                )
+                # If we don't have links, assume that os.stat doesn't return resonable
+                # inode information and thus, that samefile() doesn't work
+                if hasattr(os, "symlink"):
+                    os.symlink(
+                        test_support.TESTFN + "1",
+                        test_support.TESTFN + "2"
+                    )
+                    self.assertIs(
+                        posixpath.samefile(
+                            test_support.TESTFN + "1",
+                            test_support.TESTFN + "2"
+                        ),
+                        True
+                    )
+                    os.remove(test_support.TESTFN + "2")
+                    f = open(test_support.TESTFN + "2", "wb")
+                    f.write("bar")
+                    f.close()
+                    self.assertIs(
+                        posixpath.samefile(
+                            test_support.TESTFN + "1",
+                            test_support.TESTFN + "2"
+                        ),
+                        False
+                    )
+            finally:
+                if not f.close():
+                    f.close()
+                try:
+                    os.remove(test_support.TESTFN + "1")
+                except os.error:
+                    pass
+                try:
+                    os.remove(test_support.TESTFN + "2")
+                except os.error:
+                    pass
+
+            self.assertRaises(TypeError, posixpath.samefile)
+
+    def test_samestat(self):
+        f = open(test_support.TESTFN + "1", "wb")
+        try:
+            f.write("foo")
+            f.close()
+            self.assertIs(
+                posixpath.samestat(
+                    os.stat(test_support.TESTFN + "1"),
+                    os.stat(test_support.TESTFN + "1")
+                ),
+                True
+            )
+            # If we don't have links, assume that os.stat() doesn't return resonable
+            # inode information and thus, that samefile() doesn't work
+            if hasattr(os, "symlink"):
+                if hasattr(os, "symlink"):
+                    os.symlink(test_support.TESTFN + "1", test_support.TESTFN + "2")
+                    self.assertIs(
+                        posixpath.samestat(
+                            os.stat(test_support.TESTFN + "1"),
+                            os.stat(test_support.TESTFN + "2")
+                        ),
+                        True
+                    )
+                    os.remove(test_support.TESTFN + "2")
+                f = open(test_support.TESTFN + "2", "wb")
+                f.write("bar")
+                f.close()
+                self.assertIs(
+                    posixpath.samestat(
+                        os.stat(test_support.TESTFN + "1"),
+                        os.stat(test_support.TESTFN + "2")
+                    ),
+                    False
+                )
+        finally:
+            if not f.close():
+                f.close()
+            try:
+                os.remove(test_support.TESTFN + "1")
+            except os.error:
+                pass
+            try:
+                os.remove(test_support.TESTFN + "2")
+            except os.error:
+                pass
+
+        self.assertRaises(TypeError, posixpath.samestat)
+
+    def test_ismount(self):
+        self.assertIs(posixpath.ismount("/"), True)
+
+        self.assertRaises(TypeError, posixpath.ismount)
+
+    def test_expanduser(self):
+        self.assertEqual(posixpath.expanduser("foo"), "foo")
+        try:
+            import pwd
+        except ImportError:
+            pass
+        else:
+            self.assert_(isinstance(posixpath.expanduser("~/"), basestring))
+            # if home directory == root directory, this test makes no sense
+            if posixpath.expanduser("~") != '/':
+                self.assertEqual(
+                    posixpath.expanduser("~") + "/",
+                    posixpath.expanduser("~/")
+                )
+            self.assert_(isinstance(posixpath.expanduser("~root/"), basestring))
+            self.assert_(isinstance(posixpath.expanduser("~foo/"), basestring))
+
+        self.assertRaises(TypeError, posixpath.expanduser)
+
+    def test_expandvars(self):
+        oldenv = os.environ.copy()
+        try:
+            os.environ.clear()
+            os.environ["foo"] = "bar"
+            os.environ["{foo"] = "baz1"
+            os.environ["{foo}"] = "baz2"
+            self.assertEqual(posixpath.expandvars("foo"), "foo")
+            self.assertEqual(posixpath.expandvars("$foo bar"), "bar bar")
+            self.assertEqual(posixpath.expandvars("${foo}bar"), "barbar")
+            self.assertEqual(posixpath.expandvars("$[foo]bar"), "$[foo]bar")
+            self.assertEqual(posixpath.expandvars("$bar bar"), "$bar bar")
+            self.assertEqual(posixpath.expandvars("$?bar"), "$?bar")
+            self.assertEqual(posixpath.expandvars("${foo}bar"), "barbar")
+            self.assertEqual(posixpath.expandvars("$foo}bar"), "bar}bar")
+            self.assertEqual(posixpath.expandvars("${foo"), "${foo")
+            self.assertEqual(posixpath.expandvars("${{foo}}"), "baz1}")
+        finally:
+            os.environ.clear()
+            os.environ.update(oldenv)
+
+        self.assertRaises(TypeError, posixpath.expandvars)
+
+    def test_normpath(self):
+        self.assertEqual(posixpath.normpath(""), ".")
+        self.assertEqual(posixpath.normpath("/"), "/")
+        self.assertEqual(posixpath.normpath("//"), "//")
+        self.assertEqual(posixpath.normpath("///"), "/")
+        self.assertEqual(posixpath.normpath("///foo/.//bar//"), "/foo/bar")
+        self.assertEqual(posixpath.normpath("///foo/.//bar//.//..//.//baz"), "/foo/baz")
+        self.assertEqual(posixpath.normpath("///..//./foo/.//bar"), "/foo/bar")
+
+        self.assertRaises(TypeError, posixpath.normpath)
+
+    def test_abspath(self):
+        self.assert_("foo" in posixpath.abspath("foo"))
+
+        self.assertRaises(TypeError, posixpath.abspath)
+
+    def test_realpath(self):
+        self.assert_("foo" in realpath("foo"))
+        self.assertRaises(TypeError, posixpath.realpath)
+
+    if hasattr(os, "symlink"):
+        def test_realpath_basic(self):
+            # Basic operation.
+            try:
+                os.symlink(ABSTFN+"1", ABSTFN)
+                self.assertEqual(realpath(ABSTFN), ABSTFN+"1")
+            finally:
+                self.safe_remove(ABSTFN)
+
+        def test_realpath_symlink_loops(self):
+            # Bug #930024, return the path unchanged if we get into an infinite
+            # symlink loop.
+            try:
+                old_path = abspath('.')
+                os.symlink(ABSTFN, ABSTFN)
+                self.assertEqual(realpath(ABSTFN), ABSTFN)
+
+                os.symlink(ABSTFN+"1", ABSTFN+"2")
+                os.symlink(ABSTFN+"2", ABSTFN+"1")
+                self.assertEqual(realpath(ABSTFN+"1"), ABSTFN+"1")
+                self.assertEqual(realpath(ABSTFN+"2"), ABSTFN+"2")
+
+                # Test using relative path as well.
+                os.chdir(dirname(ABSTFN))
+                self.assertEqual(realpath(basename(ABSTFN)), ABSTFN)
+            finally:
+                os.chdir(old_path)
+                self.safe_remove(ABSTFN)
+                self.safe_remove(ABSTFN+"1")
+                self.safe_remove(ABSTFN+"2")
+
+        def test_realpath_resolve_parents(self):
+            # We also need to resolve any symlinks in the parents of a relative
+            # path passed to realpath. E.g.: current working directory is
+            # /usr/doc with 'doc' being a symlink to /usr/share/doc. We call
+            # realpath("a"). This should return /usr/share/doc/a/.
+            try:
+                old_path = abspath('.')
+                os.mkdir(ABSTFN)
+                os.mkdir(ABSTFN + "/y")
+                os.symlink(ABSTFN + "/y", ABSTFN + "/k")
+
+                os.chdir(ABSTFN + "/k")
+                self.assertEqual(realpath("a"), ABSTFN + "/y/a")
+            finally:
+                os.chdir(old_path)
+                self.safe_remove(ABSTFN + "/k")
+                self.safe_rmdir(ABSTFN + "/y")
+                self.safe_rmdir(ABSTFN)
+
+        def test_realpath_resolve_before_normalizing(self):
+            # Bug #990669: Symbolic links should be resolved before we
+            # normalize the path. E.g.: if we have directories 'a', 'k' and 'y'
+            # in the following hierarchy:
+            # a/k/y
+            #
+            # and a symbolic link 'link-y' pointing to 'y' in directory 'a',
+            # then realpath("link-y/..") should return 'k', not 'a'.
+            try:
+                old_path = abspath('.')
+                os.mkdir(ABSTFN)
+                os.mkdir(ABSTFN + "/k")
+                os.mkdir(ABSTFN + "/k/y")
+                os.symlink(ABSTFN + "/k/y", ABSTFN + "/link-y")
+
+                # Absolute path.
+                self.assertEqual(realpath(ABSTFN + "/link-y/.."), ABSTFN + "/k")
+                # Relative path.
+                os.chdir(dirname(ABSTFN))
+                self.assertEqual(realpath(basename(ABSTFN) + "/link-y/.."), ABSTFN + "/k")
+            finally:
+                os.chdir(old_path)
+                self.safe_remove(ABSTFN + "/link-y")
+                self.safe_rmdir(ABSTFN + "/k/y")
+                self.safe_rmdir(ABSTFN + "/k")
+                self.safe_rmdir(ABSTFN)
+
+        def test_realpath_resolve_first(self):
+            # Bug #1213894: The first component of the path, if not absolute,
+            # must be resolved too.
+
+            try:
+                old_path = abspath('.')
+                os.mkdir(ABSTFN)
+                os.mkdir(ABSTFN + "/k")
+                os.symlink(ABSTFN, ABSTFN + "link")
+                os.chdir(dirname(ABSTFN))
+
+                base = basename(ABSTFN)
+                self.assertEqual(realpath(base + "link"), ABSTFN)
+                self.assertEqual(realpath(base + "link/k"), ABSTFN + "/k")
+            finally:
+                os.chdir(old_path)
+                self.safe_remove(ABSTFN + "link")
+                self.safe_rmdir(ABSTFN + "/k")
+                self.safe_rmdir(ABSTFN)
+
+        # Convenience functions for removing temporary files.
+        def pass_os_error(self, func, filename):
+            try: func(filename)
+            except OSError: pass
+
+        def safe_remove(self, filename):
+            self.pass_os_error(os.remove, filename)
+
+        def safe_rmdir(self, dirname):
+            self.pass_os_error(os.rmdir, dirname)
+
+def test_main():
+    test_support.run_unittest(PosixPathTest)
+
+if __name__=="__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_pow.py
===================================================================
--- vendor/Python/current/Lib/test/test_pow.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_pow.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,126 @@
+import test.test_support, unittest
+
+class PowTest(unittest.TestCase):
+
+    def powtest(self, type):
+        if type != float:
+            for i in range(-1000, 1000):
+                self.assertEquals(pow(type(i), 0), 1)
+                self.assertEquals(pow(type(i), 1), type(i))
+                self.assertEquals(pow(type(0), 1), type(0))
+                self.assertEquals(pow(type(1), 1), type(1))
+
+            for i in range(-100, 100):
+                self.assertEquals(pow(type(i), 3), i*i*i)
+
+            pow2 = 1
+            for i in range(0,31):
+                self.assertEquals(pow(2, i), pow2)
+                if i != 30 : pow2 = pow2*2
+
+            for othertype in int, long:
+                for i in range(-10, 0) + range(1, 10):
+                    ii = type(i)
+                    for j in range(1, 11):
+                        jj = -othertype(j)
+                        pow(ii, jj)
+
+        for othertype in int, long, float:
+            for i in range(1, 100):
+                zero = type(0)
+                exp = -othertype(i/10.0)
+                if exp == 0:
+                    continue
+                self.assertRaises(ZeroDivisionError, pow, zero, exp)
+
+        il, ih = -20, 20
+        jl, jh = -5,   5
+        kl, kh = -10, 10
+        asseq = self.assertEqual
+        if type == float:
+            il = 1
+            asseq = self.assertAlmostEqual
+        elif type == int:
+            jl = 0
+        elif type == long:
+            jl, jh = 0, 15
+        for i in range(il, ih+1):
+            for j in range(jl, jh+1):
+                for k in range(kl, kh+1):
+                    if k != 0:
+                        if type == float or j < 0:
+                            self.assertRaises(TypeError, pow, type(i), j, k)
+                            continue
+                        asseq(
+                            pow(type(i),j,k),
+                            pow(type(i),j)% type(k)
+                        )
+
+    def test_powint(self):
+        self.powtest(int)
+
+    def test_powlong(self):
+        self.powtest(long)
+
+    def test_powfloat(self):
+        self.powtest(float)
+
+    def test_other(self):
+        # Other tests-- not very systematic
+        self.assertEquals(pow(3,3) % 8, pow(3,3,8))
+        self.assertEquals(pow(3,3) % -8, pow(3,3,-8))
+        self.assertEquals(pow(3,2) % -2, pow(3,2,-2))
+        self.assertEquals(pow(-3,3) % 8, pow(-3,3,8))
+        self.assertEquals(pow(-3,3) % -8, pow(-3,3,-8))
+        self.assertEquals(pow(5,2) % -8, pow(5,2,-8))
+
+        self.assertEquals(pow(3L,3L) % 8, pow(3L,3L,8))
+        self.assertEquals(pow(3L,3L) % -8, pow(3L,3L,-8))
+        self.assertEquals(pow(3L,2) % -2, pow(3L,2,-2))
+        self.assertEquals(pow(-3L,3L) % 8, pow(-3L,3L,8))
+        self.assertEquals(pow(-3L,3L) % -8, pow(-3L,3L,-8))
+        self.assertEquals(pow(5L,2) % -8, pow(5L,2,-8))
+
+        for i in range(-10, 11):
+            for j in range(0, 6):
+                for k in range(-7, 11):
+                    if j >= 0 and k != 0:
+                        self.assertEquals(
+                            pow(i,j) % k,
+                            pow(i,j,k)
+                        )
+                    if j >= 0 and k != 0:
+                        self.assertEquals(
+                            pow(long(i),j) % k,
+                            pow(long(i),j,k)
+                        )
+
+    def test_bug643260(self):
+        class TestRpow:
+            def __rpow__(self, other):
+                return None
+        None ** TestRpow() # Won't fail when __rpow__ invoked.  SF bug #643260.
+
+    def test_bug705231(self):
+        # -1.0 raised to an integer should never blow up.  It did if the
+        # platform pow() was buggy, and Python didn't worm around it.
+        eq = self.assertEquals
+        a = -1.0
+        eq(pow(a, 1.23e167), 1.0)
+        eq(pow(a, -1.23e167), 1.0)
+        for b in range(-10, 11):
+            eq(pow(a, float(b)), b & 1 and -1.0 or 1.0)
+        for n in range(0, 100):
+            fiveto = float(5 ** n)
+            # For small n, fiveto will be odd.  Eventually we run out of
+            # mantissa bits, though, and thereafer fiveto will be even.
+            expected = fiveto % 2.0 and -1.0 or 1.0
+            eq(pow(a, fiveto), expected)
+            eq(pow(a, -fiveto), expected)
+        eq(expected, 1.0)   # else we didn't push fiveto to evenness
+
+def test_main():
+    test.test_support.run_unittest(PowTest)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_pprint.py
===================================================================
--- vendor/Python/current/Lib/test/test_pprint.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_pprint.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,217 @@
+import pprint
+import test.test_support
+import unittest
+
+try:
+    uni = unicode
+except NameError:
+    def uni(x):
+        return x
+
+# list, tuple and dict subclasses that do or don't overwrite __repr__
+class list2(list):
+    pass
+
+class list3(list):
+    def __repr__(self):
+        return list.__repr__(self)
+
+class tuple2(tuple):
+    pass
+
+class tuple3(tuple):
+    def __repr__(self):
+        return tuple.__repr__(self)
+
+class dict2(dict):
+    pass
+
+class dict3(dict):
+    def __repr__(self):
+        return dict.__repr__(self)
+
+class QueryTestCase(unittest.TestCase):
+
+    def setUp(self):
+        self.a = range(100)
+        self.b = range(200)
+        self.a[-12] = self.b
+
+    def test_basic(self):
+        # Verify .isrecursive() and .isreadable() w/o recursion
+        verify = self.assert_
+        pp = pprint.PrettyPrinter()
+        for safe in (2, 2.0, 2j, "abc", [3], (2,2), {3: 3}, uni("yaddayadda"),
+                     self.a, self.b):
+            # module-level convenience functions
+            verify(not pprint.isrecursive(safe),
+                   "expected not isrecursive for %r" % (safe,))
+            verify(pprint.isreadable(safe),
+                   "expected isreadable for %r" % (safe,))
+            # PrettyPrinter methods
+            verify(not pp.isrecursive(safe),
+                   "expected not isrecursive for %r" % (safe,))
+            verify(pp.isreadable(safe),
+                   "expected isreadable for %r" % (safe,))
+
+    def test_knotted(self):
+        # Verify .isrecursive() and .isreadable() w/ recursion
+        # Tie a knot.
+        self.b[67] = self.a
+        # Messy dict.
+        self.d = {}
+        self.d[0] = self.d[1] = self.d[2] = self.d
+
+        verify = self.assert_
+        pp = pprint.PrettyPrinter()
+
+        for icky in self.a, self.b, self.d, (self.d, self.d):
+            verify(pprint.isrecursive(icky), "expected isrecursive")
+            verify(not pprint.isreadable(icky),  "expected not isreadable")
+            verify(pp.isrecursive(icky), "expected isrecursive")
+            verify(not pp.isreadable(icky),  "expected not isreadable")
+
+        # Break the cycles.
+        self.d.clear()
+        del self.a[:]
+        del self.b[:]
+
+        for safe in self.a, self.b, self.d, (self.d, self.d):
+            # module-level convenience functions
+            verify(not pprint.isrecursive(safe),
+                   "expected not isrecursive for %r" % (safe,))
+            verify(pprint.isreadable(safe),
+                   "expected isreadable for %r" % (safe,))
+            # PrettyPrinter methods
+            verify(not pp.isrecursive(safe),
+                   "expected not isrecursive for %r" % (safe,))
+            verify(pp.isreadable(safe),
+                   "expected isreadable for %r" % (safe,))
+
+    def test_unreadable(self):
+        # Not recursive but not readable anyway
+        verify = self.assert_
+        pp = pprint.PrettyPrinter()
+        for unreadable in type(3), pprint, pprint.isrecursive:
+            # module-level convenience functions
+            verify(not pprint.isrecursive(unreadable),
+                   "expected not isrecursive for %r" % (unreadable,))
+            verify(not pprint.isreadable(unreadable),
+                   "expected not isreadable for %r" % (unreadable,))
+            # PrettyPrinter methods
+            verify(not pp.isrecursive(unreadable),
+                   "expected not isrecursive for %r" % (unreadable,))
+            verify(not pp.isreadable(unreadable),
+                   "expected not isreadable for %r" % (unreadable,))
+
+    def test_same_as_repr(self):
+        # Simple objects, small containers and classes that overwrite __repr__
+        # For those the result should be the same as repr().
+        # Ahem.  The docs don't say anything about that -- this appears to
+        # be testing an implementation quirk.  Starting in Python 2.5, it's
+        # not true for dicts:  pprint always sorts dicts by key now; before,
+        # it sorted a dict display if and only if the display required
+        # multiple lines.  For that reason, dicts with more than one element
+        # aren't tested here.
+        verify = self.assert_
+        for simple in (0, 0L, 0+0j, 0.0, "", uni(""),
+                       (), tuple2(), tuple3(),
+                       [], list2(), list3(),
+                       {}, dict2(), dict3(),
+                       verify, pprint,
+                       -6, -6L, -6-6j, -1.5, "x", uni("x"), (3,), [3], {3: 6},
+                       (1,2), [3,4], {5: 6, 7: 8},
+                       tuple2((1,2)), tuple3((1,2)), tuple3(range(100)),
+                       [3,4], list2([3,4]), list3([3,4]), list3(range(100)),
+                       {5: 6, 7: 8}, dict2({5: 6}), dict3({5: 6}),
+                       range(10, -11, -1)
+                      ):
+            native = repr(simple)
+            for function in "pformat", "saferepr":
+                f = getattr(pprint, function)
+                got = f(simple)
+                verify(native == got, "expected %s got %s from pprint.%s" %
+                                      (native, got, function))
+
+    def test_basic_line_wrap(self):
+        # verify basic line-wrapping operation
+        o = {'RPM_cal': 0,
+             'RPM_cal2': 48059,
+             'Speed_cal': 0,
+             'controldesk_runtime_us': 0,
+             'main_code_runtime_us': 0,
+             'read_io_runtime_us': 0,
+             'write_io_runtime_us': 43690}
+        exp = """\
+{'RPM_cal': 0,
+ 'RPM_cal2': 48059,
+ 'Speed_cal': 0,
+ 'controldesk_runtime_us': 0,
+ 'main_code_runtime_us': 0,
+ 'read_io_runtime_us': 0,
+ 'write_io_runtime_us': 43690}"""
+        for type in [dict, dict2]:
+            self.assertEqual(pprint.pformat(type(o)), exp)
+
+        o = range(100)
+        exp = '[%s]' % ',\n '.join(map(str, o))
+        for type in [list, list2]:
+            self.assertEqual(pprint.pformat(type(o)), exp)
+
+        o = tuple(range(100))
+        exp = '(%s)' % ',\n '.join(map(str, o))
+        for type in [tuple, tuple2]:
+            self.assertEqual(pprint.pformat(type(o)), exp)
+
+        # indent parameter
+        o = range(100)
+        exp = '[   %s]' % ',\n    '.join(map(str, o))
+        for type in [list, list2]:
+            self.assertEqual(pprint.pformat(type(o), indent=4), exp)
+
+    def test_sorted_dict(self):
+        # Starting in Python 2.5, pprint sorts dict displays by key regardless
+        # of how small the dictionary may be.
+        # Before the change, on 32-bit Windows pformat() gave order
+        # 'a', 'c', 'b' here, so this test failed.
+        d = {'a': 1, 'b': 1, 'c': 1}
+        self.assertEqual(pprint.pformat(d), "{'a': 1, 'b': 1, 'c': 1}")
+        self.assertEqual(pprint.pformat([d, d]),
+            "[{'a': 1, 'b': 1, 'c': 1}, {'a': 1, 'b': 1, 'c': 1}]")
+
+        # The next one is kind of goofy.  The sorted order depends on the
+        # alphabetic order of type names:  "int" < "str" < "tuple".  Before
+        # Python 2.5, this was in the test_same_as_repr() test.  It's worth
+        # keeping around for now because it's one of few tests of pprint
+        # against a crazy mix of types.
+        self.assertEqual(pprint.pformat({"xy\tab\n": (3,), 5: [[]], (): {}}),
+            r"{5: [[]], 'xy\tab\n': (3,), (): {}}")
+
+    def test_subclassing(self):
+        o = {'names with spaces': 'should be presented using repr()',
+             'others.should.not.be': 'like.this'}
+        exp = """\
+{'names with spaces': 'should be presented using repr()',
+ others.should.not.be: like.this}"""
+        self.assertEqual(DottedPrettyPrinter().pformat(o), exp)
+
+
+class DottedPrettyPrinter(pprint.PrettyPrinter):
+
+    def format(self, object, context, maxlevels, level):
+        if isinstance(object, str):
+            if ' ' in object:
+                return repr(object), 1, 0
+            else:
+                return object, 0, 0
+        else:
+            return pprint.PrettyPrinter.format(
+                self, object, context, maxlevels, level)
+
+
+def test_main():
+    test.test_support.run_unittest(QueryTestCase)
+
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_profile.py
===================================================================
--- vendor/Python/current/Lib/test/test_profile.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_profile.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,123 @@
+"""Test suite for the profile module."""
+
+import profile, pstats, sys
+
+# In order to have reproducible time, we simulate a timer in the global
+# variable 'ticks', which represents simulated time in milliseconds.
+# (We can't use a helper function increment the timer since it would be
+# included in the profile and would appear to consume all the time.)
+ticks = 0
+
+# IMPORTANT: this is an output test.  *ALL* NUMBERS in the expected
+# output are relevant.  If you change the formatting of pstats,
+# please don't just regenerate output/test_profile without checking
+# very carefully that not a single number has changed.
+
+def test_main():
+    global ticks
+    ticks = 42000
+    prof = profile.Profile(timer)
+    prof.runctx("testfunc()", globals(), locals())
+    assert ticks == 43000, ticks
+    st = pstats.Stats(prof)
+    st.strip_dirs().sort_stats('stdname').print_stats()
+    st.print_callees()
+    st.print_callers()
+
+def timer():
+    return ticks*0.001
+
+def testfunc():
+    # 1 call
+    # 1000 ticks total: 270 ticks local, 730 ticks in subfunctions
+    global ticks
+    ticks += 99
+    helper()                            # 300
+    helper()                            # 300
+    ticks += 171
+    factorial(14)                       # 130
+
+def factorial(n):
+    # 23 calls total
+    # 170 ticks total, 150 ticks local
+    # 3 primitive calls, 130, 20 and 20 ticks total
+    # including 116, 17, 17 ticks local
+    global ticks
+    if n > 0:
+        ticks += n
+        return mul(n, factorial(n-1))
+    else:
+        ticks += 11
+        return 1
+
+def mul(a, b):
+    # 20 calls
+    # 1 tick, local
+    global ticks
+    ticks += 1
+    return a * b
+
+def helper():
+    # 2 calls
+    # 300 ticks total: 20 ticks local, 260 ticks in subfunctions
+    global ticks
+    ticks += 1
+    helper1()                           # 30
+    ticks += 2
+    helper1()                           # 30
+    ticks += 6
+    helper2()                           # 50
+    ticks += 3
+    helper2()                           # 50
+    ticks += 2
+    helper2()                           # 50
+    ticks += 5
+    helper2_indirect()                  # 70
+    ticks += 1
+
+def helper1():
+    # 4 calls
+    # 30 ticks total: 29 ticks local, 1 tick in subfunctions
+    global ticks
+    ticks += 10
+    hasattr(C(), "foo")                 # 1
+    ticks += 19
+    lst = []
+    lst.append(42)                      # 0
+    sys.exc_info()                      # 0
+
+def helper2_indirect():
+    helper2()                           # 50
+    factorial(3)                        # 20
+
+def helper2():
+    # 8 calls
+    # 50 ticks local: 39 ticks local, 11 ticks in subfunctions
+    global ticks
+    ticks += 11
+    hasattr(C(), "bar")                 # 1
+    ticks += 13
+    subhelper()                         # 10
+    ticks += 15
+
+def subhelper():
+    # 8 calls
+    # 10 ticks total: 8 ticks local, 2 ticks in subfunctions
+    global ticks
+    ticks += 2
+    for i in range(2):                  # 0
+        try:
+            C().foo                     # 1 x 2
+        except AttributeError:
+            ticks += 3                  # 3 x 2
+
+class C:
+    def __getattr__(self, name):
+        # 28 calls
+        # 1 tick, local
+        global ticks
+        ticks += 1
+        raise AttributeError
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_profilehooks.py
===================================================================
--- vendor/Python/current/Lib/test/test_profilehooks.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_profilehooks.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,368 @@
+import pprint
+import sys
+import unittest
+
+from test import test_support
+
+
+class HookWatcher:
+    def __init__(self):
+        self.frames = []
+        self.events = []
+
+    def callback(self, frame, event, arg):
+        if (event == "call"
+            or event == "return"
+            or event == "exception"):
+            self.add_event(event, frame)
+
+    def add_event(self, event, frame=None):
+        """Add an event to the log."""
+        if frame is None:
+            frame = sys._getframe(1)
+
+        try:
+            frameno = self.frames.index(frame)
+        except ValueError:
+            frameno = len(self.frames)
+            self.frames.append(frame)
+
+        self.events.append((frameno, event, ident(frame)))
+
+    def get_events(self):
+        """Remove calls to add_event()."""
+        disallowed = [ident(self.add_event.im_func), ident(ident)]
+        self.frames = None
+
+        return [item for item in self.events if item[2] not in disallowed]
+
+
+class ProfileSimulator(HookWatcher):
+    def __init__(self, testcase):
+        self.testcase = testcase
+        self.stack = []
+        HookWatcher.__init__(self)
+
+    def callback(self, frame, event, arg):
+        # Callback registered with sys.setprofile()/sys.settrace()
+        self.dispatch[event](self, frame)
+
+    def trace_call(self, frame):
+        self.add_event('call', frame)
+        self.stack.append(frame)
+
+    def trace_return(self, frame):
+        self.add_event('return', frame)
+        self.stack.pop()
+
+    def trace_exception(self, frame):
+        self.testcase.fail(
+            "the profiler should never receive exception events")
+
+    def trace_pass(self, frame):
+        pass
+
+    dispatch = {
+        'call': trace_call,
+        'exception': trace_exception,
+        'return': trace_return,
+        'c_call': trace_pass,
+        'c_return': trace_pass,
+        'c_exception': trace_pass,
+        }
+
+
+class TestCaseBase(unittest.TestCase):
+    def check_events(self, callable, expected):
+        events = capture_events(callable, self.new_watcher())
+        if events != expected:
+            self.fail("Expected events:\n%s\nReceived events:\n%s"
+                      % (pprint.pformat(expected), pprint.pformat(events)))
+
+
+class ProfileHookTestCase(TestCaseBase):
+    def new_watcher(self):
+        return HookWatcher()
+
+    def test_simple(self):
+        def f(p):
+            pass
+        f_ident = ident(f)
+        self.check_events(f, [(1, 'call', f_ident),
+                              (1, 'return', f_ident),
+                              ])
+
+    def test_exception(self):
+        def f(p):
+            1/0
+        f_ident = ident(f)
+        self.check_events(f, [(1, 'call', f_ident),
+                              (1, 'return', f_ident),
+                              ])
+
+    def test_caught_exception(self):
+        def f(p):
+            try: 1/0
+            except: pass
+        f_ident = ident(f)
+        self.check_events(f, [(1, 'call', f_ident),
+                              (1, 'return', f_ident),
+                              ])
+
+    def test_caught_nested_exception(self):
+        def f(p):
+            try: 1/0
+            except: pass
+        f_ident = ident(f)
+        self.check_events(f, [(1, 'call', f_ident),
+                              (1, 'return', f_ident),
+                              ])
+
+    def test_nested_exception(self):
+        def f(p):
+            1/0
+        f_ident = ident(f)
+        self.check_events(f, [(1, 'call', f_ident),
+                              # This isn't what I expected:
+                              # (0, 'exception', protect_ident),
+                              # I expected this again:
+                              (1, 'return', f_ident),
+                              ])
+
+    def test_exception_in_except_clause(self):
+        def f(p):
+            1/0
+        def g(p):
+            try:
+                f(p)
+            except:
+                try: f(p)
+                except: pass
+        f_ident = ident(f)
+        g_ident = ident(g)
+        self.check_events(g, [(1, 'call', g_ident),
+                              (2, 'call', f_ident),
+                              (2, 'return', f_ident),
+                              (3, 'call', f_ident),
+                              (3, 'return', f_ident),
+                              (1, 'return', g_ident),
+                              ])
+
+    def test_exception_propogation(self):
+        def f(p):
+            1/0
+        def g(p):
+            try: f(p)
+            finally: p.add_event("falling through")
+        f_ident = ident(f)
+        g_ident = ident(g)
+        self.check_events(g, [(1, 'call', g_ident),
+                              (2, 'call', f_ident),
+                              (2, 'return', f_ident),
+                              (1, 'falling through', g_ident),
+                              (1, 'return', g_ident),
+                              ])
+
+    def test_raise_twice(self):
+        def f(p):
+            try: 1/0
+            except: 1/0
+        f_ident = ident(f)
+        self.check_events(f, [(1, 'call', f_ident),
+                              (1, 'return', f_ident),
+                              ])
+
+    def test_raise_reraise(self):
+        def f(p):
+            try: 1/0
+            except: raise
+        f_ident = ident(f)
+        self.check_events(f, [(1, 'call', f_ident),
+                              (1, 'return', f_ident),
+                              ])
+
+    def test_raise(self):
+        def f(p):
+            raise Exception()
+        f_ident = ident(f)
+        self.check_events(f, [(1, 'call', f_ident),
+                              (1, 'return', f_ident),
+                              ])
+
+    def test_distant_exception(self):
+        def f():
+            1/0
+        def g():
+            f()
+        def h():
+            g()
+        def i():
+            h()
+        def j(p):
+            i()
+        f_ident = ident(f)
+        g_ident = ident(g)
+        h_ident = ident(h)
+        i_ident = ident(i)
+        j_ident = ident(j)
+        self.check_events(j, [(1, 'call', j_ident),
+                              (2, 'call', i_ident),
+                              (3, 'call', h_ident),
+                              (4, 'call', g_ident),
+                              (5, 'call', f_ident),
+                              (5, 'return', f_ident),
+                              (4, 'return', g_ident),
+                              (3, 'return', h_ident),
+                              (2, 'return', i_ident),
+                              (1, 'return', j_ident),
+                              ])
+
+    def test_generator(self):
+        def f():
+            for i in range(2):
+                yield i
+        def g(p):
+            for i in f():
+                pass
+        f_ident = ident(f)
+        g_ident = ident(g)
+        self.check_events(g, [(1, 'call', g_ident),
+                              # call the iterator twice to generate values
+                              (2, 'call', f_ident),
+                              (2, 'return', f_ident),
+                              (2, 'call', f_ident),
+                              (2, 'return', f_ident),
+                              # once more; returns end-of-iteration with
+                              # actually raising an exception
+                              (2, 'call', f_ident),
+                              (2, 'return', f_ident),
+                              (1, 'return', g_ident),
+                              ])
+
+    def test_stop_iteration(self):
+        def f():
+            for i in range(2):
+                yield i
+            raise StopIteration
+        def g(p):
+            for i in f():
+                pass
+        f_ident = ident(f)
+        g_ident = ident(g)
+        self.check_events(g, [(1, 'call', g_ident),
+                              # call the iterator twice to generate values
+                              (2, 'call', f_ident),
+                              (2, 'return', f_ident),
+                              (2, 'call', f_ident),
+                              (2, 'return', f_ident),
+                              # once more to hit the raise:
+                              (2, 'call', f_ident),
+                              (2, 'return', f_ident),
+                              (1, 'return', g_ident),
+                              ])
+
+
+class ProfileSimulatorTestCase(TestCaseBase):
+    def new_watcher(self):
+        return ProfileSimulator(self)
+
+    def test_simple(self):
+        def f(p):
+            pass
+        f_ident = ident(f)
+        self.check_events(f, [(1, 'call', f_ident),
+                              (1, 'return', f_ident),
+                              ])
+
+    def test_basic_exception(self):
+        def f(p):
+            1/0
+        f_ident = ident(f)
+        self.check_events(f, [(1, 'call', f_ident),
+                              (1, 'return', f_ident),
+                              ])
+
+    def test_caught_exception(self):
+        def f(p):
+            try: 1/0
+            except: pass
+        f_ident = ident(f)
+        self.check_events(f, [(1, 'call', f_ident),
+                              (1, 'return', f_ident),
+                              ])
+
+    def test_distant_exception(self):
+        def f():
+            1/0
+        def g():
+            f()
+        def h():
+            g()
+        def i():
+            h()
+        def j(p):
+            i()
+        f_ident = ident(f)
+        g_ident = ident(g)
+        h_ident = ident(h)
+        i_ident = ident(i)
+        j_ident = ident(j)
+        self.check_events(j, [(1, 'call', j_ident),
+                              (2, 'call', i_ident),
+                              (3, 'call', h_ident),
+                              (4, 'call', g_ident),
+                              (5, 'call', f_ident),
+                              (5, 'return', f_ident),
+                              (4, 'return', g_ident),
+                              (3, 'return', h_ident),
+                              (2, 'return', i_ident),
+                              (1, 'return', j_ident),
+                              ])
+
+
+def ident(function):
+    if hasattr(function, "f_code"):
+        code = function.f_code
+    else:
+        code = function.func_code
+    return code.co_firstlineno, code.co_name
+
+
+def protect(f, p):
+    try: f(p)
+    except: pass
+
+protect_ident = ident(protect)
+
+
+def capture_events(callable, p=None):
+    try:
+        sys.setprofile()
+    except TypeError:
+        pass
+    else:
+        raise test_support.TestFailed(
+            'sys.setprofile() did not raise TypeError')
+
+    if p is None:
+        p = HookWatcher()
+    sys.setprofile(p.callback)
+    protect(callable, p)
+    sys.setprofile(None)
+    return p.get_events()[1:-1]
+
+
+def show_events(callable):
+    import pprint
+    pprint.pprint(capture_events(callable))
+
+
+def test_main():
+    test_support.run_unittest(
+        ProfileHookTestCase,
+        ProfileSimulatorTestCase
+    )
+
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_pty.py
===================================================================
--- vendor/Python/current/Lib/test/test_pty.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_pty.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,147 @@
+import pty, os, sys, signal
+from test.test_support import verbose, TestFailed, TestSkipped
+
+TEST_STRING_1 = "I wish to buy a fish license.\n"
+TEST_STRING_2 = "For my pet fish, Eric.\n"
+
+if verbose:
+    def debug(msg):
+        print msg
+else:
+    def debug(msg):
+        pass
+
+def normalize_output(data):
+    # Some operating systems do conversions on newline.  We could possibly
+    # fix that by doing the appropriate termios.tcsetattr()s.  I couldn't
+    # figure out the right combo on Tru64 and I don't have an IRIX box.
+    # So just normalize the output and doc the problem O/Ses by allowing
+    # certain combinations for some platforms, but avoid allowing other
+    # differences (like extra whitespace, trailing garbage, etc.)
+
+    # This is about the best we can do without getting some feedback
+    # from someone more knowledgable.
+
+    # OSF/1 (Tru64) apparently turns \n into \r\r\n.
+    if data.endswith('\r\r\n'):
+        return data.replace('\r\r\n', '\n')
+
+    # IRIX apparently turns \n into \r\n.
+    if data.endswith('\r\n'):
+        return data.replace('\r\n', '\n')
+
+    return data
+
+# Marginal testing of pty suite. Cannot do extensive 'do or fail' testing
+# because pty code is not too portable.
+
+def test_basic_pty():
+    try:
+        debug("Calling master_open()")
+        master_fd, slave_name = pty.master_open()
+        debug("Got master_fd '%d', slave_name '%s'"%(master_fd, slave_name))
+        debug("Calling slave_open(%r)"%(slave_name,))
+        slave_fd = pty.slave_open(slave_name)
+        debug("Got slave_fd '%d'"%slave_fd)
+    except OSError:
+        # " An optional feature could not be imported " ... ?
+        raise TestSkipped, "Pseudo-terminals (seemingly) not functional."
+
+    if not os.isatty(slave_fd):
+        raise TestFailed, "slave_fd is not a tty"
+
+    debug("Writing to slave_fd")
+    os.write(slave_fd, TEST_STRING_1)
+    s1 = os.read(master_fd, 1024)
+    sys.stdout.write(normalize_output(s1))
+
+    debug("Writing chunked output")
+    os.write(slave_fd, TEST_STRING_2[:5])
+    os.write(slave_fd, TEST_STRING_2[5:])
+    s2 = os.read(master_fd, 1024)
+    sys.stdout.write(normalize_output(s2))
+
+    os.close(slave_fd)
+    os.close(master_fd)
+
+def handle_sig(sig, frame):
+    raise TestFailed, "isatty hung"
+
+# isatty() and close() can hang on some platforms
+# set an alarm before running the test to make sure we don't hang forever
+old_alarm = signal.signal(signal.SIGALRM, handle_sig)
+signal.alarm(10)
+
+try:
+    test_basic_pty()
+finally:
+    # remove alarm, restore old alarm handler
+    signal.alarm(0)
+    signal.signal(signal.SIGALRM, old_alarm)
+
+# basic pty passed.
+
+debug("calling pty.fork()")
+pid, master_fd = pty.fork()
+if pid == pty.CHILD:
+    # stdout should be connected to a tty.
+    if not os.isatty(1):
+        debug("Child's fd 1 is not a tty?!")
+        os._exit(3)
+
+    # After pty.fork(), the child should already be a session leader.
+    # (on those systems that have that concept.)
+    debug("In child, calling os.setsid()")
+    try:
+        os.setsid()
+    except OSError:
+        # Good, we already were session leader
+        debug("Good: OSError was raised.")
+        pass
+    except AttributeError:
+        # Have pty, but not setsid() ?
+        debug("No setsid() available ?")
+        pass
+    except:
+        # We don't want this error to propagate, escaping the call to
+        # os._exit() and causing very peculiar behavior in the calling
+        # regrtest.py !
+        # Note: could add traceback printing here.
+        debug("An unexpected error was raised.")
+        os._exit(1)
+    else:
+        debug("os.setsid() succeeded! (bad!)")
+        os._exit(2)
+    os._exit(4)
+else:
+    debug("Waiting for child (%d) to finish."%pid)
+    ##line = os.read(master_fd, 80)
+    ##lines = line.replace('\r\n', '\n').split('\n')
+    ##if False and lines != ['In child, calling os.setsid()',
+    ##             'Good: OSError was raised.', '']:
+    ##    raise TestFailed("Unexpected output from child: %r" % line)
+
+    (pid, status) = os.waitpid(pid, 0)
+    res = status >> 8
+    debug("Child (%d) exited with status %d (%d)."%(pid, res, status))
+    if res == 1:
+        raise TestFailed, "Child raised an unexpected exception in os.setsid()"
+    elif res == 2:
+        raise TestFailed, "pty.fork() failed to make child a session leader."
+    elif res == 3:
+        raise TestFailed, "Child spawned by pty.fork() did not have a tty as stdout"
+    elif res != 4:
+        raise TestFailed, "pty.fork() failed for unknown reasons."
+
+    ##debug("Reading from master_fd now that the child has exited")
+    ##try:
+    ##    s1 = os.read(master_fd, 1024)
+    ##except os.error:
+    ##    pass
+    ##else:
+    ##    raise TestFailed("Read from master_fd did not raise exception")
+
+
+os.close(master_fd)
+
+# pty.fork() passed.

Added: vendor/Python/current/Lib/test/test_pwd.py
===================================================================
--- vendor/Python/current/Lib/test/test_pwd.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_pwd.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,94 @@
+import unittest
+from test import test_support
+
+import pwd
+
+class PwdTest(unittest.TestCase):
+
+    def test_values(self):
+        entries = pwd.getpwall()
+        entriesbyname = {}
+        entriesbyuid = {}
+
+        for e in entries:
+            self.assertEqual(len(e), 7)
+            self.assertEqual(e[0], e.pw_name)
+            self.assert_(isinstance(e.pw_name, basestring))
+            self.assertEqual(e[1], e.pw_passwd)
+            self.assert_(isinstance(e.pw_passwd, basestring))
+            self.assertEqual(e[2], e.pw_uid)
+            self.assert_(isinstance(e.pw_uid, int))
+            self.assertEqual(e[3], e.pw_gid)
+            self.assert_(isinstance(e.pw_gid, int))
+            self.assertEqual(e[4], e.pw_gecos)
+            self.assert_(isinstance(e.pw_gecos, basestring))
+            self.assertEqual(e[5], e.pw_dir)
+            self.assert_(isinstance(e.pw_dir, basestring))
+            self.assertEqual(e[6], e.pw_shell)
+            self.assert_(isinstance(e.pw_shell, basestring))
+
+            # The following won't work, because of duplicate entries
+            # for one uid
+            #    self.assertEqual(pwd.getpwuid(e.pw_uid), e)
+            # instead of this collect all entries for one uid
+            # and check afterwards
+            entriesbyname.setdefault(e.pw_name, []).append(e)
+            entriesbyuid.setdefault(e.pw_uid, []).append(e)
+
+        # check whether the entry returned by getpwuid()
+        # for each uid is among those from getpwall() for this uid
+        for e in entries:
+            if not e[0] or e[0] == '+':
+                continue # skip NIS entries etc.
+            self.assert_(pwd.getpwnam(e.pw_name) in entriesbyname[e.pw_name])
+            self.assert_(pwd.getpwuid(e.pw_uid) in entriesbyuid[e.pw_uid])
+
+    def test_errors(self):
+        self.assertRaises(TypeError, pwd.getpwuid)
+        self.assertRaises(TypeError, pwd.getpwnam)
+        self.assertRaises(TypeError, pwd.getpwall, 42)
+
+        # try to get some errors
+        bynames = {}
+        byuids = {}
+        for (n, p, u, g, gecos, d, s) in pwd.getpwall():
+            bynames[n] = u
+            byuids[u] = n
+
+        allnames = bynames.keys()
+        namei = 0
+        fakename = allnames[namei]
+        while fakename in bynames:
+            chars = map(None, fakename)
+            for i in xrange(len(chars)):
+                if chars[i] == 'z':
+                    chars[i] = 'A'
+                    break
+                elif chars[i] == 'Z':
+                    continue
+                else:
+                    chars[i] = chr(ord(chars[i]) + 1)
+                    break
+            else:
+                namei = namei + 1
+                try:
+                    fakename = allnames[namei]
+                except IndexError:
+                    # should never happen... if so, just forget it
+                    break
+            fakename = ''.join(map(None, chars))
+
+        self.assertRaises(KeyError, pwd.getpwnam, fakename)
+
+        # Choose a non-existent uid.
+        fakeuid = 4127
+        while fakeuid in byuids:
+            fakeuid = (fakeuid * 3) % 0x10000
+
+        self.assertRaises(KeyError, pwd.getpwuid, fakeuid)
+
+def test_main():
+    test_support.run_unittest(PwdTest)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_pyclbr.py
===================================================================
--- vendor/Python/current/Lib/test/test_pyclbr.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_pyclbr.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,188 @@
+'''
+   Test cases for pyclbr.py
+   Nick Mathewson
+'''
+from test.test_support import run_unittest
+import unittest, sys
+from types import ClassType, FunctionType, MethodType, BuiltinFunctionType
+import pyclbr
+from unittest import TestCase
+
+StaticMethodType = type(staticmethod(lambda: None))
+ClassMethodType = type(classmethod(lambda c: None))
+
+# This next line triggers an error on old versions of pyclbr.
+
+from commands import getstatus
+
+# Here we test the python class browser code.
+#
+# The main function in this suite, 'testModule', compares the output
+# of pyclbr with the introspected members of a module.  Because pyclbr
+# is imperfect (as designed), testModule is called with a set of
+# members to ignore.
+
+class PyclbrTest(TestCase):
+
+    def assertListEq(self, l1, l2, ignore):
+        ''' succeed iff {l1} - {ignore} == {l2} - {ignore} '''
+        missing = (set(l1) ^ set(l2)) - set(ignore)
+        if missing:
+            print >>sys.stderr, "l1=%r\nl2=%r\nignore=%r" % (l1, l2, ignore)
+            self.fail("%r missing" % missing.pop())
+
+    def assertHasattr(self, obj, attr, ignore):
+        ''' succeed iff hasattr(obj,attr) or attr in ignore. '''
+        if attr in ignore: return
+        if not hasattr(obj, attr): print "???", attr
+        self.failUnless(hasattr(obj, attr),
+                        'expected hasattr(%r, %r)' % (obj, attr))
+
+
+    def assertHaskey(self, obj, key, ignore):
+        ''' succeed iff obj.has_key(key) or key in ignore. '''
+        if key in ignore: return
+        if not obj.has_key(key):
+            print >>sys.stderr, "***",key
+        self.failUnless(obj.has_key(key))
+
+    def assertEqualsOrIgnored(self, a, b, ignore):
+        ''' succeed iff a == b or a in ignore or b in ignore '''
+        if a not in ignore and b not in ignore:
+            self.assertEquals(a, b)
+
+    def checkModule(self, moduleName, module=None, ignore=()):
+        ''' succeed iff pyclbr.readmodule_ex(modulename) corresponds
+            to the actual module object, module.  Any identifiers in
+            ignore are ignored.   If no module is provided, the appropriate
+            module is loaded with __import__.'''
+
+        if module == None:
+            # Import it.
+            # ('<silly>' is to work around an API silliness in __import__)
+            module = __import__(moduleName, globals(), {}, ['<silly>'])
+
+        dict = pyclbr.readmodule_ex(moduleName)
+
+        def ismethod(oclass, obj, name):
+            classdict = oclass.__dict__
+            if isinstance(obj, FunctionType):
+                if not isinstance(classdict[name], StaticMethodType):
+                    return False
+            else:
+                if not  isinstance(obj, MethodType):
+                    return False
+                if obj.im_self is not None:
+                    if (not isinstance(classdict[name], ClassMethodType) or
+                        obj.im_self is not oclass):
+                        return False
+                else:
+                    if not isinstance(classdict[name], FunctionType):
+                        return False
+
+            objname = obj.__name__
+            if objname.startswith("__") and not objname.endswith("__"):
+                objname = "_%s%s" % (obj.im_class.__name__, objname)
+            return objname == name
+
+        # Make sure the toplevel functions and classes are the same.
+        for name, value in dict.items():
+            if name in ignore:
+                continue
+            self.assertHasattr(module, name, ignore)
+            py_item = getattr(module, name)
+            if isinstance(value, pyclbr.Function):
+                self.assert_(isinstance(py_item, (FunctionType, BuiltinFunctionType)))
+                if py_item.__module__ != moduleName:
+                    continue   # skip functions that came from somewhere else
+                self.assertEquals(py_item.__module__, value.module)
+            else:
+                self.failUnless(isinstance(py_item, (ClassType, type)))
+                if py_item.__module__ != moduleName:
+                    continue   # skip classes that came from somewhere else
+
+                real_bases = [base.__name__ for base in py_item.__bases__]
+                pyclbr_bases = [ getattr(base, 'name', base)
+                                 for base in value.super ]
+
+                try:
+                    self.assertListEq(real_bases, pyclbr_bases, ignore)
+                except:
+                    print >>sys.stderr, "class=%s" % py_item
+                    raise
+
+                actualMethods = []
+                for m in py_item.__dict__.keys():
+                    if ismethod(py_item, getattr(py_item, m), m):
+                        actualMethods.append(m)
+                foundMethods = []
+                for m in value.methods.keys():
+                    if m[:2] == '__' and m[-2:] != '__':
+                        foundMethods.append('_'+name+m)
+                    else:
+                        foundMethods.append(m)
+
+                try:
+                    self.assertListEq(foundMethods, actualMethods, ignore)
+                    self.assertEquals(py_item.__module__, value.module)
+
+                    self.assertEqualsOrIgnored(py_item.__name__, value.name,
+                                               ignore)
+                    # can't check file or lineno
+                except:
+                    print >>sys.stderr, "class=%s" % py_item
+                    raise
+
+        # Now check for missing stuff.
+        def defined_in(item, module):
+            if isinstance(item, ClassType):
+                return item.__module__ == module.__name__
+            if isinstance(item, FunctionType):
+                return item.func_globals is module.__dict__
+            return False
+        for name in dir(module):
+            item = getattr(module, name)
+            if isinstance(item,  (ClassType, FunctionType)):
+                if defined_in(item, module):
+                    self.assertHaskey(dict, name, ignore)
+
+    def test_easy(self):
+        self.checkModule('pyclbr')
+        self.checkModule('doctest')
+        self.checkModule('rfc822')
+        self.checkModule('difflib')
+
+    def test_decorators(self):
+        # XXX: See comment in pyclbr_input.py for a test that would fail
+        #      if it were not commented out.
+        #
+        self.checkModule('test.pyclbr_input')
+
+    def test_others(self):
+        cm = self.checkModule
+
+        # These were once about the 10 longest modules
+        cm('random', ignore=('Random',))  # from _random import Random as CoreGenerator
+        cm('cgi', ignore=('log',))      # set with = in module
+        cm('mhlib')
+        cm('urllib', ignore=('getproxies_registry',
+                             'open_https',
+                             'getproxies_internetconfig',)) # not on all platforms
+        cm('pickle')
+        cm('aifc', ignore=('openfp',))  # set with = in module
+        cm('Cookie')
+        cm('sre_parse', ignore=('dump',)) # from sre_constants import *
+        cm('pdb')
+        cm('pydoc')
+
+        # Tests for modules inside packages
+        cm('email.parser')
+        cm('test.test_pyclbr')
+
+
+def test_main():
+    run_unittest(PyclbrTest)
+
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_pyexpat.py
===================================================================
--- vendor/Python/current/Lib/test/test_pyexpat.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_pyexpat.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,388 @@
+# Very simple test - Parse a file and print what happens
+
+# XXX TypeErrors on calling handlers, or on bad return values from a
+# handler, are obscure and unhelpful.
+
+import pyexpat
+from xml.parsers import expat
+
+from test.test_support import sortdict, TestFailed
+
+class Outputter:
+    def StartElementHandler(self, name, attrs):
+        print 'Start element:\n\t', repr(name), sortdict(attrs)
+
+    def EndElementHandler(self, name):
+        print 'End element:\n\t', repr(name)
+
+    def CharacterDataHandler(self, data):
+        data = data.strip()
+        if data:
+            print 'Character data:'
+            print '\t', repr(data)
+
+    def ProcessingInstructionHandler(self, target, data):
+        print 'PI:\n\t', repr(target), repr(data)
+
+    def StartNamespaceDeclHandler(self, prefix, uri):
+        print 'NS decl:\n\t', repr(prefix), repr(uri)
+
+    def EndNamespaceDeclHandler(self, prefix):
+        print 'End of NS decl:\n\t', repr(prefix)
+
+    def StartCdataSectionHandler(self):
+        print 'Start of CDATA section'
+
+    def EndCdataSectionHandler(self):
+        print 'End of CDATA section'
+
+    def CommentHandler(self, text):
+        print 'Comment:\n\t', repr(text)
+
+    def NotationDeclHandler(self, *args):
+        name, base, sysid, pubid = args
+        print 'Notation declared:', args
+
+    def UnparsedEntityDeclHandler(self, *args):
+        entityName, base, systemId, publicId, notationName = args
+        print 'Unparsed entity decl:\n\t', args
+
+    def NotStandaloneHandler(self, userData):
+        print 'Not standalone'
+        return 1
+
+    def ExternalEntityRefHandler(self, *args):
+        context, base, sysId, pubId = args
+        print 'External entity ref:', args[1:]
+        return 1
+
+    def DefaultHandler(self, userData):
+        pass
+
+    def DefaultHandlerExpand(self, userData):
+        pass
+
+
+def confirm(ok):
+    if ok:
+        print "OK."
+    else:
+        print "Not OK."
+
+out = Outputter()
+parser = expat.ParserCreate(namespace_separator='!')
+
+# Test getting/setting returns_unicode
+parser.returns_unicode = 0; confirm(parser.returns_unicode == 0)
+parser.returns_unicode = 1; confirm(parser.returns_unicode == 1)
+parser.returns_unicode = 2; confirm(parser.returns_unicode == 1)
+parser.returns_unicode = 0; confirm(parser.returns_unicode == 0)
+
+# Test getting/setting ordered_attributes
+parser.ordered_attributes = 0; confirm(parser.ordered_attributes == 0)
+parser.ordered_attributes = 1; confirm(parser.ordered_attributes == 1)
+parser.ordered_attributes = 2; confirm(parser.ordered_attributes == 1)
+parser.ordered_attributes = 0; confirm(parser.ordered_attributes == 0)
+
+# Test getting/setting specified_attributes
+parser.specified_attributes = 0; confirm(parser.specified_attributes == 0)
+parser.specified_attributes = 1; confirm(parser.specified_attributes == 1)
+parser.specified_attributes = 2; confirm(parser.specified_attributes == 1)
+parser.specified_attributes = 0; confirm(parser.specified_attributes == 0)
+
+HANDLER_NAMES = [
+    'StartElementHandler', 'EndElementHandler',
+    'CharacterDataHandler', 'ProcessingInstructionHandler',
+    'UnparsedEntityDeclHandler', 'NotationDeclHandler',
+    'StartNamespaceDeclHandler', 'EndNamespaceDeclHandler',
+    'CommentHandler', 'StartCdataSectionHandler',
+    'EndCdataSectionHandler',
+    'DefaultHandler', 'DefaultHandlerExpand',
+    #'NotStandaloneHandler',
+    'ExternalEntityRefHandler'
+    ]
+for name in HANDLER_NAMES:
+    setattr(parser, name, getattr(out, name))
+
+data = '''\
+<?xml version="1.0" encoding="iso-8859-1" standalone="no"?>
+<?xml-stylesheet href="stylesheet.css"?>
+<!-- comment data -->
+<!DOCTYPE quotations SYSTEM "quotations.dtd" [
+<!ELEMENT root ANY>
+<!NOTATION notation SYSTEM "notation.jpeg">
+<!ENTITY acirc "&#226;">
+<!ENTITY external_entity SYSTEM "entity.file">
+<!ENTITY unparsed_entity SYSTEM "entity.file" NDATA notation>
+%unparsed_entity;
+]>
+
+<root attr1="value1" attr2="value2&#8000;">
+<myns:subelement xmlns:myns="http://www.python.org/namespace">
+     Contents of subelements
+</myns:subelement>
+<sub2><![CDATA[contents of CDATA section]]></sub2>
+&external_entity;
+</root>
+'''
+
+# Produce UTF-8 output
+parser.returns_unicode = 0
+try:
+    parser.Parse(data, 1)
+except expat.error:
+    print '** Error', parser.ErrorCode, expat.ErrorString(parser.ErrorCode)
+    print '** Line', parser.ErrorLineNumber
+    print '** Column', parser.ErrorColumnNumber
+    print '** Byte', parser.ErrorByteIndex
+
+# Try the parse again, this time producing Unicode output
+parser = expat.ParserCreate(namespace_separator='!')
+parser.returns_unicode = 1
+
+for name in HANDLER_NAMES:
+    setattr(parser, name, getattr(out, name))
+try:
+    parser.Parse(data, 1)
+except expat.error:
+    print '** Error', parser.ErrorCode, expat.ErrorString(parser.ErrorCode)
+    print '** Line', parser.ErrorLineNumber
+    print '** Column', parser.ErrorColumnNumber
+    print '** Byte', parser.ErrorByteIndex
+
+# Try parsing a file
+parser = expat.ParserCreate(namespace_separator='!')
+parser.returns_unicode = 1
+
+for name in HANDLER_NAMES:
+    setattr(parser, name, getattr(out, name))
+import StringIO
+file = StringIO.StringIO(data)
+try:
+    parser.ParseFile(file)
+except expat.error:
+    print '** Error', parser.ErrorCode, expat.ErrorString(parser.ErrorCode)
+    print '** Line', parser.ErrorLineNumber
+    print '** Column', parser.ErrorColumnNumber
+    print '** Byte', parser.ErrorByteIndex
+
+
+# Tests that make sure we get errors when the namespace_separator value
+# is illegal, and that we don't for good values:
+print
+print "Testing constructor for proper handling of namespace_separator values:"
+expat.ParserCreate()
+expat.ParserCreate(namespace_separator=None)
+expat.ParserCreate(namespace_separator=' ')
+print "Legal values tested o.k."
+try:
+    expat.ParserCreate(namespace_separator=42)
+except TypeError, e:
+    print "Caught expected TypeError:"
+    print e
+else:
+    print "Failed to catch expected TypeError."
+
+try:
+    expat.ParserCreate(namespace_separator='too long')
+except ValueError, e:
+    print "Caught expected ValueError:"
+    print e
+else:
+    print "Failed to catch expected ValueError."
+
+# ParserCreate() needs to accept a namespace_separator of zero length
+# to satisfy the requirements of RDF applications that are required
+# to simply glue together the namespace URI and the localname.  Though
+# considered a wart of the RDF specifications, it needs to be supported.
+#
+# See XML-SIG mailing list thread starting with
+# http://mail.python.org/pipermail/xml-sig/2001-April/005202.html
+#
+expat.ParserCreate(namespace_separator='') # too short
+
+# Test the interning machinery.
+p = expat.ParserCreate()
+L = []
+def collector(name, *args):
+    L.append(name)
+p.StartElementHandler = collector
+p.EndElementHandler = collector
+p.Parse("<e> <e/> <e></e> </e>", 1)
+tag = L[0]
+if len(L) != 6:
+    print "L should only contain 6 entries; found", len(L)
+for entry in L:
+    if tag is not entry:
+        print "expected L to contain many references to the same string",
+        print "(it didn't)"
+        print "L =", repr(L)
+        break
+
+# Tests of the buffer_text attribute.
+import sys
+
+class TextCollector:
+    def __init__(self, parser):
+        self.stuff = []
+
+    def check(self, expected, label):
+        require(self.stuff == expected,
+                "%s\nstuff    = %r\nexpected = %r"
+                % (label, self.stuff, map(unicode, expected)))
+
+    def CharacterDataHandler(self, text):
+        self.stuff.append(text)
+
+    def StartElementHandler(self, name, attrs):
+        self.stuff.append("<%s>" % name)
+        bt = attrs.get("buffer-text")
+        if bt == "yes":
+            parser.buffer_text = 1
+        elif bt == "no":
+            parser.buffer_text = 0
+
+    def EndElementHandler(self, name):
+        self.stuff.append("</%s>" % name)
+
+    def CommentHandler(self, data):
+        self.stuff.append("<!--%s-->" % data)
+
+def require(cond, label):
+    # similar to confirm(), but no extraneous output
+    if not cond:
+        raise TestFailed(label)
+
+def setup(handlers=[]):
+    parser = expat.ParserCreate()
+    require(not parser.buffer_text,
+            "buffer_text not disabled by default")
+    parser.buffer_text = 1
+    handler = TextCollector(parser)
+    parser.CharacterDataHandler = handler.CharacterDataHandler
+    for name in handlers:
+        setattr(parser, name, getattr(handler, name))
+    return parser, handler
+
+parser, handler = setup()
+require(parser.buffer_text,
+        "text buffering either not acknowledged or not enabled")
+parser.Parse("<a>1<b/>2<c/>3</a>", 1)
+handler.check(["123"],
+              "buffered text not properly collapsed")
+
+# XXX This test exposes more detail of Expat's text chunking than we
+# XXX like, but it tests what we need to concisely.
+parser, handler = setup(["StartElementHandler"])
+parser.Parse("<a>1<b buffer-text='no'/>2\n3<c buffer-text='yes'/>4\n5</a>", 1)
+handler.check(["<a>", "1", "<b>", "2", "\n", "3", "<c>", "4\n5"],
+              "buffering control not reacting as expected")
+
+parser, handler = setup()
+parser.Parse("<a>1<b/>&lt;2&gt;<c/>&#32;\n&#x20;3</a>", 1)
+handler.check(["1<2> \n 3"],
+              "buffered text not properly collapsed")
+
+parser, handler = setup(["StartElementHandler"])
+parser.Parse("<a>1<b/>2<c/>3</a>", 1)
+handler.check(["<a>", "1", "<b>", "2", "<c>", "3"],
+              "buffered text not properly split")
+
+parser, handler = setup(["StartElementHandler", "EndElementHandler"])
+parser.CharacterDataHandler = None
+parser.Parse("<a>1<b/>2<c/>3</a>", 1)
+handler.check(["<a>", "<b>", "</b>", "<c>", "</c>", "</a>"],
+              "huh?")
+
+parser, handler = setup(["StartElementHandler", "EndElementHandler"])
+parser.Parse("<a>1<b></b>2<c/>3</a>", 1)
+handler.check(["<a>", "1", "<b>", "</b>", "2", "<c>", "</c>", "3", "</a>"],
+              "huh?")
+
+parser, handler = setup(["CommentHandler", "EndElementHandler",
+                         "StartElementHandler"])
+parser.Parse("<a>1<b/>2<c></c>345</a> ", 1)
+handler.check(["<a>", "1", "<b>", "</b>", "2", "<c>", "</c>", "345", "</a>"],
+              "buffered text not properly split")
+
+parser, handler = setup(["CommentHandler", "EndElementHandler",
+                         "StartElementHandler"])
+parser.Parse("<a>1<b/>2<c></c>3<!--abc-->4<!--def-->5</a> ", 1)
+handler.check(["<a>", "1", "<b>", "</b>", "2", "<c>", "</c>", "3",
+               "<!--abc-->", "4", "<!--def-->", "5", "</a>"],
+              "buffered text not properly split")
+
+# Test handling of exception from callback:
+def StartElementHandler(name, attrs):
+    raise RuntimeError(name)
+
+parser = expat.ParserCreate()
+parser.StartElementHandler = StartElementHandler
+
+try:
+    parser.Parse("<a><b><c/></b></a>", 1)
+except RuntimeError, e:
+    if e.args[0] != "a":
+        print "Expected RuntimeError for element 'a'; found %r" % e.args[0]
+else:
+    print "Expected RuntimeError for 'a'"
+
+# Test Current* members:
+class PositionTest:
+
+    def __init__(self, expected_list, parser):
+        self.parser = parser
+        self.parser.StartElementHandler = self.StartElementHandler
+        self.parser.EndElementHandler = self.EndElementHandler
+        self.expected_list = expected_list
+        self.upto = 0
+
+    def StartElementHandler(self, name, attrs):
+        self.check_pos('s')
+
+    def EndElementHandler(self, name):
+        self.check_pos('e')
+
+    def check_pos(self, event):
+        pos = (event,
+               self.parser.CurrentByteIndex,
+               self.parser.CurrentLineNumber,
+               self.parser.CurrentColumnNumber)
+        require(self.upto < len(self.expected_list),
+                'too many parser events')
+        expected = self.expected_list[self.upto]
+        require(pos == expected,
+                'expected position %s, got %s' % (expected, pos))
+        self.upto += 1
+
+
+parser = expat.ParserCreate()
+handler = PositionTest([('s', 0, 1, 0), ('s', 5, 2, 1), ('s', 11, 3, 2),
+                        ('e', 15, 3, 6), ('e', 17, 4, 1), ('e', 22, 5, 0)],
+                       parser)
+parser.Parse('''<a>
+ <b>
+  <c/>
+ </b>
+</a>''', 1)
+
+
+def test_parse_only_xml_data():
+    # http://python.org/sf/1296433
+    #
+    xml = "<?xml version='1.0' encoding='iso8859'?><s>%s</s>" % ('a' * 1025)
+    # this one doesn't crash
+    #xml = "<?xml version='1.0'?><s>%s</s>" % ('a' * 10000)
+
+    def handler(text):
+        raise Exception
+
+    parser = expat.ParserCreate()
+    parser.CharacterDataHandler = handler
+
+    try:
+        parser.Parse(xml)
+    except:
+        pass
+
+test_parse_only_xml_data()

Added: vendor/Python/current/Lib/test/test_queue.py
===================================================================
--- vendor/Python/current/Lib/test/test_queue.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_queue.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,281 @@
+# Some simple Queue module tests, plus some failure conditions
+# to ensure the Queue locks remain stable.
+import Queue
+import sys
+import threading
+import time
+
+from test.test_support import verify, TestFailed, verbose
+
+QUEUE_SIZE = 5
+
+# A thread to run a function that unclogs a blocked Queue.
+class _TriggerThread(threading.Thread):
+    def __init__(self, fn, args):
+        self.fn = fn
+        self.args = args
+        self.startedEvent = threading.Event()
+        threading.Thread.__init__(self)
+
+    def run(self):
+        # The sleep isn't necessary, but is intended to give the blocking
+        # function in the main thread a chance at actually blocking before
+        # we unclog it.  But if the sleep is longer than the timeout-based
+        # tests wait in their blocking functions, those tests will fail.
+        # So we give them much longer timeout values compared to the
+        # sleep here (I aimed at 10 seconds for blocking functions --
+        # they should never actually wait that long - they should make
+        # progress as soon as we call self.fn()).
+        time.sleep(0.1)
+        self.startedEvent.set()
+        self.fn(*self.args)
+
+# Execute a function that blocks, and in a separate thread, a function that
+# triggers the release.  Returns the result of the blocking function.
+# Caution:  block_func must guarantee to block until trigger_func is
+# called, and trigger_func must guarantee to change queue state so that
+# block_func can make enough progress to return.  In particular, a
+# block_func that just raises an exception regardless of whether trigger_func
+# is called will lead to timing-dependent sporadic failures, and one of
+# those went rarely seen but undiagnosed for years.  Now block_func
+# must be unexceptional.  If block_func is supposed to raise an exception,
+# call _doExceptionalBlockingTest() instead.
+def _doBlockingTest(block_func, block_args, trigger_func, trigger_args):
+    t = _TriggerThread(trigger_func, trigger_args)
+    t.start()
+    result = block_func(*block_args)
+    # If block_func returned before our thread made the call, we failed!
+    if not t.startedEvent.isSet():
+        raise TestFailed("blocking function '%r' appeared not to block" %
+                         block_func)
+    t.join(10) # make sure the thread terminates
+    if t.isAlive():
+        raise TestFailed("trigger function '%r' appeared to not return" %
+                         trigger_func)
+    return result
+
+# Call this instead if block_func is supposed to raise an exception.
+def _doExceptionalBlockingTest(block_func, block_args, trigger_func,
+                               trigger_args, expected_exception_class):
+    t = _TriggerThread(trigger_func, trigger_args)
+    t.start()
+    try:
+        try:
+            block_func(*block_args)
+        except expected_exception_class:
+            raise
+        else:
+            raise TestFailed("expected exception of kind %r" %
+                             expected_exception_class)
+    finally:
+        t.join(10) # make sure the thread terminates
+        if t.isAlive():
+            raise TestFailed("trigger function '%r' appeared to not return" %
+                             trigger_func)
+        if not t.startedEvent.isSet():
+            raise TestFailed("trigger thread ended but event never set")
+
+# A Queue subclass that can provoke failure at a moment's notice :)
+class FailingQueueException(Exception):
+    pass
+
+class FailingQueue(Queue.Queue):
+    def __init__(self, *args):
+        self.fail_next_put = False
+        self.fail_next_get = False
+        Queue.Queue.__init__(self, *args)
+    def _put(self, item):
+        if self.fail_next_put:
+            self.fail_next_put = False
+            raise FailingQueueException, "You Lose"
+        return Queue.Queue._put(self, item)
+    def _get(self):
+        if self.fail_next_get:
+            self.fail_next_get = False
+            raise FailingQueueException, "You Lose"
+        return Queue.Queue._get(self)
+
+def FailingQueueTest(q):
+    if not q.empty():
+        raise RuntimeError, "Call this function with an empty queue"
+    for i in range(QUEUE_SIZE-1):
+        q.put(i)
+    # Test a failing non-blocking put.
+    q.fail_next_put = True
+    try:
+        q.put("oops", block=0)
+        raise TestFailed("The queue didn't fail when it should have")
+    except FailingQueueException:
+        pass
+    q.fail_next_put = True
+    try:
+        q.put("oops", timeout=0.1)
+        raise TestFailed("The queue didn't fail when it should have")
+    except FailingQueueException:
+        pass
+    q.put("last")
+    verify(q.full(), "Queue should be full")
+    # Test a failing blocking put
+    q.fail_next_put = True
+    try:
+        _doBlockingTest(q.put, ("full",), q.get, ())
+        raise TestFailed("The queue didn't fail when it should have")
+    except FailingQueueException:
+        pass
+    # Check the Queue isn't damaged.
+    # put failed, but get succeeded - re-add
+    q.put("last")
+    # Test a failing timeout put
+    q.fail_next_put = True
+    try:
+        _doExceptionalBlockingTest(q.put, ("full", True, 10), q.get, (),
+                                   FailingQueueException)
+        raise TestFailed("The queue didn't fail when it should have")
+    except FailingQueueException:
+        pass
+    # Check the Queue isn't damaged.
+    # put failed, but get succeeded - re-add
+    q.put("last")
+    verify(q.full(), "Queue should be full")
+    q.get()
+    verify(not q.full(), "Queue should not be full")
+    q.put("last")
+    verify(q.full(), "Queue should be full")
+    # Test a blocking put
+    _doBlockingTest( q.put, ("full",), q.get, ())
+    # Empty it
+    for i in range(QUEUE_SIZE):
+        q.get()
+    verify(q.empty(), "Queue should be empty")
+    q.put("first")
+    q.fail_next_get = True
+    try:
+        q.get()
+        raise TestFailed("The queue didn't fail when it should have")
+    except FailingQueueException:
+        pass
+    verify(not q.empty(), "Queue should not be empty")
+    q.fail_next_get = True
+    try:
+        q.get(timeout=0.1)
+        raise TestFailed("The queue didn't fail when it should have")
+    except FailingQueueException:
+        pass
+    verify(not q.empty(), "Queue should not be empty")
+    q.get()
+    verify(q.empty(), "Queue should be empty")
+    q.fail_next_get = True
+    try:
+        _doExceptionalBlockingTest(q.get, (), q.put, ('empty',),
+                                   FailingQueueException)
+        raise TestFailed("The queue didn't fail when it should have")
+    except FailingQueueException:
+        pass
+    # put succeeded, but get failed.
+    verify(not q.empty(), "Queue should not be empty")
+    q.get()
+    verify(q.empty(), "Queue should be empty")
+
+def SimpleQueueTest(q):
+    if not q.empty():
+        raise RuntimeError, "Call this function with an empty queue"
+    # I guess we better check things actually queue correctly a little :)
+    q.put(111)
+    q.put(222)
+    verify(q.get() == 111 and q.get() == 222,
+           "Didn't seem to queue the correct data!")
+    for i in range(QUEUE_SIZE-1):
+        q.put(i)
+        verify(not q.empty(), "Queue should not be empty")
+    verify(not q.full(), "Queue should not be full")
+    q.put("last")
+    verify(q.full(), "Queue should be full")
+    try:
+        q.put("full", block=0)
+        raise TestFailed("Didn't appear to block with a full queue")
+    except Queue.Full:
+        pass
+    try:
+        q.put("full", timeout=0.01)
+        raise TestFailed("Didn't appear to time-out with a full queue")
+    except Queue.Full:
+        pass
+    # Test a blocking put
+    _doBlockingTest(q.put, ("full",), q.get, ())
+    _doBlockingTest(q.put, ("full", True, 10), q.get, ())
+    # Empty it
+    for i in range(QUEUE_SIZE):
+        q.get()
+    verify(q.empty(), "Queue should be empty")
+    try:
+        q.get(block=0)
+        raise TestFailed("Didn't appear to block with an empty queue")
+    except Queue.Empty:
+        pass
+    try:
+        q.get(timeout=0.01)
+        raise TestFailed("Didn't appear to time-out with an empty queue")
+    except Queue.Empty:
+        pass
+    # Test a blocking get
+    _doBlockingTest(q.get, (), q.put, ('empty',))
+    _doBlockingTest(q.get, (True, 10), q.put, ('empty',))
+
+cum = 0
+cumlock = threading.Lock()
+
+def worker(q):
+    global cum
+    while True:
+        x = q.get()
+        if x is None:
+            q.task_done()
+            return
+        cumlock.acquire()
+        try:
+            cum += x
+        finally:
+            cumlock.release()
+        q.task_done()
+
+def QueueJoinTest(q):
+    global cum
+    cum = 0
+    for i in (0,1):
+        threading.Thread(target=worker, args=(q,)).start()
+    for i in xrange(100):
+        q.put(i)
+    q.join()
+    verify(cum==sum(range(100)), "q.join() did not block until all tasks were done")
+    for i in (0,1):
+        q.put(None)         # instruct the threads to close
+    q.join()                # verify that you can join twice
+
+def QueueTaskDoneTest(q):
+    try:
+        q.task_done()
+    except ValueError:
+        pass
+    else:
+        raise TestFailed("Did not detect task count going negative")
+
+def test():
+    q = Queue.Queue()
+    QueueTaskDoneTest(q)
+    QueueJoinTest(q)
+    QueueJoinTest(q)
+    QueueTaskDoneTest(q)
+
+    q = Queue.Queue(QUEUE_SIZE)
+    # Do it a couple of times on the same queue
+    SimpleQueueTest(q)
+    SimpleQueueTest(q)
+    if verbose:
+        print "Simple Queue tests seemed to work"
+    q = FailingQueue(QUEUE_SIZE)
+    FailingQueueTest(q)
+    FailingQueueTest(q)
+    if verbose:
+        print "Failing Queue tests seemed to work"
+
+test()

Added: vendor/Python/current/Lib/test/test_quopri.py
===================================================================
--- vendor/Python/current/Lib/test/test_quopri.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_quopri.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,199 @@
+from test import test_support
+import unittest
+
+import sys, os, cStringIO, subprocess
+import quopri
+
+
+
+ENCSAMPLE = """\
+Here's a bunch of special=20
+
+=A1=A2=A3=A4=A5=A6=A7=A8=A9
+=AA=AB=AC=AD=AE=AF=B0=B1=B2=B3
+=B4=B5=B6=B7=B8=B9=BA=BB=BC=BD=BE
+=BF=C0=C1=C2=C3=C4=C5=C6
+=C7=C8=C9=CA=CB=CC=CD=CE=CF
+=D0=D1=D2=D3=D4=D5=D6=D7
+=D8=D9=DA=DB=DC=DD=DE=DF
+=E0=E1=E2=E3=E4=E5=E6=E7
+=E8=E9=EA=EB=EC=ED=EE=EF
+=F0=F1=F2=F3=F4=F5=F6=F7
+=F8=F9=FA=FB=FC=FD=FE=FF
+
+characters... have fun!
+"""
+
+# First line ends with a space
+DECSAMPLE = "Here's a bunch of special \n" + \
+"""\
+
+\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9
+\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3
+\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe
+\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6
+\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf
+\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7
+\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf
+\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7
+\xe8\xe9\xea\xeb\xec\xed\xee\xef
+\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7
+\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff
+
+characters... have fun!
+"""
+
+
+def withpythonimplementation(testfunc):
+    def newtest(self):
+        # Test default implementation
+        testfunc(self)
+        # Test Python implementation
+        if quopri.b2a_qp is not None or quopri.a2b_qp is not None:
+            oldencode = quopri.b2a_qp
+            olddecode = quopri.a2b_qp
+            try:
+                quopri.b2a_qp = None
+                quopri.a2b_qp = None
+                testfunc(self)
+            finally:
+                quopri.b2a_qp = oldencode
+                quopri.a2b_qp = olddecode
+    newtest.__name__ = testfunc.__name__
+    return newtest
+
+class QuopriTestCase(unittest.TestCase):
+    # Each entry is a tuple of (plaintext, encoded string).  These strings are
+    # used in the "quotetabs=0" tests.
+    STRINGS = (
+        # Some normal strings
+        ('hello', 'hello'),
+        ('''hello
+        there
+        world''', '''hello
+        there
+        world'''),
+        ('''hello
+        there
+        world
+''', '''hello
+        there
+        world
+'''),
+        ('\201\202\203', '=81=82=83'),
+        # Add some trailing MUST QUOTE strings
+        ('hello ', 'hello=20'),
+        ('hello\t', 'hello=09'),
+        # Some long lines.  First, a single line of 108 characters
+        ('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\xd8\xd9\xda\xdb\xdc\xdd\xde\xdfxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
+         '''xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=D8=D9=DA=DB=DC=DD=DE=DFx=
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'''),
+        # A line of exactly 76 characters, no soft line break should be needed
+        ('yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+        'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy'),
+        # A line of 77 characters, forcing a soft line break at position 75,
+        # and a second line of exactly 2 characters (because the soft line
+        # break `=' sign counts against the line length limit).
+        ('zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz',
+         '''zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz=
+zz'''),
+        # A line of 151 characters, forcing a soft line break at position 75,
+        # with a second line of exactly 76 characters and no trailing =
+        ('zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz',
+         '''zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz=
+zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz'''),
+        # A string containing a hard line break, but which the first line is
+        # 151 characters and the second line is exactly 76 characters.  This
+        # should leave us with three lines, the first which has a soft line
+        # break, and which the second and third do not.
+        ('''yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
+zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz''',
+         '''yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy=
+yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
+zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz'''),
+        # Now some really complex stuff ;)
+        (DECSAMPLE, ENCSAMPLE),
+        )
+
+    # These are used in the "quotetabs=1" tests.
+    ESTRINGS = (
+        ('hello world', 'hello=20world'),
+        ('hello\tworld', 'hello=09world'),
+        )
+
+    # These are used in the "header=1" tests.
+    HSTRINGS = (
+        ('hello world', 'hello_world'),
+        ('hello_world', 'hello=5Fworld'),
+        )
+
+    @withpythonimplementation
+    def test_encodestring(self):
+        for p, e in self.STRINGS:
+            self.assert_(quopri.encodestring(p) == e)
+
+    @withpythonimplementation
+    def test_decodestring(self):
+        for p, e in self.STRINGS:
+            self.assert_(quopri.decodestring(e) == p)
+
+    @withpythonimplementation
+    def test_idempotent_string(self):
+        for p, e in self.STRINGS:
+            self.assert_(quopri.decodestring(quopri.encodestring(e)) == e)
+
+    @withpythonimplementation
+    def test_encode(self):
+        for p, e in self.STRINGS:
+            infp = cStringIO.StringIO(p)
+            outfp = cStringIO.StringIO()
+            quopri.encode(infp, outfp, quotetabs=False)
+            self.assert_(outfp.getvalue() == e)
+
+    @withpythonimplementation
+    def test_decode(self):
+        for p, e in self.STRINGS:
+            infp = cStringIO.StringIO(e)
+            outfp = cStringIO.StringIO()
+            quopri.decode(infp, outfp)
+            self.assert_(outfp.getvalue() == p)
+
+    @withpythonimplementation
+    def test_embedded_ws(self):
+        for p, e in self.ESTRINGS:
+            self.assert_(quopri.encodestring(p, quotetabs=True) == e)
+            self.assert_(quopri.decodestring(e) == p)
+
+    @withpythonimplementation
+    def test_encode_header(self):
+        for p, e in self.HSTRINGS:
+            self.assert_(quopri.encodestring(p, header=True) == e)
+
+    @withpythonimplementation
+    def test_decode_header(self):
+        for p, e in self.HSTRINGS:
+            self.assert_(quopri.decodestring(e, header=True) == p)
+
+    def test_scriptencode(self):
+        (p, e) = self.STRINGS[-1]
+        process = subprocess.Popen([sys.executable, "-mquopri"],
+                                   stdin=subprocess.PIPE, stdout=subprocess.PIPE)
+        cout, cerr = process.communicate(p)
+        # On Windows, Python will output the result to stdout using
+        # CRLF, as the mode of stdout is text mode. To compare this
+        # with the expected result, we need to do a line-by-line comparison.
+        self.assert_(cout.splitlines() == e.splitlines())
+
+    def test_scriptdecode(self):
+        (p, e) = self.STRINGS[-1]
+        process = subprocess.Popen([sys.executable, "-mquopri", "-d"],
+                                   stdin=subprocess.PIPE, stdout=subprocess.PIPE)
+        cout, cerr = process.communicate(e)
+        self.assert_(cout.splitlines() == p.splitlines())
+
+def test_main():
+    test_support.run_unittest(QuopriTestCase)
+
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_random.py
===================================================================
--- vendor/Python/current/Lib/test/test_random.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_random.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,552 @@
+#!/usr/bin/env python
+
+import unittest
+import random
+import time
+import pickle
+import warnings
+from math import log, exp, sqrt, pi
+from test import test_support
+
+class TestBasicOps(unittest.TestCase):
+    # Superclass with tests common to all generators.
+    # Subclasses must arrange for self.gen to retrieve the Random instance
+    # to be tested.
+
+    def randomlist(self, n):
+        """Helper function to make a list of random numbers"""
+        return [self.gen.random() for i in xrange(n)]
+
+    def test_autoseed(self):
+        self.gen.seed()
+        state1 = self.gen.getstate()
+        time.sleep(0.1)
+        self.gen.seed()      # diffent seeds at different times
+        state2 = self.gen.getstate()
+        self.assertNotEqual(state1, state2)
+
+    def test_saverestore(self):
+        N = 1000
+        self.gen.seed()
+        state = self.gen.getstate()
+        randseq = self.randomlist(N)
+        self.gen.setstate(state)    # should regenerate the same sequence
+        self.assertEqual(randseq, self.randomlist(N))
+
+    def test_seedargs(self):
+        for arg in [None, 0, 0L, 1, 1L, -1, -1L, 10**20, -(10**20),
+                    3.14, 1+2j, 'a', tuple('abc')]:
+            self.gen.seed(arg)
+        for arg in [range(3), dict(one=1)]:
+            self.assertRaises(TypeError, self.gen.seed, arg)
+        self.assertRaises(TypeError, self.gen.seed, 1, 2)
+        self.assertRaises(TypeError, type(self.gen), [])
+
+    def test_jumpahead(self):
+        self.gen.seed()
+        state1 = self.gen.getstate()
+        self.gen.jumpahead(100)
+        state2 = self.gen.getstate()    # s/b distinct from state1
+        self.assertNotEqual(state1, state2)
+        self.gen.jumpahead(100)
+        state3 = self.gen.getstate()    # s/b distinct from state2
+        self.assertNotEqual(state2, state3)
+
+        self.assertRaises(TypeError, self.gen.jumpahead)  # needs an arg
+        self.assertRaises(TypeError, self.gen.jumpahead, "ick")  # wrong type
+        self.assertRaises(TypeError, self.gen.jumpahead, 2.3)  # wrong type
+        self.assertRaises(TypeError, self.gen.jumpahead, 2, 3)  # too many
+
+    def test_sample(self):
+        # For the entire allowable range of 0 <= k <= N, validate that
+        # the sample is of the correct length and contains only unique items
+        N = 100
+        population = xrange(N)
+        for k in xrange(N+1):
+            s = self.gen.sample(population, k)
+            self.assertEqual(len(s), k)
+            uniq = set(s)
+            self.assertEqual(len(uniq), k)
+            self.failUnless(uniq <= set(population))
+        self.assertEqual(self.gen.sample([], 0), [])  # test edge case N==k==0
+
+    def test_sample_distribution(self):
+        # For the entire allowable range of 0 <= k <= N, validate that
+        # sample generates all possible permutations
+        n = 5
+        pop = range(n)
+        trials = 10000  # large num prevents false negatives without slowing normal case
+        def factorial(n):
+            return reduce(int.__mul__, xrange(1, n), 1)
+        for k in xrange(n):
+            expected = factorial(n) // factorial(n-k)
+            perms = {}
+            for i in xrange(trials):
+                perms[tuple(self.gen.sample(pop, k))] = None
+                if len(perms) == expected:
+                    break
+            else:
+                self.fail()
+
+    def test_sample_inputs(self):
+        # SF bug #801342 -- population can be any iterable defining __len__()
+        self.gen.sample(set(range(20)), 2)
+        self.gen.sample(range(20), 2)
+        self.gen.sample(xrange(20), 2)
+        self.gen.sample(str('abcdefghijklmnopqrst'), 2)
+        self.gen.sample(tuple('abcdefghijklmnopqrst'), 2)
+
+    def test_sample_on_dicts(self):
+        self.gen.sample(dict.fromkeys('abcdefghijklmnopqrst'), 2)
+
+        # SF bug #1460340 -- random.sample can raise KeyError
+        a = dict.fromkeys(range(10)+range(10,100,2)+range(100,110))
+        self.gen.sample(a, 3)
+
+        # A followup to bug #1460340:  sampling from a dict could return
+        # a subset of its keys or of its values, depending on the size of
+        # the subset requested.
+        N = 30
+        d = dict((i, complex(i, i)) for i in xrange(N))
+        for k in xrange(N+1):
+            samp = self.gen.sample(d, k)
+            # Verify that we got ints back (keys); the values are complex.
+            for x in samp:
+                self.assert_(type(x) is int)
+        samp.sort()
+        self.assertEqual(samp, range(N))
+
+    def test_gauss(self):
+        # Ensure that the seed() method initializes all the hidden state.  In
+        # particular, through 2.2.1 it failed to reset a piece of state used
+        # by (and only by) the .gauss() method.
+
+        for seed in 1, 12, 123, 1234, 12345, 123456, 654321:
+            self.gen.seed(seed)
+            x1 = self.gen.random()
+            y1 = self.gen.gauss(0, 1)
+
+            self.gen.seed(seed)
+            x2 = self.gen.random()
+            y2 = self.gen.gauss(0, 1)
+
+            self.assertEqual(x1, x2)
+            self.assertEqual(y1, y2)
+
+    def test_pickling(self):
+        state = pickle.dumps(self.gen)
+        origseq = [self.gen.random() for i in xrange(10)]
+        newgen = pickle.loads(state)
+        restoredseq = [newgen.random() for i in xrange(10)]
+        self.assertEqual(origseq, restoredseq)
+
+class WichmannHill_TestBasicOps(TestBasicOps):
+    gen = random.WichmannHill()
+
+    def test_setstate_first_arg(self):
+        self.assertRaises(ValueError, self.gen.setstate, (2, None, None))
+
+    def test_strong_jumpahead(self):
+        # tests that jumpahead(n) semantics correspond to n calls to random()
+        N = 1000
+        s = self.gen.getstate()
+        self.gen.jumpahead(N)
+        r1 = self.gen.random()
+        # now do it the slow way
+        self.gen.setstate(s)
+        for i in xrange(N):
+            self.gen.random()
+        r2 = self.gen.random()
+        self.assertEqual(r1, r2)
+
+    def test_gauss_with_whseed(self):
+        # Ensure that the seed() method initializes all the hidden state.  In
+        # particular, through 2.2.1 it failed to reset a piece of state used
+        # by (and only by) the .gauss() method.
+
+        for seed in 1, 12, 123, 1234, 12345, 123456, 654321:
+            self.gen.whseed(seed)
+            x1 = self.gen.random()
+            y1 = self.gen.gauss(0, 1)
+
+            self.gen.whseed(seed)
+            x2 = self.gen.random()
+            y2 = self.gen.gauss(0, 1)
+
+            self.assertEqual(x1, x2)
+            self.assertEqual(y1, y2)
+
+    def test_bigrand(self):
+        # Verify warnings are raised when randrange is too large for random()
+        oldfilters = warnings.filters[:]
+        warnings.filterwarnings("error", "Underlying random")
+        self.assertRaises(UserWarning, self.gen.randrange, 2**60)
+        warnings.filters[:] = oldfilters
+
+class SystemRandom_TestBasicOps(TestBasicOps):
+    gen = random.SystemRandom()
+
+    def test_autoseed(self):
+        # Doesn't need to do anything except not fail
+        self.gen.seed()
+
+    def test_saverestore(self):
+        self.assertRaises(NotImplementedError, self.gen.getstate)
+        self.assertRaises(NotImplementedError, self.gen.setstate, None)
+
+    def test_seedargs(self):
+        # Doesn't need to do anything except not fail
+        self.gen.seed(100)
+
+    def test_jumpahead(self):
+        # Doesn't need to do anything except not fail
+        self.gen.jumpahead(100)
+
+    def test_gauss(self):
+        self.gen.gauss_next = None
+        self.gen.seed(100)
+        self.assertEqual(self.gen.gauss_next, None)
+
+    def test_pickling(self):
+        self.assertRaises(NotImplementedError, pickle.dumps, self.gen)
+
+    def test_53_bits_per_float(self):
+        # This should pass whenever a C double has 53 bit precision.
+        span = 2 ** 53
+        cum = 0
+        for i in xrange(100):
+            cum |= int(self.gen.random() * span)
+        self.assertEqual(cum, span-1)
+
+    def test_bigrand(self):
+        # The randrange routine should build-up the required number of bits
+        # in stages so that all bit positions are active.
+        span = 2 ** 500
+        cum = 0
+        for i in xrange(100):
+            r = self.gen.randrange(span)
+            self.assert_(0 <= r < span)
+            cum |= r
+        self.assertEqual(cum, span-1)
+
+    def test_bigrand_ranges(self):
+        for i in [40,80, 160, 200, 211, 250, 375, 512, 550]:
+            start = self.gen.randrange(2 ** i)
+            stop = self.gen.randrange(2 ** (i-2))
+            if stop <= start:
+                return
+            self.assert_(start <= self.gen.randrange(start, stop) < stop)
+
+    def test_rangelimits(self):
+        for start, stop in [(-2,0), (-(2**60)-2,-(2**60)), (2**60,2**60+2)]:
+            self.assertEqual(set(range(start,stop)),
+                set([self.gen.randrange(start,stop) for i in xrange(100)]))
+
+    def test_genrandbits(self):
+        # Verify ranges
+        for k in xrange(1, 1000):
+            self.assert_(0 <= self.gen.getrandbits(k) < 2**k)
+
+        # Verify all bits active
+        getbits = self.gen.getrandbits
+        for span in [1, 2, 3, 4, 31, 32, 32, 52, 53, 54, 119, 127, 128, 129]:
+            cum = 0
+            for i in xrange(100):
+                cum |= getbits(span)
+            self.assertEqual(cum, 2**span-1)
+
+        # Verify argument checking
+        self.assertRaises(TypeError, self.gen.getrandbits)
+        self.assertRaises(TypeError, self.gen.getrandbits, 1, 2)
+        self.assertRaises(ValueError, self.gen.getrandbits, 0)
+        self.assertRaises(ValueError, self.gen.getrandbits, -1)
+        self.assertRaises(TypeError, self.gen.getrandbits, 10.1)
+
+    def test_randbelow_logic(self, _log=log, int=int):
+        # check bitcount transition points:  2**i and 2**(i+1)-1
+        # show that: k = int(1.001 + _log(n, 2))
+        # is equal to or one greater than the number of bits in n
+        for i in xrange(1, 1000):
+            n = 1L << i # check an exact power of two
+            numbits = i+1
+            k = int(1.00001 + _log(n, 2))
+            self.assertEqual(k, numbits)
+            self.assert_(n == 2**(k-1))
+
+            n += n - 1      # check 1 below the next power of two
+            k = int(1.00001 + _log(n, 2))
+            self.assert_(k in [numbits, numbits+1])
+            self.assert_(2**k > n > 2**(k-2))
+
+            n -= n >> 15     # check a little farther below the next power of two
+            k = int(1.00001 + _log(n, 2))
+            self.assertEqual(k, numbits)        # note the stronger assertion
+            self.assert_(2**k > n > 2**(k-1))   # note the stronger assertion
+
+
+class MersenneTwister_TestBasicOps(TestBasicOps):
+    gen = random.Random()
+
+    def test_setstate_first_arg(self):
+        self.assertRaises(ValueError, self.gen.setstate, (1, None, None))
+
+    def test_setstate_middle_arg(self):
+        # Wrong type, s/b tuple
+        self.assertRaises(TypeError, self.gen.setstate, (2, None, None))
+        # Wrong length, s/b 625
+        self.assertRaises(ValueError, self.gen.setstate, (2, (1,2,3), None))
+        # Wrong type, s/b tuple of 625 ints
+        self.assertRaises(TypeError, self.gen.setstate, (2, ('a',)*625, None))
+        # Last element s/b an int also
+        self.assertRaises(TypeError, self.gen.setstate, (2, (0,)*624+('a',), None))
+
+    def test_referenceImplementation(self):
+        # Compare the python implementation with results from the original
+        # code.  Create 2000 53-bit precision random floats.  Compare only
+        # the last ten entries to show that the independent implementations
+        # are tracking.  Here is the main() function needed to create the
+        # list of expected random numbers:
+        #    void main(void){
+        #         int i;
+        #         unsigned long init[4]={61731, 24903, 614, 42143}, length=4;
+        #         init_by_array(init, length);
+        #         for (i=0; i<2000; i++) {
+        #           printf("%.15f ", genrand_res53());
+        #           if (i%5==4) printf("\n");
+        #         }
+        #     }
+        expected = [0.45839803073713259,
+                    0.86057815201978782,
+                    0.92848331726782152,
+                    0.35932681119782461,
+                    0.081823493762449573,
+                    0.14332226470169329,
+                    0.084297823823520024,
+                    0.53814864671831453,
+                    0.089215024911993401,
+                    0.78486196105372907]
+
+        self.gen.seed(61731L + (24903L<<32) + (614L<<64) + (42143L<<96))
+        actual = self.randomlist(2000)[-10:]
+        for a, e in zip(actual, expected):
+            self.assertAlmostEqual(a,e,places=14)
+
+    def test_strong_reference_implementation(self):
+        # Like test_referenceImplementation, but checks for exact bit-level
+        # equality.  This should pass on any box where C double contains
+        # at least 53 bits of precision (the underlying algorithm suffers
+        # no rounding errors -- all results are exact).
+        from math import ldexp
+
+        expected = [0x0eab3258d2231fL,
+                    0x1b89db315277a5L,
+                    0x1db622a5518016L,
+                    0x0b7f9af0d575bfL,
+                    0x029e4c4db82240L,
+                    0x04961892f5d673L,
+                    0x02b291598e4589L,
+                    0x11388382c15694L,
+                    0x02dad977c9e1feL,
+                    0x191d96d4d334c6L]
+        self.gen.seed(61731L + (24903L<<32) + (614L<<64) + (42143L<<96))
+        actual = self.randomlist(2000)[-10:]
+        for a, e in zip(actual, expected):
+            self.assertEqual(long(ldexp(a, 53)), e)
+
+    def test_long_seed(self):
+        # This is most interesting to run in debug mode, just to make sure
+        # nothing blows up.  Under the covers, a dynamically resized array
+        # is allocated, consuming space proportional to the number of bits
+        # in the seed.  Unfortunately, that's a quadratic-time algorithm,
+        # so don't make this horribly big.
+        seed = (1L << (10000 * 8)) - 1  # about 10K bytes
+        self.gen.seed(seed)
+
+    def test_53_bits_per_float(self):
+        # This should pass whenever a C double has 53 bit precision.
+        span = 2 ** 53
+        cum = 0
+        for i in xrange(100):
+            cum |= int(self.gen.random() * span)
+        self.assertEqual(cum, span-1)
+
+    def test_bigrand(self):
+        # The randrange routine should build-up the required number of bits
+        # in stages so that all bit positions are active.
+        span = 2 ** 500
+        cum = 0
+        for i in xrange(100):
+            r = self.gen.randrange(span)
+            self.assert_(0 <= r < span)
+            cum |= r
+        self.assertEqual(cum, span-1)
+
+    def test_bigrand_ranges(self):
+        for i in [40,80, 160, 200, 211, 250, 375, 512, 550]:
+            start = self.gen.randrange(2 ** i)
+            stop = self.gen.randrange(2 ** (i-2))
+            if stop <= start:
+                return
+            self.assert_(start <= self.gen.randrange(start, stop) < stop)
+
+    def test_rangelimits(self):
+        for start, stop in [(-2,0), (-(2**60)-2,-(2**60)), (2**60,2**60+2)]:
+            self.assertEqual(set(range(start,stop)),
+                set([self.gen.randrange(start,stop) for i in xrange(100)]))
+
+    def test_genrandbits(self):
+        # Verify cross-platform repeatability
+        self.gen.seed(1234567)
+        self.assertEqual(self.gen.getrandbits(100),
+                         97904845777343510404718956115L)
+        # Verify ranges
+        for k in xrange(1, 1000):
+            self.assert_(0 <= self.gen.getrandbits(k) < 2**k)
+
+        # Verify all bits active
+        getbits = self.gen.getrandbits
+        for span in [1, 2, 3, 4, 31, 32, 32, 52, 53, 54, 119, 127, 128, 129]:
+            cum = 0
+            for i in xrange(100):
+                cum |= getbits(span)
+            self.assertEqual(cum, 2**span-1)
+
+        # Verify argument checking
+        self.assertRaises(TypeError, self.gen.getrandbits)
+        self.assertRaises(TypeError, self.gen.getrandbits, 'a')
+        self.assertRaises(TypeError, self.gen.getrandbits, 1, 2)
+        self.assertRaises(ValueError, self.gen.getrandbits, 0)
+        self.assertRaises(ValueError, self.gen.getrandbits, -1)
+
+    def test_randbelow_logic(self, _log=log, int=int):
+        # check bitcount transition points:  2**i and 2**(i+1)-1
+        # show that: k = int(1.001 + _log(n, 2))
+        # is equal to or one greater than the number of bits in n
+        for i in xrange(1, 1000):
+            n = 1L << i # check an exact power of two
+            numbits = i+1
+            k = int(1.00001 + _log(n, 2))
+            self.assertEqual(k, numbits)
+            self.assert_(n == 2**(k-1))
+
+            n += n - 1      # check 1 below the next power of two
+            k = int(1.00001 + _log(n, 2))
+            self.assert_(k in [numbits, numbits+1])
+            self.assert_(2**k > n > 2**(k-2))
+
+            n -= n >> 15     # check a little farther below the next power of two
+            k = int(1.00001 + _log(n, 2))
+            self.assertEqual(k, numbits)        # note the stronger assertion
+            self.assert_(2**k > n > 2**(k-1))   # note the stronger assertion
+
+    def test_randrange_bug_1590891(self):
+        start = 1000000000000
+        stop = -100000000000000000000
+        step = -200
+        x = self.gen.randrange(start, stop, step)
+        self.assert_(stop < x <= start)
+        self.assertEqual((x+stop)%step, 0)
+
+_gammacoeff = (0.9999999999995183, 676.5203681218835, -1259.139216722289,
+              771.3234287757674,  -176.6150291498386, 12.50734324009056,
+              -0.1385710331296526, 0.9934937113930748e-05, 0.1659470187408462e-06)
+
+def gamma(z, cof=_gammacoeff, g=7):
+    z -= 1.0
+    sum = cof[0]
+    for i in xrange(1,len(cof)):
+        sum += cof[i] / (z+i)
+    z += 0.5
+    return (z+g)**z / exp(z+g) * sqrt(2*pi) * sum
+
+class TestDistributions(unittest.TestCase):
+    def test_zeroinputs(self):
+        # Verify that distributions can handle a series of zero inputs'
+        g = random.Random()
+        x = [g.random() for i in xrange(50)] + [0.0]*5
+        g.random = x[:].pop; g.uniform(1,10)
+        g.random = x[:].pop; g.paretovariate(1.0)
+        g.random = x[:].pop; g.expovariate(1.0)
+        g.random = x[:].pop; g.weibullvariate(1.0, 1.0)
+        g.random = x[:].pop; g.normalvariate(0.0, 1.0)
+        g.random = x[:].pop; g.gauss(0.0, 1.0)
+        g.random = x[:].pop; g.lognormvariate(0.0, 1.0)
+        g.random = x[:].pop; g.vonmisesvariate(0.0, 1.0)
+        g.random = x[:].pop; g.gammavariate(0.01, 1.0)
+        g.random = x[:].pop; g.gammavariate(1.0, 1.0)
+        g.random = x[:].pop; g.gammavariate(200.0, 1.0)
+        g.random = x[:].pop; g.betavariate(3.0, 3.0)
+
+    def test_avg_std(self):
+        # Use integration to test distribution average and standard deviation.
+        # Only works for distributions which do not consume variates in pairs
+        g = random.Random()
+        N = 5000
+        x = [i/float(N) for i in xrange(1,N)]
+        for variate, args, mu, sigmasqrd in [
+                (g.uniform, (1.0,10.0), (10.0+1.0)/2, (10.0-1.0)**2/12),
+                (g.expovariate, (1.5,), 1/1.5, 1/1.5**2),
+                (g.paretovariate, (5.0,), 5.0/(5.0-1),
+                                  5.0/((5.0-1)**2*(5.0-2))),
+                (g.weibullvariate, (1.0, 3.0), gamma(1+1/3.0),
+                                  gamma(1+2/3.0)-gamma(1+1/3.0)**2) ]:
+            g.random = x[:].pop
+            y = []
+            for i in xrange(len(x)):
+                try:
+                    y.append(variate(*args))
+                except IndexError:
+                    pass
+            s1 = s2 = 0
+            for e in y:
+                s1 += e
+                s2 += (e - mu) ** 2
+            N = len(y)
+            self.assertAlmostEqual(s1/N, mu, 2)
+            self.assertAlmostEqual(s2/(N-1), sigmasqrd, 2)
+
+class TestModule(unittest.TestCase):
+    def testMagicConstants(self):
+        self.assertAlmostEqual(random.NV_MAGICCONST, 1.71552776992141)
+        self.assertAlmostEqual(random.TWOPI, 6.28318530718)
+        self.assertAlmostEqual(random.LOG4, 1.38629436111989)
+        self.assertAlmostEqual(random.SG_MAGICCONST, 2.50407739677627)
+
+    def test__all__(self):
+        # tests validity but not completeness of the __all__ list
+        self.failUnless(set(random.__all__) <= set(dir(random)))
+
+    def test_random_subclass_with_kwargs(self):
+        # SF bug #1486663 -- this used to erroneously raise a TypeError
+        class Subclass(random.Random):
+            def __init__(self, newarg=None):
+                random.Random.__init__(self)
+        Subclass(newarg=1)
+
+
+def test_main(verbose=None):
+    testclasses =    [WichmannHill_TestBasicOps,
+                      MersenneTwister_TestBasicOps,
+                      TestDistributions,
+                      TestModule]
+
+    try:
+        random.SystemRandom().random()
+    except NotImplementedError:
+        pass
+    else:
+        testclasses.append(SystemRandom_TestBasicOps)
+
+    test_support.run_unittest(*testclasses)
+
+    # verify reference counting
+    import sys
+    if verbose and hasattr(sys, "gettotalrefcount"):
+        counts = [None] * 5
+        for i in xrange(len(counts)):
+            test_support.run_unittest(*testclasses)
+            counts[i] = sys.gettotalrefcount()
+        print counts
+
+if __name__ == "__main__":
+    test_main(verbose=True)

Added: vendor/Python/current/Lib/test/test_re.py
===================================================================
--- vendor/Python/current/Lib/test/test_re.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_re.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,744 @@
+import sys
+sys.path = ['.'] + sys.path
+
+from test.test_support import verbose, run_unittest
+import re
+from re import Scanner
+import sys, os, traceback
+from weakref import proxy
+
+# Misc tests from Tim Peters' re.doc
+
+# WARNING: Don't change details in these tests if you don't know
+# what you're doing. Some of these tests were carefuly modeled to
+# cover most of the code.
+
+import unittest
+
+class ReTests(unittest.TestCase):
+
+    def test_weakref(self):
+        s = 'QabbbcR'
+        x = re.compile('ab+c')
+        y = proxy(x)
+        self.assertEqual(x.findall('QabbbcR'), y.findall('QabbbcR'))
+
+    def test_search_star_plus(self):
+        self.assertEqual(re.search('x*', 'axx').span(0), (0, 0))
+        self.assertEqual(re.search('x*', 'axx').span(), (0, 0))
+        self.assertEqual(re.search('x+', 'axx').span(0), (1, 3))
+        self.assertEqual(re.search('x+', 'axx').span(), (1, 3))
+        self.assertEqual(re.search('x', 'aaa'), None)
+        self.assertEqual(re.match('a*', 'xxx').span(0), (0, 0))
+        self.assertEqual(re.match('a*', 'xxx').span(), (0, 0))
+        self.assertEqual(re.match('x*', 'xxxa').span(0), (0, 3))
+        self.assertEqual(re.match('x*', 'xxxa').span(), (0, 3))
+        self.assertEqual(re.match('a+', 'xxx'), None)
+
+    def bump_num(self, matchobj):
+        int_value = int(matchobj.group(0))
+        return str(int_value + 1)
+
+    def test_basic_re_sub(self):
+        self.assertEqual(re.sub("(?i)b+", "x", "bbbb BBBB"), 'x x')
+        self.assertEqual(re.sub(r'\d+', self.bump_num, '08.2 -2 23x99y'),
+                         '9.3 -3 24x100y')
+        self.assertEqual(re.sub(r'\d+', self.bump_num, '08.2 -2 23x99y', 3),
+                         '9.3 -3 23x99y')
+
+        self.assertEqual(re.sub('.', lambda m: r"\n", 'x'), '\\n')
+        self.assertEqual(re.sub('.', r"\n", 'x'), '\n')
+
+        s = r"\1\1"
+        self.assertEqual(re.sub('(.)', s, 'x'), 'xx')
+        self.assertEqual(re.sub('(.)', re.escape(s), 'x'), s)
+        self.assertEqual(re.sub('(.)', lambda m: s, 'x'), s)
+
+        self.assertEqual(re.sub('(?P<a>x)', '\g<a>\g<a>', 'xx'), 'xxxx')
+        self.assertEqual(re.sub('(?P<a>x)', '\g<a>\g<1>', 'xx'), 'xxxx')
+        self.assertEqual(re.sub('(?P<unk>x)', '\g<unk>\g<unk>', 'xx'), 'xxxx')
+        self.assertEqual(re.sub('(?P<unk>x)', '\g<1>\g<1>', 'xx'), 'xxxx')
+
+        self.assertEqual(re.sub('a',r'\t\n\v\r\f\a\b\B\Z\a\A\w\W\s\S\d\D','a'),
+                         '\t\n\v\r\f\a\b\\B\\Z\a\\A\\w\\W\\s\\S\\d\\D')
+        self.assertEqual(re.sub('a', '\t\n\v\r\f\a', 'a'), '\t\n\v\r\f\a')
+        self.assertEqual(re.sub('a', '\t\n\v\r\f\a', 'a'),
+                         (chr(9)+chr(10)+chr(11)+chr(13)+chr(12)+chr(7)))
+
+        self.assertEqual(re.sub('^\s*', 'X', 'test'), 'Xtest')
+
+    def test_bug_449964(self):
+        # fails for group followed by other escape
+        self.assertEqual(re.sub(r'(?P<unk>x)', '\g<1>\g<1>\\b', 'xx'),
+                         'xx\bxx\b')
+
+    def test_bug_449000(self):
+        # Test for sub() on escaped characters
+        self.assertEqual(re.sub(r'\r\n', r'\n', 'abc\r\ndef\r\n'),
+                         'abc\ndef\n')
+        self.assertEqual(re.sub('\r\n', r'\n', 'abc\r\ndef\r\n'),
+                         'abc\ndef\n')
+        self.assertEqual(re.sub(r'\r\n', '\n', 'abc\r\ndef\r\n'),
+                         'abc\ndef\n')
+        self.assertEqual(re.sub('\r\n', '\n', 'abc\r\ndef\r\n'),
+                         'abc\ndef\n')
+
+    def test_sub_template_numeric_escape(self):
+        # bug 776311 and friends
+        self.assertEqual(re.sub('x', r'\0', 'x'), '\0')
+        self.assertEqual(re.sub('x', r'\000', 'x'), '\000')
+        self.assertEqual(re.sub('x', r'\001', 'x'), '\001')
+        self.assertEqual(re.sub('x', r'\008', 'x'), '\0' + '8')
+        self.assertEqual(re.sub('x', r'\009', 'x'), '\0' + '9')
+        self.assertEqual(re.sub('x', r'\111', 'x'), '\111')
+        self.assertEqual(re.sub('x', r'\117', 'x'), '\117')
+
+        self.assertEqual(re.sub('x', r'\1111', 'x'), '\1111')
+        self.assertEqual(re.sub('x', r'\1111', 'x'), '\111' + '1')
+
+        self.assertEqual(re.sub('x', r'\00', 'x'), '\x00')
+        self.assertEqual(re.sub('x', r'\07', 'x'), '\x07')
+        self.assertEqual(re.sub('x', r'\08', 'x'), '\0' + '8')
+        self.assertEqual(re.sub('x', r'\09', 'x'), '\0' + '9')
+        self.assertEqual(re.sub('x', r'\0a', 'x'), '\0' + 'a')
+
+        self.assertEqual(re.sub('x', r'\400', 'x'), '\0')
+        self.assertEqual(re.sub('x', r'\777', 'x'), '\377')
+
+        self.assertRaises(re.error, re.sub, 'x', r'\1', 'x')
+        self.assertRaises(re.error, re.sub, 'x', r'\8', 'x')
+        self.assertRaises(re.error, re.sub, 'x', r'\9', 'x')
+        self.assertRaises(re.error, re.sub, 'x', r'\11', 'x')
+        self.assertRaises(re.error, re.sub, 'x', r'\18', 'x')
+        self.assertRaises(re.error, re.sub, 'x', r'\1a', 'x')
+        self.assertRaises(re.error, re.sub, 'x', r'\90', 'x')
+        self.assertRaises(re.error, re.sub, 'x', r'\99', 'x')
+        self.assertRaises(re.error, re.sub, 'x', r'\118', 'x') # r'\11' + '8'
+        self.assertRaises(re.error, re.sub, 'x', r'\11a', 'x')
+        self.assertRaises(re.error, re.sub, 'x', r'\181', 'x') # r'\18' + '1'
+        self.assertRaises(re.error, re.sub, 'x', r'\800', 'x') # r'\80' + '0'
+
+        # in python2.3 (etc), these loop endlessly in sre_parser.py
+        self.assertEqual(re.sub('(((((((((((x)))))))))))', r'\11', 'x'), 'x')
+        self.assertEqual(re.sub('((((((((((y))))))))))(.)', r'\118', 'xyz'),
+                         'xz8')
+        self.assertEqual(re.sub('((((((((((y))))))))))(.)', r'\11a', 'xyz'),
+                         'xza')
+
+    def test_qualified_re_sub(self):
+        self.assertEqual(re.sub('a', 'b', 'aaaaa'), 'bbbbb')
+        self.assertEqual(re.sub('a', 'b', 'aaaaa', 1), 'baaaa')
+
+    def test_bug_114660(self):
+        self.assertEqual(re.sub(r'(\S)\s+(\S)', r'\1 \2', 'hello  there'),
+                         'hello there')
+
+    def test_bug_462270(self):
+        # Test for empty sub() behaviour, see SF bug #462270
+        self.assertEqual(re.sub('x*', '-', 'abxd'), '-a-b-d-')
+        self.assertEqual(re.sub('x+', '-', 'abxd'), 'ab-d')
+
+    def test_symbolic_refs(self):
+        self.assertRaises(re.error, re.sub, '(?P<a>x)', '\g<a', 'xx')
+        self.assertRaises(re.error, re.sub, '(?P<a>x)', '\g<', 'xx')
+        self.assertRaises(re.error, re.sub, '(?P<a>x)', '\g', 'xx')
+        self.assertRaises(re.error, re.sub, '(?P<a>x)', '\g<a a>', 'xx')
+        self.assertRaises(re.error, re.sub, '(?P<a>x)', '\g<1a1>', 'xx')
+        self.assertRaises(IndexError, re.sub, '(?P<a>x)', '\g<ab>', 'xx')
+        self.assertRaises(re.error, re.sub, '(?P<a>x)|(?P<b>y)', '\g<b>', 'xx')
+        self.assertRaises(re.error, re.sub, '(?P<a>x)|(?P<b>y)', '\\2', 'xx')
+        self.assertRaises(re.error, re.sub, '(?P<a>x)', '\g<-1>', 'xx')
+
+    def test_re_subn(self):
+        self.assertEqual(re.subn("(?i)b+", "x", "bbbb BBBB"), ('x x', 2))
+        self.assertEqual(re.subn("b+", "x", "bbbb BBBB"), ('x BBBB', 1))
+        self.assertEqual(re.subn("b+", "x", "xyz"), ('xyz', 0))
+        self.assertEqual(re.subn("b*", "x", "xyz"), ('xxxyxzx', 4))
+        self.assertEqual(re.subn("b*", "x", "xyz", 2), ('xxxyz', 2))
+
+    def test_re_split(self):
+        self.assertEqual(re.split(":", ":a:b::c"), ['', 'a', 'b', '', 'c'])
+        self.assertEqual(re.split(":*", ":a:b::c"), ['', 'a', 'b', 'c'])
+        self.assertEqual(re.split("(:*)", ":a:b::c"),
+                         ['', ':', 'a', ':', 'b', '::', 'c'])
+        self.assertEqual(re.split("(?::*)", ":a:b::c"), ['', 'a', 'b', 'c'])
+        self.assertEqual(re.split("(:)*", ":a:b::c"),
+                         ['', ':', 'a', ':', 'b', ':', 'c'])
+        self.assertEqual(re.split("([b:]+)", ":a:b::c"),
+                         ['', ':', 'a', ':b::', 'c'])
+        self.assertEqual(re.split("(b)|(:+)", ":a:b::c"),
+                         ['', None, ':', 'a', None, ':', '', 'b', None, '',
+                          None, '::', 'c'])
+        self.assertEqual(re.split("(?:b)|(?::+)", ":a:b::c"),
+                         ['', 'a', '', '', 'c'])
+
+    def test_qualified_re_split(self):
+        self.assertEqual(re.split(":", ":a:b::c", 2), ['', 'a', 'b::c'])
+        self.assertEqual(re.split(':', 'a:b:c:d', 2), ['a', 'b', 'c:d'])
+        self.assertEqual(re.split("(:)", ":a:b::c", 2),
+                         ['', ':', 'a', ':', 'b::c'])
+        self.assertEqual(re.split("(:*)", ":a:b::c", 2),
+                         ['', ':', 'a', ':', 'b::c'])
+
+    def test_re_findall(self):
+        self.assertEqual(re.findall(":+", "abc"), [])
+        self.assertEqual(re.findall(":+", "a:b::c:::d"), [":", "::", ":::"])
+        self.assertEqual(re.findall("(:+)", "a:b::c:::d"), [":", "::", ":::"])
+        self.assertEqual(re.findall("(:)(:*)", "a:b::c:::d"), [(":", ""),
+                                                               (":", ":"),
+                                                               (":", "::")])
+
+    def test_bug_117612(self):
+        self.assertEqual(re.findall(r"(a|(b))", "aba"),
+                         [("a", ""),("b", "b"),("a", "")])
+
+    def test_re_match(self):
+        self.assertEqual(re.match('a', 'a').groups(), ())
+        self.assertEqual(re.match('(a)', 'a').groups(), ('a',))
+        self.assertEqual(re.match(r'(a)', 'a').group(0), 'a')
+        self.assertEqual(re.match(r'(a)', 'a').group(1), 'a')
+        self.assertEqual(re.match(r'(a)', 'a').group(1, 1), ('a', 'a'))
+
+        pat = re.compile('((a)|(b))(c)?')
+        self.assertEqual(pat.match('a').groups(), ('a', 'a', None, None))
+        self.assertEqual(pat.match('b').groups(), ('b', None, 'b', None))
+        self.assertEqual(pat.match('ac').groups(), ('a', 'a', None, 'c'))
+        self.assertEqual(pat.match('bc').groups(), ('b', None, 'b', 'c'))
+        self.assertEqual(pat.match('bc').groups(""), ('b', "", 'b', 'c'))
+
+        # A single group
+        m = re.match('(a)', 'a')
+        self.assertEqual(m.group(0), 'a')
+        self.assertEqual(m.group(0), 'a')
+        self.assertEqual(m.group(1), 'a')
+        self.assertEqual(m.group(1, 1), ('a', 'a'))
+
+        pat = re.compile('(?:(?P<a1>a)|(?P<b2>b))(?P<c3>c)?')
+        self.assertEqual(pat.match('a').group(1, 2, 3), ('a', None, None))
+        self.assertEqual(pat.match('b').group('a1', 'b2', 'c3'),
+                         (None, 'b', None))
+        self.assertEqual(pat.match('ac').group(1, 'b2', 3), ('a', None, 'c'))
+
+    def test_re_groupref_exists(self):
+        self.assertEqual(re.match('^(\()?([^()]+)(?(1)\))$', '(a)').groups(),
+                         ('(', 'a'))
+        self.assertEqual(re.match('^(\()?([^()]+)(?(1)\))$', 'a').groups(),
+                         (None, 'a'))
+        self.assertEqual(re.match('^(\()?([^()]+)(?(1)\))$', 'a)'), None)
+        self.assertEqual(re.match('^(\()?([^()]+)(?(1)\))$', '(a'), None)
+        self.assertEqual(re.match('^(?:(a)|c)((?(1)b|d))$', 'ab').groups(),
+                         ('a', 'b'))
+        self.assertEqual(re.match('^(?:(a)|c)((?(1)b|d))$', 'cd').groups(),
+                         (None, 'd'))
+        self.assertEqual(re.match('^(?:(a)|c)((?(1)|d))$', 'cd').groups(),
+                         (None, 'd'))
+        self.assertEqual(re.match('^(?:(a)|c)((?(1)|d))$', 'a').groups(),
+                         ('a', ''))
+
+        # Tests for bug #1177831: exercise groups other than the first group
+        p = re.compile('(?P<g1>a)(?P<g2>b)?((?(g2)c|d))')
+        self.assertEqual(p.match('abc').groups(),
+                         ('a', 'b', 'c'))
+        self.assertEqual(p.match('ad').groups(),
+                         ('a', None, 'd'))
+        self.assertEqual(p.match('abd'), None)
+        self.assertEqual(p.match('ac'), None)
+
+
+    def test_re_groupref(self):
+        self.assertEqual(re.match(r'^(\|)?([^()]+)\1$', '|a|').groups(),
+                         ('|', 'a'))
+        self.assertEqual(re.match(r'^(\|)?([^()]+)\1?$', 'a').groups(),
+                         (None, 'a'))
+        self.assertEqual(re.match(r'^(\|)?([^()]+)\1$', 'a|'), None)
+        self.assertEqual(re.match(r'^(\|)?([^()]+)\1$', '|a'), None)
+        self.assertEqual(re.match(r'^(?:(a)|c)(\1)$', 'aa').groups(),
+                         ('a', 'a'))
+        self.assertEqual(re.match(r'^(?:(a)|c)(\1)?$', 'c').groups(),
+                         (None, None))
+
+    def test_groupdict(self):
+        self.assertEqual(re.match('(?P<first>first) (?P<second>second)',
+                                  'first second').groupdict(),
+                         {'first':'first', 'second':'second'})
+
+    def test_expand(self):
+        self.assertEqual(re.match("(?P<first>first) (?P<second>second)",
+                                  "first second")
+                                  .expand(r"\2 \1 \g<second> \g<first>"),
+                         "second first second first")
+
+    def test_repeat_minmax(self):
+        self.assertEqual(re.match("^(\w){1}$", "abc"), None)
+        self.assertEqual(re.match("^(\w){1}?$", "abc"), None)
+        self.assertEqual(re.match("^(\w){1,2}$", "abc"), None)
+        self.assertEqual(re.match("^(\w){1,2}?$", "abc"), None)
+
+        self.assertEqual(re.match("^(\w){3}$", "abc").group(1), "c")
+        self.assertEqual(re.match("^(\w){1,3}$", "abc").group(1), "c")
+        self.assertEqual(re.match("^(\w){1,4}$", "abc").group(1), "c")
+        self.assertEqual(re.match("^(\w){3,4}?$", "abc").group(1), "c")
+        self.assertEqual(re.match("^(\w){3}?$", "abc").group(1), "c")
+        self.assertEqual(re.match("^(\w){1,3}?$", "abc").group(1), "c")
+        self.assertEqual(re.match("^(\w){1,4}?$", "abc").group(1), "c")
+        self.assertEqual(re.match("^(\w){3,4}?$", "abc").group(1), "c")
+
+        self.assertEqual(re.match("^x{1}$", "xxx"), None)
+        self.assertEqual(re.match("^x{1}?$", "xxx"), None)
+        self.assertEqual(re.match("^x{1,2}$", "xxx"), None)
+        self.assertEqual(re.match("^x{1,2}?$", "xxx"), None)
+
+        self.assertNotEqual(re.match("^x{3}$", "xxx"), None)
+        self.assertNotEqual(re.match("^x{1,3}$", "xxx"), None)
+        self.assertNotEqual(re.match("^x{1,4}$", "xxx"), None)
+        self.assertNotEqual(re.match("^x{3,4}?$", "xxx"), None)
+        self.assertNotEqual(re.match("^x{3}?$", "xxx"), None)
+        self.assertNotEqual(re.match("^x{1,3}?$", "xxx"), None)
+        self.assertNotEqual(re.match("^x{1,4}?$", "xxx"), None)
+        self.assertNotEqual(re.match("^x{3,4}?$", "xxx"), None)
+
+        self.assertEqual(re.match("^x{}$", "xxx"), None)
+        self.assertNotEqual(re.match("^x{}$", "x{}"), None)
+
+    def test_getattr(self):
+        self.assertEqual(re.match("(a)", "a").pos, 0)
+        self.assertEqual(re.match("(a)", "a").endpos, 1)
+        self.assertEqual(re.match("(a)", "a").string, "a")
+        self.assertEqual(re.match("(a)", "a").regs, ((0, 1), (0, 1)))
+        self.assertNotEqual(re.match("(a)", "a").re, None)
+
+    def test_special_escapes(self):
+        self.assertEqual(re.search(r"\b(b.)\b",
+                                   "abcd abc bcd bx").group(1), "bx")
+        self.assertEqual(re.search(r"\B(b.)\B",
+                                   "abc bcd bc abxd").group(1), "bx")
+        self.assertEqual(re.search(r"\b(b.)\b",
+                                   "abcd abc bcd bx", re.LOCALE).group(1), "bx")
+        self.assertEqual(re.search(r"\B(b.)\B",
+                                   "abc bcd bc abxd", re.LOCALE).group(1), "bx")
+        self.assertEqual(re.search(r"\b(b.)\b",
+                                   "abcd abc bcd bx", re.UNICODE).group(1), "bx")
+        self.assertEqual(re.search(r"\B(b.)\B",
+                                   "abc bcd bc abxd", re.UNICODE).group(1), "bx")
+        self.assertEqual(re.search(r"^abc$", "\nabc\n", re.M).group(0), "abc")
+        self.assertEqual(re.search(r"^\Aabc\Z$", "abc", re.M).group(0), "abc")
+        self.assertEqual(re.search(r"^\Aabc\Z$", "\nabc\n", re.M), None)
+        self.assertEqual(re.search(r"\b(b.)\b",
+                                   u"abcd abc bcd bx").group(1), "bx")
+        self.assertEqual(re.search(r"\B(b.)\B",
+                                   u"abc bcd bc abxd").group(1), "bx")
+        self.assertEqual(re.search(r"^abc$", u"\nabc\n", re.M).group(0), "abc")
+        self.assertEqual(re.search(r"^\Aabc\Z$", u"abc", re.M).group(0), "abc")
+        self.assertEqual(re.search(r"^\Aabc\Z$", u"\nabc\n", re.M), None)
+        self.assertEqual(re.search(r"\d\D\w\W\s\S",
+                                   "1aa! a").group(0), "1aa! a")
+        self.assertEqual(re.search(r"\d\D\w\W\s\S",
+                                   "1aa! a", re.LOCALE).group(0), "1aa! a")
+        self.assertEqual(re.search(r"\d\D\w\W\s\S",
+                                   "1aa! a", re.UNICODE).group(0), "1aa! a")
+
+    def test_ignore_case(self):
+        self.assertEqual(re.match("abc", "ABC", re.I).group(0), "ABC")
+        self.assertEqual(re.match("abc", u"ABC", re.I).group(0), "ABC")
+
+    def test_bigcharset(self):
+        self.assertEqual(re.match(u"([\u2222\u2223])",
+                                  u"\u2222").group(1), u"\u2222")
+        self.assertEqual(re.match(u"([\u2222\u2223])",
+                                  u"\u2222", re.UNICODE).group(1), u"\u2222")
+
+    def test_anyall(self):
+        self.assertEqual(re.match("a.b", "a\nb", re.DOTALL).group(0),
+                         "a\nb")
+        self.assertEqual(re.match("a.*b", "a\n\nb", re.DOTALL).group(0),
+                         "a\n\nb")
+
+    def test_non_consuming(self):
+        self.assertEqual(re.match("(a(?=\s[^a]))", "a b").group(1), "a")
+        self.assertEqual(re.match("(a(?=\s[^a]*))", "a b").group(1), "a")
+        self.assertEqual(re.match("(a(?=\s[abc]))", "a b").group(1), "a")
+        self.assertEqual(re.match("(a(?=\s[abc]*))", "a bc").group(1), "a")
+        self.assertEqual(re.match(r"(a)(?=\s\1)", "a a").group(1), "a")
+        self.assertEqual(re.match(r"(a)(?=\s\1*)", "a aa").group(1), "a")
+        self.assertEqual(re.match(r"(a)(?=\s(abc|a))", "a a").group(1), "a")
+
+        self.assertEqual(re.match(r"(a(?!\s[^a]))", "a a").group(1), "a")
+        self.assertEqual(re.match(r"(a(?!\s[abc]))", "a d").group(1), "a")
+        self.assertEqual(re.match(r"(a)(?!\s\1)", "a b").group(1), "a")
+        self.assertEqual(re.match(r"(a)(?!\s(abc|a))", "a b").group(1), "a")
+
+    def test_ignore_case(self):
+        self.assertEqual(re.match(r"(a\s[^a])", "a b", re.I).group(1), "a b")
+        self.assertEqual(re.match(r"(a\s[^a]*)", "a bb", re.I).group(1), "a bb")
+        self.assertEqual(re.match(r"(a\s[abc])", "a b", re.I).group(1), "a b")
+        self.assertEqual(re.match(r"(a\s[abc]*)", "a bb", re.I).group(1), "a bb")
+        self.assertEqual(re.match(r"((a)\s\2)", "a a", re.I).group(1), "a a")
+        self.assertEqual(re.match(r"((a)\s\2*)", "a aa", re.I).group(1), "a aa")
+        self.assertEqual(re.match(r"((a)\s(abc|a))", "a a", re.I).group(1), "a a")
+        self.assertEqual(re.match(r"((a)\s(abc|a)*)", "a aa", re.I).group(1), "a aa")
+
+    def test_category(self):
+        self.assertEqual(re.match(r"(\s)", " ").group(1), " ")
+
+    def test_getlower(self):
+        import _sre
+        self.assertEqual(_sre.getlower(ord('A'), 0), ord('a'))
+        self.assertEqual(_sre.getlower(ord('A'), re.LOCALE), ord('a'))
+        self.assertEqual(_sre.getlower(ord('A'), re.UNICODE), ord('a'))
+
+        self.assertEqual(re.match("abc", "ABC", re.I).group(0), "ABC")
+        self.assertEqual(re.match("abc", u"ABC", re.I).group(0), "ABC")
+
+    def test_not_literal(self):
+        self.assertEqual(re.search("\s([^a])", " b").group(1), "b")
+        self.assertEqual(re.search("\s([^a]*)", " bb").group(1), "bb")
+
+    def test_search_coverage(self):
+        self.assertEqual(re.search("\s(b)", " b").group(1), "b")
+        self.assertEqual(re.search("a\s", "a ").group(0), "a ")
+
+    def test_re_escape(self):
+        p=""
+        for i in range(0, 256):
+            p = p + chr(i)
+            self.assertEqual(re.match(re.escape(chr(i)), chr(i)) is not None,
+                             True)
+            self.assertEqual(re.match(re.escape(chr(i)), chr(i)).span(), (0,1))
+
+        pat=re.compile(re.escape(p))
+        self.assertEqual(pat.match(p) is not None, True)
+        self.assertEqual(pat.match(p).span(), (0,256))
+
+    def test_pickling(self):
+        import pickle
+        self.pickle_test(pickle)
+        import cPickle
+        self.pickle_test(cPickle)
+        # old pickles expect the _compile() reconstructor in sre module
+        import warnings
+        original_filters = warnings.filters[:]
+        try:
+            warnings.filterwarnings("ignore", "The sre module is deprecated",
+                                    DeprecationWarning)
+            from sre import _compile
+        finally:
+            warnings.filters = original_filters
+
+    def pickle_test(self, pickle):
+        oldpat = re.compile('a(?:b|(c|e){1,2}?|d)+?(.)')
+        s = pickle.dumps(oldpat)
+        newpat = pickle.loads(s)
+        self.assertEqual(oldpat, newpat)
+
+    def test_constants(self):
+        self.assertEqual(re.I, re.IGNORECASE)
+        self.assertEqual(re.L, re.LOCALE)
+        self.assertEqual(re.M, re.MULTILINE)
+        self.assertEqual(re.S, re.DOTALL)
+        self.assertEqual(re.X, re.VERBOSE)
+
+    def test_flags(self):
+        for flag in [re.I, re.M, re.X, re.S, re.L]:
+            self.assertNotEqual(re.compile('^pattern$', flag), None)
+
+    def test_sre_character_literals(self):
+        for i in [0, 8, 16, 32, 64, 127, 128, 255]:
+            self.assertNotEqual(re.match(r"\%03o" % i, chr(i)), None)
+            self.assertNotEqual(re.match(r"\%03o0" % i, chr(i)+"0"), None)
+            self.assertNotEqual(re.match(r"\%03o8" % i, chr(i)+"8"), None)
+            self.assertNotEqual(re.match(r"\x%02x" % i, chr(i)), None)
+            self.assertNotEqual(re.match(r"\x%02x0" % i, chr(i)+"0"), None)
+            self.assertNotEqual(re.match(r"\x%02xz" % i, chr(i)+"z"), None)
+        self.assertRaises(re.error, re.match, "\911", "")
+
+    def test_sre_character_class_literals(self):
+        for i in [0, 8, 16, 32, 64, 127, 128, 255]:
+            self.assertNotEqual(re.match(r"[\%03o]" % i, chr(i)), None)
+            self.assertNotEqual(re.match(r"[\%03o0]" % i, chr(i)), None)
+            self.assertNotEqual(re.match(r"[\%03o8]" % i, chr(i)), None)
+            self.assertNotEqual(re.match(r"[\x%02x]" % i, chr(i)), None)
+            self.assertNotEqual(re.match(r"[\x%02x0]" % i, chr(i)), None)
+            self.assertNotEqual(re.match(r"[\x%02xz]" % i, chr(i)), None)
+        self.assertRaises(re.error, re.match, "[\911]", "")
+
+    def test_bug_113254(self):
+        self.assertEqual(re.match(r'(a)|(b)', 'b').start(1), -1)
+        self.assertEqual(re.match(r'(a)|(b)', 'b').end(1), -1)
+        self.assertEqual(re.match(r'(a)|(b)', 'b').span(1), (-1, -1))
+
+    def test_bug_527371(self):
+        # bug described in patches 527371/672491
+        self.assertEqual(re.match(r'(a)?a','a').lastindex, None)
+        self.assertEqual(re.match(r'(a)(b)?b','ab').lastindex, 1)
+        self.assertEqual(re.match(r'(?P<a>a)(?P<b>b)?b','ab').lastgroup, 'a')
+        self.assertEqual(re.match("(?P<a>a(b))", "ab").lastgroup, 'a')
+        self.assertEqual(re.match("((a))", "a").lastindex, 1)
+
+    def test_bug_545855(self):
+        # bug 545855 -- This pattern failed to cause a compile error as it
+        # should, instead provoking a TypeError.
+        self.assertRaises(re.error, re.compile, 'foo[a-')
+
+    def test_bug_418626(self):
+        # bugs 418626 at al. -- Testing Greg Chapman's addition of op code
+        # SRE_OP_MIN_REPEAT_ONE for eliminating recursion on simple uses of
+        # pattern '*?' on a long string.
+        self.assertEqual(re.match('.*?c', 10000*'ab'+'cd').end(0), 20001)
+        self.assertEqual(re.match('.*?cd', 5000*'ab'+'c'+5000*'ab'+'cde').end(0),
+                         20003)
+        self.assertEqual(re.match('.*?cd', 20000*'abc'+'de').end(0), 60001)
+        # non-simple '*?' still used to hit the recursion limit, before the
+        # non-recursive scheme was implemented.
+        self.assertEqual(re.search('(a|b)*?c', 10000*'ab'+'cd').end(0), 20001)
+
+    def test_bug_612074(self):
+        pat=u"["+re.escape(u"\u2039")+u"]"
+        self.assertEqual(re.compile(pat) and 1, 1)
+
+    def test_stack_overflow(self):
+        # nasty cases that used to overflow the straightforward recursive
+        # implementation of repeated groups.
+        self.assertEqual(re.match('(x)*', 50000*'x').group(1), 'x')
+        self.assertEqual(re.match('(x)*y', 50000*'x'+'y').group(1), 'x')
+        self.assertEqual(re.match('(x)*?y', 50000*'x'+'y').group(1), 'x')
+
+    def test_scanner(self):
+        def s_ident(scanner, token): return token
+        def s_operator(scanner, token): return "op%s" % token
+        def s_float(scanner, token): return float(token)
+        def s_int(scanner, token): return int(token)
+
+        scanner = Scanner([
+            (r"[a-zA-Z_]\w*", s_ident),
+            (r"\d+\.\d*", s_float),
+            (r"\d+", s_int),
+            (r"=|\+|-|\*|/", s_operator),
+            (r"\s+", None),
+            ])
+
+        self.assertNotEqual(scanner.scanner.scanner("").pattern, None)
+
+        self.assertEqual(scanner.scan("sum = 3*foo + 312.50 + bar"),
+                         (['sum', 'op=', 3, 'op*', 'foo', 'op+', 312.5,
+                           'op+', 'bar'], ''))
+
+    def test_bug_448951(self):
+        # bug 448951 (similar to 429357, but with single char match)
+        # (Also test greedy matches.)
+        for op in '','?','*':
+            self.assertEqual(re.match(r'((.%s):)?z'%op, 'z').groups(),
+                             (None, None))
+            self.assertEqual(re.match(r'((.%s):)?z'%op, 'a:z').groups(),
+                             ('a:', 'a'))
+
+    def test_bug_725106(self):
+        # capturing groups in alternatives in repeats
+        self.assertEqual(re.match('^((a)|b)*', 'abc').groups(),
+                         ('b', 'a'))
+        self.assertEqual(re.match('^(([ab])|c)*', 'abc').groups(),
+                         ('c', 'b'))
+        self.assertEqual(re.match('^((d)|[ab])*', 'abc').groups(),
+                         ('b', None))
+        self.assertEqual(re.match('^((a)c|[ab])*', 'abc').groups(),
+                         ('b', None))
+        self.assertEqual(re.match('^((a)|b)*?c', 'abc').groups(),
+                         ('b', 'a'))
+        self.assertEqual(re.match('^(([ab])|c)*?d', 'abcd').groups(),
+                         ('c', 'b'))
+        self.assertEqual(re.match('^((d)|[ab])*?c', 'abc').groups(),
+                         ('b', None))
+        self.assertEqual(re.match('^((a)c|[ab])*?c', 'abc').groups(),
+                         ('b', None))
+
+    def test_bug_725149(self):
+        # mark_stack_base restoring before restoring marks
+        self.assertEqual(re.match('(a)(?:(?=(b)*)c)*', 'abb').groups(),
+                         ('a', None))
+        self.assertEqual(re.match('(a)((?!(b)*))*', 'abb').groups(),
+                         ('a', None, None))
+
+    def test_bug_764548(self):
+        # bug 764548, re.compile() barfs on str/unicode subclasses
+        try:
+            unicode
+        except NameError:
+            return  # no problem if we have no unicode
+        class my_unicode(unicode): pass
+        pat = re.compile(my_unicode("abc"))
+        self.assertEqual(pat.match("xyz"), None)
+
+    def test_finditer(self):
+        iter = re.finditer(r":+", "a:b::c:::d")
+        self.assertEqual([item.group(0) for item in iter],
+                         [":", "::", ":::"])
+
+    def test_bug_926075(self):
+        try:
+            unicode
+        except NameError:
+            return # no problem if we have no unicode
+        self.assert_(re.compile('bug_926075') is not
+                     re.compile(eval("u'bug_926075'")))
+
+    def test_bug_931848(self):
+        try:
+            unicode
+        except NameError:
+            pass
+        pattern = eval('u"[\u002E\u3002\uFF0E\uFF61]"')
+        self.assertEqual(re.compile(pattern).split("a.b.c"),
+                         ['a','b','c'])
+
+    def test_bug_581080(self):
+        iter = re.finditer(r"\s", "a b")
+        self.assertEqual(iter.next().span(), (1,2))
+        self.assertRaises(StopIteration, iter.next)
+
+        scanner = re.compile(r"\s").scanner("a b")
+        self.assertEqual(scanner.search().span(), (1, 2))
+        self.assertEqual(scanner.search(), None)
+
+    def test_bug_817234(self):
+        iter = re.finditer(r".*", "asdf")
+        self.assertEqual(iter.next().span(), (0, 4))
+        self.assertEqual(iter.next().span(), (4, 4))
+        self.assertRaises(StopIteration, iter.next)
+
+    def test_empty_array(self):
+        # SF buf 1647541
+        import array
+        for typecode in 'cbBuhHiIlLfd':
+            a = array.array(typecode)
+            self.assertEqual(re.compile("bla").match(a), None)
+            self.assertEqual(re.compile("").match(a).groups(), ())            
+
+def run_re_tests():
+    from test.re_tests import benchmarks, tests, SUCCEED, FAIL, SYNTAX_ERROR
+    if verbose:
+        print 'Running re_tests test suite'
+    else:
+        # To save time, only run the first and last 10 tests
+        #tests = tests[:10] + tests[-10:]
+        pass
+
+    for t in tests:
+        sys.stdout.flush()
+        pattern = s = outcome = repl = expected = None
+        if len(t) == 5:
+            pattern, s, outcome, repl, expected = t
+        elif len(t) == 3:
+            pattern, s, outcome = t
+        else:
+            raise ValueError, ('Test tuples should have 3 or 5 fields', t)
+
+        try:
+            obj = re.compile(pattern)
+        except re.error:
+            if outcome == SYNTAX_ERROR: pass  # Expected a syntax error
+            else:
+                print '=== Syntax error:', t
+        except KeyboardInterrupt: raise KeyboardInterrupt
+        except:
+            print '*** Unexpected error ***', t
+            if verbose:
+                traceback.print_exc(file=sys.stdout)
+        else:
+            try:
+                result = obj.search(s)
+            except re.error, msg:
+                print '=== Unexpected exception', t, repr(msg)
+            if outcome == SYNTAX_ERROR:
+                # This should have been a syntax error; forget it.
+                pass
+            elif outcome == FAIL:
+                if result is None: pass   # No match, as expected
+                else: print '=== Succeeded incorrectly', t
+            elif outcome == SUCCEED:
+                if result is not None:
+                    # Matched, as expected, so now we compute the
+                    # result string and compare it to our expected result.
+                    start, end = result.span(0)
+                    vardict={'found': result.group(0),
+                             'groups': result.group(),
+                             'flags': result.re.flags}
+                    for i in range(1, 100):
+                        try:
+                            gi = result.group(i)
+                            # Special hack because else the string concat fails:
+                            if gi is None:
+                                gi = "None"
+                        except IndexError:
+                            gi = "Error"
+                        vardict['g%d' % i] = gi
+                    for i in result.re.groupindex.keys():
+                        try:
+                            gi = result.group(i)
+                            if gi is None:
+                                gi = "None"
+                        except IndexError:
+                            gi = "Error"
+                        vardict[i] = gi
+                    repl = eval(repl, vardict)
+                    if repl != expected:
+                        print '=== grouping error', t,
+                        print repr(repl) + ' should be ' + repr(expected)
+                else:
+                    print '=== Failed incorrectly', t
+
+                # Try the match on a unicode string, and check that it
+                # still succeeds.
+                try:
+                    result = obj.search(unicode(s, "latin-1"))
+                    if result is None:
+                        print '=== Fails on unicode match', t
+                except NameError:
+                    continue # 1.5.2
+                except TypeError:
+                    continue # unicode test case
+
+                # Try the match on a unicode pattern, and check that it
+                # still succeeds.
+                obj=re.compile(unicode(pattern, "latin-1"))
+                result = obj.search(s)
+                if result is None:
+                    print '=== Fails on unicode pattern match', t
+
+                # Try the match with the search area limited to the extent
+                # of the match and see if it still succeeds.  \B will
+                # break (because it won't match at the end or start of a
+                # string), so we'll ignore patterns that feature it.
+
+                if pattern[:2] != '\\B' and pattern[-2:] != '\\B' \
+                               and result is not None:
+                    obj = re.compile(pattern)
+                    result = obj.search(s, result.start(0), result.end(0) + 1)
+                    if result is None:
+                        print '=== Failed on range-limited match', t
+
+                # Try the match with IGNORECASE enabled, and check that it
+                # still succeeds.
+                obj = re.compile(pattern, re.IGNORECASE)
+                result = obj.search(s)
+                if result is None:
+                    print '=== Fails on case-insensitive match', t
+
+                # Try the match with LOCALE enabled, and check that it
+                # still succeeds.
+                obj = re.compile(pattern, re.LOCALE)
+                result = obj.search(s)
+                if result is None:
+                    print '=== Fails on locale-sensitive match', t
+
+                # Try the match with UNICODE locale enabled, and check
+                # that it still succeeds.
+                obj = re.compile(pattern, re.UNICODE)
+                result = obj.search(s)
+                if result is None:
+                    print '=== Fails on unicode-sensitive match', t
+
+def test_main():
+    run_unittest(ReTests)
+    run_re_tests()
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_repr.py
===================================================================
--- vendor/Python/current/Lib/test/test_repr.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_repr.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,307 @@
+"""
+  Test cases for the repr module
+  Nick Mathewson
+"""
+
+import sys
+import os
+import shutil
+import unittest
+
+from test.test_support import run_unittest
+from repr import repr as r # Don't shadow builtin repr
+
+
+def nestedTuple(nesting):
+    t = ()
+    for i in range(nesting):
+        t = (t,)
+    return t
+
+class ReprTests(unittest.TestCase):
+
+    def test_string(self):
+        eq = self.assertEquals
+        eq(r("abc"), "'abc'")
+        eq(r("abcdefghijklmnop"),"'abcdefghijklmnop'")
+
+        s = "a"*30+"b"*30
+        expected = repr(s)[:13] + "..." + repr(s)[-14:]
+        eq(r(s), expected)
+
+        eq(r("\"'"), repr("\"'"))
+        s = "\""*30+"'"*100
+        expected = repr(s)[:13] + "..." + repr(s)[-14:]
+        eq(r(s), expected)
+
+    def test_container(self):
+        from array import array
+        from collections import deque
+
+        eq = self.assertEquals
+        # Tuples give up after 6 elements
+        eq(r(()), "()")
+        eq(r((1,)), "(1,)")
+        eq(r((1, 2, 3)), "(1, 2, 3)")
+        eq(r((1, 2, 3, 4, 5, 6)), "(1, 2, 3, 4, 5, 6)")
+        eq(r((1, 2, 3, 4, 5, 6, 7)), "(1, 2, 3, 4, 5, 6, ...)")
+
+        # Lists give up after 6 as well
+        eq(r([]), "[]")
+        eq(r([1]), "[1]")
+        eq(r([1, 2, 3]), "[1, 2, 3]")
+        eq(r([1, 2, 3, 4, 5, 6]), "[1, 2, 3, 4, 5, 6]")
+        eq(r([1, 2, 3, 4, 5, 6, 7]), "[1, 2, 3, 4, 5, 6, ...]")
+
+        # Sets give up after 6 as well
+        eq(r(set([])), "set([])")
+        eq(r(set([1])), "set([1])")
+        eq(r(set([1, 2, 3])), "set([1, 2, 3])")
+        eq(r(set([1, 2, 3, 4, 5, 6])), "set([1, 2, 3, 4, 5, 6])")
+        eq(r(set([1, 2, 3, 4, 5, 6, 7])), "set([1, 2, 3, 4, 5, 6, ...])")
+
+        # Frozensets give up after 6 as well
+        eq(r(frozenset([])), "frozenset([])")
+        eq(r(frozenset([1])), "frozenset([1])")
+        eq(r(frozenset([1, 2, 3])), "frozenset([1, 2, 3])")
+        eq(r(frozenset([1, 2, 3, 4, 5, 6])), "frozenset([1, 2, 3, 4, 5, 6])")
+        eq(r(frozenset([1, 2, 3, 4, 5, 6, 7])), "frozenset([1, 2, 3, 4, 5, 6, ...])")
+
+        # collections.deque after 6
+        eq(r(deque([1, 2, 3, 4, 5, 6, 7])), "deque([1, 2, 3, 4, 5, 6, ...])")
+
+        # Dictionaries give up after 4.
+        eq(r({}), "{}")
+        d = {'alice': 1, 'bob': 2, 'charles': 3, 'dave': 4}
+        eq(r(d), "{'alice': 1, 'bob': 2, 'charles': 3, 'dave': 4}")
+        d['arthur'] = 1
+        eq(r(d), "{'alice': 1, 'arthur': 1, 'bob': 2, 'charles': 3, ...}")
+
+        # array.array after 5.
+        eq(r(array('i')), "array('i', [])")
+        eq(r(array('i', [1])), "array('i', [1])")
+        eq(r(array('i', [1, 2])), "array('i', [1, 2])")
+        eq(r(array('i', [1, 2, 3])), "array('i', [1, 2, 3])")
+        eq(r(array('i', [1, 2, 3, 4])), "array('i', [1, 2, 3, 4])")
+        eq(r(array('i', [1, 2, 3, 4, 5])), "array('i', [1, 2, 3, 4, 5])")
+        eq(r(array('i', [1, 2, 3, 4, 5, 6])),
+                   "array('i', [1, 2, 3, 4, 5, ...])")
+
+    def test_numbers(self):
+        eq = self.assertEquals
+        eq(r(123), repr(123))
+        eq(r(123L), repr(123L))
+        eq(r(1.0/3), repr(1.0/3))
+
+        n = 10L**100
+        expected = repr(n)[:18] + "..." + repr(n)[-19:]
+        eq(r(n), expected)
+
+    def test_instance(self):
+        eq = self.assertEquals
+        i1 = ClassWithRepr("a")
+        eq(r(i1), repr(i1))
+
+        i2 = ClassWithRepr("x"*1000)
+        expected = repr(i2)[:13] + "..." + repr(i2)[-14:]
+        eq(r(i2), expected)
+
+        i3 = ClassWithFailingRepr()
+        eq(r(i3), ("<ClassWithFailingRepr instance at %x>"%id(i3)))
+
+        s = r(ClassWithFailingRepr)
+        self.failUnless(s.startswith("<class "))
+        self.failUnless(s.endswith(">"))
+        self.failUnless(s.find("...") == 8)
+
+    def test_file(self):
+        fp = open(unittest.__file__)
+        self.failUnless(repr(fp).startswith(
+            "<open file '%s', mode 'r' at 0x" % unittest.__file__))
+        fp.close()
+        self.failUnless(repr(fp).startswith(
+            "<closed file '%s', mode 'r' at 0x" % unittest.__file__))
+
+    def test_lambda(self):
+        self.failUnless(repr(lambda x: x).startswith(
+            "<function <lambda"))
+        # XXX anonymous functions?  see func_repr
+
+    def test_builtin_function(self):
+        eq = self.assertEquals
+        # Functions
+        eq(repr(hash), '<built-in function hash>')
+        # Methods
+        self.failUnless(repr(''.split).startswith(
+            '<built-in method split of str object at 0x'))
+
+    def test_xrange(self):
+        import warnings
+        eq = self.assertEquals
+        eq(repr(xrange(1)), 'xrange(1)')
+        eq(repr(xrange(1, 2)), 'xrange(1, 2)')
+        eq(repr(xrange(1, 2, 3)), 'xrange(1, 4, 3)')
+
+    def test_nesting(self):
+        eq = self.assertEquals
+        # everything is meant to give up after 6 levels.
+        eq(r([[[[[[[]]]]]]]), "[[[[[[[]]]]]]]")
+        eq(r([[[[[[[[]]]]]]]]), "[[[[[[[...]]]]]]]")
+
+        eq(r(nestedTuple(6)), "(((((((),),),),),),)")
+        eq(r(nestedTuple(7)), "(((((((...),),),),),),)")
+
+        eq(r({ nestedTuple(5) : nestedTuple(5) }),
+           "{((((((),),),),),): ((((((),),),),),)}")
+        eq(r({ nestedTuple(6) : nestedTuple(6) }),
+           "{((((((...),),),),),): ((((((...),),),),),)}")
+
+        eq(r([[[[[[{}]]]]]]), "[[[[[[{}]]]]]]")
+        eq(r([[[[[[[{}]]]]]]]), "[[[[[[[...]]]]]]]")
+
+    def test_buffer(self):
+        # XXX doesn't test buffers with no b_base or read-write buffers (see
+        # bufferobject.c).  The test is fairly incomplete too.  Sigh.
+        x = buffer('foo')
+        self.failUnless(repr(x).startswith('<read-only buffer for 0x'))
+
+    def test_cell(self):
+        # XXX Hmm? How to get at a cell object?
+        pass
+
+    def test_descriptors(self):
+        eq = self.assertEquals
+        # method descriptors
+        eq(repr(dict.items), "<method 'items' of 'dict' objects>")
+        # XXX member descriptors
+        # XXX attribute descriptors
+        # XXX slot descriptors
+        # static and class methods
+        class C:
+            def foo(cls): pass
+        x = staticmethod(C.foo)
+        self.failUnless(repr(x).startswith('<staticmethod object at 0x'))
+        x = classmethod(C.foo)
+        self.failUnless(repr(x).startswith('<classmethod object at 0x'))
+
+def touch(path, text=''):
+    fp = open(path, 'w')
+    fp.write(text)
+    fp.close()
+
+def zap(actions, dirname, names):
+    for name in names:
+        actions.append(os.path.join(dirname, name))
+
+class LongReprTest(unittest.TestCase):
+    def setUp(self):
+        longname = 'areallylongpackageandmodulenametotestreprtruncation'
+        self.pkgname = os.path.join(longname)
+        self.subpkgname = os.path.join(longname, longname)
+        # Make the package and subpackage
+        shutil.rmtree(self.pkgname, ignore_errors=True)
+        os.mkdir(self.pkgname)
+        touch(os.path.join(self.pkgname, '__init__'+os.extsep+'py'))
+        shutil.rmtree(self.subpkgname, ignore_errors=True)
+        os.mkdir(self.subpkgname)
+        touch(os.path.join(self.subpkgname, '__init__'+os.extsep+'py'))
+        # Remember where we are
+        self.here = os.getcwd()
+        sys.path.insert(0, self.here)
+
+    def tearDown(self):
+        actions = []
+        os.path.walk(self.pkgname, zap, actions)
+        actions.append(self.pkgname)
+        actions.sort()
+        actions.reverse()
+        for p in actions:
+            if os.path.isdir(p):
+                os.rmdir(p)
+            else:
+                os.remove(p)
+        del sys.path[0]
+
+    def test_module(self):
+        eq = self.assertEquals
+        touch(os.path.join(self.subpkgname, self.pkgname + os.extsep + 'py'))
+        from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import areallylongpackageandmodulenametotestreprtruncation
+        eq(repr(areallylongpackageandmodulenametotestreprtruncation),
+           "<module '%s' from '%s'>" % (areallylongpackageandmodulenametotestreprtruncation.__name__, areallylongpackageandmodulenametotestreprtruncation.__file__))
+        eq(repr(sys), "<module 'sys' (built-in)>")
+
+    def test_type(self):
+        eq = self.assertEquals
+        touch(os.path.join(self.subpkgname, 'foo'+os.extsep+'py'), '''\
+class foo(object):
+    pass
+''')
+        from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import foo
+        eq(repr(foo.foo),
+               "<class '%s.foo'>" % foo.__name__)
+
+    def test_object(self):
+        # XXX Test the repr of a type with a really long tp_name but with no
+        # tp_repr.  WIBNI we had ::Inline? :)
+        pass
+
+    def test_class(self):
+        touch(os.path.join(self.subpkgname, 'bar'+os.extsep+'py'), '''\
+class bar:
+    pass
+''')
+        from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import bar
+        # Module name may be prefixed with "test.", depending on how run.
+        self.failUnless(repr(bar.bar).startswith(
+            "<class %s.bar at 0x" % bar.__name__))
+
+    def test_instance(self):
+        touch(os.path.join(self.subpkgname, 'baz'+os.extsep+'py'), '''\
+class baz:
+    pass
+''')
+        from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import baz
+        ibaz = baz.baz()
+        self.failUnless(repr(ibaz).startswith(
+            "<%s.baz instance at 0x" % baz.__name__))
+
+    def test_method(self):
+        eq = self.assertEquals
+        touch(os.path.join(self.subpkgname, 'qux'+os.extsep+'py'), '''\
+class aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:
+    def amethod(self): pass
+''')
+        from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import qux
+        # Unbound methods first
+        eq(repr(qux.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod),
+        '<unbound method aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod>')
+        # Bound method next
+        iqux = qux.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()
+        self.failUnless(repr(iqux.amethod).startswith(
+            '<bound method aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod of <%s.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa instance at 0x' \
+            % (qux.__name__,) ))
+
+    def test_builtin_function(self):
+        # XXX test built-in functions and methods with really long names
+        pass
+
+class ClassWithRepr:
+    def __init__(self, s):
+        self.s = s
+    def __repr__(self):
+        return "ClassWithLongRepr(%r)" % self.s
+
+
+class ClassWithFailingRepr:
+    def __repr__(self):
+        raise Exception("This should be caught by Repr.repr_instance")
+
+
+def test_main():
+    run_unittest(ReprTests)
+    if os.name != 'mac':
+        run_unittest(LongReprTest)
+
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_resource.py
===================================================================
--- vendor/Python/current/Lib/test/test_resource.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_resource.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,56 @@
+import os
+import resource
+
+from test.test_support import TESTFN
+
+# This test is checking a few specific problem spots.  RLIMIT_FSIZE
+# should be RLIM_INFINITY, which will be a really big number on a
+# platform with large file support.  On these platforms, we need to
+# test that the get/setrlimit functions properly convert the number to
+# a C long long and that the conversion doesn't raise an error.
+
+try:
+    cur, max = resource.getrlimit(resource.RLIMIT_FSIZE)
+except AttributeError:
+    pass
+else:
+    print resource.RLIM_INFINITY == max
+    resource.setrlimit(resource.RLIMIT_FSIZE, (cur, max))
+
+# Now check to see what happens when the RLIMIT_FSIZE is small.  Some
+# versions of Python were terminated by an uncaught SIGXFSZ, but
+# pythonrun.c has been fixed to ignore that exception.  If so, the
+# write() should return EFBIG when the limit is exceeded.
+
+# At least one platform has an unlimited RLIMIT_FSIZE and attempts to
+# change it raise ValueError instead.
+
+try:
+    try:
+        resource.setrlimit(resource.RLIMIT_FSIZE, (1024, max))
+        limit_set = 1
+    except ValueError:
+        limit_set = 0
+    f = open(TESTFN, "wb")
+    f.write("X" * 1024)
+    try:
+        f.write("Y")
+        f.flush()
+    except IOError:
+        if not limit_set:
+            raise
+    f.close()
+    os.unlink(TESTFN)
+finally:
+    resource.setrlimit(resource.RLIMIT_FSIZE, (cur, max))
+
+# And be sure that setrlimit is checking for really large values
+too_big = 10L**50
+try:
+    resource.setrlimit(resource.RLIMIT_FSIZE, (too_big, max))
+except (OverflowError, ValueError):
+    pass
+try:
+    resource.setrlimit(resource.RLIMIT_FSIZE, (max, too_big))
+except (OverflowError, ValueError):
+    pass

Added: vendor/Python/current/Lib/test/test_rfc822.py
===================================================================
--- vendor/Python/current/Lib/test/test_rfc822.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_rfc822.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,257 @@
+import rfc822
+import sys
+import unittest
+from test import test_support
+
+try:
+    from cStringIO import StringIO
+except ImportError:
+    from StringIO import StringIO
+
+
+class MessageTestCase(unittest.TestCase):
+    def create_message(self, msg):
+        return rfc822.Message(StringIO(msg))
+
+    def test_get(self):
+        msg = self.create_message(
+            'To: "last, first" <userid at foo.net>\n\ntest\n')
+        self.assert_(msg.get("to") == '"last, first" <userid at foo.net>')
+        self.assert_(msg.get("TO") == '"last, first" <userid at foo.net>')
+        self.assert_(msg.get("No-Such-Header") is None)
+        self.assert_(msg.get("No-Such-Header", "No-Such-Value")
+                     == "No-Such-Value")
+
+    def test_setdefault(self):
+        msg = self.create_message(
+            'To: "last, first" <userid at foo.net>\n\ntest\n')
+        self.assert_(not msg.has_key("New-Header"))
+        self.assert_(msg.setdefault("New-Header", "New-Value") == "New-Value")
+        self.assert_(msg.setdefault("New-Header", "Different-Value")
+                     == "New-Value")
+        self.assert_(msg["new-header"] == "New-Value")
+
+        self.assert_(msg.setdefault("Another-Header") == "")
+        self.assert_(msg["another-header"] == "")
+
+    def check(self, msg, results):
+        """Check addresses and the date."""
+        m = self.create_message(msg)
+        i = 0
+        for n, a in m.getaddrlist('to') + m.getaddrlist('cc'):
+            try:
+                mn, ma = results[i][0], results[i][1]
+            except IndexError:
+                print 'extra parsed address:', repr(n), repr(a)
+                continue
+            i = i + 1
+            self.assertEqual(mn, n,
+                             "Un-expected name: %s != %s" % (`mn`, `n`))
+            self.assertEqual(ma, a,
+                             "Un-expected address: %s != %s" % (`ma`, `a`))
+            if mn == n and ma == a:
+                pass
+            else:
+                print 'not found:', repr(n), repr(a)
+
+        out = m.getdate('date')
+        if out:
+            self.assertEqual(out,
+                             (1999, 1, 13, 23, 57, 35, 0, 1, 0),
+                             "date conversion failed")
+
+
+    # Note: all test cases must have the same date (in various formats),
+    # or no date!
+
+    def test_basic(self):
+        self.check(
+            'Date:    Wed, 13 Jan 1999 23:57:35 -0500\n'
+            'From:    Guido van Rossum <guido at CNRI.Reston.VA.US>\n'
+            'To:      "Guido van\n'
+            '\t : Rossum" <guido at python.org>\n'
+            'Subject: test2\n'
+            '\n'
+            'test2\n',
+            [('Guido van\n\t : Rossum', 'guido at python.org')])
+
+        self.check(
+            'From: Barry <bwarsaw at python.org\n'
+            'To: guido at python.org (Guido: the Barbarian)\n'
+            'Subject: nonsense\n'
+            'Date: Wednesday, January 13 1999 23:57:35 -0500\n'
+            '\n'
+            'test',
+            [('Guido: the Barbarian', 'guido at python.org')])
+
+        self.check(
+            'From: Barry <bwarsaw at python.org\n'
+            'To: guido at python.org (Guido: the Barbarian)\n'
+            'Cc: "Guido: the Madman" <guido at python.org>\n'
+            'Date:  13-Jan-1999 23:57:35 EST\n'
+            '\n'
+            'test',
+            [('Guido: the Barbarian', 'guido at python.org'),
+             ('Guido: the Madman', 'guido at python.org')
+             ])
+
+        self.check(
+            'To: "The monster with\n'
+            '     the very long name: Guido" <guido at python.org>\n'
+            'Date:    Wed, 13 Jan 1999 23:57:35 -0500\n'
+            '\n'
+            'test',
+            [('The monster with\n     the very long name: Guido',
+              'guido at python.org')])
+
+        self.check(
+            'To: "Amit J. Patel" <amitp at Theory.Stanford.EDU>\n'
+            'CC: Mike Fletcher <mfletch at vrtelecom.com>,\n'
+            '        "\'string-sig at python.org\'" <string-sig at python.org>\n'
+            'Cc: fooz at bat.com, bart at toof.com\n'
+            'Cc: goit at lip.com\n'
+            'Date:    Wed, 13 Jan 1999 23:57:35 -0500\n'
+            '\n'
+            'test',
+            [('Amit J. Patel', 'amitp at Theory.Stanford.EDU'),
+             ('Mike Fletcher', 'mfletch at vrtelecom.com'),
+             ("'string-sig at python.org'", 'string-sig at python.org'),
+             ('', 'fooz at bat.com'),
+             ('', 'bart at toof.com'),
+             ('', 'goit at lip.com'),
+             ])
+
+        self.check(
+            'To: Some One <someone at dom.ain>\n'
+            'From: Anudder Persin <subuddy.else at dom.ain>\n'
+            'Date:\n'
+            '\n'
+            'test',
+            [('Some One', 'someone at dom.ain')])
+
+        self.check(
+            'To: person at dom.ain (User J. Person)\n\n',
+            [('User J. Person', 'person at dom.ain')])
+
+    def test_doublecomment(self):
+        # The RFC allows comments within comments in an email addr
+        self.check(
+            'To: person at dom.ain ((User J. Person)), John Doe <foo at bar.com>\n\n',
+            [('User J. Person', 'person at dom.ain'), ('John Doe', 'foo at bar.com')])
+
+    def test_twisted(self):
+        # This one is just twisted.  I don't know what the proper
+        # result should be, but it shouldn't be to infloop, which is
+        # what used to happen!
+        self.check(
+            'To: <[smtp:dd47 at mail.xxx.edu]_at_hmhq at hdq-mdm1-imgout.companay.com>\n'
+            'Date:    Wed, 13 Jan 1999 23:57:35 -0500\n'
+            '\n'
+            'test',
+            [('', ''),
+             ('', 'dd47 at mail.xxx.edu'),
+             ('', '_at_hmhq at hdq-mdm1-imgout.companay.com'),
+             ])
+
+    def test_commas_in_full_name(self):
+        # This exercises the old commas-in-a-full-name bug, which
+        # should be doing the right thing in recent versions of the
+        # module.
+        self.check(
+            'To: "last, first" <userid at foo.net>\n'
+            '\n'
+            'test',
+            [('last, first', 'userid at foo.net')])
+
+    def test_quoted_name(self):
+        self.check(
+            'To: (Comment stuff) "Quoted name"@somewhere.com\n'
+            '\n'
+            'test',
+            [('Comment stuff', '"Quoted name"@somewhere.com')])
+
+    def test_bogus_to_header(self):
+        self.check(
+            'To: :\n'
+            'Cc: goit at lip.com\n'
+            'Date:    Wed, 13 Jan 1999 23:57:35 -0500\n'
+            '\n'
+            'test',
+            [('', 'goit at lip.com')])
+
+    def test_addr_ipquad(self):
+        self.check(
+            'To: guido@[132.151.1.21]\n'
+            '\n'
+            'foo',
+            [('', 'guido@[132.151.1.21]')])
+
+    def test_iter(self):
+        m = rfc822.Message(StringIO(
+            'Date:    Wed, 13 Jan 1999 23:57:35 -0500\n'
+            'From:    Guido van Rossum <guido at CNRI.Reston.VA.US>\n'
+            'To:      "Guido van\n'
+            '\t : Rossum" <guido at python.org>\n'
+            'Subject: test2\n'
+            '\n'
+            'test2\n' ))
+        self.assertEqual(sorted(m), ['date', 'from', 'subject', 'to'])
+
+    def test_rfc2822_phrases(self):
+        # RFC 2822 (the update to RFC 822) specifies that dots in phrases are
+        # obsolete syntax, which conforming programs MUST recognize but NEVER
+        # generate (see $4.1 Miscellaneous obsolete tokens).  This is a
+        # departure from RFC 822 which did not allow dots in non-quoted
+        # phrases.
+        self.check('To: User J. Person <person at dom.ain>\n\n',
+                   [('User J. Person', 'person at dom.ain')])
+
+    # This takes too long to add to the test suite
+##    def test_an_excrutiatingly_long_address_field(self):
+##        OBSCENELY_LONG_HEADER_MULTIPLIER = 10000
+##        oneaddr = ('Person' * 10) + '@' + ('.'.join(['dom']*10)) + '.com'
+##        addr = ', '.join([oneaddr] * OBSCENELY_LONG_HEADER_MULTIPLIER)
+##        lst = rfc822.AddrlistClass(addr).getaddrlist()
+##        self.assertEqual(len(lst), OBSCENELY_LONG_HEADER_MULTIPLIER)
+
+    def test_2getaddrlist(self):
+        eq = self.assertEqual
+        msg = self.create_message("""\
+To: aperson at dom.ain
+Cc: bperson at dom.ain
+Cc: cperson at dom.ain
+Cc: dperson at dom.ain
+
+A test message.
+""")
+        ccs = [('', a) for a in
+               ['bperson at dom.ain', 'cperson at dom.ain', 'dperson at dom.ain']]
+        addrs = msg.getaddrlist('cc')
+        addrs.sort()
+        eq(addrs, ccs)
+        # Try again, this one used to fail
+        addrs = msg.getaddrlist('cc')
+        addrs.sort()
+        eq(addrs, ccs)
+
+    def test_parseaddr(self):
+        eq = self.assertEqual
+        eq(rfc822.parseaddr('<>'), ('', ''))
+        eq(rfc822.parseaddr('aperson at dom.ain'), ('', 'aperson at dom.ain'))
+        eq(rfc822.parseaddr('bperson at dom.ain (Bea A. Person)'),
+           ('Bea A. Person', 'bperson at dom.ain'))
+        eq(rfc822.parseaddr('Cynthia Person <cperson at dom.ain>'),
+           ('Cynthia Person', 'cperson at dom.ain'))
+
+    def test_quote_unquote(self):
+        eq = self.assertEqual
+        eq(rfc822.quote('foo\\wacky"name'), 'foo\\\\wacky\\"name')
+        eq(rfc822.unquote('"foo\\\\wacky\\"name"'), 'foo\\wacky"name')
+
+
+def test_main():
+    test_support.run_unittest(MessageTestCase)
+
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_rgbimg.py
===================================================================
--- vendor/Python/current/Lib/test/test_rgbimg.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_rgbimg.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,70 @@
+# Testing rgbimg module
+
+import warnings
+warnings.filterwarnings("ignore",
+                        "the rgbimg module is deprecated",
+                        DeprecationWarning,
+                        ".*test_rgbimg$")
+import rgbimg
+
+import os, uu
+
+from test.test_support import verbose, unlink, findfile
+
+class error(Exception):
+    pass
+
+print 'RGBimg test suite:'
+
+def testimg(rgb_file, raw_file):
+    rgb_file = findfile(rgb_file)
+    raw_file = findfile(raw_file)
+    width, height = rgbimg.sizeofimage(rgb_file)
+    rgb = rgbimg.longimagedata(rgb_file)
+    if len(rgb) != width * height * 4:
+        raise error, 'bad image length'
+    raw = open(raw_file, 'rb').read()
+    if rgb != raw:
+        raise error, \
+              'images don\'t match for '+rgb_file+' and '+raw_file
+    for depth in [1, 3, 4]:
+        rgbimg.longstoimage(rgb, width, height, depth, '@.rgb')
+    os.unlink('@.rgb')
+
+table = [
+    ('testrgb'+os.extsep+'uue', 'test'+os.extsep+'rgb'),
+    ('testimg'+os.extsep+'uue', 'test'+os.extsep+'rawimg'),
+    ('testimgr'+os.extsep+'uue', 'test'+os.extsep+'rawimg'+os.extsep+'rev'),
+    ]
+for source, target in table:
+    source = findfile(source)
+    target = findfile(target)
+    if verbose:
+        print "uudecoding", source, "->", target, "..."
+    uu.decode(source, target)
+
+if verbose:
+    print "testing..."
+
+ttob = rgbimg.ttob(0)
+if ttob != 0:
+    raise error, 'ttob should start out as zero'
+
+testimg('test'+os.extsep+'rgb', 'test'+os.extsep+'rawimg')
+
+ttob = rgbimg.ttob(1)
+if ttob != 0:
+    raise error, 'ttob should be zero'
+
+testimg('test'+os.extsep+'rgb', 'test'+os.extsep+'rawimg'+os.extsep+'rev')
+
+ttob = rgbimg.ttob(0)
+if ttob != 1:
+    raise error, 'ttob should be one'
+
+ttob = rgbimg.ttob(0)
+if ttob != 0:
+    raise error, 'ttob should be zero'
+
+for source, target in table:
+    unlink(findfile(target))

Added: vendor/Python/current/Lib/test/test_richcmp.py
===================================================================
--- vendor/Python/current/Lib/test/test_richcmp.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_richcmp.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,337 @@
+# Tests for rich comparisons
+
+import unittest
+from test import test_support
+
+import operator
+
+class Number:
+
+    def __init__(self, x):
+        self.x = x
+
+    def __lt__(self, other):
+        return self.x < other
+
+    def __le__(self, other):
+        return self.x <= other
+
+    def __eq__(self, other):
+        return self.x == other
+
+    def __ne__(self, other):
+        return self.x != other
+
+    def __gt__(self, other):
+        return self.x > other
+
+    def __ge__(self, other):
+        return self.x >= other
+
+    def __cmp__(self, other):
+        raise test_support.TestFailed, "Number.__cmp__() should not be called"
+
+    def __repr__(self):
+        return "Number(%r)" % (self.x, )
+
+class Vector:
+
+    def __init__(self, data):
+        self.data = data
+
+    def __len__(self):
+        return len(self.data)
+
+    def __getitem__(self, i):
+        return self.data[i]
+
+    def __setitem__(self, i, v):
+        self.data[i] = v
+
+    def __hash__(self):
+        raise TypeError, "Vectors cannot be hashed"
+
+    def __nonzero__(self):
+        raise TypeError, "Vectors cannot be used in Boolean contexts"
+
+    def __cmp__(self, other):
+        raise test_support.TestFailed, "Vector.__cmp__() should not be called"
+
+    def __repr__(self):
+        return "Vector(%r)" % (self.data, )
+
+    def __lt__(self, other):
+        return Vector([a < b for a, b in zip(self.data, self.__cast(other))])
+
+    def __le__(self, other):
+        return Vector([a <= b for a, b in zip(self.data, self.__cast(other))])
+
+    def __eq__(self, other):
+        return Vector([a == b for a, b in zip(self.data, self.__cast(other))])
+
+    def __ne__(self, other):
+        return Vector([a != b for a, b in zip(self.data, self.__cast(other))])
+
+    def __gt__(self, other):
+        return Vector([a > b for a, b in zip(self.data, self.__cast(other))])
+
+    def __ge__(self, other):
+        return Vector([a >= b for a, b in zip(self.data, self.__cast(other))])
+
+    def __cast(self, other):
+        if isinstance(other, Vector):
+            other = other.data
+        if len(self.data) != len(other):
+            raise ValueError, "Cannot compare vectors of different length"
+        return other
+
+opmap = {
+    "lt": (lambda a,b: a< b, operator.lt, operator.__lt__),
+    "le": (lambda a,b: a<=b, operator.le, operator.__le__),
+    "eq": (lambda a,b: a==b, operator.eq, operator.__eq__),
+    "ne": (lambda a,b: a!=b, operator.ne, operator.__ne__),
+    "gt": (lambda a,b: a> b, operator.gt, operator.__gt__),
+    "ge": (lambda a,b: a>=b, operator.ge, operator.__ge__)
+}
+
+class VectorTest(unittest.TestCase):
+
+    def checkfail(self, error, opname, *args):
+        for op in opmap[opname]:
+            self.assertRaises(error, op, *args)
+
+    def checkequal(self, opname, a, b, expres):
+        for op in opmap[opname]:
+            realres = op(a, b)
+            # can't use assertEqual(realres, expres) here
+            self.assertEqual(len(realres), len(expres))
+            for i in xrange(len(realres)):
+                # results are bool, so we can use "is" here
+                self.assert_(realres[i] is expres[i])
+
+    def test_mixed(self):
+        # check that comparisons involving Vector objects
+        # which return rich results (i.e. Vectors with itemwise
+        # comparison results) work
+        a = Vector(range(2))
+        b = Vector(range(3))
+        # all comparisons should fail for different length
+        for opname in opmap:
+            self.checkfail(ValueError, opname, a, b)
+
+        a = range(5)
+        b = 5 * [2]
+        # try mixed arguments (but not (a, b) as that won't return a bool vector)
+        args = [(a, Vector(b)), (Vector(a), b), (Vector(a), Vector(b))]
+        for (a, b) in args:
+            self.checkequal("lt", a, b, [True,  True,  False, False, False])
+            self.checkequal("le", a, b, [True,  True,  True,  False, False])
+            self.checkequal("eq", a, b, [False, False, True,  False, False])
+            self.checkequal("ne", a, b, [True,  True,  False, True,  True ])
+            self.checkequal("gt", a, b, [False, False, False, True,  True ])
+            self.checkequal("ge", a, b, [False, False, True,  True,  True ])
+
+            for ops in opmap.itervalues():
+                for op in ops:
+                    # calls __nonzero__, which should fail
+                    self.assertRaises(TypeError, bool, op(a, b))
+
+class NumberTest(unittest.TestCase):
+
+    def test_basic(self):
+        # Check that comparisons involving Number objects
+        # give the same results give as comparing the
+        # corresponding ints
+        for a in xrange(3):
+            for b in xrange(3):
+                for typea in (int, Number):
+                    for typeb in (int, Number):
+                        if typea==typeb==int:
+                            continue # the combination int, int is useless
+                        ta = typea(a)
+                        tb = typeb(b)
+                        for ops in opmap.itervalues():
+                            for op in ops:
+                                realoutcome = op(a, b)
+                                testoutcome = op(ta, tb)
+                                self.assertEqual(realoutcome, testoutcome)
+
+    def checkvalue(self, opname, a, b, expres):
+        for typea in (int, Number):
+            for typeb in (int, Number):
+                ta = typea(a)
+                tb = typeb(b)
+                for op in opmap[opname]:
+                    realres = op(ta, tb)
+                    realres = getattr(realres, "x", realres)
+                    self.assert_(realres is expres)
+
+    def test_values(self):
+        # check all operators and all comparison results
+        self.checkvalue("lt", 0, 0, False)
+        self.checkvalue("le", 0, 0, True )
+        self.checkvalue("eq", 0, 0, True )
+        self.checkvalue("ne", 0, 0, False)
+        self.checkvalue("gt", 0, 0, False)
+        self.checkvalue("ge", 0, 0, True )
+
+        self.checkvalue("lt", 0, 1, True )
+        self.checkvalue("le", 0, 1, True )
+        self.checkvalue("eq", 0, 1, False)
+        self.checkvalue("ne", 0, 1, True )
+        self.checkvalue("gt", 0, 1, False)
+        self.checkvalue("ge", 0, 1, False)
+
+        self.checkvalue("lt", 1, 0, False)
+        self.checkvalue("le", 1, 0, False)
+        self.checkvalue("eq", 1, 0, False)
+        self.checkvalue("ne", 1, 0, True )
+        self.checkvalue("gt", 1, 0, True )
+        self.checkvalue("ge", 1, 0, True )
+
+class MiscTest(unittest.TestCase):
+
+    def test_misbehavin(self):
+        class Misb:
+            def __lt__(self, other): return 0
+            def __gt__(self, other): return 0
+            def __eq__(self, other): return 0
+            def __le__(self, other): raise TestFailed, "This shouldn't happen"
+            def __ge__(self, other): raise TestFailed, "This shouldn't happen"
+            def __ne__(self, other): raise TestFailed, "This shouldn't happen"
+            def __cmp__(self, other): raise RuntimeError, "expected"
+        a = Misb()
+        b = Misb()
+        self.assertEqual(a<b, 0)
+        self.assertEqual(a==b, 0)
+        self.assertEqual(a>b, 0)
+        self.assertRaises(RuntimeError, cmp, a, b)
+
+    def test_not(self):
+        # Check that exceptions in __nonzero__ are properly
+        # propagated by the not operator
+        import operator
+        class Exc(Exception):
+            pass
+        class Bad:
+            def __nonzero__(self):
+                raise Exc
+
+        def do(bad):
+            not bad
+
+        for func in (do, operator.not_):
+            self.assertRaises(Exc, func, Bad())
+
+    def test_recursion(self):
+        # Check that comparison for recursive objects fails gracefully
+        from UserList import UserList
+        a = UserList()
+        b = UserList()
+        a.append(b)
+        b.append(a)
+        self.assertRaises(RuntimeError, operator.eq, a, b)
+        self.assertRaises(RuntimeError, operator.ne, a, b)
+        self.assertRaises(RuntimeError, operator.lt, a, b)
+        self.assertRaises(RuntimeError, operator.le, a, b)
+        self.assertRaises(RuntimeError, operator.gt, a, b)
+        self.assertRaises(RuntimeError, operator.ge, a, b)
+
+        b.append(17)
+        # Even recursive lists of different lengths are different,
+        # but they cannot be ordered
+        self.assert_(not (a == b))
+        self.assert_(a != b)
+        self.assertRaises(RuntimeError, operator.lt, a, b)
+        self.assertRaises(RuntimeError, operator.le, a, b)
+        self.assertRaises(RuntimeError, operator.gt, a, b)
+        self.assertRaises(RuntimeError, operator.ge, a, b)
+        a.append(17)
+        self.assertRaises(RuntimeError, operator.eq, a, b)
+        self.assertRaises(RuntimeError, operator.ne, a, b)
+        a.insert(0, 11)
+        b.insert(0, 12)
+        self.assert_(not (a == b))
+        self.assert_(a != b)
+        self.assert_(a < b)
+
+class DictTest(unittest.TestCase):
+
+    def test_dicts(self):
+        # Verify that __eq__ and __ne__ work for dicts even if the keys and
+        # values don't support anything other than __eq__ and __ne__ (and
+        # __hash__).  Complex numbers are a fine example of that.
+        import random
+        imag1a = {}
+        for i in range(50):
+            imag1a[random.randrange(100)*1j] = random.randrange(100)*1j
+        items = imag1a.items()
+        random.shuffle(items)
+        imag1b = {}
+        for k, v in items:
+            imag1b[k] = v
+        imag2 = imag1b.copy()
+        imag2[k] = v + 1.0
+        self.assert_(imag1a == imag1a)
+        self.assert_(imag1a == imag1b)
+        self.assert_(imag2 == imag2)
+        self.assert_(imag1a != imag2)
+        for opname in ("lt", "le", "gt", "ge"):
+            for op in opmap[opname]:
+                self.assertRaises(TypeError, op, imag1a, imag2)
+
+class ListTest(unittest.TestCase):
+
+    def assertIs(self, a, b):
+        self.assert_(a is b)
+
+    def test_coverage(self):
+        # exercise all comparisons for lists
+        x = [42]
+        self.assertIs(x<x, False)
+        self.assertIs(x<=x, True)
+        self.assertIs(x==x, True)
+        self.assertIs(x!=x, False)
+        self.assertIs(x>x, False)
+        self.assertIs(x>=x, True)
+        y = [42, 42]
+        self.assertIs(x<y, True)
+        self.assertIs(x<=y, True)
+        self.assertIs(x==y, False)
+        self.assertIs(x!=y, True)
+        self.assertIs(x>y, False)
+        self.assertIs(x>=y, False)
+
+    def test_badentry(self):
+        # make sure that exceptions for item comparison are properly
+        # propagated in list comparisons
+        class Exc(Exception):
+            pass
+        class Bad:
+            def __eq__(self, other):
+                raise Exc
+
+        x = [Bad()]
+        y = [Bad()]
+
+        for op in opmap["eq"]:
+            self.assertRaises(Exc, op, x, y)
+
+    def test_goodentry(self):
+        # This test exercises the final call to PyObject_RichCompare()
+        # in Objects/listobject.c::list_richcompare()
+        class Good:
+            def __lt__(self, other):
+                return True
+
+        x = [Good()]
+        y = [Good()]
+
+        for op in opmap["lt"]:
+            self.assertIs(op(x, y), True)
+
+def test_main():
+    test_support.run_unittest(VectorTest, NumberTest, MiscTest, DictTest, ListTest)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_robotparser.py
===================================================================
--- vendor/Python/current/Lib/test/test_robotparser.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_robotparser.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,142 @@
+import unittest, StringIO, robotparser
+from test import test_support
+
+class RobotTestCase(unittest.TestCase):
+    def __init__(self, index, parser, url, good, agent):
+        unittest.TestCase.__init__(self)
+        if good:
+            self.str = "RobotTest(%d, good, %s)" % (index, url)
+        else:
+            self.str = "RobotTest(%d, bad, %s)" % (index, url)
+        self.parser = parser
+        self.url = url
+        self.good = good
+        self.agent = agent
+
+    def runTest(self):
+        if isinstance(self.url, tuple):
+            agent, url = self.url
+        else:
+            url = self.url
+            agent = self.agent
+        if self.good:
+            self.failUnless(self.parser.can_fetch(agent, url))
+        else:
+            self.failIf(self.parser.can_fetch(agent, url))
+
+    def __str__(self):
+        return self.str
+
+tests = unittest.TestSuite()
+
+def RobotTest(index, robots_txt, good_urls, bad_urls,
+              agent="test_robotparser"):
+
+    lines = StringIO.StringIO(robots_txt).readlines()
+    parser = robotparser.RobotFileParser()
+    parser.parse(lines)
+    for url in good_urls:
+        tests.addTest(RobotTestCase(index, parser, url, 1, agent))
+    for url in bad_urls:
+        tests.addTest(RobotTestCase(index, parser, url, 0, agent))
+
+# Examples from http://www.robotstxt.org/wc/norobots.html (fetched 2002)
+
+# 1.
+doc = """
+User-agent: *
+Disallow: /cyberworld/map/ # This is an infinite virtual URL space
+Disallow: /tmp/ # these will soon disappear
+Disallow: /foo.html
+"""
+
+good = ['/','/test.html']
+bad = ['/cyberworld/map/index.html','/tmp/xxx','/foo.html']
+
+RobotTest(1, doc, good, bad)
+
+# 2.
+doc = """
+# robots.txt for http://www.example.com/
+
+User-agent: *
+Disallow: /cyberworld/map/ # This is an infinite virtual URL space
+
+# Cybermapper knows where to go.
+User-agent: cybermapper
+Disallow:
+
+"""
+
+good = ['/','/test.html',('cybermapper','/cyberworld/map/index.html')]
+bad = ['/cyberworld/map/index.html']
+
+RobotTest(2, doc, good, bad)
+
+# 3.
+doc = """
+# go away
+User-agent: *
+Disallow: /
+"""
+
+good = []
+bad = ['/cyberworld/map/index.html','/','/tmp/']
+
+RobotTest(3, doc, good, bad)
+
+# Examples from http://www.robotstxt.org/wc/norobots-rfc.html (fetched 2002)
+
+# 4.
+doc = """
+User-agent: figtree
+Disallow: /tmp
+Disallow: /a%3cd.html
+Disallow: /a%2fb.html
+Disallow: /%7ejoe/index.html
+"""
+
+good = [] # XFAIL '/a/b.html'
+bad = ['/tmp','/tmp.html','/tmp/a.html',
+       '/a%3cd.html','/a%3Cd.html','/a%2fb.html',
+       '/~joe/index.html'
+       ]
+
+RobotTest(4, doc, good, bad, 'figtree')
+RobotTest(5, doc, good, bad, 'FigTree Robot libwww-perl/5.04')
+
+# 6.
+doc = """
+User-agent: *
+Disallow: /tmp/
+Disallow: /a%3Cd.html
+Disallow: /a/b.html
+Disallow: /%7ejoe/index.html
+"""
+
+good = ['/tmp',] # XFAIL: '/a%2fb.html'
+bad = ['/tmp/','/tmp/a.html',
+       '/a%3cd.html','/a%3Cd.html',"/a/b.html",
+       '/%7Ejoe/index.html']
+
+RobotTest(6, doc, good, bad)
+
+# From bug report #523041
+
+# 7.
+doc = """
+User-Agent: *
+Disallow: /.
+"""
+
+good = ['/foo.html']
+bad = [] # Bug report says "/" should be denied, but that is not in the RFC
+
+RobotTest(7, doc, good, bad)
+
+def test_main():
+    test_support.run_suite(tests)
+
+if __name__=='__main__':
+    test_support.Verbose = 1
+    test_support.run_suite(tests)

Added: vendor/Python/current/Lib/test/test_runpy.py
===================================================================
--- vendor/Python/current/Lib/test/test_runpy.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_runpy.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,172 @@
+# Test the runpy module
+import unittest
+import os
+import os.path
+import sys
+import tempfile
+from test.test_support import verbose, run_unittest
+from runpy import _run_module_code, run_module
+
+# Set up the test code and expected results
+
+class RunModuleCodeTest(unittest.TestCase):
+
+    expected_result = ["Top level assignment", "Lower level reference"]
+    test_source = (
+        "# Check basic code execution\n"
+        "result = ['Top level assignment']\n"
+        "def f():\n"
+        "    result.append('Lower level reference')\n"
+        "f()\n"
+        "# Check the sys module\n"
+        "import sys\n"
+        "run_argv0 = sys.argv[0]\n"
+        "if __name__ in sys.modules:\n"
+        "    run_name = sys.modules[__name__].__name__\n"
+        "# Check nested operation\n"
+        "import runpy\n"
+        "nested = runpy._run_module_code('x=1\\n', mod_name='<run>',\n"
+        "                                          alter_sys=True)\n"
+    )
+
+
+    def test_run_module_code(self):
+        initial = object()
+        name = "<Nonsense>"
+        file = "Some other nonsense"
+        loader = "Now you're just being silly"
+        d1 = dict(initial=initial)
+        saved_argv0 = sys.argv[0]
+        d2 = _run_module_code(self.test_source,
+                              d1,
+                              name,
+                              file,
+                              loader,
+                              True)
+        self.failUnless("result" not in d1)
+        self.failUnless(d2["initial"] is initial)
+        self.failUnless(d2["result"] == self.expected_result)
+        self.failUnless(d2["nested"]["x"] == 1)
+        self.failUnless(d2["__name__"] is name)
+        self.failUnless(d2["run_name"] is name)
+        self.failUnless(d2["__file__"] is file)
+        self.failUnless(d2["run_argv0"] is file)
+        self.failUnless(d2["__loader__"] is loader)
+        self.failUnless(sys.argv[0] is saved_argv0)
+        self.failUnless(name not in sys.modules)
+
+    def test_run_module_code_defaults(self):
+        saved_argv0 = sys.argv[0]
+        d = _run_module_code(self.test_source)
+        self.failUnless(d["result"] == self.expected_result)
+        self.failUnless(d["__name__"] is None)
+        self.failUnless(d["__file__"] is None)
+        self.failUnless(d["__loader__"] is None)
+        self.failUnless(d["run_argv0"] is saved_argv0)
+        self.failUnless("run_name" not in d)
+        self.failUnless(sys.argv[0] is saved_argv0)
+
+class RunModuleTest(unittest.TestCase):
+
+    def expect_import_error(self, mod_name):
+        try:
+            run_module(mod_name)
+        except ImportError:
+            pass
+        else:
+            self.fail("Expected import error for " + mod_name)
+
+    def test_invalid_names(self):
+        self.expect_import_error("sys")
+        self.expect_import_error("sys.imp.eric")
+        self.expect_import_error("os.path.half")
+        self.expect_import_error("a.bee")
+        self.expect_import_error(".howard")
+        self.expect_import_error("..eaten")
+
+    def test_library_module(self):
+        run_module("runpy")
+
+    def _make_pkg(self, source, depth):
+        pkg_name = "__runpy_pkg__"
+        init_fname = "__init__"+os.extsep+"py"
+        test_fname = "runpy_test"+os.extsep+"py"
+        pkg_dir = sub_dir = tempfile.mkdtemp()
+        if verbose: print "  Package tree in:", sub_dir
+        sys.path.insert(0, pkg_dir)
+        if verbose: print "  Updated sys.path:", sys.path[0]
+        for i in range(depth):
+            sub_dir = os.path.join(sub_dir, pkg_name)
+            os.mkdir(sub_dir)
+            if verbose: print "  Next level in:", sub_dir
+            pkg_fname = os.path.join(sub_dir, init_fname)
+            pkg_file = open(pkg_fname, "w")
+            pkg_file.close()
+            if verbose: print "  Created:", pkg_fname
+        mod_fname = os.path.join(sub_dir, test_fname)
+        mod_file = open(mod_fname, "w")
+        mod_file.write(source)
+        mod_file.close()
+        if verbose: print "  Created:", mod_fname
+        mod_name = (pkg_name+".")*depth + "runpy_test"
+        return pkg_dir, mod_fname, mod_name
+
+    def _del_pkg(self, top, depth, mod_name):
+        for i in range(depth+1): # Don't forget the module itself
+            parts = mod_name.rsplit(".", i)
+            entry = parts[0]
+            try:
+                del sys.modules[entry]
+            except KeyError, ex:
+                if verbose: print ex # Persist with cleaning up
+        if verbose: print "  Removed sys.modules entries"
+        del sys.path[0]
+        if verbose: print "  Removed sys.path entry"
+        for root, dirs, files in os.walk(top, topdown=False):
+            for name in files:
+                try:
+                    os.remove(os.path.join(root, name))
+                except OSError, ex:
+                    if verbose: print ex # Persist with cleaning up
+            for name in dirs:
+                fullname = os.path.join(root, name)
+                try:
+                    os.rmdir(fullname)
+                except OSError, ex:
+                    if verbose: print ex # Persist with cleaning up
+        try:
+            os.rmdir(top)
+            if verbose: print "  Removed package tree"
+        except OSError, ex:
+            if verbose: print ex # Persist with cleaning up
+
+    def _check_module(self, depth):
+        pkg_dir, mod_fname, mod_name = (
+               self._make_pkg("x=1\n", depth))
+        try:
+            if verbose: print "Running from source:", mod_name
+            d1 = run_module(mod_name) # Read from source
+            self.failUnless(d1["x"] == 1)
+            del d1 # Ensure __loader__ entry doesn't keep file open
+            __import__(mod_name)
+            os.remove(mod_fname)
+            if verbose: print "Running from compiled:", mod_name
+            d2 = run_module(mod_name) # Read from bytecode
+            self.failUnless(d2["x"] == 1)
+            del d2 # Ensure __loader__ entry doesn't keep file open
+        finally:
+            self._del_pkg(pkg_dir, depth, mod_name)
+        if verbose: print "Module executed successfully"
+
+    def test_run_module(self):
+        for depth in range(4):
+            if verbose: print "Testing package depth:", depth
+            self._check_module(depth)
+
+
+def test_main():
+    run_unittest(RunModuleCodeTest)
+    run_unittest(RunModuleTest)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_sax.py
===================================================================
--- vendor/Python/current/Lib/test/test_sax.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_sax.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,788 @@
+# regression test for SAX 2.0            -*- coding: iso-8859-1 -*-
+# $Id: test_sax.py 53755 2007-02-12 12:21:41Z martin.v.loewis $
+
+from xml.sax import make_parser, ContentHandler, \
+                    SAXException, SAXReaderNotAvailable, SAXParseException
+try:
+    make_parser()
+except SAXReaderNotAvailable:
+    # don't try to test this module if we cannot create a parser
+    raise ImportError("no XML parsers available")
+from xml.sax.saxutils import XMLGenerator, escape, unescape, quoteattr, \
+                             XMLFilterBase
+from xml.sax.expatreader import create_parser
+from xml.sax.xmlreader import InputSource, AttributesImpl, AttributesNSImpl
+from cStringIO import StringIO
+from test.test_support import verify, verbose, TestFailed, findfile
+import os
+
+# ===== Utilities
+
+tests = 0
+failures = []
+
+def confirm(outcome, name):
+    global tests
+
+    tests = tests + 1
+    if outcome:
+        if verbose:
+            print "Passed", name
+    else:
+        failures.append(name)
+
+def test_make_parser2():
+    try:
+        # Creating parsers several times in a row should succeed.
+        # Testing this because there have been failures of this kind
+        # before.
+        from xml.sax import make_parser
+        p = make_parser()
+        from xml.sax import make_parser
+        p = make_parser()
+        from xml.sax import make_parser
+        p = make_parser()
+        from xml.sax import make_parser
+        p = make_parser()
+        from xml.sax import make_parser
+        p = make_parser()
+        from xml.sax import make_parser
+        p = make_parser()
+    except:
+        return 0
+    else:
+        return p
+
+
+# ===========================================================================
+#
+#   saxutils tests
+#
+# ===========================================================================
+
+# ===== escape
+
+def test_escape_basic():
+    return escape("Donald Duck & Co") == "Donald Duck &amp; Co"
+
+def test_escape_all():
+    return escape("<Donald Duck & Co>") == "&lt;Donald Duck &amp; Co&gt;"
+
+def test_escape_extra():
+    return escape("Hei på deg", {"å" : "&aring;"}) == "Hei p&aring; deg"
+
+# ===== unescape
+
+def test_unescape_basic():
+    return unescape("Donald Duck &amp; Co") == "Donald Duck & Co"
+
+def test_unescape_all():
+    return unescape("&lt;Donald Duck &amp; Co&gt;") == "<Donald Duck & Co>"
+
+def test_unescape_extra():
+    return unescape("Hei på deg", {"å" : "&aring;"}) == "Hei p&aring; deg"
+
+def test_unescape_amp_extra():
+    return unescape("&amp;foo;", {"&foo;": "splat"}) == "&foo;"
+
+# ===== quoteattr
+
+def test_quoteattr_basic():
+    return quoteattr("Donald Duck & Co") == '"Donald Duck &amp; Co"'
+
+def test_single_quoteattr():
+    return (quoteattr('Includes "double" quotes')
+            == '\'Includes "double" quotes\'')
+
+def test_double_quoteattr():
+    return (quoteattr("Includes 'single' quotes")
+            == "\"Includes 'single' quotes\"")
+
+def test_single_double_quoteattr():
+    return (quoteattr("Includes 'single' and \"double\" quotes")
+            == "\"Includes 'single' and &quot;double&quot; quotes\"")
+
+# ===== make_parser
+
+def test_make_parser():
+    try:
+        # Creating a parser should succeed - it should fall back
+        # to the expatreader
+        p = make_parser(['xml.parsers.no_such_parser'])
+    except:
+        return 0
+    else:
+        return p
+
+
+# ===== XMLGenerator
+
+start = '<?xml version="1.0" encoding="iso-8859-1"?>\n'
+
+def test_xmlgen_basic():
+    result = StringIO()
+    gen = XMLGenerator(result)
+    gen.startDocument()
+    gen.startElement("doc", {})
+    gen.endElement("doc")
+    gen.endDocument()
+
+    return result.getvalue() == start + "<doc></doc>"
+
+def test_xmlgen_content():
+    result = StringIO()
+    gen = XMLGenerator(result)
+
+    gen.startDocument()
+    gen.startElement("doc", {})
+    gen.characters("huhei")
+    gen.endElement("doc")
+    gen.endDocument()
+
+    return result.getvalue() == start + "<doc>huhei</doc>"
+
+def test_xmlgen_pi():
+    result = StringIO()
+    gen = XMLGenerator(result)
+
+    gen.startDocument()
+    gen.processingInstruction("test", "data")
+    gen.startElement("doc", {})
+    gen.endElement("doc")
+    gen.endDocument()
+
+    return result.getvalue() == start + "<?test data?><doc></doc>"
+
+def test_xmlgen_content_escape():
+    result = StringIO()
+    gen = XMLGenerator(result)
+
+    gen.startDocument()
+    gen.startElement("doc", {})
+    gen.characters("<huhei&")
+    gen.endElement("doc")
+    gen.endDocument()
+
+    return result.getvalue() == start + "<doc>&lt;huhei&amp;</doc>"
+
+def test_xmlgen_attr_escape():
+    result = StringIO()
+    gen = XMLGenerator(result)
+
+    gen.startDocument()
+    gen.startElement("doc", {"a": '"'})
+    gen.startElement("e", {"a": "'"})
+    gen.endElement("e")
+    gen.startElement("e", {"a": "'\""})
+    gen.endElement("e")
+    gen.startElement("e", {"a": "\n\r\t"})
+    gen.endElement("e")
+    gen.endElement("doc")
+    gen.endDocument()
+
+    return result.getvalue() == start + ("<doc a='\"'><e a=\"'\"></e>"
+                                         "<e a=\"'&quot;\"></e>"
+                                         "<e a=\"&#10;&#13;&#9;\"></e></doc>")
+
+def test_xmlgen_ignorable():
+    result = StringIO()
+    gen = XMLGenerator(result)
+
+    gen.startDocument()
+    gen.startElement("doc", {})
+    gen.ignorableWhitespace(" ")
+    gen.endElement("doc")
+    gen.endDocument()
+
+    return result.getvalue() == start + "<doc> </doc>"
+
+ns_uri = "http://www.python.org/xml-ns/saxtest/"
+
+def test_xmlgen_ns():
+    result = StringIO()
+    gen = XMLGenerator(result)
+
+    gen.startDocument()
+    gen.startPrefixMapping("ns1", ns_uri)
+    gen.startElementNS((ns_uri, "doc"), "ns1:doc", {})
+    # add an unqualified name
+    gen.startElementNS((None, "udoc"), None, {})
+    gen.endElementNS((None, "udoc"), None)
+    gen.endElementNS((ns_uri, "doc"), "ns1:doc")
+    gen.endPrefixMapping("ns1")
+    gen.endDocument()
+
+    return result.getvalue() == start + \
+           ('<ns1:doc xmlns:ns1="%s"><udoc></udoc></ns1:doc>' %
+                                         ns_uri)
+
+def test_1463026_1():
+    result = StringIO()
+    gen = XMLGenerator(result)
+
+    gen.startDocument()
+    gen.startElementNS((None, 'a'), 'a', {(None, 'b'):'c'})
+    gen.endElementNS((None, 'a'), 'a')
+    gen.endDocument()
+
+    return result.getvalue() == start+'<a b="c"></a>'
+
+def test_1463026_2():
+    result = StringIO()
+    gen = XMLGenerator(result)
+
+    gen.startDocument()
+    gen.startPrefixMapping(None, 'qux')
+    gen.startElementNS(('qux', 'a'), 'a', {})
+    gen.endElementNS(('qux', 'a'), 'a')
+    gen.endPrefixMapping(None)
+    gen.endDocument()
+
+    return result.getvalue() == start+'<a xmlns="qux"></a>'
+
+def test_1463026_3():
+    result = StringIO()
+    gen = XMLGenerator(result)
+
+    gen.startDocument()
+    gen.startPrefixMapping('my', 'qux')
+    gen.startElementNS(('qux', 'a'), 'a', {(None, 'b'):'c'})
+    gen.endElementNS(('qux', 'a'), 'a')
+    gen.endPrefixMapping('my')
+    gen.endDocument()
+
+    return result.getvalue() == start+'<my:a xmlns:my="qux" b="c"></my:a>'
+    
+# ===== Xmlfilterbase
+
+def test_filter_basic():
+    result = StringIO()
+    gen = XMLGenerator(result)
+    filter = XMLFilterBase()
+    filter.setContentHandler(gen)
+
+    filter.startDocument()
+    filter.startElement("doc", {})
+    filter.characters("content")
+    filter.ignorableWhitespace(" ")
+    filter.endElement("doc")
+    filter.endDocument()
+
+    return result.getvalue() == start + "<doc>content </doc>"
+
+# ===========================================================================
+#
+#   expatreader tests
+#
+# ===========================================================================
+
+# ===== XMLReader support
+
+def test_expat_file():
+    parser = create_parser()
+    result = StringIO()
+    xmlgen = XMLGenerator(result)
+
+    parser.setContentHandler(xmlgen)
+    parser.parse(open(findfile("test"+os.extsep+"xml")))
+
+    return result.getvalue() == xml_test_out
+
+# ===== DTDHandler support
+
+class TestDTDHandler:
+
+    def __init__(self):
+        self._notations = []
+        self._entities  = []
+
+    def notationDecl(self, name, publicId, systemId):
+        self._notations.append((name, publicId, systemId))
+
+    def unparsedEntityDecl(self, name, publicId, systemId, ndata):
+        self._entities.append((name, publicId, systemId, ndata))
+
+def test_expat_dtdhandler():
+    parser = create_parser()
+    handler = TestDTDHandler()
+    parser.setDTDHandler(handler)
+
+    parser.feed('<!DOCTYPE doc [\n')
+    parser.feed('  <!ENTITY img SYSTEM "expat.gif" NDATA GIF>\n')
+    parser.feed('  <!NOTATION GIF PUBLIC "-//CompuServe//NOTATION Graphics Interchange Format 89a//EN">\n')
+    parser.feed(']>\n')
+    parser.feed('<doc></doc>')
+    parser.close()
+
+    return handler._notations == [("GIF", "-//CompuServe//NOTATION Graphics Interchange Format 89a//EN", None)] and \
+           handler._entities == [("img", None, "expat.gif", "GIF")]
+
+# ===== EntityResolver support
+
+class TestEntityResolver:
+
+    def resolveEntity(self, publicId, systemId):
+        inpsrc = InputSource()
+        inpsrc.setByteStream(StringIO("<entity/>"))
+        return inpsrc
+
+def test_expat_entityresolver():
+    parser = create_parser()
+    parser.setEntityResolver(TestEntityResolver())
+    result = StringIO()
+    parser.setContentHandler(XMLGenerator(result))
+
+    parser.feed('<!DOCTYPE doc [\n')
+    parser.feed('  <!ENTITY test SYSTEM "whatever">\n')
+    parser.feed(']>\n')
+    parser.feed('<doc>&test;</doc>')
+    parser.close()
+
+    return result.getvalue() == start + "<doc><entity></entity></doc>"
+
+# ===== Attributes support
+
+class AttrGatherer(ContentHandler):
+
+    def startElement(self, name, attrs):
+        self._attrs = attrs
+
+    def startElementNS(self, name, qname, attrs):
+        self._attrs = attrs
+
+def test_expat_attrs_empty():
+    parser = create_parser()
+    gather = AttrGatherer()
+    parser.setContentHandler(gather)
+
+    parser.feed("<doc/>")
+    parser.close()
+
+    return verify_empty_attrs(gather._attrs)
+
+def test_expat_attrs_wattr():
+    parser = create_parser()
+    gather = AttrGatherer()
+    parser.setContentHandler(gather)
+
+    parser.feed("<doc attr='val'/>")
+    parser.close()
+
+    return verify_attrs_wattr(gather._attrs)
+
+def test_expat_nsattrs_empty():
+    parser = create_parser(1)
+    gather = AttrGatherer()
+    parser.setContentHandler(gather)
+
+    parser.feed("<doc/>")
+    parser.close()
+
+    return verify_empty_nsattrs(gather._attrs)
+
+def test_expat_nsattrs_wattr():
+    parser = create_parser(1)
+    gather = AttrGatherer()
+    parser.setContentHandler(gather)
+
+    parser.feed("<doc xmlns:ns='%s' ns:attr='val'/>" % ns_uri)
+    parser.close()
+
+    attrs = gather._attrs
+
+    return attrs.getLength() == 1 and \
+           attrs.getNames() == [(ns_uri, "attr")] and \
+           (attrs.getQNames() == [] or attrs.getQNames() == ["ns:attr"]) and \
+           len(attrs) == 1 and \
+           attrs.has_key((ns_uri, "attr")) and \
+           attrs.keys() == [(ns_uri, "attr")] and \
+           attrs.get((ns_uri, "attr")) == "val" and \
+           attrs.get((ns_uri, "attr"), 25) == "val" and \
+           attrs.items() == [((ns_uri, "attr"), "val")] and \
+           attrs.values() == ["val"] and \
+           attrs.getValue((ns_uri, "attr")) == "val" and \
+           attrs[(ns_uri, "attr")] == "val"
+
+# ===== InputSource support
+
+xml_test_out = open(findfile("test"+os.extsep+"xml"+os.extsep+"out")).read()
+
+def test_expat_inpsource_filename():
+    parser = create_parser()
+    result = StringIO()
+    xmlgen = XMLGenerator(result)
+
+    parser.setContentHandler(xmlgen)
+    parser.parse(findfile("test"+os.extsep+"xml"))
+
+    return result.getvalue() == xml_test_out
+
+def test_expat_inpsource_sysid():
+    parser = create_parser()
+    result = StringIO()
+    xmlgen = XMLGenerator(result)
+
+    parser.setContentHandler(xmlgen)
+    parser.parse(InputSource(findfile("test"+os.extsep+"xml")))
+
+    return result.getvalue() == xml_test_out
+
+def test_expat_inpsource_stream():
+    parser = create_parser()
+    result = StringIO()
+    xmlgen = XMLGenerator(result)
+
+    parser.setContentHandler(xmlgen)
+    inpsrc = InputSource()
+    inpsrc.setByteStream(open(findfile("test"+os.extsep+"xml")))
+    parser.parse(inpsrc)
+
+    return result.getvalue() == xml_test_out
+
+# ===== IncrementalParser support
+
+def test_expat_incremental():
+    result = StringIO()
+    xmlgen = XMLGenerator(result)
+    parser = create_parser()
+    parser.setContentHandler(xmlgen)
+
+    parser.feed("<doc>")
+    parser.feed("</doc>")
+    parser.close()
+
+    return result.getvalue() == start + "<doc></doc>"
+
+def test_expat_incremental_reset():
+    result = StringIO()
+    xmlgen = XMLGenerator(result)
+    parser = create_parser()
+    parser.setContentHandler(xmlgen)
+
+    parser.feed("<doc>")
+    parser.feed("text")
+
+    result = StringIO()
+    xmlgen = XMLGenerator(result)
+    parser.setContentHandler(xmlgen)
+    parser.reset()
+
+    parser.feed("<doc>")
+    parser.feed("text")
+    parser.feed("</doc>")
+    parser.close()
+
+    return result.getvalue() == start + "<doc>text</doc>"
+
+# ===== Locator support
+
+def test_expat_locator_noinfo():
+    result = StringIO()
+    xmlgen = XMLGenerator(result)
+    parser = create_parser()
+    parser.setContentHandler(xmlgen)
+
+    parser.feed("<doc>")
+    parser.feed("</doc>")
+    parser.close()
+
+    return parser.getSystemId() is None and \
+           parser.getPublicId() is None and \
+           parser.getLineNumber() == 1
+
+def test_expat_locator_withinfo():
+    result = StringIO()
+    xmlgen = XMLGenerator(result)
+    parser = create_parser()
+    parser.setContentHandler(xmlgen)
+    parser.parse(findfile("test.xml"))
+
+    return parser.getSystemId() == findfile("test.xml") and \
+           parser.getPublicId() is None
+
+
+# ===========================================================================
+#
+#   error reporting
+#
+# ===========================================================================
+
+def test_expat_inpsource_location():
+    parser = create_parser()
+    parser.setContentHandler(ContentHandler()) # do nothing
+    source = InputSource()
+    source.setByteStream(StringIO("<foo bar foobar>"))   #ill-formed
+    name = "a file name"
+    source.setSystemId(name)
+    try:
+        parser.parse(source)
+    except SAXException, e:
+        return e.getSystemId() == name
+
+def test_expat_incomplete():
+    parser = create_parser()
+    parser.setContentHandler(ContentHandler()) # do nothing
+    try:
+        parser.parse(StringIO("<foo>"))
+    except SAXParseException:
+        return 1 # ok, error found
+    else:
+        return 0
+
+def test_sax_parse_exception_str():
+    # pass various values from a locator to the SAXParseException to
+    # make sure that the __str__() doesn't fall apart when None is
+    # passed instead of an integer line and column number
+    #
+    # use "normal" values for the locator:
+    str(SAXParseException("message", None,
+                          DummyLocator(1, 1)))
+    # use None for the line number:
+    str(SAXParseException("message", None,
+                          DummyLocator(None, 1)))
+    # use None for the column number:
+    str(SAXParseException("message", None,
+                          DummyLocator(1, None)))
+    # use None for both:
+    str(SAXParseException("message", None,
+                          DummyLocator(None, None)))
+    return 1
+
+class DummyLocator:
+    def __init__(self, lineno, colno):
+        self._lineno = lineno
+        self._colno = colno
+
+    def getPublicId(self):
+        return "pubid"
+
+    def getSystemId(self):
+        return "sysid"
+
+    def getLineNumber(self):
+        return self._lineno
+
+    def getColumnNumber(self):
+        return self._colno
+
+# ===========================================================================
+#
+#   xmlreader tests
+#
+# ===========================================================================
+
+# ===== AttributesImpl
+
+def verify_empty_attrs(attrs):
+    try:
+        attrs.getValue("attr")
+        gvk = 0
+    except KeyError:
+        gvk = 1
+
+    try:
+        attrs.getValueByQName("attr")
+        gvqk = 0
+    except KeyError:
+        gvqk = 1
+
+    try:
+        attrs.getNameByQName("attr")
+        gnqk = 0
+    except KeyError:
+        gnqk = 1
+
+    try:
+        attrs.getQNameByName("attr")
+        gqnk = 0
+    except KeyError:
+        gqnk = 1
+
+    try:
+        attrs["attr"]
+        gik = 0
+    except KeyError:
+        gik = 1
+
+    return attrs.getLength() == 0 and \
+           attrs.getNames() == [] and \
+           attrs.getQNames() == [] and \
+           len(attrs) == 0 and \
+           not attrs.has_key("attr") and \
+           attrs.keys() == [] and \
+           attrs.get("attrs") is None and \
+           attrs.get("attrs", 25) == 25 and \
+           attrs.items() == [] and \
+           attrs.values() == [] and \
+           gvk and gvqk and gnqk and gik and gqnk
+
+def verify_attrs_wattr(attrs):
+    return attrs.getLength() == 1 and \
+           attrs.getNames() == ["attr"] and \
+           attrs.getQNames() == ["attr"] and \
+           len(attrs) == 1 and \
+           attrs.has_key("attr") and \
+           attrs.keys() == ["attr"] and \
+           attrs.get("attr") == "val" and \
+           attrs.get("attr", 25) == "val" and \
+           attrs.items() == [("attr", "val")] and \
+           attrs.values() == ["val"] and \
+           attrs.getValue("attr") == "val" and \
+           attrs.getValueByQName("attr") == "val" and \
+           attrs.getNameByQName("attr") == "attr" and \
+           attrs["attr"] == "val" and \
+           attrs.getQNameByName("attr") == "attr"
+
+def test_attrs_empty():
+    return verify_empty_attrs(AttributesImpl({}))
+
+def test_attrs_wattr():
+    return verify_attrs_wattr(AttributesImpl({"attr" : "val"}))
+
+# ===== AttributesImpl
+
+def verify_empty_nsattrs(attrs):
+    try:
+        attrs.getValue((ns_uri, "attr"))
+        gvk = 0
+    except KeyError:
+        gvk = 1
+
+    try:
+        attrs.getValueByQName("ns:attr")
+        gvqk = 0
+    except KeyError:
+        gvqk = 1
+
+    try:
+        attrs.getNameByQName("ns:attr")
+        gnqk = 0
+    except KeyError:
+        gnqk = 1
+
+    try:
+        attrs.getQNameByName((ns_uri, "attr"))
+        gqnk = 0
+    except KeyError:
+        gqnk = 1
+
+    try:
+        attrs[(ns_uri, "attr")]
+        gik = 0
+    except KeyError:
+        gik = 1
+
+    return attrs.getLength() == 0 and \
+           attrs.getNames() == [] and \
+           attrs.getQNames() == [] and \
+           len(attrs) == 0 and \
+           not attrs.has_key((ns_uri, "attr")) and \
+           attrs.keys() == [] and \
+           attrs.get((ns_uri, "attr")) is None and \
+           attrs.get((ns_uri, "attr"), 25) == 25 and \
+           attrs.items() == [] and \
+           attrs.values() == [] and \
+           gvk and gvqk and gnqk and gik and gqnk
+
+def test_nsattrs_empty():
+    return verify_empty_nsattrs(AttributesNSImpl({}, {}))
+
+def test_nsattrs_wattr():
+    attrs = AttributesNSImpl({(ns_uri, "attr") : "val"},
+                             {(ns_uri, "attr") : "ns:attr"})
+
+    return attrs.getLength() == 1 and \
+           attrs.getNames() == [(ns_uri, "attr")] and \
+           attrs.getQNames() == ["ns:attr"] and \
+           len(attrs) == 1 and \
+           attrs.has_key((ns_uri, "attr")) and \
+           attrs.keys() == [(ns_uri, "attr")] and \
+           attrs.get((ns_uri, "attr")) == "val" and \
+           attrs.get((ns_uri, "attr"), 25) == "val" and \
+           attrs.items() == [((ns_uri, "attr"), "val")] and \
+           attrs.values() == ["val"] and \
+           attrs.getValue((ns_uri, "attr")) == "val" and \
+           attrs.getValueByQName("ns:attr") == "val" and \
+           attrs.getNameByQName("ns:attr") == (ns_uri, "attr") and \
+           attrs[(ns_uri, "attr")] == "val" and \
+           attrs.getQNameByName((ns_uri, "attr")) == "ns:attr"
+
+
+# During the development of Python 2.5, an attempt to move the "xml"
+# package implementation to a new package ("xmlcore") proved painful.
+# The goal of this change was to allow applications to be able to
+# obtain and rely on behavior in the standard library implementation
+# of the XML support without needing to be concerned about the
+# availability of the PyXML implementation.
+#
+# While the existing import hackery in Lib/xml/__init__.py can cause
+# PyXML's _xmlpus package to supplant the "xml" package, that only
+# works because either implementation uses the "xml" package name for
+# imports.
+#
+# The move resulted in a number of problems related to the fact that
+# the import machinery's "package context" is based on the name that's
+# being imported rather than the __name__ of the actual package
+# containment; it wasn't possible for the "xml" package to be replaced
+# by a simple module that indirected imports to the "xmlcore" package.
+#
+# The following two tests exercised bugs that were introduced in that
+# attempt.  Keeping these tests around will help detect problems with
+# other attempts to provide reliable access to the standard library's
+# implementation of the XML support.
+
+def test_sf_1511497():
+    # Bug report: http://www.python.org/sf/1511497
+    import sys
+    old_modules = sys.modules.copy()
+    for modname in sys.modules.keys():
+        if modname.startswith("xml."):
+            del sys.modules[modname]
+    try:
+        import xml.sax.expatreader
+        module = xml.sax.expatreader
+        return module.__name__ == "xml.sax.expatreader"
+    finally:
+        sys.modules.update(old_modules)
+
+def test_sf_1513611():
+    # Bug report: http://www.python.org/sf/1513611
+    sio = StringIO("invalid")
+    parser = make_parser()
+    from xml.sax import SAXParseException
+    try:
+        parser.parse(sio)
+    except SAXParseException:
+        return True
+    else:
+        return False
+
+# ===== Main program
+
+def make_test_output():
+    parser = create_parser()
+    result = StringIO()
+    xmlgen = XMLGenerator(result)
+
+    parser.setContentHandler(xmlgen)
+    parser.parse(findfile("test"+os.extsep+"xml"))
+
+    outf = open(findfile("test"+os.extsep+"xml"+os.extsep+"out"), "w")
+    outf.write(result.getvalue())
+    outf.close()
+
+items = locals().items()
+items.sort()
+for (name, value) in items:
+    if name[ : 5] == "test_":
+        confirm(value(), name)
+# We delete the items variable so that the assignment to items above
+# doesn't pick up the old value of items (which messes with attempts
+# to find reference leaks).
+del items
+
+if verbose:
+    print "%d tests, %d failures" % (tests, len(failures))
+if failures:
+    raise TestFailed("%d of %d tests failed: %s"
+                     % (len(failures), tests, ", ".join(failures)))

Added: vendor/Python/current/Lib/test/test_scope.py
===================================================================
--- vendor/Python/current/Lib/test/test_scope.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_scope.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,561 @@
+from test.test_support import verify, TestFailed, check_syntax, vereq
+
+import warnings
+warnings.filterwarnings("ignore", r"import \*", SyntaxWarning, "<string>")
+
+print "1. simple nesting"
+
+def make_adder(x):
+    def adder(y):
+        return x + y
+    return adder
+
+inc = make_adder(1)
+plus10 = make_adder(10)
+
+vereq(inc(1), 2)
+vereq(plus10(-2), 8)
+
+print "2. extra nesting"
+
+def make_adder2(x):
+    def extra(): # check freevars passing through non-use scopes
+        def adder(y):
+            return x + y
+        return adder
+    return extra()
+
+inc = make_adder2(1)
+plus10 = make_adder2(10)
+
+vereq(inc(1), 2)
+vereq(plus10(-2), 8)
+
+print "3. simple nesting + rebinding"
+
+def make_adder3(x):
+    def adder(y):
+        return x + y
+    x = x + 1 # check tracking of assignment to x in defining scope
+    return adder
+
+inc = make_adder3(0)
+plus10 = make_adder3(9)
+
+vereq(inc(1), 2)
+vereq(plus10(-2), 8)
+
+print "4. nesting with global but no free"
+
+def make_adder4(): # XXX add exta level of indirection
+    def nest():
+        def nest():
+            def adder(y):
+                return global_x + y # check that plain old globals work
+            return adder
+        return nest()
+    return nest()
+
+global_x = 1
+adder = make_adder4()
+vereq(adder(1), 2)
+
+global_x = 10
+vereq(adder(-2), 8)
+
+print "5. nesting through class"
+
+def make_adder5(x):
+    class Adder:
+        def __call__(self, y):
+            return x + y
+    return Adder()
+
+inc = make_adder5(1)
+plus10 = make_adder5(10)
+
+vereq(inc(1), 2)
+vereq(plus10(-2), 8)
+
+print "6. nesting plus free ref to global"
+
+def make_adder6(x):
+    global global_nest_x
+    def adder(y):
+        return global_nest_x + y
+    global_nest_x = x
+    return adder
+
+inc = make_adder6(1)
+plus10 = make_adder6(10)
+
+vereq(inc(1), 11) # there's only one global
+vereq(plus10(-2), 8)
+
+print "7. nearest enclosing scope"
+
+def f(x):
+    def g(y):
+        x = 42 # check that this masks binding in f()
+        def h(z):
+            return x + z
+        return h
+    return g(2)
+
+test_func = f(10)
+vereq(test_func(5), 47)
+
+print "8. mixed freevars and cellvars"
+
+def identity(x):
+    return x
+
+def f(x, y, z):
+    def g(a, b, c):
+        a = a + x # 3
+        def h():
+            # z * (4 + 9)
+            # 3 * 13
+            return identity(z * (b + y))
+        y = c + z # 9
+        return h
+    return g
+
+g = f(1, 2, 3)
+h = g(2, 4, 6)
+vereq(h(), 39)
+
+print "9. free variable in method"
+
+def test():
+    method_and_var = "var"
+    class Test:
+        def method_and_var(self):
+            return "method"
+        def test(self):
+            return method_and_var
+        def actual_global(self):
+            return str("global")
+        def str(self):
+            return str(self)
+    return Test()
+
+t = test()
+vereq(t.test(), "var")
+vereq(t.method_and_var(), "method")
+vereq(t.actual_global(), "global")
+
+method_and_var = "var"
+class Test:
+    # this class is not nested, so the rules are different
+    def method_and_var(self):
+        return "method"
+    def test(self):
+        return method_and_var
+    def actual_global(self):
+        return str("global")
+    def str(self):
+        return str(self)
+
+t = Test()
+vereq(t.test(), "var")
+vereq(t.method_and_var(), "method")
+vereq(t.actual_global(), "global")
+
+print "10. recursion"
+
+def f(x):
+    def fact(n):
+        if n == 0:
+            return 1
+        else:
+            return n * fact(n - 1)
+    if x >= 0:
+        return fact(x)
+    else:
+        raise ValueError, "x must be >= 0"
+
+vereq(f(6), 720)
+
+
+print "11. unoptimized namespaces"
+
+check_syntax("""\
+def unoptimized_clash1(strip):
+    def f(s):
+        from string import *
+        return strip(s) # ambiguity: free or local
+    return f
+""")
+
+check_syntax("""\
+def unoptimized_clash2():
+    from string import *
+    def f(s):
+        return strip(s) # ambiguity: global or local
+    return f
+""")
+
+check_syntax("""\
+def unoptimized_clash2():
+    from string import *
+    def g():
+        def f(s):
+            return strip(s) # ambiguity: global or local
+        return f
+""")
+
+# XXX could allow this for exec with const argument, but what's the point
+check_syntax("""\
+def error(y):
+    exec "a = 1"
+    def f(x):
+        return x + y
+    return f
+""")
+
+check_syntax("""\
+def f(x):
+    def g():
+        return x
+    del x # can't del name
+""")
+
+check_syntax("""\
+def f():
+    def g():
+         from string import *
+         return strip # global or local?
+""")
+
+# and verify a few cases that should work
+
+exec """
+def noproblem1():
+    from string import *
+    f = lambda x:x
+
+def noproblem2():
+    from string import *
+    def f(x):
+        return x + 1
+
+def noproblem3():
+    from string import *
+    def f(x):
+        global y
+        y = x
+"""
+
+print "12. lambdas"
+
+f1 = lambda x: lambda y: x + y
+inc = f1(1)
+plus10 = f1(10)
+vereq(inc(1), 2)
+vereq(plus10(5), 15)
+
+f2 = lambda x: (lambda : lambda y: x + y)()
+inc = f2(1)
+plus10 = f2(10)
+vereq(inc(1), 2)
+vereq(plus10(5), 15)
+
+f3 = lambda x: lambda y: global_x + y
+global_x = 1
+inc = f3(None)
+vereq(inc(2), 3)
+
+f8 = lambda x, y, z: lambda a, b, c: lambda : z * (b + y)
+g = f8(1, 2, 3)
+h = g(2, 4, 6)
+vereq(h(), 18)
+
+print "13. UnboundLocal"
+
+def errorInOuter():
+    print y
+    def inner():
+        return y
+    y = 1
+
+def errorInInner():
+    def inner():
+        return y
+    inner()
+    y = 1
+
+try:
+    errorInOuter()
+except UnboundLocalError:
+    pass
+else:
+    raise TestFailed
+
+try:
+    errorInInner()
+except NameError:
+    pass
+else:
+    raise TestFailed
+
+# test for bug #1501934: incorrect LOAD/STORE_GLOBAL generation
+global_x = 1
+def f():
+    global_x += 1
+try:
+    f()
+except UnboundLocalError:
+    pass
+else:
+    raise TestFailed, 'scope of global_x not correctly determined'
+
+print "14. complex definitions"
+
+def makeReturner(*lst):
+    def returner():
+        return lst
+    return returner
+
+vereq(makeReturner(1,2,3)(), (1,2,3))
+
+def makeReturner2(**kwargs):
+    def returner():
+        return kwargs
+    return returner
+
+vereq(makeReturner2(a=11)()['a'], 11)
+
+def makeAddPair((a, b)):
+    def addPair((c, d)):
+        return (a + c, b + d)
+    return addPair
+
+vereq(makeAddPair((1, 2))((100, 200)), (101,202))
+
+print "15. scope of global statements"
+# Examples posted by Samuele Pedroni to python-dev on 3/1/2001
+
+# I
+x = 7
+def f():
+    x = 1
+    def g():
+        global x
+        def i():
+            def h():
+                return x
+            return h()
+        return i()
+    return g()
+vereq(f(), 7)
+vereq(x, 7)
+
+# II
+x = 7
+def f():
+    x = 1
+    def g():
+        x = 2
+        def i():
+            def h():
+                return x
+            return h()
+        return i()
+    return g()
+vereq(f(), 2)
+vereq(x, 7)
+
+# III
+x = 7
+def f():
+    x = 1
+    def g():
+        global x
+        x = 2
+        def i():
+            def h():
+                return x
+            return h()
+        return i()
+    return g()
+vereq(f(), 2)
+vereq(x, 2)
+
+# IV
+x = 7
+def f():
+    x = 3
+    def g():
+        global x
+        x = 2
+        def i():
+            def h():
+                return x
+            return h()
+        return i()
+    return g()
+vereq(f(), 2)
+vereq(x, 2)
+
+# XXX what about global statements in class blocks?
+# do they affect methods?
+
+x = 12
+class Global:
+    global x
+    x = 13
+    def set(self, val):
+        x = val
+    def get(self):
+        return x
+
+g = Global()
+vereq(g.get(), 13)
+g.set(15)
+vereq(g.get(), 13)
+
+print "16. check leaks"
+
+class Foo:
+    count = 0
+
+    def __init__(self):
+        Foo.count += 1
+
+    def __del__(self):
+        Foo.count -= 1
+
+def f1():
+    x = Foo()
+    def f2():
+        return x
+    f2()
+
+for i in range(100):
+    f1()
+
+vereq(Foo.count, 0)
+
+print "17. class and global"
+
+def test(x):
+    class Foo:
+        global x
+        def __call__(self, y):
+            return x + y
+    return Foo()
+
+x = 0
+vereq(test(6)(2), 8)
+x = -1
+vereq(test(3)(2), 5)
+
+looked_up_by_load_name = False
+class X:
+    # Implicit globals inside classes are be looked up by LOAD_NAME, not
+    # LOAD_GLOBAL.
+    locals()['looked_up_by_load_name'] = True
+    passed = looked_up_by_load_name
+
+verify(X.passed)
+
+print "18. verify that locals() works"
+
+def f(x):
+    def g(y):
+        def h(z):
+            return y + z
+        w = x + y
+        y += 3
+        return locals()
+    return g
+
+d = f(2)(4)
+verify(d.has_key('h'))
+del d['h']
+vereq(d, {'x': 2, 'y': 7, 'w': 6})
+
+print "19. var is bound and free in class"
+
+def f(x):
+    class C:
+        def m(self):
+            return x
+        a = x
+    return C
+
+inst = f(3)()
+vereq(inst.a, inst.m())
+
+print "20. interaction with trace function"
+
+import sys
+def tracer(a,b,c):
+    return tracer
+
+def adaptgetter(name, klass, getter):
+    kind, des = getter
+    if kind == 1:       # AV happens when stepping from this line to next
+        if des == "":
+            des = "_%s__%s" % (klass.__name__, name)
+        return lambda obj: getattr(obj, des)
+
+class TestClass:
+    pass
+
+sys.settrace(tracer)
+adaptgetter("foo", TestClass, (1, ""))
+sys.settrace(None)
+
+try: sys.settrace()
+except TypeError: pass
+else: raise TestFailed, 'sys.settrace() did not raise TypeError'
+
+print "20. eval and exec with free variables"
+
+def f(x):
+    return lambda: x + 1
+
+g = f(3)
+try:
+    eval(g.func_code)
+except TypeError:
+    pass
+else:
+    print "eval() should have failed, because code contained free vars"
+
+try:
+    exec g.func_code
+except TypeError:
+    pass
+else:
+    print "exec should have failed, because code contained free vars"
+
+print "21. list comprehension with local variables"
+
+try:
+    print bad
+except NameError:
+    pass
+else:
+    print "bad should not be defined"
+
+def x():
+    [bad for s in 'a b' for bad in s.split()]
+
+x()
+try:
+    print bad
+except NameError:
+    pass
+
+print "22. eval with free variables"
+
+def f(x):
+    def g():
+        x
+        eval("x + 1")
+    return g
+
+f(4)()

Added: vendor/Python/current/Lib/test/test_scriptpackages.py
===================================================================
--- vendor/Python/current/Lib/test/test_scriptpackages.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_scriptpackages.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,52 @@
+# Copyright (C) 2003 Python Software Foundation
+
+import unittest
+import os
+import sys
+import tempfile
+from test import test_support
+import aetools
+
+class TestScriptpackages(unittest.TestCase):
+
+    def _test_scriptpackage(self, package, testobject=1):
+        # Check that we can import the package
+        mod = __import__(package)
+        # Test that we can get the main event class
+        klass = getattr(mod, package)
+        # Test that we can instantiate that class
+        talker = klass()
+        if testobject:
+            # Test that we can get an application object
+            obj = mod.application(0)
+
+    def test__builtinSuites(self):
+        self._test_scriptpackage('_builtinSuites', testobject=0)
+
+    def test_StdSuites(self):
+        self._test_scriptpackage('StdSuites')
+
+    def test_SystemEvents(self):
+        self._test_scriptpackage('SystemEvents')
+
+    def test_Finder(self):
+        self._test_scriptpackage('Finder')
+
+    def test_Terminal(self):
+        self._test_scriptpackage('Terminal')
+
+    def test_Netscape(self):
+        self._test_scriptpackage('Netscape')
+
+    def test_Explorer(self):
+        self._test_scriptpackage('Explorer')
+
+    def test_CodeWarrior(self):
+        self._test_scriptpackage('CodeWarrior')
+
+def test_main():
+    test_support.run_unittest(TestScriptpackages)
+
+
+if __name__ == '__main__':
+    test_main()

Added: vendor/Python/current/Lib/test/test_select.py
===================================================================
--- vendor/Python/current/Lib/test/test_select.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_select.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,70 @@
+# Testing select module
+from test.test_support import verbose, reap_children
+import select
+import os
+
+# test some known error conditions
+try:
+    rfd, wfd, xfd = select.select(1, 2, 3)
+except TypeError:
+    pass
+else:
+    print 'expected TypeError exception not raised'
+
+class Nope:
+    pass
+
+class Almost:
+    def fileno(self):
+        return 'fileno'
+
+try:
+    rfd, wfd, xfd = select.select([Nope()], [], [])
+except TypeError:
+    pass
+else:
+    print 'expected TypeError exception not raised'
+
+try:
+    rfd, wfd, xfd = select.select([Almost()], [], [])
+except TypeError:
+    pass
+else:
+    print 'expected TypeError exception not raised'
+
+try:
+    rfd, wfd, xfd = select.select([], [], [], 'not a number')
+except TypeError:
+    pass
+else:
+    print 'expected TypeError exception not raised'
+
+
+def test():
+    import sys
+    if sys.platform[:3] in ('win', 'mac', 'os2', 'riscos'):
+        if verbose:
+            print "Can't test select easily on", sys.platform
+        return
+    cmd = 'for i in 0 1 2 3 4 5 6 7 8 9; do echo testing...; sleep 1; done'
+    p = os.popen(cmd, 'r')
+    for tout in (0, 1, 2, 4, 8, 16) + (None,)*10:
+        if verbose:
+            print 'timeout =', tout
+        rfd, wfd, xfd = select.select([p], [], [], tout)
+        if (rfd, wfd, xfd) == ([], [], []):
+            continue
+        if (rfd, wfd, xfd) == ([p], [], []):
+            line = p.readline()
+            if verbose:
+                print repr(line)
+            if not line:
+                if verbose:
+                    print 'EOF'
+                break
+            continue
+        print 'Unexpected return values from select():', rfd, wfd, xfd
+    p.close()
+    reap_children()
+
+test()

Added: vendor/Python/current/Lib/test/test_set.py
===================================================================
--- vendor/Python/current/Lib/test/test_set.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_set.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1535 @@
+import unittest
+from test import test_support
+from weakref import proxy
+import operator
+import copy
+import pickle
+import os
+from random import randrange, shuffle
+import sys
+
+class PassThru(Exception):
+    pass
+
+def check_pass_thru():
+    raise PassThru
+    yield 1
+
+class BadCmp:
+    def __hash__(self):
+        return 1
+    def __cmp__(self, other):
+        raise RuntimeError
+
+class ReprWrapper:
+    'Used to test self-referential repr() calls'
+    def __repr__(self):
+        return repr(self.value)
+
+class HashCountingInt(int):
+    'int-like object that counts the number of times __hash__ is called'
+    def __init__(self, *args):
+        self.hash_count = 0
+    def __hash__(self):
+        self.hash_count += 1
+        return int.__hash__(self)
+
+class TestJointOps(unittest.TestCase):
+    # Tests common to both set and frozenset
+
+    def setUp(self):
+        self.word = word = 'simsalabim'
+        self.otherword = 'madagascar'
+        self.letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
+        self.s = self.thetype(word)
+        self.d = dict.fromkeys(word)
+
+    def test_new_or_init(self):
+        self.assertRaises(TypeError, self.thetype, [], 2)
+
+    def test_uniquification(self):
+        actual = sorted(self.s)
+        expected = sorted(self.d)
+        self.assertEqual(actual, expected)
+        self.assertRaises(PassThru, self.thetype, check_pass_thru())
+        self.assertRaises(TypeError, self.thetype, [[]])
+
+    def test_len(self):
+        self.assertEqual(len(self.s), len(self.d))
+
+    def test_contains(self):
+        for c in self.letters:
+            self.assertEqual(c in self.s, c in self.d)
+        self.assertRaises(TypeError, self.s.__contains__, [[]])
+        s = self.thetype([frozenset(self.letters)])
+        self.assert_(self.thetype(self.letters) in s)
+
+    def test_union(self):
+        u = self.s.union(self.otherword)
+        for c in self.letters:
+            self.assertEqual(c in u, c in self.d or c in self.otherword)
+        self.assertEqual(self.s, self.thetype(self.word))
+        self.assertEqual(type(u), self.thetype)
+        self.assertRaises(PassThru, self.s.union, check_pass_thru())
+        self.assertRaises(TypeError, self.s.union, [[]])
+        for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
+            self.assertEqual(self.thetype('abcba').union(C('cdc')), set('abcd'))
+            self.assertEqual(self.thetype('abcba').union(C('efgfe')), set('abcefg'))
+            self.assertEqual(self.thetype('abcba').union(C('ccb')), set('abc'))
+            self.assertEqual(self.thetype('abcba').union(C('ef')), set('abcef'))
+
+    def test_or(self):
+        i = self.s.union(self.otherword)
+        self.assertEqual(self.s | set(self.otherword), i)
+        self.assertEqual(self.s | frozenset(self.otherword), i)
+        try:
+            self.s | self.otherword
+        except TypeError:
+            pass
+        else:
+            self.fail("s|t did not screen-out general iterables")
+
+    def test_intersection(self):
+        i = self.s.intersection(self.otherword)
+        for c in self.letters:
+            self.assertEqual(c in i, c in self.d and c in self.otherword)
+        self.assertEqual(self.s, self.thetype(self.word))
+        self.assertEqual(type(i), self.thetype)
+        self.assertRaises(PassThru, self.s.intersection, check_pass_thru())
+        for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
+            self.assertEqual(self.thetype('abcba').intersection(C('cdc')), set('cc'))
+            self.assertEqual(self.thetype('abcba').intersection(C('efgfe')), set(''))
+            self.assertEqual(self.thetype('abcba').intersection(C('ccb')), set('bc'))
+            self.assertEqual(self.thetype('abcba').intersection(C('ef')), set(''))
+
+    def test_and(self):
+        i = self.s.intersection(self.otherword)
+        self.assertEqual(self.s & set(self.otherword), i)
+        self.assertEqual(self.s & frozenset(self.otherword), i)
+        try:
+            self.s & self.otherword
+        except TypeError:
+            pass
+        else:
+            self.fail("s&t did not screen-out general iterables")
+
+    def test_difference(self):
+        i = self.s.difference(self.otherword)
+        for c in self.letters:
+            self.assertEqual(c in i, c in self.d and c not in self.otherword)
+        self.assertEqual(self.s, self.thetype(self.word))
+        self.assertEqual(type(i), self.thetype)
+        self.assertRaises(PassThru, self.s.difference, check_pass_thru())
+        self.assertRaises(TypeError, self.s.difference, [[]])
+        for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
+            self.assertEqual(self.thetype('abcba').difference(C('cdc')), set('ab'))
+            self.assertEqual(self.thetype('abcba').difference(C('efgfe')), set('abc'))
+            self.assertEqual(self.thetype('abcba').difference(C('ccb')), set('a'))
+            self.assertEqual(self.thetype('abcba').difference(C('ef')), set('abc'))
+
+    def test_sub(self):
+        i = self.s.difference(self.otherword)
+        self.assertEqual(self.s - set(self.otherword), i)
+        self.assertEqual(self.s - frozenset(self.otherword), i)
+        try:
+            self.s - self.otherword
+        except TypeError:
+            pass
+        else:
+            self.fail("s-t did not screen-out general iterables")
+
+    def test_symmetric_difference(self):
+        i = self.s.symmetric_difference(self.otherword)
+        for c in self.letters:
+            self.assertEqual(c in i, (c in self.d) ^ (c in self.otherword))
+        self.assertEqual(self.s, self.thetype(self.word))
+        self.assertEqual(type(i), self.thetype)
+        self.assertRaises(PassThru, self.s.symmetric_difference, check_pass_thru())
+        self.assertRaises(TypeError, self.s.symmetric_difference, [[]])
+        for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
+            self.assertEqual(self.thetype('abcba').symmetric_difference(C('cdc')), set('abd'))
+            self.assertEqual(self.thetype('abcba').symmetric_difference(C('efgfe')), set('abcefg'))
+            self.assertEqual(self.thetype('abcba').symmetric_difference(C('ccb')), set('a'))
+            self.assertEqual(self.thetype('abcba').symmetric_difference(C('ef')), set('abcef'))
+
+    def test_xor(self):
+        i = self.s.symmetric_difference(self.otherword)
+        self.assertEqual(self.s ^ set(self.otherword), i)
+        self.assertEqual(self.s ^ frozenset(self.otherword), i)
+        try:
+            self.s ^ self.otherword
+        except TypeError:
+            pass
+        else:
+            self.fail("s^t did not screen-out general iterables")
+
+    def test_equality(self):
+        self.assertEqual(self.s, set(self.word))
+        self.assertEqual(self.s, frozenset(self.word))
+        self.assertEqual(self.s == self.word, False)
+        self.assertNotEqual(self.s, set(self.otherword))
+        self.assertNotEqual(self.s, frozenset(self.otherword))
+        self.assertEqual(self.s != self.word, True)
+
+    def test_setOfFrozensets(self):
+        t = map(frozenset, ['abcdef', 'bcd', 'bdcb', 'fed', 'fedccba'])
+        s = self.thetype(t)
+        self.assertEqual(len(s), 3)
+
+    def test_compare(self):
+        self.assertRaises(TypeError, self.s.__cmp__, self.s)
+
+    def test_sub_and_super(self):
+        p, q, r = map(self.thetype, ['ab', 'abcde', 'def'])
+        self.assert_(p < q)
+        self.assert_(p <= q)
+        self.assert_(q <= q)
+        self.assert_(q > p)
+        self.assert_(q >= p)
+        self.failIf(q < r)
+        self.failIf(q <= r)
+        self.failIf(q > r)
+        self.failIf(q >= r)
+        self.assert_(set('a').issubset('abc'))
+        self.assert_(set('abc').issuperset('a'))
+        self.failIf(set('a').issubset('cbs'))
+        self.failIf(set('cbs').issuperset('a'))
+
+    def test_pickling(self):
+        for i in (0, 1, 2):
+            p = pickle.dumps(self.s, i)
+            dup = pickle.loads(p)
+            self.assertEqual(self.s, dup, "%s != %s" % (self.s, dup))
+            if type(self.s) not in (set, frozenset):
+                self.s.x = 10
+                p = pickle.dumps(self.s)
+                dup = pickle.loads(p)
+                self.assertEqual(self.s.x, dup.x)
+
+    def test_deepcopy(self):
+        class Tracer:
+            def __init__(self, value):
+                self.value = value
+            def __hash__(self):
+                return self.value
+            def __deepcopy__(self, memo=None):
+                return Tracer(self.value + 1)
+        t = Tracer(10)
+        s = self.thetype([t])
+        dup = copy.deepcopy(s)
+        self.assertNotEqual(id(s), id(dup))
+        for elem in dup:
+            newt = elem
+        self.assertNotEqual(id(t), id(newt))
+        self.assertEqual(t.value + 1, newt.value)
+
+    def test_gc(self):
+        # Create a nest of cycles to exercise overall ref count check
+        class A:
+            pass
+        s = set(A() for i in xrange(1000))
+        for elem in s:
+            elem.cycle = s
+            elem.sub = elem
+            elem.set = set([elem])
+
+    def test_subclass_with_custom_hash(self):
+        # Bug #1257731
+        class H(self.thetype):
+            def __hash__(self):
+                return int(id(self) & 0x7fffffff)
+        s=H()
+        f=set()
+        f.add(s)
+        self.assert_(s in f)
+        f.remove(s)
+        f.add(s)
+        f.discard(s)
+
+    def test_badcmp(self):
+        s = self.thetype([BadCmp()])
+        # Detect comparison errors during insertion and lookup
+        self.assertRaises(RuntimeError, self.thetype, [BadCmp(), BadCmp()])
+        self.assertRaises(RuntimeError, s.__contains__, BadCmp())
+        # Detect errors during mutating operations
+        if hasattr(s, 'add'):
+            self.assertRaises(RuntimeError, s.add, BadCmp())
+            self.assertRaises(RuntimeError, s.discard, BadCmp())
+            self.assertRaises(RuntimeError, s.remove, BadCmp())
+
+    def test_cyclical_repr(self):
+        w = ReprWrapper()
+        s = self.thetype([w])
+        w.value = s
+        name = repr(s).partition('(')[0]    # strip class name from repr string
+        self.assertEqual(repr(s), '%s([%s(...)])' % (name, name))
+
+    def test_cyclical_print(self):
+        w = ReprWrapper()
+        s = self.thetype([w])
+        w.value = s
+        try:
+            fo = open(test_support.TESTFN, "wb")
+            print >> fo, s,
+            fo.close()
+            fo = open(test_support.TESTFN, "rb")
+            self.assertEqual(fo.read(), repr(s))
+        finally:
+            fo.close()
+            os.remove(test_support.TESTFN)
+
+    def test_do_not_rehash_dict_keys(self):
+        n = 10
+        d = dict.fromkeys(map(HashCountingInt, xrange(n)))
+        self.assertEqual(sum(elem.hash_count for elem in d), n)
+        s = self.thetype(d)
+        self.assertEqual(sum(elem.hash_count for elem in d), n)
+        s.difference(d)
+        self.assertEqual(sum(elem.hash_count for elem in d), n)
+        if hasattr(s, 'symmetric_difference_update'):
+            s.symmetric_difference_update(d)
+        self.assertEqual(sum(elem.hash_count for elem in d), n)     
+        d2 = dict.fromkeys(set(d))
+        self.assertEqual(sum(elem.hash_count for elem in d), n)
+        d3 = dict.fromkeys(frozenset(d))
+        self.assertEqual(sum(elem.hash_count for elem in d), n)
+        d3 = dict.fromkeys(frozenset(d), 123)
+        self.assertEqual(sum(elem.hash_count for elem in d), n)
+        self.assertEqual(d3, dict.fromkeys(d, 123))
+
+class TestSet(TestJointOps):
+    thetype = set
+
+    def test_init(self):
+        s = self.thetype()
+        s.__init__(self.word)
+        self.assertEqual(s, set(self.word))
+        s.__init__(self.otherword)
+        self.assertEqual(s, set(self.otherword))
+        self.assertRaises(TypeError, s.__init__, s, 2);
+        self.assertRaises(TypeError, s.__init__, 1);
+
+    def test_constructor_identity(self):
+        s = self.thetype(range(3))
+        t = self.thetype(s)
+        self.assertNotEqual(id(s), id(t))
+
+    def test_hash(self):
+        self.assertRaises(TypeError, hash, self.s)
+
+    def test_clear(self):
+        self.s.clear()
+        self.assertEqual(self.s, set())
+        self.assertEqual(len(self.s), 0)
+
+    def test_copy(self):
+        dup = self.s.copy()
+        self.assertEqual(self.s, dup)
+        self.assertNotEqual(id(self.s), id(dup))
+
+    def test_add(self):
+        self.s.add('Q')
+        self.assert_('Q' in self.s)
+        dup = self.s.copy()
+        self.s.add('Q')
+        self.assertEqual(self.s, dup)
+        self.assertRaises(TypeError, self.s.add, [])
+
+    def test_remove(self):
+        self.s.remove('a')
+        self.assert_('a' not in self.s)
+        self.assertRaises(KeyError, self.s.remove, 'Q')
+        self.assertRaises(TypeError, self.s.remove, [])
+        s = self.thetype([frozenset(self.word)])
+        self.assert_(self.thetype(self.word) in s)
+        s.remove(self.thetype(self.word))
+        self.assert_(self.thetype(self.word) not in s)
+        self.assertRaises(KeyError, self.s.remove, self.thetype(self.word))
+
+    def test_remove_keyerror_unpacking(self):
+        # bug:  www.python.org/sf/1576657
+        for v1 in ['Q', (1,)]:
+            try:
+                self.s.remove(v1)
+            except KeyError, e:
+                v2 = e.args[0]
+                self.assertEqual(v1, v2)
+            else:
+                self.fail()
+
+    def test_discard(self):
+        self.s.discard('a')
+        self.assert_('a' not in self.s)
+        self.s.discard('Q')
+        self.assertRaises(TypeError, self.s.discard, [])
+        s = self.thetype([frozenset(self.word)])
+        self.assert_(self.thetype(self.word) in s)
+        s.discard(self.thetype(self.word))
+        self.assert_(self.thetype(self.word) not in s)
+        s.discard(self.thetype(self.word))
+
+    def test_pop(self):
+        for i in xrange(len(self.s)):
+            elem = self.s.pop()
+            self.assert_(elem not in self.s)
+        self.assertRaises(KeyError, self.s.pop)
+
+    def test_update(self):
+        retval = self.s.update(self.otherword)
+        self.assertEqual(retval, None)
+        for c in (self.word + self.otherword):
+            self.assert_(c in self.s)
+        self.assertRaises(PassThru, self.s.update, check_pass_thru())
+        self.assertRaises(TypeError, self.s.update, [[]])
+        for p, q in (('cdc', 'abcd'), ('efgfe', 'abcefg'), ('ccb', 'abc'), ('ef', 'abcef')):
+            for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
+                s = self.thetype('abcba')
+                self.assertEqual(s.update(C(p)), None)
+                self.assertEqual(s, set(q))
+
+    def test_ior(self):
+        self.s |= set(self.otherword)
+        for c in (self.word + self.otherword):
+            self.assert_(c in self.s)
+
+    def test_intersection_update(self):
+        retval = self.s.intersection_update(self.otherword)
+        self.assertEqual(retval, None)
+        for c in (self.word + self.otherword):
+            if c in self.otherword and c in self.word:
+                self.assert_(c in self.s)
+            else:
+                self.assert_(c not in self.s)
+        self.assertRaises(PassThru, self.s.intersection_update, check_pass_thru())
+        self.assertRaises(TypeError, self.s.intersection_update, [[]])
+        for p, q in (('cdc', 'c'), ('efgfe', ''), ('ccb', 'bc'), ('ef', '')):
+            for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
+                s = self.thetype('abcba')
+                self.assertEqual(s.intersection_update(C(p)), None)
+                self.assertEqual(s, set(q))
+
+    def test_iand(self):
+        self.s &= set(self.otherword)
+        for c in (self.word + self.otherword):
+            if c in self.otherword and c in self.word:
+                self.assert_(c in self.s)
+            else:
+                self.assert_(c not in self.s)
+
+    def test_difference_update(self):
+        retval = self.s.difference_update(self.otherword)
+        self.assertEqual(retval, None)
+        for c in (self.word + self.otherword):
+            if c in self.word and c not in self.otherword:
+                self.assert_(c in self.s)
+            else:
+                self.assert_(c not in self.s)
+        self.assertRaises(PassThru, self.s.difference_update, check_pass_thru())
+        self.assertRaises(TypeError, self.s.difference_update, [[]])
+        self.assertRaises(TypeError, self.s.symmetric_difference_update, [[]])
+        for p, q in (('cdc', 'ab'), ('efgfe', 'abc'), ('ccb', 'a'), ('ef', 'abc')):
+            for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
+                s = self.thetype('abcba')
+                self.assertEqual(s.difference_update(C(p)), None)
+                self.assertEqual(s, set(q))
+
+    def test_isub(self):
+        self.s -= set(self.otherword)
+        for c in (self.word + self.otherword):
+            if c in self.word and c not in self.otherword:
+                self.assert_(c in self.s)
+            else:
+                self.assert_(c not in self.s)
+
+    def test_symmetric_difference_update(self):
+        retval = self.s.symmetric_difference_update(self.otherword)
+        self.assertEqual(retval, None)
+        for c in (self.word + self.otherword):
+            if (c in self.word) ^ (c in self.otherword):
+                self.assert_(c in self.s)
+            else:
+                self.assert_(c not in self.s)
+        self.assertRaises(PassThru, self.s.symmetric_difference_update, check_pass_thru())
+        self.assertRaises(TypeError, self.s.symmetric_difference_update, [[]])
+        for p, q in (('cdc', 'abd'), ('efgfe', 'abcefg'), ('ccb', 'a'), ('ef', 'abcef')):
+            for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
+                s = self.thetype('abcba')
+                self.assertEqual(s.symmetric_difference_update(C(p)), None)
+                self.assertEqual(s, set(q))
+
+    def test_ixor(self):
+        self.s ^= set(self.otherword)
+        for c in (self.word + self.otherword):
+            if (c in self.word) ^ (c in self.otherword):
+                self.assert_(c in self.s)
+            else:
+                self.assert_(c not in self.s)
+
+    def test_inplace_on_self(self):
+        t = self.s.copy()
+        t |= t
+        self.assertEqual(t, self.s)
+        t &= t
+        self.assertEqual(t, self.s)
+        t -= t
+        self.assertEqual(t, self.thetype())
+        t = self.s.copy()
+        t ^= t
+        self.assertEqual(t, self.thetype())
+
+    def test_weakref(self):
+        s = self.thetype('gallahad')
+        p = proxy(s)
+        self.assertEqual(str(p), str(s))
+        s = None
+        self.assertRaises(ReferenceError, str, p)
+
+    # C API test only available in a debug build
+    if hasattr(set, "test_c_api"):
+        def test_c_api(self):
+            self.assertEqual(set('abc').test_c_api(), True)
+
+class SetSubclass(set):
+    pass
+
+class TestSetSubclass(TestSet):
+    thetype = SetSubclass
+
+class SetSubclassWithKeywordArgs(set):
+    def __init__(self, iterable=[], newarg=None):
+        set.__init__(self, iterable)
+
+class TestSetSubclassWithKeywordArgs(TestSet):
+    
+    def test_keywords_in_subclass(self):
+        'SF bug #1486663 -- this used to erroneously raise a TypeError'
+        SetSubclassWithKeywordArgs(newarg=1)
+
+class TestFrozenSet(TestJointOps):
+    thetype = frozenset
+
+    def test_init(self):
+        s = self.thetype(self.word)
+        s.__init__(self.otherword)
+        self.assertEqual(s, set(self.word))
+
+    def test_singleton_empty_frozenset(self):
+        f = frozenset()
+        efs = [frozenset(), frozenset([]), frozenset(()), frozenset(''),
+               frozenset(), frozenset([]), frozenset(()), frozenset(''),
+               frozenset(xrange(0)), frozenset(frozenset()),
+               frozenset(f), f]
+        # All of the empty frozensets should have just one id()
+        self.assertEqual(len(set(map(id, efs))), 1)
+
+    def test_constructor_identity(self):
+        s = self.thetype(range(3))
+        t = self.thetype(s)
+        self.assertEqual(id(s), id(t))
+
+    def test_hash(self):
+        self.assertEqual(hash(self.thetype('abcdeb')),
+                         hash(self.thetype('ebecda')))
+
+        # make sure that all permutations give the same hash value
+        n = 100
+        seq = [randrange(n) for i in xrange(n)]
+        results = set()
+        for i in xrange(200):
+            shuffle(seq)
+            results.add(hash(self.thetype(seq)))
+        self.assertEqual(len(results), 1)
+
+    def test_copy(self):
+        dup = self.s.copy()
+        self.assertEqual(id(self.s), id(dup))
+
+    def test_frozen_as_dictkey(self):
+        seq = range(10) + list('abcdefg') + ['apple']
+        key1 = self.thetype(seq)
+        key2 = self.thetype(reversed(seq))
+        self.assertEqual(key1, key2)
+        self.assertNotEqual(id(key1), id(key2))
+        d = {}
+        d[key1] = 42
+        self.assertEqual(d[key2], 42)
+
+    def test_hash_caching(self):
+        f = self.thetype('abcdcda')
+        self.assertEqual(hash(f), hash(f))
+
+    def test_hash_effectiveness(self):
+        n = 13
+        hashvalues = set()
+        addhashvalue = hashvalues.add
+        elemmasks = [(i+1, 1<<i) for i in range(n)]
+        for i in xrange(2**n):
+            addhashvalue(hash(frozenset([e for e, m in elemmasks if m&i])))
+        self.assertEqual(len(hashvalues), 2**n)
+
+class FrozenSetSubclass(frozenset):
+    pass
+
+class TestFrozenSetSubclass(TestFrozenSet):
+    thetype = FrozenSetSubclass
+
+    def test_constructor_identity(self):
+        s = self.thetype(range(3))
+        t = self.thetype(s)
+        self.assertNotEqual(id(s), id(t))
+
+    def test_copy(self):
+        dup = self.s.copy()
+        self.assertNotEqual(id(self.s), id(dup))
+
+    def test_nested_empty_constructor(self):
+        s = self.thetype()
+        t = self.thetype(s)
+        self.assertEqual(s, t)
+
+    def test_singleton_empty_frozenset(self):
+        Frozenset = self.thetype
+        f = frozenset()
+        F = Frozenset()
+        efs = [Frozenset(), Frozenset([]), Frozenset(()), Frozenset(''),
+               Frozenset(), Frozenset([]), Frozenset(()), Frozenset(''),
+               Frozenset(xrange(0)), Frozenset(Frozenset()),
+               Frozenset(frozenset()), f, F, Frozenset(f), Frozenset(F)]
+        # All empty frozenset subclass instances should have different ids
+        self.assertEqual(len(set(map(id, efs))), len(efs))
+
+# Tests taken from test_sets.py =============================================
+
+empty_set = set()
+
+#==============================================================================
+
+class TestBasicOps(unittest.TestCase):
+
+    def test_repr(self):
+        if self.repr is not None:
+            self.assertEqual(repr(self.set), self.repr)
+
+    def test_print(self):
+        try:
+            fo = open(test_support.TESTFN, "wb")
+            print >> fo, self.set,
+            fo.close()
+            fo = open(test_support.TESTFN, "rb")
+            self.assertEqual(fo.read(), repr(self.set))
+        finally:
+            fo.close()
+            os.remove(test_support.TESTFN)
+
+    def test_length(self):
+        self.assertEqual(len(self.set), self.length)
+
+    def test_self_equality(self):
+        self.assertEqual(self.set, self.set)
+
+    def test_equivalent_equality(self):
+        self.assertEqual(self.set, self.dup)
+
+    def test_copy(self):
+        self.assertEqual(self.set.copy(), self.dup)
+
+    def test_self_union(self):
+        result = self.set | self.set
+        self.assertEqual(result, self.dup)
+
+    def test_empty_union(self):
+        result = self.set | empty_set
+        self.assertEqual(result, self.dup)
+
+    def test_union_empty(self):
+        result = empty_set | self.set
+        self.assertEqual(result, self.dup)
+
+    def test_self_intersection(self):
+        result = self.set & self.set
+        self.assertEqual(result, self.dup)
+
+    def test_empty_intersection(self):
+        result = self.set & empty_set
+        self.assertEqual(result, empty_set)
+
+    def test_intersection_empty(self):
+        result = empty_set & self.set
+        self.assertEqual(result, empty_set)
+
+    def test_self_symmetric_difference(self):
+        result = self.set ^ self.set
+        self.assertEqual(result, empty_set)
+
+    def checkempty_symmetric_difference(self):
+        result = self.set ^ empty_set
+        self.assertEqual(result, self.set)
+
+    def test_self_difference(self):
+        result = self.set - self.set
+        self.assertEqual(result, empty_set)
+
+    def test_empty_difference(self):
+        result = self.set - empty_set
+        self.assertEqual(result, self.dup)
+
+    def test_empty_difference_rev(self):
+        result = empty_set - self.set
+        self.assertEqual(result, empty_set)
+
+    def test_iteration(self):
+        for v in self.set:
+            self.assert_(v in self.values)
+        setiter = iter(self.set)
+        # note: __length_hint__ is an internal undocumented API,
+        # don't rely on it in your own programs
+        self.assertEqual(setiter.__length_hint__(), len(self.set))
+
+    def test_pickling(self):
+        p = pickle.dumps(self.set)
+        copy = pickle.loads(p)
+        self.assertEqual(self.set, copy,
+                         "%s != %s" % (self.set, copy))
+
+#------------------------------------------------------------------------------
+
+class TestBasicOpsEmpty(TestBasicOps):
+    def setUp(self):
+        self.case   = "empty set"
+        self.values = []
+        self.set    = set(self.values)
+        self.dup    = set(self.values)
+        self.length = 0
+        self.repr   = "set([])"
+
+#------------------------------------------------------------------------------
+
+class TestBasicOpsSingleton(TestBasicOps):
+    def setUp(self):
+        self.case   = "unit set (number)"
+        self.values = [3]
+        self.set    = set(self.values)
+        self.dup    = set(self.values)
+        self.length = 1
+        self.repr   = "set([3])"
+
+    def test_in(self):
+        self.failUnless(3 in self.set)
+
+    def test_not_in(self):
+        self.failUnless(2 not in self.set)
+
+#------------------------------------------------------------------------------
+
+class TestBasicOpsTuple(TestBasicOps):
+    def setUp(self):
+        self.case   = "unit set (tuple)"
+        self.values = [(0, "zero")]
+        self.set    = set(self.values)
+        self.dup    = set(self.values)
+        self.length = 1
+        self.repr   = "set([(0, 'zero')])"
+
+    def test_in(self):
+        self.failUnless((0, "zero") in self.set)
+
+    def test_not_in(self):
+        self.failUnless(9 not in self.set)
+
+#------------------------------------------------------------------------------
+
+class TestBasicOpsTriple(TestBasicOps):
+    def setUp(self):
+        self.case   = "triple set"
+        self.values = [0, "zero", operator.add]
+        self.set    = set(self.values)
+        self.dup    = set(self.values)
+        self.length = 3
+        self.repr   = None
+
+#==============================================================================
+
+def baditer():
+    raise TypeError
+    yield True
+
+def gooditer():
+    yield True
+
+class TestExceptionPropagation(unittest.TestCase):
+    """SF 628246:  Set constructor should not trap iterator TypeErrors"""
+
+    def test_instanceWithException(self):
+        self.assertRaises(TypeError, set, baditer())
+
+    def test_instancesWithoutException(self):
+        # All of these iterables should load without exception.
+        set([1,2,3])
+        set((1,2,3))
+        set({'one':1, 'two':2, 'three':3})
+        set(xrange(3))
+        set('abc')
+        set(gooditer())
+
+    def test_changingSizeWhileIterating(self):
+        s = set([1,2,3])
+        try:
+            for i in s:
+                s.update([4])
+        except RuntimeError:
+            pass
+        else:
+            self.fail("no exception when changing size during iteration")
+
+#==============================================================================
+
+class TestSetOfSets(unittest.TestCase):
+    def test_constructor(self):
+        inner = frozenset([1])
+        outer = set([inner])
+        element = outer.pop()
+        self.assertEqual(type(element), frozenset)
+        outer.add(inner)        # Rebuild set of sets with .add method
+        outer.remove(inner)
+        self.assertEqual(outer, set())   # Verify that remove worked
+        outer.discard(inner)    # Absence of KeyError indicates working fine
+
+#==============================================================================
+
+class TestBinaryOps(unittest.TestCase):
+    def setUp(self):
+        self.set = set((2, 4, 6))
+
+    def test_eq(self):              # SF bug 643115
+        self.assertEqual(self.set, set({2:1,4:3,6:5}))
+
+    def test_union_subset(self):
+        result = self.set | set([2])
+        self.assertEqual(result, set((2, 4, 6)))
+
+    def test_union_superset(self):
+        result = self.set | set([2, 4, 6, 8])
+        self.assertEqual(result, set([2, 4, 6, 8]))
+
+    def test_union_overlap(self):
+        result = self.set | set([3, 4, 5])
+        self.assertEqual(result, set([2, 3, 4, 5, 6]))
+
+    def test_union_non_overlap(self):
+        result = self.set | set([8])
+        self.assertEqual(result, set([2, 4, 6, 8]))
+
+    def test_intersection_subset(self):
+        result = self.set & set((2, 4))
+        self.assertEqual(result, set((2, 4)))
+
+    def test_intersection_superset(self):
+        result = self.set & set([2, 4, 6, 8])
+        self.assertEqual(result, set([2, 4, 6]))
+
+    def test_intersection_overlap(self):
+        result = self.set & set([3, 4, 5])
+        self.assertEqual(result, set([4]))
+
+    def test_intersection_non_overlap(self):
+        result = self.set & set([8])
+        self.assertEqual(result, empty_set)
+
+    def test_sym_difference_subset(self):
+        result = self.set ^ set((2, 4))
+        self.assertEqual(result, set([6]))
+
+    def test_sym_difference_superset(self):
+        result = self.set ^ set((2, 4, 6, 8))
+        self.assertEqual(result, set([8]))
+
+    def test_sym_difference_overlap(self):
+        result = self.set ^ set((3, 4, 5))
+        self.assertEqual(result, set([2, 3, 5, 6]))
+
+    def test_sym_difference_non_overlap(self):
+        result = self.set ^ set([8])
+        self.assertEqual(result, set([2, 4, 6, 8]))
+
+    def test_cmp(self):
+        a, b = set('a'), set('b')
+        self.assertRaises(TypeError, cmp, a, b)
+
+        # You can view this as a buglet:  cmp(a, a) does not raise TypeError,
+        # because __eq__ is tried before __cmp__, and a.__eq__(a) returns True,
+        # which Python thinks is good enough to synthesize a cmp() result
+        # without calling __cmp__.
+        self.assertEqual(cmp(a, a), 0)
+
+        self.assertRaises(TypeError, cmp, a, 12)
+        self.assertRaises(TypeError, cmp, "abc", a)
+
+#==============================================================================
+
+class TestUpdateOps(unittest.TestCase):
+    def setUp(self):
+        self.set = set((2, 4, 6))
+
+    def test_union_subset(self):
+        self.set |= set([2])
+        self.assertEqual(self.set, set((2, 4, 6)))
+
+    def test_union_superset(self):
+        self.set |= set([2, 4, 6, 8])
+        self.assertEqual(self.set, set([2, 4, 6, 8]))
+
+    def test_union_overlap(self):
+        self.set |= set([3, 4, 5])
+        self.assertEqual(self.set, set([2, 3, 4, 5, 6]))
+
+    def test_union_non_overlap(self):
+        self.set |= set([8])
+        self.assertEqual(self.set, set([2, 4, 6, 8]))
+
+    def test_union_method_call(self):
+        self.set.update(set([3, 4, 5]))
+        self.assertEqual(self.set, set([2, 3, 4, 5, 6]))
+
+    def test_intersection_subset(self):
+        self.set &= set((2, 4))
+        self.assertEqual(self.set, set((2, 4)))
+
+    def test_intersection_superset(self):
+        self.set &= set([2, 4, 6, 8])
+        self.assertEqual(self.set, set([2, 4, 6]))
+
+    def test_intersection_overlap(self):
+        self.set &= set([3, 4, 5])
+        self.assertEqual(self.set, set([4]))
+
+    def test_intersection_non_overlap(self):
+        self.set &= set([8])
+        self.assertEqual(self.set, empty_set)
+
+    def test_intersection_method_call(self):
+        self.set.intersection_update(set([3, 4, 5]))
+        self.assertEqual(self.set, set([4]))
+
+    def test_sym_difference_subset(self):
+        self.set ^= set((2, 4))
+        self.assertEqual(self.set, set([6]))
+
+    def test_sym_difference_superset(self):
+        self.set ^= set((2, 4, 6, 8))
+        self.assertEqual(self.set, set([8]))
+
+    def test_sym_difference_overlap(self):
+        self.set ^= set((3, 4, 5))
+        self.assertEqual(self.set, set([2, 3, 5, 6]))
+
+    def test_sym_difference_non_overlap(self):
+        self.set ^= set([8])
+        self.assertEqual(self.set, set([2, 4, 6, 8]))
+
+    def test_sym_difference_method_call(self):
+        self.set.symmetric_difference_update(set([3, 4, 5]))
+        self.assertEqual(self.set, set([2, 3, 5, 6]))
+
+    def test_difference_subset(self):
+        self.set -= set((2, 4))
+        self.assertEqual(self.set, set([6]))
+
+    def test_difference_superset(self):
+        self.set -= set((2, 4, 6, 8))
+        self.assertEqual(self.set, set([]))
+
+    def test_difference_overlap(self):
+        self.set -= set((3, 4, 5))
+        self.assertEqual(self.set, set([2, 6]))
+
+    def test_difference_non_overlap(self):
+        self.set -= set([8])
+        self.assertEqual(self.set, set([2, 4, 6]))
+
+    def test_difference_method_call(self):
+        self.set.difference_update(set([3, 4, 5]))
+        self.assertEqual(self.set, set([2, 6]))
+
+#==============================================================================
+
+class TestMutate(unittest.TestCase):
+    def setUp(self):
+        self.values = ["a", "b", "c"]
+        self.set = set(self.values)
+
+    def test_add_present(self):
+        self.set.add("c")
+        self.assertEqual(self.set, set("abc"))
+
+    def test_add_absent(self):
+        self.set.add("d")
+        self.assertEqual(self.set, set("abcd"))
+
+    def test_add_until_full(self):
+        tmp = set()
+        expected_len = 0
+        for v in self.values:
+            tmp.add(v)
+            expected_len += 1
+            self.assertEqual(len(tmp), expected_len)
+        self.assertEqual(tmp, self.set)
+
+    def test_remove_present(self):
+        self.set.remove("b")
+        self.assertEqual(self.set, set("ac"))
+
+    def test_remove_absent(self):
+        try:
+            self.set.remove("d")
+            self.fail("Removing missing element should have raised LookupError")
+        except LookupError:
+            pass
+
+    def test_remove_until_empty(self):
+        expected_len = len(self.set)
+        for v in self.values:
+            self.set.remove(v)
+            expected_len -= 1
+            self.assertEqual(len(self.set), expected_len)
+
+    def test_discard_present(self):
+        self.set.discard("c")
+        self.assertEqual(self.set, set("ab"))
+
+    def test_discard_absent(self):
+        self.set.discard("d")
+        self.assertEqual(self.set, set("abc"))
+
+    def test_clear(self):
+        self.set.clear()
+        self.assertEqual(len(self.set), 0)
+
+    def test_pop(self):
+        popped = {}
+        while self.set:
+            popped[self.set.pop()] = None
+        self.assertEqual(len(popped), len(self.values))
+        for v in self.values:
+            self.failUnless(v in popped)
+
+    def test_update_empty_tuple(self):
+        self.set.update(())
+        self.assertEqual(self.set, set(self.values))
+
+    def test_update_unit_tuple_overlap(self):
+        self.set.update(("a",))
+        self.assertEqual(self.set, set(self.values))
+
+    def test_update_unit_tuple_non_overlap(self):
+        self.set.update(("a", "z"))
+        self.assertEqual(self.set, set(self.values + ["z"]))
+
+#==============================================================================
+
+class TestSubsets(unittest.TestCase):
+
+    case2method = {"<=": "issubset",
+                   ">=": "issuperset",
+                  }
+
+    reverse = {"==": "==",
+               "!=": "!=",
+               "<":  ">",
+               ">":  "<",
+               "<=": ">=",
+               ">=": "<=",
+              }
+
+    def test_issubset(self):
+        x = self.left
+        y = self.right
+        for case in "!=", "==", "<", "<=", ">", ">=":
+            expected = case in self.cases
+            # Test the binary infix spelling.
+            result = eval("x" + case + "y", locals())
+            self.assertEqual(result, expected)
+            # Test the "friendly" method-name spelling, if one exists.
+            if case in TestSubsets.case2method:
+                method = getattr(x, TestSubsets.case2method[case])
+                result = method(y)
+                self.assertEqual(result, expected)
+
+            # Now do the same for the operands reversed.
+            rcase = TestSubsets.reverse[case]
+            result = eval("y" + rcase + "x", locals())
+            self.assertEqual(result, expected)
+            if rcase in TestSubsets.case2method:
+                method = getattr(y, TestSubsets.case2method[rcase])
+                result = method(x)
+                self.assertEqual(result, expected)
+#------------------------------------------------------------------------------
+
+class TestSubsetEqualEmpty(TestSubsets):
+    left  = set()
+    right = set()
+    name  = "both empty"
+    cases = "==", "<=", ">="
+
+#------------------------------------------------------------------------------
+
+class TestSubsetEqualNonEmpty(TestSubsets):
+    left  = set([1, 2])
+    right = set([1, 2])
+    name  = "equal pair"
+    cases = "==", "<=", ">="
+
+#------------------------------------------------------------------------------
+
+class TestSubsetEmptyNonEmpty(TestSubsets):
+    left  = set()
+    right = set([1, 2])
+    name  = "one empty, one non-empty"
+    cases = "!=", "<", "<="
+
+#------------------------------------------------------------------------------
+
+class TestSubsetPartial(TestSubsets):
+    left  = set([1])
+    right = set([1, 2])
+    name  = "one a non-empty proper subset of other"
+    cases = "!=", "<", "<="
+
+#------------------------------------------------------------------------------
+
+class TestSubsetNonOverlap(TestSubsets):
+    left  = set([1])
+    right = set([2])
+    name  = "neither empty, neither contains"
+    cases = "!="
+
+#==============================================================================
+
+class TestOnlySetsInBinaryOps(unittest.TestCase):
+
+    def test_eq_ne(self):
+        # Unlike the others, this is testing that == and != *are* allowed.
+        self.assertEqual(self.other == self.set, False)
+        self.assertEqual(self.set == self.other, False)
+        self.assertEqual(self.other != self.set, True)
+        self.assertEqual(self.set != self.other, True)
+
+    def test_ge_gt_le_lt(self):
+        self.assertRaises(TypeError, lambda: self.set < self.other)
+        self.assertRaises(TypeError, lambda: self.set <= self.other)
+        self.assertRaises(TypeError, lambda: self.set > self.other)
+        self.assertRaises(TypeError, lambda: self.set >= self.other)
+
+        self.assertRaises(TypeError, lambda: self.other < self.set)
+        self.assertRaises(TypeError, lambda: self.other <= self.set)
+        self.assertRaises(TypeError, lambda: self.other > self.set)
+        self.assertRaises(TypeError, lambda: self.other >= self.set)
+
+    def test_update_operator(self):
+        try:
+            self.set |= self.other
+        except TypeError:
+            pass
+        else:
+            self.fail("expected TypeError")
+
+    def test_update(self):
+        if self.otherIsIterable:
+            self.set.update(self.other)
+        else:
+            self.assertRaises(TypeError, self.set.update, self.other)
+
+    def test_union(self):
+        self.assertRaises(TypeError, lambda: self.set | self.other)
+        self.assertRaises(TypeError, lambda: self.other | self.set)
+        if self.otherIsIterable:
+            self.set.union(self.other)
+        else:
+            self.assertRaises(TypeError, self.set.union, self.other)
+
+    def test_intersection_update_operator(self):
+        try:
+            self.set &= self.other
+        except TypeError:
+            pass
+        else:
+            self.fail("expected TypeError")
+
+    def test_intersection_update(self):
+        if self.otherIsIterable:
+            self.set.intersection_update(self.other)
+        else:
+            self.assertRaises(TypeError,
+                              self.set.intersection_update,
+                              self.other)
+
+    def test_intersection(self):
+        self.assertRaises(TypeError, lambda: self.set & self.other)
+        self.assertRaises(TypeError, lambda: self.other & self.set)
+        if self.otherIsIterable:
+            self.set.intersection(self.other)
+        else:
+            self.assertRaises(TypeError, self.set.intersection, self.other)
+
+    def test_sym_difference_update_operator(self):
+        try:
+            self.set ^= self.other
+        except TypeError:
+            pass
+        else:
+            self.fail("expected TypeError")
+
+    def test_sym_difference_update(self):
+        if self.otherIsIterable:
+            self.set.symmetric_difference_update(self.other)
+        else:
+            self.assertRaises(TypeError,
+                              self.set.symmetric_difference_update,
+                              self.other)
+
+    def test_sym_difference(self):
+        self.assertRaises(TypeError, lambda: self.set ^ self.other)
+        self.assertRaises(TypeError, lambda: self.other ^ self.set)
+        if self.otherIsIterable:
+            self.set.symmetric_difference(self.other)
+        else:
+            self.assertRaises(TypeError, self.set.symmetric_difference, self.other)
+
+    def test_difference_update_operator(self):
+        try:
+            self.set -= self.other
+        except TypeError:
+            pass
+        else:
+            self.fail("expected TypeError")
+
+    def test_difference_update(self):
+        if self.otherIsIterable:
+            self.set.difference_update(self.other)
+        else:
+            self.assertRaises(TypeError,
+                              self.set.difference_update,
+                              self.other)
+
+    def test_difference(self):
+        self.assertRaises(TypeError, lambda: self.set - self.other)
+        self.assertRaises(TypeError, lambda: self.other - self.set)
+        if self.otherIsIterable:
+            self.set.difference(self.other)
+        else:
+            self.assertRaises(TypeError, self.set.difference, self.other)
+
+#------------------------------------------------------------------------------
+
+class TestOnlySetsNumeric(TestOnlySetsInBinaryOps):
+    def setUp(self):
+        self.set   = set((1, 2, 3))
+        self.other = 19
+        self.otherIsIterable = False
+
+#------------------------------------------------------------------------------
+
+class TestOnlySetsDict(TestOnlySetsInBinaryOps):
+    def setUp(self):
+        self.set   = set((1, 2, 3))
+        self.other = {1:2, 3:4}
+        self.otherIsIterable = True
+
+#------------------------------------------------------------------------------
+
+class TestOnlySetsOperator(TestOnlySetsInBinaryOps):
+    def setUp(self):
+        self.set   = set((1, 2, 3))
+        self.other = operator.add
+        self.otherIsIterable = False
+
+#------------------------------------------------------------------------------
+
+class TestOnlySetsTuple(TestOnlySetsInBinaryOps):
+    def setUp(self):
+        self.set   = set((1, 2, 3))
+        self.other = (2, 4, 6)
+        self.otherIsIterable = True
+
+#------------------------------------------------------------------------------
+
+class TestOnlySetsString(TestOnlySetsInBinaryOps):
+    def setUp(self):
+        self.set   = set((1, 2, 3))
+        self.other = 'abc'
+        self.otherIsIterable = True
+
+#------------------------------------------------------------------------------
+
+class TestOnlySetsGenerator(TestOnlySetsInBinaryOps):
+    def setUp(self):
+        def gen():
+            for i in xrange(0, 10, 2):
+                yield i
+        self.set   = set((1, 2, 3))
+        self.other = gen()
+        self.otherIsIterable = True
+
+#==============================================================================
+
+class TestCopying(unittest.TestCase):
+
+    def test_copy(self):
+        dup = self.set.copy()
+        dup_list = list(dup); dup_list.sort()
+        set_list = list(self.set); set_list.sort()
+        self.assertEqual(len(dup_list), len(set_list))
+        for i in range(len(dup_list)):
+            self.failUnless(dup_list[i] is set_list[i])
+
+    def test_deep_copy(self):
+        dup = copy.deepcopy(self.set)
+        ##print type(dup), repr(dup)
+        dup_list = list(dup); dup_list.sort()
+        set_list = list(self.set); set_list.sort()
+        self.assertEqual(len(dup_list), len(set_list))
+        for i in range(len(dup_list)):
+            self.assertEqual(dup_list[i], set_list[i])
+
+#------------------------------------------------------------------------------
+
+class TestCopyingEmpty(TestCopying):
+    def setUp(self):
+        self.set = set()
+
+#------------------------------------------------------------------------------
+
+class TestCopyingSingleton(TestCopying):
+    def setUp(self):
+        self.set = set(["hello"])
+
+#------------------------------------------------------------------------------
+
+class TestCopyingTriple(TestCopying):
+    def setUp(self):
+        self.set = set(["zero", 0, None])
+
+#------------------------------------------------------------------------------
+
+class TestCopyingTuple(TestCopying):
+    def setUp(self):
+        self.set = set([(1, 2)])
+
+#------------------------------------------------------------------------------
+
+class TestCopyingNested(TestCopying):
+    def setUp(self):
+        self.set = set([((1, 2), (3, 4))])
+
+#==============================================================================
+
+class TestIdentities(unittest.TestCase):
+    def setUp(self):
+        self.a = set('abracadabra')
+        self.b = set('alacazam')
+
+    def test_binopsVsSubsets(self):
+        a, b = self.a, self.b
+        self.assert_(a - b < a)
+        self.assert_(b - a < b)
+        self.assert_(a & b < a)
+        self.assert_(a & b < b)
+        self.assert_(a | b > a)
+        self.assert_(a | b > b)
+        self.assert_(a ^ b < a | b)
+
+    def test_commutativity(self):
+        a, b = self.a, self.b
+        self.assertEqual(a&b, b&a)
+        self.assertEqual(a|b, b|a)
+        self.assertEqual(a^b, b^a)
+        if a != b:
+            self.assertNotEqual(a-b, b-a)
+
+    def test_summations(self):
+        # check that sums of parts equal the whole
+        a, b = self.a, self.b
+        self.assertEqual((a-b)|(a&b)|(b-a), a|b)
+        self.assertEqual((a&b)|(a^b), a|b)
+        self.assertEqual(a|(b-a), a|b)
+        self.assertEqual((a-b)|b, a|b)
+        self.assertEqual((a-b)|(a&b), a)
+        self.assertEqual((b-a)|(a&b), b)
+        self.assertEqual((a-b)|(b-a), a^b)
+
+    def test_exclusion(self):
+        # check that inverse operations show non-overlap
+        a, b, zero = self.a, self.b, set()
+        self.assertEqual((a-b)&b, zero)
+        self.assertEqual((b-a)&a, zero)
+        self.assertEqual((a&b)&(a^b), zero)
+
+# Tests derived from test_itertools.py =======================================
+
+def R(seqn):
+    'Regular generator'
+    for i in seqn:
+        yield i
+
+class G:
+    'Sequence using __getitem__'
+    def __init__(self, seqn):
+        self.seqn = seqn
+    def __getitem__(self, i):
+        return self.seqn[i]
+
+class I:
+    'Sequence using iterator protocol'
+    def __init__(self, seqn):
+        self.seqn = seqn
+        self.i = 0
+    def __iter__(self):
+        return self
+    def next(self):
+        if self.i >= len(self.seqn): raise StopIteration
+        v = self.seqn[self.i]
+        self.i += 1
+        return v
+
+class Ig:
+    'Sequence using iterator protocol defined with a generator'
+    def __init__(self, seqn):
+        self.seqn = seqn
+        self.i = 0
+    def __iter__(self):
+        for val in self.seqn:
+            yield val
+
+class X:
+    'Missing __getitem__ and __iter__'
+    def __init__(self, seqn):
+        self.seqn = seqn
+        self.i = 0
+    def next(self):
+        if self.i >= len(self.seqn): raise StopIteration
+        v = self.seqn[self.i]
+        self.i += 1
+        return v
+
+class N:
+    'Iterator missing next()'
+    def __init__(self, seqn):
+        self.seqn = seqn
+        self.i = 0
+    def __iter__(self):
+        return self
+
+class E:
+    'Test propagation of exceptions'
+    def __init__(self, seqn):
+        self.seqn = seqn
+        self.i = 0
+    def __iter__(self):
+        return self
+    def next(self):
+        3 // 0
+
+class S:
+    'Test immediate stop'
+    def __init__(self, seqn):
+        pass
+    def __iter__(self):
+        return self
+    def next(self):
+        raise StopIteration
+
+from itertools import chain, imap
+def L(seqn):
+    'Test multiple tiers of iterators'
+    return chain(imap(lambda x:x, R(Ig(G(seqn)))))
+
+class TestVariousIteratorArgs(unittest.TestCase):
+
+    def test_constructor(self):
+        for cons in (set, frozenset):
+            for s in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5)):
+                for g in (G, I, Ig, S, L, R):
+                    self.assertEqual(sorted(cons(g(s))), sorted(g(s)))
+                self.assertRaises(TypeError, cons , X(s))
+                self.assertRaises(TypeError, cons , N(s))
+                self.assertRaises(ZeroDivisionError, cons , E(s))
+
+    def test_inline_methods(self):
+        s = set('november')
+        for data in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5), 'december'):
+            for meth in (s.union, s.intersection, s.difference, s.symmetric_difference):
+                for g in (G, I, Ig, L, R):
+                    expected = meth(data)
+                    actual = meth(G(data))
+                    self.assertEqual(sorted(actual), sorted(expected))
+                self.assertRaises(TypeError, meth, X(s))
+                self.assertRaises(TypeError, meth, N(s))
+                self.assertRaises(ZeroDivisionError, meth, E(s))
+
+    def test_inplace_methods(self):
+        for data in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5), 'december'):
+            for methname in ('update', 'intersection_update',
+                             'difference_update', 'symmetric_difference_update'):
+                for g in (G, I, Ig, S, L, R):
+                    s = set('january')
+                    t = s.copy()
+                    getattr(s, methname)(list(g(data)))
+                    getattr(t, methname)(g(data))
+                    self.assertEqual(sorted(s), sorted(t))
+
+                self.assertRaises(TypeError, getattr(set('january'), methname), X(data))
+                self.assertRaises(TypeError, getattr(set('january'), methname), N(data))
+                self.assertRaises(ZeroDivisionError, getattr(set('january'), methname), E(data))
+
+#==============================================================================
+
+def test_main(verbose=None):
+    from test import test_sets
+    test_classes = (
+        TestSet,
+        TestSetSubclass,
+        TestSetSubclassWithKeywordArgs,        
+        TestFrozenSet,
+        TestFrozenSetSubclass,
+        TestSetOfSets,
+        TestExceptionPropagation,
+        TestBasicOpsEmpty,
+        TestBasicOpsSingleton,
+        TestBasicOpsTuple,
+        TestBasicOpsTriple,
+        TestBinaryOps,
+        TestUpdateOps,
+        TestMutate,
+        TestSubsetEqualEmpty,
+        TestSubsetEqualNonEmpty,
+        TestSubsetEmptyNonEmpty,
+        TestSubsetPartial,
+        TestSubsetNonOverlap,
+        TestOnlySetsNumeric,
+        TestOnlySetsDict,
+        TestOnlySetsOperator,
+        TestOnlySetsTuple,
+        TestOnlySetsString,
+        TestOnlySetsGenerator,
+        TestCopyingEmpty,
+        TestCopyingSingleton,
+        TestCopyingTriple,
+        TestCopyingTuple,
+        TestCopyingNested,
+        TestIdentities,
+        TestVariousIteratorArgs,
+        )
+
+    test_support.run_unittest(*test_classes)
+
+    # verify reference counting
+    if verbose and hasattr(sys, "gettotalrefcount"):
+        import gc
+        counts = [None] * 5
+        for i in xrange(len(counts)):
+            test_support.run_unittest(*test_classes)
+            gc.collect()
+            counts[i] = sys.gettotalrefcount()
+        print counts
+
+if __name__ == "__main__":
+    test_main(verbose=True)

Added: vendor/Python/current/Lib/test/test_sets.py
===================================================================
--- vendor/Python/current/Lib/test/test_sets.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_sets.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,856 @@
+#!/usr/bin/env python
+
+import unittest, operator, copy, pickle, random
+from sets import Set, ImmutableSet
+from test import test_support
+
+empty_set = Set()
+
+#==============================================================================
+
+class TestBasicOps(unittest.TestCase):
+
+    def test_repr(self):
+        if self.repr is not None:
+            self.assertEqual(repr(self.set), self.repr)
+
+    def test_length(self):
+        self.assertEqual(len(self.set), self.length)
+
+    def test_self_equality(self):
+        self.assertEqual(self.set, self.set)
+
+    def test_equivalent_equality(self):
+        self.assertEqual(self.set, self.dup)
+
+    def test_copy(self):
+        self.assertEqual(self.set.copy(), self.dup)
+
+    def test_self_union(self):
+        result = self.set | self.set
+        self.assertEqual(result, self.dup)
+
+    def test_empty_union(self):
+        result = self.set | empty_set
+        self.assertEqual(result, self.dup)
+
+    def test_union_empty(self):
+        result = empty_set | self.set
+        self.assertEqual(result, self.dup)
+
+    def test_self_intersection(self):
+        result = self.set & self.set
+        self.assertEqual(result, self.dup)
+
+    def test_empty_intersection(self):
+        result = self.set & empty_set
+        self.assertEqual(result, empty_set)
+
+    def test_intersection_empty(self):
+        result = empty_set & self.set
+        self.assertEqual(result, empty_set)
+
+    def test_self_symmetric_difference(self):
+        result = self.set ^ self.set
+        self.assertEqual(result, empty_set)
+
+    def checkempty_symmetric_difference(self):
+        result = self.set ^ empty_set
+        self.assertEqual(result, self.set)
+
+    def test_self_difference(self):
+        result = self.set - self.set
+        self.assertEqual(result, empty_set)
+
+    def test_empty_difference(self):
+        result = self.set - empty_set
+        self.assertEqual(result, self.dup)
+
+    def test_empty_difference_rev(self):
+        result = empty_set - self.set
+        self.assertEqual(result, empty_set)
+
+    def test_iteration(self):
+        for v in self.set:
+            self.assert_(v in self.values)
+
+    def test_pickling(self):
+        p = pickle.dumps(self.set)
+        copy = pickle.loads(p)
+        self.assertEqual(self.set, copy,
+                         "%s != %s" % (self.set, copy))
+
+#------------------------------------------------------------------------------
+
+class TestBasicOpsEmpty(TestBasicOps):
+    def setUp(self):
+        self.case   = "empty set"
+        self.values = []
+        self.set    = Set(self.values)
+        self.dup    = Set(self.values)
+        self.length = 0
+        self.repr   = "Set([])"
+
+#------------------------------------------------------------------------------
+
+class TestBasicOpsSingleton(TestBasicOps):
+    def setUp(self):
+        self.case   = "unit set (number)"
+        self.values = [3]
+        self.set    = Set(self.values)
+        self.dup    = Set(self.values)
+        self.length = 1
+        self.repr   = "Set([3])"
+
+    def test_in(self):
+        self.failUnless(3 in self.set)
+
+    def test_not_in(self):
+        self.failUnless(2 not in self.set)
+
+#------------------------------------------------------------------------------
+
+class TestBasicOpsTuple(TestBasicOps):
+    def setUp(self):
+        self.case   = "unit set (tuple)"
+        self.values = [(0, "zero")]
+        self.set    = Set(self.values)
+        self.dup    = Set(self.values)
+        self.length = 1
+        self.repr   = "Set([(0, 'zero')])"
+
+    def test_in(self):
+        self.failUnless((0, "zero") in self.set)
+
+    def test_not_in(self):
+        self.failUnless(9 not in self.set)
+
+#------------------------------------------------------------------------------
+
+class TestBasicOpsTriple(TestBasicOps):
+    def setUp(self):
+        self.case   = "triple set"
+        self.values = [0, "zero", operator.add]
+        self.set    = Set(self.values)
+        self.dup    = Set(self.values)
+        self.length = 3
+        self.repr   = None
+
+#==============================================================================
+
+def baditer():
+    raise TypeError
+    yield True
+
+def gooditer():
+    yield True
+
+class TestExceptionPropagation(unittest.TestCase):
+    """SF 628246:  Set constructor should not trap iterator TypeErrors"""
+
+    def test_instanceWithException(self):
+        self.assertRaises(TypeError, Set, baditer())
+
+    def test_instancesWithoutException(self):
+        # All of these iterables should load without exception.
+        Set([1,2,3])
+        Set((1,2,3))
+        Set({'one':1, 'two':2, 'three':3})
+        Set(xrange(3))
+        Set('abc')
+        Set(gooditer())
+
+#==============================================================================
+
+class TestSetOfSets(unittest.TestCase):
+    def test_constructor(self):
+        inner = Set([1])
+        outer = Set([inner])
+        element = outer.pop()
+        self.assertEqual(type(element), ImmutableSet)
+        outer.add(inner)        # Rebuild set of sets with .add method
+        outer.remove(inner)
+        self.assertEqual(outer, Set())   # Verify that remove worked
+        outer.discard(inner)    # Absence of KeyError indicates working fine
+
+#==============================================================================
+
+class TestBinaryOps(unittest.TestCase):
+    def setUp(self):
+        self.set = Set((2, 4, 6))
+
+    def test_eq(self):              # SF bug 643115
+        self.assertEqual(self.set, Set({2:1,4:3,6:5}))
+
+    def test_union_subset(self):
+        result = self.set | Set([2])
+        self.assertEqual(result, Set((2, 4, 6)))
+
+    def test_union_superset(self):
+        result = self.set | Set([2, 4, 6, 8])
+        self.assertEqual(result, Set([2, 4, 6, 8]))
+
+    def test_union_overlap(self):
+        result = self.set | Set([3, 4, 5])
+        self.assertEqual(result, Set([2, 3, 4, 5, 6]))
+
+    def test_union_non_overlap(self):
+        result = self.set | Set([8])
+        self.assertEqual(result, Set([2, 4, 6, 8]))
+
+    def test_intersection_subset(self):
+        result = self.set & Set((2, 4))
+        self.assertEqual(result, Set((2, 4)))
+
+    def test_intersection_superset(self):
+        result = self.set & Set([2, 4, 6, 8])
+        self.assertEqual(result, Set([2, 4, 6]))
+
+    def test_intersection_overlap(self):
+        result = self.set & Set([3, 4, 5])
+        self.assertEqual(result, Set([4]))
+
+    def test_intersection_non_overlap(self):
+        result = self.set & Set([8])
+        self.assertEqual(result, empty_set)
+
+    def test_sym_difference_subset(self):
+        result = self.set ^ Set((2, 4))
+        self.assertEqual(result, Set([6]))
+
+    def test_sym_difference_superset(self):
+        result = self.set ^ Set((2, 4, 6, 8))
+        self.assertEqual(result, Set([8]))
+
+    def test_sym_difference_overlap(self):
+        result = self.set ^ Set((3, 4, 5))
+        self.assertEqual(result, Set([2, 3, 5, 6]))
+
+    def test_sym_difference_non_overlap(self):
+        result = self.set ^ Set([8])
+        self.assertEqual(result, Set([2, 4, 6, 8]))
+
+    def test_cmp(self):
+        a, b = Set('a'), Set('b')
+        self.assertRaises(TypeError, cmp, a, b)
+
+        # You can view this as a buglet:  cmp(a, a) does not raise TypeError,
+        # because __eq__ is tried before __cmp__, and a.__eq__(a) returns True,
+        # which Python thinks is good enough to synthesize a cmp() result
+        # without calling __cmp__.
+        self.assertEqual(cmp(a, a), 0)
+
+        self.assertRaises(TypeError, cmp, a, 12)
+        self.assertRaises(TypeError, cmp, "abc", a)
+
+    def test_inplace_on_self(self):
+        t = self.set.copy()
+        t |= t
+        self.assertEqual(t, self.set)
+        t &= t
+        self.assertEqual(t, self.set)
+        t -= t
+        self.assertEqual(len(t), 0)
+        t = self.set.copy()
+        t ^= t
+        self.assertEqual(len(t), 0)
+
+
+#==============================================================================
+
+class TestUpdateOps(unittest.TestCase):
+    def setUp(self):
+        self.set = Set((2, 4, 6))
+
+    def test_union_subset(self):
+        self.set |= Set([2])
+        self.assertEqual(self.set, Set((2, 4, 6)))
+
+    def test_union_superset(self):
+        self.set |= Set([2, 4, 6, 8])
+        self.assertEqual(self.set, Set([2, 4, 6, 8]))
+
+    def test_union_overlap(self):
+        self.set |= Set([3, 4, 5])
+        self.assertEqual(self.set, Set([2, 3, 4, 5, 6]))
+
+    def test_union_non_overlap(self):
+        self.set |= Set([8])
+        self.assertEqual(self.set, Set([2, 4, 6, 8]))
+
+    def test_union_method_call(self):
+        self.set.union_update(Set([3, 4, 5]))
+        self.assertEqual(self.set, Set([2, 3, 4, 5, 6]))
+
+    def test_intersection_subset(self):
+        self.set &= Set((2, 4))
+        self.assertEqual(self.set, Set((2, 4)))
+
+    def test_intersection_superset(self):
+        self.set &= Set([2, 4, 6, 8])
+        self.assertEqual(self.set, Set([2, 4, 6]))
+
+    def test_intersection_overlap(self):
+        self.set &= Set([3, 4, 5])
+        self.assertEqual(self.set, Set([4]))
+
+    def test_intersection_non_overlap(self):
+        self.set &= Set([8])
+        self.assertEqual(self.set, empty_set)
+
+    def test_intersection_method_call(self):
+        self.set.intersection_update(Set([3, 4, 5]))
+        self.assertEqual(self.set, Set([4]))
+
+    def test_sym_difference_subset(self):
+        self.set ^= Set((2, 4))
+        self.assertEqual(self.set, Set([6]))
+
+    def test_sym_difference_superset(self):
+        self.set ^= Set((2, 4, 6, 8))
+        self.assertEqual(self.set, Set([8]))
+
+    def test_sym_difference_overlap(self):
+        self.set ^= Set((3, 4, 5))
+        self.assertEqual(self.set, Set([2, 3, 5, 6]))
+
+    def test_sym_difference_non_overlap(self):
+        self.set ^= Set([8])
+        self.assertEqual(self.set, Set([2, 4, 6, 8]))
+
+    def test_sym_difference_method_call(self):
+        self.set.symmetric_difference_update(Set([3, 4, 5]))
+        self.assertEqual(self.set, Set([2, 3, 5, 6]))
+
+    def test_difference_subset(self):
+        self.set -= Set((2, 4))
+        self.assertEqual(self.set, Set([6]))
+
+    def test_difference_superset(self):
+        self.set -= Set((2, 4, 6, 8))
+        self.assertEqual(self.set, Set([]))
+
+    def test_difference_overlap(self):
+        self.set -= Set((3, 4, 5))
+        self.assertEqual(self.set, Set([2, 6]))
+
+    def test_difference_non_overlap(self):
+        self.set -= Set([8])
+        self.assertEqual(self.set, Set([2, 4, 6]))
+
+    def test_difference_method_call(self):
+        self.set.difference_update(Set([3, 4, 5]))
+        self.assertEqual(self.set, Set([2, 6]))
+
+#==============================================================================
+
+class TestMutate(unittest.TestCase):
+    def setUp(self):
+        self.values = ["a", "b", "c"]
+        self.set = Set(self.values)
+
+    def test_add_present(self):
+        self.set.add("c")
+        self.assertEqual(self.set, Set("abc"))
+
+    def test_add_absent(self):
+        self.set.add("d")
+        self.assertEqual(self.set, Set("abcd"))
+
+    def test_add_until_full(self):
+        tmp = Set()
+        expected_len = 0
+        for v in self.values:
+            tmp.add(v)
+            expected_len += 1
+            self.assertEqual(len(tmp), expected_len)
+        self.assertEqual(tmp, self.set)
+
+    def test_remove_present(self):
+        self.set.remove("b")
+        self.assertEqual(self.set, Set("ac"))
+
+    def test_remove_absent(self):
+        try:
+            self.set.remove("d")
+            self.fail("Removing missing element should have raised LookupError")
+        except LookupError:
+            pass
+
+    def test_remove_until_empty(self):
+        expected_len = len(self.set)
+        for v in self.values:
+            self.set.remove(v)
+            expected_len -= 1
+            self.assertEqual(len(self.set), expected_len)
+
+    def test_discard_present(self):
+        self.set.discard("c")
+        self.assertEqual(self.set, Set("ab"))
+
+    def test_discard_absent(self):
+        self.set.discard("d")
+        self.assertEqual(self.set, Set("abc"))
+
+    def test_clear(self):
+        self.set.clear()
+        self.assertEqual(len(self.set), 0)
+
+    def test_pop(self):
+        popped = {}
+        while self.set:
+            popped[self.set.pop()] = None
+        self.assertEqual(len(popped), len(self.values))
+        for v in self.values:
+            self.failUnless(v in popped)
+
+    def test_update_empty_tuple(self):
+        self.set.union_update(())
+        self.assertEqual(self.set, Set(self.values))
+
+    def test_update_unit_tuple_overlap(self):
+        self.set.union_update(("a",))
+        self.assertEqual(self.set, Set(self.values))
+
+    def test_update_unit_tuple_non_overlap(self):
+        self.set.union_update(("a", "z"))
+        self.assertEqual(self.set, Set(self.values + ["z"]))
+
+#==============================================================================
+
+class TestSubsets(unittest.TestCase):
+
+    case2method = {"<=": "issubset",
+                   ">=": "issuperset",
+                  }
+
+    reverse = {"==": "==",
+               "!=": "!=",
+               "<":  ">",
+               ">":  "<",
+               "<=": ">=",
+               ">=": "<=",
+              }
+
+    def test_issubset(self):
+        x = self.left
+        y = self.right
+        for case in "!=", "==", "<", "<=", ">", ">=":
+            expected = case in self.cases
+            # Test the binary infix spelling.
+            result = eval("x" + case + "y", locals())
+            self.assertEqual(result, expected)
+            # Test the "friendly" method-name spelling, if one exists.
+            if case in TestSubsets.case2method:
+                method = getattr(x, TestSubsets.case2method[case])
+                result = method(y)
+                self.assertEqual(result, expected)
+
+            # Now do the same for the operands reversed.
+            rcase = TestSubsets.reverse[case]
+            result = eval("y" + rcase + "x", locals())
+            self.assertEqual(result, expected)
+            if rcase in TestSubsets.case2method:
+                method = getattr(y, TestSubsets.case2method[rcase])
+                result = method(x)
+                self.assertEqual(result, expected)
+#------------------------------------------------------------------------------
+
+class TestSubsetEqualEmpty(TestSubsets):
+    left  = Set()
+    right = Set()
+    name  = "both empty"
+    cases = "==", "<=", ">="
+
+#------------------------------------------------------------------------------
+
+class TestSubsetEqualNonEmpty(TestSubsets):
+    left  = Set([1, 2])
+    right = Set([1, 2])
+    name  = "equal pair"
+    cases = "==", "<=", ">="
+
+#------------------------------------------------------------------------------
+
+class TestSubsetEmptyNonEmpty(TestSubsets):
+    left  = Set()
+    right = Set([1, 2])
+    name  = "one empty, one non-empty"
+    cases = "!=", "<", "<="
+
+#------------------------------------------------------------------------------
+
+class TestSubsetPartial(TestSubsets):
+    left  = Set([1])
+    right = Set([1, 2])
+    name  = "one a non-empty proper subset of other"
+    cases = "!=", "<", "<="
+
+#------------------------------------------------------------------------------
+
+class TestSubsetNonOverlap(TestSubsets):
+    left  = Set([1])
+    right = Set([2])
+    name  = "neither empty, neither contains"
+    cases = "!="
+
+#==============================================================================
+
+class TestOnlySetsInBinaryOps(unittest.TestCase):
+
+    def test_eq_ne(self):
+        # Unlike the others, this is testing that == and != *are* allowed.
+        self.assertEqual(self.other == self.set, False)
+        self.assertEqual(self.set == self.other, False)
+        self.assertEqual(self.other != self.set, True)
+        self.assertEqual(self.set != self.other, True)
+
+    def test_ge_gt_le_lt(self):
+        self.assertRaises(TypeError, lambda: self.set < self.other)
+        self.assertRaises(TypeError, lambda: self.set <= self.other)
+        self.assertRaises(TypeError, lambda: self.set > self.other)
+        self.assertRaises(TypeError, lambda: self.set >= self.other)
+
+        self.assertRaises(TypeError, lambda: self.other < self.set)
+        self.assertRaises(TypeError, lambda: self.other <= self.set)
+        self.assertRaises(TypeError, lambda: self.other > self.set)
+        self.assertRaises(TypeError, lambda: self.other >= self.set)
+
+    def test_union_update_operator(self):
+        try:
+            self.set |= self.other
+        except TypeError:
+            pass
+        else:
+            self.fail("expected TypeError")
+
+    def test_union_update(self):
+        if self.otherIsIterable:
+            self.set.union_update(self.other)
+        else:
+            self.assertRaises(TypeError, self.set.union_update, self.other)
+
+    def test_union(self):
+        self.assertRaises(TypeError, lambda: self.set | self.other)
+        self.assertRaises(TypeError, lambda: self.other | self.set)
+        if self.otherIsIterable:
+            self.set.union(self.other)
+        else:
+            self.assertRaises(TypeError, self.set.union, self.other)
+
+    def test_intersection_update_operator(self):
+        try:
+            self.set &= self.other
+        except TypeError:
+            pass
+        else:
+            self.fail("expected TypeError")
+
+    def test_intersection_update(self):
+        if self.otherIsIterable:
+            self.set.intersection_update(self.other)
+        else:
+            self.assertRaises(TypeError,
+                              self.set.intersection_update,
+                              self.other)
+
+    def test_intersection(self):
+        self.assertRaises(TypeError, lambda: self.set & self.other)
+        self.assertRaises(TypeError, lambda: self.other & self.set)
+        if self.otherIsIterable:
+            self.set.intersection(self.other)
+        else:
+            self.assertRaises(TypeError, self.set.intersection, self.other)
+
+    def test_sym_difference_update_operator(self):
+        try:
+            self.set ^= self.other
+        except TypeError:
+            pass
+        else:
+            self.fail("expected TypeError")
+
+    def test_sym_difference_update(self):
+        if self.otherIsIterable:
+            self.set.symmetric_difference_update(self.other)
+        else:
+            self.assertRaises(TypeError,
+                              self.set.symmetric_difference_update,
+                              self.other)
+
+    def test_sym_difference(self):
+        self.assertRaises(TypeError, lambda: self.set ^ self.other)
+        self.assertRaises(TypeError, lambda: self.other ^ self.set)
+        if self.otherIsIterable:
+            self.set.symmetric_difference(self.other)
+        else:
+            self.assertRaises(TypeError, self.set.symmetric_difference, self.other)
+
+    def test_difference_update_operator(self):
+        try:
+            self.set -= self.other
+        except TypeError:
+            pass
+        else:
+            self.fail("expected TypeError")
+
+    def test_difference_update(self):
+        if self.otherIsIterable:
+            self.set.difference_update(self.other)
+        else:
+            self.assertRaises(TypeError,
+                              self.set.difference_update,
+                              self.other)
+
+    def test_difference(self):
+        self.assertRaises(TypeError, lambda: self.set - self.other)
+        self.assertRaises(TypeError, lambda: self.other - self.set)
+        if self.otherIsIterable:
+            self.set.difference(self.other)
+        else:
+            self.assertRaises(TypeError, self.set.difference, self.other)
+
+#------------------------------------------------------------------------------
+
+class TestOnlySetsNumeric(TestOnlySetsInBinaryOps):
+    def setUp(self):
+        self.set   = Set((1, 2, 3))
+        self.other = 19
+        self.otherIsIterable = False
+
+#------------------------------------------------------------------------------
+
+class TestOnlySetsDict(TestOnlySetsInBinaryOps):
+    def setUp(self):
+        self.set   = Set((1, 2, 3))
+        self.other = {1:2, 3:4}
+        self.otherIsIterable = True
+
+#------------------------------------------------------------------------------
+
+class TestOnlySetsOperator(TestOnlySetsInBinaryOps):
+    def setUp(self):
+        self.set   = Set((1, 2, 3))
+        self.other = operator.add
+        self.otherIsIterable = False
+
+#------------------------------------------------------------------------------
+
+class TestOnlySetsTuple(TestOnlySetsInBinaryOps):
+    def setUp(self):
+        self.set   = Set((1, 2, 3))
+        self.other = (2, 4, 6)
+        self.otherIsIterable = True
+
+#------------------------------------------------------------------------------
+
+class TestOnlySetsString(TestOnlySetsInBinaryOps):
+    def setUp(self):
+        self.set   = Set((1, 2, 3))
+        self.other = 'abc'
+        self.otherIsIterable = True
+
+#------------------------------------------------------------------------------
+
+class TestOnlySetsGenerator(TestOnlySetsInBinaryOps):
+    def setUp(self):
+        def gen():
+            for i in xrange(0, 10, 2):
+                yield i
+        self.set   = Set((1, 2, 3))
+        self.other = gen()
+        self.otherIsIterable = True
+
+#------------------------------------------------------------------------------
+
+class TestOnlySetsofSets(TestOnlySetsInBinaryOps):
+    def setUp(self):
+        self.set   = Set((1, 2, 3))
+        self.other = [Set('ab'), ImmutableSet('cd')]
+        self.otherIsIterable = True
+
+#==============================================================================
+
+class TestCopying(unittest.TestCase):
+
+    def test_copy(self):
+        dup = self.set.copy()
+        dup_list = list(dup); dup_list.sort()
+        set_list = list(self.set); set_list.sort()
+        self.assertEqual(len(dup_list), len(set_list))
+        for i in range(len(dup_list)):
+            self.failUnless(dup_list[i] is set_list[i])
+
+    def test_deep_copy(self):
+        dup = copy.deepcopy(self.set)
+        ##print type(dup), repr(dup)
+        dup_list = list(dup); dup_list.sort()
+        set_list = list(self.set); set_list.sort()
+        self.assertEqual(len(dup_list), len(set_list))
+        for i in range(len(dup_list)):
+            self.assertEqual(dup_list[i], set_list[i])
+
+#------------------------------------------------------------------------------
+
+class TestCopyingEmpty(TestCopying):
+    def setUp(self):
+        self.set = Set()
+
+#------------------------------------------------------------------------------
+
+class TestCopyingSingleton(TestCopying):
+    def setUp(self):
+        self.set = Set(["hello"])
+
+#------------------------------------------------------------------------------
+
+class TestCopyingTriple(TestCopying):
+    def setUp(self):
+        self.set = Set(["zero", 0, None])
+
+#------------------------------------------------------------------------------
+
+class TestCopyingTuple(TestCopying):
+    def setUp(self):
+        self.set = Set([(1, 2)])
+
+#------------------------------------------------------------------------------
+
+class TestCopyingNested(TestCopying):
+    def setUp(self):
+        self.set = Set([((1, 2), (3, 4))])
+
+#==============================================================================
+
+class TestIdentities(unittest.TestCase):
+    def setUp(self):
+        self.a = Set([random.randrange(100) for i in xrange(50)])
+        self.b = Set([random.randrange(100) for i in xrange(50)])
+
+    def test_binopsVsSubsets(self):
+        a, b = self.a, self.b
+        self.assert_(a - b <= a)
+        self.assert_(b - a <= b)
+        self.assert_(a & b <= a)
+        self.assert_(a & b <= b)
+        self.assert_(a | b >= a)
+        self.assert_(a | b >= b)
+        self.assert_(a ^ b <= a | b)
+
+    def test_commutativity(self):
+        a, b = self.a, self.b
+        self.assertEqual(a&b, b&a)
+        self.assertEqual(a|b, b|a)
+        self.assertEqual(a^b, b^a)
+        if a != b:
+            self.assertNotEqual(a-b, b-a)
+
+    def test_reflexsive_relations(self):
+        a, zero = self.a, Set()
+        self.assertEqual(a ^ a, zero)
+        self.assertEqual(a - a, zero)
+        self.assertEqual(a | a, a)
+        self.assertEqual(a & a, a)
+        self.assert_(a <= a)
+        self.assert_(a >= a)
+        self.assert_(a == a)
+
+    def test_summations(self):
+        # check that sums of parts equal the whole
+        a, b = self.a, self.b
+        self.assertEqual((a-b)|(a&b)|(b-a), a|b)
+        self.assertEqual((a&b)|(a^b), a|b)
+        self.assertEqual(a|(b-a), a|b)
+        self.assertEqual((a-b)|b, a|b)
+        self.assertEqual((a-b)|(a&b), a)
+        self.assertEqual((b-a)|(a&b), b)
+        self.assertEqual((a-b)|(b-a), a^b)
+
+    def test_exclusion(self):
+        # check that inverse operations do not overlap
+        a, b, zero = self.a, self.b, Set()
+        self.assertEqual((a-b)&b, zero)
+        self.assertEqual((b-a)&a, zero)
+        self.assertEqual((a&b)&(a^b), zero)
+
+    def test_cardinality_relations(self):
+        a, b = self.a, self.b
+        self.assertEqual(len(a), len(a-b) + len(a&b))
+        self.assertEqual(len(b), len(b-a) + len(a&b))
+        self.assertEqual(len(a^b), len(a-b) + len(b-a))
+        self.assertEqual(len(a|b), len(a-b) + len(a&b) + len(b-a))
+        self.assertEqual(len(a^b) + len(a&b), len(a|b))
+
+#==============================================================================
+
+libreftest = """
+Example from the Library Reference:  Doc/lib/libsets.tex
+
+>>> from sets import Set as Base  # override _repr to get sorted output
+>>> class Set(Base):
+...     def _repr(self):
+...         return Base._repr(self, sorted=True)
+>>> engineers = Set(['John', 'Jane', 'Jack', 'Janice'])
+>>> programmers = Set(['Jack', 'Sam', 'Susan', 'Janice'])
+>>> managers = Set(['Jane', 'Jack', 'Susan', 'Zack'])
+>>> employees = engineers | programmers | managers           # union
+>>> engineering_management = engineers & managers            # intersection
+>>> fulltime_management = managers - engineers - programmers # difference
+>>> engineers.add('Marvin')
+>>> print engineers
+Set(['Jack', 'Jane', 'Janice', 'John', 'Marvin'])
+>>> employees.issuperset(engineers)           # superset test
+False
+>>> employees.union_update(engineers)         # update from another set
+>>> employees.issuperset(engineers)
+True
+>>> for group in [engineers, programmers, managers, employees]:
+...     group.discard('Susan')                # unconditionally remove element
+...     print group
+...
+Set(['Jack', 'Jane', 'Janice', 'John', 'Marvin'])
+Set(['Jack', 'Janice', 'Sam'])
+Set(['Jack', 'Jane', 'Zack'])
+Set(['Jack', 'Jane', 'Janice', 'John', 'Marvin', 'Sam', 'Zack'])
+"""
+
+#==============================================================================
+
+__test__ = {'libreftest' : libreftest}
+
+def test_main(verbose=None):
+    import doctest
+    from test import test_sets
+    test_support.run_unittest(
+        TestSetOfSets,
+        TestExceptionPropagation,
+        TestBasicOpsEmpty,
+        TestBasicOpsSingleton,
+        TestBasicOpsTuple,
+        TestBasicOpsTriple,
+        TestBinaryOps,
+        TestUpdateOps,
+        TestMutate,
+        TestSubsetEqualEmpty,
+        TestSubsetEqualNonEmpty,
+        TestSubsetEmptyNonEmpty,
+        TestSubsetPartial,
+        TestSubsetNonOverlap,
+        TestOnlySetsNumeric,
+        TestOnlySetsDict,
+        TestOnlySetsOperator,
+        TestOnlySetsTuple,
+        TestOnlySetsString,
+        TestOnlySetsGenerator,
+        TestOnlySetsofSets,
+        TestCopyingEmpty,
+        TestCopyingSingleton,
+        TestCopyingTriple,
+        TestCopyingTuple,
+        TestCopyingNested,
+        TestIdentities,
+        doctest.DocTestSuite(test_sets),
+    )
+
+if __name__ == "__main__":
+    test_main(verbose=True)

Added: vendor/Python/current/Lib/test/test_sgmllib.py
===================================================================
--- vendor/Python/current/Lib/test/test_sgmllib.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_sgmllib.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,439 @@
+import htmlentitydefs
+import pprint
+import re
+import sgmllib
+import unittest
+from test import test_support
+
+
+class EventCollector(sgmllib.SGMLParser):
+
+    def __init__(self):
+        self.events = []
+        self.append = self.events.append
+        sgmllib.SGMLParser.__init__(self)
+
+    def get_events(self):
+        # Normalize the list of events so that buffer artefacts don't
+        # separate runs of contiguous characters.
+        L = []
+        prevtype = None
+        for event in self.events:
+            type = event[0]
+            if type == prevtype == "data":
+                L[-1] = ("data", L[-1][1] + event[1])
+            else:
+                L.append(event)
+            prevtype = type
+        self.events = L
+        return L
+
+    # structure markup
+
+    def unknown_starttag(self, tag, attrs):
+        self.append(("starttag", tag, attrs))
+
+    def unknown_endtag(self, tag):
+        self.append(("endtag", tag))
+
+    # all other markup
+
+    def handle_comment(self, data):
+        self.append(("comment", data))
+
+    def handle_charref(self, data):
+        self.append(("charref", data))
+
+    def handle_data(self, data):
+        self.append(("data", data))
+
+    def handle_decl(self, decl):
+        self.append(("decl", decl))
+
+    def handle_entityref(self, data):
+        self.append(("entityref", data))
+
+    def handle_pi(self, data):
+        self.append(("pi", data))
+
+    def unknown_decl(self, decl):
+        self.append(("unknown decl", decl))
+
+
+class CDATAEventCollector(EventCollector):
+    def start_cdata(self, attrs):
+        self.append(("starttag", "cdata", attrs))
+        self.setliteral()
+
+
+class HTMLEntityCollector(EventCollector):
+
+    entity_or_charref = re.compile('(?:&([a-zA-Z][-.a-zA-Z0-9]*)'
+        '|&#(x[0-9a-zA-Z]+|[0-9]+))(;?)')
+
+    def convert_charref(self, name):
+        self.append(("charref", "convert", name))
+        if name[0] != "x":
+            return EventCollector.convert_charref(self, name)
+
+    def convert_codepoint(self, codepoint):
+        self.append(("codepoint", "convert", codepoint))
+        EventCollector.convert_codepoint(self, codepoint)
+
+    def convert_entityref(self, name):
+        self.append(("entityref", "convert", name))
+        return EventCollector.convert_entityref(self, name)
+
+    # These to record that they were called, then pass the call along
+    # to the default implementation so that it's actions can be
+    # recorded.
+
+    def handle_charref(self, data):
+        self.append(("charref", data))
+        sgmllib.SGMLParser.handle_charref(self, data)
+
+    def handle_entityref(self, data):
+        self.append(("entityref", data))
+        sgmllib.SGMLParser.handle_entityref(self, data)
+
+
+class SGMLParserTestCase(unittest.TestCase):
+
+    collector = EventCollector
+
+    def get_events(self, source):
+        parser = self.collector()
+        try:
+            for s in source:
+                parser.feed(s)
+            parser.close()
+        except:
+            #self.events = parser.events
+            raise
+        return parser.get_events()
+
+    def check_events(self, source, expected_events):
+        try:
+            events = self.get_events(source)
+        except:
+            import sys
+            #print >>sys.stderr, pprint.pformat(self.events)
+            raise
+        if events != expected_events:
+            self.fail("received events did not match expected events\n"
+                      "Expected:\n" + pprint.pformat(expected_events) +
+                      "\nReceived:\n" + pprint.pformat(events))
+
+    def check_parse_error(self, source):
+        parser = EventCollector()
+        try:
+            parser.feed(source)
+            parser.close()
+        except sgmllib.SGMLParseError:
+            pass
+        else:
+            self.fail("expected SGMLParseError for %r\nReceived:\n%s"
+                      % (source, pprint.pformat(parser.get_events())))
+
+    def test_doctype_decl_internal(self):
+        inside = """\
+DOCTYPE html PUBLIC '-//W3C//DTD HTML 4.01//EN'
+             SYSTEM 'http://www.w3.org/TR/html401/strict.dtd' [
+  <!ELEMENT html - O EMPTY>
+  <!ATTLIST html
+      version CDATA #IMPLIED
+      profile CDATA 'DublinCore'>
+  <!NOTATION datatype SYSTEM 'http://xml.python.org/notations/python-module'>
+  <!ENTITY myEntity 'internal parsed entity'>
+  <!ENTITY anEntity SYSTEM 'http://xml.python.org/entities/something.xml'>
+  <!ENTITY % paramEntity 'name|name|name'>
+  %paramEntity;
+  <!-- comment -->
+]"""
+        self.check_events(["<!%s>" % inside], [
+            ("decl", inside),
+            ])
+
+    def test_doctype_decl_external(self):
+        inside = "DOCTYPE html PUBLIC '-//W3C//DTD HTML 4.01//EN'"
+        self.check_events("<!%s>" % inside, [
+            ("decl", inside),
+            ])
+
+    def test_underscore_in_attrname(self):
+        # SF bug #436621
+        """Make sure attribute names with underscores are accepted"""
+        self.check_events("<a has_under _under>", [
+            ("starttag", "a", [("has_under", "has_under"),
+                               ("_under", "_under")]),
+            ])
+
+    def test_underscore_in_tagname(self):
+        # SF bug #436621
+        """Make sure tag names with underscores are accepted"""
+        self.check_events("<has_under></has_under>", [
+            ("starttag", "has_under", []),
+            ("endtag", "has_under"),
+            ])
+
+    def test_quotes_in_unquoted_attrs(self):
+        # SF bug #436621
+        """Be sure quotes in unquoted attributes are made part of the value"""
+        self.check_events("<a href=foo'bar\"baz>", [
+            ("starttag", "a", [("href", "foo'bar\"baz")]),
+            ])
+
+    def test_xhtml_empty_tag(self):
+        """Handling of XHTML-style empty start tags"""
+        self.check_events("<br />text<i></i>", [
+            ("starttag", "br", []),
+            ("data", "text"),
+            ("starttag", "i", []),
+            ("endtag", "i"),
+            ])
+
+    def test_processing_instruction_only(self):
+        self.check_events("<?processing instruction>", [
+            ("pi", "processing instruction"),
+            ])
+
+    def test_bad_nesting(self):
+        self.check_events("<a><b></a></b>", [
+            ("starttag", "a", []),
+            ("starttag", "b", []),
+            ("endtag", "a"),
+            ("endtag", "b"),
+            ])
+
+    def test_bare_ampersands(self):
+        self.check_events("this text & contains & ampersands &", [
+            ("data", "this text & contains & ampersands &"),
+            ])
+
+    def test_bare_pointy_brackets(self):
+        self.check_events("this < text > contains < bare>pointy< brackets", [
+            ("data", "this < text > contains < bare>pointy< brackets"),
+            ])
+
+    def test_attr_syntax(self):
+        output = [
+          ("starttag", "a", [("b", "v"), ("c", "v"), ("d", "v"), ("e", "e")])
+          ]
+        self.check_events("""<a b='v' c="v" d=v e>""", output)
+        self.check_events("""<a  b = 'v' c = "v" d = v e>""", output)
+        self.check_events("""<a\nb\n=\n'v'\nc\n=\n"v"\nd\n=\nv\ne>""", output)
+        self.check_events("""<a\tb\t=\t'v'\tc\t=\t"v"\td\t=\tv\te>""", output)
+
+    def test_attr_values(self):
+        self.check_events("""<a b='xxx\n\txxx' c="yyy\t\nyyy" d='\txyz\n'>""",
+                        [("starttag", "a", [("b", "xxx\n\txxx"),
+                                            ("c", "yyy\t\nyyy"),
+                                            ("d", "\txyz\n")])
+                         ])
+        self.check_events("""<a b='' c="">""", [
+            ("starttag", "a", [("b", ""), ("c", "")]),
+            ])
+        # URL construction stuff from RFC 1808:
+        safe = "$-_.+"
+        extra = "!*'(),"
+        reserved = ";/?:@&="
+        url = "http://example.com:8080/path/to/file?%s%s%s" % (
+            safe, extra, reserved)
+        self.check_events("""<e a=%s>""" % url, [
+            ("starttag", "e", [("a", url)]),
+            ])
+        # Regression test for SF patch #669683.
+        self.check_events("<e a=rgb(1,2,3)>", [
+            ("starttag", "e", [("a", "rgb(1,2,3)")]),
+            ])
+
+    def test_attr_values_entities(self):
+        """Substitution of entities and charrefs in attribute values"""
+        # SF bug #1452246
+        self.check_events("""<a b=&lt; c=&lt;&gt; d=&lt-&gt; e='&lt; '
+                                f="&xxx;" g='&#32;&#33;' h='&#500;'
+                                i='x?a=b&c=d;'
+                                j='&amp;#42;' k='&#38;#42;'>""",
+            [("starttag", "a", [("b", "<"),
+                                ("c", "<>"),
+                                ("d", "&lt->"),
+                                ("e", "< "),
+                                ("f", "&xxx;"),
+                                ("g", " !"),
+                                ("h", "&#500;"),
+                                ("i", "x?a=b&c=d;"),
+                                ("j", "&#42;"),
+                                ("k", "&#42;"),
+                                ])])
+
+    def test_convert_overrides(self):
+        # This checks that the character and entity reference
+        # conversion helpers are called at the documented times.  No
+        # attempt is made to really change what the parser accepts.
+        #
+        self.collector = HTMLEntityCollector
+        self.check_events(('<a title="&ldquo;test&#x201d;">foo</a>'
+                           '&foobar;&#42;'), [
+            ('entityref', 'convert', 'ldquo'),
+            ('charref', 'convert', 'x201d'),
+            ('starttag', 'a', [('title', '&ldquo;test&#x201d;')]),
+            ('data', 'foo'),
+            ('endtag', 'a'),
+            ('entityref', 'foobar'),
+            ('entityref', 'convert', 'foobar'),
+            ('charref', '42'),
+            ('charref', 'convert', '42'),
+            ('codepoint', 'convert', 42),
+            ])
+
+    def test_attr_funky_names(self):
+        self.check_events("""<a a.b='v' c:d=v e-f=v>""", [
+            ("starttag", "a", [("a.b", "v"), ("c:d", "v"), ("e-f", "v")]),
+            ])
+
+    def test_attr_value_ip6_url(self):
+        # http://www.python.org/sf/853506
+        self.check_events(("<a href='http://[1080::8:800:200C:417A]/'>"
+                           "<a href=http://[1080::8:800:200C:417A]/>"), [
+            ("starttag", "a", [("href", "http://[1080::8:800:200C:417A]/")]),
+            ("starttag", "a", [("href", "http://[1080::8:800:200C:417A]/")]),
+            ])
+
+    def test_illegal_declarations(self):
+        s = 'abc<!spacer type="block" height="25">def'
+        self.check_events(s, [
+            ("data", "abc"),
+            ("unknown decl", 'spacer type="block" height="25"'),
+            ("data", "def"),
+            ])
+
+    def test_weird_starttags(self):
+        self.check_events("<a<a>", [
+            ("starttag", "a", []),
+            ("starttag", "a", []),
+            ])
+        self.check_events("</a<a>", [
+            ("endtag", "a"),
+            ("starttag", "a", []),
+            ])
+
+    def test_declaration_junk_chars(self):
+        self.check_parse_error("<!DOCTYPE foo $ >")
+
+    def test_get_starttag_text(self):
+        s = """<foobar   \n   one="1"\ttwo=2   >"""
+        self.check_events(s, [
+            ("starttag", "foobar", [("one", "1"), ("two", "2")]),
+            ])
+
+    def test_cdata_content(self):
+        s = ("<cdata> <!-- not a comment --> &not-an-entity-ref; </cdata>"
+             "<notcdata> <!-- comment --> </notcdata>")
+        self.collector = CDATAEventCollector
+        self.check_events(s, [
+            ("starttag", "cdata", []),
+            ("data", " <!-- not a comment --> &not-an-entity-ref; "),
+            ("endtag", "cdata"),
+            ("starttag", "notcdata", []),
+            ("data", " "),
+            ("comment", " comment "),
+            ("data", " "),
+            ("endtag", "notcdata"),
+            ])
+        s = """<cdata> <not a='start tag'> </cdata>"""
+        self.check_events(s, [
+            ("starttag", "cdata", []),
+            ("data", " <not a='start tag'> "),
+            ("endtag", "cdata"),
+            ])
+
+    def test_illegal_declarations(self):
+        s = 'abc<!spacer type="block" height="25">def'
+        self.check_events(s, [
+            ("data", "abc"),
+            ("unknown decl", 'spacer type="block" height="25"'),
+            ("data", "def"),
+            ])
+
+    def test_enumerated_attr_type(self):
+        s = "<!DOCTYPE doc [<!ATTLIST doc attr (a | b) >]>"
+        self.check_events(s, [
+            ('decl', 'DOCTYPE doc [<!ATTLIST doc attr (a | b) >]'),
+            ])
+
+    def test_read_chunks(self):
+        # SF bug #1541697, this caused sgml parser to hang
+        # Just verify this code doesn't cause a hang.
+        CHUNK = 1024  # increasing this to 8212 makes the problem go away
+
+        f = open(test_support.findfile('sgml_input.html'))
+        fp = sgmllib.SGMLParser()
+        while 1:
+            data = f.read(CHUNK)
+            fp.feed(data)
+            if len(data) != CHUNK:
+                break
+
+    # XXX These tests have been disabled by prefixing their names with
+    # an underscore.  The first two exercise outstanding bugs in the
+    # sgmllib module, and the third exhibits questionable behavior
+    # that needs to be carefully considered before changing it.
+
+    def _test_starttag_end_boundary(self):
+        self.check_events("<a b='<'>", [("starttag", "a", [("b", "<")])])
+        self.check_events("<a b='>'>", [("starttag", "a", [("b", ">")])])
+
+    def _test_buffer_artefacts(self):
+        output = [("starttag", "a", [("b", "<")])]
+        self.check_events(["<a b='<'>"], output)
+        self.check_events(["<a ", "b='<'>"], output)
+        self.check_events(["<a b", "='<'>"], output)
+        self.check_events(["<a b=", "'<'>"], output)
+        self.check_events(["<a b='<", "'>"], output)
+        self.check_events(["<a b='<'", ">"], output)
+
+        output = [("starttag", "a", [("b", ">")])]
+        self.check_events(["<a b='>'>"], output)
+        self.check_events(["<a ", "b='>'>"], output)
+        self.check_events(["<a b", "='>'>"], output)
+        self.check_events(["<a b=", "'>'>"], output)
+        self.check_events(["<a b='>", "'>"], output)
+        self.check_events(["<a b='>'", ">"], output)
+
+        output = [("comment", "abc")]
+        self.check_events(["", "<!--abc-->"], output)
+        self.check_events(["<", "!--abc-->"], output)
+        self.check_events(["<!", "--abc-->"], output)
+        self.check_events(["<!-", "-abc-->"], output)
+        self.check_events(["<!--", "abc-->"], output)
+        self.check_events(["<!--a", "bc-->"], output)
+        self.check_events(["<!--ab", "c-->"], output)
+        self.check_events(["<!--abc", "-->"], output)
+        self.check_events(["<!--abc-", "->"], output)
+        self.check_events(["<!--abc--", ">"], output)
+        self.check_events(["<!--abc-->", ""], output)
+
+    def _test_starttag_junk_chars(self):
+        self.check_parse_error("<")
+        self.check_parse_error("<>")
+        self.check_parse_error("</$>")
+        self.check_parse_error("</")
+        self.check_parse_error("</a")
+        self.check_parse_error("<$")
+        self.check_parse_error("<$>")
+        self.check_parse_error("<!")
+        self.check_parse_error("<a $>")
+        self.check_parse_error("<a")
+        self.check_parse_error("<a foo='bar'")
+        self.check_parse_error("<a foo='bar")
+        self.check_parse_error("<a foo='>'")
+        self.check_parse_error("<a foo='>")
+        self.check_parse_error("<a foo=>")
+
+
+def test_main():
+    test_support.run_unittest(SGMLParserTestCase)
+
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_sha.py
===================================================================
--- vendor/Python/current/Lib/test/test_sha.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_sha.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,52 @@
+# Testing sha module (NIST's Secure Hash Algorithm)
+
+# use the three examples from Federal Information Processing Standards
+# Publication 180-1, Secure Hash Standard,  1995 April 17
+# http://www.itl.nist.gov/div897/pubs/fip180-1.htm
+
+import sha
+import unittest
+from test import test_support
+
+
+class SHATestCase(unittest.TestCase):
+    def check(self, data, digest):
+        # Check digest matches the expected value
+        obj = sha.new(data)
+        computed = obj.hexdigest()
+        self.assert_(computed == digest)
+
+        # Verify that the value doesn't change between two consecutive
+        # digest operations.
+        computed_again = obj.hexdigest()
+        self.assert_(computed == computed_again)
+
+        # Check hexdigest() output matches digest()'s output
+        digest = obj.digest()
+        hexd = ""
+        for c in digest:
+            hexd += '%02x' % ord(c)
+        self.assert_(computed == hexd)
+
+    def test_case_1(self):
+        self.check("abc",
+                   "a9993e364706816aba3e25717850c26c9cd0d89d")
+
+    def test_case_2(self):
+        self.check("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+                   "84983e441c3bd26ebaae4aa1f95129e5e54670f1")
+
+    def test_case_3(self):
+        self.check("a" * 1000000,
+                   "34aa973cd4c4daa4f61eeb2bdbad27316534016f")
+
+    def test_case_4(self):
+        self.check(chr(0xAA) * 80,
+                   '4ca0ef38f1794b28a8f8ee110ee79d48ce13be25')
+
+def test_main():
+    test_support.run_unittest(SHATestCase)
+
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_shelve.py
===================================================================
--- vendor/Python/current/Lib/test/test_shelve.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_shelve.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,135 @@
+import os
+import unittest
+import shelve
+import glob
+from test import test_support
+
+class TestCase(unittest.TestCase):
+
+    fn = "shelftemp" + os.extsep + "db"
+
+    def test_ascii_file_shelf(self):
+        try:
+            s = shelve.open(self.fn, protocol=0)
+            s['key1'] = (1,2,3,4)
+            self.assertEqual(s['key1'], (1,2,3,4))
+            s.close()
+        finally:
+            for f in glob.glob(self.fn+"*"):
+                os.unlink(f)
+
+    def test_binary_file_shelf(self):
+        try:
+            s = shelve.open(self.fn, protocol=1)
+            s['key1'] = (1,2,3,4)
+            self.assertEqual(s['key1'], (1,2,3,4))
+            s.close()
+        finally:
+            for f in glob.glob(self.fn+"*"):
+                os.unlink(f)
+
+    def test_proto2_file_shelf(self):
+        try:
+            s = shelve.open(self.fn, protocol=2)
+            s['key1'] = (1,2,3,4)
+            self.assertEqual(s['key1'], (1,2,3,4))
+            s.close()
+        finally:
+            for f in glob.glob(self.fn+"*"):
+                os.unlink(f)
+
+    def test_in_memory_shelf(self):
+        d1 = {}
+        s = shelve.Shelf(d1, protocol=0)
+        s['key1'] = (1,2,3,4)
+        self.assertEqual(s['key1'], (1,2,3,4))
+        s.close()
+        d2 = {}
+        s = shelve.Shelf(d2, protocol=1)
+        s['key1'] = (1,2,3,4)
+        self.assertEqual(s['key1'], (1,2,3,4))
+        s.close()
+
+        self.assertEqual(len(d1), 1)
+        self.assertNotEqual(d1, d2)
+
+    def test_mutable_entry(self):
+        d1 = {}
+        s = shelve.Shelf(d1, protocol=2, writeback=False)
+        s['key1'] = [1,2,3,4]
+        self.assertEqual(s['key1'], [1,2,3,4])
+        s['key1'].append(5)
+        self.assertEqual(s['key1'], [1,2,3,4])
+        s.close()
+
+        d2 = {}
+        s = shelve.Shelf(d2, protocol=2, writeback=True)
+        s['key1'] = [1,2,3,4]
+        self.assertEqual(s['key1'], [1,2,3,4])
+        s['key1'].append(5)
+        self.assertEqual(s['key1'], [1,2,3,4,5])
+        s.close()
+
+        self.assertEqual(len(d1), 1)
+        self.assertEqual(len(d2), 1)
+
+
+from test import mapping_tests
+
+class TestShelveBase(mapping_tests.BasicTestMappingProtocol):
+    fn = "shelftemp.db"
+    counter = 0
+    def __init__(self, *args, **kw):
+        self._db = []
+        mapping_tests.BasicTestMappingProtocol.__init__(self, *args, **kw)
+    type2test = shelve.Shelf
+    def _reference(self):
+        return {"key1":"value1", "key2":2, "key3":(1,2,3)}
+    def _empty_mapping(self):
+        if self._in_mem:
+            x= shelve.Shelf({}, **self._args)
+        else:
+            self.counter+=1
+            x= shelve.open(self.fn+str(self.counter), **self._args)
+        self._db.append(x)
+        return x
+    def tearDown(self):
+        for db in self._db:
+            db.close()
+        self._db = []
+        if not self._in_mem:
+            for f in glob.glob(self.fn+"*"):
+                os.unlink(f)
+
+class TestAsciiFileShelve(TestShelveBase):
+    _args={'protocol':0}
+    _in_mem = False
+class TestBinaryFileShelve(TestShelveBase):
+    _args={'protocol':1}
+    _in_mem = False
+class TestProto2FileShelve(TestShelveBase):
+    _args={'protocol':2}
+    _in_mem = False
+class TestAsciiMemShelve(TestShelveBase):
+    _args={'protocol':0}
+    _in_mem = True
+class TestBinaryMemShelve(TestShelveBase):
+    _args={'protocol':1}
+    _in_mem = True
+class TestProto2MemShelve(TestShelveBase):
+    _args={'protocol':2}
+    _in_mem = True
+
+def test_main():
+    test_support.run_unittest(
+        TestAsciiFileShelve,
+        TestBinaryFileShelve,
+        TestProto2FileShelve,
+        TestAsciiMemShelve,
+        TestBinaryMemShelve,
+        TestProto2MemShelve,
+        TestCase
+    )
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_shlex.py
===================================================================
--- vendor/Python/current/Lib/test/test_shlex.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_shlex.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,192 @@
+# -*- coding: iso-8859-1 -*-
+import unittest
+import os, sys
+import shlex
+
+from test import test_support
+
+try:
+    from cStringIO import StringIO
+except ImportError:
+    from StringIO import StringIO
+
+
+# The original test data set was from shellwords, by Hartmut Goebel.
+
+data = r"""x|x|
+foo bar|foo|bar|
+ foo bar|foo|bar|
+ foo bar |foo|bar|
+foo   bar    bla     fasel|foo|bar|bla|fasel|
+x y  z              xxxx|x|y|z|xxxx|
+\x bar|\|x|bar|
+\ x bar|\|x|bar|
+\ bar|\|bar|
+foo \x bar|foo|\|x|bar|
+foo \ x bar|foo|\|x|bar|
+foo \ bar|foo|\|bar|
+foo "bar" bla|foo|"bar"|bla|
+"foo" "bar" "bla"|"foo"|"bar"|"bla"|
+"foo" bar "bla"|"foo"|bar|"bla"|
+"foo" bar bla|"foo"|bar|bla|
+foo 'bar' bla|foo|'bar'|bla|
+'foo' 'bar' 'bla'|'foo'|'bar'|'bla'|
+'foo' bar 'bla'|'foo'|bar|'bla'|
+'foo' bar bla|'foo'|bar|bla|
+blurb foo"bar"bar"fasel" baz|blurb|foo"bar"bar"fasel"|baz|
+blurb foo'bar'bar'fasel' baz|blurb|foo'bar'bar'fasel'|baz|
+""|""|
+''|''|
+foo "" bar|foo|""|bar|
+foo '' bar|foo|''|bar|
+foo "" "" "" bar|foo|""|""|""|bar|
+foo '' '' '' bar|foo|''|''|''|bar|
+\""|\|""|
+"\"|"\"|
+"foo\ bar"|"foo\ bar"|
+"foo\\ bar"|"foo\\ bar"|
+"foo\\ bar\"|"foo\\ bar\"|
+"foo\\" bar\""|"foo\\"|bar|\|""|
+"foo\\ bar\" dfadf"|"foo\\ bar\"|dfadf"|
+"foo\\\ bar\" dfadf"|"foo\\\ bar\"|dfadf"|
+"foo\\\x bar\" dfadf"|"foo\\\x bar\"|dfadf"|
+"foo\x bar\" dfadf"|"foo\x bar\"|dfadf"|
+\''|\|''|
+'foo\ bar'|'foo\ bar'|
+'foo\\ bar'|'foo\\ bar'|
+"foo\\\x bar\" df'a\ 'df'|"foo\\\x bar\"|df'a|\|'df'|
+\"foo"|\|"foo"|
+\"foo"\x|\|"foo"|\|x|
+"foo\x"|"foo\x"|
+"foo\ "|"foo\ "|
+foo\ xx|foo|\|xx|
+foo\ x\x|foo|\|x|\|x|
+foo\ x\x\""|foo|\|x|\|x|\|""|
+"foo\ x\x"|"foo\ x\x"|
+"foo\ x\x\\"|"foo\ x\x\\"|
+"foo\ x\x\\""foobar"|"foo\ x\x\\"|"foobar"|
+"foo\ x\x\\"\''"foobar"|"foo\ x\x\\"|\|''|"foobar"|
+"foo\ x\x\\"\'"fo'obar"|"foo\ x\x\\"|\|'"fo'|obar"|
+"foo\ x\x\\"\'"fo'obar" 'don'\''t'|"foo\ x\x\\"|\|'"fo'|obar"|'don'|\|''|t'|
+'foo\ bar'|'foo\ bar'|
+'foo\\ bar'|'foo\\ bar'|
+foo\ bar|foo|\|bar|
+foo#bar\nbaz|foobaz|
+:-) ;-)|:|-|)|;|-|)|
+áéíóú|á|é|í|ó|ú|
+"""
+
+posix_data = r"""x|x|
+foo bar|foo|bar|
+ foo bar|foo|bar|
+ foo bar |foo|bar|
+foo   bar    bla     fasel|foo|bar|bla|fasel|
+x y  z              xxxx|x|y|z|xxxx|
+\x bar|x|bar|
+\ x bar| x|bar|
+\ bar| bar|
+foo \x bar|foo|x|bar|
+foo \ x bar|foo| x|bar|
+foo \ bar|foo| bar|
+foo "bar" bla|foo|bar|bla|
+"foo" "bar" "bla"|foo|bar|bla|
+"foo" bar "bla"|foo|bar|bla|
+"foo" bar bla|foo|bar|bla|
+foo 'bar' bla|foo|bar|bla|
+'foo' 'bar' 'bla'|foo|bar|bla|
+'foo' bar 'bla'|foo|bar|bla|
+'foo' bar bla|foo|bar|bla|
+blurb foo"bar"bar"fasel" baz|blurb|foobarbarfasel|baz|
+blurb foo'bar'bar'fasel' baz|blurb|foobarbarfasel|baz|
+""||
+''||
+foo "" bar|foo||bar|
+foo '' bar|foo||bar|
+foo "" "" "" bar|foo||||bar|
+foo '' '' '' bar|foo||||bar|
+\"|"|
+"\""|"|
+"foo\ bar"|foo\ bar|
+"foo\\ bar"|foo\ bar|
+"foo\\ bar\""|foo\ bar"|
+"foo\\" bar\"|foo\|bar"|
+"foo\\ bar\" dfadf"|foo\ bar" dfadf|
+"foo\\\ bar\" dfadf"|foo\\ bar" dfadf|
+"foo\\\x bar\" dfadf"|foo\\x bar" dfadf|
+"foo\x bar\" dfadf"|foo\x bar" dfadf|
+\'|'|
+'foo\ bar'|foo\ bar|
+'foo\\ bar'|foo\\ bar|
+"foo\\\x bar\" df'a\ 'df"|foo\\x bar" df'a\ 'df|
+\"foo|"foo|
+\"foo\x|"foox|
+"foo\x"|foo\x|
+"foo\ "|foo\ |
+foo\ xx|foo xx|
+foo\ x\x|foo xx|
+foo\ x\x\"|foo xx"|
+"foo\ x\x"|foo\ x\x|
+"foo\ x\x\\"|foo\ x\x\|
+"foo\ x\x\\""foobar"|foo\ x\x\foobar|
+"foo\ x\x\\"\'"foobar"|foo\ x\x\'foobar|
+"foo\ x\x\\"\'"fo'obar"|foo\ x\x\'fo'obar|
+"foo\ x\x\\"\'"fo'obar" 'don'\''t'|foo\ x\x\'fo'obar|don't|
+"foo\ x\x\\"\'"fo'obar" 'don'\''t' \\|foo\ x\x\'fo'obar|don't|\|
+'foo\ bar'|foo\ bar|
+'foo\\ bar'|foo\\ bar|
+foo\ bar|foo bar|
+foo#bar\nbaz|foo|baz|
+:-) ;-)|:-)|;-)|
+áéíóú|áéíóú|
+"""
+
+class ShlexTest(unittest.TestCase):
+    def setUp(self):
+        self.data = [x.split("|")[:-1]
+                     for x in data.splitlines()]
+        self.posix_data = [x.split("|")[:-1]
+                           for x in posix_data.splitlines()]
+        for item in self.data:
+            item[0] = item[0].replace(r"\n", "\n")
+        for item in self.posix_data:
+            item[0] = item[0].replace(r"\n", "\n")
+
+    def splitTest(self, data, comments):
+        for i in range(len(data)):
+            l = shlex.split(data[i][0], comments=comments)
+            self.assertEqual(l, data[i][1:],
+                             "%s: %s != %s" %
+                             (data[i][0], l, data[i][1:]))
+
+    def oldSplit(self, s):
+        ret = []
+        lex = shlex.shlex(StringIO(s))
+        tok = lex.get_token()
+        while tok:
+            ret.append(tok)
+            tok = lex.get_token()
+        return ret
+
+    def testSplitPosix(self):
+        """Test data splitting with posix parser"""
+        self.splitTest(self.posix_data, comments=True)
+
+    def testCompat(self):
+        """Test compatibility interface"""
+        for i in range(len(self.data)):
+            l = self.oldSplit(self.data[i][0])
+            self.assertEqual(l, self.data[i][1:],
+                             "%s: %s != %s" %
+                             (self.data[i][0], l, self.data[i][1:]))
+
+# Allow this test to be used with old shlex.py
+if not getattr(shlex, "split", None):
+    for methname in dir(ShlexTest):
+        if methname.startswith("test") and methname != "testCompat":
+            delattr(ShlexTest, methname)
+
+def test_main():
+    test_support.run_unittest(ShlexTest)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_shutil.py
===================================================================
--- vendor/Python/current/Lib/test/test_shutil.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_shutil.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,157 @@
+# Copyright (C) 2003 Python Software Foundation
+
+import unittest
+import shutil
+import tempfile
+import sys
+import stat
+import os
+import os.path
+from test import test_support
+from test.test_support import TESTFN
+
+class TestShutil(unittest.TestCase):
+    def test_rmtree_errors(self):
+        # filename is guaranteed not to exist
+        filename = tempfile.mktemp()
+        self.assertRaises(OSError, shutil.rmtree, filename)
+
+    # See bug #1071513 for why we don't run this on cygwin
+    # and bug #1076467 for why we don't run this as root.
+    if (hasattr(os, 'chmod') and sys.platform[:6] != 'cygwin'
+        and not (hasattr(os, 'geteuid') and os.geteuid() == 0)):
+        def test_on_error(self):
+            self.errorState = 0
+            os.mkdir(TESTFN)
+            self.childpath = os.path.join(TESTFN, 'a')
+            f = open(self.childpath, 'w')
+            f.close()
+            old_dir_mode = os.stat(TESTFN).st_mode
+            old_child_mode = os.stat(self.childpath).st_mode
+            # Make unwritable.
+            os.chmod(self.childpath, stat.S_IREAD)
+            os.chmod(TESTFN, stat.S_IREAD)
+
+            shutil.rmtree(TESTFN, onerror=self.check_args_to_onerror)
+            # Test whether onerror has actually been called.
+            self.assertEqual(self.errorState, 2,
+                             "Expected call to onerror function did not happen.")
+
+            # Make writable again.
+            os.chmod(TESTFN, old_dir_mode)
+            os.chmod(self.childpath, old_child_mode)
+
+            # Clean up.
+            shutil.rmtree(TESTFN)
+
+    def check_args_to_onerror(self, func, arg, exc):
+        if self.errorState == 0:
+            self.assertEqual(func, os.remove)
+            self.assertEqual(arg, self.childpath)
+            self.failUnless(issubclass(exc[0], OSError))
+            self.errorState = 1
+        else:
+            self.assertEqual(func, os.rmdir)
+            self.assertEqual(arg, TESTFN)
+            self.failUnless(issubclass(exc[0], OSError))
+            self.errorState = 2
+
+    def test_rmtree_dont_delete_file(self):
+        # When called on a file instead of a directory, don't delete it.
+        handle, path = tempfile.mkstemp()
+        os.fdopen(handle).close()
+        self.assertRaises(OSError, shutil.rmtree, path)
+        os.remove(path)
+
+    def test_dont_move_dir_in_itself(self):
+        src_dir = tempfile.mkdtemp()
+        try:
+            dst = os.path.join(src_dir, 'foo')
+            self.assertRaises(shutil.Error, shutil.move, src_dir, dst)
+        finally:
+            try:
+                os.rmdir(src_dir)
+            except:
+                pass
+
+    def test_copytree_simple(self):
+        def write_data(path, data):
+            f = open(path, "w")
+            f.write(data)
+            f.close()
+
+        def read_data(path):
+            f = open(path)
+            data = f.read()
+            f.close()
+            return data
+
+        src_dir = tempfile.mkdtemp()
+        dst_dir = os.path.join(tempfile.mkdtemp(), 'destination')
+
+        write_data(os.path.join(src_dir, 'test.txt'), '123')
+
+        os.mkdir(os.path.join(src_dir, 'test_dir'))
+        write_data(os.path.join(src_dir, 'test_dir', 'test.txt'), '456')
+
+        try:
+            shutil.copytree(src_dir, dst_dir)
+            self.assertTrue(os.path.isfile(os.path.join(dst_dir, 'test.txt')))
+            self.assertTrue(os.path.isdir(os.path.join(dst_dir, 'test_dir')))
+            self.assertTrue(os.path.isfile(os.path.join(dst_dir, 'test_dir',
+                                                        'test.txt')))
+            actual = read_data(os.path.join(dst_dir, 'test.txt'))
+            self.assertEqual(actual, '123')
+            actual = read_data(os.path.join(dst_dir, 'test_dir', 'test.txt'))
+            self.assertEqual(actual, '456')
+        finally:
+            for path in (
+                    os.path.join(src_dir, 'test.txt'),
+                    os.path.join(dst_dir, 'test.txt'),
+                    os.path.join(src_dir, 'test_dir', 'test.txt'),
+                    os.path.join(dst_dir, 'test_dir', 'test.txt'),
+                ):
+                if os.path.exists(path):
+                    os.remove(path)
+            for path in (
+                    os.path.join(src_dir, 'test_dir'),
+                    os.path.join(dst_dir, 'test_dir'),
+                ):
+                if os.path.exists(path):
+                    os.removedirs(path)
+
+
+    if hasattr(os, "symlink"):
+        def test_dont_copy_file_onto_link_to_itself(self):
+            # bug 851123.
+            os.mkdir(TESTFN)
+            src = os.path.join(TESTFN, 'cheese')
+            dst = os.path.join(TESTFN, 'shop')
+            try:
+                f = open(src, 'w')
+                f.write('cheddar')
+                f.close()
+
+                os.link(src, dst)
+                self.assertRaises(shutil.Error, shutil.copyfile, src, dst)
+                self.assertEqual(open(src,'r').read(), 'cheddar')
+                os.remove(dst)
+
+                # Using `src` here would mean we end up with a symlink pointing
+                # to TESTFN/TESTFN/cheese, while it should point at
+                # TESTFN/cheese.
+                os.symlink('cheese', dst)
+                self.assertRaises(shutil.Error, shutil.copyfile, src, dst)
+                self.assertEqual(open(src,'r').read(), 'cheddar')
+                os.remove(dst)
+            finally:
+                try:
+                    shutil.rmtree(TESTFN)
+                except OSError:
+                    pass
+
+def test_main():
+    test_support.run_unittest(TestShutil)
+
+if __name__ == '__main__':
+    test_main()

Added: vendor/Python/current/Lib/test/test_signal.py
===================================================================
--- vendor/Python/current/Lib/test/test_signal.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_signal.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,167 @@
+# Test the signal module
+from test.test_support import verbose, TestSkipped, TestFailed, vereq
+import signal
+import os, sys, time
+
+if sys.platform[:3] in ('win', 'os2') or sys.platform=='riscos':
+    raise TestSkipped, "Can't test signal on %s" % sys.platform
+
+MAX_DURATION = 20   # Entire test should last at most 20 sec.
+
+if verbose:
+    x = '-x'
+else:
+    x = '+x'
+
+pid = os.getpid()
+if verbose:
+    print "test runner's pid is", pid
+
+# Shell script that will send us asynchronous signals
+script = """
+ (
+        set %(x)s
+        sleep 2
+        kill -HUP %(pid)d
+        sleep 2
+        kill -USR1 %(pid)d
+        sleep 2
+        kill -USR2 %(pid)d
+ ) &
+""" % vars()
+
+a_called = b_called = False
+
+def handlerA(*args):
+    global a_called
+    a_called = True
+    if verbose:
+        print "handlerA invoked", args
+
+class HandlerBCalled(Exception):
+    pass
+
+def handlerB(*args):
+    global b_called
+    b_called = True
+    if verbose:
+        print "handlerB invoked", args
+    raise HandlerBCalled, args
+
+# Set up a child to send signals to us (the parent) after waiting long
+# enough to receive the alarm.  It seems we miss the alarm for some
+# reason.  This will hopefully stop the hangs on Tru64/Alpha.
+# Alas, it doesn't.  Tru64 appears to miss all the signals at times, or
+# seemingly random subsets of them, and nothing done in force_test_exit
+# so far has actually helped.
+def force_test_exit():
+    # Sigh, both imports seem necessary to avoid errors.
+    import os
+    fork_pid = os.fork()
+    if fork_pid:
+        # In parent.
+        return fork_pid
+
+    # In child.
+    import os, time
+    try:
+        # Wait 5 seconds longer than the expected alarm to give enough
+        # time for the normal sequence of events to occur.  This is
+        # just a stop-gap to try to prevent the test from hanging.
+        time.sleep(MAX_DURATION + 5)
+        print >> sys.__stdout__, '  child should not have to kill parent'
+        for signame in "SIGHUP", "SIGUSR1", "SIGUSR2", "SIGALRM":
+            os.kill(pid, getattr(signal, signame))
+            print >> sys.__stdout__, "    child sent", signame, "to", pid
+            time.sleep(1)
+    finally:
+        os._exit(0)
+
+# Install handlers.
+hup = signal.signal(signal.SIGHUP, handlerA)
+usr1 = signal.signal(signal.SIGUSR1, handlerB)
+usr2 = signal.signal(signal.SIGUSR2, signal.SIG_IGN)
+alrm = signal.signal(signal.SIGALRM, signal.default_int_handler)
+
+try:
+
+    signal.alarm(MAX_DURATION)
+    vereq(signal.getsignal(signal.SIGHUP), handlerA)
+    vereq(signal.getsignal(signal.SIGUSR1), handlerB)
+    vereq(signal.getsignal(signal.SIGUSR2), signal.SIG_IGN)
+    vereq(signal.getsignal(signal.SIGALRM), signal.default_int_handler)
+
+    # Try to ensure this test exits even if there is some problem with alarm.
+    # Tru64/Alpha often hangs and is ultimately killed by the buildbot.
+    fork_pid = force_test_exit()
+
+    try:
+        signal.getsignal(4242)
+        raise TestFailed('expected ValueError for invalid signal # to '
+                         'getsignal()')
+    except ValueError:
+        pass
+
+    try:
+        signal.signal(4242, handlerB)
+        raise TestFailed('expected ValueError for invalid signal # to '
+                         'signal()')
+    except ValueError:
+        pass
+
+    try:
+        signal.signal(signal.SIGUSR1, None)
+        raise TestFailed('expected TypeError for non-callable')
+    except TypeError:
+        pass
+
+    # Launch an external script to send us signals.
+    # We expect the external script to:
+    #    send HUP, which invokes handlerA to set a_called
+    #    send USR1, which invokes handlerB to set b_called and raise
+    #               HandlerBCalled
+    #    send USR2, which is ignored
+    #
+    # Then we expect the alarm to go off, and its handler raises
+    # KeyboardInterrupt, finally getting us out of the loop.
+    os.system(script)
+    try:
+        print "starting pause() loop..."
+        while 1:
+            try:
+                if verbose:
+                    print "call pause()..."
+                signal.pause()
+                if verbose:
+                    print "pause() returned"
+            except HandlerBCalled:
+                if verbose:
+                    print "HandlerBCalled exception caught"
+
+    except KeyboardInterrupt:
+        if verbose:
+            print "KeyboardInterrupt (the alarm() went off)"
+
+    if not a_called:
+        print 'HandlerA not called'
+
+    if not b_called:
+        print 'HandlerB not called'
+
+finally:
+    # Forcibly kill the child we created to ping us if there was a test error.
+    try:
+        # Make sure we don't kill ourself if there was a fork error.
+        if fork_pid > 0:
+            os.kill(fork_pid, signal.SIGKILL)
+    except:
+        # If the child killed us, it has probably exited.  Killing a
+        # non-existent process will raise an error which we don't care about.
+        pass
+
+    # Restore handlers.
+    signal.alarm(0) # cancel alarm in case we died early
+    signal.signal(signal.SIGHUP, hup)
+    signal.signal(signal.SIGUSR1, usr1)
+    signal.signal(signal.SIGUSR2, usr2)
+    signal.signal(signal.SIGALRM, alrm)

Added: vendor/Python/current/Lib/test/test_site.py
===================================================================
--- vendor/Python/current/Lib/test/test_site.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_site.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,236 @@
+"""Tests for 'site'.
+
+Tests assume the initial paths in sys.path once the interpreter has begun
+executing have not been removed.
+
+"""
+import unittest
+from test.test_support import TestSkipped, TestFailed, run_unittest, TESTFN
+import __builtin__
+import os
+import sys
+import encodings
+import tempfile
+# Need to make sure to not import 'site' if someone specified ``-S`` at the
+# command-line.  Detect this by just making sure 'site' has not been imported
+# already.
+if "site" in sys.modules:
+    import site
+else:
+    raise TestSkipped("importation of site.py suppressed")
+
+class HelperFunctionsTests(unittest.TestCase):
+    """Tests for helper functions.
+
+    The setting of the encoding (set using sys.setdefaultencoding) used by
+    the Unicode implementation is not tested.
+
+    """
+
+    def setUp(self):
+        """Save a copy of sys.path"""
+        self.sys_path = sys.path[:]
+
+    def tearDown(self):
+        """Restore sys.path"""
+        sys.path = self.sys_path
+
+    def test_makepath(self):
+        # Test makepath() have an absolute path for its first return value
+        # and a case-normalized version of the absolute path for its
+        # second value.
+        path_parts = ("Beginning", "End")
+        original_dir = os.path.join(*path_parts)
+        abs_dir, norm_dir = site.makepath(*path_parts)
+        self.failUnlessEqual(os.path.abspath(original_dir), abs_dir)
+        if original_dir == os.path.normcase(original_dir):
+            self.failUnlessEqual(abs_dir, norm_dir)
+        else:
+            self.failUnlessEqual(os.path.normcase(abs_dir), norm_dir)
+
+    def test_init_pathinfo(self):
+        dir_set = site._init_pathinfo()
+        for entry in [site.makepath(path)[1] for path in sys.path
+                        if path and os.path.isdir(path)]:
+            self.failUnless(entry in dir_set,
+                            "%s from sys.path not found in set returned "
+                            "by _init_pathinfo(): %s" % (entry, dir_set))
+
+    def pth_file_tests(self, pth_file):
+        """Contain common code for testing results of reading a .pth file"""
+        self.failUnless(pth_file.imported in sys.modules,
+                "%s not in sys.path" % pth_file.imported)
+        self.failUnless(site.makepath(pth_file.good_dir_path)[0] in sys.path)
+        self.failUnless(not os.path.exists(pth_file.bad_dir_path))
+
+    def test_addpackage(self):
+        # Make sure addpackage() imports if the line starts with 'import',
+        # adds directories to sys.path for any line in the file that is not a
+        # comment or import that is a valid directory name for where the .pth
+        # file resides; invalid directories are not added
+        pth_file = PthFile()
+        pth_file.cleanup(prep=True)  # to make sure that nothing is
+                                      # pre-existing that shouldn't be
+        try:
+            pth_file.create()
+            site.addpackage(pth_file.base_dir, pth_file.filename, set())
+            self.pth_file_tests(pth_file)
+        finally:
+            pth_file.cleanup()
+
+    def test_addsitedir(self):
+        # Same tests for test_addpackage since addsitedir() essentially just
+        # calls addpackage() for every .pth file in the directory
+        pth_file = PthFile()
+        pth_file.cleanup(prep=True) # Make sure that nothing is pre-existing
+                                    # that is tested for
+        try:
+            pth_file.create()
+            site.addsitedir(pth_file.base_dir, set())
+            self.pth_file_tests(pth_file)
+        finally:
+            pth_file.cleanup()
+
+class PthFile(object):
+    """Helper class for handling testing of .pth files"""
+
+    def __init__(self, filename_base=TESTFN, imported="time",
+                    good_dirname="__testdir__", bad_dirname="__bad"):
+        """Initialize instance variables"""
+        self.filename = filename_base + ".pth"
+        self.base_dir = os.path.abspath('')
+        self.file_path = os.path.join(self.base_dir, self.filename)
+        self.imported = imported
+        self.good_dirname = good_dirname
+        self.bad_dirname = bad_dirname
+        self.good_dir_path = os.path.join(self.base_dir, self.good_dirname)
+        self.bad_dir_path = os.path.join(self.base_dir, self.bad_dirname)
+
+    def create(self):
+        """Create a .pth file with a comment, blank lines, an ``import
+        <self.imported>``, a line with self.good_dirname, and a line with
+        self.bad_dirname.
+
+        Creation of the directory for self.good_dir_path (based off of
+        self.good_dirname) is also performed.
+
+        Make sure to call self.cleanup() to undo anything done by this method.
+
+        """
+        FILE = open(self.file_path, 'w')
+        try:
+            print>>FILE, "#import @bad module name"
+            print>>FILE, "\n"
+            print>>FILE, "import %s" % self.imported
+            print>>FILE, self.good_dirname
+            print>>FILE, self.bad_dirname
+        finally:
+            FILE.close()
+        os.mkdir(self.good_dir_path)
+
+    def cleanup(self, prep=False):
+        """Make sure that the .pth file is deleted, self.imported is not in
+        sys.modules, and that both self.good_dirname and self.bad_dirname are
+        not existing directories."""
+        if os.path.exists(self.file_path):
+            os.remove(self.file_path)
+        if prep:
+            self.imported_module = sys.modules.get(self.imported)
+            if self.imported_module:
+                del sys.modules[self.imported]
+        else:
+            if self.imported_module:
+                sys.modules[self.imported] = self.imported_module
+        if os.path.exists(self.good_dir_path):
+            os.rmdir(self.good_dir_path)
+        if os.path.exists(self.bad_dir_path):
+            os.rmdir(self.bad_dir_path)
+
+class ImportSideEffectTests(unittest.TestCase):
+    """Test side-effects from importing 'site'."""
+
+    def setUp(self):
+        """Make a copy of sys.path"""
+        self.sys_path = sys.path[:]
+
+    def tearDown(self):
+        """Restore sys.path"""
+        sys.path = self.sys_path
+
+    def test_abs__file__(self):
+        # Make sure all imported modules have their __file__ attribute
+        # as an absolute path.
+        # Handled by abs__file__()
+        site.abs__file__()
+        for module in (sys, os, __builtin__):
+            try:
+                self.failUnless(os.path.isabs(module.__file__), `module`)
+            except AttributeError:
+                continue
+        # We could try everything in sys.modules; however, when regrtest.py
+        # runs something like test_frozen before test_site, then we will
+        # be testing things loaded *after* test_site did path normalization
+
+    def test_no_duplicate_paths(self):
+        # No duplicate paths should exist in sys.path
+        # Handled by removeduppaths()
+        site.removeduppaths()
+        seen_paths = set()
+        for path in sys.path:
+            self.failUnless(path not in seen_paths)
+            seen_paths.add(path)
+
+    def test_add_build_dir(self):
+        # Test that the build directory's Modules directory is used when it
+        # should be.
+        # XXX: implement
+        pass
+
+    def test_setting_quit(self):
+        # 'quit' and 'exit' should be injected into __builtin__
+        self.failUnless(hasattr(__builtin__, "quit"))
+        self.failUnless(hasattr(__builtin__, "exit"))
+
+    def test_setting_copyright(self):
+        # 'copyright' and 'credits' should be in __builtin__
+        self.failUnless(hasattr(__builtin__, "copyright"))
+        self.failUnless(hasattr(__builtin__, "credits"))
+
+    def test_setting_help(self):
+        # 'help' should be set in __builtin__
+        self.failUnless(hasattr(__builtin__, "help"))
+
+    def test_aliasing_mbcs(self):
+        if sys.platform == "win32":
+            import locale
+            if locale.getdefaultlocale()[1].startswith('cp'):
+                for value in encodings.aliases.aliases.itervalues():
+                    if value == "mbcs":
+                        break
+                else:
+                    self.fail("did not alias mbcs")
+
+    def test_setdefaultencoding_removed(self):
+        # Make sure sys.setdefaultencoding is gone
+        self.failUnless(not hasattr(sys, "setdefaultencoding"))
+
+    def test_sitecustomize_executed(self):
+        # If sitecustomize is available, it should have been imported.
+        if not sys.modules.has_key("sitecustomize"):
+            try:
+                import sitecustomize
+            except ImportError:
+                pass
+            else:
+                self.fail("sitecustomize not imported automatically")
+
+
+
+
+def test_main():
+    run_unittest(HelperFunctionsTests, ImportSideEffectTests)
+
+
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_slice.py
===================================================================
--- vendor/Python/current/Lib/test/test_slice.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_slice.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,110 @@
+# tests for slice objects; in particular the indices method.
+
+import unittest
+from test import test_support
+
+import sys
+
+class SliceTest(unittest.TestCase):
+
+    def test_constructor(self):
+        self.assertRaises(TypeError, slice)
+        self.assertRaises(TypeError, slice, 1, 2, 3, 4)
+
+    def test_repr(self):
+        self.assertEqual(repr(slice(1, 2, 3)), "slice(1, 2, 3)")
+
+    def test_hash(self):
+        # Verify clearing of SF bug #800796
+        self.assertRaises(TypeError, hash, slice(5))
+        self.assertRaises(TypeError, slice(5).__hash__)
+
+    def test_cmp(self):
+        s1 = slice(1, 2, 3)
+        s2 = slice(1, 2, 3)
+        s3 = slice(1, 2, 4)
+        self.assertEqual(s1, s2)
+        self.assertNotEqual(s1, s3)
+
+        class Exc(Exception):
+            pass
+
+        class BadCmp(object):
+            def __eq__(self, other):
+                raise Exc
+
+        s1 = slice(BadCmp())
+        s2 = slice(BadCmp())
+        self.assertRaises(Exc, cmp, s1, s2)
+        self.assertEqual(s1, s1)
+
+        s1 = slice(1, BadCmp())
+        s2 = slice(1, BadCmp())
+        self.assertEqual(s1, s1)
+        self.assertRaises(Exc, cmp, s1, s2)
+
+        s1 = slice(1, 2, BadCmp())
+        s2 = slice(1, 2, BadCmp())
+        self.assertEqual(s1, s1)
+        self.assertRaises(Exc, cmp, s1, s2)
+
+    def test_members(self):
+        s = slice(1)
+        self.assertEqual(s.start, None)
+        self.assertEqual(s.stop, 1)
+        self.assertEqual(s.step, None)
+
+        s = slice(1, 2)
+        self.assertEqual(s.start, 1)
+        self.assertEqual(s.stop, 2)
+        self.assertEqual(s.step, None)
+
+        s = slice(1, 2, 3)
+        self.assertEqual(s.start, 1)
+        self.assertEqual(s.stop, 2)
+        self.assertEqual(s.step, 3)
+
+        class AnyClass:
+            pass
+
+        obj = AnyClass()
+        s = slice(obj)
+        self.assert_(s.stop is obj)
+
+    def test_indices(self):
+        self.assertEqual(slice(None           ).indices(10), (0, 10,  1))
+        self.assertEqual(slice(None,  None,  2).indices(10), (0, 10,  2))
+        self.assertEqual(slice(1,     None,  2).indices(10), (1, 10,  2))
+        self.assertEqual(slice(None,  None, -1).indices(10), (9, -1, -1))
+        self.assertEqual(slice(None,  None, -2).indices(10), (9, -1, -2))
+        self.assertEqual(slice(3,     None, -2).indices(10), (3, -1, -2))
+        self.assertEqual(
+            slice(-100,  100     ).indices(10),
+            slice(None).indices(10)
+        )
+        self.assertEqual(
+            slice(100,  -100,  -1).indices(10),
+            slice(None, None, -1).indices(10)
+        )
+        self.assertEqual(slice(-100L, 100L, 2L).indices(10), (0, 10,  2))
+
+        self.assertEqual(range(10)[::sys.maxint - 1], [0])
+
+        self.assertRaises(OverflowError, slice(None).indices, 1L<<100)
+
+    def test_setslice_without_getslice(self):
+        tmp = []
+        class X(object):
+            def __setslice__(self, i, j, k):
+                tmp.append((i, j, k))
+
+        x = X()
+        x[1:2] = 42
+        self.assertEquals(tmp, [(1, 2, 42)])
+
+
+def test_main():
+    test_support.run_unittest(SliceTest)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_socket.py
===================================================================
--- vendor/Python/current/Lib/test/test_socket.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_socket.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,995 @@
+#!/usr/bin/env python
+
+import unittest
+from test import test_support
+
+import socket
+import select
+import time
+import thread, threading
+import Queue
+import sys
+import array
+from weakref import proxy
+import signal
+
+PORT = 50007
+HOST = 'localhost'
+MSG = 'Michael Gilfix was here\n'
+
+class SocketTCPTest(unittest.TestCase):
+
+    def setUp(self):
+        self.serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        self.serv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+        global PORT
+        PORT = test_support.bind_port(self.serv, HOST, PORT)
+        self.serv.listen(1)
+
+    def tearDown(self):
+        self.serv.close()
+        self.serv = None
+
+class SocketUDPTest(unittest.TestCase):
+
+    def setUp(self):
+        self.serv = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+        self.serv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+        global PORT
+        PORT = test_support.bind_port(self.serv, HOST, PORT)
+
+    def tearDown(self):
+        self.serv.close()
+        self.serv = None
+
+class ThreadableTest:
+    """Threadable Test class
+
+    The ThreadableTest class makes it easy to create a threaded
+    client/server pair from an existing unit test. To create a
+    new threaded class from an existing unit test, use multiple
+    inheritance:
+
+        class NewClass (OldClass, ThreadableTest):
+            pass
+
+    This class defines two new fixture functions with obvious
+    purposes for overriding:
+
+        clientSetUp ()
+        clientTearDown ()
+
+    Any new test functions within the class must then define
+    tests in pairs, where the test name is preceeded with a
+    '_' to indicate the client portion of the test. Ex:
+
+        def testFoo(self):
+            # Server portion
+
+        def _testFoo(self):
+            # Client portion
+
+    Any exceptions raised by the clients during their tests
+    are caught and transferred to the main thread to alert
+    the testing framework.
+
+    Note, the server setup function cannot call any blocking
+    functions that rely on the client thread during setup,
+    unless serverExplicityReady() is called just before
+    the blocking call (such as in setting up a client/server
+    connection and performing the accept() in setUp().
+    """
+
+    def __init__(self):
+        # Swap the true setup function
+        self.__setUp = self.setUp
+        self.__tearDown = self.tearDown
+        self.setUp = self._setUp
+        self.tearDown = self._tearDown
+
+    def serverExplicitReady(self):
+        """This method allows the server to explicitly indicate that
+        it wants the client thread to proceed. This is useful if the
+        server is about to execute a blocking routine that is
+        dependent upon the client thread during its setup routine."""
+        self.server_ready.set()
+
+    def _setUp(self):
+        self.server_ready = threading.Event()
+        self.client_ready = threading.Event()
+        self.done = threading.Event()
+        self.queue = Queue.Queue(1)
+
+        # Do some munging to start the client test.
+        methodname = self.id()
+        i = methodname.rfind('.')
+        methodname = methodname[i+1:]
+        test_method = getattr(self, '_' + methodname)
+        self.client_thread = thread.start_new_thread(
+            self.clientRun, (test_method,))
+
+        self.__setUp()
+        if not self.server_ready.isSet():
+            self.server_ready.set()
+        self.client_ready.wait()
+
+    def _tearDown(self):
+        self.__tearDown()
+        self.done.wait()
+
+        if not self.queue.empty():
+            msg = self.queue.get()
+            self.fail(msg)
+
+    def clientRun(self, test_func):
+        self.server_ready.wait()
+        self.client_ready.set()
+        self.clientSetUp()
+        if not callable(test_func):
+            raise TypeError, "test_func must be a callable function"
+        try:
+            test_func()
+        except Exception, strerror:
+            self.queue.put(strerror)
+        self.clientTearDown()
+
+    def clientSetUp(self):
+        raise NotImplementedError, "clientSetUp must be implemented."
+
+    def clientTearDown(self):
+        self.done.set()
+        thread.exit()
+
+class ThreadedTCPSocketTest(SocketTCPTest, ThreadableTest):
+
+    def __init__(self, methodName='runTest'):
+        SocketTCPTest.__init__(self, methodName=methodName)
+        ThreadableTest.__init__(self)
+
+    def clientSetUp(self):
+        self.cli = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+
+    def clientTearDown(self):
+        self.cli.close()
+        self.cli = None
+        ThreadableTest.clientTearDown(self)
+
+class ThreadedUDPSocketTest(SocketUDPTest, ThreadableTest):
+
+    def __init__(self, methodName='runTest'):
+        SocketUDPTest.__init__(self, methodName=methodName)
+        ThreadableTest.__init__(self)
+
+    def clientSetUp(self):
+        self.cli = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+
+class SocketConnectedTest(ThreadedTCPSocketTest):
+
+    def __init__(self, methodName='runTest'):
+        ThreadedTCPSocketTest.__init__(self, methodName=methodName)
+
+    def setUp(self):
+        ThreadedTCPSocketTest.setUp(self)
+        # Indicate explicitly we're ready for the client thread to
+        # proceed and then perform the blocking call to accept
+        self.serverExplicitReady()
+        conn, addr = self.serv.accept()
+        self.cli_conn = conn
+
+    def tearDown(self):
+        self.cli_conn.close()
+        self.cli_conn = None
+        ThreadedTCPSocketTest.tearDown(self)
+
+    def clientSetUp(self):
+        ThreadedTCPSocketTest.clientSetUp(self)
+        self.cli.connect((HOST, PORT))
+        self.serv_conn = self.cli
+
+    def clientTearDown(self):
+        self.serv_conn.close()
+        self.serv_conn = None
+        ThreadedTCPSocketTest.clientTearDown(self)
+
+class SocketPairTest(unittest.TestCase, ThreadableTest):
+
+    def __init__(self, methodName='runTest'):
+        unittest.TestCase.__init__(self, methodName=methodName)
+        ThreadableTest.__init__(self)
+
+    def setUp(self):
+        self.serv, self.cli = socket.socketpair()
+
+    def tearDown(self):
+        self.serv.close()
+        self.serv = None
+
+    def clientSetUp(self):
+        pass
+
+    def clientTearDown(self):
+        self.cli.close()
+        self.cli = None
+        ThreadableTest.clientTearDown(self)
+
+
+#######################################################################
+## Begin Tests
+
+class GeneralModuleTests(unittest.TestCase):
+
+    def test_weakref(self):
+        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        p = proxy(s)
+        self.assertEqual(p.fileno(), s.fileno())
+        s.close()
+        s = None
+        try:
+            p.fileno()
+        except ReferenceError:
+            pass
+        else:
+            self.fail('Socket proxy still exists')
+
+    def testSocketError(self):
+        # Testing socket module exceptions
+        def raise_error(*args, **kwargs):
+            raise socket.error
+        def raise_herror(*args, **kwargs):
+            raise socket.herror
+        def raise_gaierror(*args, **kwargs):
+            raise socket.gaierror
+        self.failUnlessRaises(socket.error, raise_error,
+                              "Error raising socket exception.")
+        self.failUnlessRaises(socket.error, raise_herror,
+                              "Error raising socket exception.")
+        self.failUnlessRaises(socket.error, raise_gaierror,
+                              "Error raising socket exception.")
+
+    def testCrucialConstants(self):
+        # Testing for mission critical constants
+        socket.AF_INET
+        socket.SOCK_STREAM
+        socket.SOCK_DGRAM
+        socket.SOCK_RAW
+        socket.SOCK_RDM
+        socket.SOCK_SEQPACKET
+        socket.SOL_SOCKET
+        socket.SO_REUSEADDR
+
+    def testHostnameRes(self):
+        # Testing hostname resolution mechanisms
+        hostname = socket.gethostname()
+        try:
+            ip = socket.gethostbyname(hostname)
+        except socket.error:
+            # Probably name lookup wasn't set up right; skip this test
+            return
+        self.assert_(ip.find('.') >= 0, "Error resolving host to ip.")
+        try:
+            hname, aliases, ipaddrs = socket.gethostbyaddr(ip)
+        except socket.error:
+            # Probably a similar problem as above; skip this test
+            return
+        all_host_names = [hostname, hname] + aliases
+        fqhn = socket.getfqdn(ip)
+        if not fqhn in all_host_names:
+            self.fail("Error testing host resolution mechanisms. (fqdn: %s, all: %s)" % (fqhn, repr(all_host_names)))
+
+    def testRefCountGetNameInfo(self):
+        # Testing reference count for getnameinfo
+        import sys
+        if hasattr(sys, "getrefcount"):
+            try:
+                # On some versions, this loses a reference
+                orig = sys.getrefcount(__name__)
+                socket.getnameinfo(__name__,0)
+            except SystemError:
+                if sys.getrefcount(__name__) <> orig:
+                    self.fail("socket.getnameinfo loses a reference")
+
+    def testInterpreterCrash(self):
+        # Making sure getnameinfo doesn't crash the interpreter
+        try:
+            # On some versions, this crashes the interpreter.
+            socket.getnameinfo(('x', 0, 0, 0), 0)
+        except socket.error:
+            pass
+
+    def testNtoH(self):
+        # This just checks that htons etc. are their own inverse,
+        # when looking at the lower 16 or 32 bits.
+        sizes = {socket.htonl: 32, socket.ntohl: 32,
+                 socket.htons: 16, socket.ntohs: 16}
+        for func, size in sizes.items():
+            mask = (1L<<size) - 1
+            for i in (0, 1, 0xffff, ~0xffff, 2, 0x01234567, 0x76543210):
+                self.assertEqual(i & mask, func(func(i&mask)) & mask)
+
+            swapped = func(mask)
+            self.assertEqual(swapped & mask, mask)
+            self.assertRaises(OverflowError, func, 1L<<34)
+
+    def testGetServBy(self):
+        eq = self.assertEqual
+        # Find one service that exists, then check all the related interfaces.
+        # I've ordered this by protocols that have both a tcp and udp
+        # protocol, at least for modern Linuxes.
+        if sys.platform in ('linux2', 'freebsd4', 'freebsd5', 'freebsd6',
+                            'freebsd7', 'darwin'):
+            # avoid the 'echo' service on this platform, as there is an
+            # assumption breaking non-standard port/protocol entry
+            services = ('daytime', 'qotd', 'domain')
+        else:
+            services = ('echo', 'daytime', 'domain')
+        for service in services:
+            try:
+                port = socket.getservbyname(service, 'tcp')
+                break
+            except socket.error:
+                pass
+        else:
+            raise socket.error
+        # Try same call with optional protocol omitted
+        port2 = socket.getservbyname(service)
+        eq(port, port2)
+        # Try udp, but don't barf it it doesn't exist
+        try:
+            udpport = socket.getservbyname(service, 'udp')
+        except socket.error:
+            udpport = None
+        else:
+            eq(udpport, port)
+        # Now make sure the lookup by port returns the same service name
+        eq(socket.getservbyport(port2), service)
+        eq(socket.getservbyport(port, 'tcp'), service)
+        if udpport is not None:
+            eq(socket.getservbyport(udpport, 'udp'), service)
+
+    def testDefaultTimeout(self):
+        # Testing default timeout
+        # The default timeout should initially be None
+        self.assertEqual(socket.getdefaulttimeout(), None)
+        s = socket.socket()
+        self.assertEqual(s.gettimeout(), None)
+        s.close()
+
+        # Set the default timeout to 10, and see if it propagates
+        socket.setdefaulttimeout(10)
+        self.assertEqual(socket.getdefaulttimeout(), 10)
+        s = socket.socket()
+        self.assertEqual(s.gettimeout(), 10)
+        s.close()
+
+        # Reset the default timeout to None, and see if it propagates
+        socket.setdefaulttimeout(None)
+        self.assertEqual(socket.getdefaulttimeout(), None)
+        s = socket.socket()
+        self.assertEqual(s.gettimeout(), None)
+        s.close()
+
+        # Check that setting it to an invalid value raises ValueError
+        self.assertRaises(ValueError, socket.setdefaulttimeout, -1)
+
+        # Check that setting it to an invalid type raises TypeError
+        self.assertRaises(TypeError, socket.setdefaulttimeout, "spam")
+
+    def testIPv4toString(self):
+        if not hasattr(socket, 'inet_pton'):
+            return # No inet_pton() on this platform
+        from socket import inet_aton as f, inet_pton, AF_INET
+        g = lambda a: inet_pton(AF_INET, a)
+
+        self.assertEquals('\x00\x00\x00\x00', f('0.0.0.0'))
+        self.assertEquals('\xff\x00\xff\x00', f('255.0.255.0'))
+        self.assertEquals('\xaa\xaa\xaa\xaa', f('170.170.170.170'))
+        self.assertEquals('\x01\x02\x03\x04', f('1.2.3.4'))
+        self.assertEquals('\xff\xff\xff\xff', f('255.255.255.255'))
+
+        self.assertEquals('\x00\x00\x00\x00', g('0.0.0.0'))
+        self.assertEquals('\xff\x00\xff\x00', g('255.0.255.0'))
+        self.assertEquals('\xaa\xaa\xaa\xaa', g('170.170.170.170'))
+        self.assertEquals('\xff\xff\xff\xff', g('255.255.255.255'))
+
+    def testIPv6toString(self):
+        if not hasattr(socket, 'inet_pton'):
+            return # No inet_pton() on this platform
+        try:
+            from socket import inet_pton, AF_INET6, has_ipv6
+            if not has_ipv6:
+                return
+        except ImportError:
+            return
+        f = lambda a: inet_pton(AF_INET6, a)
+
+        self.assertEquals('\x00' * 16, f('::'))
+        self.assertEquals('\x00' * 16, f('0::0'))
+        self.assertEquals('\x00\x01' + '\x00' * 14, f('1::'))
+        self.assertEquals(
+            '\x45\xef\x76\xcb\x00\x1a\x56\xef\xaf\xeb\x0b\xac\x19\x24\xae\xae',
+            f('45ef:76cb:1a:56ef:afeb:bac:1924:aeae')
+        )
+
+    def testStringToIPv4(self):
+        if not hasattr(socket, 'inet_ntop'):
+            return # No inet_ntop() on this platform
+        from socket import inet_ntoa as f, inet_ntop, AF_INET
+        g = lambda a: inet_ntop(AF_INET, a)
+
+        self.assertEquals('1.0.1.0', f('\x01\x00\x01\x00'))
+        self.assertEquals('170.85.170.85', f('\xaa\x55\xaa\x55'))
+        self.assertEquals('255.255.255.255', f('\xff\xff\xff\xff'))
+        self.assertEquals('1.2.3.4', f('\x01\x02\x03\x04'))
+
+        self.assertEquals('1.0.1.0', g('\x01\x00\x01\x00'))
+        self.assertEquals('170.85.170.85', g('\xaa\x55\xaa\x55'))
+        self.assertEquals('255.255.255.255', g('\xff\xff\xff\xff'))
+
+    def testStringToIPv6(self):
+        if not hasattr(socket, 'inet_ntop'):
+            return # No inet_ntop() on this platform
+        try:
+            from socket import inet_ntop, AF_INET6, has_ipv6
+            if not has_ipv6:
+                return
+        except ImportError:
+            return
+        f = lambda a: inet_ntop(AF_INET6, a)
+
+        self.assertEquals('::', f('\x00' * 16))
+        self.assertEquals('::1', f('\x00' * 15 + '\x01'))
+        self.assertEquals(
+            'aef:b01:506:1001:ffff:9997:55:170',
+            f('\x0a\xef\x0b\x01\x05\x06\x10\x01\xff\xff\x99\x97\x00\x55\x01\x70')
+        )
+
+    # XXX The following don't test module-level functionality...
+
+    def testSockName(self):
+        # Testing getsockname()
+        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        sock.bind(("0.0.0.0", PORT+1))
+        name = sock.getsockname()
+        # XXX(nnorwitz): http://tinyurl.com/os5jz seems to indicate
+        # it reasonable to get the host's addr in addition to 0.0.0.0.
+        # At least for eCos.  This is required for the S/390 to pass.
+        my_ip_addr = socket.gethostbyname(socket.gethostname())
+        self.assert_(name[0] in ("0.0.0.0", my_ip_addr), '%s invalid' % name[0])
+        self.assertEqual(name[1], PORT+1)
+
+    def testGetSockOpt(self):
+        # Testing getsockopt()
+        # We know a socket should start without reuse==0
+        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        reuse = sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR)
+        self.failIf(reuse != 0, "initial mode is reuse")
+
+    def testSetSockOpt(self):
+        # Testing setsockopt()
+        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+        reuse = sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR)
+        self.failIf(reuse == 0, "failed to set reuse mode")
+
+    def testSendAfterClose(self):
+        # testing send() after close() with timeout
+        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        sock.settimeout(1)
+        sock.close()
+        self.assertRaises(socket.error, sock.send, "spam")
+
+    def testNewAttributes(self):
+        # testing .family, .type and .protocol
+        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        self.assertEqual(sock.family, socket.AF_INET)
+        self.assertEqual(sock.type, socket.SOCK_STREAM)
+        self.assertEqual(sock.proto, 0)
+        sock.close()
+
+class BasicTCPTest(SocketConnectedTest):
+
+    def __init__(self, methodName='runTest'):
+        SocketConnectedTest.__init__(self, methodName=methodName)
+
+    def testRecv(self):
+        # Testing large receive over TCP
+        msg = self.cli_conn.recv(1024)
+        self.assertEqual(msg, MSG)
+
+    def _testRecv(self):
+        self.serv_conn.send(MSG)
+
+    def testOverFlowRecv(self):
+        # Testing receive in chunks over TCP
+        seg1 = self.cli_conn.recv(len(MSG) - 3)
+        seg2 = self.cli_conn.recv(1024)
+        msg = seg1 + seg2
+        self.assertEqual(msg, MSG)
+
+    def _testOverFlowRecv(self):
+        self.serv_conn.send(MSG)
+
+    def testRecvFrom(self):
+        # Testing large recvfrom() over TCP
+        msg, addr = self.cli_conn.recvfrom(1024)
+        self.assertEqual(msg, MSG)
+
+    def _testRecvFrom(self):
+        self.serv_conn.send(MSG)
+
+    def testOverFlowRecvFrom(self):
+        # Testing recvfrom() in chunks over TCP
+        seg1, addr = self.cli_conn.recvfrom(len(MSG)-3)
+        seg2, addr = self.cli_conn.recvfrom(1024)
+        msg = seg1 + seg2
+        self.assertEqual(msg, MSG)
+
+    def _testOverFlowRecvFrom(self):
+        self.serv_conn.send(MSG)
+
+    def testSendAll(self):
+        # Testing sendall() with a 2048 byte string over TCP
+        msg = ''
+        while 1:
+            read = self.cli_conn.recv(1024)
+            if not read:
+                break
+            msg += read
+        self.assertEqual(msg, 'f' * 2048)
+
+    def _testSendAll(self):
+        big_chunk = 'f' * 2048
+        self.serv_conn.sendall(big_chunk)
+
+    def testFromFd(self):
+        # Testing fromfd()
+        if not hasattr(socket, "fromfd"):
+            return # On Windows, this doesn't exist
+        fd = self.cli_conn.fileno()
+        sock = socket.fromfd(fd, socket.AF_INET, socket.SOCK_STREAM)
+        msg = sock.recv(1024)
+        self.assertEqual(msg, MSG)
+
+    def _testFromFd(self):
+        self.serv_conn.send(MSG)
+
+    def testShutdown(self):
+        # Testing shutdown()
+        msg = self.cli_conn.recv(1024)
+        self.assertEqual(msg, MSG)
+
+    def _testShutdown(self):
+        self.serv_conn.send(MSG)
+        self.serv_conn.shutdown(2)
+
+class BasicUDPTest(ThreadedUDPSocketTest):
+
+    def __init__(self, methodName='runTest'):
+        ThreadedUDPSocketTest.__init__(self, methodName=methodName)
+
+    def testSendtoAndRecv(self):
+        # Testing sendto() and Recv() over UDP
+        msg = self.serv.recv(len(MSG))
+        self.assertEqual(msg, MSG)
+
+    def _testSendtoAndRecv(self):
+        self.cli.sendto(MSG, 0, (HOST, PORT))
+
+    def testRecvFrom(self):
+        # Testing recvfrom() over UDP
+        msg, addr = self.serv.recvfrom(len(MSG))
+        self.assertEqual(msg, MSG)
+
+    def _testRecvFrom(self):
+        self.cli.sendto(MSG, 0, (HOST, PORT))
+
+    def testRecvFromNegative(self):
+        # Negative lengths passed to recvfrom should give ValueError.
+        self.assertRaises(ValueError, self.serv.recvfrom, -1)
+
+    def _testRecvFromNegative(self):
+        self.cli.sendto(MSG, 0, (HOST, PORT))
+
+class TCPCloserTest(ThreadedTCPSocketTest):
+
+    def testClose(self):
+        conn, addr = self.serv.accept()
+        conn.close()
+
+        sd = self.cli
+        read, write, err = select.select([sd], [], [], 1.0)
+        self.assertEqual(read, [sd])
+        self.assertEqual(sd.recv(1), '')
+
+    def _testClose(self):
+        self.cli.connect((HOST, PORT))
+        time.sleep(1.0)
+
+class BasicSocketPairTest(SocketPairTest):
+
+    def __init__(self, methodName='runTest'):
+        SocketPairTest.__init__(self, methodName=methodName)
+
+    def testRecv(self):
+        msg = self.serv.recv(1024)
+        self.assertEqual(msg, MSG)
+
+    def _testRecv(self):
+        self.cli.send(MSG)
+
+    def testSend(self):
+        self.serv.send(MSG)
+
+    def _testSend(self):
+        msg = self.cli.recv(1024)
+        self.assertEqual(msg, MSG)
+
+class NonBlockingTCPTests(ThreadedTCPSocketTest):
+
+    def __init__(self, methodName='runTest'):
+        ThreadedTCPSocketTest.__init__(self, methodName=methodName)
+
+    def testSetBlocking(self):
+        # Testing whether set blocking works
+        self.serv.setblocking(0)
+        start = time.time()
+        try:
+            self.serv.accept()
+        except socket.error:
+            pass
+        end = time.time()
+        self.assert_((end - start) < 1.0, "Error setting non-blocking mode.")
+
+    def _testSetBlocking(self):
+        pass
+
+    def testAccept(self):
+        # Testing non-blocking accept
+        self.serv.setblocking(0)
+        try:
+            conn, addr = self.serv.accept()
+        except socket.error:
+            pass
+        else:
+            self.fail("Error trying to do non-blocking accept.")
+        read, write, err = select.select([self.serv], [], [])
+        if self.serv in read:
+            conn, addr = self.serv.accept()
+        else:
+            self.fail("Error trying to do accept after select.")
+
+    def _testAccept(self):
+        time.sleep(0.1)
+        self.cli.connect((HOST, PORT))
+
+    def testConnect(self):
+        # Testing non-blocking connect
+        conn, addr = self.serv.accept()
+
+    def _testConnect(self):
+        self.cli.settimeout(10)
+        self.cli.connect((HOST, PORT))
+
+    def testRecv(self):
+        # Testing non-blocking recv
+        conn, addr = self.serv.accept()
+        conn.setblocking(0)
+        try:
+            msg = conn.recv(len(MSG))
+        except socket.error:
+            pass
+        else:
+            self.fail("Error trying to do non-blocking recv.")
+        read, write, err = select.select([conn], [], [])
+        if conn in read:
+            msg = conn.recv(len(MSG))
+            self.assertEqual(msg, MSG)
+        else:
+            self.fail("Error during select call to non-blocking socket.")
+
+    def _testRecv(self):
+        self.cli.connect((HOST, PORT))
+        time.sleep(0.1)
+        self.cli.send(MSG)
+
+class FileObjectClassTestCase(SocketConnectedTest):
+
+    bufsize = -1 # Use default buffer size
+
+    def __init__(self, methodName='runTest'):
+        SocketConnectedTest.__init__(self, methodName=methodName)
+
+    def setUp(self):
+        SocketConnectedTest.setUp(self)
+        self.serv_file = self.cli_conn.makefile('rb', self.bufsize)
+
+    def tearDown(self):
+        self.serv_file.close()
+        self.assert_(self.serv_file.closed)
+        self.serv_file = None
+        SocketConnectedTest.tearDown(self)
+
+    def clientSetUp(self):
+        SocketConnectedTest.clientSetUp(self)
+        self.cli_file = self.serv_conn.makefile('wb')
+
+    def clientTearDown(self):
+        self.cli_file.close()
+        self.assert_(self.cli_file.closed)
+        self.cli_file = None
+        SocketConnectedTest.clientTearDown(self)
+
+    def testSmallRead(self):
+        # Performing small file read test
+        first_seg = self.serv_file.read(len(MSG)-3)
+        second_seg = self.serv_file.read(3)
+        msg = first_seg + second_seg
+        self.assertEqual(msg, MSG)
+
+    def _testSmallRead(self):
+        self.cli_file.write(MSG)
+        self.cli_file.flush()
+
+    def testFullRead(self):
+        # read until EOF
+        msg = self.serv_file.read()
+        self.assertEqual(msg, MSG)
+
+    def _testFullRead(self):
+        self.cli_file.write(MSG)
+        self.cli_file.close()
+
+    def testUnbufferedRead(self):
+        # Performing unbuffered file read test
+        buf = ''
+        while 1:
+            char = self.serv_file.read(1)
+            if not char:
+                break
+            buf += char
+        self.assertEqual(buf, MSG)
+
+    def _testUnbufferedRead(self):
+        self.cli_file.write(MSG)
+        self.cli_file.flush()
+
+    def testReadline(self):
+        # Performing file readline test
+        line = self.serv_file.readline()
+        self.assertEqual(line, MSG)
+
+    def _testReadline(self):
+        self.cli_file.write(MSG)
+        self.cli_file.flush()
+
+    def testClosedAttr(self):
+        self.assert_(not self.serv_file.closed)
+
+    def _testClosedAttr(self):
+        self.assert_(not self.cli_file.closed)
+
+class UnbufferedFileObjectClassTestCase(FileObjectClassTestCase):
+
+    """Repeat the tests from FileObjectClassTestCase with bufsize==0.
+
+    In this case (and in this case only), it should be possible to
+    create a file object, read a line from it, create another file
+    object, read another line from it, without loss of data in the
+    first file object's buffer.  Note that httplib relies on this
+    when reading multiple requests from the same socket."""
+
+    bufsize = 0 # Use unbuffered mode
+
+    def testUnbufferedReadline(self):
+        # Read a line, create a new file object, read another line with it
+        line = self.serv_file.readline() # first line
+        self.assertEqual(line, "A. " + MSG) # first line
+        self.serv_file = self.cli_conn.makefile('rb', 0)
+        line = self.serv_file.readline() # second line
+        self.assertEqual(line, "B. " + MSG) # second line
+
+    def _testUnbufferedReadline(self):
+        self.cli_file.write("A. " + MSG)
+        self.cli_file.write("B. " + MSG)
+        self.cli_file.flush()
+
+class LineBufferedFileObjectClassTestCase(FileObjectClassTestCase):
+
+    bufsize = 1 # Default-buffered for reading; line-buffered for writing
+
+
+class SmallBufferedFileObjectClassTestCase(FileObjectClassTestCase):
+
+    bufsize = 2 # Exercise the buffering code
+
+
+class Urllib2FileobjectTest(unittest.TestCase):
+
+    # urllib2.HTTPHandler has "borrowed" socket._fileobject, and requires that
+    # it close the socket if the close c'tor argument is true
+
+    def testClose(self):
+        class MockSocket:
+            closed = False
+            def flush(self): pass
+            def close(self): self.closed = True
+
+        # must not close unless we request it: the original use of _fileobject
+        # by module socket requires that the underlying socket not be closed until
+        # the _socketobject that created the _fileobject is closed
+        s = MockSocket()
+        f = socket._fileobject(s)
+        f.close()
+        self.assert_(not s.closed)
+
+        s = MockSocket()
+        f = socket._fileobject(s, close=True)
+        f.close()
+        self.assert_(s.closed)
+
+class TCPTimeoutTest(SocketTCPTest):
+
+    def testTCPTimeout(self):
+        def raise_timeout(*args, **kwargs):
+            self.serv.settimeout(1.0)
+            self.serv.accept()
+        self.failUnlessRaises(socket.timeout, raise_timeout,
+                              "Error generating a timeout exception (TCP)")
+
+    def testTimeoutZero(self):
+        ok = False
+        try:
+            self.serv.settimeout(0.0)
+            foo = self.serv.accept()
+        except socket.timeout:
+            self.fail("caught timeout instead of error (TCP)")
+        except socket.error:
+            ok = True
+        except:
+            self.fail("caught unexpected exception (TCP)")
+        if not ok:
+            self.fail("accept() returned success when we did not expect it")
+
+    def testInterruptedTimeout(self):
+        # XXX I don't know how to do this test on MSWindows or any other
+        # plaform that doesn't support signal.alarm() or os.kill(), though
+        # the bug should have existed on all platforms.
+        if not hasattr(signal, "alarm"):
+            return                  # can only test on *nix
+        self.serv.settimeout(5.0)   # must be longer than alarm
+        class Alarm(Exception):
+            pass
+        def alarm_handler(signal, frame):
+            raise Alarm
+        old_alarm = signal.signal(signal.SIGALRM, alarm_handler)
+        try:
+            signal.alarm(2)    # POSIX allows alarm to be up to 1 second early
+            try:
+                foo = self.serv.accept()
+            except socket.timeout:
+                self.fail("caught timeout instead of Alarm")
+            except Alarm:
+                pass
+            except:
+                self.fail("caught other exception instead of Alarm")
+            else:
+                self.fail("nothing caught")
+            signal.alarm(0)         # shut off alarm
+        except Alarm:
+            self.fail("got Alarm in wrong place")
+        finally:
+            # no alarm can be pending.  Safe to restore old handler.
+            signal.signal(signal.SIGALRM, old_alarm)
+
+class UDPTimeoutTest(SocketTCPTest):
+
+    def testUDPTimeout(self):
+        def raise_timeout(*args, **kwargs):
+            self.serv.settimeout(1.0)
+            self.serv.recv(1024)
+        self.failUnlessRaises(socket.timeout, raise_timeout,
+                              "Error generating a timeout exception (UDP)")
+
+    def testTimeoutZero(self):
+        ok = False
+        try:
+            self.serv.settimeout(0.0)
+            foo = self.serv.recv(1024)
+        except socket.timeout:
+            self.fail("caught timeout instead of error (UDP)")
+        except socket.error:
+            ok = True
+        except:
+            self.fail("caught unexpected exception (UDP)")
+        if not ok:
+            self.fail("recv() returned success when we did not expect it")
+
+class TestExceptions(unittest.TestCase):
+
+    def testExceptionTree(self):
+        self.assert_(issubclass(socket.error, Exception))
+        self.assert_(issubclass(socket.herror, socket.error))
+        self.assert_(issubclass(socket.gaierror, socket.error))
+        self.assert_(issubclass(socket.timeout, socket.error))
+
+class TestLinuxAbstractNamespace(unittest.TestCase):
+
+    UNIX_PATH_MAX = 108
+
+    def testLinuxAbstractNamespace(self):
+        address = "\x00python-test-hello\x00\xff"
+        s1 = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+        s1.bind(address)
+        s1.listen(1)
+        s2 = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+        s2.connect(s1.getsockname())
+        s1.accept()
+        self.assertEqual(s1.getsockname(), address)
+        self.assertEqual(s2.getpeername(), address)
+
+    def testMaxName(self):
+        address = "\x00" + "h" * (self.UNIX_PATH_MAX - 1)
+        s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+        s.bind(address)
+        self.assertEqual(s.getsockname(), address)
+
+    def testNameOverflow(self):
+        address = "\x00" + "h" * self.UNIX_PATH_MAX
+        s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+        self.assertRaises(socket.error, s.bind, address)
+
+
+class BufferIOTest(SocketConnectedTest):
+    """
+    Test the buffer versions of socket.recv() and socket.send().
+    """
+    def __init__(self, methodName='runTest'):
+        SocketConnectedTest.__init__(self, methodName=methodName)
+
+    def testRecvInto(self):
+        buf = array.array('c', ' '*1024)
+        nbytes = self.cli_conn.recv_into(buf)
+        self.assertEqual(nbytes, len(MSG))
+        msg = buf.tostring()[:len(MSG)]
+        self.assertEqual(msg, MSG)
+
+    def _testRecvInto(self):
+        buf = buffer(MSG)
+        self.serv_conn.send(buf)
+
+    def testRecvFromInto(self):
+        buf = array.array('c', ' '*1024)
+        nbytes, addr = self.cli_conn.recvfrom_into(buf)
+        self.assertEqual(nbytes, len(MSG))
+        msg = buf.tostring()[:len(MSG)]
+        self.assertEqual(msg, MSG)
+
+    def _testRecvFromInto(self):
+        buf = buffer(MSG)
+        self.serv_conn.send(buf)
+
+def test_main():
+    tests = [GeneralModuleTests, BasicTCPTest, TCPCloserTest, TCPTimeoutTest,
+             TestExceptions, BufferIOTest]
+    if sys.platform != 'mac':
+        tests.extend([ BasicUDPTest, UDPTimeoutTest ])
+
+    tests.extend([
+        NonBlockingTCPTests,
+        FileObjectClassTestCase,
+        UnbufferedFileObjectClassTestCase,
+        LineBufferedFileObjectClassTestCase,
+        SmallBufferedFileObjectClassTestCase,
+        Urllib2FileobjectTest,
+    ])
+    if hasattr(socket, "socketpair"):
+        tests.append(BasicSocketPairTest)
+    if sys.platform == 'linux2':
+        tests.append(TestLinuxAbstractNamespace)
+
+    thread_info = test_support.threading_setup()
+    test_support.run_unittest(*tests)
+    test_support.threading_cleanup(*thread_info)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_socket_ssl.py
===================================================================
--- vendor/Python/current/Lib/test/test_socket_ssl.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_socket_ssl.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,134 @@
+# Test just the SSL support in the socket module, in a moderately bogus way.
+
+import sys
+from test import test_support
+import socket
+import errno
+
+# Optionally test SSL support.  This requires the 'network' resource as given
+# on the regrtest command line.
+skip_expected = not (test_support.is_resource_enabled('network') and
+                     hasattr(socket, "ssl"))
+
+def test_basic():
+    test_support.requires('network')
+
+    import urllib
+
+    if test_support.verbose:
+        print "test_basic ..."
+
+    socket.RAND_status()
+    try:
+        socket.RAND_egd(1)
+    except TypeError:
+        pass
+    else:
+        print "didn't raise TypeError"
+    socket.RAND_add("this is a random string", 75.0)
+
+    try:
+        f = urllib.urlopen('https://sf.net')
+    except IOError, exc:
+        if exc.errno == errno.ETIMEDOUT:
+            raise test_support.ResourceDenied('HTTPS connection is timing out')
+        else:
+            raise
+    buf = f.read()
+    f.close()
+
+def test_timeout():
+    test_support.requires('network')
+
+    def error_msg(extra_msg):
+        print >> sys.stderr, """\
+    WARNING:  an attempt to connect to %r %s, in
+    test_timeout.  That may be legitimate, but is not the outcome we hoped
+    for.  If this message is seen often, test_timeout should be changed to
+    use a more reliable address.""" % (ADDR, extra_msg)
+
+    if test_support.verbose:
+        print "test_timeout ..."
+
+    # A service which issues a welcome banner (without need to write
+    # anything).
+    # XXX ("gmail.org", 995) has been unreliable so far, from time to time
+    # XXX non-responsive for hours on end (& across all buildbot slaves,
+    # XXX so that's not just a local thing).
+    ADDR = "gmail.org", 995
+
+    s = socket.socket()
+    s.settimeout(30.0)
+    try:
+        s.connect(ADDR)
+    except socket.timeout:
+        error_msg('timed out')
+        return
+    except socket.error, exc:  # In case connection is refused.
+        if exc.args[0] == errno.ECONNREFUSED:
+            error_msg('was refused')
+            return
+        else:
+            raise
+
+    ss = socket.ssl(s)
+    # Read part of return welcome banner twice.
+    ss.read(1)
+    ss.read(1)
+    s.close()
+
+def test_rude_shutdown():
+    if test_support.verbose:
+        print "test_rude_shutdown ..."
+
+    try:
+        import threading
+    except ImportError:
+        return
+
+    # Some random port to connect to.
+    PORT = [9934]
+
+    listener_ready = threading.Event()
+    listener_gone = threading.Event()
+
+    # `listener` runs in a thread.  It opens a socket listening on PORT, and
+    # sits in an accept() until the main thread connects.  Then it rudely
+    # closes the socket, and sets Event `listener_gone` to let the main thread
+    # know the socket is gone.
+    def listener():
+        s = socket.socket()
+        PORT[0] = test_support.bind_port(s, '', PORT[0])
+        s.listen(5)
+        listener_ready.set()
+        s.accept()
+        s = None # reclaim the socket object, which also closes it
+        listener_gone.set()
+
+    def connector():
+        listener_ready.wait()
+        s = socket.socket()
+        s.connect(('localhost', PORT[0]))
+        listener_gone.wait()
+        try:
+            ssl_sock = socket.ssl(s)
+        except socket.sslerror:
+            pass
+        else:
+            raise test_support.TestFailed(
+                      'connecting to closed SSL socket should have failed')
+
+    t = threading.Thread(target=listener)
+    t.start()
+    connector()
+    t.join()
+
+def test_main():
+    if not hasattr(socket, "ssl"):
+        raise test_support.TestSkipped("socket module has no ssl support")
+    test_rude_shutdown()
+    test_basic()
+    test_timeout()
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_socketserver.py
===================================================================
--- vendor/Python/current/Lib/test/test_socketserver.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_socketserver.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,218 @@
+# Test suite for SocketServer.py
+
+from test import test_support
+from test.test_support import (verbose, verify, TESTFN, TestSkipped,
+                               reap_children)
+test_support.requires('network')
+
+from SocketServer import *
+import socket
+import errno
+import select
+import time
+import threading
+import os
+
+NREQ = 3
+DELAY = 0.5
+
+class MyMixinHandler:
+    def handle(self):
+        time.sleep(DELAY)
+        line = self.rfile.readline()
+        time.sleep(DELAY)
+        self.wfile.write(line)
+
+class MyStreamHandler(MyMixinHandler, StreamRequestHandler):
+    pass
+
+class MyDatagramHandler(MyMixinHandler, DatagramRequestHandler):
+    pass
+
+class MyMixinServer:
+    def serve_a_few(self):
+        for i in range(NREQ):
+            self.handle_request()
+    def handle_error(self, request, client_address):
+        self.close_request(request)
+        self.server_close()
+        raise
+
+teststring = "hello world\n"
+
+def receive(sock, n, timeout=20):
+    r, w, x = select.select([sock], [], [], timeout)
+    if sock in r:
+        return sock.recv(n)
+    else:
+        raise RuntimeError, "timed out on %r" % (sock,)
+
+def testdgram(proto, addr):
+    s = socket.socket(proto, socket.SOCK_DGRAM)
+    s.sendto(teststring, addr)
+    buf = data = receive(s, 100)
+    while data and '\n' not in buf:
+        data = receive(s, 100)
+        buf += data
+    verify(buf == teststring)
+    s.close()
+
+def teststream(proto, addr):
+    s = socket.socket(proto, socket.SOCK_STREAM)
+    s.connect(addr)
+    s.sendall(teststring)
+    buf = data = receive(s, 100)
+    while data and '\n' not in buf:
+        data = receive(s, 100)
+        buf += data
+    verify(buf == teststring)
+    s.close()
+
+class ServerThread(threading.Thread):
+    def __init__(self, addr, svrcls, hdlrcls):
+        threading.Thread.__init__(self)
+        self.__addr = addr
+        self.__svrcls = svrcls
+        self.__hdlrcls = hdlrcls
+    def run(self):
+        class svrcls(MyMixinServer, self.__svrcls):
+            pass
+        if verbose: print "thread: creating server"
+        svr = svrcls(self.__addr, self.__hdlrcls)
+        # pull the address out of the server in case it changed
+        # this can happen if another process is using the port
+        addr = svr.server_address
+        if addr:
+            self.__addr = addr
+            if self.__addr != svr.socket.getsockname():
+                raise RuntimeError('server_address was %s, expected %s' %
+                                       (self.__addr, svr.socket.getsockname()))
+        if verbose: print "thread: serving three times"
+        svr.serve_a_few()
+        if verbose: print "thread: done"
+
+seed = 0
+def pickport():
+    global seed
+    seed += 1
+    return 10000 + (os.getpid() % 1000)*10 + seed
+
+host = "localhost"
+testfiles = []
+def pickaddr(proto):
+    if proto == socket.AF_INET:
+        return (host, pickport())
+    else:
+        fn = TESTFN + str(pickport())
+        if os.name == 'os2':
+            # AF_UNIX socket names on OS/2 require a specific prefix
+            # which can't include a drive letter and must also use
+            # backslashes as directory separators
+            if fn[1] == ':':
+                fn = fn[2:]
+            if fn[0] in (os.sep, os.altsep):
+                fn = fn[1:]
+            fn = os.path.join('\socket', fn)
+            if os.sep == '/':
+                fn = fn.replace(os.sep, os.altsep)
+            else:
+                fn = fn.replace(os.altsep, os.sep)
+        testfiles.append(fn)
+        return fn
+
+def cleanup():
+    for fn in testfiles:
+        try:
+            os.remove(fn)
+        except os.error:
+            pass
+    testfiles[:] = []
+
+def testloop(proto, servers, hdlrcls, testfunc):
+    for svrcls in servers:
+        addr = pickaddr(proto)
+        if verbose:
+            print "ADDR =", addr
+            print "CLASS =", svrcls
+        t = ServerThread(addr, svrcls, hdlrcls)
+        if verbose: print "server created"
+        t.start()
+        if verbose: print "server running"
+        for i in range(NREQ):
+            time.sleep(DELAY)
+            if verbose: print "test client", i
+            testfunc(proto, addr)
+        if verbose: print "waiting for server"
+        t.join()
+        if verbose: print "done"
+
+class ForgivingTCPServer(TCPServer):
+    # prevent errors if another process is using the port we want
+    def server_bind(self):
+        host, default_port = self.server_address
+        # this code shamelessly stolen from test.test_support
+        # the ports were changed to protect the innocent
+        import sys
+        for port in [default_port, 3434, 8798, 23833]:
+            try:
+                self.server_address = host, port
+                TCPServer.server_bind(self)
+                break
+            except socket.error, (err, msg):
+                if err != errno.EADDRINUSE:
+                    raise
+                print >>sys.__stderr__, \
+                    '  WARNING: failed to listen on port %d, trying another' % port
+
+tcpservers = [ForgivingTCPServer, ThreadingTCPServer]
+if hasattr(os, 'fork') and os.name not in ('os2',):
+    tcpservers.append(ForkingTCPServer)
+udpservers = [UDPServer, ThreadingUDPServer]
+if hasattr(os, 'fork') and os.name not in ('os2',):
+    udpservers.append(ForkingUDPServer)
+
+if not hasattr(socket, 'AF_UNIX'):
+    streamservers = []
+    dgramservers = []
+else:
+    class ForkingUnixStreamServer(ForkingMixIn, UnixStreamServer): pass
+    streamservers = [UnixStreamServer, ThreadingUnixStreamServer]
+    if hasattr(os, 'fork') and os.name not in ('os2',):
+        streamservers.append(ForkingUnixStreamServer)
+    class ForkingUnixDatagramServer(ForkingMixIn, UnixDatagramServer): pass
+    dgramservers = [UnixDatagramServer, ThreadingUnixDatagramServer]
+    if hasattr(os, 'fork') and os.name not in ('os2',):
+        dgramservers.append(ForkingUnixDatagramServer)
+
+def sloppy_cleanup():
+    # See http://python.org/sf/1540386
+    # We need to reap children here otherwise a child from one server
+    # can be left running for the next server and cause a test failure.
+    time.sleep(DELAY)
+    reap_children()
+
+def testall():
+    testloop(socket.AF_INET, tcpservers, MyStreamHandler, teststream)
+    sloppy_cleanup()
+    testloop(socket.AF_INET, udpservers, MyDatagramHandler, testdgram)
+    if hasattr(socket, 'AF_UNIX'):
+        sloppy_cleanup()
+        testloop(socket.AF_UNIX, streamservers, MyStreamHandler, teststream)
+        # Alas, on Linux (at least) recvfrom() doesn't return a meaningful
+        # client address so this cannot work:
+        ##testloop(socket.AF_UNIX, dgramservers, MyDatagramHandler, testdgram)
+
+def test_main():
+    import imp
+    if imp.lock_held():
+        # If the import lock is held, the threads will hang.
+        raise TestSkipped("can't run when import lock is held")
+
+    try:
+        testall()
+    finally:
+        cleanup()
+    reap_children()
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_softspace.py
===================================================================
--- vendor/Python/current/Lib/test/test_softspace.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_softspace.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,14 @@
+from test import test_support
+import StringIO
+
+# SF bug 480215:  softspace confused in nested print
+f = StringIO.StringIO()
+class C:
+    def __str__(self):
+        print >> f, 'a'
+        return 'b'
+
+print >> f, C(), 'c ', 'd\t', 'e'
+print >> f, 'f', 'g'
+# In 2.2 & earlier, this printed ' a\nbc  d\te\nf g\n'
+test_support.vereq(f.getvalue(), 'a\nb c  d\te\nf g\n')

Added: vendor/Python/current/Lib/test/test_sort.py
===================================================================
--- vendor/Python/current/Lib/test/test_sort.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_sort.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,289 @@
+from test import test_support
+import random
+import sys
+import unittest
+
+verbose = test_support.verbose
+nerrors = 0
+
+def check(tag, expected, raw, compare=None):
+    global nerrors
+
+    if verbose:
+        print "    checking", tag
+
+    orig = raw[:]   # save input in case of error
+    if compare:
+        raw.sort(compare)
+    else:
+        raw.sort()
+
+    if len(expected) != len(raw):
+        print "error in", tag
+        print "length mismatch;", len(expected), len(raw)
+        print expected
+        print orig
+        print raw
+        nerrors += 1
+        return
+
+    for i, good in enumerate(expected):
+        maybe = raw[i]
+        if good is not maybe:
+            print "error in", tag
+            print "out of order at index", i, good, maybe
+            print expected
+            print orig
+            print raw
+            nerrors += 1
+            return
+
+class TestBase(unittest.TestCase):
+    def testStressfully(self):
+        # Try a variety of sizes at and around powers of 2, and at powers of 10.
+        sizes = [0]
+        for power in range(1, 10):
+            n = 2 ** power
+            sizes.extend(range(n-1, n+2))
+        sizes.extend([10, 100, 1000])
+
+        class Complains(object):
+            maybe_complain = True
+
+            def __init__(self, i):
+                self.i = i
+
+            def __lt__(self, other):
+                if Complains.maybe_complain and random.random() < 0.001:
+                    if verbose:
+                        print "        complaining at", self, other
+                    raise RuntimeError
+                return self.i < other.i
+
+            def __repr__(self):
+                return "Complains(%d)" % self.i
+
+        class Stable(object):
+            def __init__(self, key, i):
+                self.key = key
+                self.index = i
+
+            def __cmp__(self, other):
+                return cmp(self.key, other.key)
+
+            def __repr__(self):
+                return "Stable(%d, %d)" % (self.key, self.index)
+
+        for n in sizes:
+            x = range(n)
+            if verbose:
+                print "Testing size", n
+
+            s = x[:]
+            check("identity", x, s)
+
+            s = x[:]
+            s.reverse()
+            check("reversed", x, s)
+
+            s = x[:]
+            random.shuffle(s)
+            check("random permutation", x, s)
+
+            y = x[:]
+            y.reverse()
+            s = x[:]
+            check("reversed via function", y, s, lambda a, b: cmp(b, a))
+
+            if verbose:
+                print "    Checking against an insane comparison function."
+                print "        If the implementation isn't careful, this may segfault."
+            s = x[:]
+            s.sort(lambda a, b:  int(random.random() * 3) - 1)
+            check("an insane function left some permutation", x, s)
+
+            x = [Complains(i) for i in x]
+            s = x[:]
+            random.shuffle(s)
+            Complains.maybe_complain = True
+            it_complained = False
+            try:
+                s.sort()
+            except RuntimeError:
+                it_complained = True
+            if it_complained:
+                Complains.maybe_complain = False
+                check("exception during sort left some permutation", x, s)
+
+            s = [Stable(random.randrange(10), i) for i in xrange(n)]
+            augmented = [(e, e.index) for e in s]
+            augmented.sort()    # forced stable because ties broken by index
+            x = [e for e, i in augmented] # a stable sort of s
+            check("stability", x, s)
+
+#==============================================================================
+
+class TestBugs(unittest.TestCase):
+
+    def test_bug453523(self):
+        # bug 453523 -- list.sort() crasher.
+        # If this fails, the most likely outcome is a core dump.
+        # Mutations during a list sort should raise a ValueError.
+
+        class C:
+            def __lt__(self, other):
+                if L and random.random() < 0.75:
+                    L.pop()
+                else:
+                    L.append(3)
+                return random.random() < 0.5
+
+        L = [C() for i in range(50)]
+        self.assertRaises(ValueError, L.sort)
+
+    def test_cmpNone(self):
+        # Testing None as a comparison function.
+
+        L = range(50)
+        random.shuffle(L)
+        L.sort(None)
+        self.assertEqual(L, range(50))
+
+    def test_undetected_mutation(self):
+        # Python 2.4a1 did not always detect mutation
+        memorywaster = []
+        for i in range(20):
+            def mutating_cmp(x, y):
+                L.append(3)
+                L.pop()
+                return cmp(x, y)
+            L = [1,2]
+            self.assertRaises(ValueError, L.sort, mutating_cmp)
+            def mutating_cmp(x, y):
+                L.append(3)
+                del L[:]
+                return cmp(x, y)
+            self.assertRaises(ValueError, L.sort, mutating_cmp)
+            memorywaster = [memorywaster]
+
+#==============================================================================
+
+class TestDecorateSortUndecorate(unittest.TestCase):
+
+    def test_decorated(self):
+        data = 'The quick Brown fox Jumped over The lazy Dog'.split()
+        copy = data[:]
+        random.shuffle(data)
+        data.sort(key=str.lower)
+        copy.sort(cmp=lambda x,y: cmp(x.lower(), y.lower()))
+
+    def test_baddecorator(self):
+        data = 'The quick Brown fox Jumped over The lazy Dog'.split()
+        self.assertRaises(TypeError, data.sort, None, lambda x,y: 0)
+
+    def test_stability(self):
+        data = [(random.randrange(100), i) for i in xrange(200)]
+        copy = data[:]
+        data.sort(key=lambda (x,y): x)  # sort on the random first field
+        copy.sort()                     # sort using both fields
+        self.assertEqual(data, copy)    # should get the same result
+
+    def test_cmp_and_key_combination(self):
+        # Verify that the wrapper has been removed
+        def compare(x, y):
+            self.assertEqual(type(x), str)
+            self.assertEqual(type(x), str)
+            return cmp(x, y)
+        data = 'The quick Brown fox Jumped over The lazy Dog'.split()
+        data.sort(cmp=compare, key=str.lower)
+
+    def test_badcmp_with_key(self):
+        # Verify that the wrapper has been removed
+        data = 'The quick Brown fox Jumped over The lazy Dog'.split()
+        self.assertRaises(TypeError, data.sort, "bad", str.lower)
+
+    def test_key_with_exception(self):
+        # Verify that the wrapper has been removed
+        data = range(-2,2)
+        dup = data[:]
+        self.assertRaises(ZeroDivisionError, data.sort, None, lambda x: 1/x)
+        self.assertEqual(data, dup)
+
+    def test_key_with_mutation(self):
+        data = range(10)
+        def k(x):
+            del data[:]
+            data[:] = range(20)
+            return x
+        self.assertRaises(ValueError, data.sort, key=k)
+
+    def test_key_with_mutating_del(self):
+        data = range(10)
+        class SortKiller(object):
+            def __init__(self, x):
+                pass
+            def __del__(self):
+                del data[:]
+                data[:] = range(20)
+        self.assertRaises(ValueError, data.sort, key=SortKiller)
+
+    def test_key_with_mutating_del_and_exception(self):
+        data = range(10)
+        ## dup = data[:]
+        class SortKiller(object):
+            def __init__(self, x):
+                if x > 2:
+                    raise RuntimeError
+            def __del__(self):
+                del data[:]
+                data[:] = range(20)
+        self.assertRaises(RuntimeError, data.sort, key=SortKiller)
+        ## major honking subtlety: we *can't* do:
+        ##
+        ## self.assertEqual(data, dup)
+        ##
+        ## because there is a reference to a SortKiller in the
+        ## traceback and by the time it dies we're outside the call to
+        ## .sort() and so the list protection gimmicks are out of
+        ## date (this cost some brain cells to figure out...).
+
+    def test_reverse(self):
+        data = range(100)
+        random.shuffle(data)
+        data.sort(reverse=True)
+        self.assertEqual(data, range(99,-1,-1))
+        self.assertRaises(TypeError, data.sort, "wrong type")
+
+    def test_reverse_stability(self):
+        data = [(random.randrange(100), i) for i in xrange(200)]
+        copy1 = data[:]
+        copy2 = data[:]
+        data.sort(cmp=lambda x,y: cmp(x[0],y[0]), reverse=True)
+        copy1.sort(cmp=lambda x,y: cmp(y[0],x[0]))
+        self.assertEqual(data, copy1)
+        copy2.sort(key=lambda x: x[0], reverse=True)
+        self.assertEqual(data, copy2)
+
+#==============================================================================
+
+def test_main(verbose=None):
+    test_classes = (
+        TestBase,
+        TestDecorateSortUndecorate,
+        TestBugs,
+    )
+
+    test_support.run_unittest(*test_classes)
+
+    # verify reference counting
+    if verbose and hasattr(sys, "gettotalrefcount"):
+        import gc
+        counts = [None] * 5
+        for i in xrange(len(counts)):
+            test_support.run_unittest(*test_classes)
+            gc.collect()
+            counts[i] = sys.gettotalrefcount()
+        print counts
+
+if __name__ == "__main__":
+    test_main(verbose=True)

Added: vendor/Python/current/Lib/test/test_sqlite.py
===================================================================
--- vendor/Python/current/Lib/test/test_sqlite.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_sqlite.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,17 @@
+from test.test_support import run_unittest, TestSkipped
+import unittest
+
+try:
+    import _sqlite3
+except ImportError:
+    raise TestSkipped('no sqlite available')
+from sqlite3.test import (dbapi, types, userfunctions,
+                                factory, transactions, hooks, regression)
+
+def test_main():
+    run_unittest(dbapi.suite(), types.suite(), userfunctions.suite(),
+                 factory.suite(), transactions.suite(), hooks.suite(),
+                 regression.suite())
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_startfile.py
===================================================================
--- vendor/Python/current/Lib/test/test_startfile.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_startfile.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,37 @@
+# Ridiculously simple test of the os.startfile function for Windows.
+#
+# empty.vbs is an empty file (except for a comment), which does
+# nothing when run with cscript or wscript.
+#
+# A possible improvement would be to have empty.vbs do something that
+# we can detect here, to make sure that not only the os.startfile()
+# call succeeded, but also the the script actually has run.
+
+import unittest
+from test import test_support
+
+# use this form so that the test is skipped when startfile is not available:
+from os import startfile, path
+
+class TestCase(unittest.TestCase):
+    def test_nonexisting(self):
+        self.assertRaises(OSError, startfile, "nonexisting.vbs")
+
+    def test_nonexisting_u(self):
+        self.assertRaises(OSError, startfile, u"nonexisting.vbs")
+
+    def test_empty(self):
+        empty = path.join(path.dirname(__file__), "empty.vbs")
+        startfile(empty)
+        startfile(empty, "open")
+
+    def test_empty_u(self):
+        empty = path.join(path.dirname(__file__), "empty.vbs")
+        startfile(unicode(empty, "mbcs"))
+        startfile(unicode(empty, "mbcs"), "open")
+
+def test_main():
+    test_support.run_unittest(TestCase)
+
+if __name__=="__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_str.py
===================================================================
--- vendor/Python/current/Lib/test/test_str.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_str.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,89 @@
+import unittest
+from test import test_support, string_tests
+
+
+class StrTest(
+    string_tests.CommonTest,
+    string_tests.MixinStrUnicodeUserStringTest,
+    string_tests.MixinStrUserStringTest,
+    string_tests.MixinStrUnicodeTest,
+    ):
+
+    type2test = str
+
+    # We don't need to propagate to str
+    def fixtype(self, obj):
+        return obj
+
+    def test_formatting(self):
+        string_tests.MixinStrUnicodeUserStringTest.test_formatting(self)
+        self.assertRaises(OverflowError, '%c'.__mod__, 0x1234)
+
+    def test_conversion(self):
+        # Make sure __str__() behaves properly
+        class Foo0:
+            def __unicode__(self):
+                return u"foo"
+
+        class Foo1:
+            def __str__(self):
+                return "foo"
+
+        class Foo2(object):
+            def __str__(self):
+                return "foo"
+
+        class Foo3(object):
+            def __str__(self):
+                return u"foo"
+
+        class Foo4(unicode):
+            def __str__(self):
+                return u"foo"
+
+        class Foo5(str):
+            def __str__(self):
+                return u"foo"
+
+        class Foo6(str):
+            def __str__(self):
+                return "foos"
+
+            def __unicode__(self):
+                return u"foou"
+
+        class Foo7(unicode):
+            def __str__(self):
+                return "foos"
+            def __unicode__(self):
+                return u"foou"
+
+        class Foo8(str):
+            def __new__(cls, content=""):
+                return str.__new__(cls, 2*content)
+            def __str__(self):
+                return self
+
+        class Foo9(str):
+            def __str__(self):
+                return "string"
+            def __unicode__(self):
+                return "not unicode"
+
+        self.assert_(str(Foo0()).startswith("<")) # this is different from __unicode__
+        self.assertEqual(str(Foo1()), "foo")
+        self.assertEqual(str(Foo2()), "foo")
+        self.assertEqual(str(Foo3()), "foo")
+        self.assertEqual(str(Foo4("bar")), "foo")
+        self.assertEqual(str(Foo5("bar")), "foo")
+        self.assertEqual(str(Foo6("bar")), "foos")
+        self.assertEqual(str(Foo7("bar")), "foos")
+        self.assertEqual(str(Foo8("foo")), "foofoo")
+        self.assertEqual(str(Foo9("foo")), "string")
+        self.assertEqual(unicode(Foo9("foo")), u"not unicode")
+
+def test_main():
+    test_support.run_unittest(StrTest)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_strftime.py
===================================================================
--- vendor/Python/current/Lib/test/test_strftime.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_strftime.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,158 @@
+#! /usr/bin/env python
+
+# Sanity checker for time.strftime
+
+import time, calendar, sys, os, re
+from test.test_support import verbose
+
+def main():
+    global verbose
+    # For C Python, these tests expect C locale, so we try to set that
+    # explicitly.  For Jython, Finn says we need to be in the US locale; my
+    # understanding is that this is the closest Java gets to C's "C" locale.
+    # Jython ought to supply an _locale module which Does The Right Thing, but
+    # this is the best we can do given today's state of affairs.
+    try:
+        import java
+        java.util.Locale.setDefault(java.util.Locale.US)
+    except ImportError:
+        # Can't do this first because it will succeed, even in Jython
+        import locale
+        locale.setlocale(locale.LC_TIME, 'C')
+    now = time.time()
+    strftest(now)
+    verbose = 0
+    # Try a bunch of dates and times,  chosen to vary through time of
+    # day and daylight saving time
+    for j in range(-5, 5):
+        for i in range(25):
+            strftest(now + (i + j*100)*23*3603)
+
+def escapestr(text, ampm):
+    """Escape text to deal with possible locale values that have regex
+    syntax while allowing regex syntax used for the comparison."""
+    new_text = re.escape(text)
+    new_text = new_text.replace(re.escape(ampm), ampm)
+    new_text = new_text.replace("\%", "%")
+    new_text = new_text.replace("\:", ":")
+    new_text = new_text.replace("\?", "?")
+    return new_text
+
+def strftest(now):
+    if verbose:
+        print "strftime test for", time.ctime(now)
+    nowsecs = str(long(now))[:-1]
+    gmt = time.gmtime(now)
+    now = time.localtime(now)
+
+    if now[3] < 12: ampm='(AM|am)'
+    else: ampm='(PM|pm)'
+
+    jan1 = time.localtime(time.mktime((now[0], 1, 1, 0, 0, 0, 0, 1, 0)))
+
+    try:
+        if now[8]: tz = time.tzname[1]
+        else: tz = time.tzname[0]
+    except AttributeError:
+        tz = ''
+
+    if now[3] > 12: clock12 = now[3] - 12
+    elif now[3] > 0: clock12 = now[3]
+    else: clock12 = 12
+
+    # Make sure any characters that could be taken as regex syntax is
+    # escaped in escapestr()
+    expectations = (
+        ('%a', calendar.day_abbr[now[6]], 'abbreviated weekday name'),
+        ('%A', calendar.day_name[now[6]], 'full weekday name'),
+        ('%b', calendar.month_abbr[now[1]], 'abbreviated month name'),
+        ('%B', calendar.month_name[now[1]], 'full month name'),
+        # %c see below
+        ('%d', '%02d' % now[2], 'day of month as number (00-31)'),
+        ('%H', '%02d' % now[3], 'hour (00-23)'),
+        ('%I', '%02d' % clock12, 'hour (01-12)'),
+        ('%j', '%03d' % now[7], 'julian day (001-366)'),
+        ('%m', '%02d' % now[1], 'month as number (01-12)'),
+        ('%M', '%02d' % now[4], 'minute, (00-59)'),
+        ('%p', ampm, 'AM or PM as appropriate'),
+        ('%S', '%02d' % now[5], 'seconds of current time (00-60)'),
+        ('%U', '%02d' % ((now[7] + jan1[6])//7),
+         'week number of the year (Sun 1st)'),
+        ('%w', '0?%d' % ((1+now[6]) % 7), 'weekday as a number (Sun 1st)'),
+        ('%W', '%02d' % ((now[7] + (jan1[6] - 1)%7)//7),
+         'week number of the year (Mon 1st)'),
+        # %x see below
+        ('%X', '%02d:%02d:%02d' % (now[3], now[4], now[5]), '%H:%M:%S'),
+        ('%y', '%02d' % (now[0]%100), 'year without century'),
+        ('%Y', '%d' % now[0], 'year with century'),
+        # %Z see below
+        ('%%', '%', 'single percent sign'),
+        )
+
+    nonstandard_expectations = (
+        # These are standard but don't have predictable output
+        ('%c', fixasctime(time.asctime(now)), 'near-asctime() format'),
+        ('%x', '%02d/%02d/%02d' % (now[1], now[2], (now[0]%100)),
+         '%m/%d/%y %H:%M:%S'),
+        ('%Z', '%s' % tz, 'time zone name'),
+
+        # These are some platform specific extensions
+        ('%D', '%02d/%02d/%02d' % (now[1], now[2], (now[0]%100)), 'mm/dd/yy'),
+        ('%e', '%2d' % now[2], 'day of month as number, blank padded ( 0-31)'),
+        ('%h', calendar.month_abbr[now[1]], 'abbreviated month name'),
+        ('%k', '%2d' % now[3], 'hour, blank padded ( 0-23)'),
+        ('%n', '\n', 'newline character'),
+        ('%r', '%02d:%02d:%02d %s' % (clock12, now[4], now[5], ampm),
+         '%I:%M:%S %p'),
+        ('%R', '%02d:%02d' % (now[3], now[4]), '%H:%M'),
+        ('%s', nowsecs, 'seconds since the Epoch in UCT'),
+        ('%t', '\t', 'tab character'),
+        ('%T', '%02d:%02d:%02d' % (now[3], now[4], now[5]), '%H:%M:%S'),
+        ('%3y', '%03d' % (now[0]%100),
+         'year without century rendered using fieldwidth'),
+        )
+
+    if verbose:
+        print "Strftime test, platform: %s, Python version: %s" % \
+              (sys.platform, sys.version.split()[0])
+
+    for e in expectations:
+        try:
+            result = time.strftime(e[0], now)
+        except ValueError, error:
+            print "Standard '%s' format gave error:" % e[0], error
+            continue
+        if re.match(escapestr(e[1], ampm), result): continue
+        if not result or result[0] == '%':
+            print "Does not support standard '%s' format (%s)" % (e[0], e[2])
+        else:
+            print "Conflict for %s (%s):" % (e[0], e[2])
+            print "  Expected %s, but got %s" % (e[1], result)
+
+    for e in nonstandard_expectations:
+        try:
+            result = time.strftime(e[0], now)
+        except ValueError, result:
+            if verbose:
+                print "Error for nonstandard '%s' format (%s): %s" % \
+                      (e[0], e[2], str(result))
+            continue
+        if re.match(escapestr(e[1], ampm), result):
+            if verbose:
+                print "Supports nonstandard '%s' format (%s)" % (e[0], e[2])
+        elif not result or result[0] == '%':
+            if verbose:
+                print "Does not appear to support '%s' format (%s)" % (e[0],
+                                                                       e[2])
+        else:
+            if verbose:
+                print "Conflict for nonstandard '%s' format (%s):" % (e[0],
+                                                                      e[2])
+                print "  Expected %s, but got %s" % (e[1], result)
+
+def fixasctime(s):
+    if s[8] == ' ':
+        s = s[:8] + '0' + s[9:]
+    return s
+
+main()


Property changes on: vendor/Python/current/Lib/test/test_strftime.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/test/test_string.py
===================================================================
--- vendor/Python/current/Lib/test/test_string.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_string.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,113 @@
+import unittest, string
+from test import test_support, string_tests
+from UserList import UserList
+
+class StringTest(
+    string_tests.CommonTest,
+    string_tests.MixinStrStringUserStringTest
+    ):
+
+    type2test = str
+
+    def checkequal(self, result, object, methodname, *args):
+        realresult = getattr(string, methodname)(object, *args)
+        self.assertEqual(
+            result,
+            realresult
+        )
+
+    def checkraises(self, exc, object, methodname, *args):
+        self.assertRaises(
+            exc,
+            getattr(string, methodname),
+            object,
+            *args
+        )
+
+    def checkcall(self, object, methodname, *args):
+        getattr(string, methodname)(object, *args)
+
+    def test_join(self):
+        # These are the same checks as in string_test.ObjectTest.test_join
+        # but the argument order ist different
+        self.checkequal('a b c d', ['a', 'b', 'c', 'd'], 'join', ' ')
+        self.checkequal('abcd', ('a', 'b', 'c', 'd'), 'join', '')
+        self.checkequal('w x y z', string_tests.Sequence(), 'join', ' ')
+        self.checkequal('abc', ('abc',), 'join', 'a')
+        self.checkequal('z', UserList(['z']), 'join', 'a')
+        if test_support.have_unicode:
+            self.checkequal(unicode('a.b.c'), ['a', 'b', 'c'], 'join', unicode('.'))
+            self.checkequal(unicode('a.b.c'), [unicode('a'), 'b', 'c'], 'join', '.')
+            self.checkequal(unicode('a.b.c'), ['a', unicode('b'), 'c'], 'join', '.')
+            self.checkequal(unicode('a.b.c'), ['a', 'b', unicode('c')], 'join', '.')
+            self.checkraises(TypeError, ['a', unicode('b'), 3], 'join', '.')
+        for i in [5, 25, 125]:
+            self.checkequal(
+                ((('a' * i) + '-') * i)[:-1],
+                ['a' * i] * i, 'join', '-')
+            self.checkequal(
+                ((('a' * i) + '-') * i)[:-1],
+                ('a' * i,) * i, 'join', '-')
+
+        self.checkraises(TypeError, string_tests.BadSeq1(), 'join', ' ')
+        self.checkequal('a b c', string_tests.BadSeq2(), 'join', ' ')
+        try:
+            def f():
+                yield 4 + ""
+            self.fixtype(' ').join(f())
+        except TypeError, e:
+            if '+' not in str(e):
+                self.fail('join() ate exception message')
+        else:
+            self.fail('exception not raised')
+
+
+
+
+class ModuleTest(unittest.TestCase):
+
+    def test_attrs(self):
+        string.whitespace
+        string.lowercase
+        string.uppercase
+        string.letters
+        string.digits
+        string.hexdigits
+        string.octdigits
+        string.punctuation
+        string.printable
+
+    def test_atoi(self):
+        self.assertEqual(string.atoi(" 1 "), 1)
+        self.assertRaises(ValueError, string.atoi, " 1x")
+        self.assertRaises(ValueError, string.atoi, " x1 ")
+
+    def test_atol(self):
+        self.assertEqual(string.atol("  1  "), 1L)
+        self.assertRaises(ValueError, string.atol, "  1x ")
+        self.assertRaises(ValueError, string.atol, "  x1 ")
+
+    def test_atof(self):
+        self.assertAlmostEqual(string.atof("  1  "), 1.0)
+        self.assertRaises(ValueError, string.atof, "  1x ")
+        self.assertRaises(ValueError, string.atof, "  x1 ")
+
+    def test_maketrans(self):
+        transtable = '\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037 !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`xyzdefghijklmnopqrstuvwxyz{|}~\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377'
+
+        self.assertEqual(string.maketrans('abc', 'xyz'), transtable)
+        self.assertRaises(ValueError, string.maketrans, 'abc', 'xyzq')
+
+    def test_capwords(self):
+        self.assertEqual(string.capwords('abc def ghi'), 'Abc Def Ghi')
+        self.assertEqual(string.capwords('abc\tdef\nghi'), 'Abc Def Ghi')
+        self.assertEqual(string.capwords('abc\t   def  \nghi'), 'Abc Def Ghi')
+        self.assertEqual(string.capwords('ABC DEF GHI'), 'Abc Def Ghi')
+        self.assertEqual(string.capwords('ABC-DEF-GHI', '-'), 'Abc-Def-Ghi')
+        self.assertEqual(string.capwords('ABC-def DEF-ghi GHI'), 'Abc-def Def-ghi Ghi')
+
+def test_main():
+    test_support.run_unittest(StringTest, ModuleTest)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_stringprep.py
===================================================================
--- vendor/Python/current/Lib/test/test_stringprep.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_stringprep.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,88 @@
+# To fully test this module, we would need a copy of the stringprep tables.
+# Since we don't have them, this test checks only a few codepoints.
+
+from test.test_support import verify, vereq
+
+import stringprep
+from stringprep import *
+
+verify(in_table_a1(u"\u0221"))
+verify(not in_table_a1(u"\u0222"))
+
+verify(in_table_b1(u"\u00ad"))
+verify(not in_table_b1(u"\u00ae"))
+
+verify(map_table_b2(u"\u0041"), u"\u0061")
+verify(map_table_b2(u"\u0061"), u"\u0061")
+
+verify(map_table_b3(u"\u0041"), u"\u0061")
+verify(map_table_b3(u"\u0061"), u"\u0061")
+
+verify(in_table_c11(u"\u0020"))
+verify(not in_table_c11(u"\u0021"))
+
+verify(in_table_c12(u"\u00a0"))
+verify(not in_table_c12(u"\u00a1"))
+
+verify(in_table_c12(u"\u00a0"))
+verify(not in_table_c12(u"\u00a1"))
+
+verify(in_table_c11_c12(u"\u00a0"))
+verify(not in_table_c11_c12(u"\u00a1"))
+
+verify(in_table_c21(u"\u001f"))
+verify(not in_table_c21(u"\u0020"))
+
+verify(in_table_c22(u"\u009f"))
+verify(not in_table_c22(u"\u00a0"))
+
+verify(in_table_c21_c22(u"\u009f"))
+verify(not in_table_c21_c22(u"\u00a0"))
+
+verify(in_table_c3(u"\ue000"))
+verify(not in_table_c3(u"\uf900"))
+
+verify(in_table_c4(u"\uffff"))
+verify(not in_table_c4(u"\u0000"))
+
+verify(in_table_c5(u"\ud800"))
+verify(not in_table_c5(u"\ud7ff"))
+
+verify(in_table_c6(u"\ufff9"))
+verify(not in_table_c6(u"\ufffe"))
+
+verify(in_table_c7(u"\u2ff0"))
+verify(not in_table_c7(u"\u2ffc"))
+
+verify(in_table_c8(u"\u0340"))
+verify(not in_table_c8(u"\u0342"))
+
+# C.9 is not in the bmp
+# verify(in_table_c9(u"\U000E0001"))
+# verify(not in_table_c8(u"\U000E0002"))
+
+verify(in_table_d1(u"\u05be"))
+verify(not in_table_d1(u"\u05bf"))
+
+verify(in_table_d2(u"\u0041"))
+verify(not in_table_d2(u"\u0040"))
+
+# This would generate a hash of all predicates. However, running
+# it is quite expensive, and only serves to detect changes in the
+# unicode database. Instead, stringprep.py asserts the version of
+# the database.
+
+# import hashlib
+# predicates = [k for k in dir(stringprep) if k.startswith("in_table")]
+# predicates.sort()
+# for p in predicates:
+#     f = getattr(stringprep, p)
+#     # Collect all BMP code points
+#     data = ["0"] * 0x10000
+#     for i in range(0x10000):
+#         if f(unichr(i)):
+#             data[i] = "1"
+#     data = "".join(data)
+#     h = hashlib.sha1()
+#     h.update(data)
+#     print p, h.hexdigest()

Added: vendor/Python/current/Lib/test/test_strop.py
===================================================================
--- vendor/Python/current/Lib/test/test_strop.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_strop.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,134 @@
+import warnings
+warnings.filterwarnings("ignore", "strop functions are obsolete;",
+                        DeprecationWarning,
+                        r'test.test_strop|unittest')
+import strop
+import unittest
+from test import test_support
+
+
+class StropFunctionTestCase(unittest.TestCase):
+
+    def test_atoi(self):
+        self.assert_(strop.atoi(" 1 ") == 1)
+        self.assertRaises(ValueError, strop.atoi, " 1x")
+        self.assertRaises(ValueError, strop.atoi, " x1 ")
+
+    def test_atol(self):
+        self.assert_(strop.atol(" 1 ") == 1L)
+        self.assertRaises(ValueError, strop.atol, " 1x")
+        self.assertRaises(ValueError, strop.atol, " x1 ")
+
+    def test_atof(self):
+        self.assert_(strop.atof(" 1 ") == 1.0)
+        self.assertRaises(ValueError, strop.atof, " 1x")
+        self.assertRaises(ValueError, strop.atof, " x1 ")
+
+    def test_capitalize(self):
+        self.assert_(strop.capitalize(" hello ") == " hello ")
+        self.assert_(strop.capitalize("hello ") == "Hello ")
+
+    def test_find(self):
+        self.assert_(strop.find("abcdefghiabc", "abc") == 0)
+        self.assert_(strop.find("abcdefghiabc", "abc", 1) == 9)
+        self.assert_(strop.find("abcdefghiabc", "def", 4) == -1)
+
+    def test_rfind(self):
+        self.assert_(strop.rfind("abcdefghiabc", "abc") == 9)
+
+    def test_lower(self):
+        self.assert_(strop.lower("HeLLo") == "hello")
+
+    def test_upper(self):
+        self.assert_(strop.upper("HeLLo") == "HELLO")
+
+    def test_swapcase(self):
+        self.assert_(strop.swapcase("HeLLo cOmpUteRs") == "hEllO CoMPuTErS")
+
+    def test_strip(self):
+        self.assert_(strop.strip(" \t\n hello \t\n ") == "hello")
+
+    def test_lstrip(self):
+        self.assert_(strop.lstrip(" \t\n hello \t\n ") == "hello \t\n ")
+
+    def test_rstrip(self):
+        self.assert_(strop.rstrip(" \t\n hello \t\n ") == " \t\n hello")
+
+    def test_replace(self):
+        replace = strop.replace
+        self.assert_(replace("one!two!three!", '!', '@', 1)
+                     == "one at two!three!")
+        self.assert_(replace("one!two!three!", '!', '@', 2)
+                     == "one at two@three!")
+        self.assert_(replace("one!two!three!", '!', '@', 3)
+                     == "one at two@three@")
+        self.assert_(replace("one!two!three!", '!', '@', 4)
+                     == "one at two@three@")
+
+        # CAUTION: a replace count of 0 means infinity only to strop,
+        # not to the string .replace() method or to the
+        # string.replace() function.
+
+        self.assert_(replace("one!two!three!", '!', '@', 0)
+                     == "one at two@three@")
+        self.assert_(replace("one!two!three!", '!', '@')
+                     == "one at two@three@")
+        self.assert_(replace("one!two!three!", 'x', '@')
+                     == "one!two!three!")
+        self.assert_(replace("one!two!three!", 'x', '@', 2)
+                     == "one!two!three!")
+
+    def test_split(self):
+        split = strop.split
+        self.assert_(split("this is the split function")
+                     == ['this', 'is', 'the', 'split', 'function'])
+        self.assert_(split("a|b|c|d", '|') == ['a', 'b', 'c', 'd'])
+        self.assert_(split("a|b|c|d", '|', 2) == ['a', 'b', 'c|d'])
+        self.assert_(split("a b c d", None, 1) == ['a', 'b c d'])
+        self.assert_(split("a b c d", None, 2) == ['a', 'b', 'c d'])
+        self.assert_(split("a b c d", None, 3) == ['a', 'b', 'c', 'd'])
+        self.assert_(split("a b c d", None, 4) == ['a', 'b', 'c', 'd'])
+        self.assert_(split("a b c d", None, 0) == ['a', 'b', 'c', 'd'])
+        self.assert_(split("a  b  c  d", None, 2) ==  ['a', 'b', 'c  d'])
+
+    def test_join(self):
+        self.assert_(strop.join(['a', 'b', 'c', 'd']) == 'a b c d')
+        self.assert_(strop.join(('a', 'b', 'c', 'd'), '') == 'abcd')
+        self.assert_(strop.join(Sequence()) == 'w x y z')
+
+        # try a few long ones
+        self.assert_(strop.join(['x' * 100] * 100, ':')
+                     == (('x' * 100) + ":") * 99 + "x" * 100)
+        self.assert_(strop.join(('x' * 100,) * 100, ':')
+                     == (('x' * 100) + ":") * 99 + "x" * 100)
+
+    def test_maketrans(self):
+        self.assert_(strop.maketrans("abc", "xyz") == transtable)
+        self.assertRaises(ValueError, strop.maketrans, "abc", "xyzq")
+
+    def test_translate(self):
+        self.assert_(strop.translate("xyzabcdef", transtable, "def")
+                     == "xyzxyz")
+
+    def test_data_attributes(self):
+        strop.lowercase
+        strop.uppercase
+        strop.whitespace
+
+
+transtable = '\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037 !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`xyzdefghijklmnopqrstuvwxyz{|}~\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377'
+
+
+# join() now works with any sequence type.
+class Sequence:
+    def __init__(self): self.seq = 'wxyz'
+    def __len__(self): return len(self.seq)
+    def __getitem__(self, i): return self.seq[i]
+
+
+def test_main():
+    test_support.run_unittest(StropFunctionTestCase)
+
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_strptime.py
===================================================================
--- vendor/Python/current/Lib/test/test_strptime.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_strptime.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,523 @@
+"""PyUnit testing against strptime"""
+
+import unittest
+import time
+import locale
+import re
+import sys
+from test import test_support
+from datetime import date as datetime_date
+
+import _strptime
+
+class getlang_Tests(unittest.TestCase):
+    """Test _getlang"""
+    def test_basic(self):
+        self.failUnlessEqual(_strptime._getlang(), locale.getlocale(locale.LC_TIME))
+
+class LocaleTime_Tests(unittest.TestCase):
+    """Tests for _strptime.LocaleTime.
+
+    All values are lower-cased when stored in LocaleTime, so make sure to
+    compare values after running ``lower`` on them.
+
+    """
+
+    def setUp(self):
+        """Create time tuple based on current time."""
+        self.time_tuple = time.localtime()
+        self.LT_ins = _strptime.LocaleTime()
+
+    def compare_against_time(self, testing, directive, tuple_position,
+                             error_msg):
+        """Helper method that tests testing against directive based on the
+        tuple_position of time_tuple.  Uses error_msg as error message.
+
+        """
+        strftime_output = time.strftime(directive, self.time_tuple).lower()
+        comparison = testing[self.time_tuple[tuple_position]]
+        self.failUnless(strftime_output in testing, "%s: not found in tuple" %
+                                                    error_msg)
+        self.failUnless(comparison == strftime_output,
+                        "%s: position within tuple incorrect; %s != %s" %
+                        (error_msg, comparison, strftime_output))
+
+    def test_weekday(self):
+        # Make sure that full and abbreviated weekday names are correct in
+        # both string and position with tuple
+        self.compare_against_time(self.LT_ins.f_weekday, '%A', 6,
+                                  "Testing of full weekday name failed")
+        self.compare_against_time(self.LT_ins.a_weekday, '%a', 6,
+                                  "Testing of abbreviated weekday name failed")
+
+    def test_month(self):
+        # Test full and abbreviated month names; both string and position
+        # within the tuple
+        self.compare_against_time(self.LT_ins.f_month, '%B', 1,
+                                  "Testing against full month name failed")
+        self.compare_against_time(self.LT_ins.a_month, '%b', 1,
+                                  "Testing against abbreviated month name failed")
+
+    def test_am_pm(self):
+        # Make sure AM/PM representation done properly
+        strftime_output = time.strftime("%p", self.time_tuple).lower()
+        self.failUnless(strftime_output in self.LT_ins.am_pm,
+                        "AM/PM representation not in tuple")
+        if self.time_tuple[3] < 12: position = 0
+        else: position = 1
+        self.failUnless(strftime_output == self.LT_ins.am_pm[position],
+                        "AM/PM representation in the wrong position within the tuple")
+
+    def test_timezone(self):
+        # Make sure timezone is correct
+        timezone = time.strftime("%Z", self.time_tuple).lower()
+        if timezone:
+            self.failUnless(timezone in self.LT_ins.timezone[0] or \
+                            timezone in self.LT_ins.timezone[1],
+                            "timezone %s not found in %s" %
+                            (timezone, self.LT_ins.timezone))
+
+    def test_date_time(self):
+        # Check that LC_date_time, LC_date, and LC_time are correct
+        # the magic date is used so as to not have issues with %c when day of
+        #  the month is a single digit and has a leading space.  This is not an
+        #  issue since strptime still parses it correctly.  The problem is
+        #  testing these directives for correctness by comparing strftime
+        #  output.
+        magic_date = (1999, 3, 17, 22, 44, 55, 2, 76, 0)
+        strftime_output = time.strftime("%c", magic_date)
+        self.failUnless(strftime_output == time.strftime(self.LT_ins.LC_date_time,
+                                                         magic_date),
+                        "LC_date_time incorrect")
+        strftime_output = time.strftime("%x", magic_date)
+        self.failUnless(strftime_output == time.strftime(self.LT_ins.LC_date,
+                                                         magic_date),
+                        "LC_date incorrect")
+        strftime_output = time.strftime("%X", magic_date)
+        self.failUnless(strftime_output == time.strftime(self.LT_ins.LC_time,
+                                                         magic_date),
+                        "LC_time incorrect")
+        LT = _strptime.LocaleTime()
+        LT.am_pm = ('', '')
+        self.failUnless(LT.LC_time, "LocaleTime's LC directives cannot handle "
+                                    "empty strings")
+
+    def test_lang(self):
+        # Make sure lang is set to what _getlang() returns
+        # Assuming locale has not changed between now and when self.LT_ins was created
+        self.failUnlessEqual(self.LT_ins.lang, _strptime._getlang())
+
+
+class TimeRETests(unittest.TestCase):
+    """Tests for TimeRE."""
+
+    def setUp(self):
+        """Construct generic TimeRE object."""
+        self.time_re = _strptime.TimeRE()
+        self.locale_time = _strptime.LocaleTime()
+
+    def test_pattern(self):
+        # Test TimeRE.pattern
+        pattern_string = self.time_re.pattern(r"%a %A %d")
+        self.failUnless(pattern_string.find(self.locale_time.a_weekday[2]) != -1,
+                        "did not find abbreviated weekday in pattern string '%s'" %
+                         pattern_string)
+        self.failUnless(pattern_string.find(self.locale_time.f_weekday[4]) != -1,
+                        "did not find full weekday in pattern string '%s'" %
+                         pattern_string)
+        self.failUnless(pattern_string.find(self.time_re['d']) != -1,
+                        "did not find 'd' directive pattern string '%s'" %
+                         pattern_string)
+
+    def test_pattern_escaping(self):
+        # Make sure any characters in the format string that might be taken as
+        # regex syntax is escaped.
+        pattern_string = self.time_re.pattern("\d+")
+        self.failUnless(r"\\d\+" in pattern_string,
+                        "%s does not have re characters escaped properly" %
+                        pattern_string)
+
+    def test_compile(self):
+        # Check that compiled regex is correct
+        found = self.time_re.compile(r"%A").match(self.locale_time.f_weekday[6])
+        self.failUnless(found and found.group('A') == self.locale_time.f_weekday[6],
+                        "re object for '%A' failed")
+        compiled = self.time_re.compile(r"%a %b")
+        found = compiled.match("%s %s" % (self.locale_time.a_weekday[4],
+                               self.locale_time.a_month[4]))
+        self.failUnless(found,
+            "Match failed with '%s' regex and '%s' string" %
+             (compiled.pattern, "%s %s" % (self.locale_time.a_weekday[4],
+                                           self.locale_time.a_month[4])))
+        self.failUnless(found.group('a') == self.locale_time.a_weekday[4] and
+                         found.group('b') == self.locale_time.a_month[4],
+                        "re object couldn't find the abbreviated weekday month in "
+                         "'%s' using '%s'; group 'a' = '%s', group 'b' = %s'" %
+                         (found.string, found.re.pattern, found.group('a'),
+                          found.group('b')))
+        for directive in ('a','A','b','B','c','d','H','I','j','m','M','p','S',
+                          'U','w','W','x','X','y','Y','Z','%'):
+            compiled = self.time_re.compile("%" + directive)
+            found = compiled.match(time.strftime("%" + directive))
+            self.failUnless(found, "Matching failed on '%s' using '%s' regex" %
+                                    (time.strftime("%" + directive),
+                                     compiled.pattern))
+
+    def test_blankpattern(self):
+        # Make sure when tuple or something has no values no regex is generated.
+        # Fixes bug #661354
+        test_locale = _strptime.LocaleTime()
+        test_locale.timezone = (frozenset(), frozenset())
+        self.failUnless(_strptime.TimeRE(test_locale).pattern("%Z") == '',
+                        "with timezone == ('',''), TimeRE().pattern('%Z') != ''")
+
+    def test_matching_with_escapes(self):
+        # Make sure a format that requires escaping of characters works
+        compiled_re = self.time_re.compile("\w+ %m")
+        found = compiled_re.match("\w+ 10")
+        self.failUnless(found, "Escaping failed of format '\w+ 10'")
+
+    def test_locale_data_w_regex_metacharacters(self):
+        # Check that if locale data contains regex metacharacters they are
+        # escaped properly.
+        # Discovered by bug #1039270 .
+        locale_time = _strptime.LocaleTime()
+        locale_time.timezone = (frozenset(("utc", "gmt",
+                                            "Tokyo (standard time)")),
+                                frozenset("Tokyo (daylight time)"))
+        time_re = _strptime.TimeRE(locale_time)
+        self.failUnless(time_re.compile("%Z").match("Tokyo (standard time)"),
+                        "locale data that contains regex metacharacters is not"
+                        " properly escaped")
+
+class StrptimeTests(unittest.TestCase):
+    """Tests for _strptime.strptime."""
+
+    def setUp(self):
+        """Create testing time tuple."""
+        self.time_tuple = time.gmtime()
+
+    def test_ValueError(self):
+        # Make sure ValueError is raised when match fails or format is bad
+        self.assertRaises(ValueError, _strptime.strptime, data_string="%d",
+                          format="%A")
+        for bad_format in ("%", "% ", "%e"):
+            try:
+                _strptime.strptime("2005", bad_format)
+            except ValueError:
+                continue
+            except Exception, err:
+                self.fail("'%s' raised %s, not ValueError" %
+                            (bad_format, err.__class__.__name__))
+            else:
+                self.fail("'%s' did not raise ValueError" % bad_format)
+
+    def test_unconverteddata(self):
+        # Check ValueError is raised when there is unconverted data
+        self.assertRaises(ValueError, _strptime.strptime, "10 12", "%m")
+
+    def helper(self, directive, position):
+        """Helper fxn in testing."""
+        strf_output = time.strftime("%" + directive, self.time_tuple)
+        strp_output = _strptime.strptime(strf_output, "%" + directive)
+        self.failUnless(strp_output[position] == self.time_tuple[position],
+                        "testing of '%s' directive failed; '%s' -> %s != %s" %
+                         (directive, strf_output, strp_output[position],
+                          self.time_tuple[position]))
+
+    def test_year(self):
+        # Test that the year is handled properly
+        for directive in ('y', 'Y'):
+            self.helper(directive, 0)
+        # Must also make sure %y values are correct for bounds set by Open Group
+        for century, bounds in ((1900, ('69', '99')), (2000, ('00', '68'))):
+            for bound in bounds:
+                strp_output = _strptime.strptime(bound, '%y')
+                expected_result = century + int(bound)
+                self.failUnless(strp_output[0] == expected_result,
+                                "'y' test failed; passed in '%s' "
+                                "and returned '%s'" % (bound, strp_output[0]))
+
+    def test_month(self):
+        # Test for month directives
+        for directive in ('B', 'b', 'm'):
+            self.helper(directive, 1)
+
+    def test_day(self):
+        # Test for day directives
+        self.helper('d', 2)
+
+    def test_hour(self):
+        # Test hour directives
+        self.helper('H', 3)
+        strf_output = time.strftime("%I %p", self.time_tuple)
+        strp_output = _strptime.strptime(strf_output, "%I %p")
+        self.failUnless(strp_output[3] == self.time_tuple[3],
+                        "testing of '%%I %%p' directive failed; '%s' -> %s != %s" %
+                         (strf_output, strp_output[3], self.time_tuple[3]))
+
+    def test_minute(self):
+        # Test minute directives
+        self.helper('M', 4)
+
+    def test_second(self):
+        # Test second directives
+        self.helper('S', 5)
+
+    def test_weekday(self):
+        # Test weekday directives
+        for directive in ('A', 'a', 'w'):
+            self.helper(directive,6)
+
+    def test_julian(self):
+        # Test julian directives
+        self.helper('j', 7)
+
+    def test_timezone(self):
+        # Test timezone directives.
+        # When gmtime() is used with %Z, entire result of strftime() is empty.
+        # Check for equal timezone names deals with bad locale info when this
+        # occurs; first found in FreeBSD 4.4.
+        strp_output = _strptime.strptime("UTC", "%Z")
+        self.failUnlessEqual(strp_output.tm_isdst, 0)
+        strp_output = _strptime.strptime("GMT", "%Z")
+        self.failUnlessEqual(strp_output.tm_isdst, 0)
+        if sys.platform == "mac":
+            # Timezones don't really work on MacOS9
+            return
+        time_tuple = time.localtime()
+        strf_output = time.strftime("%Z")  #UTC does not have a timezone
+        strp_output = _strptime.strptime(strf_output, "%Z")
+        locale_time = _strptime.LocaleTime()
+        if time.tzname[0] != time.tzname[1] or not time.daylight:
+            self.failUnless(strp_output[8] == time_tuple[8],
+                            "timezone check failed; '%s' -> %s != %s" %
+                             (strf_output, strp_output[8], time_tuple[8]))
+        else:
+            self.failUnless(strp_output[8] == -1,
+                            "LocaleTime().timezone has duplicate values and "
+                             "time.daylight but timezone value not set to -1")
+
+    def test_bad_timezone(self):
+        # Explicitly test possibility of bad timezone;
+        # when time.tzname[0] == time.tzname[1] and time.daylight
+        if sys.platform == "mac":
+            return #MacOS9 has severely broken timezone support.
+        tz_name = time.tzname[0]
+        if tz_name.upper() in ("UTC", "GMT"):
+            return
+        try:
+            original_tzname = time.tzname
+            original_daylight = time.daylight
+            time.tzname = (tz_name, tz_name)
+            time.daylight = 1
+            tz_value = _strptime.strptime(tz_name, "%Z")[8]
+            self.failUnlessEqual(tz_value, -1,
+                    "%s lead to a timezone value of %s instead of -1 when "
+                    "time.daylight set to %s and passing in %s" %
+                    (time.tzname, tz_value, time.daylight, tz_name))
+        finally:
+            time.tzname = original_tzname
+            time.daylight = original_daylight
+
+    def test_date_time(self):
+        # Test %c directive
+        for position in range(6):
+            self.helper('c', position)
+
+    def test_date(self):
+        # Test %x directive
+        for position in range(0,3):
+            self.helper('x', position)
+
+    def test_time(self):
+        # Test %X directive
+        for position in range(3,6):
+            self.helper('X', position)
+
+    def test_percent(self):
+        # Make sure % signs are handled properly
+        strf_output = time.strftime("%m %% %Y", self.time_tuple)
+        strp_output = _strptime.strptime(strf_output, "%m %% %Y")
+        self.failUnless(strp_output[0] == self.time_tuple[0] and
+                         strp_output[1] == self.time_tuple[1],
+                        "handling of percent sign failed")
+
+    def test_caseinsensitive(self):
+        # Should handle names case-insensitively.
+        strf_output = time.strftime("%B", self.time_tuple)
+        self.failUnless(_strptime.strptime(strf_output.upper(), "%B"),
+                        "strptime does not handle ALL-CAPS names properly")
+        self.failUnless(_strptime.strptime(strf_output.lower(), "%B"),
+                        "strptime does not handle lowercase names properly")
+        self.failUnless(_strptime.strptime(strf_output.capitalize(), "%B"),
+                        "strptime does not handle capword names properly")
+
+    def test_defaults(self):
+        # Default return value should be (1900, 1, 1, 0, 0, 0, 0, 1, 0)
+        defaults = (1900, 1, 1, 0, 0, 0, 0, 1, -1)
+        strp_output = _strptime.strptime('1', '%m')
+        self.failUnless(strp_output == defaults,
+                        "Default values for strptime() are incorrect;"
+                        " %s != %s" % (strp_output, defaults))
+
+    def test_escaping(self):
+        # Make sure all characters that have regex significance are escaped.
+        # Parentheses are in a purposeful order; will cause an error of
+        # unbalanced parentheses when the regex is compiled if they are not
+        # escaped.
+        # Test instigated by bug #796149 .
+        need_escaping = ".^$*+?{}\[]|)("
+        self.failUnless(_strptime.strptime(need_escaping, need_escaping))
+
+class Strptime12AMPMTests(unittest.TestCase):
+    """Test a _strptime regression in '%I %p' at 12 noon (12 PM)"""
+
+    def test_twelve_noon_midnight(self):
+        eq = self.assertEqual
+        eq(time.strptime('12 PM', '%I %p')[3], 12)
+        eq(time.strptime('12 AM', '%I %p')[3], 0)
+        eq(_strptime.strptime('12 PM', '%I %p')[3], 12)
+        eq(_strptime.strptime('12 AM', '%I %p')[3], 0)
+
+
+class JulianTests(unittest.TestCase):
+    """Test a _strptime regression that all julian (1-366) are accepted"""
+
+    def test_all_julian_days(self):
+        eq = self.assertEqual
+        for i in range(1, 367):
+            # use 2004, since it is a leap year, we have 366 days
+            eq(_strptime.strptime('%d 2004' % i, '%j %Y')[7], i)
+
+class CalculationTests(unittest.TestCase):
+    """Test that strptime() fills in missing info correctly"""
+
+    def setUp(self):
+        self.time_tuple = time.gmtime()
+
+    def test_julian_calculation(self):
+        # Make sure that when Julian is missing that it is calculated
+        format_string = "%Y %m %d %H %M %S %w %Z"
+        result = _strptime.strptime(time.strftime(format_string, self.time_tuple),
+                                    format_string)
+        self.failUnless(result.tm_yday == self.time_tuple.tm_yday,
+                        "Calculation of tm_yday failed; %s != %s" %
+                         (result.tm_yday, self.time_tuple.tm_yday))
+
+    def test_gregorian_calculation(self):
+        # Test that Gregorian date can be calculated from Julian day
+        format_string = "%Y %H %M %S %w %j %Z"
+        result = _strptime.strptime(time.strftime(format_string, self.time_tuple),
+                                    format_string)
+        self.failUnless(result.tm_year == self.time_tuple.tm_year and
+                         result.tm_mon == self.time_tuple.tm_mon and
+                         result.tm_mday == self.time_tuple.tm_mday,
+                        "Calculation of Gregorian date failed;"
+                         "%s-%s-%s != %s-%s-%s" %
+                         (result.tm_year, result.tm_mon, result.tm_mday,
+                          self.time_tuple.tm_year, self.time_tuple.tm_mon,
+                          self.time_tuple.tm_mday))
+
+    def test_day_of_week_calculation(self):
+        # Test that the day of the week is calculated as needed
+        format_string = "%Y %m %d %H %S %j %Z"
+        result = _strptime.strptime(time.strftime(format_string, self.time_tuple),
+                                    format_string)
+        self.failUnless(result.tm_wday == self.time_tuple.tm_wday,
+                        "Calculation of day of the week failed;"
+                         "%s != %s" % (result.tm_wday, self.time_tuple.tm_wday))
+
+    def test_week_of_year_and_day_of_week_calculation(self):
+        # Should be able to infer date if given year, week of year (%U or %W)
+        # and day of the week
+        def test_helper(ymd_tuple, test_reason):
+            for directive in ('W', 'U'):
+                format_string = "%%Y %%%s %%w" % directive
+                dt_date = datetime_date(*ymd_tuple)
+                strp_input = dt_date.strftime(format_string)
+                strp_output = _strptime.strptime(strp_input, format_string)
+                self.failUnless(strp_output[:3] == ymd_tuple,
+                        "%s(%s) test failed w/ '%s': %s != %s (%s != %s)" %
+                            (test_reason, directive, strp_input,
+                                strp_output[:3], ymd_tuple,
+                                strp_output[7], dt_date.timetuple()[7]))
+        test_helper((1901, 1, 3), "week 0")
+        test_helper((1901, 1, 8), "common case")
+        test_helper((1901, 1, 13), "day on Sunday")
+        test_helper((1901, 1, 14), "day on Monday")
+        test_helper((1905, 1, 1), "Jan 1 on Sunday")
+        test_helper((1906, 1, 1), "Jan 1 on Monday")
+        test_helper((1906, 1, 7), "first Sunday in a year starting on Monday")
+        test_helper((1905, 12, 31), "Dec 31 on Sunday")
+        test_helper((1906, 12, 31), "Dec 31 on Monday")
+        test_helper((2008, 12, 29), "Monday in the last week of the year")
+        test_helper((2008, 12, 22), "Monday in the second-to-last week of the "
+                                    "year")
+        test_helper((1978, 10, 23), "randomly chosen date")
+        test_helper((2004, 12, 18), "randomly chosen date")
+        test_helper((1978, 10, 23), "year starting and ending on Monday while "
+                                        "date not on Sunday or Monday")
+        test_helper((1917, 12, 17), "year starting and ending on Monday with "
+                                        "a Monday not at the beginning or end "
+                                        "of the year")
+        test_helper((1917, 12, 31), "Dec 31 on Monday with year starting and "
+                                        "ending on Monday")
+        test_helper((2007, 01, 07), "First Sunday of 2007")
+        test_helper((2007, 01, 14), "Second Sunday of 2007")
+        test_helper((2006, 12, 31), "Last Sunday of 2006")
+        test_helper((2006, 12, 24), "Second to last Sunday of 2006")
+
+
+class CacheTests(unittest.TestCase):
+    """Test that caching works properly."""
+
+    def test_time_re_recreation(self):
+        # Make sure cache is recreated when current locale does not match what
+        # cached object was created with.
+        _strptime.strptime("10", "%d")
+        _strptime.strptime("2005", "%Y")
+        _strptime._TimeRE_cache.locale_time.lang = "Ni"
+        original_time_re = id(_strptime._TimeRE_cache)
+        _strptime.strptime("10", "%d")
+        self.failIfEqual(original_time_re, id(_strptime._TimeRE_cache))
+        self.failUnlessEqual(len(_strptime._regex_cache), 1)
+
+    def test_regex_cleanup(self):
+        # Make sure cached regexes are discarded when cache becomes "full".
+        try:
+            del _strptime._regex_cache['%d']
+        except KeyError:
+            pass
+        bogus_key = 0
+        while len(_strptime._regex_cache) <= _strptime._CACHE_MAX_SIZE:
+            _strptime._regex_cache[bogus_key] = None
+            bogus_key += 1
+        _strptime.strptime("10", "%d")
+        self.failUnlessEqual(len(_strptime._regex_cache), 1)
+
+    def test_new_localetime(self):
+        # A new LocaleTime instance should be created when a new TimeRE object
+        # is created.
+        locale_time_id = id(_strptime._TimeRE_cache.locale_time)
+        _strptime._TimeRE_cache.locale_time.lang = "Ni"
+        _strptime.strptime("10", "%d")
+        self.failIfEqual(locale_time_id,
+                         id(_strptime._TimeRE_cache.locale_time))
+
+
+def test_main():
+    test_support.run_unittest(
+        getlang_Tests,
+        LocaleTime_Tests,
+        TimeRETests,
+        StrptimeTests,
+        Strptime12AMPMTests,
+        JulianTests,
+        CalculationTests,
+        CacheTests
+    )
+
+
+if __name__ == '__main__':
+    test_main()

Added: vendor/Python/current/Lib/test/test_struct.py
===================================================================
--- vendor/Python/current/Lib/test/test_struct.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_struct.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,625 @@
+from test.test_support import TestFailed, verbose, verify, vereq
+import test.test_support
+import struct
+import array
+import warnings
+
+import sys
+ISBIGENDIAN = sys.byteorder == "big"
+del sys
+verify((struct.pack('=i', 1)[0] == chr(0)) == ISBIGENDIAN,
+       "bigendian determination appears wrong")
+
+try:
+    import _struct
+except ImportError:
+    PY_STRUCT_RANGE_CHECKING = 0
+    PY_STRUCT_OVERFLOW_MASKING = 1
+    PY_STRUCT_FLOAT_COERCE = 2
+else:
+    PY_STRUCT_RANGE_CHECKING = getattr(_struct, '_PY_STRUCT_RANGE_CHECKING', 0)
+    PY_STRUCT_OVERFLOW_MASKING = getattr(_struct, '_PY_STRUCT_OVERFLOW_MASKING', 0)
+    PY_STRUCT_FLOAT_COERCE = getattr(_struct, '_PY_STRUCT_FLOAT_COERCE', 0)
+
+def string_reverse(s):
+    return "".join(reversed(s))
+
+def bigendian_to_native(value):
+    if ISBIGENDIAN:
+        return value
+    else:
+        return string_reverse(value)
+
+def simple_err(func, *args):
+    try:
+        func(*args)
+    except struct.error:
+        pass
+    else:
+        raise TestFailed, "%s%s did not raise struct.error" % (
+            func.__name__, args)
+
+def any_err(func, *args):
+    try:
+        func(*args)
+    except (struct.error, TypeError):
+        pass
+    else:
+        raise TestFailed, "%s%s did not raise error" % (
+            func.__name__, args)
+
+def with_warning_restore(func):
+    def _with_warning_restore(*args, **kw):
+        # The `warnings` module doesn't have an advertised way to restore
+        # its filter list.  Cheat.
+        save_warnings_filters = warnings.filters[:]
+        # Grrr, we need this function to warn every time.  Without removing
+        # the warningregistry, running test_tarfile then test_struct would fail
+        # on 64-bit platforms.
+        globals = func.func_globals
+        if '__warningregistry__' in globals:
+            del globals['__warningregistry__']
+        warnings.filterwarnings("error", r"""^struct.*""", DeprecationWarning)
+        warnings.filterwarnings("error", r""".*format requires.*""",
+                                DeprecationWarning)
+        try:
+            return func(*args, **kw)
+        finally:
+            warnings.filters[:] = save_warnings_filters[:]
+    return _with_warning_restore
+
+def deprecated_err(func, *args):
+    try:
+        func(*args)
+    except (struct.error, TypeError):
+        pass
+    except DeprecationWarning:
+        if not PY_STRUCT_OVERFLOW_MASKING:
+            raise TestFailed, "%s%s expected to raise struct.error" % (
+                func.__name__, args)
+    else:
+        raise TestFailed, "%s%s did not raise error" % (
+            func.__name__, args)
+deprecated_err = with_warning_restore(deprecated_err)
+
+
+simple_err(struct.calcsize, 'Z')
+
+sz = struct.calcsize('i')
+if sz * 3 != struct.calcsize('iii'):
+    raise TestFailed, 'inconsistent sizes'
+
+fmt = 'cbxxxxxxhhhhiillffd'
+fmt3 = '3c3b18x12h6i6l6f3d'
+sz = struct.calcsize(fmt)
+sz3 = struct.calcsize(fmt3)
+if sz * 3 != sz3:
+    raise TestFailed, 'inconsistent sizes (3*%r -> 3*%d = %d, %r -> %d)' % (
+        fmt, sz, 3*sz, fmt3, sz3)
+
+simple_err(struct.pack, 'iii', 3)
+simple_err(struct.pack, 'i', 3, 3, 3)
+simple_err(struct.pack, 'i', 'foo')
+simple_err(struct.pack, 'P', 'foo')
+simple_err(struct.unpack, 'd', 'flap')
+s = struct.pack('ii', 1, 2)
+simple_err(struct.unpack, 'iii', s)
+simple_err(struct.unpack, 'i', s)
+
+c = 'a'
+b = 1
+h = 255
+i = 65535
+l = 65536
+f = 3.1415
+d = 3.1415
+
+for prefix in ('', '@', '<', '>', '=', '!'):
+    for format in ('xcbhilfd', 'xcBHILfd'):
+        format = prefix + format
+        if verbose:
+            print "trying:", format
+        s = struct.pack(format, c, b, h, i, l, f, d)
+        cp, bp, hp, ip, lp, fp, dp = struct.unpack(format, s)
+        if (cp != c or bp != b or hp != h or ip != i or lp != l or
+            int(100 * fp) != int(100 * f) or int(100 * dp) != int(100 * d)):
+            # ^^^ calculate only to two decimal places
+            raise TestFailed, "unpack/pack not transitive (%s, %s)" % (
+                str(format), str((cp, bp, hp, ip, lp, fp, dp)))
+
+# Test some of the new features in detail
+
+# (format, argument, big-endian result, little-endian result, asymmetric)
+tests = [
+    ('c', 'a', 'a', 'a', 0),
+    ('xc', 'a', '\0a', '\0a', 0),
+    ('cx', 'a', 'a\0', 'a\0', 0),
+    ('s', 'a', 'a', 'a', 0),
+    ('0s', 'helloworld', '', '', 1),
+    ('1s', 'helloworld', 'h', 'h', 1),
+    ('9s', 'helloworld', 'helloworl', 'helloworl', 1),
+    ('10s', 'helloworld', 'helloworld', 'helloworld', 0),
+    ('11s', 'helloworld', 'helloworld\0', 'helloworld\0', 1),
+    ('20s', 'helloworld', 'helloworld'+10*'\0', 'helloworld'+10*'\0', 1),
+    ('b', 7, '\7', '\7', 0),
+    ('b', -7, '\371', '\371', 0),
+    ('B', 7, '\7', '\7', 0),
+    ('B', 249, '\371', '\371', 0),
+    ('h', 700, '\002\274', '\274\002', 0),
+    ('h', -700, '\375D', 'D\375', 0),
+    ('H', 700, '\002\274', '\274\002', 0),
+    ('H', 0x10000-700, '\375D', 'D\375', 0),
+    ('i', 70000000, '\004,\035\200', '\200\035,\004', 0),
+    ('i', -70000000, '\373\323\342\200', '\200\342\323\373', 0),
+    ('I', 70000000L, '\004,\035\200', '\200\035,\004', 0),
+    ('I', 0x100000000L-70000000, '\373\323\342\200', '\200\342\323\373', 0),
+    ('l', 70000000, '\004,\035\200', '\200\035,\004', 0),
+    ('l', -70000000, '\373\323\342\200', '\200\342\323\373', 0),
+    ('L', 70000000L, '\004,\035\200', '\200\035,\004', 0),
+    ('L', 0x100000000L-70000000, '\373\323\342\200', '\200\342\323\373', 0),
+    ('f', 2.0, '@\000\000\000', '\000\000\000@', 0),
+    ('d', 2.0, '@\000\000\000\000\000\000\000',
+               '\000\000\000\000\000\000\000@', 0),
+    ('f', -2.0, '\300\000\000\000', '\000\000\000\300', 0),
+    ('d', -2.0, '\300\000\000\000\000\000\000\000',
+               '\000\000\000\000\000\000\000\300', 0),
+]
+
+for fmt, arg, big, lil, asy in tests:
+    if verbose:
+        print "%r %r %r %r" % (fmt, arg, big, lil)
+    for (xfmt, exp) in [('>'+fmt, big), ('!'+fmt, big), ('<'+fmt, lil),
+                        ('='+fmt, ISBIGENDIAN and big or lil)]:
+        res = struct.pack(xfmt, arg)
+        if res != exp:
+            raise TestFailed, "pack(%r, %r) -> %r # expected %r" % (
+                fmt, arg, res, exp)
+        n = struct.calcsize(xfmt)
+        if n != len(res):
+            raise TestFailed, "calcsize(%r) -> %d # expected %d" % (
+                xfmt, n, len(res))
+        rev = struct.unpack(xfmt, res)[0]
+        if rev != arg and not asy:
+            raise TestFailed, "unpack(%r, %r) -> (%r,) # expected (%r,)" % (
+                fmt, res, rev, arg)
+
+###########################################################################
+# Simple native q/Q tests.
+
+has_native_qQ = 1
+try:
+    struct.pack("q", 5)
+except struct.error:
+    has_native_qQ = 0
+
+if verbose:
+    print "Platform has native q/Q?", has_native_qQ and "Yes." or "No."
+
+any_err(struct.pack, "Q", -1)   # can't pack -1 as unsigned regardless
+simple_err(struct.pack, "q", "a")  # can't pack string as 'q' regardless
+simple_err(struct.pack, "Q", "a")  # ditto, but 'Q'
+
+def test_native_qQ():
+    bytes = struct.calcsize('q')
+    # The expected values here are in big-endian format, primarily because
+    # I'm on a little-endian machine and so this is the clearest way (for
+    # me) to force the code to get exercised.
+    for format, input, expected in (
+            ('q', -1, '\xff' * bytes),
+            ('q', 0, '\x00' * bytes),
+            ('Q', 0, '\x00' * bytes),
+            ('q', 1L, '\x00' * (bytes-1) + '\x01'),
+            ('Q', (1L << (8*bytes))-1, '\xff' * bytes),
+            ('q', (1L << (8*bytes-1))-1, '\x7f' + '\xff' * (bytes - 1))):
+        got = struct.pack(format, input)
+        native_expected = bigendian_to_native(expected)
+        verify(got == native_expected,
+               "%r-pack of %r gave %r, not %r" %
+                    (format, input, got, native_expected))
+        retrieved = struct.unpack(format, got)[0]
+        verify(retrieved == input,
+               "%r-unpack of %r gave %r, not %r" %
+                    (format, got, retrieved, input))
+
+if has_native_qQ:
+    test_native_qQ()
+
+###########################################################################
+# Standard integer tests (bBhHiIlLqQ).
+
+import binascii
+
+class IntTester:
+
+    # XXX Most std integer modes fail to test for out-of-range.
+    # The "i" and "l" codes appear to range-check OK on 32-bit boxes, but
+    # fail to check correctly on some 64-bit ones (Tru64 Unix + Compaq C
+    # reported by Mark Favas).
+    BUGGY_RANGE_CHECK = "bBhHiIlL"
+
+    def __init__(self, formatpair, bytesize):
+        assert len(formatpair) == 2
+        self.formatpair = formatpair
+        for direction in "<>!=":
+            for code in formatpair:
+                format = direction + code
+                verify(struct.calcsize(format) == bytesize)
+        self.bytesize = bytesize
+        self.bitsize = bytesize * 8
+        self.signed_code, self.unsigned_code = formatpair
+        self.unsigned_min = 0
+        self.unsigned_max = 2L**self.bitsize - 1
+        self.signed_min = -(2L**(self.bitsize-1))
+        self.signed_max = 2L**(self.bitsize-1) - 1
+
+    def test_one(self, x, pack=struct.pack,
+                          unpack=struct.unpack,
+                          unhexlify=binascii.unhexlify):
+        if verbose:
+            print "trying std", self.formatpair, "on", x, "==", hex(x)
+
+        # Try signed.
+        code = self.signed_code
+        if self.signed_min <= x <= self.signed_max:
+            # Try big-endian.
+            expected = long(x)
+            if x < 0:
+                expected += 1L << self.bitsize
+                assert expected > 0
+            expected = hex(expected)[2:-1] # chop "0x" and trailing 'L'
+            if len(expected) & 1:
+                expected = "0" + expected
+            expected = unhexlify(expected)
+            expected = "\x00" * (self.bytesize - len(expected)) + expected
+
+            # Pack work?
+            format = ">" + code
+            got = pack(format, x)
+            verify(got == expected,
+                   "'%s'-pack of %r gave %r, not %r" %
+                    (format, x, got, expected))
+
+            # Unpack work?
+            retrieved = unpack(format, got)[0]
+            verify(x == retrieved,
+                   "'%s'-unpack of %r gave %r, not %r" %
+                    (format, got, retrieved, x))
+
+            # Adding any byte should cause a "too big" error.
+            any_err(unpack, format, '\x01' + got)
+
+            # Try little-endian.
+            format = "<" + code
+            expected = string_reverse(expected)
+
+            # Pack work?
+            got = pack(format, x)
+            verify(got == expected,
+                   "'%s'-pack of %r gave %r, not %r" %
+                    (format, x, got, expected))
+
+            # Unpack work?
+            retrieved = unpack(format, got)[0]
+            verify(x == retrieved,
+                   "'%s'-unpack of %r gave %r, not %r" %
+                    (format, got, retrieved, x))
+
+            # Adding any byte should cause a "too big" error.
+            any_err(unpack, format, '\x01' + got)
+
+        else:
+            # x is out of range -- verify pack realizes that.
+            if not PY_STRUCT_RANGE_CHECKING and code in self.BUGGY_RANGE_CHECK:
+                if verbose:
+                    print "Skipping buggy range check for code", code
+            else:
+                deprecated_err(pack, ">" + code, x)
+                deprecated_err(pack, "<" + code, x)
+
+        # Much the same for unsigned.
+        code = self.unsigned_code
+        if self.unsigned_min <= x <= self.unsigned_max:
+            # Try big-endian.
+            format = ">" + code
+            expected = long(x)
+            expected = hex(expected)[2:-1] # chop "0x" and trailing 'L'
+            if len(expected) & 1:
+                expected = "0" + expected
+            expected = unhexlify(expected)
+            expected = "\x00" * (self.bytesize - len(expected)) + expected
+
+            # Pack work?
+            got = pack(format, x)
+            verify(got == expected,
+                   "'%s'-pack of %r gave %r, not %r" %
+                    (format, x, got, expected))
+
+            # Unpack work?
+            retrieved = unpack(format, got)[0]
+            verify(x == retrieved,
+                   "'%s'-unpack of %r gave %r, not %r" %
+                    (format, got, retrieved, x))
+
+            # Adding any byte should cause a "too big" error.
+            any_err(unpack, format, '\x01' + got)
+
+            # Try little-endian.
+            format = "<" + code
+            expected = string_reverse(expected)
+
+            # Pack work?
+            got = pack(format, x)
+            verify(got == expected,
+                   "'%s'-pack of %r gave %r, not %r" %
+                    (format, x, got, expected))
+
+            # Unpack work?
+            retrieved = unpack(format, got)[0]
+            verify(x == retrieved,
+                   "'%s'-unpack of %r gave %r, not %r" %
+                    (format, got, retrieved, x))
+
+            # Adding any byte should cause a "too big" error.
+            any_err(unpack, format, '\x01' + got)
+
+        else:
+            # x is out of range -- verify pack realizes that.
+            if not PY_STRUCT_RANGE_CHECKING and code in self.BUGGY_RANGE_CHECK:
+                if verbose:
+                    print "Skipping buggy range check for code", code
+            else:
+                deprecated_err(pack, ">" + code, x)
+                deprecated_err(pack, "<" + code, x)
+
+    def run(self):
+        from random import randrange
+
+        # Create all interesting powers of 2.
+        values = []
+        for exp in range(self.bitsize + 3):
+            values.append(1L << exp)
+
+        # Add some random values.
+        for i in range(self.bitsize):
+            val = 0L
+            for j in range(self.bytesize):
+                val = (val << 8) | randrange(256)
+            values.append(val)
+
+        # Try all those, and their negations, and +-1 from them.  Note
+        # that this tests all power-of-2 boundaries in range, and a few out
+        # of range, plus +-(2**n +- 1).
+        for base in values:
+            for val in -base, base:
+                for incr in -1, 0, 1:
+                    x = val + incr
+                    try:
+                        x = int(x)
+                    except OverflowError:
+                        pass
+                    self.test_one(x)
+
+        # Some error cases.
+        for direction in "<>":
+            for code in self.formatpair:
+                for badobject in "a string", 3+42j, randrange:
+                    any_err(struct.pack, direction + code, badobject)
+
+for args in [("bB", 1),
+             ("hH", 2),
+             ("iI", 4),
+             ("lL", 4),
+             ("qQ", 8)]:
+    t = IntTester(*args)
+    t.run()
+
+
+###########################################################################
+# The p ("Pascal string") code.
+
+def test_p_code():
+    for code, input, expected, expectedback in [
+            ('p','abc', '\x00', ''),
+            ('1p', 'abc', '\x00', ''),
+            ('2p', 'abc', '\x01a', 'a'),
+            ('3p', 'abc', '\x02ab', 'ab'),
+            ('4p', 'abc', '\x03abc', 'abc'),
+            ('5p', 'abc', '\x03abc\x00', 'abc'),
+            ('6p', 'abc', '\x03abc\x00\x00', 'abc'),
+            ('1000p', 'x'*1000, '\xff' + 'x'*999, 'x'*255)]:
+        got = struct.pack(code, input)
+        if got != expected:
+            raise TestFailed("pack(%r, %r) == %r but expected %r" %
+                             (code, input, got, expected))
+        (got,) = struct.unpack(code, got)
+        if got != expectedback:
+            raise TestFailed("unpack(%r, %r) == %r but expected %r" %
+                             (code, input, got, expectedback))
+
+test_p_code()
+
+
+###########################################################################
+# SF bug 705836.  "<f" and ">f" had a severe rounding bug, where a carry
+# from the low-order discarded bits could propagate into the exponent
+# field, causing the result to be wrong by a factor of 2.
+
+def test_705836():
+    import math
+
+    for base in range(1, 33):
+        # smaller <- largest representable float less than base.
+        delta = 0.5
+        while base - delta / 2.0 != base:
+            delta /= 2.0
+        smaller = base - delta
+        # Packing this rounds away a solid string of trailing 1 bits.
+        packed = struct.pack("<f", smaller)
+        unpacked = struct.unpack("<f", packed)[0]
+        # This failed at base = 2, 4, and 32, with unpacked = 1, 2, and
+        # 16, respectively.
+        verify(base == unpacked)
+        bigpacked = struct.pack(">f", smaller)
+        verify(bigpacked == string_reverse(packed),
+               ">f pack should be byte-reversal of <f pack")
+        unpacked = struct.unpack(">f", bigpacked)[0]
+        verify(base == unpacked)
+
+    # Largest finite IEEE single.
+    big = (1 << 24) - 1
+    big = math.ldexp(big, 127 - 23)
+    packed = struct.pack(">f", big)
+    unpacked = struct.unpack(">f", packed)[0]
+    verify(big == unpacked)
+
+    # The same, but tack on a 1 bit so it rounds up to infinity.
+    big = (1 << 25) - 1
+    big = math.ldexp(big, 127 - 24)
+    try:
+        packed = struct.pack(">f", big)
+    except OverflowError:
+        pass
+    else:
+        TestFailed("expected OverflowError")
+
+test_705836()
+
+###########################################################################
+# SF bug 1229380. No struct.pack exception for some out of range integers
+
+def test_1229380():
+    import sys
+    for endian in ('', '>', '<'):
+        for cls in (int, long):
+            for fmt in ('B', 'H', 'I', 'L'):
+                deprecated_err(struct.pack, endian + fmt, cls(-1))
+
+            deprecated_err(struct.pack, endian + 'B', cls(300))
+            deprecated_err(struct.pack, endian + 'H', cls(70000))
+
+        deprecated_err(struct.pack, endian + 'I', sys.maxint * 4L)
+        deprecated_err(struct.pack, endian + 'L', sys.maxint * 4L)
+
+if PY_STRUCT_RANGE_CHECKING:
+    test_1229380()
+
+###########################################################################
+# SF bug 1530559. struct.pack raises TypeError where it used to convert.
+
+def check_float_coerce(format, number):
+    if PY_STRUCT_FLOAT_COERCE == 2:
+        # Test for pre-2.5 struct module
+        packed = struct.pack(format, number)
+        floored = struct.unpack(format, packed)[0]
+        if floored != int(number):
+            raise TestFailed("did not correcly coerce float to int")
+        return
+    try:
+        func(*args)
+    except (struct.error, TypeError):
+        if PY_STRUCT_FLOAT_COERCE:
+            raise TestFailed("expected DeprecationWarning for float coerce")
+    except DeprecationWarning:
+        if not PY_STRUCT_FLOAT_COERCE:
+            raise TestFailed("expected to raise struct.error for float coerce")
+    else:
+        raise TestFailed("did not raise error for float coerce")
+
+check_float_coerce = with_warning_restore(deprecated_err)
+
+def test_1530559():
+    for endian in ('', '>', '<'):
+        for fmt in ('B', 'H', 'I', 'L', 'b', 'h', 'i', 'l'):
+            check_float_coerce(endian + fmt, 1.0)
+            check_float_coerce(endian + fmt, 1.5)
+
+test_1530559()
+
+###########################################################################
+# Packing and unpacking to/from buffers.
+
+# Copied and modified from unittest.
+def assertRaises(excClass, callableObj, *args, **kwargs):
+    try:
+        callableObj(*args, **kwargs)
+    except excClass:
+        return
+    else:
+        raise TestFailed("%s not raised." % excClass)
+
+def test_unpack_from():
+    test_string = 'abcd01234'
+    fmt = '4s'
+    s = struct.Struct(fmt)
+    for cls in (str, buffer):
+        data = cls(test_string)
+        vereq(s.unpack_from(data), ('abcd',))
+        vereq(s.unpack_from(data, 2), ('cd01',))
+        vereq(s.unpack_from(data, 4), ('0123',))
+        for i in xrange(6):
+            vereq(s.unpack_from(data, i), (data[i:i+4],))
+        for i in xrange(6, len(test_string) + 1):
+            simple_err(s.unpack_from, data, i)
+    for cls in (str, buffer):
+        data = cls(test_string)
+        vereq(struct.unpack_from(fmt, data), ('abcd',))
+        vereq(struct.unpack_from(fmt, data, 2), ('cd01',))
+        vereq(struct.unpack_from(fmt, data, 4), ('0123',))
+        for i in xrange(6):
+            vereq(struct.unpack_from(fmt, data, i), (data[i:i+4],))
+        for i in xrange(6, len(test_string) + 1):
+            simple_err(struct.unpack_from, fmt, data, i)
+
+def test_pack_into():
+    test_string = 'Reykjavik rocks, eow!'
+    writable_buf = array.array('c', ' '*100)
+    fmt = '21s'
+    s = struct.Struct(fmt)
+
+    # Test without offset
+    s.pack_into(writable_buf, 0, test_string)
+    from_buf = writable_buf.tostring()[:len(test_string)]
+    vereq(from_buf, test_string)
+
+    # Test with offset.
+    s.pack_into(writable_buf, 10, test_string)
+    from_buf = writable_buf.tostring()[:len(test_string)+10]
+    vereq(from_buf, test_string[:10] + test_string)
+
+    # Go beyond boundaries.
+    small_buf = array.array('c', ' '*10)
+    assertRaises(struct.error, s.pack_into, small_buf, 0, test_string)
+    assertRaises(struct.error, s.pack_into, small_buf, 2, test_string)
+
+def test_pack_into_fn():
+    test_string = 'Reykjavik rocks, eow!'
+    writable_buf = array.array('c', ' '*100)
+    fmt = '21s'
+    pack_into = lambda *args: struct.pack_into(fmt, *args)
+
+    # Test without offset.
+    pack_into(writable_buf, 0, test_string)
+    from_buf = writable_buf.tostring()[:len(test_string)]
+    vereq(from_buf, test_string)
+
+    # Test with offset.
+    pack_into(writable_buf, 10, test_string)
+    from_buf = writable_buf.tostring()[:len(test_string)+10]
+    vereq(from_buf, test_string[:10] + test_string)
+
+    # Go beyond boundaries.
+    small_buf = array.array('c', ' '*10)
+    assertRaises(struct.error, pack_into, small_buf, 0, test_string)
+    assertRaises(struct.error, pack_into, small_buf, 2, test_string)
+
+def test_unpack_with_buffer():
+    # SF bug 1563759: struct.unpack doens't support buffer protocol objects
+    data = array.array('B', '\x12\x34\x56\x78')
+    value, = struct.unpack('>I', data)
+    vereq(value, 0x12345678)
+
+# Test methods to pack and unpack from buffers rather than strings.
+test_unpack_from()
+test_pack_into()
+test_pack_into_fn()
+test_unpack_with_buffer()

Added: vendor/Python/current/Lib/test/test_structmembers.py
===================================================================
--- vendor/Python/current/Lib/test/test_structmembers.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_structmembers.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,48 @@
+from _testcapi import test_structmembersType, \
+    CHAR_MAX, CHAR_MIN, UCHAR_MAX, \
+    SHRT_MAX, SHRT_MIN, USHRT_MAX, \
+    INT_MAX, INT_MIN, UINT_MAX, \
+    LONG_MAX, LONG_MIN, ULONG_MAX
+
+import warnings, exceptions, unittest, test.test_warnings
+from test import test_support
+
+ts=test_structmembersType(1,2,3,4,5,6,7,8,9.99999,10.1010101010)
+
+class ReadWriteTests(unittest.TestCase):
+    def test_types(self):
+        ts.T_BYTE=CHAR_MAX
+        self.assertEquals(ts.T_BYTE, CHAR_MAX)
+        ts.T_BYTE=CHAR_MIN
+        self.assertEquals(ts.T_BYTE, CHAR_MIN)
+        ts.T_UBYTE=UCHAR_MAX
+        self.assertEquals(ts.T_UBYTE, UCHAR_MAX)
+
+        ts.T_SHORT=SHRT_MAX
+        self.assertEquals(ts.T_SHORT, SHRT_MAX)
+        ts.T_SHORT=SHRT_MIN
+        self.assertEquals(ts.T_SHORT, SHRT_MIN)
+        ts.T_USHORT=USHRT_MAX
+        self.assertEquals(ts.T_USHORT, USHRT_MAX)
+
+        ts.T_INT=INT_MAX
+        self.assertEquals(ts.T_INT, INT_MAX)
+        ts.T_INT=INT_MIN
+        self.assertEquals(ts.T_INT, INT_MIN)
+        ts.T_UINT=UINT_MAX
+        self.assertEquals(ts.T_UINT, UINT_MAX)
+
+        ts.T_LONG=LONG_MAX
+        self.assertEquals(ts.T_LONG, LONG_MAX)
+        ts.T_LONG=LONG_MIN
+        self.assertEquals(ts.T_LONG, LONG_MIN)
+        ts.T_ULONG=ULONG_MAX
+        self.assertEquals(ts.T_ULONG, ULONG_MAX)
+
+def test_main(verbose=None):
+    test_support.run_unittest(
+        ReadWriteTests
+        )
+
+if __name__ == "__main__":
+    test_main(verbose=True)

Added: vendor/Python/current/Lib/test/test_structseq.py
===================================================================
--- vendor/Python/current/Lib/test/test_structseq.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_structseq.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,104 @@
+import unittest
+from test import test_support
+
+import time
+
+class StructSeqTest(unittest.TestCase):
+
+    def test_tuple(self):
+        t = time.gmtime()
+        astuple = tuple(t)
+        self.assertEqual(len(t), len(astuple))
+        self.assertEqual(t, astuple)
+
+        # Check that slicing works the same way; at one point, slicing t[i:j] with
+        # 0 < i < j could produce NULLs in the result.
+        for i in xrange(-len(t), len(t)):
+            self.assertEqual(t[i:], astuple[i:])
+            for j in xrange(-len(t), len(t)):
+                self.assertEqual(t[i:j], astuple[i:j])
+
+        for j in xrange(-len(t), len(t)):
+            self.assertEqual(t[:j], astuple[:j])
+
+        self.assertRaises(IndexError, t.__getitem__, -len(t)-1)
+        self.assertRaises(IndexError, t.__getitem__, len(t))
+        for i in xrange(-len(t), len(t)-1):
+            self.assertEqual(t[i], astuple[i])
+
+    def test_repr(self):
+        t = time.gmtime()
+        repr(t)
+
+    def test_concat(self):
+        t1 = time.gmtime()
+        t2 = t1 + tuple(t1)
+        for i in xrange(len(t1)):
+            self.assertEqual(t2[i], t2[i+len(t1)])
+
+    def test_repeat(self):
+        t1 = time.gmtime()
+        t2 = 3 * t1
+        for i in xrange(len(t1)):
+            self.assertEqual(t2[i], t2[i+len(t1)])
+            self.assertEqual(t2[i], t2[i+2*len(t1)])
+
+    def test_contains(self):
+        t1 = time.gmtime()
+        for item in t1:
+            self.assert_(item in t1)
+        self.assert_(-42 not in t1)
+
+    def test_hash(self):
+        t1 = time.gmtime()
+        self.assertEqual(hash(t1), hash(tuple(t1)))
+
+    def test_cmp(self):
+        t1 = time.gmtime()
+        t2 = type(t1)(t1)
+        self.assertEqual(t1, t2)
+        self.assert_(not (t1 < t2))
+        self.assert_(t1 <= t2)
+        self.assert_(not (t1 > t2))
+        self.assert_(t1 >= t2)
+        self.assert_(not (t1 != t2))
+
+    def test_fields(self):
+        t = time.gmtime()
+        self.assertEqual(len(t), t.n_fields)
+        self.assertEqual(t.n_fields, t.n_sequence_fields+t.n_unnamed_fields)
+
+    def test_constructor(self):
+        t = time.struct_time
+
+        self.assertRaises(TypeError, t)
+        self.assertRaises(TypeError, t, None)
+        self.assertRaises(TypeError, t, "123")
+        self.assertRaises(TypeError, t, "123", dict={})
+        self.assertRaises(TypeError, t, "123456789", dict=None)
+
+        s = "123456789"
+        self.assertEqual("".join(t(s)), s)
+
+    def test_eviltuple(self):
+        class Exc(Exception):
+            pass
+
+        # Devious code could crash structseqs' contructors
+        class C:
+            def __getitem__(self, i):
+                raise Exc
+            def __len__(self):
+                return 9
+
+        self.assertRaises(Exc, time.struct_time, C())
+
+    def test_reduce(self):
+        t = time.gmtime()
+        x = t.__reduce__()
+
+def test_main():
+    test_support.run_unittest(StructSeqTest)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_subprocess.py
===================================================================
--- vendor/Python/current/Lib/test/test_subprocess.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_subprocess.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,653 @@
+import unittest
+from test import test_support
+import subprocess
+import sys
+import signal
+import os
+import tempfile
+import time
+import re
+
+mswindows = (sys.platform == "win32")
+
+#
+# Depends on the following external programs: Python
+#
+
+if mswindows:
+    SETBINARY = ('import msvcrt; msvcrt.setmode(sys.stdout.fileno(), '
+                                                'os.O_BINARY);')
+else:
+    SETBINARY = ''
+
+# In a debug build, stuff like "[6580 refs]" is printed to stderr at
+# shutdown time.  That frustrates tests trying to check stderr produced
+# from a spawned Python process.
+def remove_stderr_debug_decorations(stderr):
+    return re.sub(r"\[\d+ refs\]\r?\n?$", "", stderr)
+
+class ProcessTestCase(unittest.TestCase):
+    def setUp(self):
+        # Try to minimize the number of children we have so this test
+        # doesn't crash on some buildbots (Alphas in particular).
+        if hasattr(test_support, "reap_children"):
+            test_support.reap_children()
+
+    def tearDown(self):
+        # Try to minimize the number of children we have so this test
+        # doesn't crash on some buildbots (Alphas in particular).
+        if hasattr(test_support, "reap_children"):
+            test_support.reap_children()
+
+    def mkstemp(self):
+        """wrapper for mkstemp, calling mktemp if mkstemp is not available"""
+        if hasattr(tempfile, "mkstemp"):
+            return tempfile.mkstemp()
+        else:
+            fname = tempfile.mktemp()
+            return os.open(fname, os.O_RDWR|os.O_CREAT), fname
+
+    #
+    # Generic tests
+    #
+    def test_call_seq(self):
+        # call() function with sequence argument
+        rc = subprocess.call([sys.executable, "-c",
+                              "import sys; sys.exit(47)"])
+        self.assertEqual(rc, 47)
+
+    def test_check_call_zero(self):
+        # check_call() function with zero return code
+        rc = subprocess.check_call([sys.executable, "-c",
+                                    "import sys; sys.exit(0)"])
+        self.assertEqual(rc, 0)
+
+    def test_check_call_nonzero(self):
+        # check_call() function with non-zero return code
+        try:
+            subprocess.check_call([sys.executable, "-c",
+                                   "import sys; sys.exit(47)"])
+        except subprocess.CalledProcessError, e:
+            self.assertEqual(e.returncode, 47)
+        else:
+            self.fail("Expected CalledProcessError")
+
+    def test_call_kwargs(self):
+        # call() function with keyword args
+        newenv = os.environ.copy()
+        newenv["FRUIT"] = "banana"
+        rc = subprocess.call([sys.executable, "-c",
+                          'import sys, os;' \
+                          'sys.exit(os.getenv("FRUIT")=="banana")'],
+                        env=newenv)
+        self.assertEqual(rc, 1)
+
+    def test_stdin_none(self):
+        # .stdin is None when not redirected
+        p = subprocess.Popen([sys.executable, "-c", 'print "banana"'],
+                         stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+        p.wait()
+        self.assertEqual(p.stdin, None)
+
+    def test_stdout_none(self):
+        # .stdout is None when not redirected
+        p = subprocess.Popen([sys.executable, "-c",
+                             'print "    this bit of output is from a '
+                             'test of stdout in a different '
+                             'process ..."'],
+                             stdin=subprocess.PIPE, stderr=subprocess.PIPE)
+        p.wait()
+        self.assertEqual(p.stdout, None)
+
+    def test_stderr_none(self):
+        # .stderr is None when not redirected
+        p = subprocess.Popen([sys.executable, "-c", 'print "banana"'],
+                         stdin=subprocess.PIPE, stdout=subprocess.PIPE)
+        p.wait()
+        self.assertEqual(p.stderr, None)
+
+    def test_executable(self):
+        p = subprocess.Popen(["somethingyoudonthave",
+                              "-c", "import sys; sys.exit(47)"],
+                             executable=sys.executable)
+        p.wait()
+        self.assertEqual(p.returncode, 47)
+
+    def test_stdin_pipe(self):
+        # stdin redirection
+        p = subprocess.Popen([sys.executable, "-c",
+                         'import sys; sys.exit(sys.stdin.read() == "pear")'],
+                        stdin=subprocess.PIPE)
+        p.stdin.write("pear")
+        p.stdin.close()
+        p.wait()
+        self.assertEqual(p.returncode, 1)
+
+    def test_stdin_filedes(self):
+        # stdin is set to open file descriptor
+        tf = tempfile.TemporaryFile()
+        d = tf.fileno()
+        os.write(d, "pear")
+        os.lseek(d, 0, 0)
+        p = subprocess.Popen([sys.executable, "-c",
+                         'import sys; sys.exit(sys.stdin.read() == "pear")'],
+                         stdin=d)
+        p.wait()
+        self.assertEqual(p.returncode, 1)
+
+    def test_stdin_fileobj(self):
+        # stdin is set to open file object
+        tf = tempfile.TemporaryFile()
+        tf.write("pear")
+        tf.seek(0)
+        p = subprocess.Popen([sys.executable, "-c",
+                         'import sys; sys.exit(sys.stdin.read() == "pear")'],
+                         stdin=tf)
+        p.wait()
+        self.assertEqual(p.returncode, 1)
+
+    def test_stdout_pipe(self):
+        # stdout redirection
+        p = subprocess.Popen([sys.executable, "-c",
+                          'import sys; sys.stdout.write("orange")'],
+                         stdout=subprocess.PIPE)
+        self.assertEqual(p.stdout.read(), "orange")
+
+    def test_stdout_filedes(self):
+        # stdout is set to open file descriptor
+        tf = tempfile.TemporaryFile()
+        d = tf.fileno()
+        p = subprocess.Popen([sys.executable, "-c",
+                          'import sys; sys.stdout.write("orange")'],
+                         stdout=d)
+        p.wait()
+        os.lseek(d, 0, 0)
+        self.assertEqual(os.read(d, 1024), "orange")
+
+    def test_stdout_fileobj(self):
+        # stdout is set to open file object
+        tf = tempfile.TemporaryFile()
+        p = subprocess.Popen([sys.executable, "-c",
+                          'import sys; sys.stdout.write("orange")'],
+                         stdout=tf)
+        p.wait()
+        tf.seek(0)
+        self.assertEqual(tf.read(), "orange")
+
+    def test_stderr_pipe(self):
+        # stderr redirection
+        p = subprocess.Popen([sys.executable, "-c",
+                          'import sys; sys.stderr.write("strawberry")'],
+                         stderr=subprocess.PIPE)
+        self.assertEqual(remove_stderr_debug_decorations(p.stderr.read()),
+                         "strawberry")
+
+    def test_stderr_filedes(self):
+        # stderr is set to open file descriptor
+        tf = tempfile.TemporaryFile()
+        d = tf.fileno()
+        p = subprocess.Popen([sys.executable, "-c",
+                          'import sys; sys.stderr.write("strawberry")'],
+                         stderr=d)
+        p.wait()
+        os.lseek(d, 0, 0)
+        self.assertEqual(remove_stderr_debug_decorations(os.read(d, 1024)),
+                         "strawberry")
+
+    def test_stderr_fileobj(self):
+        # stderr is set to open file object
+        tf = tempfile.TemporaryFile()
+        p = subprocess.Popen([sys.executable, "-c",
+                          'import sys; sys.stderr.write("strawberry")'],
+                         stderr=tf)
+        p.wait()
+        tf.seek(0)
+        self.assertEqual(remove_stderr_debug_decorations(tf.read()),
+                         "strawberry")
+
+    def test_stdout_stderr_pipe(self):
+        # capture stdout and stderr to the same pipe
+        p = subprocess.Popen([sys.executable, "-c",
+                          'import sys;' \
+                          'sys.stdout.write("apple");' \
+                          'sys.stdout.flush();' \
+                          'sys.stderr.write("orange")'],
+                         stdout=subprocess.PIPE,
+                         stderr=subprocess.STDOUT)
+        output = p.stdout.read()
+        stripped = remove_stderr_debug_decorations(output)
+        self.assertEqual(stripped, "appleorange")
+
+    def test_stdout_stderr_file(self):
+        # capture stdout and stderr to the same open file
+        tf = tempfile.TemporaryFile()
+        p = subprocess.Popen([sys.executable, "-c",
+                          'import sys;' \
+                          'sys.stdout.write("apple");' \
+                          'sys.stdout.flush();' \
+                          'sys.stderr.write("orange")'],
+                         stdout=tf,
+                         stderr=tf)
+        p.wait()
+        tf.seek(0)
+        output = tf.read()
+        stripped = remove_stderr_debug_decorations(output)
+        self.assertEqual(stripped, "appleorange")
+
+    def test_stdout_filedes_of_stdout(self):
+        # stdout is set to 1 (#1531862).
+        cmd = r"import sys, os; sys.exit(os.write(sys.stdout.fileno(), '.\n'))"
+        rc = subprocess.call([sys.executable, "-c", cmd], stdout=1)
+        self.assertEquals(rc, 2)
+
+    def test_cwd(self):
+        tmpdir = os.getenv("TEMP", "/tmp")
+        # We cannot use os.path.realpath to canonicalize the path,
+        # since it doesn't expand Tru64 {memb} strings. See bug 1063571.
+        cwd = os.getcwd()
+        os.chdir(tmpdir)
+        tmpdir = os.getcwd()
+        os.chdir(cwd)
+        p = subprocess.Popen([sys.executable, "-c",
+                          'import sys,os;' \
+                          'sys.stdout.write(os.getcwd())'],
+                         stdout=subprocess.PIPE,
+                         cwd=tmpdir)
+        normcase = os.path.normcase
+        self.assertEqual(normcase(p.stdout.read()), normcase(tmpdir))
+
+    def test_env(self):
+        newenv = os.environ.copy()
+        newenv["FRUIT"] = "orange"
+        p = subprocess.Popen([sys.executable, "-c",
+                          'import sys,os;' \
+                          'sys.stdout.write(os.getenv("FRUIT"))'],
+                         stdout=subprocess.PIPE,
+                         env=newenv)
+        self.assertEqual(p.stdout.read(), "orange")
+
+    def test_communicate_stdin(self):
+        p = subprocess.Popen([sys.executable, "-c",
+                              'import sys; sys.exit(sys.stdin.read() == "pear")'],
+                             stdin=subprocess.PIPE)
+        p.communicate("pear")
+        self.assertEqual(p.returncode, 1)
+
+    def test_communicate_stdout(self):
+        p = subprocess.Popen([sys.executable, "-c",
+                              'import sys; sys.stdout.write("pineapple")'],
+                             stdout=subprocess.PIPE)
+        (stdout, stderr) = p.communicate()
+        self.assertEqual(stdout, "pineapple")
+        self.assertEqual(stderr, None)
+
+    def test_communicate_stderr(self):
+        p = subprocess.Popen([sys.executable, "-c",
+                              'import sys; sys.stderr.write("pineapple")'],
+                             stderr=subprocess.PIPE)
+        (stdout, stderr) = p.communicate()
+        self.assertEqual(stdout, None)
+        # When running with a pydebug build, the # of references is outputted
+        # to stderr, so just check if stderr at least started with "pinapple"
+        self.assert_(stderr.startswith("pineapple"))
+
+    def test_communicate(self):
+        p = subprocess.Popen([sys.executable, "-c",
+                          'import sys,os;' \
+                          'sys.stderr.write("pineapple");' \
+                          'sys.stdout.write(sys.stdin.read())'],
+                         stdin=subprocess.PIPE,
+                         stdout=subprocess.PIPE,
+                         stderr=subprocess.PIPE)
+        (stdout, stderr) = p.communicate("banana")
+        self.assertEqual(stdout, "banana")
+        self.assertEqual(remove_stderr_debug_decorations(stderr),
+                         "pineapple")
+
+    def test_communicate_returns(self):
+        # communicate() should return None if no redirection is active
+        p = subprocess.Popen([sys.executable, "-c",
+                              "import sys; sys.exit(47)"])
+        (stdout, stderr) = p.communicate()
+        self.assertEqual(stdout, None)
+        self.assertEqual(stderr, None)
+
+    def test_communicate_pipe_buf(self):
+        # communicate() with writes larger than pipe_buf
+        # This test will probably deadlock rather than fail, if
+        # communicate() does not work properly.
+        x, y = os.pipe()
+        if mswindows:
+            pipe_buf = 512
+        else:
+            pipe_buf = os.fpathconf(x, "PC_PIPE_BUF")
+        os.close(x)
+        os.close(y)
+        p = subprocess.Popen([sys.executable, "-c",
+                          'import sys,os;'
+                          'sys.stdout.write(sys.stdin.read(47));' \
+                          'sys.stderr.write("xyz"*%d);' \
+                          'sys.stdout.write(sys.stdin.read())' % pipe_buf],
+                         stdin=subprocess.PIPE,
+                         stdout=subprocess.PIPE,
+                         stderr=subprocess.PIPE)
+        string_to_write = "abc"*pipe_buf
+        (stdout, stderr) = p.communicate(string_to_write)
+        self.assertEqual(stdout, string_to_write)
+
+    def test_writes_before_communicate(self):
+        # stdin.write before communicate()
+        p = subprocess.Popen([sys.executable, "-c",
+                          'import sys,os;' \
+                          'sys.stdout.write(sys.stdin.read())'],
+                         stdin=subprocess.PIPE,
+                         stdout=subprocess.PIPE,
+                         stderr=subprocess.PIPE)
+        p.stdin.write("banana")
+        (stdout, stderr) = p.communicate("split")
+        self.assertEqual(stdout, "bananasplit")
+        self.assertEqual(remove_stderr_debug_decorations(stderr), "")
+
+    def test_universal_newlines(self):
+        p = subprocess.Popen([sys.executable, "-c",
+                          'import sys,os;' + SETBINARY +
+                          'sys.stdout.write("line1\\n");'
+                          'sys.stdout.flush();'
+                          'sys.stdout.write("line2\\r");'
+                          'sys.stdout.flush();'
+                          'sys.stdout.write("line3\\r\\n");'
+                          'sys.stdout.flush();'
+                          'sys.stdout.write("line4\\r");'
+                          'sys.stdout.flush();'
+                          'sys.stdout.write("\\nline5");'
+                          'sys.stdout.flush();'
+                          'sys.stdout.write("\\nline6");'],
+                         stdout=subprocess.PIPE,
+                         universal_newlines=1)
+        stdout = p.stdout.read()
+        if hasattr(file, 'newlines'):
+            # Interpreter with universal newline support
+            self.assertEqual(stdout,
+                             "line1\nline2\nline3\nline4\nline5\nline6")
+        else:
+            # Interpreter without universal newline support
+            self.assertEqual(stdout,
+                             "line1\nline2\rline3\r\nline4\r\nline5\nline6")
+
+    def test_universal_newlines_communicate(self):
+        # universal newlines through communicate()
+        p = subprocess.Popen([sys.executable, "-c",
+                          'import sys,os;' + SETBINARY +
+                          'sys.stdout.write("line1\\n");'
+                          'sys.stdout.flush();'
+                          'sys.stdout.write("line2\\r");'
+                          'sys.stdout.flush();'
+                          'sys.stdout.write("line3\\r\\n");'
+                          'sys.stdout.flush();'
+                          'sys.stdout.write("line4\\r");'
+                          'sys.stdout.flush();'
+                          'sys.stdout.write("\\nline5");'
+                          'sys.stdout.flush();'
+                          'sys.stdout.write("\\nline6");'],
+                         stdout=subprocess.PIPE, stderr=subprocess.PIPE,
+                         universal_newlines=1)
+        (stdout, stderr) = p.communicate()
+        if hasattr(file, 'newlines'):
+            # Interpreter with universal newline support
+            self.assertEqual(stdout,
+                             "line1\nline2\nline3\nline4\nline5\nline6")
+        else:
+            # Interpreter without universal newline support
+            self.assertEqual(stdout, "line1\nline2\rline3\r\nline4\r\nline5\nline6")
+
+    def test_no_leaking(self):
+        # Make sure we leak no resources
+        if not hasattr(test_support, "is_resource_enabled") \
+               or test_support.is_resource_enabled("subprocess") and not mswindows:
+            max_handles = 1026 # too much for most UNIX systems
+        else:
+            max_handles = 65
+        for i in range(max_handles):
+            p = subprocess.Popen([sys.executable, "-c",
+                    "import sys;sys.stdout.write(sys.stdin.read())"],
+                    stdin=subprocess.PIPE,
+                    stdout=subprocess.PIPE,
+                    stderr=subprocess.PIPE)
+            data = p.communicate("lime")[0]
+            self.assertEqual(data, "lime")
+
+
+    def test_list2cmdline(self):
+        self.assertEqual(subprocess.list2cmdline(['a b c', 'd', 'e']),
+                         '"a b c" d e')
+        self.assertEqual(subprocess.list2cmdline(['ab"c', '\\', 'd']),
+                         'ab\\"c \\ d')
+        self.assertEqual(subprocess.list2cmdline(['a\\\\\\b', 'de fg', 'h']),
+                         'a\\\\\\b "de fg" h')
+        self.assertEqual(subprocess.list2cmdline(['a\\"b', 'c', 'd']),
+                         'a\\\\\\"b c d')
+        self.assertEqual(subprocess.list2cmdline(['a\\\\b c', 'd', 'e']),
+                         '"a\\\\b c" d e')
+        self.assertEqual(subprocess.list2cmdline(['a\\\\b\\ c', 'd', 'e']),
+                         '"a\\\\b\\ c" d e')
+        self.assertEqual(subprocess.list2cmdline(['ab', '']),
+                         'ab ""')
+
+
+    def test_poll(self):
+        p = subprocess.Popen([sys.executable,
+                          "-c", "import time; time.sleep(1)"])
+        count = 0
+        while p.poll() is None:
+            time.sleep(0.1)
+            count += 1
+        # We expect that the poll loop probably went around about 10 times,
+        # but, based on system scheduling we can't control, it's possible
+        # poll() never returned None.  It "should be" very rare that it
+        # didn't go around at least twice.
+        self.assert_(count >= 2)
+        # Subsequent invocations should just return the returncode
+        self.assertEqual(p.poll(), 0)
+
+
+    def test_wait(self):
+        p = subprocess.Popen([sys.executable,
+                          "-c", "import time; time.sleep(2)"])
+        self.assertEqual(p.wait(), 0)
+        # Subsequent invocations should just return the returncode
+        self.assertEqual(p.wait(), 0)
+
+
+    def test_invalid_bufsize(self):
+        # an invalid type of the bufsize argument should raise
+        # TypeError.
+        try:
+            subprocess.Popen([sys.executable, "-c", "pass"], "orange")
+        except TypeError:
+            pass
+        else:
+            self.fail("Expected TypeError")
+
+    #
+    # POSIX tests
+    #
+    if not mswindows:
+        def test_exceptions(self):
+            # catched & re-raised exceptions
+            try:
+                p = subprocess.Popen([sys.executable, "-c", ""],
+                                 cwd="/this/path/does/not/exist")
+            except OSError, e:
+                # The attribute child_traceback should contain "os.chdir"
+                # somewhere.
+                self.assertNotEqual(e.child_traceback.find("os.chdir"), -1)
+            else:
+                self.fail("Expected OSError")
+
+        def _suppress_core_files(self):
+            """Try to prevent core files from being created.
+            Returns previous ulimit if successful, else None.
+            """
+            try:
+                import resource
+                old_limit = resource.getrlimit(resource.RLIMIT_CORE)
+                resource.setrlimit(resource.RLIMIT_CORE, (0,0))
+                return old_limit
+            except (ImportError, ValueError, resource.error):
+                return None
+
+        def _unsuppress_core_files(self, old_limit):
+            """Return core file behavior to default."""
+            if old_limit is None:
+                return
+            try:
+                import resource
+                resource.setrlimit(resource.RLIMIT_CORE, old_limit)
+            except (ImportError, ValueError, resource.error):
+                return
+
+        def test_run_abort(self):
+            # returncode handles signal termination
+            old_limit = self._suppress_core_files()
+            try:
+                p = subprocess.Popen([sys.executable,
+                                      "-c", "import os; os.abort()"])
+            finally:
+                self._unsuppress_core_files(old_limit)
+            p.wait()
+            self.assertEqual(-p.returncode, signal.SIGABRT)
+
+        def test_preexec(self):
+            # preexec function
+            p = subprocess.Popen([sys.executable, "-c",
+                              'import sys,os;' \
+                              'sys.stdout.write(os.getenv("FRUIT"))'],
+                             stdout=subprocess.PIPE,
+                             preexec_fn=lambda: os.putenv("FRUIT", "apple"))
+            self.assertEqual(p.stdout.read(), "apple")
+
+        def test_args_string(self):
+            # args is a string
+            f, fname = self.mkstemp()
+            os.write(f, "#!/bin/sh\n")
+            os.write(f, "exec %s -c 'import sys; sys.exit(47)'\n" %
+                        sys.executable)
+            os.close(f)
+            os.chmod(fname, 0700)
+            p = subprocess.Popen(fname)
+            p.wait()
+            os.remove(fname)
+            self.assertEqual(p.returncode, 47)
+
+        def test_invalid_args(self):
+            # invalid arguments should raise ValueError
+            self.assertRaises(ValueError, subprocess.call,
+                              [sys.executable,
+                               "-c", "import sys; sys.exit(47)"],
+                              startupinfo=47)
+            self.assertRaises(ValueError, subprocess.call,
+                              [sys.executable,
+                               "-c", "import sys; sys.exit(47)"],
+                              creationflags=47)
+
+        def test_shell_sequence(self):
+            # Run command through the shell (sequence)
+            newenv = os.environ.copy()
+            newenv["FRUIT"] = "apple"
+            p = subprocess.Popen(["echo $FRUIT"], shell=1,
+                                 stdout=subprocess.PIPE,
+                                 env=newenv)
+            self.assertEqual(p.stdout.read().strip(), "apple")
+
+        def test_shell_string(self):
+            # Run command through the shell (string)
+            newenv = os.environ.copy()
+            newenv["FRUIT"] = "apple"
+            p = subprocess.Popen("echo $FRUIT", shell=1,
+                                 stdout=subprocess.PIPE,
+                                 env=newenv)
+            self.assertEqual(p.stdout.read().strip(), "apple")
+
+        def test_call_string(self):
+            # call() function with string argument on UNIX
+            f, fname = self.mkstemp()
+            os.write(f, "#!/bin/sh\n")
+            os.write(f, "exec %s -c 'import sys; sys.exit(47)'\n" %
+                        sys.executable)
+            os.close(f)
+            os.chmod(fname, 0700)
+            rc = subprocess.call(fname)
+            os.remove(fname)
+            self.assertEqual(rc, 47)
+
+
+    #
+    # Windows tests
+    #
+    if mswindows:
+        def test_startupinfo(self):
+            # startupinfo argument
+            # We uses hardcoded constants, because we do not want to
+            # depend on win32all.
+            STARTF_USESHOWWINDOW = 1
+            SW_MAXIMIZE = 3
+            startupinfo = subprocess.STARTUPINFO()
+            startupinfo.dwFlags = STARTF_USESHOWWINDOW
+            startupinfo.wShowWindow = SW_MAXIMIZE
+            # Since Python is a console process, it won't be affected
+            # by wShowWindow, but the argument should be silently
+            # ignored
+            subprocess.call([sys.executable, "-c", "import sys; sys.exit(0)"],
+                        startupinfo=startupinfo)
+
+        def test_creationflags(self):
+            # creationflags argument
+            CREATE_NEW_CONSOLE = 16
+            sys.stderr.write("    a DOS box should flash briefly ...\n")
+            subprocess.call(sys.executable +
+                                ' -c "import time; time.sleep(0.25)"',
+                            creationflags=CREATE_NEW_CONSOLE)
+
+        def test_invalid_args(self):
+            # invalid arguments should raise ValueError
+            self.assertRaises(ValueError, subprocess.call,
+                              [sys.executable,
+                               "-c", "import sys; sys.exit(47)"],
+                              preexec_fn=lambda: 1)
+            self.assertRaises(ValueError, subprocess.call,
+                              [sys.executable,
+                               "-c", "import sys; sys.exit(47)"],
+                              close_fds=True)
+
+        def test_shell_sequence(self):
+            # Run command through the shell (sequence)
+            newenv = os.environ.copy()
+            newenv["FRUIT"] = "physalis"
+            p = subprocess.Popen(["set"], shell=1,
+                                 stdout=subprocess.PIPE,
+                                 env=newenv)
+            self.assertNotEqual(p.stdout.read().find("physalis"), -1)
+
+        def test_shell_string(self):
+            # Run command through the shell (string)
+            newenv = os.environ.copy()
+            newenv["FRUIT"] = "physalis"
+            p = subprocess.Popen("set", shell=1,
+                                 stdout=subprocess.PIPE,
+                                 env=newenv)
+            self.assertNotEqual(p.stdout.read().find("physalis"), -1)
+
+        def test_call_string(self):
+            # call() function with string argument on Windows
+            rc = subprocess.call(sys.executable +
+                                 ' -c "import sys; sys.exit(47)"')
+            self.assertEqual(rc, 47)
+
+
+def test_main():
+    test_support.run_unittest(ProcessTestCase)
+    if hasattr(test_support, "reap_children"):
+        test_support.reap_children()
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_sunaudiodev.py
===================================================================
--- vendor/Python/current/Lib/test/test_sunaudiodev.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_sunaudiodev.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,28 @@
+from test.test_support import verbose, findfile, TestFailed, TestSkipped
+import sunaudiodev
+import os
+
+try:
+    audiodev = os.environ["AUDIODEV"]
+except KeyError:
+    audiodev = "/dev/audio"
+
+if not os.path.exists(audiodev):
+    raise TestSkipped("no audio device found!")
+
+def play_sound_file(path):
+    fp = open(path, 'r')
+    data = fp.read()
+    fp.close()
+    try:
+        a = sunaudiodev.open('w')
+    except sunaudiodev.error, msg:
+        raise TestFailed, msg
+    else:
+        a.write(data)
+        a.close()
+
+def test():
+    play_sound_file(findfile('audiotest.au'))
+
+test()

Added: vendor/Python/current/Lib/test/test_sundry.py
===================================================================
--- vendor/Python/current/Lib/test/test_sundry.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_sundry.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,77 @@
+"""Do a minimal test of all the modules that aren't otherwise tested."""
+
+import warnings
+warnings.filterwarnings('ignore', r".*posixfile module",
+                        DeprecationWarning, 'posixfile$')
+
+warnings.filterwarnings("ignore",
+                        "the gopherlib module is deprecated",
+                        DeprecationWarning,
+                        ".*test_sundry")
+
+from test.test_support import verbose
+
+import BaseHTTPServer
+import DocXMLRPCServer
+import CGIHTTPServer
+import SimpleHTTPServer
+import SimpleXMLRPCServer
+import aifc
+import audiodev
+import bdb
+import cgitb
+import cmd
+import code
+import compileall
+import encodings
+import formatter
+import ftplib
+import getpass
+import gopherlib
+import htmlentitydefs
+import ihooks
+import imghdr
+import imputil
+import keyword
+import linecache
+import macurl2path
+import mailcap
+import mimify
+import mutex
+import nntplib
+import nturl2path
+import opcode
+import os2emxpath
+import pdb
+import pipes
+#import poplib
+import posixfile
+import pstats
+import py_compile
+import pydoc
+import rexec
+import rlcompleter
+import sched
+import smtplib
+import sndhdr
+import statvfs
+import stringold
+import sunau
+import sunaudio
+import symbol
+import tabnanny
+import telnetlib
+import timeit
+import toaiff
+import token
+try:
+    import tty     # not available on Windows
+except ImportError:
+    if verbose:
+        print "skipping tty"
+
+# Can't test the "user" module -- if the user has a ~/.pythonrc.py, it
+# can screw up all sorts of things (esp. if it prints!).
+#import user
+import webbrowser
+import xml

Added: vendor/Python/current/Lib/test/test_support.py
===================================================================
--- vendor/Python/current/Lib/test/test_support.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_support.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,517 @@
+"""Supporting definitions for the Python regression tests."""
+
+if __name__ != 'test.test_support':
+    raise ImportError, 'test_support must be imported from the test package'
+
+import sys
+
+class Error(Exception):
+    """Base class for regression test exceptions."""
+
+class TestFailed(Error):
+    """Test failed."""
+
+class TestSkipped(Error):
+    """Test skipped.
+
+    This can be raised to indicate that a test was deliberatly
+    skipped, but not because a feature wasn't available.  For
+    example, if some resource can't be used, such as the network
+    appears to be unavailable, this should be raised instead of
+    TestFailed.
+    """
+
+class ResourceDenied(TestSkipped):
+    """Test skipped because it requested a disallowed resource.
+
+    This is raised when a test calls requires() for a resource that
+    has not be enabled.  It is used to distinguish between expected
+    and unexpected skips.
+    """
+
+verbose = 1              # Flag set to 0 by regrtest.py
+use_resources = None     # Flag set to [] by regrtest.py
+max_memuse = 0           # Disable bigmem tests (they will still be run with
+                         # small sizes, to make sure they work.)
+
+# _original_stdout is meant to hold stdout at the time regrtest began.
+# This may be "the real" stdout, or IDLE's emulation of stdout, or whatever.
+# The point is to have some flavor of stdout the user can actually see.
+_original_stdout = None
+def record_original_stdout(stdout):
+    global _original_stdout
+    _original_stdout = stdout
+
+def get_original_stdout():
+    return _original_stdout or sys.stdout
+
+def unload(name):
+    try:
+        del sys.modules[name]
+    except KeyError:
+        pass
+
+def unlink(filename):
+    import os
+    try:
+        os.unlink(filename)
+    except OSError:
+        pass
+
+def forget(modname):
+    '''"Forget" a module was ever imported by removing it from sys.modules and
+    deleting any .pyc and .pyo files.'''
+    unload(modname)
+    import os
+    for dirname in sys.path:
+        unlink(os.path.join(dirname, modname + os.extsep + 'pyc'))
+        # Deleting the .pyo file cannot be within the 'try' for the .pyc since
+        # the chance exists that there is no .pyc (and thus the 'try' statement
+        # is exited) but there is a .pyo file.
+        unlink(os.path.join(dirname, modname + os.extsep + 'pyo'))
+
+def is_resource_enabled(resource):
+    """Test whether a resource is enabled.  Known resources are set by
+    regrtest.py."""
+    return use_resources is not None and resource in use_resources
+
+def requires(resource, msg=None):
+    """Raise ResourceDenied if the specified resource is not available.
+
+    If the caller's module is __main__ then automatically return True.  The
+    possibility of False being returned occurs when regrtest.py is executing."""
+    # see if the caller's module is __main__ - if so, treat as if
+    # the resource was set
+    if sys._getframe().f_back.f_globals.get("__name__") == "__main__":
+        return
+    if not is_resource_enabled(resource):
+        if msg is None:
+            msg = "Use of the `%s' resource not enabled" % resource
+        raise ResourceDenied(msg)
+
+def bind_port(sock, host='', preferred_port=54321):
+    """Try to bind the sock to a port.  If we are running multiple
+    tests and we don't try multiple ports, the test can fails.  This
+    makes the test more robust."""
+
+    import socket, errno
+    # some random ports that hopefully no one is listening on.
+    for port in [preferred_port, 9907, 10243, 32999]:
+        try:
+            sock.bind((host, port))
+            return port
+        except socket.error, (err, msg):
+            if err != errno.EADDRINUSE:
+                raise
+            print >>sys.__stderr__, \
+                '  WARNING: failed to listen on port %d, trying another' % port
+    raise TestFailed, 'unable to find port to listen on'
+
+FUZZ = 1e-6
+
+def fcmp(x, y): # fuzzy comparison function
+    if type(x) == type(0.0) or type(y) == type(0.0):
+        try:
+            x, y = coerce(x, y)
+            fuzz = (abs(x) + abs(y)) * FUZZ
+            if abs(x-y) <= fuzz:
+                return 0
+        except:
+            pass
+    elif type(x) == type(y) and type(x) in (type(()), type([])):
+        for i in range(min(len(x), len(y))):
+            outcome = fcmp(x[i], y[i])
+            if outcome != 0:
+                return outcome
+        return cmp(len(x), len(y))
+    return cmp(x, y)
+
+try:
+    unicode
+    have_unicode = 1
+except NameError:
+    have_unicode = 0
+
+is_jython = sys.platform.startswith('java')
+
+import os
+# Filename used for testing
+if os.name == 'java':
+    # Jython disallows @ in module names
+    TESTFN = '$test'
+elif os.name == 'riscos':
+    TESTFN = 'testfile'
+else:
+    TESTFN = '@test'
+    # Unicode name only used if TEST_FN_ENCODING exists for the platform.
+    if have_unicode:
+        # Assuming sys.getfilesystemencoding()!=sys.getdefaultencoding()
+        # TESTFN_UNICODE is a filename that can be encoded using the
+        # file system encoding, but *not* with the default (ascii) encoding
+        if isinstance('', unicode):
+            # python -U
+            # XXX perhaps unicode() should accept Unicode strings?
+            TESTFN_UNICODE = "@test-\xe0\xf2"
+        else:
+            # 2 latin characters.
+            TESTFN_UNICODE = unicode("@test-\xe0\xf2", "latin-1")
+        TESTFN_ENCODING = sys.getfilesystemencoding()
+        # TESTFN_UNICODE_UNENCODEABLE is a filename that should *not* be
+        # able to be encoded by *either* the default or filesystem encoding.
+        # This test really only makes sense on Windows NT platforms
+        # which have special Unicode support in posixmodule.
+        if (not hasattr(sys, "getwindowsversion") or
+                sys.getwindowsversion()[3] < 2): #  0=win32s or 1=9x/ME
+            TESTFN_UNICODE_UNENCODEABLE = None
+        else:
+            # Japanese characters (I think - from bug 846133)
+            TESTFN_UNICODE_UNENCODEABLE = eval('u"@test-\u5171\u6709\u3055\u308c\u308b"')
+            try:
+                # XXX - Note - should be using TESTFN_ENCODING here - but for
+                # Windows, "mbcs" currently always operates as if in
+                # errors=ignore' mode - hence we get '?' characters rather than
+                # the exception.  'Latin1' operates as we expect - ie, fails.
+                # See [ 850997 ] mbcs encoding ignores errors
+                TESTFN_UNICODE_UNENCODEABLE.encode("Latin1")
+            except UnicodeEncodeError:
+                pass
+            else:
+                print \
+                'WARNING: The filename %r CAN be encoded by the filesystem.  ' \
+                'Unicode filename tests may not be effective' \
+                % TESTFN_UNICODE_UNENCODEABLE
+
+# Make sure we can write to TESTFN, try in /tmp if we can't
+fp = None
+try:
+    fp = open(TESTFN, 'w+')
+except IOError:
+    TMP_TESTFN = os.path.join('/tmp', TESTFN)
+    try:
+        fp = open(TMP_TESTFN, 'w+')
+        TESTFN = TMP_TESTFN
+        del TMP_TESTFN
+    except IOError:
+        print ('WARNING: tests will fail, unable to write to: %s or %s' %
+                (TESTFN, TMP_TESTFN))
+if fp is not None:
+    fp.close()
+    unlink(TESTFN)
+del os, fp
+
+def findfile(file, here=__file__):
+    """Try to find a file on sys.path and the working directory.  If it is not
+    found the argument passed to the function is returned (this does not
+    necessarily signal failure; could still be the legitimate path)."""
+    import os
+    if os.path.isabs(file):
+        return file
+    path = sys.path
+    path = [os.path.dirname(here)] + path
+    for dn in path:
+        fn = os.path.join(dn, file)
+        if os.path.exists(fn): return fn
+    return file
+
+def verify(condition, reason='test failed'):
+    """Verify that condition is true. If not, raise TestFailed.
+
+       The optional argument reason can be given to provide
+       a better error text.
+    """
+
+    if not condition:
+        raise TestFailed(reason)
+
+def vereq(a, b):
+    """Raise TestFailed if a == b is false.
+
+    This is better than verify(a == b) because, in case of failure, the
+    error message incorporates repr(a) and repr(b) so you can see the
+    inputs.
+
+    Note that "not (a == b)" isn't necessarily the same as "a != b"; the
+    former is tested.
+    """
+
+    if not (a == b):
+        raise TestFailed, "%r == %r" % (a, b)
+
+def sortdict(dict):
+    "Like repr(dict), but in sorted order."
+    items = dict.items()
+    items.sort()
+    reprpairs = ["%r: %r" % pair for pair in items]
+    withcommas = ", ".join(reprpairs)
+    return "{%s}" % withcommas
+
+def check_syntax(statement):
+    try:
+        compile(statement, '<string>', 'exec')
+    except SyntaxError:
+        pass
+    else:
+        print 'Missing SyntaxError: "%s"' % statement
+
+def open_urlresource(url):
+    import urllib, urlparse
+    import os.path
+
+    filename = urlparse.urlparse(url)[2].split('/')[-1] # '/': it's URL!
+
+    for path in [os.path.curdir, os.path.pardir]:
+        fn = os.path.join(path, filename)
+        if os.path.exists(fn):
+            return open(fn)
+
+    requires('urlfetch')
+    print >> get_original_stdout(), '\tfetching %s ...' % url
+    fn, _ = urllib.urlretrieve(url, filename)
+    return open(fn)
+
+#=======================================================================
+# Decorator for running a function in a different locale, correctly resetting
+# it afterwards.
+
+def run_with_locale(catstr, *locales):
+    def decorator(func):
+        def inner(*args, **kwds):
+            try:
+                import locale
+                category = getattr(locale, catstr)
+                orig_locale = locale.setlocale(category)
+            except AttributeError:
+                # if the test author gives us an invalid category string
+                raise
+            except:
+                # cannot retrieve original locale, so do nothing
+                locale = orig_locale = None
+            else:
+                for loc in locales:
+                    try:
+                        locale.setlocale(category, loc)
+                        break
+                    except:
+                        pass
+
+            # now run the function, resetting the locale on exceptions
+            try:
+                return func(*args, **kwds)
+            finally:
+                if locale and orig_locale:
+                    locale.setlocale(category, orig_locale)
+        inner.func_name = func.func_name
+        inner.__doc__ = func.__doc__
+        return inner
+    return decorator
+
+#=======================================================================
+# Big-memory-test support. Separate from 'resources' because memory use should be configurable.
+
+# Some handy shorthands. Note that these are used for byte-limits as well
+# as size-limits, in the various bigmem tests
+_1M = 1024*1024
+_1G = 1024 * _1M
+_2G = 2 * _1G
+
+# Hack to get at the maximum value an internal index can take.
+class _Dummy:
+    def __getslice__(self, i, j):
+        return j
+MAX_Py_ssize_t = _Dummy()[:]
+
+def set_memlimit(limit):
+    import re
+    global max_memuse
+    sizes = {
+        'k': 1024,
+        'm': _1M,
+        'g': _1G,
+        't': 1024*_1G,
+    }
+    m = re.match(r'(\d+(\.\d+)?) (K|M|G|T)b?$', limit,
+                 re.IGNORECASE | re.VERBOSE)
+    if m is None:
+        raise ValueError('Invalid memory limit %r' % (limit,))
+    memlimit = int(float(m.group(1)) * sizes[m.group(3).lower()])
+    if memlimit > MAX_Py_ssize_t:
+        memlimit = MAX_Py_ssize_t
+    if memlimit < _2G - 1:
+        raise ValueError('Memory limit %r too low to be useful' % (limit,))
+    max_memuse = memlimit
+
+def bigmemtest(minsize, memuse, overhead=5*_1M):
+    """Decorator for bigmem tests.
+
+    'minsize' is the minimum useful size for the test (in arbitrary,
+    test-interpreted units.) 'memuse' is the number of 'bytes per size' for
+    the test, or a good estimate of it. 'overhead' specifies fixed overhead,
+    independant of the testsize, and defaults to 5Mb.
+
+    The decorator tries to guess a good value for 'size' and passes it to
+    the decorated test function. If minsize * memuse is more than the
+    allowed memory use (as defined by max_memuse), the test is skipped.
+    Otherwise, minsize is adjusted upward to use up to max_memuse.
+    """
+    def decorator(f):
+        def wrapper(self):
+            if not max_memuse:
+                # If max_memuse is 0 (the default),
+                # we still want to run the tests with size set to a few kb,
+                # to make sure they work. We still want to avoid using
+                # too much memory, though, but we do that noisily.
+                maxsize = 5147
+                self.failIf(maxsize * memuse + overhead > 20 * _1M)
+            else:
+                maxsize = int((max_memuse - overhead) / memuse)
+                if maxsize < minsize:
+                    # Really ought to print 'test skipped' or something
+                    if verbose:
+                        sys.stderr.write("Skipping %s because of memory "
+                                         "constraint\n" % (f.__name__,))
+                    return
+                # Try to keep some breathing room in memory use
+                maxsize = max(maxsize - 50 * _1M, minsize)
+            return f(self, maxsize)
+        wrapper.minsize = minsize
+        wrapper.memuse = memuse
+        wrapper.overhead = overhead
+        return wrapper
+    return decorator
+
+def bigaddrspacetest(f):
+    """Decorator for tests that fill the address space."""
+    def wrapper(self):
+        if max_memuse < MAX_Py_ssize_t:
+            if verbose:
+                sys.stderr.write("Skipping %s because of memory "
+                                 "constraint\n" % (f.__name__,))
+        else:
+            return f(self)
+    return wrapper
+
+#=======================================================================
+# Preliminary PyUNIT integration.
+
+import unittest
+
+
+class BasicTestRunner:
+    def run(self, test):
+        result = unittest.TestResult()
+        test(result)
+        return result
+
+
+def run_suite(suite, testclass=None):
+    """Run tests from a unittest.TestSuite-derived class."""
+    if verbose:
+        runner = unittest.TextTestRunner(sys.stdout, verbosity=2)
+    else:
+        runner = BasicTestRunner()
+
+    result = runner.run(suite)
+    if not result.wasSuccessful():
+        if len(result.errors) == 1 and not result.failures:
+            err = result.errors[0][1]
+        elif len(result.failures) == 1 and not result.errors:
+            err = result.failures[0][1]
+        else:
+            if testclass is None:
+                msg = "errors occurred; run in verbose mode for details"
+            else:
+                msg = "errors occurred in %s.%s" \
+                      % (testclass.__module__, testclass.__name__)
+            raise TestFailed(msg)
+        raise TestFailed(err)
+
+
+def run_unittest(*classes):
+    """Run tests from unittest.TestCase-derived classes."""
+    suite = unittest.TestSuite()
+    for cls in classes:
+        if isinstance(cls, (unittest.TestSuite, unittest.TestCase)):
+            suite.addTest(cls)
+        else:
+            suite.addTest(unittest.makeSuite(cls))
+    if len(classes)==1:
+        testclass = classes[0]
+    else:
+        testclass = None
+    run_suite(suite, testclass)
+
+
+#=======================================================================
+# doctest driver.
+
+def run_doctest(module, verbosity=None):
+    """Run doctest on the given module.  Return (#failures, #tests).
+
+    If optional argument verbosity is not specified (or is None), pass
+    test_support's belief about verbosity on to doctest.  Else doctest's
+    usual behavior is used (it searches sys.argv for -v).
+    """
+
+    import doctest
+
+    if verbosity is None:
+        verbosity = verbose
+    else:
+        verbosity = None
+
+    # Direct doctest output (normally just errors) to real stdout; doctest
+    # output shouldn't be compared by regrtest.
+    save_stdout = sys.stdout
+    sys.stdout = get_original_stdout()
+    try:
+        f, t = doctest.testmod(module, verbose=verbosity)
+        if f:
+            raise TestFailed("%d of %d doctests failed" % (f, t))
+    finally:
+        sys.stdout = save_stdout
+    if verbose:
+        print 'doctest (%s) ... %d tests with zero failures' % (module.__name__, t)
+    return f, t
+
+#=======================================================================
+# Threading support to prevent reporting refleaks when running regrtest.py -R
+
+def threading_setup():
+    import threading
+    return len(threading._active), len(threading._limbo)
+
+def threading_cleanup(num_active, num_limbo):
+    import threading
+    import time
+
+    _MAX_COUNT = 10
+    count = 0
+    while len(threading._active) != num_active and count < _MAX_COUNT:
+        count += 1
+        time.sleep(0.1)
+
+    count = 0
+    while len(threading._limbo) != num_limbo and count < _MAX_COUNT:
+        count += 1
+        time.sleep(0.1)
+
+def reap_children():
+    """Use this function at the end of test_main() whenever sub-processes
+    are started.  This will help ensure that no extra children (zombies)
+    stick around to hog resources and create problems when looking
+    for refleaks.
+    """
+
+    # Reap all our dead child processes so we don't leave zombies around.
+    # These hog resources and might be causing some of the buildbots to die.
+    import os
+    if hasattr(os, 'waitpid'):
+        any_process = -1
+        while True:
+            try:
+                # This will raise an exception on Windows.  That's ok.
+                pid, status = os.waitpid(any_process, os.WNOHANG)
+                if pid == 0:
+                    break
+            except:
+                break

Added: vendor/Python/current/Lib/test/test_symtable.py
===================================================================
--- vendor/Python/current/Lib/test/test_symtable.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_symtable.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,44 @@
+from test import test_support
+
+import symtable
+import unittest
+
+
+## XXX
+## Test disabled because symtable module needs to be rewritten for new compiler
+
+##vereq(symbols[0].name, "global")
+##vereq(len([ste for ste in symbols.values() if ste.name == "f"]), 1)
+
+### Bug tickler: SyntaxError file name correct whether error raised
+### while parsing or building symbol table.
+##def checkfilename(brokencode):
+##    try:
+##        _symtable.symtable(brokencode, "spam", "exec")
+##    except SyntaxError, e:
+##        vereq(e.filename, "spam")
+##    else:
+##        raise TestFailed("no SyntaxError for %r" % (brokencode,))
+##checkfilename("def f(x): foo)(")  # parse-time
+##checkfilename("def f(x): global x")  # symtable-build-time
+
+class SymtableTest(unittest.TestCase):
+    def test_invalid_args(self):
+        self.assertRaises(TypeError, symtable.symtable, "42")
+        self.assertRaises(ValueError, symtable.symtable, "42", "?", "")
+
+    def test_eval(self):
+        symbols = symtable.symtable("42", "?", "eval")
+
+    def test_single(self):
+        symbols = symtable.symtable("42", "?", "single")
+
+    def test_exec(self):
+        symbols = symtable.symtable("def f(x): return x", "?", "exec")
+
+
+def test_main():
+    test_support.run_unittest(SymtableTest)
+
+if __name__ == '__main__':
+    test_main()

Added: vendor/Python/current/Lib/test/test_syntax.py
===================================================================
--- vendor/Python/current/Lib/test/test_syntax.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_syntax.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,500 @@
+"""This module tests SyntaxErrors.
+
+Here's an example of the sort of thing that is tested.
+
+>>> def f(x):
+...     global x
+Traceback (most recent call last):
+SyntaxError: name 'x' is local and global
+
+The tests are all raise SyntaxErrors.  They were created by checking
+each C call that raises SyntaxError.  There are several modules that
+raise these exceptions-- ast.c, compile.c, future.c, pythonrun.c, and
+symtable.c.
+
+The parser itself outlaws a lot of invalid syntax.  None of these
+errors are tested here at the moment.  We should add some tests; since
+there are infinitely many programs with invalid syntax, we would need
+to be judicious in selecting some.
+
+The compiler generates a synthetic module name for code executed by
+doctest.  Since all the code comes from the same module, a suffix like
+[1] is appended to the module name, As a consequence, changing the
+order of tests in this module means renumbering all the errors after
+it.  (Maybe we should enable the ellipsis option for these tests.)
+
+In ast.c, syntax errors are raised by calling ast_error().
+
+Errors from set_context():
+
+TODO(jhylton): "assignment to None" is inconsistent with other messages
+
+>>> obj.None = 1
+Traceback (most recent call last):
+SyntaxError: assignment to None (<doctest test.test_syntax[1]>, line 1)
+
+>>> None = 1
+Traceback (most recent call last):
+SyntaxError: assignment to None (<doctest test.test_syntax[2]>, line 1)
+
+It's a syntax error to assign to the empty tuple.  Why isn't it an
+error to assign to the empty list?  It will always raise some error at
+runtime.
+
+>>> () = 1
+Traceback (most recent call last):
+SyntaxError: can't assign to () (<doctest test.test_syntax[3]>, line 1)
+
+>>> f() = 1
+Traceback (most recent call last):
+SyntaxError: can't assign to function call (<doctest test.test_syntax[4]>, line 1)
+
+>>> del f()
+Traceback (most recent call last):
+SyntaxError: can't delete function call (<doctest test.test_syntax[5]>, line 1)
+
+>>> a + 1 = 2
+Traceback (most recent call last):
+SyntaxError: can't assign to operator (<doctest test.test_syntax[6]>, line 1)
+
+>>> (x for x in x) = 1
+Traceback (most recent call last):
+SyntaxError: can't assign to generator expression (<doctest test.test_syntax[7]>, line 1)
+
+>>> 1 = 1
+Traceback (most recent call last):
+SyntaxError: can't assign to literal (<doctest test.test_syntax[8]>, line 1)
+
+>>> "abc" = 1
+Traceback (most recent call last):
+SyntaxError: can't assign to literal (<doctest test.test_syntax[9]>, line 1)
+
+>>> `1` = 1
+Traceback (most recent call last):
+SyntaxError: can't assign to repr (<doctest test.test_syntax[10]>, line 1)
+
+If the left-hand side of an assignment is a list or tuple, an illegal
+expression inside that contain should still cause a syntax error.
+This test just checks a couple of cases rather than enumerating all of
+them.
+
+>>> (a, "b", c) = (1, 2, 3)
+Traceback (most recent call last):
+SyntaxError: can't assign to literal (<doctest test.test_syntax[11]>, line 1)
+
+>>> [a, b, c + 1] = [1, 2, 3]
+Traceback (most recent call last):
+SyntaxError: can't assign to operator (<doctest test.test_syntax[12]>, line 1)
+
+>>> a if 1 else b = 1
+Traceback (most recent call last):
+SyntaxError: can't assign to conditional expression (<doctest test.test_syntax[13]>, line 1)
+
+From compiler_complex_args():
+
+>>> def f(None=1):
+...     pass
+Traceback (most recent call last):
+SyntaxError: assignment to None (<doctest test.test_syntax[14]>, line 1)
+
+
+From ast_for_arguments():
+
+>>> def f(x, y=1, z):
+...     pass
+Traceback (most recent call last):
+SyntaxError: non-default argument follows default argument (<doctest test.test_syntax[15]>, line 1)
+
+>>> def f(x, None):
+...     pass
+Traceback (most recent call last):
+SyntaxError: assignment to None (<doctest test.test_syntax[16]>, line 1)
+
+>>> def f(*None):
+...     pass
+Traceback (most recent call last):
+SyntaxError: assignment to None (<doctest test.test_syntax[17]>, line 1)
+
+>>> def f(**None):
+...     pass
+Traceback (most recent call last):
+SyntaxError: assignment to None (<doctest test.test_syntax[18]>, line 1)
+
+
+From ast_for_funcdef():
+
+>>> def None(x):
+...     pass
+Traceback (most recent call last):
+SyntaxError: assignment to None (<doctest test.test_syntax[19]>, line 1)
+
+
+From ast_for_call():
+
+>>> def f(it, *varargs):
+...     return list(it)
+>>> L = range(10)
+>>> f(x for x in L)
+[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+>>> f(x for x in L, 1)
+Traceback (most recent call last):
+SyntaxError: Generator expression must be parenthesized if not sole argument (<doctest test.test_syntax[23]>, line 1)
+>>> f((x for x in L), 1)
+[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+
+>>> f(i0,  i1,  i2,  i3,  i4,  i5,  i6,  i7,  i8,  i9,  i10,  i11,
+...   i12,  i13,  i14,  i15,  i16,  i17,  i18,  i19,  i20,  i21,  i22,
+...   i23,  i24,  i25,  i26,  i27,  i28,  i29,  i30,  i31,  i32,  i33,
+...   i34,  i35,  i36,  i37,  i38,  i39,  i40,  i41,  i42,  i43,  i44,
+...   i45,  i46,  i47,  i48,  i49,  i50,  i51,  i52,  i53,  i54,  i55,
+...   i56,  i57,  i58,  i59,  i60,  i61,  i62,  i63,  i64,  i65,  i66,
+...   i67,  i68,  i69,  i70,  i71,  i72,  i73,  i74,  i75,  i76,  i77,
+...   i78,  i79,  i80,  i81,  i82,  i83,  i84,  i85,  i86,  i87,  i88,
+...   i89,  i90,  i91,  i92,  i93,  i94,  i95,  i96,  i97,  i98,  i99,
+...   i100,  i101,  i102,  i103,  i104,  i105,  i106,  i107,  i108,
+...   i109,  i110,  i111,  i112,  i113,  i114,  i115,  i116,  i117,
+...   i118,  i119,  i120,  i121,  i122,  i123,  i124,  i125,  i126,
+...   i127,  i128,  i129,  i130,  i131,  i132,  i133,  i134,  i135,
+...   i136,  i137,  i138,  i139,  i140,  i141,  i142,  i143,  i144,
+...   i145,  i146,  i147,  i148,  i149,  i150,  i151,  i152,  i153,
+...   i154,  i155,  i156,  i157,  i158,  i159,  i160,  i161,  i162,
+...   i163,  i164,  i165,  i166,  i167,  i168,  i169,  i170,  i171,
+...   i172,  i173,  i174,  i175,  i176,  i177,  i178,  i179,  i180,
+...   i181,  i182,  i183,  i184,  i185,  i186,  i187,  i188,  i189,
+...   i190,  i191,  i192,  i193,  i194,  i195,  i196,  i197,  i198,
+...   i199,  i200,  i201,  i202,  i203,  i204,  i205,  i206,  i207,
+...   i208,  i209,  i210,  i211,  i212,  i213,  i214,  i215,  i216,
+...   i217,  i218,  i219,  i220,  i221,  i222,  i223,  i224,  i225,
+...   i226,  i227,  i228,  i229,  i230,  i231,  i232,  i233,  i234,
+...   i235,  i236,  i237,  i238,  i239,  i240,  i241,  i242,  i243,
+...   i244,  i245,  i246,  i247,  i248,  i249,  i250,  i251,  i252,
+...   i253,  i254,  i255)
+Traceback (most recent call last):
+SyntaxError: more than 255 arguments (<doctest test.test_syntax[25]>, line 1)
+
+The actual error cases counts positional arguments, keyword arguments,
+and generator expression arguments separately.  This test combines the
+three.
+
+>>> f(i0,  i1,  i2,  i3,  i4,  i5,  i6,  i7,  i8,  i9,  i10,  i11,
+...   i12,  i13,  i14,  i15,  i16,  i17,  i18,  i19,  i20,  i21,  i22,
+...   i23,  i24,  i25,  i26,  i27,  i28,  i29,  i30,  i31,  i32,  i33,
+...   i34,  i35,  i36,  i37,  i38,  i39,  i40,  i41,  i42,  i43,  i44,
+...   i45,  i46,  i47,  i48,  i49,  i50,  i51,  i52,  i53,  i54,  i55,
+...   i56,  i57,  i58,  i59,  i60,  i61,  i62,  i63,  i64,  i65,  i66,
+...   i67,  i68,  i69,  i70,  i71,  i72,  i73,  i74,  i75,  i76,  i77,
+...   i78,  i79,  i80,  i81,  i82,  i83,  i84,  i85,  i86,  i87,  i88,
+...   i89,  i90,  i91,  i92,  i93,  i94,  i95,  i96,  i97,  i98,  i99,
+...   i100,  i101,  i102,  i103,  i104,  i105,  i106,  i107,  i108,
+...   i109,  i110,  i111,  i112,  i113,  i114,  i115,  i116,  i117,
+...   i118,  i119,  i120,  i121,  i122,  i123,  i124,  i125,  i126,
+...   i127,  i128,  i129,  i130,  i131,  i132,  i133,  i134,  i135,
+...   i136,  i137,  i138,  i139,  i140,  i141,  i142,  i143,  i144,
+...   i145,  i146,  i147,  i148,  i149,  i150,  i151,  i152,  i153,
+...   i154,  i155,  i156,  i157,  i158,  i159,  i160,  i161,  i162,
+...   i163,  i164,  i165,  i166,  i167,  i168,  i169,  i170,  i171,
+...   i172,  i173,  i174,  i175,  i176,  i177,  i178,  i179,  i180,
+...   i181,  i182,  i183,  i184,  i185,  i186,  i187,  i188,  i189,
+...   i190,  i191,  i192,  i193,  i194,  i195,  i196,  i197,  i198,
+...   i199,  i200,  i201,  i202,  i203,  i204,  i205,  i206,  i207,
+...   i208,  i209,  i210,  i211,  i212,  i213,  i214,  i215,  i216,
+...   i217,  i218,  i219,  i220,  i221,  i222,  i223,  i224,  i225,
+...   i226,  i227,  i228,  i229,  i230,  i231,  i232,  i233,  i234,
+...   i235, i236,  i237,  i238,  i239,  i240,  i241,  i242,  i243,
+...   (x for x in i244),  i245,  i246,  i247,  i248,  i249,  i250,  i251,
+...    i252=1, i253=1,  i254=1,  i255=1)
+Traceback (most recent call last):
+SyntaxError: more than 255 arguments (<doctest test.test_syntax[26]>, line 1)
+
+>>> f(lambda x: x[0] = 3)
+Traceback (most recent call last):
+SyntaxError: lambda cannot contain assignment (<doctest test.test_syntax[27]>, line 1)
+
+The grammar accepts any test (basically, any expression) in the
+keyword slot of a call site.  Test a few different options.
+
+>>> f(x()=2)
+Traceback (most recent call last):
+SyntaxError: keyword can't be an expression (<doctest test.test_syntax[28]>, line 1)
+>>> f(a or b=1)
+Traceback (most recent call last):
+SyntaxError: keyword can't be an expression (<doctest test.test_syntax[29]>, line 1)
+>>> f(x.y=1)
+Traceback (most recent call last):
+SyntaxError: keyword can't be an expression (<doctest test.test_syntax[30]>, line 1)
+
+
+From ast_for_expr_stmt():
+
+>>> (x for x in x) += 1
+Traceback (most recent call last):
+SyntaxError: augmented assignment to generator expression not possible (<doctest test.test_syntax[31]>, line 1)
+>>> None += 1
+Traceback (most recent call last):
+SyntaxError: assignment to None (<doctest test.test_syntax[32]>, line 1)
+>>> f() += 1
+Traceback (most recent call last):
+SyntaxError: illegal expression for augmented assignment (<doctest test.test_syntax[33]>, line 1)
+
+
+Test continue in finally in weird combinations.
+
+continue in for loop under finally shouuld be ok.
+
+    >>> def test():
+    ...     try:
+    ...         pass
+    ...     finally:
+    ...         for abc in range(10):
+    ...             continue
+    ...     print abc
+    >>> test()
+    9
+
+Start simple, a continue in a finally should not be allowed.
+
+    >>> def test():
+    ...    for abc in range(10):
+    ...        try:
+    ...            pass
+    ...        finally:
+    ...            continue
+    ...
+    Traceback (most recent call last):
+      ...
+    SyntaxError: 'continue' not supported inside 'finally' clause (<doctest test.test_syntax[36]>, line 6)
+
+This is essentially a continue in a finally which should not be allowed.
+
+    >>> def test():
+    ...    for abc in range(10):
+    ...        try:
+    ...            pass
+    ...        finally:
+    ...            try:
+    ...                continue
+    ...            except:
+    ...                pass
+    Traceback (most recent call last):
+      ...
+    SyntaxError: 'continue' not supported inside 'finally' clause (<doctest test.test_syntax[37]>, line 7)
+
+    >>> def foo():
+    ...   try:
+    ...     pass
+    ...   finally:
+    ...     continue
+    Traceback (most recent call last):
+      ...
+    SyntaxError: 'continue' not supported inside 'finally' clause (<doctest test.test_syntax[38]>, line 5)
+
+    >>> def foo():
+    ...   for a in ():
+    ...     try: pass
+    ...     finally: continue
+    Traceback (most recent call last):
+      ...
+    SyntaxError: 'continue' not supported inside 'finally' clause (<doctest test.test_syntax[39]>, line 4)
+
+    >>> def foo():
+    ...  for a in ():
+    ...   try: pass
+    ...   finally:
+    ...    try:
+    ...     continue
+    ...    finally: pass
+    Traceback (most recent call last):
+      ...
+    SyntaxError: 'continue' not supported inside 'finally' clause (<doctest test.test_syntax[40]>, line 6)
+
+    >>> def foo():
+    ...  for a in ():
+    ...   try: pass
+    ...   finally:
+    ...    try:
+    ...     pass
+    ...    except:
+    ...     continue
+    Traceback (most recent call last):
+      ...
+    SyntaxError: 'continue' not supported inside 'finally' clause (<doctest test.test_syntax[41]>, line 8)
+
+There is one test for a break that is not in a loop.  The compiler
+uses a single data structure to keep track of try-finally and loops,
+so we need to be sure that a break is actually inside a loop.  If it
+isn't, there should be a syntax error.
+
+   >>> try:
+   ...     print 1
+   ...     break
+   ...     print 2
+   ... finally:
+   ...     print 3
+   Traceback (most recent call last):
+     ...
+   SyntaxError: 'break' outside loop (<doctest test.test_syntax[42]>, line 3)
+
+This should probably raise a better error than a SystemError (or none at all).
+In 2.5 there was a missing exception and an assert was triggered in a debug
+build.  The number of blocks must be greater than CO_MAXBLOCKS.  SF #1565514
+
+   >>> while 1:
+   ...  while 2:
+   ...   while 3:
+   ...    while 4:
+   ...     while 5:
+   ...      while 6:
+   ...       while 8:
+   ...        while 9:
+   ...         while 10:
+   ...          while 11:
+   ...           while 12:
+   ...            while 13:
+   ...             while 14:
+   ...              while 15:
+   ...               while 16:
+   ...                while 17:
+   ...                 while 18:
+   ...                  while 19:
+   ...                   while 20:
+   ...                    while 21:
+   ...                     while 22:
+   ...                      break
+   Traceback (most recent call last):
+     ...
+   SystemError: too many statically nested blocks
+
+This tests assignment-context; there was a bug in Python 2.5 where compiling
+a complex 'if' (one with 'elif') would fail to notice an invalid suite,
+leading to spurious errors.
+
+   >>> if 1:
+   ...   x() = 1
+   ... elif 1:
+   ...   pass
+   Traceback (most recent call last):
+     ... 
+   SyntaxError: can't assign to function call (<doctest test.test_syntax[44]>, line 2)
+
+   >>> if 1:
+   ...   pass
+   ... elif 1:
+   ...   x() = 1
+   Traceback (most recent call last):
+     ... 
+   SyntaxError: can't assign to function call (<doctest test.test_syntax[45]>, line 4)
+
+   >>> if 1:
+   ...   x() = 1
+   ... elif 1:
+   ...   pass
+   ... else:
+   ...   pass
+   Traceback (most recent call last):
+     ... 
+   SyntaxError: can't assign to function call (<doctest test.test_syntax[46]>, line 2)
+
+   >>> if 1:
+   ...   pass
+   ... elif 1:
+   ...   x() = 1
+   ... else:
+   ...   pass
+   Traceback (most recent call last):
+     ... 
+   SyntaxError: can't assign to function call (<doctest test.test_syntax[47]>, line 4)
+
+   >>> if 1:
+   ...   pass
+   ... elif 1:
+   ...   pass
+   ... else:
+   ...   x() = 1
+   Traceback (most recent call last):
+     ... 
+   SyntaxError: can't assign to function call (<doctest test.test_syntax[48]>, line 6)
+
+"""
+
+import re
+import unittest
+import warnings
+
+from test import test_support
+
+class SyntaxTestCase(unittest.TestCase):
+
+    def _check_error(self, code, errtext,
+                     filename="<testcase>", mode="exec", subclass=None):
+        """Check that compiling code raises SyntaxError with errtext.
+
+        errtest is a regular expression that must be present in the
+        test of the exception raised.  If subclass is specified it
+        is the expected subclass of SyntaxError (e.g. IndentationError).
+        """
+        try:
+            compile(code, filename, mode)
+        except SyntaxError, err:
+            if subclass and not isinstance(err, subclass):
+                self.fail("SyntaxError is not a %s" % subclass.__name__)
+            mo = re.search(errtext, str(err))
+            if mo is None:
+                self.fail("SyntaxError did not contain '%r'" % (errtext,))
+        else:
+            self.fail("compile() did not raise SyntaxError")
+
+    def test_assign_call(self):
+        self._check_error("f() = 1", "assign")
+
+    def test_assign_del(self):
+        self._check_error("del f()", "delete")
+
+    def test_global_err_then_warn(self):
+        # Bug tickler:  The SyntaxError raised for one global statement
+        # shouldn't be clobbered by a SyntaxWarning issued for a later one.
+        source = re.sub('(?m)^ *:', '', """\
+            :def error(a):
+            :    global a  # SyntaxError
+            :def warning():
+            :    b = 1
+            :    global b  # SyntaxWarning
+            :""")
+        warnings.filterwarnings(action='ignore', category=SyntaxWarning)
+        self._check_error(source, "global")
+        warnings.filters.pop(0)
+
+    def test_break_outside_loop(self):
+        self._check_error("break", "outside loop")
+
+    def test_delete_deref(self):
+        source = re.sub('(?m)^ *:', '', """\
+            :def foo(x):
+            :  def bar():
+            :    print x
+            :  del x
+            :""")
+        self._check_error(source, "nested scope")
+
+    def test_unexpected_indent(self):
+        self._check_error("foo()\n bar()\n", "unexpected indent",
+                          subclass=IndentationError)
+
+    def test_no_indent(self):
+        self._check_error("if 1:\nfoo()", "expected an indented block",
+                          subclass=IndentationError)
+
+    def test_bad_outdent(self):
+        self._check_error("if 1:\n  foo()\n bar()",
+                          "unindent does not match .* level",
+                          subclass=IndentationError)
+
+    def test_kwargs_last(self):
+        self._check_error("int(base=10, '2')", "non-keyword arg")
+
+def test_main():
+    test_support.run_unittest(SyntaxTestCase)
+    from test import test_syntax
+    test_support.run_doctest(test_syntax, verbosity=True)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_sys.py
===================================================================
--- vendor/Python/current/Lib/test/test_sys.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_sys.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,357 @@
+# -*- coding: iso-8859-1 -*-
+import unittest, test.test_support
+import sys, cStringIO
+
+class SysModuleTest(unittest.TestCase):
+
+    def test_original_displayhook(self):
+        import __builtin__
+        savestdout = sys.stdout
+        out = cStringIO.StringIO()
+        sys.stdout = out
+
+        dh = sys.__displayhook__
+
+        self.assertRaises(TypeError, dh)
+        if hasattr(__builtin__, "_"):
+            del __builtin__._
+
+        dh(None)
+        self.assertEqual(out.getvalue(), "")
+        self.assert_(not hasattr(__builtin__, "_"))
+        dh(42)
+        self.assertEqual(out.getvalue(), "42\n")
+        self.assertEqual(__builtin__._, 42)
+
+        del sys.stdout
+        self.assertRaises(RuntimeError, dh, 42)
+
+        sys.stdout = savestdout
+
+    def test_lost_displayhook(self):
+        olddisplayhook = sys.displayhook
+        del sys.displayhook
+        code = compile("42", "<string>", "single")
+        self.assertRaises(RuntimeError, eval, code)
+        sys.displayhook = olddisplayhook
+
+    def test_custom_displayhook(self):
+        olddisplayhook = sys.displayhook
+        def baddisplayhook(obj):
+            raise ValueError
+        sys.displayhook = baddisplayhook
+        code = compile("42", "<string>", "single")
+        self.assertRaises(ValueError, eval, code)
+        sys.displayhook = olddisplayhook
+
+    def test_original_excepthook(self):
+        savestderr = sys.stderr
+        err = cStringIO.StringIO()
+        sys.stderr = err
+
+        eh = sys.__excepthook__
+
+        self.assertRaises(TypeError, eh)
+        try:
+            raise ValueError(42)
+        except ValueError, exc:
+            eh(*sys.exc_info())
+
+        sys.stderr = savestderr
+        self.assert_(err.getvalue().endswith("ValueError: 42\n"))
+
+    # FIXME: testing the code for a lost or replaced excepthook in
+    # Python/pythonrun.c::PyErr_PrintEx() is tricky.
+
+    def test_exc_clear(self):
+        self.assertRaises(TypeError, sys.exc_clear, 42)
+
+        # Verify that exc_info is present and matches exc, then clear it, and
+        # check that it worked.
+        def clear_check(exc):
+            typ, value, traceback = sys.exc_info()
+            self.assert_(typ is not None)
+            self.assert_(value is exc)
+            self.assert_(traceback is not None)
+
+            sys.exc_clear()
+
+            typ, value, traceback = sys.exc_info()
+            self.assert_(typ is None)
+            self.assert_(value is None)
+            self.assert_(traceback is None)
+
+        def clear():
+            try:
+                raise ValueError, 42
+            except ValueError, exc:
+                clear_check(exc)
+
+        # Raise an exception and check that it can be cleared
+        clear()
+
+        # Verify that a frame currently handling an exception is
+        # unaffected by calling exc_clear in a nested frame.
+        try:
+            raise ValueError, 13
+        except ValueError, exc:
+            typ1, value1, traceback1 = sys.exc_info()
+            clear()
+            typ2, value2, traceback2 = sys.exc_info()
+
+            self.assert_(typ1 is typ2)
+            self.assert_(value1 is exc)
+            self.assert_(value1 is value2)
+            self.assert_(traceback1 is traceback2)
+
+        # Check that an exception can be cleared outside of an except block
+        clear_check(exc)
+
+    def test_exit(self):
+        self.assertRaises(TypeError, sys.exit, 42, 42)
+
+        # call without argument
+        try:
+            sys.exit(0)
+        except SystemExit, exc:
+            self.assertEquals(exc.code, 0)
+        except:
+            self.fail("wrong exception")
+        else:
+            self.fail("no exception")
+
+        # call with tuple argument with one entry
+        # entry will be unpacked
+        try:
+            sys.exit(42)
+        except SystemExit, exc:
+            self.assertEquals(exc.code, 42)
+        except:
+            self.fail("wrong exception")
+        else:
+            self.fail("no exception")
+
+        # call with integer argument
+        try:
+            sys.exit((42,))
+        except SystemExit, exc:
+            self.assertEquals(exc.code, 42)
+        except:
+            self.fail("wrong exception")
+        else:
+            self.fail("no exception")
+
+        # call with string argument
+        try:
+            sys.exit("exit")
+        except SystemExit, exc:
+            self.assertEquals(exc.code, "exit")
+        except:
+            self.fail("wrong exception")
+        else:
+            self.fail("no exception")
+
+        # call with tuple argument with two entries
+        try:
+            sys.exit((17, 23))
+        except SystemExit, exc:
+            self.assertEquals(exc.code, (17, 23))
+        except:
+            self.fail("wrong exception")
+        else:
+            self.fail("no exception")
+
+        # test that the exit machinery handles SystemExits properly
+        import subprocess
+        # both unnormalized...
+        rc = subprocess.call([sys.executable, "-c",
+                              "raise SystemExit, 46"])
+        self.assertEqual(rc, 46)
+        # ... and normalized
+        rc = subprocess.call([sys.executable, "-c",
+                              "raise SystemExit(47)"])
+        self.assertEqual(rc, 47)
+
+
+    def test_getdefaultencoding(self):
+        if test.test_support.have_unicode:
+            self.assertRaises(TypeError, sys.getdefaultencoding, 42)
+            # can't check more than the type, as the user might have changed it
+            self.assert_(isinstance(sys.getdefaultencoding(), str))
+
+    # testing sys.settrace() is done in test_trace.py
+    # testing sys.setprofile() is done in test_profile.py
+
+    def test_setcheckinterval(self):
+        self.assertRaises(TypeError, sys.setcheckinterval)
+        orig = sys.getcheckinterval()
+        for n in 0, 100, 120, orig: # orig last to restore starting state
+            sys.setcheckinterval(n)
+            self.assertEquals(sys.getcheckinterval(), n)
+
+    def test_recursionlimit(self):
+        self.assertRaises(TypeError, sys.getrecursionlimit, 42)
+        oldlimit = sys.getrecursionlimit()
+        self.assertRaises(TypeError, sys.setrecursionlimit)
+        self.assertRaises(ValueError, sys.setrecursionlimit, -42)
+        sys.setrecursionlimit(10000)
+        self.assertEqual(sys.getrecursionlimit(), 10000)
+        sys.setrecursionlimit(oldlimit)
+
+    def test_getwindowsversion(self):
+        if hasattr(sys, "getwindowsversion"):
+            v = sys.getwindowsversion()
+            self.assert_(isinstance(v, tuple))
+            self.assertEqual(len(v), 5)
+            self.assert_(isinstance(v[0], int))
+            self.assert_(isinstance(v[1], int))
+            self.assert_(isinstance(v[2], int))
+            self.assert_(isinstance(v[3], int))
+            self.assert_(isinstance(v[4], str))
+
+    def test_dlopenflags(self):
+        if hasattr(sys, "setdlopenflags"):
+            self.assert_(hasattr(sys, "getdlopenflags"))
+            self.assertRaises(TypeError, sys.getdlopenflags, 42)
+            oldflags = sys.getdlopenflags()
+            self.assertRaises(TypeError, sys.setdlopenflags)
+            sys.setdlopenflags(oldflags+1)
+            self.assertEqual(sys.getdlopenflags(), oldflags+1)
+            sys.setdlopenflags(oldflags)
+
+    def test_refcount(self):
+        self.assertRaises(TypeError, sys.getrefcount)
+        c = sys.getrefcount(None)
+        n = None
+        self.assertEqual(sys.getrefcount(None), c+1)
+        del n
+        self.assertEqual(sys.getrefcount(None), c)
+        if hasattr(sys, "gettotalrefcount"):
+            self.assert_(isinstance(sys.gettotalrefcount(), int))
+
+    def test_getframe(self):
+        self.assertRaises(TypeError, sys._getframe, 42, 42)
+        self.assertRaises(ValueError, sys._getframe, 2000000000)
+        self.assert_(
+            SysModuleTest.test_getframe.im_func.func_code \
+            is sys._getframe().f_code
+        )
+
+    # sys._current_frames() is a CPython-only gimmick.
+    def test_current_frames(self):
+        have_threads = True
+        try:
+            import thread
+        except ImportError:
+            have_threads = False
+
+        if have_threads:
+            self.current_frames_with_threads()
+        else:
+            self.current_frames_without_threads()
+
+    # Test sys._current_frames() in a WITH_THREADS build.
+    def current_frames_with_threads(self):
+        import threading, thread
+        import traceback
+
+        # Spawn a thread that blocks at a known place.  Then the main
+        # thread does sys._current_frames(), and verifies that the frames
+        # returned make sense.
+        entered_g = threading.Event()
+        leave_g = threading.Event()
+        thread_info = []  # the thread's id
+
+        def f123():
+            g456()
+
+        def g456():
+            thread_info.append(thread.get_ident())
+            entered_g.set()
+            leave_g.wait()
+
+        t = threading.Thread(target=f123)
+        t.start()
+        entered_g.wait()
+
+        # At this point, t has finished its entered_g.set(), although it's
+        # impossible to guess whether it's still on that line or has moved on
+        # to its leave_g.wait().
+        self.assertEqual(len(thread_info), 1)
+        thread_id = thread_info[0]
+
+        d = sys._current_frames()
+
+        main_id = thread.get_ident()
+        self.assert_(main_id in d)
+        self.assert_(thread_id in d)
+
+        # Verify that the captured main-thread frame is _this_ frame.
+        frame = d.pop(main_id)
+        self.assert_(frame is sys._getframe())
+
+        # Verify that the captured thread frame is blocked in g456, called
+        # from f123.  This is a litte tricky, since various bits of
+        # threading.py are also in the thread's call stack.
+        frame = d.pop(thread_id)
+        stack = traceback.extract_stack(frame)
+        for i, (filename, lineno, funcname, sourceline) in enumerate(stack):
+            if funcname == "f123":
+                break
+        else:
+            self.fail("didn't find f123() on thread's call stack")
+
+        self.assertEqual(sourceline, "g456()")
+
+        # And the next record must be for g456().
+        filename, lineno, funcname, sourceline = stack[i+1]
+        self.assertEqual(funcname, "g456")
+        self.assert_(sourceline in ["leave_g.wait()", "entered_g.set()"])
+
+        # Reap the spawned thread.
+        leave_g.set()
+        t.join()
+
+    # Test sys._current_frames() when thread support doesn't exist.
+    def current_frames_without_threads(self):
+        # Not much happens here:  there is only one thread, with artificial
+        # "thread id" 0.
+        d = sys._current_frames()
+        self.assertEqual(len(d), 1)
+        self.assert_(0 in d)
+        self.assert_(d[0] is sys._getframe())
+
+    def test_attributes(self):
+        self.assert_(isinstance(sys.api_version, int))
+        self.assert_(isinstance(sys.argv, list))
+        self.assert_(sys.byteorder in ("little", "big"))
+        self.assert_(isinstance(sys.builtin_module_names, tuple))
+        self.assert_(isinstance(sys.copyright, basestring))
+        self.assert_(isinstance(sys.exec_prefix, basestring))
+        self.assert_(isinstance(sys.executable, basestring))
+        self.assert_(isinstance(sys.hexversion, int))
+        self.assert_(isinstance(sys.maxint, int))
+        if test.test_support.have_unicode:
+            self.assert_(isinstance(sys.maxunicode, int))
+        self.assert_(isinstance(sys.platform, basestring))
+        self.assert_(isinstance(sys.prefix, basestring))
+        self.assert_(isinstance(sys.version, basestring))
+        vi = sys.version_info
+        self.assert_(isinstance(vi, tuple))
+        self.assertEqual(len(vi), 5)
+        self.assert_(isinstance(vi[0], int))
+        self.assert_(isinstance(vi[1], int))
+        self.assert_(isinstance(vi[2], int))
+        self.assert_(vi[3] in ("alpha", "beta", "candidate", "final"))
+        self.assert_(isinstance(vi[4], int))
+
+    def test_43581(self):
+        # Can't use sys.stdout, as this is a cStringIO object when
+        # the test runs under regrtest.
+        self.assert_(sys.__stdout__.encoding == sys.__stderr__.encoding)
+
+def test_main():
+    test.test_support.run_unittest(SysModuleTest)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_tarfile.py
===================================================================
--- vendor/Python/current/Lib/test/test_tarfile.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_tarfile.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,729 @@
+import sys
+import os
+import shutil
+import tempfile
+import StringIO
+
+import unittest
+import tarfile
+
+from test import test_support
+
+# Check for our compression modules.
+try:
+    import gzip
+    gzip.GzipFile
+except (ImportError, AttributeError):
+    gzip = None
+try:
+    import bz2
+except ImportError:
+    bz2 = None
+
+def path(path):
+    return test_support.findfile(path)
+
+testtar = path("testtar.tar")
+tempdir = os.path.join(tempfile.gettempdir(), "testtar" + os.extsep + "dir")
+tempname = test_support.TESTFN
+membercount = 12
+
+def tarname(comp=""):
+    if not comp:
+        return testtar
+    return os.path.join(tempdir, "%s%s%s" % (testtar, os.extsep, comp))
+
+def dirname():
+    if not os.path.exists(tempdir):
+        os.mkdir(tempdir)
+    return tempdir
+
+def tmpname():
+    return tempname
+
+
+class BaseTest(unittest.TestCase):
+    comp = ''
+    mode = 'r'
+    sep = ':'
+
+    def setUp(self):
+        mode = self.mode + self.sep + self.comp
+        self.tar = tarfile.open(tarname(self.comp), mode)
+
+    def tearDown(self):
+        self.tar.close()
+
+class ReadTest(BaseTest):
+
+    def test(self):
+        """Test member extraction.
+        """
+        members = 0
+        for tarinfo in self.tar:
+            members += 1
+            if not tarinfo.isreg():
+                continue
+            f = self.tar.extractfile(tarinfo)
+            self.assert_(len(f.read()) == tarinfo.size,
+                         "size read does not match expected size")
+            f.close()
+
+        self.assert_(members == membercount,
+                     "could not find all members")
+
+    def test_sparse(self):
+        """Test sparse member extraction.
+        """
+        if self.sep != "|":
+            f1 = self.tar.extractfile("S-SPARSE")
+            f2 = self.tar.extractfile("S-SPARSE-WITH-NULLS")
+            self.assert_(f1.read() == f2.read(),
+                         "_FileObject failed on sparse file member")
+
+    def test_readlines(self):
+        """Test readlines() method of _FileObject.
+        """
+        if self.sep != "|":
+            filename = "0-REGTYPE-TEXT"
+            self.tar.extract(filename, dirname())
+            f = open(os.path.join(dirname(), filename), "rU")
+            lines1 = f.readlines()
+            f.close()
+            lines2 = self.tar.extractfile(filename).readlines()
+            self.assert_(lines1 == lines2,
+                         "_FileObject.readline() does not work correctly")
+
+    def test_iter(self):
+        # Test iteration over ExFileObject.
+        if self.sep != "|":
+            filename = "0-REGTYPE-TEXT"
+            self.tar.extract(filename, dirname())
+            f = open(os.path.join(dirname(), filename), "rU")
+            lines1 = f.readlines()
+            f.close()
+            lines2 = [line for line in self.tar.extractfile(filename)]
+            self.assert_(lines1 == lines2,
+                         "ExFileObject iteration does not work correctly")
+
+    def test_seek(self):
+        """Test seek() method of _FileObject, incl. random reading.
+        """
+        if self.sep != "|":
+            filename = "0-REGTYPE-TEXT"
+            self.tar.extract(filename, dirname())
+            f = open(os.path.join(dirname(), filename), "rb")
+            data = f.read()
+            f.close()
+
+            tarinfo = self.tar.getmember(filename)
+            fobj = self.tar.extractfile(tarinfo)
+
+            text = fobj.read()
+            fobj.seek(0)
+            self.assert_(0 == fobj.tell(),
+                         "seek() to file's start failed")
+            fobj.seek(2048, 0)
+            self.assert_(2048 == fobj.tell(),
+                         "seek() to absolute position failed")
+            fobj.seek(-1024, 1)
+            self.assert_(1024 == fobj.tell(),
+                         "seek() to negative relative position failed")
+            fobj.seek(1024, 1)
+            self.assert_(2048 == fobj.tell(),
+                         "seek() to positive relative position failed")
+            s = fobj.read(10)
+            self.assert_(s == data[2048:2058],
+                         "read() after seek failed")
+            fobj.seek(0, 2)
+            self.assert_(tarinfo.size == fobj.tell(),
+                         "seek() to file's end failed")
+            self.assert_(fobj.read() == "",
+                         "read() at file's end did not return empty string")
+            fobj.seek(-tarinfo.size, 2)
+            self.assert_(0 == fobj.tell(),
+                         "relative seek() to file's start failed")
+            fobj.seek(512)
+            s1 = fobj.readlines()
+            fobj.seek(512)
+            s2 = fobj.readlines()
+            self.assert_(s1 == s2,
+                         "readlines() after seek failed")
+            fobj.seek(0)
+            self.assert_(len(fobj.readline()) == fobj.tell(),
+                         "tell() after readline() failed")
+            fobj.seek(512)
+            self.assert_(len(fobj.readline()) + 512 == fobj.tell(),
+                         "tell() after seek() and readline() failed")
+            fobj.seek(0)
+            line = fobj.readline()
+            self.assert_(fobj.read() == data[len(line):],
+                         "read() after readline() failed")
+            fobj.close()
+
+    def test_old_dirtype(self):
+        """Test old style dirtype member (bug #1336623).
+        """
+        # Old tars create directory members using a REGTYPE
+        # header with a "/" appended to the filename field.
+
+        # Create an old tar style directory entry.
+        filename = tmpname()
+        tarinfo = tarfile.TarInfo("directory/")
+        tarinfo.type = tarfile.REGTYPE
+
+        fobj = open(filename, "w")
+        fobj.write(tarinfo.tobuf())
+        fobj.close()
+
+        try:
+            # Test if it is still a directory entry when
+            # read back.
+            tar = tarfile.open(filename)
+            tarinfo = tar.getmembers()[0]
+            tar.close()
+
+            self.assert_(tarinfo.type == tarfile.DIRTYPE)
+            self.assert_(tarinfo.name.endswith("/"))
+        finally:
+            try:
+                os.unlink(filename)
+            except:
+                pass
+
+class ReadStreamTest(ReadTest):
+    sep = "|"
+
+    def test(self):
+        """Test member extraction, and for StreamError when
+           seeking backwards.
+        """
+        ReadTest.test(self)
+        tarinfo = self.tar.getmembers()[0]
+        f = self.tar.extractfile(tarinfo)
+        self.assertRaises(tarfile.StreamError, f.read)
+
+    def test_stream(self):
+        """Compare the normal tar and the stream tar.
+        """
+        stream = self.tar
+        tar = tarfile.open(tarname(), 'r')
+
+        while 1:
+            t1 = tar.next()
+            t2 = stream.next()
+            if t1 is None:
+                break
+            self.assert_(t2 is not None, "stream.next() failed.")
+
+            if t2.islnk() or t2.issym():
+                self.assertRaises(tarfile.StreamError, stream.extractfile, t2)
+                continue
+            v1 = tar.extractfile(t1)
+            v2 = stream.extractfile(t2)
+            if v1 is None:
+                continue
+            self.assert_(v2 is not None, "stream.extractfile() failed")
+            self.assert_(v1.read() == v2.read(), "stream extraction failed")
+
+        tar.close()
+        stream.close()
+
+class ReadDetectTest(ReadTest):
+
+    def setUp(self):
+        self.tar = tarfile.open(tarname(self.comp), self.mode)
+
+class ReadDetectFileobjTest(ReadTest):
+
+    def setUp(self):
+        name = tarname(self.comp)
+        self.tar = tarfile.open(name, mode=self.mode,
+                                fileobj=open(name, "rb"))
+
+class ReadAsteriskTest(ReadTest):
+
+    def setUp(self):
+        mode = self.mode + self.sep + "*"
+        self.tar = tarfile.open(tarname(self.comp), mode)
+
+class ReadStreamAsteriskTest(ReadStreamTest):
+
+    def setUp(self):
+        mode = self.mode + self.sep + "*"
+        self.tar = tarfile.open(tarname(self.comp), mode)
+
+class WriteTest(BaseTest):
+    mode = 'w'
+
+    def setUp(self):
+        mode = self.mode + self.sep + self.comp
+        self.src = tarfile.open(tarname(self.comp), 'r')
+        self.dstname = tmpname()
+        self.dst = tarfile.open(self.dstname, mode)
+
+    def tearDown(self):
+        self.src.close()
+        self.dst.close()
+
+    def test_posix(self):
+        self.dst.posix = 1
+        self._test()
+
+    def test_nonposix(self):
+        self.dst.posix = 0
+        self._test()
+
+    def test_small(self):
+        self.dst.add(os.path.join(os.path.dirname(__file__),"cfgparser.1"))
+        self.dst.close()
+        self.assertNotEqual(os.stat(self.dstname).st_size, 0)
+
+    def _test(self):
+        for tarinfo in self.src:
+            if not tarinfo.isreg():
+                continue
+            f = self.src.extractfile(tarinfo)
+            if self.dst.posix and len(tarinfo.name) > tarfile.LENGTH_NAME and "/" not in tarinfo.name:
+                self.assertRaises(ValueError, self.dst.addfile,
+                                 tarinfo, f)
+            else:
+                self.dst.addfile(tarinfo, f)
+
+    def test_add_self(self):
+        dstname = os.path.abspath(self.dstname)
+
+        self.assertEqual(self.dst.name, dstname, "archive name must be absolute")
+
+        self.dst.add(dstname)
+        self.assertEqual(self.dst.getnames(), [], "added the archive to itself")
+
+        cwd = os.getcwd()
+        os.chdir(dirname())
+        self.dst.add(dstname)
+        os.chdir(cwd)
+        self.assertEqual(self.dst.getnames(), [], "added the archive to itself")
+
+
+class Write100Test(BaseTest):
+    # The name field in a tar header stores strings of at most 100 chars.
+    # If a string is shorter than 100 chars it has to be padded with '\0',
+    # which implies that a string of exactly 100 chars is stored without
+    # a trailing '\0'.
+
+    def setUp(self):
+        self.name = "01234567890123456789012345678901234567890123456789"
+        self.name += "01234567890123456789012345678901234567890123456789"
+
+        self.tar = tarfile.open(tmpname(), "w")
+        t = tarfile.TarInfo(self.name)
+        self.tar.addfile(t)
+        self.tar.close()
+
+        self.tar = tarfile.open(tmpname())
+
+    def tearDown(self):
+        self.tar.close()
+
+    def test(self):
+        self.assertEqual(self.tar.getnames()[0], self.name,
+                "failed to store 100 char filename")
+
+
+class WriteSize0Test(BaseTest):
+    mode = 'w'
+
+    def setUp(self):
+        self.tmpdir = dirname()
+        self.dstname = tmpname()
+        self.dst = tarfile.open(self.dstname, "w")
+
+    def tearDown(self):
+        self.dst.close()
+
+    def test_file(self):
+        path = os.path.join(self.tmpdir, "file")
+        f = open(path, "w")
+        f.close()
+        tarinfo = self.dst.gettarinfo(path)
+        self.assertEqual(tarinfo.size, 0)
+        f = open(path, "w")
+        f.write("aaa")
+        f.close()
+        tarinfo = self.dst.gettarinfo(path)
+        self.assertEqual(tarinfo.size, 3)
+
+    def test_directory(self):
+        path = os.path.join(self.tmpdir, "directory")
+        if os.path.exists(path):
+            # This shouldn't be necessary, but is <wink> if a previous
+            # run was killed in mid-stream.
+            shutil.rmtree(path)
+        os.mkdir(path)
+        tarinfo = self.dst.gettarinfo(path)
+        self.assertEqual(tarinfo.size, 0)
+
+    def test_symlink(self):
+        if hasattr(os, "symlink"):
+            path = os.path.join(self.tmpdir, "symlink")
+            os.symlink("link_target", path)
+            tarinfo = self.dst.gettarinfo(path)
+            self.assertEqual(tarinfo.size, 0)
+
+
+class WriteStreamTest(WriteTest):
+    sep = '|'
+
+    def test_padding(self):
+        self.dst.close()
+
+        if self.comp == "gz":
+            f = gzip.GzipFile(self.dstname)
+            s = f.read()
+            f.close()
+        elif self.comp == "bz2":
+            f = bz2.BZ2Decompressor()
+            s = file(self.dstname).read()
+            s = f.decompress(s)
+            self.assertEqual(len(f.unused_data), 0, "trailing data")
+        else:
+            f = file(self.dstname)
+            s = f.read()
+            f.close()
+
+        self.assertEqual(s.count("\0"), tarfile.RECORDSIZE,
+                         "incorrect zero padding")
+
+
+class WriteGNULongTest(unittest.TestCase):
+    """This testcase checks for correct creation of GNU Longname
+       and Longlink extensions.
+
+       It creates a tarfile and adds empty members with either
+       long names, long linknames or both and compares the size
+       of the tarfile with the expected size.
+
+       It checks for SF bug #812325 in TarFile._create_gnulong().
+
+       While I was writing this testcase, I noticed a second bug
+       in the same method:
+       Long{names,links} weren't null-terminated which lead to
+       bad tarfiles when their length was a multiple of 512. This
+       is tested as well.
+    """
+
+    def _length(self, s):
+        blocks, remainder = divmod(len(s) + 1, 512)
+        if remainder:
+            blocks += 1
+        return blocks * 512
+
+    def _calc_size(self, name, link=None):
+        # initial tar header
+        count = 512
+
+        if len(name) > tarfile.LENGTH_NAME:
+            # gnu longname extended header + longname
+            count += 512
+            count += self._length(name)
+
+        if link is not None and len(link) > tarfile.LENGTH_LINK:
+            # gnu longlink extended header + longlink
+            count += 512
+            count += self._length(link)
+
+        return count
+
+    def _test(self, name, link=None):
+        tarinfo = tarfile.TarInfo(name)
+        if link:
+            tarinfo.linkname = link
+            tarinfo.type = tarfile.LNKTYPE
+
+        tar = tarfile.open(tmpname(), "w")
+        tar.posix = False
+        tar.addfile(tarinfo)
+
+        v1 = self._calc_size(name, link)
+        v2 = tar.offset
+        self.assertEqual(v1, v2, "GNU longname/longlink creation failed")
+
+        tar.close()
+
+        tar = tarfile.open(tmpname())
+        member = tar.next()
+        self.failIf(member is None, "unable to read longname member")
+        self.assert_(tarinfo.name == member.name and \
+                     tarinfo.linkname == member.linkname, \
+                     "unable to read longname member")
+
+    def test_longname_1023(self):
+        self._test(("longnam/" * 127) + "longnam")
+
+    def test_longname_1024(self):
+        self._test(("longnam/" * 127) + "longname")
+
+    def test_longname_1025(self):
+        self._test(("longnam/" * 127) + "longname_")
+
+    def test_longlink_1023(self):
+        self._test("name", ("longlnk/" * 127) + "longlnk")
+
+    def test_longlink_1024(self):
+        self._test("name", ("longlnk/" * 127) + "longlink")
+
+    def test_longlink_1025(self):
+        self._test("name", ("longlnk/" * 127) + "longlink_")
+
+    def test_longnamelink_1023(self):
+        self._test(("longnam/" * 127) + "longnam",
+                   ("longlnk/" * 127) + "longlnk")
+
+    def test_longnamelink_1024(self):
+        self._test(("longnam/" * 127) + "longname",
+                   ("longlnk/" * 127) + "longlink")
+
+    def test_longnamelink_1025(self):
+        self._test(("longnam/" * 127) + "longname_",
+                   ("longlnk/" * 127) + "longlink_")
+
+class ReadGNULongTest(unittest.TestCase):
+
+    def setUp(self):
+        self.tar = tarfile.open(tarname())
+
+    def tearDown(self):
+        self.tar.close()
+
+    def test_1471427(self):
+        """Test reading of longname (bug #1471427).
+        """
+        name = "test/" * 20 + "0-REGTYPE"
+        try:
+            tarinfo = self.tar.getmember(name)
+        except KeyError:
+            tarinfo = None
+        self.assert_(tarinfo is not None, "longname not found")
+        self.assert_(tarinfo.type != tarfile.DIRTYPE, "read longname as dirtype")
+
+    def test_read_name(self):
+        name = ("0-LONGNAME-" * 10)[:101]
+        try:
+            tarinfo = self.tar.getmember(name)
+        except KeyError:
+            tarinfo = None
+        self.assert_(tarinfo is not None, "longname not found")
+
+    def test_read_link(self):
+        link = ("1-LONGLINK-" * 10)[:101]
+        name = ("0-LONGNAME-" * 10)[:101]
+        try:
+            tarinfo = self.tar.getmember(link)
+        except KeyError:
+            tarinfo = None
+        self.assert_(tarinfo is not None, "longlink not found")
+        self.assert_(tarinfo.linkname == name, "linkname wrong")
+
+    def test_truncated_longname(self):
+        f = open(tarname())
+        fobj = StringIO.StringIO(f.read(1024))
+        f.close()
+        tar = tarfile.open(name="foo.tar", fileobj=fobj)
+        self.assert_(len(tar.getmembers()) == 0, "")
+        tar.close()
+
+
+class ExtractHardlinkTest(BaseTest):
+
+    def test_hardlink(self):
+        """Test hardlink extraction (bug #857297)
+        """
+        # Prevent errors from being caught
+        self.tar.errorlevel = 1
+
+        self.tar.extract("0-REGTYPE", dirname())
+        try:
+            # Extract 1-LNKTYPE which is a hardlink to 0-REGTYPE
+            self.tar.extract("1-LNKTYPE", dirname())
+        except EnvironmentError, e:
+            import errno
+            if e.errno == errno.ENOENT:
+                self.fail("hardlink not extracted properly")
+
+class CreateHardlinkTest(BaseTest):
+    """Test the creation of LNKTYPE (hardlink) members in an archive.
+       In this respect tarfile.py mimics the behaviour of GNU tar: If
+       a file has a st_nlink > 1, it will be added a REGTYPE member
+       only the first time.
+    """
+
+    def setUp(self):
+        self.tar = tarfile.open(tmpname(), "w")
+
+        self.foo = os.path.join(dirname(), "foo")
+        self.bar = os.path.join(dirname(), "bar")
+
+        if os.path.exists(self.foo):
+            os.remove(self.foo)
+        if os.path.exists(self.bar):
+            os.remove(self.bar)
+
+        f = open(self.foo, "w")
+        f.write("foo")
+        f.close()
+        self.tar.add(self.foo)
+
+    def test_add_twice(self):
+        # If st_nlink == 1 then the same file will be added as
+        # REGTYPE every time.
+        tarinfo = self.tar.gettarinfo(self.foo)
+        self.assertEqual(tarinfo.type, tarfile.REGTYPE,
+                "add file as regular failed")
+
+    def test_add_hardlink(self):
+        # If st_nlink > 1 then the same file will be added as
+        # LNKTYPE.
+        os.link(self.foo, self.bar)
+        tarinfo = self.tar.gettarinfo(self.foo)
+        self.assertEqual(tarinfo.type, tarfile.LNKTYPE,
+                "add file as hardlink failed")
+
+        tarinfo = self.tar.gettarinfo(self.bar)
+        self.assertEqual(tarinfo.type, tarfile.LNKTYPE,
+                "add file as hardlink failed")
+
+    def test_dereference_hardlink(self):
+        self.tar.dereference = True
+        os.link(self.foo, self.bar)
+        tarinfo = self.tar.gettarinfo(self.bar)
+        self.assertEqual(tarinfo.type, tarfile.REGTYPE,
+                "dereferencing hardlink failed")
+
+
+# Gzip TestCases
+class ReadTestGzip(ReadTest):
+    comp = "gz"
+class ReadStreamTestGzip(ReadStreamTest):
+    comp = "gz"
+class WriteTestGzip(WriteTest):
+    comp = "gz"
+class WriteStreamTestGzip(WriteStreamTest):
+    comp = "gz"
+class ReadDetectTestGzip(ReadDetectTest):
+    comp = "gz"
+class ReadDetectFileobjTestGzip(ReadDetectFileobjTest):
+    comp = "gz"
+class ReadAsteriskTestGzip(ReadAsteriskTest):
+    comp = "gz"
+class ReadStreamAsteriskTestGzip(ReadStreamAsteriskTest):
+    comp = "gz"
+
+# Filemode test cases
+
+class FileModeTest(unittest.TestCase):
+    def test_modes(self):
+        self.assertEqual(tarfile.filemode(0755), '-rwxr-xr-x')
+        self.assertEqual(tarfile.filemode(07111), '---s--s--t')
+
+class OpenFileobjTest(BaseTest):
+    # Test for SF bug #1496501.
+
+    def test_opener(self):
+        fobj = StringIO.StringIO("foo\n")
+        try:
+            tarfile.open("", "r", fileobj=fobj)
+        except tarfile.ReadError:
+            self.assertEqual(fobj.tell(), 0, "fileobj's position has moved")
+
+if bz2:
+    # Bzip2 TestCases
+    class ReadTestBzip2(ReadTestGzip):
+        comp = "bz2"
+    class ReadStreamTestBzip2(ReadStreamTestGzip):
+        comp = "bz2"
+    class WriteTestBzip2(WriteTest):
+        comp = "bz2"
+    class WriteStreamTestBzip2(WriteStreamTestGzip):
+        comp = "bz2"
+    class ReadDetectTestBzip2(ReadDetectTest):
+        comp = "bz2"
+    class ReadDetectFileobjTestBzip2(ReadDetectFileobjTest):
+        comp = "bz2"
+    class ReadAsteriskTestBzip2(ReadAsteriskTest):
+        comp = "bz2"
+    class ReadStreamAsteriskTestBzip2(ReadStreamAsteriskTest):
+        comp = "bz2"
+
+# If importing gzip failed, discard the Gzip TestCases.
+if not gzip:
+    del ReadTestGzip
+    del ReadStreamTestGzip
+    del WriteTestGzip
+    del WriteStreamTestGzip
+
+def test_main():
+    # Create archive.
+    f = open(tarname(), "rb")
+    fguts = f.read()
+    f.close()
+    if gzip:
+        # create testtar.tar.gz
+        tar = gzip.open(tarname("gz"), "wb")
+        tar.write(fguts)
+        tar.close()
+    if bz2:
+        # create testtar.tar.bz2
+        tar = bz2.BZ2File(tarname("bz2"), "wb")
+        tar.write(fguts)
+        tar.close()
+
+    tests = [
+        FileModeTest,
+        OpenFileobjTest,
+        ReadTest,
+        ReadStreamTest,
+        ReadDetectTest,
+        ReadDetectFileobjTest,
+        ReadAsteriskTest,
+        ReadStreamAsteriskTest,
+        WriteTest,
+        Write100Test,
+        WriteSize0Test,
+        WriteStreamTest,
+        WriteGNULongTest,
+        ReadGNULongTest,
+    ]
+
+    if hasattr(os, "link"):
+        tests.append(ExtractHardlinkTest)
+        tests.append(CreateHardlinkTest)
+
+    if gzip:
+        tests.extend([
+            ReadTestGzip, ReadStreamTestGzip,
+            WriteTestGzip, WriteStreamTestGzip,
+            ReadDetectTestGzip, ReadDetectFileobjTestGzip,
+            ReadAsteriskTestGzip, ReadStreamAsteriskTestGzip
+        ])
+
+    if bz2:
+        tests.extend([
+            ReadTestBzip2, ReadStreamTestBzip2,
+            WriteTestBzip2, WriteStreamTestBzip2,
+            ReadDetectTestBzip2, ReadDetectFileobjTestBzip2,
+            ReadAsteriskTestBzip2, ReadStreamAsteriskTestBzip2
+        ])
+    try:
+        test_support.run_unittest(*tests)
+    finally:
+        if gzip:
+            os.remove(tarname("gz"))
+        if bz2:
+            os.remove(tarname("bz2"))
+        if os.path.exists(dirname()):
+            shutil.rmtree(dirname())
+        if os.path.exists(tmpname()):
+            os.remove(tmpname())
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_tcl.py
===================================================================
--- vendor/Python/current/Lib/test/test_tcl.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_tcl.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,157 @@
+#!/usr/bin/env python
+
+import unittest
+import os
+from test import test_support
+from Tkinter import Tcl
+from _tkinter import TclError
+
+class TclTest(unittest.TestCase):
+
+    def setUp(self):
+        self.interp = Tcl()
+
+    def testEval(self):
+        tcl = self.interp
+        tcl.eval('set a 1')
+        self.assertEqual(tcl.eval('set a'),'1')
+
+    def testEvalException(self):
+        tcl = self.interp
+        self.assertRaises(TclError,tcl.eval,'set a')
+
+    def testEvalException2(self):
+        tcl = self.interp
+        self.assertRaises(TclError,tcl.eval,'this is wrong')
+
+    def testCall(self):
+        tcl = self.interp
+        tcl.call('set','a','1')
+        self.assertEqual(tcl.call('set','a'),'1')
+
+    def testCallException(self):
+        tcl = self.interp
+        self.assertRaises(TclError,tcl.call,'set','a')
+
+    def testCallException2(self):
+        tcl = self.interp
+        self.assertRaises(TclError,tcl.call,'this','is','wrong')
+
+    def testSetVar(self):
+        tcl = self.interp
+        tcl.setvar('a','1')
+        self.assertEqual(tcl.eval('set a'),'1')
+
+    def testSetVarArray(self):
+        tcl = self.interp
+        tcl.setvar('a(1)','1')
+        self.assertEqual(tcl.eval('set a(1)'),'1')
+
+    def testGetVar(self):
+        tcl = self.interp
+        tcl.eval('set a 1')
+        self.assertEqual(tcl.getvar('a'),'1')
+
+    def testGetVarArray(self):
+        tcl = self.interp
+        tcl.eval('set a(1) 1')
+        self.assertEqual(tcl.getvar('a(1)'),'1')
+
+    def testGetVarException(self):
+        tcl = self.interp
+        self.assertRaises(TclError,tcl.getvar,'a')
+
+    def testGetVarArrayException(self):
+        tcl = self.interp
+        self.assertRaises(TclError,tcl.getvar,'a(1)')
+
+    def testUnsetVar(self):
+        tcl = self.interp
+        tcl.setvar('a',1)
+        self.assertEqual(tcl.eval('info exists a'),'1')
+        tcl.unsetvar('a')
+        self.assertEqual(tcl.eval('info exists a'),'0')
+
+    def testUnsetVarArray(self):
+        tcl = self.interp
+        tcl.setvar('a(1)',1)
+        tcl.setvar('a(2)',2)
+        self.assertEqual(tcl.eval('info exists a(1)'),'1')
+        self.assertEqual(tcl.eval('info exists a(2)'),'1')
+        tcl.unsetvar('a(1)')
+        self.assertEqual(tcl.eval('info exists a(1)'),'0')
+        self.assertEqual(tcl.eval('info exists a(2)'),'1')
+
+    def testUnsetVarException(self):
+        tcl = self.interp
+        self.assertRaises(TclError,tcl.unsetvar,'a')
+
+    def testEvalFile(self):
+        tcl = self.interp
+        filename = "testEvalFile.tcl"
+        fd = open(filename,'w')
+        script = """set a 1
+        set b 2
+        set c [ expr $a + $b ]
+        """
+        fd.write(script)
+        fd.close()
+        tcl.evalfile(filename)
+        os.remove(filename)
+        self.assertEqual(tcl.eval('set a'),'1')
+        self.assertEqual(tcl.eval('set b'),'2')
+        self.assertEqual(tcl.eval('set c'),'3')
+
+    def testEvalFileException(self):
+        tcl = self.interp
+        filename = "doesnotexists"
+        try:
+            os.remove(filename)
+        except Exception,e:
+            pass
+        self.assertRaises(TclError,tcl.evalfile,filename)
+
+    def testPackageRequireException(self):
+        tcl = self.interp
+        self.assertRaises(TclError,tcl.eval,'package require DNE')
+
+    def testLoadTk(self):
+        import os
+        if 'DISPLAY' not in os.environ:
+            # skipping test of clean upgradeability
+            return
+        tcl = Tcl()
+        self.assertRaises(TclError,tcl.winfo_geometry)
+        tcl.loadtk()
+        self.assertEqual('1x1+0+0', tcl.winfo_geometry())
+        tcl.destroy()
+
+    def testLoadTkFailure(self):
+        import os
+        old_display = None
+        import sys
+        if sys.platform.startswith(('win', 'darwin', 'cygwin')):
+            return  # no failure possible on windows?
+        if 'DISPLAY' in os.environ:
+            old_display = os.environ['DISPLAY']
+            del os.environ['DISPLAY']
+            # on some platforms, deleting environment variables
+            # doesn't actually carry through to the process level
+            # because they don't support unsetenv
+            # If that's the case, abort.
+            display = os.popen('echo $DISPLAY').read().strip()
+            if display:
+                return
+        try:
+            tcl = Tcl()
+            self.assertRaises(TclError, tcl.winfo_geometry)
+            self.assertRaises(TclError, tcl.loadtk)
+        finally:
+            if old_display is not None:
+                os.environ['DISPLAY'] = old_display
+
+def test_main():
+    test_support.run_unittest(TclTest)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_tempfile.py
===================================================================
--- vendor/Python/current/Lib/test/test_tempfile.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_tempfile.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,668 @@
+# tempfile.py unit tests.
+
+import tempfile
+import os
+import sys
+import re
+import errno
+import warnings
+
+import unittest
+from test import test_support
+
+warnings.filterwarnings("ignore",
+                        category=RuntimeWarning,
+                        message="mktemp", module=__name__)
+
+if hasattr(os, 'stat'):
+    import stat
+    has_stat = 1
+else:
+    has_stat = 0
+
+has_textmode = (tempfile._text_openflags != tempfile._bin_openflags)
+has_spawnl = hasattr(os, 'spawnl')
+
+# TEST_FILES may need to be tweaked for systems depending on the maximum
+# number of files that can be opened at one time (see ulimit -n)
+if sys.platform == 'mac':
+    TEST_FILES = 32
+elif sys.platform in ('openbsd3', 'openbsd4'):
+    TEST_FILES = 48
+else:
+    TEST_FILES = 100
+
+# This is organized as one test for each chunk of code in tempfile.py,
+# in order of their appearance in the file.  Testing which requires
+# threads is not done here.
+
+# Common functionality.
+class TC(unittest.TestCase):
+
+    str_check = re.compile(r"[a-zA-Z0-9_-]{6}$")
+
+    def failOnException(self, what, ei=None):
+        if ei is None:
+            ei = sys.exc_info()
+        self.fail("%s raised %s: %s" % (what, ei[0], ei[1]))
+
+    def nameCheck(self, name, dir, pre, suf):
+        (ndir, nbase) = os.path.split(name)
+        npre  = nbase[:len(pre)]
+        nsuf  = nbase[len(nbase)-len(suf):]
+
+        # check for equality of the absolute paths!
+        self.assertEqual(os.path.abspath(ndir), os.path.abspath(dir),
+                         "file '%s' not in directory '%s'" % (name, dir))
+        self.assertEqual(npre, pre,
+                         "file '%s' does not begin with '%s'" % (nbase, pre))
+        self.assertEqual(nsuf, suf,
+                         "file '%s' does not end with '%s'" % (nbase, suf))
+
+        nbase = nbase[len(pre):len(nbase)-len(suf)]
+        self.assert_(self.str_check.match(nbase),
+                     "random string '%s' does not match /^[a-zA-Z0-9_-]{6}$/"
+                     % nbase)
+
+test_classes = []
+
+class test_exports(TC):
+    def test_exports(self):
+        # There are no surprising symbols in the tempfile module
+        dict = tempfile.__dict__
+
+        expected = {
+            "NamedTemporaryFile" : 1,
+            "TemporaryFile" : 1,
+            "mkstemp" : 1,
+            "mkdtemp" : 1,
+            "mktemp" : 1,
+            "TMP_MAX" : 1,
+            "gettempprefix" : 1,
+            "gettempdir" : 1,
+            "tempdir" : 1,
+            "template" : 1
+        }
+
+        unexp = []
+        for key in dict:
+            if key[0] != '_' and key not in expected:
+                unexp.append(key)
+        self.failUnless(len(unexp) == 0,
+                        "unexpected keys: %s" % unexp)
+
+test_classes.append(test_exports)
+
+
+class test__RandomNameSequence(TC):
+    """Test the internal iterator object _RandomNameSequence."""
+
+    def setUp(self):
+        self.r = tempfile._RandomNameSequence()
+
+    def test_get_six_char_str(self):
+        # _RandomNameSequence returns a six-character string
+        s = self.r.next()
+        self.nameCheck(s, '', '', '')
+
+    def test_many(self):
+        # _RandomNameSequence returns no duplicate strings (stochastic)
+
+        dict = {}
+        r = self.r
+        for i in xrange(TEST_FILES):
+            s = r.next()
+            self.nameCheck(s, '', '', '')
+            self.failIf(s in dict)
+            dict[s] = 1
+
+    def test_supports_iter(self):
+        # _RandomNameSequence supports the iterator protocol
+
+        i = 0
+        r = self.r
+        try:
+            for s in r:
+                i += 1
+                if i == 20:
+                    break
+        except:
+            failOnException("iteration")
+
+test_classes.append(test__RandomNameSequence)
+
+
+class test__candidate_tempdir_list(TC):
+    """Test the internal function _candidate_tempdir_list."""
+
+    def test_nonempty_list(self):
+        # _candidate_tempdir_list returns a nonempty list of strings
+
+        cand = tempfile._candidate_tempdir_list()
+
+        self.failIf(len(cand) == 0)
+        for c in cand:
+            self.assert_(isinstance(c, basestring),
+                         "%s is not a string" % c)
+
+    def test_wanted_dirs(self):
+        # _candidate_tempdir_list contains the expected directories
+
+        # Make sure the interesting environment variables are all set.
+        added = []
+        try:
+            for envname in 'TMPDIR', 'TEMP', 'TMP':
+                dirname = os.getenv(envname)
+                if not dirname:
+                    os.environ[envname] = os.path.abspath(envname)
+                    added.append(envname)
+
+            cand = tempfile._candidate_tempdir_list()
+
+            for envname in 'TMPDIR', 'TEMP', 'TMP':
+                dirname = os.getenv(envname)
+                if not dirname: raise ValueError
+                self.assert_(dirname in cand)
+
+            try:
+                dirname = os.getcwd()
+            except (AttributeError, os.error):
+                dirname = os.curdir
+
+            self.assert_(dirname in cand)
+
+            # Not practical to try to verify the presence of OS-specific
+            # paths in this list.
+        finally:
+            for p in added:
+                del os.environ[p]
+
+test_classes.append(test__candidate_tempdir_list)
+
+
+# We test _get_default_tempdir by testing gettempdir.
+
+
+class test__get_candidate_names(TC):
+    """Test the internal function _get_candidate_names."""
+
+    def test_retval(self):
+        # _get_candidate_names returns a _RandomNameSequence object
+        obj = tempfile._get_candidate_names()
+        self.assert_(isinstance(obj, tempfile._RandomNameSequence))
+
+    def test_same_thing(self):
+        # _get_candidate_names always returns the same object
+        a = tempfile._get_candidate_names()
+        b = tempfile._get_candidate_names()
+
+        self.assert_(a is b)
+
+test_classes.append(test__get_candidate_names)
+
+
+class test__mkstemp_inner(TC):
+    """Test the internal function _mkstemp_inner."""
+
+    class mkstemped:
+        _bflags = tempfile._bin_openflags
+        _tflags = tempfile._text_openflags
+        _close = os.close
+        _unlink = os.unlink
+
+        def __init__(self, dir, pre, suf, bin):
+            if bin: flags = self._bflags
+            else:   flags = self._tflags
+
+            (self.fd, self.name) = tempfile._mkstemp_inner(dir, pre, suf, flags)
+
+        def write(self, str):
+            os.write(self.fd, str)
+
+        def __del__(self):
+            self._close(self.fd)
+            self._unlink(self.name)
+
+    def do_create(self, dir=None, pre="", suf="", bin=1):
+        if dir is None:
+            dir = tempfile.gettempdir()
+        try:
+            file = self.mkstemped(dir, pre, suf, bin)
+        except:
+            self.failOnException("_mkstemp_inner")
+
+        self.nameCheck(file.name, dir, pre, suf)
+        return file
+
+    def test_basic(self):
+        # _mkstemp_inner can create files
+        self.do_create().write("blat")
+        self.do_create(pre="a").write("blat")
+        self.do_create(suf="b").write("blat")
+        self.do_create(pre="a", suf="b").write("blat")
+        self.do_create(pre="aa", suf=".txt").write("blat")
+
+    def test_basic_many(self):
+        # _mkstemp_inner can create many files (stochastic)
+        extant = range(TEST_FILES)
+        for i in extant:
+            extant[i] = self.do_create(pre="aa")
+
+    def test_choose_directory(self):
+        # _mkstemp_inner can create files in a user-selected directory
+        dir = tempfile.mkdtemp()
+        try:
+            self.do_create(dir=dir).write("blat")
+        finally:
+            os.rmdir(dir)
+
+    def test_file_mode(self):
+        # _mkstemp_inner creates files with the proper mode
+        if not has_stat:
+            return            # ugh, can't use TestSkipped.
+
+        file = self.do_create()
+        mode = stat.S_IMODE(os.stat(file.name).st_mode)
+        expected = 0600
+        if sys.platform in ('win32', 'os2emx', 'mac'):
+            # There's no distinction among 'user', 'group' and 'world';
+            # replicate the 'user' bits.
+            user = expected >> 6
+            expected = user * (1 + 8 + 64)
+        self.assertEqual(mode, expected)
+
+    def test_noinherit(self):
+        # _mkstemp_inner file handles are not inherited by child processes
+        if not has_spawnl:
+            return            # ugh, can't use TestSkipped.
+
+        if test_support.verbose:
+            v="v"
+        else:
+            v="q"
+
+        file = self.do_create()
+        fd = "%d" % file.fd
+
+        try:
+            me = __file__
+        except NameError:
+            me = sys.argv[0]
+
+        # We have to exec something, so that FD_CLOEXEC will take
+        # effect.  The core of this test is therefore in
+        # tf_inherit_check.py, which see.
+        tester = os.path.join(os.path.dirname(os.path.abspath(me)),
+                              "tf_inherit_check.py")
+
+        # On Windows a spawn* /path/ with embedded spaces shouldn't be quoted,
+        # but an arg with embedded spaces should be decorated with double
+        # quotes on each end
+        if sys.platform in ('win32'):
+            decorated = '"%s"' % sys.executable
+            tester = '"%s"' % tester
+        else:
+            decorated = sys.executable
+
+        retval = os.spawnl(os.P_WAIT, sys.executable, decorated, tester, v, fd)
+        self.failIf(retval < 0,
+                    "child process caught fatal signal %d" % -retval)
+        self.failIf(retval > 0, "child process reports failure %d"%retval)
+
+    def test_textmode(self):
+        # _mkstemp_inner can create files in text mode
+        if not has_textmode:
+            return            # ugh, can't use TestSkipped.
+
+        self.do_create(bin=0).write("blat\n")
+        # XXX should test that the file really is a text file
+
+test_classes.append(test__mkstemp_inner)
+
+
+class test_gettempprefix(TC):
+    """Test gettempprefix()."""
+
+    def test_sane_template(self):
+        # gettempprefix returns a nonempty prefix string
+        p = tempfile.gettempprefix()
+
+        self.assert_(isinstance(p, basestring))
+        self.assert_(len(p) > 0)
+
+    def test_usable_template(self):
+        # gettempprefix returns a usable prefix string
+
+        # Create a temp directory, avoiding use of the prefix.
+        # Then attempt to create a file whose name is
+        # prefix + 'xxxxxx.xxx' in that directory.
+        p = tempfile.gettempprefix() + "xxxxxx.xxx"
+        d = tempfile.mkdtemp(prefix="")
+        try:
+            p = os.path.join(d, p)
+            try:
+                fd = os.open(p, os.O_RDWR | os.O_CREAT)
+            except:
+                self.failOnException("os.open")
+            os.close(fd)
+            os.unlink(p)
+        finally:
+            os.rmdir(d)
+
+test_classes.append(test_gettempprefix)
+
+
+class test_gettempdir(TC):
+    """Test gettempdir()."""
+
+    def test_directory_exists(self):
+        # gettempdir returns a directory which exists
+
+        dir = tempfile.gettempdir()
+        self.assert_(os.path.isabs(dir) or dir == os.curdir,
+                     "%s is not an absolute path" % dir)
+        self.assert_(os.path.isdir(dir),
+                     "%s is not a directory" % dir)
+
+    def test_directory_writable(self):
+        # gettempdir returns a directory writable by the user
+
+        # sneaky: just instantiate a NamedTemporaryFile, which
+        # defaults to writing into the directory returned by
+        # gettempdir.
+        try:
+            file = tempfile.NamedTemporaryFile()
+            file.write("blat")
+            file.close()
+        except:
+            self.failOnException("create file in %s" % tempfile.gettempdir())
+
+    def test_same_thing(self):
+        # gettempdir always returns the same object
+        a = tempfile.gettempdir()
+        b = tempfile.gettempdir()
+
+        self.assert_(a is b)
+
+test_classes.append(test_gettempdir)
+
+
+class test_mkstemp(TC):
+    """Test mkstemp()."""
+
+    def do_create(self, dir=None, pre="", suf=""):
+        if dir is None:
+            dir = tempfile.gettempdir()
+        try:
+            (fd, name) = tempfile.mkstemp(dir=dir, prefix=pre, suffix=suf)
+            (ndir, nbase) = os.path.split(name)
+            adir = os.path.abspath(dir)
+            self.assertEqual(adir, ndir,
+                "Directory '%s' incorrectly returned as '%s'" % (adir, ndir))
+        except:
+            self.failOnException("mkstemp")
+
+        try:
+            self.nameCheck(name, dir, pre, suf)
+        finally:
+            os.close(fd)
+            os.unlink(name)
+
+    def test_basic(self):
+        # mkstemp can create files
+        self.do_create()
+        self.do_create(pre="a")
+        self.do_create(suf="b")
+        self.do_create(pre="a", suf="b")
+        self.do_create(pre="aa", suf=".txt")
+        self.do_create(dir=".")
+
+    def test_choose_directory(self):
+        # mkstemp can create directories in a user-selected directory
+        dir = tempfile.mkdtemp()
+        try:
+            self.do_create(dir=dir)
+        finally:
+            os.rmdir(dir)
+
+test_classes.append(test_mkstemp)
+
+
+class test_mkdtemp(TC):
+    """Test mkdtemp()."""
+
+    def do_create(self, dir=None, pre="", suf=""):
+        if dir is None:
+            dir = tempfile.gettempdir()
+        try:
+            name = tempfile.mkdtemp(dir=dir, prefix=pre, suffix=suf)
+        except:
+            self.failOnException("mkdtemp")
+
+        try:
+            self.nameCheck(name, dir, pre, suf)
+            return name
+        except:
+            os.rmdir(name)
+            raise
+
+    def test_basic(self):
+        # mkdtemp can create directories
+        os.rmdir(self.do_create())
+        os.rmdir(self.do_create(pre="a"))
+        os.rmdir(self.do_create(suf="b"))
+        os.rmdir(self.do_create(pre="a", suf="b"))
+        os.rmdir(self.do_create(pre="aa", suf=".txt"))
+
+    def test_basic_many(self):
+        # mkdtemp can create many directories (stochastic)
+        extant = range(TEST_FILES)
+        try:
+            for i in extant:
+                extant[i] = self.do_create(pre="aa")
+        finally:
+            for i in extant:
+                if(isinstance(i, basestring)):
+                    os.rmdir(i)
+
+    def test_choose_directory(self):
+        # mkdtemp can create directories in a user-selected directory
+        dir = tempfile.mkdtemp()
+        try:
+            os.rmdir(self.do_create(dir=dir))
+        finally:
+            os.rmdir(dir)
+
+    def test_mode(self):
+        # mkdtemp creates directories with the proper mode
+        if not has_stat:
+            return            # ugh, can't use TestSkipped.
+
+        dir = self.do_create()
+        try:
+            mode = stat.S_IMODE(os.stat(dir).st_mode)
+            mode &= 0777 # Mask off sticky bits inherited from /tmp
+            expected = 0700
+            if sys.platform in ('win32', 'os2emx', 'mac'):
+                # There's no distinction among 'user', 'group' and 'world';
+                # replicate the 'user' bits.
+                user = expected >> 6
+                expected = user * (1 + 8 + 64)
+            self.assertEqual(mode, expected)
+        finally:
+            os.rmdir(dir)
+
+test_classes.append(test_mkdtemp)
+
+
+class test_mktemp(TC):
+    """Test mktemp()."""
+
+    # For safety, all use of mktemp must occur in a private directory.
+    # We must also suppress the RuntimeWarning it generates.
+    def setUp(self):
+        self.dir = tempfile.mkdtemp()
+
+    def tearDown(self):
+        if self.dir:
+            os.rmdir(self.dir)
+            self.dir = None
+
+    class mktemped:
+        _unlink = os.unlink
+        _bflags = tempfile._bin_openflags
+
+        def __init__(self, dir, pre, suf):
+            self.name = tempfile.mktemp(dir=dir, prefix=pre, suffix=suf)
+            # Create the file.  This will raise an exception if it's
+            # mysteriously appeared in the meanwhile.
+            os.close(os.open(self.name, self._bflags, 0600))
+
+        def __del__(self):
+            self._unlink(self.name)
+
+    def do_create(self, pre="", suf=""):
+        try:
+            file = self.mktemped(self.dir, pre, suf)
+        except:
+            self.failOnException("mktemp")
+
+        self.nameCheck(file.name, self.dir, pre, suf)
+        return file
+
+    def test_basic(self):
+        # mktemp can choose usable file names
+        self.do_create()
+        self.do_create(pre="a")
+        self.do_create(suf="b")
+        self.do_create(pre="a", suf="b")
+        self.do_create(pre="aa", suf=".txt")
+
+    def test_many(self):
+        # mktemp can choose many usable file names (stochastic)
+        extant = range(TEST_FILES)
+        for i in extant:
+            extant[i] = self.do_create(pre="aa")
+
+##     def test_warning(self):
+##         # mktemp issues a warning when used
+##         warnings.filterwarnings("error",
+##                                 category=RuntimeWarning,
+##                                 message="mktemp")
+##         self.assertRaises(RuntimeWarning,
+##                           tempfile.mktemp, dir=self.dir)
+
+test_classes.append(test_mktemp)
+
+
+# We test _TemporaryFileWrapper by testing NamedTemporaryFile.
+
+
+class test_NamedTemporaryFile(TC):
+    """Test NamedTemporaryFile()."""
+
+    def do_create(self, dir=None, pre="", suf=""):
+        if dir is None:
+            dir = tempfile.gettempdir()
+        try:
+            file = tempfile.NamedTemporaryFile(dir=dir, prefix=pre, suffix=suf)
+        except:
+            self.failOnException("NamedTemporaryFile")
+
+        self.nameCheck(file.name, dir, pre, suf)
+        return file
+
+
+    def test_basic(self):
+        # NamedTemporaryFile can create files
+        self.do_create()
+        self.do_create(pre="a")
+        self.do_create(suf="b")
+        self.do_create(pre="a", suf="b")
+        self.do_create(pre="aa", suf=".txt")
+
+    def test_creates_named(self):
+        # NamedTemporaryFile creates files with names
+        f = tempfile.NamedTemporaryFile()
+        self.failUnless(os.path.exists(f.name),
+                        "NamedTemporaryFile %s does not exist" % f.name)
+
+    def test_del_on_close(self):
+        # A NamedTemporaryFile is deleted when closed
+        dir = tempfile.mkdtemp()
+        try:
+            f = tempfile.NamedTemporaryFile(dir=dir)
+            f.write('blat')
+            f.close()
+            self.failIf(os.path.exists(f.name),
+                        "NamedTemporaryFile %s exists after close" % f.name)
+        finally:
+            os.rmdir(dir)
+
+    def test_multiple_close(self):
+        # A NamedTemporaryFile can be closed many times without error
+
+        f = tempfile.NamedTemporaryFile()
+        f.write('abc\n')
+        f.close()
+        try:
+            f.close()
+            f.close()
+        except:
+            self.failOnException("close")
+
+    # How to test the mode and bufsize parameters?
+
+test_classes.append(test_NamedTemporaryFile)
+
+
+class test_TemporaryFile(TC):
+    """Test TemporaryFile()."""
+
+    def test_basic(self):
+        # TemporaryFile can create files
+        # No point in testing the name params - the file has no name.
+        try:
+            tempfile.TemporaryFile()
+        except:
+            self.failOnException("TemporaryFile")
+
+    def test_has_no_name(self):
+        # TemporaryFile creates files with no names (on this system)
+        dir = tempfile.mkdtemp()
+        f = tempfile.TemporaryFile(dir=dir)
+        f.write('blat')
+
+        # Sneaky: because this file has no name, it should not prevent
+        # us from removing the directory it was created in.
+        try:
+            os.rmdir(dir)
+        except:
+            ei = sys.exc_info()
+            # cleanup
+            f.close()
+            os.rmdir(dir)
+            self.failOnException("rmdir", ei)
+
+    def test_multiple_close(self):
+        # A TemporaryFile can be closed many times without error
+        f = tempfile.TemporaryFile()
+        f.write('abc\n')
+        f.close()
+        try:
+            f.close()
+            f.close()
+        except:
+            self.failOnException("close")
+
+    # How to test the mode and bufsize parameters?
+
+
+if tempfile.NamedTemporaryFile is not tempfile.TemporaryFile:
+    test_classes.append(test_TemporaryFile)
+
+def test_main():
+    test_support.run_unittest(*test_classes)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_textwrap.py
===================================================================
--- vendor/Python/current/Lib/test/test_textwrap.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_textwrap.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,568 @@
+#
+# Test suite for the textwrap module.
+#
+# Original tests written by Greg Ward <gward at python.net>.
+# Converted to PyUnit by Peter Hansen <peter at engcorp.com>.
+# Currently maintained by Greg Ward.
+#
+# $Id: test_textwrap.py 46863 2006-06-11 19:42:51Z tim.peters $
+#
+
+import unittest
+from test import test_support
+
+from textwrap import TextWrapper, wrap, fill, dedent
+
+
+class BaseTestCase(unittest.TestCase):
+    '''Parent class with utility methods for textwrap tests.'''
+
+    def show(self, textin):
+        if isinstance(textin, list):
+            result = []
+            for i in range(len(textin)):
+                result.append("  %d: %r" % (i, textin[i]))
+            result = '\n'.join(result)
+        elif isinstance(textin, basestring):
+            result = "  %s\n" % repr(textin)
+        return result
+
+
+    def check(self, result, expect):
+        self.assertEquals(result, expect,
+            'expected:\n%s\nbut got:\n%s' % (
+                self.show(expect), self.show(result)))
+
+    def check_wrap(self, text, width, expect, **kwargs):
+        result = wrap(text, width, **kwargs)
+        self.check(result, expect)
+
+    def check_split(self, text, expect):
+        result = self.wrapper._split(text)
+        self.assertEquals(result, expect,
+                          "\nexpected %r\n"
+                          "but got  %r" % (expect, result))
+
+
+class WrapTestCase(BaseTestCase):
+
+    def setUp(self):
+        self.wrapper = TextWrapper(width=45)
+
+    def test_simple(self):
+        # Simple case: just words, spaces, and a bit of punctuation
+
+        text = "Hello there, how are you this fine day?  I'm glad to hear it!"
+
+        self.check_wrap(text, 12,
+                        ["Hello there,",
+                         "how are you",
+                         "this fine",
+                         "day?  I'm",
+                         "glad to hear",
+                         "it!"])
+        self.check_wrap(text, 42,
+                        ["Hello there, how are you this fine day?",
+                         "I'm glad to hear it!"])
+        self.check_wrap(text, 80, [text])
+
+
+    def test_whitespace(self):
+        # Whitespace munging and end-of-sentence detection
+
+        text = """\
+This is a paragraph that already has
+line breaks.  But some of its lines are much longer than the others,
+so it needs to be wrapped.
+Some lines are \ttabbed too.
+What a mess!
+"""
+
+        expect = ["This is a paragraph that already has line",
+                  "breaks.  But some of its lines are much",
+                  "longer than the others, so it needs to be",
+                  "wrapped.  Some lines are  tabbed too.  What a",
+                  "mess!"]
+
+        wrapper = TextWrapper(45, fix_sentence_endings=True)
+        result = wrapper.wrap(text)
+        self.check(result, expect)
+
+        result = wrapper.fill(text)
+        self.check(result, '\n'.join(expect))
+
+    def test_fix_sentence_endings(self):
+        wrapper = TextWrapper(60, fix_sentence_endings=True)
+
+        # SF #847346: ensure that fix_sentence_endings=True does the
+        # right thing even on input short enough that it doesn't need to
+        # be wrapped.
+        text = "A short line. Note the single space."
+        expect = ["A short line.  Note the single space."]
+        self.check(wrapper.wrap(text), expect)
+
+        # Test some of the hairy end cases that _fix_sentence_endings()
+        # is supposed to handle (the easy stuff is tested in
+        # test_whitespace() above).
+        text = "Well, Doctor? What do you think?"
+        expect = ["Well, Doctor?  What do you think?"]
+        self.check(wrapper.wrap(text), expect)
+
+        text = "Well, Doctor?\nWhat do you think?"
+        self.check(wrapper.wrap(text), expect)
+
+        text = 'I say, chaps! Anyone for "tennis?"\nHmmph!'
+        expect = ['I say, chaps!  Anyone for "tennis?"  Hmmph!']
+        self.check(wrapper.wrap(text), expect)
+
+        wrapper.width = 20
+        expect = ['I say, chaps!', 'Anyone for "tennis?"', 'Hmmph!']
+        self.check(wrapper.wrap(text), expect)
+
+        text = 'And she said, "Go to hell!"\nCan you believe that?'
+        expect = ['And she said, "Go to',
+                  'hell!"  Can you',
+                  'believe that?']
+        self.check(wrapper.wrap(text), expect)
+
+        wrapper.width = 60
+        expect = ['And she said, "Go to hell!"  Can you believe that?']
+        self.check(wrapper.wrap(text), expect)
+
+    def test_wrap_short(self):
+        # Wrapping to make short lines longer
+
+        text = "This is a\nshort paragraph."
+
+        self.check_wrap(text, 20, ["This is a short",
+                                   "paragraph."])
+        self.check_wrap(text, 40, ["This is a short paragraph."])
+
+
+    def test_wrap_short_1line(self):
+        # Test endcases
+
+        text = "This is a short line."
+
+        self.check_wrap(text, 30, ["This is a short line."])
+        self.check_wrap(text, 30, ["(1) This is a short line."],
+                        initial_indent="(1) ")
+
+
+    def test_hyphenated(self):
+        # Test breaking hyphenated words
+
+        text = ("this-is-a-useful-feature-for-"
+                "reformatting-posts-from-tim-peters'ly")
+
+        self.check_wrap(text, 40,
+                        ["this-is-a-useful-feature-for-",
+                         "reformatting-posts-from-tim-peters'ly"])
+        self.check_wrap(text, 41,
+                        ["this-is-a-useful-feature-for-",
+                         "reformatting-posts-from-tim-peters'ly"])
+        self.check_wrap(text, 42,
+                        ["this-is-a-useful-feature-for-reformatting-",
+                         "posts-from-tim-peters'ly"])
+
+    def test_hyphenated_numbers(self):
+        # Test that hyphenated numbers (eg. dates) are not broken like words.
+        text = ("Python 1.0.0 was released on 1994-01-26.  Python 1.0.1 was\n"
+                "released on 1994-02-15.")
+
+        self.check_wrap(text, 30, ['Python 1.0.0 was released on',
+                                   '1994-01-26.  Python 1.0.1 was',
+                                   'released on 1994-02-15.'])
+        self.check_wrap(text, 40, ['Python 1.0.0 was released on 1994-01-26.',
+                                   'Python 1.0.1 was released on 1994-02-15.'])
+
+        text = "I do all my shopping at 7-11."
+        self.check_wrap(text, 25, ["I do all my shopping at",
+                                   "7-11."])
+        self.check_wrap(text, 27, ["I do all my shopping at",
+                                   "7-11."])
+        self.check_wrap(text, 29, ["I do all my shopping at 7-11."])
+
+    def test_em_dash(self):
+        # Test text with em-dashes
+        text = "Em-dashes should be written -- thus."
+        self.check_wrap(text, 25,
+                        ["Em-dashes should be",
+                         "written -- thus."])
+
+        # Probe the boundaries of the properly written em-dash,
+        # ie. " -- ".
+        self.check_wrap(text, 29,
+                        ["Em-dashes should be written",
+                         "-- thus."])
+        expect = ["Em-dashes should be written --",
+                  "thus."]
+        self.check_wrap(text, 30, expect)
+        self.check_wrap(text, 35, expect)
+        self.check_wrap(text, 36,
+                        ["Em-dashes should be written -- thus."])
+
+        # The improperly written em-dash is handled too, because
+        # it's adjacent to non-whitespace on both sides.
+        text = "You can also do--this or even---this."
+        expect = ["You can also do",
+                  "--this or even",
+                  "---this."]
+        self.check_wrap(text, 15, expect)
+        self.check_wrap(text, 16, expect)
+        expect = ["You can also do--",
+                  "this or even---",
+                  "this."]
+        self.check_wrap(text, 17, expect)
+        self.check_wrap(text, 19, expect)
+        expect = ["You can also do--this or even",
+                  "---this."]
+        self.check_wrap(text, 29, expect)
+        self.check_wrap(text, 31, expect)
+        expect = ["You can also do--this or even---",
+                  "this."]
+        self.check_wrap(text, 32, expect)
+        self.check_wrap(text, 35, expect)
+
+        # All of the above behaviour could be deduced by probing the
+        # _split() method.
+        text = "Here's an -- em-dash and--here's another---and another!"
+        expect = ["Here's", " ", "an", " ", "--", " ", "em-", "dash", " ",
+                  "and", "--", "here's", " ", "another", "---",
+                  "and", " ", "another!"]
+        self.check_split(text, expect)
+
+        text = "and then--bam!--he was gone"
+        expect = ["and", " ", "then", "--", "bam!", "--",
+                  "he", " ", "was", " ", "gone"]
+        self.check_split(text, expect)
+
+
+    def test_unix_options (self):
+        # Test that Unix-style command-line options are wrapped correctly.
+        # Both Optik (OptionParser) and Docutils rely on this behaviour!
+
+        text = "You should use the -n option, or --dry-run in its long form."
+        self.check_wrap(text, 20,
+                        ["You should use the",
+                         "-n option, or --dry-",
+                         "run in its long",
+                         "form."])
+        self.check_wrap(text, 21,
+                        ["You should use the -n",
+                         "option, or --dry-run",
+                         "in its long form."])
+        expect = ["You should use the -n option, or",
+                  "--dry-run in its long form."]
+        self.check_wrap(text, 32, expect)
+        self.check_wrap(text, 34, expect)
+        self.check_wrap(text, 35, expect)
+        self.check_wrap(text, 38, expect)
+        expect = ["You should use the -n option, or --dry-",
+                  "run in its long form."]
+        self.check_wrap(text, 39, expect)
+        self.check_wrap(text, 41, expect)
+        expect = ["You should use the -n option, or --dry-run",
+                  "in its long form."]
+        self.check_wrap(text, 42, expect)
+
+        # Again, all of the above can be deduced from _split().
+        text = "the -n option, or --dry-run or --dryrun"
+        expect = ["the", " ", "-n", " ", "option,", " ", "or", " ",
+                  "--dry-", "run", " ", "or", " ", "--dryrun"]
+        self.check_split(text, expect)
+
+    def test_funky_hyphens (self):
+        # Screwy edge cases cooked up by David Goodger.  All reported
+        # in SF bug #596434.
+        self.check_split("what the--hey!", ["what", " ", "the", "--", "hey!"])
+        self.check_split("what the--", ["what", " ", "the--"])
+        self.check_split("what the--.", ["what", " ", "the--."])
+        self.check_split("--text--.", ["--text--."])
+
+        # When I first read bug #596434, this is what I thought David
+        # was talking about.  I was wrong; these have always worked
+        # fine.  The real problem is tested in test_funky_parens()
+        # below...
+        self.check_split("--option", ["--option"])
+        self.check_split("--option-opt", ["--option-", "opt"])
+        self.check_split("foo --option-opt bar",
+                         ["foo", " ", "--option-", "opt", " ", "bar"])
+
+    def test_punct_hyphens(self):
+        # Oh bother, SF #965425 found another problem with hyphens --
+        # hyphenated words in single quotes weren't handled correctly.
+        # In fact, the bug is that *any* punctuation around a hyphenated
+        # word was handled incorrectly, except for a leading "--", which
+        # was special-cased for Optik and Docutils.  So test a variety
+        # of styles of punctuation around a hyphenated word.
+        # (Actually this is based on an Optik bug report, #813077).
+        self.check_split("the 'wibble-wobble' widget",
+                         ['the', ' ', "'wibble-", "wobble'", ' ', 'widget'])
+        self.check_split('the "wibble-wobble" widget',
+                         ['the', ' ', '"wibble-', 'wobble"', ' ', 'widget'])
+        self.check_split("the (wibble-wobble) widget",
+                         ['the', ' ', "(wibble-", "wobble)", ' ', 'widget'])
+        self.check_split("the ['wibble-wobble'] widget",
+                         ['the', ' ', "['wibble-", "wobble']", ' ', 'widget'])
+
+    def test_funky_parens (self):
+        # Second part of SF bug #596434: long option strings inside
+        # parentheses.
+        self.check_split("foo (--option) bar",
+                         ["foo", " ", "(--option)", " ", "bar"])
+
+        # Related stuff -- make sure parens work in simpler contexts.
+        self.check_split("foo (bar) baz",
+                         ["foo", " ", "(bar)", " ", "baz"])
+        self.check_split("blah (ding dong), wubba",
+                         ["blah", " ", "(ding", " ", "dong),",
+                          " ", "wubba"])
+
+    def test_initial_whitespace(self):
+        # SF bug #622849 reported inconsistent handling of leading
+        # whitespace; let's test that a bit, shall we?
+        text = " This is a sentence with leading whitespace."
+        self.check_wrap(text, 50,
+                        [" This is a sentence with leading whitespace."])
+        self.check_wrap(text, 30,
+                        [" This is a sentence with", "leading whitespace."])
+
+    if test_support.have_unicode:
+        def test_unicode(self):
+            # *Very* simple test of wrapping Unicode strings.  I'm sure
+            # there's more to it than this, but let's at least make
+            # sure textwrap doesn't crash on Unicode input!
+            text = u"Hello there, how are you today?"
+            self.check_wrap(text, 50, [u"Hello there, how are you today?"])
+            self.check_wrap(text, 20, [u"Hello there, how are", "you today?"])
+            olines = self.wrapper.wrap(text)
+            assert isinstance(olines, list) and isinstance(olines[0], unicode)
+            otext = self.wrapper.fill(text)
+            assert isinstance(otext, unicode)
+
+    def test_split(self):
+        # Ensure that the standard _split() method works as advertised
+        # in the comments
+
+        text = "Hello there -- you goof-ball, use the -b option!"
+
+        result = self.wrapper._split(text)
+        self.check(result,
+             ["Hello", " ", "there", " ", "--", " ", "you", " ", "goof-",
+              "ball,", " ", "use", " ", "the", " ", "-b", " ",  "option!"])
+
+    def test_bad_width(self):
+        # Ensure that width <= 0 is caught.
+        text = "Whatever, it doesn't matter."
+        self.assertRaises(ValueError, wrap, text, 0)
+        self.assertRaises(ValueError, wrap, text, -1)
+
+
+class LongWordTestCase (BaseTestCase):
+    def setUp(self):
+        self.wrapper = TextWrapper()
+        self.text = '''\
+Did you say "supercalifragilisticexpialidocious?"
+How *do* you spell that odd word, anyways?
+'''
+
+    def test_break_long(self):
+        # Wrap text with long words and lots of punctuation
+
+        self.check_wrap(self.text, 30,
+                        ['Did you say "supercalifragilis',
+                         'ticexpialidocious?" How *do*',
+                         'you spell that odd word,',
+                         'anyways?'])
+        self.check_wrap(self.text, 50,
+                        ['Did you say "supercalifragilisticexpialidocious?"',
+                         'How *do* you spell that odd word, anyways?'])
+
+        # SF bug 797650.  Prevent an infinite loop by making sure that at
+        # least one character gets split off on every pass.
+        self.check_wrap('-'*10+'hello', 10,
+                        ['----------',
+                         '               h',
+                         '               e',
+                         '               l',
+                         '               l',
+                         '               o'],
+                        subsequent_indent = ' '*15)
+
+    def test_nobreak_long(self):
+        # Test with break_long_words disabled
+        self.wrapper.break_long_words = 0
+        self.wrapper.width = 30
+        expect = ['Did you say',
+                  '"supercalifragilisticexpialidocious?"',
+                  'How *do* you spell that odd',
+                  'word, anyways?'
+                  ]
+        result = self.wrapper.wrap(self.text)
+        self.check(result, expect)
+
+        # Same thing with kwargs passed to standalone wrap() function.
+        result = wrap(self.text, width=30, break_long_words=0)
+        self.check(result, expect)
+
+
+class IndentTestCases(BaseTestCase):
+
+    # called before each test method
+    def setUp(self):
+        self.text = '''\
+This paragraph will be filled, first without any indentation,
+and then with some (including a hanging indent).'''
+
+
+    def test_fill(self):
+        # Test the fill() method
+
+        expect = '''\
+This paragraph will be filled, first
+without any indentation, and then with
+some (including a hanging indent).'''
+
+        result = fill(self.text, 40)
+        self.check(result, expect)
+
+
+    def test_initial_indent(self):
+        # Test initial_indent parameter
+
+        expect = ["     This paragraph will be filled,",
+                  "first without any indentation, and then",
+                  "with some (including a hanging indent)."]
+        result = wrap(self.text, 40, initial_indent="     ")
+        self.check(result, expect)
+
+        expect = "\n".join(expect)
+        result = fill(self.text, 40, initial_indent="     ")
+        self.check(result, expect)
+
+
+    def test_subsequent_indent(self):
+        # Test subsequent_indent parameter
+
+        expect = '''\
+  * This paragraph will be filled, first
+    without any indentation, and then
+    with some (including a hanging
+    indent).'''
+
+        result = fill(self.text, 40,
+                      initial_indent="  * ", subsequent_indent="    ")
+        self.check(result, expect)
+
+
+# Despite the similar names, DedentTestCase is *not* the inverse
+# of IndentTestCase!
+class DedentTestCase(unittest.TestCase):
+
+    def assertUnchanged(self, text):
+        """assert that dedent() has no effect on 'text'"""
+        self.assertEquals(text, dedent(text))
+
+    def test_dedent_nomargin(self):
+        # No lines indented.
+        text = "Hello there.\nHow are you?\nOh good, I'm glad."
+        self.assertUnchanged(text)
+
+        # Similar, with a blank line.
+        text = "Hello there.\n\nBoo!"
+        self.assertUnchanged(text)
+
+        # Some lines indented, but overall margin is still zero.
+        text = "Hello there.\n  This is indented."
+        self.assertUnchanged(text)
+
+        # Again, add a blank line.
+        text = "Hello there.\n\n  Boo!\n"
+        self.assertUnchanged(text)
+
+    def test_dedent_even(self):
+        # All lines indented by two spaces.
+        text = "  Hello there.\n  How are ya?\n  Oh good."
+        expect = "Hello there.\nHow are ya?\nOh good."
+        self.assertEquals(expect, dedent(text))
+
+        # Same, with blank lines.
+        text = "  Hello there.\n\n  How are ya?\n  Oh good.\n"
+        expect = "Hello there.\n\nHow are ya?\nOh good.\n"
+        self.assertEquals(expect, dedent(text))
+
+        # Now indent one of the blank lines.
+        text = "  Hello there.\n  \n  How are ya?\n  Oh good.\n"
+        expect = "Hello there.\n\nHow are ya?\nOh good.\n"
+        self.assertEquals(expect, dedent(text))
+
+    def test_dedent_uneven(self):
+        # Lines indented unevenly.
+        text = '''\
+        def foo():
+            while 1:
+                return foo
+        '''
+        expect = '''\
+def foo():
+    while 1:
+        return foo
+'''
+        self.assertEquals(expect, dedent(text))
+
+        # Uneven indentation with a blank line.
+        text = "  Foo\n    Bar\n\n   Baz\n"
+        expect = "Foo\n  Bar\n\n Baz\n"
+        self.assertEquals(expect, dedent(text))
+
+        # Uneven indentation with a whitespace-only line.
+        text = "  Foo\n    Bar\n \n   Baz\n"
+        expect = "Foo\n  Bar\n\n Baz\n"
+        self.assertEquals(expect, dedent(text))
+
+    # dedent() should not mangle internal tabs
+    def test_dedent_preserve_internal_tabs(self):
+        text = "  hello\tthere\n  how are\tyou?"
+        expect = "hello\tthere\nhow are\tyou?"
+        self.assertEquals(expect, dedent(text))
+
+        # make sure that it preserves tabs when it's not making any
+        # changes at all
+        self.assertEquals(expect, dedent(expect))
+
+    # dedent() should not mangle tabs in the margin (i.e.
+    # tabs and spaces both count as margin, but are *not*
+    # considered equivalent)
+    def test_dedent_preserve_margin_tabs(self):
+        text = "  hello there\n\thow are you?"
+        self.assertUnchanged(text)
+
+        # same effect even if we have 8 spaces
+        text = "        hello there\n\thow are you?"
+        self.assertUnchanged(text)
+
+        # dedent() only removes whitespace that can be uniformly removed!
+        text = "\thello there\n\thow are you?"
+        expect = "hello there\nhow are you?"
+        self.assertEquals(expect, dedent(text))
+
+        text = "  \thello there\n  \thow are you?"
+        self.assertEquals(expect, dedent(text))
+
+        text = "  \t  hello there\n  \t  how are you?"
+        self.assertEquals(expect, dedent(text))
+
+        text = "  \thello there\n  \t  how are you?"
+        expect = "hello there\n  how are you?"
+        self.assertEquals(expect, dedent(text))
+
+
+def test_main():
+    test_support.run_unittest(WrapTestCase,
+                              LongWordTestCase,
+                              IndentTestCases,
+                              DedentTestCase)
+
+if __name__ == '__main__':
+    test_main()

Added: vendor/Python/current/Lib/test/test_thread.py
===================================================================
--- vendor/Python/current/Lib/test/test_thread.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_thread.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,160 @@
+# Very rudimentary test of thread module
+
+# Create a bunch of threads, let each do some work, wait until all are done
+
+from test.test_support import verbose
+import random
+import thread
+import time
+
+mutex = thread.allocate_lock()
+rmutex = thread.allocate_lock() # for calls to random
+running = 0
+done = thread.allocate_lock()
+done.acquire()
+
+numtasks = 10
+
+def task(ident):
+    global running
+    rmutex.acquire()
+    delay = random.random() * numtasks
+    rmutex.release()
+    if verbose:
+        print 'task', ident, 'will run for', round(delay, 1), 'sec'
+    time.sleep(delay)
+    if verbose:
+        print 'task', ident, 'done'
+    mutex.acquire()
+    running = running - 1
+    if running == 0:
+        done.release()
+    mutex.release()
+
+next_ident = 0
+def newtask():
+    global next_ident, running
+    mutex.acquire()
+    next_ident = next_ident + 1
+    if verbose:
+        print 'creating task', next_ident
+    thread.start_new_thread(task, (next_ident,))
+    running = running + 1
+    mutex.release()
+
+for i in range(numtasks):
+    newtask()
+
+print 'waiting for all tasks to complete'
+done.acquire()
+print 'all tasks done'
+
+class barrier:
+    def __init__(self, n):
+        self.n = n
+        self.waiting = 0
+        self.checkin  = thread.allocate_lock()
+        self.checkout = thread.allocate_lock()
+        self.checkout.acquire()
+
+    def enter(self):
+        checkin, checkout = self.checkin, self.checkout
+
+        checkin.acquire()
+        self.waiting = self.waiting + 1
+        if self.waiting == self.n:
+            self.waiting = self.n - 1
+            checkout.release()
+            return
+        checkin.release()
+
+        checkout.acquire()
+        self.waiting = self.waiting - 1
+        if self.waiting == 0:
+            checkin.release()
+            return
+        checkout.release()
+
+numtrips = 3
+def task2(ident):
+    global running
+    for i in range(numtrips):
+        if ident == 0:
+            # give it a good chance to enter the next
+            # barrier before the others are all out
+            # of the current one
+            delay = 0.001
+        else:
+            rmutex.acquire()
+            delay = random.random() * numtasks
+            rmutex.release()
+        if verbose:
+            print 'task', ident, 'will run for', round(delay, 1), 'sec'
+        time.sleep(delay)
+        if verbose:
+            print 'task', ident, 'entering barrier', i
+        bar.enter()
+        if verbose:
+            print 'task', ident, 'leaving barrier', i
+    mutex.acquire()
+    running -= 1
+    # Must release mutex before releasing done, else the main thread can
+    # exit and set mutex to None as part of global teardown; then
+    # mutex.release() raises AttributeError.
+    finished = running == 0
+    mutex.release()
+    if finished:
+        done.release()
+
+print '\n*** Barrier Test ***'
+if done.acquire(0):
+    raise ValueError, "'done' should have remained acquired"
+bar = barrier(numtasks)
+running = numtasks
+for i in range(numtasks):
+    thread.start_new_thread(task2, (i,))
+done.acquire()
+print 'all tasks done'
+
+# not all platforms support changing thread stack size
+print '\n*** Changing thread stack size ***'
+if thread.stack_size() != 0:
+    raise ValueError, "initial stack_size not 0"
+
+thread.stack_size(0)
+if thread.stack_size() != 0:
+    raise ValueError, "stack_size not reset to default"
+
+from os import name as os_name
+if os_name in ("nt", "os2", "posix"):
+
+    tss_supported = 1
+    try:
+        thread.stack_size(4096)
+    except ValueError:
+        print 'caught expected ValueError setting stack_size(4096)'
+    except thread.error:
+        tss_supported = 0
+        print 'platform does not support changing thread stack size'
+
+    if tss_supported:
+        failed = lambda s, e: s != e
+        fail_msg = "stack_size(%d) failed - should succeed"
+        for tss in (262144, 0x100000, 0):
+            thread.stack_size(tss)
+            if failed(thread.stack_size(), tss):
+                raise ValueError, fail_msg % tss
+            print 'successfully set stack_size(%d)' % tss
+
+        for tss in (262144, 0x100000):
+            print 'trying stack_size = %d' % tss
+            next_ident = 0
+            for i in range(numtasks):
+                newtask()
+
+            print 'waiting for all tasks to complete'
+            done.acquire()
+            print 'all tasks done'
+
+        # reset stack size to default
+        thread.stack_size(0)

Added: vendor/Python/current/Lib/test/test_threaded_import.py
===================================================================
--- vendor/Python/current/Lib/test/test_threaded_import.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_threaded_import.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,75 @@
+# This is a variant of the very old (early 90's) file
+# Demo/threads/bug.py.  It simply provokes a number of threads into
+# trying to import the same module "at the same time".
+# There are no pleasant failure modes -- most likely is that Python
+# complains several times about module random having no attribute
+# randrange, and then Python hangs.
+
+import thread
+from test.test_support import verbose, TestSkipped, TestFailed
+
+critical_section = thread.allocate_lock()
+done = thread.allocate_lock()
+
+def task():
+    global N, critical_section, done
+    import random
+    x = random.randrange(1, 3)
+    critical_section.acquire()
+    N -= 1
+    # Must release critical_section before releasing done, else the main
+    # thread can exit and set critical_section to None as part of global
+    # teardown; then critical_section.release() raises AttributeError.
+    finished = N == 0
+    critical_section.release()
+    if finished:
+        done.release()
+
+def test_import_hangers():
+    import sys
+    if verbose:
+        print "testing import hangers ...",
+
+    import test.threaded_import_hangers
+    try:
+        if test.threaded_import_hangers.errors:
+            raise TestFailed(test.threaded_import_hangers.errors)
+        elif verbose:
+            print "OK."
+    finally:
+        # In case this test is run again, make sure the helper module
+        # gets loaded from scratch again.
+        del sys.modules['test.threaded_import_hangers']
+
+# Tricky:  When regrtest imports this module, the thread running regrtest
+# grabs the import lock and won't let go of it until this module returns.
+# All other threads attempting an import hang for the duration.  Since
+# this test spawns threads that do little *but* import, we can't do that
+# successfully until after this module finishes importing and regrtest
+# regains control.  To make this work, a special case was added to
+# regrtest to invoke a module's "test_main" function (if any) after
+# importing it.
+
+def test_main():        # magic name!  see above
+    global N, done
+
+    import imp
+    if imp.lock_held():
+        # This triggers on, e.g., from test import autotest.
+        raise TestSkipped("can't run when import lock is held")
+
+    done.acquire()
+    for N in (20, 50) * 3:
+        if verbose:
+            print "Trying", N, "threads ...",
+        for i in range(N):
+            thread.start_new_thread(task, ())
+        done.acquire()
+        if verbose:
+            print "OK."
+    done.release()
+
+    test_import_hangers()
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_threadedtempfile.py
===================================================================
--- vendor/Python/current/Lib/test/test_threadedtempfile.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_threadedtempfile.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,86 @@
+"""
+Create and delete FILES_PER_THREAD temp files (via tempfile.TemporaryFile)
+in each of NUM_THREADS threads, recording the number of successes and
+failures.  A failure is a bug in tempfile, and may be due to:
+
++ Trying to create more than one tempfile with the same name.
++ Trying to delete a tempfile that doesn't still exist.
++ Something we've never seen before.
+
+By default, NUM_THREADS == 20 and FILES_PER_THREAD == 50.  This is enough to
+create about 150 failures per run under Win98SE in 2.0, and runs pretty
+quickly. Guido reports needing to boost FILES_PER_THREAD to 500 before
+provoking a 2.0 failure under Linux.  Run the test alone to boost either
+via cmdline switches:
+
+-f  FILES_PER_THREAD (int)
+-t  NUM_THREADS (int)
+"""
+
+NUM_THREADS = 20        # change w/ -t option
+FILES_PER_THREAD = 50   # change w/ -f option
+
+import thread # If this fails, we can't test this module
+import threading
+from test.test_support import TestFailed, threading_setup, threading_cleanup
+import StringIO
+from traceback import print_exc
+import tempfile
+
+startEvent = threading.Event()
+
+class TempFileGreedy(threading.Thread):
+    error_count = 0
+    ok_count = 0
+
+    def run(self):
+        self.errors = StringIO.StringIO()
+        startEvent.wait()
+        for i in range(FILES_PER_THREAD):
+            try:
+                f = tempfile.TemporaryFile("w+b")
+                f.close()
+            except:
+                self.error_count += 1
+                print_exc(file=self.errors)
+            else:
+                self.ok_count += 1
+
+def test_main():
+    threads = []
+    thread_info = threading_setup()
+
+    print "Creating"
+    for i in range(NUM_THREADS):
+        t = TempFileGreedy()
+        threads.append(t)
+        t.start()
+
+    print "Starting"
+    startEvent.set()
+
+    print "Reaping"
+    ok = errors = 0
+    for t in threads:
+        t.join()
+        ok += t.ok_count
+        errors += t.error_count
+        if t.error_count:
+            print '%s errors:\n%s' % (t.getName(), t.errors.getvalue())
+
+    msg = "Done: errors %d ok %d" % (errors, ok)
+    print msg
+    if errors:
+        raise TestFailed(msg)
+
+    threading_cleanup(*thread_info)
+
+if __name__ == "__main__":
+    import sys, getopt
+    opts, args = getopt.getopt(sys.argv[1:], "t:f:")
+    for o, v in opts:
+        if o == "-f":
+            FILES_PER_THREAD = int(v)
+        elif o == "-t":
+            NUM_THREADS = int(v)
+    test_main()

Added: vendor/Python/current/Lib/test/test_threading.py
===================================================================
--- vendor/Python/current/Lib/test/test_threading.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_threading.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,208 @@
+# Very rudimentary test of threading module
+
+import test.test_support
+from test.test_support import verbose
+import random
+import threading
+import thread
+import time
+import unittest
+
+# A trivial mutable counter.
+class Counter(object):
+    def __init__(self):
+        self.value = 0
+    def inc(self):
+        self.value += 1
+    def dec(self):
+        self.value -= 1
+    def get(self):
+        return self.value
+
+class TestThread(threading.Thread):
+    def __init__(self, name, testcase, sema, mutex, nrunning):
+        threading.Thread.__init__(self, name=name)
+        self.testcase = testcase
+        self.sema = sema
+        self.mutex = mutex
+        self.nrunning = nrunning
+
+    def run(self):
+        delay = random.random() * 2
+        if verbose:
+            print 'task', self.getName(), 'will run for', delay, 'sec'
+
+        self.sema.acquire()
+
+        self.mutex.acquire()
+        self.nrunning.inc()
+        if verbose:
+            print self.nrunning.get(), 'tasks are running'
+        self.testcase.assert_(self.nrunning.get() <= 3)
+        self.mutex.release()
+
+        time.sleep(delay)
+        if verbose:
+            print 'task', self.getName(), 'done'
+
+        self.mutex.acquire()
+        self.nrunning.dec()
+        self.testcase.assert_(self.nrunning.get() >= 0)
+        if verbose:
+            print self.getName(), 'is finished.', self.nrunning.get(), \
+                  'tasks are running'
+        self.mutex.release()
+
+        self.sema.release()
+
+class ThreadTests(unittest.TestCase):
+
+    # Create a bunch of threads, let each do some work, wait until all are
+    # done.
+    def test_various_ops(self):
+        # This takes about n/3 seconds to run (about n/3 clumps of tasks,
+        # times about 1 second per clump).
+        NUMTASKS = 10
+
+        # no more than 3 of the 10 can run at once
+        sema = threading.BoundedSemaphore(value=3)
+        mutex = threading.RLock()
+        numrunning = Counter()
+
+        threads = []
+
+        for i in range(NUMTASKS):
+            t = TestThread("<thread %d>"%i, self, sema, mutex, numrunning)
+            threads.append(t)
+            t.start()
+
+        if verbose:
+            print 'waiting for all tasks to complete'
+        for t in threads:
+            t.join(NUMTASKS)
+            self.assert_(not t.isAlive())
+        if verbose:
+            print 'all tasks done'
+        self.assertEqual(numrunning.get(), 0)
+
+    # run with a small(ish) thread stack size (256kB)
+    def test_various_ops_small_stack(self):
+        if verbose:
+            print 'with 256kB thread stack size...'
+        try:
+            threading.stack_size(262144)
+        except thread.error:
+            if verbose:
+                print 'platform does not support changing thread stack size'
+            return
+        self.test_various_ops()
+        threading.stack_size(0)
+
+    # run with a large thread stack size (1MB)
+    def test_various_ops_large_stack(self):
+        if verbose:
+            print 'with 1MB thread stack size...'
+        try:
+            threading.stack_size(0x100000)
+        except thread.error:
+            if verbose:
+                print 'platform does not support changing thread stack size'
+            return
+        self.test_various_ops()
+        threading.stack_size(0)
+
+    def test_foreign_thread(self):
+        # Check that a "foreign" thread can use the threading module.
+        def f(mutex):
+            # Acquiring an RLock forces an entry for the foreign
+            # thread to get made in the threading._active map.
+            r = threading.RLock()
+            r.acquire()
+            r.release()
+            mutex.release()
+
+        mutex = threading.Lock()
+        mutex.acquire()
+        tid = thread.start_new_thread(f, (mutex,))
+        # Wait for the thread to finish.
+        mutex.acquire()
+        self.assert_(tid in threading._active)
+        self.assert_(isinstance(threading._active[tid],
+                                threading._DummyThread))
+        del threading._active[tid]
+
+    # PyThreadState_SetAsyncExc() is a CPython-only gimmick, not (currently)
+    # exposed at the Python level.  This test relies on ctypes to get at it.
+    def test_PyThreadState_SetAsyncExc(self):
+        try:
+            import ctypes
+        except ImportError:
+            if verbose:
+                print "test_PyThreadState_SetAsyncExc can't import ctypes"
+            return  # can't do anything
+
+        set_async_exc = ctypes.pythonapi.PyThreadState_SetAsyncExc
+
+        class AsyncExc(Exception):
+            pass
+
+        exception = ctypes.py_object(AsyncExc)
+
+        # `worker_started` is set by the thread when it's inside a try/except
+        # block waiting to catch the asynchronously set AsyncExc exception.
+        # `worker_saw_exception` is set by the thread upon catching that
+        # exception.
+        worker_started = threading.Event()
+        worker_saw_exception = threading.Event()
+
+        class Worker(threading.Thread):
+            def run(self):
+                self.id = thread.get_ident()
+                self.finished = False
+
+                try:
+                    while True:
+                        worker_started.set()
+                        time.sleep(0.1)
+                except AsyncExc:
+                    self.finished = True
+                    worker_saw_exception.set()
+
+        t = Worker()
+        t.setDaemon(True) # so if this fails, we don't hang Python at shutdown
+        t.start()
+        if verbose:
+            print "    started worker thread"
+
+        # Try a thread id that doesn't make sense.
+        if verbose:
+            print "    trying nonsensical thread id"
+        result = set_async_exc(ctypes.c_long(-1), exception)
+        self.assertEqual(result, 0)  # no thread states modified
+
+        # Now raise an exception in the worker thread.
+        if verbose:
+            print "    waiting for worker thread to get started"
+        worker_started.wait()
+        if verbose:
+            print "    verifying worker hasn't exited"
+        self.assert_(not t.finished)
+        if verbose:
+            print "    attempting to raise asynch exception in worker"
+        result = set_async_exc(ctypes.c_long(t.id), exception)
+        self.assertEqual(result, 1) # one thread state modified
+        if verbose:
+            print "    waiting for worker to say it caught the exception"
+        worker_saw_exception.wait(timeout=10)
+        self.assert_(t.finished)
+        if verbose:
+            print "    all OK -- joining worker"
+        if t.finished:
+            t.join()
+        # else the thread is still running, and we have no way to kill it
+
+def test_main():
+    test.test_support.run_unittest(ThreadTests)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_threading_local.py
===================================================================
--- vendor/Python/current/Lib/test/test_threading_local.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_threading_local.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,26 @@
+import unittest
+from doctest import DocTestSuite
+from test import test_support
+
+def test_main():
+    suite = DocTestSuite('_threading_local')
+
+    try:
+        from thread import _local
+    except ImportError:
+        pass
+    else:
+        import _threading_local
+        local_orig = _threading_local.local
+        def setUp(test):
+            _threading_local.local = _local
+        def tearDown(test):
+            _threading_local.local = local_orig
+        suite.addTest(DocTestSuite('_threading_local',
+                                   setUp=setUp, tearDown=tearDown)
+                      )
+
+    test_support.run_suite(suite)
+
+if __name__ == '__main__':
+    test_main()

Added: vendor/Python/current/Lib/test/test_threadsignals.py
===================================================================
--- vendor/Python/current/Lib/test/test_threadsignals.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_threadsignals.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,84 @@
+"""PyUnit testing that threads honor our signal semantics"""
+
+import unittest
+import thread
+import signal
+import os
+import sys
+from test.test_support import run_unittest, TestSkipped
+
+if sys.platform[:3] in ('win', 'os2') or sys.platform=='riscos':
+    raise TestSkipped, "Can't test signal on %s" % sys.platform
+
+process_pid = os.getpid()
+signalled_all=thread.allocate_lock()
+
+
+def registerSignals((for_usr1, for_usr2, for_alrm)):
+    usr1 = signal.signal(signal.SIGUSR1, for_usr1)
+    usr2 = signal.signal(signal.SIGUSR2, for_usr2)
+    alrm = signal.signal(signal.SIGALRM, for_alrm)
+    return usr1, usr2, alrm
+
+
+# The signal handler. Just note that the signal occurred and
+# from who.
+def handle_signals(sig,frame):
+    signal_blackboard[sig]['tripped'] += 1
+    signal_blackboard[sig]['tripped_by'] = thread.get_ident()
+
+# a function that will be spawned as a separate thread.
+def send_signals():
+    os.kill(process_pid, signal.SIGUSR1)
+    os.kill(process_pid, signal.SIGUSR2)
+    signalled_all.release()
+
+class ThreadSignals(unittest.TestCase):
+    """Test signal handling semantics of threads.
+       We spawn a thread, have the thread send two signals, and
+       wait for it to finish. Check that we got both signals
+       and that they were run by the main thread.
+    """
+    def test_signals(self):
+        signalled_all.acquire()
+        self.spawnSignallingThread()
+        signalled_all.acquire()
+        # the signals that we asked the kernel to send
+        # will come back, but we don't know when.
+        # (it might even be after the thread exits
+        # and might be out of order.)  If we haven't seen
+        # the signals yet, send yet another signal and
+        # wait for it return.
+        if signal_blackboard[signal.SIGUSR1]['tripped'] == 0 \
+           or signal_blackboard[signal.SIGUSR2]['tripped'] == 0:
+            signal.alarm(1)
+            signal.pause()
+            signal.alarm(0)
+
+        self.assertEqual( signal_blackboard[signal.SIGUSR1]['tripped'], 1)
+        self.assertEqual( signal_blackboard[signal.SIGUSR1]['tripped_by'],
+                           thread.get_ident())
+        self.assertEqual( signal_blackboard[signal.SIGUSR2]['tripped'], 1)
+        self.assertEqual( signal_blackboard[signal.SIGUSR2]['tripped_by'],
+                           thread.get_ident())
+        signalled_all.release()
+
+    def spawnSignallingThread(self):
+        thread.start_new_thread(send_signals, ())
+
+
+def test_main():
+    global signal_blackboard
+
+    signal_blackboard = { signal.SIGUSR1 : {'tripped': 0, 'tripped_by': 0 },
+                          signal.SIGUSR2 : {'tripped': 0, 'tripped_by': 0 },
+                          signal.SIGALRM : {'tripped': 0, 'tripped_by': 0 } }
+
+    oldsigs = registerSignals((handle_signals, handle_signals, handle_signals))
+    try:
+        run_unittest(ThreadSignals)
+    finally:
+        registerSignals(oldsigs)
+
+if __name__ == '__main__':
+    test_main()

Added: vendor/Python/current/Lib/test/test_time.py
===================================================================
--- vendor/Python/current/Lib/test/test_time.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_time.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,222 @@
+from test import test_support
+import time
+import unittest
+
+
+class TimeTestCase(unittest.TestCase):
+
+    def setUp(self):
+        self.t = time.time()
+
+    def test_data_attributes(self):
+        time.altzone
+        time.daylight
+        time.timezone
+        time.tzname
+
+    def test_clock(self):
+        time.clock()
+
+    def test_conversions(self):
+        self.assert_(time.ctime(self.t)
+                     == time.asctime(time.localtime(self.t)))
+        self.assert_(long(time.mktime(time.localtime(self.t)))
+                     == long(self.t))
+
+    def test_sleep(self):
+        time.sleep(1.2)
+
+    def test_strftime(self):
+        tt = time.gmtime(self.t)
+        for directive in ('a', 'A', 'b', 'B', 'c', 'd', 'H', 'I',
+                          'j', 'm', 'M', 'p', 'S',
+                          'U', 'w', 'W', 'x', 'X', 'y', 'Y', 'Z', '%'):
+            format = ' %' + directive
+            try:
+                time.strftime(format, tt)
+            except ValueError:
+                self.fail('conversion specifier: %r failed.' % format)
+
+    def test_strftime_bounds_checking(self):
+        # Make sure that strftime() checks the bounds of the various parts
+        #of the time tuple (0 is valid for *all* values).
+
+        # Check year [1900, max(int)]
+        self.assertRaises(ValueError, time.strftime, '',
+                            (1899, 1, 1, 0, 0, 0, 0, 1, -1))
+        if time.accept2dyear:
+            self.assertRaises(ValueError, time.strftime, '',
+                                (-1, 1, 1, 0, 0, 0, 0, 1, -1))
+            self.assertRaises(ValueError, time.strftime, '',
+                                (100, 1, 1, 0, 0, 0, 0, 1, -1))
+        # Check month [1, 12] + zero support
+        self.assertRaises(ValueError, time.strftime, '',
+                            (1900, -1, 1, 0, 0, 0, 0, 1, -1))
+        self.assertRaises(ValueError, time.strftime, '',
+                            (1900, 13, 1, 0, 0, 0, 0, 1, -1))
+        # Check day of month [1, 31] + zero support
+        self.assertRaises(ValueError, time.strftime, '',
+                            (1900, 1, -1, 0, 0, 0, 0, 1, -1))
+        self.assertRaises(ValueError, time.strftime, '',
+                            (1900, 1, 32, 0, 0, 0, 0, 1, -1))
+        # Check hour [0, 23]
+        self.assertRaises(ValueError, time.strftime, '',
+                            (1900, 1, 1, -1, 0, 0, 0, 1, -1))
+        self.assertRaises(ValueError, time.strftime, '',
+                            (1900, 1, 1, 24, 0, 0, 0, 1, -1))
+        # Check minute [0, 59]
+        self.assertRaises(ValueError, time.strftime, '',
+                            (1900, 1, 1, 0, -1, 0, 0, 1, -1))
+        self.assertRaises(ValueError, time.strftime, '',
+                            (1900, 1, 1, 0, 60, 0, 0, 1, -1))
+        # Check second [0, 61]
+        self.assertRaises(ValueError, time.strftime, '',
+                            (1900, 1, 1, 0, 0, -1, 0, 1, -1))
+        # C99 only requires allowing for one leap second, but Python's docs say
+        # allow two leap seconds (0..61)
+        self.assertRaises(ValueError, time.strftime, '',
+                            (1900, 1, 1, 0, 0, 62, 0, 1, -1))
+        # No check for upper-bound day of week;
+        #  value forced into range by a ``% 7`` calculation.
+        # Start check at -2 since gettmarg() increments value before taking
+        #  modulo.
+        self.assertRaises(ValueError, time.strftime, '',
+                            (1900, 1, 1, 0, 0, 0, -2, 1, -1))
+        # Check day of the year [1, 366] + zero support
+        self.assertRaises(ValueError, time.strftime, '',
+                            (1900, 1, 1, 0, 0, 0, 0, -1, -1))
+        self.assertRaises(ValueError, time.strftime, '',
+                            (1900, 1, 1, 0, 0, 0, 0, 367, -1))
+        # Check daylight savings flag [-1, 1]
+        self.assertRaises(ValueError, time.strftime, '',
+                            (1900, 1, 1, 0, 0, 0, 0, 1, -2))
+        self.assertRaises(ValueError, time.strftime, '',
+                            (1900, 1, 1, 0, 0, 0, 0, 1, 2))
+
+    def test_default_values_for_zero(self):
+        # Make sure that using all zeros uses the proper default values.
+        # No test for daylight savings since strftime() does not change output
+        # based on its value.
+        expected = "2000 01 01 00 00 00 1 001"
+        result = time.strftime("%Y %m %d %H %M %S %w %j", (0,)*9)
+        self.assertEquals(expected, result)
+
+    def test_strptime(self):
+        tt = time.gmtime(self.t)
+        for directive in ('a', 'A', 'b', 'B', 'c', 'd', 'H', 'I',
+                          'j', 'm', 'M', 'p', 'S',
+                          'U', 'w', 'W', 'x', 'X', 'y', 'Y', 'Z', '%'):
+            format = ' %' + directive
+            try:
+                time.strptime(time.strftime(format, tt), format)
+            except ValueError:
+                self.fail('conversion specifier: %r failed.' % format)
+
+    def test_asctime(self):
+        time.asctime(time.gmtime(self.t))
+        self.assertRaises(TypeError, time.asctime, 0)
+
+    def test_tzset(self):
+        if not hasattr(time, "tzset"):
+            return # Can't test this; don't want the test suite to fail
+
+        from os import environ
+
+        # Epoch time of midnight Dec 25th 2002. Never DST in northern
+        # hemisphere.
+        xmas2002 = 1040774400.0
+
+        # These formats are correct for 2002, and possibly future years
+        # This format is the 'standard' as documented at:
+        # http://www.opengroup.org/onlinepubs/007904975/basedefs/xbd_chap08.html
+        # They are also documented in the tzset(3) man page on most Unix
+        # systems.
+        eastern = 'EST+05EDT,M4.1.0,M10.5.0'
+        victoria = 'AEST-10AEDT-11,M10.5.0,M3.5.0'
+        utc='UTC+0'
+
+        org_TZ = environ.get('TZ',None)
+        try:
+            # Make sure we can switch to UTC time and results are correct
+            # Note that unknown timezones default to UTC.
+            # Note that altzone is undefined in UTC, as there is no DST
+            environ['TZ'] = eastern
+            time.tzset()
+            environ['TZ'] = utc
+            time.tzset()
+            self.failUnlessEqual(
+                time.gmtime(xmas2002), time.localtime(xmas2002)
+                )
+            self.failUnlessEqual(time.daylight, 0)
+            self.failUnlessEqual(time.timezone, 0)
+            self.failUnlessEqual(time.localtime(xmas2002).tm_isdst, 0)
+
+            # Make sure we can switch to US/Eastern
+            environ['TZ'] = eastern
+            time.tzset()
+            self.failIfEqual(time.gmtime(xmas2002), time.localtime(xmas2002))
+            self.failUnlessEqual(time.tzname, ('EST', 'EDT'))
+            self.failUnlessEqual(len(time.tzname), 2)
+            self.failUnlessEqual(time.daylight, 1)
+            self.failUnlessEqual(time.timezone, 18000)
+            self.failUnlessEqual(time.altzone, 14400)
+            self.failUnlessEqual(time.localtime(xmas2002).tm_isdst, 0)
+            self.failUnlessEqual(len(time.tzname), 2)
+
+            # Now go to the southern hemisphere.
+            environ['TZ'] = victoria
+            time.tzset()
+            self.failIfEqual(time.gmtime(xmas2002), time.localtime(xmas2002))
+            self.failUnless(time.tzname[0] == 'AEST', str(time.tzname[0]))
+            self.failUnless(time.tzname[1] == 'AEDT', str(time.tzname[1]))
+            self.failUnlessEqual(len(time.tzname), 2)
+            self.failUnlessEqual(time.daylight, 1)
+            self.failUnlessEqual(time.timezone, -36000)
+            self.failUnlessEqual(time.altzone, -39600)
+            self.failUnlessEqual(time.localtime(xmas2002).tm_isdst, 1)
+
+        finally:
+            # Repair TZ environment variable in case any other tests
+            # rely on it.
+            if org_TZ is not None:
+                environ['TZ'] = org_TZ
+            elif environ.has_key('TZ'):
+                del environ['TZ']
+            time.tzset()
+
+    def test_insane_timestamps(self):
+        # It's possible that some platform maps time_t to double,
+        # and that this test will fail there.  This test should
+        # exempt such platforms (provided they return reasonable
+        # results!).
+        for func in time.ctime, time.gmtime, time.localtime:
+            for unreasonable in -1e200, 1e200:
+                self.assertRaises(ValueError, func, unreasonable)
+
+    def test_ctime_without_arg(self):
+        # Not sure how to check the values, since the clock could tick
+        # at any time.  Make sure these are at least accepted and
+        # don't raise errors.
+        time.ctime()
+        time.ctime(None)
+
+    def test_gmtime_without_arg(self):
+        gt0 = time.gmtime()
+        gt1 = time.gmtime(None)
+        t0 = time.mktime(gt0)
+        t1 = time.mktime(gt1)
+        self.assert_(0 <= (t1-t0) < 0.2)
+
+    def test_localtime_without_arg(self):
+        lt0 = time.localtime()
+        lt1 = time.localtime(None)
+        t0 = time.mktime(lt0)
+        t1 = time.mktime(lt1)
+        self.assert_(0 <= (t1-t0) < 0.2)
+
+def test_main():
+    test_support.run_unittest(TimeTestCase)
+
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_timeout.py
===================================================================
--- vendor/Python/current/Lib/test/test_timeout.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_timeout.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,198 @@
+"""Unit tests for socket timeout feature."""
+
+import unittest
+from test import test_support
+
+# This requires the 'network' resource as given on the regrtest command line.
+skip_expected = not test_support.is_resource_enabled('network')
+
+import time
+import socket
+
+
+class CreationTestCase(unittest.TestCase):
+    """Test case for socket.gettimeout() and socket.settimeout()"""
+
+    def setUp(self):
+        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+
+    def tearDown(self):
+        self.sock.close()
+
+    def testObjectCreation(self):
+        # Test Socket creation
+        self.assertEqual(self.sock.gettimeout(), None,
+                         "timeout not disabled by default")
+
+    def testFloatReturnValue(self):
+        # Test return value of gettimeout()
+        self.sock.settimeout(7.345)
+        self.assertEqual(self.sock.gettimeout(), 7.345)
+
+        self.sock.settimeout(3)
+        self.assertEqual(self.sock.gettimeout(), 3)
+
+        self.sock.settimeout(None)
+        self.assertEqual(self.sock.gettimeout(), None)
+
+    def testReturnType(self):
+        # Test return type of gettimeout()
+        self.sock.settimeout(1)
+        self.assertEqual(type(self.sock.gettimeout()), type(1.0))
+
+        self.sock.settimeout(3.9)
+        self.assertEqual(type(self.sock.gettimeout()), type(1.0))
+
+    def testTypeCheck(self):
+        # Test type checking by settimeout()
+        self.sock.settimeout(0)
+        self.sock.settimeout(0L)
+        self.sock.settimeout(0.0)
+        self.sock.settimeout(None)
+        self.assertRaises(TypeError, self.sock.settimeout, "")
+        self.assertRaises(TypeError, self.sock.settimeout, u"")
+        self.assertRaises(TypeError, self.sock.settimeout, ())
+        self.assertRaises(TypeError, self.sock.settimeout, [])
+        self.assertRaises(TypeError, self.sock.settimeout, {})
+        self.assertRaises(TypeError, self.sock.settimeout, 0j)
+
+    def testRangeCheck(self):
+        # Test range checking by settimeout()
+        self.assertRaises(ValueError, self.sock.settimeout, -1)
+        self.assertRaises(ValueError, self.sock.settimeout, -1L)
+        self.assertRaises(ValueError, self.sock.settimeout, -1.0)
+
+    def testTimeoutThenBlocking(self):
+        # Test settimeout() followed by setblocking()
+        self.sock.settimeout(10)
+        self.sock.setblocking(1)
+        self.assertEqual(self.sock.gettimeout(), None)
+        self.sock.setblocking(0)
+        self.assertEqual(self.sock.gettimeout(), 0.0)
+
+        self.sock.settimeout(10)
+        self.sock.setblocking(0)
+        self.assertEqual(self.sock.gettimeout(), 0.0)
+        self.sock.setblocking(1)
+        self.assertEqual(self.sock.gettimeout(), None)
+
+    def testBlockingThenTimeout(self):
+        # Test setblocking() followed by settimeout()
+        self.sock.setblocking(0)
+        self.sock.settimeout(1)
+        self.assertEqual(self.sock.gettimeout(), 1)
+
+        self.sock.setblocking(1)
+        self.sock.settimeout(1)
+        self.assertEqual(self.sock.gettimeout(), 1)
+
+
+class TimeoutTestCase(unittest.TestCase):
+    """Test case for socket.socket() timeout functions"""
+
+    # There are a number of tests here trying to make sure that an operation
+    # doesn't take too much longer than expected.  But competing machine
+    # activity makes it inevitable that such tests will fail at times.
+    # When fuzz was at 1.0, I (tim) routinely saw bogus failures on Win2K
+    # and Win98SE.  Boosting it to 2.0 helped a lot, but isn't a real
+    # solution.
+    fuzz = 2.0
+
+    def setUp(self):
+        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        self.addr_remote = ('www.python.org.', 80)
+        self.addr_local  = ('127.0.0.1', 25339)
+
+    def tearDown(self):
+        self.sock.close()
+
+    def testConnectTimeout(self):
+        # Test connect() timeout
+        _timeout = 0.001
+        self.sock.settimeout(_timeout)
+
+        # If we are too close to www.python.org, this test will fail.
+        # Pick a host that should be farther away.
+        if (socket.getfqdn().split('.')[-2:] == ['python', 'org'] or
+            socket.getfqdn().split('.')[-2:-1] == ['xs4all']):
+            self.addr_remote = ('tut.fi', 80)
+
+        _t1 = time.time()
+        self.failUnlessRaises(socket.error, self.sock.connect,
+                self.addr_remote)
+        _t2 = time.time()
+
+        _delta = abs(_t1 - _t2)
+        self.assert_(_delta < _timeout + self.fuzz,
+                     "timeout (%g) is more than %g seconds more than expected (%g)"
+                     %(_delta, self.fuzz, _timeout))
+
+    def testRecvTimeout(self):
+        # Test recv() timeout
+        _timeout = 0.02
+        self.sock.connect(self.addr_remote)
+        self.sock.settimeout(_timeout)
+
+        _t1 = time.time()
+        self.failUnlessRaises(socket.error, self.sock.recv, 1024)
+        _t2 = time.time()
+
+        _delta = abs(_t1 - _t2)
+        self.assert_(_delta < _timeout + self.fuzz,
+                     "timeout (%g) is %g seconds more than expected (%g)"
+                     %(_delta, self.fuzz, _timeout))
+
+    def testAcceptTimeout(self):
+        # Test accept() timeout
+        _timeout = 2
+        self.sock.settimeout(_timeout)
+        self.sock.bind(self.addr_local)
+        self.sock.listen(5)
+
+        _t1 = time.time()
+        self.failUnlessRaises(socket.error, self.sock.accept)
+        _t2 = time.time()
+
+        _delta = abs(_t1 - _t2)
+        self.assert_(_delta < _timeout + self.fuzz,
+                     "timeout (%g) is %g seconds more than expected (%g)"
+                     %(_delta, self.fuzz, _timeout))
+
+    def testRecvfromTimeout(self):
+        # Test recvfrom() timeout
+        _timeout = 2
+        self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+        self.sock.settimeout(_timeout)
+        self.sock.bind(self.addr_local)
+
+        _t1 = time.time()
+        self.failUnlessRaises(socket.error, self.sock.recvfrom, 8192)
+        _t2 = time.time()
+
+        _delta = abs(_t1 - _t2)
+        self.assert_(_delta < _timeout + self.fuzz,
+                     "timeout (%g) is %g seconds more than expected (%g)"
+                     %(_delta, self.fuzz, _timeout))
+
+    def testSend(self):
+        # Test send() timeout
+        # couldn't figure out how to test it
+        pass
+
+    def testSendto(self):
+        # Test sendto() timeout
+        # couldn't figure out how to test it
+        pass
+
+    def testSendall(self):
+        # Test sendall() timeout
+        # couldn't figure out how to test it
+        pass
+
+
+def test_main():
+    test_support.requires('network')
+    test_support.run_unittest(CreationTestCase, TimeoutTestCase)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_tokenize.py
===================================================================
--- vendor/Python/current/Lib/test/test_tokenize.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_tokenize.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,114 @@
+import os, glob, random
+from cStringIO import StringIO
+from test.test_support import (verbose, findfile, is_resource_enabled,
+                               TestFailed)
+from tokenize import (tokenize, generate_tokens, untokenize,
+                      NUMBER, NAME, OP, STRING)
+
+# Test roundtrip for `untokenize`.  `f` is a file path.  The source code in f
+# is tokenized, converted back to source code via tokenize.untokenize(),
+# and tokenized again from the latter.  The test fails if the second
+# tokenization doesn't match the first.
+def test_roundtrip(f):
+    ## print 'Testing:', f
+    fobj = open(f)
+    try:
+        fulltok = list(generate_tokens(fobj.readline))
+    finally:
+        fobj.close()
+
+    t1 = [tok[:2] for tok in fulltok]
+    newtext = untokenize(t1)
+    readline = iter(newtext.splitlines(1)).next
+    t2 = [tok[:2] for tok in generate_tokens(readline)]
+    if t1 != t2:
+        raise TestFailed("untokenize() roundtrip failed for %r" % f)
+
+# This is an example from the docs, set up as a doctest.
+def decistmt(s):
+    """Substitute Decimals for floats in a string of statements.
+
+    >>> from decimal import Decimal
+    >>> s = 'print +21.3e-5*-.1234/81.7'
+    >>> decistmt(s)
+    "print +Decimal ('21.3e-5')*-Decimal ('.1234')/Decimal ('81.7')"
+
+    The format of the exponent is inherited from the platform C library.
+    Known cases are "e-007" (Windows) and "e-07" (not Windows).  Since
+    we're only showing 12 digits, and the 13th isn't close to 5, the
+    rest of the output should be platform-independent.
+
+    >>> exec(s) #doctest: +ELLIPSIS
+    -3.21716034272e-0...7
+
+    Output from calculations with Decimal should be identical across all
+    platforms.
+
+    >>> exec(decistmt(s))
+    -3.217160342717258261933904529E-7
+    """
+
+    result = []
+    g = generate_tokens(StringIO(s).readline)   # tokenize the string
+    for toknum, tokval, _, _, _  in g:
+        if toknum == NUMBER and '.' in tokval:  # replace NUMBER tokens
+            result.extend([
+                (NAME, 'Decimal'),
+                (OP, '('),
+                (STRING, repr(tokval)),
+                (OP, ')')
+            ])
+        else:
+            result.append((toknum, tokval))
+    return untokenize(result)
+
+def test_main():
+    if verbose:
+        print 'starting...'
+
+    # This displays the tokenization of tokenize_tests.py to stdout, and
+    # regrtest.py checks that this equals the expected output (in the
+    # test/output/ directory).
+    f = open(findfile('tokenize_tests' + os.extsep + 'txt'))
+    tokenize(f.readline)
+    f.close()
+
+    # Now run test_roundtrip() over tokenize_test.py too, and over all
+    # (if the "compiler" resource is enabled) or a small random sample (if
+    # "compiler" is not enabled) of the test*.py files.
+    f = findfile('tokenize_tests' + os.extsep + 'txt')
+    test_roundtrip(f)
+
+    testdir = os.path.dirname(f) or os.curdir
+    testfiles = glob.glob(testdir + os.sep + 'test*.py')
+    if not is_resource_enabled('compiler'):
+        testfiles = random.sample(testfiles, 10)
+
+    for f in testfiles:
+        test_roundtrip(f)
+
+    # Test detecton of IndentationError.
+    sampleBadText = """\
+def foo():
+    bar
+  baz
+"""
+
+    try:
+        for tok in generate_tokens(StringIO(sampleBadText).readline):
+            pass
+    except IndentationError:
+        pass
+    else:
+        raise TestFailed("Did not detect IndentationError:")
+
+    # Run the doctests in this module.
+    from test import test_tokenize  # i.e., this module
+    from test.test_support import run_doctest
+    run_doctest(test_tokenize)
+
+    if verbose:
+        print 'finished'
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_trace.py
===================================================================
--- vendor/Python/current/Lib/test/test_trace.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_trace.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,626 @@
+# Testing the line trace facility.
+
+from test import test_support
+import unittest
+import sys
+import difflib
+
+# A very basic example.  If this fails, we're in deep trouble.
+def basic():
+    return 1
+
+basic.events = [(0, 'call'),
+                (1, 'line'),
+                (1, 'return')]
+
+# Many of the tests below are tricky because they involve pass statements.
+# If there is implicit control flow around a pass statement (in an except
+# clause or else caluse) under what conditions do you set a line number
+# following that clause?
+
+
+# The entire "while 0:" statement is optimized away.  No code
+# exists for it, so the line numbers skip directly from "del x"
+# to "x = 1".
+def arigo_example():
+    x = 1
+    del x
+    while 0:
+        pass
+    x = 1
+
+arigo_example.events = [(0, 'call'),
+                        (1, 'line'),
+                        (2, 'line'),
+                        (5, 'line'),
+                        (5, 'return')]
+
+# check that lines consisting of just one instruction get traced:
+def one_instr_line():
+    x = 1
+    del x
+    x = 1
+
+one_instr_line.events = [(0, 'call'),
+                         (1, 'line'),
+                         (2, 'line'),
+                         (3, 'line'),
+                         (3, 'return')]
+
+def no_pop_tops():      # 0
+    x = 1               # 1
+    for a in range(2):  # 2
+        if a:           # 3
+            x = 1       # 4
+        else:           # 5
+            x = 1       # 6
+
+no_pop_tops.events = [(0, 'call'),
+                      (1, 'line'),
+                      (2, 'line'),
+                      (3, 'line'),
+                      (6, 'line'),
+                      (2, 'line'),
+                      (3, 'line'),
+                      (4, 'line'),
+                      (2, 'line'),
+                      (2, 'return')]
+
+def no_pop_blocks():
+    y = 1
+    while not y:
+        bla
+    x = 1
+
+no_pop_blocks.events = [(0, 'call'),
+                        (1, 'line'),
+                        (2, 'line'),
+                        (4, 'line'),
+                        (4, 'return')]
+
+def called(): # line -3
+    x = 1
+
+def call():   # line 0
+    called()
+
+call.events = [(0, 'call'),
+               (1, 'line'),
+               (-3, 'call'),
+               (-2, 'line'),
+               (-2, 'return'),
+               (1, 'return')]
+
+def raises():
+    raise Exception
+
+def test_raise():
+    try:
+        raises()
+    except Exception, exc:
+        x = 1
+
+test_raise.events = [(0, 'call'),
+                     (1, 'line'),
+                     (2, 'line'),
+                     (-3, 'call'),
+                     (-2, 'line'),
+                     (-2, 'exception'),
+                     (-2, 'return'),
+                     (2, 'exception'),
+                     (3, 'line'),
+                     (4, 'line'),
+                     (4, 'return')]
+
+def _settrace_and_return(tracefunc):
+    sys.settrace(tracefunc)
+    sys._getframe().f_back.f_trace = tracefunc
+def settrace_and_return(tracefunc):
+    _settrace_and_return(tracefunc)
+
+settrace_and_return.events = [(1, 'return')]
+
+def _settrace_and_raise(tracefunc):
+    sys.settrace(tracefunc)
+    sys._getframe().f_back.f_trace = tracefunc
+    raise RuntimeError
+def settrace_and_raise(tracefunc):
+    try:
+        _settrace_and_raise(tracefunc)
+    except RuntimeError, exc:
+        pass
+
+settrace_and_raise.events = [(2, 'exception'),
+                             (3, 'line'),
+                             (4, 'line'),
+                             (4, 'return')]
+
+# implicit return example
+# This test is interesting because of the else: pass
+# part of the code.  The code generate for the true
+# part of the if contains a jump past the else branch.
+# The compiler then generates an implicit "return None"
+# Internally, the compiler visits the pass statement
+# and stores its line number for use on the next instruction.
+# The next instruction is the implicit return None.
+def ireturn_example():
+    a = 5
+    b = 5
+    if a == b:
+        b = a+1
+    else:
+        pass
+
+ireturn_example.events = [(0, 'call'),
+                          (1, 'line'),
+                          (2, 'line'),
+                          (3, 'line'),
+                          (4, 'line'),
+                          (6, 'line'),
+                          (6, 'return')]
+
+# Tight loop with while(1) example (SF #765624)
+def tightloop_example():
+    items = range(0, 3)
+    try:
+        i = 0
+        while 1:
+            b = items[i]; i+=1
+    except IndexError:
+        pass
+
+tightloop_example.events = [(0, 'call'),
+                            (1, 'line'),
+                            (2, 'line'),
+                            (3, 'line'),
+                            (4, 'line'),
+                            (5, 'line'),
+                            (5, 'line'),
+                            (5, 'line'),
+                            (5, 'line'),
+                            (5, 'exception'),
+                            (6, 'line'),
+                            (7, 'line'),
+                            (7, 'return')]
+
+def tighterloop_example():
+    items = range(1, 4)
+    try:
+        i = 0
+        while 1: i = items[i]
+    except IndexError:
+        pass
+
+tighterloop_example.events = [(0, 'call'),
+                            (1, 'line'),
+                            (2, 'line'),
+                            (3, 'line'),
+                            (4, 'line'),
+                            (4, 'line'),
+                            (4, 'line'),
+                            (4, 'line'),
+                            (4, 'exception'),
+                            (5, 'line'),
+                            (6, 'line'),
+                            (6, 'return')]
+
+class Tracer:
+    def __init__(self):
+        self.events = []
+    def trace(self, frame, event, arg):
+        self.events.append((frame.f_lineno, event))
+        return self.trace
+
+class TraceTestCase(unittest.TestCase):
+    def compare_events(self, line_offset, events, expected_events):
+        events = [(l - line_offset, e) for (l, e) in events]
+        if events != expected_events:
+            self.fail(
+                "events did not match expectation:\n" +
+                "\n".join(difflib.ndiff(map(str, expected_events),
+                                        map(str, events))))
+
+
+    def run_test(self, func):
+        tracer = Tracer()
+        sys.settrace(tracer.trace)
+        func()
+        sys.settrace(None)
+        self.compare_events(func.func_code.co_firstlineno,
+                            tracer.events, func.events)
+
+    def run_test2(self, func):
+        tracer = Tracer()
+        func(tracer.trace)
+        sys.settrace(None)
+        self.compare_events(func.func_code.co_firstlineno,
+                            tracer.events, func.events)
+
+    def test_01_basic(self):
+        self.run_test(basic)
+    def test_02_arigo(self):
+        self.run_test(arigo_example)
+    def test_03_one_instr(self):
+        self.run_test(one_instr_line)
+    def test_04_no_pop_blocks(self):
+        self.run_test(no_pop_blocks)
+    def test_05_no_pop_tops(self):
+        self.run_test(no_pop_tops)
+    def test_06_call(self):
+        self.run_test(call)
+    def test_07_raise(self):
+        self.run_test(test_raise)
+
+    def test_08_settrace_and_return(self):
+        self.run_test2(settrace_and_return)
+    def test_09_settrace_and_raise(self):
+        self.run_test2(settrace_and_raise)
+    def test_10_ireturn(self):
+        self.run_test(ireturn_example)
+    def test_11_tightloop(self):
+        self.run_test(tightloop_example)
+    def test_12_tighterloop(self):
+        self.run_test(tighterloop_example)
+
+class RaisingTraceFuncTestCase(unittest.TestCase):
+    def trace(self, frame, event, arg):
+        """A trace function that raises an exception in response to a
+        specific trace event."""
+        if event == self.raiseOnEvent:
+            raise ValueError # just something that isn't RuntimeError
+        else:
+            return self.trace
+
+    def f(self):
+        """The function to trace; raises an exception if that's the case
+        we're testing, so that the 'exception' trace event fires."""
+        if self.raiseOnEvent == 'exception':
+            x = 0
+            y = 1/x
+        else:
+            return 1
+
+    def run_test_for_event(self, event):
+        """Tests that an exception raised in response to the given event is
+        handled OK."""
+        self.raiseOnEvent = event
+        try:
+            for i in xrange(sys.getrecursionlimit() + 1):
+                sys.settrace(self.trace)
+                try:
+                    self.f()
+                except ValueError:
+                    pass
+                else:
+                    self.fail("exception not thrown!")
+        except RuntimeError:
+            self.fail("recursion counter not reset")
+
+    # Test the handling of exceptions raised by each kind of trace event.
+    def test_call(self):
+        self.run_test_for_event('call')
+    def test_line(self):
+        self.run_test_for_event('line')
+    def test_return(self):
+        self.run_test_for_event('return')
+    def test_exception(self):
+        self.run_test_for_event('exception')
+
+    def test_trash_stack(self):
+        def f():
+            for i in range(5):
+                print i  # line tracing will raise an exception at this line
+
+        def g(frame, why, extra):
+            if (why == 'line' and
+                frame.f_lineno == f.func_code.co_firstlineno + 2):
+                raise RuntimeError, "i am crashing"
+            return g
+
+        sys.settrace(g)
+        try:
+            f()
+        except RuntimeError:
+            # the test is really that this doesn't segfault:
+            import gc
+            gc.collect()
+        else:
+            self.fail("exception not propagated")
+
+
+# 'Jump' tests: assigning to frame.f_lineno within a trace function
+# moves the execution position - it's how debuggers implement a Jump
+# command (aka. "Set next statement").
+
+class JumpTracer:
+    """Defines a trace function that jumps from one place to another,
+    with the source and destination lines of the jump being defined by
+    the 'jump' property of the function under test."""
+
+    def __init__(self, function):
+        self.function = function
+        self.jumpFrom = function.jump[0]
+        self.jumpTo = function.jump[1]
+        self.done = False
+
+    def trace(self, frame, event, arg):
+        if not self.done and frame.f_code == self.function.func_code:
+            firstLine = frame.f_code.co_firstlineno
+            if frame.f_lineno == firstLine + self.jumpFrom:
+                # Cope with non-integer self.jumpTo (because of
+                # no_jump_to_non_integers below).
+                try:
+                    frame.f_lineno = firstLine + self.jumpTo
+                except TypeError:
+                    frame.f_lineno = self.jumpTo
+                self.done = True
+        return self.trace
+
+# The first set of 'jump' tests are for things that are allowed:
+
+def jump_simple_forwards(output):
+    output.append(1)
+    output.append(2)
+    output.append(3)
+
+jump_simple_forwards.jump = (1, 3)
+jump_simple_forwards.output = [3]
+
+def jump_simple_backwards(output):
+    output.append(1)
+    output.append(2)
+
+jump_simple_backwards.jump = (2, 1)
+jump_simple_backwards.output = [1, 1, 2]
+
+def jump_out_of_block_forwards(output):
+    for i in 1, 2:
+        output.append(2)
+        for j in [3]:  # Also tests jumping over a block
+            output.append(4)
+    output.append(5)
+
+jump_out_of_block_forwards.jump = (3, 5)
+jump_out_of_block_forwards.output = [2, 5]
+
+def jump_out_of_block_backwards(output):
+    output.append(1)
+    for i in [1]:
+        output.append(3)
+        for j in [2]:  # Also tests jumping over a block
+            output.append(5)
+        output.append(6)
+    output.append(7)
+
+jump_out_of_block_backwards.jump = (6, 1)
+jump_out_of_block_backwards.output = [1, 3, 5, 1, 3, 5, 6, 7]
+
+def jump_to_codeless_line(output):
+    output.append(1)
+    # Jumping to this line should skip to the next one.
+    output.append(3)
+
+jump_to_codeless_line.jump = (1, 2)
+jump_to_codeless_line.output = [3]
+
+def jump_to_same_line(output):
+    output.append(1)
+    output.append(2)
+    output.append(3)
+
+jump_to_same_line.jump = (2, 2)
+jump_to_same_line.output = [1, 2, 3]
+
+# Tests jumping within a finally block, and over one.
+def jump_in_nested_finally(output):
+    try:
+        output.append(2)
+    finally:
+        output.append(4)
+        try:
+            output.append(6)
+        finally:
+            output.append(8)
+        output.append(9)
+
+jump_in_nested_finally.jump = (4, 9)
+jump_in_nested_finally.output = [2, 9]
+
+# The second set of 'jump' tests are for things that are not allowed:
+
+def no_jump_too_far_forwards(output):
+    try:
+        output.append(2)
+        output.append(3)
+    except ValueError, e:
+        output.append('after' in str(e))
+
+no_jump_too_far_forwards.jump = (3, 6)
+no_jump_too_far_forwards.output = [2, True]
+
+def no_jump_too_far_backwards(output):
+    try:
+        output.append(2)
+        output.append(3)
+    except ValueError, e:
+        output.append('before' in str(e))
+
+no_jump_too_far_backwards.jump = (3, -1)
+no_jump_too_far_backwards.output = [2, True]
+
+# Test each kind of 'except' line.
+def no_jump_to_except_1(output):
+    try:
+        output.append(2)
+    except:
+        e = sys.exc_info()[1]
+        output.append('except' in str(e))
+
+no_jump_to_except_1.jump = (2, 3)
+no_jump_to_except_1.output = [True]
+
+def no_jump_to_except_2(output):
+    try:
+        output.append(2)
+    except ValueError:
+        e = sys.exc_info()[1]
+        output.append('except' in str(e))
+
+no_jump_to_except_2.jump = (2, 3)
+no_jump_to_except_2.output = [True]
+
+def no_jump_to_except_3(output):
+    try:
+        output.append(2)
+    except ValueError, e:
+        output.append('except' in str(e))
+
+no_jump_to_except_3.jump = (2, 3)
+no_jump_to_except_3.output = [True]
+
+def no_jump_to_except_4(output):
+    try:
+        output.append(2)
+    except (ValueError, RuntimeError), e:
+        output.append('except' in str(e))
+
+no_jump_to_except_4.jump = (2, 3)
+no_jump_to_except_4.output = [True]
+
+def no_jump_forwards_into_block(output):
+    try:
+        output.append(2)
+        for i in 1, 2:
+            output.append(4)
+    except ValueError, e:
+        output.append('into' in str(e))
+
+no_jump_forwards_into_block.jump = (2, 4)
+no_jump_forwards_into_block.output = [True]
+
+def no_jump_backwards_into_block(output):
+    try:
+        for i in 1, 2:
+            output.append(3)
+        output.append(4)
+    except ValueError, e:
+        output.append('into' in str(e))
+
+no_jump_backwards_into_block.jump = (4, 3)
+no_jump_backwards_into_block.output = [3, 3, True]
+
+def no_jump_into_finally_block(output):
+    try:
+        try:
+            output.append(3)
+            x = 1
+        finally:
+            output.append(6)
+    except ValueError, e:
+        output.append('finally' in str(e))
+
+no_jump_into_finally_block.jump = (4, 6)
+no_jump_into_finally_block.output = [3, 6, True]  # The 'finally' still runs
+
+def no_jump_out_of_finally_block(output):
+    try:
+        try:
+            output.append(3)
+        finally:
+            output.append(5)
+            output.append(6)
+    except ValueError, e:
+        output.append('finally' in str(e))
+
+no_jump_out_of_finally_block.jump = (5, 1)
+no_jump_out_of_finally_block.output = [3, True]
+
+# This verifies the line-numbers-must-be-integers rule.
+def no_jump_to_non_integers(output):
+    try:
+        output.append(2)
+    except ValueError, e:
+        output.append('integer' in str(e))
+
+no_jump_to_non_integers.jump = (2, "Spam")
+no_jump_to_non_integers.output = [True]
+
+# This verifies that you can't set f_lineno via _getframe or similar
+# trickery.
+def no_jump_without_trace_function():
+    try:
+        previous_frame = sys._getframe().f_back
+        previous_frame.f_lineno = previous_frame.f_lineno
+    except ValueError, e:
+        # This is the exception we wanted; make sure the error message
+        # talks about trace functions.
+        if 'trace' not in str(e):
+            raise
+    else:
+        # Something's wrong - the expected exception wasn't raised.
+        raise RuntimeError, "Trace-function-less jump failed to fail"
+
+
+class JumpTestCase(unittest.TestCase):
+    def compare_jump_output(self, expected, received):
+        if received != expected:
+            self.fail( "Outputs don't match:\n" +
+                       "Expected: " + repr(expected) + "\n" +
+                       "Received: " + repr(received))
+
+    def run_test(self, func):
+        tracer = JumpTracer(func)
+        sys.settrace(tracer.trace)
+        output = []
+        func(output)
+        sys.settrace(None)
+        self.compare_jump_output(func.output, output)
+
+    def test_01_jump_simple_forwards(self):
+        self.run_test(jump_simple_forwards)
+    def test_02_jump_simple_backwards(self):
+        self.run_test(jump_simple_backwards)
+    def test_03_jump_out_of_block_forwards(self):
+        self.run_test(jump_out_of_block_forwards)
+    def test_04_jump_out_of_block_backwards(self):
+        self.run_test(jump_out_of_block_backwards)
+    def test_05_jump_to_codeless_line(self):
+        self.run_test(jump_to_codeless_line)
+    def test_06_jump_to_same_line(self):
+        self.run_test(jump_to_same_line)
+    def test_07_jump_in_nested_finally(self):
+        self.run_test(jump_in_nested_finally)
+    def test_08_no_jump_too_far_forwards(self):
+        self.run_test(no_jump_too_far_forwards)
+    def test_09_no_jump_too_far_backwards(self):
+        self.run_test(no_jump_too_far_backwards)
+    def test_10_no_jump_to_except_1(self):
+        self.run_test(no_jump_to_except_1)
+    def test_11_no_jump_to_except_2(self):
+        self.run_test(no_jump_to_except_2)
+    def test_12_no_jump_to_except_3(self):
+        self.run_test(no_jump_to_except_3)
+    def test_13_no_jump_to_except_4(self):
+        self.run_test(no_jump_to_except_4)
+    def test_14_no_jump_forwards_into_block(self):
+        self.run_test(no_jump_forwards_into_block)
+    def test_15_no_jump_backwards_into_block(self):
+        self.run_test(no_jump_backwards_into_block)
+    def test_16_no_jump_into_finally_block(self):
+        self.run_test(no_jump_into_finally_block)
+    def test_17_no_jump_out_of_finally_block(self):
+        self.run_test(no_jump_out_of_finally_block)
+    def test_18_no_jump_to_non_integers(self):
+        self.run_test(no_jump_to_non_integers)
+    def test_19_no_jump_without_trace_function(self):
+        no_jump_without_trace_function()
+
+def test_main():
+    test_support.run_unittest(
+        TraceTestCase,
+        RaisingTraceFuncTestCase,
+        JumpTestCase
+    )
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_traceback.py
===================================================================
--- vendor/Python/current/Lib/test/test_traceback.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_traceback.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,162 @@
+"""Test cases for traceback module"""
+
+import unittest
+from test.test_support import run_unittest, is_jython
+
+import traceback
+
+class TracebackCases(unittest.TestCase):
+    # For now, a very minimal set of tests.  I want to be sure that
+    # formatting of SyntaxErrors works based on changes for 2.1.
+
+    def get_exception_format(self, func, exc):
+        try:
+            func()
+        except exc, value:
+            return traceback.format_exception_only(exc, value)
+        else:
+            raise ValueError, "call did not raise exception"
+
+    def syntax_error_with_caret(self):
+        compile("def fact(x):\n\treturn x!\n", "?", "exec")
+
+    def syntax_error_without_caret(self):
+        # XXX why doesn't compile raise the same traceback?
+        import test.badsyntax_nocaret
+
+    def syntax_error_bad_indentation(self):
+        compile("def spam():\n  print 1\n print 2", "?", "exec")
+
+    def test_caret(self):
+        err = self.get_exception_format(self.syntax_error_with_caret,
+                                        SyntaxError)
+        self.assert_(len(err) == 4)
+        self.assert_(err[1].strip() == "return x!")
+        self.assert_("^" in err[2]) # third line has caret
+        self.assert_(err[1].find("!") == err[2].find("^")) # in the right place
+
+    def test_nocaret(self):
+        if is_jython:
+            # jython adds a caret in this case (why shouldn't it?)
+            return
+        err = self.get_exception_format(self.syntax_error_without_caret,
+                                        SyntaxError)
+        self.assert_(len(err) == 3)
+        self.assert_(err[1].strip() == "[x for x in x] = x")
+
+    def test_bad_indentation(self):
+        err = self.get_exception_format(self.syntax_error_bad_indentation,
+                                        IndentationError)
+        self.assert_(len(err) == 4)
+        self.assert_(err[1].strip() == "print 2")
+        self.assert_("^" in err[2])
+        self.assert_(err[1].find("2") == err[2].find("^"))
+
+    def test_bug737473(self):
+        import sys, os, tempfile, time
+
+        savedpath = sys.path[:]
+        testdir = tempfile.mkdtemp()
+        try:
+            sys.path.insert(0, testdir)
+            testfile = os.path.join(testdir, 'test_bug737473.py')
+            print >> open(testfile, 'w'), """
+def test():
+    raise ValueError"""
+
+            if 'test_bug737473' in sys.modules:
+                del sys.modules['test_bug737473']
+            import test_bug737473
+
+            try:
+                test_bug737473.test()
+            except ValueError:
+                # this loads source code to linecache
+                traceback.extract_tb(sys.exc_traceback)
+
+            # If this test runs too quickly, test_bug737473.py's mtime
+            # attribute will remain unchanged even if the file is rewritten.
+            # Consequently, the file would not reload.  So, added a sleep()
+            # delay to assure that a new, distinct timestamp is written.
+            # Since WinME with FAT32 has multisecond resolution, more than
+            # three seconds are needed for this test to pass reliably :-(
+            time.sleep(4)
+
+            print >> open(testfile, 'w'), """
+def test():
+    raise NotImplementedError"""
+            reload(test_bug737473)
+            try:
+                test_bug737473.test()
+            except NotImplementedError:
+                src = traceback.extract_tb(sys.exc_traceback)[-1][-1]
+                self.failUnlessEqual(src, 'raise NotImplementedError')
+        finally:
+            sys.path[:] = savedpath
+            for f in os.listdir(testdir):
+                os.unlink(os.path.join(testdir, f))
+            os.rmdir(testdir)
+
+    def test_members(self):
+        # Covers Python/structmember.c::listmembers()
+        try:
+            1/0
+        except:
+            import sys
+            sys.exc_traceback.__members__
+
+    def test_base_exception(self):
+        # Test that exceptions derived from BaseException are formatted right
+        e = KeyboardInterrupt()
+        lst = traceback.format_exception_only(e.__class__, e)
+        self.assertEqual(lst, ['KeyboardInterrupt\n'])
+
+    # String exceptions are deprecated, but legal.  The quirky form with
+    # separate "type" and "value" tends to break things, because
+    #     not isinstance(value, type)
+    # and a string cannot be the first argument to issubclass.
+    #
+    # Note that sys.last_type and sys.last_value do not get set if an
+    # exception is caught, so we sort of cheat and just emulate them.
+    #
+    # test_string_exception1 is equivalent to
+    #
+    # >>> raise "String Exception"
+    #
+    # test_string_exception2 is equivalent to
+    #
+    # >>> raise "String Exception", "String Value"
+    #
+    def test_string_exception1(self):
+        str_type = "String Exception"
+        err = traceback.format_exception_only(str_type, None)
+        self.assertEqual(len(err), 1)
+        self.assertEqual(err[0], str_type + '\n')
+
+    def test_string_exception2(self):
+        str_type = "String Exception"
+        str_value = "String Value"
+        err = traceback.format_exception_only(str_type, str_value)
+        self.assertEqual(len(err), 1)
+        self.assertEqual(err[0], str_type + ': ' + str_value + '\n')
+
+    def test_format_exception_only_bad__str__(self):
+        class X(Exception):
+            def __str__(self):
+                1/0
+        err = traceback.format_exception_only(X, X())
+        self.assertEqual(len(err), 1)
+        str_value = '<unprintable %s object>' % X.__name__
+        self.assertEqual(err[0], X.__name__ + ': ' + str_value + '\n')
+
+    def test_without_exception(self):
+        err = traceback.format_exception_only(None, None)
+        self.assertEqual(err, ['None\n'])
+
+
+def test_main():
+    run_unittest(TracebackCases)
+
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_transformer.py
===================================================================
--- vendor/Python/current/Lib/test/test_transformer.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_transformer.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,35 @@
+import unittest
+from test import test_support
+from compiler import transformer, ast
+from compiler import compile
+
+class Tests(unittest.TestCase):
+
+    def testMultipleLHS(self):
+        """ Test multiple targets on the left hand side. """
+
+        snippets = ['a, b = 1, 2',
+                    '(a, b) = 1, 2',
+                    '((a, b), c) = (1, 2), 3']
+
+        for s in snippets:
+            a = transformer.parse(s)
+            assert isinstance(a, ast.Module)
+            child1 = a.getChildNodes()[0]
+            assert isinstance(child1, ast.Stmt)
+            child2 = child1.getChildNodes()[0]
+            assert isinstance(child2, ast.Assign)
+
+            # This actually tests the compiler, but it's a way to assure the ast
+            # is correct
+            c = compile(s, '<string>', 'single')
+            vals = {}
+            exec c in vals
+            assert vals['a'] == 1
+            assert vals['b'] == 2
+
+def test_main():
+    test_support.run_unittest(Tests)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_tuple.py
===================================================================
--- vendor/Python/current/Lib/test/test_tuple.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_tuple.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,83 @@
+import unittest
+from test import test_support, seq_tests
+
+class TupleTest(seq_tests.CommonTest):
+    type2test = tuple
+
+    def test_constructors(self):
+        super(TupleTest, self).test_len()
+        # calling built-in types without argument must return empty
+        self.assertEqual(tuple(), ())
+
+    def test_truth(self):
+        super(TupleTest, self).test_truth()
+        self.assert_(not ())
+        self.assert_((42, ))
+
+    def test_len(self):
+        super(TupleTest, self).test_len()
+        self.assertEqual(len(()), 0)
+        self.assertEqual(len((0,)), 1)
+        self.assertEqual(len((0, 1, 2)), 3)
+
+    def test_iadd(self):
+        super(TupleTest, self).test_iadd()
+        u = (0, 1)
+        u2 = u
+        u += (2, 3)
+        self.assert_(u is not u2)
+
+    def test_imul(self):
+        super(TupleTest, self).test_imul()
+        u = (0, 1)
+        u2 = u
+        u *= 3
+        self.assert_(u is not u2)
+
+    def test_tupleresizebug(self):
+        # Check that a specific bug in _PyTuple_Resize() is squashed.
+        def f():
+            for i in range(1000):
+                yield i
+        self.assertEqual(list(tuple(f())), range(1000))
+
+    def test_hash(self):
+        # See SF bug 942952:  Weakness in tuple hash
+        # The hash should:
+        #      be non-commutative
+        #      should spread-out closely spaced values
+        #      should not exhibit cancellation in tuples like (x,(x,y))
+        #      should be distinct from element hashes:  hash(x)!=hash((x,))
+        # This test exercises those cases.
+        # For a pure random hash and N=50, the expected number of occupied
+        #      buckets when tossing 252,600 balls into 2**32 buckets
+        #      is 252,592.6, or about 7.4 expected collisions.  The
+        #      standard deviation is 2.73.  On a box with 64-bit hash
+        #      codes, no collisions are expected.  Here we accept no
+        #      more than 15 collisions.  Any worse and the hash function
+        #      is sorely suspect.
+
+        N=50
+        base = range(N)
+        xp = [(i, j) for i in base for j in base]
+        inps = base + [(i, j) for i in base for j in xp] + \
+                     [(i, j) for i in xp for j in base] + xp + zip(base)
+        collisions = len(inps) - len(set(map(hash, inps)))
+        self.assert_(collisions <= 15)
+
+    def test_repr(self):
+        l0 = tuple()
+        l2 = (0, 1, 2)
+        a0 = self.type2test(l0)
+        a2 = self.type2test(l2)
+
+        self.assertEqual(str(a0), repr(l0))
+        self.assertEqual(str(a2), repr(l2))
+        self.assertEqual(repr(a0), "()")
+        self.assertEqual(repr(a2), "(0, 1, 2)")
+
+def test_main():
+    test_support.run_unittest(TupleTest)
+
+if __name__=="__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_types.py
===================================================================
--- vendor/Python/current/Lib/test/test_types.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_types.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,286 @@
+# Python test set -- part 6, built-in types
+
+from test.test_support import *
+
+print '6. Built-in types'
+
+print '6.1 Truth value testing'
+if None: raise TestFailed, 'None is true instead of false'
+if 0: raise TestFailed, '0 is true instead of false'
+if 0L: raise TestFailed, '0L is true instead of false'
+if 0.0: raise TestFailed, '0.0 is true instead of false'
+if '': raise TestFailed, '\'\' is true instead of false'
+if not 1: raise TestFailed, '1 is false instead of true'
+if not 1L: raise TestFailed, '1L is false instead of true'
+if not 1.0: raise TestFailed, '1.0 is false instead of true'
+if not 'x': raise TestFailed, '\'x\' is false instead of true'
+if not {'x': 1}: raise TestFailed, '{\'x\': 1} is false instead of true'
+def f(): pass
+class C: pass
+import sys
+x = C()
+if not f: raise TestFailed, 'f is false instead of true'
+if not C: raise TestFailed, 'C is false instead of true'
+if not sys: raise TestFailed, 'sys is false instead of true'
+if not x: raise TestFailed, 'x is false instead of true'
+
+print '6.2 Boolean operations'
+if 0 or 0: raise TestFailed, '0 or 0 is true instead of false'
+if 1 and 1: pass
+else: raise TestFailed, '1 and 1 is false instead of true'
+if not 1: raise TestFailed, 'not 1 is true instead of false'
+
+print '6.3 Comparisons'
+if 0 < 1 <= 1 == 1 >= 1 > 0 != 1: pass
+else: raise TestFailed, 'int comparisons failed'
+if 0L < 1L <= 1L == 1L >= 1L > 0L != 1L: pass
+else: raise TestFailed, 'long int comparisons failed'
+if 0.0 < 1.0 <= 1.0 == 1.0 >= 1.0 > 0.0 != 1.0: pass
+else: raise TestFailed, 'float comparisons failed'
+if '' < 'a' <= 'a' == 'a' < 'abc' < 'abd' < 'b': pass
+else: raise TestFailed, 'string comparisons failed'
+if None is None: pass
+else: raise TestFailed, 'identity test failed'
+
+try: float('')
+except ValueError: pass
+else: raise TestFailed, "float('') didn't raise ValueError"
+
+try: float('5\0')
+except ValueError: pass
+else: raise TestFailed, "float('5\0') didn't raise ValueError"
+
+try: 5.0 / 0.0
+except ZeroDivisionError: pass
+else: raise TestFailed, "5.0 / 0.0 didn't raise ZeroDivisionError"
+
+try: 5.0 // 0.0
+except ZeroDivisionError: pass
+else: raise TestFailed, "5.0 // 0.0 didn't raise ZeroDivisionError"
+
+try: 5.0 % 0.0
+except ZeroDivisionError: pass
+else: raise TestFailed, "5.0 % 0.0 didn't raise ZeroDivisionError"
+
+try: 5 / 0L
+except ZeroDivisionError: pass
+else: raise TestFailed, "5 / 0L didn't raise ZeroDivisionError"
+
+try: 5 // 0L
+except ZeroDivisionError: pass
+else: raise TestFailed, "5 // 0L didn't raise ZeroDivisionError"
+
+try: 5 % 0L
+except ZeroDivisionError: pass
+else: raise TestFailed, "5 % 0L didn't raise ZeroDivisionError"
+
+print '6.4 Numeric types (mostly conversions)'
+if 0 != 0L or 0 != 0.0 or 0L != 0.0: raise TestFailed, 'mixed comparisons'
+if 1 != 1L or 1 != 1.0 or 1L != 1.0: raise TestFailed, 'mixed comparisons'
+if -1 != -1L or -1 != -1.0 or -1L != -1.0:
+    raise TestFailed, 'int/long/float value not equal'
+# calling built-in types without argument must return 0
+if int() != 0: raise TestFailed, 'int() does not return 0'
+if long() != 0L: raise TestFailed, 'long() does not return 0L'
+if float() != 0.0: raise TestFailed, 'float() does not return 0.0'
+if int(1.9) == 1 == int(1.1) and int(-1.1) == -1 == int(-1.9): pass
+else: raise TestFailed, 'int() does not round properly'
+if long(1.9) == 1L == long(1.1) and long(-1.1) == -1L == long(-1.9): pass
+else: raise TestFailed, 'long() does not round properly'
+if float(1) == 1.0 and float(-1) == -1.0 and float(0) == 0.0: pass
+else: raise TestFailed, 'float() does not work properly'
+print '6.4.1 32-bit integers'
+# Ensure the first 256 integers are shared
+a = 256
+b = 128*2
+if a is not b: raise TestFailed, '256 is not shared'
+if 12 + 24 != 36: raise TestFailed, 'int op'
+if 12 + (-24) != -12: raise TestFailed, 'int op'
+if (-12) + 24 != 12: raise TestFailed, 'int op'
+if (-12) + (-24) != -36: raise TestFailed, 'int op'
+if not 12 < 24: raise TestFailed, 'int op'
+if not -24 < -12: raise TestFailed, 'int op'
+# Test for a particular bug in integer multiply
+xsize, ysize, zsize = 238, 356, 4
+if not (xsize*ysize*zsize == zsize*xsize*ysize == 338912):
+    raise TestFailed, 'int mul commutativity'
+# And another.
+m = -sys.maxint - 1
+for divisor in 1, 2, 4, 8, 16, 32:
+    j = m // divisor
+    prod = divisor * j
+    if prod != m:
+        raise TestFailed, "%r * %r == %r != %r" % (divisor, j, prod, m)
+    if type(prod) is not int:
+        raise TestFailed, ("expected type(prod) to be int, not %r" %
+                           type(prod))
+# Check for expected * overflow to long.
+for divisor in 1, 2, 4, 8, 16, 32:
+    j = m // divisor - 1
+    prod = divisor * j
+    if type(prod) is not long:
+        raise TestFailed, ("expected type(%r) to be long, not %r" %
+                           (prod, type(prod)))
+# Check for expected * overflow to long.
+m = sys.maxint
+for divisor in 1, 2, 4, 8, 16, 32:
+    j = m // divisor + 1
+    prod = divisor * j
+    if type(prod) is not long:
+        raise TestFailed, ("expected type(%r) to be long, not %r" %
+                           (prod, type(prod)))
+
+print '6.4.2 Long integers'
+if 12L + 24L != 36L: raise TestFailed, 'long op'
+if 12L + (-24L) != -12L: raise TestFailed, 'long op'
+if (-12L) + 24L != 12L: raise TestFailed, 'long op'
+if (-12L) + (-24L) != -36L: raise TestFailed, 'long op'
+if not 12L < 24L: raise TestFailed, 'long op'
+if not -24L < -12L: raise TestFailed, 'long op'
+x = sys.maxint
+if int(long(x)) != x: raise TestFailed, 'long op'
+try: y = int(long(x)+1L)
+except OverflowError: raise TestFailed, 'long op'
+if not isinstance(y, long): raise TestFailed, 'long op'
+x = -x
+if int(long(x)) != x: raise TestFailed, 'long op'
+x = x-1
+if int(long(x)) != x: raise TestFailed, 'long op'
+try: y = int(long(x)-1L)
+except OverflowError: raise TestFailed, 'long op'
+if not isinstance(y, long): raise TestFailed, 'long op'
+
+try: 5 << -5
+except ValueError: pass
+else: raise TestFailed, 'int negative shift <<'
+
+try: 5L << -5L
+except ValueError: pass
+else: raise TestFailed, 'long negative shift <<'
+
+try: 5 >> -5
+except ValueError: pass
+else: raise TestFailed, 'int negative shift >>'
+
+try: 5L >> -5L
+except ValueError: pass
+else: raise TestFailed, 'long negative shift >>'
+
+print '6.4.3 Floating point numbers'
+if 12.0 + 24.0 != 36.0: raise TestFailed, 'float op'
+if 12.0 + (-24.0) != -12.0: raise TestFailed, 'float op'
+if (-12.0) + 24.0 != 12.0: raise TestFailed, 'float op'
+if (-12.0) + (-24.0) != -36.0: raise TestFailed, 'float op'
+if not 12.0 < 24.0: raise TestFailed, 'float op'
+if not -24.0 < -12.0: raise TestFailed, 'float op'
+
+print '6.5 Sequence types'
+
+print '6.5.1 Strings'
+if len('') != 0: raise TestFailed, 'len(\'\')'
+if len('a') != 1: raise TestFailed, 'len(\'a\')'
+if len('abcdef') != 6: raise TestFailed, 'len(\'abcdef\')'
+if 'xyz' + 'abcde' != 'xyzabcde': raise TestFailed, 'string concatenation'
+if 'xyz'*3 != 'xyzxyzxyz': raise TestFailed, 'string repetition *3'
+if 0*'abcde' != '': raise TestFailed, 'string repetition 0*'
+if min('abc') != 'a' or max('abc') != 'c': raise TestFailed, 'min/max string'
+if 'a' in 'abc' and 'b' in 'abc' and 'c' in 'abc' and 'd' not in 'abc': pass
+else: raise TestFailed, 'in/not in string'
+x = 'x'*103
+if '%s!'%x != x+'!': raise TestFailed, 'nasty string formatting bug'
+
+#extended slices for strings
+a = '0123456789'
+vereq(a[::], a)
+vereq(a[::2], '02468')
+vereq(a[1::2], '13579')
+vereq(a[::-1],'9876543210')
+vereq(a[::-2], '97531')
+vereq(a[3::-2], '31')
+vereq(a[-100:100:], a)
+vereq(a[100:-100:-1], a[::-1])
+vereq(a[-100L:100L:2L], '02468')
+
+if have_unicode:
+    a = unicode('0123456789', 'ascii')
+    vereq(a[::], a)
+    vereq(a[::2], unicode('02468', 'ascii'))
+    vereq(a[1::2], unicode('13579', 'ascii'))
+    vereq(a[::-1], unicode('9876543210', 'ascii'))
+    vereq(a[::-2], unicode('97531', 'ascii'))
+    vereq(a[3::-2], unicode('31', 'ascii'))
+    vereq(a[-100:100:], a)
+    vereq(a[100:-100:-1], a[::-1])
+    vereq(a[-100L:100L:2L], unicode('02468', 'ascii'))
+
+
+print '6.5.2 Tuples [see test_tuple.py]'
+
+print '6.5.3 Lists [see test_list.py]'
+
+print '6.6 Mappings == Dictionaries [see test_dict.py]'
+
+
+try: type(1, 2)
+except TypeError: pass
+else: raise TestFailed, 'type(), w/2 args expected TypeError'
+
+try: type(1, 2, 3, 4)
+except TypeError: pass
+else: raise TestFailed, 'type(), w/4 args expected TypeError'
+
+print 'Buffers'
+try: buffer('asdf', -1)
+except ValueError: pass
+else: raise TestFailed, "buffer('asdf', -1) should raise ValueError"
+cmp(buffer("abc"), buffer("def")) # used to raise a warning: tp_compare didn't return -1, 0, or 1
+
+try: buffer(None)
+except TypeError: pass
+else: raise TestFailed, "buffer(None) should raise TypeError"
+
+a = buffer('asdf')
+hash(a)
+b = a * 5
+if a == b:
+    raise TestFailed, 'buffers should not be equal'
+if str(b) != ('asdf' * 5):
+    raise TestFailed, 'repeated buffer has wrong content'
+if str(a * 0) != '':
+    raise TestFailed, 'repeated buffer zero times has wrong content'
+if str(a + buffer('def')) != 'asdfdef':
+    raise TestFailed, 'concatenation of buffers yields wrong content'
+if str(buffer(a)) != 'asdf':
+    raise TestFailed, 'composing buffers failed'
+if str(buffer(a, 2)) != 'df':
+    raise TestFailed, 'specifying buffer offset failed'
+if str(buffer(a, 0, 2)) != 'as':
+    raise TestFailed, 'specifying buffer size failed'
+if str(buffer(a, 1, 2)) != 'sd':
+    raise TestFailed, 'specifying buffer offset and size failed'
+try: buffer(buffer('asdf', 1), -1)
+except ValueError: pass
+else: raise TestFailed, "buffer(buffer('asdf', 1), -1) should raise ValueError"
+if str(buffer(buffer('asdf', 0, 2), 0)) != 'as':
+    raise TestFailed, 'composing length-specified buffer failed'
+if str(buffer(buffer('asdf', 0, 2), 0, 5000)) != 'as':
+    raise TestFailed, 'composing length-specified buffer failed'
+if str(buffer(buffer('asdf', 0, 2), 0, -1)) != 'as':
+    raise TestFailed, 'composing length-specified buffer failed'
+if str(buffer(buffer('asdf', 0, 2), 1, 2)) != 's':
+    raise TestFailed, 'composing length-specified buffer failed'
+
+try: a[1] = 'g'
+except TypeError: pass
+else: raise TestFailed, "buffer assignment should raise TypeError"
+
+try: a[0:1] = 'g'
+except TypeError: pass
+else: raise TestFailed, "buffer slice assignment should raise TypeError"
+
+# array.array() returns an object that does not implement a char buffer,
+# something which int() uses for conversion.
+import array
+try: int(buffer(array.array('c')))
+except TypeError :pass
+else: raise TestFailed, "char buffer (at C level) not working"

Added: vendor/Python/current/Lib/test/test_ucn.py
===================================================================
--- vendor/Python/current/Lib/test/test_ucn.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_ucn.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,144 @@
+""" Test script for the Unicode implementation.
+
+Written by Bill Tutt.
+Modified for Python 2.0 by Fredrik Lundh (fredrik at pythonware.com)
+
+(c) Copyright CNRI, All Rights Reserved. NO WARRANTY.
+
+"""#"
+
+import unittest
+
+from test import test_support
+
+class UnicodeNamesTest(unittest.TestCase):
+
+    def checkletter(self, name, code):
+        # Helper that put all \N escapes inside eval'd raw strings,
+        # to make sure this script runs even if the compiler
+        # chokes on \N escapes
+        res = eval(ur'u"\N{%s}"' % name)
+        self.assertEqual(res, code)
+        return res
+
+    def test_general(self):
+        # General and case insensitivity test:
+        chars = [
+            "LATIN CAPITAL LETTER T",
+            "LATIN SMALL LETTER H",
+            "LATIN SMALL LETTER E",
+            "SPACE",
+            "LATIN SMALL LETTER R",
+            "LATIN CAPITAL LETTER E",
+            "LATIN SMALL LETTER D",
+            "SPACE",
+            "LATIN SMALL LETTER f",
+            "LATIN CAPITAL LeTtEr o",
+            "LATIN SMaLl LETTER x",
+            "SPACE",
+            "LATIN SMALL LETTER A",
+            "LATIN SMALL LETTER T",
+            "LATIN SMALL LETTER E",
+            "SPACE",
+            "LATIN SMALL LETTER T",
+            "LATIN SMALL LETTER H",
+            "LATIN SMALL LETTER E",
+            "SpAcE",
+            "LATIN SMALL LETTER S",
+            "LATIN SMALL LETTER H",
+            "LATIN small LETTER e",
+            "LATIN small LETTER e",
+            "LATIN SMALL LETTER P",
+            "FULL STOP"
+        ]
+        string = u"The rEd fOx ate the sheep."
+
+        self.assertEqual(
+            u"".join([self.checkletter(*args) for args in zip(chars, string)]),
+            string
+        )
+
+    def test_ascii_letters(self):
+        import unicodedata
+
+        for char in "".join(map(chr, xrange(ord("a"), ord("z")))):
+            name = "LATIN SMALL LETTER %s" % char.upper()
+            code = unicodedata.lookup(name)
+            self.assertEqual(unicodedata.name(code), name)
+
+    def test_hangul_syllables(self):
+        self.checkletter("HANGUL SYLLABLE GA", u"\uac00")
+        self.checkletter("HANGUL SYLLABLE GGWEOSS", u"\uafe8")
+        self.checkletter("HANGUL SYLLABLE DOLS", u"\ub3d0")
+        self.checkletter("HANGUL SYLLABLE RYAN", u"\ub7b8")
+        self.checkletter("HANGUL SYLLABLE MWIK", u"\ubba0")
+        self.checkletter("HANGUL SYLLABLE BBWAEM", u"\ubf88")
+        self.checkletter("HANGUL SYLLABLE SSEOL", u"\uc370")
+        self.checkletter("HANGUL SYLLABLE YI", u"\uc758")
+        self.checkletter("HANGUL SYLLABLE JJYOSS", u"\ucb40")
+        self.checkletter("HANGUL SYLLABLE KYEOLS", u"\ucf28")
+        self.checkletter("HANGUL SYLLABLE PAN", u"\ud310")
+        self.checkletter("HANGUL SYLLABLE HWEOK", u"\ud6f8")
+        self.checkletter("HANGUL SYLLABLE HIH", u"\ud7a3")
+
+        import unicodedata
+        self.assertRaises(ValueError, unicodedata.name, u"\ud7a4")
+
+    def test_cjk_unified_ideographs(self):
+        self.checkletter("CJK UNIFIED IDEOGRAPH-3400", u"\u3400")
+        self.checkletter("CJK UNIFIED IDEOGRAPH-4DB5", u"\u4db5")
+        self.checkletter("CJK UNIFIED IDEOGRAPH-4E00", u"\u4e00")
+        self.checkletter("CJK UNIFIED IDEOGRAPH-9FA5", u"\u9fa5")
+        self.checkletter("CJK UNIFIED IDEOGRAPH-20000", u"\U00020000")
+        self.checkletter("CJK UNIFIED IDEOGRAPH-2A6D6", u"\U0002a6d6")
+
+    def test_bmp_characters(self):
+        import unicodedata
+        count = 0
+        for code in xrange(0x10000):
+            char = unichr(code)
+            name = unicodedata.name(char, None)
+            if name is not None:
+                self.assertEqual(unicodedata.lookup(name), char)
+                count += 1
+
+    def test_misc_symbols(self):
+        self.checkletter("PILCROW SIGN", u"\u00b6")
+        self.checkletter("REPLACEMENT CHARACTER", u"\uFFFD")
+        self.checkletter("HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK", u"\uFF9F")
+        self.checkletter("FULLWIDTH LATIN SMALL LETTER A", u"\uFF41")
+
+    def test_errors(self):
+        import unicodedata
+        self.assertRaises(TypeError, unicodedata.name)
+        self.assertRaises(TypeError, unicodedata.name, u'xx')
+        self.assertRaises(TypeError, unicodedata.lookup)
+        self.assertRaises(KeyError, unicodedata.lookup, u'unknown')
+
+    def test_strict_eror_handling(self):
+        # bogus character name
+        self.assertRaises(
+            UnicodeError,
+            unicode, "\\N{blah}", 'unicode-escape', 'strict'
+        )
+        # long bogus character name
+        self.assertRaises(
+            UnicodeError,
+            unicode, "\\N{%s}" % ("x" * 100000), 'unicode-escape', 'strict'
+        )
+        # missing closing brace
+        self.assertRaises(
+            UnicodeError,
+            unicode, "\\N{SPACE", 'unicode-escape', 'strict'
+        )
+        # missing opening brace
+        self.assertRaises(
+            UnicodeError,
+            unicode, "\\NSPACE", 'unicode-escape', 'strict'
+        )
+
+def test_main():
+    test_support.run_unittest(UnicodeNamesTest)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_unary.py
===================================================================
--- vendor/Python/current/Lib/test/test_unary.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_unary.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,59 @@
+"""Test compiler changes for unary ops (+, -, ~) introduced in Python 2.2"""
+
+import unittest
+from test.test_support import run_unittest, have_unicode
+
+class UnaryOpTestCase(unittest.TestCase):
+
+    def test_negative(self):
+        self.assert_(-2 == 0 - 2)
+        self.assert_(-0 == 0)
+        self.assert_(--2 == 2)
+        self.assert_(-2L == 0 - 2L)
+        self.assert_(-2.0 == 0 - 2.0)
+        self.assert_(-2j == 0 - 2j)
+
+    def test_positive(self):
+        self.assert_(+2 == 2)
+        self.assert_(+0 == 0)
+        self.assert_(++2 == 2)
+        self.assert_(+2L == 2L)
+        self.assert_(+2.0 == 2.0)
+        self.assert_(+2j == 2j)
+
+    def test_invert(self):
+        self.assert_(-2 == 0 - 2)
+        self.assert_(-0 == 0)
+        self.assert_(--2 == 2)
+        self.assert_(-2L == 0 - 2L)
+
+    def test_no_overflow(self):
+        nines = "9" * 32
+        self.assert_(eval("+" + nines) == eval("+" + nines + "L"))
+        self.assert_(eval("-" + nines) == eval("-" + nines + "L"))
+        self.assert_(eval("~" + nines) == eval("~" + nines + "L"))
+
+    def test_negation_of_exponentiation(self):
+        # Make sure '**' does the right thing; these form a
+        # regression test for SourceForge bug #456756.
+        self.assertEqual(-2 ** 3, -8)
+        self.assertEqual((-2) ** 3, -8)
+        self.assertEqual(-2 ** 4, -16)
+        self.assertEqual((-2) ** 4, 16)
+
+    def test_bad_types(self):
+        for op in '+', '-', '~':
+            self.assertRaises(TypeError, eval, op + "'a'")
+            if have_unicode:
+                self.assertRaises(TypeError, eval, op + "u'a'")
+
+        self.assertRaises(TypeError, eval, "~2j")
+        self.assertRaises(TypeError, eval, "~2.0")
+
+
+def test_main():
+    run_unittest(UnaryOpTestCase)
+
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_unicode.py
===================================================================
--- vendor/Python/current/Lib/test/test_unicode.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_unicode.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,828 @@
+# -*- coding: iso-8859-1 -*-
+""" Test script for the Unicode implementation.
+
+Written by Marc-Andre Lemburg (mal at lemburg.com).
+
+(c) Copyright CNRI, All Rights Reserved. NO WARRANTY.
+
+"""#"
+import unittest, sys, string, codecs, new
+from test import test_support, string_tests
+
+# Error handling (bad decoder return)
+def search_function(encoding):
+    def decode1(input, errors="strict"):
+        return 42 # not a tuple
+    def encode1(input, errors="strict"):
+        return 42 # not a tuple
+    def encode2(input, errors="strict"):
+        return (42, 42) # no unicode
+    def decode2(input, errors="strict"):
+        return (42, 42) # no unicode
+    if encoding=="test.unicode1":
+        return (encode1, decode1, None, None)
+    elif encoding=="test.unicode2":
+        return (encode2, decode2, None, None)
+    else:
+        return None
+codecs.register(search_function)
+
+class UnicodeTest(
+    string_tests.CommonTest,
+    string_tests.MixinStrUnicodeUserStringTest,
+    string_tests.MixinStrUnicodeTest,
+    ):
+    type2test = unicode
+
+    def checkequalnofix(self, result, object, methodname, *args):
+        method = getattr(object, methodname)
+        realresult = method(*args)
+        self.assertEqual(realresult, result)
+        self.assert_(type(realresult) is type(result))
+
+        # if the original is returned make sure that
+        # this doesn't happen with subclasses
+        if realresult is object:
+            class usub(unicode):
+                def __repr__(self):
+                    return 'usub(%r)' % unicode.__repr__(self)
+            object = usub(object)
+            method = getattr(object, methodname)
+            realresult = method(*args)
+            self.assertEqual(realresult, result)
+            self.assert_(object is not realresult)
+
+    def test_literals(self):
+        self.assertEqual(u'\xff', u'\u00ff')
+        self.assertEqual(u'\uffff', u'\U0000ffff')
+        self.assertRaises(UnicodeError, eval, 'u\'\\Ufffffffe\'')
+        self.assertRaises(UnicodeError, eval, 'u\'\\Uffffffff\'')
+        self.assertRaises(UnicodeError, eval, 'u\'\\U%08x\'' % 0x110000)
+
+    def test_repr(self):
+        if not sys.platform.startswith('java'):
+            # Test basic sanity of repr()
+            self.assertEqual(repr(u'abc'), "u'abc'")
+            self.assertEqual(repr(u'ab\\c'), "u'ab\\\\c'")
+            self.assertEqual(repr(u'ab\\'), "u'ab\\\\'")
+            self.assertEqual(repr(u'\\c'), "u'\\\\c'")
+            self.assertEqual(repr(u'\\'), "u'\\\\'")
+            self.assertEqual(repr(u'\n'), "u'\\n'")
+            self.assertEqual(repr(u'\r'), "u'\\r'")
+            self.assertEqual(repr(u'\t'), "u'\\t'")
+            self.assertEqual(repr(u'\b'), "u'\\x08'")
+            self.assertEqual(repr(u"'\""), """u'\\'"'""")
+            self.assertEqual(repr(u"'\""), """u'\\'"'""")
+            self.assertEqual(repr(u"'"), '''u"'"''')
+            self.assertEqual(repr(u'"'), """u'"'""")
+            latin1repr = (
+                "u'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r"
+                "\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a"
+                "\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123456789:;<=>?@ABCDEFGHI"
+                "JKLMNOPQRSTUVWXYZ[\\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\\x7f"
+                "\\x80\\x81\\x82\\x83\\x84\\x85\\x86\\x87\\x88\\x89\\x8a\\x8b\\x8c\\x8d"
+                "\\x8e\\x8f\\x90\\x91\\x92\\x93\\x94\\x95\\x96\\x97\\x98\\x99\\x9a\\x9b"
+                "\\x9c\\x9d\\x9e\\x9f\\xa0\\xa1\\xa2\\xa3\\xa4\\xa5\\xa6\\xa7\\xa8\\xa9"
+                "\\xaa\\xab\\xac\\xad\\xae\\xaf\\xb0\\xb1\\xb2\\xb3\\xb4\\xb5\\xb6\\xb7"
+                "\\xb8\\xb9\\xba\\xbb\\xbc\\xbd\\xbe\\xbf\\xc0\\xc1\\xc2\\xc3\\xc4\\xc5"
+                "\\xc6\\xc7\\xc8\\xc9\\xca\\xcb\\xcc\\xcd\\xce\\xcf\\xd0\\xd1\\xd2\\xd3"
+                "\\xd4\\xd5\\xd6\\xd7\\xd8\\xd9\\xda\\xdb\\xdc\\xdd\\xde\\xdf\\xe0\\xe1"
+                "\\xe2\\xe3\\xe4\\xe5\\xe6\\xe7\\xe8\\xe9\\xea\\xeb\\xec\\xed\\xee\\xef"
+                "\\xf0\\xf1\\xf2\\xf3\\xf4\\xf5\\xf6\\xf7\\xf8\\xf9\\xfa\\xfb\\xfc\\xfd"
+                "\\xfe\\xff'")
+            testrepr = repr(u''.join(map(unichr, xrange(256))))
+            self.assertEqual(testrepr, latin1repr)
+            # Test repr works on wide unicode escapes without overflow.
+            self.assertEqual(repr(u"\U00010000" * 39 + u"\uffff" * 4096),
+                             repr(u"\U00010000" * 39 + u"\uffff" * 4096))
+
+
+    def test_count(self):
+        string_tests.CommonTest.test_count(self)
+        # check mixed argument types
+        self.checkequalnofix(3,  'aaa', 'count', u'a')
+        self.checkequalnofix(0,  'aaa', 'count', u'b')
+        self.checkequalnofix(3, u'aaa', 'count',  'a')
+        self.checkequalnofix(0, u'aaa', 'count',  'b')
+        self.checkequalnofix(0, u'aaa', 'count',  'b')
+        self.checkequalnofix(1, u'aaa', 'count',  'a', -1)
+        self.checkequalnofix(3, u'aaa', 'count',  'a', -10)
+        self.checkequalnofix(2, u'aaa', 'count',  'a', 0, -1)
+        self.checkequalnofix(0, u'aaa', 'count',  'a', 0, -10)
+
+    def test_find(self):
+        self.checkequalnofix(0,  u'abcdefghiabc', 'find', u'abc')
+        self.checkequalnofix(9,  u'abcdefghiabc', 'find', u'abc', 1)
+        self.checkequalnofix(-1, u'abcdefghiabc', 'find', u'def', 4)
+
+        self.assertRaises(TypeError, u'hello'.find)
+        self.assertRaises(TypeError, u'hello'.find, 42)
+
+    def test_rfind(self):
+        string_tests.CommonTest.test_rfind(self)
+        # check mixed argument types
+        self.checkequalnofix(9,   'abcdefghiabc', 'rfind', u'abc')
+        self.checkequalnofix(12,  'abcdefghiabc', 'rfind', u'')
+        self.checkequalnofix(12, u'abcdefghiabc', 'rfind',  '')
+
+    def test_index(self):
+        string_tests.CommonTest.test_index(self)
+        # check mixed argument types
+        for (t1, t2) in ((str, unicode), (unicode, str)):
+            self.checkequalnofix(0, t1('abcdefghiabc'), 'index',  t2(''))
+            self.checkequalnofix(3, t1('abcdefghiabc'), 'index',  t2('def'))
+            self.checkequalnofix(0, t1('abcdefghiabc'), 'index',  t2('abc'))
+            self.checkequalnofix(9, t1('abcdefghiabc'), 'index',  t2('abc'), 1)
+            self.assertRaises(ValueError, t1('abcdefghiabc').index, t2('hib'))
+            self.assertRaises(ValueError, t1('abcdefghiab').index,  t2('abc'), 1)
+            self.assertRaises(ValueError, t1('abcdefghi').index,  t2('ghi'), 8)
+            self.assertRaises(ValueError, t1('abcdefghi').index,  t2('ghi'), -1)
+
+    def test_rindex(self):
+        string_tests.CommonTest.test_rindex(self)
+        # check mixed argument types
+        for (t1, t2) in ((str, unicode), (unicode, str)):
+            self.checkequalnofix(12, t1('abcdefghiabc'), 'rindex',  t2(''))
+            self.checkequalnofix(3,  t1('abcdefghiabc'), 'rindex',  t2('def'))
+            self.checkequalnofix(9,  t1('abcdefghiabc'), 'rindex',  t2('abc'))
+            self.checkequalnofix(0,  t1('abcdefghiabc'), 'rindex',  t2('abc'), 0, -1)
+
+            self.assertRaises(ValueError, t1('abcdefghiabc').rindex,  t2('hib'))
+            self.assertRaises(ValueError, t1('defghiabc').rindex,  t2('def'), 1)
+            self.assertRaises(ValueError, t1('defghiabc').rindex,  t2('abc'), 0, -1)
+            self.assertRaises(ValueError, t1('abcdefghi').rindex,  t2('ghi'), 0, 8)
+            self.assertRaises(ValueError, t1('abcdefghi').rindex,  t2('ghi'), 0, -1)
+
+    def test_translate(self):
+        self.checkequalnofix(u'bbbc', u'abababc', 'translate', {ord('a'):None})
+        self.checkequalnofix(u'iiic', u'abababc', 'translate', {ord('a'):None, ord('b'):ord('i')})
+        self.checkequalnofix(u'iiix', u'abababc', 'translate', {ord('a'):None, ord('b'):ord('i'), ord('c'):u'x'})
+        self.checkequalnofix(u'<i><i><i>c', u'abababc', 'translate', {ord('a'):None, ord('b'):u'<i>'})
+        self.checkequalnofix(u'c', u'abababc', 'translate', {ord('a'):None, ord('b'):u''})
+        self.checkequalnofix(u'xyyx', u'xzx', 'translate', {ord('z'):u'yy'})
+
+        self.assertRaises(TypeError, u'hello'.translate)
+        self.assertRaises(TypeError, u'abababc'.translate, {ord('a'):''})
+
+    def test_split(self):
+        string_tests.CommonTest.test_split(self)
+
+        # Mixed arguments
+        self.checkequalnofix([u'a', u'b', u'c', u'd'], u'a//b//c//d', 'split', '//')
+        self.checkequalnofix([u'a', u'b', u'c', u'd'], 'a//b//c//d', 'split', u'//')
+        self.checkequalnofix([u'endcase ', u''], u'endcase test', 'split', 'test')
+
+    def test_join(self):
+        string_tests.MixinStrUnicodeUserStringTest.test_join(self)
+
+        # mixed arguments
+        self.checkequalnofix(u'a b c d', u' ', 'join', ['a', 'b', u'c', u'd'])
+        self.checkequalnofix(u'abcd', u'', 'join', (u'a', u'b', u'c', u'd'))
+        self.checkequalnofix(u'w x y z', u' ', 'join', string_tests.Sequence('wxyz'))
+        self.checkequalnofix(u'a b c d', ' ', 'join', [u'a', u'b', u'c', u'd'])
+        self.checkequalnofix(u'a b c d', ' ', 'join', ['a', 'b', u'c', u'd'])
+        self.checkequalnofix(u'abcd', '', 'join', (u'a', u'b', u'c', u'd'))
+        self.checkequalnofix(u'w x y z', ' ', 'join', string_tests.Sequence(u'wxyz'))
+
+    def test_strip(self):
+        string_tests.CommonTest.test_strip(self)
+        self.assertRaises(UnicodeError, u"hello".strip, "\xff")
+
+    def test_replace(self):
+        string_tests.CommonTest.test_replace(self)
+
+        # method call forwarded from str implementation because of unicode argument
+        self.checkequalnofix(u'one at two!three!', 'one!two!three!', 'replace', u'!', u'@', 1)
+        self.assertRaises(TypeError, 'replace'.replace, u"r", 42)
+
+    def test_comparison(self):
+        # Comparisons:
+        self.assertEqual(u'abc', 'abc')
+        self.assertEqual('abc', u'abc')
+        self.assertEqual(u'abc', u'abc')
+        self.assert_(u'abcd' > 'abc')
+        self.assert_('abcd' > u'abc')
+        self.assert_(u'abcd' > u'abc')
+        self.assert_(u'abc' < 'abcd')
+        self.assert_('abc' < u'abcd')
+        self.assert_(u'abc' < u'abcd')
+
+        if 0:
+            # Move these tests to a Unicode collation module test...
+            # Testing UTF-16 code point order comparisons...
+
+            # No surrogates, no fixup required.
+            self.assert_(u'\u0061' < u'\u20ac')
+            # Non surrogate below surrogate value, no fixup required
+            self.assert_(u'\u0061' < u'\ud800\udc02')
+
+            # Non surrogate above surrogate value, fixup required
+            def test_lecmp(s, s2):
+                self.assert_(s < s2)
+
+            def test_fixup(s):
+                s2 = u'\ud800\udc01'
+                test_lecmp(s, s2)
+                s2 = u'\ud900\udc01'
+                test_lecmp(s, s2)
+                s2 = u'\uda00\udc01'
+                test_lecmp(s, s2)
+                s2 = u'\udb00\udc01'
+                test_lecmp(s, s2)
+                s2 = u'\ud800\udd01'
+                test_lecmp(s, s2)
+                s2 = u'\ud900\udd01'
+                test_lecmp(s, s2)
+                s2 = u'\uda00\udd01'
+                test_lecmp(s, s2)
+                s2 = u'\udb00\udd01'
+                test_lecmp(s, s2)
+                s2 = u'\ud800\ude01'
+                test_lecmp(s, s2)
+                s2 = u'\ud900\ude01'
+                test_lecmp(s, s2)
+                s2 = u'\uda00\ude01'
+                test_lecmp(s, s2)
+                s2 = u'\udb00\ude01'
+                test_lecmp(s, s2)
+                s2 = u'\ud800\udfff'
+                test_lecmp(s, s2)
+                s2 = u'\ud900\udfff'
+                test_lecmp(s, s2)
+                s2 = u'\uda00\udfff'
+                test_lecmp(s, s2)
+                s2 = u'\udb00\udfff'
+                test_lecmp(s, s2)
+
+                test_fixup(u'\ue000')
+                test_fixup(u'\uff61')
+
+        # Surrogates on both sides, no fixup required
+        self.assert_(u'\ud800\udc02' < u'\ud84d\udc56')
+
+    def test_islower(self):
+        string_tests.MixinStrUnicodeUserStringTest.test_islower(self)
+        self.checkequalnofix(False, u'\u1FFc', 'islower')
+
+    def test_isupper(self):
+        string_tests.MixinStrUnicodeUserStringTest.test_isupper(self)
+        if not sys.platform.startswith('java'):
+            self.checkequalnofix(False, u'\u1FFc', 'isupper')
+
+    def test_istitle(self):
+        string_tests.MixinStrUnicodeUserStringTest.test_title(self)
+        self.checkequalnofix(True, u'\u1FFc', 'istitle')
+        self.checkequalnofix(True, u'Greek \u1FFcitlecases ...', 'istitle')
+
+    def test_isspace(self):
+        string_tests.MixinStrUnicodeUserStringTest.test_isspace(self)
+        self.checkequalnofix(True, u'\u2000', 'isspace')
+        self.checkequalnofix(True, u'\u200a', 'isspace')
+        self.checkequalnofix(False, u'\u2014', 'isspace')
+
+    def test_isalpha(self):
+        string_tests.MixinStrUnicodeUserStringTest.test_isalpha(self)
+        self.checkequalnofix(True, u'\u1FFc', 'isalpha')
+
+    def test_isdecimal(self):
+        self.checkequalnofix(False, u'', 'isdecimal')
+        self.checkequalnofix(False, u'a', 'isdecimal')
+        self.checkequalnofix(True, u'0', 'isdecimal')
+        self.checkequalnofix(False, u'\u2460', 'isdecimal') # CIRCLED DIGIT ONE
+        self.checkequalnofix(False, u'\xbc', 'isdecimal') # VULGAR FRACTION ONE QUARTER
+        self.checkequalnofix(True, u'\u0660', 'isdecimal') # ARABIC-INDIC DIGIT ZERO
+        self.checkequalnofix(True, u'0123456789', 'isdecimal')
+        self.checkequalnofix(False, u'0123456789a', 'isdecimal')
+
+        self.checkraises(TypeError, 'abc', 'isdecimal', 42)
+
+    def test_isdigit(self):
+        string_tests.MixinStrUnicodeUserStringTest.test_isdigit(self)
+        self.checkequalnofix(True, u'\u2460', 'isdigit')
+        self.checkequalnofix(False, u'\xbc', 'isdigit')
+        self.checkequalnofix(True, u'\u0660', 'isdigit')
+
+    def test_isnumeric(self):
+        self.checkequalnofix(False, u'', 'isnumeric')
+        self.checkequalnofix(False, u'a', 'isnumeric')
+        self.checkequalnofix(True, u'0', 'isnumeric')
+        self.checkequalnofix(True, u'\u2460', 'isnumeric')
+        self.checkequalnofix(True, u'\xbc', 'isnumeric')
+        self.checkequalnofix(True, u'\u0660', 'isnumeric')
+        self.checkequalnofix(True, u'0123456789', 'isnumeric')
+        self.checkequalnofix(False, u'0123456789a', 'isnumeric')
+
+        self.assertRaises(TypeError, u"abc".isnumeric, 42)
+
+    def test_contains(self):
+        # Testing Unicode contains method
+        self.assert_('a' in u'abdb')
+        self.assert_('a' in u'bdab')
+        self.assert_('a' in u'bdaba')
+        self.assert_('a' in u'bdba')
+        self.assert_('a' in u'bdba')
+        self.assert_(u'a' in u'bdba')
+        self.assert_(u'a' not in u'bdb')
+        self.assert_(u'a' not in 'bdb')
+        self.assert_(u'a' in 'bdba')
+        self.assert_(u'a' in ('a',1,None))
+        self.assert_(u'a' in (1,None,'a'))
+        self.assert_(u'a' in (1,None,u'a'))
+        self.assert_('a' in ('a',1,None))
+        self.assert_('a' in (1,None,'a'))
+        self.assert_('a' in (1,None,u'a'))
+        self.assert_('a' not in ('x',1,u'y'))
+        self.assert_('a' not in ('x',1,None))
+        self.assert_(u'abcd' not in u'abcxxxx')
+        self.assert_(u'ab' in u'abcd')
+        self.assert_('ab' in u'abc')
+        self.assert_(u'ab' in 'abc')
+        self.assert_(u'ab' in (1,None,u'ab'))
+        self.assert_(u'' in u'abc')
+        self.assert_('' in u'abc')
+
+        # If the following fails either
+        # the contains operator does not propagate UnicodeErrors or
+        # someone has changed the default encoding
+        self.assertRaises(UnicodeError, 'g\xe2teau'.__contains__, u'\xe2')
+
+        self.assert_(u'' in '')
+        self.assert_('' in u'')
+        self.assert_(u'' in u'')
+        self.assert_(u'' in 'abc')
+        self.assert_('' in u'abc')
+        self.assert_(u'' in u'abc')
+        self.assert_(u'\0' not in 'abc')
+        self.assert_('\0' not in u'abc')
+        self.assert_(u'\0' not in u'abc')
+        self.assert_(u'\0' in '\0abc')
+        self.assert_('\0' in u'\0abc')
+        self.assert_(u'\0' in u'\0abc')
+        self.assert_(u'\0' in 'abc\0')
+        self.assert_('\0' in u'abc\0')
+        self.assert_(u'\0' in u'abc\0')
+        self.assert_(u'a' in '\0abc')
+        self.assert_('a' in u'\0abc')
+        self.assert_(u'a' in u'\0abc')
+        self.assert_(u'asdf' in 'asdf')
+        self.assert_('asdf' in u'asdf')
+        self.assert_(u'asdf' in u'asdf')
+        self.assert_(u'asdf' not in 'asd')
+        self.assert_('asdf' not in u'asd')
+        self.assert_(u'asdf' not in u'asd')
+        self.assert_(u'asdf' not in '')
+        self.assert_('asdf' not in u'')
+        self.assert_(u'asdf' not in u'')
+
+        self.assertRaises(TypeError, u"abc".__contains__)
+
+    def test_formatting(self):
+        string_tests.MixinStrUnicodeUserStringTest.test_formatting(self)
+        # Testing Unicode formatting strings...
+        self.assertEqual(u"%s, %s" % (u"abc", "abc"), u'abc, abc')
+        self.assertEqual(u"%s, %s, %i, %f, %5.2f" % (u"abc", "abc", 1, 2, 3), u'abc, abc, 1, 2.000000,  3.00')
+        self.assertEqual(u"%s, %s, %i, %f, %5.2f" % (u"abc", "abc", 1, -2, 3), u'abc, abc, 1, -2.000000,  3.00')
+        self.assertEqual(u"%s, %s, %i, %f, %5.2f" % (u"abc", "abc", -1, -2, 3.5), u'abc, abc, -1, -2.000000,  3.50')
+        self.assertEqual(u"%s, %s, %i, %f, %5.2f" % (u"abc", "abc", -1, -2, 3.57), u'abc, abc, -1, -2.000000,  3.57')
+        self.assertEqual(u"%s, %s, %i, %f, %5.2f" % (u"abc", "abc", -1, -2, 1003.57), u'abc, abc, -1, -2.000000, 1003.57')
+        if not sys.platform.startswith('java'):
+            self.assertEqual(u"%r, %r" % (u"abc", "abc"), u"u'abc', 'abc'")
+        self.assertEqual(u"%(x)s, %(y)s" % {'x':u"abc", 'y':"def"}, u'abc, def')
+        self.assertEqual(u"%(x)s, %(\xfc)s" % {'x':u"abc", u'\xfc':"def"}, u'abc, def')
+
+        self.assertEqual(u'%c' % 0x1234, u'\u1234')
+        self.assertRaises(OverflowError, u"%c".__mod__, (sys.maxunicode+1,))
+
+        # formatting jobs delegated from the string implementation:
+        self.assertEqual('...%(foo)s...' % {'foo':u"abc"}, u'...abc...')
+        self.assertEqual('...%(foo)s...' % {'foo':"abc"}, '...abc...')
+        self.assertEqual('...%(foo)s...' % {u'foo':"abc"}, '...abc...')
+        self.assertEqual('...%(foo)s...' % {u'foo':u"abc"}, u'...abc...')
+        self.assertEqual('...%(foo)s...' % {u'foo':u"abc",'def':123},  u'...abc...')
+        self.assertEqual('...%(foo)s...' % {u'foo':u"abc",u'def':123}, u'...abc...')
+        self.assertEqual('...%s...%s...%s...%s...' % (1,2,3,u"abc"), u'...1...2...3...abc...')
+        self.assertEqual('...%%...%%s...%s...%s...%s...%s...' % (1,2,3,u"abc"), u'...%...%s...1...2...3...abc...')
+        self.assertEqual('...%s...' % u"abc", u'...abc...')
+        self.assertEqual('%*s' % (5,u'abc',), u'  abc')
+        self.assertEqual('%*s' % (-5,u'abc',), u'abc  ')
+        self.assertEqual('%*.*s' % (5,2,u'abc',), u'   ab')
+        self.assertEqual('%*.*s' % (5,3,u'abc',), u'  abc')
+        self.assertEqual('%i %*.*s' % (10, 5,3,u'abc',), u'10   abc')
+        self.assertEqual('%i%s %*.*s' % (10, 3, 5, 3, u'abc',), u'103   abc')
+        self.assertEqual('%c' % u'a', u'a')
+        class Wrapper:
+            def __str__(self):
+                return u'\u1234'
+        self.assertEqual('%s' % Wrapper(), u'\u1234')
+
+    @test_support.run_with_locale('LC_ALL', 'de_DE', 'fr_FR')
+    def test_format_float(self):
+        # should not format with a comma, but always with C locale
+        self.assertEqual(u'1.0', u'%.1f' % 1.0)
+
+    def test_constructor(self):
+        # unicode(obj) tests (this maps to PyObject_Unicode() at C level)
+
+        self.assertEqual(
+            unicode(u'unicode remains unicode'),
+            u'unicode remains unicode'
+        )
+
+        class UnicodeSubclass(unicode):
+            pass
+
+        self.assertEqual(
+            unicode(UnicodeSubclass('unicode subclass becomes unicode')),
+            u'unicode subclass becomes unicode'
+        )
+
+        self.assertEqual(
+            unicode('strings are converted to unicode'),
+            u'strings are converted to unicode'
+        )
+
+        class UnicodeCompat:
+            def __init__(self, x):
+                self.x = x
+            def __unicode__(self):
+                return self.x
+
+        self.assertEqual(
+            unicode(UnicodeCompat('__unicode__ compatible objects are recognized')),
+            u'__unicode__ compatible objects are recognized')
+
+        class StringCompat:
+            def __init__(self, x):
+                self.x = x
+            def __str__(self):
+                return self.x
+
+        self.assertEqual(
+            unicode(StringCompat('__str__ compatible objects are recognized')),
+            u'__str__ compatible objects are recognized'
+        )
+
+        # unicode(obj) is compatible to str():
+
+        o = StringCompat('unicode(obj) is compatible to str()')
+        self.assertEqual(unicode(o), u'unicode(obj) is compatible to str()')
+        self.assertEqual(str(o), 'unicode(obj) is compatible to str()')
+
+        # %-formatting and .__unicode__()
+        self.assertEqual(u'%s' %
+                         UnicodeCompat(u"u'%s' % obj uses obj.__unicode__()"),
+                         u"u'%s' % obj uses obj.__unicode__()")
+        self.assertEqual(u'%s' %
+                         UnicodeCompat(u"u'%s' % obj falls back to obj.__str__()"),
+                         u"u'%s' % obj falls back to obj.__str__()")
+
+        for obj in (123, 123.45, 123L):
+            self.assertEqual(unicode(obj), unicode(str(obj)))
+
+        # unicode(obj, encoding, error) tests (this maps to
+        # PyUnicode_FromEncodedObject() at C level)
+
+        if not sys.platform.startswith('java'):
+            self.assertRaises(
+                TypeError,
+                unicode,
+                u'decoding unicode is not supported',
+                'utf-8',
+                'strict'
+            )
+
+        self.assertEqual(
+            unicode('strings are decoded to unicode', 'utf-8', 'strict'),
+            u'strings are decoded to unicode'
+        )
+
+        if not sys.platform.startswith('java'):
+            self.assertEqual(
+                unicode(
+                    buffer('character buffers are decoded to unicode'),
+                    'utf-8',
+                    'strict'
+                ),
+                u'character buffers are decoded to unicode'
+            )
+
+        self.assertRaises(TypeError, unicode, 42, 42, 42)
+
+    def test_codecs_utf7(self):
+        utfTests = [
+            (u'A\u2262\u0391.', 'A+ImIDkQ.'),             # RFC2152 example
+            (u'Hi Mom -\u263a-!', 'Hi Mom -+Jjo--!'),     # RFC2152 example
+            (u'\u65E5\u672C\u8A9E', '+ZeVnLIqe-'),        # RFC2152 example
+            (u'Item 3 is \u00a31.', 'Item 3 is +AKM-1.'), # RFC2152 example
+            (u'+', '+-'),
+            (u'+-', '+--'),
+            (u'+?', '+-?'),
+            (u'\?', '+AFw?'),
+            (u'+?', '+-?'),
+            (ur'\\?', '+AFwAXA?'),
+            (ur'\\\?', '+AFwAXABc?'),
+            (ur'++--', '+-+---')
+        ]
+
+        for (x, y) in utfTests:
+            self.assertEqual(x.encode('utf-7'), y)
+
+        # surrogates not supported
+        self.assertRaises(UnicodeError, unicode, '+3ADYAA-', 'utf-7')
+
+        self.assertEqual(unicode('+3ADYAA-', 'utf-7', 'replace'), u'\ufffd')
+
+    def test_codecs_utf8(self):
+        self.assertEqual(u''.encode('utf-8'), '')
+        self.assertEqual(u'\u20ac'.encode('utf-8'), '\xe2\x82\xac')
+        self.assertEqual(u'\ud800\udc02'.encode('utf-8'), '\xf0\x90\x80\x82')
+        self.assertEqual(u'\ud84d\udc56'.encode('utf-8'), '\xf0\xa3\x91\x96')
+        self.assertEqual(u'\ud800'.encode('utf-8'), '\xed\xa0\x80')
+        self.assertEqual(u'\udc00'.encode('utf-8'), '\xed\xb0\x80')
+        self.assertEqual(
+            (u'\ud800\udc02'*1000).encode('utf-8'),
+            '\xf0\x90\x80\x82'*1000
+        )
+        self.assertEqual(
+            u'\u6b63\u78ba\u306b\u8a00\u3046\u3068\u7ffb\u8a33\u306f'
+            u'\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002\u4e00'
+            u'\u90e8\u306f\u30c9\u30a4\u30c4\u8a9e\u3067\u3059\u304c'
+            u'\u3001\u3042\u3068\u306f\u3067\u305f\u3089\u3081\u3067'
+            u'\u3059\u3002\u5b9f\u969b\u306b\u306f\u300cWenn ist das'
+            u' Nunstuck git und'.encode('utf-8'),
+            '\xe6\xad\xa3\xe7\xa2\xba\xe3\x81\xab\xe8\xa8\x80\xe3\x81'
+            '\x86\xe3\x81\xa8\xe7\xbf\xbb\xe8\xa8\xb3\xe3\x81\xaf\xe3'
+            '\x81\x95\xe3\x82\x8c\xe3\x81\xa6\xe3\x81\x84\xe3\x81\xbe'
+            '\xe3\x81\x9b\xe3\x82\x93\xe3\x80\x82\xe4\xb8\x80\xe9\x83'
+            '\xa8\xe3\x81\xaf\xe3\x83\x89\xe3\x82\xa4\xe3\x83\x84\xe8'
+            '\xaa\x9e\xe3\x81\xa7\xe3\x81\x99\xe3\x81\x8c\xe3\x80\x81'
+            '\xe3\x81\x82\xe3\x81\xa8\xe3\x81\xaf\xe3\x81\xa7\xe3\x81'
+            '\x9f\xe3\x82\x89\xe3\x82\x81\xe3\x81\xa7\xe3\x81\x99\xe3'
+            '\x80\x82\xe5\xae\x9f\xe9\x9a\x9b\xe3\x81\xab\xe3\x81\xaf'
+            '\xe3\x80\x8cWenn ist das Nunstuck git und'
+        )
+
+        # UTF-8 specific decoding tests
+        self.assertEqual(unicode('\xf0\xa3\x91\x96', 'utf-8'), u'\U00023456' )
+        self.assertEqual(unicode('\xf0\x90\x80\x82', 'utf-8'), u'\U00010002' )
+        self.assertEqual(unicode('\xe2\x82\xac', 'utf-8'), u'\u20ac' )
+
+        # Other possible utf-8 test cases:
+        # * strict decoding testing for all of the
+        #   UTF8_ERROR cases in PyUnicode_DecodeUTF8
+
+    def test_codecs_idna(self):
+        # Test whether trailing dot is preserved
+        self.assertEqual(u"www.python.org.".encode("idna"), "www.python.org.")
+
+    def test_codecs_errors(self):
+        # Error handling (encoding)
+        self.assertRaises(UnicodeError, u'Andr\202 x'.encode, 'ascii')
+        self.assertRaises(UnicodeError, u'Andr\202 x'.encode, 'ascii','strict')
+        self.assertEqual(u'Andr\202 x'.encode('ascii','ignore'), "Andr x")
+        self.assertEqual(u'Andr\202 x'.encode('ascii','replace'), "Andr? x")
+
+        # Error handling (decoding)
+        self.assertRaises(UnicodeError, unicode, 'Andr\202 x', 'ascii')
+        self.assertRaises(UnicodeError, unicode, 'Andr\202 x', 'ascii','strict')
+        self.assertEqual(unicode('Andr\202 x','ascii','ignore'), u"Andr x")
+        self.assertEqual(unicode('Andr\202 x','ascii','replace'), u'Andr\uFFFD x')
+
+        # Error handling (unknown character names)
+        self.assertEqual("\\N{foo}xx".decode("unicode-escape", "ignore"), u"xx")
+
+        # Error handling (truncated escape sequence)
+        self.assertRaises(UnicodeError, "\\".decode, "unicode-escape")
+
+        self.assertRaises(TypeError, "hello".decode, "test.unicode1")
+        self.assertRaises(TypeError, unicode, "hello", "test.unicode2")
+        self.assertRaises(TypeError, u"hello".encode, "test.unicode1")
+        self.assertRaises(TypeError, u"hello".encode, "test.unicode2")
+        # executes PyUnicode_Encode()
+        import imp
+        self.assertRaises(
+            ImportError,
+            imp.find_module,
+            "non-existing module",
+            [u"non-existing dir"]
+        )
+
+        # Error handling (wrong arguments)
+        self.assertRaises(TypeError, u"hello".encode, 42, 42, 42)
+
+        # Error handling (PyUnicode_EncodeDecimal())
+        self.assertRaises(UnicodeError, int, u"\u0200")
+
+    def test_codecs(self):
+        # Encoding
+        self.assertEqual(u'hello'.encode('ascii'), 'hello')
+        self.assertEqual(u'hello'.encode('utf-7'), 'hello')
+        self.assertEqual(u'hello'.encode('utf-8'), 'hello')
+        self.assertEqual(u'hello'.encode('utf8'), 'hello')
+        self.assertEqual(u'hello'.encode('utf-16-le'), 'h\000e\000l\000l\000o\000')
+        self.assertEqual(u'hello'.encode('utf-16-be'), '\000h\000e\000l\000l\000o')
+        self.assertEqual(u'hello'.encode('latin-1'), 'hello')
+
+        # Roundtrip safety for BMP (just the first 1024 chars)
+        for c in xrange(1024):
+            u = unichr(c)
+            for encoding in ('utf-7', 'utf-8', 'utf-16', 'utf-16-le',
+                             'utf-16-be', 'raw_unicode_escape',
+                             'unicode_escape', 'unicode_internal'):
+                self.assertEqual(unicode(u.encode(encoding),encoding), u)
+
+        # Roundtrip safety for BMP (just the first 256 chars)
+        for c in xrange(256):
+            u = unichr(c)
+            for encoding in ('latin-1',):
+                self.assertEqual(unicode(u.encode(encoding),encoding), u)
+
+        # Roundtrip safety for BMP (just the first 128 chars)
+        for c in xrange(128):
+            u = unichr(c)
+            for encoding in ('ascii',):
+                self.assertEqual(unicode(u.encode(encoding),encoding), u)
+
+        # Roundtrip safety for non-BMP (just a few chars)
+        u = u'\U00010001\U00020002\U00030003\U00040004\U00050005'
+        for encoding in ('utf-8', 'utf-16', 'utf-16-le', 'utf-16-be',
+                         #'raw_unicode_escape',
+                         'unicode_escape', 'unicode_internal'):
+            self.assertEqual(unicode(u.encode(encoding),encoding), u)
+
+        # UTF-8 must be roundtrip safe for all UCS-2 code points
+        # This excludes surrogates: in the full range, there would be
+        # a surrogate pair (\udbff\udc00), which gets converted back
+        # to a non-BMP character (\U0010fc00)
+        u = u''.join(map(unichr, range(0,0xd800)+range(0xe000,0x10000)))
+        for encoding in ('utf-8',):
+            self.assertEqual(unicode(u.encode(encoding),encoding), u)
+
+    def test_codecs_charmap(self):
+        # 0-127
+        s = ''.join(map(chr, xrange(128)))
+        for encoding in (
+            'cp037', 'cp1026',
+            'cp437', 'cp500', 'cp737', 'cp775', 'cp850',
+            'cp852', 'cp855', 'cp860', 'cp861', 'cp862',
+            'cp863', 'cp865', 'cp866',
+            'iso8859_10', 'iso8859_13', 'iso8859_14', 'iso8859_15',
+            'iso8859_2', 'iso8859_3', 'iso8859_4', 'iso8859_5', 'iso8859_6',
+            'iso8859_7', 'iso8859_9', 'koi8_r', 'latin_1',
+            'mac_cyrillic', 'mac_latin2',
+
+            'cp1250', 'cp1251', 'cp1252', 'cp1253', 'cp1254', 'cp1255',
+            'cp1256', 'cp1257', 'cp1258',
+            'cp856', 'cp857', 'cp864', 'cp869', 'cp874',
+
+            'mac_greek', 'mac_iceland','mac_roman', 'mac_turkish',
+            'cp1006', 'iso8859_8',
+
+            ### These have undefined mappings:
+            #'cp424',
+
+            ### These fail the round-trip:
+            #'cp875'
+
+            ):
+            self.assertEqual(unicode(s, encoding).encode(encoding), s)
+
+        # 128-255
+        s = ''.join(map(chr, xrange(128, 256)))
+        for encoding in (
+            'cp037', 'cp1026',
+            'cp437', 'cp500', 'cp737', 'cp775', 'cp850',
+            'cp852', 'cp855', 'cp860', 'cp861', 'cp862',
+            'cp863', 'cp865', 'cp866',
+            'iso8859_10', 'iso8859_13', 'iso8859_14', 'iso8859_15',
+            'iso8859_2', 'iso8859_4', 'iso8859_5',
+            'iso8859_9', 'koi8_r', 'latin_1',
+            'mac_cyrillic', 'mac_latin2',
+
+            ### These have undefined mappings:
+            #'cp1250', 'cp1251', 'cp1252', 'cp1253', 'cp1254', 'cp1255',
+            #'cp1256', 'cp1257', 'cp1258',
+            #'cp424', 'cp856', 'cp857', 'cp864', 'cp869', 'cp874',
+            #'iso8859_3', 'iso8859_6', 'iso8859_7',
+            #'mac_greek', 'mac_iceland','mac_roman', 'mac_turkish',
+
+            ### These fail the round-trip:
+            #'cp1006', 'cp875', 'iso8859_8',
+
+            ):
+            self.assertEqual(unicode(s, encoding).encode(encoding), s)
+
+    def test_concatenation(self):
+        self.assertEqual((u"abc" u"def"), u"abcdef")
+        self.assertEqual(("abc" u"def"), u"abcdef")
+        self.assertEqual((u"abc" "def"), u"abcdef")
+        self.assertEqual((u"abc" u"def" "ghi"), u"abcdefghi")
+        self.assertEqual(("abc" "def" u"ghi"), u"abcdefghi")
+
+    def test_printing(self):
+        class BitBucket:
+            def write(self, text):
+                pass
+
+        out = BitBucket()
+        print >>out, u'abc'
+        print >>out, u'abc', u'def'
+        print >>out, u'abc', 'def'
+        print >>out, 'abc', u'def'
+        print >>out, u'abc\n'
+        print >>out, u'abc\n',
+        print >>out, u'abc\n',
+        print >>out, u'def\n'
+        print >>out, u'def\n'
+
+    def test_ucs4(self):
+        if sys.maxunicode == 0xFFFF:
+            return
+        x = u'\U00100000'
+        y = x.encode("raw-unicode-escape").decode("raw-unicode-escape")
+        self.assertEqual(x, y)
+
+    def test_conversion(self):
+        # Make sure __unicode__() works properly
+        class Foo0:
+            def __str__(self):
+                return "foo"
+
+        class Foo1:
+            def __unicode__(self):
+                return u"foo"
+
+        class Foo2(object):
+            def __unicode__(self):
+                return u"foo"
+
+        class Foo3(object):
+            def __unicode__(self):
+                return "foo"
+
+        class Foo4(str):
+            def __unicode__(self):
+                return "foo"
+
+        class Foo5(unicode):
+            def __unicode__(self):
+                return "foo"
+
+        class Foo6(str):
+            def __str__(self):
+                return "foos"
+
+            def __unicode__(self):
+                return u"foou"
+
+        class Foo7(unicode):
+            def __str__(self):
+                return "foos"
+            def __unicode__(self):
+                return u"foou"
+
+        class Foo8(unicode):
+            def __new__(cls, content=""):
+                return unicode.__new__(cls, 2*content)
+            def __unicode__(self):
+                return self
+
+        class Foo9(unicode):
+            def __str__(self):
+                return "string"
+            def __unicode__(self):
+                return "not unicode"
+
+        self.assertEqual(unicode(Foo0()), u"foo")
+        self.assertEqual(unicode(Foo1()), u"foo")
+        self.assertEqual(unicode(Foo2()), u"foo")
+        self.assertEqual(unicode(Foo3()), u"foo")
+        self.assertEqual(unicode(Foo4("bar")), u"foo")
+        self.assertEqual(unicode(Foo5("bar")), u"foo")
+        self.assertEqual(unicode(Foo6("bar")), u"foou")
+        self.assertEqual(unicode(Foo7("bar")), u"foou")
+        self.assertEqual(unicode(Foo8("foo")), u"foofoo")
+        self.assertEqual(str(Foo9("foo")), "string")
+        self.assertEqual(unicode(Foo9("foo")), u"not unicode")
+
+    def test_unicode_repr(self):
+        class s1:
+            def __repr__(self):
+                return '\\n'
+
+        class s2:
+            def __repr__(self):
+                return u'\\n'
+
+        self.assertEqual(repr(s1()), '\\n')
+        self.assertEqual(repr(s2()), '\\n')
+
+
+
+
+
+def test_main():
+    test_support.run_unittest(UnicodeTest)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_unicode_file.py
===================================================================
--- vendor/Python/current/Lib/test/test_unicode_file.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_unicode_file.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,213 @@
+# Test some Unicode file name semantics
+# We dont test many operations on files other than
+# that their names can be used with Unicode characters.
+import os, glob, time, shutil
+import unicodedata
+
+import unittest
+from test.test_support import run_suite, TestSkipped, TESTFN_UNICODE
+from test.test_support import TESTFN_ENCODING, TESTFN_UNICODE_UNENCODEABLE
+try:
+    TESTFN_ENCODED = TESTFN_UNICODE.encode(TESTFN_ENCODING)
+except (UnicodeError, TypeError):
+    # Either the file system encoding is None, or the file name
+    # cannot be encoded in the file system encoding.
+    raise TestSkipped("No Unicode filesystem semantics on this platform.")
+
+if TESTFN_ENCODED.decode(TESTFN_ENCODING) != TESTFN_UNICODE:
+    # The file system encoding does not support Latin-1
+    # (which test_support assumes), so try the file system
+    # encoding instead.
+    import sys
+    try:
+        TESTFN_UNICODE = unicode("@test-\xe0\xf2", sys.getfilesystemencoding())
+        TESTFN_ENCODED = TESTFN_UNICODE.encode(TESTFN_ENCODING)
+        if '?' in TESTFN_ENCODED:
+            # MBCS will not report the error properly
+            raise UnicodeError, "mbcs encoding problem"
+    except (UnicodeError, TypeError):
+        raise TestSkipped("Cannot find a suiteable filename.")
+
+if TESTFN_ENCODED.decode(TESTFN_ENCODING) != TESTFN_UNICODE:
+    raise TestSkipped("Cannot find a suitable filename.")
+
+def remove_if_exists(filename):
+    if os.path.exists(filename):
+        os.unlink(filename)
+
+class TestUnicodeFiles(unittest.TestCase):
+    # The 'do_' functions are the actual tests.  They generally assume the
+    # file already exists etc.
+
+    # Do all the tests we can given only a single filename.  The file should
+    # exist.
+    def _do_single(self, filename):
+        self.failUnless(os.path.exists(filename))
+        self.failUnless(os.path.isfile(filename))
+        self.failUnless(os.access(filename, os.R_OK))
+        self.failUnless(os.path.exists(os.path.abspath(filename)))
+        self.failUnless(os.path.isfile(os.path.abspath(filename)))
+        self.failUnless(os.access(os.path.abspath(filename), os.R_OK))
+        os.chmod(filename, 0777)
+        os.utime(filename, None)
+        os.utime(filename, (time.time(), time.time()))
+        # Copy/rename etc tests using the same filename
+        self._do_copyish(filename, filename)
+        # Filename should appear in glob output
+        self.failUnless(
+            os.path.abspath(filename)==os.path.abspath(glob.glob(filename)[0]))
+        # basename should appear in listdir.
+        path, base = os.path.split(os.path.abspath(filename))
+        if isinstance(base, str):
+            base = base.decode(TESTFN_ENCODING)
+        file_list = os.listdir(path)
+        # listdir() with a unicode arg may or may not return Unicode
+        # objects, depending on the platform.
+        if file_list and isinstance(file_list[0], str):
+            file_list = [f.decode(TESTFN_ENCODING) for f in file_list]
+
+        # Normalize the unicode strings, as round-tripping the name via the OS
+        # may return a different (but equivalent) value.
+        base = unicodedata.normalize("NFD", base)
+        file_list = [unicodedata.normalize("NFD", f) for f in file_list]
+
+        self.failUnless(base in file_list)
+
+    # Do as many "equivalancy' tests as we can - ie, check that although we
+    # have different types for the filename, they refer to the same file.
+    def _do_equivilent(self, filename1, filename2):
+        # Note we only check "filename1 against filename2" - we don't bother
+        # checking "filename2 against 1", as we assume we are called again with
+        # the args reversed.
+        self.failUnless(type(filename1)!=type(filename2),
+                    "No point checking equivalent filenames of the same type")
+        # stat and lstat should return the same results.
+        self.failUnlessEqual(os.stat(filename1),
+                             os.stat(filename2))
+        self.failUnlessEqual(os.lstat(filename1),
+                             os.lstat(filename2))
+        # Copy/rename etc tests using equivalent filename
+        self._do_copyish(filename1, filename2)
+
+    # Tests that copy, move, etc one file to another.
+    def _do_copyish(self, filename1, filename2):
+        # Should be able to rename the file using either name.
+        self.failUnless(os.path.isfile(filename1)) # must exist.
+        os.rename(filename1, filename2 + ".new")
+        self.failUnless(os.path.isfile(filename1+".new"))
+        os.rename(filename1 + ".new", filename2)
+        self.failUnless(os.path.isfile(filename2))
+
+        # Try using shutil on the filenames.
+        try:
+            filename1==filename2
+        except UnicodeDecodeError:
+            # these filenames can't be compared - shutil.copy tries to do
+            # just that.  This is really a bug in 'shutil' - if one of shutil's
+            # 2 params are Unicode and the other isn't, it should coerce the
+            # string to Unicode with the filesystem encoding before comparison.
+            pass
+        else:
+            # filenames can be compared.
+            shutil.copy(filename1, filename2 + ".new")
+            os.unlink(filename1 + ".new") # remove using equiv name.
+            # And a couple of moves, one using each name.
+            shutil.move(filename1, filename2 + ".new")
+            self.failUnless(not os.path.exists(filename2))
+            shutil.move(filename1 + ".new", filename2)
+            self.failUnless(os.path.exists(filename1))
+            # Note - due to the implementation of shutil.move,
+            # it tries a rename first.  This only fails on Windows when on
+            # different file systems - and this test can't ensure that.
+            # So we test the shutil.copy2 function, which is the thing most
+            # likely to fail.
+            shutil.copy2(filename1, filename2 + ".new")
+            os.unlink(filename1 + ".new")
+
+    def _do_directory(self, make_name, chdir_name, encoded):
+        cwd = os.getcwd()
+        if os.path.isdir(make_name):
+            os.rmdir(make_name)
+        os.mkdir(make_name)
+        try:
+            os.chdir(chdir_name)
+            try:
+                if not encoded:
+                    cwd_result = os.getcwdu()
+                    name_result = make_name
+                else:
+                    cwd_result = os.getcwd().decode(TESTFN_ENCODING)
+                    name_result = make_name.decode(TESTFN_ENCODING)
+
+                cwd_result = unicodedata.normalize("NFD", cwd_result)
+                name_result = unicodedata.normalize("NFD", name_result)
+
+                self.failUnlessEqual(os.path.basename(cwd_result),name_result)
+            finally:
+                os.chdir(cwd)
+        finally:
+            os.rmdir(make_name)
+
+    # The '_test' functions 'entry points with params' - ie, what the
+    # top-level 'test' functions would be if they could take params
+    def _test_single(self, filename):
+        remove_if_exists(filename)
+        f = file(filename, "w")
+        f.close()
+        try:
+            self._do_single(filename)
+        finally:
+            os.unlink(filename)
+        self.failUnless(not os.path.exists(filename))
+        # and again with os.open.
+        f = os.open(filename, os.O_CREAT)
+        os.close(f)
+        try:
+            self._do_single(filename)
+        finally:
+            os.unlink(filename)
+
+    def _test_equivalent(self, filename1, filename2):
+        remove_if_exists(filename1)
+        self.failUnless(not os.path.exists(filename2))
+        f = file(filename1, "w")
+        f.close()
+        try:
+            self._do_equivilent(filename1, filename2)
+        finally:
+            os.unlink(filename1)
+
+    # The 'test' functions are unittest entry points, and simply call our
+    # _test functions with each of the filename combinations we wish to test
+    def test_single_files(self):
+        self._test_single(TESTFN_ENCODED)
+        self._test_single(TESTFN_UNICODE)
+        if TESTFN_UNICODE_UNENCODEABLE is not None:
+            self._test_single(TESTFN_UNICODE_UNENCODEABLE)
+
+    def test_equivalent_files(self):
+        self._test_equivalent(TESTFN_ENCODED, TESTFN_UNICODE)
+        self._test_equivalent(TESTFN_UNICODE, TESTFN_ENCODED)
+
+    def test_directories(self):
+        # For all 'equivilent' combinations:
+        #  Make dir with encoded, chdir with unicode, checkdir with encoded
+        #  (or unicode/encoded/unicode, etc
+        ext = ".dir"
+        self._do_directory(TESTFN_ENCODED+ext, TESTFN_ENCODED+ext, True)
+        self._do_directory(TESTFN_ENCODED+ext, TESTFN_UNICODE+ext, True)
+        self._do_directory(TESTFN_UNICODE+ext, TESTFN_ENCODED+ext, False)
+        self._do_directory(TESTFN_UNICODE+ext, TESTFN_UNICODE+ext, False)
+        # Our directory name that can't use a non-unicode name.
+        if TESTFN_UNICODE_UNENCODEABLE is not None:
+            self._do_directory(TESTFN_UNICODE_UNENCODEABLE+ext,
+                               TESTFN_UNICODE_UNENCODEABLE+ext,
+                               False)
+
+def test_main():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(TestUnicodeFiles))
+    run_suite(suite)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_unicodedata.py
===================================================================
--- vendor/Python/current/Lib/test/test_unicodedata.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_unicodedata.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,225 @@
+""" Test script for the unicodedata module.
+
+    Written by Marc-Andre Lemburg (mal at lemburg.com).
+
+    (c) Copyright CNRI, All Rights Reserved. NO WARRANTY.
+
+"""#"
+import unittest, test.test_support
+import hashlib
+
+encoding = 'utf-8'
+
+
+### Run tests
+
+class UnicodeMethodsTest(unittest.TestCase):
+
+    # update this, if the database changes
+    expectedchecksum = 'c198ed264497f108434b3f576d4107237221cc8a'
+
+    def test_method_checksum(self):
+        h = hashlib.sha1()
+        for i in range(65536):
+            char = unichr(i)
+            data = [
+                # Predicates (single char)
+                u"01"[char.isalnum()],
+                u"01"[char.isalpha()],
+                u"01"[char.isdecimal()],
+                u"01"[char.isdigit()],
+                u"01"[char.islower()],
+                u"01"[char.isnumeric()],
+                u"01"[char.isspace()],
+                u"01"[char.istitle()],
+                u"01"[char.isupper()],
+
+                # Predicates (multiple chars)
+                u"01"[(char + u'abc').isalnum()],
+                u"01"[(char + u'abc').isalpha()],
+                u"01"[(char + u'123').isdecimal()],
+                u"01"[(char + u'123').isdigit()],
+                u"01"[(char + u'abc').islower()],
+                u"01"[(char + u'123').isnumeric()],
+                u"01"[(char + u' \t').isspace()],
+                u"01"[(char + u'abc').istitle()],
+                u"01"[(char + u'ABC').isupper()],
+
+                # Mappings (single char)
+                char.lower(),
+                char.upper(),
+                char.title(),
+
+                # Mappings (multiple chars)
+                (char + u'abc').lower(),
+                (char + u'ABC').upper(),
+                (char + u'abc').title(),
+                (char + u'ABC').title(),
+
+                ]
+            h.update(u''.join(data).encode(encoding))
+        result = h.hexdigest()
+        self.assertEqual(result, self.expectedchecksum)
+
+class UnicodeDatabaseTest(unittest.TestCase):
+
+    def setUp(self):
+        # In case unicodedata is not available, this will raise an ImportError,
+        # but the other test cases will still be run
+        import unicodedata
+        self.db = unicodedata
+
+    def tearDown(self):
+        del self.db
+
+class UnicodeFunctionsTest(UnicodeDatabaseTest):
+
+    # update this, if the database changes
+    expectedchecksum = '4e389f97e9f88b8b7ab743121fd643089116f9f2'
+
+    def test_function_checksum(self):
+        data = []
+        h = hashlib.sha1()
+
+        for i in range(0x10000):
+            char = unichr(i)
+            data = [
+                # Properties
+                str(self.db.digit(char, -1)),
+                str(self.db.numeric(char, -1)),
+                str(self.db.decimal(char, -1)),
+                self.db.category(char),
+                self.db.bidirectional(char),
+                self.db.decomposition(char),
+                str(self.db.mirrored(char)),
+                str(self.db.combining(char)),
+            ]
+            h.update(''.join(data))
+        result = h.hexdigest()
+        self.assertEqual(result, self.expectedchecksum)
+
+    def test_digit(self):
+        self.assertEqual(self.db.digit(u'A', None), None)
+        self.assertEqual(self.db.digit(u'9'), 9)
+        self.assertEqual(self.db.digit(u'\u215b', None), None)
+        self.assertEqual(self.db.digit(u'\u2468'), 9)
+
+        self.assertRaises(TypeError, self.db.digit)
+        self.assertRaises(TypeError, self.db.digit, u'xx')
+        self.assertRaises(ValueError, self.db.digit, u'x')
+
+    def test_numeric(self):
+        self.assertEqual(self.db.numeric(u'A',None), None)
+        self.assertEqual(self.db.numeric(u'9'), 9)
+        self.assertEqual(self.db.numeric(u'\u215b'), 0.125)
+        self.assertEqual(self.db.numeric(u'\u2468'), 9.0)
+
+        self.assertRaises(TypeError, self.db.numeric)
+        self.assertRaises(TypeError, self.db.numeric, u'xx')
+        self.assertRaises(ValueError, self.db.numeric, u'x')
+
+    def test_decimal(self):
+        self.assertEqual(self.db.decimal(u'A',None), None)
+        self.assertEqual(self.db.decimal(u'9'), 9)
+        self.assertEqual(self.db.decimal(u'\u215b', None), None)
+        self.assertEqual(self.db.decimal(u'\u2468', None), None)
+
+        self.assertRaises(TypeError, self.db.decimal)
+        self.assertRaises(TypeError, self.db.decimal, u'xx')
+        self.assertRaises(ValueError, self.db.decimal, u'x')
+
+    def test_category(self):
+        self.assertEqual(self.db.category(u'\uFFFE'), 'Cn')
+        self.assertEqual(self.db.category(u'a'), 'Ll')
+        self.assertEqual(self.db.category(u'A'), 'Lu')
+
+        self.assertRaises(TypeError, self.db.category)
+        self.assertRaises(TypeError, self.db.category, u'xx')
+
+    def test_bidirectional(self):
+        self.assertEqual(self.db.bidirectional(u'\uFFFE'), '')
+        self.assertEqual(self.db.bidirectional(u' '), 'WS')
+        self.assertEqual(self.db.bidirectional(u'A'), 'L')
+
+        self.assertRaises(TypeError, self.db.bidirectional)
+        self.assertRaises(TypeError, self.db.bidirectional, u'xx')
+
+    def test_decomposition(self):
+        self.assertEqual(self.db.decomposition(u'\uFFFE'),'')
+        self.assertEqual(self.db.decomposition(u'\u00bc'), '<fraction> 0031 2044 0034')
+
+        self.assertRaises(TypeError, self.db.decomposition)
+        self.assertRaises(TypeError, self.db.decomposition, u'xx')
+
+    def test_mirrored(self):
+        self.assertEqual(self.db.mirrored(u'\uFFFE'), 0)
+        self.assertEqual(self.db.mirrored(u'a'), 0)
+        self.assertEqual(self.db.mirrored(u'\u2201'), 1)
+
+        self.assertRaises(TypeError, self.db.mirrored)
+        self.assertRaises(TypeError, self.db.mirrored, u'xx')
+
+    def test_combining(self):
+        self.assertEqual(self.db.combining(u'\uFFFE'), 0)
+        self.assertEqual(self.db.combining(u'a'), 0)
+        self.assertEqual(self.db.combining(u'\u20e1'), 230)
+
+        self.assertRaises(TypeError, self.db.combining)
+        self.assertRaises(TypeError, self.db.combining, u'xx')
+
+    def test_normalize(self):
+        self.assertRaises(TypeError, self.db.normalize)
+        self.assertRaises(ValueError, self.db.normalize, 'unknown', u'xx')
+        self.assertEqual(self.db.normalize('NFKC', u''), u'')
+        # The rest can be found in test_normalization.py
+        # which requires an external file.
+
+    def test_east_asian_width(self):
+        eaw = self.db.east_asian_width
+        self.assertRaises(TypeError, eaw, 'a')
+        self.assertRaises(TypeError, eaw, u'')
+        self.assertRaises(TypeError, eaw, u'ra')
+        self.assertEqual(eaw(u'\x1e'), 'N')
+        self.assertEqual(eaw(u'\x20'), 'Na')
+        self.assertEqual(eaw(u'\uC894'), 'W')
+        self.assertEqual(eaw(u'\uFF66'), 'H')
+        self.assertEqual(eaw(u'\uFF1F'), 'F')
+        self.assertEqual(eaw(u'\u2010'), 'A')
+
+class UnicodeMiscTest(UnicodeDatabaseTest):
+
+    def test_decimal_numeric_consistent(self):
+        # Test that decimal and numeric are consistent,
+        # i.e. if a character has a decimal value,
+        # its numeric value should be the same.
+        count = 0
+        for i in xrange(0x10000):
+            c = unichr(i)
+            dec = self.db.decimal(c, -1)
+            if dec != -1:
+                self.assertEqual(dec, self.db.numeric(c))
+                count += 1
+        self.assert_(count >= 10) # should have tested at least the ASCII digits
+
+    def test_digit_numeric_consistent(self):
+        # Test that digit and numeric are consistent,
+        # i.e. if a character has a digit value,
+        # its numeric value should be the same.
+        count = 0
+        for i in xrange(0x10000):
+            c = unichr(i)
+            dec = self.db.digit(c, -1)
+            if dec != -1:
+                self.assertEqual(dec, self.db.numeric(c))
+                count += 1
+        self.assert_(count >= 10) # should have tested at least the ASCII digits
+
+def test_main():
+    test.test_support.run_unittest(
+        UnicodeMiscTest,
+        UnicodeMethodsTest,
+        UnicodeFunctionsTest
+    )
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_unittest.py
===================================================================
--- vendor/Python/current/Lib/test/test_unittest.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_unittest.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,31 @@
+"""Test script for unittest.
+
+This just includes tests for new features.  We really need a
+full set of tests.
+"""
+
+import unittest
+
+def test_TestSuite_iter():
+    """
+    >>> test1 = unittest.FunctionTestCase(lambda: None)
+    >>> test2 = unittest.FunctionTestCase(lambda: None)
+    >>> suite = unittest.TestSuite((test1, test2))
+    >>> tests = []
+    >>> for test in suite:
+    ...     tests.append(test)
+    >>> tests == [test1, test2]
+    True
+    """
+
+
+######################################################################
+## Main
+######################################################################
+
+def test_main():
+    from test import test_support, test_unittest
+    test_support.run_doctest(test_unittest, verbosity=True)
+
+if __name__ == '__main__':
+    test_main()

Added: vendor/Python/current/Lib/test/test_univnewlines.py
===================================================================
--- vendor/Python/current/Lib/test/test_univnewlines.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_univnewlines.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,123 @@
+# Tests universal newline support for both reading and parsing files.
+import unittest
+import os
+import sys
+from test import test_support
+
+if not hasattr(sys.stdin, 'newlines'):
+    raise test_support.TestSkipped, \
+        "This Python does not have universal newline support"
+
+FATX = 'x' * (2**14)
+
+DATA_TEMPLATE = [
+    "line1=1",
+    "line2='this is a very long line designed to go past the magic " +
+        "hundred character limit that is inside fileobject.c and which " +
+        "is meant to speed up the common case, but we also want to test " +
+        "the uncommon case, naturally.'",
+    "def line3():pass",
+    "line4 = '%s'" % FATX,
+    ]
+
+DATA_LF = "\n".join(DATA_TEMPLATE) + "\n"
+DATA_CR = "\r".join(DATA_TEMPLATE) + "\r"
+DATA_CRLF = "\r\n".join(DATA_TEMPLATE) + "\r\n"
+
+# Note that DATA_MIXED also tests the ability to recognize a lone \r
+# before end-of-file.
+DATA_MIXED = "\n".join(DATA_TEMPLATE) + "\r"
+DATA_SPLIT = [x + "\n" for x in DATA_TEMPLATE]
+del x
+
+class TestGenericUnivNewlines(unittest.TestCase):
+    # use a class variable DATA to define the data to write to the file
+    # and a class variable NEWLINE to set the expected newlines value
+    READMODE = 'U'
+    WRITEMODE = 'wb'
+
+    def setUp(self):
+        fp = open(test_support.TESTFN, self.WRITEMODE)
+        fp.write(self.DATA)
+        fp.close()
+
+    def tearDown(self):
+        try:
+            os.unlink(test_support.TESTFN)
+        except:
+            pass
+
+    def test_read(self):
+        fp = open(test_support.TESTFN, self.READMODE)
+        data = fp.read()
+        self.assertEqual(data, DATA_LF)
+        self.assertEqual(repr(fp.newlines), repr(self.NEWLINE))
+
+    def test_readlines(self):
+        fp = open(test_support.TESTFN, self.READMODE)
+        data = fp.readlines()
+        self.assertEqual(data, DATA_SPLIT)
+        self.assertEqual(repr(fp.newlines), repr(self.NEWLINE))
+
+    def test_readline(self):
+        fp = open(test_support.TESTFN, self.READMODE)
+        data = []
+        d = fp.readline()
+        while d:
+            data.append(d)
+            d = fp.readline()
+        self.assertEqual(data, DATA_SPLIT)
+        self.assertEqual(repr(fp.newlines), repr(self.NEWLINE))
+
+    def test_seek(self):
+        fp = open(test_support.TESTFN, self.READMODE)
+        fp.readline()
+        pos = fp.tell()
+        data = fp.readlines()
+        self.assertEqual(data, DATA_SPLIT[1:])
+        fp.seek(pos)
+        data = fp.readlines()
+        self.assertEqual(data, DATA_SPLIT[1:])
+
+    def test_execfile(self):
+        namespace = {}
+        execfile(test_support.TESTFN, namespace)
+        func = namespace['line3']
+        self.assertEqual(func.func_code.co_firstlineno, 3)
+        self.assertEqual(namespace['line4'], FATX)
+
+
+class TestNativeNewlines(TestGenericUnivNewlines):
+    NEWLINE = None
+    DATA = DATA_LF
+    READMODE = 'r'
+    WRITEMODE = 'w'
+
+class TestCRNewlines(TestGenericUnivNewlines):
+    NEWLINE = '\r'
+    DATA = DATA_CR
+
+class TestLFNewlines(TestGenericUnivNewlines):
+    NEWLINE = '\n'
+    DATA = DATA_LF
+
+class TestCRLFNewlines(TestGenericUnivNewlines):
+    NEWLINE = '\r\n'
+    DATA = DATA_CRLF
+
+class TestMixedNewlines(TestGenericUnivNewlines):
+    NEWLINE = ('\r', '\n')
+    DATA = DATA_MIXED
+
+
+def test_main():
+    test_support.run_unittest(
+        TestNativeNewlines,
+        TestCRNewlines,
+        TestLFNewlines,
+        TestCRLFNewlines,
+        TestMixedNewlines
+     )
+
+if __name__ == '__main__':
+    test_main()

Added: vendor/Python/current/Lib/test/test_unpack.py
===================================================================
--- vendor/Python/current/Lib/test/test_unpack.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_unpack.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,131 @@
+doctests = """
+
+Unpack tuple
+
+    >>> t = (1, 2, 3)
+    >>> a, b, c = t
+    >>> a == 1 and b == 2 and c == 3
+    True
+
+Unpack list
+
+    >>> l = [4, 5, 6]
+    >>> a, b, c = l
+    >>> a == 4 and b == 5 and c == 6
+    True
+
+Unpack implied tuple
+
+    >>> a, b, c = 7, 8, 9
+    >>> a == 7 and b == 8 and c == 9
+    True
+
+Unpack string... fun!
+
+    >>> a, b, c = 'one'
+    >>> a == 'o' and b == 'n' and c == 'e'
+    True
+
+Unpack generic sequence
+
+    >>> class Seq:
+    ...     def __getitem__(self, i):
+    ...         if i >= 0 and i < 3: return i
+    ...         raise IndexError
+    ...
+    >>> a, b, c = Seq()
+    >>> a == 0 and b == 1 and c == 2
+    True
+
+Single element unpacking, with extra syntax
+
+    >>> st = (99,)
+    >>> sl = [100]
+    >>> a, = st
+    >>> a
+    99
+    >>> b, = sl
+    >>> b
+    100
+
+Now for some failures
+
+Unpacking non-sequence
+
+    >>> a, b, c = 7
+    Traceback (most recent call last):
+      ...
+    TypeError: 'int' object is not iterable
+
+Unpacking tuple of wrong size
+
+    >>> a, b = t
+    Traceback (most recent call last):
+      ...
+    ValueError: too many values to unpack
+
+Unpacking tuple of wrong size
+
+    >>> a, b = l
+    Traceback (most recent call last):
+      ...
+    ValueError: too many values to unpack
+
+Unpacking sequence too short
+
+    >>> a, b, c, d = Seq()
+    Traceback (most recent call last):
+      ...
+    ValueError: need more than 3 values to unpack
+
+Unpacking sequence too long
+
+    >>> a, b = Seq()
+    Traceback (most recent call last):
+      ...
+    ValueError: too many values to unpack
+
+Unpacking a sequence where the test for too long raises a different kind of
+error
+
+    >>> class BozoError(Exception):
+    ...     pass
+    ...
+    >>> class BadSeq:
+    ...     def __getitem__(self, i):
+    ...         if i >= 0 and i < 3:
+    ...             return i
+    ...         elif i == 3:
+    ...             raise BozoError
+    ...         else:
+    ...             raise IndexError
+    ...
+
+Trigger code while not expecting an IndexError (unpack sequence too long, wrong
+error)
+
+    >>> a, b, c, d, e = BadSeq()
+    Traceback (most recent call last):
+      ...
+    BozoError
+
+Trigger code while expecting an IndexError (unpack sequence too short, wrong
+error)
+
+    >>> a, b, c = BadSeq()
+    Traceback (most recent call last):
+      ...
+    BozoError
+
+"""
+
+__test__ = {'doctests' : doctests}
+
+def test_main(verbose=False):
+    import sys
+    from test import test_support
+    from test import test_unpack
+    test_support.run_doctest(test_unpack, verbose)
+
+if __name__ == "__main__":
+    test_main(verbose=True)

Added: vendor/Python/current/Lib/test/test_urllib.py
===================================================================
--- vendor/Python/current/Lib/test/test_urllib.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_urllib.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,560 @@
+"""Regresssion tests for urllib"""
+
+import urllib
+import httplib
+import unittest
+from test import test_support
+import os
+import mimetools
+import tempfile
+import StringIO
+
+def hexescape(char):
+    """Escape char as RFC 2396 specifies"""
+    hex_repr = hex(ord(char))[2:].upper()
+    if len(hex_repr) == 1:
+        hex_repr = "0%s" % hex_repr
+    return "%" + hex_repr
+
+class urlopen_FileTests(unittest.TestCase):
+    """Test urlopen() opening a temporary file.
+
+    Try to test as much functionality as possible so as to cut down on reliance
+    on connecting to the Net for testing.
+
+    """
+
+    def setUp(self):
+        """Setup of a temp file to use for testing"""
+        self.text = "test_urllib: %s\n" % self.__class__.__name__
+        FILE = file(test_support.TESTFN, 'wb')
+        try:
+            FILE.write(self.text)
+        finally:
+            FILE.close()
+        self.pathname = test_support.TESTFN
+        self.returned_obj = urllib.urlopen("file:%s" % self.pathname)
+
+    def tearDown(self):
+        """Shut down the open object"""
+        self.returned_obj.close()
+        os.remove(test_support.TESTFN)
+
+    def test_interface(self):
+        # Make sure object returned by urlopen() has the specified methods
+        for attr in ("read", "readline", "readlines", "fileno",
+                     "close", "info", "geturl", "__iter__"):
+            self.assert_(hasattr(self.returned_obj, attr),
+                         "object returned by urlopen() lacks %s attribute" %
+                         attr)
+
+    def test_read(self):
+        self.assertEqual(self.text, self.returned_obj.read())
+
+    def test_readline(self):
+        self.assertEqual(self.text, self.returned_obj.readline())
+        self.assertEqual('', self.returned_obj.readline(),
+                         "calling readline() after exhausting the file did not"
+                         " return an empty string")
+
+    def test_readlines(self):
+        lines_list = self.returned_obj.readlines()
+        self.assertEqual(len(lines_list), 1,
+                         "readlines() returned the wrong number of lines")
+        self.assertEqual(lines_list[0], self.text,
+                         "readlines() returned improper text")
+
+    def test_fileno(self):
+        file_num = self.returned_obj.fileno()
+        self.assert_(isinstance(file_num, int),
+                     "fileno() did not return an int")
+        self.assertEqual(os.read(file_num, len(self.text)), self.text,
+                         "Reading on the file descriptor returned by fileno() "
+                         "did not return the expected text")
+
+    def test_close(self):
+        # Test close() by calling it hear and then having it be called again
+        # by the tearDown() method for the test
+        self.returned_obj.close()
+
+    def test_info(self):
+        self.assert_(isinstance(self.returned_obj.info(), mimetools.Message))
+
+    def test_geturl(self):
+        self.assertEqual(self.returned_obj.geturl(), self.pathname)
+
+    def test_iter(self):
+        # Test iterator
+        # Don't need to count number of iterations since test would fail the
+        # instant it returned anything beyond the first line from the
+        # comparison
+        for line in self.returned_obj.__iter__():
+            self.assertEqual(line, self.text)
+
+class urlopen_HttpTests(unittest.TestCase):
+    """Test urlopen() opening a fake http connection."""
+
+    def fakehttp(self, fakedata):
+        class FakeSocket(StringIO.StringIO):
+            def sendall(self, str): pass
+            def makefile(self, mode, name): return self
+            def read(self, amt=None):
+                if self.closed: return ''
+                return StringIO.StringIO.read(self, amt)
+            def readline(self, length=None):
+                if self.closed: return ''
+                return StringIO.StringIO.readline(self, length)
+        class FakeHTTPConnection(httplib.HTTPConnection):
+            def connect(self):
+                self.sock = FakeSocket(fakedata)
+        assert httplib.HTTP._connection_class == httplib.HTTPConnection
+        httplib.HTTP._connection_class = FakeHTTPConnection
+
+    def unfakehttp(self):
+        httplib.HTTP._connection_class = httplib.HTTPConnection
+
+    def test_read(self):
+        self.fakehttp('Hello!')
+        try:
+            fp = urllib.urlopen("http://python.org/")
+            self.assertEqual(fp.readline(), 'Hello!')
+            self.assertEqual(fp.readline(), '')
+        finally:
+            self.unfakehttp()
+
+    def test_empty_socket(self):
+        """urlopen() raises IOError if the underlying socket does not send any
+        data. (#1680230) """
+        self.fakehttp('')
+        try:
+            self.assertRaises(IOError, urllib.urlopen, 'http://something')
+        finally:
+            self.unfakehttp()
+
+class urlretrieve_FileTests(unittest.TestCase):
+    """Test urllib.urlretrieve() on local files"""
+
+    def setUp(self):
+        # Create a list of temporary files. Each item in the list is a file
+        # name (absolute path or relative to the current working directory).
+        # All files in this list will be deleted in the tearDown method. Note,
+        # this only helps to makes sure temporary files get deleted, but it
+        # does nothing about trying to close files that may still be open. It
+        # is the responsibility of the developer to properly close files even
+        # when exceptional conditions occur.
+        self.tempFiles = []
+
+        # Create a temporary file.
+        self.registerFileForCleanUp(test_support.TESTFN)
+        self.text = 'testing urllib.urlretrieve'
+        try:
+            FILE = file(test_support.TESTFN, 'wb')
+            FILE.write(self.text)
+            FILE.close()
+        finally:
+            try: FILE.close()
+            except: pass
+
+    def tearDown(self):
+        # Delete the temporary files.
+        for each in self.tempFiles:
+            try: os.remove(each)
+            except: pass
+
+    def constructLocalFileUrl(self, filePath):
+        return "file://%s" % urllib.pathname2url(os.path.abspath(filePath))
+
+    def createNewTempFile(self, data=""):
+        """Creates a new temporary file containing the specified data,
+        registers the file for deletion during the test fixture tear down, and
+        returns the absolute path of the file."""
+
+        newFd, newFilePath = tempfile.mkstemp()
+        try:
+            self.registerFileForCleanUp(newFilePath)
+            newFile = os.fdopen(newFd, "wb")
+            newFile.write(data)
+            newFile.close()
+        finally:
+            try: newFile.close()
+            except: pass
+        return newFilePath
+
+    def registerFileForCleanUp(self, fileName):
+        self.tempFiles.append(fileName)
+
+    def test_basic(self):
+        # Make sure that a local file just gets its own location returned and
+        # a headers value is returned.
+        result = urllib.urlretrieve("file:%s" % test_support.TESTFN)
+        self.assertEqual(result[0], test_support.TESTFN)
+        self.assert_(isinstance(result[1], mimetools.Message),
+                     "did not get a mimetools.Message instance as second "
+                     "returned value")
+
+    def test_copy(self):
+        # Test that setting the filename argument works.
+        second_temp = "%s.2" % test_support.TESTFN
+        self.registerFileForCleanUp(second_temp)
+        result = urllib.urlretrieve(self.constructLocalFileUrl(
+            test_support.TESTFN), second_temp)
+        self.assertEqual(second_temp, result[0])
+        self.assert_(os.path.exists(second_temp), "copy of the file was not "
+                                                  "made")
+        FILE = file(second_temp, 'rb')
+        try:
+            text = FILE.read()
+            FILE.close()
+        finally:
+            try: FILE.close()
+            except: pass
+        self.assertEqual(self.text, text)
+
+    def test_reporthook(self):
+        # Make sure that the reporthook works.
+        def hooktester(count, block_size, total_size, count_holder=[0]):
+            self.assert_(isinstance(count, int))
+            self.assert_(isinstance(block_size, int))
+            self.assert_(isinstance(total_size, int))
+            self.assertEqual(count, count_holder[0])
+            count_holder[0] = count_holder[0] + 1
+        second_temp = "%s.2" % test_support.TESTFN
+        self.registerFileForCleanUp(second_temp)
+        urllib.urlretrieve(self.constructLocalFileUrl(test_support.TESTFN),
+            second_temp, hooktester)
+
+    def test_reporthook_0_bytes(self):
+        # Test on zero length file. Should call reporthook only 1 time.
+        report = []
+        def hooktester(count, block_size, total_size, _report=report):
+            _report.append((count, block_size, total_size))
+        srcFileName = self.createNewTempFile()
+        urllib.urlretrieve(self.constructLocalFileUrl(srcFileName),
+            test_support.TESTFN, hooktester)
+        self.assertEqual(len(report), 1)
+        self.assertEqual(report[0][2], 0)
+
+    def test_reporthook_5_bytes(self):
+        # Test on 5 byte file. Should call reporthook only 2 times (once when
+        # the "network connection" is established and once when the block is
+        # read). Since the block size is 8192 bytes, only one block read is
+        # required to read the entire file.
+        report = []
+        def hooktester(count, block_size, total_size, _report=report):
+            _report.append((count, block_size, total_size))
+        srcFileName = self.createNewTempFile("x" * 5)
+        urllib.urlretrieve(self.constructLocalFileUrl(srcFileName),
+            test_support.TESTFN, hooktester)
+        self.assertEqual(len(report), 2)
+        self.assertEqual(report[0][1], 8192)
+        self.assertEqual(report[0][2], 5)
+
+    def test_reporthook_8193_bytes(self):
+        # Test on 8193 byte file. Should call reporthook only 3 times (once
+        # when the "network connection" is established, once for the next 8192
+        # bytes, and once for the last byte).
+        report = []
+        def hooktester(count, block_size, total_size, _report=report):
+            _report.append((count, block_size, total_size))
+        srcFileName = self.createNewTempFile("x" * 8193)
+        urllib.urlretrieve(self.constructLocalFileUrl(srcFileName),
+            test_support.TESTFN, hooktester)
+        self.assertEqual(len(report), 3)
+        self.assertEqual(report[0][1], 8192)
+        self.assertEqual(report[0][2], 8193)
+
+class QuotingTests(unittest.TestCase):
+    """Tests for urllib.quote() and urllib.quote_plus()
+
+    According to RFC 2396 ("Uniform Resource Identifiers), to escape a
+    character you write it as '%' + <2 character US-ASCII hex value>.  The Python
+    code of ``'%' + hex(ord(<character>))[2:]`` escapes a character properly.
+    Case does not matter on the hex letters.
+
+    The various character sets specified are:
+
+    Reserved characters : ";/?:@&=+$,"
+        Have special meaning in URIs and must be escaped if not being used for
+        their special meaning
+    Data characters : letters, digits, and "-_.!~*'()"
+        Unreserved and do not need to be escaped; can be, though, if desired
+    Control characters : 0x00 - 0x1F, 0x7F
+        Have no use in URIs so must be escaped
+    space : 0x20
+        Must be escaped
+    Delimiters : '<>#%"'
+        Must be escaped
+    Unwise : "{}|\^[]`"
+        Must be escaped
+
+    """
+
+    def test_never_quote(self):
+        # Make sure quote() does not quote letters, digits, and "_,.-"
+        do_not_quote = '' .join(["ABCDEFGHIJKLMNOPQRSTUVWXYZ",
+                                 "abcdefghijklmnopqrstuvwxyz",
+                                 "0123456789",
+                                 "_.-"])
+        result = urllib.quote(do_not_quote)
+        self.assertEqual(do_not_quote, result,
+                         "using quote(): %s != %s" % (do_not_quote, result))
+        result = urllib.quote_plus(do_not_quote)
+        self.assertEqual(do_not_quote, result,
+                        "using quote_plus(): %s != %s" % (do_not_quote, result))
+
+    def test_default_safe(self):
+        # Test '/' is default value for 'safe' parameter
+        self.assertEqual(urllib.quote.func_defaults[0], '/')
+
+    def test_safe(self):
+        # Test setting 'safe' parameter does what it should do
+        quote_by_default = "<>"
+        result = urllib.quote(quote_by_default, safe=quote_by_default)
+        self.assertEqual(quote_by_default, result,
+                         "using quote(): %s != %s" % (quote_by_default, result))
+        result = urllib.quote_plus(quote_by_default, safe=quote_by_default)
+        self.assertEqual(quote_by_default, result,
+                         "using quote_plus(): %s != %s" %
+                         (quote_by_default, result))
+
+    def test_default_quoting(self):
+        # Make sure all characters that should be quoted are by default sans
+        # space (separate test for that).
+        should_quote = [chr(num) for num in range(32)] # For 0x00 - 0x1F
+        should_quote.append('<>#%"{}|\^[]`')
+        should_quote.append(chr(127)) # For 0x7F
+        should_quote = ''.join(should_quote)
+        for char in should_quote:
+            result = urllib.quote(char)
+            self.assertEqual(hexescape(char), result,
+                             "using quote(): %s should be escaped to %s, not %s" %
+                             (char, hexescape(char), result))
+            result = urllib.quote_plus(char)
+            self.assertEqual(hexescape(char), result,
+                             "using quote_plus(): "
+                             "%s should be escapes to %s, not %s" %
+                             (char, hexescape(char), result))
+        del should_quote
+        partial_quote = "ab[]cd"
+        expected = "ab%5B%5Dcd"
+        result = urllib.quote(partial_quote)
+        self.assertEqual(expected, result,
+                         "using quote(): %s != %s" % (expected, result))
+        self.assertEqual(expected, result,
+                         "using quote_plus(): %s != %s" % (expected, result))
+
+    def test_quoting_space(self):
+        # Make sure quote() and quote_plus() handle spaces as specified in
+        # their unique way
+        result = urllib.quote(' ')
+        self.assertEqual(result, hexescape(' '),
+                         "using quote(): %s != %s" % (result, hexescape(' ')))
+        result = urllib.quote_plus(' ')
+        self.assertEqual(result, '+',
+                         "using quote_plus(): %s != +" % result)
+        given = "a b cd e f"
+        expect = given.replace(' ', hexescape(' '))
+        result = urllib.quote(given)
+        self.assertEqual(expect, result,
+                         "using quote(): %s != %s" % (expect, result))
+        expect = given.replace(' ', '+')
+        result = urllib.quote_plus(given)
+        self.assertEqual(expect, result,
+                         "using quote_plus(): %s != %s" % (expect, result))
+
+    def test_quoting_plus(self):
+        self.assertEqual(urllib.quote_plus('alpha+beta gamma'),
+                         'alpha%2Bbeta+gamma')
+        self.assertEqual(urllib.quote_plus('alpha+beta gamma', '+'),
+                         'alpha+beta+gamma')
+
+class UnquotingTests(unittest.TestCase):
+    """Tests for unquote() and unquote_plus()
+
+    See the doc string for quoting_Tests for details on quoting and such.
+
+    """
+
+    def test_unquoting(self):
+        # Make sure unquoting of all ASCII values works
+        escape_list = []
+        for num in range(128):
+            given = hexescape(chr(num))
+            expect = chr(num)
+            result = urllib.unquote(given)
+            self.assertEqual(expect, result,
+                             "using unquote(): %s != %s" % (expect, result))
+            result = urllib.unquote_plus(given)
+            self.assertEqual(expect, result,
+                             "using unquote_plus(): %s != %s" %
+                             (expect, result))
+            escape_list.append(given)
+        escape_string = ''.join(escape_list)
+        del escape_list
+        result = urllib.unquote(escape_string)
+        self.assertEqual(result.count('%'), 1,
+                         "using quote(): not all characters escaped; %s" %
+                         result)
+        result = urllib.unquote(escape_string)
+        self.assertEqual(result.count('%'), 1,
+                         "using unquote(): not all characters escaped: "
+                         "%s" % result)
+
+    def test_unquoting_parts(self):
+        # Make sure unquoting works when have non-quoted characters
+        # interspersed
+        given = 'ab%sd' % hexescape('c')
+        expect = "abcd"
+        result = urllib.unquote(given)
+        self.assertEqual(expect, result,
+                         "using quote(): %s != %s" % (expect, result))
+        result = urllib.unquote_plus(given)
+        self.assertEqual(expect, result,
+                         "using unquote_plus(): %s != %s" % (expect, result))
+
+    def test_unquoting_plus(self):
+        # Test difference between unquote() and unquote_plus()
+        given = "are+there+spaces..."
+        expect = given
+        result = urllib.unquote(given)
+        self.assertEqual(expect, result,
+                         "using unquote(): %s != %s" % (expect, result))
+        expect = given.replace('+', ' ')
+        result = urllib.unquote_plus(given)
+        self.assertEqual(expect, result,
+                         "using unquote_plus(): %s != %s" % (expect, result))
+
+    def test_unquote_with_unicode(self):
+        r = urllib.unquote(u'br%C3%BCckner_sapporo_20050930.doc')
+        self.assertEqual(r, u'br\xc3\xbcckner_sapporo_20050930.doc')
+
+class urlencode_Tests(unittest.TestCase):
+    """Tests for urlencode()"""
+
+    def help_inputtype(self, given, test_type):
+        """Helper method for testing different input types.
+
+        'given' must lead to only the pairs:
+            * 1st, 1
+            * 2nd, 2
+            * 3rd, 3
+
+        Test cannot assume anything about order.  Docs make no guarantee and
+        have possible dictionary input.
+
+        """
+        expect_somewhere = ["1st=1", "2nd=2", "3rd=3"]
+        result = urllib.urlencode(given)
+        for expected in expect_somewhere:
+            self.assert_(expected in result,
+                         "testing %s: %s not found in %s" %
+                         (test_type, expected, result))
+        self.assertEqual(result.count('&'), 2,
+                         "testing %s: expected 2 '&'s; got %s" %
+                         (test_type, result.count('&')))
+        amp_location = result.index('&')
+        on_amp_left = result[amp_location - 1]
+        on_amp_right = result[amp_location + 1]
+        self.assert_(on_amp_left.isdigit() and on_amp_right.isdigit(),
+                     "testing %s: '&' not located in proper place in %s" %
+                     (test_type, result))
+        self.assertEqual(len(result), (5 * 3) + 2, #5 chars per thing and amps
+                         "testing %s: "
+                         "unexpected number of characters: %s != %s" %
+                         (test_type, len(result), (5 * 3) + 2))
+
+    def test_using_mapping(self):
+        # Test passing in a mapping object as an argument.
+        self.help_inputtype({"1st":'1', "2nd":'2', "3rd":'3'},
+                            "using dict as input type")
+
+    def test_using_sequence(self):
+        # Test passing in a sequence of two-item sequences as an argument.
+        self.help_inputtype([('1st', '1'), ('2nd', '2'), ('3rd', '3')],
+                            "using sequence of two-item tuples as input")
+
+    def test_quoting(self):
+        # Make sure keys and values are quoted using quote_plus()
+        given = {"&":"="}
+        expect = "%s=%s" % (hexescape('&'), hexescape('='))
+        result = urllib.urlencode(given)
+        self.assertEqual(expect, result)
+        given = {"key name":"A bunch of pluses"}
+        expect = "key+name=A+bunch+of+pluses"
+        result = urllib.urlencode(given)
+        self.assertEqual(expect, result)
+
+    def test_doseq(self):
+        # Test that passing True for 'doseq' parameter works correctly
+        given = {'sequence':['1', '2', '3']}
+        expect = "sequence=%s" % urllib.quote_plus(str(['1', '2', '3']))
+        result = urllib.urlencode(given)
+        self.assertEqual(expect, result)
+        result = urllib.urlencode(given, True)
+        for value in given["sequence"]:
+            expect = "sequence=%s" % value
+            self.assert_(expect in result,
+                         "%s not found in %s" % (expect, result))
+        self.assertEqual(result.count('&'), 2,
+                         "Expected 2 '&'s, got %s" % result.count('&'))
+
+class Pathname_Tests(unittest.TestCase):
+    """Test pathname2url() and url2pathname()"""
+
+    def test_basic(self):
+        # Make sure simple tests pass
+        expected_path = os.path.join("parts", "of", "a", "path")
+        expected_url = "parts/of/a/path"
+        result = urllib.pathname2url(expected_path)
+        self.assertEqual(expected_url, result,
+                         "pathname2url() failed; %s != %s" %
+                         (result, expected_url))
+        result = urllib.url2pathname(expected_url)
+        self.assertEqual(expected_path, result,
+                         "url2pathame() failed; %s != %s" %
+                         (result, expected_path))
+
+    def test_quoting(self):
+        # Test automatic quoting and unquoting works for pathnam2url() and
+        # url2pathname() respectively
+        given = os.path.join("needs", "quot=ing", "here")
+        expect = "needs/%s/here" % urllib.quote("quot=ing")
+        result = urllib.pathname2url(given)
+        self.assertEqual(expect, result,
+                         "pathname2url() failed; %s != %s" %
+                         (expect, result))
+        expect = given
+        result = urllib.url2pathname(result)
+        self.assertEqual(expect, result,
+                         "url2pathname() failed; %s != %s" %
+                         (expect, result))
+        given = os.path.join("make sure", "using_quote")
+        expect = "%s/using_quote" % urllib.quote("make sure")
+        result = urllib.pathname2url(given)
+        self.assertEqual(expect, result,
+                         "pathname2url() failed; %s != %s" %
+                         (expect, result))
+        given = "make+sure/using_unquote"
+        expect = os.path.join("make+sure", "using_unquote")
+        result = urllib.url2pathname(given)
+        self.assertEqual(expect, result,
+                         "url2pathname() failed; %s != %s" %
+                         (expect, result))
+
+
+
+def test_main():
+    test_support.run_unittest(
+        urlopen_FileTests,
+        urlopen_HttpTests,
+        urlretrieve_FileTests,
+        QuotingTests,
+        UnquotingTests,
+        urlencode_Tests,
+        Pathname_Tests
+    )
+
+
+
+if __name__ == '__main__':
+    test_main()

Added: vendor/Python/current/Lib/test/test_urllib2.py
===================================================================
--- vendor/Python/current/Lib/test/test_urllib2.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_urllib2.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1054 @@
+import unittest
+from test import test_support
+
+import os, socket
+import StringIO
+
+import urllib2
+from urllib2 import Request, OpenerDirector
+
+# XXX
+# Request
+# CacheFTPHandler (hard to write)
+# parse_keqv_list, parse_http_list, HTTPDigestAuthHandler
+
+class TrivialTests(unittest.TestCase):
+    def test_trivial(self):
+        # A couple trivial tests
+
+        self.assertRaises(ValueError, urllib2.urlopen, 'bogus url')
+
+        # XXX Name hacking to get this to work on Windows.
+        fname = os.path.abspath(urllib2.__file__).replace('\\', '/')
+        if fname[1:2] == ":":
+            fname = fname[2:]
+        # And more hacking to get it to work on MacOS. This assumes
+        # urllib.pathname2url works, unfortunately...
+        if os.name == 'mac':
+            fname = '/' + fname.replace(':', '/')
+        elif os.name == 'riscos':
+            import string
+            fname = os.expand(fname)
+            fname = fname.translate(string.maketrans("/.", "./"))
+
+        file_url = "file://%s" % fname
+        f = urllib2.urlopen(file_url)
+
+        buf = f.read()
+        f.close()
+
+    def test_parse_http_list(self):
+        tests = [('a,b,c', ['a', 'b', 'c']),
+                 ('path"o,l"og"i"cal, example', ['path"o,l"og"i"cal', 'example']),
+                 ('a, b, "c", "d", "e,f", g, h', ['a', 'b', '"c"', '"d"', '"e,f"', 'g', 'h']),
+                 ('a="b\\"c", d="e\\,f", g="h\\\\i"', ['a="b"c"', 'd="e,f"', 'g="h\\i"'])]
+        for string, list in tests:
+            self.assertEquals(urllib2.parse_http_list(string), list)
+
+
+def test_request_headers_dict():
+    """
+    The Request.headers dictionary is not a documented interface.  It should
+    stay that way, because the complete set of headers are only accessible
+    through the .get_header(), .has_header(), .header_items() interface.
+    However, .headers pre-dates those methods, and so real code will be using
+    the dictionary.
+
+    The introduction in 2.4 of those methods was a mistake for the same reason:
+    code that previously saw all (urllib2 user)-provided headers in .headers
+    now sees only a subset (and the function interface is ugly and incomplete).
+    A better change would have been to replace .headers dict with a dict
+    subclass (or UserDict.DictMixin instance?)  that preserved the .headers
+    interface and also provided access to the "unredirected" headers.  It's
+    probably too late to fix that, though.
+
+
+    Check .capitalize() case normalization:
+
+    >>> url = "http://example.com"
+    >>> Request(url, headers={"Spam-eggs": "blah"}).headers["Spam-eggs"]
+    'blah'
+    >>> Request(url, headers={"spam-EggS": "blah"}).headers["Spam-eggs"]
+    'blah'
+
+    Currently, Request(url, "Spam-eggs").headers["Spam-Eggs"] raises KeyError,
+    but that could be changed in future.
+
+    """
+
+def test_request_headers_methods():
+    """
+    Note the case normalization of header names here, to .capitalize()-case.
+    This should be preserved for backwards-compatibility.  (In the HTTP case,
+    normalization to .title()-case is done by urllib2 before sending headers to
+    httplib).
+
+    >>> url = "http://example.com"
+    >>> r = Request(url, headers={"Spam-eggs": "blah"})
+    >>> r.has_header("Spam-eggs")
+    True
+    >>> r.header_items()
+    [('Spam-eggs', 'blah')]
+    >>> r.add_header("Foo-Bar", "baz")
+    >>> items = r.header_items()
+    >>> items.sort()
+    >>> items
+    [('Foo-bar', 'baz'), ('Spam-eggs', 'blah')]
+
+    Note that e.g. r.has_header("spam-EggS") is currently False, and
+    r.get_header("spam-EggS") returns None, but that could be changed in
+    future.
+
+    >>> r.has_header("Not-there")
+    False
+    >>> print r.get_header("Not-there")
+    None
+    >>> r.get_header("Not-there", "default")
+    'default'
+
+    """
+
+
+def test_password_manager(self):
+    """
+    >>> mgr = urllib2.HTTPPasswordMgr()
+    >>> add = mgr.add_password
+    >>> add("Some Realm", "http://example.com/", "joe", "password")
+    >>> add("Some Realm", "http://example.com/ni", "ni", "ni")
+    >>> add("c", "http://example.com/foo", "foo", "ni")
+    >>> add("c", "http://example.com/bar", "bar", "nini")
+    >>> add("b", "http://example.com/", "first", "blah")
+    >>> add("b", "http://example.com/", "second", "spam")
+    >>> add("a", "http://example.com", "1", "a")
+    >>> add("Some Realm", "http://c.example.com:3128", "3", "c")
+    >>> add("Some Realm", "d.example.com", "4", "d")
+    >>> add("Some Realm", "e.example.com:3128", "5", "e")
+
+    >>> mgr.find_user_password("Some Realm", "example.com")
+    ('joe', 'password')
+    >>> mgr.find_user_password("Some Realm", "http://example.com")
+    ('joe', 'password')
+    >>> mgr.find_user_password("Some Realm", "http://example.com/")
+    ('joe', 'password')
+    >>> mgr.find_user_password("Some Realm", "http://example.com/spam")
+    ('joe', 'password')
+    >>> mgr.find_user_password("Some Realm", "http://example.com/spam/spam")
+    ('joe', 'password')
+    >>> mgr.find_user_password("c", "http://example.com/foo")
+    ('foo', 'ni')
+    >>> mgr.find_user_password("c", "http://example.com/bar")
+    ('bar', 'nini')
+
+    Actually, this is really undefined ATM
+##     Currently, we use the highest-level path where more than one match:
+
+##     >>> mgr.find_user_password("Some Realm", "http://example.com/ni")
+##     ('joe', 'password')
+
+    Use latest add_password() in case of conflict:
+
+    >>> mgr.find_user_password("b", "http://example.com/")
+    ('second', 'spam')
+
+    No special relationship between a.example.com and example.com:
+
+    >>> mgr.find_user_password("a", "http://example.com/")
+    ('1', 'a')
+    >>> mgr.find_user_password("a", "http://a.example.com/")
+    (None, None)
+
+    Ports:
+
+    >>> mgr.find_user_password("Some Realm", "c.example.com")
+    (None, None)
+    >>> mgr.find_user_password("Some Realm", "c.example.com:3128")
+    ('3', 'c')
+    >>> mgr.find_user_password("Some Realm", "http://c.example.com:3128")
+    ('3', 'c')
+    >>> mgr.find_user_password("Some Realm", "d.example.com")
+    ('4', 'd')
+    >>> mgr.find_user_password("Some Realm", "e.example.com:3128")
+    ('5', 'e')
+
+    """
+    pass
+
+
+def test_password_manager_default_port(self):
+    """
+    >>> mgr = urllib2.HTTPPasswordMgr()
+    >>> add = mgr.add_password
+
+    The point to note here is that we can't guess the default port if there's
+    no scheme.  This applies to both add_password and find_user_password.
+
+    >>> add("f", "http://g.example.com:80", "10", "j")
+    >>> add("g", "http://h.example.com", "11", "k")
+    >>> add("h", "i.example.com:80", "12", "l")
+    >>> add("i", "j.example.com", "13", "m")
+    >>> mgr.find_user_password("f", "g.example.com:100")
+    (None, None)
+    >>> mgr.find_user_password("f", "g.example.com:80")
+    ('10', 'j')
+    >>> mgr.find_user_password("f", "g.example.com")
+    (None, None)
+    >>> mgr.find_user_password("f", "http://g.example.com:100")
+    (None, None)
+    >>> mgr.find_user_password("f", "http://g.example.com:80")
+    ('10', 'j')
+    >>> mgr.find_user_password("f", "http://g.example.com")
+    ('10', 'j')
+    >>> mgr.find_user_password("g", "h.example.com")
+    ('11', 'k')
+    >>> mgr.find_user_password("g", "h.example.com:80")
+    ('11', 'k')
+    >>> mgr.find_user_password("g", "http://h.example.com:80")
+    ('11', 'k')
+    >>> mgr.find_user_password("h", "i.example.com")
+    (None, None)
+    >>> mgr.find_user_password("h", "i.example.com:80")
+    ('12', 'l')
+    >>> mgr.find_user_password("h", "http://i.example.com:80")
+    ('12', 'l')
+    >>> mgr.find_user_password("i", "j.example.com")
+    ('13', 'm')
+    >>> mgr.find_user_password("i", "j.example.com:80")
+    (None, None)
+    >>> mgr.find_user_password("i", "http://j.example.com")
+    ('13', 'm')
+    >>> mgr.find_user_password("i", "http://j.example.com:80")
+    (None, None)
+
+    """
+
+class MockOpener:
+    addheaders = []
+    def open(self, req, data=None):
+        self.req, self.data = req, data
+    def error(self, proto, *args):
+        self.proto, self.args = proto, args
+
+class MockFile:
+    def read(self, count=None): pass
+    def readline(self, count=None): pass
+    def close(self): pass
+
+class MockHeaders(dict):
+    def getheaders(self, name):
+        return self.values()
+
+class MockResponse(StringIO.StringIO):
+    def __init__(self, code, msg, headers, data, url=None):
+        StringIO.StringIO.__init__(self, data)
+        self.code, self.msg, self.headers, self.url = code, msg, headers, url
+    def info(self):
+        return self.headers
+    def geturl(self):
+        return self.url
+
+class MockCookieJar:
+    def add_cookie_header(self, request):
+        self.ach_req = request
+    def extract_cookies(self, response, request):
+        self.ec_req, self.ec_r = request, response
+
+class FakeMethod:
+    def __init__(self, meth_name, action, handle):
+        self.meth_name = meth_name
+        self.handle = handle
+        self.action = action
+    def __call__(self, *args):
+        return self.handle(self.meth_name, self.action, *args)
+
+class MockHandler:
+    # useful for testing handler machinery
+    # see add_ordered_mock_handlers() docstring
+    handler_order = 500
+    def __init__(self, methods):
+        self._define_methods(methods)
+    def _define_methods(self, methods):
+        for spec in methods:
+            if len(spec) == 2: name, action = spec
+            else: name, action = spec, None
+            meth = FakeMethod(name, action, self.handle)
+            setattr(self.__class__, name, meth)
+    def handle(self, fn_name, action, *args, **kwds):
+        self.parent.calls.append((self, fn_name, args, kwds))
+        if action is None:
+            return None
+        elif action == "return self":
+            return self
+        elif action == "return response":
+            res = MockResponse(200, "OK", {}, "")
+            return res
+        elif action == "return request":
+            return Request("http://blah/")
+        elif action.startswith("error"):
+            code = action[action.rfind(" ")+1:]
+            try:
+                code = int(code)
+            except ValueError:
+                pass
+            res = MockResponse(200, "OK", {}, "")
+            return self.parent.error("http", args[0], res, code, "", {})
+        elif action == "raise":
+            raise urllib2.URLError("blah")
+        assert False
+    def close(self): pass
+    def add_parent(self, parent):
+        self.parent = parent
+        self.parent.calls = []
+    def __lt__(self, other):
+        if not hasattr(other, "handler_order"):
+            # No handler_order, leave in original order.  Yuck.
+            return True
+        return self.handler_order < other.handler_order
+
+def add_ordered_mock_handlers(opener, meth_spec):
+    """Create MockHandlers and add them to an OpenerDirector.
+
+    meth_spec: list of lists of tuples and strings defining methods to define
+    on handlers.  eg:
+
+    [["http_error", "ftp_open"], ["http_open"]]
+
+    defines methods .http_error() and .ftp_open() on one handler, and
+    .http_open() on another.  These methods just record their arguments and
+    return None.  Using a tuple instead of a string causes the method to
+    perform some action (see MockHandler.handle()), eg:
+
+    [["http_error"], [("http_open", "return request")]]
+
+    defines .http_error() on one handler (which simply returns None), and
+    .http_open() on another handler, which returns a Request object.
+
+    """
+    handlers = []
+    count = 0
+    for meths in meth_spec:
+        class MockHandlerSubclass(MockHandler): pass
+        h = MockHandlerSubclass(meths)
+        h.handler_order += count
+        h.add_parent(opener)
+        count = count + 1
+        handlers.append(h)
+        opener.add_handler(h)
+    return handlers
+
+def build_test_opener(*handler_instances):
+    opener = OpenerDirector()
+    for h in handler_instances:
+        opener.add_handler(h)
+    return opener
+
+class MockHTTPHandler(urllib2.BaseHandler):
+    # useful for testing redirections and auth
+    # sends supplied headers and code as first response
+    # sends 200 OK as second response
+    def __init__(self, code, headers):
+        self.code = code
+        self.headers = headers
+        self.reset()
+    def reset(self):
+        self._count = 0
+        self.requests = []
+    def http_open(self, req):
+        import mimetools, httplib, copy
+        from StringIO import StringIO
+        self.requests.append(copy.deepcopy(req))
+        if self._count == 0:
+            self._count = self._count + 1
+            name = httplib.responses[self.code]
+            msg = mimetools.Message(StringIO(self.headers))
+            return self.parent.error(
+                "http", req, MockFile(), self.code, name, msg)
+        else:
+            self.req = req
+            msg = mimetools.Message(StringIO("\r\n\r\n"))
+            return MockResponse(200, "OK", msg, "", req.get_full_url())
+
+class MockPasswordManager:
+    def add_password(self, realm, uri, user, password):
+        self.realm = realm
+        self.url = uri
+        self.user = user
+        self.password = password
+    def find_user_password(self, realm, authuri):
+        self.target_realm = realm
+        self.target_url = authuri
+        return self.user, self.password
+
+
+class OpenerDirectorTests(unittest.TestCase):
+
+    def test_badly_named_methods(self):
+        # test work-around for three methods that accidentally follow the
+        # naming conventions for handler methods
+        # (*_open() / *_request() / *_response())
+
+        # These used to call the accidentally-named methods, causing a
+        # TypeError in real code; here, returning self from these mock
+        # methods would either cause no exception, or AttributeError.
+
+        from urllib2 import URLError
+
+        o = OpenerDirector()
+        meth_spec = [
+            [("do_open", "return self"), ("proxy_open", "return self")],
+            [("redirect_request", "return self")],
+            ]
+        handlers = add_ordered_mock_handlers(o, meth_spec)
+        o.add_handler(urllib2.UnknownHandler())
+        for scheme in "do", "proxy", "redirect":
+            self.assertRaises(URLError, o.open, scheme+"://example.com/")
+
+    def test_handled(self):
+        # handler returning non-None means no more handlers will be called
+        o = OpenerDirector()
+        meth_spec = [
+            ["http_open", "ftp_open", "http_error_302"],
+            ["ftp_open"],
+            [("http_open", "return self")],
+            [("http_open", "return self")],
+            ]
+        handlers = add_ordered_mock_handlers(o, meth_spec)
+
+        req = Request("http://example.com/")
+        r = o.open(req)
+        # Second .http_open() gets called, third doesn't, since second returned
+        # non-None.  Handlers without .http_open() never get any methods called
+        # on them.
+        # In fact, second mock handler defining .http_open() returns self
+        # (instead of response), which becomes the OpenerDirector's return
+        # value.
+        self.assertEqual(r, handlers[2])
+        calls = [(handlers[0], "http_open"), (handlers[2], "http_open")]
+        for expected, got in zip(calls, o.calls):
+            handler, name, args, kwds = got
+            self.assertEqual((handler, name), expected)
+            self.assertEqual(args, (req,))
+
+    def test_handler_order(self):
+        o = OpenerDirector()
+        handlers = []
+        for meths, handler_order in [
+            ([("http_open", "return self")], 500),
+            (["http_open"], 0),
+            ]:
+            class MockHandlerSubclass(MockHandler): pass
+            h = MockHandlerSubclass(meths)
+            h.handler_order = handler_order
+            handlers.append(h)
+            o.add_handler(h)
+
+        r = o.open("http://example.com/")
+        # handlers called in reverse order, thanks to their sort order
+        self.assertEqual(o.calls[0][0], handlers[1])
+        self.assertEqual(o.calls[1][0], handlers[0])
+
+    def test_raise(self):
+        # raising URLError stops processing of request
+        o = OpenerDirector()
+        meth_spec = [
+            [("http_open", "raise")],
+            [("http_open", "return self")],
+            ]
+        handlers = add_ordered_mock_handlers(o, meth_spec)
+
+        req = Request("http://example.com/")
+        self.assertRaises(urllib2.URLError, o.open, req)
+        self.assertEqual(o.calls, [(handlers[0], "http_open", (req,), {})])
+
+##     def test_error(self):
+##         # XXX this doesn't actually seem to be used in standard library,
+##         #  but should really be tested anyway...
+
+    def test_http_error(self):
+        # XXX http_error_default
+        # http errors are a special case
+        o = OpenerDirector()
+        meth_spec = [
+            [("http_open", "error 302")],
+            [("http_error_400", "raise"), "http_open"],
+            [("http_error_302", "return response"), "http_error_303",
+             "http_error"],
+            [("http_error_302")],
+            ]
+        handlers = add_ordered_mock_handlers(o, meth_spec)
+
+        class Unknown:
+            def __eq__(self, other): return True
+
+        req = Request("http://example.com/")
+        r = o.open(req)
+        assert len(o.calls) == 2
+        calls = [(handlers[0], "http_open", (req,)),
+                 (handlers[2], "http_error_302",
+                  (req, Unknown(), 302, "", {}))]
+        for expected, got in zip(calls, o.calls):
+            handler, method_name, args = expected
+            self.assertEqual((handler, method_name), got[:2])
+            self.assertEqual(args, got[2])
+
+    def test_processors(self):
+        # *_request / *_response methods get called appropriately
+        o = OpenerDirector()
+        meth_spec = [
+            [("http_request", "return request"),
+             ("http_response", "return response")],
+            [("http_request", "return request"),
+             ("http_response", "return response")],
+            ]
+        handlers = add_ordered_mock_handlers(o, meth_spec)
+
+        req = Request("http://example.com/")
+        r = o.open(req)
+        # processor methods are called on *all* handlers that define them,
+        # not just the first handler that handles the request
+        calls = [
+            (handlers[0], "http_request"), (handlers[1], "http_request"),
+            (handlers[0], "http_response"), (handlers[1], "http_response")]
+
+        for i, (handler, name, args, kwds) in enumerate(o.calls):
+            if i < 2:
+                # *_request
+                self.assertEqual((handler, name), calls[i])
+                self.assertEqual(len(args), 1)
+                self.assert_(isinstance(args[0], Request))
+            else:
+                # *_response
+                self.assertEqual((handler, name), calls[i])
+                self.assertEqual(len(args), 2)
+                self.assert_(isinstance(args[0], Request))
+                # response from opener.open is None, because there's no
+                # handler that defines http_open to handle it
+                self.assert_(args[1] is None or
+                             isinstance(args[1], MockResponse))
+
+
+def sanepathname2url(path):
+    import urllib
+    urlpath = urllib.pathname2url(path)
+    if os.name == "nt" and urlpath.startswith("///"):
+        urlpath = urlpath[2:]
+    # XXX don't ask me about the mac...
+    return urlpath
+
+class HandlerTests(unittest.TestCase):
+
+    def test_ftp(self):
+        class MockFTPWrapper:
+            def __init__(self, data): self.data = data
+            def retrfile(self, filename, filetype):
+                self.filename, self.filetype = filename, filetype
+                return StringIO.StringIO(self.data), len(self.data)
+
+        class NullFTPHandler(urllib2.FTPHandler):
+            def __init__(self, data): self.data = data
+            def connect_ftp(self, user, passwd, host, port, dirs):
+                self.user, self.passwd = user, passwd
+                self.host, self.port = host, port
+                self.dirs = dirs
+                self.ftpwrapper = MockFTPWrapper(self.data)
+                return self.ftpwrapper
+
+        import ftplib, socket
+        data = "rheum rhaponicum"
+        h = NullFTPHandler(data)
+        o = h.parent = MockOpener()
+
+        for url, host, port, type_, dirs, filename, mimetype in [
+            ("ftp://localhost/foo/bar/baz.html",
+             "localhost", ftplib.FTP_PORT, "I",
+             ["foo", "bar"], "baz.html", "text/html"),
+            ("ftp://localhost:80/foo/bar/",
+             "localhost", 80, "D",
+             ["foo", "bar"], "", None),
+            ("ftp://localhost/baz.gif;type=a",
+             "localhost", ftplib.FTP_PORT, "A",
+             [], "baz.gif", None),  # XXX really this should guess image/gif
+            ]:
+            r = h.ftp_open(Request(url))
+            # ftp authentication not yet implemented by FTPHandler
+            self.assert_(h.user == h.passwd == "")
+            self.assertEqual(h.host, socket.gethostbyname(host))
+            self.assertEqual(h.port, port)
+            self.assertEqual(h.dirs, dirs)
+            self.assertEqual(h.ftpwrapper.filename, filename)
+            self.assertEqual(h.ftpwrapper.filetype, type_)
+            headers = r.info()
+            self.assertEqual(headers.get("Content-type"), mimetype)
+            self.assertEqual(int(headers["Content-length"]), len(data))
+
+    def test_file(self):
+        import time, rfc822, socket
+        h = urllib2.FileHandler()
+        o = h.parent = MockOpener()
+
+        TESTFN = test_support.TESTFN
+        urlpath = sanepathname2url(os.path.abspath(TESTFN))
+        towrite = "hello, world\n"
+        urls = [
+            "file://localhost%s" % urlpath,
+            "file://%s" % urlpath,
+            "file://%s%s" % (socket.gethostbyname('localhost'), urlpath),
+            ]
+        try:
+            localaddr = socket.gethostbyname(socket.gethostname())
+        except socket.gaierror:
+            localaddr = ''
+        if localaddr:
+            urls.append("file://%s%s" % (localaddr, urlpath))
+
+        for url in urls:
+            f = open(TESTFN, "wb")
+            try:
+                try:
+                    f.write(towrite)
+                finally:
+                    f.close()
+
+                r = h.file_open(Request(url))
+                try:
+                    data = r.read()
+                    headers = r.info()
+                    newurl = r.geturl()
+                finally:
+                    r.close()
+                stats = os.stat(TESTFN)
+                modified = rfc822.formatdate(stats.st_mtime)
+            finally:
+                os.remove(TESTFN)
+            self.assertEqual(data, towrite)
+            self.assertEqual(headers["Content-type"], "text/plain")
+            self.assertEqual(headers["Content-length"], "13")
+            self.assertEqual(headers["Last-modified"], modified)
+
+        for url in [
+            "file://localhost:80%s" % urlpath,
+# XXXX bug: these fail with socket.gaierror, should be URLError
+##             "file://%s:80%s/%s" % (socket.gethostbyname('localhost'),
+##                                    os.getcwd(), TESTFN),
+##             "file://somerandomhost.ontheinternet.com%s/%s" %
+##             (os.getcwd(), TESTFN),
+            ]:
+            try:
+                f = open(TESTFN, "wb")
+                try:
+                    f.write(towrite)
+                finally:
+                    f.close()
+
+                self.assertRaises(urllib2.URLError,
+                                  h.file_open, Request(url))
+            finally:
+                os.remove(TESTFN)
+
+        h = urllib2.FileHandler()
+        o = h.parent = MockOpener()
+        # XXXX why does // mean ftp (and /// mean not ftp!), and where
+        #  is file: scheme specified?  I think this is really a bug, and
+        #  what was intended was to distinguish between URLs like:
+        # file:/blah.txt (a file)
+        # file://localhost/blah.txt (a file)
+        # file:///blah.txt (a file)
+        # file://ftp.example.com/blah.txt (an ftp URL)
+        for url, ftp in [
+            ("file://ftp.example.com//foo.txt", True),
+            ("file://ftp.example.com///foo.txt", False),
+# XXXX bug: fails with OSError, should be URLError
+            ("file://ftp.example.com/foo.txt", False),
+            ]:
+            req = Request(url)
+            try:
+                h.file_open(req)
+            # XXXX remove OSError when bug fixed
+            except (urllib2.URLError, OSError):
+                self.assert_(not ftp)
+            else:
+                self.assert_(o.req is req)
+                self.assertEqual(req.type, "ftp")
+
+    def test_http(self):
+        class MockHTTPResponse:
+            def __init__(self, fp, msg, status, reason):
+                self.fp = fp
+                self.msg = msg
+                self.status = status
+                self.reason = reason
+            def read(self):
+                return ''
+        class MockHTTPClass:
+            def __init__(self):
+                self.req_headers = []
+                self.data = None
+                self.raise_on_endheaders = False
+            def __call__(self, host):
+                self.host = host
+                return self
+            def set_debuglevel(self, level):
+                self.level = level
+            def request(self, method, url, body=None, headers={}):
+                self.method = method
+                self.selector = url
+                self.req_headers += headers.items()
+                self.req_headers.sort()
+                if body:
+                    self.data = body
+                if self.raise_on_endheaders:
+                    import socket
+                    raise socket.error()
+            def getresponse(self):
+                return MockHTTPResponse(MockFile(), {}, 200, "OK")
+
+        h = urllib2.AbstractHTTPHandler()
+        o = h.parent = MockOpener()
+
+        url = "http://example.com/"
+        for method, data in [("GET", None), ("POST", "blah")]:
+            req = Request(url, data, {"Foo": "bar"})
+            req.add_unredirected_header("Spam", "eggs")
+            http = MockHTTPClass()
+            r = h.do_open(http, req)
+
+            # result attributes
+            r.read; r.readline  # wrapped MockFile methods
+            r.info; r.geturl  # addinfourl methods
+            r.code, r.msg == 200, "OK"  # added from MockHTTPClass.getreply()
+            hdrs = r.info()
+            hdrs.get; hdrs.has_key  # r.info() gives dict from .getreply()
+            self.assertEqual(r.geturl(), url)
+
+            self.assertEqual(http.host, "example.com")
+            self.assertEqual(http.level, 0)
+            self.assertEqual(http.method, method)
+            self.assertEqual(http.selector, "/")
+            self.assertEqual(http.req_headers,
+                             [("Connection", "close"),
+                              ("Foo", "bar"), ("Spam", "eggs")])
+            self.assertEqual(http.data, data)
+
+        # check socket.error converted to URLError
+        http.raise_on_endheaders = True
+        self.assertRaises(urllib2.URLError, h.do_open, http, req)
+
+        # check adding of standard headers
+        o.addheaders = [("Spam", "eggs")]
+        for data in "", None:  # POST, GET
+            req = Request("http://example.com/", data)
+            r = MockResponse(200, "OK", {}, "")
+            newreq = h.do_request_(req)
+            if data is None:  # GET
+                self.assert_("Content-length" not in req.unredirected_hdrs)
+                self.assert_("Content-type" not in req.unredirected_hdrs)
+            else:  # POST
+                self.assertEqual(req.unredirected_hdrs["Content-length"], "0")
+                self.assertEqual(req.unredirected_hdrs["Content-type"],
+                             "application/x-www-form-urlencoded")
+            # XXX the details of Host could be better tested
+            self.assertEqual(req.unredirected_hdrs["Host"], "example.com")
+            self.assertEqual(req.unredirected_hdrs["Spam"], "eggs")
+
+            # don't clobber existing headers
+            req.add_unredirected_header("Content-length", "foo")
+            req.add_unredirected_header("Content-type", "bar")
+            req.add_unredirected_header("Host", "baz")
+            req.add_unredirected_header("Spam", "foo")
+            newreq = h.do_request_(req)
+            self.assertEqual(req.unredirected_hdrs["Content-length"], "foo")
+            self.assertEqual(req.unredirected_hdrs["Content-type"], "bar")
+            self.assertEqual(req.unredirected_hdrs["Host"], "baz")
+            self.assertEqual(req.unredirected_hdrs["Spam"], "foo")
+
+    def test_errors(self):
+        h = urllib2.HTTPErrorProcessor()
+        o = h.parent = MockOpener()
+
+        url = "http://example.com/"
+        req = Request(url)
+        # 200 OK is passed through
+        r = MockResponse(200, "OK", {}, "", url)
+        newr = h.http_response(req, r)
+        self.assert_(r is newr)
+        self.assert_(not hasattr(o, "proto"))  # o.error not called
+        # anything else calls o.error (and MockOpener returns None, here)
+        r = MockResponse(201, "Created", {}, "", url)
+        self.assert_(h.http_response(req, r) is None)
+        self.assertEqual(o.proto, "http")  # o.error called
+        self.assertEqual(o.args, (req, r, 201, "Created", {}))
+
+    def test_cookies(self):
+        cj = MockCookieJar()
+        h = urllib2.HTTPCookieProcessor(cj)
+        o = h.parent = MockOpener()
+
+        req = Request("http://example.com/")
+        r = MockResponse(200, "OK", {}, "")
+        newreq = h.http_request(req)
+        self.assert_(cj.ach_req is req is newreq)
+        self.assertEquals(req.get_origin_req_host(), "example.com")
+        self.assert_(not req.is_unverifiable())
+        newr = h.http_response(req, r)
+        self.assert_(cj.ec_req is req)
+        self.assert_(cj.ec_r is r is newr)
+
+    def test_redirect(self):
+        from_url = "http://example.com/a.html"
+        to_url = "http://example.com/b.html"
+        h = urllib2.HTTPRedirectHandler()
+        o = h.parent = MockOpener()
+
+        # ordinary redirect behaviour
+        for code in 301, 302, 303, 307:
+            for data in None, "blah\nblah\n":
+                method = getattr(h, "http_error_%s" % code)
+                req = Request(from_url, data)
+                req.add_header("Nonsense", "viking=withhold")
+                req.add_unredirected_header("Spam", "spam")
+                try:
+                    method(req, MockFile(), code, "Blah",
+                           MockHeaders({"location": to_url}))
+                except urllib2.HTTPError:
+                    # 307 in response to POST requires user OK
+                    self.assert_(code == 307 and data is not None)
+                self.assertEqual(o.req.get_full_url(), to_url)
+                try:
+                    self.assertEqual(o.req.get_method(), "GET")
+                except AttributeError:
+                    self.assert_(not o.req.has_data())
+                self.assertEqual(o.req.headers["Nonsense"],
+                                 "viking=withhold")
+                self.assert_("Spam" not in o.req.headers)
+                self.assert_("Spam" not in o.req.unredirected_hdrs)
+
+        # loop detection
+        req = Request(from_url)
+        def redirect(h, req, url=to_url):
+            h.http_error_302(req, MockFile(), 302, "Blah",
+                             MockHeaders({"location": url}))
+        # Note that the *original* request shares the same record of
+        # redirections with the sub-requests caused by the redirections.
+
+        # detect infinite loop redirect of a URL to itself
+        req = Request(from_url, origin_req_host="example.com")
+        count = 0
+        try:
+            while 1:
+                redirect(h, req, "http://example.com/")
+                count = count + 1
+        except urllib2.HTTPError:
+            # don't stop until max_repeats, because cookies may introduce state
+            self.assertEqual(count, urllib2.HTTPRedirectHandler.max_repeats)
+
+        # detect endless non-repeating chain of redirects
+        req = Request(from_url, origin_req_host="example.com")
+        count = 0
+        try:
+            while 1:
+                redirect(h, req, "http://example.com/%d" % count)
+                count = count + 1
+        except urllib2.HTTPError:
+            self.assertEqual(count,
+                             urllib2.HTTPRedirectHandler.max_redirections)
+
+    def test_cookie_redirect(self):
+        # cookies shouldn't leak into redirected requests
+        from cookielib import CookieJar
+
+        from test.test_cookielib import interact_netscape
+
+        cj = CookieJar()
+        interact_netscape(cj, "http://www.example.com/", "spam=eggs")
+        hh = MockHTTPHandler(302, "Location: http://www.cracker.com/\r\n\r\n")
+        hdeh = urllib2.HTTPDefaultErrorHandler()
+        hrh = urllib2.HTTPRedirectHandler()
+        cp = urllib2.HTTPCookieProcessor(cj)
+        o = build_test_opener(hh, hdeh, hrh, cp)
+        o.open("http://www.example.com/")
+        self.assert_(not hh.req.has_header("Cookie"))
+
+    def test_proxy(self):
+        o = OpenerDirector()
+        ph = urllib2.ProxyHandler(dict(http="proxy.example.com:3128"))
+        o.add_handler(ph)
+        meth_spec = [
+            [("http_open", "return response")]
+            ]
+        handlers = add_ordered_mock_handlers(o, meth_spec)
+
+        req = Request("http://acme.example.com/")
+        self.assertEqual(req.get_host(), "acme.example.com")
+        r = o.open(req)
+        self.assertEqual(req.get_host(), "proxy.example.com:3128")
+
+        self.assertEqual([(handlers[0], "http_open")],
+                         [tup[0:2] for tup in o.calls])
+
+    def test_basic_auth(self):
+        opener = OpenerDirector()
+        password_manager = MockPasswordManager()
+        auth_handler = urllib2.HTTPBasicAuthHandler(password_manager)
+        realm = "ACME Widget Store"
+        http_handler = MockHTTPHandler(
+            401, 'WWW-Authenticate: Basic realm="%s"\r\n\r\n' % realm)
+        opener.add_handler(auth_handler)
+        opener.add_handler(http_handler)
+        self._test_basic_auth(opener, auth_handler, "Authorization",
+                              realm, http_handler, password_manager,
+                              "http://acme.example.com/protected",
+                              "http://acme.example.com/protected",
+                              )
+
+    def test_proxy_basic_auth(self):
+        opener = OpenerDirector()
+        ph = urllib2.ProxyHandler(dict(http="proxy.example.com:3128"))
+        opener.add_handler(ph)
+        password_manager = MockPasswordManager()
+        auth_handler = urllib2.ProxyBasicAuthHandler(password_manager)
+        realm = "ACME Networks"
+        http_handler = MockHTTPHandler(
+            407, 'Proxy-Authenticate: Basic realm="%s"\r\n\r\n' % realm)
+        opener.add_handler(auth_handler)
+        opener.add_handler(http_handler)
+        self._test_basic_auth(opener, auth_handler, "Proxy-authorization",
+                              realm, http_handler, password_manager,
+                              "http://acme.example.com:3128/protected",
+                              "proxy.example.com:3128",
+                              )
+
+    def test_basic_and_digest_auth_handlers(self):
+        # HTTPDigestAuthHandler threw an exception if it couldn't handle a 40*
+        # response (http://python.org/sf/1479302), where it should instead
+        # return None to allow another handler (especially
+        # HTTPBasicAuthHandler) to handle the response.
+
+        # Also (http://python.org/sf/14797027, RFC 2617 section 1.2), we must
+        # try digest first (since it's the strongest auth scheme), so we record
+        # order of calls here to check digest comes first:
+        class RecordingOpenerDirector(OpenerDirector):
+            def __init__(self):
+                OpenerDirector.__init__(self)
+                self.recorded = []
+            def record(self, info):
+                self.recorded.append(info)
+        class TestDigestAuthHandler(urllib2.HTTPDigestAuthHandler):
+            def http_error_401(self, *args, **kwds):
+                self.parent.record("digest")
+                urllib2.HTTPDigestAuthHandler.http_error_401(self,
+                                                             *args, **kwds)
+        class TestBasicAuthHandler(urllib2.HTTPBasicAuthHandler):
+            def http_error_401(self, *args, **kwds):
+                self.parent.record("basic")
+                urllib2.HTTPBasicAuthHandler.http_error_401(self,
+                                                            *args, **kwds)
+
+        opener = RecordingOpenerDirector()
+        password_manager = MockPasswordManager()
+        digest_handler = TestDigestAuthHandler(password_manager)
+        basic_handler = TestBasicAuthHandler(password_manager)
+        realm = "ACME Networks"
+        http_handler = MockHTTPHandler(
+            401, 'WWW-Authenticate: Basic realm="%s"\r\n\r\n' % realm)
+        opener.add_handler(basic_handler)
+        opener.add_handler(digest_handler)
+        opener.add_handler(http_handler)
+
+        # check basic auth isn't blocked by digest handler failing
+        self._test_basic_auth(opener, basic_handler, "Authorization",
+                              realm, http_handler, password_manager,
+                              "http://acme.example.com/protected",
+                              "http://acme.example.com/protected",
+                              )
+        # check digest was tried before basic (twice, because
+        # _test_basic_auth called .open() twice)
+        self.assertEqual(opener.recorded, ["digest", "basic"]*2)
+
+    def _test_basic_auth(self, opener, auth_handler, auth_header,
+                         realm, http_handler, password_manager,
+                         request_url, protected_url):
+        import base64, httplib
+        user, password = "wile", "coyote"
+
+        # .add_password() fed through to password manager
+        auth_handler.add_password(realm, request_url, user, password)
+        self.assertEqual(realm, password_manager.realm)
+        self.assertEqual(request_url, password_manager.url)
+        self.assertEqual(user, password_manager.user)
+        self.assertEqual(password, password_manager.password)
+
+        r = opener.open(request_url)
+
+        # should have asked the password manager for the username/password
+        self.assertEqual(password_manager.target_realm, realm)
+        self.assertEqual(password_manager.target_url, protected_url)
+
+        # expect one request without authorization, then one with
+        self.assertEqual(len(http_handler.requests), 2)
+        self.assertFalse(http_handler.requests[0].has_header(auth_header))
+        userpass = '%s:%s' % (user, password)
+        auth_hdr_value = 'Basic '+base64.encodestring(userpass).strip()
+        self.assertEqual(http_handler.requests[1].get_header(auth_header),
+                         auth_hdr_value)
+
+        # if the password manager can't find a password, the handler won't
+        # handle the HTTP auth error
+        password_manager.user = password_manager.password = None
+        http_handler.reset()
+        r = opener.open(request_url)
+        self.assertEqual(len(http_handler.requests), 1)
+        self.assertFalse(http_handler.requests[0].has_header(auth_header))
+
+
+class MiscTests(unittest.TestCase):
+
+    def test_build_opener(self):
+        class MyHTTPHandler(urllib2.HTTPHandler): pass
+        class FooHandler(urllib2.BaseHandler):
+            def foo_open(self): pass
+        class BarHandler(urllib2.BaseHandler):
+            def bar_open(self): pass
+
+        build_opener = urllib2.build_opener
+
+        o = build_opener(FooHandler, BarHandler)
+        self.opener_has_handler(o, FooHandler)
+        self.opener_has_handler(o, BarHandler)
+
+        # can take a mix of classes and instances
+        o = build_opener(FooHandler, BarHandler())
+        self.opener_has_handler(o, FooHandler)
+        self.opener_has_handler(o, BarHandler)
+
+        # subclasses of default handlers override default handlers
+        o = build_opener(MyHTTPHandler)
+        self.opener_has_handler(o, MyHTTPHandler)
+
+        # a particular case of overriding: default handlers can be passed
+        # in explicitly
+        o = build_opener()
+        self.opener_has_handler(o, urllib2.HTTPHandler)
+        o = build_opener(urllib2.HTTPHandler)
+        self.opener_has_handler(o, urllib2.HTTPHandler)
+        o = build_opener(urllib2.HTTPHandler())
+        self.opener_has_handler(o, urllib2.HTTPHandler)
+
+    def opener_has_handler(self, opener, handler_class):
+        for h in opener.handlers:
+            if h.__class__ == handler_class:
+                break
+        else:
+            self.assert_(False)
+
+
+def test_main(verbose=None):
+    from test import test_urllib2
+    test_support.run_doctest(test_urllib2, verbose)
+    test_support.run_doctest(urllib2, verbose)
+    tests = (TrivialTests,
+             OpenerDirectorTests,
+             HandlerTests,
+             MiscTests)
+    test_support.run_unittest(*tests)
+
+if __name__ == "__main__":
+    test_main(verbose=True)

Added: vendor/Python/current/Lib/test/test_urllib2net.py
===================================================================
--- vendor/Python/current/Lib/test/test_urllib2net.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_urllib2net.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,295 @@
+#!/usr/bin/env python
+
+import unittest
+from test import test_support
+from test.test_urllib2 import sanepathname2url
+
+import socket
+import urllib2
+import sys
+import os
+import mimetools
+
+class URLTimeoutTest(unittest.TestCase):
+
+    TIMEOUT = 10.0
+
+    def setUp(self):
+        socket.setdefaulttimeout(self.TIMEOUT)
+
+    def tearDown(self):
+        socket.setdefaulttimeout(None)
+
+    def testURLread(self):
+        f = urllib2.urlopen("http://www.python.org/")
+        x = f.read()
+
+
+class AuthTests(unittest.TestCase):
+    """Tests urllib2 authentication features."""
+
+## Disabled at the moment since there is no page under python.org which
+## could be used to HTTP authentication.
+#
+#    def test_basic_auth(self):
+#        import httplib
+#
+#        test_url = "http://www.python.org/test/test_urllib2/basic_auth"
+#        test_hostport = "www.python.org"
+#        test_realm = 'Test Realm'
+#        test_user = 'test.test_urllib2net'
+#        test_password = 'blah'
+#
+#        # failure
+#        try:
+#            urllib2.urlopen(test_url)
+#        except urllib2.HTTPError, exc:
+#            self.assertEqual(exc.code, 401)
+#        else:
+#            self.fail("urlopen() should have failed with 401")
+#
+#        # success
+#        auth_handler = urllib2.HTTPBasicAuthHandler()
+#        auth_handler.add_password(test_realm, test_hostport,
+#                                  test_user, test_password)
+#        opener = urllib2.build_opener(auth_handler)
+#        f = opener.open('http://localhost/')
+#        response = urllib2.urlopen("http://www.python.org/")
+#
+#        # The 'userinfo' URL component is deprecated by RFC 3986 for security
+#        # reasons, let's not implement it!  (it's already implemented for proxy
+#        # specification strings (that is, URLs or authorities specifying a
+#        # proxy), so we must keep that)
+#        self.assertRaises(httplib.InvalidURL,
+#                          urllib2.urlopen, "http://evil:thing@example.com")
+
+
+class CloseSocketTest(unittest.TestCase):
+
+    def test_close(self):
+        import socket, httplib, gc
+
+        # calling .close() on urllib2's response objects should close the
+        # underlying socket
+
+        # delve deep into response to fetch socket._socketobject
+        response = urllib2.urlopen("http://www.python.org/")
+        abused_fileobject = response.fp
+        self.assert_(abused_fileobject.__class__ is socket._fileobject)
+        httpresponse = abused_fileobject._sock
+        self.assert_(httpresponse.__class__ is httplib.HTTPResponse)
+        fileobject = httpresponse.fp
+        self.assert_(fileobject.__class__ is socket._fileobject)
+
+        self.assert_(not fileobject.closed)
+        response.close()
+        self.assert_(fileobject.closed)
+
+class urlopenNetworkTests(unittest.TestCase):
+    """Tests urllib2.urlopen using the network.
+
+    These tests are not exhaustive.  Assuming that testing using files does a
+    good job overall of some of the basic interface features.  There are no
+    tests exercising the optional 'data' and 'proxies' arguments.  No tests
+    for transparent redirection have been written.
+
+    setUp is not used for always constructing a connection to
+    http://www.python.org/ since there a few tests that don't use that address
+    and making a connection is expensive enough to warrant minimizing unneeded
+    connections.
+
+    """
+
+    def test_basic(self):
+        # Simple test expected to pass.
+        open_url = urllib2.urlopen("http://www.python.org/")
+        for attr in ("read", "close", "info", "geturl"):
+            self.assert_(hasattr(open_url, attr), "object returned from "
+                            "urlopen lacks the %s attribute" % attr)
+        try:
+            self.assert_(open_url.read(), "calling 'read' failed")
+        finally:
+            open_url.close()
+
+    def test_info(self):
+        # Test 'info'.
+        open_url = urllib2.urlopen("http://www.python.org/")
+        try:
+            info_obj = open_url.info()
+        finally:
+            open_url.close()
+            self.assert_(isinstance(info_obj, mimetools.Message),
+                         "object returned by 'info' is not an instance of "
+                         "mimetools.Message")
+            self.assertEqual(info_obj.getsubtype(), "html")
+
+    def test_geturl(self):
+        # Make sure same URL as opened is returned by geturl.
+        URL = "http://www.python.org/"
+        open_url = urllib2.urlopen(URL)
+        try:
+            gotten_url = open_url.geturl()
+        finally:
+            open_url.close()
+        self.assertEqual(gotten_url, URL)
+
+    def test_bad_address(self):
+        # Make sure proper exception is raised when connecting to a bogus
+        # address.
+        self.assertRaises(IOError,
+                          # SF patch 809915:  In Sep 2003, VeriSign started
+                          # highjacking invalid .com and .net addresses to
+                          # boost traffic to their own site.  This test
+                          # started failing then.  One hopes the .invalid
+                          # domain will be spared to serve its defined
+                          # purpose.
+                          # urllib2.urlopen, "http://www.sadflkjsasadf.com/")
+                          urllib2.urlopen, "http://www.python.invalid./")
+
+
+class OtherNetworkTests(unittest.TestCase):
+    def setUp(self):
+        if 0:  # for debugging
+            import logging
+            logger = logging.getLogger("test_urllib2net")
+            logger.addHandler(logging.StreamHandler())
+
+    def test_range (self):
+        req = urllib2.Request("http://www.python.org",
+                              headers={'Range': 'bytes=20-39'})
+        result = urllib2.urlopen(req)
+        data = result.read()
+        self.assertEqual(len(data), 20)
+
+    # XXX The rest of these tests aren't very good -- they don't check much.
+    # They do sometimes catch some major disasters, though.
+
+    def test_ftp(self):
+        urls = [
+            'ftp://www.python.org/pub/python/misc/sousa.au',
+            'ftp://www.python.org/pub/tmp/blat',
+            'ftp://gatekeeper.research.compaq.com/pub/DEC/SRC'
+                '/research-reports/00README-Legal-Rules-Regs',
+            ]
+        self._test_urls(urls, self._extra_handlers())
+
+    def test_gopher(self):
+        import warnings
+        warnings.filterwarnings("ignore",
+                                "the gopherlib module is deprecated",
+                                DeprecationWarning,
+                                "urllib2$")
+        urls = [
+            # Thanks to Fred for finding these!
+            'gopher://gopher.lib.ncsu.edu./11/library/stacks/Alex',
+            'gopher://gopher.vt.edu.:10010/10/33',
+            ]
+        self._test_urls(urls, self._extra_handlers())
+
+    def test_file(self):
+        TESTFN = test_support.TESTFN
+        f = open(TESTFN, 'w')
+        try:
+            f.write('hi there\n')
+            f.close()
+            urls = [
+                'file:'+sanepathname2url(os.path.abspath(TESTFN)),
+
+                # XXX bug, should raise URLError
+                #('file://nonsensename/etc/passwd', None, urllib2.URLError)
+                ('file://nonsensename/etc/passwd', None, (EnvironmentError, socket.error))
+                ]
+            self._test_urls(urls, self._extra_handlers())
+        finally:
+            os.remove(TESTFN)
+
+    def test_http(self):
+        urls = [
+            'http://www.espn.com/', # redirect
+            'http://www.python.org/Spanish/Inquistion/',
+            ('http://www.python.org/cgi-bin/faqw.py',
+             'query=pythonistas&querytype=simple&casefold=yes&req=search', None),
+            'http://www.python.org/',
+            ]
+        self._test_urls(urls, self._extra_handlers())
+
+    # XXX Following test depends on machine configurations that are internal
+    # to CNRI.  Need to set up a public server with the right authentication
+    # configuration for test purposes.
+
+##     def test_cnri(self):
+##         if socket.gethostname() == 'bitdiddle':
+##             localhost = 'bitdiddle.cnri.reston.va.us'
+##         elif socket.gethostname() == 'bitdiddle.concentric.net':
+##             localhost = 'localhost'
+##         else:
+##             localhost = None
+##         if localhost is not None:
+##             urls = [
+##                 'file://%s/etc/passwd' % localhost,
+##                 'http://%s/simple/' % localhost,
+##                 'http://%s/digest/' % localhost,
+##                 'http://%s/not/found.h' % localhost,
+##                 ]
+
+##             bauth = HTTPBasicAuthHandler()
+##             bauth.add_password('basic_test_realm', localhost, 'jhylton',
+##                                'password')
+##             dauth = HTTPDigestAuthHandler()
+##             dauth.add_password('digest_test_realm', localhost, 'jhylton',
+##                                'password')
+
+##             self._test_urls(urls, self._extra_handlers()+[bauth, dauth])
+
+    def _test_urls(self, urls, handlers):
+        import socket
+        import time
+        import logging
+        debug = logging.getLogger("test_urllib2").debug
+
+        urllib2.install_opener(urllib2.build_opener(*handlers))
+
+        for url in urls:
+            if isinstance(url, tuple):
+                url, req, expected_err = url
+            else:
+                req = expected_err = None
+            debug(url)
+            try:
+                f = urllib2.urlopen(url, req)
+            except (IOError, socket.error, OSError), err:
+                debug(err)
+                if expected_err:
+                    msg = ("Didn't get expected error(s) %s for %s %s, got %s" %
+                           (expected_err, url, req, err))
+                    self.assert_(isinstance(err, expected_err), msg)
+            else:
+                buf = f.read()
+                f.close()
+                debug("read %d bytes" % len(buf))
+            debug("******** next url coming up...")
+            time.sleep(0.1)
+
+    def _extra_handlers(self):
+        handlers = []
+
+        handlers.append(urllib2.GopherHandler)
+
+        cfh = urllib2.CacheFTPHandler()
+        cfh.setTimeout(1)
+        handlers.append(cfh)
+
+        return handlers
+
+
+def test_main():
+    test_support.requires("network")
+    test_support.run_unittest(URLTimeoutTest,
+                              urlopenNetworkTests,
+                              AuthTests,
+                              OtherNetworkTests,
+                              CloseSocketTest,
+                              )
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_urllibnet.py
===================================================================
--- vendor/Python/current/Lib/test/test_urllibnet.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_urllibnet.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,160 @@
+#!/usr/bin/env python
+
+import unittest
+from test import test_support
+
+import socket
+import urllib
+import sys
+import os
+import mimetools
+
+class URLTimeoutTest(unittest.TestCase):
+
+    TIMEOUT = 10.0
+
+    def setUp(self):
+        socket.setdefaulttimeout(self.TIMEOUT)
+
+    def tearDown(self):
+        socket.setdefaulttimeout(None)
+
+    def testURLread(self):
+        f = urllib.urlopen("http://www.python.org/")
+        x = f.read()
+
+class urlopenNetworkTests(unittest.TestCase):
+    """Tests urllib.urlopen using the network.
+
+    These tests are not exhaustive.  Assuming that testing using files does a
+    good job overall of some of the basic interface features.  There are no
+    tests exercising the optional 'data' and 'proxies' arguments.  No tests
+    for transparent redirection have been written.
+
+    setUp is not used for always constructing a connection to
+    http://www.python.org/ since there a few tests that don't use that address
+    and making a connection is expensive enough to warrant minimizing unneeded
+    connections.
+
+    """
+
+    def test_basic(self):
+        # Simple test expected to pass.
+        open_url = urllib.urlopen("http://www.python.org/")
+        for attr in ("read", "readline", "readlines", "fileno", "close",
+                     "info", "geturl"):
+            self.assert_(hasattr(open_url, attr), "object returned from "
+                            "urlopen lacks the %s attribute" % attr)
+        try:
+            self.assert_(open_url.read(), "calling 'read' failed")
+        finally:
+            open_url.close()
+
+    def test_readlines(self):
+        # Test both readline and readlines.
+        open_url = urllib.urlopen("http://www.python.org/")
+        try:
+            self.assert_(isinstance(open_url.readline(), basestring),
+                         "readline did not return a string")
+            self.assert_(isinstance(open_url.readlines(), list),
+                         "readlines did not return a list")
+        finally:
+            open_url.close()
+
+    def test_info(self):
+        # Test 'info'.
+        open_url = urllib.urlopen("http://www.python.org/")
+        try:
+            info_obj = open_url.info()
+        finally:
+            open_url.close()
+            self.assert_(isinstance(info_obj, mimetools.Message),
+                         "object returned by 'info' is not an instance of "
+                         "mimetools.Message")
+            self.assertEqual(info_obj.getsubtype(), "html")
+
+    def test_geturl(self):
+        # Make sure same URL as opened is returned by geturl.
+        URL = "http://www.python.org/"
+        open_url = urllib.urlopen(URL)
+        try:
+            gotten_url = open_url.geturl()
+        finally:
+            open_url.close()
+        self.assertEqual(gotten_url, URL)
+
+    def test_fileno(self):
+        if (sys.platform in ('win32',) or
+                not hasattr(os, 'fdopen')):
+            # On Windows, socket handles are not file descriptors; this
+            # test can't pass on Windows.
+            return
+        # Make sure fd returned by fileno is valid.
+        open_url = urllib.urlopen("http://www.python.org/")
+        fd = open_url.fileno()
+        FILE = os.fdopen(fd)
+        try:
+            self.assert_(FILE.read(), "reading from file created using fd "
+                                      "returned by fileno failed")
+        finally:
+            FILE.close()
+
+    def test_bad_address(self):
+        # Make sure proper exception is raised when connecting to a bogus
+        # address.
+        self.assertRaises(IOError,
+                          # SF patch 809915:  In Sep 2003, VeriSign started
+                          # highjacking invalid .com and .net addresses to
+                          # boost traffic to their own site.  This test
+                          # started failing then.  One hopes the .invalid
+                          # domain will be spared to serve its defined
+                          # purpose.
+                          # urllib.urlopen, "http://www.sadflkjsasadf.com/")
+                          urllib.urlopen, "http://www.python.invalid./")
+
+class urlretrieveNetworkTests(unittest.TestCase):
+    """Tests urllib.urlretrieve using the network."""
+
+    def test_basic(self):
+        # Test basic functionality.
+        file_location,info = urllib.urlretrieve("http://www.python.org/")
+        self.assert_(os.path.exists(file_location), "file location returned by"
+                        " urlretrieve is not a valid path")
+        FILE = file(file_location)
+        try:
+            self.assert_(FILE.read(), "reading from the file location returned"
+                         " by urlretrieve failed")
+        finally:
+            FILE.close()
+            os.unlink(file_location)
+
+    def test_specified_path(self):
+        # Make sure that specifying the location of the file to write to works.
+        file_location,info = urllib.urlretrieve("http://www.python.org/",
+                                                test_support.TESTFN)
+        self.assertEqual(file_location, test_support.TESTFN)
+        self.assert_(os.path.exists(file_location))
+        FILE = file(file_location)
+        try:
+            self.assert_(FILE.read(), "reading from temporary file failed")
+        finally:
+            FILE.close()
+            os.unlink(file_location)
+
+    def test_header(self):
+        # Make sure header returned as 2nd value from urlretrieve is good.
+        file_location, header = urllib.urlretrieve("http://www.python.org/")
+        os.unlink(file_location)
+        self.assert_(isinstance(header, mimetools.Message),
+                     "header is not an instance of mimetools.Message")
+
+
+
+def test_main():
+    test_support.requires('network')
+    test_support.run_unittest(URLTimeoutTest,
+                              urlopenNetworkTests,
+                              urlretrieveNetworkTests)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_urlparse.py
===================================================================
--- vendor/Python/current/Lib/test/test_urlparse.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_urlparse.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,295 @@
+#! /usr/bin/env python
+
+from test import test_support
+import unittest
+import urlparse
+
+RFC1808_BASE = "http://a/b/c/d;p?q#f"
+RFC2396_BASE = "http://a/b/c/d;p?q"
+
+class UrlParseTestCase(unittest.TestCase):
+
+    def checkRoundtrips(self, url, parsed, split):
+        result = urlparse.urlparse(url)
+        self.assertEqual(result, parsed)
+        t = (result.scheme, result.netloc, result.path,
+             result.params, result.query, result.fragment)
+        self.assertEqual(t, parsed)
+        # put it back together and it should be the same
+        result2 = urlparse.urlunparse(result)
+        self.assertEqual(result2, url)
+        self.assertEqual(result2, result.geturl())
+
+        # the result of geturl() is a fixpoint; we can always parse it
+        # again to get the same result:
+        result3 = urlparse.urlparse(result.geturl())
+        self.assertEqual(result3.geturl(), result.geturl())
+        self.assertEqual(result3,          result)
+        self.assertEqual(result3.scheme,   result.scheme)
+        self.assertEqual(result3.netloc,   result.netloc)
+        self.assertEqual(result3.path,     result.path)
+        self.assertEqual(result3.params,   result.params)
+        self.assertEqual(result3.query,    result.query)
+        self.assertEqual(result3.fragment, result.fragment)
+        self.assertEqual(result3.username, result.username)
+        self.assertEqual(result3.password, result.password)
+        self.assertEqual(result3.hostname, result.hostname)
+        self.assertEqual(result3.port,     result.port)
+
+        # check the roundtrip using urlsplit() as well
+        result = urlparse.urlsplit(url)
+        self.assertEqual(result, split)
+        t = (result.scheme, result.netloc, result.path,
+             result.query, result.fragment)
+        self.assertEqual(t, split)
+        result2 = urlparse.urlunsplit(result)
+        self.assertEqual(result2, url)
+        self.assertEqual(result2, result.geturl())
+
+        # check the fixpoint property of re-parsing the result of geturl()
+        result3 = urlparse.urlsplit(result.geturl())
+        self.assertEqual(result3.geturl(), result.geturl())
+        self.assertEqual(result3,          result)
+        self.assertEqual(result3.scheme,   result.scheme)
+        self.assertEqual(result3.netloc,   result.netloc)
+        self.assertEqual(result3.path,     result.path)
+        self.assertEqual(result3.query,    result.query)
+        self.assertEqual(result3.fragment, result.fragment)
+        self.assertEqual(result3.username, result.username)
+        self.assertEqual(result3.password, result.password)
+        self.assertEqual(result3.hostname, result.hostname)
+        self.assertEqual(result3.port,     result.port)
+
+    def test_roundtrips(self):
+        testcases = [
+            ('file:///tmp/junk.txt',
+             ('file', '', '/tmp/junk.txt', '', '', ''),
+             ('file', '', '/tmp/junk.txt', '', '')),
+            ('imap://mail.python.org/mbox1',
+             ('imap', 'mail.python.org', '/mbox1', '', '', ''),
+             ('imap', 'mail.python.org', '/mbox1', '', '')),
+            ('mms://wms.sys.hinet.net/cts/Drama/09006251100.asf',
+             ('mms', 'wms.sys.hinet.net', '/cts/Drama/09006251100.asf',
+              '', '', ''),
+             ('mms', 'wms.sys.hinet.net', '/cts/Drama/09006251100.asf',
+              '', '')),
+            ('svn+ssh://svn.zope.org/repos/main/ZConfig/trunk/',
+             ('svn+ssh', 'svn.zope.org', '/repos/main/ZConfig/trunk/',
+              '', '', ''),
+             ('svn+ssh', 'svn.zope.org', '/repos/main/ZConfig/trunk/',
+              '', ''))
+            ]
+        for url, parsed, split in testcases:
+            self.checkRoundtrips(url, parsed, split)
+
+    def test_http_roundtrips(self):
+        # urlparse.urlsplit treats 'http:' as an optimized special case,
+        # so we test both 'http:' and 'https:' in all the following.
+        # Three cheers for white box knowledge!
+        testcases = [
+            ('://www.python.org',
+             ('www.python.org', '', '', '', ''),
+             ('www.python.org', '', '', '')),
+            ('://www.python.org#abc',
+             ('www.python.org', '', '', '', 'abc'),
+             ('www.python.org', '', '', 'abc')),
+            ('://www.python.org?q=abc',
+             ('www.python.org', '', '', 'q=abc', ''),
+             ('www.python.org', '', 'q=abc', '')),
+            ('://www.python.org/#abc',
+             ('www.python.org', '/', '', '', 'abc'),
+             ('www.python.org', '/', '', 'abc')),
+            ('://a/b/c/d;p?q#f',
+             ('a', '/b/c/d', 'p', 'q', 'f'),
+             ('a', '/b/c/d;p', 'q', 'f')),
+            ]
+        for scheme in ('http', 'https'):
+            for url, parsed, split in testcases:
+                url = scheme + url
+                parsed = (scheme,) + parsed
+                split = (scheme,) + split
+                self.checkRoundtrips(url, parsed, split)
+
+    def checkJoin(self, base, relurl, expected):
+        self.assertEqual(urlparse.urljoin(base, relurl), expected,
+                         (base, relurl, expected))
+
+    def test_unparse_parse(self):
+        for u in ['Python', './Python']:
+            self.assertEqual(urlparse.urlunsplit(urlparse.urlsplit(u)), u)
+            self.assertEqual(urlparse.urlunparse(urlparse.urlparse(u)), u)
+
+    def test_RFC1808(self):
+        # "normal" cases from RFC 1808:
+        self.checkJoin(RFC1808_BASE, 'g:h', 'g:h')
+        self.checkJoin(RFC1808_BASE, 'g', 'http://a/b/c/g')
+        self.checkJoin(RFC1808_BASE, './g', 'http://a/b/c/g')
+        self.checkJoin(RFC1808_BASE, 'g/', 'http://a/b/c/g/')
+        self.checkJoin(RFC1808_BASE, '/g', 'http://a/g')
+        self.checkJoin(RFC1808_BASE, '//g', 'http://g')
+        self.checkJoin(RFC1808_BASE, 'g?y', 'http://a/b/c/g?y')
+        self.checkJoin(RFC1808_BASE, 'g?y/./x', 'http://a/b/c/g?y/./x')
+        self.checkJoin(RFC1808_BASE, '#s', 'http://a/b/c/d;p?q#s')
+        self.checkJoin(RFC1808_BASE, 'g#s', 'http://a/b/c/g#s')
+        self.checkJoin(RFC1808_BASE, 'g#s/./x', 'http://a/b/c/g#s/./x')
+        self.checkJoin(RFC1808_BASE, 'g?y#s', 'http://a/b/c/g?y#s')
+        self.checkJoin(RFC1808_BASE, 'g;x', 'http://a/b/c/g;x')
+        self.checkJoin(RFC1808_BASE, 'g;x?y#s', 'http://a/b/c/g;x?y#s')
+        self.checkJoin(RFC1808_BASE, '.', 'http://a/b/c/')
+        self.checkJoin(RFC1808_BASE, './', 'http://a/b/c/')
+        self.checkJoin(RFC1808_BASE, '..', 'http://a/b/')
+        self.checkJoin(RFC1808_BASE, '../', 'http://a/b/')
+        self.checkJoin(RFC1808_BASE, '../g', 'http://a/b/g')
+        self.checkJoin(RFC1808_BASE, '../..', 'http://a/')
+        self.checkJoin(RFC1808_BASE, '../../', 'http://a/')
+        self.checkJoin(RFC1808_BASE, '../../g', 'http://a/g')
+
+        # "abnormal" cases from RFC 1808:
+        self.checkJoin(RFC1808_BASE, '', 'http://a/b/c/d;p?q#f')
+        self.checkJoin(RFC1808_BASE, '../../../g', 'http://a/../g')
+        self.checkJoin(RFC1808_BASE, '../../../../g', 'http://a/../../g')
+        self.checkJoin(RFC1808_BASE, '/./g', 'http://a/./g')
+        self.checkJoin(RFC1808_BASE, '/../g', 'http://a/../g')
+        self.checkJoin(RFC1808_BASE, 'g.', 'http://a/b/c/g.')
+        self.checkJoin(RFC1808_BASE, '.g', 'http://a/b/c/.g')
+        self.checkJoin(RFC1808_BASE, 'g..', 'http://a/b/c/g..')
+        self.checkJoin(RFC1808_BASE, '..g', 'http://a/b/c/..g')
+        self.checkJoin(RFC1808_BASE, './../g', 'http://a/b/g')
+        self.checkJoin(RFC1808_BASE, './g/.', 'http://a/b/c/g/')
+        self.checkJoin(RFC1808_BASE, 'g/./h', 'http://a/b/c/g/h')
+        self.checkJoin(RFC1808_BASE, 'g/../h', 'http://a/b/c/h')
+
+        # RFC 1808 and RFC 1630 disagree on these (according to RFC 1808),
+        # so we'll not actually run these tests (which expect 1808 behavior).
+        #self.checkJoin(RFC1808_BASE, 'http:g', 'http:g')
+        #self.checkJoin(RFC1808_BASE, 'http:', 'http:')
+
+    def test_RFC2396(self):
+        # cases from RFC 2396
+
+        self.checkJoin(RFC2396_BASE, '?y', 'http://a/b/c/?y')
+        self.checkJoin(RFC2396_BASE, ';x', 'http://a/b/c/;x')
+
+        self.checkJoin(RFC2396_BASE, 'g:h', 'g:h')
+        self.checkJoin(RFC2396_BASE, 'g', 'http://a/b/c/g')
+        self.checkJoin(RFC2396_BASE, './g', 'http://a/b/c/g')
+        self.checkJoin(RFC2396_BASE, 'g/', 'http://a/b/c/g/')
+        self.checkJoin(RFC2396_BASE, '/g', 'http://a/g')
+        self.checkJoin(RFC2396_BASE, '//g', 'http://g')
+        self.checkJoin(RFC2396_BASE, 'g?y', 'http://a/b/c/g?y')
+        self.checkJoin(RFC2396_BASE, '#s', 'http://a/b/c/d;p?q#s')
+        self.checkJoin(RFC2396_BASE, 'g#s', 'http://a/b/c/g#s')
+        self.checkJoin(RFC2396_BASE, 'g?y#s', 'http://a/b/c/g?y#s')
+        self.checkJoin(RFC2396_BASE, 'g;x', 'http://a/b/c/g;x')
+        self.checkJoin(RFC2396_BASE, 'g;x?y#s', 'http://a/b/c/g;x?y#s')
+        self.checkJoin(RFC2396_BASE, '.', 'http://a/b/c/')
+        self.checkJoin(RFC2396_BASE, './', 'http://a/b/c/')
+        self.checkJoin(RFC2396_BASE, '..', 'http://a/b/')
+        self.checkJoin(RFC2396_BASE, '../', 'http://a/b/')
+        self.checkJoin(RFC2396_BASE, '../g', 'http://a/b/g')
+        self.checkJoin(RFC2396_BASE, '../..', 'http://a/')
+        self.checkJoin(RFC2396_BASE, '../../', 'http://a/')
+        self.checkJoin(RFC2396_BASE, '../../g', 'http://a/g')
+        self.checkJoin(RFC2396_BASE, '', RFC2396_BASE)
+        self.checkJoin(RFC2396_BASE, '../../../g', 'http://a/../g')
+        self.checkJoin(RFC2396_BASE, '../../../../g', 'http://a/../../g')
+        self.checkJoin(RFC2396_BASE, '/./g', 'http://a/./g')
+        self.checkJoin(RFC2396_BASE, '/../g', 'http://a/../g')
+        self.checkJoin(RFC2396_BASE, 'g.', 'http://a/b/c/g.')
+        self.checkJoin(RFC2396_BASE, '.g', 'http://a/b/c/.g')
+        self.checkJoin(RFC2396_BASE, 'g..', 'http://a/b/c/g..')
+        self.checkJoin(RFC2396_BASE, '..g', 'http://a/b/c/..g')
+        self.checkJoin(RFC2396_BASE, './../g', 'http://a/b/g')
+        self.checkJoin(RFC2396_BASE, './g/.', 'http://a/b/c/g/')
+        self.checkJoin(RFC2396_BASE, 'g/./h', 'http://a/b/c/g/h')
+        self.checkJoin(RFC2396_BASE, 'g/../h', 'http://a/b/c/h')
+        self.checkJoin(RFC2396_BASE, 'g;x=1/./y', 'http://a/b/c/g;x=1/y')
+        self.checkJoin(RFC2396_BASE, 'g;x=1/../y', 'http://a/b/c/y')
+        self.checkJoin(RFC2396_BASE, 'g?y/./x', 'http://a/b/c/g?y/./x')
+        self.checkJoin(RFC2396_BASE, 'g?y/../x', 'http://a/b/c/g?y/../x')
+        self.checkJoin(RFC2396_BASE, 'g#s/./x', 'http://a/b/c/g#s/./x')
+        self.checkJoin(RFC2396_BASE, 'g#s/../x', 'http://a/b/c/g#s/../x')
+
+    def test_urldefrag(self):
+        for url, defrag, frag in [
+            ('http://python.org#frag', 'http://python.org', 'frag'),
+            ('http://python.org', 'http://python.org', ''),
+            ('http://python.org/#frag', 'http://python.org/', 'frag'),
+            ('http://python.org/', 'http://python.org/', ''),
+            ('http://python.org/?q#frag', 'http://python.org/?q', 'frag'),
+            ('http://python.org/?q', 'http://python.org/?q', ''),
+            ('http://python.org/p#frag', 'http://python.org/p', 'frag'),
+            ('http://python.org/p?q', 'http://python.org/p?q', ''),
+            (RFC1808_BASE, 'http://a/b/c/d;p?q', 'f'),
+            (RFC2396_BASE, 'http://a/b/c/d;p?q', ''),
+            ]:
+            self.assertEqual(urlparse.urldefrag(url), (defrag, frag))
+
+    def test_urlsplit_attributes(self):
+        url = "HTTP://WWW.PYTHON.ORG/doc/#frag"
+        p = urlparse.urlsplit(url)
+        self.assertEqual(p.scheme, "http")
+        self.assertEqual(p.netloc, "WWW.PYTHON.ORG")
+        self.assertEqual(p.path, "/doc/")
+        self.assertEqual(p.query, "")
+        self.assertEqual(p.fragment, "frag")
+        self.assertEqual(p.username, None)
+        self.assertEqual(p.password, None)
+        self.assertEqual(p.hostname, "www.python.org")
+        self.assertEqual(p.port, None)
+        # geturl() won't return exactly the original URL in this case
+        # since the scheme is always case-normalized
+        #self.assertEqual(p.geturl(), url)
+
+        url = "http://User:Pass@www.python.org:080/doc/?query=yes#frag"
+        p = urlparse.urlsplit(url)
+        self.assertEqual(p.scheme, "http")
+        self.assertEqual(p.netloc, "User:Pass at www.python.org:080")
+        self.assertEqual(p.path, "/doc/")
+        self.assertEqual(p.query, "query=yes")
+        self.assertEqual(p.fragment, "frag")
+        self.assertEqual(p.username, "User")
+        self.assertEqual(p.password, "Pass")
+        self.assertEqual(p.hostname, "www.python.org")
+        self.assertEqual(p.port, 80)
+        self.assertEqual(p.geturl(), url)
+
+    def test_attributes_bad_port(self):
+        """Check handling of non-integer ports."""
+        p = urlparse.urlsplit("http://www.example.net:foo")
+        self.assertEqual(p.netloc, "www.example.net:foo")
+        self.assertRaises(ValueError, lambda: p.port)
+
+        p = urlparse.urlparse("http://www.example.net:foo")
+        self.assertEqual(p.netloc, "www.example.net:foo")
+        self.assertRaises(ValueError, lambda: p.port)
+
+    def test_attributes_without_netloc(self):
+        # This example is straight from RFC 3261.  It looks like it
+        # should allow the username, hostname, and port to be filled
+        # in, but doesn't.  Since it's a URI and doesn't use the
+        # scheme://netloc syntax, the netloc and related attributes
+        # should be left empty.
+        uri = "sip:alice at atlanta.com;maddr=239.255.255.1;ttl=15"
+        p = urlparse.urlsplit(uri)
+        self.assertEqual(p.netloc, "")
+        self.assertEqual(p.username, None)
+        self.assertEqual(p.password, None)
+        self.assertEqual(p.hostname, None)
+        self.assertEqual(p.port, None)
+        self.assertEqual(p.geturl(), uri)
+
+        p = urlparse.urlparse(uri)
+        self.assertEqual(p.netloc, "")
+        self.assertEqual(p.username, None)
+        self.assertEqual(p.password, None)
+        self.assertEqual(p.hostname, None)
+        self.assertEqual(p.port, None)
+        self.assertEqual(p.geturl(), uri)
+
+
+def test_main():
+    test_support.run_unittest(UrlParseTestCase)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_userdict.py
===================================================================
--- vendor/Python/current/Lib/test/test_userdict.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_userdict.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,350 @@
+# Check every path through every method of UserDict
+
+import unittest
+from test import test_support, mapping_tests
+import UserDict
+
+d0 = {}
+d1 = {"one": 1}
+d2 = {"one": 1, "two": 2}
+d3 = {"one": 1, "two": 3, "three": 5}
+d4 = {"one": None, "two": None}
+d5 = {"one": 1, "two": 1}
+
+class UserDictTest(mapping_tests.TestHashMappingProtocol):
+    type2test = UserDict.IterableUserDict
+
+    def test_all(self):
+        # Test constructors
+        u = UserDict.UserDict()
+        u0 = UserDict.UserDict(d0)
+        u1 = UserDict.UserDict(d1)
+        u2 = UserDict.IterableUserDict(d2)
+
+        uu = UserDict.UserDict(u)
+        uu0 = UserDict.UserDict(u0)
+        uu1 = UserDict.UserDict(u1)
+        uu2 = UserDict.UserDict(u2)
+
+        # keyword arg constructor
+        self.assertEqual(UserDict.UserDict(one=1, two=2), d2)
+        # item sequence constructor
+        self.assertEqual(UserDict.UserDict([('one',1), ('two',2)]), d2)
+        self.assertEqual(UserDict.UserDict(dict=[('one',1), ('two',2)]), d2)
+        # both together
+        self.assertEqual(UserDict.UserDict([('one',1), ('two',2)], two=3, three=5), d3)
+
+        # alternate constructor
+        self.assertEqual(UserDict.UserDict.fromkeys('one two'.split()), d4)
+        self.assertEqual(UserDict.UserDict().fromkeys('one two'.split()), d4)
+        self.assertEqual(UserDict.UserDict.fromkeys('one two'.split(), 1), d5)
+        self.assertEqual(UserDict.UserDict().fromkeys('one two'.split(), 1), d5)
+        self.assert_(u1.fromkeys('one two'.split()) is not u1)
+        self.assert_(isinstance(u1.fromkeys('one two'.split()), UserDict.UserDict))
+        self.assert_(isinstance(u2.fromkeys('one two'.split()), UserDict.IterableUserDict))
+
+        # Test __repr__
+        self.assertEqual(str(u0), str(d0))
+        self.assertEqual(repr(u1), repr(d1))
+        self.assertEqual(`u2`, `d2`)
+
+        # Test __cmp__ and __len__
+        all = [d0, d1, d2, u, u0, u1, u2, uu, uu0, uu1, uu2]
+        for a in all:
+            for b in all:
+                self.assertEqual(cmp(a, b), cmp(len(a), len(b)))
+
+        # Test __getitem__
+        self.assertEqual(u2["one"], 1)
+        self.assertRaises(KeyError, u1.__getitem__, "two")
+
+        # Test __setitem__
+        u3 = UserDict.UserDict(u2)
+        u3["two"] = 2
+        u3["three"] = 3
+
+        # Test __delitem__
+        del u3["three"]
+        self.assertRaises(KeyError, u3.__delitem__, "three")
+
+        # Test clear
+        u3.clear()
+        self.assertEqual(u3, {})
+
+        # Test copy()
+        u2a = u2.copy()
+        self.assertEqual(u2a, u2)
+        u2b = UserDict.UserDict(x=42, y=23)
+        u2c = u2b.copy() # making a copy of a UserDict is special cased
+        self.assertEqual(u2b, u2c)
+
+        class MyUserDict(UserDict.UserDict):
+            def display(self): print self
+
+        m2 = MyUserDict(u2)
+        m2a = m2.copy()
+        self.assertEqual(m2a, m2)
+
+        # SF bug #476616 -- copy() of UserDict subclass shared data
+        m2['foo'] = 'bar'
+        self.assertNotEqual(m2a, m2)
+
+        # Test keys, items, values
+        self.assertEqual(u2.keys(), d2.keys())
+        self.assertEqual(u2.items(), d2.items())
+        self.assertEqual(u2.values(), d2.values())
+
+        # Test has_key and "in".
+        for i in u2.keys():
+            self.assert_(u2.has_key(i))
+            self.assert_(i in u2)
+            self.assertEqual(u1.has_key(i), d1.has_key(i))
+            self.assertEqual(i in u1, i in d1)
+            self.assertEqual(u0.has_key(i), d0.has_key(i))
+            self.assertEqual(i in u0, i in d0)
+
+        # Test update
+        t = UserDict.UserDict()
+        t.update(u2)
+        self.assertEqual(t, u2)
+        class Items:
+            def items(self):
+                return (("x", 42), ("y", 23))
+        t = UserDict.UserDict()
+        t.update(Items())
+        self.assertEqual(t, {"x": 42, "y": 23})
+
+        # Test get
+        for i in u2.keys():
+            self.assertEqual(u2.get(i), u2[i])
+            self.assertEqual(u1.get(i), d1.get(i))
+            self.assertEqual(u0.get(i), d0.get(i))
+
+        # Test "in" iteration.
+        for i in xrange(20):
+            u2[i] = str(i)
+        ikeys = []
+        for k in u2:
+            ikeys.append(k)
+        keys = u2.keys()
+        self.assertEqual(set(ikeys), set(keys))
+
+        # Test setdefault
+        t = UserDict.UserDict()
+        self.assertEqual(t.setdefault("x", 42), 42)
+        self.assert_(t.has_key("x"))
+        self.assertEqual(t.setdefault("x", 23), 42)
+
+        # Test pop
+        t = UserDict.UserDict(x=42)
+        self.assertEqual(t.pop("x"), 42)
+        self.assertRaises(KeyError, t.pop, "x")
+        self.assertEqual(t.pop("x", 1), 1)
+        t["x"] = 42
+        self.assertEqual(t.pop("x", 1), 42)
+
+        # Test popitem
+        t = UserDict.UserDict(x=42)
+        self.assertEqual(t.popitem(), ("x", 42))
+        self.assertRaises(KeyError, t.popitem)
+
+    def test_missing(self):
+        # Make sure UserDict doesn't have a __missing__ method
+        self.assertEqual(hasattr(UserDict, "__missing__"), False)
+        # Test several cases:
+        # (D) subclass defines __missing__ method returning a value
+        # (E) subclass defines __missing__ method raising RuntimeError
+        # (F) subclass sets __missing__ instance variable (no effect)
+        # (G) subclass doesn't define __missing__ at a all
+        class D(UserDict.UserDict):
+            def __missing__(self, key):
+                return 42
+        d = D({1: 2, 3: 4})
+        self.assertEqual(d[1], 2)
+        self.assertEqual(d[3], 4)
+        self.assert_(2 not in d)
+        self.assert_(2 not in d.keys())
+        self.assertEqual(d[2], 42)
+        class E(UserDict.UserDict):
+            def __missing__(self, key):
+                raise RuntimeError(key)
+        e = E()
+        try:
+            e[42]
+        except RuntimeError, err:
+            self.assertEqual(err.args, (42,))
+        else:
+            self.fail("e[42] didn't raise RuntimeError")
+        class F(UserDict.UserDict):
+            def __init__(self):
+                # An instance variable __missing__ should have no effect
+                self.__missing__ = lambda key: None
+                UserDict.UserDict.__init__(self)
+        f = F()
+        try:
+            f[42]
+        except KeyError, err:
+            self.assertEqual(err.args, (42,))
+        else:
+            self.fail("f[42] didn't raise KeyError")
+        class G(UserDict.UserDict):
+            pass
+        g = G()
+        try:
+            g[42]
+        except KeyError, err:
+            self.assertEqual(err.args, (42,))
+        else:
+            self.fail("g[42] didn't raise KeyError")
+
+##########################
+# Test Dict Mixin
+
+class SeqDict(UserDict.DictMixin):
+    """Dictionary lookalike implemented with lists.
+
+    Used to test and demonstrate DictMixin
+    """
+    def __init__(self, other=None, **kwargs):
+        self.keylist = []
+        self.valuelist = []
+        if other is not None:
+            for (key, value) in other:
+                self[key] = value
+        for (key, value) in kwargs.iteritems():
+            self[key] = value
+    def __getitem__(self, key):
+        try:
+            i = self.keylist.index(key)
+        except ValueError:
+            raise KeyError
+        return self.valuelist[i]
+    def __setitem__(self, key, value):
+        try:
+            i = self.keylist.index(key)
+            self.valuelist[i] = value
+        except ValueError:
+            self.keylist.append(key)
+            self.valuelist.append(value)
+    def __delitem__(self, key):
+        try:
+            i = self.keylist.index(key)
+        except ValueError:
+            raise KeyError
+        self.keylist.pop(i)
+        self.valuelist.pop(i)
+    def keys(self):
+        return list(self.keylist)
+    def copy(self):
+        d = self.__class__()
+        for key, value in self.iteritems():
+            d[key] = value
+        return d
+    @classmethod
+    def fromkeys(cls, keys, value=None):
+        d = cls()
+        for key in keys:
+            d[key] = value
+        return d
+
+class UserDictMixinTest(mapping_tests.TestMappingProtocol):
+    type2test = SeqDict
+
+    def test_all(self):
+        ## Setup test and verify working of the test class
+
+        # check init
+        s = SeqDict()
+
+        # exercise setitem
+        s[10] = 'ten'
+        s[20] = 'twenty'
+        s[30] = 'thirty'
+
+        # exercise delitem
+        del s[20]
+        # check getitem and setitem
+        self.assertEqual(s[10], 'ten')
+        # check keys() and delitem
+        self.assertEqual(s.keys(), [10, 30])
+
+        ## Now, test the DictMixin methods one by one
+        # has_key
+        self.assert_(s.has_key(10))
+        self.assert_(not s.has_key(20))
+
+        # __contains__
+        self.assert_(10 in s)
+        self.assert_(20 not in s)
+
+        # __iter__
+        self.assertEqual([k for k in s], [10, 30])
+
+        # __len__
+        self.assertEqual(len(s), 2)
+
+        # iteritems
+        self.assertEqual(list(s.iteritems()), [(10,'ten'), (30, 'thirty')])
+
+        # iterkeys
+        self.assertEqual(list(s.iterkeys()), [10, 30])
+
+        # itervalues
+        self.assertEqual(list(s.itervalues()), ['ten', 'thirty'])
+
+        # values
+        self.assertEqual(s.values(), ['ten', 'thirty'])
+
+        # items
+        self.assertEqual(s.items(), [(10,'ten'), (30, 'thirty')])
+
+        # get
+        self.assertEqual(s.get(10), 'ten')
+        self.assertEqual(s.get(15,'fifteen'), 'fifteen')
+        self.assertEqual(s.get(15), None)
+
+        # setdefault
+        self.assertEqual(s.setdefault(40, 'forty'), 'forty')
+        self.assertEqual(s.setdefault(10, 'null'), 'ten')
+        del s[40]
+
+        # pop
+        self.assertEqual(s.pop(10), 'ten')
+        self.assert_(10 not in s)
+        s[10] = 'ten'
+        self.assertEqual(s.pop("x", 1), 1)
+        s["x"] = 42
+        self.assertEqual(s.pop("x", 1), 42)
+
+        # popitem
+        k, v = s.popitem()
+        self.assert_(k not in s)
+        s[k] = v
+
+        # clear
+        s.clear()
+        self.assertEqual(len(s), 0)
+
+        # empty popitem
+        self.assertRaises(KeyError, s.popitem)
+
+        # update
+        s.update({10: 'ten', 20:'twenty'})
+        self.assertEqual(s[10], 'ten')
+        self.assertEqual(s[20], 'twenty')
+
+        # cmp
+        self.assertEqual(s, {10: 'ten', 20:'twenty'})
+        t = SeqDict()
+        t[20] = 'twenty'
+        t[10] = 'ten'
+        self.assertEqual(s, t)
+
+def test_main():
+    test_support.run_unittest(
+        UserDictTest,
+        UserDictMixinTest
+    )
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_userlist.py
===================================================================
--- vendor/Python/current/Lib/test/test_userlist.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_userlist.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,60 @@
+# Check every path through every method of UserList
+
+from UserList import UserList
+import unittest
+from test import test_support, list_tests
+
+class UserListTest(list_tests.CommonTest):
+    type2test = UserList
+
+    def test_getslice(self):
+        super(UserListTest, self).test_getslice()
+        l = [0, 1, 2, 3, 4]
+        u = self.type2test(l)
+        for i in range(-3, 6):
+            self.assertEqual(u[:i], l[:i])
+            self.assertEqual(u[i:], l[i:])
+            for j in xrange(-3, 6):
+                self.assertEqual(u[i:j], l[i:j])
+
+    def test_add_specials(self):
+        u = UserList("spam")
+        u2 = u + "eggs"
+        self.assertEqual(u2, list("spameggs"))
+
+    def test_radd_specials(self):
+        u = UserList("eggs")
+        u2 = "spam" + u
+        self.assertEqual(u2, list("spameggs"))
+        u2 = u.__radd__(UserList("spam"))
+        self.assertEqual(u2, list("spameggs"))
+
+    def test_iadd(self):
+        super(UserListTest, self).test_iadd()
+        u = [0, 1]
+        u += UserList([0, 1])
+        self.assertEqual(u, [0, 1, 0, 1])
+
+    def test_mixedcmp(self):
+        u = self.type2test([0, 1])
+        self.assertEqual(u, [0, 1])
+        self.assertNotEqual(u, [0])
+        self.assertNotEqual(u, [0, 2])
+
+    def test_mixedadd(self):
+        u = self.type2test([0, 1])
+        self.assertEqual(u + [], u)
+        self.assertEqual(u + [2], [0, 1, 2])
+
+    def test_getitemoverwriteiter(self):
+        # Verify that __getitem__ overrides *are* recognized by __iter__
+        class T(self.type2test):
+            def __getitem__(self, key):
+                return str(key) + '!!!'
+        self.assertEqual(iter(T((1,2))).next(), "0!!!")
+
+def test_main():
+    test_support.run_unittest(UserListTest)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_userstring.py
===================================================================
--- vendor/Python/current/Lib/test/test_userstring.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_userstring.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,119 @@
+#!/usr/bin/env python
+# UserString is a wrapper around the native builtin string type.
+# UserString instances should behave similar to builtin string objects.
+
+import unittest
+from test import test_support, string_tests
+
+from UserString import UserString, MutableString
+
+class UserStringTest(
+    string_tests.CommonTest,
+    string_tests.MixinStrUnicodeUserStringTest,
+    string_tests.MixinStrStringUserStringTest,
+    string_tests.MixinStrUserStringTest
+    ):
+
+    type2test = UserString
+
+    # Overwrite the three testing methods, because UserString
+    # can't cope with arguments propagated to UserString
+    # (and we don't test with subclasses)
+    def checkequal(self, result, object, methodname, *args):
+        result = self.fixtype(result)
+        object = self.fixtype(object)
+        # we don't fix the arguments, because UserString can't cope with it
+        realresult = getattr(object, methodname)(*args)
+        self.assertEqual(
+            result,
+            realresult
+        )
+
+    def checkraises(self, exc, object, methodname, *args):
+        object = self.fixtype(object)
+        # we don't fix the arguments, because UserString can't cope with it
+        self.assertRaises(
+            exc,
+            getattr(object, methodname),
+            *args
+        )
+
+    def checkcall(self, object, methodname, *args):
+        object = self.fixtype(object)
+        # we don't fix the arguments, because UserString can't cope with it
+        getattr(object, methodname)(*args)
+
+class MutableStringTest(UserStringTest):
+    type2test = MutableString
+
+    # MutableStrings can be hashed => deactivate test
+    def test_hash(self):
+        pass
+
+    def test_setitem(self):
+        s = self.type2test("foo")
+        self.assertRaises(IndexError, s.__setitem__, -4, "bar")
+        self.assertRaises(IndexError, s.__setitem__, 3, "bar")
+        s[-1] = "bar"
+        self.assertEqual(s, "fobar")
+        s[0] = "bar"
+        self.assertEqual(s, "barobar")
+
+    def test_delitem(self):
+        s = self.type2test("foo")
+        self.assertRaises(IndexError, s.__delitem__, -4)
+        self.assertRaises(IndexError, s.__delitem__, 3)
+        del s[-1]
+        self.assertEqual(s, "fo")
+        del s[0]
+        self.assertEqual(s, "o")
+        del s[0]
+        self.assertEqual(s, "")
+
+    def test_setslice(self):
+        s = self.type2test("foo")
+        s[:] = "bar"
+        self.assertEqual(s, "bar")
+        s[1:2] = "foo"
+        self.assertEqual(s, "bfoor")
+        s[1:-1] = UserString("a")
+        self.assertEqual(s, "bar")
+        s[0:10] = 42
+        self.assertEqual(s, "42")
+
+    def test_delslice(self):
+        s = self.type2test("foobar")
+        del s[3:10]
+        self.assertEqual(s, "foo")
+        del s[-1:10]
+        self.assertEqual(s, "fo")
+
+    def test_immutable(self):
+        s = self.type2test("foobar")
+        s2 = s.immutable()
+        self.assertEqual(s, s2)
+        self.assert_(isinstance(s2, UserString))
+
+    def test_iadd(self):
+        s = self.type2test("foo")
+        s += "bar"
+        self.assertEqual(s, "foobar")
+        s += UserString("baz")
+        self.assertEqual(s, "foobarbaz")
+        s += 42
+        self.assertEqual(s, "foobarbaz42")
+
+    def test_imul(self):
+        s = self.type2test("foo")
+        s *= 1
+        self.assertEqual(s, "foo")
+        s *= 2
+        self.assertEqual(s, "foofoo")
+        s *= -1
+        self.assertEqual(s, "")
+
+def test_main():
+    test_support.run_unittest(UserStringTest, MutableStringTest)
+
+if __name__ == "__main__":
+    test_main()


Property changes on: vendor/Python/current/Lib/test/test_userstring.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/test/test_uu.py
===================================================================
--- vendor/Python/current/Lib/test/test_uu.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_uu.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,180 @@
+"""
+Tests for uu module.
+Nick Mathewson
+"""
+
+import unittest
+from test import test_support
+
+import sys, os, uu, cStringIO
+import uu
+from StringIO import StringIO
+
+plaintext = "The smooth-scaled python crept over the sleeping dog\n"
+
+encodedtext = """\
+M5&AE('-M;V]T:\"US8V%L960@<'ET:&]N(&-R97!T(&]V97(@=&AE('-L965P
+(:6YG(&1O9PH """
+
+encodedtextwrapped = "begin %03o %s\n" + encodedtext.replace("%", "%%") + "\n \nend\n"
+
+class UUTest(unittest.TestCase):
+
+    def test_encode(self):
+        inp = cStringIO.StringIO(plaintext)
+        out = cStringIO.StringIO()
+        uu.encode(inp, out, "t1")
+        self.assertEqual(out.getvalue(), encodedtextwrapped % (0666, "t1"))
+        inp = cStringIO.StringIO(plaintext)
+        out = cStringIO.StringIO()
+        uu.encode(inp, out, "t1", 0644)
+        self.assertEqual(out.getvalue(), encodedtextwrapped % (0644, "t1"))
+
+    def test_decode(self):
+        inp = cStringIO.StringIO(encodedtextwrapped % (0666, "t1"))
+        out = cStringIO.StringIO()
+        uu.decode(inp, out)
+        self.assertEqual(out.getvalue(), plaintext)
+        inp = cStringIO.StringIO(
+            "UUencoded files may contain many lines,\n" +
+            "even some that have 'begin' in them.\n" +
+            encodedtextwrapped % (0666, "t1")
+        )
+        out = cStringIO.StringIO()
+        uu.decode(inp, out)
+        self.assertEqual(out.getvalue(), plaintext)
+
+    def test_truncatedinput(self):
+        inp = cStringIO.StringIO("begin 644 t1\n" + encodedtext)
+        out = cStringIO.StringIO()
+        try:
+            uu.decode(inp, out)
+            self.fail("No exception thrown")
+        except uu.Error, e:
+            self.assertEqual(str(e), "Truncated input file")
+
+    def test_missingbegin(self):
+        inp = cStringIO.StringIO("")
+        out = cStringIO.StringIO()
+        try:
+            uu.decode(inp, out)
+            self.fail("No exception thrown")
+        except uu.Error, e:
+            self.assertEqual(str(e), "No valid begin line found in input file")
+
+class UUStdIOTest(unittest.TestCase):
+
+    def setUp(self):
+        self.stdin = sys.stdin
+        self.stdout = sys.stdout
+
+    def tearDown(self):
+        sys.stdin = self.stdin
+        sys.stdout = self.stdout
+
+    def test_encode(self):
+        sys.stdin = cStringIO.StringIO(plaintext)
+        sys.stdout = cStringIO.StringIO()
+        uu.encode("-", "-", "t1", 0666)
+        self.assertEqual(
+            sys.stdout.getvalue(),
+            encodedtextwrapped % (0666, "t1")
+        )
+
+    def test_decode(self):
+        sys.stdin = cStringIO.StringIO(encodedtextwrapped % (0666, "t1"))
+        sys.stdout = cStringIO.StringIO()
+        uu.decode("-", "-")
+        self.assertEqual(sys.stdout.getvalue(), plaintext)
+
+class UUFileTest(unittest.TestCase):
+
+    def _kill(self, f):
+        # close and remove file
+        try:
+            f.close()
+        except (SystemExit, KeyboardInterrupt):
+            raise
+        except:
+            pass
+        try:
+            os.unlink(f.name)
+        except (SystemExit, KeyboardInterrupt):
+            raise
+        except:
+            pass
+
+    def setUp(self):
+        self.tmpin  = test_support.TESTFN + "i"
+        self.tmpout = test_support.TESTFN + "o"
+
+    def tearDown(self):
+        del self.tmpin
+        del self.tmpout
+
+    def test_encode(self):
+        try:
+            fin = open(self.tmpin, 'wb')
+            fin.write(plaintext)
+            fin.close()
+
+            fin = open(self.tmpin, 'rb')
+            fout = open(self.tmpout, 'w')
+            uu.encode(fin, fout, self.tmpin, mode=0644)
+            fin.close()
+            fout.close()
+
+            fout = open(self.tmpout, 'r')
+            s = fout.read()
+            fout.close()
+            self.assertEqual(s, encodedtextwrapped % (0644, self.tmpin))
+
+            # in_file and out_file as filenames
+            uu.encode(self.tmpin, self.tmpout, mode=0644)
+            fout = open(self.tmpout, 'r')
+            s = fout.read()
+            fout.close()
+            self.assertEqual(s, encodedtextwrapped % (0644, self.tmpin))
+
+        finally:
+            self._kill(fin)
+            self._kill(fout)
+
+    def test_decode(self):
+        try:
+            f = open(self.tmpin, 'wb')
+            f.write(encodedtextwrapped % (0644, self.tmpout))
+            f.close()
+
+            f = open(self.tmpin, 'rb')
+            uu.decode(f)
+            f.close()
+
+            f = open(self.tmpout, 'r')
+            s = f.read()
+            f.close()
+            self.assertEqual(s, plaintext)
+            # XXX is there an xp way to verify the mode?
+        finally:
+            self._kill(f)
+
+    def test_decodetwice(self):
+        # Verify that decode() will refuse to overwrite an existing file
+        try:
+            f = cStringIO.StringIO(encodedtextwrapped % (0644, self.tmpout))
+
+            f = open(self.tmpin, 'rb')
+            uu.decode(f)
+            f.close()
+
+            f = open(self.tmpin, 'rb')
+            self.assertRaises(uu.Error, uu.decode, f)
+            f.close()
+        finally:
+            self._kill(f)
+
+def test_main():
+    test_support.run_unittest(UUTest, UUStdIOTest, UUFileTest)
+
+if __name__=="__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_uuid.py
===================================================================
--- vendor/Python/current/Lib/test/test_uuid.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_uuid.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,459 @@
+from unittest import TestCase
+from test import test_support
+import uuid
+
+def importable(name):
+    try:
+        __import__(name)
+        return True
+    except:
+        return False
+
+class TestUUID(TestCase):
+    last_node = None
+    source2node = {}
+
+    def test_UUID(self):
+        equal = self.assertEqual
+        ascending = []
+        for (string, curly, hex, bytes, bytes_le, fields, integer, urn,
+             time, clock_seq, variant, version) in [
+            ('00000000-0000-0000-0000-000000000000',
+             '{00000000-0000-0000-0000-000000000000}',
+             '00000000000000000000000000000000',
+             '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0',
+             '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0',
+             (0, 0, 0, 0, 0, 0),
+             0,
+             'urn:uuid:00000000-0000-0000-0000-000000000000',
+             0, 0, uuid.RESERVED_NCS, None),
+            ('00010203-0405-0607-0809-0a0b0c0d0e0f',
+             '{00010203-0405-0607-0809-0a0b0c0d0e0f}',
+             '000102030405060708090a0b0c0d0e0f',
+             '\0\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\x0d\x0e\x0f',
+             '\x03\x02\x01\0\x05\x04\x07\x06\x08\t\n\x0b\x0c\x0d\x0e\x0f',
+             (0x00010203L, 0x0405, 0x0607, 8, 9, 0x0a0b0c0d0e0fL),
+             0x000102030405060708090a0b0c0d0e0fL,
+             'urn:uuid:00010203-0405-0607-0809-0a0b0c0d0e0f',
+             0x607040500010203L, 0x809, uuid.RESERVED_NCS, None),
+            ('02d9e6d5-9467-382e-8f9b-9300a64ac3cd',
+             '{02d9e6d5-9467-382e-8f9b-9300a64ac3cd}',
+             '02d9e6d59467382e8f9b9300a64ac3cd',
+             '\x02\xd9\xe6\xd5\x94\x67\x38\x2e\x8f\x9b\x93\x00\xa6\x4a\xc3\xcd',
+             '\xd5\xe6\xd9\x02\x67\x94\x2e\x38\x8f\x9b\x93\x00\xa6\x4a\xc3\xcd',
+             (0x02d9e6d5L, 0x9467, 0x382e, 0x8f, 0x9b, 0x9300a64ac3cdL),
+             0x02d9e6d59467382e8f9b9300a64ac3cdL,
+             'urn:uuid:02d9e6d5-9467-382e-8f9b-9300a64ac3cd',
+             0x82e946702d9e6d5L, 0xf9b, uuid.RFC_4122, 3),
+            ('12345678-1234-5678-1234-567812345678',
+             '{12345678-1234-5678-1234-567812345678}',
+             '12345678123456781234567812345678',
+             '\x12\x34\x56\x78'*4,
+             '\x78\x56\x34\x12\x34\x12\x78\x56\x12\x34\x56\x78\x12\x34\x56\x78',
+             (0x12345678, 0x1234, 0x5678, 0x12, 0x34, 0x567812345678),
+             0x12345678123456781234567812345678,
+             'urn:uuid:12345678-1234-5678-1234-567812345678',
+             0x678123412345678L, 0x1234, uuid.RESERVED_NCS, None),
+            ('6ba7b810-9dad-11d1-80b4-00c04fd430c8',
+             '{6ba7b810-9dad-11d1-80b4-00c04fd430c8}',
+             '6ba7b8109dad11d180b400c04fd430c8',
+             '\x6b\xa7\xb8\x10\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8',
+             '\x10\xb8\xa7\x6b\xad\x9d\xd1\x11\x80\xb4\x00\xc0\x4f\xd4\x30\xc8',
+             (0x6ba7b810L, 0x9dad, 0x11d1, 0x80, 0xb4, 0x00c04fd430c8L),
+             0x6ba7b8109dad11d180b400c04fd430c8L,
+             'urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8',
+             0x1d19dad6ba7b810L, 0xb4, uuid.RFC_4122, 1),
+            ('6ba7b811-9dad-11d1-80b4-00c04fd430c8',
+             '{6ba7b811-9dad-11d1-80b4-00c04fd430c8}',
+             '6ba7b8119dad11d180b400c04fd430c8',
+             '\x6b\xa7\xb8\x11\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8',
+             '\x11\xb8\xa7\x6b\xad\x9d\xd1\x11\x80\xb4\x00\xc0\x4f\xd4\x30\xc8',
+             (0x6ba7b811L, 0x9dad, 0x11d1, 0x80, 0xb4, 0x00c04fd430c8L),
+             0x6ba7b8119dad11d180b400c04fd430c8L,
+             'urn:uuid:6ba7b811-9dad-11d1-80b4-00c04fd430c8',
+             0x1d19dad6ba7b811L, 0xb4, uuid.RFC_4122, 1),
+            ('6ba7b812-9dad-11d1-80b4-00c04fd430c8',
+             '{6ba7b812-9dad-11d1-80b4-00c04fd430c8}',
+             '6ba7b8129dad11d180b400c04fd430c8',
+             '\x6b\xa7\xb8\x12\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8',
+             '\x12\xb8\xa7\x6b\xad\x9d\xd1\x11\x80\xb4\x00\xc0\x4f\xd4\x30\xc8',
+             (0x6ba7b812L, 0x9dad, 0x11d1, 0x80, 0xb4, 0x00c04fd430c8L),
+             0x6ba7b8129dad11d180b400c04fd430c8L,
+             'urn:uuid:6ba7b812-9dad-11d1-80b4-00c04fd430c8',
+             0x1d19dad6ba7b812L, 0xb4, uuid.RFC_4122, 1),
+            ('6ba7b814-9dad-11d1-80b4-00c04fd430c8',
+             '{6ba7b814-9dad-11d1-80b4-00c04fd430c8}',
+             '6ba7b8149dad11d180b400c04fd430c8',
+             '\x6b\xa7\xb8\x14\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8',
+             '\x14\xb8\xa7\x6b\xad\x9d\xd1\x11\x80\xb4\x00\xc0\x4f\xd4\x30\xc8',
+             (0x6ba7b814L, 0x9dad, 0x11d1, 0x80, 0xb4, 0x00c04fd430c8L),
+             0x6ba7b8149dad11d180b400c04fd430c8L,
+             'urn:uuid:6ba7b814-9dad-11d1-80b4-00c04fd430c8',
+             0x1d19dad6ba7b814L, 0xb4, uuid.RFC_4122, 1),
+            ('7d444840-9dc0-11d1-b245-5ffdce74fad2',
+             '{7d444840-9dc0-11d1-b245-5ffdce74fad2}',
+             '7d4448409dc011d1b2455ffdce74fad2',
+             '\x7d\x44\x48\x40\x9d\xc0\x11\xd1\xb2\x45\x5f\xfd\xce\x74\xfa\xd2',
+             '\x40\x48\x44\x7d\xc0\x9d\xd1\x11\xb2\x45\x5f\xfd\xce\x74\xfa\xd2',
+             (0x7d444840L, 0x9dc0, 0x11d1, 0xb2, 0x45, 0x5ffdce74fad2L),
+             0x7d4448409dc011d1b2455ffdce74fad2L,
+             'urn:uuid:7d444840-9dc0-11d1-b245-5ffdce74fad2',
+             0x1d19dc07d444840L, 0x3245, uuid.RFC_4122, 1),
+            ('e902893a-9d22-3c7e-a7b8-d6e313b71d9f',
+             '{e902893a-9d22-3c7e-a7b8-d6e313b71d9f}',
+             'e902893a9d223c7ea7b8d6e313b71d9f',
+             '\xe9\x02\x89\x3a\x9d\x22\x3c\x7e\xa7\xb8\xd6\xe3\x13\xb7\x1d\x9f',
+             '\x3a\x89\x02\xe9\x22\x9d\x7e\x3c\xa7\xb8\xd6\xe3\x13\xb7\x1d\x9f',
+             (0xe902893aL, 0x9d22, 0x3c7e, 0xa7, 0xb8, 0xd6e313b71d9fL),
+             0xe902893a9d223c7ea7b8d6e313b71d9fL,
+             'urn:uuid:e902893a-9d22-3c7e-a7b8-d6e313b71d9f',
+             0xc7e9d22e902893aL, 0x27b8, uuid.RFC_4122, 3),
+            ('eb424026-6f54-4ef8-a4d0-bb658a1fc6cf',
+             '{eb424026-6f54-4ef8-a4d0-bb658a1fc6cf}',
+             'eb4240266f544ef8a4d0bb658a1fc6cf',
+             '\xeb\x42\x40\x26\x6f\x54\x4e\xf8\xa4\xd0\xbb\x65\x8a\x1f\xc6\xcf',
+             '\x26\x40\x42\xeb\x54\x6f\xf8\x4e\xa4\xd0\xbb\x65\x8a\x1f\xc6\xcf',
+             (0xeb424026L, 0x6f54, 0x4ef8, 0xa4, 0xd0, 0xbb658a1fc6cfL),
+             0xeb4240266f544ef8a4d0bb658a1fc6cfL,
+             'urn:uuid:eb424026-6f54-4ef8-a4d0-bb658a1fc6cf',
+             0xef86f54eb424026L, 0x24d0, uuid.RFC_4122, 4),
+            ('f81d4fae-7dec-11d0-a765-00a0c91e6bf6',
+             '{f81d4fae-7dec-11d0-a765-00a0c91e6bf6}',
+             'f81d4fae7dec11d0a76500a0c91e6bf6',
+             '\xf8\x1d\x4f\xae\x7d\xec\x11\xd0\xa7\x65\x00\xa0\xc9\x1e\x6b\xf6',
+             '\xae\x4f\x1d\xf8\xec\x7d\xd0\x11\xa7\x65\x00\xa0\xc9\x1e\x6b\xf6',
+             (0xf81d4faeL, 0x7dec, 0x11d0, 0xa7, 0x65, 0x00a0c91e6bf6L),
+             0xf81d4fae7dec11d0a76500a0c91e6bf6L,
+             'urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6',
+             0x1d07decf81d4faeL, 0x2765, uuid.RFC_4122, 1),
+            ('fffefdfc-fffe-fffe-fffe-fffefdfcfbfa',
+             '{fffefdfc-fffe-fffe-fffe-fffefdfcfbfa}',
+             'fffefdfcfffefffefffefffefdfcfbfa',
+             '\xff\xfe\xfd\xfc\xff\xfe\xff\xfe\xff\xfe\xff\xfe\xfd\xfc\xfb\xfa',
+             '\xfc\xfd\xfe\xff\xfe\xff\xfe\xff\xff\xfe\xff\xfe\xfd\xfc\xfb\xfa',
+             (0xfffefdfcL, 0xfffe, 0xfffe, 0xff, 0xfe, 0xfffefdfcfbfaL),
+             0xfffefdfcfffefffefffefffefdfcfbfaL,
+             'urn:uuid:fffefdfc-fffe-fffe-fffe-fffefdfcfbfa',
+             0xffefffefffefdfcL, 0x3ffe, uuid.RESERVED_FUTURE, None),
+            ('ffffffff-ffff-ffff-ffff-ffffffffffff',
+             '{ffffffff-ffff-ffff-ffff-ffffffffffff}',
+             'ffffffffffffffffffffffffffffffff',
+             '\xff'*16,
+             '\xff'*16,
+             (0xffffffffL, 0xffffL, 0xffffL, 0xff, 0xff, 0xffffffffffffL),
+             0xffffffffffffffffffffffffffffffffL,
+             'urn:uuid:ffffffff-ffff-ffff-ffff-ffffffffffff',
+             0xfffffffffffffffL, 0x3fff, uuid.RESERVED_FUTURE, None),
+            ]:
+            equivalents = []
+            # Construct each UUID in several different ways.
+            for u in [uuid.UUID(string), uuid.UUID(curly), uuid.UUID(hex),
+                      uuid.UUID(bytes=bytes), uuid.UUID(bytes_le=bytes_le),
+                      uuid.UUID(fields=fields), uuid.UUID(int=integer),
+                      uuid.UUID(urn)]:
+                # Test all conversions and properties of the UUID object.
+                equal(str(u), string)
+                equal(int(u), integer)
+                equal(u.bytes, bytes)
+                equal(u.bytes_le, bytes_le)
+                equal(u.fields, fields)
+                equal(u.time_low, fields[0])
+                equal(u.time_mid, fields[1])
+                equal(u.time_hi_version, fields[2])
+                equal(u.clock_seq_hi_variant, fields[3])
+                equal(u.clock_seq_low, fields[4])
+                equal(u.node, fields[5])
+                equal(u.hex, hex)
+                equal(u.int, integer)
+                equal(u.urn, urn)
+                equal(u.time, time)
+                equal(u.clock_seq, clock_seq)
+                equal(u.variant, variant)
+                equal(u.version, version)
+                equivalents.append(u)
+
+            # Different construction methods should give the same UUID.
+            for u in equivalents:
+                for v in equivalents:
+                    equal(u, v)
+            ascending.append(u)
+
+        # Test comparison of UUIDs.
+        for i in range(len(ascending)):
+            for j in range(len(ascending)):
+                equal(cmp(i, j), cmp(ascending[i], ascending[j]))
+
+        # Test sorting of UUIDs (above list is in ascending order).
+        resorted = ascending[:]
+        resorted.reverse()
+        resorted.sort()
+        equal(ascending, resorted)
+
+    def test_exceptions(self):
+        badvalue = lambda f: self.assertRaises(ValueError, f)
+        badtype = lambda f: self.assertRaises(TypeError, f)
+
+        # Badly formed hex strings.
+        badvalue(lambda: uuid.UUID(''))
+        badvalue(lambda: uuid.UUID('abc'))
+        badvalue(lambda: uuid.UUID('1234567812345678123456781234567'))
+        badvalue(lambda: uuid.UUID('123456781234567812345678123456789'))
+        badvalue(lambda: uuid.UUID('123456781234567812345678z2345678'))
+
+        # Badly formed bytes.
+        badvalue(lambda: uuid.UUID(bytes='abc'))
+        badvalue(lambda: uuid.UUID(bytes='\0'*15))
+        badvalue(lambda: uuid.UUID(bytes='\0'*17))
+
+        # Badly formed bytes_le.
+        badvalue(lambda: uuid.UUID(bytes_le='abc'))
+        badvalue(lambda: uuid.UUID(bytes_le='\0'*15))
+        badvalue(lambda: uuid.UUID(bytes_le='\0'*17))
+
+        # Badly formed fields.
+        badvalue(lambda: uuid.UUID(fields=(1,)))
+        badvalue(lambda: uuid.UUID(fields=(1, 2, 3, 4, 5)))
+        badvalue(lambda: uuid.UUID(fields=(1, 2, 3, 4, 5, 6, 7)))
+
+        # Field values out of range.
+        badvalue(lambda: uuid.UUID(fields=(-1, 0, 0, 0, 0, 0)))
+        badvalue(lambda: uuid.UUID(fields=(0x100000000L, 0, 0, 0, 0, 0)))
+        badvalue(lambda: uuid.UUID(fields=(0, -1, 0, 0, 0, 0)))
+        badvalue(lambda: uuid.UUID(fields=(0, 0x10000L, 0, 0, 0, 0)))
+        badvalue(lambda: uuid.UUID(fields=(0, 0, -1, 0, 0, 0)))
+        badvalue(lambda: uuid.UUID(fields=(0, 0, 0x10000L, 0, 0, 0)))
+        badvalue(lambda: uuid.UUID(fields=(0, 0, 0, -1, 0, 0)))
+        badvalue(lambda: uuid.UUID(fields=(0, 0, 0, 0x100L, 0, 0)))
+        badvalue(lambda: uuid.UUID(fields=(0, 0, 0, 0, -1, 0)))
+        badvalue(lambda: uuid.UUID(fields=(0, 0, 0, 0, 0x100L, 0)))
+        badvalue(lambda: uuid.UUID(fields=(0, 0, 0, 0, 0, -1)))
+        badvalue(lambda: uuid.UUID(fields=(0, 0, 0, 0, 0, 0x1000000000000L)))
+
+        # Version number out of range.
+        badvalue(lambda: uuid.UUID('00'*16, version=0))
+        badvalue(lambda: uuid.UUID('00'*16, version=6))
+
+        # Integer value out of range.
+        badvalue(lambda: uuid.UUID(int=-1))
+        badvalue(lambda: uuid.UUID(int=1<<128L))
+
+        # Must supply exactly one of hex, bytes, fields, int.
+        h, b, f, i = '00'*16, '\0'*16, (0, 0, 0, 0, 0, 0), 0
+        uuid.UUID(h)
+        uuid.UUID(hex=h)
+        uuid.UUID(bytes=b)
+        uuid.UUID(bytes_le=b)
+        uuid.UUID(fields=f)
+        uuid.UUID(int=i)
+
+        # Wrong number of arguments (positional).
+        badtype(lambda: uuid.UUID())
+        badtype(lambda: uuid.UUID(h, b))
+        badtype(lambda: uuid.UUID(h, b, b))
+        badtype(lambda: uuid.UUID(h, b, b, f))
+        badtype(lambda: uuid.UUID(h, b, b, f, i))
+
+        # Duplicate arguments.
+        for hh in [[], [('hex', h)]]:
+            for bb in [[], [('bytes', b)]]:
+                for bble in [[], [('bytes_le', b)]]:
+                    for ii in [[], [('int', i)]]:
+                        for ff in [[], [('fields', f)]]:
+                            args = dict(hh + bb + bble + ii + ff)
+                            if len(args) != 0:
+                                badtype(lambda: uuid.UUID(h, **args))
+                            if len(args) != 1:
+                                badtype(lambda: uuid.UUID(**args))
+
+        # Immutability.
+        u = uuid.UUID(h)
+        badtype(lambda: setattr(u, 'hex', h))
+        badtype(lambda: setattr(u, 'bytes', b))
+        badtype(lambda: setattr(u, 'bytes_le', b))
+        badtype(lambda: setattr(u, 'fields', f))
+        badtype(lambda: setattr(u, 'int', i))
+        badtype(lambda: setattr(u, 'time_low', 0))
+        badtype(lambda: setattr(u, 'time_mid', 0))
+        badtype(lambda: setattr(u, 'time_hi_version', 0))
+        badtype(lambda: setattr(u, 'time_hi_version', 0))
+        badtype(lambda: setattr(u, 'clock_seq_hi_variant', 0))
+        badtype(lambda: setattr(u, 'clock_seq_low', 0))
+        badtype(lambda: setattr(u, 'node', 0))
+
+    def check_node(self, node, source):
+        individual_group_bit = (node >> 40L) & 1
+        universal_local_bit = (node >> 40L) & 2
+        message = "%012x doesn't look like a real MAC address" % node
+        self.assertEqual(individual_group_bit, 0, message)
+        self.assertEqual(universal_local_bit, 0, message)
+        self.assertNotEqual(node, 0, message)
+        self.assertNotEqual(node, 0xffffffffffffL, message)
+        self.assert_(0 <= node, message)
+        self.assert_(node < (1L << 48), message)
+
+        TestUUID.source2node[source] = node
+        if TestUUID.last_node:
+            if TestUUID.last_node != node:
+                msg = "different sources disagree on node:\n"
+                for s, n in TestUUID.source2node.iteritems():
+                    msg += "    from source %r, node was %012x\n" % (s, n)
+                # There's actually no reason to expect the MAC addresses
+                # to agree across various methods -- e.g., a box may have
+                # multiple network interfaces, and different ways of getting
+                # a MAC address may favor different HW.
+                ##self.fail(msg)
+        else:
+            TestUUID.last_node = node
+
+    def test_ifconfig_getnode(self):
+        import sys
+        print >>sys.__stdout__, \
+"""    WARNING: uuid._ifconfig_getnode is unreliable on many platforms.
+        It is disabled until the code and/or test can be fixed properly."""
+        return
+
+        import os
+        if os.name == 'posix':
+            node = uuid._ifconfig_getnode()
+            if node is not None:
+                self.check_node(node, 'ifconfig')
+
+    def test_ipconfig_getnode(self):
+        import os
+        if os.name == 'nt':
+            node = uuid._ipconfig_getnode()
+            if node is not None:
+                self.check_node(node, 'ipconfig')
+
+    def test_netbios_getnode(self):
+        if importable('win32wnet') and importable('netbios'):
+            self.check_node(uuid._netbios_getnode(), 'netbios')
+
+    def test_random_getnode(self):
+        node = uuid._random_getnode()
+        self.assert_(0 <= node)
+        self.assert_(node < (1L <<48))
+
+    def test_unixdll_getnode(self):
+        import sys
+        print >>sys.__stdout__, \
+"""    WARNING: uuid._unixdll_getnode is unreliable on many platforms.
+        It is disabled until the code and/or test can be fixed properly."""
+        return
+
+        import os
+        if importable('ctypes') and os.name == 'posix':
+            self.check_node(uuid._unixdll_getnode(), 'unixdll')
+
+    def test_windll_getnode(self):
+        import os
+        if importable('ctypes') and os.name == 'nt':
+            self.check_node(uuid._windll_getnode(), 'windll')
+
+    def test_getnode(self):
+        import sys
+        print >>sys.__stdout__, \
+"""    WARNING: uuid.getnode is unreliable on many platforms.
+        It is disabled until the code and/or test can be fixed properly."""
+        return
+
+        node1 = uuid.getnode()
+        self.check_node(node1, "getnode1")
+
+        # Test it again to ensure consistency.
+        node2 = uuid.getnode()
+        self.check_node(node2, "getnode2")
+
+        self.assertEqual(node1, node2)
+
+    def test_uuid1(self):
+        equal = self.assertEqual
+
+        # Make sure uuid1() generates UUIDs that are actually version 1.
+        for u in [uuid.uuid1() for i in range(10)]:
+            equal(u.variant, uuid.RFC_4122)
+            equal(u.version, 1)
+
+        # Make sure the generated UUIDs are actually unique.
+        uuids = {}
+        for u in [uuid.uuid1() for i in range(1000)]:
+            uuids[u] = 1
+        equal(len(uuids.keys()), 1000)
+
+        # Make sure the supplied node ID appears in the UUID.
+        u = uuid.uuid1(0)
+        equal(u.node, 0)
+        u = uuid.uuid1(0x123456789abc)
+        equal(u.node, 0x123456789abc)
+        u = uuid.uuid1(0xffffffffffff)
+        equal(u.node, 0xffffffffffff)
+
+        # Make sure the supplied clock sequence appears in the UUID.
+        u = uuid.uuid1(0x123456789abc, 0)
+        equal(u.node, 0x123456789abc)
+        equal(((u.clock_seq_hi_variant & 0x3f) << 8) | u.clock_seq_low, 0)
+        u = uuid.uuid1(0x123456789abc, 0x1234)
+        equal(u.node, 0x123456789abc)
+        equal(((u.clock_seq_hi_variant & 0x3f) << 8) |
+                         u.clock_seq_low, 0x1234)
+        u = uuid.uuid1(0x123456789abc, 0x3fff)
+        equal(u.node, 0x123456789abc)
+        equal(((u.clock_seq_hi_variant & 0x3f) << 8) |
+                         u.clock_seq_low, 0x3fff)
+
+    def test_uuid3(self):
+        equal = self.assertEqual
+
+        # Test some known version-3 UUIDs.
+        for u, v in [(uuid.uuid3(uuid.NAMESPACE_DNS, 'python.org'),
+                      '6fa459ea-ee8a-3ca4-894e-db77e160355e'),
+                     (uuid.uuid3(uuid.NAMESPACE_URL, 'http://python.org/'),
+                      '9fe8e8c4-aaa8-32a9-a55c-4535a88b748d'),
+                     (uuid.uuid3(uuid.NAMESPACE_OID, '1.3.6.1'),
+                      'dd1a1cef-13d5-368a-ad82-eca71acd4cd1'),
+                     (uuid.uuid3(uuid.NAMESPACE_X500, 'c=ca'),
+                      '658d3002-db6b-3040-a1d1-8ddd7d189a4d'),
+                    ]:
+            equal(u.variant, uuid.RFC_4122)
+            equal(u.version, 3)
+            equal(u, uuid.UUID(v))
+            equal(str(u), v)
+
+    def test_uuid4(self):
+        equal = self.assertEqual
+
+        # Make sure uuid4() generates UUIDs that are actually version 4.
+        for u in [uuid.uuid4() for i in range(10)]:
+            equal(u.variant, uuid.RFC_4122)
+            equal(u.version, 4)
+
+        # Make sure the generated UUIDs are actually unique.
+        uuids = {}
+        for u in [uuid.uuid4() for i in range(1000)]:
+            uuids[u] = 1
+        equal(len(uuids.keys()), 1000)
+
+    def test_uuid5(self):
+        equal = self.assertEqual
+
+        # Test some known version-5 UUIDs.
+        for u, v in [(uuid.uuid5(uuid.NAMESPACE_DNS, 'python.org'),
+                      '886313e1-3b8a-5372-9b90-0c9aee199e5d'),
+                     (uuid.uuid5(uuid.NAMESPACE_URL, 'http://python.org/'),
+                      '4c565f0d-3f5a-5890-b41b-20cf47701c5e'),
+                     (uuid.uuid5(uuid.NAMESPACE_OID, '1.3.6.1'),
+                      '1447fa61-5277-5fef-a9b3-fbc6e44f4af3'),
+                     (uuid.uuid5(uuid.NAMESPACE_X500, 'c=ca'),
+                      'cc957dd1-a972-5349-98cd-874190002798'),
+                    ]:
+            equal(u.variant, uuid.RFC_4122)
+            equal(u.version, 5)
+            equal(u, uuid.UUID(v))
+            equal(str(u), v)
+
+
+def test_main():
+    test_support.run_unittest(TestUUID)
+
+if __name__ == '__main__':
+    test_main()

Added: vendor/Python/current/Lib/test/test_wait3.py
===================================================================
--- vendor/Python/current/Lib/test/test_wait3.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_wait3.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,38 @@
+"""This test checks for correct wait3() behavior.
+"""
+
+import os
+import time
+from test.fork_wait import ForkWait
+from test.test_support import TestSkipped, run_unittest, reap_children
+
+try:
+    os.fork
+except AttributeError:
+    raise TestSkipped, "os.fork not defined -- skipping test_wait3"
+
+try:
+    os.wait3
+except AttributeError:
+    raise TestSkipped, "os.wait3 not defined -- skipping test_wait3"
+
+class Wait3Test(ForkWait):
+    def wait_impl(self, cpid):
+        for i in range(10):
+            # wait3() shouldn't hang, but some of the buildbots seem to hang
+            # in the forking tests.  This is an attempt to fix the problem.
+            spid, status, rusage = os.wait3(os.WNOHANG)
+            if spid == cpid:
+                break
+            time.sleep(1.0)
+
+        self.assertEqual(spid, cpid)
+        self.assertEqual(status, 0, "cause = %d, exit = %d" % (status&0xff, status>>8))
+        self.assertTrue(rusage)
+
+def test_main():
+    run_unittest(Wait3Test)
+    reap_children()
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_wait4.py
===================================================================
--- vendor/Python/current/Lib/test/test_wait4.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_wait4.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,37 @@
+"""This test checks for correct wait4() behavior.
+"""
+
+import os
+import time
+from test.fork_wait import ForkWait
+from test.test_support import TestSkipped, run_unittest, reap_children
+
+try:
+    os.fork
+except AttributeError:
+    raise TestSkipped, "os.fork not defined -- skipping test_wait4"
+
+try:
+    os.wait4
+except AttributeError:
+    raise TestSkipped, "os.wait4 not defined -- skipping test_wait4"
+
+class Wait4Test(ForkWait):
+    def wait_impl(self, cpid):
+        for i in range(10):
+            # wait4() shouldn't hang, but some of the buildbots seem to hang
+            # in the forking tests.  This is an attempt to fix the problem.
+            spid, status, rusage = os.wait4(cpid, os.WNOHANG)
+            if spid == cpid:
+                break
+            time.sleep(1.0)
+        self.assertEqual(spid, cpid)
+        self.assertEqual(status, 0, "cause = %d, exit = %d" % (status&0xff, status>>8))
+        self.assertTrue(rusage)
+
+def test_main():
+    run_unittest(Wait4Test)
+    reap_children()
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_warnings.py
===================================================================
--- vendor/Python/current/Lib/test/test_warnings.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_warnings.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,105 @@
+import warnings
+import os
+import unittest
+from test import test_support
+
+# The warnings module isn't easily tested, because it relies on module
+# globals to store configuration information.  setUp() and tearDown()
+# preserve the current settings to avoid bashing them while running tests.
+
+# To capture the warning messages, a replacement for showwarning() is
+# used to save warning information in a global variable.
+
+class WarningMessage:
+    "Holds results of latest showwarning() call"
+    pass
+
+def showwarning(message, category, filename, lineno, file=None):
+    msg.message = str(message)
+    msg.category = category.__name__
+    msg.filename = os.path.basename(filename)
+    msg.lineno = lineno
+
+class TestModule(unittest.TestCase):
+
+    def setUp(self):
+        global msg
+        msg = WarningMessage()
+        self._filters = warnings.filters[:]
+        self._showwarning = warnings.showwarning
+        warnings.showwarning = showwarning
+        self.ignored = [w[2].__name__ for w in self._filters
+            if w[0]=='ignore' and w[1] is None and w[3] is None]
+
+    def tearDown(self):
+        warnings.filters = self._filters[:]
+        warnings.showwarning = self._showwarning
+
+    def test_warn_default_category(self):
+        for i in range(4):
+            text = 'multi %d' %i    # Different text on each call
+            warnings.warn(text)
+            self.assertEqual(msg.message, text)
+            self.assertEqual(msg.category, 'UserWarning')
+
+    def test_warn_specific_category(self):
+        text = 'None'
+        for category in [DeprecationWarning, FutureWarning,
+                    PendingDeprecationWarning, RuntimeWarning,
+                    SyntaxWarning, UserWarning, Warning]:
+            if category.__name__ in self.ignored:
+                text = 'filtered out' + category.__name__
+                warnings.warn(text, category)
+                self.assertNotEqual(msg.message, text)
+            else:
+                text = 'unfiltered %s' % category.__name__
+                warnings.warn(text, category)
+                self.assertEqual(msg.message, text)
+                self.assertEqual(msg.category, category.__name__)
+
+    def test_filtering(self):
+
+        warnings.filterwarnings("error", "", Warning, "", 0)
+        self.assertRaises(UserWarning, warnings.warn, 'convert to error')
+
+        warnings.resetwarnings()
+        text = 'handle normally'
+        warnings.warn(text)
+        self.assertEqual(msg.message, text)
+        self.assertEqual(msg.category, 'UserWarning')
+
+        warnings.filterwarnings("ignore", "", Warning, "", 0)
+        text = 'filtered out'
+        warnings.warn(text)
+        self.assertNotEqual(msg.message, text)
+
+        warnings.resetwarnings()
+        warnings.filterwarnings("error", "hex*", Warning, "", 0)
+        self.assertRaises(UserWarning, warnings.warn, 'hex/oct')
+        text = 'nonmatching text'
+        warnings.warn(text)
+        self.assertEqual(msg.message, text)
+        self.assertEqual(msg.category, 'UserWarning')
+
+    def test_options(self):
+        # Uses the private _setoption() function to test the parsing
+        # of command-line warning arguments
+        self.assertRaises(warnings._OptionError,
+                          warnings._setoption, '1:2:3:4:5:6')
+        self.assertRaises(warnings._OptionError,
+                          warnings._setoption, 'bogus::Warning')
+        self.assertRaises(warnings._OptionError,
+                          warnings._setoption, 'ignore:2::4:-5')
+        warnings._setoption('error::Warning::0')
+        self.assertRaises(UserWarning, warnings.warn, 'convert to error')
+
+
+def test_main(verbose=None):
+    # Obscure hack so that this test passes after reloads or repeated calls
+    # to test_main (regrtest -R).
+    if '__warningregistry__' in globals():
+        del globals()['__warningregistry__']
+    test_support.run_unittest(TestModule)
+
+if __name__ == "__main__":
+    test_main(verbose=True)

Added: vendor/Python/current/Lib/test/test_wave.py
===================================================================
--- vendor/Python/current/Lib/test/test_wave.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_wave.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,32 @@
+from test.test_support import TestFailed, TESTFN
+import os
+import wave
+
+def check(t, msg=None):
+    if not t:
+        raise TestFailed, msg
+
+nchannels = 2
+sampwidth = 2
+framerate = 8000
+nframes = 100
+
+f = wave.open(TESTFN, 'wb')
+f.setnchannels(nchannels)
+f.setsampwidth(sampwidth)
+f.setframerate(framerate)
+f.setnframes(nframes)
+output = '\0' * nframes * nchannels * sampwidth
+f.writeframes(output)
+f.close()
+
+f = wave.open(TESTFN, 'rb')
+check(nchannels == f.getnchannels(), "nchannels")
+check(sampwidth == f.getsampwidth(), "sampwidth")
+check(framerate == f.getframerate(), "framerate")
+check(nframes == f.getnframes(), "nframes")
+input = f.readframes(nframes)
+check(input == output, "data")
+f.close()
+
+os.remove(TESTFN)

Added: vendor/Python/current/Lib/test/test_weakref.py
===================================================================
--- vendor/Python/current/Lib/test/test_weakref.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_weakref.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1158 @@
+import gc
+import sys
+import unittest
+import UserList
+import weakref
+
+from test import test_support
+
+# Used in ReferencesTestCase.test_ref_created_during_del() .
+ref_from_del = None
+
+class C:
+    def method(self):
+        pass
+
+
+class Callable:
+    bar = None
+
+    def __call__(self, x):
+        self.bar = x
+
+
+def create_function():
+    def f(): pass
+    return f
+
+def create_bound_method():
+    return C().method
+
+def create_unbound_method():
+    return C.method
+
+
+class TestBase(unittest.TestCase):
+
+    def setUp(self):
+        self.cbcalled = 0
+
+    def callback(self, ref):
+        self.cbcalled += 1
+
+
+class ReferencesTestCase(TestBase):
+
+    def test_basic_ref(self):
+        self.check_basic_ref(C)
+        self.check_basic_ref(create_function)
+        self.check_basic_ref(create_bound_method)
+        self.check_basic_ref(create_unbound_method)
+
+        # Just make sure the tp_repr handler doesn't raise an exception.
+        # Live reference:
+        o = C()
+        wr = weakref.ref(o)
+        `wr`
+        # Dead reference:
+        del o
+        `wr`
+
+    def test_basic_callback(self):
+        self.check_basic_callback(C)
+        self.check_basic_callback(create_function)
+        self.check_basic_callback(create_bound_method)
+        self.check_basic_callback(create_unbound_method)
+
+    def test_multiple_callbacks(self):
+        o = C()
+        ref1 = weakref.ref(o, self.callback)
+        ref2 = weakref.ref(o, self.callback)
+        del o
+        self.assert_(ref1() is None,
+                     "expected reference to be invalidated")
+        self.assert_(ref2() is None,
+                     "expected reference to be invalidated")
+        self.assert_(self.cbcalled == 2,
+                     "callback not called the right number of times")
+
+    def test_multiple_selfref_callbacks(self):
+        # Make sure all references are invalidated before callbacks are called
+        #
+        # What's important here is that we're using the first
+        # reference in the callback invoked on the second reference
+        # (the most recently created ref is cleaned up first).  This
+        # tests that all references to the object are invalidated
+        # before any of the callbacks are invoked, so that we only
+        # have one invocation of _weakref.c:cleanup_helper() active
+        # for a particular object at a time.
+        #
+        def callback(object, self=self):
+            self.ref()
+        c = C()
+        self.ref = weakref.ref(c, callback)
+        ref1 = weakref.ref(c, callback)
+        del c
+
+    def test_proxy_ref(self):
+        o = C()
+        o.bar = 1
+        ref1 = weakref.proxy(o, self.callback)
+        ref2 = weakref.proxy(o, self.callback)
+        del o
+
+        def check(proxy):
+            proxy.bar
+
+        self.assertRaises(weakref.ReferenceError, check, ref1)
+        self.assertRaises(weakref.ReferenceError, check, ref2)
+        self.assertRaises(weakref.ReferenceError, bool, weakref.proxy(C()))
+        self.assert_(self.cbcalled == 2)
+
+    def check_basic_ref(self, factory):
+        o = factory()
+        ref = weakref.ref(o)
+        self.assert_(ref() is not None,
+                     "weak reference to live object should be live")
+        o2 = ref()
+        self.assert_(o is o2,
+                     "<ref>() should return original object if live")
+
+    def check_basic_callback(self, factory):
+        self.cbcalled = 0
+        o = factory()
+        ref = weakref.ref(o, self.callback)
+        del o
+        self.assert_(self.cbcalled == 1,
+                     "callback did not properly set 'cbcalled'")
+        self.assert_(ref() is None,
+                     "ref2 should be dead after deleting object reference")
+
+    def test_ref_reuse(self):
+        o = C()
+        ref1 = weakref.ref(o)
+        # create a proxy to make sure that there's an intervening creation
+        # between these two; it should make no difference
+        proxy = weakref.proxy(o)
+        ref2 = weakref.ref(o)
+        self.assert_(ref1 is ref2,
+                     "reference object w/out callback should be re-used")
+
+        o = C()
+        proxy = weakref.proxy(o)
+        ref1 = weakref.ref(o)
+        ref2 = weakref.ref(o)
+        self.assert_(ref1 is ref2,
+                     "reference object w/out callback should be re-used")
+        self.assert_(weakref.getweakrefcount(o) == 2,
+                     "wrong weak ref count for object")
+        del proxy
+        self.assert_(weakref.getweakrefcount(o) == 1,
+                     "wrong weak ref count for object after deleting proxy")
+
+    def test_proxy_reuse(self):
+        o = C()
+        proxy1 = weakref.proxy(o)
+        ref = weakref.ref(o)
+        proxy2 = weakref.proxy(o)
+        self.assert_(proxy1 is proxy2,
+                     "proxy object w/out callback should have been re-used")
+
+    def test_basic_proxy(self):
+        o = C()
+        self.check_proxy(o, weakref.proxy(o))
+
+        L = UserList.UserList()
+        p = weakref.proxy(L)
+        self.failIf(p, "proxy for empty UserList should be false")
+        p.append(12)
+        self.assertEqual(len(L), 1)
+        self.failUnless(p, "proxy for non-empty UserList should be true")
+        p[:] = [2, 3]
+        self.assertEqual(len(L), 2)
+        self.assertEqual(len(p), 2)
+        self.failUnless(3 in p,
+                        "proxy didn't support __contains__() properly")
+        p[1] = 5
+        self.assertEqual(L[1], 5)
+        self.assertEqual(p[1], 5)
+        L2 = UserList.UserList(L)
+        p2 = weakref.proxy(L2)
+        self.assertEqual(p, p2)
+        ## self.assertEqual(repr(L2), repr(p2))
+        L3 = UserList.UserList(range(10))
+        p3 = weakref.proxy(L3)
+        self.assertEqual(L3[:], p3[:])
+        self.assertEqual(L3[5:], p3[5:])
+        self.assertEqual(L3[:5], p3[:5])
+        self.assertEqual(L3[2:5], p3[2:5])
+
+    # The PyWeakref_* C API is documented as allowing either NULL or
+    # None as the value for the callback, where either means "no
+    # callback".  The "no callback" ref and proxy objects are supposed
+    # to be shared so long as they exist by all callers so long as
+    # they are active.  In Python 2.3.3 and earlier, this guaranttee
+    # was not honored, and was broken in different ways for
+    # PyWeakref_NewRef() and PyWeakref_NewProxy().  (Two tests.)
+
+    def test_shared_ref_without_callback(self):
+        self.check_shared_without_callback(weakref.ref)
+
+    def test_shared_proxy_without_callback(self):
+        self.check_shared_without_callback(weakref.proxy)
+
+    def check_shared_without_callback(self, makeref):
+        o = Object(1)
+        p1 = makeref(o, None)
+        p2 = makeref(o, None)
+        self.assert_(p1 is p2, "both callbacks were None in the C API")
+        del p1, p2
+        p1 = makeref(o)
+        p2 = makeref(o, None)
+        self.assert_(p1 is p2, "callbacks were NULL, None in the C API")
+        del p1, p2
+        p1 = makeref(o)
+        p2 = makeref(o)
+        self.assert_(p1 is p2, "both callbacks were NULL in the C API")
+        del p1, p2
+        p1 = makeref(o, None)
+        p2 = makeref(o)
+        self.assert_(p1 is p2, "callbacks were None, NULL in the C API")
+
+    def test_callable_proxy(self):
+        o = Callable()
+        ref1 = weakref.proxy(o)
+
+        self.check_proxy(o, ref1)
+
+        self.assert_(type(ref1) is weakref.CallableProxyType,
+                     "proxy is not of callable type")
+        ref1('twinkies!')
+        self.assert_(o.bar == 'twinkies!',
+                     "call through proxy not passed through to original")
+        ref1(x='Splat.')
+        self.assert_(o.bar == 'Splat.',
+                     "call through proxy not passed through to original")
+
+        # expect due to too few args
+        self.assertRaises(TypeError, ref1)
+
+        # expect due to too many args
+        self.assertRaises(TypeError, ref1, 1, 2, 3)
+
+    def check_proxy(self, o, proxy):
+        o.foo = 1
+        self.assert_(proxy.foo == 1,
+                     "proxy does not reflect attribute addition")
+        o.foo = 2
+        self.assert_(proxy.foo == 2,
+                     "proxy does not reflect attribute modification")
+        del o.foo
+        self.assert_(not hasattr(proxy, 'foo'),
+                     "proxy does not reflect attribute removal")
+
+        proxy.foo = 1
+        self.assert_(o.foo == 1,
+                     "object does not reflect attribute addition via proxy")
+        proxy.foo = 2
+        self.assert_(
+            o.foo == 2,
+            "object does not reflect attribute modification via proxy")
+        del proxy.foo
+        self.assert_(not hasattr(o, 'foo'),
+                     "object does not reflect attribute removal via proxy")
+
+    def test_proxy_deletion(self):
+        # Test clearing of SF bug #762891
+        class Foo:
+            result = None
+            def __delitem__(self, accessor):
+                self.result = accessor
+        g = Foo()
+        f = weakref.proxy(g)
+        del f[0]
+        self.assertEqual(f.result, 0)
+
+    def test_proxy_bool(self):
+        # Test clearing of SF bug #1170766
+        class List(list): pass
+        lyst = List()
+        self.assertEqual(bool(weakref.proxy(lyst)), bool(lyst))
+
+    def test_getweakrefcount(self):
+        o = C()
+        ref1 = weakref.ref(o)
+        ref2 = weakref.ref(o, self.callback)
+        self.assert_(weakref.getweakrefcount(o) == 2,
+                     "got wrong number of weak reference objects")
+
+        proxy1 = weakref.proxy(o)
+        proxy2 = weakref.proxy(o, self.callback)
+        self.assert_(weakref.getweakrefcount(o) == 4,
+                     "got wrong number of weak reference objects")
+
+        del ref1, ref2, proxy1, proxy2
+        self.assert_(weakref.getweakrefcount(o) == 0,
+                     "weak reference objects not unlinked from"
+                     " referent when discarded.")
+
+        # assumes ints do not support weakrefs
+        self.assert_(weakref.getweakrefcount(1) == 0,
+                     "got wrong number of weak reference objects for int")
+
+    def test_getweakrefs(self):
+        o = C()
+        ref1 = weakref.ref(o, self.callback)
+        ref2 = weakref.ref(o, self.callback)
+        del ref1
+        self.assert_(weakref.getweakrefs(o) == [ref2],
+                     "list of refs does not match")
+
+        o = C()
+        ref1 = weakref.ref(o, self.callback)
+        ref2 = weakref.ref(o, self.callback)
+        del ref2
+        self.assert_(weakref.getweakrefs(o) == [ref1],
+                     "list of refs does not match")
+
+        del ref1
+        self.assert_(weakref.getweakrefs(o) == [],
+                     "list of refs not cleared")
+
+        # assumes ints do not support weakrefs
+        self.assert_(weakref.getweakrefs(1) == [],
+                     "list of refs does not match for int")
+
+    def test_newstyle_number_ops(self):
+        class F(float):
+            pass
+        f = F(2.0)
+        p = weakref.proxy(f)
+        self.assert_(p + 1.0 == 3.0)
+        self.assert_(1.0 + p == 3.0)  # this used to SEGV
+
+    def test_callbacks_protected(self):
+        # Callbacks protected from already-set exceptions?
+        # Regression test for SF bug #478534.
+        class BogusError(Exception):
+            pass
+        data = {}
+        def remove(k):
+            del data[k]
+        def encapsulate():
+            f = lambda : ()
+            data[weakref.ref(f, remove)] = None
+            raise BogusError
+        try:
+            encapsulate()
+        except BogusError:
+            pass
+        else:
+            self.fail("exception not properly restored")
+        try:
+            encapsulate()
+        except BogusError:
+            pass
+        else:
+            self.fail("exception not properly restored")
+
+    def test_sf_bug_840829(self):
+        # "weakref callbacks and gc corrupt memory"
+        # subtype_dealloc erroneously exposed a new-style instance
+        # already in the process of getting deallocated to gc,
+        # causing double-deallocation if the instance had a weakref
+        # callback that triggered gc.
+        # If the bug exists, there probably won't be an obvious symptom
+        # in a release build.  In a debug build, a segfault will occur
+        # when the second attempt to remove the instance from the "list
+        # of all objects" occurs.
+
+        import gc
+
+        class C(object):
+            pass
+
+        c = C()
+        wr = weakref.ref(c, lambda ignore: gc.collect())
+        del c
+
+        # There endeth the first part.  It gets worse.
+        del wr
+
+        c1 = C()
+        c1.i = C()
+        wr = weakref.ref(c1.i, lambda ignore: gc.collect())
+
+        c2 = C()
+        c2.c1 = c1
+        del c1  # still alive because c2 points to it
+
+        # Now when subtype_dealloc gets called on c2, it's not enough just
+        # that c2 is immune from gc while the weakref callbacks associated
+        # with c2 execute (there are none in this 2nd half of the test, btw).
+        # subtype_dealloc goes on to call the base classes' deallocs too,
+        # so any gc triggered by weakref callbacks associated with anything
+        # torn down by a base class dealloc can also trigger double
+        # deallocation of c2.
+        del c2
+
+    def test_callback_in_cycle_1(self):
+        import gc
+
+        class J(object):
+            pass
+
+        class II(object):
+            def acallback(self, ignore):
+                self.J
+
+        I = II()
+        I.J = J
+        I.wr = weakref.ref(J, I.acallback)
+
+        # Now J and II are each in a self-cycle (as all new-style class
+        # objects are, since their __mro__ points back to them).  I holds
+        # both a weak reference (I.wr) and a strong reference (I.J) to class
+        # J.  I is also in a cycle (I.wr points to a weakref that references
+        # I.acallback).  When we del these three, they all become trash, but
+        # the cycles prevent any of them from getting cleaned up immediately.
+        # Instead they have to wait for cyclic gc to deduce that they're
+        # trash.
+        #
+        # gc used to call tp_clear on all of them, and the order in which
+        # it does that is pretty accidental.  The exact order in which we
+        # built up these things manages to provoke gc into running tp_clear
+        # in just the right order (I last).  Calling tp_clear on II leaves
+        # behind an insane class object (its __mro__ becomes NULL).  Calling
+        # tp_clear on J breaks its self-cycle, but J doesn't get deleted
+        # just then because of the strong reference from I.J.  Calling
+        # tp_clear on I starts to clear I's __dict__, and just happens to
+        # clear I.J first -- I.wr is still intact.  That removes the last
+        # reference to J, which triggers the weakref callback.  The callback
+        # tries to do "self.J", and instances of new-style classes look up
+        # attributes ("J") in the class dict first.  The class (II) wants to
+        # search II.__mro__, but that's NULL.   The result was a segfault in
+        # a release build, and an assert failure in a debug build.
+        del I, J, II
+        gc.collect()
+
+    def test_callback_in_cycle_2(self):
+        import gc
+
+        # This is just like test_callback_in_cycle_1, except that II is an
+        # old-style class.  The symptom is different then:  an instance of an
+        # old-style class looks in its own __dict__ first.  'J' happens to
+        # get cleared from I.__dict__ before 'wr', and 'J' was never in II's
+        # __dict__, so the attribute isn't found.  The difference is that
+        # the old-style II doesn't have a NULL __mro__ (it doesn't have any
+        # __mro__), so no segfault occurs.  Instead it got:
+        #    test_callback_in_cycle_2 (__main__.ReferencesTestCase) ...
+        #    Exception exceptions.AttributeError:
+        #   "II instance has no attribute 'J'" in <bound method II.acallback
+        #       of <?.II instance at 0x00B9B4B8>> ignored
+
+        class J(object):
+            pass
+
+        class II:
+            def acallback(self, ignore):
+                self.J
+
+        I = II()
+        I.J = J
+        I.wr = weakref.ref(J, I.acallback)
+
+        del I, J, II
+        gc.collect()
+
+    def test_callback_in_cycle_3(self):
+        import gc
+
+        # This one broke the first patch that fixed the last two.  In this
+        # case, the objects reachable from the callback aren't also reachable
+        # from the object (c1) *triggering* the callback:  you can get to
+        # c1 from c2, but not vice-versa.  The result was that c2's __dict__
+        # got tp_clear'ed by the time the c2.cb callback got invoked.
+
+        class C:
+            def cb(self, ignore):
+                self.me
+                self.c1
+                self.wr
+
+        c1, c2 = C(), C()
+
+        c2.me = c2
+        c2.c1 = c1
+        c2.wr = weakref.ref(c1, c2.cb)
+
+        del c1, c2
+        gc.collect()
+
+    def test_callback_in_cycle_4(self):
+        import gc
+
+        # Like test_callback_in_cycle_3, except c2 and c1 have different
+        # classes.  c2's class (C) isn't reachable from c1 then, so protecting
+        # objects reachable from the dying object (c1) isn't enough to stop
+        # c2's class (C) from getting tp_clear'ed before c2.cb is invoked.
+        # The result was a segfault (C.__mro__ was NULL when the callback
+        # tried to look up self.me).
+
+        class C(object):
+            def cb(self, ignore):
+                self.me
+                self.c1
+                self.wr
+
+        class D:
+            pass
+
+        c1, c2 = D(), C()
+
+        c2.me = c2
+        c2.c1 = c1
+        c2.wr = weakref.ref(c1, c2.cb)
+
+        del c1, c2, C, D
+        gc.collect()
+
+    def test_callback_in_cycle_resurrection(self):
+        import gc
+
+        # Do something nasty in a weakref callback:  resurrect objects
+        # from dead cycles.  For this to be attempted, the weakref and
+        # its callback must also be part of the cyclic trash (else the
+        # objects reachable via the callback couldn't be in cyclic trash
+        # to begin with -- the callback would act like an external root).
+        # But gc clears trash weakrefs with callbacks early now, which
+        # disables the callbacks, so the callbacks shouldn't get called
+        # at all (and so nothing actually gets resurrected).
+
+        alist = []
+        class C(object):
+            def __init__(self, value):
+                self.attribute = value
+
+            def acallback(self, ignore):
+                alist.append(self.c)
+
+        c1, c2 = C(1), C(2)
+        c1.c = c2
+        c2.c = c1
+        c1.wr = weakref.ref(c2, c1.acallback)
+        c2.wr = weakref.ref(c1, c2.acallback)
+
+        def C_went_away(ignore):
+            alist.append("C went away")
+        wr = weakref.ref(C, C_went_away)
+
+        del c1, c2, C   # make them all trash
+        self.assertEqual(alist, [])  # del isn't enough to reclaim anything
+
+        gc.collect()
+        # c1.wr and c2.wr were part of the cyclic trash, so should have
+        # been cleared without their callbacks executing.  OTOH, the weakref
+        # to C is bound to a function local (wr), and wasn't trash, so that
+        # callback should have been invoked when C went away.
+        self.assertEqual(alist, ["C went away"])
+        # The remaining weakref should be dead now (its callback ran).
+        self.assertEqual(wr(), None)
+
+        del alist[:]
+        gc.collect()
+        self.assertEqual(alist, [])
+
+    def test_callbacks_on_callback(self):
+        import gc
+
+        # Set up weakref callbacks *on* weakref callbacks.
+        alist = []
+        def safe_callback(ignore):
+            alist.append("safe_callback called")
+
+        class C(object):
+            def cb(self, ignore):
+                alist.append("cb called")
+
+        c, d = C(), C()
+        c.other = d
+        d.other = c
+        callback = c.cb
+        c.wr = weakref.ref(d, callback)     # this won't trigger
+        d.wr = weakref.ref(callback, d.cb)  # ditto
+        external_wr = weakref.ref(callback, safe_callback)  # but this will
+        self.assert_(external_wr() is callback)
+
+        # The weakrefs attached to c and d should get cleared, so that
+        # C.cb is never called.  But external_wr isn't part of the cyclic
+        # trash, and no cyclic trash is reachable from it, so safe_callback
+        # should get invoked when the bound method object callback (c.cb)
+        # -- which is itself a callback, and also part of the cyclic trash --
+        # gets reclaimed at the end of gc.
+
+        del callback, c, d, C
+        self.assertEqual(alist, [])  # del isn't enough to clean up cycles
+        gc.collect()
+        self.assertEqual(alist, ["safe_callback called"])
+        self.assertEqual(external_wr(), None)
+
+        del alist[:]
+        gc.collect()
+        self.assertEqual(alist, [])
+
+    def test_gc_during_ref_creation(self):
+        self.check_gc_during_creation(weakref.ref)
+
+    def test_gc_during_proxy_creation(self):
+        self.check_gc_during_creation(weakref.proxy)
+
+    def check_gc_during_creation(self, makeref):
+        thresholds = gc.get_threshold()
+        gc.set_threshold(1, 1, 1)
+        gc.collect()
+        class A:
+            pass
+
+        def callback(*args):
+            pass
+
+        referenced = A()
+
+        a = A()
+        a.a = a
+        a.wr = makeref(referenced)
+
+        try:
+            # now make sure the object and the ref get labeled as
+            # cyclic trash:
+            a = A()
+            weakref.ref(referenced, callback)
+
+        finally:
+            gc.set_threshold(*thresholds)
+
+    def test_ref_created_during_del(self):
+        # Bug #1377858
+        # A weakref created in an object's __del__() would crash the
+        # interpreter when the weakref was cleaned up since it would refer to
+        # non-existent memory.  This test should not segfault the interpreter.
+        class Target(object):
+            def __del__(self):
+                global ref_from_del
+                ref_from_del = weakref.ref(self)
+
+        w = Target()
+
+
+class SubclassableWeakrefTestCase(unittest.TestCase):
+
+    def test_subclass_refs(self):
+        class MyRef(weakref.ref):
+            def __init__(self, ob, callback=None, value=42):
+                self.value = value
+                super(MyRef, self).__init__(ob, callback)
+            def __call__(self):
+                self.called = True
+                return super(MyRef, self).__call__()
+        o = Object("foo")
+        mr = MyRef(o, value=24)
+        self.assert_(mr() is o)
+        self.assert_(mr.called)
+        self.assertEqual(mr.value, 24)
+        del o
+        self.assert_(mr() is None)
+        self.assert_(mr.called)
+
+    def test_subclass_refs_dont_replace_standard_refs(self):
+        class MyRef(weakref.ref):
+            pass
+        o = Object(42)
+        r1 = MyRef(o)
+        r2 = weakref.ref(o)
+        self.assert_(r1 is not r2)
+        self.assertEqual(weakref.getweakrefs(o), [r2, r1])
+        self.assertEqual(weakref.getweakrefcount(o), 2)
+        r3 = MyRef(o)
+        self.assertEqual(weakref.getweakrefcount(o), 3)
+        refs = weakref.getweakrefs(o)
+        self.assertEqual(len(refs), 3)
+        self.assert_(r2 is refs[0])
+        self.assert_(r1 in refs[1:])
+        self.assert_(r3 in refs[1:])
+
+    def test_subclass_refs_dont_conflate_callbacks(self):
+        class MyRef(weakref.ref):
+            pass
+        o = Object(42)
+        r1 = MyRef(o, id)
+        r2 = MyRef(o, str)
+        self.assert_(r1 is not r2)
+        refs = weakref.getweakrefs(o)
+        self.assert_(r1 in refs)
+        self.assert_(r2 in refs)
+
+    def test_subclass_refs_with_slots(self):
+        class MyRef(weakref.ref):
+            __slots__ = "slot1", "slot2"
+            def __new__(type, ob, callback, slot1, slot2):
+                return weakref.ref.__new__(type, ob, callback)
+            def __init__(self, ob, callback, slot1, slot2):
+                self.slot1 = slot1
+                self.slot2 = slot2
+            def meth(self):
+                return self.slot1 + self.slot2
+        o = Object(42)
+        r = MyRef(o, None, "abc", "def")
+        self.assertEqual(r.slot1, "abc")
+        self.assertEqual(r.slot2, "def")
+        self.assertEqual(r.meth(), "abcdef")
+        self.failIf(hasattr(r, "__dict__"))
+
+
+class Object:
+    def __init__(self, arg):
+        self.arg = arg
+    def __repr__(self):
+        return "<Object %r>" % self.arg
+
+
+class MappingTestCase(TestBase):
+
+    COUNT = 10
+
+    def test_weak_values(self):
+        #
+        #  This exercises d.copy(), d.items(), d[], del d[], len(d).
+        #
+        dict, objects = self.make_weak_valued_dict()
+        for o in objects:
+            self.assert_(weakref.getweakrefcount(o) == 1,
+                         "wrong number of weak references to %r!" % o)
+            self.assert_(o is dict[o.arg],
+                         "wrong object returned by weak dict!")
+        items1 = dict.items()
+        items2 = dict.copy().items()
+        items1.sort()
+        items2.sort()
+        self.assert_(items1 == items2,
+                     "cloning of weak-valued dictionary did not work!")
+        del items1, items2
+        self.assert_(len(dict) == self.COUNT)
+        del objects[0]
+        self.assert_(len(dict) == (self.COUNT - 1),
+                     "deleting object did not cause dictionary update")
+        del objects, o
+        self.assert_(len(dict) == 0,
+                     "deleting the values did not clear the dictionary")
+        # regression on SF bug #447152:
+        dict = weakref.WeakValueDictionary()
+        self.assertRaises(KeyError, dict.__getitem__, 1)
+        dict[2] = C()
+        self.assertRaises(KeyError, dict.__getitem__, 2)
+
+    def test_weak_keys(self):
+        #
+        #  This exercises d.copy(), d.items(), d[] = v, d[], del d[],
+        #  len(d), d.has_key().
+        #
+        dict, objects = self.make_weak_keyed_dict()
+        for o in objects:
+            self.assert_(weakref.getweakrefcount(o) == 1,
+                         "wrong number of weak references to %r!" % o)
+            self.assert_(o.arg is dict[o],
+                         "wrong object returned by weak dict!")
+        items1 = dict.items()
+        items2 = dict.copy().items()
+        self.assert_(set(items1) == set(items2),
+                     "cloning of weak-keyed dictionary did not work!")
+        del items1, items2
+        self.assert_(len(dict) == self.COUNT)
+        del objects[0]
+        self.assert_(len(dict) == (self.COUNT - 1),
+                     "deleting object did not cause dictionary update")
+        del objects, o
+        self.assert_(len(dict) == 0,
+                     "deleting the keys did not clear the dictionary")
+        o = Object(42)
+        dict[o] = "What is the meaning of the universe?"
+        self.assert_(dict.has_key(o))
+        self.assert_(not dict.has_key(34))
+
+    def test_weak_keyed_iters(self):
+        dict, objects = self.make_weak_keyed_dict()
+        self.check_iters(dict)
+
+        # Test keyrefs()
+        refs = dict.keyrefs()
+        self.assertEqual(len(refs), len(objects))
+        objects2 = list(objects)
+        for wr in refs:
+            ob = wr()
+            self.assert_(dict.has_key(ob))
+            self.assert_(ob in dict)
+            self.assertEqual(ob.arg, dict[ob])
+            objects2.remove(ob)
+        self.assertEqual(len(objects2), 0)
+
+        # Test iterkeyrefs()
+        objects2 = list(objects)
+        self.assertEqual(len(list(dict.iterkeyrefs())), len(objects))
+        for wr in dict.iterkeyrefs():
+            ob = wr()
+            self.assert_(dict.has_key(ob))
+            self.assert_(ob in dict)
+            self.assertEqual(ob.arg, dict[ob])
+            objects2.remove(ob)
+        self.assertEqual(len(objects2), 0)
+
+    def test_weak_valued_iters(self):
+        dict, objects = self.make_weak_valued_dict()
+        self.check_iters(dict)
+
+        # Test valuerefs()
+        refs = dict.valuerefs()
+        self.assertEqual(len(refs), len(objects))
+        objects2 = list(objects)
+        for wr in refs:
+            ob = wr()
+            self.assertEqual(ob, dict[ob.arg])
+            self.assertEqual(ob.arg, dict[ob.arg].arg)
+            objects2.remove(ob)
+        self.assertEqual(len(objects2), 0)
+
+        # Test itervaluerefs()
+        objects2 = list(objects)
+        self.assertEqual(len(list(dict.itervaluerefs())), len(objects))
+        for wr in dict.itervaluerefs():
+            ob = wr()
+            self.assertEqual(ob, dict[ob.arg])
+            self.assertEqual(ob.arg, dict[ob.arg].arg)
+            objects2.remove(ob)
+        self.assertEqual(len(objects2), 0)
+
+    def check_iters(self, dict):
+        # item iterator:
+        items = dict.items()
+        for item in dict.iteritems():
+            items.remove(item)
+        self.assert_(len(items) == 0, "iteritems() did not touch all items")
+
+        # key iterator, via __iter__():
+        keys = dict.keys()
+        for k in dict:
+            keys.remove(k)
+        self.assert_(len(keys) == 0, "__iter__() did not touch all keys")
+
+        # key iterator, via iterkeys():
+        keys = dict.keys()
+        for k in dict.iterkeys():
+            keys.remove(k)
+        self.assert_(len(keys) == 0, "iterkeys() did not touch all keys")
+
+        # value iterator:
+        values = dict.values()
+        for v in dict.itervalues():
+            values.remove(v)
+        self.assert_(len(values) == 0,
+                     "itervalues() did not touch all values")
+
+    def test_make_weak_keyed_dict_from_dict(self):
+        o = Object(3)
+        dict = weakref.WeakKeyDictionary({o:364})
+        self.assert_(dict[o] == 364)
+
+    def test_make_weak_keyed_dict_from_weak_keyed_dict(self):
+        o = Object(3)
+        dict = weakref.WeakKeyDictionary({o:364})
+        dict2 = weakref.WeakKeyDictionary(dict)
+        self.assert_(dict[o] == 364)
+
+    def make_weak_keyed_dict(self):
+        dict = weakref.WeakKeyDictionary()
+        objects = map(Object, range(self.COUNT))
+        for o in objects:
+            dict[o] = o.arg
+        return dict, objects
+
+    def make_weak_valued_dict(self):
+        dict = weakref.WeakValueDictionary()
+        objects = map(Object, range(self.COUNT))
+        for o in objects:
+            dict[o.arg] = o
+        return dict, objects
+
+    def check_popitem(self, klass, key1, value1, key2, value2):
+        weakdict = klass()
+        weakdict[key1] = value1
+        weakdict[key2] = value2
+        self.assert_(len(weakdict) == 2)
+        k, v = weakdict.popitem()
+        self.assert_(len(weakdict) == 1)
+        if k is key1:
+            self.assert_(v is value1)
+        else:
+            self.assert_(v is value2)
+        k, v = weakdict.popitem()
+        self.assert_(len(weakdict) == 0)
+        if k is key1:
+            self.assert_(v is value1)
+        else:
+            self.assert_(v is value2)
+
+    def test_weak_valued_dict_popitem(self):
+        self.check_popitem(weakref.WeakValueDictionary,
+                           "key1", C(), "key2", C())
+
+    def test_weak_keyed_dict_popitem(self):
+        self.check_popitem(weakref.WeakKeyDictionary,
+                           C(), "value 1", C(), "value 2")
+
+    def check_setdefault(self, klass, key, value1, value2):
+        self.assert_(value1 is not value2,
+                     "invalid test"
+                     " -- value parameters must be distinct objects")
+        weakdict = klass()
+        o = weakdict.setdefault(key, value1)
+        self.assert_(o is value1)
+        self.assert_(weakdict.has_key(key))
+        self.assert_(weakdict.get(key) is value1)
+        self.assert_(weakdict[key] is value1)
+
+        o = weakdict.setdefault(key, value2)
+        self.assert_(o is value1)
+        self.assert_(weakdict.has_key(key))
+        self.assert_(weakdict.get(key) is value1)
+        self.assert_(weakdict[key] is value1)
+
+    def test_weak_valued_dict_setdefault(self):
+        self.check_setdefault(weakref.WeakValueDictionary,
+                              "key", C(), C())
+
+    def test_weak_keyed_dict_setdefault(self):
+        self.check_setdefault(weakref.WeakKeyDictionary,
+                              C(), "value 1", "value 2")
+
+    def check_update(self, klass, dict):
+        #
+        #  This exercises d.update(), len(d), d.keys(), d.has_key(),
+        #  d.get(), d[].
+        #
+        weakdict = klass()
+        weakdict.update(dict)
+        self.assert_(len(weakdict) == len(dict))
+        for k in weakdict.keys():
+            self.assert_(dict.has_key(k),
+                         "mysterious new key appeared in weak dict")
+            v = dict.get(k)
+            self.assert_(v is weakdict[k])
+            self.assert_(v is weakdict.get(k))
+        for k in dict.keys():
+            self.assert_(weakdict.has_key(k),
+                         "original key disappeared in weak dict")
+            v = dict[k]
+            self.assert_(v is weakdict[k])
+            self.assert_(v is weakdict.get(k))
+
+    def test_weak_valued_dict_update(self):
+        self.check_update(weakref.WeakValueDictionary,
+                          {1: C(), 'a': C(), C(): C()})
+
+    def test_weak_keyed_dict_update(self):
+        self.check_update(weakref.WeakKeyDictionary,
+                          {C(): 1, C(): 2, C(): 3})
+
+    def test_weak_keyed_delitem(self):
+        d = weakref.WeakKeyDictionary()
+        o1 = Object('1')
+        o2 = Object('2')
+        d[o1] = 'something'
+        d[o2] = 'something'
+        self.assert_(len(d) == 2)
+        del d[o1]
+        self.assert_(len(d) == 1)
+        self.assert_(d.keys() == [o2])
+
+    def test_weak_valued_delitem(self):
+        d = weakref.WeakValueDictionary()
+        o1 = Object('1')
+        o2 = Object('2')
+        d['something'] = o1
+        d['something else'] = o2
+        self.assert_(len(d) == 2)
+        del d['something']
+        self.assert_(len(d) == 1)
+        self.assert_(d.items() == [('something else', o2)])
+
+    def test_weak_keyed_bad_delitem(self):
+        d = weakref.WeakKeyDictionary()
+        o = Object('1')
+        # An attempt to delete an object that isn't there should raise
+        # KeyError.  It didn't before 2.3.
+        self.assertRaises(KeyError, d.__delitem__, o)
+        self.assertRaises(KeyError, d.__getitem__, o)
+
+        # If a key isn't of a weakly referencable type, __getitem__ and
+        # __setitem__ raise TypeError.  __delitem__ should too.
+        self.assertRaises(TypeError, d.__delitem__,  13)
+        self.assertRaises(TypeError, d.__getitem__,  13)
+        self.assertRaises(TypeError, d.__setitem__,  13, 13)
+
+    def test_weak_keyed_cascading_deletes(self):
+        # SF bug 742860.  For some reason, before 2.3 __delitem__ iterated
+        # over the keys via self.data.iterkeys().  If things vanished from
+        # the dict during this (or got added), that caused a RuntimeError.
+
+        d = weakref.WeakKeyDictionary()
+        mutate = False
+
+        class C(object):
+            def __init__(self, i):
+                self.value = i
+            def __hash__(self):
+                return hash(self.value)
+            def __eq__(self, other):
+                if mutate:
+                    # Side effect that mutates the dict, by removing the
+                    # last strong reference to a key.
+                    del objs[-1]
+                return self.value == other.value
+
+        objs = [C(i) for i in range(4)]
+        for o in objs:
+            d[o] = o.value
+        del o   # now the only strong references to keys are in objs
+        # Find the order in which iterkeys sees the keys.
+        objs = d.keys()
+        # Reverse it, so that the iteration implementation of __delitem__
+        # has to keep looping to find the first object we delete.
+        objs.reverse()
+
+        # Turn on mutation in C.__eq__.  The first time thru the loop,
+        # under the iterkeys() business the first comparison will delete
+        # the last item iterkeys() would see, and that causes a
+        #     RuntimeError: dictionary changed size during iteration
+        # when the iterkeys() loop goes around to try comparing the next
+        # key.  After this was fixed, it just deletes the last object *our*
+        # "for o in obj" loop would have gotten to.
+        mutate = True
+        count = 0
+        for o in objs:
+            count += 1
+            del d[o]
+        self.assertEqual(len(d), 0)
+        self.assertEqual(count, 2)
+
+from test import mapping_tests
+
+class WeakValueDictionaryTestCase(mapping_tests.BasicTestMappingProtocol):
+    """Check that WeakValueDictionary conforms to the mapping protocol"""
+    __ref = {"key1":Object(1), "key2":Object(2), "key3":Object(3)}
+    type2test = weakref.WeakValueDictionary
+    def _reference(self):
+        return self.__ref.copy()
+
+class WeakKeyDictionaryTestCase(mapping_tests.BasicTestMappingProtocol):
+    """Check that WeakKeyDictionary conforms to the mapping protocol"""
+    __ref = {Object("key1"):1, Object("key2"):2, Object("key3"):3}
+    type2test = weakref.WeakKeyDictionary
+    def _reference(self):
+        return self.__ref.copy()
+
+libreftest = """ Doctest for examples in the library reference: libweakref.tex
+
+>>> import weakref
+>>> class Dict(dict):
+...     pass
+...
+>>> obj = Dict(red=1, green=2, blue=3)   # this object is weak referencable
+>>> r = weakref.ref(obj)
+>>> print r() is obj
+True
+
+>>> import weakref
+>>> class Object:
+...     pass
+...
+>>> o = Object()
+>>> r = weakref.ref(o)
+>>> o2 = r()
+>>> o is o2
+True
+>>> del o, o2
+>>> print r()
+None
+
+>>> import weakref
+>>> class ExtendedRef(weakref.ref):
+...     def __init__(self, ob, callback=None, **annotations):
+...         super(ExtendedRef, self).__init__(ob, callback)
+...         self.__counter = 0
+...         for k, v in annotations.iteritems():
+...             setattr(self, k, v)
+...     def __call__(self):
+...         '''Return a pair containing the referent and the number of
+...         times the reference has been called.
+...         '''
+...         ob = super(ExtendedRef, self).__call__()
+...         if ob is not None:
+...             self.__counter += 1
+...             ob = (ob, self.__counter)
+...         return ob
+...
+>>> class A:   # not in docs from here, just testing the ExtendedRef
+...     pass
+...
+>>> a = A()
+>>> r = ExtendedRef(a, foo=1, bar="baz")
+>>> r.foo
+1
+>>> r.bar
+'baz'
+>>> r()[1]
+1
+>>> r()[1]
+2
+>>> r()[0] is a
+True
+
+
+>>> import weakref
+>>> _id2obj_dict = weakref.WeakValueDictionary()
+>>> def remember(obj):
+...     oid = id(obj)
+...     _id2obj_dict[oid] = obj
+...     return oid
+...
+>>> def id2obj(oid):
+...     return _id2obj_dict[oid]
+...
+>>> a = A()             # from here, just testing
+>>> a_id = remember(a)
+>>> id2obj(a_id) is a
+True
+>>> del a
+>>> try:
+...     id2obj(a_id)
+... except KeyError:
+...     print 'OK'
+... else:
+...     print 'WeakValueDictionary error'
+OK
+
+"""
+
+__test__ = {'libreftest' : libreftest}
+
+def test_main():
+    test_support.run_unittest(
+        ReferencesTestCase,
+        MappingTestCase,
+        WeakValueDictionaryTestCase,
+        WeakKeyDictionaryTestCase,
+        )
+    test_support.run_doctest(sys.modules[__name__])
+
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_whichdb.py
===================================================================
--- vendor/Python/current/Lib/test/test_whichdb.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_whichdb.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,66 @@
+#! /usr/bin/env python
+"""Test script for the whichdb module
+   based on test_anydbm.py
+"""
+
+import os
+import test.test_support
+import unittest
+import whichdb
+import anydbm
+import tempfile
+import glob
+
+_fname = test.test_support.TESTFN
+
+def _delete_files():
+    # we don't know the precise name the underlying database uses
+    # so we use glob to locate all names
+    for f in glob.glob(_fname + "*"):
+        try:
+            os.unlink(f)
+        except OSError:
+            pass
+
+class WhichDBTestCase(unittest.TestCase):
+    # Actual test methods are added to namespace
+    # after class definition.
+    def __init__(self, *args):
+        unittest.TestCase.__init__(self, *args)
+
+    def tearDown(self):
+        _delete_files()
+
+    def setUp(self):
+        _delete_files()
+
+for name in anydbm._names:
+    # we define a new test method for each
+    # candidate database module.
+    try:
+        mod = __import__(name)
+    except ImportError:
+        continue
+
+    def test_whichdb_name(self, name=name, mod=mod):
+        # Check whether whichdb correctly guesses module name
+        # for databases opened with module mod.
+        # Try with empty files first
+        f = mod.open(_fname, 'c')
+        f.close()
+        self.assertEqual(name, whichdb.whichdb(_fname))
+        # Now add a key
+        f = mod.open(_fname, 'w')
+        f["1"] = "1"
+        f.close()
+        self.assertEqual(name, whichdb.whichdb(_fname))
+    setattr(WhichDBTestCase,"test_whichdb_%s" % name, test_whichdb_name)
+
+def test_main():
+    try:
+        test.test_support.run_unittest(WhichDBTestCase)
+    finally:
+        _delete_files()
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_winreg.py
===================================================================
--- vendor/Python/current/Lib/test/test_winreg.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_winreg.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,156 @@
+# Test the windows specific win32reg module.
+# Only win32reg functions not hit here: FlushKey, LoadKey and SaveKey
+
+from _winreg import *
+import os, sys
+
+from test.test_support import verify, have_unicode
+
+test_key_name = "SOFTWARE\\Python Registry Test Key - Delete Me"
+
+test_data = [
+    ("Int Value",     45,                                      REG_DWORD),
+    ("String Val",    "A string value",                        REG_SZ),
+    ("StringExpand",  "The path is %path%",                    REG_EXPAND_SZ),
+    ("Multi-string",  ["Lots", "of", "string", "values"],      REG_MULTI_SZ),
+    ("Raw Data",      ("binary"+chr(0)+"data"),                REG_BINARY),
+    ("Big String",    "x"*(2**14-1),                           REG_SZ),
+    ("Big Binary",    "x"*(2**14),                             REG_BINARY),
+]
+if have_unicode:
+    test_data+=[
+    (unicode("Unicode Val"),  unicode("A Unicode value"),                      REG_SZ,),
+    ("UnicodeExpand", unicode("The path is %path%"),                   REG_EXPAND_SZ),
+    ("Multi-unicode", [unicode("Lots"), unicode("of"), unicode("unicode"), unicode("values")], REG_MULTI_SZ),
+    ("Multi-mixed",   [unicode("Unicode"), unicode("and"), "string", "values"],REG_MULTI_SZ),
+    ]
+
+def WriteTestData(root_key):
+    # Set the default value for this key.
+    SetValue(root_key, test_key_name, REG_SZ, "Default value")
+    key = CreateKey(root_key, test_key_name)
+    # Create a sub-key
+    sub_key = CreateKey(key, "sub_key")
+    # Give the sub-key some named values
+
+    for value_name, value_data, value_type in test_data:
+        SetValueEx(sub_key, value_name, 0, value_type, value_data)
+
+    # Check we wrote as many items as we thought.
+    nkeys, nvalues, since_mod = QueryInfoKey(key)
+    verify(nkeys==1, "Not the correct number of sub keys")
+    verify(nvalues==1, "Not the correct number of values")
+    nkeys, nvalues, since_mod = QueryInfoKey(sub_key)
+    verify(nkeys==0, "Not the correct number of sub keys")
+    verify(nvalues==len(test_data), "Not the correct number of values")
+    # Close this key this way...
+    # (but before we do, copy the key as an integer - this allows
+    # us to test that the key really gets closed).
+    int_sub_key = int(sub_key)
+    CloseKey(sub_key)
+    try:
+        QueryInfoKey(int_sub_key)
+        raise RuntimeError, "It appears the CloseKey() function does not close the actual key!"
+    except EnvironmentError:
+        pass
+    # ... and close that key that way :-)
+    int_key = int(key)
+    key.Close()
+    try:
+        QueryInfoKey(int_key)
+        raise RuntimeError, "It appears the key.Close() function does not close the actual key!"
+    except EnvironmentError:
+        pass
+
+def ReadTestData(root_key):
+    # Check we can get default value for this key.
+    val = QueryValue(root_key, test_key_name)
+    verify(val=="Default value", "Registry didn't give back the correct value")
+
+    key = OpenKey(root_key, test_key_name)
+    # Read the sub-keys
+    sub_key = OpenKey(key, "sub_key")
+    # Check I can enumerate over the values.
+    index = 0
+    while 1:
+        try:
+            data = EnumValue(sub_key, index)
+        except EnvironmentError:
+            break
+        verify(data in test_data, "Didn't read back the correct test data")
+        index = index + 1
+    verify(index==len(test_data), "Didn't read the correct number of items")
+    # Check I can directly access each item
+    for value_name, value_data, value_type in test_data:
+        read_val, read_typ = QueryValueEx(sub_key, value_name)
+        verify(read_val==value_data and read_typ == value_type, \
+               "Could not directly read the value" )
+    sub_key.Close()
+    # Enumerate our main key.
+    read_val = EnumKey(key, 0)
+    verify(read_val == "sub_key", "Read subkey value wrong")
+    try:
+        EnumKey(key, 1)
+        verify(0, "Was able to get a second key when I only have one!")
+    except EnvironmentError:
+        pass
+
+    key.Close()
+
+def DeleteTestData(root_key):
+    key = OpenKey(root_key, test_key_name, 0, KEY_ALL_ACCESS)
+    sub_key = OpenKey(key, "sub_key", 0, KEY_ALL_ACCESS)
+    # It is not necessary to delete the values before deleting
+    # the key (although subkeys must not exist).  We delete them
+    # manually just to prove we can :-)
+    for value_name, value_data, value_type in test_data:
+        DeleteValue(sub_key, value_name)
+
+    nkeys, nvalues, since_mod = QueryInfoKey(sub_key)
+    verify(nkeys==0 and nvalues==0, "subkey not empty before delete")
+    sub_key.Close()
+    DeleteKey(key, "sub_key")
+
+    try:
+        # Shouldnt be able to delete it twice!
+        DeleteKey(key, "sub_key")
+        verify(0, "Deleting the key twice succeeded")
+    except EnvironmentError:
+        pass
+    key.Close()
+    DeleteKey(root_key, test_key_name)
+    # Opening should now fail!
+    try:
+        key = OpenKey(root_key, test_key_name)
+        verify(0, "Could open the non-existent key")
+    except WindowsError: # Use this error name this time
+        pass
+
+def TestAll(root_key):
+    WriteTestData(root_key)
+    ReadTestData(root_key)
+    DeleteTestData(root_key)
+
+# Test on my local machine.
+TestAll(HKEY_CURRENT_USER)
+print "Local registry tests worked"
+try:
+    remote_name = sys.argv[sys.argv.index("--remote")+1]
+except (IndexError, ValueError):
+    remote_name = None
+
+if remote_name is not None:
+    try:
+        remote_key = ConnectRegistry(remote_name, HKEY_CURRENT_USER)
+    except EnvironmentError, exc:
+        print "Could not connect to the remote machine -", exc.strerror
+        remote_key = None
+    if remote_key is not None:
+        TestAll(remote_key)
+        print "Remote registry tests worked"
+else:
+    print "Remote registry calls can be tested using",
+    print "'test_winreg.py --remote \\\\machine_name'"
+    # perform minimal ConnectRegistry test which just invokes it
+    h = ConnectRegistry(None, HKEY_LOCAL_MACHINE)
+    h.Close()

Added: vendor/Python/current/Lib/test/test_winsound.py
===================================================================
--- vendor/Python/current/Lib/test/test_winsound.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_winsound.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,209 @@
+# Ridiculously simple test of the winsound module for Windows.
+
+import unittest
+from test import test_support
+import winsound, time
+import os
+import subprocess
+
+
+class BeepTest(unittest.TestCase):
+
+    def test_errors(self):
+        self.assertRaises(TypeError, winsound.Beep)
+        self.assertRaises(ValueError, winsound.Beep, 36, 75)
+        self.assertRaises(ValueError, winsound.Beep, 32768, 75)
+
+    def test_extremes(self):
+        winsound.Beep(37, 75)
+        winsound.Beep(32767, 75)
+
+    def test_increasingfrequency(self):
+        for i in xrange(100, 2000, 100):
+            winsound.Beep(i, 75)
+
+class MessageBeepTest(unittest.TestCase):
+
+    def tearDown(self):
+        time.sleep(0.5)
+
+    def test_default(self):
+        self.assertRaises(TypeError, winsound.MessageBeep, "bad")
+        self.assertRaises(TypeError, winsound.MessageBeep, 42, 42)
+        winsound.MessageBeep()
+
+    def test_ok(self):
+        winsound.MessageBeep(winsound.MB_OK)
+
+    def test_asterisk(self):
+        winsound.MessageBeep(winsound.MB_ICONASTERISK)
+
+    def test_exclamation(self):
+        winsound.MessageBeep(winsound.MB_ICONEXCLAMATION)
+
+    def test_hand(self):
+        winsound.MessageBeep(winsound.MB_ICONHAND)
+
+    def test_question(self):
+        winsound.MessageBeep(winsound.MB_ICONQUESTION)
+
+
+class PlaySoundTest(unittest.TestCase):
+
+    def test_errors(self):
+        self.assertRaises(TypeError, winsound.PlaySound)
+        self.assertRaises(TypeError, winsound.PlaySound, "bad", "bad")
+        self.assertRaises(
+            RuntimeError,
+            winsound.PlaySound,
+            "none", winsound.SND_ASYNC | winsound.SND_MEMORY
+        )
+
+    def test_alias_asterisk(self):
+        if _have_soundcard():
+            winsound.PlaySound('SystemAsterisk', winsound.SND_ALIAS)
+        else:
+            self.assertRaises(
+                RuntimeError,
+                winsound.PlaySound,
+                'SystemAsterisk', winsound.SND_ALIAS
+            )
+
+    def test_alias_exclamation(self):
+        if _have_soundcard():
+            winsound.PlaySound('SystemExclamation', winsound.SND_ALIAS)
+        else:
+            self.assertRaises(
+                RuntimeError,
+                winsound.PlaySound,
+                'SystemExclamation', winsound.SND_ALIAS
+            )
+
+    def test_alias_exit(self):
+        if _have_soundcard():
+            winsound.PlaySound('SystemExit', winsound.SND_ALIAS)
+        else:
+            self.assertRaises(
+                RuntimeError,
+                winsound.PlaySound,
+                'SystemExit', winsound.SND_ALIAS
+            )
+
+    def test_alias_hand(self):
+        if _have_soundcard():
+            winsound.PlaySound('SystemHand', winsound.SND_ALIAS)
+        else:
+            self.assertRaises(
+                RuntimeError,
+                winsound.PlaySound,
+                'SystemHand', winsound.SND_ALIAS
+            )
+
+    def test_alias_question(self):
+        if _have_soundcard():
+            winsound.PlaySound('SystemQuestion', winsound.SND_ALIAS)
+        else:
+            self.assertRaises(
+                RuntimeError,
+                winsound.PlaySound,
+                'SystemQuestion', winsound.SND_ALIAS
+            )
+
+    def test_alias_fallback(self):
+        # This test can't be expected to work on all systems.  The MS
+        # PlaySound() docs say:
+        #
+        #     If it cannot find the specified sound, PlaySound uses the
+        #     default system event sound entry instead.  If the function
+        #     can find neither the system default entry nor the default
+        #     sound, it makes no sound and returns FALSE.
+        #
+        # It's known to return FALSE on some real systems.
+
+        # winsound.PlaySound('!"$%&/(#+*', winsound.SND_ALIAS)
+        return
+
+    def test_alias_nofallback(self):
+        if _have_soundcard():
+            # Note that this is not the same as asserting RuntimeError
+            # will get raised:  you cannot convert this to
+            # self.assertRaises(...) form.  The attempt may or may not
+            # raise RuntimeError, but it shouldn't raise anything other
+            # than RuntimeError, and that's all we're trying to test
+            # here.  The MS docs aren't clear about whether the SDK
+            # PlaySound() with SND_ALIAS and SND_NODEFAULT will return
+            # True or False when the alias is unknown.  On Tim's WinXP
+            # box today, it returns True (no exception is raised).  What
+            # we'd really like to test is that no sound is played, but
+            # that requires first wiring an eardrum class into unittest
+            # <wink>.
+            try:
+                winsound.PlaySound(
+                    '!"$%&/(#+*',
+                    winsound.SND_ALIAS | winsound.SND_NODEFAULT
+                )
+            except RuntimeError:
+                pass
+        else:
+            self.assertRaises(
+                RuntimeError,
+                winsound.PlaySound,
+                '!"$%&/(#+*', winsound.SND_ALIAS | winsound.SND_NODEFAULT
+            )
+
+    def test_stopasync(self):
+        if _have_soundcard():
+            winsound.PlaySound(
+                'SystemQuestion',
+                winsound.SND_ALIAS | winsound.SND_ASYNC | winsound.SND_LOOP
+            )
+            time.sleep(0.5)
+            try:
+                winsound.PlaySound(
+                    'SystemQuestion',
+                    winsound.SND_ALIAS | winsound.SND_NOSTOP
+                )
+            except RuntimeError:
+                pass
+            else: # the first sound might already be finished
+                pass
+            winsound.PlaySound(None, winsound.SND_PURGE)
+        else:
+            self.assertRaises(
+                RuntimeError,
+                winsound.PlaySound,
+                None, winsound.SND_PURGE
+            )
+
+
+def _get_cscript_path():
+    """Return the full path to cscript.exe or None."""
+    for dir in os.environ.get("PATH", "").split(os.pathsep):
+        cscript_path = os.path.join(dir, "cscript.exe")
+        if os.path.exists(cscript_path):
+            return cscript_path
+
+__have_soundcard_cache = None
+def _have_soundcard():
+    """Return True iff this computer has a soundcard."""
+    global __have_soundcard_cache
+    if __have_soundcard_cache is None:
+        cscript_path = _get_cscript_path()
+        if cscript_path is None:
+            # Could not find cscript.exe to run our VBScript helper. Default
+            # to True: most computers these days *do* have a soundcard.
+            return True
+
+        check_script = os.path.join(os.path.dirname(__file__),
+                                    "check_soundcard.vbs")
+        p = subprocess.Popen([cscript_path, check_script],
+                             stdout=subprocess.PIPE)
+        __have_soundcard_cache = not p.wait()
+    return __have_soundcard_cache
+
+
+def test_main():
+    test_support.run_unittest(BeepTest, MessageBeepTest, PlaySoundTest)
+
+if __name__=="__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_with.py
===================================================================
--- vendor/Python/current/Lib/test/test_with.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_with.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,620 @@
+#!/usr/bin/env python
+
+"""Unit tests for the with statement specified in PEP 343."""
+
+from __future__ import with_statement
+
+__author__ = "Mike Bland"
+__email__ = "mbland at acm dot org"
+
+import sys
+import unittest
+from collections import deque
+from contextlib import GeneratorContextManager, contextmanager
+from test.test_support import run_unittest
+
+
+class MockContextManager(GeneratorContextManager):
+    def __init__(self, gen):
+        GeneratorContextManager.__init__(self, gen)
+        self.enter_called = False
+        self.exit_called = False
+        self.exit_args = None
+
+    def __enter__(self):
+        self.enter_called = True
+        return GeneratorContextManager.__enter__(self)
+
+    def __exit__(self, type, value, traceback):
+        self.exit_called = True
+        self.exit_args = (type, value, traceback)
+        return GeneratorContextManager.__exit__(self, type,
+                                                value, traceback)
+
+
+def mock_contextmanager(func):
+    def helper(*args, **kwds):
+        return MockContextManager(func(*args, **kwds))
+    return helper
+
+
+class MockResource(object):
+    def __init__(self):
+        self.yielded = False
+        self.stopped = False
+
+
+ at mock_contextmanager
+def mock_contextmanager_generator():
+    mock = MockResource()
+    try:
+        mock.yielded = True
+        yield mock
+    finally:
+        mock.stopped = True
+
+
+class Nested(object):
+
+    def __init__(self, *managers):
+        self.managers = managers
+        self.entered = None
+
+    def __enter__(self):
+        if self.entered is not None:
+            raise RuntimeError("Context is not reentrant")
+        self.entered = deque()
+        vars = []
+        try:
+            for mgr in self.managers:
+                vars.append(mgr.__enter__())
+                self.entered.appendleft(mgr)
+        except:
+            if not self.__exit__(*sys.exc_info()):
+                raise
+        return vars
+
+    def __exit__(self, *exc_info):
+        # Behave like nested with statements
+        # first in, last out
+        # New exceptions override old ones
+        ex = exc_info
+        for mgr in self.entered:
+            try:
+                if mgr.__exit__(*ex):
+                    ex = (None, None, None)
+            except:
+                ex = sys.exc_info()
+        self.entered = None
+        if ex is not exc_info:
+            raise ex[0], ex[1], ex[2]
+
+
+class MockNested(Nested):
+    def __init__(self, *managers):
+        Nested.__init__(self, *managers)
+        self.enter_called = False
+        self.exit_called = False
+        self.exit_args = None
+
+    def __enter__(self):
+        self.enter_called = True
+        return Nested.__enter__(self)
+
+    def __exit__(self, *exc_info):
+        self.exit_called = True
+        self.exit_args = exc_info
+        return Nested.__exit__(self, *exc_info)
+
+
+class FailureTestCase(unittest.TestCase):
+    def testNameError(self):
+        def fooNotDeclared():
+            with foo: pass
+        self.assertRaises(NameError, fooNotDeclared)
+
+    def testEnterAttributeError(self):
+        class LacksEnter(object):
+            def __exit__(self, type, value, traceback):
+                pass
+
+        def fooLacksEnter():
+            foo = LacksEnter()
+            with foo: pass
+        self.assertRaises(AttributeError, fooLacksEnter)
+
+    def testExitAttributeError(self):
+        class LacksExit(object):
+            def __enter__(self):
+                pass
+
+        def fooLacksExit():
+            foo = LacksExit()
+            with foo: pass
+        self.assertRaises(AttributeError, fooLacksExit)
+
+    def assertRaisesSyntaxError(self, codestr):
+        def shouldRaiseSyntaxError(s):
+            compile(s, '', 'single')
+        self.assertRaises(SyntaxError, shouldRaiseSyntaxError, codestr)
+
+    def testAssignmentToNoneError(self):
+        self.assertRaisesSyntaxError('with mock as None:\n  pass')
+        self.assertRaisesSyntaxError(
+            'with mock as (None):\n'
+            '  pass')
+
+    def testAssignmentToEmptyTupleError(self):
+        self.assertRaisesSyntaxError(
+            'with mock as ():\n'
+            '  pass')
+
+    def testAssignmentToTupleOnlyContainingNoneError(self):
+        self.assertRaisesSyntaxError('with mock as None,:\n  pass')
+        self.assertRaisesSyntaxError(
+            'with mock as (None,):\n'
+            '  pass')
+
+    def testAssignmentToTupleContainingNoneError(self):
+        self.assertRaisesSyntaxError(
+            'with mock as (foo, None, bar):\n'
+            '  pass')
+
+    def testEnterThrows(self):
+        class EnterThrows(object):
+            def __enter__(self):
+                raise RuntimeError("Enter threw")
+            def __exit__(self, *args):
+                pass
+
+        def shouldThrow():
+            ct = EnterThrows()
+            self.foo = None
+            with ct as self.foo:
+                pass
+        self.assertRaises(RuntimeError, shouldThrow)
+        self.assertEqual(self.foo, None)
+
+    def testExitThrows(self):
+        class ExitThrows(object):
+            def __enter__(self):
+                return
+            def __exit__(self, *args):
+                raise RuntimeError(42)
+        def shouldThrow():
+            with ExitThrows():
+                pass
+        self.assertRaises(RuntimeError, shouldThrow)
+
+class ContextmanagerAssertionMixin(object):
+    TEST_EXCEPTION = RuntimeError("test exception")
+
+    def assertInWithManagerInvariants(self, mock_manager):
+        self.assertTrue(mock_manager.enter_called)
+        self.assertFalse(mock_manager.exit_called)
+        self.assertEqual(mock_manager.exit_args, None)
+
+    def assertAfterWithManagerInvariants(self, mock_manager, exit_args):
+        self.assertTrue(mock_manager.enter_called)
+        self.assertTrue(mock_manager.exit_called)
+        self.assertEqual(mock_manager.exit_args, exit_args)
+
+    def assertAfterWithManagerInvariantsNoError(self, mock_manager):
+        self.assertAfterWithManagerInvariants(mock_manager,
+            (None, None, None))
+
+    def assertInWithGeneratorInvariants(self, mock_generator):
+        self.assertTrue(mock_generator.yielded)
+        self.assertFalse(mock_generator.stopped)
+
+    def assertAfterWithGeneratorInvariantsNoError(self, mock_generator):
+        self.assertTrue(mock_generator.yielded)
+        self.assertTrue(mock_generator.stopped)
+
+    def raiseTestException(self):
+        raise self.TEST_EXCEPTION
+
+    def assertAfterWithManagerInvariantsWithError(self, mock_manager):
+        self.assertTrue(mock_manager.enter_called)
+        self.assertTrue(mock_manager.exit_called)
+        self.assertEqual(mock_manager.exit_args[0], RuntimeError)
+        self.assertEqual(mock_manager.exit_args[1], self.TEST_EXCEPTION)
+
+    def assertAfterWithGeneratorInvariantsWithError(self, mock_generator):
+        self.assertTrue(mock_generator.yielded)
+        self.assertTrue(mock_generator.stopped)
+
+
+class NonexceptionalTestCase(unittest.TestCase, ContextmanagerAssertionMixin):
+    def testInlineGeneratorSyntax(self):
+        with mock_contextmanager_generator():
+            pass
+
+    def testUnboundGenerator(self):
+        mock = mock_contextmanager_generator()
+        with mock:
+            pass
+        self.assertAfterWithManagerInvariantsNoError(mock)
+
+    def testInlineGeneratorBoundSyntax(self):
+        with mock_contextmanager_generator() as foo:
+            self.assertInWithGeneratorInvariants(foo)
+        # FIXME: In the future, we'll try to keep the bound names from leaking
+        self.assertAfterWithGeneratorInvariantsNoError(foo)
+
+    def testInlineGeneratorBoundToExistingVariable(self):
+        foo = None
+        with mock_contextmanager_generator() as foo:
+            self.assertInWithGeneratorInvariants(foo)
+        self.assertAfterWithGeneratorInvariantsNoError(foo)
+
+    def testInlineGeneratorBoundToDottedVariable(self):
+        with mock_contextmanager_generator() as self.foo:
+            self.assertInWithGeneratorInvariants(self.foo)
+        self.assertAfterWithGeneratorInvariantsNoError(self.foo)
+
+    def testBoundGenerator(self):
+        mock = mock_contextmanager_generator()
+        with mock as foo:
+            self.assertInWithGeneratorInvariants(foo)
+            self.assertInWithManagerInvariants(mock)
+        self.assertAfterWithGeneratorInvariantsNoError(foo)
+        self.assertAfterWithManagerInvariantsNoError(mock)
+
+    def testNestedSingleStatements(self):
+        mock_a = mock_contextmanager_generator()
+        with mock_a as foo:
+            mock_b = mock_contextmanager_generator()
+            with mock_b as bar:
+                self.assertInWithManagerInvariants(mock_a)
+                self.assertInWithManagerInvariants(mock_b)
+                self.assertInWithGeneratorInvariants(foo)
+                self.assertInWithGeneratorInvariants(bar)
+            self.assertAfterWithManagerInvariantsNoError(mock_b)
+            self.assertAfterWithGeneratorInvariantsNoError(bar)
+            self.assertInWithManagerInvariants(mock_a)
+            self.assertInWithGeneratorInvariants(foo)
+        self.assertAfterWithManagerInvariantsNoError(mock_a)
+        self.assertAfterWithGeneratorInvariantsNoError(foo)
+
+
+class NestedNonexceptionalTestCase(unittest.TestCase,
+    ContextmanagerAssertionMixin):
+    def testSingleArgInlineGeneratorSyntax(self):
+        with Nested(mock_contextmanager_generator()):
+            pass
+
+    def testSingleArgUnbound(self):
+        mock_contextmanager = mock_contextmanager_generator()
+        mock_nested = MockNested(mock_contextmanager)
+        with mock_nested:
+            self.assertInWithManagerInvariants(mock_contextmanager)
+            self.assertInWithManagerInvariants(mock_nested)
+        self.assertAfterWithManagerInvariantsNoError(mock_contextmanager)
+        self.assertAfterWithManagerInvariantsNoError(mock_nested)
+
+    def testSingleArgBoundToNonTuple(self):
+        m = mock_contextmanager_generator()
+        # This will bind all the arguments to nested() into a single list
+        # assigned to foo.
+        with Nested(m) as foo:
+            self.assertInWithManagerInvariants(m)
+        self.assertAfterWithManagerInvariantsNoError(m)
+
+    def testSingleArgBoundToSingleElementParenthesizedList(self):
+        m = mock_contextmanager_generator()
+        # This will bind all the arguments to nested() into a single list
+        # assigned to foo.
+        with Nested(m) as (foo):
+            self.assertInWithManagerInvariants(m)
+        self.assertAfterWithManagerInvariantsNoError(m)
+
+    def testSingleArgBoundToMultipleElementTupleError(self):
+        def shouldThrowValueError():
+            with Nested(mock_contextmanager_generator()) as (foo, bar):
+                pass
+        self.assertRaises(ValueError, shouldThrowValueError)
+
+    def testSingleArgUnbound(self):
+        mock_contextmanager = mock_contextmanager_generator()
+        mock_nested = MockNested(mock_contextmanager)
+        with mock_nested:
+            self.assertInWithManagerInvariants(mock_contextmanager)
+            self.assertInWithManagerInvariants(mock_nested)
+        self.assertAfterWithManagerInvariantsNoError(mock_contextmanager)
+        self.assertAfterWithManagerInvariantsNoError(mock_nested)
+
+    def testMultipleArgUnbound(self):
+        m = mock_contextmanager_generator()
+        n = mock_contextmanager_generator()
+        o = mock_contextmanager_generator()
+        mock_nested = MockNested(m, n, o)
+        with mock_nested:
+            self.assertInWithManagerInvariants(m)
+            self.assertInWithManagerInvariants(n)
+            self.assertInWithManagerInvariants(o)
+            self.assertInWithManagerInvariants(mock_nested)
+        self.assertAfterWithManagerInvariantsNoError(m)
+        self.assertAfterWithManagerInvariantsNoError(n)
+        self.assertAfterWithManagerInvariantsNoError(o)
+        self.assertAfterWithManagerInvariantsNoError(mock_nested)
+
+    def testMultipleArgBound(self):
+        mock_nested = MockNested(mock_contextmanager_generator(),
+            mock_contextmanager_generator(), mock_contextmanager_generator())
+        with mock_nested as (m, n, o):
+            self.assertInWithGeneratorInvariants(m)
+            self.assertInWithGeneratorInvariants(n)
+            self.assertInWithGeneratorInvariants(o)
+            self.assertInWithManagerInvariants(mock_nested)
+        self.assertAfterWithGeneratorInvariantsNoError(m)
+        self.assertAfterWithGeneratorInvariantsNoError(n)
+        self.assertAfterWithGeneratorInvariantsNoError(o)
+        self.assertAfterWithManagerInvariantsNoError(mock_nested)
+
+
+class ExceptionalTestCase(unittest.TestCase, ContextmanagerAssertionMixin):
+    def testSingleResource(self):
+        cm = mock_contextmanager_generator()
+        def shouldThrow():
+            with cm as self.resource:
+                self.assertInWithManagerInvariants(cm)
+                self.assertInWithGeneratorInvariants(self.resource)
+                self.raiseTestException()
+        self.assertRaises(RuntimeError, shouldThrow)
+        self.assertAfterWithManagerInvariantsWithError(cm)
+        self.assertAfterWithGeneratorInvariantsWithError(self.resource)
+
+    def testNestedSingleStatements(self):
+        mock_a = mock_contextmanager_generator()
+        mock_b = mock_contextmanager_generator()
+        def shouldThrow():
+            with mock_a as self.foo:
+                with mock_b as self.bar:
+                    self.assertInWithManagerInvariants(mock_a)
+                    self.assertInWithManagerInvariants(mock_b)
+                    self.assertInWithGeneratorInvariants(self.foo)
+                    self.assertInWithGeneratorInvariants(self.bar)
+                    self.raiseTestException()
+        self.assertRaises(RuntimeError, shouldThrow)
+        self.assertAfterWithManagerInvariantsWithError(mock_a)
+        self.assertAfterWithManagerInvariantsWithError(mock_b)
+        self.assertAfterWithGeneratorInvariantsWithError(self.foo)
+        self.assertAfterWithGeneratorInvariantsWithError(self.bar)
+
+    def testMultipleResourcesInSingleStatement(self):
+        cm_a = mock_contextmanager_generator()
+        cm_b = mock_contextmanager_generator()
+        mock_nested = MockNested(cm_a, cm_b)
+        def shouldThrow():
+            with mock_nested as (self.resource_a, self.resource_b):
+                self.assertInWithManagerInvariants(cm_a)
+                self.assertInWithManagerInvariants(cm_b)
+                self.assertInWithManagerInvariants(mock_nested)
+                self.assertInWithGeneratorInvariants(self.resource_a)
+                self.assertInWithGeneratorInvariants(self.resource_b)
+                self.raiseTestException()
+        self.assertRaises(RuntimeError, shouldThrow)
+        self.assertAfterWithManagerInvariantsWithError(cm_a)
+        self.assertAfterWithManagerInvariantsWithError(cm_b)
+        self.assertAfterWithManagerInvariantsWithError(mock_nested)
+        self.assertAfterWithGeneratorInvariantsWithError(self.resource_a)
+        self.assertAfterWithGeneratorInvariantsWithError(self.resource_b)
+
+    def testNestedExceptionBeforeInnerStatement(self):
+        mock_a = mock_contextmanager_generator()
+        mock_b = mock_contextmanager_generator()
+        self.bar = None
+        def shouldThrow():
+            with mock_a as self.foo:
+                self.assertInWithManagerInvariants(mock_a)
+                self.assertInWithGeneratorInvariants(self.foo)
+                self.raiseTestException()
+                with mock_b as self.bar:
+                    pass
+        self.assertRaises(RuntimeError, shouldThrow)
+        self.assertAfterWithManagerInvariantsWithError(mock_a)
+        self.assertAfterWithGeneratorInvariantsWithError(self.foo)
+
+        # The inner statement stuff should never have been touched
+        self.assertEqual(self.bar, None)
+        self.assertFalse(mock_b.enter_called)
+        self.assertFalse(mock_b.exit_called)
+        self.assertEqual(mock_b.exit_args, None)
+
+    def testNestedExceptionAfterInnerStatement(self):
+        mock_a = mock_contextmanager_generator()
+        mock_b = mock_contextmanager_generator()
+        def shouldThrow():
+            with mock_a as self.foo:
+                with mock_b as self.bar:
+                    self.assertInWithManagerInvariants(mock_a)
+                    self.assertInWithManagerInvariants(mock_b)
+                    self.assertInWithGeneratorInvariants(self.foo)
+                    self.assertInWithGeneratorInvariants(self.bar)
+                self.raiseTestException()
+        self.assertRaises(RuntimeError, shouldThrow)
+        self.assertAfterWithManagerInvariantsWithError(mock_a)
+        self.assertAfterWithManagerInvariantsNoError(mock_b)
+        self.assertAfterWithGeneratorInvariantsWithError(self.foo)
+        self.assertAfterWithGeneratorInvariantsNoError(self.bar)
+
+    def testRaisedStopIteration1(self):
+        @contextmanager
+        def cm():
+            yield
+
+        def shouldThrow():
+            with cm():
+                raise StopIteration("from with")
+
+        self.assertRaises(StopIteration, shouldThrow)
+
+    def testRaisedStopIteration2(self):
+        class cm(object):
+            def __enter__(self):
+                pass
+            def __exit__(self, type, value, traceback):
+                pass
+
+        def shouldThrow():
+            with cm():
+                raise StopIteration("from with")
+
+        self.assertRaises(StopIteration, shouldThrow)
+
+    def testRaisedGeneratorExit1(self):
+        @contextmanager
+        def cm():
+            yield
+
+        def shouldThrow():
+            with cm():
+                raise GeneratorExit("from with")
+
+        self.assertRaises(GeneratorExit, shouldThrow)
+
+    def testRaisedGeneratorExit2(self):
+        class cm (object):
+            def __enter__(self):
+                pass
+            def __exit__(self, type, value, traceback):
+                pass
+
+        def shouldThrow():
+            with cm():
+                raise GeneratorExit("from with")
+
+        self.assertRaises(GeneratorExit, shouldThrow)
+
+
+class NonLocalFlowControlTestCase(unittest.TestCase):
+
+    def testWithBreak(self):
+        counter = 0
+        while True:
+            counter += 1
+            with mock_contextmanager_generator():
+                counter += 10
+                break
+            counter += 100 # Not reached
+        self.assertEqual(counter, 11)
+
+    def testWithContinue(self):
+        counter = 0
+        while True:
+            counter += 1
+            if counter > 2:
+                break
+            with mock_contextmanager_generator():
+                counter += 10
+                continue
+            counter += 100 # Not reached
+        self.assertEqual(counter, 12)
+
+    def testWithReturn(self):
+        def foo():
+            counter = 0
+            while True:
+                counter += 1
+                with mock_contextmanager_generator():
+                    counter += 10
+                    return counter
+                counter += 100 # Not reached
+        self.assertEqual(foo(), 11)
+
+    def testWithYield(self):
+        def gen():
+            with mock_contextmanager_generator():
+                yield 12
+                yield 13
+        x = list(gen())
+        self.assertEqual(x, [12, 13])
+
+    def testWithRaise(self):
+        counter = 0
+        try:
+            counter += 1
+            with mock_contextmanager_generator():
+                counter += 10
+                raise RuntimeError
+            counter += 100 # Not reached
+        except RuntimeError:
+            self.assertEqual(counter, 11)
+        else:
+            self.fail("Didn't raise RuntimeError")
+
+
+class AssignmentTargetTestCase(unittest.TestCase):
+
+    def testSingleComplexTarget(self):
+        targets = {1: [0, 1, 2]}
+        with mock_contextmanager_generator() as targets[1][0]:
+            self.assertEqual(targets.keys(), [1])
+            self.assertEqual(targets[1][0].__class__, MockResource)
+        with mock_contextmanager_generator() as targets.values()[0][1]:
+            self.assertEqual(targets.keys(), [1])
+            self.assertEqual(targets[1][1].__class__, MockResource)
+        with mock_contextmanager_generator() as targets[2]:
+            keys = targets.keys()
+            keys.sort()
+            self.assertEqual(keys, [1, 2])
+        class C: pass
+        blah = C()
+        with mock_contextmanager_generator() as blah.foo:
+            self.assertEqual(hasattr(blah, "foo"), True)
+
+    def testMultipleComplexTargets(self):
+        class C:
+            def __enter__(self): return 1, 2, 3
+            def __exit__(self, t, v, tb): pass
+        targets = {1: [0, 1, 2]}
+        with C() as (targets[1][0], targets[1][1], targets[1][2]):
+            self.assertEqual(targets, {1: [1, 2, 3]})
+        with C() as (targets.values()[0][2], targets.values()[0][1], targets.values()[0][0]):
+            self.assertEqual(targets, {1: [3, 2, 1]})
+        with C() as (targets[1], targets[2], targets[3]):
+            self.assertEqual(targets, {1: 1, 2: 2, 3: 3})
+        class B: pass
+        blah = B()
+        with C() as (blah.one, blah.two, blah.three):
+            self.assertEqual(blah.one, 1)
+            self.assertEqual(blah.two, 2)
+            self.assertEqual(blah.three, 3)
+
+
+class ExitSwallowsExceptionTestCase(unittest.TestCase):
+
+    def testExitTrueSwallowsException(self):
+        class AfricanSwallow:
+            def __enter__(self): pass
+            def __exit__(self, t, v, tb): return True
+        try:
+            with AfricanSwallow():
+                1/0
+        except ZeroDivisionError:
+            self.fail("ZeroDivisionError should have been swallowed")
+
+    def testExitFalseDoesntSwallowException(self):
+        class EuropeanSwallow:
+            def __enter__(self): pass
+            def __exit__(self, t, v, tb): return False
+        try:
+            with EuropeanSwallow():
+                1/0
+        except ZeroDivisionError:
+            pass
+        else:
+            self.fail("ZeroDivisionError should have been raised")
+
+
+def test_main():
+    run_unittest(FailureTestCase, NonexceptionalTestCase,
+                 NestedNonexceptionalTestCase, ExceptionalTestCase,
+                 NonLocalFlowControlTestCase,
+                 AssignmentTargetTestCase,
+                 ExitSwallowsExceptionTestCase)
+
+
+if __name__ == '__main__':
+    test_main()

Added: vendor/Python/current/Lib/test/test_wsgiref.py
===================================================================
--- vendor/Python/current/Lib/test/test_wsgiref.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_wsgiref.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,615 @@
+from __future__ import nested_scopes    # Backward compat for 2.1
+from unittest import TestSuite, TestCase, makeSuite
+from wsgiref.util import setup_testing_defaults
+from wsgiref.headers import Headers
+from wsgiref.handlers import BaseHandler, BaseCGIHandler
+from wsgiref import util
+from wsgiref.validate import validator
+from wsgiref.simple_server import WSGIServer, WSGIRequestHandler, demo_app
+from wsgiref.simple_server import make_server
+from StringIO import StringIO
+from SocketServer import BaseServer
+import re, sys
+
+
+class MockServer(WSGIServer):
+    """Non-socket HTTP server"""
+
+    def __init__(self, server_address, RequestHandlerClass):
+        BaseServer.__init__(self, server_address, RequestHandlerClass)
+        self.server_bind()
+
+    def server_bind(self):
+        host, port = self.server_address
+        self.server_name = host
+        self.server_port = port
+        self.setup_environ()
+
+
+class MockHandler(WSGIRequestHandler):
+    """Non-socket HTTP handler"""
+    def setup(self):
+        self.connection = self.request
+        self.rfile, self.wfile = self.connection
+
+    def finish(self):
+        pass
+
+
+
+
+
+def hello_app(environ,start_response):
+    start_response("200 OK", [
+        ('Content-Type','text/plain'),
+        ('Date','Mon, 05 Jun 2006 18:49:54 GMT')
+    ])
+    return ["Hello, world!"]
+
+def run_amock(app=hello_app, data="GET / HTTP/1.0\n\n"):
+    server = make_server("", 80, app, MockServer, MockHandler)
+    inp, out, err, olderr = StringIO(data), StringIO(), StringIO(), sys.stderr
+    sys.stderr = err
+
+    try:
+        server.finish_request((inp,out), ("127.0.0.1",8888))
+    finally:
+        sys.stderr = olderr
+
+    return out.getvalue(), err.getvalue()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+def compare_generic_iter(make_it,match):
+    """Utility to compare a generic 2.1/2.2+ iterator with an iterable
+
+    If running under Python 2.2+, this tests the iterator using iter()/next(),
+    as well as __getitem__.  'make_it' must be a function returning a fresh
+    iterator to be tested (since this may test the iterator twice)."""
+
+    it = make_it()
+    n = 0
+    for item in match:
+        if not it[n]==item: raise AssertionError
+        n+=1
+    try:
+        it[n]
+    except IndexError:
+        pass
+    else:
+        raise AssertionError("Too many items from __getitem__",it)
+
+    try:
+        iter, StopIteration
+    except NameError:
+        pass
+    else:
+        # Only test iter mode under 2.2+
+        it = make_it()
+        if not iter(it) is it: raise AssertionError
+        for item in match:
+            if not it.next()==item: raise AssertionError
+        try:
+            it.next()
+        except StopIteration:
+            pass
+        else:
+            raise AssertionError("Too many items from .next()",it)
+
+
+
+
+
+
+class IntegrationTests(TestCase):
+
+    def check_hello(self, out, has_length=True):
+        self.assertEqual(out,
+            "HTTP/1.0 200 OK\r\n"
+            "Server: WSGIServer/0.1 Python/"+sys.version.split()[0]+"\r\n"
+            "Content-Type: text/plain\r\n"
+            "Date: Mon, 05 Jun 2006 18:49:54 GMT\r\n" +
+            (has_length and  "Content-Length: 13\r\n" or "") +
+            "\r\n"
+            "Hello, world!"
+        )
+
+    def test_plain_hello(self):
+        out, err = run_amock()
+        self.check_hello(out)
+
+    def test_validated_hello(self):
+        out, err = run_amock(validator(hello_app))
+        # the middleware doesn't support len(), so content-length isn't there
+        self.check_hello(out, has_length=False)
+
+    def test_simple_validation_error(self):
+        def bad_app(environ,start_response):
+            start_response("200 OK", ('Content-Type','text/plain'))
+            return ["Hello, world!"]
+        out, err = run_amock(validator(bad_app))
+        self.failUnless(out.endswith(
+            "A server error occurred.  Please contact the administrator."
+        ))
+        self.assertEqual(
+            err.splitlines()[-2],
+            "AssertionError: Headers (('Content-Type', 'text/plain')) must"
+            " be of type list: <type 'tuple'>"
+        )
+
+
+
+
+
+
+class UtilityTests(TestCase):
+
+    def checkShift(self,sn_in,pi_in,part,sn_out,pi_out):
+        env = {'SCRIPT_NAME':sn_in,'PATH_INFO':pi_in}
+        util.setup_testing_defaults(env)
+        self.assertEqual(util.shift_path_info(env),part)
+        self.assertEqual(env['PATH_INFO'],pi_out)
+        self.assertEqual(env['SCRIPT_NAME'],sn_out)
+        return env
+
+    def checkDefault(self, key, value, alt=None):
+        # Check defaulting when empty
+        env = {}
+        util.setup_testing_defaults(env)
+        if isinstance(value,StringIO):
+            self.failUnless(isinstance(env[key],StringIO))
+        else:
+            self.assertEqual(env[key],value)
+
+        # Check existing value
+        env = {key:alt}
+        util.setup_testing_defaults(env)
+        self.failUnless(env[key] is alt)
+
+    def checkCrossDefault(self,key,value,**kw):
+        util.setup_testing_defaults(kw)
+        self.assertEqual(kw[key],value)
+
+    def checkAppURI(self,uri,**kw):
+        util.setup_testing_defaults(kw)
+        self.assertEqual(util.application_uri(kw),uri)
+
+    def checkReqURI(self,uri,query=1,**kw):
+        util.setup_testing_defaults(kw)
+        self.assertEqual(util.request_uri(kw,query),uri)
+
+
+
+
+
+
+    def checkFW(self,text,size,match):
+
+        def make_it(text=text,size=size):
+            return util.FileWrapper(StringIO(text),size)
+
+        compare_generic_iter(make_it,match)
+
+        it = make_it()
+        self.failIf(it.filelike.closed)
+
+        for item in it:
+            pass
+
+        self.failIf(it.filelike.closed)
+
+        it.close()
+        self.failUnless(it.filelike.closed)
+
+
+    def testSimpleShifts(self):
+        self.checkShift('','/', '', '/', '')
+        self.checkShift('','/x', 'x', '/x', '')
+        self.checkShift('/','', None, '/', '')
+        self.checkShift('/a','/x/y', 'x', '/a/x', '/y')
+        self.checkShift('/a','/x/',  'x', '/a/x', '/')
+
+
+    def testNormalizedShifts(self):
+        self.checkShift('/a/b', '/../y', '..', '/a', '/y')
+        self.checkShift('', '/../y', '..', '', '/y')
+        self.checkShift('/a/b', '//y', 'y', '/a/b/y', '')
+        self.checkShift('/a/b', '//y/', 'y', '/a/b/y', '/')
+        self.checkShift('/a/b', '/./y', 'y', '/a/b/y', '')
+        self.checkShift('/a/b', '/./y/', 'y', '/a/b/y', '/')
+        self.checkShift('/a/b', '///./..//y/.//', '..', '/a', '/y/')
+        self.checkShift('/a/b', '///', '', '/a/b/', '')
+        self.checkShift('/a/b', '/.//', '', '/a/b/', '')
+        self.checkShift('/a/b', '/x//', 'x', '/a/b/x', '/')
+        self.checkShift('/a/b', '/.', None, '/a/b', '')
+
+
+    def testDefaults(self):
+        for key, value in [
+            ('SERVER_NAME','127.0.0.1'),
+            ('SERVER_PORT', '80'),
+            ('SERVER_PROTOCOL','HTTP/1.0'),
+            ('HTTP_HOST','127.0.0.1'),
+            ('REQUEST_METHOD','GET'),
+            ('SCRIPT_NAME',''),
+            ('PATH_INFO','/'),
+            ('wsgi.version', (1,0)),
+            ('wsgi.run_once', 0),
+            ('wsgi.multithread', 0),
+            ('wsgi.multiprocess', 0),
+            ('wsgi.input', StringIO("")),
+            ('wsgi.errors', StringIO()),
+            ('wsgi.url_scheme','http'),
+        ]:
+            self.checkDefault(key,value)
+
+
+    def testCrossDefaults(self):
+        self.checkCrossDefault('HTTP_HOST',"foo.bar",SERVER_NAME="foo.bar")
+        self.checkCrossDefault('wsgi.url_scheme',"https",HTTPS="on")
+        self.checkCrossDefault('wsgi.url_scheme',"https",HTTPS="1")
+        self.checkCrossDefault('wsgi.url_scheme',"https",HTTPS="yes")
+        self.checkCrossDefault('wsgi.url_scheme',"http",HTTPS="foo")
+        self.checkCrossDefault('SERVER_PORT',"80",HTTPS="foo")
+        self.checkCrossDefault('SERVER_PORT',"443",HTTPS="on")
+
+
+    def testGuessScheme(self):
+        self.assertEqual(util.guess_scheme({}), "http")
+        self.assertEqual(util.guess_scheme({'HTTPS':"foo"}), "http")
+        self.assertEqual(util.guess_scheme({'HTTPS':"on"}), "https")
+        self.assertEqual(util.guess_scheme({'HTTPS':"yes"}), "https")
+        self.assertEqual(util.guess_scheme({'HTTPS':"1"}), "https")
+
+
+
+
+
+    def testAppURIs(self):
+        self.checkAppURI("http://127.0.0.1/")
+        self.checkAppURI("http://127.0.0.1/spam", SCRIPT_NAME="/spam")
+        self.checkAppURI("http://spam.example.com:2071/",
+            HTTP_HOST="spam.example.com:2071", SERVER_PORT="2071")
+        self.checkAppURI("http://spam.example.com/",
+            SERVER_NAME="spam.example.com")
+        self.checkAppURI("http://127.0.0.1/",
+            HTTP_HOST="127.0.0.1", SERVER_NAME="spam.example.com")
+        self.checkAppURI("https://127.0.0.1/", HTTPS="on")
+        self.checkAppURI("http://127.0.0.1:8000/", SERVER_PORT="8000",
+            HTTP_HOST=None)
+
+    def testReqURIs(self):
+        self.checkReqURI("http://127.0.0.1/")
+        self.checkReqURI("http://127.0.0.1/spam", SCRIPT_NAME="/spam")
+        self.checkReqURI("http://127.0.0.1/spammity/spam",
+            SCRIPT_NAME="/spammity", PATH_INFO="/spam")
+        self.checkReqURI("http://127.0.0.1/spammity/spam?say=ni",
+            SCRIPT_NAME="/spammity", PATH_INFO="/spam",QUERY_STRING="say=ni")
+        self.checkReqURI("http://127.0.0.1/spammity/spam", 0,
+            SCRIPT_NAME="/spammity", PATH_INFO="/spam",QUERY_STRING="say=ni")
+
+    def testFileWrapper(self):
+        self.checkFW("xyz"*50, 120, ["xyz"*40,"xyz"*10])
+
+    def testHopByHop(self):
+        for hop in (
+            "Connection Keep-Alive Proxy-Authenticate Proxy-Authorization "
+            "TE Trailers Transfer-Encoding Upgrade"
+        ).split():
+            for alt in hop, hop.title(), hop.upper(), hop.lower():
+                self.failUnless(util.is_hop_by_hop(alt))
+
+        # Not comprehensive, just a few random header names
+        for hop in (
+            "Accept Cache-Control Date Pragma Trailer Via Warning"
+        ).split():
+            for alt in hop, hop.title(), hop.upper(), hop.lower():
+                self.failIf(util.is_hop_by_hop(alt))
+
+class HeaderTests(TestCase):
+
+    def testMappingInterface(self):
+        test = [('x','y')]
+        self.assertEqual(len(Headers([])),0)
+        self.assertEqual(len(Headers(test[:])),1)
+        self.assertEqual(Headers(test[:]).keys(), ['x'])
+        self.assertEqual(Headers(test[:]).values(), ['y'])
+        self.assertEqual(Headers(test[:]).items(), test)
+        self.failIf(Headers(test).items() is test)  # must be copy!
+
+        h=Headers([])
+        del h['foo']   # should not raise an error
+
+        h['Foo'] = 'bar'
+        for m in h.has_key, h.__contains__, h.get, h.get_all, h.__getitem__:
+            self.failUnless(m('foo'))
+            self.failUnless(m('Foo'))
+            self.failUnless(m('FOO'))
+            self.failIf(m('bar'))
+
+        self.assertEqual(h['foo'],'bar')
+        h['foo'] = 'baz'
+        self.assertEqual(h['FOO'],'baz')
+        self.assertEqual(h.get_all('foo'),['baz'])
+
+        self.assertEqual(h.get("foo","whee"), "baz")
+        self.assertEqual(h.get("zoo","whee"), "whee")
+        self.assertEqual(h.setdefault("foo","whee"), "baz")
+        self.assertEqual(h.setdefault("zoo","whee"), "whee")
+        self.assertEqual(h["foo"],"baz")
+        self.assertEqual(h["zoo"],"whee")
+
+    def testRequireList(self):
+        self.assertRaises(TypeError, Headers, "foo")
+
+
+    def testExtras(self):
+        h = Headers([])
+        self.assertEqual(str(h),'\r\n')
+
+        h.add_header('foo','bar',baz="spam")
+        self.assertEqual(h['foo'], 'bar; baz="spam"')
+        self.assertEqual(str(h),'foo: bar; baz="spam"\r\n\r\n')
+
+        h.add_header('Foo','bar',cheese=None)
+        self.assertEqual(h.get_all('foo'),
+            ['bar; baz="spam"', 'bar; cheese'])
+
+        self.assertEqual(str(h),
+            'foo: bar; baz="spam"\r\n'
+            'Foo: bar; cheese\r\n'
+            '\r\n'
+        )
+
+
+class ErrorHandler(BaseCGIHandler):
+    """Simple handler subclass for testing BaseHandler"""
+
+    def __init__(self,**kw):
+        setup_testing_defaults(kw)
+        BaseCGIHandler.__init__(
+            self, StringIO(''), StringIO(), StringIO(), kw,
+            multithread=True, multiprocess=True
+        )
+
+class TestHandler(ErrorHandler):
+    """Simple handler subclass for testing BaseHandler, w/error passthru"""
+
+    def handle_error(self):
+        raise   # for testing, we want to see what's happening
+
+
+
+
+
+
+
+
+
+
+
+class HandlerTests(TestCase):
+
+    def checkEnvironAttrs(self, handler):
+        env = handler.environ
+        for attr in [
+            'version','multithread','multiprocess','run_once','file_wrapper'
+        ]:
+            if attr=='file_wrapper' and handler.wsgi_file_wrapper is None:
+                continue
+            self.assertEqual(getattr(handler,'wsgi_'+attr),env['wsgi.'+attr])
+
+    def checkOSEnviron(self,handler):
+        empty = {}; setup_testing_defaults(empty)
+        env = handler.environ
+        from os import environ
+        for k,v in environ.items():
+            if not empty.has_key(k):
+                self.assertEqual(env[k],v)
+        for k,v in empty.items():
+            self.failUnless(env.has_key(k))
+
+    def testEnviron(self):
+        h = TestHandler(X="Y")
+        h.setup_environ()
+        self.checkEnvironAttrs(h)
+        self.checkOSEnviron(h)
+        self.assertEqual(h.environ["X"],"Y")
+
+    def testCGIEnviron(self):
+        h = BaseCGIHandler(None,None,None,{})
+        h.setup_environ()
+        for key in 'wsgi.url_scheme', 'wsgi.input', 'wsgi.errors':
+            self.assert_(h.environ.has_key(key))
+
+    def testScheme(self):
+        h=TestHandler(HTTPS="on"); h.setup_environ()
+        self.assertEqual(h.environ['wsgi.url_scheme'],'https')
+        h=TestHandler(); h.setup_environ()
+        self.assertEqual(h.environ['wsgi.url_scheme'],'http')
+
+
+    def testAbstractMethods(self):
+        h = BaseHandler()
+        for name in [
+            '_flush','get_stdin','get_stderr','add_cgi_vars'
+        ]:
+            self.assertRaises(NotImplementedError, getattr(h,name))
+        self.assertRaises(NotImplementedError, h._write, "test")
+
+
+    def testContentLength(self):
+        # Demo one reason iteration is better than write()...  ;)
+
+        def trivial_app1(e,s):
+            s('200 OK',[])
+            return [e['wsgi.url_scheme']]
+
+        def trivial_app2(e,s):
+            s('200 OK',[])(e['wsgi.url_scheme'])
+            return []
+
+        h = TestHandler()
+        h.run(trivial_app1)
+        self.assertEqual(h.stdout.getvalue(),
+            "Status: 200 OK\r\n"
+            "Content-Length: 4\r\n"
+            "\r\n"
+            "http")
+
+        h = TestHandler()
+        h.run(trivial_app2)
+        self.assertEqual(h.stdout.getvalue(),
+            "Status: 200 OK\r\n"
+            "\r\n"
+            "http")
+
+
+
+
+
+
+
+    def testBasicErrorOutput(self):
+
+        def non_error_app(e,s):
+            s('200 OK',[])
+            return []
+
+        def error_app(e,s):
+            raise AssertionError("This should be caught by handler")
+
+        h = ErrorHandler()
+        h.run(non_error_app)
+        self.assertEqual(h.stdout.getvalue(),
+            "Status: 200 OK\r\n"
+            "Content-Length: 0\r\n"
+            "\r\n")
+        self.assertEqual(h.stderr.getvalue(),"")
+
+        h = ErrorHandler()
+        h.run(error_app)
+        self.assertEqual(h.stdout.getvalue(),
+            "Status: %s\r\n"
+            "Content-Type: text/plain\r\n"
+            "Content-Length: %d\r\n"
+            "\r\n%s" % (h.error_status,len(h.error_body),h.error_body))
+
+        self.failUnless(h.stderr.getvalue().find("AssertionError")<>-1)
+
+    def testErrorAfterOutput(self):
+        MSG = "Some output has been sent"
+        def error_app(e,s):
+            s("200 OK",[])(MSG)
+            raise AssertionError("This should be caught by handler")
+
+        h = ErrorHandler()
+        h.run(error_app)
+        self.assertEqual(h.stdout.getvalue(),
+            "Status: 200 OK\r\n"
+            "\r\n"+MSG)
+        self.failUnless(h.stderr.getvalue().find("AssertionError")<>-1)
+
+
+    def testHeaderFormats(self):
+
+        def non_error_app(e,s):
+            s('200 OK',[])
+            return []
+
+        stdpat = (
+            r"HTTP/%s 200 OK\r\n"
+            r"Date: \w{3}, [ 0123]\d \w{3} \d{4} \d\d:\d\d:\d\d GMT\r\n"
+            r"%s" r"Content-Length: 0\r\n" r"\r\n"
+        )
+        shortpat = (
+            "Status: 200 OK\r\n" "Content-Length: 0\r\n" "\r\n"
+        )
+
+        for ssw in "FooBar/1.0", None:
+            sw = ssw and "Server: %s\r\n" % ssw or ""
+
+            for version in "1.0", "1.1":
+                for proto in "HTTP/0.9", "HTTP/1.0", "HTTP/1.1":
+
+                    h = TestHandler(SERVER_PROTOCOL=proto)
+                    h.origin_server = False
+                    h.http_version = version
+                    h.server_software = ssw
+                    h.run(non_error_app)
+                    self.assertEqual(shortpat,h.stdout.getvalue())
+
+                    h = TestHandler(SERVER_PROTOCOL=proto)
+                    h.origin_server = True
+                    h.http_version = version
+                    h.server_software = ssw
+                    h.run(non_error_app)
+                    if proto=="HTTP/0.9":
+                        self.assertEqual(h.stdout.getvalue(),"")
+                    else:
+                        self.failUnless(
+                            re.match(stdpat%(version,sw), h.stdout.getvalue()),
+                            (stdpat%(version,sw), h.stdout.getvalue())
+                        )
+
+# This epilogue is needed for compatibility with the Python 2.5 regrtest module
+
+def test_main():
+    import unittest
+    from test.test_support import run_suite
+    run_suite(
+        unittest.defaultTestLoader.loadTestsFromModule(sys.modules[__name__])
+    )
+
+if __name__ == "__main__":
+    test_main()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# the above lines intentionally left blank


Property changes on: vendor/Python/current/Lib/test/test_wsgiref.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/test/test_xdrlib.py
===================================================================
--- vendor/Python/current/Lib/test/test_xdrlib.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_xdrlib.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,3 @@
+import xdrlib
+
+xdrlib._test()

Added: vendor/Python/current/Lib/test/test_xml_etree.py
===================================================================
--- vendor/Python/current/Lib/test/test_xml_etree.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_xml_etree.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,354 @@
+# xml.etree test.  This file contains enough tests to make sure that
+# all included components work as they should.  For a more extensive
+# test suite, see the selftest script in the ElementTree distribution.
+
+import doctest, sys
+
+from test import test_support
+
+SAMPLE_XML = """
+<body>
+  <tag>text</tag>
+  <tag />
+  <section>
+    <tag>subtext</tag>
+  </section>
+</body>
+"""
+
+SAMPLE_XML_NS = """
+<body xmlns="http://effbot.org/ns">
+  <tag>text</tag>
+  <tag />
+  <section>
+    <tag>subtext</tag>
+  </section>
+</body>
+"""
+
+def sanity():
+    """
+    Import sanity.
+
+    >>> from xml.etree import ElementTree
+    >>> from xml.etree import ElementInclude
+    >>> from xml.etree import ElementPath
+    """
+
+def check_method(method):
+    if not callable(method):
+        print method, "not callable"
+
+def serialize(ET, elem, encoding=None):
+    import StringIO
+    file = StringIO.StringIO()
+    tree = ET.ElementTree(elem)
+    if encoding:
+        tree.write(file, encoding)
+    else:
+        tree.write(file)
+    return file.getvalue()
+
+def summarize(elem):
+    return elem.tag
+
+def summarize_list(seq):
+    return map(summarize, seq)
+
+def interface():
+    """
+    Test element tree interface.
+
+    >>> from xml.etree import ElementTree as ET
+
+    >>> element = ET.Element("tag", key="value")
+    >>> tree = ET.ElementTree(element)
+
+    Make sure all standard element methods exist.
+
+    >>> check_method(element.append)
+    >>> check_method(element.insert)
+    >>> check_method(element.remove)
+    >>> check_method(element.getchildren)
+    >>> check_method(element.find)
+    >>> check_method(element.findall)
+    >>> check_method(element.findtext)
+    >>> check_method(element.clear)
+    >>> check_method(element.get)
+    >>> check_method(element.set)
+    >>> check_method(element.keys)
+    >>> check_method(element.items)
+    >>> check_method(element.getiterator)
+
+    Basic method sanity checks.
+
+    >>> serialize(ET, element) # 1
+    '<tag key="value" />'
+    >>> subelement = ET.Element("subtag")
+    >>> element.append(subelement)
+    >>> serialize(ET, element) #  2
+    '<tag key="value"><subtag /></tag>'
+    >>> element.insert(0, subelement)
+    >>> serialize(ET, element) # 3
+    '<tag key="value"><subtag /><subtag /></tag>'
+    >>> element.remove(subelement)
+    >>> serialize(ET, element) # 4
+    '<tag key="value"><subtag /></tag>'
+    >>> element.remove(subelement)
+    >>> serialize(ET, element) # 5
+    '<tag key="value" />'
+    >>> element.remove(subelement)
+    Traceback (most recent call last):
+    ValueError: list.remove(x): x not in list
+    >>> serialize(ET, element) # 6
+    '<tag key="value" />'
+    """
+
+def find():
+    """
+    Test find methods (including xpath syntax).
+
+    >>> from xml.etree import ElementTree as ET
+
+    >>> elem = ET.XML(SAMPLE_XML)
+    >>> elem.find("tag").tag
+    'tag'
+    >>> ET.ElementTree(elem).find("tag").tag
+    'tag'
+    >>> elem.find("section/tag").tag
+    'tag'
+    >>> ET.ElementTree(elem).find("section/tag").tag
+    'tag'
+    >>> elem.findtext("tag")
+    'text'
+    >>> elem.findtext("tog")
+    >>> elem.findtext("tog", "default")
+    'default'
+    >>> ET.ElementTree(elem).findtext("tag")
+    'text'
+    >>> elem.findtext("section/tag")
+    'subtext'
+    >>> ET.ElementTree(elem).findtext("section/tag")
+    'subtext'
+    >>> summarize_list(elem.findall("tag"))
+    ['tag', 'tag']
+    >>> summarize_list(elem.findall("*"))
+    ['tag', 'tag', 'section']
+    >>> summarize_list(elem.findall(".//tag"))
+    ['tag', 'tag', 'tag']
+    >>> summarize_list(elem.findall("section/tag"))
+    ['tag']
+    >>> summarize_list(elem.findall("section//tag"))
+    ['tag']
+    >>> summarize_list(elem.findall("section/*"))
+    ['tag']
+    >>> summarize_list(elem.findall("section//*"))
+    ['tag']
+    >>> summarize_list(elem.findall("section/.//*"))
+    ['tag']
+    >>> summarize_list(elem.findall("*/*"))
+    ['tag']
+    >>> summarize_list(elem.findall("*//*"))
+    ['tag']
+    >>> summarize_list(elem.findall("*/tag"))
+    ['tag']
+    >>> summarize_list(elem.findall("*/./tag"))
+    ['tag']
+    >>> summarize_list(elem.findall("./tag"))
+    ['tag', 'tag']
+    >>> summarize_list(elem.findall(".//tag"))
+    ['tag', 'tag', 'tag']
+    >>> summarize_list(elem.findall("././tag"))
+    ['tag', 'tag']
+    >>> summarize_list(ET.ElementTree(elem).findall("/tag"))
+    ['tag', 'tag']
+    >>> summarize_list(ET.ElementTree(elem).findall("./tag"))
+    ['tag', 'tag']
+    >>> elem = ET.XML(SAMPLE_XML_NS)
+    >>> summarize_list(elem.findall("tag"))
+    []
+    >>> summarize_list(elem.findall("{http://effbot.org/ns}tag"))
+    ['{http://effbot.org/ns}tag', '{http://effbot.org/ns}tag']
+    >>> summarize_list(elem.findall(".//{http://effbot.org/ns}tag"))
+    ['{http://effbot.org/ns}tag', '{http://effbot.org/ns}tag', '{http://effbot.org/ns}tag']
+    """
+
+def parseliteral():
+    r"""
+
+    >>> from xml.etree import ElementTree as ET
+
+    >>> element = ET.XML("<html><body>text</body></html>")
+    >>> ET.ElementTree(element).write(sys.stdout)
+    <html><body>text</body></html>
+    >>> element = ET.fromstring("<html><body>text</body></html>")
+    >>> ET.ElementTree(element).write(sys.stdout)
+    <html><body>text</body></html>
+    >>> print ET.tostring(element)
+    <html><body>text</body></html>
+    >>> print ET.tostring(element, "ascii")
+    <?xml version='1.0' encoding='ascii'?>
+    <html><body>text</body></html>
+    >>> _, ids = ET.XMLID("<html><body>text</body></html>")
+    >>> len(ids)
+    0
+    >>> _, ids = ET.XMLID("<html><body id='body'>text</body></html>")
+    >>> len(ids)
+    1
+    >>> ids["body"].tag
+    'body'
+    """
+
+
+def check_encoding(ET, encoding):
+    """
+    >>> from xml.etree import ElementTree as ET
+
+    >>> check_encoding(ET, "ascii")
+    >>> check_encoding(ET, "us-ascii")
+    >>> check_encoding(ET, "iso-8859-1")
+    >>> check_encoding(ET, "iso-8859-15")
+    >>> check_encoding(ET, "cp437")
+    >>> check_encoding(ET, "mac-roman")
+    """
+    ET.XML("<?xml version='1.0' encoding='%s'?><xml />" % encoding)
+
+
+#
+# xinclude tests (samples from appendix C of the xinclude specification)
+
+XINCLUDE = {}
+
+XINCLUDE["C1.xml"] = """\
+<?xml version='1.0'?>
+<document xmlns:xi="http://www.w3.org/2001/XInclude">
+  <p>120 Mz is adequate for an average home user.</p>
+  <xi:include href="disclaimer.xml"/>
+</document>
+"""
+
+XINCLUDE["disclaimer.xml"] = """\
+<?xml version='1.0'?>
+<disclaimer>
+  <p>The opinions represented herein represent those of the individual
+  and should not be interpreted as official policy endorsed by this
+  organization.</p>
+</disclaimer>
+"""
+
+XINCLUDE["C2.xml"] = """\
+<?xml version='1.0'?>
+<document xmlns:xi="http://www.w3.org/2001/XInclude">
+  <p>This document has been accessed
+  <xi:include href="count.txt" parse="text"/> times.</p>
+</document>
+"""
+
+XINCLUDE["count.txt"] = "324387"
+
+XINCLUDE["C3.xml"] = """\
+<?xml version='1.0'?>
+<document xmlns:xi="http://www.w3.org/2001/XInclude">
+  <p>The following is the source of the "data.xml" resource:</p>
+  <example><xi:include href="data.xml" parse="text"/></example>
+</document>
+"""
+
+XINCLUDE["data.xml"] = """\
+<?xml version='1.0'?>
+<data>
+  <item><![CDATA[Brooks & Shields]]></item>
+</data>
+"""
+
+XINCLUDE["C5.xml"] = """\
+<?xml version='1.0'?>
+<div xmlns:xi="http://www.w3.org/2001/XInclude">
+  <xi:include href="example.txt" parse="text">
+    <xi:fallback>
+      <xi:include href="fallback-example.txt" parse="text">
+        <xi:fallback><a href="mailto:bob at example.org">Report error</a></xi:fallback>
+      </xi:include>
+    </xi:fallback>
+  </xi:include>
+</div>
+"""
+
+XINCLUDE["default.xml"] = """\
+<?xml version='1.0'?>
+<document xmlns:xi="http://www.w3.org/2001/XInclude">
+  <p>Example.</p>
+  <xi:include href="samples/simple.xml"/>
+</document>
+"""
+
+def xinclude_loader(href, parse="xml", encoding=None):
+    try:
+        data = XINCLUDE[href]
+    except KeyError:
+        raise IOError("resource not found")
+    if parse == "xml":
+        from xml.etree.ElementTree import XML
+        return XML(data)
+    return data
+
+def xinclude():
+    r"""
+    Basic inclusion example (XInclude C.1)
+
+    >>> from xml.etree import ElementTree as ET
+    >>> from xml.etree import ElementInclude
+
+    >>> document = xinclude_loader("C1.xml")
+    >>> ElementInclude.include(document, xinclude_loader)
+    >>> print serialize(ET, document) # C1
+    <document>
+      <p>120 Mz is adequate for an average home user.</p>
+      <disclaimer>
+      <p>The opinions represented herein represent those of the individual
+      and should not be interpreted as official policy endorsed by this
+      organization.</p>
+    </disclaimer>
+    </document>
+
+    Textual inclusion example (XInclude C.2)
+
+    >>> document = xinclude_loader("C2.xml")
+    >>> ElementInclude.include(document, xinclude_loader)
+    >>> print serialize(ET, document) # C2
+    <document>
+      <p>This document has been accessed
+      324387 times.</p>
+    </document>
+
+    Textual inclusion of XML example (XInclude C.3)
+
+    >>> document = xinclude_loader("C3.xml")
+    >>> ElementInclude.include(document, xinclude_loader)
+    >>> print serialize(ET, document) # C3
+    <document>
+      <p>The following is the source of the "data.xml" resource:</p>
+      <example>&lt;?xml version='1.0'?&gt;
+    &lt;data&gt;
+      &lt;item&gt;&lt;![CDATA[Brooks &amp; Shields]]&gt;&lt;/item&gt;
+    &lt;/data&gt;
+    </example>
+    </document>
+
+    Fallback example (XInclude C.5)
+    Note! Fallback support is not yet implemented
+
+    >>> document = xinclude_loader("C5.xml")
+    >>> ElementInclude.include(document, xinclude_loader)
+    Traceback (most recent call last):
+    IOError: resource not found
+    >>> # print serialize(ET, document) # C5
+
+    """
+
+def test_main():
+    from test import test_xml_etree
+    test_support.run_doctest(test_xml_etree, verbosity=True)
+
+if __name__ == '__main__':
+    test_main()

Added: vendor/Python/current/Lib/test/test_xml_etree_c.py
===================================================================
--- vendor/Python/current/Lib/test/test_xml_etree_c.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_xml_etree_c.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,223 @@
+# xml.etree test for cElementTree
+
+import doctest, sys
+
+from test import test_support
+
+from xml.etree import cElementTree as ET
+
+SAMPLE_XML = """
+<body>
+  <tag>text</tag>
+  <tag />
+  <section>
+    <tag>subtext</tag>
+  </section>
+</body>
+"""
+
+SAMPLE_XML_NS = """
+<body xmlns="http://effbot.org/ns">
+  <tag>text</tag>
+  <tag />
+  <section>
+    <tag>subtext</tag>
+  </section>
+</body>
+"""
+
+def sanity():
+    """
+    Import sanity.
+
+    >>> from xml.etree import cElementTree
+    """
+
+def check_method(method):
+    if not callable(method):
+        print method, "not callable"
+
+def serialize(ET, elem, encoding=None):
+    import StringIO
+    file = StringIO.StringIO()
+    tree = ET.ElementTree(elem)
+    if encoding:
+        tree.write(file, encoding)
+    else:
+        tree.write(file)
+    return file.getvalue()
+
+def summarize(elem):
+    return elem.tag
+
+def summarize_list(seq):
+    return map(summarize, seq)
+
+def interface():
+    """
+    Test element tree interface.
+
+    >>> element = ET.Element("tag", key="value")
+    >>> tree = ET.ElementTree(element)
+
+    Make sure all standard element methods exist.
+
+    >>> check_method(element.append)
+    >>> check_method(element.insert)
+    >>> check_method(element.remove)
+    >>> check_method(element.getchildren)
+    >>> check_method(element.find)
+    >>> check_method(element.findall)
+    >>> check_method(element.findtext)
+    >>> check_method(element.clear)
+    >>> check_method(element.get)
+    >>> check_method(element.set)
+    >>> check_method(element.keys)
+    >>> check_method(element.items)
+    >>> check_method(element.getiterator)
+
+    Basic method sanity checks.
+
+    >>> serialize(ET, element) # 1
+    '<tag key="value" />'
+    >>> subelement = ET.Element("subtag")
+    >>> element.append(subelement)
+    >>> serialize(ET, element) #  2
+    '<tag key="value"><subtag /></tag>'
+    >>> element.insert(0, subelement)
+    >>> serialize(ET, element) # 3
+    '<tag key="value"><subtag /><subtag /></tag>'
+    >>> element.remove(subelement)
+    >>> serialize(ET, element) # 4
+    '<tag key="value"><subtag /></tag>'
+    >>> element.remove(subelement)
+    >>> serialize(ET, element) # 5
+    '<tag key="value" />'
+    >>> element.remove(subelement)
+    Traceback (most recent call last):
+    ValueError: list.remove(x): x not in list
+    >>> serialize(ET, element) # 6
+    '<tag key="value" />'
+    """
+
+def find():
+    """
+    Test find methods (including xpath syntax).
+
+    >>> elem = ET.XML(SAMPLE_XML)
+    >>> elem.find("tag").tag
+    'tag'
+    >>> ET.ElementTree(elem).find("tag").tag
+    'tag'
+    >>> elem.find("section/tag").tag
+    'tag'
+    >>> ET.ElementTree(elem).find("section/tag").tag
+    'tag'
+    >>> elem.findtext("tag")
+    'text'
+    >>> elem.findtext("tog")
+    >>> elem.findtext("tog", "default")
+    'default'
+    >>> ET.ElementTree(elem).findtext("tag")
+    'text'
+    >>> elem.findtext("section/tag")
+    'subtext'
+    >>> ET.ElementTree(elem).findtext("section/tag")
+    'subtext'
+    >>> summarize_list(elem.findall("tag"))
+    ['tag', 'tag']
+    >>> summarize_list(elem.findall("*"))
+    ['tag', 'tag', 'section']
+    >>> summarize_list(elem.findall(".//tag"))
+    ['tag', 'tag', 'tag']
+    >>> summarize_list(elem.findall("section/tag"))
+    ['tag']
+    >>> summarize_list(elem.findall("section//tag"))
+    ['tag']
+    >>> summarize_list(elem.findall("section/*"))
+    ['tag']
+    >>> summarize_list(elem.findall("section//*"))
+    ['tag']
+    >>> summarize_list(elem.findall("section/.//*"))
+    ['tag']
+    >>> summarize_list(elem.findall("*/*"))
+    ['tag']
+    >>> summarize_list(elem.findall("*//*"))
+    ['tag']
+    >>> summarize_list(elem.findall("*/tag"))
+    ['tag']
+    >>> summarize_list(elem.findall("*/./tag"))
+    ['tag']
+    >>> summarize_list(elem.findall("./tag"))
+    ['tag', 'tag']
+    >>> summarize_list(elem.findall(".//tag"))
+    ['tag', 'tag', 'tag']
+    >>> summarize_list(elem.findall("././tag"))
+    ['tag', 'tag']
+    >>> summarize_list(ET.ElementTree(elem).findall("/tag"))
+    ['tag', 'tag']
+    >>> summarize_list(ET.ElementTree(elem).findall("./tag"))
+    ['tag', 'tag']
+    >>> elem = ET.XML(SAMPLE_XML_NS)
+    >>> summarize_list(elem.findall("tag"))
+    []
+    >>> summarize_list(elem.findall("{http://effbot.org/ns}tag"))
+    ['{http://effbot.org/ns}tag', '{http://effbot.org/ns}tag']
+    >>> summarize_list(elem.findall(".//{http://effbot.org/ns}tag"))
+    ['{http://effbot.org/ns}tag', '{http://effbot.org/ns}tag', '{http://effbot.org/ns}tag']
+    """
+
+def parseliteral():
+    r"""
+
+    >>> element = ET.XML("<html><body>text</body></html>")
+    >>> ET.ElementTree(element).write(sys.stdout)
+    <html><body>text</body></html>
+    >>> element = ET.fromstring("<html><body>text</body></html>")
+    >>> ET.ElementTree(element).write(sys.stdout)
+    <html><body>text</body></html>
+    >>> print ET.tostring(element)
+    <html><body>text</body></html>
+    >>> print ET.tostring(element, "ascii")
+    <?xml version='1.0' encoding='ascii'?>
+    <html><body>text</body></html>
+    >>> _, ids = ET.XMLID("<html><body>text</body></html>")
+    >>> len(ids)
+    0
+    >>> _, ids = ET.XMLID("<html><body id='body'>text</body></html>")
+    >>> len(ids)
+    1
+    >>> ids["body"].tag
+    'body'
+    """
+
+def check_encoding(encoding):
+    """
+    >>> check_encoding("ascii")
+    >>> check_encoding("us-ascii")
+    >>> check_encoding("iso-8859-1")
+    >>> check_encoding("iso-8859-15")
+    >>> check_encoding("cp437")
+    >>> check_encoding("mac-roman")
+    """
+    ET.XML(
+        "<?xml version='1.0' encoding='%s'?><xml />" % encoding
+        )
+
+def bug_1534630():
+    """
+    >>> bob = ET.TreeBuilder()
+    >>> e = bob.data("data")
+    >>> e = bob.start("tag", {})
+    >>> e = bob.end("tag")
+    >>> e = bob.close()
+    >>> serialize(ET, e)
+    '<tag />'
+    """
+
+def test_main():
+    from test import test_xml_etree_c
+    test_support.run_doctest(test_xml_etree_c, verbosity=True)
+
+if __name__ == '__main__':
+    test_main()

Added: vendor/Python/current/Lib/test/test_xmllib.py
===================================================================
--- vendor/Python/current/Lib/test/test_xmllib.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_xmllib.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,51 @@
+'''Test module to thest the xmllib module.
+   Sjoerd Mullender
+'''
+
+testdoc = """\
+<?xml version="1.0" encoding="UTF-8" standalone='yes' ?>
+<!-- comments aren't allowed before the <?xml?> tag,
+     but they are allowed before the <!DOCTYPE> tag -->
+<?processing instructions are allowed in the same places as comments ?>
+<!DOCTYPE greeting [
+  <!ELEMENT greeting (#PCDATA)>
+]>
+<greeting>Hello, world!</greeting>
+"""
+
+nsdoc = "<foo xmlns='URI' attr='val'/>"
+
+import warnings
+warnings.filterwarnings("ignore", ".* xmllib .* obsolete.*",
+                        DeprecationWarning, r'xmllib$')
+
+from test import test_support
+import unittest
+import xmllib
+
+class XMLParserTestCase(unittest.TestCase):
+
+    def test_simple(self):
+        parser = xmllib.XMLParser()
+        for c in testdoc:
+            parser.feed(c)
+        parser.close()
+
+    def test_default_namespace(self):
+        class H(xmllib.XMLParser):
+            def unknown_starttag(self, name, attr):
+                self.name, self.attr = name, attr
+        h=H()
+        h.feed(nsdoc)
+        h.close()
+        # The default namespace applies to elements...
+        self.assertEquals(h.name, "URI foo")
+        # but not to attributes
+        self.assertEquals(h.attr, {'attr':'val'})
+
+
+def test_main():
+    test_support.run_unittest(XMLParserTestCase)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_xmlrpc.py
===================================================================
--- vendor/Python/current/Lib/test/test_xmlrpc.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_xmlrpc.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,155 @@
+import datetime
+import sys
+import unittest
+import xmlrpclib
+from test import test_support
+
+try:
+    unicode
+except NameError:
+    have_unicode = False
+else:
+    have_unicode = True
+
+alist = [{'astring': 'foo at bar.baz.spam',
+          'afloat': 7283.43,
+          'anint': 2**20,
+          'ashortlong': 2L,
+          'anotherlist': ['.zyx.41'],
+          'abase64': xmlrpclib.Binary("my dog has fleas"),
+          'boolean': xmlrpclib.False,
+          'unicode': u'\u4000\u6000\u8000',
+          u'ukey\u4000': 'regular value',
+          'datetime1': xmlrpclib.DateTime('20050210T11:41:23'),
+          'datetime2': xmlrpclib.DateTime(
+                        (2005, 02, 10, 11, 41, 23, 0, 1, -1)),
+          'datetime3': xmlrpclib.DateTime(
+                        datetime.datetime(2005, 02, 10, 11, 41, 23)),
+          }]
+
+class XMLRPCTestCase(unittest.TestCase):
+
+    def test_dump_load(self):
+        self.assertEquals(alist,
+                          xmlrpclib.loads(xmlrpclib.dumps((alist,)))[0][0])
+
+    def test_dump_bare_datetime(self):
+        # This checks that an unwrapped datetime.date object can be handled
+        # by the marshalling code.  This can't be done via test_dump_load()
+        # since with use_datetime set to 1 the unmarshaller would create
+        # datetime objects for the 'datetime[123]' keys as well
+        dt = datetime.datetime(2005, 02, 10, 11, 41, 23)
+        s = xmlrpclib.dumps((dt,))
+        (newdt,), m = xmlrpclib.loads(s, use_datetime=1)
+        self.assertEquals(newdt, dt)
+        self.assertEquals(m, None)
+
+        (newdt,), m = xmlrpclib.loads(s, use_datetime=0)
+        self.assertEquals(newdt, xmlrpclib.DateTime('20050210T11:41:23'))
+
+    def test_dump_bare_date(self):
+        # This checks that an unwrapped datetime.date object can be handled
+        # by the marshalling code.  This can't be done via test_dump_load()
+        # since the unmarshaller produces a datetime object
+        d = datetime.datetime(2005, 02, 10, 11, 41, 23).date()
+        s = xmlrpclib.dumps((d,))
+        (newd,), m = xmlrpclib.loads(s, use_datetime=1)
+        self.assertEquals(newd.date(), d)
+        self.assertEquals(newd.time(), datetime.time(0, 0, 0))
+        self.assertEquals(m, None)
+
+        (newdt,), m = xmlrpclib.loads(s, use_datetime=0)
+        self.assertEquals(newdt, xmlrpclib.DateTime('20050210T00:00:00'))
+
+    def test_dump_bare_time(self):
+        # This checks that an unwrapped datetime.time object can be handled
+        # by the marshalling code.  This can't be done via test_dump_load()
+        # since the unmarshaller produces a datetime object
+        t = datetime.datetime(2005, 02, 10, 11, 41, 23).time()
+        s = xmlrpclib.dumps((t,))
+        (newt,), m = xmlrpclib.loads(s, use_datetime=1)
+        today = datetime.datetime.now().date().strftime("%Y%m%d")
+        self.assertEquals(newt.time(), t)
+        self.assertEquals(newt.date(), datetime.datetime.now().date())
+        self.assertEquals(m, None)
+
+        (newdt,), m = xmlrpclib.loads(s, use_datetime=0)
+        self.assertEquals(newdt, xmlrpclib.DateTime('%sT11:41:23'%today))
+
+    def test_bug_1164912 (self):
+        d = xmlrpclib.DateTime()
+        ((new_d,), dummy) = xmlrpclib.loads(xmlrpclib.dumps((d,),
+                                            methodresponse=True))
+        self.assert_(isinstance(new_d.value, str))
+
+        # Check that the output of dumps() is still an 8-bit string
+        s = xmlrpclib.dumps((new_d,), methodresponse=True)
+        self.assert_(isinstance(s, str))
+
+    def test_dump_big_long(self):
+        self.assertRaises(OverflowError, xmlrpclib.dumps, (2L**99,))
+
+    def test_dump_bad_dict(self):
+        self.assertRaises(TypeError, xmlrpclib.dumps, ({(1,2,3): 1},))
+
+    def test_dump_big_int(self):
+        if sys.maxint > 2L**31-1:
+            self.assertRaises(OverflowError, xmlrpclib.dumps,
+                              (int(2L**34),))
+
+    def test_dump_none(self):
+        value = alist + [None]
+        arg1 = (alist + [None],)
+        strg = xmlrpclib.dumps(arg1, allow_none=True)
+        self.assertEquals(value,
+                          xmlrpclib.loads(strg)[0][0])
+        self.assertRaises(TypeError, xmlrpclib.dumps, (arg1,))
+
+    def test_default_encoding_issues(self):
+        # SF bug #1115989: wrong decoding in '_stringify'
+        utf8 = """<?xml version='1.0' encoding='iso-8859-1'?>
+                  <params>
+                    <param><value>
+                      <string>abc \x95</string>
+                      </value></param>
+                    <param><value>
+                      <struct>
+                        <member>
+                          <name>def \x96</name>
+                          <value><string>ghi \x97</string></value>
+                          </member>
+                        </struct>
+                      </value></param>
+                  </params>
+                  """
+
+        # sys.setdefaultencoding() normally doesn't exist after site.py is
+        # loaded.  reload(sys) is the way to get it back.
+        old_encoding = sys.getdefaultencoding()
+        setdefaultencoding_existed = hasattr(sys, "setdefaultencoding")
+        reload(sys) # ugh!
+        sys.setdefaultencoding("iso-8859-1")
+        try:
+            (s, d), m = xmlrpclib.loads(utf8)
+        finally:
+            sys.setdefaultencoding(old_encoding)
+            if not setdefaultencoding_existed:
+                del sys.setdefaultencoding
+
+        items = d.items()
+        if have_unicode:
+            self.assertEquals(s, u"abc \x95")
+            self.assert_(isinstance(s, unicode))
+            self.assertEquals(items, [(u"def \x96", u"ghi \x97")])
+            self.assert_(isinstance(items[0][0], unicode))
+            self.assert_(isinstance(items[0][1], unicode))
+        else:
+            self.assertEquals(s, "abc \xc2\x95")
+            self.assertEquals(items, [("def \xc2\x96", "ghi \xc2\x97")])
+
+def test_main():
+    test_support.run_unittest(XMLRPCTestCase)
+
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_xpickle.py
===================================================================
--- vendor/Python/current/Lib/test/test_xpickle.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_xpickle.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,44 @@
+# test_pickle dumps and loads pickles via pickle.py.
+# test_cpickle does the same, but via the cPickle module.
+# This test covers the other two cases, making pickles with one module and
+# loading them via the other.
+
+import pickle
+import cPickle
+import unittest
+
+from test import test_support
+from test.pickletester import AbstractPickleTests
+
+class DumpCPickle_LoadPickle(AbstractPickleTests):
+
+    error = KeyError
+
+    def dumps(self, arg, proto=0, fast=0):
+        # Ignore fast
+        return cPickle.dumps(arg, proto)
+
+    def loads(self, buf):
+        # Ignore fast
+        return pickle.loads(buf)
+
+class DumpPickle_LoadCPickle(AbstractPickleTests):
+
+    error = cPickle.BadPickleGet
+
+    def dumps(self, arg, proto=0, fast=0):
+        # Ignore fast
+        return pickle.dumps(arg, proto)
+
+    def loads(self, buf):
+        # Ignore fast
+        return cPickle.loads(buf)
+
+def test_main():
+    test_support.run_unittest(
+        DumpCPickle_LoadPickle,
+        DumpPickle_LoadCPickle
+    )
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_xrange.py
===================================================================
--- vendor/Python/current/Lib/test/test_xrange.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_xrange.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,64 @@
+# Python test set -- built-in functions
+
+import test.test_support, unittest
+import sys
+
+import warnings
+warnings.filterwarnings("ignore", "integer argument expected",
+                        DeprecationWarning, "unittest")
+
+class XrangeTest(unittest.TestCase):
+    def test_xrange(self):
+        self.assertEqual(list(xrange(3)), [0, 1, 2])
+        self.assertEqual(list(xrange(1, 5)), [1, 2, 3, 4])
+        self.assertEqual(list(xrange(0)), [])
+        self.assertEqual(list(xrange(-3)), [])
+        self.assertEqual(list(xrange(1, 10, 3)), [1, 4, 7])
+        self.assertEqual(list(xrange(5, -5, -3)), [5, 2, -1, -4])
+
+        a = 10
+        b = 100
+        c = 50
+
+        self.assertEqual(list(xrange(a, a+2)), [a, a+1])
+        self.assertEqual(list(xrange(a+2, a, -1L)), [a+2, a+1])
+        self.assertEqual(list(xrange(a+4, a, -2)), [a+4, a+2])
+
+        seq = list(xrange(a, b, c))
+        self.assert_(a in seq)
+        self.assert_(b not in seq)
+        self.assertEqual(len(seq), 2)
+
+        seq = list(xrange(b, a, -c))
+        self.assert_(b in seq)
+        self.assert_(a not in seq)
+        self.assertEqual(len(seq), 2)
+
+        seq = list(xrange(-a, -b, -c))
+        self.assert_(-a in seq)
+        self.assert_(-b not in seq)
+        self.assertEqual(len(seq), 2)
+
+        self.assertRaises(TypeError, xrange)
+        self.assertRaises(TypeError, xrange, 1, 2, 3, 4)
+        self.assertRaises(ValueError, xrange, 1, 2, 0)
+
+        self.assertRaises(OverflowError, xrange, 1e100, 1e101, 1e101)
+
+        self.assertRaises(TypeError, xrange, 0, "spam")
+        self.assertRaises(TypeError, xrange, 0, 42, "spam")
+
+        self.assertEqual(len(xrange(0, sys.maxint, sys.maxint-1)), 2)
+
+        self.assertRaises(OverflowError, xrange, -sys.maxint, sys.maxint)
+        self.assertRaises(OverflowError, xrange, 0, 2*sys.maxint)
+
+        r = xrange(-sys.maxint, sys.maxint, 2)
+        self.assertEqual(len(r), sys.maxint)
+        self.assertRaises(OverflowError, xrange, -sys.maxint-1, sys.maxint, 2)
+
+def test_main():
+    test.test_support.run_unittest(XrangeTest)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_zipfile.py
===================================================================
--- vendor/Python/current/Lib/test/test_zipfile.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_zipfile.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,357 @@
+# We can test part of the module without zlib.
+try:
+    import zlib
+except ImportError:
+    zlib = None
+
+import zipfile, os, unittest, sys, shutil
+
+from StringIO import StringIO
+from tempfile import TemporaryFile
+
+from test.test_support import TESTFN, run_unittest
+
+TESTFN2 = TESTFN + "2"
+
+class TestsWithSourceFile(unittest.TestCase):
+    def setUp(self):
+        line_gen = ("Test of zipfile line %d." % i for i in range(0, 1000))
+        self.data = '\n'.join(line_gen)
+
+        # Make a source file with some lines
+        fp = open(TESTFN, "wb")
+        fp.write(self.data)
+        fp.close()
+
+    def zipTest(self, f, compression):
+        # Create the ZIP archive
+        zipfp = zipfile.ZipFile(f, "w", compression)
+        zipfp.write(TESTFN, "another"+os.extsep+"name")
+        zipfp.write(TESTFN, TESTFN)
+        zipfp.writestr("strfile", self.data)
+        zipfp.close()
+
+        # Read the ZIP archive
+        zipfp = zipfile.ZipFile(f, "r", compression)
+        self.assertEqual(zipfp.read(TESTFN), self.data)
+        self.assertEqual(zipfp.read("another"+os.extsep+"name"), self.data)
+        self.assertEqual(zipfp.read("strfile"), self.data)
+
+        # Print the ZIP directory
+        fp = StringIO()
+        stdout = sys.stdout
+        try:
+            sys.stdout = fp
+
+            zipfp.printdir()
+        finally:
+            sys.stdout = stdout
+
+        directory = fp.getvalue()
+        lines = directory.splitlines()
+        self.assertEquals(len(lines), 4) # Number of files + header
+
+        self.assert_('File Name' in lines[0])
+        self.assert_('Modified' in lines[0])
+        self.assert_('Size' in lines[0])
+
+        fn, date, time, size = lines[1].split()
+        self.assertEquals(fn, 'another.name')
+        # XXX: timestamp is not tested
+        self.assertEquals(size, str(len(self.data)))
+
+        # Check the namelist
+        names = zipfp.namelist()
+        self.assertEquals(len(names), 3)
+        self.assert_(TESTFN in names)
+        self.assert_("another"+os.extsep+"name" in names)
+        self.assert_("strfile" in names)
+
+        # Check infolist
+        infos = zipfp.infolist()
+        names = [ i.filename for i in infos ]
+        self.assertEquals(len(names), 3)
+        self.assert_(TESTFN in names)
+        self.assert_("another"+os.extsep+"name" in names)
+        self.assert_("strfile" in names)
+        for i in infos:
+            self.assertEquals(i.file_size, len(self.data))
+
+        # check getinfo
+        for nm in (TESTFN, "another"+os.extsep+"name", "strfile"):
+            info = zipfp.getinfo(nm)
+            self.assertEquals(info.filename, nm)
+            self.assertEquals(info.file_size, len(self.data))
+
+        # Check that testzip doesn't raise an exception
+        zipfp.testzip()
+
+
+        zipfp.close()
+
+
+
+
+    def testStored(self):
+        for f in (TESTFN2, TemporaryFile(), StringIO()):
+            self.zipTest(f, zipfile.ZIP_STORED)
+
+    if zlib:
+        def testDeflated(self):
+            for f in (TESTFN2, TemporaryFile(), StringIO()):
+                self.zipTest(f, zipfile.ZIP_DEFLATED)
+
+    def testAbsoluteArcnames(self):
+        zipfp = zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED)
+        zipfp.write(TESTFN, "/absolute")
+        zipfp.close()
+
+        zipfp = zipfile.ZipFile(TESTFN2, "r", zipfile.ZIP_STORED)
+        self.assertEqual(zipfp.namelist(), ["absolute"])
+        zipfp.close()
+
+
+    def tearDown(self):
+        os.remove(TESTFN)
+        os.remove(TESTFN2)
+
+class TestZip64InSmallFiles(unittest.TestCase):
+    # These tests test the ZIP64 functionality without using large files,
+    # see test_zipfile64 for proper tests.
+
+    def setUp(self):
+        self._limit = zipfile.ZIP64_LIMIT
+        zipfile.ZIP64_LIMIT = 5
+
+        line_gen = ("Test of zipfile line %d." % i for i in range(0, 1000))
+        self.data = '\n'.join(line_gen)
+
+        # Make a source file with some lines
+        fp = open(TESTFN, "wb")
+        fp.write(self.data)
+        fp.close()
+
+    def largeFileExceptionTest(self, f, compression):
+        zipfp = zipfile.ZipFile(f, "w", compression)
+        self.assertRaises(zipfile.LargeZipFile,
+                zipfp.write, TESTFN, "another"+os.extsep+"name")
+        zipfp.close()
+
+    def largeFileExceptionTest2(self, f, compression):
+        zipfp = zipfile.ZipFile(f, "w", compression)
+        self.assertRaises(zipfile.LargeZipFile,
+                zipfp.writestr, "another"+os.extsep+"name", self.data)
+        zipfp.close()
+
+    def testLargeFileException(self):
+        for f in (TESTFN2, TemporaryFile(), StringIO()):
+            self.largeFileExceptionTest(f, zipfile.ZIP_STORED)
+            self.largeFileExceptionTest2(f, zipfile.ZIP_STORED)
+
+    def zipTest(self, f, compression):
+        # Create the ZIP archive
+        zipfp = zipfile.ZipFile(f, "w", compression, allowZip64=True)
+        zipfp.write(TESTFN, "another"+os.extsep+"name")
+        zipfp.write(TESTFN, TESTFN)
+        zipfp.writestr("strfile", self.data)
+        zipfp.close()
+
+        # Read the ZIP archive
+        zipfp = zipfile.ZipFile(f, "r", compression)
+        self.assertEqual(zipfp.read(TESTFN), self.data)
+        self.assertEqual(zipfp.read("another"+os.extsep+"name"), self.data)
+        self.assertEqual(zipfp.read("strfile"), self.data)
+
+        # Print the ZIP directory
+        fp = StringIO()
+        stdout = sys.stdout
+        try:
+            sys.stdout = fp
+
+            zipfp.printdir()
+        finally:
+            sys.stdout = stdout
+
+        directory = fp.getvalue()
+        lines = directory.splitlines()
+        self.assertEquals(len(lines), 4) # Number of files + header
+
+        self.assert_('File Name' in lines[0])
+        self.assert_('Modified' in lines[0])
+        self.assert_('Size' in lines[0])
+
+        fn, date, time, size = lines[1].split()
+        self.assertEquals(fn, 'another.name')
+        # XXX: timestamp is not tested
+        self.assertEquals(size, str(len(self.data)))
+
+        # Check the namelist
+        names = zipfp.namelist()
+        self.assertEquals(len(names), 3)
+        self.assert_(TESTFN in names)
+        self.assert_("another"+os.extsep+"name" in names)
+        self.assert_("strfile" in names)
+
+        # Check infolist
+        infos = zipfp.infolist()
+        names = [ i.filename for i in infos ]
+        self.assertEquals(len(names), 3)
+        self.assert_(TESTFN in names)
+        self.assert_("another"+os.extsep+"name" in names)
+        self.assert_("strfile" in names)
+        for i in infos:
+            self.assertEquals(i.file_size, len(self.data))
+
+        # check getinfo
+        for nm in (TESTFN, "another"+os.extsep+"name", "strfile"):
+            info = zipfp.getinfo(nm)
+            self.assertEquals(info.filename, nm)
+            self.assertEquals(info.file_size, len(self.data))
+
+        # Check that testzip doesn't raise an exception
+        zipfp.testzip()
+
+
+        zipfp.close()
+
+    def testStored(self):
+        for f in (TESTFN2, TemporaryFile(), StringIO()):
+            self.zipTest(f, zipfile.ZIP_STORED)
+
+
+    if zlib:
+        def testDeflated(self):
+            for f in (TESTFN2, TemporaryFile(), StringIO()):
+                self.zipTest(f, zipfile.ZIP_DEFLATED)
+
+    def testAbsoluteArcnames(self):
+        zipfp = zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED, allowZip64=True)
+        zipfp.write(TESTFN, "/absolute")
+        zipfp.close()
+
+        zipfp = zipfile.ZipFile(TESTFN2, "r", zipfile.ZIP_STORED)
+        self.assertEqual(zipfp.namelist(), ["absolute"])
+        zipfp.close()
+
+
+    def tearDown(self):
+        zipfile.ZIP64_LIMIT = self._limit
+        os.remove(TESTFN)
+        os.remove(TESTFN2)
+
+class PyZipFileTests(unittest.TestCase):
+    def testWritePyfile(self):
+        zipfp  = zipfile.PyZipFile(TemporaryFile(), "w")
+        fn = __file__
+        if fn.endswith('.pyc') or fn.endswith('.pyo'):
+            fn = fn[:-1]
+
+        zipfp.writepy(fn)
+
+        bn = os.path.basename(fn)
+        self.assert_(bn not in zipfp.namelist())
+        self.assert_(bn + 'o' in zipfp.namelist() or bn + 'c' in zipfp.namelist())
+        zipfp.close()
+
+
+        zipfp  = zipfile.PyZipFile(TemporaryFile(), "w")
+        fn = __file__
+        if fn.endswith('.pyc') or fn.endswith('.pyo'):
+            fn = fn[:-1]
+
+        zipfp.writepy(fn, "testpackage")
+
+        bn = "%s/%s"%("testpackage", os.path.basename(fn))
+        self.assert_(bn not in zipfp.namelist())
+        self.assert_(bn + 'o' in zipfp.namelist() or bn + 'c' in zipfp.namelist())
+        zipfp.close()
+
+    def testWritePythonPackage(self):
+        import email
+        packagedir = os.path.dirname(email.__file__)
+
+        zipfp  = zipfile.PyZipFile(TemporaryFile(), "w")
+        zipfp.writepy(packagedir)
+
+        # Check for a couple of modules at different levels of the hieararchy
+        names = zipfp.namelist()
+        self.assert_('email/__init__.pyo' in names or 'email/__init__.pyc' in names)
+        self.assert_('email/mime/text.pyo' in names or 'email/mime/text.pyc' in names)
+
+    def testWritePythonDirectory(self):
+        os.mkdir(TESTFN2)
+        try:
+            fp = open(os.path.join(TESTFN2, "mod1.py"), "w")
+            fp.write("print 42\n")
+            fp.close()
+
+            fp = open(os.path.join(TESTFN2, "mod2.py"), "w")
+            fp.write("print 42 * 42\n")
+            fp.close()
+
+            fp = open(os.path.join(TESTFN2, "mod2.txt"), "w")
+            fp.write("bla bla bla\n")
+            fp.close()
+
+            zipfp  = zipfile.PyZipFile(TemporaryFile(), "w")
+            zipfp.writepy(TESTFN2)
+
+            names = zipfp.namelist()
+            self.assert_('mod1.pyc' in names or 'mod1.pyo' in names)
+            self.assert_('mod2.pyc' in names or 'mod2.pyo' in names)
+            self.assert_('mod2.txt' not in names)
+
+        finally:
+            shutil.rmtree(TESTFN2)
+
+
+
+class OtherTests(unittest.TestCase):
+    def testCloseErroneousFile(self):
+        # This test checks that the ZipFile constructor closes the file object
+        # it opens if there's an error in the file.  If it doesn't, the traceback
+        # holds a reference to the ZipFile object and, indirectly, the file object.
+        # On Windows, this causes the os.unlink() call to fail because the
+        # underlying file is still open.  This is SF bug #412214.
+        #
+        fp = open(TESTFN, "w")
+        fp.write("this is not a legal zip file\n")
+        fp.close()
+        try:
+            zf = zipfile.ZipFile(TESTFN)
+        except zipfile.BadZipfile:
+            os.unlink(TESTFN)
+
+    def testNonExistentFileRaisesIOError(self):
+        # make sure we don't raise an AttributeError when a partially-constructed
+        # ZipFile instance is finalized; this tests for regression on SF tracker
+        # bug #403871.
+
+        # The bug we're testing for caused an AttributeError to be raised
+        # when a ZipFile instance was created for a file that did not
+        # exist; the .fp member was not initialized but was needed by the
+        # __del__() method.  Since the AttributeError is in the __del__(),
+        # it is ignored, but the user should be sufficiently annoyed by
+        # the message on the output that regression will be noticed
+        # quickly.
+        self.assertRaises(IOError, zipfile.ZipFile, TESTFN)
+
+    def testClosedZipRaisesRuntimeError(self):
+        # Verify that testzip() doesn't swallow inappropriate exceptions.
+        data = StringIO()
+        zipf = zipfile.ZipFile(data, mode="w")
+        zipf.writestr("foo.txt", "O, for a Muse of Fire!")
+        zipf.close()
+
+        # This is correct; calling .read on a closed ZipFile should throw
+        # a RuntimeError, and so should calling .testzip.  An earlier
+        # version of .testzip would swallow this exception (and any other)
+        # and report that the first file in the archive was corrupt.
+        self.assertRaises(RuntimeError, zipf.testzip)
+
+def test_main():
+    run_unittest(TestsWithSourceFile, TestZip64InSmallFiles, OtherTests, PyZipFileTests)
+    #run_unittest(TestZip64InSmallFiles)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_zipfile64.py
===================================================================
--- vendor/Python/current/Lib/test/test_zipfile64.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_zipfile64.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,101 @@
+# Tests of the full ZIP64 functionality of zipfile
+# The test_support.requires call is the only reason for keeping this separate
+# from test_zipfile
+from test import test_support
+# XXX(nnorwitz): disable this test by looking for extra largfile resource
+# which doesn't exist.  This test takes over 30 minutes to run in general
+# and requires more disk space than most of the buildbots.
+test_support.requires(
+        'extralargefile',
+        'test requires loads of disk-space bytes and a long time to run'
+    )
+
+# We can test part of the module without zlib.
+try:
+    import zlib
+except ImportError:
+    zlib = None
+
+import zipfile, os, unittest
+import time
+import sys
+
+from StringIO import StringIO
+from tempfile import TemporaryFile
+
+from test.test_support import TESTFN, run_unittest
+
+TESTFN2 = TESTFN + "2"
+
+# How much time in seconds can pass before we print a 'Still working' message.
+_PRINT_WORKING_MSG_INTERVAL = 5 * 60
+
+class TestsWithSourceFile(unittest.TestCase):
+    def setUp(self):
+        # Create test data.
+        # xrange() is important here -- don't want to create immortal space
+        # for a million ints.
+        line_gen = ("Test of zipfile line %d." % i for i in xrange(1000000))
+        self.data = '\n'.join(line_gen)
+
+        # And write it to a file.
+        fp = open(TESTFN, "wb")
+        fp.write(self.data)
+        fp.close()
+
+    def zipTest(self, f, compression):
+        # Create the ZIP archive.
+        zipfp = zipfile.ZipFile(f, "w", compression, allowZip64=True)
+
+        # It will contain enough copies of self.data to reach about 6GB of
+        # raw data to store.
+        filecount = 6*1024**3 // len(self.data)
+
+        next_time = time.time() + _PRINT_WORKING_MSG_INTERVAL
+        for num in range(filecount):
+            zipfp.writestr("testfn%d" % num, self.data)
+            # Print still working message since this test can be really slow
+            if next_time <= time.time():
+                next_time = time.time() + _PRINT_WORKING_MSG_INTERVAL
+                print >>sys.__stdout__, (
+                   '  zipTest still writing %d of %d, be patient...' %
+                   (num, filecount))
+                sys.__stdout__.flush()
+        zipfp.close()
+
+        # Read the ZIP archive
+        zipfp = zipfile.ZipFile(f, "r", compression)
+        for num in range(filecount):
+            self.assertEqual(zipfp.read("testfn%d" % num), self.data)
+            # Print still working message since this test can be really slow
+            if next_time <= time.time():
+                next_time = time.time() + _PRINT_WORKING_MSG_INTERVAL
+                print >>sys.__stdout__, (
+                   '  zipTest still reading %d of %d, be patient...' %
+                   (num, filecount))
+                sys.__stdout__.flush()
+        zipfp.close()
+
+    def testStored(self):
+        # Try the temp file first.  If we do TESTFN2 first, then it hogs
+        # gigabytes of disk space for the duration of the test.
+        for f in TemporaryFile(), TESTFN2:
+            self.zipTest(f, zipfile.ZIP_STORED)
+
+    if zlib:
+        def testDeflated(self):
+            # Try the temp file first.  If we do TESTFN2 first, then it hogs
+            # gigabytes of disk space for the duration of the test.
+            for f in TemporaryFile(), TESTFN2:
+                self.zipTest(f, zipfile.ZIP_DEFLATED)
+
+    def tearDown(self):
+        for fname in TESTFN, TESTFN2:
+            if os.path.exists(fname):
+                os.remove(fname)
+
+def test_main():
+    run_unittest(TestsWithSourceFile)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_zipimport.py
===================================================================
--- vendor/Python/current/Lib/test/test_zipimport.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_zipimport.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,429 @@
+import sys
+import os
+import marshal
+import imp
+import struct
+import time
+import unittest
+
+import zlib # implied prerequisite
+from zipfile import ZipFile, ZipInfo, ZIP_STORED, ZIP_DEFLATED
+from test import test_support
+from test.test_importhooks import ImportHooksBaseTestCase, test_src, test_co
+
+import zipimport
+import linecache
+import doctest
+import inspect
+import StringIO
+from traceback import extract_tb, extract_stack, print_tb
+raise_src = 'def do_raise(): raise TypeError\n'
+
+# so we only run testAFakeZlib once if this test is run repeatedly
+# which happens when we look for ref leaks
+test_imported = False
+
+
+def make_pyc(co, mtime):
+    data = marshal.dumps(co)
+    if type(mtime) is type(0.0):
+        # Mac mtimes need a bit of special casing
+        if mtime < 0x7fffffff:
+            mtime = int(mtime)
+        else:
+            mtime = int(-0x100000000L + long(mtime))
+    pyc = imp.get_magic() + struct.pack("<i", int(mtime)) + data
+    return pyc
+
+def module_path_to_dotted_name(path):
+    return path.replace(os.sep, '.')
+
+NOW = time.time()
+test_pyc = make_pyc(test_co, NOW)
+
+
+if __debug__:
+    pyc_ext = ".pyc"
+else:
+    pyc_ext = ".pyo"
+
+
+TESTMOD = "ziptestmodule"
+TESTPACK = "ziptestpackage"
+TESTPACK2 = "ziptestpackage2"
+TEMP_ZIP = os.path.abspath("junk95142" + os.extsep + "zip")
+
+class UncompressedZipImportTestCase(ImportHooksBaseTestCase):
+
+    compression = ZIP_STORED
+
+    def setUp(self):
+        # We're reusing the zip archive path, so we must clear the
+        # cached directory info and linecache
+        linecache.clearcache()
+        zipimport._zip_directory_cache.clear()
+        ImportHooksBaseTestCase.setUp(self)
+
+    def doTest(self, expected_ext, files, *modules, **kw):
+        z = ZipFile(TEMP_ZIP, "w")
+        try:
+            for name, (mtime, data) in files.items():
+                zinfo = ZipInfo(name, time.localtime(mtime))
+                zinfo.compress_type = self.compression
+                z.writestr(zinfo, data)
+            z.close()
+
+            stuff = kw.get("stuff", None)
+            if stuff is not None:
+                # Prepend 'stuff' to the start of the zipfile
+                f = open(TEMP_ZIP, "rb")
+                data = f.read()
+                f.close()
+
+                f = open(TEMP_ZIP, "wb")
+                f.write(stuff)
+                f.write(data)
+                f.close()
+
+            sys.path.insert(0, TEMP_ZIP)
+
+            mod = __import__(".".join(modules), globals(), locals(),
+                             ["__dummy__"])
+
+            call = kw.get('call')
+            if call is not None:
+                call(mod)
+
+            if expected_ext:
+                file = mod.get_file()
+                self.assertEquals(file, os.path.join(TEMP_ZIP,
+                                  *modules) + expected_ext)
+        finally:
+            z.close()
+            os.remove(TEMP_ZIP)
+
+    def testAFakeZlib(self):
+        #
+        # This could cause a stack overflow before: importing zlib.py
+        # from a compressed archive would cause zlib to be imported
+        # which would find zlib.py in the archive, which would... etc.
+        #
+        # This test *must* be executed first: it must be the first one
+        # to trigger zipimport to import zlib (zipimport caches the
+        # zlib.decompress function object, after which the problem being
+        # tested here wouldn't be a problem anymore...
+        # (Hence the 'A' in the test method name: to make it the first
+        # item in a list sorted by name, like unittest.makeSuite() does.)
+        #
+        # This test fails on platforms on which the zlib module is
+        # statically linked, but the problem it tests for can't
+        # occur in that case (builtin modules are always found first),
+        # so we'll simply skip it then. Bug #765456.
+        #
+        if "zlib" in sys.builtin_module_names:
+            return
+        if "zlib" in sys.modules:
+            del sys.modules["zlib"]
+        files = {"zlib.py": (NOW, test_src)}
+        try:
+            self.doTest(".py", files, "zlib")
+        except ImportError:
+            if self.compression != ZIP_DEFLATED:
+                self.fail("expected test to not raise ImportError")
+        else:
+            if self.compression != ZIP_STORED:
+                self.fail("expected test to raise ImportError")
+
+    def testPy(self):
+        files = {TESTMOD + ".py": (NOW, test_src)}
+        self.doTest(".py", files, TESTMOD)
+
+    def testPyc(self):
+        files = {TESTMOD + pyc_ext: (NOW, test_pyc)}
+        self.doTest(pyc_ext, files, TESTMOD)
+
+    def testBoth(self):
+        files = {TESTMOD + ".py": (NOW, test_src),
+                 TESTMOD + pyc_ext: (NOW, test_pyc)}
+        self.doTest(pyc_ext, files, TESTMOD)
+
+    def testEmptyPy(self):
+        files = {TESTMOD + ".py": (NOW, "")}
+        self.doTest(None, files, TESTMOD)
+
+    def testBadMagic(self):
+        # make pyc magic word invalid, forcing loading from .py
+        m0 = ord(test_pyc[0])
+        m0 ^= 0x04  # flip an arbitrary bit
+        badmagic_pyc = chr(m0) + test_pyc[1:]
+        files = {TESTMOD + ".py": (NOW, test_src),
+                 TESTMOD + pyc_ext: (NOW, badmagic_pyc)}
+        self.doTest(".py", files, TESTMOD)
+
+    def testBadMagic2(self):
+        # make pyc magic word invalid, causing an ImportError
+        m0 = ord(test_pyc[0])
+        m0 ^= 0x04  # flip an arbitrary bit
+        badmagic_pyc = chr(m0) + test_pyc[1:]
+        files = {TESTMOD + pyc_ext: (NOW, badmagic_pyc)}
+        try:
+            self.doTest(".py", files, TESTMOD)
+        except ImportError:
+            pass
+        else:
+            self.fail("expected ImportError; import from bad pyc")
+
+    def testBadMTime(self):
+        t3 = ord(test_pyc[7])
+        t3 ^= 0x02  # flip the second bit -- not the first as that one
+                    # isn't stored in the .py's mtime in the zip archive.
+        badtime_pyc = test_pyc[:7] + chr(t3) + test_pyc[8:]
+        files = {TESTMOD + ".py": (NOW, test_src),
+                 TESTMOD + pyc_ext: (NOW, badtime_pyc)}
+        self.doTest(".py", files, TESTMOD)
+
+    def testPackage(self):
+        packdir = TESTPACK + os.sep
+        files = {packdir + "__init__" + pyc_ext: (NOW, test_pyc),
+                 packdir + TESTMOD + pyc_ext: (NOW, test_pyc)}
+        self.doTest(pyc_ext, files, TESTPACK, TESTMOD)
+
+    def testDeepPackage(self):
+        packdir = TESTPACK + os.sep
+        packdir2 = packdir + TESTPACK2 + os.sep
+        files = {packdir + "__init__" + pyc_ext: (NOW, test_pyc),
+                 packdir2 + "__init__" + pyc_ext: (NOW, test_pyc),
+                 packdir2 + TESTMOD + pyc_ext: (NOW, test_pyc)}
+        self.doTest(pyc_ext, files, TESTPACK, TESTPACK2, TESTMOD)
+
+    def testZipImporterMethods(self):
+        packdir = TESTPACK + os.sep
+        packdir2 = packdir + TESTPACK2 + os.sep
+        files = {packdir + "__init__" + pyc_ext: (NOW, test_pyc),
+                 packdir2 + "__init__" + pyc_ext: (NOW, test_pyc),
+                 packdir2 + TESTMOD + pyc_ext: (NOW, test_pyc)}
+
+        z = ZipFile(TEMP_ZIP, "w")
+        try:
+            for name, (mtime, data) in files.items():
+                zinfo = ZipInfo(name, time.localtime(mtime))
+                zinfo.compress_type = self.compression
+                z.writestr(zinfo, data)
+            z.close()
+
+            zi = zipimport.zipimporter(TEMP_ZIP)
+            self.assertEquals(zi.is_package(TESTPACK), True)
+            zi.load_module(TESTPACK)
+
+            self.assertEquals(zi.is_package(packdir + '__init__'), False)
+            self.assertEquals(zi.is_package(packdir + TESTPACK2), True)
+            self.assertEquals(zi.is_package(packdir2 + TESTMOD), False)
+
+            mod_name = packdir2 + TESTMOD
+            mod = __import__(module_path_to_dotted_name(mod_name))
+            self.assertEquals(zi.get_source(TESTPACK), None)
+            self.assertEquals(zi.get_source(mod_name), None)
+        finally:
+            z.close()
+            os.remove(TEMP_ZIP)
+
+    def testGetData(self):
+        z = ZipFile(TEMP_ZIP, "w")
+        z.compression = self.compression
+        try:
+            name = "testdata.dat"
+            data = "".join([chr(x) for x in range(256)]) * 500
+            z.writestr(name, data)
+            z.close()
+            zi = zipimport.zipimporter(TEMP_ZIP)
+            self.assertEquals(data, zi.get_data(name))
+            self.assert_('zipimporter object' in repr(zi))
+        finally:
+            z.close()
+            os.remove(TEMP_ZIP)
+
+    def testImporterAttr(self):
+        src = """if 1:  # indent hack
+        def get_file():
+            return __file__
+        if __loader__.get_data("some.data") != "some data":
+            raise AssertionError, "bad data"\n"""
+        pyc = make_pyc(compile(src, "<???>", "exec"), NOW)
+        files = {TESTMOD + pyc_ext: (NOW, pyc),
+                 "some.data": (NOW, "some data")}
+        self.doTest(pyc_ext, files, TESTMOD)
+
+    def testImport_WithStuff(self):
+        # try importing from a zipfile which contains additional
+        # stuff at the beginning of the file
+        files = {TESTMOD + ".py": (NOW, test_src)}
+        self.doTest(".py", files, TESTMOD,
+                    stuff="Some Stuff"*31)
+
+    def assertModuleSource(self, module):
+        self.assertEqual(inspect.getsource(module), test_src)
+
+    def testGetSource(self):
+        files = {TESTMOD + ".py": (NOW, test_src)}
+        self.doTest(".py", files, TESTMOD, call=self.assertModuleSource)
+
+    def testGetCompiledSource(self):
+        pyc = make_pyc(compile(test_src, "<???>", "exec"), NOW)
+        files = {TESTMOD + ".py": (NOW, test_src),
+                 TESTMOD + pyc_ext: (NOW, pyc)}
+        self.doTest(pyc_ext, files, TESTMOD, call=self.assertModuleSource)
+
+    def runDoctest(self, callback):
+        files = {TESTMOD + ".py": (NOW, test_src),
+                 "xyz.txt": (NOW, ">>> log.append(True)\n")}
+        self.doTest(".py", files, TESTMOD, call=callback)
+
+    def doDoctestFile(self, module):
+        log = []
+        old_master, doctest.master = doctest.master, None
+        try:
+            doctest.testfile(
+                'xyz.txt', package=module, module_relative=True,
+                globs=locals()
+            )
+        finally:
+            doctest.master = old_master
+        self.assertEqual(log,[True])
+
+    def testDoctestFile(self):
+        self.runDoctest(self.doDoctestFile)
+
+    def doDoctestSuite(self, module):
+        log = []
+        doctest.DocFileTest(
+            'xyz.txt', package=module, module_relative=True,
+            globs=locals()
+        ).run()
+        self.assertEqual(log,[True])
+
+    def testDoctestSuite(self):
+        self.runDoctest(self.doDoctestSuite)
+
+
+    def doTraceback(self, module):
+        try:
+            module.do_raise()
+        except:
+            tb = sys.exc_info()[2].tb_next
+
+            f,lno,n,line = extract_tb(tb, 1)[0]
+            self.assertEqual(line, raise_src.strip())
+
+            f,lno,n,line = extract_stack(tb.tb_frame, 1)[0]
+            self.assertEqual(line, raise_src.strip())
+
+            s = StringIO.StringIO()
+            print_tb(tb, 1, s)
+            self.failUnless(s.getvalue().endswith(raise_src))
+        else:
+            raise AssertionError("This ought to be impossible")
+
+    def testTraceback(self):
+        files = {TESTMOD + ".py": (NOW, raise_src)}
+        self.doTest(None, files, TESTMOD, call=self.doTraceback)
+
+
+class CompressedZipImportTestCase(UncompressedZipImportTestCase):
+    compression = ZIP_DEFLATED
+
+
+class BadFileZipImportTestCase(unittest.TestCase):
+    def assertZipFailure(self, filename):
+        self.assertRaises(zipimport.ZipImportError,
+                          zipimport.zipimporter, filename)
+
+    def testNoFile(self):
+        self.assertZipFailure('AdfjdkFJKDFJjdklfjs')
+
+    def testEmptyFilename(self):
+        self.assertZipFailure('')
+
+    def testBadArgs(self):
+        self.assertRaises(TypeError, zipimport.zipimporter, None)
+        self.assertRaises(TypeError, zipimport.zipimporter, TESTMOD, kwd=None)
+
+    def testFilenameTooLong(self):
+        self.assertZipFailure('A' * 33000)
+
+    def testEmptyFile(self):
+        test_support.unlink(TESTMOD)
+        open(TESTMOD, 'w+').close()
+        self.assertZipFailure(TESTMOD)
+
+    def testFileUnreadable(self):
+        test_support.unlink(TESTMOD)
+        fd = os.open(TESTMOD, os.O_CREAT, 000)
+        try:
+            os.close(fd)
+            self.assertZipFailure(TESTMOD)
+        finally:
+            # If we leave "the read-only bit" set on Windows, nothing can
+            # delete TESTMOD, and later tests suffer bogus failures.
+            os.chmod(TESTMOD, 0666)
+            test_support.unlink(TESTMOD)
+
+    def testNotZipFile(self):
+        test_support.unlink(TESTMOD)
+        fp = open(TESTMOD, 'w+')
+        fp.write('a' * 22)
+        fp.close()
+        self.assertZipFailure(TESTMOD)
+
+    # XXX: disabled until this works on Big-endian machines
+    def _testBogusZipFile(self):
+        test_support.unlink(TESTMOD)
+        fp = open(TESTMOD, 'w+')
+        fp.write(struct.pack('=I', 0x06054B50))
+        fp.write('a' * 18)
+        fp.close()
+        z = zipimport.zipimporter(TESTMOD)
+
+        try:
+            self.assertRaises(TypeError, z.find_module, None)
+            self.assertRaises(TypeError, z.load_module, None)
+            self.assertRaises(TypeError, z.is_package, None)
+            self.assertRaises(TypeError, z.get_code, None)
+            self.assertRaises(TypeError, z.get_data, None)
+            self.assertRaises(TypeError, z.get_source, None)
+
+            error = zipimport.ZipImportError
+            self.assertEqual(z.find_module('abc'), None)
+
+            self.assertRaises(error, z.load_module, 'abc')
+            self.assertRaises(error, z.get_code, 'abc')
+            self.assertRaises(IOError, z.get_data, 'abc')
+            self.assertRaises(error, z.get_source, 'abc')
+            self.assertRaises(error, z.is_package, 'abc')
+        finally:
+            zipimport._zip_directory_cache.clear()
+
+
+def cleanup():
+    # this is necessary if test is run repeated (like when finding leaks)
+    global test_imported
+    if test_imported:
+        zipimport._zip_directory_cache.clear()
+        if hasattr(UncompressedZipImportTestCase, 'testAFakeZlib'):
+            delattr(UncompressedZipImportTestCase, 'testAFakeZlib')
+        if hasattr(CompressedZipImportTestCase, 'testAFakeZlib'):
+            delattr(CompressedZipImportTestCase, 'testAFakeZlib')
+    test_imported = True
+
+def test_main():
+    cleanup()
+    try:
+        test_support.run_unittest(
+              UncompressedZipImportTestCase,
+              CompressedZipImportTestCase,
+              BadFileZipImportTestCase,
+            )
+    finally:
+        test_support.unlink(TESTMOD)
+
+if __name__ == "__main__":
+    test_main()

Added: vendor/Python/current/Lib/test/test_zlib.py
===================================================================
--- vendor/Python/current/Lib/test/test_zlib.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/test_zlib.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,481 @@
+import unittest
+from test import test_support
+import zlib
+import random
+
+# print test_support.TESTFN
+
+def getbuf():
+    # This was in the original.  Avoid non-repeatable sources.
+    # Left here (unused) in case something wants to be done with it.
+    import imp
+    try:
+        t = imp.find_module('test_zlib')
+        file = t[0]
+    except ImportError:
+        file = open(__file__)
+    buf = file.read() * 8
+    file.close()
+    return buf
+
+
+
+class ChecksumTestCase(unittest.TestCase):
+    # checksum test cases
+    def test_crc32start(self):
+        self.assertEqual(zlib.crc32(""), zlib.crc32("", 0))
+        self.assert_(zlib.crc32("abc", 0xffffffff))
+
+    def test_crc32empty(self):
+        self.assertEqual(zlib.crc32("", 0), 0)
+        self.assertEqual(zlib.crc32("", 1), 1)
+        self.assertEqual(zlib.crc32("", 432), 432)
+
+    def test_adler32start(self):
+        self.assertEqual(zlib.adler32(""), zlib.adler32("", 1))
+        self.assert_(zlib.adler32("abc", 0xffffffff))
+
+    def test_adler32empty(self):
+        self.assertEqual(zlib.adler32("", 0), 0)
+        self.assertEqual(zlib.adler32("", 1), 1)
+        self.assertEqual(zlib.adler32("", 432), 432)
+
+    def assertEqual32(self, seen, expected):
+        # 32-bit values masked -- checksums on 32- vs 64- bit machines
+        # This is important if bit 31 (0x08000000L) is set.
+        self.assertEqual(seen & 0x0FFFFFFFFL, expected & 0x0FFFFFFFFL)
+
+    def test_penguins(self):
+        self.assertEqual32(zlib.crc32("penguin", 0), 0x0e5c1a120L)
+        self.assertEqual32(zlib.crc32("penguin", 1), 0x43b6aa94)
+        self.assertEqual32(zlib.adler32("penguin", 0), 0x0bcf02f6)
+        self.assertEqual32(zlib.adler32("penguin", 1), 0x0bd602f7)
+
+        self.assertEqual(zlib.crc32("penguin"), zlib.crc32("penguin", 0))
+        self.assertEqual(zlib.adler32("penguin"),zlib.adler32("penguin",1))
+
+
+
+class ExceptionTestCase(unittest.TestCase):
+    # make sure we generate some expected errors
+    def test_bigbits(self):
+        # specifying total bits too large causes an error
+        self.assertRaises(zlib.error,
+                zlib.compress, 'ERROR', zlib.MAX_WBITS + 1)
+
+    def test_badcompressobj(self):
+        # verify failure on building compress object with bad params
+        self.assertRaises(ValueError, zlib.compressobj, 1, zlib.DEFLATED, 0)
+
+    def test_baddecompressobj(self):
+        # verify failure on building decompress object with bad params
+        self.assertRaises(ValueError, zlib.decompressobj, 0)
+
+
+
+class CompressTestCase(unittest.TestCase):
+    # Test compression in one go (whole message compression)
+    def test_speech(self):
+        x = zlib.compress(HAMLET_SCENE)
+        self.assertEqual(zlib.decompress(x), HAMLET_SCENE)
+
+    def test_speech128(self):
+        # compress more data
+        data = HAMLET_SCENE * 128
+        x = zlib.compress(data)
+        self.assertEqual(zlib.decompress(x), data)
+
+
+
+
+class CompressObjectTestCase(unittest.TestCase):
+    # Test compression object
+    def test_pair(self):
+        # straightforward compress/decompress objects
+        data = HAMLET_SCENE * 128
+        co = zlib.compressobj()
+        x1 = co.compress(data)
+        x2 = co.flush()
+        self.assertRaises(zlib.error, co.flush) # second flush should not work
+        dco = zlib.decompressobj()
+        y1 = dco.decompress(x1 + x2)
+        y2 = dco.flush()
+        self.assertEqual(data, y1 + y2)
+
+    def test_compressoptions(self):
+        # specify lots of options to compressobj()
+        level = 2
+        method = zlib.DEFLATED
+        wbits = -12
+        memlevel = 9
+        strategy = zlib.Z_FILTERED
+        co = zlib.compressobj(level, method, wbits, memlevel, strategy)
+        x1 = co.compress(HAMLET_SCENE)
+        x2 = co.flush()
+        dco = zlib.decompressobj(wbits)
+        y1 = dco.decompress(x1 + x2)
+        y2 = dco.flush()
+        self.assertEqual(HAMLET_SCENE, y1 + y2)
+
+    def test_compressincremental(self):
+        # compress object in steps, decompress object as one-shot
+        data = HAMLET_SCENE * 128
+        co = zlib.compressobj()
+        bufs = []
+        for i in range(0, len(data), 256):
+            bufs.append(co.compress(data[i:i+256]))
+        bufs.append(co.flush())
+        combuf = ''.join(bufs)
+
+        dco = zlib.decompressobj()
+        y1 = dco.decompress(''.join(bufs))
+        y2 = dco.flush()
+        self.assertEqual(data, y1 + y2)
+
+    def test_decompinc(self, flush=False, source=None, cx=256, dcx=64):
+        # compress object in steps, decompress object in steps
+        source = source or HAMLET_SCENE
+        data = source * 128
+        co = zlib.compressobj()
+        bufs = []
+        for i in range(0, len(data), cx):
+            bufs.append(co.compress(data[i:i+cx]))
+        bufs.append(co.flush())
+        combuf = ''.join(bufs)
+
+        self.assertEqual(data, zlib.decompress(combuf))
+
+        dco = zlib.decompressobj()
+        bufs = []
+        for i in range(0, len(combuf), dcx):
+            bufs.append(dco.decompress(combuf[i:i+dcx]))
+            self.assertEqual('', dco.unconsumed_tail, ########
+                             "(A) uct should be '': not %d long" %
+                                       len(dco.unconsumed_tail))
+        if flush:
+            bufs.append(dco.flush())
+        else:
+            while True:
+                chunk = dco.decompress('')
+                if chunk:
+                    bufs.append(chunk)
+                else:
+                    break
+        self.assertEqual('', dco.unconsumed_tail, ########
+                         "(B) uct should be '': not %d long" %
+                                       len(dco.unconsumed_tail))
+        self.assertEqual(data, ''.join(bufs))
+        # Failure means: "decompressobj with init options failed"
+
+    def test_decompincflush(self):
+        self.test_decompinc(flush=True)
+
+    def test_decompimax(self, source=None, cx=256, dcx=64):
+        # compress in steps, decompress in length-restricted steps
+        source = source or HAMLET_SCENE
+        # Check a decompression object with max_length specified
+        data = source * 128
+        co = zlib.compressobj()
+        bufs = []
+        for i in range(0, len(data), cx):
+            bufs.append(co.compress(data[i:i+cx]))
+        bufs.append(co.flush())
+        combuf = ''.join(bufs)
+        self.assertEqual(data, zlib.decompress(combuf),
+                         'compressed data failure')
+
+        dco = zlib.decompressobj()
+        bufs = []
+        cb = combuf
+        while cb:
+            #max_length = 1 + len(cb)//10
+            chunk = dco.decompress(cb, dcx)
+            self.failIf(len(chunk) > dcx,
+                    'chunk too big (%d>%d)' % (len(chunk), dcx))
+            bufs.append(chunk)
+            cb = dco.unconsumed_tail
+        bufs.append(dco.flush())
+        self.assertEqual(data, ''.join(bufs), 'Wrong data retrieved')
+
+    def test_decompressmaxlen(self, flush=False):
+        # Check a decompression object with max_length specified
+        data = HAMLET_SCENE * 128
+        co = zlib.compressobj()
+        bufs = []
+        for i in range(0, len(data), 256):
+            bufs.append(co.compress(data[i:i+256]))
+        bufs.append(co.flush())
+        combuf = ''.join(bufs)
+        self.assertEqual(data, zlib.decompress(combuf),
+                         'compressed data failure')
+
+        dco = zlib.decompressobj()
+        bufs = []
+        cb = combuf
+        while cb:
+            max_length = 1 + len(cb)//10
+            chunk = dco.decompress(cb, max_length)
+            self.failIf(len(chunk) > max_length,
+                        'chunk too big (%d>%d)' % (len(chunk),max_length))
+            bufs.append(chunk)
+            cb = dco.unconsumed_tail
+        if flush:
+            bufs.append(dco.flush())
+        else:
+            while chunk:
+                chunk = dco.decompress('', max_length)
+                self.failIf(len(chunk) > max_length,
+                            'chunk too big (%d>%d)' % (len(chunk),max_length))
+                bufs.append(chunk)
+        self.assertEqual(data, ''.join(bufs), 'Wrong data retrieved')
+
+    def test_decompressmaxlenflush(self):
+        self.test_decompressmaxlen(flush=True)
+
+    def test_maxlenmisc(self):
+        # Misc tests of max_length
+        dco = zlib.decompressobj()
+        self.assertRaises(ValueError, dco.decompress, "", -1)
+        self.assertEqual('', dco.unconsumed_tail)
+
+    def test_flushes(self):
+        # Test flush() with the various options, using all the
+        # different levels in order to provide more variations.
+        sync_opt = ['Z_NO_FLUSH', 'Z_SYNC_FLUSH', 'Z_FULL_FLUSH']
+        sync_opt = [getattr(zlib, opt) for opt in sync_opt
+                    if hasattr(zlib, opt)]
+        data = HAMLET_SCENE * 8
+
+        for sync in sync_opt:
+            for level in range(10):
+                obj = zlib.compressobj( level )
+                a = obj.compress( data[:3000] )
+                b = obj.flush( sync )
+                c = obj.compress( data[3000:] )
+                d = obj.flush()
+                self.assertEqual(zlib.decompress(''.join([a,b,c,d])),
+                                 data, ("Decompress failed: flush "
+                                        "mode=%i, level=%i") % (sync, level))
+                del obj
+
+    def test_odd_flush(self):
+        # Test for odd flushing bugs noted in 2.0, and hopefully fixed in 2.1
+        import random
+
+        if hasattr(zlib, 'Z_SYNC_FLUSH'):
+            # Testing on 17K of "random" data
+
+            # Create compressor and decompressor objects
+            co = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
+            dco = zlib.decompressobj()
+
+            # Try 17K of data
+            # generate random data stream
+            try:
+                # In 2.3 and later, WichmannHill is the RNG of the bug report
+                gen = random.WichmannHill()
+            except AttributeError:
+                try:
+                    # 2.2 called it Random
+                    gen = random.Random()
+                except AttributeError:
+                    # others might simply have a single RNG
+                    gen = random
+            gen.seed(1)
+            data = genblock(1, 17 * 1024, generator=gen)
+
+            # compress, sync-flush, and decompress
+            first = co.compress(data)
+            second = co.flush(zlib.Z_SYNC_FLUSH)
+            expanded = dco.decompress(first + second)
+
+            # if decompressed data is different from the input data, choke.
+            self.assertEqual(expanded, data, "17K random source doesn't match")
+
+    def test_empty_flush(self):
+        # Test that calling .flush() on unused objects works.
+        # (Bug #1083110 -- calling .flush() on decompress objects
+        # caused a core dump.)
+
+        co = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
+        self.failUnless(co.flush())  # Returns a zlib header
+        dco = zlib.decompressobj()
+        self.assertEqual(dco.flush(), "") # Returns nothing
+
+    if hasattr(zlib.compressobj(), "copy"):
+        def test_compresscopy(self):
+            # Test copying a compression object
+            data0 = HAMLET_SCENE
+            data1 = HAMLET_SCENE.swapcase()
+            c0 = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
+            bufs0 = []
+            bufs0.append(c0.compress(data0))
+
+            c1 = c0.copy()
+            bufs1 = bufs0[:]
+
+            bufs0.append(c0.compress(data0))
+            bufs0.append(c0.flush())
+            s0 = ''.join(bufs0)
+
+            bufs1.append(c1.compress(data1))
+            bufs1.append(c1.flush())
+            s1 = ''.join(bufs1)
+
+            self.assertEqual(zlib.decompress(s0),data0+data0)
+            self.assertEqual(zlib.decompress(s1),data0+data1)
+
+        def test_badcompresscopy(self):
+            # Test copying a compression object in an inconsistent state
+            c = zlib.compressobj()
+            c.compress(HAMLET_SCENE)
+            c.flush()
+            self.assertRaises(ValueError, c.copy)
+
+    if hasattr(zlib.decompressobj(), "copy"):
+        def test_decompresscopy(self):
+            # Test copying a decompression object
+            data = HAMLET_SCENE
+            comp = zlib.compress(data)
+
+            d0 = zlib.decompressobj()
+            bufs0 = []
+            bufs0.append(d0.decompress(comp[:32]))
+
+            d1 = d0.copy()
+            bufs1 = bufs0[:]
+
+            bufs0.append(d0.decompress(comp[32:]))
+            s0 = ''.join(bufs0)
+
+            bufs1.append(d1.decompress(comp[32:]))
+            s1 = ''.join(bufs1)
+
+            self.assertEqual(s0,s1)
+            self.assertEqual(s0,data)
+
+        def test_baddecompresscopy(self):
+            # Test copying a compression object in an inconsistent state
+            data = zlib.compress(HAMLET_SCENE)
+            d = zlib.decompressobj()
+            d.decompress(data)
+            d.flush()
+            self.assertRaises(ValueError, d.copy)
+
+def genblock(seed, length, step=1024, generator=random):
+    """length-byte stream of random data from a seed (in step-byte blocks)."""
+    if seed is not None:
+        generator.seed(seed)
+    randint = generator.randint
+    if length < step or step < 2:
+        step = length
+    blocks = []
+    for i in range(0, length, step):
+        blocks.append(''.join([chr(randint(0,255))
+                               for x in range(step)]))
+    return ''.join(blocks)[:length]
+
+
+
+def choose_lines(source, number, seed=None, generator=random):
+    """Return a list of number lines randomly chosen from the source"""
+    if seed is not None:
+        generator.seed(seed)
+    sources = source.split('\n')
+    return [generator.choice(sources) for n in range(number)]
+
+
+
+HAMLET_SCENE = """
+LAERTES
+
+       O, fear me not.
+       I stay too long: but here my father comes.
+
+       Enter POLONIUS
+
+       A double blessing is a double grace,
+       Occasion smiles upon a second leave.
+
+LORD POLONIUS
+
+       Yet here, Laertes! aboard, aboard, for shame!
+       The wind sits in the shoulder of your sail,
+       And you are stay'd for. There; my blessing with thee!
+       And these few precepts in thy memory
+       See thou character. Give thy thoughts no tongue,
+       Nor any unproportioned thought his act.
+       Be thou familiar, but by no means vulgar.
+       Those friends thou hast, and their adoption tried,
+       Grapple them to thy soul with hoops of steel;
+       But do not dull thy palm with entertainment
+       Of each new-hatch'd, unfledged comrade. Beware
+       Of entrance to a quarrel, but being in,
+       Bear't that the opposed may beware of thee.
+       Give every man thy ear, but few thy voice;
+       Take each man's censure, but reserve thy judgment.
+       Costly thy habit as thy purse can buy,
+       But not express'd in fancy; rich, not gaudy;
+       For the apparel oft proclaims the man,
+       And they in France of the best rank and station
+       Are of a most select and generous chief in that.
+       Neither a borrower nor a lender be;
+       For loan oft loses both itself and friend,
+       And borrowing dulls the edge of husbandry.
+       This above all: to thine ownself be true,
+       And it must follow, as the night the day,
+       Thou canst not then be false to any man.
+       Farewell: my blessing season this in thee!
+
+LAERTES
+
+       Most humbly do I take my leave, my lord.
+
+LORD POLONIUS
+
+       The time invites you; go; your servants tend.
+
+LAERTES
+
+       Farewell, Ophelia; and remember well
+       What I have said to you.
+
+OPHELIA
+
+       'Tis in my memory lock'd,
+       And you yourself shall keep the key of it.
+
+LAERTES
+
+       Farewell.
+"""
+
+
+def test_main():
+    test_support.run_unittest(
+        ChecksumTestCase,
+        ExceptionTestCase,
+        CompressTestCase,
+        CompressObjectTestCase
+    )
+
+if __name__ == "__main__":
+    test_main()
+
+def test(tests=''):
+    if not tests: tests = 'o'
+    testcases = []
+    if 'k' in tests: testcases.append(ChecksumTestCase)
+    if 'x' in tests: testcases.append(ExceptionTestCase)
+    if 'c' in tests: testcases.append(CompressTestCase)
+    if 'o' in tests: testcases.append(CompressObjectTestCase)
+    test_support.run_unittest(*testcases)
+
+if False:
+    import sys
+    sys.path.insert(1, '/Py23Src/python/dist/src/Lib/test')
+    import test_zlib as tz
+    ts, ut = tz.test_support, tz.unittest
+    su = ut.TestSuite()
+    su.addTest(ut.makeSuite(tz.CompressTestCase))
+    ts.run_suite(su)

Added: vendor/Python/current/Lib/test/testall.py
===================================================================
--- vendor/Python/current/Lib/test/testall.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/testall.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,4 @@
+# Backward compatibility -- you should use regrtest instead of this module.
+import sys, regrtest
+sys.argv[1:] = ["-vv"]
+regrtest.main()

Added: vendor/Python/current/Lib/test/testcodec.py
===================================================================
--- vendor/Python/current/Lib/test/testcodec.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/testcodec.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,48 @@
+""" Test Codecs (used by test_charmapcodec)
+
+Written by Marc-Andre Lemburg (mal at lemburg.com).
+
+(c) Copyright 2000 Guido van Rossum.
+
+"""#"
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+
+        return codecs.charmap_encode(input,errors,encoding_map)
+
+    def decode(self,input,errors='strict'):
+
+        return codecs.charmap_decode(input,errors,decoding_map)
+
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+
+    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+
+### Decoding Map
+
+decoding_map = codecs.make_identity_dict(range(256))
+decoding_map.update({
+        0x78: u"abc", # 1-n decoding mapping
+        "abc": 0x0078,# 1-n encoding mapping
+        0x01: None,   # decoding mapping to <undefined>
+        0x79: u"",    # decoding mapping to <remove character>
+})
+
+### Encoding Map
+
+encoding_map = {}
+for k,v in decoding_map.items():
+    encoding_map[v] = k

Added: vendor/Python/current/Lib/test/testimg.uue
===================================================================
--- vendor/Python/current/Lib/test/testimg.uue	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/testimg.uue	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1170 @@
+begin 755 test.rawimg
+M___Y^/\A$Q3_*1LC_QL4'/\;%AS_%Q(6_QP7&?\B&AW_'A<7_QT5&/\7$A3_
+M&108_Q84%O\7%1?_$Q 6_Q<3'/\:$Q__'1<;_R$:&O\5$Q7_'!D8_SHW-O\\
+M.CW_141*_TE)3/]/3U+_'1DA_R,<)O\B'"3_249,_T=$2O]$0D7_.3<Z_T1"
+M1?].3$__44]2_QD2'/\;%![_*24M_U166_]55US_55=<_UQ>8_]<7F/_%1$9
+M_QH6'O\B(2C_65A>_U587?]87%[_65M>_Q at 5&_\@'"3_%Q8<_U%34?]<6E7_
+M5U9/_U-14_\:%A__'AHB_TA&2/\]/CC_24I$_RDG*O\B'B;_)",I_UI;7/];
+M65;_7EA6_X%\?/^!?GW_7E]@_U!45O]45US_4U5:_U)46_].4%?_2TU4_T9(
+M3_]#14S_1$E/_TA)4/](1T[_1D=._TI/5?])2E'_2$=._T-%3/])2U+_2$E0
+M_T9'3O]#1$O_0D1,_T!"2O]#14S_1DE._T5(3?]$1TS_0$-(_T1'3/]!0TC_
+M0T)(_S\^1/]#0DC_04-(_SD\0?\[0$7_0#]%_SY 1?\Z/$'_.CQ!_SH\0?\[
+M.S[_/SU _Q43%O\E(R;_%Q48_S0R-?\7%1C_)R4H_Q02%?\2$!/_%!(5_Q,1
+M%/\5$Q;_^>[U_SXT/O\F'"O_'QDA_QD4&/\6$17_%1 4_Q<2%O\:%1G_&!,7
+M_Q40%/\8$Q?_%Q03_Q<3%?\:%1O_'1<?_QL4'O\L)RW_(1T?_QP7&_\5$Q;_
+M'AP?_QT;'O\<&AW_03]"_TE'2O\:%A[_'AHC_QT8'/\8%!;_'!@:_Q\;'?\@
+M&Q__(ATA_R0?(_\H(R?_&1,;_Q at 4'/\='R3_2T]1_TU/4O]04%/_45%4_U14
+M5_\7$QO_&14=_R\M,/]I:6;_5597_U%34?]14$__'!<=_R,<*/\8%1O_6%A5
+M_UA85?];6%/_5%!2_QL7(/\;&B'_6%98_UM:4_];653_)2(A_R$=)?\<&1__
+M7UU at _T=%1_\M*RW_(B B_R at G)O]24TW_>7YX_Y&1CO]O:FS_5U=:_U)45_]1
+M4U;_4%)7_TY/5O])4%;_2$]5_T1(4/]%1E'_1DA0_T=)4/]&2$__1$9-_T%#
+M2O]$1DW_04-*_T!"2?] 0DG_04-*_T1&3?]!0TK_/D%&_T)%2O]!1$G_1$=,
+M_T%#2O]!0TK_/3]&_T!"2?] 0D?_/D!%_S]!1O\^0$7_.3M _ST_1/\\/D/_
+M.CQ!_ST[/O\W-3?_,C R_S N,/\M*2O_)B(D_Q82%/\7$Q7_%1 4_Q(-$?\7
+M$A;_%1 4_Q81%?__]?K_+R4N_T<^2_\A'"+_&A49_Q81%?\5$!3_&!,7_Q81
+M%?\6$17_%1 4_Q at 3%_\7$1G_%Q(8_PT(#/]V<G3_241*_QD5%_\:&!/_&!44
+M_Q(0$_\5$Q;_%1,6_Q,1%/\3$13_#0L._QD5'?\=&2+_'1@<_Q at 4%O\3#Q'_
+M%! 2_Q<2%O\6$17_&108_QP7&_\4$!C_%Q,;_QX;(?\=&Q[_(1\A_S$O,?\_
+M/3__3$I,_Q<3&_\9%1W_)2,F_U%13O]14U'_3U),_U)23_\=&!S_(QPF_QH7
+M'?]965;_5552_U933O]85%;_&Q<@_QD8'_]85U;_65I4_UA94O\E(R7_'!LA
+M_QL:(/]<6V'_75QB_V%@9O\7%AS_)"0G_U=86?]04$W_5U%/_UY65/]64E#_
+M>GUW_V!C7?]765?_5E=8_TQ15O]+3U?_2E!:_T=*5O].4%C_2DQ3_T=)4/]'
+M25#_14=._T9(3_]'25#_1$9-_SY 1_] 0DG_.SU$_T-%3/] 0TC_041)_TI-
+M4O\^04;_/T%(_S]!2/\^0$?_0D1+_SY 1?\^0$7_/T%&_SY 1?\Z.CW_,C(U
+M_RTM,/\G)RK_*RDK_R at F*/\J*"K_(R$C_R4A(_\I)2?_(AX at _RXJ+/\9%!C_
+M% \3_Q at 3%_\3#A+_&!,7__KQ\?\@%Q[_&Q0<_QL6&O\8$Q?_%1 4_Q40%/\5
+M$!3_%1 4_Q40%/\4#Q/_%Q(6_Q<3%?\7$A;_$PX2_Q at 3&?\<%1__&!,7_Q42
+M$?\4$!+_$0\2_Q(0$_\3$13_$Q$4_Q,1%/\4$A7_%A(:_QP8(?\;%AK_'!@:
+M_Q\;'?\;%QG_%Q(6_Q40%/\5$!3_% \3_Q,/%_\7$QO_'AD?_Q\9'?\=&1O_
+M(R ?_R<D(_\A'AW_%A(:_Q at 4'/\@'B'_2TM(_TU/3/].4DK_3D](_QP8&O\>
+M%R'_&Q@>_U964_]:6E?_7%E4_UE55_\8%!W_&AD at _V!?9?]=7E__86)C_ST\
+M0_\6%Q[_&QTB_V%B:?]B8FO_86%L_Q<7(/\B(RK_3E!5_U-56O]74EC_)Q\C
+M_R4D(_];6UC_75Y8_VMJ:?^5DY7_A(""_UE65?]86%O_4U5:_U!26?].4%?_
+M2TU4_TE+4O]+353_1TE0_T)$2_]$1DW_1$9-_T-%3/]!0TK_04-*_SY!1O] 
+M0TC_0$-(_T%$2?\\/D7_/3]&_ST_1O\^0$?_/3]$_SP^0_\]/T3_.#H__S(P
+M,_\J*"K_*RDK_R at F*/\H)BC_*2<I_R<E)_\D(B3_)R,E_R at D)O\I)2?_*24G
+M_R4@)/\8$Q?_%Q(6_Q at 3%_\4#Q/_^_+R_R8;(/\;$AG_%Q,5_Q at 3%_\5$!3_
+M%1 4_Q40%/\5$!3_%1 4_Q0/$_\7$A;_%Q,5_Q<3%?\5$!3_&!$;_S0J.?\:
+M$QO_%1 4_Q0/%?\1#Q+_$A 3_Q$/$O\/#1#_#0T0_Q 0$_\?'"+_&Q<?_Q81
+M%?\5$1/_$P\1_Q00$O\2#1'_$PX2_Q(-$?\3#A+_$1 7_Q<3&_\8$AK_&1$5
+M_QD4%O\M*"C_14$__STZ.?\6$AK_&!0=_RDF+/]245#_35%/_U%34/]24TW_
+M)R0C_R <)?\='"+_6UU;_V-B8?]=6UC_9V-E_QD5'O\:&"'_6EIC_V)C:O]H
+M:7#_1450_Q46'?\:'"'_7U]H_V1D;_]B8FW_$A(=_QL;)/]A8FG_7F!H_V%?
+M:/\?&R/_'!XC_SY /O\Z.#K_'AP?_R at E*_]:55#_8%M6_W9R</]D86#_5EA;
+M_U=97/]:7&'_45-8_TQ15_]*3E;_14E1_TA*4?]%1T[_149-_T-%3/]%1T[_
+M0D5*_SP_1/\]0$7_041)_SU 1?\^0$?_/#Y%_SP^1?\X.C__.CD__RPK,?\I
+M*"[_+BPN_RHH*O\J*"K_)R4G_RDG*?\E(R7_*"8H_R4C)?\F(B3_)R,E_R(>
+M(/\E(2/_)B$E_R,>(O\W,C;_)!\C_Q81%?_\\//_'A07_S$I+/\L)RG_'!<;
+M_Q0/$_\5$!3_% \3_Q40%/\5$!3_% \3_Q<2%O\3#QC_%Q(8_Q at 3%_\8$1G_
+M$PP3_Q<1%?\5$!3_$1$4_Q(0$_\2$!/_$0\2_Q$/$O\0$!/_#0\2_Q43%O\@
+M&Q__%1,6_Q(0$_\1#Q+_$0\2_Q$/$O\0#A'_$0\2_Q .$?\1$A/_&!<>_Q at 4
+M'/\A'1__$0\1_TI&1/]54$K_(R(A_Q,1&O\5$QS_+2PR_U-45?]-4%7_5EE>
+M_UY=8_\P+3/_'!@@_Q<8'_]>8VG_8F%H_V)A9_]C8FG_&!8?_Q<4(/]>7V;_
+M8&%H_V!A:/]45EO_&QHA_Q at 7'O]E9&K_961J_U]>9/\9%R#_'!HC_TU-4/\Q
+M,S#_)R<J_QL:(?\9&![_04 __RTK+O\@'"3_)R0J_T ]./]"/D#_(1XD_Q\?
+M(O]D95__ at H-]_Y:5E/]G96C_55E;_U587?].4%?_2DI3_TA'3O]&1T[_14=.
+M_T%&3/\^0TC_0$5*_SY#2/\]0D?_/D!#_SX^0?\T-#?_+R\R_RPJ+?\K*2S_
+M*B at K_RHH*_\K*2O_*"8H_RDG*?\H)BC_*2<J_R8D)_\E(R;_)2,F_R8D)O\D
+M(B3_)"(D_R0B)/\D(B3_)"(D_R(@(O\F)";_$@X0___V^?\@&!O_'AD;_QD5
+M%_\9%!C_%Q(6_QP7&_\9%!C_%A$5_Q81%?\5$!3_&!,7_Q<1%?\@&QO_%Q03
+M_Q<4&O\>("7_'B C_R at L+O\;'R'_$1$4_Q$1%/\0$!/_$! 3_Q(0$_\3#A+_
+M&A08_W!H;/\7$A;_$A 3_Q$/$O\1#Q+_$0\2_Q .$?\1#Q+_$ X1_QD9'/]/
+M2U/_-S(X_R,@&_\].S/_5U!$_UI00?]>5TO_&A4;_Q at 4'/\X-CG_/#LZ_SY!
+M0O]14UC_45)9_RPM-/\?&R/_%Q@?_V%F;/]H9V[_;6QR_V]N=?\6%!W_&Q at D
+M_UU;9/]F9FG_9VAI_UM:8/\8%A__&AD at _V-C9O]H:FC_969G_Q85'/\4$QK_
+M5E=8_U]A7O]65EG_%A4<_QD8'O] /S[_)R4H_QH6'O\B'R7_9V-A_V%<8/\<
+M&"#_(2 F_T=%1_\>'![_*"8H_UY<7O]Z=7#_J:&=_W=R=/];6%[_5%5<_TY.
+M5_]$1D[_/4-+_S@[0/\Y/$'_+S(W_RDL,?\K*2S_+RHN_RTH+/\M*"S_*RDL
+M_R at H*_\F)BG_)B8I_R8F*?\E)2C_*"@K_R<G*O\G)RK_)"0G_R0D)_\E)2C_
+M*"8H_R<E)_\E(R7_)2,E_R4C)?\E(R7_*"8H_R(@(O\M*2O_^/#S_RDD)O\=
+M&1O_&QD;_WQW>_\6$17_&A49_QD4&/\8$Q?_&!,7_Q\:'O\F(27_2T5#_Y"+
+MA?^+B83_'Q\B_V)G;/]26%K_2DY0_S<W.O\K+3#_*"HM_R0F*?\:'!__%148
+M_Q04%_\9%!C_$PT1_Q(0$_\3$13_$0\2_Q$/$O\0#A'_$0\2_Q$/$O\0#A'_
+M$0X4_SXX0/\=%QO_)R,;_TI%.?]>4D/_;%E'_W5 at 5/\I(27_,BTS_T1 0O]"
+M0#W_55!*_U%,1O]'0D+_.C4Y_Q\;(_\7&!__4UA>_U-26?]/3E3_5U9=_Q at 6
+M'_\[.$3_,R\X_UM96_];7%;_6%99_QH7(_\9&!__6UQ=_U]C6_]@8F#_&!<=
+M_QH9'_]?85__8&)?_UY>8?\8%Q[_%Q8<_T5$0_\V-#?_&!0<_QT:(/]K9F;_
+M;6AN_QD5'O\<&R+_;VQR_QT:(/\C(23_5U57_R8@)/\L)"C_4DU-_UM65O^ 
+M>WO_A8""_T1 0O\T,C3_)"0G_Q\>)/\;&B#_$A$7_R(B)?\H)BG_*RDL_S(P
+M,_\R-#?_-SD\_SD[/O\Z/#__.3M _S at Z/_\V.#W_-3<\_S(T-_\L+C'_*"HM
+M_R<I+/\J*"K_*"8H_R at F*/\H)BC_)R4G_R<E)_\F)";_*"8H_QD5%__\]/?_
+M)R(D_QD7&?\6%QC_DI"3_Q\:'O\8$Q?_&!,7_Q<2%O\4$A7_%1,6_QD4&/]$
+M/#C_EY&'_YF8D?_!Q,7_M+F^_Z^SM?^VM+?_P;F]_V5C9?]G:FO_76!A_S,V
+M-_\D*2G_(28F_R C)/\C)"7_(B B_QT;'O\8%AG_%A07_Q .$?\3#A+_$PX2
+M_Q(-$?\B'2'_/SD]_RPF)/]>5TO_:V%6_UU/0/]\9%7_?F19_RT>(O\H(RG_
+M-S,U_SX[-O]E6D__85=)_U=,1?\\-C3_&A8>_Q<8'_\\/T3_/3Q"_QX;(?\<
+M&R'_#PT6_R8B*_\M(B?_)2(=_UI<4_]3453_&Q at D_QD9(O]97%W_5UQ6_UI<
+M6?\9&1S_&1@>_UYB8/]O<6__9&1G_Q at 7'O\<&R'_/T$__RDI+/\9%1W_'1DA
+M_S\]/_\=&B#_&14>_Q<6'?\Q,#;_&Q@>_QP:'?]J:6C_(A\K_R =*?]02T__
+M3$9$_RHB'O\H(!S_3TI%_VAE8/^)A8?_6%99_TE'2O\5%!K_24Q1_T9)3O\\
+M/T3_0$-(_SY!1O]"14K_14A-_T!#2/]!1$G_/T!'_SH[0O\\/43_.3M _SL]
+M0/\]/T+_+S$T_RLL+?\L*BS_*2<I_RDG*?\H)BC_*"8H_R at F*/\=&QW_%A(4
+M__;R\/\_.CK_+2LM_R<G*O^:F)O_&!,7_Q at 3%_\9%!C_'!@:_Q43%?\:'1[_
+M&!89_Q\;&?^:E8__F92._];9VO_/T]7_T-#3_\W(RO_+O\#_8E97_T="0O]_
+M at 7__8E]>_U-34/]"0C__,S,P_RXN*_\X.S7_-#8S_RLM*_\C(R;_'!D8_Q83
+M$O\1#!#_%1 6_R 9&?]%0SS_5E-(_VUC5?^ <F/_<V56_VY<3O]O6TW_74Y/
+M_UM77_\H*S#_14(]_V=;4O]F64S_6U!%_TI&1/\C'R?_&A@;_U554O\>'1S_
+M&A45_QD6'/\8%Q[_'QD=_T at N(?]*."K_4E-,_T9%2_\@&R?_%QDA_UYG;?]B
+M9VS_:&=F_QT:(/\;&R;_0D1,_S at Z/?\M+#/_&!8?_Q85&_\\03W_#0\2_Q01
+M'?\8%A__$1D=_T5'3/\8%1O_%!8;_TQ.3/\:&!O_(R F_V9D9O\L*#'_'QLC
+M_VAF:/]=6F#_(R F_T9$1_\A'R+_)"(E_U!*2/]%/SW_1D1'_Q45'O]B9&G_
+M4$]5_TQ+4?])2$[_24M0_T9(3?\_04;_0$)'_TU,4O\U-#K_,"\U_RTL,O\K
+M*C#_*RHP_RHI+_\I*"[_)R<J_RDJ*_\I*BO_*2HK_RLI+/\I)RK_*B at K_QL9
+M'/\9%1?_\_7R_SP^//\A'R'_CXJ._T]-4/\6%!?_%Q48_Q43%O\C&Q__&108
+M_QT@(?\6&!;_&Q\=_Y"1B_^BFY7_U<_-_];+RO_5R<7_T\K$_\W'O_^>DI/_
+M% \1_QD:&_\;%QG_&!,3_QD4%/\>&1G_%A$1_R4F(/\R-2__0$,]_T)%/_\R
+M,B__+BXK_R$@'_\1#Q'_(!L;_T1"._]$03;_7%)$_WIK7O]31#?_0C,F_U-"
+M-?]:2TO_'AD?_R,E*/]234?_;6)7_V582_]K7E'_95Q5_U)-4?].2TK_:FAC
+M_Q41$_\6$A3_&A<=_Q83&?\J'A__6#TL_TTX)O]H7UC_;FIL_QX7(?\@'R;_
+M4UM?_V%E9_^)B(?_%!$7_Q<3'/^"@(/_?X%^_V-C9O\8%A__%!,9_TY,1_\6
+M$Q+_&14>_Q at 7'O\8("3_5%9;_Q,0%O\@(B?_65I;_Q,2&/\H)R[_9&1G_S0P
+M.?\?&R/_9V5G_V%>9/\3$!;_5U58_QX<'_\C(23_96-F_QP;(?\6%A__1TI5
+M_R <'O]D7U__ at GU]_UU86/].3$__2DI-_T]/4O]&1DG_0$)'_T)$2?\^0$7_
+M/3]$_SY 1?\Y.T#_/D!%_ST_1/\]/4#_/S]"_SX^0?\_/T+_/CY!_SP\/_\S
+M,S;_(" C_QH6&/_\^O?_*R at G_Q@6&/\;&1S_+2TP_Q at 8&_\6%AG_%!07_QX=
+M)/\4%AO_%1 at 9_RDF(?\>'R#_CXZ-_YZ8D/_3SLG_T\O)_]7+Q__3RL3_R\6]
+M_Z.7F/\8$A;_&1D<_Q at 3%_\<&!K_&A88_QP8&O\7$Q7_$1(3_QT>'_\;'1K_
+M)"<A_QP@&/] 0SW_)2<D_Q47%?\>&AC_24= _U932/]I7U'_>&9<_UA(/O]%
+M."W_4D<\_V)34_\:$A;_&!H8_W)L9/]E6U'_;6!3_VI:2O]S9EO_55!+_VEG
+M8/]:6%'_$PX0_Q40%/\5$AC_'QH<_T4V,?];/BS_2C =_Y:&??^&?W__)!TD
+M_RDF+/]B:&K_?'^ _XF*B_\7%!K_&Q8<_WMW=?]O<6C_8F1A_QH9(/\7%AS_
+M14 [_T])1_\;%1W_%1<<_QHB)O\Y.T#_&18<_Q06&_]'24S_#Q 7_QP<)?]0
+M4E?_-C$]_Q\;(_]A7V'_6%5;_Q,0%O]85EG_'AP?_Q\=(/\[.D#_&!<=_Q01
+M%_\6$QG_&108_Q(,$/\J)"C_2D1(_U)04O]T<G3_7%I<_UA66/]+35+_1TI/
+M_T9)3O]"14K_/T)'_SL^0_\X.T#_,S8[_RXP-?\N+3/_+BTS_RXM,_\K+3#_
+M*RTP_RXP,_\K+3#_(!X at ___T]?\O)RK_&1D<_WM^?_^3E)7_%Q<:_QT=(/]I
+M96?_;6QR_Q(5&O\F)RC_'!00_RPH*O^0BXO_F)2,_\[-QO_4T=#_T<S,_];0
+MSO_*P+S_IIJ=_QX7'O\;&![_%1(8_Q46%_\3%!7_%A<8_Q 1$O\.#1/_'!LA
+M_Q at 9&O\>(![_*"TG_SQ!._\K,"S_*S L_R\K*?]!/#;_5U%'_VA>4/]B4$;_
+M4$ V_T4Z+_]=4TC_7U)-_Q40$O\0$!/_;FEC_VQB6/][;F'_>6M<_X1W:O]C
+M7%;_8%Q4_W%L9O\>%AG_%1 6_Q(0$_\@&1G_5$$Y_V%#+?]4-R7_D'UU_X^'
+MA?\K)"O_8%]E_U!45O]04U3_3$U._P<&#/\C(23_14$__U)63?\F*"7_'ATC
+M_Q at 7'?]-1D#_6%!._QL6'/\7%AS_*# T_U987?\;&![_%!8;_T1&2?\4%AO_
+M'1TH_T1&2_\M*S3_'QPB_TY,3O]/3%+_%!$7_UA66?\>'!__%A07_Q$,$/\:
+M%AC_&!,5_R$:&O\;%AS_$P\7_QL7'_\=&2'_'!H=_R >(?\?'2#_4E!3_V]Q
+M=/]565O_35%3_TI.4/]#2$W_/T1)_SY#2/\_1$G_0$%(_T-"2?]"04C_0D%(
+M_ST_1/\]04/_.CY _S8Z//\5$Q7_^O+U_S0O-?\D(RG_;VIJ_Y:2D/\>&1W_
+M+2 at L_Z"5E/^+?WO_'1<;_QH9'_\=&QW_'1X?_Y60D/^>E8[_S\K%_];/S__8
+MS\__U,K&_]C,Q_^=E)3_&A47_QT9&_\5$Q7_%Q47_Q at 6&/\:&!K_$Q$3_Q,1
+M$_\;&1O_'!H<_QP:'/\G+";_.3X\_RHO+_\F+"C_-30M_R\J)/]+13W_6U-)
+M_W]S:O]-03C_13LQ_TU%._]P8U;_(1D5_R\K+?]/1#W_<F58_WUP8_]]<F?_
+MAGMP_W!H7O]E8E?_<G!H_S8R-/\<&1__&QD;_RTH(O\Z*![_8D(L_T at O'O^^
+MKZK_:6%?_S$M+_]C9VG_86QM_UE?8?]46ES_-ST__SM!0_\L,C3_3U-5_Q$3
+M%O\-#1#_(!XA_SPY-/^-B(C_(1LC_R,@)O\Q-CO_7F!E_Q83&?\9&R#_2DM,
+M_R =(_\<&"#_)B0G_R$?(O\<&AW_2$9)_TI(2_\4$1?_44Y4_Q\<(O\0#1/_
+M%A$5_Q at 3%_\4#Q/_&Q8:_QD6'/\5$AC_%A,9_QX;(?\:%QW_%!$7_QL8'O\;
+M&![_)2,E_R4C)?]'14?_=7-U_U]?8O].4%7_2DQ1_T-%2O]!0TC_/D!%_SP^
+M0_\[/4+_,3,V_S$S-O\T-CG_+S$T_QD7&O_X\//_1T)(_RLJ,/\?&AK_;V=E
+M_R0?(_\@(B7_(" =_R$>&?\5$Q;_&AD?_Q\7&O\N+"[_C8B(_YZ5CO_/RL7_
+MTLO+_]?.SO_<TL[_ULK%_Z"7E_\D'R'_'1D;_Q84%O\7%1?_&1<9_QH8&O\3
+M$1/_$A 2_QH8&O\<&AS_&A@:_R<L)O\W/#K_*B\O_R4K)_\O,2[_*"8C_SPY
+M-/]$/SG_1S\]_QL2$O\C'!S_'AD9_S,J)/]$/#C_4DU-_VA?6?]F6E'_<69;
+M_WIM8/^%=VC_>7%G_V9C6/]L:V#_-3,P_R >(?\B("+_*"0B_RT>&/]&*QK_
+M."$5_]3&P_^4C(K_'AH8_UU?7/]A;&?_6F!<_U]E8?]I;VO_76-?_SU#/_]*
+M3T__$1,6_P\/$O\6%!?_-S0O_TQ'1_\@&B+_&!4;_S0Y/O]<7F/_659<_S R
+M-_]045+_$@\5_R <)/\7%1C_%A07_QL9'/\6%!?_(!XA_Q42&/\D(2?_%!$7
+M_QX;(?\:%1G_&A49_Q81%?\4#Q/_%Q0:_Q83&?\8%1O_%1(8_Q83&?\4$1?_
+M%A,9_QD6'/\4$!C_(!PD_Q41&?\C'R?_-38W_U-54_]E9V7_2DQ*_TI,3_]$
+M1DG_04-&_SY 0_]"1$?_/T%$_SL]0/\^0$/_.3D\__OS]O\G(BC_(2 F_XZ)
+MB?]U;VW_*B4I_Q at 6&?^]M[7_O;6Q_QP7&_\8%QW_&147_Q43%?^2C8W_GI6.
+M_\K%P/_6S\__W=34_]S2SO_2QL'_H)>7_Q\:'/\7$Q7_%1,5_Q84%O\9%QG_
+M'!H<_Q,1$_\3$1/_&A@:_QL9&_\;&1O_)"DC_S4Z./\N,S/_)BPH_S0U+_\L
+M*23_2T9 _TE#._]C657_65%-_TI%0/\Y-C'_,"PN_R0B)?\8%AG_&!89_QL7
+M&?\?&QG_+"4?_X!V;/]G6US_8EQ:_VEF8?] /3S_'AH<_QD7&?\T,B__)QP;
+M_THS)_\Y)1W_RKV\_X-Y=?\@&1G_+"HL_S,Z.O](2TS_*2HK_V%B8_]]?G__
+M$1(3_[.UN/\;'2#_%A89_QP:'?\I)B'_O;BX_V!:8O\;&![_,C<\_S at Z/_\?
+M'"+_*"HO_T!!0O\7%!K_)R,K_Q,1%/\,"@W_,C S_Q84%_\2$!/_'QPB_Q at 5
+M&_\3$!;_$0X4_Q at 3%_\9%!C_%A$5_Q40%/\2#Q7_&A<=_Q,0%O\2#Q7_&18<
+M_Q$.%/\:%QW_$Q 6_Q82&O\7$QO_%1$9_Q82&O\?'2#_+"HM_RTK+O]24%/_
+M24I+_T5(2?]$1TC_0T9'_S]!1/\^0$/_04-&_T)$1_] 0D7___C[_R(?)?\5
+M%AW_'QP;_SPV-/\@&Q__(QTA_RX?'_\G%Q3_(AH>_Q,5&O\1%!7_0$%"_XB&
+M at _^;E8W_Q\*]_];/S__=U-3_V]'-_]'%P?^>EY?_'!<9_Q82%/\4$A3_$ X0
+M_Q43%?\=&QW_$Q$3_Q<5%_\9%QG_,"XP_QH8&O\E*B;_,C<U_S,X./\D*B;_
+M/#@P_R at D'/]O;&?_8EQ4_W]U<?]L8US_;6A<_W!J8/]U:F/_<F9=_W-F6_]J
+M7%/_4DY,_U).4/]=6%/_;61=_VI>8?]%.C__'QH:_RXJ+/\;%1G_%Q,5_R0C
+M(O\?&AS_-"4?_R<9%O]74E3_>W-Q_R4=(/\E)"K_)BHL_R @(_\H)BG_&18<
+M_VAG;?\@'R7_G)ZA_Q<9'/\:&AW_'1L>_R,>&?_$P<#_:&=M_R,@)O\7&A__
+M%QD>_Q(/%?\8%QW_*RPM_QT;'O\@'"3_$Q$4_Q84%_\U,S;_#0L._Q84%_\Q
+M+C3_.#0\_QH6'O\;%Q__%Q(6_QH5&?\6$17_%1 4_Q83&?\7%!K_%!$7_Q83
+M&?\1#A3_$0X4_Q83&?\5$AC_%A,9_QL9'/\9%QK_&1<9_Q$-%?\3#Q?_.#0\
+M_RLH+O\G*2S_<G9T_U)44O]*34[_1$A*_T1&2?]#14C_1D9)_T9(2___\O/_
+M*B4I_R B*?]"/D#_0SLY_S4O,_\7%!K_DXN._YJ2D/\J)2G_%QD>_QP:'/\I
+M)B7_CXZ'_Y65C/_$PKW_UL[,_]7*R?_:S\[_S<+!_Z&=F_\G)"/_%A(4_Q<2
+M%O\3$13_%Q47_Q84%O\5$Q7_%1,5_Q at 6&/\C(2/_&QD;_R0H)O\Y/CS_+S0R
+M_R0I)_\[.SC_&R,M_S9&8/]#3VK_-3I3_S Z3O\]3UW_+#Q,_R<L/O\K,D#_
+M.D1/_UYB:O]H9V;_;F=O_X!Y<_^$>F__<V1>_Y^7E?]/34__24=$_Q\;'?\<
+M&!K_(R4H_SY*4_\6+3+_3V)N_XZHM?\<)27_)2 @_SP_0/](34O_5E93_TU,
+M2_],34[_LK2W_Q@;(/^TK[/_'AP>_Q\B(_\>&AS_(1\<_[FUL_]84U?_%A4<
+M_Q(/%?\2$!/_$ X1_Q84%_\?'2#_%1,6_Q43%O\4$A7_$Q$4_Q$/$O\3$13_
+M$A 3_S<S._\R+C?_'1DB_QH6'_\2#Q7_%Q48_Q<5&/\7%1C_#PT0_R >(?\7
+M%1C_$ X1_QH8&_\4$A7_%!(5_Q02%?\3$AG_$Q(8_Q04%_\3%!7_%!4<_Q .
+M%_]13U+_'QP;_VYO</]F9&'_A8!Z_U134O],4%+_14E+_TA(2_]*2$O_1T5(
+M___P[/\[-#3_*2HK_TU'1?\U+2O_-C T_QH7'?]9453_8UM9_R<B)O\;'2+_
+M)B0F_S8S,O^/CH?_F)B/_\3"O?_9T<__U\S+_]K/SO_%NKG_JJ:D_T],2_\5
+M$1/_%A$5_Q,1%/\7%1?_%A06_Q43%?\5$Q7_%A06_QX<'O\:&!K_(B8D_S@]
+M._\P-3/_(R at F_S4Y-_\7'RG_"Q<R_PP3-_\($S+_*SQJ_QXY=O\I2WW_)U"!
+M_SYLGO\L6HS_,EN,_T5HD/].9HW_3%1>_Y>- at O]W:V+_.#(P_S] 0?](2$7_
+M:FYE_VIN9O]U at X;_.UUQ_WVOQ/^@Q^#_>**R_W6$A/^$>WO_0S]!_QLC(/\M
+M,R__0TA&_W5Z>O^XP,+_%1\C_[V[OO\<&AS_&AT>_QX:'/\5&!+_MZFF_YN 
+MAO\4#Q7_$1$4_Q02%?\4$A7_$ X1_Q02%?\3$13_$Q$4_Q$/$O\2$!/_%1,6
+M_Q,1%/\4$A7_'ALA_Q,/%_\1#17_$ P4_Q$/$O\:&!O_&1<:_Q at 6&?\2$!/_
+M'1L>_Q02%?\:&!O_$@\5_Q(/%?\5$AC_%1(8_Q,2&/\1$QC_$Q4:_Q<9'O\1
+M$AG_$Q(8_S(P,O\?'1K_H9R<_X^$@_]H7%?_9EU=_V!<7O]>6ES_2D9(_U%-
+M3_]24%/___3T_RPG*?\>("7_(1X=_RXF)/],1DK_(R F_R8>(?\J(B#_'1@<
+M_Q@:'_\<&AS_=G-R_X.">_^8F(__O+JU_]C0SO_>T]+_V<[-_\6ZN?^JIJ3_
+M1T1#_Q82%/\7$A;_%Q48_QH8&O\7%1?_&!88_Q<5%_\7%1?_&QD;_QT;'?\?
+M(R'_,38T_S,X-O\=(B#_.#8Q_R0B'_\?'"+_%A,?_Q01*/\P-U7_'S%5_R V
+M7/\O5'?_.VJ-_RU:@O\>16__+%5Y_RY(;_]\@XG_GI"!_VQ at 5_]%03__+C$R
+M_RHO*_]?8UK_ at 7]Z_UUF;?]9?)/_;YZV_Y_!V_^#I;G_H::K_S,L+/\T-3;_
+M55I8_WZ ??]L:VK_*2PM_Z"DIO]>8VC_PL##_Q,1$_\0$Q3_'AH<_R,A&O^X
+MKZG_BWQ\_Q<1%?\6%!?_%!(5_Q02%?\3$13_$Q$4_Q,1%/\2$!/_$A 3_Q,1
+M%/\2$!/_$Q$4_QH8&_])1TK_%1,6_Q .$?\2$!/_$A 3_R >(?\B("/_(R$D
+M_Q<5&/]$0D7_%!(5_Q .$?\4$!C_$@X6_QH6'O\G(RO_,2XT_S at S.?].2%#_
+M85ID_Q$.&_\4$1W_'!@@_T(]0?^MJ*K_LJJH_WMO:O]L967_BX*"_W!G9_]L
+M967_7%=7_T,^0O__^?K_)R8M_RHO._\U-#K_*"(@_U=15?\>&R'_EI&3_[2L
+MJO\^.3W_#A 5_QH8&O\>&QK_@'YW_Y63B_^\NK7_U]'/_]O0S__7S,O_PK>V
+M_ZVII_\D(2#_&A88_Q40%/\3$13_&1<9_Q<5%_\8%AC_%Q47_Q<5%_\;&1O_
+M'QT?_Q\C(?\O-S3_.#T[_QPA'_\T.#K_'R$F_QH='O\1%AS_%QHL_Q<B(_]#
+M6%+_>8^7_Y:QO/]\F*#_7GB#_T-79?](97'_,D=D_WE[>?^6A';_<&5:_TM'
+M1?]"14;_,38R_XZ/B/]Z=W;_'!DF_T%:<?^!L,+_F<79_XRWR?^JN;G_.#4T
+M_SD^/O]D:6?_S<G'_X^*BO\<&!K_CHZ1_V%C:/^FI*?_$Q,6_S S-/\E(B'_
+MDH:!_V1?6?\;'1K_&Q<9_QD4&/\=&Q[_%1,6_Q(0$_\2$!/_$A 3_Q$/$O\1
+M#Q+_$A 3_Q(0$_\-"P[_&QD<_U!/5?](1TW_%!(5_Q(0$_\/#1#_$ X1_QH8
+M&_\7%1C_$0\2_P@&"?\2$!/_&A49_T9"2O\_/4;_.CI%_Q$/&/\R*3#_0#4Z
+M_XE^@_]81U'_:5UL_V1::_]W;GO_;VAO_Z.>H/^=EY7_2D="_U535?_6RLO_
+M6U-1_TI#0_\:%17_'!8:___X\_]!/4;_4UAJ_Q02%?\D)"'_;V1I_Q<4&O\3
+M%!7_*!T<_Q80%/\7%AS_&A88_X^*BO]_>'+_G9>/_ZVKIO_2T,W_V-#,_]?+
+MQ_^MJ*/_JZFF_QD6%?\;%QG_&A49_Q,1%/\7%1C_$0\2_Q02%?\5$AC_%A07
+M_Q84%O\Y.#?_)",B_RDX-/\U.3?_&1T;_R\T,/\E(BC_'1\<_Q0:(O\7&SO_
+M'!XA_UM95O^+F)W_B:.F_X69G?]E;6__6&)?_U=O;/\E0G+_>'U[_XMU<_]O
+M95K_3TE'_R0E)O\C)2+_G92-_UUL<?\?+D7_$"M#_WVENO^;R^?_H<SD_[S 
+MPO]01T?_*2<I_V!D8O_.R,;_F924_QL9&_^[N[[_2DQ1_[BWOO\9&Q[_8&-D
+M_Q at 4$O\A'1O_)B$A_QD4%O\4#Q7_&!89_R(@(_\=&Q[_$A 3_Q$/$O\2$!/_
+M%A07_Q,1%/\1#Q'_$0\1_PT+#O\<&1__,SM+_Q(2'_\5#Q/_$A,4_Q 0$_\8
+M%AG_)"(E_Q<5&/\8%AC_%Q47_Q at 4%O\:%1?_'!<=_PT/%O\'#!+_" <._Q,.
+M$O\<&A?_'QL3_WYI9_]]8G+_2"Y)_U,]5_]"-C__C8*!_U914?\Y.S[_+2\T
+M_\["P_\N,S'_3$U._QT8'/\7%!K___3Q_SDT.O\7%R3_)B$E_RDK*/]]<G?_
+M&A<=_XJ+C/^RIZ;_<&IN_Q,2&/\:%AC_%Q(2_W=P:O^;E8W_N+:Q_[V]NO_!
+MOKG_J:&=_YR:E?^<FI?_)2(A_R <'O\<%QO_$Q$4_QH8&_\3$13_%Q48_Q<4
+M&O\7%1C_(!X at _QD8%_\?'AW_*CDU_S<[.?\8'!K_+C8R_R<B)O\G)A__)"DU
+M_QPF2_\4&R'_/SLY_X2)CO^7K*[_ at 9:8_WB&A?]E;6G_771O_R1!<?]Y?GS_
+ME7]]_W=M8O](0D#_*2HK_R,E(O^?D(O_&2,G_S9?<O];C:C_99.O_UV1LO]0
+M?9O_JK"Z_U]56/\L*BS_%!@6_]#*R/^@FYO_'AP>_["PL_]"1$G_LK"S_QH:
+M'?]S=7C_%1(8_QXB)/\E*2O_%!07_Q,.$O\6%!?_&A@;_Q<5&/\2$!/_%1,6
+M_Q,1%/\0#A'_$0\2_Q$/$?\1#Q'_#PT0_QL8'O\?)CS_%!8E_QT8&O\E("3_
+M$A 3_QD7&O\L*BW_'1L>_Q<5%_\5$Q7_34E+_RDD)O\:$A;_%A(4_Q(1$/\A
+M'R+_$18<_Q@>(/\L*2C_'Q,6_V1:;?\;$BK_C("5_X%V??]%/#S_(1X=_SQ 
+M/O\P,C#_S\3#_S U,_]'2$G_(!L?_QH8&___\_+_*" C_R0A)_\A'!S_/T$^
+M_W1I;O\0#1/_)28G_S4J*?\G(27_%!,9_QL7&?];5E;_9V!:_Z":DO^EHY[_
+M@(6!_YR=E_^2D(O_=GES_WAX=?\7%!/_&!06_Q<2%O\1#Q+_%A07_Q02%?\7
+M%1C_%1(8_Q84%_\C(2/_&QH9_QP;&O\G-C+_.#PZ_Q@<&O\O.SC_)2(A_S8P
+M)O\F+#S_'B=0_Q4;(_\B'AS_5%M;_U1G9_]TBHG_>XZ(_V!J8?]9<&O_+DM[
+M_W=\>O^9 at X'_=6M at _W9P;O\J*RS_,#(O_X^. at _]J8F#_#"<R_W&HP/^#L<W_
+M8I:W_WFBP/^SL[S_;F)C_R0B)/\N,C#_S\G'_Y^:FO\L*BS_IJ:I_RHL,?^Q
+MK:O_&Q at 7_V)C:O\G)#'_/#E%_R$B*?\4$QG_$1$4_Q,1%/\6%!?_$A 3_Q,1
+M%/\:&!O_%Q48_Q$/$O\1#Q+_$A 2_Q(0$O\0#A'_'!D?_QPC0?\*#1__$ L+
+M_R at C)?\8%1O_&1<:_R0B)?\@'B'_'1L=_R(@(O]J9FC_)B$C_Q,/'_\8&"/_
+M%1@=_QHE,/\>)CK_.3U%_R<B'?\U+R?_;&MJ_PP-#O^DHI__-3 K_R$<'/\6
+M&!;_/D,__TQ*1?_%N;7_1TQ*_RXO,/\9%!C_&!89__GM[O\G'R+_%A$5_QX;
+M&O\='1K_FHZ1_R at E*_\H*2K_,2DG_RHE)_\5$AC_(B B_WYY>?];5E#_HYJ3
+M_Y22C?]N=6[_D9:0_WI]=_]N=6[_<G-M_Q01$/\9%!C_&108_Q84%_\8%AG_
+M&!89_QD7&O\9%QK_%A07_R >(/\7%A7_&QH9_R<S,/\T.3?_%AH8_S@^0/\A
+M'QS_'A<1_T9.7O\D+5S_&ALF_R >&_\F-#/_AIN=_W.)B_]A=W7_6V1=_UYU
+M</\N3WK_>'Q^_YR'@O]G6DW_BH)^_Q\@(?\O,2__AXZ"_ZF5C?]06&+_9)2I
+M_WFHP/^;S>C_6WR3_[RWO?^"=G?_'R A_SL^/__/R<?_J*&A_S$O,?\O+S+_
+M*BDO_UQ85O\=&AG_0T)(_PD(%?\=%B+_(!HB_QD6'/\0$Q3_%148_Q02%?\1
+M#Q+_%A07_Q\=(/\6%!?_$0\2_Q$/$O\2$!/_$A 2_Q(0$_\5$AC_'2-#_Q$6
+M,/\1#Q+_%Q$5_RDE+O\G)"K_,"TS_RXL+_\Q+S'_)B0F_QX:'/]"/3__(B4^
+M_TI19_\4'BS_(S--_TI6=?\+#!W_(1D5_V%<2O]#/CG_&!,5_Z*=G_\J)"S_
+M&A4;_Q47%?])3$;_4$](_ZRBGO\9'1O_&!D:_R at F*?\P+C#___KY_RLC)_\2
+M$1?_'!T>_WEW=/^FEYC_%1,5_RDM+_^[M;/_G)>9_Q at 3&?\=&Q[_%Q(2_T5)
+M0?^HG9;_A8-^_V5O9O^%C8/_;'1J_V=O9?]I;67_%Q47_QH7'?\:&!O_&!88
+M_QL9&_\>'![_'!H<_Q at 6&/\:&!K_&A@:_Q at 6&/\7&!G_*"\O_S([._\4&1G_
+M-3 \_R(F'?\@%A__'2DP_R$V;/\6%"3_(A\>_R$M-/^*I*?_ at IVD_UUT>?]&
+M4D__46IO_RU5?/]T>8O_D8!R_W- at 5O^>DHW_(2(C_Q\;'?^2BH;_IYV2_YFJ
+MM_]VHKS_F,38_ZG-XO\J.TC_B(.#_YV8D_\>'B'_2TI0_\7 PO^NIJG_.C at Z
+M_S@[//]+3D__/D-#_QH='O^"?H#_&!D:_QD9'/\<'!__$Q,6_Q04%_\6%AG_
+M%A89_QH:'?\]/4#_'Q\B_QD9'/\?'R+_#@X1_Q0.%O\4#Q/_$0\2_Q(0&?\8
+M(CW_(BI6_Q8<-O\8&"'_5$QG_T ^1_\K)R__&QHA_X.!?O]23T[_&A88_R<B
+M)O\-$B3_'",Q_S(U0/]G;8/_=H&@_Q\D-O\=%A;_."TF_R,?'?\=%A;_K:>E
+M_RLH+O\?&R/_%!(4_V)C7?\;&QC_,S$L_QL8%_\5$Q;_*2TK_Q at 6&/__^/?_
+M0SL__Q\>)/\5%A?_)24B_[&EIO\;&1O_&1L>_QD3$?\6$1/_'!<=_QL9'/^2
+MC8W_14E!_Z*7D/]_?7C_7&5>_V9M9?]@9U__86A at _V1H8/\8%AC_&18<_Q84
+M%_\6%!;_&A@:_QT;'?\6%!;_%1,5_Q(0$O\9%QG_%Q47_Q<8&?\F+2W_-#T]
+M_Q09&?\S,#S_(2@>_QH0&?\)$AG_&REA_QL7)_\G(1__&!H=_S1+2O^%H:3_
+M9'A\_TU65O]2:6C_,UAW_W%R??^7@&W_A7=N_ZB at GO\A'R+_'QT?_XV*A?^H
+MH97_D:*O_R5/:?^SS^3_M<K<_Q,=)_^*A7__ at X![_QXB)/]96V#_O[N]_[VY
+MN_\L,3'_-$ __S0]/?],6%?_)"<H_Y2,C_\9$13_%A07_QH:'?\0$!/_&!@;
+M_Q45&/\>'B'_'AXA_T-#1O\J*BW_(" C_RHJ+?\2$A7_% X6_Q0/$_\.# __
+M$Q$:_Q4A//\:)53_'"=*_S(U3O]B5'K_@'Z'_PT0%?\5$A[_$ T,_U!-3/\9
+M%1?_(!L?_T-"2/]65%;_8UQ<_Z:BJO]N;W;_%A07_QD2$O\Q)2'_'QH:_QL4
+M%/^IHZ'_%!$7_Q,/%_\/#0__8F-=_YN;F/\]/3K_'1L=_QL9'/\M+BC_&A88
+M___X]_],1$C_)20J_QX?(/\O-##_O[:V_QD7&?\D)"?_LZNI_[JUM_\;%AS_
+M$0\2_QX9&?\?(QO_H9:/_X!^>?\T/#C_.3\[_RTS+_\U.S?_76!:_Q at 6&/\4
+M$1?_%!(5_Q,1$_\5$Q7_%1,5_Q43%?\3$1/_%!(4_QD7&?\9%QG_%A<8_R$H
+M*/\Q.CK_$A<7_RTM./\C*R'_(QDB_Q\E+?\?+67_-C5&_S<X,O\_03[_,S at R
+M_YFEI/^9I:G_;G5U_T]E8_\S67G_='R0_XB ?O^&@8'_K*:J_QL6'/\>'![_
+MC8Z(_YV8C/](66;_1VV(_Z_/Y?]TCJ/_1%1>_X2$@?^9FI3_)RTO_S U.O^P
+MKK#_P[_!_V1I:?]<:&?_='M[_X2)B?^1CY'_J*"C_Q at 3%?\5$Q;_&AH=_Q 0
+M$_\7%QK_#@X1_Q86&?\='2#_'AXA_Q\?(O\9&1S_&1D<_P\/$O\3#17_$PX2
+M_Q .$?\4$AO_%1XV_QDC4/\;)4K_%!DW_V5/?/]^>87_$!@:_QH:)_\=&1O_
+M55)1_R at D)O\P*R__)R,E_R(8&_\R)2K_>7!W_T$V-?]@5EG_$0X4_Q00$O\6
+M$A3_&1(2_Y6/C?\5$AC_%! 8_Q<5%_]=7EC_GIZ;_S$R,_\<'!__'1L=_TM*
+M0_^'A(/___7R_T Z/O\;'"/_&!D:_WAZ=_^\M;7_&A@:_Q43%O\F'Q__&A88
+M_Q83&?\='"+_BX:&_RHK)/^=E(W_ at X%\_R\W-/\H+2O_&1\;_RTS+_]365'_
+M&!88_Q01%_\4$A7_%1,5_Q02%/\3$1/_%!(4_Q43%?\4$A3_&1<9_QD7&?\7
+M&!G_(B<G_RPU-?\;("#_-3<__Q8>&O\=%1G_&1\G_R0V;O\9'R__)BHB_RTP
+M*O\V+2;_.S8V_VUP<?]&3T__,%%C_QM0AO\;.W/_.$]Z_UQH=_^ZLK;_(ATC
+M_R <'O^-CX;_HI^4_U-@:_]+;(/_1VN _R%"6/\A-D+_*2LI_Y^AGO_#QL?_
+MA(F._\/$Q?^_O+O_6EU>_[[#P_\^04+_S<G+_V%97/^7CY+_&1<9_R4E*/\9
+M&1S_$Q,6_Q<7&O\0$!/_'AXA_R,C)O\H*"O_&1D<_QL;'O\5%1C_$! 3_Q,.
+M%/\3#A+_$A 3_QL:(?\5'##_&B%+_Q8=0?\;'#O_9D]Y_W-P??\J-3;_'R K
+M_WUZ>?]'1$/_&!06_RTH+/]'0DC_13M$_T,T/_^$?(;_85-4_Z&9G?\4$AO_
+M$Q48_Q,1$_\<%Q?_EY&/_PT+#O\5$AC_&!<6_V5F8/]K:6;_-38W_QH<(?\4
+M$A3_5%)*_[VZN?__]O#_54]3_S4Z1O\H)2O_)" >_[&NK?\9%1?_&A49_V%6
+M5?]C657_&Q<5_QT<&_\J'!W_*"DB_Y64B?^'B(+_)2PL_Q\F)O\>)B/_*C(N
+M_TI63?\8&1K_%A$7_Q,1%/\6%!?_%A07_Q84%_\3$13_%!(4_Q02%/\6%!;_
+M&1<9_Q<5%_\?(B/_)S,R_PL2$O\M-3+_#Q$@_QL8$_\7(2S_&3!E_QXA,_\A
+M'QC_+"HE_SPZ*_\G(AW_2D<\_X*(A/\C0F3_+%>%_QQ B_\M3I;_26=]_\"N
+MLO\:'R3_(QD<_Y"0@?^>G)7_C(Z3_YFDJ_^7H[+_1UAE_SI&2O^.AH+_J*6D
+M_]W5V/^3F)C_J:JK_\&_O/^ZN;C_V-/7_[JVM/_)PL+_<VYN_X6"@?\O+BW_
+M&!H=_QH<'_\2$A7_&!89_PT.#_]86US_4515_R(E)O\@'B'_)"(E_QT;'O\3
+M$13_%A 4_Q0/$_\1#Q+_%!07_QTF/O\<(U'_%!U"_QP@//\N'CK_869R_UE>
+M7O]K;6K_E9.._U%-2_\7$A;_+"@P_QX=(_\R*S+_.C$X_WYY?_]42TO_J:"@
+M_QP7&?\8%AG_$Q(8_QD4%O^EGYW_&!,7_Q43%O\:&1C_ at 8%X_YF6D?\\.#;_
+M)B(D_QD8%_]334/_P+V\___T\/]]=G;_&1HA_Q .$?^(A(+_JJ>F_QX:'/\=
+M&!S_=&EH_VYF9/\:%17_'1L=_R\G*O\7(!G_-CTS_SI"/O\F+2W_(R8G_QD=
+M&_\I+BK_1E!'_QL<'?\9%!K_%1,6_Q at 6&?\8%AG_&!89_Q02%?\6%!;_%1,5
+M_Q84%O\9%QG_%1,5_QXA(O\C+R[_$!<7_RLS,/\4%B7_&Q at 3_Q0>*?\9,6C_
+M+S-(_TA&0_\D)"'_+2LC_SHP,_\Y,RO_/STZ_R1 8O\L5X7_'D:1_RI+D_]$
+M7W?_MZ6I_Q,:&O\B%QS_C9!^_Z. at E/]X<&[_P;6X_]++U?\<'B;_.#L\_[6H
+MH_^II*3_V<_2_WV"@O^;GI__RL7 _[JTLO_<TM7_R+ZZ_\[&Q/]^>7G_B8:%
+M_Q\>'?\7&1S_%1<:_Q$1%/\7%1C_%!46_PX/$/\_0$'_'A\@_R<E*/\E(R;_
+M(!XA_Q02%?\6$!3_% \3_P\-$/\/#Q+_'"4]_QLA4?\3'D#_%ALT_R\@.?]I
+M;GK_9&EI_VAJ9_^)AX+_4DY,_R0?(_\\.$#_1D5+_Q$*$?\Z,3C_C(>-_V-:
+M6O^BF9G_'QH<_Q84%_\3$AC_'!<9_ZJDHO\T+S/_&A@;_R<F)?]_?W;_?7IU
+M_S\V,/\K)B'_'QH4_U9,0?_+P<3___3Q_Z&6E?\:%Q;_'AH<_S<T,_^VL[+_
+M%A(4_Q\:'O\>&1__%1(8_Q<9(/\4&B+_=W!W_QPD(/^*CXG_>7Y\_S5!0/\Y
+M0D+_.4- _SM&0?]"3D7_$A,4_QD4&O\5$Q;_%1,6_Q84%_\7%1C_%!(5_Q84
+M%O\7%1?_%A06_QD7&?\8%AC_'2 A_R(N+?\@)R?_+#0Q_Q,5)/\<&13_"Q4@
+M_QHR:_\9'S7_0#\^_T!"0/\K,"K_'QPB_S8T+?\W.3;_'S99_RE7A/\:1I#_
+M*TJ2_SE2;_^QGZ'_%AX:_R8;(/^*BW[_I9^7_VA:6__JV=G_Z-C<_SDT-O]Y
+M>7;_U<G$_Z6>GO_8S,__C9*2_WR#@__(QK__O;BS_^#7U__*P;O_O[>U_XJ%
+MA?]Q;FW_+BTL_QH<'_\6&!O_%!07_Q at 6&?\/#0__$Q$3_Q,1$_\D(B3_'AP?
+M_QP:'?\9%QK_%!(5_Q4/$_\4#Q/_$ X1_Q,3%O\8'RO_'R5%_Q$7,?\:%RW_
+M6$EB_V1I=?]D:6G_5EA5_X6#?O]134O_&A49_U).5O]_?H3_?WA__X!W?O^V
+ML;?_A7Q\_Z:=G?\<%QG_'!H=_QP;(?\<%QG_K:>E_X:!A?\[.3S_+RXM_X:&
+M??^=FI7_244]_QH8$_\:&!7_-"TG_[ZXO/__^OK_O+&P_R<B(O\D("+_)!\?
+M_XV*B?\/"PW_%1 4_[*HI/^WJZ?_'Q<5_QP9&/\?%1C_("0B_Y:6D_]?8F/_
+M-$)!_SA&1?\Z247_/DU(_T-/1O\1%!7_&Q8<_Q,1%/\8%AG_&1<:_Q<5&/\4
+M$A7_&1<9_Q84%O\<&AS_%1,5_Q at 6&/\<(2'_)C(Q_R(I*?\E+"S_&1TL_Q\;
+M&?\.%2'_(3MT_QH?./\G)B7_*RTJ_S0[-/\U.#G_+S,K_S$V,/\<,5/_*U:$
+M_Q9$CO\N397_.%%T_ZN8F/\:(A__'A07_WQ[=/^BFI;_8%17_^77V/_KW-W_
+M+BHH_\#!N_^PJ:/_J*&A_]S-T?^&BXO_86IJ_]74S?^]NK7_W]G7_\O$OO^\
+MM[+_C8B*_V!=7/\S,C'_&AP?_Q88'?\4%!?_&!89_Q(0$_\2$!/_$Q$4_R8D
+M)O\>'B'_&AH=_Q04%_\1$13_% \3_Q0/$_\3$13_$A(5_Q<:&_\:'2[_#1$@
+M_Q at 1(O\E&BW_)RTU_S8[.?]45E/_55)-_U103O\9%!C_44Y4_RXK,?\B'2/_
+M+B4L_VYI;_]-1$3_KJ6E_Q at 3%?\5$Q;_#@T4_Q0/$_^LIZ?_?'AZ_S at V./\P
+M,"W_EI:-_Z&<EO],2D/_'AX;_R,A(_\H(R/_M[6X___Q[?^JGJ'_(1XD_QH:
+M'?^%@(#_MK&Q_Q(.$/\8%AG_'186_RLD)/\9%1?_%1<:_VAB9O\5'!S_FIV>
+M_SH]/O\N/S__,4)"_S1&1/\Z3$C_2E-,_Q05%O\6$QG_'!8:_QD7&O\>'!__
+M%1,6_Q,1%/\6%!?_%!(5_QP:'?\:&!O_%148_QH>(/\B+S#_&B(D_R(J+O\3
+M'2?_(AX at _QH=*?\A.G7_)"9!_RHE(/]144;_.SLN_UA93/\Q-"C_'B =_Q at O
+M3/\?2G3_"39]_RI+E/\B/V__Q*^K_Q08(/\F(1O_='1Q_ZBCG?])/SO_ZMO;
+M__+<W?\B(!W_GY>5_];'Q_^YN;;_V\_0_YB9FO]67%[_S\C(_[JRL/_:TM#_
+MPKJX_[NSK_^EFZ3_4DU-_R(@'?\>'23_%!8;_Q<5&/\<&!K_$ T3_Q,0%O\3
+M$13_*RDK_RLK+O\9&R#_%!8;_Q$3&/\D)2;_-38W_SX_0/]+3$W_*"8I_Q88
+M&_\L,3'_9FAF_U!44O\\/CO_5U)-_VQ at 6_]_<VS_<FIH_QX9'?]02D[_(1PB
+M_Q *$O\L)B[_;&9N_UQ34_^MI*3_&A47_Q<5&/\/#QK_$A$>_R(?*_\6#QG_
+M%10:_Q<8&?^BG9W_IIZ<_TI(0?]&1#W_3DE#_U),1/]_=W/___#L_[&EJ/\>
+M&R'_&QL>_R4@(/]U<'#_&147_Q$/$O^JHZ/_LJNK_Q<3%?\3%1C_'AH<_R$I
+M)O^QKJW_P;R\_W=\@?])457_0TM-_T)+2_]*3TG_%Q47_Q,0%O\2$!/_&A@;
+M_Q02%?\5$Q;_$Q$4_Q04%_\2$A7_&1D<_QH:'?\8&!O_&Q\A_R M+O\B*BS_
+M(RDK_QHE+/\C)2/_)28Q_R9">_\?)#[_)R,A_S4V,/]'13W_5E9+_TU/1O\A
+M(R'_%2Q)_R!+=?\)-GW_)D>0_QPY:?^QG)C_%1DA_R8A&_]34U#_G)>1_T V
+M,O_NW]__[]G:_S N*__9T<__W]#0_WMY=O_;S<[_GYV?_T5)2__3T,__K:NH
+M_]73T/^\NK?_HYZ9_ZF?J/\T+R__'!H7_S4X/?\>(R/_%AH8_S at Z-_\S+S'_
+M&A88_W!M;/]&1$'_*"<F_S0V-/^BI*+_(R4C_U]A7O]*3$G_04- _S]!/O]9
+M6UC_3DY+_V%<5_^9C8C_MZ6A_\BTL/_1N+/_T;6N_\VTI_]40SW_(QHA_U5/
+M5_]X<GK_>'%[_WYW@?^NI['_J)^?_Z^FIO\:%1?_%Q48_Q<9(/\4%2#_(R(S
+M_QH7+O\:%RW_$Q B_QD5)?\4#!K_$ P4_S0Q,/\_/C/_2T@\_S at V+___\^__
+MMZNN_Q42&/\7%QK_=7!P_STX./\6$A3_&!89_R8?'_\;%!3_&Q<9_Q47&O]*
+M24C_-#PX_\.[N?_JV]O_X-'2_^+0U/_9R,C_T\/ _Y^:E/\?&QW_%1(8_Q,3
+M%O\8%AG_$Q$4_QD7&O\5$Q;_$! 3_Q 2%?\9&Q[_%QD<_Q45&/\9'1__("TN
+M_R,K+?\H*RS_'2HO_R4K)_\L+C;_)$%W_R4K1?\C'R'_)"8D_S\]-O]144C_
+M75Y7_Q at 9&O\.)$3_&41N_P8S>O\H29+_'CMK_[NFHO\@)"S_)2 :_TM+2/^A
+MG);_.C L_^76UO_PVMO_-C0Q_]C0SO_>S\__FI:4_][/T/^EH:/_2DQ/_]#)
+MR?^LIJ3_U,[,_\"ZN/_$O+C_O;.\_S(M+?\R,"W_2$9(_YN;F/^8EI'_/3LT
+M_ZFEH_\S+RW_KZRG_T ^-_^<FI7_.3HT_W5V</\G*"+_14E!_S8Z,O]$2$#_
+M0D8^_T9,1/]44$C_RK>O_\JRJ?_)L:C_PZF at _[RAEO_5N*S_OZRB_T,W,_\>
+M&1W_1T)(_Q<3%?\?&QW_)2$C_T(^0/\_-S7_HYJ:_QL6&/\7%1C_%!$7_Q<3
+M'/\-#!G_%!(E_QT9,_\<&#+_&Q at O_Q42*/\?&C3_)B,P_S0R+?\T,BO_4%53
+M___V\O_!M+/_'QXD_Q(4%_\=&1?_)!\?_R$='_\5$Q;_-"DH_T,X-_\?&AS_
+M&AH=_T1&1/\P.#3_P[FU__'<VO_GV]?_X=71_]W0R__9S<;_GI>1_R,@'_\6
+M&!W_%QL=_Q\B(_\='2#_(" C_R(B)?\E*2O_)2LM_R8L+O\J,#+_+# R_S(X
+M.O\E,C/_)C$R_RHO+?\?*C'_)3 I_R4G+O\D/W7_*3%+_R0B)/\G*"G_1T=$
+M_U153_]254__)B at K_P\D0/\80V__!C)\_R9'C_\C/FW_N*>G_S O-?\K)B'_
+M,S$N_Z";E?\T+"C_Z]S=_^_9VO\L*2C_ULW-_]O,S/][<V__U\;&_["KJ_]*
+M2DW_V]/1_[JOKO_*O[[_Q;BW_\:\N/_)O\C_+"@J_\"\NO]Z='+_L:RG_STX
+M,O^*@7K_3DQ%_V5>6/^,AG[_1$$V_Z&@F?\N+RC_JJFB_RPK)/]>8%?_0$0[
+M_T-'/O]!13S_6%]3_Z6>DO_)KZ;_Q:J?_\JRJ?_*LJG_Q["D_\JSI_\[+RO_
+M/CH\_Q\=(/\M*BG_2$E#_TI+1?]24TW_4E--_TQ(1O]+1D;_&147_Q45&/\7
+M$A3_%@X8_Q80'O\7%1[_%A,J_Q41*_\7%2__&ALT_R$://\>&"S_'1P;_R4D
+M(_^(@X?___+R_\V\MO\@'R;_%ALA_T-!/O\E)"/_%A06_QH8&_^,?W[_FHR-
+M_R$7&O\@&R'_.C\__S4W-?^_NK7_\.'<_^W?W/_CU=+_VLK'_^'1SO^RJZ7_
+M/T$__R\Z._\N.CG_+3DX_RTY./\N.CG_+SLZ_RTX.?\N.3K_-#] _S(]/O\N
+M.SS_+SP]_R8S-/\@+2[_'2XD_R$E-/\;*BG_,#@Z_R4]=/\H,TS_'R A_RDF
+M)?\I*2;_2DU'_SH^-O\V-SC_%R$P_Q\[9_\0/(#_'D!__RH]9_^?FZ/_0S at W
+M_R<E*/\K)B#_GYV6_S,N*?_KW-W_[]C9_RLF*O_/Q\O_Y,[/_[ROJO_)O[O_
+MM[&O_TY+2O_;TLS_M*RH_\G P/_6Q\+_T,"]_\W%R?\H*"O_R<&__]/%PO_!
+MO;O_.3TU_Z&8D?\K,B;_M*RB_T,],_^.C8+_H)Z7_UU;5/^LIZ'_0CLU_U]?
+M5O])3$#_8&-7_U583/])3$#_P[>N_]2YLO^LEH[_OZ:?_^'(P__:P<#_T[V_
+M_QL4%/\?'!O_7UU:_R8D'_\[/SW_+"\P_SL^/_\W.CO_.3T[_UY at 7O]?8&'_
+M2TM._Q00&/\4#QO_#Q00_QD7*O\6$2W_%Q,M_Q44,?\3$C?_.35+_S,R.?]$
+M1D3_0T5#_]'(R/__\_?_SKRY_Q\<*?\<'RO_3$E(_QP;&O\9%QG_&1<:_QP6
+M'O\@&B+_'!<=_Q at 6&?]'3$S_/3\]_[^ZM?_LW=C_\-W7_]"]M__HU]'_X-'+
+M_ZNJH_\Y0$#_+SL__R at P,O\L-37_*34T_R at T,_\G,S+_)"\P_R,N+_\C+B__
+M(BTN_R8Q,O\K-C?_*C4V_R<R,_\L-BW_-459_Q >)_\?(23_+4A^_RHT3_\C
+M(R;_+"@J_R\M)O]85TS_8V)7_UQ85O\-%B?_#"91_Q$Z?/\>1(+_)SE?_[*M
+ML_\K)BC_'ATC_R0?&?^<G)/_,2\H_^[BW?_QV]S_.3<Z_\K$R/_?S,S_N:RG
+M_\&WL__ NKC_4D]._]K1R_^\M+#_NK.S_\S#O?_6R,7_SL;*_R4E*/_,Q,+_
+MVLS)_UM34?\Y.#'_P;VU_R(G&_^ ?7+_.3PP_[>\L/]=6%+_I9Z8_YB/B?]Y
+M;6C_1$0[_U)52?]*34'_14@\_V%A5O_&N*__[]/,_^#'P/_ERK__\-?0_]+#
+MP_\@%A__%1 6_Q at 4%O\E(B'_+RTJ_Q83$O\U,3/_0S]!_QH6&/\F(2'_6%-3
+M_W5P<O^+A8G_$AT8_Q at 4._\L'UK_'!I!_Q at 9,O\3$"W_&18Z_R<E1O\R,$#_
+M)B4K_R<G*O\H*2K_V,K+__[O\/_&M+#_/CQ%_R0H,/\8%A/_&!<6_Q43%?\5
+M$Q;_HIV?_Z^GJO\9%!C_%A89_R4J*O\U-S7_M;"K_]S-R/_ at T='_CX:&_VIE
+M9?]=7%O_24]+_RLV-_\N.C__+C8Z_RHS,_\J-C7_)C(Q_R(N+?\F,3+_(BTN
+M_R(M+O\C+B__%AX at _QLC)?\=)2?_("@J_R\Q*/\D0%O_#!<O_R$='_\@.W'_
+M)"U+_QH9'_\C'B+_'QL9_SDW,/]*2$#_3$='_Q49+O\<+5'_'3=C_RE :O\?
+M*43_6E18_R at E*_\?("?_'AH<_R0B)/\H)B/_YMS8_^_<W/]#0T;_:V9J_]C)
+MR?^_LJW_MZVI_\2^O/]13DW_T\K$_[VSK_^HI:3_RL6__[&EH?_$O,#_+2TP
+M_[>OK?_>T,W_,R at G_Z&<EO]45$O_:FI?_\"VK/\V.R__G:*6_T$_./^[NK/_
+M03\X_ZZIH_]45$O_.SXR_U993?]254G_3DU"_]?'OO_TU<__ZL_(_]:_NO^I
+MEY/_2#\__Q,0%O\5$AC_&108_Q<3%?\P+2S_%A,2_QT9&_\G(R7_&!06_QP9
+M&/\M*"C_3DE+_YN5F?\/"S__IZ+,_[:SO_^NH]C_%!$\_R >/_\I)D/_8F-N
+M_SH[//\F)BG_)",J_RPL+__2RLC___+M_X1R:/\6%!?_%!8;_UY=5O])1T3_
+M'!@:_QP7&_\B%13_'1$,_QL6%O\4%!?_$Q at 8_RDM*_^KIJ;_W]#+_[*KJ_\P
+M-#;_*C(T_RLX.?\J-C/_+SP]_RHV._\K,S?_*3(R_RDU-/\D,"__)# O_RHR
+M-/\J,C3_("@J_Q at C)/\:(B3_("8H_R at N,/\F+"[_+"PC_QP[7?\'$R[_'148
+M_QTW</\G,U+_)R4H_QX9'_\D'R/_'QP;_R0C(O\H)BG_(QPC_QT;)/\C(RS_
+M(R ?_QP=*/\H(R?_)B4K_RPH,/\S+#/_+BDM_S<U./_5S,S_Z-;3_XZ/D/^9
+ME)C_U,7%_\>XL_^NI*#_QKZ\_UY96?_,PK[_D(J(_T=(2?_'Q<#_,BHH_\S$
+MR/\D)"?_N+"L_]C*Q__.P<#_A'UW_R(D&__*QK[_2#PU_ZRLH_^LK*/_,"\H
+M_ZNLI?\W.S/_D)*)_S\_-/]$13C_<7%D_V9G6O^1BX/_V,6__]["O_^ID8[_
+M)Q at 8_RD=(/\2#0__$0\,_RLK'/\R-1__,30=_R\S'?\N,"W_,C,T_S$R,_\Q
+M,C/_*BDH_Q43%?\8%AC_3DQ/_Q48._^AG+;_9F%<_Z>BNO\<&S__(R(__UM;
+M;O\S.#+_.3TU_R ?)?\K*#3_961J_\C"P/_TZO3_5T9&_R4A*?\;'27_'1P;
+M_QD7&O\;&![_&Q<@_QP8(?\;%Q__&18<_QD7&O\@'B'_&QH9_QH8%?\R*"O_
+MVL[*_TE24O\U/4'_-3T__S$\/?\O-SG_*C(T_R<O,?\?)RG_&R,E_QDA(_\9
+M(2/_("0F_QP>(?\7'1__&2$C_QHE)O\>*2K_(2PM_R$L+?\N-2G_-TEE_Q$9
+M*?\:&1C_(BQ._RLT1?\@(B#_'AHC_Q\A)O\B)2;_(R8G_R at M+?\P-3/_,C4V
+M_S0S.?\\.$'_/C8Y_UA33O^&?GK_M*BK_\&\OO^FFY3_1T1*_^3=W?_RV];_
+M>71T_]K2U?_9R,C_T+NY_X)Z=O_$N+G_)B$C_\+!P/]03E'_-#8[_[^]O_]?
+M75__O+&X_RLG*?^[LJS_WL[+_V%95_\V-2[_R<6]_V=F7_\_.C3_P[JT_SDW
+M,/^NHIW_;&9>_SHZ+_]T=&?_:6=8_X![:?]W;UO_='!A_RXI)/\@&QO_$PX2
+M_Q$0%O\3%!7_&!4;_Q at 2%O\7$@S_-S$A_SLW(?\T-"'_-C0L_Q<6%?\D(B3_
+M)"(D_R$?(?\7%1C_$A 3_Q,3%O\?(23_!@HP_S<N8_^TH]G_13AK_U%,9/\<
+M&27_/D%&_QL@'O\M,2__G9VF_WMYB?\J*S+_Q+^Z__#F[_]"+B;_-RLD_S0K
+M)?\\+2?_138P_S at K(/]$."G_3CTP_U5"-O]92#C_:UM(_W9<3O^#9TS_ at VY1
+M_X5\=?_AS\S_RL;(_S<Y/O\C*2O_(RLM_RPR-/\G+2__)2LM_R(H*O\:("+_
+M(RDK_P\5%_\C)2C_#Q$4_QLA(_\9(2/_&R,E_Q\G*?\B*BS_)2TO_RD]+O]H
+M;WO_)R,S_QTF+?\@*4'_)3-*_Q8A,O\].#[_0S\]_W!L:O^FGIS_R[Z]_]7*
+MR?_FU]'_[=?/_^[3TO_MV-;_Z=;,_]G)O_\G)"/_*"LP_Z"7D/]84U7_Y-O;
+M_^S4T?]Z=77_T<G,_]C'Q__9QL;_(R ?_[^ZO/].3E'_ at X%\_YJ6E/^;F9O_
+MR\?%_W9W<?_!N+C_*B8H_[JQJ__ at T,W_L*BF_\' N?]H9%S_/#<Q_ZJHH?]3
+M3DC_-C0M_\"[M?\R+B;_P;ZS_WIW:_][>6K_?WEI_WQV9O\\.C/_-#DU_P\5
+M$?\@)"+_&QP=_R(@(O\H)BC_)R8E_R at F(?\W-3#_'1H5_R0@'O]*1T;_$A 3
+M_Q(0$_\7%1C_$A 3_Q84%_\5$Q;_$1$4_Q@:'?\]0C[_(R<V_UQ><_^=D8S_
+M;&-=_TI%1?^1E)7_,SP\_T9+2?^1D9K_'APL_R at I,/^0CXC__^_B_[R2:O^Y
+MCV'_K8E<_ZZ#5?^WBU__M(E9_[2+5_^WBUG_O(Y;_[>*5/^WBU/_O8E7_ZF 
+M5O^1>5[_V,J[_^31R_\L+2[_$Q4:_Q(6&/\6&AS_$Q48_R at J+?\0$A7_)RDL
+M_QD;'O\F*"O_%!89_R4G*O\1$Q;_&R$C_QHB)/\?)2?_(2<I_R,I*_\I+S'_
+M+#LZ_R B*?\@+D?_.DEL_RDY9?]37X3_SLC6_]_-R?_IT,O_\-31__79UO_U
+MV=;_\M;9__36U/_KU,__X]O?_XV/GO_/Q\O_3CPX_S(Q-_\7(BG_GIB._W5K
+M9__EV=S_\-C5_WUX>/_*PL7_V<C(_][*QO^*A7__S\?#_W=U<O_*QK[_?G=Q
+M_XZ*B/_(O[C_;V]F_[^WL_\C(!__N[&M_][.R_]_=W7_3TY'_SHV+O_!NK3_
+M?7MT_S$P*?^SKJC_34Q%_WAV;O^!>6__=W)F_WYZ:_][=&;_;&9<_Q\='_]0
+M3$K_4TM'_R$;&?\@&QO_+BDM_SP\.?]04TW_-#<X_Q\C(?\;'2+_$@X6_QP8
+M&O\;&1S_&18<_QH7'?\6$QG_&!89_Q at 6&?\6%AG_&!H=_U!$6?]%/DC_8%Y9
+M_[FGL?\N(RC_GIN:_Y^@H?\C)B?_*"PJ_XF)DO\G)37_)R at O_S0X-O__\./_
+MS)UM_\J:9__+G&7_PY1:_\:46__"D%?_P8]8_\"35__ CUS_P8Q6_[Z04_^I
+M?4O_1B\8_V%C8?_,Q<7_W='-_QXG)_\0%1K_'1\D_QP@(O\8&AW_)RDL_Q08
+M&O\G*RW_&1T?_RDK+O\5%QK_*"HO_Q(4&?\=("7_'B(D_R,H*/\L,3'_,C at Z
+M_RLP-?\]0TO_H:*M_R@]6O]=9H__V<S?__#9VO_UU<O_\-G:__#:V/_QV=;_
+M[MS8_^_ at V__MX=C_X]C7_UUEA?\^49?_+4Q\_[W#T_]01$?_3DQ5_QTH+_^?
+MF8__?G5O_^79W/_LT]+_4D]._T(]/__8R<G_YM',_YJ/A/_+P;?_*B at A_[^Y
+MK_^.A7[_=W)L_\:^M/]>7E'_@'IR_R(@&_^QJJ3_X,[+_X1Y>/^HHYW_M;&I
+M_S(P*/\V-2[_O;RU_Z2?FO\C)!W_F96-_W%E7/]U;F+_:V9:_WET:/\@'1C_
+M'1\B_QD7%/\^/3;_,#,M_TU33_]G96?_8F)?_T9+1?\I+B[_(BDI_RHM,O\8
+M%Q[_&QD;_YJ2E?^@F)O_HYN>_ZZFJ?^SJJK_N[*R_[RUM?_$O[__Q,Z]_UM@
+M6O]866#_J[.O_RLM,/^6DIK_,2PP_S8R-/]W=7?_B8F4_R0B,O\='B7_+3,U
+M___T[O_4FV'_S)YQ_[Z%0__"DUW_OY!6_\256__ D5?_OY%7_[^,5__!D5+_
+MDFQ%_RT;#?]<4U/_8&!7_]+'P/_=SL__*S$S_RTR./\^0$7_)2DK_R8H*_\M
+M,S7_(BHL_R0L+O\6'![_+# R_Q06&?\I*S#_%!,9_S0S.?\A'R+_&!X at _R,K
+M+?\F+C+_*S V_S at T-O_4R<[_X,_7_^G7U/_MV='_\=K5__'9UO_SVMG_^-S9
+M__/7T__AR<;_^./?_Z.9E?\V,T#_)52._QXS@?\K4XK_P<+-_U=05_\G&"/_
+M='AZ_Y^7C?^'@GW_W=/6_][)SO\9'1__F9>9_\[ P?_8Q\?_9EE4_\_)P?\H
+M)R;_14(]_X)[=?\^/#7_6UI3_T$\-_\3$0S_# H'_ZJBH/_.P\+_Q+RX_U!.
+M1_] 1#O_6E1,_[:JI?]*0SW_+"TF_[>PI/^">&K_E8N _Y2)?O]A64__+RTJ
+M_S@[0/]A8V;_8F5?_U-43?\R,2K_3$I#_RXL*?\R-#+_(RHJ_QD='_\;'2#_
+M%QD<_Q\A)/\M+S+_EXV)_Z&4C_^CEI'_FXZ)_Y6,AO^1B(+_C(-]_XR#??^$
+M?7?_*B8H_V%A:O^VLKO_,BXV_XZ+D?\6%!?_$ X0_X5_ at _]Z=8'_*BDZ_RDI
+M,O],45;___'K_\6,4O_ DF7_SY94_\*37?_)F6+_R)AA_\657O_*EU;_R)EI
+M_V!%(/\F&A7_(AP at _R$?*/]/3TS_S\.\_^?6UO\O,S7_%QD at _QT<(O\C)RG_
+M&QT at _R,I*_\P.#K_*"\O_Q@='?\K+B__&!D:_SL\-O]&24/_*3 P_QDC)_\<
+M(R__(R8Q_S8S.?_1R,C_Z-;2_^W:U/_VW]K_^-_:__+<U/_SW-?_]]O8__;7
+MU__LU-'_QK&O_R49'/\O*3'_9FAO_Q 4*?\A5Y'_)#N(_R-,B/^]O<S_7UA?
+M_VA79_\?(B?_HIJ0_Y"+AO_=T];_V<G-_SI!0?_%PL'_WLO+_\F]OO\Z-S;_
+M'!T>_QX;(?\G(B;_)" B_QP:'/\9&AO_(!TC_Q at 8&_\7%1C_<6=J_XN#AO^>
+MF9G_='!N_ZNHH__.O+C_+B@@_R\R)?_'O:[_GX]\_YN.??^1B('_75Q;_TY1
+M5O\Y04O_-3]*_SD^1/\I,2[_+S<S_SY#/_\\/CO_(R(A_RXS,_\G+S'_*2XS
+M_QTA(_\A)RG_'R<I_RLX.?]B9&?_<G!S_VUK;O]H9FG_8&1F_UA>8/]46ES_
+M4%98_U%24_]/3E7_9F9U_Z^IM_]X='W_B(6+_X:$A_^IIZG_BH2(_W]ZAO\E
+M)#7_.#A!_VQN<?__].[_UYYD_\Z@<__6G5O_S9UJ_\J99/_,FV;_S9QG_[:/
+M7O]@/S__'1 C_Q\A'_]64$C_:F1H_S] .?_3Q\#_Y]/5_S at Z/?\='"/_&18<
+M_RTQ,_\V.#O_)RTO_RDQ,_\M,C+_%!@6_S4W-?]%1$/_+B\P_Q04%_\;'2#_
+M*BPO_U-.5/_/Q,G_Z]C8__3=V/_WW-7_]]W2__;<T__YW=K_\-?2_^_8T__J
+MU='_II21_WEQ=/\S+C3_+2\W_VYT?O]M;W+_'B O_QA,A?\A/(G_)$R*_[Z_
+MRO]\=W?_(Q,A_Q 3&/^:DHC_AX)]_]#&R?_?R<O_FYV;_\G%P__4Q,'_V<K%
+M_SLS-O\5%Q[_&!@;_R4C)O\>'B'_(2,F_RDM+_\H*C'_3E%6_Q46%_^1B8?_
+MT\# _]"]O?^DF)3_3$,]_T-$/?]35T[_BH1\_YR+A?]I8V'_6EI=_SQ$3O\W
+M1%7_-T=;_S%"6?\Z25S_,SQ#_RHP,O\A)RG_-CH\_Q88&_\G)RK_,C at Z_S,_
+M0_\K,CC_+CH^_RPW./\9(2/_*"PN_]K2U?_;TM+_X=C8_][5U?_HV=K_Y]77
+M_^C6V/_GU=?_]./C_]3)SO]X<W__L*VY_WIV?O^ ?8/_L[&T_ZVKK?^"?(#_
+MA'^+_R<F-_\E)2[_;&IL___RZ?_?J&[_Q)EM_]VF9O_'FVG_SIIH_\.06_^_
+MDFG_0!\W_S$B0?\-%!3_'1L=_YF)@/^- at 7S_3DM _];)Q/_QV]S_-#<X_R ?
+M)?\:%QW_+# R_Q,5&O\A)2?_'",C_S U,?]$24/_,C(O_QH8%?\H)R[_&Q<?
+M_VYE;/_=SM+_]-[<__G?W/_XW-C__^#<__C<V/_XWM7_]]_6__'8V?_QU]3_
+M;EI6_S$H(O\M)Q__+"@J_RTD'O\J(1K_-3 K_R at B&O\<'2C_'4R"_RA&D/\F
+M38C_O<+(_Y:4C?\D&2#_&!H?_X^)?_^'A'__R\+"_]W$Q?^\M;7_R,+ _]'$
+MO__9Q+__64Q+_R at L+O\B)R?_'R(C_Q<:&_\?)"3_+S8V_Q,8'?\3&1O_%1D7
+M_S<R+/_.P;S_P;FU_SD[,O][A'?_CXV(_RX@'?\<%!+_#1P<_R] 3O\U157_
+M-TMA_S)'8_\N0U__,49>_S%"6?\T/$;_%A@;_Q06'?\Z-SW_&18<_Q<9'O\O
+M-SO_'2DM_R$J,?\C,33_(S Q_S R-?\K)2G_Y]//__+;UO_OVM7_]^+=__?B
+MWO_ZY>'_]>#;__?BW?_]XMO_S[FZ_VAB:O^IJ[#_D8V5_WY[@?^XM;O_IZ6H
+M_VUG:_]Z=X/_(R0U_R at I,/\I)RG___7K_]FE;/_-IGS_VJ1A_\JA8/_%E5[_
+MO91C_Q\- /\@&#K_,"I&_RHI,/\\/#G_3TI%_SDT+O\]-3'_U,3!_^W9U?\V
+M.SG_(R at M_R0D)_\M,C+_%AH8_S$S,?\_/CW_+3(R_R(F*/\G*2S_'1@>_VQF
+M9/_$M[+_[M;3__'7U/_VW=C_\][9__'>V/_XW]K_[MO3__G<V/_BT]/_4DI.
+M_QT;)/\L-TC_'"(L_VMB6_\@+$G_*20D_R<I)O\S/5+_)R<T_Q at M1O\]:)S_
+M,UB9_RU+ at __$QM7_GIZ;_QT5&/\9%QK_ at H5Y_X>%@O_)O[O_ULC%_[ROM/]J
+M8&/_T<7!_\R]N/]M9V7_)B at K_R(G+?\V.3[_)BHL_TI.4/\[/T'_1TQ,_SL^
+M/_\@(2+_'QT?_];*S?_&O+__&A88_QX:'/\Q-CO_*B0H_Q8>(O\N/TW_,3]8
+M_SE#3?\]4&+_,$1 at _R8S1O\1%Q__.D=8_RXY1/\=&AG_*S \_RPL+_]A863_
+M+#0^_S=!1?\@+"O_+#4[_R0Q-O\K-SO_)BPN_RTK+?_GV-/_[]K5__+=V?_U
+MW]W_^.'B__;@WO_VX=W_^.'<___GX/_FU=7_<G%X_ZVOM/^9E)K_<6QR_["K
+ML?^HHZG_ at GU__UI<9/\?)C3_,#$X_XN,C?_]\.O_X:MQ_\ZC<__=HU[_VJ=K
+M_ZV%:_\H&Q;_&!,7_Q )%?\8$QG_-C,N_SDT+_\Q*2?_&Q<5_S K)O_+O;K_
+M[=O8_SD^/O\<(2?_(!\E_S$W+_]'2T+_,S0N_QP9&/\I)2?_)R @_XU_?/_8
+MP[[_[MC/__?=U/_[W]?_\]W4__C>U?_TWM7_\N+8__7BV/_AS\O_V,7+_SQ$
+M5/\M057_.T5:_R=!;/\7("[_GY.$_R Q5?];763_%QXD_QLS6O\C,$G_$BQ-
+M_R=6C?\L69G_,4V&_[Z^S?^NL*W_0#@[_QD4&/^!A'C_@'Y[_\:\N/_5QL'_
+MNJZQ_X%Y??_&O;W_R;V^_T1 0O\/%1?_&!HA_R,G*?\3%QG_%!@:_Q@<'O\1
+M%!7_'A\@_S$O,?\Y-3?_-C$W_S at Y0/\W.4#_'!LB_R8O+_\B(2?_'2HW_RT^
+M5O\Q/E'_)2HO_QXH-_]%3V3_EI6;_ZZII/]W?HK_,#I(_[*MK?\Y/TG_04)#
+M_]'-S_\P-#S_-3U!_QLD)/\L,SG_("TR_S$]0?\8'B#_%187_]_0R__RW=C_
+M]=O8__G<V__WV]W_]MW>__#9VO_OVMC_[]G7_YJ.D?^$AHW_J*NP_Z";G_]F
+M867_K*>K_Z:AI?]S;G#_$1(=_R F-O\N+C?_H9V?__SPZ__=IVW_RJ!R_\:7
+M7?^ND'K_.2(S_QX7-?\K)$+_*"$S_QP7'?\?&AK_(!D9_QH3&O\=&!S_*24C
+M_\["O?_SW-?_/STZ_SDW.?]A6EK_-C at U_QP<&?\G)2+_+RHJ_YB,A?^FEHW_
+MT[VT_^_3R__ES\;_\-C/_^W1R?_LULW_\M;3_^+)R/^RH)W_N*:C_T8Z-O_6
+MSMC_-$=9_S1.7/\[/DG_.%:"_Q\?(O^QFGW_)3MB_T-%3/\Z/S__'#%4_Q8@
+M-/\@,D[_%SAM_R=,C?\L0'K_N[G)_X**AO\D("+_&!,7_W=Z;O]V=''_M:NG
+M_]?'OO^^L;#_8%M?_U)-3_^PJJ[_B(J/_R$F*_\<'R3_&1T?_RTQ,_\R-CC_
+M)RLM_R4F)_\>'![_'QL=_YF4EO\X-SW_1DM1_R\T.O\7$QO_("0B_R$>)/\A
+M+CO_,$!0_SD[0_^IHJ+_H**Q_TU79O][>W[_YN#>_Y*9I_\V/TW_P[BW_S@]
+M0_\Y/CS_S,C&_S<Y0?\Z/T3_&B$A_S U._\3&B#_'B,H_RPJ+?\I(23_Y]//
+M_^W8T__KV=7_\N3A__KDW/_VW=;_\=S7_][,R/_IU]G_24-+_WR%C/^8FZ#_
+MI:.E_TI&2/^DH*+_HIZ at _WES=_\G)S3_(R at Z_RPL-_^MI:C___+I_]FC:O_ 
+MEVW_?5PX_QT;%O\1#AO_%!$>_QD1)?\T+D+_$ T9_Q84%_\8$QG_% T5_Q(/
+M%?\K*"?_Q;NW__#6S?^KHIO_:V5C_R,9%?\E("3_&10:_Q,.$/\<%Q?_$@T-
+M_R(='_\?&!__(QPD_RH?'O\T)"'_.",A_RX<&?\G&1K_(AT?_QTB(/]U>7?_
+M0T5#_];1T_]::WO_&B8J_Q89)/\F3H;_&A\K_W)B4O\=-%[_<W-\_U953O\B
+M,$?_7&)L_RDP1O\+'TS_(CQ[_R at Z=/^XM<?_76-?_S<X.?\4$A7_='9M_U)0
+M3?]G7UO_T<*\_[JOKO]*2$K_B(6$_XB#A_]*3%'_+#$V_RTP-?\E*2O_*2LN
+M_R$C)O\3%A?_&QT;_Q\='_\?&QW_BX2$_S,S-O\Q-#G_*R\Q_Q at 3%_\4$@__
+M(!L?_QPF,/\@+#/_O;>[_^C;VO]\?8[_/$Q6_W%X?O_?VM[_-SU-_S8]2__'
+MN[?_049,_SD_.__8TM#_,C,Z_S(U.O\K+S'_*RTT_RHJ,_\;'2+_O+2X_X1X
+M>__CSLG_D7UU_SXU+_]&1#__\N'4_Y^'>/^LFHS_ at W=N_]_0U/]!0$?_769M
+M_T!#2/^;F9O_&147_YJ6F/^GHZ7_<&MO_R(B,?\E*#K_+R\X_ZZFJO__[M;_
+MQYMS_SX>!/\<%17_&108_Q40%/\7$A;_%A$5_Q,1%/\6%!?_%1,6_Q43%O\4
+M$A3_%!,9_QD4&/^^LJ[_Z-7-_VI=6/\E'!S_2D \_TI%1?\9%1?_%A(4_QH6
+M&/]12T__-2\S_R8@)/\Y,S?_%A$5_Q<2%O\9%!C_&A49_QL9'/\5&1O_.D1!
+M_U%64/\R-T/_[-O._S5#6/\G(R'_$!8F_S1:C?\;&RK_4T X_QTI1O\9'"[_
+M&AH=_Q4=,?\;)3#_'2 Y_Q <.?\C-V3_(#UW_ZVQQO^2C8__+2\T_Q89&O]P
+M<F__-#4O_TA&/__+N[C_KZ6H_RDK*?] .S7_N[.O_XF$A/]]?G__*2TO_QL?
+M(?\>&R'_)R(D_TA#/?\9&A3_$1$4_RDG*O^&?GS_+RTP_Q,6&_\0$Q3_*BXL
+M_V=F9?\P,3+_'2 E_SD^1/\U,S;_+2PK_T!#5?\Q04K_ at I"/_]W9V_\P-$G_
+M-D!/_[^WL_\U.D#_/$$__\W)Q_\O,3C_-C<^_SX^1_\G*C7_)24R_QDB*/^'
+M at H3_M:ZU_][3R/^&<67_4U)'_RTL)?_?T,O_CGEM_ZF8B/]H9%S_TL+&_S]!
+M2/\V.D+_0T)(_YB6F/\B'B#_E9&3_Y>3E?]J:&O_)24P_R$C,O\T-#?_K:BN
+M___MX/\L'P[_'QPB_QT:(/\A'AW_'AD=_QD4&/\9%!C_%A07_R >(?\O+3#_
+M-S4X_SD[0/\_0$?_5E%7_\:YM/_NV]/_BGQY_T4V.O\I%QG_%@\/_Q,/$?\8
+M%!;_7%A:_VME:?]=5UO_2$)&_UM56?]54%3_%1 4_QX9'?\2#1'_C8>%_ZVE
+MH_^]N+/_N+"L_Z6DJ__"L:3_4F)\_R,@'_\3&2/_1EN+_QD;(_]>4TC_$Q at Q
+M_QH<*_\2$A7_%ATK_RHS.O\5%RS_#A4I_Q ;/?\C07G_HZF__XJ"AO\I(2O_
+M%1,6_V9E9/\B(A__,S0N_XZ%?_^BG)K_%Q47_RHG(O^(@'S_C(6%_Q\:'/\9
+M%QK_%A06_Q04%_\8%13_,28?_V5=6?]84U?_-#(U_XB ?O]544__@()__X:(
+MA?\W/#C_&!L at _V-C9O]N:6G_L*RN_[VZN?]W=V[_.SY#_SA#1/]\B(7_W-C:
+M_SD]4O\Q.TK_OK:R_S,X/O\^0T'_S\O)_S(T._]"0TK_-S= _RTP._\E*#/_
+M(RTQ_[RSL_^VJ[#_X-/&_XAN8/]223O_8EA-__'<U_^/>F[_G(]^_VEC6__4
+MQ,C_.#I!_S@\1/\^/4/_D(Z0_R <'O]>6ES_-# R_VUK;O\F)C'_(2,R_S,S
+M-O^OJK#_^-?H_Q@:&/\6$AO_& X7_Q02%/\5$!3_$PX2_Q at 3%_\Y-SK_/SU 
+M_TI(2_]%0T;_0$))_T-%3?]'0DC_T+^Y_^W7S_^$=7;_(!@<_QP7&?\7$Q7_
+M&!06_R\K+?],2$K_6U59_TQ&2O\4#A+_(QTA_S$L,/] .S__&A49_Q0/$_^Z
+MKZC_Q;&I_Z")A/^ ;&C_:V-F_[BFF/\S1F3_&!D:_Q(7'/\C)E#_%1@=_UQ8
+M2?\:&"O_'1TH_QH8&O\6&"#_(RPR_Q86)?\4%A[_&!PQ_R(Z:_^4EZC_I)N;
+M_T,^0O\<%AK_03Q _QH8&O\;'1K_2DA _Z&>F?\:%AC_+"LJ_T! /?\R+R[_
+M$P\1_QH5&?\>&QK_*"PJ_VEI9O]B4DG_MZJE_\*ZOO\E("3_9U]=_Y^7D__B
+MWMS_<7-Q_TM/4?\V.#W_7UI5_V)64?]/35#_6%)6_TU-0O]+2DG_&1P=_W5^
+M?O_=V=O_/$!5_RHT0_^_M[/_1$E/_S@].__/R\G_*2LR_ST^1?] 0$G_*RXY
+M_R8L-/\9)"7_P;:U_\*RMO_CU,[_=5U4_U!&._];44/_Z]3/_W]L8/^+ at G'_
+M9F!8_]3"QO]!0TK_.CY&_T5$2O]^?'[_(Q\A_Q\;'?\B'B#_:6=J_Q at 8(_\5
+M%R;_3$Q/_[*ML?_YV/?_%A$5_R$1%?\=#QC_%!(5_Q40%/\8$Q?_%Q(8_PX)
+M#?\U,#3_1D1'_U!-4_]&1U+_5EED_TQ'3?_&M:__Y]+._XQ_?O\;&1O_%1 at 9
+M_Q43%?\8%!;_&A88_Q82%/\1"P__#@@,_R :'O\;%1G_% \3_R ;'_\4#Q/_
+M'AD=_S\^,_^]M*;_P+*I_[RVKO_'O[O_JIN._TA;>?]34%;_&A\?_RLF2O\<
+M'B'_6%9'_QX8)O\?'2;_&1<:_Q04'?\E+#+_$Q8B_PP-%/\:&B?_#!I!_T9&
+M4?_ N;/_)B at F_QX9'?\6$17_%A89_Q(5%O\E)A__5E-._R,?(?\A(R'_)"DE
+M_S]$0O\?(R'_4U%3_VYL:?^*B8C_'1\=_XMX;O_(M+#_UL?+_R,=(?]:5%+_
+MP[V[_^+:W?^!?H3_*"HQ_R ;(?]Q96'_?G-L_SH\0?\7$AC_6%9._S0Q,/\Z
+M.#O_;7%S_]G6U?\Z/U'_,3M)_\*ZMO] 14O_.3X\_\C#P_\G*RW_/D!#_T9'
+M3O\H*S;_,C8^_Q<B(__#N;7_QK2V_]?.R/]20SW_0CXV_U!(/O_LU-'_<&%4
+M_W9R7?]A6U/_U</'_T5(3?\Y/47_-C,Y_V]M</\E(2/_'AH<_R <'O]U<W;_
+M@'^,_RPM/O\Q,SC_L*NO_^W;Z?\B&"+_#Q 7_Q 2%_\:%1?_&106_Q40$O\9
+M%!;_(!H8_S(N+/]*14G_.S<__TM(5/])25;_.34^_[FLJ_]K75[_2T,__V]J
+M9/]?6UG_%Q(6_T5 1/^CGJ+_&108_R4?(_])0T?_A'Z"_V]I;?]G867_9V%E
+M_X!Z?O\>&!S_+RHD_ZF?E?^/@7C_:V-9_W%@6O^2C8C_0%-E_R$9)_\9&1S_
+M(R$T_R A*/]F85O_%A(:_Q\?*O\6%B'_'AXI_R<J-O\M,#S_%!0A_Q03(/\7
+M&2[_'R$I_X>$@_\6&!W_&1@>_R<E*/\P+C'_'1L>_QX='/\M+"O_-#,R_T)!
+M0/\N+2S_*RTJ_WA]=_^@GI?_CHB&_^#5VO\;'!W_;5Q/_]W(P__MU=K_,2DM
+M_T$\//^UM[7_XMC;_X:$A_\R.C[_'1LD_VID:/]H96#_4590_VEG8O]$03S_
+M8U]=_R4B(?^)B8S_X]W;_SQ 3_\\1E3_M[*M_T%&3/\]0$'_H)ZA_S Z-_] 
+M1D+_24A._S8Y1/\I*C7_(BHL_\2YN/_$M;G_V<W(_TU$/?]!.S/_4D= _^33
+MT_]<4DC_9V13_U=*1?_5P,;_1$=,_X&$B?]V<7?_6%):_U505/\=&AG_'1@>
+M_V]J;O]Q;7W_*"E"_RPN-O]I;&W_XMCA_R at C)_\>(![_,S$L_S<S,?]!/3O_
+M3TI%_U502O]&03O_03XY_T9$0?\\.CS_*BDP_S(S/O\X-C__,BLK_]7(Q_^H
+MGYG_=G!H_VED7_\=&!K_(!L?_Q(-$?]P:V__'1<;_T$[/_\;%1G_65-7_Q80
+M%/\E'R/_:6-G_QT7&_\='AC_96-<_Y")@_^;FI/_C7MX_Z:<F/\_4%[_%1,C
+M_QD;'O\@'C'_&1DB_R4C(/\M*S3_+2TX_RLK-O\E)3#_("$L_R8G,O\4%!__
+M$Q <_Q at 7*/\<'2C_6UU at _R,B*/\D(A__-C,N_T9#/O]"/SK_/CPY_QX>&_\_
+M/SS_0T- _R0B)/\?(1__/T1 _V=D7__-R,/_ZMO at _R<G*O\]-2O_U\; __/;
+MX/\G'R/_-"\O_[BUM/_AU=C_EY>:_TM56?\6&!__)R at I_VUL9?]+3T?_8F-<
+M_RHK)?]?9&#_45E6_XJ.D/_AV]G_/T-2_SQ&5/^ZM;#_049,_T!#1/_+R<S_
+M.$%!_T%&1O]*25#_,30__R at J,O\D+"[_P[BW_[ZOL__/QL;_0S\]_SLY-O].
+M2$;_V-#3_T='1/]04TW_249%_]/"RO]15%G_MKF^_VED:O^DGJ;_)B$E_VIG
+M9O^AG*+_<6QP_W=S at _\L+4;_+C X_V%@7__GVMG_/C at V_S8U-/\Y-SG_/3]'
+M_QXA+/\;&B#_(Q\A_S(K*_\U,#+_.S<Y_SLZ.?\S,S;_+2TV_S<Y0?\J*"O_
+M:EU<_UI/2/]V;F3_AG]Y_QX9&_\8$Q?_'1@<_QT8'/\;%1G_7%9:_QX8'/\:
+M%!C_'A@<_R<A)?\F("3_(AP at _Q4.#O^>D9#_,R0D_R09&/\G&1K_3D=!_SA#
+M3O\:$R3_%!46_Q<4)_\I+#?_,3,V_R0D+_\='2C_(2$L_QP<)_\4%A[_$! 9
+M_Q,1&O\3#QC_%A, at _Q<:)?\H+3/_/#H]_S\].O\].S;_/3LV_S\]./\Q+S'_
+M'AP?_QH8&_\<&AW_'!H=_Q<7&O\8&QS_BX>%_]#(Q/_IU]O_*28L_S4S+O_4
+MQ\+_[]?<_RXF*O\Q+"S_MK&Q_^G9W?^8F)O_6&9I_YRDKO\3%AO_3DY+_WM]
+M>O]76%G_*RTP_RDS-_\X1TS_ at XB-_]O5T_] 1%/_.4-1_XN&@?\^0TG_1DE*
+M_\O)S/\Q.#[_0D5*_SX]1/\I+#?_-3<__R at P,O_!MK7_OJ^S_]/1SO]#0T#_
+M04=#_UI:5__,RL?_3U%._UA=6?];75K_T+_%_TI-4O^TM[S_:F5K_YR6GO\F
+M(27_IJ.B_YV8GO]J96G_=7&!_RDJ0_\R-#S_B82(_]C0WO\3%B?_.4=<_Q$>
+M._]!3&7_*"]%_QL=+/\<'"?_(1HB_RTF+?\P*S'_,S$T_S0O,_\_04;_-CA 
+M_SHX.__8R<G_S+VW_WEN8_]Y;6C_&A47_V!;7_]13%#_%Q(6_R(<(/\E'R/_
+M3DA,_UI46/^ >G[_,"HN_Q80%/\W,37_&1<9_QP8&O\B'1__'QT?_Q00$O\N
+M*2/_/45/_Q0*&?\3$13_$Q B_R$D+_\@(2C_'!PE_Q<7(/\<'"7_&AHC_R(B
+M*_\;&R3_%A0=_Q<3'/\5$A[_%!0A_Q49(?](24K_24M)_RHM+O\<'R#_&AT>
+M_Q@:'_\8%Q[_&A8>_QX?)O\F)2O_.#H]_QPA(?\Z.SS_O+FT_^?5V?\F("C_
+M+C(P_\*VL?_UW>#_*B(F_R\J*O^SK*S_V,O*_Z*=H?]7:V__FZ*N_Y>9H?\G
+M)BS_'ATC_R(F+O]E9FW_L;;"_T9=:?^"BY'_V]73_T-&4O\Z1%+_LZZI_T-%
+M3/\[/C__OKR__S$V//\[/47_0#Y'_R<K,_\N,#C_)2TO_X%Y=_^[K[+_W,K&
+M_][+Q?_>S<?_W<G!_^+)PO_0N[;_V,3 _]&ZM?_?R<O_4U9;_Z6HK?]74EC_
+MBH:._R4@)/^BGY[_FY::_V5 at 9/]P;G[_)RA!_S,U/?]N<WG_Y]3D_R,=*_\P
+M.DC_&R R_R$F./\8&RS_%14 at _QL6'/\9%1?_'!@:_R<C)?\U,3/_0SP\_S8Q
+M-_\Q,#?_+B at L_V5=6_]P:6/_3$D^_TY+1O\B'1__&1,7_Q<1%?\4#A+_&!(6
+M_R,=(?\9$Q?_%A 4_Q\4&?\7#Q/_%Q$5_QH5&?\6$1/_)!\A_R0?(?\D'R'_
+M$A 2_QP7$O\,$1W_#Q,B_Q(.%_\8$Q__%A$=_QP7(_\<&B/_%Q8=_Q85'/\9
+M&!__'1TF_QL;)O\;&R;_%14 at _Q(0&?\3$1K_%A4;_RPM+O\N,#/_&1L>_R,E
+M*/\F*"O_("@J_RHN,/\M+3#_*R\Q_RDJ*_\O+S+_'B(D_T-(3?]%2DC_T+_%
+M_R\F+?\H*2K_KJ*=__7=X/\I(27_+"<I_[RPL__2T<K_LZ*M_TIG<O]RAHK_
+M25QD_VYWA?]24E__5%QL_SY*4?]XDJ7_3FAV_WJ @O_;T\__:&=T_S [1O^@
+MGI;_0#]&_SM!0_^^NKS_+"\T_SD[0O]+25+_*RXY_R4H,_\C+S/_ at 7Q\_\>\
+MP?^GDXO_O:.6_["6B/_!J)?_R+&?_\VRH?_!I9?_R;*F_]O'P_]:7%__KK"X
+M_UA56_]U<7G_)R(F_YN9EO^/BXW_75A:_VMK>O\I+$7_-#0]_VA=8O_MV>/_
+M(A at A_QT<(_\='"/_*2,K_Q at 2&O\8$Q?_'QT?_R0@(O\>&AS_'!@:_QH6&/\>
+M%Q?_)2 F_ST\0_\F("3_HYF<_[2NK/^)AH'_+"DH_QX8'/\4#A+_KZFM_QL5
+M&?]P:F[_*"(F_UM56?\W,37_F8Z3_V1<8/^"?(#_$PX2_Q40$O\F(2/_)R(D
+M_Q\:'/\.#A'_%A(4_Q(>,_\H-5+_$A$>_Q(/&_\4$1W_%Q0 at _QL8)/\>&R?_
+M'QPH_QH7(_\@'B?_'QTF_QH8(?\2$!G_$1 7_Q(1&/\3$AC_%!,9_R$C)O\>
+M("/_.CP__SH\/_\4&AS_-SD\_U!+3_^4B8[_:V1K_X)]@_]"0$/_8V%C_Z6C
+MH/_IVMO_*R4I_RXN*__-P;S_\MK=_R8>(O\I)";_L*"H_\# O?^ZJ;G_,TQ=
+M_V9U>_]OA)#_;H:9_UEXBO]RD*;_;Y"<_V*-G_\H/$K_ at H2'_]C0S/].35K_
+M.41/_UQ>5?\Z.T+_,S<Y_W)S=/\P,SC_/#Y%_T$_2/\R-4#_*RPW_R0N,O^[
+MLK+_S<#%_\"LI/^WG9#_LYF+_\.JF?_$JI7_S:^:_\.DDO_)L)__X,G$_W1U
+M=O^IJK'_7UI>_V9B:O\E("3_E9.0_XR(BO]E8&+_=76$_RTP2?\P,#G_KZBH
+M_^G<Y_\;$1K_)A\F_R ;'_\B'2/_)!\E_R<D*O\M*C#_&!,7_QT9&_\7$Q7_
+M%1$3_Q<0$/\<%QW_/3Q#_R0>(O]",CK_,2 F_R$5%O\F&R#_'!,:_QT7&_]-
+M1TO_&A08_Q<1%?\<%AK_*B0H_QP6&O\>$QC_% P0_QP6&O\7$A;_%A$3_QT8
+M&O\G(B3_'QH<_QL9'/\>&AC_$AHJ_Q8=,?\7%R+_&QLF_QL;)O\;&R;_'!HC
+M_QT;)/\>'"7_*2<P_RXK,?\P+3/_%Q0:_Q,0%O\3$Q;_$A(5_Q44&_\4$AO_
+M(B0I_SY 0_\J+"__*BPO_RXN,?]45EG_0T5(_Q</$_\7$QO_-#,Z_S$L,/]+
+M1D;_J:*<_^O8V/\J)BC_+2HE_\F]MO_KT];_+24I_S(M+_^SI*G_?()Z_[NQ
+MN_] 5&+_DXB/_[Z]RO]"5VG_1W*$_T=]A_^TO\;_8%AL_RY#3_]N>7K_WM;2
+M_TE(5?\M.$/_+#0J_TU.5?\[/4#_+S(S_R<L,?\Y.T+_2DA1_S(U0/\K+#?_
+M&R,G_YR0D?_,O<+_PZ^G_[ZDE_^]HY7_OZ:5_\:NF__%JYC_Q*:6_\2MH/_?
+MQL'_<7!O_[.SMO]13$[_65-;_R8A)?^0CHO_B(2&_V9A8_]F9G7_*RY'_S(R
+M._^HH*/_Y=OL_S0L-O\M)R__'ALA_RHL,?\C)2S_(1\H_RXI-?\?&B#_'AH<
+M_Q at 3%?\:%AC_)B$C_R4C)O]!0$;_)R,E_Q at 3&?\7%1C_%A<8_Q06&_\0"P__
+M&A08_QD3%_\9$Q?_$@P0_QH4&/\3#1'_&Q49_QL3%_\1"0W_$0L/_Q$,$/\6
+M$1/_'!<9_R,>(/\C'B#_'1@:_R,<%O\<'B/_*",I_QX:(O\='2;_'1TF_QP=
+M*/\L*S+_,C$W_R ?)?\8%QW_&A<=_QH7'?\9%AS_%Q0:_Q<7&O\='"+_)B4L
+M_QT:)O\7%AS_7EYA_S P,_],3$__+BHL_QT@(?\Z0D3_&1L>_Q47'_\<'"7_
+M$Q87_V-?7?_$O;?_ZMK7_RHF*/\G(1__LJ:?_^/+SO\P*"S_,"PN_\.WL_]N
+M=W#_N[6Y_S]27/^0D9+_PL3)_S<]3?\Y057_>H&'_]3,RO]H:'?_/$95_SQ"
+M1/]T;&C_3$M8_RXY1/\1&Q+_(B0I_S at Z/?\5&AK_)BLP_SD\0?])2$__,C8^
+M_S0U0/\@)2K_JZ*B_\:WO/^LFY7_JI2+_ZB3A_^?BWW_EXA[_Y>%>_][:&#_
+MBGQS_^?2S?]C8V#_JZNN_TI%1?](14O_(!L?_X)_?O]I96?_9%]C_UU=;/\C
+M)SW_/#U$_Y60EO_DT>?_*28L_S V0/\V,S__(R,L_Q,4'_\3%!__.SQ'_RLD
+M+/\N+"[_/S0S_UI25O]965S_-#<X_RTR,O\F)23_(AT?_R4@(O\B'1__)2 B
+M_RPD)_\D'!__*2$D_RLC)O\I)";_(QX at _R@C)?\F(2/_)B$A_R$<'/\D'Q__
+M)!\?_QH5%?\B'1W_)R(B_R0?'_\B&A[_(QP<_R$?(O\8(3+_$!<I_QX>)_\L
+M*2__(" I_QX;)_\6$1W_%Q(>_Q<2'O\6%!W_&1<@_QT;)/\?'2;_&AHC_Q<7
+M(/\<'"7_,S,\_U=46O\J*"O_$ X1_QH8&_]@8%W_>'IW_SP_0/\5%QK_'B E
+M_T- 1O\9)B?_65M>_\6RLO_RU='_-R<O_R,C)O^)BX+_R[>Y_S4J+_\Q+S'_
+MSL*Y_V]UA?_,P<#_.TA9_Y".D?_*Q<7_-#Y-_R\[2O]Y?G[_V];1_VUO?O\R
+M0E7_+3LZ_U122_]245[_,CQ*_QD='_\5&1O_,C8X_SH^0/\Z/T7_/3]"_TQ.
+M4?\P-#S_)2LU_R$D*?]K:&?_N["U_]/(Q__-P[__U,K&_]S2SO_EV=7_Z-K7
+M_^77U/_JW-G_]N+>_UQ>7/]L;G'_)"$@_SLY._\?'2#_1D1'_QH8&_];6F'_
+M'A\P_R0G./\T.#K_ at H""_^'3[_\K+37_2%%?_RXP/_\:'2C_)BHY_QTA,/\0
+M%"/_5U!:_VEK;O^^L+'_Q+G _V5E;O].4%C_1DE._RHE)_\E'A[_(1H:_R,<
+M'/\C'!S_*"$A_R$:&O\I(B+_+B<G_S$J*O\F'Q__*B,C_RTF)O\J)27_)R(B
+M_RTH*/\K)B;_-"\O_RDD)/\E("#_(1P<_Q\A'_],/S[_/#4__T-GC/]4;(W_
+M#10H_Q<4(/\7%1[_&!4A_Q,0'/\8%2'_'1HF_QH7)/\?'"G_&18C_R =*O\T
+M,CO_*2 at O_TA'3O\?'B7_'AP?_Q,1%/\/#1#_"PD,_Q<2&/]".#O_'A00_Q@:
+M%_\6%Q#_-C4N_R$X,_]-7V/_/T%(_]?(P_\R)R[_'!\D_SA"./]E65K_-2\S
+M_S at T-O_*OK7_)2L[_\_$P_\V0U3_F9>:_\W(R/] 2EG_.454_VIS<_]S<&O_
+M?7^._S% 4_\T0#__1T4^_U958O\B+#K_/D)$_SD]/_\_0T7_/4%#_SQ!1_\W
+M.3S_/D!#_S T//\G+3?_(20I_R4G)?^BG*#_YM'/__OBW?_XW]K_^N'<__WF
+MX?_ZX][_^.'<__GBW?_TV-K_;6MM_R8F*?\X-3#_DY*1_R4C)?\B("+_(1\A
+M_U-26?\N+T#_)"<X_S8Z//]/34__XM'I_S0S.O]57&C_(!\L_QP;(O\B("G_
+M(1\H_R$?*/\R+C?_&QXC_]#!Q?_9R-+_7%ML_TQ/8/\_/TC_*R,F_RL@'_\L
+M)"+_*2$?_RLC(?\L)B3_+RDG_RDC(?\F(![_)!P:_RTE(_\N)B3_+24C_R\H
+M*/\T+R__(QX>_RTH*/\U,##_'AD9_RTH*/\D'Q__)"(D_XM^>?]%-SC_)C15
+M_Q(>._\8&2K_%A,?_Q85(O\>'2K_&AHE_QX>*?\8&"/_%!,:_S(Q./\?'B7_
+M(!\F_QX<'_\>'!__'!H=_R<E*/\I)RK_$Q$4_R$?(O\F)"?_'!LA_V)64O_#
+MLJS_8VEK_QXY.O\*)"?_'D=,_V2%D?]:?8K_HZZI_S8Q,_\M*"[_MKJR_\RZ
+MO/]'/$'_*2<I_\J^M?]$2EK_U<K)_SA%5O^+B8S_R,/#_T),6_\W0U+_*C8U
+M_TQ*1?^#A93_)"Y"_R8R,?]!/SC_3TY;_QLE,_\P-#;_*BXP_R\S-?\G*RW_
+M*2XT_R\Q-/\K+3#_+3$Y_RHP.O\A)"G_)"@F_S4U./_(NKO_QK2V_\&OL?^]
+MJZW_K9^@_Z&5EO^AE9;_F8V._Y-X?O]*14G_-C0V_U-.2/]N;FO_&AD8_R8E
+M)/]B86#_6%=>_R at I.O\D)SC_-#@Z_TA&2/_AS^/_,2PP_R(C*O\R+C;_)2 B
+M_Q0/$_\>&1W_,2PP_T,_1_\H*B__S+_$_]G(TO]85FG_1DE;_T-#3O\I(27_
+M*A\>_S0I*/\N(R+_*R ?_S H)/\L)R+_-"\J_R at C'O\R*B;_,B<F_R\D(_\N
+M(R+_*2(B_RHE)?\<%Q?_%Q(2_QT8&O\=&!K_'1 at 8_RLF)O\=%AW_A7IS_W9I
+M7/]'.$/_,BDZ_R4>*/\>&B/_&ADF_QD:)?\8&"'_*2DR_S$Q.O\K+"W_(R(A
+M_R$?(?\?'1__'QT at _QP:'?\7%1C_-30Z_Q<4&O\5%1C_'R A_R\I+?\C)"7_
+M4TI$_X5V</]M='K_5Y&G_TB(I_\P<(__.F:(_RHP1O]P6EO_-R(G_R0A)_^V
+MKZG_T+FZ_V%46?\O+2__S<&X_VIK=O_:T='_04M:_U!.4?_ OL#_1E!?_SY*
+M6?\7(R+_1D1!_X2"DO\D+3[_+#4U_R4B'?]+2E?_+#5#_SD\0?\Z/D#_14E+
+M_S,Y._\W/$'_,3,V_Q$3%O\Q-CS_)"<R_R,F*_\;("#_,#,T_[.NKO_5SL[_
+MV<_2_]?0T/_ at T-3_Y-+6_\&PMO^RHZ?_[]78_][3V/]K9FC_=&]I_RPN*_\G
+M)B7_ at 7]Z_VMI9/]&14O_*2LZ_QH=+O\Q-3?_149'_][1X_\H("K_(!L?_R$=
+M)?\B'2/_&Q8:_Q\:'O\H(R?_&Q@>_QD5%_^EGI[_VL_6_T-#3O\\/$O_0#I(
+M_S$J,?\G("#_(QP<_RLD)/\F'Q__+",C_S4L+/\X+R__,"<G_S(K*_\K)"3_
+M)R @_RLD)/\K(R?_%1 4_Q45&/\;%1G_'!4<_QP7&_\@&!O_*R(B_R,A(_]R
+M;6?_1STO_Z&3D/_2Q=#_8EMG_QD:)?\>(2S_,S(X_R4C)O\@'B'_'AP?_R,@
+M'_\A'AW_(1P at _R$<(O\F'R;_'AD=_QP;(O\O,SO_FI&8_YRAH?\V3T[_15]H
+M_SHW1/^3 at XO_N:JN_V%:8?_DW>?_?H&2_T%)7?\N*C+_FY::_\_ NO\W+#'_
+M*R at N_[:II/^]KJ__?7)Y_R at C(__%N;#_FY&-_\C'SO],3E7_%A06_W^!B/]#
+M35O_.D95_QTL*/],3E/_CXJ<_R at R1O\?(R7_2DM,_QX@*/\H*SS_.SU$_S0X
+M.O]"2$K_.T%#_RXQ-O\N,3;_*2PQ_RHM,O\F*S'_*"LP_S0V.?\D)2;_PKBM
+M_[>CF__ at R<3_BWEO_Z"-A?^[JZC_8UM9_U-+0?_FU-#_XLW+_Y:+BO\U.CK_
+M,S@]_R$>'?^0BH+_>WEQ_R8F*?\E*#3_*RX__U-26/^%A8+_V,O=_RXF,/\Q
+M+##_'QLC_QL7'_\B'R7_'1H at _S M,_\Q,3K_%Q0:_S<P,/_CU-G_.SA$_S\_
+M3O\^.$;_,RPS_R8?'_\G("#_+28F_R8?'_\V+C'_,BHM_S8N,?\B&AW_'A<7
+M_RHC(_\I(B+_*2(B_R4@)/\>&R'_'!D?_QT:(/\H(RG_*R8J_RLC)O\M)"3_
+M)",B_V=E8/]F85O_*!T<_[*GKO]S;77_)B<N_QT<(_\B'2'_(!L?_QX9'?\A
+M'"#_(QXD_R(=(_\?&B#_&A0<_R4?(_\A'"#_)B4L_RLO-_^BF9G_IZFL_WR9
+MI?]<AY__0#M5_VE3:/^OGJG_:%YA_]S/SO^-CI7_.TM5_S="0_^.CY#_U<; 
+M_SXS./\G)"K_F).._Y^4D_^6BHW_'AD;_\:ZL_\Z,"S_O[[%_T%#2O]>7%[_
+M-#8]_SQ'4O\\2U'_'RD?_T5(0O^5E)O_*2\Y_UQ?9/\;("7_+C9 _Q at B,/\]
+M1DS_-#H\_T!"1?\9%QK_%QD>_RTP-?\I+#'_+C$V_R$F+/\B)2K_+C S_SDZ
+M._^^M*G_K9F1_^++QO^,>G#_F(A^_\"TK?]_<VS_J)6)_^?7U/_.OL+_13H_
+M_R\R-_]!1D;_0T$\_XV-@/]E9U[_*BDH_RTM./]W=(;_1C]'_[NQM/_AU.;_
+M,BHT_R4@)/\6$AK_&1@?_Q\>)?\='"/_(!\F_QX>*_\G*"__95Y>_]_0T?\W
+M-3[_,# __T0^3/]".T+_+28F_R4>'O\E'A[_(AL;_S J+O\9%!C_%1 4_Q<2
+M%O\:$A7_(AL;_RLD)/\K)"3_-C$Q_R4=(/]^<G7_85E<_R0?(_\A'"#_*R,F
+M_R\F)O\G)B7_76%?_WR ?O^:DY/_+R4H_Q\;'?\9&AO_'QH<_R :'O\B'"#_
+M'QD=_R,=(?\8$Q?_'!<;_QT:&?]44D__CXJ,_T]*3O\?'B7_/4%)_U=<6/_ 
+MPL7_T]'A_[RWR?\C'"W_24-1_]7.V/_JW=S_ZM;8_Z><J?]*0E;_/",T_W=N
+M=?_#M*[_2T!%_R$>)/]L:VK_,"LF_YN.C?\I(R?_N*VF_R@>&O]I:&__1$9-
+M_QL?)_\W0$[_1D]@_S]"3O\0#1K_"0 2_R(7+O\.!QG_*20P_QL;)/\Q-$#_
+M*"\]_R0F+?\9&1S_24E,_Q04%_\;'2+_*2PQ_R\R-_\N,3;_)"DO_R,F*_\F
+M*"O_/3X__[ZTJ?^SGY?_YL_*_Y.!=_^.>W/_P;*M_VE?6_]>4DG_[M_:_^33
+MT__7R,G_14!$_SDZ._\C(1[_85]:_RLP+O\I+2O_1TE1_S0T1_\T+SO_TL;/
+M_]3$V/]%/D;_(R F_R$?*/\W-T+_.3I%_U-47_\F)B__*"@S_Q\?*/](0$/_
+MWL_/_T,_2/]#0U+_/#E&_T [0?\D'!__*2 @_S(I*?\S*BK_&1,7_QH5&_\>
+M&1__'1@<_QL3%O\@&1G_)1X>_R at A(?\P*"3_D8B"_]?(P_]J7EK_)R(D_R$;
+M'_\H("/_,2 at H_R0B'_]>8V/_8F9H_XJ%A?]02$;_(!T<_Q\='_\C'!S_)1TA
+M_R$;'_\F("3_*B(E_T])1_^1CHG_G)>1_[2PJ/\V,3'_,"LO_W]^A?\T.$#_
+M9&9D_[NVNO_<UM[_U-31_[W#O_^KL;/_U-'7_^S;V__RW-3_N;6W_S]05O\5
+M)"3_=WAY_[JMJ/]=4U;_'AP?_QT<&_^0BHC_13DU_R,>(O^EF93_ at GEY_R\Q
+M.?\R-#S_+35%_SI%5O\(#R/_)1TX_VIDGO]13I#_.#AQ_Q@;2O\:$BW_+RD_
+M_Q01)/\7%R+_&!,7_QL8'O\A(23_J*BK_RLN,_\L+C/_-CD^_RPN-?\C*"[_
+M'B$F_R4G*O\S,3/_P+:L_[*?E__>QL/_DX%W_X5T;O^MFY__;&IL_X)[=?_D
+MU];_X\[,_["?G_^[LK+_)R4H_R\J+O\T,3#_("8H_U]F9O\L-#[_,C=)_S P
+M.__3R]7_U<GB_T=+3?\G,SS_%!XM_S P/?\>'RK_&ALF_R0=)_\8$1C_&1,;
+M_RXG+__DU=G_1T!*_ST]3/\V-D/_3TI0_RH>)_\I'"'_+2,?_R\C)/\:%!C_
+M(AP at _R(='_\J(B7_)R @_RDB(O\K)"3_*2(B_S0J)O]E9F#_X-/2_X%O<?\E
+M'2#_)1T at _RPE)?\J)"+_*R<E_U]?8O]97F/_'!<9_\B\N/\E'A[_(R F_R(<
+M(/\5#@[_&108_VAC9_\H'AK_KZ":_\&_M__$N+/_P+*O_S4T,_\C'R'_&Q<?
+M_S<Z1?]-4$K_R</'_^37XO_FU]C_95]5_VA at 7/_CU-C_\M_?__/=V__%O,/_
+M/$%-_R4D*_\^-C3_65-1_VQG9_\A'1__<6=C_RL@'_\E'R/_'ATD_Y.'B/\Q
+M,#?_04Q=_SD]3/\\2$W_!@LG_V9CF/\Y-F;_&! L_QL,'O\>$!G_'Q8=_QL9
+M,_]75X#_4E)Y_P\/'O\E("#_+C0\_T-!0__;TM+_*BDP_RXM-/\V.$#_*RXY
+M_R8J,O\A)"G_*RDL_SHU-_^_L*K_UL.]_^W8UO^>BX/_A8!T_]C S_] 3E?_
+M+ATC_W9VA?_6Q\?_.# S_V]L<O\U-#O_-3 R_[NSK_^0EY#_041%_UI=:/\S
+M.$K_+RLT_Z2=J?_&P=G_,C4Z_QP@*/\3$A__&Q<9_Q,3%O\6%Q[_'!<C_QP7
+M'?\2#A;_*B0L_]#$Q_]33%;_0$!/_T%!3O]02U'_+"(E_RL?(O],04#_-RPK
+M_UA-3/^7CXW_-"TM_R0?(?\F'Q__*R0D_RLD)/\H(2'_,B at D_XF*A/_AU-/_
+MBWE[_R,;'O\E'2#_*R0D_RTG)?\M*2?_8&!C_U-87?\G(B3_FY&-_R0='?\:
+M%QW_(QXB_YB,A_^FFYK_5U!0_RP@'/^^LJ[_ at 8.!_Z^EJ/_:S]3_,C R_R4A
+M(_\?&R/_-CE$_SX_.?_)O[O_XM/4_^/6T?]13T?_/#@V_\S!QO_GV-S_]=_=
+M_\S#RO\X/4G_&QHA_S(J*/\W,2__0CT]_QD5%_\A&AK_)1X>_R <'O\@'2/_
+M>G)P_SP^1?]'5V?_.T53_SE"0O\;%C+_:5:$_Q4,'?\3%!O_$@X6_Q80&/\4
+M$1[_%Q8=_PH&%O\Q*T'_&14>_R4<'/\_0TO_24=)_];1T?\@'R7_+BTS_S$S
+M.O\N,CK_,#4[_R4H+?\P+C'_(1P>_XM[<O_!K:7_Z=30_YB%>_]Q;67_R[;,
+M_Q<I-_\F'BC_'R4U_\>_O?\M*"K_1#]%_RTI,?\X,3'_GY6+_X6$??^-BHG_
+M9F9O_RHM/O]%04G_Q+W'_]K#X/\E'"/_&!$8_R$0&O\A&B'_&QLD_R(H,/\M
+M,#O_)20J_RXM-/]545G_ULS/_T([1?\[.TK_4U- at _U-.5/\P*";_(148_RP@
+M(?].13__O[.L_]S/RO]&/CS_*"(F_R,;'O\I(B+_)1X>_RDB(O\S*27_B8J$
+M_][1T/^@CI#_*" C_R<?(O\H(2'_+"8D_S L*O]?7V+_76)G_R4@(O^PHIG_
+M95A3_Z:>G/^FG)C_P[>P_YZ6E/\H(R7_*B(E_U=(2/^4DH__WM+5_^+3V/\O
+M+BW_)" B_R(>)O\W.D7_/4!!_[RTLO_:R\O_XM[<_U5:5/\U,S7_8%E at _Z.8
+MG?_MU]C_SL7,_SQ!3?\<&R+_8EI8_U5/3?\:%17_(Q\A_R$?(?\<&AS_'QT?
+M_Q\='_]834S_2$E0_T939/]!2%;_)QTP_STK+?^KDH'_=EI7_UH]//^8=6[_
+MA6%7_X1B7_\K&!+_EH%__Z>1D_\4!@/_-RDF_T)$3/])2DO_U=+1_QP>(?\L
+M+2[_/T)'_S U._\L,3?_)"<L_QP:'?\<%QG_B'9L_\&KHO_JU,S_E8!T_W=O
+M9?_5O=+_&"HX_RPE+_\C,#W_I*">_RPH*O\\-SW_+R at R_T X-O^@E(7_ at GES
+M_XE]?O]?6V/_)BDU_SLZ0/^\M[W_S+S8_RDJ,?\4'R;_&QTD_R(B+?\E*C;_
+M/$1._Q,:(/\E)"K_*RHP_SDV//\?&!C_/3E"_SL[2O]*2EG_4U!6_RLC(?\X
+M+"W_*AXA_RLD'O^7BX+_V,S%_UE.3?\J)BC_(!L=_RHC(_\J(R/_*"$A_S F
+M(O^)BH3_WM'0_Z22E/\H("/_)Q\B_RHC(_\K)2/_+RDG_VUN;_]@96K_)B$C
+M_Z21A?_ K:7_Q[NT_\6YL/_(N[;_JJ.C_R at E*_\E(R;_1C at U_[>PJO_?T-#_
+MZMO<_S0Q,/\D("+_'AHB_S<Z1?]&3E+_9EYA_]/'RO][>7O_>GU^_W5[??]H
+M96O_KJ.H__/AWO_8S=3_24Y:_QD:(?\H(B#_)A\?_R8A(?\A'1__'!P?_R >
+M(?\A'R'_'AL:_T8W-_]!.T/_1T]?_U9;9_],3E7_#0,,_RL4'_\R(2?_%0H7
+M_R$4'_\G%Q__&0T6_R$:(O\8"QC_)A at G_R :(O^6BHO_1$)+_T=(2?_1T,__
+M+"XQ_TQ.3/\9'!W_("4J_SQ!1_\I+C/_2$-'_][6V?^)>&O_P:NB_^G3R_^8
+MA';_?W1I_]>[S_\<+CC_+"4L_R8Q//^1D(__*28E_S8P-/\I(RO_1S\[_YN+
+M>_^1AG__D8.$_TE$2O\B)3#_(R,F_ZZLKO_=SN;_)RLS_SM)6/\G*S/_-C8S
+M_T) /?\_.SG_&Q,1_RPM)_\M,R__66%=_]72T?\X.4#_+3 \_SHW1/]I9&C_
+M+"(E_RXD)_\F'Q__)B(@_ST\-?_7R\?_;%M;_R8?'_\A'AW_)R @_R\F)O\M
+M(2+_-2 at G_XZ.B__>T=#_LZ*B_RDD)/\D'Q__*",C_RHE)?\X,"[_96=E_V)I
+M:?\B'2'_F8R!_\.RLO^#?';_:6=B_^76VO^MH:+_*28E_R4@(/\X,RW_O;2N
+M_]3(Q/_DW-K_.#4T_R0@(O\@'"3_,C5 _SY%1?_"L[/_S+^^_^_DX_]Q:G;_
+M1U-<_UY=8_^YJZS_Z=K4_^70U?]%15+_&!HA_R0?(?\F(B3_(Q\A_R <'O\@
+M'![_(1T?_R(>(/\>&AS_-2<H_TM&3/]58&O_45ME_T=-7?\H*#?_8%UO_W)N
+ME/\C(CG_$! ?_PT-&O\*"1;_&QDZ_RPG4?\Y-%;_'R$H_Z>EHO]955[_0D5&
+M_];3TO\K+3#_.#HX_S4W-/\R-3K_,#$\_R at P-/_&NKO_Y]C=_Y5_=O_)L*O_
+MY<S+_YZ&=_][<6?_U\#3_R S/_\A&R/_+S4__V)F:/\E)R7_,2PN_R$@)_].
+M1D3_B'EL_XA]=O^1 at H/_2T1+_R,E+/\U-3C_H9R<_\3#T/\>'!G_(QL?_Q<;
+M&?\?)1?_/D,W_SE"-?\M.BW_(RX;_R)"+?]ICX#_QL7$_TE$2O] /D?_-2\W
+M_T Y.?\N(B/_)1L>_RLD)/\E(1__("0<_\C#OO^#<'#_,B0E_R0='?\G("#_
+M,RHJ_RTA(O\P(R+_AX>$_]K-S/^_KJ[_*20D_R0?'_\M*"C_,"LK_S8N+/]E
+M9V7_7V9F_R,>(O]V;&'_:EU<_XR*@_^,CXG_Y]C<_["DI?\O+"O_)B$A_RLJ
+M(_^MIJ#_R+JW_^O at W_\Q+BW_(Q\A_QL7'_\P,S[_/$-#_[^NKO^_L+#_\N7D
+M_VYH=O])5F'_5E=>_[*FJ?_AU<[_Y]+7_S\_3/\@(BG_)2 B_R,?(?\C'R'_
+M(!P>_R <'O\A'1__(AX at _QX:'/\K(R'_24M._T926_]:96S_1$]:_SE#3O\J
+M,3__,C%._S G8_\T*F__/S9\_UM1FO\8%4G_95^+_T$]7?\Y04O_E923_UA4
+M7?],3U#_V=;5_S R-_\P,3+_24M)_S R.?\Q,CW_)R\S_\.WN/_DU=K_?G%L
+M_\"KJ?_<R<G_AG)N_W=N9__4O=#_%"<S_R4?)_\W0$[_.3]'_R$C)O\P+#3_
+M(20O_TQ(2O]X:F'_=FMD_Y*!@?]&/43_(R0K_SX\/_^VJZK_O\3*_SY(-_\V
+M0C/_+T P_TQC4/\Y5$/_#"D7_SY?3?\S3CW_/%I*_YBMH?_9T<W_2T=/_S0U
+M0/\M*C;_0SY _R8='?\E&Q[_)R @_R<C(?].3TC_T<?#_YR)B?\F'1W_(AT=
+M_R<@(/\L(R/_+B(C_S(E)/][>WC_U\K)_\BWM_\H(R/_)2 @_R<B(O\I)"3_
+M+B8D_ST_/?]=9&3_'QH>_WMP9?]H65G_LJNE_YN9E/_DU=G_MZNL_S,P+_\G
+M(B+_(2(;_ZZIH_^MGYS_Y=C7_S,N+O\E(2/_)" H_SD\1_\Y/C[_P*VM_Z>6
+MEO_NW]__8UUK_SA)5O]#1T__JZ"E_^'4S__FT=;_/3U*_R B*?\H(R7_)B(D
+M_R4A(_\B'B#_(AX at _R(>(/\B'B#_(AX at _R,;%_]14$__/$5,_XB*D?^+B8O_
+M24]1_SM'3/] 2%+_>'I__T9'3O\H+CC_'"4S_TQ55?]Y>GO_Q\')_SD^2O^+
+MB8O_3TM4_T)%1O_)QL7_+S W_RDI+/^8F9K_/#Y&_S<X0_\O-SO_OK*S_^+3
+MV/]W<FS_R;ZW_]_2S?^9CXO_FI6/_]['VO\U2%3_)B H_SI"3/\N,SC_:&EJ
+M_T(]0?\U-#O_4DQ*_[6IHO]=6%C_D(2'_SHU._\A*"[_0T5(_ZFDI/_&R,__
+M+D4R_TQO5_]UCWK_*#\L_R L*_\Q.C/_-T0Y_R at T/?\_0E3_RL+%_^?8TO\[
+M.T3_/$!/_TM)6?]&0DK_+B0G_RTC)O\G'A[_,"HH_V-<5O_>T,W_J9B8_R8C
+M(O\A'AW_)R @_RXE)?\N(B/_,20C_T1%/__7R,C_S+N[_R at C(_\E("#_)!\?
+M_R8A(?\N)R?_*RDK_SH_/_\?&A[_;U]6_W]O;/^1B(+_I)^:_^C9VO^ZKJ__
+M+2HI_R,>'O\D)1[_KZFA_Y.'@__BU=3_/CDY_R,?(?\C(";_1$=2_T1(2O^\
+MK*G_DX*"_^?8V/^#?8O_-TA6_U]B;?^<E)C_VL[)_^;4UO\V-T+_+C W_R at D
+M)O\G(R7_(AX at _R,?(?\B'B#_(AX at _R$='_\C'R'_*!T<_T=#1?]14%;_P+G 
+M_^K9X_]=5F?_/4)4_T))6_]]=H#_M:FR_^?=[/]44F7_86%P_XR"B__ at T]C_
+M/#]$_XZ0CO]03E?_0D5&_\[+RO\H*3#_*RHP_XF(CO\S-#__+C X_RXV.O_$
+MN+G_YM;:_]'!N/_3N:S_U[>O_\RPK/^9C8;_V<37_R,Q0/\E(2G_)BLQ_WAX
+M=?^=F)+_D(N+_X![>_^(@7O_9V!:_UQ=9/^5D)3_*"HM_S=#1_\[1$3_9FMK
+M_][;S_\M*BG_,"XW_S@^.O]_?HO_9D.*_Z-[K_]%+$O_JHJ]_WM8F/_3PLS_
+M[-K0_TI&3_\^/DO_4U)?_ST\0_\K(R'_+R,D_S D)?\^-##_<F9?_]?(P_^L
+MG9W_*R,F_R ;'?\G'R+_,RHJ_R\D(_\Q)2#_B8> _]W+R/_2P<'_)B$A_R0?
+M'_\H(R/_*R8F_R at C)_\I)"C_)B$E_Q\:'O]S8V#_C(![_WIW<O^GH9__X=/0
+M_\J_OO\O+"O_)2 B_RPH)O_$MJ?_=6UI_^?>WO\Z-37_)R,E_R0B)?]256#_
+M1$=3_[JKI?]U9V3_Z=O<_Y6)DO] 2EC_7%]J_Z.;GO^?F)C_Z-O6_T-#3O\N
+M,3S_*B8H_R8B)/\C'R'_)" B_R(>(/\B'B#_(!P>_R(>(/\7$!C_*2XT_\K%
+MR_^\M+C_W-/3_U%59/\A*3/_0$=3_VQN=?^7CH[_W,W2_TY17?]L;G7_=VUP
+M_]W.T_]$1U+_AHN+_V%?:/\^04+_QL'!_R<F+?\K*C'_DY&:_S<X0_\W.C__
+M)BPV_[BKJO_-N;O_MZ*6_\2HFO^[GI+_P:67_YN*>O_4R-?_+BY!_R$C*_\Y
+M-3?_C7QV_]K#M_]!-3;_)R,E_V!>6?^$A7__B(B+_Y2/D_]P<7+_2E-3_U5:
+M6O^'B8S_Z+O?_XA.H/^F9-'_QYS2_UQ(4?\U&3/_1S [_S4N*/^)?7G_FHF4
+M_]3(Q/_MVM3_4T]7_S<W1/]44V#_6UIA_RHB(/\K'R#_+R,D_STS+_^#=W#_
+MU,7 _\2UM?\K(R;_(!L=_RDA)/\T*RO_,28E_SPP*_^*B('_W,K'_]3#P_\N
+M*2G_)B$A_R,>'O\J)27_)R(F_QH5&?\A'"#_'!<;_U1$0?^6BH7_8V!;_ZFC
+MH?_;S<K_U<K)_S$N+?\H(R7_+2DG_\6WJ/]>5E+_Y-O;_SPW-_\G(R7_'1L>
+M_T!#3O\[/DK_L*&;_U]13O_DUM?_K:&J_T)-6/]35U__7E=7_X%Z>O_DU]+_
+M3T]:_RTP._\D("+_)2$C_R,?(?\D("+_(AX at _R,?(?\F(B3_(1T?_RLC(?\S
+M,2S_74Y._ZB>FO_7S\W_3U-B_RLS/?] 1U/_7%YE_X^&AO_FU]S_24Q8_U)4
+M6_]C65S_VLO0_SH]2/]^@X/_85]H_TE,3?_>V=G_+RXU_R\N-?^4DIO_/#U(
+M_SU 1?\N-#[_MJFH_\"LKO^JD8K_HHA]_ZJ4C/^YGY3_CG]R_\K#S_\P,S[_
+M(R8G_XU_@/^3 at 7W_WLO%_TH\/?\<%A[_(1\B_UQ>6_]K;VW_='%P_W]^??]W
+M?'K_9VMI_UU at 8?_FQ=;_;DAI_]RUV/_[XMW_54A-_RDB+/\I)C+_-35 _WIS
+M9_^5C7W_R[^Z_^30S/]'1$K_,S- _S at W1/]655S_*2$?_S(F)_\S)RC_-"HF
+M_Y&%?O_9RL7_Q;:V_RLC)O\B'1__)1T at _RXE)?\K(!__-BHE_X* >?_2P+W_
+MTL'!_RDD)/\E("#_)B$A_R(='?\<%QO_%A$5_Q<2%O\;%AK_134R_Z>;EO].
+M2T;_IJ">_]W/S/_7S,O_,"TL_R8A(_\R+BS_Q+:G_U5-2?_BV=G_.C4U_R8B
+M)/\:&!O_(R8Q_T)%4?^FEY'_4D1!_^'3U/^WK+/_/$A1_U9;8?^9DY'_D(F)
+M_^G<U_]&1E'_.#M&_R<C)?\G(R7_)2$C_R8B)/\M*2O_KJJL_R,?(?\H)";_
+M;6!5_X-[:_^>AWO_<&-8_]K2T/]35V;_+34__T5,6/]:7&/_?71T_^G:W_]%
+M2%3_3U%8_V!66?_>S]3_1$=2_XZ3D_]T<GO_14A)_\G$Q/\T,SK_+"LR_YJ8
+MH?\S-#__.#M _R0J-/^KGIW_KIJ<_XY]=_]P9%W_0CLU_Y*$>_][:&#_R[_(
+M_T$_0?\X,R[_9EM:_SX\.?\J+"K_-C0V_R =(_\V-SC_='AV_VIM<O^9EI7_
+M:&9C_W!U<?]45E/_5%5/_^C;UO];44?_Y-?2_^+.U_]>4E/_-#$E_RPH)O]$
+M.T+_>FYE_XZ%=__)O+O_W<G%_T$_0?\Q,3[_1$11_TA'3O\P*BC_*AX?_S,G
+M*/\W+BC_F(V&_]C)Q/_3PL+_*B(E_R,>(/\F'B'_+20D_RXF)/\V+2?_;FEC
+M_]K(Q?_/OK[_*R8F_R4@(/\D'Q__*",C_Q0/$_\4$!+_%A$5_Q at 3%_\P)B+_
+MLJ6 at _T-!.O^ZL*S_T\?#_]S1T/\T+R__)R(D_S at T,O^_LZ3_23\[_^79VO]"
+M/3__)B(D_R ;'_\C)C'_0D-._ZB<E_\T*"3_WM'0_\:YOO\\2%'_5EUC_Y60
+MB_^;E)3_Z][9_U!06_\]0$O_)B$C_R<C)?\I)2?_5E)4_V=B9/]33U'_(QXB
+M_RLG*?\J)B3_1T=$_V=87/^$@8?_V-#3_UA@:O]-5EW_2$];_U5:8/]T:VO_
+MYMG>_T-&4O]46V'_1CY!_]O/TO] 1E#_<'-T_VEH;_]'2DO_GIJ<_S0V._\M
+M+#+_IJ*K_S8Y1/\O,C?_+C0^_Y^2D?^QGZ'_:U]:_UQ74?]H:6/_;FIB_WUK
+M9__#LKC_ULS(_]&_O/]V85__JJ&A_R0C*?\_-SO_)B0A_XN.B/]G;&K_455=
+M_W%P;_]^?'?_5UE6_U!12_]344G_X]/*_V=84__ATM+_Y=#+_VQ at 8?\Q*C'_
+M.3,[_SPX0?^+ at GO_?G5N_[ZRK?_ at S,3_349-_SL]3/])2UK_.C8__S H*_\L
+M)27_+RHE_R\J)/^/BX/_S<&Z_]+ O?\N)27_)!\?_RDB(O\J(R/_*"$A_R<D
+M'_]D6U7_PK.N_\S N_\M)2/_)A\?_R0='?\J(R/_(QDC_R,<'/\@&2'_*"$K
+M_Q\D(/^]IJ'_>WMP_\"KI__&P;S_V]/1_S0M+?\D'R'_/34S_ZJDE/]5247_
+MY]C9_TI$2/\I(R?_(AP at _R >)_\M+S3_B(6$_T Z,O_BU-'_R;C _TM48O]$
+M257_E8^-_Z.<G/_FU-#_7%5A_SH[1O\M)RO_,"HN_ZJEI_\[-C;_AWM\_YN2
+MF?\A'27_(AP at _R,=&_\K+2K_-RXN_R ;'__0Q<K_5V%E_TM77O])4%S_4UM?
+M_VUH:/_>T]C_0$-/_S]+5/\T,C3_S<;&_SQ!3?]*1T;_8&%B_T-(3?]02T__
+M+3$S_RTM,/^JI*S_045-_SM 1?\I,3O_6E)0_]#$Q?^*C8[_?W^"_Y^=IO]6
+M76/_+C<^_SL]0O\N)R?_,2 at H_[2GHO\J)2?_(" I_TQ'2?^'A'G_I:29_V=L
+M:/]L='C_8W9^_X:(C?^"@G__1T5"_UI54/_8R+[_<6)<_]W/S/_FTLK_=VII
+M_S4M,?\_.#__0SU%_V=@6O]N9V'_K**>_][+Q?]M9F[_0T15_U97:/]'0D[_
+M+24H_RTF)O\K)B'_-C$K_VQH8/_)O;;_U,*__RLB(O\D'Q__)A\?_RTF)O\J
+M(R/_+2<E_TI"/O\J(!S_R[^[_RLB(O\D'1W_(AL;_RLD)/\E%Q__(QL7_R(;
+M(O\N)BG_("$:_\ZRKO]S<F?_PZFF_[BSKO_=U=/_-B\O_R,>(/\_-S7_E8]_
+M_W!D8/_:R\S_95]C_RDC)_\C'2'_(!XG_ST_1/]%0D'_M:^G_]C*Q__1P,C_
+M04I8_U199?^0BHC_H)F9_^/1S?]W<'S_1D=2_R at C)?\J)2?_K*6E_Y2,BO^+
+M?GW_G)&6_R4@)O\J(B7_?W1S_UI<6O_$O;W_MK.R_[RNMO]-55__0DQ:_TE.
+M8/]'3E3_<6QL_^+7W/],3UO_.45._X2"A/_:T]/_.3Y*_ST^/_]765S_/3]&
+M_R at G+?\4&!K_)"0G_[NUO?]"1D[_049+_S$Y0_^1B8?_W]/4_U=I=_\W36/_
+M)SQ5_S!%7?](7'#_%R$O_QT?(O\F)23_4$5*_S G+O\?&A[_I9^7_["EGO^.
+MAX'_;6]M_VYV>O]6:(S_2%%B_U!:2_],3$G_4TY._]?(N_]Z;&/_V<W&_^72
+MR/^ <F__*B$A_T$Y/?])0DG_:F-=_V=B7?]/1T7_T\2__V%<8/\Y/$?_8V9R
+M_T- 1O\N)R?_*R0D_RXI)/\H(QW_<V]G_[VQJO_6Q,'_*R(B_R$<'/\C'!S_
+M*B,C_RLD)/\S*BK_(1P<_R0?'__,P,'_+20D_R4>'O\G("#_*"$A_R@='/\B
+M(1K_%A8C_RDE+?\<'1?_RJVI_W-P9?_,L*W_L*BD_]_7U?\V+R__)!\A_S H
+M)O]X<F+_A'AT_][/T/]L9FK_*"(F_R8@)/\=&R3_/D!%_SPY./^UKZ?_X=/0
+M_]7$S/],56/_1$E5_X1^?/^*@X/_UL3 _XJ#C_]'2%/_+"@J_R\H*/^OI*/_
+MJYV:_X=W=/^BEI?_+RDM_RLC(?^JDI7_44E,_\N_P/^_L+#_N*>M_UAA9_]+
+M5V#_/T94_T=/4_]234W_W-'6_U-68O]#3UC_A(*$_]3-S?\]0D[_'2,E_R\Q
+M-O]/3UC_)B<N_SI 0O\H*"O_OKC _TI.5O\R-SS_,3E#_WUU<__9S<[_-$-0
+M_R<[3_]!5&S_,3]6_V%B<_\C'";_+B4E_R at A(?]@6%S_,BHN_\K"OO^BEY#_
+MBHB#_T]34?\]0D+_<WM]_SI+6?]A8&;_65Q0_U!.1_]C6U'_TL:W_VE=5/_7
+MR,+_XL_%_X5W=/\L(R/_,RLN_T4_0_]H8U[_,2TK_R4>'O_6R<3_AH."_UI@
+M8O^/EYO_8F-D_RLF)O\N)R?_+24A_RLF(?]A757_HY>0_]3"O_\I("#_(AT=
+M_R0='?\K)"3_+R at H_RXE)?\B'AS_3TU(_\O O_\M)"3_(QP<_RLD)/\M)B;_
+M(14>_U588_\@)%'_-S!?_QX<'__'JZ?_<FI at _\>MJO^4CXK_W-'0_S at O+_\D
+M'R'_*B(@_UU62/]V:F7_V\S-_X5]@/\H(B;_(!H>_QD9(O\^/T;_.3 at W_[6O
+MI__3QL'_V,?-_T--6/]%2U7_?G9T_UE45/_(N;3_B8.+_T]27?\E(R7_+"<G
+M_ZF=F?^SI)__FHN&_ZN=GO\D'!__+28F_S$F*_]"24G_GJ*@_ZVKIO]B6EC_
+M3%A7_T515O]!2%3_3%18_T(_/O_EV=S_1DE5_T),5O]K:6O_RL/#_S@]2?\J
+M,3?_$1(9_TA(4?])2U+_04=)_RHJ+?^WL;G_/$!(_RPQ-O\P-C[_>W5S_]K.
+MS_\C)2K_'"$G_U-68O\I)##_(ATA_R(@'?\D(AW_(B<E_UI96/]M96/_W=',
+M_[*HI/],4U/_,CX]_XF0D/]>86;_<7AL_Y*(?O^2AH'_?G-L_ZZBD__,Q[O_
+M7%%*_Z:2CO_AR<#_F8B(_S$I+/\X-3O_1#U%_R8A(?\@'Q[_+BPN_[^VL/^(
+M at X/_/$)$_V9R=O]O<7C_+RHJ_S$F)?\K(!__)" >_UM94O]".3/_T,*__S H
+M)O\B&QO_)1X>_S I*?\H(2'_*B,C_R\I(?^0B7O_R;VX_RLD)/\B'1W_*",C
+M_RDD)/\K(BG_6&)?_R I6/\\/&?_'!X<_[VHH_]B4DG_MZJE_W1Q;/_=S,S_
+M/C4U_R,A(_\H("/_/C at V_SLT+O]G6US_E(N+_RLD)/\>&1__&AHC_SQ 2/\\
+M.CS_IYN6_\>YL/_;R<W_2%!:_TE07O]/1TO_(B$G_U!%/O^!>W__0D)/_QT;
+M'O\G'2#_IIB5_]'%OO^JFI?_MJ>G_S$H*/\G(R7_-CP^_TQ04O]85%;_IIZ<
+M_S4Z-O\B*RO_2%%8_T9/7?]045S_AXF,_^/4V/]24&#_-T%+_U]@8?^^N[K_
+M-CE%_R at K-_\_04G_1DA/_T5(3?](3E#_*2DL_ZVIL?])25+_,3@^_S$U-_]+
+M24;_R\+"_R4@(O\B&AW_N:VP_R at C)?\@'2/_'!LA_Q86&?\E*"G_LZRF_]C+
+MQO_BUM+_N[>U_T)'1_]P=G+_4EA4_SD^0__CU]/_[]S4_^S9T?_SX-C_^^??
+M_\2[M?]%.S?_>FQI_]2^M?^:BH?_+28F_S\]0/\V+S;_'!T>_SP[.O^4D([_
+ML:6 at _W!H;/\G)S3_0DA8_V9D=/\E'2#_+B,B_RTB(?\E(1__)2,>_R 8%/_/
+MPL'_+28F_Q\8&/\B&QO_*2(B_R\H*/\M)B;_,"HB_Y.,?O_,P+O_*R0D_R(=
+M'?\E("#_+2 at H_RLB(O]?9%[_7F5S_UI:9?\;&13_PJVH_T<Y,/^FG9?_85]:
+M_][-S?]$.SO_(B B_QX9'?\N*RK_,BXL_W=O<O^BF9G_+28F_R$<(O\>'B?_
+M04=1_T='2O^;D8W_M:FB_]K(RO]26F3_1$Q at _Q\>*_\6&R#_4TQ&_V5?9_\I
+M)##_*B(F_S at I+?^LEY7_V<C"_Y>%@O]Y:FK_*R(B_R<C)?\O,C?_3E%6_S<W
+M.O^&@8/_'!\@_P\5%_]+45G_0$=3_T=(4_^)BX[_V\S0_T5#4_\W04O_(B,D
+M_S at U-/\L+SO_/4!,_T)$3/],3E7_2TY3_T)(2O\E)2C_L:VU_T%!2O\O,SO_
+M-CD^_TE+2?^0BXW_(1T?_R\H*/\X+R__0CT]_TA&2/]J967_D8F'_ZF=F?_K
+MW-;_U<C#_UI03/]S;6O_:&=F_T]44O\^1D/_3E)0_\>RK?_XW=;_^=[7__[C
+MW/_]Y-W_P+*S_RLC)O\A&QG_K9J0_Z>8D_\P*BC_04 __S8Q,_]%2TW_1$A&
+M_Y&(@O^:C(G_CH.(_RPJ.O]$15S_<6U]_RLC)O\M(B'_,"4D_QX:&/\>'!?_
+M&A02_\B_O_\G(B3_(AT=_R$:&O\G("#_*R0D_RXG)_\M)Q__AX!R_\_#OO\H
+M(2'_(!L;_R8A(?\F(2'_)B0A_UQ at 7O]G;&K_9&-B_R(>'/^]J*/_-RTC_YV8
+MDO\].S;_WLW-_V%86/\C(2/_*",E_S8S+O^ >W7_3$1 _ZJBH/\J(R/_(!LA
+M_QD9(O\]1%#_/3Y%_X^'A?]934G_X,[2_T1,5O] 2%C_+BDO_TI&2/^!>'+_
+M(2$L_S4R/O\H(R7_,2<J_Z&1CO_ L:O_J):3_[6FIO\L(R/_)B(D_S<Y0/].
+M4%?_&!H?_TY.4?\>("7_0$-(_TQ06/\[04O_3E!8_VIL;__4Q<G_.SE)_RDS
+M/?]'2$G_;VQK_R4H-/\S-D+_/D!(_UQ>9?]+3E/_-#H\_QP<'_^>FJ+_1D9/
+M_RPO._\N,#?_,30U_TM*4/^KI*3_V\[-_^G8V/_KWMW_XM31_[^MJ?^5A'[_
+M=V1<_^?2S?_MV]?_T\O'_];+RO_3S\W_/T)#_V]Q;__JV];_^=[7___DW?__
+MY=[__^7>___GX/^BD9?_(QL?_QD4%/^,>V[_I)2+_R4@(/\^.SK_1#\__S=!
+M1?]$247_CH-\_X^!?O^IH*#_/SQ(_SY 5?]84F#_+B<G_RTA(O\M(B'_*B4@
+M_QP:%?]G8EW_R[_ _RHE)_\A'![_'Q at 8_R<@(/\R*RO_+"4E_RPH(/^!?'#_
+MQ[NV_RDB(O\A'!S_(QX>_RXI*?\H*"7_8&)E_V5K9_]D9&?_(AT=_\*NIO\_
+M-"W_ at X)[_QL<%O_:R\S_<F9G_RDE)_\P*"3_4DI _WIQ8_]:3TC_KZ2C_S$L
+M+/\<%QW_+"HS_SE#3?\I*C'_?W9V_R8@'O_6R<[_2DU8_T5(4_^'?'O_7EA6
+M_R@@'O],3UK_.CQ$_QX:'/\K)BC_G9*1_[*GH/^\JJ;_O:ZN_RPC(_\F(B3_
+M-38]_U988/\@(BG_'!XC_XR-E/]*3%/_0$%(_V9G<O]&253_;G!S_Z^CI/]%
+M0U/_*# Z_VAJ;?\Z.#O_)2 at T_R8I-?] 0DK_5EA?_T-%2O\W/3__+2TP_VEE
+M;?\_0$?_,#$\_S4W/O]&2DS_+S$V_WYR;O^@BXG_T;FV_W5B7/_8RM+_6$Y8
+M_R at A*_\@&R'_Z=32_^'/R_]%/CC_3D9"_TU-2O]]?'O_W,_.__C9T___Z>'_
+M_^;?___GX/__YM___>3=_YR$C?\J&B+_03LY_WUL7O][:V'_)!\C_T$Y-_]"
+M.CC_+S@^_S(U-O^+ at GO_>6QG_[ZTL/\V-3S_3U)D_TQ(6/\K(R;_*R$D_R\C
+M)/\L(1K_*B0<_WAP9O_2Q\#_,B at K_R :'O\A&1S_+R8F_RXC(O\N)27_)R,A
+M_VMJ7_^XKZG_*"$A_R$<'O\C'A[_+"@F_RPC(_]B8V3_8FMK_V%D9?\@'AO_
+MNJF;_R4=&_]W>'G_&!<6_\2]O?^4AH?_*" >_R8>&O];44?_95Q._V)>5O^Y
+MK*O_*RHI_R8?)O\9%1[_.$%(_R<F+?\P*B[_)B at F_WMS<?\_.T3_-3M+_U15
+M7/]/453_14M3_TQ27/\Z.4#_'A@<_RLC)O^QIZ/_J)V6_[BDG/^WIZ3_+2(G
+M_R4?(_\P+S7_3D]6_R0F+O]L;WK_75YI_U9?9?]545G_-S5%_T!*6?\W/#S_
+M+2LF_S] 2_\G+S__+S9$_S$V0O\<'BW_&ATH_T1&3O\\/D/_-34X_SP_1/\E
+M)"K_*B<M_S]!1O\T.$#_-C at __S@Z/_\F)BG_H):'_\6MJO_GT,/_HY-__]/'
+MR/\^-S__)1\G_RDB(O_KT];_U</%_T,_0?]H:FW_4UUA_[6QK__XX=S__.7@
+M___GWO__Y=S__^;=___DW?__Z.'_MYV at _S$?(?])/3G_=F%5_W]M8_\B'2'_
+M-BXL_S\W-?\D)BW_)"(D_WUY<?]M85S_K*"<_S(N-O]66VW_24E8_S$L+O\H
+M'B'_,"0E_S,H(?\N*"#_;65;_\F^M_\S*2S_(!H>_R$9'/\P)R?_+R0C_R\F
+M)O\A'1O_7UY3_XZ%?_\G("#_(QX at _Q\:&O\J)B3_+20D_UE:6_]:8V/_:6QM
+M_QX=(_^QI9[_'Q<:_S<W.O]#0#O_O;6S_Z.7F/\J(B7_*2,A_U5,1?].1SO_
+M;6MD_\:YN/\N+2S_(!D at _RDE+O]03%S_+BXW_Q4=&?]$/SG_;&!<_S at S.?])
+M4%[_14Y<_T%&3/]"2%+_/D51_T!$3/\=&QW_)1X>_["DG_^<C(/_M*"8_[.C
+MH/\I'B/_)!XB_S8U._]55U[_*S$Y_UYF</]?8&O_769L_UE57?\O+3W_.$),
+M_SD]._^HJ:/_)"LQ_QXH/?\F+4'_'2(N_QTB)_\P-CC_.3Q!_QD;'O\:&AW_
+M-SH__RHI+_\B'R7_.CQ!_RLO-_\R-#O_+S$V_S<W.O^<DX+_QJVH_^C0P?^D
+MDWS_S+^^_SLT._\A'RC_)B$G_^70S/_/P;[_6EQ?_SD]/_^ >7G_\>#:__OB
+MU?__Y-G__^7A___CW___Y=[__^7<__WDW?^FD8W_+B(>_S\X,O]D447_=F9<
+M_QH5&?] .#;_,"@F_RDE+?\E(R7_:&A?_UM23/^XJJ?_,"HR_TY18_]&2%?_
+M,"LM_RLA)/\T*"G_,"4>_R at B&O^-A7O_QKNT_RXD)_\?&1W_'Q<:_RPC(_\M
+M(B'_+",C_R8B(/\Z.2[_7U90_R8?'_\?&AS_*",C_R <&O\M)"3_4U15_UYG
+M9_]B96;_(!TC_ZJ9D_\X*RK_6E12_W%K8_^TJJ;_IYN<_R8@)/\F(R+_65),
+M_T,],_]V=&__R[Z]_RDH)_\A&B'_(!PE_SD^2O] 0D7_ at H!X_YB.BO\@'2/_
+M6EQD_TA/6_]-5V7_045-_T-&4O],5F3_355?_R A(O\O*2?_J9V6_Z*, at _^L
+MEH[_HY.0_RD>(_\D'B+_*BPQ_TE05O]+5%O_2U5?_U!17/]<96O_M[.[_T$_
+M3_\I+SG_EY.;_R(?)?\K-4#_)BX^_QH>+?\A(";_A8" _TY24/\U.CC_&1L>
+M_SDX/O]!1$G_'ATC_S4R./\A(RC_*"PT_R4G+O\\/D/_/CY!_YF/>__!II__
+MY,NZ_YF&;O_3P[K_EHB)_S,M,?\G(B3_Y]+&_\:]M_]/5UO_86=I_^',T?_V
+MWMO__N?;___HW__[WMW_PZ6G__S at W/__Y][__^;?_[.DGO\F'AK_.30N_U=*
+M/?]Q8UK_&!(6_S(I*?\F'1W_*"$I_QT9&_]+3$7_44A!_\BVL_\H'B?_861U
+M_T5(5/\X,S/_)QT at _S,G*O\S*"'_*R4=_VYE7O^_M*W_,BDI_R$<'O\?%QK_
+M*R(B_S$F)?\J(2'_)R$?_RHH(/\_.#+_(!@;_R ;'?\G(B+_)2$?_RHC(_]/
+M4%'_769F_V%D9?\C'B+_IY2*_VY=5_]<4$?_<&9;_ZJ>F?^SI:;_)R(F_R0@
+M(O])1#__,BTG_W-Q;O_+P+__+"DH_R,=(?\A'27_(R\V_SH\.O]J75C_(QX@
+M_T1)5?]#2E;_04E3_T--6/]/4EW_2U!<_TM59/],5V+_(20E_RTH(_^GEX[_
+MNJ69_Z6/A_]$-C/_)QT at _R8@)/\N+C'_/$-)_T=05_]C9V__HJ*K_U1=9/\N
+M*S'_-31!_S4Z1O\:&"C_.3='_RHR0O\<("C_(" C_XR(AO]G6U;_BHZ&_X:+
+MA_]\?'__-SD^_TY15O\;'2+_*B<M_S8X/?\?(RO_+3(X_S,U.O\_/T+_AWIG
+M_[ZCF/_6NZK_ at W!8_\6MI/^ADHW_,2HJ_RHC(__IS<__Q[K'_S0Y4O\_/U3_
+M4$1=_UE39_]@7&S_:V=W_WMF<O^.=GO__.+?___HW?__ZN'_HY*2_R@<'?\X
+M,"[_2#XT_V9:5?\;$A+_*R,F_R,=(?\K)2G_(AX at _SX[-O]#-S#_RK6S_RXF
+M*O]-3EG_9V1P_S$I)?\O(R3_*APD_RLB'/\E'AC_;&-<_[.HH?\V+2W_'QH<
+M_QP4%_\M)"3_+2(A_RTD)/\E'A[_(1X9_RLJ(_\6$A3_'AD=_RDA)/\F'1W_
+M*"0B_S]!/_]@:6G_8V=I_R >(?^@C8'_8%!&_SDM)O]?54O_D(1__[6HI_\F
+M'B'_)AP?_S4P,O\N+"[_85U?_\>^OO\N)27_(QX at _R$?(O\;'2+_-C<^_TU1
+M6?\^1$[_+C(Z_TE/6?]"257_14Y<_T!*5?]&4%O_/DA3_TE37O\A(RC_*2$=
+M_ZB8CO^XI9O_:EI7_X5X=_\B&QO_)"(D_R at C(_\T.3__0DA2_["GI_^EH*#_
+M24Y:_TU+3?\X.D+_(2LZ_SA#5/\H,4+_'1TH_RDD*/^AG9O_6%-'_Z><D?^)
+MB7[_75M8_]?1V?\Y/$'_2TY3_R$C*/\M+S3_+2\T_RHN-O\K,#;_.#M _S]!
+M1/]K7U#_K9B&_[JBD_]C4D3_LYR=_R\C)O\@(2+_)B$C_^S0T_^[KK/_9W)Y
+M_T=(3__FV.#_Z=GA_^K:XO_FUM[_YMGD_]S,U/_ZY>'__^C;___FV_^CE)7_
+M(QD<_R\H*/] -S#_8%92_QH1$?\F'B'_(!H>_R0>(O\>&AS_+2LH_R,;%__"
+MLZW_.34S_T)'3/]L<'+_-BXL_RXB(_\Q)2C_,RHD_R0=%_\Q*"'_DXB!_SDP
+M,/\A'![_'Q<:_RHA(?\P)23_+R8F_R4>'O\8%!+_'!H7_Q40%/\;%AK_)AXA
+M_R@?'_\J)B3_14=%_V-L;/]@9&;_(!\E_XIX;O]00CG_*Q\;_T4[,?]U:63_
+MNJVL_RDA)/\F&R+_+R at O_QP>(?\/$A/_44M)_RD@(/\A'![_(!XA_QL=(O\I
+M*C'_/$!(_T9,5O\M,3G_6F!J_S]&4O])4F#_35=B_T--6/]"3%?_45MF_R$C
+M*/\J(B#_I):-_TH\,_^)?GW_& \/_R0?(?\A'"#_4$='_T)$2?]%2U/_9U]=
+M_W)M;?\]0D[_+RTO_S]!2?]%4F7_+#9%_R at H,?]12$C_M+"N_V1;5/^]K)__
+MHX^'_U=84?]H;6G_O[W _S(T.?]/45;_(2,H_S R-_\K+3+_(2,K_RTO-O\Z
+M/$'_-C8Y_V1;5/^#<VG_?FYE_WQQ:O\N("'_)1T at _R,A(_\H(R7_\-;3_\6X
+MM_]775__,BTM__G=V?__X=O__^';___BW/__YM___^;B___JX___Z>#__^7>
+M_Z"1E?\B&A[_*20F_S(K)?]734G_'!,3_R4=(/\>&!S_'A8:_QL7&?\D)2;_
+M'AD;_[VPJ_\Q+RS_66%E_X*'C/\X,#/_-"@I_R\D(_\Q*"+_'A82_T(Y,O]3
+M2$'_*R(B_R(='_\>%AG_*B$A_RH?'O\K(R'_)1X>_Q0/$?\7$A;_%1 6_Q0/
+M$_\E'2#_*R(B_RLG)?\J+"K_9W!P_VEM;_\?'B7_?&QC_UI.1_\Q)B7_1#LT
+M_UQ02__"M;3_+"0G_R8=)/\C'2'_*2<D_WQU;_]N9&#_(1 at 8_QT8&O\8%AG_
+M'!XC_Q87'O] 1$S_45=A_R(F+O],4ES_/T92_T=07O\]1U+_14]:_T1.6?])
+M4U[_)R4N_RD='O]83$7_A'MU_QX9&?\G(R7_(QXB_R$<(O]P86'_CHF-_T%&
+M3/]=6%/_HY^=_SQ!3?\O+2__.CQ$_T5.7/\J*S+_8%I8_ZB=G/];5E#_P+.H
+M_Z62AO^/@WK_0DI&_U-;5_]P<G#_-C<^_TY/5O\H*B__.CQ!_RPN,_\>("C_
+M("$H_SLZ0/\D(B7_'AH8_T(Z-O]0143_(1T?_R4A(_\B'B#_(Q\A_R8B)/_I
+MU-#_HYV;_VQT=O]234__]=_=__KAX/_[XN'__N7D___IXO__Z>+__^KB___K
+MYO__Z^;_E8B-_R$8'_\A'"#_*B4 at _TI"0/\5#@[_)!P?_QT7&_\@&!O_'AL:
+M_R at D)O]33$S_M*>F_S(P,O]A:&[_2D]5_R\G*_\S*"?_+B0 at _R\E(?\;%1/_
+M+B@@_S\W+?\;$Q'_*20F_QX9&_\K(B+_,28E_RD@(/\H("/_%A 4_QP6'O\3
+M#A3_% \3_R$<'O\E'A[_*B4E_S at Z./]I<G+_8V=I_QL:(?]N8EG_8550_S G
+M)_\[-R__-RXG_\>YMO\Q*2S_)2 B_SLV,?^+ at GO_:5E/_QT1#?\I("#_*B4G
+M_S0R-?\7&1[_)"4L_TE-5?]67&;_1$I4_T]48/\Z04W_0DM9_U-:9O]#35C_
+M1E%<_TY79?\B'B?_+"(E_W5K9_\;%A'_)B(D_R >(?\A'"#_'18=_YJ-C/_@
+MV-O_/D%&_V!;5O^8E)+_-3M#_S P,_]+3U?_&A\E_XN)AO^QIZ/_8UI:_ZJD
+MG/^:BW[_IYB+_V5E7/\\2DG_*S<T_T]44/] 0D?_4E5:_QL=(O\Z.3__*BPQ
+M_R,D*_\G)S#_0T%$_RLG*?\E(2/_.3(R_\&YO/\J*"O_'AXA_R$@'_\H(R/_
+M*20D_[JKJ_]S<&__765I_R\I+?_VX-C__>/8___HW?__Z^#_^^3?___KY___
+MZN;__^WG__WJY/^-?(;_(!<>_QT;'O\?&AS_.30V_Q<3%?\<&!K_'AH<_R,?
+M'?]S;FG_M*NE_U!#/O]22DC_*2<I_T1,3O]#2$W_,"LM_RHC(_\F'Q__*2(B
+M_Q at 2%O\C(!O_)248_Q82$/\C'B+_'AH<_RLD)/\L)"+_)R(D_R<B)O\6$17_
+M%1 4_Q00$O\<&!K_)" B_R0@(O\J(B7_+2LM_VAQ<?]=9&3_'ALA_U9/0_]R
+M9&'_(ATA_S@^.O\C'AC_Q+>R_R\G*O\C(!__?75S_R,6%?\E'1O_(ATA_R0<
+M'_\H(2'_(1TE_Q at 8(?\A(2K_1TA3_TY17?]-4V/_1DY>_T5-7?\Z0E+_6U]N
+M_T]99_]'5F/_3UAF_R<F+?\D'R/_(!L?_R0?(_\F)";_'AH<_QL7&?\7$A3_
+MNK:T_][1UO]%1$K_6E)._Y>1C_\Y.3S_;W!W_U!06?]E:&G_?W]\_X!X=/^\
+MJZ7_GY2-_Y>,A?]D7%C_1TU)_S="0_\J-3;_-#L[_X.)A?])3U'_)20J_S(O
+M-?\A(RC_)RTO_R,D+_\Z/#G_Y.'@_RLH+O\A'![_IIN:_R$9'/\?'"+_+BLJ
+M_Z.AF?^<F93_ULG(_[FMJ?_AU]/_^.;C__OBV___Y][__^?>___HW___ZN+_
+M_^OC__[JXO__Z^/__NOC_WUL=O\>%1S_&!89_Q at 3%?\M*"K_&!06_QH6&/\<
+M&!K_65!*_S at O*?\T+BS_03P^_T5 0O\B("/_04E-_U9;8?\H(R7_*R0D_R8?
+M'_\L)27_%A 4_QH7%O\<&A7_%1$3_Q82%/\;%QG_)A\?_RXF)/\F'Q__)2 B
+M_Q81$_\;%AC_)2 @_RDD)/\F(2'_)B$A_R<?(O\F)";_9W!P_V-J:O\>&R'_
+M3D<[_V]A7O\;%AK_0$5%_QL:&?]G8ES_)B0?_QX?(/\7$A;_(AH>_R$?(O\A
+M'B3_(1D<_R(;&_\;%Q__("(J_SD[0_\_14__2E%=_T)+6?\Z0U'_1D]=_U9?
+M;?\_3%G_2%5B_TE47_]-5V'_-S8\_R at C)_\@&Q__(!L?_X%Y?/\I(23_'!<9
+M_QL7&?^>F);_KI^D_T-%2O]74DW_D8J*_TA"1O_CU=W_Y=KA_Y&/F/]<5%?_
+MO*RC_[RIG?]]>W3_24Q&_S]$0O\Y1T;_+C<W_SE"0O^.E97_+C4U_S<]/_\Y
+M.#[_&!4;_S$S./\U.SW_*BLV_U!.2__<U=7_)28M_Q87&/\W,##_)R$E_Q at 3
+M%_\>(!W_9VID_WEV<?_ at T,?_SKBO__SDV__XWM7__.+9___FW?__Y][__^C?
+M___JXO__Z^/__NKB__[JXO__Z^/_;EUG_R$8'_\3$13_&106_R ;'?\5$1/_
+M&A88_QH6&/\D'!K_*!\?_T,^/O\]/#O_0SU!_QX;(?])4%;_3E):_S8P-/\I
+M(B+_*R0D_RHC(_\6$A3_%1,5_Q,1$_\4$A3_$@X0_R <'O\C'!S_-"PJ_R8?
+M'_\I(B+_)!T=_R at A(?\I(R'_*2,A_RDC(?\L)B3_*B(E_RXL+O]B:VO_96QL
+M_R =(_\[-"C_AGAU_Q at 3%_\7%Q3_7UU8_UI84?\C'!S_&A@;_R(=(?\C&Q__
+M(!L?_R(=(_\@&!O_*2(B_R4A*?\D)B[_+C0\_SM#3?\\1E'_0DQ7_TI47_]$
+M3EG_1U%<_SY(5O]!2%3_7EYG_Y&3F/]!/T+_(ATA_RDD*/\E("3_3T-&_R at 9
+M'?\>%AG_'AH<_]S4TO_PW^7_0T5*_V5C7O^"@(+_8%I>_^C6VO_IW=[_V-+:
+M_^[@X?^]KJ'_BH)X_TU/3?\X04'_.$='_R\Y/?]%2DK_B9&._S Y.?]!3$W_
+M/T=+_R,B*/^?G*+_,S4Z_RPT-O\Q,CW_75E7_^;8V?]*04C_F)*0_YF4C_^/
+MCHW_C8N(_V1I9_]=9&3_9F5>_^W=T__VW-'__]_5__[CV/__YMW__^;=___E
+MW/__Z-___^OC__SHX/_ZYM[__NKB___JXO]:25/_(1@?_QL9'/\=&!K_&!,5
+M_Q41$_\6$A3_%A(4_QT6'?\E'R/_/#<W_T5"/?\<%!C_&A8>_TU36_](2U;_
+M/SD]_R<@(/\B&QO_*"$A_Q42$?\3$13_&!89_Q(0$O\3#Q'_'1D;_R4>'O\R
+M*BC_*2$?_S H)O\J(B#_+"0B_R@@'/\O)R/_+B8B_RHB'O\J(R/_(R$C_UIC
+M8_]C:FK_)2(H_S I'?^8BH?_-3 T_W5P:O]%0C?_(QL7_QP-$O\B&AW_(1L9
+M_R<<&_\A'1O_'QH>_R,;'O\E'A[_)2$I_S0V/O\T.D+_0TM5_SU'4O\U/TG_
+M0$I4_T]98_\X0DS_,3M)_SX^3?^KH:O_I)ZB_SLV.O\F(27_(1P at _QP7&_]2
+M0T?_,B,G_R(8&_\/#0__J9Z=_^/2V/];76+_7%I5_W%V=O]A7&#_Y-+4_^/9
+MU?_HX.3_NJVH_XA^</],44O_.C\__S]'2?\A+S+_459<_XB,BO\V/#C_0TM-
+M_SI&2O\Z0D;_'QXD_]C5V_\V.#W_+C8X_R\P._]=65?_Z=?9_UU+3?_ at T<O_
+MGI2)_U]@6?]=7%7_6%U=_U9B8?]O;F?_[-_4__??UO_]W=7_^]_7__SBV?__
+>YMW__N3;___GWO__ZN+_^^??__[JXO_]Z>'__^CA
+ 
+end

Added: vendor/Python/current/Lib/test/testimgr.uue
===================================================================
--- vendor/Python/current/Lib/test/testimgr.uue	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/testimgr.uue	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1170 @@
+begin 755 test.rawimg.rev
+M_UI)4_\A&!__&QD<_QT8&O\8$Q7_%1$3_Q82%/\6$A3_'18=_R4?(_\\-S?_
+M14(]_QP4&/\:%A[_35-;_TA+5O\_.3W_)R @_R(;&_\H(2'_%1(1_Q,1%/\8
+M%AG_$A 2_Q,/$?\=&1O_)1X>_S(J*/\I(1__,"@F_RHB(/\L)"+_*" <_R\G
+M(_\N)B+_*B(>_RHC(_\C(2/_6F-C_V-J:O\E(BC_,"D=_YB*A_\U,#3_=7!J
+M_T5"-_\C&Q?_' T2_R(:'?\A&QG_)QP;_R$=&_\?&A[_(QL>_R4>'O\E(2G_
+M-#8^_S0Z0O]#2U7_/4=2_S4_2?] 2E3_3UEC_SA"3/\Q.TG_/CY-_ZNAJ_^D
+MGJ+_.S8Z_R8A)?\A'"#_'!<;_U)#1_\R(R?_(A@;_P\-#_^IGIW_X]+8_UM=
+M8O]<6E7_<79V_V%<8/_DTM3_X]G5_^C at Y/^ZK:C_B'YP_TQ12_\Z/S__/T=)
+M_R$O,O]15ES_B(R*_S8\./]#2TW_.D9*_SI"1O\?'B3_V-7;_S8X/?\N-CC_
+M+S [_UU95__IU]G_74M-_^#1R_^>E(G_7V!9_UU<5?]875W_5F)A_V]N9__L
+MW]3_]]_6__W=U?_[W]?__.+9___FW?_^Y-O__^?>___JXO_[Y]___NKB__WI
+MX?__Z.'_;EUG_R$8'_\3$13_&106_R ;'?\5$1/_&A88_QH6&/\D'!K_*!\?
+M_T,^/O\]/#O_0SU!_QX;(?])4%;_3E):_S8P-/\I(B+_*R0D_RHC(_\6$A3_
+M%1,5_Q,1$_\4$A3_$@X0_R <'O\C'!S_-"PJ_R8?'_\I(B+_)!T=_R at A(?\I
+M(R'_*2,A_RDC(?\L)B3_*B(E_RXL+O]B:VO_96QL_R =(_\[-"C_AGAU_Q at 3
+M%_\7%Q3_7UU8_UI84?\C'!S_&A@;_R(=(?\C&Q__(!L?_R(=(_\@&!O_*2(B
+M_R4A*?\D)B[_+C0\_SM#3?\\1E'_0DQ7_TI47_]$3EG_1U%<_SY(5O]!2%3_
+M7EYG_Y&3F/]!/T+_(ATA_RDD*/\E("3_3T-&_R at 9'?\>%AG_'AH<_]S4TO_P
+MW^7_0T5*_V5C7O^"@(+_8%I>_^C6VO_IW=[_V-+:_^[@X?^]KJ'_BH)X_TU/
+M3?\X04'_.$='_R\Y/?]%2DK_B9&._S Y.?]!3$W_/T=+_R,B*/^?G*+_,S4Z
+M_RPT-O\Q,CW_75E7_^;8V?]*04C_F)*0_YF4C_^/CHW_C8N(_V1I9_]=9&3_
+M9F5>_^W=T__VW-'__]_5__[CV/__YMW__^;=___EW/__Z-___^OC__SHX/_Z
+MYM[__NKB___JXO]];';_'A4<_Q at 6&?\8$Q7_+2 at J_Q@4%O\:%AC_'!@:_UE0
+M2O\X+RG_-"XL_T$\/O]%0$+_(B C_T%)3?]66V'_*",E_RLD)/\F'Q__+"4E
+M_Q80%/\:%Q;_'!H5_Q41$_\6$A3_&Q<9_R8?'_\N)B3_)A\?_R4@(O\6$1/_
+M&Q88_R4@(/\I)"3_)B$A_R8A(?\G'R+_)B0F_V=P</]C:FK_'ALA_TY'._]O
+M85[_&Q8:_T!%1?\;&AG_9V)<_R8D'_\>'R#_%Q(6_R(:'O\A'R+_(1XD_R$9
+M'/\B&QO_&Q<?_R B*O\Y.T/_/T5/_TI17?]"2UG_.D-1_T9/7?]67VW_/TQ9
+M_TA58O])5%__35=A_S<V//\H(R?_(!L?_R ;'_^!>7S_*2$D_QP7&?\;%QG_
+MGIB6_ZZ?I/]#14K_5U)-_Y&*BO](0D;_X]7=_^7:X?^1CYC_7%17_[RLH_^\
+MJ9W_?7MT_TE,1O\_1$+_.4=&_RXW-_\Y0D+_CI65_RXU-?\W/3__.3@^_Q at 5
+M&_\Q,SC_-3L]_RHK-O]03DO_W-75_R4F+?\6%QC_-S P_R<A)?\8$Q?_'B =
+M_V=J9/]Y=G'_X-#'_\ZXK__\Y-O_^-[5__SBV?__YMW__^?>___HW___ZN+_
+M_^OC__[JXO_^ZN+__^OC_XU\AO\@%Q[_'1L>_Q\:'/\Y-#;_%Q,5_QP8&O\>
+M&AS_(Q\=_W-N:?^TJZ7_4$,^_U)*2/\I)RG_1$Q._T-(3?\P*RW_*B,C_R8?
+M'_\I(B+_&!(6_R,@&_\E)1C_%A(0_R,>(O\>&AS_*R0D_RPD(O\G(B3_)R(F
+M_Q81%?\5$!3_%! 2_QP8&O\D("+_)" B_RHB)?\M*RW_:'%Q_UUD9/\>&R'_
+M5D]#_W)D8?\B'2'_.#XZ_R,>&/_$M[+_+R<J_R,@'_]]=7/_(Q85_R4=&_\B
+M'2'_)!P?_R at A(?\A'27_&!@A_R$A*O]'2%/_3E%=_TU38_]&3E[_14U=_SI"
+M4O];7V[_3UEG_T=68_]/6&;_)R8M_R0?(_\@&Q__)!\C_R8D)O\>&AS_&Q<9
+M_Q<2%/^ZMK3_WM'6_T5$2O]:4D[_EY&/_SDY//]O<'?_4%!9_V5H:?]_?WS_
+M@'AT_[RKI?^?E(W_EXR%_V1<6/]'34G_-T)#_RHU-O\T.SO_ at XF%_TE/4?\E
+M)"K_,B\U_R$C*/\G+2__(R0O_SH\.?_DX>#_*R at N_R$<'O^FFYK_(1D<_Q\<
+M(O\N*RK_HZ&9_YR9E/_6R<C_N:VI_^'7T__XYN/_^^+;___GWO__Y][__^C?
+M___JXO__Z^/__NKB___KX__^Z^/_E8B-_R$8'_\A'"#_*B4 at _TI"0/\5#@[_
+M)!P?_QT7&_\@&!O_'AL:_R at D)O]33$S_M*>F_S(P,O]A:&[_2D]5_R\G*_\S
+M*"?_+B0 at _R\E(?\;%1/_+B@@_S\W+?\;$Q'_*20F_QX9&_\K(B+_,28E_RD@
+M(/\H("/_%A 4_QP6'O\3#A3_% \3_R$<'O\E'A[_*B4E_S at Z./]I<G+_8V=I
+M_QL:(?]N8EG_8550_S G)_\[-R__-RXG_\>YMO\Q*2S_)2 B_SLV,?^+ at GO_
+M:5E/_QT1#?\I("#_*B4G_S0R-?\7&1[_)"4L_TE-5?]67&;_1$I4_T]48/\Z
+M04W_0DM9_U-:9O]#35C_1E%<_TY79?\B'B?_+"(E_W5K9_\;%A'_)B(D_R >
+M(?\A'"#_'18=_YJ-C/_ at V-O_/D%&_V!;5O^8E)+_-3M#_S P,_]+3U?_&A\E
+M_XN)AO^QIZ/_8UI:_ZJDG/^:BW[_IYB+_V5E7/\\2DG_*S<T_T]44/] 0D?_
+M4E5:_QL=(O\Z.3__*BPQ_R,D*_\G)S#_0T%$_RLG*?\E(2/_.3(R_\&YO/\J
+M*"O_'AXA_R$@'_\H(R/_*20D_[JKJ_]S<&__765I_R\I+?_VX-C__>/8___H
+MW?__Z^#_^^3?___KY___ZN;__^WG__WJY/^@D97_(AH>_RDD)O\R*R7_5TU)
+M_QP3$_\E'2#_'A@<_QX6&O\;%QG_)"4F_QX9&_^]L*O_,2\L_UEA9?^"AXS_
+M.# S_S0H*?\O)"/_,2 at B_QX6$O]".3+_4TA!_RLB(O\B'1__'A89_RHA(?\J
+M'Q[_*R,A_R4>'O\4#Q'_%Q(6_Q40%O\4#Q/_)1T at _RLB(O\K)R7_*BPJ_V=P
+M</]I;6__'QXE_WQL8_]:3D?_,28E_T0[-/]<4$O_PK6T_RPD)_\F'23_(QTA
+M_RDG)/]\=6__;F1 at _R$8&/\=&!K_&!89_QP>(_\6%Q[_0$1,_U%78?\B)B[_
+M3%)<_S]&4O]'4%[_/4=2_T5/6O]$3EG_25->_R<E+O\I'1[_6$Q%_X1[=?\>
+M&1G_)R,E_R,>(O\A'"+_<&%A_XZ)C?]!1DS_75A3_Z.?G?\\04W_+RTO_SH\
+M1/]%3ES_*BLR_V!:6/^HG9S_6U90_\"SJ/^EDH;_CX-Z_T)*1O]36U?_<')P
+M_S8W/O].3U;_*"HO_SH\0?\L+C/_'B H_R A*/\[.D#_)"(E_QX:&/]".C;_
+M4$5$_R$='_\E(2/_(AX at _R,?(?\F(B3_Z=30_Z.=F_]L=';_4DU/__7?W?_Z
+MX>#_^^+A__[EY/__Z>+__^GB___JXO__Z^;__^OF_Z.4E?\C&1S_+R at H_T W
+M,/]@5E+_&A$1_R8>(?\@&A[_)!XB_QX:'/\M*RC_(QL7_\*SK?\Y-3/_0D=,
+M_VQP<O\V+BS_+B(C_S$E*/\S*B3_)!T7_S$H(?^3B('_.3 P_R$<'O\?%QK_
+M*B$A_S E)/\O)B;_)1X>_Q at 4$O\<&A?_%1 4_QL6&O\F'B'_*!\?_RHF)/]%
+M1T7_8VQL_V!D9O\@'R7_BGAN_U!".?\K'QO_13LQ_W5I9/^ZK:S_*2$D_R8;
+M(O\O*"__'!XA_P\2$_]12TG_*2 @_R$<'O\@'B'_&QTB_RDJ,?\\0$C_1DQ6
+M_RTQ.?]:8&K_/T92_TE28/]-5V+_0TU8_T),5_]16V;_(2,H_RHB(/^DEHW_
+M2CPS_XE^??\8#P__)!\A_R$<(/]01T?_0D1)_T5+4_]G7UW_<FUM_SU"3O\O
+M+2__/T%)_T529?\L-D7_*"@Q_U%(2/^TL*[_9%M4_[VLG_^CCX?_5UA1_VAM
+M:?^_O<#_,C0Y_T]15O\A(RC_,#(W_RLM,O\A(RO_+2\V_SH\0?\V-CG_9%M4
+M_X-S:?]^;F7_?'%J_RX@(?\E'2#_(R$C_R at C)?_PUM/_Q;BW_U==7_\R+2W_
+M^=W9___AV___X=O__^+<___FW___YN+__^KC___IX/__Y=[_HY*2_R@<'?\X
+M,"[_2#XT_V9:5?\;$A+_*R,F_R,=(?\K)2G_(AX at _SX[-O]#-S#_RK6S_RXF
+M*O]-3EG_9V1P_S$I)?\O(R3_*APD_RLB'/\E'AC_;&-<_[.HH?\V+2W_'QH<
+M_QP4%_\M)"3_+2(A_RTD)/\E'A[_(1X9_RLJ(_\6$A3_'AD=_RDA)/\F'1W_
+M*"0B_S]!/_]@:6G_8V=I_R >(?^@C8'_8%!&_SDM)O]?54O_D(1__[6HI_\F
+M'B'_)AP?_S4P,O\N+"[_85U?_\>^OO\N)27_(QX at _R$?(O\;'2+_-C<^_TU1
+M6?\^1$[_+C(Z_TE/6?]"257_14Y<_T!*5?]&4%O_/DA3_TE37O\A(RC_*2$=
+M_ZB8CO^XI9O_:EI7_X5X=_\B&QO_)"(D_R at C(_\T.3__0DA2_["GI_^EH*#_
+M24Y:_TU+3?\X.D+_(2LZ_SA#5/\H,4+_'1TH_RDD*/^AG9O_6%-'_Z><D?^)
+MB7[_75M8_]?1V?\Y/$'_2TY3_R$C*/\M+S3_+2\T_RHN-O\K,#;_.#M _S]!
+M1/]K7U#_K9B&_[JBD_]C4D3_LYR=_R\C)O\@(2+_)B$C_^S0T_^[KK/_9W)Y
+M_T=(3__FV.#_Z=GA_^K:XO_FUM[_YMGD_]S,U/_ZY>'__^C;___FV_^SI)[_
+M)AX:_SDT+O]72CW_<6-:_Q at 2%O\R*2G_)AT=_R at A*?\=&1O_2TQ%_U%(0?_(
+MMK/_*!XG_V%D=?]%2%3_.#,S_R<=(/\S)RK_,R at A_RLE'?]N95[_O[2M_S(I
+M*?\A'![_'Q<:_RLB(O\Q)B7_*B$A_R<A'_\J*"#_/S at R_R 8&_\@&QW_)R(B
+M_R4A'_\J(R/_3U!1_UUF9O]A9&7_(QXB_Z>4BO]N75?_7%!'_W!F6_^JGIG_
+MLZ6F_R<B)O\D("+_240__S(M)_]S<6[_R\"__RPI*/\C'2'_(1TE_R,O-O\Z
+M/#K_:EU8_R,>(/]$257_0TI6_T%)4_]#35C_3U)=_TM07/]+563_3%=B_R$D
+M)?\M*"/_IY>._[JEF?^ECX?_1#8S_R<=(/\F("3_+BXQ_SQ#2?]'4%?_8V=O
+M_Z*BJ_]4763_+BLQ_S4T0?\U.D;_&A at H_SDW1_\J,D+_'" H_R @(_^,B(;_
+M9UM6_XJ.AO^&BX?_?'Q__S<Y/O].45;_&QTB_RHG+?\V.#W_'R,K_RTR./\S
+M-3K_/S]"_X=Z9_^^HYC_UKNJ_X-P6/_%K:3_H9*-_S$J*O\J(R/_Z<W/_\>Z
+MQ_\T.5+_/S]4_U!$7?]94V?_8%QL_VMG=_][9G+_CG9[__SBW___Z-W__^KA
+M_Z:1C?\N(A[_/S at R_V111?]V9ES_&A49_T X-O\P*";_*24M_R4C)?]H:%__
+M6U),_[BJI_\P*C+_3E%C_T9(5_\P*RW_*R$D_S0H*?\P)1[_*"(:_XV%>__&
+MN[3_+B0G_Q\9'?\?%QK_+",C_RTB(?\L(R/_)B(@_SHY+O]?5E#_)A\?_Q\:
+M'/\H(R/_(!P:_RTD)/]35%7_7F=G_V)E9O\@'2/_JIF3_S at K*O]:5%+_<6MC
+M_[2JIO^GFYS_)B D_R8C(O]94DS_0STS_W9T;__+OKW_*2 at G_R$:(?\@'"7_
+M.3Y*_T!"1?^"@'C_F(Z*_R =(_]:7&3_2$];_TU79?]!14W_0T92_TQ69/]-
+M55__("$B_R\I)_^IG9;_HHR#_ZR6CO^CDY#_*1XC_R0>(O\J+#'_25!6_TM4
+M6_]+55__4%%<_UQE:_^WL[O_03]/_RDO.?^7DYO_(A\E_RLU0/\F+C[_&AXM
+M_R$@)O^%@(#_3E)0_S4Z./\9&Q[_.3@^_T%$2?\>'2/_-3(X_R$C*/\H+#3_
+M)2<N_SP^0_\^/D'_F8][_\&FG__DR[K_F89N_]/#NO^6B(G_,RTQ_R<B)/_G
+MTL;_QKVW_T]76_]A9VG_X<S1__;>V__^Y]O__^C?__O>W?_#I:?__.#<___G
+MWO__YM__MYV at _S$?(?])/3G_=F%5_W]M8_\B'2'_-BXL_S\W-?\D)BW_)"(D
+M_WUY<?]M85S_K*"<_S(N-O]66VW_24E8_S$L+O\H'B'_,"0E_S,H(?\N*"#_
+M;65;_\F^M_\S*2S_(!H>_R$9'/\P)R?_+R0C_R\F)O\A'1O_7UY3_XZ%?_\G
+M("#_(QX at _Q\:&O\J)B3_+20D_UE:6_]:8V/_:6QM_QX=(_^QI9[_'Q<:_S<W
+M.O]#0#O_O;6S_Z.7F/\J(B7_*2,A_U5,1?].1SO_;6MD_\:YN/\N+2S_(!D@
+M_RDE+O]03%S_+BXW_Q4=&?]$/SG_;&!<_S at S.?])4%[_14Y<_T%&3/]"2%+_
+M/D51_T!$3/\=&QW_)1X>_["DG_^<C(/_M*"8_[.CH/\I'B/_)!XB_S8U._]5
+M5U[_*S$Y_UYF</]?8&O_769L_UE57?\O+3W_.$),_SD]._^HJ:/_)"LQ_QXH
+M/?\F+4'_'2(N_QTB)_\P-CC_.3Q!_QD;'O\:&AW_-SH__RHI+_\B'R7_.CQ!
+M_RLO-_\R-#O_+S$V_S<W.O^<DX+_QJVH_^C0P?^DDWS_S+^^_SLT._\A'RC_
+M)B$G_^70S/_/P;[_6EQ?_SD]/_^ >7G_\>#:__OBU?__Y-G__^7A___CW___
+MY=[__^7<__WDW?^<A(W_*AHB_T$[.?]];%[_>VMA_R0?(_]!.3?_0CHX_R\X
+M/O\R-3;_BX)[_WEL9_^^M+#_-C4\_T]29/],2%C_*R,F_RLA)/\O(R3_+"$:
+M_RHD'/]X<&;_TL? _S(H*_\@&A[_(1D<_R\F)O\N(R+_+B4E_R<C(?]K:E__
+MN*^I_R at A(?\A'![_(QX>_RPH)O\L(R/_8F-D_V)K:_]A9&7_(!X;_[JIF_\E
+M'1O_=WAY_Q at 7%O_$O;W_E(:'_R@@'O\F'AK_6U%'_V5<3O]B7E;_N:RK_RLJ
+M*?\F'R;_&14>_SA!2/\G)BW_,"HN_R8H)O][<W'_/SM$_S4[2_]455S_3U%4
+M_T5+4_],4ES_.CE _QX8'/\K(R;_L:>C_ZB=EO^XI)S_MZ>D_RTB)_\E'R/_
+M,"\U_TY/5O\D)B[_;&]Z_UU>:?]67V7_55%9_S<U1?] 2EG_-SP\_RTK)O\_
+M0$O_)R\__R\V1/\Q-D+_'!XM_QH=*/]$1D[_/#Y#_S4U./\\/T3_)20J_RHG
+M+?\_04;_-#A _S8X/_\X.C__)B8I_Z"6A__%K:K_Y]##_Z.3?__3Q\C_/C<_
+M_R4?)_\I(B+_Z]/6_]7#Q?]#/T'_:&IM_U-=8?^UL:__^.'<__SEX/__Y][_
+M_^7<___FW?__Y-W__^CA_Z*1E_\C&Q__&104_XQ[;O^DE(O_)2 @_SX[.O]$
+M/S__-T%%_T1)1?^. at WS_CX%^_ZF at H/\_/$C_/D!5_UA28/\N)R?_+2$B_RTB
+M(?\J)2#_'!H5_V=B7?_+O\#_*B4G_R$<'O\?&!C_)R @_S(K*_\L)27_+"@@
+M_X%\</_'N[;_*2(B_R$<'/\C'A[_+BDI_R at H)?]@8F7_96MG_V1D9_\B'1W_
+MPJZF_S\T+?^#@GO_&QP6_]K+S/]R9F?_*24G_S H)/]22D#_>G%C_UI/2/^O
+MI*/_,2PL_QP7'?\L*C/_.4--_RDJ,?]_=G;_)B >_];)SO]*35C_14A3_X=\
+M>_]>6%;_*" >_TQ/6O\Z/$3_'AH<_RLF*/^=DI'_LJ>@_[RJIO^]KJ[_+",C
+M_R8B)/\U-CW_5EA at _R B*?\<'B/_C(V4_TI,4_] 04C_9F=R_T9)5/]N<'/_
+MKZ.D_T5#4_\H,#K_:&IM_SHX._\E*#3_)BDU_T!"2O]66%__0T5*_S<]/_\M
+M+3#_:65M_S] 1_\P,3S_-3<^_T9*3/\O,3;_?G)N_Z"+B?_1N;;_=6)<_]C*
+MTO]83EC_*"$K_R ;(?_IU-+_X<_+_T4^./].1D+_34U*_WU\>__<S\[_^-G3
+M___IX?__YM___^?@___FW__]Y-W_P+*S_RLC)O\A&QG_K9J0_Z>8D_\P*BC_
+M04 __S8Q,_]%2TW_1$A&_Y&(@O^:C(G_CH.(_RPJ.O]$15S_<6U]_RLC)O\M
+M(B'_,"4D_QX:&/\>'!?_&A02_\B_O_\G(B3_(AT=_R$:&O\G("#_*R0D_RXG
+M)_\M)Q__AX!R_\_#OO\H(2'_(!L;_R8A(?\F(2'_)B0A_UQ at 7O]G;&K_9&-B
+M_R(>'/^]J*/_-RTC_YV8DO\].S;_WLW-_V%86/\C(2/_*",E_S8S+O^ >W7_
+M3$1 _ZJBH/\J(R/_(!LA_QD9(O\]1%#_/3Y%_X^'A?]934G_X,[2_T1,5O] 
+M2%C_+BDO_TI&2/^!>'+_(2$L_S4R/O\H(R7_,2<J_Z&1CO_ L:O_J):3_[6F
+MIO\L(R/_)B(D_S<Y0/].4%?_&!H?_TY.4?\>("7_0$-(_TQ06/\[04O_3E!8
+M_VIL;__4Q<G_.SE)_RDS/?]'2$G_;VQK_R4H-/\S-D+_/D!(_UQ>9?]+3E/_
+M-#H\_QP<'_^>FJ+_1D9/_RPO._\N,#?_,30U_TM*4/^KI*3_V\[-_^G8V/_K
+MWMW_XM31_[^MJ?^5A'[_=V1<_^?2S?_MV]?_T\O'_];+RO_3S\W_/T)#_V]Q
+M;__JV];_^=[7___DW?__Y=[__^7>___GX/_$N[7_13LW_WIL:?_4OK7_FHJ'
+M_RTF)O\_/4#_-B\V_QP='O\\.SK_E)"._[&EH/]P:&S_)R<T_T)(6/]F9'3_
+M)1T at _RXC(O\M(B'_)2$?_R4C'O\@&!3_S\+!_RTF)O\?&!C_(AL;_RDB(O\O
+M*"C_+28F_S J(O^3C'[_S,"[_RLD)/\B'1W_)2 @_RTH*/\K(B+_7V1>_UYE
+M<_]:6F7_&QD4_\*MJ/]'.3#_IIV7_V%?6O_>S<W_1#L[_R(@(O\>&1W_+BLJ
+M_S(N+/]W;W+_HIF9_RTF)O\A'"+_'AXG_T%'4?]'1TK_FY&-_[6IHO_:R,K_
+M4EID_T1,8/\?'BO_%AL at _U-,1O]E7V?_*20P_RHB)O\X*2W_K)>5_]G(PO^7
+MA8+_>6IJ_RLB(O\G(R7_+S(W_TY15O\W-SK_AH&#_QP?(/\/%1?_2U%9_T!'
+M4_]'2%/_B8N._]O,T/]%0U/_-T%+_R(C)/\X-33_+"\[_SU 3/]"1$S_3$Y5
+M_TM.4_]"2$K_)24H_[&MM?]!04K_+S,[_S8Y/O])2TG_D(N-_R$='_\O*"C_
+M."\O_T(]/?](1DC_:F5E_Y&)A_^IG9G_Z]S6_]7(P_]:4$S_<VUK_VAG9O]/
+M5%+_/D9#_TY24/_'LJW_^-W6__G>U__^X]S__>3=_\S'N_]<44K_II*._^')
+MP/^9B(C_,2DL_S at U._]$/47_)B$A_R ?'O\N+"[_O[:P_XB#@_\\0D3_9G)V
+M_V]Q>/\O*BK_,28E_RL@'_\D(![_6UE2_T(Y,__0PK__,"@F_R(;&_\E'A[_
+M,"DI_R at A(?\J(R/_+RDA_Y")>__)O;C_*R0D_R(='?\H(R/_*20D_RLB*?]8
+M8E__("E8_SP\9_\<'AS_O:BC_V)22?^WJJ7_='%L_]W,S/\^-37_(R$C_R@@
+M(_\^.#;_.S0N_V=;7/^4BXO_*R0D_QX9'_\:&B/_/$!(_SPZ//^GFY;_Q[FP
+M_]O)S?](4%K_25!>_T]'2_\B(2?_4$4^_X%[?_]"0D__'1L>_R<=(/^FF)7_
+MT<6^_ZJ:E_^VIZ?_,2 at H_R<C)?\V/#[_3%!2_UA45O^FGIS_-3HV_R(K*_](
+M45C_1D]=_U!17/^'B8S_X]38_U)08/\W04O_7V!A_[Z[NO\V.47_*"LW_S]!
+M2?]&2$__14A-_TA.4/\I*2S_K:FQ_TE)4O\Q.#[_,34W_TM)1O_+PL+_)2 B
+M_R(:'?^YK;#_*",E_R =(_\<&R'_%A89_R4H*?^SK*;_V,O&_^+6TO^[M[7_
+M0D='_W!V<O]26%3_.3Y#_^/7T__OW-3_[-G1__/@V/_[Y]__TL:W_VE=5/_7
+MR,+_XL_%_X5W=/\L(R/_,RLN_T4_0_]H8U[_,2TK_R4>'O_6R<3_AH."_UI@
+M8O^/EYO_8F-D_RLF)O\N)R?_+24A_RLF(?]A757_HY>0_]3"O_\I("#_(AT=
+M_R0='?\K)"3_+R at H_RXE)?\B'AS_3TU(_\O O_\M)"3_(QP<_RLD)/\M)B;_
+M(14>_U588_\@)%'_-S!?_QX<'__'JZ?_<FI at _\>MJO^4CXK_W-'0_S at O+_\D
+M'R'_*B(@_UU62/]V:F7_V\S-_X5]@/\H(B;_(!H>_QD9(O\^/T;_.3 at W_[6O
+MI__3QL'_V,?-_T--6/]%2U7_?G9T_UE45/_(N;3_B8.+_T]27?\E(R7_+"<G
+M_ZF=F?^SI)__FHN&_ZN=GO\D'!__+28F_S$F*_]"24G_GJ*@_ZVKIO]B6EC_
+M3%A7_T515O]!2%3_3%18_T(_/O_EV=S_1DE5_T),5O]K:6O_RL/#_S@]2?\J
+M,3?_$1(9_TA(4?])2U+_04=)_RHJ+?^WL;G_/$!(_RPQ-O\P-C[_>W5S_]K.
+MS_\C)2K_'"$G_U-68O\I)##_(ATA_R(@'?\D(AW_(B<E_UI96/]M96/_W=',
+M_[*HI/],4U/_,CX]_XF0D/]>86;_<7AL_Y*(?O^2AH'_?G-L_ZZBD__7R+O_
+M>FQC_]G-QO_ETLC_@')O_RHA(?]!.3W_24))_VIC7?]G8EW_3T=%_]/$O_]A
+M7&#_.3Q'_V-F<O]#0$;_+B<G_RLD)/\N*23_*",=_W-O9_^]L:K_UL3!_RLB
+M(O\A'!S_(QP<_RHC(_\K)"3_,RHJ_R$<'/\D'Q__S,#!_RTD)/\E'A[_)R @
+M_R at A(?\H'1S_(B$:_Q86(_\I)2W_'!T7_\JMJ?]S<&7_S+"M_["HI/_?U]7_
+M-B\O_R0?(?\P*";_>')B_X1X=/_>S]#_;&9J_R at B)O\F("3_'1LD_SY 1?\\
+M.3C_M:^G_^'3T/_5Q,S_3%5C_T1)5?^$?GS_BH.#_];$P/^*@X__1TA3_RPH
+M*O\O*"C_KZ2C_ZN=FO^'=W3_HI:7_R\I+?\K(R'_JI*5_U%)3/_+O\#_O["P
+M_[BGK?]886?_2U=@_S]&5/]'3U/_4DU-_]S1UO]35F+_0T]8_X2"A/_4S<W_
+M/4)._QTC)?\O,3;_3T]8_R8G+O\Z0$+_*"@K_[ZXP/]*3E;_,C<\_S$Y0_]]
+M=7/_V<W._S1#4/\G.T__051L_S$_5O]A8G/_(QPF_RXE)?\H(2'_8%A<_S(J
+M+O_*PK[_HI>0_XJ(@_]/4U'_/4)"_W-[??\Z2UG_86!F_UE<4/]03D?_8UM1
+M_]C(OO]Q8ES_W<_,_^;2RO]W:FG_-2TQ_S\X/_]#/47_9V!:_VYG8?^LHI[_
+MWLO%_VUF;O]#1%7_5E=H_T="3O\M)2C_+28F_RLF(?\V,2O_;&A at _\F]MO_4
+MPK__*R(B_R0?'_\F'Q__+28F_RHC(_\M)R7_2D(^_RH@'/_+O[O_*R(B_R0=
+M'?\B&QO_*R0D_R47'_\C&Q?_(ALB_RXF*?\@(1K_SK*N_W-R9__#J:;_N+.N
+M_]W5T_\V+R__(QX at _S\W-?^5CW__<&1 at _]K+S/]E7V/_*2,G_R,=(?\@'B?_
+M/3]$_T5"0?^UKZ?_V,K'_]' R/]!2EC_5%EE_Y"*B/^@F9G_X]'-_W=P?/]&
+M1U+_*",E_RHE)_^LI:7_E(R*_XM^??^<D9;_)2 F_RHB)?]_='/_6EQ:_\2]
+MO?^VL[+_O*ZV_TU57_]"3%K_24Y at _T=.5/]Q;&S_XM?<_TQ/6_\Y14[_A(*$
+M_]K3T_\Y/DK_/3X__U=97/\]/T;_*"<M_Q08&O\D)"?_N[6]_T)&3O]!1DO_
+M,3E#_Y&)A__?T]3_5VEW_S=-8_\G/%7_,$5=_TA<</\7(2__'1\B_R8E)/]0
+M14K_,"<N_Q\:'O^EGY?_L*6>_XZ'@?]M;VW_;G9Z_U9HC/](46+_4%I+_TQ,
+M2?]33D[_X]/*_V=84__ATM+_Y=#+_VQ at 8?\Q*C'_.3,[_SPX0?^+ at GO_?G5N
+M_[ZRK?_ at S,3_349-_SL]3/])2UK_.C8__S H*_\L)27_+RHE_R\J)/^/BX/_
+MS<&Z_]+ O?\N)27_)!\?_RDB(O\J(R/_*"$A_R<D'_]D6U7_PK.N_\S N_\M
+M)2/_)A\?_R0='?\J(R/_(QDC_R,<'/\@&2'_*"$K_Q\D(/^]IJ'_>WMP_\"K
+MI__&P;S_V]/1_S0M+?\D'R'_/34S_ZJDE/]5247_Y]C9_TI$2/\I(R?_(AP@
+M_R >)_\M+S3_B(6$_T Z,O_BU-'_R;C _TM48O]$257_E8^-_Z.<G/_FU-#_
+M7%5A_SH[1O\M)RO_,"HN_ZJEI_\[-C;_AWM\_YN2F?\A'27_(AP at _R,=&_\K
+M+2K_-RXN_R ;'__0Q<K_5V%E_TM77O])4%S_4UM?_VUH:/_>T]C_0$-/_S]+
+M5/\T,C3_S<;&_SQ!3?]*1T;_8&%B_T-(3?]02T__+3$S_RTM,/^JI*S_045-
+M_SM 1?\I,3O_6E)0_]#$Q?^*C8[_?W^"_Y^=IO]676/_+C<^_SL]0O\N)R?_
+M,2 at H_[2GHO\J)2?_(" I_TQ'2?^'A'G_I:29_V=L:/]L='C_8W9^_X:(C?^"
+M at G__1T5"_UI54/_HV];_6U%'_^37TO_BSM?_7E)3_S0Q)?\L*";_1#M"_WIN
+M9?^.A7?_R;R[_]W)Q?]!/T'_,3$^_T1$4?](1T[_,"HH_RH>'_\S)RC_-RXH
+M_YB-AO_8R<3_T\+"_RHB)?\C'B#_)AXA_RTD)/\N)B3_-BTG_VYI8__:R,7_
+MS[Z^_RLF)O\E("#_)!\?_R at C(_\4#Q/_%! 2_Q81%?\8$Q?_,"8B_[*EH/]#
+M03K_NK"L_]/'P__<T=#_-"\O_R<B)/\X-#+_O[.D_TD_.__EV=K_0CT__R8B
+M)/\@&Q__(R8Q_T)#3O^HG)?_-"@D_][1T/_&N;[_/$A1_U9=8_^5D(O_FY24
+M_^O>V?]04%O_/4!+_R8A(_\G(R7_*24G_U925/]G8F3_4T]1_R,>(O\K)RG_
+M*B8D_T='1/]G6%S_A(&'_]C0T_]88&K_359=_TA/6_]56F#_=&MK_^;9WO]#
+M1E+_5%MA_T8^0?_;S]+_0$90_W!S=/]I:&__1TI+_YZ:G/\T-CO_+2PR_Z:B
+MJ_\V.43_+S(W_RXT/O^?DI'_L9^A_VM?6O]<5U'_:&EC_VYJ8O]]:V?_P[*X
+M_];,R/_1O[S_=F%?_ZJAH?\D(RG_/S<[_R8D(?^+CHC_9VQJ_U%57?]Q<&__
+M?GQW_U=95O]044O_4U%)_^;%UO]N2&G_W+78__OBW?]52$W_*2(L_RDF,O\U
+M-4#_>G-G_Y6-??_+O[K_Y-#,_T=$2O\S,T#_.#=$_U957/\I(1__,B8G_S,G
+M*/\T*B;_D85^_]G*Q?_%MK;_*R,F_R(='_\E'2#_+B4E_RL@'_\V*B7_ at H!Y
+M_]+ O?_2P<'_*20D_R4@(/\F(2'_(AT=_QP7&_\6$17_%Q(6_QL6&O]%-3+_
+MIYN6_TY+1O^FH)[_W<_,_]?,R_\P+2S_)B$C_S(N+/_$MJ?_54U)_^+9V?\Z
+M-37_)B(D_QH8&_\C)C'_0D51_Z:7D?]21$'_X=/4_[>LL_\\2%'_5EMA_YF3
+MD?^0B8G_Z=S7_T9&4?\X.T;_)R,E_R<C)?\E(2/_)B(D_RTI*_^NJJS_(Q\A
+M_R at D)O]M8%7_ at WMK_YZ'>_]P8UC_VM+0_U-79O\M-3__14Q8_UI<8_]]='3_
+MZ=K?_T5(5/]/45C_8%99_][/U/]$1U+_CI.3_W1R>_]%2$G_R<3$_S0S.O\L
+M*S+_FIBA_S,T/_\X.T#_)"HT_ZN>G?^NFIS_CGUW_W!D7?]".S7_DH1[_WMH
+M8/_+O\C_03]!_S at S+O]F6UK_/CPY_RHL*O\V-#;_(!TC_S8W./]T>';_:FUR
+M_YF6E?]H9F/_<'5Q_U164_]454__Z+O?_XA.H/^F9-'_QYS2_UQ(4?\U&3/_
+M1S [_S4N*/^)?7G_FHF4_]3(Q/_MVM3_4T]7_S<W1/]44V#_6UIA_RHB(/\K
+M'R#_+R,D_STS+_^#=W#_U,7 _\2UM?\K(R;_(!L=_RDA)/\T*RO_,28E_SPP
+M*_^*B('_W,K'_]3#P_\N*2G_)B$A_R,>'O\J)27_)R(F_QH5&?\A'"#_'!<;
+M_U1$0?^6BH7_8V!;_ZFCH?_;S<K_U<K)_S$N+?\H(R7_+2DG_\6WJ/]>5E+_
+MY-O;_SPW-_\G(R7_'1L>_T!#3O\[/DK_L*&;_U]13O_DUM?_K:&J_T)-6/]3
+M5U__7E=7_X%Z>O_DU]+_3T]:_RTP._\D("+_)2$C_R,?(?\D("+_(AX at _R,?
+M(?\F(B3_(1T?_RLC(?\S,2S_74Y._ZB>FO_7S\W_3U-B_RLS/?] 1U/_7%YE
+M_X^&AO_FU]S_24Q8_U)46_]C65S_VLO0_SH]2/]^@X/_85]H_TE,3?_>V=G_
+M+RXU_R\N-?^4DIO_/#U(_SU 1?\N-#[_MJFH_\"LKO^JD8K_HHA]_ZJ4C/^Y
+MGY3_CG]R_\K#S_\P,S[_(R8G_XU_@/^3 at 7W_WLO%_TH\/?\<%A[_(1\B_UQ>
+M6_]K;VW_='%P_W]^??]W?'K_9VMI_UU at 8?_>V\__+2HI_S N-_\X/CK_?WZ+
+M_V9#BO^C>Z__12Q+_ZJ*O?][6)C_T\+,_^S:T/]*1D__/CY+_U-27_\]/$/_
+M*R,A_R\C)/\P)"7_/C0P_W)F7__7R,/_K)V=_RLC)O\@&QW_)Q\B_S,J*O\O
+M)"/_,24 at _XF'@/_=R\C_TL'!_R8A(?\D'Q__*",C_RLF)O\H(R?_*20H_R8A
+M)?\?&A[_<V- at _XR >_]Z=W+_IZ&?_^'3T/_*O[[_+RPK_R4@(O\L*";_Q+:G
+M_W5M:?_GWM[_.C4U_R<C)?\D(B7_4E5 at _T1'4_^ZJZ7_=6=D_^G;W/^5B9+_
+M0$I8_UQ?:O^CFY[_GYB8_^C;UO]#0T[_+C$\_RHF*/\F(B3_(Q\A_R0@(O\B
+M'B#_(AX at _R <'O\B'B#_%Q 8_RDN-/_*Q<O_O+2X_]S3T_]1563_(2DS_T!'
+M4_]L;G7_EXZ._]S-TO].45W_;&YU_W=M</_=SM/_1$=2_X:+B_]A7VC_/D%"
+M_\;!P?\G)BW_*RHQ_Y.1FO\W.$/_-SH__R8L-O^XJZK_S;F[_[>BEO_$J)K_
+MNYZ2_\&EE_^;BGK_U,C7_RXN0?\A(RO_.34W_XU\=O_:P[?_034V_R<C)?]@
+M7EG_A(5__XB(B_^4CY/_<'%R_TI34_]56EK_AXF,_\;(S_\N13+_3&]7_W6/
+M>O\H/RS_("PK_S$Z,_\W1#G_*#0]_S]"5/_*PL7_Y]C2_SL[1/\\0$__2TE9
+M_T9"2O\N)"?_+2,F_R<>'O\P*BC_8UQ6_][0S?^IF)C_)B,B_R$>'?\G("#_
+M+B4E_RXB(_\Q)"/_1$4__]?(R/_,N[O_*",C_R4@(/\D'Q__)B$A_RXG)_\K
+M*2O_.C\__Q\:'O]O7U;_?V]L_Y&(@O^DGYK_Z-G:_[JNK_\M*BG_(QX>_R0E
+M'O^OJ:'_DX>#_^+5U/\^.3G_(Q\A_R,@)O]$1U+_1$A*_[RLJ?^3 at H+_Y]C8
+M_X-]B_\W2%;_7V)M_YR4F/_:SLG_YM36_S8W0O\N,#?_*"0F_R<C)?\B'B#_
+M(Q\A_R(>(/\B'B#_(1T?_R,?(?\H'1S_1T-%_U%05O_ N<#_ZMGC_UU69_\]
+M0E3_0DE;_WUV@/^UJ;+_Y]WL_U129?]A87#_C(*+_^#3V/\\/T3_CI"._U!.
+M5_]"14;_SLO*_R at I,/\K*C#_B8B._S,T/_\N,#C_+C8Z_\2XN?_FUMK_T<&X
+M_].YK/_7MZ__S+"L_YF-AO_9Q-?_(S% _R4A*?\F*S'_>'AU_YV8DO^0BXO_
+M@'M[_XB!>_]G8%K_7%UD_Y60E/\H*BW_-T-'_SM$1/]F:VO_O\3*_SY(-_\V
+M0C/_+T P_TQC4/\Y5$/_#"D7_SY?3?\S3CW_/%I*_YBMH?_9T<W_2T=/_S0U
+M0/\M*C;_0SY _R8='?\E&Q[_)R @_R<C(?].3TC_T<?#_YR)B?\F'1W_(AT=
+M_R<@(/\L(R/_+B(C_S(E)/][>WC_U\K)_\BWM_\H(R/_)2 @_R<B(O\I)"3_
+M+B8D_ST_/?]=9&3_'QH>_WMP9?]H65G_LJNE_YN9E/_DU=G_MZNL_S,P+_\G
+M(B+_(2(;_ZZIH_^MGYS_Y=C7_S,N+O\E(2/_)" H_SD\1_\Y/C[_P*VM_Z>6
+MEO_NW]__8UUK_SA)5O]#1T__JZ"E_^'4S__FT=;_/3U*_R B*?\H(R7_)B(D
+M_R4A(_\B'B#_(AX at _R(>(/\B'B#_(AX at _R,;%_]14$__/$5,_XB*D?^+B8O_
+M24]1_SM'3/] 2%+_>'I__T9'3O\H+CC_'"4S_TQ55?]Y>GO_Q\')_SD^2O^+
+MB8O_3TM4_T)%1O_)QL7_+S W_RDI+/^8F9K_/#Y&_S<X0_\O-SO_OK*S_^+3
+MV/]W<FS_R;ZW_]_2S?^9CXO_FI6/_]['VO\U2%3_)B H_SI"3/\N,SC_:&EJ
+M_T(]0?\U-#O_4DQ*_[6IHO]=6%C_D(2'_SHU._\A*"[_0T5(_ZFDI/_$P]#_
+M'AP9_R,;'_\7&QG_'R47_SY#-_\Y0C7_+3HM_R,N&_\B0BW_:8^ _\;%Q/])
+M1$K_0#Y'_S4O-_] .3G_+B(C_R4;'O\K)"3_)2$?_R D'/_(P[[_ at W!P_S(D
+M)?\D'1W_)R @_S,J*O\M(2+_,",B_X>'A/_:S<S_OZZN_RDD)/\D'Q__+2 at H
+M_S K*_\V+BS_96=E_U]F9O\C'B+_=FQA_VI=7/^,BH/_C(^)_^?8W/^PI*7_
+M+RPK_R8A(?\K*B/_K::@_\BZM__KX-__,2XM_R,?(?\;%Q__,#,^_SQ#0_^_
+MKJ[_O["P__+EY/]N:';_259A_U977O^RIJG_X=7._^?2U_\_/TS_("(I_R4@
+M(O\C'R'_(Q\A_R <'O\@'![_(1T?_R(>(/\>&AS_*R,A_TE+3O]&4EO_6F5L
+M_T1/6O\Y0T[_*C$__S(Q3O\P)V/_-"IO_S\V?/];49K_&!5)_V5?B_]!/5W_
+M.4%+_Y64D_]85%W_3$]0_]G6U?\P,C?_,#$R_TE+2?\P,CG_,3(]_R<O,__#
+MM[C_Y-7:_WYQ;/_ JZG_W,G)_X9R;O]W;F?_U+W0_Q0G,_\E'R?_-T!._SD_
+M1_\A(R;_,"PT_R$D+_],2$K_>&IA_W9K9/^2 at 8'_1CU$_R,D*_\^/#__MJNJ
+M_]W.YO\G*S/_.TE8_R<K,_\V-C/_0D ]_S\[.?\;$Q'_+"TG_RTS+_]985W_
+MU=+1_S at Y0/\M,#S_.C=$_VED:/\L(B7_+B0G_R8?'_\F(B#_/3PU_]?+Q_]L
+M6UO_)A\?_R$>'?\G("#_+R8F_RTA(O\U*"?_CHZ+_][1T/^SHJ+_*20D_R0?
+M'_\H(R/_*B4E_S at P+O]E9V7_8FEI_R(=(?^9C('_P[*R_X-\=O]I9V+_Y=;:
+M_ZVAHO\I)B7_)2 @_S at S+?^]M*[_U,C$_^3<VO\X-33_)" B_R <)/\R-4#_
+M/D5%_\*SL__,O[[_[^3C_W%J=O]'4US_7EUC_[FKK/_IVM3_Y=#5_T5%4O\8
+M&B'_)!\A_R8B)/\C'R'_(!P>_R <'O\A'1__(AX at _QX:'/\U)RC_2T9,_U5@
+M:_]16V7_1TU=_R at H-_]@76__<FZ4_R,B.?\0$!__#0T:_PH)%O\;&3K_+"=1
+M_SDT5O\?(2C_IZ6B_UE57O]"14;_UM/2_RLM,/\X.CC_-3<T_S(U.O\P,3S_
+M*# T_\:ZN__GV-W_E7]V_\FPJ__ES,O_GH9W_WMQ9__7P-/_(#,__R$;(_\O
+M-3__8F9H_R4G)?\Q+"[_(2 G_TY&1/^(>6S_B'UV_Y&"@_]+1$O_(R4L_S4U
+M./^AG)S_S+S8_RDJ,?\4'R;_&QTD_R(B+?\E*C;_/$1._Q,:(/\E)"K_*RHP
+M_SDV//\?&!C_/3E"_SL[2O]*2EG_4U!6_RLC(?\X+"W_*AXA_RLD'O^7BX+_
+MV,S%_UE.3?\J)BC_(!L=_RHC(_\J(R/_*"$A_S F(O^)BH3_WM'0_Z22E/\H
+M("/_)Q\B_RHC(_\K)2/_+RDG_VUN;_]@96K_)B$C_Z21A?_ K:7_Q[NT_\6Y
+ML/_(N[;_JJ.C_R at E*_\E(R;_1C at U_[>PJO_?T-#_ZMO<_S0Q,/\D("+_'AHB
+M_S<Z1?]&3E+_9EYA_]/'RO][>7O_>GU^_W5[??]H96O_KJ.H__/AWO_8S=3_
+M24Y:_QD:(?\H(B#_)A\?_R8A(?\A'1__'!P?_R >(?\A'R'_'AL:_T8W-_]!
+M.T/_1T]?_U9;9_],3E7_#0,,_RL4'_\R(2?_%0H7_R$4'_\G%Q__&0T6_R$:
+M(O\8"QC_)A at G_R :(O^6BHO_1$)+_T=(2?_1T,__+"XQ_TQ.3/\9'!W_("4J
+M_SQ!1_\I+C/_2$-'_][6V?^)>&O_P:NB_^G3R_^8A';_?W1I_]>[S_\<+CC_
+M+"4L_R8Q//^1D(__*28E_S8P-/\I(RO_1S\[_YN+>_^1AG__D8.$_TE$2O\B
+M)3#_(R,F_ZZLKO_:P^#_)1PC_Q at 1&/\A$!K_(1HA_QL;)/\B*##_+3 [_R4D
+M*O\N+33_55%9_];,S_]".T7_.SM*_U-38/]33E3_,"@F_R$5&/\L("'_3D4_
+M_[^SK/_<S\K_1CX\_R at B)O\C&Q[_*2(B_R4>'O\I(B+_,RDE_XF*A/_>T=#_
+MH(Z0_R@@(_\G'R+_*"$A_RPF)/\P+"K_7U]B_UUB9_\E("+_L**9_V584_^F
+MGIS_IIR8_\.WL/^>EI3_*",E_RHB)?]72$C_E)*/_][2U?_BT]C_+RXM_R0@
+M(O\B'B;_-SI%_SU 0?^\M++_VLO+_^+>W/]56E3_-3,U_V!98/^CF)W_[=?8
+M_\[%S/\\04W_'!LB_V):6/]53TW_&A45_R,?(?\A'R'_'!H<_Q\='_\?'1__
+M6$U,_TA)4/]&4V3_04A6_R<=,/\]*RW_JY*!_W9:5_]:/3S_F'5N_X5A5_^$
+M8E__*Q at 2_Y:!?_^GD9/_% 8#_S<I)O]"1$S_24I+_]72T?\<'B'_+"TN_S]"
+M1_\P-3O_+#$W_R0G+/\<&AW_'!<9_XAV;/_!JZ+_ZM3,_Y6 =/]W;V7_U;W2
+M_Q at J./\L)2__(S ]_Z2 at GO\L*"K_/#<]_R\H,O] .#;_H)2%_X)Y<_^)?7[_
+M7UMC_R8I-?\[.D#_O+>]_\;!V?\R-3K_'" H_Q,2'_\;%QG_$Q,6_Q87'O\<
+M%R/_'!<=_Q(.%O\J)"S_T,3'_U-,5O] 0$__04%._U!+4?\L(B7_*Q\B_TQ!
+M0/\W+"O_6$U,_Y>/C?\T+2W_)!\A_R8?'_\K)"3_*R0D_R at A(?\R*"3_B8J$
+M_^'4T_^+>7O_(QL>_R4=(/\K)"3_+2<E_RTI)_]@8&/_4UA=_R<B)/^;D8W_
+M)!T=_QH7'?\C'B+_F(R'_Z:;FO]74%#_+" <_[ZRKO^!@X'_KZ6H_]K/U/\R
+M,#+_)2$C_Q\;(_\V.43_/C\Y_\F_N__BT]3_X];1_U%/1_\\.#;_S,'&_^?8
+MW/_UW]W_S,/*_S@]2?\;&B'_,BHH_S<Q+_]"/3W_&147_R$:&O\E'A[_(!P>
+M_R =(_]Z<G#_/#Y%_T=79_\[15/_.4)"_QL6,O]I5H3_%0P=_Q,4&_\2#A;_
+M%A 8_Q01'O\7%AW_"@86_S$K0?\9%1[_)1P<_S]#2_])1TG_UM'1_R ?)?\N
+M+3/_,3,Z_RXR.O\P-3O_)2 at M_S N,?\A'![_BWMR_\&MI?_IU-#_F(5[_W%M
+M9?_+MLS_%RDW_R8>*/\?)37_Q[^]_RTH*O]$/T7_+2DQ_S at Q,?^?E8O_A81]
+M_XV*B?]F9F__*BT^_T5!2?_$O<?_U<GB_T=+3?\G,SS_%!XM_S P/?\>'RK_
+M&ALF_R0=)_\8$1C_&1,;_RXG+__DU=G_1T!*_ST]3/\V-D/_3TI0_RH>)_\I
+M'"'_+2,?_R\C)/\:%!C_(AP at _R(='_\J(B7_)R @_RDB(O\K)"3_*2(B_S0J
+M)O]E9F#_X-/2_X%O<?\E'2#_)1T at _RPE)?\J)"+_*R<E_U]?8O]97F/_'!<9
+M_\B\N/\E'A[_(R F_R(<(/\5#@[_&108_VAC9_\H'AK_KZ":_\&_M__$N+/_
+MP+*O_S4T,_\C'R'_&Q<?_S<Z1?]-4$K_R</'_^37XO_FU]C_95]5_VA at 7/_C
+MU-C_\M_?__/=V__%O,/_/$%-_R4D*_\^-C3_65-1_VQG9_\A'1__<6=C_RL@
+M'_\E'R/_'ATD_Y.'B/\Q,#?_04Q=_SD]3/\\2$W_!@LG_V9CF/\Y-F;_&! L
+M_QL,'O\>$!G_'Q8=_QL9,_]75X#_4E)Y_P\/'O\E("#_+C0\_T-!0__;TM+_
+M*BDP_RXM-/\V.$#_*RXY_R8J,O\A)"G_*RDL_SHU-_^_L*K_UL.]_^W8UO^>
+MBX/_A8!T_]C S_] 3E?_+ATC_W9VA?_6Q\?_.# S_V]L<O\U-#O_-3 R_[NS
+MK_^0EY#_041%_UI=:/\S.$K_+RLT_Z2=J?_4Q-C_13Y&_R,@)O\A'RC_-S="
+M_SDZ1?]35%__)B8O_R at H,_\?'RC_2$!#_][/S_]#/TC_0T-2_SPY1O] .T'_
+M)!P?_RD@(/\R*2G_,RHJ_QD3%_\:%1O_'AD?_QT8'/\;$Q;_(!D9_R4>'O\H
+M(2'_,"@D_Y&(@O_7R,/_:EY:_R<B)/\A&Q__*" C_S$H*/\D(A__7F-C_V)F
+M:/^*A87_4$A&_R ='/\?'1__(QP<_R4=(?\A&Q__)B D_RHB)?]/24?_D8Z)
+M_YR7D?^TL*C_-C$Q_S K+_]_?H7_-#A _V1F9/^[MKK_W-;>_]34T?^]P[__
+MJ[&S_]31U__LV]O_\MS4_[FUM_\_4%;_%20D_W=X>?^ZK:C_75-6_QX<'_\=
+M'!O_D(J(_T4Y-?\C'B+_I9F4_X)Y>?\O,3G_,C0\_RTU1?\Z15;_" \C_R4=
+M./]J9)[_44Z0_S at X<?\8&TK_&A(M_R\I/_\4$23_%Q<B_Q at 3%_\;&![_(2$D
+M_ZBHJ_\K+C/_+"XS_S8Y/O\L+C7_(R at N_QXA)O\E)RK_,S$S_\"VK/^RGY?_
+MWL;#_Y.!=_^%=&[_K9N?_VQJ;/^">W7_Y-?6_^/.S/^PGY__N[*R_R<E*/\O
+M*B[_-#$P_R F*/]?9F;_+#0^_S(W2?\P,#O_T\O5_^'4YO\R*C3_)2 D_Q82
+M&O\9&!__'QXE_QT<(_\@'R;_'AXK_R<H+_]E7E[_W]#1_S<U/O\P,#__1#Y,
+M_T([0O\M)B;_)1X>_R4>'O\B&QO_,"HN_QD4&/\5$!3_%Q(6_QH2%?\B&QO_
+M*R0D_RLD)/\V,3'_)1T at _WYR=?]A65S_)!\C_R$<(/\K(R;_+R8F_R<F)?]=
+M85__?(!^_YJ3D_\O)2C_'QL=_QD:&_\?&AS_(!H>_R(<(/\?&1W_(QTA_Q at 3
+M%_\<%QO_'1H9_U123_^/BHS_3TI._Q\>)?\]04G_5UQ8_\#"Q?_3T>'_O+?)
+M_R,<+?])0U'_U<[8_^K=W/_JUMC_IYRI_TI"5O\\(S3_=VYU_\.TKO]+0$7_
+M(1XD_VQK:O\P*R;_FXZ-_RDC)_^XK:;_*!X:_VEH;_]$1DW_&Q\G_S= 3O]&
+M3V#_/T)._Q -&O\) !+_(A<N_PX'&?\I)##_&QLD_S$T0/\H+SW_)"8M_QD9
+M'/])24S_%!07_QL=(O\I+#'_+S(W_RXQ-O\D*2__(R8K_R8H*_\]/C__OK2I
+M_[.?E__FS\K_DX%W_XY[<__!LJW_:5];_UY22?_NW]K_Y-/3_]?(R?]%0$3_
+M.3H[_R,A'O]A7UK_*S N_RDM*_]'25'_-#1'_S0O.__2QL__V,O=_RXF,/\Q
+M+##_'QLC_QL7'_\B'R7_'1H at _S M,_\Q,3K_%Q0:_S<P,/_CU-G_.SA$_S\_
+M3O\^.$;_,RPS_R8?'_\G("#_+28F_R8?'_\V+C'_,BHM_S8N,?\B&AW_'A<7
+M_RHC(_\I(B+_*2(B_R4@)/\>&R'_'!D?_QT:(/\H(RG_*R8J_RLC)O\M)"3_
+M)",B_V=E8/]F85O_*!T<_[*GKO]S;77_)B<N_QT<(_\B'2'_(!L?_QX9'?\A
+M'"#_(QXD_R(=(_\?&B#_&A0<_R4?(_\A'"#_)B4L_RLO-_^BF9G_IZFL_WR9
+MI?]<AY__0#M5_VE3:/^OGJG_:%YA_]S/SO^-CI7_.TM5_S="0_^.CY#_U<; 
+M_SXS./\G)"K_F).._Y^4D_^6BHW_'AD;_\:ZL_\Z,"S_O[[%_T%#2O]>7%[_
+M-#8]_SQ'4O\\2U'_'RD?_T5(0O^5E)O_*2\Y_UQ?9/\;("7_+C9 _Q at B,/\]
+M1DS_-#H\_T!"1?\9%QK_%QD>_RTP-?\I+#'_+C$V_R$F+/\B)2K_+C S_SDZ
+M._^^M*G_K9F1_^++QO^,>G#_F(A^_\"TK?]_<VS_J)6)_^?7U/_.OL+_13H_
+M_R\R-_]!1D;_0T$\_XV-@/]E9U[_*BDH_RTM./]W=(;_1C]'_[NQM/_>T>/_
+M*" J_R ;'_\A'27_(ATC_QL6&O\?&A[_*",G_QL8'O\9%1?_I9Z>_]K/UO]#
+M0T[_/#Q+_T Z2/\Q*C'_)R @_R,<'/\K)"3_)A\?_RPC(_\U+"S_."\O_S G
+M)_\R*RO_*R0D_R<@(/\K)"3_*R,G_Q40%/\5%1C_&Q49_QP5'/\<%QO_(!@;
+M_RLB(O\C(2/_<FUG_T<]+_^ADY#_TL70_V);9_\9&B7_'B$L_S,R./\E(R;_
+M(!XA_QX<'_\C(!__(1X=_R$<(/\A'"+_)A\F_QX9'?\<&R+_+S,[_YJ1F/^<
+MH:'_-D]._T5?:/\Z-T3_DX.+_[FJKO]A6F'_Y-WG_WZ!DO]!25W_+BHR_YN6
+MFO_/P+K_-RPQ_RLH+O^VJ:3_O:ZO_WUR>?\H(R/_Q;FP_YN1C?_(Q\[_3$Y5
+M_Q84%O]_ at 8C_0TU;_SI&5?\=+"C_3$Y3_X^*G/\H,D;_'R,E_TI+3/\>("C_
+M*"L\_SL]1/\T.#K_0DA*_SM!0_\N,3;_+C$V_RDL,?\J+3+_)BLQ_R at K,/\T
+M-CG_)"4F_\*XK?^WHYO_X,G$_XMY;_^@C87_NZNH_V-;6?]32T'_YM30_^+-
+MR_^6BXK_-3HZ_S,X/?\A'AW_D(J"_WMY<?\F)BG_)2 at T_RLN/_]34EC_A86"
+M_^'/X_\Q+##_(B,J_S(N-O\E("+_% \3_QX9'?\Q+##_0S]'_R at J+__,O\3_
+MV<C2_UA6:?]&25O_0T-._RDA)?\J'Q[_-"DH_RXC(O\K(!__,"@D_RPG(O\T
+M+RK_*",>_S(J)O\R)R;_+R0C_RXC(O\I(B+_*B4E_QP7%_\7$A+_'1@:_QT8
+M&O\=&!C_*R8F_QT6'?^%>G/_=FE<_T<X0_\R*3K_)1XH_QX:(_\:&2;_&1HE
+M_Q at 8(?\I*3+_,3$Z_RLL+?\C(B'_(1\A_Q\='_\?'2#_'!H=_Q<5&/\U-#K_
+M%Q0:_Q45&/\?("'_+RDM_R,D)?]32D3_A79P_VUT>O]7D:?_2(BG_S!PC_\Z
+M9HC_*C!&_W!:6_\W(B?_)"$G_[:OJ?_0N;K_8519_R\M+__-P;C_:FMV_]K1
+MT?]!2UK_4$Y1_\"^P/]&4%__/DI9_Q<C(O]&1$'_A(*2_R0M/O\L-37_)2(=
+M_TM*5_\L-4/_.3Q!_SH^0/]%24O_,SD[_S<\0?\Q,S;_$1,6_S$V//\D)S+_
+M(R8K_QL@(/\P,S3_LZZN_]7.SO_9S]+_U]#0_^#0U/_DTM;_P;"V_[*CI__O
+MU=C_WM/8_VMF:/]T;VG_+"XK_R<F)?^!?WK_:VED_T9%2_\I*SK_&ATN_S$U
+M-_]%1D?_XM'I_S0S.O]57&C_(!\L_QP;(O\B("G_(1\H_R$?*/\R+C?_&QXC
+M_]#!Q?_9R-+_7%ML_TQ/8/\_/TC_*R,F_RL@'_\L)"+_*2$?_RLC(?\L)B3_
+M+RDG_RDC(?\F(![_)!P:_RTE(_\N)B3_+24C_R\H*/\T+R__(QX>_RTH*/\U
+M,##_'AD9_RTH*/\D'Q__)"(D_XM^>?]%-SC_)C15_Q(>._\8&2K_%A,?_Q85
+M(O\>'2K_&AHE_QX>*?\8&"/_%!,:_S(Q./\?'B7_(!\F_QX<'_\>'!__'!H=
+M_R<E*/\I)RK_$Q$4_R$?(O\F)"?_'!LA_V)64O_#LJS_8VEK_QXY.O\*)"?_
+M'D=,_V2%D?]:?8K_HZZI_S8Q,_\M*"[_MKJR_\RZO/]'/$'_*2<I_\J^M?]$
+M2EK_U<K)_SA%5O^+B8S_R,/#_T),6_\W0U+_*C8U_TQ*1?^#A93_)"Y"_R8R
+M,?]!/SC_3TY;_QLE,_\P-#;_*BXP_R\S-?\G*RW_*2XT_R\Q-/\K+3#_+3$Y
+M_RHP.O\A)"G_)"@F_S4U./_(NKO_QK2V_\&OL?^]JZW_K9^@_Z&5EO^AE9;_
+MF8V._Y-X?O]*14G_-C0V_U-.2/]N;FO_&AD8_R8E)/]B86#_6%=>_R at I.O\D
+M)SC_-#@Z_TA&2/_AT^__*RTU_TA17_\N,#__&ATH_R8J.?\=(3#_$!0C_U=0
+M6O]I:V[_OK"Q_\2YP/]E96[_3E!8_T9)3O\J)2?_)1X>_R$:&O\C'!S_(QP<
+M_R at A(?\A&AK_*2(B_RXG)_\Q*BK_)A\?_RHC(_\M)B;_*B4E_R<B(O\M*"C_
+M*R8F_S0O+_\I)"3_)2 @_R$<'/\?(1__3#\^_SPU/_]#9XS_5&R-_PT4*/\7
+M%"#_%Q4>_Q at 5(?\3$!S_&!4A_QT:)O\:%R3_'QPI_QD6(_\@'2K_-#([_RDH
+M+_](1T[_'QXE_QX<'_\3$13_#PT0_PL)#/\7$AC_0C@[_QX4$/\8&A?_%A<0
+M_S8U+O\A.#/_35]C_S]!2/_7R,/_,B<N_QP?)/\X0CC_95E:_S4O,_\X-#;_
+MRKZU_R4K.__/Q,/_-D-4_YF7FO_-R,C_0$I9_SE%5/]J<W/_<W!K_WU_CO\Q
+M0%/_-$ __T=%/O]656+_(BPZ_SY"1/\Y/3__/T-%_SU!0_\\04?_-SD\_SY 
+M0_\P-#S_)RTW_R$D*?\E)R7_HIR at _^;1S__[XMW_^-_:__KAW/_]YN'_^N/>
+M__CAW/_YXMW_]-C:_VUK;?\F)BG_.#4P_Y.2D?\E(R7_(B B_R$?(?]34EG_
+M+B] _R0G./\V.CS_3TU/_^31Y_\I)BS_,#9 _S8S/_\C(RS_$Q0?_Q,4'_\[
+M/$?_*R0L_RXL+O\_-#/_6E)6_UE97/\T-SC_+3(R_R8E)/\B'1__)2 B_R(=
+M'_\E("+_+"0G_R0<'_\I(23_*R,F_RDD)O\C'B#_*",E_R8A(_\F(2'_(1P<
+M_R0?'_\D'Q__&A45_R(='?\G(B+_)!\?_R(:'O\C'!S_(1\B_Q at A,O\0%RG_
+M'AXG_RPI+_\@("G_'ALG_Q81'?\7$A[_%Q(>_Q84'?\9%R#_'1LD_Q\=)O\:
+M&B/_%Q<@_QP<)?\S,SS_5U1:_RHH*_\0#A'_&A@;_V!@7?]X>G?_/#] _Q47
+M&O\>("7_0T!&_QDF)_]96U[_Q;*R__+5T?\W)R__(R,F_XF+ at O_+M[G_-2HO
+M_S$O,?_.PKG_;W6%_\S!P/\[2%G_D(Z1_\K%Q?\T/DW_+SM*_WE^?O_;UM'_
+M;6]^_S)"5?\M.SK_5%)+_U)17O\R/$K_&1T?_Q49&_\R-CC_.CY _SH_1?\]
+M/T+_3$Y1_S T//\E*S7_(20I_VMH9_^[L+7_T\C'_\W#O__4RL;_W-+._^79
+MU?_HVM?_Y=?4_^K<V?_VXM[_7%Y<_VQN<?\D(2#_.SD[_Q\=(/]&1$?_&A@;
+M_UM:8?\>'S#_)"<X_S0X.O^"@(+_Y=OL_S0L-O\M)R__'ALA_RHL,?\C)2S_
+M(1\H_RXI-?\?&B#_'AH<_Q at 3%?\:%AC_)B$C_R4C)O]!0$;_)R,E_Q at 3&?\7
+M%1C_%A<8_Q06&_\0"P__&A08_QD3%_\9$Q?_$@P0_QH4&/\3#1'_&Q49_QL3
+M%_\1"0W_$0L/_Q$,$/\6$1/_'!<9_R,>(/\C'B#_'1@:_R,<%O\<'B/_*",I
+M_QX:(O\='2;_'1TF_QP=*/\L*S+_,C$W_R ?)?\8%QW_&A<=_QH7'?\9%AS_
+M%Q0:_Q<7&O\='"+_)B4L_QT:)O\7%AS_7EYA_S P,_],3$__+BHL_QT@(?\Z
+M0D3_&1L>_Q47'_\<'"7_$Q87_V-?7?_$O;?_ZMK7_RHF*/\G(1__LJ:?_^/+
+MSO\P*"S_,"PN_\.WL_]N=W#_N[6Y_S]27/^0D9+_PL3)_S<]3?\Y057_>H&'
+M_]3,RO]H:'?_/$95_SQ"1/]T;&C_3$M8_RXY1/\1&Q+_(B0I_S at Z/?\5&AK_
+M)BLP_SD\0?])2$__,C8^_S0U0/\@)2K_JZ*B_\:WO/^LFY7_JI2+_ZB3A_^?
+MBWW_EXA[_Y>%>_][:&#_BGQS_^?2S?]C8V#_JZNN_TI%1?](14O_(!L?_X)_
+M?O]I96?_9%]C_UU=;/\C)SW_/#U$_Y60EO_IW.?_&Q$:_R8?)O\@&Q__(ATC
+M_R0?)?\G)"K_+2HP_Q at 3%_\=&1O_%Q,5_Q41$_\7$!#_'!<=_ST\0_\D'B+_
+M0C(Z_S$@)O\A%1;_)AL at _QP3&O\=%QO_34=+_QH4&/\7$17_'!8:_RHD*/\<
+M%AK_'A,8_Q0,$/\<%AK_%Q(6_Q81$_\=&!K_)R(D_Q\:'/\;&1S_'AH8_Q(:
+M*O\6'3'_%Q<B_QL;)O\;&R;_&QLF_QP:(_\=&R3_'APE_RDG,/\N*S'_,"TS
+M_Q<4&O\3$!;_$Q,6_Q(2%?\5%!O_%!(;_R(D*?\^0$/_*BPO_RHL+_\N+C'_
+M5%99_T-%2/\7#Q/_%Q,;_S0S.O\Q+##_2T9&_ZFBG/_KV-C_*B8H_RTJ)?_)
+MO;;_Z]/6_RTE*?\R+2__LZ2I_WR">O^[L;O_0%1B_Y.(C_^^O<K_0E=I_T=R
+MA/]'?8?_M+_&_V!8;/\N0T__;GEZ_][6TO])2%7_+3A#_RPT*O]-3E7_.SU 
+M_R\R,_\G+#'_.3M"_TI(4?\R-4#_*RPW_QLC)_^<D)'_S+W"_\.OI_^^I)?_
+MO:.5_[^FE?_&KIO_Q:N8_\2FEO_$K:#_W\;!_W%P;_^SL[;_44Q._UE36_\F
+M(27_D(Z+_XB$AO]F86/_9F9U_RLN1_\R,CO_J*"C_^W9X_\B&"'_'1PC_QT<
+M(_\I(RO_&!(:_Q at 3%_\?'1__)" B_QX:'/\<&!K_&A88_QX7%_\E(";_/3Q#
+M_R8@)/^CF9S_M*ZL_XF&@?\L*2C_'A@<_Q0.$O^OJ:W_&Q49_W!J;O\H(B;_
+M6U59_S<Q-?^9CI/_9%Q at _X)\@/\3#A+_%1 2_R8A(_\G(B3_'QH<_PX.$?\6
+M$A3_$AXS_R at U4O\2$1[_$@\;_Q01'?\7%"#_&Q at D_QX;)_\?'"C_&A<C_R >
+M)_\?'2;_&A at A_Q(0&?\1$!?_$A$8_Q,2&/\4$QG_(2,F_QX@(_\Z/#__.CP_
+M_Q0:'/\W.3S_4$M/_Y2)CO]K9&O_ at GV#_T) 0_]C86/_I:. at _^G:V_\K)2G_
+M+BXK_\W!O/_RVMW_)AXB_RDD)O^PH*C_P,"]_[JIN?\S3%W_9G5[_V^$D/]N
+MAIG_67B*_W*0IO]OD)S_8HV?_R@\2O^"A(?_V-#,_TY-6O\Y1$__7%Y5_SH[
+M0O\S-SG_<G-T_S S./\\/D7_03](_S(U0/\K+#?_)"XR_[NRLO_-P,7_P*RD
+M_[>=D/^SF8O_PZJ9_\2JE?_-KYK_PZ22_\FPG__ at R<3_='5V_ZFJL?]?6E[_
+M9F)J_R4@)/^5DY#_C(B*_V5 at 8O]U=83_+3!)_S P.?^OJ*C_Y]3D_R,=*_\P
+M.DC_&R R_R$F./\8&RS_%14 at _QL6'/\9%1?_'!@:_R<C)?\U,3/_0SP\_S8Q
+M-_\Q,#?_+B at L_V5=6_]P:6/_3$D^_TY+1O\B'1__&1,7_Q<1%?\4#A+_&!(6
+M_R,=(?\9$Q?_%A 4_Q\4&?\7#Q/_%Q$5_QH5&?\6$1/_)!\A_R0?(?\D'R'_
+M$A 2_QP7$O\,$1W_#Q,B_Q(.%_\8$Q__%A$=_QP7(_\<&B/_%Q8=_Q85'/\9
+M&!__'1TF_QL;)O\;&R;_%14 at _Q(0&?\3$1K_%A4;_RPM+O\N,#/_&1L>_R,E
+M*/\F*"O_("@J_RHN,/\M+3#_*R\Q_RDJ*_\O+S+_'B(D_T-(3?]%2DC_T+_%
+M_R\F+?\H*2K_KJ*=__7=X/\I(27_+"<I_[RPL__2T<K_LZ*M_TIG<O]RAHK_
+M25QD_VYWA?]24E__5%QL_SY*4?]XDJ7_3FAV_WJ @O_;T\__:&=T_S [1O^@
+MGI;_0#]&_SM!0_^^NKS_+"\T_SD[0O]+25+_*RXY_R4H,_\C+S/_ at 7Q\_\>\
+MP?^GDXO_O:.6_["6B/_!J)?_R+&?_\VRH?_!I9?_R;*F_]O'P_]:7%__KK"X
+M_UA56_]U<7G_)R(F_YN9EO^/BXW_75A:_VMK>O\I+$7_-#0]_VA=8O_8T-[_
+M$Q8G_SE'7/\1'CO_04QE_R at O1?\;'2S_'!PG_R$:(O\M)BW_,"LQ_S,Q-/\T
+M+S/_/T%&_S8X0/\Z.#O_V,G)_\R]M_]Y;F/_>6UH_QH5%_]@6U__44Q0_Q<2
+M%O\B'"#_)1\C_TY(3/]:5%C_@'I^_S J+O\6$!3_-S$U_QD7&?\<&!K_(AT?
+M_Q\='_\4$!+_+BDC_SU%3_\4"AG_$Q$4_Q,0(O\A)"__("$H_QP<)?\7%R#_
+M'!PE_QH:(_\B(BO_&QLD_Q84'?\7$QS_%1(>_Q04(?\5&2'_2$E*_TE+2?\J
+M+2[_'!\@_QH='O\8&A__&!<>_QH6'O\>'R;_)B4K_S at Z/?\<(2'_.CL\_[RY
+MM/_GU=G_)B H_RXR,/_"MK'_]=W at _RHB)O\O*BK_LZRL_]C+RO^BG:'_5VMO
+M_YNBKO^7F:'_)R8L_QX=(_\B)B[_969M_[&VPO]&76G_ at HN1_]O5T_]#1E+_
+M.D12_[.NJ?]#14S_.SX__[Z\O_\Q-CS_.SU%_T ^1_\G*S/_+C X_R4M+_^!
+M>7?_NZ^R_]S*QO_>R\7_WLW'_]W)P?_BR<+_T+NV_]C$P/_1NK7_W\G+_U-6
+M6_^EJ*W_5U)8_XJ&CO\E("3_HI^>_YN6FO]E8&3_<&Y^_R<H0?\S-3W_;G-Y
+M_^?:V?\^.#;_-C4T_SDW.?\]/T?_'B$L_QL:(/\C'R'_,BLK_S4P,O\[-SG_
+M.SHY_S,S-O\M+3;_-SE!_RHH*_]J75S_6D](_W9N9/^&?WG_'AD;_Q at 3%_\=
+M&!S_'1@<_QL5&?]<5EK_'A@<_QH4&/\>&!S_)R$E_R8@)/\B'"#_%0X._YZ1
+MD/\S)"3_)!D8_R<9&O].1T'_.$-._QH3)/\4%1;_%Q0G_RDL-_\Q,S;_)"0O
+M_QT=*/\A(2S_'!PG_Q06'O\0$!G_$Q$:_Q,/&/\6$R#_%QHE_R at M,_\\.CW_
+M/STZ_ST[-O\].S;_/STX_S$O,?\>'!__&A@;_QP:'?\<&AW_%Q<:_Q@;'/^+
+MAX7_T,C$_^G7V_\I)BS_-3,N_]3'PO_OU]S_+B8J_S$L+/^VL;'_Z=G=_YB8
+MF_]89FG_G*2N_Q,6&_].3DO_>WUZ_U=86?\K+3#_*3,W_SA'3/^#B(W_V]73
+M_T!$4_\Y0U'_BX:!_SY#2?]&24K_R\G,_S$X/O]"14K_/CU$_RDL-_\U-S__
+M*# R_\&VM?^^K[/_T]'._T-#0/]!1T/_6EI7_\S*Q_]/44[_6%U9_UM=6O_0
+MO\7_2DU2_[2WO/]J96O_G):>_R8A)?^FHZ+_G9B>_VIE:?]U<8'_*2I#_S(T
+M//^)A(C_XMCA_R at C)_\>(![_,S$L_S<S,?]!/3O_3TI%_U502O]&03O_03XY
+M_T9$0?\\.CS_*BDP_S(S/O\X-C__,BLK_]7(Q_^HGYG_=G!H_VED7_\=&!K_
+M(!L?_Q(-$?]P:V__'1<;_T$[/_\;%1G_65-7_Q80%/\E'R/_:6-G_QT7&_\=
+M'AC_96-<_Y")@_^;FI/_C7MX_Z:<F/\_4%[_%1,C_QD;'O\@'C'_&1DB_R4C
+M(/\M*S3_+2TX_RLK-O\E)3#_("$L_R8G,O\4%!__$Q <_Q at 7*/\<'2C_6UU@
+M_R,B*/\D(A__-C,N_T9#/O]"/SK_/CPY_QX>&_\_/SS_0T- _R0B)/\?(1__
+M/T1 _V=D7__-R,/_ZMO at _R<G*O\]-2O_U\; __/;X/\G'R/_-"\O_[BUM/_A
+MU=C_EY>:_TM56?\6&!__)R at I_VUL9?]+3T?_8F-<_RHK)?]?9&#_45E6_XJ.
+MD/_AV]G_/T-2_SQ&5/^ZM;#_049,_T!#1/_+R<S_.$%!_T%&1O]*25#_,30_
+M_R at J,O\D+"[_P[BW_[ZOL__/QL;_0S\]_SLY-O].2$;_V-#3_T='1/]04TW_
+M249%_]/"RO]15%G_MKF^_VED:O^DGJ;_)B$E_VIG9O^AG*+_<6QP_W=S at _\L
+M+4;_+C X_V%@7__MV^G_(A at B_P\0%_\0$A?_&A47_QD4%O\5$!+_&106_R :
+M&/\R+BS_2D5)_SLW/_]+2%3_24E6_SDU/O^YK*O_:UU>_TM#/_]O:F3_7UM9
+M_Q<2%O]%0$3_HYZB_QD4&/\E'R/_24-'_X1^@O]O:6W_9V%E_V=A9?^ >G[_
+M'A@<_R\J)/^IGY7_CX%X_VMC6?]Q8%K_DHV(_T!39?\A&2?_&1D<_R,A-/\@
+M(2C_9F%;_Q82&O\?'RK_%A8A_QX>*?\G*C;_+3 \_Q04(?\4$R#_%QDN_Q\A
+M*?^'A(/_%A@=_QD8'O\G)2C_,"XQ_QT;'O\>'1S_+2PK_S0S,O]"04#_+BTL
+M_RLM*O]X?7?_H)Z7_XZ(AO_ at U=K_&QP=_VU<3__=R,/_[=7:_S$I+?]!/#S_
+MM;>U_^+8V_^&A(?_,CH^_QT;)/]J9&C_:&5 at _U%64/]I9V+_1$$\_V-?7?\E
+M(B'_B8F,_^/=V_\\0$__/$94_[>RK?]!1DS_/4!!_Z">H?\P.C?_0$9"_TE(
+M3O\V.43_*2HU_R(J+/_$N;C_Q+6Y_]G-R/]-1#W_03LS_U)'0/_DT]/_7%)(
+M_V=D4_]72D7_U<#&_T1'3/^!A(G_=G%W_UA26O]54%3_'1H9_QT8'O]O:F[_
+M<6U]_R at I0O\L+C;_:6QM__G8]_\6$17_(1$5_QT/&/\4$A7_%1 4_Q at 3%_\7
+M$AC_#@D-_S4P-/]&1$?_4$U3_T9'4O]6663_3$=-_\:UK__GTL[_C']^_QL9
+M&_\5&!G_%1,5_Q at 4%O\:%AC_%A(4_Q$+#_\." S_(!H>_QL5&?\4#Q/_(!L?
+M_Q0/$_\>&1W_/SXS_[VTIO_ LJG_O+:N_\>_N_^JFX[_2%MY_U-05O\:'Q__
+M*R9*_QP>(?]85D?_'A at F_Q\=)O\9%QK_%!0=_R4L,O\3%B+_# T4_QH:)_\,
+M&D'_1D91_\"YL_\F*";_'AD=_Q81%?\6%AG_$A46_R4F'_]64T[_(Q\A_R$C
+M(?\D*27_/T1"_Q\C(?]345/_;FQI_XJ)B/\='QW_BWAN_\BTL/_6Q\O_(QTA
+M_UI44O_#O;O_XMK=_X%^A/\H*C'_(!LA_W%E8?]^<VS_.CQ!_Q<2&/]85D[_
+M-#$P_SHX._]M<7/_V=;5_SH_4?\Q.TG_PKJV_T!%2_\Y/CS_R,/#_R<K+?\^
+M0$/_1D=._R at K-O\R-C[_%R(C_\.YM?_&M+;_U\[(_U)#/?]"/C;_4$@^_^S4
+MT?]P853_=G)=_V%;4__5P\?_14A-_SD]1?\V,SG_;VUP_R4A(_\>&AS_(!P>
+M_W5S=O^ ?XS_+"T^_S$S./^PJZ__^-?H_Q@:&/\6$AO_& X7_Q02%/\5$!3_
+M$PX2_Q at 3%_\Y-SK_/SU _TI(2_]%0T;_0$))_T-%3?]'0DC_T+^Y_^W7S_^$
+M=7;_(!@<_QP7&?\7$Q7_&!06_R\K+?],2$K_6U59_TQ&2O\4#A+_(QTA_S$L
+M,/] .S__&A49_Q0/$_^ZKZC_Q;&I_Z")A/^ ;&C_:V-F_[BFF/\S1F3_&!D:
+M_Q(7'/\C)E#_%1@=_UQ82?\:&"O_'1TH_QH8&O\6&"#_(RPR_Q86)?\4%A[_
+M&!PQ_R(Z:_^4EZC_I)N;_T,^0O\<%AK_03Q _QH8&O\;'1K_2DA _Z&>F?\:
+M%AC_+"LJ_T! /?\R+R[_$P\1_QH5&?\>&QK_*"PJ_VEI9O]B4DG_MZJE_\*Z
+MOO\E("3_9U]=_Y^7D__BWMS_<7-Q_TM/4?\V.#W_7UI5_V)64?]/35#_6%)6
+M_TU-0O]+2DG_&1P=_W5^?O_=V=O_/$!5_RHT0_^_M[/_1$E/_S@].__/R\G_
+M*2LR_ST^1?] 0$G_*RXY_R8L-/\9)"7_P;:U_\*RMO_CU,[_=5U4_U!&._];
+M44/_Z]3/_W]L8/^+ at G'_9F!8_]3"QO]!0TK_.CY&_T5$2O]^?'[_(Q\A_Q\;
+M'?\B'B#_:6=J_Q at 8(_\5%R;_3$Q/_[*ML?__[>#_+!\._Q\<(O\=&B#_(1X=
+M_QX9'?\9%!C_&108_Q84%_\@'B'_+RTP_S<U./\Y.T#_/T!'_U915__&N;3_
+M[MO3_XI\>?]%-CK_*1<9_Q8/#_\3#Q'_&!06_UQ86O]K96G_75=;_TA"1O];
+M55G_55!4_Q40%/\>&1W_$@T1_XV'A?^MI:/_O;BS_[BPK/^EI*O_PK&D_U)B
+M?/\C(!__$QDC_T9;B_\9&R/_7E-(_Q,8,?\:'"O_$A(5_Q8=*_\J,SK_%1<L
+M_PX5*?\0&SW_(T%Y_Z.IO_^*@H;_*2$K_Q43%O]F963_(B(?_S,T+O^.A7__
+MHIR:_Q<5%_\J)R+_B(!\_XR%A?\?&AS_&1<:_Q84%O\4%!?_&!44_S$F'_]E
+M75G_6%-7_S0R-?^(@'[_55%/_X""?_^&B(7_-SPX_Q@;(/]C8V;_;FEI_["L
+MKO^]NKG_=W=N_SL^0_\X0T3_?(B%_]S8VO\Y/5+_,3M*_[ZVLO\S.#[_/D-!
+M_\_+R?\R-#O_0D-*_S<W0/\M,#O_)2 at S_R,M,?^\L[/_MJNP_^#3QO^(;F#_
+M4DD[_V)83?_QW-?_CWIN_YR/?O]I8UO_U,3(_S at Z0?\X/$3_/CU#_Y".D/\@
+M'![_7EI<_S0P,O]M:V[_)B8Q_R$C,O\S,S;_KZJP___NUO_'FW/_/AX$_QP5
+M%?\9%!C_%1 4_Q<2%O\6$17_$Q$4_Q84%_\5$Q;_%1,6_Q02%/\4$QG_&108
+M_[ZRKO_HU<W_:EU8_R4<'/]*0#S_2D5%_QD5%_\6$A3_&A88_U%+3_\U+S/_
+M)B D_SDS-_\6$17_%Q(6_QD4&/\:%1G_&QD<_Q49&_\Z1$'_4590_S(W0__L
+MV\[_-4-8_R<C(?\0%B;_-%J-_QL;*O]30#C_'2E&_QD<+O\:&AW_%1TQ_QLE
+M,/\=(#G_$!PY_R,W9/\@/7?_K;'&_Y*-C_\M+S3_%AD:_W!R;_\T-2__2$8_
+M_\N[N/^OI:C_*2LI_T [-?^[LZ__B82$_WU^?_\I+2__&Q\A_QX;(?\G(B3_
+M2$,]_QD:%/\1$13_*2<J_X9^?/\O+3#_$Q8;_Q 3%/\J+BS_9V9E_S Q,O\=
+M("7_.3Y$_S4S-O\M+"O_0$-5_S%!2O^"D(__W=G;_S T2?\V0$__O[>S_S4Z
+M0/\\03__S<G'_R\Q./\V-S[_/CY'_R<J-?\E)3+_&2(H_X>"A/^UKK7_WM/(
+M_X9Q9?]34D?_+2PE_]_0R_^.>6W_J9B(_VAD7/_2PL;_/T%(_S8Z0O]#0DC_
+MF):8_R(>(/^5D9/_EY.5_VIH:_\E)3#_(2,R_S0T-_^MJ*[___+I_]FC:O_ 
+MEVW_?5PX_QT;%O\1#AO_%!$>_QD1)?\T+D+_$ T9_Q84%_\8$QG_% T5_Q(/
+M%?\K*"?_Q;NW__#6S?^KHIO_:V5C_R,9%?\E("3_&10:_Q,.$/\<%Q?_$@T-
+M_R(='_\?&!__(QPD_RH?'O\T)"'_.",A_RX<&?\G&1K_(AT?_QTB(/]U>7?_
+M0T5#_];1T_]::WO_&B8J_Q89)/\F3H;_&A\K_W)B4O\=-%[_<W-\_U953O\B
+M,$?_7&)L_RDP1O\+'TS_(CQ[_R at Z=/^XM<?_76-?_S<X.?\4$A7_='9M_U)0
+M3?]G7UO_T<*\_[JOKO]*2$K_B(6$_XB#A_]*3%'_+#$V_RTP-?\E*2O_*2LN
+M_R$C)O\3%A?_&QT;_Q\='_\?&QW_BX2$_S,S-O\Q-#G_*R\Q_Q at 3%_\4$@__
+M(!L?_QPF,/\@+#/_O;>[_^C;VO]\?8[_/$Q6_W%X?O_?VM[_-SU-_S8]2__'
+MN[?_049,_SD_.__8TM#_,C,Z_S(U.O\K+S'_*RTT_RHJ,_\;'2+_O+2X_X1X
+M>__CSLG_D7UU_SXU+_]&1#__\N'4_Y^'>/^LFHS_ at W=N_]_0U/]!0$?_769M
+M_T!#2/^;F9O_&147_YJ6F/^GHZ7_<&MO_R(B,?\E*#K_+R\X_ZZFJO_\\.O_
+MW:=M_\J@<O_&EUW_KI!Z_SDB,_\>%S7_*R1"_R at A,_\<%QW_'QH:_R 9&?\:
+M$QK_'1@<_RDE(__.PKW_\]S7_S\].O\Y-SG_85I:_S8X-?\<'!G_)R4B_R\J
+M*O^8C(7_II:-_].]M/_OT\O_Y<_&__#8S__MT<G_[-;-__+6T__BR<C_LJ"=
+M_[BFH_]&.C;_UL[8_S1'6?\T3ES_.SY)_SA6 at O\?'R+_L9I]_R4[8O]#14S_
+M.C\__QPQ5/\6(#3_(#)._Q<X;?\G3(W_+$!Z_[NYR?^"BH;_)" B_Q at 3%_]W
+M>F[_=G1Q_[6KI__7Q[[_OK&P_V!;7_]234__L*JN_XB*C_\A)BO_'!\D_QD=
+M'_\M,3/_,C8X_R<K+?\E)B?_'AP>_Q\;'?^9E);_.#<]_T9+4?\O-#K_%Q,;
+M_R D(O\A'B3_(2X[_S! 4/\Y.T/_J:*B_Z"BL?]-5V;_>WM^_^;@WO^2F:?_
+M-C]-_\.XM_\X/4/_.3X\_\S(QO\W.4'_.C]$_QHA(?\P-3O_$QH at _QXC*/\L
+M*BW_*2$D_^?3S__MV-/_Z]G5__+DX?_ZY-S_]MW6__'<U__>S,C_Z=?9_TE#
+M2_]\A8S_F)N at _Z6CI?]*1DC_I*"B_Z*>H/]Y<W?_)R<T_R,H.O\L+#?_K:6H
+M__WPZ__AJW'_SJ-S_]VC7O_:IVO_K85K_R@;%O\8$Q?_$ D5_Q at 3&?\V,R[_
+M.30O_S$I)_\;%Q7_,"LF_\N]NO_MV]C_.3X^_QPA)_\@'R7_,3<O_T=+0O\S
+M-"[_'!D8_RDE)_\G("#_C7]\_]C#OO_NV,__]]W4__O?U__SW=3_^-[5__3>
+MU?_RXMC_]>+8_^'/R__8Q<O_/$14_RU!5?\[15K_)T%L_Q<@+O^?DX3_(#%5
+M_UM=9/\7'B3_&S-:_R,P2?\2+$W_)U:-_RQ9F?\Q38;_OK[-_ZZPK?] .#O_
+M&108_X&$>/^ ?GO_QKRX_]7&P?^ZKK'_ at 7E]_\:]O?_)O;[_1$!"_P\5%_\8
+M&B'_(R<I_Q,7&?\4&!K_&!P>_Q$4%?\>'R#_,2\Q_SDU-_\V,3?_.#E _S<Y
+M0/\<&R+_)B\O_R(A)_\=*C?_+3Y6_S$^4?\E*B__'B at W_T5/9/^6E9O_KJFD
+M_W=^BO\P.DC_LJVM_SD_2?]!0D/_T<W/_S T//\U/4'_&R0D_RPS.?\@+3+_
+M,3U!_Q@>(/\5%A?_W]#+__+=V/_UV]C_^=S;__?;W?_VW=[_\-G:_^_:V/_O
+MV=?_FHZ1_X2&C?^HJ[#_H)N?_V9A9?^LIZO_IJ&E_W-N</\1$AW_("8V_RXN
+M-_^AG9____7K_]FE;/_-IGS_VJ1A_\JA8/_%E5[_O91C_Q\- /\@&#K_,"I&
+M_RHI,/\\/#G_3TI%_SDT+O\]-3'_U,3!_^W9U?\V.SG_(R at M_R0D)_\M,C+_
+M%AH8_S$S,?\_/CW_+3(R_R(F*/\G*2S_'1@>_VQF9/_$M[+_[M;3__'7U/_V
+MW=C_\][9__'>V/_XW]K_[MO3__G<V/_BT]/_4DI._QT;)/\L-TC_'"(L_VMB
+M6_\@+$G_*20D_R<I)O\S/5+_)R<T_Q at M1O\]:)S_,UB9_RU+ at __$QM7_GIZ;
+M_QT5&/\9%QK_ at H5Y_X>%@O_)O[O_ULC%_[ROM/]J8&/_T<7!_\R]N/]M9V7_
+M)B at K_R(G+?\V.3[_)BHL_TI.4/\[/T'_1TQ,_SL^/_\@(2+_'QT?_];*S?_&
+MO+__&A88_QX:'/\Q-CO_*B0H_Q8>(O\N/TW_,3]8_SE#3?\]4&+_,$1 at _R8S
+M1O\1%Q__.D=8_RXY1/\=&AG_*S \_RPL+_]A863_+#0^_S=!1?\@+"O_+#4[
+M_R0Q-O\K-SO_)BPN_RTK+?_GV-/_[]K5__+=V?_UW]W_^.'B__;@WO_VX=W_
+M^.'<___GX/_FU=7_<G%X_ZVOM/^9E)K_<6QR_["KL?^HHZG_ at GU__UI<9/\?
+M)C3_,#$X_XN,C?__\NG_WZAN_\29;?_=IF;_QYMI_\Z::/_#D%O_OY)I_T ?
+M-_\Q(D'_#104_QT;'?^9B8#_C8%\_TY+0/_6R<3_\=O<_S0W./\@'R7_&A<=
+M_RPP,O\3%1K_(24G_QPC(_\P-3'_1$E#_S(R+_\:&!7_*"<N_QL7'_]N96S_
+MW<[2__3>W/_YW]S_^-S8___ at W/_XW-C_^-[5__??UO_QV-G_\=?4_VY:5O\Q
+M*"+_+2<?_RPH*O\M)![_*B$:_S4P*_\H(AK_'!TH_QU, at O\H1I#_)DV(_[W"
+MR/^6E(W_)!D at _Q@:'_^/B7__AX1__\O"PO_=Q,7_O+6U_\C"P/_1Q+__V<2_
+M_UE,2_\H+"[_(B<G_Q\B(_\7&AO_'R0D_R\V-O\3&!W_$QD;_Q49%_\W,BS_
+MSL&\_\&YM?\Y.S+_>X1W_X^-B/\N(!W_'!02_PT<'/\O0$[_-455_S=+8?\R
+M1V/_+D-?_S%&7O\Q0EG_-#Q&_Q88&_\4%AW_.C<]_QD6'/\7&1[_+S<[_QTI
+M+?\A*C'_(S$T_R,P,?\P,C7_*R4I_^?3S__RV];_[]K5__?BW?_WXM[_^N7A
+M__7 at V__WXMW__>+;_\^YNO]H8FK_J:NP_Y&-E?]^>X'_N+6[_Z>EJ/]M9VO_
+M>G>#_R,D-?\H*3#_*2<I___T[O_7GF3_SJ!S_]:=6__-G6K_RIED_\R;9O_-
+MG&?_MH]>_V _/_\=$"/_'R$?_U902/]J9&C_/T Y_]/'P/_GT]7_.#H]_QT<
+M(_\9%AS_+3$S_S8X._\G+2__*3$S_RTR,O\4&!;_-3<U_T5$0_\N+S#_%!07
+M_QL=(/\J+"__4TY4_\_$R?_KV-C_]-W8__?<U?_WW=+_]MS3__G=VO_PU]+_
+M[]C3_^K5T?^FE)'_>7%T_S,N-/\M+S?_;G1^_VUO<O\>("__&$R%_R$\B?\D
+M3(K_OK_*_WQW=_\C$R'_$!,8_YJ2B/^'@GW_T,;)_]_)R_^;G9O_R<7#_]3$
+MP?_9RL7_.S,V_Q47'O\8&!O_)2,F_QX>(?\A(R;_*2TO_R at J,?].45;_%187
+M_Y&)A__3P,#_T+V]_Z28E/],0SW_0T0]_U-73O^*A'S_G(N%_VEC8?]:6EW_
+M/$1._S=$5?\W1UO_,4)9_SI)7/\S/$/_*C R_R$G*?\V.CS_%A@;_R<G*O\R
+M.#K_,S]#_RLR./\N.C[_+#<X_QDA(_\H+"[_VM+5_]O2TO_AV-C_WM75_^C9
+MVO_GU=?_Z-;8_^?5U__TX^/_U,G._WAS?_^PK;G_>G9^_X!]@_^SL;3_K:NM
+M_X)\@/^$?XO_)R8W_R4E+O]L:FS___'K_\6,4O_ DF7_SY94_\*37?_)F6+_
+MR)AA_\657O_*EU;_R)EI_V!%(/\F&A7_(AP at _R$?*/]/3TS_S\.\_^?6UO\O
+M,S7_%QD at _QT<(O\C)RG_&QT at _R,I*_\P.#K_*"\O_Q@='?\K+B__&!D:_SL\
+M-O]&24/_*3 P_QDC)_\<(R__(R8Q_S8S.?_1R,C_Z-;2_^W:U/_VW]K_^-_:
+M__+<U/_SW-?_]]O8__;7U__LU-'_QK&O_R49'/\O*3'_9FAO_Q 4*?\A5Y'_
+M)#N(_R-,B/^]O<S_7UA?_VA79_\?(B?_HIJ0_Y"+AO_=T];_V<G-_SI!0?_%
+MPL'_WLO+_\F]OO\Z-S;_'!T>_QX;(?\G(B;_)" B_QP:'/\9&AO_(!TC_Q at 8
+M&_\7%1C_<6=J_XN#AO^>F9G_='!N_ZNHH__.O+C_+B@@_R\R)?_'O:[_GX]\
+M_YN.??^1B('_75Q;_TY15O\Y04O_-3]*_SD^1/\I,2[_+S<S_SY#/_\\/CO_
+M(R(A_RXS,_\G+S'_*2XS_QTA(_\A)RG_'R<I_RLX.?]B9&?_<G!S_VUK;O]H
+M9FG_8&1F_UA>8/]46ES_4%98_U%24_]/3E7_9F9U_Z^IM_]X='W_B(6+_X:$
+MA_^IIZG_BH2(_W]ZAO\E)#7_.#A!_VQN<?__].[_U)MA_\R><?^^A4/_PI-=
+M_[^05O_$E5O_P)%7_[^15_^_C%?_P9%2_Y)L1?\M&PW_7%-3_V!@5__2Q\#_
+MW<[/_RLQ,_\M,CC_/D!%_R4I*_\F*"O_+3,U_R(J+/\D+"[_%AP>_RPP,O\4
+M%AG_*2LP_Q03&?\T,SG_(1\B_Q@>(/\C*RW_)BXR_RLP-O\X-#;_U,G._^#/
+MU__IU]3_[=G1__':U?_QV=;_\]K9__C<V?_SU]/_X<G&__CCW_^CF97_-C- 
+M_R54CO\>,X'_*U.*_\'"S?]74%?_)Q at C_W1X>O^?EXW_AX)]_]W3UO_>R<[_
+M&1T?_YF7F?_.P,'_V,?'_V995/_/R<'_*"<F_T5"/?^">W7_/CPU_UM:4_]!
+M/#?_$Q$,_PP*!_^JHJ#_SL/"_\2\N/]03D?_0$0[_UI43/^VJJ7_2D,]_RPM
+M)O^WL*3_ at GAJ_Y6+@/^4B7[_85E/_R\M*O\X.T#_86-F_V)E7_]35$W_,C$J
+M_TQ*0_\N+"G_,C0R_R,J*O\9'1__&QT at _Q<9'/\?(23_+2\R_Y>-B?^AE(__
+MHY:1_YN.B?^5C(;_D8B"_XR#??^, at WW_A'UW_RHF*/]A86K_MK*[_S(N-O^.
+MBY'_%A07_Q .$/^%?X/_>G6!_RHI.O\I*3+_3%%6___PX__,G6W_RIIG_\N<
+M9?_#E%K_QI1;_\*05__!CUC_P)-7_\"/7/_!C%;_OI!3_ZE]2_]&+QC_86-A
+M_\S%Q?_=T<W_'B<G_Q 5&O\='R3_'" B_Q@:'?\G*2S_%!@:_R<K+?\9'1__
+M*2LN_Q47&O\H*B__$A09_QT@)?\>(B3_(R at H_RPQ,?\R.#K_*S U_SU#2_^A
+MHJW_*#U:_UUFC__9S-__\-G:__75R__PV=K_\-K8__'9UO_NW-C_[^#;_^WA
+MV/_CV-?_766%_SY1E_\M3'S_O</3_U!$1_].3%7_'2 at O_Y^9C_]^=6__Y=G<
+M_^S3TO]23T[_0CT__]C)R?_FT<S_FH^$_\O!M_\J*"'_O[FO_XZ%?O]W<FS_
+MQKZT_UY>4?^ >G+_(B ;_[&JI/_ at SLO_A'EX_ZBCG?^UL:G_,C H_S8U+O^]
+MO+7_I)^:_R,D'?^9E8W_<65<_W5N8O]K9EK_>71H_R =&/\='R+_&1<4_SX]
+M-O\P,RW_35-/_V=E9_]B8E__1DM%_RDN+O\B*2G_*BTR_Q at 7'O\;&1O_FI*5
+M_Z"8F_^CFY[_KJ:I_[.JJO^[LK+_O+6U_\2_O__$SKW_6V!:_UA98/^KLZ__
+M*RTP_Y:2FO\Q+##_-C(T_W=U=_^)B93_)"(R_QT>)?\M,S7__^_B_[R2:O^Y
+MCV'_K8E<_ZZ#5?^WBU__M(E9_[2+5_^WBUG_O(Y;_[>*5/^WBU/_O8E7_ZF 
+M5O^1>5[_V,J[_^31R_\L+2[_$Q4:_Q(6&/\6&AS_$Q48_R at J+?\0$A7_)RDL
+M_QD;'O\F*"O_%!89_R4G*O\1$Q;_&R$C_QHB)/\?)2?_(2<I_R,I*_\I+S'_
+M+#LZ_R B*?\@+D?_.DEL_RDY9?]37X3_SLC6_]_-R?_IT,O_\-31__79UO_U
+MV=;_\M;9__36U/_KU,__X]O?_XV/GO_/Q\O_3CPX_S(Q-_\7(BG_GIB._W5K
+M9__EV=S_\-C5_WUX>/_*PL7_V<C(_][*QO^*A7__S\?#_W=U<O_*QK[_?G=Q
+M_XZ*B/_(O[C_;V]F_[^WL_\C(!__N[&M_][.R_]_=W7_3TY'_SHV+O_!NK3_
+M?7MT_S$P*?^SKJC_34Q%_WAV;O^!>6__=W)F_WYZ:_][=&;_;&9<_Q\='_]0
+M3$K_4TM'_R$;&?\@&QO_+BDM_SP\.?]04TW_-#<X_Q\C(?\;'2+_$@X6_QP8
+M&O\;&1S_&18<_QH7'?\6$QG_&!89_Q at 6&?\6%AG_&!H=_U!$6?]%/DC_8%Y9
+M_[FGL?\N(RC_GIN:_Y^@H?\C)B?_*"PJ_XF)DO\G)37_)R at O_S0X-O_PYN__
+M0BXF_S<K)/\T*R7_/"TG_T4V,/\X*R#_1#@I_TX],/]50C;_64 at X_VM;2/]V
+M7$[_ at V=,_X-N4?^%?'7_X<_,_\K&R/\W.3[_(RDK_R,K+?\L,C3_)RTO_R4K
+M+?\B*"K_&B B_R,I*_\/%1?_(R4H_P\1%/\;(2/_&2$C_QLC)?\?)RG_(BHL
+M_R4M+_\I/2[_:&][_R<C,_\=)BW_("E!_R4S2O\6(3+_/3@^_T,_/?]P;&K_
+MIIZ<_\N^O?_5RLG_YM?1_^W7S__NT]+_[=C6_^G6S/_9R;__)R0C_R at K,/^@
+MEY#_6%-5_^3;V__LU-'_>G5U_]')S/_8Q\?_V<;&_R,@'_^_NKS_3DY1_X.!
+M?/^:EI3_FYF;_\O'Q?]V=W'_P;BX_RHF*/^ZL:O_X-#-_["HIO_!P+G_:&1<
+M_SPW,?^JJ*'_4TY(_S8T+?_ N[7_,BXF_\&^L_]Z=VO_>WEJ_W]Y:?]\=F;_
+M/#HS_S0Y-?\/%1'_("0B_QL<'?\B("+_*"8H_R<F)?\H)B'_-S4P_QT:%?\D
+M(![_2D=&_Q(0$_\2$!/_%Q48_Q(0$_\6%!?_%1,6_Q$1%/\8&AW_/4(^_R,G
+M-O]<7G/_G9&,_VQC7?]*147_D925_S,\//]&2TG_D9&:_QX<+/\H*3#_D(^(
+M__3J]/]71D;_)2$I_QL=)?\='!O_&1<:_QL8'O\;%R#_'!@A_QL7'_\9%AS_
+M&1<:_R >(?\;&AG_&A at 5_S(H*__:SLK_25)2_S4]0?\U/3__,3P]_R\W.?\J
+M,C3_)R\Q_Q\G*?\;(R7_&2$C_QDA(_\@)";_'!XA_Q<='_\9(2/_&B4F_QXI
+M*O\A+"W_(2PM_RXU*?\W267_$1DI_QH9&/\B+$[_*S1%_R B(/\>&B/_'R$F
+M_R(E)O\C)B?_*"TM_S U,_\R-3;_-#,Y_SPX0?\^-CG_6%-._X9^>O^TJ*O_
+MP;R^_Z:;E/]'1$K_Y-W=__+;UO]Y='3_VM+5_]G(R/_0N[G_ at GIV_\2XN?\F
+M(2/_PL' _U!.4?\T-CO_O[V__U]=7_^\L;C_*R<I_[NRK/_>SLO_85E7_S8U
+M+O_)Q;W_9V9?_S\Z-/_#NK3_.3<P_ZZBG?]L9E[_.CHO_W1T9_]I9UC_@'MI
+M_W=O6_]T<&'_+BDD_R ;&_\3#A+_$1 6_Q,4%?\8%1O_&!(6_Q<2#/\W,2'_
+M.S<A_S0T(?\V-"S_%Q85_R0B)/\D(B3_(1\A_Q<5&/\2$!/_$Q,6_Q\A)/\&
+M"C#_-RYC_[2CV?]%.&O_44QD_QP9)?\^04;_&R >_RTQ+_^=G:;_>WF)_RHK
+M,O_$O[K___+M_X1R:/\6%!?_%!8;_UY=5O])1T3_'!@:_QP7&_\B%13_'1$,
+M_QL6%O\4%!?_$Q at 8_RDM*_^KIJ;_W]#+_[*KJ_\P-#;_*C(T_RLX.?\J-C/_
+M+SP]_RHV._\K,S?_*3(R_RDU-/\D,"__)# O_RHR-/\J,C3_("@J_Q at C)/\:
+M(B3_("8H_R at N,/\F+"[_+"PC_QP[7?\'$R[_'148_QTW</\G,U+_)R4H_QX9
+M'_\D'R/_'QP;_R0C(O\H)BG_(QPC_QT;)/\C(RS_(R ?_QP=*/\H(R?_)B4K
+M_RPH,/\S+#/_+BDM_S<U./_5S,S_Z-;3_XZ/D/^9E)C_U,7%_\>XL_^NI*#_
+MQKZ\_UY96?_,PK[_D(J(_T=(2?_'Q<#_,BHH_\S$R/\D)"?_N+"L_]C*Q__.
+MP<#_A'UW_R(D&__*QK[_2#PU_ZRLH_^LK*/_,"\H_ZNLI?\W.S/_D)*)_S\_
+M-/]$13C_<7%D_V9G6O^1BX/_V,6__]["O_^ID8[_)Q at 8_RD=(/\2#0__$0\,
+M_RLK'/\R-1__,30=_R\S'?\N,"W_,C,T_S$R,_\Q,C/_*BDH_Q43%?\8%AC_
+M3DQ/_Q48._^AG+;_9F%<_Z>BNO\<&S__(R(__UM;;O\S.#+_.3TU_R ?)?\K
+M*#3_961J_\C"P/_^[_#_QK2P_SX\1?\D*##_&!83_Q at 7%O\5$Q7_%1,6_Z*=
+MG_^OIZK_&108_Q86&?\E*BK_-3<U_[6PJ__<S<C_X-'1_X^&AO]J967_75Q;
+M_TE/2_\K-C?_+CH__RXV.O\J,S/_*C8U_R8R,?\B+BW_)C$R_R(M+O\B+2[_
+M(RXO_Q8>(/\;(R7_'24G_R H*O\O,2C_)$!;_PP7+_\A'1__(#MQ_R0M2_\:
+M&1__(QXB_Q\;&?\Y-S#_2DA _TQ'1_\5&2[_'"U1_QTW8_\I0&K_'RE$_UI4
+M6/\H)2O_'R G_QX:'/\D(B3_*"8C_^;<V/_OW-S_0T-&_VMF:O_8R<G_O[*M
+M_[>MJ?_$OKS_44Y-_]/*Q/^]LZ__J*6D_\K%O_^QI:'_Q+S _RTM,/^WKZW_
+MWM#-_S,H)_^AG);_5%1+_VIJ7__ MJS_-CLO_YVBEO]!/SC_N[JS_T$_./^N
+MJ:/_5%1+_SL^,O]664W_4E5)_TY-0O_7Q[[_]-7/_^K/R/_6O[K_J9>3_T at _
+M/_\3$!;_%1(8_QD4&/\7$Q7_,"TL_Q83$O\=&1O_)R,E_Q at 4%O\<&1C_+2 at H
+M_TY)2_^;E9G_#PL__Z>BS/^VL[__KJ/8_Q01//\@'C__*29#_V)C;O\Z.SS_
+M)B8I_R0C*O\L+"__TLK(___S]__.O+G_'QPI_QP?*_],24C_'!L:_QD7&?\9
+M%QK_'!8>_R :(O\<%QW_&!89_T=,3/\]/SW_O[JU_^S=V/_PW=?_T+VW_^C7
+MT?_ at T<O_JZJC_SE 0/\O.S__*# R_RPU-?\I-33_*#0S_R<S,O\D+S#_(RXO
+M_R,N+_\B+2[_)C$R_RLV-_\J-3;_)S(S_RPV+?\U15G_$!XG_Q\A)/\M2'[_
+M*C1/_R,C)O\L*"K_+RTF_UA73/]C8E?_7%A6_PT6)_\,)E'_$3I\_QY$@O\G
+M.5__LJVS_RLF*/\>'2/_)!\9_YR<D_\Q+RC_[N+=__';W/\Y-SK_RL3(_]_,
+MS/^YK*?_P;>S_\"ZN/]23T[_VM'+_[RTL/^ZL[/_S,.]_];(Q?_.QLK_)24H
+M_\S$PO_:S,G_6U-1_SDX,?_!O;7_(B<;_X!]<O\Y/##_M[RP_UU84O^EGIC_
+MF(^)_WEM:/]$1#O_4E5)_TI-0?]%2#S_86%6_\:XK__OT\S_X,? _^7*O__P
+MU]#_TL/#_R 6'_\5$!;_&!06_R4B(?\O+2K_%A,2_S4Q,_]#/T'_&A88_R8A
+M(?]84U/_=7!R_XN%B?\2'1C_&!0[_RP?6O\<&D'_&!DR_Q,0+?\9%CK_)R5&
+M_S(P0/\F)2O_)R<J_R at I*O_8RLO___+R_\V\MO\@'R;_%ALA_T-!/O\E)"/_
+M%A06_QH8&_^,?W[_FHR-_R$7&O\@&R'_.C\__S4W-?^_NK7_\.'<_^W?W/_C
+MU=+_VLK'_^'1SO^RJZ7_/T$__R\Z._\N.CG_+3DX_RTY./\N.CG_+SLZ_RTX
+M.?\N.3K_-#] _S(]/O\N.SS_+SP]_R8S-/\@+2[_'2XD_R$E-/\;*BG_,#@Z
+M_R4]=/\H,TS_'R A_RDF)?\I*2;_2DU'_SH^-O\V-SC_%R$P_Q\[9_\0/(#_
+M'D!__RH]9_^?FZ/_0S at W_R<E*/\K)B#_GYV6_S,N*?_KW-W_[]C9_RLF*O_/
+MQ\O_Y,[/_[ROJO_)O[O_M[&O_TY+2O_;TLS_M*RH_\G P/_6Q\+_T,"]_\W%
+MR?\H*"O_R<&__]/%PO_!O;O_.3TU_Z&8D?\K,B;_M*RB_T,],_^.C8+_H)Z7
+M_UU;5/^LIZ'_0CLU_U]?5O])3$#_8&-7_U583/])3$#_P[>N_]2YLO^LEH[_
+MOZ:?_^'(P__:P<#_T[V__QL4%/\?'!O_7UU:_R8D'_\[/SW_+"\P_SL^/_\W
+M.CO_.3T[_UY at 7O]?8&'_2TM._Q00&/\4#QO_#Q00_QD7*O\6$2W_%Q,M_Q44
+M,?\3$C?_.35+_S,R.?]$1D3_0T5#_]'(R/__]O+_P;2S_Q\>)/\2%!?_'1D7
+M_R0?'_\A'1__%1,6_S0I*/]#.#?_'QH<_QH:'?]$1D3_,#@T_\.YM?_QW-K_
+MY]O7_^'5T?_=T,O_V<W&_YZ7D?\C(!__%A@=_Q<;'?\?(B/_'1T at _R @(_\B
+M(B7_)2DK_R4K+?\F+"[_*C R_RPP,O\R.#K_)3(S_R8Q,O\J+RW_'RHQ_R4P
+M*?\E)R[_)#]U_RDQ2_\D(B3_)R at I_T='1/]454__4E5/_R8H*_\/)$#_&$-O
+M_P8R?/\F1X__(SYM_[BGI_\P+S7_*R8A_S,Q+O^@FY7_-"PH_^O<W?_OV=K_
+M+"DH_];-S?_;S,S_>W-O_]?&QO^PJZO_2DI-_]O3T?^ZKZ[_RK^^_\6XM__&
+MO+C_R;_(_RPH*O_ O+K_>G1R_[&LI_\].#+_BH%Z_TY,1?]E7EC_C(9^_T1!
+M-O^AH)G_+B\H_ZJIHO\L*R3_7F!7_T!$._]#1S[_044\_UA?4_^EGI+_R:^F
+M_\6JG__*LJG_RK*I_\>PI/_*LZ?_.R\K_SXZ//\?'2#_+2HI_TA)0_]*2T7_
+M4E--_U)33?],2$;_2T9&_QD5%_\5%1C_%Q(4_Q8.&/\6$![_%Q4>_Q83*O\5
+M$2O_%Q4O_QH;-/\A&CS_'A at L_QT<&_\E)"/_B(.'___S[_^WJZ[_%1(8_Q<7
+M&O]U<'#_/3 at X_Q82%/\8%AG_)A\?_QL4%/\;%QG_%1<:_TI)2/\T/#C_P[NY
+M_^K;V__ at T=+_XM#4_]G(R/_3P\#_GYJ4_Q\;'?\5$AC_$Q,6_Q at 6&?\3$13_
+M&1<:_Q43%O\0$!/_$!(5_QD;'O\7&1S_%148_QD='_\@+2[_(RLM_R at K+/\=
+M*B__)2LG_RPN-O\D07?_)2M%_R,?(?\D)B3_/STV_U%12/]=7E?_&!D:_PXD
+M1/\91&[_!C-Z_RA)DO\>.VO_NZ:B_R D+/\E(!K_2TM(_Z&<EO\Z,"S_Y=;6
+M__#:V_\V-#'_V-#._][/S_^:EI3_WL_0_Z6AH_]*3$__T,G)_ZRFI/_4SLS_
+MP+JX_\2\N/^]L[S_,BTM_S(P+?](1DC_FYN8_YB6D?\].S3_J:6C_S,O+?^O
+MK*?_0#XW_YR:E?\Y.C3_=79P_R<H(O]%24'_-CHR_T1(0/]"1C[_1DQ$_U10
+M2/_*MZ__RK*I_\FQJ/_#J:#_O*&6_]6XK/^_K*+_0S<S_QX9'?]'0DC_%Q,5
+M_Q\;'?\E(2/_0CY _S\W-?^CFIK_&Q88_Q<5&/\4$1?_%Q,<_PT,&?\4$B7_
+M'1DS_QP8,O\;&"__%1(H_Q\:-/\F(S#_-#(M_S0R*_]055/___#L_[&EJ/\>
+M&R'_&QL>_R4@(/]U<'#_&147_Q$/$O^JHZ/_LJNK_Q<3%?\3%1C_'AH<_R$I
+M)O^QKJW_P;R\_W=\@?])457_0TM-_T)+2_]*3TG_%Q47_Q,0%O\2$!/_&A@;
+M_Q02%?\5$Q;_$Q$4_Q04%_\2$A7_&1D<_QH:'?\8&!O_&Q\A_R M+O\B*BS_
+M(RDK_QHE+/\C)2/_)28Q_R9">_\?)#[_)R,A_S4V,/]'13W_5E9+_TU/1O\A
+M(R'_%2Q)_R!+=?\)-GW_)D>0_QPY:?^QG)C_%1DA_R8A&_]34U#_G)>1_T V
+M,O_NW]__[]G:_S N*__9T<__W]#0_WMY=O_;S<[_GYV?_T5)2__3T,__K:NH
+M_]73T/^\NK?_HYZ9_ZF?J/\T+R__'!H7_S4X/?\>(R/_%AH8_S at Z-_\S+S'_
+M&A88_W!M;/]&1$'_*"<F_S0V-/^BI*+_(R4C_U]A7O]*3$G_04- _S]!/O]9
+M6UC_3DY+_V%<5_^9C8C_MZ6A_\BTL/_1N+/_T;6N_\VTI_]40SW_(QHA_U5/
+M5_]X<GK_>'%[_WYW@?^NI['_J)^?_Z^FIO\:%1?_%Q48_Q<9(/\4%2#_(R(S
+M_QH7+O\:%RW_$Q B_QD5)?\4#!K_$ P4_S0Q,/\_/C/_2T@\_S at V+___\>W_
+MJIZA_R$>)/\:&AW_A8" _[:QL?\2#A#_&!89_QT6%O\K)"3_&147_Q47&O]H
+M8F;_%1P<_YJ=GO\Z/3[_+C\__S%"0O\T1D3_.DQ(_TI33/\4%1;_%A,9_QP6
+M&O\9%QK_'AP?_Q43%O\3$13_%A07_Q02%?\<&AW_&A@;_Q45&/\:'B#_(B\P
+M_QHB)/\B*B[_$QTG_R(>(/\:'2G_(3IU_R0F0?\J)2#_45%&_SL[+O]864S_
+M,30H_QX@'?\8+TS_'TIT_PDV??\J2Y3_(C]O_\2OJ_\4&"#_)B$;_W1T<?^H
+MHYW_23\[_^K;V__RW-W_(B =_Y^7E?_6Q\?_N;FV_]O/T/^8F9K_5EQ>_\_(
+MR/^ZLK#_VM+0_\*ZN/^[LZ__I9ND_U)-3?\B(!W_'ATD_Q06&_\7%1C_'!@:
+M_Q -$_\3$!;_$Q$4_RLI*_\K*R[_&1L at _Q06&_\1$QC_)"4F_S4V-_\^/T#_
+M2TQ-_R at F*?\6&!O_+#$Q_V9H9O]05%+_/#X[_U=23?]L8%O_?W-L_W)J:/\>
+M&1W_4$I._R$<(O\0"A+_+"8N_VQF;O]<4U/_K:2D_QH5%_\7%1C_#P\:_Q(1
+M'O\B'RO_%@\9_Q44&O\7&!G_HIV=_Z:>G/]*2$'_1D0]_TY)0_]23$3_?W=S
+M___Z^O^\L;#_)R(B_R0@(O\D'Q__C8J)_P\+#?\5$!3_LJBD_[>KI_\?%Q7_
+M'!D8_Q\5&/\@)"+_EI:3_U]B8_\T0D'_.$9%_SI)1?\^34C_0T]&_Q$4%?\;
+M%AS_$Q$4_Q at 6&?\9%QK_%Q48_Q02%?\9%QG_%A06_QP:'/\5$Q7_&!88_QPA
+M(?\F,C'_(BDI_R4L+/\9'2S_'QL9_PX5(?\A.W3_&A\X_R<F)?\K+2K_-#LT
+M_S4X.?\O,RO_,38P_QPQ4_\K5H3_%D2._RY-E?\X473_JYB8_QHB'_\>%!?_
+M?'MT_Z*:EO]@5%?_Y=?8_^O<W?\N*BC_P,&[_["IH_^HH:'_W,W1_X:+B_]A
+M:FK_U=3-_[VZM?_?V=?_R\2^_[RWLO^-B(K_8%U<_S,R,?\:'!__%A@=_Q04
+M%_\8%AG_$A 3_Q(0$_\3$13_)B0F_QX>(?\:&AW_%!07_Q$1%/\4#Q/_% \3
+M_Q,1%/\2$A7_%QH;_QH=+O\-$2#_&!$B_R4:+?\G+37_-CLY_U164_]54DW_
+M5%!._QD4&/]13E3_+BLQ_R(=(_\N)2S_;FEO_TU$1/^NI:7_&!,5_Q43%O\.
+M#13_% \3_ZRGI_]\>'K_.#8X_S P+?^6EHW_H9R6_TQ*0_\>'AO_(R$C_R at C
+M(_^WM;C___3Q_Z&6E?\:%Q;_'AH<_S<T,_^VL[+_%A(4_Q\:'O\>&1__%1(8
+M_Q<9(/\4&B+_=W!W_QPD(/^*CXG_>7Y\_S5!0/\Y0D+_.4- _SM&0?]"3D7_
+M$A,4_QD4&O\5$Q;_%1,6_Q84%_\7%1C_%!(5_Q84%O\7%1?_%A06_QD7&?\8
+M%AC_'2 A_R(N+?\@)R?_+#0Q_Q,5)/\<&13_"Q4 at _QHR:_\9'S7_0#\^_T!"
+M0/\K,"K_'QPB_S8T+?\W.3;_'S99_RE7A/\:1I#_*TJ2_SE2;_^QGZ'_%AX:
+M_R8;(/^*BW[_I9^7_VA:6__JV=G_Z-C<_SDT-O]Y>7;_U<G$_Z6>GO_8S,__
+MC9*2_WR#@__(QK__O;BS_^#7U__*P;O_O[>U_XJ%A?]Q;FW_+BTL_QH<'_\6
+M&!O_%!07_Q at 6&?\/#0__$Q$3_Q,1$_\D(B3_'AP?_QP:'?\9%QK_%!(5_Q4/
+M$_\4#Q/_$ X1_Q,3%O\8'RO_'R5%_Q$7,?\:%RW_6$EB_V1I=?]D:6G_5EA5
+M_X6#?O]134O_&A49_U).5O]_?H3_?WA__X!W?O^VL;?_A7Q\_Z:=G?\<%QG_
+M'!H=_QP;(?\<%QG_K:>E_X:!A?\[.3S_+RXM_X:&??^=FI7_244]_QH8$_\:
+M&!7_-"TG_[ZXO/__]/#_?79V_QD:(?\0#A'_B(2"_ZJGIO\>&AS_'1@<_W1I
+M:/]N9F3_&A45_QT;'?\O)RK_%R 9_S8],_\Z0C[_)BTM_R,F)_\9'1O_*2XJ
+M_T901_\;'!W_&10:_Q43%O\8%AG_&!89_Q at 6&?\4$A7_%A06_Q43%?\6%!;_
+M&1<9_Q43%?\>(2+_(R\N_Q 7%_\K,S#_%!8E_QL8$_\4'BG_&3%H_R\S2/](
+M1D/_)"0A_RTK(_\Z,#/_.3,K_S\].O\D0&+_+%>%_QY&D?\J2Y/_1%]W_[>E
+MJ?\3&AK_(A<<_XV0?O^CH)3_>'!N_\&UN/_2R]7_'!XF_S@[//^UJ*/_J:2D
+M_]G/TO]]@H+_FYZ?_\K%P/^ZM++_W-+5_\B^NO_.QL3_?GEY_XF&A?\?'AW_
+M%QD<_Q47&O\1$13_%Q48_Q05%O\.#Q#_/T!!_QX?(/\G)2C_)2,F_R >(?\4
+M$A7_%A 4_Q0/$_\/#1#_#P\2_QPE/?\;(5'_$QY _Q8;-/\O(#G_:6YZ_V1I
+M:?]H:F?_B8>"_U).3/\D'R/_/#A _T9%2_\1"A'_.C$X_XR'C?]C6EK_HIF9
+M_Q\:'/\6%!?_$Q(8_QP7&?^JI*+_-"\S_QH8&_\G)B7_?W]V_WUZ=?\_-C#_
+M*R8A_Q\:%/]63$'_R\'$___V\/]53U/_-3I&_R at E*_\D(![_L:ZM_QD5%_\:
+M%1G_8595_V-95?\;%Q7_'1P;_RH<'?\H*2+_E92)_X>(@O\E+"S_'R8F_QXF
+M(_\J,B[_2E9-_Q at 9&O\6$1?_$Q$4_Q84%_\6%!?_%A07_Q,1%/\4$A3_%!(4
+M_Q84%O\9%QG_%Q47_Q\B(_\G,S+_"Q(2_RTU,O\/$2#_&Q at 3_Q<A+/\9,&7_
+M'B$S_R$?&/\L*B7_/#HK_R<B'?]*1SS_ at HB$_R-"9/\L5X7_'$"+_RU.EO])
+M9WW_P*ZR_QH?)/\C&1S_D)"!_YZ<E?^,CI/_F:2K_Y>CLO]'6&7_.D9*_XZ&
+M at O^HI:3_W=78_Y.8F/^IJJO_P;^\_[JYN/_8T]?_NK:T_\G"PO]S;F[_A8*!
+M_R\N+?\8&AW_&AP?_Q(2%?\8%AG_#0X/_UA;7/]15%7_(B4F_R >(?\D(B7_
+M'1L>_Q,1%/\6$!3_% \3_Q$/$O\4%!?_'28^_QPC4?\4'4+_'" \_RX>.O]A
+M9G+_65Y>_VMM:O^5DX[_44U+_Q<2%O\L*##_'ATC_S(K,O\Z,3C_?GE__U1+
+M2_^IH*#_'!<9_Q at 6&?\3$AC_&106_Z6?G?\8$Q?_%1,6_QH9&/^!@7C_F9:1
+M_SPX-O\F(B3_&1 at 7_U--0__ O;S___7R_T Z/O\;'"/_&!D:_WAZ=_^\M;7_
+M&A@:_Q43%O\F'Q__&A88_Q83&?\='"+_BX:&_RHK)/^=E(W_ at X%\_R\W-/\H
+M+2O_&1\;_RTS+_]365'_&!88_Q01%_\4$A7_%1,5_Q02%/\3$1/_%!(4_Q43
+M%?\4$A3_&1<9_QD7&?\7&!G_(B<G_RPU-?\;("#_-3<__Q8>&O\=%1G_&1\G
+M_R0V;O\9'R__)BHB_RTP*O\V+2;_.S8V_VUP<?]&3T__,%%C_QM0AO\;.W/_
+M.$]Z_UQH=_^ZLK;_(ATC_R <'O^-CX;_HI^4_U-@:_]+;(/_1VN _R%"6/\A
+M-D+_*2LI_Y^AGO_#QL?_A(F._\/$Q?^_O+O_6EU>_[[#P_\^04+_S<G+_V%9
+M7/^7CY+_&1<9_R4E*/\9&1S_$Q,6_Q<7&O\0$!/_'AXA_R,C)O\H*"O_&1D<
+M_QL;'O\5%1C_$! 3_Q,.%/\3#A+_$A 3_QL:(?\5'##_&B%+_Q8=0?\;'#O_
+M9D]Y_W-P??\J-3;_'R K_WUZ>?]'1$/_&!06_RTH+/]'0DC_13M$_T,T/_^$
+M?(;_85-4_Z&9G?\4$AO_$Q48_Q,1$_\<%Q?_EY&/_PT+#O\5$AC_&!<6_V5F
+M8/]K:6;_-38W_QH<(?\4$A3_5%)*_[VZN?__^/?_3$1(_R4D*O\>'R#_+S0P
+M_[^VMO\9%QG_)"0G_[.KJ?^ZM;?_&Q8<_Q$/$O\>&1G_'R,;_Z&6C_^ ?GG_
+M-#PX_SD_._\M,R__-3LW_UU at 6O\8%AC_%!$7_Q02%?\3$1/_%1,5_Q43%?\5
+M$Q7_$Q$3_Q02%/\9%QG_&1<9_Q87&/\A*"C_,3HZ_Q(7%_\M+3C_(RLA_R,9
+M(O\?)2W_'RUE_S8U1O\W.#+_/T$^_S,X,O^9I:3_F:6I_VYU=?]/96/_,UEY
+M_W1\D/^(@'[_AH&!_ZRFJO\;%AS_'AP>_XV.B/^=F(S_2%EF_T=MB/^OS^7_
+M=(ZC_T147O^$A('_F9J4_R<M+_\P-3K_L*ZP_\._P?]D:6G_7&AG_W1[>_^$
+MB8G_D8^1_ZB at H_\8$Q7_%1,6_QH:'?\0$!/_%Q<:_PX.$?\6%AG_'1T at _QX>
+M(?\?'R+_&1D<_QD9'/\/#Q+_$PT5_Q,.$O\0#A'_%!(;_Q4>-O\9(U#_&R5*
+M_Q09-_]E3WS_?GF%_Q 8&O\:&B?_'1D;_U524?\H)";_,"LO_R<C)?\B&!O_
+M,B4J_WEP=_]!-C7_8%99_Q$.%/\4$!+_%A(4_QD2$O^5CXW_%1(8_Q00&/\7
+M%1?_75Y8_YZ>F_\Q,C/_'!P?_QT;'?]+2D/_AX2#___X]_]#.S__'QXD_Q46
+M%_\E)2+_L:6F_QL9&_\9&Q[_&1,1_Q81$_\<%QW_&QD<_Y*-C?]%24'_HI>0
+M_W]]>/]<95[_9FUE_V!G7_]A:&#_9&A at _Q@6&/\9%AS_%A07_Q84%O\:&!K_
+M'1L=_Q84%O\5$Q7_$A 2_QD7&?\7%1?_%Q at 9_R8M+?\T/3W_%!D9_S,P//\A
+M*![_&A 9_PD2&?\;*6'_&Q<G_R<A'_\8&AW_-$M*_X6AI/]D>'S_3596_U)I
+M:/\S6'?_<7)]_Y> ;?^%=V[_J*">_R$?(O\?'1__C8J%_ZBAE?^1HJ__)4]I
+M_[//Y/^URMS_$QTG_XJ%?_^#@'O_'B(D_UE;8/^_N[W_O;F[_RPQ,?\T0#__
+M-#T]_TQ85_\D)RC_E(R/_QD1%/\6%!?_&AH=_Q 0$_\8&!O_%148_QX>(?\>
+M'B'_0T-&_RHJ+?\@("/_*BHM_Q(2%?\4#A;_% \3_PX,#_\3$1K_%2$\_QHE
+M5/\<)TK_,C5._V)4>O^ ?H?_#1 5_Q42'O\0#0S_4$U,_QD5%_\@&Q__0T)(
+M_U945O]C7%S_IJ*J_VYO=O\6%!?_&1(2_S$E(?\?&AK_&Q04_ZFCH?\4$1?_
+M$P\7_P\-#_]B8UW_FYN8_ST].O\=&QW_&QD<_RTN*/\:%AC___KY_RLC)_\2
+M$1?_'!T>_WEW=/^FEYC_%1,5_RDM+_^[M;/_G)>9_Q at 3&?\=&Q[_%Q(2_T5)
+M0?^HG9;_A8-^_V5O9O^%C8/_;'1J_V=O9?]I;67_%Q47_QH7'?\:&!O_&!88
+M_QL9&_\>'![_'!H<_Q at 6&/\:&!K_&A@:_Q at 6&/\7&!G_*"\O_S([._\4&1G_
+M-3 \_R(F'?\@%A__'2DP_R$V;/\6%"3_(A\>_R$M-/^*I*?_ at IVD_UUT>?]&
+M4D__46IO_RU5?/]T>8O_D8!R_W- at 5O^>DHW_(2(C_Q\;'?^2BH;_IYV2_YFJ
+MM_]VHKS_F,38_ZG-XO\J.TC_B(.#_YV8D_\>'B'_2TI0_\7 PO^NIJG_.C at Z
+M_S@[//]+3D__/D-#_QH='O^"?H#_&!D:_QD9'/\<'!__$Q,6_Q04%_\6%AG_
+M%A89_QH:'?\]/4#_'Q\B_QD9'/\?'R+_#@X1_Q0.%O\4#Q/_$0\2_Q(0&?\8
+M(CW_(BI6_Q8<-O\8&"'_5$QG_T ^1_\K)R__&QHA_X.!?O]23T[_&A88_R<B
+M)O\-$B3_'",Q_S(U0/]G;8/_=H&@_Q\D-O\=%A;_."TF_R,?'?\=%A;_K:>E
+M_RLH+O\?&R/_%!(4_V)C7?\;&QC_,S$L_QL8%_\5$Q;_*2TK_Q at 6&/_Y[>[_
+M)Q\B_Q81%?\>&QK_'1T:_YJ.D?\H)2O_*"DJ_S$I)_\J)2?_%1(8_R(@(O]^
+M>7G_6U90_Z.:D_^4DHW_;G5N_Y&6D/]Z?7?_;G5N_W)S;?\4$1#_&108_QD4
+M&/\6%!?_&!89_Q at 6&?\9%QK_&1<:_Q84%_\@'B#_%Q85_QL:&?\G,S#_-#DW
+M_Q8:&/\X/D#_(1\<_QX7$?]&3E[_)"U<_QH;)O\@'AO_)C0S_X:;G?]SB8O_
+M87=U_UMD7?]>=7#_+D]Z_WA\?O^<AX+_9UI-_XJ"?O\?("'_+S$O_X>. at O^I
+ME8W_4%AB_V24J?]YJ,#_F\WH_UM\D_^\M[W_ at G9W_Q\@(?\[/C__S\G'_ZBA
+MH?\Q+S'_+R\R_RHI+_]<6%;_'1H9_T-"2/\)"!7_'18B_R :(O\9%AS_$!,4
+M_Q45&/\4$A7_$0\2_Q84%_\?'2#_%A07_Q$/$O\1#Q+_$A 3_Q(0$O\2$!/_
+M%1(8_QTC0_\1%C#_$0\2_Q<1%?\I)2[_)R0J_S M,_\N+"__,2\Q_R8D)O\>
+M&AS_0CT__R(E/O]*46?_%!XL_R,S3?]*5G7_"PP=_R$9%?]A7$K_0SXY_Q at 3
+M%?^BG9__*B0L_QH5&_\5%Q7_24Q&_U!/2/^LHI[_&1T;_Q at 9&O\H)BG_,"XP
+M___S\O\H("/_)"$G_R$<'/\_03[_=&EN_Q -$_\E)B?_-2HI_R<A)?\4$QG_
+M&Q<9_UM65O]G8%K_H)J2_Z6CGO^ A8'_G)V7_Y*0B_]V>7/_>'AU_Q<4$_\8
+M%!;_%Q(6_Q$/$O\6%!?_%!(5_Q<5&/\5$AC_%A07_R,A(_\;&AG_'!L:_R<V
+M,O\X/#K_&!P:_R\[./\E(B'_-C F_R8L//\>)U#_%1LC_R(>'/]46UO_5&=G
+M_W2*B?][CHC_8&IA_UEP:_\N2WO_=WQZ_YF#@?]U:V#_=G!N_RHK+/\P,B__
+MCXZ#_VIB8/\,)S+_<:C _X.QS?]BEK?_>:+ _[.SO/]N8F/_)"(D_RXR,/_/
+MR<?_GYJ:_RPJ+/^FIJG_*BPQ_[&MJ_\;&!?_8F-J_R<D,?\\.47_(2(I_Q03
+M&?\1$13_$Q$4_Q84%_\2$!/_$Q$4_QH8&_\7%1C_$0\2_Q$/$O\2$!+_$A 2
+M_Q .$?\<&1__'"-!_PH-'_\0"PO_*",E_Q at 5&_\9%QK_)"(E_R >(?\=&QW_
+M(B B_VIF:/\F(2/_$P\?_Q at 8(_\5&!W_&B4P_QXF.O\Y/47_)R(=_S4O)_]L
+M:VK_# T._Z2BG_\U,"O_(1P<_Q88%O\^0S__3$I%_\6YM?]'3$K_+B\P_QD4
+M&/\8%AG___3Q_SDT.O\7%R3_)B$E_RDK*/]]<G?_&A<=_XJ+C/^RIZ;_<&IN
+M_Q,2&/\:%AC_%Q(2_W=P:O^;E8W_N+:Q_[V]NO_!OKG_J:&=_YR:E?^<FI?_
+M)2(A_R <'O\<%QO_$Q$4_QH8&_\3$13_%Q48_Q<4&O\7%1C_(!X at _QD8%_\?
+M'AW_*CDU_S<[.?\8'!K_+C8R_R<B)O\G)A__)"DU_QPF2_\4&R'_/SLY_X2)
+MCO^7K*[_ at 9:8_WB&A?]E;6G_771O_R1!<?]Y?GS_E7]]_W=M8O](0D#_*2HK
+M_R,E(O^?D(O_&2,G_S9?<O];C:C_99.O_UV1LO]0?9O_JK"Z_U]56/\L*BS_
+M%!@6_]#*R/^@FYO_'AP>_["PL_]"1$G_LK"S_QH:'?]S=7C_%1(8_QXB)/\E
+M*2O_%!07_Q,.$O\6%!?_&A@;_Q<5&/\2$!/_%1,6_Q,1%/\0#A'_$0\2_Q$/
+M$?\1#Q'_#PT0_QL8'O\?)CS_%!8E_QT8&O\E("3_$A 3_QD7&O\L*BW_'1L>
+M_Q<5%_\5$Q7_34E+_RDD)O\:$A;_%A(4_Q(1$/\A'R+_$18<_Q@>(/\L*2C_
+M'Q,6_V1:;?\;$BK_C("5_X%V??]%/#S_(1X=_SQ /O\P,C#_S\3#_S U,_]'
+M2$G_(!L?_QH8&___^//_03U&_U-8:O\4$A7_)"0A_V]D:?\7%!K_$Q05_R@=
+M'/\6$!3_%Q8<_QH6&/^/BHK_?WAR_YV7C_^MJZ;_TM#-_]C0S/_7R\?_K:BC
+M_ZNIIO\9%A7_&Q<9_QH5&?\3$13_%Q48_Q$/$O\4$A7_%1(8_Q84%_\6%!;_
+M.3 at W_R0C(O\I.#3_-3DW_QD=&_\O-##_)2(H_QT?'/\4&B+_%QL[_QP>(?];
+M65;_BYB=_XFCIO^%F9W_96UO_UAB7_]7;VS_)4)R_WA]>_^+=7/_;V5:_T])
+M1_\D)2;_(R4B_YV4C?]=;''_'RY%_Q K0_]]I;K_F\OG_Z',Y/^\P,+_4$='
+M_RDG*?]@9&+_SLC&_YF4E/\;&1O_N[N^_TI,4?^XM[[_&1L>_V!C9/\8%!+_
+M(1T;_R8A(?\9%!;_% \5_Q at 6&?\B("/_'1L>_Q(0$_\1#Q+_$A 3_Q84%_\3
+M$13_$0\1_Q$/$?\-"P[_'!D?_S,[2_\2$A__%0\3_Q(3%/\0$!/_&!89_R0B
+M)?\7%1C_&!88_Q<5%_\8%!;_&A47_QP7'?\-#Q;_!PP2_P@'#O\3#A+_'!H7
+M_Q\;$_]^:6?_?6)R_T at N2?]3/5?_0C8__XV"@?]645'_.3L^_RTO-/_.PL/_
+M+C,Q_TQ-3O\=&!S_%Q0:___Y^O\G)BW_*B\[_S4T.O\H(B#_5U%5_QX;(?^6
+MD9/_M*RJ_SXY/?\.$!7_&A@:_QX;&O^ ?G?_E9.+_[RZM?_7T<__V]#/_]?,
+MR__"M[;_K:FG_R0A(/\:%AC_%1 4_Q,1%/\9%QG_%Q47_Q at 6&/\7%1?_%Q47
+M_QL9&_\?'1__'R,A_R\W-/\X/3O_'"$?_S0X.O\?(2;_&AT>_Q$6'/\7&BS_
+M%R(C_T-84O]YCY?_EK&\_WR8H/]>>(/_0U=E_TAE<?\R1V3_>7MY_Y:$=O]P
+M95K_2T=%_T)%1O\Q-C+_CH^(_WIW=O\<&2;_05IQ_X&PPO^9Q=G_C+?)_ZJY
+MN?\X-33_.3X^_V1I9__-R<?_CXJ*_QP8&O^.CI'_86-H_Z:DI_\3$Q;_,#,T
+M_R4B(?^2AH'_9%]9_QL=&O\;%QG_&108_QT;'O\5$Q;_$A 3_Q(0$_\2$!/_
+M$0\2_Q$/$O\2$!/_$A 3_PT+#O\;&1S_4$]5_TA'3?\4$A7_$A 3_P\-$/\0
+M#A'_&A@;_Q<5&/\1#Q+_" 8)_Q(0$_\:%1G_1D)*_S\]1O\Z.D7_$0\8_S(I
+M,/] -3K_B7Z#_UA'4?]I76S_9%IK_W=N>_]O:&__HYZ at _YV7E?]*1T+_55-5
+M_];*R_];4U'_2D-#_QH5%?\<%AK___3T_RPG*?\>("7_(1X=_RXF)/],1DK_
+M(R F_R8>(?\J(B#_'1@<_Q@:'_\<&AS_=G-R_X.">_^8F(__O+JU_]C0SO_>
+MT]+_V<[-_\6ZN?^JIJ3_1T1#_Q82%/\7$A;_%Q48_QH8&O\7%1?_&!88_Q<5
+M%_\7%1?_&QD;_QT;'?\?(R'_,38T_S,X-O\=(B#_.#8Q_R0B'_\?'"+_%A,?
+M_Q01*/\P-U7_'S%5_R V7/\O5'?_.VJ-_RU:@O\>16__+%5Y_RY(;_]\@XG_
+MGI"!_VQ at 5_]%03__+C$R_RHO*_]?8UK_ at 7]Z_UUF;?]9?)/_;YZV_Y_!V_^#
+MI;G_H::K_S,L+/\T-3;_55I8_WZ ??]L:VK_*2PM_Z"DIO]>8VC_PL##_Q,1
+M$_\0$Q3_'AH<_R,A&O^XKZG_BWQ\_Q<1%?\6%!?_%!(5_Q02%?\3$13_$Q$4
+M_Q,1%/\2$!/_$A 3_Q,1%/\2$!/_$Q$4_QH8&_])1TK_%1,6_Q .$?\2$!/_
+M$A 3_R >(?\B("/_(R$D_Q<5&/]$0D7_%!(5_Q .$?\4$!C_$@X6_QH6'O\G
+M(RO_,2XT_S at S.?].2%#_85ID_Q$.&_\4$1W_'!@@_T(]0?^MJ*K_LJJH_WMO
+M:O]L967_BX*"_W!G9_]L967_7%=7_T,^0O__\.S_.S0T_RDJ*_]-1T7_-2TK
+M_S8P-/\:%QW_65%4_V-;6?\G(B;_&QTB_R8D)O\V,S+_CXZ'_YB8C__$PKW_
+MV='/_]?,R__:S\[_Q;JY_ZJFI/]/3$O_%1$3_Q81%?\3$13_%Q47_Q84%O\5
+M$Q7_%1,5_Q84%O\>'![_&A@:_R(F)/\X/3O_,#4S_R,H)O\U.3?_%Q\I_PL7
+M,O\,$S?_"!,R_RL\:O\>.7;_*4M]_R=0@?\^;)[_+%J,_S);C/]%:)#_3F:-
+M_TQ47O^7C8+_=VMB_S at R,/\_0$'_2$A%_VIN9?]J;F;_=8.&_SM=<?]]K\3_
+MH,?@_WBBLO]UA(3_A'M[_T,_0?\;(R#_+3,O_T-(1O]U>GK_N,#"_Q4?(_^]
+MN[[_'!H<_QH='O\>&AS_%1 at 2_[>IIO^;@(;_% \5_Q$1%/\4$A7_%!(5_Q .
+M$?\4$A7_$Q$4_Q,1%/\1#Q+_$A 3_Q43%O\3$13_%!(5_QX;(?\3#Q?_$0T5
+M_Q ,%/\1#Q+_&A@;_QD7&O\8%AG_$A 3_QT;'O\4$A7_&A@;_Q(/%?\2#Q7_
+M%1(8_Q42&/\3$AC_$1,8_Q,5&O\7&1[_$1(9_Q,2&/\R,#+_'QT:_Z&<G/^/
+MA(/_:%Q7_V9=7?]@7%[_7EI<_TI&2/]134__4E!3___R\_\J)2G_("(I_T(^
+M0/]#.SG_-2\S_Q<4&O^3BX[_FI*0_RHE*?\7&1[_'!H<_RDF)?^/CH?_E96,
+M_\3"O?_6SLS_U<K)_]K/SO_-PL'_H9V;_R<D(_\6$A3_%Q(6_Q,1%/\7%1?_
+M%A06_Q43%?\5$Q7_&!88_R,A(_\;&1O_)"@F_SD^//\O-#+_)"DG_SL[./\;
+M(RW_-D9 at _T-/:O\U.E/_,#I._SU/7?\L/$S_)RP^_RLR0/\Z1$__7F)J_VAG
+M9O]N9V__@'ES_X1Z;_]S9%[_GY>5_T]-3_])1T3_'QL=_QP8&O\C)2C_/DI3
+M_Q8M,O]/8F[_CJBU_QPE)?\E("#_/#] _TA-2_]65E/_34Q+_TQ-3O^RM+?_
+M&!L at _[2OL_\>'![_'R(C_QX:'/\A'QS_N;6S_UA35_\6%1S_$@\5_Q(0$_\0
+M#A'_%A07_Q\=(/\5$Q;_%1,6_Q02%?\3$13_$0\2_Q,1%/\2$!/_-S,[_S(N
+M-_\=&2+_&A8?_Q(/%?\7%1C_%Q48_Q<5&/\/#1#_(!XA_Q<5&/\0#A'_&A@;
+M_Q02%?\4$A7_%!(5_Q,2&?\3$AC_%!07_Q,4%?\4%1S_$ X7_U%/4O\?'!O_
+M;F]P_V9D8?^%@'K_5%-2_TQ04O]%24O_2$A+_TI(2_]'14C___C[_R(?)?\5
+M%AW_'QP;_SPV-/\@&Q__(QTA_RX?'_\G%Q3_(AH>_Q,5&O\1%!7_0$%"_XB&
+M at _^;E8W_Q\*]_];/S__=U-3_V]'-_]'%P?^>EY?_'!<9_Q82%/\4$A3_$ X0
+M_Q43%?\=&QW_$Q$3_Q<5%_\9%QG_,"XP_QH8&O\E*B;_,C<U_S,X./\D*B;_
+M/#@P_R at D'/]O;&?_8EQ4_W]U<?]L8US_;6A<_W!J8/]U:F/_<F9=_W-F6_]J
+M7%/_4DY,_U).4/]=6%/_;61=_VI>8?]%.C__'QH:_RXJ+/\;%1G_%Q,5_R0C
+M(O\?&AS_-"4?_R<9%O]74E3_>W-Q_R4=(/\E)"K_)BHL_R @(_\H)BG_&18<
+M_VAG;?\@'R7_G)ZA_Q<9'/\:&AW_'1L>_R,>&?_$P<#_:&=M_R,@)O\7&A__
+M%QD>_Q(/%?\8%QW_*RPM_QT;'O\@'"3_$Q$4_Q84%_\U,S;_#0L._Q84%_\Q
+M+C3_.#0\_QH6'O\;%Q__%Q(6_QH5&?\6$17_%1 4_Q83&?\7%!K_%!$7_Q83
+M&?\1#A3_$0X4_Q83&?\5$AC_%A,9_QL9'/\9%QK_&1<9_Q$-%?\3#Q?_.#0\
+M_RLH+O\G*2S_<G9T_U)44O]*34[_1$A*_T1&2?]#14C_1D9)_T9(2__[\_;_
+M)R(H_R$@)O^.B8G_=6]M_RHE*?\8%AG_O;>U_[VUL?\<%QO_&!<=_QD5%_\5
+M$Q7_DHV-_YZ5CO_*Q<#_UL_/_]W4U/_<TL[_TL;!_Z"7E_\?&AS_%Q,5_Q43
+M%?\6%!;_&1<9_QP:'/\3$1/_$Q$3_QH8&O\;&1O_&QD;_R0I(_\U.CC_+C,S
+M_R8L*/\T-2__+"DD_TM&0/])0SO_8UE5_UE13?]*14#_.38Q_S L+O\D(B7_
+M&!89_Q at 6&?\;%QG_'QL9_RPE'_^ =FS_9UM<_V)<6O]I9F'_0#T\_QX:'/\9
+M%QG_-#(O_R<<&_]*,R?_.24=_\J]O/^#>77_(!D9_RPJ+/\S.CK_2$M,_RDJ
+M*_]A8F/_?7Y__Q$2$_^SM;C_&QT at _Q86&?\<&AW_*28A_[VXN/]@6F+_&Q@>
+M_S(W//\X.C__'QPB_R at J+_] 04+_%Q0:_R<C*_\3$13_# H-_S(P,_\6%!?_
+M$A 3_Q\<(O\8%1O_$Q 6_Q$.%/\8$Q?_&108_Q81%?\5$!3_$@\5_QH7'?\3
+M$!;_$@\5_QD6'/\1#A3_&A<=_Q,0%O\6$AK_%Q,;_Q41&?\6$AK_'QT at _RPJ
+M+?\M*R[_4E!3_TE*2_]%2$G_1$=(_T-&1_\_043_/D!#_T%#1O]"1$?_0$)%
+M__CP\_]'0DC_*RHP_Q\:&O]O9V7_)!\C_R B)?\@(!W_(1X9_Q43%O\:&1__
+M'Q<:_RXL+O^-B(C_GI6._\_*Q?_2R\O_U\[._]S2SO_6RL7_H)>7_R0?(?\=
+M&1O_%A06_Q<5%_\9%QG_&A@:_Q,1$_\2$!+_&A@:_QP:'/\:&!K_)RPF_S<\
+M.O\J+R__)2LG_R\Q+O\H)B/_/#DT_T0_.?]'/SW_&Q(2_R,<'/\>&1G_,RHD
+M_T0\./]234W_:%]9_V9:4?]Q9EO_>FU at _X5W:/]Y<6?_9F-8_VQK8/\U,S#_
+M(!XA_R(@(O\H)"+_+1X8_T8K&O\X(17_U,;#_Y2,BO\>&AC_75]<_V%L9_]:
+M8%S_7V5A_VEO:_]=8U__/4,__TI/3_\1$Q;_#P\2_Q84%_\W-"__3$='_R :
+M(O\8%1O_-#D^_UQ>8_]95ES_,#(W_U!14O\2#Q7_(!PD_Q<5&/\6%!?_&QD<
+M_Q84%_\@'B'_%1(8_R0A)_\4$1?_'ALA_QH5&?\:%1G_%A$5_Q0/$_\7%!K_
+M%A,9_Q at 5&_\5$AC_%A,9_Q01%_\6$QG_&18<_Q00&/\@'"3_%1$9_R,?)_\U
+M-C?_4U53_V5G9?]*3$K_2DQ/_T1&2?]!0T;_/D!#_T)$1_\_043_.SU _SY 
+M0_\Y.3S_^O+U_S0O-?\D(RG_;VIJ_Y:2D/\>&1W_+2 at L_Z"5E/^+?WO_'1<;
+M_QH9'_\=&QW_'1X?_Y60D/^>E8[_S\K%_];/S__8S\__U,K&_]C,Q_^=E)3_
+M&A47_QT9&_\5$Q7_%Q47_Q at 6&/\:&!K_$Q$3_Q,1$_\;&1O_'!H<_QP:'/\G
+M+";_.3X\_RHO+_\F+"C_-30M_R\J)/]+13W_6U-)_W]S:O]-03C_13LQ_TU%
+M._]P8U;_(1D5_R\K+?]/1#W_<F58_WUP8_]]<F?_AGMP_W!H7O]E8E?_<G!H
+M_S8R-/\<&1__&QD;_RTH(O\Z*![_8D(L_T at O'O^^KZK_:6%?_S$M+_]C9VG_
+M86QM_UE?8?]46ES_-ST__SM!0_\L,C3_3U-5_Q$3%O\-#1#_(!XA_SPY-/^-
+MB(C_(1LC_R,@)O\Q-CO_7F!E_Q83&?\9&R#_2DM,_R =(_\<&"#_)B0G_R$?
+M(O\<&AW_2$9)_TI(2_\4$1?_44Y4_Q\<(O\0#1/_%A$5_Q at 3%_\4#Q/_&Q8:
+M_QD6'/\5$AC_%A,9_QX;(?\:%QW_%!$7_QL8'O\;&![_)2,E_R4C)?]'14?_
+M=7-U_U]?8O].4%7_2DQ1_T-%2O]!0TC_/D!%_SP^0_\[/4+_,3,V_S$S-O\T
+M-CG_+S$T_QD7&O__]/7_+R<J_QD9'/][?G__DY25_Q<7&O\='2#_:65G_VUL
+M<O\2%1K_)B<H_QP4$/\L*"K_D(N+_YB4C/_.S<;_U-'0_]',S/_6T,[_RL"\
+M_Z::G?\>%Q[_&Q@>_Q42&/\5%A?_$Q05_Q87&/\0$1+_#@T3_QP;(?\8&1K_
+M'B >_R at M)_\\03O_*S L_RLP+/\O*RG_03PV_U=11_]H7E#_8E!&_U! -O]%
+M.B__75-(_U]23?\5$!+_$! 3_VYI8_]L8EC_>VYA_WEK7/^$=VK_8UQ6_V!<
+M5/]Q;&;_'A89_Q40%O\2$!/_(!D9_U1!.?]A0RW_5#<E_Y!]=?^/AX7_*R0K
+M_V!?9?]05%;_4%-4_TQ-3O\'!@S_(R$D_T5!/_]25DW_)B at E_QX=(_\8%QW_
+M349 _UA03O\;%AS_%Q8<_R at P-/]66%W_&Q@>_Q06&_]$1DG_%!8;_QT=*/]$
+M1DO_+2LT_Q\<(O].3$[_3TQ2_Q01%_]85EG_'AP?_Q84%_\1#!#_&A88_Q at 3
+M%?\A&AK_&Q8<_Q,/%_\;%Q__'1DA_QP:'?\@'B'_'QT at _U)04_]O<73_55E;
+M_TU14_]*3E#_0TA-_S]$2?\^0TC_/T1)_T!!2/]#0DG_0D%(_T)!2/\]/T3_
+M/4%#_SH^0/\V.CS_%1,5__SZ]_\K*"?_&!88_QL9'/\M+3#_&!@;_Q86&?\4
+M%!?_'ATD_Q06&_\5&!G_*28A_QX?(/^/CHW_GIB0_]/.R?_3R\G_U<O'_]/*
+MQ/_+Q;W_HY>8_Q at 2%O\9&1S_&!,7_QP8&O\:%AC_'!@:_Q<3%?\1$A/_'1X?
+M_QL=&O\D)R'_'" 8_T!#/?\E)R3_%1<5_QX:&/])1T#_5E-(_VE?4?]X9ES_
+M6$@^_T4X+?]21SS_8E-3_QH2%O\8&AC_<FQD_V5;4?]M8%/_:EI*_W-F6_]5
+M4$O_:6=@_UI84?\3#A#_%1 4_Q42&/\?&AS_138Q_UL^+/]*,!W_EH9]_X9_
+M?_\D'23_*28L_V)H:O]\?X#_B8J+_Q<4&O\;%AS_>W=U_V]Q:/]B9&'_&AD@
+M_Q<6'/]%0#O_3TE'_QL5'?\5%QS_&B(F_SD[0/\9%AS_%!8;_T=)3/\/$!?_
+M'!PE_U!25_\V,3W_'QLC_V%?8?]855O_$Q 6_UA66?\>'!__'QT at _SLZ0/\8
+M%QW_%!$7_Q83&?\9%!C_$@P0_RHD*/]*1$C_4E!2_W1R=/]<6ES_6%98_TM-
+M4O]'2D__1DE._T)%2O\_0D?_.SY#_S@[0/\S-CO_+C U_RXM,_\N+3/_+BTS
+M_RLM,/\K+3#_+C S_RLM,/\@'B#_\_7R_SP^//\A'R'_CXJ._T]-4/\6%!?_
+M%Q48_Q43%O\C&Q__&108_QT@(?\6&!;_&Q\=_Y"1B_^BFY7_U<_-_];+RO_5
+MR<7_T\K$_\W'O_^>DI/_% \1_QD:&_\;%QG_&!,3_QD4%/\>&1G_%A$1_R4F
+M(/\R-2__0$,]_T)%/_\R,B__+BXK_R$@'_\1#Q'_(!L;_T1"._]$03;_7%)$
+M_WIK7O]31#?_0C,F_U-"-?]:2TO_'AD?_R,E*/]234?_;6)7_V582_]K7E'_
+M95Q5_U)-4?].2TK_:FAC_Q41$_\6$A3_&A<=_Q83&?\J'A__6#TL_TTX)O]H
+M7UC_;FIL_QX7(?\@'R;_4UM?_V%E9_^)B(?_%!$7_Q<3'/^"@(/_?X%^_V-C
+M9O\8%A__%!,9_TY,1_\6$Q+_&14>_Q at 7'O\8("3_5%9;_Q,0%O\@(B?_65I;
+M_Q,2&/\H)R[_9&1G_S0P.?\?&R/_9V5G_V%>9/\3$!;_5U58_QX<'_\C(23_
+M96-F_QP;(?\6%A__1TI5_R <'O]D7U__ at GU]_UU86/].3$__2DI-_T]/4O]&
+M1DG_0$)'_T)$2?\^0$7_/3]$_SY 1?\Y.T#_/D!%_ST_1/\]/4#_/S]"_SX^
+M0?\_/T+_/CY!_SP\/_\S,S;_(" C_QH6&/_V\O#_/SHZ_RTK+?\G)RK_FIB;
+M_Q at 3%_\8$Q?_&108_QP8&O\5$Q7_&AT>_Q at 6&?\?&QG_FI6/_YF4CO_6V=K_
+MS]/5_]#0T__-R,K_R[_ _V)65_]'0D+_?X%__V)?7O]34U#_0D(__S,S,/\N
+M+BO_.#LU_S0V,_\K+2O_(R,F_QP9&/\6$Q+_$0P0_Q40%O\@&1G_14,\_U93
+M2/]M8U7_@')C_W-E5O]N7$[_;UM-_UU.3_];5U__*"LP_T5"/?]G6U+_9EE,
+M_UM01?]*1D3_(Q\G_QH8&_]555+_'AT<_QH5%?\9%AS_&!<>_Q\9'?](+B'_
+M2C at J_U)33/]&14O_(!LG_Q<9(?]>9VW_8F=L_VAG9O\=&B#_&QLF_T)$3/\X
+M.CW_+2PS_Q at 6'_\6%1O_/$$]_PT/$O\4$1W_&!8?_Q$9'?]%1TS_&!4;_Q06
+M&_],3DS_&A@;_R,@)O]F9&;_+"@Q_Q\;(_]H9FC_75I at _R,@)O]&1$?_(1\B
+M_R0B)?]02DC_13\]_T9$1_\5%1[_8F1I_U!/5?],2U'_24A._TE+4/]&2$W_
+M/T%&_T!"1_]-3%+_-30Z_S O-?\M+#+_*RHP_RLJ,/\J*2__*2 at N_R<G*O\I
+M*BO_*2HK_RDJ*_\K*2S_*2<J_RHH*_\;&1S_&147__ST]_\G(B3_&1<9_Q87
+M&/^2D)/_'QH>_Q at 3%_\8$Q?_%Q(6_Q02%?\5$Q;_&108_T0\./^7D8?_F9B1
+M_\'$Q?^TN;[_K[.U_[:TM__!N;W_96-E_V=J:_]=8&'_,S8W_R0I*?\A)B;_
+M(",D_R,D)?\B("+_'1L>_Q at 6&?\6%!?_$ X1_Q,.$O\3#A+_$@T1_R(=(?\_
+M.3W_+"8D_UY72_]K85;_74] _WQD5?]^9%G_+1XB_R at C*?\W,S7_/CLV_V5:
+M3_]A5TG_5TQ%_SPV-/\:%A[_%Q@?_SP_1/\]/$+_'ALA_QP;(?\/#1;_)B(K
+M_RTB)_\E(AW_6EQ3_U-15/\;&"3_&1DB_UE<7?]77%;_6EQ9_QD9'/\9&![_
+M7F)@_V]Q;_]D9&?_&!<>_QP;(?\_03__*2DL_QD5'?\=&2'_/ST__QT:(/\9
+M%1[_%Q8=_S$P-O\;&![_'!H=_VII:/\B'RO_(!TI_U!+3_],1D3_*B(>_R@@
+M'/]/2D7_:&5 at _XF%A_]85EG_24=*_Q44&O])3%'_1DE._SP_1/] 0TC_/D%&
+M_T)%2O]%2$W_0$-(_T%$2?\_0$?_.CM"_SP]1/\Y.T#_.SU _ST_0O\O,33_
+M*RPM_RPJ+/\I)RG_*2<I_R at F*/\H)BC_*"8H_QT;'?\6$A3_^/#S_RDD)O\=
+M&1O_&QD;_WQW>_\6$17_&A49_QD4&/\8$Q?_&!,7_Q\:'O\F(27_2T5#_Y"+
+MA?^+B83_'Q\B_V)G;/]26%K_2DY0_S<W.O\K+3#_*"HM_R0F*?\:'!__%148
+M_Q04%_\9%!C_$PT1_Q(0$_\3$13_$0\2_Q$/$O\0#A'_$0\2_Q$/$O\0#A'_
+M$0X4_SXX0/\=%QO_)R,;_TI%.?]>4D/_;%E'_W5 at 5/\I(27_,BTS_T1 0O]"
+M0#W_55!*_U%,1O]'0D+_.C4Y_Q\;(_\7&!__4UA>_U-26?]/3E3_5U9=_Q at 6
+M'_\[.$3_,R\X_UM96_];7%;_6%99_QH7(_\9&!__6UQ=_U]C6_]@8F#_&!<=
+M_QH9'_]?85__8&)?_UY>8?\8%Q[_%Q8<_T5$0_\V-#?_&!0<_QT:(/]K9F;_
+M;6AN_QD5'O\<&R+_;VQR_QT:(/\C(23_5U57_R8@)/\L)"C_4DU-_UM65O^ 
+M>WO_A8""_T1 0O\T,C3_)"0G_Q\>)/\;&B#_$A$7_R(B)?\H)BG_*RDL_S(P
+M,_\R-#?_-SD\_SD[/O\Z/#__.3M _S at Z/_\V.#W_-3<\_S(T-_\L+C'_*"HM
+M_R<I+/\J*"K_*"8H_R at F*/\H)BC_)R4G_R<E)_\F)";_*"8H_QD5%___]OG_
+M(!@;_QX9&_\9%1?_&108_Q<2%O\<%QO_&108_Q81%?\6$17_%1 4_Q at 3%_\7
+M$17_(!L;_Q<4$_\7%!K_'B E_QX@(_\H+"[_&Q\A_Q$1%/\1$13_$! 3_Q 0
+M$_\2$!/_$PX2_QH4&/]P:&S_%Q(6_Q(0$_\1#Q+_$0\2_Q$/$O\0#A'_$0\2
+M_Q .$?\9&1S_3TM3_S<R./\C(!O_/3LS_U=01/]:4$'_7E=+_QH5&_\8%!S_
+M.#8Y_SP[.O\^04+_45-8_U%26?\L+33_'QLC_Q<8'_]A9FS_:&=N_VUL<O]O
+M;G7_%A0=_QL8)/]=6V3_9F9I_V=H:?];6F#_&!8?_QH9(/]C8V;_:&IH_V5F
+M9_\6%1S_%!,:_U976/]?85[_5E99_Q85'/\9&![_0#\^_R<E*/\:%A[_(A\E
+M_V=C8?]A7&#_'!@@_R$@)O]'14?_'AP>_R at F*/]>7%[_>G5P_ZFAG?]W<G3_
+M6UA>_U157/].3E?_1$9._SU#2_\X.T#_.3Q!_R\R-_\I+#'_*RDL_R\J+O\M
+M*"S_+2 at L_RLI+/\H*"O_)B8I_R8F*?\F)BG_)24H_R at H*_\G)RK_)R<J_R0D
+M)_\D)"?_)24H_R at F*/\G)2?_)2,E_R4C)?\E(R7_)2,E_R at F*/\B("+_+2DK
+M__SP\_\>%!?_,2DL_RPG*?\<%QO_% \3_Q40%/\4#Q/_%1 4_Q40%/\4#Q/_
+M%Q(6_Q,/&/\7$AC_&!,7_Q at 1&?\3#!/_%Q$5_Q40%/\1$13_$A 3_Q(0$_\1
+M#Q+_$0\2_Q 0$_\-#Q+_%1,6_R ;'_\5$Q;_$A 3_Q$/$O\1#Q+_$0\2_Q .
+M$?\1#Q+_$ X1_Q$2$_\8%Q[_&!0<_R$='_\1#Q'_2D9$_U502O\C(B'_$Q$:
+M_Q43'/\M+#+_4U15_TU05?]665[_7EUC_S M,_\<&"#_%Q@?_UYC:?]B86C_
+M8F%G_V-B:?\8%A__%Q0 at _UY?9O]@86C_8&%H_U166_\;&B'_&!<>_V5D:O]E
+M9&K_7UYD_QD7(/\<&B/_34U0_S$S,/\G)RK_&QHA_QD8'O]!0#__+2LN_R <
+M)/\G)"K_0#TX_T(^0/\A'B3_'Q\B_V1E7_^"@WW_EI64_V=E:/]565O_55A=
+M_TY05_]*2E/_2$=._T9'3O]%1T[_049,_SY#2/] 14K_/D-(_SU"1_\^0$/_
+M/CY!_S0T-_\O+S+_+"HM_RLI+/\J*"O_*B at K_RLI*_\H)BC_*2<I_R at F*/\I
+M)RK_)B0G_R4C)O\E(R;_)B0F_R0B)/\D(B3_)"(D_R0B)/\D(B3_(B B_R8D
+M)O\2#A#_^_+R_R8;(/\;$AG_%Q,5_Q at 3%_\5$!3_%1 4_Q40%/\5$!3_%1 4
+M_Q0/$_\7$A;_%Q,5_Q<3%?\5$!3_&!$;_S0J.?\:$QO_%1 4_Q0/%?\1#Q+_
+M$A 3_Q$/$O\/#1#_#0T0_Q 0$_\?'"+_&Q<?_Q81%?\5$1/_$P\1_Q00$O\2
+M#1'_$PX2_Q(-$?\3#A+_$1 7_Q<3&_\8$AK_&1$5_QD4%O\M*"C_14$__STZ
+M.?\6$AK_&!0=_RDF+/]245#_35%/_U%34/]24TW_)R0C_R <)?\='"+_6UU;
+M_V-B8?]=6UC_9V-E_QD5'O\:&"'_6EIC_V)C:O]H:7#_1450_Q46'?\:'"'_
+M7U]H_V1D;_]B8FW_$A(=_QL;)/]A8FG_7F!H_V%?:/\?&R/_'!XC_SY /O\Z
+M.#K_'AP?_R at E*_]:55#_8%M6_W9R</]D86#_5EA;_U=97/]:7&'_45-8_TQ1
+M5_]*3E;_14E1_TA*4?]%1T[_149-_T-%3/]%1T[_0D5*_SP_1/\]0$7_041)
+M_SU 1?\^0$?_/#Y%_SP^1?\X.C__.CD__RPK,?\I*"[_+BPN_RHH*O\J*"K_
+M)R4G_RDG*?\E(R7_*"8H_R4C)?\F(B3_)R,E_R(>(/\E(2/_)B$E_R,>(O\W
+M,C;_)!\C_Q81%?_Z\?'_(!<>_QL4'/\;%AK_&!,7_Q40%/\5$!3_%1 4_Q40
+M%/\5$!3_% \3_Q<2%O\7$Q7_%Q(6_Q,.$O\8$QG_'!4?_Q at 3%_\5$A'_%! 2
+M_Q$/$O\2$!/_$Q$4_Q,1%/\3$13_%!(5_Q82&O\<&"'_&Q8:_QP8&O\?&QW_
+M&Q<9_Q<2%O\5$!3_%1 4_Q0/$_\3#Q?_%Q,;_QX9'_\?&1W_'1D;_R,@'_\G
+M)"/_(1X=_Q82&O\8%!S_(!XA_TM+2/]-3TS_3E)*_TY/2/\<&!K_'A<A_QL8
+M'O]65E/_6EI7_UQ95/]955?_&!0=_QH9(/]@7V7_75Y?_V%B8_\]/$/_%A<>
+M_QL=(O]A8FG_8F)K_V%A;/\7%R#_(B,J_TY05?]355K_5U)8_R<?(_\E)"/_
+M6UM8_UU>6/]K:FG_E9.5_X2 @O]95E7_6%A;_U-56O]04EG_3E!7_TM-5/])
+M2U+_2TU4_T=)4/]"1$O_1$9-_T1&3?]#14S_04-*_T%#2O\^04;_0$-(_T!#
+M2/]!1$G_/#Y%_ST_1O\]/T;_/D!'_ST_1/\\/D/_/3]$_S at Z/_\R,#/_*B at J
+M_RLI*_\H)BC_*"8H_RDG*?\G)2?_)"(D_R<C)?\H)";_*24G_RDE)_\E("3_
+M&!,7_Q<2%O\8$Q?_% \3___U^O\O)2[_1SY+_R$<(O\:%1G_%A$5_Q40%/\8
+M$Q?_%A$5_Q81%?\5$!3_&!,7_Q<1&?\7$AC_#0@,_W9R=/])1$K_&147_QH8
+M$_\8%13_$A 3_Q43%O\5$Q;_$Q$4_Q,1%/\-"P[_&14=_QT9(O\=&!S_&!06
+M_Q,/$?\4$!+_%Q(6_Q81%?\9%!C_'!<;_Q00&/\7$QO_'ALA_QT;'O\A'R'_
+M,2\Q_S\]/_],2DS_%Q,;_QD5'?\E(R;_45%._U%34?]/4DS_4E)/_QT8'/\C
+M'";_&A<=_UE95O]555+_5E-._UA45O\;%R#_&1@?_UA75O]96E3_6%E2_R4C
+M)?\<&R'_&QH at _UQ;8?]=7&+_86!F_Q<6'/\D)"?_5UA9_U!03?]744__7E94
+M_U924/]Z?7?_8&-=_U=95_]65UC_3%%6_TM/5_]*4%K_1TI6_TY06/]*3%/_
+M1TE0_T=)4/]%1T[_1DA/_T=)4/]$1DW_/D!'_T!"2?\[/43_0T5,_T!#2/]!
+M1$G_2DU2_SY!1O\_04C_/T%(_SY 1_]"1$O_/D!%_SY 1?\_04;_/D!%_SHZ
+M/?\R,C7_+2TP_R<G*O\K*2O_*"8H_RHH*O\C(2/_)2$C_RDE)_\B'B#_+BHL
+M_QD4&/\4#Q/_&!,7_Q,.$O\8$Q?_^>[U_SXT/O\F'"O_'QDA_QD4&/\6$17_
+M%1 4_Q<2%O\:%1G_&!,7_Q40%/\8$Q?_%Q03_Q<3%?\:%1O_'1<?_QL4'O\L
+M)RW_(1T?_QP7&_\5$Q;_'AP?_QT;'O\<&AW_03]"_TE'2O\:%A[_'AHC_QT8
+M'/\8%!;_'!@:_Q\;'?\@&Q__(ATA_R0?(_\H(R?_&1,;_Q at 4'/\='R3_2T]1
+M_TU/4O]04%/_45%4_U145_\7$QO_&14=_R\M,/]I:6;_5597_U%34?]14$__
+M'!<=_R,<*/\8%1O_6%A5_UA85?];6%/_5%!2_QL7(/\;&B'_6%98_UM:4_];
+M653_)2(A_R$=)?\<&1__7UU at _T=%1_\M*RW_(B B_R at G)O]24TW_>7YX_Y&1
+MCO]O:FS_5U=:_U)45_]14U;_4%)7_TY/5O])4%;_2$]5_T1(4/]%1E'_1DA0
+M_T=)4/]&2$__1$9-_T%#2O]$1DW_04-*_T!"2?] 0DG_04-*_T1&3?]!0TK_
+M/D%&_T)%2O]!1$G_1$=,_T%#2O]!0TK_/3]&_T!"2?] 0D?_/D!%_S]!1O\^
+M0$7_.3M _ST_1/\\/D/_.CQ!_ST[/O\W-3?_,C R_S N,/\M*2O_)B(D_Q82
+M%/\7$Q7_%1 4_Q(-$?\7$A;_%1 4_Q81%?__^?C_(1,4_RD;(_\;%!S_&Q8<
+M_Q<2%O\<%QG_(AH=_QX7%_\=%1C_%Q(4_QD4&/\6%!;_%Q47_Q,0%O\7$QS_
+M&A,?_QT7&_\A&AK_%1,5_QP9&/\Z-S;_/#H]_T5$2O])24S_3T]2_QT9(?\C
+M'";_(APD_TE&3/]'1$K_1$)%_SDW.O]$0D7_3DQ/_U%/4O\9$AS_&Q0>_RDE
+M+?]45EO_55=<_U577/]<7F/_7%YC_Q41&?\:%A[_(B$H_UE87O]56%W_6%Q>
+M_UE;7O\8%1O_(!PD_Q<6'/]14U'_7%I5_U=63_]345/_&A8?_QX:(O](1DC_
+M/3XX_TE*1/\I)RK_(AXF_R0C*?]:6US_6UE6_UY85O^!?'S_ at 7Y]_UY?8/]0
+M5%;_5%=<_U-56O]25%O_3E!7_TM-5/]&2$__0T5,_T1)3_](25#_2$=._T9'
+M3O]*3U7_24I1_TA'3O]#14S_24M2_TA)4/]&1T[_0T1+_T)$3/] 0DK_0T5,
+M_T9)3O]%2$W_1$=,_T!#2/]$1TS_04-(_T-"2/\_/D3_0T)(_T%#2/\Y/$'_
+M.T!%_T _1?\^0$7_.CQ!_SH\0?\Z/$'_.SL^_S\]0/\5$Q;_)2,F_Q<5&/\T
+>,C7_%Q48_R<E*/\4$A7_$A 3_Q02%?\3$13_%1,6
+ 
+end

Added: vendor/Python/current/Lib/test/testrgb.uue
===================================================================
--- vendor/Python/current/Lib/test/testrgb.uue	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/testrgb.uue	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,971 @@
+begin 644 test.rgb
+M =H! 0 # 'T :0 #         /\     3FEE=7=E(%-P:65G96QS=')A870 
+M                                                            
+M                                                            
+M                                                            
+M                                                            
+M                                                            
+M                                                            
+M                                                            
+M                                                            
+M                                                            
+M                                                            
+M                          O8   -6@  #MT  !!@   1W0  $UH  !36
+M   65@  %]D  !E9   :W   '%\  !W?   ?8@  (.4  ")H   CZ@  )6L 
+M ";J   H;   *>\  "MR   L]0  +G@  "_Z   Q?0  ,P   #2#   V!@  
+M-XD  #D+   ZC@  /!   #V3   _%@  0)D  $(<  !#GP  12(  $:E  !(
+M*   2:L  $LN  !,L0  3C,  $^V  !1.0  4KP  %0_  !5P@  5T4  %C(
+M  !:2P  6\X  %U1  !>U   8%<  &':  !C70  9.   &9C  !GY@  :6D 
+M &KL  !L;P  ;?(  &]U  !P^   <GL  '/^  !U at 0  =P0  'B'  !Z"@  
+M>XT  'T0  !^DP  @!8  (&9  "#'   A)D  (8<  "'GP  B2(  (JC  ",
+M)   C:<  (\J  "0K0  DC   ).S  "5-@  EK4  )@U  "9LP  FS(  )RS
+M  ">-   G[,  *$N  "BIP  I"@  *6E  "G)@  J*(   Q8   -VP  #UX 
+M !#?   27   $]@  !56   6UP  &%D  !G:   ;70  '.   !Y@   ?XP  
+M(68  "+H   D:P  )>H  "=J   H[0  *G   "OS   M=@  +O@  #![   Q
+M_@  ,X$  #4$   VAP  . D  #F,   [#P  /)$  #X4   _EP  01H  $*=
+M  !$(   1:,  $<F  !(J0  2BP  $NO  !-,0  3K0  % W  !1N@  4ST 
+M %3   !60P  5\8  %E)  !:S   7$\  %W2  !?50  8-@  &);  !CW@  
+M96$  &;D  !H9P  :>H  &MM  !L\   ;G,  &_V  !Q>0  <OP  '1_  !V
+M @  =X4  'D(  !ZBP  ? X  'V1  !_%   @)<  ((:  "#FP  A1H  (:=
+M  "((   B:,  (LD  ",I0  CB@  (^K  "1+@  DK$  )0T  "5MP  ES8 
+M )BV  ":-   F[,  )TT  ">LP  H#0  *&L  "C*   I*<  *8F  "GI   
+MJ2$   S9   .7   #]\  !%>   2VP  %%<  !76   76   &-D  !I;   ;
+MW@  '5\  ![A   @9   (><  "-I   D[   )FD  "?K   I;@  *O$  "QT
+M   M]P  +WD  ##\   R?P  - (  #6%   W"   .(H  #H-   [D   /1( 
+M #Z5  ! &   09L  $,>  !$H0  1B0  $>G  !)*@  2JT  $PP  !-L@  
+M3S4  %"X  !2.P  4[X  %5!  !6Q   6$<  %G*  !;30  7-   %Y3  !?
+MU@  85D  &+<  !D7P  9>(  &=E  !HZ   :FL  &ON  !M<0  ;O0  '!W
+M  !Q^@  <WT  '4   !V at P  > 8  'F)  ![#   ?(\  'X2  !_E0  @1@ 
+M (*;  "$&@  A9L  (<>  "(H0  BB0  (NC  "-)@  CJD  ) L  "1KP  
+MDS(  )2U  "6.   E[<  )DW  ":M0  G#0  )VU  "?-   H+4  *(K  "C
+MJ0  I28  *:G  "H(P  J:(   "     @0   ($   !_    ?P   'X   " 
+M    @0   (    "!    @0   ($   "!    @0   ($   "     @0   '\ 
+M  "     @0   ($   "!    @0   (    "!    @0   ($   "!    @0  
+M (    "!    @0   ($   "!    @0   ($   "!    @0   ($   "!    
+M at 0   ($   "!    @    ($   "!    @0   ($   "!    @0   ($   "!
+M    @0   ($   "!    @0   ($   "!    @0   ($   "!    @0   ($ 
+M  "!    @0   ($   "!    @0   ($   "!    @0   ($   "!    @0  
+M ($   "!    @0   ($   "!    ?P   ($   "!    @0   ($   "!    
+M at 0   ($   "!    @0   ($   "!    @0   ($   "!    @0   ($   "!
+M    ?P   ($   !^    @0   '\   "!    ?@   '\   "!    @0   ($ 
+M  !_    ?P   '\   "     @0   (    "!    @0   '\   "!    @0  
+M ($   "!    @0   '\   "!    @0   ($   "!    @0   ($   "!    
+M at 0   ($   "!    @0   ($   "!    @0   ($   "!    @0   ($   "!
+M    @0   ($   "!    @0   ($   "!    @0   ($   "!    @0   ($ 
+M  "!    @0   ($   "!    @0   ($   "!    @0   ($   "!    @0  
+M ($   "!    @0   ($   "!    @0   ($   "!    @0   ($   "!    
+M at 0   ($   "!    @0   ($   "!    @0   ($   "!    ?P   ($   "!
+M    @0   ($   !_    @0   ($   "!    @0   ($   "!    @0   ($ 
+M  "!    @0   ($   "!    @0   ($   !_    @0   '\   "!    ?P  
+M ($   "!    @0   ($   !_    ?P   '\   "     @0   (    "!    
+M at 0   (    "!    @0   ($   "!    ?P   ($   "!    @0   ($   "!
+M    @0   ($   "!    @0   ($   "!    @0   ($   "!    @    ($ 
+M  "!    @0   ($   "!    @0   ($   "!    @0   ($   "!    @0  
+M ($   "!    @0   ($   "!    @0   ($   "!    @0   ($   "!    
+M at 0   ($   "!    @0   ($   "!    @0   ($   "!    @0   ($   "!
+M    @0   ($   "!    @0   ($   "!    @0   ($   "!    @0   ($ 
+M  "!    ?P   ($   "!    @0   '\   "!    @0   ($   "!    @0  
+M ($   "!    ?0   'X   !\    ?0   '\   !_    ?P   'D   !\    
+M?P   '\   !_    ?P   ('J^!0C'!P6&1T7&!08%A<6'!\;&A48-CU*3%(A
+M)B1,2D4Z14]2'!XM6UQ<8V,9'BA>75Y>&R0<455/4Q\B2#A$*B8I7%96?'U@
+M5EQ:6U=43TQ/4$Y.55%.3%)03DM,2DQ.34Q(3$A(1$A(00-% T&+/D 6)A at U
+M&"@5$Q4!% $6 .WY$QL4%A(7&A<5$A04%1 3$Q<:$QDW.D1)3QD<'$9$0C="
+M3$\2%"565U=>7A$6(5A87%L5'!936E91%AI&/DHG'B-;65A\?E]45U544$U(
+M14E)1T=/2D=%2TE'1$1"14E(1T-'0T(^0D,\0#]  SR+.ST3(Q4R%242$!(!
+M$0$3 .W_(2D;&Q<<(AX=%QD6%Q,7&ATA%1PZ/$5)3QTC(DE'1#E$3E$9&RE4
+M555<7!4:(EE56%D8(!=17%=3&AY(/4DI(B1:6UZ!@5Y05%-23DM&0T1(2$9*
+M24A#24A&0T) 0T9%1$!$04,_0T$Y.T ^ SJ+.S\5)1<T%R<4$A0!$P$5 /OU
+M/BLA&!44%AD7%!<3%1L?'BT?&Q8?'AU"2AXC'!8:'1\A(R<;'"114E-45QL=
+M,&9744\=*!M555-2("%84U0A)1]@1RTB)DUXCFQ:5U975E954%%04$]-2DU*
+M24E*34I&2DE,2DI&24=%1D5 1$-!/C<R,"LD%!44$18!% $5 +;N-!P9%!$0
+M$A43$!,4$Q47%"<=%Q,<&QH_1Q8:&!08&QL='R,3%!]/3U!15!,5+6E64U 7
+M'!4#6,)0%QI66EDB'1E=12L@)U-^D6I75%-23U!/2$9(24A&0T9#0D)#1D-!
+M141'0T,_0D) 04 [/SX\.S4P+BDB$A,0#1(!$ $1 /OY/B8?&185%QH8%1 at 7
+M%QH=&RPA'!4>'1Q!21H>'1@<'R B)"@9&!U+35!15!<9+VE545$<(QA86%M4
+M&QM86ULE(1Q?1RTB*%)YD6]74E%03DE(1$5&1T9$041!0$!!1$$^0D%$04$]
+M0$ ^/SXY/3PZ/3<R,"TF%A<5$A<!%0$6 /OZ+DLB&144%Q45%!<9& QT2A<3
+M%!,6%A04#ATB'!81$A85&!L8&R$>(3$_3!L=)DY13$\<)AU64DY6(!]65%(E
+M(2!A8F8<)UE-3U10=UU76%976E984U!03D]034=)1$Q(25)&2$A'2T5%1D4]
+M-3 J*R at J(R,G("P8$Q<!$@$7 ./U)3X<%1$0$Q$1$!,1$@AR1!48%1 3$Q$1
+M"Q49&!0/$!(1%!<0$QL;'R\]2A,5(U%34E(8'!=955-4%QA76EDC&QI;7& 6
+M)%A04592?6-95U%/4$I03$E)1TA)1D!"/45#1$T#095 1$! 04 Z,BTG*28H
+M(2$E'BH4#Q,!#@$3 /O_+T<A&A85&!86%1 at 7%PUV21D:&!(5%1,3#1D='1 at 3
+M%!<6&1P4%QX=(3$_3!<9)5%13U(=(QI95598&QE865 at E'!M<76$7)%=05UY6
+M>F!75DQ+2D=.2D='149'1#Y .T- 04H^/S\^0CX^/SXZ,BTG*R at J(R4I(BX9
+M%!@!$P$8 (7Q'AP:%P44C!,6%182&1\7$1(2$P,4XA4:(1H:'1D6%!03%QL?
+M'1L?(QT:'"%(3$I(&B$>4U=45QT at 95]C0QXB:6ML("I56E at C(UA8:96"55M:
+M65=44E102TU-3$I*1DA(245&1D=$0T0_,RHK*"@I)R0E)B<G)!<6 1<!$P"%
+M\1<4%A,%$(P/$A,2#A,5$Q(0#Q #$8T2$A at 6&!L7$A 0#P\3 QG2("0>$A0>
+M2T]23Q at 7&%9:6544&5]>8CP7'6)B81<C4%52'R1;7FJ3@%9855)034M-241&
+M1D5#0T%#0T0^/S] /SX_.C H*28F)R4B(R0E)2 3$@$3 0\ A?H@&QL8!16!
+M% ,7B!,8'!@5%!$2 Q/B%!8<&QP?&Q<5%103%QX?'2,G(188($M-3DX<'AM6
+M6EQ9&!I at 76$]%AMA8F$7(DY35R<E6UUKE8196%-03DM)2T="1$1#04$^0$!!
+M/#T]/CT\/3 at R*BLH*"DG)"<H*2DE&!<!& $4 (7R(!D5%P44\1,6%144&SD;
+M%!42$Q(0$!,B'Q43$1(1$A$2%QL:%18H/SD:'2Q03U!-(R4B6V%891XA8VIP
+M4!TA:&]M'21I:&@C(SXZ'RM05G!@6UQA6%=645%.34Q.2D1%245'144_/S$N
+M+BHJ)RDE*"4D)2 C)2(V 2,!%0"%\AL2$Q,%$/$/$A,3$!$J$Q /#Q /#0T0
+M'!<1$0\0#0X-#A 3$A$4*$$Z$A0F45%34R0<'%UB6V,5&%IC:446'%]D8A(;
+M8F!?&QY .!PE55MR85A97%-13DE*1T9%1T4_0$1 0#X^.CDK*"PH*"4G(R8C
+M(B,>(2$>,@$? 1$ A?LF&Q<8!16!% ,7[148-!H5%!$2$0\-$!\;%A43%!(3
+M$A,1%Q at 9&2U%/188*5)-45(G(!U;8UUG&1I:8FA%%1I?9&(2&V%>81\</CH>
+M*%I@=F165UI13$I%2$5%0T5"/#U!/3X\/#@Z+"DN*BHG*24H)28G(B4F(S<!
+M) $6 )[S%RPI&Q,4$Q04$Q88&!<9$Q44%!,3$A(3$A8?%A,#$KL1$A$3'AP?
+M$41*(1H<,E557F,S(!]I:&=I'R!F:&A;(1YJ:F0@(U P*B$>/RXD*CA )")?
+M?91H6UU74P-.BTQ(2DA'0T$W,BTL RN%*"DH*B<#)@4D at 2(!)@$0 )[P%"DG
+M%P\0#Q 0#Q(/$A,1#!$0$1 0#P\0#Q,;$Q ##[L.#PX2%Q0=#T90(A$3+%10
+M65TM&!AC86%B%A1?86%6&A=D9%X7&DTS)QH80"L<)#T^'A]E at Y5E65A02@-'
+MED9#14-"0#XT+RHI*"@I)B<F)R0C(R0%(H$@ 20!#@">_!XQ+!P4%105%107
+M$Q<8&!,7%1$2$A$1$ T5(!42 Q'4$!$0$1 at 8(1%*52,3%2U3359>,!P77F)B
+M8Q at 77F!@5!L8965?&1Q-,2<;&4$M("= 0B$?9(*69U553DI(1D5!/D ^/3X^
+M-"\L*RHJ*R at I*"DF)24F!22!(@$F 1( EOD;&Q<8%AL8%144%Q4;$QHE(RXA
+M%!0#$X42&&P6$P,2Q1$2$1Q3.!LS1$%+&QPY.D)8630C'VQN<G4=)&1I:6 ?
+M(&9H9QP:6%Y9'!X^*!XE86 @)D<>*%YPG71>7%=.2T!!-S$L+@,L at 2L#*8DH
+M*RHJ)R<H*"<$)8$H 2(!*P"6]A at 9%102%Q01$1 3$1L4%" @+!\1$0,0A0X4
+M:!(0 P_)#@\.&4LR(#M04%<5%#8[05-2+1L89F=L;A086V9H6A898VIF%1-7
+M8585&#\E%A]C7!@@11PF7'6A<EA53D9#.SPR+"DJ*"@I* ,FB24H)R<D)"4F
+M)00C at 28!( $I )[_(!X9&1<<&186%1 at 7(!<7'AXH&Q$1$! 2$QIP%Q(#$<D0
+M$1 93S<C/5=:7AH8.#P^45$L'Q=A:&UO%AM=9F=;&!IC:&46%%9?5A890"<:
+M(F=A'"%''BA>>JEW6U1.1#TX.2\I*R\M+2LH R:))2 at G)R0D)2 at G!"6!* $B
+M 2T ]?,F&QM[%1D8%Q<>)4.%A")L6E Z,"TI'Q at 7&!$3%!(2$1(2$11 &QLY
+M0T=4)3-"/4I&0CDC'UY95%T?1#A;5EDC'UU;8!T?7U]A'AQ#-QP at 9FX>(G(@
+M)%<D*$U6>X)"-"<D(!<E*2PS-SP^/T _/3PW,2TL*@,H at R<G)@$H 1< ]? D
+M&1EW$144$Q,:(46+B1]G6$XW+2HF'!44% T0$0\/#@\/#@XX%R-%4EE@(2U 
+M0%!,0C4;&%A23E86."]97%87&%QC8A<986)>%Q9$-!0:9F at 5&VP:(54@)$U6
+M>X! ,B0>&A$B)BDP-#D[/#LZ.#<T+BHI* ,F at R4E) $F 14 ]?@I'1M\%AH9
+M&!@?)DN0BQ]B4DHW*R at D&A44&1,2$Q$1$!$1$!$^'2=*7FQU*3)$0E511SH?
+M%U-33U<8.S-;6U@:&5M?8!@:7V!>&!=%-A@=:VT9'&\=(U<F+%);@(5$-"0?
+M&Q(B*"LR,C<Y.CDX-C4R+"@G*@,H at R<G)@$H 1D ^/<D&1B3'A<7%A46&#B'
+MD<6^M;>]96MA-RDF)"4B'AD7$1(2$2$])$M60%59(BDU-D])130>'T1"(2$6
+M*R<=4U0D(EU661P>8&]G'B$_+!TA/R >'38>'6 at K*4]$'AQ%8(=92AI13D1(
+M1DI-2$E'0D1 0$(T+2PI*0,H 1T!% "@]"(7%Y :$Q,2$A,4/)&8Q+FSM+EC
+M:F V*28C)" ;%A0##I at -'3DF5V%/9&0>(S,[6E=,-A88/SP;&PT#(H1<41 at 9
+M URS&1AB<607&T$I%1D]&A46,!@::1\=2T8B($IEA59'%$Q)/T-!14A#1$ [
+M/3L]/S$L*B<G R8!&P$2 /C\)QD6DA\8&!<4%1E$EYG!M*^VP65G73,D(2 C
+M(AT8%A 3$Q(B/RQ>:UU\?BTH-SYE85<\&A<\/1X<#R8M)5I3&QE95UH9&5YO
+M9!@</RD9'3\=&1<Q&QQJ(B!03"HH3VB)6$D5248\0#Y"14!!/SH\.3L]+RLL
+M*2D#* $= 18 ]? Z+2J;%Q<8&A4>&1F/CMK5T\K 5T)_7E _,"LU,RLF&!(0
+M%AD\2%5C5DY-3U\P/5),140G&U(<%1P>'2$J3$LG(6UL9B F3#TS'QL]$AT?
+M'4P;&TP;)F8Q(VA@)D<B)4@]1QYI55%.4$U&1U(Z-3(P,"\N*@,K at RPJ*P$<
+M 1< PO(Z*R>8$Q,4&!,=%AN5E-G3T,B_5D*!7U-",RX[-BTC&1,,$!E#4V-R
+M95Q;3E<K0EM94$8?&%4=%187&2XX4T4;&0-GL!H;1#HL%A5!#Q$6&4<5%DX8
+M(&0H&V9:($0?(DH_1!5D3TM(2TA!0DPT+RPJ*BDH)P,J at RDG* $9 14 ]?8_
+M+2>:&!@9'!4:&!^:F=;/T,W+8D=_8E-",RXX-"LC'!81%2!%5FV <VYO75LH
+M16=F6THC&E4>&AD8'TA*4D8@%UYB:!T;0C at M&!8\#108$448%$P:(V8L'VA=
+M(T8A)%!%1A5B4$Q)248_0$TU,"TK*RHI)P,I at RLI*@$; 1D ^_(\(8Y0%Q at 6
+M'Q at A%AV+E<W*Q<2_DQ$;&1,4&1$@+ST_+RL?$1L[-D1>-R8U2Q\H1U=+4551
+M2F,3%!T9'RPF6&PA)E]GAQ<<@WYF'QE'$AX>)%L6)UL8+F<Y(V=D%E@?)&8A
+M'U4>7WU83TU224=)141%0$5$0$)!0D$_-@$C 1@ ^_4^'XI-%!43&Q0@&!^1
+MF\_+R<K'D@\:%Q,4&1$F-4-%,BX@#QM"05)K1#-"2QDE36)87EQ-2V at 1$A<3
+M'CTX7VH7'UMEB!$3@(%C%A-,$Q47(%80(EH2)V0P&V5>$%4<(6,;%DH<7WU8
+M3$I/1D)$0#] .T _/3\^/SX\,P$@ 18 ^_,\(8]/%A<5(QD=%AN0HM76U=/-
+MGA09&Q at 9'A8E,D!",BXA$2!$1%QZ4T)36AXC4FUE:V523FH5%AH6*EA-:&X>
+M(%-AB107 at G]C&!1.%AD8&%03(%D3*&0T'V=A$U<>(V4<%D<@9()=3DI/1D!"
+M/CT^.3X]/3\^/SX\,P$@ 1H ]?<G&!PP&QD7)!L9(2"-D,G)Q\2]F!8<%QH8
+M&A43'QHA&#TD%1A 2%%</BT\4Q889%%32EM+8%$0%!@<,2P=?7\D+&J BQH<
+M=6AA(!P[1QT<)D <&TP7)5<](V%;%ED?($ =%QD8$"A(4G1<6%)/3DI'0T [
+M-0,S at S P,P$P 2  ]?HH%ADM&!84'188)A^.F,[+R\K%EQ(9$Q at 6&!,2'ATG
+M($,G%QI'4U]F2#A'4Q(:;%M at 6F909U@.$!(:-CXPAG\=)FA_BA06=W%D&19 
+M2147(CL6%DD0'%(Q&U]5$%8<'3H7$1,4#"1$4'):5DU*245"/CLV, 4M at 3 !
+M+0$> /3\*Q@;+1 at 6%!X4%2D>CY[3T]73RZ,8&1@<&AP7$1T;)!Q )14>259I
+M>%A%4F(:&')E;6IS56E:$Q45'T5;2I:&)"EB?(D7&WMO8AH714\;%1HY&11'
+M#QQ0-A]A6!-8'A\[&!06&1(J2E)T7%A+1T9"/SLX,P0N at RLK+@$K 2  ^_4J
+M''^5&B!G<AHH$"J+C,;0S,Z\G1X>&!<5&!(3(1H>)SLL+"DV1U!&-B](31(3
+M8UAA7&I65&89%A,9.2TE=84K95943 at PD/TTE(QU 3AP<-%T>&TD;*$LT(DY2
+M%UD?%Q 8%1H<%Q\A'2$@4W1;4U!-24A)2$E(2$1#0 $\ 14 ^_0G&7Z4%QUE
+M;!4G%"B+E,W1S-# FA<8$A84%Q$-&QD at +4$P,"L\45Y00#I34A 0:6)N:W=<
+M7&P6$! 904,W?8<D7U13308A058H'1=&4!86,%@8%D86'48K'$Q,$58<% P6
+M$QH6#Q<9&AX=4'%944Y(1$-$04)!03]!/@$Z 1, ^_\O&7N3%QUI;1(F'"R0
+MF,[4T=;*IAX;%143%A .'!@>*#PK*R]!5VAB4$5=7Q40;FQ[>81C8'$>%1(@
+M5&%4D(\K8%!03 <C15(F'AA-6!L7*%8;%$04'40M'TY/%%@>%A$:&"$;$QL=
+M'" ?4F]534I#/SX_0$-"0CT].@$V 14 ^_4U*6J0'2R4>QL?'1^0CL7/S\;'
+ME!<;%1<8&A,3&QP<)CPO*"TD/4EJ.#$[5A4M/5AC9W!>5V at T'QLB'BP>JE\O
+M:6UA7#]#-%46$"$TB",F.V49($PC("<B'4E+%U0B$Q47$QH<&!DA'1<>'B4E
+M1W5B55%*2$5#0C8V.0$T 1H ^_(O(VJ2&2B5?Q<9&QZ0E<K/S\K,E!49$Q46
+M&!$1&1H:+#XO+#0J15-S03M%8QDK1&5P<GMH8G R&1DH*$(OKV$M9VQ?6CU!
+M,E,3#1XYB!L at -F 3&TL=&"0?&D9($4X<#1$3#Q86$A,;%Q$8&",C17-?4$Q%
+M0T ^/3,S-@$Q 1< ^_HT)&^6'BV at BQT:'1V5GL_6V-38G1H=%1<8&A,3&QP<
+M)SDJ)C4O2UM_345-<"$O3W)]?89P97(V'!LM.F)(OFDQ8V%95#<[+$\1#2 \
+MC2$C,5X6&4H@'"8A'$A*%%$?$!88%!L9%18>&A0;&R4E1W5?3DI#03X\.S$Q
+M- $O 1D ^_-(,!IE(R4=&18?&BZ(CL7+SL[%ER$;%A<9&A,2&AP:)CHO)RXC
+M-#D]$AP9)#A-65%;8&AG6& P(2(B&!H5PXH87&=<86M?/T\6$A<O1R(;/F-<
+M-U(5)!@7'!<A&"<7(1D9%1,:&1L8&1<9'!@D&2<W4V5*3TE&0T=$0 %# 3P 
+M^_!"*AIG'R(@'A,9%RR(E<K+SM+*EQ\9%!47&!$0&!H8+#PO*S$F.3\_$AP9
+M*CQ-7UIF;7=Q8VLS'B D'BLAQHP:7VQ at 96]C0T\3#Q0T1QH5.5Y6,E$/'!44
+M&10>$B$1&Q45$0\4$Q42$Q$3%A <$1\V56=,3$9#0$1!/0%  3D ^_A'*Q]O
+M)" @(14:'RZ-GL_2U]S6H"0=%A<9&A,2&AP:)S<J)2\H/$1'&R,>,T12:&9Q
+M>H5Y9FPU("(H+48XU)0>76%:7VE=/4H1#Q8W3" 8-%Q9,% 2(!<6&Q8@%204
+M'AH:%A07%A at 5%A06&10@%2,U4V5*2D1!/D(_.P$^ 3D KO8H)HEM*1FUL1L=
+M%Q6-CL#/U,[!EQP5%189'!,3&AL;(S at S*"\D0#M534 Q+B4$&<D?;%Q:83P<
+M&2\;)QV\=1DL.DPK8W\3N" 9'2&X8AX\/R(O0AHK% TS%Q,B&Q84%Q at 5%!4=
+M%A4<%!T6&AL9&B M+E-+24A'1$-& 4<!10#[\R(@B6\E%K>U%Q<5$XV5Q<_4
+MTL:7&A,3%!<:$1$8&1DI.C,L-2E&0UE1138L(A86%QLE=EM<9CT:%S(<,R6]
+M>1DJ.DLJ8GX2M1T6&B:X6A at W.APJ010C$0HP%! <%1 .$Q01$ \7$ \6#A<0
+M$A,1$ATJ*U!*2$=&04!# 40!0@#[^R<ACG4J&+V]'!@9%9*>RM;=W-*@'Q<5
+M%AD<$Q,:&QLD-2XF-"Q+26-92CDP)!@8&Q\L@&=B:4 >&30G2CG*@R L,T at I
+M87T1LQL6'"F]8!LR.!\H0!<G$PPR%A(?&!,1&!D6%1(:$Q(9$1H3%A<5%A\L
+M+5))141#/SY! 4(!0 #[^R4=&S0?(1\4'AH50H.-O<_4S<&7&104$!4=$Q<9
+M,!HF-3 at F,!QG5'%<7&!C75M33%!376$_&BP9%2(<'Q94<2 J+",I'&TEH1P=
+M'AG ;28?'A4=+1XD%!<V#A<T/!X?%AD5%!D:%QD4%!D8&1P:&147/"XL=%).
+M2DE( 4D!2P#[^!\6'#8;'1\7&A4408:5PL_4T<67%Q(2#A,;$147+A at J-S@J
+M."1L7'5C:&IJ9F9<3DY89%XZ&BH5$R,:)1E2<QTD*B F%F<?GAD:&Q[!9R :
+M&0\7+!L<$10S"Q0N-!87$A41$!,4$1,.#A,2$QD7%PT/-"@I=E1-2$9% 48!
+M2 #[_R(5'SP@(RXG(A,10(B;Q];=V]&>'!84$!4=$Q<9,!HE,C,D/"AO8G]L
+M;7!U<G-J4E)=;6I%'RX;%R0?-"=7>R4E)B H&6@@G!<:'2/$:",7%Q(8*QT@
+M$Q8U#18Q.!H;%QH6%187%!81$185%AL9&1$3."LG<E)*1$1# D8 X?,I*4 Y
+M,QJ.D"D>'"6'C+W,R<[!FR,4%A07%A45&",;)CPR)S at M8&I33EU,/D!/:F9O
+M<V]>E4]$'1HH4S)NM24 at 0$M32TZW(+,>(QP<LU<<%1,1%R 6%A44$A03.S<B
+M'Q4#&(40(1 at 1&P,5C1D8%Q4<%U(;<&%Z4E(#2P%( .'R)2(^.R\4BY(E&1HF
+MCI7"SLK/PITD$A(1%103$Q8A&2@^-"D[(T9/.CI//"PR1&)G9WEZ9)=-1QL8
+M)4HM8J at E(#]-5DQ-M!NO'"(:'[53%0\0#A0=$Q,2$0\1$#,N&18/ Q6%#1X5
+M#A@%$HT4%!4.3QQO9(!34$E( 4@!10#A_RH at 0D,U%Y.:*A<<*8^5Q-;5VLVA
+M)Q87$Q<6%148(QLD.2\D.QLV0S4P/2PG*SI>:&Z A'.?3TD?'",^%D^.'"4\
+M2%9-3+(8M!X?'B&Y6!82$A 6'Q45%!,1$Q(W,AT:$@,7A0\@%Q : Q2/$Q,4
+M$Q0041]N9H543$5( 4H!1P#J[#0K12LT'519)B(F,H>/O<_+SKFD2Q,5%!<6
+M%146'AHD.S,F-RDR-S)J=GV!GHR,D(U>@F(P045E9H9QQ."RA'M!("]&>L(C
+MOAP>'!*FAA44%141%104$A,6%!4A%Q44$AL:&1,>%1L5%008C1H>&1 at R&IR#
+M5UU>7$@!3P%3 );P-"I'+3 745LB'20SCIC"T<S/NJ9, Q'1%103$Q0<&"8]
+M-2 at Y'Q<3$SPY2U!L6EMH9E2-:S) 2&YN at UVOQZ*$>S\C,TAZP!^[&AT:&*F 
+M#Q$2$@X2$1$/$!,1$AL/#0P/&!<6$!L2& \/ Q*.$Q49$A(P'9R$7%U<6D8!
+M30%0 /O_.RE--38:66,G&R8VCYC$V=?:Q:I/%183%Q85%18>&B(X,",U%PL,
+M""L>*2<^+#)%3DR7=S at _2&IJ=3M]H'AUA$,;+4-UN!6]'!H>%;>;%!$4%! 4
+M$Q,1$A43%!X3$1 1&AD8$AT4&A(2%143$1,7$1,R'Z&/:&9 at 7DH!40%2 -/T
+M*24=)$HF(2 <'QQR>X^USM+-N:1#%!88&A<8%Q<;'2$T-B Q'R(?*%557'>-
+M at F]Y;XF!5S\R*UIZ;9.VV[FK+#98?6HMIFC#$Q0<&JE\%1<5%0,4I1,3%!,4
+M&TH6$1,3(2,D&$45$1 at 6'BLT.5!D&QT at 0:JH:F6"9V4!5P%" -/T)R >)D8@
+M'B(8&AIS at IBZT-/.NJ9$$A(5&!46%149&R,V."(V(AP3$3<Q-E1J6D552(.0
+M8$$Q+V-_9GR>P:6F+#5:@&LLI&/ $1,:(:]\$102$@,1I1 0$1 1&$<3#A 0
+M'B A%4(2#A .%B,N,TA:#A$8/:BJ;V6"9V4!5P$^ -/_+!XA+DPC)BH=&!QV
+M at YB\V-[9Q:I'%A<7&A<8%Q<;'1\Q,QTX)!\6%# ?("\[+1XL+GR>;$4N*E^!
+M75EOGX.A,S15?FPIH%["$Q >([B+%Q84% ,3I1(2$Q(3&DD5$!(2("(C%T04
+M$!02&B<Q.$YA$10<0JVR>VR+<&P!7 %# -/Z+3LZ(%4ADZH]%1H:=XNUS\_+
+MMJ<@&!04&1<8%Q<;'R$T.Q\Z)AX<+"-2E[R@@V5Q9'EV6D5&,HAV)G'"V<FY
+M-#YGQXH:D6BG%C0A at 5D:&1@>%@,3I1(2$Q,.'%5-%1,0$1L8$@D3&4I&11 at P
+M.H-1;&M[;Z"50E7+44,!%0$: -/Y)B\T(E$;D:PY$!@;?I.ZT=#,MZDA%A 1
+M%Q46%149'2,W/2$X(1T6&B)8C[&8>%=E1WN$94=%-H]W&5JPQ;>Y-3YIR8H8
+MCF.D$S,BAE\=%Q0;$P,0I0\/$! +&4]'$A -#A at 5#P80%4(].@\I-7Y'75IN
+M:)Z71U/*4T,!%0$6 -/_)RHU*%<>EK0^#AH>@)6\U]O7PJTD&A43&1<8%Q<;
+M'Q\O.!PT'QH1%Q=#>99\7D-(,GF6<$M",8YZ'$&!F8RJ.#EDS8\<CF&F$S E
+MDF0;&QD=%0,2I1$1$A(-&U!(%!(/$!H7$0 at 2&D8_.A$R0(E8:61W;Z.=2E76
+M6TH!&@$< /OS1FH5(6D:%1P4'!B*<H^FS<S'HZ85&1D4&!(5&!<6-R(T-QLP
+M*!PB.R%6G::=;U]L<GMS6D<F(HUQ14.ZY^3"1REBQI0;OE&^'F02&R$6%1DC
+M'A,2$Q<4$1$.'TL?$Q03&248&!<6%QT6$@X2%Q-G<DE7/X%1/C3#,4X!' $:
+M /OX/5 at 2)&04%!T0%A:*>)>KT-#+J*D6%Q41%0\2$A04.",X.1TT(A\:&QY9
+MF*.9;6)O0GUU94DE)91L+BNER\S 1R=DR)09NTRW&V,4'2$4#Q8@&Q /$!01
+M#P\+&3L2#Q,0%B(5%A44%1</# <.&AMI8BX]-H)1.R_",TT!& $4 /O_05,4
+M)&\7$R at 6%QJ/?YVMTMC7K:L9&QH3%Q$4%186.20I-1DO)1T4%QQ;BXF%95A7
+M)7B+;T\D(YU='Q!]FZ&\4"E at SID;NTJX&6 8(289%!@B'1(1$A83$1$-'#,2
+M%1(0&"07&!<8&AP-!P at 3'!]^?4A30HU6.2W.+DP!'0$7 /OQ.B0E*'<=C*9N
+M&!@2:HVQNKF=E9<A'AL4&Q08&A@@%QTU.1HR)A\U2R$YCJZ8A6EO<7Q]8D K
+M(HLG<JBOLINZ6"P6R)L>LTFS'7 at 8)"L7$A<;&!,6%!$2$1$0'CPE&B03&BT>
+M%Q5+)A84$"(<("@6;2J5?3P=/C##,TD!'P$; -?T-!<A*W(7BZ=J$A82<)6V
+MO;ZAFIHB'!<1&!$5%!4>&!XY.QPV(B8I)AL[B:R6AFUT07Y_;4(J)9 C7XV3
+MD7VP52H8RIL<L$2P&G42(BD4#A08%1 3$0X##Z$-&"86&" 0%RH;%1-))!(2
+M$1\6'BD36A* =CP>0#+$-4@!&P$8 )O_.1<F*7T:BK)P$QH7=YNXO<&IG)PE
+M(!P3&A,#%[D@&1\J-Q at N)R<D'!0_A)>!>&5=)'F5=T at I(Y\9-EME75"J7RP4
+MT* >L$*R&G,5'B44$Q8:%Q(5$Q #$:$/&Q\4'242&2P=%Q5-*1H6$B$1&"P?
+M9!N, at 44A/##/,$<!( $: -;R(R<</FX3)RDE&1E66I*>@9>+<W43%A82%Q48
+M&!<C&1HR.AHX(28\4",<6V>)B&%K>WJ!8&XL+X-@,L#-M\"\8R0PQYHLJ3&K
+M%VHQ12D9%!07$Q0;& 02H1$?01\+)1L:)2$=(F at C'R,=,#I%'2=J#I\K'!8_
+M1;5*, $8 1D ^_,@(1Q!:0TF*B$3%U9 at FJ.%G9!Y>!04$@\4$A42%"$:&S8\
+M'#LB,"PG&QY;9XJ.:G!+?(-K<"LRCF(GJ+&6HK-B(C+)FBJF+*T88R0Y(A,1
+M$100$1 at 5#P\0$ X9(PT+(Q47(AX;(&8A#Q at 8)28](B]K#:(P'!A#2KE,+P$4
+M 18 ^_\H)"$_=! E-2<4&UMGH*6 G))V>!<8%Q$6%!<5%B,;'"<X&"\E-B8>
+M%2)45'1[8%DN=YEU=BHPCVH,<8-B>;-N)"[/GRRF*K$;8B<\(101$Q82$QH7
+M$1$2$A <' H0*!@9)" =(FHF$Q at 5&AXY)S5L#*0U(18^3,5'+@$9 1@ ^^XB
+M%1H:D2LJ)R<8(GE0DXUND'=N;1 8&!<9&1H:%R 5&3 W&$ <$5Y<)ALSG8MU
+M77!Z?H)-?B$O at HUBJ<#HD[UW(3_'H3$R+U892!4B(AP4&!42%R 7$A(3$A,8
+M0S 2%2XJ,R\Q)AP_/F<L374=%4HY%9\L&Q5&2)X;&@$I 3  ENT?$1L=CB4I
+M*242('E6FI)UEGUU<Q$#%+\6%A<7%!X6&C,Y&CX?%TXM&QXTFXEW9'5/?(=:
+M at B QCI58E*C-?+=V(#[)H2\O*5@:0@@6&A83%1(/%!T4#P\#$* 2(Q8/$24D
+M+2PO)!H])5$>,U8,&5P^$YTD%1=,3Z(=&0$F 2X V/DG%AX=FB at H,2H5(GY;
+MHY1ND7IN<A09&188&!D9%B 7&R<T%C at A'D8D&B FAG-A6UXN>)QGBA\OAZE0
+M9'F;6[R"'SO/J#$O*EP=0PD=(!D0%101%A\6$1$#$J 5'1$1%RDG,"XQ)AY"
+M(DH4(TH+(6%#&*(J&A5)4*P9& $H 3  ^_DG%QYTF!4OLYD9'A)!EGYF at VIE
+M91<=&Q@;'AP8&AH8&2\[&3P='S!L)!XTIZ1Y3V]\BW)6C2,=AI*WO-CB2(.3
+M(5#"J3H\3T,>@!H<'Q87&1D=0"(<(A$6$Q(9/58V(6='+R%^3A at F)#% @Z V
+M%B8=%J4N(Q1=&"P7%@$K 1@ ^_HC$1UWEQ,MM9<3&Q))G8-OC71O;147&!89
+M'!H6&!@6&"\[&3 F%BDV%!\MI)UT4FI5>8!@DB(;BIVJHL3-.X.8'DK IC@[
+M3D,=?AD9'!,4%A8:/1\9'PX.#P\0(BH<&$P^)QJ!3Q8B$B,U;8$D%BT?%J<H
+M&Q)C&S$8$P$M 18 ^_\K$AQYIA4INYP8'1=%J(5EA6QG:1<:&A@;'AP8&AH8
+M%R at R%#4B(!TA%B(ABH)=1E$M=)%SGB$?DJ>9=IBI*HB='DO%KCHX2SX:@A at 9
+M'!,4%A8:/1\9'PX4%!$2&"(6&%1 *QN#4AHG#1PR9W8?'3 at C':TK'Q1B&S,;
+M%0$I 1@ ^_<_)!<BIAL>$1,='(U!D'A>95]@8!@<%Q8:'185$AD7&2T]&3P>
+M&1EA)Q\=2J1\5FAW?6UNGB(?A96O:>3<)W][)&"]NS$_/5<HCQ07'1,;&"$A
+M1BTC+146$P\:/%1*3GJ'%1X,3!<?2%9<JG87$B$:%*$7%P]=F#H=' $H 1@ 
+M^_@['A8EI1D;$Q$7&8U)EWUE;6=H:!86%!08&Q03$!<5&"T]&3 H$!(I%R$:
+M2Z%X5FE8<H!WH!\=BJ&B3\_*'86 (EN[N3% /5 at GC!$4&A 8%1X>0RH@*A(.
+M#PP1(24G-51^$!(-314;0E1<HF\4$B4:%*,1#PUCFST;&0$N 18 ^_]#'Q4E
+ML1L9&18<&Y)%HG]<9F!A9!@9%A8:'185$AD7%R8T%#,A&@D;&R<8-(5D35(S
+M<9>%J"$?C:B1);.U$XJ#'EF_O2PT-$PDE!D6&A 8%1X>0RH@*A(4% X3%1H<
+M,F* #1404!D at 0U9CIFX6&3$?&ZD4$P]BFST=&P$M 1H F?=(*B PMADGJ;<<
+M$AD;CWDX.R\W6A at 7%1,#%=\3%!D9&"@Z%S at A(BUE1C(^,J2I=6-YD'Z!JAP>
+MB(QFB.6C7H&4+SJPP6EG>XF1HQ46'1,:$1D@(2(<'!(5$A$;-E!*-WR%&B<;
+M428O)1LJ=S59%!(4$HT8&!=8FS,?'0%# 8, F?A$)!\TMA<DJ[46#QDCEGX\
+M/S,[8!81$A$#$X(1$@,7VB at Z%RTK&24M-3A!.*6E=659?("!IA8<CIA9;<^.
+M5(2:+36NOVEH>XF/H!,3&A 7#A8='A\9&0\-#@X2'B,E&4]Y&!H94B0K(Q at E
+M<#96#A 2$H\2$!5>GC(<&P%* 80 F?],)1XOOQDDL[H;$1X?H8 T.2TU71 at 4
+M%!,#%=\3%!D9%B$Q$BTC(Q\?-C<_,YF9;D\S=(B&K!L>C9U(1Z]T1(29)S"P
+MPV1<=(21J!@5&A 7#A8='A\9&0\3$Q 4%1D;%&5^$!H=52 at P)R(R>4%@$106
+M&945%!==GC$<'0%+ 8< GO(^(QIWM1H6'Q at 9(H8DC7PT*QLO41 at 7%144$Q05
+M% ,9VB<U(#\:&2=N+R(J)C9Q3V.&<WIWMB,>AI1K at X!80BF>QX[%NU[#0LM<
+MDADH'!8:$R$F*QP>&!,4$A,A,$M!.WE]-BMY0Q8L2$0_AE2=&Q at 3%X\.&!9@
+M9C<A% %* ;D ^_4Z'!EZM1 at 3'Q83'(8KE($W+1\S6181$A,2$1(3$A<7&"<U
+M(#<>%1\V'RHP+39P3U%0.T]HLAT<CY]@;&M"-BNAQHG$O%W#0<E9CQ<E&1,7
+M$!XC*!D;%1 .#A :'"$='$]P-2!Z1!0H0CLT?%.9$A41%Y$+$A=F:38<$@%2
+M ;H ^_] &QAXO!H5)AH6'8LJG8,O*!DM4Q at 4%!44$Q05%!D9%R(L&S46'1DD
+M&28M-CMM1C ;&SA<NB(@C:)32T<A(2F?PX3#OUJ^/LUAEQDE&1,7$!XC*!D;
+M%1 3$Q(;%1H6&V9S*A]]1Q at M1T5#A&&A%!,3')<-%1AE:S4:% %4 ;T F/!3
+M1BL>K1<95545&QTBB8(L)B,N31H7% ,7 Q3=%AD7(S(2,B 3+&4S&"4K'3R$
+M9(6+EGVR)!R!E9.KLF5*@J38F*N\N->TPFZ!+1T?%1D/7%4F(24>%!03$A<^
+M44(\.G)>:HY+%C C,CA_2Z 9&1 at 6G1<6&'B1-B07 4,!O "8]D\Z)2"N%156
+M61<<'"F4B"PF)C)6&1$1 Q3@$1(2%!<5(C,2-1$8(3 A'RHZ(D>(0E= 3F>N
+M'QF0G(ZDHUA&AJ75F*J_N=.VPFZ"+AH<$A8.6U0E'B(;$1 /#Q0F(QT@'F9>
+M;9--$B@=*S%Y2Z 7%A(4GQ,3&8&6."(8 4T!O0"8_U4U*"2Q&1IA8QL=*BB5
+MAR4?'BI*&!83 Q;@$Q04%AD7'R<++0\;%QD>(2P\)TJ"(RP<+4G &B.0GHR9
+MET<ZCJC=DZG!NMBZR7.%+Q@:$A at -6%$B("0=$Q84$10='!0<+F%9:Y51%RP>
+M,CI^5*D<&!,9I1 at 5&H&9/"89 5,!P "8\'8A$8*F'!QH9!4=*ADS/BTG&RI'
+M'1H6 QG@%185%AD5(BX7,"43*6A(0R$C,RLZ8H61DW>I&AQ^E&ZXU28\HZ32
+M at I_ LM6ZQ'F%'1P:%!@6$$$@*"8A%103$!(]44 T.7II9X),(T!+$3B-6ID<
+M%Q at 9HC,;)79U,"$4 4$!Q "8]'8:#H2G&AAI9A4;)R ]0BTF'2Y0'!03 Q;@
+M$A03%!<3(2\7,Q88'C$S1B0K,#,]0%=&2U^E&A>0H'"URQX[J*3/@I[%M-*^
+MQGF&'AD7$145#T ?)2,>$A /#0\E(1X;(&YI:H=.'SA%"C&'6ID:%!(7I"\8
+M)G]Z-B8: 4P!P0"8_WT9$(BJ'AUT;AH=+Q<V.B8C&2E&&QD5 QC@%!85%AD5
+M'B,0*Q0;%!DO2"0M.CD_)"P>*D2W$R*-HWC!TAPXM:G9?9O*NMS(SGZ)'Q<5
+M$1<4#C\>)R4@%!84#P\<&Q,6+VED:(E2)#Q&$3J,8Z(?%A,<JC0:)W]]/RL?
+M 58!RP#[\946'#.R%!X?&" B=R")?$!"0$%%%!H6%A<8%187%AD8(2TG,204
+M(&LU/D J(BTV6820DF^A&B!^EUO9W#9VQ)[/DH._L]>[M85M+!\;%QD/$Q,D
+M'QT:%1,3$18K13$M8G5I57Y+&5:$?WZW?)T9'2$9I84\+7V5/1,5 2<!O #[
+M])87&C2S$AH9$AD:<"2/?D%"0T9.$Q03$Q05$A05%!<6("XG-!49%3(?/T(P
+M'#0Y-E=&2E*?'AN+GUK9V#1YR9[,DH/&N-?!MX5N+1P8%!8-$1$B'!H7$@\/
+M#A,?)1<726EI6(--%4Y^>'>Q?)T7&AL7IX$Y+H::11 at 8 2T!N #N_Z$:'C>V
+M%A\>%1<4=QR*>34Y.3M"$AD5%187%!87%AD8'2(@+!,<"QH90$ K'S8W'RD:
+M*SFQ%B:*I6CJZ#EYU:78C7S(O>#*OXIQ+AH6%!@/$Q,D'AP9%!44$!,8'Q$:
+M6&1D5H51&E)_?X"VA:8$'(FMACLOAIU)&AH!- &^ /OZL"(B'XD-%*2G%1 at 8
+M(I-C045%2$85'!09&A at 5&18<%1 at A,2DL+!DA=#@E*C0Y*S!3A(Z5=)@?%W26
+M5]C=*+NCH=&+:LVUU[ZRBEPQ'QT7&1,3%"8A'1<4$Q,4%1LN("(M-3E334X8
+M5#$C+&]$I146%!.G>C at MC99#&R,!(P&X /OZL2(@'XH+$*BK%QD5))9B0D9)
+M34\4%A$6%Q42%Q0:$Q8A,BDL'1L5.Q\F+3LX,S8Q5D1-49 at B%'N:5-?<*L&I
+MH<V+:M2ZV<2WB%TR'!@4%A 0$20>&A01#P\1$AH=$1$:+3M64E 43BL=)6E$
+MI1,3#0^G>#8PEIQ*'B$!(P&U /O_O"<D)(T/%;*W'QP?()9?-#@Z/D,1&Q,8
+M&1<4&18<%1@<)B(E&1\.(1HG*S0U+S$<*Q8N.*L:'GRB8.7K+L"PJ-R&8=6]
+MW\N\C6 S&A84&!(2$R8>&A01%!03$A<:#1 at E)S94550942XB+FY-KA at 5#A2L
+M?#@PEJ%,'B,!* &W /OMH20=@+$0&18D%QIF')X^/T)$2$P6&1H:'Q84%Q4=
+M&Q@@,"0N)R I=4$@1BY,*!U,='V4;ZL@&W&=.]O='97'MM":7LBPT+BOI$T=
+M)!L8&A,6%"LN(!L8)C= 32D;,692.TU;;&@=3B(2+FY3I!<8&AXK&1H9G9Q!
+M/4,!1 %S /OQGAX:@+$.%A8D%1=B')T]/T)&3%,5$Q87'!,1%!(:&!4>+R(J
+M'1X=.B8E43M9-" O2C9+/Z\8(72C/]O<()?'N<^97,BRTKJSFTT@'185& T0
+M$2DK&Q83)38_3"88,6A4/E)@<VH92AP*)F93I!45#Q$?#Q08G9Y(1$D!3 %W
+M /O_JB$:A;82&!TK&15H%9HZ+C$T.DH4%AP9'A43%A0<&A4:(AHB$R(:(20J
+M43M8,1X8'PDJ(L04)G2H2>KR(I_6N=N85L^ZVL*[I5(B'A07'! 3$RLK&101
+M)#4^2R at 6+&90/%=L?W(>4"$0+&Q<K1H7#Q(B%A47HJ9*1DX!4@%_ /OLJ"$>
+M(' 7$J.K%1@<)JV\@55-2TD7%A,;%184%Q4<'1LA+BPK+",Q>SXA,#U+1B%)
+M=7V0:9 at A&U"1,M_:*\_0=LZ?2\^HT+>9J"\7/2,8-S$8;$$F-*(C7DE /EA+
+M5XBAL+.NISTA5WI[@;&?IA<8(" S+BTB)1H4,#,!/ $O /OPI1L;(' 5#Z.K
+M$Q4:*:Z\?%%+2T\5$! 8$A,1%!(9&A@?+2HI)24F0B0C-D563R,L2S9'.9P9
+M(5.7-M_9+M'0><V=2="KT[J>GR\:.",:.B\6;40G-J0E84Q#05M.7(VEM+BU
+MM$,:3W)Q=Z>?IA45&14B%Q<0%0P,,3X!2 $V /O_L1X;)749$:JR%Q,>(;'!
+M=TE#0DH7$Q(:%!43%!(9&A@;("(C&B,E)A\G-4=632$5( DF'+$5)E.<0.[O
+M,-G?>]N?1=.MU;RCJ30<-1X6.#,:<$8H-*(C7TI!/UE.89FWR-'1S50C57AX
+M?JZHKQH7%Q0C&AH3&100-#\!2P$X /OOKA@:<#@4&1\4&1I(.+G;TM3(P)0=
+M&!89%!H6$Q4>'!@?+BTL+R<V=T4A)#9(5QI$;GJ2:Z(L&DB6+-;;,<[/E-"C
+M3\FDS+BXO"TM2)B1-*,MIS>5-' B03) /D1(KZFHH):LHC,=2!4=(T UFA at 8
+M%QP9)3,R+R at T,"T!*P%3 /OSJQ(7<#@2%A\4%Q=)/+O;T=#(PYH;$A,6$1<3
+M$!(;&14=+2LK*BLN02L?)CU17ADD1#-).Z8D($N<,-;:--#/EL^A3,FFSKJ\
+MLRTP1IN6.Z4OK#Z:.G8H23I(1DQ0M[*QJ:&XK#<90A,;(3XWFA85$1,,$AD8
+M&!(:(S(!,@%5 /O_MQ47=3T6&"8;&Q5*-,/JX.+9TY\?%1,8$QD5$! 9%Q49
+M(",H'24L)"4C)#]171 at .&08H'KL@)4NA.N7P-MC>FMZE2M"LU,#$O3(R2)N8
+M/:DSKT"<.74G139$0D94RLK)P[S5OT,>1Q<?)4(_HQL7%!<-%!T<&Q4?)C0!
+M- %0 /ORLR07%Q\?%B at W'!U$-+7:U]'+QI$?'1TC(",E*RTN,C(Z,S(M,2DN
+M=4LD*41/3RM ;WR/;:<U(2Z5*-W:*,W,;\:K3=&NOK>XR"JZ<J<R>D58?C:9
+M**(D5SL^/%.2II^IJ:2G*SP@*4-%34U&1A<8%!@>'BHK+S0\+!L!(P&' /OV
+MM!X4&1\=$RDX&AI&.+G<V]70S9<@&!LB'2 B*2LL,# X,C$O*C G/S$B*$=5
+M52 at D0S)'/J<O)C&;+-S9*<W,<\:K2M.OO[B\ORB\=*PX at 4Q>AD&@+ZDK8$1'
+M15^>KZJRLK"S+SH=*DE+4U-(1A45$@X0%1,1%1L:&!P!) &# /O_P1\2'20A
+M%31#'QI$,,/QY^'=V9XC%A<?'2 B)24F*BPR)28J'R4E)"DD)T=44B8/& 8F
+M([@P*S. at -.OO+-;;>]>P2MNZRL7&R2S >K$]BDYEC$2A+JHL7D!#05BER<7*
+MRL?*.SX?+4A*4E),2QD5%Q86%Q85%QHA'AT!)0&( /ORMB8A/B,6&WZ-&B$_
+M-;7<W-+'SJ4_.SDX.#DZ.3I /CP]-"XD-"DZ=$PA)29'-C at P9X!_9Z,W*""6
+M*=W9*LO/JKNO2LRHP,*]R2N_PKLUD2:B,X*75*$U5D!73$"NLHZ?P\"_%!M:
+M'STP/SL[7F%.&!L0*BTM,3=+.40!0P'( /ORO!\;0204&'^,%QL_-[KAW]7*
+MT:M!.CHY.3H[.#D_/3L\,RTN)2HX/3,@)BE-/C<A.SQ /9LX)2:=+MS8)L?.
+MK[^Q2]*LP,? Q2C!Q;T]F#*L/8V>6Z<[7TQC6$RWN9:FR,&]%!Q=)#\O/CH]
+M8&!+$ \4%Q$3%!(U,D8!10'( /O_S2 60R46&HR:(2 Z-;_P[>/:X;(_+RXM
+M+2XO+2XT,BXO)B =(1LP)2@?*2E*.C87'Q >*I]#)RN?,^OO*\_DO,FW3MNT
+MR=;0S2C)T\$YH2NT0XZ at 7:Q"7TE at 54G#U*R_X=K3&Q]?)CLL.S<Y7E]+%!0/
+M&187%1,Y,T0!0P'1 /OWN2DK2!H9&AXB'1E,/;78U[?1RZ- /S(U-#,R,"\O
+M+C(W-C,M62<D?D\F*B9,5U8G47R"7[,H(QF3*-W<.LC,I[.X3LNPL[W%RBC"
+MR5$QM1MR,+!2F(EH.TE!/%:OS,"_T,,?%A8A*A(S01 at A4W*)&#M:03(M.D9 
+M*RH!*@'+ /OSO!P?21L7%Q8:%Q9,/[K=W;W7T:I .S U-30S+RXN+3$V-3(V
+M11XA2#0C*"U78E at 6)CI$.:TF'1^<+^+;-\3,K+>Z3]&TL\/(QB7$S%,XO2=]
+M/+Q8GH]M1%5-2&&XT\?*U\,6$!0B+1,Q/Q8A4W"%'10?&AD0%B4P)2<!*0'*
+M /O_SA\<3!P9&1P@'!A'/;_L\-#HX*LY+R at L*2 at G)",C(B8K*B<L-1 ?+2HC
+M+"]88UP-#!$>)[(K'B2<,>[Q.<K?N<' 4MJ\NLS6SB7,VELYP2* .;==I9AY
+M1%)*16'&[^#E\-(@%1 at E+Q8U0QHF6'6+$A at L'!@3&2<R)B<!* '8 /OPL$4P
+M$Q85%I^J&!DJ-:O(T89E6TLW/SHS-3$M,BXN+R E)RHH6R\?<4L?(ADP0$<N
+M46-J1%@K)QPD(]C<1FK)K:F\3<2OI+^AP#"MS2>62U^L+Y8XLSBC2S)-24*^
+MS\BZDS\6&!@5+!(;)188*$N9/\R_V#P_0VX\*2H!+P'( /OOM#PH%A<3$YVG
+M%!8J-[#-T89E7$\V.C8S-C(N,2TM+AXC)2 at Q0!<=.RT9'ALW2$<9+3= *50E
+M(!HB)MS<0V;)LJV^3LJSI<6EO"VOT"B<5&JV.Z(_NC^I5#Y954W'U<^_ES\0
+M$A03+1,9(Q09*$F5"Z*SHQ$>)F,[)B,!+ '* /O^QCXD&!@5%:*O&18E-;7<
+MX(]J74DK+BXJ*B8B)B(B(Q8;'2 O) PA("0:(Q\Y2DP5'!TI'UHH'QXD*.;O
+M0VO8O[?$4=.]J,JQQ"VWWC.A5&K -IU!NT&N5#M64D[7].K6J4 at 3%1D7,!8=
+M)Q@<+4Z;#Z>VKA0@*6(Z)B0!+ '2 /OM:!<;5D0:&Q0,%A<8*Z;+JS8T.3,]
+M.S<R-"\O-#0J)"0H,"XC72X8<%(H'R,;(BDC)"P?*"<K,#,M.,S3D)C%LZ"\
+M6;Z(2< HR">LQ\!W&[XUHZ,HI3.)-#AD6H._OXX8( \,'!\='2TT,S,H%1A/
+M.[9<NC\_;C(U)30!:@'  /OR<A0674<8%Q41%A08+:;0JS0R.#8\-C,R-3 P
+M,C(H(R(F+BPL.Q,5-S,E&1\<(R8<&R,@'2,E*"PI-<S6CY3%N*2^6<**2,4J
+MQ"2PRL%]),8\K*POK#N2/T5Q9XO%PI$8'0T/*S4T,S S,C(I$Q9,&)QAHALB
+M6S@]'R@!9 '" /O_A!847DD<'"(=&Q03*:O?LC J*RHO*BLI*20D*BH@&!H@
+M*"8L' <='2<G'B0?)"@C'2,C'"@F+#,N-]7HCIG4QZ[&7LR01\<RS"2XV,Z$
+M(LI(K*PPJS>0/T1Q9I'8WJDG*1(1*S(Q+RXR,3$J%1A.%:%FIQPC6S,Y("L!
+M90'( .3T1BDE&QH>("$?'!HA&14KRE)!/STY-#$I)2,C)B$?(R8J+2TI92D8
+M3D4@(R8F)RTS-CE!.4YZJ[Z42MW6=-7(N7:Y(\!1.[]?N"FLRU<NO5\TM#"=
+M7B]G6&E;820;$A85&Q8, R&4+!4D)"$8$Q8D,&/9:V0E1AXOIHD!,@&Z /OJ
+M1B$='!<8%Q at 7%A<>&A at HSE(]/3PW,B\G(R$A)!X=(24I+"PU21D9+#0B&B$E
+M)BTU-3,X-E-^J+R;1-W;=-+(NWJX(<%.-KU=L2>RSEDUQ68ZNC>B9CIT9WMO
+M<"D;#A 4%1(2,3<T-!8B(A\5$!,A"BZC.$P902 QG7D!*P&_ /OT5R4;'1D;
+M&QP;&1D@&QHRVDDU-3$O*B<?&QD9(!P7&1H>(2$N-Q$:(BL@'A\B(R at P,C0\
+M/EB&M,&F1^3R>=K9T(+$)L)0-+]?O"N[WF$VR6<_PSFN;#IT:8!W="X@$Q$3
+M&!@7-SLT-A<D)"$7$A,?!C>T15$</ALMG7L!*@'$ /OO)B0E)S @*3 V.$A.
+M3%%US,@^*RTT+RTJ(BL7*!0C(R4I+"\N>S,M04HR/CUJG+W)T<_2ULR_(S"0
+M5=O1=<S'QA^\47R4F\5QN"BKS::Y7#&A2"VU)K-K:FEF,S41(ATB*"4A,!4>
+M1A,3&!,7%A0=/C9SC%U%E3Q)FBP!, &( .'F+BLK+38K.#U"2%M<9VY\S\8Y
+M*2LR+2LH("D5)1$A(2,G*BT];R,F*3,A.#]LGK[*U]?3V-;))"N74]O4=<G'
+MQB"Z3H&6F<=WN":QT*C 9#>H3C2[+KYW>7EV.CD5)!P@ R:7-1H at 1Q 0%1 4
+M$Q$:0B=>D6-%E#Q+D1P!*0&/ /OP0C<T/$4X1$Y566MV at X.%X<HW(R,L)R4B
+M&B,/(P\;&1L?(B4I:"<=("46/4-PILO5YNWN[>G9)RB at 6.3L>M'8V2._3H.:
+MF\MVP2JZX+#!:#RJ4S; ,L%Z>W]\/#0/(!LB*"<H-QTD2A(2%Q(6%1$8/2-<
+MG6Q*D3-&D1X!* &0 .OB:F%<55]95UE;5%-75EZ[RRX:&!P8+14L'BL9*A8C
+M)"<I*S$Z*4=L9836R<O1UM;9U,_?GLLX-RF.9]S5>,7(QG_#<KYQB+AFLQ^M
+MRW5'+K1T*:A%;F]F:V9<'TI'&1LM.4TX(2(6&AP<'009C!U92%FQ*)JA)RJ2
+M-0$O 38 [.^2CXF#BXF+BXZ*BXF ><K1+146&A4J$BD;*!8G$R$B)2<I+SLB
+M+DDY7\C-T-39V=;6U-N/QSPQ(IAKV=AXPLC*A<=UQG>*OV^W(+'.=TXVNGLP
+MKDQV>7)Z=&8=3$L;&RD\4S<C'0X8&187$P,6C!I$/EZG(YN@)BR))0$H 3@ 
+M^_^\N:VNM[2TM[RWM[VID=CD+!,2%A,H$"<9)A0E$1L:'R$C*2P@(#HI4\[?
+MZ?#U]?+TZ^.-STXR%YYUY?!]RMG>BL]WRGZ.R&^_([O>?T\ZP7TQLTUX at 7=^
+M>VP?4%,A("X\4#0?&Q(<&QD:%A at 8%AA016"Y+IZ?(RB))P$G 30 ^^-M9V5:
+M6U=85UQ64TL88<7-)QHD(ATL&BT?+AHO&24D*#$Z-4NM6H_?VLO:V-;8V]C7
+MA9=\TT=5+X]OW-)./\G,A+<AKWYLM%%R&Z3+>)VI*"ZUFAV-7&)::!@B%#8M
+M3V=?12XI,AX;E9N>J:JRM;^]6F"O,)HP-'>4,@$E 34 ^_"=FIR4E)"/DX^,
+MD'TO8\71)Q4?(!HI&"L=*Q<J%" B*#$X,$.B/6;,V=79VMG<X.'895%,PT1,
+M*)EUV=-//<G1C\$HN85ROEYZ(*K.>:.Q,#6\GR2596YF=!T?%STS4V5B2RXI
+M+1<9DIB;IJJRM;_.8%FS+9(L,G6)(@$> 3, ^__,RLO#QL+!P,#!OJE&8<S=
+M'A ='!@G%"<9*14H$AT>(RPR*SVA*%W9\/7P\/'N[^WC73XMO5!.'9]^Y>Q2
+M0MCFFLLJOXYWQEZ (K'@A*BU,C:]I".9<75K>2 =&3XP36=B1BDB*A@;FJ"C
+MKK.[O,3$6UBK*Y8Q-G>)) $= 2T A^YA<4-=5EL#5_%210U35\#/,SA%*RLU
+M+"X>,ADP&3DB("TR-C;.U]31U=;9V=/&WY5 CH&*S5<C>HU]ULX?F<''5,$F
+M/74U4S<,!Z#"N$<[3*4])J1J@'Y/*D!F7TTJ0RDR*A\@'"0RB8^1B8:"?7UW
+M*&J[-I$7$(.!.@$R 58 ^_2;GH63D)61D8R1;!M38,?.,3) *2 at S*BP<,!8K
+M$S,?'BLN,#3)S]?9VMG:W-?)XYDS5#-3PE 8>)>"T\D=E\#'6<DG0GL\6CP1
+M"J+#O$Y$5*I#+;!XBXE9+3MC950Q2BPT*AT=&2$OC926CHR(@X-])F&R+HL4
+M#G]U*0$I 5$ ^__4S+["O\3 O[_!DBU<8-+=*RT^)28M(B06+!0I%#0A&",F
+M*SC4X.GM\?'S^//A^*,V)1XKP5<G=)^'W=X9F<[89L\H18(^6T$3#*K.Q%! 
+M6K9*++>"E91A+SAA8E,R3"XR(QD;%Q\MEZ&CFY61C(R$*F&V,HX6$(5Z*@$I
+M 4P ^^M2951=8F%>5FD@%2 H3+S6-2 B*2 K.B\=+QHV0S G+S$YR-+4VMK4
+MU]C7T:\<,6\ID8B(S%]G)Y"&ULU!P<N^-AXA)B(<&R,;&&J&F6ZCN" EKGQ]
+M at 5M62TI$+C,_.R$S,3,C*2DY9W-N:69 at 7%A3576W?8N'J8B&-0%! 7$ ^_&,
+MDI:3F9B5EYE%&AP?3\/6,QD<)QTI."\=+AD\23 C(R8SR-;:W]_<W-O7U+$9
+M*6 at 45SM,O5A7(IJ+T\E!PLN]-QT;(B :&AT8%6>#F7"HO"@RO8^.B%Q103\^
+M,3=#/B(S+RXA)R<X9'!K9F1>6E923F:I=(6$IX1Z) $X 6X ^__%P,_"R<C%
+MRLA@)B(A3\_G+Q<=(QLC,"@8*Q@[1BD9'",VT>CM]OCR\_?V[,8E+V80(20C
+MO5]H'Z*0W=DZQ=[).AP>)R0<&2 8%W&+GG2KSBXOQY^;D5U..34Y*2\^/",N
+M)RD=(1\K8G)M:&!85%!13V:O>(B&J8I_)0$X 6P ^^YD<UMJ9&9G7C\C'TAH
+M.<#5/2,<,SLO,S(6-4,P%R O5,G8V-72T]K2T]&1=#0W?G(OA8F*RG<A&(A]
+MR<N;P\'%-AX;)B$F+S%6%X? O90]/4Y\A6%=3E5;65Q#,BD\&RHZ0S@^.",N
+MU=+8U=K7V-?CSG^Y?H.TK8"+-P$N 6P ^_2>H)V=F9N<CS\0(5!D0,?3.AP6
+M,3 at M,3(8-T0O%!TL3L38W=S=W-W7V-64<2XO=&\@3#Q,OW<3$Y*"QLF=Q<3*
+M,Q<8(QXC+2I1%HG O9A#1%>$BV-:1$1'0DD\,"<Z&"<X/S(Z-R$LTM+8U=G5
+MUM7CR7.M=GVQJWQ_)@$E 6H ^__7SM;-RLS-MF ='U9J/]/G.!T9+38G*2T4
+M-44N%!LJ4\_K]/?W]OGP[^JF>3,M;FT>&"$DOGPC$)J'T-^;R=39.Q48)1XA
+M*2A.%9'3T*1,0U.*G&E:/#<W,3HS*B$V%B<R,RLN+!DHVMOAWNCGZ.?TU'BP
+M>H"SK8*$)P$E 6P ^^EN;69I:%MI-T$4'8!\0,3<."4=,AHG(S%#+Q4N'VS2
+MW-S8W-C5UMG45B(?*AX:*QHH at I"(R(T@'W]_PL6UP+^_2RXG(QLD-AT;%RR\
+MM3)WB!T2'$Y586-?7EE&&QT]'!X[+3$T,34IS];5W=[AV]W;NFJPE8&[J&N#
+M-0$P 2D ^_*HF::;FI"2'R(4&XF!2\G;-Q\7,!4E(S5),A at G%V7.WM_<X-S>
+MW]C76B at G*"0A,"(=3$9-PI09&HF$PL2UPL3$3"PG(AHD-A at 9&3+!N3N$C2 4
+M'$!%2T=#1D(\&!8W%ADW*2HQ,#(ET]O:XN+EX.+BN6*KC7NUI6=W) $I 2< 
+M^__?Q-W'SL._0#$-'9F-3M;Q-" :+!,A'#!$,AHH&V[=]/GX__CX]_'Q;C$M
+M+"TJ-2@<'2 at FO98D&(^'R]V\R-'962 at B'Q<?+Q,3%3?.P3E[CRX<#2\U-S(N
+M,3$T%A0Z&1<O'2$C(S KY_+O]_?Z]??]SVBID7ZXIVUZ(P$H 2D ^^ML?&%@
+M7F, .D8P.44N,<'5.2TG,A at Q/3(H+!YDLM/4V-G8VM/8TTXD2"Q;220F4C1&
+MG)F#U9L8&GF"N\6T8\&X92LM/BQ004P_(A_-OQ@<.R at B35A-8F!&'UA$&3PO
+M9#Y%*SLV.RXMT]79W>+>W=S at U7BTFG*QJ7]D- $X 8T ^_6EIJ2AE90-&"HI
+M/$HT-<39.R at D,AHS/C(F*1AFM];7W=[>W]O<TTH;-R)B+"0I/2<M:%A+QIX5
+M%X6%O\BO8,6]9R at G.2I./TP^(1W*O!8:-B0>/S]#4$0S%T<Y&C L831!+#4Q
+M-RPKV-K=W^'@X>'GU7&OE&RKHWU<)@$Q 8P ^__9S=K*Q;T?(# J/$\Y/=3M
+M-B,D+18Q/RTB)QULQ.[Q]O/Q^.[YXE(=+!QK("DG,R<8/3,MQ)X=&8*'R=:\
+M:M',;28B-B9*.T<[(!_6QAH>,2H6+C$Y/3 F$3HN'2LL82PW("PD*R8MY^_R
+M]?CV]OC_YG*MF7&PJ():'P$P 8L ^^MQ<UYK:Q87%1DN+R<5)KK8/B<E+T(N
+M&"<@?+[/U-?4U=78V,O+5%5:;"Z$560D6DE-C9F&S:T[&'A[N,&Q?;V^0A<A
+M*1D:'A4@,3<W0$ B+R<W5E$O-V2;I(I(K4E#SSQ!)#DR02 7R]C8V]W>VMC7
+MD8VPGV6KI7 =-@$W 9\ ^_"KHZ.GA1L3"1,S-"D7*[W;/B$?-TLT&24@?\/8
+MW=_=WM[BXL_%1$%%02"3,5T>,S L5EE-OK X%(1^O,:N>;V]0!4:)Q<8'!0?
+M+S4Q.3D;+R$J/CXJ*$^5J7XZK3]"S30])#,M/1X6T-W;W-O=V=K9CH:KFV&G
+MH6X2)@$N 9T ^_WASMW:K2 at 8$!@V.3$;,,OM.1P@,4<S'"DGC=CN]_OS^/3R
+M]>'8/"T[)Q>?(%L7&R,2)RPQOJY &8& QM6Z@<;)1 \8(Q,4&!$>,3DV.#<<
+M)B(=+3$E'D66KG<PLCE!T3 U&RP@,1 at 5W_+U^??V\._OFH2HH&:LIG,1( $N
+M :$ ^^MM<EUZ,S5",QT:&1H<([W7.CE:-1DB*H6-M,O&S\G-T\B=HS;865Q)
+M at B)]8DP_5#1.;8UZR88B%VYQI[ZP7T^NCRLD'S,X+2<>'98]43H;(B0[4$.B
+ML69^WJ=-MT,\QD%$(3L@*"TDS]/5X=S6U\C92XR at I4BBH'<T.@$W :@ ^_"G
+MH)>0(A<D(1<:&1,8)<+</3=:.!PE*HR6O=//V-'6ULF at ICK.1TX^5A^:.T4_
+M,2 R.$Q N8H@$WITJ\>Q6TVJBB8?'3$V*R8<&Y0W2S03)!XN0#NBHE=[X)D_
+MN#T^R#D_(34:(RHAT]C9Y.3=W,S70X6;HT:@GG,G* $L :4 ^_S=RL:N.1XK
+M*!P?(!H=*<[S/SEA-APG+YBFT^_E\.WL\N*RN$;6-#0[.!^Q)4,Z'!8@%R<L
+MNX(D&'=VM=>^8%*PB"$<&2TR)R4>'YDX1B\7("$A,#FIH$U[YI(VPS at YS#<Z
+M&C 3'BPIY^WK\OKV\=[I27R8I4JDHGDG(P$L :T ^^EJ;3 at 6&QXE0AD7&145
+M)[?-FV,5)!H0%PT?'R0>(2$9&A\@=T/3>RHDABM27GQ.1VQ&3'MTQU\Y%6U-
+M6[RN2H2'438U*RXF%QL?'80V.3$7#Q\P,[O:CE9^WDU+MTP[T#HZ,30S(KA[
+MR74O/]1XC&[41VU(FQ>8I6\Q.@$X :H ^_*CEUP;#A$1+ at T4$PT/*+O6HF49
+M(!0.%PT=&!P?)",<&1TB>471:R893A]B-'-5,&(P'SPZM6,X$G907\*O2(6#
+M3#$P*2LC%AT=&X0S-"\3$ALF++?;?4QXVCT]NT8_TC,U+RTJ';1XSGTU1.&'
+MFG?00&9#F166HVLB* $O :8 ^__9P'T=$109-! 6&!02*\7PJVLC)1D3'!(B
+M'R,J-#@N)R(==4/66AH6)AIR'7-6(EPI"R(HN%TW%'129]&Z2HB(2BPM)2DA
+M$QL?'XLS,2L8%" <(+WH?#QQWS<VQT$YV#(R*RLJ&[R$XY$^1O*?K(/?05U 
+MFQF:IW B)0$O :X ^]9S!!48%!85%!<6%A09&*[-6!P\11<4&$\S)#<5%A at 9
+M'!M!4$/.6"$FC2HX1BX=,3 Y.61WQH\T&F\O/[BH*36OA'\O(2$D/104*GPP
+M&Q0L93(E1#8K54J/VTE/LT _QS@^1S4R*(2UR&5')<MMB%S&2$)(F""3E6LP
+M,@$W :X ^^Z;'A44$!(1$103$Q(3%++571Q 1142%DLO(#,1$A05&1E$5C?;
+M0R,66AM *1P:'24@'#<]L8TO&7(U1KNE*SNSA'XM'QLB0QH1)WXM%A,N9C$@
+M/C,L0T&0V31 MSI!R3$W/BHE(H*NTW%2+-!YF&3"03I"EAZ1DV at E(P$T :@ 
+M^__'/AP9%1<6$Q85%104&;[H:B5*2AD6&E$U)CD6%QD:&Q4Z43+L-2<0-!M3
+M'1D:%1L=$", at K9(M%G T2,NO*4"[B7TI&QXG2!D1*88O$Q J9S =.34M0#&"
+MW3 VOS4\S2\V/B<E&8>UWH93+=^.J6C2/S9#F"*5EVHE(0$T :T ^^ .(B =
+M'1 at 8%R$P.$!'5[33>3H9#Q$66FE;1EE4%!T1A:.SK*ND?!\CBR-(,2L5*SHL
+M*3UYOX8K%F0?+G^:%R)\A1P:%A<4'UE7-7Y/?X4X(&9IKKEN0T2%VE)*LCY!
+MR3M*0#LS,;.PQF [3==N?EO(041#D!Y<,FXQ,@$V ;  ANT?'!H>&0,4\AXM
+M-3M 4;G;?#87#P\46&570E50$!D-AZ6XL*2Q8B 96QM3&!P2'3,7%1M!J8(A
+M$V4B-(6<%2> A1H7%!05)EU3,H!1 at H@\&V-IK+IW/D.(V#T[MCA#RS1#-S H
+M+;.KTVY)6-QZCV/$.CP]CAQ:,&LF(P$S :H ^_\L'QTA'AD9%B O-SD_5L;N
+MBD4I%A,87&M=2%M5%1X2C:V]N*7"4B,31AE>$QH2%BH5#A CHXHI%68B,XZB
+M%RJ(C!\9%A08,658-(A5@(8W&&-NL+UW.SA\W#DQOC,^SS)"-RTE([RVX(A2
+M8O&/G&G4.#@^D"!>-&TF(0$S :\ ^^@8&Q<4%!(7.D!+1DE-2+G/=AP9%18M
+M2EE*$B$P/QD3J*F$:&:89!H<4!U)*R@:(#(E'C%KJ)M"&D :&D"9&"H]+A$9
+M&BIF2:6^)%V3W'%1/5514%9"21U^VU5#LT\[R3)%23DT);6VSE0[0\]@<5C&
+M2D9*?B$=(&HC)@%/ ;$ ^]<:$@X2$ X3-SU(0T)%0K_7=1 at 7$Q0K2%5&#ATL
+M.Q4/K[&);&.F1AD7)AA8&!T8&"P6%APZEYL^%CP8'4B>%BM +P\5&RQI4JJZ
+M(%^7WG-/.%I635)-2AQ^V4 TMTD]RRL^0"XL)+:RU%U&4=1L at F#"0SY$?!\;
+M'F<8%P%, :T ^_ at 8%A at 4%1,8.3]*14!#1]#MA" <%Q at O3%M,%",Q0!H4NL6@
+M@&NX,Q at 2(Q5<&AT:%B,6%!@BE*1#'$$:&TJA&BQ ,A,:'BAI8K?")6>?XG%+
+M-E]B3UA-2QEUW3PJOT0XSRD]0"LF&<'"XW506^M_BV;403I%?B,?(FD8%0%,
+M ;( ^_<5%1 at 5%!<8#31'4U)D3:_.?AL9%188% \,'AD3'Q,=,Z:IKKN.>58?
+M2B%')B8:'3(B%"=!4;,F'149%A].(2$E0B%3:8@=;K#+(5*[W80Q(6%L01A.
+M,#MSU5%)MDL\PRU#3C8^([6VR#TV/M%475/'344Y<",<'G:,/@$X :\ ^]@1
+M$0\2$!,2"3!$34=91[72?QD8$Q06$@L(&A4/&P\9/K2RMK^;6U ?)AY6&!T7
+M%"P6#1H:1KDH&1$6%293'R,I1"-1;(D?>+3''52]VGXJ&V5S/!)6,3AQUC\[
+MND4^PRM 1RLV(KFTSD,^2-1A<EO#2#TS;2$:''-_+0$S :L ^_D6(1T4%1 at 7
+M#C5&4$963,;GC!L5%1@:%A$.(!L4(!0>/[W O,>J2%,:*QQ8'A\9%"43#!H,
+M1L F'A86$B56(R$D/Q]3;HH=B\C6(UK#XH$H('%^.A=8-#IMV3HQPD YR"<^
+M1B at R%\/&UU)"4.QP=F'513DV;R4>('6 + $Q ;  @NDB Q?V%A(6&"Q)/U16
+M/JM>/V19%D2B&"-'@FUE97X<))5X65J(92<<-"A;&BHA*38\(2 N*8,='B at Q
+M'APK,D L*G>7AMH=3\/:+3RUVX<^)&A at 4&(\72&,VT]4K4Q!H3="3D0U++BY
+MR#TS0--(4T7&3(EW6E09'FY]0@$V 6T ^]L8$!(5%! 4&BY%-TA)-:Q=0VI;
+M$D">%!]#?FEA87H8*I^!8V"-4QD9(2%A$A\6'BHP%!,9(808&"4N&QTL,T$M
+M+7V>B-4<7,C5*3RWV(0Z&V1E5F=!7R*)W4!&LD9 GCI&2#DJ*KFUS40[1]-2
+M9$K 1X1Q4E :&&IM*0$N 6P ^^TB#Q :&149(#)*.TM).;EK2V]?%T6C&25)
+MA&]G9X >+ZF/:W&20"$9(R!F%A\6'B<M%!07'X<6&2<P'1XM-$(N*WB at CN ;
+M;=WM,4&UXH8R'6IH46E$8R6)XSP\MT$]H#! 238I(L3$V4U!4N1<9U?51(%V
+M6%4='6]Q* $L 6D ^^$G'BPQ.T5*.SE!/# ^/RO'F6A?&A\1;QL_&5<4(V<;
+M&%R#DWB87B,>,2(@-#@V,"PR'QPH*& H'RX^.CD;/$ D'T!?P^ J*\#@(R^T
+MV)I9'REE1UPE8%:0V5)4L$Q$S$%&4#\R+K>SQCTV1M-$347*6;YJIB5FHG"#
+M1@$X 5\ ^]@C(#$S/4I003Y$.BDS-BO(GW!D&!L-:Q<[%5,0'V,7'F.)FGN<
+M4!,;'ADC*RTK)2$G%! 7'5TB(C-#/SP>/T,B(41DR-LG-<;;'R^UU9=5&"AL
+M3V,K9%F.VT-&M49#R4%&230J++BOQC\Y2-!'4T;"5+EDGB%GG&QS+0$P 6  
+M^^(H'C,W04]51D%&/"HR.#+5J'9I'2 2<!U!&UD6)6D='660FXVF/Q49(!DE
+M+2TK)2 F%!,8'%LC)#9&0CX>/T,D'S]GS>HG/=?S)S2XX9=+%B=M2V(J7U&*
+MX3\\ND% RSA!2C$H),.^ST,[3MA'4$G34;9II"9JH7%W+ $N 6$ ^]DV-#E'
+M+" A*S(Y.38V02M<2&1Y&Q<<'!E:'!@<)20@#I D&!I!3B06)S<V+R at L)QX9
+M&A@@)3,].C8V.#$?&QT=&AR%Q-LL+L+<*BRQW9MIKAM+>EDP-TR-TU-1 at 4E*
+MS#Y*1#<_,K6SSD!#5\=.65K%4KQKGB6BGFF!0P$\ 8@ ^]HX-3<_(1H?*S W
+M.C,M.2A=3VY_&1,8&!56&!08(2 <#I$D&1E'0Q,5%"PS)!TA'!80$0\3&BTZ
+M/3L[/2\<&!H:%QN'R-<F,\?7)BRQV9AFI!9.?5 at M,T>(U41#AD-)R3A%/2PW
+M,+:OT4-'6LI175V_3;=EEB&CF&5Q*@$T 80 ^^<^-CD]'ALC,C4[.S,M-RIJ
+M6G:&'A@='1M<'AH>)R8B%9XS)"=..!H4%RDQ)!TA'!00$Q,6%R@\/ST]/S$>
+M&AP<%QB+T.DI-=3O+C&VZ9A8G!-.>U<K*3B#VT YBSY&RS%"/BDU*,&^TT-!
+M6LQ/6%O02K1JG":FG6IU*0$R 8D ^]XG7#ME12PG(BTQ-#-&0#O)MV-H%U]0
+M%B C3%A^+A0U&1H?'Q(C3QD4(B\H)2 E(RLD'1P>(2%*22X@'A\>'B8K/2$\
+MM-DH,+'@)BJLRJ%OKJ$L(RYMPFF1TU)2J4P_OSQ%1S,X+W>RQL7'P<*VP+7+
+M6ZU8CB2>FF1^00$] 7D ^] 61QY,+QT<&B8K,2]!.#C)O6YM%5M,$AP?2%1Z
+M*A Q%Q@='1 I10H1$"0A'!<<&B(;%!,2%!E)2RT?'1H7%A\E.B$[N=4@,K;=
+M(BJLRYUKHIDF'29FMEV+U49$KD4^O#8]/BLP+7FORLO-R<F[Q+K)5JA2AB"?
+MEF!N* $U 7, ^]@3.1%!*!L<(2TP,S0_-CK8S'EY&F!1%R(E3EJ ,!8W&1PB
+M'Q0N/103$R$@'!<<&B(;%A<5%!5(22H<&A at 8&AXF.!PZO.<F+L+U*B^SV*)7
+MFY<G'B)EL4:"VT,ZLT,[OC$[0"<N)8&[W-[>W>+0V-'?4Z57BB6BFV5P)P$S
+M 6X H>0K2#(X+" <%QHE,SPW-RQ;8SY&'Q<5$A8A%Q09$Q49$P,AC!(2'2(7
+M'QTC(QT<'P,FR" 9&ALN,QXH*RHP,#$K,B1-2,4M*IW@)2FSRJURBF2%7VQ1
+MI7:"SW1&ED9#O#1"4CDS,WS!BY:(EY^AEZ;#7[A;>2:6C5IZ10$] 6( H=0=
+M.B F&Q46%1 at C,3PQ,"A=:4E+'1,1#A(=$Q 4#Q$5$0,?UQ 7$1,.$Q$7&A85
+M&!T;&Q40$14M,!LE*"@N+2\J+R)(2K\F*:+=(2>PT:)GAEQW4EQ*DFB TV<[
+MGC]!NB\[22XH+WR\DZ.6J+&RI;+'7+!5<2*9BUAK+ $T 5T H><C,!LA&!4;
+M&1PG-4,V,2YE<$Q.(AD7%!@C&18?%Q<:%@,DUQ(<# \2&!8<'!<6&1T;&Q42
+M$Q8L+ADC)B J+2LI+QY#1= O**[U*2R\TK-*<DEN4E0^>$YZVV at PH$ [OBPY
+M2RLE(X''I[VPP<C-P<G;6JY8=2>;CUUK*0$T 6@ ^^,A(R,K&A<?(AP:&!<F
+M0R2<K($H'!*M&6XF63638( 2$B,D'!$4,U(>&QT@)"<H(R<F(1D7&!@9)B,_
+M/QP\3XYK at T-CH-LI*[S=(B:HO;E=>Y"9BJ:<GTJ'S%I/54(Y=#A%2$ W,K+%
+MI)"+F96:DI_$=K%>:B20BF*$20$Y :@ ^]D8'!PC$A,=(!H8%A<@/""9KH8I
+M& ZI%6HB53&.7'P.$"$B&@X2'C41#Q$4&!L<%QX=&! 0$1(3(R \/!HY2XED
+M?4!AH]HE+L':'B2 at P*E,=82&>)"0C3R$T$U$7CLW<S,^/S4L+K+ K)V9JJJO
+MI+#)=:I:8B"3B&!U, $P :@ ^^TB'1TI&!@?)!X<&AXE/2:CM(DL'A2O&W H
+M6S>99((3%28G'PX6$B at 2$A07&QX?&B ?&A(1$A,4(1XZ.A0W4)1K at D)CI>DK
+M+LWR)BFPP+HS9F]N67)O8BB"V$XY7#HS<C \03(K)+O-P+>SP\3-P\G@=*E?
+M9B65C&5U+0$P :\ J><:)A\C)2HP%QL5$Q =0R(Z)A8@&AM+&!4:*!H8$!H6
+M$QHD'!P8*C$B R;/(R0E,#$S&A86%1L;*4,O+S%92!,;.C!&G- at H);;6*2^I
+M>KMBC\IIA(?&;$]ZTE5#*E5 ,S%"44 W)Y'"IY>5E9N8EJ#!;[9.6R6+AF-U
+M1P$[ :, J=P1'QL='R0J$QD3$1 7/!XR(!4;$Q='%!$6)!83#!82$1 at B&AD:
+M&AT7 QO/&AL<)RLM%! 3$A02)$ L+"Y610\3,RQ&HM at F*KW3)2VD at K%4B+U7
+M<GV_6$-YUD at X-$X],BP[2#4L(Y"]KZ2CIJZKIJW&<+-,4R&.A&%F+@$R :  
+MJ>D;)B B)"<M&!T7%1<</21",2$F'!U-&A<<*AP>%!P7%ATG'QL>$A87 QO/
+M'!T>*2XP%Q,3$A44(CXJ*BY40Q<7-#%+J>LJ+<GK+3*S?+M D[Y"1T>T8"YN
+MWDDM+$T[+R<Y2C(K&YS,P[Z]O\;%Q,3?<;-162:0B&9F*P$R :@ K^PV+R$Q
+M+"@U(!P5&",F1B49&!@;#Q at 7%Q 8$1D7#0\0$QD@(!H6(RDB)B8H,C<E QW)
+M'!H:(BPF'&$S3RPA1!X?)1==M]<H'Y_.+"ZS<+E<DLE-58?*=U5$:%A$$BD]
+M&C!!3SY *J*\E8N'?7M[8'/-8*Y%2Q]^9V-L/0%$ 98 J=LL)QLL)1\I&AH3
+M%B$C0",3%1<6"Q03$PP4#143"0L,$1<>'A@<'B,: QV#*S$? Q?)%A07'"4:
+M%EXP3"H at 0AL7'!9?O=HF(:;+*"RW=[52D<0]08',:$9";$LY&R0Z&BL\2#8U
+M):*WFY23BXB%:'S28ZM%11M_95]=)P$] 9  G>4T+1XJ(R$N'QX8&B8E02<8
+M%Q84$!H9&1(:$QL; Q';%APC(QTC'"@>'1T<+#(@&!H:&1<7'28=%UXP3"X=
+M.AD5'!-CQ.HJ)[+C,###;KL_D,(W.7K4:#P\=$PN$2(X%28Y23(T(*O&K*JH
+MGY>7>XKG8ZM*2""":61=(P$\ 94 ^^<L0#\L'Q]'+"XS5EPX,B0?(A\B)Q\D
+M)B8@)2,A'!\?%1TB'QX<(C(I)R\I)QT>'AT@)"8C("4\6BL1&UUW0!HE1B=>
+MLM$O)H*Y+S&YA<!9D<5-2G[1?E4Z2UY*'QLX0$5"43PU*6>UQ[_&SM77U-G>
+M7'$@.R!'&V$P. $Z 8( ^]$F-C,C%!0\)"PT4EDW,B4=(!T@)!PA(R0>(R$A
+M'!\?%1TB'QH<'R$7'BD@&Q$2$A07&QT:%QPS5"@.&&!Z/Q<@0"9;LM4G(XNW
+M*B_"=<%(CL4^.W[6;T([4E$\'1DV/C\_3C0K)&BPR,/*TMG:U]SB7FXA.1U$
+M&%H?)P$X 8  ^^0I,#8C$Q,[*RX_6EDT+28B)2(E+"0I*RDC*"8F(20D&B(G
+M)"(C(1 at 0'BP@'A87%Q89'1\:%QPS5RH0&F!X/!4>0QE9Q?(W(XG+-3'.;\P[
+MD,HT+WG;;3(M5%(R&14R.CH]3# E(6N[T\W4W.7HY>KV7&PD.Q]&&EL>) $T
+M 8( ^^\U7S\H.3 C6FZQP&Y83B<>&AP<(1HB)RH?(R8E(B at F+R0@'!\^/XR-
+M*" >(1PA)B0I(RH[+TXE'Q00#!@[$!<0+C-C2,,N)#A:,S:U.\-4FLA95'-K
+MCE,_/F(Z1#]%0T<\0SPW*26 at S]W:W.'>W-W:;2DPD24B(5E . $\ 4\ ^],M
+M43 =*B$44&NPN650224>&AP<(1HB)RH?(R8E(B at F+R0@'"$_-6=L%!05%1 5
+M&A<<%ATR*$<>'!$-"1(X%!H7-3A?0<@G'T)9+S2^*\1#E\A*17-P?T! 154L
+M0CU#04$Y0#0M)"><T>+?X>;CX>+8:R8UDB,@'U(O)P$Z 4T ^^$K2"X:)AT0
+M5VF^Q&5.1BHE(2,C*"$I+C$F*BTJ)RTK-"DE(1],/$-4#1<7&!,8'1H?&2 T
+M*4@?'A,/"Q="'A at 6-B%-/]<R'#AE-3C*)<\VF<U .6IS?3$T1U8B/CD_/3PW
+M/C G(26BYOOX^OWZ^/GT;28XDR4B(5,N) $V 4\ ^^DZ:"PB*2 at H-R/%TFQ@
+M2"8?(A\A)"<A'AHC)",H+QXH,!DH'R1Y.%4[*A\B*B4I(QHX)28?'QTH*A0B
+M)R%2K&LZ)TR1BJDS+K*\02FU6LE6C,-;4C5%E$(Q.%LS-C U+30T,#DZ*28X
+MN[:QK:"6EHY^239(:Q at D8%XZ. $Z 4@ ^]$S7!\;(!\?+A[!R%M//R,@)"$C
+M)BDC(!PE)B4H+QXH,!DH'R)^-S0>&1,5'1H>&!,Q'A\<'!HE)Q$?)!M6LFDY
+M)$>%?:XQ*+JZ/">^2LI%B<-,0S9*A2XR/TXE-"XS*RXQ+3$P)"@UNK2OJY^5
+ME8UX131.;ADE85<I)P$X 48 ^^(T52 <(B$A,AO0V5Q,/RLK+"DK+"\I)B0M
+M+BTO-",M-1XM)"2+1282&!86'AH>&!0R'R >'APG*1,A)AQBPV,>"AYD6J,V
+M+;;,1RG*1-4XB\A"-RI, at R0F04\;,"HO)RDO*RTJ(20UR,;!O:VAH9F32C93
+M;AHF8E at H) $T 4@ ^^,P*C8B$QTP1R_$TFE;3B4>*"(?)"(J'B8F(R(B)1<2
+M&AH8)AUS7$,Z*",F)2$R.BTA(1\@'1 at Z&A at A+25$<'JGIX^(1ELG)ZFZ62^X
+M=M%:4<!?62)!DCXU'5=#04!+.T$V%CPR*R TKL[2T-36MJ?8V&AI*R5Z9$LZ
+M+@$W 4< H,\L(RX@#QDL/RJ_R%9)0R$?*2,@*"<O(RHG)",B)1<2 QC8)A9Z
+M:3 at I'AH9&A at I,2PB'QT=&A4T%!4@*21*=G21B'!F,%HB(:^Y5"W!:]%+3KY0
+M2B-$@BTU(DHU/#Y).3PS$S8G)B SKL[/T-#2L*/5TV9O+B9_:44K'0$U 48 
+MH.$Q(C(E%!XQ0RC,V5A&0RDJ-"XK,"PT*#(R+RXI*AP7 QW8*QV%=D<R)1X:
+M&1 at I,2LC(1\?'!<U%Q4?+R-3A6U72# Z*G W)+;082_-:MI!4,!&/A=&A"0L
+M)4LL.3I%,S<Q$3$D(QLPL]79U^#DP;+OWFMT+">!:T8I&@$Q 44 ^^,J'R4C
+M&AXG'A>>UDY+2#$@'"0?(RPO)RLD("0G%!@9'!L;(B-G+Y#09R4L."8A'Q\=
+M("(F'2([F*%.:$2+KF'GDETRFKHQ+J2O>2.PC<Y5%HA;52A3G$8E3"@\1#I*
+M0S8V,3(Q,#DFK9O$;X6H64'0RXHZ/1V"<2DT/P%8 8( GM$@&QT=%AHC&!6>
+MST,\.BH@'"0?(RPO)RLD("0C$ ,5VA<8(B%M/9/%6QHA,B,>'" >'!P?&1LS
+MD:%/7S>#JEK=@4DJEL L**FN<B.YD<=.%(%-1BQ.BC(C2R K/3A(03$Q+"TK
+M*S8EN*/)>8VK6TO4S8LZ.!Z*>28H+@%2 84 L=XH("$B&Q\H&QFEVD,\0#$G
+M(RLF+#4X,#(K)RLK%14;'!P@*R-R1Z'28AD>,R4@'B,#(<<F'APOFIPV13J3
+MN6'D?D$NF\\W*[:]?2C%F\A,%G]#.AU,CR@?2AXH.S1".RXN*2HF*#0DPK?@
+MBZ"[8U/FXI8U,R&0>R8E*P%3 84 ^]TP,",?)2 S.AHPV41.1C,?("8?,2TQ
+M'1<C(B(D(1\@*2HF)")@6QRN=2XC(1\=("0C(!PC("PWF:REGU5HJ6'.E55#
+MD, X*HZ3C1NS+,5*7CU241]"FSED)4 P3#Q%&AXU,38L*C,[J9'&<'ZM;(G4
+MPC\W1CR 7B at XA@%' ;0 ^\LF+!L7'QHM,10PU#@_."P?("8?+BHN&A<C(B(@
+M&QD:(R8C)"-E81VG;2<<'1L9'!X=&A0?'"4OF:F9ASM3GE[/CDM"C\8S)).4
+MBAFZ,+Y#7#9'2RE(E"]?(#8B1CI"%QDP+#$F)3 ZM)G+>HBT<Y77OCHR1D&-
+M9RDM= $_ ;$ ^]@N,1\;(ATP,1<WXSL_/C,F)RTF-C(V(AXJ*2DE'AP=*"LK
+M+21G9BBR<R8=(B >(2,B'QHE(28KHJ=\7$!IKVC<C3LWCM4^)YB?EA[&.K]!
+M7C0\/!]%E2E<&RX8/31 &1<M*2XA(BXYOJWBC)C ?ZCGSD4O04.-92HM=P%&
+M ;L ^^8T)!H?)2,F*R]>T3X_3$(F'AX;+A at 4%A4;)"0Q('5<(R F)B5??I,H
+M'1L<'B =(1<;&4^,3B5)6,7AR2U1V-S8J58T=:Y%)&HFC2>F&F]-)TY at 3AH2
+M+ADP)$ ]+1Q,%R(Q-S8O*RL_J9?*=W.M6TG:T\E$.QY:+BM11P$[ <\ JM0J
+M(!(8'AP?'BA>T#4P/CLF'AX;*A00$A(;)"0Q'7)9'QPC)B9A@),E&P,:SAP9
+M'1,7&E**2AY!7,+1MQQ#SMW6G$(C;K1 'FLKCB.M'FA&'T!/0 at T %P<D&S0O
+M)AE)%!TL,C$I)B@^M)_/@7NR7U+?T\A .B%?,"U)- $O <8 ^^$R)189'QT@
+M'B=EWS<P1$(M)24B,!D5%QHB*RLV)7YA)"$K+R==?)HO'QD?("(?(Q@<'52/
+M3Q\]5\#3O"-)U>KJITH\=\-+(6PPFRFX*&E$&S=&/Q )(@XI&S$H)!E)%!LI
+M+RXD(R8]OK/FDX[!:5[NY-=%.2-A*RE'- $T =( ^]A&)BA"15\O,RA#STA2
+M1D$?("DJ%QL?'!89'B$D at L-:)!\C*!]C:(5&'!\<(1\D)4>)D:@Q+X5 9+K>
+MT;^SU]O4MU8D>:A6'QN(-2*4>3D\158C.)Z0<4HM/R0B%QXDJS,S/C4N)BHS
+MK)?#=VZ?;'76S)^R*"XP*&8^20$[ =4 ^\0^(!\W.E0F*!] SS]#.3L<("DJ
+M$Q49&!,9'B$HB,A>(AL@*")C9H5('1T<'1L@(DF.E[ Q*WXX9K;6U,.QT=O<
+MM5 D>*U3'!R*.1Z9>3$T-44/'61..!L2*1$7$Q at AJ"XN.2XH(2<QMI_&@72;
+M:GO7SI^R)2HQ)F8T-P$P <L ^]1%(R$W.5,F*!](WD-#/$ D*3(S&1H>'1L@
+M)2 at PD==J)R$H,21>8HI0(!\C)2$F*D^1G+0V,'\T9+O<U+VKU.SRN3\5=[I=
+M'AV012.E at B\R+3H()6I1.!@:+Q07&!LAJ"LL-BPC'B4SP++>DX6M;(+DX["[
+M)R\T(%\L,@$P =, ^^)-/"T]*B8G&!LOV4I,0U G(1\D&" ?)2 B)"(F8-)Q
+M(" E(B5B8QFX'B8@#AAG&IJWLZ\S(1]%2L?BV%5<V-_;PTTK-%%G'V,?(R2(
+M-UU,32>89BP>&1TS@'D>(#Q#TC T0#DR*2PWJKW6 at W3/5R.%QS-R.S*OD$5H
+M2@$T :D ^\E+,QXP'QL=$1,GU4 ]-DH>'",C%!P=(B B)"(J9M-O'1TE)"=?
+M7A>\'B <#A1C'J"_N+(T'Q<Z4,/7UU]@U-_=O$$D-E-G'6<@'QV',$P]2 MC
+M-A ,$!895U(/(#1!TBDM."XJ)"DUL,/8BX# 3AUVQS!L-#"SET1=. $K 9T 
+M^]5')Q0P'AHD&!DNY$<]-D\J*2TO&B(B*B<I*RDT9>"!)24L*BM?61S()2,B
+M%1EH**_!Q, U(QLW3<GDYF5HX_+SQ3PE/EEL(7$K)1Z3,4$Y/ 9F.1@;'A\;
+M5U(/)2Y#VRHN-BLF(2LZO];MGH780"YVUCAO-36[D$%:,P$O :0 ^]DZ*!\9
+M%AXC'18LQU9/3E$E(D K3(TM(1\D)"$DA--['B D)2=C722-'1TBAYI0'*Z!
+MJ-0R(R-$.;O4T4<VQMS=RDDA*"\]%QH>'B-P16=30C*$'1L6&!X=%D$>'$M)
+MT24S.CH[+3$><J70>V7,-R at UO2I%,3&+?8EO/@%) << AL$U(!(7$P,7\@XD
+MQ$Q 04LB'T$L38\M'Q\D)"$HBM1Y&QTD)RE at 6"*1'1<>C)M0(+*#I<\P(1LY
+M/[_3UD\XP=C?PST:*C$]%1H>'!UR/E=%0A96#!0.$!$6!BL5'$-'T1\M,S(U
+M*"X<>ZW4A6VV*1XEOR at _*3&5A(IF+0%! ;T ^\8R'!,;$Q8<'!(JT%- 05 L
+M*TPW6)<T)"8K*R at RB>&+(R4K+2U at 4R>;)!HCF*97++Z!K]HR)1\V/LGBXU$\
+MS.?US#@;,C="&2$E("!Z/$<[.1MI%1,2%A07"C$9)3])UB N,2XP)3 AB\'I
+MF''+%R8?QRU$+3B?A8UF*@%% <0 ^^ C&!HA)# [*C19ST5*8%0F&"$_K,H\
+M)AXB'B(EA-"0(R(A)"IB9R*94YR8L)0E)4B/U=@M(B9%0;++W%0U8)W8S$TB
+M6$T5(2$<'Q],4&16,"V!5SQN5U\2?Y,#)DQ+T2$N1SLW+!T9;*+,=&72."\]
+MGBH],C:%<WYC-0%  ;T ^\,<$1 :&R at P)"U1S#L[4TXH%2!%L\\^(ALB'B(I
+MBM&.(!\A)BQ?8B"B6)Z<MY8C(DB2TM,N(!XZ0+3+WEHS69C7Q4$;6D\5'Q\:
+M'1U-25-('2N26CUU86(8 at 9$&*41*TAXM0C4Q)QH7=JO4@&^]*B4PH"@W*#B4
+M>7U;*0$Z ;< ^]HE&"$A&R(M)2Y5UD([4U,P(2Q.O]Q&*",I)2DSB=Z@*"<H
+M+#!?726P9::FPYXH*E>4WN(O)"(W/;S:XE4U8*/MSCP<8E4:(R$<'Q]82$9!
+M)SVK=EJ8A80KEJ<4-T))U1PL/S L)!P<B,'JE7?5&"PCI"P\+T"@@HE?)@$[
+M ;P ^]@Q)B0M-DX@*C \&$)*658A+2$>@L5-*!TC(R$BA-"4(R(C(R=O:B.%
+MI;2PMJ,K)C6JT-PP(B)%4F'*>WY]:ZC>U%HA(!\A'Q\A(1HW0U]G50P?)Q<?
+M'Q8B&"<BBTM)SS%,'2I',T?9:Z++=FG/."P\CR4T*SM[?X1*, $F :X ^[PJ
+M'QTB*D0:)"HV&#D[2E C+!XDB\Q.)ALC(R$FBM&2(!\C)2EN92&1K;NYNZ,E
+M(SBPT-LQ(!HZ3E['>7U[9:/AS4X:(A\A'1P>'QLW.T];3@,4(0H4%PT:"Q@:
+MBD)(T"Y.'"5!+D/6>*O3A'2[+B4QD"8P(S^+AH-$)0$C :P ^\PI%!LB)3P3
+M)2LY'ST[2E,K."HKE]A9*B J*B at PB=ZD*"<J*R]M8":DP,?%R*HH)4:WW^HT
+M)!XW1F;3>WIU:*[SV$D9*"8F(1P@(1Y&04=63 TK,A4A)QDA&"8 at ED1'T2Q,
+M&2 \*4C>B<'IF'_7'"PFD2DV*4>;D9%)(@$C :X ^^8S6#,S/3D1)R]=T4 \
+M1&@E)Q\@-<=;'QT@)B(GB]"B)!\C)2YE:2&!LG9BVJ(E("VNQ-HT(B1 1;.^
+MXW9<8ZS4U5(A(20A'AX?(!PH3&ME73=OE#D?&A8Z458HHEY&TC X-#H\-+O=
+M=JO+=V?3/R,_:"4N)T1L=H-++ $X 9P ^\XK22LV0#L3+3-ATCDP-V0B)!\B
+M/,M;'QX@)B$HCM&B)!\C)3!G:1V,LGQGUJ$F(#.TR-PU(!PU1;._Y&I37:O:
+MT$4:'R(?'!P='AHG1F!;32A=;B(0#0D9)S0AI55%TRTZ-S4Q,+K8?[#,AG' 
+M,QLU9B<L($9Y?8)$)0$U 9P ^]TG.R<V0C\;+"U9U3 at M.FDL+B8F/==L)B$G
+M+RTUCMZS*20H*CAE8B*9PX-IY:TI)3B]U.0X)" R/L+,[W%'7KGIY448)"8C
+M(" A(AXU2U511RA@<B,0#0H;+#D?IUE"UBLX-3(P*,;GE<GEGGO7("$O8B4Q
+M(4Z(B)%+(P$U :$ ^] 9'QD7-S4M&RV Q$I'-SDC'B0?'+YP)1T@*B(BA,RN
+M)!\H*RQE9B)A7(.)W*4K(2. at M]\M(1\^0ZZPY'9A7JG.UTPI(B$A'AX?(!PA
+M3EML6DX_3F-O?)I)BUU+DUU0U3<R23D],[C:;*G);F?0,R=.1R8T+TIA9(%$
+M*P$_ :H ^\,<&QLE0T(Z+D*/Q40^+SDB&R0A),-P)!T@*B$CA\VN)!\H*RYG
+M9AYL78J/V*0L(2JFNN N'Q<S0ZZPY6A65Z;5TC\B(!\?'!P='AHC2U)E3T,Q
+M,2<J-E$57SU!E%1/UC(Q2S(R+[?5<:O)<FZ])Q] /R,L)$AJ:X$]) $\ :L 
+M^\0>(Q<?/CDM(R)IQDE -4 N)2LE(,B#,B0G,RTPA]J_*20M,#9E7R-V:HR,
+MY[ O)BNMR.LQ(QLP/+^_\FY)5K+AYS\@)2,C(" A(AXK249:1#DJ,C T/UL8
+M94$YE5A,V3 P23 Q)\/D?L#<AG?4%"4W.2$P(4QX=I)&(P$^ ;8 Q\HW,S!0
+M0Q=-/4JAS4] -D ='B A2,.)'1T@(R,D>,FW(R B)"0]9!YE6:64V:PO(ANC
+MG-<N(RA'/JV6WVM63Z7/UDHI)20C!2"O%T],D8M13%)_3C at S57O)2HM41L4W
+M+)I&0SNSV&RWS8N/VE0H3#AJ03M*HEB'.RX!2 &D ,?$2$) 8U0I7TY:K=%'
+M-2H^'1L@(T_'B1T=(",B)7O*MR,@(B0F/V0:<%FKF=6K,"(BJ9_8+B$@/#ZM
+MEM]=24>@U-$](B,B(04>KQM018J)3T=(>D<N)55ZP3Z)2T7&,"F9/C at WLM-R
+MOM*/E<=(($(S:3TT3*E8A#4H 44!I #'OSXV+TPY##XS/)C92S0M0R8E)R=.
+MT9PF(B<L+C)[U\@H)2<I+CU='WMHLIODMS,G(:ZMY3,E)#DYP*?N8SA#J^'F
+M/2 H)B4%(J\C43R(BTD[0'A&*!Q,><<YBT]"R2\IF#PW+[[B=\G?F9K>-28Z
+M+FA"-5*U79 Z(0%# :D ^\\R5WHL*S,Y/53%TD1/64HG)AXH5LV8(AT@)2,C
+M/\B[(R ?(2<K/QY6;(*:VJ\I'AZA@]0Y(2922JF"V(M6;9C)UD(W)B4@(2 @
+M'R$<15; XV=46X"R[&5PB]A$CE=&RC PCC\X.KG:N*ROK(;70"DQ=9*+>WM:
+M9)0M1P%$ 6L ^\A%;X\_+#I$-$+"V#M 24(D(QXJ7-"8(QX@)2(D1<B[(R ?
+M(2<I/QI?;XB?V:XJ'B6IA]4Y'R!'2*R"V'U(8I3.U#<P)",>'QX>'1\=0U"Y
+MV59"27:IW5)A at M,_D$Y%RRDJB#0P-KC6P;FWL(W$,2$K>)B+>X%@79 J0P%$
+M 6L ^\8N3'4H(#$W*#_*YSL\2T8N+2<P8]ZI)B$G+BXQ1-?,*"4D)BXK.A]O
+M?Y&DZ+HM(R2OD^(^(R-$1+R3YX,W7YS:YC8N*"<B(R(B(2,H1U' ZET]0GVU
+MYU1AC. \CE!"SB at KB3,N+L3FT=/7S)G9(R4F>)V0@(AG7)4H-P$[ 68 ^\\I
+M-SJ+BJ]+O9C,T$]+7T,A)"4P7\.=)ATB*B,@@,C!(1\C)B<H)1Y@>W*?T+XK
+M(B:G:=XU)25 at 4Z5DW))8:IZ8UDX\*"0A(B @'B 8-,NXTV0S4W6.TEUU<--2
+MBVA"P2TQFD,_-JJ[EIJ2EWK702LW=K<V)5E_BY-R4P%: 8P ^]LJ+CY^0WLL
+MBEC"VD8^4CPC(R0T9LB=(QL?*B0EA\O!(1\C)B,D(1IC@'>AT[\L("BV;=XU
+M(R)51ZMGVXE*7YN8VT,Q)B(?(!X>'!X0+L6TTU4I1VZ.S5%N;<Y'BU]!P28J
+MD3 at Z+*NYHJB>I8K(+B,U?,,U(UZ%B(]Q4P%: 8D ^]XM,#A_9J-%JGO3[$H^
+M4STK+S ^<M>L*R G,R\QB=W2)B0H*R at I)A]SC'JGX<HO)2S$=><Z)R121+IU
+MZ95 7*.?Z$,N*B8C)"(B("(7*<J\W%$A0&R7W$YL=]U$AF$^QB<KDS<W)KC-
+MM\2[P9O4+B$YC=I!)V"$B)1P2@%5 8< ^]^@T=)1,SLH>93$U%=$8&$@("0O
+M<,"U)ATD*R4K@<?#*2$>)289(!M!A5NARLDM)2>H4MLW)1Y.2IM.UZI87U=Z
+MTEH[(B,A(B A)!\A+$Z:S6(]4V6&W%A;7-!(@VA-V34UFTA%/JBNBGV,E'+/
+M/B> ?<4]'B);;7!]>@%I 6$ ^[M.9)Q(&3 N?8G(VD\W4UHB'R,S=\6U(QLA
+M*R8PB,K#*2$>)2(5'!=$BF"CS<HN(RFW5MLW(QM#/J%1UJ%-5U=ZUT\P("$?
+M(!X?(ATC,4Z>SU,S1UZ&UTQ46<L]@U],V2XNDCU -*FLD8B4GW_#,R9_@<L\
+M%A]>;W%^? %K 6  ^^B(IL=<-4<UB9K4[5,W5%LJ*R\]@]3$*R I-#$\BMS4
+M+B8C*B<:(1Q4EF.IV]4Q*"W%7N0\)QU .[!?Y*U"4UZ!Y$\M)"4C)"(C)B$K
+M,UVHUT\K0%R/YDE28]HZ?F%)WB\OE#P]+K; JJ*JN8[*,".-D]Y*'"%<:W1_
+M=P%G 5T ^]9IV-U-+#) 9WVZS$I 1%P?)R at F?L6V)A\@)1\E>;W!)" A'1L5
+M%AHRED:>S,LL(RRG2=DU)!LQ49%!U+-189&)UU%&)24C)"NL(295:WM8T&8_
+M6&-TWU186=12DWM)Q#HRH3] -)V<=UTU>V#(02Y:.2HV(SAV<I5C<0%3 4\ 
+M^\5(M>)((B8U<XV_T$0S-U4A)B<JA<JV(QT=)2 J@,#!)" A'1<1$A8UFTN@
+MS\PM(2ZV3=DU(A at F19=$TZQ(6Y.)W$8[(R,A(BFJ'R1@>X=CTE<U3%QTVDA1
+M5L]'DW)(Q#,KF#0[*IZ:?60[A&B_/S-;/"PT'3=X;99F=0%6 54 ^^9NW/M5
+M*2DU>I7+Y$<S.%8I,C,TD=G%*R(E+BLV at M+2*24F(AP6%QM%ITZFW=<P)C+$
+M5>(Z)AHC0J92X;<\5IF0Z48X)R<E)BVN(RAM at YYPVE,M15I]Z45/8-Y$CG1%
+MR30LFC,X)*NNCG!"DGO+03AF/BHV(#9T:IEH< )4 /O61]+74R4F0F5WN\5!
+M/E%.*!\H*(;$PB4@(20D)V/%OB8@'R,3$A47(J ZK,/0+R0RI#O:/R0?,4Z7
+M)-"^46.+E-E;2R,E)U1D42(I)$1<A]-J75M@:]Y284'24'1O2YP[,JM$-SZ1
+MH5I18V)GN,B\7Z$I.R&(:EUO=U8!2P%) /O;4=?.4C$H.VZ%O,D_,41'*AXG
+M+HW)PB(>'B0F+6G(OB8@'R,/$!$3)J5!L,?1+R(TLS_9/2(;)D.<*-&Y2%V0
+ME-Y00"$C)5)B3QXG)D=8@=!@5D]::]E&6S[/1G-H2IHV+*(Y,C22GU]7:6IK
+MLLR_8:$C-R2.;%5P?%D"40#[Z%ODXEXT+$1ZCLG=03%$2# J,S>8V-,J(R8M
+M+C9NVL\K)20H%!06&#"R0[K3W#0G.+])Y4(F("-"J#3>QCQ6E9OK4#TF)RE6
+M9U,C*RI'9X386$U(573F0U1&VT!P:4>>-"VF-B\NG[%K7&AN?</6T7:J)#\F
+MBV=1<7Y7 5 !4P#[RE/2RV$Q.T%[;JW$34Q:/RLE)22#NKTE'R(C(1]5KKLC
+M'QTC(QPA*R"A<*>\T2TA,Y1%V4 at G("<TA#+1P&)5C9S0848K+J<V?)DE(!LJ
+M+A_*95Y<7VC83U0TQDU&8DU/,S"L344[4,6. at J9C/D(G**(G*4EYF6AX?HU_
+M 4(!4 #[TUC2T& J,SB"=;+,1CU+-B at E*BJ+P< E'R(C(21;L\ E'QTC&1P9
+M(22F>ZO!TRT?-:1)V$0C'!XOA3K4N%1)CYS453LG*J4V>Y(='!TM+AO%85=0
+M6VC30TLRQD%'84A+,2VD14 Q4L2-?YU=-STG**<E($>$I&QT=HB" 44!50#[
+MXV?AY6PQ.3R+?K[@33M).C L+R^/S=(N)"DJ*"=DPLPM)B0J(R,@*!^]>\#&
+MVS0D/:I5YTHI(B MB$#BR4M$E:/F7#HM,*H[AYLA(B,K-R#05TM)4VW>0#\T
+MS3Q*8$-0+2VJ03LI6M"*?Y]6+CLN,;0J($R'I6=L8X:" 4<!6@#[OES,RFDQ
+M/T5:89[%;E5H3B at F(2M at MK\B'Q\F(R4^'+LB'1LD'Q<B*1JN9Z:NTR\@-7]@
+MS&,G(2=$0:?'R%AEB)G-?%(E)Z6*?98F)7-:O;*V7UI at 5&S<6TZ$TTH_7$8M
+M&B>]3DM#A]1W8U5=<"\B)$HN'I>>@6UZC&)+ 4D!3@#[R&+/TFHM.#U at 9Z++
+M9D170B4F)C%HO<(B'Q\F(R="(+\B'1LD%QL;)B&R<JFSU2\>-X]DRU\C'1X_
+M0J_*P$I9BIG1<$<C):6,?I$@(G1<O;.N54Q.3FS73T6"TSX^63\G&"2U1D8Y
+MB=-I33Q%7"$?)44G&I^EAV]V:%%: 4P!3@#[V''=YG<U/T-G;JS>;4-61RTM
+M*S9LR=0K)"8M*BU**LLK)"(K)2,B+B#.<\.XW38C/Y5PVF4I(R ]1;78T4%4
+MD*#C=T8H*JR4BYPE*G]:Q+:\34))1W'B3#F$VCD]5STH%"2[0D$QD=]7-R<P
+M2!<=)E P'Z6PCFUN5DA0 4P!4P#[NV/&R&\A/4E=746_8$=R1B<D)!UGJL$B
+M'!PC)"H<'\$D'B A'!HC+1>I9:VDU2\A)F)TT&HF)"1%.*?0S&-5?(/ CU,J
+M**.:=)<M(95,P+"M9V!44TW68EB$S4XE-E at N0BO 5CQ#<\Y03VQ6<R8E(5PN
+MOI"#44)]6690 4<!40#[R&S-TG(A.4)C8D?$7#QF0"<D*2-OL<0B'!PC)"H<
+M'\ D'B A'2$6)1VM<+"HUR\?*')XSV8B(!M .:_3Q%5)?H/$@T at H**2==Y8I
+M(Y))O["G85=&3TW15D^"S4(C,4\G0"BX3C<Y=<U#.U0_8APE(5 at JPI>(4T)[
+M2V!< 4X!6P#[UWK9Y8 J04EJ9T_383EC0RXK+BASO=8K(2,J*S,A),PM)2<H
+M*"(6*1S*<\RPWS8D,'B$WFPH)AT^/+7AU4Q$A(K6BD<L+Z^KAZ(O*ZI1R[^X
+M6$L_1U+<4T.$U#T=+T\F.BB^2C(Q?=DT)T$Q82,N*& RRJ**3SUS.F%9 5 !
+M8P#[MU3"Q70C+D->*Q[$@F*;9"8G(2%5D+\@'1TD*"4<2+\D'"0F'F-17Q^G
+M8*J*T"\A($AES8 F'B)&-Z?!S5A5=%2TBUTE)YF?AIX?)BM)H*985U946#[<
+M559KPTDW&5%222VY2#8^<\\J)V(P(1T=)5ACS*13/9!F;'Z! 6P!DP#[QEW(
+MSW<C*S]C+1[)@V"78R8G)29=E\(@'1TD*"4>3< D'"0F%5 at D,!RK:JV/T2\?
+M(E9JS'TB&AD_.*_&QTU+=E2Y at U(C)YVDBYT<)B9)HJM:6%%(5#_924QIPSTQ
+M$DA+1RJQ0#$V=<XE(58D'2 B)UEET:A3/I!A>(B& 7,!H@#[TFG7XH4L,T5H
+M,276AEJ/8BLN+2MAH]0I(B0K+RXB3\LM(RLM(54 at -Q['<L>4W#@D*EUVVX4H
+M(!D^.;73V$-%?EG(B4\E+*FSFJLD+3%"GJUB3$5!3$+E1D)KRC at J$4A)02JW
+M/"PP>]HC'%,I(B(D(EIMW;),,HE><9*2 7X!K@#[NTJ.P(@L.T4A'BZP at T1V
+M>"HE'QY2,[\F&QXI(2,A>[@D'2,D*5]89QRC2:5LS#4C(S8N7(LD'R-(/):P
+MS5I>2R<^?T\>()6^EZ<H)3Y25IPV*UA=7(S88$MAND4W24]-4"RQ4CXW1L(B
+M'; E(R$9*:;&TK5'<E1#T]31 =@!WP#[QU&2R8 at I-3TA'RRV at T)R<2HF("!9
+M.<(H&QXI(2,IB;TD'2,D(F(I/!ZH4JIQS#4A(#@T6XLD&1I .INYR5!01R%%
+M>T(;'9C%FJ<H(SQ05)XZ*U%/48G44$%@NSDK04A(3BFI23 at U2<(@&JTC'1L6
+M**S+UK='=E@^U]S9 > !YP#[S%RFX9DQ.$0F("Z_B#QF;R\Q*R1;0M P(B4P
+M*"HOD,DK(B at I*U@@/!R]8K=TW3XC*#X[9Y0K'AH\/*?'VTA)3R)0 at 4(=)Z;1
+MJK8Q)S9,6*8U(DA&4(?C4C=?OC8H/T9%2"FM23$Q2\LE(KDH(!P6);/8XKM"
+M<%(YX^_L ?,!^P#[M3=IM8<F0#8>.HZ@;#18=" B(1\>%,$F&!LB*"8B?KLD
+M'2 H(EYS912H,)=:S3LB'2HL<IDF(B=12HVBRF1@*R!&9S F+97"@FHB)3=6
+M.H,@%UE34X[04TLD-#M,3%532BBU2CL^28T?*"\]2&6'F=;#3&MF4D-0K=;7
+M =P!W0#[NSMLOHHF/2\=.Y"E:"=(9!TC(B$C&,(F&!LB*"8JC, D'2 H(F1E
+M6AFM.9U?S3L@&2LN;YDF'!Y'1Y&IR%I,'AM,7R0B*9?(A6HB(S)1-X$?%5%'
+M2(O,0T$C-2] 1$Y.2"6M03,Y2XL=*"\]1F6)G=S(4&UG5$92LMW> >,!Y #[
+MQ$5ZU)HM/S8</)2Q<"="9B4N+24E(,\M'R(I+RTPD\PK(B4M*U]>6AO"1Z9A
+MWD0B'BXR=Z(M(1Y!1YNUVE)$'Q9392DJ.*S9EWDK)R].-X8<#TM 1XG;13<B
+M."P]0DQ+0B6Q02\V29 A+SA"2&J1J>O56G-H3SY.Q_CY ?X!_0"BLR89D),H
+M/S--1H*)B#I<?28A)!@7$K\D'1H@)"<?<KXA&P,AUEYJ8ARC(Y(VS5 at C)2YU
+M0* C(2)0185)TE98+TAR+#XE*HZKDZ8C)$!7'U$E2%A+6&_)23U):S1"2&53
+M/!^B3SLW-5"DS=C=T:E^7,W7Q\K-0V_6U]W> =X!X #[LB,;FI at J0#%+2(B,
+M at RI%;2,B)1H<%+\B'1H@)"<G@,,A&R$A)&!L8QZH+9@[S5 at A(S-[1*(C&QE$
+M/H=-SDQ(*49X(3(C)Y&QEJ8C(CE0&DX at 0U!!4&S%.3-(;"@V0%Y..AR:1B\P
+M-$JDSMC>U*V$9-+;R\O/0G';WN3E >4!YP"BP"LAK:<P039%1)&:CBQ$<2LM
+M,!X>&L at G(B$G*RXMA\\H( ,FU%QG9"*]-YT]WF$C*#: 3*HJ(!D]/8]9X$1 
+M+DJ!(34H,:' J+4L)C=.&$X>0$P[3FK4.RE';R4S/EQ+-!R>1BPN,4NKV^GK
+MXK^5=^?MT];3/V_J^03_ /N7'Q1NBR Z/T5%?'Z at 2%5@)R(A(!5=P"<>&" K
+M)2!PMB(<'BDE96=G':8M>Q;,9R<D0&-(HRP=,TTQ=A[.6%-[5AY:1!PHD:"F
+MKB,D/6 I(Y132')4<Z13.FT[-#5*7TH_,&U'/#Y,-FZ)MES26"LATLLX0DI[
+MSM/AW^ !WP'= /N1&Q1[E" [/T%)@X&@/$!2)R$B)1IBOR4<&" K)2A\NR(<
+M'BDH8FMD':XT at AS+9B4H2G%/I"P7*D,J=B#)34A\6"!//!HFDJ>JKB,B-E at B
+M'HU,06=)<*-#,&HX*"E"6$4]+65 ,3=*,7*+N6+*3B$;U,\^1DU\S]GIYN<!
+MY@'D /BB(QF,I"4^1#=$CH^I/SY8+BTM*AQGRRHA'R<R+"R!QRDA(RXH8&5D
+M(L(_ at QO:<BDP4GI:KS$<+#DI?R;62D6'7BA,.AXKG;*\O2PF-58@'(Q*0&9&
+M;J]%*&@Z)29 5D,W+6D_,#5&+WZ at T7786"@@Z>%%3DU]W/@$_P'] /N-(CE>
+M82,W.#XV>V>P/&18)B0D&AQFP"L>'"8B)2%?J2$>'B8C9&ME&YL;>1:]AQX:
+M1TY6JRDF'D at M+B9Q1$M<5%-<0!PFHY:<I"<C-58N>FEE6459/"9+/T1"+2A.
+M0SA$*BU&0#\_*8>JPW_(/R<BUL5!;6&OW.#>W-T!W0'A /N$&CML:Q\Y.C at U
+M at FRT-5)((R$C(21PQR@:&28C)2-JKR$<'B at C8VMD'JD=>!>]AB >45Q>K"H?
+M%4$F*BAS.SM544M2.1 at CIYVDIR(?+T\F;UY?435*/"M +S8V'AU&/C4_)"=!
+M.#@Z)I:MT)/'-Q\BT\,_:EVQX>7GY>8!Y 'H /B<*D%]>R1!0B\RBWF^-D],
+M*RLO+"IXTC(@(2\N+B=KN"@A(RPL8F)A(+HE=QC$E"@F6V5BN2LF&3 at G,"9[
+M/S543T5,.AXKL:BXMRTE,$XD;%U653= -RT_)R\Q'!I$/#4\)2H_-#8X)J#%
+MYZ/3/B4IZ]5#:%.U^/P%_P#[H"$Y56,A+#4M)'%<G#9M6"XA)2$@6[<L'APG
+M(R8;4W\@(!HD)%MC;2.>&CH[LY at E(44[9+ at L("Y<-QDY7#E>7$Q244P='I^#
+MF* C(CM>.7!K;%T]3#NC,3U!+B<X01X=/R\E03<[-CJ"J,%\OCLH)\R^7S]Y
+MVM79X=_> =P!W0#[G1\]86T=+C<F(GEAH"Y;22P>)"@H9;XI&ADG)"8=7H4@
+M'AHF)%IC;!VE%S= M9<B(TQ':[DM&25,+AT_8#-03D9(140;'J2,H*,>'C57
+M,69 at 9E4M0CVI*R at M(B(V/!L:.BD?/"\T,3>3K="3OS0?(=#!7#UYX.+DY>/E
+M >4!Y #WMS%)=G\B-C\D)'UMK#)623$H,#,N;<DS("$P+R\A7XXG(Q\J+5E:
+M:1ZQ'S=#O:,J*55.;<8N("E0+A5$;#A)14%"/D =);"<M+,I)#95*UY?75DO
+M.#FH)!XF'1TP.1D:-RHB.BLR+S><QNBDS#LA)N7/6CF \?L%_P'] /N-'C)%
+M7!DV)BTE7TRG,F-7+20I'AI[M"<=&B,A(R N4!\<(QHD56=F(Y,J4F.FG"0B
+M3#-OO2<A)4I%>(HC9%ME35)D7R(GEH..D",B,59;7UQKNT\YFR5 /BTF@% X
+M'CY)(S at H-"Y#07N?NFZZB3$DQK=;:=';V]_=I]P!W@'? /N1(CA19A4X*"4C
+M:%*J*E%(*R$H)2*%NR09%R,B(R(Y5A\:(QPD5&=E'9DK5&NJFR C4CUTOB@:
+M'#Y"@(X=7$]7149652$IG8R6DQX>+%!455%ELS\ODQ\U+AX@@%(Z&SA$'3(C
+M+"<^/H^FRX;#B"TBTKU79\S>Y^C>I> !YP'F /NF+C]D=AI ,"DE:%NX,$Y&
+M,"LT,"B-QBX?'RPM+"8Z7R8?*" M4UYB(*HX6G&TIR8F64-VRRDA(#E @I@@
+M6DA-04-,32 OJ:*LHRDD*DE+2U!<MT$IER(K)AHAA4XU&3E!'C4A*"4\/IG!
+MY)G3EC,GY\9/8>'V_O_[P_P"_P#[GAHN/5H6*1TI&T5!LR=U5#,@*B$=7JTI
+M'AHB)2$?(#(;'2(?(U%F92**5T=;F:8F(C\G;K\H(24V.E@@55936%U<9&(E
+M(XZ9AS,@)#%)5V^K9#%!1BA'0B at CAE:&AW\^5B(M/2LX.D)GF*I8I(TJ(\_'
+M4E1=9VQW<GO? =T!X0#[I!XT2F,2*1TA&4Q(MAYD2#,=)R at E9;0I'!<B)B$A
+M*#@8&R(A(U!F9!Z475!FGJ4B($0M<< I'1TO/%T>24I)35)055<D*)>ECS8=
+M("Y#4&>B72LT.A at W,B @B%N.BWPY41TG.",R-3]ZH[MPK9(J(\VZ.3]$4UQG
+M9G;B >@!Z@#[LR8Y5W$8,B8H'4M1R"AA13 at G,S,K;K\R(1\K,2HG*C\@("<E
+M*D]=82.G;EQPJK,G)$DR<\LL(R$C.FHC1$-!0T]+2TPA+:>ZI40G)BX\1V.B
+M5"XU-1HY*AP at C&>*AGPW3ALJ-A\M,S^'OM:#Q:$Q*NG'-#]066!K>X[\ O\ 
+M^Y(=+C15$B8A*2 V,+,J67 E)"0<&%RA+1P7)"$D'ADC%!TD'2(_:6DA at 48F
+M2W^G(1\R+E^^)2 B(CY93CI955Q56U->*!V.FU=W&R0C/U*GH%I-0CI40B at H
+MFT>1?EC905,H-#0V-D!$4(:31)TF(B/3LWE/X.'BWN34X0+; /N2'# ^6A(C
+M'24>.S>U)DYD*2,<(AYCJ"T:%"0B)!X>*A(9(1TD06EG'HU0+56$J!X<,"Q=
+MOB4>'QTW440R3TE.2E!(4R,AF*5:>!LB(SE(IZ!.2SHK0S$=))U3G(E;T3Q.
+M(R\O+C [05^8HE*<(R$AT*YR2-C9VM;9S.4!Z 'F )JC*#A(9ALK(RLB/D/*
+M+DUG,2\J*R5LLS8?' ,MWB4A*Q8>*28H/V!C(*!@.5^0M28F-2YAQRXC(1LV
+M33XN24)%0$8^22$IJ+AJA2(D*#1"L*5)33 at A."@=*:%8IXE=USE+(2TM*BLX
+M/VNMNF.S+R F[+MG1^;IZN;FW/H"_P#[E1PH,%(1(1XB'"@7K3-,<BPC*"07
+M(8$P'AHA)"8>$A<4&B$?)$5L9B5N.1LQ9*PD(B\A$TD@'B$B,4A6.6I28&)8
+M5V8H((TS?0\A($=)4UUM3B])944Q2*Y4GX=1:< Y5B at W,BLV03E4:65J(2 C
+M)=.W7RW9V]O<W^+C > !W@#[E!DH-U81'AH>&BL;LS5'<"XB)2H=*(@P'!<A
+M)28>%!H0%AX?)D=L9!]X0A\[::TA&R@>$DL@'!X=*D!,,6!&4E=-3%LC(I8\
+M?@\?'$=$2U]M0BU!4C8H2+!;K(]8;;TT42,R+2,O/#9;<VYQ(!TA(]:X72W=
+MX>'BYN;J >D!Y0#UHR,O0& :)B D'BTCPCE";#8N,3,D,9,Y(1\J,"\E&!P5
+M&R8H*D5C8""*4"M%=;HI)B\<#U$I(2 ;*3Q&+5H_24U#0E$A*J1*B1 at D(5!"
+M16=R/2\_12PH4;1DO:-7:+\R3R$P*R$M.C9D at WY\+B4C*/#%5S+Y"/\ ^)4>
+M)B5)$R <&ADF&ZLL98PS*2,B$C)!(A\9(1XA'A$6%A,@(B4J<&\E8T<E-$NT
+M)R0A)&]@&!H9(QY,82Y<4EY26EE>+AY%=1DE(B)AC4Q3G4TO1%PR6)Q0J(9Z
+M1E=P/E8O03,H*$ E&#9$'R,@(230FW9/W>#AY /B N8 ^Y$:)"M-$QT8%A<E
+M&; O88<P*"0H%CE((AT6(1\C'@\2$ \=(B<L<&T>;$XF.U"U)!T=)W5D&!@6
+M'A=$5R921E!'3TY3)1U,>QDC'AQAB498GT$M/$XK6IU6LY*#2EMR-T\J/"X@
+M(3HB&CI%'2$>'R+4G71-W^'BY>GIZ at +K /B@(BDR5QPE'AX;)!Z],5F".#0O
+M,1Y"4RLB'BHJ*R44%Q44)2LK*F=I'WQ:,41<PBPF(RE\;B$=&!P60%$B3#]'
+M/45$22<I6(0>)R,A<(Y!7:,\+SI%*F"H6\"ECT)3<#9.*#HL'B [)!Y"4"$E
+M(B,FZ:-L4O7Z^_X%_P#[C1\@($ .'QL;&B9,IC)N52LG("$3("T1)ALB)2 C
+M%!X4$QX>)3AR:2%94"<O)[8L(C%[3PT@)S4>+%5F5&!-66987&4G)6<1)"$@
+M'8S;1E:20S-7)8:C6IQ^BUQ)-%!'6B(_,2LP1"DC,KPK(1\C)*MO:2W8V-W@
+MW^?F ><!Y #[B!@<)4(.'!<8&R1,IS!H3R<H)"45*#<3)!DB)B @$!8.#QP>
+M)3IR9QIB52<W+KDI(#:"61$@)3(9)4U<2E1!2UI-45<>(FL6(AX<%HW805N4
+M.S!/'XFG6J2+F&5*-U1"51TY+"0G02<A,KDH'B C)*MP92G at X^CKY.OJ >T!
+MZ@#YE2$A*DH5)!T@'BA3M#)A2B\S+B\;+C\;*1XK,2DH%AP3%"$E*CAI8QMN
+M83 [-\<Q)3N+:1TI*C07)$E61$\Z0E-#1DXB+'4;)B A'9K@/F"8-3!+&HNQ
+M8ZJ:IV4\*T] 4ALZ*B,G0RLE.<$J'B$H*;IS72_V_?__^P/_ ?T ^X8>'APV
+M%1H<'6FE/D at I3DTM(Q\B%AL8$"(<)"(D)A44$AHB(B4M<60A0V$A.ABR*A]S
+M%1LA'R$E(2I376->75)N9V-F+2,?(R8<&12TUDI.CSQW66E\=*6-A5A)0S8[
+MA5$J-2 at O+SG@+AZ:'"(JF93(J=/CV][>W^+CX at +C /M\%QL:-!,8&A]NJT-*
+M)TQ(*R,?(A(@)1(>&B0D(B(1$! 8(" B*W%D&T]D'3X>MR<@=18='1PA'1 at A
+M2%%33DU"7UE66"8?&Q\D&A<2MM%$4I$Y<%!H?WBKE(Q<34(U.XE/)"\C+20\
+MX2@<FQD<*Z&9R:W7YN+GY^CJZ^H"ZP#UC2 ='SD7'!XC<[104BE$0S J)BD8
+M(R46(QXK+"<G%A44'"0D*BUH71Y6<B(X(\0O(WTC)2(D*"$8(4=.349%.EM/
+M1T\G)" D)AX;%[K>15J7.6]097^ O)^79$<W*C2#224R(2<C.N0K(:8A'RZC
+MG-:YX?C[!?^!_@'_ ?X ^W8<&14J%A@:2BDL/D(C36$E)!\E%!85$Q09'R0?
+M(A,8("0A(2(F<&HA.UX:11E<'R 6'B(D'!L?*D-/75E176U98E]A/"<?'WPD
+M&1F6I$I-BD;=X9A7HYUT1D)&-T*5-3\^&S@]-DO5+1 at P)1<=9'''K]O5V=W>
+MW^+CX@'B >, ^VP5%A,H%!884"\N/$ @25LC)!\E$!<:$1(7'R8?(!$6("0A
+M(1\D<&H;1V$611IB)!\2&A\>&1L7(CM%44M#3U],5517-B,;&WDA%Q>8GT52
+MBD+5VH]4K*E[3$1'-T*5-3TX%3,[*T[5)A<P(1,@:G;0N.3>XN;GZ.KKZ@'J
+M >L LWT>&!@M&!H<63 at T044B058H*R8L%AH<%18;)BXF)18;)2DF)B<F9V,>
+M3F\;0!MG)AX7(@,AOR(;(#D_2D(Z1E8_2$E--R@@(($I'!N>KD-7D4CCY9%<
+MO+Q]23\Y+CF.+C<Y&#$U*E#<)18W)Q@>9WG at SOSX_ 7_@?X!_@'_ )]G'Q06
+M'1,8&!H?/CM!(59:-"(D(Q05$Q00'APJ'R(=!"'8)"4N:VPC*'47%%A1'!LA
+M'Q\C&R(I+CQ-45=?65Q65&>80B$H)$8=&1S2Y4I>@E[:WMKAH7A-04<]2HXY
+M34LHHCHV/5?92)"/C8AG9%[3T=78W=W<W^/@W at +B *!=&!$4&Q$6%AP?/CP]
+M&U!2,"(D(Q(3$1(.'!PL'R(=(0,CV"8B+&ML'31X$Q==6!P8'1L;'1 at B(28T
+M0T9,5$Y12$A>DS\=)"!#&18:U-]%8X!:UMW2X*Z"3T%'.4J1.4Q'(IPU-#)9
+MV$&2E(Z+:61EW=S?X^;FY>CKZ.8"Z@"@;B$3&2 5&AHD*$,]0QY)3C8I*RH6
+M%1,4$B C-"8I)"@#*=$L*BYB92 [AA at 77UHC&B(C("(@*24D+CL\0DI$1SY!
+M7I%!(BDE3R@>'MSP0V6"8.CIV.Z]BDTX."]%B3!!/R.?,RPQ7>9*F)F/C61=
+M9NWV__X%_X+\^@'^ ?\ M%,?'!H5$Q04'2,W/1@>6U8](!LA$109$A$;'B@?
+M)B B'",B'B,C8VHH'8<T:C<7$AT9&QL#'L0I/D)54DE48TQ)3:NB.B4@&T<G
+M&P^=V&)5=F#4U>2H<$L_23)<BCA-2D8DVSTX.U?93<N)655=86?4UM77V=W;
+MWN+?X at +A /M)&!D8$Q$2$A8?-T(4%E-+.2 ;(1(1%A /&1XJ(2 at B)" G)B(C
+M(6-J(BF*,'!"&PT:&QP=&AL>(38Z2T<_2EE".SZAGC8A'!=#(Q at -GM)=6G9<
+MTMG at K7Y1/T<O5HP\2T9"'M4X-C!9UTO1E&!<76)NW]_=W^+FY.?JY^H!Z0'H
+M /M:(1L=&!46%ATE/$4<&DU(/R<B*!43&!(3'24R*3 J+"@O+BHJ(UIC)3"8
+M-75%(QPB(2<A'R,E)30T0STU0$\X,3ZKI#LF(1Q2,B(/J>-;7'%AY./HNHA,
+H.C\A48 at V0SHZ']@V+B]=Z5W at GE]=6%9O[/?]^_S__O__^_X!_0'_    
+ 
+end

Added: vendor/Python/current/Lib/test/testtar.tar
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Lib/test/testtar.tar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Lib/test/tf_inherit_check.py
===================================================================
--- vendor/Python/current/Lib/test/tf_inherit_check.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/tf_inherit_check.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,25 @@
+# Helper script for test_tempfile.py.  argv[2] is the number of a file
+# descriptor which should _not_ be open.  Check this by attempting to
+# write to it -- if we succeed, something is wrong.
+
+import sys
+import os
+
+verbose = (sys.argv[1] == 'v')
+try:
+    fd = int(sys.argv[2])
+
+    try:
+        os.write(fd, "blat")
+    except os.error:
+        # Success -- could not write to fd.
+        sys.exit(0)
+    else:
+        if verbose:
+            sys.stderr.write("fd %d is open in child" % fd)
+        sys.exit(1)
+
+except StandardError:
+    if verbose:
+        raise
+    sys.exit(1)

Added: vendor/Python/current/Lib/test/threaded_import_hangers.py
===================================================================
--- vendor/Python/current/Lib/test/threaded_import_hangers.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/threaded_import_hangers.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,42 @@
+# This is a helper module for test_threaded_import.  The test imports this
+# module, and this module tries to run various Python library functions in
+# their own thread, as a side effect of being imported.  If the spawned
+# thread doesn't complete in TIMEOUT seconds, an "appeared to hang" message
+# is appended to the module-global `errors` list.  That list remains empty
+# if (and only if) all functions tested complete.
+
+TIMEOUT = 10
+
+import threading
+
+import tempfile
+import os.path
+
+errors = []
+
+# This class merely runs a function in its own thread T.  The thread importing
+# this module holds the import lock, so if the function called by T tries
+# to do its own imports it will block waiting for this module's import
+# to complete.
+class Worker(threading.Thread):
+    def __init__(self, function, args):
+        threading.Thread.__init__(self)
+        self.function = function
+        self.args = args
+
+    def run(self):
+        self.function(*self.args)
+
+for name, func, args in [
+        # Bug 147376:  TemporaryFile hung on Windows, starting in Python 2.4.
+        ("tempfile.TemporaryFile", tempfile.TemporaryFile, ()),
+
+        # The real cause for bug 147376:  ntpath.abspath() caused the hang.
+        ("os.path.abspath", os.path.abspath, ('.',)),
+        ]:
+
+    t = Worker(func, args)
+    t.start()
+    t.join(TIMEOUT)
+    if t.isAlive():
+        errors.append("%s appeared to hang" % name)

Added: vendor/Python/current/Lib/test/time_hashlib.py
===================================================================
--- vendor/Python/current/Lib/test/time_hashlib.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/time_hashlib.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,87 @@
+# It's intended that this script be run by hand.  It runs speed tests on
+# hashlib functions; it does not test for correctness.
+
+import sys, time
+import hashlib
+
+
+def creatorFunc():
+    raise RuntimeError, "eek, creatorFunc not overridden"
+
+def test_scaled_msg(scale, name):
+    iterations = 106201/scale * 20
+    longStr = 'Z'*scale
+
+    localCF = creatorFunc
+    start = time.time()
+    for f in xrange(iterations):
+        x = localCF(longStr).digest()
+    end = time.time()
+
+    print ('%2.2f' % (end-start)), "seconds", iterations, "x", len(longStr), "bytes", name
+
+def test_create():
+    start = time.time()
+    for f in xrange(20000):
+        d = creatorFunc()
+    end = time.time()
+
+    print ('%2.2f' % (end-start)), "seconds", '[20000 creations]'
+
+def test_zero():
+    start = time.time()
+    for f in xrange(20000):
+        x = creatorFunc().digest()
+    end = time.time()
+
+    print ('%2.2f' % (end-start)), "seconds", '[20000 "" digests]'
+
+
+
+hName = sys.argv[1]
+
+#
+# setup our creatorFunc to test the requested hash
+#
+if hName in ('_md5', '_sha'):
+    exec 'import '+hName
+    exec 'creatorFunc = '+hName+'.new'
+    print "testing speed of old", hName, "legacy interface"
+elif hName == '_hashlib' and len(sys.argv) > 3:
+    import _hashlib
+    exec 'creatorFunc = _hashlib.%s' % sys.argv[2]
+    print "testing speed of _hashlib.%s" % sys.argv[2], getattr(_hashlib, sys.argv[2])
+elif hName == '_hashlib' and len(sys.argv) == 3:
+    import _hashlib
+    exec 'creatorFunc = lambda x=_hashlib.new : x(%r)' % sys.argv[2]
+    print "testing speed of _hashlib.new(%r)" % sys.argv[2]
+elif hasattr(hashlib, hName) and callable(getattr(hashlib, hName)):
+    creatorFunc = getattr(hashlib, hName)
+    print "testing speed of hashlib."+hName, getattr(hashlib, hName)
+else:
+    exec "creatorFunc = lambda x=hashlib.new : x(%r)" % hName
+    print "testing speed of hashlib.new(%r)" % hName
+
+try:
+    test_create()
+except ValueError:
+    print
+    print "pass argument(s) naming the hash to run a speed test on:"
+    print " '_md5' and '_sha' test the legacy builtin md5 and sha"
+    print " '_hashlib' 'openssl_hName' 'fast' tests the builtin _hashlib"
+    print " '_hashlib' 'hName' tests builtin _hashlib.new(shaFOO)"
+    print " 'hName' tests the hashlib.hName() implementation if it exists"
+    print "         otherwise it uses hashlib.new(hName)."
+    print
+    raise
+
+test_zero()
+test_scaled_msg(scale=106201, name='[huge data]')
+test_scaled_msg(scale=10620, name='[large data]')
+test_scaled_msg(scale=1062, name='[medium data]')
+test_scaled_msg(scale=424, name='[4*small data]')
+test_scaled_msg(scale=336, name='[3*small data]')
+test_scaled_msg(scale=212, name='[2*small data]')
+test_scaled_msg(scale=106, name='[small data]')
+test_scaled_msg(scale=creatorFunc().digest_size, name='[digest_size data]')
+test_scaled_msg(scale=10, name='[tiny data]')

Added: vendor/Python/current/Lib/test/tokenize_tests.txt
===================================================================
--- vendor/Python/current/Lib/test/tokenize_tests.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/tokenize_tests.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,178 @@
+# Tests for the 'tokenize' module.
+# Large bits stolen from test_grammar.py. 
+
+# Comments
+"#"
+#'
+#"
+#\
+       #
+    # abc
+'''#
+#'''
+
+x = 1  #
+
+# Balancing continuation
+
+a = (3, 4,
+  5, 6)
+y = [3, 4,
+  5]
+z = {'a':5,
+  'b':6}
+x = (len(`y`) + 5*x - a[
+   3 ]
+   - x + len({
+   }
+    )
+  )
+
+# Backslash means line continuation:
+x = 1 \
++ 1
+
+# Backslash does not means continuation in comments :\
+x = 0
+
+# Ordinary integers
+0xff <> 255
+0377 <> 255
+2147483647   != 017777777777
+-2147483647-1 != 020000000000
+037777777777 != -1
+0xffffffff != -1
+
+# Long integers
+x = 0L
+x = 0l
+x = 0xffffffffffffffffL
+x = 0xffffffffffffffffl
+x = 077777777777777777L
+x = 077777777777777777l
+x = 123456789012345678901234567890L
+x = 123456789012345678901234567890l
+
+# Floating-point numbers
+x = 3.14
+x = 314.
+x = 0.314
+# XXX x = 000.314
+x = .314
+x = 3e14
+x = 3E14
+x = 3e-14
+x = 3e+14
+x = 3.e14
+x = .3e14
+x = 3.1e4
+
+# String literals
+x = ''; y = "";
+x = '\''; y = "'";
+x = '"'; y = "\"";
+x = "doesn't \"shrink\" does it"
+y = 'doesn\'t "shrink" does it'
+x = "does \"shrink\" doesn't it"
+y = 'does "shrink" doesn\'t it'
+x = """
+The "quick"
+brown fox
+jumps over
+the 'lazy' dog.
+"""
+y = '\nThe "quick"\nbrown fox\njumps over\nthe \'lazy\' dog.\n'
+y = '''
+The "quick"
+brown fox
+jumps over
+the 'lazy' dog.
+''';
+y = "\n\
+The \"quick\"\n\
+brown fox\n\
+jumps over\n\
+the 'lazy' dog.\n\
+";
+y = '\n\
+The \"quick\"\n\
+brown fox\n\
+jumps over\n\
+the \'lazy\' dog.\n\
+';
+x = r'\\' + R'\\'
+x = r'\'' + ''
+y = r'''
+foo bar \\
+baz''' + R'''
+foo'''
+y = r"""foo
+bar \\ baz
+""" + R'''spam
+'''
+x = u'abc' + U'ABC'
+y = u"abc" + U"ABC"
+x = ur'abc' + Ur'ABC' + uR'ABC' + UR'ABC'
+y = ur"abc" + Ur"ABC" + uR"ABC" + UR"ABC"
+x = ur'\\' + UR'\\'
+x = ur'\'' + ''
+y = ur'''
+foo bar \\
+baz''' + UR'''
+foo'''
+y = Ur"""foo
+bar \\ baz
+""" + uR'''spam
+'''
+
+# Indentation
+if 1:
+    x = 2
+if 1:
+        x = 2
+if 1:
+    while 0:
+     if 0:
+           x = 2
+     x = 2
+if 0:
+  if 2:
+   while 0:
+        if 1:
+          x = 2
+
+# Operators
+
+def d22(a, b, c=1, d=2): pass
+def d01v(a=1, *restt, **restd): pass
+
+(x, y) <> ({'a':1}, {'b':2})
+
+# comparison
+if 1 < 1 > 1 == 1 >= 1 <= 1 <> 1 != 1 in 1 not in 1 is 1 is not 1: pass
+
+# binary
+x = 1 & 1
+x = 1 ^ 1
+x = 1 | 1
+
+# shift
+x = 1 << 1 >> 1
+
+# additive
+x = 1 - 1 + 1 - 1 + 1
+
+# multiplicative
+x = 1 / 1 * 1 % 1
+
+# unary
+x = ~1 ^ 1 & 1 | 1 & 1 ^ -1
+x = -1*1/1 + 1*1 - ---1*1
+
+# selector
+import sys, time
+x = sys.modules['time'].time()
+
+ at staticmethod
+def foo(): pass
+

Added: vendor/Python/current/Lib/test/xmltests.py
===================================================================
--- vendor/Python/current/Lib/test/xmltests.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/test/xmltests.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,21 @@
+# Convenience test module to run all of the XML-related tests in the
+# standard library.
+
+import sys
+import test.test_support
+
+test.test_support.verbose = 0
+
+def runtest(name):
+    __import__(name)
+    module = sys.modules[name]
+    if hasattr(module, "test_main"):
+        module.test_main()
+
+runtest("test.test_minidom")
+runtest("test.test_pyexpat")
+runtest("test.test_sax")
+runtest("test.test_xml_etree")
+runtest("test.test_xml_etree_c")
+runtest("test.test_xmllib")
+runtest("test.test_xmlrpc")

Added: vendor/Python/current/Lib/textwrap.py
===================================================================
--- vendor/Python/current/Lib/textwrap.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/textwrap.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,374 @@
+"""Text wrapping and filling.
+"""
+
+# Copyright (C) 1999-2001 Gregory P. Ward.
+# Copyright (C) 2002, 2003 Python Software Foundation.
+# Written by Greg Ward <gward at python.net>
+
+__revision__ = "$Id: textwrap.py 46863 2006-06-11 19:42:51Z tim.peters $"
+
+import string, re
+
+# Do the right thing with boolean values for all known Python versions
+# (so this module can be copied to projects that don't depend on Python
+# 2.3, e.g. Optik and Docutils).
+try:
+    True, False
+except NameError:
+    (True, False) = (1, 0)
+
+__all__ = ['TextWrapper', 'wrap', 'fill']
+
+# Hardcode the recognized whitespace characters to the US-ASCII
+# whitespace characters.  The main reason for doing this is that in
+# ISO-8859-1, 0xa0 is non-breaking whitespace, so in certain locales
+# that character winds up in string.whitespace.  Respecting
+# string.whitespace in those cases would 1) make textwrap treat 0xa0 the
+# same as any other whitespace char, which is clearly wrong (it's a
+# *non-breaking* space), 2) possibly cause problems with Unicode,
+# since 0xa0 is not in range(128).
+_whitespace = '\t\n\x0b\x0c\r '
+
+class TextWrapper:
+    """
+    Object for wrapping/filling text.  The public interface consists of
+    the wrap() and fill() methods; the other methods are just there for
+    subclasses to override in order to tweak the default behaviour.
+    If you want to completely replace the main wrapping algorithm,
+    you'll probably have to override _wrap_chunks().
+
+    Several instance attributes control various aspects of wrapping:
+      width (default: 70)
+        the maximum width of wrapped lines (unless break_long_words
+        is false)
+      initial_indent (default: "")
+        string that will be prepended to the first line of wrapped
+        output.  Counts towards the line's width.
+      subsequent_indent (default: "")
+        string that will be prepended to all lines save the first
+        of wrapped output; also counts towards each line's width.
+      expand_tabs (default: true)
+        Expand tabs in input text to spaces before further processing.
+        Each tab will become 1 .. 8 spaces, depending on its position in
+        its line.  If false, each tab is treated as a single character.
+      replace_whitespace (default: true)
+        Replace all whitespace characters in the input text by spaces
+        after tab expansion.  Note that if expand_tabs is false and
+        replace_whitespace is true, every tab will be converted to a
+        single space!
+      fix_sentence_endings (default: false)
+        Ensure that sentence-ending punctuation is always followed
+        by two spaces.  Off by default because the algorithm is
+        (unavoidably) imperfect.
+      break_long_words (default: true)
+        Break words longer than 'width'.  If false, those words will not
+        be broken, and some lines might be longer than 'width'.
+    """
+
+    whitespace_trans = string.maketrans(_whitespace, ' ' * len(_whitespace))
+
+    unicode_whitespace_trans = {}
+    uspace = ord(u' ')
+    for x in map(ord, _whitespace):
+        unicode_whitespace_trans[x] = uspace
+
+    # This funky little regex is just the trick for splitting
+    # text up into word-wrappable chunks.  E.g.
+    #   "Hello there -- you goof-ball, use the -b option!"
+    # splits into
+    #   Hello/ /there/ /--/ /you/ /goof-/ball,/ /use/ /the/ /-b/ /option!
+    # (after stripping out empty strings).
+    wordsep_re = re.compile(
+        r'(\s+|'                                  # any whitespace
+        r'[^\s\w]*\w+[a-zA-Z]-(?=\w+[a-zA-Z])|'   # hyphenated words
+        r'(?<=[\w\!\"\'\&\.\,\?])-{2,}(?=\w))')   # em-dash
+
+    # XXX this is not locale- or charset-aware -- string.lowercase
+    # is US-ASCII only (and therefore English-only)
+    sentence_end_re = re.compile(r'[%s]'              # lowercase letter
+                                 r'[\.\!\?]'          # sentence-ending punct.
+                                 r'[\"\']?'           # optional end-of-quote
+                                 % string.lowercase)
+
+
+    def __init__(self,
+                 width=70,
+                 initial_indent="",
+                 subsequent_indent="",
+                 expand_tabs=True,
+                 replace_whitespace=True,
+                 fix_sentence_endings=False,
+                 break_long_words=True):
+        self.width = width
+        self.initial_indent = initial_indent
+        self.subsequent_indent = subsequent_indent
+        self.expand_tabs = expand_tabs
+        self.replace_whitespace = replace_whitespace
+        self.fix_sentence_endings = fix_sentence_endings
+        self.break_long_words = break_long_words
+
+
+    # -- Private methods -----------------------------------------------
+    # (possibly useful for subclasses to override)
+
+    def _munge_whitespace(self, text):
+        """_munge_whitespace(text : string) -> string
+
+        Munge whitespace in text: expand tabs and convert all other
+        whitespace characters to spaces.  Eg. " foo\tbar\n\nbaz"
+        becomes " foo    bar  baz".
+        """
+        if self.expand_tabs:
+            text = text.expandtabs()
+        if self.replace_whitespace:
+            if isinstance(text, str):
+                text = text.translate(self.whitespace_trans)
+            elif isinstance(text, unicode):
+                text = text.translate(self.unicode_whitespace_trans)
+        return text
+
+
+    def _split(self, text):
+        """_split(text : string) -> [string]
+
+        Split the text to wrap into indivisible chunks.  Chunks are
+        not quite the same as words; see wrap_chunks() for full
+        details.  As an example, the text
+          Look, goof-ball -- use the -b option!
+        breaks into the following chunks:
+          'Look,', ' ', 'goof-', 'ball', ' ', '--', ' ',
+          'use', ' ', 'the', ' ', '-b', ' ', 'option!'
+        """
+        chunks = self.wordsep_re.split(text)
+        chunks = filter(None, chunks)
+        return chunks
+
+    def _fix_sentence_endings(self, chunks):
+        """_fix_sentence_endings(chunks : [string])
+
+        Correct for sentence endings buried in 'chunks'.  Eg. when the
+        original text contains "... foo.\nBar ...", munge_whitespace()
+        and split() will convert that to [..., "foo.", " ", "Bar", ...]
+        which has one too few spaces; this method simply changes the one
+        space to two.
+        """
+        i = 0
+        pat = self.sentence_end_re
+        while i < len(chunks)-1:
+            if chunks[i+1] == " " and pat.search(chunks[i]):
+                chunks[i+1] = "  "
+                i += 2
+            else:
+                i += 1
+
+    def _handle_long_word(self, reversed_chunks, cur_line, cur_len, width):
+        """_handle_long_word(chunks : [string],
+                             cur_line : [string],
+                             cur_len : int, width : int)
+
+        Handle a chunk of text (most likely a word, not whitespace) that
+        is too long to fit in any line.
+        """
+        space_left = max(width - cur_len, 1)
+
+        # If we're allowed to break long words, then do so: put as much
+        # of the next chunk onto the current line as will fit.
+        if self.break_long_words:
+            cur_line.append(reversed_chunks[-1][:space_left])
+            reversed_chunks[-1] = reversed_chunks[-1][space_left:]
+
+        # Otherwise, we have to preserve the long word intact.  Only add
+        # it to the current line if there's nothing already there --
+        # that minimizes how much we violate the width constraint.
+        elif not cur_line:
+            cur_line.append(reversed_chunks.pop())
+
+        # If we're not allowed to break long words, and there's already
+        # text on the current line, do nothing.  Next time through the
+        # main loop of _wrap_chunks(), we'll wind up here again, but
+        # cur_len will be zero, so the next line will be entirely
+        # devoted to the long word that we can't handle right now.
+
+    def _wrap_chunks(self, chunks):
+        """_wrap_chunks(chunks : [string]) -> [string]
+
+        Wrap a sequence of text chunks and return a list of lines of
+        length 'self.width' or less.  (If 'break_long_words' is false,
+        some lines may be longer than this.)  Chunks correspond roughly
+        to words and the whitespace between them: each chunk is
+        indivisible (modulo 'break_long_words'), but a line break can
+        come between any two chunks.  Chunks should not have internal
+        whitespace; ie. a chunk is either all whitespace or a "word".
+        Whitespace chunks will be removed from the beginning and end of
+        lines, but apart from that whitespace is preserved.
+        """
+        lines = []
+        if self.width <= 0:
+            raise ValueError("invalid width %r (must be > 0)" % self.width)
+
+        # Arrange in reverse order so items can be efficiently popped
+        # from a stack of chucks.
+        chunks.reverse()
+
+        while chunks:
+
+            # Start the list of chunks that will make up the current line.
+            # cur_len is just the length of all the chunks in cur_line.
+            cur_line = []
+            cur_len = 0
+
+            # Figure out which static string will prefix this line.
+            if lines:
+                indent = self.subsequent_indent
+            else:
+                indent = self.initial_indent
+
+            # Maximum width for this line.
+            width = self.width - len(indent)
+
+            # First chunk on line is whitespace -- drop it, unless this
+            # is the very beginning of the text (ie. no lines started yet).
+            if chunks[-1].strip() == '' and lines:
+                del chunks[-1]
+
+            while chunks:
+                l = len(chunks[-1])
+
+                # Can at least squeeze this chunk onto the current line.
+                if cur_len + l <= width:
+                    cur_line.append(chunks.pop())
+                    cur_len += l
+
+                # Nope, this line is full.
+                else:
+                    break
+
+            # The current line is full, and the next chunk is too big to
+            # fit on *any* line (not just this one).
+            if chunks and len(chunks[-1]) > width:
+                self._handle_long_word(chunks, cur_line, cur_len, width)
+
+            # If the last chunk on this line is all whitespace, drop it.
+            if cur_line and cur_line[-1].strip() == '':
+                del cur_line[-1]
+
+            # Convert current line back to a string and store it in list
+            # of all lines (return value).
+            if cur_line:
+                lines.append(indent + ''.join(cur_line))
+
+        return lines
+
+
+    # -- Public interface ----------------------------------------------
+
+    def wrap(self, text):
+        """wrap(text : string) -> [string]
+
+        Reformat the single paragraph in 'text' so it fits in lines of
+        no more than 'self.width' columns, and return a list of wrapped
+        lines.  Tabs in 'text' are expanded with string.expandtabs(),
+        and all other whitespace characters (including newline) are
+        converted to space.
+        """
+        text = self._munge_whitespace(text)
+        chunks = self._split(text)
+        if self.fix_sentence_endings:
+            self._fix_sentence_endings(chunks)
+        return self._wrap_chunks(chunks)
+
+    def fill(self, text):
+        """fill(text : string) -> string
+
+        Reformat the single paragraph in 'text' to fit in lines of no
+        more than 'self.width' columns, and return a new string
+        containing the entire wrapped paragraph.
+        """
+        return "\n".join(self.wrap(text))
+
+
+# -- Convenience interface ---------------------------------------------
+
+def wrap(text, width=70, **kwargs):
+    """Wrap a single paragraph of text, returning a list of wrapped lines.
+
+    Reformat the single paragraph in 'text' so it fits in lines of no
+    more than 'width' columns, and return a list of wrapped lines.  By
+    default, tabs in 'text' are expanded with string.expandtabs(), and
+    all other whitespace characters (including newline) are converted to
+    space.  See TextWrapper class for available keyword args to customize
+    wrapping behaviour.
+    """
+    w = TextWrapper(width=width, **kwargs)
+    return w.wrap(text)
+
+def fill(text, width=70, **kwargs):
+    """Fill a single paragraph of text, returning a new string.
+
+    Reformat the single paragraph in 'text' to fit in lines of no more
+    than 'width' columns, and return a new string containing the entire
+    wrapped paragraph.  As with wrap(), tabs are expanded and other
+    whitespace characters converted to space.  See TextWrapper class for
+    available keyword args to customize wrapping behaviour.
+    """
+    w = TextWrapper(width=width, **kwargs)
+    return w.fill(text)
+
+
+# -- Loosely related functionality -------------------------------------
+
+_whitespace_only_re = re.compile('^[ \t]+$', re.MULTILINE)
+_leading_whitespace_re = re.compile('(^[ \t]*)(?:[^ \t\n])', re.MULTILINE)
+
+def dedent(text):
+    """Remove any common leading whitespace from every line in `text`.
+
+    This can be used to make triple-quoted strings line up with the left
+    edge of the display, while still presenting them in the source code
+    in indented form.
+
+    Note that tabs and spaces are both treated as whitespace, but they
+    are not equal: the lines "  hello" and "\thello" are
+    considered to have no common leading whitespace.  (This behaviour is
+    new in Python 2.5; older versions of this module incorrectly
+    expanded tabs before searching for common leading whitespace.)
+    """
+    # Look for the longest leading string of spaces and tabs common to
+    # all lines.
+    margin = None
+    text = _whitespace_only_re.sub('', text)
+    indents = _leading_whitespace_re.findall(text)
+    for indent in indents:
+        if margin is None:
+            margin = indent
+
+        # Current line more deeply indented than previous winner:
+        # no change (previous winner is still on top).
+        elif indent.startswith(margin):
+            pass
+
+        # Current line consistent with and no deeper than previous winner:
+        # it's the new winner.
+        elif margin.startswith(indent):
+            margin = indent
+
+        # Current line and previous winner have no common whitespace:
+        # there is no margin.
+        else:
+            margin = ""
+            break
+
+    # sanity check (testing/debugging only)
+    if 0 and margin:
+        for line in text.split("\n"):
+            assert not line or line.startswith(margin), \
+                   "line = %r, margin = %r" % (line, margin)
+
+    if margin:
+        text = re.sub(r'(?m)^' + margin, '', text)
+    return text
+
+if __name__ == "__main__":
+    #print dedent("\tfoo\n\tbar")
+    #print dedent("  \thello there\n  \t  how are you?")
+    print dedent("Hello there.\n  This is indented.")

Added: vendor/Python/current/Lib/this.py
===================================================================
--- vendor/Python/current/Lib/this.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/this.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,28 @@
+s = """Gur Mra bs Clguba, ol Gvz Crgref
+
+Ornhgvshy vf orggre guna htyl.
+Rkcyvpvg vf orggre guna vzcyvpvg.
+Fvzcyr vf orggre guna pbzcyrk.
+Pbzcyrk vf orggre guna pbzcyvpngrq.
+Syng vf orggre guna arfgrq.
+Fcnefr vf orggre guna qrafr.
+Ernqnovyvgl pbhagf.
+Fcrpvny pnfrf nera'g fcrpvny rabhtu gb oernx gur ehyrf.
+Nygubhtu cenpgvpnyvgl orngf chevgl.
+Reebef fubhyq arire cnff fvyragyl.
+Hayrff rkcyvpvgyl fvyraprq.
+Va gur snpr bs nzovthvgl, ershfr gur grzcgngvba gb thrff.
+Gurer fubhyq or bar-- naq cersrenoyl bayl bar --boivbhf jnl gb qb vg.
+Nygubhtu gung jnl znl abg or boivbhf ng svefg hayrff lbh'er Qhgpu.
+Abj vf orggre guna arire.
+Nygubhtu arire vf bsgra orggre guna *evtug* abj.
+Vs gur vzcyrzragngvba vf uneq gb rkcynva, vg'f n onq vqrn.
+Vs gur vzcyrzragngvba vf rnfl gb rkcynva, vg znl or n tbbq vqrn.
+Anzrfcnprf ner bar ubaxvat terng vqrn -- yrg'f qb zber bs gubfr!"""
+
+d = {}
+for c in (65, 97):
+    for i in range(26):
+        d[chr(i+c)] = chr((i+13) % 26 + c)
+
+print "".join([d.get(c, c) for c in s])

Added: vendor/Python/current/Lib/threading.py
===================================================================
--- vendor/Python/current/Lib/threading.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/threading.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,816 @@
+"""Thread module emulating a subset of Java's threading model."""
+
+import sys as _sys
+
+try:
+    import thread
+except ImportError:
+    del _sys.modules[__name__]
+    raise
+
+from time import time as _time, sleep as _sleep
+from traceback import format_exc as _format_exc
+from collections import deque
+
+# Rename some stuff so "from threading import *" is safe
+__all__ = ['activeCount', 'Condition', 'currentThread', 'enumerate', 'Event',
+           'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Thread',
+           'Timer', 'setprofile', 'settrace', 'local', 'stack_size']
+
+_start_new_thread = thread.start_new_thread
+_allocate_lock = thread.allocate_lock
+_get_ident = thread.get_ident
+ThreadError = thread.error
+del thread
+
+
+# Debug support (adapted from ihooks.py).
+# All the major classes here derive from _Verbose.  We force that to
+# be a new-style class so that all the major classes here are new-style.
+# This helps debugging (type(instance) is more revealing for instances
+# of new-style classes).
+
+_VERBOSE = False
+
+if __debug__:
+
+    class _Verbose(object):
+
+        def __init__(self, verbose=None):
+            if verbose is None:
+                verbose = _VERBOSE
+            self.__verbose = verbose
+
+        def _note(self, format, *args):
+            if self.__verbose:
+                format = format % args
+                format = "%s: %s\n" % (
+                    currentThread().getName(), format)
+                _sys.stderr.write(format)
+
+else:
+    # Disable this when using "python -O"
+    class _Verbose(object):
+        def __init__(self, verbose=None):
+            pass
+        def _note(self, *args):
+            pass
+
+# Support for profile and trace hooks
+
+_profile_hook = None
+_trace_hook = None
+
+def setprofile(func):
+    global _profile_hook
+    _profile_hook = func
+
+def settrace(func):
+    global _trace_hook
+    _trace_hook = func
+
+# Synchronization classes
+
+Lock = _allocate_lock
+
+def RLock(*args, **kwargs):
+    return _RLock(*args, **kwargs)
+
+class _RLock(_Verbose):
+
+    def __init__(self, verbose=None):
+        _Verbose.__init__(self, verbose)
+        self.__block = _allocate_lock()
+        self.__owner = None
+        self.__count = 0
+
+    def __repr__(self):
+        return "<%s(%s, %d)>" % (
+                self.__class__.__name__,
+                self.__owner and self.__owner.getName(),
+                self.__count)
+
+    def acquire(self, blocking=1):
+        me = currentThread()
+        if self.__owner is me:
+            self.__count = self.__count + 1
+            if __debug__:
+                self._note("%s.acquire(%s): recursive success", self, blocking)
+            return 1
+        rc = self.__block.acquire(blocking)
+        if rc:
+            self.__owner = me
+            self.__count = 1
+            if __debug__:
+                self._note("%s.acquire(%s): initial success", self, blocking)
+        else:
+            if __debug__:
+                self._note("%s.acquire(%s): failure", self, blocking)
+        return rc
+
+    __enter__ = acquire
+
+    def release(self):
+        me = currentThread()
+        assert self.__owner is me, "release() of un-acquire()d lock"
+        self.__count = count = self.__count - 1
+        if not count:
+            self.__owner = None
+            self.__block.release()
+            if __debug__:
+                self._note("%s.release(): final release", self)
+        else:
+            if __debug__:
+                self._note("%s.release(): non-final release", self)
+
+    def __exit__(self, t, v, tb):
+        self.release()
+
+    # Internal methods used by condition variables
+
+    def _acquire_restore(self, (count, owner)):
+        self.__block.acquire()
+        self.__count = count
+        self.__owner = owner
+        if __debug__:
+            self._note("%s._acquire_restore()", self)
+
+    def _release_save(self):
+        if __debug__:
+            self._note("%s._release_save()", self)
+        count = self.__count
+        self.__count = 0
+        owner = self.__owner
+        self.__owner = None
+        self.__block.release()
+        return (count, owner)
+
+    def _is_owned(self):
+        return self.__owner is currentThread()
+
+
+def Condition(*args, **kwargs):
+    return _Condition(*args, **kwargs)
+
+class _Condition(_Verbose):
+
+    def __init__(self, lock=None, verbose=None):
+        _Verbose.__init__(self, verbose)
+        if lock is None:
+            lock = RLock()
+        self.__lock = lock
+        # Export the lock's acquire() and release() methods
+        self.acquire = lock.acquire
+        self.release = lock.release
+        # If the lock defines _release_save() and/or _acquire_restore(),
+        # these override the default implementations (which just call
+        # release() and acquire() on the lock).  Ditto for _is_owned().
+        try:
+            self._release_save = lock._release_save
+        except AttributeError:
+            pass
+        try:
+            self._acquire_restore = lock._acquire_restore
+        except AttributeError:
+            pass
+        try:
+            self._is_owned = lock._is_owned
+        except AttributeError:
+            pass
+        self.__waiters = []
+
+    def __enter__(self):
+        return self.__lock.__enter__()
+
+    def __exit__(self, *args):
+        return self.__lock.__exit__(*args)
+
+    def __repr__(self):
+        return "<Condition(%s, %d)>" % (self.__lock, len(self.__waiters))
+
+    def _release_save(self):
+        self.__lock.release()           # No state to save
+
+    def _acquire_restore(self, x):
+        self.__lock.acquire()           # Ignore saved state
+
+    def _is_owned(self):
+        # Return True if lock is owned by currentThread.
+        # This method is called only if __lock doesn't have _is_owned().
+        if self.__lock.acquire(0):
+            self.__lock.release()
+            return False
+        else:
+            return True
+
+    def wait(self, timeout=None):
+        assert self._is_owned(), "wait() of un-acquire()d lock"
+        waiter = _allocate_lock()
+        waiter.acquire()
+        self.__waiters.append(waiter)
+        saved_state = self._release_save()
+        try:    # restore state no matter what (e.g., KeyboardInterrupt)
+            if timeout is None:
+                waiter.acquire()
+                if __debug__:
+                    self._note("%s.wait(): got it", self)
+            else:
+                # Balancing act:  We can't afford a pure busy loop, so we
+                # have to sleep; but if we sleep the whole timeout time,
+                # we'll be unresponsive.  The scheme here sleeps very
+                # little at first, longer as time goes on, but never longer
+                # than 20 times per second (or the timeout time remaining).
+                endtime = _time() + timeout
+                delay = 0.0005 # 500 us -> initial delay of 1 ms
+                while True:
+                    gotit = waiter.acquire(0)
+                    if gotit:
+                        break
+                    remaining = endtime - _time()
+                    if remaining <= 0:
+                        break
+                    delay = min(delay * 2, remaining, .05)
+                    _sleep(delay)
+                if not gotit:
+                    if __debug__:
+                        self._note("%s.wait(%s): timed out", self, timeout)
+                    try:
+                        self.__waiters.remove(waiter)
+                    except ValueError:
+                        pass
+                else:
+                    if __debug__:
+                        self._note("%s.wait(%s): got it", self, timeout)
+        finally:
+            self._acquire_restore(saved_state)
+
+    def notify(self, n=1):
+        assert self._is_owned(), "notify() of un-acquire()d lock"
+        __waiters = self.__waiters
+        waiters = __waiters[:n]
+        if not waiters:
+            if __debug__:
+                self._note("%s.notify(): no waiters", self)
+            return
+        self._note("%s.notify(): notifying %d waiter%s", self, n,
+                   n!=1 and "s" or "")
+        for waiter in waiters:
+            waiter.release()
+            try:
+                __waiters.remove(waiter)
+            except ValueError:
+                pass
+
+    def notifyAll(self):
+        self.notify(len(self.__waiters))
+
+
+def Semaphore(*args, **kwargs):
+    return _Semaphore(*args, **kwargs)
+
+class _Semaphore(_Verbose):
+
+    # After Tim Peters' semaphore class, but not quite the same (no maximum)
+
+    def __init__(self, value=1, verbose=None):
+        assert value >= 0, "Semaphore initial value must be >= 0"
+        _Verbose.__init__(self, verbose)
+        self.__cond = Condition(Lock())
+        self.__value = value
+
+    def acquire(self, blocking=1):
+        rc = False
+        self.__cond.acquire()
+        while self.__value == 0:
+            if not blocking:
+                break
+            if __debug__:
+                self._note("%s.acquire(%s): blocked waiting, value=%s",
+                           self, blocking, self.__value)
+            self.__cond.wait()
+        else:
+            self.__value = self.__value - 1
+            if __debug__:
+                self._note("%s.acquire: success, value=%s",
+                           self, self.__value)
+            rc = True
+        self.__cond.release()
+        return rc
+
+    __enter__ = acquire
+
+    def release(self):
+        self.__cond.acquire()
+        self.__value = self.__value + 1
+        if __debug__:
+            self._note("%s.release: success, value=%s",
+                       self, self.__value)
+        self.__cond.notify()
+        self.__cond.release()
+
+    def __exit__(self, t, v, tb):
+        self.release()
+
+
+def BoundedSemaphore(*args, **kwargs):
+    return _BoundedSemaphore(*args, **kwargs)
+
+class _BoundedSemaphore(_Semaphore):
+    """Semaphore that checks that # releases is <= # acquires"""
+    def __init__(self, value=1, verbose=None):
+        _Semaphore.__init__(self, value, verbose)
+        self._initial_value = value
+
+    def release(self):
+        if self._Semaphore__value >= self._initial_value:
+            raise ValueError, "Semaphore released too many times"
+        return _Semaphore.release(self)
+
+
+def Event(*args, **kwargs):
+    return _Event(*args, **kwargs)
+
+class _Event(_Verbose):
+
+    # After Tim Peters' event class (without is_posted())
+
+    def __init__(self, verbose=None):
+        _Verbose.__init__(self, verbose)
+        self.__cond = Condition(Lock())
+        self.__flag = False
+
+    def isSet(self):
+        return self.__flag
+
+    def set(self):
+        self.__cond.acquire()
+        try:
+            self.__flag = True
+            self.__cond.notifyAll()
+        finally:
+            self.__cond.release()
+
+    def clear(self):
+        self.__cond.acquire()
+        try:
+            self.__flag = False
+        finally:
+            self.__cond.release()
+
+    def wait(self, timeout=None):
+        self.__cond.acquire()
+        try:
+            if not self.__flag:
+                self.__cond.wait(timeout)
+        finally:
+            self.__cond.release()
+
+# Helper to generate new thread names
+_counter = 0
+def _newname(template="Thread-%d"):
+    global _counter
+    _counter = _counter + 1
+    return template % _counter
+
+# Active thread administration
+_active_limbo_lock = _allocate_lock()
+_active = {}    # maps thread id to Thread object
+_limbo = {}
+
+
+# Main class for threads
+
+class Thread(_Verbose):
+
+    __initialized = False
+    # Need to store a reference to sys.exc_info for printing
+    # out exceptions when a thread tries to use a global var. during interp.
+    # shutdown and thus raises an exception about trying to perform some
+    # operation on/with a NoneType
+    __exc_info = _sys.exc_info
+
+    def __init__(self, group=None, target=None, name=None,
+                 args=(), kwargs=None, verbose=None):
+        assert group is None, "group argument must be None for now"
+        _Verbose.__init__(self, verbose)
+        if kwargs is None:
+            kwargs = {}
+        self.__target = target
+        self.__name = str(name or _newname())
+        self.__args = args
+        self.__kwargs = kwargs
+        self.__daemonic = self._set_daemon()
+        self.__started = False
+        self.__stopped = False
+        self.__block = Condition(Lock())
+        self.__initialized = True
+        # sys.stderr is not stored in the class like
+        # sys.exc_info since it can be changed between instances
+        self.__stderr = _sys.stderr
+
+    def _set_daemon(self):
+        # Overridden in _MainThread and _DummyThread
+        return currentThread().isDaemon()
+
+    def __repr__(self):
+        assert self.__initialized, "Thread.__init__() was not called"
+        status = "initial"
+        if self.__started:
+            status = "started"
+        if self.__stopped:
+            status = "stopped"
+        if self.__daemonic:
+            status = status + " daemon"
+        return "<%s(%s, %s)>" % (self.__class__.__name__, self.__name, status)
+
+    def start(self):
+        assert self.__initialized, "Thread.__init__() not called"
+        assert not self.__started, "thread already started"
+        if __debug__:
+            self._note("%s.start(): starting thread", self)
+        _active_limbo_lock.acquire()
+        _limbo[self] = self
+        _active_limbo_lock.release()
+        _start_new_thread(self.__bootstrap, ())
+        self.__started = True
+        _sleep(0.000001)    # 1 usec, to let the thread run (Solaris hack)
+
+    def run(self):
+        if self.__target:
+            self.__target(*self.__args, **self.__kwargs)
+
+    def __bootstrap(self):
+        try:
+            self.__started = True
+            _active_limbo_lock.acquire()
+            _active[_get_ident()] = self
+            del _limbo[self]
+            _active_limbo_lock.release()
+            if __debug__:
+                self._note("%s.__bootstrap(): thread started", self)
+
+            if _trace_hook:
+                self._note("%s.__bootstrap(): registering trace hook", self)
+                _sys.settrace(_trace_hook)
+            if _profile_hook:
+                self._note("%s.__bootstrap(): registering profile hook", self)
+                _sys.setprofile(_profile_hook)
+
+            try:
+                self.run()
+            except SystemExit:
+                if __debug__:
+                    self._note("%s.__bootstrap(): raised SystemExit", self)
+            except:
+                if __debug__:
+                    self._note("%s.__bootstrap(): unhandled exception", self)
+                # If sys.stderr is no more (most likely from interpreter
+                # shutdown) use self.__stderr.  Otherwise still use sys (as in
+                # _sys) in case sys.stderr was redefined since the creation of
+                # self.
+                if _sys:
+                    _sys.stderr.write("Exception in thread %s:\n%s\n" %
+                                      (self.getName(), _format_exc()))
+                else:
+                    # Do the best job possible w/o a huge amt. of code to
+                    # approximate a traceback (code ideas from
+                    # Lib/traceback.py)
+                    exc_type, exc_value, exc_tb = self.__exc_info()
+                    try:
+                        print>>self.__stderr, (
+                            "Exception in thread " + self.getName() +
+                            " (most likely raised during interpreter shutdown):")
+                        print>>self.__stderr, (
+                            "Traceback (most recent call last):")
+                        while exc_tb:
+                            print>>self.__stderr, (
+                                '  File "%s", line %s, in %s' %
+                                (exc_tb.tb_frame.f_code.co_filename,
+                                    exc_tb.tb_lineno,
+                                    exc_tb.tb_frame.f_code.co_name))
+                            exc_tb = exc_tb.tb_next
+                        print>>self.__stderr, ("%s: %s" % (exc_type, exc_value))
+                    # Make sure that exc_tb gets deleted since it is a memory
+                    # hog; deleting everything else is just for thoroughness
+                    finally:
+                        del exc_type, exc_value, exc_tb
+            else:
+                if __debug__:
+                    self._note("%s.__bootstrap(): normal return", self)
+        finally:
+            self.__stop()
+            try:
+                self.__delete()
+            except:
+                pass
+
+    def __stop(self):
+        self.__block.acquire()
+        self.__stopped = True
+        self.__block.notifyAll()
+        self.__block.release()
+
+    def __delete(self):
+        "Remove current thread from the dict of currently running threads."
+
+        # Notes about running with dummy_thread:
+        #
+        # Must take care to not raise an exception if dummy_thread is being
+        # used (and thus this module is being used as an instance of
+        # dummy_threading).  dummy_thread.get_ident() always returns -1 since
+        # there is only one thread if dummy_thread is being used.  Thus
+        # len(_active) is always <= 1 here, and any Thread instance created
+        # overwrites the (if any) thread currently registered in _active.
+        #
+        # An instance of _MainThread is always created by 'threading'.  This
+        # gets overwritten the instant an instance of Thread is created; both
+        # threads return -1 from dummy_thread.get_ident() and thus have the
+        # same key in the dict.  So when the _MainThread instance created by
+        # 'threading' tries to clean itself up when atexit calls this method
+        # it gets a KeyError if another Thread instance was created.
+        #
+        # This all means that KeyError from trying to delete something from
+        # _active if dummy_threading is being used is a red herring.  But
+        # since it isn't if dummy_threading is *not* being used then don't
+        # hide the exception.
+
+        _active_limbo_lock.acquire()
+        try:
+            try:
+                del _active[_get_ident()]
+            except KeyError:
+                if 'dummy_threading' not in _sys.modules:
+                    raise
+        finally:
+            _active_limbo_lock.release()
+
+    def join(self, timeout=None):
+        assert self.__initialized, "Thread.__init__() not called"
+        assert self.__started, "cannot join thread before it is started"
+        assert self is not currentThread(), "cannot join current thread"
+        if __debug__:
+            if not self.__stopped:
+                self._note("%s.join(): waiting until thread stops", self)
+        self.__block.acquire()
+        try:
+            if timeout is None:
+                while not self.__stopped:
+                    self.__block.wait()
+                if __debug__:
+                    self._note("%s.join(): thread stopped", self)
+            else:
+                deadline = _time() + timeout
+                while not self.__stopped:
+                    delay = deadline - _time()
+                    if delay <= 0:
+                        if __debug__:
+                            self._note("%s.join(): timed out", self)
+                        break
+                    self.__block.wait(delay)
+                else:
+                    if __debug__:
+                        self._note("%s.join(): thread stopped", self)
+        finally:
+            self.__block.release()
+
+    def getName(self):
+        assert self.__initialized, "Thread.__init__() not called"
+        return self.__name
+
+    def setName(self, name):
+        assert self.__initialized, "Thread.__init__() not called"
+        self.__name = str(name)
+
+    def isAlive(self):
+        assert self.__initialized, "Thread.__init__() not called"
+        return self.__started and not self.__stopped
+
+    def isDaemon(self):
+        assert self.__initialized, "Thread.__init__() not called"
+        return self.__daemonic
+
+    def setDaemon(self, daemonic):
+        assert self.__initialized, "Thread.__init__() not called"
+        assert not self.__started, "cannot set daemon status of active thread"
+        self.__daemonic = daemonic
+
+# The timer class was contributed by Itamar Shtull-Trauring
+
+def Timer(*args, **kwargs):
+    return _Timer(*args, **kwargs)
+
+class _Timer(Thread):
+    """Call a function after a specified number of seconds:
+
+    t = Timer(30.0, f, args=[], kwargs={})
+    t.start()
+    t.cancel() # stop the timer's action if it's still waiting
+    """
+
+    def __init__(self, interval, function, args=[], kwargs={}):
+        Thread.__init__(self)
+        self.interval = interval
+        self.function = function
+        self.args = args
+        self.kwargs = kwargs
+        self.finished = Event()
+
+    def cancel(self):
+        """Stop the timer if it hasn't finished yet"""
+        self.finished.set()
+
+    def run(self):
+        self.finished.wait(self.interval)
+        if not self.finished.isSet():
+            self.function(*self.args, **self.kwargs)
+        self.finished.set()
+
+# Special thread class to represent the main thread
+# This is garbage collected through an exit handler
+
+class _MainThread(Thread):
+
+    def __init__(self):
+        Thread.__init__(self, name="MainThread")
+        self._Thread__started = True
+        _active_limbo_lock.acquire()
+        _active[_get_ident()] = self
+        _active_limbo_lock.release()
+
+    def _set_daemon(self):
+        return False
+
+    def _exitfunc(self):
+        self._Thread__stop()
+        t = _pickSomeNonDaemonThread()
+        if t:
+            if __debug__:
+                self._note("%s: waiting for other threads", self)
+        while t:
+            t.join()
+            t = _pickSomeNonDaemonThread()
+        if __debug__:
+            self._note("%s: exiting", self)
+        self._Thread__delete()
+
+def _pickSomeNonDaemonThread():
+    for t in enumerate():
+        if not t.isDaemon() and t.isAlive():
+            return t
+    return None
+
+
+# Dummy thread class to represent threads not started here.
+# These aren't garbage collected when they die, nor can they be waited for.
+# If they invoke anything in threading.py that calls currentThread(), they
+# leave an entry in the _active dict forever after.
+# Their purpose is to return *something* from currentThread().
+# They are marked as daemon threads so we won't wait for them
+# when we exit (conform previous semantics).
+
+class _DummyThread(Thread):
+
+    def __init__(self):
+        Thread.__init__(self, name=_newname("Dummy-%d"))
+
+        # Thread.__block consumes an OS-level locking primitive, which
+        # can never be used by a _DummyThread.  Since a _DummyThread
+        # instance is immortal, that's bad, so release this resource.
+        del self._Thread__block
+
+        self._Thread__started = True
+        _active_limbo_lock.acquire()
+        _active[_get_ident()] = self
+        _active_limbo_lock.release()
+
+    def _set_daemon(self):
+        return True
+
+    def join(self, timeout=None):
+        assert False, "cannot join a dummy thread"
+
+
+# Global API functions
+
+def currentThread():
+    try:
+        return _active[_get_ident()]
+    except KeyError:
+        ##print "currentThread(): no current thread for", _get_ident()
+        return _DummyThread()
+
+def activeCount():
+    _active_limbo_lock.acquire()
+    count = len(_active) + len(_limbo)
+    _active_limbo_lock.release()
+    return count
+
+def enumerate():
+    _active_limbo_lock.acquire()
+    active = _active.values() + _limbo.values()
+    _active_limbo_lock.release()
+    return active
+
+from thread import stack_size
+
+# Create the main thread object,
+# and make it available for the interpreter
+# (Py_Main) as threading._shutdown.
+
+_shutdown = _MainThread()._exitfunc
+
+# get thread-local implementation, either from the thread
+# module, or from the python fallback
+
+try:
+    from thread import _local as local
+except ImportError:
+    from _threading_local import local
+
+
+# Self-test code
+
+def _test():
+
+    class BoundedQueue(_Verbose):
+
+        def __init__(self, limit):
+            _Verbose.__init__(self)
+            self.mon = RLock()
+            self.rc = Condition(self.mon)
+            self.wc = Condition(self.mon)
+            self.limit = limit
+            self.queue = deque()
+
+        def put(self, item):
+            self.mon.acquire()
+            while len(self.queue) >= self.limit:
+                self._note("put(%s): queue full", item)
+                self.wc.wait()
+            self.queue.append(item)
+            self._note("put(%s): appended, length now %d",
+                       item, len(self.queue))
+            self.rc.notify()
+            self.mon.release()
+
+        def get(self):
+            self.mon.acquire()
+            while not self.queue:
+                self._note("get(): queue empty")
+                self.rc.wait()
+            item = self.queue.popleft()
+            self._note("get(): got %s, %d left", item, len(self.queue))
+            self.wc.notify()
+            self.mon.release()
+            return item
+
+    class ProducerThread(Thread):
+
+        def __init__(self, queue, quota):
+            Thread.__init__(self, name="Producer")
+            self.queue = queue
+            self.quota = quota
+
+        def run(self):
+            from random import random
+            counter = 0
+            while counter < self.quota:
+                counter = counter + 1
+                self.queue.put("%s.%d" % (self.getName(), counter))
+                _sleep(random() * 0.00001)
+
+
+    class ConsumerThread(Thread):
+
+        def __init__(self, queue, count):
+            Thread.__init__(self, name="Consumer")
+            self.queue = queue
+            self.count = count
+
+        def run(self):
+            while self.count > 0:
+                item = self.queue.get()
+                print item
+                self.count = self.count - 1
+
+    NP = 3
+    QL = 4
+    NI = 5
+
+    Q = BoundedQueue(QL)
+    P = []
+    for i in range(NP):
+        t = ProducerThread(Q, NI)
+        t.setName("Producer-%d" % (i+1))
+        P.append(t)
+    C = ConsumerThread(Q, NI*NP)
+    for t in P:
+        t.start()
+        _sleep(0.000001)
+    C.start()
+    for t in P:
+        t.join()
+    C.join()
+
+if __name__ == '__main__':
+    _test()

Added: vendor/Python/current/Lib/timeit.py
===================================================================
--- vendor/Python/current/Lib/timeit.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/timeit.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,285 @@
+#! /usr/bin/env python
+
+"""Tool for measuring execution time of small code snippets.
+
+This module avoids a number of common traps for measuring execution
+times.  See also Tim Peters' introduction to the Algorithms chapter in
+the Python Cookbook, published by O'Reilly.
+
+Library usage: see the Timer class.
+
+Command line usage:
+    python timeit.py [-n N] [-r N] [-s S] [-t] [-c] [-h] [statement]
+
+Options:
+  -n/--number N: how many times to execute 'statement' (default: see below)
+  -r/--repeat N: how many times to repeat the timer (default 3)
+  -s/--setup S: statement to be executed once initially (default 'pass')
+  -t/--time: use time.time() (default on Unix)
+  -c/--clock: use time.clock() (default on Windows)
+  -v/--verbose: print raw timing results; repeat for more digits precision
+  -h/--help: print this usage message and exit
+  statement: statement to be timed (default 'pass')
+
+A multi-line statement may be given by specifying each line as a
+separate argument; indented lines are possible by enclosing an
+argument in quotes and using leading spaces.  Multiple -s options are
+treated similarly.
+
+If -n is not given, a suitable number of loops is calculated by trying
+successive powers of 10 until the total time is at least 0.2 seconds.
+
+The difference in default timer function is because on Windows,
+clock() has microsecond granularity but time()'s granularity is 1/60th
+of a second; on Unix, clock() has 1/100th of a second granularity and
+time() is much more precise.  On either platform, the default timer
+functions measure wall clock time, not the CPU time.  This means that
+other processes running on the same computer may interfere with the
+timing.  The best thing to do when accurate timing is necessary is to
+repeat the timing a few times and use the best time.  The -r option is
+good for this; the default of 3 repetitions is probably enough in most
+cases.  On Unix, you can use clock() to measure CPU time.
+
+Note: there is a certain baseline overhead associated with executing a
+pass statement.  The code here doesn't try to hide it, but you should
+be aware of it.  The baseline overhead can be measured by invoking the
+program without arguments.
+
+The baseline overhead differs between Python versions!  Also, to
+fairly compare older Python versions to Python 2.3, you may want to
+use python -O for the older versions to avoid timing SET_LINENO
+instructions.
+"""
+
+import gc
+import sys
+import time
+try:
+    import itertools
+except ImportError:
+    # Must be an older Python version (see timeit() below)
+    itertools = None
+
+__all__ = ["Timer"]
+
+dummy_src_name = "<timeit-src>"
+default_number = 1000000
+default_repeat = 3
+
+if sys.platform == "win32":
+    # On Windows, the best timer is time.clock()
+    default_timer = time.clock
+else:
+    # On most other platforms the best timer is time.time()
+    default_timer = time.time
+
+# Don't change the indentation of the template; the reindent() calls
+# in Timer.__init__() depend on setup being indented 4 spaces and stmt
+# being indented 8 spaces.
+template = """
+def inner(_it, _timer):
+    %(setup)s
+    _t0 = _timer()
+    for _i in _it:
+        %(stmt)s
+    _t1 = _timer()
+    return _t1 - _t0
+"""
+
+def reindent(src, indent):
+    """Helper to reindent a multi-line statement."""
+    return src.replace("\n", "\n" + " "*indent)
+
+class Timer:
+    """Class for timing execution speed of small code snippets.
+
+    The constructor takes a statement to be timed, an additional
+    statement used for setup, and a timer function.  Both statements
+    default to 'pass'; the timer function is platform-dependent (see
+    module doc string).
+
+    To measure the execution time of the first statement, use the
+    timeit() method.  The repeat() method is a convenience to call
+    timeit() multiple times and return a list of results.
+
+    The statements may contain newlines, as long as they don't contain
+    multi-line string literals.
+    """
+
+    def __init__(self, stmt="pass", setup="pass", timer=default_timer):
+        """Constructor.  See class doc string."""
+        self.timer = timer
+        stmt = reindent(stmt, 8)
+        setup = reindent(setup, 4)
+        src = template % {'stmt': stmt, 'setup': setup}
+        self.src = src # Save for traceback display
+        code = compile(src, dummy_src_name, "exec")
+        ns = {}
+        exec code in globals(), ns
+        self.inner = ns["inner"]
+
+    def print_exc(self, file=None):
+        """Helper to print a traceback from the timed code.
+
+        Typical use:
+
+            t = Timer(...)       # outside the try/except
+            try:
+                t.timeit(...)    # or t.repeat(...)
+            except:
+                t.print_exc()
+
+        The advantage over the standard traceback is that source lines
+        in the compiled template will be displayed.
+
+        The optional file argument directs where the traceback is
+        sent; it defaults to sys.stderr.
+        """
+        import linecache, traceback
+        linecache.cache[dummy_src_name] = (len(self.src),
+                                           None,
+                                           self.src.split("\n"),
+                                           dummy_src_name)
+        traceback.print_exc(file=file)
+
+    def timeit(self, number=default_number):
+        """Time 'number' executions of the main statement.
+
+        To be precise, this executes the setup statement once, and
+        then returns the time it takes to execute the main statement
+        a number of times, as a float measured in seconds.  The
+        argument is the number of times through the loop, defaulting
+        to one million.  The main statement, the setup statement and
+        the timer function to be used are passed to the constructor.
+        """
+        if itertools:
+            it = itertools.repeat(None, number)
+        else:
+            it = [None] * number
+        gcold = gc.isenabled()
+        gc.disable()
+        timing = self.inner(it, self.timer)
+        if gcold:
+            gc.enable()
+        return timing
+
+    def repeat(self, repeat=default_repeat, number=default_number):
+        """Call timeit() a few times.
+
+        This is a convenience function that calls the timeit()
+        repeatedly, returning a list of results.  The first argument
+        specifies how many times to call timeit(), defaulting to 3;
+        the second argument specifies the timer argument, defaulting
+        to one million.
+
+        Note: it's tempting to calculate mean and standard deviation
+        from the result vector and report these.  However, this is not
+        very useful.  In a typical case, the lowest value gives a
+        lower bound for how fast your machine can run the given code
+        snippet; higher values in the result vector are typically not
+        caused by variability in Python's speed, but by other
+        processes interfering with your timing accuracy.  So the min()
+        of the result is probably the only number you should be
+        interested in.  After that, you should look at the entire
+        vector and apply common sense rather than statistics.
+        """
+        r = []
+        for i in range(repeat):
+            t = self.timeit(number)
+            r.append(t)
+        return r
+
+def main(args=None):
+    """Main program, used when run as a script.
+
+    The optional argument specifies the command line to be parsed,
+    defaulting to sys.argv[1:].
+
+    The return value is an exit code to be passed to sys.exit(); it
+    may be None to indicate success.
+
+    When an exception happens during timing, a traceback is printed to
+    stderr and the return value is 1.  Exceptions at other times
+    (including the template compilation) are not caught.
+    """
+    if args is None:
+        args = sys.argv[1:]
+    import getopt
+    try:
+        opts, args = getopt.getopt(args, "n:s:r:tcvh",
+                                   ["number=", "setup=", "repeat=",
+                                    "time", "clock", "verbose", "help"])
+    except getopt.error, err:
+        print err
+        print "use -h/--help for command line help"
+        return 2
+    timer = default_timer
+    stmt = "\n".join(args) or "pass"
+    number = 0 # auto-determine
+    setup = []
+    repeat = default_repeat
+    verbose = 0
+    precision = 3
+    for o, a in opts:
+        if o in ("-n", "--number"):
+            number = int(a)
+        if o in ("-s", "--setup"):
+            setup.append(a)
+        if o in ("-r", "--repeat"):
+            repeat = int(a)
+            if repeat <= 0:
+                repeat = 1
+        if o in ("-t", "--time"):
+            timer = time.time
+        if o in ("-c", "--clock"):
+            timer = time.clock
+        if o in ("-v", "--verbose"):
+            if verbose:
+                precision += 1
+            verbose += 1
+        if o in ("-h", "--help"):
+            print __doc__,
+            return 0
+    setup = "\n".join(setup) or "pass"
+    # Include the current directory, so that local imports work (sys.path
+    # contains the directory of this script, rather than the current
+    # directory)
+    import os
+    sys.path.insert(0, os.curdir)
+    t = Timer(stmt, setup, timer)
+    if number == 0:
+        # determine number so that 0.2 <= total time < 2.0
+        for i in range(1, 10):
+            number = 10**i
+            try:
+                x = t.timeit(number)
+            except:
+                t.print_exc()
+                return 1
+            if verbose:
+                print "%d loops -> %.*g secs" % (number, precision, x)
+            if x >= 0.2:
+                break
+    try:
+        r = t.repeat(repeat, number)
+    except:
+        t.print_exc()
+        return 1
+    best = min(r)
+    if verbose:
+        print "raw times:", " ".join(["%.*g" % (precision, x) for x in r])
+    print "%d loops," % number,
+    usec = best * 1e6 / number
+    if usec < 1000:
+        print "best of %d: %.*g usec per loop" % (repeat, precision, usec)
+    else:
+        msec = usec / 1000
+        if msec < 1000:
+            print "best of %d: %.*g msec per loop" % (repeat, precision, msec)
+        else:
+            sec = msec / 1000
+            print "best of %d: %.*g sec per loop" % (repeat, precision, sec)
+    return None
+
+if __name__ == "__main__":
+    sys.exit(main())

Added: vendor/Python/current/Lib/toaiff.py
===================================================================
--- vendor/Python/current/Lib/toaiff.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/toaiff.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,107 @@
+"""Convert "arbitrary" sound files to AIFF (Apple and SGI's audio format).
+
+Input may be compressed.
+Uncompressed file type may be AIFF, WAV, VOC, 8SVX, NeXT/Sun, and others.
+An exception is raised if the file is not of a recognized type.
+Returned filename is either the input filename or a temporary filename;
+in the latter case the caller must ensure that it is removed.
+Other temporary files used are removed by the function.
+"""
+
+import os
+import tempfile
+import pipes
+import sndhdr
+
+__all__ = ["error", "toaiff"]
+
+table = {}
+
+t = pipes.Template()
+t.append('sox -t au - -t aiff -r 8000 -', '--')
+table['au'] = t
+
+# XXX The following is actually sub-optimal.
+# XXX The HCOM sampling rate can be 22k, 22k/2, 22k/3 or 22k/4.
+# XXX We must force the output sampling rate else the SGI won't play
+# XXX files sampled at 5.5k or 7.333k; however this means that files
+# XXX sampled at 11k are unnecessarily expanded.
+# XXX Similar comments apply to some other file types.
+t = pipes.Template()
+t.append('sox -t hcom - -t aiff -r 22050 -', '--')
+table['hcom'] = t
+
+t = pipes.Template()
+t.append('sox -t voc - -t aiff -r 11025 -', '--')
+table['voc'] = t
+
+t = pipes.Template()
+t.append('sox -t wav - -t aiff -', '--')
+table['wav'] = t
+
+t = pipes.Template()
+t.append('sox -t 8svx - -t aiff -r 16000 -', '--')
+table['8svx'] = t
+
+t = pipes.Template()
+t.append('sox -t sndt - -t aiff -r 16000 -', '--')
+table['sndt'] = t
+
+t = pipes.Template()
+t.append('sox -t sndr - -t aiff -r 16000 -', '--')
+table['sndr'] = t
+
+uncompress = pipes.Template()
+uncompress.append('uncompress', '--')
+
+
+class error(Exception):
+    pass
+
+def toaiff(filename):
+    temps = []
+    ret = None
+    try:
+        ret = _toaiff(filename, temps)
+    finally:
+        for temp in temps[:]:
+            if temp != ret:
+                try:
+                    os.unlink(temp)
+                except os.error:
+                    pass
+                temps.remove(temp)
+    return ret
+
+def _toaiff(filename, temps):
+    if filename[-2:] == '.Z':
+        (fd, fname) = tempfile.mkstemp()
+        os.close(fd)
+        temps.append(fname)
+        sts = uncompress.copy(filename, fname)
+        if sts:
+            raise error, filename + ': uncompress failed'
+    else:
+        fname = filename
+    try:
+        ftype = sndhdr.whathdr(fname)
+        if ftype:
+            ftype = ftype[0] # All we're interested in
+    except IOError, msg:
+        if type(msg) == type(()) and len(msg) == 2 and \
+                type(msg[0]) == type(0) and type(msg[1]) == type(''):
+            msg = msg[1]
+        if type(msg) != type(''):
+            msg = repr(msg)
+        raise error, filename + ': ' + msg
+    if ftype == 'aiff':
+        return fname
+    if ftype is None or not ftype in table:
+        raise error, '%s: unsupported audio file type %r' % (filename, ftype)
+    (fd, temp) = tempfile.mkstemp()
+    os.close(fd)
+    temps.append(temp)
+    sts = table[ftype].copy(fname, temp)
+    if sts:
+        raise error, filename + ': conversion to aiff failed'
+    return temp

Added: vendor/Python/current/Lib/token.py
===================================================================
--- vendor/Python/current/Lib/token.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/token.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,141 @@
+#! /usr/bin/env python
+
+"""Token constants (from "token.h")."""
+
+#  This file is automatically generated; please don't muck it up!
+#
+#  To update the symbols in this file, 'cd' to the top directory of
+#  the python source tree after building the interpreter and run:
+#
+#    python Lib/token.py
+
+#--start constants--
+ENDMARKER = 0
+NAME = 1
+NUMBER = 2
+STRING = 3
+NEWLINE = 4
+INDENT = 5
+DEDENT = 6
+LPAR = 7
+RPAR = 8
+LSQB = 9
+RSQB = 10
+COLON = 11
+COMMA = 12
+SEMI = 13
+PLUS = 14
+MINUS = 15
+STAR = 16
+SLASH = 17
+VBAR = 18
+AMPER = 19
+LESS = 20
+GREATER = 21
+EQUAL = 22
+DOT = 23
+PERCENT = 24
+BACKQUOTE = 25
+LBRACE = 26
+RBRACE = 27
+EQEQUAL = 28
+NOTEQUAL = 29
+LESSEQUAL = 30
+GREATEREQUAL = 31
+TILDE = 32
+CIRCUMFLEX = 33
+LEFTSHIFT = 34
+RIGHTSHIFT = 35
+DOUBLESTAR = 36
+PLUSEQUAL = 37
+MINEQUAL = 38
+STAREQUAL = 39
+SLASHEQUAL = 40
+PERCENTEQUAL = 41
+AMPEREQUAL = 42
+VBAREQUAL = 43
+CIRCUMFLEXEQUAL = 44
+LEFTSHIFTEQUAL = 45
+RIGHTSHIFTEQUAL = 46
+DOUBLESTAREQUAL = 47
+DOUBLESLASH = 48
+DOUBLESLASHEQUAL = 49
+AT = 50
+OP = 51
+ERRORTOKEN = 52
+N_TOKENS = 53
+NT_OFFSET = 256
+#--end constants--
+
+tok_name = {}
+for _name, _value in globals().items():
+    if type(_value) is type(0):
+        tok_name[_value] = _name
+
+
+def ISTERMINAL(x):
+    return x < NT_OFFSET
+
+def ISNONTERMINAL(x):
+    return x >= NT_OFFSET
+
+def ISEOF(x):
+    return x == ENDMARKER
+
+
+def main():
+    import re
+    import sys
+    args = sys.argv[1:]
+    inFileName = args and args[0] or "Include/token.h"
+    outFileName = "Lib/token.py"
+    if len(args) > 1:
+        outFileName = args[1]
+    try:
+        fp = open(inFileName)
+    except IOError, err:
+        sys.stdout.write("I/O error: %s\n" % str(err))
+        sys.exit(1)
+    lines = fp.read().split("\n")
+    fp.close()
+    prog = re.compile(
+        "#define[ \t][ \t]*([A-Z0-9][A-Z0-9_]*)[ \t][ \t]*([0-9][0-9]*)",
+        re.IGNORECASE)
+    tokens = {}
+    for line in lines:
+        match = prog.match(line)
+        if match:
+            name, val = match.group(1, 2)
+            val = int(val)
+            tokens[val] = name          # reverse so we can sort them...
+    keys = tokens.keys()
+    keys.sort()
+    # load the output skeleton from the target:
+    try:
+        fp = open(outFileName)
+    except IOError, err:
+        sys.stderr.write("I/O error: %s\n" % str(err))
+        sys.exit(2)
+    format = fp.read().split("\n")
+    fp.close()
+    try:
+        start = format.index("#--start constants--") + 1
+        end = format.index("#--end constants--")
+    except ValueError:
+        sys.stderr.write("target does not contain format markers")
+        sys.exit(3)
+    lines = []
+    for val in keys:
+        lines.append("%s = %d" % (tokens[val], val))
+    format[start:end] = lines
+    try:
+        fp = open(outFileName, 'w')
+    except IOError, err:
+        sys.stderr.write("I/O error: %s\n" % str(err))
+        sys.exit(4)
+    fp.write("\n".join(format))
+    fp.close()
+
+
+if __name__ == "__main__":
+    main()


Property changes on: vendor/Python/current/Lib/token.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/tokenize.py
===================================================================
--- vendor/Python/current/Lib/tokenize.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/tokenize.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,345 @@
+"""Tokenization help for Python programs.
+
+generate_tokens(readline) is a generator that breaks a stream of
+text into Python tokens.  It accepts a readline-like method which is called
+repeatedly to get the next line of input (or "" for EOF).  It generates
+5-tuples with these members:
+
+    the token type (see token.py)
+    the token (a string)
+    the starting (row, column) indices of the token (a 2-tuple of ints)
+    the ending (row, column) indices of the token (a 2-tuple of ints)
+    the original line (string)
+
+It is designed to match the working of the Python tokenizer exactly, except
+that it produces COMMENT tokens for comments and gives type OP for all
+operators
+
+Older entry points
+    tokenize_loop(readline, tokeneater)
+    tokenize(readline, tokeneater=printtoken)
+are the same, except instead of generating tokens, tokeneater is a callback
+function to which the 5 fields described above are passed as 5 arguments,
+each time a new token is found."""
+
+__author__ = 'Ka-Ping Yee <ping at lfw.org>'
+__credits__ = \
+    'GvR, ESR, Tim Peters, Thomas Wouters, Fred Drake, Skip Montanaro'
+
+import string, re
+from token import *
+
+import token
+__all__ = [x for x in dir(token) if x[0] != '_'] + ["COMMENT", "tokenize",
+           "generate_tokens", "NL", "untokenize"]
+del x
+del token
+
+COMMENT = N_TOKENS
+tok_name[COMMENT] = 'COMMENT'
+NL = N_TOKENS + 1
+tok_name[NL] = 'NL'
+N_TOKENS += 2
+
+def group(*choices): return '(' + '|'.join(choices) + ')'
+def any(*choices): return group(*choices) + '*'
+def maybe(*choices): return group(*choices) + '?'
+
+Whitespace = r'[ \f\t]*'
+Comment = r'#[^\r\n]*'
+Ignore = Whitespace + any(r'\\\r?\n' + Whitespace) + maybe(Comment)
+Name = r'[a-zA-Z_]\w*'
+
+Hexnumber = r'0[xX][\da-fA-F]*[lL]?'
+Octnumber = r'0[0-7]*[lL]?'
+Decnumber = r'[1-9]\d*[lL]?'
+Intnumber = group(Hexnumber, Octnumber, Decnumber)
+Exponent = r'[eE][-+]?\d+'
+Pointfloat = group(r'\d+\.\d*', r'\.\d+') + maybe(Exponent)
+Expfloat = r'\d+' + Exponent
+Floatnumber = group(Pointfloat, Expfloat)
+Imagnumber = group(r'\d+[jJ]', Floatnumber + r'[jJ]')
+Number = group(Imagnumber, Floatnumber, Intnumber)
+
+# Tail end of ' string.
+Single = r"[^'\\]*(?:\\.[^'\\]*)*'"
+# Tail end of " string.
+Double = r'[^"\\]*(?:\\.[^"\\]*)*"'
+# Tail end of ''' string.
+Single3 = r"[^'\\]*(?:(?:\\.|'(?!''))[^'\\]*)*'''"
+# Tail end of """ string.
+Double3 = r'[^"\\]*(?:(?:\\.|"(?!""))[^"\\]*)*"""'
+Triple = group("[uU]?[rR]?'''", '[uU]?[rR]?"""')
+# Single-line ' or " string.
+String = group(r"[uU]?[rR]?'[^\n'\\]*(?:\\.[^\n'\\]*)*'",
+               r'[uU]?[rR]?"[^\n"\\]*(?:\\.[^\n"\\]*)*"')
+
+# Because of leftmost-then-longest match semantics, be sure to put the
+# longest operators first (e.g., if = came before ==, == would get
+# recognized as two instances of =).
+Operator = group(r"\*\*=?", r">>=?", r"<<=?", r"<>", r"!=",
+                 r"//=?",
+                 r"[+\-*/%&|^=<>]=?",
+                 r"~")
+
+Bracket = '[][(){}]'
+Special = group(r'\r?\n', r'[:;.,`@]')
+Funny = group(Operator, Bracket, Special)
+
+PlainToken = group(Number, Funny, String, Name)
+Token = Ignore + PlainToken
+
+# First (or only) line of ' or " string.
+ContStr = group(r"[uU]?[rR]?'[^\n'\\]*(?:\\.[^\n'\\]*)*" +
+                group("'", r'\\\r?\n'),
+                r'[uU]?[rR]?"[^\n"\\]*(?:\\.[^\n"\\]*)*' +
+                group('"', r'\\\r?\n'))
+PseudoExtras = group(r'\\\r?\n', Comment, Triple)
+PseudoToken = Whitespace + group(PseudoExtras, Number, Funny, ContStr, Name)
+
+tokenprog, pseudoprog, single3prog, double3prog = map(
+    re.compile, (Token, PseudoToken, Single3, Double3))
+endprogs = {"'": re.compile(Single), '"': re.compile(Double),
+            "'''": single3prog, '"""': double3prog,
+            "r'''": single3prog, 'r"""': double3prog,
+            "u'''": single3prog, 'u"""': double3prog,
+            "ur'''": single3prog, 'ur"""': double3prog,
+            "R'''": single3prog, 'R"""': double3prog,
+            "U'''": single3prog, 'U"""': double3prog,
+            "uR'''": single3prog, 'uR"""': double3prog,
+            "Ur'''": single3prog, 'Ur"""': double3prog,
+            "UR'''": single3prog, 'UR"""': double3prog,
+            'r': None, 'R': None, 'u': None, 'U': None}
+
+triple_quoted = {}
+for t in ("'''", '"""',
+          "r'''", 'r"""', "R'''", 'R"""',
+          "u'''", 'u"""', "U'''", 'U"""',
+          "ur'''", 'ur"""', "Ur'''", 'Ur"""',
+          "uR'''", 'uR"""', "UR'''", 'UR"""'):
+    triple_quoted[t] = t
+single_quoted = {}
+for t in ("'", '"',
+          "r'", 'r"', "R'", 'R"',
+          "u'", 'u"', "U'", 'U"',
+          "ur'", 'ur"', "Ur'", 'Ur"',
+          "uR'", 'uR"', "UR'", 'UR"' ):
+    single_quoted[t] = t
+
+tabsize = 8
+
+class TokenError(Exception): pass
+
+class StopTokenizing(Exception): pass
+
+def printtoken(type, token, (srow, scol), (erow, ecol), line): # for testing
+    print "%d,%d-%d,%d:\t%s\t%s" % \
+        (srow, scol, erow, ecol, tok_name[type], repr(token))
+
+def tokenize(readline, tokeneater=printtoken):
+    """
+    The tokenize() function accepts two parameters: one representing the
+    input stream, and one providing an output mechanism for tokenize().
+
+    The first parameter, readline, must be a callable object which provides
+    the same interface as the readline() method of built-in file objects.
+    Each call to the function should return one line of input as a string.
+
+    The second parameter, tokeneater, must also be a callable object. It is
+    called once for each token, with five arguments, corresponding to the
+    tuples generated by generate_tokens().
+    """
+    try:
+        tokenize_loop(readline, tokeneater)
+    except StopTokenizing:
+        pass
+
+# backwards compatible interface
+def tokenize_loop(readline, tokeneater):
+    for token_info in generate_tokens(readline):
+        tokeneater(*token_info)
+
+
+def untokenize(iterable):
+    """Transform tokens back into Python source code.
+
+    Each element returned by the iterable must be a token sequence
+    with at least two elements, a token number and token value.
+
+    Round-trip invariant:
+        # Output text will tokenize the back to the input
+        t1 = [tok[:2] for tok in generate_tokens(f.readline)]
+        newcode = untokenize(t1)
+        readline = iter(newcode.splitlines(1)).next
+        t2 = [tok[:2] for tokin generate_tokens(readline)]
+        assert t1 == t2
+    """
+
+    startline = False
+    indents = []
+    toks = []
+    toks_append = toks.append
+    for tok in iterable:
+        toknum, tokval = tok[:2]
+
+        if toknum in (NAME, NUMBER):
+            tokval += ' '
+
+        if toknum == INDENT:
+            indents.append(tokval)
+            continue
+        elif toknum == DEDENT:
+            indents.pop()
+            continue
+        elif toknum in (NEWLINE, COMMENT, NL):
+            startline = True
+        elif startline and indents:
+            toks_append(indents[-1])
+            startline = False
+        toks_append(tokval)
+    return ''.join(toks)
+
+
+def generate_tokens(readline):
+    """
+    The generate_tokens() generator requires one argment, readline, which
+    must be a callable object which provides the same interface as the
+    readline() method of built-in file objects. Each call to the function
+    should return one line of input as a string.  Alternately, readline
+    can be a callable function terminating with StopIteration:
+        readline = open(myfile).next    # Example of alternate readline
+
+    The generator produces 5-tuples with these members: the token type; the
+    token string; a 2-tuple (srow, scol) of ints specifying the row and
+    column where the token begins in the source; a 2-tuple (erow, ecol) of
+    ints specifying the row and column where the token ends in the source;
+    and the line on which the token was found. The line passed is the
+    logical line; continuation lines are included.
+    """
+    lnum = parenlev = continued = 0
+    namechars, numchars = string.ascii_letters + '_', '0123456789'
+    contstr, needcont = '', 0
+    contline = None
+    indents = [0]
+
+    while 1:                                   # loop over lines in stream
+        try:
+            line = readline()
+        except StopIteration:
+            line = ''
+        lnum = lnum + 1
+        pos, max = 0, len(line)
+
+        if contstr:                            # continued string
+            if not line:
+                raise TokenError, ("EOF in multi-line string", strstart)
+            endmatch = endprog.match(line)
+            if endmatch:
+                pos = end = endmatch.end(0)
+                yield (STRING, contstr + line[:end],
+                           strstart, (lnum, end), contline + line)
+                contstr, needcont = '', 0
+                contline = None
+            elif needcont and line[-2:] != '\\\n' and line[-3:] != '\\\r\n':
+                yield (ERRORTOKEN, contstr + line,
+                           strstart, (lnum, len(line)), contline)
+                contstr = ''
+                contline = None
+                continue
+            else:
+                contstr = contstr + line
+                contline = contline + line
+                continue
+
+        elif parenlev == 0 and not continued:  # new statement
+            if not line: break
+            column = 0
+            while pos < max:                   # measure leading whitespace
+                if line[pos] == ' ': column = column + 1
+                elif line[pos] == '\t': column = (column/tabsize + 1)*tabsize
+                elif line[pos] == '\f': column = 0
+                else: break
+                pos = pos + 1
+            if pos == max: break
+
+            if line[pos] in '#\r\n':           # skip comments or blank lines
+                yield ((NL, COMMENT)[line[pos] == '#'], line[pos:],
+                           (lnum, pos), (lnum, len(line)), line)
+                continue
+
+            if column > indents[-1]:           # count indents or dedents
+                indents.append(column)
+                yield (INDENT, line[:pos], (lnum, 0), (lnum, pos), line)
+            while column < indents[-1]:
+                if column not in indents:
+                    raise IndentationError(
+                        "unindent does not match any outer indentation level",
+                        ("<tokenize>", lnum, pos, line))
+                indents = indents[:-1]
+                yield (DEDENT, '', (lnum, pos), (lnum, pos), line)
+
+        else:                                  # continued statement
+            if not line:
+                raise TokenError, ("EOF in multi-line statement", (lnum, 0))
+            continued = 0
+
+        while pos < max:
+            pseudomatch = pseudoprog.match(line, pos)
+            if pseudomatch:                                # scan for tokens
+                start, end = pseudomatch.span(1)
+                spos, epos, pos = (lnum, start), (lnum, end), end
+                token, initial = line[start:end], line[start]
+
+                if initial in numchars or \
+                   (initial == '.' and token != '.'):      # ordinary number
+                    yield (NUMBER, token, spos, epos, line)
+                elif initial in '\r\n':
+                    yield (parenlev > 0 and NL or NEWLINE,
+                               token, spos, epos, line)
+                elif initial == '#':
+                    yield (COMMENT, token, spos, epos, line)
+                elif token in triple_quoted:
+                    endprog = endprogs[token]
+                    endmatch = endprog.match(line, pos)
+                    if endmatch:                           # all on one line
+                        pos = endmatch.end(0)
+                        token = line[start:pos]
+                        yield (STRING, token, spos, (lnum, pos), line)
+                    else:
+                        strstart = (lnum, start)           # multiple lines
+                        contstr = line[start:]
+                        contline = line
+                        break
+                elif initial in single_quoted or \
+                    token[:2] in single_quoted or \
+                    token[:3] in single_quoted:
+                    if token[-1] == '\n':                  # continued string
+                        strstart = (lnum, start)
+                        endprog = (endprogs[initial] or endprogs[token[1]] or
+                                   endprogs[token[2]])
+                        contstr, needcont = line[start:], 1
+                        contline = line
+                        break
+                    else:                                  # ordinary string
+                        yield (STRING, token, spos, epos, line)
+                elif initial in namechars:                 # ordinary name
+                    yield (NAME, token, spos, epos, line)
+                elif initial == '\\':                      # continued stmt
+                    continued = 1
+                else:
+                    if initial in '([{': parenlev = parenlev + 1
+                    elif initial in ')]}': parenlev = parenlev - 1
+                    yield (OP, token, spos, epos, line)
+            else:
+                yield (ERRORTOKEN, line[pos],
+                           (lnum, pos), (lnum, pos+1), line)
+                pos = pos + 1
+
+    for indent in indents[1:]:                 # pop remaining indent levels
+        yield (DEDENT, '', (lnum, 0), (lnum, 0), '')
+    yield (ENDMARKER, '', (lnum, 0), (lnum, 0), '')
+
+if __name__ == '__main__':                     # testing
+    import sys
+    if len(sys.argv) > 1: tokenize(open(sys.argv[1]).readline)
+    else: tokenize(sys.stdin.readline)

Added: vendor/Python/current/Lib/trace.py
===================================================================
--- vendor/Python/current/Lib/trace.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/trace.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,792 @@
+#!/usr/bin/env python
+
+# portions copyright 2001, Autonomous Zones Industries, Inc., all rights...
+# err...  reserved and offered to the public under the terms of the
+# Python 2.2 license.
+# Author: Zooko O'Whielacronx
+# http://zooko.com/
+# mailto:zooko at zooko.com
+#
+# Copyright 2000, Mojam Media, Inc., all rights reserved.
+# Author: Skip Montanaro
+#
+# Copyright 1999, Bioreason, Inc., all rights reserved.
+# Author: Andrew Dalke
+#
+# Copyright 1995-1997, Automatrix, Inc., all rights reserved.
+# Author: Skip Montanaro
+#
+# Copyright 1991-1995, Stichting Mathematisch Centrum, all rights reserved.
+#
+#
+# Permission to use, copy, modify, and distribute this Python software and
+# its associated documentation for any purpose without fee is hereby
+# granted, provided that the above copyright notice appears in all copies,
+# and that both that copyright notice and this permission notice appear in
+# supporting documentation, and that the name of neither Automatrix,
+# Bioreason or Mojam Media be used in advertising or publicity pertaining to
+# distribution of the software without specific, written prior permission.
+#
+"""program/module to trace Python program or function execution
+
+Sample use, command line:
+  trace.py -c -f counts --ignore-dir '$prefix' spam.py eggs
+  trace.py -t --ignore-dir '$prefix' spam.py eggs
+  trace.py --trackcalls spam.py eggs
+
+Sample use, programmatically
+  import sys
+
+  # create a Trace object, telling it what to ignore, and whether to
+  # do tracing or line-counting or both.
+  tracer = trace.Trace(ignoredirs=[sys.prefix, sys.exec_prefix,], trace=0,
+                    count=1)
+  # run the new command using the given tracer
+  tracer.run('main()')
+  # make a report, placing output in /tmp
+  r = tracer.results()
+  r.write_results(show_missing=True, coverdir="/tmp")
+"""
+
+import linecache
+import os
+import re
+import sys
+import threading
+import token
+import tokenize
+import types
+import gc
+
+try:
+    import cPickle
+    pickle = cPickle
+except ImportError:
+    import pickle
+
+def usage(outfile):
+    outfile.write("""Usage: %s [OPTIONS] <file> [ARGS]
+
+Meta-options:
+--help                Display this help then exit.
+--version             Output version information then exit.
+
+Otherwise, exactly one of the following three options must be given:
+-t, --trace           Print each line to sys.stdout before it is executed.
+-c, --count           Count the number of times each line is executed
+                      and write the counts to <module>.cover for each
+                      module executed, in the module's directory.
+                      See also `--coverdir', `--file', `--no-report' below.
+-l, --listfuncs       Keep track of which functions are executed at least
+                      once and write the results to sys.stdout after the
+                      program exits.
+-T, --trackcalls      Keep track of caller/called pairs and write the
+                      results to sys.stdout after the program exits.
+-r, --report          Generate a report from a counts file; do not execute
+                      any code.  `--file' must specify the results file to
+                      read, which must have been created in a previous run
+                      with `--count --file=FILE'.
+
+Modifiers:
+-f, --file=<file>     File to accumulate counts over several runs.
+-R, --no-report       Do not generate the coverage report files.
+                      Useful if you want to accumulate over several runs.
+-C, --coverdir=<dir>  Directory where the report files.  The coverage
+                      report for <package>.<module> is written to file
+                      <dir>/<package>/<module>.cover.
+-m, --missing         Annotate executable lines that were not executed
+                      with '>>>>>> '.
+-s, --summary         Write a brief summary on stdout for each file.
+                      (Can only be used with --count or --report.)
+
+Filters, may be repeated multiple times:
+--ignore-module=<mod> Ignore the given module and its submodules
+                      (if it is a package).
+--ignore-dir=<dir>    Ignore files in the given directory (multiple
+                      directories can be joined by os.pathsep).
+""" % sys.argv[0])
+
+PRAGMA_NOCOVER = "#pragma NO COVER"
+
+# Simple rx to find lines with no code.
+rx_blank = re.compile(r'^\s*(#.*)?$')
+
+class Ignore:
+    def __init__(self, modules = None, dirs = None):
+        self._mods = modules or []
+        self._dirs = dirs or []
+
+        self._dirs = map(os.path.normpath, self._dirs)
+        self._ignore = { '<string>': 1 }
+
+    def names(self, filename, modulename):
+        if self._ignore.has_key(modulename):
+            return self._ignore[modulename]
+
+        # haven't seen this one before, so see if the module name is
+        # on the ignore list.  Need to take some care since ignoring
+        # "cmp" musn't mean ignoring "cmpcache" but ignoring
+        # "Spam" must also mean ignoring "Spam.Eggs".
+        for mod in self._mods:
+            if mod == modulename:  # Identical names, so ignore
+                self._ignore[modulename] = 1
+                return 1
+            # check if the module is a proper submodule of something on
+            # the ignore list
+            n = len(mod)
+            # (will not overflow since if the first n characters are the
+            # same and the name has not already occurred, then the size
+            # of "name" is greater than that of "mod")
+            if mod == modulename[:n] and modulename[n] == '.':
+                self._ignore[modulename] = 1
+                return 1
+
+        # Now check that __file__ isn't in one of the directories
+        if filename is None:
+            # must be a built-in, so we must ignore
+            self._ignore[modulename] = 1
+            return 1
+
+        # Ignore a file when it contains one of the ignorable paths
+        for d in self._dirs:
+            # The '+ os.sep' is to ensure that d is a parent directory,
+            # as compared to cases like:
+            #  d = "/usr/local"
+            #  filename = "/usr/local.py"
+            # or
+            #  d = "/usr/local.py"
+            #  filename = "/usr/local.py"
+            if filename.startswith(d + os.sep):
+                self._ignore[modulename] = 1
+                return 1
+
+        # Tried the different ways, so we don't ignore this module
+        self._ignore[modulename] = 0
+        return 0
+
+def modname(path):
+    """Return a plausible module name for the patch."""
+
+    base = os.path.basename(path)
+    filename, ext = os.path.splitext(base)
+    return filename
+
+def fullmodname(path):
+    """Return a plausible module name for the path."""
+
+    # If the file 'path' is part of a package, then the filename isn't
+    # enough to uniquely identify it.  Try to do the right thing by
+    # looking in sys.path for the longest matching prefix.  We'll
+    # assume that the rest is the package name.
+
+    comparepath = os.path.normcase(path)
+    longest = ""
+    for dir in sys.path:
+        dir = os.path.normcase(dir)
+        if comparepath.startswith(dir) and comparepath[len(dir)] == os.sep:
+            if len(dir) > len(longest):
+                longest = dir
+
+    if longest:
+        base = path[len(longest) + 1:]
+    else:
+        base = path
+    base = base.replace(os.sep, ".")
+    if os.altsep:
+        base = base.replace(os.altsep, ".")
+    filename, ext = os.path.splitext(base)
+    return filename
+
+class CoverageResults:
+    def __init__(self, counts=None, calledfuncs=None, infile=None,
+                 callers=None, outfile=None):
+        self.counts = counts
+        if self.counts is None:
+            self.counts = {}
+        self.counter = self.counts.copy() # map (filename, lineno) to count
+        self.calledfuncs = calledfuncs
+        if self.calledfuncs is None:
+            self.calledfuncs = {}
+        self.calledfuncs = self.calledfuncs.copy()
+        self.callers = callers
+        if self.callers is None:
+            self.callers = {}
+        self.callers = self.callers.copy()
+        self.infile = infile
+        self.outfile = outfile
+        if self.infile:
+            # Try to merge existing counts file.
+            try:
+                counts, calledfuncs, callers = \
+                        pickle.load(open(self.infile, 'rb'))
+                self.update(self.__class__(counts, calledfuncs, callers))
+            except (IOError, EOFError, ValueError), err:
+                print >> sys.stderr, ("Skipping counts file %r: %s"
+                                      % (self.infile, err))
+
+    def update(self, other):
+        """Merge in the data from another CoverageResults"""
+        counts = self.counts
+        calledfuncs = self.calledfuncs
+        callers = self.callers
+        other_counts = other.counts
+        other_calledfuncs = other.calledfuncs
+        other_callers = other.callers
+
+        for key in other_counts.keys():
+            counts[key] = counts.get(key, 0) + other_counts[key]
+
+        for key in other_calledfuncs.keys():
+            calledfuncs[key] = 1
+
+        for key in other_callers.keys():
+            callers[key] = 1
+
+    def write_results(self, show_missing=True, summary=False, coverdir=None):
+        """
+        @param coverdir
+        """
+        if self.calledfuncs:
+            print
+            print "functions called:"
+            calls = self.calledfuncs.keys()
+            calls.sort()
+            for filename, modulename, funcname in calls:
+                print ("filename: %s, modulename: %s, funcname: %s"
+                       % (filename, modulename, funcname))
+
+        if self.callers:
+            print
+            print "calling relationships:"
+            calls = self.callers.keys()
+            calls.sort()
+            lastfile = lastcfile = ""
+            for ((pfile, pmod, pfunc), (cfile, cmod, cfunc)) in calls:
+                if pfile != lastfile:
+                    print
+                    print "***", pfile, "***"
+                    lastfile = pfile
+                    lastcfile = ""
+                if cfile != pfile and lastcfile != cfile:
+                    print "  -->", cfile
+                    lastcfile = cfile
+                print "    %s.%s -> %s.%s" % (pmod, pfunc, cmod, cfunc)
+
+        # turn the counts data ("(filename, lineno) = count") into something
+        # accessible on a per-file basis
+        per_file = {}
+        for filename, lineno in self.counts.keys():
+            lines_hit = per_file[filename] = per_file.get(filename, {})
+            lines_hit[lineno] = self.counts[(filename, lineno)]
+
+        # accumulate summary info, if needed
+        sums = {}
+
+        for filename, count in per_file.iteritems():
+            # skip some "files" we don't care about...
+            if filename == "<string>":
+                continue
+
+            if filename.endswith((".pyc", ".pyo")):
+                filename = filename[:-1]
+
+            if coverdir is None:
+                dir = os.path.dirname(os.path.abspath(filename))
+                modulename = modname(filename)
+            else:
+                dir = coverdir
+                if not os.path.exists(dir):
+                    os.makedirs(dir)
+                modulename = fullmodname(filename)
+
+            # If desired, get a list of the line numbers which represent
+            # executable content (returned as a dict for better lookup speed)
+            if show_missing:
+                lnotab = find_executable_linenos(filename)
+            else:
+                lnotab = {}
+
+            source = linecache.getlines(filename)
+            coverpath = os.path.join(dir, modulename + ".cover")
+            n_hits, n_lines = self.write_results_file(coverpath, source,
+                                                      lnotab, count)
+
+            if summary and n_lines:
+                percent = int(100 * n_hits / n_lines)
+                sums[modulename] = n_lines, percent, modulename, filename
+
+        if summary and sums:
+            mods = sums.keys()
+            mods.sort()
+            print "lines   cov%   module   (path)"
+            for m in mods:
+                n_lines, percent, modulename, filename = sums[m]
+                print "%5d   %3d%%   %s   (%s)" % sums[m]
+
+        if self.outfile:
+            # try and store counts and module info into self.outfile
+            try:
+                pickle.dump((self.counts, self.calledfuncs, self.callers),
+                            open(self.outfile, 'wb'), 1)
+            except IOError, err:
+                print >> sys.stderr, "Can't save counts files because %s" % err
+
+    def write_results_file(self, path, lines, lnotab, lines_hit):
+        """Return a coverage results file in path."""
+
+        try:
+            outfile = open(path, "w")
+        except IOError, err:
+            print >> sys.stderr, ("trace: Could not open %r for writing: %s"
+                                  "- skipping" % (path, err))
+            return 0, 0
+
+        n_lines = 0
+        n_hits = 0
+        for i, line in enumerate(lines):
+            lineno = i + 1
+            # do the blank/comment match to try to mark more lines
+            # (help the reader find stuff that hasn't been covered)
+            if lineno in lines_hit:
+                outfile.write("%5d: " % lines_hit[lineno])
+                n_hits += 1
+                n_lines += 1
+            elif rx_blank.match(line):
+                outfile.write("       ")
+            else:
+                # lines preceded by no marks weren't hit
+                # Highlight them if so indicated, unless the line contains
+                # #pragma: NO COVER
+                if lineno in lnotab and not PRAGMA_NOCOVER in lines[i]:
+                    outfile.write(">>>>>> ")
+                    n_lines += 1
+                else:
+                    outfile.write("       ")
+            outfile.write(lines[i].expandtabs(8))
+        outfile.close()
+
+        return n_hits, n_lines
+
+def find_lines_from_code(code, strs):
+    """Return dict where keys are lines in the line number table."""
+    linenos = {}
+
+    line_increments = [ord(c) for c in code.co_lnotab[1::2]]
+    table_length = len(line_increments)
+    docstring = False
+
+    lineno = code.co_firstlineno
+    for li in line_increments:
+        lineno += li
+        if lineno not in strs:
+            linenos[lineno] = 1
+
+    return linenos
+
+def find_lines(code, strs):
+    """Return lineno dict for all code objects reachable from code."""
+    # get all of the lineno information from the code of this scope level
+    linenos = find_lines_from_code(code, strs)
+
+    # and check the constants for references to other code objects
+    for c in code.co_consts:
+        if isinstance(c, types.CodeType):
+            # find another code object, so recurse into it
+            linenos.update(find_lines(c, strs))
+    return linenos
+
+def find_strings(filename):
+    """Return a dict of possible docstring positions.
+
+    The dict maps line numbers to strings.  There is an entry for
+    line that contains only a string or a part of a triple-quoted
+    string.
+    """
+    d = {}
+    # If the first token is a string, then it's the module docstring.
+    # Add this special case so that the test in the loop passes.
+    prev_ttype = token.INDENT
+    f = open(filename)
+    for ttype, tstr, start, end, line in tokenize.generate_tokens(f.readline):
+        if ttype == token.STRING:
+            if prev_ttype == token.INDENT:
+                sline, scol = start
+                eline, ecol = end
+                for i in range(sline, eline + 1):
+                    d[i] = 1
+        prev_ttype = ttype
+    f.close()
+    return d
+
+def find_executable_linenos(filename):
+    """Return dict where keys are line numbers in the line number table."""
+    try:
+        prog = open(filename, "rU").read()
+    except IOError, err:
+        print >> sys.stderr, ("Not printing coverage data for %r: %s"
+                              % (filename, err))
+        return {}
+    code = compile(prog, filename, "exec")
+    strs = find_strings(filename)
+    return find_lines(code, strs)
+
+class Trace:
+    def __init__(self, count=1, trace=1, countfuncs=0, countcallers=0,
+                 ignoremods=(), ignoredirs=(), infile=None, outfile=None):
+        """
+        @param count true iff it should count number of times each
+                     line is executed
+        @param trace true iff it should print out each line that is
+                     being counted
+        @param countfuncs true iff it should just output a list of
+                     (filename, modulename, funcname,) for functions
+                     that were called at least once;  This overrides
+                     `count' and `trace'
+        @param ignoremods a list of the names of modules to ignore
+        @param ignoredirs a list of the names of directories to ignore
+                     all of the (recursive) contents of
+        @param infile file from which to read stored counts to be
+                     added into the results
+        @param outfile file in which to write the results
+        """
+        self.infile = infile
+        self.outfile = outfile
+        self.ignore = Ignore(ignoremods, ignoredirs)
+        self.counts = {}   # keys are (filename, linenumber)
+        self.blabbed = {} # for debugging
+        self.pathtobasename = {} # for memoizing os.path.basename
+        self.donothing = 0
+        self.trace = trace
+        self._calledfuncs = {}
+        self._callers = {}
+        self._caller_cache = {}
+        if countcallers:
+            self.globaltrace = self.globaltrace_trackcallers
+        elif countfuncs:
+            self.globaltrace = self.globaltrace_countfuncs
+        elif trace and count:
+            self.globaltrace = self.globaltrace_lt
+            self.localtrace = self.localtrace_trace_and_count
+        elif trace:
+            self.globaltrace = self.globaltrace_lt
+            self.localtrace = self.localtrace_trace
+        elif count:
+            self.globaltrace = self.globaltrace_lt
+            self.localtrace = self.localtrace_count
+        else:
+            # Ahem -- do nothing?  Okay.
+            self.donothing = 1
+
+    def run(self, cmd):
+        import __main__
+        dict = __main__.__dict__
+        if not self.donothing:
+            sys.settrace(self.globaltrace)
+            threading.settrace(self.globaltrace)
+        try:
+            exec cmd in dict, dict
+        finally:
+            if not self.donothing:
+                sys.settrace(None)
+                threading.settrace(None)
+
+    def runctx(self, cmd, globals=None, locals=None):
+        if globals is None: globals = {}
+        if locals is None: locals = {}
+        if not self.donothing:
+            sys.settrace(self.globaltrace)
+            threading.settrace(self.globaltrace)
+        try:
+            exec cmd in globals, locals
+        finally:
+            if not self.donothing:
+                sys.settrace(None)
+                threading.settrace(None)
+
+    def runfunc(self, func, *args, **kw):
+        result = None
+        if not self.donothing:
+            sys.settrace(self.globaltrace)
+        try:
+            result = func(*args, **kw)
+        finally:
+            if not self.donothing:
+                sys.settrace(None)
+        return result
+
+    def file_module_function_of(self, frame):
+        code = frame.f_code
+        filename = code.co_filename
+        if filename:
+            modulename = modname(filename)
+        else:
+            modulename = None
+
+        funcname = code.co_name
+        clsname = None
+        if code in self._caller_cache:
+            if self._caller_cache[code] is not None:
+                clsname = self._caller_cache[code]
+        else:
+            self._caller_cache[code] = None
+            ## use of gc.get_referrers() was suggested by Michael Hudson
+            # all functions which refer to this code object
+            funcs = [f for f in gc.get_referrers(code)
+                         if hasattr(f, "func_doc")]
+            # require len(func) == 1 to avoid ambiguity caused by calls to
+            # new.function(): "In the face of ambiguity, refuse the
+            # temptation to guess."
+            if len(funcs) == 1:
+                dicts = [d for d in gc.get_referrers(funcs[0])
+                             if isinstance(d, dict)]
+                if len(dicts) == 1:
+                    classes = [c for c in gc.get_referrers(dicts[0])
+                                   if hasattr(c, "__bases__")]
+                    if len(classes) == 1:
+                        # ditto for new.classobj()
+                        clsname = str(classes[0])
+                        # cache the result - assumption is that new.* is
+                        # not called later to disturb this relationship
+                        # _caller_cache could be flushed if functions in
+                        # the new module get called.
+                        self._caller_cache[code] = clsname
+        if clsname is not None:
+            # final hack - module name shows up in str(cls), but we've already
+            # computed module name, so remove it
+            clsname = clsname.split(".")[1:]
+            clsname = ".".join(clsname)
+            funcname = "%s.%s" % (clsname, funcname)
+
+        return filename, modulename, funcname
+
+    def globaltrace_trackcallers(self, frame, why, arg):
+        """Handler for call events.
+
+        Adds information about who called who to the self._callers dict.
+        """
+        if why == 'call':
+            # XXX Should do a better job of identifying methods
+            this_func = self.file_module_function_of(frame)
+            parent_func = self.file_module_function_of(frame.f_back)
+            self._callers[(parent_func, this_func)] = 1
+
+    def globaltrace_countfuncs(self, frame, why, arg):
+        """Handler for call events.
+
+        Adds (filename, modulename, funcname) to the self._calledfuncs dict.
+        """
+        if why == 'call':
+            this_func = self.file_module_function_of(frame)
+            self._calledfuncs[this_func] = 1
+
+    def globaltrace_lt(self, frame, why, arg):
+        """Handler for call events.
+
+        If the code block being entered is to be ignored, returns `None',
+        else returns self.localtrace.
+        """
+        if why == 'call':
+            code = frame.f_code
+            filename = frame.f_globals.get('__file__', None)
+            if filename:
+                # XXX modname() doesn't work right for packages, so
+                # the ignore support won't work right for packages
+                modulename = modname(filename)
+                if modulename is not None:
+                    ignore_it = self.ignore.names(filename, modulename)
+                    if not ignore_it:
+                        if self.trace:
+                            print (" --- modulename: %s, funcname: %s"
+                                   % (modulename, code.co_name))
+                        return self.localtrace
+            else:
+                return None
+
+    def localtrace_trace_and_count(self, frame, why, arg):
+        if why == "line":
+            # record the file name and line number of every trace
+            filename = frame.f_code.co_filename
+            lineno = frame.f_lineno
+            key = filename, lineno
+            self.counts[key] = self.counts.get(key, 0) + 1
+
+            bname = os.path.basename(filename)
+            print "%s(%d): %s" % (bname, lineno,
+                                  linecache.getline(filename, lineno)),
+        return self.localtrace
+
+    def localtrace_trace(self, frame, why, arg):
+        if why == "line":
+            # record the file name and line number of every trace
+            filename = frame.f_code.co_filename
+            lineno = frame.f_lineno
+
+            bname = os.path.basename(filename)
+            print "%s(%d): %s" % (bname, lineno,
+                                  linecache.getline(filename, lineno)),
+        return self.localtrace
+
+    def localtrace_count(self, frame, why, arg):
+        if why == "line":
+            filename = frame.f_code.co_filename
+            lineno = frame.f_lineno
+            key = filename, lineno
+            self.counts[key] = self.counts.get(key, 0) + 1
+        return self.localtrace
+
+    def results(self):
+        return CoverageResults(self.counts, infile=self.infile,
+                               outfile=self.outfile,
+                               calledfuncs=self._calledfuncs,
+                               callers=self._callers)
+
+def _err_exit(msg):
+    sys.stderr.write("%s: %s\n" % (sys.argv[0], msg))
+    sys.exit(1)
+
+def main(argv=None):
+    import getopt
+
+    if argv is None:
+        argv = sys.argv
+    try:
+        opts, prog_argv = getopt.getopt(argv[1:], "tcrRf:d:msC:lT",
+                                        ["help", "version", "trace", "count",
+                                         "report", "no-report", "summary",
+                                         "file=", "missing",
+                                         "ignore-module=", "ignore-dir=",
+                                         "coverdir=", "listfuncs",
+                                         "trackcalls"])
+
+    except getopt.error, msg:
+        sys.stderr.write("%s: %s\n" % (sys.argv[0], msg))
+        sys.stderr.write("Try `%s --help' for more information\n"
+                         % sys.argv[0])
+        sys.exit(1)
+
+    trace = 0
+    count = 0
+    report = 0
+    no_report = 0
+    counts_file = None
+    missing = 0
+    ignore_modules = []
+    ignore_dirs = []
+    coverdir = None
+    summary = 0
+    listfuncs = False
+    countcallers = False
+
+    for opt, val in opts:
+        if opt == "--help":
+            usage(sys.stdout)
+            sys.exit(0)
+
+        if opt == "--version":
+            sys.stdout.write("trace 2.0\n")
+            sys.exit(0)
+
+        if opt == "-T" or opt == "--trackcalls":
+            countcallers = True
+            continue
+
+        if opt == "-l" or opt == "--listfuncs":
+            listfuncs = True
+            continue
+
+        if opt == "-t" or opt == "--trace":
+            trace = 1
+            continue
+
+        if opt == "-c" or opt == "--count":
+            count = 1
+            continue
+
+        if opt == "-r" or opt == "--report":
+            report = 1
+            continue
+
+        if opt == "-R" or opt == "--no-report":
+            no_report = 1
+            continue
+
+        if opt == "-f" or opt == "--file":
+            counts_file = val
+            continue
+
+        if opt == "-m" or opt == "--missing":
+            missing = 1
+            continue
+
+        if opt == "-C" or opt == "--coverdir":
+            coverdir = val
+            continue
+
+        if opt == "-s" or opt == "--summary":
+            summary = 1
+            continue
+
+        if opt == "--ignore-module":
+            ignore_modules.append(val)
+            continue
+
+        if opt == "--ignore-dir":
+            for s in val.split(os.pathsep):
+                s = os.path.expandvars(s)
+                # should I also call expanduser? (after all, could use $HOME)
+
+                s = s.replace("$prefix",
+                              os.path.join(sys.prefix, "lib",
+                                           "python" + sys.version[:3]))
+                s = s.replace("$exec_prefix",
+                              os.path.join(sys.exec_prefix, "lib",
+                                           "python" + sys.version[:3]))
+                s = os.path.normpath(s)
+                ignore_dirs.append(s)
+            continue
+
+        assert 0, "Should never get here"
+
+    if listfuncs and (count or trace):
+        _err_exit("cannot specify both --listfuncs and (--trace or --count)")
+
+    if not (count or trace or report or listfuncs or countcallers):
+        _err_exit("must specify one of --trace, --count, --report, "
+                  "--listfuncs, or --trackcalls")
+
+    if report and no_report:
+        _err_exit("cannot specify both --report and --no-report")
+
+    if report and not counts_file:
+        _err_exit("--report requires a --file")
+
+    if no_report and len(prog_argv) == 0:
+        _err_exit("missing name of file to run")
+
+    # everything is ready
+    if report:
+        results = CoverageResults(infile=counts_file, outfile=counts_file)
+        results.write_results(missing, summary=summary, coverdir=coverdir)
+    else:
+        sys.argv = prog_argv
+        progname = prog_argv[0]
+        sys.path[0] = os.path.split(progname)[0]
+
+        t = Trace(count, trace, countfuncs=listfuncs,
+                  countcallers=countcallers, ignoremods=ignore_modules,
+                  ignoredirs=ignore_dirs, infile=counts_file,
+                  outfile=counts_file)
+        try:
+            t.run('execfile(%r)' % (progname,))
+        except IOError, err:
+            _err_exit("Cannot run file %r because: %s" % (sys.argv[0], err))
+        except SystemExit:
+            pass
+
+        results = t.results()
+
+        if not no_report:
+            results.write_results(missing, summary=summary, coverdir=coverdir)
+
+if __name__=='__main__':
+    main()

Added: vendor/Python/current/Lib/traceback.py
===================================================================
--- vendor/Python/current/Lib/traceback.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/traceback.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,312 @@
+"""Extract, format and print information about Python stack traces."""
+
+import linecache
+import sys
+import types
+
+__all__ = ['extract_stack', 'extract_tb', 'format_exception',
+           'format_exception_only', 'format_list', 'format_stack',
+           'format_tb', 'print_exc', 'format_exc', 'print_exception',
+           'print_last', 'print_stack', 'print_tb', 'tb_lineno']
+
+def _print(file, str='', terminator='\n'):
+    file.write(str+terminator)
+
+
+def print_list(extracted_list, file=None):
+    """Print the list of tuples as returned by extract_tb() or
+    extract_stack() as a formatted stack trace to the given file."""
+    if file is None:
+        file = sys.stderr
+    for filename, lineno, name, line in extracted_list:
+        _print(file,
+               '  File "%s", line %d, in %s' % (filename,lineno,name))
+        if line:
+            _print(file, '    %s' % line.strip())
+
+def format_list(extracted_list):
+    """Format a list of traceback entry tuples for printing.
+
+    Given a list of tuples as returned by extract_tb() or
+    extract_stack(), return a list of strings ready for printing.
+    Each string in the resulting list corresponds to the item with the
+    same index in the argument list.  Each string ends in a newline;
+    the strings may contain internal newlines as well, for those items
+    whose source text line is not None.
+    """
+    list = []
+    for filename, lineno, name, line in extracted_list:
+        item = '  File "%s", line %d, in %s\n' % (filename,lineno,name)
+        if line:
+            item = item + '    %s\n' % line.strip()
+        list.append(item)
+    return list
+
+
+def print_tb(tb, limit=None, file=None):
+    """Print up to 'limit' stack trace entries from the traceback 'tb'.
+
+    If 'limit' is omitted or None, all entries are printed.  If 'file'
+    is omitted or None, the output goes to sys.stderr; otherwise
+    'file' should be an open file or file-like object with a write()
+    method.
+    """
+    if file is None:
+        file = sys.stderr
+    if limit is None:
+        if hasattr(sys, 'tracebacklimit'):
+            limit = sys.tracebacklimit
+    n = 0
+    while tb is not None and (limit is None or n < limit):
+        f = tb.tb_frame
+        lineno = tb.tb_lineno
+        co = f.f_code
+        filename = co.co_filename
+        name = co.co_name
+        _print(file,
+               '  File "%s", line %d, in %s' % (filename,lineno,name))
+        linecache.checkcache(filename)
+        line = linecache.getline(filename, lineno, f.f_globals)
+        if line: _print(file, '    ' + line.strip())
+        tb = tb.tb_next
+        n = n+1
+
+def format_tb(tb, limit = None):
+    """A shorthand for 'format_list(extract_stack(f, limit))."""
+    return format_list(extract_tb(tb, limit))
+
+def extract_tb(tb, limit = None):
+    """Return list of up to limit pre-processed entries from traceback.
+
+    This is useful for alternate formatting of stack traces.  If
+    'limit' is omitted or None, all entries are extracted.  A
+    pre-processed stack trace entry is a quadruple (filename, line
+    number, function name, text) representing the information that is
+    usually printed for a stack trace.  The text is a string with
+    leading and trailing whitespace stripped; if the source is not
+    available it is None.
+    """
+    if limit is None:
+        if hasattr(sys, 'tracebacklimit'):
+            limit = sys.tracebacklimit
+    list = []
+    n = 0
+    while tb is not None and (limit is None or n < limit):
+        f = tb.tb_frame
+        lineno = tb.tb_lineno
+        co = f.f_code
+        filename = co.co_filename
+        name = co.co_name
+        linecache.checkcache(filename)
+        line = linecache.getline(filename, lineno, f.f_globals)
+        if line: line = line.strip()
+        else: line = None
+        list.append((filename, lineno, name, line))
+        tb = tb.tb_next
+        n = n+1
+    return list
+
+
+def print_exception(etype, value, tb, limit=None, file=None):
+    """Print exception up to 'limit' stack trace entries from 'tb' to 'file'.
+
+    This differs from print_tb() in the following ways: (1) if
+    traceback is not None, it prints a header "Traceback (most recent
+    call last):"; (2) it prints the exception type and value after the
+    stack trace; (3) if type is SyntaxError and value has the
+    appropriate format, it prints the line where the syntax error
+    occurred with a caret on the next line indicating the approximate
+    position of the error.
+    """
+    if file is None:
+        file = sys.stderr
+    if tb:
+        _print(file, 'Traceback (most recent call last):')
+        print_tb(tb, limit, file)
+    lines = format_exception_only(etype, value)
+    for line in lines[:-1]:
+        _print(file, line, ' ')
+    _print(file, lines[-1], '')
+
+def format_exception(etype, value, tb, limit = None):
+    """Format a stack trace and the exception information.
+
+    The arguments have the same meaning as the corresponding arguments
+    to print_exception().  The return value is a list of strings, each
+    ending in a newline and some containing internal newlines.  When
+    these lines are concatenated and printed, exactly the same text is
+    printed as does print_exception().
+    """
+    if tb:
+        list = ['Traceback (most recent call last):\n']
+        list = list + format_tb(tb, limit)
+    else:
+        list = []
+    list = list + format_exception_only(etype, value)
+    return list
+
+def format_exception_only(etype, value):
+    """Format the exception part of a traceback.
+
+    The arguments are the exception type and value such as given by
+    sys.last_type and sys.last_value. The return value is a list of
+    strings, each ending in a newline.
+
+    Normally, the list contains a single string; however, for
+    SyntaxError exceptions, it contains several lines that (when
+    printed) display detailed information about where the syntax
+    error occurred.
+
+    The message indicating which exception occurred is always the last
+    string in the list.
+
+    """
+
+    # An instance should not have a meaningful value parameter, but
+    # sometimes does, particularly for string exceptions, such as
+    # >>> raise string1, string2  # deprecated
+    #
+    # Clear these out first because issubtype(string1, SyntaxError)
+    # would throw another exception and mask the original problem.
+    if (isinstance(etype, BaseException) or
+        isinstance(etype, types.InstanceType) or
+        etype is None or type(etype) is str):
+        return [_format_final_exc_line(etype, value)]
+
+    stype = etype.__name__
+
+    if not issubclass(etype, SyntaxError):
+        return [_format_final_exc_line(stype, value)]
+
+    # It was a syntax error; show exactly where the problem was found.
+    lines = []
+    try:
+        msg, (filename, lineno, offset, badline) = value
+    except Exception:
+        pass
+    else:
+        filename = filename or "<string>"
+        lines.append('  File "%s", line %d\n' % (filename, lineno))
+        if badline is not None:
+            lines.append('    %s\n' % badline.strip())
+            if offset is not None:
+                caretspace = badline[:offset].lstrip()
+                # non-space whitespace (likes tabs) must be kept for alignment
+                caretspace = ((c.isspace() and c or ' ') for c in caretspace)
+                # only three spaces to account for offset1 == pos 0
+                lines.append('   %s^\n' % ''.join(caretspace))
+            value = msg
+
+    lines.append(_format_final_exc_line(stype, value))
+    return lines
+
+def _format_final_exc_line(etype, value):
+    """Return a list of a single line -- normal case for format_exception_only"""
+    valuestr = _some_str(value)
+    if value is None or not valuestr:
+        line = "%s\n" % etype
+    else:
+        line = "%s: %s\n" % (etype, valuestr)
+    return line
+
+def _some_str(value):
+    try:
+        return str(value)
+    except:
+        return '<unprintable %s object>' % type(value).__name__
+
+
+def print_exc(limit=None, file=None):
+    """Shorthand for 'print_exception(sys.exc_type, sys.exc_value, sys.exc_traceback, limit, file)'.
+    (In fact, it uses sys.exc_info() to retrieve the same information
+    in a thread-safe way.)"""
+    if file is None:
+        file = sys.stderr
+    try:
+        etype, value, tb = sys.exc_info()
+        print_exception(etype, value, tb, limit, file)
+    finally:
+        etype = value = tb = None
+
+
+def format_exc(limit=None):
+    """Like print_exc() but return a string."""
+    try:
+        etype, value, tb = sys.exc_info()
+        return ''.join(format_exception(etype, value, tb, limit))
+    finally:
+        etype = value = tb = None
+
+
+def print_last(limit=None, file=None):
+    """This is a shorthand for 'print_exception(sys.last_type,
+    sys.last_value, sys.last_traceback, limit, file)'."""
+    if file is None:
+        file = sys.stderr
+    print_exception(sys.last_type, sys.last_value, sys.last_traceback,
+                    limit, file)
+
+
+def print_stack(f=None, limit=None, file=None):
+    """Print a stack trace from its invocation point.
+
+    The optional 'f' argument can be used to specify an alternate
+    stack frame at which to start. The optional 'limit' and 'file'
+    arguments have the same meaning as for print_exception().
+    """
+    if f is None:
+        try:
+            raise ZeroDivisionError
+        except ZeroDivisionError:
+            f = sys.exc_info()[2].tb_frame.f_back
+    print_list(extract_stack(f, limit), file)
+
+def format_stack(f=None, limit=None):
+    """Shorthand for 'format_list(extract_stack(f, limit))'."""
+    if f is None:
+        try:
+            raise ZeroDivisionError
+        except ZeroDivisionError:
+            f = sys.exc_info()[2].tb_frame.f_back
+    return format_list(extract_stack(f, limit))
+
+def extract_stack(f=None, limit = None):
+    """Extract the raw traceback from the current stack frame.
+
+    The return value has the same format as for extract_tb().  The
+    optional 'f' and 'limit' arguments have the same meaning as for
+    print_stack().  Each item in the list is a quadruple (filename,
+    line number, function name, text), and the entries are in order
+    from oldest to newest stack frame.
+    """
+    if f is None:
+        try:
+            raise ZeroDivisionError
+        except ZeroDivisionError:
+            f = sys.exc_info()[2].tb_frame.f_back
+    if limit is None:
+        if hasattr(sys, 'tracebacklimit'):
+            limit = sys.tracebacklimit
+    list = []
+    n = 0
+    while f is not None and (limit is None or n < limit):
+        lineno = f.f_lineno
+        co = f.f_code
+        filename = co.co_filename
+        name = co.co_name
+        linecache.checkcache(filename)
+        line = linecache.getline(filename, lineno, f.f_globals)
+        if line: line = line.strip()
+        else: line = None
+        list.append((filename, lineno, name, line))
+        f = f.f_back
+        n = n+1
+    list.reverse()
+    return list
+
+def tb_lineno(tb):
+    """Calculate correct line number of traceback given in tb.
+
+    Obsolete in 2.3.
+    """
+    return tb.tb_lineno

Added: vendor/Python/current/Lib/tty.py
===================================================================
--- vendor/Python/current/Lib/tty.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/tty.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,36 @@
+"""Terminal utilities."""
+
+# Author: Steen Lumholt.
+
+from termios import *
+
+__all__ = ["setraw", "setcbreak"]
+
+# Indexes for termios list.
+IFLAG = 0
+OFLAG = 1
+CFLAG = 2
+LFLAG = 3
+ISPEED = 4
+OSPEED = 5
+CC = 6
+
+def setraw(fd, when=TCSAFLUSH):
+    """Put terminal into a raw mode."""
+    mode = tcgetattr(fd)
+    mode[IFLAG] = mode[IFLAG] & ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON)
+    mode[OFLAG] = mode[OFLAG] & ~(OPOST)
+    mode[CFLAG] = mode[CFLAG] & ~(CSIZE | PARENB)
+    mode[CFLAG] = mode[CFLAG] | CS8
+    mode[LFLAG] = mode[LFLAG] & ~(ECHO | ICANON | IEXTEN | ISIG)
+    mode[CC][VMIN] = 1
+    mode[CC][VTIME] = 0
+    tcsetattr(fd, when, mode)
+
+def setcbreak(fd, when=TCSAFLUSH):
+    """Put terminal into a cbreak mode."""
+    mode = tcgetattr(fd)
+    mode[LFLAG] = mode[LFLAG] & ~(ECHO | ICANON)
+    mode[CC][VMIN] = 1
+    mode[CC][VTIME] = 0
+    tcsetattr(fd, when, mode)

Added: vendor/Python/current/Lib/types.py
===================================================================
--- vendor/Python/current/Lib/types.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/types.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,101 @@
+"""Define names for all type symbols known in the standard interpreter.
+
+Types that are part of optional modules (e.g. array) are not listed.
+"""
+import sys
+
+# Iterators in Python aren't a matter of type but of protocol.  A large
+# and changing number of builtin types implement *some* flavor of
+# iterator.  Don't check the type!  Use hasattr to check for both
+# "__iter__" and "next" attributes instead.
+
+NoneType = type(None)
+TypeType = type
+ObjectType = object
+
+IntType = int
+LongType = long
+FloatType = float
+BooleanType = bool
+try:
+    ComplexType = complex
+except NameError:
+    pass
+
+StringType = str
+
+# StringTypes is already outdated.  Instead of writing "type(x) in
+# types.StringTypes", you should use "isinstance(x, basestring)".  But
+# we keep around for compatibility with Python 2.2.
+try:
+    UnicodeType = unicode
+    StringTypes = (StringType, UnicodeType)
+except NameError:
+    StringTypes = (StringType,)
+
+BufferType = buffer
+
+TupleType = tuple
+ListType = list
+DictType = DictionaryType = dict
+
+def _f(): pass
+FunctionType = type(_f)
+LambdaType = type(lambda: None)         # Same as FunctionType
+try:
+    CodeType = type(_f.func_code)
+except RuntimeError:
+    # Execution in restricted environment
+    pass
+
+def _g():
+    yield 1
+GeneratorType = type(_g())
+
+class _C:
+    def _m(self): pass
+ClassType = type(_C)
+UnboundMethodType = type(_C._m)         # Same as MethodType
+_x = _C()
+InstanceType = type(_x)
+MethodType = type(_x._m)
+
+BuiltinFunctionType = type(len)
+BuiltinMethodType = type([].append)     # Same as BuiltinFunctionType
+
+ModuleType = type(sys)
+FileType = file
+XRangeType = xrange
+
+try:
+    raise TypeError
+except TypeError:
+    try:
+        tb = sys.exc_info()[2]
+        TracebackType = type(tb)
+        FrameType = type(tb.tb_frame)
+    except AttributeError:
+        # In the restricted environment, exc_info returns (None, None,
+        # None) Then, tb.tb_frame gives an attribute error
+        pass
+    tb = None; del tb
+
+SliceType = slice
+EllipsisType = type(Ellipsis)
+
+DictProxyType = type(TypeType.__dict__)
+NotImplementedType = type(NotImplemented)
+
+# Extension types defined in a C helper module.  XXX There may be no
+# equivalent in implementations other than CPython, so it seems better to
+# leave them undefined then to set them to e.g. None.
+try:
+    import _types
+except ImportError:
+    pass
+else:
+    GetSetDescriptorType = type(_types.Helper.getter)
+    MemberDescriptorType = type(_types.Helper.member)
+    del _types
+
+del sys, _f, _g, _C, _x                           # Not for export

Added: vendor/Python/current/Lib/unittest.py
===================================================================
--- vendor/Python/current/Lib/unittest.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/unittest.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,816 @@
+#!/usr/bin/env python
+'''
+Python unit testing framework, based on Erich Gamma's JUnit and Kent Beck's
+Smalltalk testing framework.
+
+This module contains the core framework classes that form the basis of
+specific test cases and suites (TestCase, TestSuite etc.), and also a
+text-based utility class for running the tests and reporting the results
+ (TextTestRunner).
+
+Simple usage:
+
+    import unittest
+
+    class IntegerArithmenticTestCase(unittest.TestCase):
+        def testAdd(self):  ## test method names begin 'test*'
+            self.assertEquals((1 + 2), 3)
+            self.assertEquals(0 + 1, 1)
+        def testMultiply(self):
+            self.assertEquals((0 * 10), 0)
+            self.assertEquals((5 * 8), 40)
+
+    if __name__ == '__main__':
+        unittest.main()
+
+Further information is available in the bundled documentation, and from
+
+  http://pyunit.sourceforge.net/
+
+Copyright (c) 1999-2003 Steve Purcell
+This module is free software, and you may redistribute it and/or modify
+it under the same terms as Python itself, so long as this copyright message
+and disclaimer are retained in their original form.
+
+IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
+SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF
+THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
+
+THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE.  THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS,
+AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
+SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+'''
+
+__author__ = "Steve Purcell"
+__email__ = "stephen_purcell at yahoo dot com"
+__version__ = "#Revision: 1.63 $"[11:-2]
+
+import time
+import sys
+import traceback
+import os
+import types
+
+##############################################################################
+# Exported classes and functions
+##############################################################################
+__all__ = ['TestResult', 'TestCase', 'TestSuite', 'TextTestRunner',
+           'TestLoader', 'FunctionTestCase', 'main', 'defaultTestLoader']
+
+# Expose obsolete functions for backwards compatibility
+__all__.extend(['getTestCaseNames', 'makeSuite', 'findTestCases'])
+
+
+##############################################################################
+# Backward compatibility
+##############################################################################
+if sys.version_info[:2] < (2, 2):
+    False, True = 0, 1
+    def isinstance(obj, clsinfo):
+        import __builtin__
+        if type(clsinfo) in (tuple, list):
+            for cls in clsinfo:
+                if cls is type: cls = types.ClassType
+                if __builtin__.isinstance(obj, cls):
+                    return 1
+            return 0
+        else: return __builtin__.isinstance(obj, clsinfo)
+
+
+##############################################################################
+# Test framework core
+##############################################################################
+
+# All classes defined herein are 'new-style' classes, allowing use of 'super()'
+__metaclass__ = type
+
+def _strclass(cls):
+    return "%s.%s" % (cls.__module__, cls.__name__)
+
+__unittest = 1
+
+class TestResult:
+    """Holder for test result information.
+
+    Test results are automatically managed by the TestCase and TestSuite
+    classes, and do not need to be explicitly manipulated by writers of tests.
+
+    Each instance holds the total number of tests run, and collections of
+    failures and errors that occurred among those test runs. The collections
+    contain tuples of (testcase, exceptioninfo), where exceptioninfo is the
+    formatted traceback of the error that occurred.
+    """
+    def __init__(self):
+        self.failures = []
+        self.errors = []
+        self.testsRun = 0
+        self.shouldStop = 0
+
+    def startTest(self, test):
+        "Called when the given test is about to be run"
+        self.testsRun = self.testsRun + 1
+
+    def stopTest(self, test):
+        "Called when the given test has been run"
+        pass
+
+    def addError(self, test, err):
+        """Called when an error has occurred. 'err' is a tuple of values as
+        returned by sys.exc_info().
+        """
+        self.errors.append((test, self._exc_info_to_string(err, test)))
+
+    def addFailure(self, test, err):
+        """Called when an error has occurred. 'err' is a tuple of values as
+        returned by sys.exc_info()."""
+        self.failures.append((test, self._exc_info_to_string(err, test)))
+
+    def addSuccess(self, test):
+        "Called when a test has completed successfully"
+        pass
+
+    def wasSuccessful(self):
+        "Tells whether or not this result was a success"
+        return len(self.failures) == len(self.errors) == 0
+
+    def stop(self):
+        "Indicates that the tests should be aborted"
+        self.shouldStop = True
+
+    def _exc_info_to_string(self, err, test):
+        """Converts a sys.exc_info()-style tuple of values into a string."""
+        exctype, value, tb = err
+        # Skip test runner traceback levels
+        while tb and self._is_relevant_tb_level(tb):
+            tb = tb.tb_next
+        if exctype is test.failureException:
+            # Skip assert*() traceback levels
+            length = self._count_relevant_tb_levels(tb)
+            return ''.join(traceback.format_exception(exctype, value, tb, length))
+        return ''.join(traceback.format_exception(exctype, value, tb))
+
+    def _is_relevant_tb_level(self, tb):
+        return tb.tb_frame.f_globals.has_key('__unittest')
+
+    def _count_relevant_tb_levels(self, tb):
+        length = 0
+        while tb and not self._is_relevant_tb_level(tb):
+            length += 1
+            tb = tb.tb_next
+        return length
+
+    def __repr__(self):
+        return "<%s run=%i errors=%i failures=%i>" % \
+               (_strclass(self.__class__), self.testsRun, len(self.errors),
+                len(self.failures))
+
+class TestCase:
+    """A class whose instances are single test cases.
+
+    By default, the test code itself should be placed in a method named
+    'runTest'.
+
+    If the fixture may be used for many test cases, create as
+    many test methods as are needed. When instantiating such a TestCase
+    subclass, specify in the constructor arguments the name of the test method
+    that the instance is to execute.
+
+    Test authors should subclass TestCase for their own tests. Construction
+    and deconstruction of the test's environment ('fixture') can be
+    implemented by overriding the 'setUp' and 'tearDown' methods respectively.
+
+    If it is necessary to override the __init__ method, the base class
+    __init__ method must always be called. It is important that subclasses
+    should not change the signature of their __init__ method, since instances
+    of the classes are instantiated automatically by parts of the framework
+    in order to be run.
+    """
+
+    # This attribute determines which exception will be raised when
+    # the instance's assertion methods fail; test methods raising this
+    # exception will be deemed to have 'failed' rather than 'errored'
+
+    failureException = AssertionError
+
+    def __init__(self, methodName='runTest'):
+        """Create an instance of the class that will use the named test
+           method when executed. Raises a ValueError if the instance does
+           not have a method with the specified name.
+        """
+        try:
+            self._testMethodName = methodName
+            testMethod = getattr(self, methodName)
+            self._testMethodDoc = testMethod.__doc__
+        except AttributeError:
+            raise ValueError, "no such test method in %s: %s" % \
+                  (self.__class__, methodName)
+
+    def setUp(self):
+        "Hook method for setting up the test fixture before exercising it."
+        pass
+
+    def tearDown(self):
+        "Hook method for deconstructing the test fixture after testing it."
+        pass
+
+    def countTestCases(self):
+        return 1
+
+    def defaultTestResult(self):
+        return TestResult()
+
+    def shortDescription(self):
+        """Returns a one-line description of the test, or None if no
+        description has been provided.
+
+        The default implementation of this method returns the first line of
+        the specified test method's docstring.
+        """
+        doc = self._testMethodDoc
+        return doc and doc.split("\n")[0].strip() or None
+
+    def id(self):
+        return "%s.%s" % (_strclass(self.__class__), self._testMethodName)
+
+    def __str__(self):
+        return "%s (%s)" % (self._testMethodName, _strclass(self.__class__))
+
+    def __repr__(self):
+        return "<%s testMethod=%s>" % \
+               (_strclass(self.__class__), self._testMethodName)
+
+    def run(self, result=None):
+        if result is None: result = self.defaultTestResult()
+        result.startTest(self)
+        testMethod = getattr(self, self._testMethodName)
+        try:
+            try:
+                self.setUp()
+            except KeyboardInterrupt:
+                raise
+            except:
+                result.addError(self, self._exc_info())
+                return
+
+            ok = False
+            try:
+                testMethod()
+                ok = True
+            except self.failureException:
+                result.addFailure(self, self._exc_info())
+            except KeyboardInterrupt:
+                raise
+            except:
+                result.addError(self, self._exc_info())
+
+            try:
+                self.tearDown()
+            except KeyboardInterrupt:
+                raise
+            except:
+                result.addError(self, self._exc_info())
+                ok = False
+            if ok: result.addSuccess(self)
+        finally:
+            result.stopTest(self)
+
+    def __call__(self, *args, **kwds):
+        return self.run(*args, **kwds)
+
+    def debug(self):
+        """Run the test without collecting errors in a TestResult"""
+        self.setUp()
+        getattr(self, self._testMethodName)()
+        self.tearDown()
+
+    def _exc_info(self):
+        """Return a version of sys.exc_info() with the traceback frame
+           minimised; usually the top level of the traceback frame is not
+           needed.
+        """
+        exctype, excvalue, tb = sys.exc_info()
+        if sys.platform[:4] == 'java': ## tracebacks look different in Jython
+            return (exctype, excvalue, tb)
+        return (exctype, excvalue, tb)
+
+    def fail(self, msg=None):
+        """Fail immediately, with the given message."""
+        raise self.failureException, msg
+
+    def failIf(self, expr, msg=None):
+        "Fail the test if the expression is true."
+        if expr: raise self.failureException, msg
+
+    def failUnless(self, expr, msg=None):
+        """Fail the test unless the expression is true."""
+        if not expr: raise self.failureException, msg
+
+    def failUnlessRaises(self, excClass, callableObj, *args, **kwargs):
+        """Fail unless an exception of class excClass is thrown
+           by callableObj when invoked with arguments args and keyword
+           arguments kwargs. If a different type of exception is
+           thrown, it will not be caught, and the test case will be
+           deemed to have suffered an error, exactly as for an
+           unexpected exception.
+        """
+        try:
+            callableObj(*args, **kwargs)
+        except excClass:
+            return
+        else:
+            if hasattr(excClass,'__name__'): excName = excClass.__name__
+            else: excName = str(excClass)
+            raise self.failureException, "%s not raised" % excName
+
+    def failUnlessEqual(self, first, second, msg=None):
+        """Fail if the two objects are unequal as determined by the '=='
+           operator.
+        """
+        if not first == second:
+            raise self.failureException, \
+                  (msg or '%r != %r' % (first, second))
+
+    def failIfEqual(self, first, second, msg=None):
+        """Fail if the two objects are equal as determined by the '=='
+           operator.
+        """
+        if first == second:
+            raise self.failureException, \
+                  (msg or '%r == %r' % (first, second))
+
+    def failUnlessAlmostEqual(self, first, second, places=7, msg=None):
+        """Fail if the two objects are unequal as determined by their
+           difference rounded to the given number of decimal places
+           (default 7) and comparing to zero.
+
+           Note that decimal places (from zero) are usually not the same
+           as significant digits (measured from the most signficant digit).
+        """
+        if round(second-first, places) != 0:
+            raise self.failureException, \
+                  (msg or '%r != %r within %r places' % (first, second, places))
+
+    def failIfAlmostEqual(self, first, second, places=7, msg=None):
+        """Fail if the two objects are equal as determined by their
+           difference rounded to the given number of decimal places
+           (default 7) and comparing to zero.
+
+           Note that decimal places (from zero) are usually not the same
+           as significant digits (measured from the most signficant digit).
+        """
+        if round(second-first, places) == 0:
+            raise self.failureException, \
+                  (msg or '%r == %r within %r places' % (first, second, places))
+
+    # Synonyms for assertion methods
+
+    assertEqual = assertEquals = failUnlessEqual
+
+    assertNotEqual = assertNotEquals = failIfEqual
+
+    assertAlmostEqual = assertAlmostEquals = failUnlessAlmostEqual
+
+    assertNotAlmostEqual = assertNotAlmostEquals = failIfAlmostEqual
+
+    assertRaises = failUnlessRaises
+
+    assert_ = assertTrue = failUnless
+
+    assertFalse = failIf
+
+
+
+class TestSuite:
+    """A test suite is a composite test consisting of a number of TestCases.
+
+    For use, create an instance of TestSuite, then add test case instances.
+    When all tests have been added, the suite can be passed to a test
+    runner, such as TextTestRunner. It will run the individual test cases
+    in the order in which they were added, aggregating the results. When
+    subclassing, do not forget to call the base class constructor.
+    """
+    def __init__(self, tests=()):
+        self._tests = []
+        self.addTests(tests)
+
+    def __repr__(self):
+        return "<%s tests=%s>" % (_strclass(self.__class__), self._tests)
+
+    __str__ = __repr__
+
+    def __iter__(self):
+        return iter(self._tests)
+
+    def countTestCases(self):
+        cases = 0
+        for test in self._tests:
+            cases += test.countTestCases()
+        return cases
+
+    def addTest(self, test):
+        # sanity checks
+        if not callable(test):
+            raise TypeError("the test to add must be callable")
+        if (isinstance(test, (type, types.ClassType)) and
+            issubclass(test, (TestCase, TestSuite))):
+            raise TypeError("TestCases and TestSuites must be instantiated "
+                            "before passing them to addTest()")
+        self._tests.append(test)
+
+    def addTests(self, tests):
+        if isinstance(tests, basestring):
+            raise TypeError("tests must be an iterable of tests, not a string")
+        for test in tests:
+            self.addTest(test)
+
+    def run(self, result):
+        for test in self._tests:
+            if result.shouldStop:
+                break
+            test(result)
+        return result
+
+    def __call__(self, *args, **kwds):
+        return self.run(*args, **kwds)
+
+    def debug(self):
+        """Run the tests without collecting errors in a TestResult"""
+        for test in self._tests: test.debug()
+
+
+class FunctionTestCase(TestCase):
+    """A test case that wraps a test function.
+
+    This is useful for slipping pre-existing test functions into the
+    PyUnit framework. Optionally, set-up and tidy-up functions can be
+    supplied. As with TestCase, the tidy-up ('tearDown') function will
+    always be called if the set-up ('setUp') function ran successfully.
+    """
+
+    def __init__(self, testFunc, setUp=None, tearDown=None,
+                 description=None):
+        TestCase.__init__(self)
+        self.__setUpFunc = setUp
+        self.__tearDownFunc = tearDown
+        self.__testFunc = testFunc
+        self.__description = description
+
+    def setUp(self):
+        if self.__setUpFunc is not None:
+            self.__setUpFunc()
+
+    def tearDown(self):
+        if self.__tearDownFunc is not None:
+            self.__tearDownFunc()
+
+    def runTest(self):
+        self.__testFunc()
+
+    def id(self):
+        return self.__testFunc.__name__
+
+    def __str__(self):
+        return "%s (%s)" % (_strclass(self.__class__), self.__testFunc.__name__)
+
+    def __repr__(self):
+        return "<%s testFunc=%s>" % (_strclass(self.__class__), self.__testFunc)
+
+    def shortDescription(self):
+        if self.__description is not None: return self.__description
+        doc = self.__testFunc.__doc__
+        return doc and doc.split("\n")[0].strip() or None
+
+
+
+##############################################################################
+# Locating and loading tests
+##############################################################################
+
+class TestLoader:
+    """This class is responsible for loading tests according to various
+    criteria and returning them wrapped in a Test
+    """
+    testMethodPrefix = 'test'
+    sortTestMethodsUsing = cmp
+    suiteClass = TestSuite
+
+    def loadTestsFromTestCase(self, testCaseClass):
+        """Return a suite of all tests cases contained in testCaseClass"""
+        if issubclass(testCaseClass, TestSuite):
+            raise TypeError("Test cases should not be derived from TestSuite. Maybe you meant to derive from TestCase?")
+        testCaseNames = self.getTestCaseNames(testCaseClass)
+        if not testCaseNames and hasattr(testCaseClass, 'runTest'):
+            testCaseNames = ['runTest']
+        return self.suiteClass(map(testCaseClass, testCaseNames))
+
+    def loadTestsFromModule(self, module):
+        """Return a suite of all tests cases contained in the given module"""
+        tests = []
+        for name in dir(module):
+            obj = getattr(module, name)
+            if (isinstance(obj, (type, types.ClassType)) and
+                issubclass(obj, TestCase)):
+                tests.append(self.loadTestsFromTestCase(obj))
+        return self.suiteClass(tests)
+
+    def loadTestsFromName(self, name, module=None):
+        """Return a suite of all tests cases given a string specifier.
+
+        The name may resolve either to a module, a test case class, a
+        test method within a test case class, or a callable object which
+        returns a TestCase or TestSuite instance.
+
+        The method optionally resolves the names relative to a given module.
+        """
+        parts = name.split('.')
+        if module is None:
+            parts_copy = parts[:]
+            while parts_copy:
+                try:
+                    module = __import__('.'.join(parts_copy))
+                    break
+                except ImportError:
+                    del parts_copy[-1]
+                    if not parts_copy: raise
+            parts = parts[1:]
+        obj = module
+        for part in parts:
+            parent, obj = obj, getattr(obj, part)
+
+        if type(obj) == types.ModuleType:
+            return self.loadTestsFromModule(obj)
+        elif (isinstance(obj, (type, types.ClassType)) and
+              issubclass(obj, TestCase)):
+            return self.loadTestsFromTestCase(obj)
+        elif type(obj) == types.UnboundMethodType:
+            return parent(obj.__name__)
+        elif isinstance(obj, TestSuite):
+            return obj
+        elif callable(obj):
+            test = obj()
+            if not isinstance(test, (TestCase, TestSuite)):
+                raise ValueError, \
+                      "calling %s returned %s, not a test" % (obj,test)
+            return test
+        else:
+            raise ValueError, "don't know how to make test from: %s" % obj
+
+    def loadTestsFromNames(self, names, module=None):
+        """Return a suite of all tests cases found using the given sequence
+        of string specifiers. See 'loadTestsFromName()'.
+        """
+        suites = [self.loadTestsFromName(name, module) for name in names]
+        return self.suiteClass(suites)
+
+    def getTestCaseNames(self, testCaseClass):
+        """Return a sorted sequence of method names found within testCaseClass
+        """
+        def isTestMethod(attrname, testCaseClass=testCaseClass, prefix=self.testMethodPrefix):
+            return attrname.startswith(prefix) and callable(getattr(testCaseClass, attrname))
+        testFnNames = filter(isTestMethod, dir(testCaseClass))
+        for baseclass in testCaseClass.__bases__:
+            for testFnName in self.getTestCaseNames(baseclass):
+                if testFnName not in testFnNames:  # handle overridden methods
+                    testFnNames.append(testFnName)
+        if self.sortTestMethodsUsing:
+            testFnNames.sort(self.sortTestMethodsUsing)
+        return testFnNames
+
+
+
+defaultTestLoader = TestLoader()
+
+
+##############################################################################
+# Patches for old functions: these functions should be considered obsolete
+##############################################################################
+
+def _makeLoader(prefix, sortUsing, suiteClass=None):
+    loader = TestLoader()
+    loader.sortTestMethodsUsing = sortUsing
+    loader.testMethodPrefix = prefix
+    if suiteClass: loader.suiteClass = suiteClass
+    return loader
+
+def getTestCaseNames(testCaseClass, prefix, sortUsing=cmp):
+    return _makeLoader(prefix, sortUsing).getTestCaseNames(testCaseClass)
+
+def makeSuite(testCaseClass, prefix='test', sortUsing=cmp, suiteClass=TestSuite):
+    return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromTestCase(testCaseClass)
+
+def findTestCases(module, prefix='test', sortUsing=cmp, suiteClass=TestSuite):
+    return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromModule(module)
+
+
+##############################################################################
+# Text UI
+##############################################################################
+
+class _WritelnDecorator:
+    """Used to decorate file-like objects with a handy 'writeln' method"""
+    def __init__(self,stream):
+        self.stream = stream
+
+    def __getattr__(self, attr):
+        return getattr(self.stream,attr)
+
+    def writeln(self, arg=None):
+        if arg: self.write(arg)
+        self.write('\n') # text-mode streams translate to \r\n if needed
+
+
+class _TextTestResult(TestResult):
+    """A test result class that can print formatted text results to a stream.
+
+    Used by TextTestRunner.
+    """
+    separator1 = '=' * 70
+    separator2 = '-' * 70
+
+    def __init__(self, stream, descriptions, verbosity):
+        TestResult.__init__(self)
+        self.stream = stream
+        self.showAll = verbosity > 1
+        self.dots = verbosity == 1
+        self.descriptions = descriptions
+
+    def getDescription(self, test):
+        if self.descriptions:
+            return test.shortDescription() or str(test)
+        else:
+            return str(test)
+
+    def startTest(self, test):
+        TestResult.startTest(self, test)
+        if self.showAll:
+            self.stream.write(self.getDescription(test))
+            self.stream.write(" ... ")
+
+    def addSuccess(self, test):
+        TestResult.addSuccess(self, test)
+        if self.showAll:
+            self.stream.writeln("ok")
+        elif self.dots:
+            self.stream.write('.')
+
+    def addError(self, test, err):
+        TestResult.addError(self, test, err)
+        if self.showAll:
+            self.stream.writeln("ERROR")
+        elif self.dots:
+            self.stream.write('E')
+
+    def addFailure(self, test, err):
+        TestResult.addFailure(self, test, err)
+        if self.showAll:
+            self.stream.writeln("FAIL")
+        elif self.dots:
+            self.stream.write('F')
+
+    def printErrors(self):
+        if self.dots or self.showAll:
+            self.stream.writeln()
+        self.printErrorList('ERROR', self.errors)
+        self.printErrorList('FAIL', self.failures)
+
+    def printErrorList(self, flavour, errors):
+        for test, err in errors:
+            self.stream.writeln(self.separator1)
+            self.stream.writeln("%s: %s" % (flavour,self.getDescription(test)))
+            self.stream.writeln(self.separator2)
+            self.stream.writeln("%s" % err)
+
+
+class TextTestRunner:
+    """A test runner class that displays results in textual form.
+
+    It prints out the names of tests as they are run, errors as they
+    occur, and a summary of the results at the end of the test run.
+    """
+    def __init__(self, stream=sys.stderr, descriptions=1, verbosity=1):
+        self.stream = _WritelnDecorator(stream)
+        self.descriptions = descriptions
+        self.verbosity = verbosity
+
+    def _makeResult(self):
+        return _TextTestResult(self.stream, self.descriptions, self.verbosity)
+
+    def run(self, test):
+        "Run the given test case or test suite."
+        result = self._makeResult()
+        startTime = time.time()
+        test(result)
+        stopTime = time.time()
+        timeTaken = stopTime - startTime
+        result.printErrors()
+        self.stream.writeln(result.separator2)
+        run = result.testsRun
+        self.stream.writeln("Ran %d test%s in %.3fs" %
+                            (run, run != 1 and "s" or "", timeTaken))
+        self.stream.writeln()
+        if not result.wasSuccessful():
+            self.stream.write("FAILED (")
+            failed, errored = map(len, (result.failures, result.errors))
+            if failed:
+                self.stream.write("failures=%d" % failed)
+            if errored:
+                if failed: self.stream.write(", ")
+                self.stream.write("errors=%d" % errored)
+            self.stream.writeln(")")
+        else:
+            self.stream.writeln("OK")
+        return result
+
+
+
+##############################################################################
+# Facilities for running tests from the command line
+##############################################################################
+
+class TestProgram:
+    """A command-line program that runs a set of tests; this is primarily
+       for making test modules conveniently executable.
+    """
+    USAGE = """\
+Usage: %(progName)s [options] [test] [...]
+
+Options:
+  -h, --help       Show this message
+  -v, --verbose    Verbose output
+  -q, --quiet      Minimal output
+
+Examples:
+  %(progName)s                               - run default set of tests
+  %(progName)s MyTestSuite                   - run suite 'MyTestSuite'
+  %(progName)s MyTestCase.testSomething      - run MyTestCase.testSomething
+  %(progName)s MyTestCase                    - run all 'test*' test methods
+                                               in MyTestCase
+"""
+    def __init__(self, module='__main__', defaultTest=None,
+                 argv=None, testRunner=None, testLoader=defaultTestLoader):
+        if type(module) == type(''):
+            self.module = __import__(module)
+            for part in module.split('.')[1:]:
+                self.module = getattr(self.module, part)
+        else:
+            self.module = module
+        if argv is None:
+            argv = sys.argv
+        self.verbosity = 1
+        self.defaultTest = defaultTest
+        self.testRunner = testRunner
+        self.testLoader = testLoader
+        self.progName = os.path.basename(argv[0])
+        self.parseArgs(argv)
+        self.runTests()
+
+    def usageExit(self, msg=None):
+        if msg: print msg
+        print self.USAGE % self.__dict__
+        sys.exit(2)
+
+    def parseArgs(self, argv):
+        import getopt
+        try:
+            options, args = getopt.getopt(argv[1:], 'hHvq',
+                                          ['help','verbose','quiet'])
+            for opt, value in options:
+                if opt in ('-h','-H','--help'):
+                    self.usageExit()
+                if opt in ('-q','--quiet'):
+                    self.verbosity = 0
+                if opt in ('-v','--verbose'):
+                    self.verbosity = 2
+            if len(args) == 0 and self.defaultTest is None:
+                self.test = self.testLoader.loadTestsFromModule(self.module)
+                return
+            if len(args) > 0:
+                self.testNames = args
+            else:
+                self.testNames = (self.defaultTest,)
+            self.createTests()
+        except getopt.error, msg:
+            self.usageExit(msg)
+
+    def createTests(self):
+        self.test = self.testLoader.loadTestsFromNames(self.testNames,
+                                                       self.module)
+
+    def runTests(self):
+        if self.testRunner is None:
+            self.testRunner = TextTestRunner(verbosity=self.verbosity)
+        result = self.testRunner.run(self.test)
+        sys.exit(not result.wasSuccessful())
+
+main = TestProgram
+
+
+##############################################################################
+# Executing this module from the command line
+##############################################################################
+
+if __name__ == "__main__":
+    main(module=None)

Added: vendor/Python/current/Lib/urllib.py
===================================================================
--- vendor/Python/current/Lib/urllib.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/urllib.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1538 @@
+"""Open an arbitrary URL.
+
+See the following document for more info on URLs:
+"Names and Addresses, URIs, URLs, URNs, URCs", at
+http://www.w3.org/pub/WWW/Addressing/Overview.html
+
+See also the HTTP spec (from which the error codes are derived):
+"HTTP - Hypertext Transfer Protocol", at
+http://www.w3.org/pub/WWW/Protocols/
+
+Related standards and specs:
+- RFC1808: the "relative URL" spec. (authoritative status)
+- RFC1738 - the "URL standard". (authoritative status)
+- RFC1630 - the "URI spec". (informational status)
+
+The object returned by URLopener().open(file) will differ per
+protocol.  All you know is that is has methods read(), readline(),
+readlines(), fileno(), close() and info().  The read*(), fileno()
+and close() methods work like those of open files.
+The info() method returns a mimetools.Message object which can be
+used to query various info about the object, if available.
+(mimetools.Message objects are queried with the getheader() method.)
+"""
+
+import string
+import socket
+import os
+import time
+import sys
+from urlparse import urljoin as basejoin
+
+__all__ = ["urlopen", "URLopener", "FancyURLopener", "urlretrieve",
+           "urlcleanup", "quote", "quote_plus", "unquote", "unquote_plus",
+           "urlencode", "url2pathname", "pathname2url", "splittag",
+           "localhost", "thishost", "ftperrors", "basejoin", "unwrap",
+           "splittype", "splithost", "splituser", "splitpasswd", "splitport",
+           "splitnport", "splitquery", "splitattr", "splitvalue",
+           "splitgophertype", "getproxies"]
+
+__version__ = '1.17'    # XXX This version is not always updated :-(
+
+MAXFTPCACHE = 10        # Trim the ftp cache beyond this size
+
+# Helper for non-unix systems
+if os.name == 'mac':
+    from macurl2path import url2pathname, pathname2url
+elif os.name == 'nt':
+    from nturl2path import url2pathname, pathname2url
+elif os.name == 'riscos':
+    from rourl2path import url2pathname, pathname2url
+else:
+    def url2pathname(pathname):
+        """OS-specific conversion from a relative URL of the 'file' scheme
+        to a file system path; not recommended for general use."""
+        return unquote(pathname)
+
+    def pathname2url(pathname):
+        """OS-specific conversion from a file system path to a relative URL
+        of the 'file' scheme; not recommended for general use."""
+        return quote(pathname)
+
+# This really consists of two pieces:
+# (1) a class which handles opening of all sorts of URLs
+#     (plus assorted utilities etc.)
+# (2) a set of functions for parsing URLs
+# XXX Should these be separated out into different modules?
+
+
+# Shortcut for basic usage
+_urlopener = None
+def urlopen(url, data=None, proxies=None):
+    """urlopen(url [, data]) -> open file-like object"""
+    global _urlopener
+    if proxies is not None:
+        opener = FancyURLopener(proxies=proxies)
+    elif not _urlopener:
+        opener = FancyURLopener()
+        _urlopener = opener
+    else:
+        opener = _urlopener
+    if data is None:
+        return opener.open(url)
+    else:
+        return opener.open(url, data)
+def urlretrieve(url, filename=None, reporthook=None, data=None):
+    global _urlopener
+    if not _urlopener:
+        _urlopener = FancyURLopener()
+    return _urlopener.retrieve(url, filename, reporthook, data)
+def urlcleanup():
+    if _urlopener:
+        _urlopener.cleanup()
+
+# exception raised when downloaded size does not match content-length
+class ContentTooShortError(IOError):
+    def __init__(self, message, content):
+        IOError.__init__(self, message)
+        self.content = content
+
+ftpcache = {}
+class URLopener:
+    """Class to open URLs.
+    This is a class rather than just a subroutine because we may need
+    more than one set of global protocol-specific options.
+    Note -- this is a base class for those who don't want the
+    automatic handling of errors type 302 (relocated) and 401
+    (authorization needed)."""
+
+    __tempfiles = None
+
+    version = "Python-urllib/%s" % __version__
+
+    # Constructor
+    def __init__(self, proxies=None, **x509):
+        if proxies is None:
+            proxies = getproxies()
+        assert hasattr(proxies, 'has_key'), "proxies must be a mapping"
+        self.proxies = proxies
+        self.key_file = x509.get('key_file')
+        self.cert_file = x509.get('cert_file')
+        self.addheaders = [('User-Agent', self.version)]
+        self.__tempfiles = []
+        self.__unlink = os.unlink # See cleanup()
+        self.tempcache = None
+        # Undocumented feature: if you assign {} to tempcache,
+        # it is used to cache files retrieved with
+        # self.retrieve().  This is not enabled by default
+        # since it does not work for changing documents (and I
+        # haven't got the logic to check expiration headers
+        # yet).
+        self.ftpcache = ftpcache
+        # Undocumented feature: you can use a different
+        # ftp cache by assigning to the .ftpcache member;
+        # in case you want logically independent URL openers
+        # XXX This is not threadsafe.  Bah.
+
+    def __del__(self):
+        self.close()
+
+    def close(self):
+        self.cleanup()
+
+    def cleanup(self):
+        # This code sometimes runs when the rest of this module
+        # has already been deleted, so it can't use any globals
+        # or import anything.
+        if self.__tempfiles:
+            for file in self.__tempfiles:
+                try:
+                    self.__unlink(file)
+                except OSError:
+                    pass
+            del self.__tempfiles[:]
+        if self.tempcache:
+            self.tempcache.clear()
+
+    def addheader(self, *args):
+        """Add a header to be used by the HTTP interface only
+        e.g. u.addheader('Accept', 'sound/basic')"""
+        self.addheaders.append(args)
+
+    # External interface
+    def open(self, fullurl, data=None):
+        """Use URLopener().open(file) instead of open(file, 'r')."""
+        fullurl = unwrap(toBytes(fullurl))
+        if self.tempcache and fullurl in self.tempcache:
+            filename, headers = self.tempcache[fullurl]
+            fp = open(filename, 'rb')
+            return addinfourl(fp, headers, fullurl)
+        urltype, url = splittype(fullurl)
+        if not urltype:
+            urltype = 'file'
+        if urltype in self.proxies:
+            proxy = self.proxies[urltype]
+            urltype, proxyhost = splittype(proxy)
+            host, selector = splithost(proxyhost)
+            url = (host, fullurl) # Signal special case to open_*()
+        else:
+            proxy = None
+        name = 'open_' + urltype
+        self.type = urltype
+        name = name.replace('-', '_')
+        if not hasattr(self, name):
+            if proxy:
+                return self.open_unknown_proxy(proxy, fullurl, data)
+            else:
+                return self.open_unknown(fullurl, data)
+        try:
+            if data is None:
+                return getattr(self, name)(url)
+            else:
+                return getattr(self, name)(url, data)
+        except socket.error, msg:
+            raise IOError, ('socket error', msg), sys.exc_info()[2]
+
+    def open_unknown(self, fullurl, data=None):
+        """Overridable interface to open unknown URL type."""
+        type, url = splittype(fullurl)
+        raise IOError, ('url error', 'unknown url type', type)
+
+    def open_unknown_proxy(self, proxy, fullurl, data=None):
+        """Overridable interface to open unknown URL type."""
+        type, url = splittype(fullurl)
+        raise IOError, ('url error', 'invalid proxy for %s' % type, proxy)
+
+    # External interface
+    def retrieve(self, url, filename=None, reporthook=None, data=None):
+        """retrieve(url) returns (filename, headers) for a local object
+        or (tempfilename, headers) for a remote object."""
+        url = unwrap(toBytes(url))
+        if self.tempcache and url in self.tempcache:
+            return self.tempcache[url]
+        type, url1 = splittype(url)
+        if filename is None and (not type or type == 'file'):
+            try:
+                fp = self.open_local_file(url1)
+                hdrs = fp.info()
+                del fp
+                return url2pathname(splithost(url1)[1]), hdrs
+            except IOError, msg:
+                pass
+        fp = self.open(url, data)
+        headers = fp.info()
+        if filename:
+            tfp = open(filename, 'wb')
+        else:
+            import tempfile
+            garbage, path = splittype(url)
+            garbage, path = splithost(path or "")
+            path, garbage = splitquery(path or "")
+            path, garbage = splitattr(path or "")
+            suffix = os.path.splitext(path)[1]
+            (fd, filename) = tempfile.mkstemp(suffix)
+            self.__tempfiles.append(filename)
+            tfp = os.fdopen(fd, 'wb')
+        result = filename, headers
+        if self.tempcache is not None:
+            self.tempcache[url] = result
+        bs = 1024*8
+        size = -1
+        read = 0
+        blocknum = 0
+        if reporthook:
+            if "content-length" in headers:
+                size = int(headers["Content-Length"])
+            reporthook(blocknum, bs, size)
+        while 1:
+            block = fp.read(bs)
+            if block == "":
+                break
+            read += len(block)
+            tfp.write(block)
+            blocknum += 1
+            if reporthook:
+                reporthook(blocknum, bs, size)
+        fp.close()
+        tfp.close()
+        del fp
+        del tfp
+
+        # raise exception if actual size does not match content-length header
+        if size >= 0 and read < size:
+            raise ContentTooShortError("retrieval incomplete: got only %i out "
+                                       "of %i bytes" % (read, size), result)
+
+        return result
+
+    # Each method named open_<type> knows how to open that type of URL
+
+    def open_http(self, url, data=None):
+        """Use HTTP protocol."""
+        import httplib
+        user_passwd = None
+        proxy_passwd= None
+        if isinstance(url, str):
+            host, selector = splithost(url)
+            if host:
+                user_passwd, host = splituser(host)
+                host = unquote(host)
+            realhost = host
+        else:
+            host, selector = url
+            # check whether the proxy contains authorization information
+            proxy_passwd, host = splituser(host)
+            # now we proceed with the url we want to obtain
+            urltype, rest = splittype(selector)
+            url = rest
+            user_passwd = None
+            if urltype.lower() != 'http':
+                realhost = None
+            else:
+                realhost, rest = splithost(rest)
+                if realhost:
+                    user_passwd, realhost = splituser(realhost)
+                if user_passwd:
+                    selector = "%s://%s%s" % (urltype, realhost, rest)
+                if proxy_bypass(realhost):
+                    host = realhost
+
+            #print "proxy via http:", host, selector
+        if not host: raise IOError, ('http error', 'no host given')
+
+        if proxy_passwd:
+            import base64
+            proxy_auth = base64.b64encode(proxy_passwd).strip()
+        else:
+            proxy_auth = None
+
+        if user_passwd:
+            import base64
+            auth = base64.b64encode(user_passwd).strip()
+        else:
+            auth = None
+        h = httplib.HTTP(host)
+        if data is not None:
+            h.putrequest('POST', selector)
+            h.putheader('Content-Type', 'application/x-www-form-urlencoded')
+            h.putheader('Content-Length', '%d' % len(data))
+        else:
+            h.putrequest('GET', selector)
+        if proxy_auth: h.putheader('Proxy-Authorization', 'Basic %s' % proxy_auth)
+        if auth: h.putheader('Authorization', 'Basic %s' % auth)
+        if realhost: h.putheader('Host', realhost)
+        for args in self.addheaders: h.putheader(*args)
+        h.endheaders()
+        if data is not None:
+            h.send(data)
+        errcode, errmsg, headers = h.getreply()
+        if errcode == -1:
+            # something went wrong with the HTTP status line
+            raise IOError, ('http protocol error', 0,
+                            'got a bad status line', None)
+        fp = h.getfile()
+        if errcode == 200:
+            return addinfourl(fp, headers, "http:" + url)
+        else:
+            if data is None:
+                return self.http_error(url, fp, errcode, errmsg, headers)
+            else:
+                return self.http_error(url, fp, errcode, errmsg, headers, data)
+
+    def http_error(self, url, fp, errcode, errmsg, headers, data=None):
+        """Handle http errors.
+        Derived class can override this, or provide specific handlers
+        named http_error_DDD where DDD is the 3-digit error code."""
+        # First check if there's a specific handler for this error
+        name = 'http_error_%d' % errcode
+        if hasattr(self, name):
+            method = getattr(self, name)
+            if data is None:
+                result = method(url, fp, errcode, errmsg, headers)
+            else:
+                result = method(url, fp, errcode, errmsg, headers, data)
+            if result: return result
+        return self.http_error_default(url, fp, errcode, errmsg, headers)
+
+    def http_error_default(self, url, fp, errcode, errmsg, headers):
+        """Default error handler: close the connection and raise IOError."""
+        void = fp.read()
+        fp.close()
+        raise IOError, ('http error', errcode, errmsg, headers)
+
+    if hasattr(socket, "ssl"):
+        def open_https(self, url, data=None):
+            """Use HTTPS protocol."""
+            import httplib
+            user_passwd = None
+            proxy_passwd = None
+            if isinstance(url, str):
+                host, selector = splithost(url)
+                if host:
+                    user_passwd, host = splituser(host)
+                    host = unquote(host)
+                realhost = host
+            else:
+                host, selector = url
+                # here, we determine, whether the proxy contains authorization information
+                proxy_passwd, host = splituser(host)
+                urltype, rest = splittype(selector)
+                url = rest
+                user_passwd = None
+                if urltype.lower() != 'https':
+                    realhost = None
+                else:
+                    realhost, rest = splithost(rest)
+                    if realhost:
+                        user_passwd, realhost = splituser(realhost)
+                    if user_passwd:
+                        selector = "%s://%s%s" % (urltype, realhost, rest)
+                #print "proxy via https:", host, selector
+            if not host: raise IOError, ('https error', 'no host given')
+            if proxy_passwd:
+                import base64
+                proxy_auth = base64.b64encode(proxy_passwd).strip()
+            else:
+                proxy_auth = None
+            if user_passwd:
+                import base64
+                auth = base64.b64encode(user_passwd).strip()
+            else:
+                auth = None
+            h = httplib.HTTPS(host, 0,
+                              key_file=self.key_file,
+                              cert_file=self.cert_file)
+            if data is not None:
+                h.putrequest('POST', selector)
+                h.putheader('Content-Type',
+                            'application/x-www-form-urlencoded')
+                h.putheader('Content-Length', '%d' % len(data))
+            else:
+                h.putrequest('GET', selector)
+            if proxy_auth: h.putheader('Proxy-Authorization', 'Basic %s' % proxy_auth)
+            if auth: h.putheader('Authorization', 'Basic %s' % auth)
+            if realhost: h.putheader('Host', realhost)
+            for args in self.addheaders: h.putheader(*args)
+            h.endheaders()
+            if data is not None:
+                h.send(data)
+            errcode, errmsg, headers = h.getreply()
+            if errcode == -1:
+                # something went wrong with the HTTP status line
+                raise IOError, ('http protocol error', 0,
+                                'got a bad status line', None)
+            fp = h.getfile()
+            if errcode == 200:
+                return addinfourl(fp, headers, "https:" + url)
+            else:
+                if data is None:
+                    return self.http_error(url, fp, errcode, errmsg, headers)
+                else:
+                    return self.http_error(url, fp, errcode, errmsg, headers,
+                                           data)
+
+    def open_gopher(self, url):
+        """Use Gopher protocol."""
+        if not isinstance(url, str):
+            raise IOError, ('gopher error', 'proxy support for gopher protocol currently not implemented')
+        import gopherlib
+        host, selector = splithost(url)
+        if not host: raise IOError, ('gopher error', 'no host given')
+        host = unquote(host)
+        type, selector = splitgophertype(selector)
+        selector, query = splitquery(selector)
+        selector = unquote(selector)
+        if query:
+            query = unquote(query)
+            fp = gopherlib.send_query(selector, query, host)
+        else:
+            fp = gopherlib.send_selector(selector, host)
+        return addinfourl(fp, noheaders(), "gopher:" + url)
+
+    def open_file(self, url):
+        """Use local file or FTP depending on form of URL."""
+        if not isinstance(url, str):
+            raise IOError, ('file error', 'proxy support for file protocol currently not implemented')
+        if url[:2] == '//' and url[2:3] != '/' and url[2:12].lower() != 'localhost/':
+            return self.open_ftp(url)
+        else:
+            return self.open_local_file(url)
+
+    def open_local_file(self, url):
+        """Use local file."""
+        import mimetypes, mimetools, email.Utils
+        try:
+            from cStringIO import StringIO
+        except ImportError:
+            from StringIO import StringIO
+        host, file = splithost(url)
+        localname = url2pathname(file)
+        try:
+            stats = os.stat(localname)
+        except OSError, e:
+            raise IOError(e.errno, e.strerror, e.filename)
+        size = stats.st_size
+        modified = email.Utils.formatdate(stats.st_mtime, usegmt=True)
+        mtype = mimetypes.guess_type(url)[0]
+        headers = mimetools.Message(StringIO(
+            'Content-Type: %s\nContent-Length: %d\nLast-modified: %s\n' %
+            (mtype or 'text/plain', size, modified)))
+        if not host:
+            urlfile = file
+            if file[:1] == '/':
+                urlfile = 'file://' + file
+            return addinfourl(open(localname, 'rb'),
+                              headers, urlfile)
+        host, port = splitport(host)
+        if not port \
+           and socket.gethostbyname(host) in (localhost(), thishost()):
+            urlfile = file
+            if file[:1] == '/':
+                urlfile = 'file://' + file
+            return addinfourl(open(localname, 'rb'),
+                              headers, urlfile)
+        raise IOError, ('local file error', 'not on local host')
+
+    def open_ftp(self, url):
+        """Use FTP protocol."""
+        if not isinstance(url, str):
+            raise IOError, ('ftp error', 'proxy support for ftp protocol currently not implemented')
+        import mimetypes, mimetools
+        try:
+            from cStringIO import StringIO
+        except ImportError:
+            from StringIO import StringIO
+        host, path = splithost(url)
+        if not host: raise IOError, ('ftp error', 'no host given')
+        host, port = splitport(host)
+        user, host = splituser(host)
+        if user: user, passwd = splitpasswd(user)
+        else: passwd = None
+        host = unquote(host)
+        user = unquote(user or '')
+        passwd = unquote(passwd or '')
+        host = socket.gethostbyname(host)
+        if not port:
+            import ftplib
+            port = ftplib.FTP_PORT
+        else:
+            port = int(port)
+        path, attrs = splitattr(path)
+        path = unquote(path)
+        dirs = path.split('/')
+        dirs, file = dirs[:-1], dirs[-1]
+        if dirs and not dirs[0]: dirs = dirs[1:]
+        if dirs and not dirs[0]: dirs[0] = '/'
+        key = user, host, port, '/'.join(dirs)
+        # XXX thread unsafe!
+        if len(self.ftpcache) > MAXFTPCACHE:
+            # Prune the cache, rather arbitrarily
+            for k in self.ftpcache.keys():
+                if k != key:
+                    v = self.ftpcache[k]
+                    del self.ftpcache[k]
+                    v.close()
+        try:
+            if not key in self.ftpcache:
+                self.ftpcache[key] = \
+                    ftpwrapper(user, passwd, host, port, dirs)
+            if not file: type = 'D'
+            else: type = 'I'
+            for attr in attrs:
+                attr, value = splitvalue(attr)
+                if attr.lower() == 'type' and \
+                   value in ('a', 'A', 'i', 'I', 'd', 'D'):
+                    type = value.upper()
+            (fp, retrlen) = self.ftpcache[key].retrfile(file, type)
+            mtype = mimetypes.guess_type("ftp:" + url)[0]
+            headers = ""
+            if mtype:
+                headers += "Content-Type: %s\n" % mtype
+            if retrlen is not None and retrlen >= 0:
+                headers += "Content-Length: %d\n" % retrlen
+            headers = mimetools.Message(StringIO(headers))
+            return addinfourl(fp, headers, "ftp:" + url)
+        except ftperrors(), msg:
+            raise IOError, ('ftp error', msg), sys.exc_info()[2]
+
+    def open_data(self, url, data=None):
+        """Use "data" URL."""
+        if not isinstance(url, str):
+            raise IOError, ('data error', 'proxy support for data protocol currently not implemented')
+        # ignore POSTed data
+        #
+        # syntax of data URLs:
+        # dataurl   := "data:" [ mediatype ] [ ";base64" ] "," data
+        # mediatype := [ type "/" subtype ] *( ";" parameter )
+        # data      := *urlchar
+        # parameter := attribute "=" value
+        import mimetools
+        try:
+            from cStringIO import StringIO
+        except ImportError:
+            from StringIO import StringIO
+        try:
+            [type, data] = url.split(',', 1)
+        except ValueError:
+            raise IOError, ('data error', 'bad data URL')
+        if not type:
+            type = 'text/plain;charset=US-ASCII'
+        semi = type.rfind(';')
+        if semi >= 0 and '=' not in type[semi:]:
+            encoding = type[semi+1:]
+            type = type[:semi]
+        else:
+            encoding = ''
+        msg = []
+        msg.append('Date: %s'%time.strftime('%a, %d %b %Y %T GMT',
+                                            time.gmtime(time.time())))
+        msg.append('Content-type: %s' % type)
+        if encoding == 'base64':
+            import base64
+            data = base64.decodestring(data)
+        else:
+            data = unquote(data)
+        msg.append('Content-Length: %d' % len(data))
+        msg.append('')
+        msg.append(data)
+        msg = '\n'.join(msg)
+        f = StringIO(msg)
+        headers = mimetools.Message(f, 0)
+        #f.fileno = None     # needed for addinfourl
+        return addinfourl(f, headers, url)
+
+
+class FancyURLopener(URLopener):
+    """Derived class with handlers for errors we can handle (perhaps)."""
+
+    def __init__(self, *args, **kwargs):
+        URLopener.__init__(self, *args, **kwargs)
+        self.auth_cache = {}
+        self.tries = 0
+        self.maxtries = 10
+
+    def http_error_default(self, url, fp, errcode, errmsg, headers):
+        """Default error handling -- don't raise an exception."""
+        return addinfourl(fp, headers, "http:" + url)
+
+    def http_error_302(self, url, fp, errcode, errmsg, headers, data=None):
+        """Error 302 -- relocated (temporarily)."""
+        self.tries += 1
+        if self.maxtries and self.tries >= self.maxtries:
+            if hasattr(self, "http_error_500"):
+                meth = self.http_error_500
+            else:
+                meth = self.http_error_default
+            self.tries = 0
+            return meth(url, fp, 500,
+                        "Internal Server Error: Redirect Recursion", headers)
+        result = self.redirect_internal(url, fp, errcode, errmsg, headers,
+                                        data)
+        self.tries = 0
+        return result
+
+    def redirect_internal(self, url, fp, errcode, errmsg, headers, data):
+        if 'location' in headers:
+            newurl = headers['location']
+        elif 'uri' in headers:
+            newurl = headers['uri']
+        else:
+            return
+        void = fp.read()
+        fp.close()
+        # In case the server sent a relative URL, join with original:
+        newurl = basejoin(self.type + ":" + url, newurl)
+        return self.open(newurl)
+
+    def http_error_301(self, url, fp, errcode, errmsg, headers, data=None):
+        """Error 301 -- also relocated (permanently)."""
+        return self.http_error_302(url, fp, errcode, errmsg, headers, data)
+
+    def http_error_303(self, url, fp, errcode, errmsg, headers, data=None):
+        """Error 303 -- also relocated (essentially identical to 302)."""
+        return self.http_error_302(url, fp, errcode, errmsg, headers, data)
+
+    def http_error_307(self, url, fp, errcode, errmsg, headers, data=None):
+        """Error 307 -- relocated, but turn POST into error."""
+        if data is None:
+            return self.http_error_302(url, fp, errcode, errmsg, headers, data)
+        else:
+            return self.http_error_default(url, fp, errcode, errmsg, headers)
+
+    def http_error_401(self, url, fp, errcode, errmsg, headers, data=None):
+        """Error 401 -- authentication required.
+        This function supports Basic authentication only."""
+        if not 'www-authenticate' in headers:
+            URLopener.http_error_default(self, url, fp,
+                                         errcode, errmsg, headers)
+        stuff = headers['www-authenticate']
+        import re
+        match = re.match('[ \t]*([^ \t]+)[ \t]+realm="([^"]*)"', stuff)
+        if not match:
+            URLopener.http_error_default(self, url, fp,
+                                         errcode, errmsg, headers)
+        scheme, realm = match.groups()
+        if scheme.lower() != 'basic':
+            URLopener.http_error_default(self, url, fp,
+                                         errcode, errmsg, headers)
+        name = 'retry_' + self.type + '_basic_auth'
+        if data is None:
+            return getattr(self,name)(url, realm)
+        else:
+            return getattr(self,name)(url, realm, data)
+
+    def http_error_407(self, url, fp, errcode, errmsg, headers, data=None):
+        """Error 407 -- proxy authentication required.
+        This function supports Basic authentication only."""
+        if not 'proxy-authenticate' in headers:
+            URLopener.http_error_default(self, url, fp,
+                                         errcode, errmsg, headers)
+        stuff = headers['proxy-authenticate']
+        import re
+        match = re.match('[ \t]*([^ \t]+)[ \t]+realm="([^"]*)"', stuff)
+        if not match:
+            URLopener.http_error_default(self, url, fp,
+                                         errcode, errmsg, headers)
+        scheme, realm = match.groups()
+        if scheme.lower() != 'basic':
+            URLopener.http_error_default(self, url, fp,
+                                         errcode, errmsg, headers)
+        name = 'retry_proxy_' + self.type + '_basic_auth'
+        if data is None:
+            return getattr(self,name)(url, realm)
+        else:
+            return getattr(self,name)(url, realm, data)
+
+    def retry_proxy_http_basic_auth(self, url, realm, data=None):
+        host, selector = splithost(url)
+        newurl = 'http://' + host + selector
+        proxy = self.proxies['http']
+        urltype, proxyhost = splittype(proxy)
+        proxyhost, proxyselector = splithost(proxyhost)
+        i = proxyhost.find('@') + 1
+        proxyhost = proxyhost[i:]
+        user, passwd = self.get_user_passwd(proxyhost, realm, i)
+        if not (user or passwd): return None
+        proxyhost = quote(user, safe='') + ':' + quote(passwd, safe='') + '@' + proxyhost
+        self.proxies['http'] = 'http://' + proxyhost + proxyselector
+        if data is None:
+            return self.open(newurl)
+        else:
+            return self.open(newurl, data)
+
+    def retry_proxy_https_basic_auth(self, url, realm, data=None):
+        host, selector = splithost(url)
+        newurl = 'https://' + host + selector
+        proxy = self.proxies['https']
+        urltype, proxyhost = splittype(proxy)
+        proxyhost, proxyselector = splithost(proxyhost)
+        i = proxyhost.find('@') + 1
+        proxyhost = proxyhost[i:]
+        user, passwd = self.get_user_passwd(proxyhost, realm, i)
+        if not (user or passwd): return None
+        proxyhost = quote(user, safe='') + ':' + quote(passwd, safe='') + '@' + proxyhost
+        self.proxies['https'] = 'https://' + proxyhost + proxyselector
+        if data is None:
+            return self.open(newurl)
+        else:
+            return self.open(newurl, data)
+
+    def retry_http_basic_auth(self, url, realm, data=None):
+        host, selector = splithost(url)
+        i = host.find('@') + 1
+        host = host[i:]
+        user, passwd = self.get_user_passwd(host, realm, i)
+        if not (user or passwd): return None
+        host = quote(user, safe='') + ':' + quote(passwd, safe='') + '@' + host
+        newurl = 'http://' + host + selector
+        if data is None:
+            return self.open(newurl)
+        else:
+            return self.open(newurl, data)
+
+    def retry_https_basic_auth(self, url, realm, data=None):
+        host, selector = splithost(url)
+        i = host.find('@') + 1
+        host = host[i:]
+        user, passwd = self.get_user_passwd(host, realm, i)
+        if not (user or passwd): return None
+        host = quote(user, safe='') + ':' + quote(passwd, safe='') + '@' + host
+        newurl = 'https://' + host + selector
+        if data is None:
+            return self.open(newurl)
+        else:
+            return self.open(newurl, data)
+
+    def get_user_passwd(self, host, realm, clear_cache = 0):
+        key = realm + '@' + host.lower()
+        if key in self.auth_cache:
+            if clear_cache:
+                del self.auth_cache[key]
+            else:
+                return self.auth_cache[key]
+        user, passwd = self.prompt_user_passwd(host, realm)
+        if user or passwd: self.auth_cache[key] = (user, passwd)
+        return user, passwd
+
+    def prompt_user_passwd(self, host, realm):
+        """Override this in a GUI environment!"""
+        import getpass
+        try:
+            user = raw_input("Enter username for %s at %s: " % (realm,
+                                                                host))
+            passwd = getpass.getpass("Enter password for %s in %s at %s: " %
+                (user, realm, host))
+            return user, passwd
+        except KeyboardInterrupt:
+            print
+            return None, None
+
+
+# Utility functions
+
+_localhost = None
+def localhost():
+    """Return the IP address of the magic hostname 'localhost'."""
+    global _localhost
+    if _localhost is None:
+        _localhost = socket.gethostbyname('localhost')
+    return _localhost
+
+_thishost = None
+def thishost():
+    """Return the IP address of the current host."""
+    global _thishost
+    if _thishost is None:
+        _thishost = socket.gethostbyname(socket.gethostname())
+    return _thishost
+
+_ftperrors = None
+def ftperrors():
+    """Return the set of errors raised by the FTP class."""
+    global _ftperrors
+    if _ftperrors is None:
+        import ftplib
+        _ftperrors = ftplib.all_errors
+    return _ftperrors
+
+_noheaders = None
+def noheaders():
+    """Return an empty mimetools.Message object."""
+    global _noheaders
+    if _noheaders is None:
+        import mimetools
+        try:
+            from cStringIO import StringIO
+        except ImportError:
+            from StringIO import StringIO
+        _noheaders = mimetools.Message(StringIO(), 0)
+        _noheaders.fp.close()   # Recycle file descriptor
+    return _noheaders
+
+
+# Utility classes
+
+class ftpwrapper:
+    """Class used by open_ftp() for cache of open FTP connections."""
+
+    def __init__(self, user, passwd, host, port, dirs):
+        self.user = user
+        self.passwd = passwd
+        self.host = host
+        self.port = port
+        self.dirs = dirs
+        self.init()
+
+    def init(self):
+        import ftplib
+        self.busy = 0
+        self.ftp = ftplib.FTP()
+        self.ftp.connect(self.host, self.port)
+        self.ftp.login(self.user, self.passwd)
+        for dir in self.dirs:
+            self.ftp.cwd(dir)
+
+    def retrfile(self, file, type):
+        import ftplib
+        self.endtransfer()
+        if type in ('d', 'D'): cmd = 'TYPE A'; isdir = 1
+        else: cmd = 'TYPE ' + type; isdir = 0
+        try:
+            self.ftp.voidcmd(cmd)
+        except ftplib.all_errors:
+            self.init()
+            self.ftp.voidcmd(cmd)
+        conn = None
+        if file and not isdir:
+            # Try to retrieve as a file
+            try:
+                cmd = 'RETR ' + file
+                conn = self.ftp.ntransfercmd(cmd)
+            except ftplib.error_perm, reason:
+                if str(reason)[:3] != '550':
+                    raise IOError, ('ftp error', reason), sys.exc_info()[2]
+        if not conn:
+            # Set transfer mode to ASCII!
+            self.ftp.voidcmd('TYPE A')
+            # Try a directory listing
+            if file: cmd = 'LIST ' + file
+            else: cmd = 'LIST'
+            conn = self.ftp.ntransfercmd(cmd)
+        self.busy = 1
+        # Pass back both a suitably decorated object and a retrieval length
+        return (addclosehook(conn[0].makefile('rb'),
+                             self.endtransfer), conn[1])
+    def endtransfer(self):
+        if not self.busy:
+            return
+        self.busy = 0
+        try:
+            self.ftp.voidresp()
+        except ftperrors():
+            pass
+
+    def close(self):
+        self.endtransfer()
+        try:
+            self.ftp.close()
+        except ftperrors():
+            pass
+
+class addbase:
+    """Base class for addinfo and addclosehook."""
+
+    def __init__(self, fp):
+        self.fp = fp
+        self.read = self.fp.read
+        self.readline = self.fp.readline
+        if hasattr(self.fp, "readlines"): self.readlines = self.fp.readlines
+        if hasattr(self.fp, "fileno"):
+            self.fileno = self.fp.fileno
+        else:
+            self.fileno = lambda: None
+        if hasattr(self.fp, "__iter__"):
+            self.__iter__ = self.fp.__iter__
+            if hasattr(self.fp, "next"):
+                self.next = self.fp.next
+
+    def __repr__(self):
+        return '<%s at %r whose fp = %r>' % (self.__class__.__name__,
+                                             id(self), self.fp)
+
+    def close(self):
+        self.read = None
+        self.readline = None
+        self.readlines = None
+        self.fileno = None
+        if self.fp: self.fp.close()
+        self.fp = None
+
+class addclosehook(addbase):
+    """Class to add a close hook to an open file."""
+
+    def __init__(self, fp, closehook, *hookargs):
+        addbase.__init__(self, fp)
+        self.closehook = closehook
+        self.hookargs = hookargs
+
+    def close(self):
+        addbase.close(self)
+        if self.closehook:
+            self.closehook(*self.hookargs)
+            self.closehook = None
+            self.hookargs = None
+
+class addinfo(addbase):
+    """class to add an info() method to an open file."""
+
+    def __init__(self, fp, headers):
+        addbase.__init__(self, fp)
+        self.headers = headers
+
+    def info(self):
+        return self.headers
+
+class addinfourl(addbase):
+    """class to add info() and geturl() methods to an open file."""
+
+    def __init__(self, fp, headers, url):
+        addbase.__init__(self, fp)
+        self.headers = headers
+        self.url = url
+
+    def info(self):
+        return self.headers
+
+    def geturl(self):
+        return self.url
+
+
+# Utilities to parse URLs (most of these return None for missing parts):
+# unwrap('<URL:type://host/path>') --> 'type://host/path'
+# splittype('type:opaquestring') --> 'type', 'opaquestring'
+# splithost('//host[:port]/path') --> 'host[:port]', '/path'
+# splituser('user[:passwd]@host[:port]') --> 'user[:passwd]', 'host[:port]'
+# splitpasswd('user:passwd') -> 'user', 'passwd'
+# splitport('host:port') --> 'host', 'port'
+# splitquery('/path?query') --> '/path', 'query'
+# splittag('/path#tag') --> '/path', 'tag'
+# splitattr('/path;attr1=value1;attr2=value2;...') ->
+#   '/path', ['attr1=value1', 'attr2=value2', ...]
+# splitvalue('attr=value') --> 'attr', 'value'
+# splitgophertype('/Xselector') --> 'X', 'selector'
+# unquote('abc%20def') -> 'abc def'
+# quote('abc def') -> 'abc%20def')
+
+try:
+    unicode
+except NameError:
+    def _is_unicode(x):
+        return 0
+else:
+    def _is_unicode(x):
+        return isinstance(x, unicode)
+
+def toBytes(url):
+    """toBytes(u"URL") --> 'URL'."""
+    # Most URL schemes require ASCII. If that changes, the conversion
+    # can be relaxed
+    if _is_unicode(url):
+        try:
+            url = url.encode("ASCII")
+        except UnicodeError:
+            raise UnicodeError("URL " + repr(url) +
+                               " contains non-ASCII characters")
+    return url
+
+def unwrap(url):
+    """unwrap('<URL:type://host/path>') --> 'type://host/path'."""
+    url = url.strip()
+    if url[:1] == '<' and url[-1:] == '>':
+        url = url[1:-1].strip()
+    if url[:4] == 'URL:': url = url[4:].strip()
+    return url
+
+_typeprog = None
+def splittype(url):
+    """splittype('type:opaquestring') --> 'type', 'opaquestring'."""
+    global _typeprog
+    if _typeprog is None:
+        import re
+        _typeprog = re.compile('^([^/:]+):')
+
+    match = _typeprog.match(url)
+    if match:
+        scheme = match.group(1)
+        return scheme.lower(), url[len(scheme) + 1:]
+    return None, url
+
+_hostprog = None
+def splithost(url):
+    """splithost('//host[:port]/path') --> 'host[:port]', '/path'."""
+    global _hostprog
+    if _hostprog is None:
+        import re
+        _hostprog = re.compile('^//([^/?]*)(.*)$')
+
+    match = _hostprog.match(url)
+    if match: return match.group(1, 2)
+    return None, url
+
+_userprog = None
+def splituser(host):
+    """splituser('user[:passwd]@host[:port]') --> 'user[:passwd]', 'host[:port]'."""
+    global _userprog
+    if _userprog is None:
+        import re
+        _userprog = re.compile('^(.*)@(.*)$')
+
+    match = _userprog.match(host)
+    if match: return map(unquote, match.group(1, 2))
+    return None, host
+
+_passwdprog = None
+def splitpasswd(user):
+    """splitpasswd('user:passwd') -> 'user', 'passwd'."""
+    global _passwdprog
+    if _passwdprog is None:
+        import re
+        _passwdprog = re.compile('^([^:]*):(.*)$')
+
+    match = _passwdprog.match(user)
+    if match: return match.group(1, 2)
+    return user, None
+
+# splittag('/path#tag') --> '/path', 'tag'
+_portprog = None
+def splitport(host):
+    """splitport('host:port') --> 'host', 'port'."""
+    global _portprog
+    if _portprog is None:
+        import re
+        _portprog = re.compile('^(.*):([0-9]+)$')
+
+    match = _portprog.match(host)
+    if match: return match.group(1, 2)
+    return host, None
+
+_nportprog = None
+def splitnport(host, defport=-1):
+    """Split host and port, returning numeric port.
+    Return given default port if no ':' found; defaults to -1.
+    Return numerical port if a valid number are found after ':'.
+    Return None if ':' but not a valid number."""
+    global _nportprog
+    if _nportprog is None:
+        import re
+        _nportprog = re.compile('^(.*):(.*)$')
+
+    match = _nportprog.match(host)
+    if match:
+        host, port = match.group(1, 2)
+        try:
+            if not port: raise ValueError, "no digits"
+            nport = int(port)
+        except ValueError:
+            nport = None
+        return host, nport
+    return host, defport
+
+_queryprog = None
+def splitquery(url):
+    """splitquery('/path?query') --> '/path', 'query'."""
+    global _queryprog
+    if _queryprog is None:
+        import re
+        _queryprog = re.compile('^(.*)\?([^?]*)$')
+
+    match = _queryprog.match(url)
+    if match: return match.group(1, 2)
+    return url, None
+
+_tagprog = None
+def splittag(url):
+    """splittag('/path#tag') --> '/path', 'tag'."""
+    global _tagprog
+    if _tagprog is None:
+        import re
+        _tagprog = re.compile('^(.*)#([^#]*)$')
+
+    match = _tagprog.match(url)
+    if match: return match.group(1, 2)
+    return url, None
+
+def splitattr(url):
+    """splitattr('/path;attr1=value1;attr2=value2;...') ->
+        '/path', ['attr1=value1', 'attr2=value2', ...]."""
+    words = url.split(';')
+    return words[0], words[1:]
+
+_valueprog = None
+def splitvalue(attr):
+    """splitvalue('attr=value') --> 'attr', 'value'."""
+    global _valueprog
+    if _valueprog is None:
+        import re
+        _valueprog = re.compile('^([^=]*)=(.*)$')
+
+    match = _valueprog.match(attr)
+    if match: return match.group(1, 2)
+    return attr, None
+
+def splitgophertype(selector):
+    """splitgophertype('/Xselector') --> 'X', 'selector'."""
+    if selector[:1] == '/' and selector[1:2]:
+        return selector[1], selector[2:]
+    return None, selector
+
+_hextochr = dict(('%02x' % i, chr(i)) for i in range(256))
+_hextochr.update(('%02X' % i, chr(i)) for i in range(256))
+
+def unquote(s):
+    """unquote('abc%20def') -> 'abc def'."""
+    res = s.split('%')
+    for i in xrange(1, len(res)):
+        item = res[i]
+        try:
+            res[i] = _hextochr[item[:2]] + item[2:]
+        except KeyError:
+            res[i] = '%' + item
+        except UnicodeDecodeError:
+            res[i] = unichr(int(item[:2], 16)) + item[2:]
+    return "".join(res)
+
+def unquote_plus(s):
+    """unquote('%7e/abc+def') -> '~/abc def'"""
+    s = s.replace('+', ' ')
+    return unquote(s)
+
+always_safe = ('ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+               'abcdefghijklmnopqrstuvwxyz'
+               '0123456789' '_.-')
+_safemaps = {}
+
+def quote(s, safe = '/'):
+    """quote('abc def') -> 'abc%20def'
+
+    Each part of a URL, e.g. the path info, the query, etc., has a
+    different set of reserved characters that must be quoted.
+
+    RFC 2396 Uniform Resource Identifiers (URI): Generic Syntax lists
+    the following reserved characters.
+
+    reserved    = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" |
+                  "$" | ","
+
+    Each of these characters is reserved in some component of a URL,
+    but not necessarily in all of them.
+
+    By default, the quote function is intended for quoting the path
+    section of a URL.  Thus, it will not encode '/'.  This character
+    is reserved, but in typical usage the quote function is being
+    called on a path where the existing slash characters are used as
+    reserved characters.
+    """
+    cachekey = (safe, always_safe)
+    try:
+        safe_map = _safemaps[cachekey]
+    except KeyError:
+        safe += always_safe
+        safe_map = {}
+        for i in range(256):
+            c = chr(i)
+            safe_map[c] = (c in safe) and c or ('%%%02X' % i)
+        _safemaps[cachekey] = safe_map
+    res = map(safe_map.__getitem__, s)
+    return ''.join(res)
+
+def quote_plus(s, safe = ''):
+    """Quote the query fragment of a URL; replacing ' ' with '+'"""
+    if ' ' in s:
+        s = quote(s, safe + ' ')
+        return s.replace(' ', '+')
+    return quote(s, safe)
+
+def urlencode(query,doseq=0):
+    """Encode a sequence of two-element tuples or dictionary into a URL query string.
+
+    If any values in the query arg are sequences and doseq is true, each
+    sequence element is converted to a separate parameter.
+
+    If the query arg is a sequence of two-element tuples, the order of the
+    parameters in the output will match the order of parameters in the
+    input.
+    """
+
+    if hasattr(query,"items"):
+        # mapping objects
+        query = query.items()
+    else:
+        # it's a bother at times that strings and string-like objects are
+        # sequences...
+        try:
+            # non-sequence items should not work with len()
+            # non-empty strings will fail this
+            if len(query) and not isinstance(query[0], tuple):
+                raise TypeError
+            # zero-length sequences of all types will get here and succeed,
+            # but that's a minor nit - since the original implementation
+            # allowed empty dicts that type of behavior probably should be
+            # preserved for consistency
+        except TypeError:
+            ty,va,tb = sys.exc_info()
+            raise TypeError, "not a valid non-string sequence or mapping object", tb
+
+    l = []
+    if not doseq:
+        # preserve old behavior
+        for k, v in query:
+            k = quote_plus(str(k))
+            v = quote_plus(str(v))
+            l.append(k + '=' + v)
+    else:
+        for k, v in query:
+            k = quote_plus(str(k))
+            if isinstance(v, str):
+                v = quote_plus(v)
+                l.append(k + '=' + v)
+            elif _is_unicode(v):
+                # is there a reasonable way to convert to ASCII?
+                # encode generates a string, but "replace" or "ignore"
+                # lose information and "strict" can raise UnicodeError
+                v = quote_plus(v.encode("ASCII","replace"))
+                l.append(k + '=' + v)
+            else:
+                try:
+                    # is this a sufficient test for sequence-ness?
+                    x = len(v)
+                except TypeError:
+                    # not a sequence
+                    v = quote_plus(str(v))
+                    l.append(k + '=' + v)
+                else:
+                    # loop over the sequence
+                    for elt in v:
+                        l.append(k + '=' + quote_plus(str(elt)))
+    return '&'.join(l)
+
+# Proxy handling
+def getproxies_environment():
+    """Return a dictionary of scheme -> proxy server URL mappings.
+
+    Scan the environment for variables named <scheme>_proxy;
+    this seems to be the standard convention.  If you need a
+    different way, you can pass a proxies dictionary to the
+    [Fancy]URLopener constructor.
+
+    """
+    proxies = {}
+    for name, value in os.environ.items():
+        name = name.lower()
+        if value and name[-6:] == '_proxy':
+            proxies[name[:-6]] = value
+    return proxies
+
+if sys.platform == 'darwin':
+    def getproxies_internetconfig():
+        """Return a dictionary of scheme -> proxy server URL mappings.
+
+        By convention the mac uses Internet Config to store
+        proxies.  An HTTP proxy, for instance, is stored under
+        the HttpProxy key.
+
+        """
+        try:
+            import ic
+        except ImportError:
+            return {}
+
+        try:
+            config = ic.IC()
+        except ic.error:
+            return {}
+        proxies = {}
+        # HTTP:
+        if 'UseHTTPProxy' in config and config['UseHTTPProxy']:
+            try:
+                value = config['HTTPProxyHost']
+            except ic.error:
+                pass
+            else:
+                proxies['http'] = 'http://%s' % value
+        # FTP: XXXX To be done.
+        # Gopher: XXXX To be done.
+        return proxies
+
+    def proxy_bypass(x):
+        return 0
+
+    def getproxies():
+        return getproxies_environment() or getproxies_internetconfig()
+
+elif os.name == 'nt':
+    def getproxies_registry():
+        """Return a dictionary of scheme -> proxy server URL mappings.
+
+        Win32 uses the registry to store proxies.
+
+        """
+        proxies = {}
+        try:
+            import _winreg
+        except ImportError:
+            # Std module, so should be around - but you never know!
+            return proxies
+        try:
+            internetSettings = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER,
+                r'Software\Microsoft\Windows\CurrentVersion\Internet Settings')
+            proxyEnable = _winreg.QueryValueEx(internetSettings,
+                                               'ProxyEnable')[0]
+            if proxyEnable:
+                # Returned as Unicode but problems if not converted to ASCII
+                proxyServer = str(_winreg.QueryValueEx(internetSettings,
+                                                       'ProxyServer')[0])
+                if '=' in proxyServer:
+                    # Per-protocol settings
+                    for p in proxyServer.split(';'):
+                        protocol, address = p.split('=', 1)
+                        # See if address has a type:// prefix
+                        import re
+                        if not re.match('^([^/:]+)://', address):
+                            address = '%s://%s' % (protocol, address)
+                        proxies[protocol] = address
+                else:
+                    # Use one setting for all protocols
+                    if proxyServer[:5] == 'http:':
+                        proxies['http'] = proxyServer
+                    else:
+                        proxies['http'] = 'http://%s' % proxyServer
+                        proxies['ftp'] = 'ftp://%s' % proxyServer
+            internetSettings.Close()
+        except (WindowsError, ValueError, TypeError):
+            # Either registry key not found etc, or the value in an
+            # unexpected format.
+            # proxies already set up to be empty so nothing to do
+            pass
+        return proxies
+
+    def getproxies():
+        """Return a dictionary of scheme -> proxy server URL mappings.
+
+        Returns settings gathered from the environment, if specified,
+        or the registry.
+
+        """
+        return getproxies_environment() or getproxies_registry()
+
+    def proxy_bypass(host):
+        try:
+            import _winreg
+            import re
+        except ImportError:
+            # Std modules, so should be around - but you never know!
+            return 0
+        try:
+            internetSettings = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER,
+                r'Software\Microsoft\Windows\CurrentVersion\Internet Settings')
+            proxyEnable = _winreg.QueryValueEx(internetSettings,
+                                               'ProxyEnable')[0]
+            proxyOverride = str(_winreg.QueryValueEx(internetSettings,
+                                                     'ProxyOverride')[0])
+            # ^^^^ Returned as Unicode but problems if not converted to ASCII
+        except WindowsError:
+            return 0
+        if not proxyEnable or not proxyOverride:
+            return 0
+        # try to make a host list from name and IP address.
+        rawHost, port = splitport(host)
+        host = [rawHost]
+        try:
+            addr = socket.gethostbyname(rawHost)
+            if addr != rawHost:
+                host.append(addr)
+        except socket.error:
+            pass
+        try:
+            fqdn = socket.getfqdn(rawHost)
+            if fqdn != rawHost:
+                host.append(fqdn)
+        except socket.error:
+            pass
+        # make a check value list from the registry entry: replace the
+        # '<local>' string by the localhost entry and the corresponding
+        # canonical entry.
+        proxyOverride = proxyOverride.split(';')
+        i = 0
+        while i < len(proxyOverride):
+            if proxyOverride[i] == '<local>':
+                proxyOverride[i:i+1] = ['localhost',
+                                        '127.0.0.1',
+                                        socket.gethostname(),
+                                        socket.gethostbyname(
+                                            socket.gethostname())]
+            i += 1
+        # print proxyOverride
+        # now check if we match one of the registry values.
+        for test in proxyOverride:
+            test = test.replace(".", r"\.")     # mask dots
+            test = test.replace("*", r".*")     # change glob sequence
+            test = test.replace("?", r".")      # change glob char
+            for val in host:
+                # print "%s <--> %s" %( test, val )
+                if re.match(test, val, re.I):
+                    return 1
+        return 0
+
+else:
+    # By default use environment variables
+    getproxies = getproxies_environment
+
+    def proxy_bypass(host):
+        return 0
+
+# Test and time quote() and unquote()
+def test1():
+    s = ''
+    for i in range(256): s = s + chr(i)
+    s = s*4
+    t0 = time.time()
+    qs = quote(s)
+    uqs = unquote(qs)
+    t1 = time.time()
+    if uqs != s:
+        print 'Wrong!'
+    print repr(s)
+    print repr(qs)
+    print repr(uqs)
+    print round(t1 - t0, 3), 'sec'
+
+
+def reporthook(blocknum, blocksize, totalsize):
+    # Report during remote transfers
+    print "Block number: %d, Block size: %d, Total size: %d" % (
+        blocknum, blocksize, totalsize)
+
+# Test program
+def test(args=[]):
+    if not args:
+        args = [
+            '/etc/passwd',
+            'file:/etc/passwd',
+            'file://localhost/etc/passwd',
+            'ftp://ftp.gnu.org/pub/README',
+##          'gopher://gopher.micro.umn.edu/1/',
+            'http://www.python.org/index.html',
+            ]
+        if hasattr(URLopener, "open_https"):
+            args.append('https://synergy.as.cmu.edu/~geek/')
+    try:
+        for url in args:
+            print '-'*10, url, '-'*10
+            fn, h = urlretrieve(url, None, reporthook)
+            print fn
+            if h:
+                print '======'
+                for k in h.keys(): print k + ':', h[k]
+                print '======'
+            fp = open(fn, 'rb')
+            data = fp.read()
+            del fp
+            if '\r' in data:
+                table = string.maketrans("", "")
+                data = data.translate(table, "\r")
+            print data
+            fn, h = None, None
+        print '-'*40
+    finally:
+        urlcleanup()
+
+def main():
+    import getopt, sys
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], "th")
+    except getopt.error, msg:
+        print msg
+        print "Use -h for help"
+        return
+    t = 0
+    for o, a in opts:
+        if o == '-t':
+            t = t + 1
+        if o == '-h':
+            print "Usage: python urllib.py [-t] [url ...]"
+            print "-t runs self-test;",
+            print "otherwise, contents of urls are printed"
+            return
+    if t:
+        if t > 1:
+            test1()
+        test(args)
+    else:
+        if not args:
+            print "Use -h for help"
+        for url in args:
+            print urlopen(url).read(),
+
+# Run test program when run as a script
+if __name__ == '__main__':
+    main()

Added: vendor/Python/current/Lib/urllib2.py
===================================================================
--- vendor/Python/current/Lib/urllib2.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/urllib2.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1353 @@
+"""An extensible library for opening URLs using a variety of protocols
+
+The simplest way to use this module is to call the urlopen function,
+which accepts a string containing a URL or a Request object (described
+below).  It opens the URL and returns the results as file-like
+object; the returned object has some extra methods described below.
+
+The OpenerDirector manages a collection of Handler objects that do
+all the actual work.  Each Handler implements a particular protocol or
+option.  The OpenerDirector is a composite object that invokes the
+Handlers needed to open the requested URL.  For example, the
+HTTPHandler performs HTTP GET and POST requests and deals with
+non-error returns.  The HTTPRedirectHandler automatically deals with
+HTTP 301, 302, 303 and 307 redirect errors, and the HTTPDigestAuthHandler
+deals with digest authentication.
+
+urlopen(url, data=None) -- basic usage is the same as original
+urllib.  pass the url and optionally data to post to an HTTP URL, and
+get a file-like object back.  One difference is that you can also pass
+a Request instance instead of URL.  Raises a URLError (subclass of
+IOError); for HTTP errors, raises an HTTPError, which can also be
+treated as a valid response.
+
+build_opener -- function that creates a new OpenerDirector instance.
+will install the default handlers.  accepts one or more Handlers as
+arguments, either instances or Handler classes that it will
+instantiate.  if one of the argument is a subclass of the default
+handler, the argument will be installed instead of the default.
+
+install_opener -- installs a new opener as the default opener.
+
+objects of interest:
+OpenerDirector --
+
+Request -- an object that encapsulates the state of a request.  the
+state can be a simple as the URL.  it can also include extra HTTP
+headers, e.g. a User-Agent.
+
+BaseHandler --
+
+exceptions:
+URLError-- a subclass of IOError, individual protocols have their own
+specific subclass
+
+HTTPError-- also a valid HTTP response, so you can treat an HTTP error
+as an exceptional event or valid response
+
+internals:
+BaseHandler and parent
+_call_chain conventions
+
+Example usage:
+
+import urllib2
+
+# set up authentication info
+authinfo = urllib2.HTTPBasicAuthHandler()
+authinfo.add_password('realm', 'host', 'username', 'password')
+
+proxy_support = urllib2.ProxyHandler({"http" : "http://ahad-haam:3128"})
+
+# build a new opener that adds authentication and caching FTP handlers
+opener = urllib2.build_opener(proxy_support, authinfo, urllib2.CacheFTPHandler)
+
+# install it
+urllib2.install_opener(opener)
+
+f = urllib2.urlopen('http://www.python.org/')
+
+
+"""
+
+# XXX issues:
+# If an authentication error handler that tries to perform
+# authentication for some reason but fails, how should the error be
+# signalled?  The client needs to know the HTTP error code.  But if
+# the handler knows that the problem was, e.g., that it didn't know
+# that hash algo that requested in the challenge, it would be good to
+# pass that information along to the client, too.
+# ftp errors aren't handled cleanly
+# check digest against correct (i.e. non-apache) implementation
+
+# Possible extensions:
+# complex proxies  XXX not sure what exactly was meant by this
+# abstract factory for opener
+
+import base64
+import hashlib
+import httplib
+import mimetools
+import os
+import posixpath
+import random
+import re
+import socket
+import sys
+import time
+import urlparse
+import bisect
+
+try:
+    from cStringIO import StringIO
+except ImportError:
+    from StringIO import StringIO
+
+from urllib import (unwrap, unquote, splittype, splithost, quote,
+     addinfourl, splitport, splitgophertype, splitquery,
+     splitattr, ftpwrapper, noheaders, splituser, splitpasswd, splitvalue)
+
+# support for FileHandler, proxies via environment variables
+from urllib import localhost, url2pathname, getproxies
+
+# used in User-Agent header sent
+__version__ = sys.version[:3]
+
+_opener = None
+def urlopen(url, data=None):
+    global _opener
+    if _opener is None:
+        _opener = build_opener()
+    return _opener.open(url, data)
+
+def install_opener(opener):
+    global _opener
+    _opener = opener
+
+# do these error classes make sense?
+# make sure all of the IOError stuff is overridden.  we just want to be
+# subtypes.
+
+class URLError(IOError):
+    # URLError is a sub-type of IOError, but it doesn't share any of
+    # the implementation.  need to override __init__ and __str__.
+    # It sets self.args for compatibility with other EnvironmentError
+    # subclasses, but args doesn't have the typical format with errno in
+    # slot 0 and strerror in slot 1.  This may be better than nothing.
+    def __init__(self, reason):
+        self.args = reason,
+        self.reason = reason
+
+    def __str__(self):
+        return '<urlopen error %s>' % self.reason
+
+class HTTPError(URLError, addinfourl):
+    """Raised when HTTP error occurs, but also acts like non-error return"""
+    __super_init = addinfourl.__init__
+
+    def __init__(self, url, code, msg, hdrs, fp):
+        self.code = code
+        self.msg = msg
+        self.hdrs = hdrs
+        self.fp = fp
+        self.filename = url
+        # The addinfourl classes depend on fp being a valid file
+        # object.  In some cases, the HTTPError may not have a valid
+        # file object.  If this happens, the simplest workaround is to
+        # not initialize the base classes.
+        if fp is not None:
+            self.__super_init(fp, hdrs, url)
+
+    def __str__(self):
+        return 'HTTP Error %s: %s' % (self.code, self.msg)
+
+class GopherError(URLError):
+    pass
+
+# copied from cookielib.py
+_cut_port_re = re.compile(r":\d+$")
+def request_host(request):
+    """Return request-host, as defined by RFC 2965.
+
+    Variation from RFC: returned value is lowercased, for convenient
+    comparison.
+
+    """
+    url = request.get_full_url()
+    host = urlparse.urlparse(url)[1]
+    if host == "":
+        host = request.get_header("Host", "")
+
+    # remove port, if present
+    host = _cut_port_re.sub("", host, 1)
+    return host.lower()
+
+class Request:
+
+    def __init__(self, url, data=None, headers={},
+                 origin_req_host=None, unverifiable=False):
+        # unwrap('<URL:type://host/path>') --> 'type://host/path'
+        self.__original = unwrap(url)
+        self.type = None
+        # self.__r_type is what's left after doing the splittype
+        self.host = None
+        self.port = None
+        self.data = data
+        self.headers = {}
+        for key, value in headers.items():
+            self.add_header(key, value)
+        self.unredirected_hdrs = {}
+        if origin_req_host is None:
+            origin_req_host = request_host(self)
+        self.origin_req_host = origin_req_host
+        self.unverifiable = unverifiable
+
+    def __getattr__(self, attr):
+        # XXX this is a fallback mechanism to guard against these
+        # methods getting called in a non-standard order.  this may be
+        # too complicated and/or unnecessary.
+        # XXX should the __r_XXX attributes be public?
+        if attr[:12] == '_Request__r_':
+            name = attr[12:]
+            if hasattr(Request, 'get_' + name):
+                getattr(self, 'get_' + name)()
+                return getattr(self, attr)
+        raise AttributeError, attr
+
+    def get_method(self):
+        if self.has_data():
+            return "POST"
+        else:
+            return "GET"
+
+    # XXX these helper methods are lame
+
+    def add_data(self, data):
+        self.data = data
+
+    def has_data(self):
+        return self.data is not None
+
+    def get_data(self):
+        return self.data
+
+    def get_full_url(self):
+        return self.__original
+
+    def get_type(self):
+        if self.type is None:
+            self.type, self.__r_type = splittype(self.__original)
+            if self.type is None:
+                raise ValueError, "unknown url type: %s" % self.__original
+        return self.type
+
+    def get_host(self):
+        if self.host is None:
+            self.host, self.__r_host = splithost(self.__r_type)
+            if self.host:
+                self.host = unquote(self.host)
+        return self.host
+
+    def get_selector(self):
+        return self.__r_host
+
+    def set_proxy(self, host, type):
+        self.host, self.type = host, type
+        self.__r_host = self.__original
+
+    def get_origin_req_host(self):
+        return self.origin_req_host
+
+    def is_unverifiable(self):
+        return self.unverifiable
+
+    def add_header(self, key, val):
+        # useful for something like authentication
+        self.headers[key.capitalize()] = val
+
+    def add_unredirected_header(self, key, val):
+        # will not be added to a redirected request
+        self.unredirected_hdrs[key.capitalize()] = val
+
+    def has_header(self, header_name):
+        return (header_name in self.headers or
+                header_name in self.unredirected_hdrs)
+
+    def get_header(self, header_name, default=None):
+        return self.headers.get(
+            header_name,
+            self.unredirected_hdrs.get(header_name, default))
+
+    def header_items(self):
+        hdrs = self.unredirected_hdrs.copy()
+        hdrs.update(self.headers)
+        return hdrs.items()
+
+class OpenerDirector:
+    def __init__(self):
+        client_version = "Python-urllib/%s" % __version__
+        self.addheaders = [('User-agent', client_version)]
+        # manage the individual handlers
+        self.handlers = []
+        self.handle_open = {}
+        self.handle_error = {}
+        self.process_response = {}
+        self.process_request = {}
+
+    def add_handler(self, handler):
+        added = False
+        for meth in dir(handler):
+            if meth in ["redirect_request", "do_open", "proxy_open"]:
+                # oops, coincidental match
+                continue
+
+            i = meth.find("_")
+            protocol = meth[:i]
+            condition = meth[i+1:]
+
+            if condition.startswith("error"):
+                j = condition.find("_") + i + 1
+                kind = meth[j+1:]
+                try:
+                    kind = int(kind)
+                except ValueError:
+                    pass
+                lookup = self.handle_error.get(protocol, {})
+                self.handle_error[protocol] = lookup
+            elif condition == "open":
+                kind = protocol
+                lookup = self.handle_open
+            elif condition == "response":
+                kind = protocol
+                lookup = self.process_response
+            elif condition == "request":
+                kind = protocol
+                lookup = self.process_request
+            else:
+                continue
+
+            handlers = lookup.setdefault(kind, [])
+            if handlers:
+                bisect.insort(handlers, handler)
+            else:
+                handlers.append(handler)
+            added = True
+
+        if added:
+            # XXX why does self.handlers need to be sorted?
+            bisect.insort(self.handlers, handler)
+            handler.add_parent(self)
+
+    def close(self):
+        # Only exists for backwards compatibility.
+        pass
+
+    def _call_chain(self, chain, kind, meth_name, *args):
+        # Handlers raise an exception if no one else should try to handle
+        # the request, or return None if they can't but another handler
+        # could.  Otherwise, they return the response.
+        handlers = chain.get(kind, ())
+        for handler in handlers:
+            func = getattr(handler, meth_name)
+
+            result = func(*args)
+            if result is not None:
+                return result
+
+    def open(self, fullurl, data=None):
+        # accept a URL or a Request object
+        if isinstance(fullurl, basestring):
+            req = Request(fullurl, data)
+        else:
+            req = fullurl
+            if data is not None:
+                req.add_data(data)
+
+        protocol = req.get_type()
+
+        # pre-process request
+        meth_name = protocol+"_request"
+        for processor in self.process_request.get(protocol, []):
+            meth = getattr(processor, meth_name)
+            req = meth(req)
+
+        response = self._open(req, data)
+
+        # post-process response
+        meth_name = protocol+"_response"
+        for processor in self.process_response.get(protocol, []):
+            meth = getattr(processor, meth_name)
+            response = meth(req, response)
+
+        return response
+
+    def _open(self, req, data=None):
+        result = self._call_chain(self.handle_open, 'default',
+                                  'default_open', req)
+        if result:
+            return result
+
+        protocol = req.get_type()
+        result = self._call_chain(self.handle_open, protocol, protocol +
+                                  '_open', req)
+        if result:
+            return result
+
+        return self._call_chain(self.handle_open, 'unknown',
+                                'unknown_open', req)
+
+    def error(self, proto, *args):
+        if proto in ('http', 'https'):
+            # XXX http[s] protocols are special-cased
+            dict = self.handle_error['http'] # https is not different than http
+            proto = args[2]  # YUCK!
+            meth_name = 'http_error_%s' % proto
+            http_err = 1
+            orig_args = args
+        else:
+            dict = self.handle_error
+            meth_name = proto + '_error'
+            http_err = 0
+        args = (dict, proto, meth_name) + args
+        result = self._call_chain(*args)
+        if result:
+            return result
+
+        if http_err:
+            args = (dict, 'default', 'http_error_default') + orig_args
+            return self._call_chain(*args)
+
+# XXX probably also want an abstract factory that knows when it makes
+# sense to skip a superclass in favor of a subclass and when it might
+# make sense to include both
+
+def build_opener(*handlers):
+    """Create an opener object from a list of handlers.
+
+    The opener will use several default handlers, including support
+    for HTTP and FTP.
+
+    If any of the handlers passed as arguments are subclasses of the
+    default handlers, the default handlers will not be used.
+    """
+    import types
+    def isclass(obj):
+        return isinstance(obj, types.ClassType) or hasattr(obj, "__bases__")
+
+    opener = OpenerDirector()
+    default_classes = [ProxyHandler, UnknownHandler, HTTPHandler,
+                       HTTPDefaultErrorHandler, HTTPRedirectHandler,
+                       FTPHandler, FileHandler, HTTPErrorProcessor]
+    if hasattr(httplib, 'HTTPS'):
+        default_classes.append(HTTPSHandler)
+    skip = []
+    for klass in default_classes:
+        for check in handlers:
+            if isclass(check):
+                if issubclass(check, klass):
+                    skip.append(klass)
+            elif isinstance(check, klass):
+                skip.append(klass)
+    for klass in skip:
+        default_classes.remove(klass)
+
+    for klass in default_classes:
+        opener.add_handler(klass())
+
+    for h in handlers:
+        if isclass(h):
+            h = h()
+        opener.add_handler(h)
+    return opener
+
+class BaseHandler:
+    handler_order = 500
+
+    def add_parent(self, parent):
+        self.parent = parent
+
+    def close(self):
+        # Only exists for backwards compatibility
+        pass
+
+    def __lt__(self, other):
+        if not hasattr(other, "handler_order"):
+            # Try to preserve the old behavior of having custom classes
+            # inserted after default ones (works only for custom user
+            # classes which are not aware of handler_order).
+            return True
+        return self.handler_order < other.handler_order
+
+
+class HTTPErrorProcessor(BaseHandler):
+    """Process HTTP error responses."""
+    handler_order = 1000  # after all other processing
+
+    def http_response(self, request, response):
+        code, msg, hdrs = response.code, response.msg, response.info()
+
+        if code not in (200, 206):
+            response = self.parent.error(
+                'http', request, response, code, msg, hdrs)
+
+        return response
+
+    https_response = http_response
+
+class HTTPDefaultErrorHandler(BaseHandler):
+    def http_error_default(self, req, fp, code, msg, hdrs):
+        raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
+
+class HTTPRedirectHandler(BaseHandler):
+    # maximum number of redirections to any single URL
+    # this is needed because of the state that cookies introduce
+    max_repeats = 4
+    # maximum total number of redirections (regardless of URL) before
+    # assuming we're in a loop
+    max_redirections = 10
+
+    def redirect_request(self, req, fp, code, msg, headers, newurl):
+        """Return a Request or None in response to a redirect.
+
+        This is called by the http_error_30x methods when a
+        redirection response is received.  If a redirection should
+        take place, return a new Request to allow http_error_30x to
+        perform the redirect.  Otherwise, raise HTTPError if no-one
+        else should try to handle this url.  Return None if you can't
+        but another Handler might.
+        """
+        m = req.get_method()
+        if (code in (301, 302, 303, 307) and m in ("GET", "HEAD")
+            or code in (301, 302, 303) and m == "POST"):
+            # Strictly (according to RFC 2616), 301 or 302 in response
+            # to a POST MUST NOT cause a redirection without confirmation
+            # from the user (of urllib2, in this case).  In practice,
+            # essentially all clients do redirect in this case, so we
+            # do the same.
+            # be conciliant with URIs containing a space
+            newurl = newurl.replace(' ', '%20')
+            return Request(newurl,
+                           headers=req.headers,
+                           origin_req_host=req.get_origin_req_host(),
+                           unverifiable=True)
+        else:
+            raise HTTPError(req.get_full_url(), code, msg, headers, fp)
+
+    # Implementation note: To avoid the server sending us into an
+    # infinite loop, the request object needs to track what URLs we
+    # have already seen.  Do this by adding a handler-specific
+    # attribute to the Request object.
+    def http_error_302(self, req, fp, code, msg, headers):
+        # Some servers (incorrectly) return multiple Location headers
+        # (so probably same goes for URI).  Use first header.
+        if 'location' in headers:
+            newurl = headers.getheaders('location')[0]
+        elif 'uri' in headers:
+            newurl = headers.getheaders('uri')[0]
+        else:
+            return
+        newurl = urlparse.urljoin(req.get_full_url(), newurl)
+
+        # XXX Probably want to forget about the state of the current
+        # request, although that might interact poorly with other
+        # handlers that also use handler-specific request attributes
+        new = self.redirect_request(req, fp, code, msg, headers, newurl)
+        if new is None:
+            return
+
+        # loop detection
+        # .redirect_dict has a key url if url was previously visited.
+        if hasattr(req, 'redirect_dict'):
+            visited = new.redirect_dict = req.redirect_dict
+            if (visited.get(newurl, 0) >= self.max_repeats or
+                len(visited) >= self.max_redirections):
+                raise HTTPError(req.get_full_url(), code,
+                                self.inf_msg + msg, headers, fp)
+        else:
+            visited = new.redirect_dict = req.redirect_dict = {}
+        visited[newurl] = visited.get(newurl, 0) + 1
+
+        # Don't close the fp until we are sure that we won't use it
+        # with HTTPError.
+        fp.read()
+        fp.close()
+
+        return self.parent.open(new)
+
+    http_error_301 = http_error_303 = http_error_307 = http_error_302
+
+    inf_msg = "The HTTP server returned a redirect error that would " \
+              "lead to an infinite loop.\n" \
+              "The last 30x error message was:\n"
+
+
+def _parse_proxy(proxy):
+    """Return (scheme, user, password, host/port) given a URL or an authority.
+
+    If a URL is supplied, it must have an authority (host:port) component.
+    According to RFC 3986, having an authority component means the URL must
+    have two slashes after the scheme:
+
+    >>> _parse_proxy('file:/ftp.example.com/')
+    Traceback (most recent call last):
+    ValueError: proxy URL with no authority: 'file:/ftp.example.com/'
+
+    The first three items of the returned tuple may be None.
+
+    Examples of authority parsing:
+
+    >>> _parse_proxy('proxy.example.com')
+    (None, None, None, 'proxy.example.com')
+    >>> _parse_proxy('proxy.example.com:3128')
+    (None, None, None, 'proxy.example.com:3128')
+
+    The authority component may optionally include userinfo (assumed to be
+    username:password):
+
+    >>> _parse_proxy('joe:password at proxy.example.com')
+    (None, 'joe', 'password', 'proxy.example.com')
+    >>> _parse_proxy('joe:password at proxy.example.com:3128')
+    (None, 'joe', 'password', 'proxy.example.com:3128')
+
+    Same examples, but with URLs instead:
+
+    >>> _parse_proxy('http://proxy.example.com/')
+    ('http', None, None, 'proxy.example.com')
+    >>> _parse_proxy('http://proxy.example.com:3128/')
+    ('http', None, None, 'proxy.example.com:3128')
+    >>> _parse_proxy('http://joe:password@proxy.example.com/')
+    ('http', 'joe', 'password', 'proxy.example.com')
+    >>> _parse_proxy('http://joe:password@proxy.example.com:3128')
+    ('http', 'joe', 'password', 'proxy.example.com:3128')
+
+    Everything after the authority is ignored:
+
+    >>> _parse_proxy('ftp://joe:password@proxy.example.com/rubbish:3128')
+    ('ftp', 'joe', 'password', 'proxy.example.com')
+
+    Test for no trailing '/' case:
+
+    >>> _parse_proxy('http://joe:password@proxy.example.com')
+    ('http', 'joe', 'password', 'proxy.example.com')
+
+    """
+    scheme, r_scheme = splittype(proxy)
+    if not r_scheme.startswith("/"):
+        # authority
+        scheme = None
+        authority = proxy
+    else:
+        # URL
+        if not r_scheme.startswith("//"):
+            raise ValueError("proxy URL with no authority: %r" % proxy)
+        # We have an authority, so for RFC 3986-compliant URLs (by ss 3.
+        # and 3.3.), path is empty or starts with '/'
+        end = r_scheme.find("/", 2)
+        if end == -1:
+            end = None
+        authority = r_scheme[2:end]
+    userinfo, hostport = splituser(authority)
+    if userinfo is not None:
+        user, password = splitpasswd(userinfo)
+    else:
+        user = password = None
+    return scheme, user, password, hostport
+
+class ProxyHandler(BaseHandler):
+    # Proxies must be in front
+    handler_order = 100
+
+    def __init__(self, proxies=None):
+        if proxies is None:
+            proxies = getproxies()
+        assert hasattr(proxies, 'has_key'), "proxies must be a mapping"
+        self.proxies = proxies
+        for type, url in proxies.items():
+            setattr(self, '%s_open' % type,
+                    lambda r, proxy=url, type=type, meth=self.proxy_open: \
+                    meth(r, proxy, type))
+
+    def proxy_open(self, req, proxy, type):
+        orig_type = req.get_type()
+        proxy_type, user, password, hostport = _parse_proxy(proxy)
+        if proxy_type is None:
+            proxy_type = orig_type
+        if user and password:
+            user_pass = '%s:%s' % (unquote(user), unquote(password))
+            creds = base64.b64encode(user_pass).strip()
+            req.add_header('Proxy-authorization', 'Basic ' + creds)
+        hostport = unquote(hostport)
+        req.set_proxy(hostport, proxy_type)
+        if orig_type == proxy_type:
+            # let other handlers take care of it
+            return None
+        else:
+            # need to start over, because the other handlers don't
+            # grok the proxy's URL type
+            # e.g. if we have a constructor arg proxies like so:
+            # {'http': 'ftp://proxy.example.com'}, we may end up turning
+            # a request for http://acme.example.com/a into one for
+            # ftp://proxy.example.com/a
+            return self.parent.open(req)
+
+class HTTPPasswordMgr:
+
+    def __init__(self):
+        self.passwd = {}
+
+    def add_password(self, realm, uri, user, passwd):
+        # uri could be a single URI or a sequence
+        if isinstance(uri, basestring):
+            uri = [uri]
+        if not realm in self.passwd:
+            self.passwd[realm] = {}
+        for default_port in True, False:
+            reduced_uri = tuple(
+                [self.reduce_uri(u, default_port) for u in uri])
+            self.passwd[realm][reduced_uri] = (user, passwd)
+
+    def find_user_password(self, realm, authuri):
+        domains = self.passwd.get(realm, {})
+        for default_port in True, False:
+            reduced_authuri = self.reduce_uri(authuri, default_port)
+            for uris, authinfo in domains.iteritems():
+                for uri in uris:
+                    if self.is_suburi(uri, reduced_authuri):
+                        return authinfo
+        return None, None
+
+    def reduce_uri(self, uri, default_port=True):
+        """Accept authority or URI and extract only the authority and path."""
+        # note HTTP URLs do not have a userinfo component
+        parts = urlparse.urlsplit(uri)
+        if parts[1]:
+            # URI
+            scheme = parts[0]
+            authority = parts[1]
+            path = parts[2] or '/'
+        else:
+            # host or host:port
+            scheme = None
+            authority = uri
+            path = '/'
+        host, port = splitport(authority)
+        if default_port and port is None and scheme is not None:
+            dport = {"http": 80,
+                     "https": 443,
+                     }.get(scheme)
+            if dport is not None:
+                authority = "%s:%d" % (host, dport)
+        return authority, path
+
+    def is_suburi(self, base, test):
+        """Check if test is below base in a URI tree
+
+        Both args must be URIs in reduced form.
+        """
+        if base == test:
+            return True
+        if base[0] != test[0]:
+            return False
+        common = posixpath.commonprefix((base[1], test[1]))
+        if len(common) == len(base[1]):
+            return True
+        return False
+
+
+class HTTPPasswordMgrWithDefaultRealm(HTTPPasswordMgr):
+
+    def find_user_password(self, realm, authuri):
+        user, password = HTTPPasswordMgr.find_user_password(self, realm,
+                                                            authuri)
+        if user is not None:
+            return user, password
+        return HTTPPasswordMgr.find_user_password(self, None, authuri)
+
+
+class AbstractBasicAuthHandler:
+
+    # XXX this allows for multiple auth-schemes, but will stupidly pick
+    # the last one with a realm specified.
+
+    rx = re.compile('(?:.*,)*[ \t]*([^ \t]+)[ \t]+realm="([^"]*)"', re.I)
+
+    # XXX could pre-emptively send auth info already accepted (RFC 2617,
+    # end of section 2, and section 1.2 immediately after "credentials"
+    # production).
+
+    def __init__(self, password_mgr=None):
+        if password_mgr is None:
+            password_mgr = HTTPPasswordMgr()
+        self.passwd = password_mgr
+        self.add_password = self.passwd.add_password
+
+    def http_error_auth_reqed(self, authreq, host, req, headers):
+        # host may be an authority (without userinfo) or a URL with an
+        # authority
+        # XXX could be multiple headers
+        authreq = headers.get(authreq, None)
+        if authreq:
+            mo = AbstractBasicAuthHandler.rx.search(authreq)
+            if mo:
+                scheme, realm = mo.groups()
+                if scheme.lower() == 'basic':
+                    return self.retry_http_basic_auth(host, req, realm)
+
+    def retry_http_basic_auth(self, host, req, realm):
+        user, pw = self.passwd.find_user_password(realm, host)
+        if pw is not None:
+            raw = "%s:%s" % (user, pw)
+            auth = 'Basic %s' % base64.b64encode(raw).strip()
+            if req.headers.get(self.auth_header, None) == auth:
+                return None
+            req.add_header(self.auth_header, auth)
+            return self.parent.open(req)
+        else:
+            return None
+
+
+class HTTPBasicAuthHandler(AbstractBasicAuthHandler, BaseHandler):
+
+    auth_header = 'Authorization'
+
+    def http_error_401(self, req, fp, code, msg, headers):
+        url = req.get_full_url()
+        return self.http_error_auth_reqed('www-authenticate',
+                                          url, req, headers)
+
+
+class ProxyBasicAuthHandler(AbstractBasicAuthHandler, BaseHandler):
+
+    auth_header = 'Proxy-authorization'
+
+    def http_error_407(self, req, fp, code, msg, headers):
+        # http_error_auth_reqed requires that there is no userinfo component in
+        # authority.  Assume there isn't one, since urllib2 does not (and
+        # should not, RFC 3986 s. 3.2.1) support requests for URLs containing
+        # userinfo.
+        authority = req.get_host()
+        return self.http_error_auth_reqed('proxy-authenticate',
+                                          authority, req, headers)
+
+
+def randombytes(n):
+    """Return n random bytes."""
+    # Use /dev/urandom if it is available.  Fall back to random module
+    # if not.  It might be worthwhile to extend this function to use
+    # other platform-specific mechanisms for getting random bytes.
+    if os.path.exists("/dev/urandom"):
+        f = open("/dev/urandom")
+        s = f.read(n)
+        f.close()
+        return s
+    else:
+        L = [chr(random.randrange(0, 256)) for i in range(n)]
+        return "".join(L)
+
+class AbstractDigestAuthHandler:
+    # Digest authentication is specified in RFC 2617.
+
+    # XXX The client does not inspect the Authentication-Info header
+    # in a successful response.
+
+    # XXX It should be possible to test this implementation against
+    # a mock server that just generates a static set of challenges.
+
+    # XXX qop="auth-int" supports is shaky
+
+    def __init__(self, passwd=None):
+        if passwd is None:
+            passwd = HTTPPasswordMgr()
+        self.passwd = passwd
+        self.add_password = self.passwd.add_password
+        self.retried = 0
+        self.nonce_count = 0
+
+    def reset_retry_count(self):
+        self.retried = 0
+
+    def http_error_auth_reqed(self, auth_header, host, req, headers):
+        authreq = headers.get(auth_header, None)
+        if self.retried > 5:
+            # Don't fail endlessly - if we failed once, we'll probably
+            # fail a second time. Hm. Unless the Password Manager is
+            # prompting for the information. Crap. This isn't great
+            # but it's better than the current 'repeat until recursion
+            # depth exceeded' approach <wink>
+            raise HTTPError(req.get_full_url(), 401, "digest auth failed",
+                            headers, None)
+        else:
+            self.retried += 1
+        if authreq:
+            scheme = authreq.split()[0]
+            if scheme.lower() == 'digest':
+                return self.retry_http_digest_auth(req, authreq)
+
+    def retry_http_digest_auth(self, req, auth):
+        token, challenge = auth.split(' ', 1)
+        chal = parse_keqv_list(parse_http_list(challenge))
+        auth = self.get_authorization(req, chal)
+        if auth:
+            auth_val = 'Digest %s' % auth
+            if req.headers.get(self.auth_header, None) == auth_val:
+                return None
+            req.add_unredirected_header(self.auth_header, auth_val)
+            resp = self.parent.open(req)
+            return resp
+
+    def get_cnonce(self, nonce):
+        # The cnonce-value is an opaque
+        # quoted string value provided by the client and used by both client
+        # and server to avoid chosen plaintext attacks, to provide mutual
+        # authentication, and to provide some message integrity protection.
+        # This isn't a fabulous effort, but it's probably Good Enough.
+        dig = hashlib.sha1("%s:%s:%s:%s" % (self.nonce_count, nonce, time.ctime(),
+                                            randombytes(8))).hexdigest()
+        return dig[:16]
+
+    def get_authorization(self, req, chal):
+        try:
+            realm = chal['realm']
+            nonce = chal['nonce']
+            qop = chal.get('qop')
+            algorithm = chal.get('algorithm', 'MD5')
+            # mod_digest doesn't send an opaque, even though it isn't
+            # supposed to be optional
+            opaque = chal.get('opaque', None)
+        except KeyError:
+            return None
+
+        H, KD = self.get_algorithm_impls(algorithm)
+        if H is None:
+            return None
+
+        user, pw = self.passwd.find_user_password(realm, req.get_full_url())
+        if user is None:
+            return None
+
+        # XXX not implemented yet
+        if req.has_data():
+            entdig = self.get_entity_digest(req.get_data(), chal)
+        else:
+            entdig = None
+
+        A1 = "%s:%s:%s" % (user, realm, pw)
+        A2 = "%s:%s" % (req.get_method(),
+                        # XXX selector: what about proxies and full urls
+                        req.get_selector())
+        if qop == 'auth':
+            self.nonce_count += 1
+            ncvalue = '%08x' % self.nonce_count
+            cnonce = self.get_cnonce(nonce)
+            noncebit = "%s:%s:%s:%s:%s" % (nonce, ncvalue, cnonce, qop, H(A2))
+            respdig = KD(H(A1), noncebit)
+        elif qop is None:
+            respdig = KD(H(A1), "%s:%s" % (nonce, H(A2)))
+        else:
+            # XXX handle auth-int.
+            pass
+
+        # XXX should the partial digests be encoded too?
+
+        base = 'username="%s", realm="%s", nonce="%s", uri="%s", ' \
+               'response="%s"' % (user, realm, nonce, req.get_selector(),
+                                  respdig)
+        if opaque:
+            base += ', opaque="%s"' % opaque
+        if entdig:
+            base += ', digest="%s"' % entdig
+        base += ', algorithm="%s"' % algorithm
+        if qop:
+            base += ', qop=auth, nc=%s, cnonce="%s"' % (ncvalue, cnonce)
+        return base
+
+    def get_algorithm_impls(self, algorithm):
+        # lambdas assume digest modules are imported at the top level
+        if algorithm == 'MD5':
+            H = lambda x: hashlib.md5(x).hexdigest()
+        elif algorithm == 'SHA':
+            H = lambda x: hashlib.sha1(x).hexdigest()
+        # XXX MD5-sess
+        KD = lambda s, d: H("%s:%s" % (s, d))
+        return H, KD
+
+    def get_entity_digest(self, data, chal):
+        # XXX not implemented yet
+        return None
+
+
+class HTTPDigestAuthHandler(BaseHandler, AbstractDigestAuthHandler):
+    """An authentication protocol defined by RFC 2069
+
+    Digest authentication improves on basic authentication because it
+    does not transmit passwords in the clear.
+    """
+
+    auth_header = 'Authorization'
+    handler_order = 490  # before Basic auth
+
+    def http_error_401(self, req, fp, code, msg, headers):
+        host = urlparse.urlparse(req.get_full_url())[1]
+        retry = self.http_error_auth_reqed('www-authenticate',
+                                           host, req, headers)
+        self.reset_retry_count()
+        return retry
+
+
+class ProxyDigestAuthHandler(BaseHandler, AbstractDigestAuthHandler):
+
+    auth_header = 'Proxy-Authorization'
+    handler_order = 490  # before Basic auth
+
+    def http_error_407(self, req, fp, code, msg, headers):
+        host = req.get_host()
+        retry = self.http_error_auth_reqed('proxy-authenticate',
+                                           host, req, headers)
+        self.reset_retry_count()
+        return retry
+
+class AbstractHTTPHandler(BaseHandler):
+
+    def __init__(self, debuglevel=0):
+        self._debuglevel = debuglevel
+
+    def set_http_debuglevel(self, level):
+        self._debuglevel = level
+
+    def do_request_(self, request):
+        host = request.get_host()
+        if not host:
+            raise URLError('no host given')
+
+        if request.has_data():  # POST
+            data = request.get_data()
+            if not request.has_header('Content-type'):
+                request.add_unredirected_header(
+                    'Content-type',
+                    'application/x-www-form-urlencoded')
+            if not request.has_header('Content-length'):
+                request.add_unredirected_header(
+                    'Content-length', '%d' % len(data))
+
+        scheme, sel = splittype(request.get_selector())
+        sel_host, sel_path = splithost(sel)
+        if not request.has_header('Host'):
+            request.add_unredirected_header('Host', sel_host or host)
+        for name, value in self.parent.addheaders:
+            name = name.capitalize()
+            if not request.has_header(name):
+                request.add_unredirected_header(name, value)
+
+        return request
+
+    def do_open(self, http_class, req):
+        """Return an addinfourl object for the request, using http_class.
+
+        http_class must implement the HTTPConnection API from httplib.
+        The addinfourl return value is a file-like object.  It also
+        has methods and attributes including:
+            - info(): return a mimetools.Message object for the headers
+            - geturl(): return the original request URL
+            - code: HTTP status code
+        """
+        host = req.get_host()
+        if not host:
+            raise URLError('no host given')
+
+        h = http_class(host) # will parse host:port
+        h.set_debuglevel(self._debuglevel)
+
+        headers = dict(req.headers)
+        headers.update(req.unredirected_hdrs)
+        # We want to make an HTTP/1.1 request, but the addinfourl
+        # class isn't prepared to deal with a persistent connection.
+        # It will try to read all remaining data from the socket,
+        # which will block while the server waits for the next request.
+        # So make sure the connection gets closed after the (only)
+        # request.
+        headers["Connection"] = "close"
+        headers = dict(
+            (name.title(), val) for name, val in headers.items())
+        try:
+            h.request(req.get_method(), req.get_selector(), req.data, headers)
+            r = h.getresponse()
+        except socket.error, err: # XXX what error?
+            raise URLError(err)
+
+        # Pick apart the HTTPResponse object to get the addinfourl
+        # object initialized properly.
+
+        # Wrap the HTTPResponse object in socket's file object adapter
+        # for Windows.  That adapter calls recv(), so delegate recv()
+        # to read().  This weird wrapping allows the returned object to
+        # have readline() and readlines() methods.
+
+        # XXX It might be better to extract the read buffering code
+        # out of socket._fileobject() and into a base class.
+
+        r.recv = r.read
+        fp = socket._fileobject(r, close=True)
+
+        resp = addinfourl(fp, r.msg, req.get_full_url())
+        resp.code = r.status
+        resp.msg = r.reason
+        return resp
+
+
+class HTTPHandler(AbstractHTTPHandler):
+
+    def http_open(self, req):
+        return self.do_open(httplib.HTTPConnection, req)
+
+    http_request = AbstractHTTPHandler.do_request_
+
+if hasattr(httplib, 'HTTPS'):
+    class HTTPSHandler(AbstractHTTPHandler):
+
+        def https_open(self, req):
+            return self.do_open(httplib.HTTPSConnection, req)
+
+        https_request = AbstractHTTPHandler.do_request_
+
+class HTTPCookieProcessor(BaseHandler):
+    def __init__(self, cookiejar=None):
+        import cookielib
+        if cookiejar is None:
+            cookiejar = cookielib.CookieJar()
+        self.cookiejar = cookiejar
+
+    def http_request(self, request):
+        self.cookiejar.add_cookie_header(request)
+        return request
+
+    def http_response(self, request, response):
+        self.cookiejar.extract_cookies(response, request)
+        return response
+
+    https_request = http_request
+    https_response = http_response
+
+class UnknownHandler(BaseHandler):
+    def unknown_open(self, req):
+        type = req.get_type()
+        raise URLError('unknown url type: %s' % type)
+
+def parse_keqv_list(l):
+    """Parse list of key=value strings where keys are not duplicated."""
+    parsed = {}
+    for elt in l:
+        k, v = elt.split('=', 1)
+        if v[0] == '"' and v[-1] == '"':
+            v = v[1:-1]
+        parsed[k] = v
+    return parsed
+
+def parse_http_list(s):
+    """Parse lists as described by RFC 2068 Section 2.
+
+    In particular, parse comma-separated lists where the elements of
+    the list may include quoted-strings.  A quoted-string could
+    contain a comma.  A non-quoted string could have quotes in the
+    middle.  Neither commas nor quotes count if they are escaped.
+    Only double-quotes count, not single-quotes.
+    """
+    res = []
+    part = ''
+
+    escape = quote = False
+    for cur in s:
+        if escape:
+            part += cur
+            escape = False
+            continue
+        if quote:
+            if cur == '\\':
+                escape = True
+                continue
+            elif cur == '"':
+                quote = False
+            part += cur
+            continue
+
+        if cur == ',':
+            res.append(part)
+            part = ''
+            continue
+
+        if cur == '"':
+            quote = True
+
+        part += cur
+
+    # append last part
+    if part:
+        res.append(part)
+
+    return [part.strip() for part in res]
+
+class FileHandler(BaseHandler):
+    # Use local file or FTP depending on form of URL
+    def file_open(self, req):
+        url = req.get_selector()
+        if url[:2] == '//' and url[2:3] != '/':
+            req.type = 'ftp'
+            return self.parent.open(req)
+        else:
+            return self.open_local_file(req)
+
+    # names for the localhost
+    names = None
+    def get_names(self):
+        if FileHandler.names is None:
+            try:
+                FileHandler.names = (socket.gethostbyname('localhost'),
+                                    socket.gethostbyname(socket.gethostname()))
+            except socket.gaierror:
+                FileHandler.names = (socket.gethostbyname('localhost'),)
+        return FileHandler.names
+
+    # not entirely sure what the rules are here
+    def open_local_file(self, req):
+        import email.Utils
+        import mimetypes
+        host = req.get_host()
+        file = req.get_selector()
+        localfile = url2pathname(file)
+        stats = os.stat(localfile)
+        size = stats.st_size
+        modified = email.Utils.formatdate(stats.st_mtime, usegmt=True)
+        mtype = mimetypes.guess_type(file)[0]
+        headers = mimetools.Message(StringIO(
+            'Content-type: %s\nContent-length: %d\nLast-modified: %s\n' %
+            (mtype or 'text/plain', size, modified)))
+        if host:
+            host, port = splitport(host)
+        if not host or \
+           (not port and socket.gethostbyname(host) in self.get_names()):
+            return addinfourl(open(localfile, 'rb'),
+                              headers, 'file:'+file)
+        raise URLError('file not on local host')
+
+class FTPHandler(BaseHandler):
+    def ftp_open(self, req):
+        import ftplib
+        import mimetypes
+        host = req.get_host()
+        if not host:
+            raise IOError, ('ftp error', 'no host given')
+        host, port = splitport(host)
+        if port is None:
+            port = ftplib.FTP_PORT
+        else:
+            port = int(port)
+
+        # username/password handling
+        user, host = splituser(host)
+        if user:
+            user, passwd = splitpasswd(user)
+        else:
+            passwd = None
+        host = unquote(host)
+        user = unquote(user or '')
+        passwd = unquote(passwd or '')
+
+        try:
+            host = socket.gethostbyname(host)
+        except socket.error, msg:
+            raise URLError(msg)
+        path, attrs = splitattr(req.get_selector())
+        dirs = path.split('/')
+        dirs = map(unquote, dirs)
+        dirs, file = dirs[:-1], dirs[-1]
+        if dirs and not dirs[0]:
+            dirs = dirs[1:]
+        try:
+            fw = self.connect_ftp(user, passwd, host, port, dirs)
+            type = file and 'I' or 'D'
+            for attr in attrs:
+                attr, value = splitvalue(attr)
+                if attr.lower() == 'type' and \
+                   value in ('a', 'A', 'i', 'I', 'd', 'D'):
+                    type = value.upper()
+            fp, retrlen = fw.retrfile(file, type)
+            headers = ""
+            mtype = mimetypes.guess_type(req.get_full_url())[0]
+            if mtype:
+                headers += "Content-type: %s\n" % mtype
+            if retrlen is not None and retrlen >= 0:
+                headers += "Content-length: %d\n" % retrlen
+            sf = StringIO(headers)
+            headers = mimetools.Message(sf)
+            return addinfourl(fp, headers, req.get_full_url())
+        except ftplib.all_errors, msg:
+            raise IOError, ('ftp error', msg), sys.exc_info()[2]
+
+    def connect_ftp(self, user, passwd, host, port, dirs):
+        fw = ftpwrapper(user, passwd, host, port, dirs)
+##        fw.ftp.set_debuglevel(1)
+        return fw
+
+class CacheFTPHandler(FTPHandler):
+    # XXX would be nice to have pluggable cache strategies
+    # XXX this stuff is definitely not thread safe
+    def __init__(self):
+        self.cache = {}
+        self.timeout = {}
+        self.soonest = 0
+        self.delay = 60
+        self.max_conns = 16
+
+    def setTimeout(self, t):
+        self.delay = t
+
+    def setMaxConns(self, m):
+        self.max_conns = m
+
+    def connect_ftp(self, user, passwd, host, port, dirs):
+        key = user, host, port, '/'.join(dirs)
+        if key in self.cache:
+            self.timeout[key] = time.time() + self.delay
+        else:
+            self.cache[key] = ftpwrapper(user, passwd, host, port, dirs)
+            self.timeout[key] = time.time() + self.delay
+        self.check_cache()
+        return self.cache[key]
+
+    def check_cache(self):
+        # first check for old ones
+        t = time.time()
+        if self.soonest <= t:
+            for k, v in self.timeout.items():
+                if v < t:
+                    self.cache[k].close()
+                    del self.cache[k]
+                    del self.timeout[k]
+        self.soonest = min(self.timeout.values())
+
+        # then check the size
+        if len(self.cache) == self.max_conns:
+            for k, v in self.timeout.items():
+                if v == self.soonest:
+                    del self.cache[k]
+                    del self.timeout[k]
+                    break
+            self.soonest = min(self.timeout.values())
+
+class GopherHandler(BaseHandler):
+    def gopher_open(self, req):
+        # XXX can raise socket.error
+        import gopherlib  # this raises DeprecationWarning in 2.5
+        host = req.get_host()
+        if not host:
+            raise GopherError('no host given')
+        host = unquote(host)
+        selector = req.get_selector()
+        type, selector = splitgophertype(selector)
+        selector, query = splitquery(selector)
+        selector = unquote(selector)
+        if query:
+            query = unquote(query)
+            fp = gopherlib.send_query(selector, query, host)
+        else:
+            fp = gopherlib.send_selector(selector, host)
+        return addinfourl(fp, noheaders(), req.get_full_url())

Added: vendor/Python/current/Lib/urlparse.py
===================================================================
--- vendor/Python/current/Lib/urlparse.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/urlparse.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,375 @@
+"""Parse (absolute and relative) URLs.
+
+See RFC 1808: "Relative Uniform Resource Locators", by R. Fielding,
+UC Irvine, June 1995.
+"""
+
+__all__ = ["urlparse", "urlunparse", "urljoin", "urldefrag",
+           "urlsplit", "urlunsplit"]
+
+# A classification of schemes ('' means apply by default)
+uses_relative = ['ftp', 'http', 'gopher', 'nntp', 'imap',
+                 'wais', 'file', 'https', 'shttp', 'mms',
+                 'prospero', 'rtsp', 'rtspu', '', 'sftp']
+uses_netloc = ['ftp', 'http', 'gopher', 'nntp', 'telnet',
+               'imap', 'wais', 'file', 'mms', 'https', 'shttp',
+               'snews', 'prospero', 'rtsp', 'rtspu', 'rsync', '',
+               'svn', 'svn+ssh', 'sftp']
+non_hierarchical = ['gopher', 'hdl', 'mailto', 'news',
+                    'telnet', 'wais', 'imap', 'snews', 'sip', 'sips']
+uses_params = ['ftp', 'hdl', 'prospero', 'http', 'imap',
+               'https', 'shttp', 'rtsp', 'rtspu', 'sip', 'sips',
+               'mms', '', 'sftp']
+uses_query = ['http', 'wais', 'imap', 'https', 'shttp', 'mms',
+              'gopher', 'rtsp', 'rtspu', 'sip', 'sips', '']
+uses_fragment = ['ftp', 'hdl', 'http', 'gopher', 'news',
+                 'nntp', 'wais', 'https', 'shttp', 'snews',
+                 'file', 'prospero', '']
+
+# Characters valid in scheme names
+scheme_chars = ('abcdefghijklmnopqrstuvwxyz'
+                'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+                '0123456789'
+                '+-.')
+
+MAX_CACHE_SIZE = 20
+_parse_cache = {}
+
+def clear_cache():
+    """Clear the parse cache."""
+    global _parse_cache
+    _parse_cache = {}
+
+
+class BaseResult(tuple):
+    """Base class for the parsed result objects.
+
+    This provides the attributes shared by the two derived result
+    objects as read-only properties.  The derived classes are
+    responsible for checking the right number of arguments were
+    supplied to the constructor.
+
+    """
+
+    __slots__ = ()
+
+    # Attributes that access the basic components of the URL:
+
+    @property
+    def scheme(self):
+        return self[0]
+
+    @property
+    def netloc(self):
+        return self[1]
+
+    @property
+    def path(self):
+        return self[2]
+
+    @property
+    def query(self):
+        return self[-2]
+
+    @property
+    def fragment(self):
+        return self[-1]
+
+    # Additional attributes that provide access to parsed-out portions
+    # of the netloc:
+
+    @property
+    def username(self):
+        netloc = self.netloc
+        if "@" in netloc:
+            userinfo = netloc.split("@", 1)[0]
+            if ":" in userinfo:
+                userinfo = userinfo.split(":", 1)[0]
+            return userinfo
+        return None
+
+    @property
+    def password(self):
+        netloc = self.netloc
+        if "@" in netloc:
+            userinfo = netloc.split("@", 1)[0]
+            if ":" in userinfo:
+                return userinfo.split(":", 1)[1]
+        return None
+
+    @property
+    def hostname(self):
+        netloc = self.netloc
+        if "@" in netloc:
+            netloc = netloc.split("@", 1)[1]
+        if ":" in netloc:
+            netloc = netloc.split(":", 1)[0]
+        return netloc.lower() or None
+
+    @property
+    def port(self):
+        netloc = self.netloc
+        if "@" in netloc:
+            netloc = netloc.split("@", 1)[1]
+        if ":" in netloc:
+            port = netloc.split(":", 1)[1]
+            return int(port, 10)
+        return None
+
+
+class SplitResult(BaseResult):
+
+    __slots__ = ()
+
+    def __new__(cls, scheme, netloc, path, query, fragment):
+        return BaseResult.__new__(
+            cls, (scheme, netloc, path, query, fragment))
+
+    def geturl(self):
+        return urlunsplit(self)
+
+
+class ParseResult(BaseResult):
+
+    __slots__ = ()
+
+    def __new__(cls, scheme, netloc, path, params, query, fragment):
+        return BaseResult.__new__(
+            cls, (scheme, netloc, path, params, query, fragment))
+
+    @property
+    def params(self):
+        return self[3]
+
+    def geturl(self):
+        return urlunparse(self)
+
+
+def urlparse(url, scheme='', allow_fragments=True):
+    """Parse a URL into 6 components:
+    <scheme>://<netloc>/<path>;<params>?<query>#<fragment>
+    Return a 6-tuple: (scheme, netloc, path, params, query, fragment).
+    Note that we don't break the components up in smaller bits
+    (e.g. netloc is a single string) and we don't expand % escapes."""
+    tuple = urlsplit(url, scheme, allow_fragments)
+    scheme, netloc, url, query, fragment = tuple
+    if scheme in uses_params and ';' in url:
+        url, params = _splitparams(url)
+    else:
+        params = ''
+    return ParseResult(scheme, netloc, url, params, query, fragment)
+
+def _splitparams(url):
+    if '/'  in url:
+        i = url.find(';', url.rfind('/'))
+        if i < 0:
+            return url, ''
+    else:
+        i = url.find(';')
+    return url[:i], url[i+1:]
+
+def _splitnetloc(url, start=0):
+    for c in '/?#': # the order is important!
+        delim = url.find(c, start)
+        if delim >= 0:
+            break
+    else:
+        delim = len(url)
+    return url[start:delim], url[delim:]
+
+def urlsplit(url, scheme='', allow_fragments=True):
+    """Parse a URL into 5 components:
+    <scheme>://<netloc>/<path>?<query>#<fragment>
+    Return a 5-tuple: (scheme, netloc, path, query, fragment).
+    Note that we don't break the components up in smaller bits
+    (e.g. netloc is a single string) and we don't expand % escapes."""
+    allow_fragments = bool(allow_fragments)
+    key = url, scheme, allow_fragments
+    cached = _parse_cache.get(key, None)
+    if cached:
+        return cached
+    if len(_parse_cache) >= MAX_CACHE_SIZE: # avoid runaway growth
+        clear_cache()
+    netloc = query = fragment = ''
+    i = url.find(':')
+    if i > 0:
+        if url[:i] == 'http': # optimize the common case
+            scheme = url[:i].lower()
+            url = url[i+1:]
+            if url[:2] == '//':
+                netloc, url = _splitnetloc(url, 2)
+            if allow_fragments and '#' in url:
+                url, fragment = url.split('#', 1)
+            if '?' in url:
+                url, query = url.split('?', 1)
+            v = SplitResult(scheme, netloc, url, query, fragment)
+            _parse_cache[key] = v
+            return v
+        for c in url[:i]:
+            if c not in scheme_chars:
+                break
+        else:
+            scheme, url = url[:i].lower(), url[i+1:]
+    if scheme in uses_netloc and url[:2] == '//':
+        netloc, url = _splitnetloc(url, 2)
+    if allow_fragments and scheme in uses_fragment and '#' in url:
+        url, fragment = url.split('#', 1)
+    if scheme in uses_query and '?' in url:
+        url, query = url.split('?', 1)
+    v = SplitResult(scheme, netloc, url, query, fragment)
+    _parse_cache[key] = v
+    return v
+
+def urlunparse((scheme, netloc, url, params, query, fragment)):
+    """Put a parsed URL back together again.  This may result in a
+    slightly different, but equivalent URL, if the URL that was parsed
+    originally had redundant delimiters, e.g. a ? with an empty query
+    (the draft states that these are equivalent)."""
+    if params:
+        url = "%s;%s" % (url, params)
+    return urlunsplit((scheme, netloc, url, query, fragment))
+
+def urlunsplit((scheme, netloc, url, query, fragment)):
+    if netloc or (scheme and scheme in uses_netloc and url[:2] != '//'):
+        if url and url[:1] != '/': url = '/' + url
+        url = '//' + (netloc or '') + url
+    if scheme:
+        url = scheme + ':' + url
+    if query:
+        url = url + '?' + query
+    if fragment:
+        url = url + '#' + fragment
+    return url
+
+def urljoin(base, url, allow_fragments=True):
+    """Join a base URL and a possibly relative URL to form an absolute
+    interpretation of the latter."""
+    if not base:
+        return url
+    if not url:
+        return base
+    bscheme, bnetloc, bpath, bparams, bquery, bfragment = \
+            urlparse(base, '', allow_fragments)
+    scheme, netloc, path, params, query, fragment = \
+            urlparse(url, bscheme, allow_fragments)
+    if scheme != bscheme or scheme not in uses_relative:
+        return url
+    if scheme in uses_netloc:
+        if netloc:
+            return urlunparse((scheme, netloc, path,
+                               params, query, fragment))
+        netloc = bnetloc
+    if path[:1] == '/':
+        return urlunparse((scheme, netloc, path,
+                           params, query, fragment))
+    if not (path or params or query):
+        return urlunparse((scheme, netloc, bpath,
+                           bparams, bquery, fragment))
+    segments = bpath.split('/')[:-1] + path.split('/')
+    # XXX The stuff below is bogus in various ways...
+    if segments[-1] == '.':
+        segments[-1] = ''
+    while '.' in segments:
+        segments.remove('.')
+    while 1:
+        i = 1
+        n = len(segments) - 1
+        while i < n:
+            if (segments[i] == '..'
+                and segments[i-1] not in ('', '..')):
+                del segments[i-1:i+1]
+                break
+            i = i+1
+        else:
+            break
+    if segments == ['', '..']:
+        segments[-1] = ''
+    elif len(segments) >= 2 and segments[-1] == '..':
+        segments[-2:] = ['']
+    return urlunparse((scheme, netloc, '/'.join(segments),
+                       params, query, fragment))
+
+def urldefrag(url):
+    """Removes any existing fragment from URL.
+
+    Returns a tuple of the defragmented URL and the fragment.  If
+    the URL contained no fragments, the second element is the
+    empty string.
+    """
+    if '#' in url:
+        s, n, p, a, q, frag = urlparse(url)
+        defrag = urlunparse((s, n, p, a, q, ''))
+        return defrag, frag
+    else:
+        return url, ''
+
+
+test_input = """
+      http://a/b/c/d
+
+      g:h        = <URL:g:h>
+      http:g     = <URL:http://a/b/c/g>
+      http:      = <URL:http://a/b/c/d>
+      g          = <URL:http://a/b/c/g>
+      ./g        = <URL:http://a/b/c/g>
+      g/         = <URL:http://a/b/c/g/>
+      /g         = <URL:http://a/g>
+      //g        = <URL:http://g>
+      ?y         = <URL:http://a/b/c/d?y>
+      g?y        = <URL:http://a/b/c/g?y>
+      g?y/./x    = <URL:http://a/b/c/g?y/./x>
+      .          = <URL:http://a/b/c/>
+      ./         = <URL:http://a/b/c/>
+      ..         = <URL:http://a/b/>
+      ../        = <URL:http://a/b/>
+      ../g       = <URL:http://a/b/g>
+      ../..      = <URL:http://a/>
+      ../../g    = <URL:http://a/g>
+      ../../../g = <URL:http://a/../g>
+      ./../g     = <URL:http://a/b/g>
+      ./g/.      = <URL:http://a/b/c/g/>
+      /./g       = <URL:http://a/./g>
+      g/./h      = <URL:http://a/b/c/g/h>
+      g/../h     = <URL:http://a/b/c/h>
+      http:g     = <URL:http://a/b/c/g>
+      http:      = <URL:http://a/b/c/d>
+      http:?y         = <URL:http://a/b/c/d?y>
+      http:g?y        = <URL:http://a/b/c/g?y>
+      http:g?y/./x    = <URL:http://a/b/c/g?y/./x>
+"""
+
+def test():
+    import sys
+    base = ''
+    if sys.argv[1:]:
+        fn = sys.argv[1]
+        if fn == '-':
+            fp = sys.stdin
+        else:
+            fp = open(fn)
+    else:
+        try:
+            from cStringIO import StringIO
+        except ImportError:
+            from StringIO import StringIO
+        fp = StringIO(test_input)
+    while 1:
+        line = fp.readline()
+        if not line: break
+        words = line.split()
+        if not words:
+            continue
+        url = words[0]
+        parts = urlparse(url)
+        print '%-10s : %s' % (url, parts)
+        abs = urljoin(base, url)
+        if not base:
+            base = abs
+        wrapped = '<URL:%s>' % abs
+        print '%-10s = %s' % (url, wrapped)
+        if len(words) == 3 and words[1] == '=':
+            if wrapped != words[2]:
+                print 'EXPECTED', words[2], '!!!!!!!!!!'
+
+if __name__ == '__main__':
+    test()

Added: vendor/Python/current/Lib/user.py
===================================================================
--- vendor/Python/current/Lib/user.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/user.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,45 @@
+"""Hook to allow user-specified customization code to run.
+
+As a policy, Python doesn't run user-specified code on startup of
+Python programs (interactive sessions execute the script specified in
+the PYTHONSTARTUP environment variable if it exists).
+
+However, some programs or sites may find it convenient to allow users
+to have a standard customization file, which gets run when a program
+requests it.  This module implements such a mechanism.  A program
+that wishes to use the mechanism must execute the statement
+
+    import user
+
+The user module looks for a file .pythonrc.py in the user's home
+directory and if it can be opened, execfile()s it in its own global
+namespace.  Errors during this phase are not caught; that's up to the
+program that imports the user module, if it wishes.
+
+The user's .pythonrc.py could conceivably test for sys.version if it
+wishes to do different things depending on the Python version.
+
+"""
+
+import os
+
+home = os.curdir                        # Default
+if 'HOME' in os.environ:
+    home = os.environ['HOME']
+elif os.name == 'posix':
+    home = os.path.expanduser("~/")
+elif os.name == 'nt':                   # Contributed by Jeff Bauer
+    if 'HOMEPATH' in os.environ:
+        if 'HOMEDRIVE' in os.environ:
+            home = os.environ['HOMEDRIVE'] + os.environ['HOMEPATH']
+        else:
+            home = os.environ['HOMEPATH']
+
+pythonrc = os.path.join(home, ".pythonrc.py")
+try:
+    f = open(pythonrc)
+except IOError:
+    pass
+else:
+    f.close()
+    execfile(pythonrc)

Added: vendor/Python/current/Lib/uu.py
===================================================================
--- vendor/Python/current/Lib/uu.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/uu.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,186 @@
+#! /usr/bin/env python
+
+# Copyright 1994 by Lance Ellinghouse
+# Cathedral City, California Republic, United States of America.
+#                        All Rights Reserved
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose and without fee is hereby granted,
+# provided that the above copyright notice appear in all copies and that
+# both that copyright notice and this permission notice appear in
+# supporting documentation, and that the name of Lance Ellinghouse
+# not be used in advertising or publicity pertaining to distribution
+# of the software without specific, written prior permission.
+# LANCE ELLINGHOUSE DISCLAIMS ALL WARRANTIES WITH REGARD TO
+# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+# FITNESS, IN NO EVENT SHALL LANCE ELLINGHOUSE CENTRUM BE LIABLE
+# FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+# Modified by Jack Jansen, CWI, July 1995:
+# - Use binascii module to do the actual line-by-line conversion
+#   between ascii and binary. This results in a 1000-fold speedup. The C
+#   version is still 5 times faster, though.
+# - Arguments more compliant with python standard
+
+"""Implementation of the UUencode and UUdecode functions.
+
+encode(in_file, out_file [,name, mode])
+decode(in_file [, out_file, mode])
+"""
+
+import binascii
+import os
+import sys
+
+__all__ = ["Error", "encode", "decode"]
+
+class Error(Exception):
+    pass
+
+def encode(in_file, out_file, name=None, mode=None):
+    """Uuencode file"""
+    #
+    # If in_file is a pathname open it and change defaults
+    #
+    if in_file == '-':
+        in_file = sys.stdin
+    elif isinstance(in_file, basestring):
+        if name is None:
+            name = os.path.basename(in_file)
+        if mode is None:
+            try:
+                mode = os.stat(in_file).st_mode
+            except AttributeError:
+                pass
+        in_file = open(in_file, 'rb')
+    #
+    # Open out_file if it is a pathname
+    #
+    if out_file == '-':
+        out_file = sys.stdout
+    elif isinstance(out_file, basestring):
+        out_file = open(out_file, 'w')
+    #
+    # Set defaults for name and mode
+    #
+    if name is None:
+        name = '-'
+    if mode is None:
+        mode = 0666
+    #
+    # Write the data
+    #
+    out_file.write('begin %o %s\n' % ((mode&0777),name))
+    data = in_file.read(45)
+    while len(data) > 0:
+        out_file.write(binascii.b2a_uu(data))
+        data = in_file.read(45)
+    out_file.write(' \nend\n')
+
+
+def decode(in_file, out_file=None, mode=None, quiet=0):
+    """Decode uuencoded file"""
+    #
+    # Open the input file, if needed.
+    #
+    if in_file == '-':
+        in_file = sys.stdin
+    elif isinstance(in_file, basestring):
+        in_file = open(in_file)
+    #
+    # Read until a begin is encountered or we've exhausted the file
+    #
+    while True:
+        hdr = in_file.readline()
+        if not hdr:
+            raise Error('No valid begin line found in input file')
+        if not hdr.startswith('begin'):
+            continue
+        hdrfields = hdr.split(' ', 2)
+        if len(hdrfields) == 3 and hdrfields[0] == 'begin':
+            try:
+                int(hdrfields[1], 8)
+                break
+            except ValueError:
+                pass
+    if out_file is None:
+        out_file = hdrfields[2].rstrip()
+        if os.path.exists(out_file):
+            raise Error('Cannot overwrite existing file: %s' % out_file)
+    if mode is None:
+        mode = int(hdrfields[1], 8)
+    #
+    # Open the output file
+    #
+    opened = False
+    if out_file == '-':
+        out_file = sys.stdout
+    elif isinstance(out_file, basestring):
+        fp = open(out_file, 'wb')
+        try:
+            os.path.chmod(out_file, mode)
+        except AttributeError:
+            pass
+        out_file = fp
+        opened = True
+    #
+    # Main decoding loop
+    #
+    s = in_file.readline()
+    while s and s.strip() != 'end':
+        try:
+            data = binascii.a2b_uu(s)
+        except binascii.Error, v:
+            # Workaround for broken uuencoders by /Fredrik Lundh
+            nbytes = (((ord(s[0])-32) & 63) * 4 + 5) // 3
+            data = binascii.a2b_uu(s[:nbytes])
+            if not quiet:
+                sys.stderr.write("Warning: %s\n" % v)
+        out_file.write(data)
+        s = in_file.readline()
+    if not s:
+        raise Error('Truncated input file')
+    if opened:
+        out_file.close()
+
+def test():
+    """uuencode/uudecode main program"""
+
+    import optparse
+    parser = optparse.OptionParser(usage='usage: %prog [-d] [-t] [input [output]]')
+    parser.add_option('-d', '--decode', dest='decode', help='Decode (instead of encode)?', default=False, action='store_true')
+    parser.add_option('-t', '--text', dest='text', help='data is text, encoded format unix-compatible text?', default=False, action='store_true')
+
+    (options, args) = parser.parse_args()
+    if len(args) > 2:
+        parser.error('incorrect number of arguments')
+        sys.exit(1)
+
+    input = sys.stdin
+    output = sys.stdout
+    if len(args) > 0:
+        input = args[0]
+    if len(args) > 1:
+        output = args[1]
+
+    if options.decode:
+        if options.text:
+            if isinstance(output, basestring):
+                output = open(output, 'w')
+            else:
+                print sys.argv[0], ': cannot do -t to stdout'
+                sys.exit(1)
+        decode(input, output)
+    else:
+        if options.text:
+            if isinstance(input, basestring):
+                input = open(input, 'r')
+            else:
+                print sys.argv[0], ': cannot do -t from stdin'
+                sys.exit(1)
+        encode(input, output)
+
+if __name__ == '__main__':
+    test()


Property changes on: vendor/Python/current/Lib/uu.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Lib/uuid.py
===================================================================
--- vendor/Python/current/Lib/uuid.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/uuid.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,541 @@
+r"""UUID objects (universally unique identifiers) according to RFC 4122.
+
+This module provides immutable UUID objects (class UUID) and the functions
+uuid1(), uuid3(), uuid4(), uuid5() for generating version 1, 3, 4, and 5
+UUIDs as specified in RFC 4122.
+
+If all you want is a unique ID, you should probably call uuid1() or uuid4().
+Note that uuid1() may compromise privacy since it creates a UUID containing
+the computer's network address.  uuid4() creates a random UUID.
+
+Typical usage:
+
+    >>> import uuid
+
+    # make a UUID based on the host ID and current time
+    >>> uuid.uuid1()
+    UUID('a8098c1a-f86e-11da-bd1a-00112444be1e')
+
+    # make a UUID using an MD5 hash of a namespace UUID and a name
+    >>> uuid.uuid3(uuid.NAMESPACE_DNS, 'python.org')
+    UUID('6fa459ea-ee8a-3ca4-894e-db77e160355e')
+
+    # make a random UUID
+    >>> uuid.uuid4()
+    UUID('16fd2706-8baf-433b-82eb-8c7fada847da')
+
+    # make a UUID using a SHA-1 hash of a namespace UUID and a name
+    >>> uuid.uuid5(uuid.NAMESPACE_DNS, 'python.org')
+    UUID('886313e1-3b8a-5372-9b90-0c9aee199e5d')
+
+    # make a UUID from a string of hex digits (braces and hyphens ignored)
+    >>> x = uuid.UUID('{00010203-0405-0607-0809-0a0b0c0d0e0f}')
+
+    # convert a UUID to a string of hex digits in standard form
+    >>> str(x)
+    '00010203-0405-0607-0809-0a0b0c0d0e0f'
+
+    # get the raw 16 bytes of the UUID
+    >>> x.bytes
+    '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f'
+
+    # make a UUID from a 16-byte string
+    >>> uuid.UUID(bytes=x.bytes)
+    UUID('00010203-0405-0607-0809-0a0b0c0d0e0f')
+"""
+
+__author__ = 'Ka-Ping Yee <ping at zesty.ca>'
+
+RESERVED_NCS, RFC_4122, RESERVED_MICROSOFT, RESERVED_FUTURE = [
+    'reserved for NCS compatibility', 'specified in RFC 4122',
+    'reserved for Microsoft compatibility', 'reserved for future definition']
+
+class UUID(object):
+    """Instances of the UUID class represent UUIDs as specified in RFC 4122.
+    UUID objects are immutable, hashable, and usable as dictionary keys.
+    Converting a UUID to a string with str() yields something in the form
+    '12345678-1234-1234-1234-123456789abc'.  The UUID constructor accepts
+    five possible forms: a similar string of hexadecimal digits, or a tuple
+    of six integer fields (with 32-bit, 16-bit, 16-bit, 8-bit, 8-bit, and
+    48-bit values respectively) as an argument named 'fields', or a string
+    of 16 bytes (with all the integer fields in big-endian order) as an
+    argument named 'bytes', or a string of 16 bytes (with the first three
+    fields in little-endian order) as an argument named 'bytes_le', or a
+    single 128-bit integer as an argument named 'int'.
+
+    UUIDs have these read-only attributes:
+
+        bytes       the UUID as a 16-byte string (containing the six
+                    integer fields in big-endian byte order)
+
+        bytes_le    the UUID as a 16-byte string (with time_low, time_mid,
+                    and time_hi_version in little-endian byte order)
+
+        fields      a tuple of the six integer fields of the UUID,
+                    which are also available as six individual attributes
+                    and two derived attributes:
+
+            time_low                the first 32 bits of the UUID
+            time_mid                the next 16 bits of the UUID
+            time_hi_version         the next 16 bits of the UUID
+            clock_seq_hi_variant    the next 8 bits of the UUID
+            clock_seq_low           the next 8 bits of the UUID
+            node                    the last 48 bits of the UUID
+
+            time                    the 60-bit timestamp
+            clock_seq               the 14-bit sequence number
+
+        hex         the UUID as a 32-character hexadecimal string
+
+        int         the UUID as a 128-bit integer
+
+        urn         the UUID as a URN as specified in RFC 4122
+
+        variant     the UUID variant (one of the constants RESERVED_NCS,
+                    RFC_4122, RESERVED_MICROSOFT, or RESERVED_FUTURE)
+
+        version     the UUID version number (1 through 5, meaningful only
+                    when the variant is RFC_4122)
+    """
+
+    def __init__(self, hex=None, bytes=None, bytes_le=None, fields=None,
+                       int=None, version=None):
+        r"""Create a UUID from either a string of 32 hexadecimal digits,
+        a string of 16 bytes as the 'bytes' argument, a string of 16 bytes
+        in little-endian order as the 'bytes_le' argument, a tuple of six
+        integers (32-bit time_low, 16-bit time_mid, 16-bit time_hi_version,
+        8-bit clock_seq_hi_variant, 8-bit clock_seq_low, 48-bit node) as
+        the 'fields' argument, or a single 128-bit integer as the 'int'
+        argument.  When a string of hex digits is given, curly braces,
+        hyphens, and a URN prefix are all optional.  For example, these
+        expressions all yield the same UUID:
+
+        UUID('{12345678-1234-5678-1234-567812345678}')
+        UUID('12345678123456781234567812345678')
+        UUID('urn:uuid:12345678-1234-5678-1234-567812345678')
+        UUID(bytes='\x12\x34\x56\x78'*4)
+        UUID(bytes_le='\x78\x56\x34\x12\x34\x12\x78\x56' +
+                      '\x12\x34\x56\x78\x12\x34\x56\x78')
+        UUID(fields=(0x12345678, 0x1234, 0x5678, 0x12, 0x34, 0x567812345678))
+        UUID(int=0x12345678123456781234567812345678)
+
+        Exactly one of 'hex', 'bytes', 'bytes_le', 'fields', or 'int' must
+        be given.  The 'version' argument is optional; if given, the resulting
+        UUID will have its variant and version set according to RFC 4122,
+        overriding the given 'hex', 'bytes', 'bytes_le', 'fields', or 'int'.
+        """
+
+        if [hex, bytes, bytes_le, fields, int].count(None) != 4:
+            raise TypeError('need one of hex, bytes, bytes_le, fields, or int')
+        if hex is not None:
+            hex = hex.replace('urn:', '').replace('uuid:', '')
+            hex = hex.strip('{}').replace('-', '')
+            if len(hex) != 32:
+                raise ValueError('badly formed hexadecimal UUID string')
+            int = long(hex, 16)
+        if bytes_le is not None:
+            if len(bytes_le) != 16:
+                raise ValueError('bytes_le is not a 16-char string')
+            bytes = (bytes_le[3] + bytes_le[2] + bytes_le[1] + bytes_le[0] +
+                     bytes_le[5] + bytes_le[4] + bytes_le[7] + bytes_le[6] +
+                     bytes_le[8:])
+        if bytes is not None:
+            if len(bytes) != 16:
+                raise ValueError('bytes is not a 16-char string')
+            int = long(('%02x'*16) % tuple(map(ord, bytes)), 16)
+        if fields is not None:
+            if len(fields) != 6:
+                raise ValueError('fields is not a 6-tuple')
+            (time_low, time_mid, time_hi_version,
+             clock_seq_hi_variant, clock_seq_low, node) = fields
+            if not 0 <= time_low < 1<<32L:
+                raise ValueError('field 1 out of range (need a 32-bit value)')
+            if not 0 <= time_mid < 1<<16L:
+                raise ValueError('field 2 out of range (need a 16-bit value)')
+            if not 0 <= time_hi_version < 1<<16L:
+                raise ValueError('field 3 out of range (need a 16-bit value)')
+            if not 0 <= clock_seq_hi_variant < 1<<8L:
+                raise ValueError('field 4 out of range (need an 8-bit value)')
+            if not 0 <= clock_seq_low < 1<<8L:
+                raise ValueError('field 5 out of range (need an 8-bit value)')
+            if not 0 <= node < 1<<48L:
+                raise ValueError('field 6 out of range (need a 48-bit value)')
+            clock_seq = (clock_seq_hi_variant << 8L) | clock_seq_low
+            int = ((time_low << 96L) | (time_mid << 80L) |
+                   (time_hi_version << 64L) | (clock_seq << 48L) | node)
+        if int is not None:
+            if not 0 <= int < 1<<128L:
+                raise ValueError('int is out of range (need a 128-bit value)')
+        if version is not None:
+            if not 1 <= version <= 5:
+                raise ValueError('illegal version number')
+            # Set the variant to RFC 4122.
+            int &= ~(0xc000 << 48L)
+            int |= 0x8000 << 48L
+            # Set the version number.
+            int &= ~(0xf000 << 64L)
+            int |= version << 76L
+        self.__dict__['int'] = int
+
+    def __cmp__(self, other):
+        if isinstance(other, UUID):
+            return cmp(self.int, other.int)
+        return NotImplemented
+
+    def __hash__(self):
+        return hash(self.int)
+
+    def __int__(self):
+        return self.int
+
+    def __repr__(self):
+        return 'UUID(%r)' % str(self)
+
+    def __setattr__(self, name, value):
+        raise TypeError('UUID objects are immutable')
+
+    def __str__(self):
+        hex = '%032x' % self.int
+        return '%s-%s-%s-%s-%s' % (
+            hex[:8], hex[8:12], hex[12:16], hex[16:20], hex[20:])
+
+    def get_bytes(self):
+        bytes = ''
+        for shift in range(0, 128, 8):
+            bytes = chr((self.int >> shift) & 0xff) + bytes
+        return bytes
+
+    bytes = property(get_bytes)
+
+    def get_bytes_le(self):
+        bytes = self.bytes
+        return (bytes[3] + bytes[2] + bytes[1] + bytes[0] +
+                bytes[5] + bytes[4] + bytes[7] + bytes[6] + bytes[8:])
+
+    bytes_le = property(get_bytes_le)
+
+    def get_fields(self):
+        return (self.time_low, self.time_mid, self.time_hi_version,
+                self.clock_seq_hi_variant, self.clock_seq_low, self.node)
+
+    fields = property(get_fields)
+
+    def get_time_low(self):
+        return self.int >> 96L
+
+    time_low = property(get_time_low)
+
+    def get_time_mid(self):
+        return (self.int >> 80L) & 0xffff
+
+    time_mid = property(get_time_mid)
+
+    def get_time_hi_version(self):
+        return (self.int >> 64L) & 0xffff
+
+    time_hi_version = property(get_time_hi_version)
+
+    def get_clock_seq_hi_variant(self):
+        return (self.int >> 56L) & 0xff
+
+    clock_seq_hi_variant = property(get_clock_seq_hi_variant)
+
+    def get_clock_seq_low(self):
+        return (self.int >> 48L) & 0xff
+
+    clock_seq_low = property(get_clock_seq_low)
+
+    def get_time(self):
+        return (((self.time_hi_version & 0x0fffL) << 48L) |
+                (self.time_mid << 32L) | self.time_low)
+
+    time = property(get_time)
+
+    def get_clock_seq(self):
+        return (((self.clock_seq_hi_variant & 0x3fL) << 8L) |
+                self.clock_seq_low)
+
+    clock_seq = property(get_clock_seq)
+
+    def get_node(self):
+        return self.int & 0xffffffffffff
+
+    node = property(get_node)
+
+    def get_hex(self):
+        return '%032x' % self.int
+
+    hex = property(get_hex)
+
+    def get_urn(self):
+        return 'urn:uuid:' + str(self)
+
+    urn = property(get_urn)
+
+    def get_variant(self):
+        if not self.int & (0x8000 << 48L):
+            return RESERVED_NCS
+        elif not self.int & (0x4000 << 48L):
+            return RFC_4122
+        elif not self.int & (0x2000 << 48L):
+            return RESERVED_MICROSOFT
+        else:
+            return RESERVED_FUTURE
+
+    variant = property(get_variant)
+
+    def get_version(self):
+        # The version bits are only meaningful for RFC 4122 UUIDs.
+        if self.variant == RFC_4122:
+            return int((self.int >> 76L) & 0xf)
+
+    version = property(get_version)
+
+def _find_mac(command, args, hw_identifiers, get_index):
+    import os
+    for dir in ['', '/sbin/', '/usr/sbin']:
+        executable = os.path.join(dir, command)
+        if not os.path.exists(executable):
+            continue
+
+        try:
+            # LC_ALL to get English output, 2>/dev/null to
+            # prevent output on stderr
+            cmd = 'LC_ALL=C %s %s 2>/dev/null' % (executable, args)
+            pipe = os.popen(cmd)
+        except IOError:
+            continue
+
+        for line in pipe:
+            words = line.lower().split()
+            for i in range(len(words)):
+                if words[i] in hw_identifiers:
+                    return int(words[get_index(i)].replace(':', ''), 16)
+    return None
+
+def _ifconfig_getnode():
+    """Get the hardware address on Unix by running ifconfig."""
+
+    # This works on Linux ('' or '-a'), Tru64 ('-av'), but not all Unixes.
+    for args in ('', '-a', '-av'):
+        mac = _find_mac('ifconfig', args, ['hwaddr', 'ether'], lambda i: i+1)
+        if mac:
+            return mac
+
+    import socket
+    ip_addr = socket.gethostbyname(socket.gethostname())
+
+    # Try getting the MAC addr from arp based on our IP address (Solaris).
+    mac = _find_mac('arp', '-an', [ip_addr], lambda i: -1)
+    if mac:
+        return mac
+
+    # This might work on HP-UX.
+    mac = _find_mac('lanscan', '-ai', ['lan0'], lambda i: 0)
+    if mac:
+        return mac
+
+    return None
+
+def _ipconfig_getnode():
+    """Get the hardware address on Windows by running ipconfig.exe."""
+    import os, re
+    dirs = ['', r'c:\windows\system32', r'c:\winnt\system32']
+    try:
+        import ctypes
+        buffer = ctypes.create_string_buffer(300)
+        ctypes.windll.kernel32.GetSystemDirectoryA(buffer, 300)
+        dirs.insert(0, buffer.value.decode('mbcs'))
+    except:
+        pass
+    for dir in dirs:
+        try:
+            pipe = os.popen(os.path.join(dir, 'ipconfig') + ' /all')
+        except IOError:
+            continue
+        for line in pipe:
+            value = line.split(':')[-1].strip().lower()
+            if re.match('([0-9a-f][0-9a-f]-){5}[0-9a-f][0-9a-f]', value):
+                return int(value.replace('-', ''), 16)
+
+def _netbios_getnode():
+    """Get the hardware address on Windows using NetBIOS calls.
+    See http://support.microsoft.com/kb/118623 for details."""
+    import win32wnet, netbios
+    ncb = netbios.NCB()
+    ncb.Command = netbios.NCBENUM
+    ncb.Buffer = adapters = netbios.LANA_ENUM()
+    adapters._pack()
+    if win32wnet.Netbios(ncb) != 0:
+        return
+    adapters._unpack()
+    for i in range(adapters.length):
+        ncb.Reset()
+        ncb.Command = netbios.NCBRESET
+        ncb.Lana_num = ord(adapters.lana[i])
+        if win32wnet.Netbios(ncb) != 0:
+            continue
+        ncb.Reset()
+        ncb.Command = netbios.NCBASTAT
+        ncb.Lana_num = ord(adapters.lana[i])
+        ncb.Callname = '*'.ljust(16)
+        ncb.Buffer = status = netbios.ADAPTER_STATUS()
+        if win32wnet.Netbios(ncb) != 0:
+            continue
+        status._unpack()
+        bytes = map(ord, status.adapter_address)
+        return ((bytes[0]<<40L) + (bytes[1]<<32L) + (bytes[2]<<24L) +
+                (bytes[3]<<16L) + (bytes[4]<<8L) + bytes[5])
+
+# Thanks to Thomas Heller for ctypes and for his help with its use here.
+
+# If ctypes is available, use it to find system routines for UUID generation.
+_uuid_generate_random = _uuid_generate_time = _UuidCreate = None
+try:
+    import ctypes, ctypes.util
+    _buffer = ctypes.create_string_buffer(16)
+
+    # The uuid_generate_* routines are provided by libuuid on at least
+    # Linux and FreeBSD, and provided by libc on Mac OS X.
+    for libname in ['uuid', 'c']:
+        try:
+            lib = ctypes.CDLL(ctypes.util.find_library(libname))
+        except:
+            continue
+        if hasattr(lib, 'uuid_generate_random'):
+            _uuid_generate_random = lib.uuid_generate_random
+        if hasattr(lib, 'uuid_generate_time'):
+            _uuid_generate_time = lib.uuid_generate_time
+
+    # On Windows prior to 2000, UuidCreate gives a UUID containing the
+    # hardware address.  On Windows 2000 and later, UuidCreate makes a
+    # random UUID and UuidCreateSequential gives a UUID containing the
+    # hardware address.  These routines are provided by the RPC runtime.
+    # NOTE:  at least on Tim's WinXP Pro SP2 desktop box, while the last
+    # 6 bytes returned by UuidCreateSequential are fixed, they don't appear
+    # to bear any relationship to the MAC address of any network device
+    # on the box.
+    try:
+        lib = ctypes.windll.rpcrt4
+    except:
+        lib = None
+    _UuidCreate = getattr(lib, 'UuidCreateSequential',
+                          getattr(lib, 'UuidCreate', None))
+except:
+    pass
+
+def _unixdll_getnode():
+    """Get the hardware address on Unix using ctypes."""
+    _uuid_generate_time(_buffer)
+    return UUID(bytes=_buffer.raw).node
+
+def _windll_getnode():
+    """Get the hardware address on Windows using ctypes."""
+    if _UuidCreate(_buffer) == 0:
+        return UUID(bytes=_buffer.raw).node
+
+def _random_getnode():
+    """Get a random node ID, with eighth bit set as suggested by RFC 4122."""
+    import random
+    return random.randrange(0, 1<<48L) | 0x010000000000L
+
+_node = None
+
+def getnode():
+    """Get the hardware address as a 48-bit positive integer.
+
+    The first time this runs, it may launch a separate program, which could
+    be quite slow.  If all attempts to obtain the hardware address fail, we
+    choose a random 48-bit number with its eighth bit set to 1 as recommended
+    in RFC 4122.
+    """
+
+    global _node
+    if _node is not None:
+        return _node
+
+    import sys
+    if sys.platform == 'win32':
+        getters = [_windll_getnode, _netbios_getnode, _ipconfig_getnode]
+    else:
+        getters = [_unixdll_getnode, _ifconfig_getnode]
+
+    for getter in getters + [_random_getnode]:
+        try:
+            _node = getter()
+        except:
+            continue
+        if _node is not None:
+            return _node
+
+_last_timestamp = None
+
+def uuid1(node=None, clock_seq=None):
+    """Generate a UUID from a host ID, sequence number, and the current time.
+    If 'node' is not given, getnode() is used to obtain the hardware
+    address.  If 'clock_seq' is given, it is used as the sequence number;
+    otherwise a random 14-bit sequence number is chosen."""
+
+    # When the system provides a version-1 UUID generator, use it (but don't
+    # use UuidCreate here because its UUIDs don't conform to RFC 4122).
+    if _uuid_generate_time and node is clock_seq is None:
+        _uuid_generate_time(_buffer)
+        return UUID(bytes=_buffer.raw)
+
+    global _last_timestamp
+    import time
+    nanoseconds = int(time.time() * 1e9)
+    # 0x01b21dd213814000 is the number of 100-ns intervals between the
+    # UUID epoch 1582-10-15 00:00:00 and the Unix epoch 1970-01-01 00:00:00.
+    timestamp = int(nanoseconds/100) + 0x01b21dd213814000L
+    if timestamp <= _last_timestamp:
+        timestamp = _last_timestamp + 1
+    _last_timestamp = timestamp
+    if clock_seq is None:
+        import random
+        clock_seq = random.randrange(1<<14L) # instead of stable storage
+    time_low = timestamp & 0xffffffffL
+    time_mid = (timestamp >> 32L) & 0xffffL
+    time_hi_version = (timestamp >> 48L) & 0x0fffL
+    clock_seq_low = clock_seq & 0xffL
+    clock_seq_hi_variant = (clock_seq >> 8L) & 0x3fL
+    if node is None:
+        node = getnode()
+    return UUID(fields=(time_low, time_mid, time_hi_version,
+                        clock_seq_hi_variant, clock_seq_low, node), version=1)
+
+def uuid3(namespace, name):
+    """Generate a UUID from the MD5 hash of a namespace UUID and a name."""
+    import md5
+    hash = md5.md5(namespace.bytes + name).digest()
+    return UUID(bytes=hash[:16], version=3)
+
+def uuid4():
+    """Generate a random UUID."""
+
+    # When the system provides a version-4 UUID generator, use it.
+    if _uuid_generate_random:
+        _uuid_generate_random(_buffer)
+        return UUID(bytes=_buffer.raw)
+
+    # Otherwise, get randomness from urandom or the 'random' module.
+    try:
+        import os
+        return UUID(bytes=os.urandom(16), version=4)
+    except:
+        import random
+        bytes = [chr(random.randrange(256)) for i in range(16)]
+        return UUID(bytes=bytes, version=4)
+
+def uuid5(namespace, name):
+    """Generate a UUID from the SHA-1 hash of a namespace UUID and a name."""
+    import sha
+    hash = sha.sha(namespace.bytes + name).digest()
+    return UUID(bytes=hash[:16], version=5)
+
+# The following standard UUIDs are for use with uuid3() or uuid5().
+
+NAMESPACE_DNS = UUID('6ba7b810-9dad-11d1-80b4-00c04fd430c8')
+NAMESPACE_URL = UUID('6ba7b811-9dad-11d1-80b4-00c04fd430c8')
+NAMESPACE_OID = UUID('6ba7b812-9dad-11d1-80b4-00c04fd430c8')
+NAMESPACE_X500 = UUID('6ba7b814-9dad-11d1-80b4-00c04fd430c8')

Added: vendor/Python/current/Lib/warnings.py
===================================================================
--- vendor/Python/current/Lib/warnings.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/warnings.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,264 @@
+"""Python part of the warnings subsystem."""
+
+# Note: function level imports should *not* be used
+# in this module as it may cause import lock deadlock.
+# See bug 683658.
+import sys, types
+import linecache
+
+__all__ = ["warn", "showwarning", "formatwarning", "filterwarnings",
+           "resetwarnings"]
+
+# filters contains a sequence of filter 5-tuples
+# The components of the 5-tuple are:
+# - an action: error, ignore, always, default, module, or once
+# - a compiled regex that must match the warning message
+# - a class representing the warning category
+# - a compiled regex that must match the module that is being warned
+# - a line number for the line being warning, or 0 to mean any line
+# If either if the compiled regexs are None, match anything.
+filters = []
+defaultaction = "default"
+onceregistry = {}
+
+def warn(message, category=None, stacklevel=1):
+    """Issue a warning, or maybe ignore it or raise an exception."""
+    # Check if message is already a Warning object
+    if isinstance(message, Warning):
+        category = message.__class__
+    # Check category argument
+    if category is None:
+        category = UserWarning
+    assert issubclass(category, Warning)
+    # Get context information
+    try:
+        caller = sys._getframe(stacklevel)
+    except ValueError:
+        globals = sys.__dict__
+        lineno = 1
+    else:
+        globals = caller.f_globals
+        lineno = caller.f_lineno
+    if '__name__' in globals:
+        module = globals['__name__']
+    else:
+        module = "<string>"
+    filename = globals.get('__file__')
+    if filename:
+        fnl = filename.lower()
+        if fnl.endswith((".pyc", ".pyo")):
+            filename = filename[:-1]
+    else:
+        if module == "__main__":
+            try:
+                filename = sys.argv[0]
+            except AttributeError:
+                # embedded interpreters don't have sys.argv, see bug #839151
+                filename = '__main__'
+        if not filename:
+            filename = module
+    registry = globals.setdefault("__warningregistry__", {})
+    warn_explicit(message, category, filename, lineno, module, registry,
+                  globals)
+
+def warn_explicit(message, category, filename, lineno,
+                  module=None, registry=None, module_globals=None):
+    if module is None:
+        module = filename or "<unknown>"
+        if module[-3:].lower() == ".py":
+            module = module[:-3] # XXX What about leading pathname?
+    if registry is None:
+        registry = {}
+    if isinstance(message, Warning):
+        text = str(message)
+        category = message.__class__
+    else:
+        text = message
+        message = category(message)
+    key = (text, category, lineno)
+    # Quick test for common case
+    if registry.get(key):
+        return
+    # Search the filters
+    for item in filters:
+        action, msg, cat, mod, ln = item
+        if ((msg is None or msg.match(text)) and
+            issubclass(category, cat) and
+            (mod is None or mod.match(module)) and
+            (ln == 0 or lineno == ln)):
+            break
+    else:
+        action = defaultaction
+    # Early exit actions
+    if action == "ignore":
+        registry[key] = 1
+        return
+
+    # Prime the linecache for formatting, in case the
+    # "file" is actually in a zipfile or something.
+    linecache.getlines(filename, module_globals)
+
+    if action == "error":
+        raise message
+    # Other actions
+    if action == "once":
+        registry[key] = 1
+        oncekey = (text, category)
+        if onceregistry.get(oncekey):
+            return
+        onceregistry[oncekey] = 1
+    elif action == "always":
+        pass
+    elif action == "module":
+        registry[key] = 1
+        altkey = (text, category, 0)
+        if registry.get(altkey):
+            return
+        registry[altkey] = 1
+    elif action == "default":
+        registry[key] = 1
+    else:
+        # Unrecognized actions are errors
+        raise RuntimeError(
+              "Unrecognized action (%r) in warnings.filters:\n %s" %
+              (action, item))
+    # Print message and context
+    showwarning(message, category, filename, lineno)
+
+def showwarning(message, category, filename, lineno, file=None):
+    """Hook to write a warning to a file; replace if you like."""
+    if file is None:
+        file = sys.stderr
+    try:
+        file.write(formatwarning(message, category, filename, lineno))
+    except IOError:
+        pass # the file (probably stderr) is invalid - this warning gets lost.
+
+def formatwarning(message, category, filename, lineno):
+    """Function to format a warning the standard way."""
+    s =  "%s:%s: %s: %s\n" % (filename, lineno, category.__name__, message)
+    line = linecache.getline(filename, lineno).strip()
+    if line:
+        s = s + "  " + line + "\n"
+    return s
+
+def filterwarnings(action, message="", category=Warning, module="", lineno=0,
+                   append=0):
+    """Insert an entry into the list of warnings filters (at the front).
+
+    Use assertions to check that all arguments have the right type."""
+    import re
+    assert action in ("error", "ignore", "always", "default", "module",
+                      "once"), "invalid action: %r" % (action,)
+    assert isinstance(message, basestring), "message must be a string"
+    assert isinstance(category, (type, types.ClassType)), \
+           "category must be a class"
+    assert issubclass(category, Warning), "category must be a Warning subclass"
+    assert isinstance(module, basestring), "module must be a string"
+    assert isinstance(lineno, int) and lineno >= 0, \
+           "lineno must be an int >= 0"
+    item = (action, re.compile(message, re.I), category,
+            re.compile(module), lineno)
+    if append:
+        filters.append(item)
+    else:
+        filters.insert(0, item)
+
+def simplefilter(action, category=Warning, lineno=0, append=0):
+    """Insert a simple entry into the list of warnings filters (at the front).
+
+    A simple filter matches all modules and messages.
+    """
+    assert action in ("error", "ignore", "always", "default", "module",
+                      "once"), "invalid action: %r" % (action,)
+    assert isinstance(lineno, int) and lineno >= 0, \
+           "lineno must be an int >= 0"
+    item = (action, None, category, None, lineno)
+    if append:
+        filters.append(item)
+    else:
+        filters.insert(0, item)
+
+def resetwarnings():
+    """Clear the list of warning filters, so that no filters are active."""
+    filters[:] = []
+
+class _OptionError(Exception):
+    """Exception used by option processing helpers."""
+    pass
+
+# Helper to process -W options passed via sys.warnoptions
+def _processoptions(args):
+    for arg in args:
+        try:
+            _setoption(arg)
+        except _OptionError, msg:
+            print >>sys.stderr, "Invalid -W option ignored:", msg
+
+# Helper for _processoptions()
+def _setoption(arg):
+    import re
+    parts = arg.split(':')
+    if len(parts) > 5:
+        raise _OptionError("too many fields (max 5): %r" % (arg,))
+    while len(parts) < 5:
+        parts.append('')
+    action, message, category, module, lineno = [s.strip()
+                                                 for s in parts]
+    action = _getaction(action)
+    message = re.escape(message)
+    category = _getcategory(category)
+    module = re.escape(module)
+    if module:
+        module = module + '$'
+    if lineno:
+        try:
+            lineno = int(lineno)
+            if lineno < 0:
+                raise ValueError
+        except (ValueError, OverflowError):
+            raise _OptionError("invalid lineno %r" % (lineno,))
+    else:
+        lineno = 0
+    filterwarnings(action, message, category, module, lineno)
+
+# Helper for _setoption()
+def _getaction(action):
+    if not action:
+        return "default"
+    if action == "all": return "always" # Alias
+    for a in ('default', 'always', 'ignore', 'module', 'once', 'error'):
+        if a.startswith(action):
+            return a
+    raise _OptionError("invalid action: %r" % (action,))
+
+# Helper for _setoption()
+def _getcategory(category):
+    import re
+    if not category:
+        return Warning
+    if re.match("^[a-zA-Z0-9_]+$", category):
+        try:
+            cat = eval(category)
+        except NameError:
+            raise _OptionError("unknown warning category: %r" % (category,))
+    else:
+        i = category.rfind(".")
+        module = category[:i]
+        klass = category[i+1:]
+        try:
+            m = __import__(module, None, None, [klass])
+        except ImportError:
+            raise _OptionError("invalid module name: %r" % (module,))
+        try:
+            cat = getattr(m, klass)
+        except AttributeError:
+            raise _OptionError("unknown warning category: %r" % (category,))
+    if not issubclass(cat, Warning):
+        raise _OptionError("invalid warning category: %r" % (category,))
+    return cat
+
+# Module initialization
+_processoptions(sys.warnoptions)
+simplefilter("ignore", category=PendingDeprecationWarning, append=1)
+simplefilter("ignore", category=ImportWarning, append=1)

Added: vendor/Python/current/Lib/wave.py
===================================================================
--- vendor/Python/current/Lib/wave.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/wave.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,499 @@
+"""Stuff to parse WAVE files.
+
+Usage.
+
+Reading WAVE files:
+      f = wave.open(file, 'r')
+where file is either the name of a file or an open file pointer.
+The open file pointer must have methods read(), seek(), and close().
+When the setpos() and rewind() methods are not used, the seek()
+method is not  necessary.
+
+This returns an instance of a class with the following public methods:
+      getnchannels()  -- returns number of audio channels (1 for
+                         mono, 2 for stereo)
+      getsampwidth()  -- returns sample width in bytes
+      getframerate()  -- returns sampling frequency
+      getnframes()    -- returns number of audio frames
+      getcomptype()   -- returns compression type ('NONE' for linear samples)
+      getcompname()   -- returns human-readable version of
+                         compression type ('not compressed' linear samples)
+      getparams()     -- returns a tuple consisting of all of the
+                         above in the above order
+      getmarkers()    -- returns None (for compatibility with the
+                         aifc module)
+      getmark(id)     -- raises an error since the mark does not
+                         exist (for compatibility with the aifc module)
+      readframes(n)   -- returns at most n frames of audio
+      rewind()        -- rewind to the beginning of the audio stream
+      setpos(pos)     -- seek to the specified position
+      tell()          -- return the current position
+      close()         -- close the instance (make it unusable)
+The position returned by tell() and the position given to setpos()
+are compatible and have nothing to do with the actual position in the
+file.
+The close() method is called automatically when the class instance
+is destroyed.
+
+Writing WAVE files:
+      f = wave.open(file, 'w')
+where file is either the name of a file or an open file pointer.
+The open file pointer must have methods write(), tell(), seek(), and
+close().
+
+This returns an instance of a class with the following public methods:
+      setnchannels(n) -- set the number of channels
+      setsampwidth(n) -- set the sample width
+      setframerate(n) -- set the frame rate
+      setnframes(n)   -- set the number of frames
+      setcomptype(type, name)
+                      -- set the compression type and the
+                         human-readable compression type
+      setparams(tuple)
+                      -- set all parameters at once
+      tell()          -- return current position in output file
+      writeframesraw(data)
+                      -- write audio frames without pathing up the
+                         file header
+      writeframes(data)
+                      -- write audio frames and patch up the file header
+      close()         -- patch up the file header and close the
+                         output file
+You should set the parameters before the first writeframesraw or
+writeframes.  The total number of frames does not need to be set,
+but when it is set to the correct value, the header does not have to
+be patched up.
+It is best to first set all parameters, perhaps possibly the
+compression type, and then write audio frames using writeframesraw.
+When all frames have been written, either call writeframes('') or
+close() to patch up the sizes in the header.
+The close() method is called automatically when the class instance
+is destroyed.
+"""
+
+import __builtin__
+
+__all__ = ["open", "openfp", "Error"]
+
+class Error(Exception):
+    pass
+
+WAVE_FORMAT_PCM = 0x0001
+
+_array_fmts = None, 'b', 'h', None, 'l'
+
+# Determine endian-ness
+import struct
+if struct.pack("h", 1) == "\000\001":
+    big_endian = 1
+else:
+    big_endian = 0
+
+from chunk import Chunk
+
+class Wave_read:
+    """Variables used in this class:
+
+    These variables are available to the user though appropriate
+    methods of this class:
+    _file -- the open file with methods read(), close(), and seek()
+              set through the __init__() method
+    _nchannels -- the number of audio channels
+              available through the getnchannels() method
+    _nframes -- the number of audio frames
+              available through the getnframes() method
+    _sampwidth -- the number of bytes per audio sample
+              available through the getsampwidth() method
+    _framerate -- the sampling frequency
+              available through the getframerate() method
+    _comptype -- the AIFF-C compression type ('NONE' if AIFF)
+              available through the getcomptype() method
+    _compname -- the human-readable AIFF-C compression type
+              available through the getcomptype() method
+    _soundpos -- the position in the audio stream
+              available through the tell() method, set through the
+              setpos() method
+
+    These variables are used internally only:
+    _fmt_chunk_read -- 1 iff the FMT chunk has been read
+    _data_seek_needed -- 1 iff positioned correctly in audio
+              file for readframes()
+    _data_chunk -- instantiation of a chunk class for the DATA chunk
+    _framesize -- size of one frame in the file
+    """
+
+    def initfp(self, file):
+        self._convert = None
+        self._soundpos = 0
+        self._file = Chunk(file, bigendian = 0)
+        if self._file.getname() != 'RIFF':
+            raise Error, 'file does not start with RIFF id'
+        if self._file.read(4) != 'WAVE':
+            raise Error, 'not a WAVE file'
+        self._fmt_chunk_read = 0
+        self._data_chunk = None
+        while 1:
+            self._data_seek_needed = 1
+            try:
+                chunk = Chunk(self._file, bigendian = 0)
+            except EOFError:
+                break
+            chunkname = chunk.getname()
+            if chunkname == 'fmt ':
+                self._read_fmt_chunk(chunk)
+                self._fmt_chunk_read = 1
+            elif chunkname == 'data':
+                if not self._fmt_chunk_read:
+                    raise Error, 'data chunk before fmt chunk'
+                self._data_chunk = chunk
+                self._nframes = chunk.chunksize // self._framesize
+                self._data_seek_needed = 0
+                break
+            chunk.skip()
+        if not self._fmt_chunk_read or not self._data_chunk:
+            raise Error, 'fmt chunk and/or data chunk missing'
+
+    def __init__(self, f):
+        self._i_opened_the_file = None
+        if isinstance(f, basestring):
+            f = __builtin__.open(f, 'rb')
+            self._i_opened_the_file = f
+        # else, assume it is an open file object already
+        try:
+            self.initfp(f)
+        except:
+            if self._i_opened_the_file:
+                f.close()
+            raise
+
+    def __del__(self):
+        self.close()
+    #
+    # User visible methods.
+    #
+    def getfp(self):
+        return self._file
+
+    def rewind(self):
+        self._data_seek_needed = 1
+        self._soundpos = 0
+
+    def close(self):
+        if self._i_opened_the_file:
+            self._i_opened_the_file.close()
+            self._i_opened_the_file = None
+        self._file = None
+
+    def tell(self):
+        return self._soundpos
+
+    def getnchannels(self):
+        return self._nchannels
+
+    def getnframes(self):
+        return self._nframes
+
+    def getsampwidth(self):
+        return self._sampwidth
+
+    def getframerate(self):
+        return self._framerate
+
+    def getcomptype(self):
+        return self._comptype
+
+    def getcompname(self):
+        return self._compname
+
+    def getparams(self):
+        return self.getnchannels(), self.getsampwidth(), \
+               self.getframerate(), self.getnframes(), \
+               self.getcomptype(), self.getcompname()
+
+    def getmarkers(self):
+        return None
+
+    def getmark(self, id):
+        raise Error, 'no marks'
+
+    def setpos(self, pos):
+        if pos < 0 or pos > self._nframes:
+            raise Error, 'position not in range'
+        self._soundpos = pos
+        self._data_seek_needed = 1
+
+    def readframes(self, nframes):
+        if self._data_seek_needed:
+            self._data_chunk.seek(0, 0)
+            pos = self._soundpos * self._framesize
+            if pos:
+                self._data_chunk.seek(pos, 0)
+            self._data_seek_needed = 0
+        if nframes == 0:
+            return ''
+        if self._sampwidth > 1 and big_endian:
+            # unfortunately the fromfile() method does not take
+            # something that only looks like a file object, so
+            # we have to reach into the innards of the chunk object
+            import array
+            chunk = self._data_chunk
+            data = array.array(_array_fmts[self._sampwidth])
+            nitems = nframes * self._nchannels
+            if nitems * self._sampwidth > chunk.chunksize - chunk.size_read:
+                nitems = (chunk.chunksize - chunk.size_read) / self._sampwidth
+            data.fromfile(chunk.file.file, nitems)
+            # "tell" data chunk how much was read
+            chunk.size_read = chunk.size_read + nitems * self._sampwidth
+            # do the same for the outermost chunk
+            chunk = chunk.file
+            chunk.size_read = chunk.size_read + nitems * self._sampwidth
+            data.byteswap()
+            data = data.tostring()
+        else:
+            data = self._data_chunk.read(nframes * self._framesize)
+        if self._convert and data:
+            data = self._convert(data)
+        self._soundpos = self._soundpos + len(data) // (self._nchannels * self._sampwidth)
+        return data
+
+    #
+    # Internal methods.
+    #
+
+    def _read_fmt_chunk(self, chunk):
+        wFormatTag, self._nchannels, self._framerate, dwAvgBytesPerSec, wBlockAlign = struct.unpack('<hhllh', chunk.read(14))
+        if wFormatTag == WAVE_FORMAT_PCM:
+            sampwidth = struct.unpack('<h', chunk.read(2))[0]
+            self._sampwidth = (sampwidth + 7) // 8
+        else:
+            raise Error, 'unknown format: %r' % (wFormatTag,)
+        self._framesize = self._nchannels * self._sampwidth
+        self._comptype = 'NONE'
+        self._compname = 'not compressed'
+
+class Wave_write:
+    """Variables used in this class:
+
+    These variables are user settable through appropriate methods
+    of this class:
+    _file -- the open file with methods write(), close(), tell(), seek()
+              set through the __init__() method
+    _comptype -- the AIFF-C compression type ('NONE' in AIFF)
+              set through the setcomptype() or setparams() method
+    _compname -- the human-readable AIFF-C compression type
+              set through the setcomptype() or setparams() method
+    _nchannels -- the number of audio channels
+              set through the setnchannels() or setparams() method
+    _sampwidth -- the number of bytes per audio sample
+              set through the setsampwidth() or setparams() method
+    _framerate -- the sampling frequency
+              set through the setframerate() or setparams() method
+    _nframes -- the number of audio frames written to the header
+              set through the setnframes() or setparams() method
+
+    These variables are used internally only:
+    _datalength -- the size of the audio samples written to the header
+    _nframeswritten -- the number of frames actually written
+    _datawritten -- the size of the audio samples actually written
+    """
+
+    def __init__(self, f):
+        self._i_opened_the_file = None
+        if isinstance(f, basestring):
+            f = __builtin__.open(f, 'wb')
+            self._i_opened_the_file = f
+        try:
+            self.initfp(f)
+        except:
+            if self._i_opened_the_file:
+                f.close()
+            raise
+
+    def initfp(self, file):
+        self._file = file
+        self._convert = None
+        self._nchannels = 0
+        self._sampwidth = 0
+        self._framerate = 0
+        self._nframes = 0
+        self._nframeswritten = 0
+        self._datawritten = 0
+        self._datalength = 0
+
+    def __del__(self):
+        self.close()
+
+    #
+    # User visible methods.
+    #
+    def setnchannels(self, nchannels):
+        if self._datawritten:
+            raise Error, 'cannot change parameters after starting to write'
+        if nchannels < 1:
+            raise Error, 'bad # of channels'
+        self._nchannels = nchannels
+
+    def getnchannels(self):
+        if not self._nchannels:
+            raise Error, 'number of channels not set'
+        return self._nchannels
+
+    def setsampwidth(self, sampwidth):
+        if self._datawritten:
+            raise Error, 'cannot change parameters after starting to write'
+        if sampwidth < 1 or sampwidth > 4:
+            raise Error, 'bad sample width'
+        self._sampwidth = sampwidth
+
+    def getsampwidth(self):
+        if not self._sampwidth:
+            raise Error, 'sample width not set'
+        return self._sampwidth
+
+    def setframerate(self, framerate):
+        if self._datawritten:
+            raise Error, 'cannot change parameters after starting to write'
+        if framerate <= 0:
+            raise Error, 'bad frame rate'
+        self._framerate = framerate
+
+    def getframerate(self):
+        if not self._framerate:
+            raise Error, 'frame rate not set'
+        return self._framerate
+
+    def setnframes(self, nframes):
+        if self._datawritten:
+            raise Error, 'cannot change parameters after starting to write'
+        self._nframes = nframes
+
+    def getnframes(self):
+        return self._nframeswritten
+
+    def setcomptype(self, comptype, compname):
+        if self._datawritten:
+            raise Error, 'cannot change parameters after starting to write'
+        if comptype not in ('NONE',):
+            raise Error, 'unsupported compression type'
+        self._comptype = comptype
+        self._compname = compname
+
+    def getcomptype(self):
+        return self._comptype
+
+    def getcompname(self):
+        return self._compname
+
+    def setparams(self, (nchannels, sampwidth, framerate, nframes, comptype, compname)):
+        if self._datawritten:
+            raise Error, 'cannot change parameters after starting to write'
+        self.setnchannels(nchannels)
+        self.setsampwidth(sampwidth)
+        self.setframerate(framerate)
+        self.setnframes(nframes)
+        self.setcomptype(comptype, compname)
+
+    def getparams(self):
+        if not self._nchannels or not self._sampwidth or not self._framerate:
+            raise Error, 'not all parameters set'
+        return self._nchannels, self._sampwidth, self._framerate, \
+              self._nframes, self._comptype, self._compname
+
+    def setmark(self, id, pos, name):
+        raise Error, 'setmark() not supported'
+
+    def getmark(self, id):
+        raise Error, 'no marks'
+
+    def getmarkers(self):
+        return None
+
+    def tell(self):
+        return self._nframeswritten
+
+    def writeframesraw(self, data):
+        self._ensure_header_written(len(data))
+        nframes = len(data) // (self._sampwidth * self._nchannels)
+        if self._convert:
+            data = self._convert(data)
+        if self._sampwidth > 1 and big_endian:
+            import array
+            data = array.array(_array_fmts[self._sampwidth], data)
+            data.byteswap()
+            data.tofile(self._file)
+            self._datawritten = self._datawritten + len(data) * self._sampwidth
+        else:
+            self._file.write(data)
+            self._datawritten = self._datawritten + len(data)
+        self._nframeswritten = self._nframeswritten + nframes
+
+    def writeframes(self, data):
+        self.writeframesraw(data)
+        if self._datalength != self._datawritten:
+            self._patchheader()
+
+    def close(self):
+        if self._file:
+            self._ensure_header_written(0)
+            if self._datalength != self._datawritten:
+                self._patchheader()
+            self._file.flush()
+            self._file = None
+        if self._i_opened_the_file:
+            self._i_opened_the_file.close()
+            self._i_opened_the_file = None
+
+    #
+    # Internal methods.
+    #
+
+    def _ensure_header_written(self, datasize):
+        if not self._datawritten:
+            if not self._nchannels:
+                raise Error, '# channels not specified'
+            if not self._sampwidth:
+                raise Error, 'sample width not specified'
+            if not self._framerate:
+                raise Error, 'sampling rate not specified'
+            self._write_header(datasize)
+
+    def _write_header(self, initlength):
+        self._file.write('RIFF')
+        if not self._nframes:
+            self._nframes = initlength / (self._nchannels * self._sampwidth)
+        self._datalength = self._nframes * self._nchannels * self._sampwidth
+        self._form_length_pos = self._file.tell()
+        self._file.write(struct.pack('<l4s4slhhllhh4s',
+            36 + self._datalength, 'WAVE', 'fmt ', 16,
+            WAVE_FORMAT_PCM, self._nchannels, self._framerate,
+            self._nchannels * self._framerate * self._sampwidth,
+            self._nchannels * self._sampwidth,
+            self._sampwidth * 8, 'data'))
+        self._data_length_pos = self._file.tell()
+        self._file.write(struct.pack('<l', self._datalength))
+
+    def _patchheader(self):
+        if self._datawritten == self._datalength:
+            return
+        curpos = self._file.tell()
+        self._file.seek(self._form_length_pos, 0)
+        self._file.write(struct.pack('<l', 36 + self._datawritten))
+        self._file.seek(self._data_length_pos, 0)
+        self._file.write(struct.pack('<l', self._datawritten))
+        self._file.seek(curpos, 0)
+        self._datalength = self._datawritten
+
+def open(f, mode=None):
+    if mode is None:
+        if hasattr(f, 'mode'):
+            mode = f.mode
+        else:
+            mode = 'rb'
+    if mode in ('r', 'rb'):
+        return Wave_read(f)
+    elif mode in ('w', 'wb'):
+        return Wave_write(f)
+    else:
+        raise Error, "mode must be 'r', 'rb', 'w', or 'wb'"
+
+openfp = open # B/W compatibility

Added: vendor/Python/current/Lib/weakref.py
===================================================================
--- vendor/Python/current/Lib/weakref.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/weakref.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,355 @@
+"""Weak reference support for Python.
+
+This module is an implementation of PEP 205:
+
+http://python.sourceforge.net/peps/pep-0205.html
+"""
+
+# Naming convention: Variables named "wr" are weak reference objects;
+# they are called this instead of "ref" to avoid name collisions with
+# the module-global ref() function imported from _weakref.
+
+import UserDict
+
+from _weakref import (
+     getweakrefcount,
+     getweakrefs,
+     ref,
+     proxy,
+     CallableProxyType,
+     ProxyType,
+     ReferenceType)
+
+from exceptions import ReferenceError
+
+
+ProxyTypes = (ProxyType, CallableProxyType)
+
+__all__ = ["ref", "proxy", "getweakrefcount", "getweakrefs",
+           "WeakKeyDictionary", "ReferenceType", "ProxyType",
+           "CallableProxyType", "ProxyTypes", "WeakValueDictionary"]
+
+
+class WeakValueDictionary(UserDict.UserDict):
+    """Mapping class that references values weakly.
+
+    Entries in the dictionary will be discarded when no strong
+    reference to the value exists anymore
+    """
+    # We inherit the constructor without worrying about the input
+    # dictionary; since it uses our .update() method, we get the right
+    # checks (if the other dictionary is a WeakValueDictionary,
+    # objects are unwrapped on the way out, and we always wrap on the
+    # way in).
+
+    def __init__(self, *args, **kw):
+        def remove(wr, selfref=ref(self)):
+            self = selfref()
+            if self is not None:
+                del self.data[wr.key]
+        self._remove = remove
+        UserDict.UserDict.__init__(self, *args, **kw)
+
+    def __getitem__(self, key):
+        o = self.data[key]()
+        if o is None:
+            raise KeyError, key
+        else:
+            return o
+
+    def __contains__(self, key):
+        try:
+            o = self.data[key]()
+        except KeyError:
+            return False
+        return o is not None
+
+    def has_key(self, key):
+        try:
+            o = self.data[key]()
+        except KeyError:
+            return False
+        return o is not None
+
+    def __repr__(self):
+        return "<WeakValueDictionary at %s>" % id(self)
+
+    def __setitem__(self, key, value):
+        self.data[key] = KeyedRef(value, self._remove, key)
+
+    def copy(self):
+        new = WeakValueDictionary()
+        for key, wr in self.data.items():
+            o = wr()
+            if o is not None:
+                new[key] = o
+        return new
+
+    def get(self, key, default=None):
+        try:
+            wr = self.data[key]
+        except KeyError:
+            return default
+        else:
+            o = wr()
+            if o is None:
+                # This should only happen
+                return default
+            else:
+                return o
+
+    def items(self):
+        L = []
+        for key, wr in self.data.items():
+            o = wr()
+            if o is not None:
+                L.append((key, o))
+        return L
+
+    def iteritems(self):
+        for wr in self.data.itervalues():
+            value = wr()
+            if value is not None:
+                yield wr.key, value
+
+    def iterkeys(self):
+        return self.data.iterkeys()
+
+    def __iter__(self):
+        return self.data.iterkeys()
+
+    def itervaluerefs(self):
+        """Return an iterator that yields the weak references to the values.
+
+        The references are not guaranteed to be 'live' at the time
+        they are used, so the result of calling the references needs
+        to be checked before being used.  This can be used to avoid
+        creating references that will cause the garbage collector to
+        keep the values around longer than needed.
+
+        """
+        return self.data.itervalues()
+
+    def itervalues(self):
+        for wr in self.data.itervalues():
+            obj = wr()
+            if obj is not None:
+                yield obj
+
+    def popitem(self):
+        while 1:
+            key, wr = self.data.popitem()
+            o = wr()
+            if o is not None:
+                return key, o
+
+    def pop(self, key, *args):
+        try:
+            o = self.data.pop(key)()
+        except KeyError:
+            if args:
+                return args[0]
+            raise
+        if o is None:
+            raise KeyError, key
+        else:
+            return o
+
+    def setdefault(self, key, default=None):
+        try:
+            wr = self.data[key]
+        except KeyError:
+            self.data[key] = KeyedRef(default, self._remove, key)
+            return default
+        else:
+            return wr()
+
+    def update(self, dict=None, **kwargs):
+        d = self.data
+        if dict is not None:
+            if not hasattr(dict, "items"):
+                dict = type({})(dict)
+            for key, o in dict.items():
+                d[key] = KeyedRef(o, self._remove, key)
+        if len(kwargs):
+            self.update(kwargs)
+
+    def valuerefs(self):
+        """Return a list of weak references to the values.
+
+        The references are not guaranteed to be 'live' at the time
+        they are used, so the result of calling the references needs
+        to be checked before being used.  This can be used to avoid
+        creating references that will cause the garbage collector to
+        keep the values around longer than needed.
+
+        """
+        return self.data.values()
+
+    def values(self):
+        L = []
+        for wr in self.data.values():
+            o = wr()
+            if o is not None:
+                L.append(o)
+        return L
+
+
+class KeyedRef(ref):
+    """Specialized reference that includes a key corresponding to the value.
+
+    This is used in the WeakValueDictionary to avoid having to create
+    a function object for each key stored in the mapping.  A shared
+    callback object can use the 'key' attribute of a KeyedRef instead
+    of getting a reference to the key from an enclosing scope.
+
+    """
+
+    __slots__ = "key",
+
+    def __new__(type, ob, callback, key):
+        self = ref.__new__(type, ob, callback)
+        self.key = key
+        return self
+
+    def __init__(self, ob, callback, key):
+        super(KeyedRef,  self).__init__(ob, callback)
+
+
+class WeakKeyDictionary(UserDict.UserDict):
+    """ Mapping class that references keys weakly.
+
+    Entries in the dictionary will be discarded when there is no
+    longer a strong reference to the key. This can be used to
+    associate additional data with an object owned by other parts of
+    an application without adding attributes to those objects. This
+    can be especially useful with objects that override attribute
+    accesses.
+    """
+
+    def __init__(self, dict=None):
+        self.data = {}
+        def remove(k, selfref=ref(self)):
+            self = selfref()
+            if self is not None:
+                del self.data[k]
+        self._remove = remove
+        if dict is not None: self.update(dict)
+
+    def __delitem__(self, key):
+        del self.data[ref(key)]
+
+    def __getitem__(self, key):
+        return self.data[ref(key)]
+
+    def __repr__(self):
+        return "<WeakKeyDictionary at %s>" % id(self)
+
+    def __setitem__(self, key, value):
+        self.data[ref(key, self._remove)] = value
+
+    def copy(self):
+        new = WeakKeyDictionary()
+        for key, value in self.data.items():
+            o = key()
+            if o is not None:
+                new[o] = value
+        return new
+
+    def get(self, key, default=None):
+        return self.data.get(ref(key),default)
+
+    def has_key(self, key):
+        try:
+            wr = ref(key)
+        except TypeError:
+            return 0
+        return wr in self.data
+
+    def __contains__(self, key):
+        try:
+            wr = ref(key)
+        except TypeError:
+            return 0
+        return wr in self.data
+
+    def items(self):
+        L = []
+        for key, value in self.data.items():
+            o = key()
+            if o is not None:
+                L.append((o, value))
+        return L
+
+    def iteritems(self):
+        for wr, value in self.data.iteritems():
+            key = wr()
+            if key is not None:
+                yield key, value
+
+    def iterkeyrefs(self):
+        """Return an iterator that yields the weak references to the keys.
+
+        The references are not guaranteed to be 'live' at the time
+        they are used, so the result of calling the references needs
+        to be checked before being used.  This can be used to avoid
+        creating references that will cause the garbage collector to
+        keep the keys around longer than needed.
+
+        """
+        return self.data.iterkeys()
+
+    def iterkeys(self):
+        for wr in self.data.iterkeys():
+            obj = wr()
+            if obj is not None:
+                yield obj
+
+    def __iter__(self):
+        return self.iterkeys()
+
+    def itervalues(self):
+        return self.data.itervalues()
+
+    def keyrefs(self):
+        """Return a list of weak references to the keys.
+
+        The references are not guaranteed to be 'live' at the time
+        they are used, so the result of calling the references needs
+        to be checked before being used.  This can be used to avoid
+        creating references that will cause the garbage collector to
+        keep the keys around longer than needed.
+
+        """
+        return self.data.keys()
+
+    def keys(self):
+        L = []
+        for wr in self.data.keys():
+            o = wr()
+            if o is not None:
+                L.append(o)
+        return L
+
+    def popitem(self):
+        while 1:
+            key, value = self.data.popitem()
+            o = key()
+            if o is not None:
+                return o, value
+
+    def pop(self, key, *args):
+        return self.data.pop(ref(key), *args)
+
+    def setdefault(self, key, default=None):
+        return self.data.setdefault(ref(key, self._remove),default)
+
+    def update(self, dict=None, **kwargs):
+        d = self.data
+        if dict is not None:
+            if not hasattr(dict, "items"):
+                dict = type({})(dict)
+            for key, value in dict.items():
+                d[ref(key, self._remove)] = value
+        if len(kwargs):
+            self.update(kwargs)

Added: vendor/Python/current/Lib/webbrowser.py
===================================================================
--- vendor/Python/current/Lib/webbrowser.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/webbrowser.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,651 @@
+#! /usr/bin/env python
+"""Interfaces for launching and remotely controlling Web browsers."""
+
+import os
+import shlex
+import sys
+import stat
+import subprocess
+import time
+
+__all__ = ["Error", "open", "open_new", "open_new_tab", "get", "register"]
+
+class Error(Exception):
+    pass
+
+_browsers = {}          # Dictionary of available browser controllers
+_tryorder = []          # Preference order of available browsers
+
+def register(name, klass, instance=None, update_tryorder=1):
+    """Register a browser connector and, optionally, connection."""
+    _browsers[name.lower()] = [klass, instance]
+    if update_tryorder > 0:
+        _tryorder.append(name)
+    elif update_tryorder < 0:
+        _tryorder.insert(0, name)
+
+def get(using=None):
+    """Return a browser launcher instance appropriate for the environment."""
+    if using is not None:
+        alternatives = [using]
+    else:
+        alternatives = _tryorder
+    for browser in alternatives:
+        if '%s' in browser:
+            # User gave us a command line, split it into name and args
+            browser = shlex.split(browser)
+            if browser[-1] == '&':
+                return BackgroundBrowser(browser[:-1])
+            else:
+                return GenericBrowser(browser)
+        else:
+            # User gave us a browser name or path.
+            try:
+                command = _browsers[browser.lower()]
+            except KeyError:
+                command = _synthesize(browser)
+            if command[1] is not None:
+                return command[1]
+            elif command[0] is not None:
+                return command[0]()
+    raise Error("could not locate runnable browser")
+
+# Please note: the following definition hides a builtin function.
+# It is recommended one does "import webbrowser" and uses webbrowser.open(url)
+# instead of "from webbrowser import *".
+
+def open(url, new=0, autoraise=1):
+    for name in _tryorder:
+        browser = get(name)
+        if browser.open(url, new, autoraise):
+            return True
+    return False
+
+def open_new(url):
+    return open(url, 1)
+
+def open_new_tab(url):
+    return open(url, 2)
+
+
+def _synthesize(browser, update_tryorder=1):
+    """Attempt to synthesize a controller base on existing controllers.
+
+    This is useful to create a controller when a user specifies a path to
+    an entry in the BROWSER environment variable -- we can copy a general
+    controller to operate using a specific installation of the desired
+    browser in this way.
+
+    If we can't create a controller in this way, or if there is no
+    executable for the requested browser, return [None, None].
+
+    """
+    cmd = browser.split()[0]
+    if not _iscommand(cmd):
+        return [None, None]
+    name = os.path.basename(cmd)
+    try:
+        command = _browsers[name.lower()]
+    except KeyError:
+        return [None, None]
+    # now attempt to clone to fit the new name:
+    controller = command[1]
+    if controller and name.lower() == controller.basename:
+        import copy
+        controller = copy.copy(controller)
+        controller.name = browser
+        controller.basename = os.path.basename(browser)
+        register(browser, None, controller, update_tryorder)
+        return [None, controller]
+    return [None, None]
+
+
+if sys.platform[:3] == "win":
+    def _isexecutable(cmd):
+        cmd = cmd.lower()
+        if os.path.isfile(cmd) and cmd.endswith((".exe", ".bat")):
+            return True
+        for ext in ".exe", ".bat":
+            if os.path.isfile(cmd + ext):
+                return True
+        return False
+else:
+    def _isexecutable(cmd):
+        if os.path.isfile(cmd):
+            mode = os.stat(cmd)[stat.ST_MODE]
+            if mode & stat.S_IXUSR or mode & stat.S_IXGRP or mode & stat.S_IXOTH:
+                return True
+        return False
+
+def _iscommand(cmd):
+    """Return True if cmd is executable or can be found on the executable
+    search path."""
+    if _isexecutable(cmd):
+        return True
+    path = os.environ.get("PATH")
+    if not path:
+        return False
+    for d in path.split(os.pathsep):
+        exe = os.path.join(d, cmd)
+        if _isexecutable(exe):
+            return True
+    return False
+
+
+# General parent classes
+
+class BaseBrowser(object):
+    """Parent class for all browsers. Do not use directly."""
+
+    args = ['%s']
+
+    def __init__(self, name=""):
+        self.name = name
+        self.basename = name
+
+    def open(self, url, new=0, autoraise=1):
+        raise NotImplementedError
+
+    def open_new(self, url):
+        return self.open(url, 1)
+
+    def open_new_tab(self, url):
+        return self.open(url, 2)
+
+
+class GenericBrowser(BaseBrowser):
+    """Class for all browsers started with a command
+       and without remote functionality."""
+
+    def __init__(self, name):
+        if isinstance(name, basestring):
+            self.name = name
+        else:
+            # name should be a list with arguments
+            self.name = name[0]
+            self.args = name[1:]
+        self.basename = os.path.basename(self.name)
+
+    def open(self, url, new=0, autoraise=1):
+        cmdline = [self.name] + [arg.replace("%s", url)
+                                 for arg in self.args]
+        try:
+            if sys.platform[:3] == 'win':
+                p = subprocess.Popen(cmdline)
+            else:
+                p = subprocess.Popen(cmdline, close_fds=True)
+            return not p.wait()
+        except OSError:
+            return False
+
+
+class BackgroundBrowser(GenericBrowser):
+    """Class for all browsers which are to be started in the
+       background."""
+
+    def open(self, url, new=0, autoraise=1):
+        cmdline = [self.name] + [arg.replace("%s", url)
+                                 for arg in self.args]
+        try:
+            if sys.platform[:3] == 'win':
+                p = subprocess.Popen(cmdline)
+            else:
+                setsid = getattr(os, 'setsid', None)
+                if not setsid:
+                    setsid = getattr(os, 'setpgrp', None)
+                p = subprocess.Popen(cmdline, close_fds=True, preexec_fn=setsid)
+            return (p.poll() is None)
+        except OSError:
+            return False
+
+
+class UnixBrowser(BaseBrowser):
+    """Parent class for all Unix browsers with remote functionality."""
+
+    raise_opts = None
+    remote_args = ['%action', '%s']
+    remote_action = None
+    remote_action_newwin = None
+    remote_action_newtab = None
+    background = False
+    redirect_stdout = True
+
+    def _invoke(self, args, remote, autoraise):
+        raise_opt = []
+        if remote and self.raise_opts:
+            # use autoraise argument only for remote invocation
+            autoraise = int(bool(autoraise))
+            opt = self.raise_opts[autoraise]
+            if opt: raise_opt = [opt]
+
+        cmdline = [self.name] + raise_opt + args
+
+        if remote or self.background:
+            inout = file(os.devnull, "r+")
+        else:
+            # for TTY browsers, we need stdin/out
+            inout = None
+        # if possible, put browser in separate process group, so
+        # keyboard interrupts don't affect browser as well as Python
+        setsid = getattr(os, 'setsid', None)
+        if not setsid:
+            setsid = getattr(os, 'setpgrp', None)
+
+        p = subprocess.Popen(cmdline, close_fds=True, stdin=inout,
+                             stdout=(self.redirect_stdout and inout or None),
+                             stderr=inout, preexec_fn=setsid)
+        if remote:
+            # wait five secons. If the subprocess is not finished, the
+            # remote invocation has (hopefully) started a new instance.
+            time.sleep(1)
+            rc = p.poll()
+            if rc is None:
+                time.sleep(4)
+                rc = p.poll()
+                if rc is None:
+                    return True
+            # if remote call failed, open() will try direct invocation
+            return not rc
+        elif self.background:
+            if p.poll() is None:
+                return True
+            else:
+                return False
+        else:
+            return not p.wait()
+
+    def open(self, url, new=0, autoraise=1):
+        if new == 0:
+            action = self.remote_action
+        elif new == 1:
+            action = self.remote_action_newwin
+        elif new == 2:
+            if self.remote_action_newtab is None:
+                action = self.remote_action_newwin
+            else:
+                action = self.remote_action_newtab
+        else:
+            raise Error("Bad 'new' parameter to open(); " +
+                        "expected 0, 1, or 2, got %s" % new)
+
+        args = [arg.replace("%s", url).replace("%action", action)
+                for arg in self.remote_args]
+        success = self._invoke(args, True, autoraise)
+        if not success:
+            # remote invocation failed, try straight way
+            args = [arg.replace("%s", url) for arg in self.args]
+            return self._invoke(args, False, False)
+        else:
+            return True
+
+
+class Mozilla(UnixBrowser):
+    """Launcher class for Mozilla/Netscape browsers."""
+
+    raise_opts = ["-noraise", "-raise"]
+
+    remote_args = ['-remote', 'openURL(%s%action)']
+    remote_action = ""
+    remote_action_newwin = ",new-window"
+    remote_action_newtab = ",new-tab"
+
+    background = True
+
+Netscape = Mozilla
+
+
+class Galeon(UnixBrowser):
+    """Launcher class for Galeon/Epiphany browsers."""
+
+    raise_opts = ["-noraise", ""]
+    remote_args = ['%action', '%s']
+    remote_action = "-n"
+    remote_action_newwin = "-w"
+
+    background = True
+
+
+class Opera(UnixBrowser):
+    "Launcher class for Opera browser."
+
+    raise_opts = ["", "-raise"]
+
+    remote_args = ['-remote', 'openURL(%s%action)']
+    remote_action = ""
+    remote_action_newwin = ",new-window"
+    remote_action_newtab = ",new-page"
+    background = True
+
+
+class Elinks(UnixBrowser):
+    "Launcher class for Elinks browsers."
+
+    remote_args = ['-remote', 'openURL(%s%action)']
+    remote_action = ""
+    remote_action_newwin = ",new-window"
+    remote_action_newtab = ",new-tab"
+    background = False
+
+    # elinks doesn't like its stdout to be redirected -
+    # it uses redirected stdout as a signal to do -dump
+    redirect_stdout = False
+
+
+class Konqueror(BaseBrowser):
+    """Controller for the KDE File Manager (kfm, or Konqueror).
+
+    See the output of ``kfmclient --commands``
+    for more information on the Konqueror remote-control interface.
+    """
+
+    def open(self, url, new=0, autoraise=1):
+        # XXX Currently I know no way to prevent KFM from opening a new win.
+        if new == 2:
+            action = "newTab"
+        else:
+            action = "openURL"
+
+        devnull = file(os.devnull, "r+")
+        # if possible, put browser in separate process group, so
+        # keyboard interrupts don't affect browser as well as Python
+        setsid = getattr(os, 'setsid', None)
+        if not setsid:
+            setsid = getattr(os, 'setpgrp', None)
+
+        try:
+            p = subprocess.Popen(["kfmclient", action, url],
+                                 close_fds=True, stdin=devnull,
+                                 stdout=devnull, stderr=devnull)
+        except OSError:
+            # fall through to next variant
+            pass
+        else:
+            p.wait()
+            # kfmclient's return code unfortunately has no meaning as it seems
+            return True
+
+        try:
+            p = subprocess.Popen(["konqueror", "--silent", url],
+                                 close_fds=True, stdin=devnull,
+                                 stdout=devnull, stderr=devnull,
+                                 preexec_fn=setsid)
+        except OSError:
+            # fall through to next variant
+            pass
+        else:
+            if p.poll() is None:
+                # Should be running now.
+                return True
+
+        try:
+            p = subprocess.Popen(["kfm", "-d", url],
+                                 close_fds=True, stdin=devnull,
+                                 stdout=devnull, stderr=devnull,
+                                 preexec_fn=setsid)
+        except OSError:
+            return False
+        else:
+            return (p.poll() is None)
+
+
+class Grail(BaseBrowser):
+    # There should be a way to maintain a connection to Grail, but the
+    # Grail remote control protocol doesn't really allow that at this
+    # point.  It probably never will!
+    def _find_grail_rc(self):
+        import glob
+        import pwd
+        import socket
+        import tempfile
+        tempdir = os.path.join(tempfile.gettempdir(),
+                               ".grail-unix")
+        user = pwd.getpwuid(os.getuid())[0]
+        filename = os.path.join(tempdir, user + "-*")
+        maybes = glob.glob(filename)
+        if not maybes:
+            return None
+        s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+        for fn in maybes:
+            # need to PING each one until we find one that's live
+            try:
+                s.connect(fn)
+            except socket.error:
+                # no good; attempt to clean it out, but don't fail:
+                try:
+                    os.unlink(fn)
+                except IOError:
+                    pass
+            else:
+                return s
+
+    def _remote(self, action):
+        s = self._find_grail_rc()
+        if not s:
+            return 0
+        s.send(action)
+        s.close()
+        return 1
+
+    def open(self, url, new=0, autoraise=1):
+        if new:
+            ok = self._remote("LOADNEW " + url)
+        else:
+            ok = self._remote("LOAD " + url)
+        return ok
+
+
+#
+# Platform support for Unix
+#
+
+# These are the right tests because all these Unix browsers require either
+# a console terminal or an X display to run.
+
+def register_X_browsers():
+    # The default Gnome browser
+    if _iscommand("gconftool-2"):
+        # get the web browser string from gconftool
+        gc = 'gconftool-2 -g /desktop/gnome/url-handlers/http/command 2>/dev/null'
+        out = os.popen(gc)
+        commd = out.read().strip()
+        retncode = out.close()
+
+        # if successful, register it
+        if retncode is None and commd:
+            register("gnome", None, BackgroundBrowser(commd.split()))
+
+    # First, the Mozilla/Netscape browsers
+    for browser in ("mozilla-firefox", "firefox",
+                    "mozilla-firebird", "firebird",
+                    "seamonkey", "mozilla", "netscape"):
+        if _iscommand(browser):
+            register(browser, None, Mozilla(browser))
+
+    # Konqueror/kfm, the KDE browser.
+    if _iscommand("kfm"):
+        register("kfm", Konqueror, Konqueror("kfm"))
+    elif _iscommand("konqueror"):
+        register("konqueror", Konqueror, Konqueror("konqueror"))
+
+    # Gnome's Galeon and Epiphany
+    for browser in ("galeon", "epiphany"):
+        if _iscommand(browser):
+            register(browser, None, Galeon(browser))
+
+    # Skipstone, another Gtk/Mozilla based browser
+    if _iscommand("skipstone"):
+        register("skipstone", None, BackgroundBrowser("skipstone"))
+
+    # Opera, quite popular
+    if _iscommand("opera"):
+        register("opera", None, Opera("opera"))
+
+    # Next, Mosaic -- old but still in use.
+    if _iscommand("mosaic"):
+        register("mosaic", None, BackgroundBrowser("mosaic"))
+
+    # Grail, the Python browser. Does anybody still use it?
+    if _iscommand("grail"):
+        register("grail", Grail, None)
+
+# Prefer X browsers if present
+if os.environ.get("DISPLAY"):
+    register_X_browsers()
+
+# Also try console browsers
+if os.environ.get("TERM"):
+    # The Links/elinks browsers <http://artax.karlin.mff.cuni.cz/~mikulas/links/>
+    if _iscommand("links"):
+        register("links", None, GenericBrowser("links"))
+    if _iscommand("elinks"):
+        register("elinks", None, Elinks("elinks"))
+    # The Lynx browser <http://lynx.isc.org/>, <http://lynx.browser.org/>
+    if _iscommand("lynx"):
+        register("lynx", None, GenericBrowser("lynx"))
+    # The w3m browser <http://w3m.sourceforge.net/>
+    if _iscommand("w3m"):
+        register("w3m", None, GenericBrowser("w3m"))
+
+#
+# Platform support for Windows
+#
+
+if sys.platform[:3] == "win":
+    class WindowsDefault(BaseBrowser):
+        def open(self, url, new=0, autoraise=1):
+            os.startfile(url)
+            return True # Oh, my...
+
+    _tryorder = []
+    _browsers = {}
+    # Prefer mozilla/netscape/opera if present
+    for browser in ("firefox", "firebird", "seamonkey", "mozilla",
+                    "netscape", "opera"):
+        if _iscommand(browser):
+            register(browser, None, BackgroundBrowser(browser))
+    register("windows-default", WindowsDefault)
+
+#
+# Platform support for MacOS
+#
+
+try:
+    import ic
+except ImportError:
+    pass
+else:
+    class InternetConfig(BaseBrowser):
+        def open(self, url, new=0, autoraise=1):
+            ic.launchurl(url)
+            return True # Any way to get status?
+
+    register("internet-config", InternetConfig, update_tryorder=-1)
+
+if sys.platform == 'darwin':
+    # Adapted from patch submitted to SourceForge by Steven J. Burr
+    class MacOSX(BaseBrowser):
+        """Launcher class for Aqua browsers on Mac OS X
+
+        Optionally specify a browser name on instantiation.  Note that this
+        will not work for Aqua browsers if the user has moved the application
+        package after installation.
+
+        If no browser is specified, the default browser, as specified in the
+        Internet System Preferences panel, will be used.
+        """
+        def __init__(self, name):
+            self.name = name
+
+        def open(self, url, new=0, autoraise=1):
+            assert "'" not in url
+            # hack for local urls
+            if not ':' in url:
+                url = 'file:'+url
+
+            # new must be 0 or 1
+            new = int(bool(new))
+            if self.name == "default":
+                # User called open, open_new or get without a browser parameter
+                script = 'open location "%s"' % url.replace('"', '%22') # opens in default browser
+            else:
+                # User called get and chose a browser
+                if self.name == "OmniWeb":
+                    toWindow = ""
+                else:
+                    # Include toWindow parameter of OpenURL command for browsers
+                    # that support it.  0 == new window; -1 == existing
+                    toWindow = "toWindow %d" % (new - 1)
+                cmd = 'OpenURL "%s"' % url.replace('"', '%22')
+                script = '''tell application "%s"
+                                activate
+                                %s %s
+                            end tell''' % (self.name, cmd, toWindow)
+            # Open pipe to AppleScript through osascript command
+            osapipe = os.popen("osascript", "w")
+            if osapipe is None:
+                return False
+            # Write script to osascript's stdin
+            osapipe.write(script)
+            rc = osapipe.close()
+            return not rc
+
+    # Don't clear _tryorder or _browsers since OS X can use above Unix support
+    # (but we prefer using the OS X specific stuff)
+    register("MacOSX", None, MacOSX('default'), -1)
+
+
+#
+# Platform support for OS/2
+#
+
+if sys.platform[:3] == "os2" and _iscommand("netscape"):
+    _tryorder = []
+    _browsers = {}
+    register("os2netscape", None,
+             GenericBrowser(["start", "netscape", "%s"]), -1)
+
+
+# OK, now that we know what the default preference orders for each
+# platform are, allow user to override them with the BROWSER variable.
+if "BROWSER" in os.environ:
+    _userchoices = os.environ["BROWSER"].split(os.pathsep)
+    _userchoices.reverse()
+
+    # Treat choices in same way as if passed into get() but do register
+    # and prepend to _tryorder
+    for cmdline in _userchoices:
+        if cmdline != '':
+            _synthesize(cmdline, -1)
+    cmdline = None # to make del work if _userchoices was empty
+    del cmdline
+    del _userchoices
+
+# what to do if _tryorder is now empty?
+
+
+def main():
+    import getopt
+    usage = """Usage: %s [-n | -t] url
+    -n: open new window
+    -t: open new tab""" % sys.argv[0]
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], 'ntd')
+    except getopt.error, msg:
+        print >>sys.stderr, msg
+        print >>sys.stderr, usage
+        sys.exit(1)
+    new_win = 0
+    for o, a in opts:
+        if o == '-n': new_win = 1
+        elif o == '-t': new_win = 2
+    if len(args) <> 1:
+        print >>sys.stderr, usage
+        sys.exit(1)
+
+    url = args[0]
+    open(url, new_win)
+
+    print "\a"
+
+if __name__ == "__main__":
+    main()

Added: vendor/Python/current/Lib/whichdb.py
===================================================================
--- vendor/Python/current/Lib/whichdb.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/whichdb.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,117 @@
+# !/usr/bin/env python
+"""Guess which db package to use to open a db file."""
+
+import os
+import struct
+import sys
+
+try:
+    import dbm
+    _dbmerror = dbm.error
+except ImportError:
+    dbm = None
+    # just some sort of valid exception which might be raised in the
+    # dbm test
+    _dbmerror = IOError
+
+def whichdb(filename):
+    """Guess which db package to use to open a db file.
+
+    Return values:
+
+    - None if the database file can't be read;
+    - empty string if the file can be read but can't be recognized
+    - the module name (e.g. "dbm" or "gdbm") if recognized.
+
+    Importing the given module may still fail, and opening the
+    database using that module may still fail.
+    """
+
+    # Check for dbm first -- this has a .pag and a .dir file
+    try:
+        f = open(filename + os.extsep + "pag", "rb")
+        f.close()
+        # dbm linked with gdbm on OS/2 doesn't have .dir file
+        if not (dbm.library == "GNU gdbm" and sys.platform == "os2emx"):
+            f = open(filename + os.extsep + "dir", "rb")
+            f.close()
+        return "dbm"
+    except IOError:
+        # some dbm emulations based on Berkeley DB generate a .db file
+        # some do not, but they should be caught by the dbhash checks
+        try:
+            f = open(filename + os.extsep + "db", "rb")
+            f.close()
+            # guarantee we can actually open the file using dbm
+            # kind of overkill, but since we are dealing with emulations
+            # it seems like a prudent step
+            if dbm is not None:
+                d = dbm.open(filename)
+                d.close()
+                return "dbm"
+        except (IOError, _dbmerror):
+            pass
+
+    # Check for dumbdbm next -- this has a .dir and a .dat file
+    try:
+        # First check for presence of files
+        os.stat(filename + os.extsep + "dat")
+        size = os.stat(filename + os.extsep + "dir").st_size
+        # dumbdbm files with no keys are empty
+        if size == 0:
+            return "dumbdbm"
+        f = open(filename + os.extsep + "dir", "rb")
+        try:
+            if f.read(1) in ("'", '"'):
+                return "dumbdbm"
+        finally:
+            f.close()
+    except (OSError, IOError):
+        pass
+
+    # See if the file exists, return None if not
+    try:
+        f = open(filename, "rb")
+    except IOError:
+        return None
+
+    # Read the start of the file -- the magic number
+    s16 = f.read(16)
+    f.close()
+    s = s16[0:4]
+
+    # Return "" if not at least 4 bytes
+    if len(s) != 4:
+        return ""
+
+    # Convert to 4-byte int in native byte order -- return "" if impossible
+    try:
+        (magic,) = struct.unpack("=l", s)
+    except struct.error:
+        return ""
+
+    # Check for GNU dbm
+    if magic == 0x13579ace:
+        return "gdbm"
+
+    # Check for old Berkeley db hash file format v2
+    if magic in (0x00061561, 0x61150600):
+        return "bsddb185"
+
+    # Later versions of Berkeley db hash file have a 12-byte pad in
+    # front of the file type
+    try:
+        (magic,) = struct.unpack("=l", s16[-4:])
+    except struct.error:
+        return ""
+
+    # Check for BSD hash
+    if magic in (0x00061561, 0x61150600):
+        return "dbhash"
+
+    # Unknown
+    return ""
+
+if __name__ == "__main__":
+    for filename in sys.argv[1:]:
+        print whichdb(filename) or "UNKNOWN", filename

Added: vendor/Python/current/Lib/wsgiref/__init__.py
===================================================================
--- vendor/Python/current/Lib/wsgiref/__init__.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/wsgiref/__init__.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,23 @@
+"""wsgiref -- a WSGI (PEP 333) Reference Library
+
+Current Contents:
+
+* util -- Miscellaneous useful functions and wrappers
+
+* headers -- Manage response headers
+
+* handlers -- base classes for server/gateway implementations
+
+* simple_server -- a simple BaseHTTPServer that supports WSGI
+
+* validate -- validation wrapper that sits between an app and a server
+  to detect errors in either
+
+To-Do:
+
+* cgi_gateway -- Run WSGI apps under CGI (pending a deployment standard)
+
+* cgi_wrapper -- Run CGI apps under WSGI
+
+* router -- a simple middleware component that handles URL traversal
+"""

Added: vendor/Python/current/Lib/wsgiref/handlers.py
===================================================================
--- vendor/Python/current/Lib/wsgiref/handlers.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/wsgiref/handlers.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,492 @@
+"""Base classes for server/gateway implementations"""
+
+from types import StringType
+from util import FileWrapper, guess_scheme, is_hop_by_hop
+from headers import Headers
+
+import sys, os, time
+
+__all__ = ['BaseHandler', 'SimpleHandler', 'BaseCGIHandler', 'CGIHandler']
+
+try:
+    dict
+except NameError:
+    def dict(items):
+        d = {}
+        for k,v in items:
+            d[k] = v
+        return d
+
+try:
+    True
+    False
+except NameError:
+    True = not None
+    False = not True
+
+
+# Weekday and month names for HTTP date/time formatting; always English!
+_weekdayname = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
+_monthname = [None, # Dummy so we can use 1-based month numbers
+              "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+              "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
+
+def format_date_time(timestamp):
+    year, month, day, hh, mm, ss, wd, y, z = time.gmtime(timestamp)
+    return "%s, %02d %3s %4d %02d:%02d:%02d GMT" % (
+        _weekdayname[wd], day, _monthname[month], year, hh, mm, ss
+    )
+
+
+
+class BaseHandler:
+    """Manage the invocation of a WSGI application"""
+
+    # Configuration parameters; can override per-subclass or per-instance
+    wsgi_version = (1,0)
+    wsgi_multithread = True
+    wsgi_multiprocess = True
+    wsgi_run_once = False
+
+    origin_server = True    # We are transmitting direct to client
+    http_version  = "1.0"   # Version that should be used for response
+    server_software = None  # String name of server software, if any
+
+    # os_environ is used to supply configuration from the OS environment:
+    # by default it's a copy of 'os.environ' as of import time, but you can
+    # override this in e.g. your __init__ method.
+    os_environ = dict(os.environ.items())
+
+    # Collaborator classes
+    wsgi_file_wrapper = FileWrapper     # set to None to disable
+    headers_class = Headers             # must be a Headers-like class
+
+    # Error handling (also per-subclass or per-instance)
+    traceback_limit = None  # Print entire traceback to self.get_stderr()
+    error_status = "500 Dude, this is whack!"
+    error_headers = [('Content-Type','text/plain')]
+    error_body = "A server error occurred.  Please contact the administrator."
+
+    # State variables (don't mess with these)
+    status = result = None
+    headers_sent = False
+    headers = None
+    bytes_sent = 0
+
+
+
+
+
+
+
+
+    def run(self, application):
+        """Invoke the application"""
+        # Note to self: don't move the close()!  Asynchronous servers shouldn't
+        # call close() from finish_response(), so if you close() anywhere but
+        # the double-error branch here, you'll break asynchronous servers by
+        # prematurely closing.  Async servers must return from 'run()' without
+        # closing if there might still be output to iterate over.
+        try:
+            self.setup_environ()
+            self.result = application(self.environ, self.start_response)
+            self.finish_response()
+        except:
+            try:
+                self.handle_error()
+            except:
+                # If we get an error handling an error, just give up already!
+                self.close()
+                raise   # ...and let the actual server figure it out.
+
+
+    def setup_environ(self):
+        """Set up the environment for one request"""
+
+        env = self.environ = self.os_environ.copy()
+        self.add_cgi_vars()
+
+        env['wsgi.input']        = self.get_stdin()
+        env['wsgi.errors']       = self.get_stderr()
+        env['wsgi.version']      = self.wsgi_version
+        env['wsgi.run_once']     = self.wsgi_run_once
+        env['wsgi.url_scheme']   = self.get_scheme()
+        env['wsgi.multithread']  = self.wsgi_multithread
+        env['wsgi.multiprocess'] = self.wsgi_multiprocess
+
+        if self.wsgi_file_wrapper is not None:
+            env['wsgi.file_wrapper'] = self.wsgi_file_wrapper
+
+        if self.origin_server and self.server_software:
+            env.setdefault('SERVER_SOFTWARE',self.server_software)
+
+
+    def finish_response(self):
+        """Send any iterable data, then close self and the iterable
+
+        Subclasses intended for use in asynchronous servers will
+        want to redefine this method, such that it sets up callbacks
+        in the event loop to iterate over the data, and to call
+        'self.close()' once the response is finished.
+        """
+        if not self.result_is_file() or not self.sendfile():
+            for data in self.result:
+                self.write(data)
+            self.finish_content()
+        self.close()
+
+
+    def get_scheme(self):
+        """Return the URL scheme being used"""
+        return guess_scheme(self.environ)
+
+
+    def set_content_length(self):
+        """Compute Content-Length or switch to chunked encoding if possible"""
+        try:
+            blocks = len(self.result)
+        except (TypeError,AttributeError,NotImplementedError):
+            pass
+        else:
+            if blocks==1:
+                self.headers['Content-Length'] = str(self.bytes_sent)
+                return
+        # XXX Try for chunked encoding if origin server and client is 1.1
+
+
+    def cleanup_headers(self):
+        """Make any necessary header changes or defaults
+
+        Subclasses can extend this to add other defaults.
+        """
+        if not self.headers.has_key('Content-Length'):
+            self.set_content_length()
+
+    def start_response(self, status, headers,exc_info=None):
+        """'start_response()' callable as specified by PEP 333"""
+
+        if exc_info:
+            try:
+                if self.headers_sent:
+                    # Re-raise original exception if headers sent
+                    raise exc_info[0], exc_info[1], exc_info[2]
+            finally:
+                exc_info = None        # avoid dangling circular ref
+        elif self.headers is not None:
+            raise AssertionError("Headers already set!")
+
+        assert type(status) is StringType,"Status must be a string"
+        assert len(status)>=4,"Status must be at least 4 characters"
+        assert int(status[:3]),"Status message must begin w/3-digit code"
+        assert status[3]==" ", "Status message must have a space after code"
+        if __debug__:
+            for name,val in headers:
+                assert type(name) is StringType,"Header names must be strings"
+                assert type(val) is StringType,"Header values must be strings"
+                assert not is_hop_by_hop(name),"Hop-by-hop headers not allowed"
+        self.status = status
+        self.headers = self.headers_class(headers)
+        return self.write
+
+
+    def send_preamble(self):
+        """Transmit version/status/date/server, via self._write()"""
+        if self.origin_server:
+            if self.client_is_modern():
+                self._write('HTTP/%s %s\r\n' % (self.http_version,self.status))
+                if not self.headers.has_key('Date'):
+                    self._write(
+                        'Date: %s\r\n' % format_date_time(time.time())
+                    )
+                if self.server_software and not self.headers.has_key('Server'):
+                    self._write('Server: %s\r\n' % self.server_software)
+        else:
+            self._write('Status: %s\r\n' % self.status)
+
+    def write(self, data):
+        """'write()' callable as specified by PEP 333"""
+
+        assert type(data) is StringType,"write() argument must be string"
+
+        if not self.status:
+            raise AssertionError("write() before start_response()")
+
+        elif not self.headers_sent:
+            # Before the first output, send the stored headers
+            self.bytes_sent = len(data)    # make sure we know content-length
+            self.send_headers()
+        else:
+            self.bytes_sent += len(data)
+
+        # XXX check Content-Length and truncate if too many bytes written?
+        self._write(data)
+        self._flush()
+
+
+    def sendfile(self):
+        """Platform-specific file transmission
+
+        Override this method in subclasses to support platform-specific
+        file transmission.  It is only called if the application's
+        return iterable ('self.result') is an instance of
+        'self.wsgi_file_wrapper'.
+
+        This method should return a true value if it was able to actually
+        transmit the wrapped file-like object using a platform-specific
+        approach.  It should return a false value if normal iteration
+        should be used instead.  An exception can be raised to indicate
+        that transmission was attempted, but failed.
+
+        NOTE: this method should call 'self.send_headers()' if
+        'self.headers_sent' is false and it is going to attempt direct
+        transmission of the file.
+        """
+        return False   # No platform-specific transmission by default
+
+
+    def finish_content(self):
+        """Ensure headers and content have both been sent"""
+        if not self.headers_sent:
+            self.headers['Content-Length'] = "0"
+            self.send_headers()
+        else:
+            pass # XXX check if content-length was too short?
+
+    def close(self):
+        """Close the iterable (if needed) and reset all instance vars
+
+        Subclasses may want to also drop the client connection.
+        """
+        try:
+            if hasattr(self.result,'close'):
+                self.result.close()
+        finally:
+            self.result = self.headers = self.status = self.environ = None
+            self.bytes_sent = 0; self.headers_sent = False
+
+
+    def send_headers(self):
+        """Transmit headers to the client, via self._write()"""
+        self.cleanup_headers()
+        self.headers_sent = True
+        if not self.origin_server or self.client_is_modern():
+            self.send_preamble()
+            self._write(str(self.headers))
+
+
+    def result_is_file(self):
+        """True if 'self.result' is an instance of 'self.wsgi_file_wrapper'"""
+        wrapper = self.wsgi_file_wrapper
+        return wrapper is not None and isinstance(self.result,wrapper)
+
+
+    def client_is_modern(self):
+        """True if client can accept status and headers"""
+        return self.environ['SERVER_PROTOCOL'].upper() != 'HTTP/0.9'
+
+
+    def log_exception(self,exc_info):
+        """Log the 'exc_info' tuple in the server log
+
+        Subclasses may override to retarget the output or change its format.
+        """
+        try:
+            from traceback import print_exception
+            stderr = self.get_stderr()
+            print_exception(
+                exc_info[0], exc_info[1], exc_info[2],
+                self.traceback_limit, stderr
+            )
+            stderr.flush()
+        finally:
+            exc_info = None
+
+    def handle_error(self):
+        """Log current error, and send error output to client if possible"""
+        self.log_exception(sys.exc_info())
+        if not self.headers_sent:
+            self.result = self.error_output(self.environ, self.start_response)
+            self.finish_response()
+        # XXX else: attempt advanced recovery techniques for HTML or text?
+
+    def error_output(self, environ, start_response):
+        """WSGI mini-app to create error output
+
+        By default, this just uses the 'error_status', 'error_headers',
+        and 'error_body' attributes to generate an output page.  It can
+        be overridden in a subclass to dynamically generate diagnostics,
+        choose an appropriate message for the user's preferred language, etc.
+
+        Note, however, that it's not recommended from a security perspective to
+        spit out diagnostics to any old user; ideally, you should have to do
+        something special to enable diagnostic output, which is why we don't
+        include any here!
+        """
+        start_response(self.error_status,self.error_headers[:],sys.exc_info())
+        return [self.error_body]
+
+
+    # Pure abstract methods; *must* be overridden in subclasses
+
+    def _write(self,data):
+        """Override in subclass to buffer data for send to client
+
+        It's okay if this method actually transmits the data; BaseHandler
+        just separates write and flush operations for greater efficiency
+        when the underlying system actually has such a distinction.
+        """
+        raise NotImplementedError
+
+    def _flush(self):
+        """Override in subclass to force sending of recent '_write()' calls
+
+        It's okay if this method is a no-op (i.e., if '_write()' actually
+        sends the data.
+        """
+        raise NotImplementedError
+
+    def get_stdin(self):
+        """Override in subclass to return suitable 'wsgi.input'"""
+        raise NotImplementedError
+
+    def get_stderr(self):
+        """Override in subclass to return suitable 'wsgi.errors'"""
+        raise NotImplementedError
+
+    def add_cgi_vars(self):
+        """Override in subclass to insert CGI variables in 'self.environ'"""
+        raise NotImplementedError
+
+
+
+
+
+
+
+
+
+
+
+class SimpleHandler(BaseHandler):
+    """Handler that's just initialized with streams, environment, etc.
+
+    This handler subclass is intended for synchronous HTTP/1.0 origin servers,
+    and handles sending the entire response output, given the correct inputs.
+
+    Usage::
+
+        handler = SimpleHandler(
+            inp,out,err,env, multithread=False, multiprocess=True
+        )
+        handler.run(app)"""
+
+    def __init__(self,stdin,stdout,stderr,environ,
+        multithread=True, multiprocess=False
+    ):
+        self.stdin = stdin
+        self.stdout = stdout
+        self.stderr = stderr
+        self.base_env = environ
+        self.wsgi_multithread = multithread
+        self.wsgi_multiprocess = multiprocess
+
+    def get_stdin(self):
+        return self.stdin
+
+    def get_stderr(self):
+        return self.stderr
+
+    def add_cgi_vars(self):
+        self.environ.update(self.base_env)
+
+    def _write(self,data):
+        self.stdout.write(data)
+        self._write = self.stdout.write
+
+    def _flush(self):
+        self.stdout.flush()
+        self._flush = self.stdout.flush
+
+
+class BaseCGIHandler(SimpleHandler):
+
+    """CGI-like systems using input/output/error streams and environ mapping
+
+    Usage::
+
+        handler = BaseCGIHandler(inp,out,err,env)
+        handler.run(app)
+
+    This handler class is useful for gateway protocols like ReadyExec and
+    FastCGI, that have usable input/output/error streams and an environment
+    mapping.  It's also the base class for CGIHandler, which just uses
+    sys.stdin, os.environ, and so on.
+
+    The constructor also takes keyword arguments 'multithread' and
+    'multiprocess' (defaulting to 'True' and 'False' respectively) to control
+    the configuration sent to the application.  It sets 'origin_server' to
+    False (to enable CGI-like output), and assumes that 'wsgi.run_once' is
+    False.
+    """
+
+    origin_server = False
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+class CGIHandler(BaseCGIHandler):
+
+    """CGI-based invocation via sys.stdin/stdout/stderr and os.environ
+
+    Usage::
+
+        CGIHandler().run(app)
+
+    The difference between this class and BaseCGIHandler is that it always
+    uses 'wsgi.run_once' of 'True', 'wsgi.multithread' of 'False', and
+    'wsgi.multiprocess' of 'True'.  It does not take any initialization
+    parameters, but always uses 'sys.stdin', 'os.environ', and friends.
+
+    If you need to override any of these parameters, use BaseCGIHandler
+    instead.
+    """
+
+    wsgi_run_once = True
+
+    def __init__(self):
+        BaseCGIHandler.__init__(
+            self, sys.stdin, sys.stdout, sys.stderr, dict(os.environ.items()),
+            multithread=False, multiprocess=True
+        )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#

Added: vendor/Python/current/Lib/wsgiref/headers.py
===================================================================
--- vendor/Python/current/Lib/wsgiref/headers.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/wsgiref/headers.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,205 @@
+"""Manage HTTP Response Headers
+
+Much of this module is red-handedly pilfered from email.Message in the stdlib,
+so portions are Copyright (C) 2001,2002 Python Software Foundation, and were
+written by Barry Warsaw.
+"""
+
+from types import ListType, TupleType
+
+# Regular expression that matches `special' characters in parameters, the
+# existance of which force quoting of the parameter value.
+import re
+tspecials = re.compile(r'[ \(\)<>@,;:\\"/\[\]\?=]')
+
+def _formatparam(param, value=None, quote=1):
+    """Convenience function to format and return a key=value pair.
+
+    This will quote the value if needed or if quote is true.
+    """
+    if value is not None and len(value) > 0:
+        if quote or tspecials.search(value):
+            value = value.replace('\\', '\\\\').replace('"', r'\"')
+            return '%s="%s"' % (param, value)
+        else:
+            return '%s=%s' % (param, value)
+    else:
+        return param
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+class Headers:
+
+    """Manage a collection of HTTP response headers"""
+
+    def __init__(self,headers):
+        if type(headers) is not ListType:
+            raise TypeError("Headers must be a list of name/value tuples")
+        self._headers = headers
+
+    def __len__(self):
+        """Return the total number of headers, including duplicates."""
+        return len(self._headers)
+
+    def __setitem__(self, name, val):
+        """Set the value of a header."""
+        del self[name]
+        self._headers.append((name, val))
+
+    def __delitem__(self,name):
+        """Delete all occurrences of a header, if present.
+
+        Does *not* raise an exception if the header is missing.
+        """
+        name = name.lower()
+        self._headers[:] = [kv for kv in self._headers if kv[0].lower()<>name]
+
+    def __getitem__(self,name):
+        """Get the first header value for 'name'
+
+        Return None if the header is missing instead of raising an exception.
+
+        Note that if the header appeared multiple times, the first exactly which
+        occurrance gets returned is undefined.  Use getall() to get all
+        the values matching a header field name.
+        """
+        return self.get(name)
+
+
+
+
+
+    def has_key(self, name):
+        """Return true if the message contains the header."""
+        return self.get(name) is not None
+
+    __contains__ = has_key
+
+
+    def get_all(self, name):
+        """Return a list of all the values for the named field.
+
+        These will be sorted in the order they appeared in the original header
+        list or were added to this instance, and may contain duplicates.  Any
+        fields deleted and re-inserted are always appended to the header list.
+        If no fields exist with the given name, returns an empty list.
+        """
+        name = name.lower()
+        return [kv[1] for kv in self._headers if kv[0].lower()==name]
+
+
+    def get(self,name,default=None):
+        """Get the first header value for 'name', or return 'default'"""
+        name = name.lower()
+        for k,v in self._headers:
+            if k.lower()==name:
+                return v
+        return default
+
+
+    def keys(self):
+        """Return a list of all the header field names.
+
+        These will be sorted in the order they appeared in the original header
+        list, or were added to this instance, and may contain duplicates.
+        Any fields deleted and re-inserted are always appended to the header
+        list.
+        """
+        return [k for k, v in self._headers]
+
+
+
+
+    def values(self):
+        """Return a list of all header values.
+
+        These will be sorted in the order they appeared in the original header
+        list, or were added to this instance, and may contain duplicates.
+        Any fields deleted and re-inserted are always appended to the header
+        list.
+        """
+        return [v for k, v in self._headers]
+
+    def items(self):
+        """Get all the header fields and values.
+
+        These will be sorted in the order they were in the original header
+        list, or were added to this instance, and may contain duplicates.
+        Any fields deleted and re-inserted are always appended to the header
+        list.
+        """
+        return self._headers[:]
+
+    def __repr__(self):
+        return "Headers(%s)" % `self._headers`
+
+    def __str__(self):
+        """str() returns the formatted headers, complete with end line,
+        suitable for direct HTTP transmission."""
+        return '\r\n'.join(["%s: %s" % kv for kv in self._headers]+['',''])
+
+    def setdefault(self,name,value):
+        """Return first matching header value for 'name', or 'value'
+
+        If there is no header named 'name', add a new header with name 'name'
+        and value 'value'."""
+        result = self.get(name)
+        if result is None:
+            self._headers.append((name,value))
+            return value
+        else:
+            return result
+
+
+    def add_header(self, _name, _value, **_params):
+        """Extended header setting.
+
+        _name is the header field to add.  keyword arguments can be used to set
+        additional parameters for the header field, with underscores converted
+        to dashes.  Normally the parameter will be added as key="value" unless
+        value is None, in which case only the key will be added.
+
+        Example:
+
+        h.add_header('content-disposition', 'attachment', filename='bud.gif')
+
+        Note that unlike the corresponding 'email.Message' method, this does
+        *not* handle '(charset, language, value)' tuples: all values must be
+        strings or None.
+        """
+        parts = []
+        if _value is not None:
+            parts.append(_value)
+        for k, v in _params.items():
+            if v is None:
+                parts.append(k.replace('_', '-'))
+            else:
+                parts.append(_formatparam(k.replace('_', '-'), v))
+        self._headers.append((_name, "; ".join(parts)))
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#

Added: vendor/Python/current/Lib/wsgiref/simple_server.py
===================================================================
--- vendor/Python/current/Lib/wsgiref/simple_server.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/wsgiref/simple_server.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,205 @@
+"""BaseHTTPServer that implements the Python WSGI protocol (PEP 333, rev 1.21)
+
+This is both an example of how WSGI can be implemented, and a basis for running
+simple web applications on a local machine, such as might be done when testing
+or debugging an application.  It has not been reviewed for security issues,
+however, and we strongly recommend that you use a "real" web server for
+production use.
+
+For example usage, see the 'if __name__=="__main__"' block at the end of the
+module.  See also the BaseHTTPServer module docs for other API information.
+"""
+
+from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
+import urllib, sys
+from wsgiref.handlers import SimpleHandler
+
+__version__ = "0.1"
+__all__ = ['WSGIServer', 'WSGIRequestHandler', 'demo_app', 'make_server']
+
+
+server_version = "WSGIServer/" + __version__
+sys_version = "Python/" + sys.version.split()[0]
+software_version = server_version + ' ' + sys_version
+
+
+class ServerHandler(SimpleHandler):
+
+    server_software = software_version
+
+    def close(self):
+        try:
+            self.request_handler.log_request(
+                self.status.split(' ',1)[0], self.bytes_sent
+            )
+        finally:
+            SimpleHandler.close(self)
+
+
+
+
+
+class WSGIServer(HTTPServer):
+
+    """BaseHTTPServer that implements the Python WSGI protocol"""
+
+    application = None
+
+    def server_bind(self):
+        """Override server_bind to store the server name."""
+        HTTPServer.server_bind(self)
+        self.setup_environ()
+
+    def setup_environ(self):
+        # Set up base environment
+        env = self.base_environ = {}
+        env['SERVER_NAME'] = self.server_name
+        env['GATEWAY_INTERFACE'] = 'CGI/1.1'
+        env['SERVER_PORT'] = str(self.server_port)
+        env['REMOTE_HOST']=''
+        env['CONTENT_LENGTH']=''
+        env['SCRIPT_NAME'] = ''
+
+    def get_app(self):
+        return self.application
+
+    def set_app(self,application):
+        self.application = application
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+class WSGIRequestHandler(BaseHTTPRequestHandler):
+
+    server_version = "WSGIServer/" + __version__
+
+    def get_environ(self):
+        env = self.server.base_environ.copy()
+        env['SERVER_PROTOCOL'] = self.request_version
+        env['REQUEST_METHOD'] = self.command
+        if '?' in self.path:
+            path,query = self.path.split('?',1)
+        else:
+            path,query = self.path,''
+
+        env['PATH_INFO'] = urllib.unquote(path)
+        env['QUERY_STRING'] = query
+
+        host = self.address_string()
+        if host != self.client_address[0]:
+            env['REMOTE_HOST'] = host
+        env['REMOTE_ADDR'] = self.client_address[0]
+
+        if self.headers.typeheader is None:
+            env['CONTENT_TYPE'] = self.headers.type
+        else:
+            env['CONTENT_TYPE'] = self.headers.typeheader
+
+        length = self.headers.getheader('content-length')
+        if length:
+            env['CONTENT_LENGTH'] = length
+
+        for h in self.headers.headers:
+            k,v = h.split(':',1)
+            k=k.replace('-','_').upper(); v=v.strip()
+            if k in env:
+                continue                    # skip content length, type,etc.
+            if 'HTTP_'+k in env:
+                env['HTTP_'+k] += ','+v     # comma-separate multiple headers
+            else:
+                env['HTTP_'+k] = v
+        return env
+
+    def get_stderr(self):
+        return sys.stderr
+
+    def handle(self):
+        """Handle a single HTTP request"""
+
+        self.raw_requestline = self.rfile.readline()
+        if not self.parse_request(): # An error code has been sent, just exit
+            return
+
+        handler = ServerHandler(
+            self.rfile, self.wfile, self.get_stderr(), self.get_environ()
+        )
+        handler.request_handler = self      # backpointer for logging
+        handler.run(self.server.get_app())
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+def demo_app(environ,start_response):
+    from StringIO import StringIO
+    stdout = StringIO()
+    print >>stdout, "Hello world!"
+    print >>stdout
+    h = environ.items(); h.sort()
+    for k,v in h:
+        print >>stdout, k,'=',`v`
+    start_response("200 OK", [('Content-Type','text/plain')])
+    return [stdout.getvalue()]
+
+
+def make_server(
+    host, port, app, server_class=WSGIServer, handler_class=WSGIRequestHandler
+):
+    """Create a new WSGI server listening on `host` and `port` for `app`"""
+    server = server_class((host, port), handler_class)
+    server.set_app(app)
+    return server
+
+
+if __name__ == '__main__':
+    httpd = make_server('', 8000, demo_app)
+    sa = httpd.socket.getsockname()
+    print "Serving HTTP on", sa[0], "port", sa[1], "..."
+    import webbrowser
+    webbrowser.open('http://localhost:8000/xyz?abc')
+    httpd.handle_request()  # serve one request, then exit
+
+
+
+
+
+
+
+
+
+
+
+
+#

Added: vendor/Python/current/Lib/wsgiref/util.py
===================================================================
--- vendor/Python/current/Lib/wsgiref/util.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/wsgiref/util.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,205 @@
+"""Miscellaneous WSGI-related Utilities"""
+
+import posixpath
+
+__all__ = [
+    'FileWrapper', 'guess_scheme', 'application_uri', 'request_uri',
+    'shift_path_info', 'setup_testing_defaults',
+]
+
+
+class FileWrapper:
+    """Wrapper to convert file-like objects to iterables"""
+
+    def __init__(self, filelike, blksize=8192):
+        self.filelike = filelike
+        self.blksize = blksize
+        if hasattr(filelike,'close'):
+            self.close = filelike.close
+
+    def __getitem__(self,key):
+        data = self.filelike.read(self.blksize)
+        if data:
+            return data
+        raise IndexError
+
+    def __iter__(self):
+        return self
+
+    def next(self):
+        data = self.filelike.read(self.blksize)
+        if data:
+            return data
+        raise StopIteration
+
+
+
+
+
+
+
+
+def guess_scheme(environ):
+    """Return a guess for whether 'wsgi.url_scheme' should be 'http' or 'https'
+    """
+    if environ.get("HTTPS") in ('yes','on','1'):
+        return 'https'
+    else:
+        return 'http'
+
+def application_uri(environ):
+    """Return the application's base URI (no PATH_INFO or QUERY_STRING)"""
+    url = environ['wsgi.url_scheme']+'://'
+    from urllib import quote
+
+    if environ.get('HTTP_HOST'):
+        url += environ['HTTP_HOST']
+    else:
+        url += environ['SERVER_NAME']
+
+        if environ['wsgi.url_scheme'] == 'https':
+            if environ['SERVER_PORT'] != '443':
+                url += ':' + environ['SERVER_PORT']
+        else:
+            if environ['SERVER_PORT'] != '80':
+                url += ':' + environ['SERVER_PORT']
+
+    url += quote(environ.get('SCRIPT_NAME') or '/')
+    return url
+
+def request_uri(environ, include_query=1):
+    """Return the full request URI, optionally including the query string"""
+    url = application_uri(environ)
+    from urllib import quote
+    path_info = quote(environ.get('PATH_INFO',''))
+    if not environ.get('SCRIPT_NAME'):
+        url += path_info[1:]
+    else:
+        url += path_info
+    if include_query and environ.get('QUERY_STRING'):
+        url += '?' + environ['QUERY_STRING']
+    return url
+
+def shift_path_info(environ):
+    """Shift a name from PATH_INFO to SCRIPT_NAME, returning it
+
+    If there are no remaining path segments in PATH_INFO, return None.
+    Note: 'environ' is modified in-place; use a copy if you need to keep
+    the original PATH_INFO or SCRIPT_NAME.
+
+    Note: when PATH_INFO is just a '/', this returns '' and appends a trailing
+    '/' to SCRIPT_NAME, even though empty path segments are normally ignored,
+    and SCRIPT_NAME doesn't normally end in a '/'.  This is intentional
+    behavior, to ensure that an application can tell the difference between
+    '/x' and '/x/' when traversing to objects.
+    """
+    path_info = environ.get('PATH_INFO','')
+    if not path_info:
+        return None
+
+    path_parts = path_info.split('/')
+    path_parts[1:-1] = [p for p in path_parts[1:-1] if p and p<>'.']
+    name = path_parts[1]
+    del path_parts[1]
+
+    script_name = environ.get('SCRIPT_NAME','')
+    script_name = posixpath.normpath(script_name+'/'+name)
+    if script_name.endswith('/'):
+        script_name = script_name[:-1]
+    if not name and not script_name.endswith('/'):
+        script_name += '/'
+
+    environ['SCRIPT_NAME'] = script_name
+    environ['PATH_INFO']   = '/'.join(path_parts)
+
+    # Special case: '/.' on PATH_INFO doesn't get stripped,
+    # because we don't strip the last element of PATH_INFO
+    # if there's only one path part left.  Instead of fixing this
+    # above, we fix it here so that PATH_INFO gets normalized to
+    # an empty string in the environ.
+    if name=='.':
+        name = None
+    return name
+
+def setup_testing_defaults(environ):
+    """Update 'environ' with trivial defaults for testing purposes
+
+    This adds various parameters required for WSGI, including HTTP_HOST,
+    SERVER_NAME, SERVER_PORT, REQUEST_METHOD, SCRIPT_NAME, PATH_INFO,
+    and all of the wsgi.* variables.  It only supplies default values,
+    and does not replace any existing settings for these variables.
+
+    This routine is intended to make it easier for unit tests of WSGI
+    servers and applications to set up dummy environments.  It should *not*
+    be used by actual WSGI servers or applications, since the data is fake!
+    """
+
+    environ.setdefault('SERVER_NAME','127.0.0.1')
+    environ.setdefault('SERVER_PROTOCOL','HTTP/1.0')
+
+    environ.setdefault('HTTP_HOST',environ['SERVER_NAME'])
+    environ.setdefault('REQUEST_METHOD','GET')
+
+    if 'SCRIPT_NAME' not in environ and 'PATH_INFO' not in environ:
+        environ.setdefault('SCRIPT_NAME','')
+        environ.setdefault('PATH_INFO','/')
+
+    environ.setdefault('wsgi.version', (1,0))
+    environ.setdefault('wsgi.run_once', 0)
+    environ.setdefault('wsgi.multithread', 0)
+    environ.setdefault('wsgi.multiprocess', 0)
+
+    from StringIO import StringIO
+    environ.setdefault('wsgi.input', StringIO(""))
+    environ.setdefault('wsgi.errors', StringIO())
+    environ.setdefault('wsgi.url_scheme',guess_scheme(environ))
+
+    if environ['wsgi.url_scheme']=='http':
+        environ.setdefault('SERVER_PORT', '80')
+    elif environ['wsgi.url_scheme']=='https':
+        environ.setdefault('SERVER_PORT', '443')
+
+
+
+
+_hoppish = {
+    'connection':1, 'keep-alive':1, 'proxy-authenticate':1,
+    'proxy-authorization':1, 'te':1, 'trailers':1, 'transfer-encoding':1,
+    'upgrade':1
+}.has_key
+
+def is_hop_by_hop(header_name):
+    """Return true if 'header_name' is an HTTP/1.1 "Hop-by-Hop" header"""
+    return _hoppish(header_name.lower())
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#

Added: vendor/Python/current/Lib/wsgiref/validate.py
===================================================================
--- vendor/Python/current/Lib/wsgiref/validate.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/wsgiref/validate.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,432 @@
+# (c) 2005 Ian Bicking and contributors; written for Paste (http://pythonpaste.org)
+# Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
+# Also licenced under the Apache License, 2.0: http://opensource.org/licenses/apache2.0.php
+# Licensed to PSF under a Contributor Agreement
+"""
+Middleware to check for obedience to the WSGI specification.
+
+Some of the things this checks:
+
+* Signature of the application and start_response (including that
+  keyword arguments are not used).
+
+* Environment checks:
+
+  - Environment is a dictionary (and not a subclass).
+
+  - That all the required keys are in the environment: REQUEST_METHOD,
+    SERVER_NAME, SERVER_PORT, wsgi.version, wsgi.input, wsgi.errors,
+    wsgi.multithread, wsgi.multiprocess, wsgi.run_once
+
+  - That HTTP_CONTENT_TYPE and HTTP_CONTENT_LENGTH are not in the
+    environment (these headers should appear as CONTENT_LENGTH and
+    CONTENT_TYPE).
+
+  - Warns if QUERY_STRING is missing, as the cgi module acts
+    unpredictably in that case.
+
+  - That CGI-style variables (that don't contain a .) have
+    (non-unicode) string values
+
+  - That wsgi.version is a tuple
+
+  - That wsgi.url_scheme is 'http' or 'https' (@@: is this too
+    restrictive?)
+
+  - Warns if the REQUEST_METHOD is not known (@@: probably too
+    restrictive).
+
+  - That SCRIPT_NAME and PATH_INFO are empty or start with /
+
+  - That at least one of SCRIPT_NAME or PATH_INFO are set.
+
+  - That CONTENT_LENGTH is a positive integer.
+
+  - That SCRIPT_NAME is not '/' (it should be '', and PATH_INFO should
+    be '/').
+
+  - That wsgi.input has the methods read, readline, readlines, and
+    __iter__
+
+  - That wsgi.errors has the methods flush, write, writelines
+
+* The status is a string, contains a space, starts with an integer,
+  and that integer is in range (> 100).
+
+* That the headers is a list (not a subclass, not another kind of
+  sequence).
+
+* That the items of the headers are tuples of strings.
+
+* That there is no 'status' header (that is used in CGI, but not in
+  WSGI).
+
+* That the headers don't contain newlines or colons, end in _ or -, or
+  contain characters codes below 037.
+
+* That Content-Type is given if there is content (CGI often has a
+  default content type, but WSGI does not).
+
+* That no Content-Type is given when there is no content (@@: is this
+  too restrictive?)
+
+* That the exc_info argument to start_response is a tuple or None.
+
+* That all calls to the writer are with strings, and no other methods
+  on the writer are accessed.
+
+* That wsgi.input is used properly:
+
+  - .read() is called with zero or one argument
+
+  - That it returns a string
+
+  - That readline, readlines, and __iter__ return strings
+
+  - That .close() is not called
+
+  - No other methods are provided
+
+* That wsgi.errors is used properly:
+
+  - .write() and .writelines() is called with a string
+
+  - That .close() is not called, and no other methods are provided.
+
+* The response iterator:
+
+  - That it is not a string (it should be a list of a single string; a
+    string will work, but perform horribly).
+
+  - That .next() returns a string
+
+  - That the iterator is not iterated over until start_response has
+    been called (that can signal either a server or application
+    error).
+
+  - That .close() is called (doesn't raise exception, only prints to
+    sys.stderr, because we only know it isn't called when the object
+    is garbage collected).
+"""
+__all__ = ['validator']
+
+
+import re
+import sys
+from types import DictType, StringType, TupleType, ListType
+import warnings
+
+header_re = re.compile(r'^[a-zA-Z][a-zA-Z0-9\-_]*$')
+bad_header_value_re = re.compile(r'[\000-\037]')
+
+class WSGIWarning(Warning):
+    """
+    Raised in response to WSGI-spec-related warnings
+    """
+
+def assert_(cond, *args):
+    if not cond:
+        raise AssertionError(*args)
+
+def validator(application):
+
+    """
+    When applied between a WSGI server and a WSGI application, this
+    middleware will check for WSGI compliancy on a number of levels.
+    This middleware does not modify the request or response in any
+    way, but will throw an AssertionError if anything seems off
+    (except for a failure to close the application iterator, which
+    will be printed to stderr -- there's no way to throw an exception
+    at that point).
+    """
+
+    def lint_app(*args, **kw):
+        assert_(len(args) == 2, "Two arguments required")
+        assert_(not kw, "No keyword arguments allowed")
+        environ, start_response = args
+
+        check_environ(environ)
+
+        # We use this to check if the application returns without
+        # calling start_response:
+        start_response_started = []
+
+        def start_response_wrapper(*args, **kw):
+            assert_(len(args) == 2 or len(args) == 3, (
+                "Invalid number of arguments: %s" % (args,)))
+            assert_(not kw, "No keyword arguments allowed")
+            status = args[0]
+            headers = args[1]
+            if len(args) == 3:
+                exc_info = args[2]
+            else:
+                exc_info = None
+
+            check_status(status)
+            check_headers(headers)
+            check_content_type(status, headers)
+            check_exc_info(exc_info)
+
+            start_response_started.append(None)
+            return WriteWrapper(start_response(*args))
+
+        environ['wsgi.input'] = InputWrapper(environ['wsgi.input'])
+        environ['wsgi.errors'] = ErrorWrapper(environ['wsgi.errors'])
+
+        iterator = application(environ, start_response_wrapper)
+        assert_(iterator is not None and iterator != False,
+            "The application must return an iterator, if only an empty list")
+
+        check_iterator(iterator)
+
+        return IteratorWrapper(iterator, start_response_started)
+
+    return lint_app
+
+class InputWrapper:
+
+    def __init__(self, wsgi_input):
+        self.input = wsgi_input
+
+    def read(self, *args):
+        assert_(len(args) <= 1)
+        v = self.input.read(*args)
+        assert_(type(v) is type(""))
+        return v
+
+    def readline(self):
+        v = self.input.readline()
+        assert_(type(v) is type(""))
+        return v
+
+    def readlines(self, *args):
+        assert_(len(args) <= 1)
+        lines = self.input.readlines(*args)
+        assert_(type(lines) is type([]))
+        for line in lines:
+            assert_(type(line) is type(""))
+        return lines
+
+    def __iter__(self):
+        while 1:
+            line = self.readline()
+            if not line:
+                return
+            yield line
+
+    def close(self):
+        assert_(0, "input.close() must not be called")
+
+class ErrorWrapper:
+
+    def __init__(self, wsgi_errors):
+        self.errors = wsgi_errors
+
+    def write(self, s):
+        assert_(type(s) is type(""))
+        self.errors.write(s)
+
+    def flush(self):
+        self.errors.flush()
+
+    def writelines(self, seq):
+        for line in seq:
+            self.write(line)
+
+    def close(self):
+        assert_(0, "errors.close() must not be called")
+
+class WriteWrapper:
+
+    def __init__(self, wsgi_writer):
+        self.writer = wsgi_writer
+
+    def __call__(self, s):
+        assert_(type(s) is type(""))
+        self.writer(s)
+
+class PartialIteratorWrapper:
+
+    def __init__(self, wsgi_iterator):
+        self.iterator = wsgi_iterator
+
+    def __iter__(self):
+        # We want to make sure __iter__ is called
+        return IteratorWrapper(self.iterator, None)
+
+class IteratorWrapper:
+
+    def __init__(self, wsgi_iterator, check_start_response):
+        self.original_iterator = wsgi_iterator
+        self.iterator = iter(wsgi_iterator)
+        self.closed = False
+        self.check_start_response = check_start_response
+
+    def __iter__(self):
+        return self
+
+    def next(self):
+        assert_(not self.closed,
+            "Iterator read after closed")
+        v = self.iterator.next()
+        if self.check_start_response is not None:
+            assert_(self.check_start_response,
+                "The application returns and we started iterating over its body, but start_response has not yet been called")
+            self.check_start_response = None
+        return v
+
+    def close(self):
+        self.closed = True
+        if hasattr(self.original_iterator, 'close'):
+            self.original_iterator.close()
+
+    def __del__(self):
+        if not self.closed:
+            sys.stderr.write(
+                "Iterator garbage collected without being closed")
+        assert_(self.closed,
+            "Iterator garbage collected without being closed")
+
+def check_environ(environ):
+    assert_(type(environ) is DictType,
+        "Environment is not of the right type: %r (environment: %r)"
+        % (type(environ), environ))
+
+    for key in ['REQUEST_METHOD', 'SERVER_NAME', 'SERVER_PORT',
+                'wsgi.version', 'wsgi.input', 'wsgi.errors',
+                'wsgi.multithread', 'wsgi.multiprocess',
+                'wsgi.run_once']:
+        assert_(key in environ,
+            "Environment missing required key: %r" % (key,))
+
+    for key in ['HTTP_CONTENT_TYPE', 'HTTP_CONTENT_LENGTH']:
+        assert_(key not in environ,
+            "Environment should not have the key: %s "
+            "(use %s instead)" % (key, key[5:]))
+
+    if 'QUERY_STRING' not in environ:
+        warnings.warn(
+            'QUERY_STRING is not in the WSGI environment; the cgi '
+            'module will use sys.argv when this variable is missing, '
+            'so application errors are more likely',
+            WSGIWarning)
+
+    for key in environ.keys():
+        if '.' in key:
+            # Extension, we don't care about its type
+            continue
+        assert_(type(environ[key]) is StringType,
+            "Environmental variable %s is not a string: %r (value: %r)"
+            % (key, type(environ[key]), environ[key]))
+
+    assert_(type(environ['wsgi.version']) is TupleType,
+        "wsgi.version should be a tuple (%r)" % (environ['wsgi.version'],))
+    assert_(environ['wsgi.url_scheme'] in ('http', 'https'),
+        "wsgi.url_scheme unknown: %r" % environ['wsgi.url_scheme'])
+
+    check_input(environ['wsgi.input'])
+    check_errors(environ['wsgi.errors'])
+
+    # @@: these need filling out:
+    if environ['REQUEST_METHOD'] not in (
+        'GET', 'HEAD', 'POST', 'OPTIONS','PUT','DELETE','TRACE'):
+        warnings.warn(
+            "Unknown REQUEST_METHOD: %r" % environ['REQUEST_METHOD'],
+            WSGIWarning)
+
+    assert_(not environ.get('SCRIPT_NAME')
+            or environ['SCRIPT_NAME'].startswith('/'),
+        "SCRIPT_NAME doesn't start with /: %r" % environ['SCRIPT_NAME'])
+    assert_(not environ.get('PATH_INFO')
+            or environ['PATH_INFO'].startswith('/'),
+        "PATH_INFO doesn't start with /: %r" % environ['PATH_INFO'])
+    if environ.get('CONTENT_LENGTH'):
+        assert_(int(environ['CONTENT_LENGTH']) >= 0,
+            "Invalid CONTENT_LENGTH: %r" % environ['CONTENT_LENGTH'])
+
+    if not environ.get('SCRIPT_NAME'):
+        assert_(environ.has_key('PATH_INFO'),
+            "One of SCRIPT_NAME or PATH_INFO are required (PATH_INFO "
+            "should at least be '/' if SCRIPT_NAME is empty)")
+    assert_(environ.get('SCRIPT_NAME') != '/',
+        "SCRIPT_NAME cannot be '/'; it should instead be '', and "
+        "PATH_INFO should be '/'")
+
+def check_input(wsgi_input):
+    for attr in ['read', 'readline', 'readlines', '__iter__']:
+        assert_(hasattr(wsgi_input, attr),
+            "wsgi.input (%r) doesn't have the attribute %s"
+            % (wsgi_input, attr))
+
+def check_errors(wsgi_errors):
+    for attr in ['flush', 'write', 'writelines']:
+        assert_(hasattr(wsgi_errors, attr),
+            "wsgi.errors (%r) doesn't have the attribute %s"
+            % (wsgi_errors, attr))
+
+def check_status(status):
+    assert_(type(status) is StringType,
+        "Status must be a string (not %r)" % status)
+    # Implicitly check that we can turn it into an integer:
+    status_code = status.split(None, 1)[0]
+    assert_(len(status_code) == 3,
+        "Status codes must be three characters: %r" % status_code)
+    status_int = int(status_code)
+    assert_(status_int >= 100, "Status code is invalid: %r" % status_int)
+    if len(status) < 4 or status[3] != ' ':
+        warnings.warn(
+            "The status string (%r) should be a three-digit integer "
+            "followed by a single space and a status explanation"
+            % status, WSGIWarning)
+
+def check_headers(headers):
+    assert_(type(headers) is ListType,
+        "Headers (%r) must be of type list: %r"
+        % (headers, type(headers)))
+    header_names = {}
+    for item in headers:
+        assert_(type(item) is TupleType,
+            "Individual headers (%r) must be of type tuple: %r"
+            % (item, type(item)))
+        assert_(len(item) == 2)
+        name, value = item
+        assert_(name.lower() != 'status',
+            "The Status header cannot be used; it conflicts with CGI "
+            "script, and HTTP status is not given through headers "
+            "(value: %r)." % value)
+        header_names[name.lower()] = None
+        assert_('\n' not in name and ':' not in name,
+            "Header names may not contain ':' or '\\n': %r" % name)
+        assert_(header_re.search(name), "Bad header name: %r" % name)
+        assert_(not name.endswith('-') and not name.endswith('_'),
+            "Names may not end in '-' or '_': %r" % name)
+        if bad_header_value_re.search(value):
+            assert_(0, "Bad header value: %r (bad char: %r)"
+            % (value, bad_header_value_re.search(value).group(0)))
+
+def check_content_type(status, headers):
+    code = int(status.split(None, 1)[0])
+    # @@: need one more person to verify this interpretation of RFC 2616
+    #     http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
+    NO_MESSAGE_BODY = (204, 304)
+    for name, value in headers:
+        if name.lower() == 'content-type':
+            if code not in NO_MESSAGE_BODY:
+                return
+            assert_(0, ("Content-Type header found in a %s response, "
+                        "which must not return content.") % code)
+    if code not in NO_MESSAGE_BODY:
+        assert_(0, "No Content-Type header found in headers (%s)" % headers)
+
+def check_exc_info(exc_info):
+    assert_(exc_info is None or type(exc_info) is type(()),
+        "exc_info (%r) is not a tuple: %r" % (exc_info, type(exc_info)))
+    # More exc_info checks?
+
+def check_iterator(iterator):
+    # Technically a string is legal, which is why it's a really bad
+    # idea, because it may cause the response to be returned
+    # character-by-character
+    assert_(not isinstance(iterator, str),
+        "You should not return a string as your application iterator, "
+        "instead return a single-item list containing that string.")

Added: vendor/Python/current/Lib/wsgiref.egg-info
===================================================================
--- vendor/Python/current/Lib/wsgiref.egg-info	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/wsgiref.egg-info	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,8 @@
+Metadata-Version: 1.0
+Name: wsgiref
+Version: 0.1.2
+Summary: WSGI (PEP 333) Reference Library
+Author: Phillip J. Eby
+Author-email: web-sig at python.org
+License: PSF or ZPL
+Platform: UNKNOWN

Added: vendor/Python/current/Lib/xdrlib.py
===================================================================
--- vendor/Python/current/Lib/xdrlib.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/xdrlib.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,287 @@
+"""Implements (a subset of) Sun XDR -- eXternal Data Representation.
+
+See: RFC 1014
+
+"""
+
+import struct
+try:
+    from cStringIO import StringIO as _StringIO
+except ImportError:
+    from StringIO import StringIO as _StringIO
+
+__all__ = ["Error", "Packer", "Unpacker", "ConversionError"]
+
+# exceptions
+class Error(Exception):
+    """Exception class for this module. Use:
+
+    except xdrlib.Error, var:
+        # var has the Error instance for the exception
+
+    Public ivars:
+        msg -- contains the message
+
+    """
+    def __init__(self, msg):
+        self.msg = msg
+    def __repr__(self):
+        return repr(self.msg)
+    def __str__(self):
+        return str(self.msg)
+
+
+class ConversionError(Error):
+    pass
+
+
+
+class Packer:
+    """Pack various data representations into a buffer."""
+
+    def __init__(self):
+        self.reset()
+
+    def reset(self):
+        self.__buf = _StringIO()
+
+    def get_buffer(self):
+        return self.__buf.getvalue()
+    # backwards compatibility
+    get_buf = get_buffer
+
+    def pack_uint(self, x):
+        self.__buf.write(struct.pack('>L', x))
+
+    pack_int = pack_uint
+    pack_enum = pack_int
+
+    def pack_bool(self, x):
+        if x: self.__buf.write('\0\0\0\1')
+        else: self.__buf.write('\0\0\0\0')
+
+    def pack_uhyper(self, x):
+        self.pack_uint(x>>32 & 0xffffffffL)
+        self.pack_uint(x & 0xffffffffL)
+
+    pack_hyper = pack_uhyper
+
+    def pack_float(self, x):
+        try: self.__buf.write(struct.pack('>f', x))
+        except struct.error, msg:
+            raise ConversionError, msg
+
+    def pack_double(self, x):
+        try: self.__buf.write(struct.pack('>d', x))
+        except struct.error, msg:
+            raise ConversionError, msg
+
+    def pack_fstring(self, n, s):
+        if n < 0:
+            raise ValueError, 'fstring size must be nonnegative'
+        data = s[:n]
+        n = ((n+3)//4)*4
+        data = data + (n - len(data)) * '\0'
+        self.__buf.write(data)
+
+    pack_fopaque = pack_fstring
+
+    def pack_string(self, s):
+        n = len(s)
+        self.pack_uint(n)
+        self.pack_fstring(n, s)
+
+    pack_opaque = pack_string
+    pack_bytes = pack_string
+
+    def pack_list(self, list, pack_item):
+        for item in list:
+            self.pack_uint(1)
+            pack_item(item)
+        self.pack_uint(0)
+
+    def pack_farray(self, n, list, pack_item):
+        if len(list) != n:
+            raise ValueError, 'wrong array size'
+        for item in list:
+            pack_item(item)
+
+    def pack_array(self, list, pack_item):
+        n = len(list)
+        self.pack_uint(n)
+        self.pack_farray(n, list, pack_item)
+
+
+
+class Unpacker:
+    """Unpacks various data representations from the given buffer."""
+
+    def __init__(self, data):
+        self.reset(data)
+
+    def reset(self, data):
+        self.__buf = data
+        self.__pos = 0
+
+    def get_position(self):
+        return self.__pos
+
+    def set_position(self, position):
+        self.__pos = position
+
+    def get_buffer(self):
+        return self.__buf
+
+    def done(self):
+        if self.__pos < len(self.__buf):
+            raise Error('unextracted data remains')
+
+    def unpack_uint(self):
+        i = self.__pos
+        self.__pos = j = i+4
+        data = self.__buf[i:j]
+        if len(data) < 4:
+            raise EOFError
+        x = struct.unpack('>L', data)[0]
+        try:
+            return int(x)
+        except OverflowError:
+            return x
+
+    def unpack_int(self):
+        i = self.__pos
+        self.__pos = j = i+4
+        data = self.__buf[i:j]
+        if len(data) < 4:
+            raise EOFError
+        return struct.unpack('>l', data)[0]
+
+    unpack_enum = unpack_int
+
+    def unpack_bool(self):
+        return bool(self.unpack_int())
+
+    def unpack_uhyper(self):
+        hi = self.unpack_uint()
+        lo = self.unpack_uint()
+        return long(hi)<<32 | lo
+
+    def unpack_hyper(self):
+        x = self.unpack_uhyper()
+        if x >= 0x8000000000000000L:
+            x = x - 0x10000000000000000L
+        return x
+
+    def unpack_float(self):
+        i = self.__pos
+        self.__pos = j = i+4
+        data = self.__buf[i:j]
+        if len(data) < 4:
+            raise EOFError
+        return struct.unpack('>f', data)[0]
+
+    def unpack_double(self):
+        i = self.__pos
+        self.__pos = j = i+8
+        data = self.__buf[i:j]
+        if len(data) < 8:
+            raise EOFError
+        return struct.unpack('>d', data)[0]
+
+    def unpack_fstring(self, n):
+        if n < 0:
+            raise ValueError, 'fstring size must be nonnegative'
+        i = self.__pos
+        j = i + (n+3)//4*4
+        if j > len(self.__buf):
+            raise EOFError
+        self.__pos = j
+        return self.__buf[i:i+n]
+
+    unpack_fopaque = unpack_fstring
+
+    def unpack_string(self):
+        n = self.unpack_uint()
+        return self.unpack_fstring(n)
+
+    unpack_opaque = unpack_string
+    unpack_bytes = unpack_string
+
+    def unpack_list(self, unpack_item):
+        list = []
+        while 1:
+            x = self.unpack_uint()
+            if x == 0: break
+            if x != 1:
+                raise ConversionError, '0 or 1 expected, got %r' % (x,)
+            item = unpack_item()
+            list.append(item)
+        return list
+
+    def unpack_farray(self, n, unpack_item):
+        list = []
+        for i in range(n):
+            list.append(unpack_item())
+        return list
+
+    def unpack_array(self, unpack_item):
+        n = self.unpack_uint()
+        return self.unpack_farray(n, unpack_item)
+
+
+# test suite
+def _test():
+    p = Packer()
+    packtest = [
+        (p.pack_uint,    (9,)),
+        (p.pack_bool,    (True,)),
+        (p.pack_bool,    (False,)),
+        (p.pack_uhyper,  (45L,)),
+        (p.pack_float,   (1.9,)),
+        (p.pack_double,  (1.9,)),
+        (p.pack_string,  ('hello world',)),
+        (p.pack_list,    (range(5), p.pack_uint)),
+        (p.pack_array,   (['what', 'is', 'hapnin', 'doctor'], p.pack_string)),
+        ]
+    succeedlist = [1] * len(packtest)
+    count = 0
+    for method, args in packtest:
+        print 'pack test', count,
+        try:
+            method(*args)
+            print 'succeeded'
+        except ConversionError, var:
+            print 'ConversionError:', var.msg
+            succeedlist[count] = 0
+        count = count + 1
+    data = p.get_buffer()
+    # now verify
+    up = Unpacker(data)
+    unpacktest = [
+        (up.unpack_uint,   (), lambda x: x == 9),
+        (up.unpack_bool,   (), lambda x: x is True),
+        (up.unpack_bool,   (), lambda x: x is False),
+        (up.unpack_uhyper, (), lambda x: x == 45L),
+        (up.unpack_float,  (), lambda x: 1.89 < x < 1.91),
+        (up.unpack_double, (), lambda x: 1.89 < x < 1.91),
+        (up.unpack_string, (), lambda x: x == 'hello world'),
+        (up.unpack_list,   (up.unpack_uint,), lambda x: x == range(5)),
+        (up.unpack_array,  (up.unpack_string,),
+         lambda x: x == ['what', 'is', 'hapnin', 'doctor']),
+        ]
+    count = 0
+    for method, args, pred in unpacktest:
+        print 'unpack test', count,
+        try:
+            if succeedlist[count]:
+                x = method(*args)
+                print pred(x) and 'succeeded' or 'failed', ':', x
+            else:
+                print 'skipping'
+        except ConversionError, var:
+            print 'ConversionError:', var.msg
+        count = count + 1
+
+
+if __name__ == '__main__':
+    _test()

Added: vendor/Python/current/Lib/xml/__init__.py
===================================================================
--- vendor/Python/current/Lib/xml/__init__.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/xml/__init__.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,47 @@
+"""Core XML support for Python.
+
+This package contains four sub-packages:
+
+dom -- The W3C Document Object Model.  This supports DOM Level 1 +
+       Namespaces.
+
+parsers -- Python wrappers for XML parsers (currently only supports Expat).
+
+sax -- The Simple API for XML, developed by XML-Dev, led by David
+       Megginson and ported to Python by Lars Marius Garshol.  This
+       supports the SAX 2 API.
+
+etree -- The ElementTree XML library.  This is a subset of the full
+       ElementTree XML release.
+
+"""
+
+
+__all__ = ["dom", "parsers", "sax", "etree"]
+
+# When being checked-out without options, this has the form
+# "<dollar>Revision: x.y </dollar>"
+# When exported using -kv, it is "x.y".
+__version__ = "$Revision: 41660 $".split()[-2:][0]
+
+
+_MINIMUM_XMLPLUS_VERSION = (0, 8, 4)
+
+
+try:
+    import _xmlplus
+except ImportError:
+    pass
+else:
+    try:
+        v = _xmlplus.version_info
+    except AttributeError:
+        # _xmlplus is too old; ignore it
+        pass
+    else:
+        if v >= _MINIMUM_XMLPLUS_VERSION:
+            import sys
+            _xmlplus.__path__.extend(__path__)
+            sys.modules[__name__] = _xmlplus
+        else:
+            del v

Added: vendor/Python/current/Lib/xml/dom/NodeFilter.py
===================================================================
--- vendor/Python/current/Lib/xml/dom/NodeFilter.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/xml/dom/NodeFilter.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,27 @@
+# This is the Python mapping for interface NodeFilter from
+# DOM2-Traversal-Range. It contains only constants.
+
+class NodeFilter:
+    """
+    This is the DOM2 NodeFilter interface. It contains only constants.
+    """
+    FILTER_ACCEPT = 1
+    FILTER_REJECT = 2
+    FILTER_SKIP   = 3
+
+    SHOW_ALL                    = 0xFFFFFFFFL
+    SHOW_ELEMENT                = 0x00000001
+    SHOW_ATTRIBUTE              = 0x00000002
+    SHOW_TEXT                   = 0x00000004
+    SHOW_CDATA_SECTION          = 0x00000008
+    SHOW_ENTITY_REFERENCE       = 0x00000010
+    SHOW_ENTITY                 = 0x00000020
+    SHOW_PROCESSING_INSTRUCTION = 0x00000040
+    SHOW_COMMENT                = 0x00000080
+    SHOW_DOCUMENT               = 0x00000100
+    SHOW_DOCUMENT_TYPE          = 0x00000200
+    SHOW_DOCUMENT_FRAGMENT      = 0x00000400
+    SHOW_NOTATION               = 0x00000800
+
+    def acceptNode(self, node):
+        raise NotImplementedError

Added: vendor/Python/current/Lib/xml/dom/__init__.py
===================================================================
--- vendor/Python/current/Lib/xml/dom/__init__.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/xml/dom/__init__.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,139 @@
+"""W3C Document Object Model implementation for Python.
+
+The Python mapping of the Document Object Model is documented in the
+Python Library Reference in the section on the xml.dom package.
+
+This package contains the following modules:
+
+minidom -- A simple implementation of the Level 1 DOM with namespace
+           support added (based on the Level 2 specification) and other
+           minor Level 2 functionality.
+
+pulldom -- DOM builder supporting on-demand tree-building for selected
+           subtrees of the document.
+
+"""
+
+
+class Node:
+    """Class giving the NodeType constants."""
+
+    # DOM implementations may use this as a base class for their own
+    # Node implementations.  If they don't, the constants defined here
+    # should still be used as the canonical definitions as they match
+    # the values given in the W3C recommendation.  Client code can
+    # safely refer to these values in all tests of Node.nodeType
+    # values.
+
+    ELEMENT_NODE                = 1
+    ATTRIBUTE_NODE              = 2
+    TEXT_NODE                   = 3
+    CDATA_SECTION_NODE          = 4
+    ENTITY_REFERENCE_NODE       = 5
+    ENTITY_NODE                 = 6
+    PROCESSING_INSTRUCTION_NODE = 7
+    COMMENT_NODE                = 8
+    DOCUMENT_NODE               = 9
+    DOCUMENT_TYPE_NODE          = 10
+    DOCUMENT_FRAGMENT_NODE      = 11
+    NOTATION_NODE               = 12
+
+
+#ExceptionCode
+INDEX_SIZE_ERR                 = 1
+DOMSTRING_SIZE_ERR             = 2
+HIERARCHY_REQUEST_ERR          = 3
+WRONG_DOCUMENT_ERR             = 4
+INVALID_CHARACTER_ERR          = 5
+NO_DATA_ALLOWED_ERR            = 6
+NO_MODIFICATION_ALLOWED_ERR    = 7
+NOT_FOUND_ERR                  = 8
+NOT_SUPPORTED_ERR              = 9
+INUSE_ATTRIBUTE_ERR            = 10
+INVALID_STATE_ERR              = 11
+SYNTAX_ERR                     = 12
+INVALID_MODIFICATION_ERR       = 13
+NAMESPACE_ERR                  = 14
+INVALID_ACCESS_ERR             = 15
+VALIDATION_ERR                 = 16
+
+
+class DOMException(Exception):
+    """Abstract base class for DOM exceptions.
+    Exceptions with specific codes are specializations of this class."""
+
+    def __init__(self, *args, **kw):
+        if self.__class__ is DOMException:
+            raise RuntimeError(
+                "DOMException should not be instantiated directly")
+        Exception.__init__(self, *args, **kw)
+
+    def _get_code(self):
+        return self.code
+
+
+class IndexSizeErr(DOMException):
+    code = INDEX_SIZE_ERR
+
+class DomstringSizeErr(DOMException):
+    code = DOMSTRING_SIZE_ERR
+
+class HierarchyRequestErr(DOMException):
+    code = HIERARCHY_REQUEST_ERR
+
+class WrongDocumentErr(DOMException):
+    code = WRONG_DOCUMENT_ERR
+
+class InvalidCharacterErr(DOMException):
+    code = INVALID_CHARACTER_ERR
+
+class NoDataAllowedErr(DOMException):
+    code = NO_DATA_ALLOWED_ERR
+
+class NoModificationAllowedErr(DOMException):
+    code = NO_MODIFICATION_ALLOWED_ERR
+
+class NotFoundErr(DOMException):
+    code = NOT_FOUND_ERR
+
+class NotSupportedErr(DOMException):
+    code = NOT_SUPPORTED_ERR
+
+class InuseAttributeErr(DOMException):
+    code = INUSE_ATTRIBUTE_ERR
+
+class InvalidStateErr(DOMException):
+    code = INVALID_STATE_ERR
+
+class SyntaxErr(DOMException):
+    code = SYNTAX_ERR
+
+class InvalidModificationErr(DOMException):
+    code = INVALID_MODIFICATION_ERR
+
+class NamespaceErr(DOMException):
+    code = NAMESPACE_ERR
+
+class InvalidAccessErr(DOMException):
+    code = INVALID_ACCESS_ERR
+
+class ValidationErr(DOMException):
+    code = VALIDATION_ERR
+
+class UserDataHandler:
+    """Class giving the operation constants for UserDataHandler.handle()."""
+
+    # Based on DOM Level 3 (WD 9 April 2002)
+
+    NODE_CLONED   = 1
+    NODE_IMPORTED = 2
+    NODE_DELETED  = 3
+    NODE_RENAMED  = 4
+
+XML_NAMESPACE = "http://www.w3.org/XML/1998/namespace"
+XMLNS_NAMESPACE = "http://www.w3.org/2000/xmlns/"
+XHTML_NAMESPACE = "http://www.w3.org/1999/xhtml"
+EMPTY_NAMESPACE = None
+EMPTY_PREFIX = None
+
+from domreg import getDOMImplementation,registerDOMImplementation

Added: vendor/Python/current/Lib/xml/dom/domreg.py
===================================================================
--- vendor/Python/current/Lib/xml/dom/domreg.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/xml/dom/domreg.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,99 @@
+"""Registration facilities for DOM. This module should not be used
+directly. Instead, the functions getDOMImplementation and
+registerDOMImplementation should be imported from xml.dom."""
+
+from xml.dom.minicompat import *  # isinstance, StringTypes
+
+# This is a list of well-known implementations.  Well-known names
+# should be published by posting to xml-sig at python.org, and are
+# subsequently recorded in this file.
+
+well_known_implementations = {
+    'minidom':'xml.dom.minidom',
+    '4DOM': 'xml.dom.DOMImplementation',
+    }
+
+# DOM implementations not officially registered should register
+# themselves with their
+
+registered = {}
+
+def registerDOMImplementation(name, factory):
+    """registerDOMImplementation(name, factory)
+
+    Register the factory function with the name. The factory function
+    should return an object which implements the DOMImplementation
+    interface. The factory function can either return the same object,
+    or a new one (e.g. if that implementation supports some
+    customization)."""
+
+    registered[name] = factory
+
+def _good_enough(dom, features):
+    "_good_enough(dom, features) -> Return 1 if the dom offers the features"
+    for f,v in features:
+        if not dom.hasFeature(f,v):
+            return 0
+    return 1
+
+def getDOMImplementation(name = None, features = ()):
+    """getDOMImplementation(name = None, features = ()) -> DOM implementation.
+
+    Return a suitable DOM implementation. The name is either
+    well-known, the module name of a DOM implementation, or None. If
+    it is not None, imports the corresponding module and returns
+    DOMImplementation object if the import succeeds.
+
+    If name is not given, consider the available implementations to
+    find one with the required feature set. If no implementation can
+    be found, raise an ImportError. The features list must be a sequence
+    of (feature, version) pairs which are passed to hasFeature."""
+
+    import os
+    creator = None
+    mod = well_known_implementations.get(name)
+    if mod:
+        mod = __import__(mod, {}, {}, ['getDOMImplementation'])
+        return mod.getDOMImplementation()
+    elif name:
+        return registered[name]()
+    elif os.environ.has_key("PYTHON_DOM"):
+        return getDOMImplementation(name = os.environ["PYTHON_DOM"])
+
+    # User did not specify a name, try implementations in arbitrary
+    # order, returning the one that has the required features
+    if isinstance(features, StringTypes):
+        features = _parse_feature_string(features)
+    for creator in registered.values():
+        dom = creator()
+        if _good_enough(dom, features):
+            return dom
+
+    for creator in well_known_implementations.keys():
+        try:
+            dom = getDOMImplementation(name = creator)
+        except StandardError: # typically ImportError, or AttributeError
+            continue
+        if _good_enough(dom, features):
+            return dom
+
+    raise ImportError,"no suitable DOM implementation found"
+
+def _parse_feature_string(s):
+    features = []
+    parts = s.split()
+    i = 0
+    length = len(parts)
+    while i < length:
+        feature = parts[i]
+        if feature[0] in "0123456789":
+            raise ValueError, "bad feature name: %r" % (feature,)
+        i = i + 1
+        version = None
+        if i < length:
+            v = parts[i]
+            if v[0] in "0123456789":
+                i = i + 1
+                version = v
+        features.append((feature, version))
+    return tuple(features)

Added: vendor/Python/current/Lib/xml/dom/expatbuilder.py
===================================================================
--- vendor/Python/current/Lib/xml/dom/expatbuilder.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/xml/dom/expatbuilder.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,983 @@
+"""Facility to use the Expat parser to load a minidom instance
+from a string or file.
+
+This avoids all the overhead of SAX and pulldom to gain performance.
+"""
+
+# Warning!
+#
+# This module is tightly bound to the implementation details of the
+# minidom DOM and can't be used with other DOM implementations.  This
+# is due, in part, to a lack of appropriate methods in the DOM (there is
+# no way to create Entity and Notation nodes via the DOM Level 2
+# interface), and for performance.  The later is the cause of some fairly
+# cryptic code.
+#
+# Performance hacks:
+#
+#   -  .character_data_handler() has an extra case in which continuing
+#      data is appended to an existing Text node; this can be a
+#      speedup since pyexpat can break up character data into multiple
+#      callbacks even though we set the buffer_text attribute on the
+#      parser.  This also gives us the advantage that we don't need a
+#      separate normalization pass.
+#
+#   -  Determining that a node exists is done using an identity comparison
+#      with None rather than a truth test; this avoids searching for and
+#      calling any methods on the node object if it exists.  (A rather
+#      nice speedup is achieved this way as well!)
+
+from xml.dom import xmlbuilder, minidom, Node
+from xml.dom import EMPTY_NAMESPACE, EMPTY_PREFIX, XMLNS_NAMESPACE
+from xml.parsers import expat
+from xml.dom.minidom import _append_child, _set_attribute_node
+from xml.dom.NodeFilter import NodeFilter
+
+from xml.dom.minicompat import *
+
+TEXT_NODE = Node.TEXT_NODE
+CDATA_SECTION_NODE = Node.CDATA_SECTION_NODE
+DOCUMENT_NODE = Node.DOCUMENT_NODE
+
+FILTER_ACCEPT = xmlbuilder.DOMBuilderFilter.FILTER_ACCEPT
+FILTER_REJECT = xmlbuilder.DOMBuilderFilter.FILTER_REJECT
+FILTER_SKIP = xmlbuilder.DOMBuilderFilter.FILTER_SKIP
+FILTER_INTERRUPT = xmlbuilder.DOMBuilderFilter.FILTER_INTERRUPT
+
+theDOMImplementation = minidom.getDOMImplementation()
+
+# Expat typename -> TypeInfo
+_typeinfo_map = {
+    "CDATA":    minidom.TypeInfo(None, "cdata"),
+    "ENUM":     minidom.TypeInfo(None, "enumeration"),
+    "ENTITY":   minidom.TypeInfo(None, "entity"),
+    "ENTITIES": minidom.TypeInfo(None, "entities"),
+    "ID":       minidom.TypeInfo(None, "id"),
+    "IDREF":    minidom.TypeInfo(None, "idref"),
+    "IDREFS":   minidom.TypeInfo(None, "idrefs"),
+    "NMTOKEN":  minidom.TypeInfo(None, "nmtoken"),
+    "NMTOKENS": minidom.TypeInfo(None, "nmtokens"),
+    }
+
+class ElementInfo(object):
+    __slots__ = '_attr_info', '_model', 'tagName'
+
+    def __init__(self, tagName, model=None):
+        self.tagName = tagName
+        self._attr_info = []
+        self._model = model
+
+    def __getstate__(self):
+        return self._attr_info, self._model, self.tagName
+
+    def __setstate__(self, state):
+        self._attr_info, self._model, self.tagName = state
+
+    def getAttributeType(self, aname):
+        for info in self._attr_info:
+            if info[1] == aname:
+                t = info[-2]
+                if t[0] == "(":
+                    return _typeinfo_map["ENUM"]
+                else:
+                    return _typeinfo_map[info[-2]]
+        return minidom._no_type
+
+    def getAttributeTypeNS(self, namespaceURI, localName):
+        return minidom._no_type
+
+    def isElementContent(self):
+        if self._model:
+            type = self._model[0]
+            return type not in (expat.model.XML_CTYPE_ANY,
+                                expat.model.XML_CTYPE_MIXED)
+        else:
+            return False
+
+    def isEmpty(self):
+        if self._model:
+            return self._model[0] == expat.model.XML_CTYPE_EMPTY
+        else:
+            return False
+
+    def isId(self, aname):
+        for info in self._attr_info:
+            if info[1] == aname:
+                return info[-2] == "ID"
+        return False
+
+    def isIdNS(self, euri, ename, auri, aname):
+        # not sure this is meaningful
+        return self.isId((auri, aname))
+
+def _intern(builder, s):
+    return builder._intern_setdefault(s, s)
+
+def _parse_ns_name(builder, name):
+    assert ' ' in name
+    parts = name.split(' ')
+    intern = builder._intern_setdefault
+    if len(parts) == 3:
+        uri, localname, prefix = parts
+        prefix = intern(prefix, prefix)
+        qname = "%s:%s" % (prefix, localname)
+        qname = intern(qname, qname)
+        localname = intern(localname, localname)
+    else:
+        uri, localname = parts
+        prefix = EMPTY_PREFIX
+        qname = localname = intern(localname, localname)
+    return intern(uri, uri), localname, prefix, qname
+
+
+class ExpatBuilder:
+    """Document builder that uses Expat to build a ParsedXML.DOM document
+    instance."""
+
+    def __init__(self, options=None):
+        if options is None:
+            options = xmlbuilder.Options()
+        self._options = options
+        if self._options.filter is not None:
+            self._filter = FilterVisibilityController(self._options.filter)
+        else:
+            self._filter = None
+            # This *really* doesn't do anything in this case, so
+            # override it with something fast & minimal.
+            self._finish_start_element = id
+        self._parser = None
+        self.reset()
+
+    def createParser(self):
+        """Create a new parser object."""
+        return expat.ParserCreate()
+
+    def getParser(self):
+        """Return the parser object, creating a new one if needed."""
+        if not self._parser:
+            self._parser = self.createParser()
+            self._intern_setdefault = self._parser.intern.setdefault
+            self._parser.buffer_text = True
+            self._parser.ordered_attributes = True
+            self._parser.specified_attributes = True
+            self.install(self._parser)
+        return self._parser
+
+    def reset(self):
+        """Free all data structures used during DOM construction."""
+        self.document = theDOMImplementation.createDocument(
+            EMPTY_NAMESPACE, None, None)
+        self.curNode = self.document
+        self._elem_info = self.document._elem_info
+        self._cdata = False
+
+    def install(self, parser):
+        """Install the callbacks needed to build the DOM into the parser."""
+        # This creates circular references!
+        parser.StartDoctypeDeclHandler = self.start_doctype_decl_handler
+        parser.StartElementHandler = self.first_element_handler
+        parser.EndElementHandler = self.end_element_handler
+        parser.ProcessingInstructionHandler = self.pi_handler
+        if self._options.entities:
+            parser.EntityDeclHandler = self.entity_decl_handler
+        parser.NotationDeclHandler = self.notation_decl_handler
+        if self._options.comments:
+            parser.CommentHandler = self.comment_handler
+        if self._options.cdata_sections:
+            parser.StartCdataSectionHandler = self.start_cdata_section_handler
+            parser.EndCdataSectionHandler = self.end_cdata_section_handler
+            parser.CharacterDataHandler = self.character_data_handler_cdata
+        else:
+            parser.CharacterDataHandler = self.character_data_handler
+        parser.ExternalEntityRefHandler = self.external_entity_ref_handler
+        parser.XmlDeclHandler = self.xml_decl_handler
+        parser.ElementDeclHandler = self.element_decl_handler
+        parser.AttlistDeclHandler = self.attlist_decl_handler
+
+    def parseFile(self, file):
+        """Parse a document from a file object, returning the document
+        node."""
+        parser = self.getParser()
+        first_buffer = True
+        try:
+            while 1:
+                buffer = file.read(16*1024)
+                if not buffer:
+                    break
+                parser.Parse(buffer, 0)
+                if first_buffer and self.document.documentElement:
+                    self._setup_subset(buffer)
+                first_buffer = False
+            parser.Parse("", True)
+        except ParseEscape:
+            pass
+        doc = self.document
+        self.reset()
+        self._parser = None
+        return doc
+
+    def parseString(self, string):
+        """Parse a document from a string, returning the document node."""
+        parser = self.getParser()
+        try:
+            parser.Parse(string, True)
+            self._setup_subset(string)
+        except ParseEscape:
+            pass
+        doc = self.document
+        self.reset()
+        self._parser = None
+        return doc
+
+    def _setup_subset(self, buffer):
+        """Load the internal subset if there might be one."""
+        if self.document.doctype:
+            extractor = InternalSubsetExtractor()
+            extractor.parseString(buffer)
+            subset = extractor.getSubset()
+            self.document.doctype.internalSubset = subset
+
+    def start_doctype_decl_handler(self, doctypeName, systemId, publicId,
+                                   has_internal_subset):
+        doctype = self.document.implementation.createDocumentType(
+            doctypeName, publicId, systemId)
+        doctype.ownerDocument = self.document
+        self.document.childNodes.append(doctype)
+        self.document.doctype = doctype
+        if self._filter and self._filter.acceptNode(doctype) == FILTER_REJECT:
+            self.document.doctype = None
+            del self.document.childNodes[-1]
+            doctype = None
+            self._parser.EntityDeclHandler = None
+            self._parser.NotationDeclHandler = None
+        if has_internal_subset:
+            if doctype is not None:
+                doctype.entities._seq = []
+                doctype.notations._seq = []
+            self._parser.CommentHandler = None
+            self._parser.ProcessingInstructionHandler = None
+            self._parser.EndDoctypeDeclHandler = self.end_doctype_decl_handler
+
+    def end_doctype_decl_handler(self):
+        if self._options.comments:
+            self._parser.CommentHandler = self.comment_handler
+        self._parser.ProcessingInstructionHandler = self.pi_handler
+        if not (self._elem_info or self._filter):
+            self._finish_end_element = id
+
+    def pi_handler(self, target, data):
+        node = self.document.createProcessingInstruction(target, data)
+        _append_child(self.curNode, node)
+        if self._filter and self._filter.acceptNode(node) == FILTER_REJECT:
+            self.curNode.removeChild(node)
+
+    def character_data_handler_cdata(self, data):
+        childNodes = self.curNode.childNodes
+        if self._cdata:
+            if (  self._cdata_continue
+                  and childNodes[-1].nodeType == CDATA_SECTION_NODE):
+                childNodes[-1].appendData(data)
+                return
+            node = self.document.createCDATASection(data)
+            self._cdata_continue = True
+        elif childNodes and childNodes[-1].nodeType == TEXT_NODE:
+            node = childNodes[-1]
+            value = node.data + data
+            d = node.__dict__
+            d['data'] = d['nodeValue'] = value
+            return
+        else:
+            node = minidom.Text()
+            d = node.__dict__
+            d['data'] = d['nodeValue'] = data
+            d['ownerDocument'] = self.document
+        _append_child(self.curNode, node)
+
+    def character_data_handler(self, data):
+        childNodes = self.curNode.childNodes
+        if childNodes and childNodes[-1].nodeType == TEXT_NODE:
+            node = childNodes[-1]
+            d = node.__dict__
+            d['data'] = d['nodeValue'] = node.data + data
+            return
+        node = minidom.Text()
+        d = node.__dict__
+        d['data'] = d['nodeValue'] = node.data + data
+        d['ownerDocument'] = self.document
+        _append_child(self.curNode, node)
+
+    def entity_decl_handler(self, entityName, is_parameter_entity, value,
+                            base, systemId, publicId, notationName):
+        if is_parameter_entity:
+            # we don't care about parameter entities for the DOM
+            return
+        if not self._options.entities:
+            return
+        node = self.document._create_entity(entityName, publicId,
+                                            systemId, notationName)
+        if value is not None:
+            # internal entity
+            # node *should* be readonly, but we'll cheat
+            child = self.document.createTextNode(value)
+            node.childNodes.append(child)
+        self.document.doctype.entities._seq.append(node)
+        if self._filter and self._filter.acceptNode(node) == FILTER_REJECT:
+            del self.document.doctype.entities._seq[-1]
+
+    def notation_decl_handler(self, notationName, base, systemId, publicId):
+        node = self.document._create_notation(notationName, publicId, systemId)
+        self.document.doctype.notations._seq.append(node)
+        if self._filter and self._filter.acceptNode(node) == FILTER_ACCEPT:
+            del self.document.doctype.notations._seq[-1]
+
+    def comment_handler(self, data):
+        node = self.document.createComment(data)
+        _append_child(self.curNode, node)
+        if self._filter and self._filter.acceptNode(node) == FILTER_REJECT:
+            self.curNode.removeChild(node)
+
+    def start_cdata_section_handler(self):
+        self._cdata = True
+        self._cdata_continue = False
+
+    def end_cdata_section_handler(self):
+        self._cdata = False
+        self._cdata_continue = False
+
+    def external_entity_ref_handler(self, context, base, systemId, publicId):
+        return 1
+
+    def first_element_handler(self, name, attributes):
+        if self._filter is None and not self._elem_info:
+            self._finish_end_element = id
+        self.getParser().StartElementHandler = self.start_element_handler
+        self.start_element_handler(name, attributes)
+
+    def start_element_handler(self, name, attributes):
+        node = self.document.createElement(name)
+        _append_child(self.curNode, node)
+        self.curNode = node
+
+        if attributes:
+            for i in range(0, len(attributes), 2):
+                a = minidom.Attr(attributes[i], EMPTY_NAMESPACE,
+                                 None, EMPTY_PREFIX)
+                value = attributes[i+1]
+                d = a.childNodes[0].__dict__
+                d['data'] = d['nodeValue'] = value
+                d = a.__dict__
+                d['value'] = d['nodeValue'] = value
+                d['ownerDocument'] = self.document
+                _set_attribute_node(node, a)
+
+        if node is not self.document.documentElement:
+            self._finish_start_element(node)
+
+    def _finish_start_element(self, node):
+        if self._filter:
+            # To be general, we'd have to call isSameNode(), but this
+            # is sufficient for minidom:
+            if node is self.document.documentElement:
+                return
+            filt = self._filter.startContainer(node)
+            if filt == FILTER_REJECT:
+                # ignore this node & all descendents
+                Rejecter(self)
+            elif filt == FILTER_SKIP:
+                # ignore this node, but make it's children become
+                # children of the parent node
+                Skipper(self)
+            else:
+                return
+            self.curNode = node.parentNode
+            node.parentNode.removeChild(node)
+            node.unlink()
+
+    # If this ever changes, Namespaces.end_element_handler() needs to
+    # be changed to match.
+    #
+    def end_element_handler(self, name):
+        curNode = self.curNode
+        self.curNode = curNode.parentNode
+        self._finish_end_element(curNode)
+
+    def _finish_end_element(self, curNode):
+        info = self._elem_info.get(curNode.tagName)
+        if info:
+            self._handle_white_text_nodes(curNode, info)
+        if self._filter:
+            if curNode is self.document.documentElement:
+                return
+            if self._filter.acceptNode(curNode) == FILTER_REJECT:
+                self.curNode.removeChild(curNode)
+                curNode.unlink()
+
+    def _handle_white_text_nodes(self, node, info):
+        if (self._options.whitespace_in_element_content
+            or not info.isElementContent()):
+            return
+
+        # We have element type information and should remove ignorable
+        # whitespace; identify for text nodes which contain only
+        # whitespace.
+        L = []
+        for child in node.childNodes:
+            if child.nodeType == TEXT_NODE and not child.data.strip():
+                L.append(child)
+
+        # Remove ignorable whitespace from the tree.
+        for child in L:
+            node.removeChild(child)
+
+    def element_decl_handler(self, name, model):
+        info = self._elem_info.get(name)
+        if info is None:
+            self._elem_info[name] = ElementInfo(name, model)
+        else:
+            assert info._model is None
+            info._model = model
+
+    def attlist_decl_handler(self, elem, name, type, default, required):
+        info = self._elem_info.get(elem)
+        if info is None:
+            info = ElementInfo(elem)
+            self._elem_info[elem] = info
+        info._attr_info.append(
+            [None, name, None, None, default, 0, type, required])
+
+    def xml_decl_handler(self, version, encoding, standalone):
+        self.document.version = version
+        self.document.encoding = encoding
+        # This is still a little ugly, thanks to the pyexpat API. ;-(
+        if standalone >= 0:
+            if standalone:
+                self.document.standalone = True
+            else:
+                self.document.standalone = False
+
+
+# Don't include FILTER_INTERRUPT, since that's checked separately
+# where allowed.
+_ALLOWED_FILTER_RETURNS = (FILTER_ACCEPT, FILTER_REJECT, FILTER_SKIP)
+
+class FilterVisibilityController(object):
+    """Wrapper around a DOMBuilderFilter which implements the checks
+    to make the whatToShow filter attribute work."""
+
+    __slots__ = 'filter',
+
+    def __init__(self, filter):
+        self.filter = filter
+
+    def startContainer(self, node):
+        mask = self._nodetype_mask[node.nodeType]
+        if self.filter.whatToShow & mask:
+            val = self.filter.startContainer(node)
+            if val == FILTER_INTERRUPT:
+                raise ParseEscape
+            if val not in _ALLOWED_FILTER_RETURNS:
+                raise ValueError, \
+                      "startContainer() returned illegal value: " + repr(val)
+            return val
+        else:
+            return FILTER_ACCEPT
+
+    def acceptNode(self, node):
+        mask = self._nodetype_mask[node.nodeType]
+        if self.filter.whatToShow & mask:
+            val = self.filter.acceptNode(node)
+            if val == FILTER_INTERRUPT:
+                raise ParseEscape
+            if val == FILTER_SKIP:
+                # move all child nodes to the parent, and remove this node
+                parent = node.parentNode
+                for child in node.childNodes[:]:
+                    parent.appendChild(child)
+                # node is handled by the caller
+                return FILTER_REJECT
+            if val not in _ALLOWED_FILTER_RETURNS:
+                raise ValueError, \
+                      "acceptNode() returned illegal value: " + repr(val)
+            return val
+        else:
+            return FILTER_ACCEPT
+
+    _nodetype_mask = {
+        Node.ELEMENT_NODE:                NodeFilter.SHOW_ELEMENT,
+        Node.ATTRIBUTE_NODE:              NodeFilter.SHOW_ATTRIBUTE,
+        Node.TEXT_NODE:                   NodeFilter.SHOW_TEXT,
+        Node.CDATA_SECTION_NODE:          NodeFilter.SHOW_CDATA_SECTION,
+        Node.ENTITY_REFERENCE_NODE:       NodeFilter.SHOW_ENTITY_REFERENCE,
+        Node.ENTITY_NODE:                 NodeFilter.SHOW_ENTITY,
+        Node.PROCESSING_INSTRUCTION_NODE: NodeFilter.SHOW_PROCESSING_INSTRUCTION,
+        Node.COMMENT_NODE:                NodeFilter.SHOW_COMMENT,
+        Node.DOCUMENT_NODE:               NodeFilter.SHOW_DOCUMENT,
+        Node.DOCUMENT_TYPE_NODE:          NodeFilter.SHOW_DOCUMENT_TYPE,
+        Node.DOCUMENT_FRAGMENT_NODE:      NodeFilter.SHOW_DOCUMENT_FRAGMENT,
+        Node.NOTATION_NODE:               NodeFilter.SHOW_NOTATION,
+        }
+
+
+class FilterCrutch(object):
+    __slots__ = '_builder', '_level', '_old_start', '_old_end'
+
+    def __init__(self, builder):
+        self._level = 0
+        self._builder = builder
+        parser = builder._parser
+        self._old_start = parser.StartElementHandler
+        self._old_end = parser.EndElementHandler
+        parser.StartElementHandler = self.start_element_handler
+        parser.EndElementHandler = self.end_element_handler
+
+class Rejecter(FilterCrutch):
+    __slots__ = ()
+
+    def __init__(self, builder):
+        FilterCrutch.__init__(self, builder)
+        parser = builder._parser
+        for name in ("ProcessingInstructionHandler",
+                     "CommentHandler",
+                     "CharacterDataHandler",
+                     "StartCdataSectionHandler",
+                     "EndCdataSectionHandler",
+                     "ExternalEntityRefHandler",
+                     ):
+            setattr(parser, name, None)
+
+    def start_element_handler(self, *args):
+        self._level = self._level + 1
+
+    def end_element_handler(self, *args):
+        if self._level == 0:
+            # restore the old handlers
+            parser = self._builder._parser
+            self._builder.install(parser)
+            parser.StartElementHandler = self._old_start
+            parser.EndElementHandler = self._old_end
+        else:
+            self._level = self._level - 1
+
+class Skipper(FilterCrutch):
+    __slots__ = ()
+
+    def start_element_handler(self, *args):
+        node = self._builder.curNode
+        self._old_start(*args)
+        if self._builder.curNode is not node:
+            self._level = self._level + 1
+
+    def end_element_handler(self, *args):
+        if self._level == 0:
+            # We're popping back out of the node we're skipping, so we
+            # shouldn't need to do anything but reset the handlers.
+            self._builder._parser.StartElementHandler = self._old_start
+            self._builder._parser.EndElementHandler = self._old_end
+            self._builder = None
+        else:
+            self._level = self._level - 1
+            self._old_end(*args)
+
+
+# framework document used by the fragment builder.
+# Takes a string for the doctype, subset string, and namespace attrs string.
+
+_FRAGMENT_BUILDER_INTERNAL_SYSTEM_ID = \
+    "http://xml.python.org/entities/fragment-builder/internal"
+
+_FRAGMENT_BUILDER_TEMPLATE = (
+    '''\
+<!DOCTYPE wrapper
+  %%s [
+  <!ENTITY fragment-builder-internal
+    SYSTEM "%s">
+%%s
+]>
+<wrapper %%s
+>&fragment-builder-internal;</wrapper>'''
+    % _FRAGMENT_BUILDER_INTERNAL_SYSTEM_ID)
+
+
+class FragmentBuilder(ExpatBuilder):
+    """Builder which constructs document fragments given XML source
+    text and a context node.
+
+    The context node is expected to provide information about the
+    namespace declarations which are in scope at the start of the
+    fragment.
+    """
+
+    def __init__(self, context, options=None):
+        if context.nodeType == DOCUMENT_NODE:
+            self.originalDocument = context
+            self.context = context
+        else:
+            self.originalDocument = context.ownerDocument
+            self.context = context
+        ExpatBuilder.__init__(self, options)
+
+    def reset(self):
+        ExpatBuilder.reset(self)
+        self.fragment = None
+
+    def parseFile(self, file):
+        """Parse a document fragment from a file object, returning the
+        fragment node."""
+        return self.parseString(file.read())
+
+    def parseString(self, string):
+        """Parse a document fragment from a string, returning the
+        fragment node."""
+        self._source = string
+        parser = self.getParser()
+        doctype = self.originalDocument.doctype
+        ident = ""
+        if doctype:
+            subset = doctype.internalSubset or self._getDeclarations()
+            if doctype.publicId:
+                ident = ('PUBLIC "%s" "%s"'
+                         % (doctype.publicId, doctype.systemId))
+            elif doctype.systemId:
+                ident = 'SYSTEM "%s"' % doctype.systemId
+        else:
+            subset = ""
+        nsattrs = self._getNSattrs() # get ns decls from node's ancestors
+        document = _FRAGMENT_BUILDER_TEMPLATE % (ident, subset, nsattrs)
+        try:
+            parser.Parse(document, 1)
+        except:
+            self.reset()
+            raise
+        fragment = self.fragment
+        self.reset()
+##         self._parser = None
+        return fragment
+
+    def _getDeclarations(self):
+        """Re-create the internal subset from the DocumentType node.
+
+        This is only needed if we don't already have the
+        internalSubset as a string.
+        """
+        doctype = self.context.ownerDocument.doctype
+        s = ""
+        if doctype:
+            for i in range(doctype.notations.length):
+                notation = doctype.notations.item(i)
+                if s:
+                    s = s + "\n  "
+                s = "%s<!NOTATION %s" % (s, notation.nodeName)
+                if notation.publicId:
+                    s = '%s PUBLIC "%s"\n             "%s">' \
+                        % (s, notation.publicId, notation.systemId)
+                else:
+                    s = '%s SYSTEM "%s">' % (s, notation.systemId)
+            for i in range(doctype.entities.length):
+                entity = doctype.entities.item(i)
+                if s:
+                    s = s + "\n  "
+                s = "%s<!ENTITY %s" % (s, entity.nodeName)
+                if entity.publicId:
+                    s = '%s PUBLIC "%s"\n             "%s"' \
+                        % (s, entity.publicId, entity.systemId)
+                elif entity.systemId:
+                    s = '%s SYSTEM "%s"' % (s, entity.systemId)
+                else:
+                    s = '%s "%s"' % (s, entity.firstChild.data)
+                if entity.notationName:
+                    s = "%s NOTATION %s" % (s, entity.notationName)
+                s = s + ">"
+        return s
+
+    def _getNSattrs(self):
+        return ""
+
+    def external_entity_ref_handler(self, context, base, systemId, publicId):
+        if systemId == _FRAGMENT_BUILDER_INTERNAL_SYSTEM_ID:
+            # this entref is the one that we made to put the subtree
+            # in; all of our given input is parsed in here.
+            old_document = self.document
+            old_cur_node = self.curNode
+            parser = self._parser.ExternalEntityParserCreate(context)
+            # put the real document back, parse into the fragment to return
+            self.document = self.originalDocument
+            self.fragment = self.document.createDocumentFragment()
+            self.curNode = self.fragment
+            try:
+                parser.Parse(self._source, 1)
+            finally:
+                self.curNode = old_cur_node
+                self.document = old_document
+                self._source = None
+            return -1
+        else:
+            return ExpatBuilder.external_entity_ref_handler(
+                self, context, base, systemId, publicId)
+
+
+class Namespaces:
+    """Mix-in class for builders; adds support for namespaces."""
+
+    def _initNamespaces(self):
+        # list of (prefix, uri) ns declarations.  Namespace attrs are
+        # constructed from this and added to the element's attrs.
+        self._ns_ordered_prefixes = []
+
+    def createParser(self):
+        """Create a new namespace-handling parser."""
+        parser = expat.ParserCreate(namespace_separator=" ")
+        parser.namespace_prefixes = True
+        return parser
+
+    def install(self, parser):
+        """Insert the namespace-handlers onto the parser."""
+        ExpatBuilder.install(self, parser)
+        if self._options.namespace_declarations:
+            parser.StartNamespaceDeclHandler = (
+                self.start_namespace_decl_handler)
+
+    def start_namespace_decl_handler(self, prefix, uri):
+        """Push this namespace declaration on our storage."""
+        self._ns_ordered_prefixes.append((prefix, uri))
+
+    def start_element_handler(self, name, attributes):
+        if ' ' in name:
+            uri, localname, prefix, qname = _parse_ns_name(self, name)
+        else:
+            uri = EMPTY_NAMESPACE
+            qname = name
+            localname = None
+            prefix = EMPTY_PREFIX
+        node = minidom.Element(qname, uri, prefix, localname)
+        node.ownerDocument = self.document
+        _append_child(self.curNode, node)
+        self.curNode = node
+
+        if self._ns_ordered_prefixes:
+            for prefix, uri in self._ns_ordered_prefixes:
+                if prefix:
+                    a = minidom.Attr(_intern(self, 'xmlns:' + prefix),
+                                     XMLNS_NAMESPACE, prefix, "xmlns")
+                else:
+                    a = minidom.Attr("xmlns", XMLNS_NAMESPACE,
+                                     "xmlns", EMPTY_PREFIX)
+                d = a.childNodes[0].__dict__
+                d['data'] = d['nodeValue'] = uri
+                d = a.__dict__
+                d['value'] = d['nodeValue'] = uri
+                d['ownerDocument'] = self.document
+                _set_attribute_node(node, a)
+            del self._ns_ordered_prefixes[:]
+
+        if attributes:
+            _attrs = node._attrs
+            _attrsNS = node._attrsNS
+            for i in range(0, len(attributes), 2):
+                aname = attributes[i]
+                value = attributes[i+1]
+                if ' ' in aname:
+                    uri, localname, prefix, qname = _parse_ns_name(self, aname)
+                    a = minidom.Attr(qname, uri, localname, prefix)
+                    _attrs[qname] = a
+                    _attrsNS[(uri, localname)] = a
+                else:
+                    a = minidom.Attr(aname, EMPTY_NAMESPACE,
+                                     aname, EMPTY_PREFIX)
+                    _attrs[aname] = a
+                    _attrsNS[(EMPTY_NAMESPACE, aname)] = a
+                d = a.childNodes[0].__dict__
+                d['data'] = d['nodeValue'] = value
+                d = a.__dict__
+                d['ownerDocument'] = self.document
+                d['value'] = d['nodeValue'] = value
+                d['ownerElement'] = node
+
+    if __debug__:
+        # This only adds some asserts to the original
+        # end_element_handler(), so we only define this when -O is not
+        # used.  If changing one, be sure to check the other to see if
+        # it needs to be changed as well.
+        #
+        def end_element_handler(self, name):
+            curNode = self.curNode
+            if ' ' in name:
+                uri, localname, prefix, qname = _parse_ns_name(self, name)
+                assert (curNode.namespaceURI == uri
+                        and curNode.localName == localname
+                        and curNode.prefix == prefix), \
+                        "element stack messed up! (namespace)"
+            else:
+                assert curNode.nodeName == name, \
+                       "element stack messed up - bad nodeName"
+                assert curNode.namespaceURI == EMPTY_NAMESPACE, \
+                       "element stack messed up - bad namespaceURI"
+            self.curNode = curNode.parentNode
+            self._finish_end_element(curNode)
+
+
+class ExpatBuilderNS(Namespaces, ExpatBuilder):
+    """Document builder that supports namespaces."""
+
+    def reset(self):
+        ExpatBuilder.reset(self)
+        self._initNamespaces()
+
+
+class FragmentBuilderNS(Namespaces, FragmentBuilder):
+    """Fragment builder that supports namespaces."""
+
+    def reset(self):
+        FragmentBuilder.reset(self)
+        self._initNamespaces()
+
+    def _getNSattrs(self):
+        """Return string of namespace attributes from this element and
+        ancestors."""
+        # XXX This needs to be re-written to walk the ancestors of the
+        # context to build up the namespace information from
+        # declarations, elements, and attributes found in context.
+        # Otherwise we have to store a bunch more data on the DOM
+        # (though that *might* be more reliable -- not clear).
+        attrs = ""
+        context = self.context
+        L = []
+        while context:
+            if hasattr(context, '_ns_prefix_uri'):
+                for prefix, uri in context._ns_prefix_uri.items():
+                    # add every new NS decl from context to L and attrs string
+                    if prefix in L:
+                        continue
+                    L.append(prefix)
+                    if prefix:
+                        declname = "xmlns:" + prefix
+                    else:
+                        declname = "xmlns"
+                    if attrs:
+                        attrs = "%s\n    %s='%s'" % (attrs, declname, uri)
+                    else:
+                        attrs = " %s='%s'" % (declname, uri)
+            context = context.parentNode
+        return attrs
+
+
+class ParseEscape(Exception):
+    """Exception raised to short-circuit parsing in InternalSubsetExtractor."""
+    pass
+
+class InternalSubsetExtractor(ExpatBuilder):
+    """XML processor which can rip out the internal document type subset."""
+
+    subset = None
+
+    def getSubset(self):
+        """Return the internal subset as a string."""
+        return self.subset
+
+    def parseFile(self, file):
+        try:
+            ExpatBuilder.parseFile(self, file)
+        except ParseEscape:
+            pass
+
+    def parseString(self, string):
+        try:
+            ExpatBuilder.parseString(self, string)
+        except ParseEscape:
+            pass
+
+    def install(self, parser):
+        parser.StartDoctypeDeclHandler = self.start_doctype_decl_handler
+        parser.StartElementHandler = self.start_element_handler
+
+    def start_doctype_decl_handler(self, name, publicId, systemId,
+                                   has_internal_subset):
+        if has_internal_subset:
+            parser = self.getParser()
+            self.subset = []
+            parser.DefaultHandler = self.subset.append
+            parser.EndDoctypeDeclHandler = self.end_doctype_decl_handler
+        else:
+            raise ParseEscape()
+
+    def end_doctype_decl_handler(self):
+        s = ''.join(self.subset).replace('\r\n', '\n').replace('\r', '\n')
+        self.subset = s
+        raise ParseEscape()
+
+    def start_element_handler(self, name, attrs):
+        raise ParseEscape()
+
+
+def parse(file, namespaces=True):
+    """Parse a document, returning the resulting Document node.
+
+    'file' may be either a file name or an open file object.
+    """
+    if namespaces:
+        builder = ExpatBuilderNS()
+    else:
+        builder = ExpatBuilder()
+
+    if isinstance(file, StringTypes):
+        fp = open(file, 'rb')
+        try:
+            result = builder.parseFile(fp)
+        finally:
+            fp.close()
+    else:
+        result = builder.parseFile(file)
+    return result
+
+
+def parseString(string, namespaces=True):
+    """Parse a document from a string, returning the resulting
+    Document node.
+    """
+    if namespaces:
+        builder = ExpatBuilderNS()
+    else:
+        builder = ExpatBuilder()
+    return builder.parseString(string)
+
+
+def parseFragment(file, context, namespaces=True):
+    """Parse a fragment of a document, given the context from which it
+    was originally extracted.  context should be the parent of the
+    node(s) which are in the fragment.
+
+    'file' may be either a file name or an open file object.
+    """
+    if namespaces:
+        builder = FragmentBuilderNS(context)
+    else:
+        builder = FragmentBuilder(context)
+
+    if isinstance(file, StringTypes):
+        fp = open(file, 'rb')
+        try:
+            result = builder.parseFile(fp)
+        finally:
+            fp.close()
+    else:
+        result = builder.parseFile(file)
+    return result
+
+
+def parseFragmentString(string, context, namespaces=True):
+    """Parse a fragment of a document from a string, given the context
+    from which it was originally extracted.  context should be the
+    parent of the node(s) which are in the fragment.
+    """
+    if namespaces:
+        builder = FragmentBuilderNS(context)
+    else:
+        builder = FragmentBuilder(context)
+    return builder.parseString(string)
+
+
+def makeBuilder(options):
+    """Create a builder based on an Options object."""
+    if options.namespaces:
+        return ExpatBuilderNS(options)
+    else:
+        return ExpatBuilder(options)

Added: vendor/Python/current/Lib/xml/dom/minicompat.py
===================================================================
--- vendor/Python/current/Lib/xml/dom/minicompat.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/xml/dom/minicompat.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,110 @@
+"""Python version compatibility support for minidom."""
+
+# This module should only be imported using "import *".
+#
+# The following names are defined:
+#
+#   NodeList      -- lightest possible NodeList implementation
+#
+#   EmptyNodeList -- lightest possible NodeList that is guarateed to
+#                    remain empty (immutable)
+#
+#   StringTypes   -- tuple of defined string types
+#
+#   defproperty   -- function used in conjunction with GetattrMagic;
+#                    using these together is needed to make them work
+#                    as efficiently as possible in both Python 2.2+
+#                    and older versions.  For example:
+#
+#                        class MyClass(GetattrMagic):
+#                            def _get_myattr(self):
+#                                return something
+#
+#                        defproperty(MyClass, "myattr",
+#                                    "return some value")
+#
+#                    For Python 2.2 and newer, this will construct a
+#                    property object on the class, which avoids
+#                    needing to override __getattr__().  It will only
+#                    work for read-only attributes.
+#
+#                    For older versions of Python, inheriting from
+#                    GetattrMagic will use the traditional
+#                    __getattr__() hackery to achieve the same effect,
+#                    but less efficiently.
+#
+#                    defproperty() should be used for each version of
+#                    the relevant _get_<property>() function.
+
+__all__ = ["NodeList", "EmptyNodeList", "StringTypes", "defproperty"]
+
+import xml.dom
+
+try:
+    unicode
+except NameError:
+    StringTypes = type(''),
+else:
+    StringTypes = type(''), type(unicode(''))
+
+
+class NodeList(list):
+    __slots__ = ()
+
+    def item(self, index):
+        if 0 <= index < len(self):
+            return self[index]
+
+    def _get_length(self):
+        return len(self)
+
+    def _set_length(self, value):
+        raise xml.dom.NoModificationAllowedErr(
+            "attempt to modify read-only attribute 'length'")
+
+    length = property(_get_length, _set_length,
+                      doc="The number of nodes in the NodeList.")
+
+    def __getstate__(self):
+        return list(self)
+
+    def __setstate__(self, state):
+        self[:] = state
+
+
+class EmptyNodeList(tuple):
+    __slots__ = ()
+
+    def __add__(self, other):
+        NL = NodeList()
+        NL.extend(other)
+        return NL
+
+    def __radd__(self, other):
+        NL = NodeList()
+        NL.extend(other)
+        return NL
+
+    def item(self, index):
+        return None
+
+    def _get_length(self):
+        return 0
+
+    def _set_length(self, value):
+        raise xml.dom.NoModificationAllowedErr(
+            "attempt to modify read-only attribute 'length'")
+
+    length = property(_get_length, _set_length,
+                      doc="The number of nodes in the NodeList.")
+
+
+def defproperty(klass, name, doc):
+    get = getattr(klass, ("_get_" + name)).im_func
+    def set(self, value, name=name):
+        raise xml.dom.NoModificationAllowedErr(
+            "attempt to modify read-only attribute " + repr(name))
+    assert not hasattr(klass, "_set_" + name), \
+           "expected not to find _set_" + name
+    prop = property(get, set, doc=doc)
+    setattr(klass, name, prop)

Added: vendor/Python/current/Lib/xml/dom/minidom.py
===================================================================
--- vendor/Python/current/Lib/xml/dom/minidom.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/xml/dom/minidom.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1936 @@
+"""\
+minidom.py -- a lightweight DOM implementation.
+
+parse("foo.xml")
+
+parseString("<foo><bar/></foo>")
+
+Todo:
+=====
+ * convenience methods for getting elements and text.
+ * more testing
+ * bring some of the writer and linearizer code into conformance with this
+        interface
+ * SAX 2 namespaces
+"""
+
+import xml.dom
+
+from xml.dom import EMPTY_NAMESPACE, EMPTY_PREFIX, XMLNS_NAMESPACE, domreg
+from xml.dom.minicompat import *
+from xml.dom.xmlbuilder import DOMImplementationLS, DocumentLS
+
+# This is used by the ID-cache invalidation checks; the list isn't
+# actually complete, since the nodes being checked will never be the
+# DOCUMENT_NODE or DOCUMENT_FRAGMENT_NODE.  (The node being checked is
+# the node being added or removed, not the node being modified.)
+#
+_nodeTypes_with_children = (xml.dom.Node.ELEMENT_NODE,
+                            xml.dom.Node.ENTITY_REFERENCE_NODE)
+
+
+class Node(xml.dom.Node):
+    namespaceURI = None # this is non-null only for elements and attributes
+    parentNode = None
+    ownerDocument = None
+    nextSibling = None
+    previousSibling = None
+
+    prefix = EMPTY_PREFIX # non-null only for NS elements and attributes
+
+    def __nonzero__(self):
+        return True
+
+    def toxml(self, encoding = None):
+        return self.toprettyxml("", "", encoding)
+
+    def toprettyxml(self, indent="\t", newl="\n", encoding = None):
+        # indent = the indentation string to prepend, per level
+        # newl = the newline string to append
+        writer = _get_StringIO()
+        if encoding is not None:
+            import codecs
+            # Can't use codecs.getwriter to preserve 2.0 compatibility
+            writer = codecs.lookup(encoding)[3](writer)
+        if self.nodeType == Node.DOCUMENT_NODE:
+            # Can pass encoding only to document, to put it into XML header
+            self.writexml(writer, "", indent, newl, encoding)
+        else:
+            self.writexml(writer, "", indent, newl)
+        return writer.getvalue()
+
+    def hasChildNodes(self):
+        if self.childNodes:
+            return True
+        else:
+            return False
+
+    def _get_childNodes(self):
+        return self.childNodes
+
+    def _get_firstChild(self):
+        if self.childNodes:
+            return self.childNodes[0]
+
+    def _get_lastChild(self):
+        if self.childNodes:
+            return self.childNodes[-1]
+
+    def insertBefore(self, newChild, refChild):
+        if newChild.nodeType == self.DOCUMENT_FRAGMENT_NODE:
+            for c in tuple(newChild.childNodes):
+                self.insertBefore(c, refChild)
+            ### The DOM does not clearly specify what to return in this case
+            return newChild
+        if newChild.nodeType not in self._child_node_types:
+            raise xml.dom.HierarchyRequestErr(
+                "%s cannot be child of %s" % (repr(newChild), repr(self)))
+        if newChild.parentNode is not None:
+            newChild.parentNode.removeChild(newChild)
+        if refChild is None:
+            self.appendChild(newChild)
+        else:
+            try:
+                index = self.childNodes.index(refChild)
+            except ValueError:
+                raise xml.dom.NotFoundErr()
+            if newChild.nodeType in _nodeTypes_with_children:
+                _clear_id_cache(self)
+            self.childNodes.insert(index, newChild)
+            newChild.nextSibling = refChild
+            refChild.previousSibling = newChild
+            if index:
+                node = self.childNodes[index-1]
+                node.nextSibling = newChild
+                newChild.previousSibling = node
+            else:
+                newChild.previousSibling = None
+            newChild.parentNode = self
+        return newChild
+
+    def appendChild(self, node):
+        if node.nodeType == self.DOCUMENT_FRAGMENT_NODE:
+            for c in tuple(node.childNodes):
+                self.appendChild(c)
+            ### The DOM does not clearly specify what to return in this case
+            return node
+        if node.nodeType not in self._child_node_types:
+            raise xml.dom.HierarchyRequestErr(
+                "%s cannot be child of %s" % (repr(node), repr(self)))
+        elif node.nodeType in _nodeTypes_with_children:
+            _clear_id_cache(self)
+        if node.parentNode is not None:
+            node.parentNode.removeChild(node)
+        _append_child(self, node)
+        node.nextSibling = None
+        return node
+
+    def replaceChild(self, newChild, oldChild):
+        if newChild.nodeType == self.DOCUMENT_FRAGMENT_NODE:
+            refChild = oldChild.nextSibling
+            self.removeChild(oldChild)
+            return self.insertBefore(newChild, refChild)
+        if newChild.nodeType not in self._child_node_types:
+            raise xml.dom.HierarchyRequestErr(
+                "%s cannot be child of %s" % (repr(newChild), repr(self)))
+        if newChild is oldChild:
+            return
+        if newChild.parentNode is not None:
+            newChild.parentNode.removeChild(newChild)
+        try:
+            index = self.childNodes.index(oldChild)
+        except ValueError:
+            raise xml.dom.NotFoundErr()
+        self.childNodes[index] = newChild
+        newChild.parentNode = self
+        oldChild.parentNode = None
+        if (newChild.nodeType in _nodeTypes_with_children
+            or oldChild.nodeType in _nodeTypes_with_children):
+            _clear_id_cache(self)
+        newChild.nextSibling = oldChild.nextSibling
+        newChild.previousSibling = oldChild.previousSibling
+        oldChild.nextSibling = None
+        oldChild.previousSibling = None
+        if newChild.previousSibling:
+            newChild.previousSibling.nextSibling = newChild
+        if newChild.nextSibling:
+            newChild.nextSibling.previousSibling = newChild
+        return oldChild
+
+    def removeChild(self, oldChild):
+        try:
+            self.childNodes.remove(oldChild)
+        except ValueError:
+            raise xml.dom.NotFoundErr()
+        if oldChild.nextSibling is not None:
+            oldChild.nextSibling.previousSibling = oldChild.previousSibling
+        if oldChild.previousSibling is not None:
+            oldChild.previousSibling.nextSibling = oldChild.nextSibling
+        oldChild.nextSibling = oldChild.previousSibling = None
+        if oldChild.nodeType in _nodeTypes_with_children:
+            _clear_id_cache(self)
+
+        oldChild.parentNode = None
+        return oldChild
+
+    def normalize(self):
+        L = []
+        for child in self.childNodes:
+            if child.nodeType == Node.TEXT_NODE:
+                data = child.data
+                if data and L and L[-1].nodeType == child.nodeType:
+                    # collapse text node
+                    node = L[-1]
+                    node.data = node.data + child.data
+                    node.nextSibling = child.nextSibling
+                    child.unlink()
+                elif data:
+                    if L:
+                        L[-1].nextSibling = child
+                        child.previousSibling = L[-1]
+                    else:
+                        child.previousSibling = None
+                    L.append(child)
+                else:
+                    # empty text node; discard
+                    child.unlink()
+            else:
+                if L:
+                    L[-1].nextSibling = child
+                    child.previousSibling = L[-1]
+                else:
+                    child.previousSibling = None
+                L.append(child)
+                if child.nodeType == Node.ELEMENT_NODE:
+                    child.normalize()
+        self.childNodes[:] = L
+
+    def cloneNode(self, deep):
+        return _clone_node(self, deep, self.ownerDocument or self)
+
+    def isSupported(self, feature, version):
+        return self.ownerDocument.implementation.hasFeature(feature, version)
+
+    def _get_localName(self):
+        # Overridden in Element and Attr where localName can be Non-Null
+        return None
+
+    # Node interfaces from Level 3 (WD 9 April 2002)
+
+    def isSameNode(self, other):
+        return self is other
+
+    def getInterface(self, feature):
+        if self.isSupported(feature, None):
+            return self
+        else:
+            return None
+
+    # The "user data" functions use a dictionary that is only present
+    # if some user data has been set, so be careful not to assume it
+    # exists.
+
+    def getUserData(self, key):
+        try:
+            return self._user_data[key][0]
+        except (AttributeError, KeyError):
+            return None
+
+    def setUserData(self, key, data, handler):
+        old = None
+        try:
+            d = self._user_data
+        except AttributeError:
+            d = {}
+            self._user_data = d
+        if d.has_key(key):
+            old = d[key][0]
+        if data is None:
+            # ignore handlers passed for None
+            handler = None
+            if old is not None:
+                del d[key]
+        else:
+            d[key] = (data, handler)
+        return old
+
+    def _call_user_data_handler(self, operation, src, dst):
+        if hasattr(self, "_user_data"):
+            for key, (data, handler) in self._user_data.items():
+                if handler is not None:
+                    handler.handle(operation, key, data, src, dst)
+
+    # minidom-specific API:
+
+    def unlink(self):
+        self.parentNode = self.ownerDocument = None
+        if self.childNodes:
+            for child in self.childNodes:
+                child.unlink()
+            self.childNodes = NodeList()
+        self.previousSibling = None
+        self.nextSibling = None
+
+defproperty(Node, "firstChild", doc="First child node, or None.")
+defproperty(Node, "lastChild",  doc="Last child node, or None.")
+defproperty(Node, "localName",  doc="Namespace-local name of this node.")
+
+
+def _append_child(self, node):
+    # fast path with less checks; usable by DOM builders if careful
+    childNodes = self.childNodes
+    if childNodes:
+        last = childNodes[-1]
+        node.__dict__["previousSibling"] = last
+        last.__dict__["nextSibling"] = node
+    childNodes.append(node)
+    node.__dict__["parentNode"] = self
+
+def _in_document(node):
+    # return True iff node is part of a document tree
+    while node is not None:
+        if node.nodeType == Node.DOCUMENT_NODE:
+            return True
+        node = node.parentNode
+    return False
+
+def _write_data(writer, data):
+    "Writes datachars to writer."
+    data = data.replace("&", "&amp;").replace("<", "&lt;")
+    data = data.replace("\"", "&quot;").replace(">", "&gt;")
+    writer.write(data)
+
+def _get_elements_by_tagName_helper(parent, name, rc):
+    for node in parent.childNodes:
+        if node.nodeType == Node.ELEMENT_NODE and \
+            (name == "*" or node.tagName == name):
+            rc.append(node)
+        _get_elements_by_tagName_helper(node, name, rc)
+    return rc
+
+def _get_elements_by_tagName_ns_helper(parent, nsURI, localName, rc):
+    for node in parent.childNodes:
+        if node.nodeType == Node.ELEMENT_NODE:
+            if ((localName == "*" or node.localName == localName) and
+                (nsURI == "*" or node.namespaceURI == nsURI)):
+                rc.append(node)
+            _get_elements_by_tagName_ns_helper(node, nsURI, localName, rc)
+    return rc
+
+class DocumentFragment(Node):
+    nodeType = Node.DOCUMENT_FRAGMENT_NODE
+    nodeName = "#document-fragment"
+    nodeValue = None
+    attributes = None
+    parentNode = None
+    _child_node_types = (Node.ELEMENT_NODE,
+                         Node.TEXT_NODE,
+                         Node.CDATA_SECTION_NODE,
+                         Node.ENTITY_REFERENCE_NODE,
+                         Node.PROCESSING_INSTRUCTION_NODE,
+                         Node.COMMENT_NODE,
+                         Node.NOTATION_NODE)
+
+    def __init__(self):
+        self.childNodes = NodeList()
+
+
+class Attr(Node):
+    nodeType = Node.ATTRIBUTE_NODE
+    attributes = None
+    ownerElement = None
+    specified = False
+    _is_id = False
+
+    _child_node_types = (Node.TEXT_NODE, Node.ENTITY_REFERENCE_NODE)
+
+    def __init__(self, qName, namespaceURI=EMPTY_NAMESPACE, localName=None,
+                 prefix=None):
+        # skip setattr for performance
+        d = self.__dict__
+        d["nodeName"] = d["name"] = qName
+        d["namespaceURI"] = namespaceURI
+        d["prefix"] = prefix
+        d['childNodes'] = NodeList()
+
+        # Add the single child node that represents the value of the attr
+        self.childNodes.append(Text())
+
+        # nodeValue and value are set elsewhere
+
+    def _get_localName(self):
+        return self.nodeName.split(":", 1)[-1]
+
+    def _get_name(self):
+        return self.name
+
+    def _get_specified(self):
+        return self.specified
+
+    def __setattr__(self, name, value):
+        d = self.__dict__
+        if name in ("value", "nodeValue"):
+            d["value"] = d["nodeValue"] = value
+            d2 = self.childNodes[0].__dict__
+            d2["data"] = d2["nodeValue"] = value
+            if self.ownerElement is not None:
+                _clear_id_cache(self.ownerElement)
+        elif name in ("name", "nodeName"):
+            d["name"] = d["nodeName"] = value
+            if self.ownerElement is not None:
+                _clear_id_cache(self.ownerElement)
+        else:
+            d[name] = value
+
+    def _set_prefix(self, prefix):
+        nsuri = self.namespaceURI
+        if prefix == "xmlns":
+            if nsuri and nsuri != XMLNS_NAMESPACE:
+                raise xml.dom.NamespaceErr(
+                    "illegal use of 'xmlns' prefix for the wrong namespace")
+        d = self.__dict__
+        d['prefix'] = prefix
+        if prefix is None:
+            newName = self.localName
+        else:
+            newName = "%s:%s" % (prefix, self.localName)
+        if self.ownerElement:
+            _clear_id_cache(self.ownerElement)
+        d['nodeName'] = d['name'] = newName
+
+    def _set_value(self, value):
+        d = self.__dict__
+        d['value'] = d['nodeValue'] = value
+        if self.ownerElement:
+            _clear_id_cache(self.ownerElement)
+        self.childNodes[0].data = value
+
+    def unlink(self):
+        # This implementation does not call the base implementation
+        # since most of that is not needed, and the expense of the
+        # method call is not warranted.  We duplicate the removal of
+        # children, but that's all we needed from the base class.
+        elem = self.ownerElement
+        if elem is not None:
+            del elem._attrs[self.nodeName]
+            del elem._attrsNS[(self.namespaceURI, self.localName)]
+            if self._is_id:
+                self._is_id = False
+                elem._magic_id_nodes -= 1
+                self.ownerDocument._magic_id_count -= 1
+        for child in self.childNodes:
+            child.unlink()
+        del self.childNodes[:]
+
+    def _get_isId(self):
+        if self._is_id:
+            return True
+        doc = self.ownerDocument
+        elem = self.ownerElement
+        if doc is None or elem is None:
+            return False
+
+        info = doc._get_elem_info(elem)
+        if info is None:
+            return False
+        if self.namespaceURI:
+            return info.isIdNS(self.namespaceURI, self.localName)
+        else:
+            return info.isId(self.nodeName)
+
+    def _get_schemaType(self):
+        doc = self.ownerDocument
+        elem = self.ownerElement
+        if doc is None or elem is None:
+            return _no_type
+
+        info = doc._get_elem_info(elem)
+        if info is None:
+            return _no_type
+        if self.namespaceURI:
+            return info.getAttributeTypeNS(self.namespaceURI, self.localName)
+        else:
+            return info.getAttributeType(self.nodeName)
+
+defproperty(Attr, "isId",       doc="True if this attribute is an ID.")
+defproperty(Attr, "localName",  doc="Namespace-local name of this attribute.")
+defproperty(Attr, "schemaType", doc="Schema type for this attribute.")
+
+
+class NamedNodeMap(object):
+    """The attribute list is a transient interface to the underlying
+    dictionaries.  Mutations here will change the underlying element's
+    dictionary.
+
+    Ordering is imposed artificially and does not reflect the order of
+    attributes as found in an input document.
+    """
+
+    __slots__ = ('_attrs', '_attrsNS', '_ownerElement')
+
+    def __init__(self, attrs, attrsNS, ownerElement):
+        self._attrs = attrs
+        self._attrsNS = attrsNS
+        self._ownerElement = ownerElement
+
+    def _get_length(self):
+        return len(self._attrs)
+
+    def item(self, index):
+        try:
+            return self[self._attrs.keys()[index]]
+        except IndexError:
+            return None
+
+    def items(self):
+        L = []
+        for node in self._attrs.values():
+            L.append((node.nodeName, node.value))
+        return L
+
+    def itemsNS(self):
+        L = []
+        for node in self._attrs.values():
+            L.append(((node.namespaceURI, node.localName), node.value))
+        return L
+
+    def has_key(self, key):
+        if isinstance(key, StringTypes):
+            return self._attrs.has_key(key)
+        else:
+            return self._attrsNS.has_key(key)
+
+    def keys(self):
+        return self._attrs.keys()
+
+    def keysNS(self):
+        return self._attrsNS.keys()
+
+    def values(self):
+        return self._attrs.values()
+
+    def get(self, name, value=None):
+        return self._attrs.get(name, value)
+
+    __len__ = _get_length
+
+    def __cmp__(self, other):
+        if self._attrs is getattr(other, "_attrs", None):
+            return 0
+        else:
+            return cmp(id(self), id(other))
+
+    def __getitem__(self, attname_or_tuple):
+        if isinstance(attname_or_tuple, tuple):
+            return self._attrsNS[attname_or_tuple]
+        else:
+            return self._attrs[attname_or_tuple]
+
+    # same as set
+    def __setitem__(self, attname, value):
+        if isinstance(value, StringTypes):
+            try:
+                node = self._attrs[attname]
+            except KeyError:
+                node = Attr(attname)
+                node.ownerDocument = self._ownerElement.ownerDocument
+                self.setNamedItem(node)
+            node.value = value
+        else:
+            if not isinstance(value, Attr):
+                raise TypeError, "value must be a string or Attr object"
+            node = value
+            self.setNamedItem(node)
+
+    def getNamedItem(self, name):
+        try:
+            return self._attrs[name]
+        except KeyError:
+            return None
+
+    def getNamedItemNS(self, namespaceURI, localName):
+        try:
+            return self._attrsNS[(namespaceURI, localName)]
+        except KeyError:
+            return None
+
+    def removeNamedItem(self, name):
+        n = self.getNamedItem(name)
+        if n is not None:
+            _clear_id_cache(self._ownerElement)
+            del self._attrs[n.nodeName]
+            del self._attrsNS[(n.namespaceURI, n.localName)]
+            if n.__dict__.has_key('ownerElement'):
+                n.__dict__['ownerElement'] = None
+            return n
+        else:
+            raise xml.dom.NotFoundErr()
+
+    def removeNamedItemNS(self, namespaceURI, localName):
+        n = self.getNamedItemNS(namespaceURI, localName)
+        if n is not None:
+            _clear_id_cache(self._ownerElement)
+            del self._attrsNS[(n.namespaceURI, n.localName)]
+            del self._attrs[n.nodeName]
+            if n.__dict__.has_key('ownerElement'):
+                n.__dict__['ownerElement'] = None
+            return n
+        else:
+            raise xml.dom.NotFoundErr()
+
+    def setNamedItem(self, node):
+        if not isinstance(node, Attr):
+            raise xml.dom.HierarchyRequestErr(
+                "%s cannot be child of %s" % (repr(node), repr(self)))
+        old = self._attrs.get(node.name)
+        if old:
+            old.unlink()
+        self._attrs[node.name] = node
+        self._attrsNS[(node.namespaceURI, node.localName)] = node
+        node.ownerElement = self._ownerElement
+        _clear_id_cache(node.ownerElement)
+        return old
+
+    def setNamedItemNS(self, node):
+        return self.setNamedItem(node)
+
+    def __delitem__(self, attname_or_tuple):
+        node = self[attname_or_tuple]
+        _clear_id_cache(node.ownerElement)
+        node.unlink()
+
+    def __getstate__(self):
+        return self._attrs, self._attrsNS, self._ownerElement
+
+    def __setstate__(self, state):
+        self._attrs, self._attrsNS, self._ownerElement = state
+
+defproperty(NamedNodeMap, "length",
+            doc="Number of nodes in the NamedNodeMap.")
+
+AttributeList = NamedNodeMap
+
+
+class TypeInfo(object):
+    __slots__ = 'namespace', 'name'
+
+    def __init__(self, namespace, name):
+        self.namespace = namespace
+        self.name = name
+
+    def __repr__(self):
+        if self.namespace:
+            return "<TypeInfo %r (from %r)>" % (self.name, self.namespace)
+        else:
+            return "<TypeInfo %r>" % self.name
+
+    def _get_name(self):
+        return self.name
+
+    def _get_namespace(self):
+        return self.namespace
+
+_no_type = TypeInfo(None, None)
+
+class Element(Node):
+    nodeType = Node.ELEMENT_NODE
+    nodeValue = None
+    schemaType = _no_type
+
+    _magic_id_nodes = 0
+
+    _child_node_types = (Node.ELEMENT_NODE,
+                         Node.PROCESSING_INSTRUCTION_NODE,
+                         Node.COMMENT_NODE,
+                         Node.TEXT_NODE,
+                         Node.CDATA_SECTION_NODE,
+                         Node.ENTITY_REFERENCE_NODE)
+
+    def __init__(self, tagName, namespaceURI=EMPTY_NAMESPACE, prefix=None,
+                 localName=None):
+        self.tagName = self.nodeName = tagName
+        self.prefix = prefix
+        self.namespaceURI = namespaceURI
+        self.childNodes = NodeList()
+
+        self._attrs = {}   # attributes are double-indexed:
+        self._attrsNS = {} #    tagName -> Attribute
+                           #    URI,localName -> Attribute
+                           # in the future: consider lazy generation
+                           # of attribute objects this is too tricky
+                           # for now because of headaches with
+                           # namespaces.
+
+    def _get_localName(self):
+        return self.tagName.split(":", 1)[-1]
+
+    def _get_tagName(self):
+        return self.tagName
+
+    def unlink(self):
+        for attr in self._attrs.values():
+            attr.unlink()
+        self._attrs = None
+        self._attrsNS = None
+        Node.unlink(self)
+
+    def getAttribute(self, attname):
+        try:
+            return self._attrs[attname].value
+        except KeyError:
+            return ""
+
+    def getAttributeNS(self, namespaceURI, localName):
+        try:
+            return self._attrsNS[(namespaceURI, localName)].value
+        except KeyError:
+            return ""
+
+    def setAttribute(self, attname, value):
+        attr = self.getAttributeNode(attname)
+        if attr is None:
+            attr = Attr(attname)
+            # for performance
+            d = attr.__dict__
+            d["value"] = d["nodeValue"] = value
+            d["ownerDocument"] = self.ownerDocument
+            self.setAttributeNode(attr)
+        elif value != attr.value:
+            d = attr.__dict__
+            d["value"] = d["nodeValue"] = value
+            if attr.isId:
+                _clear_id_cache(self)
+
+    def setAttributeNS(self, namespaceURI, qualifiedName, value):
+        prefix, localname = _nssplit(qualifiedName)
+        attr = self.getAttributeNodeNS(namespaceURI, localname)
+        if attr is None:
+            # for performance
+            attr = Attr(qualifiedName, namespaceURI, localname, prefix)
+            d = attr.__dict__
+            d["prefix"] = prefix
+            d["nodeName"] = qualifiedName
+            d["value"] = d["nodeValue"] = value
+            d["ownerDocument"] = self.ownerDocument
+            self.setAttributeNode(attr)
+        else:
+            d = attr.__dict__
+            if value != attr.value:
+                d["value"] = d["nodeValue"] = value
+                if attr.isId:
+                    _clear_id_cache(self)
+            if attr.prefix != prefix:
+                d["prefix"] = prefix
+                d["nodeName"] = qualifiedName
+
+    def getAttributeNode(self, attrname):
+        return self._attrs.get(attrname)
+
+    def getAttributeNodeNS(self, namespaceURI, localName):
+        return self._attrsNS.get((namespaceURI, localName))
+
+    def setAttributeNode(self, attr):
+        if attr.ownerElement not in (None, self):
+            raise xml.dom.InuseAttributeErr("attribute node already owned")
+        old1 = self._attrs.get(attr.name, None)
+        if old1 is not None:
+            self.removeAttributeNode(old1)
+        old2 = self._attrsNS.get((attr.namespaceURI, attr.localName), None)
+        if old2 is not None and old2 is not old1:
+            self.removeAttributeNode(old2)
+        _set_attribute_node(self, attr)
+
+        if old1 is not attr:
+            # It might have already been part of this node, in which case
+            # it doesn't represent a change, and should not be returned.
+            return old1
+        if old2 is not attr:
+            return old2
+
+    setAttributeNodeNS = setAttributeNode
+
+    def removeAttribute(self, name):
+        try:
+            attr = self._attrs[name]
+        except KeyError:
+            raise xml.dom.NotFoundErr()
+        self.removeAttributeNode(attr)
+
+    def removeAttributeNS(self, namespaceURI, localName):
+        try:
+            attr = self._attrsNS[(namespaceURI, localName)]
+        except KeyError:
+            raise xml.dom.NotFoundErr()
+        self.removeAttributeNode(attr)
+
+    def removeAttributeNode(self, node):
+        if node is None:
+            raise xml.dom.NotFoundErr()
+        try:
+            self._attrs[node.name]
+        except KeyError:
+            raise xml.dom.NotFoundErr()
+        _clear_id_cache(self)
+        node.unlink()
+        # Restore this since the node is still useful and otherwise
+        # unlinked
+        node.ownerDocument = self.ownerDocument
+
+    removeAttributeNodeNS = removeAttributeNode
+
+    def hasAttribute(self, name):
+        return self._attrs.has_key(name)
+
+    def hasAttributeNS(self, namespaceURI, localName):
+        return self._attrsNS.has_key((namespaceURI, localName))
+
+    def getElementsByTagName(self, name):
+        return _get_elements_by_tagName_helper(self, name, NodeList())
+
+    def getElementsByTagNameNS(self, namespaceURI, localName):
+        return _get_elements_by_tagName_ns_helper(
+            self, namespaceURI, localName, NodeList())
+
+    def __repr__(self):
+        return "<DOM Element: %s at %#x>" % (self.tagName, id(self))
+
+    def writexml(self, writer, indent="", addindent="", newl=""):
+        # indent = current indentation
+        # addindent = indentation to add to higher levels
+        # newl = newline string
+        writer.write(indent+"<" + self.tagName)
+
+        attrs = self._get_attributes()
+        a_names = attrs.keys()
+        a_names.sort()
+
+        for a_name in a_names:
+            writer.write(" %s=\"" % a_name)
+            _write_data(writer, attrs[a_name].value)
+            writer.write("\"")
+        if self.childNodes:
+            writer.write(">%s"%(newl))
+            for node in self.childNodes:
+                node.writexml(writer,indent+addindent,addindent,newl)
+            writer.write("%s</%s>%s" % (indent,self.tagName,newl))
+        else:
+            writer.write("/>%s"%(newl))
+
+    def _get_attributes(self):
+        return NamedNodeMap(self._attrs, self._attrsNS, self)
+
+    def hasAttributes(self):
+        if self._attrs:
+            return True
+        else:
+            return False
+
+    # DOM Level 3 attributes, based on the 22 Oct 2002 draft
+
+    def setIdAttribute(self, name):
+        idAttr = self.getAttributeNode(name)
+        self.setIdAttributeNode(idAttr)
+
+    def setIdAttributeNS(self, namespaceURI, localName):
+        idAttr = self.getAttributeNodeNS(namespaceURI, localName)
+        self.setIdAttributeNode(idAttr)
+
+    def setIdAttributeNode(self, idAttr):
+        if idAttr is None or not self.isSameNode(idAttr.ownerElement):
+            raise xml.dom.NotFoundErr()
+        if _get_containing_entref(self) is not None:
+            raise xml.dom.NoModificationAllowedErr()
+        if not idAttr._is_id:
+            idAttr.__dict__['_is_id'] = True
+            self._magic_id_nodes += 1
+            self.ownerDocument._magic_id_count += 1
+            _clear_id_cache(self)
+
+defproperty(Element, "attributes",
+            doc="NamedNodeMap of attributes on the element.")
+defproperty(Element, "localName",
+            doc="Namespace-local name of this element.")
+
+
+def _set_attribute_node(element, attr):
+    _clear_id_cache(element)
+    element._attrs[attr.name] = attr
+    element._attrsNS[(attr.namespaceURI, attr.localName)] = attr
+
+    # This creates a circular reference, but Element.unlink()
+    # breaks the cycle since the references to the attribute
+    # dictionaries are tossed.
+    attr.__dict__['ownerElement'] = element
+
+
+class Childless:
+    """Mixin that makes childless-ness easy to implement and avoids
+    the complexity of the Node methods that deal with children.
+    """
+
+    attributes = None
+    childNodes = EmptyNodeList()
+    firstChild = None
+    lastChild = None
+
+    def _get_firstChild(self):
+        return None
+
+    def _get_lastChild(self):
+        return None
+
+    def appendChild(self, node):
+        raise xml.dom.HierarchyRequestErr(
+            self.nodeName + " nodes cannot have children")
+
+    def hasChildNodes(self):
+        return False
+
+    def insertBefore(self, newChild, refChild):
+        raise xml.dom.HierarchyRequestErr(
+            self.nodeName + " nodes do not have children")
+
+    def removeChild(self, oldChild):
+        raise xml.dom.NotFoundErr(
+            self.nodeName + " nodes do not have children")
+
+    def replaceChild(self, newChild, oldChild):
+        raise xml.dom.HierarchyRequestErr(
+            self.nodeName + " nodes do not have children")
+
+
+class ProcessingInstruction(Childless, Node):
+    nodeType = Node.PROCESSING_INSTRUCTION_NODE
+
+    def __init__(self, target, data):
+        self.target = self.nodeName = target
+        self.data = self.nodeValue = data
+
+    def _get_data(self):
+        return self.data
+    def _set_data(self, value):
+        d = self.__dict__
+        d['data'] = d['nodeValue'] = value
+
+    def _get_target(self):
+        return self.target
+    def _set_target(self, value):
+        d = self.__dict__
+        d['target'] = d['nodeName'] = value
+
+    def __setattr__(self, name, value):
+        if name == "data" or name == "nodeValue":
+            self.__dict__['data'] = self.__dict__['nodeValue'] = value
+        elif name == "target" or name == "nodeName":
+            self.__dict__['target'] = self.__dict__['nodeName'] = value
+        else:
+            self.__dict__[name] = value
+
+    def writexml(self, writer, indent="", addindent="", newl=""):
+        writer.write("%s<?%s %s?>%s" % (indent,self.target, self.data, newl))
+
+
+class CharacterData(Childless, Node):
+    def _get_length(self):
+        return len(self.data)
+    __len__ = _get_length
+
+    def _get_data(self):
+        return self.__dict__['data']
+    def _set_data(self, data):
+        d = self.__dict__
+        d['data'] = d['nodeValue'] = data
+
+    _get_nodeValue = _get_data
+    _set_nodeValue = _set_data
+
+    def __setattr__(self, name, value):
+        if name == "data" or name == "nodeValue":
+            self.__dict__['data'] = self.__dict__['nodeValue'] = value
+        else:
+            self.__dict__[name] = value
+
+    def __repr__(self):
+        data = self.data
+        if len(data) > 10:
+            dotdotdot = "..."
+        else:
+            dotdotdot = ""
+        return "<DOM %s node \"%s%s\">" % (
+            self.__class__.__name__, data[0:10], dotdotdot)
+
+    def substringData(self, offset, count):
+        if offset < 0:
+            raise xml.dom.IndexSizeErr("offset cannot be negative")
+        if offset >= len(self.data):
+            raise xml.dom.IndexSizeErr("offset cannot be beyond end of data")
+        if count < 0:
+            raise xml.dom.IndexSizeErr("count cannot be negative")
+        return self.data[offset:offset+count]
+
+    def appendData(self, arg):
+        self.data = self.data + arg
+
+    def insertData(self, offset, arg):
+        if offset < 0:
+            raise xml.dom.IndexSizeErr("offset cannot be negative")
+        if offset >= len(self.data):
+            raise xml.dom.IndexSizeErr("offset cannot be beyond end of data")
+        if arg:
+            self.data = "%s%s%s" % (
+                self.data[:offset], arg, self.data[offset:])
+
+    def deleteData(self, offset, count):
+        if offset < 0:
+            raise xml.dom.IndexSizeErr("offset cannot be negative")
+        if offset >= len(self.data):
+            raise xml.dom.IndexSizeErr("offset cannot be beyond end of data")
+        if count < 0:
+            raise xml.dom.IndexSizeErr("count cannot be negative")
+        if count:
+            self.data = self.data[:offset] + self.data[offset+count:]
+
+    def replaceData(self, offset, count, arg):
+        if offset < 0:
+            raise xml.dom.IndexSizeErr("offset cannot be negative")
+        if offset >= len(self.data):
+            raise xml.dom.IndexSizeErr("offset cannot be beyond end of data")
+        if count < 0:
+            raise xml.dom.IndexSizeErr("count cannot be negative")
+        if count:
+            self.data = "%s%s%s" % (
+                self.data[:offset], arg, self.data[offset+count:])
+
+defproperty(CharacterData, "length", doc="Length of the string data.")
+
+
+class Text(CharacterData):
+    # Make sure we don't add an instance __dict__ if we don't already
+    # have one, at least when that's possible:
+    # XXX this does not work, CharacterData is an old-style class
+    # __slots__ = ()
+
+    nodeType = Node.TEXT_NODE
+    nodeName = "#text"
+    attributes = None
+
+    def splitText(self, offset):
+        if offset < 0 or offset > len(self.data):
+            raise xml.dom.IndexSizeErr("illegal offset value")
+        newText = self.__class__()
+        newText.data = self.data[offset:]
+        newText.ownerDocument = self.ownerDocument
+        next = self.nextSibling
+        if self.parentNode and self in self.parentNode.childNodes:
+            if next is None:
+                self.parentNode.appendChild(newText)
+            else:
+                self.parentNode.insertBefore(newText, next)
+        self.data = self.data[:offset]
+        return newText
+
+    def writexml(self, writer, indent="", addindent="", newl=""):
+        _write_data(writer, "%s%s%s"%(indent, self.data, newl))
+
+    # DOM Level 3 (WD 9 April 2002)
+
+    def _get_wholeText(self):
+        L = [self.data]
+        n = self.previousSibling
+        while n is not None:
+            if n.nodeType in (Node.TEXT_NODE, Node.CDATA_SECTION_NODE):
+                L.insert(0, n.data)
+                n = n.previousSibling
+            else:
+                break
+        n = self.nextSibling
+        while n is not None:
+            if n.nodeType in (Node.TEXT_NODE, Node.CDATA_SECTION_NODE):
+                L.append(n.data)
+                n = n.nextSibling
+            else:
+                break
+        return ''.join(L)
+
+    def replaceWholeText(self, content):
+        # XXX This needs to be seriously changed if minidom ever
+        # supports EntityReference nodes.
+        parent = self.parentNode
+        n = self.previousSibling
+        while n is not None:
+            if n.nodeType in (Node.TEXT_NODE, Node.CDATA_SECTION_NODE):
+                next = n.previousSibling
+                parent.removeChild(n)
+                n = next
+            else:
+                break
+        n = self.nextSibling
+        if not content:
+            parent.removeChild(self)
+        while n is not None:
+            if n.nodeType in (Node.TEXT_NODE, Node.CDATA_SECTION_NODE):
+                next = n.nextSibling
+                parent.removeChild(n)
+                n = next
+            else:
+                break
+        if content:
+            d = self.__dict__
+            d['data'] = content
+            d['nodeValue'] = content
+            return self
+        else:
+            return None
+
+    def _get_isWhitespaceInElementContent(self):
+        if self.data.strip():
+            return False
+        elem = _get_containing_element(self)
+        if elem is None:
+            return False
+        info = self.ownerDocument._get_elem_info(elem)
+        if info is None:
+            return False
+        else:
+            return info.isElementContent()
+
+defproperty(Text, "isWhitespaceInElementContent",
+            doc="True iff this text node contains only whitespace"
+                " and is in element content.")
+defproperty(Text, "wholeText",
+            doc="The text of all logically-adjacent text nodes.")
+
+
+def _get_containing_element(node):
+    c = node.parentNode
+    while c is not None:
+        if c.nodeType == Node.ELEMENT_NODE:
+            return c
+        c = c.parentNode
+    return None
+
+def _get_containing_entref(node):
+    c = node.parentNode
+    while c is not None:
+        if c.nodeType == Node.ENTITY_REFERENCE_NODE:
+            return c
+        c = c.parentNode
+    return None
+
+
+class Comment(Childless, CharacterData):
+    nodeType = Node.COMMENT_NODE
+    nodeName = "#comment"
+
+    def __init__(self, data):
+        self.data = self.nodeValue = data
+
+    def writexml(self, writer, indent="", addindent="", newl=""):
+        writer.write("%s<!--%s-->%s" % (indent, self.data, newl))
+
+
+class CDATASection(Text):
+    # Make sure we don't add an instance __dict__ if we don't already
+    # have one, at least when that's possible:
+    # XXX this does not work, Text is an old-style class
+    # __slots__ = ()
+
+    nodeType = Node.CDATA_SECTION_NODE
+    nodeName = "#cdata-section"
+
+    def writexml(self, writer, indent="", addindent="", newl=""):
+        if self.data.find("]]>") >= 0:
+            raise ValueError("']]>' not allowed in a CDATA section")
+        writer.write("<![CDATA[%s]]>" % self.data)
+
+
+class ReadOnlySequentialNamedNodeMap(object):
+    __slots__ = '_seq',
+
+    def __init__(self, seq=()):
+        # seq should be a list or tuple
+        self._seq = seq
+
+    def __len__(self):
+        return len(self._seq)
+
+    def _get_length(self):
+        return len(self._seq)
+
+    def getNamedItem(self, name):
+        for n in self._seq:
+            if n.nodeName == name:
+                return n
+
+    def getNamedItemNS(self, namespaceURI, localName):
+        for n in self._seq:
+            if n.namespaceURI == namespaceURI and n.localName == localName:
+                return n
+
+    def __getitem__(self, name_or_tuple):
+        if isinstance(name_or_tuple, tuple):
+            node = self.getNamedItemNS(*name_or_tuple)
+        else:
+            node = self.getNamedItem(name_or_tuple)
+        if node is None:
+            raise KeyError, name_or_tuple
+        return node
+
+    def item(self, index):
+        if index < 0:
+            return None
+        try:
+            return self._seq[index]
+        except IndexError:
+            return None
+
+    def removeNamedItem(self, name):
+        raise xml.dom.NoModificationAllowedErr(
+            "NamedNodeMap instance is read-only")
+
+    def removeNamedItemNS(self, namespaceURI, localName):
+        raise xml.dom.NoModificationAllowedErr(
+            "NamedNodeMap instance is read-only")
+
+    def setNamedItem(self, node):
+        raise xml.dom.NoModificationAllowedErr(
+            "NamedNodeMap instance is read-only")
+
+    def setNamedItemNS(self, node):
+        raise xml.dom.NoModificationAllowedErr(
+            "NamedNodeMap instance is read-only")
+
+    def __getstate__(self):
+        return [self._seq]
+
+    def __setstate__(self, state):
+        self._seq = state[0]
+
+defproperty(ReadOnlySequentialNamedNodeMap, "length",
+            doc="Number of entries in the NamedNodeMap.")
+
+
+class Identified:
+    """Mix-in class that supports the publicId and systemId attributes."""
+
+    # XXX this does not work, this is an old-style class
+    # __slots__ = 'publicId', 'systemId'
+
+    def _identified_mixin_init(self, publicId, systemId):
+        self.publicId = publicId
+        self.systemId = systemId
+
+    def _get_publicId(self):
+        return self.publicId
+
+    def _get_systemId(self):
+        return self.systemId
+
+class DocumentType(Identified, Childless, Node):
+    nodeType = Node.DOCUMENT_TYPE_NODE
+    nodeValue = None
+    name = None
+    publicId = None
+    systemId = None
+    internalSubset = None
+
+    def __init__(self, qualifiedName):
+        self.entities = ReadOnlySequentialNamedNodeMap()
+        self.notations = ReadOnlySequentialNamedNodeMap()
+        if qualifiedName:
+            prefix, localname = _nssplit(qualifiedName)
+            self.name = localname
+        self.nodeName = self.name
+
+    def _get_internalSubset(self):
+        return self.internalSubset
+
+    def cloneNode(self, deep):
+        if self.ownerDocument is None:
+            # it's ok
+            clone = DocumentType(None)
+            clone.name = self.name
+            clone.nodeName = self.name
+            operation = xml.dom.UserDataHandler.NODE_CLONED
+            if deep:
+                clone.entities._seq = []
+                clone.notations._seq = []
+                for n in self.notations._seq:
+                    notation = Notation(n.nodeName, n.publicId, n.systemId)
+                    clone.notations._seq.append(notation)
+                    n._call_user_data_handler(operation, n, notation)
+                for e in self.entities._seq:
+                    entity = Entity(e.nodeName, e.publicId, e.systemId,
+                                    e.notationName)
+                    entity.actualEncoding = e.actualEncoding
+                    entity.encoding = e.encoding
+                    entity.version = e.version
+                    clone.entities._seq.append(entity)
+                    e._call_user_data_handler(operation, n, entity)
+            self._call_user_data_handler(operation, self, clone)
+            return clone
+        else:
+            return None
+
+    def writexml(self, writer, indent="", addindent="", newl=""):
+        writer.write("<!DOCTYPE ")
+        writer.write(self.name)
+        if self.publicId:
+            writer.write("%s  PUBLIC '%s'%s  '%s'"
+                         % (newl, self.publicId, newl, self.systemId))
+        elif self.systemId:
+            writer.write("%s  SYSTEM '%s'" % (newl, self.systemId))
+        if self.internalSubset is not None:
+            writer.write(" [")
+            writer.write(self.internalSubset)
+            writer.write("]")
+        writer.write(">"+newl)
+
+class Entity(Identified, Node):
+    attributes = None
+    nodeType = Node.ENTITY_NODE
+    nodeValue = None
+
+    actualEncoding = None
+    encoding = None
+    version = None
+
+    def __init__(self, name, publicId, systemId, notation):
+        self.nodeName = name
+        self.notationName = notation
+        self.childNodes = NodeList()
+        self._identified_mixin_init(publicId, systemId)
+
+    def _get_actualEncoding(self):
+        return self.actualEncoding
+
+    def _get_encoding(self):
+        return self.encoding
+
+    def _get_version(self):
+        return self.version
+
+    def appendChild(self, newChild):
+        raise xml.dom.HierarchyRequestErr(
+            "cannot append children to an entity node")
+
+    def insertBefore(self, newChild, refChild):
+        raise xml.dom.HierarchyRequestErr(
+            "cannot insert children below an entity node")
+
+    def removeChild(self, oldChild):
+        raise xml.dom.HierarchyRequestErr(
+            "cannot remove children from an entity node")
+
+    def replaceChild(self, newChild, oldChild):
+        raise xml.dom.HierarchyRequestErr(
+            "cannot replace children of an entity node")
+
+class Notation(Identified, Childless, Node):
+    nodeType = Node.NOTATION_NODE
+    nodeValue = None
+
+    def __init__(self, name, publicId, systemId):
+        self.nodeName = name
+        self._identified_mixin_init(publicId, systemId)
+
+
+class DOMImplementation(DOMImplementationLS):
+    _features = [("core", "1.0"),
+                 ("core", "2.0"),
+                 ("core", "3.0"),
+                 ("core", None),
+                 ("xml", "1.0"),
+                 ("xml", "2.0"),
+                 ("xml", "3.0"),
+                 ("xml", None),
+                 ("ls-load", "3.0"),
+                 ("ls-load", None),
+                 ]
+
+    def hasFeature(self, feature, version):
+        if version == "":
+            version = None
+        return (feature.lower(), version) in self._features
+
+    def createDocument(self, namespaceURI, qualifiedName, doctype):
+        if doctype and doctype.parentNode is not None:
+            raise xml.dom.WrongDocumentErr(
+                "doctype object owned by another DOM tree")
+        doc = self._create_document()
+
+        add_root_element = not (namespaceURI is None
+                                and qualifiedName is None
+                                and doctype is None)
+
+        if not qualifiedName and add_root_element:
+            # The spec is unclear what to raise here; SyntaxErr
+            # would be the other obvious candidate. Since Xerces raises
+            # InvalidCharacterErr, and since SyntaxErr is not listed
+            # for createDocument, that seems to be the better choice.
+            # XXX: need to check for illegal characters here and in
+            # createElement.
+
+            # DOM Level III clears this up when talking about the return value
+            # of this function.  If namespaceURI, qName and DocType are
+            # Null the document is returned without a document element
+            # Otherwise if doctype or namespaceURI are not None
+            # Then we go back to the above problem
+            raise xml.dom.InvalidCharacterErr("Element with no name")
+
+        if add_root_element:
+            prefix, localname = _nssplit(qualifiedName)
+            if prefix == "xml" \
+               and namespaceURI != "http://www.w3.org/XML/1998/namespace":
+                raise xml.dom.NamespaceErr("illegal use of 'xml' prefix")
+            if prefix and not namespaceURI:
+                raise xml.dom.NamespaceErr(
+                    "illegal use of prefix without namespaces")
+            element = doc.createElementNS(namespaceURI, qualifiedName)
+            if doctype:
+                doc.appendChild(doctype)
+            doc.appendChild(element)
+
+        if doctype:
+            doctype.parentNode = doctype.ownerDocument = doc
+
+        doc.doctype = doctype
+        doc.implementation = self
+        return doc
+
+    def createDocumentType(self, qualifiedName, publicId, systemId):
+        doctype = DocumentType(qualifiedName)
+        doctype.publicId = publicId
+        doctype.systemId = systemId
+        return doctype
+
+    # DOM Level 3 (WD 9 April 2002)
+
+    def getInterface(self, feature):
+        if self.hasFeature(feature, None):
+            return self
+        else:
+            return None
+
+    # internal
+    def _create_document(self):
+        return Document()
+
+class ElementInfo(object):
+    """Object that represents content-model information for an element.
+
+    This implementation is not expected to be used in practice; DOM
+    builders should provide implementations which do the right thing
+    using information available to it.
+
+    """
+
+    __slots__ = 'tagName',
+
+    def __init__(self, name):
+        self.tagName = name
+
+    def getAttributeType(self, aname):
+        return _no_type
+
+    def getAttributeTypeNS(self, namespaceURI, localName):
+        return _no_type
+
+    def isElementContent(self):
+        return False
+
+    def isEmpty(self):
+        """Returns true iff this element is declared to have an EMPTY
+        content model."""
+        return False
+
+    def isId(self, aname):
+        """Returns true iff the named attribte is a DTD-style ID."""
+        return False
+
+    def isIdNS(self, namespaceURI, localName):
+        """Returns true iff the identified attribute is a DTD-style ID."""
+        return False
+
+    def __getstate__(self):
+        return self.tagName
+
+    def __setstate__(self, state):
+        self.tagName = state
+
+def _clear_id_cache(node):
+    if node.nodeType == Node.DOCUMENT_NODE:
+        node._id_cache.clear()
+        node._id_search_stack = None
+    elif _in_document(node):
+        node.ownerDocument._id_cache.clear()
+        node.ownerDocument._id_search_stack= None
+
+class Document(Node, DocumentLS):
+    _child_node_types = (Node.ELEMENT_NODE, Node.PROCESSING_INSTRUCTION_NODE,
+                         Node.COMMENT_NODE, Node.DOCUMENT_TYPE_NODE)
+
+    nodeType = Node.DOCUMENT_NODE
+    nodeName = "#document"
+    nodeValue = None
+    attributes = None
+    doctype = None
+    parentNode = None
+    previousSibling = nextSibling = None
+
+    implementation = DOMImplementation()
+
+    # Document attributes from Level 3 (WD 9 April 2002)
+
+    actualEncoding = None
+    encoding = None
+    standalone = None
+    version = None
+    strictErrorChecking = False
+    errorHandler = None
+    documentURI = None
+
+    _magic_id_count = 0
+
+    def __init__(self):
+        self.childNodes = NodeList()
+        # mapping of (namespaceURI, localName) -> ElementInfo
+        #        and tagName -> ElementInfo
+        self._elem_info = {}
+        self._id_cache = {}
+        self._id_search_stack = None
+
+    def _get_elem_info(self, element):
+        if element.namespaceURI:
+            key = element.namespaceURI, element.localName
+        else:
+            key = element.tagName
+        return self._elem_info.get(key)
+
+    def _get_actualEncoding(self):
+        return self.actualEncoding
+
+    def _get_doctype(self):
+        return self.doctype
+
+    def _get_documentURI(self):
+        return self.documentURI
+
+    def _get_encoding(self):
+        return self.encoding
+
+    def _get_errorHandler(self):
+        return self.errorHandler
+
+    def _get_standalone(self):
+        return self.standalone
+
+    def _get_strictErrorChecking(self):
+        return self.strictErrorChecking
+
+    def _get_version(self):
+        return self.version
+
+    def appendChild(self, node):
+        if node.nodeType not in self._child_node_types:
+            raise xml.dom.HierarchyRequestErr(
+                "%s cannot be child of %s" % (repr(node), repr(self)))
+        if node.parentNode is not None:
+            # This needs to be done before the next test since this
+            # may *be* the document element, in which case it should
+            # end up re-ordered to the end.
+            node.parentNode.removeChild(node)
+
+        if node.nodeType == Node.ELEMENT_NODE \
+           and self._get_documentElement():
+            raise xml.dom.HierarchyRequestErr(
+                "two document elements disallowed")
+        return Node.appendChild(self, node)
+
+    def removeChild(self, oldChild):
+        try:
+            self.childNodes.remove(oldChild)
+        except ValueError:
+            raise xml.dom.NotFoundErr()
+        oldChild.nextSibling = oldChild.previousSibling = None
+        oldChild.parentNode = None
+        if self.documentElement is oldChild:
+            self.documentElement = None
+
+        return oldChild
+
+    def _get_documentElement(self):
+        for node in self.childNodes:
+            if node.nodeType == Node.ELEMENT_NODE:
+                return node
+
+    def unlink(self):
+        if self.doctype is not None:
+            self.doctype.unlink()
+            self.doctype = None
+        Node.unlink(self)
+
+    def cloneNode(self, deep):
+        if not deep:
+            return None
+        clone = self.implementation.createDocument(None, None, None)
+        clone.encoding = self.encoding
+        clone.standalone = self.standalone
+        clone.version = self.version
+        for n in self.childNodes:
+            childclone = _clone_node(n, deep, clone)
+            assert childclone.ownerDocument.isSameNode(clone)
+            clone.childNodes.append(childclone)
+            if childclone.nodeType == Node.DOCUMENT_NODE:
+                assert clone.documentElement is None
+            elif childclone.nodeType == Node.DOCUMENT_TYPE_NODE:
+                assert clone.doctype is None
+                clone.doctype = childclone
+            childclone.parentNode = clone
+        self._call_user_data_handler(xml.dom.UserDataHandler.NODE_CLONED,
+                                     self, clone)
+        return clone
+
+    def createDocumentFragment(self):
+        d = DocumentFragment()
+        d.ownerDocument = self
+        return d
+
+    def createElement(self, tagName):
+        e = Element(tagName)
+        e.ownerDocument = self
+        return e
+
+    def createTextNode(self, data):
+        if not isinstance(data, StringTypes):
+            raise TypeError, "node contents must be a string"
+        t = Text()
+        t.data = data
+        t.ownerDocument = self
+        return t
+
+    def createCDATASection(self, data):
+        if not isinstance(data, StringTypes):
+            raise TypeError, "node contents must be a string"
+        c = CDATASection()
+        c.data = data
+        c.ownerDocument = self
+        return c
+
+    def createComment(self, data):
+        c = Comment(data)
+        c.ownerDocument = self
+        return c
+
+    def createProcessingInstruction(self, target, data):
+        p = ProcessingInstruction(target, data)
+        p.ownerDocument = self
+        return p
+
+    def createAttribute(self, qName):
+        a = Attr(qName)
+        a.ownerDocument = self
+        a.value = ""
+        return a
+
+    def createElementNS(self, namespaceURI, qualifiedName):
+        prefix, localName = _nssplit(qualifiedName)
+        e = Element(qualifiedName, namespaceURI, prefix)
+        e.ownerDocument = self
+        return e
+
+    def createAttributeNS(self, namespaceURI, qualifiedName):
+        prefix, localName = _nssplit(qualifiedName)
+        a = Attr(qualifiedName, namespaceURI, localName, prefix)
+        a.ownerDocument = self
+        a.value = ""
+        return a
+
+    # A couple of implementation-specific helpers to create node types
+    # not supported by the W3C DOM specs:
+
+    def _create_entity(self, name, publicId, systemId, notationName):
+        e = Entity(name, publicId, systemId, notationName)
+        e.ownerDocument = self
+        return e
+
+    def _create_notation(self, name, publicId, systemId):
+        n = Notation(name, publicId, systemId)
+        n.ownerDocument = self
+        return n
+
+    def getElementById(self, id):
+        if self._id_cache.has_key(id):
+            return self._id_cache[id]
+        if not (self._elem_info or self._magic_id_count):
+            return None
+
+        stack = self._id_search_stack
+        if stack is None:
+            # we never searched before, or the cache has been cleared
+            stack = [self.documentElement]
+            self._id_search_stack = stack
+        elif not stack:
+            # Previous search was completed and cache is still valid;
+            # no matching node.
+            return None
+
+        result = None
+        while stack:
+            node = stack.pop()
+            # add child elements to stack for continued searching
+            stack.extend([child for child in node.childNodes
+                          if child.nodeType in _nodeTypes_with_children])
+            # check this node
+            info = self._get_elem_info(node)
+            if info:
+                # We have to process all ID attributes before
+                # returning in order to get all the attributes set to
+                # be IDs using Element.setIdAttribute*().
+                for attr in node.attributes.values():
+                    if attr.namespaceURI:
+                        if info.isIdNS(attr.namespaceURI, attr.localName):
+                            self._id_cache[attr.value] = node
+                            if attr.value == id:
+                                result = node
+                            elif not node._magic_id_nodes:
+                                break
+                    elif info.isId(attr.name):
+                        self._id_cache[attr.value] = node
+                        if attr.value == id:
+                            result = node
+                        elif not node._magic_id_nodes:
+                            break
+                    elif attr._is_id:
+                        self._id_cache[attr.value] = node
+                        if attr.value == id:
+                            result = node
+                        elif node._magic_id_nodes == 1:
+                            break
+            elif node._magic_id_nodes:
+                for attr in node.attributes.values():
+                    if attr._is_id:
+                        self._id_cache[attr.value] = node
+                        if attr.value == id:
+                            result = node
+            if result is not None:
+                break
+        return result
+
+    def getElementsByTagName(self, name):
+        return _get_elements_by_tagName_helper(self, name, NodeList())
+
+    def getElementsByTagNameNS(self, namespaceURI, localName):
+        return _get_elements_by_tagName_ns_helper(
+            self, namespaceURI, localName, NodeList())
+
+    def isSupported(self, feature, version):
+        return self.implementation.hasFeature(feature, version)
+
+    def importNode(self, node, deep):
+        if node.nodeType == Node.DOCUMENT_NODE:
+            raise xml.dom.NotSupportedErr("cannot import document nodes")
+        elif node.nodeType == Node.DOCUMENT_TYPE_NODE:
+            raise xml.dom.NotSupportedErr("cannot import document type nodes")
+        return _clone_node(node, deep, self)
+
+    def writexml(self, writer, indent="", addindent="", newl="",
+                 encoding = None):
+        if encoding is None:
+            writer.write('<?xml version="1.0" ?>'+newl)
+        else:
+            writer.write('<?xml version="1.0" encoding="%s"?>%s' % (encoding, newl))
+        for node in self.childNodes:
+            node.writexml(writer, indent, addindent, newl)
+
+    # DOM Level 3 (WD 9 April 2002)
+
+    def renameNode(self, n, namespaceURI, name):
+        if n.ownerDocument is not self:
+            raise xml.dom.WrongDocumentErr(
+                "cannot rename nodes from other documents;\n"
+                "expected %s,\nfound %s" % (self, n.ownerDocument))
+        if n.nodeType not in (Node.ELEMENT_NODE, Node.ATTRIBUTE_NODE):
+            raise xml.dom.NotSupportedErr(
+                "renameNode() only applies to element and attribute nodes")
+        if namespaceURI != EMPTY_NAMESPACE:
+            if ':' in name:
+                prefix, localName = name.split(':', 1)
+                if (  prefix == "xmlns"
+                      and namespaceURI != xml.dom.XMLNS_NAMESPACE):
+                    raise xml.dom.NamespaceErr(
+                        "illegal use of 'xmlns' prefix")
+            else:
+                if (  name == "xmlns"
+                      and namespaceURI != xml.dom.XMLNS_NAMESPACE
+                      and n.nodeType == Node.ATTRIBUTE_NODE):
+                    raise xml.dom.NamespaceErr(
+                        "illegal use of the 'xmlns' attribute")
+                prefix = None
+                localName = name
+        else:
+            prefix = None
+            localName = None
+        if n.nodeType == Node.ATTRIBUTE_NODE:
+            element = n.ownerElement
+            if element is not None:
+                is_id = n._is_id
+                element.removeAttributeNode(n)
+        else:
+            element = None
+        # avoid __setattr__
+        d = n.__dict__
+        d['prefix'] = prefix
+        d['localName'] = localName
+        d['namespaceURI'] = namespaceURI
+        d['nodeName'] = name
+        if n.nodeType == Node.ELEMENT_NODE:
+            d['tagName'] = name
+        else:
+            # attribute node
+            d['name'] = name
+            if element is not None:
+                element.setAttributeNode(n)
+                if is_id:
+                    element.setIdAttributeNode(n)
+        # It's not clear from a semantic perspective whether we should
+        # call the user data handlers for the NODE_RENAMED event since
+        # we're re-using the existing node.  The draft spec has been
+        # interpreted as meaning "no, don't call the handler unless a
+        # new node is created."
+        return n
+
+defproperty(Document, "documentElement",
+            doc="Top-level element of this document.")
+
+
+def _clone_node(node, deep, newOwnerDocument):
+    """
+    Clone a node and give it the new owner document.
+    Called by Node.cloneNode and Document.importNode
+    """
+    if node.ownerDocument.isSameNode(newOwnerDocument):
+        operation = xml.dom.UserDataHandler.NODE_CLONED
+    else:
+        operation = xml.dom.UserDataHandler.NODE_IMPORTED
+    if node.nodeType == Node.ELEMENT_NODE:
+        clone = newOwnerDocument.createElementNS(node.namespaceURI,
+                                                 node.nodeName)
+        for attr in node.attributes.values():
+            clone.setAttributeNS(attr.namespaceURI, attr.nodeName, attr.value)
+            a = clone.getAttributeNodeNS(attr.namespaceURI, attr.localName)
+            a.specified = attr.specified
+
+        if deep:
+            for child in node.childNodes:
+                c = _clone_node(child, deep, newOwnerDocument)
+                clone.appendChild(c)
+
+    elif node.nodeType == Node.DOCUMENT_FRAGMENT_NODE:
+        clone = newOwnerDocument.createDocumentFragment()
+        if deep:
+            for child in node.childNodes:
+                c = _clone_node(child, deep, newOwnerDocument)
+                clone.appendChild(c)
+
+    elif node.nodeType == Node.TEXT_NODE:
+        clone = newOwnerDocument.createTextNode(node.data)
+    elif node.nodeType == Node.CDATA_SECTION_NODE:
+        clone = newOwnerDocument.createCDATASection(node.data)
+    elif node.nodeType == Node.PROCESSING_INSTRUCTION_NODE:
+        clone = newOwnerDocument.createProcessingInstruction(node.target,
+                                                             node.data)
+    elif node.nodeType == Node.COMMENT_NODE:
+        clone = newOwnerDocument.createComment(node.data)
+    elif node.nodeType == Node.ATTRIBUTE_NODE:
+        clone = newOwnerDocument.createAttributeNS(node.namespaceURI,
+                                                   node.nodeName)
+        clone.specified = True
+        clone.value = node.value
+    elif node.nodeType == Node.DOCUMENT_TYPE_NODE:
+        assert node.ownerDocument is not newOwnerDocument
+        operation = xml.dom.UserDataHandler.NODE_IMPORTED
+        clone = newOwnerDocument.implementation.createDocumentType(
+            node.name, node.publicId, node.systemId)
+        clone.ownerDocument = newOwnerDocument
+        if deep:
+            clone.entities._seq = []
+            clone.notations._seq = []
+            for n in node.notations._seq:
+                notation = Notation(n.nodeName, n.publicId, n.systemId)
+                notation.ownerDocument = newOwnerDocument
+                clone.notations._seq.append(notation)
+                if hasattr(n, '_call_user_data_handler'):
+                    n._call_user_data_handler(operation, n, notation)
+            for e in node.entities._seq:
+                entity = Entity(e.nodeName, e.publicId, e.systemId,
+                                e.notationName)
+                entity.actualEncoding = e.actualEncoding
+                entity.encoding = e.encoding
+                entity.version = e.version
+                entity.ownerDocument = newOwnerDocument
+                clone.entities._seq.append(entity)
+                if hasattr(e, '_call_user_data_handler'):
+                    e._call_user_data_handler(operation, n, entity)
+    else:
+        # Note the cloning of Document and DocumentType nodes is
+        # implemenetation specific.  minidom handles those cases
+        # directly in the cloneNode() methods.
+        raise xml.dom.NotSupportedErr("Cannot clone node %s" % repr(node))
+
+    # Check for _call_user_data_handler() since this could conceivably
+    # used with other DOM implementations (one of the FourThought
+    # DOMs, perhaps?).
+    if hasattr(node, '_call_user_data_handler'):
+        node._call_user_data_handler(operation, node, clone)
+    return clone
+
+
+def _nssplit(qualifiedName):
+    fields = qualifiedName.split(':', 1)
+    if len(fields) == 2:
+        return fields
+    else:
+        return (None, fields[0])
+
+
+def _get_StringIO():
+    # we can't use cStringIO since it doesn't support Unicode strings
+    from StringIO import StringIO
+    return StringIO()
+
+def _do_pulldom_parse(func, args, kwargs):
+    events = func(*args, **kwargs)
+    toktype, rootNode = events.getEvent()
+    events.expandNode(rootNode)
+    events.clear()
+    return rootNode
+
+def parse(file, parser=None, bufsize=None):
+    """Parse a file into a DOM by filename or file object."""
+    if parser is None and not bufsize:
+        from xml.dom import expatbuilder
+        return expatbuilder.parse(file)
+    else:
+        from xml.dom import pulldom
+        return _do_pulldom_parse(pulldom.parse, (file,),
+            {'parser': parser, 'bufsize': bufsize})
+
+def parseString(string, parser=None):
+    """Parse a file into a DOM from a string."""
+    if parser is None:
+        from xml.dom import expatbuilder
+        return expatbuilder.parseString(string)
+    else:
+        from xml.dom import pulldom
+        return _do_pulldom_parse(pulldom.parseString, (string,),
+                                 {'parser': parser})
+
+def getDOMImplementation(features=None):
+    if features:
+        if isinstance(features, StringTypes):
+            features = domreg._parse_feature_string(features)
+        for f, v in features:
+            if not Document.implementation.hasFeature(f, v):
+                return None
+    return Document.implementation

Added: vendor/Python/current/Lib/xml/dom/pulldom.py
===================================================================
--- vendor/Python/current/Lib/xml/dom/pulldom.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/xml/dom/pulldom.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,351 @@
+import xml.sax
+import xml.sax.handler
+import types
+
+try:
+    _StringTypes = [types.StringType, types.UnicodeType]
+except AttributeError:
+    _StringTypes = [types.StringType]
+
+START_ELEMENT = "START_ELEMENT"
+END_ELEMENT = "END_ELEMENT"
+COMMENT = "COMMENT"
+START_DOCUMENT = "START_DOCUMENT"
+END_DOCUMENT = "END_DOCUMENT"
+PROCESSING_INSTRUCTION = "PROCESSING_INSTRUCTION"
+IGNORABLE_WHITESPACE = "IGNORABLE_WHITESPACE"
+CHARACTERS = "CHARACTERS"
+
+class PullDOM(xml.sax.ContentHandler):
+    _locator = None
+    document = None
+
+    def __init__(self, documentFactory=None):
+        from xml.dom import XML_NAMESPACE
+        self.documentFactory = documentFactory
+        self.firstEvent = [None, None]
+        self.lastEvent = self.firstEvent
+        self.elementStack = []
+        self.push = self.elementStack.append
+        try:
+            self.pop = self.elementStack.pop
+        except AttributeError:
+            # use class' pop instead
+            pass
+        self._ns_contexts = [{XML_NAMESPACE:'xml'}] # contains uri -> prefix dicts
+        self._current_context = self._ns_contexts[-1]
+        self.pending_events = []
+
+    def pop(self):
+        result = self.elementStack[-1]
+        del self.elementStack[-1]
+        return result
+
+    def setDocumentLocator(self, locator):
+        self._locator = locator
+
+    def startPrefixMapping(self, prefix, uri):
+        if not hasattr(self, '_xmlns_attrs'):
+            self._xmlns_attrs = []
+        self._xmlns_attrs.append((prefix or 'xmlns', uri))
+        self._ns_contexts.append(self._current_context.copy())
+        self._current_context[uri] = prefix or None
+
+    def endPrefixMapping(self, prefix):
+        self._current_context = self._ns_contexts.pop()
+
+    def startElementNS(self, name, tagName , attrs):
+        # Retrieve xml namespace declaration attributes.
+        xmlns_uri = 'http://www.w3.org/2000/xmlns/'
+        xmlns_attrs = getattr(self, '_xmlns_attrs', None)
+        if xmlns_attrs is not None:
+            for aname, value in xmlns_attrs:
+                attrs._attrs[(xmlns_uri, aname)] = value
+            self._xmlns_attrs = []
+        uri, localname = name
+        if uri:
+            # When using namespaces, the reader may or may not
+            # provide us with the original name. If not, create
+            # *a* valid tagName from the current context.
+            if tagName is None:
+                prefix = self._current_context[uri]
+                if prefix:
+                    tagName = prefix + ":" + localname
+                else:
+                    tagName = localname
+            if self.document:
+                node = self.document.createElementNS(uri, tagName)
+            else:
+                node = self.buildDocument(uri, tagName)
+        else:
+            # When the tagname is not prefixed, it just appears as
+            # localname
+            if self.document:
+                node = self.document.createElement(localname)
+            else:
+                node = self.buildDocument(None, localname)
+
+        for aname,value in attrs.items():
+            a_uri, a_localname = aname
+            if a_uri == xmlns_uri:
+                if a_localname == 'xmlns':
+                    qname = a_localname
+                else:
+                    qname = 'xmlns:' + a_localname
+                attr = self.document.createAttributeNS(a_uri, qname)
+                node.setAttributeNodeNS(attr)
+            elif a_uri:
+                prefix = self._current_context[a_uri]
+                if prefix:
+                    qname = prefix + ":" + a_localname
+                else:
+                    qname = a_localname
+                attr = self.document.createAttributeNS(a_uri, qname)
+                node.setAttributeNodeNS(attr)
+            else:
+                attr = self.document.createAttribute(a_localname)
+                node.setAttributeNode(attr)
+            attr.value = value
+
+        self.lastEvent[1] = [(START_ELEMENT, node), None]
+        self.lastEvent = self.lastEvent[1]
+        self.push(node)
+
+    def endElementNS(self, name, tagName):
+        self.lastEvent[1] = [(END_ELEMENT, self.pop()), None]
+        self.lastEvent = self.lastEvent[1]
+
+    def startElement(self, name, attrs):
+        if self.document:
+            node = self.document.createElement(name)
+        else:
+            node = self.buildDocument(None, name)
+
+        for aname,value in attrs.items():
+            attr = self.document.createAttribute(aname)
+            attr.value = value
+            node.setAttributeNode(attr)
+
+        self.lastEvent[1] = [(START_ELEMENT, node), None]
+        self.lastEvent = self.lastEvent[1]
+        self.push(node)
+
+    def endElement(self, name):
+        self.lastEvent[1] = [(END_ELEMENT, self.pop()), None]
+        self.lastEvent = self.lastEvent[1]
+
+    def comment(self, s):
+        if self.document:
+            node = self.document.createComment(s)
+            self.lastEvent[1] = [(COMMENT, node), None]
+            self.lastEvent = self.lastEvent[1]
+        else:
+            event = [(COMMENT, s), None]
+            self.pending_events.append(event)
+
+    def processingInstruction(self, target, data):
+        if self.document:
+            node = self.document.createProcessingInstruction(target, data)
+            self.lastEvent[1] = [(PROCESSING_INSTRUCTION, node), None]
+            self.lastEvent = self.lastEvent[1]
+        else:
+            event = [(PROCESSING_INSTRUCTION, target, data), None]
+            self.pending_events.append(event)
+
+    def ignorableWhitespace(self, chars):
+        node = self.document.createTextNode(chars)
+        self.lastEvent[1] = [(IGNORABLE_WHITESPACE, node), None]
+        self.lastEvent = self.lastEvent[1]
+
+    def characters(self, chars):
+        node = self.document.createTextNode(chars)
+        self.lastEvent[1] = [(CHARACTERS, node), None]
+        self.lastEvent = self.lastEvent[1]
+
+    def startDocument(self):
+        if self.documentFactory is None:
+            import xml.dom.minidom
+            self.documentFactory = xml.dom.minidom.Document.implementation
+
+    def buildDocument(self, uri, tagname):
+        # Can't do that in startDocument, since we need the tagname
+        # XXX: obtain DocumentType
+        node = self.documentFactory.createDocument(uri, tagname, None)
+        self.document = node
+        self.lastEvent[1] = [(START_DOCUMENT, node), None]
+        self.lastEvent = self.lastEvent[1]
+        self.push(node)
+        # Put everything we have seen so far into the document
+        for e in self.pending_events:
+            if e[0][0] == PROCESSING_INSTRUCTION:
+                _,target,data = e[0]
+                n = self.document.createProcessingInstruction(target, data)
+                e[0] = (PROCESSING_INSTRUCTION, n)
+            elif e[0][0] == COMMENT:
+                n = self.document.createComment(e[0][1])
+                e[0] = (COMMENT, n)
+            else:
+                raise AssertionError("Unknown pending event ",e[0][0])
+            self.lastEvent[1] = e
+            self.lastEvent = e
+        self.pending_events = None
+        return node.firstChild
+
+    def endDocument(self):
+        self.lastEvent[1] = [(END_DOCUMENT, self.document), None]
+        self.pop()
+
+    def clear(self):
+        "clear(): Explicitly release parsing structures"
+        self.document = None
+
+class ErrorHandler:
+    def warning(self, exception):
+        print exception
+    def error(self, exception):
+        raise exception
+    def fatalError(self, exception):
+        raise exception
+
+class DOMEventStream:
+    def __init__(self, stream, parser, bufsize):
+        self.stream = stream
+        self.parser = parser
+        self.bufsize = bufsize
+        if not hasattr(self.parser, 'feed'):
+            self.getEvent = self._slurp
+        self.reset()
+
+    def reset(self):
+        self.pulldom = PullDOM()
+        # This content handler relies on namespace support
+        self.parser.setFeature(xml.sax.handler.feature_namespaces, 1)
+        self.parser.setContentHandler(self.pulldom)
+
+    def __getitem__(self, pos):
+        rc = self.getEvent()
+        if rc:
+            return rc
+        raise IndexError
+
+    def next(self):
+        rc = self.getEvent()
+        if rc:
+            return rc
+        raise StopIteration
+
+    def __iter__(self):
+        return self
+
+    def expandNode(self, node):
+        event = self.getEvent()
+        parents = [node]
+        while event:
+            token, cur_node = event
+            if cur_node is node:
+                return
+            if token != END_ELEMENT:
+                parents[-1].appendChild(cur_node)
+            if token == START_ELEMENT:
+                parents.append(cur_node)
+            elif token == END_ELEMENT:
+                del parents[-1]
+            event = self.getEvent()
+
+    def getEvent(self):
+        # use IncrementalParser interface, so we get the desired
+        # pull effect
+        if not self.pulldom.firstEvent[1]:
+            self.pulldom.lastEvent = self.pulldom.firstEvent
+        while not self.pulldom.firstEvent[1]:
+            buf = self.stream.read(self.bufsize)
+            if not buf:
+                self.parser.close()
+                return None
+            self.parser.feed(buf)
+        rc = self.pulldom.firstEvent[1][0]
+        self.pulldom.firstEvent[1] = self.pulldom.firstEvent[1][1]
+        return rc
+
+    def _slurp(self):
+        """ Fallback replacement for getEvent() using the
+            standard SAX2 interface, which means we slurp the
+            SAX events into memory (no performance gain, but
+            we are compatible to all SAX parsers).
+        """
+        self.parser.parse(self.stream)
+        self.getEvent = self._emit
+        return self._emit()
+
+    def _emit(self):
+        """ Fallback replacement for getEvent() that emits
+            the events that _slurp() read previously.
+        """
+        rc = self.pulldom.firstEvent[1][0]
+        self.pulldom.firstEvent[1] = self.pulldom.firstEvent[1][1]
+        return rc
+
+    def clear(self):
+        """clear(): Explicitly release parsing objects"""
+        self.pulldom.clear()
+        del self.pulldom
+        self.parser = None
+        self.stream = None
+
+class SAX2DOM(PullDOM):
+
+    def startElementNS(self, name, tagName , attrs):
+        PullDOM.startElementNS(self, name, tagName, attrs)
+        curNode = self.elementStack[-1]
+        parentNode = self.elementStack[-2]
+        parentNode.appendChild(curNode)
+
+    def startElement(self, name, attrs):
+        PullDOM.startElement(self, name, attrs)
+        curNode = self.elementStack[-1]
+        parentNode = self.elementStack[-2]
+        parentNode.appendChild(curNode)
+
+    def processingInstruction(self, target, data):
+        PullDOM.processingInstruction(self, target, data)
+        node = self.lastEvent[0][1]
+        parentNode = self.elementStack[-1]
+        parentNode.appendChild(node)
+
+    def ignorableWhitespace(self, chars):
+        PullDOM.ignorableWhitespace(self, chars)
+        node = self.lastEvent[0][1]
+        parentNode = self.elementStack[-1]
+        parentNode.appendChild(node)
+
+    def characters(self, chars):
+        PullDOM.characters(self, chars)
+        node = self.lastEvent[0][1]
+        parentNode = self.elementStack[-1]
+        parentNode.appendChild(node)
+
+
+default_bufsize = (2 ** 14) - 20
+
+def parse(stream_or_string, parser=None, bufsize=None):
+    if bufsize is None:
+        bufsize = default_bufsize
+    if type(stream_or_string) in _StringTypes:
+        stream = open(stream_or_string)
+    else:
+        stream = stream_or_string
+    if not parser:
+        parser = xml.sax.make_parser()
+    return DOMEventStream(stream, parser, bufsize)
+
+def parseString(string, parser=None):
+    try:
+        from cStringIO import StringIO
+    except ImportError:
+        from StringIO import StringIO
+
+    bufsize = len(string)
+    buf = StringIO(string)
+    if not parser:
+        parser = xml.sax.make_parser()
+    return DOMEventStream(buf, parser, bufsize)

Added: vendor/Python/current/Lib/xml/dom/xmlbuilder.py
===================================================================
--- vendor/Python/current/Lib/xml/dom/xmlbuilder.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/xml/dom/xmlbuilder.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,386 @@
+"""Implementation of the DOM Level 3 'LS-Load' feature."""
+
+import copy
+import xml.dom
+
+from xml.dom.NodeFilter import NodeFilter
+
+
+__all__ = ["DOMBuilder", "DOMEntityResolver", "DOMInputSource"]
+
+
+class Options:
+    """Features object that has variables set for each DOMBuilder feature.
+
+    The DOMBuilder class uses an instance of this class to pass settings to
+    the ExpatBuilder class.
+    """
+
+    # Note that the DOMBuilder class in LoadSave constrains which of these
+    # values can be set using the DOM Level 3 LoadSave feature.
+
+    namespaces = 1
+    namespace_declarations = True
+    validation = False
+    external_parameter_entities = True
+    external_general_entities = True
+    external_dtd_subset = True
+    validate_if_schema = False
+    validate = False
+    datatype_normalization = False
+    create_entity_ref_nodes = True
+    entities = True
+    whitespace_in_element_content = True
+    cdata_sections = True
+    comments = True
+    charset_overrides_xml_encoding = True
+    infoset = False
+    supported_mediatypes_only = False
+
+    errorHandler = None
+    filter = None
+
+
+class DOMBuilder:
+    entityResolver = None
+    errorHandler = None
+    filter = None
+
+    ACTION_REPLACE = 1
+    ACTION_APPEND_AS_CHILDREN = 2
+    ACTION_INSERT_AFTER = 3
+    ACTION_INSERT_BEFORE = 4
+
+    _legal_actions = (ACTION_REPLACE, ACTION_APPEND_AS_CHILDREN,
+                      ACTION_INSERT_AFTER, ACTION_INSERT_BEFORE)
+
+    def __init__(self):
+        self._options = Options()
+
+    def _get_entityResolver(self):
+        return self.entityResolver
+    def _set_entityResolver(self, entityResolver):
+        self.entityResolver = entityResolver
+
+    def _get_errorHandler(self):
+        return self.errorHandler
+    def _set_errorHandler(self, errorHandler):
+        self.errorHandler = errorHandler
+
+    def _get_filter(self):
+        return self.filter
+    def _set_filter(self, filter):
+        self.filter = filter
+
+    def setFeature(self, name, state):
+        if self.supportsFeature(name):
+            state = state and 1 or 0
+            try:
+                settings = self._settings[(_name_xform(name), state)]
+            except KeyError:
+                raise xml.dom.NotSupportedErr(
+                    "unsupported feature: %r" % (name,))
+            else:
+                for name, value in settings:
+                    setattr(self._options, name, value)
+        else:
+            raise xml.dom.NotFoundErr("unknown feature: " + repr(name))
+
+    def supportsFeature(self, name):
+        return hasattr(self._options, _name_xform(name))
+
+    def canSetFeature(self, name, state):
+        key = (_name_xform(name), state and 1 or 0)
+        return self._settings.has_key(key)
+
+    # This dictionary maps from (feature,value) to a list of
+    # (option,value) pairs that should be set on the Options object.
+    # If a (feature,value) setting is not in this dictionary, it is
+    # not supported by the DOMBuilder.
+    #
+    _settings = {
+        ("namespace_declarations", 0): [
+            ("namespace_declarations", 0)],
+        ("namespace_declarations", 1): [
+            ("namespace_declarations", 1)],
+        ("validation", 0): [
+            ("validation", 0)],
+        ("external_general_entities", 0): [
+            ("external_general_entities", 0)],
+        ("external_general_entities", 1): [
+            ("external_general_entities", 1)],
+        ("external_parameter_entities", 0): [
+            ("external_parameter_entities", 0)],
+        ("external_parameter_entities", 1): [
+            ("external_parameter_entities", 1)],
+        ("validate_if_schema", 0): [
+            ("validate_if_schema", 0)],
+        ("create_entity_ref_nodes", 0): [
+            ("create_entity_ref_nodes", 0)],
+        ("create_entity_ref_nodes", 1): [
+            ("create_entity_ref_nodes", 1)],
+        ("entities", 0): [
+            ("create_entity_ref_nodes", 0),
+            ("entities", 0)],
+        ("entities", 1): [
+            ("entities", 1)],
+        ("whitespace_in_element_content", 0): [
+            ("whitespace_in_element_content", 0)],
+        ("whitespace_in_element_content", 1): [
+            ("whitespace_in_element_content", 1)],
+        ("cdata_sections", 0): [
+            ("cdata_sections", 0)],
+        ("cdata_sections", 1): [
+            ("cdata_sections", 1)],
+        ("comments", 0): [
+            ("comments", 0)],
+        ("comments", 1): [
+            ("comments", 1)],
+        ("charset_overrides_xml_encoding", 0): [
+            ("charset_overrides_xml_encoding", 0)],
+        ("charset_overrides_xml_encoding", 1): [
+            ("charset_overrides_xml_encoding", 1)],
+        ("infoset", 0): [],
+        ("infoset", 1): [
+            ("namespace_declarations", 0),
+            ("validate_if_schema", 0),
+            ("create_entity_ref_nodes", 0),
+            ("entities", 0),
+            ("cdata_sections", 0),
+            ("datatype_normalization", 1),
+            ("whitespace_in_element_content", 1),
+            ("comments", 1),
+            ("charset_overrides_xml_encoding", 1)],
+        ("supported_mediatypes_only", 0): [
+            ("supported_mediatypes_only", 0)],
+        ("namespaces", 0): [
+            ("namespaces", 0)],
+        ("namespaces", 1): [
+            ("namespaces", 1)],
+    }
+
+    def getFeature(self, name):
+        xname = _name_xform(name)
+        try:
+            return getattr(self._options, xname)
+        except AttributeError:
+            if name == "infoset":
+                options = self._options
+                return (options.datatype_normalization
+                        and options.whitespace_in_element_content
+                        and options.comments
+                        and options.charset_overrides_xml_encoding
+                        and not (options.namespace_declarations
+                                 or options.validate_if_schema
+                                 or options.create_entity_ref_nodes
+                                 or options.entities
+                                 or options.cdata_sections))
+            raise xml.dom.NotFoundErr("feature %s not known" % repr(name))
+
+    def parseURI(self, uri):
+        if self.entityResolver:
+            input = self.entityResolver.resolveEntity(None, uri)
+        else:
+            input = DOMEntityResolver().resolveEntity(None, uri)
+        return self.parse(input)
+
+    def parse(self, input):
+        options = copy.copy(self._options)
+        options.filter = self.filter
+        options.errorHandler = self.errorHandler
+        fp = input.byteStream
+        if fp is None and options.systemId:
+            import urllib2
+            fp = urllib2.urlopen(input.systemId)
+        return self._parse_bytestream(fp, options)
+
+    def parseWithContext(self, input, cnode, action):
+        if action not in self._legal_actions:
+            raise ValueError("not a legal action")
+        raise NotImplementedError("Haven't written this yet...")
+
+    def _parse_bytestream(self, stream, options):
+        import xml.dom.expatbuilder
+        builder = xml.dom.expatbuilder.makeBuilder(options)
+        return builder.parseFile(stream)
+
+
+def _name_xform(name):
+    return name.lower().replace('-', '_')
+
+
+class DOMEntityResolver(object):
+    __slots__ = '_opener',
+
+    def resolveEntity(self, publicId, systemId):
+        assert systemId is not None
+        source = DOMInputSource()
+        source.publicId = publicId
+        source.systemId = systemId
+        source.byteStream = self._get_opener().open(systemId)
+
+        # determine the encoding if the transport provided it
+        source.encoding = self._guess_media_encoding(source)
+
+        # determine the base URI is we can
+        import posixpath, urlparse
+        parts = urlparse.urlparse(systemId)
+        scheme, netloc, path, params, query, fragment = parts
+        # XXX should we check the scheme here as well?
+        if path and not path.endswith("/"):
+            path = posixpath.dirname(path) + "/"
+            parts = scheme, netloc, path, params, query, fragment
+            source.baseURI = urlparse.urlunparse(parts)
+
+        return source
+
+    def _get_opener(self):
+        try:
+            return self._opener
+        except AttributeError:
+            self._opener = self._create_opener()
+            return self._opener
+
+    def _create_opener(self):
+        import urllib2
+        return urllib2.build_opener()
+
+    def _guess_media_encoding(self, source):
+        info = source.byteStream.info()
+        if info.has_key("Content-Type"):
+            for param in info.getplist():
+                if param.startswith("charset="):
+                    return param.split("=", 1)[1].lower()
+
+
+class DOMInputSource(object):
+    __slots__ = ('byteStream', 'characterStream', 'stringData',
+                 'encoding', 'publicId', 'systemId', 'baseURI')
+
+    def __init__(self):
+        self.byteStream = None
+        self.characterStream = None
+        self.stringData = None
+        self.encoding = None
+        self.publicId = None
+        self.systemId = None
+        self.baseURI = None
+
+    def _get_byteStream(self):
+        return self.byteStream
+    def _set_byteStream(self, byteStream):
+        self.byteStream = byteStream
+
+    def _get_characterStream(self):
+        return self.characterStream
+    def _set_characterStream(self, characterStream):
+        self.characterStream = characterStream
+
+    def _get_stringData(self):
+        return self.stringData
+    def _set_stringData(self, data):
+        self.stringData = data
+
+    def _get_encoding(self):
+        return self.encoding
+    def _set_encoding(self, encoding):
+        self.encoding = encoding
+
+    def _get_publicId(self):
+        return self.publicId
+    def _set_publicId(self, publicId):
+        self.publicId = publicId
+
+    def _get_systemId(self):
+        return self.systemId
+    def _set_systemId(self, systemId):
+        self.systemId = systemId
+
+    def _get_baseURI(self):
+        return self.baseURI
+    def _set_baseURI(self, uri):
+        self.baseURI = uri
+
+
+class DOMBuilderFilter:
+    """Element filter which can be used to tailor construction of
+    a DOM instance.
+    """
+
+    # There's really no need for this class; concrete implementations
+    # should just implement the endElement() and startElement()
+    # methods as appropriate.  Using this makes it easy to only
+    # implement one of them.
+
+    FILTER_ACCEPT = 1
+    FILTER_REJECT = 2
+    FILTER_SKIP = 3
+    FILTER_INTERRUPT = 4
+
+    whatToShow = NodeFilter.SHOW_ALL
+
+    def _get_whatToShow(self):
+        return self.whatToShow
+
+    def acceptNode(self, element):
+        return self.FILTER_ACCEPT
+
+    def startContainer(self, element):
+        return self.FILTER_ACCEPT
+
+del NodeFilter
+
+
+class DocumentLS:
+    """Mixin to create documents that conform to the load/save spec."""
+
+    async = False
+
+    def _get_async(self):
+        return False
+    def _set_async(self, async):
+        if async:
+            raise xml.dom.NotSupportedErr(
+                "asynchronous document loading is not supported")
+
+    def abort(self):
+        # What does it mean to "clear" a document?  Does the
+        # documentElement disappear?
+        raise NotImplementedError(
+            "haven't figured out what this means yet")
+
+    def load(self, uri):
+        raise NotImplementedError("haven't written this yet")
+
+    def loadXML(self, source):
+        raise NotImplementedError("haven't written this yet")
+
+    def saveXML(self, snode):
+        if snode is None:
+            snode = self
+        elif snode.ownerDocument is not self:
+            raise xml.dom.WrongDocumentErr()
+        return snode.toxml()
+
+
+class DOMImplementationLS:
+    MODE_SYNCHRONOUS = 1
+    MODE_ASYNCHRONOUS = 2
+
+    def createDOMBuilder(self, mode, schemaType):
+        if schemaType is not None:
+            raise xml.dom.NotSupportedErr(
+                "schemaType not yet supported")
+        if mode == self.MODE_SYNCHRONOUS:
+            return DOMBuilder()
+        if mode == self.MODE_ASYNCHRONOUS:
+            raise xml.dom.NotSupportedErr(
+                "asynchronous builders are not supported")
+        raise ValueError("unknown value for mode")
+
+    def createDOMWriter(self):
+        raise NotImplementedError(
+            "the writer interface hasn't been written yet!")
+
+    def createDOMInputSource(self):
+        return DOMInputSource()

Added: vendor/Python/current/Lib/xml/etree/ElementInclude.py
===================================================================
--- vendor/Python/current/Lib/xml/etree/ElementInclude.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/xml/etree/ElementInclude.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,143 @@
+#
+# ElementTree
+# $Id: ElementInclude.py 1862 2004-06-18 07:31:02Z Fredrik $
+#
+# limited xinclude support for element trees
+#
+# history:
+# 2003-08-15 fl   created
+# 2003-11-14 fl   fixed default loader
+#
+# Copyright (c) 2003-2004 by Fredrik Lundh.  All rights reserved.
+#
+# fredrik at pythonware.com
+# http://www.pythonware.com
+#
+# --------------------------------------------------------------------
+# The ElementTree toolkit is
+#
+# Copyright (c) 1999-2004 by Fredrik Lundh
+#
+# By obtaining, using, and/or copying this software and/or its
+# associated documentation, you agree that you have read, understood,
+# and will comply with the following terms and conditions:
+#
+# Permission to use, copy, modify, and distribute this software and
+# its associated documentation for any purpose and without fee is
+# hereby granted, provided that the above copyright notice appears in
+# all copies, and that both that copyright notice and this permission
+# notice appear in supporting documentation, and that the name of
+# Secret Labs AB or the author not be used in advertising or publicity
+# pertaining to distribution of the software without specific, written
+# prior permission.
+#
+# SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
+# TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT-
+# ABILITY AND FITNESS.  IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR
+# BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+# OF THIS SOFTWARE.
+# --------------------------------------------------------------------
+
+# Licensed to PSF under a Contributor Agreement.
+# See http://www.python.org/2.4/license for licensing details.
+
+##
+# Limited XInclude support for the ElementTree package.
+##
+
+import copy
+import ElementTree
+
+XINCLUDE = "{http://www.w3.org/2001/XInclude}"
+
+XINCLUDE_INCLUDE = XINCLUDE + "include"
+XINCLUDE_FALLBACK = XINCLUDE + "fallback"
+
+##
+# Fatal include error.
+
+class FatalIncludeError(SyntaxError):
+    pass
+
+##
+# Default loader.  This loader reads an included resource from disk.
+#
+# @param href Resource reference.
+# @param parse Parse mode.  Either "xml" or "text".
+# @param encoding Optional text encoding.
+# @return The expanded resource.  If the parse mode is "xml", this
+#    is an ElementTree instance.  If the parse mode is "text", this
+#    is a Unicode string.  If the loader fails, it can return None
+#    or raise an IOError exception.
+# @throws IOError If the loader fails to load the resource.
+
+def default_loader(href, parse, encoding=None):
+    file = open(href)
+    if parse == "xml":
+        data = ElementTree.parse(file).getroot()
+    else:
+        data = file.read()
+        if encoding:
+            data = data.decode(encoding)
+    file.close()
+    return data
+
+##
+# Expand XInclude directives.
+#
+# @param elem Root element.
+# @param loader Optional resource loader.  If omitted, it defaults
+#     to {@link default_loader}.  If given, it should be a callable
+#     that implements the same interface as <b>default_loader</b>.
+# @throws FatalIncludeError If the function fails to include a given
+#     resource, or if the tree contains malformed XInclude elements.
+# @throws IOError If the function fails to load a given resource.
+
+def include(elem, loader=None):
+    if loader is None:
+        loader = default_loader
+    # look for xinclude elements
+    i = 0
+    while i < len(elem):
+        e = elem[i]
+        if e.tag == XINCLUDE_INCLUDE:
+            # process xinclude directive
+            href = e.get("href")
+            parse = e.get("parse", "xml")
+            if parse == "xml":
+                node = loader(href, parse)
+                if node is None:
+                    raise FatalIncludeError(
+                        "cannot load %r as %r" % (href, parse)
+                        )
+                node = copy.copy(node)
+                if e.tail:
+                    node.tail = (node.tail or "") + e.tail
+                elem[i] = node
+            elif parse == "text":
+                text = loader(href, parse, e.get("encoding"))
+                if text is None:
+                    raise FatalIncludeError(
+                        "cannot load %r as %r" % (href, parse)
+                        )
+                if i:
+                    node = elem[i-1]
+                    node.tail = (node.tail or "") + text
+                else:
+                    elem.text = (elem.text or "") + text + (e.tail or "")
+                del elem[i]
+                continue
+            else:
+                raise FatalIncludeError(
+                    "unknown parse type in xi:include tag (%r)" % parse
+                )
+        elif e.tag == XINCLUDE_FALLBACK:
+            raise FatalIncludeError(
+                "xi:fallback tag must be child of xi:include (%r)" % e.tag
+                )
+        else:
+            include(e, loader)
+        i = i + 1

Added: vendor/Python/current/Lib/xml/etree/ElementPath.py
===================================================================
--- vendor/Python/current/Lib/xml/etree/ElementPath.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/xml/etree/ElementPath.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,198 @@
+#
+# ElementTree
+# $Id: ElementPath.py 1858 2004-06-17 21:31:41Z Fredrik $
+#
+# limited xpath support for element trees
+#
+# history:
+# 2003-05-23 fl   created
+# 2003-05-28 fl   added support for // etc
+# 2003-08-27 fl   fixed parsing of periods in element names
+#
+# Copyright (c) 2003-2004 by Fredrik Lundh.  All rights reserved.
+#
+# fredrik at pythonware.com
+# http://www.pythonware.com
+#
+# --------------------------------------------------------------------
+# The ElementTree toolkit is
+#
+# Copyright (c) 1999-2004 by Fredrik Lundh
+#
+# By obtaining, using, and/or copying this software and/or its
+# associated documentation, you agree that you have read, understood,
+# and will comply with the following terms and conditions:
+#
+# Permission to use, copy, modify, and distribute this software and
+# its associated documentation for any purpose and without fee is
+# hereby granted, provided that the above copyright notice appears in
+# all copies, and that both that copyright notice and this permission
+# notice appear in supporting documentation, and that the name of
+# Secret Labs AB or the author not be used in advertising or publicity
+# pertaining to distribution of the software without specific, written
+# prior permission.
+#
+# SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
+# TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT-
+# ABILITY AND FITNESS.  IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR
+# BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+# OF THIS SOFTWARE.
+# --------------------------------------------------------------------
+
+# Licensed to PSF under a Contributor Agreement.
+# See http://www.python.org/2.4/license for licensing details.
+
+##
+# Implementation module for XPath support.  There's usually no reason
+# to import this module directly; the <b>ElementTree</b> does this for
+# you, if needed.
+##
+
+import re
+
+xpath_tokenizer = re.compile(
+    "(::|\.\.|\(\)|[/.*:\[\]\(\)@=])|((?:\{[^}]+\})?[^/:\[\]\(\)@=\s]+)|\s+"
+    ).findall
+
+class xpath_descendant_or_self:
+    pass
+
+##
+# Wrapper for a compiled XPath.
+
+class Path:
+
+    ##
+    # Create an Path instance from an XPath expression.
+
+    def __init__(self, path):
+        tokens = xpath_tokenizer(path)
+        # the current version supports 'path/path'-style expressions only
+        self.path = []
+        self.tag = None
+        if tokens and tokens[0][0] == "/":
+            raise SyntaxError("cannot use absolute path on element")
+        while tokens:
+            op, tag = tokens.pop(0)
+            if tag or op == "*":
+                self.path.append(tag or op)
+            elif op == ".":
+                pass
+            elif op == "/":
+                self.path.append(xpath_descendant_or_self())
+                continue
+            else:
+                raise SyntaxError("unsupported path syntax (%s)" % op)
+            if tokens:
+                op, tag = tokens.pop(0)
+                if op != "/":
+                    raise SyntaxError(
+                        "expected path separator (%s)" % (op or tag)
+                        )
+        if self.path and isinstance(self.path[-1], xpath_descendant_or_self):
+            raise SyntaxError("path cannot end with //")
+        if len(self.path) == 1 and isinstance(self.path[0], type("")):
+            self.tag = self.path[0]
+
+    ##
+    # Find first matching object.
+
+    def find(self, element):
+        tag = self.tag
+        if tag is None:
+            nodeset = self.findall(element)
+            if not nodeset:
+                return None
+            return nodeset[0]
+        for elem in element:
+            if elem.tag == tag:
+                return elem
+        return None
+
+    ##
+    # Find text for first matching object.
+
+    def findtext(self, element, default=None):
+        tag = self.tag
+        if tag is None:
+            nodeset = self.findall(element)
+            if not nodeset:
+                return default
+            return nodeset[0].text or ""
+        for elem in element:
+            if elem.tag == tag:
+                return elem.text or ""
+        return default
+
+    ##
+    # Find all matching objects.
+
+    def findall(self, element):
+        nodeset = [element]
+        index = 0
+        while 1:
+            try:
+                path = self.path[index]
+                index = index + 1
+            except IndexError:
+                return nodeset
+            set = []
+            if isinstance(path, xpath_descendant_or_self):
+                try:
+                    tag = self.path[index]
+                    if not isinstance(tag, type("")):
+                        tag = None
+                    else:
+                        index = index + 1
+                except IndexError:
+                    tag = None # invalid path
+                for node in nodeset:
+                    new = list(node.getiterator(tag))
+                    if new and new[0] is node:
+                        set.extend(new[1:])
+                    else:
+                        set.extend(new)
+            else:
+                for node in nodeset:
+                    for node in node:
+                        if path == "*" or node.tag == path:
+                            set.append(node)
+            if not set:
+                return []
+            nodeset = set
+
+_cache = {}
+
+##
+# (Internal) Compile path.
+
+def _compile(path):
+    p = _cache.get(path)
+    if p is not None:
+        return p
+    p = Path(path)
+    if len(_cache) >= 100:
+        _cache.clear()
+    _cache[path] = p
+    return p
+
+##
+# Find first matching object.
+
+def find(element, path):
+    return _compile(path).find(element)
+
+##
+# Find text for first matching object.
+
+def findtext(element, path, default=None):
+    return _compile(path).findtext(element, default)
+
+##
+# Find all matching objects.
+
+def findall(element, path):
+    return _compile(path).findall(element)

Added: vendor/Python/current/Lib/xml/etree/ElementTree.py
===================================================================
--- vendor/Python/current/Lib/xml/etree/ElementTree.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/xml/etree/ElementTree.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1260 @@
+#
+# ElementTree
+# $Id: ElementTree.py 2326 2005-03-17 07:45:21Z fredrik $
+#
+# light-weight XML support for Python 1.5.2 and later.
+#
+# history:
+# 2001-10-20 fl   created (from various sources)
+# 2001-11-01 fl   return root from parse method
+# 2002-02-16 fl   sort attributes in lexical order
+# 2002-04-06 fl   TreeBuilder refactoring, added PythonDoc markup
+# 2002-05-01 fl   finished TreeBuilder refactoring
+# 2002-07-14 fl   added basic namespace support to ElementTree.write
+# 2002-07-25 fl   added QName attribute support
+# 2002-10-20 fl   fixed encoding in write
+# 2002-11-24 fl   changed default encoding to ascii; fixed attribute encoding
+# 2002-11-27 fl   accept file objects or file names for parse/write
+# 2002-12-04 fl   moved XMLTreeBuilder back to this module
+# 2003-01-11 fl   fixed entity encoding glitch for us-ascii
+# 2003-02-13 fl   added XML literal factory
+# 2003-02-21 fl   added ProcessingInstruction/PI factory
+# 2003-05-11 fl   added tostring/fromstring helpers
+# 2003-05-26 fl   added ElementPath support
+# 2003-07-05 fl   added makeelement factory method
+# 2003-07-28 fl   added more well-known namespace prefixes
+# 2003-08-15 fl   fixed typo in ElementTree.findtext (Thomas Dartsch)
+# 2003-09-04 fl   fall back on emulator if ElementPath is not installed
+# 2003-10-31 fl   markup updates
+# 2003-11-15 fl   fixed nested namespace bug
+# 2004-03-28 fl   added XMLID helper
+# 2004-06-02 fl   added default support to findtext
+# 2004-06-08 fl   fixed encoding of non-ascii element/attribute names
+# 2004-08-23 fl   take advantage of post-2.1 expat features
+# 2005-02-01 fl   added iterparse implementation
+# 2005-03-02 fl   fixed iterparse support for pre-2.2 versions
+#
+# Copyright (c) 1999-2005 by Fredrik Lundh.  All rights reserved.
+#
+# fredrik at pythonware.com
+# http://www.pythonware.com
+#
+# --------------------------------------------------------------------
+# The ElementTree toolkit is
+#
+# Copyright (c) 1999-2005 by Fredrik Lundh
+#
+# By obtaining, using, and/or copying this software and/or its
+# associated documentation, you agree that you have read, understood,
+# and will comply with the following terms and conditions:
+#
+# Permission to use, copy, modify, and distribute this software and
+# its associated documentation for any purpose and without fee is
+# hereby granted, provided that the above copyright notice appears in
+# all copies, and that both that copyright notice and this permission
+# notice appear in supporting documentation, and that the name of
+# Secret Labs AB or the author not be used in advertising or publicity
+# pertaining to distribution of the software without specific, written
+# prior permission.
+#
+# SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
+# TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT-
+# ABILITY AND FITNESS.  IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR
+# BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+# OF THIS SOFTWARE.
+# --------------------------------------------------------------------
+
+# Licensed to PSF under a Contributor Agreement.
+# See http://www.python.org/2.4/license for licensing details.
+
+__all__ = [
+    # public symbols
+    "Comment",
+    "dump",
+    "Element", "ElementTree",
+    "fromstring",
+    "iselement", "iterparse",
+    "parse",
+    "PI", "ProcessingInstruction",
+    "QName",
+    "SubElement",
+    "tostring",
+    "TreeBuilder",
+    "VERSION", "XML",
+    "XMLParser", "XMLTreeBuilder",
+    ]
+
+##
+# The <b>Element</b> type is a flexible container object, designed to
+# store hierarchical data structures in memory. The type can be
+# described as a cross between a list and a dictionary.
+# <p>
+# Each element has a number of properties associated with it:
+# <ul>
+# <li>a <i>tag</i>. This is a string identifying what kind of data
+# this element represents (the element type, in other words).</li>
+# <li>a number of <i>attributes</i>, stored in a Python dictionary.</li>
+# <li>a <i>text</i> string.</li>
+# <li>an optional <i>tail</i> string.</li>
+# <li>a number of <i>child elements</i>, stored in a Python sequence</li>
+# </ul>
+#
+# To create an element instance, use the {@link #Element} or {@link
+# #SubElement} factory functions.
+# <p>
+# The {@link #ElementTree} class can be used to wrap an element
+# structure, and convert it from and to XML.
+##
+
+import string, sys, re
+
+class _SimpleElementPath:
+    # emulate pre-1.2 find/findtext/findall behaviour
+    def find(self, element, tag):
+        for elem in element:
+            if elem.tag == tag:
+                return elem
+        return None
+    def findtext(self, element, tag, default=None):
+        for elem in element:
+            if elem.tag == tag:
+                return elem.text or ""
+        return default
+    def findall(self, element, tag):
+        if tag[:3] == ".//":
+            return element.getiterator(tag[3:])
+        result = []
+        for elem in element:
+            if elem.tag == tag:
+                result.append(elem)
+        return result
+
+try:
+    import ElementPath
+except ImportError:
+    # FIXME: issue warning in this case?
+    ElementPath = _SimpleElementPath()
+
+# TODO: add support for custom namespace resolvers/default namespaces
+# TODO: add improved support for incremental parsing
+
+VERSION = "1.2.6"
+
+##
+# Internal element class.  This class defines the Element interface,
+# and provides a reference implementation of this interface.
+# <p>
+# You should not create instances of this class directly.  Use the
+# appropriate factory functions instead, such as {@link #Element}
+# and {@link #SubElement}.
+#
+# @see Element
+# @see SubElement
+# @see Comment
+# @see ProcessingInstruction
+
+class _ElementInterface:
+    # <tag attrib>text<child/>...</tag>tail
+
+    ##
+    # (Attribute) Element tag.
+
+    tag = None
+
+    ##
+    # (Attribute) Element attribute dictionary.  Where possible, use
+    # {@link #_ElementInterface.get},
+    # {@link #_ElementInterface.set},
+    # {@link #_ElementInterface.keys}, and
+    # {@link #_ElementInterface.items} to access
+    # element attributes.
+
+    attrib = None
+
+    ##
+    # (Attribute) Text before first subelement.  This is either a
+    # string or the value None, if there was no text.
+
+    text = None
+
+    ##
+    # (Attribute) Text after this element's end tag, but before the
+    # next sibling element's start tag.  This is either a string or
+    # the value None, if there was no text.
+
+    tail = None # text after end tag, if any
+
+    def __init__(self, tag, attrib):
+        self.tag = tag
+        self.attrib = attrib
+        self._children = []
+
+    def __repr__(self):
+        return "<Element %s at %x>" % (self.tag, id(self))
+
+    ##
+    # Creates a new element object of the same type as this element.
+    #
+    # @param tag Element tag.
+    # @param attrib Element attributes, given as a dictionary.
+    # @return A new element instance.
+
+    def makeelement(self, tag, attrib):
+        return Element(tag, attrib)
+
+    ##
+    # Returns the number of subelements.
+    #
+    # @return The number of subelements.
+
+    def __len__(self):
+        return len(self._children)
+
+    ##
+    # Returns the given subelement.
+    #
+    # @param index What subelement to return.
+    # @return The given subelement.
+    # @exception IndexError If the given element does not exist.
+
+    def __getitem__(self, index):
+        return self._children[index]
+
+    ##
+    # Replaces the given subelement.
+    #
+    # @param index What subelement to replace.
+    # @param element The new element value.
+    # @exception IndexError If the given element does not exist.
+    # @exception AssertionError If element is not a valid object.
+
+    def __setitem__(self, index, element):
+        assert iselement(element)
+        self._children[index] = element
+
+    ##
+    # Deletes the given subelement.
+    #
+    # @param index What subelement to delete.
+    # @exception IndexError If the given element does not exist.
+
+    def __delitem__(self, index):
+        del self._children[index]
+
+    ##
+    # Returns a list containing subelements in the given range.
+    #
+    # @param start The first subelement to return.
+    # @param stop The first subelement that shouldn't be returned.
+    # @return A sequence object containing subelements.
+
+    def __getslice__(self, start, stop):
+        return self._children[start:stop]
+
+    ##
+    # Replaces a number of subelements with elements from a sequence.
+    #
+    # @param start The first subelement to replace.
+    # @param stop The first subelement that shouldn't be replaced.
+    # @param elements A sequence object with zero or more elements.
+    # @exception AssertionError If a sequence member is not a valid object.
+
+    def __setslice__(self, start, stop, elements):
+        for element in elements:
+            assert iselement(element)
+        self._children[start:stop] = list(elements)
+
+    ##
+    # Deletes a number of subelements.
+    #
+    # @param start The first subelement to delete.
+    # @param stop The first subelement to leave in there.
+
+    def __delslice__(self, start, stop):
+        del self._children[start:stop]
+
+    ##
+    # Adds a subelement to the end of this element.
+    #
+    # @param element The element to add.
+    # @exception AssertionError If a sequence member is not a valid object.
+
+    def append(self, element):
+        assert iselement(element)
+        self._children.append(element)
+
+    ##
+    # Inserts a subelement at the given position in this element.
+    #
+    # @param index Where to insert the new subelement.
+    # @exception AssertionError If the element is not a valid object.
+
+    def insert(self, index, element):
+        assert iselement(element)
+        self._children.insert(index, element)
+
+    ##
+    # Removes a matching subelement.  Unlike the <b>find</b> methods,
+    # this method compares elements based on identity, not on tag
+    # value or contents.
+    #
+    # @param element What element to remove.
+    # @exception ValueError If a matching element could not be found.
+    # @exception AssertionError If the element is not a valid object.
+
+    def remove(self, element):
+        assert iselement(element)
+        self._children.remove(element)
+
+    ##
+    # Returns all subelements.  The elements are returned in document
+    # order.
+    #
+    # @return A list of subelements.
+    # @defreturn list of Element instances
+
+    def getchildren(self):
+        return self._children
+
+    ##
+    # Finds the first matching subelement, by tag name or path.
+    #
+    # @param path What element to look for.
+    # @return The first matching element, or None if no element was found.
+    # @defreturn Element or None
+
+    def find(self, path):
+        return ElementPath.find(self, path)
+
+    ##
+    # Finds text for the first matching subelement, by tag name or path.
+    #
+    # @param path What element to look for.
+    # @param default What to return if the element was not found.
+    # @return The text content of the first matching element, or the
+    #     default value no element was found.  Note that if the element
+    #     has is found, but has no text content, this method returns an
+    #     empty string.
+    # @defreturn string
+
+    def findtext(self, path, default=None):
+        return ElementPath.findtext(self, path, default)
+
+    ##
+    # Finds all matching subelements, by tag name or path.
+    #
+    # @param path What element to look for.
+    # @return A list or iterator containing all matching elements,
+    #    in document order.
+    # @defreturn list of Element instances
+
+    def findall(self, path):
+        return ElementPath.findall(self, path)
+
+    ##
+    # Resets an element.  This function removes all subelements, clears
+    # all attributes, and sets the text and tail attributes to None.
+
+    def clear(self):
+        self.attrib.clear()
+        self._children = []
+        self.text = self.tail = None
+
+    ##
+    # Gets an element attribute.
+    #
+    # @param key What attribute to look for.
+    # @param default What to return if the attribute was not found.
+    # @return The attribute value, or the default value, if the
+    #     attribute was not found.
+    # @defreturn string or None
+
+    def get(self, key, default=None):
+        return self.attrib.get(key, default)
+
+    ##
+    # Sets an element attribute.
+    #
+    # @param key What attribute to set.
+    # @param value The attribute value.
+
+    def set(self, key, value):
+        self.attrib[key] = value
+
+    ##
+    # Gets a list of attribute names.  The names are returned in an
+    # arbitrary order (just like for an ordinary Python dictionary).
+    #
+    # @return A list of element attribute names.
+    # @defreturn list of strings
+
+    def keys(self):
+        return self.attrib.keys()
+
+    ##
+    # Gets element attributes, as a sequence.  The attributes are
+    # returned in an arbitrary order.
+    #
+    # @return A list of (name, value) tuples for all attributes.
+    # @defreturn list of (string, string) tuples
+
+    def items(self):
+        return self.attrib.items()
+
+    ##
+    # Creates a tree iterator.  The iterator loops over this element
+    # and all subelements, in document order, and returns all elements
+    # with a matching tag.
+    # <p>
+    # If the tree structure is modified during iteration, the result
+    # is undefined.
+    #
+    # @param tag What tags to look for (default is to return all elements).
+    # @return A list or iterator containing all the matching elements.
+    # @defreturn list or iterator
+
+    def getiterator(self, tag=None):
+        nodes = []
+        if tag == "*":
+            tag = None
+        if tag is None or self.tag == tag:
+            nodes.append(self)
+        for node in self._children:
+            nodes.extend(node.getiterator(tag))
+        return nodes
+
+# compatibility
+_Element = _ElementInterface
+
+##
+# Element factory.  This function returns an object implementing the
+# standard Element interface.  The exact class or type of that object
+# is implementation dependent, but it will always be compatible with
+# the {@link #_ElementInterface} class in this module.
+# <p>
+# The element name, attribute names, and attribute values can be
+# either 8-bit ASCII strings or Unicode strings.
+#
+# @param tag The element name.
+# @param attrib An optional dictionary, containing element attributes.
+# @param **extra Additional attributes, given as keyword arguments.
+# @return An element instance.
+# @defreturn Element
+
+def Element(tag, attrib={}, **extra):
+    attrib = attrib.copy()
+    attrib.update(extra)
+    return _ElementInterface(tag, attrib)
+
+##
+# Subelement factory.  This function creates an element instance, and
+# appends it to an existing element.
+# <p>
+# The element name, attribute names, and attribute values can be
+# either 8-bit ASCII strings or Unicode strings.
+#
+# @param parent The parent element.
+# @param tag The subelement name.
+# @param attrib An optional dictionary, containing element attributes.
+# @param **extra Additional attributes, given as keyword arguments.
+# @return An element instance.
+# @defreturn Element
+
+def SubElement(parent, tag, attrib={}, **extra):
+    attrib = attrib.copy()
+    attrib.update(extra)
+    element = parent.makeelement(tag, attrib)
+    parent.append(element)
+    return element
+
+##
+# Comment element factory.  This factory function creates a special
+# element that will be serialized as an XML comment.
+# <p>
+# The comment string can be either an 8-bit ASCII string or a Unicode
+# string.
+#
+# @param text A string containing the comment string.
+# @return An element instance, representing a comment.
+# @defreturn Element
+
+def Comment(text=None):
+    element = Element(Comment)
+    element.text = text
+    return element
+
+##
+# PI element factory.  This factory function creates a special element
+# that will be serialized as an XML processing instruction.
+#
+# @param target A string containing the PI target.
+# @param text A string containing the PI contents, if any.
+# @return An element instance, representing a PI.
+# @defreturn Element
+
+def ProcessingInstruction(target, text=None):
+    element = Element(ProcessingInstruction)
+    element.text = target
+    if text:
+        element.text = element.text + " " + text
+    return element
+
+PI = ProcessingInstruction
+
+##
+# QName wrapper.  This can be used to wrap a QName attribute value, in
+# order to get proper namespace handling on output.
+#
+# @param text A string containing the QName value, in the form {uri}local,
+#     or, if the tag argument is given, the URI part of a QName.
+# @param tag Optional tag.  If given, the first argument is interpreted as
+#     an URI, and this argument is interpreted as a local name.
+# @return An opaque object, representing the QName.
+
+class QName:
+    def __init__(self, text_or_uri, tag=None):
+        if tag:
+            text_or_uri = "{%s}%s" % (text_or_uri, tag)
+        self.text = text_or_uri
+    def __str__(self):
+        return self.text
+    def __hash__(self):
+        return hash(self.text)
+    def __cmp__(self, other):
+        if isinstance(other, QName):
+            return cmp(self.text, other.text)
+        return cmp(self.text, other)
+
+##
+# ElementTree wrapper class.  This class represents an entire element
+# hierarchy, and adds some extra support for serialization to and from
+# standard XML.
+#
+# @param element Optional root element.
+# @keyparam file Optional file handle or name.  If given, the
+#     tree is initialized with the contents of this XML file.
+
+class ElementTree:
+
+    def __init__(self, element=None, file=None):
+        assert element is None or iselement(element)
+        self._root = element # first node
+        if file:
+            self.parse(file)
+
+    ##
+    # Gets the root element for this tree.
+    #
+    # @return An element instance.
+    # @defreturn Element
+
+    def getroot(self):
+        return self._root
+
+    ##
+    # Replaces the root element for this tree.  This discards the
+    # current contents of the tree, and replaces it with the given
+    # element.  Use with care.
+    #
+    # @param element An element instance.
+
+    def _setroot(self, element):
+        assert iselement(element)
+        self._root = element
+
+    ##
+    # Loads an external XML document into this element tree.
+    #
+    # @param source A file name or file object.
+    # @param parser An optional parser instance.  If not given, the
+    #     standard {@link XMLTreeBuilder} parser is used.
+    # @return The document root element.
+    # @defreturn Element
+
+    def parse(self, source, parser=None):
+        if not hasattr(source, "read"):
+            source = open(source, "rb")
+        if not parser:
+            parser = XMLTreeBuilder()
+        while 1:
+            data = source.read(32768)
+            if not data:
+                break
+            parser.feed(data)
+        self._root = parser.close()
+        return self._root
+
+    ##
+    # Creates a tree iterator for the root element.  The iterator loops
+    # over all elements in this tree, in document order.
+    #
+    # @param tag What tags to look for (default is to return all elements)
+    # @return An iterator.
+    # @defreturn iterator
+
+    def getiterator(self, tag=None):
+        assert self._root is not None
+        return self._root.getiterator(tag)
+
+    ##
+    # Finds the first toplevel element with given tag.
+    # Same as getroot().find(path).
+    #
+    # @param path What element to look for.
+    # @return The first matching element, or None if no element was found.
+    # @defreturn Element or None
+
+    def find(self, path):
+        assert self._root is not None
+        if path[:1] == "/":
+            path = "." + path
+        return self._root.find(path)
+
+    ##
+    # Finds the element text for the first toplevel element with given
+    # tag.  Same as getroot().findtext(path).
+    #
+    # @param path What toplevel element to look for.
+    # @param default What to return if the element was not found.
+    # @return The text content of the first matching element, or the
+    #     default value no element was found.  Note that if the element
+    #     has is found, but has no text content, this method returns an
+    #     empty string.
+    # @defreturn string
+
+    def findtext(self, path, default=None):
+        assert self._root is not None
+        if path[:1] == "/":
+            path = "." + path
+        return self._root.findtext(path, default)
+
+    ##
+    # Finds all toplevel elements with the given tag.
+    # Same as getroot().findall(path).
+    #
+    # @param path What element to look for.
+    # @return A list or iterator containing all matching elements,
+    #    in document order.
+    # @defreturn list of Element instances
+
+    def findall(self, path):
+        assert self._root is not None
+        if path[:1] == "/":
+            path = "." + path
+        return self._root.findall(path)
+
+    ##
+    # Writes the element tree to a file, as XML.
+    #
+    # @param file A file name, or a file object opened for writing.
+    # @param encoding Optional output encoding (default is US-ASCII).
+
+    def write(self, file, encoding="us-ascii"):
+        assert self._root is not None
+        if not hasattr(file, "write"):
+            file = open(file, "wb")
+        if not encoding:
+            encoding = "us-ascii"
+        elif encoding != "utf-8" and encoding != "us-ascii":
+            file.write("<?xml version='1.0' encoding='%s'?>\n" % encoding)
+        self._write(file, self._root, encoding, {})
+
+    def _write(self, file, node, encoding, namespaces):
+        # write XML to file
+        tag = node.tag
+        if tag is Comment:
+            file.write("<!-- %s -->" % _escape_cdata(node.text, encoding))
+        elif tag is ProcessingInstruction:
+            file.write("<?%s?>" % _escape_cdata(node.text, encoding))
+        else:
+            items = node.items()
+            xmlns_items = [] # new namespaces in this scope
+            try:
+                if isinstance(tag, QName) or tag[:1] == "{":
+                    tag, xmlns = fixtag(tag, namespaces)
+                    if xmlns: xmlns_items.append(xmlns)
+            except TypeError:
+                _raise_serialization_error(tag)
+            file.write("<" + _encode(tag, encoding))
+            if items or xmlns_items:
+                items.sort() # lexical order
+                for k, v in items:
+                    try:
+                        if isinstance(k, QName) or k[:1] == "{":
+                            k, xmlns = fixtag(k, namespaces)
+                            if xmlns: xmlns_items.append(xmlns)
+                    except TypeError:
+                        _raise_serialization_error(k)
+                    try:
+                        if isinstance(v, QName):
+                            v, xmlns = fixtag(v, namespaces)
+                            if xmlns: xmlns_items.append(xmlns)
+                    except TypeError:
+                        _raise_serialization_error(v)
+                    file.write(" %s=\"%s\"" % (_encode(k, encoding),
+                                               _escape_attrib(v, encoding)))
+                for k, v in xmlns_items:
+                    file.write(" %s=\"%s\"" % (_encode(k, encoding),
+                                               _escape_attrib(v, encoding)))
+            if node.text or len(node):
+                file.write(">")
+                if node.text:
+                    file.write(_escape_cdata(node.text, encoding))
+                for n in node:
+                    self._write(file, n, encoding, namespaces)
+                file.write("</" + _encode(tag, encoding) + ">")
+            else:
+                file.write(" />")
+            for k, v in xmlns_items:
+                del namespaces[v]
+        if node.tail:
+            file.write(_escape_cdata(node.tail, encoding))
+
+# --------------------------------------------------------------------
+# helpers
+
+##
+# Checks if an object appears to be a valid element object.
+#
+# @param An element instance.
+# @return A true value if this is an element object.
+# @defreturn flag
+
+def iselement(element):
+    # FIXME: not sure about this; might be a better idea to look
+    # for tag/attrib/text attributes
+    return isinstance(element, _ElementInterface) or hasattr(element, "tag")
+
+##
+# Writes an element tree or element structure to sys.stdout.  This
+# function should be used for debugging only.
+# <p>
+# The exact output format is implementation dependent.  In this
+# version, it's written as an ordinary XML file.
+#
+# @param elem An element tree or an individual element.
+
+def dump(elem):
+    # debugging
+    if not isinstance(elem, ElementTree):
+        elem = ElementTree(elem)
+    elem.write(sys.stdout)
+    tail = elem.getroot().tail
+    if not tail or tail[-1] != "\n":
+        sys.stdout.write("\n")
+
+def _encode(s, encoding):
+    try:
+        return s.encode(encoding)
+    except AttributeError:
+        return s # 1.5.2: assume the string uses the right encoding
+
+if sys.version[:3] == "1.5":
+    _escape = re.compile(r"[&<>\"\x80-\xff]+") # 1.5.2
+else:
+    _escape = re.compile(eval(r'u"[&<>\"\u0080-\uffff]+"'))
+
+_escape_map = {
+    "&": "&amp;",
+    "<": "&lt;",
+    ">": "&gt;",
+    '"': "&quot;",
+}
+
+_namespace_map = {
+    # "well-known" namespace prefixes
+    "http://www.w3.org/XML/1998/namespace": "xml",
+    "http://www.w3.org/1999/xhtml": "html",
+    "http://www.w3.org/1999/02/22-rdf-syntax-ns#": "rdf",
+    "http://schemas.xmlsoap.org/wsdl/": "wsdl",
+}
+
+def _raise_serialization_error(text):
+    raise TypeError(
+        "cannot serialize %r (type %s)" % (text, type(text).__name__)
+        )
+
+def _encode_entity(text, pattern=_escape):
+    # map reserved and non-ascii characters to numerical entities
+    def escape_entities(m, map=_escape_map):
+        out = []
+        append = out.append
+        for char in m.group():
+            text = map.get(char)
+            if text is None:
+                text = "&#%d;" % ord(char)
+            append(text)
+        return string.join(out, "")
+    try:
+        return _encode(pattern.sub(escape_entities, text), "ascii")
+    except TypeError:
+        _raise_serialization_error(text)
+
+#
+# the following functions assume an ascii-compatible encoding
+# (or "utf-16")
+
+def _escape_cdata(text, encoding=None, replace=string.replace):
+    # escape character data
+    try:
+        if encoding:
+            try:
+                text = _encode(text, encoding)
+            except UnicodeError:
+                return _encode_entity(text)
+        text = replace(text, "&", "&amp;")
+        text = replace(text, "<", "&lt;")
+        text = replace(text, ">", "&gt;")
+        return text
+    except (TypeError, AttributeError):
+        _raise_serialization_error(text)
+
+def _escape_attrib(text, encoding=None, replace=string.replace):
+    # escape attribute value
+    try:
+        if encoding:
+            try:
+                text = _encode(text, encoding)
+            except UnicodeError:
+                return _encode_entity(text)
+        text = replace(text, "&", "&amp;")
+        text = replace(text, "'", "&apos;") # FIXME: overkill
+        text = replace(text, "\"", "&quot;")
+        text = replace(text, "<", "&lt;")
+        text = replace(text, ">", "&gt;")
+        return text
+    except (TypeError, AttributeError):
+        _raise_serialization_error(text)
+
+def fixtag(tag, namespaces):
+    # given a decorated tag (of the form {uri}tag), return prefixed
+    # tag and namespace declaration, if any
+    if isinstance(tag, QName):
+        tag = tag.text
+    namespace_uri, tag = string.split(tag[1:], "}", 1)
+    prefix = namespaces.get(namespace_uri)
+    if prefix is None:
+        prefix = _namespace_map.get(namespace_uri)
+        if prefix is None:
+            prefix = "ns%d" % len(namespaces)
+        namespaces[namespace_uri] = prefix
+        if prefix == "xml":
+            xmlns = None
+        else:
+            xmlns = ("xmlns:%s" % prefix, namespace_uri)
+    else:
+        xmlns = None
+    return "%s:%s" % (prefix, tag), xmlns
+
+##
+# Parses an XML document into an element tree.
+#
+# @param source A filename or file object containing XML data.
+# @param parser An optional parser instance.  If not given, the
+#     standard {@link XMLTreeBuilder} parser is used.
+# @return An ElementTree instance
+
+def parse(source, parser=None):
+    tree = ElementTree()
+    tree.parse(source, parser)
+    return tree
+
+##
+# Parses an XML document into an element tree incrementally, and reports
+# what's going on to the user.
+#
+# @param source A filename or file object containing XML data.
+# @param events A list of events to report back.  If omitted, only "end"
+#     events are reported.
+# @return A (event, elem) iterator.
+
+class iterparse:
+
+    def __init__(self, source, events=None):
+        if not hasattr(source, "read"):
+            source = open(source, "rb")
+        self._file = source
+        self._events = []
+        self._index = 0
+        self.root = self._root = None
+        self._parser = XMLTreeBuilder()
+        # wire up the parser for event reporting
+        parser = self._parser._parser
+        append = self._events.append
+        if events is None:
+            events = ["end"]
+        for event in events:
+            if event == "start":
+                try:
+                    parser.ordered_attributes = 1
+                    parser.specified_attributes = 1
+                    def handler(tag, attrib_in, event=event, append=append,
+                                start=self._parser._start_list):
+                        append((event, start(tag, attrib_in)))
+                    parser.StartElementHandler = handler
+                except AttributeError:
+                    def handler(tag, attrib_in, event=event, append=append,
+                                start=self._parser._start):
+                        append((event, start(tag, attrib_in)))
+                    parser.StartElementHandler = handler
+            elif event == "end":
+                def handler(tag, event=event, append=append,
+                            end=self._parser._end):
+                    append((event, end(tag)))
+                parser.EndElementHandler = handler
+            elif event == "start-ns":
+                def handler(prefix, uri, event=event, append=append):
+                    try:
+                        uri = _encode(uri, "ascii")
+                    except UnicodeError:
+                        pass
+                    append((event, (prefix or "", uri)))
+                parser.StartNamespaceDeclHandler = handler
+            elif event == "end-ns":
+                def handler(prefix, event=event, append=append):
+                    append((event, None))
+                parser.EndNamespaceDeclHandler = handler
+
+    def next(self):
+        while 1:
+            try:
+                item = self._events[self._index]
+            except IndexError:
+                if self._parser is None:
+                    self.root = self._root
+                    try:
+                        raise StopIteration
+                    except NameError:
+                        raise IndexError
+                # load event buffer
+                del self._events[:]
+                self._index = 0
+                data = self._file.read(16384)
+                if data:
+                    self._parser.feed(data)
+                else:
+                    self._root = self._parser.close()
+                    self._parser = None
+            else:
+                self._index = self._index + 1
+                return item
+
+    try:
+        iter
+        def __iter__(self):
+            return self
+    except NameError:
+        def __getitem__(self, index):
+            return self.next()
+
+##
+# Parses an XML document from a string constant.  This function can
+# be used to embed "XML literals" in Python code.
+#
+# @param source A string containing XML data.
+# @return An Element instance.
+# @defreturn Element
+
+def XML(text):
+    parser = XMLTreeBuilder()
+    parser.feed(text)
+    return parser.close()
+
+##
+# Parses an XML document from a string constant, and also returns
+# a dictionary which maps from element id:s to elements.
+#
+# @param source A string containing XML data.
+# @return A tuple containing an Element instance and a dictionary.
+# @defreturn (Element, dictionary)
+
+def XMLID(text):
+    parser = XMLTreeBuilder()
+    parser.feed(text)
+    tree = parser.close()
+    ids = {}
+    for elem in tree.getiterator():
+        id = elem.get("id")
+        if id:
+            ids[id] = elem
+    return tree, ids
+
+##
+# Parses an XML document from a string constant.  Same as {@link #XML}.
+#
+# @def fromstring(text)
+# @param source A string containing XML data.
+# @return An Element instance.
+# @defreturn Element
+
+fromstring = XML
+
+##
+# Generates a string representation of an XML element, including all
+# subelements.
+#
+# @param element An Element instance.
+# @return An encoded string containing the XML data.
+# @defreturn string
+
+def tostring(element, encoding=None):
+    class dummy:
+        pass
+    data = []
+    file = dummy()
+    file.write = data.append
+    ElementTree(element).write(file, encoding)
+    return string.join(data, "")
+
+##
+# Generic element structure builder.  This builder converts a sequence
+# of {@link #TreeBuilder.start}, {@link #TreeBuilder.data}, and {@link
+# #TreeBuilder.end} method calls to a well-formed element structure.
+# <p>
+# You can use this class to build an element structure using a custom XML
+# parser, or a parser for some other XML-like format.
+#
+# @param element_factory Optional element factory.  This factory
+#    is called to create new Element instances, as necessary.
+
+class TreeBuilder:
+
+    def __init__(self, element_factory=None):
+        self._data = [] # data collector
+        self._elem = [] # element stack
+        self._last = None # last element
+        self._tail = None # true if we're after an end tag
+        if element_factory is None:
+            element_factory = _ElementInterface
+        self._factory = element_factory
+
+    ##
+    # Flushes the parser buffers, and returns the toplevel documen
+    # element.
+    #
+    # @return An Element instance.
+    # @defreturn Element
+
+    def close(self):
+        assert len(self._elem) == 0, "missing end tags"
+        assert self._last != None, "missing toplevel element"
+        return self._last
+
+    def _flush(self):
+        if self._data:
+            if self._last is not None:
+                text = string.join(self._data, "")
+                if self._tail:
+                    assert self._last.tail is None, "internal error (tail)"
+                    self._last.tail = text
+                else:
+                    assert self._last.text is None, "internal error (text)"
+                    self._last.text = text
+            self._data = []
+
+    ##
+    # Adds text to the current element.
+    #
+    # @param data A string.  This should be either an 8-bit string
+    #    containing ASCII text, or a Unicode string.
+
+    def data(self, data):
+        self._data.append(data)
+
+    ##
+    # Opens a new element.
+    #
+    # @param tag The element name.
+    # @param attrib A dictionary containing element attributes.
+    # @return The opened element.
+    # @defreturn Element
+
+    def start(self, tag, attrs):
+        self._flush()
+        self._last = elem = self._factory(tag, attrs)
+        if self._elem:
+            self._elem[-1].append(elem)
+        self._elem.append(elem)
+        self._tail = 0
+        return elem
+
+    ##
+    # Closes the current element.
+    #
+    # @param tag The element name.
+    # @return The closed element.
+    # @defreturn Element
+
+    def end(self, tag):
+        self._flush()
+        self._last = self._elem.pop()
+        assert self._last.tag == tag,\
+               "end tag mismatch (expected %s, got %s)" % (
+                   self._last.tag, tag)
+        self._tail = 1
+        return self._last
+
+##
+# Element structure builder for XML source data, based on the
+# <b>expat</b> parser.
+#
+# @keyparam target Target object.  If omitted, the builder uses an
+#     instance of the standard {@link #TreeBuilder} class.
+# @keyparam html Predefine HTML entities.  This flag is not supported
+#     by the current implementation.
+# @see #ElementTree
+# @see #TreeBuilder
+
+class XMLTreeBuilder:
+
+    def __init__(self, html=0, target=None):
+        try:
+            from xml.parsers import expat
+        except ImportError:
+            raise ImportError(
+                "No module named expat; use SimpleXMLTreeBuilder instead"
+                )
+        self._parser = parser = expat.ParserCreate(None, "}")
+        if target is None:
+            target = TreeBuilder()
+        self._target = target
+        self._names = {} # name memo cache
+        # callbacks
+        parser.DefaultHandlerExpand = self._default
+        parser.StartElementHandler = self._start
+        parser.EndElementHandler = self._end
+        parser.CharacterDataHandler = self._data
+        # let expat do the buffering, if supported
+        try:
+            self._parser.buffer_text = 1
+        except AttributeError:
+            pass
+        # use new-style attribute handling, if supported
+        try:
+            self._parser.ordered_attributes = 1
+            self._parser.specified_attributes = 1
+            parser.StartElementHandler = self._start_list
+        except AttributeError:
+            pass
+        encoding = None
+        if not parser.returns_unicode:
+            encoding = "utf-8"
+        # target.xml(encoding, None)
+        self._doctype = None
+        self.entity = {}
+
+    def _fixtext(self, text):
+        # convert text string to ascii, if possible
+        try:
+            return _encode(text, "ascii")
+        except UnicodeError:
+            return text
+
+    def _fixname(self, key):
+        # expand qname, and convert name string to ascii, if possible
+        try:
+            name = self._names[key]
+        except KeyError:
+            name = key
+            if "}" in name:
+                name = "{" + name
+            self._names[key] = name = self._fixtext(name)
+        return name
+
+    def _start(self, tag, attrib_in):
+        fixname = self._fixname
+        tag = fixname(tag)
+        attrib = {}
+        for key, value in attrib_in.items():
+            attrib[fixname(key)] = self._fixtext(value)
+        return self._target.start(tag, attrib)
+
+    def _start_list(self, tag, attrib_in):
+        fixname = self._fixname
+        tag = fixname(tag)
+        attrib = {}
+        if attrib_in:
+            for i in range(0, len(attrib_in), 2):
+                attrib[fixname(attrib_in[i])] = self._fixtext(attrib_in[i+1])
+        return self._target.start(tag, attrib)
+
+    def _data(self, text):
+        return self._target.data(self._fixtext(text))
+
+    def _end(self, tag):
+        return self._target.end(self._fixname(tag))
+
+    def _default(self, text):
+        prefix = text[:1]
+        if prefix == "&":
+            # deal with undefined entities
+            try:
+                self._target.data(self.entity[text[1:-1]])
+            except KeyError:
+                from xml.parsers import expat
+                raise expat.error(
+                    "undefined entity %s: line %d, column %d" %
+                    (text, self._parser.ErrorLineNumber,
+                    self._parser.ErrorColumnNumber)
+                    )
+        elif prefix == "<" and text[:9] == "<!DOCTYPE":
+            self._doctype = [] # inside a doctype declaration
+        elif self._doctype is not None:
+            # parse doctype contents
+            if prefix == ">":
+                self._doctype = None
+                return
+            text = string.strip(text)
+            if not text:
+                return
+            self._doctype.append(text)
+            n = len(self._doctype)
+            if n > 2:
+                type = self._doctype[1]
+                if type == "PUBLIC" and n == 4:
+                    name, type, pubid, system = self._doctype
+                elif type == "SYSTEM" and n == 3:
+                    name, type, system = self._doctype
+                    pubid = None
+                else:
+                    return
+                if pubid:
+                    pubid = pubid[1:-1]
+                self.doctype(name, pubid, system[1:-1])
+                self._doctype = None
+
+    ##
+    # Handles a doctype declaration.
+    #
+    # @param name Doctype name.
+    # @param pubid Public identifier.
+    # @param system System identifier.
+
+    def doctype(self, name, pubid, system):
+        pass
+
+    ##
+    # Feeds data to the parser.
+    #
+    # @param data Encoded data.
+
+    def feed(self, data):
+        self._parser.Parse(data, 0)
+
+    ##
+    # Finishes feeding data to the parser.
+    #
+    # @return An element structure.
+    # @defreturn Element
+
+    def close(self):
+        self._parser.Parse("", 1) # end of data
+        tree = self._target.close()
+        del self._target, self._parser # get rid of circular references
+        return tree
+
+# compatibility
+XMLParser = XMLTreeBuilder

Added: vendor/Python/current/Lib/xml/etree/__init__.py
===================================================================
--- vendor/Python/current/Lib/xml/etree/__init__.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/xml/etree/__init__.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,33 @@
+# $Id: __init__.py 1821 2004-06-03 16:57:49Z fredrik $
+# elementtree package
+
+# --------------------------------------------------------------------
+# The ElementTree toolkit is
+#
+# Copyright (c) 1999-2004 by Fredrik Lundh
+#
+# By obtaining, using, and/or copying this software and/or its
+# associated documentation, you agree that you have read, understood,
+# and will comply with the following terms and conditions:
+#
+# Permission to use, copy, modify, and distribute this software and
+# its associated documentation for any purpose and without fee is
+# hereby granted, provided that the above copyright notice appears in
+# all copies, and that both that copyright notice and this permission
+# notice appear in supporting documentation, and that the name of
+# Secret Labs AB or the author not be used in advertising or publicity
+# pertaining to distribution of the software without specific, written
+# prior permission.
+#
+# SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
+# TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT-
+# ABILITY AND FITNESS.  IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR
+# BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+# OF THIS SOFTWARE.
+# --------------------------------------------------------------------
+
+# Licensed to PSF under a Contributor Agreement.
+# See http://www.python.org/2.4/license for licensing details.

Added: vendor/Python/current/Lib/xml/etree/cElementTree.py
===================================================================
--- vendor/Python/current/Lib/xml/etree/cElementTree.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/xml/etree/cElementTree.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,3 @@
+# Wrapper module for _elementtree
+
+from _elementtree import *

Added: vendor/Python/current/Lib/xml/parsers/__init__.py
===================================================================
--- vendor/Python/current/Lib/xml/parsers/__init__.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/xml/parsers/__init__.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,8 @@
+"""Python interfaces to XML parsers.
+
+This package contains one module:
+
+expat -- Python wrapper for James Clark's Expat parser, with namespace
+         support.
+
+"""

Added: vendor/Python/current/Lib/xml/parsers/expat.py
===================================================================
--- vendor/Python/current/Lib/xml/parsers/expat.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/xml/parsers/expat.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,4 @@
+"""Interface to the Expat non-validating XML parser."""
+__version__ = '$Revision: 17640 $'
+
+from pyexpat import *

Added: vendor/Python/current/Lib/xml/sax/__init__.py
===================================================================
--- vendor/Python/current/Lib/xml/sax/__init__.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/xml/sax/__init__.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,108 @@
+"""Simple API for XML (SAX) implementation for Python.
+
+This module provides an implementation of the SAX 2 interface;
+information about the Java version of the interface can be found at
+http://www.megginson.com/SAX/.  The Python version of the interface is
+documented at <...>.
+
+This package contains the following modules:
+
+handler -- Base classes and constants which define the SAX 2 API for
+           the 'client-side' of SAX for Python.
+
+saxutils -- Implementation of the convenience classes commonly used to
+            work with SAX.
+
+xmlreader -- Base classes and constants which define the SAX 2 API for
+             the parsers used with SAX for Python.
+
+expatreader -- Driver that allows use of the Expat parser with SAX.
+"""
+
+from xmlreader import InputSource
+from handler import ContentHandler, ErrorHandler
+from _exceptions import SAXException, SAXNotRecognizedException, \
+                        SAXParseException, SAXNotSupportedException, \
+                        SAXReaderNotAvailable
+
+
+def parse(source, handler, errorHandler=ErrorHandler()):
+    parser = make_parser()
+    parser.setContentHandler(handler)
+    parser.setErrorHandler(errorHandler)
+    parser.parse(source)
+
+def parseString(string, handler, errorHandler=ErrorHandler()):
+    try:
+        from cStringIO import StringIO
+    except ImportError:
+        from StringIO import StringIO
+
+    if errorHandler is None:
+        errorHandler = ErrorHandler()
+    parser = make_parser()
+    parser.setContentHandler(handler)
+    parser.setErrorHandler(errorHandler)
+
+    inpsrc = InputSource()
+    inpsrc.setByteStream(StringIO(string))
+    parser.parse(inpsrc)
+
+# this is the parser list used by the make_parser function if no
+# alternatives are given as parameters to the function
+
+default_parser_list = ["xml.sax.expatreader"]
+
+# tell modulefinder that importing sax potentially imports expatreader
+_false = 0
+if _false:
+    import xml.sax.expatreader
+
+import os, sys
+if os.environ.has_key("PY_SAX_PARSER"):
+    default_parser_list = os.environ["PY_SAX_PARSER"].split(",")
+del os
+
+_key = "python.xml.sax.parser"
+if sys.platform[:4] == "java" and sys.registry.containsKey(_key):
+    default_parser_list = sys.registry.getProperty(_key).split(",")
+
+
+def make_parser(parser_list = []):
+    """Creates and returns a SAX parser.
+
+    Creates the first parser it is able to instantiate of the ones
+    given in the list created by doing parser_list +
+    default_parser_list.  The lists must contain the names of Python
+    modules containing both a SAX parser and a create_parser function."""
+
+    for parser_name in parser_list + default_parser_list:
+        try:
+            return _create_parser(parser_name)
+        except ImportError,e:
+            import sys
+            if sys.modules.has_key(parser_name):
+                # The parser module was found, but importing it
+                # failed unexpectedly, pass this exception through
+                raise
+        except SAXReaderNotAvailable:
+            # The parser module detected that it won't work properly,
+            # so try the next one
+            pass
+
+    raise SAXReaderNotAvailable("No parsers found", None)
+
+# --- Internal utility methods used by make_parser
+
+if sys.platform[ : 4] == "java":
+    def _create_parser(parser_name):
+        from org.python.core import imp
+        drv_module = imp.importName(parser_name, 0, globals())
+        return drv_module.create_parser()
+
+else:
+    def _create_parser(parser_name):
+        drv_module = __import__(parser_name,{},{},['create_parser'])
+        return drv_module.create_parser()
+
+del sys

Added: vendor/Python/current/Lib/xml/sax/_exceptions.py
===================================================================
--- vendor/Python/current/Lib/xml/sax/_exceptions.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/xml/sax/_exceptions.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,131 @@
+"""Different kinds of SAX Exceptions"""
+import sys
+if sys.platform[:4] == "java":
+    from java.lang import Exception
+del sys
+
+# ===== SAXEXCEPTION =====
+
+class SAXException(Exception):
+    """Encapsulate an XML error or warning. This class can contain
+    basic error or warning information from either the XML parser or
+    the application: you can subclass it to provide additional
+    functionality, or to add localization. Note that although you will
+    receive a SAXException as the argument to the handlers in the
+    ErrorHandler interface, you are not actually required to throw
+    the exception; instead, you can simply read the information in
+    it."""
+
+    def __init__(self, msg, exception=None):
+        """Creates an exception. The message is required, but the exception
+        is optional."""
+        self._msg = msg
+        self._exception = exception
+        Exception.__init__(self, msg)
+
+    def getMessage(self):
+        "Return a message for this exception."
+        return self._msg
+
+    def getException(self):
+        "Return the embedded exception, or None if there was none."
+        return self._exception
+
+    def __str__(self):
+        "Create a string representation of the exception."
+        return self._msg
+
+    def __getitem__(self, ix):
+        """Avoids weird error messages if someone does exception[ix] by
+        mistake, since Exception has __getitem__ defined."""
+        raise AttributeError("__getitem__")
+
+
+# ===== SAXPARSEEXCEPTION =====
+
+class SAXParseException(SAXException):
+    """Encapsulate an XML parse error or warning.
+
+    This exception will include information for locating the error in
+    the original XML document. Note that although the application will
+    receive a SAXParseException as the argument to the handlers in the
+    ErrorHandler interface, the application is not actually required
+    to throw the exception; instead, it can simply read the
+    information in it and take a different action.
+
+    Since this exception is a subclass of SAXException, it inherits
+    the ability to wrap another exception."""
+
+    def __init__(self, msg, exception, locator):
+        "Creates the exception. The exception parameter is allowed to be None."
+        SAXException.__init__(self, msg, exception)
+        self._locator = locator
+
+        # We need to cache this stuff at construction time.
+        # If this exception is thrown, the objects through which we must
+        # traverse to get this information may be deleted by the time
+        # it gets caught.
+        self._systemId = self._locator.getSystemId()
+        self._colnum = self._locator.getColumnNumber()
+        self._linenum = self._locator.getLineNumber()
+
+    def getColumnNumber(self):
+        """The column number of the end of the text where the exception
+        occurred."""
+        return self._colnum
+
+    def getLineNumber(self):
+        "The line number of the end of the text where the exception occurred."
+        return self._linenum
+
+    def getPublicId(self):
+        "Get the public identifier of the entity where the exception occurred."
+        return self._locator.getPublicId()
+
+    def getSystemId(self):
+        "Get the system identifier of the entity where the exception occurred."
+        return self._systemId
+
+    def __str__(self):
+        "Create a string representation of the exception."
+        sysid = self.getSystemId()
+        if sysid is None:
+            sysid = "<unknown>"
+        linenum = self.getLineNumber()
+        if linenum is None:
+            linenum = "?"
+        colnum = self.getColumnNumber()
+        if colnum is None:
+            colnum = "?"
+        return "%s:%s:%s: %s" % (sysid, linenum, colnum, self._msg)
+
+
+# ===== SAXNOTRECOGNIZEDEXCEPTION =====
+
+class SAXNotRecognizedException(SAXException):
+    """Exception class for an unrecognized identifier.
+
+    An XMLReader will raise this exception when it is confronted with an
+    unrecognized feature or property. SAX applications and extensions may
+    use this class for similar purposes."""
+
+
+# ===== SAXNOTSUPPORTEDEXCEPTION =====
+
+class SAXNotSupportedException(SAXException):
+    """Exception class for an unsupported operation.
+
+    An XMLReader will raise this exception when a service it cannot
+    perform is requested (specifically setting a state or value). SAX
+    applications and extensions may use this class for similar
+    purposes."""
+
+# ===== SAXNOTSUPPORTEDEXCEPTION =====
+
+class SAXReaderNotAvailable(SAXNotSupportedException):
+    """Exception class for a missing driver.
+
+    An XMLReader module (driver) should raise this exception when it
+    is first imported, e.g. when a support module cannot be imported.
+    It also may be raised during parsing, e.g. if executing an external
+    program is not permitted."""

Added: vendor/Python/current/Lib/xml/sax/expatreader.py
===================================================================
--- vendor/Python/current/Lib/xml/sax/expatreader.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/xml/sax/expatreader.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,414 @@
+"""
+SAX driver for the pyexpat C module.  This driver works with
+pyexpat.__version__ == '2.22'.
+"""
+
+version = "0.20"
+
+from xml.sax._exceptions import *
+from xml.sax.handler import feature_validation, feature_namespaces
+from xml.sax.handler import feature_namespace_prefixes
+from xml.sax.handler import feature_external_ges, feature_external_pes
+from xml.sax.handler import feature_string_interning
+from xml.sax.handler import property_xml_string, property_interning_dict
+
+# xml.parsers.expat does not raise ImportError in Jython
+import sys
+if sys.platform[:4] == "java":
+    raise SAXReaderNotAvailable("expat not available in Java", None)
+del sys
+
+try:
+    from xml.parsers import expat
+except ImportError:
+    raise SAXReaderNotAvailable("expat not supported", None)
+else:
+    if not hasattr(expat, "ParserCreate"):
+        raise SAXReaderNotAvailable("expat not supported", None)
+from xml.sax import xmlreader, saxutils, handler
+
+AttributesImpl = xmlreader.AttributesImpl
+AttributesNSImpl = xmlreader.AttributesNSImpl
+
+# If we're using a sufficiently recent version of Python, we can use
+# weak references to avoid cycles between the parser and content
+# handler, otherwise we'll just have to pretend.
+try:
+    import _weakref
+except ImportError:
+    def _mkproxy(o):
+        return o
+else:
+    import weakref
+    _mkproxy = weakref.proxy
+    del weakref, _weakref
+
+# --- ExpatLocator
+
+class ExpatLocator(xmlreader.Locator):
+    """Locator for use with the ExpatParser class.
+
+    This uses a weak reference to the parser object to avoid creating
+    a circular reference between the parser and the content handler.
+    """
+    def __init__(self, parser):
+        self._ref = _mkproxy(parser)
+
+    def getColumnNumber(self):
+        parser = self._ref
+        if parser._parser is None:
+            return None
+        return parser._parser.ErrorColumnNumber
+
+    def getLineNumber(self):
+        parser = self._ref
+        if parser._parser is None:
+            return 1
+        return parser._parser.ErrorLineNumber
+
+    def getPublicId(self):
+        parser = self._ref
+        if parser is None:
+            return None
+        return parser._source.getPublicId()
+
+    def getSystemId(self):
+        parser = self._ref
+        if parser is None:
+            return None
+        return parser._source.getSystemId()
+
+
+# --- ExpatParser
+
+class ExpatParser(xmlreader.IncrementalParser, xmlreader.Locator):
+    """SAX driver for the pyexpat C module."""
+
+    def __init__(self, namespaceHandling=0, bufsize=2**16-20):
+        xmlreader.IncrementalParser.__init__(self, bufsize)
+        self._source = xmlreader.InputSource()
+        self._parser = None
+        self._namespaces = namespaceHandling
+        self._lex_handler_prop = None
+        self._parsing = 0
+        self._entity_stack = []
+        self._external_ges = 1
+        self._interning = None
+
+    # XMLReader methods
+
+    def parse(self, source):
+        "Parse an XML document from a URL or an InputSource."
+        source = saxutils.prepare_input_source(source)
+
+        self._source = source
+        self.reset()
+        self._cont_handler.setDocumentLocator(ExpatLocator(self))
+        xmlreader.IncrementalParser.parse(self, source)
+
+    def prepareParser(self, source):
+        if source.getSystemId() != None:
+            self._parser.SetBase(source.getSystemId())
+
+    # Redefined setContentHandler to allow changing handlers during parsing
+
+    def setContentHandler(self, handler):
+        xmlreader.IncrementalParser.setContentHandler(self, handler)
+        if self._parsing:
+            self._reset_cont_handler()
+
+    def getFeature(self, name):
+        if name == feature_namespaces:
+            return self._namespaces
+        elif name == feature_string_interning:
+            return self._interning is not None
+        elif name in (feature_validation, feature_external_pes,
+                      feature_namespace_prefixes):
+            return 0
+        elif name == feature_external_ges:
+            return self._external_ges
+        raise SAXNotRecognizedException("Feature '%s' not recognized" % name)
+
+    def setFeature(self, name, state):
+        if self._parsing:
+            raise SAXNotSupportedException("Cannot set features while parsing")
+
+        if name == feature_namespaces:
+            self._namespaces = state
+        elif name == feature_external_ges:
+            self._external_ges = state
+        elif name == feature_string_interning:
+            if state:
+                if self._interning is None:
+                    self._interning = {}
+            else:
+                self._interning = None
+        elif name == feature_validation:
+            if state:
+                raise SAXNotSupportedException(
+                    "expat does not support validation")
+        elif name == feature_external_pes:
+            if state:
+                raise SAXNotSupportedException(
+                    "expat does not read external parameter entities")
+        elif name == feature_namespace_prefixes:
+            if state:
+                raise SAXNotSupportedException(
+                    "expat does not report namespace prefixes")
+        else:
+            raise SAXNotRecognizedException(
+                "Feature '%s' not recognized" % name)
+
+    def getProperty(self, name):
+        if name == handler.property_lexical_handler:
+            return self._lex_handler_prop
+        elif name == property_interning_dict:
+            return self._interning
+        elif name == property_xml_string:
+            if self._parser:
+                if hasattr(self._parser, "GetInputContext"):
+                    return self._parser.GetInputContext()
+                else:
+                    raise SAXNotRecognizedException(
+                        "This version of expat does not support getting"
+                        " the XML string")
+            else:
+                raise SAXNotSupportedException(
+                    "XML string cannot be returned when not parsing")
+        raise SAXNotRecognizedException("Property '%s' not recognized" % name)
+
+    def setProperty(self, name, value):
+        if name == handler.property_lexical_handler:
+            self._lex_handler_prop = value
+            if self._parsing:
+                self._reset_lex_handler_prop()
+        elif name == property_interning_dict:
+            self._interning = value
+        elif name == property_xml_string:
+            raise SAXNotSupportedException("Property '%s' cannot be set" %
+                                           name)
+        else:
+            raise SAXNotRecognizedException("Property '%s' not recognized" %
+                                            name)
+
+    # IncrementalParser methods
+
+    def feed(self, data, isFinal = 0):
+        if not self._parsing:
+            self.reset()
+            self._parsing = 1
+            self._cont_handler.startDocument()
+
+        try:
+            # The isFinal parameter is internal to the expat reader.
+            # If it is set to true, expat will check validity of the entire
+            # document. When feeding chunks, they are not normally final -
+            # except when invoked from close.
+            self._parser.Parse(data, isFinal)
+        except expat.error, e:
+            exc = SAXParseException(expat.ErrorString(e.code), e, self)
+            # FIXME: when to invoke error()?
+            self._err_handler.fatalError(exc)
+
+    def close(self):
+        if self._entity_stack:
+            # If we are completing an external entity, do nothing here
+            return
+        self.feed("", isFinal = 1)
+        self._cont_handler.endDocument()
+        self._parsing = 0
+        # break cycle created by expat handlers pointing to our methods
+        self._parser = None
+
+    def _reset_cont_handler(self):
+        self._parser.ProcessingInstructionHandler = \
+                                    self._cont_handler.processingInstruction
+        self._parser.CharacterDataHandler = self._cont_handler.characters
+
+    def _reset_lex_handler_prop(self):
+        lex = self._lex_handler_prop
+        parser = self._parser
+        if lex is None:
+            parser.CommentHandler = None
+            parser.StartCdataSectionHandler = None
+            parser.EndCdataSectionHandler = None
+            parser.StartDoctypeDeclHandler = None
+            parser.EndDoctypeDeclHandler = None
+        else:
+            parser.CommentHandler = lex.comment
+            parser.StartCdataSectionHandler = lex.startCDATA
+            parser.EndCdataSectionHandler = lex.endCDATA
+            parser.StartDoctypeDeclHandler = self.start_doctype_decl
+            parser.EndDoctypeDeclHandler = lex.endDTD
+
+    def reset(self):
+        if self._namespaces:
+            self._parser = expat.ParserCreate(self._source.getEncoding(), " ",
+                                              intern=self._interning)
+            self._parser.namespace_prefixes = 1
+            self._parser.StartElementHandler = self.start_element_ns
+            self._parser.EndElementHandler = self.end_element_ns
+        else:
+            self._parser = expat.ParserCreate(self._source.getEncoding(),
+                                              intern = self._interning)
+            self._parser.StartElementHandler = self.start_element
+            self._parser.EndElementHandler = self.end_element
+
+        self._reset_cont_handler()
+        self._parser.UnparsedEntityDeclHandler = self.unparsed_entity_decl
+        self._parser.NotationDeclHandler = self.notation_decl
+        self._parser.StartNamespaceDeclHandler = self.start_namespace_decl
+        self._parser.EndNamespaceDeclHandler = self.end_namespace_decl
+
+        self._decl_handler_prop = None
+        if self._lex_handler_prop:
+            self._reset_lex_handler_prop()
+#         self._parser.DefaultHandler =
+#         self._parser.DefaultHandlerExpand =
+#         self._parser.NotStandaloneHandler =
+        self._parser.ExternalEntityRefHandler = self.external_entity_ref
+        try:
+            self._parser.SkippedEntityHandler = self.skipped_entity_handler
+        except AttributeError:
+            # This pyexpat does not support SkippedEntity
+            pass
+        self._parser.SetParamEntityParsing(
+            expat.XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
+
+        self._parsing = 0
+        self._entity_stack = []
+
+    # Locator methods
+
+    def getColumnNumber(self):
+        if self._parser is None:
+            return None
+        return self._parser.ErrorColumnNumber
+
+    def getLineNumber(self):
+        if self._parser is None:
+            return 1
+        return self._parser.ErrorLineNumber
+
+    def getPublicId(self):
+        return self._source.getPublicId()
+
+    def getSystemId(self):
+        return self._source.getSystemId()
+
+    # event handlers
+    def start_element(self, name, attrs):
+        self._cont_handler.startElement(name, AttributesImpl(attrs))
+
+    def end_element(self, name):
+        self._cont_handler.endElement(name)
+
+    def start_element_ns(self, name, attrs):
+        pair = name.split()
+        if len(pair) == 1:
+            # no namespace
+            pair = (None, name)
+        elif len(pair) == 3:
+            pair = pair[0], pair[1]
+        else:
+            # default namespace
+            pair = tuple(pair)
+
+        newattrs = {}
+        qnames = {}
+        for (aname, value) in attrs.items():
+            parts = aname.split()
+            length = len(parts)
+            if length == 1:
+                # no namespace
+                qname = aname
+                apair = (None, aname)
+            elif length == 3:
+                qname = "%s:%s" % (parts[2], parts[1])
+                apair = parts[0], parts[1]
+            else:
+                # default namespace
+                qname = parts[1]
+                apair = tuple(parts)
+
+            newattrs[apair] = value
+            qnames[apair] = qname
+
+        self._cont_handler.startElementNS(pair, None,
+                                          AttributesNSImpl(newattrs, qnames))
+
+    def end_element_ns(self, name):
+        pair = name.split()
+        if len(pair) == 1:
+            pair = (None, name)
+        elif len(pair) == 3:
+            pair = pair[0], pair[1]
+        else:
+            pair = tuple(pair)
+
+        self._cont_handler.endElementNS(pair, None)
+
+    # this is not used (call directly to ContentHandler)
+    def processing_instruction(self, target, data):
+        self._cont_handler.processingInstruction(target, data)
+
+    # this is not used (call directly to ContentHandler)
+    def character_data(self, data):
+        self._cont_handler.characters(data)
+
+    def start_namespace_decl(self, prefix, uri):
+        self._cont_handler.startPrefixMapping(prefix, uri)
+
+    def end_namespace_decl(self, prefix):
+        self._cont_handler.endPrefixMapping(prefix)
+
+    def start_doctype_decl(self, name, sysid, pubid, has_internal_subset):
+        self._lex_handler_prop.startDTD(name, pubid, sysid)
+
+    def unparsed_entity_decl(self, name, base, sysid, pubid, notation_name):
+        self._dtd_handler.unparsedEntityDecl(name, pubid, sysid, notation_name)
+
+    def notation_decl(self, name, base, sysid, pubid):
+        self._dtd_handler.notationDecl(name, pubid, sysid)
+
+    def external_entity_ref(self, context, base, sysid, pubid):
+        if not self._external_ges:
+            return 1
+
+        source = self._ent_handler.resolveEntity(pubid, sysid)
+        source = saxutils.prepare_input_source(source,
+                                               self._source.getSystemId() or
+                                               "")
+
+        self._entity_stack.append((self._parser, self._source))
+        self._parser = self._parser.ExternalEntityParserCreate(context)
+        self._source = source
+
+        try:
+            xmlreader.IncrementalParser.parse(self, source)
+        except:
+            return 0  # FIXME: save error info here?
+
+        (self._parser, self._source) = self._entity_stack[-1]
+        del self._entity_stack[-1]
+        return 1
+
+    def skipped_entity_handler(self, name, is_pe):
+        if is_pe:
+            # The SAX spec requires to report skipped PEs with a '%'
+            name = '%'+name
+        self._cont_handler.skippedEntity(name)
+
+# ---
+
+def create_parser(*args, **kwargs):
+    return ExpatParser(*args, **kwargs)
+
+# ---
+
+if __name__ == "__main__":
+    import xml.sax
+    p = create_parser()
+    p.setContentHandler(xml.sax.XMLGenerator())
+    p.setErrorHandler(xml.sax.ErrorHandler())
+    p.parse("../../../hamlet.xml")

Added: vendor/Python/current/Lib/xml/sax/handler.py
===================================================================
--- vendor/Python/current/Lib/xml/sax/handler.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/xml/sax/handler.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,342 @@
+"""
+This module contains the core classes of version 2.0 of SAX for Python.
+This file provides only default classes with absolutely minimum
+functionality, from which drivers and applications can be subclassed.
+
+Many of these classes are empty and are included only as documentation
+of the interfaces.
+
+$Id: handler.py 35816 2004-05-06 03:47:48Z fdrake $
+"""
+
+version = '2.0beta'
+
+#============================================================================
+#
+# HANDLER INTERFACES
+#
+#============================================================================
+
+# ===== ERRORHANDLER =====
+
+class ErrorHandler:
+    """Basic interface for SAX error handlers.
+
+    If you create an object that implements this interface, then
+    register the object with your XMLReader, the parser will call the
+    methods in your object to report all warnings and errors. There
+    are three levels of errors available: warnings, (possibly)
+    recoverable errors, and unrecoverable errors. All methods take a
+    SAXParseException as the only parameter."""
+
+    def error(self, exception):
+        "Handle a recoverable error."
+        raise exception
+
+    def fatalError(self, exception):
+        "Handle a non-recoverable error."
+        raise exception
+
+    def warning(self, exception):
+        "Handle a warning."
+        print exception
+
+
+# ===== CONTENTHANDLER =====
+
+class ContentHandler:
+    """Interface for receiving logical document content events.
+
+    This is the main callback interface in SAX, and the one most
+    important to applications. The order of events in this interface
+    mirrors the order of the information in the document."""
+
+    def __init__(self):
+        self._locator = None
+
+    def setDocumentLocator(self, locator):
+        """Called by the parser to give the application a locator for
+        locating the origin of document events.
+
+        SAX parsers are strongly encouraged (though not absolutely
+        required) to supply a locator: if it does so, it must supply
+        the locator to the application by invoking this method before
+        invoking any of the other methods in the DocumentHandler
+        interface.
+
+        The locator allows the application to determine the end
+        position of any document-related event, even if the parser is
+        not reporting an error. Typically, the application will use
+        this information for reporting its own errors (such as
+        character content that does not match an application's
+        business rules). The information returned by the locator is
+        probably not sufficient for use with a search engine.
+
+        Note that the locator will return correct information only
+        during the invocation of the events in this interface. The
+        application should not attempt to use it at any other time."""
+        self._locator = locator
+
+    def startDocument(self):
+        """Receive notification of the beginning of a document.
+
+        The SAX parser will invoke this method only once, before any
+        other methods in this interface or in DTDHandler (except for
+        setDocumentLocator)."""
+
+    def endDocument(self):
+        """Receive notification of the end of a document.
+
+        The SAX parser will invoke this method only once, and it will
+        be the last method invoked during the parse. The parser shall
+        not invoke this method until it has either abandoned parsing
+        (because of an unrecoverable error) or reached the end of
+        input."""
+
+    def startPrefixMapping(self, prefix, uri):
+        """Begin the scope of a prefix-URI Namespace mapping.
+
+        The information from this event is not necessary for normal
+        Namespace processing: the SAX XML reader will automatically
+        replace prefixes for element and attribute names when the
+        http://xml.org/sax/features/namespaces feature is true (the
+        default).
+
+        There are cases, however, when applications need to use
+        prefixes in character data or in attribute values, where they
+        cannot safely be expanded automatically; the
+        start/endPrefixMapping event supplies the information to the
+        application to expand prefixes in those contexts itself, if
+        necessary.
+
+        Note that start/endPrefixMapping events are not guaranteed to
+        be properly nested relative to each-other: all
+        startPrefixMapping events will occur before the corresponding
+        startElement event, and all endPrefixMapping events will occur
+        after the corresponding endElement event, but their order is
+        not guaranteed."""
+
+    def endPrefixMapping(self, prefix):
+        """End the scope of a prefix-URI mapping.
+
+        See startPrefixMapping for details. This event will always
+        occur after the corresponding endElement event, but the order
+        of endPrefixMapping events is not otherwise guaranteed."""
+
+    def startElement(self, name, attrs):
+        """Signals the start of an element in non-namespace mode.
+
+        The name parameter contains the raw XML 1.0 name of the
+        element type as a string and the attrs parameter holds an
+        instance of the Attributes class containing the attributes of
+        the element."""
+
+    def endElement(self, name):
+        """Signals the end of an element in non-namespace mode.
+
+        The name parameter contains the name of the element type, just
+        as with the startElement event."""
+
+    def startElementNS(self, name, qname, attrs):
+        """Signals the start of an element in namespace mode.
+
+        The name parameter contains the name of the element type as a
+        (uri, localname) tuple, the qname parameter the raw XML 1.0
+        name used in the source document, and the attrs parameter
+        holds an instance of the Attributes class containing the
+        attributes of the element.
+
+        The uri part of the name tuple is None for elements which have
+        no namespace."""
+
+    def endElementNS(self, name, qname):
+        """Signals the end of an element in namespace mode.
+
+        The name parameter contains the name of the element type, just
+        as with the startElementNS event."""
+
+    def characters(self, content):
+        """Receive notification of character data.
+
+        The Parser will call this method to report each chunk of
+        character data. SAX parsers may return all contiguous
+        character data in a single chunk, or they may split it into
+        several chunks; however, all of the characters in any single
+        event must come from the same external entity so that the
+        Locator provides useful information."""
+
+    def ignorableWhitespace(self, whitespace):
+        """Receive notification of ignorable whitespace in element content.
+
+        Validating Parsers must use this method to report each chunk
+        of ignorable whitespace (see the W3C XML 1.0 recommendation,
+        section 2.10): non-validating parsers may also use this method
+        if they are capable of parsing and using content models.
+
+        SAX parsers may return all contiguous whitespace in a single
+        chunk, or they may split it into several chunks; however, all
+        of the characters in any single event must come from the same
+        external entity, so that the Locator provides useful
+        information."""
+
+    def processingInstruction(self, target, data):
+        """Receive notification of a processing instruction.
+
+        The Parser will invoke this method once for each processing
+        instruction found: note that processing instructions may occur
+        before or after the main document element.
+
+        A SAX parser should never report an XML declaration (XML 1.0,
+        section 2.8) or a text declaration (XML 1.0, section 4.3.1)
+        using this method."""
+
+    def skippedEntity(self, name):
+        """Receive notification of a skipped entity.
+
+        The Parser will invoke this method once for each entity
+        skipped. Non-validating processors may skip entities if they
+        have not seen the declarations (because, for example, the
+        entity was declared in an external DTD subset). All processors
+        may skip external entities, depending on the values of the
+        http://xml.org/sax/features/external-general-entities and the
+        http://xml.org/sax/features/external-parameter-entities
+        properties."""
+
+
+# ===== DTDHandler =====
+
+class DTDHandler:
+    """Handle DTD events.
+
+    This interface specifies only those DTD events required for basic
+    parsing (unparsed entities and attributes)."""
+
+    def notationDecl(self, name, publicId, systemId):
+        "Handle a notation declaration event."
+
+    def unparsedEntityDecl(self, name, publicId, systemId, ndata):
+        "Handle an unparsed entity declaration event."
+
+
+# ===== ENTITYRESOLVER =====
+
+class EntityResolver:
+    """Basic interface for resolving entities. If you create an object
+    implementing this interface, then register the object with your
+    Parser, the parser will call the method in your object to
+    resolve all external entities. Note that DefaultHandler implements
+    this interface with the default behaviour."""
+
+    def resolveEntity(self, publicId, systemId):
+        """Resolve the system identifier of an entity and return either
+        the system identifier to read from as a string, or an InputSource
+        to read from."""
+        return systemId
+
+
+#============================================================================
+#
+# CORE FEATURES
+#
+#============================================================================
+
+feature_namespaces = "http://xml.org/sax/features/namespaces"
+# true: Perform Namespace processing (default).
+# false: Optionally do not perform Namespace processing
+#        (implies namespace-prefixes).
+# access: (parsing) read-only; (not parsing) read/write
+
+feature_namespace_prefixes = "http://xml.org/sax/features/namespace-prefixes"
+# true: Report the original prefixed names and attributes used for Namespace
+#       declarations.
+# false: Do not report attributes used for Namespace declarations, and
+#        optionally do not report original prefixed names (default).
+# access: (parsing) read-only; (not parsing) read/write
+
+feature_string_interning = "http://xml.org/sax/features/string-interning"
+# true: All element names, prefixes, attribute names, Namespace URIs, and
+#       local names are interned using the built-in intern function.
+# false: Names are not necessarily interned, although they may be (default).
+# access: (parsing) read-only; (not parsing) read/write
+
+feature_validation = "http://xml.org/sax/features/validation"
+# true: Report all validation errors (implies external-general-entities and
+#       external-parameter-entities).
+# false: Do not report validation errors.
+# access: (parsing) read-only; (not parsing) read/write
+
+feature_external_ges = "http://xml.org/sax/features/external-general-entities"
+# true: Include all external general (text) entities.
+# false: Do not include external general entities.
+# access: (parsing) read-only; (not parsing) read/write
+
+feature_external_pes = "http://xml.org/sax/features/external-parameter-entities"
+# true: Include all external parameter entities, including the external
+#       DTD subset.
+# false: Do not include any external parameter entities, even the external
+#        DTD subset.
+# access: (parsing) read-only; (not parsing) read/write
+
+all_features = [feature_namespaces,
+                feature_namespace_prefixes,
+                feature_string_interning,
+                feature_validation,
+                feature_external_ges,
+                feature_external_pes]
+
+
+#============================================================================
+#
+# CORE PROPERTIES
+#
+#============================================================================
+
+property_lexical_handler = "http://xml.org/sax/properties/lexical-handler"
+# data type: xml.sax.sax2lib.LexicalHandler
+# description: An optional extension handler for lexical events like comments.
+# access: read/write
+
+property_declaration_handler = "http://xml.org/sax/properties/declaration-handler"
+# data type: xml.sax.sax2lib.DeclHandler
+# description: An optional extension handler for DTD-related events other
+#              than notations and unparsed entities.
+# access: read/write
+
+property_dom_node = "http://xml.org/sax/properties/dom-node"
+# data type: org.w3c.dom.Node
+# description: When parsing, the current DOM node being visited if this is
+#              a DOM iterator; when not parsing, the root DOM node for
+#              iteration.
+# access: (parsing) read-only; (not parsing) read/write
+
+property_xml_string = "http://xml.org/sax/properties/xml-string"
+# data type: String
+# description: The literal string of characters that was the source for
+#              the current event.
+# access: read-only
+
+property_encoding = "http://www.python.org/sax/properties/encoding"
+# data type: String
+# description: The name of the encoding to assume for input data.
+# access: write: set the encoding, e.g. established by a higher-level
+#                protocol. May change during parsing (e.g. after
+#                processing a META tag)
+#         read:  return the current encoding (possibly established through
+#                auto-detection.
+# initial value: UTF-8
+#
+
+property_interning_dict = "http://www.python.org/sax/properties/interning-dict"
+# data type: Dictionary
+# description: The dictionary used to intern common strings in the document
+# access: write: Request that the parser uses a specific dictionary, to
+#                allow interning across different documents
+#         read:  return the current interning dictionary, or None
+#
+
+all_properties = [property_lexical_handler,
+                  property_dom_node,
+                  property_declaration_handler,
+                  property_xml_string,
+                  property_encoding,
+                  property_interning_dict]

Added: vendor/Python/current/Lib/xml/sax/saxutils.py
===================================================================
--- vendor/Python/current/Lib/xml/sax/saxutils.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/xml/sax/saxutils.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,302 @@
+"""\
+A library of useful helper classes to the SAX classes, for the
+convenience of application and driver writers.
+"""
+
+import os, urlparse, urllib, types
+import handler
+import xmlreader
+
+try:
+    _StringTypes = [types.StringType, types.UnicodeType]
+except AttributeError:
+    _StringTypes = [types.StringType]
+
+# See whether the xmlcharrefreplace error handler is
+# supported
+try:
+    from codecs import xmlcharrefreplace_errors
+    _error_handling = "xmlcharrefreplace"
+    del xmlcharrefreplace_errors
+except ImportError:
+    _error_handling = "strict"
+
+def __dict_replace(s, d):
+    """Replace substrings of a string using a dictionary."""
+    for key, value in d.items():
+        s = s.replace(key, value)
+    return s
+
+def escape(data, entities={}):
+    """Escape &, <, and > in a string of data.
+
+    You can escape other strings of data by passing a dictionary as
+    the optional entities parameter.  The keys and values must all be
+    strings; each key will be replaced with its corresponding value.
+    """
+
+    # must do ampersand first
+    data = data.replace("&", "&amp;")
+    data = data.replace(">", "&gt;")
+    data = data.replace("<", "&lt;")
+    if entities:
+        data = __dict_replace(data, entities)
+    return data
+
+def unescape(data, entities={}):
+    """Unescape &amp;, &lt;, and &gt; in a string of data.
+
+    You can unescape other strings of data by passing a dictionary as
+    the optional entities parameter.  The keys and values must all be
+    strings; each key will be replaced with its corresponding value.
+    """
+    data = data.replace("&lt;", "<")
+    data = data.replace("&gt;", ">")
+    if entities:
+        data = __dict_replace(data, entities)
+    # must do ampersand last
+    return data.replace("&amp;", "&")
+
+def quoteattr(data, entities={}):
+    """Escape and quote an attribute value.
+
+    Escape &, <, and > in a string of data, then quote it for use as
+    an attribute value.  The \" character will be escaped as well, if
+    necessary.
+
+    You can escape other strings of data by passing a dictionary as
+    the optional entities parameter.  The keys and values must all be
+    strings; each key will be replaced with its corresponding value.
+    """
+    entities = entities.copy()
+    entities.update({'\n': '&#10;', '\r': '&#13;', '\t':'&#9;'})
+    data = escape(data, entities)
+    if '"' in data:
+        if "'" in data:
+            data = '"%s"' % data.replace('"', "&quot;")
+        else:
+            data = "'%s'" % data
+    else:
+        data = '"%s"' % data
+    return data
+
+
+class XMLGenerator(handler.ContentHandler):
+
+    def __init__(self, out=None, encoding="iso-8859-1"):
+        if out is None:
+            import sys
+            out = sys.stdout
+        handler.ContentHandler.__init__(self)
+        self._out = out
+        self._ns_contexts = [{}] # contains uri -> prefix dicts
+        self._current_context = self._ns_contexts[-1]
+        self._undeclared_ns_maps = []
+        self._encoding = encoding
+
+    def _write(self, text):
+        if isinstance(text, str):
+            self._out.write(text)
+        else:
+            self._out.write(text.encode(self._encoding, _error_handling))
+
+    def _qname(self, name):
+        """Builds a qualified name from a (ns_url, localname) pair"""
+        if name[0]:
+            # The name is in a non-empty namespace
+            prefix = self._current_context[name[0]]
+            if prefix:
+                # If it is not the default namespace, prepend the prefix
+                return prefix + ":" + name[1]
+        # Return the unqualified name
+        return name[1]
+
+    # ContentHandler methods
+
+    def startDocument(self):
+        self._write('<?xml version="1.0" encoding="%s"?>\n' %
+                        self._encoding)
+
+    def startPrefixMapping(self, prefix, uri):
+        self._ns_contexts.append(self._current_context.copy())
+        self._current_context[uri] = prefix
+        self._undeclared_ns_maps.append((prefix, uri))
+
+    def endPrefixMapping(self, prefix):
+        self._current_context = self._ns_contexts[-1]
+        del self._ns_contexts[-1]
+
+    def startElement(self, name, attrs):
+        self._write('<' + name)
+        for (name, value) in attrs.items():
+            self._write(' %s=%s' % (name, quoteattr(value)))
+        self._write('>')
+
+    def endElement(self, name):
+        self._write('</%s>' % name)
+
+    def startElementNS(self, name, qname, attrs):
+        self._write('<' + self._qname(name))
+
+        for prefix, uri in self._undeclared_ns_maps:
+            if prefix:
+                self._out.write(' xmlns:%s="%s"' % (prefix, uri))
+            else:
+                self._out.write(' xmlns="%s"' % uri)
+        self._undeclared_ns_maps = []
+
+        for (name, value) in attrs.items():
+            self._write(' %s=%s' % (self._qname(name), quoteattr(value)))
+        self._write('>')
+
+    def endElementNS(self, name, qname):
+        self._write('</%s>' % self._qname(name))
+
+    def characters(self, content):
+        self._write(escape(content))
+
+    def ignorableWhitespace(self, content):
+        self._write(content)
+
+    def processingInstruction(self, target, data):
+        self._write('<?%s %s?>' % (target, data))
+
+
+class XMLFilterBase(xmlreader.XMLReader):
+    """This class is designed to sit between an XMLReader and the
+    client application's event handlers.  By default, it does nothing
+    but pass requests up to the reader and events on to the handlers
+    unmodified, but subclasses can override specific methods to modify
+    the event stream or the configuration requests as they pass
+    through."""
+
+    def __init__(self, parent = None):
+        xmlreader.XMLReader.__init__(self)
+        self._parent = parent
+
+    # ErrorHandler methods
+
+    def error(self, exception):
+        self._err_handler.error(exception)
+
+    def fatalError(self, exception):
+        self._err_handler.fatalError(exception)
+
+    def warning(self, exception):
+        self._err_handler.warning(exception)
+
+    # ContentHandler methods
+
+    def setDocumentLocator(self, locator):
+        self._cont_handler.setDocumentLocator(locator)
+
+    def startDocument(self):
+        self._cont_handler.startDocument()
+
+    def endDocument(self):
+        self._cont_handler.endDocument()
+
+    def startPrefixMapping(self, prefix, uri):
+        self._cont_handler.startPrefixMapping(prefix, uri)
+
+    def endPrefixMapping(self, prefix):
+        self._cont_handler.endPrefixMapping(prefix)
+
+    def startElement(self, name, attrs):
+        self._cont_handler.startElement(name, attrs)
+
+    def endElement(self, name):
+        self._cont_handler.endElement(name)
+
+    def startElementNS(self, name, qname, attrs):
+        self._cont_handler.startElementNS(name, qname, attrs)
+
+    def endElementNS(self, name, qname):
+        self._cont_handler.endElementNS(name, qname)
+
+    def characters(self, content):
+        self._cont_handler.characters(content)
+
+    def ignorableWhitespace(self, chars):
+        self._cont_handler.ignorableWhitespace(chars)
+
+    def processingInstruction(self, target, data):
+        self._cont_handler.processingInstruction(target, data)
+
+    def skippedEntity(self, name):
+        self._cont_handler.skippedEntity(name)
+
+    # DTDHandler methods
+
+    def notationDecl(self, name, publicId, systemId):
+        self._dtd_handler.notationDecl(name, publicId, systemId)
+
+    def unparsedEntityDecl(self, name, publicId, systemId, ndata):
+        self._dtd_handler.unparsedEntityDecl(name, publicId, systemId, ndata)
+
+    # EntityResolver methods
+
+    def resolveEntity(self, publicId, systemId):
+        return self._ent_handler.resolveEntity(publicId, systemId)
+
+    # XMLReader methods
+
+    def parse(self, source):
+        self._parent.setContentHandler(self)
+        self._parent.setErrorHandler(self)
+        self._parent.setEntityResolver(self)
+        self._parent.setDTDHandler(self)
+        self._parent.parse(source)
+
+    def setLocale(self, locale):
+        self._parent.setLocale(locale)
+
+    def getFeature(self, name):
+        return self._parent.getFeature(name)
+
+    def setFeature(self, name, state):
+        self._parent.setFeature(name, state)
+
+    def getProperty(self, name):
+        return self._parent.getProperty(name)
+
+    def setProperty(self, name, value):
+        self._parent.setProperty(name, value)
+
+    # XMLFilter methods
+
+    def getParent(self):
+        return self._parent
+
+    def setParent(self, parent):
+        self._parent = parent
+
+# --- Utility functions
+
+def prepare_input_source(source, base = ""):
+    """This function takes an InputSource and an optional base URL and
+    returns a fully resolved InputSource object ready for reading."""
+
+    if type(source) in _StringTypes:
+        source = xmlreader.InputSource(source)
+    elif hasattr(source, "read"):
+        f = source
+        source = xmlreader.InputSource()
+        source.setByteStream(f)
+        if hasattr(f, "name"):
+            source.setSystemId(f.name)
+
+    if source.getByteStream() is None:
+        sysid = source.getSystemId()
+        basehead = os.path.dirname(os.path.normpath(base))
+        sysidfilename = os.path.join(basehead, sysid)
+        if os.path.isfile(sysidfilename):
+            source.setSystemId(sysidfilename)
+            f = open(sysidfilename, "rb")
+        else:
+            source.setSystemId(urlparse.urljoin(base, sysid))
+            f = urllib.urlopen(source.getSystemId())
+
+        source.setByteStream(f)
+
+    return source

Added: vendor/Python/current/Lib/xml/sax/xmlreader.py
===================================================================
--- vendor/Python/current/Lib/xml/sax/xmlreader.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/xml/sax/xmlreader.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,381 @@
+"""An XML Reader is the SAX 2 name for an XML parser. XML Parsers
+should be based on this code. """
+
+import handler
+
+from _exceptions import SAXNotSupportedException, SAXNotRecognizedException
+
+
+# ===== XMLREADER =====
+
+class XMLReader:
+    """Interface for reading an XML document using callbacks.
+
+    XMLReader is the interface that an XML parser's SAX2 driver must
+    implement. This interface allows an application to set and query
+    features and properties in the parser, to register event handlers
+    for document processing, and to initiate a document parse.
+
+    All SAX interfaces are assumed to be synchronous: the parse
+    methods must not return until parsing is complete, and readers
+    must wait for an event-handler callback to return before reporting
+    the next event."""
+
+    def __init__(self):
+        self._cont_handler = handler.ContentHandler()
+        self._dtd_handler = handler.DTDHandler()
+        self._ent_handler = handler.EntityResolver()
+        self._err_handler = handler.ErrorHandler()
+
+    def parse(self, source):
+        "Parse an XML document from a system identifier or an InputSource."
+        raise NotImplementedError("This method must be implemented!")
+
+    def getContentHandler(self):
+        "Returns the current ContentHandler."
+        return self._cont_handler
+
+    def setContentHandler(self, handler):
+        "Registers a new object to receive document content events."
+        self._cont_handler = handler
+
+    def getDTDHandler(self):
+        "Returns the current DTD handler."
+        return self._dtd_handler
+
+    def setDTDHandler(self, handler):
+        "Register an object to receive basic DTD-related events."
+        self._dtd_handler = handler
+
+    def getEntityResolver(self):
+        "Returns the current EntityResolver."
+        return self._ent_handler
+
+    def setEntityResolver(self, resolver):
+        "Register an object to resolve external entities."
+        self._ent_handler = resolver
+
+    def getErrorHandler(self):
+        "Returns the current ErrorHandler."
+        return self._err_handler
+
+    def setErrorHandler(self, handler):
+        "Register an object to receive error-message events."
+        self._err_handler = handler
+
+    def setLocale(self, locale):
+        """Allow an application to set the locale for errors and warnings.
+
+        SAX parsers are not required to provide localization for errors
+        and warnings; if they cannot support the requested locale,
+        however, they must throw a SAX exception. Applications may
+        request a locale change in the middle of a parse."""
+        raise SAXNotSupportedException("Locale support not implemented")
+
+    def getFeature(self, name):
+        "Looks up and returns the state of a SAX2 feature."
+        raise SAXNotRecognizedException("Feature '%s' not recognized" % name)
+
+    def setFeature(self, name, state):
+        "Sets the state of a SAX2 feature."
+        raise SAXNotRecognizedException("Feature '%s' not recognized" % name)
+
+    def getProperty(self, name):
+        "Looks up and returns the value of a SAX2 property."
+        raise SAXNotRecognizedException("Property '%s' not recognized" % name)
+
+    def setProperty(self, name, value):
+        "Sets the value of a SAX2 property."
+        raise SAXNotRecognizedException("Property '%s' not recognized" % name)
+
+class IncrementalParser(XMLReader):
+    """This interface adds three extra methods to the XMLReader
+    interface that allow XML parsers to support incremental
+    parsing. Support for this interface is optional, since not all
+    underlying XML parsers support this functionality.
+
+    When the parser is instantiated it is ready to begin accepting
+    data from the feed method immediately. After parsing has been
+    finished with a call to close the reset method must be called to
+    make the parser ready to accept new data, either from feed or
+    using the parse method.
+
+    Note that these methods must _not_ be called during parsing, that
+    is, after parse has been called and before it returns.
+
+    By default, the class also implements the parse method of the XMLReader
+    interface using the feed, close and reset methods of the
+    IncrementalParser interface as a convenience to SAX 2.0 driver
+    writers."""
+
+    def __init__(self, bufsize=2**16):
+        self._bufsize = bufsize
+        XMLReader.__init__(self)
+
+    def parse(self, source):
+        import saxutils
+        source = saxutils.prepare_input_source(source)
+
+        self.prepareParser(source)
+        file = source.getByteStream()
+        buffer = file.read(self._bufsize)
+        while buffer != "":
+            self.feed(buffer)
+            buffer = file.read(self._bufsize)
+        self.close()
+
+    def feed(self, data):
+        """This method gives the raw XML data in the data parameter to
+        the parser and makes it parse the data, emitting the
+        corresponding events. It is allowed for XML constructs to be
+        split across several calls to feed.
+
+        feed may raise SAXException."""
+        raise NotImplementedError("This method must be implemented!")
+
+    def prepareParser(self, source):
+        """This method is called by the parse implementation to allow
+        the SAX 2.0 driver to prepare itself for parsing."""
+        raise NotImplementedError("prepareParser must be overridden!")
+
+    def close(self):
+        """This method is called when the entire XML document has been
+        passed to the parser through the feed method, to notify the
+        parser that there are no more data. This allows the parser to
+        do the final checks on the document and empty the internal
+        data buffer.
+
+        The parser will not be ready to parse another document until
+        the reset method has been called.
+
+        close may raise SAXException."""
+        raise NotImplementedError("This method must be implemented!")
+
+    def reset(self):
+        """This method is called after close has been called to reset
+        the parser so that it is ready to parse new documents. The
+        results of calling parse or feed after close without calling
+        reset are undefined."""
+        raise NotImplementedError("This method must be implemented!")
+
+# ===== LOCATOR =====
+
+class Locator:
+    """Interface for associating a SAX event with a document
+    location. A locator object will return valid results only during
+    calls to DocumentHandler methods; at any other time, the
+    results are unpredictable."""
+
+    def getColumnNumber(self):
+        "Return the column number where the current event ends."
+        return -1
+
+    def getLineNumber(self):
+        "Return the line number where the current event ends."
+        return -1
+
+    def getPublicId(self):
+        "Return the public identifier for the current event."
+        return None
+
+    def getSystemId(self):
+        "Return the system identifier for the current event."
+        return None
+
+# ===== INPUTSOURCE =====
+
+class InputSource:
+    """Encapsulation of the information needed by the XMLReader to
+    read entities.
+
+    This class may include information about the public identifier,
+    system identifier, byte stream (possibly with character encoding
+    information) and/or the character stream of an entity.
+
+    Applications will create objects of this class for use in the
+    XMLReader.parse method and for returning from
+    EntityResolver.resolveEntity.
+
+    An InputSource belongs to the application, the XMLReader is not
+    allowed to modify InputSource objects passed to it from the
+    application, although it may make copies and modify those."""
+
+    def __init__(self, system_id = None):
+        self.__system_id = system_id
+        self.__public_id = None
+        self.__encoding  = None
+        self.__bytefile  = None
+        self.__charfile  = None
+
+    def setPublicId(self, public_id):
+        "Sets the public identifier of this InputSource."
+        self.__public_id = public_id
+
+    def getPublicId(self):
+        "Returns the public identifier of this InputSource."
+        return self.__public_id
+
+    def setSystemId(self, system_id):
+        "Sets the system identifier of this InputSource."
+        self.__system_id = system_id
+
+    def getSystemId(self):
+        "Returns the system identifier of this InputSource."
+        return self.__system_id
+
+    def setEncoding(self, encoding):
+        """Sets the character encoding of this InputSource.
+
+        The encoding must be a string acceptable for an XML encoding
+        declaration (see section 4.3.3 of the XML recommendation).
+
+        The encoding attribute of the InputSource is ignored if the
+        InputSource also contains a character stream."""
+        self.__encoding = encoding
+
+    def getEncoding(self):
+        "Get the character encoding of this InputSource."
+        return self.__encoding
+
+    def setByteStream(self, bytefile):
+        """Set the byte stream (a Python file-like object which does
+        not perform byte-to-character conversion) for this input
+        source.
+
+        The SAX parser will ignore this if there is also a character
+        stream specified, but it will use a byte stream in preference
+        to opening a URI connection itself.
+
+        If the application knows the character encoding of the byte
+        stream, it should set it with the setEncoding method."""
+        self.__bytefile = bytefile
+
+    def getByteStream(self):
+        """Get the byte stream for this input source.
+
+        The getEncoding method will return the character encoding for
+        this byte stream, or None if unknown."""
+        return self.__bytefile
+
+    def setCharacterStream(self, charfile):
+        """Set the character stream for this input source. (The stream
+        must be a Python 2.0 Unicode-wrapped file-like that performs
+        conversion to Unicode strings.)
+
+        If there is a character stream specified, the SAX parser will
+        ignore any byte stream and will not attempt to open a URI
+        connection to the system identifier."""
+        self.__charfile = charfile
+
+    def getCharacterStream(self):
+        "Get the character stream for this input source."
+        return self.__charfile
+
+# ===== ATTRIBUTESIMPL =====
+
+class AttributesImpl:
+
+    def __init__(self, attrs):
+        """Non-NS-aware implementation.
+
+        attrs should be of the form {name : value}."""
+        self._attrs = attrs
+
+    def getLength(self):
+        return len(self._attrs)
+
+    def getType(self, name):
+        return "CDATA"
+
+    def getValue(self, name):
+        return self._attrs[name]
+
+    def getValueByQName(self, name):
+        return self._attrs[name]
+
+    def getNameByQName(self, name):
+        if not self._attrs.has_key(name):
+            raise KeyError, name
+        return name
+
+    def getQNameByName(self, name):
+        if not self._attrs.has_key(name):
+            raise KeyError, name
+        return name
+
+    def getNames(self):
+        return self._attrs.keys()
+
+    def getQNames(self):
+        return self._attrs.keys()
+
+    def __len__(self):
+        return len(self._attrs)
+
+    def __getitem__(self, name):
+        return self._attrs[name]
+
+    def keys(self):
+        return self._attrs.keys()
+
+    def has_key(self, name):
+        return self._attrs.has_key(name)
+
+    def __contains__(self, name):
+        return self._attrs.has_key(name)
+
+    def get(self, name, alternative=None):
+        return self._attrs.get(name, alternative)
+
+    def copy(self):
+        return self.__class__(self._attrs)
+
+    def items(self):
+        return self._attrs.items()
+
+    def values(self):
+        return self._attrs.values()
+
+# ===== ATTRIBUTESNSIMPL =====
+
+class AttributesNSImpl(AttributesImpl):
+
+    def __init__(self, attrs, qnames):
+        """NS-aware implementation.
+
+        attrs should be of the form {(ns_uri, lname): value, ...}.
+        qnames of the form {(ns_uri, lname): qname, ...}."""
+        self._attrs = attrs
+        self._qnames = qnames
+
+    def getValueByQName(self, name):
+        for (nsname, qname) in self._qnames.items():
+            if qname == name:
+                return self._attrs[nsname]
+
+        raise KeyError, name
+
+    def getNameByQName(self, name):
+        for (nsname, qname) in self._qnames.items():
+            if qname == name:
+                return nsname
+
+        raise KeyError, name
+
+    def getQNameByName(self, name):
+        return self._qnames[name]
+
+    def getQNames(self):
+        return self._qnames.values()
+
+    def copy(self):
+        return self.__class__(self._attrs, self._qnames)
+
+
+def _test():
+    XMLReader()
+    IncrementalParser()
+    Locator()
+
+if __name__ == "__main__":
+    _test()

Added: vendor/Python/current/Lib/xmllib.py
===================================================================
--- vendor/Python/current/Lib/xmllib.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/xmllib.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,929 @@
+"""A parser for XML, using the derived class as static DTD."""
+
+# Author: Sjoerd Mullender.
+
+import re
+import string
+
+import warnings
+warnings.warn("The xmllib module is obsolete.  Use xml.sax instead.", DeprecationWarning)
+del warnings
+
+version = '0.3'
+
+class Error(RuntimeError):
+    pass
+
+# Regular expressions used for parsing
+
+_S = '[ \t\r\n]+'                       # white space
+_opS = '[ \t\r\n]*'                     # optional white space
+_Name = '[a-zA-Z_:][-a-zA-Z0-9._:]*'    # valid XML name
+_QStr = "(?:'[^']*'|\"[^\"]*\")"        # quoted XML string
+illegal = re.compile('[^\t\r\n -\176\240-\377]') # illegal chars in content
+interesting = re.compile('[]&<]')
+
+amp = re.compile('&')
+ref = re.compile('&(' + _Name + '|#[0-9]+|#x[0-9a-fA-F]+)[^-a-zA-Z0-9._:]')
+entityref = re.compile('&(?P<name>' + _Name + ')[^-a-zA-Z0-9._:]')
+charref = re.compile('&#(?P<char>[0-9]+[^0-9]|x[0-9a-fA-F]+[^0-9a-fA-F])')
+space = re.compile(_S + '$')
+newline = re.compile('\n')
+
+attrfind = re.compile(
+    _S + '(?P<name>' + _Name + ')'
+    '(' + _opS + '=' + _opS +
+    '(?P<value>'+_QStr+'|[-a-zA-Z0-9.:+*%?!\(\)_#=~]+))?')
+starttagopen = re.compile('<' + _Name)
+starttagend = re.compile(_opS + '(?P<slash>/?)>')
+starttagmatch = re.compile('<(?P<tagname>'+_Name+')'
+                      '(?P<attrs>(?:'+attrfind.pattern+')*)'+
+                      starttagend.pattern)
+endtagopen = re.compile('</')
+endbracket = re.compile(_opS + '>')
+endbracketfind = re.compile('(?:[^>\'"]|'+_QStr+')*>')
+tagfind = re.compile(_Name)
+cdataopen = re.compile(r'<!\[CDATA\[')
+cdataclose = re.compile(r'\]\]>')
+# this matches one of the following:
+# SYSTEM SystemLiteral
+# PUBLIC PubidLiteral SystemLiteral
+_SystemLiteral = '(?P<%s>'+_QStr+')'
+_PublicLiteral = '(?P<%s>"[-\'\(\)+,./:=?;!*#@$_%% \n\ra-zA-Z0-9]*"|' \
+                        "'[-\(\)+,./:=?;!*#@$_%% \n\ra-zA-Z0-9]*')"
+_ExternalId = '(?:SYSTEM|' \
+                 'PUBLIC'+_S+_PublicLiteral%'pubid'+ \
+              ')'+_S+_SystemLiteral%'syslit'
+doctype = re.compile('<!DOCTYPE'+_S+'(?P<name>'+_Name+')'
+                     '(?:'+_S+_ExternalId+')?'+_opS)
+xmldecl = re.compile('<\?xml'+_S+
+                     'version'+_opS+'='+_opS+'(?P<version>'+_QStr+')'+
+                     '(?:'+_S+'encoding'+_opS+'='+_opS+
+                        "(?P<encoding>'[A-Za-z][-A-Za-z0-9._]*'|"
+                        '"[A-Za-z][-A-Za-z0-9._]*"))?'
+                     '(?:'+_S+'standalone'+_opS+'='+_opS+
+                        '(?P<standalone>\'(?:yes|no)\'|"(?:yes|no)"))?'+
+                     _opS+'\?>')
+procopen = re.compile(r'<\?(?P<proc>' + _Name + ')' + _opS)
+procclose = re.compile(_opS + r'\?>')
+commentopen = re.compile('<!--')
+commentclose = re.compile('-->')
+doubledash = re.compile('--')
+attrtrans = string.maketrans(' \r\n\t', '    ')
+
+# definitions for XML namespaces
+_NCName = '[a-zA-Z_][-a-zA-Z0-9._]*'    # XML Name, minus the ":"
+ncname = re.compile(_NCName + '$')
+qname = re.compile('(?:(?P<prefix>' + _NCName + '):)?' # optional prefix
+                   '(?P<local>' + _NCName + ')$')
+
+xmlns = re.compile('xmlns(?::(?P<ncname>'+_NCName+'))?$')
+
+# XML parser base class -- find tags and call handler functions.
+# Usage: p = XMLParser(); p.feed(data); ...; p.close().
+# The dtd is defined by deriving a class which defines methods with
+# special names to handle tags: start_foo and end_foo to handle <foo>
+# and </foo>, respectively.  The data between tags is passed to the
+# parser by calling self.handle_data() with some data as argument (the
+# data may be split up in arbitrary chunks).
+
+class XMLParser:
+    attributes = {}                     # default, to be overridden
+    elements = {}                       # default, to be overridden
+
+    # parsing options, settable using keyword args in __init__
+    __accept_unquoted_attributes = 0
+    __accept_missing_endtag_name = 0
+    __map_case = 0
+    __accept_utf8 = 0
+    __translate_attribute_references = 1
+
+    # Interface -- initialize and reset this instance
+    def __init__(self, **kw):
+        self.__fixed = 0
+        if 'accept_unquoted_attributes' in kw:
+            self.__accept_unquoted_attributes = kw['accept_unquoted_attributes']
+        if 'accept_missing_endtag_name' in kw:
+            self.__accept_missing_endtag_name = kw['accept_missing_endtag_name']
+        if 'map_case' in kw:
+            self.__map_case = kw['map_case']
+        if 'accept_utf8' in kw:
+            self.__accept_utf8 = kw['accept_utf8']
+        if 'translate_attribute_references' in kw:
+            self.__translate_attribute_references = kw['translate_attribute_references']
+        self.reset()
+
+    def __fixelements(self):
+        self.__fixed = 1
+        self.elements = {}
+        self.__fixdict(self.__dict__)
+        self.__fixclass(self.__class__)
+
+    def __fixclass(self, kl):
+        self.__fixdict(kl.__dict__)
+        for k in kl.__bases__:
+            self.__fixclass(k)
+
+    def __fixdict(self, dict):
+        for key in dict.keys():
+            if key[:6] == 'start_':
+                tag = key[6:]
+                start, end = self.elements.get(tag, (None, None))
+                if start is None:
+                    self.elements[tag] = getattr(self, key), end
+            elif key[:4] == 'end_':
+                tag = key[4:]
+                start, end = self.elements.get(tag, (None, None))
+                if end is None:
+                    self.elements[tag] = start, getattr(self, key)
+
+    # Interface -- reset this instance.  Loses all unprocessed data
+    def reset(self):
+        self.rawdata = ''
+        self.stack = []
+        self.nomoretags = 0
+        self.literal = 0
+        self.lineno = 1
+        self.__at_start = 1
+        self.__seen_doctype = None
+        self.__seen_starttag = 0
+        self.__use_namespaces = 0
+        self.__namespaces = {'xml':None}   # xml is implicitly declared
+        # backward compatibility hack: if elements not overridden,
+        # fill it in ourselves
+        if self.elements is XMLParser.elements:
+            self.__fixelements()
+
+    # For derived classes only -- enter literal mode (CDATA) till EOF
+    def setnomoretags(self):
+        self.nomoretags = self.literal = 1
+
+    # For derived classes only -- enter literal mode (CDATA)
+    def setliteral(self, *args):
+        self.literal = 1
+
+    # Interface -- feed some data to the parser.  Call this as
+    # often as you want, with as little or as much text as you
+    # want (may include '\n').  (This just saves the text, all the
+    # processing is done by goahead().)
+    def feed(self, data):
+        self.rawdata = self.rawdata + data
+        self.goahead(0)
+
+    # Interface -- handle the remaining data
+    def close(self):
+        self.goahead(1)
+        if self.__fixed:
+            self.__fixed = 0
+            # remove self.elements so that we don't leak
+            del self.elements
+
+    # Interface -- translate references
+    def translate_references(self, data, all = 1):
+        if not self.__translate_attribute_references:
+            return data
+        i = 0
+        while 1:
+            res = amp.search(data, i)
+            if res is None:
+                return data
+            s = res.start(0)
+            res = ref.match(data, s)
+            if res is None:
+                self.syntax_error("bogus `&'")
+                i = s+1
+                continue
+            i = res.end(0)
+            str = res.group(1)
+            rescan = 0
+            if str[0] == '#':
+                if str[1] == 'x':
+                    str = chr(int(str[2:], 16))
+                else:
+                    str = chr(int(str[1:]))
+                if data[i - 1] != ';':
+                    self.syntax_error("`;' missing after char reference")
+                    i = i-1
+            elif all:
+                if str in self.entitydefs:
+                    str = self.entitydefs[str]
+                    rescan = 1
+                elif data[i - 1] != ';':
+                    self.syntax_error("bogus `&'")
+                    i = s + 1 # just past the &
+                    continue
+                else:
+                    self.syntax_error("reference to unknown entity `&%s;'" % str)
+                    str = '&' + str + ';'
+            elif data[i - 1] != ';':
+                self.syntax_error("bogus `&'")
+                i = s + 1 # just past the &
+                continue
+
+            # when we get here, str contains the translated text and i points
+            # to the end of the string that is to be replaced
+            data = data[:s] + str + data[i:]
+            if rescan:
+                i = s
+            else:
+                i = s + len(str)
+
+    # Interface - return a dictionary of all namespaces currently valid
+    def getnamespace(self):
+        nsdict = {}
+        for t, d, nst in self.stack:
+            nsdict.update(d)
+        return nsdict
+
+    # Internal -- handle data as far as reasonable.  May leave state
+    # and data to be processed by a subsequent call.  If 'end' is
+    # true, force handling all data as if followed by EOF marker.
+    def goahead(self, end):
+        rawdata = self.rawdata
+        i = 0
+        n = len(rawdata)
+        while i < n:
+            if i > 0:
+                self.__at_start = 0
+            if self.nomoretags:
+                data = rawdata[i:n]
+                self.handle_data(data)
+                self.lineno = self.lineno + data.count('\n')
+                i = n
+                break
+            res = interesting.search(rawdata, i)
+            if res:
+                j = res.start(0)
+            else:
+                j = n
+            if i < j:
+                data = rawdata[i:j]
+                if self.__at_start and space.match(data) is None:
+                    self.syntax_error('illegal data at start of file')
+                self.__at_start = 0
+                if not self.stack and space.match(data) is None:
+                    self.syntax_error('data not in content')
+                if not self.__accept_utf8 and illegal.search(data):
+                    self.syntax_error('illegal character in content')
+                self.handle_data(data)
+                self.lineno = self.lineno + data.count('\n')
+            i = j
+            if i == n: break
+            if rawdata[i] == '<':
+                if starttagopen.match(rawdata, i):
+                    if self.literal:
+                        data = rawdata[i]
+                        self.handle_data(data)
+                        self.lineno = self.lineno + data.count('\n')
+                        i = i+1
+                        continue
+                    k = self.parse_starttag(i)
+                    if k < 0: break
+                    self.__seen_starttag = 1
+                    self.lineno = self.lineno + rawdata[i:k].count('\n')
+                    i = k
+                    continue
+                if endtagopen.match(rawdata, i):
+                    k = self.parse_endtag(i)
+                    if k < 0: break
+                    self.lineno = self.lineno + rawdata[i:k].count('\n')
+                    i =  k
+                    continue
+                if commentopen.match(rawdata, i):
+                    if self.literal:
+                        data = rawdata[i]
+                        self.handle_data(data)
+                        self.lineno = self.lineno + data.count('\n')
+                        i = i+1
+                        continue
+                    k = self.parse_comment(i)
+                    if k < 0: break
+                    self.lineno = self.lineno + rawdata[i:k].count('\n')
+                    i = k
+                    continue
+                if cdataopen.match(rawdata, i):
+                    k = self.parse_cdata(i)
+                    if k < 0: break
+                    self.lineno = self.lineno + rawdata[i:k].count('\n')
+                    i = k
+                    continue
+                res = xmldecl.match(rawdata, i)
+                if res:
+                    if not self.__at_start:
+                        self.syntax_error("<?xml?> declaration not at start of document")
+                    version, encoding, standalone = res.group('version',
+                                                              'encoding',
+                                                              'standalone')
+                    if version[1:-1] != '1.0':
+                        raise Error('only XML version 1.0 supported')
+                    if encoding: encoding = encoding[1:-1]
+                    if standalone: standalone = standalone[1:-1]
+                    self.handle_xml(encoding, standalone)
+                    i = res.end(0)
+                    continue
+                res = procopen.match(rawdata, i)
+                if res:
+                    k = self.parse_proc(i)
+                    if k < 0: break
+                    self.lineno = self.lineno + rawdata[i:k].count('\n')
+                    i = k
+                    continue
+                res = doctype.match(rawdata, i)
+                if res:
+                    if self.literal:
+                        data = rawdata[i]
+                        self.handle_data(data)
+                        self.lineno = self.lineno + data.count('\n')
+                        i = i+1
+                        continue
+                    if self.__seen_doctype:
+                        self.syntax_error('multiple DOCTYPE elements')
+                    if self.__seen_starttag:
+                        self.syntax_error('DOCTYPE not at beginning of document')
+                    k = self.parse_doctype(res)
+                    if k < 0: break
+                    self.__seen_doctype = res.group('name')
+                    if self.__map_case:
+                        self.__seen_doctype = self.__seen_doctype.lower()
+                    self.lineno = self.lineno + rawdata[i:k].count('\n')
+                    i = k
+                    continue
+            elif rawdata[i] == '&':
+                if self.literal:
+                    data = rawdata[i]
+                    self.handle_data(data)
+                    i = i+1
+                    continue
+                res = charref.match(rawdata, i)
+                if res is not None:
+                    i = res.end(0)
+                    if rawdata[i-1] != ';':
+                        self.syntax_error("`;' missing in charref")
+                        i = i-1
+                    if not self.stack:
+                        self.syntax_error('data not in content')
+                    self.handle_charref(res.group('char')[:-1])
+                    self.lineno = self.lineno + res.group(0).count('\n')
+                    continue
+                res = entityref.match(rawdata, i)
+                if res is not None:
+                    i = res.end(0)
+                    if rawdata[i-1] != ';':
+                        self.syntax_error("`;' missing in entityref")
+                        i = i-1
+                    name = res.group('name')
+                    if self.__map_case:
+                        name = name.lower()
+                    if name in self.entitydefs:
+                        self.rawdata = rawdata = rawdata[:res.start(0)] + self.entitydefs[name] + rawdata[i:]
+                        n = len(rawdata)
+                        i = res.start(0)
+                    else:
+                        self.unknown_entityref(name)
+                    self.lineno = self.lineno + res.group(0).count('\n')
+                    continue
+            elif rawdata[i] == ']':
+                if self.literal:
+                    data = rawdata[i]
+                    self.handle_data(data)
+                    i = i+1
+                    continue
+                if n-i < 3:
+                    break
+                if cdataclose.match(rawdata, i):
+                    self.syntax_error("bogus `]]>'")
+                self.handle_data(rawdata[i])
+                i = i+1
+                continue
+            else:
+                raise Error('neither < nor & ??')
+            # We get here only if incomplete matches but
+            # nothing else
+            break
+        # end while
+        if i > 0:
+            self.__at_start = 0
+        if end and i < n:
+            data = rawdata[i]
+            self.syntax_error("bogus `%s'" % data)
+            if not self.__accept_utf8 and illegal.search(data):
+                self.syntax_error('illegal character in content')
+            self.handle_data(data)
+            self.lineno = self.lineno + data.count('\n')
+            self.rawdata = rawdata[i+1:]
+            return self.goahead(end)
+        self.rawdata = rawdata[i:]
+        if end:
+            if not self.__seen_starttag:
+                self.syntax_error('no elements in file')
+            if self.stack:
+                self.syntax_error('missing end tags')
+                while self.stack:
+                    self.finish_endtag(self.stack[-1][0])
+
+    # Internal -- parse comment, return length or -1 if not terminated
+    def parse_comment(self, i):
+        rawdata = self.rawdata
+        if rawdata[i:i+4] != '<!--':
+            raise Error('unexpected call to handle_comment')
+        res = commentclose.search(rawdata, i+4)
+        if res is None:
+            return -1
+        if doubledash.search(rawdata, i+4, res.start(0)):
+            self.syntax_error("`--' inside comment")
+        if rawdata[res.start(0)-1] == '-':
+            self.syntax_error('comment cannot end in three dashes')
+        if not self.__accept_utf8 and \
+           illegal.search(rawdata, i+4, res.start(0)):
+            self.syntax_error('illegal character in comment')
+        self.handle_comment(rawdata[i+4: res.start(0)])
+        return res.end(0)
+
+    # Internal -- handle DOCTYPE tag, return length or -1 if not terminated
+    def parse_doctype(self, res):
+        rawdata = self.rawdata
+        n = len(rawdata)
+        name = res.group('name')
+        if self.__map_case:
+            name = name.lower()
+        pubid, syslit = res.group('pubid', 'syslit')
+        if pubid is not None:
+            pubid = pubid[1:-1]         # remove quotes
+            pubid = ' '.join(pubid.split()) # normalize
+        if syslit is not None: syslit = syslit[1:-1] # remove quotes
+        j = k = res.end(0)
+        if k >= n:
+            return -1
+        if rawdata[k] == '[':
+            level = 0
+            k = k+1
+            dq = sq = 0
+            while k < n:
+                c = rawdata[k]
+                if not sq and c == '"':
+                    dq = not dq
+                elif not dq and c == "'":
+                    sq = not sq
+                elif sq or dq:
+                    pass
+                elif level <= 0 and c == ']':
+                    res = endbracket.match(rawdata, k+1)
+                    if res is None:
+                        return -1
+                    self.handle_doctype(name, pubid, syslit, rawdata[j+1:k])
+                    return res.end(0)
+                elif c == '<':
+                    level = level + 1
+                elif c == '>':
+                    level = level - 1
+                    if level < 0:
+                        self.syntax_error("bogus `>' in DOCTYPE")
+                k = k+1
+        res = endbracketfind.match(rawdata, k)
+        if res is None:
+            return -1
+        if endbracket.match(rawdata, k) is None:
+            self.syntax_error('garbage in DOCTYPE')
+        self.handle_doctype(name, pubid, syslit, None)
+        return res.end(0)
+
+    # Internal -- handle CDATA tag, return length or -1 if not terminated
+    def parse_cdata(self, i):
+        rawdata = self.rawdata
+        if rawdata[i:i+9] != '<![CDATA[':
+            raise Error('unexpected call to parse_cdata')
+        res = cdataclose.search(rawdata, i+9)
+        if res is None:
+            return -1
+        if not self.__accept_utf8 and \
+           illegal.search(rawdata, i+9, res.start(0)):
+            self.syntax_error('illegal character in CDATA')
+        if not self.stack:
+            self.syntax_error('CDATA not in content')
+        self.handle_cdata(rawdata[i+9:res.start(0)])
+        return res.end(0)
+
+    __xml_namespace_attributes = {'ns':None, 'src':None, 'prefix':None}
+    # Internal -- handle a processing instruction tag
+    def parse_proc(self, i):
+        rawdata = self.rawdata
+        end = procclose.search(rawdata, i)
+        if end is None:
+            return -1
+        j = end.start(0)
+        if not self.__accept_utf8 and illegal.search(rawdata, i+2, j):
+            self.syntax_error('illegal character in processing instruction')
+        res = tagfind.match(rawdata, i+2)
+        if res is None:
+            raise Error('unexpected call to parse_proc')
+        k = res.end(0)
+        name = res.group(0)
+        if self.__map_case:
+            name = name.lower()
+        if name == 'xml:namespace':
+            self.syntax_error('old-fashioned namespace declaration')
+            self.__use_namespaces = -1
+            # namespace declaration
+            # this must come after the <?xml?> declaration (if any)
+            # and before the <!DOCTYPE> (if any).
+            if self.__seen_doctype or self.__seen_starttag:
+                self.syntax_error('xml:namespace declaration too late in document')
+            attrdict, namespace, k = self.parse_attributes(name, k, j)
+            if namespace:
+                self.syntax_error('namespace declaration inside namespace declaration')
+            for attrname in attrdict.keys():
+                if not attrname in self.__xml_namespace_attributes:
+                    self.syntax_error("unknown attribute `%s' in xml:namespace tag" % attrname)
+            if not 'ns' in attrdict or not 'prefix' in attrdict:
+                self.syntax_error('xml:namespace without required attributes')
+            prefix = attrdict.get('prefix')
+            if ncname.match(prefix) is None:
+                self.syntax_error('xml:namespace illegal prefix value')
+                return end.end(0)
+            if prefix in self.__namespaces:
+                self.syntax_error('xml:namespace prefix not unique')
+            self.__namespaces[prefix] = attrdict['ns']
+        else:
+            if name.lower() == 'xml':
+                self.syntax_error('illegal processing instruction target name')
+            self.handle_proc(name, rawdata[k:j])
+        return end.end(0)
+
+    # Internal -- parse attributes between i and j
+    def parse_attributes(self, tag, i, j):
+        rawdata = self.rawdata
+        attrdict = {}
+        namespace = {}
+        while i < j:
+            res = attrfind.match(rawdata, i)
+            if res is None:
+                break
+            attrname, attrvalue = res.group('name', 'value')
+            if self.__map_case:
+                attrname = attrname.lower()
+            i = res.end(0)
+            if attrvalue is None:
+                self.syntax_error("no value specified for attribute `%s'" % attrname)
+                attrvalue = attrname
+            elif attrvalue[:1] == "'" == attrvalue[-1:] or \
+                 attrvalue[:1] == '"' == attrvalue[-1:]:
+                attrvalue = attrvalue[1:-1]
+            elif not self.__accept_unquoted_attributes:
+                self.syntax_error("attribute `%s' value not quoted" % attrname)
+            res = xmlns.match(attrname)
+            if res is not None:
+                # namespace declaration
+                ncname = res.group('ncname')
+                namespace[ncname or ''] = attrvalue or None
+                if not self.__use_namespaces:
+                    self.__use_namespaces = len(self.stack)+1
+                continue
+            if '<' in attrvalue:
+                self.syntax_error("`<' illegal in attribute value")
+            if attrname in attrdict:
+                self.syntax_error("attribute `%s' specified twice" % attrname)
+            attrvalue = attrvalue.translate(attrtrans)
+            attrdict[attrname] = self.translate_references(attrvalue)
+        return attrdict, namespace, i
+
+    # Internal -- handle starttag, return length or -1 if not terminated
+    def parse_starttag(self, i):
+        rawdata = self.rawdata
+        # i points to start of tag
+        end = endbracketfind.match(rawdata, i+1)
+        if end is None:
+            return -1
+        tag = starttagmatch.match(rawdata, i)
+        if tag is None or tag.end(0) != end.end(0):
+            self.syntax_error('garbage in starttag')
+            return end.end(0)
+        nstag = tagname = tag.group('tagname')
+        if self.__map_case:
+            nstag = tagname = nstag.lower()
+        if not self.__seen_starttag and self.__seen_doctype and \
+           tagname != self.__seen_doctype:
+            self.syntax_error('starttag does not match DOCTYPE')
+        if self.__seen_starttag and not self.stack:
+            self.syntax_error('multiple elements on top level')
+        k, j = tag.span('attrs')
+        attrdict, nsdict, k = self.parse_attributes(tagname, k, j)
+        self.stack.append((tagname, nsdict, nstag))
+        if self.__use_namespaces:
+            res = qname.match(tagname)
+        else:
+            res = None
+        if res is not None:
+            prefix, nstag = res.group('prefix', 'local')
+            if prefix is None:
+                prefix = ''
+            ns = None
+            for t, d, nst in self.stack:
+                if prefix in d:
+                    ns = d[prefix]
+            if ns is None and prefix != '':
+                ns = self.__namespaces.get(prefix)
+            if ns is not None:
+                nstag = ns + ' ' + nstag
+            elif prefix != '':
+                nstag = prefix + ':' + nstag # undo split
+            self.stack[-1] = tagname, nsdict, nstag
+        # translate namespace of attributes
+        attrnamemap = {} # map from new name to old name (used for error reporting)
+        for key in attrdict.keys():
+            attrnamemap[key] = key
+        if self.__use_namespaces:
+            nattrdict = {}
+            for key, val in attrdict.items():
+                okey = key
+                res = qname.match(key)
+                if res is not None:
+                    aprefix, key = res.group('prefix', 'local')
+                    if self.__map_case:
+                        key = key.lower()
+                    if aprefix is not None:
+                        ans = None
+                        for t, d, nst in self.stack:
+                            if aprefix in d:
+                                ans = d[aprefix]
+                        if ans is None:
+                            ans = self.__namespaces.get(aprefix)
+                        if ans is not None:
+                            key = ans + ' ' + key
+                        else:
+                            key = aprefix + ':' + key
+                nattrdict[key] = val
+                attrnamemap[key] = okey
+            attrdict = nattrdict
+        attributes = self.attributes.get(nstag)
+        if attributes is not None:
+            for key in attrdict.keys():
+                if not key in attributes:
+                    self.syntax_error("unknown attribute `%s' in tag `%s'" % (attrnamemap[key], tagname))
+            for key, val in attributes.items():
+                if val is not None and not key in attrdict:
+                    attrdict[key] = val
+        method = self.elements.get(nstag, (None, None))[0]
+        self.finish_starttag(nstag, attrdict, method)
+        if tag.group('slash') == '/':
+            self.finish_endtag(tagname)
+        return tag.end(0)
+
+    # Internal -- parse endtag
+    def parse_endtag(self, i):
+        rawdata = self.rawdata
+        end = endbracketfind.match(rawdata, i+1)
+        if end is None:
+            return -1
+        res = tagfind.match(rawdata, i+2)
+        if res is None:
+            if self.literal:
+                self.handle_data(rawdata[i])
+                return i+1
+            if not self.__accept_missing_endtag_name:
+                self.syntax_error('no name specified in end tag')
+            tag = self.stack[-1][0]
+            k = i+2
+        else:
+            tag = res.group(0)
+            if self.__map_case:
+                tag = tag.lower()
+            if self.literal:
+                if not self.stack or tag != self.stack[-1][0]:
+                    self.handle_data(rawdata[i])
+                    return i+1
+            k = res.end(0)
+        if endbracket.match(rawdata, k) is None:
+            self.syntax_error('garbage in end tag')
+        self.finish_endtag(tag)
+        return end.end(0)
+
+    # Internal -- finish processing of start tag
+    def finish_starttag(self, tagname, attrdict, method):
+        if method is not None:
+            self.handle_starttag(tagname, method, attrdict)
+        else:
+            self.unknown_starttag(tagname, attrdict)
+
+    # Internal -- finish processing of end tag
+    def finish_endtag(self, tag):
+        self.literal = 0
+        if not tag:
+            self.syntax_error('name-less end tag')
+            found = len(self.stack) - 1
+            if found < 0:
+                self.unknown_endtag(tag)
+                return
+        else:
+            found = -1
+            for i in range(len(self.stack)):
+                if tag == self.stack[i][0]:
+                    found = i
+            if found == -1:
+                self.syntax_error('unopened end tag')
+                return
+        while len(self.stack) > found:
+            if found < len(self.stack) - 1:
+                self.syntax_error('missing close tag for %s' % self.stack[-1][2])
+            nstag = self.stack[-1][2]
+            method = self.elements.get(nstag, (None, None))[1]
+            if method is not None:
+                self.handle_endtag(nstag, method)
+            else:
+                self.unknown_endtag(nstag)
+            if self.__use_namespaces == len(self.stack):
+                self.__use_namespaces = 0
+            del self.stack[-1]
+
+    # Overridable -- handle xml processing instruction
+    def handle_xml(self, encoding, standalone):
+        pass
+
+    # Overridable -- handle DOCTYPE
+    def handle_doctype(self, tag, pubid, syslit, data):
+        pass
+
+    # Overridable -- handle start tag
+    def handle_starttag(self, tag, method, attrs):
+        method(attrs)
+
+    # Overridable -- handle end tag
+    def handle_endtag(self, tag, method):
+        method()
+
+    # Example -- handle character reference, no need to override
+    def handle_charref(self, name):
+        try:
+            if name[0] == 'x':
+                n = int(name[1:], 16)
+            else:
+                n = int(name)
+        except ValueError:
+            self.unknown_charref(name)
+            return
+        if not 0 <= n <= 255:
+            self.unknown_charref(name)
+            return
+        self.handle_data(chr(n))
+
+    # Definition of entities -- derived classes may override
+    entitydefs = {'lt': '&#60;',        # must use charref
+                  'gt': '&#62;',
+                  'amp': '&#38;',       # must use charref
+                  'quot': '&#34;',
+                  'apos': '&#39;',
+                  }
+
+    # Example -- handle data, should be overridden
+    def handle_data(self, data):
+        pass
+
+    # Example -- handle cdata, could be overridden
+    def handle_cdata(self, data):
+        pass
+
+    # Example -- handle comment, could be overridden
+    def handle_comment(self, data):
+        pass
+
+    # Example -- handle processing instructions, could be overridden
+    def handle_proc(self, name, data):
+        pass
+
+    # Example -- handle relatively harmless syntax errors, could be overridden
+    def syntax_error(self, message):
+        raise Error('Syntax error at line %d: %s' % (self.lineno, message))
+
+    # To be overridden -- handlers for unknown objects
+    def unknown_starttag(self, tag, attrs): pass
+    def unknown_endtag(self, tag): pass
+    def unknown_charref(self, ref): pass
+    def unknown_entityref(self, name):
+        self.syntax_error("reference to unknown entity `&%s;'" % name)
+
+
+class TestXMLParser(XMLParser):
+
+    def __init__(self, **kw):
+        self.testdata = ""
+        XMLParser.__init__(self, **kw)
+
+    def handle_xml(self, encoding, standalone):
+        self.flush()
+        print 'xml: encoding =',encoding,'standalone =',standalone
+
+    def handle_doctype(self, tag, pubid, syslit, data):
+        self.flush()
+        print 'DOCTYPE:',tag, repr(data)
+
+    def handle_data(self, data):
+        self.testdata = self.testdata + data
+        if len(repr(self.testdata)) >= 70:
+            self.flush()
+
+    def flush(self):
+        data = self.testdata
+        if data:
+            self.testdata = ""
+            print 'data:', repr(data)
+
+    def handle_cdata(self, data):
+        self.flush()
+        print 'cdata:', repr(data)
+
+    def handle_proc(self, name, data):
+        self.flush()
+        print 'processing:',name,repr(data)
+
+    def handle_comment(self, data):
+        self.flush()
+        r = repr(data)
+        if len(r) > 68:
+            r = r[:32] + '...' + r[-32:]
+        print 'comment:', r
+
+    def syntax_error(self, message):
+        print 'error at line %d:' % self.lineno, message
+
+    def unknown_starttag(self, tag, attrs):
+        self.flush()
+        if not attrs:
+            print 'start tag: <' + tag + '>'
+        else:
+            print 'start tag: <' + tag,
+            for name, value in attrs.items():
+                print name + '=' + '"' + value + '"',
+            print '>'
+
+    def unknown_endtag(self, tag):
+        self.flush()
+        print 'end tag: </' + tag + '>'
+
+    def unknown_entityref(self, ref):
+        self.flush()
+        print '*** unknown entity ref: &' + ref + ';'
+
+    def unknown_charref(self, ref):
+        self.flush()
+        print '*** unknown char ref: &#' + ref + ';'
+
+    def close(self):
+        XMLParser.close(self)
+        self.flush()
+
+def test(args = None):
+    import sys, getopt
+    from time import time
+
+    if not args:
+        args = sys.argv[1:]
+
+    opts, args = getopt.getopt(args, 'st')
+    klass = TestXMLParser
+    do_time = 0
+    for o, a in opts:
+        if o == '-s':
+            klass = XMLParser
+        elif o == '-t':
+            do_time = 1
+
+    if args:
+        file = args[0]
+    else:
+        file = 'test.xml'
+
+    if file == '-':
+        f = sys.stdin
+    else:
+        try:
+            f = open(file, 'r')
+        except IOError, msg:
+            print file, ":", msg
+            sys.exit(1)
+
+    data = f.read()
+    if f is not sys.stdin:
+        f.close()
+
+    x = klass()
+    t0 = time()
+    try:
+        if do_time:
+            x.feed(data)
+            x.close()
+        else:
+            for c in data:
+                x.feed(c)
+            x.close()
+    except Error, msg:
+        t1 = time()
+        print msg
+        if do_time:
+            print 'total time: %g' % (t1-t0)
+        sys.exit(1)
+    t1 = time()
+    if do_time:
+        print 'total time: %g' % (t1-t0)
+
+
+if __name__ == '__main__':
+    test()

Added: vendor/Python/current/Lib/xmlrpclib.py
===================================================================
--- vendor/Python/current/Lib/xmlrpclib.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/xmlrpclib.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1488 @@
+#
+# XML-RPC CLIENT LIBRARY
+# $Id: xmlrpclib.py 41594 2005-12-04 19:11:17Z andrew.kuchling $
+#
+# an XML-RPC client interface for Python.
+#
+# the marshalling and response parser code can also be used to
+# implement XML-RPC servers.
+#
+# Notes:
+# this version is designed to work with Python 2.1 or newer.
+#
+# History:
+# 1999-01-14 fl  Created
+# 1999-01-15 fl  Changed dateTime to use localtime
+# 1999-01-16 fl  Added Binary/base64 element, default to RPC2 service
+# 1999-01-19 fl  Fixed array data element (from Skip Montanaro)
+# 1999-01-21 fl  Fixed dateTime constructor, etc.
+# 1999-02-02 fl  Added fault handling, handle empty sequences, etc.
+# 1999-02-10 fl  Fixed problem with empty responses (from Skip Montanaro)
+# 1999-06-20 fl  Speed improvements, pluggable parsers/transports (0.9.8)
+# 2000-11-28 fl  Changed boolean to check the truth value of its argument
+# 2001-02-24 fl  Added encoding/Unicode/SafeTransport patches
+# 2001-02-26 fl  Added compare support to wrappers (0.9.9/1.0b1)
+# 2001-03-28 fl  Make sure response tuple is a singleton
+# 2001-03-29 fl  Don't require empty params element (from Nicholas Riley)
+# 2001-06-10 fl  Folded in _xmlrpclib accelerator support (1.0b2)
+# 2001-08-20 fl  Base xmlrpclib.Error on built-in Exception (from Paul Prescod)
+# 2001-09-03 fl  Allow Transport subclass to override getparser
+# 2001-09-10 fl  Lazy import of urllib, cgi, xmllib (20x import speedup)
+# 2001-10-01 fl  Remove containers from memo cache when done with them
+# 2001-10-01 fl  Use faster escape method (80% dumps speedup)
+# 2001-10-02 fl  More dumps microtuning
+# 2001-10-04 fl  Make sure import expat gets a parser (from Guido van Rossum)
+# 2001-10-10 sm  Allow long ints to be passed as ints if they don't overflow
+# 2001-10-17 sm  Test for int and long overflow (allows use on 64-bit systems)
+# 2001-11-12 fl  Use repr() to marshal doubles (from Paul Felix)
+# 2002-03-17 fl  Avoid buffered read when possible (from James Rucker)
+# 2002-04-07 fl  Added pythondoc comments
+# 2002-04-16 fl  Added __str__ methods to datetime/binary wrappers
+# 2002-05-15 fl  Added error constants (from Andrew Kuchling)
+# 2002-06-27 fl  Merged with Python CVS version
+# 2002-10-22 fl  Added basic authentication (based on code from Phillip Eby)
+# 2003-01-22 sm  Add support for the bool type
+# 2003-02-27 gvr Remove apply calls
+# 2003-04-24 sm  Use cStringIO if available
+# 2003-04-25 ak  Add support for nil
+# 2003-06-15 gn  Add support for time.struct_time
+# 2003-07-12 gp  Correct marshalling of Faults
+# 2003-10-31 mvl Add multicall support
+# 2004-08-20 mvl Bump minimum supported Python version to 2.1
+#
+# Copyright (c) 1999-2002 by Secret Labs AB.
+# Copyright (c) 1999-2002 by Fredrik Lundh.
+#
+# info at pythonware.com
+# http://www.pythonware.com
+#
+# --------------------------------------------------------------------
+# The XML-RPC client interface is
+#
+# Copyright (c) 1999-2002 by Secret Labs AB
+# Copyright (c) 1999-2002 by Fredrik Lundh
+#
+# By obtaining, using, and/or copying this software and/or its
+# associated documentation, you agree that you have read, understood,
+# and will comply with the following terms and conditions:
+#
+# Permission to use, copy, modify, and distribute this software and
+# its associated documentation for any purpose and without fee is
+# hereby granted, provided that the above copyright notice appears in
+# all copies, and that both that copyright notice and this permission
+# notice appear in supporting documentation, and that the name of
+# Secret Labs AB or the author not be used in advertising or publicity
+# pertaining to distribution of the software without specific, written
+# prior permission.
+#
+# SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
+# TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT-
+# ABILITY AND FITNESS.  IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR
+# BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+# OF THIS SOFTWARE.
+# --------------------------------------------------------------------
+
+#
+# things to look into some day:
+
+# TODO: sort out True/False/boolean issues for Python 2.3
+
+"""
+An XML-RPC client interface for Python.
+
+The marshalling and response parser code can also be used to
+implement XML-RPC servers.
+
+Exported exceptions:
+
+  Error          Base class for client errors
+  ProtocolError  Indicates an HTTP protocol error
+  ResponseError  Indicates a broken response package
+  Fault          Indicates an XML-RPC fault package
+
+Exported classes:
+
+  ServerProxy    Represents a logical connection to an XML-RPC server
+
+  MultiCall      Executor of boxcared xmlrpc requests
+  Boolean        boolean wrapper to generate a "boolean" XML-RPC value
+  DateTime       dateTime wrapper for an ISO 8601 string or time tuple or
+                 localtime integer value to generate a "dateTime.iso8601"
+                 XML-RPC value
+  Binary         binary data wrapper
+
+  SlowParser     Slow but safe standard parser (based on xmllib)
+  Marshaller     Generate an XML-RPC params chunk from a Python data structure
+  Unmarshaller   Unmarshal an XML-RPC response from incoming XML event message
+  Transport      Handles an HTTP transaction to an XML-RPC server
+  SafeTransport  Handles an HTTPS transaction to an XML-RPC server
+
+Exported constants:
+
+  True
+  False
+
+Exported functions:
+
+  boolean        Convert any Python value to an XML-RPC boolean
+  getparser      Create instance of the fastest available parser & attach
+                 to an unmarshalling object
+  dumps          Convert an argument tuple or a Fault instance to an XML-RPC
+                 request (or response, if the methodresponse option is used).
+  loads          Convert an XML-RPC packet to unmarshalled data plus a method
+                 name (None if not present).
+"""
+
+import re, string, time, operator
+
+from types import *
+
+# --------------------------------------------------------------------
+# Internal stuff
+
+try:
+    unicode
+except NameError:
+    unicode = None # unicode support not available
+
+try:
+    import datetime
+except ImportError:
+    datetime = None
+
+try:
+    _bool_is_builtin = False.__class__.__name__ == "bool"
+except NameError:
+    _bool_is_builtin = 0
+
+def _decode(data, encoding, is8bit=re.compile("[\x80-\xff]").search):
+    # decode non-ascii string (if possible)
+    if unicode and encoding and is8bit(data):
+        data = unicode(data, encoding)
+    return data
+
+def escape(s, replace=string.replace):
+    s = replace(s, "&", "&amp;")
+    s = replace(s, "<", "&lt;")
+    return replace(s, ">", "&gt;",)
+
+if unicode:
+    def _stringify(string):
+        # convert to 7-bit ascii if possible
+        try:
+            return string.encode("ascii")
+        except UnicodeError:
+            return string
+else:
+    def _stringify(string):
+        return string
+
+__version__ = "1.0.1"
+
+# xmlrpc integer limits
+MAXINT =  2L**31-1
+MININT = -2L**31
+
+# --------------------------------------------------------------------
+# Error constants (from Dan Libby's specification at
+# http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php)
+
+# Ranges of errors
+PARSE_ERROR       = -32700
+SERVER_ERROR      = -32600
+APPLICATION_ERROR = -32500
+SYSTEM_ERROR      = -32400
+TRANSPORT_ERROR   = -32300
+
+# Specific errors
+NOT_WELLFORMED_ERROR  = -32700
+UNSUPPORTED_ENCODING  = -32701
+INVALID_ENCODING_CHAR = -32702
+INVALID_XMLRPC        = -32600
+METHOD_NOT_FOUND      = -32601
+INVALID_METHOD_PARAMS = -32602
+INTERNAL_ERROR        = -32603
+
+# --------------------------------------------------------------------
+# Exceptions
+
+##
+# Base class for all kinds of client-side errors.
+
+class Error(Exception):
+    """Base class for client errors."""
+    def __str__(self):
+        return repr(self)
+
+##
+# Indicates an HTTP-level protocol error.  This is raised by the HTTP
+# transport layer, if the server returns an error code other than 200
+# (OK).
+#
+# @param url The target URL.
+# @param errcode The HTTP error code.
+# @param errmsg The HTTP error message.
+# @param headers The HTTP header dictionary.
+
+class ProtocolError(Error):
+    """Indicates an HTTP protocol error."""
+    def __init__(self, url, errcode, errmsg, headers):
+        Error.__init__(self)
+        self.url = url
+        self.errcode = errcode
+        self.errmsg = errmsg
+        self.headers = headers
+    def __repr__(self):
+        return (
+            "<ProtocolError for %s: %s %s>" %
+            (self.url, self.errcode, self.errmsg)
+            )
+
+##
+# Indicates a broken XML-RPC response package.  This exception is
+# raised by the unmarshalling layer, if the XML-RPC response is
+# malformed.
+
+class ResponseError(Error):
+    """Indicates a broken response package."""
+    pass
+
+##
+# Indicates an XML-RPC fault response package.  This exception is
+# raised by the unmarshalling layer, if the XML-RPC response contains
+# a fault string.  This exception can also used as a class, to
+# generate a fault XML-RPC message.
+#
+# @param faultCode The XML-RPC fault code.
+# @param faultString The XML-RPC fault string.
+
+class Fault(Error):
+    """Indicates an XML-RPC fault package."""
+    def __init__(self, faultCode, faultString, **extra):
+        Error.__init__(self)
+        self.faultCode = faultCode
+        self.faultString = faultString
+    def __repr__(self):
+        return (
+            "<Fault %s: %s>" %
+            (self.faultCode, repr(self.faultString))
+            )
+
+# --------------------------------------------------------------------
+# Special values
+
+##
+# Wrapper for XML-RPC boolean values.  Use the xmlrpclib.True and
+# xmlrpclib.False constants, or the xmlrpclib.boolean() function, to
+# generate boolean XML-RPC values.
+#
+# @param value A boolean value.  Any true value is interpreted as True,
+#              all other values are interpreted as False.
+
+if _bool_is_builtin:
+    boolean = Boolean = bool
+    # to avoid breaking code which references xmlrpclib.{True,False}
+    True, False = True, False
+else:
+    class Boolean:
+        """Boolean-value wrapper.
+
+        Use True or False to generate a "boolean" XML-RPC value.
+        """
+
+        def __init__(self, value = 0):
+            self.value = operator.truth(value)
+
+        def encode(self, out):
+            out.write("<value><boolean>%d</boolean></value>\n" % self.value)
+
+        def __cmp__(self, other):
+            if isinstance(other, Boolean):
+                other = other.value
+            return cmp(self.value, other)
+
+        def __repr__(self):
+            if self.value:
+                return "<Boolean True at %x>" % id(self)
+            else:
+                return "<Boolean False at %x>" % id(self)
+
+        def __int__(self):
+            return self.value
+
+        def __nonzero__(self):
+            return self.value
+
+    True, False = Boolean(1), Boolean(0)
+
+    ##
+    # Map true or false value to XML-RPC boolean values.
+    #
+    # @def boolean(value)
+    # @param value A boolean value.  Any true value is mapped to True,
+    #              all other values are mapped to False.
+    # @return xmlrpclib.True or xmlrpclib.False.
+    # @see Boolean
+    # @see True
+    # @see False
+
+    def boolean(value, _truefalse=(False, True)):
+        """Convert any Python value to XML-RPC 'boolean'."""
+        return _truefalse[operator.truth(value)]
+
+##
+# Wrapper for XML-RPC DateTime values.  This converts a time value to
+# the format used by XML-RPC.
+# <p>
+# The value can be given as a string in the format
+# "yyyymmddThh:mm:ss", as a 9-item time tuple (as returned by
+# time.localtime()), or an integer value (as returned by time.time()).
+# The wrapper uses time.localtime() to convert an integer to a time
+# tuple.
+#
+# @param value The time, given as an ISO 8601 string, a time
+#              tuple, or a integer time value.
+
+class DateTime:
+    """DateTime wrapper for an ISO 8601 string or time tuple or
+    localtime integer value to generate 'dateTime.iso8601' XML-RPC
+    value.
+    """
+
+    def __init__(self, value=0):
+        if not isinstance(value, StringType):
+            if datetime and isinstance(value, datetime.datetime):
+                self.value = value.strftime("%Y%m%dT%H:%M:%S")
+                return
+            if datetime and isinstance(value, datetime.date):
+                self.value = value.strftime("%Y%m%dT%H:%M:%S")
+                return
+            if datetime and isinstance(value, datetime.time):
+                today = datetime.datetime.now().strftime("%Y%m%d")
+                self.value = value.strftime(today+"T%H:%M:%S")
+                return
+            if not isinstance(value, (TupleType, time.struct_time)):
+                if value == 0:
+                    value = time.time()
+                value = time.localtime(value)
+            value = time.strftime("%Y%m%dT%H:%M:%S", value)
+        self.value = value
+
+    def __cmp__(self, other):
+        if isinstance(other, DateTime):
+            other = other.value
+        return cmp(self.value, other)
+
+    ##
+    # Get date/time value.
+    #
+    # @return Date/time value, as an ISO 8601 string.
+
+    def __str__(self):
+        return self.value
+
+    def __repr__(self):
+        return "<DateTime %s at %x>" % (repr(self.value), id(self))
+
+    def decode(self, data):
+        data = str(data)
+        self.value = string.strip(data)
+
+    def encode(self, out):
+        out.write("<value><dateTime.iso8601>")
+        out.write(self.value)
+        out.write("</dateTime.iso8601></value>\n")
+
+def _datetime(data):
+    # decode xml element contents into a DateTime structure.
+    value = DateTime()
+    value.decode(data)
+    return value
+
+def _datetime_type(data):
+    t = time.strptime(data, "%Y%m%dT%H:%M:%S")
+    return datetime.datetime(*tuple(t)[:6])
+
+##
+# Wrapper for binary data.  This can be used to transport any kind
+# of binary data over XML-RPC, using BASE64 encoding.
+#
+# @param data An 8-bit string containing arbitrary data.
+
+import base64
+try:
+    import cStringIO as StringIO
+except ImportError:
+    import StringIO
+
+class Binary:
+    """Wrapper for binary data."""
+
+    def __init__(self, data=None):
+        self.data = data
+
+    ##
+    # Get buffer contents.
+    #
+    # @return Buffer contents, as an 8-bit string.
+
+    def __str__(self):
+        return self.data or ""
+
+    def __cmp__(self, other):
+        if isinstance(other, Binary):
+            other = other.data
+        return cmp(self.data, other)
+
+    def decode(self, data):
+        self.data = base64.decodestring(data)
+
+    def encode(self, out):
+        out.write("<value><base64>\n")
+        base64.encode(StringIO.StringIO(self.data), out)
+        out.write("</base64></value>\n")
+
+def _binary(data):
+    # decode xml element contents into a Binary structure
+    value = Binary()
+    value.decode(data)
+    return value
+
+WRAPPERS = (DateTime, Binary)
+if not _bool_is_builtin:
+    WRAPPERS = WRAPPERS + (Boolean,)
+
+# --------------------------------------------------------------------
+# XML parsers
+
+try:
+    # optional xmlrpclib accelerator
+    import _xmlrpclib
+    FastParser = _xmlrpclib.Parser
+    FastUnmarshaller = _xmlrpclib.Unmarshaller
+except (AttributeError, ImportError):
+    FastParser = FastUnmarshaller = None
+
+try:
+    import _xmlrpclib
+    FastMarshaller = _xmlrpclib.Marshaller
+except (AttributeError, ImportError):
+    FastMarshaller = None
+
+#
+# the SGMLOP parser is about 15x faster than Python's builtin
+# XML parser.  SGMLOP sources can be downloaded from:
+#
+#     http://www.pythonware.com/products/xml/sgmlop.htm
+#
+
+try:
+    import sgmlop
+    if not hasattr(sgmlop, "XMLParser"):
+        raise ImportError
+except ImportError:
+    SgmlopParser = None # sgmlop accelerator not available
+else:
+    class SgmlopParser:
+        def __init__(self, target):
+
+            # setup callbacks
+            self.finish_starttag = target.start
+            self.finish_endtag = target.end
+            self.handle_data = target.data
+            self.handle_xml = target.xml
+
+            # activate parser
+            self.parser = sgmlop.XMLParser()
+            self.parser.register(self)
+            self.feed = self.parser.feed
+            self.entity = {
+                "amp": "&", "gt": ">", "lt": "<",
+                "apos": "'", "quot": '"'
+                }
+
+        def close(self):
+            try:
+                self.parser.close()
+            finally:
+                self.parser = self.feed = None # nuke circular reference
+
+        def handle_proc(self, tag, attr):
+            m = re.search("encoding\s*=\s*['\"]([^\"']+)[\"']", attr)
+            if m:
+                self.handle_xml(m.group(1), 1)
+
+        def handle_entityref(self, entity):
+            # <string> entity
+            try:
+                self.handle_data(self.entity[entity])
+            except KeyError:
+                self.handle_data("&%s;" % entity)
+
+try:
+    from xml.parsers import expat
+    if not hasattr(expat, "ParserCreate"):
+        raise ImportError
+except ImportError:
+    ExpatParser = None # expat not available
+else:
+    class ExpatParser:
+        # fast expat parser for Python 2.0 and later.  this is about
+        # 50% slower than sgmlop, on roundtrip testing
+        def __init__(self, target):
+            self._parser = parser = expat.ParserCreate(None, None)
+            self._target = target
+            parser.StartElementHandler = target.start
+            parser.EndElementHandler = target.end
+            parser.CharacterDataHandler = target.data
+            encoding = None
+            if not parser.returns_unicode:
+                encoding = "utf-8"
+            target.xml(encoding, None)
+
+        def feed(self, data):
+            self._parser.Parse(data, 0)
+
+        def close(self):
+            self._parser.Parse("", 1) # end of data
+            del self._target, self._parser # get rid of circular references
+
+class SlowParser:
+    """Default XML parser (based on xmllib.XMLParser)."""
+    # this is about 10 times slower than sgmlop, on roundtrip
+    # testing.
+    def __init__(self, target):
+        import xmllib # lazy subclassing (!)
+        if xmllib.XMLParser not in SlowParser.__bases__:
+            SlowParser.__bases__ = (xmllib.XMLParser,)
+        self.handle_xml = target.xml
+        self.unknown_starttag = target.start
+        self.handle_data = target.data
+        self.handle_cdata = target.data
+        self.unknown_endtag = target.end
+        try:
+            xmllib.XMLParser.__init__(self, accept_utf8=1)
+        except TypeError:
+            xmllib.XMLParser.__init__(self) # pre-2.0
+
+# --------------------------------------------------------------------
+# XML-RPC marshalling and unmarshalling code
+
+##
+# XML-RPC marshaller.
+#
+# @param encoding Default encoding for 8-bit strings.  The default
+#     value is None (interpreted as UTF-8).
+# @see dumps
+
+class Marshaller:
+    """Generate an XML-RPC params chunk from a Python data structure.
+
+    Create a Marshaller instance for each set of parameters, and use
+    the "dumps" method to convert your data (represented as a tuple)
+    to an XML-RPC params chunk.  To write a fault response, pass a
+    Fault instance instead.  You may prefer to use the "dumps" module
+    function for this purpose.
+    """
+
+    # by the way, if you don't understand what's going on in here,
+    # that's perfectly ok.
+
+    def __init__(self, encoding=None, allow_none=0):
+        self.memo = {}
+        self.data = None
+        self.encoding = encoding
+        self.allow_none = allow_none
+
+    dispatch = {}
+
+    def dumps(self, values):
+        out = []
+        write = out.append
+        dump = self.__dump
+        if isinstance(values, Fault):
+            # fault instance
+            write("<fault>\n")
+            dump({'faultCode': values.faultCode,
+                  'faultString': values.faultString},
+                 write)
+            write("</fault>\n")
+        else:
+            # parameter block
+            # FIXME: the xml-rpc specification allows us to leave out
+            # the entire <params> block if there are no parameters.
+            # however, changing this may break older code (including
+            # old versions of xmlrpclib.py), so this is better left as
+            # is for now.  See @XMLRPC3 for more information. /F
+            write("<params>\n")
+            for v in values:
+                write("<param>\n")
+                dump(v, write)
+                write("</param>\n")
+            write("</params>\n")
+        result = string.join(out, "")
+        return result
+
+    def __dump(self, value, write):
+        try:
+            f = self.dispatch[type(value)]
+        except KeyError:
+            raise TypeError, "cannot marshal %s objects" % type(value)
+        else:
+            f(self, value, write)
+
+    def dump_nil (self, value, write):
+        if not self.allow_none:
+            raise TypeError, "cannot marshal None unless allow_none is enabled"
+        write("<value><nil/></value>")
+    dispatch[NoneType] = dump_nil
+
+    def dump_int(self, value, write):
+        # in case ints are > 32 bits
+        if value > MAXINT or value < MININT:
+            raise OverflowError, "int exceeds XML-RPC limits"
+        write("<value><int>")
+        write(str(value))
+        write("</int></value>\n")
+    dispatch[IntType] = dump_int
+
+    if _bool_is_builtin:
+        def dump_bool(self, value, write):
+            write("<value><boolean>")
+            write(value and "1" or "0")
+            write("</boolean></value>\n")
+        dispatch[bool] = dump_bool
+
+    def dump_long(self, value, write):
+        if value > MAXINT or value < MININT:
+            raise OverflowError, "long int exceeds XML-RPC limits"
+        write("<value><int>")
+        write(str(int(value)))
+        write("</int></value>\n")
+    dispatch[LongType] = dump_long
+
+    def dump_double(self, value, write):
+        write("<value><double>")
+        write(repr(value))
+        write("</double></value>\n")
+    dispatch[FloatType] = dump_double
+
+    def dump_string(self, value, write, escape=escape):
+        write("<value><string>")
+        write(escape(value))
+        write("</string></value>\n")
+    dispatch[StringType] = dump_string
+
+    if unicode:
+        def dump_unicode(self, value, write, escape=escape):
+            value = value.encode(self.encoding)
+            write("<value><string>")
+            write(escape(value))
+            write("</string></value>\n")
+        dispatch[UnicodeType] = dump_unicode
+
+    def dump_array(self, value, write):
+        i = id(value)
+        if self.memo.has_key(i):
+            raise TypeError, "cannot marshal recursive sequences"
+        self.memo[i] = None
+        dump = self.__dump
+        write("<value><array><data>\n")
+        for v in value:
+            dump(v, write)
+        write("</data></array></value>\n")
+        del self.memo[i]
+    dispatch[TupleType] = dump_array
+    dispatch[ListType] = dump_array
+
+    def dump_struct(self, value, write, escape=escape):
+        i = id(value)
+        if self.memo.has_key(i):
+            raise TypeError, "cannot marshal recursive dictionaries"
+        self.memo[i] = None
+        dump = self.__dump
+        write("<value><struct>\n")
+        for k, v in value.items():
+            write("<member>\n")
+            if type(k) is not StringType:
+                if unicode and type(k) is UnicodeType:
+                    k = k.encode(self.encoding)
+                else:
+                    raise TypeError, "dictionary key must be string"
+            write("<name>%s</name>\n" % escape(k))
+            dump(v, write)
+            write("</member>\n")
+        write("</struct></value>\n")
+        del self.memo[i]
+    dispatch[DictType] = dump_struct
+
+    if datetime:
+        def dump_datetime(self, value, write):
+            write("<value><dateTime.iso8601>")
+            write(value.strftime("%Y%m%dT%H:%M:%S"))
+            write("</dateTime.iso8601></value>\n")
+        dispatch[datetime.datetime] = dump_datetime
+
+        def dump_date(self, value, write):
+            write("<value><dateTime.iso8601>")
+            write(value.strftime("%Y%m%dT00:00:00"))
+            write("</dateTime.iso8601></value>\n")
+        dispatch[datetime.date] = dump_date
+
+        def dump_time(self, value, write):
+            write("<value><dateTime.iso8601>")
+            write(datetime.datetime.now().date().strftime("%Y%m%dT"))
+            write(value.strftime("%H:%M:%S"))
+            write("</dateTime.iso8601></value>\n")
+        dispatch[datetime.time] = dump_time
+
+    def dump_instance(self, value, write):
+        # check for special wrappers
+        if value.__class__ in WRAPPERS:
+            self.write = write
+            value.encode(self)
+            del self.write
+        else:
+            # store instance attributes as a struct (really?)
+            self.dump_struct(value.__dict__, write)
+    dispatch[InstanceType] = dump_instance
+
+##
+# XML-RPC unmarshaller.
+#
+# @see loads
+
+class Unmarshaller:
+    """Unmarshal an XML-RPC response, based on incoming XML event
+    messages (start, data, end).  Call close() to get the resulting
+    data structure.
+
+    Note that this reader is fairly tolerant, and gladly accepts bogus
+    XML-RPC data without complaining (but not bogus XML).
+    """
+
+    # and again, if you don't understand what's going on in here,
+    # that's perfectly ok.
+
+    def __init__(self, use_datetime=0):
+        self._type = None
+        self._stack = []
+        self._marks = []
+        self._data = []
+        self._methodname = None
+        self._encoding = "utf-8"
+        self.append = self._stack.append
+        self._use_datetime = use_datetime
+        if use_datetime and not datetime:
+            raise ValueError, "the datetime module is not available"
+
+    def close(self):
+        # return response tuple and target method
+        if self._type is None or self._marks:
+            raise ResponseError()
+        if self._type == "fault":
+            raise Fault(**self._stack[0])
+        return tuple(self._stack)
+
+    def getmethodname(self):
+        return self._methodname
+
+    #
+    # event handlers
+
+    def xml(self, encoding, standalone):
+        self._encoding = encoding
+        # FIXME: assert standalone == 1 ???
+
+    def start(self, tag, attrs):
+        # prepare to handle this element
+        if tag == "array" or tag == "struct":
+            self._marks.append(len(self._stack))
+        self._data = []
+        self._value = (tag == "value")
+
+    def data(self, text):
+        self._data.append(text)
+
+    def end(self, tag, join=string.join):
+        # call the appropriate end tag handler
+        try:
+            f = self.dispatch[tag]
+        except KeyError:
+            pass # unknown tag ?
+        else:
+            return f(self, join(self._data, ""))
+
+    #
+    # accelerator support
+
+    def end_dispatch(self, tag, data):
+        # dispatch data
+        try:
+            f = self.dispatch[tag]
+        except KeyError:
+            pass # unknown tag ?
+        else:
+            return f(self, data)
+
+    #
+    # element decoders
+
+    dispatch = {}
+
+    def end_nil (self, data):
+        self.append(None)
+        self._value = 0
+    dispatch["nil"] = end_nil
+
+    def end_boolean(self, data):
+        if data == "0":
+            self.append(False)
+        elif data == "1":
+            self.append(True)
+        else:
+            raise TypeError, "bad boolean value"
+        self._value = 0
+    dispatch["boolean"] = end_boolean
+
+    def end_int(self, data):
+        self.append(int(data))
+        self._value = 0
+    dispatch["i4"] = end_int
+    dispatch["int"] = end_int
+
+    def end_double(self, data):
+        self.append(float(data))
+        self._value = 0
+    dispatch["double"] = end_double
+
+    def end_string(self, data):
+        if self._encoding:
+            data = _decode(data, self._encoding)
+        self.append(_stringify(data))
+        self._value = 0
+    dispatch["string"] = end_string
+    dispatch["name"] = end_string # struct keys are always strings
+
+    def end_array(self, data):
+        mark = self._marks.pop()
+        # map arrays to Python lists
+        self._stack[mark:] = [self._stack[mark:]]
+        self._value = 0
+    dispatch["array"] = end_array
+
+    def end_struct(self, data):
+        mark = self._marks.pop()
+        # map structs to Python dictionaries
+        dict = {}
+        items = self._stack[mark:]
+        for i in range(0, len(items), 2):
+            dict[_stringify(items[i])] = items[i+1]
+        self._stack[mark:] = [dict]
+        self._value = 0
+    dispatch["struct"] = end_struct
+
+    def end_base64(self, data):
+        value = Binary()
+        value.decode(data)
+        self.append(value)
+        self._value = 0
+    dispatch["base64"] = end_base64
+
+    def end_dateTime(self, data):
+        value = DateTime()
+        value.decode(data)
+        if self._use_datetime:
+            value = _datetime_type(data)
+        self.append(value)
+    dispatch["dateTime.iso8601"] = end_dateTime
+
+    def end_value(self, data):
+        # if we stumble upon a value element with no internal
+        # elements, treat it as a string element
+        if self._value:
+            self.end_string(data)
+    dispatch["value"] = end_value
+
+    def end_params(self, data):
+        self._type = "params"
+    dispatch["params"] = end_params
+
+    def end_fault(self, data):
+        self._type = "fault"
+    dispatch["fault"] = end_fault
+
+    def end_methodName(self, data):
+        if self._encoding:
+            data = _decode(data, self._encoding)
+        self._methodname = data
+        self._type = "methodName" # no params
+    dispatch["methodName"] = end_methodName
+
+## Multicall support
+#
+
+class _MultiCallMethod:
+    # some lesser magic to store calls made to a MultiCall object
+    # for batch execution
+    def __init__(self, call_list, name):
+        self.__call_list = call_list
+        self.__name = name
+    def __getattr__(self, name):
+        return _MultiCallMethod(self.__call_list, "%s.%s" % (self.__name, name))
+    def __call__(self, *args):
+        self.__call_list.append((self.__name, args))
+
+class MultiCallIterator:
+    """Iterates over the results of a multicall. Exceptions are
+    thrown in response to xmlrpc faults."""
+
+    def __init__(self, results):
+        self.results = results
+
+    def __getitem__(self, i):
+        item = self.results[i]
+        if type(item) == type({}):
+            raise Fault(item['faultCode'], item['faultString'])
+        elif type(item) == type([]):
+            return item[0]
+        else:
+            raise ValueError,\
+                  "unexpected type in multicall result"
+
+class MultiCall:
+    """server -> a object used to boxcar method calls
+
+    server should be a ServerProxy object.
+
+    Methods can be added to the MultiCall using normal
+    method call syntax e.g.:
+
+    multicall = MultiCall(server_proxy)
+    multicall.add(2,3)
+    multicall.get_address("Guido")
+
+    To execute the multicall, call the MultiCall object e.g.:
+
+    add_result, address = multicall()
+    """
+
+    def __init__(self, server):
+        self.__server = server
+        self.__call_list = []
+
+    def __repr__(self):
+        return "<MultiCall at %x>" % id(self)
+
+    __str__ = __repr__
+
+    def __getattr__(self, name):
+        return _MultiCallMethod(self.__call_list, name)
+
+    def __call__(self):
+        marshalled_list = []
+        for name, args in self.__call_list:
+            marshalled_list.append({'methodName' : name, 'params' : args})
+
+        return MultiCallIterator(self.__server.system.multicall(marshalled_list))
+
+# --------------------------------------------------------------------
+# convenience functions
+
+##
+# Create a parser object, and connect it to an unmarshalling instance.
+# This function picks the fastest available XML parser.
+#
+# return A (parser, unmarshaller) tuple.
+
+def getparser(use_datetime=0):
+    """getparser() -> parser, unmarshaller
+
+    Create an instance of the fastest available parser, and attach it
+    to an unmarshalling object.  Return both objects.
+    """
+    if use_datetime and not datetime:
+        raise ValueError, "the datetime module is not available"
+    if FastParser and FastUnmarshaller:
+        if use_datetime:
+            mkdatetime = _datetime_type
+        else:
+            mkdatetime = _datetime
+        target = FastUnmarshaller(True, False, _binary, mkdatetime, Fault)
+        parser = FastParser(target)
+    else:
+        target = Unmarshaller(use_datetime=use_datetime)
+        if FastParser:
+            parser = FastParser(target)
+        elif SgmlopParser:
+            parser = SgmlopParser(target)
+        elif ExpatParser:
+            parser = ExpatParser(target)
+        else:
+            parser = SlowParser(target)
+    return parser, target
+
+##
+# Convert a Python tuple or a Fault instance to an XML-RPC packet.
+#
+# @def dumps(params, **options)
+# @param params A tuple or Fault instance.
+# @keyparam methodname If given, create a methodCall request for
+#     this method name.
+# @keyparam methodresponse If given, create a methodResponse packet.
+#     If used with a tuple, the tuple must be a singleton (that is,
+#     it must contain exactly one element).
+# @keyparam encoding The packet encoding.
+# @return A string containing marshalled data.
+
+def dumps(params, methodname=None, methodresponse=None, encoding=None,
+          allow_none=0):
+    """data [,options] -> marshalled data
+
+    Convert an argument tuple or a Fault instance to an XML-RPC
+    request (or response, if the methodresponse option is used).
+
+    In addition to the data object, the following options can be given
+    as keyword arguments:
+
+        methodname: the method name for a methodCall packet
+
+        methodresponse: true to create a methodResponse packet.
+        If this option is used with a tuple, the tuple must be
+        a singleton (i.e. it can contain only one element).
+
+        encoding: the packet encoding (default is UTF-8)
+
+    All 8-bit strings in the data structure are assumed to use the
+    packet encoding.  Unicode strings are automatically converted,
+    where necessary.
+    """
+
+    assert isinstance(params, TupleType) or isinstance(params, Fault),\
+           "argument must be tuple or Fault instance"
+
+    if isinstance(params, Fault):
+        methodresponse = 1
+    elif methodresponse and isinstance(params, TupleType):
+        assert len(params) == 1, "response tuple must be a singleton"
+
+    if not encoding:
+        encoding = "utf-8"
+
+    if FastMarshaller:
+        m = FastMarshaller(encoding)
+    else:
+        m = Marshaller(encoding, allow_none)
+
+    data = m.dumps(params)
+
+    if encoding != "utf-8":
+        xmlheader = "<?xml version='1.0' encoding='%s'?>\n" % str(encoding)
+    else:
+        xmlheader = "<?xml version='1.0'?>\n" # utf-8 is default
+
+    # standard XML-RPC wrappings
+    if methodname:
+        # a method call
+        if not isinstance(methodname, StringType):
+            methodname = methodname.encode(encoding)
+        data = (
+            xmlheader,
+            "<methodCall>\n"
+            "<methodName>", methodname, "</methodName>\n",
+            data,
+            "</methodCall>\n"
+            )
+    elif methodresponse:
+        # a method response, or a fault structure
+        data = (
+            xmlheader,
+            "<methodResponse>\n",
+            data,
+            "</methodResponse>\n"
+            )
+    else:
+        return data # return as is
+    return string.join(data, "")
+
+##
+# Convert an XML-RPC packet to a Python object.  If the XML-RPC packet
+# represents a fault condition, this function raises a Fault exception.
+#
+# @param data An XML-RPC packet, given as an 8-bit string.
+# @return A tuple containing the unpacked data, and the method name
+#     (None if not present).
+# @see Fault
+
+def loads(data, use_datetime=0):
+    """data -> unmarshalled data, method name
+
+    Convert an XML-RPC packet to unmarshalled data plus a method
+    name (None if not present).
+
+    If the XML-RPC packet represents a fault condition, this function
+    raises a Fault exception.
+    """
+    p, u = getparser(use_datetime=use_datetime)
+    p.feed(data)
+    p.close()
+    return u.close(), u.getmethodname()
+
+
+# --------------------------------------------------------------------
+# request dispatcher
+
+class _Method:
+    # some magic to bind an XML-RPC method to an RPC server.
+    # supports "nested" methods (e.g. examples.getStateName)
+    def __init__(self, send, name):
+        self.__send = send
+        self.__name = name
+    def __getattr__(self, name):
+        return _Method(self.__send, "%s.%s" % (self.__name, name))
+    def __call__(self, *args):
+        return self.__send(self.__name, args)
+
+##
+# Standard transport class for XML-RPC over HTTP.
+# <p>
+# You can create custom transports by subclassing this method, and
+# overriding selected methods.
+
+class Transport:
+    """Handles an HTTP transaction to an XML-RPC server."""
+
+    # client identifier (may be overridden)
+    user_agent = "xmlrpclib.py/%s (by www.pythonware.com)" % __version__
+
+    def __init__(self, use_datetime=0):
+        self._use_datetime = use_datetime
+
+    ##
+    # Send a complete request, and parse the response.
+    #
+    # @param host Target host.
+    # @param handler Target PRC handler.
+    # @param request_body XML-RPC request body.
+    # @param verbose Debugging flag.
+    # @return Parsed response.
+
+    def request(self, host, handler, request_body, verbose=0):
+        # issue XML-RPC request
+
+        h = self.make_connection(host)
+        if verbose:
+            h.set_debuglevel(1)
+
+        self.send_request(h, handler, request_body)
+        self.send_host(h, host)
+        self.send_user_agent(h)
+        self.send_content(h, request_body)
+
+        errcode, errmsg, headers = h.getreply()
+
+        if errcode != 200:
+            raise ProtocolError(
+                host + handler,
+                errcode, errmsg,
+                headers
+                )
+
+        self.verbose = verbose
+
+        try:
+            sock = h._conn.sock
+        except AttributeError:
+            sock = None
+
+        return self._parse_response(h.getfile(), sock)
+
+    ##
+    # Create parser.
+    #
+    # @return A 2-tuple containing a parser and a unmarshaller.
+
+    def getparser(self):
+        # get parser and unmarshaller
+        return getparser(use_datetime=self._use_datetime)
+
+    ##
+    # Get authorization info from host parameter
+    # Host may be a string, or a (host, x509-dict) tuple; if a string,
+    # it is checked for a "user:pw at host" format, and a "Basic
+    # Authentication" header is added if appropriate.
+    #
+    # @param host Host descriptor (URL or (URL, x509 info) tuple).
+    # @return A 3-tuple containing (actual host, extra headers,
+    #     x509 info).  The header and x509 fields may be None.
+
+    def get_host_info(self, host):
+
+        x509 = {}
+        if isinstance(host, TupleType):
+            host, x509 = host
+
+        import urllib
+        auth, host = urllib.splituser(host)
+
+        if auth:
+            import base64
+            auth = base64.encodestring(urllib.unquote(auth))
+            auth = string.join(string.split(auth), "") # get rid of whitespace
+            extra_headers = [
+                ("Authorization", "Basic " + auth)
+                ]
+        else:
+            extra_headers = None
+
+        return host, extra_headers, x509
+
+    ##
+    # Connect to server.
+    #
+    # @param host Target host.
+    # @return A connection handle.
+
+    def make_connection(self, host):
+        # create a HTTP connection object from a host descriptor
+        import httplib
+        host, extra_headers, x509 = self.get_host_info(host)
+        return httplib.HTTP(host)
+
+    ##
+    # Send request header.
+    #
+    # @param connection Connection handle.
+    # @param handler Target RPC handler.
+    # @param request_body XML-RPC body.
+
+    def send_request(self, connection, handler, request_body):
+        connection.putrequest("POST", handler)
+
+    ##
+    # Send host name.
+    #
+    # @param connection Connection handle.
+    # @param host Host name.
+
+    def send_host(self, connection, host):
+        host, extra_headers, x509 = self.get_host_info(host)
+        connection.putheader("Host", host)
+        if extra_headers:
+            if isinstance(extra_headers, DictType):
+                extra_headers = extra_headers.items()
+            for key, value in extra_headers:
+                connection.putheader(key, value)
+
+    ##
+    # Send user-agent identifier.
+    #
+    # @param connection Connection handle.
+
+    def send_user_agent(self, connection):
+        connection.putheader("User-Agent", self.user_agent)
+
+    ##
+    # Send request body.
+    #
+    # @param connection Connection handle.
+    # @param request_body XML-RPC request body.
+
+    def send_content(self, connection, request_body):
+        connection.putheader("Content-Type", "text/xml")
+        connection.putheader("Content-Length", str(len(request_body)))
+        connection.endheaders()
+        if request_body:
+            connection.send(request_body)
+
+    ##
+    # Parse response.
+    #
+    # @param file Stream.
+    # @return Response tuple and target method.
+
+    def parse_response(self, file):
+        # compatibility interface
+        return self._parse_response(file, None)
+
+    ##
+    # Parse response (alternate interface).  This is similar to the
+    # parse_response method, but also provides direct access to the
+    # underlying socket object (where available).
+    #
+    # @param file Stream.
+    # @param sock Socket handle (or None, if the socket object
+    #    could not be accessed).
+    # @return Response tuple and target method.
+
+    def _parse_response(self, file, sock):
+        # read response from input file/socket, and parse it
+
+        p, u = self.getparser()
+
+        while 1:
+            if sock:
+                response = sock.recv(1024)
+            else:
+                response = file.read(1024)
+            if not response:
+                break
+            if self.verbose:
+                print "body:", repr(response)
+            p.feed(response)
+
+        file.close()
+        p.close()
+
+        return u.close()
+
+##
+# Standard transport class for XML-RPC over HTTPS.
+
+class SafeTransport(Transport):
+    """Handles an HTTPS transaction to an XML-RPC server."""
+
+    # FIXME: mostly untested
+
+    def make_connection(self, host):
+        # create a HTTPS connection object from a host descriptor
+        # host may be a string, or a (host, x509-dict) tuple
+        import httplib
+        host, extra_headers, x509 = self.get_host_info(host)
+        try:
+            HTTPS = httplib.HTTPS
+        except AttributeError:
+            raise NotImplementedError(
+                "your version of httplib doesn't support HTTPS"
+                )
+        else:
+            return HTTPS(host, None, **(x509 or {}))
+
+##
+# Standard server proxy.  This class establishes a virtual connection
+# to an XML-RPC server.
+# <p>
+# This class is available as ServerProxy and Server.  New code should
+# use ServerProxy, to avoid confusion.
+#
+# @def ServerProxy(uri, **options)
+# @param uri The connection point on the server.
+# @keyparam transport A transport factory, compatible with the
+#    standard transport class.
+# @keyparam encoding The default encoding used for 8-bit strings
+#    (default is UTF-8).
+# @keyparam verbose Use a true value to enable debugging output.
+#    (printed to standard output).
+# @see Transport
+
+class ServerProxy:
+    """uri [,options] -> a logical connection to an XML-RPC server
+
+    uri is the connection point on the server, given as
+    scheme://host/target.
+
+    The standard implementation always supports the "http" scheme.  If
+    SSL socket support is available (Python 2.0), it also supports
+    "https".
+
+    If the target part and the slash preceding it are both omitted,
+    "/RPC2" is assumed.
+
+    The following options can be given as keyword arguments:
+
+        transport: a transport factory
+        encoding: the request encoding (default is UTF-8)
+
+    All 8-bit strings passed to the server proxy are assumed to use
+    the given encoding.
+    """
+
+    def __init__(self, uri, transport=None, encoding=None, verbose=0,
+                 allow_none=0, use_datetime=0):
+        # establish a "logical" server connection
+
+        # get the url
+        import urllib
+        type, uri = urllib.splittype(uri)
+        if type not in ("http", "https"):
+            raise IOError, "unsupported XML-RPC protocol"
+        self.__host, self.__handler = urllib.splithost(uri)
+        if not self.__handler:
+            self.__handler = "/RPC2"
+
+        if transport is None:
+            if type == "https":
+                transport = SafeTransport(use_datetime=use_datetime)
+            else:
+                transport = Transport(use_datetime=use_datetime)
+        self.__transport = transport
+
+        self.__encoding = encoding
+        self.__verbose = verbose
+        self.__allow_none = allow_none
+
+    def __request(self, methodname, params):
+        # call a method on the remote server
+
+        request = dumps(params, methodname, encoding=self.__encoding,
+                        allow_none=self.__allow_none)
+
+        response = self.__transport.request(
+            self.__host,
+            self.__handler,
+            request,
+            verbose=self.__verbose
+            )
+
+        if len(response) == 1:
+            response = response[0]
+
+        return response
+
+    def __repr__(self):
+        return (
+            "<ServerProxy for %s%s>" %
+            (self.__host, self.__handler)
+            )
+
+    __str__ = __repr__
+
+    def __getattr__(self, name):
+        # magic method dispatcher
+        return _Method(self.__request, name)
+
+    # note: to call a remote object with an non-standard name, use
+    # result getattr(server, "strange-python-name")(args)
+
+# compatibility
+
+Server = ServerProxy
+
+# --------------------------------------------------------------------
+# test code
+
+if __name__ == "__main__":
+
+    # simple test program (from the XML-RPC specification)
+
+    # server = ServerProxy("http://localhost:8000") # local server
+    server = ServerProxy("http://time.xmlrpc.com/RPC2")
+
+    print server
+
+    try:
+        print server.currentTime.getCurrentTime()
+    except Error, v:
+        print "ERROR", v
+
+    multi = MultiCall(server)
+    multi.currentTime.getCurrentTime()
+    multi.currentTime.getCurrentTime()
+    try:
+        for response in multi():
+            print response
+    except Error, v:
+        print "ERROR", v

Added: vendor/Python/current/Lib/zipfile.py
===================================================================
--- vendor/Python/current/Lib/zipfile.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Lib/zipfile.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,900 @@
+"""
+Read and write ZIP files.
+"""
+import struct, os, time, sys
+import binascii, cStringIO
+
+try:
+    import zlib # We may need its compression method
+except ImportError:
+    zlib = None
+
+__all__ = ["BadZipfile", "error", "ZIP_STORED", "ZIP_DEFLATED", "is_zipfile",
+           "ZipInfo", "ZipFile", "PyZipFile", "LargeZipFile" ]
+
+class BadZipfile(Exception):
+    pass
+
+
+class LargeZipFile(Exception):
+    """
+    Raised when writing a zipfile, the zipfile requires ZIP64 extensions
+    and those extensions are disabled.
+    """
+
+error = BadZipfile      # The exception raised by this module
+
+ZIP64_LIMIT= (1 << 31) - 1
+
+# constants for Zip file compression methods
+ZIP_STORED = 0
+ZIP_DEFLATED = 8
+# Other ZIP compression methods not supported
+
+# Here are some struct module formats for reading headers
+structEndArchive = "<4s4H2lH"     # 9 items, end of archive, 22 bytes
+stringEndArchive = "PK\005\006"   # magic number for end of archive record
+structCentralDir = "<4s4B4HlLL5HLl"# 19 items, central directory, 46 bytes
+stringCentralDir = "PK\001\002"   # magic number for central directory
+structFileHeader = "<4s2B4HlLL2H"  # 12 items, file header record, 30 bytes
+stringFileHeader = "PK\003\004"   # magic number for file header
+structEndArchive64Locator = "<4slql" # 4 items, locate Zip64 header, 20 bytes
+stringEndArchive64Locator = "PK\x06\x07" # magic token for locator header
+structEndArchive64 = "<4sqhhllqqqq" # 10 items, end of archive (Zip64), 56 bytes
+stringEndArchive64 = "PK\x06\x06" # magic token for Zip64 header
+
+
+# indexes of entries in the central directory structure
+_CD_SIGNATURE = 0
+_CD_CREATE_VERSION = 1
+_CD_CREATE_SYSTEM = 2
+_CD_EXTRACT_VERSION = 3
+_CD_EXTRACT_SYSTEM = 4                  # is this meaningful?
+_CD_FLAG_BITS = 5
+_CD_COMPRESS_TYPE = 6
+_CD_TIME = 7
+_CD_DATE = 8
+_CD_CRC = 9
+_CD_COMPRESSED_SIZE = 10
+_CD_UNCOMPRESSED_SIZE = 11
+_CD_FILENAME_LENGTH = 12
+_CD_EXTRA_FIELD_LENGTH = 13
+_CD_COMMENT_LENGTH = 14
+_CD_DISK_NUMBER_START = 15
+_CD_INTERNAL_FILE_ATTRIBUTES = 16
+_CD_EXTERNAL_FILE_ATTRIBUTES = 17
+_CD_LOCAL_HEADER_OFFSET = 18
+
+# indexes of entries in the local file header structure
+_FH_SIGNATURE = 0
+_FH_EXTRACT_VERSION = 1
+_FH_EXTRACT_SYSTEM = 2                  # is this meaningful?
+_FH_GENERAL_PURPOSE_FLAG_BITS = 3
+_FH_COMPRESSION_METHOD = 4
+_FH_LAST_MOD_TIME = 5
+_FH_LAST_MOD_DATE = 6
+_FH_CRC = 7
+_FH_COMPRESSED_SIZE = 8
+_FH_UNCOMPRESSED_SIZE = 9
+_FH_FILENAME_LENGTH = 10
+_FH_EXTRA_FIELD_LENGTH = 11
+
+def is_zipfile(filename):
+    """Quickly see if file is a ZIP file by checking the magic number."""
+    try:
+        fpin = open(filename, "rb")
+        endrec = _EndRecData(fpin)
+        fpin.close()
+        if endrec:
+            return True                 # file has correct magic number
+    except IOError:
+        pass
+    return False
+
+def _EndRecData64(fpin, offset, endrec):
+    """
+    Read the ZIP64 end-of-archive records and use that to update endrec
+    """
+    locatorSize = struct.calcsize(structEndArchive64Locator)
+    fpin.seek(offset - locatorSize, 2)
+    data = fpin.read(locatorSize)
+    sig, diskno, reloff, disks = struct.unpack(structEndArchive64Locator, data)
+    if sig != stringEndArchive64Locator:
+        return endrec
+
+    if diskno != 0 or disks != 1:
+        raise BadZipfile("zipfiles that span multiple disks are not supported")
+
+    # Assume no 'zip64 extensible data'
+    endArchiveSize = struct.calcsize(structEndArchive64)
+    fpin.seek(offset - locatorSize - endArchiveSize, 2)
+    data = fpin.read(endArchiveSize)
+    sig, sz, create_version, read_version, disk_num, disk_dir, \
+            dircount, dircount2, dirsize, diroffset = \
+            struct.unpack(structEndArchive64, data)
+    if sig != stringEndArchive64:
+        return endrec
+
+    # Update the original endrec using data from the ZIP64 record
+    endrec[1] = disk_num
+    endrec[2] = disk_dir
+    endrec[3] = dircount
+    endrec[4] = dircount2
+    endrec[5] = dirsize
+    endrec[6] = diroffset
+    return endrec
+
+
+def _EndRecData(fpin):
+    """Return data from the "End of Central Directory" record, or None.
+
+    The data is a list of the nine items in the ZIP "End of central dir"
+    record followed by a tenth item, the file seek offset of this record."""
+    fpin.seek(-22, 2)               # Assume no archive comment.
+    filesize = fpin.tell() + 22     # Get file size
+    data = fpin.read()
+    if data[0:4] == stringEndArchive and data[-2:] == "\000\000":
+        endrec = struct.unpack(structEndArchive, data)
+        endrec = list(endrec)
+        endrec.append("")               # Append the archive comment
+        endrec.append(filesize - 22)    # Append the record start offset
+        if endrec[-4] == -1 or endrec[-4] == 0xffffffff:
+            return _EndRecData64(fpin, -22, endrec)
+        return endrec
+    # Search the last END_BLOCK bytes of the file for the record signature.
+    # The comment is appended to the ZIP file and has a 16 bit length.
+    # So the comment may be up to 64K long.  We limit the search for the
+    # signature to a few Kbytes at the end of the file for efficiency.
+    # also, the signature must not appear in the comment.
+    END_BLOCK = min(filesize, 1024 * 4)
+    fpin.seek(filesize - END_BLOCK, 0)
+    data = fpin.read()
+    start = data.rfind(stringEndArchive)
+    if start >= 0:     # Correct signature string was found
+        endrec = struct.unpack(structEndArchive, data[start:start+22])
+        endrec = list(endrec)
+        comment = data[start+22:]
+        if endrec[7] == len(comment):     # Comment length checks out
+            # Append the archive comment and start offset
+            endrec.append(comment)
+            endrec.append(filesize - END_BLOCK + start)
+            if endrec[-4] == -1 or endrec[-4] == 0xffffffff:
+                return _EndRecData64(fpin, - END_BLOCK + start, endrec)
+            return endrec
+    return      # Error, return None
+
+
+class ZipInfo (object):
+    """Class with attributes describing each file in the ZIP archive."""
+
+    __slots__ = (
+            'orig_filename',
+            'filename',
+            'date_time',
+            'compress_type',
+            'comment',
+            'extra',
+            'create_system',
+            'create_version',
+            'extract_version',
+            'reserved',
+            'flag_bits',
+            'volume',
+            'internal_attr',
+            'external_attr',
+            'header_offset',
+            'CRC',
+            'compress_size',
+            'file_size',
+        )
+
+    def __init__(self, filename="NoName", date_time=(1980,1,1,0,0,0)):
+        self.orig_filename = filename   # Original file name in archive
+
+        # Terminate the file name at the first null byte.  Null bytes in file
+        # names are used as tricks by viruses in archives.
+        null_byte = filename.find(chr(0))
+        if null_byte >= 0:
+            filename = filename[0:null_byte]
+        # This is used to ensure paths in generated ZIP files always use
+        # forward slashes as the directory separator, as required by the
+        # ZIP format specification.
+        if os.sep != "/" and os.sep in filename:
+            filename = filename.replace(os.sep, "/")
+
+        self.filename = filename        # Normalized file name
+        self.date_time = date_time      # year, month, day, hour, min, sec
+        # Standard values:
+        self.compress_type = ZIP_STORED # Type of compression for the file
+        self.comment = ""               # Comment for each file
+        self.extra = ""                 # ZIP extra data
+        if sys.platform == 'win32':
+            self.create_system = 0          # System which created ZIP archive
+        else:
+            # Assume everything else is unix-y
+            self.create_system = 3          # System which created ZIP archive
+        self.create_version = 20        # Version which created ZIP archive
+        self.extract_version = 20       # Version needed to extract archive
+        self.reserved = 0               # Must be zero
+        self.flag_bits = 0              # ZIP flag bits
+        self.volume = 0                 # Volume number of file header
+        self.internal_attr = 0          # Internal attributes
+        self.external_attr = 0          # External file attributes
+        # Other attributes are set by class ZipFile:
+        # header_offset         Byte offset to the file header
+        # CRC                   CRC-32 of the uncompressed file
+        # compress_size         Size of the compressed file
+        # file_size             Size of the uncompressed file
+
+    def FileHeader(self):
+        """Return the per-file header as a string."""
+        dt = self.date_time
+        dosdate = (dt[0] - 1980) << 9 | dt[1] << 5 | dt[2]
+        dostime = dt[3] << 11 | dt[4] << 5 | (dt[5] // 2)
+        if self.flag_bits & 0x08:
+            # Set these to zero because we write them after the file data
+            CRC = compress_size = file_size = 0
+        else:
+            CRC = self.CRC
+            compress_size = self.compress_size
+            file_size = self.file_size
+
+        extra = self.extra
+
+        if file_size > ZIP64_LIMIT or compress_size > ZIP64_LIMIT:
+            # File is larger than what fits into a 4 byte integer,
+            # fall back to the ZIP64 extension
+            fmt = '<hhqq'
+            extra = extra + struct.pack(fmt,
+                    1, struct.calcsize(fmt)-4, file_size, compress_size)
+            file_size = 0xffffffff # -1
+            compress_size = 0xffffffff # -1
+            self.extract_version = max(45, self.extract_version)
+            self.create_version = max(45, self.extract_version)
+
+        header = struct.pack(structFileHeader, stringFileHeader,
+                 self.extract_version, self.reserved, self.flag_bits,
+                 self.compress_type, dostime, dosdate, CRC,
+                 compress_size, file_size,
+                 len(self.filename), len(extra))
+        return header + self.filename + extra
+
+    def _decodeExtra(self):
+        # Try to decode the extra field.
+        extra = self.extra
+        unpack = struct.unpack
+        while extra:
+            tp, ln = unpack('<hh', extra[:4])
+            if tp == 1:
+                if ln >= 24:
+                    counts = unpack('<qqq', extra[4:28])
+                elif ln == 16:
+                    counts = unpack('<qq', extra[4:20])
+                elif ln == 8:
+                    counts = unpack('<q', extra[4:12])
+                elif ln == 0:
+                    counts = ()
+                else:
+                    raise RuntimeError, "Corrupt extra field %s"%(ln,)
+
+                idx = 0
+
+                # ZIP64 extension (large files and/or large archives)
+                if self.file_size == -1 or self.file_size == 0xFFFFFFFFL:
+                    self.file_size = counts[idx]
+                    idx += 1
+
+                if self.compress_size == -1 or self.compress_size == 0xFFFFFFFFL:
+                    self.compress_size = counts[idx]
+                    idx += 1
+
+                if self.header_offset == -1 or self.header_offset == 0xffffffffL:
+                    old = self.header_offset
+                    self.header_offset = counts[idx]
+                    idx+=1
+
+            extra = extra[ln+4:]
+
+
+class ZipFile:
+    """ Class with methods to open, read, write, close, list zip files.
+
+    z = ZipFile(file, mode="r", compression=ZIP_STORED, allowZip64=True)
+
+    file: Either the path to the file, or a file-like object.
+          If it is a path, the file will be opened and closed by ZipFile.
+    mode: The mode can be either read "r", write "w" or append "a".
+    compression: ZIP_STORED (no compression) or ZIP_DEFLATED (requires zlib).
+    allowZip64: if True ZipFile will create files with ZIP64 extensions when
+                needed, otherwise it will raise an exception when this would
+                be necessary.
+
+    """
+
+    fp = None                   # Set here since __del__ checks it
+
+    def __init__(self, file, mode="r", compression=ZIP_STORED, allowZip64=False):
+        """Open the ZIP file with mode read "r", write "w" or append "a"."""
+        self._allowZip64 = allowZip64
+        self._didModify = False
+        if compression == ZIP_STORED:
+            pass
+        elif compression == ZIP_DEFLATED:
+            if not zlib:
+                raise RuntimeError,\
+                      "Compression requires the (missing) zlib module"
+        else:
+            raise RuntimeError, "That compression method is not supported"
+        self.debug = 0  # Level of printing: 0 through 3
+        self.NameToInfo = {}    # Find file info given name
+        self.filelist = []      # List of ZipInfo instances for archive
+        self.compression = compression  # Method of compression
+        self.mode = key = mode.replace('b', '')[0]
+
+        # Check if we were passed a file-like object
+        if isinstance(file, basestring):
+            self._filePassed = 0
+            self.filename = file
+            modeDict = {'r' : 'rb', 'w': 'wb', 'a' : 'r+b'}
+            self.fp = open(file, modeDict[mode])
+        else:
+            self._filePassed = 1
+            self.fp = file
+            self.filename = getattr(file, 'name', None)
+
+        if key == 'r':
+            self._GetContents()
+        elif key == 'w':
+            pass
+        elif key == 'a':
+            try:                        # See if file is a zip file
+                self._RealGetContents()
+                # seek to start of directory and overwrite
+                self.fp.seek(self.start_dir, 0)
+            except BadZipfile:          # file is not a zip file, just append
+                self.fp.seek(0, 2)
+        else:
+            if not self._filePassed:
+                self.fp.close()
+                self.fp = None
+            raise RuntimeError, 'Mode must be "r", "w" or "a"'
+
+    def _GetContents(self):
+        """Read the directory, making sure we close the file if the format
+        is bad."""
+        try:
+            self._RealGetContents()
+        except BadZipfile:
+            if not self._filePassed:
+                self.fp.close()
+                self.fp = None
+            raise
+
+    def _RealGetContents(self):
+        """Read in the table of contents for the ZIP file."""
+        fp = self.fp
+        endrec = _EndRecData(fp)
+        if not endrec:
+            raise BadZipfile, "File is not a zip file"
+        if self.debug > 1:
+            print endrec
+        size_cd = endrec[5]             # bytes in central directory
+        offset_cd = endrec[6]   # offset of central directory
+        self.comment = endrec[8]        # archive comment
+        # endrec[9] is the offset of the "End of Central Dir" record
+        if endrec[9] > ZIP64_LIMIT:
+            x = endrec[9] - size_cd - 56 - 20
+        else:
+            x = endrec[9] - size_cd
+        # "concat" is zero, unless zip was concatenated to another file
+        concat = x - offset_cd
+        if self.debug > 2:
+            print "given, inferred, offset", offset_cd, x, concat
+        # self.start_dir:  Position of start of central directory
+        self.start_dir = offset_cd + concat
+        fp.seek(self.start_dir, 0)
+        data = fp.read(size_cd)
+        fp = cStringIO.StringIO(data)
+        total = 0
+        while total < size_cd:
+            centdir = fp.read(46)
+            total = total + 46
+            if centdir[0:4] != stringCentralDir:
+                raise BadZipfile, "Bad magic number for central directory"
+            centdir = struct.unpack(structCentralDir, centdir)
+            if self.debug > 2:
+                print centdir
+            filename = fp.read(centdir[_CD_FILENAME_LENGTH])
+            # Create ZipInfo instance to store file information
+            x = ZipInfo(filename)
+            x.extra = fp.read(centdir[_CD_EXTRA_FIELD_LENGTH])
+            x.comment = fp.read(centdir[_CD_COMMENT_LENGTH])
+            total = (total + centdir[_CD_FILENAME_LENGTH]
+                     + centdir[_CD_EXTRA_FIELD_LENGTH]
+                     + centdir[_CD_COMMENT_LENGTH])
+            x.header_offset = centdir[_CD_LOCAL_HEADER_OFFSET]
+            (x.create_version, x.create_system, x.extract_version, x.reserved,
+                x.flag_bits, x.compress_type, t, d,
+                x.CRC, x.compress_size, x.file_size) = centdir[1:12]
+            x.volume, x.internal_attr, x.external_attr = centdir[15:18]
+            # Convert date/time code to (year, month, day, hour, min, sec)
+            x.date_time = ( (d>>9)+1980, (d>>5)&0xF, d&0x1F,
+                                     t>>11, (t>>5)&0x3F, (t&0x1F) * 2 )
+
+            x._decodeExtra()
+            x.header_offset = x.header_offset + concat
+            self.filelist.append(x)
+            self.NameToInfo[x.filename] = x
+            if self.debug > 2:
+                print "total", total
+
+
+    def namelist(self):
+        """Return a list of file names in the archive."""
+        l = []
+        for data in self.filelist:
+            l.append(data.filename)
+        return l
+
+    def infolist(self):
+        """Return a list of class ZipInfo instances for files in the
+        archive."""
+        return self.filelist
+
+    def printdir(self):
+        """Print a table of contents for the zip file."""
+        print "%-46s %19s %12s" % ("File Name", "Modified    ", "Size")
+        for zinfo in self.filelist:
+            date = "%d-%02d-%02d %02d:%02d:%02d" % zinfo.date_time
+            print "%-46s %s %12d" % (zinfo.filename, date, zinfo.file_size)
+
+    def testzip(self):
+        """Read all the files and check the CRC."""
+        for zinfo in self.filelist:
+            try:
+                self.read(zinfo.filename)       # Check CRC-32
+            except BadZipfile:
+                return zinfo.filename
+
+
+    def getinfo(self, name):
+        """Return the instance of ZipInfo given 'name'."""
+        return self.NameToInfo[name]
+
+    def read(self, name):
+        """Return file bytes (as a string) for name."""
+        if self.mode not in ("r", "a"):
+            raise RuntimeError, 'read() requires mode "r" or "a"'
+        if not self.fp:
+            raise RuntimeError, \
+                  "Attempt to read ZIP archive that was already closed"
+        zinfo = self.getinfo(name)
+        filepos = self.fp.tell()
+
+        self.fp.seek(zinfo.header_offset, 0)
+
+        # Skip the file header:
+        fheader = self.fp.read(30)
+        if fheader[0:4] != stringFileHeader:
+            raise BadZipfile, "Bad magic number for file header"
+
+        fheader = struct.unpack(structFileHeader, fheader)
+        fname = self.fp.read(fheader[_FH_FILENAME_LENGTH])
+        if fheader[_FH_EXTRA_FIELD_LENGTH]:
+            self.fp.read(fheader[_FH_EXTRA_FIELD_LENGTH])
+
+        if fname != zinfo.orig_filename:
+            raise BadZipfile, \
+                      'File name in directory "%s" and header "%s" differ.' % (
+                          zinfo.orig_filename, fname)
+
+        bytes = self.fp.read(zinfo.compress_size)
+        self.fp.seek(filepos, 0)
+        if zinfo.compress_type == ZIP_STORED:
+            pass
+        elif zinfo.compress_type == ZIP_DEFLATED:
+            if not zlib:
+                raise RuntimeError, \
+                      "De-compression requires the (missing) zlib module"
+            # zlib compress/decompress code by Jeremy Hylton of CNRI
+            dc = zlib.decompressobj(-15)
+            bytes = dc.decompress(bytes)
+            # need to feed in unused pad byte so that zlib won't choke
+            ex = dc.decompress('Z') + dc.flush()
+            if ex:
+                bytes = bytes + ex
+        else:
+            raise BadZipfile, \
+                  "Unsupported compression method %d for file %s" % \
+            (zinfo.compress_type, name)
+        crc = binascii.crc32(bytes)
+        if crc != zinfo.CRC:
+            raise BadZipfile, "Bad CRC-32 for file %s" % name
+        return bytes
+
+    def _writecheck(self, zinfo):
+        """Check for errors before writing a file to the archive."""
+        if zinfo.filename in self.NameToInfo:
+            if self.debug:      # Warning for duplicate names
+                print "Duplicate name:", zinfo.filename
+        if self.mode not in ("w", "a"):
+            raise RuntimeError, 'write() requires mode "w" or "a"'
+        if not self.fp:
+            raise RuntimeError, \
+                  "Attempt to write ZIP archive that was already closed"
+        if zinfo.compress_type == ZIP_DEFLATED and not zlib:
+            raise RuntimeError, \
+                  "Compression requires the (missing) zlib module"
+        if zinfo.compress_type not in (ZIP_STORED, ZIP_DEFLATED):
+            raise RuntimeError, \
+                  "That compression method is not supported"
+        if zinfo.file_size > ZIP64_LIMIT:
+            if not self._allowZip64:
+                raise LargeZipFile("Filesize would require ZIP64 extensions")
+        if zinfo.header_offset > ZIP64_LIMIT:
+            if not self._allowZip64:
+                raise LargeZipFile("Zipfile size would require ZIP64 extensions")
+
+    def write(self, filename, arcname=None, compress_type=None):
+        """Put the bytes from filename into the archive under the name
+        arcname."""
+        st = os.stat(filename)
+        mtime = time.localtime(st.st_mtime)
+        date_time = mtime[0:6]
+        # Create ZipInfo instance to store file information
+        if arcname is None:
+            arcname = filename
+        arcname = os.path.normpath(os.path.splitdrive(arcname)[1])
+        while arcname[0] in (os.sep, os.altsep):
+            arcname = arcname[1:]
+        zinfo = ZipInfo(arcname, date_time)
+        zinfo.external_attr = (st[0] & 0xFFFF) << 16L      # Unix attributes
+        if compress_type is None:
+            zinfo.compress_type = self.compression
+        else:
+            zinfo.compress_type = compress_type
+
+        zinfo.file_size = st.st_size
+        zinfo.flag_bits = 0x00
+        zinfo.header_offset = self.fp.tell()    # Start of header bytes
+
+        self._writecheck(zinfo)
+        self._didModify = True
+        fp = open(filename, "rb")
+        # Must overwrite CRC and sizes with correct data later
+        zinfo.CRC = CRC = 0
+        zinfo.compress_size = compress_size = 0
+        zinfo.file_size = file_size = 0
+        self.fp.write(zinfo.FileHeader())
+        if zinfo.compress_type == ZIP_DEFLATED:
+            cmpr = zlib.compressobj(zlib.Z_DEFAULT_COMPRESSION,
+                 zlib.DEFLATED, -15)
+        else:
+            cmpr = None
+        while 1:
+            buf = fp.read(1024 * 8)
+            if not buf:
+                break
+            file_size = file_size + len(buf)
+            CRC = binascii.crc32(buf, CRC)
+            if cmpr:
+                buf = cmpr.compress(buf)
+                compress_size = compress_size + len(buf)
+            self.fp.write(buf)
+        fp.close()
+        if cmpr:
+            buf = cmpr.flush()
+            compress_size = compress_size + len(buf)
+            self.fp.write(buf)
+            zinfo.compress_size = compress_size
+        else:
+            zinfo.compress_size = file_size
+        zinfo.CRC = CRC
+        zinfo.file_size = file_size
+        # Seek backwards and write CRC and file sizes
+        position = self.fp.tell()       # Preserve current position in file
+        self.fp.seek(zinfo.header_offset + 14, 0)
+        self.fp.write(struct.pack("<lLL", zinfo.CRC, zinfo.compress_size,
+              zinfo.file_size))
+        self.fp.seek(position, 0)
+        self.filelist.append(zinfo)
+        self.NameToInfo[zinfo.filename] = zinfo
+
+    def writestr(self, zinfo_or_arcname, bytes):
+        """Write a file into the archive.  The contents is the string
+        'bytes'.  'zinfo_or_arcname' is either a ZipInfo instance or
+        the name of the file in the archive."""
+        if not isinstance(zinfo_or_arcname, ZipInfo):
+            zinfo = ZipInfo(filename=zinfo_or_arcname,
+                            date_time=time.localtime(time.time()))
+            zinfo.compress_type = self.compression
+        else:
+            zinfo = zinfo_or_arcname
+        zinfo.file_size = len(bytes)            # Uncompressed size
+        zinfo.header_offset = self.fp.tell()    # Start of header bytes
+        self._writecheck(zinfo)
+        self._didModify = True
+        zinfo.CRC = binascii.crc32(bytes)       # CRC-32 checksum
+        if zinfo.compress_type == ZIP_DEFLATED:
+            co = zlib.compressobj(zlib.Z_DEFAULT_COMPRESSION,
+                 zlib.DEFLATED, -15)
+            bytes = co.compress(bytes) + co.flush()
+            zinfo.compress_size = len(bytes)    # Compressed size
+        else:
+            zinfo.compress_size = zinfo.file_size
+        zinfo.header_offset = self.fp.tell()    # Start of header bytes
+        self.fp.write(zinfo.FileHeader())
+        self.fp.write(bytes)
+        self.fp.flush()
+        if zinfo.flag_bits & 0x08:
+            # Write CRC and file sizes after the file data
+            self.fp.write(struct.pack("<lLL", zinfo.CRC, zinfo.compress_size,
+                  zinfo.file_size))
+        self.filelist.append(zinfo)
+        self.NameToInfo[zinfo.filename] = zinfo
+
+    def __del__(self):
+        """Call the "close()" method in case the user forgot."""
+        self.close()
+
+    def close(self):
+        """Close the file, and for mode "w" and "a" write the ending
+        records."""
+        if self.fp is None:
+            return
+
+        if self.mode in ("w", "a") and self._didModify: # write ending records
+            count = 0
+            pos1 = self.fp.tell()
+            for zinfo in self.filelist:         # write central directory
+                count = count + 1
+                dt = zinfo.date_time
+                dosdate = (dt[0] - 1980) << 9 | dt[1] << 5 | dt[2]
+                dostime = dt[3] << 11 | dt[4] << 5 | (dt[5] // 2)
+                extra = []
+                if zinfo.file_size > ZIP64_LIMIT \
+                        or zinfo.compress_size > ZIP64_LIMIT:
+                    extra.append(zinfo.file_size)
+                    extra.append(zinfo.compress_size)
+                    file_size = 0xffffffff #-1
+                    compress_size = 0xffffffff #-1
+                else:
+                    file_size = zinfo.file_size
+                    compress_size = zinfo.compress_size
+
+                if zinfo.header_offset > ZIP64_LIMIT:
+                    extra.append(zinfo.header_offset)
+                    header_offset = -1  # struct "l" format:  32 one bits
+                else:
+                    header_offset = zinfo.header_offset
+
+                extra_data = zinfo.extra
+                if extra:
+                    # Append a ZIP64 field to the extra's
+                    extra_data = struct.pack(
+                            '<hh' + 'q'*len(extra),
+                            1, 8*len(extra), *extra) + extra_data
+
+                    extract_version = max(45, zinfo.extract_version)
+                    create_version = max(45, zinfo.create_version)
+                else:
+                    extract_version = zinfo.extract_version
+                    create_version = zinfo.create_version
+
+                centdir = struct.pack(structCentralDir,
+                  stringCentralDir, create_version,
+                  zinfo.create_system, extract_version, zinfo.reserved,
+                  zinfo.flag_bits, zinfo.compress_type, dostime, dosdate,
+                  zinfo.CRC, compress_size, file_size,
+                  len(zinfo.filename), len(extra_data), len(zinfo.comment),
+                  0, zinfo.internal_attr, zinfo.external_attr,
+                  header_offset)
+                self.fp.write(centdir)
+                self.fp.write(zinfo.filename)
+                self.fp.write(extra_data)
+                self.fp.write(zinfo.comment)
+
+            pos2 = self.fp.tell()
+            # Write end-of-zip-archive record
+            if pos1 > ZIP64_LIMIT:
+                # Need to write the ZIP64 end-of-archive records
+                zip64endrec = struct.pack(
+                        structEndArchive64, stringEndArchive64,
+                        44, 45, 45, 0, 0, count, count, pos2 - pos1, pos1)
+                self.fp.write(zip64endrec)
+
+                zip64locrec = struct.pack(
+                        structEndArchive64Locator,
+                        stringEndArchive64Locator, 0, pos2, 1)
+                self.fp.write(zip64locrec)
+
+                # XXX Why is `pos3` computed next?  It's never referenced.
+                pos3 = self.fp.tell()
+                endrec = struct.pack(structEndArchive, stringEndArchive,
+                            0, 0, count, count, pos2 - pos1, -1, 0)
+                self.fp.write(endrec)
+
+            else:
+                endrec = struct.pack(structEndArchive, stringEndArchive,
+                         0, 0, count, count, pos2 - pos1, pos1, 0)
+                self.fp.write(endrec)
+            self.fp.flush()
+        if not self._filePassed:
+            self.fp.close()
+        self.fp = None
+
+
+class PyZipFile(ZipFile):
+    """Class to create ZIP archives with Python library files and packages."""
+
+    def writepy(self, pathname, basename = ""):
+        """Add all files from "pathname" to the ZIP archive.
+
+        If pathname is a package directory, search the directory and
+        all package subdirectories recursively for all *.py and enter
+        the modules into the archive.  If pathname is a plain
+        directory, listdir *.py and enter all modules.  Else, pathname
+        must be a Python *.py file and the module will be put into the
+        archive.  Added modules are always module.pyo or module.pyc.
+        This method will compile the module.py into module.pyc if
+        necessary.
+        """
+        dir, name = os.path.split(pathname)
+        if os.path.isdir(pathname):
+            initname = os.path.join(pathname, "__init__.py")
+            if os.path.isfile(initname):
+                # This is a package directory, add it
+                if basename:
+                    basename = "%s/%s" % (basename, name)
+                else:
+                    basename = name
+                if self.debug:
+                    print "Adding package in", pathname, "as", basename
+                fname, arcname = self._get_codename(initname[0:-3], basename)
+                if self.debug:
+                    print "Adding", arcname
+                self.write(fname, arcname)
+                dirlist = os.listdir(pathname)
+                dirlist.remove("__init__.py")
+                # Add all *.py files and package subdirectories
+                for filename in dirlist:
+                    path = os.path.join(pathname, filename)
+                    root, ext = os.path.splitext(filename)
+                    if os.path.isdir(path):
+                        if os.path.isfile(os.path.join(path, "__init__.py")):
+                            # This is a package directory, add it
+                            self.writepy(path, basename)  # Recursive call
+                    elif ext == ".py":
+                        fname, arcname = self._get_codename(path[0:-3],
+                                         basename)
+                        if self.debug:
+                            print "Adding", arcname
+                        self.write(fname, arcname)
+            else:
+                # This is NOT a package directory, add its files at top level
+                if self.debug:
+                    print "Adding files from directory", pathname
+                for filename in os.listdir(pathname):
+                    path = os.path.join(pathname, filename)
+                    root, ext = os.path.splitext(filename)
+                    if ext == ".py":
+                        fname, arcname = self._get_codename(path[0:-3],
+                                         basename)
+                        if self.debug:
+                            print "Adding", arcname
+                        self.write(fname, arcname)
+        else:
+            if pathname[-3:] != ".py":
+                raise RuntimeError, \
+                      'Files added with writepy() must end with ".py"'
+            fname, arcname = self._get_codename(pathname[0:-3], basename)
+            if self.debug:
+                print "Adding file", arcname
+            self.write(fname, arcname)
+
+    def _get_codename(self, pathname, basename):
+        """Return (filename, archivename) for the path.
+
+        Given a module name path, return the correct file path and
+        archive name, compiling if necessary.  For example, given
+        /python/lib/string, return (/python/lib/string.pyc, string).
+        """
+        file_py  = pathname + ".py"
+        file_pyc = pathname + ".pyc"
+        file_pyo = pathname + ".pyo"
+        if os.path.isfile(file_pyo) and \
+                            os.stat(file_pyo).st_mtime >= os.stat(file_py).st_mtime:
+            fname = file_pyo    # Use .pyo file
+        elif not os.path.isfile(file_pyc) or \
+             os.stat(file_pyc).st_mtime < os.stat(file_py).st_mtime:
+            import py_compile
+            if self.debug:
+                print "Compiling", file_py
+            try:
+                py_compile.compile(file_py, file_pyc, None, True)
+            except py_compile.PyCompileError,err:
+                print err.msg
+            fname = file_pyc
+        else:
+            fname = file_pyc
+        archivename = os.path.split(fname)[1]
+        if basename:
+            archivename = "%s/%s" % (basename, archivename)
+        return (fname, archivename)
+
+
+def main(args = None):
+    import textwrap
+    USAGE=textwrap.dedent("""\
+        Usage:
+            zipfile.py -l zipfile.zip        # Show listing of a zipfile
+            zipfile.py -t zipfile.zip        # Test if a zipfile is valid
+            zipfile.py -e zipfile.zip target # Extract zipfile into target dir
+            zipfile.py -c zipfile.zip src ... # Create zipfile from sources
+        """)
+    if args is None:
+        args = sys.argv[1:]
+
+    if not args or args[0] not in ('-l', '-c', '-e', '-t'):
+        print USAGE
+        sys.exit(1)
+
+    if args[0] == '-l':
+        if len(args) != 2:
+            print USAGE
+            sys.exit(1)
+        zf = ZipFile(args[1], 'r')
+        zf.printdir()
+        zf.close()
+
+    elif args[0] == '-t':
+        if len(args) != 2:
+            print USAGE
+            sys.exit(1)
+        zf = ZipFile(args[1], 'r')
+        zf.testzip()
+        print "Done testing"
+
+    elif args[0] == '-e':
+        if len(args) != 3:
+            print USAGE
+            sys.exit(1)
+
+        zf = ZipFile(args[1], 'r')
+        out = args[2]
+        for path in zf.namelist():
+            if path.startswith('./'):
+                tgt = os.path.join(out, path[2:])
+            else:
+                tgt = os.path.join(out, path)
+
+            tgtdir = os.path.dirname(tgt)
+            if not os.path.exists(tgtdir):
+                os.makedirs(tgtdir)
+            fp = open(tgt, 'wb')
+            fp.write(zf.read(path))
+            fp.close()
+        zf.close()
+
+    elif args[0] == '-c':
+        if len(args) < 3:
+            print USAGE
+            sys.exit(1)
+
+        def addToZip(zf, path, zippath):
+            if os.path.isfile(path):
+                zf.write(path, zippath, ZIP_DEFLATED)
+            elif os.path.isdir(path):
+                for nm in os.listdir(path):
+                    addToZip(zf,
+                            os.path.join(path, nm), os.path.join(zippath, nm))
+            # else: ignore
+
+        zf = ZipFile(args[1], 'w', allowZip64=True)
+        for src in args[2:]:
+            addToZip(zf, src, os.path.basename(src))
+
+        zf.close()
+
+if __name__ == "__main__":
+    main()

Added: vendor/Python/current/Mac/BuildScript/README.txt
===================================================================
--- vendor/Python/current/Mac/BuildScript/README.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/BuildScript/README.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,67 @@
+Building a MacPython distribution
+=================================
+
+The ``build-install.py`` script creates MacPython distributions, including
+sleepycat db4, sqlite3 and readline support.  It builds a complete 
+framework-based Python out-of-tree, installs it in a funny place with 
+$DESTROOT, massages that installation to remove .pyc files and such, creates 
+an Installer package from the installation plus other files in ``resources`` 
+and ``scripts`` and placed that on a ``.dmg`` disk image.
+
+Prerequisites
+-------------
+
+* A MacOS X 10.4 (or later)
+
+* XCode 2.2 (or later), with the universal SDK
+
+* No Fink (in ``/sw``) or DarwinPorts (in ``/opt/local``), those could
+  interfere with the build.
+
+* The documentation for the release must be available on python.org
+  because it is included in the installer.
+
+
+The Recipe
+----------
+
+Here are the steps you need to follow to build a MacPython installer:
+
+*  Run ``./build-installer.py``. Optionally you can pass a number of arguments
+   to specify locations of various files. Please see the top of
+  ``build-installer.py`` for its usage.
+
+  Running this script takes some time, I will not only build Python itself
+  but also some 3th-party libraries that are needed for extensions.
+
+* When done the script will tell you where the DMG image is (by default
+  somewhere in ``/tmp/_py``).
+
+Testing
+-------
+
+The resulting binaries should work on MacOSX 10.3.9 or later. I usually run
+the installer on a 10.3.9, a 10.4.x PPC and a 10.4.x Intel system and then
+run the testsuite to make sure.
+
+
+Announcements
+-------------
+
+(This is mostly of historic interest)
+
+When all is done, announcements can be posted to at least the following
+places:
+-   pythonmac-sig at python.org
+-   python-dev at python.org
+-   python-announce at python.org
+-   archivist at info-mac.org
+-   adcnews at apple.com
+-   news at macnn.com
+-   http://www.macupdate.com
+-   http://guide.apple.com/usindex.lasso
+-   http://www.apple.com/downloads/macosx/submit
+-   http://www.versiontracker.com/ (userid Jack.Jansen at oratrix.com)
+-   http://www.macshareware.net (userid jackjansen)
+
+Also, check out Stephan Deibels http://pythonology.org/market contact list

Added: vendor/Python/current/Mac/BuildScript/build-installer.py
===================================================================
--- vendor/Python/current/Mac/BuildScript/build-installer.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/BuildScript/build-installer.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1067 @@
+#!/usr/bin/python2.3
+"""
+This script is used to build the "official unofficial" universal build on
+Mac OS X. It requires Mac OS X 10.4, Xcode 2.2 and the 10.4u SDK to do its
+work.
+
+Please ensure that this script keeps working with Python 2.3, to avoid
+bootstrap issues (/usr/bin/python is Python 2.3 on OSX 10.4)
+
+Usage: see USAGE variable in the script.
+"""
+import platform, os, sys, getopt, textwrap, shutil, urllib2, stat, time, pwd
+import grp
+
+INCLUDE_TIMESTAMP=1
+VERBOSE=1
+
+from plistlib import Plist
+
+import MacOS
+import Carbon.File
+import Carbon.Icn
+import Carbon.Res
+from Carbon.Files import kCustomIconResource, fsRdWrPerm, kHasCustomIcon
+from Carbon.Files import kFSCatInfoFinderInfo
+
+try:
+    from plistlib import writePlist
+except ImportError:
+    # We're run using python2.3
+    def writePlist(plist, path):
+        plist.write(path)
+
+def shellQuote(value):
+    """
+    Return the string value in a form that can safely be inserted into
+    a shell command.
+    """
+    return "'%s'"%(value.replace("'", "'\"'\"'"))
+
+def grepValue(fn, variable):
+    variable = variable + '='
+    for ln in open(fn, 'r'):
+        if ln.startswith(variable):
+            value = ln[len(variable):].strip()
+            return value[1:-1]
+
+def getVersion():
+    return grepValue(os.path.join(SRCDIR, 'configure'), 'PACKAGE_VERSION')
+
+def getFullVersion():
+    fn = os.path.join(SRCDIR, 'Include', 'patchlevel.h')
+    for ln in open(fn):
+        if 'PY_VERSION' in ln:
+            return ln.split()[-1][1:-1]
+
+    raise RuntimeError, "Cannot find full version??"
+
+# The directory we'll use to create the build (will be erased and recreated)
+WORKDIR="/tmp/_py"
+
+# The directory we'll use to store third-party sources. Set this to something
+# else if you don't want to re-fetch required libraries every time.
+DEPSRC=os.path.join(WORKDIR, 'third-party')
+DEPSRC=os.path.expanduser('~/Universal/other-sources')
+
+# Location of the preferred SDK
+SDKPATH="/Developer/SDKs/MacOSX10.4u.sdk"
+#SDKPATH="/"
+
+ARCHLIST=('i386', 'ppc',)
+
+# Source directory (asume we're in Mac/BuildScript)
+SRCDIR=os.path.dirname(
+        os.path.dirname(
+            os.path.dirname(
+                os.path.abspath(__file__
+        ))))
+
+USAGE=textwrap.dedent("""\
+    Usage: build_python [options]
+
+    Options:
+    -? or -h:            Show this message
+    -b DIR
+    --build-dir=DIR:     Create build here (default: %(WORKDIR)r)
+    --third-party=DIR:   Store third-party sources here (default: %(DEPSRC)r)
+    --sdk-path=DIR:      Location of the SDK (default: %(SDKPATH)r)
+    --src-dir=DIR:       Location of the Python sources (default: %(SRCDIR)r)
+""")% globals()
+
+
+# Instructions for building libraries that are necessary for building a
+# batteries included python.
+LIBRARY_RECIPES=[
+    dict(
+        name="Bzip2 1.0.3",
+        url="http://www.bzip.org/1.0.3/bzip2-1.0.3.tar.gz",
+        configure=None,
+        install='make install PREFIX=%s/usr/local/ CFLAGS="-arch %s -isysroot %s"'%(
+            shellQuote(os.path.join(WORKDIR, 'libraries')),
+            ' -arch '.join(ARCHLIST),
+            SDKPATH,
+        ),
+    ),
+    dict(
+        name="ZLib 1.2.3",
+        url="http://www.gzip.org/zlib/zlib-1.2.3.tar.gz",
+        configure=None,
+        install='make install prefix=%s/usr/local/ CFLAGS="-arch %s -isysroot %s"'%(
+            shellQuote(os.path.join(WORKDIR, 'libraries')),
+            ' -arch '.join(ARCHLIST),
+            SDKPATH,
+        ),
+    ),
+    dict(
+        # Note that GNU readline is GPL'd software
+        name="GNU Readline 5.1.4",
+        url="http://ftp.gnu.org/pub/gnu/readline/readline-5.1.tar.gz" ,
+        patchlevel='0',
+        patches=[
+            # The readline maintainers don't do actual micro releases, but
+            # just ship a set of patches.
+            'http://ftp.gnu.org/pub/gnu/readline/readline-5.1-patches/readline51-001',
+            'http://ftp.gnu.org/pub/gnu/readline/readline-5.1-patches/readline51-002',
+            'http://ftp.gnu.org/pub/gnu/readline/readline-5.1-patches/readline51-003',
+            'http://ftp.gnu.org/pub/gnu/readline/readline-5.1-patches/readline51-004',
+        ]
+    ),
+
+    dict(
+        name="SQLite 3.3.5",
+        url="http://www.sqlite.org/sqlite-3.3.5.tar.gz",
+        checksum='93f742986e8bc2dfa34792e16df017a6feccf3a2',
+        configure_pre=[
+            '--enable-threadsafe',
+            '--enable-tempstore',
+            '--enable-shared=no',
+            '--enable-static=yes',
+            '--disable-tcl',
+        ]
+    ),
+
+    dict(
+        name="NCurses 5.5",
+        url="http://ftp.gnu.org/pub/gnu/ncurses/ncurses-5.5.tar.gz",
+        configure_pre=[
+            "--without-cxx",
+            "--without-ada",
+            "--without-progs",
+            "--without-curses-h",
+            "--enable-shared",
+            "--with-shared",
+            "--datadir=/usr/share",
+            "--sysconfdir=/etc",
+            "--sharedstatedir=/usr/com",
+            "--with-terminfo-dirs=/usr/share/terminfo",
+            "--with-default-terminfo-dir=/usr/share/terminfo",
+            "--libdir=/Library/Frameworks/Python.framework/Versions/%s/lib"%(getVersion(),),
+            "--enable-termcap",
+        ],
+        patches=[
+            "ncurses-5.5.patch",
+        ],
+        useLDFlags=False,
+        install='make && make install DESTDIR=%s && cd %s/usr/local/lib && ln -fs ../../../Library/Frameworks/Python.framework/Versions/%s/lib/lib* .'%(
+            shellQuote(os.path.join(WORKDIR, 'libraries')),
+            shellQuote(os.path.join(WORKDIR, 'libraries')),
+            getVersion(),
+            ),
+    ),
+    dict(
+        name="Sleepycat DB 4.4",
+        url="http://downloads.sleepycat.com/db-4.4.20.tar.gz",
+        #name="Sleepycat DB 4.3.29",
+        #url="http://downloads.sleepycat.com/db-4.3.29.tar.gz",
+        buildDir="build_unix",
+        configure="../dist/configure",
+        configure_pre=[
+            '--includedir=/usr/local/include/db4',
+        ]
+    ),
+]
+
+
+# Instructions for building packages inside the .mpkg.
+PKG_RECIPES=[
+    dict(
+        name="PythonFramework",
+        long_name="Python Framework",
+        source="/Library/Frameworks/Python.framework",
+        readme="""\
+            This package installs Python.framework, that is the python
+            interpreter and the standard library. This also includes Python
+            wrappers for lots of Mac OS X API's.
+        """,
+        postflight="scripts/postflight.framework",
+    ),
+    dict(
+        name="PythonApplications",
+        long_name="GUI Applications",
+        source="/Applications/MacPython %(VER)s",
+        readme="""\
+            This package installs IDLE (an interactive Python IDE),
+            Python Launcher and Build Applet (create application bundles
+            from python scripts).
+
+            It also installs a number of examples and demos.
+            """,
+        required=False,
+    ),
+    dict(
+        name="PythonUnixTools",
+        long_name="UNIX command-line tools",
+        source="/usr/local/bin",
+        readme="""\
+            This package installs the unix tools in /usr/local/bin for
+            compatibility with older releases of MacPython. This package
+            is not necessary to use MacPython.
+            """,
+        required=False,
+    ),
+    dict(
+        name="PythonDocumentation",
+        long_name="Python Documentation",
+        topdir="/Library/Frameworks/Python.framework/Versions/%(VER)s/Resources/English.lproj/Documentation",
+        source="/pydocs",
+        readme="""\
+            This package installs the python documentation at a location
+            that is useable for pydoc and IDLE. If you have installed Xcode
+            it will also install a link to the documentation in
+            /Developer/Documentation/Python
+            """,
+        postflight="scripts/postflight.documentation",
+        required=False,
+    ),
+    dict(
+        name="PythonProfileChanges",
+        long_name="Shell profile updater",
+        readme="""\
+            This packages updates your shell profile to make sure that
+            the MacPython tools are found by your shell in preference of
+            the system provided Python tools.
+
+            If you don't install this package you'll have to add
+            "/Library/Frameworks/Python.framework/Versions/%(VER)s/bin"
+            to your PATH by hand.
+            """,
+        postflight="scripts/postflight.patch-profile",
+        topdir="/Library/Frameworks/Python.framework",
+        source="/empty-dir",
+        required=False,
+    ),
+    dict(
+        name="PythonSystemFixes",
+        long_name="Fix system Python",
+        readme="""\
+            This package updates the system python installation on
+            Mac OS X 10.3 to ensure that you can build new python extensions
+            using that copy of python after installing this version.
+            """,
+        postflight="../Tools/fixapplepython23.py",
+        topdir="/Library/Frameworks/Python.framework",
+        source="/empty-dir",
+        required=False,
+    )
+]
+
+def fatal(msg):
+    """
+    A fatal error, bail out.
+    """
+    sys.stderr.write('FATAL: ')
+    sys.stderr.write(msg)
+    sys.stderr.write('\n')
+    sys.exit(1)
+
+def fileContents(fn):
+    """
+    Return the contents of the named file
+    """
+    return open(fn, 'rb').read()
+
+def runCommand(commandline):
+    """
+    Run a command and raise RuntimeError if it fails. Output is surpressed
+    unless the command fails.
+    """
+    fd = os.popen(commandline, 'r')
+    data = fd.read()
+    xit = fd.close()
+    if xit != None:
+        sys.stdout.write(data)
+        raise RuntimeError, "command failed: %s"%(commandline,)
+
+    if VERBOSE:
+        sys.stdout.write(data); sys.stdout.flush()
+
+def captureCommand(commandline):
+    fd = os.popen(commandline, 'r')
+    data = fd.read()
+    xit = fd.close()
+    if xit != None:
+        sys.stdout.write(data)
+        raise RuntimeError, "command failed: %s"%(commandline,)
+
+    return data
+
+def checkEnvironment():
+    """
+    Check that we're running on a supported system.
+    """
+
+    if platform.system() != 'Darwin':
+        fatal("This script should be run on a Mac OS X 10.4 system")
+
+    if platform.release() <= '8.':
+        fatal("This script should be run on a Mac OS X 10.4 system")
+
+    if not os.path.exists(SDKPATH):
+        fatal("Please install the latest version of Xcode and the %s SDK"%(
+            os.path.basename(SDKPATH[:-4])))
+
+
+
+def parseOptions(args = None):
+    """
+    Parse arguments and update global settings.
+    """
+    global WORKDIR, DEPSRC, SDKPATH, SRCDIR
+
+    if args is None:
+        args = sys.argv[1:]
+
+    try:
+        options, args = getopt.getopt(args, '?hb',
+                [ 'build-dir=', 'third-party=', 'sdk-path=' , 'src-dir='])
+    except getopt.error, msg:
+        print msg
+        sys.exit(1)
+
+    if args:
+        print "Additional arguments"
+        sys.exit(1)
+
+    for k, v in options:
+        if k in ('-h', '-?'):
+            print USAGE
+            sys.exit(0)
+
+        elif k in ('-d', '--build-dir'):
+            WORKDIR=v
+
+        elif k in ('--third-party',):
+            DEPSRC=v
+
+        elif k in ('--sdk-path',):
+            SDKPATH=v
+
+        elif k in ('--src-dir',):
+            SRCDIR=v
+
+        else:
+            raise NotImplementedError, k
+
+    SRCDIR=os.path.abspath(SRCDIR)
+    WORKDIR=os.path.abspath(WORKDIR)
+    SDKPATH=os.path.abspath(SDKPATH)
+    DEPSRC=os.path.abspath(DEPSRC)
+
+    print "Settings:"
+    print " * Source directory:", SRCDIR
+    print " * Build directory: ", WORKDIR
+    print " * SDK location:    ", SDKPATH
+    print " * third-party source:", DEPSRC
+    print ""
+
+
+
+
+def extractArchive(builddir, archiveName):
+    """
+    Extract a source archive into 'builddir'. Returns the path of the
+    extracted archive.
+
+    XXX: This function assumes that archives contain a toplevel directory
+    that is has the same name as the basename of the archive. This is
+    save enough for anything we use.
+    """
+    curdir = os.getcwd()
+    try:
+        os.chdir(builddir)
+        if archiveName.endswith('.tar.gz'):
+            retval = os.path.basename(archiveName[:-7])
+            if os.path.exists(retval):
+                shutil.rmtree(retval)
+            fp = os.popen("tar zxf %s 2>&1"%(shellQuote(archiveName),), 'r')
+
+        elif archiveName.endswith('.tar.bz2'):
+            retval = os.path.basename(archiveName[:-8])
+            if os.path.exists(retval):
+                shutil.rmtree(retval)
+            fp = os.popen("tar jxf %s 2>&1"%(shellQuote(archiveName),), 'r')
+
+        elif archiveName.endswith('.tar'):
+            retval = os.path.basename(archiveName[:-4])
+            if os.path.exists(retval):
+                shutil.rmtree(retval)
+            fp = os.popen("tar xf %s 2>&1"%(shellQuote(archiveName),), 'r')
+
+        elif archiveName.endswith('.zip'):
+            retval = os.path.basename(archiveName[:-4])
+            if os.path.exists(retval):
+                shutil.rmtree(retval)
+            fp = os.popen("unzip %s 2>&1"%(shellQuote(archiveName),), 'r')
+
+        data = fp.read()
+        xit = fp.close()
+        if xit is not None:
+            sys.stdout.write(data)
+            raise RuntimeError, "Cannot extract %s"%(archiveName,)
+
+        return os.path.join(builddir, retval)
+
+    finally:
+        os.chdir(curdir)
+
+KNOWNSIZES = {
+    "http://ftp.gnu.org/pub/gnu/readline/readline-5.1.tar.gz": 7952742,
+    "http://downloads.sleepycat.com/db-4.4.20.tar.gz": 2030276,
+}
+
+def downloadURL(url, fname):
+    """
+    Download the contents of the url into the file.
+    """
+    try:
+        size = os.path.getsize(fname)
+    except OSError:
+        pass
+    else:
+        if KNOWNSIZES.get(url) == size:
+            print "Using existing file for", url
+            return
+    fpIn = urllib2.urlopen(url)
+    fpOut = open(fname, 'wb')
+    block = fpIn.read(10240)
+    try:
+        while block:
+            fpOut.write(block)
+            block = fpIn.read(10240)
+        fpIn.close()
+        fpOut.close()
+    except:
+        try:
+            os.unlink(fname)
+        except:
+            pass
+
+def buildRecipe(recipe, basedir, archList):
+    """
+    Build software using a recipe. This function does the
+    'configure;make;make install' dance for C software, with a possibility
+    to customize this process, basically a poor-mans DarwinPorts.
+    """
+    curdir = os.getcwd()
+
+    name = recipe['name']
+    url = recipe['url']
+    configure = recipe.get('configure', './configure')
+    install = recipe.get('install', 'make && make install DESTDIR=%s'%(
+        shellQuote(basedir)))
+
+    archiveName = os.path.split(url)[-1]
+    sourceArchive = os.path.join(DEPSRC, archiveName)
+
+    if not os.path.exists(DEPSRC):
+        os.mkdir(DEPSRC)
+
+
+    if os.path.exists(sourceArchive):
+        print "Using local copy of %s"%(name,)
+
+    else:
+        print "Downloading %s"%(name,)
+        downloadURL(url, sourceArchive)
+        print "Archive for %s stored as %s"%(name, sourceArchive)
+
+    print "Extracting archive for %s"%(name,)
+    buildDir=os.path.join(WORKDIR, '_bld')
+    if not os.path.exists(buildDir):
+        os.mkdir(buildDir)
+
+    workDir = extractArchive(buildDir, sourceArchive)
+    os.chdir(workDir)
+    if 'buildDir' in recipe:
+        os.chdir(recipe['buildDir'])
+
+
+    for fn in recipe.get('patches', ()):
+        if fn.startswith('http://'):
+            # Download the patch before applying it.
+            path = os.path.join(DEPSRC, os.path.basename(fn))
+            downloadURL(fn, path)
+            fn = path
+
+        fn = os.path.join(curdir, fn)
+        runCommand('patch -p%s < %s'%(recipe.get('patchlevel', 1),
+            shellQuote(fn),))
+
+    if configure is not None:
+        configure_args = [
+            "--prefix=/usr/local",
+            "--enable-static",
+            "--disable-shared",
+            #"CPP=gcc -arch %s -E"%(' -arch '.join(archList,),),
+        ]
+
+        if 'configure_pre' in recipe:
+            args = list(recipe['configure_pre'])
+            if '--disable-static' in args:
+                configure_args.remove('--enable-static')
+            if '--enable-shared' in args:
+                configure_args.remove('--disable-shared')
+            configure_args.extend(args)
+
+        if recipe.get('useLDFlags', 1):
+            configure_args.extend([
+                "CFLAGS=-arch %s -isysroot %s -I%s/usr/local/include"%(
+                        ' -arch '.join(archList),
+                        shellQuote(SDKPATH)[1:-1],
+                        shellQuote(basedir)[1:-1],),
+                "LDFLAGS=-syslibroot,%s -L%s/usr/local/lib -arch %s"%(
+                    shellQuote(SDKPATH)[1:-1],
+                    shellQuote(basedir)[1:-1],
+                    ' -arch '.join(archList)),
+            ])
+        else:
+            configure_args.extend([
+                "CFLAGS=-arch %s -isysroot %s -I%s/usr/local/include"%(
+                        ' -arch '.join(archList),
+                        shellQuote(SDKPATH)[1:-1],
+                        shellQuote(basedir)[1:-1],),
+            ])
+
+        if 'configure_post' in recipe:
+            configure_args = configure_args = list(recipe['configure_post'])
+
+        configure_args.insert(0, configure)
+        configure_args = [ shellQuote(a) for a in configure_args ]
+
+        print "Running configure for %s"%(name,)
+        runCommand(' '.join(configure_args) + ' 2>&1')
+
+    print "Running install for %s"%(name,)
+    runCommand('{ ' + install + ' ;} 2>&1')
+
+    print "Done %s"%(name,)
+    print ""
+
+    os.chdir(curdir)
+
+def buildLibraries():
+    """
+    Build our dependencies into $WORKDIR/libraries/usr/local
+    """
+    print ""
+    print "Building required libraries"
+    print ""
+    universal = os.path.join(WORKDIR, 'libraries')
+    os.mkdir(universal)
+    os.makedirs(os.path.join(universal, 'usr', 'local', 'lib'))
+    os.makedirs(os.path.join(universal, 'usr', 'local', 'include'))
+
+    for recipe in LIBRARY_RECIPES:
+        buildRecipe(recipe, universal, ARCHLIST)
+
+
+
+def buildPythonDocs():
+    # This stores the documentation as Resources/English.lproj/Docuentation
+    # inside the framwork. pydoc and IDLE will pick it up there.
+    print "Install python documentation"
+    rootDir = os.path.join(WORKDIR, '_root')
+    version = getVersion()
+    docdir = os.path.join(rootDir, 'pydocs')
+
+    name = 'html-%s.tar.bz2'%(getFullVersion(),)
+    sourceArchive = os.path.join(DEPSRC, name)
+    if os.path.exists(sourceArchive):
+        print "Using local copy of %s"%(name,)
+
+    else:
+        print "Downloading %s"%(name,)
+        downloadURL('http://www.python.org/ftp/python/doc/%s/%s'%(
+            getFullVersion(), name), sourceArchive)
+        print "Archive for %s stored as %s"%(name, sourceArchive)
+
+    extractArchive(os.path.dirname(docdir), sourceArchive)
+    os.rename(
+            os.path.join(
+                os.path.dirname(docdir), 'Python-Docs-%s'%(getFullVersion(),)),
+            docdir)
+
+
+def buildPython():
+    print "Building a universal python"
+
+    buildDir = os.path.join(WORKDIR, '_bld', 'python')
+    rootDir = os.path.join(WORKDIR, '_root')
+
+    if os.path.exists(buildDir):
+        shutil.rmtree(buildDir)
+    if os.path.exists(rootDir):
+        shutil.rmtree(rootDir)
+    os.mkdir(buildDir)
+    os.mkdir(rootDir)
+    os.mkdir(os.path.join(rootDir, 'empty-dir'))
+    curdir = os.getcwd()
+    os.chdir(buildDir)
+
+    # Not sure if this is still needed, the original build script
+    # claims that parts of the install assume python.exe exists.
+    os.symlink('python', os.path.join(buildDir, 'python.exe'))
+
+    # Extract the version from the configure file, needed to calculate
+    # several paths.
+    version = getVersion()
+
+    print "Running configure..."
+    runCommand("%s -C --enable-framework --enable-universalsdk=%s LDFLAGS='-g -L%s/libraries/usr/local/lib' OPT='-g -O3 -I%s/libraries/usr/local/include' 2>&1"%(
+        shellQuote(os.path.join(SRCDIR, 'configure')),
+        shellQuote(SDKPATH), shellQuote(WORKDIR)[1:-1],
+        shellQuote(WORKDIR)[1:-1]))
+
+    print "Running make"
+    runCommand("make")
+
+    print "Running make frameworkinstall"
+    runCommand("make frameworkinstall DESTDIR=%s"%(
+        shellQuote(rootDir)))
+
+    print "Running make frameworkinstallextras"
+    runCommand("make frameworkinstallextras DESTDIR=%s"%(
+        shellQuote(rootDir)))
+
+    print "Copying required shared libraries"
+    if os.path.exists(os.path.join(WORKDIR, 'libraries', 'Library')):
+        runCommand("mv %s/* %s"%(
+            shellQuote(os.path.join(
+                WORKDIR, 'libraries', 'Library', 'Frameworks',
+                'Python.framework', 'Versions', getVersion(),
+                'lib')),
+            shellQuote(os.path.join(WORKDIR, '_root', 'Library', 'Frameworks',
+                'Python.framework', 'Versions', getVersion(),
+                'lib'))))
+
+    print "Fix file modes"
+    frmDir = os.path.join(rootDir, 'Library', 'Frameworks', 'Python.framework')
+    gid = grp.getgrnam('admin').gr_gid
+
+    for dirpath, dirnames, filenames in os.walk(frmDir):
+        for dn in dirnames:
+            os.chmod(os.path.join(dirpath, dn), 0775)
+            os.chown(os.path.join(dirpath, dn), -1, gid)
+            
+
+        for fn in filenames:
+            if os.path.islink(fn):
+                continue
+
+            # "chmod g+w $fn"
+            p = os.path.join(dirpath, fn)
+            st = os.stat(p)
+            os.chmod(p, stat.S_IMODE(st.st_mode) | stat.S_IWGRP)
+            os.chown(p, -1, gid)
+
+    # We added some directories to the search path during the configure
+    # phase. Remove those because those directories won't be there on
+    # the end-users system.
+    path =os.path.join(rootDir, 'Library', 'Frameworks', 'Python.framework',
+                'Versions', version, 'lib', 'python%s'%(version,),
+                'config', 'Makefile')
+    fp = open(path, 'r')
+    data = fp.read()
+    fp.close()
+
+    data = data.replace('-L%s/libraries/usr/local/lib'%(WORKDIR,), '')
+    data = data.replace('-I%s/libraries/usr/local/include'%(WORKDIR,), '')
+    fp = open(path, 'w')
+    fp.write(data)
+    fp.close()
+
+    # Add symlinks in /usr/local/bin, using relative links
+    usr_local_bin = os.path.join(rootDir, 'usr', 'local', 'bin')
+    to_framework = os.path.join('..', '..', '..', 'Library', 'Frameworks',
+            'Python.framework', 'Versions', version, 'bin')
+    if os.path.exists(usr_local_bin):
+        shutil.rmtree(usr_local_bin)
+    os.makedirs(usr_local_bin)
+    for fn in os.listdir(
+                os.path.join(frmDir, 'Versions', version, 'bin')):
+        os.symlink(os.path.join(to_framework, fn),
+                   os.path.join(usr_local_bin, fn))
+
+    os.chdir(curdir)
+
+
+
+def patchFile(inPath, outPath):
+    data = fileContents(inPath)
+    data = data.replace('$FULL_VERSION', getFullVersion())
+    data = data.replace('$VERSION', getVersion())
+    data = data.replace('$MACOSX_DEPLOYMENT_TARGET', '10.3 or later')
+    data = data.replace('$ARCHITECTURES', "i386, ppc")
+    data = data.replace('$INSTALL_SIZE', installSize())
+
+    # This one is not handy as a template variable
+    data = data.replace('$PYTHONFRAMEWORKINSTALLDIR', '/Library/Frameworks/Python.framework')
+    fp = open(outPath, 'wb')
+    fp.write(data)
+    fp.close()
+
+def patchScript(inPath, outPath):
+    data = fileContents(inPath)
+    data = data.replace('@PYVER@', getVersion())
+    fp = open(outPath, 'wb')
+    fp.write(data)
+    fp.close()
+    os.chmod(outPath, 0755)
+
+
+
+def packageFromRecipe(targetDir, recipe):
+    curdir = os.getcwd()
+    try:
+        # The major version (such as 2.5) is included in the package name
+        # because having two version of python installed at the same time is
+        # common.
+        pkgname = '%s-%s'%(recipe['name'], getVersion())
+        srcdir  = recipe.get('source')
+        pkgroot = recipe.get('topdir', srcdir)
+        postflight = recipe.get('postflight')
+        readme = textwrap.dedent(recipe['readme'])
+        isRequired = recipe.get('required', True)
+
+        print "- building package %s"%(pkgname,)
+
+        # Substitute some variables
+        textvars = dict(
+            VER=getVersion(),
+            FULLVER=getFullVersion(),
+        )
+        readme = readme % textvars
+
+        if pkgroot is not None:
+            pkgroot = pkgroot % textvars
+        else:
+            pkgroot = '/'
+
+        if srcdir is not None:
+            srcdir = os.path.join(WORKDIR, '_root', srcdir[1:])
+            srcdir = srcdir % textvars
+
+        if postflight is not None:
+            postflight = os.path.abspath(postflight)
+
+        packageContents = os.path.join(targetDir, pkgname + '.pkg', 'Contents')
+        os.makedirs(packageContents)
+
+        if srcdir is not None:
+            os.chdir(srcdir)
+            runCommand("pax -wf %s . 2>&1"%(shellQuote(os.path.join(packageContents, 'Archive.pax')),))
+            runCommand("gzip -9 %s 2>&1"%(shellQuote(os.path.join(packageContents, 'Archive.pax')),))
+            runCommand("mkbom . %s 2>&1"%(shellQuote(os.path.join(packageContents, 'Archive.bom')),))
+
+        fn = os.path.join(packageContents, 'PkgInfo')
+        fp = open(fn, 'w')
+        fp.write('pmkrpkg1')
+        fp.close()
+
+        rsrcDir = os.path.join(packageContents, "Resources")
+        os.mkdir(rsrcDir)
+        fp = open(os.path.join(rsrcDir, 'ReadMe.txt'), 'w')
+        fp.write(readme)
+        fp.close()
+
+        if postflight is not None:
+            patchScript(postflight, os.path.join(rsrcDir, 'postflight'))
+
+        vers = getFullVersion()
+        major, minor = map(int, getVersion().split('.', 2))
+        pl = Plist(
+                CFBundleGetInfoString="MacPython.%s %s"%(pkgname, vers,),
+                CFBundleIdentifier='org.python.MacPython.%s'%(pkgname,),
+                CFBundleName='MacPython.%s'%(pkgname,),
+                CFBundleShortVersionString=vers,
+                IFMajorVersion=major,
+                IFMinorVersion=minor,
+                IFPkgFormatVersion=0.10000000149011612,
+                IFPkgFlagAllowBackRev=False,
+                IFPkgFlagAuthorizationAction="RootAuthorization",
+                IFPkgFlagDefaultLocation=pkgroot,
+                IFPkgFlagFollowLinks=True,
+                IFPkgFlagInstallFat=True,
+                IFPkgFlagIsRequired=isRequired,
+                IFPkgFlagOverwritePermissions=False,
+                IFPkgFlagRelocatable=False,
+                IFPkgFlagRestartAction="NoRestart",
+                IFPkgFlagRootVolumeOnly=True,
+                IFPkgFlagUpdateInstalledLangauges=False,
+            )
+        writePlist(pl, os.path.join(packageContents, 'Info.plist'))
+
+        pl = Plist(
+                    IFPkgDescriptionDescription=readme,
+                    IFPkgDescriptionTitle=recipe.get('long_name', "MacPython.%s"%(pkgname,)),
+                    IFPkgDescriptionVersion=vers,
+                )
+        writePlist(pl, os.path.join(packageContents, 'Resources', 'Description.plist'))
+
+    finally:
+        os.chdir(curdir)
+
+
+def makeMpkgPlist(path):
+
+    vers = getFullVersion()
+    major, minor = map(int, getVersion().split('.', 2))
+
+    pl = Plist(
+            CFBundleGetInfoString="MacPython %s"%(vers,),
+            CFBundleIdentifier='org.python.MacPython',
+            CFBundleName='MacPython',
+            CFBundleShortVersionString=vers,
+            IFMajorVersion=major,
+            IFMinorVersion=minor,
+            IFPkgFlagComponentDirectory="Contents/Packages",
+            IFPkgFlagPackageList=[
+                dict(
+                    IFPkgFlagPackageLocation='%s-%s.pkg'%(item['name'], getVersion()),
+                    IFPkgFlagPackageSelection='selected'
+                )
+                for item in PKG_RECIPES
+            ],
+            IFPkgFormatVersion=0.10000000149011612,
+            IFPkgFlagBackgroundScaling="proportional",
+            IFPkgFlagBackgroundAlignment="left",
+            IFPkgFlagAuthorizationAction="RootAuthorization",
+        )
+
+    writePlist(pl, path)
+
+
+def buildInstaller():
+
+    # Zap all compiled files
+    for dirpath, _, filenames in os.walk(os.path.join(WORKDIR, '_root')):
+        for fn in filenames:
+            if fn.endswith('.pyc') or fn.endswith('.pyo'):
+                os.unlink(os.path.join(dirpath, fn))
+
+    outdir = os.path.join(WORKDIR, 'installer')
+    if os.path.exists(outdir):
+        shutil.rmtree(outdir)
+    os.mkdir(outdir)
+
+    pkgroot = os.path.join(outdir, 'MacPython.mpkg', 'Contents')
+    pkgcontents = os.path.join(pkgroot, 'Packages')
+    os.makedirs(pkgcontents)
+    for recipe in PKG_RECIPES:
+        packageFromRecipe(pkgcontents, recipe)
+
+    rsrcDir = os.path.join(pkgroot, 'Resources')
+
+    fn = os.path.join(pkgroot, 'PkgInfo')
+    fp = open(fn, 'w')
+    fp.write('pmkrpkg1')
+    fp.close()
+
+    os.mkdir(rsrcDir)
+
+    makeMpkgPlist(os.path.join(pkgroot, 'Info.plist'))
+    pl = Plist(
+                IFPkgDescriptionTitle="Universal MacPython",
+                IFPkgDescriptionVersion=getVersion(),
+            )
+
+    writePlist(pl, os.path.join(pkgroot, 'Resources', 'Description.plist'))
+    for fn in os.listdir('resources'):
+        if fn == '.svn': continue
+        if fn.endswith('.jpg'):
+            shutil.copy(os.path.join('resources', fn), os.path.join(rsrcDir, fn))
+        else:
+            patchFile(os.path.join('resources', fn), os.path.join(rsrcDir, fn))
+
+    shutil.copy("../../LICENSE", os.path.join(rsrcDir, 'License.txt'))
+
+
+def installSize(clear=False, _saved=[]):
+    if clear:
+        del _saved[:]
+    if not _saved:
+        data = captureCommand("du -ks %s"%(
+                    shellQuote(os.path.join(WORKDIR, '_root'))))
+        _saved.append("%d"%((0.5 + (int(data.split()[0]) / 1024.0)),))
+    return _saved[0]
+
+
+def buildDMG():
+    """
+    Create DMG containing the rootDir.
+    """
+    outdir = os.path.join(WORKDIR, 'diskimage')
+    if os.path.exists(outdir):
+        shutil.rmtree(outdir)
+
+    imagepath = os.path.join(outdir,
+                    'python-%s-macosx'%(getFullVersion(),))
+    if INCLUDE_TIMESTAMP:
+        imagepath = imagepath + '%04d-%02d-%02d'%(time.localtime()[:3])
+    imagepath = imagepath + '.dmg'
+
+    os.mkdir(outdir)
+    runCommand("hdiutil create -volname 'Universal MacPython %s' -srcfolder %s %s"%(
+            getFullVersion(),
+            shellQuote(os.path.join(WORKDIR, 'installer')),
+            shellQuote(imagepath)))
+
+    return imagepath
+
+
+def setIcon(filePath, icnsPath):
+    """
+    Set the custom icon for the specified file or directory.
+
+    For a directory the icon data is written in a file named 'Icon\r' inside
+    the directory. For both files and directories write the icon as an 'icns'
+    resource. Furthermore set kHasCustomIcon in the finder flags for filePath.
+    """
+    ref, isDirectory = Carbon.File.FSPathMakeRef(icnsPath)
+    icon = Carbon.Icn.ReadIconFile(ref)
+    del ref
+
+    #
+    # Open the resource fork of the target, to add the icon later on.
+    # For directories we use the file 'Icon\r' inside the directory.
+    #
+
+    ref, isDirectory = Carbon.File.FSPathMakeRef(filePath)
+
+    if isDirectory:
+        # There is a problem with getting this into the pax(1) archive,
+        # just ignore directory icons for now.
+        return
+
+        tmpPath = os.path.join(filePath, "Icon\r")
+        if not os.path.exists(tmpPath):
+            fp = open(tmpPath, 'w')
+            fp.close()
+
+        tmpRef, _ = Carbon.File.FSPathMakeRef(tmpPath)
+        spec = Carbon.File.FSSpec(tmpRef)
+
+    else:
+        spec = Carbon.File.FSSpec(ref)
+
+    try:
+        Carbon.Res.HCreateResFile(*spec.as_tuple())
+    except MacOS.Error:
+        pass
+
+    # Try to create the resource fork again, this will avoid problems
+    # when adding an icon to a directory. I have no idea why this helps,
+    # but without this adding the icon to a directory will fail sometimes.
+    try:
+        Carbon.Res.HCreateResFile(*spec.as_tuple())
+    except MacOS.Error:
+        pass
+
+    refNum = Carbon.Res.FSpOpenResFile(spec, fsRdWrPerm)
+
+    Carbon.Res.UseResFile(refNum)
+
+    # Check if there already is an icon, remove it if there is.
+    try:
+        h = Carbon.Res.Get1Resource('icns', kCustomIconResource)
+    except MacOS.Error:
+        pass
+
+    else:
+        h.RemoveResource()
+        del h
+
+    # Add the icon to the resource for of the target
+    res = Carbon.Res.Resource(icon)
+    res.AddResource('icns', kCustomIconResource, '')
+    res.WriteResource()
+    res.DetachResource()
+    Carbon.Res.CloseResFile(refNum)
+
+    # And now set the kHasCustomIcon property for the target. Annoyingly,
+    # python doesn't seem to have bindings for the API that is needed for
+    # this. Cop out and call SetFile
+    os.system("/Developer/Tools/SetFile -a C %s"%(
+            shellQuote(filePath),))
+
+    if isDirectory:
+        os.system('/Developer/Tools/SetFile -a V %s'%(
+            shellQuote(tmpPath),
+        ))
+
+def main():
+    # First parse options and check if we can perform our work
+    parseOptions()
+    checkEnvironment()
+
+    os.environ['MACOSX_DEPLOYMENT_TARGET'] = '10.3'
+
+    if os.path.exists(WORKDIR):
+        shutil.rmtree(WORKDIR)
+    os.mkdir(WORKDIR)
+
+    # Then build third-party libraries such as sleepycat DB4.
+    buildLibraries()
+
+    # Now build python itself
+    buildPython()
+    buildPythonDocs()
+    fn = os.path.join(WORKDIR, "_root", "Applications",
+                "MacPython %s"%(getVersion(),), "Update Shell Profile.command")
+    patchFile("scripts/postflight.patch-profile",  fn)
+    os.chmod(fn, 0755)
+
+    folder = os.path.join(WORKDIR, "_root", "Applications", "MacPython %s"%(
+        getVersion(),))
+    os.chmod(folder, 0755)
+    setIcon(folder, "../Icons/Python Folder.icns")
+
+    # Create the installer
+    buildInstaller()
+
+    # And copy the readme into the directory containing the installer
+    patchFile('resources/ReadMe.txt', os.path.join(WORKDIR, 'installer', 'ReadMe.txt'))
+
+    # Ditto for the license file.
+    shutil.copy('../../LICENSE', os.path.join(WORKDIR, 'installer', 'License.txt'))
+
+    fp = open(os.path.join(WORKDIR, 'installer', 'Build.txt'), 'w')
+    print >> fp, "# BUILD INFO"
+    print >> fp, "# Date:", time.ctime()
+    print >> fp, "# By:", pwd.getpwuid(os.getuid()).pw_gecos
+    fp.close()
+
+    # Custom icon for the DMG, shown when the DMG is mounted.
+    shutil.copy("../Icons/Disk Image.icns",
+            os.path.join(WORKDIR, "installer", ".VolumeIcon.icns"))
+    os.system("/Developer/Tools/SetFile -a C %s"%(
+            os.path.join(WORKDIR, "installer", ".VolumeIcon.icns")))
+
+
+    # And copy it to a DMG
+    buildDMG()
+
+
+if __name__ == "__main__":
+    main()


Property changes on: vendor/Python/current/Mac/BuildScript/build-installer.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Mac/BuildScript/ncurses-5.5.patch
===================================================================
--- vendor/Python/current/Mac/BuildScript/ncurses-5.5.patch	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/BuildScript/ncurses-5.5.patch	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,36 @@
+diff -r -u ncurses-5.5-orig/test/Makefile.in ncurses-5.5/test/Makefile.in
+--- ncurses-5.5-orig/test/Makefile.in	2006-03-24 12:47:40.000000000 +0100
++++ ncurses-5.5/test/Makefile.in	2006-03-24 12:47:50.000000000 +0100
+@@ -75,7 +75,7 @@
+ MATH_LIB	= @MATH_LIB@
+ 
+ LD		= @LD@
+-LINK		= @LINK_TESTS@ $(LIBTOOL_LINK) $(CC) $(CFLAGS)
++LINK		= @LINK_TESTS@ $(LIBTOOL_LINK) $(CC) 
+ 
+ usFLAGS		= @LD_MODEL@ @LOCAL_LDFLAGS@ @LDFLAGS@
+ 
+diff -ru ncurses-5.5-orig/ncurses/tinfo/read_entry.c ncurses-5.5/ncurses/tinfo/read_entry.c
+--- ncurses-5.5-orig/ncurses/tinfo/read_entry.c 2004-01-11 02:57:05.000000000 +0100
++++ ncurses-5.5/ncurses/tinfo/read_entry.c      2006-03-25 22:49:39.000000000 +0100
+@@ -474,7 +474,7 @@
+     }
+ 
+     /* truncate the terminal name to prevent buffer overflow */
+-    (void) sprintf(ttn, "%c/%.*s", *tn, (int) sizeof(ttn) - 3, tn);
++    (void) sprintf(ttn, "%x/%.*s", *tn, (int) sizeof(ttn) - 3, tn);
+ 
+     /* This is System V behavior, in conjunction with our requirements for
+      * writing terminfo entries.
+diff -ru ncurses-5.5-orig/configure ncurses-5.5/configure
+--- ncurses-5.5-orig/configure	2005-09-24 23:50:50.000000000 +0200
++++ ncurses-5.5/configure	2006-03-26 22:24:59.000000000 +0200
+@@ -5027,7 +5027,7 @@
+ 	darwin*)
+ 		EXTRA_CFLAGS="-no-cpp-precomp"
+ 		CC_SHARED_OPTS="-dynamic"
+-		MK_SHARED_LIB='$(CC) -dynamiclib -install_name $(DESTDIR)$(libdir)/`basename $@` -compatibility_version $(ABI_VERSION) -current_version $(ABI_VERSION) -o $@'
++		MK_SHARED_LIB='$(CC) $(CFLAGS) -dynamiclib -install_name $(DESTDIR)$(libdir)/`basename $@` -compatibility_version $(ABI_VERSION) -current_version $(ABI_VERSION) -o $@'
+ 		test "$cf_cv_shlib_version" = auto && cf_cv_shlib_version=abi
+ 		cf_cv_shlib_version_infix=yes
+ 		;;

Added: vendor/Python/current/Mac/BuildScript/resources/ReadMe.txt
===================================================================
--- vendor/Python/current/Mac/BuildScript/resources/ReadMe.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/BuildScript/resources/ReadMe.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,31 @@
+This package will install MacPython $FULL_VERSION for Mac OS X
+$MACOSX_DEPLOYMENT_TARGET for the following 
+architecture(s): $ARCHITECTURES.
+
+Separate installers are available for older versions
+of Mac OS X, see the homepage, below.
+
+Installation requires approximately $INSTALL_SIZE MB of disk
+space, ignore the message that it will take zero bytes.
+
+You must install onto your current boot disk, even
+though the installer does not enforce this, otherwise
+things will not work.
+
+MacPython consists of the Python programming language
+interpreter, plus a set of programs to allow easy
+access to it for Mac users (an integrated development
+environment, an applet builder), plus a set of pre-built 
+extension modules that open up specific Macintosh technologies 
+to Python programs (Carbon, AppleScript, Quicktime, more).
+
+The installer puts the applications in "MacPython $VERSION" 
+in your Applications folder, command-line tools in
+/usr/local/bin and the underlying machinery in
+$PYTHONFRAMEWORKINSTALLDIR.
+
+More information on MacPython can be found at
+http://www.cwi.nl/~jack/macpython and
+http://pythonmac.org/.  More information on
+Python in general can be found at
+http://www.python.org.

Added: vendor/Python/current/Mac/BuildScript/resources/Welcome.rtf
===================================================================
--- vendor/Python/current/Mac/BuildScript/resources/Welcome.rtf	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/BuildScript/resources/Welcome.rtf	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,18 @@
+{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf410
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;\f1\fswiss\fcharset77 Helvetica-Bold;}
+{\colortbl;\red255\green255\blue255;}
+\paperw11900\paperh16840\margl1440\margr1440\vieww9920\viewh10660\viewkind0
+\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural
+
+\f0\fs24 \cf0 This package will install 
+\f1\b MacPython $FULL_VERSION
+\f0\b0  for 
+\f1\b Mac OS X $MACOSX_DEPLOYMENT_TARGET
+\f0\b0 .\
+\
+MacPython consists of the Python programming language interpreter, plus a set of programs to allow easy access to it for Mac users (an integrated development environment, an applet builder), plus a set of pre-built extension modules that open up specific Macintosh technologies to Python programs (Carbon, AppleScript, Quicktime, more).\
+\
+See the ReadMe file for more information.\
+\
+\
+This package will by default update your shell profile to ensure that this version of Python is on the search path of your shell. Please deselect the "Shell profile updater" package on the package customization screen  if you want to avoid this modification. }
\ No newline at end of file

Added: vendor/Python/current/Mac/BuildScript/resources/background.jpg
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Mac/BuildScript/resources/background.jpg
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Mac/BuildScript/scripts/postflight.documentation
===================================================================
--- vendor/Python/current/Mac/BuildScript/scripts/postflight.documentation	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/BuildScript/scripts/postflight.documentation	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+PYVER="@PYVER@"
+
+if [ -d /Developer/Documentation ]; then
+	if [ ! -d /Developer/Documentation/Python ]; then
+		mkdir -p /Developer/Documentation/Python
+	fi
+
+	ln -fhs /Library/Frameworks/Python.framework/Versions/${PYVER}/Resources/English.lproj/Documentation "/Developer/Documentation/Python/Reference Documentation @PYVER@"
+fi


Property changes on: vendor/Python/current/Mac/BuildScript/scripts/postflight.documentation
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Mac/BuildScript/scripts/postflight.framework
===================================================================
--- vendor/Python/current/Mac/BuildScript/scripts/postflight.framework	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/BuildScript/scripts/postflight.framework	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,33 @@
+#!/bin/sh
+#
+# Recompile the .py files.
+#
+
+PYVER="@PYVER@"
+FWK="/Library/Frameworks/Python.framework/Versions/@PYVER@"
+
+"${FWK}/bin/python" -Wi -tt \
+    "${FWK}/lib/python${PYVER}/compileall.py" \
+    -x badsyntax -x site-packages \
+    "${FWK}/lib/python${PYVER}"
+
+"${FWK}/bin/python" -Wi -tt -O \
+    "${FWK}/lib/python${PYVER}/compileall.py" \
+    -x badsyntax -x site-packages \
+    "${FWK}/lib/python${PYVER}"
+
+"${FWK}/bin/python" -Wi -tt \
+    "${FWK}/lib/python${PYVER}/compileall.py" \
+    -x badsyntax -x site-packages \
+    "${FWK}/Mac/Tools"
+
+"${FWK}/bin/python" -Wi -tt -O \
+    "${FWK}/lib/python${PYVER}/compileall.py" \
+    -x badsyntax -x site-packages \
+    "${FWK}/Mac/Tools"
+
+
+chown -R admin "${FWK}"
+chmod -R g+w "${FWK}"
+
+exit 0


Property changes on: vendor/Python/current/Mac/BuildScript/scripts/postflight.framework
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Mac/BuildScript/scripts/postflight.patch-profile
===================================================================
--- vendor/Python/current/Mac/BuildScript/scripts/postflight.patch-profile	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/BuildScript/scripts/postflight.patch-profile	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,96 @@
+#!/bin/sh
+
+echo "This script will update your shell profile when the 'bin' directory"
+echo "of python is not early enough of the PATH of your shell."
+echo "These changes will be effective only in shell windows that you open"
+echo "after running this script."
+
+PYVER=2.5
+PYTHON_ROOT="/Library/Frameworks/Python.framework/Versions/Current"
+
+if [ `id -ur` = 0 ]; then
+	# Run from the installer, do some trickery to fetch the information
+	# we need.
+	theShell="`finger $USER | grep Shell: | head  -1 | awk '{ print $NF }'`"
+
+else
+	theShell="${SHELL}"
+fi
+
+# Make sure the directory ${PYTHON_ROOT}/bin is on the users PATH.
+BSH="`basename "${theShell}"`"
+case "${BSH}" in
+bash|ksh|sh|*csh)
+	if [ `id -ur` = 0 ]; then
+		P=`su - ${USER} -c 'echo A-X-4-X@@$PATH@@X-4-X-A' | grep 'A-X-4-X@@.*@@X-4-X-A' | sed -e 's/^A-X-4-X@@//g' -e 's/@@X-4-X-A$//g'`
+	else
+		P="`(exec -l ${theShell} -c 'echo $PATH')`"
+	fi
+	;;
+*)
+	echo "Sorry, I don't know how to patch $BSH shells"
+	exit 0
+	;;
+esac
+
+# Now ensure that our bin directory is on $P and before /usr/bin at that
+for elem in `echo $P | tr ':' ' '`
+do
+	if [ "${elem}" == "${PYTHON_ROOT}/bin" ]; then
+		echo "All right, you're a python lover already"
+		exit 0
+	elif [ "${elem}" == "/usr/bin" ]; then
+		break
+	fi
+done
+
+echo "${PYTHON_ROOT}/bin is not on your PATH or at least not early enough"
+case "${BSH}" in
+*csh)
+	if [ -f "${HOME}/.tcshrc" ]; then
+		RC="${HOME}/.tcshrc"
+	else
+		RC="${HOME}/.cshrc"
+	fi
+	# Create backup copy before patching
+	if [ -f "${RC}" ]; then
+		cp -fp "${RC}" "${RC}.pysave"
+	fi
+	echo "" >> "${RC}"
+	echo "# Setting PATH for MacPython ${PYVER}" >> "${RC}"
+	echo "# The orginal version is saved in .cshrc.pysave" >> "${RC}"
+	echo "set path=(${PYTHON_ROOT}/bin "'$path'")" >> "${RC}"
+	if [ `id -ur` = 0 ]; then
+		chown "${USER}" "${RC}"
+	fi
+	exit 0
+	;;
+bash)
+	if [ -e "${HOME}/.bash_profile" ]; then
+		PR="${HOME}/.bash_profile"
+	elif [ -e "${HOME}/.bash_login" ]; then
+		PR="${HOME}/.bash_login"
+	elif [ -e "${HOME}/.profile" ]; then
+		PR="${HOME}/.profile"
+	else
+		PR="${HOME}/.bash_profile"
+	fi
+	;;
+*sh)
+	PR="${HOME}/.profile"
+	;;
+esac
+
+# Create backup copy before patching
+if [ -f "${PR}" ]; then
+	cp -fp "${PR}" "${PR}.pysave"
+fi
+echo "" >> "${PR}"
+echo "# Setting PATH for MacPython ${PYVER}" >> "${PR}"
+echo "# The orginal version is saved in `basename ${PR}`.pysave" >> "${PR}"
+echo 'PATH="'"${PYTHON_ROOT}/bin"':${PATH}"' >> "${PR}"
+echo 'export PATH' >> "${PR}"
+if [ `id -ur` = 0 ]; then
+	chown "${USER}" "${PR}"
+fi
+exit 0


Property changes on: vendor/Python/current/Mac/BuildScript/scripts/postflight.patch-profile
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Mac/Demo/PICTbrowse/ICONbrowse.py
===================================================================
--- vendor/Python/current/Mac/Demo/PICTbrowse/ICONbrowse.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Demo/PICTbrowse/ICONbrowse.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,163 @@
+"""browsepict - Display all "ICON" resources found"""
+
+import FrameWork
+import EasyDialogs
+from Carbon import Res
+from Carbon import Qd
+from Carbon import Win
+from Carbon import Controls
+from Carbon import List
+import sys
+import struct
+from Carbon import Icn
+import macresource
+
+#
+# Resource definitions
+ID_MAIN=512
+MAIN_LIST=1
+MAIN_SHOW=2
+
+# Where is the picture window?
+LEFT=200
+TOP=64
+MINWIDTH=32
+MINHEIGHT=32
+MAXWIDTH=320
+MAXHEIGHT=320
+
+def main():
+    macresource.need('DLOG', ID_MAIN, "PICTbrowse.rsrc")
+    ICONbrowse()
+
+class ICONbrowse(FrameWork.Application):
+    def __init__(self):
+        # First init menus, etc.
+        FrameWork.Application.__init__(self)
+        # Next create our dialog
+        self.main_dialog = MyDialog(self)
+        # Now open the dialog
+        contents = self.findICONresources()
+        self.main_dialog.open(ID_MAIN, contents)
+        # Finally, go into the event loop
+        self.mainloop()
+
+    def makeusermenus(self):
+        self.filemenu = m = FrameWork.Menu(self.menubar, "File")
+        self.quititem = FrameWork.MenuItem(m, "Quit", "Q", self.quit)
+
+    def quit(self, *args):
+        self._quit()
+
+    def showICON(self, resid):
+        w = ICONwindow(self)
+        w.open(resid)
+        #EasyDialogs.Message('Show ICON %r' % (resid,))
+
+    def findICONresources(self):
+        num = Res.CountResources('ICON')
+        rv = []
+        for i in range(1, num+1):
+            Res.SetResLoad(0)
+            try:
+                r = Res.GetIndResource('ICON', i)
+            finally:
+                Res.SetResLoad(1)
+            id, type, name = r.GetResInfo()
+            rv.append((id, name))
+        return rv
+
+class ICONwindow(FrameWork.Window):
+    def open(self, (resid, resname)):
+        if not resname:
+            resname = '#%r' % (resid,)
+        self.resid = resid
+        self.picture = Icn.GetIcon(self.resid)
+        l, t, r, b = 0, 0, 32, 32
+        self.pictrect = (l, t, r, b)
+        width = r-l
+        height = b-t
+        if width < MINWIDTH: width = MINWIDTH
+        elif width > MAXWIDTH: width = MAXWIDTH
+        if height < MINHEIGHT: height = MINHEIGHT
+        elif height > MAXHEIGHT: height = MAXHEIGHT
+        bounds = (LEFT, TOP, LEFT+width, TOP+height)
+
+        self.wid = Win.NewWindow(bounds, resname, 1, 0, -1, 1, 0)
+        self.do_postopen()
+
+    def do_update(self, *args):
+        currect = self.fitrect()
+        Icn.PlotIcon(currect, self.picture)
+
+    def fitrect(self):
+        """Return self.pictrect scaled to fit in window"""
+        graf = self.wid.GetWindowPort()
+        screenrect = graf.GetPortBounds()
+        picwidth = self.pictrect[2] - self.pictrect[0]
+        picheight = self.pictrect[3] - self.pictrect[1]
+        if picwidth > screenrect[2] - screenrect[0]:
+            factor = float(picwidth) / float(screenrect[2]-screenrect[0])
+            picwidth = picwidth / factor
+            picheight = picheight / factor
+        if picheight > screenrect[3] - screenrect[1]:
+            factor = float(picheight) / float(screenrect[3]-screenrect[1])
+            picwidth = picwidth / factor
+            picheight = picheight / factor
+        return (screenrect[0], screenrect[1], screenrect[0]+int(picwidth),
+                        screenrect[1]+int(picheight))
+
+class MyDialog(FrameWork.DialogWindow):
+    "Main dialog window for ICONbrowse"
+
+    def open(self, id, contents):
+        self.id = id
+        FrameWork.DialogWindow.open(self, ID_MAIN)
+        self.dlg.SetDialogDefaultItem(MAIN_SHOW)
+        self.contents = contents
+        self.ctl = self.dlg.GetDialogItemAsControl(MAIN_LIST)
+        h = self.ctl.GetControlData_Handle(Controls.kControlListBoxPart,
+                        Controls.kControlListBoxListHandleTag)
+        self.list = List.as_List(h)
+        self.setlist()
+
+    def setlist(self):
+        self.list.LDelRow(0, 0)
+        self.list.LSetDrawingMode(0)
+        if self.contents:
+            self.list.LAddRow(len(self.contents), 0)
+            for i in range(len(self.contents)):
+                v = repr(self.contents[i][0])
+                if self.contents[i][1]:
+                    v = v + '"' + self.contents[i][1] + '"'
+                self.list.LSetCell(v, (0, i))
+        self.list.LSetDrawingMode(1)
+        self.list.LUpdate(self.wid.GetWindowPort().visRgn)
+
+    def getselection(self):
+        items = []
+        point = (0,0)
+        while 1:
+            ok, point = self.list.LGetSelect(1, point)
+            if not ok:
+                break
+            items.append(point[1])
+            point = point[0], point[1]+1
+        values = []
+        for i in items:
+            values.append(self.contents[i])
+        return values
+
+    def do_show(self, *args):
+        selection = self.getselection()
+        for resid in selection:
+            self.parent.showICON(resid)
+
+    def do_close(self):
+        self.close()
+
+    def do_itemhit(self, item, event):
+        if item == MAIN_SHOW:
+            self.do_show()
+
+main()

Added: vendor/Python/current/Mac/Demo/PICTbrowse/PICTbrowse.py
===================================================================
--- vendor/Python/current/Mac/Demo/PICTbrowse/PICTbrowse.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Demo/PICTbrowse/PICTbrowse.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,141 @@
+"""browsepict - Display all "PICT" resources found"""
+
+import FrameWork
+import EasyDialogs
+from Carbon import Res
+from Carbon import Qd
+from Carbon import Win
+from Carbon import Controls
+from Carbon import List
+import sys
+import struct
+import macresource
+
+#
+# Resource definitions
+ID_MAIN=512
+MAIN_LIST=1
+MAIN_SHOW=2
+
+# Where is the picture window?
+LEFT=200
+TOP=64
+
+def main():
+    macresource.need('DLOG', ID_MAIN, "PICTbrowse.rsrc")
+    PICTbrowse()
+
+class PICTbrowse(FrameWork.Application):
+    def __init__(self):
+        # First init menus, etc.
+        FrameWork.Application.__init__(self)
+        # Next create our dialog
+        self.main_dialog = MyDialog(self)
+        # Now open the dialog
+        contents = self.findPICTresources()
+        self.main_dialog.open(ID_MAIN, contents)
+        # Finally, go into the event loop
+        self.mainloop()
+
+    def makeusermenus(self):
+        self.filemenu = m = FrameWork.Menu(self.menubar, "File")
+        self.quititem = FrameWork.MenuItem(m, "Quit", "Q", self.quit)
+
+    def quit(self, *args):
+        self._quit()
+
+    def showPICT(self, resid):
+        w = PICTwindow(self)
+        w.open(resid)
+        #EasyDialogs.Message('Show PICT %r' % (resid,))
+
+    def findPICTresources(self):
+        num = Res.CountResources('PICT')
+        rv = []
+        for i in range(1, num+1):
+            Res.SetResLoad(0)
+            try:
+                r = Res.GetIndResource('PICT', i)
+            finally:
+                Res.SetResLoad(1)
+            id, type, name = r.GetResInfo()
+            rv.append((id, name))
+        return rv
+
+class PICTwindow(FrameWork.Window):
+    def open(self, (resid, resname)):
+        if not resname:
+            resname = '#%r' % (resid,)
+        self.resid = resid
+        picture = Qd.GetPicture(self.resid)
+        # Get rect for picture
+        print repr(picture.data[:16])
+        sz, t, l, b, r = struct.unpack('hhhhh', picture.data[:10])
+        print 'pict:', t, l, b, r
+        width = r-l
+        height = b-t
+        if width < 64: width = 64
+        elif width > 480: width = 480
+        if height < 64: height = 64
+        elif height > 320: height = 320
+        bounds = (LEFT, TOP, LEFT+width, TOP+height)
+        print 'bounds:', bounds
+
+        self.wid = Win.NewWindow(bounds, resname, 1, 0, -1, 1, 0)
+        self.wid.SetWindowPic(picture)
+        self.do_postopen()
+
+class MyDialog(FrameWork.DialogWindow):
+    "Main dialog window for PICTbrowse"
+
+    def open(self, id, contents):
+        self.id = id
+        FrameWork.DialogWindow.open(self, ID_MAIN)
+        self.dlg.SetDialogDefaultItem(MAIN_SHOW)
+        self.contents = contents
+        self.ctl = self.dlg.GetDialogItemAsControl(MAIN_LIST)
+        h = self.ctl.GetControlData_Handle(Controls.kControlListBoxPart,
+                        Controls.kControlListBoxListHandleTag)
+        self.list = List.as_List(h)
+        self.setlist()
+
+    def setlist(self):
+        self.list.LDelRow(0, 0)
+        self.list.LSetDrawingMode(0)
+        if self.contents:
+            self.list.LAddRow(len(self.contents), 0)
+            for i in range(len(self.contents)):
+                v = repr(self.contents[i][0])
+                if self.contents[i][1]:
+                    v = v + '"' + self.contents[i][1] + '"'
+                self.list.LSetCell(v, (0, i))
+        self.list.LSetDrawingMode(1)
+        self.list.LUpdate(self.wid.GetWindowPort().visRgn)
+
+    def getselection(self):
+        items = []
+        point = (0,0)
+        while 1:
+            ok, point = self.list.LGetSelect(1, point)
+            if not ok:
+                break
+            items.append(point[1])
+            point = point[0], point[1]+1
+        values = []
+        for i in items:
+            values.append(self.contents[i])
+        return values
+
+    def do_show(self, *args):
+        selection = self.getselection()
+        for resid in selection:
+            self.parent.showPICT(resid)
+
+    def do_close(self):
+        self.close()
+
+    def do_itemhit(self, item, event):
+        if item == MAIN_SHOW:
+            self.do_show()
+
+main()

Added: vendor/Python/current/Mac/Demo/PICTbrowse/PICTbrowse.rsrc
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Mac/Demo/PICTbrowse/PICTbrowse.rsrc
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Mac/Demo/PICTbrowse/PICTbrowse2.py
===================================================================
--- vendor/Python/current/Mac/Demo/PICTbrowse/PICTbrowse2.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Demo/PICTbrowse/PICTbrowse2.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,163 @@
+"""browsepict - Display all "PICT" resources found"""
+
+import FrameWork
+import EasyDialogs
+from Carbon import Res
+from Carbon import Qd
+from Carbon import Win
+from Carbon import Controls
+from Carbon import List
+import sys
+import struct
+import macresource
+
+#
+# Resource definitions
+ID_MAIN=512
+MAIN_LIST=1
+MAIN_SHOW=2
+
+# Where is the picture window?
+LEFT=200
+TOP=64
+MINWIDTH=64
+MINHEIGHT=64
+MAXWIDTH=320
+MAXHEIGHT=320
+
+def main():
+    macresource.need('DLOG', ID_MAIN, "PICTbrowse.rsrc")
+    PICTbrowse()
+
+class PICTbrowse(FrameWork.Application):
+    def __init__(self):
+        # First init menus, etc.
+        FrameWork.Application.__init__(self)
+        # Next create our dialog
+        self.main_dialog = MyDialog(self)
+        # Now open the dialog
+        contents = self.findPICTresources()
+        self.main_dialog.open(ID_MAIN, contents)
+        # Finally, go into the event loop
+        self.mainloop()
+
+    def makeusermenus(self):
+        self.filemenu = m = FrameWork.Menu(self.menubar, "File")
+        self.quititem = FrameWork.MenuItem(m, "Quit", "Q", self.quit)
+
+    def quit(self, *args):
+        self._quit()
+
+    def showPICT(self, resid):
+        w = PICTwindow(self)
+        w.open(resid)
+        #EasyDialogs.Message('Show PICT %r' % (resid,))
+
+    def findPICTresources(self):
+        num = Res.CountResources('PICT')
+        rv = []
+        for i in range(1, num+1):
+            Res.SetResLoad(0)
+            try:
+                r = Res.GetIndResource('PICT', i)
+            finally:
+                Res.SetResLoad(1)
+            id, type, name = r.GetResInfo()
+            rv.append((id, name))
+        return rv
+
+class PICTwindow(FrameWork.Window):
+    def open(self, (resid, resname)):
+        if not resname:
+            resname = '#%r' % (resid,)
+        self.resid = resid
+        self.picture = Qd.GetPicture(self.resid)
+        # Get rect for picture
+        sz, t, l, b, r = struct.unpack('hhhhh', self.picture.data[:10])
+        self.pictrect = (l, t, r, b)
+        width = r-l
+        height = b-t
+        if width < MINWIDTH: width = MINWIDTH
+        elif width > MAXWIDTH: width = MAXWIDTH
+        if height < MINHEIGHT: height = MINHEIGHT
+        elif height > MAXHEIGHT: height = MAXHEIGHT
+        bounds = (LEFT, TOP, LEFT+width, TOP+height)
+
+        self.wid = Win.NewWindow(bounds, resname, 1, 0, -1, 1, 0)
+        self.do_postopen()
+
+    def do_update(self, *args):
+        currect = self.fitrect()
+        Qd.DrawPicture(self.picture, currect)
+
+    def fitrect(self):
+        """Return self.pictrect scaled to fit in window"""
+        graf = self.dlg.GetWindowPort()
+        screenrect = graf.GetPortBounds()
+        picwidth = self.pictrect[2] - self.pictrect[0]
+        picheight = self.pictrect[3] - self.pictrect[1]
+        if picwidth > screenrect[2] - screenrect[0]:
+            factor = float(picwidth) / float(screenrect[2]-screenrect[0])
+            picwidth = picwidth / factor
+            picheight = picheight / factor
+        if picheight > screenrect[3] - screenrect[1]:
+            factor = float(picheight) / float(screenrect[3]-screenrect[1])
+            picwidth = picwidth / factor
+            picheight = picheight / factor
+        return (screenrect[0], screenrect[1], screenrect[0]+int(picwidth),
+                        screenrect[1]+int(picheight))
+
+class MyDialog(FrameWork.DialogWindow):
+    "Main dialog window for PICTbrowse"
+
+    def open(self, id, contents):
+        self.id = id
+        FrameWork.DialogWindow.open(self, ID_MAIN)
+        self.dlg.SetDialogDefaultItem(MAIN_SHOW)
+        self.contents = contents
+        self.ctl = self.dlg.GetDialogItemAsControl(MAIN_LIST)
+        h = self.ctl.GetControlData_Handle(Controls.kControlListBoxPart,
+                        Controls.kControlListBoxListHandleTag)
+        self.list = List.as_List(h)
+        self.setlist()
+
+    def setlist(self):
+        self.list.LDelRow(0, 0)
+        self.list.LSetDrawingMode(0)
+        if self.contents:
+            self.list.LAddRow(len(self.contents), 0)
+            for i in range(len(self.contents)):
+                v = repr(self.contents[i][0])
+                if self.contents[i][1]:
+                    v = v + '"' + self.contents[i][1] + '"'
+                self.list.LSetCell(v, (0, i))
+        self.list.LSetDrawingMode(1)
+        self.list.LUpdate(self.wid.GetWindowPort().visRgn)
+
+    def getselection(self):
+        items = []
+        point = (0,0)
+        while 1:
+            ok, point = self.list.LGetSelect(1, point)
+            if not ok:
+                break
+            items.append(point[1])
+            point = point[0], point[1]+1
+        values = []
+        for i in items:
+            values.append(self.contents[i])
+        return values
+
+    def do_show(self, *args):
+        selection = self.getselection()
+        for resid in selection:
+            self.parent.showPICT(resid)
+
+    def do_close(self):
+        self.close()
+
+    def do_itemhit(self, item, event):
+        if item == MAIN_SHOW:
+            self.do_show()
+
+main()

Added: vendor/Python/current/Mac/Demo/PICTbrowse/cicnbrowse.py
===================================================================
--- vendor/Python/current/Mac/Demo/PICTbrowse/cicnbrowse.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Demo/PICTbrowse/cicnbrowse.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,163 @@
+"""browsepict - Display all "cicn" resources found"""
+
+import FrameWork
+import EasyDialogs
+from Carbon import Res
+from Carbon import Qd
+from Carbon import Win
+from Carbon import Controls
+from Carbon import List
+import sys
+import struct
+from Carbon import Icn
+import macresource
+
+#
+# Resource definitions
+ID_MAIN=512
+MAIN_LIST=1
+MAIN_SHOW=2
+
+# Where is the picture window?
+LEFT=200
+TOP=64
+MINWIDTH=32
+MINHEIGHT=32
+MAXWIDTH=320
+MAXHEIGHT=320
+
+def main():
+    macresource.need('DLOG', ID_MAIN, "PICTbrowse.rsrc")
+    CIconbrowse()
+
+class CIconbrowse(FrameWork.Application):
+    def __init__(self):
+        # First init menus, etc.
+        FrameWork.Application.__init__(self)
+        # Next create our dialog
+        self.main_dialog = MyDialog(self)
+        # Now open the dialog
+        contents = self.findcicnresources()
+        self.main_dialog.open(ID_MAIN, contents)
+        # Finally, go into the event loop
+        self.mainloop()
+
+    def makeusermenus(self):
+        self.filemenu = m = FrameWork.Menu(self.menubar, "File")
+        self.quititem = FrameWork.MenuItem(m, "Quit", "Q", self.quit)
+
+    def quit(self, *args):
+        self._quit()
+
+    def showCIcon(self, resid):
+        w = CIconwindow(self)
+        w.open(resid)
+        #EasyDialogs.Message('Show cicn %r' % (resid,))
+
+    def findcicnresources(self):
+        num = Res.CountResources('cicn')
+        rv = []
+        for i in range(1, num+1):
+            Res.SetResLoad(0)
+            try:
+                r = Res.GetIndResource('cicn', i)
+            finally:
+                Res.SetResLoad(1)
+            id, type, name = r.GetResInfo()
+            rv.append((id, name))
+        return rv
+
+class CIconwindow(FrameWork.Window):
+    def open(self, (resid, resname)):
+        if not resname:
+            resname = '#%r' % (resid,)
+        self.resid = resid
+        self.picture = Icn.GetCIcon(self.resid)
+        l, t, r, b = 0, 0, 32, 32
+        self.pictrect = (l, t, r, b)
+        width = r-l
+        height = b-t
+        if width < MINWIDTH: width = MINWIDTH
+        elif width > MAXWIDTH: width = MAXWIDTH
+        if height < MINHEIGHT: height = MINHEIGHT
+        elif height > MAXHEIGHT: height = MAXHEIGHT
+        bounds = (LEFT, TOP, LEFT+width, TOP+height)
+
+        self.wid = Win.NewWindow(bounds, resname, 1, 0, -1, 1, 0)
+        self.do_postopen()
+
+    def do_update(self, *args):
+        currect = self.fitrect()
+        Icn.PlotCIcon(currect, self.picture)
+
+    def fitrect(self):
+        """Return self.pictrect scaled to fit in window"""
+        graf = self.wid.GetWindowPort()
+        screenrect = graf.GetPortBounds()
+        picwidth = self.pictrect[2] - self.pictrect[0]
+        picheight = self.pictrect[3] - self.pictrect[1]
+        if picwidth > screenrect[2] - screenrect[0]:
+            factor = float(picwidth) / float(screenrect[2]-screenrect[0])
+            picwidth = picwidth / factor
+            picheight = picheight / factor
+        if picheight > screenrect[3] - screenrect[1]:
+            factor = float(picheight) / float(screenrect[3]-screenrect[1])
+            picwidth = picwidth / factor
+            picheight = picheight / factor
+        return (screenrect[0], screenrect[1], screenrect[0]+int(picwidth),
+                        screenrect[1]+int(picheight))
+
+class MyDialog(FrameWork.DialogWindow):
+    "Main dialog window for cicnbrowse"
+
+    def open(self, id, contents):
+        self.id = id
+        FrameWork.DialogWindow.open(self, ID_MAIN)
+        self.dlg.SetDialogDefaultItem(MAIN_SHOW)
+        self.contents = contents
+        self.ctl = self.dlg.GetDialogItemAsControl(MAIN_LIST)
+        h = self.ctl.GetControlData_Handle(Controls.kControlListBoxPart,
+                        Controls.kControlListBoxListHandleTag)
+        self.list = List.as_List(h)
+        self.setlist()
+
+    def setlist(self):
+        self.list.LDelRow(0, 0)
+        self.list.LSetDrawingMode(0)
+        if self.contents:
+            self.list.LAddRow(len(self.contents), 0)
+            for i in range(len(self.contents)):
+                v = repr(self.contents[i][0])
+                if self.contents[i][1]:
+                    v = v + '"' + self.contents[i][1] + '"'
+                self.list.LSetCell(v, (0, i))
+        self.list.LSetDrawingMode(1)
+        self.list.LUpdate(self.wid.GetWindowPort().visRgn)
+
+    def getselection(self):
+        items = []
+        point = (0,0)
+        while 1:
+            ok, point = self.list.LGetSelect(1, point)
+            if not ok:
+                break
+            items.append(point[1])
+            point = point[0], point[1]+1
+        values = []
+        for i in items:
+            values.append(self.contents[i])
+        return values
+
+    def do_show(self, *args):
+        selection = self.getselection()
+        for resid in selection:
+            self.parent.showCIcon(resid)
+
+    def do_close(self):
+        self.close()
+
+    def do_itemhit(self, item, event):
+        if item == MAIN_SHOW:
+            self.do_show()
+
+main()

Added: vendor/Python/current/Mac/Demo/PICTbrowse/oldPICTbrowse.py
===================================================================
--- vendor/Python/current/Mac/Demo/PICTbrowse/oldPICTbrowse.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Demo/PICTbrowse/oldPICTbrowse.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,159 @@
+"""browsepict - Display all "PICT" resources found"""
+
+import FrameWork
+import EasyDialogs
+from Carbon import Res
+from Carbon import Qd
+from Carbon import Win
+from Carbon import List
+import sys
+import struct
+import macresource
+
+#
+# Resource definitions
+ID_MAIN=512
+MAIN_LIST=1
+MAIN_SHOW=2
+
+# Where is the picture window?
+LEFT=200
+TOP=64
+
+def main():
+    macresource.need('DLOG', ID_MAIN, "oldPICTbrowse.rsrc")
+    PICTbrowse()
+
+class PICTbrowse(FrameWork.Application):
+    def __init__(self):
+        # First init menus, etc.
+        FrameWork.Application.__init__(self)
+        # Next create our dialog
+        self.main_dialog = MyDialog(self)
+        # Now open the dialog
+        contents = self.findPICTresources()
+        self.main_dialog.open(ID_MAIN, contents)
+        # Finally, go into the event loop
+        self.mainloop()
+
+    def makeusermenus(self):
+        self.filemenu = m = FrameWork.Menu(self.menubar, "File")
+        self.quititem = FrameWork.MenuItem(m, "Quit", "Q", self.quit)
+
+    def quit(self, *args):
+        self._quit()
+
+    def showPICT(self, resid):
+        w = PICTwindow(self)
+        w.open(resid)
+        #EasyDialogs.Message('Show PICT %r' % (resid,))
+
+    def findPICTresources(self):
+        num = Res.CountResources('PICT')
+        rv = []
+        for i in range(1, num+1):
+            Res.SetResLoad(0)
+            try:
+                r = Res.GetIndResource('PICT', i)
+            finally:
+                Res.SetResLoad(1)
+            id, type, name = r.GetResInfo()
+            rv.append((id, name))
+        return rv
+
+class PICTwindow(FrameWork.Window):
+    def open(self, (resid, resname)):
+        if not resname:
+            resname = '#%r' % (resid,)
+        self.resid = resid
+        picture = Qd.GetPicture(self.resid)
+        # Get rect for picture
+        print repr(picture.data[:16])
+        sz, t, l, b, r = struct.unpack('hhhhh', picture.data[:10])
+        print 'pict:', t, l, b, r
+        width = r-l
+        height = b-t
+        if width < 64: width = 64
+        elif width > 480: width = 480
+        if height < 64: height = 64
+        elif height > 320: height = 320
+        bounds = (LEFT, TOP, LEFT+width, TOP+height)
+        print 'bounds:', bounds
+
+        self.wid = Win.NewWindow(bounds, resname, 1, 0, -1, 1, 0)
+        self.wid.SetWindowPic(picture)
+        self.do_postopen()
+
+class MyDialog(FrameWork.DialogWindow):
+    "Main dialog window for PICTbrowse"
+
+    def open(self, id, contents):
+        self.id = id
+        FrameWork.DialogWindow.open(self, ID_MAIN)
+        self.dlg.SetDialogDefaultItem(MAIN_SHOW)
+        tp, h, rect = self.dlg.GetDialogItem(MAIN_LIST)
+        rect2 = rect[0]+1, rect[1]+1, rect[2]-17, rect[3]-17    # Scroll bar space
+        self.list = List.LNew(rect2, (0, 0, 1, len(contents)), (0,0), 0, self.wid,
+                        0, 1, 1, 1)
+        self.contents = contents
+        self.setlist()
+
+    def setlist(self):
+        self.list.LDelRow(0, 0)
+        self.list.LSetDrawingMode(0)
+        if self.contents:
+            self.list.LAddRow(len(self.contents), 0)
+            for i in range(len(self.contents)):
+                v = repr(self.contents[i][0])
+                if self.contents[i][1]:
+                    v = v + '"' + self.contents[i][1] + '"'
+                self.list.LSetCell(v, (0, i))
+        self.list.LSetDrawingMode(1)
+        self.list.LUpdate(self.wid.GetWindowPort().visRgn)
+
+    def do_listhit(self, event):
+        (what, message, when, where, modifiers) = event
+        Qd.SetPort(self.wid)
+        where = Qd.GlobalToLocal(where)
+        print 'LISTHIT', where
+        if self.list.LClick(where, modifiers):
+            self.do_show()
+
+    def getselection(self):
+        items = []
+        point = (0,0)
+        while 1:
+            ok, point = self.list.LGetSelect(1, point)
+            if not ok:
+                break
+            items.append(point[1])
+            point = point[0], point[1]+1
+        values = []
+        for i in items:
+            values.append(self.contents[i])
+        return values
+
+    def do_show(self, *args):
+        selection = self.getselection()
+        for resid in selection:
+            self.parent.showPICT(resid)
+
+    def do_rawupdate(self, window, event):
+        tp, h, rect = self.dlg.GetDialogItem(MAIN_LIST)
+        Qd.SetPort(self.wid)
+        Qd.FrameRect(rect)
+        self.list.LUpdate(self.wid.GetWindowPort().visRgn)
+
+    def do_activate(self, activate, event):
+        self.list.LActivate(activate)
+
+    def do_close(self):
+        self.close()
+
+    def do_itemhit(self, item, event):
+        if item == MAIN_LIST:
+            self.do_listhit(event)
+        if item == MAIN_SHOW:
+            self.do_show()
+
+main()

Added: vendor/Python/current/Mac/Demo/PICTbrowse/oldPICTbrowse.rsrc
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Mac/Demo/PICTbrowse/oldPICTbrowse.rsrc
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Mac/Demo/applescript/Disk_Copy/Special_Events.py
===================================================================
--- vendor/Python/current/Mac/Demo/applescript/Disk_Copy/Special_Events.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Demo/applescript/Disk_Copy/Special_Events.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,424 @@
+"""Suite Special Events: Commands for mounting Disk Copy images
+Level 1, version 1
+
+Generated from Macintosh HD:Hulpprogramma's:Disk Copy
+AETE/AEUT resource version 1/0, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'ddsk'
+
+class Special_Events_Events:
+
+    _argmap_mount = {
+            'access_mode' : 'Acss',
+            'checksum_verification' : 'VChk',
+            'signature_verification' : 'VSig',
+            'RAM_caching' : 'Cach',
+    }
+
+    def mount(self, _object, _attributes={}, **_arguments):
+        """mount: Mounts an Disk Copy image as a disk volume
+        Required argument: a reference to the disk image to be mounted
+        Keyword argument access_mode: the access mode for mounted volume (default is "any", i.e. best possible)
+        Keyword argument checksum_verification: Verify the checksum before mounting?
+        Keyword argument signature_verification: Verify the DigiSignŽ signature before mounting?
+        Keyword argument RAM_caching: Cache the disk image in RAM? (if omitted, don't cache)
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: a reference to mounted disk
+        """
+        _code = 'ddsk'
+        _subcode = 'Moun'
+
+        aetools.keysubst(_arguments, self._argmap_mount)
+        _arguments['----'] = _object
+
+        aetools.enumsubst(_arguments, 'Acss', _Enum_Acss)
+        aetools.enumsubst(_arguments, 'VChk', _Enum_bool)
+        aetools.enumsubst(_arguments, 'VSig', _Enum_bool)
+        aetools.enumsubst(_arguments, 'Cach', _Enum_bool)
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                        _arguments, _attributes)
+        if _arguments.has_key('errn'):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_execute_DiskScript = {
+            'checksum_verification' : 'VChk',
+            'signature_verification' : 'VSig',
+    }
+
+    def execute_DiskScript(self, _object, _attributes={}, **_arguments):
+        """execute DiskScript: Executes a Disk Copy-specific DiskScript
+        Required argument: a reference to the DiskScript to execute
+        Keyword argument checksum_verification: Should checksums be verified when mounting images referenced in the DiskScript?
+        Keyword argument signature_verification: Should the DigiSignŽ signature of the DiskScript and the images it references be verified?
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'ddsk'
+        _subcode = 'XEQd'
+
+        aetools.keysubst(_arguments, self._argmap_execute_DiskScript)
+        _arguments['----'] = _object
+
+        aetools.enumsubst(_arguments, 'VChk', _Enum_bool)
+        aetools.enumsubst(_arguments, 'VSig', _Enum_bool)
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                        _arguments, _attributes)
+        if _arguments.has_key('errn'):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def unmount(self, _object, _attributes={}, **_arguments):
+        """unmount: Unmount and eject (if necessary) a volume
+        Required argument: a reference to disk to be unmounted (and ejected)
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'ddsk'
+        _subcode = 'Umnt'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                        _arguments, _attributes)
+        if _arguments.has_key('errn'):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_create = {
+            'saving_as' : 'SvAs',
+            'logical_blocks' : 'Blks',
+            'zeroing' : 'Zero',
+            'leave_image_mounted' : 'Moun',
+            'filesystem' : 'Fsys',
+    }
+
+    def create(self, _object, _attributes={}, **_arguments):
+        """create: Create a new Disk Copy document
+        Required argument: the name of the volume to create
+        Keyword argument saving_as: the disk image to be created
+        Keyword argument logical_blocks: the number of logical blocks
+        Keyword argument zeroing: Should all blocks on the disk be set to zero?
+        Keyword argument leave_image_mounted: Should the image be mounted after it is created?
+        Keyword argument filesystem: file system to use (Mac OS Standard/compatible, Mac OS Enhanced)
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: a reference to newly created disk image (or newly mounted disk)
+        """
+        _code = 'ddsk'
+        _subcode = 'Crea'
+
+        aetools.keysubst(_arguments, self._argmap_create)
+        _arguments['----'] = _object
+
+        aetools.enumsubst(_arguments, 'SvAs', _Enum_fss_)
+        aetools.enumsubst(_arguments, 'Blks', _Enum_long)
+        aetools.enumsubst(_arguments, 'Zero', _Enum_bool)
+        aetools.enumsubst(_arguments, 'Moun', _Enum_bool)
+        aetools.enumsubst(_arguments, 'Fsys', _Enum_Fsys)
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                        _arguments, _attributes)
+        if _arguments.has_key('errn'):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def verify_checksum(self, _object, _attributes={}, **_arguments):
+        """verify checksum: Verify the checksum of a Disk Copy 4.2 or a Disk Copy 6.0 read-only document
+        Required argument: the disk image to be verified
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: the result of the checksum verification
+        """
+        _code = 'ddsk'
+        _subcode = 'Vcrc'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                        _arguments, _attributes)
+        if _arguments.has_key('errn'):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def verify_signature(self, _object, _attributes={}, **_arguments):
+        """verify signature: Verify the DigiSignŽ signature for a Disk Copy document
+        Required argument: the disk image to be verified
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: Is the DigiSignŽ signature valid?
+        """
+        _code = 'ddsk'
+        _subcode = 'Vsig'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                        _arguments, _attributes)
+        if _arguments.has_key('errn'):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_sign_image = {
+            'using_signer' : 'Sinr',
+    }
+
+    def sign_image(self, _object, _attributes={}, **_arguments):
+        """sign image: Add a DigiSignŽ signature to a Disk Copy document
+        Required argument: the disk image to be signed
+        Keyword argument using_signer: a reference to signer file to use
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'ddsk'
+        _subcode = 'Asig'
+
+        aetools.keysubst(_arguments, self._argmap_sign_image)
+        _arguments['----'] = _object
+
+        aetools.enumsubst(_arguments, 'Sinr', _Enum_alis)
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                        _arguments, _attributes)
+        if _arguments.has_key('errn'):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_create_a_floppy_from = {
+            'signature_verification' : 'VSig',
+            'erase_confirmation' : 'Cfrm',
+            'make_multiple_floppies' : 'Mult',
+    }
+
+    def create_a_floppy_from(self, _object, _attributes={}, **_arguments):
+        """create a floppy from: create a floppy disk from a Disk Copy document
+        Required argument: the disk image to make a floppy from
+        Keyword argument signature_verification: Should the DigiSignŽ signature be verified before creating a floppy disk?
+        Keyword argument erase_confirmation: Should the user be asked to confirm the erasure of the previous contents of floppy disks?
+        Keyword argument make_multiple_floppies: Should the user be prompted to create multiple floppy disks?
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'ddsk'
+        _subcode = 'Bfpy'
+
+        aetools.keysubst(_arguments, self._argmap_create_a_floppy_from)
+        _arguments['----'] = _object
+
+        aetools.enumsubst(_arguments, 'VSig', _Enum_bool)
+        aetools.enumsubst(_arguments, 'Cfrm', _Enum_bool)
+        aetools.enumsubst(_arguments, 'Mult', _Enum_bool)
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                        _arguments, _attributes)
+        if _arguments.has_key('errn'):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_check_image = {
+            'details' : 'ChDe',
+    }
+
+    def check_image(self, _object, _attributes={}, **_arguments):
+        """check image: Check the disk imageÕs internal data structures for any inconsistencies.  Works on NDIF, Disk Copy 4.2, DARTŽ, or DiskSet images.
+        Required argument: the disk image to be verified
+        Keyword argument details: Should the disk image details be displayed?
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: a record containing a boolean (true/false) value if the image passes consistency tests, and the numbers of warnings and errors
+        """
+        _code = 'ddsk'
+        _subcode = 'Chek'
+
+        aetools.keysubst(_arguments, self._argmap_check_image)
+        _arguments['----'] = _object
+
+        aetools.enumsubst(_arguments, 'ChDe', _Enum_bool)
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                        _arguments, _attributes)
+        if _arguments.has_key('errn'):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_segment_image = {
+            'segment_count' : 'SGCT',
+            'segment_size' : 'SGSZ',
+            'segment_name' : 'SGNM',
+            'image_ID' : 'SGID',
+    }
+
+    def segment_image(self, _object, _attributes={}, **_arguments):
+        """segment image: Segment a NDIF R/W or R/O image into smaller pieces
+        Required argument: the disk image to be segmented
+        Keyword argument segment_count: the number of image segments to create
+        Keyword argument segment_size: the size of image segments (in blocks) to create
+        Keyword argument segment_name: the root name for each image segment file
+        Keyword argument image_ID: string used to generate a unique image ID to group the segments
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: a list of references to the image segments created
+        """
+        _code = 'ddsk'
+        _subcode = 'SGMT'
+
+        aetools.keysubst(_arguments, self._argmap_segment_image)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                        _arguments, _attributes)
+        if _arguments.has_key('errn'):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_create_SMI = {
+            'source_images' : 'SMI1',
+            'launching_application' : 'SMI2',
+            'launching_document' : 'SMI3',
+            'version_string' : 'SMI4',
+            'checksum_verification' : 'VChk',
+            'signature_verification' : 'VSig',
+            'image_signing' : 'SImg',
+    }
+
+    def create_SMI(self, _object, _attributes={}, **_arguments):
+        """create SMI: Creates a self-mounting image (SMI) from a list of NDIF disk images
+        Required argument: the self-mounting image to create
+        Keyword argument source_images: a list of references to sources images
+        Keyword argument launching_application: the path to an application to launch
+        Keyword argument launching_document: the path to a document to open
+        Keyword argument version_string: sets the 'vers' 1 resource of the self-mounting image
+        Keyword argument checksum_verification: Should the checksum of the source images be verified before creating the SMI?
+        Keyword argument signature_verification: Should the DigiSignŽ signature of the source images be verified before creating the SMI?
+        Keyword argument image_signing: Should the SMI be given a digital signature when it is created?
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: a reference to the self-mounting image created
+        """
+        _code = 'ddsk'
+        _subcode = 'MSMI'
+
+        aetools.keysubst(_arguments, self._argmap_create_SMI)
+        _arguments['----'] = _object
+
+        aetools.enumsubst(_arguments, 'VChk', _Enum_bool)
+        aetools.enumsubst(_arguments, 'VSig', _Enum_bool)
+        aetools.enumsubst(_arguments, 'SImg', _Enum_bool)
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                        _arguments, _attributes)
+        if _arguments.has_key('errn'):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+
+class Verify_Checksum_reply_record(aetools.ComponentItem):
+    """Verify Checksum reply record -  """
+    want = 'Rcrc'
+class validity(aetools.NProperty):
+    """validity - true if checksum is valid """
+    which = 'Vlid'
+    want = 'bool'
+class expected_checksum(aetools.NProperty):
+    """expected checksum - checksum value stored in the image header (in hexadecimal) """
+    which = 'crcE'
+    want = 'TEXT'
+class calculated_checksum(aetools.NProperty):
+    """calculated checksum - checksum value actually calculated (in hexadecimal) """
+    which = 'crcA'
+    want = 'TEXT'
+
+class Check_Image_reply_record(aetools.ComponentItem):
+    """Check Image reply record -  """
+    want = 'Rchk'
+class consistency(aetools.NProperty):
+    """consistency - Does the image pass consistency checks? """
+    which = 'Rch1'
+    want = 'bool'
+class error_count(aetools.NProperty):
+    """error count - the number of errors recorded """
+    which = 'Rch2'
+    want = 'long'
+class warning_count(aetools.NProperty):
+    """warning count - the number of warnings recorded """
+    which = 'Rch3'
+    want = 'long'
+Verify_Checksum_reply_record._propdict = {
+        'validity' : validity,
+        'expected_checksum' : expected_checksum,
+        'calculated_checksum' : calculated_checksum,
+}
+Verify_Checksum_reply_record._elemdict = {
+}
+Check_Image_reply_record._propdict = {
+        'consistency' : consistency,
+        'error_count' : error_count,
+        'warning_count' : warning_count,
+}
+Check_Image_reply_record._elemdict = {
+}
+_Enum_Acss = {
+        'read_and_write' : 'RdWr',      # read/write access
+        'read_only' : 'Rdxx',   # read-only access
+        'any' : 'Anyx', # best possible access
+}
+
+_Enum_Fsys = {
+        'Mac_OS_Standard' : 'Fhfs',     # classic HFS file system
+        'compatible_Mac_OS_Extended' : 'Fhf+',  # new HFS+ file system
+}
+
+_Enum_alis = None # XXXX enum alis not found!!
+_Enum_fss_ = None # XXXX enum fss  not found!!
+_Enum_long = None # XXXX enum long not found!!
+_Enum_bool = None # XXXX enum bool not found!!
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+        'Rchk' : Check_Image_reply_record,
+        'Rcrc' : Verify_Checksum_reply_record,
+}
+
+_propdeclarations = {
+        'crcE' : expected_checksum,
+        'Rch2' : error_count,
+        'crcA' : calculated_checksum,
+        'Rch3' : warning_count,
+        'Vlid' : validity,
+        'Rch1' : consistency,
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+        'Acss' : _Enum_Acss,
+        'Fsys' : _Enum_Fsys,
+}

Added: vendor/Python/current/Mac/Demo/applescript/Disk_Copy/Standard_Suite.py
===================================================================
--- vendor/Python/current/Mac/Demo/applescript/Disk_Copy/Standard_Suite.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Demo/applescript/Disk_Copy/Standard_Suite.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,477 @@
+"""Suite Standard Suite: Common terms for most applications
+Level 1, version 1
+
+Generated from Macintosh HD:Hulpprogramma's:Disk Copy
+AETE/AEUT resource version 1/0, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'Core'
+
+class Standard_Suite_Events:
+
+    _argmap_save = {
+            '_in' : 'kfil',
+            'using_format' : 'SvAs',
+            'checksum_verification' : 'VChk',
+            'signature_verification' : 'VSig',
+            'image_signing' : 'SImg',
+            'leave_image_mounted' : 'Moun',
+            'percent_free_space' : 'Slop',
+            'logical_blocks' : 'Blks',
+            'zeroing' : 'Zero',
+    }
+
+    def save(self, _object, _attributes={}, **_arguments):
+        """save: Save an object
+        Required argument: the source object
+        Keyword argument _in: the target object
+        Keyword argument using_format: the format for the target
+        Keyword argument checksum_verification: Should the checksum be verified before saving?
+        Keyword argument signature_verification: Should the DigiSignŽ signature be verified before saving?
+        Keyword argument image_signing: Should the image be signed?
+        Keyword argument leave_image_mounted: Should the image be mounted after saving?
+        Keyword argument percent_free_space: percent free space to reserve (for image folder operation, 0-255%)
+        Keyword argument logical_blocks: number of logical blocks in the image (for image folder operation)
+        Keyword argument zeroing: Should all the blocks in the image be set to zeros? (for image folder operation)
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: the result of the save operation
+        """
+        _code = 'core'
+        _subcode = 'save'
+
+        aetools.keysubst(_arguments, self._argmap_save)
+        _arguments['----'] = _object
+
+        aetools.enumsubst(_arguments, 'kfil', _Enum_obj_)
+        aetools.enumsubst(_arguments, 'SvAs', _Enum_SvAs)
+        aetools.enumsubst(_arguments, 'VChk', _Enum_bool)
+        aetools.enumsubst(_arguments, 'VSig', _Enum_bool)
+        aetools.enumsubst(_arguments, 'SImg', _Enum_bool)
+        aetools.enumsubst(_arguments, 'Moun', _Enum_bool)
+        aetools.enumsubst(_arguments, 'Slop', _Enum_long)
+        aetools.enumsubst(_arguments, 'Blks', _Enum_long)
+        aetools.enumsubst(_arguments, 'Zero', _Enum_bool)
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                        _arguments, _attributes)
+        if _arguments.has_key('errn'):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def do_script(self, _object, _attributes={}, **_arguments):
+        """do script: Execute an attached script located in the folder "Scripts"
+        Required argument: the script to be executed
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'core'
+        _subcode = 'dosc'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                        _arguments, _attributes)
+        if _arguments.has_key('errn'):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+
+class application(aetools.ComponentItem):
+    """application - The Disk Copy application """
+    want = 'capp'
+class version(aetools.NProperty):
+    """version - the version of this application """
+    which = 'vers'
+    want = 'vers'
+class name(aetools.NProperty):
+    """name - the name of this application """
+    which = 'pnam'
+    want = 'TEXT'
+class comment(aetools.NProperty):
+    """comment - the comment associated with the application """
+    which = 'comt'
+    want = 'TEXT'
+class driver_version(aetools.NProperty):
+    """driver version - the version of the disk image driver """
+    which = 'dVer'
+    want = 'vers'
+class nonejectable_mode(aetools.NProperty):
+    """nonejectable mode - Should mounted images be non-ejectable? """
+    which = 'otto'
+    want = 'bool'
+class save_log_file(aetools.NProperty):
+    """save log file - Should the log file be saved on disk? """
+    which = 'PSaL'
+    want = 'bool'
+class use_speech(aetools.NProperty):
+    """use speech - Should Disk Copy use spoken feedback? """
+    which = 'PTlk'
+    want = 'bool'
+class smart_Save_As(aetools.NProperty):
+    """smart Save As - Should the Save As... dialog box automatically go to the right folder? """
+    which = 'PSSP'
+    want = 'bool'
+class checksum_verification(aetools.NProperty):
+    """checksum verification - Should image checksums be verified? """
+    which = 'PVeC'
+    want = 'bool'
+class signature_verification(aetools.NProperty):
+    """signature verification - Should digital signatures be verified? """
+    which = 'PVeS'
+    want = 'bool'
+class exclude_DiskScripts(aetools.NProperty):
+    """exclude DiskScripts - Should images referenced in DiskScripts/DiskSets be excluded from verification? """
+    which = 'PExD'
+    want = 'bool'
+class exclude_remote_images(aetools.NProperty):
+    """exclude remote images - Should images that are located on network volumes be excluded from verification? """
+    which = 'PExR'
+    want = 'bool'
+class image_signing(aetools.NProperty):
+    """image signing - Should images be signed with a digital signature? """
+    which = 'PSiI'
+    want = 'bool'
+class leave_image_mounted(aetools.NProperty):
+    """leave image mounted - Should images be mounted after they are created? """
+    which = 'PMoA'
+    want = 'bool'
+class erase_confirmation(aetools.NProperty):
+    """erase confirmation - Should the user be required to confirm commands that erase disks? """
+    which = 'PCoE'
+    want = 'bool'
+class zeroing(aetools.NProperty):
+    """zeroing - Should all blocks of a new image be set to zero? """
+    which = 'PZeB'
+    want = 'bool'
+class default_create_size(aetools.NProperty):
+    """default create size - the default size for a new image, in blocks (512 bytes per block) """
+    which = 'PDeS'
+    want = 'long'
+class default_create_name(aetools.NProperty):
+    """default create name - the default volume name for a new image """
+    which = 'PDeN'
+    want = 'TEXT'
+class make_multiple_floppies(aetools.NProperty):
+    """make multiple floppies - Should the user be prompted to make multiple floppy disk images at a time? """
+    which = 'PBuM'
+    want = 'bool'
+class auto_image_upon_insert(aetools.NProperty):
+    """auto image upon insert - Should a newly-inserted disk automatically be processed into an image? """
+    which = 'Paim'
+    want = 'bool'
+class eject_after_auto_image(aetools.NProperty):
+    """eject after auto image - Should auto-imaged disks be ejected afterwards? """
+    which = 'Pejc'
+    want = 'bool'
+class auto_copy_upon_floppy_insert(aetools.NProperty):
+    """auto copy upon floppy insert - Instead of auto-imaging, should newly-inserted floppy disks be copied? """
+    which = 'Pcpf'
+    want = 'bool'
+class volume_suffix(aetools.NProperty):
+    """volume suffix - the default volume name suffix """
+    which = 'PDiE'
+    want = 'TEXT'
+class image_suffix(aetools.NProperty):
+    """image suffix - the default image name suffix """
+    which = 'PImE'
+    want = 'TEXT'
+class default_file_system(aetools.NProperty):
+    """default file system - the default file system type for new blank images """
+    which = 'Pfsy'
+    want = 'Fsys'
+class default_image_format(aetools.NProperty):
+    """default image format - the default image file format """
+    which = 'Pdfm'
+    want = 'SvAs'
+
+class disk(aetools.ComponentItem):
+    """disk - A mounted volume """
+    want = 'Disk'
+
+name = name
+
+comment = comment
+class locked(aetools.NProperty):
+    """locked - Is the disk locked? """
+    which = 'islk'
+    want = 'bool'
+class creation_date(aetools.NProperty):
+    """creation date - the creation date of disk """
+    which = 'ascd'
+    want = 'ldt '
+class modification_date(aetools.NProperty):
+    """modification date - the modification date of disk """
+    which = 'asmo'
+    want = 'ldt '
+class crc32_checksum(aetools.NProperty):
+    """crc32 checksum - the crc-32 checksum of the disk """
+    which = 'Xcrc'
+    want = 'TEXT'
+class disk_copy_4_2e_2_checksum(aetools.NProperty):
+    """disk copy 4.2 checksum - the Disk Copy 4.2 checksum of the disk """
+    which = 'Xc42'
+    want = 'TEXT'
+class block_count(aetools.NProperty):
+    """block count - the number of blocks on disk """
+    which = 'Xblk'
+    want = 'long'
+class file_system(aetools.NProperty):
+    """file system - the file system used on disk """
+    which = 'Xfsi'
+    want = 'TEXT'
+
+class folder(aetools.ComponentItem):
+    """folder - A folder or directory on a disk """
+    want = 'Fold'
+
+name = name
+
+comment = comment
+
+creation_date = creation_date
+
+modification_date = modification_date
+
+class disk_image(aetools.ComponentItem):
+    """disk image - A disk image file """
+    want = 'DImg'
+
+name = name
+
+comment = comment
+
+locked = locked
+
+creation_date = creation_date
+
+modification_date = modification_date
+class file_format(aetools.NProperty):
+    """file format - the format of the disk image file """
+    which = 'Ifmt'
+    want = 'TEXT'
+class signed(aetools.NProperty):
+    """signed - Does the disk image have a DigiSignŽ signature? """
+    which = 'Isin'
+    want = 'bool'
+class compressed(aetools.NProperty):
+    """compressed - Is the disk image compressed? """
+    which = 'Icom'
+    want = 'bool'
+class segmented(aetools.NProperty):
+    """segmented - Is the disk image segmented? """
+    which = 'Iseg'
+    want = 'bool'
+class segments(aetools.NProperty):
+    """segments - a list of references to other segments that make up a complete image """
+    which = 'Isg#'
+    want = 'fss '
+class disk_name(aetools.NProperty):
+    """disk name - the name of the disk this image represents """
+    which = 'Idnm'
+    want = 'TEXT'
+
+crc32_checksum = crc32_checksum
+
+disk_copy_4_2e_2_checksum = disk_copy_4_2e_2_checksum
+
+block_count = block_count
+
+file_system = file_system
+class data_fork_size(aetools.NProperty):
+    """data fork size - the size (in bytes) of the data fork of the disk image """
+    which = 'Idfk'
+    want = 'long'
+class resource_fork_size(aetools.NProperty):
+    """resource fork size - the size (in bytes) of the resource fork of the disk image """
+    which = 'Irfk'
+    want = 'long'
+
+class Save_reply_record(aetools.ComponentItem):
+    """Save reply record - Result from the save operation """
+    want = 'cpyR'
+class resulting_target_object(aetools.NProperty):
+    """resulting target object - a reference to the target object after it has been saved """
+    which = 'rcpO'
+    want = 'obj '
+class copy_type(aetools.NProperty):
+    """copy type - the way in which the target object was saved """
+    which = 'rcpT'
+    want = 'rcpT'
+application._propdict = {
+        'version' : version,
+        'name' : name,
+        'comment' : comment,
+        'driver_version' : driver_version,
+        'nonejectable_mode' : nonejectable_mode,
+        'save_log_file' : save_log_file,
+        'use_speech' : use_speech,
+        'smart_Save_As' : smart_Save_As,
+        'checksum_verification' : checksum_verification,
+        'signature_verification' : signature_verification,
+        'exclude_DiskScripts' : exclude_DiskScripts,
+        'exclude_remote_images' : exclude_remote_images,
+        'image_signing' : image_signing,
+        'leave_image_mounted' : leave_image_mounted,
+        'erase_confirmation' : erase_confirmation,
+        'zeroing' : zeroing,
+        'default_create_size' : default_create_size,
+        'default_create_name' : default_create_name,
+        'make_multiple_floppies' : make_multiple_floppies,
+        'auto_image_upon_insert' : auto_image_upon_insert,
+        'eject_after_auto_image' : eject_after_auto_image,
+        'auto_copy_upon_floppy_insert' : auto_copy_upon_floppy_insert,
+        'volume_suffix' : volume_suffix,
+        'image_suffix' : image_suffix,
+        'default_file_system' : default_file_system,
+        'default_image_format' : default_image_format,
+}
+application._elemdict = {
+}
+disk._propdict = {
+        'name' : name,
+        'comment' : comment,
+        'locked' : locked,
+        'creation_date' : creation_date,
+        'modification_date' : modification_date,
+        'crc32_checksum' : crc32_checksum,
+        'disk_copy_4_2e_2_checksum' : disk_copy_4_2e_2_checksum,
+        'block_count' : block_count,
+        'file_system' : file_system,
+}
+disk._elemdict = {
+}
+folder._propdict = {
+        'name' : name,
+        'comment' : comment,
+        'creation_date' : creation_date,
+        'modification_date' : modification_date,
+}
+folder._elemdict = {
+}
+disk_image._propdict = {
+        'name' : name,
+        'comment' : comment,
+        'locked' : locked,
+        'creation_date' : creation_date,
+        'modification_date' : modification_date,
+        'file_format' : file_format,
+        'signed' : signed,
+        'compressed' : compressed,
+        'segmented' : segmented,
+        'segments' : segments,
+        'disk_name' : disk_name,
+        'crc32_checksum' : crc32_checksum,
+        'disk_copy_4_2e_2_checksum' : disk_copy_4_2e_2_checksum,
+        'block_count' : block_count,
+        'file_system' : file_system,
+        'data_fork_size' : data_fork_size,
+        'resource_fork_size' : resource_fork_size,
+}
+disk_image._elemdict = {
+}
+Save_reply_record._propdict = {
+        'resulting_target_object' : resulting_target_object,
+        'copy_type' : copy_type,
+}
+Save_reply_record._elemdict = {
+}
+_Enum_UIAc = {
+        'never_interact' : 'eNvr',      # DonÕt allow any interaction at all
+        'interact_with_self' : 'eInS',  # Only allow interaction from internal events
+        'interact_with_local' : 'eInL', # Allow interaction from any event originating on this machine
+        'interact_with_all' : 'eInA',   # Allow interaction from network events
+}
+
+_Enum_SvAs = {
+        'NDIF_RW' : 'RdWr',     # read/write NDIF disk image
+        'NDIF_RO' : 'Rdxx',     # read-only NDIF disk image
+        'NDIF_Compressed' : 'ROCo',     # compressed NDIF disk image
+        'Disk_Copy_4_2e_2' : 'DC42',    # Disk Copy 4.2 disk image
+}
+
+_Enum_rcpT = {
+        'block_disk_copy' : 'cpBl',     # block-by-block disk-level copy
+        'files_and_file_ID_copy' : 'cpID',      # all files including desktop databases and file IDÕs
+        'files_and_desktop_info' : 'cpDT',      # all files and most desktop information
+        'files_only' : 'cpFI',  # all files but no desktop information
+        'disk_image_conversion' : 'cpCV',       # disk image format conversion
+        'disk_image_creation' : 'cpCR', # disk image creation
+}
+
+_Enum_long = None # XXXX enum long not found!!
+_Enum_bool = None # XXXX enum bool not found!!
+_Enum_obj_ = None # XXXX enum obj  not found!!
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+        'DImg' : disk_image,
+        'capp' : application,
+        'Disk' : disk,
+        'Fold' : folder,
+        'cpyR' : Save_reply_record,
+}
+
+_propdeclarations = {
+        'Xcrc' : crc32_checksum,
+        'PDeS' : default_create_size,
+        'Idnm' : disk_name,
+        'PSSP' : smart_Save_As,
+        'Pcpf' : auto_copy_upon_floppy_insert,
+        'pnam' : name,
+        'Isin' : signed,
+        'otto' : nonejectable_mode,
+        'PExD' : exclude_DiskScripts,
+        'Iseg' : segmented,
+        'islk' : locked,
+        'asmo' : modification_date,
+        'PTlk' : use_speech,
+        'Pfsy' : default_file_system,
+        'PVeC' : checksum_verification,
+        'Xc42' : disk_copy_4_2e_2_checksum,
+        'rcpO' : resulting_target_object,
+        'Paim' : auto_image_upon_insert,
+        'comt' : comment,
+        'PCoE' : erase_confirmation,
+        'dVer' : driver_version,
+        'PDeN' : default_create_name,
+        'PBuM' : make_multiple_floppies,
+        'rcpT' : copy_type,
+        'PDiE' : volume_suffix,
+        'Ifmt' : file_format,
+        'Pdfm' : default_image_format,
+        'ascd' : creation_date,
+        'Pejc' : eject_after_auto_image,
+        'PZeB' : zeroing,
+        'PExR' : exclude_remote_images,
+        'PImE' : image_suffix,
+        'PVeS' : signature_verification,
+        'PSaL' : save_log_file,
+        'Xblk' : block_count,
+        'PMoA' : leave_image_mounted,
+        'Isg#' : segments,
+        'Irfk' : resource_fork_size,
+        'Icom' : compressed,
+        'Xfsi' : file_system,
+        'Idfk' : data_fork_size,
+        'vers' : version,
+        'PSiI' : image_signing,
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+        'SvAs' : _Enum_SvAs,
+        'UIAc' : _Enum_UIAc,
+        'rcpT' : _Enum_rcpT,
+}

Added: vendor/Python/current/Mac/Demo/applescript/Disk_Copy/Utility_Events.py
===================================================================
--- vendor/Python/current/Mac/Demo/applescript/Disk_Copy/Utility_Events.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Demo/applescript/Disk_Copy/Utility_Events.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,213 @@
+"""Suite Utility Events: Commands that allow the user to select Disk Copy files
+Level 1, version 1
+
+Generated from Macintosh HD:Hulpprogramma's:Disk Copy
+AETE/AEUT resource version 1/0, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'ddsk'
+
+class Utility_Events_Events:
+
+    _argmap_select_disk_image = {
+            'with_prompt' : 'SELp',
+    }
+
+    def select_disk_image(self, _no_object=None, _attributes={}, **_arguments):
+        """select disk image: Prompt the user to select a disk image
+        Keyword argument with_prompt: the prompt string to be displayed
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: a reference to a disk image
+        """
+        _code = 'UTIL'
+        _subcode = 'SEL1'
+
+        aetools.keysubst(_arguments, self._argmap_select_disk_image)
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+        aetools.enumsubst(_arguments, 'SELp', _Enum_TEXT)
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                        _arguments, _attributes)
+        if _arguments.has_key('errn'):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_select_DiskScript = {
+            'with_prompt' : 'SELp',
+    }
+
+    def select_DiskScript(self, _no_object=None, _attributes={}, **_arguments):
+        """select DiskScript: Prompt the user to select a DiskScript
+        Keyword argument with_prompt: the prompt string to be displayed
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: a reference to a DiskScript
+        """
+        _code = 'UTIL'
+        _subcode = 'SEL2'
+
+        aetools.keysubst(_arguments, self._argmap_select_DiskScript)
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+        aetools.enumsubst(_arguments, 'SELp', _Enum_TEXT)
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                        _arguments, _attributes)
+        if _arguments.has_key('errn'):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_select_disk_image_or_DiskScript = {
+            'with_prompt' : 'SELp',
+    }
+
+    def select_disk_image_or_DiskScript(self, _no_object=None, _attributes={}, **_arguments):
+        """select disk image or DiskScript: Prompt the user to select a disk image or DiskScript
+        Keyword argument with_prompt: the prompt string to be displayed
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: a reference to disk image or a DiskScript
+        """
+        _code = 'UTIL'
+        _subcode = 'SEL3'
+
+        aetools.keysubst(_arguments, self._argmap_select_disk_image_or_DiskScript)
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+        aetools.enumsubst(_arguments, 'SELp', _Enum_TEXT)
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                        _arguments, _attributes)
+        if _arguments.has_key('errn'):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_select_floppy_disk_image = {
+            'with_prompt' : 'SELp',
+    }
+
+    def select_floppy_disk_image(self, _no_object=None, _attributes={}, **_arguments):
+        """select floppy disk image: Prompt the user to select a floppy disk image
+        Keyword argument with_prompt: the prompt string to be displayed
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: a reference to a floppy disk image
+        """
+        _code = 'UTIL'
+        _subcode = 'SEL4'
+
+        aetools.keysubst(_arguments, self._argmap_select_floppy_disk_image)
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+        aetools.enumsubst(_arguments, 'SELp', _Enum_TEXT)
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                        _arguments, _attributes)
+        if _arguments.has_key('errn'):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_select_disk = {
+            'with_prompt' : 'SELp',
+    }
+
+    def select_disk(self, _no_object=None, _attributes={}, **_arguments):
+        """select disk: Prompt the user to select a disk volume
+        Keyword argument with_prompt: the prompt string to be displayed
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: a reference to the disk
+        """
+        _code = 'UTIL'
+        _subcode = 'SEL5'
+
+        aetools.keysubst(_arguments, self._argmap_select_disk)
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+        aetools.enumsubst(_arguments, 'SELp', _Enum_TEXT)
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                        _arguments, _attributes)
+        if _arguments.has_key('errn'):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_select_folder = {
+            'with_prompt' : 'SELp',
+    }
+
+    def select_folder(self, _no_object=None, _attributes={}, **_arguments):
+        """select folder: Prompt the user to select a folder
+        Keyword argument with_prompt: the prompt string to be displayed
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: a reference to the folder
+        """
+        _code = 'UTIL'
+        _subcode = 'SEL6'
+
+        aetools.keysubst(_arguments, self._argmap_select_folder)
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+        aetools.enumsubst(_arguments, 'SELp', _Enum_TEXT)
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                        _arguments, _attributes)
+        if _arguments.has_key('errn'):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_log = {
+            'time_stamp' : 'TSMP',
+    }
+
+    def log(self, _object, _attributes={}, **_arguments):
+        """log: Add a string to the log window
+        Required argument: the string to add to the log window
+        Keyword argument time_stamp: Should the log entry be time-stamped? (false if not supplied)
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'UTIL'
+        _subcode = 'LOG '
+
+        aetools.keysubst(_arguments, self._argmap_log)
+        _arguments['----'] = _object
+
+        aetools.enumsubst(_arguments, 'TSMP', _Enum_bool)
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                        _arguments, _attributes)
+        if _arguments.has_key('errn'):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+_Enum_TEXT = None # XXXX enum TEXT not found!!
+_Enum_bool = None # XXXX enum bool not found!!
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+}
+
+_propdeclarations = {
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+}

Added: vendor/Python/current/Mac/Demo/applescript/Disk_Copy/__init__.py
===================================================================
--- vendor/Python/current/Mac/Demo/applescript/Disk_Copy/__init__.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Demo/applescript/Disk_Copy/__init__.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,35 @@
+"""
+Package generated from Macintosh HD:Hulpprogramma's:Disk Copy
+Resource aete resid 0
+"""
+import aetools
+Error = aetools.Error
+import Standard_Suite
+import Special_Events
+import Utility_Events
+
+
+_code_to_module = {
+        'Core' : Standard_Suite,
+        'ddsk' : Special_Events,
+        'ddsk' : Utility_Events,
+}
+
+
+
+_code_to_fullname = {
+        'Core' : ('Disk_Copy.Standard_Suite', 'Standard_Suite'),
+        'ddsk' : ('Disk_Copy.Special_Events', 'Special_Events'),
+        'ddsk' : ('Disk_Copy.Utility_Events', 'Utility_Events'),
+}
+
+from Standard_Suite import *
+from Special_Events import *
+from Utility_Events import *
+
+
+class Disk_Copy(Standard_Suite_Events,
+                Special_Events_Events,
+                Utility_Events_Events,
+                aetools.TalkTo):
+    _signature = 'ddsk'

Added: vendor/Python/current/Mac/Demo/applescript/makedisk.py
===================================================================
--- vendor/Python/current/Mac/Demo/applescript/makedisk.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Demo/applescript/makedisk.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,15 @@
+import Disk_Copy
+import macfs
+import sys
+
+talker = Disk_Copy.Disk_Copy(start=1)
+talker.activate()
+filespec = macfs.FSSpec('my disk image.img')
+try:
+    objref = talker.create('my disk image', saving_as=filespec, leave_image_mounted=1)
+except Disk_Copy.Error, arg:
+    print "ERROR: my disk image:", arg
+else:
+    print 'objref=', objref
+print 'Type return to exit-'
+sys.stdin.readline()

Added: vendor/Python/current/Mac/Demo/applescript.html
===================================================================
--- vendor/Python/current/Mac/Demo/applescript.html	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Demo/applescript.html	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,362 @@
+<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
+<html><head><title>Using the Open Scripting Architecture from Python</title></head>
+<body>
+<h1>Using the Open Scripting Architecture from Python</h1>
+<hr>
+
+<p><b>NOTE:</b> this document describes the OSA support that is shipped with
+the core python distribution. Most users are better of with the more 
+userfriendly <a href="http://freespace.virgin.net/hamish.sanderson/appscript.html">appscript library</a>.
+
+<p>OSA support in Python is still not 100% complete, but
+there is already enough in place to allow you to do some nifty things
+with other programs from your python program. </p> 
+
+
+<p>
+In this example, we will look at a scriptable application, extract its
+&#8220;AppleScript Dictionary,&#8221;  generate a Python interface package from
+the dictionary, and use that package to control the application. 
+The application we are going to script is Disk Copy, Apple's standard
+utility for making copies of floppies, creating files that are mountable
+as disk images, etc. 
+Because we want
+to concentrate on the OSA details, we won&#8217;t bother with a real
+user-interface for our application. </p>
+
+
+<p>
+<em>When we say &#8220;AppleScript&#8221; in this document we actually mean
+&#8220;the Open Scripting Architecture.&#8221; There is nothing
+AppleScript-specific in the Python implementation. Most of this document 
+focuses on the classic Mac OS; <a href="#osx">Mac OS X</a> users have some 
+additional tools.</em>
+</p>
+
+<h2>Python OSA architecture</h2>
+
+<p>Open Scripting suites and inheritance can be modelled rather nicely 
+with Python packages, so we generate
+a package for each application we want to script. Each suite defined in 
+the application becomes a module in the
+package, and the package main module imports everything from all the
+submodules and glues together all the classes (in Python terminology&#8212; 
+events in OSA terminology or verbs in AppleScript terminology). </p>
+
+<p>
+A suite in an OSA application can extend the functionality of a standard
+suite. This is implemented in Python by importing everything from the
+module that implements the standard suites and overriding anything that has
+been extended. The standard suites live in the StdSuite package. </p>
+
+<p>
+This all sounds complicated, but the good news is that basic
+scripting is actually pretty simple. You can do strange and wondrous things
+with OSA scripting once you fully understand it. </p>
+
+<h2>Creating the Python interface package</h2>
+
+
+<p>There is a tool in the standard distribution that can automatically 
+generate the interface packages.  This tool is called
+<code>gensuitemodule.py</code>, and lives in <code>Mac:scripts</code>. 
+It looks through a file
+for an &#8216;AETE&#8217; or &#8216;AEUT&#8217; resource, 
+the internal representation of the
+AppleScript dictionary, and parses the resource to generate the suite 
+modules.
+When we start <code>gensuitemodule</code>, it asks us for an input file; 
+for our example,
+we point it to the Disk Copy executable. </p>
+
+<p>
+Next, <code>gensuitemodule</code> wants a folder where it will store the 
+package it is going to generate.
+Note that this is the package folder, not the parent folder, so we
+navigate to <code>Python:Mac:Demo:applescript</code>, create a folder
+<code>Disk_Copy</code>, and select that. </p>
+
+<p>
+We  next specify the folder from which <code>gensuitemodule</code>  
+should import the standard suites. Here,
+we always select <code>Python:Mac:Lib:lib-scriptpackages:StdSuites</code>. (There is
+one exception to this rule: when you are generating <code>StdSuites</code> itself
+you select <code>_builtinSuites</code>.)
+</p>
+
+<p>
+It starts parsing the AETE resource, and for
+each AppleEvent suite it finds, <code>gensuitemodule.py</code>
+prompts us for the filename of the
+resulting python module. Remember to change folders for the first
+module&#8212;you don't want to clutter up, say, the 
+Disk Copy folder
+with your python
+interfaces. If you want to skip a suite, press <code>cancel</code> and the process
+continues with the next suite. </p>
+
+<h3>Summary</h3>
+
+<ol>
+	
+	<li>Run <code>gensuitemodule</code>.</li>
+	
+	<li>Select the application (or OSAX) for which you would like a Python interface.</li>
+	
+	<li>Select the package folder where the interface modules should be 
+	stored.</li>
+	
+	<li>Specify the folder <code>Python:Mac:Lib:lib-scriptpackages:StdSuites</code>
+	to import the standard suites (or <code>_builtinSuites</code> if you are 
+	generating <code>StdSuites</code> itself). </li>
+	
+	<li>Save the generated suites (use <code>cancel</code> to skip a suite).</li>
+	
+	
+</ol>
+
+
+<h3>Notes</h3>
+
+
+<ul>
+	
+	<li>The interface package may occasionally need some editing by hand.  For example, 
+	<code>gensuitemodule</code> does not handle all Python reserved words, so
+	if
+	 one of the AppleScript verbs is a Python reserved word, a <code>SyntaxError</code> 
+	 may be raised when the package is imported.  
+	Simply rename the class into something acceptable, if this happens;
+	take a look at how the
+	<code>print</code> verb is handled (automatically by <code>gensuitemodule</code>) 
+	in the standard suites. But: f you need to edit your package this should be considered a
+	bug in gensuitemodule, so please report it so it can be fixed in future releases.
+	</li>
+	
+	
+	<li>If you want to re-create the StdSuite modules,
+you should look in one of two places. With versions of AppleScript older than 1.4.0 
+(which first shipped with OS 9.0),  you will find the
+AEUT resources in <code>System Folder:Extensions:Scripting
+Additions:Dialects:English Dialect</code>. For newer versions, you will
+find them in <code>System Folder:Extensions:Applescript</code>.
+</li>
+
+	<li>Since MacPython 2.0, this new structure, with packages
+per application and submodules per suite, is used. Older MacPythons had a
+single level of modules, with uncertain semantics. With the new structure,
+it is possible for programs to override standard suites, as programs often do.
+
+</li>
+
+<li><code>Gensuitemodule.py</code> may ask you questions 
+like &#8220;Where is enum 'xyz ' declared?&#8221;.
+This is either due to a misunderstanding on my part or (rather too commonly)
+bugs in the AETE resources. Pressing <code>cancel</code> is usually the
+right choice: it will cause the specific enum not to be treated as an enum
+but as a &#8220;normal&#8221; type. As things like fsspecs and TEXT strings clearly are
+not enumerators, this is correct. If someone understands what is really going on
+here, please let me know.</li>
+
+</ul>
+
+
+
+<h2>The Python interface package contents</h2>
+
+<p>
+Let&#8217;s glance at the 
+<a href="applescript/Disk_Copy">Disk_Copy</a> package just created. You
+may want to open Script Editor alongside to see how it
+interprets the dictionary. 
+</p>
+
+
+<p>
+The main package module is in <code>__init__.py</code>.
+The only interesting bit is the <code>Disk_Copy</code> class, which
+includes the event handling classes from the individual suites. It also
+inherits <code>aetools.TalkTo</code>, which is a base class that handles all
+details on how to start the program and talk to it, and a class variable
+<code>_signature</code> which is the default application this class will talk
+to (you can override this in various ways when you instantiate your class, see
+<code>aetools.py</code> for details).
+</p>
+
+<p>
+The <a href="applescript/Disk_Copy/Special_Events.py">Special_Events</a>
+module is a nice example of a suite module.
+The <code>Special_Events_Events</code> class is the bulk of the code
+generated. For each verb, it contains a method. Each method knows what
+arguments the verb expects, and it makes  use of keyword
+arguments to present a palatable
+interface to the python programmer. 
+
+Notice that each method
+calls some routines from <code>aetools</code>, an auxiliary module
+living in <code>Mac:Lib</code>.
+The other thing to notice is that each method calls
+<code>self.send</code>.  This comes from the <code>aetools.TalkTo</code> 
+baseclass. </p>
+
+
+<p>
+After the big class, there are a number of little class declarations. These
+declarations are for the (AppleEvent) classes and properties in the suite.
+They allow you to create object IDs, which can then be passed to the verbs.
+For instance,
+when scripting the popular email program Eudora,
+you would use <code>mailbox("inbox").message(1).sender</code>
+to get the name of the sender of the first message in mailbox
+inbox. It is
+also possible to specify this as <code>sender(message(1, mailbox("inbox")))</code>,
+which is sometimes needed because these classes don&#8217;t always inherit correctly
+from baseclasses, so you may have to use a class or property from another 
+suite. </p>
+
+<p>
+Next we get the enumeration dictionaries, which allow you to pass
+english names as arguments to verbs, so you don't have to bother with the 4-letter
+type code. So, you can say
+<code>
+	diskcopy.create(..., filesystem="Mac OS Standard")
+</code>
+as it is called in Script Editor, instead of the cryptic lowlevel
+<code>
+	diskcopy.create(..., filesystem="Fhfs")
+</code></p>
+
+<p>
+Finally, we get the &#8220;table of contents&#8221; of the module, listing all 
+classes and such
+by code, which is used by <code>gensuitemodule</code> itself: if you use this
+suite as a base package in a later run this is how it knows what is defined in this
+suite, and what the Python names are.
+</p>
+
+<h3>Notes</h3>
+
+<ul>
+	
+	<li>The <code>aetools</code> module contains some other nifty
+AppleEvent tools as well. Have a look at it sometime, there is (of
+course) no documentation yet. 
+</li>
+	
+	<li>There are also some older object specifiers for standard objects in aetools.
+You use these in the form <code>aetools.Word(10,
+aetools.Document(1))</code>, where the corresponding AppleScript
+terminology would be <code>word 10 of the first
+document</code>. Examine 
+<code>aetools</code> and <code>aetools.TalkTo</code>
+along with
+the comments at the end of your suite module if you need to create
+more than the standard object specifiers.
+</li>
+	
+</ul>
+
+
+
+
+<h2>Using a Python suite module</h2>
+
+<p>
+Now that we have created the suite module, we can use it in a Python script.
+In older MacPython distributions this used to be a rather
+complicated affair, but with the package scheme and with the application signature
+known by the package it is very simple: you import the package and instantiate
+the class, e.g. 
+<code>
+	talker = Disk_Copy.Disk_Copy(start=1)
+</code>
+You will usually specify the <code>start=1</code>: it will run the application if it is
+not already running. 
+You may want to omit it if you want to talk to the application
+only if it is already running, or if the application is something like the Finder. 
+Another way to ensure that  the application is running is to call <code>talker._start()</code>.
+</p>
+
+<p>
+Looking at the sourcefile <a
+href="applescript/makedisk.py">makedisk.py</a>, we see that it starts
+with some imports.  Naturally, one of these is the Python interface to Disk 
+Copy.</p>
+
+<p>
+The main program itself is a wonder of simplicity: we create the
+object (<code>talker</code>) that talks to Disk Copy, 
+create a disk, and mount it. The bulk of 
+the work is done by <code>talker</code> and the Python interface package we 
+just created.</p>
+
+<p>
+The exception handling does warrant a few comments, though. Since
+AppleScript is basically a connectionless RPC protocol,
+nothing happens
+when we create the <code>talker</code> object. Hence, if the destination application
+is not running, we will not notice until we send our first
+command (avoid this as described above). There is another thing to note about errors returned by
+AppleScript calls: <code>MacOS.Error</code> is raised for
+all of the errors that are known to be <code>OSErr</code>-type errors, 
+while
+server generated errors raise <code>aetools.Error</code>. </p>
+
+<h2>Scripting Additions</h2>
+
+<p>
+If you want to use any of the scripting additions (or OSAXen, in
+everyday speech) from a Python program, you can use the same method
+as for applications, i.e. run <code>gensuitemodule</code> on the
+OSAX (commonly found in <code>System Folder:Scripting Additions</code>
+or something similar). There is one minor gotcha: the application
+signature to use is <code>MACS</code>. You will need to edit the main class
+in the <code>__init__.py</code> file of the created package and change the value 
+of <code>_signature</code> to <code>MACS</code>, or use a subclass to the
+same effect.
+</p>
+
+<p>
+There are two minor points to watch out for when using <code>gensuitemodule</code>
+on OSAXen: they appear all to define the class <code>System_Object_Suite</code>,
+and a lot of them have the command set in multiple dialects. You have to
+watch out for name conflicts and make sure you select a reasonable dialect
+(some of the non-English dialects cause <code>gensuitemodule</code> to generate incorrect
+Python code). </p>
+
+Despite these difficulties, OSAXen offer a lot of possibilities.  Take a 
+look at some of the OSAXen in the Scripting Additions folder, or 
+<A HREF="http://www.osaxen.com/index.php">download</A> some from the net.
+
+<h2>Further Reading</h2>
+
+<p>
+If you want to look at more involved examples of applescripting, look at the standard
+modules <code>findertools</code> and <code>nsremote</code>, or (possibly better, as it
+is more involved) <code>fullbuild</code> from the <code>Mac:scripts</code> folder.
+</p>
+
+<h2><a name="alternatives">Alternatives</a></h2>
+
+<h3><a name="osx">Mac OS X</a></h3>
+
+<p>
+Under Mac OS X, the above still works, but with some new difficulties.
+The application package structure can hide the &#8216;AETE&#8217; or
+&#8216;AEUT&#8217; resource from <code>gensuitemodule</code>, so that,
+for example, it cannot generate an OSA interface to iTunes. Script
+Editor gets at the dictionary of such programs using a &#8216;Get
+AETE&#8217; AppleEvent, if someone wants to donate code to use the same
+method for gensuitemodule: by all means!
+</p>
+
+<p>
+One alternative is available through the Unix command line version of python. 
+Apple has provided the <code>osacompile</code> and <code>osascript</code> tools, 
+which can be used to compile and execute scripts written in OSA languages. See the 
+man pages for more details.
+</p>
+
+
+</body>
+</html>

Added: vendor/Python/current/Mac/Demo/example0/checktext.py
===================================================================
--- vendor/Python/current/Mac/Demo/example0/checktext.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Demo/example0/checktext.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,35 @@
+"""checktext - Check that a text file has macintosh-style newlines"""
+
+import sys
+import EasyDialogs
+import string
+
+def main():
+    pathname = EasyDialogs.AskFileForOpen(message='File to check end-of-lines in:')
+    if not pathname:
+        sys.exit(0)
+    fp = open(pathname, 'rb')
+    try:
+        data = fp.read()
+    except MemoryError:
+        EasyDialogs.Message('Sorry, file is too big.')
+        sys.exit(0)
+    if len(data) == 0:
+        EasyDialogs.Message('File is empty.')
+        sys.exit(0)
+    number_cr = string.count(data, '\r')
+    number_lf = string.count(data, '\n')
+    if number_cr == number_lf == 0:
+        EasyDialogs.Message('File contains no lines.')
+    if number_cr == 0:
+        EasyDialogs.Message('File has unix-style line endings')
+    elif number_lf == 0:
+        EasyDialogs.Message('File has mac-style line endings')
+    elif number_cr == number_lf:
+        EasyDialogs.Message('File probably has MSDOS-style line endings')
+    else:
+        EasyDialogs.Message('File has no recognizable line endings (binary file?)')
+    sys.exit(0)
+
+if __name__ == '__main__':
+    main()

Added: vendor/Python/current/Mac/Demo/example0.html
===================================================================
--- vendor/Python/current/Mac/Demo/example0.html	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Demo/example0.html	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,75 @@
+<HTML><HEAD><TITLE>Using python to create Macintosh applications, part zero</TITLE></HEAD>
+<BODY>
+<H1>Using python to create Macintosh applications, part zero</H1>
+<HR>
+
+This document will show you how to create a simple mac-style
+application using Python. We will glance at how to use file dialogs and
+messages. <p>
+
+Our example program <a href="example0/checktext.py">checktext.py</a> asks
+the user for a text file and checks what style end-of-lines the file has.
+This may need a little explanation: ASCII text files are almost identical
+on different machines, with one exception: 
+<ul>
+<li> Unix systems terminate lines with the "linefeed" character, <code>0x0a</code>,
+<li> Macintoshes terminate lines with the "carriage return" character,
+<code>0x0d</code> and
+<li> MSDOS and Windows terminate lines with first a carriage return and then a linefeed.
+</ul>
+
+Let us have a look at the program. The first interesting statement in the main
+program is the call to <code>macfs.PromptGetFile</code>. This is one of the routines
+that allow you to ask the user to specify a file. You pass it one required
+argument, the prompt string. There are up to four optional MacOS <em>file type</em> arguments
+you can pass, as 4-byte strings. Specifying no file
+type will allow the user to select any file, specifying one or more types restricts
+the user to files of this type. File types are explained in most books on the Mac. <p>
+
+<code>PromptGetFile</code> returns two values: an <em>FSSpec</em> object and a
+success indicator. The FSSpec object is the "official" MacOS way of specifying a
+file, more on it later. The success indicator tells you whether the user clicked OK
+or Cancel. In the event of Cancel we simply exit back to the finder. <p>
+
+<code>PromptGetFile</code> has a number of friends that do similar things:
+<ul>
+<li> <code>StandardGetFile</code> is identical to <code>PromptGetFile</code> but
+without the prompt. It has up to four optional filetype arguments.
+<li> <code>StandardPutFile</code> asks the user for an output file. It will
+warn the user when she tries to overwrite an existing file. The routine has one
+mandatory argument: a prompt string. Pass the empty string if you do not want a prompt.
+<li> <code>GetDirectory</code> asks the user for a folder (or directory, in unix terms).
+It has one optional argument: a prompt string.
+</ul>
+All routines return an FSSpec and a success indicator. <p>
+
+There are many things you can do with FSSpec objects (see the 
+<a href="http://www.python.org/doc/lib/macfs.html">macfs</a> section in the
+<a href="http://www.python.org/doc/lib/Top.html">Python Library Reference</a>
+for details), but passing them to <code>open</code> is not
+one of them. For this, we first have to convert the FSSpec object to a pathname, with
+the <code>as_pathname</code> method. This returns a standard MacOS-style pathname with
+colon-separated components. This can then be passed to <code>open</code>. Note that
+we call open with mode parameter <code>'rb'</code>: we want to read the file in binary
+mode. Python, like C and C++, uses unix-style line endings internally and opening a
+file in text mode (<code>'r'</code>) would result in conversion of carriage-returns to
+linefeeds upon reading. This is something that Mac and DOS programmers are usually aware
+of but that never ceases to amaze unix buffs. <p>
+
+After we open the file we attempt to read all data into memory. If this fails we use
+<code>EasyDialogs.Message</code> to display a message in a standard dialog box and exit.
+The EasyDialogs module has a few more useful simple dialog routines, more on that in 
+<a href="example1.html">example 1</a>. <p>
+
+The rest of the code is pretty straightforward: we check that the file actually contains
+data, count the number of linefeeds and returns and display a message with our guess of the
+end-of-line convention used in the file. <p>
+
+The <a href="example0">example0</a> folder has three text files in Mac, Unix and DOS style
+for you to try the program on. After that, you can continue with <a href="example1.html">example 1</a>
+or go back to the <a href="index.html">index</a> to find another interesting topic. <p>
+
+<HR>
+<A HREF="http://www.cwi.nl/~jack">Jack Jansen</A>,
+<A HREF="mailto:jack at cwi.nl">jack at cwi.nl</A>, 18-July-1996.
+</BODY></HTML>

Added: vendor/Python/current/Mac/Demo/example1/dnslookup-1.gif
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Mac/Demo/example1/dnslookup-1.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Mac/Demo/example1/dnslookup-1.py
===================================================================
--- vendor/Python/current/Mac/Demo/example1/dnslookup-1.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Demo/example1/dnslookup-1.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,56 @@
+"""Sample program performing domain name lookups and showing off EasyDialogs,
+Res and Dlg in the process"""
+
+import EasyDialogs
+from Carbon import Res
+from Carbon import Dlg
+import sys
+import socket
+import string
+import macresource
+#
+# Definitions for our resources
+ID_MAIN=512
+
+ITEM_LOOKUP_ENTRY=1
+ITEM_RESULT=2
+ITEM_LOOKUP_BUTTON=3
+ITEM_QUIT_BUTTON=4
+
+def main():
+    """Main routine: open resource file, call dialog handler"""
+    macresource.need("DLOG", ID_MAIN, "dnslookup-1.rsrc")
+    do_dialog()
+
+def do_dialog():
+    """Post dialog and handle user interaction until quit"""
+    my_dlg = Dlg.GetNewDialog(ID_MAIN, -1)
+    while 1:
+        n = Dlg.ModalDialog(None)
+        if n == ITEM_LOOKUP_BUTTON:
+            tp, h, rect = my_dlg.GetDialogItem(ITEM_LOOKUP_ENTRY)
+            txt = Dlg.GetDialogItemText(h)
+
+            tp, h, rect = my_dlg.GetDialogItem(ITEM_RESULT)
+            Dlg.SetDialogItemText(h, dnslookup(txt))
+        elif n == ITEM_QUIT_BUTTON:
+            break
+
+def dnslookup(str):
+    """ Perform DNS lookup on str.  If first character of digit is numeric,
+        assume that str contains an IP address.  Otherwise, assume that str
+        contains a hostname."""
+    if str == '': str = ' '
+    if str[0] in string.digits:
+        try:
+            value = socket.gethostbyaddr(str)[0]
+        except:
+            value = 'Lookup failed'
+    else:
+        try:
+            value = socket.gethostbyname(str)
+        except:
+            value = 'Lookup failed'
+    return value
+
+main()

Added: vendor/Python/current/Mac/Demo/example1/dnslookup-1.rsrc
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Mac/Demo/example1/dnslookup-1.rsrc
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Mac/Demo/example1.html
===================================================================
--- vendor/Python/current/Mac/Demo/example1.html	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Demo/example1.html	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,193 @@
+<HTML><HEAD><TITLE>Using python to create Macintosh applications, part one</TITLE></HEAD>
+<BODY>
+
+<H1>Using python to create Macintosh applications, part one</H1>
+<HR>
+
+This document will show you how to create a simple mac-style
+application using Python. We will glance at how to use dialogs and
+resources. <p>
+
+The example application we look at will be a simple program with a
+dialog that allows you to perform domain name lookups on IP addresses
+and hostnames.
+The <A HREF="example1/dnslookup-1.py">source code</A> and 
+<A HREF="example1/dnslookup-1.rsrc">resource file</A> 
+for this application are available in the <A
+HREF="example1">example1</A> folder (which you will have to download
+if you are reading this document over the net and if you want to look
+at the resources). <p>
+
+We will use the builtin module "socket" that allows a
+Python program to perform all sorts of networking functions, and we 
+will create the user interface around that. You should be able to run
+the sample code with the standard Python distribution.<p>
+
+<CITE>
+If you are interested in building your own extensions to python you
+should check out the companion document <A
+HREF="plugins.html">Creating Macintosh Python C extensions</A>,
+which tells you how to build your own C extension.
+<p>
+</CITE>
+
+<H2><A NAME="dialog-resources">Creating dialog resources</A></H2>
+
+Let us start with the creative bit: building the dialogs and creating
+an icon for our program. For this you need ResEdit, and a reasonable
+working knowledge of how to use it. "Inside Mac" or various books on
+macintosh programming will help here. <p>
+
+There is one fine point that deserves to be mentioned here: <A
+NAME="resource-numbering">resource numbering</A>.  Because often your
+resources will be combined with those that the Python interpreter and
+various standard modules need you should give your DLOG and DITL
+resources numbers above 512. 128 and below are reserved for Apple,
+128-228 are for extensions like Tk,
+228-255 for the Python interpreter and 256-511 for standard
+modules. If you are writing a module that you will be distributing for
+inclusion in other people's programs you may want to register a number
+in the 256-511 range, contact Guido or myself or whoever you think is
+"in charge" of Python for the Macintosh at the moment. Even though the
+application we are writing at the moment will keep its resources in a
+separate resource file it is still a good idea to make sure that no
+conflicts arise: once you have opened your resource file any attempt
+by the interpreter to open a dialog will also search your resource
+file. <p>
+
+Okay, let's have a look at dnslookup-1.rsrc, our resource file.
+The DLOG and accompanying DITL resource both have number 512. Since
+ResEdit creates both with default ID=128 you should take care to
+change the number on both. The dialog itself is pretty basic: two
+buttons (Lookup and Quit), two labels and
+two text entry areas, one of which is used for output only.  Here's what
+the dialog will look like at run time<p>
+<div align=center>
+<img width=324 height=189 src="example1/dnslookup-1.gif" alt="dialog image">
+</div>
+<p>
+
+<H2><A NAME="modal-dialog">An application with a modal dialog</A></H2>
+
+Next, we will have to write the actual application. For this example,
+we will use a modal dialog. This means that we will put up the dialog
+and go into a loop asking the dialog manager for events (buttons
+pushed). We handle the actions requested by the user until the Quit
+button is pressed, upon which we exit our loop (and the program). This
+way of structuring your program is actually rather antisocial, since
+you force the user to do whatever you, the application writer, happen
+to want. A modal dialog leaves no way of escape whatsoever (except
+command-option-escape), and is usually not a good way to structure
+anything but the most simple questions.  Even then: how often have you
+been confronted with a dialog asking a question that you could not
+answer because the data you needed was obscured by the dialog itself?
+In the next example we will look at an application that does pretty
+much the same as this one but in a more user-friendly way. <p>
+
+The code itself is contained in the file <A
+HREF="example1/dnslookup-1.py"> dnslookup-1.py</A>. Have
+a copy handy before you read on.  The file starts off with a
+textstring giving a short description. Not many tools do anything with
+this as yet, but at some point in the future we <EM>will</EM> have all
+sorts of nifty class browser that will display this string, so just
+include it. Just put a short description at the start of each module,
+class, method and function.  After the initial description and some
+comments, we import the modules we need. <p>
+ 
+<A NAME="easydialogs"><CODE>EasyDialogs</CODE></A> is a handy standard
+module that provides you with routines that put up common text-only
+modal dialogs:
+<UL>
+<LI> <CODE>Message(str)</CODE>
+displays the message "str" and an OK button,
+<LI> <CODE>AskString(prompt, default)</CODE>
+asks for a string, displays OK and Cancel buttons,
+<LI> <CODE>AskYesNoCancel(question, default)</CODE>
+displays a question and Yes, No and Cancel buttons.
+</UL>
+
+<A NAME="res"><CODE>Res</CODE></A> is a pretty complete interface to
+the MacOS Resource Manager, described fully in Inside Mac. There is
+currently no documentation of it, but the Apple documentation (or
+Think Ref) will help you on your way if you remember two points:
+<UL>
+<LI> Resources are implemented as Python objects, and each routine
+with a resource first argument is implemented as a python method.
+<LI> When in doubt about the arguments examine the routines docstring,
+as in <CODE>print Res.OpenResFile.__doc__</CODE>
+</UL>
+  	
+Similarly, <A NAME="dlg"><CODE>Dlg</CODE></A> is an interface to the
+Dialog manager (with Dialogs being implemented as python objects and
+routines with Dialog arguments being methods). The sys module you
+know, I hope.  The string module is an often used module that enables
+you to perform many string related operations.  In this case however, we
+are only using the "digits" constant from the string module.  We could
+have simply defined "digits" as "0123456789".  The socket module enables 
+us to perform the domain name lookups. We
+use two calls from it:
+<UL>
+<LI> <CODE>gethostbyaddr()</CODE>
+returns the hostname associated with an IP address
+<LI> <CODE>gethostbyname()</CODE>
+returns the IP address associated with a hostname
+</UL>
+  
+Next in the source file we get definitions for our dialog resource
+number and for the item numbers in our dialog. These should match the
+situation in our resource file dnslookup-1.rsrc,
+obviously.<p>
+
+On to the main program. We start off with opening our resource file,
+which should live in the same folder as the python source. If we
+cannot open it we use <CODE>EasyDialogs</CODE> to print a message and
+exit. You can try it: just move the resource file somewhere else for a
+moment. Then we call do_dialog() to do the real work. <p>
+
+<CODE>Do_dialog()</CODE> uses <CODE>Dlg.GetNewDialog()</CODE> to open
+a dialog window initialized from 'DLOG' resource ID_MAIN and putting
+it on screen in the frontmost position.  Next, we go into a loop,
+calling <CODE>Dlg.ModalDialog()</CODE> to wait for the next user
+action. <CODE>ModalDialog()</CODE> will return us the item number that
+the user has clicked on (or otherwise activated). It will handle a few
+slightly more complicated things also, like the user typing into
+simple textfields, but it will <EM>not</EM> do things like updating
+the physical appearance of radio buttons, etc. See Inside Mac or
+another programming guide for how to handle this
+yourself. Fortunately, our simple application doesn't have to bother with this,
+since buttons and textfields are the only active elements we have. So, we do a
+simple switch on item number and call the appropriate routine to implement the
+action requested. Upon the user pressing "Quit" we simply leave the loop and,
+hence, <CODE>do_dialog()</CODE>. This will cause the python dialog object
+<CODE>my_dlg</CODE> to be deleted and the on-screen dialog to disappear. <p>
+
+<A NAME="dialog-warning">Time for a warning</A>: be very careful what
+you do as long as a dialog is on-screen.  Printing something, for
+instance, may suddenly cause the standard output window to appear over
+the dialog, and since we took no measures to redraw the dialog it will
+become very difficult to get out of the dialog. Also, command-period
+may or may not work in this situation. I have also seen crashes in
+such a situation, probably due to the multiple event loops involved or
+some oversight in the interpreter. You have been warned. <p>
+
+The implementation of the "Lookup" command can use a bit more
+explaining: we get the necessary information with <CODE>dnslookup()</CODE>
+but now we have to update the on-screen dialog to present this
+information to the user. The <CODE>GetDialogItem()</CODE> method of
+the dialog returns three bits of information about the given item: its
+type, its data handle and its rect (the on-screen <CODE>x,y,w,h</CODE>
+coordinates). We are only interested in the data handle here, on which
+we call <CODE>SetDialogItemText()</CODE> to set our new text.  Note
+here that python programmers need not bother with the C-string versus
+pascal-string controversy: the python glue module knows what is needed
+and converts the python string to the correct type. <p>
+
+And that concludes our first example of the use of resources and
+dialogs. Next, you could have a look at the source of EasyDialogs for
+some examples of using input fields and filterprocs. Or, go on with
+reading the <A HREF="example2.html">second part</A> of this document
+to see how to implement a better version of this application.<p>
+
+</BODY>
+</HTML>
+

Added: vendor/Python/current/Mac/Demo/example2/dnslookup-2.gif
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Mac/Demo/example2/dnslookup-2.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Mac/Demo/example2/dnslookup-2.py
===================================================================
--- vendor/Python/current/Mac/Demo/example2/dnslookup-2.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Demo/example2/dnslookup-2.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,86 @@
+import FrameWork
+import EasyDialogs
+from Carbon import Res
+from Carbon import Dlg
+import sys
+import socket
+import string
+import macresource
+#
+# Definitions for our resources
+ID_MAIN=512
+ID_ABOUT=513
+
+ITEM_LOOKUP_ENTRY=1
+ITEM_RESULT=2
+ITEM_LOOKUP_BUTTON=3
+
+def main():
+    macresource.need("DLOG", ID_MAIN, "dnslookup-2.rsrc")
+    DNSLookup()
+
+class DNSLookup(FrameWork.Application):
+    "Application class for DNS Lookup"
+
+    def __init__(self):
+        # First init menus, etc.
+        FrameWork.Application.__init__(self)
+        # Next create our dialog
+        self.main_dialog = MyDialog(self)
+        # Now open the dialog
+        self.main_dialog.open(ID_MAIN)
+        # Finally, go into the event loop
+        self.mainloop()
+
+    def makeusermenus(self):
+        self.filemenu = m = FrameWork.Menu(self.menubar, "File")
+        self.quititem = FrameWork.MenuItem(m, "Quit", "Q", self.quit)
+
+    def quit(self, *args):
+        self._quit()
+
+    def do_about(self, *args):
+        f = Dlg.GetNewDialog(ID_ABOUT, -1)
+        while 1:
+            n = Dlg.ModalDialog(None)
+            if n == 1:
+                return
+
+class MyDialog(FrameWork.DialogWindow):
+    "Main dialog window for DNSLookup"
+    def __init__(self, parent):
+        FrameWork.DialogWindow.__init__(self, parent)
+        self.parent = parent
+
+    def do_itemhit(self, item, event):
+        if item == ITEM_LOOKUP_BUTTON:
+            self.dolookup()
+
+    def dolookup(self):
+        """Get text entered in the lookup entry area.  Place result of the
+           call to dnslookup in the result entry area."""
+        tp, h, rect = self.dlg.GetDialogItem(ITEM_LOOKUP_ENTRY)
+        txt = Dlg.GetDialogItemText(h)
+
+        tp, h, rect = self.dlg.GetDialogItem(ITEM_RESULT)
+        Dlg.SetDialogItemText(h, self.dnslookup(txt))
+
+    def dnslookup(self, str):
+        """ Perform DNS lookup on str.  If first character of digit is numeric,
+            assume that str contains an IP address.  Otherwise, assume that str
+            contains a hostname."""
+        if str == '': str = ' '
+        if str[0] in string.digits:
+            try:
+                value = socket.gethostbyaddr(str)[0]
+            except:
+                value = 'Lookup failed'
+        else:
+            try:
+                value = socket.gethostbyname(str)
+            except:
+                value = 'Lookup failed'
+        return value
+
+
+main()

Added: vendor/Python/current/Mac/Demo/example2/dnslookup-2.rsrc
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Mac/Demo/example2/dnslookup-2.rsrc
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Mac/Demo/example2.html
===================================================================
--- vendor/Python/current/Mac/Demo/example2.html	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Demo/example2.html	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,162 @@
+<HTML><HEAD><TITLE>Using python to create Macintosh applications, part two</TITLE></HEAD>
+<BODY>
+<H1>Using python to create Macintosh applications, part two</H1>
+<HR>
+
+In this document we rewrite the application of the <A
+HREF="example1.html">previous example</A> to use modeless dialogs. We
+will use an application framework, and we will have a look at creating
+applets, standalone applications written in Python.  The <A
+HREF="example2/dnslookup-2.py">source code</A> and 
+<A HREF="example2/dnslookup-2.rsrc">resource file</A> are available in the folder 
+<A HREF="example2">example2</A>. <p>
+
+Again, we start with ResEdit to create our dialogs. Not only do we
+want a main dialog this time but also an "About" dialog.  This example is less
+than complete since we do not provide a <A NAME="bundle">BNDL resource</A> 
+and related stuff that an application cannot be without. We are able to do this
+when building a python applet since BuildApplet will substitute default resources
+for BNDL, etc. when none are supplied (<A HREF="#no-bundle">See below</A>.)
+"Inside Mac" or various
+books on Macintosh programming will help here. Also, you can refer to
+the resource files provided in the Python source distribution for some
+of the python-specific points of BNDL programming: the
+"appletbundle.rsrc" file is what is used for creating applets if you
+don't provide your own resource file. <p>
+
+When creating your own BNDL resouorces, keep in mind that the Finder gets 
+confused if you have more than one application with the same signature. This may be due 
+to some incorrectness on the side of "BuildApplet", I am not sure.  There is one 
+case when you definitely need a unique signature: when you create an applet that 
+has its own data files and you want the user to be able to start your
+applet by double-clicking one of the datafiles. <p>
+
+Let's have a look at dnslookup-2.rsrc, our resource file. Dialog 512 is the
+main window which has one button (Lookup), two labels and
+two text entry areas, one of which is used for output only. The "Quit"
+button has disappeared, because its function is handled by a menu choice.  Here's
+what it will look like at run time:<p>
+<div align=center>
+<img width=324 height=205 src="example2/dnslookup-2.gif" alt="dialog image">
+</div>
+<p>
+
+<H2>A modeless dialog application using FrameWork</H2>
+
+On to the source code in <A
+HREF="example2/dnslookup-2.py">dnslookup-2.py</A>.  The
+start is similar to our previous example program <A
+HREF="example1/dnslookup-1.py">dnslookup-1.py</A>, with
+one extra module being imported. To make life more simple we will use
+the <CODE>FrameWork</CODE> module, a nifty piece of code that handles
+all the gory Mac details of event loop programming, menubar
+installation and all the other code that is the same for every Mac
+program in the world.  Like most standard modules, FrameWork will run
+some sample test code when you invoke it as a main program, so try it
+now. It will create a menu bar with an Apple menu with the about box
+and a "File" menu with some pythonesque choices (which do nothing
+interesting, by the way) and a "Quit" command that works. <p>
+
+<BLOCKQUOTE>
+If you have not used <code>FrameWork</code> before you may want to
+first take a look at the <A HREF="textedit.html">Pathetic EDitor</A>
+example, which builds a minimal text editor using FrameWork and TextEdit.
+On the other hand: we don't use many features of FrameWork, so you could
+also continue with this document. 
+</BLOCKQUOTE>
+
+After the imports we get the definitions of resource-IDs in our
+resource file, slightly changed from the previous version of our
+program. The main program is also
+similar to our previous version, with one important exception: we
+first check to see whether our resource is available before opening
+the resource file. Why is this? Because later, when we will have
+converted the script to an applet, our resources will be available in
+the applet file and we don't need the separate resource file
+anymore. <p>
+
+Next comes the definition of our main class,
+<CODE>DNSLookup</CODE>, which inherits
+<CODE>FrameWork.Application</CODE>. The Application class handles the
+menu bar and the main event loop and event dispatching. In the
+<CODE>__init__</CODE> routine we first let the base class initialize
+itself, then we create our modeless dialog and finally we jump into
+the main loop. The main loop continues until we call <CODE>self._quit</CODE>,
+which we will do when the user selects "Quit". When we create
+the instance of <CODE>MyDialog</CODE> (which inherits
+<CODE>DialogWindow</CODE>, which inherits <CODE>Window</CODE>) we pass
+a reference to the application object, this reference is used to tell
+Application about our new window.  This enables the event loop to keep
+track of all windows and dispatch things like update events and mouse
+clicks. <p>
+
+The <CODE>makeusermenus()</CODE> method (which is called sometime
+during the Application <CODE>__init__</CODE> routine) creates a File
+menu with a Quit command (shortcut command-Q), which will callback to
+our quit() method. <CODE>Quit()</CODE>, in turn, calls <CODE>_quit</CODE> which
+causes the mainloop to terminate at a convenient time. <p>
+
+Application provides a standard about box, but we override this by
+providing our own <CODE>do_about()</CODE> method which shows an about
+box from a resource as a modal dialog. This piece of code should look
+familiar to you from the previous example program. That do_about is
+called when the user selects About from the Apple menu is, again,
+taken care of by the __init__ routine of Application. <p>
+
+The <CODE>MyDialog</CODE> class is the container for our main
+window. Initialization is again done by first calling the base class
+<CODE>__init__</CODE> function and finally setting the local variable
+"parent." <p>
+
+<CODE>Do_itemhit()</CODE> is called when an item is selected in this
+dialog by the user. We are passed the item number (and the original
+event structure, which we normally ignore). The code is similar to the
+main loop of our previous example program: a switch depending on the
+item selected.  <CODE>Dnslookup()</CODE> is quite similar to our previous 
+example. <p>
+
+<H2><IMG SRC="html.icons/mkapplet.gif"><A NAME="applets">Creating applets</A></H2>
+
+Now let us try to turn the python script into an applet, a standalone
+application. This will <em>not</em> work if you have the "classic 68k"
+Python distribution, only if you have the cfm68k or PPC distribution.
+
+<blockquote>
+Actually, "standalone" is probably not the correct term here, since an
+applet does still depend on a lot of the python environment: the
+PythonCore shared library, the Python Preferences file, the python Lib
+folder and any other modules that the main module depends on. It is
+possible to get rid of all these dependencies and create true standalone
+applications in Python, but this is a bit difficult. See <a href="freezing.html">
+Standalone Applications in Python</a> for details. For this
+document, by standalone we mean here that
+the script has the look-and-feel of an application, including the
+ability to have its own document types, be droppable, etc.
+</blockquote>
+
+The easiest way to create an applet is to take your source file and
+drop it onto "BuildApplet", located in the Python home
+folder. This will create an applet with the same name as your python
+source with the ".py" stripped. Also, if a resource file with the same
+name as your source but with ".rsrc" extension is available the
+resources from that file will be copied to your applet too. If there
+is no resource file for your script a set of default resources will be
+used, and the applet will have the default creator 'Pyt0'. The latter
+also happens if you do have a resource file but without the BNDL
+combo. <A NAME="no-bundle">Actually</A>, as in the present example.
+<p>
+
+If you need slightly more control over the BuildApplet process you can
+double-click it, and you will get dialogs for source and
+destination of the applet. The rest of the process, including locating
+the resource file, remains the same. <p>
+
+Note that though our example application completely bypasses the
+normal python user interface this is by no means necessary. Any python
+script can be turned into an applet, and all the usual features of the
+interpreter still work. <p>
+
+That's all for this example, you may now return to the <A HREF="index.html">
+table of contents</A> to pick another topic. <p>
+</BODY>
+</HTML>

Added: vendor/Python/current/Mac/Demo/html.icons/createmake.png
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Mac/Demo/html.icons/createmake.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Mac/Demo/html.icons/mkapplet.gif
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Mac/Demo/html.icons/mkapplet.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Mac/Demo/html.icons/modulator.gif
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Mac/Demo/html.icons/modulator.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Mac/Demo/html.icons/options.gif
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Mac/Demo/html.icons/options.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Mac/Demo/html.icons/preferences.gif
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Mac/Demo/html.icons/preferences.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Mac/Demo/html.icons/python.gif
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Mac/Demo/html.icons/python.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Mac/Demo/imgbrowse/imgbrowse.py
===================================================================
--- vendor/Python/current/Mac/Demo/imgbrowse/imgbrowse.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Demo/imgbrowse/imgbrowse.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,117 @@
+"""imgbrowse - Display pictures using img"""
+
+import FrameWork
+import EasyDialogs
+from Carbon import Res
+from Carbon import Qd
+from Carbon import QuickDraw
+from Carbon import Win
+#ifrom Carbon mport List
+import sys
+import struct
+import img
+import imgformat
+import struct
+import mac_image
+
+
+# Where is the picture window?
+LEFT=200
+TOP=64
+MINWIDTH=64
+MINHEIGHT=64
+MAXWIDTH=320
+MAXHEIGHT=320
+
+
+def main():
+    print 'hello world'
+    imgbrowse()
+
+class imgbrowse(FrameWork.Application):
+    def __init__(self):
+        # First init menus, etc.
+        FrameWork.Application.__init__(self)
+        self.lastwin = None
+        # Finally, go into the event loop
+        self.mainloop()
+
+    def makeusermenus(self):
+        self.filemenu = m = FrameWork.Menu(self.menubar, "File")
+        self.openitem = FrameWork.MenuItem(m, "Open...", "O", self.opendoc)
+        self.infoitem = FrameWork.MenuItem(m, "Info", "I", self.info)
+        self.quititem = FrameWork.MenuItem(m, "Quit", "Q", self.quit)
+
+    def quit(self, *args):
+        self._quit()
+
+    def opendoc(self, *args):
+        pathname = EasyDialogs.AskFileForOpen() # Any file type
+        if not pathname:
+            return
+        bar = EasyDialogs.ProgressBar('Reading and converting...')
+        try:
+            rdr = img.reader(imgformat.macrgb16, pathname)
+        except img.error, arg:
+            EasyDialogs.Message(repr(arg))
+            return
+        w, h = rdr.width, rdr.height
+        bar.set(10)
+        data = rdr.read()
+        del bar
+        pixmap = mac_image.mkpixmap(w, h, imgformat.macrgb16, data)
+        self.showimg(w, h, pixmap, data)
+
+    def showimg(self, w, h, pixmap, data):
+        win = imgwindow(self)
+        win.open(w, h, pixmap, data)
+        self.lastwin = win
+
+    def info(self, *args):
+        if self.lastwin:
+            self.lastwin.info()
+
+class imgwindow(FrameWork.Window):
+    def open(self, width, height, pixmap, data):
+        self.pixmap = pixmap
+        self.data = data
+        self.pictrect = (0, 0, width, height)
+        bounds = (LEFT, TOP, LEFT+width, TOP+height)
+
+        self.wid = Win.NewCWindow(bounds, "Picture", 1, 0, -1, 1, 0)
+        self.do_postopen()
+
+    def do_update(self, *args):
+        pass
+        currect = self.fitrect()
+        print 'PICT:', self.pictrect
+        print 'WIND:', currect
+        print 'ARGS:', (self.pixmap, self.wid.GetWindowPort().GetPortBitMapForCopyBits(), self.pictrect,
+                        currect, QuickDraw.srcCopy, None)
+        self.info()
+        Qd.CopyBits(self.pixmap, self.wid.GetWindowPort().GetPortBitMapForCopyBits(), self.pictrect,
+                        currect, QuickDraw.srcCopy, None)
+
+    def fitrect(self):
+        """Return self.pictrect scaled to fit in window"""
+        graf = self.wid.GetWindowPort()
+        screenrect = graf.GetPortBounds()
+        picwidth = self.pictrect[2] - self.pictrect[0]
+        picheight = self.pictrect[3] - self.pictrect[1]
+        if picwidth > screenrect[2] - screenrect[0]:
+            factor = float(picwidth) / float(screenrect[2]-screenrect[0])
+            picwidth = picwidth / factor
+            picheight = picheight / factor
+        if picheight > screenrect[3] - screenrect[1]:
+            factor = float(picheight) / float(screenrect[3]-screenrect[1])
+            picwidth = picwidth / factor
+            picheight = picheight / factor
+        return (screenrect[0], screenrect[1], screenrect[0]+int(picwidth),
+                        screenrect[1]+int(picheight))
+
+    def info(self):
+        graf = self.wid.GetWindowPort()
+        bits = graf.GetPortBitMapForCopyBits()
+        mac_image.dumppixmap(bits.pixmap_data)
+
+main()

Added: vendor/Python/current/Mac/Demo/imgbrowse/mac_image.py
===================================================================
--- vendor/Python/current/Mac/Demo/imgbrowse/mac_image.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Demo/imgbrowse/mac_image.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,56 @@
+"""mac_image - Helper routines (hacks) for images"""
+import imgformat
+from Carbon import Qd
+import time
+import struct
+import MacOS
+
+_fmt_to_mac = {
+        imgformat.macrgb16 : (16, 16, 3, 5),
+}
+
+def mkpixmap(w, h, fmt, data):
+    """kludge a pixmap together"""
+    fmtinfo = _fmt_to_mac[fmt]
+
+    rv = struct.pack("lHhhhhhhlllhhhhlll",
+            id(data)+MacOS.string_id_to_buffer, # HACK HACK!!
+            w*2 + 0x8000,
+            0, 0, h, w,
+            0,
+            0, 0, # XXXX?
+            72<<16, 72<<16,
+            fmtinfo[0], fmtinfo[1],
+            fmtinfo[2], fmtinfo[3],
+            0, 0, 0)
+##      print 'Our pixmap, size %d:'%len(rv)
+##      dumppixmap(rv)
+    return Qd.RawBitMap(rv)
+
+def dumppixmap(data):
+    baseAddr, \
+            rowBytes, \
+            t, l, b, r, \
+            pmVersion, \
+            packType, packSize, \
+            hRes, vRes, \
+            pixelType, pixelSize, \
+            cmpCount, cmpSize, \
+            planeBytes, pmTable, pmReserved \
+                    = struct.unpack("lhhhhhhhlllhhhhlll", data)
+    print 'Base:       0x%x'%baseAddr
+    print 'rowBytes:   %d (0x%x)'%(rowBytes&0x3fff, rowBytes)
+    print 'rect:       %d, %d, %d, %d'%(t, l, b, r)
+    print 'pmVersion:  0x%x'%pmVersion
+    print 'packing:    %d %d'%(packType, packSize)
+    print 'resolution: %f x %f'%(float(hRes)/0x10000, float(vRes)/0x10000)
+    print 'pixeltype:  %d, size %d'%(pixelType, pixelSize)
+    print 'components: %d, size %d'%(cmpCount, cmpSize)
+    print 'planeBytes: %d (0x%x)'%(planeBytes, planeBytes)
+    print 'pmTable:    0x%x'%pmTable
+    print 'pmReserved: 0x%x'%pmReserved
+    for i in range(0, len(data), 16):
+        for j in range(16):
+            if i + j < len(data):
+                print '%02.2x'%ord(data[i+j]),
+        print

Added: vendor/Python/current/Mac/Demo/index.html
===================================================================
--- vendor/Python/current/Mac/Demo/index.html	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Demo/index.html	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,156 @@
+<HTML><HEAD><TITLE>Macintosh Python crash course</TITLE></HEAD>
+<BODY>
+<H1><IMG SRC="html.icons/python.gif">Macintosh Python crash course</H1>
+<HR>
+
+<p>This set of documents provides an introduction to various aspects of
+Python programming on the Mac. It is assumed that the reader is
+already familiar with Python and, to some extent, with MacOS Toolbox
+programming. Other readers may find something interesting here too,
+your mileage may vary. </p>
+
+<p>As the previous paragraph reveals to the careful observer these examples
+are dated, most of them were writting before OSX and haven't been updated
+afterwards. They still show how to use the Carbon wrappers but aren't 
+necessarily the best way to use the Carbon API's in OSX.</p>
+
+Another set of Macintosh-savvy examples, more aimed at beginners, is
+maintained by Joseph Strout, at Python Tidbits in <A
+HREF="http://www.strout.net/python/">
+http://www.strout.net/python/</A>.
+<P>
+
+The <a href="http://www.python.org/doc/lib/Top.html">Python Library
+Reference</a> contains a section on <a
+href="http://www.python.org/doc/lib/Macintosh-Specific-Services.html">Macintosh-specific
+modules</a> that you should also read. Documentation is also available
+in PostScript and other forms, see the <a
+href="http://www.python.org/doc/">documentation</a> section on the
+webserver. <p>
+
+<p>The W widget set by Just van Rossum, does not have complete documentation as 
+of this writing, but Corran Webster has documented most of it on his
+<A HREF="http://www.nevada.edu/~cwebster/Python/">Python Page</A>.</p>
+
+There are also some documentation links, as well as other MacPython-related
+pages, in the
+<A HREF="http://dmoz.org/Computers/Systems/Macintosh/Development/Scripting/Python/">
+Open Directory</A>.
+
+
+<H2>Table of contents</H2>
+
+<blockquote><B>Note:</B>
+Some of these documents were actually written a long time ago and have seen
+little maintainance, so use with care. </blockquote>
+<UL>
+<LI>
+<A HREF="example0.html">Using python to create Macintosh applications,
+part zero</A> whets your appetite by showing you how to ask the user
+for a filename, and how to display a message. It explains about end-of-line
+confusion while doing so.
+
+<LI>
+<A HREF="example1.html">Using python to create Macintosh applications,
+part one</A> explains how to create a simple modal-dialog application
+in Python. It also takes a glance at using the toolbox modules Res and
+Dlg, and EasyDialogs for simple question-dialogs.
+
+<LI>
+<A HREF="example2.html">Using python to create Macintosh applications,
+part two</A> turns the previous example program into a more complete
+mac application, using a modeless dialog, menus, etc. It also explains
+how to create applets, standalone applications written in Python.
+
+<LI>
+<A HREF="freezing.html">Freezing Python programs</A> extends on this concept,
+and shows you how to create applications that can be used on machines without
+a full Python installed. This one is probably best skipped on first contact
+with MacPython.
+
+<LI>
+<A HREF="textedit.html">Using FrameWork and TextEdit</A> shows you
+how to use <code>FrameWork</code> application framework and the
+<code>TextEdit</code> toolbox to build a text editor.
+
+<LI>
+<A HREF="plugins.html">Creating a C extension module on the Macintosh</A>
+is meant for the hardcore programmer, and shows how to create an
+extension module in C. It also handles using Modulator to create the
+boilerplate for your module, and creating dynamically-loadable modules
+on PowerPC Macs. It assumes you use CodeWarrior for you development.
+
+<LI>
+<A HREF="mpwextensions.html">Creating C extension modules using MPW</A>
+is a companion document, written by Corran Webster, which explains how you
+can develop Python extensions using Apple's free MPW compiler environment.
+
+<LI>
+<A HREF="applescript.html">Using Open Scripting Architecture from Python</A> explains
+how to create a Python module interfacing to a scriptable application,
+and how to use that module in your python program.
+
+<LI>
+<A HREF="cgi.html">Using python to create CGI scripts</A> is a preliminary
+introduction to writing CGI scripts in Python and to writing scriptable applications
+in Python.
+
+<LI>
+<A HREF="building.html">Building Mac Python from source</A> explains
+how to build a PPC or 68K interpreter from a source distribution.
+
+<LI>
+<A HREF="embed.html">Embedding Python on the Mac</A> is a minimal example of
+how to embed Python in other Mac applications.
+
+</UL>
+
+The Python distribution contains a few more examples, all unexplained:
+<UL>
+<LI>
+<I>PICTbrowse</I> is an application that locates PICT
+resources and displays them, it demonstrates some quickdraw and the
+resource and list managers. In the same folder you will find the very
+similar scripts ICONbrowse and cicnbrowse. oldPICTbrowse is the same program
+but form the pre-Appearance era, it uses a dialog with a user item and
+creates and manages its own List object.
+
+<LI>
+<I>Imgbrowse</I> displays image files in
+many different formats (gif, tiff, pbm, etc). It shows how to use the
+img modules on the mac.
+
+<LI>
+<I>Quicktime</I> has the standard <code>MovieInWindow</code> and
+<code>VerySimplePlayer</code> examples, re-coded in Python.
+
+<LI>
+<I>Resources</I>, <I>Sound</I> and <I>Speech</I> have some examples
+on using the respective managers. In the <i>Mac:Lib</i> folder you
+will also find modules that do useful things with the Communications
+Toolbox, the Finder interface, etc.
+
+<LI>
+<I>Printing</I> has an example on using the Printing module to, you guessed
+it, print from Python. The code is somewhat self-documenting. Donated
+by Just van Rossum, who also donated the Printing module itself.
+</UL>
+
+At some point in the (possibly distant) future, I will add chapters on
+how to use bgen to create modules completely automatic and how to make
+your Python program scriptable, but that will have to wait. <p>
+
+<HR>
+
+Please let me know if you miss critical information in this
+document. I am quite sure that I will never find the time to turn it
+into a complete MacPython programmers guide (which would probably be a
+400-page book instead of 10 lousy html-files), but it should contain
+at least the information that is neither in the standard Python
+documentation nor in Inside Mac or other Mac programmers
+documentation. <p>
+
+<HR>
+<A HREF="http://www.cwi.nl/~jack">Jack Jansen</A>,
+<A HREF="mailto:jack at cwi.nl">jack at cwi.nl</A>, 22-Apr-00.
+</BODY></HTML>

Added: vendor/Python/current/Mac/Demo/mlte/mlted.py
===================================================================
--- vendor/Python/current/Mac/Demo/mlte/mlted.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Demo/mlte/mlted.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,374 @@
+# A minimal text editor using MLTE. Based on wed.py.
+#
+# To be done:
+# - Functionality: find, etc.
+
+from Menu import DrawMenuBar
+from FrameWork import *
+from Carbon import Win
+from Carbon import Ctl
+from Carbon import Qd
+from Carbon import Res
+from Carbon import Scrap
+import os
+from Carbon import MacTextEditor
+from Carbon import Mlte
+
+UNDOLABELS = [ # Indexed by MLTECanUndo() value
+        "Typing", "Cut", "Paste", "Clear", "Font Change", "Color Change", "Size Change",
+        "Style Change", "Align Left", "Align Center", "Align Right", "Drop", "Move"]
+
+class MlteWindow(Window):
+    def open(self, path, name, data):
+        self.path = path
+        self.name = name
+        r = windowbounds(400, 400)
+        w = Win.NewWindow(r, name, 1, 0, -1, 1, 0)
+        self.wid = w
+        flags = MacTextEditor.kTXNDrawGrowIconMask|MacTextEditor.kTXNWantHScrollBarMask| \
+                        MacTextEditor.kTXNWantVScrollBarMask
+        self.ted, self.frameid = Mlte.TXNNewObject(None, w, None, flags, MacTextEditor.kTXNTextEditStyleFrameType,
+                        MacTextEditor.kTXNTextFile, MacTextEditor.kTXNMacOSEncoding)
+        self.ted.TXNSetData(MacTextEditor.kTXNTextData, data, 0, 0x7fffffff)
+        self.changed = 0
+        self.do_postopen()
+        self.do_activate(1, None)
+
+    def do_idle(self, event):
+        self.ted.TXNIdle()
+        self.ted.TXNAdjustCursor(None)
+
+
+
+    def do_activate(self, onoff, evt):
+        if onoff:
+##                      self.ted.TXNActivate(self.frameid, 0)
+            self.ted.TXNFocus(1)
+            self.parent.active = self
+        else:
+            self.ted.TXNFocus(0)
+            self.parent.active = None
+        self.parent.updatemenubar()
+
+    def do_update(self, wid, event):
+        self.ted.TXNDraw(None)
+
+    def do_postresize(self, width, height, window):
+        self.ted.TXNResizeFrame(width, height, self.frameid)
+
+    def do_contentclick(self, local, modifiers, evt):
+        self.ted.TXNClick(evt)
+        self.parent.updatemenubar()
+
+    def do_char(self, ch, event):
+        self.ted.TXNKeyDown(event)
+        self.parent.updatemenubar()
+
+    def close(self):
+        if self.changed:
+            save = EasyDialogs.AskYesNoCancel('Save window "%s" before closing?'%self.name, 1)
+            if save > 0:
+                self.menu_save()
+            elif save < 0:
+                return
+        if self.parent.active == self:
+            self.parent.active = None
+        self.ted.TXNDeleteObject()
+        del self.ted
+##              del self.tedtexthandle
+        self.do_postclose()
+
+    def menu_save(self):
+        if not self.path:
+            self.menu_save_as()
+            return # Will call us recursively
+        dhandle = self.ted.TXNGetData(0, 0x7fffffff)
+        data = dhandle.data
+        fp = open(self.path, 'wb')  # NOTE: wb, because data has CR for end-of-line
+        fp.write(data)
+        if data[-1] <> '\r': fp.write('\r')
+        fp.close()
+        self.changed = 0
+
+    def menu_save_as(self):
+        path = EasyDialogs.AskFileForSave(message='Save as:')
+        if not path: return
+        self.path = path
+        self.name = os.path.split(self.path)[-1]
+        self.wid.SetWTitle(self.name)
+        self.menu_save()
+
+    def menu_cut(self):
+##              self.ted.WESelView()
+        self.ted.TXNCut()
+###             Mlte.ConvertToPublicScrap()
+##              Scrap.ZeroScrap()
+##              self.ted.WECut()
+##              self.updatescrollbars()
+        self.parent.updatemenubar()
+        self.changed = 1
+
+    def menu_copy(self):
+##              Scrap.ZeroScrap()
+        self.ted.TXNCopy()
+###             Mlte.ConvertToPublicScrap()
+##              self.updatescrollbars()
+        self.parent.updatemenubar()
+
+    def menu_paste(self):
+###             Mlte.ConvertFromPublicScrap()
+        self.ted.TXNPaste()
+##              self.updatescrollbars()
+        self.parent.updatemenubar()
+        self.changed = 1
+
+    def menu_clear(self):
+##              self.ted.WESelView()
+        self.ted.TXNClear()
+##              self.updatescrollbars()
+        self.parent.updatemenubar()
+        self.changed = 1
+
+    def menu_undo(self):
+        self.ted.TXNUndo()
+##              self.updatescrollbars()
+        self.parent.updatemenubar()
+
+    def menu_redo(self):
+        self.ted.TXNRedo()
+##              self.updatescrollbars()
+        self.parent.updatemenubar()
+
+    def have_selection(self):
+        start, stop = self.ted.TXNGetSelection()
+        return start < stop
+
+    def can_paste(self):
+        return Mlte.TXNIsScrapPastable()
+
+    def can_undo(self):
+        can, which = self.ted.TXNCanUndo()
+        if not can:
+            return None
+        if which >= len(UNDOLABELS):
+            # Unspecified undo
+            return "Undo"
+        which = UNDOLABELS[which]
+
+        return "Undo "+which
+
+    def can_redo(self):
+        can, which = self.ted.TXNCanRedo()
+        if not can:
+            return None
+        if which >= len(UNDOLABELS):
+            # Unspecified undo
+            return "Redo"
+        which = UNDOLABELS[which]
+
+        return "Redo "+which
+
+class Mlted(Application):
+    def __init__(self):
+        Application.__init__(self)
+        self.num = 0
+        self.active = None
+        self.updatemenubar()
+
+    def makeusermenus(self):
+        self.filemenu = m = Menu(self.menubar, "File")
+        self.newitem = MenuItem(m, "New window", "N", self.open)
+        self.openitem = MenuItem(m, "Open...", "O", self.openfile)
+        self.closeitem = MenuItem(m, "Close", "W", self.closewin)
+        m.addseparator()
+        self.saveitem = MenuItem(m, "Save", "S", self.save)
+        self.saveasitem = MenuItem(m, "Save as...", "", self.saveas)
+        m.addseparator()
+        self.quititem = MenuItem(m, "Quit", "Q", self.quit)
+
+        self.editmenu = m = Menu(self.menubar, "Edit")
+        self.undoitem = MenuItem(m, "Undo", "Z", self.undo)
+        self.redoitem = MenuItem(m, "Redo", None, self.redo)
+        m.addseparator()
+        self.cutitem = MenuItem(m, "Cut", "X", self.cut)
+        self.copyitem = MenuItem(m, "Copy", "C", self.copy)
+        self.pasteitem = MenuItem(m, "Paste", "V", self.paste)
+        self.clearitem = MenuItem(m, "Clear", "", self.clear)
+
+        # Groups of items enabled together:
+        self.windowgroup = [self.closeitem, self.saveitem, self.saveasitem, self.editmenu]
+        self.focusgroup = [self.cutitem, self.copyitem, self.clearitem]
+        self.windowgroup_on = -1
+        self.focusgroup_on = -1
+        self.pastegroup_on = -1
+        self.undo_label = "never"
+        self.redo_label = "never"
+
+    def updatemenubar(self):
+        changed = 0
+        on = (self.active <> None)
+        if on <> self.windowgroup_on:
+            for m in self.windowgroup:
+                m.enable(on)
+            self.windowgroup_on = on
+            changed = 1
+        if on:
+            # only if we have an edit menu
+            on = self.active.have_selection()
+            if on <> self.focusgroup_on:
+                for m in self.focusgroup:
+                    m.enable(on)
+                self.focusgroup_on = on
+                changed = 1
+            on = self.active.can_paste()
+            if on <> self.pastegroup_on:
+                self.pasteitem.enable(on)
+                self.pastegroup_on = on
+                changed = 1
+            on = self.active.can_undo()
+            if on <> self.undo_label:
+                if on:
+                    self.undoitem.enable(1)
+                    self.undoitem.settext(on)
+                    self.undo_label = on
+                else:
+                    self.undoitem.settext("Nothing to undo")
+                    self.undoitem.enable(0)
+                changed = 1
+            on = self.active.can_redo()
+            if on <> self.redo_label:
+                if on:
+                    self.redoitem.enable(1)
+                    self.redoitem.settext(on)
+                    self.redo_label = on
+                else:
+                    self.redoitem.settext("Nothing to redo")
+                    self.redoitem.enable(0)
+                changed = 1
+        if changed:
+            DrawMenuBar()
+
+    #
+    # Apple menu
+    #
+
+    def do_about(self, id, item, window, event):
+        EasyDialogs.Message("A simple single-font text editor based on MacTextEditor")
+
+    #
+    # File menu
+    #
+
+    def open(self, *args):
+        self._open(0)
+
+    def openfile(self, *args):
+        self._open(1)
+
+    def _open(self, askfile):
+        if askfile:
+            path = EasyDialogs.AskFileForOpen(typeList=('TEXT',))
+            if not path:
+                return
+            name = os.path.split(path)[-1]
+            try:
+                fp = open(path, 'rb') # NOTE binary, we need cr as end-of-line
+                data = fp.read()
+                fp.close()
+            except IOError, arg:
+                EasyDialogs.Message("IOERROR: %r" % (arg,))
+                return
+        else:
+            path = None
+            name = "Untitled %d"%self.num
+            data = ''
+        w = MlteWindow(self)
+        w.open(path, name, data)
+        self.num = self.num + 1
+
+    def closewin(self, *args):
+        if self.active:
+            self.active.close()
+        else:
+            EasyDialogs.Message("No active window?")
+
+    def save(self, *args):
+        if self.active:
+            self.active.menu_save()
+        else:
+            EasyDialogs.Message("No active window?")
+
+    def saveas(self, *args):
+        if self.active:
+            self.active.menu_save_as()
+        else:
+            EasyDialogs.Message("No active window?")
+
+
+    def quit(self, *args):
+        for w in self._windows.values():
+            w.close()
+        if self._windows:
+            return
+        self._quit()
+
+    #
+    # Edit menu
+    #
+
+    def undo(self, *args):
+        if self.active:
+            self.active.menu_undo()
+        else:
+            EasyDialogs.Message("No active window?")
+
+    def redo(self, *args):
+        if self.active:
+            self.active.menu_redo()
+        else:
+            EasyDialogs.Message("No active window?")
+
+    def cut(self, *args):
+        if self.active:
+            self.active.menu_cut()
+        else:
+            EasyDialogs.Message("No active window?")
+
+    def copy(self, *args):
+        if self.active:
+            self.active.menu_copy()
+        else:
+            EasyDialogs.Message("No active window?")
+
+    def paste(self, *args):
+        if self.active:
+            self.active.menu_paste()
+        else:
+            EasyDialogs.Message("No active window?")
+
+    def clear(self, *args):
+        if self.active:
+            self.active.menu_clear()
+        else:
+            EasyDialogs.Message("No active window?")
+
+    #
+    # Other stuff
+    #
+
+    def idle(self, event):
+        if self.active:
+            self.active.do_idle(event)
+        else:
+            Qd.SetCursor(Qd.GetQDGlobalsArrow())
+
+def main():
+    Mlte.TXNInitTextension(0)
+    try:
+        App = Mlted()
+        App.mainloop()
+    finally:
+        Mlte.TXNTerminateTextension()
+
+if __name__ == '__main__':
+    main()

Added: vendor/Python/current/Mac/Demo/quicktime/MovieInWindow.py
===================================================================
--- vendor/Python/current/Mac/Demo/quicktime/MovieInWindow.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Demo/quicktime/MovieInWindow.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,70 @@
+"""MovieInWindow converted to python
+
+Jack Jansen, CWI, December 1995
+"""
+
+from Carbon import Qt
+from Carbon import QuickTime
+from Carbon import Qd
+from Carbon import QuickDraw
+from Carbon import Evt
+from Carbon import Events
+from Carbon import Win
+from Carbon import Windows
+from Carbon import File
+import EasyDialogs
+import sys
+import os
+
+
+def main():
+    # skip the toolbox initializations, already done
+    # XXXX Should use gestalt here to check for quicktime version
+    Qt.EnterMovies()
+
+    # Get the movie file
+    if len(sys.argv) > 1:
+        filename = sys.argv[1]
+    else:
+        filename = EasyDialogs.AskFileForOpen() # Was: QuickTime.MovieFileType
+    if not filename:
+        sys.exit(0)
+
+    # Open the window
+    bounds = (175, 75, 175+160, 75+120)
+    theWindow = Win.NewCWindow(bounds, os.path.split(filename)[1], 1, 0, -1, 0, 0)
+    Qd.SetPort(theWindow)
+    # XXXX Needed? SetGWorld((CGrafPtr)theWindow, nil)
+
+    playMovieInWindow(theWindow, filename, theWindow.GetWindowPort().GetPortBounds())
+
+def playMovieInWindow(theWindow, theFile, movieBox):
+    """Play a movie in a window"""
+    # XXXX Needed?  SetGWorld((CGrafPtr)theWindow, nil);
+
+    # Get the movie
+    theMovie = loadMovie(theFile)
+
+    # Set where we want it
+    theMovie.SetMovieBox(movieBox)
+
+    # Start at the beginning
+    theMovie.GoToBeginningOfMovie()
+
+    # Give a little time to preroll
+    theMovie.MoviesTask(0)
+
+    # Start playing
+    theMovie.StartMovie()
+
+    while not theMovie.IsMovieDone() and not Evt.Button():
+        theMovie.MoviesTask(0)
+
+def loadMovie(theFile):
+    """Load a movie given an fsspec. Return the movie object"""
+    movieResRef = Qt.OpenMovieFile(theFile, 1)
+    movie, d1, d2 = Qt.NewMovieFromFile(movieResRef, 0, QuickTime.newMovieActive)
+    return movie
+
+if __name__ == '__main__':
+    main()

Added: vendor/Python/current/Mac/Demo/quicktime/VerySimplePlayer.py
===================================================================
--- vendor/Python/current/Mac/Demo/quicktime/VerySimplePlayer.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Demo/quicktime/VerySimplePlayer.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,92 @@
+"""VerySimplePlayer converted to python
+
+Jack Jansen, CWI, December 1995
+"""
+
+from Carbon import Qt
+from Carbon import QuickTime
+from Carbon import Qd
+from Carbon import QuickDraw
+from Carbon import Evt
+from Carbon import Events
+from Carbon import Win
+from Carbon import Windows
+from Carbon import File
+import EasyDialogs
+import sys
+
+# XXXX maxbounds = (40, 40, 1000, 1000)
+
+def main():
+    print 'hello world' # XXXX
+    # skip the toolbox initializations, already done
+    # XXXX Should use gestalt here to check for quicktime version
+    Qt.EnterMovies()
+
+    # Get the movie file
+    fss = EasyDialogs.AskFileForOpen(wanted=File.FSSpec) # Was: QuickTime.MovieFileType
+    if not fss:
+        sys.exit(0)
+
+    # Open the window
+    bounds = (175, 75, 175+160, 75+120)
+    theWindow = Win.NewCWindow(bounds, fss.as_tuple()[2], 0, 0, -1, 1, 0)
+    # XXXX Needed? SetGWorld((CGrafPtr)theWindow, nil)
+    Qd.SetPort(theWindow)
+
+    # Get the movie
+    theMovie = loadMovie(fss)
+
+    # Relocate to (0, 0)
+    bounds = theMovie.GetMovieBox()
+    bounds = 0, 0, bounds[2]-bounds[0], bounds[3]-bounds[1]
+    theMovie.SetMovieBox(bounds)
+
+    # Create a controller
+    theController = theMovie.NewMovieController(bounds, QuickTime.mcTopLeftMovie)
+
+    # Get movie size and update window parameters
+    rv, bounds = theController.MCGetControllerBoundsRect()
+    theWindow.SizeWindow(bounds[2], bounds[3], 0)   # XXXX or [3] [2]?
+    Qt.AlignWindow(theWindow, 0)
+    theWindow.ShowWindow()
+
+    # XXXX MCDoAction(theController, mcActionSetGrowBoxBounds, &maxBounds)
+    theController.MCDoAction(QuickTime.mcActionSetKeysEnabled, '1')
+
+    # XXXX MCSetActionFilterWithRefCon(theController, movieControllerEventFilter, (long)theWindow)
+
+    done = 0
+    while not done:
+        gotone, evt = Evt.WaitNextEvent(0xffff, 0)
+        (what, message, when, where, modifiers) = evt
+##              print what, message, when, where, modifiers # XXXX
+
+        if theController.MCIsPlayerEvent(evt):
+            continue
+
+        if what == Events.mouseDown:
+            part, whichWindow = Win.FindWindow(where)
+            if part == Windows.inGoAway:
+                done = whichWindow.TrackGoAway(where)
+            elif part == Windows.inDrag:
+                Qt.DragAlignedWindow(whichWindow, where, (0, 0, 4000, 4000))
+        elif what == Events.updateEvt:
+            whichWindow = Win.WhichWindow(message)
+            if not whichWindow:
+                # Probably the console window. Print something, hope it helps.
+                print 'update'
+            else:
+                Qd.SetPort(whichWindow)
+                whichWindow.BeginUpdate()
+                Qd.EraseRect(whichWindow.GetWindowPort().GetPortBounds())
+                whichWindow.EndUpdate()
+
+def loadMovie(theFile):
+    """Load a movie given an fsspec. Return the movie object"""
+    movieResRef = Qt.OpenMovieFile(theFile, 1)
+    movie, d1, d2 = Qt.NewMovieFromFile(movieResRef, 0, QuickTime.newMovieActive)
+    return movie
+
+if __name__ == '__main__':
+    main()

Added: vendor/Python/current/Mac/Demo/resources/copyres.py
===================================================================
--- vendor/Python/current/Mac/Demo/resources/copyres.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Demo/resources/copyres.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,57 @@
+from Carbon.Res import *
+from Carbon.Resources import *
+import MacOS
+
+READ = 1
+WRITE = 2
+smAllScripts = -3
+
+def copyres(src, dst):
+    """Copy resource from src file to dst file."""
+
+    cur = CurResFile()
+    ctor, type = MacOS.GetCreatorAndType(src)
+    input = FSpOpenResFile(src, READ)
+    try:
+        FSpCreateResFile(dst, ctor, type, smAllScripts)
+    except:
+        raw_input("%s already exists...  CR to write anyway! " % dst)
+    output = FSpOpenResFile(dst, WRITE)
+    UseResFile(input)
+    ntypes = Count1Types()
+    for itype in range(1, 1+ntypes):
+        type = Get1IndType(itype)
+        nresources = Count1Resources(type)
+        for ires in range(1, 1+nresources):
+            res = Get1IndResource(type, ires)
+            res.LoadResource()
+            id, type, name = res.GetResInfo()
+            size = res.SizeResource()
+            attrs = res.GetResAttrs()
+            print id, type, name, size, hex(attrs)
+            res.DetachResource()
+            UseResFile(output)
+            try:
+                res2 = Get1Resource(type, id)
+            except (RuntimeError, Res.Error), msg:
+                res2 = None
+            if res2:
+                print "Duplicate type+id, not copied"
+                print (res2.size, res2.data)
+                print res2.GetResInfo()
+                if res2.HomeResFile() == output:
+                    'OK'
+                elif res2.HomeResFile() == input:
+                    'BAD!'
+                else:
+                    print 'Home:', res2.HomeResFile()
+            else:
+                res.AddResource(type, id, name)
+                #res.SetResAttrs(attrs)
+                res.WriteResource()
+            UseResFile(input)
+    UseResFile(cur)
+    CloseResFile(output)
+    CloseResFile(input)
+
+copyres('::python.¹.rsrc', '::foo.rsrc')

Added: vendor/Python/current/Mac/Demo/resources/listres.py
===================================================================
--- vendor/Python/current/Mac/Demo/resources/listres.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Demo/resources/listres.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,60 @@
+# List all resources
+
+from Carbon import Res
+from Carbon.Resources import *
+
+def list1resources():
+    ntypes = Res.Count1Types()
+    for itype in range(1, 1+ntypes):
+        type = Res.Get1IndType(itype)
+        print "Type:", repr(type)
+        nresources = Res.Count1Resources(type)
+        for i in range(1, 1 + nresources):
+            Res.SetResLoad(0)
+            res = Res.Get1IndResource(type, i)
+            Res.SetResLoad(1)
+            info(res)
+
+def listresources():
+    ntypes = Res.CountTypes()
+    for itype in range(1, 1+ntypes):
+        type = Res.GetIndType(itype)
+        print "Type:", repr(type)
+        nresources = Res.CountResources(type)
+        for i in range(1, 1 + nresources):
+            Res.SetResLoad(0)
+            res = Res.GetIndResource(type, i)
+            Res.SetResLoad(1)
+            info(res)
+
+def info(res):
+    print res.GetResInfo(), res.SizeResource(), decodeattrs(res.GetResAttrs())
+
+attrnames = {
+        resChanged:     'Changed',
+        resPreload:     'Preload',
+        resProtected:   'Protected',
+        resLocked:      'Locked',
+        resPurgeable:   'Purgeable',
+        resSysHeap:     'SysHeap',
+}
+
+def decodeattrs(attrs):
+    names = []
+    for bit in range(16):
+        mask = 1<<bit
+        if attrs & mask:
+            if attrnames.has_key(mask):
+                names.append(attrnames[mask])
+            else:
+                names.append(hex(mask))
+    return names
+
+def test():
+    print "=== Local resourcess ==="
+    list1resources()
+    print "=== All resources ==="
+    listresources()
+
+if __name__ == '__main__':
+    test()

Added: vendor/Python/current/Mac/Demo/sound/morse.py
===================================================================
--- vendor/Python/current/Mac/Demo/sound/morse.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Demo/sound/morse.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,180 @@
+import sys, math, audiodev
+
+DOT = 30
+DAH = 80
+OCTAVE = 2                              # 1 == 441 Hz, 2 == 882 Hz, ...
+SAMPWIDTH = 2
+FRAMERATE = 44100
+BASEFREQ = 441
+QSIZE = 20000
+
+morsetab = {
+        'A': '.-',              'a': '.-',
+        'B': '-...',            'b': '-...',
+        'C': '-.-.',            'c': '-.-.',
+        'D': '-..',             'd': '-..',
+        'E': '.',               'e': '.',
+        'F': '..-.',            'f': '..-.',
+        'G': '--.',             'g': '--.',
+        'H': '....',            'h': '....',
+        'I': '..',              'i': '..',
+        'J': '.---',            'j': '.---',
+        'K': '-.-',             'k': '-.-',
+        'L': '.-..',            'l': '.-..',
+        'M': '--',              'm': '--',
+        'N': '-.',              'n': '-.',
+        'O': '---',             'o': '---',
+        'P': '.--.',            'p': '.--.',
+        'Q': '--.-',            'q': '--.-',
+        'R': '.-.',             'r': '.-.',
+        'S': '...',             's': '...',
+        'T': '-',               't': '-',
+        'U': '..-',             'u': '..-',
+        'V': '...-',            'v': '...-',
+        'W': '.--',             'w': '.--',
+        'X': '-..-',            'x': '-..-',
+        'Y': '-.--',            'y': '-.--',
+        'Z': '--..',            'z': '--..',
+        '0': '-----',
+        '1': '.----',
+        '2': '..---',
+        '3': '...--',
+        '4': '....-',
+        '5': '.....',
+        '6': '-....',
+        '7': '--...',
+        '8': '---..',
+        '9': '----.',
+        ',': '--..--',
+        '.': '.-.-.-',
+        '?': '..--..',
+        ';': '-.-.-.',
+        ':': '---...',
+        "'": '.----.',
+        '-': '-....-',
+        '/': '-..-.',
+        '(': '-.--.-',
+        ')': '-.--.-',
+        '_': '..--.-',
+        ' ': ' '
+}
+
+# If we play at 44.1 kHz (which we do), then if we produce one sine
+# wave in 100 samples, we get a tone of 441 Hz.  If we produce two
+# sine waves in these 100 samples, we get a tone of 882 Hz.  882 Hz
+# appears to be a nice one for playing morse code.
+def mkwave(octave):
+    global sinewave, nowave
+    sinewave = ''
+    n = int(FRAMERATE / BASEFREQ)
+    for i in range(n):
+        val = int(math.sin(2 * math.pi * i * octave / n) * 0x7fff)
+        sample = chr((val >> 8) & 255) + chr(val & 255)
+        sinewave = sinewave + sample[:SAMPWIDTH]
+    nowave = '\0' * (n*SAMPWIDTH)
+
+mkwave(OCTAVE)
+
+class BufferedAudioDev:
+    def __init__(self, *args):
+        import audiodev
+        self._base = apply(audiodev.AudioDev, args)
+        self._buffer = []
+        self._filled = 0
+        self._addmethods(self._base, self._base.__class__)
+    def _addmethods(self, inst, cls):
+        for name in cls.__dict__.keys():
+            if not hasattr(self, name):
+                try:
+                    setattr(self, name, getattr(inst, name))
+                except:
+                    pass
+        for basecls in cls.__bases__:
+            self._addmethods(self, inst, basecls)
+    def writeframesraw(self, frames):
+        self._buffer.append(frames)
+        self._filled = self._filled + len(frames)
+        if self._filled >= QSIZE:
+            self.flush()
+    def wait(self):
+        self.flush()
+        self._base.wait()
+    def flush(self):
+        print 'flush: %d blocks, %d bytes' % (len(self._buffer), self._filled)
+        if self._buffer:
+            import string
+            self._base.writeframes(string.joinfields(self._buffer, ''))
+            self._buffer = []
+            self._filled = 0
+
+def main(args = sys.argv[1:]):
+    import getopt, string
+    try:
+        opts, args = getopt.getopt(args, 'o:p:')
+    except getopt.error:
+        sys.stderr.write('Usage ' + sys.argv[0] +
+                         ' [ -o outfile ] [ args ] ...\n')
+        sys.exit(1)
+    dev = None
+    for o, a in opts:
+        if o == '-o':
+            import aifc
+            dev = aifc.open(a, 'w')
+            dev.setframerate(FRAMERATE)
+            dev.setsampwidth(SAMPWIDTH)
+            dev.setnchannels(1)
+        if o == '-p':
+            mkwave(string.atoi(a))
+    if not dev:
+        dev = BufferedAudioDev()
+        dev.setoutrate(FRAMERATE)
+        dev.setsampwidth(SAMPWIDTH)
+        dev.setnchannels(1)
+        dev.close = dev.stop
+    if args:
+        line = string.join(args)
+    else:
+        line = sys.stdin.readline()
+    while line:
+        print line
+        mline = morse(line)
+        print mline
+        play(mline, dev)
+        if hasattr(dev, 'wait'):
+            dev.wait()
+        if not args:
+            line = sys.stdin.readline()
+        else:
+            line = ''
+    dev.close()
+
+# Convert a string to morse code with \001 between the characters in
+# the string.
+def morse(line):
+    res = ''
+    for c in line:
+        try:
+            res = res + morsetab[c] + '\001'
+        except KeyError:
+            pass
+    return res
+
+# Play a line of morse code.
+def play(line, dev):
+    for c in line:
+        if c == '.':
+            sine(dev, DOT)
+        elif c == '-':
+            sine(dev, DAH)
+        else:
+            pause(dev, DAH)
+        pause(dev, DOT)
+
+def sine(dev, length):
+    dev.writeframesraw(sinewave*length)
+
+def pause(dev, length):
+    dev.writeframesraw(nowave*length)
+
+if __name__ == '__main__' or sys.argv[0] == __name__:
+    main()

Added: vendor/Python/current/Mac/Demo/sound/morselib.py
===================================================================
--- vendor/Python/current/Mac/Demo/sound/morselib.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Demo/sound/morselib.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,188 @@
+"""Translate text strings to Morse code"""
+
+FRAMERATE = 22050
+SAMPWIDTH = 2
+
+BASEFREQ = 441
+OCTAVE = 2
+
+DOT = 30
+DAH = 80
+
+morsetab = {
+        'a': '.-',
+        'b': '-...',
+        'c': '-.-.',
+        'd': '-..',
+        'e': '.',
+        'f': '..-.',
+        'g': '--.',
+        'h': '....',
+        'i': '..',
+        'j': '.---',
+        'k': '-.-',
+        'l': '.-..',
+        'm': '--',
+        'n': '-.',
+        'o': '---',
+        'p': '.--.',
+        'q': '--.-',
+        'r': '.-.',
+        's': '...',
+        't': '-',
+        'u': '..-',
+        'v': '...-',
+        'w': '.--',
+        'x': '-..-',
+        'y': '-.--',
+        'z': '--..',
+        '0': '-----',
+        '1': '.----',
+        '2': '..---',
+        '3': '...--',
+        '4': '....-',
+        '5': '.....',
+        '6': '-....',
+        '7': '--...',
+        '8': '---..',
+        '9': '----.',
+        ',': '--..--',
+        '.': '.-.-.-',
+        '?': '..--..',
+        ';': '-.-.-.',
+        ':': '---...',
+        "'": '.----.',
+        '-': '-....-',
+        '/': '-..-.',
+        '(': '-.--.-',
+        ')': '-.--.-', # XXX same as code for '(' ???
+        '_': '..--.-',
+        ' ': ' '
+}
+
+def morsecode(s):
+    from string import lower
+    m = ''
+    for c in s:
+        c = lower(c)
+        if morsetab.has_key(c):
+            c = morsetab[c] + ' '
+        else:
+            c = '? '
+        m = m + c
+    return m
+
+
+class BaseMorse:
+    "base class for morse transmissions"
+
+    def __init__(self):
+        "constructor"
+        self.dots = DOT
+        self.dahs = DAH
+
+    def noise(self, duration):
+        "beep for given duration"
+        pass
+
+    def pause(self, duration):
+        "pause for given duration"
+        pass
+
+    def dot(self):
+        "short beep"
+        self.noise(self.dots)
+
+    def dah(self):
+        "long beep"
+        self.noise(self.dahs)
+
+    def pdot(self):
+        "pause as long as a dot"
+        self.pause(self.dots)
+
+    def pdah(self):
+        "pause as long as a dah"
+        self.pause(self.dahs)
+
+    def sendmorse(self, s):
+        for c in s:
+            if c == '.': self.dot()
+            elif c == '-': self.dah()
+            else: self.pdah()
+            self.pdot()
+
+    def sendascii(self, s):
+        self.sendmorse(morsecode(s))
+
+    def send(self, s):
+        self.sendascii(s)
+
+
+import Audio_mac
+class MyAudio(Audio_mac.Play_Audio_mac):
+    def _callback(self, *args):
+        if hasattr(self, 'usercallback'): self.usercallback()
+        apply(Audio_mac.Play_Audio_mac._callback, (self,) + args)
+
+
+class MacMorse(BaseMorse):
+    "Mac specific class to play Morse code"
+
+    def __init__(self):
+        BaseMorse.__init__(self)
+        self.dev = MyAudio()
+        self.dev.setoutrate(FRAMERATE)
+        self.dev.setsampwidth(SAMPWIDTH)
+        self.dev.setnchannels(1)
+        self.dev.usercallback = self.usercallback
+        sinewave = ''
+        n = int(FRAMERATE / BASEFREQ)
+        octave = OCTAVE
+        from math import sin, pi
+        for i in range(n):
+            val = int(sin(2 * pi * i * octave / n) * 0x7fff)
+            sample = chr((val >> 8) & 255) + chr(val & 255)
+            sinewave = sinewave + sample[:SAMPWIDTH]
+        self.sinewave = sinewave
+        self.silence = '\0' * (n*SAMPWIDTH)
+        self.morsequeue = ''
+
+    def __del__(self):
+        self.close()
+
+    def close(self):
+        self.dev = None
+
+    def pause(self, duration):
+        self.dev.writeframes(self.silence * duration)
+
+    def noise(self, duration):
+        self.dev.writeframes(self.sinewave * duration)
+
+    def sendmorse(self, s):
+        self.morsequeue = self.morsequeue + s
+        self.dev.usercallback()
+        self.dev.usercallback()
+        self.dev.usercallback()
+
+    def usercallback(self):
+        if self.morsequeue:
+            c, self.morsequeue = self.morsequeue[0], self.morsequeue[1:]
+            if c == '.': self.dot()
+            elif c == '-': self.dah()
+            else: self.pdah()
+            self.pdot()
+
+
+def test():
+    m = MacMorse()
+    while 1:
+        try:
+            line = raw_input('Morse line: ')
+        except (EOFError, KeyboardInterrupt):
+            break
+        m.send(line)
+        while m.morsequeue: pass
+
+test()

Added: vendor/Python/current/Mac/Demo/sound/playaiff.py
===================================================================
--- vendor/Python/current/Mac/Demo/sound/playaiff.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Demo/sound/playaiff.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,45 @@
+from Carbon.Sound import *
+from Carbon import Snd
+
+import aifc, audioop
+
+fn = 'f:just samples:2ndbeat.aif'
+af = aifc.open(fn, 'r')
+print af.getparams()
+print 'nframes  =', af.getnframes()
+print 'nchannels =', af.getnchannels()
+print 'framerate =', af.getframerate()
+nframes = min(af.getnframes(), 100000)
+frames = af.readframes(nframes)
+print 'len(frames) =', len(frames)
+print repr(frames[:100])
+frames = audioop.add(frames, '\x80'*len(frames), 1)
+print repr(frames[:100])
+
+import struct
+
+header1 = struct.pack('llhhllbbl',
+                      0,
+                      af.getnchannels(),
+                      af.getframerate(),0,
+                      0,
+                      0,
+                      0xFF,
+                      60,
+                      nframes)
+print repr(header1)
+header2 = struct.pack('llhlll', 0, 0, 0, 0, 0, 0)
+header3 = struct.pack('hhlll',
+                      af.getsampwidth()*8,
+                      0,
+                      0,
+                      0,
+                      0)
+print repr(header3)
+header = header1 + header2 + header3
+
+buffer = header + frames
+
+chan = Snd.SndNewChannel(5,0x00C0)
+
+Snd.SndDoCommand(chan, (bufferCmd, 0, buffer), 0)

Added: vendor/Python/current/Mac/Demo/textedit/ped.py
===================================================================
--- vendor/Python/current/Mac/Demo/textedit/ped.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Demo/textedit/ped.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,359 @@
+# A minimal text editor.
+#
+# To be done:
+# - Update viewrect after resize
+# - Handle horizontal scrollbar correctly
+# - Functionality: find, etc.
+
+from Carbon.Menu import DrawMenuBar
+from FrameWork import *
+from Carbon import Win
+from Carbon import Qd
+from Carbon import TE
+from Carbon import Scrap
+import os
+import macfs
+
+class TEWindow(ScrolledWindow):
+    def open(self, path, name, data):
+        self.path = path
+        self.name = name
+        r = windowbounds(400, 400)
+        w = Win.NewWindow(r, name, 1, 0, -1, 1, 0)
+        self.wid = w
+        x0, y0, x1, y1 = self.wid.GetWindowPort().GetPortBounds()
+        x0 = x0 + 4
+        y0 = y0 + 4
+        x1 = x1 - 20
+        y1 = y1 - 20
+        vr = dr = x0, y0, x1, y1
+        ##vr = 4, 0, r[2]-r[0]-15, r[3]-r[1]-15
+        ##dr = (0, 0, vr[2], 0)
+        Qd.SetPort(w)
+        Qd.TextFont(4)
+        Qd.TextSize(9)
+        self.ted = TE.TENew(dr, vr)
+        self.ted.TEAutoView(1)
+        self.ted.TESetText(data)
+        w.DrawGrowIcon()
+        self.scrollbars()
+        self.changed = 0
+        self.do_postopen()
+        self.do_activate(1, None)
+
+    def do_idle(self):
+        self.ted.TEIdle()
+
+    def getscrollbarvalues(self):
+        dr = self.ted.destRect
+        vr = self.ted.viewRect
+        height = self.ted.nLines * self.ted.lineHeight
+        vx = self.scalebarvalue(dr[0], dr[2]-dr[0], vr[0], vr[2])
+        vy = self.scalebarvalue(dr[1], dr[1]+height, vr[1], vr[3])
+        print dr, vr, height, vx, vy
+        return None, vy
+
+    def scrollbar_callback(self, which, what, value):
+        if which == 'y':
+            if what == 'set':
+                height = self.ted.nLines * self.ted.lineHeight
+                cur = self.getscrollbarvalues()[1]
+                delta = (cur-value)*height/32767
+            if what == '-':
+                delta = self.ted.lineHeight
+            elif what == '--':
+                delta = (self.ted.viewRect[3]-self.ted.lineHeight)
+                if delta <= 0:
+                    delta = self.ted.lineHeight
+            elif what == '+':
+                delta = -self.ted.lineHeight
+            elif what == '++':
+                delta = -(self.ted.viewRect[3]-self.ted.lineHeight)
+                if delta >= 0:
+                    delta = -self.ted.lineHeight
+            self.ted.TEPinScroll(0, delta)
+            print 'SCROLL Y', delta
+        else:
+            pass # No horizontal scrolling
+
+    def do_activate(self, onoff, evt):
+        print "ACTIVATE", onoff
+        ScrolledWindow.do_activate(self, onoff, evt)
+        if onoff:
+            self.ted.TEActivate()
+            self.parent.active = self
+            self.parent.updatemenubar()
+        else:
+            self.ted.TEDeactivate()
+
+    def do_update(self, wid, event):
+        Qd.EraseRect(wid.GetWindowPort().GetPortBounds())
+        self.ted.TEUpdate(wid.GetWindowPort().GetPortBounds())
+        self.updatescrollbars()
+
+    def do_contentclick(self, local, modifiers, evt):
+        shifted = (modifiers & 0x200)
+        self.ted.TEClick(local, shifted)
+        self.updatescrollbars()
+        self.parent.updatemenubar()
+
+    def do_char(self, ch, event):
+        self.ted.TESelView()
+        self.ted.TEKey(ord(ch))
+        self.changed = 1
+        self.updatescrollbars()
+        self.parent.updatemenubar()
+
+    def close(self):
+        if self.changed:
+            save = EasyDialogs.AskYesNoCancel('Save window "%s" before closing?'%self.name, 1)
+            if save > 0:
+                self.menu_save()
+            elif save < 0:
+                return
+        if self.parent.active == self:
+            self.parent.active = None
+        self.parent.updatemenubar()
+        del self.ted
+        self.do_postclose()
+
+    def menu_save(self):
+        if not self.path:
+            self.menu_save_as()
+            return # Will call us recursively
+        print 'Saving to ', self.path
+        dhandle = self.ted.TEGetText()
+        data = dhandle.data
+        fp = open(self.path, 'wb')  # NOTE: wb, because data has CR for end-of-line
+        fp.write(data)
+        if data[-1] <> '\r': fp.write('\r')
+        fp.close()
+        self.changed = 0
+
+    def menu_save_as(self):
+        path = EasyDialogs.AskFileForSave(message='Save as:')
+        if not path: return
+        self.path = path
+        self.name = os.path.split(self.path)[-1]
+        self.wid.SetWTitle(self.name)
+        self.menu_save()
+
+    def menu_cut(self):
+        self.ted.TESelView()
+        self.ted.TECut()
+        if hasattr(Scrap, 'ZeroScrap'):
+            Scrap.ZeroScrap()
+        else:
+            Scrap.ClearCurrentScrap()
+        TE.TEToScrap()
+        self.updatescrollbars()
+        self.parent.updatemenubar()
+        self.changed = 1
+
+    def menu_copy(self):
+        self.ted.TECopy()
+        if hasattr(Scrap, 'ZeroScrap'):
+            Scrap.ZeroScrap()
+        else:
+            Scrap.ClearCurrentScrap()
+        TE.TEToScrap()
+        self.updatescrollbars()
+        self.parent.updatemenubar()
+
+    def menu_paste(self):
+        TE.TEFromScrap()
+        self.ted.TESelView()
+        self.ted.TEPaste()
+        self.updatescrollbars()
+        self.parent.updatemenubar()
+        self.changed = 1
+
+    def menu_clear(self):
+        self.ted.TESelView()
+        self.ted.TEDelete()
+        self.updatescrollbars()
+        self.parent.updatemenubar()
+        self.changed = 1
+
+    def have_selection(self):
+        return (self.ted.selStart < self.ted.selEnd)
+
+class Ped(Application):
+    def __init__(self):
+        Application.__init__(self)
+        self.num = 0
+        self.active = None
+        self.updatemenubar()
+
+    def makeusermenus(self):
+        self.filemenu = m = Menu(self.menubar, "File")
+        self.newitem = MenuItem(m, "New window", "N", self.open)
+        self.openitem = MenuItem(m, "Open...", "O", self.openfile)
+        self.closeitem = MenuItem(m, "Close", "W", self.closewin)
+        m.addseparator()
+        self.saveitem = MenuItem(m, "Save", "S", self.save)
+        self.saveasitem = MenuItem(m, "Save as...", "", self.saveas)
+        m.addseparator()
+        self.quititem = MenuItem(m, "Quit", "Q", self.quit)
+
+        self.editmenu = m = Menu(self.menubar, "Edit")
+        self.undoitem = MenuItem(m, "Undo", "Z", self.undo)
+        self.cutitem = MenuItem(m, "Cut", "X", self.cut)
+        self.copyitem = MenuItem(m, "Copy", "C", self.copy)
+        self.pasteitem = MenuItem(m, "Paste", "V", self.paste)
+        self.clearitem = MenuItem(m, "Clear", "", self.clear)
+
+        # Not yet implemented:
+        self.undoitem.enable(0)
+
+        # Groups of items enabled together:
+        self.windowgroup = [self.closeitem, self.saveitem, self.saveasitem, self.editmenu]
+        self.focusgroup = [self.cutitem, self.copyitem, self.clearitem]
+        self.windowgroup_on = -1
+        self.focusgroup_on = -1
+        self.pastegroup_on = -1
+
+    def updatemenubar(self):
+        changed = 0
+        on = (self.active <> None)
+        if on <> self.windowgroup_on:
+            for m in self.windowgroup:
+                m.enable(on)
+            self.windowgroup_on = on
+            changed = 1
+        if on:
+            # only if we have an edit menu
+            on = self.active.have_selection()
+            if on <> self.focusgroup_on:
+                for m in self.focusgroup:
+                    m.enable(on)
+                self.focusgroup_on = on
+                changed = 1
+            if hasattr(Scrap, 'InfoScrap'):
+                on = (Scrap.InfoScrap()[0] <> 0)
+            else:
+                flavors = Scrap.GetCurrentScrap().GetScrapFlavorInfoList()
+                for tp, info in flavors:
+                    if tp == 'TEXT':
+                        on = 1
+                        break
+                else:
+                    on = 0
+            if on <> self.pastegroup_on:
+                self.pasteitem.enable(on)
+                self.pastegroup_on = on
+                changed = 1
+        if changed:
+            DrawMenuBar()
+
+    #
+    # Apple menu
+    #
+
+    def do_about(self, id, item, window, event):
+        EasyDialogs.Message("A simple single-font text editor")
+
+    #
+    # File menu
+    #
+
+    def open(self, *args):
+        self._open(0)
+
+    def openfile(self, *args):
+        self._open(1)
+
+    def _open(self, askfile):
+        if askfile:
+            path = EasyDialogs.AskFileForOpen(typeList=('TEXT',))
+            if not path:
+                return
+            name = os.path.split(path)[-1]
+            try:
+                fp = open(path, 'rb') # NOTE binary, we need cr as end-of-line
+                data = fp.read()
+                fp.close()
+            except IOError, arg:
+                EasyDialogs.Message("IOERROR: %r" % (arg,))
+                return
+        else:
+            path = None
+            name = "Untitled %d"%self.num
+            data = ''
+        w = TEWindow(self)
+        w.open(path, name, data)
+        self.num = self.num + 1
+
+    def closewin(self, *args):
+        if self.active:
+            self.active.close()
+        else:
+            EasyDialogs.Message("No active window?")
+
+    def save(self, *args):
+        if self.active:
+            self.active.menu_save()
+        else:
+            EasyDialogs.Message("No active window?")
+
+    def saveas(self, *args):
+        if self.active:
+            self.active.menu_save_as()
+        else:
+            EasyDialogs.Message("No active window?")
+
+
+    def quit(self, *args):
+        for w in self._windows.values():
+            w.close()
+        if self._windows:
+            return
+        self._quit()
+
+    #
+    # Edit menu
+    #
+
+    def undo(self, *args):
+        pass
+
+    def cut(self, *args):
+        if self.active:
+            self.active.menu_cut()
+        else:
+            EasyDialogs.Message("No active window?")
+
+    def copy(self, *args):
+        if self.active:
+            self.active.menu_copy()
+        else:
+            EasyDialogs.Message("No active window?")
+
+    def paste(self, *args):
+        if self.active:
+            self.active.menu_paste()
+        else:
+            EasyDialogs.Message("No active window?")
+
+    def clear(self, *args):
+        if self.active:
+            self.active.menu_clear()
+        else:
+            EasyDialogs.Message("No active window?")
+
+    #
+    # Other stuff
+    #
+
+    def idle(self, *args):
+        if self.active:
+            self.active.do_idle()
+        else:
+            Qd.SetCursor(Qd.GetQDGlobalsArrow())
+
+def main():
+    App = Ped()
+    App.mainloop()
+
+if __name__ == '__main__':
+    main()

Added: vendor/Python/current/Mac/Demo/textedit.html
===================================================================
--- vendor/Python/current/Mac/Demo/textedit.html	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Demo/textedit.html	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,150 @@
+<HTML><HEAD><TITLE>Using FrameWork and TextEdit</TITLE></HEAD>
+<BODY>
+<H1>Using FrameWork and TextEdit</H1>
+<HR>
+
+In this document we use the <CODE>FrameWork</CODE> and <CODE>TextEdit</CODE>
+modules to create a simple text editor. The functionality
+of the editor is very basic: you can open multiple files, type text and use
+cut/copy/paste. The main intention is to explain the use of FrameWork, really. <p>
+
+<H2>FrameWork</H2>
+
+The FrameWork module provides you with a skeleton application. It declares a
+number of classes suitable for subclassing in your application, thereby
+releaving you of the burden of doing all event handling, etc. yourself. For a
+real understanding you will have to browse the source. Here is a short overview
+of the classes and what functionality they provide.
+
+<dl>
+<dt> <CODE>Application</CODE>
+<dd>
+This is the toplevel class you will override. It maintains the menu bar and contains
+the main event handling code. Normal use is to override the <code>__init__</code> routine
+to do your own initializations and override <code>makeusermenus</code> to create your menus
+(your menu callback routines may be here too, but this is by no means necessary).
+The event handling code can be overridden at various levels, from very low-level (the
+<code>dispatch</code> method) to intermedeate level (<code>do_keyDown</code>, for instance)
+to high-level (<code>do_key</code>). The application class knows about the <code>Window</code>
+objects you create, and will forward events to the appropriate window (So, normally you
+would have a <code>do_key</code> method in your window object, not your application object).
+
+<dt> <CODE>MenuBar</CODE>, <CODE>Menu</CODE> and <CODE>MenuItem</CODE>
+<dd>
+These classes (and a few friends like <CODE>SubMenu</CODE>) handle your menus. You would not
+normally override them but use them as-is. The idiom for creating menus is a bit strange,
+see the test code at the bottom of FrameWork for sample use. The apple menu is handled for you
+by <CODE>MenuBar</CODE> and <CODE>Application</CODE>.
+
+<dt> <CODE>Window</CODE>
+<dd>
+The basic window. Again, a class that you normally subclass in your application, possibly
+multiple times if you have different types of windows. The init call instantiates the data
+structure but actually opening the window is delayed until you call <code>open</code>. Your
+open method should call <code>do_postopen</code> to let the base class handle linking in to
+the application object. Similarly with <code>close</code> and <code>do_postclose</code>. The
+rest of the code is mainly event-oriented: you override <code>do_postresize</code>,
+<code>do_contentclick</code>, <code>do_update</code>, <code>do_activate</code>
+and <code>do_key</code> to "do your thing". When these methods are called the relevant environment
+has been setup (like <code>BeginDrawing</code> has been called for updates, etc).
+
+<dt> <CODE>windowbounds</CODE>
+<dd>
+Not a class but a function: you pass it a width and height and it will return you a rectangle
+you can use to create your window. It will take care of staggering windows and it will try
+to fit the window on the screen (but the resulting rect will <em>always</em> have the size you
+specify).
+
+<dt> <CODE>ControlsWindow</CODE>
+<dd>
+A subclass of Window which automatically handles drawing and clicking for controls. You override
+the same methods as for Window (if you need to: control-related things are done automatically) and
+<code>do_controlhit</code>.
+
+<dt> <CODE>ScrolledWindow</CODE>
+<dd>
+A subclass of ControlsWindow, a window with optional scrollbars. If you override <code>do_activate</code>
+or <code>do_postresize</code> you must call the ScrolledWindow methods at the end of your override.
+You call <code>scrollbars</code> to enable/disable scrollbars and <code>updatescrollbars</code> to
+update them. You provide <code>getscrollbarvalues</code> to return the current x/y values (a helper
+method <code>scalebarvalues</code> is available) and <code>scrollbarcallback</code> to update your
+display after the user has used the scrollbars.
+
+<dt> <CODE>DialogWindow</CODE>
+<dd>
+A modeless dialog window initialized from a DLOG resource. See the
+<A HREF="example2.html">second Interslip example</A> for its useage.
+</dl>
+
+<H2>A sample text editor</H2>
+
+Let us have a look at <A HREF="textedit/ped.py">ped.py</A> (in the Demo:textedit folder), the Pathetic
+EDitor. It has multiple windows, cut/copy/paste and keyboard input, but that is about all. It looks
+as if you can resize the window but it does not work. Still, it serves as an example. 
+
+Ped creates two classes, <code>TEWindow</code> and <code>Ped</code>. Let us start with the latter one,
+which is a subclass of <code>FrameWork.Application</code> and our main application. The init function
+has little to do aside from the standard init: it remembers a window sequence number (for untitled windows),
+and sets things up for menu disable to work. Remember, the <code>makeusermenus</code> is called
+automatically. <p>
+
+<code>Makeusermenus</code> creates the <code>File</code> and <code>Edit</code> menus. It also initializes
+a couple of lists that are used later to correctly enable and disable menu items (and complete menus) depending
+on whether a window is open, text is selected, etc. The callback functions for the menu items are
+all methods of this class. <p>
+
+<code>Updatemenubar</code> handles greying out (and re-enabling) of menu items depending on whether there
+is a current window and its state. <p>
+
+The rest of the methods are all callbacks and simple to understand. They check whether there is an active
+window (and complain loudly if there is none: the corresponding menu entry should have been disabled
+in that case!) and call the appropriate window method. Only the <code>_open</code> method (the common code
+for <code>Open</code> and <code>New</code>) deserves some mention. It instantiates a <code>TEWindow</code>
+object and opens it with the title, filename and contents of the file to edit. Note that FrameWork takes
+care of remembering the window object. A minor note on opening the file in binary mode: this is because
+TextEdit expects MacOS style carriage-return terminated lines, not python/unix/C style newline-terminated
+lines. <p>
+
+Oh yes: the <code>quit</code> callback does a little magic too. It closes all windows, and only if this
+succeeds it actually quits. This gives the user a chance to cancel the operation if some files are unsaved.
+<p>
+
+Lastly, there is the <code>idle</code> method, called by the Application base class when no event
+is available. It is forwarded to the active window, so it can blink the text caret. <p>
+
+The <code>TEWindow</code> object handles a single window. Due to this structuring it is absolutely no
+problem to have multiple windows open at the same time (although a real application should exercise care when
+two windows refer to the same document). TEWindow uses the standard init code inherited from
+<code>ScrolledWindow</code>, and sets itself up at the time of the <code>open</code> call. It obtains screen
+coordinates, opens the window, creates rectangles for TextEdit to work in (the magical number <code>15</code>
+here is the size of a normal scroll bar: unfortunately there is no symbolic constant for it),
+creates the TextEdit object and initializes it with our data. Finally, the scroll bars are created (the
+initial values will be obtained automatically through <code>getscrollbarvalues</code>) and we activate
+ourselves (this is unfortunately not done automatically by the MacOS event handling code). <p>
+
+<code>Do_idle</code> simply calls the TextEdit routine that blinks the cursor. <code>Getscrollbarvalues</code>
+returns the current X and Y scrollbar values, scaled to <code>0..32767</code>. For X we return <code>None</code>,
+which means "no scrollbar, please", for Y we use the scaler provided by <code>ScrolledWindow</code>. <p>
+
+<code>Scrollbar_callback</code> is called when the user uses the scrollbar. It is passed a string <code>'x'</code>
+or <code>'y'</code>, one of <code>'set', '-', '--', '+', '++'</code> and (for <code>set</code>) an absolute
+value. Note that the sign of the value passed to <code>TEPinScroll</code> is counter-intuitive. <p>
+
+<code>do_activate</code> (de)activates the scrollbars and calls the relevant TextEdit routine. Moreover, it
+tells the application object if we are now the active window, and updates the menubar. The next few methods
+are update and menu callbacks, and pretty straightforward. Note that <code>do_close</code> can
+return without closing the window (if the document is changed and the users cancels out of the operation).
+Also note the "magic" in <code>menu_save_as</code>
+that set the correct window title. <p>
+
+Things get moderately interesting again at the cut/copy/paste handling, since the TextEdit scrap is
+separate from the desktop scrap. For that reason there are various calls to routines that move the scrap
+back and forth. <code>Have_selection</code> is called by the menubar update code to determine whether cut and
+copy should be enabled. <p>
+
+Understanding the main program is left as an exercise to the reader. <p>
+
+<hr>
+That's all for this example, you could now continue with the <A HREF="waste.html">next example</A>, where we use WASTE, a more-or-less
+TextEdit compatible library with more functionality, to rebuild our editor. Or you can
+return to the <A HREF="index.html">table of contents</A> to pick another topic. <p>

Added: vendor/Python/current/Mac/Extras.ReadMe.txt
===================================================================
--- vendor/Python/current/Mac/Extras.ReadMe.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Extras.ReadMe.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,5 @@
+This folder contains examples of Python usage and useful scripts and tools.
+
+You should be aware that these are not Macintosh-specific but are shared
+among Python on all platforms, so there are some that only run on Windows
+or Unix or another platform, and/or make little sense on a Macintosh.

Added: vendor/Python/current/Mac/Extras.install.py
===================================================================
--- vendor/Python/current/Mac/Extras.install.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Extras.install.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,54 @@
+"""Recursively copy a directory but skip undesired files and
+directories (CVS, backup files, pyc files, etc)"""
+
+import sys
+import os
+import shutil
+
+verbose = 1
+debug = 0
+
+def isclean(name):
+    if name == 'CVS': return 0
+    if name == '.cvsignore': return 0
+    if name == '.DS_store': return 0
+    if name == '.svn': return 0
+    if name.endswith('~'): return 0
+    if name.endswith('.BAK'): return 0
+    if name.endswith('.pyc'): return 0
+    if name.endswith('.pyo'): return 0
+    if name.endswith('.orig'): return 0
+    return 1
+
+def copycleandir(src, dst):
+    for cursrc, dirs, files in os.walk(src):
+        assert cursrc.startswith(src)
+        curdst = dst + cursrc[len(src):]
+        if verbose:
+            print "mkdir", curdst
+        if not debug:
+            if not os.path.exists(curdst):
+                os.makedirs(curdst)
+        for fn in files:
+            if isclean(fn):
+                if verbose:
+                    print "copy", os.path.join(cursrc, fn), os.path.join(curdst, fn)
+                if not debug:
+                    shutil.copy2(os.path.join(cursrc, fn), os.path.join(curdst, fn))
+            else:
+                if verbose:
+                    print "skipfile", os.path.join(cursrc, fn)
+        for i in range(len(dirs)-1, -1, -1):
+            if not isclean(dirs[i]):
+                if verbose:
+                    print "skipdir", os.path.join(cursrc, dirs[i])
+                del dirs[i]
+
+def main():
+    if len(sys.argv) != 3:
+        sys.stderr.write("Usage: %s srcdir dstdir\n" % sys.argv[0])
+        sys.exit(1)
+    copycleandir(sys.argv[1], sys.argv[2])
+
+if __name__ == '__main__':
+    main()

Added: vendor/Python/current/Mac/IDLE/Info.plist.in
===================================================================
--- vendor/Python/current/Mac/IDLE/Info.plist.in	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/IDLE/Info.plist.in	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleDocumentTypes</key>
+	<array>
+		<dict>
+			<key>CFBundleTypeExtensions</key>
+			<array>
+				<string>py</string>
+				<string>pyw</string>
+			</array>
+			<key>CFBundleTypeIconFile</key>
+			<string>PythonSource.icns</string>
+			<key>CFBundleTypeName</key>
+			<string>Python Script</string>
+			<key>CFBundleTypeRole</key>
+			<string>Editor</string>
+		</dict>
+		<dict>
+			<key>CFBundleTypeExtensions</key>
+			<array>
+				<string>pyc</string>
+				<string>pyo</string>
+			</array>
+			<key>CFBundleTypeIconFile</key>
+			<string>PythonCompiled.icns</string>
+			<key>CFBundleTypeName</key>
+			<string>Python Bytecode Document</string>
+			<key>CFBundleTypeRole</key>
+			<string>Editor</string>
+		</dict>
+	</array>
+	<key>CFBundleExecutable</key>
+	<string>IDLE</string>
+	<key>CFBundleGetInfoString</key>
+	<string>%VERSION%, © 001-2006 Python Software Foundation</string>
+	<key>CFBundleIconFile</key>
+	<string>IDLE.icns</string>
+	<key>CFBundleIdentifier</key>
+	<string>org.python.IDLE</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>IDLE</string>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>%VERSION%</string>
+	<key>CFBundleVersion</key>
+	<string>%VERSION%</string>
+</dict>
+</plist>

Added: vendor/Python/current/Mac/IDLE/config-extensions.def
===================================================================
--- vendor/Python/current/Mac/IDLE/config-extensions.def	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/IDLE/config-extensions.def	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,88 @@
+# config-extensions.def
+#
+# IDLE reads several config files to determine user preferences.  This
+# file is the default configuration file for IDLE extensions settings.
+#
+# Each extension must have at least one section, named after the extension
+# module. This section must contain an 'enable' item (=1 to enable the
+# extension, =0 to disable it), it may contain 'enable_editor' or 'enable_shell'
+# items, to apply it only to editor/shell windows, and may also contain any
+# other general configuration items for the extension.
+#
+# Each extension must define at least one section named ExtensionName_bindings
+# or ExtensionName_cfgBindings. If present, ExtensionName_bindings defines
+# virtual event bindings for the extension that are not user re-configurable.
+# If present, ExtensionName_cfgBindings defines virtual event bindings for the
+# extension that may be sensibly re-configured.
+#
+# If there are no keybindings for a menus' virtual events, include lines like
+# <<toggle-code-context>>=   (See [CodeContext], below.)
+#
+# Currently it is necessary to manually modify this file to change extension
+# key bindings and default values. To customize, create
+# ~/.idlerc/config-extensions.cfg and append the appropriate customized
+# section(s).  Those sections will override the defaults in this file.
+#
+# Note: If a keybinding is already in use when the extension is
+# loaded, the extension's virtual event's keybinding will be set to ''.
+#
+# See config-keys.def for notes on specifying keys and extend.txt for
+# information on creating IDLE extensions.
+
+[FormatParagraph]
+enable=1
+[FormatParagraph_cfgBindings]
+format-paragraph=<Option-Key-q>
+
+[AutoExpand]
+enable=1
+[AutoExpand_cfgBindings]
+expand-word=<Option-Key-slash>
+
+[ZoomHeight]
+enable=1
+[ZoomHeight_cfgBindings]
+zoom-height=<Option-Key-0>
+
+[ScriptBinding]
+enable=1
+[ScriptBinding_cfgBindings]
+run-module=<Key-F5>
+check-module=<Option-Key-x>
+
+[CallTips]
+enable=1
+[CallTips_cfgBindings]
+force-open-calltip=<Control-Key-backslash>
+[CallTips_bindings]
+try-open-calltip=<KeyRelease-parenleft>
+refresh-calltip=<KeyRelease-parenright> <KeyRelease-0>
+
+[ParenMatch]
+enable=1
+style= expression
+flash-delay= 500
+bell= 1
+[ParenMatch_cfgBindings]
+flash-paren=<Control-Key-0>
+[ParenMatch_bindings]
+paren-closed=<KeyRelease-parenright> <KeyRelease-bracketright> <KeyRelease-braceright>
+
+[AutoComplete]
+enable=1
+popupwait=2000
+[AutoComplete_cfgBindings]
+force-open-completions=<Control-Key-space>
+[AutoComplete_bindings]
+autocomplete=<Key-Tab>
+try-open-completions=<KeyRelease-period> <KeyRelease-slash> <KeyRelease-backslash>
+
+[CodeContext]
+enable=1
+enable_shell=0
+numlines=3
+visible=0
+bgcolor=LightGray
+fgcolor=Black
+[CodeContext_bindings]
+toggle-code-context=

Added: vendor/Python/current/Mac/IDLE/config-main.def
===================================================================
--- vendor/Python/current/Mac/IDLE/config-main.def	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/IDLE/config-main.def	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,79 @@
+# IDLE reads several config files to determine user preferences.  This
+# file is the default config file for general idle settings.
+#
+# When IDLE starts, it will look in
+# the following two sets of files, in order:
+#
+#     default configuration
+#     ---------------------
+#     config-main.def         the default general config file
+#     config-extensions.def   the default extension config file
+#     config-highlight.def    the default highlighting config file
+#     config-keys.def         the default keybinding config file
+#
+#     user configuration
+#     -------------------
+#     ~/.idlerc/config-main.cfg            the user general config file
+#     ~/.idlerc/config-extensions.cfg      the user extension config file
+#     ~/.idlerc/config-highlight.cfg       the user highlighting config file
+#     ~/.idlerc/config-keys.cfg            the user keybinding config file
+#
+# On Windows2000 and Windows XP the .idlerc directory is at
+#     Documents and Settings\<username>\.idlerc
+#
+# On Windows98 it is at c:\.idlerc
+#
+# Any options the user saves through the config dialog will be saved to
+# the relevant user config file. Reverting any general setting to the
+# default causes that entry to be wiped from the user file and re-read
+# from the default file. User highlighting themes or keybinding sets are
+# retained unless specifically deleted within the config dialog. Choosing
+# one of the default themes or keysets just applies the relevant settings
+# from the default file.
+#
+# Additional help sources are listed in the [HelpFiles] section and must be
+# viewable by a web browser (or the Windows Help viewer in the case of .chm
+# files). These sources will be listed on the Help menu.  The pattern is
+# <sequence_number = menu item;/path/to/help/source>
+# You can't use a semi-colon in a menu item or path.  The path will be platform
+# specific because of path separators, drive specs etc.
+#
+# It is best to use the Configuration GUI to set up additional help sources!
+# Example:
+#1 = My Extra Help Source;/usr/share/doc/foo/index.html
+#2 = Another Help Source;/path/to/another.pdf
+
+[General]
+editor-on-startup= 0
+autosave= 0
+print-command-posix=lpr %s
+print-command-win=start /min notepad /p %s
+delete-exitfunc= 1
+
+[EditorWindow]
+width= 80
+height= 40
+font= courier
+font-size= 10
+font-bold= 0
+encoding= none
+
+[FormatParagraph]
+paragraph=70
+
+[Indent]
+use-spaces= 1
+num-spaces= 4
+
+[Theme]
+default= 1
+name= IDLE Classic
+
+[Keys]
+default= 1
+name= IDLE Classic OSX
+
+[History]
+cyclic=1
+
+[HelpFiles]

Added: vendor/Python/current/Mac/IDLE/idlemain.py
===================================================================
--- vendor/Python/current/Mac/IDLE/idlemain.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/IDLE/idlemain.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,27 @@
+"""
+Bootstrap script for IDLE as an application bundle.
+"""
+import sys, os
+
+from idlelib.PyShell import main
+
+# Change the current directory the user's home directory, that way we'll get
+# a more useful default location in the open/save dialogs.
+os.chdir(os.path.expanduser('~/Documents'))
+
+
+# Make sure sys.executable points to the python interpreter inside the
+# framework, instead of at the helper executable inside the application
+# bundle (the latter works, but doesn't allow access to the window server)
+sys.executable = os.path.join(sys.prefix, 'bin', 'python')
+
+# Look for the -psn argument that the launcher adds and remove it, it will
+# only confuse the IDLE startup code.
+for idx, value in enumerate(sys.argv):
+    if value.startswith('-psn_'):
+        del sys.argv[idx]
+        break
+
+#argvemulator.ArgvCollector().mainloop()
+if __name__ == '__main__':
+    main()

Added: vendor/Python/current/Mac/Icons/Disk Image.icns
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Mac/Icons/Disk Image.icns
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Mac/Icons/IDLE.icns
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Mac/Icons/IDLE.icns
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Mac/Icons/Python Folder.icns
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Mac/Icons/Python Folder.icns
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Mac/Icons/PythonCompiled.icns
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Mac/Icons/PythonCompiled.icns
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Mac/Icons/PythonLauncher.icns
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Mac/Icons/PythonLauncher.icns
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Mac/Icons/PythonSource.icns
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Mac/Icons/PythonSource.icns
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Mac/Icons/ReadMe.txt
===================================================================
--- vendor/Python/current/Mac/Icons/ReadMe.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Icons/ReadMe.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,3 @@
+The icons for use on MacOS X were created by Jacob Rus <jrus at fas.harvard.edu>
+with some feedback from the folks on pythonmac-sig at python.org.
+

Added: vendor/Python/current/Mac/Modules/ColorPickermodule.c
===================================================================
--- vendor/Python/current/Mac/Modules/ColorPickermodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/ColorPickermodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,81 @@
+/******************************************************************
+Copyright 1998 by Just van Rossum, Den Haag, The Netherlands.
+
+                        All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Just van Rossum not be 
+used in advertising or publicity pertaining to distribution of the 
+software without specific, written prior permission.
+
+JUST VAN ROSSUM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 
+EVENT SHALL JUST VAN ROSSUM BE LIABLE FOR ANY SPECIAL, INDIRECT OR 
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 
+USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 
+OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+
+******************************************************************/
+
+#include <Carbon/Carbon.h>
+#include "Python.h"
+#include "pymactoolbox.h"
+
+/* ----------------------------------------------------- */
+
+static char cp_GetColor__doc__[] =
+"GetColor(prompt, (r, g, b)) -> (r, g, b), ok"
+;
+
+static PyObject *
+cp_GetColor(PyObject *self, PyObject *args)
+{
+	RGBColor inColor, outColor;
+	Boolean ok;
+	Point where = {0, 0};
+	Str255 prompt;
+	
+	if (!PyArg_ParseTuple(args, "O&O&", PyMac_GetStr255, prompt, QdRGB_Convert, &inColor))
+		return NULL;
+	
+	ok = GetColor(where, prompt, &inColor, &outColor);
+	
+	return Py_BuildValue("O&h", QdRGB_New, &outColor, ok);
+}
+
+/* List of methods defined in the module */
+
+static struct PyMethodDef cp_methods[] = {
+	{"GetColor",	(PyCFunction)cp_GetColor,	METH_VARARGS,	cp_GetColor__doc__},
+	{NULL,	 		(PyCFunction)NULL, 			0, 				NULL}		/* sentinel */
+};
+
+
+/* Initialization function for the module (*must* be called initColorPicker) */
+
+static char cp_module_documentation[] = 
+""
+;
+
+void initColorPicker(void)
+{
+	PyObject *m;
+
+	/* Create the module and add the functions */
+	m = Py_InitModule4("ColorPicker", cp_methods,
+		cp_module_documentation,
+		(PyObject*)NULL,PYTHON_API_VERSION);
+
+	/* Add symbolic constants to the module here */
+	
+	/* XXXX Add constants here */
+	
+	/* Check for errors */
+	if (PyErr_Occurred())
+		Py_FatalError("can't initialize module ColorPicker");
+}
+

Added: vendor/Python/current/Mac/Modules/MacOS.c
===================================================================
--- vendor/Python/current/Mac/Modules/MacOS.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/MacOS.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,644 @@
+/***********************************************************
+Copyright 1991-1997 by Stichting Mathematisch Centrum, Amsterdam,
+The Netherlands.
+
+                        All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its 
+documentation for any purpose and without fee is hereby granted, 
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in 
+supporting documentation, and that the names of Stichting Mathematisch
+Centrum or CWI not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior permission.
+
+STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
+THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
+FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+******************************************************************/
+
+/* Macintosh OS-specific interface */
+
+#include "Python.h"
+#include "pymactoolbox.h"
+
+#include <Carbon/Carbon.h>
+#include <ApplicationServices/ApplicationServices.h>
+
+static PyObject *MacOS_Error; /* Exception MacOS.Error */
+
+#define PATHNAMELEN 1024
+
+/* ----------------------------------------------------- */
+
+/* Declarations for objects of type Resource fork */
+
+typedef struct {
+	PyObject_HEAD
+	short fRefNum;
+	int isclosed;
+} rfobject;
+
+static PyTypeObject Rftype;
+
+
+
+/* ---------------------------------------------------------------- */
+
+static void
+do_close(rfobject *self)
+{
+	if (self->isclosed ) return;
+	(void)FSClose(self->fRefNum);
+	self->isclosed = 1;
+}
+
+static char rf_read__doc__[] = 
+"Read data from resource fork"
+;
+
+static PyObject *
+rf_read(rfobject *self, PyObject *args)
+{
+	long n;
+	PyObject *v;
+	OSErr err;
+	
+	if (self->isclosed) {
+		PyErr_SetString(PyExc_ValueError, "Operation on closed file");
+		return NULL;
+	}
+	
+	if (!PyArg_ParseTuple(args, "l", &n))
+		return NULL;
+		
+	v = PyString_FromStringAndSize((char *)NULL, n);
+	if (v == NULL)
+		return NULL;
+		
+	err = FSRead(self->fRefNum, &n, PyString_AsString(v));
+	if (err && err != eofErr) {
+		PyMac_Error(err);
+		Py_DECREF(v);
+		return NULL;
+	}
+	_PyString_Resize(&v, n);
+	return v;
+}
+
+
+static char rf_write__doc__[] = 
+"Write to resource fork"
+;
+
+static PyObject *
+rf_write(rfobject *self, PyObject *args)
+{
+	char *buffer;
+	long size;
+	OSErr err;
+	
+	if (self->isclosed) {
+		PyErr_SetString(PyExc_ValueError, "Operation on closed file");
+		return NULL;
+	}
+	if (!PyArg_ParseTuple(args, "s#", &buffer, &size))
+		return NULL;
+	err = FSWrite(self->fRefNum, &size, buffer);
+	if (err) {
+		PyMac_Error(err);
+		return NULL;
+	}
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+
+static char rf_seek__doc__[] = 
+"Set file position"
+;
+
+static PyObject *
+rf_seek(rfobject *self, PyObject *args)
+{
+	long amount, pos;
+	int whence = SEEK_SET;
+	long eof;
+	OSErr err;
+	
+	if (self->isclosed) {
+		PyErr_SetString(PyExc_ValueError, "Operation on closed file");
+		return NULL;
+	}
+	if (!PyArg_ParseTuple(args, "l|i", &amount, &whence))
+		return NULL;
+	
+	if ((err = GetEOF(self->fRefNum, &eof)))
+		goto ioerr;
+	
+	switch (whence) {
+	case SEEK_CUR:
+		if ((err = GetFPos(self->fRefNum, &pos)))
+			goto ioerr; 
+		break;
+	case SEEK_END:
+		pos = eof;
+		break;
+	case SEEK_SET:
+		pos = 0;
+		break;
+	default:
+		PyErr_BadArgument();
+		return NULL;
+	}
+	
+	pos += amount;
+	
+	/* Don't bother implementing seek past EOF */
+	if (pos > eof || pos < 0) {
+		PyErr_BadArgument();
+		return NULL;
+	}
+	
+	if ((err = SetFPos(self->fRefNum, fsFromStart, pos)) ) {
+ioerr:
+		PyMac_Error(err);
+		return NULL;
+	}
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+
+static char rf_tell__doc__[] = 
+"Get file position"
+;
+
+static PyObject *
+rf_tell(rfobject *self, PyObject *args)
+{
+	long where;
+	OSErr err;
+	
+	if (self->isclosed) {
+		PyErr_SetString(PyExc_ValueError, "Operation on closed file");
+		return NULL;
+	}
+	if (!PyArg_ParseTuple(args, ""))
+		return NULL;
+	if ((err = GetFPos(self->fRefNum, &where)) ) {
+		PyMac_Error(err);
+		return NULL;
+	}
+	return PyInt_FromLong(where);
+}
+
+static char rf_close__doc__[] = 
+"Close resource fork"
+;
+
+static PyObject *
+rf_close(rfobject *self, PyObject *args)
+{
+	if (!PyArg_ParseTuple(args, ""))
+		return NULL;
+	do_close(self);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+
+static struct PyMethodDef rf_methods[] = {
+ {"read",	(PyCFunction)rf_read,	1,	rf_read__doc__},
+ {"write",	(PyCFunction)rf_write,	1,	rf_write__doc__},
+ {"seek",	(PyCFunction)rf_seek,	1,	rf_seek__doc__},
+ {"tell",	(PyCFunction)rf_tell,	1,	rf_tell__doc__},
+ {"close",	(PyCFunction)rf_close,	1,	rf_close__doc__},
+ 
+	{NULL,		NULL}		/* sentinel */
+};
+
+/* ---------- */
+
+
+static rfobject *
+newrfobject(void)
+{
+	rfobject *self;
+	
+	self = PyObject_NEW(rfobject, &Rftype);
+	if (self == NULL)
+		return NULL;
+	self->isclosed = 1;
+	return self;
+}
+
+
+static void
+rf_dealloc(rfobject *self)
+{
+	do_close(self);
+	PyObject_DEL(self);
+}
+
+static PyObject *
+rf_getattr(rfobject *self, char *name)
+{
+	return Py_FindMethod(rf_methods, (PyObject *)self, name);
+}
+
+static char Rftype__doc__[] = 
+"Resource fork file object"
+;
+
+static PyTypeObject Rftype = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,				/*ob_size*/
+	"MacOS.ResourceFork",		/*tp_name*/
+	sizeof(rfobject),		/*tp_basicsize*/
+	0,				/*tp_itemsize*/
+	/* methods */
+	(destructor)rf_dealloc,	/*tp_dealloc*/
+	(printfunc)0,		/*tp_print*/
+	(getattrfunc)rf_getattr,	/*tp_getattr*/
+	(setattrfunc)0,	/*tp_setattr*/
+	(cmpfunc)0,		/*tp_compare*/
+	(reprfunc)0,		/*tp_repr*/
+	0,			/*tp_as_number*/
+	0,		/*tp_as_sequence*/
+	0,		/*tp_as_mapping*/
+	(hashfunc)0,		/*tp_hash*/
+	(ternaryfunc)0,		/*tp_call*/
+	(reprfunc)0,		/*tp_str*/
+
+	/* Space for future expansion */
+	0L,0L,0L,0L,
+	Rftype__doc__ /* Documentation string */
+};
+
+/* End of code for Resource fork objects */
+/* -------------------------------------------------------- */
+
+/*----------------------------------------------------------------------*/
+/* Miscellaneous File System Operations */
+
+static char getcrtp_doc[] = "Get MacOS 4-char creator and type for a file";
+
+static PyObject *
+MacOS_GetCreatorAndType(PyObject *self, PyObject *args)
+{
+	FSSpec fss;
+	FInfo info;
+	PyObject *creator, *type, *res;
+	OSErr err;
+	
+	if (!PyArg_ParseTuple(args, "O&", PyMac_GetFSSpec, &fss))
+		return NULL;
+	if ((err = FSpGetFInfo(&fss, &info)) != noErr)
+		return PyErr_Mac(MacOS_Error, err);
+	creator = PyString_FromStringAndSize((char *)&info.fdCreator, 4);
+	type = PyString_FromStringAndSize((char *)&info.fdType, 4);
+	res = Py_BuildValue("OO", creator, type);
+	Py_DECREF(creator);
+	Py_DECREF(type);
+	return res;
+}
+
+static char setcrtp_doc[] = "Set MacOS 4-char creator and type for a file";
+
+static PyObject *
+MacOS_SetCreatorAndType(PyObject *self, PyObject *args)
+{
+	FSSpec fss;
+	ResType creator, type;
+	FInfo info;
+	OSErr err;
+	
+	if (!PyArg_ParseTuple(args, "O&O&O&",
+			PyMac_GetFSSpec, &fss, PyMac_GetOSType, &creator, PyMac_GetOSType, &type))
+		return NULL;
+	if ((err = FSpGetFInfo(&fss, &info)) != noErr)
+		return PyErr_Mac(MacOS_Error, err);
+	info.fdCreator = creator;
+	info.fdType = type;
+	if ((err = FSpSetFInfo(&fss, &info)) != noErr)
+		return PyErr_Mac(MacOS_Error, err);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+
+static char geterr_doc[] = "Convert OSErr number to string";
+
+static PyObject *
+MacOS_GetErrorString(PyObject *self, PyObject *args)
+{
+	int err;
+	char buf[256];
+	Handle h;
+	char *str;
+	static int errors_loaded;
+	
+	if (!PyArg_ParseTuple(args, "i", &err))
+		return NULL;
+
+	h = GetResource('Estr', err);
+	if (!h && !errors_loaded) {
+		/*
+		** Attempt to open the resource file containing the
+		** Estr resources. We ignore all errors. We also try
+		** this only once.
+		*/
+		PyObject *m, *rv;
+		errors_loaded = 1;
+		
+		m = PyImport_ImportModule("macresource");
+		if (!m) {
+			if (Py_VerboseFlag)
+				PyErr_Print();
+			PyErr_Clear();
+		}
+		else {
+			rv = PyObject_CallMethod(m, "open_error_resource", "");
+			if (!rv) {
+				if (Py_VerboseFlag)
+					PyErr_Print();
+				PyErr_Clear();
+			}
+			else {
+				Py_DECREF(rv);
+				/* And try again... */
+				h = GetResource('Estr', err);
+			}
+			Py_DECREF(m);
+		}
+	}
+	/*
+	** Whether the code above succeeded or not, we won't try
+	** again.
+	*/
+	errors_loaded = 1;
+		
+	if (h) {
+		HLock(h);
+		str = (char *)*h;
+		memcpy(buf, str+1, (unsigned char)str[0]);
+		buf[(unsigned char)str[0]] = '\0';
+		HUnlock(h);
+		ReleaseResource(h);
+	}
+	else {
+		PyOS_snprintf(buf, sizeof(buf), "Mac OS error code %d", err);
+	}
+
+	return Py_BuildValue("s", buf);
+}
+
+static char splash_doc[] = "Open a splash-screen dialog by resource-id (0=close)";
+
+static PyObject *
+MacOS_splash(PyObject *self, PyObject *args)
+{
+	int resid = -1;
+	static DialogPtr curdialog = NULL;
+	DialogPtr olddialog;
+	WindowRef theWindow;
+	CGrafPtr thePort;
+#if 0
+	short xpos, ypos, width, height, swidth, sheight;
+#endif
+	
+	if (!PyArg_ParseTuple(args, "|i", &resid))
+		return NULL;
+	olddialog = curdialog;
+	curdialog = NULL;
+		
+	if ( resid != -1 ) {
+		curdialog = GetNewDialog(resid, NULL, (WindowPtr)-1);
+		if ( curdialog ) {
+			theWindow = GetDialogWindow(curdialog);
+			thePort = GetWindowPort(theWindow);
+#if 0
+			width = thePort->portRect.right - thePort->portRect.left;
+			height = thePort->portRect.bottom - thePort->portRect.top;
+			swidth = qd.screenBits.bounds.right - qd.screenBits.bounds.left;
+			sheight = qd.screenBits.bounds.bottom - qd.screenBits.bounds.top - LMGetMBarHeight();
+			xpos = (swidth-width)/2;
+			ypos = (sheight-height)/5 + LMGetMBarHeight();
+			MoveWindow(theWindow, xpos, ypos, 0);
+			ShowWindow(theWindow);
+#endif
+			DrawDialog(curdialog);
+		}
+	}
+	if (olddialog)
+		DisposeDialog(olddialog);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static char DebugStr_doc[] = "Switch to low-level debugger with a message";
+
+static PyObject *
+MacOS_DebugStr(PyObject *self, PyObject *args)
+{
+	Str255 message;
+	PyObject *object = 0;
+	
+	if (!PyArg_ParseTuple(args, "O&|O", PyMac_GetStr255, message, &object))
+		return NULL;
+	DebugStr(message);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static char SysBeep_doc[] = "BEEEEEP!!!";
+
+static PyObject *
+MacOS_SysBeep(PyObject *self, PyObject *args)
+{
+	int duration = 6;
+	
+	if (!PyArg_ParseTuple(args, "|i", &duration))
+		return NULL;
+	SysBeep(duration);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static char WMAvailable_doc[] = 
+	"True if this process can interact with the display."
+	"Will foreground the application on the first call as a side-effect."
+	;
+
+static PyObject *
+MacOS_WMAvailable(PyObject *self, PyObject *args)
+{
+	static PyObject *rv = NULL;
+	
+	if (!PyArg_ParseTuple(args, ""))
+		return NULL;
+	if (!rv) {
+		ProcessSerialNumber psn;
+		
+		/*
+		** This is a fairly innocuous call to make if we don't have a window
+		** manager, or if we have no permission to talk to it. It will print
+		** a message on stderr, but at least it won't abort the process.
+		** It appears the function caches the result itself, and it's cheap, so
+		** no need for us to cache.
+		*/
+#ifdef kCGNullDirectDisplay
+		/* On 10.1 CGMainDisplayID() isn't available, and
+		** kCGNullDirectDisplay isn't defined.
+		*/
+		if (CGMainDisplayID() == 0) {
+			rv = Py_False;
+		} else {
+#else
+		{
+#endif
+			if (GetCurrentProcess(&psn) < 0 ||
+				SetFrontProcess(&psn) < 0) {
+				rv = Py_False;
+			} else {
+				rv = Py_True;
+			}
+		}
+	}
+	Py_INCREF(rv);
+	return rv;
+}
+
+static char GetTicks_doc[] = "Return number of ticks since bootup";
+
+static PyObject *
+MacOS_GetTicks(PyObject *self, PyObject *args)
+{
+	return Py_BuildValue("i", (int)TickCount());
+}
+
+static char openrf_doc[] = "Open resource fork of a file";
+
+static PyObject *
+MacOS_openrf(PyObject *self, PyObject *args)
+{
+	OSErr err;
+	char *mode = "r";
+	FSSpec fss;
+	SignedByte permission = 1;
+	rfobject *fp;
+		
+	if (!PyArg_ParseTuple(args, "O&|s", PyMac_GetFSSpec, &fss, &mode))
+		return NULL;
+	while (*mode) {
+		switch (*mode++) {
+		case '*': break;
+		case 'r': permission = 1; break;
+		case 'w': permission = 2; break;
+		case 'b': break;
+		default:
+			PyErr_BadArgument();
+			return NULL;
+		}
+	}
+	
+	if ( (fp = newrfobject()) == NULL )
+		return NULL;
+		
+	err = HOpenRF(fss.vRefNum, fss.parID, fss.name, permission, &fp->fRefNum);
+	
+	if ( err == fnfErr ) {
+		/* In stead of doing complicated things here to get creator/type
+		** correct we let the standard i/o library handle it
+		*/
+		FILE *tfp;
+		char pathname[PATHNAMELEN];
+		
+		if ( (err=PyMac_GetFullPathname(&fss, pathname, PATHNAMELEN)) ) {
+			PyMac_Error(err);
+			Py_DECREF(fp);
+			return NULL;
+		}
+		
+		if ( (tfp = fopen(pathname, "w")) == NULL ) {
+			PyMac_Error(fnfErr); /* What else... */
+			Py_DECREF(fp);
+			return NULL;
+		}
+		fclose(tfp);
+		err = HOpenRF(fss.vRefNum, fss.parID, fss.name, permission, &fp->fRefNum);
+	}
+	if ( err ) {
+		Py_DECREF(fp);
+		PyMac_Error(err);
+		return NULL;
+	}
+	fp->isclosed = 0;
+	return (PyObject *)fp;
+}
+
+
+static PyMethodDef MacOS_Methods[] = {
+	{"GetCreatorAndType",		MacOS_GetCreatorAndType, 1,	getcrtp_doc},
+	{"SetCreatorAndType",		MacOS_SetCreatorAndType, 1,	setcrtp_doc},
+	{"GetErrorString",		MacOS_GetErrorString,	1,	geterr_doc},
+	{"openrf",			MacOS_openrf, 		1, 	openrf_doc},
+	{"splash",			MacOS_splash,		1, 	splash_doc},
+	{"DebugStr",			MacOS_DebugStr,		1,	DebugStr_doc},
+	{"GetTicks",			MacOS_GetTicks,		1,	GetTicks_doc},
+	{"SysBeep",			MacOS_SysBeep,		1,	SysBeep_doc},
+	{"WMAvailable",			MacOS_WMAvailable,		1,	WMAvailable_doc},
+	{NULL,				NULL}		 /* Sentinel */
+};
+
+
+void
+initMacOS(void)
+{
+	PyObject *m, *d;
+	
+	m = Py_InitModule("MacOS", MacOS_Methods);
+	d = PyModule_GetDict(m);
+	
+	/* Initialize MacOS.Error exception */
+	MacOS_Error = PyMac_GetOSErrException();
+	if (MacOS_Error == NULL || PyDict_SetItemString(d, "Error", MacOS_Error) != 0)
+		return;
+	Rftype.ob_type = &PyType_Type;
+	Py_INCREF(&Rftype);
+	if (PyDict_SetItemString(d, "ResourceForkType", (PyObject *)&Rftype) != 0)
+		return;
+	/*
+	** This is a hack: the following constant added to the id() of a string
+	** object gives you the address of the data. Unfortunately, it is needed for
+	** some of the image and sound processing interfaces on the mac:-(
+	*/
+	{
+		PyStringObject *p = 0;
+		long off = (long)&(p->ob_sval[0]);
+		
+		if( PyDict_SetItemString(d, "string_id_to_buffer", Py_BuildValue("i", off)) != 0)
+			return;
+	}
+#define PY_RUNTIMEMODEL "macho"
+	if (PyDict_SetItemString(d, "runtimemodel", 
+				Py_BuildValue("s", PY_RUNTIMEMODEL)) != 0)
+		return;
+#if defined(WITH_NEXT_FRAMEWORK)
+#define PY_LINKMODEL "framework"
+#elif defined(Py_ENABLE_SHARED)
+#define PY_LINKMODEL "shared"
+#else
+#define PY_LINKMODEL "static"
+#endif
+	if (PyDict_SetItemString(d, "linkmodel", 
+				Py_BuildValue("s", PY_LINKMODEL)) != 0)
+		return;
+
+}

Added: vendor/Python/current/Mac/Modules/Nav.c
===================================================================
--- vendor/Python/current/Mac/Modules/Nav.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/Nav.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,943 @@
+/***********************************************************
+Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
+The Netherlands.
+
+                        All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the names of Stichting Mathematisch
+Centrum or CWI or Corporation for National Research Initiatives or
+CNRI not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+While CWI is the initial source for this software, a modified version
+is made available by the Corporation for National Research Initiatives
+(CNRI) at the Internet address ftp://ftp.python.org.
+
+STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
+CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+
+******************************************************************/
+
+#include "Python.h"
+#include "pymactoolbox.h"
+#include <Carbon/Carbon.h>
+
+static PyObject *ErrorObject;
+
+static NavEventUPP my_eventProcUPP;
+static NavPreviewUPP my_previewProcUPP;
+static NavObjectFilterUPP my_filterProcUPP;
+
+/* Callback functions */
+static pascal void
+my_eventProc(NavEventCallbackMessage callBackSelector,
+			 NavCBRecPtr callBackParms,
+			 NavCallBackUserData callbackUD)
+{
+	PyObject *dict = (PyObject *)callbackUD;
+	PyObject *pyfunc;
+	PyObject *rv;
+	
+	if (!dict) return;
+	if ( (pyfunc = PyDict_GetItemString(dict, "eventProc")) == NULL ) {
+		PyErr_Print();
+		return;
+	}
+	if ( pyfunc == Py_None ) {
+		return;
+	}
+	rv = PyObject_CallFunction(pyfunc, "ls#", (long)callBackSelector,
+			(void *)callBackParms, sizeof(NavCBRec));
+	if ( rv )
+		Py_DECREF(rv);
+	else {
+		PySys_WriteStderr("Nav: exception in eventProc callback\n");
+		PyErr_Print();
+	}
+}
+
+static pascal Boolean
+my_previewProc(NavCBRecPtr callBackParms,
+			   NavCallBackUserData callbackUD)
+{
+	PyObject *dict = (PyObject *)callbackUD;
+	PyObject *pyfunc;
+	PyObject *rv;
+	Boolean c_rv = false;
+	
+	if (!dict) return false;
+	if ( (pyfunc = PyDict_GetItemString(dict, "previewProc")) == NULL ) {
+		PyErr_Print();
+		return false;
+	}
+	rv = PyObject_CallFunction(pyfunc, "s#", (void *)callBackParms, sizeof(NavCBRec));
+	if ( rv ) {
+		c_rv = PyObject_IsTrue(rv);
+		Py_DECREF(rv);
+	} else {
+		PySys_WriteStderr("Nav: exception in previewProc callback\n");
+		PyErr_Print();
+	}
+	return c_rv;
+}
+
+static pascal Boolean
+my_filterProc(AEDesc *theItem, void *info,
+			  NavCallBackUserData callbackUD,
+			  NavFilterModes filterMode)
+{
+	PyObject *dict = (PyObject *)callbackUD;
+	PyObject *pyfunc;
+	PyObject *rv;
+	Boolean c_rv = false;
+	
+	if (!dict) return false;
+	if ( (pyfunc = PyDict_GetItemString(dict, "filterProc")) == NULL ) {
+		PyErr_Print();
+		return false;
+	}
+	rv = PyObject_CallFunction(pyfunc, "O&s#h",
+		AEDesc_NewBorrowed, theItem, info, sizeof(NavFileOrFolderInfo), (short)filterMode);
+	if ( rv ) {
+		c_rv = PyObject_IsTrue(rv);
+		Py_DECREF(rv);
+	} else {
+		PySys_WriteStderr("Nav: exception in filterProc callback\n");
+		PyErr_Print();
+	}
+	return c_rv;
+}
+
+/* ----------------------------------------------------- */
+static int
+filldialogoptions(PyObject *d,
+		AEDesc **defaultLocationP,
+		NavDialogOptions *opt,
+		NavEventUPP *eventProcP,
+		NavPreviewUPP *previewProcP,
+		NavObjectFilterUPP *filterProcP,
+		NavTypeListHandle *typeListP,
+		OSType *fileTypeP,
+		OSType *fileCreatorP)
+{
+	Py_ssize_t pos = 0;
+	PyObject *key, *value;
+	char *keystr;
+	AEDesc *defaultLocation_storage;
+	
+	NavGetDefaultDialogOptions(opt);
+
+	while ( PyDict_Next(d, &pos, &key, &value) ) {
+		if ( !key || !value || !PyString_Check(key) ) {
+			PyErr_SetString(ErrorObject, "DialogOption has non-string key");
+			return 0;
+		}
+		keystr = PyString_AsString(key);
+		if( strcmp(keystr, "defaultLocation") == 0 ) {
+			if ( (defaultLocation_storage = PyMem_NEW(AEDesc, 1)) == NULL ) {
+				PyErr_NoMemory();
+				return 0;
+			}
+			if ( !PyArg_Parse(value, "O&", AEDesc_Convert, defaultLocation_storage) ) {
+				PyMem_DEL(defaultLocation_storage);
+				return 0;
+			}
+			*defaultLocationP = defaultLocation_storage;
+		} else if( strcmp(keystr, "version") == 0 ) {
+			if ( !PyArg_Parse(value, "H", &opt->version) )
+				return 0;
+		} else if( strcmp(keystr, "dialogOptionFlags") == 0 ) {
+			if ( !PyArg_Parse(value, "k", &opt->dialogOptionFlags) )
+				return 0;
+		} else if( strcmp(keystr, "location") == 0 ) {
+			if ( !PyArg_Parse(value, "O&", PyMac_GetPoint, &opt->location) )
+				return 0;
+		} else if( strcmp(keystr, "clientName") == 0 ) {
+			if ( !PyArg_Parse(value, "O&", PyMac_GetStr255, &opt->clientName) )
+				return 0;
+		} else if( strcmp(keystr, "windowTitle") == 0 ) {
+			if ( !PyArg_Parse(value, "O&", PyMac_GetStr255, &opt->windowTitle) )
+				return 0;
+		} else if( strcmp(keystr, "actionButtonLabel") == 0 ) {
+			if ( !PyArg_Parse(value, "O&", PyMac_GetStr255, &opt->actionButtonLabel) )
+				return 0;
+		} else if( strcmp(keystr, "cancelButtonLabel") == 0 ) {
+			if ( !PyArg_Parse(value, "O&", PyMac_GetStr255, &opt->cancelButtonLabel) )
+				return 0;
+		} else if( strcmp(keystr, "savedFileName") == 0 ) {
+			if ( !PyArg_Parse(value, "O&", PyMac_GetStr255, &opt->savedFileName) )
+				return 0;
+		} else if( strcmp(keystr, "message") == 0 ) {
+			if ( !PyArg_Parse(value, "O&", PyMac_GetStr255, &opt->message) )
+				return 0;
+		} else if( strcmp(keystr, "preferenceKey") == 0 ) {
+			if ( !PyArg_Parse(value, "O&", PyMac_GetOSType, &opt->preferenceKey) )
+				return 0;
+		} else if( strcmp(keystr, "popupExtension") == 0 ) {
+			if ( !PyArg_Parse(value, "O&", ResObj_Convert, &opt->popupExtension) )
+				return 0;
+		} else if( eventProcP && strcmp(keystr, "eventProc") == 0 ) {
+			*eventProcP = my_eventProcUPP;
+		} else if( previewProcP && strcmp(keystr, "previewProc") == 0 ) {
+			*previewProcP = my_previewProcUPP;
+		} else if( filterProcP && strcmp(keystr, "filterProc") == 0 ) {
+			*filterProcP = my_filterProcUPP;
+		} else if( typeListP && strcmp(keystr, "typeList") == 0 ) {
+			if ( !PyArg_Parse(value, "O&", ResObj_Convert, typeListP) )
+				return 0;
+		} else if( fileTypeP && strcmp(keystr, "fileType") == 0 ) {
+			if ( !PyArg_Parse(value, "O&", PyMac_GetOSType, fileTypeP) )
+				return 0;
+		} else if( fileCreatorP && strcmp(keystr, "fileCreator") == 0 ) {
+			if ( !PyArg_Parse(value, "O&", PyMac_GetOSType, fileCreatorP) )
+				return 0;
+		} else {
+			PyErr_Format(ErrorObject, "Unknown DialogOption key: %s", keystr);
+			return 0;
+		}
+	}
+	return 1;
+}
+
+/* ----------------------------------------------------- */
+
+/* Declarations for objects of type NavReplyRecord */
+
+typedef struct {
+	PyObject_HEAD
+	NavReplyRecord itself;
+} navrrobject;
+
+static PyTypeObject Navrrtype;
+
+
+
+/* ---------------------------------------------------------------- */
+
+static char nav_NavTranslateFile__doc__[] =
+"(NavTranslationOptions)->None"
+;
+
+static PyObject *
+nav_NavTranslateFile(navrrobject *self, PyObject *args)
+{
+	NavTranslationOptions howToTranslate;
+	OSErr err;
+
+	if (!PyArg_ParseTuple(args, "k", &howToTranslate))
+		return NULL;
+	err = NavTranslateFile(&self->itself, howToTranslate);
+	if ( err ) {
+		PyErr_Mac(ErrorObject, err);
+		return NULL;
+	}
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static char nav_NavCompleteSave__doc__[] =
+"(NavTranslationOptions)->None"
+;
+
+static PyObject *
+nav_NavCompleteSave(navrrobject *self, PyObject *args)
+{
+	NavTranslationOptions howToTranslate;
+	OSErr err;
+
+	if (!PyArg_ParseTuple(args, "k", &howToTranslate))
+		return NULL;
+	err = NavCompleteSave(&self->itself, howToTranslate);
+	if ( err ) {
+		PyErr_Mac(ErrorObject, err);
+		return NULL;
+	}
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+
+static struct PyMethodDef navrr_methods[] = {
+ {"NavTranslateFile",	(PyCFunction)nav_NavTranslateFile,	METH_VARARGS,	nav_NavTranslateFile__doc__},
+ {"NavCompleteSave",	(PyCFunction)nav_NavCompleteSave,	METH_VARARGS,	nav_NavCompleteSave__doc__},
+	
+	{NULL,		NULL}		/* sentinel */
+};
+
+/* ---------- */
+
+
+static navrrobject *
+newnavrrobject(NavReplyRecord *itself)
+{
+	navrrobject *self;
+	
+	self = PyObject_NEW(navrrobject, &Navrrtype);
+	if (self == NULL)
+		return NULL;
+	self->itself = *itself;
+	return self;
+}
+
+
+static void
+navrr_dealloc(navrrobject *self)
+{
+	NavDisposeReply(&self->itself);
+	PyObject_DEL(self);
+}
+
+static PyObject *
+navrr_getattr(navrrobject *self, char *name)
+{
+	FSSpec fss;
+	FSRef fsr;
+	
+	if( strcmp(name, "__members__") == 0 )
+		return Py_BuildValue("ssssssssss", "version", "validRecord", "replacing",
+			"isStationery", "translationNeeded", "selection", "selection_fsr",
+			"fileTranslation", "keyScript", "saveFileName");
+	if( strcmp(name, "version") == 0 )
+		return Py_BuildValue("h", self->itself.version);
+	if( strcmp(name, "validRecord") == 0 )
+		return Py_BuildValue("l", (long)self->itself.validRecord);
+	if( strcmp(name, "replacing") == 0 )
+		return Py_BuildValue("l", (long)self->itself.replacing);
+	if( strcmp(name, "isStationery") == 0 )
+		return Py_BuildValue("l", (long)self->itself.isStationery);
+	if( strcmp(name, "translationNeeded") == 0 )
+		return Py_BuildValue("l", (long)self->itself.translationNeeded);
+	if( strcmp(name, "selection") == 0 ) {
+		SInt32 i, count;
+		OSErr err;
+		PyObject *rv, *rvitem;
+		AEDesc desc;
+		
+		if ((err=AECountItems(&self->itself.selection, &count))) {
+			PyErr_Mac(ErrorObject, err);
+			return NULL;
+		}
+		if ( (rv=PyList_New(count)) == NULL )
+			return NULL;
+		for(i=0; i<count; i++) {
+			desc.dataHandle = NULL;
+			if ((err=AEGetNthDesc(&self->itself.selection, i+1, typeFSS, NULL, &desc))) {
+				Py_DECREF(rv);
+				PyErr_Mac(ErrorObject, err);
+				return NULL;
+			}
+			if ((err=AEGetDescData(&desc, &fss, sizeof(FSSpec)))) {
+				Py_DECREF(rv);
+				PyErr_Mac(ErrorObject, err);
+				return NULL;
+			}
+			rvitem = PyMac_BuildFSSpec(&fss);
+			PyList_SetItem(rv, i, rvitem);
+			AEDisposeDesc(&desc);
+		}
+		return rv;
+	}
+	if( strcmp(name, "selection_fsr") == 0 ) {
+		SInt32 i, count;
+		OSErr err;
+		PyObject *rv, *rvitem;
+		AEDesc desc;
+		
+		if ((err=AECountItems(&self->itself.selection, &count))) {
+			PyErr_Mac(ErrorObject, err);
+			return NULL;
+		}
+		if ( (rv=PyList_New(count)) == NULL )
+			return NULL;
+		for(i=0; i<count; i++) {
+			desc.dataHandle = NULL;
+			if ((err=AEGetNthDesc(&self->itself.selection, i+1, typeFSRef, NULL, &desc))) {
+				Py_DECREF(rv);
+				PyErr_Mac(ErrorObject, err);
+				return NULL;
+			}
+			if ((err=AEGetDescData(&desc, &fsr, sizeof(FSRef)))) {
+				Py_DECREF(rv);
+				PyErr_Mac(ErrorObject, err);
+				return NULL;
+			}
+			rvitem = PyMac_BuildFSRef(&fsr);
+			PyList_SetItem(rv, i, rvitem);
+			AEDisposeDesc(&desc);
+		}
+		return rv;
+	}
+	if( strcmp(name, "fileTranslation") == 0 )
+		return ResObj_New((Handle)self->itself.fileTranslation);
+	if( strcmp(name, "keyScript") == 0 )
+		return Py_BuildValue("h", (short)self->itself.keyScript);
+	if( strcmp(name, "saveFileName") == 0 )
+		return Py_BuildValue("O&", CFStringRefObj_New, self->itself.saveFileName);
+
+
+	return Py_FindMethod(navrr_methods, (PyObject *)self, name);
+}
+
+static int
+navrr_setattr(navrrobject *self, char *name, PyObject *v)
+{
+	/* Set attribute 'name' to value 'v'. v==NULL means delete */
+	
+	/* XXXX Add your own setattr code here */
+	return -1;
+}
+
+static char Navrrtype__doc__[] = 
+"Record containing result of a Nav file selection call. Use dir() for member names."
+;
+
+static PyTypeObject Navrrtype = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,				/*ob_size*/
+	"Nav.NavReplyRecord",			/*tp_name*/
+	sizeof(navrrobject),		/*tp_basicsize*/
+	0,				/*tp_itemsize*/
+	/* methods */
+	(destructor)navrr_dealloc,	/*tp_dealloc*/
+	(printfunc)0,		/*tp_print*/
+	(getattrfunc)navrr_getattr,	/*tp_getattr*/
+	(setattrfunc)navrr_setattr,	/*tp_setattr*/
+	(cmpfunc)0,		/*tp_compare*/
+	(reprfunc)0,		/*tp_repr*/
+	0,			/*tp_as_number*/
+	0,		/*tp_as_sequence*/
+	0,		/*tp_as_mapping*/
+	(hashfunc)0,		/*tp_hash*/
+	(ternaryfunc)0,		/*tp_call*/
+	(reprfunc)0,		/*tp_str*/
+
+	/* Space for future expansion */
+	0L,0L,0L,0L,
+	Navrrtype__doc__ /* Documentation string */
+};
+
+/* End of code for NavReplyRecord objects */
+		
+/* ----------------------------------------------------- */
+
+static char nav_NavGetFile__doc__[] =
+"(DialogOptions dict or kwargs+defaultLocation,eventProc,previewProc,filterProc,typeList) -> NavReplyRecord"
+;
+
+static PyObject *
+nav_NavGetFile(PyObject *self, PyObject *args, PyObject *kw)
+{
+	PyObject *dict;
+	AEDesc	*defaultLocation = NULL;
+	NavReplyRecord reply;
+	NavDialogOptions dialogOptions;
+	NavEventUPP eventProc = NULL;
+	NavPreviewUPP previewProc = NULL;
+	NavObjectFilterUPP filterProc = NULL;
+	NavTypeListHandle typeList = NULL;
+	OSErr err;
+
+	if ( kw && PyObject_IsTrue(kw) ) {
+		if (!PyArg_ParseTuple(args, ";either keyword arguments or dictionary expected"))
+			return NULL;
+		dict = kw;
+	} else if (!PyArg_ParseTuple(args, "O!", &PyDict_Type, &dict))
+		return NULL;
+	if (!filldialogoptions(dict, &defaultLocation, &dialogOptions, &eventProc, &previewProc, &filterProc, &typeList, NULL, NULL))
+		return NULL;
+	err = NavGetFile(defaultLocation, &reply, &dialogOptions,
+			eventProc, previewProc, filterProc, typeList, (void *)dict);
+	PyMem_DEL(defaultLocation);
+	if ( err ) {
+		PyErr_Mac(ErrorObject, err);
+		return NULL;
+	}
+	return (PyObject *)newnavrrobject(&reply);
+}
+
+static char nav_NavPutFile__doc__[] =
+"(DialogOptions dict or kwargs+defaultLocation,eventProc,fileCreator,fileType) -> NavReplyRecord"
+;
+
+static PyObject *
+nav_NavPutFile(PyObject *self, PyObject *args, PyObject *kw)
+{
+	PyObject *dict;
+	AEDesc	*defaultLocation = NULL;
+	NavReplyRecord reply;
+	NavDialogOptions dialogOptions;
+	NavEventUPP eventProc = NULL;
+	OSType fileType;
+	OSType fileCreator;
+	OSErr err;
+
+	if ( kw && PyObject_IsTrue(kw) ) {
+		if (!PyArg_ParseTuple(args, ";either keyword arguments or dictionary expected"))
+			return NULL;
+		dict = kw;
+	} else if (!PyArg_ParseTuple(args, "O!", &PyDict_Type, &dict))
+		return NULL;
+	if (!filldialogoptions(dict, &defaultLocation, &dialogOptions, &eventProc, NULL, NULL, NULL, &fileType, &fileCreator))
+		return NULL;
+	err = NavPutFile(defaultLocation, &reply, &dialogOptions,
+			eventProc, fileType, fileCreator, (void *)dict);
+	PyMem_DEL(defaultLocation);
+	if ( err ) {
+		PyErr_Mac(ErrorObject, err);
+		return NULL;
+	}
+	return (PyObject *)newnavrrobject(&reply);
+}
+
+static char nav_NavAskSaveChanges__doc__[] =
+"(NavAskSaveChangesAction, DialogOptions dict or kwargs+eventProc) -> NavAskSaveChangesResult"
+
+;
+
+static PyObject *
+nav_NavAskSaveChanges(PyObject *self, PyObject *args, PyObject *kw)
+{
+	PyObject *dict;
+	NavDialogOptions dialogOptions;
+	NavAskSaveChangesAction action;
+	NavAskSaveChangesResult reply;
+	NavEventUPP eventProc = NULL;
+	OSErr err;
+
+	if ( kw && PyObject_IsTrue(kw) ) {
+		if (!PyArg_ParseTuple(args, "k", &action))
+			return NULL;
+		dict = kw;
+	} else if (!PyArg_ParseTuple(args, "lO!", &action, &PyDict_Type, &dict))
+		return NULL;
+	if (!filldialogoptions(dict, NULL, &dialogOptions, &eventProc, NULL, NULL, NULL, NULL, NULL))
+		return NULL;
+	err = NavAskSaveChanges(&dialogOptions, action, &reply, eventProc, (void *)dict);
+	if ( err ) {
+		PyErr_Mac(ErrorObject, err);
+		return NULL;
+	}
+	return Py_BuildValue("l", (long)reply);
+}
+
+static char nav_NavCustomAskSaveChanges__doc__[] =
+"(DialogOptions dict or kwargs+eventProc) -> NavAskSaveChangesResult"
+;
+
+static PyObject *
+nav_NavCustomAskSaveChanges(PyObject *self, PyObject *args, PyObject *kw)
+{
+	PyObject *dict;
+	NavDialogOptions dialogOptions;
+	NavAskSaveChangesResult reply;
+	NavEventUPP eventProc = NULL;
+	OSErr err;
+
+	if ( kw && PyObject_IsTrue(kw) ) {
+		if (!PyArg_ParseTuple(args, ";either keyword arguments or dictionary expected"))
+			return NULL;
+		dict = kw;
+	} else if (!PyArg_ParseTuple(args, "O!", &PyDict_Type, &dict))
+		return NULL;
+	if (!filldialogoptions(dict, NULL, &dialogOptions, &eventProc, NULL, NULL, NULL, NULL, NULL))
+		return NULL;
+	err = NavCustomAskSaveChanges(&dialogOptions, &reply, eventProc, (void *)dict);
+	if ( err ) {
+		PyErr_Mac(ErrorObject, err);
+		return NULL;
+	}
+	return Py_BuildValue("l", (long)reply);
+}
+
+static char nav_NavAskDiscardChanges__doc__[] =
+"(DialogOptions dict or kwargs+eventProc) -> NavAskSaveChangesResult"
+;
+
+static PyObject *
+nav_NavAskDiscardChanges(PyObject *self, PyObject *args, PyObject *kw)
+{
+	PyObject *dict;
+	NavDialogOptions dialogOptions;
+	NavAskSaveChangesResult reply;
+	NavEventUPP eventProc = NULL;
+	OSErr err;
+
+	if ( kw && PyObject_IsTrue(kw) ) {
+		if (!PyArg_ParseTuple(args, ";either keyword arguments or dictionary expected"))
+			return NULL;
+		dict = kw;
+	} else if (!PyArg_ParseTuple(args, "O!", &PyDict_Type, &dict))
+		return NULL;
+	if (!filldialogoptions(dict, NULL, &dialogOptions, &eventProc, NULL, NULL, NULL, NULL, NULL))
+		return NULL;
+	err = NavAskDiscardChanges(&dialogOptions, &reply, eventProc, (void *)dict);
+	if ( err ) {
+		PyErr_Mac(ErrorObject, err);
+		return NULL;
+	}
+	return Py_BuildValue("l", (long)reply);
+}
+
+static char nav_NavChooseFile__doc__[] =
+"(DialogOptions dict or kwargs+defaultLocation,eventProc,previewProc,filterProc,typeList) -> NavReplyRecord"
+;
+
+static PyObject *
+nav_NavChooseFile(PyObject *self, PyObject *args, PyObject *kw)
+{
+	PyObject *dict;
+	AEDesc	*defaultLocation = NULL;
+	NavReplyRecord reply;
+	NavDialogOptions dialogOptions;
+	NavEventUPP eventProc = NULL;
+	NavPreviewUPP previewProc = NULL;
+	NavObjectFilterUPP filterProc = NULL;
+	NavTypeListHandle typeList = NULL;
+	OSErr err;
+
+	if ( kw && PyObject_IsTrue(kw) ) {
+		if (!PyArg_ParseTuple(args, ";either keyword arguments or dictionary expected"))
+			return NULL;
+		dict = kw;
+	} else if (!PyArg_ParseTuple(args, "O!", &PyDict_Type, &dict))
+		return NULL;
+	if (!filldialogoptions(dict, &defaultLocation, &dialogOptions, &eventProc, &previewProc, &filterProc, &typeList, NULL, NULL))
+		return NULL;
+	err = NavChooseFile(defaultLocation, &reply, &dialogOptions,
+			eventProc, previewProc, filterProc, typeList, (void *)dict);
+	PyMem_DEL(defaultLocation);
+	if ( err ) {
+		PyErr_Mac(ErrorObject, err);
+		return NULL;
+	}
+	return (PyObject *)newnavrrobject(&reply);
+}
+
+static char nav_NavChooseFolder__doc__[] =
+"(DialogOptions dict or kwargs+defaultLocation,eventProc,filterProc) -> NavReplyRecord"
+;
+
+static PyObject *
+nav_NavChooseFolder(PyObject *self, PyObject *args, PyObject *kw)
+{
+	PyObject *dict;
+	AEDesc	*defaultLocation = NULL;
+	NavReplyRecord reply;
+	NavDialogOptions dialogOptions;
+	NavEventUPP eventProc = NULL;
+	NavObjectFilterUPP filterProc = NULL;
+	OSErr err;
+
+	if ( kw && PyObject_IsTrue(kw) ) {
+		if (!PyArg_ParseTuple(args, ";either keyword arguments or dictionary expected"))
+			return NULL;
+		dict = kw;
+	} else if (!PyArg_ParseTuple(args, "O!", &PyDict_Type, &dict))
+		return NULL;
+	if (!filldialogoptions(dict, &defaultLocation, &dialogOptions, &eventProc, NULL, &filterProc, NULL, NULL, NULL))
+		return NULL;
+	err = NavChooseFolder(defaultLocation, &reply, &dialogOptions,
+			eventProc, filterProc, (void *)dict);
+	PyMem_DEL(defaultLocation);
+	if ( err ) {
+		PyErr_Mac(ErrorObject, err);
+		return NULL;
+	}
+	return (PyObject *)newnavrrobject(&reply);
+}
+
+static char nav_NavChooseVolume__doc__[] =
+"(DialogOptions dict or kwargs+defaultLocation,eventProc,filterProc) -> NavReplyRecord"
+;
+
+static PyObject *
+nav_NavChooseVolume(PyObject *self, PyObject *args, PyObject *kw)
+{
+	PyObject *dict;
+	AEDesc	*defaultLocation = NULL;
+	NavReplyRecord reply;
+	NavDialogOptions dialogOptions;
+	NavEventUPP eventProc = NULL;
+	NavObjectFilterUPP filterProc = NULL;
+	OSErr err;
+
+	if ( kw && PyObject_IsTrue(kw) ) {
+		if (!PyArg_ParseTuple(args, ";either keyword arguments or dictionary expected"))
+			return NULL;
+		dict = kw;
+	} else if (!PyArg_ParseTuple(args, "O!", &PyDict_Type, &dict))
+		return NULL;
+	if (!filldialogoptions(dict, &defaultLocation, &dialogOptions, &eventProc, NULL, &filterProc, NULL, NULL, NULL))
+		return NULL;
+	err = NavChooseVolume(defaultLocation, &reply, &dialogOptions,
+			eventProc, filterProc, (void *)dict);
+	PyMem_DEL(defaultLocation);
+	if ( err ) {
+		PyErr_Mac(ErrorObject, err);
+		return NULL;
+	}
+	return (PyObject *)newnavrrobject(&reply);
+}
+
+static char nav_NavChooseObject__doc__[] =
+"(DialogOptions dict or kwargs+defaultLocation,eventProc,filterProc) -> NavReplyRecord"
+;
+
+static PyObject *
+nav_NavChooseObject(PyObject *self, PyObject *args, PyObject *kw)
+{
+	PyObject *dict;
+	AEDesc	*defaultLocation = NULL;
+	NavReplyRecord reply;
+	NavDialogOptions dialogOptions;
+	NavEventUPP eventProc = NULL;
+	NavObjectFilterUPP filterProc = NULL;
+	OSErr err;
+
+	if ( kw && PyObject_IsTrue(kw) ) {
+		if (!PyArg_ParseTuple(args, ";either keyword arguments or dictionary expected"))
+			return NULL;
+		dict = kw;
+	} else if (!PyArg_ParseTuple(args, "O!", &PyDict_Type, &dict))
+		return NULL;
+	if (!filldialogoptions(dict, &defaultLocation, &dialogOptions, &eventProc, NULL, &filterProc, NULL, NULL, NULL))
+		return NULL;
+	err = NavChooseObject(defaultLocation, &reply, &dialogOptions,
+			eventProc, filterProc, (void *)dict);
+	PyMem_DEL(defaultLocation);
+	if ( err ) {
+		PyErr_Mac(ErrorObject, err);
+		return NULL;
+	}
+	return (PyObject *)newnavrrobject(&reply);
+}
+
+static char nav_NavNewFolder__doc__[] =
+"(DialogOptions dict or kwargs+defaultLocation,eventProc) -> NavReplyRecord"
+;
+
+static PyObject *
+nav_NavNewFolder(PyObject *self, PyObject *args, PyObject *kw)
+{
+	PyObject *dict;
+	AEDesc	*defaultLocation = NULL;
+	NavReplyRecord reply;
+	NavDialogOptions dialogOptions;
+	NavEventUPP eventProc = NULL;
+	OSErr err;
+
+	if ( kw && PyObject_IsTrue(kw) ) {
+		if (!PyArg_ParseTuple(args, ";either keyword arguments or dictionary expected"))
+			return NULL;
+		dict = kw;
+	} else if (!PyArg_ParseTuple(args, "O!", &PyDict_Type, &dict))
+		return NULL;
+	if (!filldialogoptions(dict, &defaultLocation, &dialogOptions, &eventProc, NULL, NULL, NULL, NULL, NULL))
+		return NULL;
+	err = NavNewFolder(defaultLocation, &reply, &dialogOptions, eventProc, (void *)dict);
+	PyMem_DEL(defaultLocation);
+	if ( err ) {
+		PyErr_Mac(ErrorObject, err);
+		return NULL;
+	}
+	return (PyObject *)newnavrrobject(&reply);
+}
+
+#if 0
+/* XXXX I don't know what to do with the void * argument */
+static char nav_NavCustomControl__doc__[] =
+""
+;
+
+
+static PyObject *
+nav_NavCustomControl(PyObject *self, PyObject *args)
+{
+
+	if (!PyArg_ParseTuple(args, ""))
+		return NULL;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+#endif
+
+static char nav_NavServicesCanRun__doc__[] =
+"()->int"
+;
+
+static PyObject *
+nav_NavServicesCanRun(PyObject *self, PyObject *args)
+{
+	Boolean rv;
+	if (!PyArg_ParseTuple(args, ""))
+		return NULL;
+	rv = NavServicesCanRun();
+	return Py_BuildValue("l", (long)rv);
+}
+
+static char nav_NavServicesAvailable__doc__[] =
+"()->int"
+;
+
+static PyObject *
+nav_NavServicesAvailable(PyObject *self, PyObject *args)
+{
+	Boolean rv;
+	
+	if (!PyArg_ParseTuple(args, ""))
+		return NULL;
+	rv = NavServicesAvailable();
+	return Py_BuildValue("l", (long)rv);
+}
+/* XX */
+static char nav_NavLoad__doc__[] =
+"()->None"
+;
+
+static PyObject *
+nav_NavLoad(PyObject *self, PyObject *args)
+{
+
+	if (!PyArg_ParseTuple(args, ""))
+		return NULL;
+	NavLoad();
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static char nav_NavUnload__doc__[] =
+"()->None"
+;
+
+static PyObject *
+nav_NavUnload(PyObject *self, PyObject *args)
+{
+
+	if (!PyArg_ParseTuple(args, ""))
+		return NULL;
+	NavUnload();
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static char nav_NavLibraryVersion__doc__[] =
+"()->int"
+;
+
+static PyObject *
+nav_NavLibraryVersion(PyObject *self, PyObject *args)
+{
+	UInt32 rv;
+	
+	if (!PyArg_ParseTuple(args, ""))
+		return NULL;
+	rv = NavLibraryVersion();
+	return Py_BuildValue("l", (long)rv);
+}
+
+static char nav_NavGetDefaultDialogOptions__doc__[] =
+"()->dict\nPass dict or keyword args with same names to other calls."
+;
+
+static PyObject *
+nav_NavGetDefaultDialogOptions(PyObject *self, PyObject *args)
+{
+	NavDialogOptions dialogOptions;
+	OSErr err;
+	
+	err = NavGetDefaultDialogOptions(&dialogOptions);
+	if ( err ) {
+		PyErr_Mac(ErrorObject, err);
+		return NULL;
+	}
+	return Py_BuildValue("{s:h,s:l,s:O&,s:O&,s:O&,s:O&,s:O&,s:O&,s:O&,s:O&,s:O&}",
+		"version", dialogOptions.version,
+		"dialogOptionFlags", dialogOptions.dialogOptionFlags,
+		"location", PyMac_BuildPoint, dialogOptions.location,
+		"clientName", PyMac_BuildStr255, &dialogOptions.clientName,
+		"windowTitle", PyMac_BuildStr255, &dialogOptions.windowTitle,
+		"actionButtonLabel", PyMac_BuildStr255, &dialogOptions.actionButtonLabel,
+		"cancelButtonLabel", PyMac_BuildStr255, &dialogOptions.cancelButtonLabel,
+		"savedFileName", PyMac_BuildStr255, &dialogOptions.savedFileName,
+		"message", PyMac_BuildStr255, &dialogOptions.message,
+		"preferenceKey", PyMac_BuildOSType, dialogOptions.preferenceKey,
+		"popupExtension", OptResObj_New, dialogOptions.popupExtension);
+}
+
+/* List of methods defined in the module */
+
+static struct PyMethodDef nav_methods[] = {
+	{"NavGetFile",	(PyCFunction)nav_NavGetFile,	METH_VARARGS|METH_KEYWORDS,	nav_NavGetFile__doc__},
+ {"NavPutFile",	(PyCFunction)nav_NavPutFile,	METH_VARARGS|METH_KEYWORDS,	nav_NavPutFile__doc__},
+ {"NavAskSaveChanges",	(PyCFunction)nav_NavAskSaveChanges,	METH_VARARGS|METH_KEYWORDS,	nav_NavAskSaveChanges__doc__},
+ {"NavCustomAskSaveChanges",	(PyCFunction)nav_NavCustomAskSaveChanges,	METH_VARARGS|METH_KEYWORDS,	nav_NavCustomAskSaveChanges__doc__},
+ {"NavAskDiscardChanges",	(PyCFunction)nav_NavAskDiscardChanges,	METH_VARARGS|METH_KEYWORDS,	nav_NavAskDiscardChanges__doc__},
+ {"NavChooseFile",	(PyCFunction)nav_NavChooseFile,	METH_VARARGS|METH_KEYWORDS,	nav_NavChooseFile__doc__},
+ {"NavChooseFolder",	(PyCFunction)nav_NavChooseFolder,	METH_VARARGS|METH_KEYWORDS,	nav_NavChooseFolder__doc__},
+ {"NavChooseVolume",	(PyCFunction)nav_NavChooseVolume,	METH_VARARGS|METH_KEYWORDS,	nav_NavChooseVolume__doc__},
+ {"NavChooseObject",	(PyCFunction)nav_NavChooseObject,	METH_VARARGS|METH_KEYWORDS,	nav_NavChooseObject__doc__},
+ {"NavNewFolder",	(PyCFunction)nav_NavNewFolder,	METH_VARARGS|METH_KEYWORDS,	nav_NavNewFolder__doc__},
+#if 0
+ {"NavCustomControl",	(PyCFunction)nav_NavCustomControl,	METH_VARARGS,	nav_NavCustomControl__doc__},
+#endif
+ {"NavServicesCanRun",	(PyCFunction)nav_NavServicesCanRun,	METH_VARARGS,	nav_NavServicesCanRun__doc__},
+ {"NavServicesAvailable",	(PyCFunction)nav_NavServicesAvailable,	METH_VARARGS,	nav_NavServicesAvailable__doc__},
+ {"NavLoad",	(PyCFunction)nav_NavLoad,	METH_VARARGS,	nav_NavLoad__doc__},
+ {"NavUnload",	(PyCFunction)nav_NavUnload,	METH_VARARGS,	nav_NavUnload__doc__},
+ {"NavLibraryVersion",	(PyCFunction)nav_NavLibraryVersion,	METH_VARARGS,	nav_NavLibraryVersion__doc__},
+ {"NavGetDefaultDialogOptions",	(PyCFunction)nav_NavGetDefaultDialogOptions,	METH_VARARGS,	nav_NavGetDefaultDialogOptions__doc__},
+	{NULL,	 (PyCFunction)NULL, 0, NULL}		/* sentinel */
+};
+
+
+/* Initialization function for the module (*must* be called initNav) */
+
+static char Nav_module_documentation[] = 
+"Interface to Navigation Services\n"
+"Most calls accept a NavDialogOptions dictionary or keywords with the same names, pass {}\n"
+"if you want the default options.\n"
+"Use NavGetDefaultDialogOptions() to find out common option names.\n"
+"See individual docstrings for additional keyword args/dictentries supported by each call.\n"
+"Pass None as eventProc to get movable-modal dialogs that process updates through the standard Python mechanism."
+;
+
+void
+initNav(void)
+{
+	PyObject *m, *d;
+
+	/* Test that we have NavServices */
+	if ( !NavServicesAvailable() ) {
+		PyErr_SetString(PyExc_ImportError, "Navigation Services not available");
+		return;
+	}
+	/* Create the module and add the functions */
+	m = Py_InitModule4("Nav", nav_methods,
+		Nav_module_documentation,
+		(PyObject*)NULL,PYTHON_API_VERSION);
+
+	/* Add some symbolic constants to the module */
+	d = PyModule_GetDict(m);
+	ErrorObject = PyString_FromString("Nav.error");
+	PyDict_SetItemString(d, "error", ErrorObject);
+
+	/* XXXX Add constants here */
+	
+	/* Set UPPs */
+	my_eventProcUPP = NewNavEventUPP(my_eventProc);
+	my_previewProcUPP = NewNavPreviewUPP(my_previewProc);
+	my_filterProcUPP = NewNavObjectFilterUPP(my_filterProc);
+	
+}
+

Added: vendor/Python/current/Mac/Modules/OSATerminology.c
===================================================================
--- vendor/Python/current/Mac/Modules/OSATerminology.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/OSATerminology.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,93 @@
+/*
+** This module is a one-trick pony: given an FSSpec it gets the aeut
+** resources. It was written by Donovan Preston and slightly modified
+** by Jack.
+**
+** It should be considered a placeholder, it will probably be replaced
+** by a full interface to OpenScripting.
+*/
+#include "Python.h"
+#include "pymactoolbox.h"
+
+#include <Carbon/Carbon.h>
+
+static PyObject *
+PyOSA_GetAppTerminology(PyObject* self, PyObject* args)
+{
+	AEDesc theDesc = {0,0};
+	FSSpec fss;
+	ComponentInstance defaultComponent = NULL;
+	SInt16 defaultTerminology = 0;
+	Boolean didLaunch = 0;
+	OSAError err;
+	long modeFlags = 0;
+	
+	if (!PyArg_ParseTuple(args, "O&|i", PyMac_GetFSSpec, &fss, &modeFlags))
+		 return NULL;
+	
+	defaultComponent = OpenDefaultComponent (kOSAComponentType, 'ascr');
+	err = GetComponentInstanceError (defaultComponent);
+	if (err) return PyMac_Error(err);
+	err = OSAGetAppTerminology (
+    	defaultComponent, 
+    	modeFlags,
+    	&fss, 
+    	defaultTerminology, 
+    	&didLaunch, 
+    	&theDesc
+	);
+	if (err) return PyMac_Error(err);
+	return Py_BuildValue("O&i", AEDesc_New, &theDesc, didLaunch);
+}
+
+static PyObject *
+PyOSA_GetSysTerminology(PyObject* self, PyObject* args)
+{
+	AEDesc theDesc = {0,0};
+	FSSpec fss;
+	ComponentInstance defaultComponent = NULL;
+	SInt16 defaultTerminology = 0;
+	Boolean didLaunch = 0;
+	OSAError err;
+	long modeFlags = 0;
+	
+	if (!PyArg_ParseTuple(args, "O&|i", PyMac_GetFSSpec, &fss, &modeFlags))
+		 return NULL;
+	
+	defaultComponent = OpenDefaultComponent (kOSAComponentType, 'ascr');
+	err = GetComponentInstanceError (defaultComponent);
+	if (err) return PyMac_Error(err);
+	err = OSAGetAppTerminology (
+    	defaultComponent, 
+    	modeFlags,
+    	&fss, 
+    	defaultTerminology, 
+    	&didLaunch, 
+    	&theDesc
+	);
+	if (err) return PyMac_Error(err);
+	return Py_BuildValue("O&i", AEDesc_New, &theDesc, didLaunch);
+}
+
+/* 
+ * List of methods defined in the module
+ */
+static struct PyMethodDef OSATerminology_methods[] =
+{
+  	{"GetAppTerminology", 
+		(PyCFunction) PyOSA_GetAppTerminology,
+		METH_VARARGS,
+		"Get an applications terminology, as an AEDesc object."},
+  	{"GetSysTerminology", 
+		(PyCFunction) PyOSA_GetSysTerminology,
+		METH_VARARGS,
+		"Get an applications system terminology, as an AEDesc object."},
+	{NULL, (PyCFunction) NULL, 0, NULL}
+};
+
+
+void
+initOSATerminology(void)
+{
+	Py_InitModule("OSATerminology", OSATerminology_methods);
+}
\ No newline at end of file

Added: vendor/Python/current/Mac/Modules/ae/README
===================================================================
--- vendor/Python/current/Mac/Modules/ae/README	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/ae/README	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,24 @@
+A quick note on what all the files here are, currently (16-7-95),
+and whether they really are source or generated.
+
+aegen.py		Generated by aescan, temporary file
+AEModule.c		Generated by aescan, from AppleEvents.h
+AEObjects.py	Generated by aescan, from AEObjects.h
+aepack.py		Routines to convert python objects <-> AEDesc record
+				(formerly part of aetools, now imported there)
+AERegistry.py	Generated by aescan, from AERegistry.h
+aescan.py		Program to scan headers and generate AE modules
+aesupport.py	Helper code for aescan
+aetools.py		Routines/classes to create and send appleevents
+aetypes.py		Classes for python objects corresponding to AEDesc types
+				(formerly part of aetools, now imported there)
+AppleEvents.py	Generated by aescan, from AppleEvents.h
+AppleScript_Suite.py	Generated by gensuitemodule
+echo.py			Old test program (may still work) to echo events back to sender
+gensuitemodule.py	Program to scan aete/aeut resources and generate python
+				interface modules
+Required_Suite.py	Generated by gensuitemodule
+Standard_Suite.py	Generated by gensuitemodule
+tae.py			Old test program (may still work) to send an appleevent
+tell.py			Old test program (may still work) to send an appleevent
+test_suite.py	Test program to test bits of the _Suite modules and aetools/etc

Added: vendor/Python/current/Mac/Modules/ae/_AEmodule.c
===================================================================
--- vendor/Python/current/Mac/Modules/ae/_AEmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/ae/_AEmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1454 @@
+
+/* =========================== Module _AE =========================== */
+
+#include "Python.h"
+
+
+
+#include "pymactoolbox.h"
+
+/* Macro to test whether a weak-loaded CFM function exists */
+#define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL )  {\
+        PyErr_SetString(PyExc_NotImplementedError, \
+        "Not available in this shared library/OS version"); \
+        return NULL; \
+    }} while(0)
+
+
+#include <Carbon/Carbon.h>
+
+#ifdef USE_TOOLBOX_OBJECT_GLUE
+extern PyObject *_AEDesc_New(AEDesc *);
+extern int _AEDesc_Convert(PyObject *, AEDesc *);
+
+#define AEDesc_New _AEDesc_New
+#define AEDesc_NewBorrowed _AEDesc_NewBorrowed
+#define AEDesc_Convert _AEDesc_Convert
+#endif
+
+typedef long refcontype;
+
+static pascal OSErr GenericEventHandler(const AppleEvent *request, AppleEvent *reply, refcontype refcon); /* Forward */
+
+AEEventHandlerUPP upp_GenericEventHandler;
+
+static pascal Boolean AEIdleProc(EventRecord *theEvent, long *sleepTime, RgnHandle *mouseRgn)
+{
+        if ( PyOS_InterruptOccurred() )
+                return 1;
+        return 0;
+}
+
+AEIdleUPP upp_AEIdleProc;
+
+static PyObject *AE_Error;
+
+/* ----------------------- Object type AEDesc ----------------------- */
+
+PyTypeObject AEDesc_Type;
+
+#define AEDesc_Check(x) ((x)->ob_type == &AEDesc_Type || PyObject_TypeCheck((x), &AEDesc_Type))
+
+typedef struct AEDescObject {
+	PyObject_HEAD
+	AEDesc ob_itself;
+	int ob_owned;
+} AEDescObject;
+
+PyObject *AEDesc_New(AEDesc *itself)
+{
+	AEDescObject *it;
+	it = PyObject_NEW(AEDescObject, &AEDesc_Type);
+	if (it == NULL) return NULL;
+	it->ob_itself = *itself;
+	it->ob_owned = 1;
+	return (PyObject *)it;
+}
+
+int AEDesc_Convert(PyObject *v, AEDesc *p_itself)
+{
+	if (!AEDesc_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "AEDesc required");
+		return 0;
+	}
+	*p_itself = ((AEDescObject *)v)->ob_itself;
+	return 1;
+}
+
+static void AEDesc_dealloc(AEDescObject *self)
+{
+	if (self->ob_owned) AEDisposeDesc(&self->ob_itself);
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *AEDesc_AECoerceDesc(AEDescObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	DescType toType;
+	AEDesc result;
+#ifndef AECoerceDesc
+	PyMac_PRECHECK(AECoerceDesc);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetOSType, &toType))
+		return NULL;
+	_err = AECoerceDesc(&_self->ob_itself,
+	                    toType,
+	                    &result);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     AEDesc_New, &result);
+	return _res;
+}
+
+static PyObject *AEDesc_AEDuplicateDesc(AEDescObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	AEDesc result;
+#ifndef AEDuplicateDesc
+	PyMac_PRECHECK(AEDuplicateDesc);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = AEDuplicateDesc(&_self->ob_itself,
+	                       &result);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     AEDesc_New, &result);
+	return _res;
+}
+
+static PyObject *AEDesc_AECountItems(AEDescObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	long theCount;
+#ifndef AECountItems
+	PyMac_PRECHECK(AECountItems);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = AECountItems(&_self->ob_itself,
+	                    &theCount);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     theCount);
+	return _res;
+}
+
+static PyObject *AEDesc_AEPutPtr(AEDescObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	long index;
+	DescType typeCode;
+	char *dataPtr__in__;
+	long dataPtr__len__;
+	int dataPtr__in_len__;
+#ifndef AEPutPtr
+	PyMac_PRECHECK(AEPutPtr);
+#endif
+	if (!PyArg_ParseTuple(_args, "lO&s#",
+	                      &index,
+	                      PyMac_GetOSType, &typeCode,
+	                      &dataPtr__in__, &dataPtr__in_len__))
+		return NULL;
+	dataPtr__len__ = dataPtr__in_len__;
+	_err = AEPutPtr(&_self->ob_itself,
+	                index,
+	                typeCode,
+	                dataPtr__in__, dataPtr__len__);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *AEDesc_AEPutDesc(AEDescObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	long index;
+	AEDesc theAEDesc;
+#ifndef AEPutDesc
+	PyMac_PRECHECK(AEPutDesc);
+#endif
+	if (!PyArg_ParseTuple(_args, "lO&",
+	                      &index,
+	                      AEDesc_Convert, &theAEDesc))
+		return NULL;
+	_err = AEPutDesc(&_self->ob_itself,
+	                 index,
+	                 &theAEDesc);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *AEDesc_AEGetNthPtr(AEDescObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	long index;
+	DescType desiredType;
+	AEKeyword theAEKeyword;
+	DescType typeCode;
+	char *dataPtr__out__;
+	long dataPtr__len__;
+	int dataPtr__in_len__;
+#ifndef AEGetNthPtr
+	PyMac_PRECHECK(AEGetNthPtr);
+#endif
+	if (!PyArg_ParseTuple(_args, "lO&i",
+	                      &index,
+	                      PyMac_GetOSType, &desiredType,
+	                      &dataPtr__in_len__))
+		return NULL;
+	if ((dataPtr__out__ = malloc(dataPtr__in_len__)) == NULL)
+	{
+		PyErr_NoMemory();
+		goto dataPtr__error__;
+	}
+	dataPtr__len__ = dataPtr__in_len__;
+	_err = AEGetNthPtr(&_self->ob_itself,
+	                   index,
+	                   desiredType,
+	                   &theAEKeyword,
+	                   &typeCode,
+	                   dataPtr__out__, dataPtr__len__, &dataPtr__len__);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&O&s#",
+	                     PyMac_BuildOSType, theAEKeyword,
+	                     PyMac_BuildOSType, typeCode,
+	                     dataPtr__out__, (int)dataPtr__len__);
+	free(dataPtr__out__);
+ dataPtr__error__: ;
+	return _res;
+}
+
+static PyObject *AEDesc_AEGetNthDesc(AEDescObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	long index;
+	DescType desiredType;
+	AEKeyword theAEKeyword;
+	AEDesc result;
+#ifndef AEGetNthDesc
+	PyMac_PRECHECK(AEGetNthDesc);
+#endif
+	if (!PyArg_ParseTuple(_args, "lO&",
+	                      &index,
+	                      PyMac_GetOSType, &desiredType))
+		return NULL;
+	_err = AEGetNthDesc(&_self->ob_itself,
+	                    index,
+	                    desiredType,
+	                    &theAEKeyword,
+	                    &result);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&O&",
+	                     PyMac_BuildOSType, theAEKeyword,
+	                     AEDesc_New, &result);
+	return _res;
+}
+
+static PyObject *AEDesc_AESizeOfNthItem(AEDescObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	long index;
+	DescType typeCode;
+	Size dataSize;
+#ifndef AESizeOfNthItem
+	PyMac_PRECHECK(AESizeOfNthItem);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &index))
+		return NULL;
+	_err = AESizeOfNthItem(&_self->ob_itself,
+	                       index,
+	                       &typeCode,
+	                       &dataSize);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&l",
+	                     PyMac_BuildOSType, typeCode,
+	                     dataSize);
+	return _res;
+}
+
+static PyObject *AEDesc_AEDeleteItem(AEDescObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	long index;
+#ifndef AEDeleteItem
+	PyMac_PRECHECK(AEDeleteItem);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &index))
+		return NULL;
+	_err = AEDeleteItem(&_self->ob_itself,
+	                    index);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *AEDesc_AEPutParamPtr(AEDescObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	AEKeyword theAEKeyword;
+	DescType typeCode;
+	char *dataPtr__in__;
+	long dataPtr__len__;
+	int dataPtr__in_len__;
+#ifndef AEPutParamPtr
+	PyMac_PRECHECK(AEPutParamPtr);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&s#",
+	                      PyMac_GetOSType, &theAEKeyword,
+	                      PyMac_GetOSType, &typeCode,
+	                      &dataPtr__in__, &dataPtr__in_len__))
+		return NULL;
+	dataPtr__len__ = dataPtr__in_len__;
+	_err = AEPutParamPtr(&_self->ob_itself,
+	                     theAEKeyword,
+	                     typeCode,
+	                     dataPtr__in__, dataPtr__len__);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *AEDesc_AEPutParamDesc(AEDescObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	AEKeyword theAEKeyword;
+	AEDesc theAEDesc;
+#ifndef AEPutParamDesc
+	PyMac_PRECHECK(AEPutParamDesc);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetOSType, &theAEKeyword,
+	                      AEDesc_Convert, &theAEDesc))
+		return NULL;
+	_err = AEPutParamDesc(&_self->ob_itself,
+	                      theAEKeyword,
+	                      &theAEDesc);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *AEDesc_AEGetParamPtr(AEDescObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	AEKeyword theAEKeyword;
+	DescType desiredType;
+	DescType typeCode;
+	char *dataPtr__out__;
+	long dataPtr__len__;
+	int dataPtr__in_len__;
+#ifndef AEGetParamPtr
+	PyMac_PRECHECK(AEGetParamPtr);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&i",
+	                      PyMac_GetOSType, &theAEKeyword,
+	                      PyMac_GetOSType, &desiredType,
+	                      &dataPtr__in_len__))
+		return NULL;
+	if ((dataPtr__out__ = malloc(dataPtr__in_len__)) == NULL)
+	{
+		PyErr_NoMemory();
+		goto dataPtr__error__;
+	}
+	dataPtr__len__ = dataPtr__in_len__;
+	_err = AEGetParamPtr(&_self->ob_itself,
+	                     theAEKeyword,
+	                     desiredType,
+	                     &typeCode,
+	                     dataPtr__out__, dataPtr__len__, &dataPtr__len__);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&s#",
+	                     PyMac_BuildOSType, typeCode,
+	                     dataPtr__out__, (int)dataPtr__len__);
+	free(dataPtr__out__);
+ dataPtr__error__: ;
+	return _res;
+}
+
+static PyObject *AEDesc_AEGetParamDesc(AEDescObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	AEKeyword theAEKeyword;
+	DescType desiredType;
+	AEDesc result;
+#ifndef AEGetParamDesc
+	PyMac_PRECHECK(AEGetParamDesc);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetOSType, &theAEKeyword,
+	                      PyMac_GetOSType, &desiredType))
+		return NULL;
+	_err = AEGetParamDesc(&_self->ob_itself,
+	                      theAEKeyword,
+	                      desiredType,
+	                      &result);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     AEDesc_New, &result);
+	return _res;
+}
+
+static PyObject *AEDesc_AESizeOfParam(AEDescObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	AEKeyword theAEKeyword;
+	DescType typeCode;
+	Size dataSize;
+#ifndef AESizeOfParam
+	PyMac_PRECHECK(AESizeOfParam);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetOSType, &theAEKeyword))
+		return NULL;
+	_err = AESizeOfParam(&_self->ob_itself,
+	                     theAEKeyword,
+	                     &typeCode,
+	                     &dataSize);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&l",
+	                     PyMac_BuildOSType, typeCode,
+	                     dataSize);
+	return _res;
+}
+
+static PyObject *AEDesc_AEDeleteParam(AEDescObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	AEKeyword theAEKeyword;
+#ifndef AEDeleteParam
+	PyMac_PRECHECK(AEDeleteParam);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetOSType, &theAEKeyword))
+		return NULL;
+	_err = AEDeleteParam(&_self->ob_itself,
+	                     theAEKeyword);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *AEDesc_AEGetAttributePtr(AEDescObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	AEKeyword theAEKeyword;
+	DescType desiredType;
+	DescType typeCode;
+	char *dataPtr__out__;
+	long dataPtr__len__;
+	int dataPtr__in_len__;
+#ifndef AEGetAttributePtr
+	PyMac_PRECHECK(AEGetAttributePtr);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&i",
+	                      PyMac_GetOSType, &theAEKeyword,
+	                      PyMac_GetOSType, &desiredType,
+	                      &dataPtr__in_len__))
+		return NULL;
+	if ((dataPtr__out__ = malloc(dataPtr__in_len__)) == NULL)
+	{
+		PyErr_NoMemory();
+		goto dataPtr__error__;
+	}
+	dataPtr__len__ = dataPtr__in_len__;
+	_err = AEGetAttributePtr(&_self->ob_itself,
+	                         theAEKeyword,
+	                         desiredType,
+	                         &typeCode,
+	                         dataPtr__out__, dataPtr__len__, &dataPtr__len__);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&s#",
+	                     PyMac_BuildOSType, typeCode,
+	                     dataPtr__out__, (int)dataPtr__len__);
+	free(dataPtr__out__);
+ dataPtr__error__: ;
+	return _res;
+}
+
+static PyObject *AEDesc_AEGetAttributeDesc(AEDescObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	AEKeyword theAEKeyword;
+	DescType desiredType;
+	AEDesc result;
+#ifndef AEGetAttributeDesc
+	PyMac_PRECHECK(AEGetAttributeDesc);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetOSType, &theAEKeyword,
+	                      PyMac_GetOSType, &desiredType))
+		return NULL;
+	_err = AEGetAttributeDesc(&_self->ob_itself,
+	                          theAEKeyword,
+	                          desiredType,
+	                          &result);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     AEDesc_New, &result);
+	return _res;
+}
+
+static PyObject *AEDesc_AESizeOfAttribute(AEDescObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	AEKeyword theAEKeyword;
+	DescType typeCode;
+	Size dataSize;
+#ifndef AESizeOfAttribute
+	PyMac_PRECHECK(AESizeOfAttribute);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetOSType, &theAEKeyword))
+		return NULL;
+	_err = AESizeOfAttribute(&_self->ob_itself,
+	                         theAEKeyword,
+	                         &typeCode,
+	                         &dataSize);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&l",
+	                     PyMac_BuildOSType, typeCode,
+	                     dataSize);
+	return _res;
+}
+
+static PyObject *AEDesc_AEPutAttributePtr(AEDescObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	AEKeyword theAEKeyword;
+	DescType typeCode;
+	char *dataPtr__in__;
+	long dataPtr__len__;
+	int dataPtr__in_len__;
+#ifndef AEPutAttributePtr
+	PyMac_PRECHECK(AEPutAttributePtr);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&s#",
+	                      PyMac_GetOSType, &theAEKeyword,
+	                      PyMac_GetOSType, &typeCode,
+	                      &dataPtr__in__, &dataPtr__in_len__))
+		return NULL;
+	dataPtr__len__ = dataPtr__in_len__;
+	_err = AEPutAttributePtr(&_self->ob_itself,
+	                         theAEKeyword,
+	                         typeCode,
+	                         dataPtr__in__, dataPtr__len__);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *AEDesc_AEPutAttributeDesc(AEDescObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	AEKeyword theAEKeyword;
+	AEDesc theAEDesc;
+#ifndef AEPutAttributeDesc
+	PyMac_PRECHECK(AEPutAttributeDesc);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetOSType, &theAEKeyword,
+	                      AEDesc_Convert, &theAEDesc))
+		return NULL;
+	_err = AEPutAttributeDesc(&_self->ob_itself,
+	                          theAEKeyword,
+	                          &theAEDesc);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *AEDesc_AEGetDescDataSize(AEDescObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Size _rv;
+#ifndef AEGetDescDataSize
+	PyMac_PRECHECK(AEGetDescDataSize);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = AEGetDescDataSize(&_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *AEDesc_AESend(AEDescObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	AppleEvent reply;
+	AESendMode sendMode;
+	AESendPriority sendPriority;
+	long timeOutInTicks;
+#ifndef AESend
+	PyMac_PRECHECK(AESend);
+#endif
+	if (!PyArg_ParseTuple(_args, "lhl",
+	                      &sendMode,
+	                      &sendPriority,
+	                      &timeOutInTicks))
+		return NULL;
+	_err = AESend(&_self->ob_itself,
+	              &reply,
+	              sendMode,
+	              sendPriority,
+	              timeOutInTicks,
+	              upp_AEIdleProc,
+	              (AEFilterUPP)0);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     AEDesc_New, &reply);
+	return _res;
+}
+
+static PyObject *AEDesc_AEResetTimer(AEDescObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+#ifndef AEResetTimer
+	PyMac_PRECHECK(AEResetTimer);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = AEResetTimer(&_self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *AEDesc_AESuspendTheCurrentEvent(AEDescObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+#ifndef AESuspendTheCurrentEvent
+	PyMac_PRECHECK(AESuspendTheCurrentEvent);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = AESuspendTheCurrentEvent(&_self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *AEDesc_AEResumeTheCurrentEvent(AEDescObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	AppleEvent reply;
+	AEEventHandlerUPP dispatcher__proc__ = upp_GenericEventHandler;
+	PyObject *dispatcher;
+#ifndef AEResumeTheCurrentEvent
+	PyMac_PRECHECK(AEResumeTheCurrentEvent);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O",
+	                      AEDesc_Convert, &reply,
+	                      &dispatcher))
+		return NULL;
+	_err = AEResumeTheCurrentEvent(&_self->ob_itself,
+	                               &reply,
+	                               dispatcher__proc__, (long)dispatcher);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	Py_INCREF(dispatcher); /* XXX leak, but needed */
+	return _res;
+}
+
+static PyObject *AEDesc_AEGetTheCurrentEvent(AEDescObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+#ifndef AEGetTheCurrentEvent
+	PyMac_PRECHECK(AEGetTheCurrentEvent);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = AEGetTheCurrentEvent(&_self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *AEDesc_AESetTheCurrentEvent(AEDescObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+#ifndef AESetTheCurrentEvent
+	PyMac_PRECHECK(AESetTheCurrentEvent);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = AESetTheCurrentEvent(&_self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *AEDesc_AEResolve(AEDescObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short callbackFlags;
+	AEDesc theToken;
+#ifndef AEResolve
+	PyMac_PRECHECK(AEResolve);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &callbackFlags))
+		return NULL;
+	_err = AEResolve(&_self->ob_itself,
+	                 callbackFlags,
+	                 &theToken);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     AEDesc_New, &theToken);
+	return _res;
+}
+
+static PyObject *AEDesc_AutoDispose(AEDescObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+
+	int onoff, old;
+	if (!PyArg_ParseTuple(_args, "i", &onoff))
+	        return NULL;
+	old = _self->ob_owned;
+	_self->ob_owned = onoff;
+	_res = Py_BuildValue("i", old);
+	return _res;
+
+}
+
+static PyMethodDef AEDesc_methods[] = {
+	{"AECoerceDesc", (PyCFunction)AEDesc_AECoerceDesc, 1,
+	 PyDoc_STR("(DescType toType) -> (AEDesc result)")},
+	{"AEDuplicateDesc", (PyCFunction)AEDesc_AEDuplicateDesc, 1,
+	 PyDoc_STR("() -> (AEDesc result)")},
+	{"AECountItems", (PyCFunction)AEDesc_AECountItems, 1,
+	 PyDoc_STR("() -> (long theCount)")},
+	{"AEPutPtr", (PyCFunction)AEDesc_AEPutPtr, 1,
+	 PyDoc_STR("(long index, DescType typeCode, Buffer dataPtr) -> None")},
+	{"AEPutDesc", (PyCFunction)AEDesc_AEPutDesc, 1,
+	 PyDoc_STR("(long index, AEDesc theAEDesc) -> None")},
+	{"AEGetNthPtr", (PyCFunction)AEDesc_AEGetNthPtr, 1,
+	 PyDoc_STR("(long index, DescType desiredType, Buffer dataPtr) -> (AEKeyword theAEKeyword, DescType typeCode, Buffer dataPtr)")},
+	{"AEGetNthDesc", (PyCFunction)AEDesc_AEGetNthDesc, 1,
+	 PyDoc_STR("(long index, DescType desiredType) -> (AEKeyword theAEKeyword, AEDesc result)")},
+	{"AESizeOfNthItem", (PyCFunction)AEDesc_AESizeOfNthItem, 1,
+	 PyDoc_STR("(long index) -> (DescType typeCode, Size dataSize)")},
+	{"AEDeleteItem", (PyCFunction)AEDesc_AEDeleteItem, 1,
+	 PyDoc_STR("(long index) -> None")},
+	{"AEPutParamPtr", (PyCFunction)AEDesc_AEPutParamPtr, 1,
+	 PyDoc_STR("(AEKeyword theAEKeyword, DescType typeCode, Buffer dataPtr) -> None")},
+	{"AEPutParamDesc", (PyCFunction)AEDesc_AEPutParamDesc, 1,
+	 PyDoc_STR("(AEKeyword theAEKeyword, AEDesc theAEDesc) -> None")},
+	{"AEGetParamPtr", (PyCFunction)AEDesc_AEGetParamPtr, 1,
+	 PyDoc_STR("(AEKeyword theAEKeyword, DescType desiredType, Buffer dataPtr) -> (DescType typeCode, Buffer dataPtr)")},
+	{"AEGetParamDesc", (PyCFunction)AEDesc_AEGetParamDesc, 1,
+	 PyDoc_STR("(AEKeyword theAEKeyword, DescType desiredType) -> (AEDesc result)")},
+	{"AESizeOfParam", (PyCFunction)AEDesc_AESizeOfParam, 1,
+	 PyDoc_STR("(AEKeyword theAEKeyword) -> (DescType typeCode, Size dataSize)")},
+	{"AEDeleteParam", (PyCFunction)AEDesc_AEDeleteParam, 1,
+	 PyDoc_STR("(AEKeyword theAEKeyword) -> None")},
+	{"AEGetAttributePtr", (PyCFunction)AEDesc_AEGetAttributePtr, 1,
+	 PyDoc_STR("(AEKeyword theAEKeyword, DescType desiredType, Buffer dataPtr) -> (DescType typeCode, Buffer dataPtr)")},
+	{"AEGetAttributeDesc", (PyCFunction)AEDesc_AEGetAttributeDesc, 1,
+	 PyDoc_STR("(AEKeyword theAEKeyword, DescType desiredType) -> (AEDesc result)")},
+	{"AESizeOfAttribute", (PyCFunction)AEDesc_AESizeOfAttribute, 1,
+	 PyDoc_STR("(AEKeyword theAEKeyword) -> (DescType typeCode, Size dataSize)")},
+	{"AEPutAttributePtr", (PyCFunction)AEDesc_AEPutAttributePtr, 1,
+	 PyDoc_STR("(AEKeyword theAEKeyword, DescType typeCode, Buffer dataPtr) -> None")},
+	{"AEPutAttributeDesc", (PyCFunction)AEDesc_AEPutAttributeDesc, 1,
+	 PyDoc_STR("(AEKeyword theAEKeyword, AEDesc theAEDesc) -> None")},
+	{"AEGetDescDataSize", (PyCFunction)AEDesc_AEGetDescDataSize, 1,
+	 PyDoc_STR("() -> (Size _rv)")},
+	{"AESend", (PyCFunction)AEDesc_AESend, 1,
+	 PyDoc_STR("(AESendMode sendMode, AESendPriority sendPriority, long timeOutInTicks) -> (AppleEvent reply)")},
+	{"AEResetTimer", (PyCFunction)AEDesc_AEResetTimer, 1,
+	 PyDoc_STR("() -> None")},
+	{"AESuspendTheCurrentEvent", (PyCFunction)AEDesc_AESuspendTheCurrentEvent, 1,
+	 PyDoc_STR("() -> None")},
+	{"AEResumeTheCurrentEvent", (PyCFunction)AEDesc_AEResumeTheCurrentEvent, 1,
+	 PyDoc_STR("(AppleEvent reply, EventHandler dispatcher) -> None")},
+	{"AEGetTheCurrentEvent", (PyCFunction)AEDesc_AEGetTheCurrentEvent, 1,
+	 PyDoc_STR("() -> None")},
+	{"AESetTheCurrentEvent", (PyCFunction)AEDesc_AESetTheCurrentEvent, 1,
+	 PyDoc_STR("() -> None")},
+	{"AEResolve", (PyCFunction)AEDesc_AEResolve, 1,
+	 PyDoc_STR("(short callbackFlags) -> (AEDesc theToken)")},
+	{"AutoDispose", (PyCFunction)AEDesc_AutoDispose, 1,
+	 PyDoc_STR("(int)->int. Automatically AEDisposeDesc the object on Python object cleanup")},
+	{NULL, NULL, 0}
+};
+
+static PyObject *AEDesc_get_type(AEDescObject *self, void *closure)
+{
+	return PyMac_BuildOSType(self->ob_itself.descriptorType);
+}
+
+#define AEDesc_set_type NULL
+
+static PyObject *AEDesc_get_data(AEDescObject *self, void *closure)
+{
+	PyObject *res;
+	Size size;
+	char *ptr;
+	OSErr err;
+
+	size = AEGetDescDataSize(&self->ob_itself);
+	if ( (res = PyString_FromStringAndSize(NULL, size)) == NULL )
+		return NULL;
+	if ( (ptr = PyString_AsString(res)) == NULL )
+		return NULL;
+	if ( (err=AEGetDescData(&self->ob_itself, ptr, size)) < 0 )
+		return PyMac_Error(err);
+	return res;
+}
+
+#define AEDesc_set_data NULL
+
+static PyGetSetDef AEDesc_getsetlist[] = {
+	{"type", (getter)AEDesc_get_type, (setter)AEDesc_set_type, "Type of this AEDesc"},
+	{"data", (getter)AEDesc_get_data, (setter)AEDesc_set_data, "The raw data in this AEDesc"},
+	{NULL, NULL, NULL, NULL},
+};
+
+
+#define AEDesc_compare NULL
+
+#define AEDesc_repr NULL
+
+#define AEDesc_hash NULL
+#define AEDesc_tp_init 0
+
+#define AEDesc_tp_alloc PyType_GenericAlloc
+
+static PyObject *AEDesc_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *_self;
+	AEDesc itself;
+	char *kw[] = {"itself", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, AEDesc_Convert, &itself)) return NULL;
+	if ((_self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	((AEDescObject *)_self)->ob_itself = itself;
+	return _self;
+}
+
+#define AEDesc_tp_free PyObject_Del
+
+
+PyTypeObject AEDesc_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"_AE.AEDesc", /*tp_name*/
+	sizeof(AEDescObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) AEDesc_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) AEDesc_compare, /*tp_compare*/
+	(reprfunc) AEDesc_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) AEDesc_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	AEDesc_methods, /* tp_methods */
+	0, /*tp_members*/
+	AEDesc_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	AEDesc_tp_init, /* tp_init */
+	AEDesc_tp_alloc, /* tp_alloc */
+	AEDesc_tp_new, /* tp_new */
+	AEDesc_tp_free, /* tp_free */
+};
+
+/* --------------------- End object type AEDesc --------------------- */
+
+
+static PyObject *AE_AECoercePtr(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	DescType typeCode;
+	char *dataPtr__in__;
+	long dataPtr__len__;
+	int dataPtr__in_len__;
+	DescType toType;
+	AEDesc result;
+#ifndef AECoercePtr
+	PyMac_PRECHECK(AECoercePtr);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&s#O&",
+	                      PyMac_GetOSType, &typeCode,
+	                      &dataPtr__in__, &dataPtr__in_len__,
+	                      PyMac_GetOSType, &toType))
+		return NULL;
+	dataPtr__len__ = dataPtr__in_len__;
+	_err = AECoercePtr(typeCode,
+	                   dataPtr__in__, dataPtr__len__,
+	                   toType,
+	                   &result);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     AEDesc_New, &result);
+	return _res;
+}
+
+static PyObject *AE_AECreateDesc(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	DescType typeCode;
+	char *dataPtr__in__;
+	long dataPtr__len__;
+	int dataPtr__in_len__;
+	AEDesc result;
+#ifndef AECreateDesc
+	PyMac_PRECHECK(AECreateDesc);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&s#",
+	                      PyMac_GetOSType, &typeCode,
+	                      &dataPtr__in__, &dataPtr__in_len__))
+		return NULL;
+	dataPtr__len__ = dataPtr__in_len__;
+	_err = AECreateDesc(typeCode,
+	                    dataPtr__in__, dataPtr__len__,
+	                    &result);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     AEDesc_New, &result);
+	return _res;
+}
+
+static PyObject *AE_AECreateList(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	char *factoringPtr__in__;
+	long factoringPtr__len__;
+	int factoringPtr__in_len__;
+	Boolean isRecord;
+	AEDescList resultList;
+#ifndef AECreateList
+	PyMac_PRECHECK(AECreateList);
+#endif
+	if (!PyArg_ParseTuple(_args, "s#b",
+	                      &factoringPtr__in__, &factoringPtr__in_len__,
+	                      &isRecord))
+		return NULL;
+	factoringPtr__len__ = factoringPtr__in_len__;
+	_err = AECreateList(factoringPtr__in__, factoringPtr__len__,
+	                    isRecord,
+	                    &resultList);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     AEDesc_New, &resultList);
+	return _res;
+}
+
+static PyObject *AE_AECreateAppleEvent(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	AEEventClass theAEEventClass;
+	AEEventID theAEEventID;
+	AEAddressDesc target;
+	AEReturnID returnID;
+	AETransactionID transactionID;
+	AppleEvent result;
+#ifndef AECreateAppleEvent
+	PyMac_PRECHECK(AECreateAppleEvent);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&hl",
+	                      PyMac_GetOSType, &theAEEventClass,
+	                      PyMac_GetOSType, &theAEEventID,
+	                      AEDesc_Convert, &target,
+	                      &returnID,
+	                      &transactionID))
+		return NULL;
+	_err = AECreateAppleEvent(theAEEventClass,
+	                          theAEEventID,
+	                          &target,
+	                          returnID,
+	                          transactionID,
+	                          &result);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     AEDesc_New, &result);
+	return _res;
+}
+
+static PyObject *AE_AEReplaceDescData(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	DescType typeCode;
+	char *dataPtr__in__;
+	long dataPtr__len__;
+	int dataPtr__in_len__;
+	AEDesc theAEDesc;
+#ifndef AEReplaceDescData
+	PyMac_PRECHECK(AEReplaceDescData);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&s#",
+	                      PyMac_GetOSType, &typeCode,
+	                      &dataPtr__in__, &dataPtr__in_len__))
+		return NULL;
+	dataPtr__len__ = dataPtr__in_len__;
+	_err = AEReplaceDescData(typeCode,
+	                         dataPtr__in__, dataPtr__len__,
+	                         &theAEDesc);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     AEDesc_New, &theAEDesc);
+	return _res;
+}
+
+static PyObject *AE_AEProcessAppleEvent(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	EventRecord theEventRecord;
+#ifndef AEProcessAppleEvent
+	PyMac_PRECHECK(AEProcessAppleEvent);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetEventRecord, &theEventRecord))
+		return NULL;
+	_err = AEProcessAppleEvent(&theEventRecord);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *AE_AEGetInteractionAllowed(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	AEInteractAllowed level;
+#ifndef AEGetInteractionAllowed
+	PyMac_PRECHECK(AEGetInteractionAllowed);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = AEGetInteractionAllowed(&level);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("b",
+	                     level);
+	return _res;
+}
+
+static PyObject *AE_AESetInteractionAllowed(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	AEInteractAllowed level;
+#ifndef AESetInteractionAllowed
+	PyMac_PRECHECK(AESetInteractionAllowed);
+#endif
+	if (!PyArg_ParseTuple(_args, "b",
+	                      &level))
+		return NULL;
+	_err = AESetInteractionAllowed(level);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *AE_AEInteractWithUser(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	long timeOutInTicks;
+#ifndef AEInteractWithUser
+	PyMac_PRECHECK(AEInteractWithUser);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &timeOutInTicks))
+		return NULL;
+	_err = AEInteractWithUser(timeOutInTicks,
+	                          (NMRecPtr)0,
+	                          upp_AEIdleProc);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *AE_AEInstallEventHandler(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	AEEventClass theAEEventClass;
+	AEEventID theAEEventID;
+	AEEventHandlerUPP handler__proc__ = upp_GenericEventHandler;
+	PyObject *handler;
+#ifndef AEInstallEventHandler
+	PyMac_PRECHECK(AEInstallEventHandler);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O",
+	                      PyMac_GetOSType, &theAEEventClass,
+	                      PyMac_GetOSType, &theAEEventID,
+	                      &handler))
+		return NULL;
+	_err = AEInstallEventHandler(theAEEventClass,
+	                             theAEEventID,
+	                             handler__proc__, (long)handler,
+	                             0);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	Py_INCREF(handler); /* XXX leak, but needed */
+	return _res;
+}
+
+static PyObject *AE_AERemoveEventHandler(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	AEEventClass theAEEventClass;
+	AEEventID theAEEventID;
+#ifndef AERemoveEventHandler
+	PyMac_PRECHECK(AERemoveEventHandler);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetOSType, &theAEEventClass,
+	                      PyMac_GetOSType, &theAEEventID))
+		return NULL;
+	_err = AERemoveEventHandler(theAEEventClass,
+	                            theAEEventID,
+	                            upp_GenericEventHandler,
+	                            0);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *AE_AEGetEventHandler(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	AEEventClass theAEEventClass;
+	AEEventID theAEEventID;
+	AEEventHandlerUPP handler__proc__ = upp_GenericEventHandler;
+	PyObject *handler;
+#ifndef AEGetEventHandler
+	PyMac_PRECHECK(AEGetEventHandler);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetOSType, &theAEEventClass,
+	                      PyMac_GetOSType, &theAEEventID))
+		return NULL;
+	_err = AEGetEventHandler(theAEEventClass,
+	                         theAEEventID,
+	                         &handler__proc__, (long *)&handler,
+	                         0);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O",
+	                     handler);
+	Py_INCREF(handler); /* XXX leak, but needed */
+	return _res;
+}
+
+static PyObject *AE_AEInstallSpecialHandler(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	AEKeyword functionClass;
+#ifndef AEInstallSpecialHandler
+	PyMac_PRECHECK(AEInstallSpecialHandler);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetOSType, &functionClass))
+		return NULL;
+	_err = AEInstallSpecialHandler(functionClass,
+	                               upp_GenericEventHandler,
+	                               0);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *AE_AERemoveSpecialHandler(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	AEKeyword functionClass;
+#ifndef AERemoveSpecialHandler
+	PyMac_PRECHECK(AERemoveSpecialHandler);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetOSType, &functionClass))
+		return NULL;
+	_err = AERemoveSpecialHandler(functionClass,
+	                              upp_GenericEventHandler,
+	                              0);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *AE_AEManagerInfo(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	AEKeyword keyWord;
+	long result;
+#ifndef AEManagerInfo
+	PyMac_PRECHECK(AEManagerInfo);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetOSType, &keyWord))
+		return NULL;
+	_err = AEManagerInfo(keyWord,
+	                     &result);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     result);
+	return _res;
+}
+
+static PyObject *AE_AEObjectInit(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+#ifndef AEObjectInit
+	PyMac_PRECHECK(AEObjectInit);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = AEObjectInit();
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *AE_AEDisposeToken(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	AEDesc theToken;
+#ifndef AEDisposeToken
+	PyMac_PRECHECK(AEDisposeToken);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = AEDisposeToken(&theToken);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     AEDesc_New, &theToken);
+	return _res;
+}
+
+static PyObject *AE_AECallObjectAccessor(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	DescType desiredClass;
+	AEDesc containerToken;
+	DescType containerClass;
+	DescType keyForm;
+	AEDesc keyData;
+	AEDesc token;
+#ifndef AECallObjectAccessor
+	PyMac_PRECHECK(AECallObjectAccessor);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&O&O&",
+	                      PyMac_GetOSType, &desiredClass,
+	                      AEDesc_Convert, &containerToken,
+	                      PyMac_GetOSType, &containerClass,
+	                      PyMac_GetOSType, &keyForm,
+	                      AEDesc_Convert, &keyData))
+		return NULL;
+	_err = AECallObjectAccessor(desiredClass,
+	                            &containerToken,
+	                            containerClass,
+	                            keyForm,
+	                            &keyData,
+	                            &token);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     AEDesc_New, &token);
+	return _res;
+}
+
+static PyMethodDef AE_methods[] = {
+	{"AECoercePtr", (PyCFunction)AE_AECoercePtr, 1,
+	 PyDoc_STR("(DescType typeCode, Buffer dataPtr, DescType toType) -> (AEDesc result)")},
+	{"AECreateDesc", (PyCFunction)AE_AECreateDesc, 1,
+	 PyDoc_STR("(DescType typeCode, Buffer dataPtr) -> (AEDesc result)")},
+	{"AECreateList", (PyCFunction)AE_AECreateList, 1,
+	 PyDoc_STR("(Buffer factoringPtr, Boolean isRecord) -> (AEDescList resultList)")},
+	{"AECreateAppleEvent", (PyCFunction)AE_AECreateAppleEvent, 1,
+	 PyDoc_STR("(AEEventClass theAEEventClass, AEEventID theAEEventID, AEAddressDesc target, AEReturnID returnID, AETransactionID transactionID) -> (AppleEvent result)")},
+	{"AEReplaceDescData", (PyCFunction)AE_AEReplaceDescData, 1,
+	 PyDoc_STR("(DescType typeCode, Buffer dataPtr) -> (AEDesc theAEDesc)")},
+	{"AEProcessAppleEvent", (PyCFunction)AE_AEProcessAppleEvent, 1,
+	 PyDoc_STR("(EventRecord theEventRecord) -> None")},
+	{"AEGetInteractionAllowed", (PyCFunction)AE_AEGetInteractionAllowed, 1,
+	 PyDoc_STR("() -> (AEInteractAllowed level)")},
+	{"AESetInteractionAllowed", (PyCFunction)AE_AESetInteractionAllowed, 1,
+	 PyDoc_STR("(AEInteractAllowed level) -> None")},
+	{"AEInteractWithUser", (PyCFunction)AE_AEInteractWithUser, 1,
+	 PyDoc_STR("(long timeOutInTicks) -> None")},
+	{"AEInstallEventHandler", (PyCFunction)AE_AEInstallEventHandler, 1,
+	 PyDoc_STR("(AEEventClass theAEEventClass, AEEventID theAEEventID, EventHandler handler) -> None")},
+	{"AERemoveEventHandler", (PyCFunction)AE_AERemoveEventHandler, 1,
+	 PyDoc_STR("(AEEventClass theAEEventClass, AEEventID theAEEventID) -> None")},
+	{"AEGetEventHandler", (PyCFunction)AE_AEGetEventHandler, 1,
+	 PyDoc_STR("(AEEventClass theAEEventClass, AEEventID theAEEventID) -> (EventHandler handler)")},
+	{"AEInstallSpecialHandler", (PyCFunction)AE_AEInstallSpecialHandler, 1,
+	 PyDoc_STR("(AEKeyword functionClass) -> None")},
+	{"AERemoveSpecialHandler", (PyCFunction)AE_AERemoveSpecialHandler, 1,
+	 PyDoc_STR("(AEKeyword functionClass) -> None")},
+	{"AEManagerInfo", (PyCFunction)AE_AEManagerInfo, 1,
+	 PyDoc_STR("(AEKeyword keyWord) -> (long result)")},
+	{"AEObjectInit", (PyCFunction)AE_AEObjectInit, 1,
+	 PyDoc_STR("() -> None")},
+	{"AEDisposeToken", (PyCFunction)AE_AEDisposeToken, 1,
+	 PyDoc_STR("() -> (AEDesc theToken)")},
+	{"AECallObjectAccessor", (PyCFunction)AE_AECallObjectAccessor, 1,
+	 PyDoc_STR("(DescType desiredClass, AEDesc containerToken, DescType containerClass, DescType keyForm, AEDesc keyData) -> (AEDesc token)")},
+	{NULL, NULL, 0}
+};
+
+
+
+static pascal OSErr
+GenericEventHandler(const AppleEvent *request, AppleEvent *reply, refcontype refcon)
+{
+        PyObject *handler = (PyObject *)refcon;
+        AEDescObject *requestObject, *replyObject;
+        PyObject *args, *res;
+        if ((requestObject = (AEDescObject *)AEDesc_New((AppleEvent *)request)) == NULL) {
+                return -1;
+        }
+        if ((replyObject = (AEDescObject *)AEDesc_New(reply)) == NULL) {
+                Py_DECREF(requestObject);
+                return -1;
+        }
+        if ((args = Py_BuildValue("OO", requestObject, replyObject)) == NULL) {
+                Py_DECREF(requestObject);
+                Py_DECREF(replyObject);
+                return -1;
+        }
+        res = PyEval_CallObject(handler, args);
+        requestObject->ob_itself.descriptorType = 'null';
+        requestObject->ob_itself.dataHandle = NULL;
+        replyObject->ob_itself.descriptorType = 'null';
+        replyObject->ob_itself.dataHandle = NULL;
+        Py_DECREF(args);
+        if (res == NULL) {
+                PySys_WriteStderr("Exception in AE event handler function\n");
+                PyErr_Print();
+                return -1;
+        }
+        Py_DECREF(res);
+        return noErr;
+}
+
+PyObject *AEDesc_NewBorrowed(AEDesc *itself)
+{
+        PyObject *it;
+
+        it = AEDesc_New(itself);
+        if (it)
+                ((AEDescObject *)it)->ob_owned = 0;
+        return (PyObject *)it;
+}
+
+
+
+void init_AE(void)
+{
+	PyObject *m;
+	PyObject *d;
+
+        upp_AEIdleProc = NewAEIdleUPP(AEIdleProc);
+        upp_GenericEventHandler = NewAEEventHandlerUPP(GenericEventHandler);
+        PyMac_INIT_TOOLBOX_OBJECT_NEW(AEDesc *, AEDesc_New);
+        PyMac_INIT_TOOLBOX_OBJECT_NEW(AEDesc *, AEDesc_NewBorrowed);
+        PyMac_INIT_TOOLBOX_OBJECT_CONVERT(AEDesc, AEDesc_Convert);
+
+	m = Py_InitModule("_AE", AE_methods);
+	d = PyModule_GetDict(m);
+	AE_Error = PyMac_GetOSErrException();
+	if (AE_Error == NULL ||
+	    PyDict_SetItemString(d, "Error", AE_Error) != 0)
+		return;
+	AEDesc_Type.ob_type = &PyType_Type;
+	if (PyType_Ready(&AEDesc_Type) < 0) return;
+	Py_INCREF(&AEDesc_Type);
+	PyModule_AddObject(m, "AEDesc", (PyObject *)&AEDesc_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&AEDesc_Type);
+	PyModule_AddObject(m, "AEDescType", (PyObject *)&AEDesc_Type);
+}
+
+/* ========================= End module _AE ========================= */
+

Added: vendor/Python/current/Mac/Modules/ae/aescan.py
===================================================================
--- vendor/Python/current/Mac/Modules/ae/aescan.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/ae/aescan.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,99 @@
+# Scan AppleEvents.h header file, generate aegen.py and AppleEvents.py files.
+# Then run aesupport to generate AEmodule.c.
+# (Should learn how to tell the compiler to compile it as well.)
+
+import sys
+import os
+import string
+import MacOS
+
+from bgenlocations import TOOLBOXDIR, BGENDIR
+sys.path.append(BGENDIR)
+
+from scantools import Scanner
+
+def main():
+    print "=== Scanning AEDataModel.h, AppleEvents.h, AERegistry.h, AEObjects.h ==="
+    input = ["AEDataModel.h", "AEInteraction.h", "AppleEvents.h", "AERegistry.h", "AEObjects.h"]
+    output = "aegen.py"
+    defsoutput = TOOLBOXDIR + "AppleEvents.py"
+    scanner = AppleEventsScanner(input, output, defsoutput)
+    scanner.scan()
+    scanner.close()
+    print "=== Testing definitions output code ==="
+    execfile(defsoutput, {}, {})
+    print "=== Done Scanning and Generating, now doing 'import aesupport' ==="
+    import aesupport
+    print "=== Done 'import aesupport'.  It's up to you to compile AEmodule.c ==="
+
+class AppleEventsScanner(Scanner):
+
+    def destination(self, type, name, arglist):
+        classname = "AEFunction"
+        listname = "functions"
+        if arglist:
+            t, n, m = arglist[0]
+            if t[-4:] == "_ptr" and m == "InMode" and \
+               t[:-4] in ("AEDesc", "AEAddressDesc", "AEDescList",
+                     "AERecord", "AppleEvent"):
+                classname = "AEMethod"
+                listname = "aedescmethods"
+        return classname, listname
+
+    def makeblacklistnames(self):
+        return [
+                "AEDisposeDesc",
+#                       "AEGetEventHandler",
+                "AEGetDescData", # Use object.data
+                "AEGetSpecialHandler",
+                # Constants with funny definitions
+                "kAEDontDisposeOnResume",
+                "kAEUseStandardDispatch",
+                ]
+
+    def makeblacklisttypes(self):
+        return [
+                "ProcPtr",
+                "AEArrayType",
+                "AECoercionHandlerUPP",
+                "UniversalProcPtr",
+                "OSLCompareUPP",
+                "OSLAccessorUPP",
+                ]
+
+    def makerepairinstructions(self):
+        return [
+                ([("Boolean", "isSysHandler", "InMode")],
+                 [("AlwaysFalse", "*", "*")]),
+
+                ([("void_ptr", "*", "InMode"), ("Size", "*", "InMode")],
+                 [("InBuffer", "*", "*")]),
+
+                ([("EventHandlerProcPtr", "*", "InMode"), ("long", "*", "InMode")],
+                 [("EventHandler", "*", "*")]),
+
+                ([("EventHandlerProcPtr", "*", "OutMode"), ("long", "*", "OutMode")],
+                 [("EventHandler", "*", "*")]),
+
+                ([("AEEventHandlerUPP", "*", "InMode"), ("long", "*", "InMode")],
+                 [("EventHandler", "*", "*")]),
+
+                ([("AEEventHandlerUPP", "*", "OutMode"), ("long", "*", "OutMode")],
+                 [("EventHandler", "*", "*")]),
+
+                ([("void", "*", "OutMode"), ("Size", "*", "InMode"),
+                                            ("Size", "*", "OutMode")],
+                 [("VarVarOutBuffer", "*", "InOutMode")]),
+
+                ([("AppleEvent", "theAppleEvent", "OutMode")],
+                 [("AppleEvent_ptr", "*", "InMode")]),
+
+                ([("AEDescList", "theAEDescList", "OutMode")],
+                 [("AEDescList_ptr", "*", "InMode")]),
+                ]
+
+    def writeinitialdefs(self):
+        self.defsfile.write("def FOUR_CHAR_CODE(x): return x\n")
+
+if __name__ == "__main__":
+    main()

Added: vendor/Python/current/Mac/Modules/ae/aesupport.py
===================================================================
--- vendor/Python/current/Mac/Modules/ae/aesupport.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/ae/aesupport.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,237 @@
+# This script will generate the AppleEvents interface for Python.
+# It uses the "bgen" package to generate C code.
+# It execs the file aegen.py which contain the function definitions
+# (aegen.py was generated by aescan.py, scanning the <AppleEvents.h> header file).
+
+
+from macsupport import *
+
+
+AEArrayType = Type("AEArrayType", "c")
+AESendMode = Type("AESendMode", "l")
+AESendPriority = Type("AESendPriority", "h")
+AEInteractAllowed = Type("AEInteractAllowed", "b")
+AEReturnID = Type("AEReturnID", "h")
+AETransactionID = Type("AETransactionID", "l")
+
+
+
+AEEventClass = OSTypeType('AEEventClass')
+AEEventID = OSTypeType('AEEventID')
+AEKeyword = OSTypeType('AEKeyword')
+DescType = OSTypeType('DescType')
+
+
+AEDesc = OpaqueType('AEDesc')
+AEDesc_ptr = OpaqueType('AEDesc')
+
+AEAddressDesc = OpaqueType('AEAddressDesc', 'AEDesc')
+AEAddressDesc_ptr = OpaqueType('AEAddressDesc', 'AEDesc')
+
+AEDescList = OpaqueType('AEDescList', 'AEDesc')
+AEDescList_ptr = OpaqueType('AEDescList', 'AEDesc')
+
+AERecord = OpaqueType('AERecord', 'AEDesc')
+AERecord_ptr = OpaqueType('AERecord', 'AEDesc')
+
+AppleEvent = OpaqueType('AppleEvent', 'AEDesc')
+AppleEvent_ptr = OpaqueType('AppleEvent', 'AEDesc')
+
+
+class EHType(Type):
+    def __init__(self, name = 'EventHandler', format = ''):
+        Type.__init__(self, name, format)
+    def declare(self, name):
+        Output("AEEventHandlerUPP %s__proc__ = upp_GenericEventHandler;", name)
+        Output("PyObject *%s;", name)
+    def getargsFormat(self):
+        return "O"
+    def getargsArgs(self, name):
+        return "&%s" % name
+    def passInput(self, name):
+        return "%s__proc__, (long)%s" % (name, name)
+    def passOutput(self, name):
+        return "&%s__proc__, (long *)&%s" % (name, name)
+    def mkvalueFormat(self):
+        return "O"
+    def mkvalueArgs(self, name):
+        return name
+    def cleanup(self, name):
+        Output("Py_INCREF(%s); /* XXX leak, but needed */", name)
+
+class EHNoRefConType(EHType):
+    def passInput(self, name):
+        return "upp_GenericEventHandler"
+
+EventHandler = EHType()
+EventHandlerNoRefCon = EHNoRefConType()
+
+
+IdleProcPtr = FakeType("upp_AEIdleProc")
+AEIdleUPP = IdleProcPtr
+EventFilterProcPtr = FakeType("(AEFilterUPP)0")
+AEFilterUPP = EventFilterProcPtr
+NMRecPtr = FakeType("(NMRecPtr)0")
+EventHandlerProcPtr = FakeType("upp_GenericEventHandler")
+AEEventHandlerUPP = EventHandlerProcPtr
+AlwaysFalse = FakeType("0")
+
+
+AEFunction = OSErrWeakLinkFunctionGenerator
+AEMethod = OSErrWeakLinkMethodGenerator
+
+
+includestuff = includestuff + """
+#include <Carbon/Carbon.h>
+
+#ifdef USE_TOOLBOX_OBJECT_GLUE
+extern PyObject *_AEDesc_New(AEDesc *);
+extern int _AEDesc_Convert(PyObject *, AEDesc *);
+
+#define AEDesc_New _AEDesc_New
+#define AEDesc_NewBorrowed _AEDesc_NewBorrowed
+#define AEDesc_Convert _AEDesc_Convert
+#endif
+
+typedef long refcontype;
+
+static pascal OSErr GenericEventHandler(const AppleEvent *request, AppleEvent *reply, refcontype refcon); /* Forward */
+
+AEEventHandlerUPP upp_GenericEventHandler;
+
+static pascal Boolean AEIdleProc(EventRecord *theEvent, long *sleepTime, RgnHandle *mouseRgn)
+{
+        if ( PyOS_InterruptOccurred() )
+                return 1;
+        return 0;
+}
+
+AEIdleUPP upp_AEIdleProc;
+"""
+
+finalstuff = finalstuff + """
+static pascal OSErr
+GenericEventHandler(const AppleEvent *request, AppleEvent *reply, refcontype refcon)
+{
+        PyObject *handler = (PyObject *)refcon;
+        AEDescObject *requestObject, *replyObject;
+        PyObject *args, *res;
+        if ((requestObject = (AEDescObject *)AEDesc_New((AppleEvent *)request)) == NULL) {
+                return -1;
+        }
+        if ((replyObject = (AEDescObject *)AEDesc_New(reply)) == NULL) {
+                Py_DECREF(requestObject);
+                return -1;
+        }
+        if ((args = Py_BuildValue("OO", requestObject, replyObject)) == NULL) {
+                Py_DECREF(requestObject);
+                Py_DECREF(replyObject);
+                return -1;
+        }
+        res = PyEval_CallObject(handler, args);
+        requestObject->ob_itself.descriptorType = 'null';
+        requestObject->ob_itself.dataHandle = NULL;
+        replyObject->ob_itself.descriptorType = 'null';
+        replyObject->ob_itself.dataHandle = NULL;
+        Py_DECREF(args);
+        if (res == NULL) {
+                PySys_WriteStderr("Exception in AE event handler function\\n");
+                PyErr_Print();
+                return -1;
+        }
+        Py_DECREF(res);
+        return noErr;
+}
+
+PyObject *AEDesc_NewBorrowed(AEDesc *itself)
+{
+        PyObject *it;
+
+        it = AEDesc_New(itself);
+        if (it)
+                ((AEDescObject *)it)->ob_owned = 0;
+        return (PyObject *)it;
+}
+
+"""
+
+initstuff = initstuff + """
+        upp_AEIdleProc = NewAEIdleUPP(AEIdleProc);
+        upp_GenericEventHandler = NewAEEventHandlerUPP(GenericEventHandler);
+        PyMac_INIT_TOOLBOX_OBJECT_NEW(AEDesc *, AEDesc_New);
+        PyMac_INIT_TOOLBOX_OBJECT_NEW(AEDesc *, AEDesc_NewBorrowed);
+        PyMac_INIT_TOOLBOX_OBJECT_CONVERT(AEDesc, AEDesc_Convert);
+"""
+
+module = MacModule('_AE', 'AE', includestuff, finalstuff, initstuff)
+
+class AEDescDefinition(PEP253Mixin, GlobalObjectDefinition):
+    getsetlist = [(
+            'type',
+            'return PyMac_BuildOSType(self->ob_itself.descriptorType);',
+            None,
+            'Type of this AEDesc'
+            ), (
+            'data',
+            """
+            PyObject *res;
+            Size size;
+            char *ptr;
+            OSErr err;
+
+            size = AEGetDescDataSize(&self->ob_itself);
+            if ( (res = PyString_FromStringAndSize(NULL, size)) == NULL )
+                    return NULL;
+            if ( (ptr = PyString_AsString(res)) == NULL )
+                    return NULL;
+            if ( (err=AEGetDescData(&self->ob_itself, ptr, size)) < 0 )
+                    return PyMac_Error(err);
+            return res;
+            """,
+            None,
+            'The raw data in this AEDesc'
+            )]
+
+    def __init__(self, name, prefix = None, itselftype = None):
+        GlobalObjectDefinition.__init__(self, name, prefix or name, itselftype or name)
+        self.argref = "*"
+
+    def outputStructMembers(self):
+        GlobalObjectDefinition.outputStructMembers(self)
+        Output("int ob_owned;")
+
+    def outputInitStructMembers(self):
+        GlobalObjectDefinition.outputInitStructMembers(self)
+        Output("it->ob_owned = 1;")
+
+    def outputCleanupStructMembers(self):
+        Output("if (self->ob_owned) AEDisposeDesc(&self->ob_itself);")
+
+aedescobject = AEDescDefinition('AEDesc')
+module.addobject(aedescobject)
+
+functions = []
+aedescmethods = []
+
+execfile('aegen.py')
+##execfile('aedatamodelgen.py')
+
+# Manual generator
+AutoDispose_body = """
+int onoff, old;
+if (!PyArg_ParseTuple(_args, "i", &onoff))
+        return NULL;
+old = _self->ob_owned;
+_self->ob_owned = onoff;
+_res = Py_BuildValue("i", old);
+return _res;
+"""
+f = ManualGenerator("AutoDispose", AutoDispose_body)
+f.docstring = lambda: "(int)->int. Automatically AEDisposeDesc the object on Python object cleanup"
+aedescmethods.append(f)
+
+for f in functions: module.add(f)
+for f in aedescmethods: aedescobject.add(f)
+
+SetOutputFileName('_AEmodule.c')
+module.generate()

Added: vendor/Python/current/Mac/Modules/ah/_AHmodule.c
===================================================================
--- vendor/Python/current/Mac/Modules/ah/_AHmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/ah/_AHmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,144 @@
+
+/* =========================== Module _AH =========================== */
+
+#include "Python.h"
+
+
+
+#include "pymactoolbox.h"
+
+/* Macro to test whether a weak-loaded CFM function exists */
+#define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL )  {\
+        PyErr_SetString(PyExc_NotImplementedError, \
+        "Not available in this shared library/OS version"); \
+        return NULL; \
+    }} while(0)
+
+
+#include <Carbon/Carbon.h>
+
+
+static PyObject *Ah_Error;
+
+static PyObject *Ah_AHSearch(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	CFStringRef bookname;
+	CFStringRef query;
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CFStringRefObj_Convert, &bookname,
+	                      CFStringRefObj_Convert, &query))
+		return NULL;
+	_err = AHSearch(bookname,
+	                query);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Ah_AHGotoMainTOC(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	AHTOCType toctype;
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &toctype))
+		return NULL;
+	_err = AHGotoMainTOC(toctype);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Ah_AHGotoPage(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	CFStringRef bookname;
+	CFStringRef path;
+	CFStringRef anchor;
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      CFStringRefObj_Convert, &bookname,
+	                      CFStringRefObj_Convert, &path,
+	                      CFStringRefObj_Convert, &anchor))
+		return NULL;
+	_err = AHGotoPage(bookname,
+	                  path,
+	                  anchor);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Ah_AHLookupAnchor(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	CFStringRef bookname;
+	CFStringRef anchor;
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CFStringRefObj_Convert, &bookname,
+	                      CFStringRefObj_Convert, &anchor))
+		return NULL;
+	_err = AHLookupAnchor(bookname,
+	                      anchor);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Ah_AHRegisterHelpBook(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	FSRef appBundleRef;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetFSRef, &appBundleRef))
+		return NULL;
+	_err = AHRegisterHelpBook(&appBundleRef);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyMethodDef Ah_methods[] = {
+	{"AHSearch", (PyCFunction)Ah_AHSearch, 1,
+	 PyDoc_STR("(CFStringRef bookname, CFStringRef query) -> None")},
+	{"AHGotoMainTOC", (PyCFunction)Ah_AHGotoMainTOC, 1,
+	 PyDoc_STR("(AHTOCType toctype) -> None")},
+	{"AHGotoPage", (PyCFunction)Ah_AHGotoPage, 1,
+	 PyDoc_STR("(CFStringRef bookname, CFStringRef path, CFStringRef anchor) -> None")},
+	{"AHLookupAnchor", (PyCFunction)Ah_AHLookupAnchor, 1,
+	 PyDoc_STR("(CFStringRef bookname, CFStringRef anchor) -> None")},
+	{"AHRegisterHelpBook", (PyCFunction)Ah_AHRegisterHelpBook, 1,
+	 PyDoc_STR("(FSRef appBundleRef) -> None")},
+	{NULL, NULL, 0}
+};
+
+
+
+
+void init_AH(void)
+{
+	PyObject *m;
+	PyObject *d;
+
+
+
+
+	m = Py_InitModule("_AH", Ah_methods);
+	d = PyModule_GetDict(m);
+	Ah_Error = PyMac_GetOSErrException();
+	if (Ah_Error == NULL ||
+	    PyDict_SetItemString(d, "Error", Ah_Error) != 0)
+		return;
+}
+
+/* ========================= End module _AH ========================= */
+

Added: vendor/Python/current/Mac/Modules/ah/ahscan.py
===================================================================
--- vendor/Python/current/Mac/Modules/ah/ahscan.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/ah/ahscan.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,52 @@
+# Scan an Apple header file, generating a Python file of generator calls.
+
+import sys
+import os
+from bgenlocations import TOOLBOXDIR, BGENDIR
+sys.path.append(BGENDIR)
+from scantools import Scanner_OSX
+
+LONG = "AppleHelp"
+SHORT = "ah"
+OBJECT = "NOTUSED"
+
+def main():
+    input = LONG + ".h"
+    output = SHORT + "gen.py"
+    defsoutput = TOOLBOXDIR + LONG + ".py"
+    scanner = MyScanner(input, output, defsoutput)
+    scanner.scan()
+    scanner.close()
+    print "=== Testing definitions output code ==="
+    execfile(defsoutput, {}, {})
+    print "=== Done scanning and generating, now importing the generated code... ==="
+    exec "import " + SHORT + "support"
+    print "=== Done.  It's up to you to compile it now! ==="
+
+class MyScanner(Scanner_OSX):
+
+    def destination(self, type, name, arglist):
+        classname = "Function"
+        listname = "functions"
+        if arglist:
+            t, n, m = arglist[0]
+            # This is non-functional today
+            if t == OBJECT and m == "InMode":
+                classname = "Method"
+                listname = "methods"
+        return classname, listname
+
+    def makeblacklistnames(self):
+        return [
+                ]
+
+    def makeblacklisttypes(self):
+        return [
+                ]
+
+    def makerepairinstructions(self):
+        return [
+                ]
+
+if __name__ == "__main__":
+    main()

Added: vendor/Python/current/Mac/Modules/ah/ahsupport.py
===================================================================
--- vendor/Python/current/Mac/Modules/ah/ahsupport.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/ah/ahsupport.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,45 @@
+# This script generates a Python interface for an Apple Macintosh Manager.
+# It uses the "bgen" package to generate C code.
+# The function specifications are generated by scanning the mamager's header file,
+# using the "scantools" package (customized for this particular manager).
+
+import string
+
+# Declarations that change for each manager
+MACHEADERFILE = 'AppleHelp.h'           # The Apple header file
+MODNAME = '_AH'                         # The name of the module
+
+# The following is *usually* unchanged but may still require tuning
+MODPREFIX = 'Ah'                        # The prefix for module-wide routines
+INPUTFILE = string.lower(MODPREFIX) + 'gen.py' # The file generated by the scanner
+OUTPUTFILE = MODNAME + "module.c"       # The file generated by this program
+
+from macsupport import *
+
+# Create the type objects
+AHTOCType = Type("AHTOCType", "h")
+
+includestuff = includestuff + """
+#include <Carbon/Carbon.h>
+
+"""
+
+# From here on it's basically all boiler plate...
+
+# Create the generator groups and link them
+module = MacModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff)
+
+# Create the generator classes used to populate the lists
+Function = OSErrFunctionGenerator
+
+# Create and populate the lists
+functions = []
+execfile(INPUTFILE)
+
+# add the populated lists to the generator groups
+# (in a different wordl the scan program would generate this)
+for f in functions: module.add(f)
+
+# generate output (open the output file as late as possible)
+SetOutputFileName(OUTPUTFILE)
+module.generate()

Added: vendor/Python/current/Mac/Modules/app/_Appmodule.c
===================================================================
--- vendor/Python/current/Mac/Modules/app/_Appmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/app/_Appmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1821 @@
+
+/* ========================== Module _App =========================== */
+
+#include "Python.h"
+
+
+
+#include "pymactoolbox.h"
+
+/* Macro to test whether a weak-loaded CFM function exists */
+#define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL )  {\
+        PyErr_SetString(PyExc_NotImplementedError, \
+        "Not available in this shared library/OS version"); \
+        return NULL; \
+    }} while(0)
+
+
+#include <Carbon/Carbon.h>
+
+
+int ThemeButtonDrawInfo_Convert(PyObject *v, ThemeButtonDrawInfo *p_itself)
+{
+        return PyArg_Parse(v, "(iHH)", &p_itself->state, &p_itself->value, &p_itself->adornment);
+}
+
+
+static PyObject *App_Error;
+
+/* ----------------- Object type ThemeDrawingState ------------------ */
+
+PyTypeObject ThemeDrawingState_Type;
+
+#define ThemeDrawingStateObj_Check(x) ((x)->ob_type == &ThemeDrawingState_Type || PyObject_TypeCheck((x), &ThemeDrawingState_Type))
+
+typedef struct ThemeDrawingStateObject {
+	PyObject_HEAD
+	ThemeDrawingState ob_itself;
+} ThemeDrawingStateObject;
+
+PyObject *ThemeDrawingStateObj_New(ThemeDrawingState itself)
+{
+	ThemeDrawingStateObject *it;
+	it = PyObject_NEW(ThemeDrawingStateObject, &ThemeDrawingState_Type);
+	if (it == NULL) return NULL;
+	it->ob_itself = itself;
+	return (PyObject *)it;
+}
+
+int ThemeDrawingStateObj_Convert(PyObject *v, ThemeDrawingState *p_itself)
+{
+	if (!ThemeDrawingStateObj_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "ThemeDrawingState required");
+		return 0;
+	}
+	*p_itself = ((ThemeDrawingStateObject *)v)->ob_itself;
+	return 1;
+}
+
+static void ThemeDrawingStateObj_dealloc(ThemeDrawingStateObject *self)
+{
+	/* Cleanup of self->ob_itself goes here */
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *ThemeDrawingStateObj_SetThemeDrawingState(ThemeDrawingStateObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _rv;
+	Boolean inDisposeNow;
+#ifndef SetThemeDrawingState
+	PyMac_PRECHECK(SetThemeDrawingState);
+#endif
+	if (!PyArg_ParseTuple(_args, "b",
+	                      &inDisposeNow))
+		return NULL;
+	_rv = SetThemeDrawingState(_self->ob_itself,
+	                           inDisposeNow);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *ThemeDrawingStateObj_DisposeThemeDrawingState(ThemeDrawingStateObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _rv;
+#ifndef DisposeThemeDrawingState
+	PyMac_PRECHECK(DisposeThemeDrawingState);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = DisposeThemeDrawingState(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyMethodDef ThemeDrawingStateObj_methods[] = {
+	{"SetThemeDrawingState", (PyCFunction)ThemeDrawingStateObj_SetThemeDrawingState, 1,
+	 PyDoc_STR("(Boolean inDisposeNow) -> (OSStatus _rv)")},
+	{"DisposeThemeDrawingState", (PyCFunction)ThemeDrawingStateObj_DisposeThemeDrawingState, 1,
+	 PyDoc_STR("() -> (OSStatus _rv)")},
+	{NULL, NULL, 0}
+};
+
+#define ThemeDrawingStateObj_getsetlist NULL
+
+
+#define ThemeDrawingStateObj_compare NULL
+
+#define ThemeDrawingStateObj_repr NULL
+
+#define ThemeDrawingStateObj_hash NULL
+#define ThemeDrawingStateObj_tp_init 0
+
+#define ThemeDrawingStateObj_tp_alloc PyType_GenericAlloc
+
+static PyObject *ThemeDrawingStateObj_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *_self;
+	ThemeDrawingState itself;
+	char *kw[] = {"itself", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, ThemeDrawingStateObj_Convert, &itself)) return NULL;
+	if ((_self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	((ThemeDrawingStateObject *)_self)->ob_itself = itself;
+	return _self;
+}
+
+#define ThemeDrawingStateObj_tp_free PyObject_Del
+
+
+PyTypeObject ThemeDrawingState_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"_App.ThemeDrawingState", /*tp_name*/
+	sizeof(ThemeDrawingStateObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) ThemeDrawingStateObj_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) ThemeDrawingStateObj_compare, /*tp_compare*/
+	(reprfunc) ThemeDrawingStateObj_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) ThemeDrawingStateObj_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	ThemeDrawingStateObj_methods, /* tp_methods */
+	0, /*tp_members*/
+	ThemeDrawingStateObj_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	ThemeDrawingStateObj_tp_init, /* tp_init */
+	ThemeDrawingStateObj_tp_alloc, /* tp_alloc */
+	ThemeDrawingStateObj_tp_new, /* tp_new */
+	ThemeDrawingStateObj_tp_free, /* tp_free */
+};
+
+/* --------------- End object type ThemeDrawingState ---------------- */
+
+
+static PyObject *App_RegisterAppearanceClient(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+#ifndef RegisterAppearanceClient
+	PyMac_PRECHECK(RegisterAppearanceClient);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = RegisterAppearanceClient();
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *App_UnregisterAppearanceClient(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+#ifndef UnregisterAppearanceClient
+	PyMac_PRECHECK(UnregisterAppearanceClient);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = UnregisterAppearanceClient();
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *App_SetThemePen(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	ThemeBrush inBrush;
+	SInt16 inDepth;
+	Boolean inIsColorDevice;
+#ifndef SetThemePen
+	PyMac_PRECHECK(SetThemePen);
+#endif
+	if (!PyArg_ParseTuple(_args, "hhb",
+	                      &inBrush,
+	                      &inDepth,
+	                      &inIsColorDevice))
+		return NULL;
+	_err = SetThemePen(inBrush,
+	                   inDepth,
+	                   inIsColorDevice);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *App_SetThemeBackground(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	ThemeBrush inBrush;
+	SInt16 inDepth;
+	Boolean inIsColorDevice;
+#ifndef SetThemeBackground
+	PyMac_PRECHECK(SetThemeBackground);
+#endif
+	if (!PyArg_ParseTuple(_args, "hhb",
+	                      &inBrush,
+	                      &inDepth,
+	                      &inIsColorDevice))
+		return NULL;
+	_err = SetThemeBackground(inBrush,
+	                          inDepth,
+	                          inIsColorDevice);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *App_SetThemeTextColor(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	ThemeTextColor inColor;
+	SInt16 inDepth;
+	Boolean inIsColorDevice;
+#ifndef SetThemeTextColor
+	PyMac_PRECHECK(SetThemeTextColor);
+#endif
+	if (!PyArg_ParseTuple(_args, "hhb",
+	                      &inColor,
+	                      &inDepth,
+	                      &inIsColorDevice))
+		return NULL;
+	_err = SetThemeTextColor(inColor,
+	                         inDepth,
+	                         inIsColorDevice);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *App_SetThemeWindowBackground(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr inWindow;
+	ThemeBrush inBrush;
+	Boolean inUpdate;
+#ifndef SetThemeWindowBackground
+	PyMac_PRECHECK(SetThemeWindowBackground);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hb",
+	                      WinObj_Convert, &inWindow,
+	                      &inBrush,
+	                      &inUpdate))
+		return NULL;
+	_err = SetThemeWindowBackground(inWindow,
+	                                inBrush,
+	                                inUpdate);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *App_DrawThemeWindowHeader(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Rect inRect;
+	ThemeDrawState inState;
+#ifndef DrawThemeWindowHeader
+	PyMac_PRECHECK(DrawThemeWindowHeader);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      PyMac_GetRect, &inRect,
+	                      &inState))
+		return NULL;
+	_err = DrawThemeWindowHeader(&inRect,
+	                             inState);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *App_DrawThemeWindowListViewHeader(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Rect inRect;
+	ThemeDrawState inState;
+#ifndef DrawThemeWindowListViewHeader
+	PyMac_PRECHECK(DrawThemeWindowListViewHeader);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      PyMac_GetRect, &inRect,
+	                      &inState))
+		return NULL;
+	_err = DrawThemeWindowListViewHeader(&inRect,
+	                                     inState);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *App_DrawThemePlacard(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Rect inRect;
+	ThemeDrawState inState;
+#ifndef DrawThemePlacard
+	PyMac_PRECHECK(DrawThemePlacard);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      PyMac_GetRect, &inRect,
+	                      &inState))
+		return NULL;
+	_err = DrawThemePlacard(&inRect,
+	                        inState);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *App_DrawThemeEditTextFrame(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Rect inRect;
+	ThemeDrawState inState;
+#ifndef DrawThemeEditTextFrame
+	PyMac_PRECHECK(DrawThemeEditTextFrame);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      PyMac_GetRect, &inRect,
+	                      &inState))
+		return NULL;
+	_err = DrawThemeEditTextFrame(&inRect,
+	                              inState);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *App_DrawThemeListBoxFrame(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Rect inRect;
+	ThemeDrawState inState;
+#ifndef DrawThemeListBoxFrame
+	PyMac_PRECHECK(DrawThemeListBoxFrame);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      PyMac_GetRect, &inRect,
+	                      &inState))
+		return NULL;
+	_err = DrawThemeListBoxFrame(&inRect,
+	                             inState);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *App_DrawThemeFocusRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Rect inRect;
+	Boolean inHasFocus;
+#ifndef DrawThemeFocusRect
+	PyMac_PRECHECK(DrawThemeFocusRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&b",
+	                      PyMac_GetRect, &inRect,
+	                      &inHasFocus))
+		return NULL;
+	_err = DrawThemeFocusRect(&inRect,
+	                          inHasFocus);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *App_DrawThemePrimaryGroup(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Rect inRect;
+	ThemeDrawState inState;
+#ifndef DrawThemePrimaryGroup
+	PyMac_PRECHECK(DrawThemePrimaryGroup);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      PyMac_GetRect, &inRect,
+	                      &inState))
+		return NULL;
+	_err = DrawThemePrimaryGroup(&inRect,
+	                             inState);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *App_DrawThemeSecondaryGroup(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Rect inRect;
+	ThemeDrawState inState;
+#ifndef DrawThemeSecondaryGroup
+	PyMac_PRECHECK(DrawThemeSecondaryGroup);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      PyMac_GetRect, &inRect,
+	                      &inState))
+		return NULL;
+	_err = DrawThemeSecondaryGroup(&inRect,
+	                               inState);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *App_DrawThemeSeparator(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Rect inRect;
+	ThemeDrawState inState;
+#ifndef DrawThemeSeparator
+	PyMac_PRECHECK(DrawThemeSeparator);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      PyMac_GetRect, &inRect,
+	                      &inState))
+		return NULL;
+	_err = DrawThemeSeparator(&inRect,
+	                          inState);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *App_DrawThemeModelessDialogFrame(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Rect inRect;
+	ThemeDrawState inState;
+#ifndef DrawThemeModelessDialogFrame
+	PyMac_PRECHECK(DrawThemeModelessDialogFrame);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      PyMac_GetRect, &inRect,
+	                      &inState))
+		return NULL;
+	_err = DrawThemeModelessDialogFrame(&inRect,
+	                                    inState);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *App_DrawThemeGenericWell(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Rect inRect;
+	ThemeDrawState inState;
+	Boolean inFillCenter;
+#ifndef DrawThemeGenericWell
+	PyMac_PRECHECK(DrawThemeGenericWell);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&lb",
+	                      PyMac_GetRect, &inRect,
+	                      &inState,
+	                      &inFillCenter))
+		return NULL;
+	_err = DrawThemeGenericWell(&inRect,
+	                            inState,
+	                            inFillCenter);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *App_DrawThemeFocusRegion(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Boolean inHasFocus;
+#ifndef DrawThemeFocusRegion
+	PyMac_PRECHECK(DrawThemeFocusRegion);
+#endif
+	if (!PyArg_ParseTuple(_args, "b",
+	                      &inHasFocus))
+		return NULL;
+	_err = DrawThemeFocusRegion((RgnHandle)0,
+	                            inHasFocus);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *App_IsThemeInColor(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	SInt16 inDepth;
+	Boolean inIsColorDevice;
+#ifndef IsThemeInColor
+	PyMac_PRECHECK(IsThemeInColor);
+#endif
+	if (!PyArg_ParseTuple(_args, "hb",
+	                      &inDepth,
+	                      &inIsColorDevice))
+		return NULL;
+	_rv = IsThemeInColor(inDepth,
+	                     inIsColorDevice);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *App_GetThemeAccentColors(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	CTabHandle outColors;
+#ifndef GetThemeAccentColors
+	PyMac_PRECHECK(GetThemeAccentColors);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetThemeAccentColors(&outColors);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, outColors);
+	return _res;
+}
+
+static PyObject *App_DrawThemeMenuBarBackground(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Rect inBounds;
+	ThemeMenuBarState inState;
+	UInt32 inAttributes;
+#ifndef DrawThemeMenuBarBackground
+	PyMac_PRECHECK(DrawThemeMenuBarBackground);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&Hl",
+	                      PyMac_GetRect, &inBounds,
+	                      &inState,
+	                      &inAttributes))
+		return NULL;
+	_err = DrawThemeMenuBarBackground(&inBounds,
+	                                  inState,
+	                                  inAttributes);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *App_GetThemeMenuBarHeight(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	SInt16 outHeight;
+#ifndef GetThemeMenuBarHeight
+	PyMac_PRECHECK(GetThemeMenuBarHeight);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetThemeMenuBarHeight(&outHeight);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("h",
+	                     outHeight);
+	return _res;
+}
+
+static PyObject *App_DrawThemeMenuBackground(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Rect inMenuRect;
+	ThemeMenuType inMenuType;
+#ifndef DrawThemeMenuBackground
+	PyMac_PRECHECK(DrawThemeMenuBackground);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&H",
+	                      PyMac_GetRect, &inMenuRect,
+	                      &inMenuType))
+		return NULL;
+	_err = DrawThemeMenuBackground(&inMenuRect,
+	                               inMenuType);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *App_GetThemeMenuBackgroundRegion(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Rect inMenuRect;
+	ThemeMenuType menuType;
+#ifndef GetThemeMenuBackgroundRegion
+	PyMac_PRECHECK(GetThemeMenuBackgroundRegion);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&H",
+	                      PyMac_GetRect, &inMenuRect,
+	                      &menuType))
+		return NULL;
+	_err = GetThemeMenuBackgroundRegion(&inMenuRect,
+	                                    menuType,
+	                                    (RgnHandle)0);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *App_DrawThemeMenuSeparator(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Rect inItemRect;
+#ifndef DrawThemeMenuSeparator
+	PyMac_PRECHECK(DrawThemeMenuSeparator);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetRect, &inItemRect))
+		return NULL;
+	_err = DrawThemeMenuSeparator(&inItemRect);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *App_GetThemeMenuSeparatorHeight(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	SInt16 outHeight;
+#ifndef GetThemeMenuSeparatorHeight
+	PyMac_PRECHECK(GetThemeMenuSeparatorHeight);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetThemeMenuSeparatorHeight(&outHeight);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("h",
+	                     outHeight);
+	return _res;
+}
+
+static PyObject *App_GetThemeMenuItemExtra(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	ThemeMenuItemType inItemType;
+	SInt16 outHeight;
+	SInt16 outWidth;
+#ifndef GetThemeMenuItemExtra
+	PyMac_PRECHECK(GetThemeMenuItemExtra);
+#endif
+	if (!PyArg_ParseTuple(_args, "H",
+	                      &inItemType))
+		return NULL;
+	_err = GetThemeMenuItemExtra(inItemType,
+	                             &outHeight,
+	                             &outWidth);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("hh",
+	                     outHeight,
+	                     outWidth);
+	return _res;
+}
+
+static PyObject *App_GetThemeMenuTitleExtra(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	SInt16 outWidth;
+	Boolean inIsSquished;
+#ifndef GetThemeMenuTitleExtra
+	PyMac_PRECHECK(GetThemeMenuTitleExtra);
+#endif
+	if (!PyArg_ParseTuple(_args, "b",
+	                      &inIsSquished))
+		return NULL;
+	_err = GetThemeMenuTitleExtra(&outWidth,
+	                              inIsSquished);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("h",
+	                     outWidth);
+	return _res;
+}
+
+static PyObject *App_DrawThemeTabPane(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Rect inRect;
+	ThemeDrawState inState;
+#ifndef DrawThemeTabPane
+	PyMac_PRECHECK(DrawThemeTabPane);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      PyMac_GetRect, &inRect,
+	                      &inState))
+		return NULL;
+	_err = DrawThemeTabPane(&inRect,
+	                        inState);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *App_GetThemeTabRegion(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Rect inRect;
+	ThemeTabStyle inStyle;
+	ThemeTabDirection inDirection;
+#ifndef GetThemeTabRegion
+	PyMac_PRECHECK(GetThemeTabRegion);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&HH",
+	                      PyMac_GetRect, &inRect,
+	                      &inStyle,
+	                      &inDirection))
+		return NULL;
+	_err = GetThemeTabRegion(&inRect,
+	                         inStyle,
+	                         inDirection,
+	                         (RgnHandle)0);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *App_SetThemeCursor(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	ThemeCursor inCursor;
+#ifndef SetThemeCursor
+	PyMac_PRECHECK(SetThemeCursor);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &inCursor))
+		return NULL;
+	_err = SetThemeCursor(inCursor);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *App_SetAnimatedThemeCursor(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	ThemeCursor inCursor;
+	UInt32 inAnimationStep;
+#ifndef SetAnimatedThemeCursor
+	PyMac_PRECHECK(SetAnimatedThemeCursor);
+#endif
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &inCursor,
+	                      &inAnimationStep))
+		return NULL;
+	_err = SetAnimatedThemeCursor(inCursor,
+	                              inAnimationStep);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *App_GetThemeScrollBarThumbStyle(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	ThemeScrollBarThumbStyle outStyle;
+#ifndef GetThemeScrollBarThumbStyle
+	PyMac_PRECHECK(GetThemeScrollBarThumbStyle);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetThemeScrollBarThumbStyle(&outStyle);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("H",
+	                     outStyle);
+	return _res;
+}
+
+static PyObject *App_GetThemeScrollBarArrowStyle(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	ThemeScrollBarArrowStyle outStyle;
+#ifndef GetThemeScrollBarArrowStyle
+	PyMac_PRECHECK(GetThemeScrollBarArrowStyle);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetThemeScrollBarArrowStyle(&outStyle);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("H",
+	                     outStyle);
+	return _res;
+}
+
+static PyObject *App_GetThemeCheckBoxStyle(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	ThemeCheckBoxStyle outStyle;
+#ifndef GetThemeCheckBoxStyle
+	PyMac_PRECHECK(GetThemeCheckBoxStyle);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetThemeCheckBoxStyle(&outStyle);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("H",
+	                     outStyle);
+	return _res;
+}
+
+static PyObject *App_UseThemeFont(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	ThemeFontID inFontID;
+	ScriptCode inScript;
+#ifndef UseThemeFont
+	PyMac_PRECHECK(UseThemeFont);
+#endif
+	if (!PyArg_ParseTuple(_args, "Hh",
+	                      &inFontID,
+	                      &inScript))
+		return NULL;
+	_err = UseThemeFont(inFontID,
+	                    inScript);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *App_DrawThemeTextBox(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	CFStringRef inString;
+	ThemeFontID inFontID;
+	ThemeDrawState inState;
+	Boolean inWrapToWidth;
+	Rect inBoundingBox;
+	SInt16 inJust;
+#ifndef DrawThemeTextBox
+	PyMac_PRECHECK(DrawThemeTextBox);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&HlbO&h",
+	                      CFStringRefObj_Convert, &inString,
+	                      &inFontID,
+	                      &inState,
+	                      &inWrapToWidth,
+	                      PyMac_GetRect, &inBoundingBox,
+	                      &inJust))
+		return NULL;
+	_err = DrawThemeTextBox(inString,
+	                        inFontID,
+	                        inState,
+	                        inWrapToWidth,
+	                        &inBoundingBox,
+	                        inJust,
+	                        NULL);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *App_TruncateThemeText(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	CFMutableStringRef inString;
+	ThemeFontID inFontID;
+	ThemeDrawState inState;
+	SInt16 inPixelWidthLimit;
+	TruncCode inTruncWhere;
+	Boolean outTruncated;
+#ifndef TruncateThemeText
+	PyMac_PRECHECK(TruncateThemeText);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&Hlhh",
+	                      CFMutableStringRefObj_Convert, &inString,
+	                      &inFontID,
+	                      &inState,
+	                      &inPixelWidthLimit,
+	                      &inTruncWhere))
+		return NULL;
+	_err = TruncateThemeText(inString,
+	                         inFontID,
+	                         inState,
+	                         inPixelWidthLimit,
+	                         inTruncWhere,
+	                         &outTruncated);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("b",
+	                     outTruncated);
+	return _res;
+}
+
+static PyObject *App_GetThemeTextDimensions(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	CFStringRef inString;
+	ThemeFontID inFontID;
+	ThemeDrawState inState;
+	Boolean inWrapToWidth;
+	Point ioBounds;
+	SInt16 outBaseline;
+#ifndef GetThemeTextDimensions
+	PyMac_PRECHECK(GetThemeTextDimensions);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&HlbO&",
+	                      CFStringRefObj_Convert, &inString,
+	                      &inFontID,
+	                      &inState,
+	                      &inWrapToWidth,
+	                      PyMac_GetPoint, &ioBounds))
+		return NULL;
+	_err = GetThemeTextDimensions(inString,
+	                              inFontID,
+	                              inState,
+	                              inWrapToWidth,
+	                              &ioBounds,
+	                              &outBaseline);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&h",
+	                     PyMac_BuildPoint, ioBounds,
+	                     outBaseline);
+	return _res;
+}
+
+static PyObject *App_GetThemeTextShadowOutset(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	ThemeFontID inFontID;
+	ThemeDrawState inState;
+	Rect outOutset;
+#ifndef GetThemeTextShadowOutset
+	PyMac_PRECHECK(GetThemeTextShadowOutset);
+#endif
+	if (!PyArg_ParseTuple(_args, "Hl",
+	                      &inFontID,
+	                      &inState))
+		return NULL;
+	_err = GetThemeTextShadowOutset(inFontID,
+	                                inState,
+	                                &outOutset);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildRect, &outOutset);
+	return _res;
+}
+
+static PyObject *App_DrawThemeScrollBarArrows(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Rect bounds;
+	ThemeTrackEnableState enableState;
+	ThemeTrackPressState pressState;
+	Boolean isHoriz;
+	Rect trackBounds;
+#ifndef DrawThemeScrollBarArrows
+	PyMac_PRECHECK(DrawThemeScrollBarArrows);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&bbb",
+	                      PyMac_GetRect, &bounds,
+	                      &enableState,
+	                      &pressState,
+	                      &isHoriz))
+		return NULL;
+	_err = DrawThemeScrollBarArrows(&bounds,
+	                                enableState,
+	                                pressState,
+	                                isHoriz,
+	                                &trackBounds);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildRect, &trackBounds);
+	return _res;
+}
+
+static PyObject *App_GetThemeScrollBarTrackRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Rect bounds;
+	ThemeTrackEnableState enableState;
+	ThemeTrackPressState pressState;
+	Boolean isHoriz;
+	Rect trackBounds;
+#ifndef GetThemeScrollBarTrackRect
+	PyMac_PRECHECK(GetThemeScrollBarTrackRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&bbb",
+	                      PyMac_GetRect, &bounds,
+	                      &enableState,
+	                      &pressState,
+	                      &isHoriz))
+		return NULL;
+	_err = GetThemeScrollBarTrackRect(&bounds,
+	                                  enableState,
+	                                  pressState,
+	                                  isHoriz,
+	                                  &trackBounds);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildRect, &trackBounds);
+	return _res;
+}
+
+static PyObject *App_HitTestThemeScrollBarArrows(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	Rect scrollBarBounds;
+	ThemeTrackEnableState enableState;
+	ThemeTrackPressState pressState;
+	Boolean isHoriz;
+	Point ptHit;
+	Rect trackBounds;
+	ControlPartCode partcode;
+#ifndef HitTestThemeScrollBarArrows
+	PyMac_PRECHECK(HitTestThemeScrollBarArrows);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&bbbO&",
+	                      PyMac_GetRect, &scrollBarBounds,
+	                      &enableState,
+	                      &pressState,
+	                      &isHoriz,
+	                      PyMac_GetPoint, &ptHit))
+		return NULL;
+	_rv = HitTestThemeScrollBarArrows(&scrollBarBounds,
+	                                  enableState,
+	                                  pressState,
+	                                  isHoriz,
+	                                  ptHit,
+	                                  &trackBounds,
+	                                  &partcode);
+	_res = Py_BuildValue("bO&h",
+	                     _rv,
+	                     PyMac_BuildRect, &trackBounds,
+	                     partcode);
+	return _res;
+}
+
+static PyObject *App_DrawThemeScrollBarDelimiters(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	ThemeWindowType flavor;
+	Rect inContRect;
+	ThemeDrawState state;
+	ThemeWindowAttributes attributes;
+#ifndef DrawThemeScrollBarDelimiters
+	PyMac_PRECHECK(DrawThemeScrollBarDelimiters);
+#endif
+	if (!PyArg_ParseTuple(_args, "HO&ll",
+	                      &flavor,
+	                      PyMac_GetRect, &inContRect,
+	                      &state,
+	                      &attributes))
+		return NULL;
+	_err = DrawThemeScrollBarDelimiters(flavor,
+	                                    &inContRect,
+	                                    state,
+	                                    attributes);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *App_DrawThemeButton(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Rect inBounds;
+	UInt16 inKind;
+	ThemeButtonDrawInfo inNewInfo;
+	ThemeButtonDrawInfo inPrevInfo;
+	UInt32 inUserData;
+#ifndef DrawThemeButton
+	PyMac_PRECHECK(DrawThemeButton);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&HO&O&l",
+	                      PyMac_GetRect, &inBounds,
+	                      &inKind,
+	                      ThemeButtonDrawInfo_Convert, &inNewInfo,
+	                      ThemeButtonDrawInfo_Convert, &inPrevInfo,
+	                      &inUserData))
+		return NULL;
+	_err = DrawThemeButton(&inBounds,
+	                       inKind,
+	                       &inNewInfo,
+	                       &inPrevInfo,
+	                       NULL,
+	                       NULL,
+	                       inUserData);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *App_GetThemeButtonRegion(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Rect inBounds;
+	UInt16 inKind;
+	ThemeButtonDrawInfo inNewInfo;
+#ifndef GetThemeButtonRegion
+	PyMac_PRECHECK(GetThemeButtonRegion);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&HO&",
+	                      PyMac_GetRect, &inBounds,
+	                      &inKind,
+	                      ThemeButtonDrawInfo_Convert, &inNewInfo))
+		return NULL;
+	_err = GetThemeButtonRegion(&inBounds,
+	                            inKind,
+	                            &inNewInfo,
+	                            (RgnHandle)0);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *App_GetThemeButtonContentBounds(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Rect inBounds;
+	UInt16 inKind;
+	ThemeButtonDrawInfo inDrawInfo;
+	Rect outBounds;
+#ifndef GetThemeButtonContentBounds
+	PyMac_PRECHECK(GetThemeButtonContentBounds);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&HO&",
+	                      PyMac_GetRect, &inBounds,
+	                      &inKind,
+	                      ThemeButtonDrawInfo_Convert, &inDrawInfo))
+		return NULL;
+	_err = GetThemeButtonContentBounds(&inBounds,
+	                                   inKind,
+	                                   &inDrawInfo,
+	                                   &outBounds);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildRect, &outBounds);
+	return _res;
+}
+
+static PyObject *App_GetThemeButtonBackgroundBounds(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Rect inBounds;
+	UInt16 inKind;
+	ThemeButtonDrawInfo inDrawInfo;
+	Rect outBounds;
+#ifndef GetThemeButtonBackgroundBounds
+	PyMac_PRECHECK(GetThemeButtonBackgroundBounds);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&HO&",
+	                      PyMac_GetRect, &inBounds,
+	                      &inKind,
+	                      ThemeButtonDrawInfo_Convert, &inDrawInfo))
+		return NULL;
+	_err = GetThemeButtonBackgroundBounds(&inBounds,
+	                                      inKind,
+	                                      &inDrawInfo,
+	                                      &outBounds);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildRect, &outBounds);
+	return _res;
+}
+
+static PyObject *App_PlayThemeSound(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	ThemeSoundKind kind;
+#ifndef PlayThemeSound
+	PyMac_PRECHECK(PlayThemeSound);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetOSType, &kind))
+		return NULL;
+	_err = PlayThemeSound(kind);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *App_BeginThemeDragSound(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	ThemeDragSoundKind kind;
+#ifndef BeginThemeDragSound
+	PyMac_PRECHECK(BeginThemeDragSound);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetOSType, &kind))
+		return NULL;
+	_err = BeginThemeDragSound(kind);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *App_EndThemeDragSound(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+#ifndef EndThemeDragSound
+	PyMac_PRECHECK(EndThemeDragSound);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = EndThemeDragSound();
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *App_DrawThemeTickMark(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Rect bounds;
+	ThemeDrawState state;
+#ifndef DrawThemeTickMark
+	PyMac_PRECHECK(DrawThemeTickMark);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      PyMac_GetRect, &bounds,
+	                      &state))
+		return NULL;
+	_err = DrawThemeTickMark(&bounds,
+	                         state);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *App_DrawThemeChasingArrows(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Rect bounds;
+	UInt32 index;
+	ThemeDrawState state;
+	UInt32 eraseData;
+#ifndef DrawThemeChasingArrows
+	PyMac_PRECHECK(DrawThemeChasingArrows);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&lll",
+	                      PyMac_GetRect, &bounds,
+	                      &index,
+	                      &state,
+	                      &eraseData))
+		return NULL;
+	_err = DrawThemeChasingArrows(&bounds,
+	                              index,
+	                              state,
+	                              NULL,
+	                              eraseData);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *App_DrawThemePopupArrow(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Rect bounds;
+	ThemeArrowOrientation orientation;
+	ThemePopupArrowSize size;
+	ThemeDrawState state;
+	UInt32 eraseData;
+#ifndef DrawThemePopupArrow
+	PyMac_PRECHECK(DrawThemePopupArrow);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&HHll",
+	                      PyMac_GetRect, &bounds,
+	                      &orientation,
+	                      &size,
+	                      &state,
+	                      &eraseData))
+		return NULL;
+	_err = DrawThemePopupArrow(&bounds,
+	                           orientation,
+	                           size,
+	                           state,
+	                           NULL,
+	                           eraseData);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *App_DrawThemeStandaloneGrowBox(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Point origin;
+	ThemeGrowDirection growDirection;
+	Boolean isSmall;
+	ThemeDrawState state;
+#ifndef DrawThemeStandaloneGrowBox
+	PyMac_PRECHECK(DrawThemeStandaloneGrowBox);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&Hbl",
+	                      PyMac_GetPoint, &origin,
+	                      &growDirection,
+	                      &isSmall,
+	                      &state))
+		return NULL;
+	_err = DrawThemeStandaloneGrowBox(origin,
+	                                  growDirection,
+	                                  isSmall,
+	                                  state);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *App_DrawThemeStandaloneNoGrowBox(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Point origin;
+	ThemeGrowDirection growDirection;
+	Boolean isSmall;
+	ThemeDrawState state;
+#ifndef DrawThemeStandaloneNoGrowBox
+	PyMac_PRECHECK(DrawThemeStandaloneNoGrowBox);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&Hbl",
+	                      PyMac_GetPoint, &origin,
+	                      &growDirection,
+	                      &isSmall,
+	                      &state))
+		return NULL;
+	_err = DrawThemeStandaloneNoGrowBox(origin,
+	                                    growDirection,
+	                                    isSmall,
+	                                    state);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *App_GetThemeStandaloneGrowBoxBounds(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Point origin;
+	ThemeGrowDirection growDirection;
+	Boolean isSmall;
+	Rect bounds;
+#ifndef GetThemeStandaloneGrowBoxBounds
+	PyMac_PRECHECK(GetThemeStandaloneGrowBoxBounds);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&Hb",
+	                      PyMac_GetPoint, &origin,
+	                      &growDirection,
+	                      &isSmall))
+		return NULL;
+	_err = GetThemeStandaloneGrowBoxBounds(origin,
+	                                       growDirection,
+	                                       isSmall,
+	                                       &bounds);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildRect, &bounds);
+	return _res;
+}
+
+static PyObject *App_NormalizeThemeDrawingState(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+#ifndef NormalizeThemeDrawingState
+	PyMac_PRECHECK(NormalizeThemeDrawingState);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = NormalizeThemeDrawingState();
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *App_GetThemeDrawingState(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	ThemeDrawingState outState;
+#ifndef GetThemeDrawingState
+	PyMac_PRECHECK(GetThemeDrawingState);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetThemeDrawingState(&outState);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     ThemeDrawingStateObj_New, outState);
+	return _res;
+}
+
+static PyObject *App_ApplyThemeBackground(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	ThemeBackgroundKind inKind;
+	Rect bounds;
+	ThemeDrawState inState;
+	SInt16 inDepth;
+	Boolean inColorDev;
+#ifndef ApplyThemeBackground
+	PyMac_PRECHECK(ApplyThemeBackground);
+#endif
+	if (!PyArg_ParseTuple(_args, "lO&lhb",
+	                      &inKind,
+	                      PyMac_GetRect, &bounds,
+	                      &inState,
+	                      &inDepth,
+	                      &inColorDev))
+		return NULL;
+	_err = ApplyThemeBackground(inKind,
+	                            &bounds,
+	                            inState,
+	                            inDepth,
+	                            inColorDev);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *App_SetThemeTextColorForWindow(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr window;
+	Boolean isActive;
+	SInt16 depth;
+	Boolean isColorDev;
+#ifndef SetThemeTextColorForWindow
+	PyMac_PRECHECK(SetThemeTextColorForWindow);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&bhb",
+	                      WinObj_Convert, &window,
+	                      &isActive,
+	                      &depth,
+	                      &isColorDev))
+		return NULL;
+	_err = SetThemeTextColorForWindow(window,
+	                                  isActive,
+	                                  depth,
+	                                  isColorDev);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *App_IsValidAppearanceFileType(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	OSType fileType;
+#ifndef IsValidAppearanceFileType
+	PyMac_PRECHECK(IsValidAppearanceFileType);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetOSType, &fileType))
+		return NULL;
+	_rv = IsValidAppearanceFileType(fileType);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *App_GetThemeBrushAsColor(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	ThemeBrush inBrush;
+	SInt16 inDepth;
+	Boolean inColorDev;
+	RGBColor outColor;
+#ifndef GetThemeBrushAsColor
+	PyMac_PRECHECK(GetThemeBrushAsColor);
+#endif
+	if (!PyArg_ParseTuple(_args, "hhb",
+	                      &inBrush,
+	                      &inDepth,
+	                      &inColorDev))
+		return NULL;
+	_err = GetThemeBrushAsColor(inBrush,
+	                            inDepth,
+	                            inColorDev,
+	                            &outColor);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     QdRGB_New, &outColor);
+	return _res;
+}
+
+static PyObject *App_GetThemeTextColor(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	ThemeTextColor inColor;
+	SInt16 inDepth;
+	Boolean inColorDev;
+	RGBColor outColor;
+#ifndef GetThemeTextColor
+	PyMac_PRECHECK(GetThemeTextColor);
+#endif
+	if (!PyArg_ParseTuple(_args, "hhb",
+	                      &inColor,
+	                      &inDepth,
+	                      &inColorDev))
+		return NULL;
+	_err = GetThemeTextColor(inColor,
+	                         inDepth,
+	                         inColorDev,
+	                         &outColor);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     QdRGB_New, &outColor);
+	return _res;
+}
+
+static PyObject *App_GetThemeMetric(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	ThemeMetric inMetric;
+	SInt32 outMetric;
+#ifndef GetThemeMetric
+	PyMac_PRECHECK(GetThemeMetric);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &inMetric))
+		return NULL;
+	_err = GetThemeMetric(inMetric,
+	                      &outMetric);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     outMetric);
+	return _res;
+}
+
+static PyMethodDef App_methods[] = {
+	{"RegisterAppearanceClient", (PyCFunction)App_RegisterAppearanceClient, 1,
+	 PyDoc_STR("() -> None")},
+	{"UnregisterAppearanceClient", (PyCFunction)App_UnregisterAppearanceClient, 1,
+	 PyDoc_STR("() -> None")},
+	{"SetThemePen", (PyCFunction)App_SetThemePen, 1,
+	 PyDoc_STR("(ThemeBrush inBrush, SInt16 inDepth, Boolean inIsColorDevice) -> None")},
+	{"SetThemeBackground", (PyCFunction)App_SetThemeBackground, 1,
+	 PyDoc_STR("(ThemeBrush inBrush, SInt16 inDepth, Boolean inIsColorDevice) -> None")},
+	{"SetThemeTextColor", (PyCFunction)App_SetThemeTextColor, 1,
+	 PyDoc_STR("(ThemeTextColor inColor, SInt16 inDepth, Boolean inIsColorDevice) -> None")},
+	{"SetThemeWindowBackground", (PyCFunction)App_SetThemeWindowBackground, 1,
+	 PyDoc_STR("(WindowPtr inWindow, ThemeBrush inBrush, Boolean inUpdate) -> None")},
+	{"DrawThemeWindowHeader", (PyCFunction)App_DrawThemeWindowHeader, 1,
+	 PyDoc_STR("(Rect inRect, ThemeDrawState inState) -> None")},
+	{"DrawThemeWindowListViewHeader", (PyCFunction)App_DrawThemeWindowListViewHeader, 1,
+	 PyDoc_STR("(Rect inRect, ThemeDrawState inState) -> None")},
+	{"DrawThemePlacard", (PyCFunction)App_DrawThemePlacard, 1,
+	 PyDoc_STR("(Rect inRect, ThemeDrawState inState) -> None")},
+	{"DrawThemeEditTextFrame", (PyCFunction)App_DrawThemeEditTextFrame, 1,
+	 PyDoc_STR("(Rect inRect, ThemeDrawState inState) -> None")},
+	{"DrawThemeListBoxFrame", (PyCFunction)App_DrawThemeListBoxFrame, 1,
+	 PyDoc_STR("(Rect inRect, ThemeDrawState inState) -> None")},
+	{"DrawThemeFocusRect", (PyCFunction)App_DrawThemeFocusRect, 1,
+	 PyDoc_STR("(Rect inRect, Boolean inHasFocus) -> None")},
+	{"DrawThemePrimaryGroup", (PyCFunction)App_DrawThemePrimaryGroup, 1,
+	 PyDoc_STR("(Rect inRect, ThemeDrawState inState) -> None")},
+	{"DrawThemeSecondaryGroup", (PyCFunction)App_DrawThemeSecondaryGroup, 1,
+	 PyDoc_STR("(Rect inRect, ThemeDrawState inState) -> None")},
+	{"DrawThemeSeparator", (PyCFunction)App_DrawThemeSeparator, 1,
+	 PyDoc_STR("(Rect inRect, ThemeDrawState inState) -> None")},
+	{"DrawThemeModelessDialogFrame", (PyCFunction)App_DrawThemeModelessDialogFrame, 1,
+	 PyDoc_STR("(Rect inRect, ThemeDrawState inState) -> None")},
+	{"DrawThemeGenericWell", (PyCFunction)App_DrawThemeGenericWell, 1,
+	 PyDoc_STR("(Rect inRect, ThemeDrawState inState, Boolean inFillCenter) -> None")},
+	{"DrawThemeFocusRegion", (PyCFunction)App_DrawThemeFocusRegion, 1,
+	 PyDoc_STR("(Boolean inHasFocus) -> None")},
+	{"IsThemeInColor", (PyCFunction)App_IsThemeInColor, 1,
+	 PyDoc_STR("(SInt16 inDepth, Boolean inIsColorDevice) -> (Boolean _rv)")},
+	{"GetThemeAccentColors", (PyCFunction)App_GetThemeAccentColors, 1,
+	 PyDoc_STR("() -> (CTabHandle outColors)")},
+	{"DrawThemeMenuBarBackground", (PyCFunction)App_DrawThemeMenuBarBackground, 1,
+	 PyDoc_STR("(Rect inBounds, ThemeMenuBarState inState, UInt32 inAttributes) -> None")},
+	{"GetThemeMenuBarHeight", (PyCFunction)App_GetThemeMenuBarHeight, 1,
+	 PyDoc_STR("() -> (SInt16 outHeight)")},
+	{"DrawThemeMenuBackground", (PyCFunction)App_DrawThemeMenuBackground, 1,
+	 PyDoc_STR("(Rect inMenuRect, ThemeMenuType inMenuType) -> None")},
+	{"GetThemeMenuBackgroundRegion", (PyCFunction)App_GetThemeMenuBackgroundRegion, 1,
+	 PyDoc_STR("(Rect inMenuRect, ThemeMenuType menuType) -> None")},
+	{"DrawThemeMenuSeparator", (PyCFunction)App_DrawThemeMenuSeparator, 1,
+	 PyDoc_STR("(Rect inItemRect) -> None")},
+	{"GetThemeMenuSeparatorHeight", (PyCFunction)App_GetThemeMenuSeparatorHeight, 1,
+	 PyDoc_STR("() -> (SInt16 outHeight)")},
+	{"GetThemeMenuItemExtra", (PyCFunction)App_GetThemeMenuItemExtra, 1,
+	 PyDoc_STR("(ThemeMenuItemType inItemType) -> (SInt16 outHeight, SInt16 outWidth)")},
+	{"GetThemeMenuTitleExtra", (PyCFunction)App_GetThemeMenuTitleExtra, 1,
+	 PyDoc_STR("(Boolean inIsSquished) -> (SInt16 outWidth)")},
+	{"DrawThemeTabPane", (PyCFunction)App_DrawThemeTabPane, 1,
+	 PyDoc_STR("(Rect inRect, ThemeDrawState inState) -> None")},
+	{"GetThemeTabRegion", (PyCFunction)App_GetThemeTabRegion, 1,
+	 PyDoc_STR("(Rect inRect, ThemeTabStyle inStyle, ThemeTabDirection inDirection) -> None")},
+	{"SetThemeCursor", (PyCFunction)App_SetThemeCursor, 1,
+	 PyDoc_STR("(ThemeCursor inCursor) -> None")},
+	{"SetAnimatedThemeCursor", (PyCFunction)App_SetAnimatedThemeCursor, 1,
+	 PyDoc_STR("(ThemeCursor inCursor, UInt32 inAnimationStep) -> None")},
+	{"GetThemeScrollBarThumbStyle", (PyCFunction)App_GetThemeScrollBarThumbStyle, 1,
+	 PyDoc_STR("() -> (ThemeScrollBarThumbStyle outStyle)")},
+	{"GetThemeScrollBarArrowStyle", (PyCFunction)App_GetThemeScrollBarArrowStyle, 1,
+	 PyDoc_STR("() -> (ThemeScrollBarArrowStyle outStyle)")},
+	{"GetThemeCheckBoxStyle", (PyCFunction)App_GetThemeCheckBoxStyle, 1,
+	 PyDoc_STR("() -> (ThemeCheckBoxStyle outStyle)")},
+	{"UseThemeFont", (PyCFunction)App_UseThemeFont, 1,
+	 PyDoc_STR("(ThemeFontID inFontID, ScriptCode inScript) -> None")},
+	{"DrawThemeTextBox", (PyCFunction)App_DrawThemeTextBox, 1,
+	 PyDoc_STR("(CFStringRef inString, ThemeFontID inFontID, ThemeDrawState inState, Boolean inWrapToWidth, Rect inBoundingBox, SInt16 inJust) -> None")},
+	{"TruncateThemeText", (PyCFunction)App_TruncateThemeText, 1,
+	 PyDoc_STR("(CFMutableStringRef inString, ThemeFontID inFontID, ThemeDrawState inState, SInt16 inPixelWidthLimit, TruncCode inTruncWhere) -> (Boolean outTruncated)")},
+	{"GetThemeTextDimensions", (PyCFunction)App_GetThemeTextDimensions, 1,
+	 PyDoc_STR("(CFStringRef inString, ThemeFontID inFontID, ThemeDrawState inState, Boolean inWrapToWidth, Point ioBounds) -> (Point ioBounds, SInt16 outBaseline)")},
+	{"GetThemeTextShadowOutset", (PyCFunction)App_GetThemeTextShadowOutset, 1,
+	 PyDoc_STR("(ThemeFontID inFontID, ThemeDrawState inState) -> (Rect outOutset)")},
+	{"DrawThemeScrollBarArrows", (PyCFunction)App_DrawThemeScrollBarArrows, 1,
+	 PyDoc_STR("(Rect bounds, ThemeTrackEnableState enableState, ThemeTrackPressState pressState, Boolean isHoriz) -> (Rect trackBounds)")},
+	{"GetThemeScrollBarTrackRect", (PyCFunction)App_GetThemeScrollBarTrackRect, 1,
+	 PyDoc_STR("(Rect bounds, ThemeTrackEnableState enableState, ThemeTrackPressState pressState, Boolean isHoriz) -> (Rect trackBounds)")},
+	{"HitTestThemeScrollBarArrows", (PyCFunction)App_HitTestThemeScrollBarArrows, 1,
+	 PyDoc_STR("(Rect scrollBarBounds, ThemeTrackEnableState enableState, ThemeTrackPressState pressState, Boolean isHoriz, Point ptHit) -> (Boolean _rv, Rect trackBounds, ControlPartCode partcode)")},
+	{"DrawThemeScrollBarDelimiters", (PyCFunction)App_DrawThemeScrollBarDelimiters, 1,
+	 PyDoc_STR("(ThemeWindowType flavor, Rect inContRect, ThemeDrawState state, ThemeWindowAttributes attributes) -> None")},
+	{"DrawThemeButton", (PyCFunction)App_DrawThemeButton, 1,
+	 PyDoc_STR("(Rect inBounds, UInt16 inKind, ThemeButtonDrawInfo inNewInfo, ThemeButtonDrawInfo inPrevInfo, UInt32 inUserData) -> None")},
+	{"GetThemeButtonRegion", (PyCFunction)App_GetThemeButtonRegion, 1,
+	 PyDoc_STR("(Rect inBounds, UInt16 inKind, ThemeButtonDrawInfo inNewInfo) -> None")},
+	{"GetThemeButtonContentBounds", (PyCFunction)App_GetThemeButtonContentBounds, 1,
+	 PyDoc_STR("(Rect inBounds, UInt16 inKind, ThemeButtonDrawInfo inDrawInfo) -> (Rect outBounds)")},
+	{"GetThemeButtonBackgroundBounds", (PyCFunction)App_GetThemeButtonBackgroundBounds, 1,
+	 PyDoc_STR("(Rect inBounds, UInt16 inKind, ThemeButtonDrawInfo inDrawInfo) -> (Rect outBounds)")},
+	{"PlayThemeSound", (PyCFunction)App_PlayThemeSound, 1,
+	 PyDoc_STR("(ThemeSoundKind kind) -> None")},
+	{"BeginThemeDragSound", (PyCFunction)App_BeginThemeDragSound, 1,
+	 PyDoc_STR("(ThemeDragSoundKind kind) -> None")},
+	{"EndThemeDragSound", (PyCFunction)App_EndThemeDragSound, 1,
+	 PyDoc_STR("() -> None")},
+	{"DrawThemeTickMark", (PyCFunction)App_DrawThemeTickMark, 1,
+	 PyDoc_STR("(Rect bounds, ThemeDrawState state) -> None")},
+	{"DrawThemeChasingArrows", (PyCFunction)App_DrawThemeChasingArrows, 1,
+	 PyDoc_STR("(Rect bounds, UInt32 index, ThemeDrawState state, UInt32 eraseData) -> None")},
+	{"DrawThemePopupArrow", (PyCFunction)App_DrawThemePopupArrow, 1,
+	 PyDoc_STR("(Rect bounds, ThemeArrowOrientation orientation, ThemePopupArrowSize size, ThemeDrawState state, UInt32 eraseData) -> None")},
+	{"DrawThemeStandaloneGrowBox", (PyCFunction)App_DrawThemeStandaloneGrowBox, 1,
+	 PyDoc_STR("(Point origin, ThemeGrowDirection growDirection, Boolean isSmall, ThemeDrawState state) -> None")},
+	{"DrawThemeStandaloneNoGrowBox", (PyCFunction)App_DrawThemeStandaloneNoGrowBox, 1,
+	 PyDoc_STR("(Point origin, ThemeGrowDirection growDirection, Boolean isSmall, ThemeDrawState state) -> None")},
+	{"GetThemeStandaloneGrowBoxBounds", (PyCFunction)App_GetThemeStandaloneGrowBoxBounds, 1,
+	 PyDoc_STR("(Point origin, ThemeGrowDirection growDirection, Boolean isSmall) -> (Rect bounds)")},
+	{"NormalizeThemeDrawingState", (PyCFunction)App_NormalizeThemeDrawingState, 1,
+	 PyDoc_STR("() -> None")},
+	{"GetThemeDrawingState", (PyCFunction)App_GetThemeDrawingState, 1,
+	 PyDoc_STR("() -> (ThemeDrawingState outState)")},
+	{"ApplyThemeBackground", (PyCFunction)App_ApplyThemeBackground, 1,
+	 PyDoc_STR("(ThemeBackgroundKind inKind, Rect bounds, ThemeDrawState inState, SInt16 inDepth, Boolean inColorDev) -> None")},
+	{"SetThemeTextColorForWindow", (PyCFunction)App_SetThemeTextColorForWindow, 1,
+	 PyDoc_STR("(WindowPtr window, Boolean isActive, SInt16 depth, Boolean isColorDev) -> None")},
+	{"IsValidAppearanceFileType", (PyCFunction)App_IsValidAppearanceFileType, 1,
+	 PyDoc_STR("(OSType fileType) -> (Boolean _rv)")},
+	{"GetThemeBrushAsColor", (PyCFunction)App_GetThemeBrushAsColor, 1,
+	 PyDoc_STR("(ThemeBrush inBrush, SInt16 inDepth, Boolean inColorDev) -> (RGBColor outColor)")},
+	{"GetThemeTextColor", (PyCFunction)App_GetThemeTextColor, 1,
+	 PyDoc_STR("(ThemeTextColor inColor, SInt16 inDepth, Boolean inColorDev) -> (RGBColor outColor)")},
+	{"GetThemeMetric", (PyCFunction)App_GetThemeMetric, 1,
+	 PyDoc_STR("(ThemeMetric inMetric) -> (SInt32 outMetric)")},
+	{NULL, NULL, 0}
+};
+
+
+
+
+void init_App(void)
+{
+	PyObject *m;
+	PyObject *d;
+
+
+
+
+	m = Py_InitModule("_App", App_methods);
+	d = PyModule_GetDict(m);
+	App_Error = PyMac_GetOSErrException();
+	if (App_Error == NULL ||
+	    PyDict_SetItemString(d, "Error", App_Error) != 0)
+		return;
+	ThemeDrawingState_Type.ob_type = &PyType_Type;
+	if (PyType_Ready(&ThemeDrawingState_Type) < 0) return;
+	Py_INCREF(&ThemeDrawingState_Type);
+	PyModule_AddObject(m, "ThemeDrawingState", (PyObject *)&ThemeDrawingState_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&ThemeDrawingState_Type);
+	PyModule_AddObject(m, "ThemeDrawingStateType", (PyObject *)&ThemeDrawingState_Type);
+}
+
+/* ======================== End module _App ========================= */
+

Added: vendor/Python/current/Mac/Modules/app/appscan.py
===================================================================
--- vendor/Python/current/Mac/Modules/app/appscan.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/app/appscan.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,81 @@
+# Scan an Apple header file, generating a Python file of generator calls.
+
+import sys
+import os
+from bgenlocations import TOOLBOXDIR, BGENDIR
+sys.path.append(BGENDIR)
+from scantools import Scanner
+
+LONG = "Appearance"
+SHORT = "app"
+OBJECT = "ThemeDrawingState"
+
+def main():
+    input = LONG + ".h"
+    output = SHORT + "gen.py"
+    defsoutput = TOOLBOXDIR + LONG + ".py"
+    scanner = MyScanner(input, output, defsoutput)
+    scanner.scan()
+    scanner.close()
+    print "=== Testing definitions output code ==="
+    execfile(defsoutput, {}, {})
+    print "=== Done scanning and generating, now importing the generated code... ==="
+    exec "import " + SHORT + "support"
+    print "=== Done.  It's up to you to compile it now! ==="
+
+class MyScanner(Scanner):
+
+    def destination(self, type, name, arglist):
+        classname = "Function"
+        listname = "functions"
+        if arglist:
+            t, n, m = arglist[0]
+            # This is non-functional today
+            if t == OBJECT and m == "InMode":
+                classname = "Method"
+                listname = "methods"
+        return classname, listname
+
+    def writeinitialdefs(self):
+        self.defsfile.write("def FOUR_CHAR_CODE(x): return x\n")
+
+    def makeblacklistnames(self):
+        return [
+                "GetThemeFont",         # Funny stringbuffer in/out parameter, I think...
+                # Constants with funny definitions
+                "appearanceBadBrushIndexErr",
+                "appearanceProcessRegisteredErr",
+                "appearanceProcessNotRegisteredErr",
+                "appearanceBadTextColorIndexErr",
+                "appearanceThemeHasNoAccents",
+                "appearanceBadCursorIndexErr",
+                ]
+
+    def makeblacklisttypes(self):
+        return [
+                "MenuTitleDrawingUPP",
+                "MenuItemDrawingUPP",
+                "ThemeIteratorUPP",
+                "ThemeTabTitleDrawUPP",
+#                       "ThemeEraseUPP",
+#                       "ThemeButtonDrawUPP",
+                "WindowTitleDrawingUPP",
+                "ProcessSerialNumber_ptr",              # Too much work for now.
+                "ThemeTrackDrawInfo_ptr",       # Too much work
+#                       "ThemeButtonDrawInfo_ptr",      # ditto
+                "ThemeWindowMetrics_ptr",       # ditto
+#                       "ThemeDrawingState",    # This is an opaque pointer, so it should be simple. Later.
+                "Collection",           # No interface to collection mgr yet.
+                "BytePtr",              # Not yet.
+                ]
+
+    def makerepairinstructions(self):
+        return [
+                ([("void", 'inContext', "OutMode")],
+                 [("NULL", 'inContext', "InMode")]),
+                ([("Point", 'ioBounds', "OutMode")],
+                 [("Point", 'ioBounds', "InOutMode")]),
+                ]
+
+if __name__ == "__main__":
+    main()

Added: vendor/Python/current/Mac/Modules/app/appsupport.py
===================================================================
--- vendor/Python/current/Mac/Modules/app/appsupport.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/app/appsupport.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,133 @@
+# This script generates a Python interface for an Apple Macintosh Manager.
+# It uses the "bgen" package to generate C code.
+# The function specifications are generated by scanning the mamager's header file,
+# using the "scantools" package (customized for this particular manager).
+
+import string
+
+# Declarations that change for each manager
+MACHEADERFILE = 'Appearance.h'          # The Apple header file
+MODNAME = '_App'                                # The name of the module
+OBJECTNAME = 'ThemeDrawingState'                        # The basic name of the objects used here
+KIND = ''                               # Usually 'Ptr' or 'Handle'
+
+# The following is *usually* unchanged but may still require tuning
+MODPREFIX = 'App'                       # The prefix for module-wide routines
+OBJECTTYPE = OBJECTNAME + KIND          # The C type used to represent them
+OBJECTPREFIX = OBJECTNAME + 'Obj'       # The prefix for object methods
+INPUTFILE = string.lower(MODPREFIX) + 'gen.py' # The file generated by the scanner
+OUTPUTFILE = MODNAME + "module.c"       # The file generated by this program
+
+from macsupport import *
+
+# Create the type objects
+#MenuRef = OpaqueByValueType("MenuRef", "MenuObj")
+
+
+#WindowPeek = OpaqueByValueType("WindowPeek", OBJECTPREFIX)
+
+RgnHandle = FakeType("(RgnHandle)0")
+NULL = FakeType("NULL")
+
+# XXXX Should be next, but this will break a lot of code...
+# RgnHandle = OpaqueByValueType("RgnHandle", "OptResObj")
+
+#KeyMap = ArrayOutputBufferType("KeyMap")
+#MacOSEventKind = Type("MacOSEventKind", "h") # Old-style
+#MacOSEventMask = Type("MacOSEventMask", "h") # Old-style
+#EventMask = Type("EventMask", "h")
+#EventKind = Type("EventKind", "h")
+ThemeBrush = Type("ThemeBrush", "h")
+ThemeColor = Type("ThemeColor", "h")
+ThemeTextColor = Type("ThemeTextColor", "h")
+ThemeMenuBarState = Type("ThemeMenuBarState", "H")
+ThemeMenuState = Type("ThemeMenuState", "H")
+ThemeMenuType = Type("ThemeMenuType", "H")
+ThemeMenuItemType = Type("ThemeMenuItemType", "H")
+ThemeFontID = Type("ThemeFontID", "H")
+ThemeTabStyle = Type("ThemeTabStyle", "H")
+ThemeTabDirection = Type("ThemeTabDirection", "H")
+ThemeDrawState = Type("ThemeDrawState", "l")
+ThemeCursor = Type("ThemeCursor", "l")
+ThemeCheckBoxStyle = Type("ThemeCheckBoxStyle", "H")
+ThemeScrollBarArrowStyle = Type("ThemeScrollBarArrowStyle", "H")
+ThemeScrollBarThumbStyle = Type("ThemeScrollBarThumbStyle", "H")
+CTabHandle = OpaqueByValueType("CTabHandle", "ResObj")
+ThemeTrackEnableState = Type("ThemeTrackEnableState", "b")
+ThemeTrackPressState = Type("ThemeTrackPressState", "b")
+ThemeThumbDirection = Type("ThemeThumbDirection", "b")
+ThemeTrackAttributes = Type("ThemeTrackAttributes", "H")
+ControlPartCode = Type("ControlPartCode", "h")
+ThemeWindowAttributes = Type("ThemeWindowAttributes", "l")
+ThemeWindowType = Type("ThemeWindowType", "H")
+ThemeTitleBarWidget = Type("ThemeTitleBarWidget", "H")
+ThemeArrowOrientation = Type("ThemeArrowOrientation", "H")
+ThemePopupArrowSize = Type("ThemePopupArrowSize", "H")
+ThemeGrowDirection = Type("ThemeGrowDirection", "H")
+ThemeSoundKind = OSTypeType("ThemeSoundKind")
+ThemeDragSoundKind = OSTypeType("ThemeDragSoundKind")
+ThemeBackgroundKind = Type("ThemeBackgroundKind", "l")
+ThemeMetric = Type("ThemeMetric", "l")
+RGBColor = OpaqueType("RGBColor", "QdRGB")
+TruncCode = Type("TruncCode", "h")
+
+
+ThemeButtonKind = UInt16
+ThemeButtonDrawInfo_ptr = OpaqueType("ThemeButtonDrawInfo", "ThemeButtonDrawInfo")
+ThemeEraseUPP = FakeType("NULL")
+ThemeButtonDrawUPP = FakeType("NULL")
+
+
+includestuff = includestuff + """
+#include <Carbon/Carbon.h>
+
+
+int ThemeButtonDrawInfo_Convert(PyObject *v, ThemeButtonDrawInfo *p_itself)
+{
+        return PyArg_Parse(v, "(iHH)", &p_itself->state, &p_itself->value, &p_itself->adornment);
+}
+
+"""
+
+class MyObjectDefinition(PEP253Mixin, GlobalObjectDefinition):
+    pass
+##      def outputCheckNewArg(self):
+##              Output("if (itself == NULL) return PyMac_Error(resNotFound);")
+##      def outputCheckConvertArg(self):
+##              OutLbrace("if (DlgObj_Check(v))")
+##              Output("*p_itself = ((WindowObject *)v)->ob_itself;")
+##              Output("return 1;")
+##              OutRbrace()
+##              Out("""
+##              if (v == Py_None) { *p_itself = NULL; return 1; }
+##              if (PyInt_Check(v)) { *p_itself = (WindowPtr)PyInt_AsLong(v); return 1; }
+##              """)
+
+# From here on it's basically all boiler plate...
+
+# Create the generator groups and link them
+module = MacModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff)
+object = MyObjectDefinition(OBJECTNAME, OBJECTPREFIX, OBJECTTYPE)
+module.addobject(object)
+
+ThemeDrawingState = OpaqueByValueType("ThemeDrawingState", "ThemeDrawingStateObj")
+Method = WeakLinkMethodGenerator
+
+
+# Create the generator classes used to populate the lists
+Function = OSErrWeakLinkFunctionGenerator
+##Method = OSErrWeakLinkMethodGenerator
+
+# Create and populate the lists
+functions = []
+methods = []
+execfile(INPUTFILE)
+
+# add the populated lists to the generator groups
+# (in a different wordl the scan program would generate this)
+for f in functions: module.add(f)
+for f in methods: object.add(f)
+
+# generate output (open the output file as late as possible)
+SetOutputFileName(OUTPUTFILE)
+module.generate()

Added: vendor/Python/current/Mac/Modules/autoGIL.c
===================================================================
--- vendor/Python/current/Mac/Modules/autoGIL.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/autoGIL.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,149 @@
+#include "Python.h"
+#include <CoreFoundation/CFRunLoop.h>
+
+/* These macros are defined in Python 2.3 but not 2.2 */
+#ifndef PyMODINIT_FUNC
+#define PyMODINIT_FUNC void
+#endif
+#ifndef PyDoc_STRVAR
+#define PyDoc_STRVAR(Var,Str) static char Var[] = Str
+#endif
+
+
+#undef AUTOGIL_DEBUG
+
+static PyObject *AutoGILError;
+
+
+static void autoGILCallback(CFRunLoopObserverRef observer,
+			    CFRunLoopActivity activity,
+			    void *info) {
+	PyThreadState **p_tstate = (PyThreadState **)info;
+
+	switch (activity) {
+	case kCFRunLoopBeforeWaiting:
+		/* going to sleep, release GIL */
+#ifdef AUTOGIL_DEBUG
+		fprintf(stderr, "going to sleep, release GIL\n");
+#endif
+		*p_tstate = PyEval_SaveThread();
+		break;
+	case kCFRunLoopAfterWaiting:
+		/* waking up, acquire GIL */
+#ifdef AUTOGIL_DEBUG
+		fprintf(stderr, "waking up, acquire GIL\n");
+#endif
+		PyEval_RestoreThread(*p_tstate);
+		*p_tstate = NULL;
+		break;
+	default:
+		break;
+	}
+}
+
+static void infoRelease(const void *info) {
+	/* XXX This should get called when the run loop is deallocated,
+	   but this doesn't seem to happen. So for now: leak. */
+	PyMem_Free((void *)info);
+}
+
+static PyObject *
+autoGIL_installAutoGIL(PyObject *self)
+{
+	PyObject *tstate_dict = PyThreadState_GetDict();
+	PyObject *v;
+	CFRunLoopRef rl;
+	PyThreadState **p_tstate;  /* for use in the info field */
+	CFRunLoopObserverContext context = {0, NULL, NULL, NULL, NULL};
+	CFRunLoopObserverRef observer;
+
+	if (tstate_dict == NULL)
+		return NULL;
+	v = PyDict_GetItemString(tstate_dict, "autoGIL.InstalledAutoGIL");
+	if (v != NULL) {
+		/* we've already installed a callback for this thread */
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+
+	rl = CFRunLoopGetCurrent();
+	if (rl == NULL) {
+		PyErr_SetString(AutoGILError,
+				"can't get run loop for current thread");
+		return NULL;
+	}
+
+	p_tstate = PyMem_Malloc(sizeof(PyThreadState *));
+	if (p_tstate == NULL) {
+		PyErr_SetString(PyExc_MemoryError,
+				"not enough memory to allocate "
+				"tstate pointer");
+		return NULL;
+	}
+	*p_tstate = NULL;
+	context.info = (void *)p_tstate;
+	context.release = infoRelease;
+
+	observer = CFRunLoopObserverCreate(
+		NULL,
+		kCFRunLoopBeforeWaiting | kCFRunLoopAfterWaiting,
+		1, 0, autoGILCallback, &context);
+	if (observer == NULL) {
+		PyErr_SetString(AutoGILError,
+				"can't create event loop observer");
+		return NULL;
+	}
+	CFRunLoopAddObserver(rl, observer, kCFRunLoopDefaultMode);
+	/* XXX how to check for errors? */
+
+	/* register that we have installed a callback for this thread */
+	if (PyDict_SetItemString(tstate_dict, "autoGIL.InstalledAutoGIL",
+				 Py_None) < 0)
+		return NULL;
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(autoGIL_installAutoGIL_doc,
+"installAutoGIL() -> None\n\
+Install an observer callback in the event loop (CFRunLoop) for the\n\
+current thread, that will lock and unlock the Global Interpreter Lock\n\
+(GIL) at appropriate times, allowing other Python threads to run while\n\
+the event loop is idle."
+);
+
+static PyMethodDef autoGIL_methods[] = {
+	{
+		"installAutoGIL",
+		(PyCFunction)autoGIL_installAutoGIL,
+		METH_NOARGS,
+		autoGIL_installAutoGIL_doc
+	},
+	{ 0, 0, 0, 0 } /* sentinel */
+};
+
+PyDoc_STRVAR(autoGIL_docs,
+"The autoGIL module provides a function (installAutoGIL) that\n\
+automatically locks and unlocks Python's Global Interpreter Lock\n\
+when running an event loop."
+);
+
+PyMODINIT_FUNC
+initautoGIL(void)
+{
+	PyObject *mod;
+
+	mod = Py_InitModule4("autoGIL", autoGIL_methods, autoGIL_docs,
+			     NULL, PYTHON_API_VERSION);
+	if (mod == NULL)
+		return;
+	AutoGILError = PyErr_NewException("autoGIL.AutoGILError",
+					  PyExc_Exception, NULL);
+	if (AutoGILError == NULL)
+		return;
+	Py_INCREF(AutoGILError);
+	if (PyModule_AddObject(mod, "AutoGILError",
+			       AutoGILError) < 0)
+		return;
+}

Added: vendor/Python/current/Mac/Modules/carbonevt/CarbonEvtscan.py
===================================================================
--- vendor/Python/current/Mac/Modules/carbonevt/CarbonEvtscan.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/carbonevt/CarbonEvtscan.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,117 @@
+# IBCarbonscan.py
+
+import sys
+import os
+import string
+import MacOS
+import sys
+
+from bgenlocations import TOOLBOXDIR, BGENDIR
+sys.path.append(BGENDIR)
+
+from scantools import Scanner, Scanner_OSX
+
+def main():
+    print "---Scanning CarbonEvents.h---"
+    input = ["CarbonEvents.h"]
+    output = "CarbonEventsgen.py"
+    defsoutput = TOOLBOXDIR + "CarbonEvents.py"
+    scanner = CarbonEvents_Scanner(input, output, defsoutput)
+    scanner.scan()
+    scanner.close()
+    print "=== Testing definitions output code ==="
+    execfile(defsoutput, {}, {})
+    print "--done scanning, importing--"
+    import CarbonEvtsupport
+    print "done"
+
+RefObjectTypes = ["EventRef",
+                                "EventQueueRef",
+                                "EventLoopRef",
+                                "EventLoopTimerRef",
+                                "EventHandlerRef",
+                                "EventHandlerCallRef",
+                                "EventTargetRef",
+                                "EventHotKeyRef",
+                                ]
+
+class CarbonEvents_Scanner(Scanner_OSX):
+    def destination(self, type, name, arglist):
+        classname = "CarbonEventsFunction"
+        listname = "functions"
+        if arglist:
+            t, n, m = arglist[0]
+            if t in RefObjectTypes and m == "InMode":
+                if t == "EventHandlerRef":
+                    classname = "EventHandlerRefMethod"
+                else:
+                    classname = "CarbonEventsMethod"
+                listname = t + "methods"
+            #else:
+            #       print "not method"
+        return classname, listname
+
+    def writeinitialdefs(self):
+        self.defsfile.write("def FOUR_CHAR_CODE(x): return x\n")
+        self.defsfile.write("def FOUR_CHAR_CODE(x): return x\n")
+        self.defsfile.write("false = 0\n")
+        self.defsfile.write("true = 1\n")
+        self.defsfile.write("keyAEEventClass = FOUR_CHAR_CODE('evcl')\n")
+        self.defsfile.write("keyAEEventID = FOUR_CHAR_CODE('evti')\n")
+
+    def makeblacklistnames(self):
+        return [
+                "sHandler",
+                "MacCreateEvent",
+#                       "TrackMouseLocationWithOptions",
+#                       "TrackMouseLocation",
+#                       "TrackMouseRegion",
+                "RegisterToolboxObjectClass",
+                "UnregisterToolboxObjectClass",
+                "ProcessHICommand",
+                "GetCFRunLoopFromEventLoop",
+
+                "InvokeEventHandlerUPP",
+                "InvokeEventComparatorUPP",
+                "InvokeEventLoopTimerUPP",
+                "NewEventComparatorUPP",
+                "NewEventLoopTimerUPP",
+                "NewEventHandlerUPP",
+                "DisposeEventComparatorUPP",
+                "DisposeEventLoopTimerUPP",
+                "DisposeEventHandlerUPP",
+
+                # Wrote by hand
+                "InstallEventHandler",
+                "RemoveEventHandler",
+
+                # Write by hand?
+                "GetEventParameter",
+                "FlushSpecificEventsFromQueue",
+                "FindSpecificEventInQueue",
+                "InstallEventLoopTimer",
+
+                # Don't do these because they require a CFRelease
+                "CreateTypeStringWithOSType",
+                "CopyEvent",
+                ]
+
+#       def makeblacklisttypes(self):
+#               return ["EventComparatorUPP",
+#                               "EventLoopTimerUPP",
+#                               #"EventHandlerUPP",
+#                               "EventComparatorProcPtr",
+#                               "EventLoopTimerProcPtr",
+#                               "EventHandlerProcPtr",
+#                               ]
+
+    def makerepairinstructions(self):
+        return [
+                ([("UInt32", 'inSize', "InMode"), ("void_ptr", 'inDataPtr', "InMode")],
+                 [("MyInBuffer", 'inDataPtr', "InMode")]),
+                ([("Boolean", 'ioWasInRgn', "OutMode")],
+                 [("Boolean", 'ioWasInRgn', "InOutMode")]),
+        ]
+
+if __name__ == "__main__":
+    main()

Added: vendor/Python/current/Mac/Modules/carbonevt/CarbonEvtsupport.py
===================================================================
--- vendor/Python/current/Mac/Modules/carbonevt/CarbonEvtsupport.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/carbonevt/CarbonEvtsupport.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,314 @@
+# IBCarbonsupport.py
+
+from macsupport import *
+
+from CarbonEvtscan import RefObjectTypes
+
+# where should this go? macsupport.py?
+CFStringRef = OpaqueByValueType('CFStringRef')
+
+for typ in RefObjectTypes:
+    execstr = "%(name)s = OpaqueByValueType('%(name)s')" % {"name": typ}
+    exec execstr
+
+
+if 0:
+    # these types will have no methods and will merely be opaque blobs
+    # should write getattr and setattr for them?
+
+    StructObjectTypes = ["EventTypeSpec",
+                                            "HIPoint",
+                                            "HICommand",
+                                            "EventHotKeyID",
+                                            ]
+
+    for typ in StructObjectTypes:
+        execstr = "%(name)s = OpaqueType('%(name)s')" % {"name": typ}
+        exec execstr
+
+EventHotKeyID = OpaqueByValueType("EventHotKeyID", "EventHotKeyID")
+EventTypeSpec_ptr = OpaqueType("EventTypeSpec", "EventTypeSpec")
+
+# is this the right type for the void * in GetEventParameter
+#void_ptr = FixedInputBufferType(1024)
+void_ptr = stringptr
+# here are some types that are really other types
+
+class MyVarInputBufferType(VarInputBufferType):
+    def passInput(self, name):
+        return "%s__len__, %s__in__" % (name, name)
+
+MyInBuffer = MyVarInputBufferType('char', 'long', 'l')          # (buf, len)
+
+EventTime = double
+EventTimeout = EventTime
+EventTimerInterval = EventTime
+EventAttributes = UInt32
+EventParamName = OSType
+EventParamType = OSType
+EventPriority = SInt16
+EventMask = UInt16
+
+EventComparatorUPP = FakeType("(EventComparatorUPP)0")
+EventLoopTimerUPP = FakeType("(EventLoopTimerUPP)0")
+EventHandlerUPP = FakeType("(EventHandlerUPP)0")
+EventHandlerUPP = FakeType("(EventHandlerUPP)0")
+EventComparatorProcPtr = FakeType("(EventComparatorProcPtr)0")
+EventLoopTimerProcPtr = FakeType("(EventLoopTimerProcPtr)0")
+EventHandlerProcPtr = FakeType("(EventHandlerProcPtr)0")
+
+CarbonEventsFunction = OSErrFunctionGenerator
+CarbonEventsMethod = OSErrMethodGenerator
+
+class EventHandlerRefMethod(OSErrMethodGenerator):
+    def precheck(self):
+        OutLbrace('if (_self->ob_itself == NULL)')
+        Output('PyErr_SetString(CarbonEvents_Error, "Handler has been removed");')
+        Output('return NULL;')
+        OutRbrace()
+
+
+RgnHandle = OpaqueByValueType("RgnHandle", "ResObj")
+GrafPtr = OpaqueByValueType("GrafPtr", "GrafObj")
+MouseTrackingResult = UInt16
+
+
+includestuff = includestuff + r"""
+#include <Carbon/Carbon.h>
+
+extern int CFStringRef_New(CFStringRef *);
+
+extern int CFStringRef_Convert(PyObject *, CFStringRef *);
+extern int CFBundleRef_Convert(PyObject *, CFBundleRef *);
+
+int EventTargetRef_Convert(PyObject *, EventTargetRef *);
+PyObject *EventHandlerCallRef_New(EventHandlerCallRef itself);
+PyObject *EventRef_New(EventRef itself);
+
+/********** EventTypeSpec *******/
+static PyObject*
+EventTypeSpec_New(EventTypeSpec *in)
+{
+        return Py_BuildValue("ll", in->eventClass, in->eventKind);
+}
+
+static int
+EventTypeSpec_Convert(PyObject *v, EventTypeSpec *out)
+{
+        if (PyArg_Parse(v, "(O&l)",
+                        PyMac_GetOSType, &(out->eventClass),
+                        &(out->eventKind)))
+                return 1;
+        return NULL;
+}
+
+/********** end EventTypeSpec *******/
+
+/********** HIPoint *******/
+
+#if 0  /* XXX doesn't compile */
+static PyObject*
+HIPoint_New(HIPoint *in)
+{
+        return Py_BuildValue("ff", in->x, in->y);
+}
+
+static int
+HIPoint_Convert(PyObject *v, HIPoint *out)
+{
+        if (PyArg_ParseTuple(v, "ff", &(out->x), &(out->y)))
+                return 1;
+        return NULL;
+}
+#endif
+
+/********** end HIPoint *******/
+
+/********** EventHotKeyID *******/
+
+static PyObject*
+EventHotKeyID_New(EventHotKeyID *in)
+{
+        return Py_BuildValue("ll", in->signature, in->id);
+}
+
+static int
+EventHotKeyID_Convert(PyObject *v, EventHotKeyID *out)
+{
+        if (PyArg_ParseTuple(v, "ll", &out->signature, &out->id))
+                return 1;
+        return NULL;
+}
+
+/********** end EventHotKeyID *******/
+
+/******** myEventHandler ***********/
+
+static EventHandlerUPP myEventHandlerUPP;
+
+static pascal OSStatus
+myEventHandler(EventHandlerCallRef handlerRef, EventRef event, void *outPyObject) {
+        PyObject *retValue;
+        int status;
+
+        retValue = PyObject_CallFunction((PyObject *)outPyObject, "O&O&",
+                                         EventHandlerCallRef_New, handlerRef,
+                                         EventRef_New, event);
+        if (retValue == NULL) {
+                PySys_WriteStderr("Error in event handler callback:\n");
+                PyErr_Print();  /* this also clears the error */
+                status = noErr; /* complain? how? */
+        } else {
+                if (retValue == Py_None)
+                        status = noErr;
+                else if (PyInt_Check(retValue)) {
+                        status = PyInt_AsLong(retValue);
+                } else
+                        status = noErr; /* wrong object type, complain? */
+                Py_DECREF(retValue);
+        }
+
+        return status;
+}
+
+/******** end myEventHandler ***********/
+
+"""
+
+initstuff = initstuff + """
+myEventHandlerUPP = NewEventHandlerUPP(myEventHandler);
+"""
+module = MacModule('_CarbonEvt', 'CarbonEvents', includestuff, finalstuff, initstuff)
+
+
+
+
+class EventHandlerRefObjectDefinition(PEP253Mixin, GlobalObjectDefinition):
+    def outputStructMembers(self):
+        Output("%s ob_itself;", self.itselftype)
+        Output("PyObject *ob_callback;")
+    def outputInitStructMembers(self):
+        Output("it->ob_itself = %sitself;", self.argref)
+        Output("it->ob_callback = NULL;")
+    def outputFreeIt(self, name):
+        OutLbrace("if (self->ob_itself != NULL)")
+        Output("RemoveEventHandler(self->ob_itself);")
+        Output("Py_DECREF(self->ob_callback);")
+        OutRbrace()
+
+class MyGlobalObjectDefinition(PEP253Mixin, GlobalObjectDefinition):
+    pass
+
+for typ in RefObjectTypes:
+    if typ == 'EventHandlerRef':
+        EventHandlerRefobject = EventHandlerRefObjectDefinition('EventHandlerRef')
+    else:
+        execstr = typ + 'object = MyGlobalObjectDefinition(typ)'
+        exec execstr
+    module.addobject(eval(typ + 'object'))
+
+
+functions = []
+for typ in RefObjectTypes: ## go thru all ObjectTypes as defined in CarbonEventsscan.py
+    # initialize the lists for carbongen to fill
+    execstr = typ + 'methods = []'
+    exec execstr
+
+execfile('CarbonEventsgen.py')
+
+
+
+for f in functions: module.add(f)       # add all the functions carboneventsgen put in the list
+
+for typ in RefObjectTypes:                               ## go thru all ObjectTypes as defined in CarbonEventsscan.py
+    methods = eval(typ + 'methods')  ## get a reference to the method list from the main namespace
+    obj = eval(typ + 'object')                ## get a reference to the object
+    for m in methods: obj.add(m)    ## add each method in the list to the object
+
+
+removeeventhandler = """
+OSStatus _err;
+if (_self->ob_itself == NULL) {
+        PyErr_SetString(CarbonEvents_Error, "Handler has been removed");
+        return NULL;
+}
+if (!PyArg_ParseTuple(_args, ""))
+        return NULL;
+_err = RemoveEventHandler(_self->ob_itself);
+if (_err != noErr) return PyMac_Error(_err);
+_self->ob_itself = NULL;
+Py_DECREF(_self->ob_callback);
+_self->ob_callback = NULL;
+Py_INCREF(Py_None);
+_res = Py_None;
+return _res;"""
+
+f = ManualGenerator("RemoveEventHandler", removeeventhandler);
+f.docstring = lambda: "() -> None"
+EventHandlerRefobject.add(f)
+
+
+installeventhandler = """
+EventTypeSpec inSpec;
+PyObject *callback;
+EventHandlerRef outRef;
+OSStatus _err;
+
+if (!PyArg_ParseTuple(_args, "O&O", EventTypeSpec_Convert, &inSpec, &callback))
+        return NULL;
+
+_err = InstallEventHandler(_self->ob_itself, myEventHandlerUPP, 1, &inSpec, (void *)callback, &outRef);
+if (_err != noErr) return PyMac_Error(_err);
+
+_res = EventHandlerRef_New(outRef);
+if (_res != NULL) {
+        ((EventHandlerRefObject*)_res)->ob_callback = callback;
+        Py_INCREF(callback);
+}
+return _res;"""
+
+f = ManualGenerator("InstallEventHandler", installeventhandler);
+f.docstring = lambda: "(EventTypeSpec inSpec, Method callback) -> (EventHandlerRef outRef)"
+EventTargetRefobject.add(f)
+
+# This may not be the best, but at least it lets you get the raw data back into python as a string. You'll have to cut it up yourself and parse the result.
+
+geteventparameter = """
+UInt32 bufferSize;
+EventParamName inName;
+EventParamType inType;
+OSErr _err;
+void * buffer;
+
+if (!PyArg_ParseTuple(_args, "O&O&", PyMac_GetOSType, &inName, PyMac_GetOSType, &inType))
+      return NULL;
+
+/* Figure out the size by passing a null buffer to GetEventParameter */
+_err = GetEventParameter(_self->ob_itself, inName, inType, NULL, 0, &bufferSize, NULL);
+
+if (_err != noErr)
+      return PyMac_Error(_err);
+buffer = PyMem_NEW(char, bufferSize);
+if (buffer == NULL)
+      return PyErr_NoMemory();
+
+_err = GetEventParameter(_self->ob_itself, inName, inType, NULL, bufferSize, NULL, buffer);
+
+if (_err != noErr) {
+      PyMem_DEL(buffer);
+      return PyMac_Error(_err);
+}
+_res = Py_BuildValue("s#", buffer, bufferSize);
+PyMem_DEL(buffer);
+return _res;
+"""
+
+f = ManualGenerator("GetEventParameter", geteventparameter);
+f.docstring = lambda: "(EventParamName eventName, EventParamType eventType) -> (String eventParamData)"
+EventRefobject.add(f)
+
+SetOutputFileName('_CarbonEvtmodule.c')
+module.generate()
+
+##import os
+##os.system("python setup.py build")

Added: vendor/Python/current/Mac/Modules/carbonevt/_CarbonEvtmodule.c
===================================================================
--- vendor/Python/current/Mac/Modules/carbonevt/_CarbonEvtmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/carbonevt/_CarbonEvtmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2222 @@
+
+/* ======================= Module _CarbonEvt ======================== */
+
+#include "Python.h"
+
+
+
+#include "pymactoolbox.h"
+
+/* Macro to test whether a weak-loaded CFM function exists */
+#define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL )  {\
+        PyErr_SetString(PyExc_NotImplementedError, \
+        "Not available in this shared library/OS version"); \
+        return NULL; \
+    }} while(0)
+
+
+#include <Carbon/Carbon.h>
+
+extern int CFStringRef_New(CFStringRef *);
+
+extern int CFStringRef_Convert(PyObject *, CFStringRef *);
+extern int CFBundleRef_Convert(PyObject *, CFBundleRef *);
+
+int EventTargetRef_Convert(PyObject *, EventTargetRef *);
+PyObject *EventHandlerCallRef_New(EventHandlerCallRef itself);
+PyObject *EventRef_New(EventRef itself);
+
+/********** EventTypeSpec *******/
+static PyObject*
+EventTypeSpec_New(EventTypeSpec *in)
+{
+        return Py_BuildValue("ll", in->eventClass, in->eventKind);
+}
+
+static int
+EventTypeSpec_Convert(PyObject *v, EventTypeSpec *out)
+{
+        if (PyArg_Parse(v, "(O&l)",
+                        PyMac_GetOSType, &(out->eventClass),
+                        &(out->eventKind)))
+                return 1;
+        return 0;
+}
+
+/********** end EventTypeSpec *******/
+
+/********** HIPoint *******/
+
+#if 0  /* XXX doesn't compile */
+static PyObject*
+HIPoint_New(HIPoint *in)
+{
+        return Py_BuildValue("ff", in->x, in->y);
+}
+
+static int
+HIPoint_Convert(PyObject *v, HIPoint *out)
+{
+        if (PyArg_ParseTuple(v, "ff", &(out->x), &(out->y)))
+                return 1;
+        return NULL;
+}
+#endif
+
+/********** end HIPoint *******/
+
+/********** EventHotKeyID *******/
+
+static PyObject*
+EventHotKeyID_New(EventHotKeyID *in)
+{
+        return Py_BuildValue("ll", in->signature, in->id);
+}
+
+static int
+EventHotKeyID_Convert(PyObject *v, EventHotKeyID *out)
+{
+        if (PyArg_ParseTuple(v, "ll", &out->signature, &out->id))
+                return 1;
+        return 0;
+}
+
+/********** end EventHotKeyID *******/
+
+/******** myEventHandler ***********/
+
+static EventHandlerUPP myEventHandlerUPP;
+
+static pascal OSStatus
+myEventHandler(EventHandlerCallRef handlerRef, EventRef event, void *outPyObject) {
+        PyObject *retValue;
+        int status;
+
+        retValue = PyObject_CallFunction((PyObject *)outPyObject, "O&O&",
+                                         EventHandlerCallRef_New, handlerRef,
+                                         EventRef_New, event);
+        if (retValue == NULL) {
+                PySys_WriteStderr("Error in event handler callback:\n");
+                PyErr_Print();  /* this also clears the error */
+                status = noErr; /* complain? how? */
+        } else {
+                if (retValue == Py_None)
+                        status = noErr;
+                else if (PyInt_Check(retValue)) {
+                        status = PyInt_AsLong(retValue);
+                } else
+                        status = noErr; /* wrong object type, complain? */
+                Py_DECREF(retValue);
+        }
+
+        return status;
+}
+
+/******** end myEventHandler ***********/
+
+
+static PyObject *CarbonEvents_Error;
+
+/* ---------------------- Object type EventRef ---------------------- */
+
+PyTypeObject EventRef_Type;
+
+#define EventRef_Check(x) ((x)->ob_type == &EventRef_Type || PyObject_TypeCheck((x), &EventRef_Type))
+
+typedef struct EventRefObject {
+	PyObject_HEAD
+	EventRef ob_itself;
+} EventRefObject;
+
+PyObject *EventRef_New(EventRef itself)
+{
+	EventRefObject *it;
+	it = PyObject_NEW(EventRefObject, &EventRef_Type);
+	if (it == NULL) return NULL;
+	it->ob_itself = itself;
+	return (PyObject *)it;
+}
+
+int EventRef_Convert(PyObject *v, EventRef *p_itself)
+{
+	if (!EventRef_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "EventRef required");
+		return 0;
+	}
+	*p_itself = ((EventRefObject *)v)->ob_itself;
+	return 1;
+}
+
+static void EventRef_dealloc(EventRefObject *self)
+{
+	/* Cleanup of self->ob_itself goes here */
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *EventRef_RetainEvent(EventRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	EventRef _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = RetainEvent(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     EventRef_New, _rv);
+	return _res;
+}
+
+static PyObject *EventRef_GetEventRetainCount(EventRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	UInt32 _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetEventRetainCount(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *EventRef_ReleaseEvent(EventRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	ReleaseEvent(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *EventRef_SetEventParameter(EventRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	OSType inName;
+	OSType inType;
+	char *inDataPtr__in__;
+	long inDataPtr__len__;
+	int inDataPtr__in_len__;
+	if (!PyArg_ParseTuple(_args, "O&O&s#",
+	                      PyMac_GetOSType, &inName,
+	                      PyMac_GetOSType, &inType,
+	                      &inDataPtr__in__, &inDataPtr__in_len__))
+		return NULL;
+	inDataPtr__len__ = inDataPtr__in_len__;
+	_err = SetEventParameter(_self->ob_itself,
+	                         inName,
+	                         inType,
+	                         inDataPtr__len__, inDataPtr__in__);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *EventRef_GetEventClass(EventRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	UInt32 _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetEventClass(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *EventRef_GetEventKind(EventRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	UInt32 _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetEventKind(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *EventRef_GetEventTime(EventRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	double _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetEventTime(_self->ob_itself);
+	_res = Py_BuildValue("d",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *EventRef_SetEventTime(EventRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	double inTime;
+	if (!PyArg_ParseTuple(_args, "d",
+	                      &inTime))
+		return NULL;
+	_err = SetEventTime(_self->ob_itself,
+	                    inTime);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *EventRef_IsUserCancelEventRef(EventRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = IsUserCancelEventRef(_self->ob_itself);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *EventRef_ConvertEventRefToEventRecord(EventRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	EventRecord outEvent;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = ConvertEventRefToEventRecord(_self->ob_itself,
+	                                   &outEvent);
+	_res = Py_BuildValue("bO&",
+	                     _rv,
+	                     PyMac_BuildEventRecord, &outEvent);
+	return _res;
+}
+
+static PyObject *EventRef_IsEventInMask(EventRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	UInt16 inMask;
+	if (!PyArg_ParseTuple(_args, "H",
+	                      &inMask))
+		return NULL;
+	_rv = IsEventInMask(_self->ob_itself,
+	                    inMask);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *EventRef_SendEventToEventTarget(EventRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	EventTargetRef inTarget;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      EventTargetRef_Convert, &inTarget))
+		return NULL;
+	_err = SendEventToEventTarget(_self->ob_itself,
+	                              inTarget);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *EventRef_GetEventParameter(EventRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+
+	UInt32 bufferSize;
+	EventParamName inName;
+	EventParamType inType;
+	OSErr _err;
+	void * buffer;
+
+	if (!PyArg_ParseTuple(_args, "O&O&", PyMac_GetOSType, &inName, PyMac_GetOSType, &inType))
+	      return NULL;
+
+	/* Figure out the size by passing a null buffer to GetEventParameter */
+	_err = GetEventParameter(_self->ob_itself, inName, inType, NULL, 0, &bufferSize, NULL);
+
+	if (_err != noErr)
+	      return PyMac_Error(_err);
+	buffer = PyMem_NEW(char, bufferSize);
+	if (buffer == NULL)
+	      return PyErr_NoMemory();
+
+	_err = GetEventParameter(_self->ob_itself, inName, inType, NULL, bufferSize, NULL, buffer);
+
+	if (_err != noErr) {
+	      PyMem_DEL(buffer);
+	      return PyMac_Error(_err);
+	}
+	_res = Py_BuildValue("s#", buffer, bufferSize);
+	PyMem_DEL(buffer);
+	return _res;
+
+}
+
+static PyMethodDef EventRef_methods[] = {
+	{"RetainEvent", (PyCFunction)EventRef_RetainEvent, 1,
+	 PyDoc_STR("() -> (EventRef _rv)")},
+	{"GetEventRetainCount", (PyCFunction)EventRef_GetEventRetainCount, 1,
+	 PyDoc_STR("() -> (UInt32 _rv)")},
+	{"ReleaseEvent", (PyCFunction)EventRef_ReleaseEvent, 1,
+	 PyDoc_STR("() -> None")},
+	{"SetEventParameter", (PyCFunction)EventRef_SetEventParameter, 1,
+	 PyDoc_STR("(OSType inName, OSType inType, Buffer inDataPtr) -> None")},
+	{"GetEventClass", (PyCFunction)EventRef_GetEventClass, 1,
+	 PyDoc_STR("() -> (UInt32 _rv)")},
+	{"GetEventKind", (PyCFunction)EventRef_GetEventKind, 1,
+	 PyDoc_STR("() -> (UInt32 _rv)")},
+	{"GetEventTime", (PyCFunction)EventRef_GetEventTime, 1,
+	 PyDoc_STR("() -> (double _rv)")},
+	{"SetEventTime", (PyCFunction)EventRef_SetEventTime, 1,
+	 PyDoc_STR("(double inTime) -> None")},
+	{"IsUserCancelEventRef", (PyCFunction)EventRef_IsUserCancelEventRef, 1,
+	 PyDoc_STR("() -> (Boolean _rv)")},
+	{"ConvertEventRefToEventRecord", (PyCFunction)EventRef_ConvertEventRefToEventRecord, 1,
+	 PyDoc_STR("() -> (Boolean _rv, EventRecord outEvent)")},
+	{"IsEventInMask", (PyCFunction)EventRef_IsEventInMask, 1,
+	 PyDoc_STR("(UInt16 inMask) -> (Boolean _rv)")},
+	{"SendEventToEventTarget", (PyCFunction)EventRef_SendEventToEventTarget, 1,
+	 PyDoc_STR("(EventTargetRef inTarget) -> None")},
+	{"GetEventParameter", (PyCFunction)EventRef_GetEventParameter, 1,
+	 PyDoc_STR("(EventParamName eventName, EventParamType eventType) -> (String eventParamData)")},
+	{NULL, NULL, 0}
+};
+
+#define EventRef_getsetlist NULL
+
+
+#define EventRef_compare NULL
+
+#define EventRef_repr NULL
+
+#define EventRef_hash NULL
+#define EventRef_tp_init 0
+
+#define EventRef_tp_alloc PyType_GenericAlloc
+
+static PyObject *EventRef_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *_self;
+	EventRef itself;
+	char *kw[] = {"itself", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, EventRef_Convert, &itself)) return NULL;
+	if ((_self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	((EventRefObject *)_self)->ob_itself = itself;
+	return _self;
+}
+
+#define EventRef_tp_free PyObject_Del
+
+
+PyTypeObject EventRef_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"_CarbonEvt.EventRef", /*tp_name*/
+	sizeof(EventRefObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) EventRef_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) EventRef_compare, /*tp_compare*/
+	(reprfunc) EventRef_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) EventRef_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	EventRef_methods, /* tp_methods */
+	0, /*tp_members*/
+	EventRef_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	EventRef_tp_init, /* tp_init */
+	EventRef_tp_alloc, /* tp_alloc */
+	EventRef_tp_new, /* tp_new */
+	EventRef_tp_free, /* tp_free */
+};
+
+/* -------------------- End object type EventRef -------------------- */
+
+
+/* ------------------- Object type EventQueueRef -------------------- */
+
+PyTypeObject EventQueueRef_Type;
+
+#define EventQueueRef_Check(x) ((x)->ob_type == &EventQueueRef_Type || PyObject_TypeCheck((x), &EventQueueRef_Type))
+
+typedef struct EventQueueRefObject {
+	PyObject_HEAD
+	EventQueueRef ob_itself;
+} EventQueueRefObject;
+
+PyObject *EventQueueRef_New(EventQueueRef itself)
+{
+	EventQueueRefObject *it;
+	it = PyObject_NEW(EventQueueRefObject, &EventQueueRef_Type);
+	if (it == NULL) return NULL;
+	it->ob_itself = itself;
+	return (PyObject *)it;
+}
+
+int EventQueueRef_Convert(PyObject *v, EventQueueRef *p_itself)
+{
+	if (!EventQueueRef_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "EventQueueRef required");
+		return 0;
+	}
+	*p_itself = ((EventQueueRefObject *)v)->ob_itself;
+	return 1;
+}
+
+static void EventQueueRef_dealloc(EventQueueRefObject *self)
+{
+	/* Cleanup of self->ob_itself goes here */
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *EventQueueRef_PostEventToQueue(EventQueueRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	EventRef inEvent;
+	SInt16 inPriority;
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      EventRef_Convert, &inEvent,
+	                      &inPriority))
+		return NULL;
+	_err = PostEventToQueue(_self->ob_itself,
+	                        inEvent,
+	                        inPriority);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *EventQueueRef_FlushEventsMatchingListFromQueue(EventQueueRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 inNumTypes;
+	EventTypeSpec inList;
+	if (!PyArg_ParseTuple(_args, "lO&",
+	                      &inNumTypes,
+	                      EventTypeSpec_Convert, &inList))
+		return NULL;
+	_err = FlushEventsMatchingListFromQueue(_self->ob_itself,
+	                                        inNumTypes,
+	                                        &inList);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *EventQueueRef_FlushEventQueue(EventQueueRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = FlushEventQueue(_self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *EventQueueRef_GetNumEventsInQueue(EventQueueRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	UInt32 _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetNumEventsInQueue(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *EventQueueRef_RemoveEventFromQueue(EventQueueRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	EventRef inEvent;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      EventRef_Convert, &inEvent))
+		return NULL;
+	_err = RemoveEventFromQueue(_self->ob_itself,
+	                            inEvent);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *EventQueueRef_IsEventInQueue(EventQueueRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	EventRef inEvent;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      EventRef_Convert, &inEvent))
+		return NULL;
+	_rv = IsEventInQueue(_self->ob_itself,
+	                     inEvent);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyMethodDef EventQueueRef_methods[] = {
+	{"PostEventToQueue", (PyCFunction)EventQueueRef_PostEventToQueue, 1,
+	 PyDoc_STR("(EventRef inEvent, SInt16 inPriority) -> None")},
+	{"FlushEventsMatchingListFromQueue", (PyCFunction)EventQueueRef_FlushEventsMatchingListFromQueue, 1,
+	 PyDoc_STR("(UInt32 inNumTypes, EventTypeSpec inList) -> None")},
+	{"FlushEventQueue", (PyCFunction)EventQueueRef_FlushEventQueue, 1,
+	 PyDoc_STR("() -> None")},
+	{"GetNumEventsInQueue", (PyCFunction)EventQueueRef_GetNumEventsInQueue, 1,
+	 PyDoc_STR("() -> (UInt32 _rv)")},
+	{"RemoveEventFromQueue", (PyCFunction)EventQueueRef_RemoveEventFromQueue, 1,
+	 PyDoc_STR("(EventRef inEvent) -> None")},
+	{"IsEventInQueue", (PyCFunction)EventQueueRef_IsEventInQueue, 1,
+	 PyDoc_STR("(EventRef inEvent) -> (Boolean _rv)")},
+	{NULL, NULL, 0}
+};
+
+#define EventQueueRef_getsetlist NULL
+
+
+#define EventQueueRef_compare NULL
+
+#define EventQueueRef_repr NULL
+
+#define EventQueueRef_hash NULL
+#define EventQueueRef_tp_init 0
+
+#define EventQueueRef_tp_alloc PyType_GenericAlloc
+
+static PyObject *EventQueueRef_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *_self;
+	EventQueueRef itself;
+	char *kw[] = {"itself", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, EventQueueRef_Convert, &itself)) return NULL;
+	if ((_self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	((EventQueueRefObject *)_self)->ob_itself = itself;
+	return _self;
+}
+
+#define EventQueueRef_tp_free PyObject_Del
+
+
+PyTypeObject EventQueueRef_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"_CarbonEvt.EventQueueRef", /*tp_name*/
+	sizeof(EventQueueRefObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) EventQueueRef_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) EventQueueRef_compare, /*tp_compare*/
+	(reprfunc) EventQueueRef_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) EventQueueRef_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	EventQueueRef_methods, /* tp_methods */
+	0, /*tp_members*/
+	EventQueueRef_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	EventQueueRef_tp_init, /* tp_init */
+	EventQueueRef_tp_alloc, /* tp_alloc */
+	EventQueueRef_tp_new, /* tp_new */
+	EventQueueRef_tp_free, /* tp_free */
+};
+
+/* ----------------- End object type EventQueueRef ------------------ */
+
+
+/* -------------------- Object type EventLoopRef -------------------- */
+
+PyTypeObject EventLoopRef_Type;
+
+#define EventLoopRef_Check(x) ((x)->ob_type == &EventLoopRef_Type || PyObject_TypeCheck((x), &EventLoopRef_Type))
+
+typedef struct EventLoopRefObject {
+	PyObject_HEAD
+	EventLoopRef ob_itself;
+} EventLoopRefObject;
+
+PyObject *EventLoopRef_New(EventLoopRef itself)
+{
+	EventLoopRefObject *it;
+	it = PyObject_NEW(EventLoopRefObject, &EventLoopRef_Type);
+	if (it == NULL) return NULL;
+	it->ob_itself = itself;
+	return (PyObject *)it;
+}
+
+int EventLoopRef_Convert(PyObject *v, EventLoopRef *p_itself)
+{
+	if (!EventLoopRef_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "EventLoopRef required");
+		return 0;
+	}
+	*p_itself = ((EventLoopRefObject *)v)->ob_itself;
+	return 1;
+}
+
+static void EventLoopRef_dealloc(EventLoopRefObject *self)
+{
+	/* Cleanup of self->ob_itself goes here */
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *EventLoopRef_QuitEventLoop(EventLoopRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = QuitEventLoop(_self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyMethodDef EventLoopRef_methods[] = {
+	{"QuitEventLoop", (PyCFunction)EventLoopRef_QuitEventLoop, 1,
+	 PyDoc_STR("() -> None")},
+	{NULL, NULL, 0}
+};
+
+#define EventLoopRef_getsetlist NULL
+
+
+#define EventLoopRef_compare NULL
+
+#define EventLoopRef_repr NULL
+
+#define EventLoopRef_hash NULL
+#define EventLoopRef_tp_init 0
+
+#define EventLoopRef_tp_alloc PyType_GenericAlloc
+
+static PyObject *EventLoopRef_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *_self;
+	EventLoopRef itself;
+	char *kw[] = {"itself", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, EventLoopRef_Convert, &itself)) return NULL;
+	if ((_self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	((EventLoopRefObject *)_self)->ob_itself = itself;
+	return _self;
+}
+
+#define EventLoopRef_tp_free PyObject_Del
+
+
+PyTypeObject EventLoopRef_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"_CarbonEvt.EventLoopRef", /*tp_name*/
+	sizeof(EventLoopRefObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) EventLoopRef_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) EventLoopRef_compare, /*tp_compare*/
+	(reprfunc) EventLoopRef_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) EventLoopRef_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	EventLoopRef_methods, /* tp_methods */
+	0, /*tp_members*/
+	EventLoopRef_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	EventLoopRef_tp_init, /* tp_init */
+	EventLoopRef_tp_alloc, /* tp_alloc */
+	EventLoopRef_tp_new, /* tp_new */
+	EventLoopRef_tp_free, /* tp_free */
+};
+
+/* ------------------ End object type EventLoopRef ------------------ */
+
+
+/* ----------------- Object type EventLoopTimerRef ------------------ */
+
+PyTypeObject EventLoopTimerRef_Type;
+
+#define EventLoopTimerRef_Check(x) ((x)->ob_type == &EventLoopTimerRef_Type || PyObject_TypeCheck((x), &EventLoopTimerRef_Type))
+
+typedef struct EventLoopTimerRefObject {
+	PyObject_HEAD
+	EventLoopTimerRef ob_itself;
+} EventLoopTimerRefObject;
+
+PyObject *EventLoopTimerRef_New(EventLoopTimerRef itself)
+{
+	EventLoopTimerRefObject *it;
+	it = PyObject_NEW(EventLoopTimerRefObject, &EventLoopTimerRef_Type);
+	if (it == NULL) return NULL;
+	it->ob_itself = itself;
+	return (PyObject *)it;
+}
+
+int EventLoopTimerRef_Convert(PyObject *v, EventLoopTimerRef *p_itself)
+{
+	if (!EventLoopTimerRef_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "EventLoopTimerRef required");
+		return 0;
+	}
+	*p_itself = ((EventLoopTimerRefObject *)v)->ob_itself;
+	return 1;
+}
+
+static void EventLoopTimerRef_dealloc(EventLoopTimerRefObject *self)
+{
+	/* Cleanup of self->ob_itself goes here */
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *EventLoopTimerRef_RemoveEventLoopTimer(EventLoopTimerRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = RemoveEventLoopTimer(_self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *EventLoopTimerRef_SetEventLoopTimerNextFireTime(EventLoopTimerRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	double inNextFire;
+	if (!PyArg_ParseTuple(_args, "d",
+	                      &inNextFire))
+		return NULL;
+	_err = SetEventLoopTimerNextFireTime(_self->ob_itself,
+	                                     inNextFire);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyMethodDef EventLoopTimerRef_methods[] = {
+	{"RemoveEventLoopTimer", (PyCFunction)EventLoopTimerRef_RemoveEventLoopTimer, 1,
+	 PyDoc_STR("() -> None")},
+	{"SetEventLoopTimerNextFireTime", (PyCFunction)EventLoopTimerRef_SetEventLoopTimerNextFireTime, 1,
+	 PyDoc_STR("(double inNextFire) -> None")},
+	{NULL, NULL, 0}
+};
+
+#define EventLoopTimerRef_getsetlist NULL
+
+
+#define EventLoopTimerRef_compare NULL
+
+#define EventLoopTimerRef_repr NULL
+
+#define EventLoopTimerRef_hash NULL
+#define EventLoopTimerRef_tp_init 0
+
+#define EventLoopTimerRef_tp_alloc PyType_GenericAlloc
+
+static PyObject *EventLoopTimerRef_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *_self;
+	EventLoopTimerRef itself;
+	char *kw[] = {"itself", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, EventLoopTimerRef_Convert, &itself)) return NULL;
+	if ((_self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	((EventLoopTimerRefObject *)_self)->ob_itself = itself;
+	return _self;
+}
+
+#define EventLoopTimerRef_tp_free PyObject_Del
+
+
+PyTypeObject EventLoopTimerRef_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"_CarbonEvt.EventLoopTimerRef", /*tp_name*/
+	sizeof(EventLoopTimerRefObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) EventLoopTimerRef_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) EventLoopTimerRef_compare, /*tp_compare*/
+	(reprfunc) EventLoopTimerRef_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) EventLoopTimerRef_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	EventLoopTimerRef_methods, /* tp_methods */
+	0, /*tp_members*/
+	EventLoopTimerRef_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	EventLoopTimerRef_tp_init, /* tp_init */
+	EventLoopTimerRef_tp_alloc, /* tp_alloc */
+	EventLoopTimerRef_tp_new, /* tp_new */
+	EventLoopTimerRef_tp_free, /* tp_free */
+};
+
+/* --------------- End object type EventLoopTimerRef ---------------- */
+
+
+/* ------------------ Object type EventHandlerRef ------------------- */
+
+PyTypeObject EventHandlerRef_Type;
+
+#define EventHandlerRef_Check(x) ((x)->ob_type == &EventHandlerRef_Type || PyObject_TypeCheck((x), &EventHandlerRef_Type))
+
+typedef struct EventHandlerRefObject {
+	PyObject_HEAD
+	EventHandlerRef ob_itself;
+	PyObject *ob_callback;
+} EventHandlerRefObject;
+
+PyObject *EventHandlerRef_New(EventHandlerRef itself)
+{
+	EventHandlerRefObject *it;
+	it = PyObject_NEW(EventHandlerRefObject, &EventHandlerRef_Type);
+	if (it == NULL) return NULL;
+	it->ob_itself = itself;
+	it->ob_callback = NULL;
+	return (PyObject *)it;
+}
+
+int EventHandlerRef_Convert(PyObject *v, EventHandlerRef *p_itself)
+{
+	if (!EventHandlerRef_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "EventHandlerRef required");
+		return 0;
+	}
+	*p_itself = ((EventHandlerRefObject *)v)->ob_itself;
+	return 1;
+}
+
+static void EventHandlerRef_dealloc(EventHandlerRefObject *self)
+{
+	if (self->ob_itself != NULL) {
+		RemoveEventHandler(self->ob_itself);
+		Py_DECREF(self->ob_callback);
+	}
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *EventHandlerRef_AddEventTypesToHandler(EventHandlerRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 inNumTypes;
+	EventTypeSpec inList;
+	if (_self->ob_itself == NULL) {
+		PyErr_SetString(CarbonEvents_Error, "Handler has been removed");
+		return NULL;
+	}
+	if (!PyArg_ParseTuple(_args, "lO&",
+	                      &inNumTypes,
+	                      EventTypeSpec_Convert, &inList))
+		return NULL;
+	_err = AddEventTypesToHandler(_self->ob_itself,
+	                              inNumTypes,
+	                              &inList);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *EventHandlerRef_RemoveEventTypesFromHandler(EventHandlerRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 inNumTypes;
+	EventTypeSpec inList;
+	if (_self->ob_itself == NULL) {
+		PyErr_SetString(CarbonEvents_Error, "Handler has been removed");
+		return NULL;
+	}
+	if (!PyArg_ParseTuple(_args, "lO&",
+	                      &inNumTypes,
+	                      EventTypeSpec_Convert, &inList))
+		return NULL;
+	_err = RemoveEventTypesFromHandler(_self->ob_itself,
+	                                   inNumTypes,
+	                                   &inList);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *EventHandlerRef_RemoveEventHandler(EventHandlerRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+
+	OSStatus _err;
+	if (_self->ob_itself == NULL) {
+	        PyErr_SetString(CarbonEvents_Error, "Handler has been removed");
+	        return NULL;
+	}
+	if (!PyArg_ParseTuple(_args, ""))
+	        return NULL;
+	_err = RemoveEventHandler(_self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	_self->ob_itself = NULL;
+	Py_DECREF(_self->ob_callback);
+	_self->ob_callback = NULL;
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyMethodDef EventHandlerRef_methods[] = {
+	{"AddEventTypesToHandler", (PyCFunction)EventHandlerRef_AddEventTypesToHandler, 1,
+	 PyDoc_STR("(UInt32 inNumTypes, EventTypeSpec inList) -> None")},
+	{"RemoveEventTypesFromHandler", (PyCFunction)EventHandlerRef_RemoveEventTypesFromHandler, 1,
+	 PyDoc_STR("(UInt32 inNumTypes, EventTypeSpec inList) -> None")},
+	{"RemoveEventHandler", (PyCFunction)EventHandlerRef_RemoveEventHandler, 1,
+	 PyDoc_STR("() -> None")},
+	{NULL, NULL, 0}
+};
+
+#define EventHandlerRef_getsetlist NULL
+
+
+#define EventHandlerRef_compare NULL
+
+#define EventHandlerRef_repr NULL
+
+#define EventHandlerRef_hash NULL
+#define EventHandlerRef_tp_init 0
+
+#define EventHandlerRef_tp_alloc PyType_GenericAlloc
+
+static PyObject *EventHandlerRef_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *_self;
+	EventHandlerRef itself;
+	char *kw[] = {"itself", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, EventHandlerRef_Convert, &itself)) return NULL;
+	if ((_self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	((EventHandlerRefObject *)_self)->ob_itself = itself;
+	return _self;
+}
+
+#define EventHandlerRef_tp_free PyObject_Del
+
+
+PyTypeObject EventHandlerRef_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"_CarbonEvt.EventHandlerRef", /*tp_name*/
+	sizeof(EventHandlerRefObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) EventHandlerRef_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) EventHandlerRef_compare, /*tp_compare*/
+	(reprfunc) EventHandlerRef_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) EventHandlerRef_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	EventHandlerRef_methods, /* tp_methods */
+	0, /*tp_members*/
+	EventHandlerRef_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	EventHandlerRef_tp_init, /* tp_init */
+	EventHandlerRef_tp_alloc, /* tp_alloc */
+	EventHandlerRef_tp_new, /* tp_new */
+	EventHandlerRef_tp_free, /* tp_free */
+};
+
+/* ---------------- End object type EventHandlerRef ----------------- */
+
+
+/* ---------------- Object type EventHandlerCallRef ----------------- */
+
+PyTypeObject EventHandlerCallRef_Type;
+
+#define EventHandlerCallRef_Check(x) ((x)->ob_type == &EventHandlerCallRef_Type || PyObject_TypeCheck((x), &EventHandlerCallRef_Type))
+
+typedef struct EventHandlerCallRefObject {
+	PyObject_HEAD
+	EventHandlerCallRef ob_itself;
+} EventHandlerCallRefObject;
+
+PyObject *EventHandlerCallRef_New(EventHandlerCallRef itself)
+{
+	EventHandlerCallRefObject *it;
+	it = PyObject_NEW(EventHandlerCallRefObject, &EventHandlerCallRef_Type);
+	if (it == NULL) return NULL;
+	it->ob_itself = itself;
+	return (PyObject *)it;
+}
+
+int EventHandlerCallRef_Convert(PyObject *v, EventHandlerCallRef *p_itself)
+{
+	if (!EventHandlerCallRef_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "EventHandlerCallRef required");
+		return 0;
+	}
+	*p_itself = ((EventHandlerCallRefObject *)v)->ob_itself;
+	return 1;
+}
+
+static void EventHandlerCallRef_dealloc(EventHandlerCallRefObject *self)
+{
+	/* Cleanup of self->ob_itself goes here */
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *EventHandlerCallRef_CallNextEventHandler(EventHandlerCallRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	EventRef inEvent;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      EventRef_Convert, &inEvent))
+		return NULL;
+	_err = CallNextEventHandler(_self->ob_itself,
+	                            inEvent);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyMethodDef EventHandlerCallRef_methods[] = {
+	{"CallNextEventHandler", (PyCFunction)EventHandlerCallRef_CallNextEventHandler, 1,
+	 PyDoc_STR("(EventRef inEvent) -> None")},
+	{NULL, NULL, 0}
+};
+
+#define EventHandlerCallRef_getsetlist NULL
+
+
+#define EventHandlerCallRef_compare NULL
+
+#define EventHandlerCallRef_repr NULL
+
+#define EventHandlerCallRef_hash NULL
+#define EventHandlerCallRef_tp_init 0
+
+#define EventHandlerCallRef_tp_alloc PyType_GenericAlloc
+
+static PyObject *EventHandlerCallRef_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *_self;
+	EventHandlerCallRef itself;
+	char *kw[] = {"itself", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, EventHandlerCallRef_Convert, &itself)) return NULL;
+	if ((_self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	((EventHandlerCallRefObject *)_self)->ob_itself = itself;
+	return _self;
+}
+
+#define EventHandlerCallRef_tp_free PyObject_Del
+
+
+PyTypeObject EventHandlerCallRef_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"_CarbonEvt.EventHandlerCallRef", /*tp_name*/
+	sizeof(EventHandlerCallRefObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) EventHandlerCallRef_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) EventHandlerCallRef_compare, /*tp_compare*/
+	(reprfunc) EventHandlerCallRef_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) EventHandlerCallRef_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	EventHandlerCallRef_methods, /* tp_methods */
+	0, /*tp_members*/
+	EventHandlerCallRef_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	EventHandlerCallRef_tp_init, /* tp_init */
+	EventHandlerCallRef_tp_alloc, /* tp_alloc */
+	EventHandlerCallRef_tp_new, /* tp_new */
+	EventHandlerCallRef_tp_free, /* tp_free */
+};
+
+/* -------------- End object type EventHandlerCallRef --------------- */
+
+
+/* ------------------- Object type EventTargetRef ------------------- */
+
+PyTypeObject EventTargetRef_Type;
+
+#define EventTargetRef_Check(x) ((x)->ob_type == &EventTargetRef_Type || PyObject_TypeCheck((x), &EventTargetRef_Type))
+
+typedef struct EventTargetRefObject {
+	PyObject_HEAD
+	EventTargetRef ob_itself;
+} EventTargetRefObject;
+
+PyObject *EventTargetRef_New(EventTargetRef itself)
+{
+	EventTargetRefObject *it;
+	it = PyObject_NEW(EventTargetRefObject, &EventTargetRef_Type);
+	if (it == NULL) return NULL;
+	it->ob_itself = itself;
+	return (PyObject *)it;
+}
+
+int EventTargetRef_Convert(PyObject *v, EventTargetRef *p_itself)
+{
+	if (!EventTargetRef_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "EventTargetRef required");
+		return 0;
+	}
+	*p_itself = ((EventTargetRefObject *)v)->ob_itself;
+	return 1;
+}
+
+static void EventTargetRef_dealloc(EventTargetRefObject *self)
+{
+	/* Cleanup of self->ob_itself goes here */
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *EventTargetRef_InstallStandardEventHandler(EventTargetRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = InstallStandardEventHandler(_self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *EventTargetRef_InstallEventHandler(EventTargetRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+
+	EventTypeSpec inSpec;
+	PyObject *callback;
+	EventHandlerRef outRef;
+	OSStatus _err;
+
+	if (!PyArg_ParseTuple(_args, "O&O", EventTypeSpec_Convert, &inSpec, &callback))
+	        return NULL;
+
+	_err = InstallEventHandler(_self->ob_itself, myEventHandlerUPP, 1, &inSpec, (void *)callback, &outRef);
+	if (_err != noErr) return PyMac_Error(_err);
+
+	_res = EventHandlerRef_New(outRef);
+	if (_res != NULL) {
+	        ((EventHandlerRefObject*)_res)->ob_callback = callback;
+	        Py_INCREF(callback);
+	}
+	return _res;
+}
+
+static PyMethodDef EventTargetRef_methods[] = {
+	{"InstallStandardEventHandler", (PyCFunction)EventTargetRef_InstallStandardEventHandler, 1,
+	 PyDoc_STR("() -> None")},
+	{"InstallEventHandler", (PyCFunction)EventTargetRef_InstallEventHandler, 1,
+	 PyDoc_STR("(EventTypeSpec inSpec, Method callback) -> (EventHandlerRef outRef)")},
+	{NULL, NULL, 0}
+};
+
+#define EventTargetRef_getsetlist NULL
+
+
+#define EventTargetRef_compare NULL
+
+#define EventTargetRef_repr NULL
+
+#define EventTargetRef_hash NULL
+#define EventTargetRef_tp_init 0
+
+#define EventTargetRef_tp_alloc PyType_GenericAlloc
+
+static PyObject *EventTargetRef_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *_self;
+	EventTargetRef itself;
+	char *kw[] = {"itself", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, EventTargetRef_Convert, &itself)) return NULL;
+	if ((_self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	((EventTargetRefObject *)_self)->ob_itself = itself;
+	return _self;
+}
+
+#define EventTargetRef_tp_free PyObject_Del
+
+
+PyTypeObject EventTargetRef_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"_CarbonEvt.EventTargetRef", /*tp_name*/
+	sizeof(EventTargetRefObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) EventTargetRef_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) EventTargetRef_compare, /*tp_compare*/
+	(reprfunc) EventTargetRef_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) EventTargetRef_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	EventTargetRef_methods, /* tp_methods */
+	0, /*tp_members*/
+	EventTargetRef_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	EventTargetRef_tp_init, /* tp_init */
+	EventTargetRef_tp_alloc, /* tp_alloc */
+	EventTargetRef_tp_new, /* tp_new */
+	EventTargetRef_tp_free, /* tp_free */
+};
+
+/* ----------------- End object type EventTargetRef ----------------- */
+
+
+/* ------------------- Object type EventHotKeyRef ------------------- */
+
+PyTypeObject EventHotKeyRef_Type;
+
+#define EventHotKeyRef_Check(x) ((x)->ob_type == &EventHotKeyRef_Type || PyObject_TypeCheck((x), &EventHotKeyRef_Type))
+
+typedef struct EventHotKeyRefObject {
+	PyObject_HEAD
+	EventHotKeyRef ob_itself;
+} EventHotKeyRefObject;
+
+PyObject *EventHotKeyRef_New(EventHotKeyRef itself)
+{
+	EventHotKeyRefObject *it;
+	it = PyObject_NEW(EventHotKeyRefObject, &EventHotKeyRef_Type);
+	if (it == NULL) return NULL;
+	it->ob_itself = itself;
+	return (PyObject *)it;
+}
+
+int EventHotKeyRef_Convert(PyObject *v, EventHotKeyRef *p_itself)
+{
+	if (!EventHotKeyRef_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "EventHotKeyRef required");
+		return 0;
+	}
+	*p_itself = ((EventHotKeyRefObject *)v)->ob_itself;
+	return 1;
+}
+
+static void EventHotKeyRef_dealloc(EventHotKeyRefObject *self)
+{
+	/* Cleanup of self->ob_itself goes here */
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *EventHotKeyRef_UnregisterEventHotKey(EventHotKeyRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = UnregisterEventHotKey(_self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyMethodDef EventHotKeyRef_methods[] = {
+	{"UnregisterEventHotKey", (PyCFunction)EventHotKeyRef_UnregisterEventHotKey, 1,
+	 PyDoc_STR("() -> None")},
+	{NULL, NULL, 0}
+};
+
+#define EventHotKeyRef_getsetlist NULL
+
+
+#define EventHotKeyRef_compare NULL
+
+#define EventHotKeyRef_repr NULL
+
+#define EventHotKeyRef_hash NULL
+#define EventHotKeyRef_tp_init 0
+
+#define EventHotKeyRef_tp_alloc PyType_GenericAlloc
+
+static PyObject *EventHotKeyRef_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *_self;
+	EventHotKeyRef itself;
+	char *kw[] = {"itself", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, EventHotKeyRef_Convert, &itself)) return NULL;
+	if ((_self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	((EventHotKeyRefObject *)_self)->ob_itself = itself;
+	return _self;
+}
+
+#define EventHotKeyRef_tp_free PyObject_Del
+
+
+PyTypeObject EventHotKeyRef_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"_CarbonEvt.EventHotKeyRef", /*tp_name*/
+	sizeof(EventHotKeyRefObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) EventHotKeyRef_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) EventHotKeyRef_compare, /*tp_compare*/
+	(reprfunc) EventHotKeyRef_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) EventHotKeyRef_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	EventHotKeyRef_methods, /* tp_methods */
+	0, /*tp_members*/
+	EventHotKeyRef_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	EventHotKeyRef_tp_init, /* tp_init */
+	EventHotKeyRef_tp_alloc, /* tp_alloc */
+	EventHotKeyRef_tp_new, /* tp_new */
+	EventHotKeyRef_tp_free, /* tp_free */
+};
+
+/* ----------------- End object type EventHotKeyRef ----------------- */
+
+
+static PyObject *CarbonEvents_GetCurrentEventLoop(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	EventLoopRef _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetCurrentEventLoop();
+	_res = Py_BuildValue("O&",
+	                     EventLoopRef_New, _rv);
+	return _res;
+}
+
+static PyObject *CarbonEvents_GetMainEventLoop(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	EventLoopRef _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetMainEventLoop();
+	_res = Py_BuildValue("O&",
+	                     EventLoopRef_New, _rv);
+	return _res;
+}
+
+static PyObject *CarbonEvents_RunCurrentEventLoop(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	double inTimeout;
+	if (!PyArg_ParseTuple(_args, "d",
+	                      &inTimeout))
+		return NULL;
+	_err = RunCurrentEventLoop(inTimeout);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CarbonEvents_ReceiveNextEvent(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 inNumTypes;
+	EventTypeSpec inList;
+	double inTimeout;
+	Boolean inPullEvent;
+	EventRef outEvent;
+	if (!PyArg_ParseTuple(_args, "lO&db",
+	                      &inNumTypes,
+	                      EventTypeSpec_Convert, &inList,
+	                      &inTimeout,
+	                      &inPullEvent))
+		return NULL;
+	_err = ReceiveNextEvent(inNumTypes,
+	                        &inList,
+	                        inTimeout,
+	                        inPullEvent,
+	                        &outEvent);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     EventRef_New, outEvent);
+	return _res;
+}
+
+static PyObject *CarbonEvents_GetCurrentEventQueue(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	EventQueueRef _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetCurrentEventQueue();
+	_res = Py_BuildValue("O&",
+	                     EventQueueRef_New, _rv);
+	return _res;
+}
+
+static PyObject *CarbonEvents_GetMainEventQueue(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	EventQueueRef _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetMainEventQueue();
+	_res = Py_BuildValue("O&",
+	                     EventQueueRef_New, _rv);
+	return _res;
+}
+
+static PyObject *CarbonEvents_GetCurrentEventTime(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	double _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetCurrentEventTime();
+	_res = Py_BuildValue("d",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CarbonEvents_TrackMouseLocation(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	GrafPtr inPort;
+	Point outPt;
+	UInt16 outResult;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      GrafObj_Convert, &inPort))
+		return NULL;
+	_err = TrackMouseLocation(inPort,
+	                          &outPt,
+	                          &outResult);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&H",
+	                     PyMac_BuildPoint, outPt,
+	                     outResult);
+	return _res;
+}
+
+static PyObject *CarbonEvents_TrackMouseLocationWithOptions(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	GrafPtr inPort;
+	OptionBits inOptions;
+	double inTimeout;
+	Point outPt;
+	UInt32 outModifiers;
+	UInt16 outResult;
+	if (!PyArg_ParseTuple(_args, "O&ld",
+	                      GrafObj_Convert, &inPort,
+	                      &inOptions,
+	                      &inTimeout))
+		return NULL;
+	_err = TrackMouseLocationWithOptions(inPort,
+	                                     inOptions,
+	                                     inTimeout,
+	                                     &outPt,
+	                                     &outModifiers,
+	                                     &outResult);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&lH",
+	                     PyMac_BuildPoint, outPt,
+	                     outModifiers,
+	                     outResult);
+	return _res;
+}
+
+static PyObject *CarbonEvents_TrackMouseRegion(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	GrafPtr inPort;
+	RgnHandle inRegion;
+	Boolean ioWasInRgn;
+	UInt16 outResult;
+	if (!PyArg_ParseTuple(_args, "O&O&b",
+	                      GrafObj_Convert, &inPort,
+	                      ResObj_Convert, &inRegion,
+	                      &ioWasInRgn))
+		return NULL;
+	_err = TrackMouseRegion(inPort,
+	                        inRegion,
+	                        &ioWasInRgn,
+	                        &outResult);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("bH",
+	                     ioWasInRgn,
+	                     outResult);
+	return _res;
+}
+
+static PyObject *CarbonEvents_GetLastUserEventTime(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	double _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetLastUserEventTime();
+	_res = Py_BuildValue("d",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CarbonEvents_IsMouseCoalescingEnabled(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = IsMouseCoalescingEnabled();
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CarbonEvents_SetMouseCoalescingEnabled(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Boolean inNewState;
+	Boolean outOldState;
+	if (!PyArg_ParseTuple(_args, "b",
+	                      &inNewState))
+		return NULL;
+	_err = SetMouseCoalescingEnabled(inNewState,
+	                                 &outOldState);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("b",
+	                     outOldState);
+	return _res;
+}
+
+static PyObject *CarbonEvents_GetWindowEventTarget(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	EventTargetRef _rv;
+	WindowPtr inWindow;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      WinObj_Convert, &inWindow))
+		return NULL;
+	_rv = GetWindowEventTarget(inWindow);
+	_res = Py_BuildValue("O&",
+	                     EventTargetRef_New, _rv);
+	return _res;
+}
+
+static PyObject *CarbonEvents_GetControlEventTarget(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	EventTargetRef _rv;
+	ControlHandle inControl;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CtlObj_Convert, &inControl))
+		return NULL;
+	_rv = GetControlEventTarget(inControl);
+	_res = Py_BuildValue("O&",
+	                     EventTargetRef_New, _rv);
+	return _res;
+}
+
+static PyObject *CarbonEvents_GetMenuEventTarget(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	EventTargetRef _rv;
+	MenuHandle inMenu;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      MenuObj_Convert, &inMenu))
+		return NULL;
+	_rv = GetMenuEventTarget(inMenu);
+	_res = Py_BuildValue("O&",
+	                     EventTargetRef_New, _rv);
+	return _res;
+}
+
+static PyObject *CarbonEvents_GetApplicationEventTarget(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	EventTargetRef _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetApplicationEventTarget();
+	_res = Py_BuildValue("O&",
+	                     EventTargetRef_New, _rv);
+	return _res;
+}
+
+static PyObject *CarbonEvents_GetUserFocusEventTarget(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	EventTargetRef _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetUserFocusEventTarget();
+	_res = Py_BuildValue("O&",
+	                     EventTargetRef_New, _rv);
+	return _res;
+}
+
+static PyObject *CarbonEvents_GetEventDispatcherTarget(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	EventTargetRef _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetEventDispatcherTarget();
+	_res = Py_BuildValue("O&",
+	                     EventTargetRef_New, _rv);
+	return _res;
+}
+
+static PyObject *CarbonEvents_RunApplicationEventLoop(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	RunApplicationEventLoop();
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CarbonEvents_QuitApplicationEventLoop(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	QuitApplicationEventLoop();
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CarbonEvents_RunAppModalLoopForWindow(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr inWindow;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      WinObj_Convert, &inWindow))
+		return NULL;
+	_err = RunAppModalLoopForWindow(inWindow);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CarbonEvents_QuitAppModalLoopForWindow(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr inWindow;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      WinObj_Convert, &inWindow))
+		return NULL;
+	_err = QuitAppModalLoopForWindow(inWindow);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CarbonEvents_BeginAppModalStateForWindow(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr inWindow;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      WinObj_Convert, &inWindow))
+		return NULL;
+	_err = BeginAppModalStateForWindow(inWindow);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CarbonEvents_EndAppModalStateForWindow(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr inWindow;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      WinObj_Convert, &inWindow))
+		return NULL;
+	_err = EndAppModalStateForWindow(inWindow);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CarbonEvents_SetUserFocusWindow(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr inWindow;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      WinObj_Convert, &inWindow))
+		return NULL;
+	_err = SetUserFocusWindow(inWindow);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CarbonEvents_GetUserFocusWindow(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	WindowPtr _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetUserFocusWindow();
+	_res = Py_BuildValue("O&",
+	                     WinObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CarbonEvents_SetWindowDefaultButton(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr inWindow;
+	ControlHandle inControl;
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      WinObj_Convert, &inWindow,
+	                      CtlObj_Convert, &inControl))
+		return NULL;
+	_err = SetWindowDefaultButton(inWindow,
+	                              inControl);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CarbonEvents_SetWindowCancelButton(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr inWindow;
+	ControlHandle inControl;
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      WinObj_Convert, &inWindow,
+	                      CtlObj_Convert, &inControl))
+		return NULL;
+	_err = SetWindowCancelButton(inWindow,
+	                             inControl);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CarbonEvents_GetWindowDefaultButton(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr inWindow;
+	ControlHandle outControl;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      WinObj_Convert, &inWindow))
+		return NULL;
+	_err = GetWindowDefaultButton(inWindow,
+	                              &outControl);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CtlObj_New, outControl);
+	return _res;
+}
+
+static PyObject *CarbonEvents_GetWindowCancelButton(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr inWindow;
+	ControlHandle outControl;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      WinObj_Convert, &inWindow))
+		return NULL;
+	_err = GetWindowCancelButton(inWindow,
+	                             &outControl);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CtlObj_New, outControl);
+	return _res;
+}
+
+static PyObject *CarbonEvents_RegisterEventHotKey(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 inHotKeyCode;
+	UInt32 inHotKeyModifiers;
+	EventHotKeyID inHotKeyID;
+	EventTargetRef inTarget;
+	OptionBits inOptions;
+	EventHotKeyRef outRef;
+	if (!PyArg_ParseTuple(_args, "llO&O&l",
+	                      &inHotKeyCode,
+	                      &inHotKeyModifiers,
+	                      EventHotKeyID_Convert, &inHotKeyID,
+	                      EventTargetRef_Convert, &inTarget,
+	                      &inOptions))
+		return NULL;
+	_err = RegisterEventHotKey(inHotKeyCode,
+	                           inHotKeyModifiers,
+	                           inHotKeyID,
+	                           inTarget,
+	                           inOptions,
+	                           &outRef);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     EventHotKeyRef_New, outRef);
+	return _res;
+}
+
+static PyMethodDef CarbonEvents_methods[] = {
+	{"GetCurrentEventLoop", (PyCFunction)CarbonEvents_GetCurrentEventLoop, 1,
+	 PyDoc_STR("() -> (EventLoopRef _rv)")},
+	{"GetMainEventLoop", (PyCFunction)CarbonEvents_GetMainEventLoop, 1,
+	 PyDoc_STR("() -> (EventLoopRef _rv)")},
+	{"RunCurrentEventLoop", (PyCFunction)CarbonEvents_RunCurrentEventLoop, 1,
+	 PyDoc_STR("(double inTimeout) -> None")},
+	{"ReceiveNextEvent", (PyCFunction)CarbonEvents_ReceiveNextEvent, 1,
+	 PyDoc_STR("(UInt32 inNumTypes, EventTypeSpec inList, double inTimeout, Boolean inPullEvent) -> (EventRef outEvent)")},
+	{"GetCurrentEventQueue", (PyCFunction)CarbonEvents_GetCurrentEventQueue, 1,
+	 PyDoc_STR("() -> (EventQueueRef _rv)")},
+	{"GetMainEventQueue", (PyCFunction)CarbonEvents_GetMainEventQueue, 1,
+	 PyDoc_STR("() -> (EventQueueRef _rv)")},
+	{"GetCurrentEventTime", (PyCFunction)CarbonEvents_GetCurrentEventTime, 1,
+	 PyDoc_STR("() -> (double _rv)")},
+	{"TrackMouseLocation", (PyCFunction)CarbonEvents_TrackMouseLocation, 1,
+	 PyDoc_STR("(GrafPtr inPort) -> (Point outPt, UInt16 outResult)")},
+	{"TrackMouseLocationWithOptions", (PyCFunction)CarbonEvents_TrackMouseLocationWithOptions, 1,
+	 PyDoc_STR("(GrafPtr inPort, OptionBits inOptions, double inTimeout) -> (Point outPt, UInt32 outModifiers, UInt16 outResult)")},
+	{"TrackMouseRegion", (PyCFunction)CarbonEvents_TrackMouseRegion, 1,
+	 PyDoc_STR("(GrafPtr inPort, RgnHandle inRegion, Boolean ioWasInRgn) -> (Boolean ioWasInRgn, UInt16 outResult)")},
+	{"GetLastUserEventTime", (PyCFunction)CarbonEvents_GetLastUserEventTime, 1,
+	 PyDoc_STR("() -> (double _rv)")},
+	{"IsMouseCoalescingEnabled", (PyCFunction)CarbonEvents_IsMouseCoalescingEnabled, 1,
+	 PyDoc_STR("() -> (Boolean _rv)")},
+	{"SetMouseCoalescingEnabled", (PyCFunction)CarbonEvents_SetMouseCoalescingEnabled, 1,
+	 PyDoc_STR("(Boolean inNewState) -> (Boolean outOldState)")},
+	{"GetWindowEventTarget", (PyCFunction)CarbonEvents_GetWindowEventTarget, 1,
+	 PyDoc_STR("(WindowPtr inWindow) -> (EventTargetRef _rv)")},
+	{"GetControlEventTarget", (PyCFunction)CarbonEvents_GetControlEventTarget, 1,
+	 PyDoc_STR("(ControlHandle inControl) -> (EventTargetRef _rv)")},
+	{"GetMenuEventTarget", (PyCFunction)CarbonEvents_GetMenuEventTarget, 1,
+	 PyDoc_STR("(MenuHandle inMenu) -> (EventTargetRef _rv)")},
+	{"GetApplicationEventTarget", (PyCFunction)CarbonEvents_GetApplicationEventTarget, 1,
+	 PyDoc_STR("() -> (EventTargetRef _rv)")},
+	{"GetUserFocusEventTarget", (PyCFunction)CarbonEvents_GetUserFocusEventTarget, 1,
+	 PyDoc_STR("() -> (EventTargetRef _rv)")},
+	{"GetEventDispatcherTarget", (PyCFunction)CarbonEvents_GetEventDispatcherTarget, 1,
+	 PyDoc_STR("() -> (EventTargetRef _rv)")},
+	{"RunApplicationEventLoop", (PyCFunction)CarbonEvents_RunApplicationEventLoop, 1,
+	 PyDoc_STR("() -> None")},
+	{"QuitApplicationEventLoop", (PyCFunction)CarbonEvents_QuitApplicationEventLoop, 1,
+	 PyDoc_STR("() -> None")},
+	{"RunAppModalLoopForWindow", (PyCFunction)CarbonEvents_RunAppModalLoopForWindow, 1,
+	 PyDoc_STR("(WindowPtr inWindow) -> None")},
+	{"QuitAppModalLoopForWindow", (PyCFunction)CarbonEvents_QuitAppModalLoopForWindow, 1,
+	 PyDoc_STR("(WindowPtr inWindow) -> None")},
+	{"BeginAppModalStateForWindow", (PyCFunction)CarbonEvents_BeginAppModalStateForWindow, 1,
+	 PyDoc_STR("(WindowPtr inWindow) -> None")},
+	{"EndAppModalStateForWindow", (PyCFunction)CarbonEvents_EndAppModalStateForWindow, 1,
+	 PyDoc_STR("(WindowPtr inWindow) -> None")},
+	{"SetUserFocusWindow", (PyCFunction)CarbonEvents_SetUserFocusWindow, 1,
+	 PyDoc_STR("(WindowPtr inWindow) -> None")},
+	{"GetUserFocusWindow", (PyCFunction)CarbonEvents_GetUserFocusWindow, 1,
+	 PyDoc_STR("() -> (WindowPtr _rv)")},
+	{"SetWindowDefaultButton", (PyCFunction)CarbonEvents_SetWindowDefaultButton, 1,
+	 PyDoc_STR("(WindowPtr inWindow, ControlHandle inControl) -> None")},
+	{"SetWindowCancelButton", (PyCFunction)CarbonEvents_SetWindowCancelButton, 1,
+	 PyDoc_STR("(WindowPtr inWindow, ControlHandle inControl) -> None")},
+	{"GetWindowDefaultButton", (PyCFunction)CarbonEvents_GetWindowDefaultButton, 1,
+	 PyDoc_STR("(WindowPtr inWindow) -> (ControlHandle outControl)")},
+	{"GetWindowCancelButton", (PyCFunction)CarbonEvents_GetWindowCancelButton, 1,
+	 PyDoc_STR("(WindowPtr inWindow) -> (ControlHandle outControl)")},
+	{"RegisterEventHotKey", (PyCFunction)CarbonEvents_RegisterEventHotKey, 1,
+	 PyDoc_STR("(UInt32 inHotKeyCode, UInt32 inHotKeyModifiers, EventHotKeyID inHotKeyID, EventTargetRef inTarget, OptionBits inOptions) -> (EventHotKeyRef outRef)")},
+	{NULL, NULL, 0}
+};
+
+
+
+
+void init_CarbonEvt(void)
+{
+	PyObject *m;
+	PyObject *d;
+
+
+
+	myEventHandlerUPP = NewEventHandlerUPP(myEventHandler);
+
+
+	m = Py_InitModule("_CarbonEvt", CarbonEvents_methods);
+	d = PyModule_GetDict(m);
+	CarbonEvents_Error = PyMac_GetOSErrException();
+	if (CarbonEvents_Error == NULL ||
+	    PyDict_SetItemString(d, "Error", CarbonEvents_Error) != 0)
+		return;
+	EventRef_Type.ob_type = &PyType_Type;
+	if (PyType_Ready(&EventRef_Type) < 0) return;
+	Py_INCREF(&EventRef_Type);
+	PyModule_AddObject(m, "EventRef", (PyObject *)&EventRef_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&EventRef_Type);
+	PyModule_AddObject(m, "EventRefType", (PyObject *)&EventRef_Type);
+	EventQueueRef_Type.ob_type = &PyType_Type;
+	if (PyType_Ready(&EventQueueRef_Type) < 0) return;
+	Py_INCREF(&EventQueueRef_Type);
+	PyModule_AddObject(m, "EventQueueRef", (PyObject *)&EventQueueRef_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&EventQueueRef_Type);
+	PyModule_AddObject(m, "EventQueueRefType", (PyObject *)&EventQueueRef_Type);
+	EventLoopRef_Type.ob_type = &PyType_Type;
+	if (PyType_Ready(&EventLoopRef_Type) < 0) return;
+	Py_INCREF(&EventLoopRef_Type);
+	PyModule_AddObject(m, "EventLoopRef", (PyObject *)&EventLoopRef_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&EventLoopRef_Type);
+	PyModule_AddObject(m, "EventLoopRefType", (PyObject *)&EventLoopRef_Type);
+	EventLoopTimerRef_Type.ob_type = &PyType_Type;
+	if (PyType_Ready(&EventLoopTimerRef_Type) < 0) return;
+	Py_INCREF(&EventLoopTimerRef_Type);
+	PyModule_AddObject(m, "EventLoopTimerRef", (PyObject *)&EventLoopTimerRef_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&EventLoopTimerRef_Type);
+	PyModule_AddObject(m, "EventLoopTimerRefType", (PyObject *)&EventLoopTimerRef_Type);
+	EventHandlerRef_Type.ob_type = &PyType_Type;
+	if (PyType_Ready(&EventHandlerRef_Type) < 0) return;
+	Py_INCREF(&EventHandlerRef_Type);
+	PyModule_AddObject(m, "EventHandlerRef", (PyObject *)&EventHandlerRef_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&EventHandlerRef_Type);
+	PyModule_AddObject(m, "EventHandlerRefType", (PyObject *)&EventHandlerRef_Type);
+	EventHandlerCallRef_Type.ob_type = &PyType_Type;
+	if (PyType_Ready(&EventHandlerCallRef_Type) < 0) return;
+	Py_INCREF(&EventHandlerCallRef_Type);
+	PyModule_AddObject(m, "EventHandlerCallRef", (PyObject *)&EventHandlerCallRef_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&EventHandlerCallRef_Type);
+	PyModule_AddObject(m, "EventHandlerCallRefType", (PyObject *)&EventHandlerCallRef_Type);
+	EventTargetRef_Type.ob_type = &PyType_Type;
+	if (PyType_Ready(&EventTargetRef_Type) < 0) return;
+	Py_INCREF(&EventTargetRef_Type);
+	PyModule_AddObject(m, "EventTargetRef", (PyObject *)&EventTargetRef_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&EventTargetRef_Type);
+	PyModule_AddObject(m, "EventTargetRefType", (PyObject *)&EventTargetRef_Type);
+	EventHotKeyRef_Type.ob_type = &PyType_Type;
+	if (PyType_Ready(&EventHotKeyRef_Type) < 0) return;
+	Py_INCREF(&EventHotKeyRef_Type);
+	PyModule_AddObject(m, "EventHotKeyRef", (PyObject *)&EventHotKeyRef_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&EventHotKeyRef_Type);
+	PyModule_AddObject(m, "EventHotKeyRefType", (PyObject *)&EventHotKeyRef_Type);
+}
+
+/* ===================== End module _CarbonEvt ====================== */
+


Property changes on: vendor/Python/current/Mac/Modules/carbonevt/_CarbonEvtmodule.c
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Mac/Modules/cf/_CFmodule.c
===================================================================
--- vendor/Python/current/Mac/Modules/cf/_CFmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/cf/_CFmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,4995 @@
+
+/* =========================== Module _CF =========================== */
+
+#include "Python.h"
+
+
+
+#include "pymactoolbox.h"
+
+/* Macro to test whether a weak-loaded CFM function exists */
+#define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL )  {\
+        PyErr_SetString(PyExc_NotImplementedError, \
+        "Not available in this shared library/OS version"); \
+        return NULL; \
+    }} while(0)
+
+
+#include <CoreServices/CoreServices.h>
+
+#include "pycfbridge.h"
+
+#ifdef USE_TOOLBOX_OBJECT_GLUE
+extern PyObject *_CFObj_New(CFTypeRef);
+extern int _CFObj_Convert(PyObject *, CFTypeRef *);
+#define CFObj_New _CFObj_New
+#define CFObj_Convert _CFObj_Convert
+
+extern PyObject *_CFTypeRefObj_New(CFTypeRef);
+extern int _CFTypeRefObj_Convert(PyObject *, CFTypeRef *);
+#define CFTypeRefObj_New _CFTypeRefObj_New
+#define CFTypeRefObj_Convert _CFTypeRefObj_Convert
+
+extern PyObject *_CFStringRefObj_New(CFStringRef);
+extern int _CFStringRefObj_Convert(PyObject *, CFStringRef *);
+#define CFStringRefObj_New _CFStringRefObj_New
+#define CFStringRefObj_Convert _CFStringRefObj_Convert
+
+extern PyObject *_CFMutableStringRefObj_New(CFMutableStringRef);
+extern int _CFMutableStringRefObj_Convert(PyObject *, CFMutableStringRef *);
+#define CFMutableStringRefObj_New _CFMutableStringRefObj_New
+#define CFMutableStringRefObj_Convert _CFMutableStringRefObj_Convert
+
+extern PyObject *_CFArrayRefObj_New(CFArrayRef);
+extern int _CFArrayRefObj_Convert(PyObject *, CFArrayRef *);
+#define CFArrayRefObj_New _CFArrayRefObj_New
+#define CFArrayRefObj_Convert _CFArrayRefObj_Convert
+
+extern PyObject *_CFMutableArrayRefObj_New(CFMutableArrayRef);
+extern int _CFMutableArrayRefObj_Convert(PyObject *, CFMutableArrayRef *);
+#define CFMutableArrayRefObj_New _CFMutableArrayRefObj_New
+#define CFMutableArrayRefObj_Convert _CFMutableArrayRefObj_Convert
+
+extern PyObject *_CFDataRefObj_New(CFDataRef);
+extern int _CFDataRefObj_Convert(PyObject *, CFDataRef *);
+#define CFDataRefObj_New _CFDataRefObj_New
+#define CFDataRefObj_Convert _CFDataRefObj_Convert
+
+extern PyObject *_CFMutableDataRefObj_New(CFMutableDataRef);
+extern int _CFMutableDataRefObj_Convert(PyObject *, CFMutableDataRef *);
+#define CFMutableDataRefObj_New _CFMutableDataRefObj_New
+#define CFMutableDataRefObj_Convert _CFMutableDataRefObj_Convert
+
+extern PyObject *_CFDictionaryRefObj_New(CFDictionaryRef);
+extern int _CFDictionaryRefObj_Convert(PyObject *, CFDictionaryRef *);
+#define CFDictionaryRefObj_New _CFDictionaryRefObj_New
+#define CFDictionaryRefObj_Convert _CFDictionaryRefObj_Convert
+
+extern PyObject *_CFMutableDictionaryRefObj_New(CFMutableDictionaryRef);
+extern int _CFMutableDictionaryRefObj_Convert(PyObject *, CFMutableDictionaryRef *);
+#define CFMutableDictionaryRefObj_New _CFMutableDictionaryRefObj_New
+#define CFMutableDictionaryRefObj_Convert _CFMutableDictionaryRefObj_Convert
+
+extern PyObject *_CFURLRefObj_New(CFURLRef);
+extern int _CFURLRefObj_Convert(PyObject *, CFURLRef *);
+extern int _OptionalCFURLRefObj_Convert(PyObject *, CFURLRef *);
+#define CFURLRefObj_New _CFURLRefObj_New
+#define CFURLRefObj_Convert _CFURLRefObj_Convert
+#define OptionalCFURLRefObj_Convert _OptionalCFURLRefObj_Convert
+#endif
+
+/*
+** Parse/generate CFRange records
+*/
+PyObject *CFRange_New(CFRange *itself)
+{
+
+        return Py_BuildValue("ll", (long)itself->location, (long)itself->length);
+}
+
+int
+CFRange_Convert(PyObject *v, CFRange *p_itself)
+{
+        long location, length;
+
+        if( !PyArg_ParseTuple(v, "ll", &location, &length) )
+                return 0;
+        p_itself->location = (CFIndex)location;
+        p_itself->length = (CFIndex)length;
+        return 1;
+}
+
+/* Optional CFURL argument or None (passed as NULL) */
+int
+OptionalCFURLRefObj_Convert(PyObject *v, CFURLRef *p_itself)
+{
+    if ( v == Py_None ) {
+        p_itself = NULL;
+        return 1;
+    }
+    return CFURLRefObj_Convert(v, p_itself);
+}
+
+static PyObject *CF_Error;
+
+/* --------------------- Object type CFTypeRef ---------------------- */
+
+PyTypeObject CFTypeRef_Type;
+
+#define CFTypeRefObj_Check(x) ((x)->ob_type == &CFTypeRef_Type || PyObject_TypeCheck((x), &CFTypeRef_Type))
+
+typedef struct CFTypeRefObject {
+	PyObject_HEAD
+	CFTypeRef ob_itself;
+	void (*ob_freeit)(CFTypeRef ptr);
+} CFTypeRefObject;
+
+PyObject *CFTypeRefObj_New(CFTypeRef itself)
+{
+	CFTypeRefObject *it;
+	if (itself == NULL)
+	{
+		PyErr_SetString(PyExc_RuntimeError, "cannot wrap NULL");
+		return NULL;
+	}
+	it = PyObject_NEW(CFTypeRefObject, &CFTypeRef_Type);
+	if (it == NULL) return NULL;
+	it->ob_itself = itself;
+	it->ob_freeit = CFRelease;
+	return (PyObject *)it;
+}
+
+int CFTypeRefObj_Convert(PyObject *v, CFTypeRef *p_itself)
+{
+
+	if (v == Py_None) { *p_itself = NULL; return 1; }
+	/* Check for other CF objects here */
+
+	if (!CFTypeRefObj_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "CFTypeRef required");
+		return 0;
+	}
+	*p_itself = ((CFTypeRefObject *)v)->ob_itself;
+	return 1;
+}
+
+static void CFTypeRefObj_dealloc(CFTypeRefObject *self)
+{
+	if (self->ob_freeit && self->ob_itself)
+	{
+		self->ob_freeit((CFTypeRef)self->ob_itself);
+		self->ob_itself = NULL;
+	}
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *CFTypeRefObj_CFGetTypeID(CFTypeRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFTypeID _rv;
+#ifndef CFGetTypeID
+	PyMac_PRECHECK(CFGetTypeID);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFGetTypeID(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CFTypeRefObj_CFRetain(CFTypeRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFTypeRef _rv;
+#ifndef CFRetain
+	PyMac_PRECHECK(CFRetain);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFRetain(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     CFTypeRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFTypeRefObj_CFRelease(CFTypeRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef CFRelease
+	PyMac_PRECHECK(CFRelease);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	CFRelease(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CFTypeRefObj_CFGetRetainCount(CFTypeRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFIndex _rv;
+#ifndef CFGetRetainCount
+	PyMac_PRECHECK(CFGetRetainCount);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFGetRetainCount(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CFTypeRefObj_CFEqual(CFTypeRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	CFTypeRef cf2;
+#ifndef CFEqual
+	PyMac_PRECHECK(CFEqual);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CFTypeRefObj_Convert, &cf2))
+		return NULL;
+	_rv = CFEqual(_self->ob_itself,
+	              cf2);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CFTypeRefObj_CFHash(CFTypeRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFHashCode _rv;
+#ifndef CFHash
+	PyMac_PRECHECK(CFHash);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFHash(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CFTypeRefObj_CFCopyDescription(CFTypeRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef _rv;
+#ifndef CFCopyDescription
+	PyMac_PRECHECK(CFCopyDescription);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFCopyDescription(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFTypeRefObj_CFPropertyListCreateXMLData(CFTypeRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFDataRef _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFPropertyListCreateXMLData((CFAllocatorRef)NULL,
+	                                  _self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     CFDataRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFTypeRefObj_CFPropertyListCreateDeepCopy(CFTypeRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFTypeRef _rv;
+	CFOptionFlags mutabilityOption;
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &mutabilityOption))
+		return NULL;
+	_rv = CFPropertyListCreateDeepCopy((CFAllocatorRef)NULL,
+	                                   _self->ob_itself,
+	                                   mutabilityOption);
+	_res = Py_BuildValue("O&",
+	                     CFTypeRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFTypeRefObj_CFShow(CFTypeRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef CFShow
+	PyMac_PRECHECK(CFShow);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	CFShow(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CFTypeRefObj_CFPropertyListCreateFromXMLData(CFTypeRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+
+	CFTypeRef _rv;
+	CFOptionFlags mutabilityOption;
+	CFStringRef errorString;
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &mutabilityOption))
+	        return NULL;
+	_rv = CFPropertyListCreateFromXMLData((CFAllocatorRef)NULL,
+	                                      _self->ob_itself,
+	                                      mutabilityOption,
+	                                      &errorString);
+	if (errorString)
+	        CFRelease(errorString);
+	if (_rv == NULL) {
+	        PyErr_SetString(PyExc_RuntimeError, "Parse error in XML data");
+	        return NULL;
+	}
+	_res = Py_BuildValue("O&",
+	                     CFTypeRefObj_New, _rv);
+	return _res;
+
+}
+
+static PyObject *CFTypeRefObj_toPython(CFTypeRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+
+	_res = PyCF_CF2Python(_self->ob_itself);
+	return _res;
+
+}
+
+static PyMethodDef CFTypeRefObj_methods[] = {
+	{"CFGetTypeID", (PyCFunction)CFTypeRefObj_CFGetTypeID, 1,
+	 PyDoc_STR("() -> (CFTypeID _rv)")},
+	{"CFRetain", (PyCFunction)CFTypeRefObj_CFRetain, 1,
+	 PyDoc_STR("() -> (CFTypeRef _rv)")},
+	{"CFRelease", (PyCFunction)CFTypeRefObj_CFRelease, 1,
+	 PyDoc_STR("() -> None")},
+	{"CFGetRetainCount", (PyCFunction)CFTypeRefObj_CFGetRetainCount, 1,
+	 PyDoc_STR("() -> (CFIndex _rv)")},
+	{"CFEqual", (PyCFunction)CFTypeRefObj_CFEqual, 1,
+	 PyDoc_STR("(CFTypeRef cf2) -> (Boolean _rv)")},
+	{"CFHash", (PyCFunction)CFTypeRefObj_CFHash, 1,
+	 PyDoc_STR("() -> (CFHashCode _rv)")},
+	{"CFCopyDescription", (PyCFunction)CFTypeRefObj_CFCopyDescription, 1,
+	 PyDoc_STR("() -> (CFStringRef _rv)")},
+	{"CFPropertyListCreateXMLData", (PyCFunction)CFTypeRefObj_CFPropertyListCreateXMLData, 1,
+	 PyDoc_STR("() -> (CFDataRef _rv)")},
+	{"CFPropertyListCreateDeepCopy", (PyCFunction)CFTypeRefObj_CFPropertyListCreateDeepCopy, 1,
+	 PyDoc_STR("(CFOptionFlags mutabilityOption) -> (CFTypeRef _rv)")},
+	{"CFShow", (PyCFunction)CFTypeRefObj_CFShow, 1,
+	 PyDoc_STR("() -> None")},
+	{"CFPropertyListCreateFromXMLData", (PyCFunction)CFTypeRefObj_CFPropertyListCreateFromXMLData, 1,
+	 PyDoc_STR("(CFOptionFlags mutabilityOption) -> (CFTypeRefObj)")},
+	{"toPython", (PyCFunction)CFTypeRefObj_toPython, 1,
+	 PyDoc_STR("() -> (python_object)")},
+	{NULL, NULL, 0}
+};
+
+#define CFTypeRefObj_getsetlist NULL
+
+
+static int CFTypeRefObj_compare(CFTypeRefObject *self, CFTypeRefObject *other)
+{
+	/* XXXX Or should we use CFEqual?? */
+	if ( self->ob_itself > other->ob_itself ) return 1;
+	if ( self->ob_itself < other->ob_itself ) return -1;
+	return 0;
+}
+
+static PyObject * CFTypeRefObj_repr(CFTypeRefObject *self)
+{
+	char buf[100];
+	sprintf(buf, "<CFTypeRef type-%d object at 0x%8.8x for 0x%8.8x>", (int)CFGetTypeID(self->ob_itself), (unsigned)self, (unsigned)self->ob_itself);
+	return PyString_FromString(buf);
+}
+
+static int CFTypeRefObj_hash(CFTypeRefObject *self)
+{
+	/* XXXX Or should we use CFHash?? */
+	return (int)self->ob_itself;
+}
+static int CFTypeRefObj_tp_init(PyObject *_self, PyObject *_args, PyObject *_kwds)
+{
+	CFTypeRef itself;
+	char *kw[] = {"itself", 0};
+
+	if (PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, CFTypeRefObj_Convert, &itself))
+	{
+		((CFTypeRefObject *)_self)->ob_itself = itself;
+		return 0;
+	}
+	return -1;
+}
+
+#define CFTypeRefObj_tp_alloc PyType_GenericAlloc
+
+static PyObject *CFTypeRefObj_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *self;
+	if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	((CFTypeRefObject *)self)->ob_itself = NULL;
+	((CFTypeRefObject *)self)->ob_freeit = CFRelease;
+	return self;
+}
+
+#define CFTypeRefObj_tp_free PyObject_Del
+
+
+PyTypeObject CFTypeRef_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"_CF.CFTypeRef", /*tp_name*/
+	sizeof(CFTypeRefObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) CFTypeRefObj_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) CFTypeRefObj_compare, /*tp_compare*/
+	(reprfunc) CFTypeRefObj_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) CFTypeRefObj_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	CFTypeRefObj_methods, /* tp_methods */
+	0, /*tp_members*/
+	CFTypeRefObj_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	CFTypeRefObj_tp_init, /* tp_init */
+	CFTypeRefObj_tp_alloc, /* tp_alloc */
+	CFTypeRefObj_tp_new, /* tp_new */
+	CFTypeRefObj_tp_free, /* tp_free */
+};
+
+/* ------------------- End object type CFTypeRef -------------------- */
+
+
+/* --------------------- Object type CFArrayRef --------------------- */
+
+PyTypeObject CFArrayRef_Type;
+
+#define CFArrayRefObj_Check(x) ((x)->ob_type == &CFArrayRef_Type || PyObject_TypeCheck((x), &CFArrayRef_Type))
+
+typedef struct CFArrayRefObject {
+	PyObject_HEAD
+	CFArrayRef ob_itself;
+	void (*ob_freeit)(CFTypeRef ptr);
+} CFArrayRefObject;
+
+PyObject *CFArrayRefObj_New(CFArrayRef itself)
+{
+	CFArrayRefObject *it;
+	if (itself == NULL)
+	{
+		PyErr_SetString(PyExc_RuntimeError, "cannot wrap NULL");
+		return NULL;
+	}
+	it = PyObject_NEW(CFArrayRefObject, &CFArrayRef_Type);
+	if (it == NULL) return NULL;
+	/* XXXX Should we tp_init or tp_new our basetype? */
+	it->ob_itself = itself;
+	it->ob_freeit = CFRelease;
+	return (PyObject *)it;
+}
+
+int CFArrayRefObj_Convert(PyObject *v, CFArrayRef *p_itself)
+{
+
+	if (v == Py_None) { *p_itself = NULL; return 1; }
+	/* Check for other CF objects here */
+
+	if (!CFArrayRefObj_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "CFArrayRef required");
+		return 0;
+	}
+	*p_itself = ((CFArrayRefObject *)v)->ob_itself;
+	return 1;
+}
+
+static void CFArrayRefObj_dealloc(CFArrayRefObject *self)
+{
+	if (self->ob_freeit && self->ob_itself)
+	{
+		self->ob_freeit((CFTypeRef)self->ob_itself);
+		self->ob_itself = NULL;
+	}
+	CFTypeRef_Type.tp_dealloc((PyObject *)self);
+}
+
+static PyObject *CFArrayRefObj_CFArrayCreateCopy(CFArrayRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFArrayRef _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFArrayCreateCopy((CFAllocatorRef)NULL,
+	                        _self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     CFArrayRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFArrayRefObj_CFArrayGetCount(CFArrayRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFIndex _rv;
+#ifndef CFArrayGetCount
+	PyMac_PRECHECK(CFArrayGetCount);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFArrayGetCount(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CFArrayRefObj_CFStringCreateByCombiningStrings(CFArrayRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef _rv;
+	CFStringRef separatorString;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CFStringRefObj_Convert, &separatorString))
+		return NULL;
+	_rv = CFStringCreateByCombiningStrings((CFAllocatorRef)NULL,
+	                                       _self->ob_itself,
+	                                       separatorString);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, _rv);
+	return _res;
+}
+
+static PyMethodDef CFArrayRefObj_methods[] = {
+	{"CFArrayCreateCopy", (PyCFunction)CFArrayRefObj_CFArrayCreateCopy, 1,
+	 PyDoc_STR("() -> (CFArrayRef _rv)")},
+	{"CFArrayGetCount", (PyCFunction)CFArrayRefObj_CFArrayGetCount, 1,
+	 PyDoc_STR("() -> (CFIndex _rv)")},
+	{"CFStringCreateByCombiningStrings", (PyCFunction)CFArrayRefObj_CFStringCreateByCombiningStrings, 1,
+	 PyDoc_STR("(CFStringRef separatorString) -> (CFStringRef _rv)")},
+	{NULL, NULL, 0}
+};
+
+#define CFArrayRefObj_getsetlist NULL
+
+
+static int CFArrayRefObj_compare(CFArrayRefObject *self, CFArrayRefObject *other)
+{
+	/* XXXX Or should we use CFEqual?? */
+	if ( self->ob_itself > other->ob_itself ) return 1;
+	if ( self->ob_itself < other->ob_itself ) return -1;
+	return 0;
+}
+
+static PyObject * CFArrayRefObj_repr(CFArrayRefObject *self)
+{
+	char buf[100];
+	sprintf(buf, "<CFArrayRef object at 0x%8.8x for 0x%8.8x>", (unsigned)self, (unsigned)self->ob_itself);
+	return PyString_FromString(buf);
+}
+
+static int CFArrayRefObj_hash(CFArrayRefObject *self)
+{
+	/* XXXX Or should we use CFHash?? */
+	return (int)self->ob_itself;
+}
+static int CFArrayRefObj_tp_init(PyObject *_self, PyObject *_args, PyObject *_kwds)
+{
+	CFArrayRef itself;
+	char *kw[] = {"itself", 0};
+
+	if (PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, CFArrayRefObj_Convert, &itself))
+	{
+		((CFArrayRefObject *)_self)->ob_itself = itself;
+		return 0;
+	}
+
+	/* Any CFTypeRef descendent is allowed as initializer too */
+	if (PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, CFTypeRefObj_Convert, &itself))
+	{
+		((CFArrayRefObject *)_self)->ob_itself = itself;
+		return 0;
+	}
+	return -1;
+}
+
+#define CFArrayRefObj_tp_alloc PyType_GenericAlloc
+
+static PyObject *CFArrayRefObj_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *self;
+	if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	((CFArrayRefObject *)self)->ob_itself = NULL;
+	((CFArrayRefObject *)self)->ob_freeit = CFRelease;
+	return self;
+}
+
+#define CFArrayRefObj_tp_free PyObject_Del
+
+
+PyTypeObject CFArrayRef_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"_CF.CFArrayRef", /*tp_name*/
+	sizeof(CFArrayRefObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) CFArrayRefObj_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) CFArrayRefObj_compare, /*tp_compare*/
+	(reprfunc) CFArrayRefObj_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) CFArrayRefObj_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	CFArrayRefObj_methods, /* tp_methods */
+	0, /*tp_members*/
+	CFArrayRefObj_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	CFArrayRefObj_tp_init, /* tp_init */
+	CFArrayRefObj_tp_alloc, /* tp_alloc */
+	CFArrayRefObj_tp_new, /* tp_new */
+	CFArrayRefObj_tp_free, /* tp_free */
+};
+
+/* ------------------- End object type CFArrayRef ------------------- */
+
+
+/* ----------------- Object type CFMutableArrayRef ------------------ */
+
+PyTypeObject CFMutableArrayRef_Type;
+
+#define CFMutableArrayRefObj_Check(x) ((x)->ob_type == &CFMutableArrayRef_Type || PyObject_TypeCheck((x), &CFMutableArrayRef_Type))
+
+typedef struct CFMutableArrayRefObject {
+	PyObject_HEAD
+	CFMutableArrayRef ob_itself;
+	void (*ob_freeit)(CFTypeRef ptr);
+} CFMutableArrayRefObject;
+
+PyObject *CFMutableArrayRefObj_New(CFMutableArrayRef itself)
+{
+	CFMutableArrayRefObject *it;
+	if (itself == NULL)
+	{
+		PyErr_SetString(PyExc_RuntimeError, "cannot wrap NULL");
+		return NULL;
+	}
+	it = PyObject_NEW(CFMutableArrayRefObject, &CFMutableArrayRef_Type);
+	if (it == NULL) return NULL;
+	/* XXXX Should we tp_init or tp_new our basetype? */
+	it->ob_itself = itself;
+	it->ob_freeit = CFRelease;
+	return (PyObject *)it;
+}
+
+int CFMutableArrayRefObj_Convert(PyObject *v, CFMutableArrayRef *p_itself)
+{
+
+	if (v == Py_None) { *p_itself = NULL; return 1; }
+	/* Check for other CF objects here */
+
+	if (!CFMutableArrayRefObj_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "CFMutableArrayRef required");
+		return 0;
+	}
+	*p_itself = ((CFMutableArrayRefObject *)v)->ob_itself;
+	return 1;
+}
+
+static void CFMutableArrayRefObj_dealloc(CFMutableArrayRefObject *self)
+{
+	if (self->ob_freeit && self->ob_itself)
+	{
+		self->ob_freeit((CFTypeRef)self->ob_itself);
+		self->ob_itself = NULL;
+	}
+	CFArrayRef_Type.tp_dealloc((PyObject *)self);
+}
+
+static PyObject *CFMutableArrayRefObj_CFArrayRemoveValueAtIndex(CFMutableArrayRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFIndex idx;
+#ifndef CFArrayRemoveValueAtIndex
+	PyMac_PRECHECK(CFArrayRemoveValueAtIndex);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &idx))
+		return NULL;
+	CFArrayRemoveValueAtIndex(_self->ob_itself,
+	                          idx);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CFMutableArrayRefObj_CFArrayRemoveAllValues(CFMutableArrayRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef CFArrayRemoveAllValues
+	PyMac_PRECHECK(CFArrayRemoveAllValues);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	CFArrayRemoveAllValues(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CFMutableArrayRefObj_CFArrayExchangeValuesAtIndices(CFMutableArrayRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFIndex idx1;
+	CFIndex idx2;
+#ifndef CFArrayExchangeValuesAtIndices
+	PyMac_PRECHECK(CFArrayExchangeValuesAtIndices);
+#endif
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &idx1,
+	                      &idx2))
+		return NULL;
+	CFArrayExchangeValuesAtIndices(_self->ob_itself,
+	                               idx1,
+	                               idx2);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CFMutableArrayRefObj_CFArrayAppendArray(CFMutableArrayRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFArrayRef otherArray;
+	CFRange otherRange;
+#ifndef CFArrayAppendArray
+	PyMac_PRECHECK(CFArrayAppendArray);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CFArrayRefObj_Convert, &otherArray,
+	                      CFRange_Convert, &otherRange))
+		return NULL;
+	CFArrayAppendArray(_self->ob_itself,
+	                   otherArray,
+	                   otherRange);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyMethodDef CFMutableArrayRefObj_methods[] = {
+	{"CFArrayRemoveValueAtIndex", (PyCFunction)CFMutableArrayRefObj_CFArrayRemoveValueAtIndex, 1,
+	 PyDoc_STR("(CFIndex idx) -> None")},
+	{"CFArrayRemoveAllValues", (PyCFunction)CFMutableArrayRefObj_CFArrayRemoveAllValues, 1,
+	 PyDoc_STR("() -> None")},
+	{"CFArrayExchangeValuesAtIndices", (PyCFunction)CFMutableArrayRefObj_CFArrayExchangeValuesAtIndices, 1,
+	 PyDoc_STR("(CFIndex idx1, CFIndex idx2) -> None")},
+	{"CFArrayAppendArray", (PyCFunction)CFMutableArrayRefObj_CFArrayAppendArray, 1,
+	 PyDoc_STR("(CFArrayRef otherArray, CFRange otherRange) -> None")},
+	{NULL, NULL, 0}
+};
+
+#define CFMutableArrayRefObj_getsetlist NULL
+
+
+static int CFMutableArrayRefObj_compare(CFMutableArrayRefObject *self, CFMutableArrayRefObject *other)
+{
+	/* XXXX Or should we use CFEqual?? */
+	if ( self->ob_itself > other->ob_itself ) return 1;
+	if ( self->ob_itself < other->ob_itself ) return -1;
+	return 0;
+}
+
+static PyObject * CFMutableArrayRefObj_repr(CFMutableArrayRefObject *self)
+{
+	char buf[100];
+	sprintf(buf, "<CFMutableArrayRef object at 0x%8.8x for 0x%8.8x>", (unsigned)self, (unsigned)self->ob_itself);
+	return PyString_FromString(buf);
+}
+
+static int CFMutableArrayRefObj_hash(CFMutableArrayRefObject *self)
+{
+	/* XXXX Or should we use CFHash?? */
+	return (int)self->ob_itself;
+}
+static int CFMutableArrayRefObj_tp_init(PyObject *_self, PyObject *_args, PyObject *_kwds)
+{
+	CFMutableArrayRef itself;
+	char *kw[] = {"itself", 0};
+
+	if (PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, CFMutableArrayRefObj_Convert, &itself))
+	{
+		((CFMutableArrayRefObject *)_self)->ob_itself = itself;
+		return 0;
+	}
+
+	/* Any CFTypeRef descendent is allowed as initializer too */
+	if (PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, CFTypeRefObj_Convert, &itself))
+	{
+		((CFMutableArrayRefObject *)_self)->ob_itself = itself;
+		return 0;
+	}
+	return -1;
+}
+
+#define CFMutableArrayRefObj_tp_alloc PyType_GenericAlloc
+
+static PyObject *CFMutableArrayRefObj_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *self;
+	if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	((CFMutableArrayRefObject *)self)->ob_itself = NULL;
+	((CFMutableArrayRefObject *)self)->ob_freeit = CFRelease;
+	return self;
+}
+
+#define CFMutableArrayRefObj_tp_free PyObject_Del
+
+
+PyTypeObject CFMutableArrayRef_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"_CF.CFMutableArrayRef", /*tp_name*/
+	sizeof(CFMutableArrayRefObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) CFMutableArrayRefObj_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) CFMutableArrayRefObj_compare, /*tp_compare*/
+	(reprfunc) CFMutableArrayRefObj_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) CFMutableArrayRefObj_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	CFMutableArrayRefObj_methods, /* tp_methods */
+	0, /*tp_members*/
+	CFMutableArrayRefObj_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	CFMutableArrayRefObj_tp_init, /* tp_init */
+	CFMutableArrayRefObj_tp_alloc, /* tp_alloc */
+	CFMutableArrayRefObj_tp_new, /* tp_new */
+	CFMutableArrayRefObj_tp_free, /* tp_free */
+};
+
+/* --------------- End object type CFMutableArrayRef ---------------- */
+
+
+/* ------------------ Object type CFDictionaryRef ------------------- */
+
+PyTypeObject CFDictionaryRef_Type;
+
+#define CFDictionaryRefObj_Check(x) ((x)->ob_type == &CFDictionaryRef_Type || PyObject_TypeCheck((x), &CFDictionaryRef_Type))
+
+typedef struct CFDictionaryRefObject {
+	PyObject_HEAD
+	CFDictionaryRef ob_itself;
+	void (*ob_freeit)(CFTypeRef ptr);
+} CFDictionaryRefObject;
+
+PyObject *CFDictionaryRefObj_New(CFDictionaryRef itself)
+{
+	CFDictionaryRefObject *it;
+	if (itself == NULL)
+	{
+		PyErr_SetString(PyExc_RuntimeError, "cannot wrap NULL");
+		return NULL;
+	}
+	it = PyObject_NEW(CFDictionaryRefObject, &CFDictionaryRef_Type);
+	if (it == NULL) return NULL;
+	/* XXXX Should we tp_init or tp_new our basetype? */
+	it->ob_itself = itself;
+	it->ob_freeit = CFRelease;
+	return (PyObject *)it;
+}
+
+int CFDictionaryRefObj_Convert(PyObject *v, CFDictionaryRef *p_itself)
+{
+
+	if (v == Py_None) { *p_itself = NULL; return 1; }
+	/* Check for other CF objects here */
+
+	if (!CFDictionaryRefObj_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "CFDictionaryRef required");
+		return 0;
+	}
+	*p_itself = ((CFDictionaryRefObject *)v)->ob_itself;
+	return 1;
+}
+
+static void CFDictionaryRefObj_dealloc(CFDictionaryRefObject *self)
+{
+	if (self->ob_freeit && self->ob_itself)
+	{
+		self->ob_freeit((CFTypeRef)self->ob_itself);
+		self->ob_itself = NULL;
+	}
+	CFTypeRef_Type.tp_dealloc((PyObject *)self);
+}
+
+static PyObject *CFDictionaryRefObj_CFDictionaryCreateCopy(CFDictionaryRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFDictionaryRef _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFDictionaryCreateCopy((CFAllocatorRef)NULL,
+	                             _self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     CFDictionaryRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFDictionaryRefObj_CFDictionaryGetCount(CFDictionaryRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFIndex _rv;
+#ifndef CFDictionaryGetCount
+	PyMac_PRECHECK(CFDictionaryGetCount);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFDictionaryGetCount(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyMethodDef CFDictionaryRefObj_methods[] = {
+	{"CFDictionaryCreateCopy", (PyCFunction)CFDictionaryRefObj_CFDictionaryCreateCopy, 1,
+	 PyDoc_STR("() -> (CFDictionaryRef _rv)")},
+	{"CFDictionaryGetCount", (PyCFunction)CFDictionaryRefObj_CFDictionaryGetCount, 1,
+	 PyDoc_STR("() -> (CFIndex _rv)")},
+	{NULL, NULL, 0}
+};
+
+#define CFDictionaryRefObj_getsetlist NULL
+
+
+static int CFDictionaryRefObj_compare(CFDictionaryRefObject *self, CFDictionaryRefObject *other)
+{
+	/* XXXX Or should we use CFEqual?? */
+	if ( self->ob_itself > other->ob_itself ) return 1;
+	if ( self->ob_itself < other->ob_itself ) return -1;
+	return 0;
+}
+
+static PyObject * CFDictionaryRefObj_repr(CFDictionaryRefObject *self)
+{
+	char buf[100];
+	sprintf(buf, "<CFDictionaryRef object at 0x%8.8x for 0x%8.8x>", (unsigned)self, (unsigned)self->ob_itself);
+	return PyString_FromString(buf);
+}
+
+static int CFDictionaryRefObj_hash(CFDictionaryRefObject *self)
+{
+	/* XXXX Or should we use CFHash?? */
+	return (int)self->ob_itself;
+}
+static int CFDictionaryRefObj_tp_init(PyObject *_self, PyObject *_args, PyObject *_kwds)
+{
+	CFDictionaryRef itself;
+	char *kw[] = {"itself", 0};
+
+	if (PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, CFDictionaryRefObj_Convert, &itself))
+	{
+		((CFDictionaryRefObject *)_self)->ob_itself = itself;
+		return 0;
+	}
+
+	/* Any CFTypeRef descendent is allowed as initializer too */
+	if (PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, CFTypeRefObj_Convert, &itself))
+	{
+		((CFDictionaryRefObject *)_self)->ob_itself = itself;
+		return 0;
+	}
+	return -1;
+}
+
+#define CFDictionaryRefObj_tp_alloc PyType_GenericAlloc
+
+static PyObject *CFDictionaryRefObj_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *self;
+	if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	((CFDictionaryRefObject *)self)->ob_itself = NULL;
+	((CFDictionaryRefObject *)self)->ob_freeit = CFRelease;
+	return self;
+}
+
+#define CFDictionaryRefObj_tp_free PyObject_Del
+
+
+PyTypeObject CFDictionaryRef_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"_CF.CFDictionaryRef", /*tp_name*/
+	sizeof(CFDictionaryRefObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) CFDictionaryRefObj_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) CFDictionaryRefObj_compare, /*tp_compare*/
+	(reprfunc) CFDictionaryRefObj_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) CFDictionaryRefObj_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	CFDictionaryRefObj_methods, /* tp_methods */
+	0, /*tp_members*/
+	CFDictionaryRefObj_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	CFDictionaryRefObj_tp_init, /* tp_init */
+	CFDictionaryRefObj_tp_alloc, /* tp_alloc */
+	CFDictionaryRefObj_tp_new, /* tp_new */
+	CFDictionaryRefObj_tp_free, /* tp_free */
+};
+
+/* ---------------- End object type CFDictionaryRef ----------------- */
+
+
+/* --------------- Object type CFMutableDictionaryRef --------------- */
+
+PyTypeObject CFMutableDictionaryRef_Type;
+
+#define CFMutableDictionaryRefObj_Check(x) ((x)->ob_type == &CFMutableDictionaryRef_Type || PyObject_TypeCheck((x), &CFMutableDictionaryRef_Type))
+
+typedef struct CFMutableDictionaryRefObject {
+	PyObject_HEAD
+	CFMutableDictionaryRef ob_itself;
+	void (*ob_freeit)(CFTypeRef ptr);
+} CFMutableDictionaryRefObject;
+
+PyObject *CFMutableDictionaryRefObj_New(CFMutableDictionaryRef itself)
+{
+	CFMutableDictionaryRefObject *it;
+	if (itself == NULL)
+	{
+		PyErr_SetString(PyExc_RuntimeError, "cannot wrap NULL");
+		return NULL;
+	}
+	it = PyObject_NEW(CFMutableDictionaryRefObject, &CFMutableDictionaryRef_Type);
+	if (it == NULL) return NULL;
+	/* XXXX Should we tp_init or tp_new our basetype? */
+	it->ob_itself = itself;
+	it->ob_freeit = CFRelease;
+	return (PyObject *)it;
+}
+
+int CFMutableDictionaryRefObj_Convert(PyObject *v, CFMutableDictionaryRef *p_itself)
+{
+
+	if (v == Py_None) { *p_itself = NULL; return 1; }
+	/* Check for other CF objects here */
+
+	if (!CFMutableDictionaryRefObj_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "CFMutableDictionaryRef required");
+		return 0;
+	}
+	*p_itself = ((CFMutableDictionaryRefObject *)v)->ob_itself;
+	return 1;
+}
+
+static void CFMutableDictionaryRefObj_dealloc(CFMutableDictionaryRefObject *self)
+{
+	if (self->ob_freeit && self->ob_itself)
+	{
+		self->ob_freeit((CFTypeRef)self->ob_itself);
+		self->ob_itself = NULL;
+	}
+	CFDictionaryRef_Type.tp_dealloc((PyObject *)self);
+}
+
+static PyObject *CFMutableDictionaryRefObj_CFDictionaryRemoveAllValues(CFMutableDictionaryRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef CFDictionaryRemoveAllValues
+	PyMac_PRECHECK(CFDictionaryRemoveAllValues);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	CFDictionaryRemoveAllValues(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyMethodDef CFMutableDictionaryRefObj_methods[] = {
+	{"CFDictionaryRemoveAllValues", (PyCFunction)CFMutableDictionaryRefObj_CFDictionaryRemoveAllValues, 1,
+	 PyDoc_STR("() -> None")},
+	{NULL, NULL, 0}
+};
+
+#define CFMutableDictionaryRefObj_getsetlist NULL
+
+
+static int CFMutableDictionaryRefObj_compare(CFMutableDictionaryRefObject *self, CFMutableDictionaryRefObject *other)
+{
+	/* XXXX Or should we use CFEqual?? */
+	if ( self->ob_itself > other->ob_itself ) return 1;
+	if ( self->ob_itself < other->ob_itself ) return -1;
+	return 0;
+}
+
+static PyObject * CFMutableDictionaryRefObj_repr(CFMutableDictionaryRefObject *self)
+{
+	char buf[100];
+	sprintf(buf, "<CFMutableDictionaryRef object at 0x%8.8x for 0x%8.8x>", (unsigned)self, (unsigned)self->ob_itself);
+	return PyString_FromString(buf);
+}
+
+static int CFMutableDictionaryRefObj_hash(CFMutableDictionaryRefObject *self)
+{
+	/* XXXX Or should we use CFHash?? */
+	return (int)self->ob_itself;
+}
+static int CFMutableDictionaryRefObj_tp_init(PyObject *_self, PyObject *_args, PyObject *_kwds)
+{
+	CFMutableDictionaryRef itself;
+	char *kw[] = {"itself", 0};
+
+	if (PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, CFMutableDictionaryRefObj_Convert, &itself))
+	{
+		((CFMutableDictionaryRefObject *)_self)->ob_itself = itself;
+		return 0;
+	}
+
+	/* Any CFTypeRef descendent is allowed as initializer too */
+	if (PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, CFTypeRefObj_Convert, &itself))
+	{
+		((CFMutableDictionaryRefObject *)_self)->ob_itself = itself;
+		return 0;
+	}
+	return -1;
+}
+
+#define CFMutableDictionaryRefObj_tp_alloc PyType_GenericAlloc
+
+static PyObject *CFMutableDictionaryRefObj_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *self;
+	if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	((CFMutableDictionaryRefObject *)self)->ob_itself = NULL;
+	((CFMutableDictionaryRefObject *)self)->ob_freeit = CFRelease;
+	return self;
+}
+
+#define CFMutableDictionaryRefObj_tp_free PyObject_Del
+
+
+PyTypeObject CFMutableDictionaryRef_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"_CF.CFMutableDictionaryRef", /*tp_name*/
+	sizeof(CFMutableDictionaryRefObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) CFMutableDictionaryRefObj_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) CFMutableDictionaryRefObj_compare, /*tp_compare*/
+	(reprfunc) CFMutableDictionaryRefObj_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) CFMutableDictionaryRefObj_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	CFMutableDictionaryRefObj_methods, /* tp_methods */
+	0, /*tp_members*/
+	CFMutableDictionaryRefObj_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	CFMutableDictionaryRefObj_tp_init, /* tp_init */
+	CFMutableDictionaryRefObj_tp_alloc, /* tp_alloc */
+	CFMutableDictionaryRefObj_tp_new, /* tp_new */
+	CFMutableDictionaryRefObj_tp_free, /* tp_free */
+};
+
+/* ------------- End object type CFMutableDictionaryRef ------------- */
+
+
+/* --------------------- Object type CFDataRef ---------------------- */
+
+PyTypeObject CFDataRef_Type;
+
+#define CFDataRefObj_Check(x) ((x)->ob_type == &CFDataRef_Type || PyObject_TypeCheck((x), &CFDataRef_Type))
+
+typedef struct CFDataRefObject {
+	PyObject_HEAD
+	CFDataRef ob_itself;
+	void (*ob_freeit)(CFTypeRef ptr);
+} CFDataRefObject;
+
+PyObject *CFDataRefObj_New(CFDataRef itself)
+{
+	CFDataRefObject *it;
+	if (itself == NULL)
+	{
+		PyErr_SetString(PyExc_RuntimeError, "cannot wrap NULL");
+		return NULL;
+	}
+	it = PyObject_NEW(CFDataRefObject, &CFDataRef_Type);
+	if (it == NULL) return NULL;
+	/* XXXX Should we tp_init or tp_new our basetype? */
+	it->ob_itself = itself;
+	it->ob_freeit = CFRelease;
+	return (PyObject *)it;
+}
+
+int CFDataRefObj_Convert(PyObject *v, CFDataRef *p_itself)
+{
+
+	if (v == Py_None) { *p_itself = NULL; return 1; }
+	if (PyString_Check(v)) {
+	    char *cStr;
+	    Py_ssize_t cLen;
+	    if( PyString_AsStringAndSize(v, &cStr, &cLen) < 0 ) return 0;
+	    *p_itself = CFDataCreate((CFAllocatorRef)NULL, (unsigned char *)cStr, cLen);
+	    return 1;
+	}
+
+	if (!CFDataRefObj_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "CFDataRef required");
+		return 0;
+	}
+	*p_itself = ((CFDataRefObject *)v)->ob_itself;
+	return 1;
+}
+
+static void CFDataRefObj_dealloc(CFDataRefObject *self)
+{
+	if (self->ob_freeit && self->ob_itself)
+	{
+		self->ob_freeit((CFTypeRef)self->ob_itself);
+		self->ob_itself = NULL;
+	}
+	CFTypeRef_Type.tp_dealloc((PyObject *)self);
+}
+
+static PyObject *CFDataRefObj_CFDataCreateCopy(CFDataRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFDataRef _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFDataCreateCopy((CFAllocatorRef)NULL,
+	                       _self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     CFDataRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFDataRefObj_CFDataGetLength(CFDataRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFIndex _rv;
+#ifndef CFDataGetLength
+	PyMac_PRECHECK(CFDataGetLength);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFDataGetLength(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CFDataRefObj_CFStringCreateFromExternalRepresentation(CFDataRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef _rv;
+	CFStringEncoding encoding;
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &encoding))
+		return NULL;
+	_rv = CFStringCreateFromExternalRepresentation((CFAllocatorRef)NULL,
+	                                               _self->ob_itself,
+	                                               encoding);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFDataRefObj_CFDataGetData(CFDataRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+
+	int size = CFDataGetLength(_self->ob_itself);
+	char *data = (char *)CFDataGetBytePtr(_self->ob_itself);
+
+	_res = (PyObject *)PyString_FromStringAndSize(data, size);
+	return _res;
+
+}
+
+static PyMethodDef CFDataRefObj_methods[] = {
+	{"CFDataCreateCopy", (PyCFunction)CFDataRefObj_CFDataCreateCopy, 1,
+	 PyDoc_STR("() -> (CFDataRef _rv)")},
+	{"CFDataGetLength", (PyCFunction)CFDataRefObj_CFDataGetLength, 1,
+	 PyDoc_STR("() -> (CFIndex _rv)")},
+	{"CFStringCreateFromExternalRepresentation", (PyCFunction)CFDataRefObj_CFStringCreateFromExternalRepresentation, 1,
+	 PyDoc_STR("(CFStringEncoding encoding) -> (CFStringRef _rv)")},
+	{"CFDataGetData", (PyCFunction)CFDataRefObj_CFDataGetData, 1,
+	 PyDoc_STR("() -> (string _rv)")},
+	{NULL, NULL, 0}
+};
+
+#define CFDataRefObj_getsetlist NULL
+
+
+static int CFDataRefObj_compare(CFDataRefObject *self, CFDataRefObject *other)
+{
+	/* XXXX Or should we use CFEqual?? */
+	if ( self->ob_itself > other->ob_itself ) return 1;
+	if ( self->ob_itself < other->ob_itself ) return -1;
+	return 0;
+}
+
+static PyObject * CFDataRefObj_repr(CFDataRefObject *self)
+{
+	char buf[100];
+	sprintf(buf, "<CFDataRef object at 0x%8.8x for 0x%8.8x>", (unsigned)self, (unsigned)self->ob_itself);
+	return PyString_FromString(buf);
+}
+
+static int CFDataRefObj_hash(CFDataRefObject *self)
+{
+	/* XXXX Or should we use CFHash?? */
+	return (int)self->ob_itself;
+}
+static int CFDataRefObj_tp_init(PyObject *_self, PyObject *_args, PyObject *_kwds)
+{
+	CFDataRef itself;
+	char *kw[] = {"itself", 0};
+
+	if (PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, CFDataRefObj_Convert, &itself))
+	{
+		((CFDataRefObject *)_self)->ob_itself = itself;
+		return 0;
+	}
+
+	/* Any CFTypeRef descendent is allowed as initializer too */
+	if (PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, CFTypeRefObj_Convert, &itself))
+	{
+		((CFDataRefObject *)_self)->ob_itself = itself;
+		return 0;
+	}
+	return -1;
+}
+
+#define CFDataRefObj_tp_alloc PyType_GenericAlloc
+
+static PyObject *CFDataRefObj_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *self;
+	if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	((CFDataRefObject *)self)->ob_itself = NULL;
+	((CFDataRefObject *)self)->ob_freeit = CFRelease;
+	return self;
+}
+
+#define CFDataRefObj_tp_free PyObject_Del
+
+
+PyTypeObject CFDataRef_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"_CF.CFDataRef", /*tp_name*/
+	sizeof(CFDataRefObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) CFDataRefObj_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) CFDataRefObj_compare, /*tp_compare*/
+	(reprfunc) CFDataRefObj_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) CFDataRefObj_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	CFDataRefObj_methods, /* tp_methods */
+	0, /*tp_members*/
+	CFDataRefObj_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	CFDataRefObj_tp_init, /* tp_init */
+	CFDataRefObj_tp_alloc, /* tp_alloc */
+	CFDataRefObj_tp_new, /* tp_new */
+	CFDataRefObj_tp_free, /* tp_free */
+};
+
+/* ------------------- End object type CFDataRef -------------------- */
+
+
+/* ------------------ Object type CFMutableDataRef ------------------ */
+
+PyTypeObject CFMutableDataRef_Type;
+
+#define CFMutableDataRefObj_Check(x) ((x)->ob_type == &CFMutableDataRef_Type || PyObject_TypeCheck((x), &CFMutableDataRef_Type))
+
+typedef struct CFMutableDataRefObject {
+	PyObject_HEAD
+	CFMutableDataRef ob_itself;
+	void (*ob_freeit)(CFTypeRef ptr);
+} CFMutableDataRefObject;
+
+PyObject *CFMutableDataRefObj_New(CFMutableDataRef itself)
+{
+	CFMutableDataRefObject *it;
+	if (itself == NULL)
+	{
+		PyErr_SetString(PyExc_RuntimeError, "cannot wrap NULL");
+		return NULL;
+	}
+	it = PyObject_NEW(CFMutableDataRefObject, &CFMutableDataRef_Type);
+	if (it == NULL) return NULL;
+	/* XXXX Should we tp_init or tp_new our basetype? */
+	it->ob_itself = itself;
+	it->ob_freeit = CFRelease;
+	return (PyObject *)it;
+}
+
+int CFMutableDataRefObj_Convert(PyObject *v, CFMutableDataRef *p_itself)
+{
+
+	if (v == Py_None) { *p_itself = NULL; return 1; }
+	/* Check for other CF objects here */
+
+	if (!CFMutableDataRefObj_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "CFMutableDataRef required");
+		return 0;
+	}
+	*p_itself = ((CFMutableDataRefObject *)v)->ob_itself;
+	return 1;
+}
+
+static void CFMutableDataRefObj_dealloc(CFMutableDataRefObject *self)
+{
+	if (self->ob_freeit && self->ob_itself)
+	{
+		self->ob_freeit((CFTypeRef)self->ob_itself);
+		self->ob_itself = NULL;
+	}
+	CFDataRef_Type.tp_dealloc((PyObject *)self);
+}
+
+static PyObject *CFMutableDataRefObj_CFDataSetLength(CFMutableDataRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFIndex length;
+#ifndef CFDataSetLength
+	PyMac_PRECHECK(CFDataSetLength);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &length))
+		return NULL;
+	CFDataSetLength(_self->ob_itself,
+	                length);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CFMutableDataRefObj_CFDataIncreaseLength(CFMutableDataRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFIndex extraLength;
+#ifndef CFDataIncreaseLength
+	PyMac_PRECHECK(CFDataIncreaseLength);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &extraLength))
+		return NULL;
+	CFDataIncreaseLength(_self->ob_itself,
+	                     extraLength);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CFMutableDataRefObj_CFDataAppendBytes(CFMutableDataRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	unsigned char *bytes__in__;
+	long bytes__len__;
+	int bytes__in_len__;
+#ifndef CFDataAppendBytes
+	PyMac_PRECHECK(CFDataAppendBytes);
+#endif
+	if (!PyArg_ParseTuple(_args, "s#",
+	                      &bytes__in__, &bytes__in_len__))
+		return NULL;
+	bytes__len__ = bytes__in_len__;
+	CFDataAppendBytes(_self->ob_itself,
+	                  bytes__in__, bytes__len__);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CFMutableDataRefObj_CFDataReplaceBytes(CFMutableDataRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFRange range;
+	unsigned char *newBytes__in__;
+	long newBytes__len__;
+	int newBytes__in_len__;
+#ifndef CFDataReplaceBytes
+	PyMac_PRECHECK(CFDataReplaceBytes);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&s#",
+	                      CFRange_Convert, &range,
+	                      &newBytes__in__, &newBytes__in_len__))
+		return NULL;
+	newBytes__len__ = newBytes__in_len__;
+	CFDataReplaceBytes(_self->ob_itself,
+	                   range,
+	                   newBytes__in__, newBytes__len__);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CFMutableDataRefObj_CFDataDeleteBytes(CFMutableDataRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFRange range;
+#ifndef CFDataDeleteBytes
+	PyMac_PRECHECK(CFDataDeleteBytes);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CFRange_Convert, &range))
+		return NULL;
+	CFDataDeleteBytes(_self->ob_itself,
+	                  range);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyMethodDef CFMutableDataRefObj_methods[] = {
+	{"CFDataSetLength", (PyCFunction)CFMutableDataRefObj_CFDataSetLength, 1,
+	 PyDoc_STR("(CFIndex length) -> None")},
+	{"CFDataIncreaseLength", (PyCFunction)CFMutableDataRefObj_CFDataIncreaseLength, 1,
+	 PyDoc_STR("(CFIndex extraLength) -> None")},
+	{"CFDataAppendBytes", (PyCFunction)CFMutableDataRefObj_CFDataAppendBytes, 1,
+	 PyDoc_STR("(Buffer bytes) -> None")},
+	{"CFDataReplaceBytes", (PyCFunction)CFMutableDataRefObj_CFDataReplaceBytes, 1,
+	 PyDoc_STR("(CFRange range, Buffer newBytes) -> None")},
+	{"CFDataDeleteBytes", (PyCFunction)CFMutableDataRefObj_CFDataDeleteBytes, 1,
+	 PyDoc_STR("(CFRange range) -> None")},
+	{NULL, NULL, 0}
+};
+
+#define CFMutableDataRefObj_getsetlist NULL
+
+
+static int CFMutableDataRefObj_compare(CFMutableDataRefObject *self, CFMutableDataRefObject *other)
+{
+	/* XXXX Or should we use CFEqual?? */
+	if ( self->ob_itself > other->ob_itself ) return 1;
+	if ( self->ob_itself < other->ob_itself ) return -1;
+	return 0;
+}
+
+static PyObject * CFMutableDataRefObj_repr(CFMutableDataRefObject *self)
+{
+	char buf[100];
+	sprintf(buf, "<CFMutableDataRef object at 0x%8.8x for 0x%8.8x>", (unsigned)self, (unsigned)self->ob_itself);
+	return PyString_FromString(buf);
+}
+
+static int CFMutableDataRefObj_hash(CFMutableDataRefObject *self)
+{
+	/* XXXX Or should we use CFHash?? */
+	return (int)self->ob_itself;
+}
+static int CFMutableDataRefObj_tp_init(PyObject *_self, PyObject *_args, PyObject *_kwds)
+{
+	CFMutableDataRef itself;
+	char *kw[] = {"itself", 0};
+
+	if (PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, CFMutableDataRefObj_Convert, &itself))
+	{
+		((CFMutableDataRefObject *)_self)->ob_itself = itself;
+		return 0;
+	}
+
+	/* Any CFTypeRef descendent is allowed as initializer too */
+	if (PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, CFTypeRefObj_Convert, &itself))
+	{
+		((CFMutableDataRefObject *)_self)->ob_itself = itself;
+		return 0;
+	}
+	return -1;
+}
+
+#define CFMutableDataRefObj_tp_alloc PyType_GenericAlloc
+
+static PyObject *CFMutableDataRefObj_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *self;
+	if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	((CFMutableDataRefObject *)self)->ob_itself = NULL;
+	((CFMutableDataRefObject *)self)->ob_freeit = CFRelease;
+	return self;
+}
+
+#define CFMutableDataRefObj_tp_free PyObject_Del
+
+
+PyTypeObject CFMutableDataRef_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"_CF.CFMutableDataRef", /*tp_name*/
+	sizeof(CFMutableDataRefObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) CFMutableDataRefObj_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) CFMutableDataRefObj_compare, /*tp_compare*/
+	(reprfunc) CFMutableDataRefObj_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) CFMutableDataRefObj_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	CFMutableDataRefObj_methods, /* tp_methods */
+	0, /*tp_members*/
+	CFMutableDataRefObj_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	CFMutableDataRefObj_tp_init, /* tp_init */
+	CFMutableDataRefObj_tp_alloc, /* tp_alloc */
+	CFMutableDataRefObj_tp_new, /* tp_new */
+	CFMutableDataRefObj_tp_free, /* tp_free */
+};
+
+/* ---------------- End object type CFMutableDataRef ---------------- */
+
+
+/* -------------------- Object type CFStringRef --------------------- */
+
+PyTypeObject CFStringRef_Type;
+
+#define CFStringRefObj_Check(x) ((x)->ob_type == &CFStringRef_Type || PyObject_TypeCheck((x), &CFStringRef_Type))
+
+typedef struct CFStringRefObject {
+	PyObject_HEAD
+	CFStringRef ob_itself;
+	void (*ob_freeit)(CFTypeRef ptr);
+} CFStringRefObject;
+
+PyObject *CFStringRefObj_New(CFStringRef itself)
+{
+	CFStringRefObject *it;
+	if (itself == NULL)
+	{
+		PyErr_SetString(PyExc_RuntimeError, "cannot wrap NULL");
+		return NULL;
+	}
+	it = PyObject_NEW(CFStringRefObject, &CFStringRef_Type);
+	if (it == NULL) return NULL;
+	/* XXXX Should we tp_init or tp_new our basetype? */
+	it->ob_itself = itself;
+	it->ob_freeit = CFRelease;
+	return (PyObject *)it;
+}
+
+int CFStringRefObj_Convert(PyObject *v, CFStringRef *p_itself)
+{
+
+	if (v == Py_None) { *p_itself = NULL; return 1; }
+	if (PyString_Check(v)) {
+	    char *cStr;
+	    if (!PyArg_Parse(v, "es", "ascii", &cStr))
+	        return 0;
+	        *p_itself = CFStringCreateWithCString((CFAllocatorRef)NULL, cStr, kCFStringEncodingASCII);
+	        return 1;
+	}
+	if (PyUnicode_Check(v)) {
+	        /* We use the CF types here, if Python was configured differently that will give an error */
+	        CFIndex size = PyUnicode_GetSize(v);
+	        UniChar *unichars = PyUnicode_AsUnicode(v);
+	        if (!unichars) return 0;
+	        *p_itself = CFStringCreateWithCharacters((CFAllocatorRef)NULL, unichars, size);
+	        return 1;
+	}
+
+
+	if (!CFStringRefObj_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "CFStringRef required");
+		return 0;
+	}
+	*p_itself = ((CFStringRefObject *)v)->ob_itself;
+	return 1;
+}
+
+static void CFStringRefObj_dealloc(CFStringRefObject *self)
+{
+	if (self->ob_freeit && self->ob_itself)
+	{
+		self->ob_freeit((CFTypeRef)self->ob_itself);
+		self->ob_itself = NULL;
+	}
+	CFTypeRef_Type.tp_dealloc((PyObject *)self);
+}
+
+static PyObject *CFStringRefObj_CFStringCreateWithSubstring(CFStringRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef _rv;
+	CFRange range;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CFRange_Convert, &range))
+		return NULL;
+	_rv = CFStringCreateWithSubstring((CFAllocatorRef)NULL,
+	                                  _self->ob_itself,
+	                                  range);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFStringRefObj_CFStringCreateCopy(CFStringRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFStringCreateCopy((CFAllocatorRef)NULL,
+	                         _self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFStringRefObj_CFStringGetLength(CFStringRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFIndex _rv;
+#ifndef CFStringGetLength
+	PyMac_PRECHECK(CFStringGetLength);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFStringGetLength(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CFStringRefObj_CFStringGetBytes(CFStringRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFIndex _rv;
+	CFRange range;
+	CFStringEncoding encoding;
+	UInt8 lossByte;
+	Boolean isExternalRepresentation;
+	UInt8 buffer;
+	CFIndex maxBufLen;
+	CFIndex usedBufLen;
+#ifndef CFStringGetBytes
+	PyMac_PRECHECK(CFStringGetBytes);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&lbll",
+	                      CFRange_Convert, &range,
+	                      &encoding,
+	                      &lossByte,
+	                      &isExternalRepresentation,
+	                      &maxBufLen))
+		return NULL;
+	_rv = CFStringGetBytes(_self->ob_itself,
+	                       range,
+	                       encoding,
+	                       lossByte,
+	                       isExternalRepresentation,
+	                       &buffer,
+	                       maxBufLen,
+	                       &usedBufLen);
+	_res = Py_BuildValue("lbl",
+	                     _rv,
+	                     buffer,
+	                     usedBufLen);
+	return _res;
+}
+
+static PyObject *CFStringRefObj_CFStringCreateExternalRepresentation(CFStringRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFDataRef _rv;
+	CFStringEncoding encoding;
+	UInt8 lossByte;
+	if (!PyArg_ParseTuple(_args, "lb",
+	                      &encoding,
+	                      &lossByte))
+		return NULL;
+	_rv = CFStringCreateExternalRepresentation((CFAllocatorRef)NULL,
+	                                           _self->ob_itself,
+	                                           encoding,
+	                                           lossByte);
+	_res = Py_BuildValue("O&",
+	                     CFDataRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFStringRefObj_CFStringGetSmallestEncoding(CFStringRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringEncoding _rv;
+#ifndef CFStringGetSmallestEncoding
+	PyMac_PRECHECK(CFStringGetSmallestEncoding);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFStringGetSmallestEncoding(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CFStringRefObj_CFStringGetFastestEncoding(CFStringRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringEncoding _rv;
+#ifndef CFStringGetFastestEncoding
+	PyMac_PRECHECK(CFStringGetFastestEncoding);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFStringGetFastestEncoding(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CFStringRefObj_CFStringCompareWithOptions(CFStringRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFComparisonResult _rv;
+	CFStringRef theString2;
+	CFRange rangeToCompare;
+	CFOptionFlags compareOptions;
+#ifndef CFStringCompareWithOptions
+	PyMac_PRECHECK(CFStringCompareWithOptions);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&l",
+	                      CFStringRefObj_Convert, &theString2,
+	                      CFRange_Convert, &rangeToCompare,
+	                      &compareOptions))
+		return NULL;
+	_rv = CFStringCompareWithOptions(_self->ob_itself,
+	                                 theString2,
+	                                 rangeToCompare,
+	                                 compareOptions);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CFStringRefObj_CFStringCompare(CFStringRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFComparisonResult _rv;
+	CFStringRef theString2;
+	CFOptionFlags compareOptions;
+#ifndef CFStringCompare
+	PyMac_PRECHECK(CFStringCompare);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CFStringRefObj_Convert, &theString2,
+	                      &compareOptions))
+		return NULL;
+	_rv = CFStringCompare(_self->ob_itself,
+	                      theString2,
+	                      compareOptions);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CFStringRefObj_CFStringFindWithOptions(CFStringRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	CFStringRef stringToFind;
+	CFRange rangeToSearch;
+	CFOptionFlags searchOptions;
+	CFRange result;
+#ifndef CFStringFindWithOptions
+	PyMac_PRECHECK(CFStringFindWithOptions);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&l",
+	                      CFStringRefObj_Convert, &stringToFind,
+	                      CFRange_Convert, &rangeToSearch,
+	                      &searchOptions))
+		return NULL;
+	_rv = CFStringFindWithOptions(_self->ob_itself,
+	                              stringToFind,
+	                              rangeToSearch,
+	                              searchOptions,
+	                              &result);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     CFRange_New, result);
+	return _res;
+}
+
+static PyObject *CFStringRefObj_CFStringCreateArrayWithFindResults(CFStringRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFArrayRef _rv;
+	CFStringRef stringToFind;
+	CFRange rangeToSearch;
+	CFOptionFlags compareOptions;
+	if (!PyArg_ParseTuple(_args, "O&O&l",
+	                      CFStringRefObj_Convert, &stringToFind,
+	                      CFRange_Convert, &rangeToSearch,
+	                      &compareOptions))
+		return NULL;
+	_rv = CFStringCreateArrayWithFindResults((CFAllocatorRef)NULL,
+	                                         _self->ob_itself,
+	                                         stringToFind,
+	                                         rangeToSearch,
+	                                         compareOptions);
+	_res = Py_BuildValue("O&",
+	                     CFArrayRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFStringRefObj_CFStringFind(CFStringRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFRange _rv;
+	CFStringRef stringToFind;
+	CFOptionFlags compareOptions;
+#ifndef CFStringFind
+	PyMac_PRECHECK(CFStringFind);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CFStringRefObj_Convert, &stringToFind,
+	                      &compareOptions))
+		return NULL;
+	_rv = CFStringFind(_self->ob_itself,
+	                   stringToFind,
+	                   compareOptions);
+	_res = Py_BuildValue("O&",
+	                     CFRange_New, _rv);
+	return _res;
+}
+
+static PyObject *CFStringRefObj_CFStringHasPrefix(CFStringRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	CFStringRef prefix;
+#ifndef CFStringHasPrefix
+	PyMac_PRECHECK(CFStringHasPrefix);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CFStringRefObj_Convert, &prefix))
+		return NULL;
+	_rv = CFStringHasPrefix(_self->ob_itself,
+	                        prefix);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CFStringRefObj_CFStringHasSuffix(CFStringRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	CFStringRef suffix;
+#ifndef CFStringHasSuffix
+	PyMac_PRECHECK(CFStringHasSuffix);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CFStringRefObj_Convert, &suffix))
+		return NULL;
+	_rv = CFStringHasSuffix(_self->ob_itself,
+	                        suffix);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CFStringRefObj_CFStringGetLineBounds(CFStringRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFRange range;
+	CFIndex lineBeginIndex;
+	CFIndex lineEndIndex;
+	CFIndex contentsEndIndex;
+#ifndef CFStringGetLineBounds
+	PyMac_PRECHECK(CFStringGetLineBounds);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CFRange_Convert, &range))
+		return NULL;
+	CFStringGetLineBounds(_self->ob_itself,
+	                      range,
+	                      &lineBeginIndex,
+	                      &lineEndIndex,
+	                      &contentsEndIndex);
+	_res = Py_BuildValue("lll",
+	                     lineBeginIndex,
+	                     lineEndIndex,
+	                     contentsEndIndex);
+	return _res;
+}
+
+static PyObject *CFStringRefObj_CFStringCreateArrayBySeparatingStrings(CFStringRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFArrayRef _rv;
+	CFStringRef separatorString;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CFStringRefObj_Convert, &separatorString))
+		return NULL;
+	_rv = CFStringCreateArrayBySeparatingStrings((CFAllocatorRef)NULL,
+	                                             _self->ob_itself,
+	                                             separatorString);
+	_res = Py_BuildValue("O&",
+	                     CFArrayRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFStringRefObj_CFStringGetIntValue(CFStringRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	SInt32 _rv;
+#ifndef CFStringGetIntValue
+	PyMac_PRECHECK(CFStringGetIntValue);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFStringGetIntValue(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CFStringRefObj_CFStringGetDoubleValue(CFStringRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	double _rv;
+#ifndef CFStringGetDoubleValue
+	PyMac_PRECHECK(CFStringGetDoubleValue);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFStringGetDoubleValue(_self->ob_itself);
+	_res = Py_BuildValue("d",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CFStringRefObj_CFStringConvertIANACharSetNameToEncoding(CFStringRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringEncoding _rv;
+#ifndef CFStringConvertIANACharSetNameToEncoding
+	PyMac_PRECHECK(CFStringConvertIANACharSetNameToEncoding);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFStringConvertIANACharSetNameToEncoding(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CFStringRefObj_CFShowStr(CFStringRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef CFShowStr
+	PyMac_PRECHECK(CFShowStr);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	CFShowStr(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CFStringRefObj_CFURLCreateWithString(CFStringRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFURLRef _rv;
+	CFURLRef baseURL;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      OptionalCFURLRefObj_Convert, &baseURL))
+		return NULL;
+	_rv = CFURLCreateWithString((CFAllocatorRef)NULL,
+	                            _self->ob_itself,
+	                            baseURL);
+	_res = Py_BuildValue("O&",
+	                     CFURLRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFStringRefObj_CFURLCreateWithFileSystemPath(CFStringRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFURLRef _rv;
+	CFURLPathStyle pathStyle;
+	Boolean isDirectory;
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &pathStyle,
+	                      &isDirectory))
+		return NULL;
+	_rv = CFURLCreateWithFileSystemPath((CFAllocatorRef)NULL,
+	                                    _self->ob_itself,
+	                                    pathStyle,
+	                                    isDirectory);
+	_res = Py_BuildValue("O&",
+	                     CFURLRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFStringRefObj_CFURLCreateWithFileSystemPathRelativeToBase(CFStringRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFURLRef _rv;
+	CFURLPathStyle pathStyle;
+	Boolean isDirectory;
+	CFURLRef baseURL;
+	if (!PyArg_ParseTuple(_args, "llO&",
+	                      &pathStyle,
+	                      &isDirectory,
+	                      OptionalCFURLRefObj_Convert, &baseURL))
+		return NULL;
+	_rv = CFURLCreateWithFileSystemPathRelativeToBase((CFAllocatorRef)NULL,
+	                                                  _self->ob_itself,
+	                                                  pathStyle,
+	                                                  isDirectory,
+	                                                  baseURL);
+	_res = Py_BuildValue("O&",
+	                     CFURLRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFStringRefObj_CFURLCreateStringByReplacingPercentEscapes(CFStringRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef _rv;
+	CFStringRef charactersToLeaveEscaped;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CFStringRefObj_Convert, &charactersToLeaveEscaped))
+		return NULL;
+	_rv = CFURLCreateStringByReplacingPercentEscapes((CFAllocatorRef)NULL,
+	                                                 _self->ob_itself,
+	                                                 charactersToLeaveEscaped);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFStringRefObj_CFURLCreateStringByAddingPercentEscapes(CFStringRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef _rv;
+	CFStringRef charactersToLeaveUnescaped;
+	CFStringRef legalURLCharactersToBeEscaped;
+	CFStringEncoding encoding;
+	if (!PyArg_ParseTuple(_args, "O&O&l",
+	                      CFStringRefObj_Convert, &charactersToLeaveUnescaped,
+	                      CFStringRefObj_Convert, &legalURLCharactersToBeEscaped,
+	                      &encoding))
+		return NULL;
+	_rv = CFURLCreateStringByAddingPercentEscapes((CFAllocatorRef)NULL,
+	                                              _self->ob_itself,
+	                                              charactersToLeaveUnescaped,
+	                                              legalURLCharactersToBeEscaped,
+	                                              encoding);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFStringRefObj_CFStringGetString(CFStringRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+
+	int size = CFStringGetLength(_self->ob_itself)+1;
+	char *data = malloc(size);
+
+	if( data == NULL ) return PyErr_NoMemory();
+	if ( CFStringGetCString(_self->ob_itself, data, size, 0) ) {
+	        _res = (PyObject *)PyString_FromString(data);
+	} else {
+	        PyErr_SetString(PyExc_RuntimeError, "CFStringGetCString could not fit the string");
+	        _res = NULL;
+	}
+	free(data);
+	return _res;
+
+}
+
+static PyObject *CFStringRefObj_CFStringGetUnicode(CFStringRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+
+	int size = CFStringGetLength(_self->ob_itself)+1;
+	Py_UNICODE *data = malloc(size*sizeof(Py_UNICODE));
+	CFRange range;
+
+	range.location = 0;
+	range.length = size;
+	if( data == NULL ) return PyErr_NoMemory();
+	CFStringGetCharacters(_self->ob_itself, range, data);
+	_res = (PyObject *)PyUnicode_FromUnicode(data, size-1);
+	free(data);
+	return _res;
+
+}
+
+static PyMethodDef CFStringRefObj_methods[] = {
+	{"CFStringCreateWithSubstring", (PyCFunction)CFStringRefObj_CFStringCreateWithSubstring, 1,
+	 PyDoc_STR("(CFRange range) -> (CFStringRef _rv)")},
+	{"CFStringCreateCopy", (PyCFunction)CFStringRefObj_CFStringCreateCopy, 1,
+	 PyDoc_STR("() -> (CFStringRef _rv)")},
+	{"CFStringGetLength", (PyCFunction)CFStringRefObj_CFStringGetLength, 1,
+	 PyDoc_STR("() -> (CFIndex _rv)")},
+	{"CFStringGetBytes", (PyCFunction)CFStringRefObj_CFStringGetBytes, 1,
+	 PyDoc_STR("(CFRange range, CFStringEncoding encoding, UInt8 lossByte, Boolean isExternalRepresentation, CFIndex maxBufLen) -> (CFIndex _rv, UInt8 buffer, CFIndex usedBufLen)")},
+	{"CFStringCreateExternalRepresentation", (PyCFunction)CFStringRefObj_CFStringCreateExternalRepresentation, 1,
+	 PyDoc_STR("(CFStringEncoding encoding, UInt8 lossByte) -> (CFDataRef _rv)")},
+	{"CFStringGetSmallestEncoding", (PyCFunction)CFStringRefObj_CFStringGetSmallestEncoding, 1,
+	 PyDoc_STR("() -> (CFStringEncoding _rv)")},
+	{"CFStringGetFastestEncoding", (PyCFunction)CFStringRefObj_CFStringGetFastestEncoding, 1,
+	 PyDoc_STR("() -> (CFStringEncoding _rv)")},
+	{"CFStringCompareWithOptions", (PyCFunction)CFStringRefObj_CFStringCompareWithOptions, 1,
+	 PyDoc_STR("(CFStringRef theString2, CFRange rangeToCompare, CFOptionFlags compareOptions) -> (CFComparisonResult _rv)")},
+	{"CFStringCompare", (PyCFunction)CFStringRefObj_CFStringCompare, 1,
+	 PyDoc_STR("(CFStringRef theString2, CFOptionFlags compareOptions) -> (CFComparisonResult _rv)")},
+	{"CFStringFindWithOptions", (PyCFunction)CFStringRefObj_CFStringFindWithOptions, 1,
+	 PyDoc_STR("(CFStringRef stringToFind, CFRange rangeToSearch, CFOptionFlags searchOptions) -> (Boolean _rv, CFRange result)")},
+	{"CFStringCreateArrayWithFindResults", (PyCFunction)CFStringRefObj_CFStringCreateArrayWithFindResults, 1,
+	 PyDoc_STR("(CFStringRef stringToFind, CFRange rangeToSearch, CFOptionFlags compareOptions) -> (CFArrayRef _rv)")},
+	{"CFStringFind", (PyCFunction)CFStringRefObj_CFStringFind, 1,
+	 PyDoc_STR("(CFStringRef stringToFind, CFOptionFlags compareOptions) -> (CFRange _rv)")},
+	{"CFStringHasPrefix", (PyCFunction)CFStringRefObj_CFStringHasPrefix, 1,
+	 PyDoc_STR("(CFStringRef prefix) -> (Boolean _rv)")},
+	{"CFStringHasSuffix", (PyCFunction)CFStringRefObj_CFStringHasSuffix, 1,
+	 PyDoc_STR("(CFStringRef suffix) -> (Boolean _rv)")},
+	{"CFStringGetLineBounds", (PyCFunction)CFStringRefObj_CFStringGetLineBounds, 1,
+	 PyDoc_STR("(CFRange range) -> (CFIndex lineBeginIndex, CFIndex lineEndIndex, CFIndex contentsEndIndex)")},
+	{"CFStringCreateArrayBySeparatingStrings", (PyCFunction)CFStringRefObj_CFStringCreateArrayBySeparatingStrings, 1,
+	 PyDoc_STR("(CFStringRef separatorString) -> (CFArrayRef _rv)")},
+	{"CFStringGetIntValue", (PyCFunction)CFStringRefObj_CFStringGetIntValue, 1,
+	 PyDoc_STR("() -> (SInt32 _rv)")},
+	{"CFStringGetDoubleValue", (PyCFunction)CFStringRefObj_CFStringGetDoubleValue, 1,
+	 PyDoc_STR("() -> (double _rv)")},
+	{"CFStringConvertIANACharSetNameToEncoding", (PyCFunction)CFStringRefObj_CFStringConvertIANACharSetNameToEncoding, 1,
+	 PyDoc_STR("() -> (CFStringEncoding _rv)")},
+	{"CFShowStr", (PyCFunction)CFStringRefObj_CFShowStr, 1,
+	 PyDoc_STR("() -> None")},
+	{"CFURLCreateWithString", (PyCFunction)CFStringRefObj_CFURLCreateWithString, 1,
+	 PyDoc_STR("(CFURLRef baseURL) -> (CFURLRef _rv)")},
+	{"CFURLCreateWithFileSystemPath", (PyCFunction)CFStringRefObj_CFURLCreateWithFileSystemPath, 1,
+	 PyDoc_STR("(CFURLPathStyle pathStyle, Boolean isDirectory) -> (CFURLRef _rv)")},
+	{"CFURLCreateWithFileSystemPathRelativeToBase", (PyCFunction)CFStringRefObj_CFURLCreateWithFileSystemPathRelativeToBase, 1,
+	 PyDoc_STR("(CFURLPathStyle pathStyle, Boolean isDirectory, CFURLRef baseURL) -> (CFURLRef _rv)")},
+	{"CFURLCreateStringByReplacingPercentEscapes", (PyCFunction)CFStringRefObj_CFURLCreateStringByReplacingPercentEscapes, 1,
+	 PyDoc_STR("(CFStringRef charactersToLeaveEscaped) -> (CFStringRef _rv)")},
+	{"CFURLCreateStringByAddingPercentEscapes", (PyCFunction)CFStringRefObj_CFURLCreateStringByAddingPercentEscapes, 1,
+	 PyDoc_STR("(CFStringRef charactersToLeaveUnescaped, CFStringRef legalURLCharactersToBeEscaped, CFStringEncoding encoding) -> (CFStringRef _rv)")},
+	{"CFStringGetString", (PyCFunction)CFStringRefObj_CFStringGetString, 1,
+	 PyDoc_STR("() -> (string _rv)")},
+	{"CFStringGetUnicode", (PyCFunction)CFStringRefObj_CFStringGetUnicode, 1,
+	 PyDoc_STR("() -> (unicode _rv)")},
+	{NULL, NULL, 0}
+};
+
+#define CFStringRefObj_getsetlist NULL
+
+
+static int CFStringRefObj_compare(CFStringRefObject *self, CFStringRefObject *other)
+{
+	/* XXXX Or should we use CFEqual?? */
+	if ( self->ob_itself > other->ob_itself ) return 1;
+	if ( self->ob_itself < other->ob_itself ) return -1;
+	return 0;
+}
+
+static PyObject * CFStringRefObj_repr(CFStringRefObject *self)
+{
+	char buf[100];
+	sprintf(buf, "<CFStringRef object at 0x%8.8x for 0x%8.8x>", (unsigned)self, (unsigned)self->ob_itself);
+	return PyString_FromString(buf);
+}
+
+static int CFStringRefObj_hash(CFStringRefObject *self)
+{
+	/* XXXX Or should we use CFHash?? */
+	return (int)self->ob_itself;
+}
+static int CFStringRefObj_tp_init(PyObject *_self, PyObject *_args, PyObject *_kwds)
+{
+	CFStringRef itself;
+	char *kw[] = {"itself", 0};
+
+	if (PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, CFStringRefObj_Convert, &itself))
+	{
+		((CFStringRefObject *)_self)->ob_itself = itself;
+		return 0;
+	}
+
+	/* Any CFTypeRef descendent is allowed as initializer too */
+	if (PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, CFTypeRefObj_Convert, &itself))
+	{
+		((CFStringRefObject *)_self)->ob_itself = itself;
+		return 0;
+	}
+	return -1;
+}
+
+#define CFStringRefObj_tp_alloc PyType_GenericAlloc
+
+static PyObject *CFStringRefObj_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *self;
+	if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	((CFStringRefObject *)self)->ob_itself = NULL;
+	((CFStringRefObject *)self)->ob_freeit = CFRelease;
+	return self;
+}
+
+#define CFStringRefObj_tp_free PyObject_Del
+
+
+PyTypeObject CFStringRef_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"_CF.CFStringRef", /*tp_name*/
+	sizeof(CFStringRefObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) CFStringRefObj_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) CFStringRefObj_compare, /*tp_compare*/
+	(reprfunc) CFStringRefObj_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) CFStringRefObj_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	CFStringRefObj_methods, /* tp_methods */
+	0, /*tp_members*/
+	CFStringRefObj_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	CFStringRefObj_tp_init, /* tp_init */
+	CFStringRefObj_tp_alloc, /* tp_alloc */
+	CFStringRefObj_tp_new, /* tp_new */
+	CFStringRefObj_tp_free, /* tp_free */
+};
+
+/* ------------------ End object type CFStringRef ------------------- */
+
+
+/* ----------------- Object type CFMutableStringRef ----------------- */
+
+PyTypeObject CFMutableStringRef_Type;
+
+#define CFMutableStringRefObj_Check(x) ((x)->ob_type == &CFMutableStringRef_Type || PyObject_TypeCheck((x), &CFMutableStringRef_Type))
+
+typedef struct CFMutableStringRefObject {
+	PyObject_HEAD
+	CFMutableStringRef ob_itself;
+	void (*ob_freeit)(CFTypeRef ptr);
+} CFMutableStringRefObject;
+
+PyObject *CFMutableStringRefObj_New(CFMutableStringRef itself)
+{
+	CFMutableStringRefObject *it;
+	if (itself == NULL)
+	{
+		PyErr_SetString(PyExc_RuntimeError, "cannot wrap NULL");
+		return NULL;
+	}
+	it = PyObject_NEW(CFMutableStringRefObject, &CFMutableStringRef_Type);
+	if (it == NULL) return NULL;
+	/* XXXX Should we tp_init or tp_new our basetype? */
+	it->ob_itself = itself;
+	it->ob_freeit = CFRelease;
+	return (PyObject *)it;
+}
+
+int CFMutableStringRefObj_Convert(PyObject *v, CFMutableStringRef *p_itself)
+{
+
+	if (v == Py_None) { *p_itself = NULL; return 1; }
+	/* Check for other CF objects here */
+
+	if (!CFMutableStringRefObj_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "CFMutableStringRef required");
+		return 0;
+	}
+	*p_itself = ((CFMutableStringRefObject *)v)->ob_itself;
+	return 1;
+}
+
+static void CFMutableStringRefObj_dealloc(CFMutableStringRefObject *self)
+{
+	if (self->ob_freeit && self->ob_itself)
+	{
+		self->ob_freeit((CFTypeRef)self->ob_itself);
+		self->ob_itself = NULL;
+	}
+	CFStringRef_Type.tp_dealloc((PyObject *)self);
+}
+
+static PyObject *CFMutableStringRefObj_CFStringAppend(CFMutableStringRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef appendedString;
+#ifndef CFStringAppend
+	PyMac_PRECHECK(CFStringAppend);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CFStringRefObj_Convert, &appendedString))
+		return NULL;
+	CFStringAppend(_self->ob_itself,
+	               appendedString);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CFMutableStringRefObj_CFStringAppendCharacters(CFMutableStringRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	UniChar *chars__in__;
+	UniCharCount chars__len__;
+	int chars__in_len__;
+#ifndef CFStringAppendCharacters
+	PyMac_PRECHECK(CFStringAppendCharacters);
+#endif
+	if (!PyArg_ParseTuple(_args, "u#",
+	                      &chars__in__, &chars__in_len__))
+		return NULL;
+	chars__len__ = chars__in_len__;
+	CFStringAppendCharacters(_self->ob_itself,
+	                         chars__in__, chars__len__);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CFMutableStringRefObj_CFStringAppendPascalString(CFMutableStringRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Str255 pStr;
+	CFStringEncoding encoding;
+#ifndef CFStringAppendPascalString
+	PyMac_PRECHECK(CFStringAppendPascalString);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      PyMac_GetStr255, pStr,
+	                      &encoding))
+		return NULL;
+	CFStringAppendPascalString(_self->ob_itself,
+	                           pStr,
+	                           encoding);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CFMutableStringRefObj_CFStringAppendCString(CFMutableStringRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	char* cStr;
+	CFStringEncoding encoding;
+#ifndef CFStringAppendCString
+	PyMac_PRECHECK(CFStringAppendCString);
+#endif
+	if (!PyArg_ParseTuple(_args, "sl",
+	                      &cStr,
+	                      &encoding))
+		return NULL;
+	CFStringAppendCString(_self->ob_itself,
+	                      cStr,
+	                      encoding);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CFMutableStringRefObj_CFStringInsert(CFMutableStringRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFIndex idx;
+	CFStringRef insertedStr;
+#ifndef CFStringInsert
+	PyMac_PRECHECK(CFStringInsert);
+#endif
+	if (!PyArg_ParseTuple(_args, "lO&",
+	                      &idx,
+	                      CFStringRefObj_Convert, &insertedStr))
+		return NULL;
+	CFStringInsert(_self->ob_itself,
+	               idx,
+	               insertedStr);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CFMutableStringRefObj_CFStringDelete(CFMutableStringRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFRange range;
+#ifndef CFStringDelete
+	PyMac_PRECHECK(CFStringDelete);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CFRange_Convert, &range))
+		return NULL;
+	CFStringDelete(_self->ob_itself,
+	               range);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CFMutableStringRefObj_CFStringReplace(CFMutableStringRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFRange range;
+	CFStringRef replacement;
+#ifndef CFStringReplace
+	PyMac_PRECHECK(CFStringReplace);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CFRange_Convert, &range,
+	                      CFStringRefObj_Convert, &replacement))
+		return NULL;
+	CFStringReplace(_self->ob_itself,
+	                range,
+	                replacement);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CFMutableStringRefObj_CFStringReplaceAll(CFMutableStringRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef replacement;
+#ifndef CFStringReplaceAll
+	PyMac_PRECHECK(CFStringReplaceAll);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CFStringRefObj_Convert, &replacement))
+		return NULL;
+	CFStringReplaceAll(_self->ob_itself,
+	                   replacement);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CFMutableStringRefObj_CFStringPad(CFMutableStringRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef padString;
+	CFIndex length;
+	CFIndex indexIntoPad;
+#ifndef CFStringPad
+	PyMac_PRECHECK(CFStringPad);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&ll",
+	                      CFStringRefObj_Convert, &padString,
+	                      &length,
+	                      &indexIntoPad))
+		return NULL;
+	CFStringPad(_self->ob_itself,
+	            padString,
+	            length,
+	            indexIntoPad);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CFMutableStringRefObj_CFStringTrim(CFMutableStringRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef trimString;
+#ifndef CFStringTrim
+	PyMac_PRECHECK(CFStringTrim);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CFStringRefObj_Convert, &trimString))
+		return NULL;
+	CFStringTrim(_self->ob_itself,
+	             trimString);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CFMutableStringRefObj_CFStringTrimWhitespace(CFMutableStringRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef CFStringTrimWhitespace
+	PyMac_PRECHECK(CFStringTrimWhitespace);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	CFStringTrimWhitespace(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyMethodDef CFMutableStringRefObj_methods[] = {
+	{"CFStringAppend", (PyCFunction)CFMutableStringRefObj_CFStringAppend, 1,
+	 PyDoc_STR("(CFStringRef appendedString) -> None")},
+	{"CFStringAppendCharacters", (PyCFunction)CFMutableStringRefObj_CFStringAppendCharacters, 1,
+	 PyDoc_STR("(Buffer chars) -> None")},
+	{"CFStringAppendPascalString", (PyCFunction)CFMutableStringRefObj_CFStringAppendPascalString, 1,
+	 PyDoc_STR("(Str255 pStr, CFStringEncoding encoding) -> None")},
+	{"CFStringAppendCString", (PyCFunction)CFMutableStringRefObj_CFStringAppendCString, 1,
+	 PyDoc_STR("(char* cStr, CFStringEncoding encoding) -> None")},
+	{"CFStringInsert", (PyCFunction)CFMutableStringRefObj_CFStringInsert, 1,
+	 PyDoc_STR("(CFIndex idx, CFStringRef insertedStr) -> None")},
+	{"CFStringDelete", (PyCFunction)CFMutableStringRefObj_CFStringDelete, 1,
+	 PyDoc_STR("(CFRange range) -> None")},
+	{"CFStringReplace", (PyCFunction)CFMutableStringRefObj_CFStringReplace, 1,
+	 PyDoc_STR("(CFRange range, CFStringRef replacement) -> None")},
+	{"CFStringReplaceAll", (PyCFunction)CFMutableStringRefObj_CFStringReplaceAll, 1,
+	 PyDoc_STR("(CFStringRef replacement) -> None")},
+	{"CFStringPad", (PyCFunction)CFMutableStringRefObj_CFStringPad, 1,
+	 PyDoc_STR("(CFStringRef padString, CFIndex length, CFIndex indexIntoPad) -> None")},
+	{"CFStringTrim", (PyCFunction)CFMutableStringRefObj_CFStringTrim, 1,
+	 PyDoc_STR("(CFStringRef trimString) -> None")},
+	{"CFStringTrimWhitespace", (PyCFunction)CFMutableStringRefObj_CFStringTrimWhitespace, 1,
+	 PyDoc_STR("() -> None")},
+	{NULL, NULL, 0}
+};
+
+#define CFMutableStringRefObj_getsetlist NULL
+
+
+static int CFMutableStringRefObj_compare(CFMutableStringRefObject *self, CFMutableStringRefObject *other)
+{
+	/* XXXX Or should we use CFEqual?? */
+	if ( self->ob_itself > other->ob_itself ) return 1;
+	if ( self->ob_itself < other->ob_itself ) return -1;
+	return 0;
+}
+
+static PyObject * CFMutableStringRefObj_repr(CFMutableStringRefObject *self)
+{
+	char buf[100];
+	sprintf(buf, "<CFMutableStringRef object at 0x%8.8x for 0x%8.8x>", (unsigned)self, (unsigned)self->ob_itself);
+	return PyString_FromString(buf);
+}
+
+static int CFMutableStringRefObj_hash(CFMutableStringRefObject *self)
+{
+	/* XXXX Or should we use CFHash?? */
+	return (int)self->ob_itself;
+}
+static int CFMutableStringRefObj_tp_init(PyObject *_self, PyObject *_args, PyObject *_kwds)
+{
+	CFMutableStringRef itself;
+	char *kw[] = {"itself", 0};
+
+	if (PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, CFMutableStringRefObj_Convert, &itself))
+	{
+		((CFMutableStringRefObject *)_self)->ob_itself = itself;
+		return 0;
+	}
+
+	/* Any CFTypeRef descendent is allowed as initializer too */
+	if (PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, CFTypeRefObj_Convert, &itself))
+	{
+		((CFMutableStringRefObject *)_self)->ob_itself = itself;
+		return 0;
+	}
+	return -1;
+}
+
+#define CFMutableStringRefObj_tp_alloc PyType_GenericAlloc
+
+static PyObject *CFMutableStringRefObj_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *self;
+	if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	((CFMutableStringRefObject *)self)->ob_itself = NULL;
+	((CFMutableStringRefObject *)self)->ob_freeit = CFRelease;
+	return self;
+}
+
+#define CFMutableStringRefObj_tp_free PyObject_Del
+
+
+PyTypeObject CFMutableStringRef_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"_CF.CFMutableStringRef", /*tp_name*/
+	sizeof(CFMutableStringRefObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) CFMutableStringRefObj_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) CFMutableStringRefObj_compare, /*tp_compare*/
+	(reprfunc) CFMutableStringRefObj_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) CFMutableStringRefObj_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	CFMutableStringRefObj_methods, /* tp_methods */
+	0, /*tp_members*/
+	CFMutableStringRefObj_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	CFMutableStringRefObj_tp_init, /* tp_init */
+	CFMutableStringRefObj_tp_alloc, /* tp_alloc */
+	CFMutableStringRefObj_tp_new, /* tp_new */
+	CFMutableStringRefObj_tp_free, /* tp_free */
+};
+
+/* --------------- End object type CFMutableStringRef --------------- */
+
+
+/* ---------------------- Object type CFURLRef ---------------------- */
+
+PyTypeObject CFURLRef_Type;
+
+#define CFURLRefObj_Check(x) ((x)->ob_type == &CFURLRef_Type || PyObject_TypeCheck((x), &CFURLRef_Type))
+
+typedef struct CFURLRefObject {
+	PyObject_HEAD
+	CFURLRef ob_itself;
+	void (*ob_freeit)(CFTypeRef ptr);
+} CFURLRefObject;
+
+PyObject *CFURLRefObj_New(CFURLRef itself)
+{
+	CFURLRefObject *it;
+	if (itself == NULL)
+	{
+		PyErr_SetString(PyExc_RuntimeError, "cannot wrap NULL");
+		return NULL;
+	}
+	it = PyObject_NEW(CFURLRefObject, &CFURLRef_Type);
+	if (it == NULL) return NULL;
+	/* XXXX Should we tp_init or tp_new our basetype? */
+	it->ob_itself = itself;
+	it->ob_freeit = CFRelease;
+	return (PyObject *)it;
+}
+
+int CFURLRefObj_Convert(PyObject *v, CFURLRef *p_itself)
+{
+
+	if (v == Py_None) { *p_itself = NULL; return 1; }
+	/* Check for other CF objects here */
+
+	if (!CFURLRefObj_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "CFURLRef required");
+		return 0;
+	}
+	*p_itself = ((CFURLRefObject *)v)->ob_itself;
+	return 1;
+}
+
+static void CFURLRefObj_dealloc(CFURLRefObject *self)
+{
+	if (self->ob_freeit && self->ob_itself)
+	{
+		self->ob_freeit((CFTypeRef)self->ob_itself);
+		self->ob_itself = NULL;
+	}
+	CFTypeRef_Type.tp_dealloc((PyObject *)self);
+}
+
+static PyObject *CFURLRefObj_CFURLCreateData(CFURLRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFDataRef _rv;
+	CFStringEncoding encoding;
+	Boolean escapeWhitespace;
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &encoding,
+	                      &escapeWhitespace))
+		return NULL;
+	_rv = CFURLCreateData((CFAllocatorRef)NULL,
+	                      _self->ob_itself,
+	                      encoding,
+	                      escapeWhitespace);
+	_res = Py_BuildValue("O&",
+	                     CFDataRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFURLRefObj_CFURLGetFileSystemRepresentation(CFURLRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	Boolean resolveAgainstBase;
+	UInt8 buffer;
+	CFIndex maxBufLen;
+#ifndef CFURLGetFileSystemRepresentation
+	PyMac_PRECHECK(CFURLGetFileSystemRepresentation);
+#endif
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &resolveAgainstBase,
+	                      &maxBufLen))
+		return NULL;
+	_rv = CFURLGetFileSystemRepresentation(_self->ob_itself,
+	                                       resolveAgainstBase,
+	                                       &buffer,
+	                                       maxBufLen);
+	_res = Py_BuildValue("lb",
+	                     _rv,
+	                     buffer);
+	return _res;
+}
+
+static PyObject *CFURLRefObj_CFURLCopyAbsoluteURL(CFURLRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFURLRef _rv;
+#ifndef CFURLCopyAbsoluteURL
+	PyMac_PRECHECK(CFURLCopyAbsoluteURL);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFURLCopyAbsoluteURL(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     CFURLRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFURLRefObj_CFURLGetString(CFURLRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef _rv;
+#ifndef CFURLGetString
+	PyMac_PRECHECK(CFURLGetString);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFURLGetString(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFURLRefObj_CFURLGetBaseURL(CFURLRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFURLRef _rv;
+#ifndef CFURLGetBaseURL
+	PyMac_PRECHECK(CFURLGetBaseURL);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFURLGetBaseURL(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     CFURLRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFURLRefObj_CFURLCanBeDecomposed(CFURLRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+#ifndef CFURLCanBeDecomposed
+	PyMac_PRECHECK(CFURLCanBeDecomposed);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFURLCanBeDecomposed(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CFURLRefObj_CFURLCopyScheme(CFURLRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef _rv;
+#ifndef CFURLCopyScheme
+	PyMac_PRECHECK(CFURLCopyScheme);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFURLCopyScheme(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFURLRefObj_CFURLCopyNetLocation(CFURLRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef _rv;
+#ifndef CFURLCopyNetLocation
+	PyMac_PRECHECK(CFURLCopyNetLocation);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFURLCopyNetLocation(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFURLRefObj_CFURLCopyPath(CFURLRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef _rv;
+#ifndef CFURLCopyPath
+	PyMac_PRECHECK(CFURLCopyPath);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFURLCopyPath(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFURLRefObj_CFURLCopyStrictPath(CFURLRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef _rv;
+	Boolean isAbsolute;
+#ifndef CFURLCopyStrictPath
+	PyMac_PRECHECK(CFURLCopyStrictPath);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFURLCopyStrictPath(_self->ob_itself,
+	                          &isAbsolute);
+	_res = Py_BuildValue("O&l",
+	                     CFStringRefObj_New, _rv,
+	                     isAbsolute);
+	return _res;
+}
+
+static PyObject *CFURLRefObj_CFURLCopyFileSystemPath(CFURLRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef _rv;
+	CFURLPathStyle pathStyle;
+#ifndef CFURLCopyFileSystemPath
+	PyMac_PRECHECK(CFURLCopyFileSystemPath);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &pathStyle))
+		return NULL;
+	_rv = CFURLCopyFileSystemPath(_self->ob_itself,
+	                              pathStyle);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFURLRefObj_CFURLHasDirectoryPath(CFURLRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+#ifndef CFURLHasDirectoryPath
+	PyMac_PRECHECK(CFURLHasDirectoryPath);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFURLHasDirectoryPath(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CFURLRefObj_CFURLCopyResourceSpecifier(CFURLRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef _rv;
+#ifndef CFURLCopyResourceSpecifier
+	PyMac_PRECHECK(CFURLCopyResourceSpecifier);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFURLCopyResourceSpecifier(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFURLRefObj_CFURLCopyHostName(CFURLRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef _rv;
+#ifndef CFURLCopyHostName
+	PyMac_PRECHECK(CFURLCopyHostName);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFURLCopyHostName(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFURLRefObj_CFURLGetPortNumber(CFURLRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	SInt32 _rv;
+#ifndef CFURLGetPortNumber
+	PyMac_PRECHECK(CFURLGetPortNumber);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFURLGetPortNumber(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CFURLRefObj_CFURLCopyUserName(CFURLRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef _rv;
+#ifndef CFURLCopyUserName
+	PyMac_PRECHECK(CFURLCopyUserName);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFURLCopyUserName(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFURLRefObj_CFURLCopyPassword(CFURLRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef _rv;
+#ifndef CFURLCopyPassword
+	PyMac_PRECHECK(CFURLCopyPassword);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFURLCopyPassword(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFURLRefObj_CFURLCopyParameterString(CFURLRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef _rv;
+	CFStringRef charactersToLeaveEscaped;
+#ifndef CFURLCopyParameterString
+	PyMac_PRECHECK(CFURLCopyParameterString);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CFStringRefObj_Convert, &charactersToLeaveEscaped))
+		return NULL;
+	_rv = CFURLCopyParameterString(_self->ob_itself,
+	                               charactersToLeaveEscaped);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFURLRefObj_CFURLCopyQueryString(CFURLRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef _rv;
+	CFStringRef charactersToLeaveEscaped;
+#ifndef CFURLCopyQueryString
+	PyMac_PRECHECK(CFURLCopyQueryString);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CFStringRefObj_Convert, &charactersToLeaveEscaped))
+		return NULL;
+	_rv = CFURLCopyQueryString(_self->ob_itself,
+	                           charactersToLeaveEscaped);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFURLRefObj_CFURLCopyFragment(CFURLRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef _rv;
+	CFStringRef charactersToLeaveEscaped;
+#ifndef CFURLCopyFragment
+	PyMac_PRECHECK(CFURLCopyFragment);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CFStringRefObj_Convert, &charactersToLeaveEscaped))
+		return NULL;
+	_rv = CFURLCopyFragment(_self->ob_itself,
+	                        charactersToLeaveEscaped);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFURLRefObj_CFURLCopyLastPathComponent(CFURLRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef _rv;
+#ifndef CFURLCopyLastPathComponent
+	PyMac_PRECHECK(CFURLCopyLastPathComponent);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFURLCopyLastPathComponent(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFURLRefObj_CFURLCopyPathExtension(CFURLRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef _rv;
+#ifndef CFURLCopyPathExtension
+	PyMac_PRECHECK(CFURLCopyPathExtension);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFURLCopyPathExtension(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFURLRefObj_CFURLCreateCopyAppendingPathComponent(CFURLRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFURLRef _rv;
+	CFStringRef pathComponent;
+	Boolean isDirectory;
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CFStringRefObj_Convert, &pathComponent,
+	                      &isDirectory))
+		return NULL;
+	_rv = CFURLCreateCopyAppendingPathComponent((CFAllocatorRef)NULL,
+	                                            _self->ob_itself,
+	                                            pathComponent,
+	                                            isDirectory);
+	_res = Py_BuildValue("O&",
+	                     CFURLRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFURLRefObj_CFURLCreateCopyDeletingLastPathComponent(CFURLRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFURLRef _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFURLCreateCopyDeletingLastPathComponent((CFAllocatorRef)NULL,
+	                                               _self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     CFURLRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFURLRefObj_CFURLCreateCopyAppendingPathExtension(CFURLRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFURLRef _rv;
+	CFStringRef extension;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CFStringRefObj_Convert, &extension))
+		return NULL;
+	_rv = CFURLCreateCopyAppendingPathExtension((CFAllocatorRef)NULL,
+	                                            _self->ob_itself,
+	                                            extension);
+	_res = Py_BuildValue("O&",
+	                     CFURLRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFURLRefObj_CFURLCreateCopyDeletingPathExtension(CFURLRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFURLRef _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFURLCreateCopyDeletingPathExtension((CFAllocatorRef)NULL,
+	                                           _self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     CFURLRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFURLRefObj_CFURLGetFSRef(CFURLRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	FSRef fsRef;
+#ifndef CFURLGetFSRef
+	PyMac_PRECHECK(CFURLGetFSRef);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFURLGetFSRef(_self->ob_itself,
+	                    &fsRef);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     PyMac_BuildFSRef, &fsRef);
+	return _res;
+}
+
+static PyMethodDef CFURLRefObj_methods[] = {
+	{"CFURLCreateData", (PyCFunction)CFURLRefObj_CFURLCreateData, 1,
+	 PyDoc_STR("(CFStringEncoding encoding, Boolean escapeWhitespace) -> (CFDataRef _rv)")},
+	{"CFURLGetFileSystemRepresentation", (PyCFunction)CFURLRefObj_CFURLGetFileSystemRepresentation, 1,
+	 PyDoc_STR("(Boolean resolveAgainstBase, CFIndex maxBufLen) -> (Boolean _rv, UInt8 buffer)")},
+	{"CFURLCopyAbsoluteURL", (PyCFunction)CFURLRefObj_CFURLCopyAbsoluteURL, 1,
+	 PyDoc_STR("() -> (CFURLRef _rv)")},
+	{"CFURLGetString", (PyCFunction)CFURLRefObj_CFURLGetString, 1,
+	 PyDoc_STR("() -> (CFStringRef _rv)")},
+	{"CFURLGetBaseURL", (PyCFunction)CFURLRefObj_CFURLGetBaseURL, 1,
+	 PyDoc_STR("() -> (CFURLRef _rv)")},
+	{"CFURLCanBeDecomposed", (PyCFunction)CFURLRefObj_CFURLCanBeDecomposed, 1,
+	 PyDoc_STR("() -> (Boolean _rv)")},
+	{"CFURLCopyScheme", (PyCFunction)CFURLRefObj_CFURLCopyScheme, 1,
+	 PyDoc_STR("() -> (CFStringRef _rv)")},
+	{"CFURLCopyNetLocation", (PyCFunction)CFURLRefObj_CFURLCopyNetLocation, 1,
+	 PyDoc_STR("() -> (CFStringRef _rv)")},
+	{"CFURLCopyPath", (PyCFunction)CFURLRefObj_CFURLCopyPath, 1,
+	 PyDoc_STR("() -> (CFStringRef _rv)")},
+	{"CFURLCopyStrictPath", (PyCFunction)CFURLRefObj_CFURLCopyStrictPath, 1,
+	 PyDoc_STR("() -> (CFStringRef _rv, Boolean isAbsolute)")},
+	{"CFURLCopyFileSystemPath", (PyCFunction)CFURLRefObj_CFURLCopyFileSystemPath, 1,
+	 PyDoc_STR("(CFURLPathStyle pathStyle) -> (CFStringRef _rv)")},
+	{"CFURLHasDirectoryPath", (PyCFunction)CFURLRefObj_CFURLHasDirectoryPath, 1,
+	 PyDoc_STR("() -> (Boolean _rv)")},
+	{"CFURLCopyResourceSpecifier", (PyCFunction)CFURLRefObj_CFURLCopyResourceSpecifier, 1,
+	 PyDoc_STR("() -> (CFStringRef _rv)")},
+	{"CFURLCopyHostName", (PyCFunction)CFURLRefObj_CFURLCopyHostName, 1,
+	 PyDoc_STR("() -> (CFStringRef _rv)")},
+	{"CFURLGetPortNumber", (PyCFunction)CFURLRefObj_CFURLGetPortNumber, 1,
+	 PyDoc_STR("() -> (SInt32 _rv)")},
+	{"CFURLCopyUserName", (PyCFunction)CFURLRefObj_CFURLCopyUserName, 1,
+	 PyDoc_STR("() -> (CFStringRef _rv)")},
+	{"CFURLCopyPassword", (PyCFunction)CFURLRefObj_CFURLCopyPassword, 1,
+	 PyDoc_STR("() -> (CFStringRef _rv)")},
+	{"CFURLCopyParameterString", (PyCFunction)CFURLRefObj_CFURLCopyParameterString, 1,
+	 PyDoc_STR("(CFStringRef charactersToLeaveEscaped) -> (CFStringRef _rv)")},
+	{"CFURLCopyQueryString", (PyCFunction)CFURLRefObj_CFURLCopyQueryString, 1,
+	 PyDoc_STR("(CFStringRef charactersToLeaveEscaped) -> (CFStringRef _rv)")},
+	{"CFURLCopyFragment", (PyCFunction)CFURLRefObj_CFURLCopyFragment, 1,
+	 PyDoc_STR("(CFStringRef charactersToLeaveEscaped) -> (CFStringRef _rv)")},
+	{"CFURLCopyLastPathComponent", (PyCFunction)CFURLRefObj_CFURLCopyLastPathComponent, 1,
+	 PyDoc_STR("() -> (CFStringRef _rv)")},
+	{"CFURLCopyPathExtension", (PyCFunction)CFURLRefObj_CFURLCopyPathExtension, 1,
+	 PyDoc_STR("() -> (CFStringRef _rv)")},
+	{"CFURLCreateCopyAppendingPathComponent", (PyCFunction)CFURLRefObj_CFURLCreateCopyAppendingPathComponent, 1,
+	 PyDoc_STR("(CFStringRef pathComponent, Boolean isDirectory) -> (CFURLRef _rv)")},
+	{"CFURLCreateCopyDeletingLastPathComponent", (PyCFunction)CFURLRefObj_CFURLCreateCopyDeletingLastPathComponent, 1,
+	 PyDoc_STR("() -> (CFURLRef _rv)")},
+	{"CFURLCreateCopyAppendingPathExtension", (PyCFunction)CFURLRefObj_CFURLCreateCopyAppendingPathExtension, 1,
+	 PyDoc_STR("(CFStringRef extension) -> (CFURLRef _rv)")},
+	{"CFURLCreateCopyDeletingPathExtension", (PyCFunction)CFURLRefObj_CFURLCreateCopyDeletingPathExtension, 1,
+	 PyDoc_STR("() -> (CFURLRef _rv)")},
+	{"CFURLGetFSRef", (PyCFunction)CFURLRefObj_CFURLGetFSRef, 1,
+	 PyDoc_STR("() -> (Boolean _rv, FSRef fsRef)")},
+	{NULL, NULL, 0}
+};
+
+#define CFURLRefObj_getsetlist NULL
+
+
+static int CFURLRefObj_compare(CFURLRefObject *self, CFURLRefObject *other)
+{
+	/* XXXX Or should we use CFEqual?? */
+	if ( self->ob_itself > other->ob_itself ) return 1;
+	if ( self->ob_itself < other->ob_itself ) return -1;
+	return 0;
+}
+
+static PyObject * CFURLRefObj_repr(CFURLRefObject *self)
+{
+	char buf[100];
+	sprintf(buf, "<CFURL object at 0x%8.8x for 0x%8.8x>", (unsigned)self, (unsigned)self->ob_itself);
+	return PyString_FromString(buf);
+}
+
+static int CFURLRefObj_hash(CFURLRefObject *self)
+{
+	/* XXXX Or should we use CFHash?? */
+	return (int)self->ob_itself;
+}
+static int CFURLRefObj_tp_init(PyObject *_self, PyObject *_args, PyObject *_kwds)
+{
+	CFURLRef itself;
+	char *kw[] = {"itself", 0};
+
+	if (PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, CFURLRefObj_Convert, &itself))
+	{
+		((CFURLRefObject *)_self)->ob_itself = itself;
+		return 0;
+	}
+
+	/* Any CFTypeRef descendent is allowed as initializer too */
+	if (PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, CFTypeRefObj_Convert, &itself))
+	{
+		((CFURLRefObject *)_self)->ob_itself = itself;
+		return 0;
+	}
+	return -1;
+}
+
+#define CFURLRefObj_tp_alloc PyType_GenericAlloc
+
+static PyObject *CFURLRefObj_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *self;
+	if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	((CFURLRefObject *)self)->ob_itself = NULL;
+	((CFURLRefObject *)self)->ob_freeit = CFRelease;
+	return self;
+}
+
+#define CFURLRefObj_tp_free PyObject_Del
+
+
+PyTypeObject CFURLRef_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"_CF.CFURLRef", /*tp_name*/
+	sizeof(CFURLRefObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) CFURLRefObj_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) CFURLRefObj_compare, /*tp_compare*/
+	(reprfunc) CFURLRefObj_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) CFURLRefObj_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	CFURLRefObj_methods, /* tp_methods */
+	0, /*tp_members*/
+	CFURLRefObj_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	CFURLRefObj_tp_init, /* tp_init */
+	CFURLRefObj_tp_alloc, /* tp_alloc */
+	CFURLRefObj_tp_new, /* tp_new */
+	CFURLRefObj_tp_free, /* tp_free */
+};
+
+/* -------------------- End object type CFURLRef -------------------- */
+
+
+static PyObject *CF___CFRangeMake(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFRange _rv;
+	CFIndex loc;
+	CFIndex len;
+#ifndef __CFRangeMake
+	PyMac_PRECHECK(__CFRangeMake);
+#endif
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &loc,
+	                      &len))
+		return NULL;
+	_rv = __CFRangeMake(loc,
+	                    len);
+	_res = Py_BuildValue("O&",
+	                     CFRange_New, _rv);
+	return _res;
+}
+
+static PyObject *CF_CFAllocatorGetTypeID(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFTypeID _rv;
+#ifndef CFAllocatorGetTypeID
+	PyMac_PRECHECK(CFAllocatorGetTypeID);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFAllocatorGetTypeID();
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CF_CFAllocatorGetPreferredSizeForSize(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFIndex _rv;
+	CFIndex size;
+	CFOptionFlags hint;
+#ifndef CFAllocatorGetPreferredSizeForSize
+	PyMac_PRECHECK(CFAllocatorGetPreferredSizeForSize);
+#endif
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &size,
+	                      &hint))
+		return NULL;
+	_rv = CFAllocatorGetPreferredSizeForSize((CFAllocatorRef)NULL,
+	                                         size,
+	                                         hint);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CF_CFCopyTypeIDDescription(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef _rv;
+	CFTypeID type_id;
+#ifndef CFCopyTypeIDDescription
+	PyMac_PRECHECK(CFCopyTypeIDDescription);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &type_id))
+		return NULL;
+	_rv = CFCopyTypeIDDescription(type_id);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CF_CFArrayGetTypeID(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFTypeID _rv;
+#ifndef CFArrayGetTypeID
+	PyMac_PRECHECK(CFArrayGetTypeID);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFArrayGetTypeID();
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CF_CFArrayCreateMutable(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFMutableArrayRef _rv;
+	CFIndex capacity;
+#ifndef CFArrayCreateMutable
+	PyMac_PRECHECK(CFArrayCreateMutable);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &capacity))
+		return NULL;
+	_rv = CFArrayCreateMutable((CFAllocatorRef)NULL,
+	                           capacity,
+	                           &kCFTypeArrayCallBacks);
+	_res = Py_BuildValue("O&",
+	                     CFMutableArrayRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CF_CFArrayCreateMutableCopy(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFMutableArrayRef _rv;
+	CFIndex capacity;
+	CFArrayRef theArray;
+#ifndef CFArrayCreateMutableCopy
+	PyMac_PRECHECK(CFArrayCreateMutableCopy);
+#endif
+	if (!PyArg_ParseTuple(_args, "lO&",
+	                      &capacity,
+	                      CFArrayRefObj_Convert, &theArray))
+		return NULL;
+	_rv = CFArrayCreateMutableCopy((CFAllocatorRef)NULL,
+	                               capacity,
+	                               theArray);
+	_res = Py_BuildValue("O&",
+	                     CFMutableArrayRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CF_CFDataGetTypeID(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFTypeID _rv;
+#ifndef CFDataGetTypeID
+	PyMac_PRECHECK(CFDataGetTypeID);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFDataGetTypeID();
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CF_CFDataCreate(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFDataRef _rv;
+	unsigned char *bytes__in__;
+	long bytes__len__;
+	int bytes__in_len__;
+#ifndef CFDataCreate
+	PyMac_PRECHECK(CFDataCreate);
+#endif
+	if (!PyArg_ParseTuple(_args, "s#",
+	                      &bytes__in__, &bytes__in_len__))
+		return NULL;
+	bytes__len__ = bytes__in_len__;
+	_rv = CFDataCreate((CFAllocatorRef)NULL,
+	                   bytes__in__, bytes__len__);
+	_res = Py_BuildValue("O&",
+	                     CFDataRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CF_CFDataCreateWithBytesNoCopy(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFDataRef _rv;
+	unsigned char *bytes__in__;
+	long bytes__len__;
+	int bytes__in_len__;
+#ifndef CFDataCreateWithBytesNoCopy
+	PyMac_PRECHECK(CFDataCreateWithBytesNoCopy);
+#endif
+	if (!PyArg_ParseTuple(_args, "s#",
+	                      &bytes__in__, &bytes__in_len__))
+		return NULL;
+	bytes__len__ = bytes__in_len__;
+	_rv = CFDataCreateWithBytesNoCopy((CFAllocatorRef)NULL,
+	                                  bytes__in__, bytes__len__,
+	                                  (CFAllocatorRef)NULL);
+	_res = Py_BuildValue("O&",
+	                     CFDataRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CF_CFDataCreateMutable(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFMutableDataRef _rv;
+	CFIndex capacity;
+#ifndef CFDataCreateMutable
+	PyMac_PRECHECK(CFDataCreateMutable);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &capacity))
+		return NULL;
+	_rv = CFDataCreateMutable((CFAllocatorRef)NULL,
+	                          capacity);
+	_res = Py_BuildValue("O&",
+	                     CFMutableDataRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CF_CFDataCreateMutableCopy(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFMutableDataRef _rv;
+	CFIndex capacity;
+	CFDataRef theData;
+#ifndef CFDataCreateMutableCopy
+	PyMac_PRECHECK(CFDataCreateMutableCopy);
+#endif
+	if (!PyArg_ParseTuple(_args, "lO&",
+	                      &capacity,
+	                      CFDataRefObj_Convert, &theData))
+		return NULL;
+	_rv = CFDataCreateMutableCopy((CFAllocatorRef)NULL,
+	                              capacity,
+	                              theData);
+	_res = Py_BuildValue("O&",
+	                     CFMutableDataRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CF_CFDictionaryGetTypeID(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFTypeID _rv;
+#ifndef CFDictionaryGetTypeID
+	PyMac_PRECHECK(CFDictionaryGetTypeID);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFDictionaryGetTypeID();
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CF_CFDictionaryCreateMutable(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFMutableDictionaryRef _rv;
+	CFIndex capacity;
+#ifndef CFDictionaryCreateMutable
+	PyMac_PRECHECK(CFDictionaryCreateMutable);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &capacity))
+		return NULL;
+	_rv = CFDictionaryCreateMutable((CFAllocatorRef)NULL,
+	                                capacity,
+	                                &kCFTypeDictionaryKeyCallBacks,
+	                                &kCFTypeDictionaryValueCallBacks);
+	_res = Py_BuildValue("O&",
+	                     CFMutableDictionaryRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CF_CFDictionaryCreateMutableCopy(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFMutableDictionaryRef _rv;
+	CFIndex capacity;
+	CFDictionaryRef theDict;
+#ifndef CFDictionaryCreateMutableCopy
+	PyMac_PRECHECK(CFDictionaryCreateMutableCopy);
+#endif
+	if (!PyArg_ParseTuple(_args, "lO&",
+	                      &capacity,
+	                      CFDictionaryRefObj_Convert, &theDict))
+		return NULL;
+	_rv = CFDictionaryCreateMutableCopy((CFAllocatorRef)NULL,
+	                                    capacity,
+	                                    theDict);
+	_res = Py_BuildValue("O&",
+	                     CFMutableDictionaryRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CF_CFPreferencesCopyAppValue(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFTypeRef _rv;
+	CFStringRef key;
+	CFStringRef applicationID;
+#ifndef CFPreferencesCopyAppValue
+	PyMac_PRECHECK(CFPreferencesCopyAppValue);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CFStringRefObj_Convert, &key,
+	                      CFStringRefObj_Convert, &applicationID))
+		return NULL;
+	_rv = CFPreferencesCopyAppValue(key,
+	                                applicationID);
+	_res = Py_BuildValue("O&",
+	                     CFTypeRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CF_CFPreferencesGetAppBooleanValue(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	CFStringRef key;
+	CFStringRef applicationID;
+	Boolean keyExistsAndHasValidFormat;
+#ifndef CFPreferencesGetAppBooleanValue
+	PyMac_PRECHECK(CFPreferencesGetAppBooleanValue);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CFStringRefObj_Convert, &key,
+	                      CFStringRefObj_Convert, &applicationID))
+		return NULL;
+	_rv = CFPreferencesGetAppBooleanValue(key,
+	                                      applicationID,
+	                                      &keyExistsAndHasValidFormat);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     keyExistsAndHasValidFormat);
+	return _res;
+}
+
+static PyObject *CF_CFPreferencesGetAppIntegerValue(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFIndex _rv;
+	CFStringRef key;
+	CFStringRef applicationID;
+	Boolean keyExistsAndHasValidFormat;
+#ifndef CFPreferencesGetAppIntegerValue
+	PyMac_PRECHECK(CFPreferencesGetAppIntegerValue);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CFStringRefObj_Convert, &key,
+	                      CFStringRefObj_Convert, &applicationID))
+		return NULL;
+	_rv = CFPreferencesGetAppIntegerValue(key,
+	                                      applicationID,
+	                                      &keyExistsAndHasValidFormat);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     keyExistsAndHasValidFormat);
+	return _res;
+}
+
+static PyObject *CF_CFPreferencesSetAppValue(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef key;
+	CFTypeRef value;
+	CFStringRef applicationID;
+#ifndef CFPreferencesSetAppValue
+	PyMac_PRECHECK(CFPreferencesSetAppValue);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      CFStringRefObj_Convert, &key,
+	                      CFTypeRefObj_Convert, &value,
+	                      CFStringRefObj_Convert, &applicationID))
+		return NULL;
+	CFPreferencesSetAppValue(key,
+	                         value,
+	                         applicationID);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CF_CFPreferencesAddSuitePreferencesToApp(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef applicationID;
+	CFStringRef suiteID;
+#ifndef CFPreferencesAddSuitePreferencesToApp
+	PyMac_PRECHECK(CFPreferencesAddSuitePreferencesToApp);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CFStringRefObj_Convert, &applicationID,
+	                      CFStringRefObj_Convert, &suiteID))
+		return NULL;
+	CFPreferencesAddSuitePreferencesToApp(applicationID,
+	                                      suiteID);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CF_CFPreferencesRemoveSuitePreferencesFromApp(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef applicationID;
+	CFStringRef suiteID;
+#ifndef CFPreferencesRemoveSuitePreferencesFromApp
+	PyMac_PRECHECK(CFPreferencesRemoveSuitePreferencesFromApp);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CFStringRefObj_Convert, &applicationID,
+	                      CFStringRefObj_Convert, &suiteID))
+		return NULL;
+	CFPreferencesRemoveSuitePreferencesFromApp(applicationID,
+	                                           suiteID);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CF_CFPreferencesAppSynchronize(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	CFStringRef applicationID;
+#ifndef CFPreferencesAppSynchronize
+	PyMac_PRECHECK(CFPreferencesAppSynchronize);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CFStringRefObj_Convert, &applicationID))
+		return NULL;
+	_rv = CFPreferencesAppSynchronize(applicationID);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CF_CFPreferencesCopyValue(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFTypeRef _rv;
+	CFStringRef key;
+	CFStringRef applicationID;
+	CFStringRef userName;
+	CFStringRef hostName;
+#ifndef CFPreferencesCopyValue
+	PyMac_PRECHECK(CFPreferencesCopyValue);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&O&",
+	                      CFStringRefObj_Convert, &key,
+	                      CFStringRefObj_Convert, &applicationID,
+	                      CFStringRefObj_Convert, &userName,
+	                      CFStringRefObj_Convert, &hostName))
+		return NULL;
+	_rv = CFPreferencesCopyValue(key,
+	                             applicationID,
+	                             userName,
+	                             hostName);
+	_res = Py_BuildValue("O&",
+	                     CFTypeRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CF_CFPreferencesCopyMultiple(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFDictionaryRef _rv;
+	CFArrayRef keysToFetch;
+	CFStringRef applicationID;
+	CFStringRef userName;
+	CFStringRef hostName;
+#ifndef CFPreferencesCopyMultiple
+	PyMac_PRECHECK(CFPreferencesCopyMultiple);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&O&",
+	                      CFArrayRefObj_Convert, &keysToFetch,
+	                      CFStringRefObj_Convert, &applicationID,
+	                      CFStringRefObj_Convert, &userName,
+	                      CFStringRefObj_Convert, &hostName))
+		return NULL;
+	_rv = CFPreferencesCopyMultiple(keysToFetch,
+	                                applicationID,
+	                                userName,
+	                                hostName);
+	_res = Py_BuildValue("O&",
+	                     CFDictionaryRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CF_CFPreferencesSetValue(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef key;
+	CFTypeRef value;
+	CFStringRef applicationID;
+	CFStringRef userName;
+	CFStringRef hostName;
+#ifndef CFPreferencesSetValue
+	PyMac_PRECHECK(CFPreferencesSetValue);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&O&O&",
+	                      CFStringRefObj_Convert, &key,
+	                      CFTypeRefObj_Convert, &value,
+	                      CFStringRefObj_Convert, &applicationID,
+	                      CFStringRefObj_Convert, &userName,
+	                      CFStringRefObj_Convert, &hostName))
+		return NULL;
+	CFPreferencesSetValue(key,
+	                      value,
+	                      applicationID,
+	                      userName,
+	                      hostName);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CF_CFPreferencesSetMultiple(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFDictionaryRef keysToSet;
+	CFArrayRef keysToRemove;
+	CFStringRef applicationID;
+	CFStringRef userName;
+	CFStringRef hostName;
+#ifndef CFPreferencesSetMultiple
+	PyMac_PRECHECK(CFPreferencesSetMultiple);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&O&O&",
+	                      CFDictionaryRefObj_Convert, &keysToSet,
+	                      CFArrayRefObj_Convert, &keysToRemove,
+	                      CFStringRefObj_Convert, &applicationID,
+	                      CFStringRefObj_Convert, &userName,
+	                      CFStringRefObj_Convert, &hostName))
+		return NULL;
+	CFPreferencesSetMultiple(keysToSet,
+	                         keysToRemove,
+	                         applicationID,
+	                         userName,
+	                         hostName);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CF_CFPreferencesSynchronize(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	CFStringRef applicationID;
+	CFStringRef userName;
+	CFStringRef hostName;
+#ifndef CFPreferencesSynchronize
+	PyMac_PRECHECK(CFPreferencesSynchronize);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      CFStringRefObj_Convert, &applicationID,
+	                      CFStringRefObj_Convert, &userName,
+	                      CFStringRefObj_Convert, &hostName))
+		return NULL;
+	_rv = CFPreferencesSynchronize(applicationID,
+	                               userName,
+	                               hostName);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CF_CFPreferencesCopyApplicationList(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFArrayRef _rv;
+	CFStringRef userName;
+	CFStringRef hostName;
+#ifndef CFPreferencesCopyApplicationList
+	PyMac_PRECHECK(CFPreferencesCopyApplicationList);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CFStringRefObj_Convert, &userName,
+	                      CFStringRefObj_Convert, &hostName))
+		return NULL;
+	_rv = CFPreferencesCopyApplicationList(userName,
+	                                       hostName);
+	_res = Py_BuildValue("O&",
+	                     CFArrayRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CF_CFPreferencesCopyKeyList(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFArrayRef _rv;
+	CFStringRef applicationID;
+	CFStringRef userName;
+	CFStringRef hostName;
+#ifndef CFPreferencesCopyKeyList
+	PyMac_PRECHECK(CFPreferencesCopyKeyList);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      CFStringRefObj_Convert, &applicationID,
+	                      CFStringRefObj_Convert, &userName,
+	                      CFStringRefObj_Convert, &hostName))
+		return NULL;
+	_rv = CFPreferencesCopyKeyList(applicationID,
+	                               userName,
+	                               hostName);
+	_res = Py_BuildValue("O&",
+	                     CFArrayRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CF_CFStringGetTypeID(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFTypeID _rv;
+#ifndef CFStringGetTypeID
+	PyMac_PRECHECK(CFStringGetTypeID);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFStringGetTypeID();
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CF_CFStringCreateWithPascalString(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef _rv;
+	Str255 pStr;
+	CFStringEncoding encoding;
+#ifndef CFStringCreateWithPascalString
+	PyMac_PRECHECK(CFStringCreateWithPascalString);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      PyMac_GetStr255, pStr,
+	                      &encoding))
+		return NULL;
+	_rv = CFStringCreateWithPascalString((CFAllocatorRef)NULL,
+	                                     pStr,
+	                                     encoding);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CF_CFStringCreateWithCString(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef _rv;
+	char* cStr;
+	CFStringEncoding encoding;
+#ifndef CFStringCreateWithCString
+	PyMac_PRECHECK(CFStringCreateWithCString);
+#endif
+	if (!PyArg_ParseTuple(_args, "sl",
+	                      &cStr,
+	                      &encoding))
+		return NULL;
+	_rv = CFStringCreateWithCString((CFAllocatorRef)NULL,
+	                                cStr,
+	                                encoding);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CF_CFStringCreateWithCharacters(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef _rv;
+	UniChar *chars__in__;
+	UniCharCount chars__len__;
+	int chars__in_len__;
+#ifndef CFStringCreateWithCharacters
+	PyMac_PRECHECK(CFStringCreateWithCharacters);
+#endif
+	if (!PyArg_ParseTuple(_args, "u#",
+	                      &chars__in__, &chars__in_len__))
+		return NULL;
+	chars__len__ = chars__in_len__;
+	_rv = CFStringCreateWithCharacters((CFAllocatorRef)NULL,
+	                                   chars__in__, chars__len__);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CF_CFStringCreateWithPascalStringNoCopy(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef _rv;
+	Str255 pStr;
+	CFStringEncoding encoding;
+#ifndef CFStringCreateWithPascalStringNoCopy
+	PyMac_PRECHECK(CFStringCreateWithPascalStringNoCopy);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      PyMac_GetStr255, pStr,
+	                      &encoding))
+		return NULL;
+	_rv = CFStringCreateWithPascalStringNoCopy((CFAllocatorRef)NULL,
+	                                           pStr,
+	                                           encoding,
+	                                           (CFAllocatorRef)NULL);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CF_CFStringCreateWithCStringNoCopy(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef _rv;
+	char* cStr;
+	CFStringEncoding encoding;
+#ifndef CFStringCreateWithCStringNoCopy
+	PyMac_PRECHECK(CFStringCreateWithCStringNoCopy);
+#endif
+	if (!PyArg_ParseTuple(_args, "sl",
+	                      &cStr,
+	                      &encoding))
+		return NULL;
+	_rv = CFStringCreateWithCStringNoCopy((CFAllocatorRef)NULL,
+	                                      cStr,
+	                                      encoding,
+	                                      (CFAllocatorRef)NULL);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CF_CFStringCreateWithCharactersNoCopy(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef _rv;
+	UniChar *chars__in__;
+	UniCharCount chars__len__;
+	int chars__in_len__;
+#ifndef CFStringCreateWithCharactersNoCopy
+	PyMac_PRECHECK(CFStringCreateWithCharactersNoCopy);
+#endif
+	if (!PyArg_ParseTuple(_args, "u#",
+	                      &chars__in__, &chars__in_len__))
+		return NULL;
+	chars__len__ = chars__in_len__;
+	_rv = CFStringCreateWithCharactersNoCopy((CFAllocatorRef)NULL,
+	                                         chars__in__, chars__len__,
+	                                         (CFAllocatorRef)NULL);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CF_CFStringCreateMutable(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFMutableStringRef _rv;
+	CFIndex maxLength;
+#ifndef CFStringCreateMutable
+	PyMac_PRECHECK(CFStringCreateMutable);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &maxLength))
+		return NULL;
+	_rv = CFStringCreateMutable((CFAllocatorRef)NULL,
+	                            maxLength);
+	_res = Py_BuildValue("O&",
+	                     CFMutableStringRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CF_CFStringCreateMutableCopy(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFMutableStringRef _rv;
+	CFIndex maxLength;
+	CFStringRef theString;
+#ifndef CFStringCreateMutableCopy
+	PyMac_PRECHECK(CFStringCreateMutableCopy);
+#endif
+	if (!PyArg_ParseTuple(_args, "lO&",
+	                      &maxLength,
+	                      CFStringRefObj_Convert, &theString))
+		return NULL;
+	_rv = CFStringCreateMutableCopy((CFAllocatorRef)NULL,
+	                                maxLength,
+	                                theString);
+	_res = Py_BuildValue("O&",
+	                     CFMutableStringRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CF_CFStringCreateWithBytes(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef _rv;
+	unsigned char *bytes__in__;
+	long bytes__len__;
+	int bytes__in_len__;
+	CFStringEncoding encoding;
+	Boolean isExternalRepresentation;
+#ifndef CFStringCreateWithBytes
+	PyMac_PRECHECK(CFStringCreateWithBytes);
+#endif
+	if (!PyArg_ParseTuple(_args, "s#ll",
+	                      &bytes__in__, &bytes__in_len__,
+	                      &encoding,
+	                      &isExternalRepresentation))
+		return NULL;
+	bytes__len__ = bytes__in_len__;
+	_rv = CFStringCreateWithBytes((CFAllocatorRef)NULL,
+	                              bytes__in__, bytes__len__,
+	                              encoding,
+	                              isExternalRepresentation);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CF_CFStringGetSystemEncoding(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringEncoding _rv;
+#ifndef CFStringGetSystemEncoding
+	PyMac_PRECHECK(CFStringGetSystemEncoding);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFStringGetSystemEncoding();
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CF_CFStringGetMaximumSizeForEncoding(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFIndex _rv;
+	CFIndex length;
+	CFStringEncoding encoding;
+#ifndef CFStringGetMaximumSizeForEncoding
+	PyMac_PRECHECK(CFStringGetMaximumSizeForEncoding);
+#endif
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &length,
+	                      &encoding))
+		return NULL;
+	_rv = CFStringGetMaximumSizeForEncoding(length,
+	                                        encoding);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CF_CFStringIsEncodingAvailable(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	CFStringEncoding encoding;
+#ifndef CFStringIsEncodingAvailable
+	PyMac_PRECHECK(CFStringIsEncodingAvailable);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &encoding))
+		return NULL;
+	_rv = CFStringIsEncodingAvailable(encoding);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CF_CFStringGetNameOfEncoding(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef _rv;
+	CFStringEncoding encoding;
+#ifndef CFStringGetNameOfEncoding
+	PyMac_PRECHECK(CFStringGetNameOfEncoding);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &encoding))
+		return NULL;
+	_rv = CFStringGetNameOfEncoding(encoding);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CF_CFStringConvertEncodingToNSStringEncoding(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	UInt32 _rv;
+	CFStringEncoding encoding;
+#ifndef CFStringConvertEncodingToNSStringEncoding
+	PyMac_PRECHECK(CFStringConvertEncodingToNSStringEncoding);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &encoding))
+		return NULL;
+	_rv = CFStringConvertEncodingToNSStringEncoding(encoding);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CF_CFStringConvertNSStringEncodingToEncoding(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringEncoding _rv;
+	UInt32 encoding;
+#ifndef CFStringConvertNSStringEncodingToEncoding
+	PyMac_PRECHECK(CFStringConvertNSStringEncodingToEncoding);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &encoding))
+		return NULL;
+	_rv = CFStringConvertNSStringEncodingToEncoding(encoding);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CF_CFStringConvertEncodingToWindowsCodepage(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	UInt32 _rv;
+	CFStringEncoding encoding;
+#ifndef CFStringConvertEncodingToWindowsCodepage
+	PyMac_PRECHECK(CFStringConvertEncodingToWindowsCodepage);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &encoding))
+		return NULL;
+	_rv = CFStringConvertEncodingToWindowsCodepage(encoding);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CF_CFStringConvertWindowsCodepageToEncoding(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringEncoding _rv;
+	UInt32 codepage;
+#ifndef CFStringConvertWindowsCodepageToEncoding
+	PyMac_PRECHECK(CFStringConvertWindowsCodepageToEncoding);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &codepage))
+		return NULL;
+	_rv = CFStringConvertWindowsCodepageToEncoding(codepage);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CF_CFStringConvertEncodingToIANACharSetName(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef _rv;
+	CFStringEncoding encoding;
+#ifndef CFStringConvertEncodingToIANACharSetName
+	PyMac_PRECHECK(CFStringConvertEncodingToIANACharSetName);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &encoding))
+		return NULL;
+	_rv = CFStringConvertEncodingToIANACharSetName(encoding);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CF_CFStringGetMostCompatibleMacStringEncoding(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringEncoding _rv;
+	CFStringEncoding encoding;
+#ifndef CFStringGetMostCompatibleMacStringEncoding
+	PyMac_PRECHECK(CFStringGetMostCompatibleMacStringEncoding);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &encoding))
+		return NULL;
+	_rv = CFStringGetMostCompatibleMacStringEncoding(encoding);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CF___CFStringMakeConstantString(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef _rv;
+	char* cStr;
+#ifndef __CFStringMakeConstantString
+	PyMac_PRECHECK(__CFStringMakeConstantString);
+#endif
+	if (!PyArg_ParseTuple(_args, "s",
+	                      &cStr))
+		return NULL;
+	_rv = __CFStringMakeConstantString(cStr);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CF_CFURLGetTypeID(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFTypeID _rv;
+#ifndef CFURLGetTypeID
+	PyMac_PRECHECK(CFURLGetTypeID);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFURLGetTypeID();
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CF_CFURLCreateWithBytes(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFURLRef _rv;
+	unsigned char *URLBytes__in__;
+	long URLBytes__len__;
+	int URLBytes__in_len__;
+	CFStringEncoding encoding;
+	CFURLRef baseURL;
+#ifndef CFURLCreateWithBytes
+	PyMac_PRECHECK(CFURLCreateWithBytes);
+#endif
+	if (!PyArg_ParseTuple(_args, "s#lO&",
+	                      &URLBytes__in__, &URLBytes__in_len__,
+	                      &encoding,
+	                      OptionalCFURLRefObj_Convert, &baseURL))
+		return NULL;
+	URLBytes__len__ = URLBytes__in_len__;
+	_rv = CFURLCreateWithBytes((CFAllocatorRef)NULL,
+	                           URLBytes__in__, URLBytes__len__,
+	                           encoding,
+	                           baseURL);
+	_res = Py_BuildValue("O&",
+	                     CFURLRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CF_CFURLCreateFromFileSystemRepresentation(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFURLRef _rv;
+	unsigned char *buffer__in__;
+	long buffer__len__;
+	int buffer__in_len__;
+	Boolean isDirectory;
+#ifndef CFURLCreateFromFileSystemRepresentation
+	PyMac_PRECHECK(CFURLCreateFromFileSystemRepresentation);
+#endif
+	if (!PyArg_ParseTuple(_args, "s#l",
+	                      &buffer__in__, &buffer__in_len__,
+	                      &isDirectory))
+		return NULL;
+	buffer__len__ = buffer__in_len__;
+	_rv = CFURLCreateFromFileSystemRepresentation((CFAllocatorRef)NULL,
+	                                              buffer__in__, buffer__len__,
+	                                              isDirectory);
+	_res = Py_BuildValue("O&",
+	                     CFURLRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CF_CFURLCreateFromFileSystemRepresentationRelativeToBase(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFURLRef _rv;
+	unsigned char *buffer__in__;
+	long buffer__len__;
+	int buffer__in_len__;
+	Boolean isDirectory;
+	CFURLRef baseURL;
+#ifndef CFURLCreateFromFileSystemRepresentationRelativeToBase
+	PyMac_PRECHECK(CFURLCreateFromFileSystemRepresentationRelativeToBase);
+#endif
+	if (!PyArg_ParseTuple(_args, "s#lO&",
+	                      &buffer__in__, &buffer__in_len__,
+	                      &isDirectory,
+	                      OptionalCFURLRefObj_Convert, &baseURL))
+		return NULL;
+	buffer__len__ = buffer__in_len__;
+	_rv = CFURLCreateFromFileSystemRepresentationRelativeToBase((CFAllocatorRef)NULL,
+	                                                            buffer__in__, buffer__len__,
+	                                                            isDirectory,
+	                                                            baseURL);
+	_res = Py_BuildValue("O&",
+	                     CFURLRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CF_CFURLCreateFromFSRef(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFURLRef _rv;
+	FSRef fsRef;
+#ifndef CFURLCreateFromFSRef
+	PyMac_PRECHECK(CFURLCreateFromFSRef);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetFSRef, &fsRef))
+		return NULL;
+	_rv = CFURLCreateFromFSRef((CFAllocatorRef)NULL,
+	                           &fsRef);
+	_res = Py_BuildValue("O&",
+	                     CFURLRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CF_toCF(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+
+	CFTypeRef rv;
+	CFTypeID typeid;
+
+	if (!PyArg_ParseTuple(_args, "O&", PyCF_Python2CF, &rv))
+	        return NULL;
+	typeid = CFGetTypeID(rv);
+
+	if (typeid == CFStringGetTypeID())
+	        return Py_BuildValue("O&", CFStringRefObj_New, rv);
+	if (typeid == CFArrayGetTypeID())
+	        return Py_BuildValue("O&", CFArrayRefObj_New, rv);
+	if (typeid == CFDictionaryGetTypeID())
+	        return Py_BuildValue("O&", CFDictionaryRefObj_New, rv);
+	if (typeid == CFURLGetTypeID())
+	        return Py_BuildValue("O&", CFURLRefObj_New, rv);
+
+	_res = Py_BuildValue("O&", CFTypeRefObj_New, rv);
+	return _res;
+
+}
+
+static PyMethodDef CF_methods[] = {
+	{"__CFRangeMake", (PyCFunction)CF___CFRangeMake, 1,
+	 PyDoc_STR("(CFIndex loc, CFIndex len) -> (CFRange _rv)")},
+	{"CFAllocatorGetTypeID", (PyCFunction)CF_CFAllocatorGetTypeID, 1,
+	 PyDoc_STR("() -> (CFTypeID _rv)")},
+	{"CFAllocatorGetPreferredSizeForSize", (PyCFunction)CF_CFAllocatorGetPreferredSizeForSize, 1,
+	 PyDoc_STR("(CFIndex size, CFOptionFlags hint) -> (CFIndex _rv)")},
+	{"CFCopyTypeIDDescription", (PyCFunction)CF_CFCopyTypeIDDescription, 1,
+	 PyDoc_STR("(CFTypeID type_id) -> (CFStringRef _rv)")},
+	{"CFArrayGetTypeID", (PyCFunction)CF_CFArrayGetTypeID, 1,
+	 PyDoc_STR("() -> (CFTypeID _rv)")},
+	{"CFArrayCreateMutable", (PyCFunction)CF_CFArrayCreateMutable, 1,
+	 PyDoc_STR("(CFIndex capacity) -> (CFMutableArrayRef _rv)")},
+	{"CFArrayCreateMutableCopy", (PyCFunction)CF_CFArrayCreateMutableCopy, 1,
+	 PyDoc_STR("(CFIndex capacity, CFArrayRef theArray) -> (CFMutableArrayRef _rv)")},
+	{"CFDataGetTypeID", (PyCFunction)CF_CFDataGetTypeID, 1,
+	 PyDoc_STR("() -> (CFTypeID _rv)")},
+	{"CFDataCreate", (PyCFunction)CF_CFDataCreate, 1,
+	 PyDoc_STR("(Buffer bytes) -> (CFDataRef _rv)")},
+	{"CFDataCreateWithBytesNoCopy", (PyCFunction)CF_CFDataCreateWithBytesNoCopy, 1,
+	 PyDoc_STR("(Buffer bytes) -> (CFDataRef _rv)")},
+	{"CFDataCreateMutable", (PyCFunction)CF_CFDataCreateMutable, 1,
+	 PyDoc_STR("(CFIndex capacity) -> (CFMutableDataRef _rv)")},
+	{"CFDataCreateMutableCopy", (PyCFunction)CF_CFDataCreateMutableCopy, 1,
+	 PyDoc_STR("(CFIndex capacity, CFDataRef theData) -> (CFMutableDataRef _rv)")},
+	{"CFDictionaryGetTypeID", (PyCFunction)CF_CFDictionaryGetTypeID, 1,
+	 PyDoc_STR("() -> (CFTypeID _rv)")},
+	{"CFDictionaryCreateMutable", (PyCFunction)CF_CFDictionaryCreateMutable, 1,
+	 PyDoc_STR("(CFIndex capacity) -> (CFMutableDictionaryRef _rv)")},
+	{"CFDictionaryCreateMutableCopy", (PyCFunction)CF_CFDictionaryCreateMutableCopy, 1,
+	 PyDoc_STR("(CFIndex capacity, CFDictionaryRef theDict) -> (CFMutableDictionaryRef _rv)")},
+	{"CFPreferencesCopyAppValue", (PyCFunction)CF_CFPreferencesCopyAppValue, 1,
+	 PyDoc_STR("(CFStringRef key, CFStringRef applicationID) -> (CFTypeRef _rv)")},
+	{"CFPreferencesGetAppBooleanValue", (PyCFunction)CF_CFPreferencesGetAppBooleanValue, 1,
+	 PyDoc_STR("(CFStringRef key, CFStringRef applicationID) -> (Boolean _rv, Boolean keyExistsAndHasValidFormat)")},
+	{"CFPreferencesGetAppIntegerValue", (PyCFunction)CF_CFPreferencesGetAppIntegerValue, 1,
+	 PyDoc_STR("(CFStringRef key, CFStringRef applicationID) -> (CFIndex _rv, Boolean keyExistsAndHasValidFormat)")},
+	{"CFPreferencesSetAppValue", (PyCFunction)CF_CFPreferencesSetAppValue, 1,
+	 PyDoc_STR("(CFStringRef key, CFTypeRef value, CFStringRef applicationID) -> None")},
+	{"CFPreferencesAddSuitePreferencesToApp", (PyCFunction)CF_CFPreferencesAddSuitePreferencesToApp, 1,
+	 PyDoc_STR("(CFStringRef applicationID, CFStringRef suiteID) -> None")},
+	{"CFPreferencesRemoveSuitePreferencesFromApp", (PyCFunction)CF_CFPreferencesRemoveSuitePreferencesFromApp, 1,
+	 PyDoc_STR("(CFStringRef applicationID, CFStringRef suiteID) -> None")},
+	{"CFPreferencesAppSynchronize", (PyCFunction)CF_CFPreferencesAppSynchronize, 1,
+	 PyDoc_STR("(CFStringRef applicationID) -> (Boolean _rv)")},
+	{"CFPreferencesCopyValue", (PyCFunction)CF_CFPreferencesCopyValue, 1,
+	 PyDoc_STR("(CFStringRef key, CFStringRef applicationID, CFStringRef userName, CFStringRef hostName) -> (CFTypeRef _rv)")},
+	{"CFPreferencesCopyMultiple", (PyCFunction)CF_CFPreferencesCopyMultiple, 1,
+	 PyDoc_STR("(CFArrayRef keysToFetch, CFStringRef applicationID, CFStringRef userName, CFStringRef hostName) -> (CFDictionaryRef _rv)")},
+	{"CFPreferencesSetValue", (PyCFunction)CF_CFPreferencesSetValue, 1,
+	 PyDoc_STR("(CFStringRef key, CFTypeRef value, CFStringRef applicationID, CFStringRef userName, CFStringRef hostName) -> None")},
+	{"CFPreferencesSetMultiple", (PyCFunction)CF_CFPreferencesSetMultiple, 1,
+	 PyDoc_STR("(CFDictionaryRef keysToSet, CFArrayRef keysToRemove, CFStringRef applicationID, CFStringRef userName, CFStringRef hostName) -> None")},
+	{"CFPreferencesSynchronize", (PyCFunction)CF_CFPreferencesSynchronize, 1,
+	 PyDoc_STR("(CFStringRef applicationID, CFStringRef userName, CFStringRef hostName) -> (Boolean _rv)")},
+	{"CFPreferencesCopyApplicationList", (PyCFunction)CF_CFPreferencesCopyApplicationList, 1,
+	 PyDoc_STR("(CFStringRef userName, CFStringRef hostName) -> (CFArrayRef _rv)")},
+	{"CFPreferencesCopyKeyList", (PyCFunction)CF_CFPreferencesCopyKeyList, 1,
+	 PyDoc_STR("(CFStringRef applicationID, CFStringRef userName, CFStringRef hostName) -> (CFArrayRef _rv)")},
+	{"CFStringGetTypeID", (PyCFunction)CF_CFStringGetTypeID, 1,
+	 PyDoc_STR("() -> (CFTypeID _rv)")},
+	{"CFStringCreateWithPascalString", (PyCFunction)CF_CFStringCreateWithPascalString, 1,
+	 PyDoc_STR("(Str255 pStr, CFStringEncoding encoding) -> (CFStringRef _rv)")},
+	{"CFStringCreateWithCString", (PyCFunction)CF_CFStringCreateWithCString, 1,
+	 PyDoc_STR("(char* cStr, CFStringEncoding encoding) -> (CFStringRef _rv)")},
+	{"CFStringCreateWithCharacters", (PyCFunction)CF_CFStringCreateWithCharacters, 1,
+	 PyDoc_STR("(Buffer chars) -> (CFStringRef _rv)")},
+	{"CFStringCreateWithPascalStringNoCopy", (PyCFunction)CF_CFStringCreateWithPascalStringNoCopy, 1,
+	 PyDoc_STR("(Str255 pStr, CFStringEncoding encoding) -> (CFStringRef _rv)")},
+	{"CFStringCreateWithCStringNoCopy", (PyCFunction)CF_CFStringCreateWithCStringNoCopy, 1,
+	 PyDoc_STR("(char* cStr, CFStringEncoding encoding) -> (CFStringRef _rv)")},
+	{"CFStringCreateWithCharactersNoCopy", (PyCFunction)CF_CFStringCreateWithCharactersNoCopy, 1,
+	 PyDoc_STR("(Buffer chars) -> (CFStringRef _rv)")},
+	{"CFStringCreateMutable", (PyCFunction)CF_CFStringCreateMutable, 1,
+	 PyDoc_STR("(CFIndex maxLength) -> (CFMutableStringRef _rv)")},
+	{"CFStringCreateMutableCopy", (PyCFunction)CF_CFStringCreateMutableCopy, 1,
+	 PyDoc_STR("(CFIndex maxLength, CFStringRef theString) -> (CFMutableStringRef _rv)")},
+	{"CFStringCreateWithBytes", (PyCFunction)CF_CFStringCreateWithBytes, 1,
+	 PyDoc_STR("(Buffer bytes, CFStringEncoding encoding, Boolean isExternalRepresentation) -> (CFStringRef _rv)")},
+	{"CFStringGetSystemEncoding", (PyCFunction)CF_CFStringGetSystemEncoding, 1,
+	 PyDoc_STR("() -> (CFStringEncoding _rv)")},
+	{"CFStringGetMaximumSizeForEncoding", (PyCFunction)CF_CFStringGetMaximumSizeForEncoding, 1,
+	 PyDoc_STR("(CFIndex length, CFStringEncoding encoding) -> (CFIndex _rv)")},
+	{"CFStringIsEncodingAvailable", (PyCFunction)CF_CFStringIsEncodingAvailable, 1,
+	 PyDoc_STR("(CFStringEncoding encoding) -> (Boolean _rv)")},
+	{"CFStringGetNameOfEncoding", (PyCFunction)CF_CFStringGetNameOfEncoding, 1,
+	 PyDoc_STR("(CFStringEncoding encoding) -> (CFStringRef _rv)")},
+	{"CFStringConvertEncodingToNSStringEncoding", (PyCFunction)CF_CFStringConvertEncodingToNSStringEncoding, 1,
+	 PyDoc_STR("(CFStringEncoding encoding) -> (UInt32 _rv)")},
+	{"CFStringConvertNSStringEncodingToEncoding", (PyCFunction)CF_CFStringConvertNSStringEncodingToEncoding, 1,
+	 PyDoc_STR("(UInt32 encoding) -> (CFStringEncoding _rv)")},
+	{"CFStringConvertEncodingToWindowsCodepage", (PyCFunction)CF_CFStringConvertEncodingToWindowsCodepage, 1,
+	 PyDoc_STR("(CFStringEncoding encoding) -> (UInt32 _rv)")},
+	{"CFStringConvertWindowsCodepageToEncoding", (PyCFunction)CF_CFStringConvertWindowsCodepageToEncoding, 1,
+	 PyDoc_STR("(UInt32 codepage) -> (CFStringEncoding _rv)")},
+	{"CFStringConvertEncodingToIANACharSetName", (PyCFunction)CF_CFStringConvertEncodingToIANACharSetName, 1,
+	 PyDoc_STR("(CFStringEncoding encoding) -> (CFStringRef _rv)")},
+	{"CFStringGetMostCompatibleMacStringEncoding", (PyCFunction)CF_CFStringGetMostCompatibleMacStringEncoding, 1,
+	 PyDoc_STR("(CFStringEncoding encoding) -> (CFStringEncoding _rv)")},
+	{"__CFStringMakeConstantString", (PyCFunction)CF___CFStringMakeConstantString, 1,
+	 PyDoc_STR("(char* cStr) -> (CFStringRef _rv)")},
+	{"CFURLGetTypeID", (PyCFunction)CF_CFURLGetTypeID, 1,
+	 PyDoc_STR("() -> (CFTypeID _rv)")},
+	{"CFURLCreateWithBytes", (PyCFunction)CF_CFURLCreateWithBytes, 1,
+	 PyDoc_STR("(Buffer URLBytes, CFStringEncoding encoding, CFURLRef baseURL) -> (CFURLRef _rv)")},
+	{"CFURLCreateFromFileSystemRepresentation", (PyCFunction)CF_CFURLCreateFromFileSystemRepresentation, 1,
+	 PyDoc_STR("(Buffer buffer, Boolean isDirectory) -> (CFURLRef _rv)")},
+	{"CFURLCreateFromFileSystemRepresentationRelativeToBase", (PyCFunction)CF_CFURLCreateFromFileSystemRepresentationRelativeToBase, 1,
+	 PyDoc_STR("(Buffer buffer, Boolean isDirectory, CFURLRef baseURL) -> (CFURLRef _rv)")},
+	{"CFURLCreateFromFSRef", (PyCFunction)CF_CFURLCreateFromFSRef, 1,
+	 PyDoc_STR("(FSRef fsRef) -> (CFURLRef _rv)")},
+	{"toCF", (PyCFunction)CF_toCF, 1,
+	 PyDoc_STR("(python_object) -> (CF_object)")},
+	{NULL, NULL, 0}
+};
+
+
+
+
+/* Routines to convert any CF type to/from the corresponding CFxxxObj */
+PyObject *CFObj_New(CFTypeRef itself)
+{
+        if (itself == NULL)
+        {
+                PyErr_SetString(PyExc_RuntimeError, "cannot wrap NULL");
+                return NULL;
+        }
+        if (CFGetTypeID(itself) == CFArrayGetTypeID()) return CFArrayRefObj_New((CFArrayRef)itself);
+        if (CFGetTypeID(itself) == CFDictionaryGetTypeID()) return CFDictionaryRefObj_New((CFDictionaryRef)itself);
+        if (CFGetTypeID(itself) == CFDataGetTypeID()) return CFDataRefObj_New((CFDataRef)itself);
+        if (CFGetTypeID(itself) == CFStringGetTypeID()) return CFStringRefObj_New((CFStringRef)itself);
+        if (CFGetTypeID(itself) == CFURLGetTypeID()) return CFURLRefObj_New((CFURLRef)itself);
+        /* XXXX Or should we use PyCF_CF2Python here?? */
+        return CFTypeRefObj_New(itself);
+}
+int CFObj_Convert(PyObject *v, CFTypeRef *p_itself)
+{
+
+        if (v == Py_None) { *p_itself = NULL; return 1; }
+        /* Check for other CF objects here */
+
+        if (!CFTypeRefObj_Check(v) &&
+                !CFArrayRefObj_Check(v) &&
+                !CFMutableArrayRefObj_Check(v) &&
+                !CFDictionaryRefObj_Check(v) &&
+                !CFMutableDictionaryRefObj_Check(v) &&
+                !CFDataRefObj_Check(v) &&
+                !CFMutableDataRefObj_Check(v) &&
+                !CFStringRefObj_Check(v) &&
+                !CFMutableStringRefObj_Check(v) &&
+                !CFURLRefObj_Check(v) )
+        {
+                /* XXXX Or should we use PyCF_Python2CF here?? */
+                PyErr_SetString(PyExc_TypeError, "CF object required");
+                return 0;
+        }
+        *p_itself = ((CFTypeRefObject *)v)->ob_itself;
+        return 1;
+}
+
+
+void init_CF(void)
+{
+	PyObject *m;
+	PyObject *d;
+
+
+
+	PyMac_INIT_TOOLBOX_OBJECT_NEW(CFTypeRef, CFObj_New);
+	PyMac_INIT_TOOLBOX_OBJECT_CONVERT(CFTypeRef, CFObj_Convert);
+	PyMac_INIT_TOOLBOX_OBJECT_NEW(CFTypeRef, CFTypeRefObj_New);
+	PyMac_INIT_TOOLBOX_OBJECT_CONVERT(CFTypeRef, CFTypeRefObj_Convert);
+	PyMac_INIT_TOOLBOX_OBJECT_NEW(CFStringRef, CFStringRefObj_New);
+	PyMac_INIT_TOOLBOX_OBJECT_CONVERT(CFStringRef, CFStringRefObj_Convert);
+	PyMac_INIT_TOOLBOX_OBJECT_NEW(CFMutableStringRef, CFMutableStringRefObj_New);
+	PyMac_INIT_TOOLBOX_OBJECT_CONVERT(CFMutableStringRef, CFMutableStringRefObj_Convert);
+	PyMac_INIT_TOOLBOX_OBJECT_NEW(CFArrayRef, CFArrayRefObj_New);
+	PyMac_INIT_TOOLBOX_OBJECT_CONVERT(CFArrayRef, CFArrayRefObj_Convert);
+	PyMac_INIT_TOOLBOX_OBJECT_NEW(CFMutableArrayRef, CFMutableArrayRefObj_New);
+	PyMac_INIT_TOOLBOX_OBJECT_CONVERT(CFMutableArrayRef, CFMutableArrayRefObj_Convert);
+	PyMac_INIT_TOOLBOX_OBJECT_NEW(CFDictionaryRef, CFDictionaryRefObj_New);
+	PyMac_INIT_TOOLBOX_OBJECT_CONVERT(CFDictionaryRef, CFDictionaryRefObj_Convert);
+	PyMac_INIT_TOOLBOX_OBJECT_NEW(CFMutableDictionaryRef, CFMutableDictionaryRefObj_New);
+	PyMac_INIT_TOOLBOX_OBJECT_CONVERT(CFMutableDictionaryRef, CFMutableDictionaryRefObj_Convert);
+	PyMac_INIT_TOOLBOX_OBJECT_NEW(CFURLRef, CFURLRefObj_New);
+	PyMac_INIT_TOOLBOX_OBJECT_CONVERT(CFURLRef, CFURLRefObj_Convert);
+
+
+	m = Py_InitModule("_CF", CF_methods);
+	d = PyModule_GetDict(m);
+	CF_Error = PyMac_GetOSErrException();
+	if (CF_Error == NULL ||
+	    PyDict_SetItemString(d, "Error", CF_Error) != 0)
+		return;
+	CFTypeRef_Type.ob_type = &PyType_Type;
+	if (PyType_Ready(&CFTypeRef_Type) < 0) return;
+	Py_INCREF(&CFTypeRef_Type);
+	PyModule_AddObject(m, "CFTypeRef", (PyObject *)&CFTypeRef_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&CFTypeRef_Type);
+	PyModule_AddObject(m, "CFTypeRefType", (PyObject *)&CFTypeRef_Type);
+	CFArrayRef_Type.ob_type = &PyType_Type;
+	CFArrayRef_Type.tp_base = &CFTypeRef_Type;
+	if (PyType_Ready(&CFArrayRef_Type) < 0) return;
+	Py_INCREF(&CFArrayRef_Type);
+	PyModule_AddObject(m, "CFArrayRef", (PyObject *)&CFArrayRef_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&CFArrayRef_Type);
+	PyModule_AddObject(m, "CFArrayRefType", (PyObject *)&CFArrayRef_Type);
+	CFMutableArrayRef_Type.ob_type = &PyType_Type;
+	CFMutableArrayRef_Type.tp_base = &CFArrayRef_Type;
+	if (PyType_Ready(&CFMutableArrayRef_Type) < 0) return;
+	Py_INCREF(&CFMutableArrayRef_Type);
+	PyModule_AddObject(m, "CFMutableArrayRef", (PyObject *)&CFMutableArrayRef_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&CFMutableArrayRef_Type);
+	PyModule_AddObject(m, "CFMutableArrayRefType", (PyObject *)&CFMutableArrayRef_Type);
+	CFDictionaryRef_Type.ob_type = &PyType_Type;
+	CFDictionaryRef_Type.tp_base = &CFTypeRef_Type;
+	if (PyType_Ready(&CFDictionaryRef_Type) < 0) return;
+	Py_INCREF(&CFDictionaryRef_Type);
+	PyModule_AddObject(m, "CFDictionaryRef", (PyObject *)&CFDictionaryRef_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&CFDictionaryRef_Type);
+	PyModule_AddObject(m, "CFDictionaryRefType", (PyObject *)&CFDictionaryRef_Type);
+	CFMutableDictionaryRef_Type.ob_type = &PyType_Type;
+	CFMutableDictionaryRef_Type.tp_base = &CFDictionaryRef_Type;
+	if (PyType_Ready(&CFMutableDictionaryRef_Type) < 0) return;
+	Py_INCREF(&CFMutableDictionaryRef_Type);
+	PyModule_AddObject(m, "CFMutableDictionaryRef", (PyObject *)&CFMutableDictionaryRef_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&CFMutableDictionaryRef_Type);
+	PyModule_AddObject(m, "CFMutableDictionaryRefType", (PyObject *)&CFMutableDictionaryRef_Type);
+	CFDataRef_Type.ob_type = &PyType_Type;
+	CFDataRef_Type.tp_base = &CFTypeRef_Type;
+	if (PyType_Ready(&CFDataRef_Type) < 0) return;
+	Py_INCREF(&CFDataRef_Type);
+	PyModule_AddObject(m, "CFDataRef", (PyObject *)&CFDataRef_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&CFDataRef_Type);
+	PyModule_AddObject(m, "CFDataRefType", (PyObject *)&CFDataRef_Type);
+	CFMutableDataRef_Type.ob_type = &PyType_Type;
+	CFMutableDataRef_Type.tp_base = &CFDataRef_Type;
+	if (PyType_Ready(&CFMutableDataRef_Type) < 0) return;
+	Py_INCREF(&CFMutableDataRef_Type);
+	PyModule_AddObject(m, "CFMutableDataRef", (PyObject *)&CFMutableDataRef_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&CFMutableDataRef_Type);
+	PyModule_AddObject(m, "CFMutableDataRefType", (PyObject *)&CFMutableDataRef_Type);
+	CFStringRef_Type.ob_type = &PyType_Type;
+	CFStringRef_Type.tp_base = &CFTypeRef_Type;
+	if (PyType_Ready(&CFStringRef_Type) < 0) return;
+	Py_INCREF(&CFStringRef_Type);
+	PyModule_AddObject(m, "CFStringRef", (PyObject *)&CFStringRef_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&CFStringRef_Type);
+	PyModule_AddObject(m, "CFStringRefType", (PyObject *)&CFStringRef_Type);
+	CFMutableStringRef_Type.ob_type = &PyType_Type;
+	CFMutableStringRef_Type.tp_base = &CFStringRef_Type;
+	if (PyType_Ready(&CFMutableStringRef_Type) < 0) return;
+	Py_INCREF(&CFMutableStringRef_Type);
+	PyModule_AddObject(m, "CFMutableStringRef", (PyObject *)&CFMutableStringRef_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&CFMutableStringRef_Type);
+	PyModule_AddObject(m, "CFMutableStringRefType", (PyObject *)&CFMutableStringRef_Type);
+	CFURLRef_Type.ob_type = &PyType_Type;
+	CFURLRef_Type.tp_base = &CFTypeRef_Type;
+	if (PyType_Ready(&CFURLRef_Type) < 0) return;
+	Py_INCREF(&CFURLRef_Type);
+	PyModule_AddObject(m, "CFURLRef", (PyObject *)&CFURLRef_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&CFURLRef_Type);
+	PyModule_AddObject(m, "CFURLRefType", (PyObject *)&CFURLRef_Type);
+
+#define _STRINGCONST(name) PyModule_AddObject(m, #name, CFStringRefObj_New(name))
+	_STRINGCONST(kCFPreferencesAnyApplication);
+	_STRINGCONST(kCFPreferencesCurrentApplication);
+	_STRINGCONST(kCFPreferencesAnyHost);
+	_STRINGCONST(kCFPreferencesCurrentHost);
+	_STRINGCONST(kCFPreferencesAnyUser);
+	_STRINGCONST(kCFPreferencesCurrentUser);
+
+
+
+}
+
+/* ========================= End module _CF ========================= */
+

Added: vendor/Python/current/Mac/Modules/cf/cfscan.py
===================================================================
--- vendor/Python/current/Mac/Modules/cf/cfscan.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/cf/cfscan.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,142 @@
+# Scan an Apple header file, generating a Python file of generator calls.
+
+import sys
+import os
+from bgenlocations import TOOLBOXDIR, BGENDIR
+sys.path.append(BGENDIR)
+from scantools import Scanner_OSX
+
+LONG = "CoreFoundation"
+SHORT = "cf"
+OBJECTS = ("CFTypeRef",
+                "CFArrayRef", "CFMutableArrayRef",
+                "CFDataRef", "CFMutableDataRef",
+                "CFDictionaryRef", "CFMutableDictionaryRef",
+                "CFStringRef", "CFMutableStringRef",
+                "CFURLRef",
+##              "CFPropertyListRef",
+                )
+# ADD object typenames here
+
+def main():
+    input = [
+            "CFBase.h",
+            "CFArray.h",
+##              "CFBag.h",
+##              "CFBundle.h",
+##              "CFCharacterSet.h",
+            "CFData.h",
+##              "CFDate.h",
+            "CFDictionary.h",
+##              "CFNumber.h",
+##              "CFPlugIn.h",
+            "CFPreferences.h",
+            "CFPropertyList.h",
+##              "CFSet.h",
+            "CFString.h",
+##              "CFStringEncodingExt.h",
+##              "CFTimeZone.h",
+            "CFURL.h",
+            ]
+    output = SHORT + "gen.py"
+    defsoutput = TOOLBOXDIR + LONG + ".py"
+    scanner = MyScanner(input, output, defsoutput)
+    scanner.scan()
+    scanner.gentypetest(SHORT+"typetest.py")
+    scanner.close()
+    print "=== Testing definitions output code ==="
+    execfile(defsoutput, {}, {})
+    print "=== Done scanning and generating, now importing the generated code... ==="
+    exec "import " + SHORT + "support"
+    print "=== Done.  It's up to you to compile it now! ==="
+
+class MyScanner(Scanner_OSX):
+
+    def destination(self, type, name, arglist):
+        classname = "Function"
+        listname = "functions"
+        if arglist and name[:13] != 'CFPreferences':
+            t, n, m = arglist[0]
+            if t in OBJECTS and m == "InMode":
+                classname = "Method"
+                listname = t + "_methods"
+            # Special case for the silly first AllocatorRef argument
+            if t == 'CFAllocatorRef' and m == 'InMode' and len(arglist) > 1:
+                t, n, m = arglist[1]
+                if t in OBJECTS and m == "InMode":
+                    classname = "MethodSkipArg1"
+                    listname = t + "_methods"
+        return classname, listname
+
+    def writeinitialdefs(self):
+        self.defsfile.write("def FOUR_CHAR_CODE(x): return x\n")
+
+    def makeblacklistnames(self):
+        return [
+                # Memory allocator functions
+                "CFAllocatorGetDefault",
+                "CFAllocatorSetDefault",
+                "CFAllocatorAllocate",
+                "CFAllocatorReallocate",
+                "CFAllocatorDeallocate",
+                "CFGetAllocator",
+                # Array functions we skip for now.
+                "CFArrayGetValueAtIndex",
+                # Data pointer functions. Skip for now.
+                "CFDataGetBytePtr",
+                "CFDataGetMutableBytePtr",
+                "CFDataGetBytes",   # XXXX Should support this one
+                # String functions
+                "CFStringGetPascalString", # Use the C-string methods.
+                "CFStringGetPascalStringPtr", # TBD automatically
+                "CFStringGetCStringPtr",
+                "CFStringGetCharactersPtr",
+                "CFStringGetCString",
+                "CFStringGetCharacters",
+                "CFURLCreateStringWithFileSystemPath", # Gone in later releases
+                "CFStringCreateMutableWithExternalCharactersNoCopy", # Not a clue...
+                "CFStringSetExternalCharactersNoCopy",
+                "CFStringGetCharacterAtIndex", # No format for single unichars yet.
+                "kCFStringEncodingInvalidId", # incompatible constant declaration
+                "CFPropertyListCreateFromXMLData", # Manually generated
+                ]
+
+    def makegreylist(self):
+        return []
+
+    def makeblacklisttypes(self):
+        return [
+                "CFComparatorFunction", # Callback function pointer
+                "CFAllocatorContext", # Not interested in providing our own allocator
+                "void_ptr_ptr",  # Tricky. This is the initializer for arrays...
+                "void_ptr", # Ditto for various array lookup methods
+                "CFArrayApplierFunction", # Callback function pointer
+                "CFDictionaryApplierFunction", # Callback function pointer
+                "va_list", # For printf-to-a-cfstring. Use Python.
+                "const_CFStringEncoding_ptr", # To be done, I guess
+                ]
+
+    def makerepairinstructions(self):
+        return [
+                # Buffers in CF seem to be passed as UInt8 * normally.
+                ([("UInt8_ptr", "*", "InMode"), ("CFIndex", "*", "InMode")],
+                 [("UcharInBuffer", "*", "*")]),
+
+                ([("UniChar_ptr", "*", "InMode"), ("CFIndex", "*", "InMode")],
+                 [("UnicodeInBuffer", "*", "*")]),
+
+                # Some functions return a const char *. Don't worry, we won't modify it.
+                ([("const_char_ptr", "*", "ReturnMode")],
+                 [("return_stringptr", "*", "*")]),
+
+                # base URLs are optional (pass None for NULL)
+                ([("CFURLRef", "baseURL", "InMode")],
+                 [("OptionalCFURLRef", "*", "*")]),
+
+                # We handle CFPropertyListRef objects as plain CFTypeRef
+                ([("CFPropertyListRef", "*", "*")],
+                 [("CFTypeRef", "*", "*")]),
+                ]
+
+if __name__ == "__main__":
+    main()

Added: vendor/Python/current/Mac/Modules/cf/cfsupport.py
===================================================================
--- vendor/Python/current/Mac/Modules/cf/cfsupport.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/cf/cfsupport.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,665 @@
+# This script generates a Python interface for an Apple Macintosh Manager.
+# It uses the "bgen" package to generate C code.
+# The function specifications are generated by scanning the mamager's header file,
+# using the "scantools" package (customized for this particular manager).
+
+#error missing SetActionFilter
+
+import string
+
+# Declarations that change for each manager
+MODNAME = '_CF'                         # The name of the module
+
+# The following is *usually* unchanged but may still require tuning
+MODPREFIX = 'CF'                        # The prefix for module-wide routines
+INPUTFILE = string.lower(MODPREFIX) + 'gen.py' # The file generated by the scanner
+OUTPUTFILE = MODNAME + "module.c"       # The file generated by this program
+
+from macsupport import *
+
+# Special case generator for the functions that have an AllocatorRef first argument,
+# which we skip anyway, and the object as the second arg.
+class MethodSkipArg1(MethodGenerator):
+    """Similar to MethodGenerator, but has self as last argument"""
+
+    def parseArgumentList(self, args):
+        if len(args) < 2:
+            raise ValueError, "MethodSkipArg1 expects at least 2 args"
+        a0, a1, args = args[0], args[1], args[2:]
+        t0, n0, m0 = a0
+        if t0 != "CFAllocatorRef" and m0 != InMode:
+            raise ValueError, "MethodSkipArg1 should have dummy AllocatorRef first arg"
+        t1, n1, m1 = a1
+        if m1 != InMode:
+            raise ValueError, "method's 'self' must be 'InMode'"
+        dummy = Variable(t0, n0, m0)
+        self.argumentList.append(dummy)
+        self.itself = Variable(t1, "_self->ob_itself", SelfMode)
+        self.argumentList.append(self.itself)
+        FunctionGenerator.parseArgumentList(self, args)
+
+
+# Create the type objects
+
+includestuff = includestuff + """
+#include <CoreServices/CoreServices.h>
+
+#include "pycfbridge.h"
+
+#ifdef USE_TOOLBOX_OBJECT_GLUE
+extern PyObject *_CFObj_New(CFTypeRef);
+extern int _CFObj_Convert(PyObject *, CFTypeRef *);
+#define CFObj_New _CFObj_New
+#define CFObj_Convert _CFObj_Convert
+
+extern PyObject *_CFTypeRefObj_New(CFTypeRef);
+extern int _CFTypeRefObj_Convert(PyObject *, CFTypeRef *);
+#define CFTypeRefObj_New _CFTypeRefObj_New
+#define CFTypeRefObj_Convert _CFTypeRefObj_Convert
+
+extern PyObject *_CFStringRefObj_New(CFStringRef);
+extern int _CFStringRefObj_Convert(PyObject *, CFStringRef *);
+#define CFStringRefObj_New _CFStringRefObj_New
+#define CFStringRefObj_Convert _CFStringRefObj_Convert
+
+extern PyObject *_CFMutableStringRefObj_New(CFMutableStringRef);
+extern int _CFMutableStringRefObj_Convert(PyObject *, CFMutableStringRef *);
+#define CFMutableStringRefObj_New _CFMutableStringRefObj_New
+#define CFMutableStringRefObj_Convert _CFMutableStringRefObj_Convert
+
+extern PyObject *_CFArrayRefObj_New(CFArrayRef);
+extern int _CFArrayRefObj_Convert(PyObject *, CFArrayRef *);
+#define CFArrayRefObj_New _CFArrayRefObj_New
+#define CFArrayRefObj_Convert _CFArrayRefObj_Convert
+
+extern PyObject *_CFMutableArrayRefObj_New(CFMutableArrayRef);
+extern int _CFMutableArrayRefObj_Convert(PyObject *, CFMutableArrayRef *);
+#define CFMutableArrayRefObj_New _CFMutableArrayRefObj_New
+#define CFMutableArrayRefObj_Convert _CFMutableArrayRefObj_Convert
+
+extern PyObject *_CFDataRefObj_New(CFDataRef);
+extern int _CFDataRefObj_Convert(PyObject *, CFDataRef *);
+#define CFDataRefObj_New _CFDataRefObj_New
+#define CFDataRefObj_Convert _CFDataRefObj_Convert
+
+extern PyObject *_CFMutableDataRefObj_New(CFMutableDataRef);
+extern int _CFMutableDataRefObj_Convert(PyObject *, CFMutableDataRef *);
+#define CFMutableDataRefObj_New _CFMutableDataRefObj_New
+#define CFMutableDataRefObj_Convert _CFMutableDataRefObj_Convert
+
+extern PyObject *_CFDictionaryRefObj_New(CFDictionaryRef);
+extern int _CFDictionaryRefObj_Convert(PyObject *, CFDictionaryRef *);
+#define CFDictionaryRefObj_New _CFDictionaryRefObj_New
+#define CFDictionaryRefObj_Convert _CFDictionaryRefObj_Convert
+
+extern PyObject *_CFMutableDictionaryRefObj_New(CFMutableDictionaryRef);
+extern int _CFMutableDictionaryRefObj_Convert(PyObject *, CFMutableDictionaryRef *);
+#define CFMutableDictionaryRefObj_New _CFMutableDictionaryRefObj_New
+#define CFMutableDictionaryRefObj_Convert _CFMutableDictionaryRefObj_Convert
+
+extern PyObject *_CFURLRefObj_New(CFURLRef);
+extern int _CFURLRefObj_Convert(PyObject *, CFURLRef *);
+extern int _OptionalCFURLRefObj_Convert(PyObject *, CFURLRef *);
+#define CFURLRefObj_New _CFURLRefObj_New
+#define CFURLRefObj_Convert _CFURLRefObj_Convert
+#define OptionalCFURLRefObj_Convert _OptionalCFURLRefObj_Convert
+#endif
+
+/*
+** Parse/generate CFRange records
+*/
+PyObject *CFRange_New(CFRange *itself)
+{
+
+        return Py_BuildValue("ll", (long)itself->location, (long)itself->length);
+}
+
+int
+CFRange_Convert(PyObject *v, CFRange *p_itself)
+{
+        long location, length;
+
+        if( !PyArg_ParseTuple(v, "ll", &location, &length) )
+                return 0;
+        p_itself->location = (CFIndex)location;
+        p_itself->length = (CFIndex)length;
+        return 1;
+}
+
+/* Optional CFURL argument or None (passed as NULL) */
+int
+OptionalCFURLRefObj_Convert(PyObject *v, CFURLRef *p_itself)
+{
+    if ( v == Py_None ) {
+        p_itself = NULL;
+        return 1;
+    }
+    return CFURLRefObj_Convert(v, p_itself);
+}
+"""
+
+finalstuff = finalstuff + """
+
+/* Routines to convert any CF type to/from the corresponding CFxxxObj */
+PyObject *CFObj_New(CFTypeRef itself)
+{
+        if (itself == NULL)
+        {
+                PyErr_SetString(PyExc_RuntimeError, "cannot wrap NULL");
+                return NULL;
+        }
+        if (CFGetTypeID(itself) == CFArrayGetTypeID()) return CFArrayRefObj_New((CFArrayRef)itself);
+        if (CFGetTypeID(itself) == CFDictionaryGetTypeID()) return CFDictionaryRefObj_New((CFDictionaryRef)itself);
+        if (CFGetTypeID(itself) == CFDataGetTypeID()) return CFDataRefObj_New((CFDataRef)itself);
+        if (CFGetTypeID(itself) == CFStringGetTypeID()) return CFStringRefObj_New((CFStringRef)itself);
+        if (CFGetTypeID(itself) == CFURLGetTypeID()) return CFURLRefObj_New((CFURLRef)itself);
+        /* XXXX Or should we use PyCF_CF2Python here?? */
+        return CFTypeRefObj_New(itself);
+}
+int CFObj_Convert(PyObject *v, CFTypeRef *p_itself)
+{
+
+        if (v == Py_None) { *p_itself = NULL; return 1; }
+        /* Check for other CF objects here */
+
+        if (!CFTypeRefObj_Check(v) &&
+                !CFArrayRefObj_Check(v) &&
+                !CFMutableArrayRefObj_Check(v) &&
+                !CFDictionaryRefObj_Check(v) &&
+                !CFMutableDictionaryRefObj_Check(v) &&
+                !CFDataRefObj_Check(v) &&
+                !CFMutableDataRefObj_Check(v) &&
+                !CFStringRefObj_Check(v) &&
+                !CFMutableStringRefObj_Check(v) &&
+                !CFURLRefObj_Check(v) )
+        {
+                /* XXXX Or should we use PyCF_Python2CF here?? */
+                PyErr_SetString(PyExc_TypeError, "CF object required");
+                return 0;
+        }
+        *p_itself = ((CFTypeRefObject *)v)->ob_itself;
+        return 1;
+}
+"""
+
+initstuff = initstuff + """
+PyMac_INIT_TOOLBOX_OBJECT_NEW(CFTypeRef, CFObj_New);
+PyMac_INIT_TOOLBOX_OBJECT_CONVERT(CFTypeRef, CFObj_Convert);
+PyMac_INIT_TOOLBOX_OBJECT_NEW(CFTypeRef, CFTypeRefObj_New);
+PyMac_INIT_TOOLBOX_OBJECT_CONVERT(CFTypeRef, CFTypeRefObj_Convert);
+PyMac_INIT_TOOLBOX_OBJECT_NEW(CFStringRef, CFStringRefObj_New);
+PyMac_INIT_TOOLBOX_OBJECT_CONVERT(CFStringRef, CFStringRefObj_Convert);
+PyMac_INIT_TOOLBOX_OBJECT_NEW(CFMutableStringRef, CFMutableStringRefObj_New);
+PyMac_INIT_TOOLBOX_OBJECT_CONVERT(CFMutableStringRef, CFMutableStringRefObj_Convert);
+PyMac_INIT_TOOLBOX_OBJECT_NEW(CFArrayRef, CFArrayRefObj_New);
+PyMac_INIT_TOOLBOX_OBJECT_CONVERT(CFArrayRef, CFArrayRefObj_Convert);
+PyMac_INIT_TOOLBOX_OBJECT_NEW(CFMutableArrayRef, CFMutableArrayRefObj_New);
+PyMac_INIT_TOOLBOX_OBJECT_CONVERT(CFMutableArrayRef, CFMutableArrayRefObj_Convert);
+PyMac_INIT_TOOLBOX_OBJECT_NEW(CFDictionaryRef, CFDictionaryRefObj_New);
+PyMac_INIT_TOOLBOX_OBJECT_CONVERT(CFDictionaryRef, CFDictionaryRefObj_Convert);
+PyMac_INIT_TOOLBOX_OBJECT_NEW(CFMutableDictionaryRef, CFMutableDictionaryRefObj_New);
+PyMac_INIT_TOOLBOX_OBJECT_CONVERT(CFMutableDictionaryRef, CFMutableDictionaryRefObj_Convert);
+PyMac_INIT_TOOLBOX_OBJECT_NEW(CFURLRef, CFURLRefObj_New);
+PyMac_INIT_TOOLBOX_OBJECT_CONVERT(CFURLRef, CFURLRefObj_Convert);
+"""
+
+variablestuff="""
+#define _STRINGCONST(name) PyModule_AddObject(m, #name, CFStringRefObj_New(name))
+_STRINGCONST(kCFPreferencesAnyApplication);
+_STRINGCONST(kCFPreferencesCurrentApplication);
+_STRINGCONST(kCFPreferencesAnyHost);
+_STRINGCONST(kCFPreferencesCurrentHost);
+_STRINGCONST(kCFPreferencesAnyUser);
+_STRINGCONST(kCFPreferencesCurrentUser);
+
+"""
+
+Boolean = Type("Boolean", "l")
+CFTypeID = Type("CFTypeID", "l") # XXXX a guess, seems better than OSTypeType.
+CFHashCode = Type("CFHashCode", "l")
+CFIndex = Type("CFIndex", "l")
+CFRange = OpaqueByValueType('CFRange', 'CFRange')
+CFOptionFlags = Type("CFOptionFlags", "l")
+CFStringEncoding = Type("CFStringEncoding", "l")
+CFComparisonResult = Type("CFComparisonResult", "l")  # a bit dangerous, it's an enum
+CFURLPathStyle = Type("CFURLPathStyle", "l") #  a bit dangerous, it's an enum
+
+char_ptr = stringptr
+return_stringptr = Type("char *", "s")  # ONLY FOR RETURN VALUES!!
+
+CFAllocatorRef = FakeType("(CFAllocatorRef)NULL")
+CFArrayCallBacks_ptr = FakeType("&kCFTypeArrayCallBacks")
+CFDictionaryKeyCallBacks_ptr = FakeType("&kCFTypeDictionaryKeyCallBacks")
+CFDictionaryValueCallBacks_ptr = FakeType("&kCFTypeDictionaryValueCallBacks")
+# The real objects
+CFTypeRef = OpaqueByValueType("CFTypeRef", "CFTypeRefObj")
+CFArrayRef = OpaqueByValueType("CFArrayRef", "CFArrayRefObj")
+CFMutableArrayRef = OpaqueByValueType("CFMutableArrayRef", "CFMutableArrayRefObj")
+CFArrayRef = OpaqueByValueType("CFArrayRef", "CFArrayRefObj")
+CFMutableArrayRef = OpaqueByValueType("CFMutableArrayRef", "CFMutableArrayRefObj")
+CFDataRef = OpaqueByValueType("CFDataRef", "CFDataRefObj")
+CFMutableDataRef = OpaqueByValueType("CFMutableDataRef", "CFMutableDataRefObj")
+CFDictionaryRef = OpaqueByValueType("CFDictionaryRef", "CFDictionaryRefObj")
+CFMutableDictionaryRef = OpaqueByValueType("CFMutableDictionaryRef", "CFMutableDictionaryRefObj")
+CFStringRef = OpaqueByValueType("CFStringRef", "CFStringRefObj")
+CFMutableStringRef = OpaqueByValueType("CFMutableStringRef", "CFMutableStringRefObj")
+CFURLRef = OpaqueByValueType("CFURLRef", "CFURLRefObj")
+OptionalCFURLRef  = OpaqueByValueType("CFURLRef", "OptionalCFURLRefObj")
+##CFPropertyListRef = OpaqueByValueType("CFPropertyListRef", "CFTypeRefObj")
+# ADD object type here
+
+# Our (opaque) objects
+
+class MyGlobalObjectDefinition(PEP253Mixin, GlobalObjectDefinition):
+    def outputCheckNewArg(self):
+        Output('if (itself == NULL)')
+        OutLbrace()
+        Output('PyErr_SetString(PyExc_RuntimeError, "cannot wrap NULL");')
+        Output('return NULL;')
+        OutRbrace()
+    def outputStructMembers(self):
+        GlobalObjectDefinition.outputStructMembers(self)
+        Output("void (*ob_freeit)(CFTypeRef ptr);")
+    def outputInitStructMembers(self):
+        GlobalObjectDefinition.outputInitStructMembers(self)
+##              Output("it->ob_freeit = NULL;")
+        Output("it->ob_freeit = CFRelease;")
+    def outputCheckConvertArg(self):
+        Out("""
+        if (v == Py_None) { *p_itself = NULL; return 1; }
+        /* Check for other CF objects here */
+        """)
+    def outputCleanupStructMembers(self):
+        Output("if (self->ob_freeit && self->ob_itself)")
+        OutLbrace()
+        Output("self->ob_freeit((CFTypeRef)self->ob_itself);")
+        Output("self->ob_itself = NULL;")
+        OutRbrace()
+
+    def outputCompare(self):
+        Output()
+        Output("static int %s_compare(%s *self, %s *other)", self.prefix, self.objecttype, self.objecttype)
+        OutLbrace()
+        Output("/* XXXX Or should we use CFEqual?? */")
+        Output("if ( self->ob_itself > other->ob_itself ) return 1;")
+        Output("if ( self->ob_itself < other->ob_itself ) return -1;")
+        Output("return 0;")
+        OutRbrace()
+
+    def outputHash(self):
+        Output()
+        Output("static int %s_hash(%s *self)", self.prefix, self.objecttype)
+        OutLbrace()
+        Output("/* XXXX Or should we use CFHash?? */")
+        Output("return (int)self->ob_itself;")
+        OutRbrace()
+
+    def outputRepr(self):
+        Output()
+        Output("static PyObject * %s_repr(%s *self)", self.prefix, self.objecttype)
+        OutLbrace()
+        Output("char buf[100];")
+        Output("""sprintf(buf, "<CFTypeRef type-%%d object at 0x%%8.8x for 0x%%8.8x>", (int)CFGetTypeID(self->ob_itself), (unsigned)self, (unsigned)self->ob_itself);""")
+        Output("return PyString_FromString(buf);")
+        OutRbrace()
+
+    def output_tp_newBody(self):
+        Output("PyObject *self;")
+        Output
+        Output("if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;")
+        Output("((%s *)self)->ob_itself = NULL;", self.objecttype)
+        Output("((%s *)self)->ob_freeit = CFRelease;", self.objecttype)
+        Output("return self;")
+
+    def output_tp_initBody(self):
+        Output("%s itself;", self.itselftype)
+        Output("char *kw[] = {\"itself\", 0};")
+        Output()
+        Output("if (PyArg_ParseTupleAndKeywords(_args, _kwds, \"O&\", kw, %s_Convert, &itself))",
+                self.prefix)
+        OutLbrace()
+        Output("((%s *)_self)->ob_itself = itself;", self.objecttype)
+        Output("return 0;")
+        OutRbrace()
+        if self.prefix != 'CFTypeRefObj':
+            Output()
+            Output("/* Any CFTypeRef descendent is allowed as initializer too */")
+            Output("if (PyArg_ParseTupleAndKeywords(_args, _kwds, \"O&\", kw, CFTypeRefObj_Convert, &itself))")
+            OutLbrace()
+            Output("((%s *)_self)->ob_itself = itself;", self.objecttype)
+            Output("return 0;")
+            OutRbrace()
+        Output("return -1;")
+
+class CFTypeRefObjectDefinition(MyGlobalObjectDefinition):
+    pass
+
+class CFArrayRefObjectDefinition(MyGlobalObjectDefinition):
+    basetype = "CFTypeRef_Type"
+
+    def outputRepr(self):
+        Output()
+        Output("static PyObject * %s_repr(%s *self)", self.prefix, self.objecttype)
+        OutLbrace()
+        Output("char buf[100];")
+        Output("""sprintf(buf, "<CFArrayRef object at 0x%%8.8x for 0x%%8.8x>", (unsigned)self, (unsigned)self->ob_itself);""")
+        Output("return PyString_FromString(buf);")
+        OutRbrace()
+
+class CFMutableArrayRefObjectDefinition(MyGlobalObjectDefinition):
+    basetype = "CFArrayRef_Type"
+
+    def outputRepr(self):
+        Output()
+        Output("static PyObject * %s_repr(%s *self)", self.prefix, self.objecttype)
+        OutLbrace()
+        Output("char buf[100];")
+        Output("""sprintf(buf, "<CFMutableArrayRef object at 0x%%8.8x for 0x%%8.8x>", (unsigned)self, (unsigned)self->ob_itself);""")
+        Output("return PyString_FromString(buf);")
+        OutRbrace()
+
+class CFDictionaryRefObjectDefinition(MyGlobalObjectDefinition):
+    basetype = "CFTypeRef_Type"
+
+    def outputRepr(self):
+        Output()
+        Output("static PyObject * %s_repr(%s *self)", self.prefix, self.objecttype)
+        OutLbrace()
+        Output("char buf[100];")
+        Output("""sprintf(buf, "<CFDictionaryRef object at 0x%%8.8x for 0x%%8.8x>", (unsigned)self, (unsigned)self->ob_itself);""")
+        Output("return PyString_FromString(buf);")
+        OutRbrace()
+
+class CFMutableDictionaryRefObjectDefinition(MyGlobalObjectDefinition):
+    basetype = "CFDictionaryRef_Type"
+
+    def outputRepr(self):
+        Output()
+        Output("static PyObject * %s_repr(%s *self)", self.prefix, self.objecttype)
+        OutLbrace()
+        Output("char buf[100];")
+        Output("""sprintf(buf, "<CFMutableDictionaryRef object at 0x%%8.8x for 0x%%8.8x>", (unsigned)self, (unsigned)self->ob_itself);""")
+        Output("return PyString_FromString(buf);")
+        OutRbrace()
+
+class CFDataRefObjectDefinition(MyGlobalObjectDefinition):
+    basetype = "CFTypeRef_Type"
+
+    def outputCheckConvertArg(self):
+        Out("""
+        if (v == Py_None) { *p_itself = NULL; return 1; }
+        if (PyString_Check(v)) {
+            char *cStr;
+            int cLen;
+            if( PyString_AsStringAndSize(v, &cStr, &cLen) < 0 ) return 0;
+            *p_itself = CFDataCreate((CFAllocatorRef)NULL, (unsigned char *)cStr, cLen);
+            return 1;
+        }
+        """)
+
+    def outputRepr(self):
+        Output()
+        Output("static PyObject * %s_repr(%s *self)", self.prefix, self.objecttype)
+        OutLbrace()
+        Output("char buf[100];")
+        Output("""sprintf(buf, "<CFDataRef object at 0x%%8.8x for 0x%%8.8x>", (unsigned)self, (unsigned)self->ob_itself);""")
+        Output("return PyString_FromString(buf);")
+        OutRbrace()
+
+class CFMutableDataRefObjectDefinition(MyGlobalObjectDefinition):
+    basetype = "CFDataRef_Type"
+
+    def outputRepr(self):
+        Output()
+        Output("static PyObject * %s_repr(%s *self)", self.prefix, self.objecttype)
+        OutLbrace()
+        Output("char buf[100];")
+        Output("""sprintf(buf, "<CFMutableDataRef object at 0x%%8.8x for 0x%%8.8x>", (unsigned)self, (unsigned)self->ob_itself);""")
+        Output("return PyString_FromString(buf);")
+        OutRbrace()
+
+class CFStringRefObjectDefinition(MyGlobalObjectDefinition):
+    basetype = "CFTypeRef_Type"
+
+    def outputCheckConvertArg(self):
+        Out("""
+        if (v == Py_None) { *p_itself = NULL; return 1; }
+        if (PyString_Check(v)) {
+            char *cStr;
+            if (!PyArg_Parse(v, "es", "ascii", &cStr))
+                return NULL;
+                *p_itself = CFStringCreateWithCString((CFAllocatorRef)NULL, cStr, kCFStringEncodingASCII);
+                return 1;
+        }
+        if (PyUnicode_Check(v)) {
+                /* We use the CF types here, if Python was configured differently that will give an error */
+                CFIndex size = PyUnicode_GetSize(v);
+                UniChar *unichars = PyUnicode_AsUnicode(v);
+                if (!unichars) return 0;
+                *p_itself = CFStringCreateWithCharacters((CFAllocatorRef)NULL, unichars, size);
+                return 1;
+        }
+
+        """)
+
+    def outputRepr(self):
+        Output()
+        Output("static PyObject * %s_repr(%s *self)", self.prefix, self.objecttype)
+        OutLbrace()
+        Output("char buf[100];")
+        Output("""sprintf(buf, "<CFStringRef object at 0x%%8.8x for 0x%%8.8x>", (unsigned)self, (unsigned)self->ob_itself);""")
+        Output("return PyString_FromString(buf);")
+        OutRbrace()
+
+class CFMutableStringRefObjectDefinition(CFStringRefObjectDefinition):
+    basetype = "CFStringRef_Type"
+
+    def outputCheckConvertArg(self):
+        # Mutable, don't allow Python strings
+        return MyGlobalObjectDefinition.outputCheckConvertArg(self)
+
+    def outputRepr(self):
+        Output()
+        Output("static PyObject * %s_repr(%s *self)", self.prefix, self.objecttype)
+        OutLbrace()
+        Output("char buf[100];")
+        Output("""sprintf(buf, "<CFMutableStringRef object at 0x%%8.8x for 0x%%8.8x>", (unsigned)self, (unsigned)self->ob_itself);""")
+        Output("return PyString_FromString(buf);")
+        OutRbrace()
+
+class CFURLRefObjectDefinition(MyGlobalObjectDefinition):
+    basetype = "CFTypeRef_Type"
+
+    def outputRepr(self):
+        Output()
+        Output("static PyObject * %s_repr(%s *self)", self.prefix, self.objecttype)
+        OutLbrace()
+        Output("char buf[100];")
+        Output("""sprintf(buf, "<CFURL object at 0x%%8.8x for 0x%%8.8x>", (unsigned)self, (unsigned)self->ob_itself);""")
+        Output("return PyString_FromString(buf);")
+        OutRbrace()
+
+
+# ADD object class here
+
+# From here on it's basically all boiler plate...
+
+# Create the generator groups and link them
+module = MacModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff, variablestuff)
+CFTypeRef_object = CFTypeRefObjectDefinition('CFTypeRef', 'CFTypeRefObj', 'CFTypeRef')
+CFArrayRef_object = CFArrayRefObjectDefinition('CFArrayRef', 'CFArrayRefObj', 'CFArrayRef')
+CFMutableArrayRef_object = CFMutableArrayRefObjectDefinition('CFMutableArrayRef', 'CFMutableArrayRefObj', 'CFMutableArrayRef')
+CFDictionaryRef_object = CFDictionaryRefObjectDefinition('CFDictionaryRef', 'CFDictionaryRefObj', 'CFDictionaryRef')
+CFMutableDictionaryRef_object = CFMutableDictionaryRefObjectDefinition('CFMutableDictionaryRef', 'CFMutableDictionaryRefObj', 'CFMutableDictionaryRef')
+CFDataRef_object = CFDataRefObjectDefinition('CFDataRef', 'CFDataRefObj', 'CFDataRef')
+CFMutableDataRef_object = CFMutableDataRefObjectDefinition('CFMutableDataRef', 'CFMutableDataRefObj', 'CFMutableDataRef')
+CFStringRef_object = CFStringRefObjectDefinition('CFStringRef', 'CFStringRefObj', 'CFStringRef')
+CFMutableStringRef_object = CFMutableStringRefObjectDefinition('CFMutableStringRef', 'CFMutableStringRefObj', 'CFMutableStringRef')
+CFURLRef_object = CFURLRefObjectDefinition('CFURLRef', 'CFURLRefObj', 'CFURLRef')
+
+# ADD object here
+
+module.addobject(CFTypeRef_object)
+module.addobject(CFArrayRef_object)
+module.addobject(CFMutableArrayRef_object)
+module.addobject(CFDictionaryRef_object)
+module.addobject(CFMutableDictionaryRef_object)
+module.addobject(CFDataRef_object)
+module.addobject(CFMutableDataRef_object)
+module.addobject(CFStringRef_object)
+module.addobject(CFMutableStringRef_object)
+module.addobject(CFURLRef_object)
+# ADD addobject call here
+
+# Create the generator classes used to populate the lists
+Function = OSErrWeakLinkFunctionGenerator
+Method = OSErrWeakLinkMethodGenerator
+
+# Create and populate the lists
+functions = []
+CFTypeRef_methods = []
+CFArrayRef_methods = []
+CFMutableArrayRef_methods = []
+CFDictionaryRef_methods = []
+CFMutableDictionaryRef_methods = []
+CFDataRef_methods = []
+CFMutableDataRef_methods = []
+CFStringRef_methods = []
+CFMutableStringRef_methods = []
+CFURLRef_methods = []
+
+# ADD _methods initializer here
+execfile(INPUTFILE)
+
+
+# add the populated lists to the generator groups
+# (in a different wordl the scan program would generate this)
+for f in functions: module.add(f)
+for f in CFTypeRef_methods: CFTypeRef_object.add(f)
+for f in CFArrayRef_methods: CFArrayRef_object.add(f)
+for f in CFMutableArrayRef_methods: CFMutableArrayRef_object.add(f)
+for f in CFDictionaryRef_methods: CFDictionaryRef_object.add(f)
+for f in CFMutableDictionaryRef_methods: CFMutableDictionaryRef_object.add(f)
+for f in CFDataRef_methods: CFDataRef_object.add(f)
+for f in CFMutableDataRef_methods: CFMutableDataRef_object.add(f)
+for f in CFStringRef_methods: CFStringRef_object.add(f)
+for f in CFMutableStringRef_methods: CFMutableStringRef_object.add(f)
+for f in CFURLRef_methods: CFURLRef_object.add(f)
+
+# Manual generators for getting data out of strings
+
+getasstring_body = """
+int size = CFStringGetLength(_self->ob_itself)+1;
+char *data = malloc(size);
+
+if( data == NULL ) return PyErr_NoMemory();
+if ( CFStringGetCString(_self->ob_itself, data, size, 0) ) {
+        _res = (PyObject *)PyString_FromString(data);
+} else {
+        PyErr_SetString(PyExc_RuntimeError, "CFStringGetCString could not fit the string");
+        _res = NULL;
+}
+free(data);
+return _res;
+"""
+
+f = ManualGenerator("CFStringGetString", getasstring_body);
+f.docstring = lambda: "() -> (string _rv)"
+CFStringRef_object.add(f)
+
+getasunicode_body = """
+int size = CFStringGetLength(_self->ob_itself)+1;
+Py_UNICODE *data = malloc(size*sizeof(Py_UNICODE));
+CFRange range;
+
+range.location = 0;
+range.length = size;
+if( data == NULL ) return PyErr_NoMemory();
+CFStringGetCharacters(_self->ob_itself, range, data);
+_res = (PyObject *)PyUnicode_FromUnicode(data, size-1);
+free(data);
+return _res;
+"""
+
+f = ManualGenerator("CFStringGetUnicode", getasunicode_body);
+f.docstring = lambda: "() -> (unicode _rv)"
+CFStringRef_object.add(f)
+
+# Get data from CFDataRef
+getasdata_body = """
+int size = CFDataGetLength(_self->ob_itself);
+char *data = (char *)CFDataGetBytePtr(_self->ob_itself);
+
+_res = (PyObject *)PyString_FromStringAndSize(data, size);
+return _res;
+"""
+
+f = ManualGenerator("CFDataGetData", getasdata_body);
+f.docstring = lambda: "() -> (string _rv)"
+CFDataRef_object.add(f)
+
+# Manual generator for CFPropertyListCreateFromXMLData because of funny error return
+fromxml_body = """
+CFTypeRef _rv;
+CFOptionFlags mutabilityOption;
+CFStringRef errorString;
+if (!PyArg_ParseTuple(_args, "l",
+                      &mutabilityOption))
+        return NULL;
+_rv = CFPropertyListCreateFromXMLData((CFAllocatorRef)NULL,
+                                      _self->ob_itself,
+                                      mutabilityOption,
+                                      &errorString);
+if (errorString)
+        CFRelease(errorString);
+if (_rv == NULL) {
+        PyErr_SetString(PyExc_RuntimeError, "Parse error in XML data");
+        return NULL;
+}
+_res = Py_BuildValue("O&",
+                     CFTypeRefObj_New, _rv);
+return _res;
+"""
+f = ManualGenerator("CFPropertyListCreateFromXMLData", fromxml_body)
+f.docstring = lambda: "(CFOptionFlags mutabilityOption) -> (CFTypeRefObj)"
+CFTypeRef_object.add(f)
+
+# Convert CF objects to Python objects
+toPython_body = """
+_res = PyCF_CF2Python(_self->ob_itself);
+return _res;
+"""
+
+f = ManualGenerator("toPython", toPython_body);
+f.docstring = lambda: "() -> (python_object)"
+CFTypeRef_object.add(f)
+
+toCF_body = """
+CFTypeRef rv;
+CFTypeID typeid;
+
+if (!PyArg_ParseTuple(_args, "O&", PyCF_Python2CF, &rv))
+        return NULL;
+typeid = CFGetTypeID(rv);
+
+if (typeid == CFStringGetTypeID())
+        return Py_BuildValue("O&", CFStringRefObj_New, rv);
+if (typeid == CFArrayGetTypeID())
+        return Py_BuildValue("O&", CFArrayRefObj_New, rv);
+if (typeid == CFDictionaryGetTypeID())
+        return Py_BuildValue("O&", CFDictionaryRefObj_New, rv);
+if (typeid == CFURLGetTypeID())
+        return Py_BuildValue("O&", CFURLRefObj_New, rv);
+
+_res = Py_BuildValue("O&", CFTypeRefObj_New, rv);
+return _res;
+"""
+f = ManualGenerator("toCF", toCF_body);
+f.docstring = lambda: "(python_object) -> (CF_object)"
+module.add(f)
+
+# ADD add forloop here
+
+# generate output (open the output file as late as possible)
+SetOutputFileName(OUTPUTFILE)
+module.generate()

Added: vendor/Python/current/Mac/Modules/cf/pycfbridge.c
===================================================================
--- vendor/Python/current/Mac/Modules/cf/pycfbridge.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/cf/pycfbridge.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,302 @@
+/*
+** Convert objects from Python to CoreFoundation and vice-versa.
+*/
+
+#include <CoreServices/CoreServices.h>
+
+#include "Python.h"
+#include "pymactoolbox.h"
+#include "pycfbridge.h"
+
+
+/* ---------------------------------------- */
+/* CoreFoundation objects to Python objects */
+/* ---------------------------------------- */
+
+PyObject *
+PyCF_CF2Python(CFTypeRef src) {
+	CFTypeID typeid;
+	
+	if( src == NULL ) {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+	typeid = CFGetTypeID(src);
+	if (typeid == CFArrayGetTypeID())
+		return PyCF_CF2Python_sequence((CFArrayRef)src);
+	if (typeid == CFDictionaryGetTypeID())
+		return PyCF_CF2Python_mapping((CFDictionaryRef)src);
+	return PyCF_CF2Python_simple(src);
+}
+
+PyObject *
+PyCF_CF2Python_sequence(CFArrayRef src) {
+	int size = CFArrayGetCount(src);
+	PyObject *rv;
+	CFTypeRef item_cf;
+	PyObject *item_py = NULL;
+	int i;
+	
+	if ( (rv=PyList_New(size)) == NULL )
+		return NULL;
+	for(i=0; i<size; i++) {
+		item_cf = CFArrayGetValueAtIndex(src, i);
+		if (item_cf == NULL ) goto err;
+		item_py = PyCF_CF2Python(item_cf);
+		if (item_py == NULL ) goto err;
+		if (PyList_SetItem(rv, i, item_py) < 0) goto err;
+		item_py = NULL;
+	}
+	return rv;
+err:
+	Py_XDECREF(item_py);
+	Py_DECREF(rv);
+	return NULL;
+}
+
+PyObject *
+PyCF_CF2Python_mapping(CFTypeRef src) {
+	int size = CFDictionaryGetCount(src);
+	PyObject *rv = NULL;
+	CFTypeRef *allkeys = NULL, *allvalues = NULL;
+	CFTypeRef key_cf, value_cf;
+	PyObject *key_py = NULL, *value_py = NULL;
+	int i;
+	
+	allkeys = malloc(size*sizeof(CFTypeRef *));
+	if (allkeys == NULL) {
+		PyErr_NoMemory();
+		goto err;
+	}
+	allvalues = malloc(size*sizeof(CFTypeRef *));
+	if (allvalues == NULL) {
+		PyErr_NoMemory();
+		goto err;
+	}
+	if ( (rv=PyDict_New()) == NULL ) goto err;
+	CFDictionaryGetKeysAndValues(src, allkeys, allvalues);
+	for(i=0; i<size; i++) {
+		key_cf = allkeys[i];
+		value_cf = allvalues[i];
+		key_py = PyCF_CF2Python(key_cf);
+		if (key_py == NULL ) goto err;
+		value_py = PyCF_CF2Python(value_cf);
+		if (value_py == NULL ) goto err;
+		if (PyDict_SetItem(rv, key_py, value_py) < 0) goto err;
+		key_py = NULL;
+		value_py = NULL;
+	}
+	return rv;
+err:
+	Py_XDECREF(key_py);
+	Py_XDECREF(value_py);
+	Py_XDECREF(rv);
+	free(allkeys);
+	free(allvalues);
+	return NULL;
+}
+
+PyObject *
+PyCF_CF2Python_simple(CFTypeRef src) {
+	CFTypeID typeid;
+	
+	typeid = CFGetTypeID(src);
+	if (typeid == CFStringGetTypeID())
+		return PyCF_CF2Python_string((CFStringRef)src);
+	if (typeid == CFBooleanGetTypeID())
+		return PyBool_FromLong((long)CFBooleanGetValue(src));
+	if (typeid == CFNumberGetTypeID()) {
+		if (CFNumberIsFloatType(src)) {
+			double d;
+			CFNumberGetValue(src, kCFNumberDoubleType, &d);
+			return PyFloat_FromDouble(d);
+		} else {
+			long l;
+			if (!CFNumberGetValue(src, kCFNumberLongType, &l))
+				/* XXXX Out of range! */;
+			return PyInt_FromLong(l);
+		}
+	}
+	/* XXXX Should return as CFTypeRef, really... */
+	PyMac_Error(resNotFound);
+	return NULL;
+}
+
+/* Unsure - Return unicode or 8 bit strings? */
+PyObject *
+PyCF_CF2Python_string(CFStringRef src) {
+	int size = CFStringGetLength(src)+1;
+	Py_UNICODE *data = malloc(size*sizeof(Py_UNICODE));
+	CFRange range;
+	PyObject *rv;
+
+	range.location = 0;
+	range.length = size;
+	if( data == NULL ) return PyErr_NoMemory();
+	CFStringGetCharacters(src, range, data);
+	rv = (PyObject *)PyUnicode_FromUnicode(data, size-1);
+	free(data);
+	return rv;
+}
+
+/* ---------------------------------------- */
+/* Python objects to CoreFoundation objects */
+/* ---------------------------------------- */
+
+int
+PyCF_Python2CF(PyObject *src, CFTypeRef *dst) {
+
+	if (PyString_Check(src) || PyUnicode_Check(src))
+		return PyCF_Python2CF_simple(src, dst);
+	if (PySequence_Check(src))
+		return PyCF_Python2CF_sequence(src, (CFArrayRef *)dst);
+	if (PyMapping_Check(src))
+		return PyCF_Python2CF_mapping(src, (CFDictionaryRef *)dst);
+	return PyCF_Python2CF_simple(src, dst);
+}
+
+int
+PyCF_Python2CF_sequence(PyObject *src, CFArrayRef *dst) {
+	CFMutableArrayRef rv = NULL;
+	CFTypeRef item_cf = NULL;
+	PyObject *item_py = NULL;
+	int size, i;
+	
+	if( !PySequence_Check(src) ) {
+		PyErr_Format(PyExc_TypeError,
+			"Cannot convert %.500s objects to CFArray",
+			src->ob_type->tp_name);
+		return 0;
+	}
+	size = PySequence_Size(src);
+	rv = CFArrayCreateMutable((CFAllocatorRef)NULL, size, &kCFTypeArrayCallBacks);
+	if (rv == NULL) {
+		PyMac_Error(resNotFound); 
+		goto err;
+	}
+
+	for( i=0; i<size; i++) {
+		item_py = PySequence_GetItem(src, i);
+		if (item_py == NULL) goto err;
+		if ( !PyCF_Python2CF(item_py, &item_cf)) goto err;
+		Py_DECREF(item_py);
+		CFArraySetValueAtIndex(rv, i, item_cf);
+		CFRelease(item_cf);
+		item_cf = NULL;
+	}
+	*dst = rv;
+	return 1;
+err:
+	Py_XDECREF(item_py);
+	if (rv) CFRelease(rv);
+	if (item_cf) CFRelease(item_cf);
+	return 0;		
+}
+
+int
+PyCF_Python2CF_mapping(PyObject *src, CFDictionaryRef *dst) {
+	CFMutableDictionaryRef rv = NULL;
+	PyObject *aslist = NULL;
+	CFTypeRef key_cf = NULL, value_cf = NULL;
+	PyObject *item_py = NULL, *key_py = NULL, *value_py = NULL;
+	int size, i;
+	
+	if( !PyMapping_Check(src) ) {
+		PyErr_Format(PyExc_TypeError,
+			"Cannot convert %.500s objects to CFDictionary",
+			src->ob_type->tp_name);
+		return 0;
+	}
+	size = PyMapping_Size(src);
+	rv = CFDictionaryCreateMutable((CFAllocatorRef)NULL, size,
+					&kCFTypeDictionaryKeyCallBacks,
+	                                &kCFTypeDictionaryValueCallBacks);
+	if (rv == NULL) {
+		PyMac_Error(resNotFound); 
+		goto err;
+	}
+	if ( (aslist = PyMapping_Items(src)) == NULL ) goto err;
+
+	for( i=0; i<size; i++) {
+		item_py = PySequence_GetItem(aslist, i);
+		if (item_py == NULL) goto err;
+		if (!PyArg_ParseTuple(item_py, "OO", &key_py, &value_py)) goto err;
+		if ( !PyCF_Python2CF(key_py, &key_cf) ) goto err;
+		if ( !PyCF_Python2CF(value_py, &value_cf) ) goto err;
+		CFDictionaryAddValue(rv, key_cf, value_cf);
+		CFRelease(key_cf);
+		key_cf = NULL;
+		CFRelease(value_cf);
+		value_cf = NULL;
+	}
+	*dst = rv;
+	return 1;
+err:
+	Py_XDECREF(item_py);
+	Py_XDECREF(aslist);
+	if (rv) CFRelease(rv);
+	if (key_cf) CFRelease(key_cf);
+	if (value_cf) CFRelease(value_cf);
+	return 0;		
+}
+
+int
+PyCF_Python2CF_simple(PyObject *src, CFTypeRef *dst) {
+	
+#if 0
+	if (PyObject_HasAttrString(src, "CFType")) {
+		*dst = PyObject_CallMethod(src, "CFType", "");
+		return (*dst != NULL);
+	}
+#endif
+	if (PyString_Check(src) || PyUnicode_Check(src)) 
+		return PyCF_Python2CF_string(src, (CFStringRef *)dst);
+	if (PyBool_Check(src)) {
+		if (src == Py_True)
+			*dst = kCFBooleanTrue;
+		else
+			*dst = kCFBooleanFalse;
+		return 1;
+	}
+	if (PyInt_Check(src)) {
+		long v = PyInt_AsLong(src);
+		*dst = CFNumberCreate(NULL, kCFNumberLongType, &v);
+		return 1;
+	}
+	if (PyFloat_Check(src)) {
+		double d = PyFloat_AsDouble(src);
+		*dst = CFNumberCreate(NULL, kCFNumberDoubleType, &d);
+		return 1;
+	}
+			
+	PyErr_Format(PyExc_TypeError,
+		  "Cannot convert %.500s objects to CFType",
+				     src->ob_type->tp_name);
+	return 0;
+}
+
+int
+PyCF_Python2CF_string(PyObject *src, CFStringRef *dst) {
+	char *chars;
+	CFIndex size;
+	UniChar *unichars;
+	
+	if (PyString_Check(src)) {
+		if (!PyArg_Parse(src, "es", "ascii", &chars))
+			return 0; /* This error is more descriptive than the general one below */
+		*dst = CFStringCreateWithCString((CFAllocatorRef)NULL, chars, kCFStringEncodingASCII);
+		return 1;
+	}
+	if (PyUnicode_Check(src)) {
+		/* We use the CF types here, if Python was configured differently that will give an error */
+		size = PyUnicode_GetSize(src);
+		if ((unichars = PyUnicode_AsUnicode(src)) == NULL ) goto err;
+		*dst = CFStringCreateWithCharacters((CFAllocatorRef)NULL, unichars, size);
+		return 1;
+	}
+err:
+	PyErr_Format(PyExc_TypeError,
+		  "Cannot convert %.500s objects to CFString",
+				     src->ob_type->tp_name);
+	return 0;
+}

Added: vendor/Python/current/Mac/Modules/cf/pycfbridge.h
===================================================================
--- vendor/Python/current/Mac/Modules/cf/pycfbridge.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/cf/pycfbridge.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,11 @@
+extern PyObject *PyCF_CF2Python(CFTypeRef src);
+extern PyObject *PyCF_CF2Python_sequence(CFArrayRef src);
+extern PyObject *PyCF_CF2Python_mapping(CFTypeRef src);
+extern PyObject *PyCF_CF2Python_simple(CFTypeRef src);
+extern PyObject *PyCF_CF2Python_string(CFStringRef src);
+
+extern int PyCF_Python2CF(PyObject *src, CFTypeRef *dst);
+extern int PyCF_Python2CF_sequence(PyObject *src, CFArrayRef *dst);
+extern int PyCF_Python2CF_mapping(PyObject *src, CFDictionaryRef *dst);
+extern int PyCF_Python2CF_simple(PyObject *src, CFTypeRef *dst);
+extern int PyCF_Python2CF_string(PyObject *src, CFStringRef *dst);
\ No newline at end of file

Added: vendor/Python/current/Mac/Modules/cg/CFMLateImport.c
===================================================================
--- vendor/Python/current/Mac/Modules/cg/CFMLateImport.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/cg/CFMLateImport.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1360 @@
+/*
+	File:		CFMLateImport.c
+
+	Contains:	Implementation of CFM late import library.
+
+	Written by:	Quinn
+
+	Copyright:	Copyright © 1999 by Apple Computer, Inc., all rights reserved.
+
+				You may incorporate this Apple sample source code into your program(s) without
+				restriction. This Apple sample source code has been provided "AS IS" and the
+				responsibility for its operation is yours. You are not permitted to redistribute
+				this Apple sample source code as "Apple sample source code" after having made
+				changes. If you're going to re-distribute the source, we require that you make
+				it clear in the source that the code was descended from Apple sample source
+				code, but that you've made changes.
+
+	Change History (most recent first):
+
+        <13>     24/9/01    Quinn   Fixes to compile with C++ activated.
+        <12>     21/9/01    Quinn   [2710489] Fix typo in the comments for FragmentLookup.
+        <11>     21/9/01    Quinn   Changes for CWPro7 Mach-O build.
+        <10>     19/9/01    Quinn   Corrected implementation of kPEFRelocSmBySection. Added
+                                    implementations of kPEFRelocSetPosition and kPEFRelocLgByImport
+                                    (from code contributed by Eric Grant, Ned Holbrook, and Steve
+                                    Kalkwarf), although I can't test them yet.
+         <9>     19/9/01    Quinn   We now handle unpacked data sections, courtesy of some code from
+                                    Ned Holbrook.
+         <8>     19/9/01    Quinn   Minor fixes for the previous checkin. Updated some comments and
+                                    killed some dead code.
+         <7>     19/9/01    Quinn   Simplified API and implementation after a suggestion by Eric
+                                    Grant. You no longer have to CFM export a dummy function; you
+                                    can just pass in the address of your fragment's init routine.
+         <6>     15/2/01    Quinn   Modify compile-time warnings to complain if you try to build
+                                    this module into a Mach-O binary.
+         <5>      5/2/01    Quinn   Removed redundant assignment in CFMLateImportCore.
+         <4>    30/11/00    Quinn   Added comment about future of data symbols in CF.
+         <3>    16/11/00    Quinn   Allow symbol finding via a callback and use that to implement
+                                    CFBundle support.
+         <2>    18/10/99    Quinn   Renamed CFMLateImport to CFMLateImportLibrary to allow for
+                                    possible future API expansion.
+         <1>     15/6/99    Quinn   First checked in.
+*/
+
+// To Do List:
+//
+// o get rid of dependence on ANSI "string.h", but how?
+//
+// Done:
+//
+// Ã investigate alternative APIs, like an external lookup routine
+//   renamed CFMLateImport to CFMLateImportLibrary to allow for
+//   future expansion of the APIs for things like CFMLateImportSymbol
+// Ã test with non-zero fragment offset in the file
+// Ã test more with MPW fragments
+// Ã test data imports
+
+/////////////////////////////////////////////////////////////////
+
+// MoreIsBetter Setup
+
+//#include "MoreSetup.h"
+#define MoreAssert(x) (true)
+#define MoreAssertQ(x)
+
+// Mac OS Interfaces
+
+#if ! MORE_FRAMEWORK_INCLUDES
+	#include <CodeFragments.h>
+	#include <PEFBinaryFormat.h>
+#endif
+
+// Standard C Interfaces
+
+#include <string.h>
+
+// MIB Prototypes
+
+//#include "MoreInterfaceLib.h"
+#define MoreBlockZero BlockZero
+
+// Our Prototypes
+
+#include "CFMLateImport.h"
+
+/////////////////////////////////////////////////////////////////
+
+#if TARGET_RT_MAC_MACHO
+	#error CFMLateImport is not suitable for use in a Mach-O project.
+#elif !TARGET_RT_MAC_CFM || !TARGET_CPU_PPC
+	#error CFMLateImport has not been qualified for 68K or CFM-68K use.
+#endif
+
+/////////////////////////////////////////////////////////////////
+#pragma mark ----- Utility Routines -----
+
+static OSStatus FSReadAtOffset(SInt16 refNum, SInt32 offset, SInt32 count, void *buffer)
+	// A convenient wrapper around PBRead which has two advantages
+	// over FSRead.  First, it takes count as a value parameter.
+	// Second, it reads from an arbitrary offset into the file,
+	// which avoids a bunch of SetFPos calls.
+	//
+	// I guess this should go into "MoreFiles.h", but I'm not sure
+	// how we're going to integrate such a concept into MIB yet.
+{
+	ParamBlockRec pb;
+	
+	pb.ioParam.ioRefNum     = refNum;
+	pb.ioParam.ioBuffer     = (Ptr) buffer;
+	pb.ioParam.ioReqCount   = count;
+	pb.ioParam.ioPosMode    = fsFromStart;
+	pb.ioParam.ioPosOffset  = offset;
+	
+	return PBReadSync(&pb);
+}
+
+/////////////////////////////////////////////////////////////////
+#pragma mark ----- Late Import Engine -----
+
+// This structure represents the core data structure of the late import
+// engine.  It basically holds information about the fragment we're going
+// to fix up.  It starts off with the first three fields, which are
+// provided by the client.  Then, as we procede through the operation,
+// we fill out more fields.
+
+struct FragToFixInfo {
+	CFragSystem7DiskFlatLocator	locator;				// How to find the fragment's container.
+	CFragConnectionID 			connID;					// CFM connection to the fragment.
+	CFragInitFunction 			initRoutine;			// The CFM init routine for the fragment.
+	PEFContainerHeader 			containerHeader;		// The CFM header, read in from the container.
+	PEFSectionHeader			*sectionHeaders;		// The CFM section headers.  A pointer block containing an array of containerHeader.sectionCount elements.
+	PEFLoaderInfoHeader			*loaderSection;			// The entire CFM loader section in a pointer block.
+	SInt16						fileRef;				// A read-only path to the CFM container.  We keep this here because one that one routine needs to read from the container.
+	void 						*section0Base;			// The base address of section 0, which we go through hoops to calculate.
+	void 						*section1Base;			// The base address of section 1, which we go through hoops to calculate.
+	Boolean						disposeSectionPointers;	// See below.
+};
+typedef struct FragToFixInfo FragToFixInfo;
+
+// The disposeSectionPointers Boolean is designed for future cool VM
+// support.  If VM is on, the entire code fragment is file mapped into
+// high memory, including the data we're forced to allocate the
+// sectionHeaders and loaderSection memory blocks to maintain.  If
+// we could find the address of the entire file mapped container,
+// we could access the information directly from there and thus
+// we wouldn't need to allocate (or dispose of) the memory blocks
+// for sectionHeaders and loaderSection.
+//
+// I haven't implemented this yet because a) I'm not sure how to do
+// it with documented APIs, and b) I couldn't be bothered, but
+// disposeSectionPointers remains as vestigial support for the concept.
+
+static OSStatus ReadContainerBasics(FragToFixInfo *fragToFix)
+	// Reads some basic information from the container of the
+	// fragment to fix and stores it in various fields of
+	// fragToFix.  This includes:
+	//
+	// o containerHeader -- The contain header itself.
+	// o sectionHeaders  -- The array of section headers (in a newly allocated pointer block).
+	// o loaderSection   -- The entire loader section (in a newly allocated pointer block).
+	//
+	// Also sets disposeSectionPointers to indicate whether
+	// the last two pointers should be disposed of.
+	//
+	// Finally, it leaves the container file open for later
+	// folks who want to read data from it.
+{
+	OSStatus 	err;
+	UInt16 		sectionIndex;
+	Boolean 	found;
+
+	MoreAssertQ(fragToFix != nil);
+	MoreAssertQ(fragToFix->locator.fileSpec != nil);
+	MoreAssertQ(fragToFix->connID != nil);
+	MoreAssertQ(fragToFix->loaderSection == nil);
+	MoreAssertQ(fragToFix->sectionHeaders == nil);
+	MoreAssertQ(fragToFix->fileRef == 0);
+	
+	fragToFix->disposeSectionPointers = true;
+	
+	// Open up the file, read the container head, then read in
+	// all the section headers, then go looking through the
+	// section headers for the loader section (PEF defines
+	// that there can be only one).
+	
+	err = FSpOpenDF(fragToFix->locator.fileSpec, fsRdPerm, &fragToFix->fileRef);
+	if (err == noErr) {
+		err = FSReadAtOffset(fragToFix->fileRef,
+								fragToFix->locator.offset,
+								sizeof(fragToFix->containerHeader),
+								&fragToFix->containerHeader);
+		if (err == noErr) {
+			if (   fragToFix->containerHeader.tag1 != kPEFTag1
+				|| fragToFix->containerHeader.tag2 != kPEFTag2
+				|| fragToFix->containerHeader.architecture != kCompiledCFragArch
+				|| fragToFix->containerHeader.formatVersion != kPEFVersion) {
+				err = cfragFragmentFormatErr;
+			}
+		}
+		if (err == noErr) {
+			fragToFix->sectionHeaders = (PEFSectionHeader *) NewPtr(fragToFix->containerHeader.sectionCount * sizeof(PEFSectionHeader));
+			err = MemError();
+		}
+		if (err == noErr) {
+			err = FSReadAtOffset(fragToFix->fileRef,
+									fragToFix->locator.offset + sizeof(fragToFix->containerHeader),
+									fragToFix->containerHeader.sectionCount * sizeof(PEFSectionHeader), 
+									fragToFix->sectionHeaders);
+		}
+		if (err == noErr) {
+			sectionIndex = 0;
+			found = false;
+			while ( sectionIndex < fragToFix->containerHeader.sectionCount && ! found ) {
+				found = (fragToFix->sectionHeaders[sectionIndex].sectionKind == kPEFLoaderSection);
+				if ( ! found ) {
+					sectionIndex += 1;
+				}
+			}
+		}
+		if (err == noErr && ! found) {
+			err = cfragNoSectionErr;
+		}
+		
+		// Now read allocate a pointer block and read the loader section into it.
+		
+		if (err == noErr) {
+			fragToFix->loaderSection = (PEFLoaderInfoHeader *) NewPtr(fragToFix->sectionHeaders[sectionIndex].containerLength);
+			err = MemError();
+		}
+		if (err == noErr) {
+			err = FSReadAtOffset(fragToFix->fileRef, 
+									fragToFix->locator.offset + fragToFix->sectionHeaders[sectionIndex].containerOffset,
+									fragToFix->sectionHeaders[sectionIndex].containerLength, 
+									fragToFix->loaderSection);
+		}				
+	}
+	
+	// No clean up.  The client must init fragToFix to zeros and then
+	// clean up regardless of whether we return an error.
+		
+	return err;
+}
+
+static UInt32 DecodeVCountValue(const UInt8 *start, UInt32 *outCount)
+	// Given a pointer to the start of a variable length PEF value, 
+	// work out the value (in *outCount).  Returns the number of bytes 
+	// consumed by the value.
+{
+	UInt8 *			bytePtr;
+	UInt8			byte;
+	UInt32			count;
+	
+	bytePtr = (UInt8 *)start;
+	
+	// Code taken from "PEFBinaryFormat.h".
+	count = 0;
+	do {
+		byte = *bytePtr++;
+		count = (count << kPEFPkDataVCountShift) | (byte & kPEFPkDataVCountMask);
+	} while ((byte & kPEFPkDataVCountEndMask) != 0);
+	
+	*outCount = count;
+	return bytePtr - start;
+}
+
+static UInt32 DecodeInstrCountValue(const UInt8 *inOpStart, UInt32 *outCount)
+	// Given a pointer to the start of an opcode (inOpStart), work out the 
+	// count argument for that opcode (*outCount).  Returns the number of 
+	// bytes consumed by the opcode and count combination.
+{
+	MoreAssertQ(inOpStart != nil);
+	MoreAssertQ(outCount  != nil);
+	
+	if (PEFPkDataCount5(*inOpStart) != 0)
+	{
+		// Simple case, count encoded in opcode.
+		*outCount = PEFPkDataCount5(*inOpStart);
+		return 1;
+	}
+	else
+	{
+		// Variable-length case.
+		return 1 + DecodeVCountValue(inOpStart + 1, outCount);
+	}
+}
+
+static OSStatus UnpackPEFDataSection(const UInt8 * const packedData,   UInt32 packedSize,
+								           UInt8 * const unpackedData, UInt32 unpackedSize)
+{
+	OSErr			err;
+	UInt32			offset;
+	UInt8			opCode;
+	UInt8 *			unpackCursor;
+	
+	MoreAssertQ(packedData != nil);
+	MoreAssertQ(unpackedData != nil);
+	MoreAssertQ(unpackedSize >= packedSize);
+
+	// The following asserts assume that the client allocated the memory with NewPtr, 
+	// which may not always be true.  However, the asserts' value in preventing accidental 
+	// memory block overruns outweighs the possible maintenance effort.
+	
+	MoreAssertQ( packedSize   == GetPtrSize( (Ptr) packedData  ) );
+	MoreAssertQ( unpackedSize == GetPtrSize( (Ptr) unpackedData) );
+	
+	err          = noErr;
+	offset       = 0;
+	unpackCursor = unpackedData;
+	while (offset < packedSize) {
+		MoreAssertQ(unpackCursor < &unpackedData[unpackedSize]);
+		
+		opCode = packedData[offset];
+		
+		switch (PEFPkDataOpcode(opCode)) {
+			case kPEFPkDataZero:
+				{
+					UInt32	count;
+					
+					offset += DecodeInstrCountValue(&packedData[offset], &count);
+					
+					MoreBlockZero(unpackCursor, count);
+					unpackCursor += count;
+				}
+				break;
+			
+			case kPEFPkDataBlock:
+				{
+					UInt32	blockSize;
+					
+					offset += DecodeInstrCountValue(&packedData[offset], &blockSize);
+					
+					BlockMoveData(&packedData[offset], unpackCursor, blockSize);
+					unpackCursor += blockSize;
+					offset += blockSize;
+				}
+				break;
+			
+			case kPEFPkDataRepeat:
+				{
+					UInt32	blockSize;
+					UInt32	repeatCount;
+					UInt32  loopCounter;
+					
+					offset += DecodeInstrCountValue(&packedData[offset], &blockSize);
+					offset += DecodeVCountValue(&packedData[offset], &repeatCount);
+					repeatCount += 1;	// stored value is (repeatCount - 1)
+					
+					for (loopCounter = 0; loopCounter < repeatCount; loopCounter++) {
+						BlockMoveData(&packedData[offset], unpackCursor, blockSize);
+						unpackCursor += blockSize;
+					}
+					offset += blockSize;
+				}
+				break;
+			
+			case kPEFPkDataRepeatBlock:
+				{
+					UInt32	commonSize;
+					UInt32	customSize;
+					UInt32	repeatCount;
+					const UInt8 *commonData;
+					const UInt8 *customData;
+					UInt32 loopCounter;
+					
+					offset += DecodeInstrCountValue(&packedData[offset], &commonSize);
+					offset += DecodeVCountValue(&packedData[offset], &customSize);
+					offset += DecodeVCountValue(&packedData[offset], &repeatCount);
+					
+					commonData = &packedData[offset];
+					customData = &packedData[offset + commonSize];
+					
+					for (loopCounter = 0; loopCounter < repeatCount; loopCounter++) {
+						BlockMoveData(commonData, unpackCursor, commonSize);
+						unpackCursor += commonSize;
+						BlockMoveData(customData, unpackCursor, customSize);
+						unpackCursor += customSize;
+						customData += customSize;
+					}
+					BlockMoveData(commonData, unpackCursor, commonSize);
+					unpackCursor += commonSize;
+					offset += (repeatCount * (commonSize + customSize)) + commonSize;
+				}
+				break;
+			
+			case kPEFPkDataRepeatZero:
+				{
+					UInt32	commonSize;
+					UInt32	customSize;
+					UInt32	repeatCount;
+					const UInt8 *customData;
+					UInt32 loopCounter;
+					
+					offset += DecodeInstrCountValue(&packedData[offset], &commonSize);
+					offset += DecodeVCountValue(&packedData[offset], &customSize);
+					offset += DecodeVCountValue(&packedData[offset], &repeatCount);
+					
+					customData = &packedData[offset];
+					
+					for (loopCounter = 0; loopCounter < repeatCount; loopCounter++) {
+						MoreBlockZero(unpackCursor, commonSize);
+						unpackCursor += commonSize;
+						BlockMoveData(customData, unpackCursor, customSize);
+						unpackCursor += customSize;
+						customData += customSize;
+					}
+					MoreBlockZero(unpackCursor, commonSize);
+					unpackCursor += commonSize;
+					offset += repeatCount * customSize;
+				}
+				break;
+			
+			default:
+				#if MORE_DEBUG
+					DebugStr("\pUnpackPEFDataSection: Unexpected data opcode");
+				#endif
+				err = cfragFragmentCorruptErr;
+				goto leaveNow;
+				break;
+		}
+	}
+	
+leaveNow:
+	return err;
+}
+
+/*	SetupSectionBaseAddresses Rationale
+	-----------------------------------
+	
+	OK, here's where things get weird.  In order to run the relocation
+	engine, I need to be able to find the base address of an instantiated
+	section of the fragment we're fixing up given only its section number.
+	This isn't hard for CFM to do because it's the one that instantiated the
+	sections in the first place.  It's surprisingly difficult to do if
+	you're not CFM.  [And you don't have access to the private CFM APis for 
+	doing it.]
+	
+	[Alan Lillich is going to kill me when he reads this!  I should point out
+	 that TVector's don't have to contain two words, they can be longer,
+	 and that the second word isn't necessarily a TOC pointer, it's
+	 just that the calling conventions require that it be put in the
+	 TOC register when the code is called.
+	 
+	 Furthermore, the code section isn't always section 0, and the data
+	 section isn't always section 1, and there can be zero to many sections
+	 of each type.
+	 
+	 But these niceties are besides the point: I'm doing something tricky 
+	 because I don't have a nice API for getting section base addresses.  
+	 If I had a nice API for doing that, none of this code would exist.
+	]
+
+	The technique is very sneaky (thanks to Eric Grant).  The fragment to 
+	fix necessarily has a CFM init routine (because it needs that routine 
+	in order to capture the fragment location and connection ID).  Thus the 
+	fragment to fix must have a TVector in its data section.  TVectors are 
+	interesting because they're made up of two words.  The first is a pointer 
+	to the code that implements the routine; the second is a pointer to the TOC
+	for the fragment that's exporting the TVector.  How TVectors are
+	created is interesting too.  On disk, a TVector consists of two words,
+	the first being the offset from the start of the code section to the
+	routine, the second being the offset from the start of the data section
+	to the TOC base.  When CFM prepares a TVector, it applies the following
+	transform:
+	
+		tvector.codePtr = tvector.codeOffset + base of code section
+		tvector.tocPtr  = tvector.tocOffset  + base of data section
+		
+	Now, you can reverse these questions to make them:
+	
+		base of code section = tvector.codePtr - tvector.codeOffset
+		base of data section = tvector.dataPtr - tvector.dataOffset
+	
+	So if you can find the relocated contents of the TVector and
+	find the original offsets that made up the TVector, you can then
+	calculate the base address of both the code and data sections.
+	
+	Finding the relocated contents of the TVector is easy; I simply 
+	require the client to pass in a pointer to its init routine. 
+	A routine pointer is a TVector pointer, so you can just cast it 
+	and extract the pair of words.
+
+	Finding the original offsets is a trickier.  My technique is to
+	look up the init routine in the fragment's loader info header.  This
+	yields the section number and offset where the init routine's unrelocated 
+	TVector exists.  Once I have that, I can just read the unrelocated TVector
+	out of the file and extract the offsets.
+*/
+
+struct TVector {
+	void *codePtr;
+	void *tocPtr;
+};
+typedef struct TVector TVector;
+
+static OSStatus SetupSectionBaseAddresses(FragToFixInfo *fragToFix)
+	// This routine initialises the section0Base and section1Base
+	// base fields of fragToFix to the base addresses of the
+	// instantiated fragment represented by the other fields
+	// of fragToFix.  The process works in three states:
+	//
+	// 1. 	Find the contents of the relocated TVector of the 
+	//      fragment's initialisation routine, provided to us by 
+	//      the caller.
+	//
+	// 2.	Find the contents of the non-relocated TVector by 
+	//      looking it up in the PEF loader info header and then 
+	//      using that to read the TVector contents from disk.
+	//      This yields the offsets from the section bases for 
+	//      the init routine.
+	//
+	// 3.	Subtract 2 from 3.
+{
+	OSStatus 			err;
+	TVector *			relocatedExport;
+	SInt32				initSection;
+	UInt32				initOffset;
+	PEFSectionHeader *	initSectionHeader;
+	Ptr					packedDataSection;
+	Ptr					unpackedDataSection;
+	TVector 			originalOffsets;
+
+	packedDataSection   = nil;
+	unpackedDataSection = nil;
+	
+	// Step 1.
+
+	// First find the init routine's TVector, which gives us the relocated 
+	// offsets of the init routine into the data and code sections.
+
+	relocatedExport = (TVector *) fragToFix->initRoutine;
+		
+	// Step 2.
+	
+	// Now find the init routine's TVector's offsets in the data section on 
+	// disk.  This gives us the raw offsets from the data and code section 
+	// of the beginning of the init routine.
+	
+	err = noErr;
+	initSection = fragToFix->loaderSection->initSection;
+	initOffset  = fragToFix->loaderSection->initOffset;
+	if (initSection == -1) {
+		err = cfragFragmentUsageErr;
+	}
+	if (err == noErr) {
+		MoreAssertQ( initSection >= 0 );		// Negative indexes are pseudo-sections which are just not allowed!
+		MoreAssertQ( initSection < fragToFix->containerHeader.sectionCount );
+
+		initSectionHeader = &fragToFix->sectionHeaders[initSection];
+		
+		// If the data section is packed, unpack it to a temporary buffer and then get the 
+		// original offsets from that buffer.  If the data section is unpacked, just read 
+		// the original offsets directly off the disk.
+		
+		if ( initSectionHeader->sectionKind == kPEFPackedDataSection ) {
+
+			// Allocate space for packed and unpacked copies of the section.
+			
+			packedDataSection = NewPtr(initSectionHeader->containerLength);
+			err = MemError();
+
+			if (err == noErr) {
+				unpackedDataSection = NewPtr(initSectionHeader->unpackedLength);
+				err = MemError();
+			}
+
+			// Read the contents of the packed section.
+			
+			if (err == noErr) {
+				err = FSReadAtOffset(	fragToFix->fileRef,
+										fragToFix->locator.offset
+										+ initSectionHeader->containerOffset,
+										initSectionHeader->containerLength,
+										packedDataSection);
+			}
+			
+			// Unpack the data into the unpacked section.
+			
+			if (err == noErr) {
+				err = UnpackPEFDataSection( (UInt8 *) packedDataSection,   initSectionHeader->containerLength,
+								            (UInt8 *) unpackedDataSection, initSectionHeader->unpackedLength);
+			}
+			
+			// Extract the init routine's TVector from the unpacked section.
+			
+			if (err == noErr) {
+				BlockMoveData(unpackedDataSection + initOffset, &originalOffsets, sizeof(TVector));
+			}
+			
+		} else {
+			MoreAssertQ(fragToFix->sectionHeaders[initSection].sectionKind == kPEFUnpackedDataSection);
+			err = FSReadAtOffset(fragToFix->fileRef, 
+									fragToFix->locator.offset
+									+ fragToFix->sectionHeaders[initSection].containerOffset
+									+ initOffset,
+									sizeof(TVector), 
+									&originalOffsets);
+		}
+	}
+
+	// Step 3.
+		
+	// Do the maths to subtract the unrelocated offsets from the current address 
+	// to get the base address.
+	
+	if (err == noErr) {
+		fragToFix->section0Base = ((char *) relocatedExport->codePtr) - (UInt32) originalOffsets.codePtr;
+		fragToFix->section1Base = ((char *) relocatedExport->tocPtr)  - (UInt32) originalOffsets.tocPtr;
+	}
+	
+	// Clean up.
+	
+	if (packedDataSection != nil) {
+		DisposePtr(packedDataSection);
+		MoreAssertQ( MemError() == noErr );
+	}
+	if (unpackedDataSection != nil) {
+		DisposePtr(unpackedDataSection);
+		MoreAssertQ( MemError() == noErr );
+	}
+	return err;
+}
+
+static void *GetSectionBaseAddress(const FragToFixInfo *fragToFix, UInt16 sectionIndex)
+	// This routine returns the base of the instantiated section
+	// whose index is sectionIndex.  This routine is the evil twin
+	// of SetupSectionBaseAddresses.  It simply returns the values
+	// for section 0 and 1 that we derived in SetupSectionBaseAddresses.
+	// In a real implementation, this routine would call CFM API
+	// to get this information, and SetupSectionBaseAddresses would
+	// not exist, but CFM does not export the necessary APIs to
+	// third parties.
+{
+	void *result;
+	
+	MoreAssertQ(fragToFix != nil);
+	MoreAssertQ(fragToFix->containerHeader.tag1 == kPEFTag1);
+	
+	switch (sectionIndex) {
+		case 0:
+			result = fragToFix->section0Base;
+			break;
+		case 1:
+			result = fragToFix->section1Base;
+			break;
+		default:
+			result = nil;
+			break;
+	}
+	return result;
+}
+
+
+static OSStatus FindImportLibrary(PEFLoaderInfoHeader *loaderSection, const char *libraryName, PEFImportedLibrary **importLibrary)
+	// This routine finds the import library description (PEFImportedLibrary)
+	// for the import library libraryName in the PEF loader section.
+	// It sets *importLibrary to the address of the description.
+{
+	OSStatus 			err;
+	UInt32 				librariesRemaining;
+	PEFImportedLibrary 	*thisImportLibrary;
+	Boolean 			found;
+	
+	MoreAssertQ(loaderSection != nil);
+	MoreAssertQ(libraryName != nil);
+	MoreAssertQ(importLibrary != nil);
+	
+	// Loop through each import library looking for a matching name.
+	
+	// Initialise thisImportLibrary to point to the byte after the
+	// end of the loader section's header.
+	
+	thisImportLibrary = (PEFImportedLibrary *) (loaderSection + 1);
+	librariesRemaining = loaderSection->importedLibraryCount;
+	found = false;
+	while ( librariesRemaining > 0 && ! found ) {
+		// PEF defines that import library names will have
+		// a null terminator, so we can just use strcmp.
+		found = (strcmp( libraryName,
+						((char *)loaderSection)
+						+ loaderSection->loaderStringsOffset 
+						+ thisImportLibrary->nameOffset) == 0);
+		// *** Remove ANSI strcmp eventually.
+		if ( ! found ) {
+			thisImportLibrary += 1;
+			librariesRemaining -= 1;
+		}
+	}
+	
+	if (found) {
+		*importLibrary = thisImportLibrary;
+		err = noErr;
+	} else {
+		*importLibrary = nil;
+		err = cfragNoLibraryErr;
+	}
+	return err;
+}
+
+static OSStatus LookupSymbol(CFMLateImportLookupProc lookup, void *refCon,
+							PEFLoaderInfoHeader *loaderSection,
+							UInt32 symbolIndex,
+							UInt32 *symbolValue)
+	// This routine is used to look up a symbol during relocation.
+	// "lookup" is a client callback and refCon is its argument.
+	// Typically refCon is the CFM connection to the library that is
+	// substituting for the weak linked library.  loaderSection
+	// is a pointer to the loader section of the fragment to fix up.
+	// symbolIndex is the index of the imported symbol in the loader section.
+	// The routine sets the word pointed to by symbolValue to the
+	// value of the symbol.
+	//
+	// The routine works by using symbolIndex to index into the imported
+	// symbol table to find the offset of the symbol's name in the string
+	// table.  It then looks up the symbol by calling the client's "lookup"
+	// function and passes the resulting symbol address back in symbolValue.
+{
+	OSStatus 			err;
+	UInt32 				*importSymbolTable;
+	UInt32 				symbolStringOffset;
+	Boolean 			symbolIsWeak;
+	CFragSymbolClass 	symbolClass;
+	char 				*symbolStringAddress;
+	Str255 				symbolString;
+	
+	MoreAssertQ(lookup != nil);
+	MoreAssertQ(loaderSection != nil);
+	MoreAssertQ(symbolIndex < loaderSection->totalImportedSymbolCount);
+	MoreAssertQ(symbolValue != nil);
+	
+	// Find the base of the imported symbol table.
+	
+	importSymbolTable = (UInt32 *)(((char *)(loaderSection + 1)) + (loaderSection->importedLibraryCount * sizeof(PEFImportedLibrary)));
+	
+	// Grab the appropriate entry out of the table and
+	// extract the information from that entry.
+	
+	symbolStringOffset = importSymbolTable[symbolIndex];
+	symbolClass = PEFImportedSymbolClass(symbolStringOffset);
+	symbolIsWeak = ((symbolClass & kPEFWeakImportSymMask) != 0);
+	symbolClass = symbolClass & ~kPEFWeakImportSymMask;
+	symbolStringOffset = PEFImportedSymbolNameOffset(symbolStringOffset);
+	
+	// Find the string for the symbol in the strings table and
+	// extract it from the table into a Pascal string on the stack.
+	
+	symbolStringAddress = ((char *)loaderSection) + loaderSection->loaderStringsOffset + symbolStringOffset;
+	symbolString[0] = strlen(symbolStringAddress);		// *** remove ANSI strlen
+	BlockMoveData(symbolStringAddress, &symbolString[1], symbolString[0]);
+	
+	// Look up the symbol in substitute library.  If it fails, return
+	// a 0 value and check whether the error is fatal (a strong linked
+	// symbol) or benign (a weak linked symbol).
+	
+	err = lookup(symbolString, symbolClass, (void **) symbolValue, refCon);
+	if (err != noErr) {
+		*symbolValue = 0;
+		if (symbolIsWeak) {
+			err = noErr;
+		}
+	}
+	return err;
+}
+
+// The EngineState structure encapsulates all of the persistent state
+// of the CFM relocation engine virtual machine.  I originally defined
+// this structure so I could pass the state around between routines
+// that implement various virtual opcodes, however I later worked
+// out that the relocation was sufficiently simple that I could put it
+// in in one routine.  Still, I left the state in this structure in
+// case I ever need to reverse that decision.  It's also a convenient
+// instructional design.
+
+struct EngineState {
+	UInt32 currentReloc;		// Index of current relocation opcodes
+	UInt32 terminatingReloc;	// Index of relocation opcodes which terminates relocation
+	UInt32 *sectionBase;		// Start of the section
+	UInt32 *relocAddress;		// Address within the section where the relocations are to be performed
+	UInt32 importIndex;			// Symbol index, which is used to access an imported symbol's address
+	void  *sectionC;			// Memory address of an instantiated section within the PEF container; this variable is used by relocation opcodes that relocate section addresses
+	void  *sectionD;			// Memory address of an instantiated section within the PEF container; this variable is used by relocation opcodes that relocate section addresses
+};
+typedef struct EngineState EngineState;
+
+// Note:
+// If I ever have to support the repeat opcodes, I'll probably
+// have to add a repeat counter to EngineState.
+
+static OSStatus InitEngineState(const FragToFixInfo *fragToFix,
+								UInt16 relocHeaderIndex,
+								EngineState *state)
+	// This routine initialises the engine state suitably for
+	// running the relocation opcodes for the section whose
+	// index is relocHeaderIndex.  relocHeaderIndex is not a
+	// a section number.  See the comment where it's used below
+	// for details.  The routine basically fills out all the fields
+	// in the EngineState structure as described by
+	// "Mac OS Runtime Architectures".
+{
+	OSStatus err;
+	PEFLoaderRelocationHeader *relocHeader;
+	
+	MoreAssertQ(fragToFix != nil);
+	MoreAssertQ(state != nil);
+
+	// This bit is tricky.  relocHeaderIndex is an index into the relocation
+	// header table, starting at relocSectionCount (which is in the loader
+	// section header) for the first relocated section and decrementing
+	// down to 1 for the last relocated section.  I find the relocation
+	// header by using relocHeaderIndex as a index backwards from the
+	// start of the relocation opcodes (ie relocInstrOffset).  If you
+	// look at the diagram of the layout of the container in
+	// "PEFBinaryFormat.h", you'll see that the relocation opcodes
+	// immediately follow the relocation headers.
+	//
+	// I did this because the alternative (starting at the loader
+	// header and stepping past the import library table and the
+	// import symbol table) was a pain.
+
+	relocHeader = (PEFLoaderRelocationHeader *) (((char *) fragToFix->loaderSection) + fragToFix->loaderSection->relocInstrOffset - relocHeaderIndex * sizeof(PEFLoaderRelocationHeader));
+	
+	MoreAssertQ(relocHeader->reservedA == 0);		// PEF spec says it must be; we check to try to catch bugs in calculation of relocHeader
+	
+	state->currentReloc = relocHeader->firstRelocOffset;
+	state->terminatingReloc = relocHeader->firstRelocOffset + relocHeader->relocCount;
+	state->sectionBase = (UInt32 *) GetSectionBaseAddress(fragToFix, relocHeader->sectionIndex);
+	state->relocAddress = state->sectionBase;
+	state->importIndex = 0;
+
+	// From "Mac OS Runtime Architectures":
+	//
+	// The sectionC and sectionD variables actually contain the
+	// memory address of an instantiated section minus the
+	// default address for that section. The default address for a
+	// section is contained in the defaultAddress field of the
+	// section header. However, in almost all cases the default
+	// address should be 0, so the simplified definition suffices.
+	// 
+	// In the debug version, we drop into MacsBug if this weird case
+	// ever executes because it's more likely we made a mistake than
+	// we encountered a section with a default address.
+
+	state->sectionC = GetSectionBaseAddress(fragToFix, 0);
+	if (state->sectionC != nil) {
+		#if MORE_DEBUG
+			if (fragToFix->sectionHeaders[0].defaultAddress != 0) {
+				DebugStr("\pInitEngineState: Executing weird case.");
+			}
+		#endif
+		(char *) state->sectionC -= fragToFix->sectionHeaders[0].defaultAddress;
+	}
+	state->sectionD = GetSectionBaseAddress(fragToFix, 1);
+	if (state->sectionD != nil) {
+		#if MORE_DEBUG
+			if (fragToFix->sectionHeaders[1].defaultAddress != 0) {
+				DebugStr("\pInitEngineState: Executing weird case.");
+			}
+		#endif
+		(char *) state->sectionD -= fragToFix->sectionHeaders[1].defaultAddress;
+	}
+
+	err = noErr;
+	if (state->relocAddress == nil) {
+		err = cfragFragmentUsageErr;
+	}
+	return err;
+}
+
+// kPEFRelocBasicOpcodes is a table that maps the top 7 bits of the opcode
+// to a fundamental action.  It's contents are defined for me in "PEFBinaryFormat.h",
+// which is really convenient.
+
+static UInt8 kPEFRelocBasicOpcodes[kPEFRelocBasicOpcodeRange] = { PEFMaskedBasicOpcodes };
+
+static OSStatus RunRelocationEngine(const FragToFixInfo *fragToFix, 
+										PEFImportedLibrary  *importLibrary, 
+										CFMLateImportLookupProc lookup, void *refCon)
+	// This is where the rubber really hits the.  Given a fully
+	// populated fragToFix structure, the import library description
+	// of the weak imported library we're resolving, and a connection
+	// to the library we're going to substitute it, re-execute the
+	// relocation instructions (CFM has already executed them once)
+	// but only *do* instructions (ie store the change to the data section)
+	// that CFM skipped because the weak symbols were missing.
+{
+	OSStatus 	err;
+	EngineState	state;
+	UInt16 		sectionsLeftToRelocate;
+	UInt32 		totalRelocs;
+	UInt16		*relocInstrTable;
+	UInt16 		opCode;
+	
+	MoreAssertQ(fragToFix != nil);
+	MoreAssertQ(fragToFix->containerHeader.tag1 == kPEFTag1);
+	MoreAssertQ(fragToFix->sectionHeaders != nil);
+	MoreAssertQ(fragToFix->loaderSection != nil);
+	MoreAssertQ(fragToFix->section0Base != nil);	// Technically, having a nil for these two is not a problem, ...
+	MoreAssertQ(fragToFix->section1Base != nil);	// but in practise it a wildly deviant case and we should know about it.
+	MoreAssertQ(importLibrary != nil);
+	MoreAssertQ(lookup != nil);
+
+	// Before entering the loop, work out some information in advance.
+
+	// totalRelocs is only used for debugging, to make sure our
+	// relocation PC (state.currentReloc) doesn't run wild.
+	
+	totalRelocs = (fragToFix->loaderSection->loaderStringsOffset - fragToFix->loaderSection->relocInstrOffset) / sizeof(UInt16);
+	
+	// relocInstrTable is the base address of the table of relocation
+	// instructions in the fragment to fix.
+	
+	relocInstrTable = (UInt16 *)((char *) fragToFix->loaderSection + fragToFix->loaderSection->relocInstrOffset);
+	
+	// sectionsLeftToRelocate is the loop counter for the outer loop.
+	
+	MoreAssertQ(fragToFix->loaderSection->relocSectionCount <= 0x0FFFF);
+	sectionsLeftToRelocate = fragToFix->loaderSection->relocSectionCount;
+
+	// Now let's run the relocation engine.  We run it once per
+	// section in the table.  Each time around, we init the engine
+	// and then loop again, this time executing individual opcodes.
+	// The opcode loop terminates when the relocation PC
+	// (state.currentReloc) hits the final opcode (state.terminatingReloc).
+	
+	// Note:
+	// One design decision I made was to totally re-init the engine state
+	// for each section.  The CFM spec is unclear as to whether you're supposed
+	// to totally re-init the engine state, or just re-init the section-specific
+	// state (ie currentReloc, terminatingReloc, and relocAddress).  I hope this
+	// is correct, but it's hard to test without having a fragment with multiple
+	// relocated sections, which is difficult to create.
+	
+	// How do I decide which opcodes should be effective (ie make changes to
+	// the section being relocated) and which opcodes should just be executed
+	// for their side effects (ie updated state.relocAddress or state.importIndex)?
+	// The answer is both simple and subtle.  Opcodes whose actions are dependent
+	// on a symbol that was in the weak linked library are effective, those that
+	// an independent of those symbols are not.  The only opcodes that use
+	// symbolic values are kPEFRelocImportRun and kPEFRelocSmByImport, and
+	// these are only if the symbol is in the weak linked library.
+	// All other cases are executed for their side effects only.
+	//
+	// How do I determine if a symbol is in the weak linked library?
+	// Well I know the symbol's index and I know the lower bound and count
+	// of the symbols in the weak linked library, so I just do a simple
+	// bounds test, ie 
+	//
+	//   firstImportedSymbol <= importIndex < firstImportedSymbol + importedSymbolCount
+
+	// From this code, it's relatively easy to see which relocation opcodes
+	// aren't implemented.  If you ever encounter one, you'll find yourself
+	// in MacsBug with a message telling you which opcode was found.  The
+	// two big groups of opcodes I skipped were the large format opcodes
+	// and the repeating opcodes.  I skipped them because:
+	//
+	// a) I haven't got a way to generate them in a PEF container that I can 
+	//    test against. Without that, there's no way I could be assured that
+	//    the code worked.
+	//
+	// b) I'm lazy.
+
+	err = noErr;
+	while ( sectionsLeftToRelocate > 0 ) {
+		err = InitEngineState(fragToFix, sectionsLeftToRelocate, &state);
+		if (err != noErr) {
+			goto leaveNow;
+		}
+		
+		while ( state.currentReloc != state.terminatingReloc ) {
+			
+			MoreAssertQ( state.currentReloc < totalRelocs );
+
+			opCode = relocInstrTable[state.currentReloc];
+			switch ( PEFRelocBasicOpcode(opCode) ) {
+				case kPEFRelocBySectDWithSkip:
+					{
+						UInt16 skipCount;
+						UInt16 relocCount;
+						
+						skipCount = ((opCode >> 6) & 0x00FF);
+						relocCount = (opCode & 0x003F);
+						state.relocAddress += skipCount;
+						state.relocAddress += relocCount;
+					}
+					break;
+				case kPEFRelocBySectC:
+				case kPEFRelocBySectD:
+					{
+						UInt16 runLength;
+
+						runLength = (opCode & 0x01FF) + 1;
+						state.relocAddress += runLength;
+					}
+					break;
+				case kPEFRelocTVector12:
+					{
+						UInt16 runLength;
+
+						runLength = (opCode & 0x01FF) + 1;
+						state.relocAddress += (runLength * 3);
+					}
+					break;
+				case kPEFRelocTVector8:
+				case kPEFRelocVTable8:
+					{
+						UInt16 runLength;
+
+						runLength = (opCode & 0x01FF) + 1;
+						state.relocAddress += (runLength * 2);
+					}
+					break;
+				case kPEFRelocImportRun:
+					{
+						UInt32 symbolValue;
+						UInt16 runLength;
+						
+						runLength = (opCode & 0x01FF) + 1;
+						while (runLength > 0) {
+							if ( state.importIndex >= importLibrary->firstImportedSymbol && state.importIndex < (importLibrary->firstImportedSymbol + importLibrary->importedSymbolCount) ) {
+								err = LookupSymbol(lookup, refCon, fragToFix->loaderSection, state.importIndex, &symbolValue);
+								if (err != noErr) {
+									goto leaveNow;
+								}
+								*(state.relocAddress) += symbolValue;
+							}
+							state.importIndex += 1;
+							state.relocAddress += 1;
+							runLength -= 1;
+						}
+					}
+					break;
+				case kPEFRelocSmByImport:
+					{
+						UInt32 symbolValue;
+						UInt32 index;
+
+						index = (opCode & 0x01FF);
+						if ( index >= importLibrary->firstImportedSymbol && index < (importLibrary->firstImportedSymbol + importLibrary->importedSymbolCount) ) {
+							err = LookupSymbol(lookup, refCon, fragToFix->loaderSection, index, &symbolValue);
+							if (err != noErr) {
+								goto leaveNow;
+							}
+							*(state.relocAddress) += symbolValue;
+						}
+						state.importIndex = index + 1;
+						state.relocAddress += 1;
+					}
+					break;
+				case kPEFRelocSmSetSectC:
+					{
+						UInt32 index;
+
+						index = (opCode & 0x01FF);
+						state.sectionC = GetSectionBaseAddress(fragToFix, index);
+						MoreAssertQ(state.sectionC != nil);
+					}
+					break;
+				case kPEFRelocSmSetSectD:
+					{
+						UInt32 index;
+
+						index = (opCode & 0x01FF);
+						state.sectionD = GetSectionBaseAddress(fragToFix, index);
+						MoreAssertQ(state.sectionD != nil);
+					}
+					break;
+				case kPEFRelocSmBySection:
+					state.relocAddress += 1;
+					break;
+				case kPEFRelocIncrPosition:
+					{
+						UInt16 offset;
+						
+						offset = (opCode & 0x0FFF) + 1;
+						((char *) state.relocAddress) += offset;
+					}
+					break;
+				case kPEFRelocSmRepeat:
+					#if MORE_DEBUG
+						DebugStr("\pRunRelocationEngine: kPEFRelocSmRepeat not yet implemented");
+					#endif
+					err = unimpErr;
+					goto leaveNow;
+					break;
+				case kPEFRelocSetPosition:
+					{
+						UInt32 offset;
+
+						// Lot's of folks have tried various interpretations of the description of 
+						// this opCode in "Mac OS Runtime Architectures" (which states "This instruction 
+						// sets relocAddress to the address of the section offset offset."  *smile*).
+						// I eventually dug into the CFM source code to find my interpretation, which 
+						// I believe is correct.  The key point is tht the offset is relative to 
+						// the start of the section for which these relocations are being performed.
+						
+						// Skip to next reloc word, which is the second chunk of the offset.
+						
+						state.currentReloc += 1;
+						
+						// Extract offset based on the most significant 10 bits in opCode and 
+						// the next significant 16 bits in the next reloc word.
+						
+						offset = PEFRelocSetPosFullOffset(opCode, relocInstrTable[state.currentReloc]);
+
+						state.relocAddress = (UInt32 *) ( ((char *) state.sectionBase) + offset);
+					}
+					break;
+				case kPEFRelocLgByImport:
+					{
+						UInt32 symbolValue;
+						UInt32 index;
+
+						// Get the 26 bit symbol index from the current and next reloc words.
+						
+						state.currentReloc += 1;
+						index = PEFRelocLgByImportFullIndex(opCode, relocInstrTable[state.currentReloc]);
+						
+						if ( index >= importLibrary->firstImportedSymbol && index < (importLibrary->firstImportedSymbol + importLibrary->importedSymbolCount) ) {
+							err = LookupSymbol(lookup, refCon, fragToFix->loaderSection, index, &symbolValue);
+							if (err != noErr) {
+								goto leaveNow;
+							}
+							*(state.relocAddress) += symbolValue;
+						}
+						state.importIndex = index + 1;
+						state.relocAddress += 1;
+					}
+					break;
+				case kPEFRelocLgRepeat:
+					#if MORE_DEBUG
+						DebugStr("\pRunRelocationEngine: kPEFRelocLgRepeat not yet implemented");
+					#endif
+					err = unimpErr;
+					goto leaveNow;
+					break;
+				case kPEFRelocLgSetOrBySection:
+					#if MORE_DEBUG
+						DebugStr("\pRunRelocationEngine: kPEFRelocLgSetOrBySection not yet implemented");
+					#endif
+					err = unimpErr;
+					goto leaveNow;
+					break;
+				case kPEFRelocUndefinedOpcode:
+					err = cfragFragmentCorruptErr;
+					goto leaveNow;
+					break;
+				default:
+					MoreAssertQ(false);
+					err = cfragFragmentCorruptErr;
+					goto leaveNow;
+					break;
+			}
+			state.currentReloc += 1;
+		}
+		
+		sectionsLeftToRelocate -= 1;
+	}
+
+leaveNow:
+	return err;
+}
+
+extern pascal OSStatus CFMLateImportCore(const CFragSystem7DiskFlatLocator *fragToFixLocator,
+										CFragConnectionID fragToFixConnID,
+										CFragInitFunction fragToFixInitRoutine,
+										ConstStr255Param weakLinkedLibraryName,
+										CFMLateImportLookupProc lookup,
+										void *refCon)
+	// See comments in interface part.
+{
+	OSStatus err;
+	OSStatus junk;
+	FragToFixInfo fragToFix;
+	PEFImportedLibrary *importLibrary;
+	char weakLinkedLibraryNameCString[256];
+
+	MoreAssertQ(fragToFixLocator != nil);	
+	MoreAssertQ(fragToFixConnID != nil);
+	MoreAssertQ(fragToFixInitRoutine != nil);
+	MoreAssertQ(weakLinkedLibraryName != nil);	
+	MoreAssertQ(lookup != nil);	
+	
+	// Fill out the bits of fragToFix which are passed in
+	// by the client.
+	
+	MoreBlockZero(&fragToFix, sizeof(fragToFix));
+	fragToFix.locator = *fragToFixLocator;
+	fragToFix.connID  = fragToFixConnID;
+	fragToFix.initRoutine = fragToFixInitRoutine;
+	
+	// Make a C string from weakLinkedLibraryName.
+	
+	BlockMoveData(weakLinkedLibraryName + 1, weakLinkedLibraryNameCString, weakLinkedLibraryName[0]);
+	weakLinkedLibraryNameCString[weakLinkedLibraryName[0]] = 0;
+
+	// Get the basic information from the fragment.
+	// Fills out the containerHeader, sectionHeaders, loaderSection and fileRef fields
+	// of fragToFix.
+	
+	err = ReadContainerBasics(&fragToFix);
+
+	// Set up the base address fields in fragToFix (ie section0Base and section1Base)
+	// by looking up our init routine (fragToFix.initRoutine) and subtracting
+	// away the section offsets (which we get from the disk copy of the section)
+	// to derive the bases of the sections themselves.
+	
+	if (err == noErr) {
+		err = SetupSectionBaseAddresses(&fragToFix);
+	}
+	
+	// Look inside the loader section for the import library description
+	// of weakLinkedLibraryName.  We need this to know the range of symbol
+	// indexes we're going to fix up.
+	
+	if (err == noErr) {
+		err = FindImportLibrary(fragToFix.loaderSection, weakLinkedLibraryNameCString, &importLibrary);
+	}
+	
+	// Do a quick check to ensure that the library was actually imported weak.
+	// If it wasn't, it doesn't make much sense to resolve its weak imports
+	// later on.  Resolving them again is likely to be bad.
+	
+	if (err == noErr) {
+		if ((importLibrary->options & kPEFWeakImportLibMask) == 0) {
+			err = cfragFragmentUsageErr;
+		}
+	}
+	
+	// Now run the main relocation engine.
+	
+	if (err == noErr) {
+		err = RunRelocationEngine(&fragToFix, importLibrary, lookup, refCon);
+	}
+	
+	// Clean up.
+	
+	if (fragToFix.disposeSectionPointers) {
+		if (fragToFix.fileRef != 0) {
+			junk = FSClose(fragToFix.fileRef);
+			MoreAssertQ(junk == noErr);
+		}
+		if (fragToFix.loaderSection != nil) {
+			DisposePtr( (Ptr) fragToFix.loaderSection);
+			MoreAssertQ(MemError() == noErr);
+		}
+		if (fragToFix.sectionHeaders != nil) {
+			DisposePtr( (Ptr) fragToFix.sectionHeaders);
+			MoreAssertQ(MemError() == noErr);
+		}
+	}
+	return err;
+}
+
+static pascal OSStatus FragmentLookup(ConstStr255Param symName, CFragSymbolClass symClass,
+									void **symAddr, void *refCon)
+	// This is the CFMLateImportLookupProc callback used when 
+	// late importing from a CFM shared library.
+{
+	OSStatus err;
+	CFragConnectionID connIDToImport;
+	CFragSymbolClass  foundSymClass;
+	
+	MoreAssertQ(symName != nil);
+	MoreAssertQ(symAddr != nil);
+	MoreAssertQ(refCon  != nil);
+	
+	connIDToImport = (CFragConnectionID) refCon;
+	
+	// Shame there's no way to validate that connIDToImport is valid.
+
+	err = FindSymbol(connIDToImport, symName, (Ptr *) symAddr, &foundSymClass);
+	if (err == noErr) {
+		// If the symbol isn't of the right class, we act like we didn't 
+		// find it, but also assert in the debug build because weird things 
+		// are afoot.
+		if (foundSymClass != symClass) {
+			MoreAssertQ(false);
+			*symAddr = nil;
+			err = cfragNoSymbolErr;
+		}
+	}
+	return err;
+}
+
+extern pascal OSStatus CFMLateImportLibrary(const CFragSystem7DiskFlatLocator *fragToFixLocator,
+										CFragConnectionID fragToFixConnID,
+										CFragInitFunction fragToFixInitRoutine,
+										ConstStr255Param weakLinkedLibraryName,
+										CFragConnectionID connIDToImport)
+	// See comments in interface part.
+{
+	MoreAssertQ(connIDToImport != nil);
+	return CFMLateImportCore(fragToFixLocator, fragToFixConnID, fragToFixInitRoutine,
+										weakLinkedLibraryName, FragmentLookup, connIDToImport);
+}
+
+static pascal OSStatus BundleLookup(ConstStr255Param symName, CFragSymbolClass symClass,
+									void **symAddr, void *refCon)
+	// This is the CFMLateImportLookupProc callback used when 
+	// late importing from a CFBundle.
+{
+	OSStatus 	err;
+	CFBundleRef bundleToImport;
+	CFStringRef symNameStr;
+	
+	MoreAssertQ(symName != nil);
+	MoreAssertQ(symAddr != nil);
+	MoreAssertQ(refCon  != nil);
+	
+	symNameStr = nil;
+	
+	bundleToImport = (CFBundleRef) refCon;
+	
+	// Shame there's no way to validate that bundleToImport is really a bundle.
+	
+	// We can only find function pointers because CFBundleGetFunctionPointerForName 
+	// only works for function pointers.  So if the client is asking for something 
+	// other than a function pointer (ie TVector symbol) then we don't even true.
+	// Also assert in the debug build because this shows a certain lack of 
+	// understanding on the part of the client.
+	//
+	// CF is being revise to support accessing data symbols using a new API
+	// (currently this is available to Apple internal developers as 
+	// CFBundleGetDataPointerForName).  When the new API is available in a 
+	// public header file I should revise this code to lift this restriction.
+	
+	err = noErr;
+	if (symClass != kTVectorCFragSymbol) {
+		MoreAssertQ(false);
+		err = cfragNoSymbolErr;
+	}
+	if (err == noErr) {
+		symNameStr = CFStringCreateWithPascalString(kCFAllocatorSystemDefault, 
+													symName, kCFStringEncodingMacRoman);
+		if (symNameStr == nil) {
+			err = coreFoundationUnknownErr;
+		}
+	}
+	if (err == noErr) {
+		*symAddr = CFBundleGetFunctionPointerForName(bundleToImport, symNameStr);
+		if (*symAddr == nil) {
+			err = cfragNoSymbolErr;
+		}
+	}
+	if (symNameStr != nil) {
+		CFRelease(symNameStr);
+	}
+	return err;
+}
+
+extern pascal OSStatus CFMLateImportBundle(const CFragSystem7DiskFlatLocator *fragToFixLocator,
+										CFragConnectionID fragToFixConnID,
+										CFragInitFunction fragToFixInitRoutine,
+										ConstStr255Param weakLinkedLibraryName,
+										CFBundleRef bundleToImport)
+	// See comments in interface part.
+{
+	MoreAssertQ(bundleToImport != nil);
+	return CFMLateImportCore(fragToFixLocator, fragToFixConnID, fragToFixInitRoutine,
+										weakLinkedLibraryName, BundleLookup, bundleToImport);
+}


Property changes on: vendor/Python/current/Mac/Modules/cg/CFMLateImport.c
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Mac/Modules/cg/CFMLateImport.h
===================================================================
--- vendor/Python/current/Mac/Modules/cg/CFMLateImport.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/cg/CFMLateImport.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,272 @@
+/*
+	File:		CFMLateImport.h
+
+	Contains:	Interface to CFM late import library.
+
+	Written by:	Quinn
+
+	Copyright:	Copyright © 1999 by Apple Computer, Inc., all rights reserved.
+
+				You may incorporate this Apple sample source code into your program(s) without
+				restriction. This Apple sample source code has been provided "AS IS" and the
+				responsibility for its operation is yours. You are not permitted to redistribute
+				this Apple sample source code as "Apple sample source code" after having made
+				changes. If you're going to re-distribute the source, we require that you make
+				it clear in the source that the code was descended from Apple sample source
+				code, but that you've made changes.
+
+	Change History (most recent first):
+
+         <6>     21/9/01    Quinn   Changes for CWPro7 Mach-O build.
+         <5>     19/9/01    Quinn   Change comments to reflect the fact that an unpacked data
+                                    section is no longer required.
+         <4>     19/9/01    Quinn   Simplified API and implementation after a suggestion by Eric
+                                    Grant. You no longer have to CFM export a dummy function; you
+                                    can just pass in the address of your fragment's init routine.
+         <3>    16/11/00    Quinn   Allow symbol finding via a callback and use that to implement
+                                    CFBundle support.
+         <2>    18/10/99    Quinn   Renamed CFMLateImport to CFMLateImportLibrary to allow for
+                                    possible future API expansion.
+         <1>     15/6/99    Quinn   First checked in.
+*/
+
+#pragma once
+
+/////////////////////////////////////////////////////////////////
+
+// MoreIsBetter Setup
+
+//#include "MoreSetup.h"
+
+// Mac OS Interfaces
+
+#if ! MORE_FRAMEWORK_INCLUDES
+	#include <MacTypes.h>
+	#include <CodeFragments.h>
+	#include <Devices.h>
+	#include <CFBundle.h>
+#endif
+
+/////////////////////////////////////////////////////////////////
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*	FAQ
+	---
+	
+	Q:	What does this library do?
+	A:	It allows you to resolve a weak linked library at runtime,
+	   	by supply a CFM connection to the library that should substitute
+	   	for the weak linked one.
+	
+	Q:	Does the substituted library have to have the same name as the
+		weak linked library.
+	A:	No.
+	
+	Q:	What's this useful for?
+	A:	The most obvious example of where this is useful is when
+		you rely on shared libraries that the user might delete
+		or move.  To can find the shared library (possibly even
+		using CatSearch), call GetDiskFragment to open a connection
+		to it, late import it using this library, and then the
+		rest of your code can continue to use the shared library
+		as if nothing had happened.  No more defining thousands
+		of stub routines which call through routine pointers.
+		
+		There are, however, numerous less obvious uses.  You can
+		use this code to make a 'self repairing' application.  If
+		the user removes your shared library from the Extensions
+		folder, the startup code for your application can offer
+		tor re-install it.  If the user agrees, you can then
+		re-install your shared library, late import it, and then
+		continue running your application if nothing happened.
+		
+		You can even use this code to free yourself from the
+		Extensions folder entirely.  Say you have a suite of
+		applications that currently installs a dozen shared 
+		libraries in the Extensions folder.  You can move those
+		libraries to another folder entirely and each application's
+		startup code can track down the library (using an alias
+		in the Preferences file) and late import it.
+		
+		An even cooler use is to provide easy abstraction layers.
+		Say you have a network code for both the MacTCP
+		API and the Open Transport API.  Typically, you would be
+		force to do this by having an abstraction layer where every
+		routine contains a switch between MacTCP and OT.  Your
+		OpenSocket routine might look like:
+
+			static int OpenSocket(void)
+			{
+			    if (gOTAvailable) {
+			        return OpenSocketOT();
+			    } else {
+			        return OpenSocketMacTCP();
+			    }
+			}
+		
+		With this code, you can avoid that entirely.  Simply
+		weak link to a shared library that you know is never
+		going to be implemented ("crea;MySocketsDummy") and then, 
+		at runtime, decide whether the system has MacTCP or OT
+		and late import the relevant real implementation
+		("crea;MySocketsMacTCP" or "crea;MySocketsOT").
+		One benefit of this approach is that only the MacTCP or
+		the OT code is resident in memory on any given system.
+*/
+
+typedef pascal OSStatus (*CFMLateImportLookupProc)(ConstStr255Param symName, CFragSymbolClass symClass,
+													void **symAddr, void *refCon);
+	// CFMLateImportLookupProc defines a callback for CFMLateImportCore.
+	// The routine is expected to look up the address of the symbol named 
+	// symName and return it in *symAddr.  The symbol should be of class 
+	// symClass, although the callback decides whether a class mismatch is 
+	// an error.  refCon is an application defined value that was originally 
+	// passed in to CFMLateImportCore.
+	//
+	// If this routine returns an error, a symbol address of 0 is assumed. 
+	// If the symbol is marked as a weak import, the CFMLateImportCore will 
+	// continue, otherwise the CFMLateImportCore routine will fail with the 
+	// error.
+	
+extern pascal OSStatus CFMLateImportCore(const CFragSystem7DiskFlatLocator *fragToFixLocator,
+										CFragConnectionID fragToFixConnID,
+										CFragInitFunction fragToFixInitRoutine,
+										ConstStr255Param weakLinkedLibraryName,
+										CFMLateImportLookupProc lookup,
+										void *refCon);
+	// This routine will link you, at runtime, to some library 
+	// that you were weak linked to and wasn't present when your
+	// fragment was prepared.  As well as the obvious functionality
+	// of being able to resolve weak links after prepare time,
+	// this functionality can be put to a number of less obvious uses,
+	// some of which are discussed at the top of this header file.
+	//
+	// To call this routine, you need a number of pieces of information:
+	//
+	// 1. fragToFixLocator, fragToFixConnID:  The location of your own
+	//    code fragment on disk and the CFM connection ID to your own
+	//    code fragment.  Typically you get this information from your 
+	//    fragment's CFM init routine.  You must ensure that
+	//    fragToFixLocator->fileSpec points to an FSSpec of the
+	//    file which holds your code fragment.
+	//
+	//    IMPORTANT:
+	//    The fact that you pass in a CFragSystem7DiskFlatLocator as the
+	//    fragToFixLocator implies that the fragment to be fixed up must
+	//    be in the data fork of a file.  The code could be modified
+	//    to remove this requirement, but on disk code fragments are the most
+	//    common case.
+	//
+	//    IMPORTANT:
+	//    The fragment to fix may have a packed data section.  Packing the 
+	//    data section will reduce the size of your fragment on disk, but it 
+	//    will significantly increase the memory needed by this routine 
+	//    (it increases memory usage by the sum of the sizes of the packed 
+	//    and unpacked data section).  See below for instructions on how to 
+	//    create an unpacked data section.
+	//
+	// 2. fragToFixInitRoutine:  A pointer to your own code fragment's
+	//    fragment initialiser routine.  You necessarily have one of these 
+	//    because you need it to get values for the fragToFixLocator and 
+	//    fragToFixConnID parameters.  Just pass its address in as a parameter 
+	//    as well. 
+	//
+	// 3. weakLinkedLibraryName:  The name of the weak linked library which
+	//    failed to link.  You must have weak linked to this library.
+	//    It is oxymoric for you to pass a strong linked library here,
+	//    because your code would not have prepared if a strong linked
+	//    library failed to prepare, and so you couldn't supply a valid
+	///   fragToFix.
+	//
+	// 4. lookup, refCon:  A pointer to a callback function that the 
+	//	  routine calls to look up the address of a symbol, and a refCon 
+	//    for that callback routine.
+	//
+	// Note:
+	// The fragToFixLocator and fragToFixInitRoutine parameters
+	// are artifacts of the way in which this functionality is implemented.
+	// In an ideal world, where CFM exported decent introspection APIs
+	// to third party developers, these parameters would not be necessary.
+	// If you're using this code inside Apple, you probably should investigate
+	// using the CFM private APIs for getting at the information these
+	// parameters are needed for.  See the comments inside the implementation
+	// for more details.
+	//
+	// Note:
+	// The extra memory taken when you use a packed data section is also an 
+	// artifact of my workaround for the lack of CFM introspection APIs.  In 
+	// my opinion it's better to use an unpacked data section and consume more 
+	// space on disk while saving memory.  In CodeWarrior you can switch to an 
+	// unpacked data section by checking the "Expand Uninitialized Data" 
+	// checkbox in the "PPC PEF" settings panel.  In MPW, specified the
+	// "-packdata off" option to PPCLink.
+	//
+	// When the routine returns, any symbols that you imported from the
+	// library named weakLinkedLibraryName will be resolved to the address
+	// of the symbol provided by the "lookup" callback routine.
+	//
+	// It is possible for an unresolved import to remain unresolved after
+	// this routine returns.  If the symbol import is marked as weak (as
+	// opposed to the library, which *must* be marked as weak) and the symbol
+	// is not found by the "lookup" callback, the routine will simple skip 
+	// that symbol.  If the symbol isn't marked as weak, the routine will fail 
+	// in that case.
+	//
+	// Most of the possible error results are co-opted CFM errors.  These
+	// include:
+	//
+	// cfragFragmentFormatErr  -- The fragment to fix is is an unknown format.
+	// cfragNoSectionErr       -- Could not find the loader section in the fragment to fix.
+	// cfragNoLibraryErr       -- The fragment to fix is not weak linked to weakLinkedLibraryName.
+	// cfragFragmentUsageErr   -- The fragment to fix doesn't have a data section.
+	//                         -- The fragment to fix is strong linked to weakLinkedLibraryName.
+	//                         -- The fragment doesn't have an init routine.
+	// cfragFragmentCorruptErr -- Encountered an undefined relocation opcode.
+	// unimpErr                -- Encountered an unimplement relocation opcode.  The
+	//                            relocation engine only implements a subset of the CFM
+	//                            relocation opcodes, the subset most commonly used by
+	//                            MPW and CodeWarrior PEF containers.  If you encounter
+	//                            this error, you'll probably have to add the weird
+	//                            relocation opcode to the engine, which shouldn't be
+	//                            be too hard.
+	// memFullErr			   -- It's likely that this error is triggered by the memory 
+	//                            needed to unpack your data section.  Either make your 
+	//                            data section smaller, or unpack it (see above).
+	// errors returned by FindSymbol
+	// errors returned by Memory Manager
+	//
+	// The routine needs enough memory to hold the loader section of the fragment
+	// to fix in memory.  It allocates that memory using NewPtr and dispsoses of 
+	// it before it returns.  You may want to change the memory allocator, which
+	// is very simple.
+
+extern pascal OSStatus CFMLateImportLibrary(const CFragSystem7DiskFlatLocator *fragToFixLocator,
+										CFragConnectionID fragToFixConnID,
+										CFragInitFunction fragToFixInitRoutine,
+										ConstStr255Param weakLinkedLibraryName,
+										CFragConnectionID connIDToImport);
+	// A wrapper around CFMLateImportCore that looks up symbols by calling 
+	// FindSymbol on a connection to a CFM library (connIDToImport).
+	// You can get this connection ID through any standard CFM API, for example
+	// GetSharedLibrary, GetDiskFragment, or GetMemFragment.
+	//
+	// IMPORTANT:
+	// The fragment name for connIDToImport *does not* have to match
+	// weakLinkedLibraryName.  This is part of the power of this library.
+
+extern pascal OSStatus CFMLateImportBundle(const CFragSystem7DiskFlatLocator *fragToFixLocator,
+										CFragConnectionID fragToFixConnID,
+										CFragInitFunction fragToFixInitRoutine,
+										ConstStr255Param weakLinkedLibraryName,
+										CFBundleRef bundleToImport);
+	// A wrapper around CFMLateImportCore that looks up symbols by calling 
+	// CFBundleGetFunctionPointerForName on a reference to a Core Foundation 
+	// bundle (bundleToImport).  You can get this reference through any 
+	// Core Foundation bundle API, for example CFBundleCreate.
+
+#ifdef __cplusplus
+}
+#endif


Property changes on: vendor/Python/current/Mac/Modules/cg/CFMLateImport.h
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Mac/Modules/cg/CGStubLib
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Mac/Modules/cg/CGStubLib
___________________________________________________________________
Name: svn:executable
   + 
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Mac/Modules/cg/CGStubLib.exp
===================================================================
--- vendor/Python/current/Mac/Modules/cg/CGStubLib.exp	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/cg/CGStubLib.exp	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,60 @@
+CGContextShowTextAtPoint
+CGContextShowText
+CGContextSelectFont
+CGContextSetTextDrawingMode
+CGContextDrawPath
+CGContextSetLineJoin
+CGContextSetLineCap
+CGContextGetTextPosition
+CGContextGetPathCurrentPoint
+CGContextSetShouldAntialias
+CGContextSynchronize
+CGContextFlush
+CGContextEndPage
+CGContextSetFontSize
+CGContextGetTextMatrix
+CGContextSetTextMatrix
+CGContextSetTextPosition
+CGContextSetCharacterSpacing
+CGContextSetCMYKStrokeColor
+CGContextSetCMYKFillColor
+CGContextSetRGBStrokeColor
+CGContextSetRGBFillColor
+CGContextSetGrayStrokeColor
+CGContextSetGrayFillColor
+CGContextClipToRect
+CGContextEOClip
+CGContextClip
+CGContextClearRect
+CGContextStrokeRectWithWidth
+CGContextStrokeRect
+CGContextFillRect
+CGContextStrokePath
+CGContextEOFillPath
+CGContextFillPath
+CGContextGetPathBoundingBox
+CGContextIsPathEmpty
+CGContextAddArcToPoint
+CGContextAddArc
+CGContextAddRect
+CGContextClosePath
+CGContextAddQuadCurveToPoint
+CGContextAddCurveToPoint
+CGContextAddLineToPoint
+CGContextMoveToPoint
+CGContextBeginPath
+CGContextSetAlpha
+CGContextSetFlatness
+CGContextSetMiterLimit
+CGContextSetLineWidth
+CGContextGetCTM
+CGContextConcatCTM
+CGContextRotateCTM
+CGContextTranslateCTM
+CGContextScaleCTM
+CGContextRestoreGState
+CGContextSaveGState
+CGContextRelease
+CreateCGContextForPort
+SyncCGContextOriginWithPort
+ClipCGContextToRegion


Property changes on: vendor/Python/current/Mac/Modules/cg/CGStubLib.exp
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Mac/Modules/cg/CGStubLib.readme
===================================================================
--- vendor/Python/current/Mac/Modules/cg/CGStubLib.readme	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/cg/CGStubLib.readme	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,3 @@
+# CGStubLib was created by issuing this command in MPW:
+
+MakeStub CGStubLib.exp -o CGStubLib


Property changes on: vendor/Python/current/Mac/Modules/cg/CGStubLib.readme
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Mac/Modules/cg/_CGmodule.c
===================================================================
--- vendor/Python/current/Mac/Modules/cg/_CGmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/cg/_CGmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1308 @@
+
+/* =========================== Module _CG =========================== */
+
+#include "Python.h"
+
+
+
+#include "pymactoolbox.h"
+
+/* Macro to test whether a weak-loaded CFM function exists */
+#define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL )  {\
+        PyErr_SetString(PyExc_NotImplementedError, \
+        "Not available in this shared library/OS version"); \
+        return NULL; \
+    }} while(0)
+
+
+#include <ApplicationServices/ApplicationServices.h>
+
+extern int GrafObj_Convert(PyObject *, GrafPtr *);
+
+/*
+** Manual converters
+*/
+
+PyObject *CGPoint_New(CGPoint *itself)
+{
+
+        return Py_BuildValue("(ff)",
+                        itself->x,
+                        itself->y);
+}
+
+int
+CGPoint_Convert(PyObject *v, CGPoint *p_itself)
+{
+        if( !PyArg_Parse(v, "(ff)",
+                        &p_itself->x,
+                        &p_itself->y) )
+                return 0;
+        return 1;
+}
+
+PyObject *CGRect_New(CGRect *itself)
+{
+
+        return Py_BuildValue("(ffff)",
+                        itself->origin.x,
+                        itself->origin.y,
+                        itself->size.width,
+                        itself->size.height);
+}
+
+int
+CGRect_Convert(PyObject *v, CGRect *p_itself)
+{
+        if( !PyArg_Parse(v, "(ffff)",
+                        &p_itself->origin.x,
+                        &p_itself->origin.y,
+                        &p_itself->size.width,
+                        &p_itself->size.height) )
+                return 0;
+        return 1;
+}
+
+PyObject *CGAffineTransform_New(CGAffineTransform *itself)
+{
+
+        return Py_BuildValue("(ffffff)",
+                        itself->a,
+                        itself->b,
+                        itself->c,
+                        itself->d,
+                        itself->tx,
+                        itself->ty);
+}
+
+int
+CGAffineTransform_Convert(PyObject *v, CGAffineTransform *p_itself)
+{
+        if( !PyArg_Parse(v, "(ffffff)",
+                        &p_itself->a,
+                        &p_itself->b,
+                        &p_itself->c,
+                        &p_itself->d,
+                        &p_itself->tx,
+                        &p_itself->ty) )
+                return 0;
+        return 1;
+}
+
+static PyObject *CG_Error;
+
+/* -------------------- Object type CGContextRef -------------------- */
+
+PyTypeObject CGContextRef_Type;
+
+#define CGContextRefObj_Check(x) ((x)->ob_type == &CGContextRef_Type || PyObject_TypeCheck((x), &CGContextRef_Type))
+
+typedef struct CGContextRefObject {
+	PyObject_HEAD
+	CGContextRef ob_itself;
+} CGContextRefObject;
+
+PyObject *CGContextRefObj_New(CGContextRef itself)
+{
+	CGContextRefObject *it;
+	it = PyObject_NEW(CGContextRefObject, &CGContextRef_Type);
+	if (it == NULL) return NULL;
+	it->ob_itself = itself;
+	return (PyObject *)it;
+}
+
+int CGContextRefObj_Convert(PyObject *v, CGContextRef *p_itself)
+{
+	if (!CGContextRefObj_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "CGContextRef required");
+		return 0;
+	}
+	*p_itself = ((CGContextRefObject *)v)->ob_itself;
+	return 1;
+}
+
+static void CGContextRefObj_dealloc(CGContextRefObject *self)
+{
+	CGContextRelease(self->ob_itself);
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *CGContextRefObj_CGContextSaveGState(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	CGContextSaveGState(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextRestoreGState(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	CGContextRestoreGState(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextScaleCTM(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	float sx;
+	float sy;
+	if (!PyArg_ParseTuple(_args, "ff",
+	                      &sx,
+	                      &sy))
+		return NULL;
+	CGContextScaleCTM(_self->ob_itself,
+	                  sx,
+	                  sy);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextTranslateCTM(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	float tx;
+	float ty;
+	if (!PyArg_ParseTuple(_args, "ff",
+	                      &tx,
+	                      &ty))
+		return NULL;
+	CGContextTranslateCTM(_self->ob_itself,
+	                      tx,
+	                      ty);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextRotateCTM(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	float angle;
+	if (!PyArg_ParseTuple(_args, "f",
+	                      &angle))
+		return NULL;
+	CGContextRotateCTM(_self->ob_itself,
+	                   angle);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextConcatCTM(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CGAffineTransform transform;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CGAffineTransform_Convert, &transform))
+		return NULL;
+	CGContextConcatCTM(_self->ob_itself,
+	                   transform);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextGetCTM(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CGAffineTransform _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CGContextGetCTM(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     CGAffineTransform_New, &_rv);
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextSetLineWidth(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	float width;
+	if (!PyArg_ParseTuple(_args, "f",
+	                      &width))
+		return NULL;
+	CGContextSetLineWidth(_self->ob_itself,
+	                      width);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextSetLineCap(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	int cap;
+	if (!PyArg_ParseTuple(_args, "i",
+	                      &cap))
+		return NULL;
+	CGContextSetLineCap(_self->ob_itself,
+	                    cap);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextSetLineJoin(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	int join;
+	if (!PyArg_ParseTuple(_args, "i",
+	                      &join))
+		return NULL;
+	CGContextSetLineJoin(_self->ob_itself,
+	                     join);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextSetMiterLimit(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	float limit;
+	if (!PyArg_ParseTuple(_args, "f",
+	                      &limit))
+		return NULL;
+	CGContextSetMiterLimit(_self->ob_itself,
+	                       limit);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextSetFlatness(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	float flatness;
+	if (!PyArg_ParseTuple(_args, "f",
+	                      &flatness))
+		return NULL;
+	CGContextSetFlatness(_self->ob_itself,
+	                     flatness);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextSetAlpha(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	float alpha;
+	if (!PyArg_ParseTuple(_args, "f",
+	                      &alpha))
+		return NULL;
+	CGContextSetAlpha(_self->ob_itself,
+	                  alpha);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextBeginPath(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	CGContextBeginPath(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextMoveToPoint(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	float x;
+	float y;
+	if (!PyArg_ParseTuple(_args, "ff",
+	                      &x,
+	                      &y))
+		return NULL;
+	CGContextMoveToPoint(_self->ob_itself,
+	                     x,
+	                     y);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextAddLineToPoint(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	float x;
+	float y;
+	if (!PyArg_ParseTuple(_args, "ff",
+	                      &x,
+	                      &y))
+		return NULL;
+	CGContextAddLineToPoint(_self->ob_itself,
+	                        x,
+	                        y);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextAddCurveToPoint(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	float cp1x;
+	float cp1y;
+	float cp2x;
+	float cp2y;
+	float x;
+	float y;
+	if (!PyArg_ParseTuple(_args, "ffffff",
+	                      &cp1x,
+	                      &cp1y,
+	                      &cp2x,
+	                      &cp2y,
+	                      &x,
+	                      &y))
+		return NULL;
+	CGContextAddCurveToPoint(_self->ob_itself,
+	                         cp1x,
+	                         cp1y,
+	                         cp2x,
+	                         cp2y,
+	                         x,
+	                         y);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextAddQuadCurveToPoint(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	float cpx;
+	float cpy;
+	float x;
+	float y;
+	if (!PyArg_ParseTuple(_args, "ffff",
+	                      &cpx,
+	                      &cpy,
+	                      &x,
+	                      &y))
+		return NULL;
+	CGContextAddQuadCurveToPoint(_self->ob_itself,
+	                             cpx,
+	                             cpy,
+	                             x,
+	                             y);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextClosePath(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	CGContextClosePath(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextAddRect(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CGRect rect;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CGRect_Convert, &rect))
+		return NULL;
+	CGContextAddRect(_self->ob_itself,
+	                 rect);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextAddArc(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	float x;
+	float y;
+	float radius;
+	float startAngle;
+	float endAngle;
+	int clockwise;
+	if (!PyArg_ParseTuple(_args, "fffffi",
+	                      &x,
+	                      &y,
+	                      &radius,
+	                      &startAngle,
+	                      &endAngle,
+	                      &clockwise))
+		return NULL;
+	CGContextAddArc(_self->ob_itself,
+	                x,
+	                y,
+	                radius,
+	                startAngle,
+	                endAngle,
+	                clockwise);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextAddArcToPoint(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	float x1;
+	float y1;
+	float x2;
+	float y2;
+	float radius;
+	if (!PyArg_ParseTuple(_args, "fffff",
+	                      &x1,
+	                      &y1,
+	                      &x2,
+	                      &y2,
+	                      &radius))
+		return NULL;
+	CGContextAddArcToPoint(_self->ob_itself,
+	                       x1,
+	                       y1,
+	                       x2,
+	                       y2,
+	                       radius);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextIsPathEmpty(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	int _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CGContextIsPathEmpty(_self->ob_itself);
+	_res = Py_BuildValue("i",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextGetPathCurrentPoint(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CGPoint _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CGContextGetPathCurrentPoint(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     CGPoint_New, &_rv);
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextGetPathBoundingBox(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CGRect _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CGContextGetPathBoundingBox(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     CGRect_New, &_rv);
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextDrawPath(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	int mode;
+	if (!PyArg_ParseTuple(_args, "i",
+	                      &mode))
+		return NULL;
+	CGContextDrawPath(_self->ob_itself,
+	                  mode);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextFillPath(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	CGContextFillPath(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextEOFillPath(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	CGContextEOFillPath(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextStrokePath(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	CGContextStrokePath(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextFillRect(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CGRect rect;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CGRect_Convert, &rect))
+		return NULL;
+	CGContextFillRect(_self->ob_itself,
+	                  rect);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextStrokeRect(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CGRect rect;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CGRect_Convert, &rect))
+		return NULL;
+	CGContextStrokeRect(_self->ob_itself,
+	                    rect);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextStrokeRectWithWidth(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CGRect rect;
+	float width;
+	if (!PyArg_ParseTuple(_args, "O&f",
+	                      CGRect_Convert, &rect,
+	                      &width))
+		return NULL;
+	CGContextStrokeRectWithWidth(_self->ob_itself,
+	                             rect,
+	                             width);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextClearRect(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CGRect rect;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CGRect_Convert, &rect))
+		return NULL;
+	CGContextClearRect(_self->ob_itself,
+	                   rect);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextClip(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	CGContextClip(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextEOClip(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	CGContextEOClip(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextClipToRect(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CGRect rect;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CGRect_Convert, &rect))
+		return NULL;
+	CGContextClipToRect(_self->ob_itself,
+	                    rect);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextSetGrayFillColor(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	float gray;
+	float alpha;
+	if (!PyArg_ParseTuple(_args, "ff",
+	                      &gray,
+	                      &alpha))
+		return NULL;
+	CGContextSetGrayFillColor(_self->ob_itself,
+	                          gray,
+	                          alpha);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextSetGrayStrokeColor(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	float gray;
+	float alpha;
+	if (!PyArg_ParseTuple(_args, "ff",
+	                      &gray,
+	                      &alpha))
+		return NULL;
+	CGContextSetGrayStrokeColor(_self->ob_itself,
+	                            gray,
+	                            alpha);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextSetRGBFillColor(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	float red;
+	float green;
+	float blue;
+	float alpha;
+	if (!PyArg_ParseTuple(_args, "ffff",
+	                      &red,
+	                      &green,
+	                      &blue,
+	                      &alpha))
+		return NULL;
+	CGContextSetRGBFillColor(_self->ob_itself,
+	                         red,
+	                         green,
+	                         blue,
+	                         alpha);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextSetRGBStrokeColor(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	float red;
+	float green;
+	float blue;
+	float alpha;
+	if (!PyArg_ParseTuple(_args, "ffff",
+	                      &red,
+	                      &green,
+	                      &blue,
+	                      &alpha))
+		return NULL;
+	CGContextSetRGBStrokeColor(_self->ob_itself,
+	                           red,
+	                           green,
+	                           blue,
+	                           alpha);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextSetCMYKFillColor(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	float cyan;
+	float magenta;
+	float yellow;
+	float black;
+	float alpha;
+	if (!PyArg_ParseTuple(_args, "fffff",
+	                      &cyan,
+	                      &magenta,
+	                      &yellow,
+	                      &black,
+	                      &alpha))
+		return NULL;
+	CGContextSetCMYKFillColor(_self->ob_itself,
+	                          cyan,
+	                          magenta,
+	                          yellow,
+	                          black,
+	                          alpha);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextSetCMYKStrokeColor(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	float cyan;
+	float magenta;
+	float yellow;
+	float black;
+	float alpha;
+	if (!PyArg_ParseTuple(_args, "fffff",
+	                      &cyan,
+	                      &magenta,
+	                      &yellow,
+	                      &black,
+	                      &alpha))
+		return NULL;
+	CGContextSetCMYKStrokeColor(_self->ob_itself,
+	                            cyan,
+	                            magenta,
+	                            yellow,
+	                            black,
+	                            alpha);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextGetInterpolationQuality(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	int _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CGContextGetInterpolationQuality(_self->ob_itself);
+	_res = Py_BuildValue("i",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextSetInterpolationQuality(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	int quality;
+	if (!PyArg_ParseTuple(_args, "i",
+	                      &quality))
+		return NULL;
+	CGContextSetInterpolationQuality(_self->ob_itself,
+	                                 quality);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextSetCharacterSpacing(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	float spacing;
+	if (!PyArg_ParseTuple(_args, "f",
+	                      &spacing))
+		return NULL;
+	CGContextSetCharacterSpacing(_self->ob_itself,
+	                             spacing);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextSetTextPosition(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	float x;
+	float y;
+	if (!PyArg_ParseTuple(_args, "ff",
+	                      &x,
+	                      &y))
+		return NULL;
+	CGContextSetTextPosition(_self->ob_itself,
+	                         x,
+	                         y);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextGetTextPosition(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CGPoint _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CGContextGetTextPosition(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     CGPoint_New, &_rv);
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextSetTextMatrix(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CGAffineTransform transform;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CGAffineTransform_Convert, &transform))
+		return NULL;
+	CGContextSetTextMatrix(_self->ob_itself,
+	                       transform);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextGetTextMatrix(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CGAffineTransform _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CGContextGetTextMatrix(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     CGAffineTransform_New, &_rv);
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextSetTextDrawingMode(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	int mode;
+	if (!PyArg_ParseTuple(_args, "i",
+	                      &mode))
+		return NULL;
+	CGContextSetTextDrawingMode(_self->ob_itself,
+	                            mode);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextSetFontSize(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	float size;
+	if (!PyArg_ParseTuple(_args, "f",
+	                      &size))
+		return NULL;
+	CGContextSetFontSize(_self->ob_itself,
+	                     size);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextSelectFont(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	char * name;
+	float size;
+	int textEncoding;
+	if (!PyArg_ParseTuple(_args, "sfi",
+	                      &name,
+	                      &size,
+	                      &textEncoding))
+		return NULL;
+	CGContextSelectFont(_self->ob_itself,
+	                    name,
+	                    size,
+	                    textEncoding);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextShowText(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	char *cstring__in__;
+	long cstring__len__;
+	int cstring__in_len__;
+	if (!PyArg_ParseTuple(_args, "s#",
+	                      &cstring__in__, &cstring__in_len__))
+		return NULL;
+	cstring__len__ = cstring__in_len__;
+	CGContextShowText(_self->ob_itself,
+	                  cstring__in__, cstring__len__);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextShowTextAtPoint(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	float x;
+	float y;
+	char *cstring__in__;
+	long cstring__len__;
+	int cstring__in_len__;
+	if (!PyArg_ParseTuple(_args, "ffs#",
+	                      &x,
+	                      &y,
+	                      &cstring__in__, &cstring__in_len__))
+		return NULL;
+	cstring__len__ = cstring__in_len__;
+	CGContextShowTextAtPoint(_self->ob_itself,
+	                         x,
+	                         y,
+	                         cstring__in__, cstring__len__);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextEndPage(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	CGContextEndPage(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextFlush(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	CGContextFlush(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextSynchronize(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	CGContextSynchronize(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_CGContextSetShouldAntialias(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	int shouldAntialias;
+	if (!PyArg_ParseTuple(_args, "i",
+	                      &shouldAntialias))
+		return NULL;
+	CGContextSetShouldAntialias(_self->ob_itself,
+	                            shouldAntialias);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_SyncCGContextOriginWithPort(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CGrafPtr port;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      GrafObj_Convert, &port))
+		return NULL;
+	SyncCGContextOriginWithPort(_self->ob_itself,
+	                            port);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CGContextRefObj_ClipCGContextToRegion(CGContextRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect portRect;
+	RgnHandle region;
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetRect, &portRect,
+	                      ResObj_Convert, &region))
+		return NULL;
+	ClipCGContextToRegion(_self->ob_itself,
+	                      &portRect,
+	                      region);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyMethodDef CGContextRefObj_methods[] = {
+	{"CGContextSaveGState", (PyCFunction)CGContextRefObj_CGContextSaveGState, 1,
+	 PyDoc_STR("() -> None")},
+	{"CGContextRestoreGState", (PyCFunction)CGContextRefObj_CGContextRestoreGState, 1,
+	 PyDoc_STR("() -> None")},
+	{"CGContextScaleCTM", (PyCFunction)CGContextRefObj_CGContextScaleCTM, 1,
+	 PyDoc_STR("(float sx, float sy) -> None")},
+	{"CGContextTranslateCTM", (PyCFunction)CGContextRefObj_CGContextTranslateCTM, 1,
+	 PyDoc_STR("(float tx, float ty) -> None")},
+	{"CGContextRotateCTM", (PyCFunction)CGContextRefObj_CGContextRotateCTM, 1,
+	 PyDoc_STR("(float angle) -> None")},
+	{"CGContextConcatCTM", (PyCFunction)CGContextRefObj_CGContextConcatCTM, 1,
+	 PyDoc_STR("(CGAffineTransform transform) -> None")},
+	{"CGContextGetCTM", (PyCFunction)CGContextRefObj_CGContextGetCTM, 1,
+	 PyDoc_STR("() -> (CGAffineTransform _rv)")},
+	{"CGContextSetLineWidth", (PyCFunction)CGContextRefObj_CGContextSetLineWidth, 1,
+	 PyDoc_STR("(float width) -> None")},
+	{"CGContextSetLineCap", (PyCFunction)CGContextRefObj_CGContextSetLineCap, 1,
+	 PyDoc_STR("(int cap) -> None")},
+	{"CGContextSetLineJoin", (PyCFunction)CGContextRefObj_CGContextSetLineJoin, 1,
+	 PyDoc_STR("(int join) -> None")},
+	{"CGContextSetMiterLimit", (PyCFunction)CGContextRefObj_CGContextSetMiterLimit, 1,
+	 PyDoc_STR("(float limit) -> None")},
+	{"CGContextSetFlatness", (PyCFunction)CGContextRefObj_CGContextSetFlatness, 1,
+	 PyDoc_STR("(float flatness) -> None")},
+	{"CGContextSetAlpha", (PyCFunction)CGContextRefObj_CGContextSetAlpha, 1,
+	 PyDoc_STR("(float alpha) -> None")},
+	{"CGContextBeginPath", (PyCFunction)CGContextRefObj_CGContextBeginPath, 1,
+	 PyDoc_STR("() -> None")},
+	{"CGContextMoveToPoint", (PyCFunction)CGContextRefObj_CGContextMoveToPoint, 1,
+	 PyDoc_STR("(float x, float y) -> None")},
+	{"CGContextAddLineToPoint", (PyCFunction)CGContextRefObj_CGContextAddLineToPoint, 1,
+	 PyDoc_STR("(float x, float y) -> None")},
+	{"CGContextAddCurveToPoint", (PyCFunction)CGContextRefObj_CGContextAddCurveToPoint, 1,
+	 PyDoc_STR("(float cp1x, float cp1y, float cp2x, float cp2y, float x, float y) -> None")},
+	{"CGContextAddQuadCurveToPoint", (PyCFunction)CGContextRefObj_CGContextAddQuadCurveToPoint, 1,
+	 PyDoc_STR("(float cpx, float cpy, float x, float y) -> None")},
+	{"CGContextClosePath", (PyCFunction)CGContextRefObj_CGContextClosePath, 1,
+	 PyDoc_STR("() -> None")},
+	{"CGContextAddRect", (PyCFunction)CGContextRefObj_CGContextAddRect, 1,
+	 PyDoc_STR("(CGRect rect) -> None")},
+	{"CGContextAddArc", (PyCFunction)CGContextRefObj_CGContextAddArc, 1,
+	 PyDoc_STR("(float x, float y, float radius, float startAngle, float endAngle, int clockwise) -> None")},
+	{"CGContextAddArcToPoint", (PyCFunction)CGContextRefObj_CGContextAddArcToPoint, 1,
+	 PyDoc_STR("(float x1, float y1, float x2, float y2, float radius) -> None")},
+	{"CGContextIsPathEmpty", (PyCFunction)CGContextRefObj_CGContextIsPathEmpty, 1,
+	 PyDoc_STR("() -> (int _rv)")},
+	{"CGContextGetPathCurrentPoint", (PyCFunction)CGContextRefObj_CGContextGetPathCurrentPoint, 1,
+	 PyDoc_STR("() -> (CGPoint _rv)")},
+	{"CGContextGetPathBoundingBox", (PyCFunction)CGContextRefObj_CGContextGetPathBoundingBox, 1,
+	 PyDoc_STR("() -> (CGRect _rv)")},
+	{"CGContextDrawPath", (PyCFunction)CGContextRefObj_CGContextDrawPath, 1,
+	 PyDoc_STR("(int mode) -> None")},
+	{"CGContextFillPath", (PyCFunction)CGContextRefObj_CGContextFillPath, 1,
+	 PyDoc_STR("() -> None")},
+	{"CGContextEOFillPath", (PyCFunction)CGContextRefObj_CGContextEOFillPath, 1,
+	 PyDoc_STR("() -> None")},
+	{"CGContextStrokePath", (PyCFunction)CGContextRefObj_CGContextStrokePath, 1,
+	 PyDoc_STR("() -> None")},
+	{"CGContextFillRect", (PyCFunction)CGContextRefObj_CGContextFillRect, 1,
+	 PyDoc_STR("(CGRect rect) -> None")},
+	{"CGContextStrokeRect", (PyCFunction)CGContextRefObj_CGContextStrokeRect, 1,
+	 PyDoc_STR("(CGRect rect) -> None")},
+	{"CGContextStrokeRectWithWidth", (PyCFunction)CGContextRefObj_CGContextStrokeRectWithWidth, 1,
+	 PyDoc_STR("(CGRect rect, float width) -> None")},
+	{"CGContextClearRect", (PyCFunction)CGContextRefObj_CGContextClearRect, 1,
+	 PyDoc_STR("(CGRect rect) -> None")},
+	{"CGContextClip", (PyCFunction)CGContextRefObj_CGContextClip, 1,
+	 PyDoc_STR("() -> None")},
+	{"CGContextEOClip", (PyCFunction)CGContextRefObj_CGContextEOClip, 1,
+	 PyDoc_STR("() -> None")},
+	{"CGContextClipToRect", (PyCFunction)CGContextRefObj_CGContextClipToRect, 1,
+	 PyDoc_STR("(CGRect rect) -> None")},
+	{"CGContextSetGrayFillColor", (PyCFunction)CGContextRefObj_CGContextSetGrayFillColor, 1,
+	 PyDoc_STR("(float gray, float alpha) -> None")},
+	{"CGContextSetGrayStrokeColor", (PyCFunction)CGContextRefObj_CGContextSetGrayStrokeColor, 1,
+	 PyDoc_STR("(float gray, float alpha) -> None")},
+	{"CGContextSetRGBFillColor", (PyCFunction)CGContextRefObj_CGContextSetRGBFillColor, 1,
+	 PyDoc_STR("(float red, float green, float blue, float alpha) -> None")},
+	{"CGContextSetRGBStrokeColor", (PyCFunction)CGContextRefObj_CGContextSetRGBStrokeColor, 1,
+	 PyDoc_STR("(float red, float green, float blue, float alpha) -> None")},
+	{"CGContextSetCMYKFillColor", (PyCFunction)CGContextRefObj_CGContextSetCMYKFillColor, 1,
+	 PyDoc_STR("(float cyan, float magenta, float yellow, float black, float alpha) -> None")},
+	{"CGContextSetCMYKStrokeColor", (PyCFunction)CGContextRefObj_CGContextSetCMYKStrokeColor, 1,
+	 PyDoc_STR("(float cyan, float magenta, float yellow, float black, float alpha) -> None")},
+	{"CGContextGetInterpolationQuality", (PyCFunction)CGContextRefObj_CGContextGetInterpolationQuality, 1,
+	 PyDoc_STR("() -> (int _rv)")},
+	{"CGContextSetInterpolationQuality", (PyCFunction)CGContextRefObj_CGContextSetInterpolationQuality, 1,
+	 PyDoc_STR("(int quality) -> None")},
+	{"CGContextSetCharacterSpacing", (PyCFunction)CGContextRefObj_CGContextSetCharacterSpacing, 1,
+	 PyDoc_STR("(float spacing) -> None")},
+	{"CGContextSetTextPosition", (PyCFunction)CGContextRefObj_CGContextSetTextPosition, 1,
+	 PyDoc_STR("(float x, float y) -> None")},
+	{"CGContextGetTextPosition", (PyCFunction)CGContextRefObj_CGContextGetTextPosition, 1,
+	 PyDoc_STR("() -> (CGPoint _rv)")},
+	{"CGContextSetTextMatrix", (PyCFunction)CGContextRefObj_CGContextSetTextMatrix, 1,
+	 PyDoc_STR("(CGAffineTransform transform) -> None")},
+	{"CGContextGetTextMatrix", (PyCFunction)CGContextRefObj_CGContextGetTextMatrix, 1,
+	 PyDoc_STR("() -> (CGAffineTransform _rv)")},
+	{"CGContextSetTextDrawingMode", (PyCFunction)CGContextRefObj_CGContextSetTextDrawingMode, 1,
+	 PyDoc_STR("(int mode) -> None")},
+	{"CGContextSetFontSize", (PyCFunction)CGContextRefObj_CGContextSetFontSize, 1,
+	 PyDoc_STR("(float size) -> None")},
+	{"CGContextSelectFont", (PyCFunction)CGContextRefObj_CGContextSelectFont, 1,
+	 PyDoc_STR("(char * name, float size, int textEncoding) -> None")},
+	{"CGContextShowText", (PyCFunction)CGContextRefObj_CGContextShowText, 1,
+	 PyDoc_STR("(Buffer cstring) -> None")},
+	{"CGContextShowTextAtPoint", (PyCFunction)CGContextRefObj_CGContextShowTextAtPoint, 1,
+	 PyDoc_STR("(float x, float y, Buffer cstring) -> None")},
+	{"CGContextEndPage", (PyCFunction)CGContextRefObj_CGContextEndPage, 1,
+	 PyDoc_STR("() -> None")},
+	{"CGContextFlush", (PyCFunction)CGContextRefObj_CGContextFlush, 1,
+	 PyDoc_STR("() -> None")},
+	{"CGContextSynchronize", (PyCFunction)CGContextRefObj_CGContextSynchronize, 1,
+	 PyDoc_STR("() -> None")},
+	{"CGContextSetShouldAntialias", (PyCFunction)CGContextRefObj_CGContextSetShouldAntialias, 1,
+	 PyDoc_STR("(int shouldAntialias) -> None")},
+	{"SyncCGContextOriginWithPort", (PyCFunction)CGContextRefObj_SyncCGContextOriginWithPort, 1,
+	 PyDoc_STR("(CGrafPtr port) -> None")},
+	{"ClipCGContextToRegion", (PyCFunction)CGContextRefObj_ClipCGContextToRegion, 1,
+	 PyDoc_STR("(Rect portRect, RgnHandle region) -> None")},
+	{NULL, NULL, 0}
+};
+
+#define CGContextRefObj_getsetlist NULL
+
+
+#define CGContextRefObj_compare NULL
+
+#define CGContextRefObj_repr NULL
+
+#define CGContextRefObj_hash NULL
+#define CGContextRefObj_tp_init 0
+
+#define CGContextRefObj_tp_alloc PyType_GenericAlloc
+
+static PyObject *CGContextRefObj_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *_self;
+	CGContextRef itself;
+	char *kw[] = {"itself", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, CGContextRefObj_Convert, &itself)) return NULL;
+	if ((_self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	((CGContextRefObject *)_self)->ob_itself = itself;
+	return _self;
+}
+
+#define CGContextRefObj_tp_free PyObject_Del
+
+
+PyTypeObject CGContextRef_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"_CG.CGContextRef", /*tp_name*/
+	sizeof(CGContextRefObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) CGContextRefObj_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) CGContextRefObj_compare, /*tp_compare*/
+	(reprfunc) CGContextRefObj_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) CGContextRefObj_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	CGContextRefObj_methods, /* tp_methods */
+	0, /*tp_members*/
+	CGContextRefObj_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	CGContextRefObj_tp_init, /* tp_init */
+	CGContextRefObj_tp_alloc, /* tp_alloc */
+	CGContextRefObj_tp_new, /* tp_new */
+	CGContextRefObj_tp_free, /* tp_free */
+};
+
+/* ------------------ End object type CGContextRef ------------------ */
+
+
+static PyObject *CG_CreateCGContextForPort(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	GrafPtr port;
+	CGContextRef ctx;
+	OSStatus _err;
+
+	if (!PyArg_ParseTuple(_args, "O&", GrafObj_Convert, &port))
+	        return NULL;
+
+	_err = CreateCGContextForPort(port, &ctx);
+	if (_err != noErr)
+	        if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&", CGContextRefObj_New, ctx);
+	return _res;
+
+}
+
+static PyMethodDef CG_methods[] = {
+	{"CreateCGContextForPort", (PyCFunction)CG_CreateCGContextForPort, 1,
+	 PyDoc_STR("(CGrafPtr) -> CGContextRef")},
+	{NULL, NULL, 0}
+};
+
+
+
+
+void init_CG(void)
+{
+	PyObject *m;
+	PyObject *d;
+
+
+
+
+	m = Py_InitModule("_CG", CG_methods);
+	d = PyModule_GetDict(m);
+	CG_Error = PyMac_GetOSErrException();
+	if (CG_Error == NULL ||
+	    PyDict_SetItemString(d, "Error", CG_Error) != 0)
+		return;
+	CGContextRef_Type.ob_type = &PyType_Type;
+	if (PyType_Ready(&CGContextRef_Type) < 0) return;
+	Py_INCREF(&CGContextRef_Type);
+	PyModule_AddObject(m, "CGContextRef", (PyObject *)&CGContextRef_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&CGContextRef_Type);
+	PyModule_AddObject(m, "CGContextRefType", (PyObject *)&CGContextRef_Type);
+}
+
+/* ========================= End module _CG ========================= */
+


Property changes on: vendor/Python/current/Mac/Modules/cg/_CGmodule.c
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Mac/Modules/cg/cgscan.py
===================================================================
--- vendor/Python/current/Mac/Modules/cg/cgscan.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/cg/cgscan.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,84 @@
+# Scan an Apple header file, generating a Python file of generator calls.
+
+import sys
+import os
+from bgenlocations import TOOLBOXDIR, BGENDIR
+sys.path.append(BGENDIR)
+from scantools import Scanner_OSX
+
+LONG = "CoreGraphics"
+SHORT = "cg"
+OBJECTS = ("CGContextRef",
+                )
+# ADD object typenames here
+
+def main():
+    input = [
+            "CGContext.h",
+    ]
+    output = SHORT + "gen.py"
+    defsoutput = TOOLBOXDIR + LONG + ".py"
+    scanner = MyScanner(input, output, defsoutput)
+    scanner.scan()
+    scanner.gentypetest(SHORT+"typetest.py")
+    scanner.close()
+    print "=== Testing definitions output code ==="
+    execfile(defsoutput, {}, {})
+    print "=== Done scanning and generating, now importing the generated code... ==="
+    exec "import " + SHORT + "support"
+    print "=== Done.  It's up to you to compile it now! ==="
+
+class MyScanner(Scanner_OSX):
+
+    def destination(self, type, name, arglist):
+        classname = "Function"
+        listname = "functions"
+        if arglist:
+            t, n, m = arglist[0]
+            if t in OBJECTS and m == "InMode":
+                classname = "Method"
+                listname = t + "_methods"
+            # Special case for the silly first AllocatorRef argument
+            if t == 'CFAllocatorRef' and m == 'InMode' and len(arglist) > 1:
+                t, n, m = arglist[1]
+                if t in OBJECTS and m == "InMode":
+                    classname = "MethodSkipArg1"
+                    listname = t + "_methods"
+        return classname, listname
+
+    def writeinitialdefs(self):
+        self.defsfile.write("def FOUR_CHAR_CODE(x): return x\n")
+
+    def makeblacklistnames(self):
+        return [
+                "CGContextRetain",
+                "CGContextRelease",
+                ]
+
+    def makegreylist(self):
+        return []
+
+    def makeblacklisttypes(self):
+        return [
+                "float_ptr",
+                "CGRect_ptr",
+                "CGPoint_ptr",
+                "CGColorSpaceRef",
+                "CGColorRenderingIntent",
+                "CGFontRef",
+#                       "char_ptr",
+                "CGGlyph_ptr",
+                "CGImageRef",
+                "CGPDFDocumentRef",
+                ]
+
+    def makerepairinstructions(self):
+        return [
+                ([("char_ptr", "cstring", "InMode"), ("size_t", "length", "InMode")],
+                 [("InBuffer", "*", "*")]),
+#                       ([("char_ptr", "name", "InMode"),],
+#                        [("CCCCC", "*", "*")]),
+                ]
+
+if __name__ == "__main__":
+    main()


Property changes on: vendor/Python/current/Mac/Modules/cg/cgscan.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Mac/Modules/cg/cgsupport.py
===================================================================
--- vendor/Python/current/Mac/Modules/cg/cgsupport.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/cg/cgsupport.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,192 @@
+# This script generates a Python interface for an Apple Macintosh Manager.
+# It uses the "bgen" package to generate C code.
+# The function specifications are generated by scanning the mamager's header file,
+# using the "scantools" package (customized for this particular manager).
+
+#error missing SetActionFilter
+
+import string
+
+# Declarations that change for each manager
+MODNAME = '_CG'                         # The name of the module
+
+# The following is *usually* unchanged but may still require tuning
+MODPREFIX = 'CG'                        # The prefix for module-wide routines
+INPUTFILE = string.lower(MODPREFIX) + 'gen.py' # The file generated by the scanner
+OUTPUTFILE = MODNAME + "module.c"       # The file generated by this program
+
+from macsupport import *
+
+CGrafPtr = OpaqueByValueType("CGrafPtr", "GrafObj")
+RgnHandle = OpaqueByValueType("RgnHandle", "ResObj")
+
+# Create the type objects
+
+includestuff = includestuff + """
+#include <ApplicationServices/ApplicationServices.h>
+
+extern int GrafObj_Convert(PyObject *, GrafPtr *);
+
+/*
+** Manual converters
+*/
+
+PyObject *CGPoint_New(CGPoint *itself)
+{
+
+        return Py_BuildValue("(ff)",
+                        itself->x,
+                        itself->y);
+}
+
+int
+CGPoint_Convert(PyObject *v, CGPoint *p_itself)
+{
+        if( !PyArg_Parse(v, "(ff)",
+                        &p_itself->x,
+                        &p_itself->y) )
+                return 0;
+        return 1;
+}
+
+PyObject *CGRect_New(CGRect *itself)
+{
+
+        return Py_BuildValue("(ffff)",
+                        itself->origin.x,
+                        itself->origin.y,
+                        itself->size.width,
+                        itself->size.height);
+}
+
+int
+CGRect_Convert(PyObject *v, CGRect *p_itself)
+{
+        if( !PyArg_Parse(v, "(ffff)",
+                        &p_itself->origin.x,
+                        &p_itself->origin.y,
+                        &p_itself->size.width,
+                        &p_itself->size.height) )
+                return 0;
+        return 1;
+}
+
+PyObject *CGAffineTransform_New(CGAffineTransform *itself)
+{
+
+        return Py_BuildValue("(ffffff)",
+                        itself->a,
+                        itself->b,
+                        itself->c,
+                        itself->d,
+                        itself->tx,
+                        itself->ty);
+}
+
+int
+CGAffineTransform_Convert(PyObject *v, CGAffineTransform *p_itself)
+{
+        if( !PyArg_Parse(v, "(ffffff)",
+                        &p_itself->a,
+                        &p_itself->b,
+                        &p_itself->c,
+                        &p_itself->d,
+                        &p_itself->tx,
+                        &p_itself->ty) )
+                return 0;
+        return 1;
+}
+"""
+
+class MyOpaqueByValueType(OpaqueByValueType):
+    """Sort of a mix between OpaqueByValueType and OpaqueType."""
+    def mkvalueArgs(self, name):
+        return "%s, &%s" % (self.new, name)
+
+CGPoint = MyOpaqueByValueType('CGPoint', 'CGPoint')
+CGRect = MyOpaqueByValueType('CGRect', 'CGRect')
+CGAffineTransform = MyOpaqueByValueType('CGAffineTransform', 'CGAffineTransform')
+
+char_ptr = Type("char *", "s")
+
+CGTextEncoding = int
+CGLineCap = int
+CGLineJoin = int
+CGTextDrawingMode = int
+CGPathDrawingMode = int
+CGInterpolationQuality = int
+
+# The real objects
+CGContextRef = OpaqueByValueType("CGContextRef", "CGContextRefObj")
+
+
+class MyObjectDefinition(PEP253Mixin, GlobalObjectDefinition):
+    def outputStructMembers(self):
+        ObjectDefinition.outputStructMembers(self)
+    def outputCleanupStructMembers(self):
+        Output("CGContextRelease(self->ob_itself);")
+
+
+# Create the generator groups and link them
+module = MacModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff)
+
+CGContextRef_object = MyObjectDefinition('CGContextRef', 'CGContextRefObj', 'CGContextRef')
+
+
+# ADD object here
+
+module.addobject(CGContextRef_object)
+
+
+
+Function = FunctionGenerator
+Method = MethodGenerator
+
+CGContextRef_methods = []
+
+# ADD _methods initializer here
+execfile(INPUTFILE)
+
+# manual method, lives in Quickdraw.h
+f = Method(void, 'SyncCGContextOriginWithPort',
+    (CGContextRef, 'ctx', InMode),
+    (CGrafPtr, 'port', InMode),
+)
+CGContextRef_methods.append(f)
+
+# manual method, lives in Quickdraw.h
+f = Method(void, 'ClipCGContextToRegion',
+    (CGContextRef, 'ctx', InMode),
+    (Rect, 'portRect', InMode),
+    (RgnHandle, 'region', InMode),
+)
+CGContextRef_methods.append(f)
+
+
+CreateCGContextForPort_body = """\
+GrafPtr port;
+CGContextRef ctx;
+OSStatus _err;
+
+if (!PyArg_ParseTuple(_args, "O&", GrafObj_Convert, &port))
+        return NULL;
+
+_err = CreateCGContextForPort(port, &ctx);
+if (_err != noErr)
+        if (_err != noErr) return PyMac_Error(_err);
+_res = Py_BuildValue("O&", CGContextRefObj_New, ctx);
+return _res;
+"""
+
+f = ManualGenerator("CreateCGContextForPort", CreateCGContextForPort_body);
+f.docstring = lambda: "(CGrafPtr) -> CGContextRef"
+module.add(f)
+
+
+# ADD add forloop here
+for f in CGContextRef_methods:
+    CGContextRef_object.add(f)
+
+# generate output (open the output file as late as possible)
+SetOutputFileName(OUTPUTFILE)
+module.generate()


Property changes on: vendor/Python/current/Mac/Modules/cg/cgsupport.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Mac/Modules/cm/_Cmmodule.c
===================================================================
--- vendor/Python/current/Mac/Modules/cm/_Cmmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/cm/_Cmmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,947 @@
+
+/* =========================== Module _Cm =========================== */
+
+#include "Python.h"
+
+
+
+#include "pymactoolbox.h"
+
+/* Macro to test whether a weak-loaded CFM function exists */
+#define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL )  {\
+        PyErr_SetString(PyExc_NotImplementedError, \
+        "Not available in this shared library/OS version"); \
+        return NULL; \
+    }} while(0)
+
+
+#include <Carbon/Carbon.h>
+
+#ifdef USE_TOOLBOX_OBJECT_GLUE
+extern PyObject *_CmpObj_New(Component);
+extern int _CmpObj_Convert(PyObject *, Component *);
+extern PyObject *_CmpInstObj_New(ComponentInstance);
+extern int _CmpInstObj_Convert(PyObject *, ComponentInstance *);
+
+#define CmpObj_New _CmpObj_New
+#define CmpObj_Convert _CmpObj_Convert
+#define CmpInstObj_New _CmpInstObj_New
+#define CmpInstObj_Convert _CmpInstObj_Convert
+#endif
+
+/*
+** Parse/generate ComponentDescriptor records
+*/
+static PyObject *
+CmpDesc_New(ComponentDescription *itself)
+{
+
+        return Py_BuildValue("O&O&O&ll",
+                PyMac_BuildOSType, itself->componentType,
+                PyMac_BuildOSType, itself->componentSubType,
+                PyMac_BuildOSType, itself->componentManufacturer,
+                itself->componentFlags, itself->componentFlagsMask);
+}
+
+static int
+CmpDesc_Convert(PyObject *v, ComponentDescription *p_itself)
+{
+        return PyArg_ParseTuple(v, "O&O&O&ll",
+                PyMac_GetOSType, &p_itself->componentType,
+                PyMac_GetOSType, &p_itself->componentSubType,
+                PyMac_GetOSType, &p_itself->componentManufacturer,
+                &p_itself->componentFlags, &p_itself->componentFlagsMask);
+}
+
+
+static PyObject *Cm_Error;
+
+/* ----------------- Object type ComponentInstance ------------------ */
+
+PyTypeObject ComponentInstance_Type;
+
+#define CmpInstObj_Check(x) ((x)->ob_type == &ComponentInstance_Type || PyObject_TypeCheck((x), &ComponentInstance_Type))
+
+typedef struct ComponentInstanceObject {
+	PyObject_HEAD
+	ComponentInstance ob_itself;
+} ComponentInstanceObject;
+
+PyObject *CmpInstObj_New(ComponentInstance itself)
+{
+	ComponentInstanceObject *it;
+	if (itself == NULL) {
+	                                PyErr_SetString(Cm_Error,"NULL ComponentInstance");
+	                                return NULL;
+	                        }
+	it = PyObject_NEW(ComponentInstanceObject, &ComponentInstance_Type);
+	if (it == NULL) return NULL;
+	it->ob_itself = itself;
+	return (PyObject *)it;
+}
+
+int CmpInstObj_Convert(PyObject *v, ComponentInstance *p_itself)
+{
+	if (!CmpInstObj_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "ComponentInstance required");
+		return 0;
+	}
+	*p_itself = ((ComponentInstanceObject *)v)->ob_itself;
+	return 1;
+}
+
+static void CmpInstObj_dealloc(ComponentInstanceObject *self)
+{
+	/* Cleanup of self->ob_itself goes here */
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *CmpInstObj_CloseComponent(ComponentInstanceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+#ifndef CloseComponent
+	PyMac_PRECHECK(CloseComponent);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = CloseComponent(_self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CmpInstObj_GetComponentInstanceError(ComponentInstanceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+#ifndef GetComponentInstanceError
+	PyMac_PRECHECK(GetComponentInstanceError);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetComponentInstanceError(_self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CmpInstObj_SetComponentInstanceError(ComponentInstanceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr theError;
+#ifndef SetComponentInstanceError
+	PyMac_PRECHECK(SetComponentInstanceError);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &theError))
+		return NULL;
+	SetComponentInstanceError(_self->ob_itself,
+	                          theError);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CmpInstObj_GetComponentInstanceStorage(ComponentInstanceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Handle _rv;
+#ifndef GetComponentInstanceStorage
+	PyMac_PRECHECK(GetComponentInstanceStorage);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetComponentInstanceStorage(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CmpInstObj_SetComponentInstanceStorage(ComponentInstanceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Handle theStorage;
+#ifndef SetComponentInstanceStorage
+	PyMac_PRECHECK(SetComponentInstanceStorage);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &theStorage))
+		return NULL;
+	SetComponentInstanceStorage(_self->ob_itself,
+	                            theStorage);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CmpInstObj_ComponentFunctionImplemented(ComponentInstanceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long _rv;
+	short ftnNumber;
+#ifndef ComponentFunctionImplemented
+	PyMac_PRECHECK(ComponentFunctionImplemented);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &ftnNumber))
+		return NULL;
+	_rv = ComponentFunctionImplemented(_self->ob_itself,
+	                                   ftnNumber);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CmpInstObj_GetComponentVersion(ComponentInstanceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long _rv;
+#ifndef GetComponentVersion
+	PyMac_PRECHECK(GetComponentVersion);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetComponentVersion(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CmpInstObj_ComponentSetTarget(ComponentInstanceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long _rv;
+	ComponentInstance target;
+#ifndef ComponentSetTarget
+	PyMac_PRECHECK(ComponentSetTarget);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &target))
+		return NULL;
+	_rv = ComponentSetTarget(_self->ob_itself,
+	                         target);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyMethodDef CmpInstObj_methods[] = {
+	{"CloseComponent", (PyCFunction)CmpInstObj_CloseComponent, 1,
+	 PyDoc_STR("() -> None")},
+	{"GetComponentInstanceError", (PyCFunction)CmpInstObj_GetComponentInstanceError, 1,
+	 PyDoc_STR("() -> None")},
+	{"SetComponentInstanceError", (PyCFunction)CmpInstObj_SetComponentInstanceError, 1,
+	 PyDoc_STR("(OSErr theError) -> None")},
+	{"GetComponentInstanceStorage", (PyCFunction)CmpInstObj_GetComponentInstanceStorage, 1,
+	 PyDoc_STR("() -> (Handle _rv)")},
+	{"SetComponentInstanceStorage", (PyCFunction)CmpInstObj_SetComponentInstanceStorage, 1,
+	 PyDoc_STR("(Handle theStorage) -> None")},
+	{"ComponentFunctionImplemented", (PyCFunction)CmpInstObj_ComponentFunctionImplemented, 1,
+	 PyDoc_STR("(short ftnNumber) -> (long _rv)")},
+	{"GetComponentVersion", (PyCFunction)CmpInstObj_GetComponentVersion, 1,
+	 PyDoc_STR("() -> (long _rv)")},
+	{"ComponentSetTarget", (PyCFunction)CmpInstObj_ComponentSetTarget, 1,
+	 PyDoc_STR("(ComponentInstance target) -> (long _rv)")},
+	{NULL, NULL, 0}
+};
+
+#define CmpInstObj_getsetlist NULL
+
+
+#define CmpInstObj_compare NULL
+
+#define CmpInstObj_repr NULL
+
+#define CmpInstObj_hash NULL
+#define CmpInstObj_tp_init 0
+
+#define CmpInstObj_tp_alloc PyType_GenericAlloc
+
+static PyObject *CmpInstObj_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *_self;
+	ComponentInstance itself;
+	char *kw[] = {"itself", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, CmpInstObj_Convert, &itself)) return NULL;
+	if ((_self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	((ComponentInstanceObject *)_self)->ob_itself = itself;
+	return _self;
+}
+
+#define CmpInstObj_tp_free PyObject_Del
+
+
+PyTypeObject ComponentInstance_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"_Cm.ComponentInstance", /*tp_name*/
+	sizeof(ComponentInstanceObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) CmpInstObj_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) CmpInstObj_compare, /*tp_compare*/
+	(reprfunc) CmpInstObj_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) CmpInstObj_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	CmpInstObj_methods, /* tp_methods */
+	0, /*tp_members*/
+	CmpInstObj_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	CmpInstObj_tp_init, /* tp_init */
+	CmpInstObj_tp_alloc, /* tp_alloc */
+	CmpInstObj_tp_new, /* tp_new */
+	CmpInstObj_tp_free, /* tp_free */
+};
+
+/* --------------- End object type ComponentInstance ---------------- */
+
+
+/* --------------------- Object type Component ---------------------- */
+
+PyTypeObject Component_Type;
+
+#define CmpObj_Check(x) ((x)->ob_type == &Component_Type || PyObject_TypeCheck((x), &Component_Type))
+
+typedef struct ComponentObject {
+	PyObject_HEAD
+	Component ob_itself;
+} ComponentObject;
+
+PyObject *CmpObj_New(Component itself)
+{
+	ComponentObject *it;
+	if (itself == NULL) {
+	                                /* XXXX Or should we return None? */
+	                                PyErr_SetString(Cm_Error,"No such component");
+	                                return NULL;
+	                        }
+	it = PyObject_NEW(ComponentObject, &Component_Type);
+	if (it == NULL) return NULL;
+	it->ob_itself = itself;
+	return (PyObject *)it;
+}
+
+int CmpObj_Convert(PyObject *v, Component *p_itself)
+{
+	if ( v == Py_None ) {
+	                                *p_itself = 0;
+	                                return 1;
+	        }
+	if (!CmpObj_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "Component required");
+		return 0;
+	}
+	*p_itself = ((ComponentObject *)v)->ob_itself;
+	return 1;
+}
+
+static void CmpObj_dealloc(ComponentObject *self)
+{
+	/* Cleanup of self->ob_itself goes here */
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *CmpObj_UnregisterComponent(ComponentObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+#ifndef UnregisterComponent
+	PyMac_PRECHECK(UnregisterComponent);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = UnregisterComponent(_self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CmpObj_GetComponentInfo(ComponentObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	ComponentDescription cd;
+	Handle componentName;
+	Handle componentInfo;
+	Handle componentIcon;
+#ifndef GetComponentInfo
+	PyMac_PRECHECK(GetComponentInfo);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      ResObj_Convert, &componentName,
+	                      ResObj_Convert, &componentInfo,
+	                      ResObj_Convert, &componentIcon))
+		return NULL;
+	_err = GetComponentInfo(_self->ob_itself,
+	                        &cd,
+	                        componentName,
+	                        componentInfo,
+	                        componentIcon);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CmpDesc_New, &cd);
+	return _res;
+}
+
+static PyObject *CmpObj_OpenComponent(ComponentObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentInstance _rv;
+#ifndef OpenComponent
+	PyMac_PRECHECK(OpenComponent);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = OpenComponent(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     CmpInstObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CmpObj_ResolveComponentAlias(ComponentObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Component _rv;
+#ifndef ResolveComponentAlias
+	PyMac_PRECHECK(ResolveComponentAlias);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = ResolveComponentAlias(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     CmpObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CmpObj_GetComponentPublicIndString(ComponentObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Str255 theString;
+	short strListID;
+	short index;
+#ifndef GetComponentPublicIndString
+	PyMac_PRECHECK(GetComponentPublicIndString);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hh",
+	                      PyMac_GetStr255, theString,
+	                      &strListID,
+	                      &index))
+		return NULL;
+	_err = GetComponentPublicIndString(_self->ob_itself,
+	                                   theString,
+	                                   strListID,
+	                                   index);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CmpObj_GetComponentRefcon(ComponentObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long _rv;
+#ifndef GetComponentRefcon
+	PyMac_PRECHECK(GetComponentRefcon);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetComponentRefcon(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CmpObj_SetComponentRefcon(ComponentObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long theRefcon;
+#ifndef SetComponentRefcon
+	PyMac_PRECHECK(SetComponentRefcon);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &theRefcon))
+		return NULL;
+	SetComponentRefcon(_self->ob_itself,
+	                   theRefcon);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CmpObj_OpenComponentResFile(ComponentObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short _rv;
+#ifndef OpenComponentResFile
+	PyMac_PRECHECK(OpenComponentResFile);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = OpenComponentResFile(_self->ob_itself);
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CmpObj_GetComponentResource(ComponentObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	OSType resType;
+	short resID;
+	Handle theResource;
+#ifndef GetComponentResource
+	PyMac_PRECHECK(GetComponentResource);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      PyMac_GetOSType, &resType,
+	                      &resID))
+		return NULL;
+	_err = GetComponentResource(_self->ob_itself,
+	                            resType,
+	                            resID,
+	                            &theResource);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, theResource);
+	return _res;
+}
+
+static PyObject *CmpObj_GetComponentIndString(ComponentObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Str255 theString;
+	short strListID;
+	short index;
+#ifndef GetComponentIndString
+	PyMac_PRECHECK(GetComponentIndString);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hh",
+	                      PyMac_GetStr255, theString,
+	                      &strListID,
+	                      &index))
+		return NULL;
+	_err = GetComponentIndString(_self->ob_itself,
+	                             theString,
+	                             strListID,
+	                             index);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CmpObj_CountComponentInstances(ComponentObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long _rv;
+#ifndef CountComponentInstances
+	PyMac_PRECHECK(CountComponentInstances);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CountComponentInstances(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CmpObj_SetDefaultComponent(ComponentObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short flags;
+#ifndef SetDefaultComponent
+	PyMac_PRECHECK(SetDefaultComponent);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &flags))
+		return NULL;
+	_err = SetDefaultComponent(_self->ob_itself,
+	                           flags);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CmpObj_CaptureComponent(ComponentObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Component _rv;
+	Component capturingComponent;
+#ifndef CaptureComponent
+	PyMac_PRECHECK(CaptureComponent);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &capturingComponent))
+		return NULL;
+	_rv = CaptureComponent(_self->ob_itself,
+	                       capturingComponent);
+	_res = Py_BuildValue("O&",
+	                     CmpObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CmpObj_UncaptureComponent(ComponentObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+#ifndef UncaptureComponent
+	PyMac_PRECHECK(UncaptureComponent);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = UncaptureComponent(_self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CmpObj_GetComponentIconSuite(ComponentObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Handle iconSuite;
+#ifndef GetComponentIconSuite
+	PyMac_PRECHECK(GetComponentIconSuite);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetComponentIconSuite(_self->ob_itself,
+	                             &iconSuite);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, iconSuite);
+	return _res;
+}
+
+static PyMethodDef CmpObj_methods[] = {
+	{"UnregisterComponent", (PyCFunction)CmpObj_UnregisterComponent, 1,
+	 PyDoc_STR("() -> None")},
+	{"GetComponentInfo", (PyCFunction)CmpObj_GetComponentInfo, 1,
+	 PyDoc_STR("(Handle componentName, Handle componentInfo, Handle componentIcon) -> (ComponentDescription cd)")},
+	{"OpenComponent", (PyCFunction)CmpObj_OpenComponent, 1,
+	 PyDoc_STR("() -> (ComponentInstance _rv)")},
+	{"ResolveComponentAlias", (PyCFunction)CmpObj_ResolveComponentAlias, 1,
+	 PyDoc_STR("() -> (Component _rv)")},
+	{"GetComponentPublicIndString", (PyCFunction)CmpObj_GetComponentPublicIndString, 1,
+	 PyDoc_STR("(Str255 theString, short strListID, short index) -> None")},
+	{"GetComponentRefcon", (PyCFunction)CmpObj_GetComponentRefcon, 1,
+	 PyDoc_STR("() -> (long _rv)")},
+	{"SetComponentRefcon", (PyCFunction)CmpObj_SetComponentRefcon, 1,
+	 PyDoc_STR("(long theRefcon) -> None")},
+	{"OpenComponentResFile", (PyCFunction)CmpObj_OpenComponentResFile, 1,
+	 PyDoc_STR("() -> (short _rv)")},
+	{"GetComponentResource", (PyCFunction)CmpObj_GetComponentResource, 1,
+	 PyDoc_STR("(OSType resType, short resID) -> (Handle theResource)")},
+	{"GetComponentIndString", (PyCFunction)CmpObj_GetComponentIndString, 1,
+	 PyDoc_STR("(Str255 theString, short strListID, short index) -> None")},
+	{"CountComponentInstances", (PyCFunction)CmpObj_CountComponentInstances, 1,
+	 PyDoc_STR("() -> (long _rv)")},
+	{"SetDefaultComponent", (PyCFunction)CmpObj_SetDefaultComponent, 1,
+	 PyDoc_STR("(short flags) -> None")},
+	{"CaptureComponent", (PyCFunction)CmpObj_CaptureComponent, 1,
+	 PyDoc_STR("(Component capturingComponent) -> (Component _rv)")},
+	{"UncaptureComponent", (PyCFunction)CmpObj_UncaptureComponent, 1,
+	 PyDoc_STR("() -> None")},
+	{"GetComponentIconSuite", (PyCFunction)CmpObj_GetComponentIconSuite, 1,
+	 PyDoc_STR("() -> (Handle iconSuite)")},
+	{NULL, NULL, 0}
+};
+
+#define CmpObj_getsetlist NULL
+
+
+#define CmpObj_compare NULL
+
+#define CmpObj_repr NULL
+
+#define CmpObj_hash NULL
+#define CmpObj_tp_init 0
+
+#define CmpObj_tp_alloc PyType_GenericAlloc
+
+static PyObject *CmpObj_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *_self;
+	Component itself;
+	char *kw[] = {"itself", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, CmpObj_Convert, &itself)) return NULL;
+	if ((_self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	((ComponentObject *)_self)->ob_itself = itself;
+	return _self;
+}
+
+#define CmpObj_tp_free PyObject_Del
+
+
+PyTypeObject Component_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"_Cm.Component", /*tp_name*/
+	sizeof(ComponentObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) CmpObj_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) CmpObj_compare, /*tp_compare*/
+	(reprfunc) CmpObj_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) CmpObj_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	CmpObj_methods, /* tp_methods */
+	0, /*tp_members*/
+	CmpObj_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	CmpObj_tp_init, /* tp_init */
+	CmpObj_tp_alloc, /* tp_alloc */
+	CmpObj_tp_new, /* tp_new */
+	CmpObj_tp_free, /* tp_free */
+};
+
+/* ------------------- End object type Component -------------------- */
+
+
+static PyObject *Cm_RegisterComponentResource(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Component _rv;
+	ComponentResourceHandle cr;
+	short global;
+#ifndef RegisterComponentResource
+	PyMac_PRECHECK(RegisterComponentResource);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      ResObj_Convert, &cr,
+	                      &global))
+		return NULL;
+	_rv = RegisterComponentResource(cr,
+	                                global);
+	_res = Py_BuildValue("O&",
+	                     CmpObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Cm_FindNextComponent(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Component _rv;
+	Component aComponent;
+	ComponentDescription looking;
+#ifndef FindNextComponent
+	PyMac_PRECHECK(FindNextComponent);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &aComponent,
+	                      CmpDesc_Convert, &looking))
+		return NULL;
+	_rv = FindNextComponent(aComponent,
+	                        &looking);
+	_res = Py_BuildValue("O&",
+	                     CmpObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Cm_CountComponents(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long _rv;
+	ComponentDescription looking;
+#ifndef CountComponents
+	PyMac_PRECHECK(CountComponents);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpDesc_Convert, &looking))
+		return NULL;
+	_rv = CountComponents(&looking);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Cm_GetComponentListModSeed(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long _rv;
+#ifndef GetComponentListModSeed
+	PyMac_PRECHECK(GetComponentListModSeed);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetComponentListModSeed();
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Cm_CloseComponentResFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short refnum;
+#ifndef CloseComponentResFile
+	PyMac_PRECHECK(CloseComponentResFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &refnum))
+		return NULL;
+	_err = CloseComponentResFile(refnum);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Cm_OpenDefaultComponent(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentInstance _rv;
+	OSType componentType;
+	OSType componentSubType;
+#ifndef OpenDefaultComponent
+	PyMac_PRECHECK(OpenDefaultComponent);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetOSType, &componentType,
+	                      PyMac_GetOSType, &componentSubType))
+		return NULL;
+	_rv = OpenDefaultComponent(componentType,
+	                           componentSubType);
+	_res = Py_BuildValue("O&",
+	                     CmpInstObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Cm_RegisterComponentResourceFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long _rv;
+	short resRefNum;
+	short global;
+#ifndef RegisterComponentResourceFile
+	PyMac_PRECHECK(RegisterComponentResourceFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "hh",
+	                      &resRefNum,
+	                      &global))
+		return NULL;
+	_rv = RegisterComponentResourceFile(resRefNum,
+	                                    global);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyMethodDef Cm_methods[] = {
+	{"RegisterComponentResource", (PyCFunction)Cm_RegisterComponentResource, 1,
+	 PyDoc_STR("(ComponentResourceHandle cr, short global) -> (Component _rv)")},
+	{"FindNextComponent", (PyCFunction)Cm_FindNextComponent, 1,
+	 PyDoc_STR("(Component aComponent, ComponentDescription looking) -> (Component _rv)")},
+	{"CountComponents", (PyCFunction)Cm_CountComponents, 1,
+	 PyDoc_STR("(ComponentDescription looking) -> (long _rv)")},
+	{"GetComponentListModSeed", (PyCFunction)Cm_GetComponentListModSeed, 1,
+	 PyDoc_STR("() -> (long _rv)")},
+	{"CloseComponentResFile", (PyCFunction)Cm_CloseComponentResFile, 1,
+	 PyDoc_STR("(short refnum) -> None")},
+	{"OpenDefaultComponent", (PyCFunction)Cm_OpenDefaultComponent, 1,
+	 PyDoc_STR("(OSType componentType, OSType componentSubType) -> (ComponentInstance _rv)")},
+	{"RegisterComponentResourceFile", (PyCFunction)Cm_RegisterComponentResourceFile, 1,
+	 PyDoc_STR("(short resRefNum, short global) -> (long _rv)")},
+	{NULL, NULL, 0}
+};
+
+
+
+
+void init_Cm(void)
+{
+	PyObject *m;
+	PyObject *d;
+
+
+
+	        PyMac_INIT_TOOLBOX_OBJECT_NEW(Component, CmpObj_New);
+	        PyMac_INIT_TOOLBOX_OBJECT_CONVERT(Component, CmpObj_Convert);
+	        PyMac_INIT_TOOLBOX_OBJECT_NEW(ComponentInstance, CmpInstObj_New);
+	        PyMac_INIT_TOOLBOX_OBJECT_CONVERT(ComponentInstance, CmpInstObj_Convert);
+
+
+	m = Py_InitModule("_Cm", Cm_methods);
+	d = PyModule_GetDict(m);
+	Cm_Error = PyMac_GetOSErrException();
+	if (Cm_Error == NULL ||
+	    PyDict_SetItemString(d, "Error", Cm_Error) != 0)
+		return;
+	ComponentInstance_Type.ob_type = &PyType_Type;
+	if (PyType_Ready(&ComponentInstance_Type) < 0) return;
+	Py_INCREF(&ComponentInstance_Type);
+	PyModule_AddObject(m, "ComponentInstance", (PyObject *)&ComponentInstance_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&ComponentInstance_Type);
+	PyModule_AddObject(m, "ComponentInstanceType", (PyObject *)&ComponentInstance_Type);
+	Component_Type.ob_type = &PyType_Type;
+	if (PyType_Ready(&Component_Type) < 0) return;
+	Py_INCREF(&Component_Type);
+	PyModule_AddObject(m, "Component", (PyObject *)&Component_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&Component_Type);
+	PyModule_AddObject(m, "ComponentType", (PyObject *)&Component_Type);
+}
+
+/* ========================= End module _Cm ========================= */
+

Added: vendor/Python/current/Mac/Modules/cm/cmscan.py
===================================================================
--- vendor/Python/current/Mac/Modules/cm/cmscan.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/cm/cmscan.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,89 @@
+# Scan an Apple header file, generating a Python file of generator calls.
+
+import sys
+import os
+from bgenlocations import TOOLBOXDIR, BGENDIR
+sys.path.append(BGENDIR)
+from scantools import Scanner
+
+LONG = "Components"
+SHORT = "cm"
+
+def main():
+    input = "Components.h"
+    output = SHORT + "gen.py"
+    defsoutput = TOOLBOXDIR + LONG + ".py"
+    scanner = MyScanner(input, output, defsoutput)
+    scanner.scan()
+    scanner.close()
+    print "=== Testing definitions output code ==="
+    execfile(defsoutput, {}, {})
+    print "=== Done scanning and generating, now importing the generated code... ==="
+    exec "import " + SHORT + "support"
+    print "=== Done.  It's up to you to compile it now! ==="
+
+class MyScanner(Scanner):
+
+    def destination(self, type, name, arglist):
+        classname = "Function"
+        listname = "functions"
+        if arglist:
+            t, n, m = arglist[0]
+            #
+            # FindNextComponent is a special case, since it call also be called
+            # with None as the argument. Hence, we make it a function
+            #
+            if t == "Component" and m == "InMode" and name != "FindNextComponent":
+                classname = "Method"
+                listname = "c_methods"
+            elif t == "ComponentInstance" and m == "InMode":
+                classname = "Method"
+                listname = "ci_methods"
+        return classname, listname
+
+    def writeinitialdefs(self):
+        self.defsfile.write("def FOUR_CHAR_CODE(x): return x\n")
+
+    def makeblacklistnames(self):
+        return [
+                "OpenADefaultComponent",
+                "GetComponentTypeModSeed",
+                "OpenAComponentResFile",
+                "CallComponentUnregister",
+                "CallComponentTarget",
+                "CallComponentRegister",
+                "CallComponentVersion",
+                "CallComponentCanDo",
+                "CallComponentClose",
+                "CallComponentOpen",
+                "OpenAComponent",
+                "GetComponentPublicResource", # Missing in CW Pro 6
+                "CallComponentGetPublicResource", # Missing in CW Pro 6
+                'SetComponentInstanceA5',
+                'GetComponentInstanceA5',
+                ]
+
+    def makeblacklisttypes(self):
+        return [
+                "ResourceSpec",
+                "ComponentResource",
+                "ComponentPlatformInfo",
+                "ComponentResourceExtension",
+                "ComponentPlatformInfoArray",
+                "ExtComponentResource",
+                "ComponentParameters",
+
+                "ComponentRoutineUPP",
+                "ComponentMPWorkFunctionUPP",
+                "ComponentFunctionUPP",
+                "GetMissingComponentResourceUPP",
+                ]
+
+    def makerepairinstructions(self):
+        return [
+                ([('ComponentDescription', 'looking', 'OutMode')],
+                 [('ComponentDescription', '*', 'InMode')]),
+                ]
+
+if __name__ == "__main__":
+    main()

Added: vendor/Python/current/Mac/Modules/cm/cmsupport.py
===================================================================
--- vendor/Python/current/Mac/Modules/cm/cmsupport.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/cm/cmsupport.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,125 @@
+# This script generates a Python interface for an Apple Macintosh Manager.
+# It uses the "bgen" package to generate C code.
+# The function specifications are generated by scanning the mamager's header file,
+# using the "scantools" package (customized for this particular manager).
+
+import string
+
+# Declarations that change for each manager
+MACHEADERFILE = 'Components.h'          # The Apple header file
+MODNAME = '_Cm'                         # The name of the module
+
+# The following is *usually* unchanged but may still require tuning
+MODPREFIX = 'Cm'                        # The prefix for module-wide routines
+C_OBJECTPREFIX = 'CmpObj'       # The prefix for object methods
+CI_OBJECTPREFIX = 'CmpInstObj'
+INPUTFILE = string.lower(MODPREFIX) + 'gen.py' # The file generated by the scanner
+OUTPUTFILE = MODNAME + "module.c"       # The file generated by this program
+
+from macsupport import *
+
+# Create the type objects
+
+includestuff = includestuff + """
+#include <Carbon/Carbon.h>
+
+#ifdef USE_TOOLBOX_OBJECT_GLUE
+extern PyObject *_CmpObj_New(Component);
+extern int _CmpObj_Convert(PyObject *, Component *);
+extern PyObject *_CmpInstObj_New(ComponentInstance);
+extern int _CmpInstObj_Convert(PyObject *, ComponentInstance *);
+
+#define CmpObj_New _CmpObj_New
+#define CmpObj_Convert _CmpObj_Convert
+#define CmpInstObj_New _CmpInstObj_New
+#define CmpInstObj_Convert _CmpInstObj_Convert
+#endif
+
+/*
+** Parse/generate ComponentDescriptor records
+*/
+static PyObject *
+CmpDesc_New(ComponentDescription *itself)
+{
+
+        return Py_BuildValue("O&O&O&ll",
+                PyMac_BuildOSType, itself->componentType,
+                PyMac_BuildOSType, itself->componentSubType,
+                PyMac_BuildOSType, itself->componentManufacturer,
+                itself->componentFlags, itself->componentFlagsMask);
+}
+
+static int
+CmpDesc_Convert(PyObject *v, ComponentDescription *p_itself)
+{
+        return PyArg_ParseTuple(v, "O&O&O&ll",
+                PyMac_GetOSType, &p_itself->componentType,
+                PyMac_GetOSType, &p_itself->componentSubType,
+                PyMac_GetOSType, &p_itself->componentManufacturer,
+                &p_itself->componentFlags, &p_itself->componentFlagsMask);
+}
+
+"""
+
+initstuff = initstuff + """
+        PyMac_INIT_TOOLBOX_OBJECT_NEW(Component, CmpObj_New);
+        PyMac_INIT_TOOLBOX_OBJECT_CONVERT(Component, CmpObj_Convert);
+        PyMac_INIT_TOOLBOX_OBJECT_NEW(ComponentInstance, CmpInstObj_New);
+        PyMac_INIT_TOOLBOX_OBJECT_CONVERT(ComponentInstance, CmpInstObj_Convert);
+"""
+
+ComponentDescription = OpaqueType('ComponentDescription', 'CmpDesc')
+Component = OpaqueByValueType('Component', C_OBJECTPREFIX)
+ComponentInstance = OpaqueByValueType('ComponentInstance', CI_OBJECTPREFIX)
+ComponentResult = Type("ComponentResult", "l")
+
+ComponentResourceHandle = OpaqueByValueType("ComponentResourceHandle", "ResObj")
+
+class MyCIObjectDefinition(PEP253Mixin, GlobalObjectDefinition):
+    def outputCheckNewArg(self):
+        Output("""if (itself == NULL) {
+                                PyErr_SetString(Cm_Error,"NULL ComponentInstance");
+                                return NULL;
+                        }""")
+
+class MyCObjectDefinition(PEP253Mixin, GlobalObjectDefinition):
+    def outputCheckNewArg(self):
+        Output("""if (itself == NULL) {
+                                /* XXXX Or should we return None? */
+                                PyErr_SetString(Cm_Error,"No such component");
+                                return NULL;
+                        }""")
+
+    def outputCheckConvertArg(self):
+        Output("""if ( v == Py_None ) {
+                                *p_itself = 0;
+                                return 1;
+        }""")
+
+# Create the generator groups and link them
+module = MacModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff)
+ci_object = MyCIObjectDefinition('ComponentInstance', CI_OBJECTPREFIX,
+                'ComponentInstance')
+c_object = MyCObjectDefinition('Component', C_OBJECTPREFIX, 'Component')
+module.addobject(ci_object)
+module.addobject(c_object)
+
+# Create the generator classes used to populate the lists
+Function = OSErrWeakLinkFunctionGenerator
+Method = OSErrWeakLinkMethodGenerator
+
+# Create and populate the lists
+functions = []
+c_methods = []
+ci_methods = []
+execfile(INPUTFILE)
+
+# add the populated lists to the generator groups
+# (in a different wordl the scan program would generate this)
+for f in functions: module.add(f)
+for f in c_methods: c_object.add(f)
+for f in ci_methods: ci_object.add(f)
+
+# generate output (open the output file as late as possible)
+SetOutputFileName(OUTPUTFILE)
+module.generate()

Added: vendor/Python/current/Mac/Modules/ctl/_Ctlmodule.c
===================================================================
--- vendor/Python/current/Mac/Modules/ctl/_Ctlmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/ctl/_Ctlmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,5804 @@
+
+/* ========================== Module _Ctl =========================== */
+
+#include "Python.h"
+
+
+
+#include "pymactoolbox.h"
+
+/* Macro to test whether a weak-loaded CFM function exists */
+#define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL )  {\
+        PyErr_SetString(PyExc_NotImplementedError, \
+        "Not available in this shared library/OS version"); \
+        return NULL; \
+    }} while(0)
+
+
+#include <Carbon/Carbon.h>
+
+#ifdef USE_TOOLBOX_OBJECT_GLUE
+extern PyObject *_CtlObj_New(ControlHandle);
+extern int _CtlObj_Convert(PyObject *, ControlHandle *);
+
+#define CtlObj_New _CtlObj_New
+#define CtlObj_Convert _CtlObj_Convert
+#endif
+
+static PyObject *CtlObj_WhichControl(ControlHandle);
+
+#define as_Control(h) ((ControlHandle)h)
+#define as_Resource(ctl) ((Handle)ctl)
+#define GetControlRect(ctl, rectp) GetControlBounds(ctl, rectp)
+
+#define MAXTABS 32  /* maximum number of tabs that we support in a tabs control */
+/*
+** Parse/generate ControlFontStyleRec records
+*/
+#if 0 /* Not needed */
+static PyObject *
+ControlFontStyle_New(ControlFontStyleRec *itself)
+{
+
+        return Py_BuildValue("hhhhhhO&O&", itself->flags, itself->font,
+                itself->size, itself->style, itself->mode, itself->just,
+                QdRGB_New, &itself->foreColor, QdRGB_New, &itself->backColor);
+}
+#endif
+
+static int
+ControlFontStyle_Convert(PyObject *v, ControlFontStyleRec *itself)
+{
+        return PyArg_Parse(v, "(hhhhhhO&O&)", &itself->flags,
+                &itself->font, &itself->size, &itself->style, &itself->mode,
+                &itself->just, QdRGB_Convert, &itself->foreColor,
+                QdRGB_Convert, &itself->backColor);
+}
+
+/*
+** Parse/generate ControlID records
+*/
+static PyObject *
+PyControlID_New(ControlID *itself)
+{
+
+        return Py_BuildValue("O&l", PyMac_BuildOSType, itself->signature, itself->id);
+}
+
+static int
+PyControlID_Convert(PyObject *v, ControlID *itself)
+{
+        return PyArg_Parse(v, "(O&l)", PyMac_GetOSType, &itself->signature, &itself->id);
+}
+
+/*
+** generate DataBrowserListViewColumnDesc records
+*/
+static int
+DataBrowserTableViewColumnDesc_Convert(PyObject *v, DataBrowserTableViewColumnDesc *itself)
+{
+        return PyArg_Parse(v, "(lO&l)",
+                           &itself->propertyID,
+                           PyMac_GetOSType, &itself->propertyType,
+                           &itself->propertyFlags);
+}
+
+static int
+ControlButtonContentInfo_Convert(PyObject *v, ControlButtonContentInfo *itself)
+{
+        return PyArg_Parse(v, "(hO&)",
+                           &itself->contentType,
+                           OptResObj_Convert, &itself->u.iconSuite);
+}
+
+static int
+DataBrowserListViewHeaderDesc_Convert(PyObject *v, DataBrowserListViewHeaderDesc *itself)
+{
+        itself->version = kDataBrowserListViewLatestHeaderDesc;
+        return PyArg_Parse(v, "(HHhO&HO&O&)",
+                           &itself->minimumWidth,
+                           &itself->maximumWidth,
+                           &itself->titleOffset,
+                           CFStringRefObj_Convert, &itself->titleString,
+                           &itself->initialOrder,
+                           ControlFontStyle_Convert, &itself->btnFontStyle,
+                           ControlButtonContentInfo_Convert, &itself->btnContentInfo);
+}
+
+static int
+DataBrowserListViewColumnDesc_Convert(PyObject *v, DataBrowserListViewColumnDesc *itself)
+{
+        return PyArg_Parse(v, "(O&O&)",
+                           DataBrowserTableViewColumnDesc_Convert, &itself->propertyDesc,
+                           DataBrowserListViewHeaderDesc_Convert, &itself->headerBtnDesc);
+}
+
+/* TrackControl and HandleControlClick callback support */
+#define kMyControlActionProcTag 'ACTN'  /* not an official tag, only for internal use */
+static PyObject *tracker;
+static ControlActionUPP mytracker_upp;
+static ControlActionUPP myactionproc_upp;
+static ControlUserPaneKeyDownUPP mykeydownproc_upp;
+static ControlUserPaneFocusUPP myfocusproc_upp;
+static ControlUserPaneDrawUPP mydrawproc_upp;
+static ControlUserPaneIdleUPP myidleproc_upp;
+static ControlUserPaneHitTestUPP myhittestproc_upp;
+static ControlUserPaneTrackingUPP mytrackingproc_upp;
+
+static int settrackfunc(PyObject *);    /* forward */
+static void clrtrackfunc(void); /* forward */
+static int setcallback(PyObject *, OSType, PyObject *, UniversalProcPtr *);
+
+static PyObject *Ctl_Error;
+
+/* ---------------------- Object type Control ----------------------- */
+
+PyTypeObject Control_Type;
+
+#define CtlObj_Check(x) ((x)->ob_type == &Control_Type || PyObject_TypeCheck((x), &Control_Type))
+
+typedef struct ControlObject {
+	PyObject_HEAD
+	ControlHandle ob_itself;
+	PyObject *ob_callbackdict;
+} ControlObject;
+
+PyObject *CtlObj_New(ControlHandle itself)
+{
+	ControlObject *it;
+	if (itself == NULL) return PyMac_Error(resNotFound);
+	it = PyObject_NEW(ControlObject, &Control_Type);
+	if (it == NULL) return NULL;
+	it->ob_itself = itself;
+	SetControlReference(itself, (long)it);
+	it->ob_callbackdict = NULL;
+	return (PyObject *)it;
+}
+
+int CtlObj_Convert(PyObject *v, ControlHandle *p_itself)
+{
+	if (!CtlObj_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "Control required");
+		return 0;
+	}
+	*p_itself = ((ControlObject *)v)->ob_itself;
+	return 1;
+}
+
+static void CtlObj_dealloc(ControlObject *self)
+{
+	Py_XDECREF(self->ob_callbackdict);
+	if (self->ob_itself)SetControlReference(self->ob_itself, (long)0); /* Make it forget about us */
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *CtlObj_HiliteControl(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ControlPartCode hiliteState;
+#ifndef HiliteControl
+	PyMac_PRECHECK(HiliteControl);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &hiliteState))
+		return NULL;
+	HiliteControl(_self->ob_itself,
+	              hiliteState);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_ShowControl(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef ShowControl
+	PyMac_PRECHECK(ShowControl);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	ShowControl(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_HideControl(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef HideControl
+	PyMac_PRECHECK(HideControl);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	HideControl(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_IsControlActive(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+#ifndef IsControlActive
+	PyMac_PRECHECK(IsControlActive);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = IsControlActive(_self->ob_itself);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CtlObj_IsControlVisible(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+#ifndef IsControlVisible
+	PyMac_PRECHECK(IsControlVisible);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = IsControlVisible(_self->ob_itself);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CtlObj_ActivateControl(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+#ifndef ActivateControl
+	PyMac_PRECHECK(ActivateControl);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = ActivateControl(_self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_DeactivateControl(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+#ifndef DeactivateControl
+	PyMac_PRECHECK(DeactivateControl);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = DeactivateControl(_self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_SetControlVisibility(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Boolean inIsVisible;
+	Boolean inDoDraw;
+#ifndef SetControlVisibility
+	PyMac_PRECHECK(SetControlVisibility);
+#endif
+	if (!PyArg_ParseTuple(_args, "bb",
+	                      &inIsVisible,
+	                      &inDoDraw))
+		return NULL;
+	_err = SetControlVisibility(_self->ob_itself,
+	                            inIsVisible,
+	                            inDoDraw);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_IsControlEnabled(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+#ifndef IsControlEnabled
+	PyMac_PRECHECK(IsControlEnabled);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = IsControlEnabled(_self->ob_itself);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CtlObj_EnableControl(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+#ifndef EnableControl
+	PyMac_PRECHECK(EnableControl);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = EnableControl(_self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_DisableControl(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+#ifndef DisableControl
+	PyMac_PRECHECK(DisableControl);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = DisableControl(_self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_Draw1Control(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef Draw1Control
+	PyMac_PRECHECK(Draw1Control);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	Draw1Control(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_GetBestControlRect(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Rect outRect;
+	SInt16 outBaseLineOffset;
+#ifndef GetBestControlRect
+	PyMac_PRECHECK(GetBestControlRect);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetBestControlRect(_self->ob_itself,
+	                          &outRect,
+	                          &outBaseLineOffset);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&h",
+	                     PyMac_BuildRect, &outRect,
+	                     outBaseLineOffset);
+	return _res;
+}
+
+static PyObject *CtlObj_SetControlFontStyle(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	ControlFontStyleRec inStyle;
+#ifndef SetControlFontStyle
+	PyMac_PRECHECK(SetControlFontStyle);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ControlFontStyle_Convert, &inStyle))
+		return NULL;
+	_err = SetControlFontStyle(_self->ob_itself,
+	                           &inStyle);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_DrawControlInCurrentPort(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef DrawControlInCurrentPort
+	PyMac_PRECHECK(DrawControlInCurrentPort);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	DrawControlInCurrentPort(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_SetUpControlBackground(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SInt16 inDepth;
+	Boolean inIsColorDevice;
+#ifndef SetUpControlBackground
+	PyMac_PRECHECK(SetUpControlBackground);
+#endif
+	if (!PyArg_ParseTuple(_args, "hb",
+	                      &inDepth,
+	                      &inIsColorDevice))
+		return NULL;
+	_err = SetUpControlBackground(_self->ob_itself,
+	                              inDepth,
+	                              inIsColorDevice);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_SetUpControlTextColor(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SInt16 inDepth;
+	Boolean inIsColorDevice;
+#ifndef SetUpControlTextColor
+	PyMac_PRECHECK(SetUpControlTextColor);
+#endif
+	if (!PyArg_ParseTuple(_args, "hb",
+	                      &inDepth,
+	                      &inIsColorDevice))
+		return NULL;
+	_err = SetUpControlTextColor(_self->ob_itself,
+	                             inDepth,
+	                             inIsColorDevice);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_DragControl(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Point startPoint;
+	Rect limitRect;
+	Rect slopRect;
+	DragConstraint axis;
+#ifndef DragControl
+	PyMac_PRECHECK(DragControl);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&H",
+	                      PyMac_GetPoint, &startPoint,
+	                      PyMac_GetRect, &limitRect,
+	                      PyMac_GetRect, &slopRect,
+	                      &axis))
+		return NULL;
+	DragControl(_self->ob_itself,
+	            startPoint,
+	            &limitRect,
+	            &slopRect,
+	            axis);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_TestControl(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ControlPartCode _rv;
+	Point testPoint;
+#ifndef TestControl
+	PyMac_PRECHECK(TestControl);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetPoint, &testPoint))
+		return NULL;
+	_rv = TestControl(_self->ob_itself,
+	                  testPoint);
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CtlObj_HandleControlContextualMenuClick(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Point inWhere;
+	Boolean menuDisplayed;
+#ifndef HandleControlContextualMenuClick
+	PyMac_PRECHECK(HandleControlContextualMenuClick);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetPoint, &inWhere))
+		return NULL;
+	_err = HandleControlContextualMenuClick(_self->ob_itself,
+	                                        inWhere,
+	                                        &menuDisplayed);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("b",
+	                     menuDisplayed);
+	return _res;
+}
+
+static PyObject *CtlObj_GetControlClickActivation(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Point inWhere;
+	EventModifiers inModifiers;
+	ClickActivationResult outResult;
+#ifndef GetControlClickActivation
+	PyMac_PRECHECK(GetControlClickActivation);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&H",
+	                      PyMac_GetPoint, &inWhere,
+	                      &inModifiers))
+		return NULL;
+	_err = GetControlClickActivation(_self->ob_itself,
+	                                 inWhere,
+	                                 inModifiers,
+	                                 &outResult);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     outResult);
+	return _res;
+}
+
+static PyObject *CtlObj_HandleControlKey(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ControlPartCode _rv;
+	SInt16 inKeyCode;
+	SInt16 inCharCode;
+	EventModifiers inModifiers;
+#ifndef HandleControlKey
+	PyMac_PRECHECK(HandleControlKey);
+#endif
+	if (!PyArg_ParseTuple(_args, "hhH",
+	                      &inKeyCode,
+	                      &inCharCode,
+	                      &inModifiers))
+		return NULL;
+	_rv = HandleControlKey(_self->ob_itself,
+	                       inKeyCode,
+	                       inCharCode,
+	                       inModifiers);
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CtlObj_HandleControlSetCursor(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Point localPoint;
+	EventModifiers modifiers;
+	Boolean cursorWasSet;
+#ifndef HandleControlSetCursor
+	PyMac_PRECHECK(HandleControlSetCursor);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&H",
+	                      PyMac_GetPoint, &localPoint,
+	                      &modifiers))
+		return NULL;
+	_err = HandleControlSetCursor(_self->ob_itself,
+	                              localPoint,
+	                              modifiers,
+	                              &cursorWasSet);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("b",
+	                     cursorWasSet);
+	return _res;
+}
+
+static PyObject *CtlObj_MoveControl(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	SInt16 h;
+	SInt16 v;
+#ifndef MoveControl
+	PyMac_PRECHECK(MoveControl);
+#endif
+	if (!PyArg_ParseTuple(_args, "hh",
+	                      &h,
+	                      &v))
+		return NULL;
+	MoveControl(_self->ob_itself,
+	            h,
+	            v);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_SizeControl(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	SInt16 w;
+	SInt16 h;
+#ifndef SizeControl
+	PyMac_PRECHECK(SizeControl);
+#endif
+	if (!PyArg_ParseTuple(_args, "hh",
+	                      &w,
+	                      &h))
+		return NULL;
+	SizeControl(_self->ob_itself,
+	            w,
+	            h);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_SetControlTitle(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Str255 title;
+#ifndef SetControlTitle
+	PyMac_PRECHECK(SetControlTitle);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetStr255, title))
+		return NULL;
+	SetControlTitle(_self->ob_itself,
+	                title);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_GetControlTitle(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Str255 title;
+#ifndef GetControlTitle
+	PyMac_PRECHECK(GetControlTitle);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	GetControlTitle(_self->ob_itself,
+	                title);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildStr255, title);
+	return _res;
+}
+
+static PyObject *CtlObj_SetControlTitleWithCFString(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	CFStringRef inString;
+#ifndef SetControlTitleWithCFString
+	PyMac_PRECHECK(SetControlTitleWithCFString);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CFStringRefObj_Convert, &inString))
+		return NULL;
+	_err = SetControlTitleWithCFString(_self->ob_itself,
+	                                   inString);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_CopyControlTitleAsCFString(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	CFStringRef outString;
+#ifndef CopyControlTitleAsCFString
+	PyMac_PRECHECK(CopyControlTitleAsCFString);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = CopyControlTitleAsCFString(_self->ob_itself,
+	                                  &outString);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, outString);
+	return _res;
+}
+
+static PyObject *CtlObj_GetControlValue(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	SInt16 _rv;
+#ifndef GetControlValue
+	PyMac_PRECHECK(GetControlValue);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetControlValue(_self->ob_itself);
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CtlObj_SetControlValue(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	SInt16 newValue;
+#ifndef SetControlValue
+	PyMac_PRECHECK(SetControlValue);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &newValue))
+		return NULL;
+	SetControlValue(_self->ob_itself,
+	                newValue);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_GetControlMinimum(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	SInt16 _rv;
+#ifndef GetControlMinimum
+	PyMac_PRECHECK(GetControlMinimum);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetControlMinimum(_self->ob_itself);
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CtlObj_SetControlMinimum(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	SInt16 newMinimum;
+#ifndef SetControlMinimum
+	PyMac_PRECHECK(SetControlMinimum);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &newMinimum))
+		return NULL;
+	SetControlMinimum(_self->ob_itself,
+	                  newMinimum);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_GetControlMaximum(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	SInt16 _rv;
+#ifndef GetControlMaximum
+	PyMac_PRECHECK(GetControlMaximum);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetControlMaximum(_self->ob_itself);
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CtlObj_SetControlMaximum(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	SInt16 newMaximum;
+#ifndef SetControlMaximum
+	PyMac_PRECHECK(SetControlMaximum);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &newMaximum))
+		return NULL;
+	SetControlMaximum(_self->ob_itself,
+	                  newMaximum);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_GetControlViewSize(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	SInt32 _rv;
+#ifndef GetControlViewSize
+	PyMac_PRECHECK(GetControlViewSize);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetControlViewSize(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CtlObj_SetControlViewSize(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	SInt32 newViewSize;
+#ifndef SetControlViewSize
+	PyMac_PRECHECK(SetControlViewSize);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &newViewSize))
+		return NULL;
+	SetControlViewSize(_self->ob_itself,
+	                   newViewSize);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_GetControl32BitValue(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	SInt32 _rv;
+#ifndef GetControl32BitValue
+	PyMac_PRECHECK(GetControl32BitValue);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetControl32BitValue(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CtlObj_SetControl32BitValue(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	SInt32 newValue;
+#ifndef SetControl32BitValue
+	PyMac_PRECHECK(SetControl32BitValue);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &newValue))
+		return NULL;
+	SetControl32BitValue(_self->ob_itself,
+	                     newValue);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_GetControl32BitMaximum(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	SInt32 _rv;
+#ifndef GetControl32BitMaximum
+	PyMac_PRECHECK(GetControl32BitMaximum);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetControl32BitMaximum(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CtlObj_SetControl32BitMaximum(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	SInt32 newMaximum;
+#ifndef SetControl32BitMaximum
+	PyMac_PRECHECK(SetControl32BitMaximum);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &newMaximum))
+		return NULL;
+	SetControl32BitMaximum(_self->ob_itself,
+	                       newMaximum);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_GetControl32BitMinimum(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	SInt32 _rv;
+#ifndef GetControl32BitMinimum
+	PyMac_PRECHECK(GetControl32BitMinimum);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetControl32BitMinimum(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CtlObj_SetControl32BitMinimum(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	SInt32 newMinimum;
+#ifndef SetControl32BitMinimum
+	PyMac_PRECHECK(SetControl32BitMinimum);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &newMinimum))
+		return NULL;
+	SetControl32BitMinimum(_self->ob_itself,
+	                       newMinimum);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_IsValidControlHandle(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+#ifndef IsValidControlHandle
+	PyMac_PRECHECK(IsValidControlHandle);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = IsValidControlHandle(_self->ob_itself);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CtlObj_SetControlID(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	ControlID inID;
+#ifndef SetControlID
+	PyMac_PRECHECK(SetControlID);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyControlID_Convert, &inID))
+		return NULL;
+	_err = SetControlID(_self->ob_itself,
+	                    &inID);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_GetControlID(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	ControlID outID;
+#ifndef GetControlID
+	PyMac_PRECHECK(GetControlID);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetControlID(_self->ob_itself,
+	                    &outID);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     PyControlID_New, &outID);
+	return _res;
+}
+
+static PyObject *CtlObj_SetControlCommandID(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 inCommandID;
+#ifndef SetControlCommandID
+	PyMac_PRECHECK(SetControlCommandID);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &inCommandID))
+		return NULL;
+	_err = SetControlCommandID(_self->ob_itself,
+	                           inCommandID);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_GetControlCommandID(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 outCommandID;
+#ifndef GetControlCommandID
+	PyMac_PRECHECK(GetControlCommandID);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetControlCommandID(_self->ob_itself,
+	                           &outCommandID);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     outCommandID);
+	return _res;
+}
+
+static PyObject *CtlObj_RemoveControlProperty(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	OSType propertyCreator;
+	OSType propertyTag;
+#ifndef RemoveControlProperty
+	PyMac_PRECHECK(RemoveControlProperty);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetOSType, &propertyCreator,
+	                      PyMac_GetOSType, &propertyTag))
+		return NULL;
+	_err = RemoveControlProperty(_self->ob_itself,
+	                             propertyCreator,
+	                             propertyTag);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_GetControlPropertyAttributes(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	OSType propertyCreator;
+	OSType propertyTag;
+	UInt32 attributes;
+#ifndef GetControlPropertyAttributes
+	PyMac_PRECHECK(GetControlPropertyAttributes);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetOSType, &propertyCreator,
+	                      PyMac_GetOSType, &propertyTag))
+		return NULL;
+	_err = GetControlPropertyAttributes(_self->ob_itself,
+	                                    propertyCreator,
+	                                    propertyTag,
+	                                    &attributes);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     attributes);
+	return _res;
+}
+
+static PyObject *CtlObj_ChangeControlPropertyAttributes(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	OSType propertyCreator;
+	OSType propertyTag;
+	UInt32 attributesToSet;
+	UInt32 attributesToClear;
+#ifndef ChangeControlPropertyAttributes
+	PyMac_PRECHECK(ChangeControlPropertyAttributes);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&ll",
+	                      PyMac_GetOSType, &propertyCreator,
+	                      PyMac_GetOSType, &propertyTag,
+	                      &attributesToSet,
+	                      &attributesToClear))
+		return NULL;
+	_err = ChangeControlPropertyAttributes(_self->ob_itself,
+	                                       propertyCreator,
+	                                       propertyTag,
+	                                       attributesToSet,
+	                                       attributesToClear);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_GetControlRegion(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	ControlPartCode inPart;
+	RgnHandle outRegion;
+#ifndef GetControlRegion
+	PyMac_PRECHECK(GetControlRegion);
+#endif
+	if (!PyArg_ParseTuple(_args, "hO&",
+	                      &inPart,
+	                      ResObj_Convert, &outRegion))
+		return NULL;
+	_err = GetControlRegion(_self->ob_itself,
+	                        inPart,
+	                        outRegion);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_GetControlVariant(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ControlVariant _rv;
+#ifndef GetControlVariant
+	PyMac_PRECHECK(GetControlVariant);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetControlVariant(_self->ob_itself);
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CtlObj_SetControlAction(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PyObject* actionProc;
+	UniversalProcPtr c_callback;
+#ifndef SetControlAction
+	PyMac_PRECHECK(SetControlAction);
+#endif
+	if (!PyArg_ParseTuple(_args, "O",
+	                      &actionProc))
+		return NULL;
+	SetControlAction(_self->ob_itself,
+	                 myactionproc_upp);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	setcallback((PyObject*)_self, kMyControlActionProcTag, actionProc, &c_callback);
+	return _res;
+}
+
+static PyObject *CtlObj_SetControlReference(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	SInt32 data;
+#ifndef SetControlReference
+	PyMac_PRECHECK(SetControlReference);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &data))
+		return NULL;
+	SetControlReference(_self->ob_itself,
+	                    data);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_GetControlReference(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	SInt32 _rv;
+#ifndef GetControlReference
+	PyMac_PRECHECK(GetControlReference);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetControlReference(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CtlObj_EmbedControl(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	ControlHandle inContainer;
+#ifndef EmbedControl
+	PyMac_PRECHECK(EmbedControl);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CtlObj_Convert, &inContainer))
+		return NULL;
+	_err = EmbedControl(_self->ob_itself,
+	                    inContainer);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_AutoEmbedControl(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	WindowPtr inWindow;
+#ifndef AutoEmbedControl
+	PyMac_PRECHECK(AutoEmbedControl);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      WinObj_Convert, &inWindow))
+		return NULL;
+	_err = AutoEmbedControl(_self->ob_itself,
+	                        inWindow);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_GetSuperControl(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	ControlHandle outParent;
+#ifndef GetSuperControl
+	PyMac_PRECHECK(GetSuperControl);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetSuperControl(_self->ob_itself,
+	                       &outParent);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CtlObj_WhichControl, outParent);
+	return _res;
+}
+
+static PyObject *CtlObj_CountSubControls(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	UInt16 outNumChildren;
+#ifndef CountSubControls
+	PyMac_PRECHECK(CountSubControls);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = CountSubControls(_self->ob_itself,
+	                        &outNumChildren);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("H",
+	                     outNumChildren);
+	return _res;
+}
+
+static PyObject *CtlObj_GetIndexedSubControl(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	UInt16 inIndex;
+	ControlHandle outSubControl;
+#ifndef GetIndexedSubControl
+	PyMac_PRECHECK(GetIndexedSubControl);
+#endif
+	if (!PyArg_ParseTuple(_args, "H",
+	                      &inIndex))
+		return NULL;
+	_err = GetIndexedSubControl(_self->ob_itself,
+	                            inIndex,
+	                            &outSubControl);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CtlObj_WhichControl, outSubControl);
+	return _res;
+}
+
+static PyObject *CtlObj_SetControlSupervisor(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	ControlHandle inBoss;
+#ifndef SetControlSupervisor
+	PyMac_PRECHECK(SetControlSupervisor);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CtlObj_Convert, &inBoss))
+		return NULL;
+	_err = SetControlSupervisor(_self->ob_itself,
+	                            inBoss);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_GetControlFeatures(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	UInt32 outFeatures;
+#ifndef GetControlFeatures
+	PyMac_PRECHECK(GetControlFeatures);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetControlFeatures(_self->ob_itself,
+	                          &outFeatures);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     outFeatures);
+	return _res;
+}
+
+static PyObject *CtlObj_GetControlDataSize(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	ControlPartCode inPart;
+	ResType inTagName;
+	Size outMaxSize;
+#ifndef GetControlDataSize
+	PyMac_PRECHECK(GetControlDataSize);
+#endif
+	if (!PyArg_ParseTuple(_args, "hO&",
+	                      &inPart,
+	                      PyMac_GetOSType, &inTagName))
+		return NULL;
+	_err = GetControlDataSize(_self->ob_itself,
+	                          inPart,
+	                          inTagName,
+	                          &outMaxSize);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     outMaxSize);
+	return _res;
+}
+
+static PyObject *CtlObj_HandleControlDragTracking(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	DragTrackingMessage inMessage;
+	DragReference inDrag;
+	Boolean outLikesDrag;
+#ifndef HandleControlDragTracking
+	PyMac_PRECHECK(HandleControlDragTracking);
+#endif
+	if (!PyArg_ParseTuple(_args, "hO&",
+	                      &inMessage,
+	                      DragObj_Convert, &inDrag))
+		return NULL;
+	_err = HandleControlDragTracking(_self->ob_itself,
+	                                 inMessage,
+	                                 inDrag,
+	                                 &outLikesDrag);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("b",
+	                     outLikesDrag);
+	return _res;
+}
+
+static PyObject *CtlObj_HandleControlDragReceive(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	DragReference inDrag;
+#ifndef HandleControlDragReceive
+	PyMac_PRECHECK(HandleControlDragReceive);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      DragObj_Convert, &inDrag))
+		return NULL;
+	_err = HandleControlDragReceive(_self->ob_itself,
+	                                inDrag);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_SetControlDragTrackingEnabled(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Boolean inTracks;
+#ifndef SetControlDragTrackingEnabled
+	PyMac_PRECHECK(SetControlDragTrackingEnabled);
+#endif
+	if (!PyArg_ParseTuple(_args, "b",
+	                      &inTracks))
+		return NULL;
+	_err = SetControlDragTrackingEnabled(_self->ob_itself,
+	                                     inTracks);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_IsControlDragTrackingEnabled(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Boolean outTracks;
+#ifndef IsControlDragTrackingEnabled
+	PyMac_PRECHECK(IsControlDragTrackingEnabled);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = IsControlDragTrackingEnabled(_self->ob_itself,
+	                                    &outTracks);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("b",
+	                     outTracks);
+	return _res;
+}
+
+static PyObject *CtlObj_GetControlBounds(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect bounds;
+#ifndef GetControlBounds
+	PyMac_PRECHECK(GetControlBounds);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	GetControlBounds(_self->ob_itself,
+	                 &bounds);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildRect, &bounds);
+	return _res;
+}
+
+static PyObject *CtlObj_IsControlHilited(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+#ifndef IsControlHilited
+	PyMac_PRECHECK(IsControlHilited);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = IsControlHilited(_self->ob_itself);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CtlObj_GetControlHilite(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	UInt16 _rv;
+#ifndef GetControlHilite
+	PyMac_PRECHECK(GetControlHilite);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetControlHilite(_self->ob_itself);
+	_res = Py_BuildValue("H",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CtlObj_GetControlOwner(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	WindowPtr _rv;
+#ifndef GetControlOwner
+	PyMac_PRECHECK(GetControlOwner);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetControlOwner(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     WinObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CtlObj_GetControlDataHandle(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Handle _rv;
+#ifndef GetControlDataHandle
+	PyMac_PRECHECK(GetControlDataHandle);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetControlDataHandle(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CtlObj_GetControlPopupMenuHandle(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	MenuHandle _rv;
+#ifndef GetControlPopupMenuHandle
+	PyMac_PRECHECK(GetControlPopupMenuHandle);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetControlPopupMenuHandle(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     MenuObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CtlObj_GetControlPopupMenuID(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short _rv;
+#ifndef GetControlPopupMenuID
+	PyMac_PRECHECK(GetControlPopupMenuID);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetControlPopupMenuID(_self->ob_itself);
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CtlObj_SetControlDataHandle(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Handle dataHandle;
+#ifndef SetControlDataHandle
+	PyMac_PRECHECK(SetControlDataHandle);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &dataHandle))
+		return NULL;
+	SetControlDataHandle(_self->ob_itself,
+	                     dataHandle);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_SetControlBounds(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect bounds;
+#ifndef SetControlBounds
+	PyMac_PRECHECK(SetControlBounds);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetRect, &bounds))
+		return NULL;
+	SetControlBounds(_self->ob_itself,
+	                 &bounds);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_SetControlPopupMenuHandle(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	MenuHandle popupMenu;
+#ifndef SetControlPopupMenuHandle
+	PyMac_PRECHECK(SetControlPopupMenuHandle);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      MenuObj_Convert, &popupMenu))
+		return NULL;
+	SetControlPopupMenuHandle(_self->ob_itself,
+	                          popupMenu);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_SetControlPopupMenuID(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short menuID;
+#ifndef SetControlPopupMenuID
+	PyMac_PRECHECK(SetControlPopupMenuID);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &menuID))
+		return NULL;
+	SetControlPopupMenuID(_self->ob_itself,
+	                      menuID);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_GetBevelButtonMenuValue(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SInt16 outValue;
+#ifndef GetBevelButtonMenuValue
+	PyMac_PRECHECK(GetBevelButtonMenuValue);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetBevelButtonMenuValue(_self->ob_itself,
+	                               &outValue);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("h",
+	                     outValue);
+	return _res;
+}
+
+static PyObject *CtlObj_SetBevelButtonMenuValue(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SInt16 inValue;
+#ifndef SetBevelButtonMenuValue
+	PyMac_PRECHECK(SetBevelButtonMenuValue);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &inValue))
+		return NULL;
+	_err = SetBevelButtonMenuValue(_self->ob_itself,
+	                               inValue);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_GetBevelButtonMenuHandle(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	MenuHandle outHandle;
+#ifndef GetBevelButtonMenuHandle
+	PyMac_PRECHECK(GetBevelButtonMenuHandle);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetBevelButtonMenuHandle(_self->ob_itself,
+	                                &outHandle);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     MenuObj_New, outHandle);
+	return _res;
+}
+
+static PyObject *CtlObj_SetBevelButtonContentInfo(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	ControlButtonContentInfo inContent;
+#ifndef SetBevelButtonContentInfo
+	PyMac_PRECHECK(SetBevelButtonContentInfo);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ControlButtonContentInfo_Convert, &inContent))
+		return NULL;
+	_err = SetBevelButtonContentInfo(_self->ob_itself,
+	                                 &inContent);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_SetBevelButtonTransform(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	IconTransformType transform;
+#ifndef SetBevelButtonTransform
+	PyMac_PRECHECK(SetBevelButtonTransform);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &transform))
+		return NULL;
+	_err = SetBevelButtonTransform(_self->ob_itself,
+	                               transform);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_SetDisclosureTriangleLastValue(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SInt16 inValue;
+#ifndef SetDisclosureTriangleLastValue
+	PyMac_PRECHECK(SetDisclosureTriangleLastValue);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &inValue))
+		return NULL;
+	_err = SetDisclosureTriangleLastValue(_self->ob_itself,
+	                                      inValue);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_GetTabContentRect(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Rect outContentRect;
+#ifndef GetTabContentRect
+	PyMac_PRECHECK(GetTabContentRect);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetTabContentRect(_self->ob_itself,
+	                         &outContentRect);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildRect, &outContentRect);
+	return _res;
+}
+
+static PyObject *CtlObj_SetTabEnabled(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SInt16 inTabToHilite;
+	Boolean inEnabled;
+#ifndef SetTabEnabled
+	PyMac_PRECHECK(SetTabEnabled);
+#endif
+	if (!PyArg_ParseTuple(_args, "hb",
+	                      &inTabToHilite,
+	                      &inEnabled))
+		return NULL;
+	_err = SetTabEnabled(_self->ob_itself,
+	                     inTabToHilite,
+	                     inEnabled);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_SetImageWellContentInfo(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	ControlButtonContentInfo inContent;
+#ifndef SetImageWellContentInfo
+	PyMac_PRECHECK(SetImageWellContentInfo);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ControlButtonContentInfo_Convert, &inContent))
+		return NULL;
+	_err = SetImageWellContentInfo(_self->ob_itself,
+	                               &inContent);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_SetImageWellTransform(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	IconTransformType inTransform;
+#ifndef SetImageWellTransform
+	PyMac_PRECHECK(SetImageWellTransform);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &inTransform))
+		return NULL;
+	_err = SetImageWellTransform(_self->ob_itself,
+	                             inTransform);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_GetDataBrowserViewStyle(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	OSType style;
+#ifndef GetDataBrowserViewStyle
+	PyMac_PRECHECK(GetDataBrowserViewStyle);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetDataBrowserViewStyle(_self->ob_itself,
+	                               &style);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildOSType, style);
+	return _res;
+}
+
+static PyObject *CtlObj_SetDataBrowserViewStyle(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	OSType style;
+#ifndef SetDataBrowserViewStyle
+	PyMac_PRECHECK(SetDataBrowserViewStyle);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetOSType, &style))
+		return NULL;
+	_err = SetDataBrowserViewStyle(_self->ob_itself,
+	                               style);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_EnableDataBrowserEditCommand(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	UInt32 command;
+#ifndef EnableDataBrowserEditCommand
+	PyMac_PRECHECK(EnableDataBrowserEditCommand);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &command))
+		return NULL;
+	_rv = EnableDataBrowserEditCommand(_self->ob_itself,
+	                                   command);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CtlObj_ExecuteDataBrowserEditCommand(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 command;
+#ifndef ExecuteDataBrowserEditCommand
+	PyMac_PRECHECK(ExecuteDataBrowserEditCommand);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &command))
+		return NULL;
+	_err = ExecuteDataBrowserEditCommand(_self->ob_itself,
+	                                     command);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_GetDataBrowserSelectionAnchor(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 first;
+	UInt32 last;
+#ifndef GetDataBrowserSelectionAnchor
+	PyMac_PRECHECK(GetDataBrowserSelectionAnchor);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetDataBrowserSelectionAnchor(_self->ob_itself,
+	                                     &first,
+	                                     &last);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("ll",
+	                     first,
+	                     last);
+	return _res;
+}
+
+static PyObject *CtlObj_MoveDataBrowserSelectionAnchor(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 direction;
+	Boolean extendSelection;
+#ifndef MoveDataBrowserSelectionAnchor
+	PyMac_PRECHECK(MoveDataBrowserSelectionAnchor);
+#endif
+	if (!PyArg_ParseTuple(_args, "lb",
+	                      &direction,
+	                      &extendSelection))
+		return NULL;
+	_err = MoveDataBrowserSelectionAnchor(_self->ob_itself,
+	                                      direction,
+	                                      extendSelection);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_OpenDataBrowserContainer(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 container;
+#ifndef OpenDataBrowserContainer
+	PyMac_PRECHECK(OpenDataBrowserContainer);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &container))
+		return NULL;
+	_err = OpenDataBrowserContainer(_self->ob_itself,
+	                                container);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_CloseDataBrowserContainer(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 container;
+#ifndef CloseDataBrowserContainer
+	PyMac_PRECHECK(CloseDataBrowserContainer);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &container))
+		return NULL;
+	_err = CloseDataBrowserContainer(_self->ob_itself,
+	                                 container);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_SortDataBrowserContainer(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 container;
+	Boolean sortChildren;
+#ifndef SortDataBrowserContainer
+	PyMac_PRECHECK(SortDataBrowserContainer);
+#endif
+	if (!PyArg_ParseTuple(_args, "lb",
+	                      &container,
+	                      &sortChildren))
+		return NULL;
+	_err = SortDataBrowserContainer(_self->ob_itself,
+	                                container,
+	                                sortChildren);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_GetDataBrowserItems(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 container;
+	Boolean recurse;
+	UInt32 state;
+	Handle items;
+#ifndef GetDataBrowserItems
+	PyMac_PRECHECK(GetDataBrowserItems);
+#endif
+	if (!PyArg_ParseTuple(_args, "lblO&",
+	                      &container,
+	                      &recurse,
+	                      &state,
+	                      ResObj_Convert, &items))
+		return NULL;
+	_err = GetDataBrowserItems(_self->ob_itself,
+	                           container,
+	                           recurse,
+	                           state,
+	                           items);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_GetDataBrowserItemCount(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 container;
+	Boolean recurse;
+	UInt32 state;
+	UInt32 numItems;
+#ifndef GetDataBrowserItemCount
+	PyMac_PRECHECK(GetDataBrowserItemCount);
+#endif
+	if (!PyArg_ParseTuple(_args, "lbl",
+	                      &container,
+	                      &recurse,
+	                      &state))
+		return NULL;
+	_err = GetDataBrowserItemCount(_self->ob_itself,
+	                               container,
+	                               recurse,
+	                               state,
+	                               &numItems);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     numItems);
+	return _res;
+}
+
+static PyObject *CtlObj_IsDataBrowserItemSelected(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	UInt32 item;
+#ifndef IsDataBrowserItemSelected
+	PyMac_PRECHECK(IsDataBrowserItemSelected);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &item))
+		return NULL;
+	_rv = IsDataBrowserItemSelected(_self->ob_itself,
+	                                item);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CtlObj_GetDataBrowserItemState(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 item;
+	UInt32 state;
+#ifndef GetDataBrowserItemState
+	PyMac_PRECHECK(GetDataBrowserItemState);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &item))
+		return NULL;
+	_err = GetDataBrowserItemState(_self->ob_itself,
+	                               item,
+	                               &state);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     state);
+	return _res;
+}
+
+static PyObject *CtlObj_RevealDataBrowserItem(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 item;
+	UInt32 propertyID;
+	UInt8 options;
+#ifndef RevealDataBrowserItem
+	PyMac_PRECHECK(RevealDataBrowserItem);
+#endif
+	if (!PyArg_ParseTuple(_args, "llb",
+	                      &item,
+	                      &propertyID,
+	                      &options))
+		return NULL;
+	_err = RevealDataBrowserItem(_self->ob_itself,
+	                             item,
+	                             propertyID,
+	                             options);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_SetDataBrowserActiveItems(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Boolean active;
+#ifndef SetDataBrowserActiveItems
+	PyMac_PRECHECK(SetDataBrowserActiveItems);
+#endif
+	if (!PyArg_ParseTuple(_args, "b",
+	                      &active))
+		return NULL;
+	_err = SetDataBrowserActiveItems(_self->ob_itself,
+	                                 active);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_GetDataBrowserActiveItems(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Boolean active;
+#ifndef GetDataBrowserActiveItems
+	PyMac_PRECHECK(GetDataBrowserActiveItems);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetDataBrowserActiveItems(_self->ob_itself,
+	                                 &active);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("b",
+	                     active);
+	return _res;
+}
+
+static PyObject *CtlObj_SetDataBrowserScrollBarInset(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Rect insetRect;
+#ifndef SetDataBrowserScrollBarInset
+	PyMac_PRECHECK(SetDataBrowserScrollBarInset);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = SetDataBrowserScrollBarInset(_self->ob_itself,
+	                                    &insetRect);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildRect, &insetRect);
+	return _res;
+}
+
+static PyObject *CtlObj_GetDataBrowserScrollBarInset(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Rect insetRect;
+#ifndef GetDataBrowserScrollBarInset
+	PyMac_PRECHECK(GetDataBrowserScrollBarInset);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetDataBrowserScrollBarInset(_self->ob_itself,
+	                                    &insetRect);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildRect, &insetRect);
+	return _res;
+}
+
+static PyObject *CtlObj_SetDataBrowserTarget(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 target;
+#ifndef SetDataBrowserTarget
+	PyMac_PRECHECK(SetDataBrowserTarget);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &target))
+		return NULL;
+	_err = SetDataBrowserTarget(_self->ob_itself,
+	                            target);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_GetDataBrowserTarget(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 target;
+#ifndef GetDataBrowserTarget
+	PyMac_PRECHECK(GetDataBrowserTarget);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetDataBrowserTarget(_self->ob_itself,
+	                            &target);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     target);
+	return _res;
+}
+
+static PyObject *CtlObj_SetDataBrowserSortOrder(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt16 order;
+#ifndef SetDataBrowserSortOrder
+	PyMac_PRECHECK(SetDataBrowserSortOrder);
+#endif
+	if (!PyArg_ParseTuple(_args, "H",
+	                      &order))
+		return NULL;
+	_err = SetDataBrowserSortOrder(_self->ob_itself,
+	                               order);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_GetDataBrowserSortOrder(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt16 order;
+#ifndef GetDataBrowserSortOrder
+	PyMac_PRECHECK(GetDataBrowserSortOrder);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetDataBrowserSortOrder(_self->ob_itself,
+	                               &order);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("H",
+	                     order);
+	return _res;
+}
+
+static PyObject *CtlObj_SetDataBrowserScrollPosition(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 top;
+	UInt32 left;
+#ifndef SetDataBrowserScrollPosition
+	PyMac_PRECHECK(SetDataBrowserScrollPosition);
+#endif
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &top,
+	                      &left))
+		return NULL;
+	_err = SetDataBrowserScrollPosition(_self->ob_itself,
+	                                    top,
+	                                    left);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_GetDataBrowserScrollPosition(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 top;
+	UInt32 left;
+#ifndef GetDataBrowserScrollPosition
+	PyMac_PRECHECK(GetDataBrowserScrollPosition);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetDataBrowserScrollPosition(_self->ob_itself,
+	                                    &top,
+	                                    &left);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("ll",
+	                     top,
+	                     left);
+	return _res;
+}
+
+static PyObject *CtlObj_SetDataBrowserHasScrollBars(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Boolean horiz;
+	Boolean vert;
+#ifndef SetDataBrowserHasScrollBars
+	PyMac_PRECHECK(SetDataBrowserHasScrollBars);
+#endif
+	if (!PyArg_ParseTuple(_args, "bb",
+	                      &horiz,
+	                      &vert))
+		return NULL;
+	_err = SetDataBrowserHasScrollBars(_self->ob_itself,
+	                                   horiz,
+	                                   vert);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_GetDataBrowserHasScrollBars(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Boolean horiz;
+	Boolean vert;
+#ifndef GetDataBrowserHasScrollBars
+	PyMac_PRECHECK(GetDataBrowserHasScrollBars);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetDataBrowserHasScrollBars(_self->ob_itself,
+	                                   &horiz,
+	                                   &vert);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("bb",
+	                     horiz,
+	                     vert);
+	return _res;
+}
+
+static PyObject *CtlObj_SetDataBrowserSortProperty(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 property;
+#ifndef SetDataBrowserSortProperty
+	PyMac_PRECHECK(SetDataBrowserSortProperty);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &property))
+		return NULL;
+	_err = SetDataBrowserSortProperty(_self->ob_itself,
+	                                  property);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_GetDataBrowserSortProperty(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 property;
+#ifndef GetDataBrowserSortProperty
+	PyMac_PRECHECK(GetDataBrowserSortProperty);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetDataBrowserSortProperty(_self->ob_itself,
+	                                  &property);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     property);
+	return _res;
+}
+
+static PyObject *CtlObj_SetDataBrowserSelectionFlags(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 selectionFlags;
+#ifndef SetDataBrowserSelectionFlags
+	PyMac_PRECHECK(SetDataBrowserSelectionFlags);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &selectionFlags))
+		return NULL;
+	_err = SetDataBrowserSelectionFlags(_self->ob_itself,
+	                                    selectionFlags);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_GetDataBrowserSelectionFlags(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 selectionFlags;
+#ifndef GetDataBrowserSelectionFlags
+	PyMac_PRECHECK(GetDataBrowserSelectionFlags);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetDataBrowserSelectionFlags(_self->ob_itself,
+	                                    &selectionFlags);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     selectionFlags);
+	return _res;
+}
+
+static PyObject *CtlObj_SetDataBrowserPropertyFlags(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 property;
+	UInt32 flags;
+#ifndef SetDataBrowserPropertyFlags
+	PyMac_PRECHECK(SetDataBrowserPropertyFlags);
+#endif
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &property,
+	                      &flags))
+		return NULL;
+	_err = SetDataBrowserPropertyFlags(_self->ob_itself,
+	                                   property,
+	                                   flags);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_GetDataBrowserPropertyFlags(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 property;
+	UInt32 flags;
+#ifndef GetDataBrowserPropertyFlags
+	PyMac_PRECHECK(GetDataBrowserPropertyFlags);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &property))
+		return NULL;
+	_err = GetDataBrowserPropertyFlags(_self->ob_itself,
+	                                   property,
+	                                   &flags);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     flags);
+	return _res;
+}
+
+static PyObject *CtlObj_SetDataBrowserEditText(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	CFStringRef text;
+#ifndef SetDataBrowserEditText
+	PyMac_PRECHECK(SetDataBrowserEditText);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CFStringRefObj_Convert, &text))
+		return NULL;
+	_err = SetDataBrowserEditText(_self->ob_itself,
+	                              text);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_CopyDataBrowserEditText(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	CFStringRef text;
+#ifndef CopyDataBrowserEditText
+	PyMac_PRECHECK(CopyDataBrowserEditText);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = CopyDataBrowserEditText(_self->ob_itself,
+	                               &text);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, text);
+	return _res;
+}
+
+static PyObject *CtlObj_GetDataBrowserEditText(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	CFMutableStringRef text;
+#ifndef GetDataBrowserEditText
+	PyMac_PRECHECK(GetDataBrowserEditText);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CFMutableStringRefObj_Convert, &text))
+		return NULL;
+	_err = GetDataBrowserEditText(_self->ob_itself,
+	                              text);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_SetDataBrowserEditItem(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 item;
+	UInt32 property;
+#ifndef SetDataBrowserEditItem
+	PyMac_PRECHECK(SetDataBrowserEditItem);
+#endif
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &item,
+	                      &property))
+		return NULL;
+	_err = SetDataBrowserEditItem(_self->ob_itself,
+	                              item,
+	                              property);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_GetDataBrowserEditItem(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 item;
+	UInt32 property;
+#ifndef GetDataBrowserEditItem
+	PyMac_PRECHECK(GetDataBrowserEditItem);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetDataBrowserEditItem(_self->ob_itself,
+	                              &item,
+	                              &property);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("ll",
+	                     item,
+	                     property);
+	return _res;
+}
+
+static PyObject *CtlObj_GetDataBrowserItemPartBounds(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 item;
+	UInt32 property;
+	OSType part;
+	Rect bounds;
+#ifndef GetDataBrowserItemPartBounds
+	PyMac_PRECHECK(GetDataBrowserItemPartBounds);
+#endif
+	if (!PyArg_ParseTuple(_args, "llO&",
+	                      &item,
+	                      &property,
+	                      PyMac_GetOSType, &part))
+		return NULL;
+	_err = GetDataBrowserItemPartBounds(_self->ob_itself,
+	                                    item,
+	                                    property,
+	                                    part,
+	                                    &bounds);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildRect, &bounds);
+	return _res;
+}
+
+static PyObject *CtlObj_RemoveDataBrowserTableViewColumn(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 column;
+#ifndef RemoveDataBrowserTableViewColumn
+	PyMac_PRECHECK(RemoveDataBrowserTableViewColumn);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &column))
+		return NULL;
+	_err = RemoveDataBrowserTableViewColumn(_self->ob_itself,
+	                                        column);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_GetDataBrowserTableViewColumnCount(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 numColumns;
+#ifndef GetDataBrowserTableViewColumnCount
+	PyMac_PRECHECK(GetDataBrowserTableViewColumnCount);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetDataBrowserTableViewColumnCount(_self->ob_itself,
+	                                          &numColumns);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     numColumns);
+	return _res;
+}
+
+static PyObject *CtlObj_SetDataBrowserTableViewHiliteStyle(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 hiliteStyle;
+#ifndef SetDataBrowserTableViewHiliteStyle
+	PyMac_PRECHECK(SetDataBrowserTableViewHiliteStyle);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &hiliteStyle))
+		return NULL;
+	_err = SetDataBrowserTableViewHiliteStyle(_self->ob_itself,
+	                                          hiliteStyle);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_GetDataBrowserTableViewHiliteStyle(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 hiliteStyle;
+#ifndef GetDataBrowserTableViewHiliteStyle
+	PyMac_PRECHECK(GetDataBrowserTableViewHiliteStyle);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetDataBrowserTableViewHiliteStyle(_self->ob_itself,
+	                                          &hiliteStyle);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     hiliteStyle);
+	return _res;
+}
+
+static PyObject *CtlObj_SetDataBrowserTableViewRowHeight(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt16 height;
+#ifndef SetDataBrowserTableViewRowHeight
+	PyMac_PRECHECK(SetDataBrowserTableViewRowHeight);
+#endif
+	if (!PyArg_ParseTuple(_args, "H",
+	                      &height))
+		return NULL;
+	_err = SetDataBrowserTableViewRowHeight(_self->ob_itself,
+	                                        height);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_GetDataBrowserTableViewRowHeight(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt16 height;
+#ifndef GetDataBrowserTableViewRowHeight
+	PyMac_PRECHECK(GetDataBrowserTableViewRowHeight);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetDataBrowserTableViewRowHeight(_self->ob_itself,
+	                                        &height);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("H",
+	                     height);
+	return _res;
+}
+
+static PyObject *CtlObj_SetDataBrowserTableViewColumnWidth(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt16 width;
+#ifndef SetDataBrowserTableViewColumnWidth
+	PyMac_PRECHECK(SetDataBrowserTableViewColumnWidth);
+#endif
+	if (!PyArg_ParseTuple(_args, "H",
+	                      &width))
+		return NULL;
+	_err = SetDataBrowserTableViewColumnWidth(_self->ob_itself,
+	                                          width);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_GetDataBrowserTableViewColumnWidth(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt16 width;
+#ifndef GetDataBrowserTableViewColumnWidth
+	PyMac_PRECHECK(GetDataBrowserTableViewColumnWidth);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetDataBrowserTableViewColumnWidth(_self->ob_itself,
+	                                          &width);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("H",
+	                     width);
+	return _res;
+}
+
+static PyObject *CtlObj_SetDataBrowserTableViewItemRowHeight(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 item;
+	UInt16 height;
+#ifndef SetDataBrowserTableViewItemRowHeight
+	PyMac_PRECHECK(SetDataBrowserTableViewItemRowHeight);
+#endif
+	if (!PyArg_ParseTuple(_args, "lH",
+	                      &item,
+	                      &height))
+		return NULL;
+	_err = SetDataBrowserTableViewItemRowHeight(_self->ob_itself,
+	                                            item,
+	                                            height);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_GetDataBrowserTableViewItemRowHeight(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 item;
+	UInt16 height;
+#ifndef GetDataBrowserTableViewItemRowHeight
+	PyMac_PRECHECK(GetDataBrowserTableViewItemRowHeight);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &item))
+		return NULL;
+	_err = GetDataBrowserTableViewItemRowHeight(_self->ob_itself,
+	                                            item,
+	                                            &height);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("H",
+	                     height);
+	return _res;
+}
+
+static PyObject *CtlObj_SetDataBrowserTableViewNamedColumnWidth(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 column;
+	UInt16 width;
+#ifndef SetDataBrowserTableViewNamedColumnWidth
+	PyMac_PRECHECK(SetDataBrowserTableViewNamedColumnWidth);
+#endif
+	if (!PyArg_ParseTuple(_args, "lH",
+	                      &column,
+	                      &width))
+		return NULL;
+	_err = SetDataBrowserTableViewNamedColumnWidth(_self->ob_itself,
+	                                               column,
+	                                               width);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_GetDataBrowserTableViewNamedColumnWidth(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 column;
+	UInt16 width;
+#ifndef GetDataBrowserTableViewNamedColumnWidth
+	PyMac_PRECHECK(GetDataBrowserTableViewNamedColumnWidth);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &column))
+		return NULL;
+	_err = GetDataBrowserTableViewNamedColumnWidth(_self->ob_itself,
+	                                               column,
+	                                               &width);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("H",
+	                     width);
+	return _res;
+}
+
+static PyObject *CtlObj_SetDataBrowserTableViewGeometry(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Boolean variableWidthColumns;
+	Boolean variableHeightRows;
+#ifndef SetDataBrowserTableViewGeometry
+	PyMac_PRECHECK(SetDataBrowserTableViewGeometry);
+#endif
+	if (!PyArg_ParseTuple(_args, "bb",
+	                      &variableWidthColumns,
+	                      &variableHeightRows))
+		return NULL;
+	_err = SetDataBrowserTableViewGeometry(_self->ob_itself,
+	                                       variableWidthColumns,
+	                                       variableHeightRows);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_GetDataBrowserTableViewGeometry(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Boolean variableWidthColumns;
+	Boolean variableHeightRows;
+#ifndef GetDataBrowserTableViewGeometry
+	PyMac_PRECHECK(GetDataBrowserTableViewGeometry);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetDataBrowserTableViewGeometry(_self->ob_itself,
+	                                       &variableWidthColumns,
+	                                       &variableHeightRows);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("bb",
+	                     variableWidthColumns,
+	                     variableHeightRows);
+	return _res;
+}
+
+static PyObject *CtlObj_GetDataBrowserTableViewItemID(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 row;
+	UInt32 item;
+#ifndef GetDataBrowserTableViewItemID
+	PyMac_PRECHECK(GetDataBrowserTableViewItemID);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &row))
+		return NULL;
+	_err = GetDataBrowserTableViewItemID(_self->ob_itself,
+	                                     row,
+	                                     &item);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     item);
+	return _res;
+}
+
+static PyObject *CtlObj_SetDataBrowserTableViewItemRow(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 item;
+	UInt32 row;
+#ifndef SetDataBrowserTableViewItemRow
+	PyMac_PRECHECK(SetDataBrowserTableViewItemRow);
+#endif
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &item,
+	                      &row))
+		return NULL;
+	_err = SetDataBrowserTableViewItemRow(_self->ob_itself,
+	                                      item,
+	                                      row);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_GetDataBrowserTableViewItemRow(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 item;
+	UInt32 row;
+#ifndef GetDataBrowserTableViewItemRow
+	PyMac_PRECHECK(GetDataBrowserTableViewItemRow);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &item))
+		return NULL;
+	_err = GetDataBrowserTableViewItemRow(_self->ob_itself,
+	                                      item,
+	                                      &row);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     row);
+	return _res;
+}
+
+static PyObject *CtlObj_SetDataBrowserTableViewColumnPosition(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 column;
+	UInt32 position;
+#ifndef SetDataBrowserTableViewColumnPosition
+	PyMac_PRECHECK(SetDataBrowserTableViewColumnPosition);
+#endif
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &column,
+	                      &position))
+		return NULL;
+	_err = SetDataBrowserTableViewColumnPosition(_self->ob_itself,
+	                                             column,
+	                                             position);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_GetDataBrowserTableViewColumnPosition(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 column;
+	UInt32 position;
+#ifndef GetDataBrowserTableViewColumnPosition
+	PyMac_PRECHECK(GetDataBrowserTableViewColumnPosition);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &column))
+		return NULL;
+	_err = GetDataBrowserTableViewColumnPosition(_self->ob_itself,
+	                                             column,
+	                                             &position);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     position);
+	return _res;
+}
+
+static PyObject *CtlObj_GetDataBrowserTableViewColumnProperty(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 column;
+	UInt32 property;
+#ifndef GetDataBrowserTableViewColumnProperty
+	PyMac_PRECHECK(GetDataBrowserTableViewColumnProperty);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &column))
+		return NULL;
+	_err = GetDataBrowserTableViewColumnProperty(_self->ob_itself,
+	                                             column,
+	                                             &property);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     property);
+	return _res;
+}
+
+static PyObject *CtlObj_AutoSizeDataBrowserListViewColumns(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+#ifndef AutoSizeDataBrowserListViewColumns
+	PyMac_PRECHECK(AutoSizeDataBrowserListViewColumns);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = AutoSizeDataBrowserListViewColumns(_self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_AddDataBrowserListViewColumn(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	DataBrowserListViewColumnDesc columnDesc;
+	UInt32 position;
+#ifndef AddDataBrowserListViewColumn
+	PyMac_PRECHECK(AddDataBrowserListViewColumn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      DataBrowserListViewColumnDesc_Convert, &columnDesc,
+	                      &position))
+		return NULL;
+	_err = AddDataBrowserListViewColumn(_self->ob_itself,
+	                                    &columnDesc,
+	                                    position);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_SetDataBrowserListViewHeaderBtnHeight(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt16 height;
+#ifndef SetDataBrowserListViewHeaderBtnHeight
+	PyMac_PRECHECK(SetDataBrowserListViewHeaderBtnHeight);
+#endif
+	if (!PyArg_ParseTuple(_args, "H",
+	                      &height))
+		return NULL;
+	_err = SetDataBrowserListViewHeaderBtnHeight(_self->ob_itself,
+	                                             height);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_GetDataBrowserListViewHeaderBtnHeight(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt16 height;
+#ifndef GetDataBrowserListViewHeaderBtnHeight
+	PyMac_PRECHECK(GetDataBrowserListViewHeaderBtnHeight);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetDataBrowserListViewHeaderBtnHeight(_self->ob_itself,
+	                                             &height);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("H",
+	                     height);
+	return _res;
+}
+
+static PyObject *CtlObj_SetDataBrowserListViewUsePlainBackground(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Boolean usePlainBackground;
+#ifndef SetDataBrowserListViewUsePlainBackground
+	PyMac_PRECHECK(SetDataBrowserListViewUsePlainBackground);
+#endif
+	if (!PyArg_ParseTuple(_args, "b",
+	                      &usePlainBackground))
+		return NULL;
+	_err = SetDataBrowserListViewUsePlainBackground(_self->ob_itself,
+	                                                usePlainBackground);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_GetDataBrowserListViewUsePlainBackground(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Boolean usePlainBackground;
+#ifndef GetDataBrowserListViewUsePlainBackground
+	PyMac_PRECHECK(GetDataBrowserListViewUsePlainBackground);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetDataBrowserListViewUsePlainBackground(_self->ob_itself,
+	                                                &usePlainBackground);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("b",
+	                     usePlainBackground);
+	return _res;
+}
+
+static PyObject *CtlObj_SetDataBrowserListViewDisclosureColumn(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 column;
+	Boolean expandableRows;
+#ifndef SetDataBrowserListViewDisclosureColumn
+	PyMac_PRECHECK(SetDataBrowserListViewDisclosureColumn);
+#endif
+	if (!PyArg_ParseTuple(_args, "lb",
+	                      &column,
+	                      &expandableRows))
+		return NULL;
+	_err = SetDataBrowserListViewDisclosureColumn(_self->ob_itself,
+	                                              column,
+	                                              expandableRows);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_GetDataBrowserListViewDisclosureColumn(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 column;
+	Boolean expandableRows;
+#ifndef GetDataBrowserListViewDisclosureColumn
+	PyMac_PRECHECK(GetDataBrowserListViewDisclosureColumn);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetDataBrowserListViewDisclosureColumn(_self->ob_itself,
+	                                              &column,
+	                                              &expandableRows);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("lb",
+	                     column,
+	                     expandableRows);
+	return _res;
+}
+
+static PyObject *CtlObj_GetDataBrowserColumnViewPath(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Handle path;
+#ifndef GetDataBrowserColumnViewPath
+	PyMac_PRECHECK(GetDataBrowserColumnViewPath);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &path))
+		return NULL;
+	_err = GetDataBrowserColumnViewPath(_self->ob_itself,
+	                                    path);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_GetDataBrowserColumnViewPathLength(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 pathLength;
+#ifndef GetDataBrowserColumnViewPathLength
+	PyMac_PRECHECK(GetDataBrowserColumnViewPathLength);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetDataBrowserColumnViewPathLength(_self->ob_itself,
+	                                          &pathLength);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     pathLength);
+	return _res;
+}
+
+static PyObject *CtlObj_SetDataBrowserColumnViewDisplayType(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	OSType propertyType;
+#ifndef SetDataBrowserColumnViewDisplayType
+	PyMac_PRECHECK(SetDataBrowserColumnViewDisplayType);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetOSType, &propertyType))
+		return NULL;
+	_err = SetDataBrowserColumnViewDisplayType(_self->ob_itself,
+	                                           propertyType);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *CtlObj_GetDataBrowserColumnViewDisplayType(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	OSType propertyType;
+#ifndef GetDataBrowserColumnViewDisplayType
+	PyMac_PRECHECK(GetDataBrowserColumnViewDisplayType);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetDataBrowserColumnViewDisplayType(_self->ob_itself,
+	                                           &propertyType);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildOSType, propertyType);
+	return _res;
+}
+
+static PyObject *CtlObj_as_Resource(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Handle _rv;
+#ifndef as_Resource
+	PyMac_PRECHECK(as_Resource);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = as_Resource(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CtlObj_GetControlRect(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect rect;
+#ifndef GetControlRect
+	PyMac_PRECHECK(GetControlRect);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	GetControlRect(_self->ob_itself,
+	               &rect);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildRect, &rect);
+	return _res;
+}
+
+static PyObject *CtlObj_DisposeControl(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+
+	        if (!PyArg_ParseTuple(_args, ""))
+	                return NULL;
+	        if ( _self->ob_itself ) {
+	                SetControlReference(_self->ob_itself, (long)0); /* Make it forget about us */
+	                DisposeControl(_self->ob_itself);
+	                _self->ob_itself = NULL;
+	        }
+	        Py_INCREF(Py_None);
+	        _res = Py_None;
+	        return _res;
+
+}
+
+static PyObject *CtlObj_TrackControl(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+
+	ControlPartCode _rv;
+	Point startPoint;
+	ControlActionUPP upp = 0;
+	PyObject *callback = 0;
+
+	if (!PyArg_ParseTuple(_args, "O&|O",
+	                      PyMac_GetPoint, &startPoint, &callback))
+	        return NULL;
+	if (callback && callback != Py_None) {
+	        if (PyInt_Check(callback) && PyInt_AS_LONG(callback) == -1)
+	                upp = (ControlActionUPP)-1;
+	        else {
+	                settrackfunc(callback);
+	                upp = mytracker_upp;
+	        }
+	}
+	_rv = TrackControl(_self->ob_itself,
+	                   startPoint,
+	                   upp);
+	clrtrackfunc();
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+
+}
+
+static PyObject *CtlObj_HandleControlClick(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+
+	ControlPartCode _rv;
+	Point startPoint;
+	SInt16 modifiers;
+	ControlActionUPP upp = 0;
+	PyObject *callback = 0;
+
+	if (!PyArg_ParseTuple(_args, "O&h|O",
+	                      PyMac_GetPoint, &startPoint,
+	                      &modifiers,
+	                      &callback))
+	        return NULL;
+	if (callback && callback != Py_None) {
+	        if (PyInt_Check(callback) && PyInt_AS_LONG(callback) == -1)
+	                upp = (ControlActionUPP)-1;
+	        else {
+	                settrackfunc(callback);
+	                upp = mytracker_upp;
+	        }
+	}
+	_rv = HandleControlClick(_self->ob_itself,
+	                   startPoint,
+	                   modifiers,
+	                   upp);
+	clrtrackfunc();
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+
+}
+
+static PyObject *CtlObj_SetControlData(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+
+	OSErr _err;
+	ControlPartCode inPart;
+	ResType inTagName;
+	Size bufferSize;
+	Ptr buffer;
+
+	if (!PyArg_ParseTuple(_args, "hO&s#",
+	                      &inPart,
+	                      PyMac_GetOSType, &inTagName,
+	                      &buffer, &bufferSize))
+	        return NULL;
+
+	_err = SetControlData(_self->ob_itself,
+	                      inPart,
+	                      inTagName,
+	                      bufferSize,
+	                      buffer);
+
+	if (_err != noErr)
+	        return PyMac_Error(_err);
+	_res = Py_None;
+	return _res;
+
+}
+
+static PyObject *CtlObj_GetControlData(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+
+	OSErr _err;
+	ControlPartCode inPart;
+	ResType inTagName;
+	Size bufferSize;
+	Ptr buffer;
+	Size outSize;
+
+	if (!PyArg_ParseTuple(_args, "hO&",
+	                      &inPart,
+	                      PyMac_GetOSType, &inTagName))
+	        return NULL;
+
+	/* allocate a buffer for the data */
+	_err = GetControlDataSize(_self->ob_itself,
+	                          inPart,
+	                          inTagName,
+	                          &bufferSize);
+	if (_err != noErr)
+	        return PyMac_Error(_err);
+	buffer = PyMem_NEW(char, bufferSize);
+	if (buffer == NULL)
+	        return PyErr_NoMemory();
+
+	_err = GetControlData(_self->ob_itself,
+	                      inPart,
+	                      inTagName,
+	                      bufferSize,
+	                      buffer,
+	                      &outSize);
+
+	if (_err != noErr) {
+	        PyMem_DEL(buffer);
+	        return PyMac_Error(_err);
+	}
+	_res = Py_BuildValue("s#", buffer, outSize);
+	PyMem_DEL(buffer);
+	return _res;
+
+}
+
+static PyObject *CtlObj_SetControlData_Handle(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+
+	OSErr _err;
+	ControlPartCode inPart;
+	ResType inTagName;
+	Handle buffer;
+
+	if (!PyArg_ParseTuple(_args, "hO&O&",
+	                      &inPart,
+	                      PyMac_GetOSType, &inTagName,
+	                      OptResObj_Convert, &buffer))
+	        return NULL;
+
+	_err = SetControlData(_self->ob_itself,
+	                      inPart,
+	                      inTagName,
+	                      sizeof(buffer),
+	                      (Ptr)&buffer);
+
+	if (_err != noErr)
+	        return PyMac_Error(_err);
+	_res = Py_None;
+	return _res;
+
+}
+
+static PyObject *CtlObj_GetControlData_Handle(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+
+	OSErr _err;
+	ControlPartCode inPart;
+	ResType inTagName;
+	Size bufferSize;
+	Handle hdl;
+
+	if (!PyArg_ParseTuple(_args, "hO&",
+	                      &inPart,
+	                      PyMac_GetOSType, &inTagName))
+	        return NULL;
+
+	/* Check it is handle-sized */
+	_err = GetControlDataSize(_self->ob_itself,
+	                          inPart,
+	                          inTagName,
+	                          &bufferSize);
+	if (_err != noErr)
+	        return PyMac_Error(_err);
+	if (bufferSize != sizeof(Handle)) {
+	        PyErr_SetString(Ctl_Error, "GetControlDataSize() != sizeof(Handle)");
+	        return NULL;
+	}
+
+	_err = GetControlData(_self->ob_itself,
+	                      inPart,
+	                      inTagName,
+	                      sizeof(Handle),
+	                      (Ptr)&hdl,
+	                      &bufferSize);
+
+	if (_err != noErr) {
+	        return PyMac_Error(_err);
+	}
+	_res = Py_BuildValue("O&", OptResObj_New, hdl);
+	return _res;
+
+}
+
+static PyObject *CtlObj_SetControlData_Callback(ControlObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+
+	OSErr _err;
+	ControlPartCode inPart;
+	ResType inTagName;
+	PyObject *callback;
+	UniversalProcPtr c_callback;
+
+	if (!PyArg_ParseTuple(_args, "hO&O",
+	                      &inPart,
+	                      PyMac_GetOSType, &inTagName,
+	                      &callback))
+	        return NULL;
+
+	if ( setcallback((PyObject *)_self, inTagName, callback, &c_callback) < 0 )
+	        return NULL;
+	_err = SetControlData(_self->ob_itself,
+	                      inPart,
+	                      inTagName,
+	                      sizeof(c_callback),
+	                      (Ptr)&c_callback);
+
+	if (_err != noErr)
+	        return PyMac_Error(_err);
+	_res = Py_None;
+	return _res;
+
+}
+
+static PyMethodDef CtlObj_methods[] = {
+	{"HiliteControl", (PyCFunction)CtlObj_HiliteControl, 1,
+	 PyDoc_STR("(ControlPartCode hiliteState) -> None")},
+	{"ShowControl", (PyCFunction)CtlObj_ShowControl, 1,
+	 PyDoc_STR("() -> None")},
+	{"HideControl", (PyCFunction)CtlObj_HideControl, 1,
+	 PyDoc_STR("() -> None")},
+	{"IsControlActive", (PyCFunction)CtlObj_IsControlActive, 1,
+	 PyDoc_STR("() -> (Boolean _rv)")},
+	{"IsControlVisible", (PyCFunction)CtlObj_IsControlVisible, 1,
+	 PyDoc_STR("() -> (Boolean _rv)")},
+	{"ActivateControl", (PyCFunction)CtlObj_ActivateControl, 1,
+	 PyDoc_STR("() -> None")},
+	{"DeactivateControl", (PyCFunction)CtlObj_DeactivateControl, 1,
+	 PyDoc_STR("() -> None")},
+	{"SetControlVisibility", (PyCFunction)CtlObj_SetControlVisibility, 1,
+	 PyDoc_STR("(Boolean inIsVisible, Boolean inDoDraw) -> None")},
+	{"IsControlEnabled", (PyCFunction)CtlObj_IsControlEnabled, 1,
+	 PyDoc_STR("() -> (Boolean _rv)")},
+	{"EnableControl", (PyCFunction)CtlObj_EnableControl, 1,
+	 PyDoc_STR("() -> None")},
+	{"DisableControl", (PyCFunction)CtlObj_DisableControl, 1,
+	 PyDoc_STR("() -> None")},
+	{"Draw1Control", (PyCFunction)CtlObj_Draw1Control, 1,
+	 PyDoc_STR("() -> None")},
+	{"GetBestControlRect", (PyCFunction)CtlObj_GetBestControlRect, 1,
+	 PyDoc_STR("() -> (Rect outRect, SInt16 outBaseLineOffset)")},
+	{"SetControlFontStyle", (PyCFunction)CtlObj_SetControlFontStyle, 1,
+	 PyDoc_STR("(ControlFontStyleRec inStyle) -> None")},
+	{"DrawControlInCurrentPort", (PyCFunction)CtlObj_DrawControlInCurrentPort, 1,
+	 PyDoc_STR("() -> None")},
+	{"SetUpControlBackground", (PyCFunction)CtlObj_SetUpControlBackground, 1,
+	 PyDoc_STR("(SInt16 inDepth, Boolean inIsColorDevice) -> None")},
+	{"SetUpControlTextColor", (PyCFunction)CtlObj_SetUpControlTextColor, 1,
+	 PyDoc_STR("(SInt16 inDepth, Boolean inIsColorDevice) -> None")},
+	{"DragControl", (PyCFunction)CtlObj_DragControl, 1,
+	 PyDoc_STR("(Point startPoint, Rect limitRect, Rect slopRect, DragConstraint axis) -> None")},
+	{"TestControl", (PyCFunction)CtlObj_TestControl, 1,
+	 PyDoc_STR("(Point testPoint) -> (ControlPartCode _rv)")},
+	{"HandleControlContextualMenuClick", (PyCFunction)CtlObj_HandleControlContextualMenuClick, 1,
+	 PyDoc_STR("(Point inWhere) -> (Boolean menuDisplayed)")},
+	{"GetControlClickActivation", (PyCFunction)CtlObj_GetControlClickActivation, 1,
+	 PyDoc_STR("(Point inWhere, EventModifiers inModifiers) -> (ClickActivationResult outResult)")},
+	{"HandleControlKey", (PyCFunction)CtlObj_HandleControlKey, 1,
+	 PyDoc_STR("(SInt16 inKeyCode, SInt16 inCharCode, EventModifiers inModifiers) -> (ControlPartCode _rv)")},
+	{"HandleControlSetCursor", (PyCFunction)CtlObj_HandleControlSetCursor, 1,
+	 PyDoc_STR("(Point localPoint, EventModifiers modifiers) -> (Boolean cursorWasSet)")},
+	{"MoveControl", (PyCFunction)CtlObj_MoveControl, 1,
+	 PyDoc_STR("(SInt16 h, SInt16 v) -> None")},
+	{"SizeControl", (PyCFunction)CtlObj_SizeControl, 1,
+	 PyDoc_STR("(SInt16 w, SInt16 h) -> None")},
+	{"SetControlTitle", (PyCFunction)CtlObj_SetControlTitle, 1,
+	 PyDoc_STR("(Str255 title) -> None")},
+	{"GetControlTitle", (PyCFunction)CtlObj_GetControlTitle, 1,
+	 PyDoc_STR("() -> (Str255 title)")},
+	{"SetControlTitleWithCFString", (PyCFunction)CtlObj_SetControlTitleWithCFString, 1,
+	 PyDoc_STR("(CFStringRef inString) -> None")},
+	{"CopyControlTitleAsCFString", (PyCFunction)CtlObj_CopyControlTitleAsCFString, 1,
+	 PyDoc_STR("() -> (CFStringRef outString)")},
+	{"GetControlValue", (PyCFunction)CtlObj_GetControlValue, 1,
+	 PyDoc_STR("() -> (SInt16 _rv)")},
+	{"SetControlValue", (PyCFunction)CtlObj_SetControlValue, 1,
+	 PyDoc_STR("(SInt16 newValue) -> None")},
+	{"GetControlMinimum", (PyCFunction)CtlObj_GetControlMinimum, 1,
+	 PyDoc_STR("() -> (SInt16 _rv)")},
+	{"SetControlMinimum", (PyCFunction)CtlObj_SetControlMinimum, 1,
+	 PyDoc_STR("(SInt16 newMinimum) -> None")},
+	{"GetControlMaximum", (PyCFunction)CtlObj_GetControlMaximum, 1,
+	 PyDoc_STR("() -> (SInt16 _rv)")},
+	{"SetControlMaximum", (PyCFunction)CtlObj_SetControlMaximum, 1,
+	 PyDoc_STR("(SInt16 newMaximum) -> None")},
+	{"GetControlViewSize", (PyCFunction)CtlObj_GetControlViewSize, 1,
+	 PyDoc_STR("() -> (SInt32 _rv)")},
+	{"SetControlViewSize", (PyCFunction)CtlObj_SetControlViewSize, 1,
+	 PyDoc_STR("(SInt32 newViewSize) -> None")},
+	{"GetControl32BitValue", (PyCFunction)CtlObj_GetControl32BitValue, 1,
+	 PyDoc_STR("() -> (SInt32 _rv)")},
+	{"SetControl32BitValue", (PyCFunction)CtlObj_SetControl32BitValue, 1,
+	 PyDoc_STR("(SInt32 newValue) -> None")},
+	{"GetControl32BitMaximum", (PyCFunction)CtlObj_GetControl32BitMaximum, 1,
+	 PyDoc_STR("() -> (SInt32 _rv)")},
+	{"SetControl32BitMaximum", (PyCFunction)CtlObj_SetControl32BitMaximum, 1,
+	 PyDoc_STR("(SInt32 newMaximum) -> None")},
+	{"GetControl32BitMinimum", (PyCFunction)CtlObj_GetControl32BitMinimum, 1,
+	 PyDoc_STR("() -> (SInt32 _rv)")},
+	{"SetControl32BitMinimum", (PyCFunction)CtlObj_SetControl32BitMinimum, 1,
+	 PyDoc_STR("(SInt32 newMinimum) -> None")},
+	{"IsValidControlHandle", (PyCFunction)CtlObj_IsValidControlHandle, 1,
+	 PyDoc_STR("() -> (Boolean _rv)")},
+	{"SetControlID", (PyCFunction)CtlObj_SetControlID, 1,
+	 PyDoc_STR("(ControlID inID) -> None")},
+	{"GetControlID", (PyCFunction)CtlObj_GetControlID, 1,
+	 PyDoc_STR("() -> (ControlID outID)")},
+	{"SetControlCommandID", (PyCFunction)CtlObj_SetControlCommandID, 1,
+	 PyDoc_STR("(UInt32 inCommandID) -> None")},
+	{"GetControlCommandID", (PyCFunction)CtlObj_GetControlCommandID, 1,
+	 PyDoc_STR("() -> (UInt32 outCommandID)")},
+	{"RemoveControlProperty", (PyCFunction)CtlObj_RemoveControlProperty, 1,
+	 PyDoc_STR("(OSType propertyCreator, OSType propertyTag) -> None")},
+	{"GetControlPropertyAttributes", (PyCFunction)CtlObj_GetControlPropertyAttributes, 1,
+	 PyDoc_STR("(OSType propertyCreator, OSType propertyTag) -> (UInt32 attributes)")},
+	{"ChangeControlPropertyAttributes", (PyCFunction)CtlObj_ChangeControlPropertyAttributes, 1,
+	 PyDoc_STR("(OSType propertyCreator, OSType propertyTag, UInt32 attributesToSet, UInt32 attributesToClear) -> None")},
+	{"GetControlRegion", (PyCFunction)CtlObj_GetControlRegion, 1,
+	 PyDoc_STR("(ControlPartCode inPart, RgnHandle outRegion) -> None")},
+	{"GetControlVariant", (PyCFunction)CtlObj_GetControlVariant, 1,
+	 PyDoc_STR("() -> (ControlVariant _rv)")},
+	{"SetControlAction", (PyCFunction)CtlObj_SetControlAction, 1,
+	 PyDoc_STR("(PyObject* actionProc) -> None")},
+	{"SetControlReference", (PyCFunction)CtlObj_SetControlReference, 1,
+	 PyDoc_STR("(SInt32 data) -> None")},
+	{"GetControlReference", (PyCFunction)CtlObj_GetControlReference, 1,
+	 PyDoc_STR("() -> (SInt32 _rv)")},
+	{"EmbedControl", (PyCFunction)CtlObj_EmbedControl, 1,
+	 PyDoc_STR("(ControlHandle inContainer) -> None")},
+	{"AutoEmbedControl", (PyCFunction)CtlObj_AutoEmbedControl, 1,
+	 PyDoc_STR("(WindowPtr inWindow) -> None")},
+	{"GetSuperControl", (PyCFunction)CtlObj_GetSuperControl, 1,
+	 PyDoc_STR("() -> (ControlHandle outParent)")},
+	{"CountSubControls", (PyCFunction)CtlObj_CountSubControls, 1,
+	 PyDoc_STR("() -> (UInt16 outNumChildren)")},
+	{"GetIndexedSubControl", (PyCFunction)CtlObj_GetIndexedSubControl, 1,
+	 PyDoc_STR("(UInt16 inIndex) -> (ControlHandle outSubControl)")},
+	{"SetControlSupervisor", (PyCFunction)CtlObj_SetControlSupervisor, 1,
+	 PyDoc_STR("(ControlHandle inBoss) -> None")},
+	{"GetControlFeatures", (PyCFunction)CtlObj_GetControlFeatures, 1,
+	 PyDoc_STR("() -> (UInt32 outFeatures)")},
+	{"GetControlDataSize", (PyCFunction)CtlObj_GetControlDataSize, 1,
+	 PyDoc_STR("(ControlPartCode inPart, ResType inTagName) -> (Size outMaxSize)")},
+	{"HandleControlDragTracking", (PyCFunction)CtlObj_HandleControlDragTracking, 1,
+	 PyDoc_STR("(DragTrackingMessage inMessage, DragReference inDrag) -> (Boolean outLikesDrag)")},
+	{"HandleControlDragReceive", (PyCFunction)CtlObj_HandleControlDragReceive, 1,
+	 PyDoc_STR("(DragReference inDrag) -> None")},
+	{"SetControlDragTrackingEnabled", (PyCFunction)CtlObj_SetControlDragTrackingEnabled, 1,
+	 PyDoc_STR("(Boolean inTracks) -> None")},
+	{"IsControlDragTrackingEnabled", (PyCFunction)CtlObj_IsControlDragTrackingEnabled, 1,
+	 PyDoc_STR("() -> (Boolean outTracks)")},
+	{"GetControlBounds", (PyCFunction)CtlObj_GetControlBounds, 1,
+	 PyDoc_STR("() -> (Rect bounds)")},
+	{"IsControlHilited", (PyCFunction)CtlObj_IsControlHilited, 1,
+	 PyDoc_STR("() -> (Boolean _rv)")},
+	{"GetControlHilite", (PyCFunction)CtlObj_GetControlHilite, 1,
+	 PyDoc_STR("() -> (UInt16 _rv)")},
+	{"GetControlOwner", (PyCFunction)CtlObj_GetControlOwner, 1,
+	 PyDoc_STR("() -> (WindowPtr _rv)")},
+	{"GetControlDataHandle", (PyCFunction)CtlObj_GetControlDataHandle, 1,
+	 PyDoc_STR("() -> (Handle _rv)")},
+	{"GetControlPopupMenuHandle", (PyCFunction)CtlObj_GetControlPopupMenuHandle, 1,
+	 PyDoc_STR("() -> (MenuHandle _rv)")},
+	{"GetControlPopupMenuID", (PyCFunction)CtlObj_GetControlPopupMenuID, 1,
+	 PyDoc_STR("() -> (short _rv)")},
+	{"SetControlDataHandle", (PyCFunction)CtlObj_SetControlDataHandle, 1,
+	 PyDoc_STR("(Handle dataHandle) -> None")},
+	{"SetControlBounds", (PyCFunction)CtlObj_SetControlBounds, 1,
+	 PyDoc_STR("(Rect bounds) -> None")},
+	{"SetControlPopupMenuHandle", (PyCFunction)CtlObj_SetControlPopupMenuHandle, 1,
+	 PyDoc_STR("(MenuHandle popupMenu) -> None")},
+	{"SetControlPopupMenuID", (PyCFunction)CtlObj_SetControlPopupMenuID, 1,
+	 PyDoc_STR("(short menuID) -> None")},
+	{"GetBevelButtonMenuValue", (PyCFunction)CtlObj_GetBevelButtonMenuValue, 1,
+	 PyDoc_STR("() -> (SInt16 outValue)")},
+	{"SetBevelButtonMenuValue", (PyCFunction)CtlObj_SetBevelButtonMenuValue, 1,
+	 PyDoc_STR("(SInt16 inValue) -> None")},
+	{"GetBevelButtonMenuHandle", (PyCFunction)CtlObj_GetBevelButtonMenuHandle, 1,
+	 PyDoc_STR("() -> (MenuHandle outHandle)")},
+	{"SetBevelButtonContentInfo", (PyCFunction)CtlObj_SetBevelButtonContentInfo, 1,
+	 PyDoc_STR("(ControlButtonContentInfo inContent) -> None")},
+	{"SetBevelButtonTransform", (PyCFunction)CtlObj_SetBevelButtonTransform, 1,
+	 PyDoc_STR("(IconTransformType transform) -> None")},
+	{"SetDisclosureTriangleLastValue", (PyCFunction)CtlObj_SetDisclosureTriangleLastValue, 1,
+	 PyDoc_STR("(SInt16 inValue) -> None")},
+	{"GetTabContentRect", (PyCFunction)CtlObj_GetTabContentRect, 1,
+	 PyDoc_STR("() -> (Rect outContentRect)")},
+	{"SetTabEnabled", (PyCFunction)CtlObj_SetTabEnabled, 1,
+	 PyDoc_STR("(SInt16 inTabToHilite, Boolean inEnabled) -> None")},
+	{"SetImageWellContentInfo", (PyCFunction)CtlObj_SetImageWellContentInfo, 1,
+	 PyDoc_STR("(ControlButtonContentInfo inContent) -> None")},
+	{"SetImageWellTransform", (PyCFunction)CtlObj_SetImageWellTransform, 1,
+	 PyDoc_STR("(IconTransformType inTransform) -> None")},
+	{"GetDataBrowserViewStyle", (PyCFunction)CtlObj_GetDataBrowserViewStyle, 1,
+	 PyDoc_STR("() -> (OSType style)")},
+	{"SetDataBrowserViewStyle", (PyCFunction)CtlObj_SetDataBrowserViewStyle, 1,
+	 PyDoc_STR("(OSType style) -> None")},
+	{"EnableDataBrowserEditCommand", (PyCFunction)CtlObj_EnableDataBrowserEditCommand, 1,
+	 PyDoc_STR("(UInt32 command) -> (Boolean _rv)")},
+	{"ExecuteDataBrowserEditCommand", (PyCFunction)CtlObj_ExecuteDataBrowserEditCommand, 1,
+	 PyDoc_STR("(UInt32 command) -> None")},
+	{"GetDataBrowserSelectionAnchor", (PyCFunction)CtlObj_GetDataBrowserSelectionAnchor, 1,
+	 PyDoc_STR("() -> (UInt32 first, UInt32 last)")},
+	{"MoveDataBrowserSelectionAnchor", (PyCFunction)CtlObj_MoveDataBrowserSelectionAnchor, 1,
+	 PyDoc_STR("(UInt32 direction, Boolean extendSelection) -> None")},
+	{"OpenDataBrowserContainer", (PyCFunction)CtlObj_OpenDataBrowserContainer, 1,
+	 PyDoc_STR("(UInt32 container) -> None")},
+	{"CloseDataBrowserContainer", (PyCFunction)CtlObj_CloseDataBrowserContainer, 1,
+	 PyDoc_STR("(UInt32 container) -> None")},
+	{"SortDataBrowserContainer", (PyCFunction)CtlObj_SortDataBrowserContainer, 1,
+	 PyDoc_STR("(UInt32 container, Boolean sortChildren) -> None")},
+	{"GetDataBrowserItems", (PyCFunction)CtlObj_GetDataBrowserItems, 1,
+	 PyDoc_STR("(UInt32 container, Boolean recurse, UInt32 state, Handle items) -> None")},
+	{"GetDataBrowserItemCount", (PyCFunction)CtlObj_GetDataBrowserItemCount, 1,
+	 PyDoc_STR("(UInt32 container, Boolean recurse, UInt32 state) -> (UInt32 numItems)")},
+	{"IsDataBrowserItemSelected", (PyCFunction)CtlObj_IsDataBrowserItemSelected, 1,
+	 PyDoc_STR("(UInt32 item) -> (Boolean _rv)")},
+	{"GetDataBrowserItemState", (PyCFunction)CtlObj_GetDataBrowserItemState, 1,
+	 PyDoc_STR("(UInt32 item) -> (UInt32 state)")},
+	{"RevealDataBrowserItem", (PyCFunction)CtlObj_RevealDataBrowserItem, 1,
+	 PyDoc_STR("(UInt32 item, UInt32 propertyID, UInt8 options) -> None")},
+	{"SetDataBrowserActiveItems", (PyCFunction)CtlObj_SetDataBrowserActiveItems, 1,
+	 PyDoc_STR("(Boolean active) -> None")},
+	{"GetDataBrowserActiveItems", (PyCFunction)CtlObj_GetDataBrowserActiveItems, 1,
+	 PyDoc_STR("() -> (Boolean active)")},
+	{"SetDataBrowserScrollBarInset", (PyCFunction)CtlObj_SetDataBrowserScrollBarInset, 1,
+	 PyDoc_STR("() -> (Rect insetRect)")},
+	{"GetDataBrowserScrollBarInset", (PyCFunction)CtlObj_GetDataBrowserScrollBarInset, 1,
+	 PyDoc_STR("() -> (Rect insetRect)")},
+	{"SetDataBrowserTarget", (PyCFunction)CtlObj_SetDataBrowserTarget, 1,
+	 PyDoc_STR("(UInt32 target) -> None")},
+	{"GetDataBrowserTarget", (PyCFunction)CtlObj_GetDataBrowserTarget, 1,
+	 PyDoc_STR("() -> (UInt32 target)")},
+	{"SetDataBrowserSortOrder", (PyCFunction)CtlObj_SetDataBrowserSortOrder, 1,
+	 PyDoc_STR("(UInt16 order) -> None")},
+	{"GetDataBrowserSortOrder", (PyCFunction)CtlObj_GetDataBrowserSortOrder, 1,
+	 PyDoc_STR("() -> (UInt16 order)")},
+	{"SetDataBrowserScrollPosition", (PyCFunction)CtlObj_SetDataBrowserScrollPosition, 1,
+	 PyDoc_STR("(UInt32 top, UInt32 left) -> None")},
+	{"GetDataBrowserScrollPosition", (PyCFunction)CtlObj_GetDataBrowserScrollPosition, 1,
+	 PyDoc_STR("() -> (UInt32 top, UInt32 left)")},
+	{"SetDataBrowserHasScrollBars", (PyCFunction)CtlObj_SetDataBrowserHasScrollBars, 1,
+	 PyDoc_STR("(Boolean horiz, Boolean vert) -> None")},
+	{"GetDataBrowserHasScrollBars", (PyCFunction)CtlObj_GetDataBrowserHasScrollBars, 1,
+	 PyDoc_STR("() -> (Boolean horiz, Boolean vert)")},
+	{"SetDataBrowserSortProperty", (PyCFunction)CtlObj_SetDataBrowserSortProperty, 1,
+	 PyDoc_STR("(UInt32 property) -> None")},
+	{"GetDataBrowserSortProperty", (PyCFunction)CtlObj_GetDataBrowserSortProperty, 1,
+	 PyDoc_STR("() -> (UInt32 property)")},
+	{"SetDataBrowserSelectionFlags", (PyCFunction)CtlObj_SetDataBrowserSelectionFlags, 1,
+	 PyDoc_STR("(UInt32 selectionFlags) -> None")},
+	{"GetDataBrowserSelectionFlags", (PyCFunction)CtlObj_GetDataBrowserSelectionFlags, 1,
+	 PyDoc_STR("() -> (UInt32 selectionFlags)")},
+	{"SetDataBrowserPropertyFlags", (PyCFunction)CtlObj_SetDataBrowserPropertyFlags, 1,
+	 PyDoc_STR("(UInt32 property, UInt32 flags) -> None")},
+	{"GetDataBrowserPropertyFlags", (PyCFunction)CtlObj_GetDataBrowserPropertyFlags, 1,
+	 PyDoc_STR("(UInt32 property) -> (UInt32 flags)")},
+	{"SetDataBrowserEditText", (PyCFunction)CtlObj_SetDataBrowserEditText, 1,
+	 PyDoc_STR("(CFStringRef text) -> None")},
+	{"CopyDataBrowserEditText", (PyCFunction)CtlObj_CopyDataBrowserEditText, 1,
+	 PyDoc_STR("() -> (CFStringRef text)")},
+	{"GetDataBrowserEditText", (PyCFunction)CtlObj_GetDataBrowserEditText, 1,
+	 PyDoc_STR("(CFMutableStringRef text) -> None")},
+	{"SetDataBrowserEditItem", (PyCFunction)CtlObj_SetDataBrowserEditItem, 1,
+	 PyDoc_STR("(UInt32 item, UInt32 property) -> None")},
+	{"GetDataBrowserEditItem", (PyCFunction)CtlObj_GetDataBrowserEditItem, 1,
+	 PyDoc_STR("() -> (UInt32 item, UInt32 property)")},
+	{"GetDataBrowserItemPartBounds", (PyCFunction)CtlObj_GetDataBrowserItemPartBounds, 1,
+	 PyDoc_STR("(UInt32 item, UInt32 property, OSType part) -> (Rect bounds)")},
+	{"RemoveDataBrowserTableViewColumn", (PyCFunction)CtlObj_RemoveDataBrowserTableViewColumn, 1,
+	 PyDoc_STR("(UInt32 column) -> None")},
+	{"GetDataBrowserTableViewColumnCount", (PyCFunction)CtlObj_GetDataBrowserTableViewColumnCount, 1,
+	 PyDoc_STR("() -> (UInt32 numColumns)")},
+	{"SetDataBrowserTableViewHiliteStyle", (PyCFunction)CtlObj_SetDataBrowserTableViewHiliteStyle, 1,
+	 PyDoc_STR("(UInt32 hiliteStyle) -> None")},
+	{"GetDataBrowserTableViewHiliteStyle", (PyCFunction)CtlObj_GetDataBrowserTableViewHiliteStyle, 1,
+	 PyDoc_STR("() -> (UInt32 hiliteStyle)")},
+	{"SetDataBrowserTableViewRowHeight", (PyCFunction)CtlObj_SetDataBrowserTableViewRowHeight, 1,
+	 PyDoc_STR("(UInt16 height) -> None")},
+	{"GetDataBrowserTableViewRowHeight", (PyCFunction)CtlObj_GetDataBrowserTableViewRowHeight, 1,
+	 PyDoc_STR("() -> (UInt16 height)")},
+	{"SetDataBrowserTableViewColumnWidth", (PyCFunction)CtlObj_SetDataBrowserTableViewColumnWidth, 1,
+	 PyDoc_STR("(UInt16 width) -> None")},
+	{"GetDataBrowserTableViewColumnWidth", (PyCFunction)CtlObj_GetDataBrowserTableViewColumnWidth, 1,
+	 PyDoc_STR("() -> (UInt16 width)")},
+	{"SetDataBrowserTableViewItemRowHeight", (PyCFunction)CtlObj_SetDataBrowserTableViewItemRowHeight, 1,
+	 PyDoc_STR("(UInt32 item, UInt16 height) -> None")},
+	{"GetDataBrowserTableViewItemRowHeight", (PyCFunction)CtlObj_GetDataBrowserTableViewItemRowHeight, 1,
+	 PyDoc_STR("(UInt32 item) -> (UInt16 height)")},
+	{"SetDataBrowserTableViewNamedColumnWidth", (PyCFunction)CtlObj_SetDataBrowserTableViewNamedColumnWidth, 1,
+	 PyDoc_STR("(UInt32 column, UInt16 width) -> None")},
+	{"GetDataBrowserTableViewNamedColumnWidth", (PyCFunction)CtlObj_GetDataBrowserTableViewNamedColumnWidth, 1,
+	 PyDoc_STR("(UInt32 column) -> (UInt16 width)")},
+	{"SetDataBrowserTableViewGeometry", (PyCFunction)CtlObj_SetDataBrowserTableViewGeometry, 1,
+	 PyDoc_STR("(Boolean variableWidthColumns, Boolean variableHeightRows) -> None")},
+	{"GetDataBrowserTableViewGeometry", (PyCFunction)CtlObj_GetDataBrowserTableViewGeometry, 1,
+	 PyDoc_STR("() -> (Boolean variableWidthColumns, Boolean variableHeightRows)")},
+	{"GetDataBrowserTableViewItemID", (PyCFunction)CtlObj_GetDataBrowserTableViewItemID, 1,
+	 PyDoc_STR("(UInt32 row) -> (UInt32 item)")},
+	{"SetDataBrowserTableViewItemRow", (PyCFunction)CtlObj_SetDataBrowserTableViewItemRow, 1,
+	 PyDoc_STR("(UInt32 item, UInt32 row) -> None")},
+	{"GetDataBrowserTableViewItemRow", (PyCFunction)CtlObj_GetDataBrowserTableViewItemRow, 1,
+	 PyDoc_STR("(UInt32 item) -> (UInt32 row)")},
+	{"SetDataBrowserTableViewColumnPosition", (PyCFunction)CtlObj_SetDataBrowserTableViewColumnPosition, 1,
+	 PyDoc_STR("(UInt32 column, UInt32 position) -> None")},
+	{"GetDataBrowserTableViewColumnPosition", (PyCFunction)CtlObj_GetDataBrowserTableViewColumnPosition, 1,
+	 PyDoc_STR("(UInt32 column) -> (UInt32 position)")},
+	{"GetDataBrowserTableViewColumnProperty", (PyCFunction)CtlObj_GetDataBrowserTableViewColumnProperty, 1,
+	 PyDoc_STR("(UInt32 column) -> (UInt32 property)")},
+	{"AutoSizeDataBrowserListViewColumns", (PyCFunction)CtlObj_AutoSizeDataBrowserListViewColumns, 1,
+	 PyDoc_STR("() -> None")},
+	{"AddDataBrowserListViewColumn", (PyCFunction)CtlObj_AddDataBrowserListViewColumn, 1,
+	 PyDoc_STR("(DataBrowserListViewColumnDesc columnDesc, UInt32 position) -> None")},
+	{"SetDataBrowserListViewHeaderBtnHeight", (PyCFunction)CtlObj_SetDataBrowserListViewHeaderBtnHeight, 1,
+	 PyDoc_STR("(UInt16 height) -> None")},
+	{"GetDataBrowserListViewHeaderBtnHeight", (PyCFunction)CtlObj_GetDataBrowserListViewHeaderBtnHeight, 1,
+	 PyDoc_STR("() -> (UInt16 height)")},
+	{"SetDataBrowserListViewUsePlainBackground", (PyCFunction)CtlObj_SetDataBrowserListViewUsePlainBackground, 1,
+	 PyDoc_STR("(Boolean usePlainBackground) -> None")},
+	{"GetDataBrowserListViewUsePlainBackground", (PyCFunction)CtlObj_GetDataBrowserListViewUsePlainBackground, 1,
+	 PyDoc_STR("() -> (Boolean usePlainBackground)")},
+	{"SetDataBrowserListViewDisclosureColumn", (PyCFunction)CtlObj_SetDataBrowserListViewDisclosureColumn, 1,
+	 PyDoc_STR("(UInt32 column, Boolean expandableRows) -> None")},
+	{"GetDataBrowserListViewDisclosureColumn", (PyCFunction)CtlObj_GetDataBrowserListViewDisclosureColumn, 1,
+	 PyDoc_STR("() -> (UInt32 column, Boolean expandableRows)")},
+	{"GetDataBrowserColumnViewPath", (PyCFunction)CtlObj_GetDataBrowserColumnViewPath, 1,
+	 PyDoc_STR("(Handle path) -> None")},
+	{"GetDataBrowserColumnViewPathLength", (PyCFunction)CtlObj_GetDataBrowserColumnViewPathLength, 1,
+	 PyDoc_STR("() -> (UInt32 pathLength)")},
+	{"SetDataBrowserColumnViewDisplayType", (PyCFunction)CtlObj_SetDataBrowserColumnViewDisplayType, 1,
+	 PyDoc_STR("(OSType propertyType) -> None")},
+	{"GetDataBrowserColumnViewDisplayType", (PyCFunction)CtlObj_GetDataBrowserColumnViewDisplayType, 1,
+	 PyDoc_STR("() -> (OSType propertyType)")},
+	{"as_Resource", (PyCFunction)CtlObj_as_Resource, 1,
+	 PyDoc_STR("() -> (Handle _rv)")},
+	{"GetControlRect", (PyCFunction)CtlObj_GetControlRect, 1,
+	 PyDoc_STR("() -> (Rect rect)")},
+	{"DisposeControl", (PyCFunction)CtlObj_DisposeControl, 1,
+	 PyDoc_STR("() -> None")},
+	{"TrackControl", (PyCFunction)CtlObj_TrackControl, 1,
+	 PyDoc_STR("(Point startPoint [,trackercallback]) -> (ControlPartCode _rv)")},
+	{"HandleControlClick", (PyCFunction)CtlObj_HandleControlClick, 1,
+	 PyDoc_STR("(Point startPoint, Integer modifiers, [,trackercallback]) -> (ControlPartCode _rv)")},
+	{"SetControlData", (PyCFunction)CtlObj_SetControlData, 1,
+	 PyDoc_STR("(stuff) -> None")},
+	{"GetControlData", (PyCFunction)CtlObj_GetControlData, 1,
+	 PyDoc_STR("(part, type) -> String")},
+	{"SetControlData_Handle", (PyCFunction)CtlObj_SetControlData_Handle, 1,
+	 PyDoc_STR("(ResObj) -> None")},
+	{"GetControlData_Handle", (PyCFunction)CtlObj_GetControlData_Handle, 1,
+	 PyDoc_STR("(part, type) -> ResObj")},
+	{"SetControlData_Callback", (PyCFunction)CtlObj_SetControlData_Callback, 1,
+	 PyDoc_STR("(callbackfunc) -> None")},
+	{NULL, NULL, 0}
+};
+
+#define CtlObj_getsetlist NULL
+
+
+static int CtlObj_compare(ControlObject *self, ControlObject *other)
+{
+	unsigned long v, w;
+
+	if (!CtlObj_Check((PyObject *)other))
+	{
+		v=(unsigned long)self;
+		w=(unsigned long)other;
+	}
+	else
+	{
+		v=(unsigned long)self->ob_itself;
+		w=(unsigned long)other->ob_itself;
+	}
+	if( v < w ) return -1;
+	if( v > w ) return 1;
+	return 0;
+}
+
+#define CtlObj_repr NULL
+
+static long CtlObj_hash(ControlObject *self)
+{
+	return (long)self->ob_itself;
+}
+#define CtlObj_tp_init 0
+
+#define CtlObj_tp_alloc PyType_GenericAlloc
+
+static PyObject *CtlObj_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *_self;
+	ControlHandle itself;
+	char *kw[] = {"itself", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, CtlObj_Convert, &itself)) return NULL;
+	if ((_self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	((ControlObject *)_self)->ob_itself = itself;
+	return _self;
+}
+
+#define CtlObj_tp_free PyObject_Del
+
+
+PyTypeObject Control_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"_Ctl.Control", /*tp_name*/
+	sizeof(ControlObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) CtlObj_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) CtlObj_compare, /*tp_compare*/
+	(reprfunc) CtlObj_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) CtlObj_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	CtlObj_methods, /* tp_methods */
+	0, /*tp_members*/
+	CtlObj_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	CtlObj_tp_init, /* tp_init */
+	CtlObj_tp_alloc, /* tp_alloc */
+	CtlObj_tp_new, /* tp_new */
+	CtlObj_tp_free, /* tp_free */
+};
+
+/* -------------------- End object type Control --------------------- */
+
+
+static PyObject *Ctl_NewControl(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ControlHandle _rv;
+	WindowPtr owningWindow;
+	Rect boundsRect;
+	Str255 controlTitle;
+	Boolean initiallyVisible;
+	SInt16 initialValue;
+	SInt16 minimumValue;
+	SInt16 maximumValue;
+	SInt16 procID;
+	SInt32 controlReference;
+#ifndef NewControl
+	PyMac_PRECHECK(NewControl);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&bhhhhl",
+	                      WinObj_Convert, &owningWindow,
+	                      PyMac_GetRect, &boundsRect,
+	                      PyMac_GetStr255, controlTitle,
+	                      &initiallyVisible,
+	                      &initialValue,
+	                      &minimumValue,
+	                      &maximumValue,
+	                      &procID,
+	                      &controlReference))
+		return NULL;
+	_rv = NewControl(owningWindow,
+	                 &boundsRect,
+	                 controlTitle,
+	                 initiallyVisible,
+	                 initialValue,
+	                 minimumValue,
+	                 maximumValue,
+	                 procID,
+	                 controlReference);
+	_res = Py_BuildValue("O&",
+	                     CtlObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Ctl_GetNewControl(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ControlHandle _rv;
+	SInt16 resourceID;
+	WindowPtr owningWindow;
+#ifndef GetNewControl
+	PyMac_PRECHECK(GetNewControl);
+#endif
+	if (!PyArg_ParseTuple(_args, "hO&",
+	                      &resourceID,
+	                      WinObj_Convert, &owningWindow))
+		return NULL;
+	_rv = GetNewControl(resourceID,
+	                    owningWindow);
+	_res = Py_BuildValue("O&",
+	                     CtlObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Ctl_DrawControls(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	WindowPtr theWindow;
+#ifndef DrawControls
+	PyMac_PRECHECK(DrawControls);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      WinObj_Convert, &theWindow))
+		return NULL;
+	DrawControls(theWindow);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Ctl_UpdateControls(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	WindowPtr inWindow;
+	RgnHandle inUpdateRegion;
+#ifndef UpdateControls
+	PyMac_PRECHECK(UpdateControls);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      WinObj_Convert, &inWindow,
+	                      ResObj_Convert, &inUpdateRegion))
+		return NULL;
+	UpdateControls(inWindow,
+	               inUpdateRegion);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Ctl_FindControl(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ControlPartCode _rv;
+	Point testPoint;
+	WindowPtr theWindow;
+	ControlHandle theControl;
+#ifndef FindControl
+	PyMac_PRECHECK(FindControl);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetPoint, &testPoint,
+	                      WinObj_Convert, &theWindow))
+		return NULL;
+	_rv = FindControl(testPoint,
+	                  theWindow,
+	                  &theControl);
+	_res = Py_BuildValue("hO&",
+	                     _rv,
+	                     CtlObj_WhichControl, theControl);
+	return _res;
+}
+
+static PyObject *Ctl_IdleControls(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	WindowPtr inWindow;
+#ifndef IdleControls
+	PyMac_PRECHECK(IdleControls);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      WinObj_Convert, &inWindow))
+		return NULL;
+	IdleControls(inWindow);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Ctl_GetControlByID(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr inWindow;
+	ControlID inID;
+	ControlHandle outControl;
+#ifndef GetControlByID
+	PyMac_PRECHECK(GetControlByID);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      WinObj_Convert, &inWindow,
+	                      PyControlID_Convert, &inID))
+		return NULL;
+	_err = GetControlByID(inWindow,
+	                      &inID,
+	                      &outControl);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CtlObj_WhichControl, outControl);
+	return _res;
+}
+
+static PyObject *Ctl_DumpControlHierarchy(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	WindowPtr inWindow;
+	FSSpec inDumpFile;
+#ifndef DumpControlHierarchy
+	PyMac_PRECHECK(DumpControlHierarchy);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      WinObj_Convert, &inWindow,
+	                      PyMac_GetFSSpec, &inDumpFile))
+		return NULL;
+	_err = DumpControlHierarchy(inWindow,
+	                            &inDumpFile);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Ctl_CreateRootControl(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	WindowPtr inWindow;
+	ControlHandle outControl;
+#ifndef CreateRootControl
+	PyMac_PRECHECK(CreateRootControl);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      WinObj_Convert, &inWindow))
+		return NULL;
+	_err = CreateRootControl(inWindow,
+	                         &outControl);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CtlObj_New, outControl);
+	return _res;
+}
+
+static PyObject *Ctl_GetRootControl(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	WindowPtr inWindow;
+	ControlHandle outControl;
+#ifndef GetRootControl
+	PyMac_PRECHECK(GetRootControl);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      WinObj_Convert, &inWindow))
+		return NULL;
+	_err = GetRootControl(inWindow,
+	                      &outControl);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CtlObj_WhichControl, outControl);
+	return _res;
+}
+
+static PyObject *Ctl_GetKeyboardFocus(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	WindowPtr inWindow;
+	ControlHandle outControl;
+#ifndef GetKeyboardFocus
+	PyMac_PRECHECK(GetKeyboardFocus);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      WinObj_Convert, &inWindow))
+		return NULL;
+	_err = GetKeyboardFocus(inWindow,
+	                        &outControl);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CtlObj_WhichControl, outControl);
+	return _res;
+}
+
+static PyObject *Ctl_SetKeyboardFocus(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	WindowPtr inWindow;
+	ControlHandle inControl;
+	ControlFocusPart inPart;
+#ifndef SetKeyboardFocus
+	PyMac_PRECHECK(SetKeyboardFocus);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&h",
+	                      WinObj_Convert, &inWindow,
+	                      CtlObj_Convert, &inControl,
+	                      &inPart))
+		return NULL;
+	_err = SetKeyboardFocus(inWindow,
+	                        inControl,
+	                        inPart);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Ctl_AdvanceKeyboardFocus(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	WindowPtr inWindow;
+#ifndef AdvanceKeyboardFocus
+	PyMac_PRECHECK(AdvanceKeyboardFocus);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      WinObj_Convert, &inWindow))
+		return NULL;
+	_err = AdvanceKeyboardFocus(inWindow);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Ctl_ReverseKeyboardFocus(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	WindowPtr inWindow;
+#ifndef ReverseKeyboardFocus
+	PyMac_PRECHECK(ReverseKeyboardFocus);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      WinObj_Convert, &inWindow))
+		return NULL;
+	_err = ReverseKeyboardFocus(inWindow);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Ctl_ClearKeyboardFocus(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	WindowPtr inWindow;
+#ifndef ClearKeyboardFocus
+	PyMac_PRECHECK(ClearKeyboardFocus);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      WinObj_Convert, &inWindow))
+		return NULL;
+	_err = ClearKeyboardFocus(inWindow);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Ctl_SetAutomaticControlDragTrackingEnabledForWindow(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr inWindow;
+	Boolean inTracks;
+#ifndef SetAutomaticControlDragTrackingEnabledForWindow
+	PyMac_PRECHECK(SetAutomaticControlDragTrackingEnabledForWindow);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&b",
+	                      WinObj_Convert, &inWindow,
+	                      &inTracks))
+		return NULL;
+	_err = SetAutomaticControlDragTrackingEnabledForWindow(inWindow,
+	                                                       inTracks);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Ctl_IsAutomaticControlDragTrackingEnabledForWindow(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr inWindow;
+	Boolean outTracks;
+#ifndef IsAutomaticControlDragTrackingEnabledForWindow
+	PyMac_PRECHECK(IsAutomaticControlDragTrackingEnabledForWindow);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      WinObj_Convert, &inWindow))
+		return NULL;
+	_err = IsAutomaticControlDragTrackingEnabledForWindow(inWindow,
+	                                                      &outTracks);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("b",
+	                     outTracks);
+	return _res;
+}
+
+static PyObject *Ctl_CreateBevelButtonControl(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr window;
+	Rect boundsRect;
+	CFStringRef title;
+	UInt16 thickness;
+	UInt16 behavior;
+	ControlButtonContentInfo info;
+	SInt16 menuID;
+	UInt16 menuBehavior;
+	UInt16 menuPlacement;
+	ControlHandle outControl;
+#ifndef CreateBevelButtonControl
+	PyMac_PRECHECK(CreateBevelButtonControl);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&HHO&hHH",
+	                      WinObj_Convert, &window,
+	                      PyMac_GetRect, &boundsRect,
+	                      CFStringRefObj_Convert, &title,
+	                      &thickness,
+	                      &behavior,
+	                      ControlButtonContentInfo_Convert, &info,
+	                      &menuID,
+	                      &menuBehavior,
+	                      &menuPlacement))
+		return NULL;
+	_err = CreateBevelButtonControl(window,
+	                                &boundsRect,
+	                                title,
+	                                thickness,
+	                                behavior,
+	                                &info,
+	                                menuID,
+	                                menuBehavior,
+	                                menuPlacement,
+	                                &outControl);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CtlObj_New, outControl);
+	return _res;
+}
+
+static PyObject *Ctl_CreateSliderControl(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr window;
+	Rect boundsRect;
+	SInt32 value;
+	SInt32 minimum;
+	SInt32 maximum;
+	UInt16 orientation;
+	UInt16 numTickMarks;
+	Boolean liveTracking;
+	PyObject* liveTrackingProc;
+	UniversalProcPtr c_callback;
+	ControlHandle outControl;
+#ifndef CreateSliderControl
+	PyMac_PRECHECK(CreateSliderControl);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&lllHHbO",
+	                      WinObj_Convert, &window,
+	                      PyMac_GetRect, &boundsRect,
+	                      &value,
+	                      &minimum,
+	                      &maximum,
+	                      &orientation,
+	                      &numTickMarks,
+	                      &liveTracking,
+	                      &liveTrackingProc))
+		return NULL;
+	_err = CreateSliderControl(window,
+	                           &boundsRect,
+	                           value,
+	                           minimum,
+	                           maximum,
+	                           orientation,
+	                           numTickMarks,
+	                           liveTracking,
+	                           myactionproc_upp,
+	                           &outControl);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CtlObj_New, outControl);
+	setcallback(_res, kMyControlActionProcTag, liveTrackingProc, &c_callback);
+	return _res;
+}
+
+static PyObject *Ctl_CreateDisclosureTriangleControl(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr inWindow;
+	Rect inBoundsRect;
+	UInt16 inOrientation;
+	CFStringRef inTitle;
+	SInt32 inInitialValue;
+	Boolean inDrawTitle;
+	Boolean inAutoToggles;
+	ControlHandle outControl;
+#ifndef CreateDisclosureTriangleControl
+	PyMac_PRECHECK(CreateDisclosureTriangleControl);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&HO&lbb",
+	                      WinObj_Convert, &inWindow,
+	                      PyMac_GetRect, &inBoundsRect,
+	                      &inOrientation,
+	                      CFStringRefObj_Convert, &inTitle,
+	                      &inInitialValue,
+	                      &inDrawTitle,
+	                      &inAutoToggles))
+		return NULL;
+	_err = CreateDisclosureTriangleControl(inWindow,
+	                                       &inBoundsRect,
+	                                       inOrientation,
+	                                       inTitle,
+	                                       inInitialValue,
+	                                       inDrawTitle,
+	                                       inAutoToggles,
+	                                       &outControl);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CtlObj_New, outControl);
+	return _res;
+}
+
+static PyObject *Ctl_CreateProgressBarControl(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr window;
+	Rect boundsRect;
+	SInt32 value;
+	SInt32 minimum;
+	SInt32 maximum;
+	Boolean indeterminate;
+	ControlHandle outControl;
+#ifndef CreateProgressBarControl
+	PyMac_PRECHECK(CreateProgressBarControl);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&lllb",
+	                      WinObj_Convert, &window,
+	                      PyMac_GetRect, &boundsRect,
+	                      &value,
+	                      &minimum,
+	                      &maximum,
+	                      &indeterminate))
+		return NULL;
+	_err = CreateProgressBarControl(window,
+	                                &boundsRect,
+	                                value,
+	                                minimum,
+	                                maximum,
+	                                indeterminate,
+	                                &outControl);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CtlObj_New, outControl);
+	return _res;
+}
+
+static PyObject *Ctl_CreateRelevanceBarControl(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr window;
+	Rect boundsRect;
+	SInt32 value;
+	SInt32 minimum;
+	SInt32 maximum;
+	ControlHandle outControl;
+#ifndef CreateRelevanceBarControl
+	PyMac_PRECHECK(CreateRelevanceBarControl);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&lll",
+	                      WinObj_Convert, &window,
+	                      PyMac_GetRect, &boundsRect,
+	                      &value,
+	                      &minimum,
+	                      &maximum))
+		return NULL;
+	_err = CreateRelevanceBarControl(window,
+	                                 &boundsRect,
+	                                 value,
+	                                 minimum,
+	                                 maximum,
+	                                 &outControl);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CtlObj_New, outControl);
+	return _res;
+}
+
+static PyObject *Ctl_CreateLittleArrowsControl(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr window;
+	Rect boundsRect;
+	SInt32 value;
+	SInt32 minimum;
+	SInt32 maximum;
+	SInt32 increment;
+	ControlHandle outControl;
+#ifndef CreateLittleArrowsControl
+	PyMac_PRECHECK(CreateLittleArrowsControl);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&llll",
+	                      WinObj_Convert, &window,
+	                      PyMac_GetRect, &boundsRect,
+	                      &value,
+	                      &minimum,
+	                      &maximum,
+	                      &increment))
+		return NULL;
+	_err = CreateLittleArrowsControl(window,
+	                                 &boundsRect,
+	                                 value,
+	                                 minimum,
+	                                 maximum,
+	                                 increment,
+	                                 &outControl);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CtlObj_New, outControl);
+	return _res;
+}
+
+static PyObject *Ctl_CreateChasingArrowsControl(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr window;
+	Rect boundsRect;
+	ControlHandle outControl;
+#ifndef CreateChasingArrowsControl
+	PyMac_PRECHECK(CreateChasingArrowsControl);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      WinObj_Convert, &window,
+	                      PyMac_GetRect, &boundsRect))
+		return NULL;
+	_err = CreateChasingArrowsControl(window,
+	                                  &boundsRect,
+	                                  &outControl);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CtlObj_New, outControl);
+	return _res;
+}
+
+static PyObject *Ctl_CreateSeparatorControl(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr window;
+	Rect boundsRect;
+	ControlHandle outControl;
+#ifndef CreateSeparatorControl
+	PyMac_PRECHECK(CreateSeparatorControl);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      WinObj_Convert, &window,
+	                      PyMac_GetRect, &boundsRect))
+		return NULL;
+	_err = CreateSeparatorControl(window,
+	                              &boundsRect,
+	                              &outControl);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CtlObj_New, outControl);
+	return _res;
+}
+
+static PyObject *Ctl_CreateGroupBoxControl(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr window;
+	Rect boundsRect;
+	CFStringRef title;
+	Boolean primary;
+	ControlHandle outControl;
+#ifndef CreateGroupBoxControl
+	PyMac_PRECHECK(CreateGroupBoxControl);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&b",
+	                      WinObj_Convert, &window,
+	                      PyMac_GetRect, &boundsRect,
+	                      CFStringRefObj_Convert, &title,
+	                      &primary))
+		return NULL;
+	_err = CreateGroupBoxControl(window,
+	                             &boundsRect,
+	                             title,
+	                             primary,
+	                             &outControl);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CtlObj_New, outControl);
+	return _res;
+}
+
+static PyObject *Ctl_CreateCheckGroupBoxControl(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr window;
+	Rect boundsRect;
+	CFStringRef title;
+	SInt32 initialValue;
+	Boolean primary;
+	Boolean autoToggle;
+	ControlHandle outControl;
+#ifndef CreateCheckGroupBoxControl
+	PyMac_PRECHECK(CreateCheckGroupBoxControl);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&lbb",
+	                      WinObj_Convert, &window,
+	                      PyMac_GetRect, &boundsRect,
+	                      CFStringRefObj_Convert, &title,
+	                      &initialValue,
+	                      &primary,
+	                      &autoToggle))
+		return NULL;
+	_err = CreateCheckGroupBoxControl(window,
+	                                  &boundsRect,
+	                                  title,
+	                                  initialValue,
+	                                  primary,
+	                                  autoToggle,
+	                                  &outControl);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CtlObj_New, outControl);
+	return _res;
+}
+
+static PyObject *Ctl_CreatePopupGroupBoxControl(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr window;
+	Rect boundsRect;
+	CFStringRef title;
+	Boolean primary;
+	SInt16 menuID;
+	Boolean variableWidth;
+	SInt16 titleWidth;
+	SInt16 titleJustification;
+	Style titleStyle;
+	ControlHandle outControl;
+#ifndef CreatePopupGroupBoxControl
+	PyMac_PRECHECK(CreatePopupGroupBoxControl);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&bhbhhb",
+	                      WinObj_Convert, &window,
+	                      PyMac_GetRect, &boundsRect,
+	                      CFStringRefObj_Convert, &title,
+	                      &primary,
+	                      &menuID,
+	                      &variableWidth,
+	                      &titleWidth,
+	                      &titleJustification,
+	                      &titleStyle))
+		return NULL;
+	_err = CreatePopupGroupBoxControl(window,
+	                                  &boundsRect,
+	                                  title,
+	                                  primary,
+	                                  menuID,
+	                                  variableWidth,
+	                                  titleWidth,
+	                                  titleJustification,
+	                                  titleStyle,
+	                                  &outControl);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CtlObj_New, outControl);
+	return _res;
+}
+
+static PyObject *Ctl_CreateImageWellControl(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr window;
+	Rect boundsRect;
+	ControlButtonContentInfo info;
+	ControlHandle outControl;
+#ifndef CreateImageWellControl
+	PyMac_PRECHECK(CreateImageWellControl);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      WinObj_Convert, &window,
+	                      PyMac_GetRect, &boundsRect,
+	                      ControlButtonContentInfo_Convert, &info))
+		return NULL;
+	_err = CreateImageWellControl(window,
+	                              &boundsRect,
+	                              &info,
+	                              &outControl);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CtlObj_New, outControl);
+	return _res;
+}
+
+static PyObject *Ctl_CreatePopupArrowControl(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr window;
+	Rect boundsRect;
+	UInt16 orientation;
+	UInt16 size;
+	ControlHandle outControl;
+#ifndef CreatePopupArrowControl
+	PyMac_PRECHECK(CreatePopupArrowControl);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&HH",
+	                      WinObj_Convert, &window,
+	                      PyMac_GetRect, &boundsRect,
+	                      &orientation,
+	                      &size))
+		return NULL;
+	_err = CreatePopupArrowControl(window,
+	                               &boundsRect,
+	                               orientation,
+	                               size,
+	                               &outControl);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CtlObj_New, outControl);
+	return _res;
+}
+
+static PyObject *Ctl_CreatePlacardControl(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr window;
+	Rect boundsRect;
+	ControlHandle outControl;
+#ifndef CreatePlacardControl
+	PyMac_PRECHECK(CreatePlacardControl);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      WinObj_Convert, &window,
+	                      PyMac_GetRect, &boundsRect))
+		return NULL;
+	_err = CreatePlacardControl(window,
+	                            &boundsRect,
+	                            &outControl);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CtlObj_New, outControl);
+	return _res;
+}
+
+static PyObject *Ctl_CreateClockControl(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr window;
+	Rect boundsRect;
+	UInt16 clockType;
+	UInt32 clockFlags;
+	ControlHandle outControl;
+#ifndef CreateClockControl
+	PyMac_PRECHECK(CreateClockControl);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&Hl",
+	                      WinObj_Convert, &window,
+	                      PyMac_GetRect, &boundsRect,
+	                      &clockType,
+	                      &clockFlags))
+		return NULL;
+	_err = CreateClockControl(window,
+	                          &boundsRect,
+	                          clockType,
+	                          clockFlags,
+	                          &outControl);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CtlObj_New, outControl);
+	return _res;
+}
+
+static PyObject *Ctl_CreateUserPaneControl(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr window;
+	Rect boundsRect;
+	UInt32 features;
+	ControlHandle outControl;
+#ifndef CreateUserPaneControl
+	PyMac_PRECHECK(CreateUserPaneControl);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&l",
+	                      WinObj_Convert, &window,
+	                      PyMac_GetRect, &boundsRect,
+	                      &features))
+		return NULL;
+	_err = CreateUserPaneControl(window,
+	                             &boundsRect,
+	                             features,
+	                             &outControl);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CtlObj_New, outControl);
+	return _res;
+}
+
+static PyObject *Ctl_CreateEditTextControl(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr window;
+	Rect boundsRect;
+	CFStringRef text;
+	Boolean isPassword;
+	Boolean useInlineInput;
+	ControlFontStyleRec style;
+	ControlHandle outControl;
+#ifndef CreateEditTextControl
+	PyMac_PRECHECK(CreateEditTextControl);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&bbO&",
+	                      WinObj_Convert, &window,
+	                      PyMac_GetRect, &boundsRect,
+	                      CFStringRefObj_Convert, &text,
+	                      &isPassword,
+	                      &useInlineInput,
+	                      ControlFontStyle_Convert, &style))
+		return NULL;
+	_err = CreateEditTextControl(window,
+	                             &boundsRect,
+	                             text,
+	                             isPassword,
+	                             useInlineInput,
+	                             &style,
+	                             &outControl);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CtlObj_New, outControl);
+	return _res;
+}
+
+static PyObject *Ctl_CreateStaticTextControl(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr window;
+	Rect boundsRect;
+	CFStringRef text;
+	ControlFontStyleRec style;
+	ControlHandle outControl;
+#ifndef CreateStaticTextControl
+	PyMac_PRECHECK(CreateStaticTextControl);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&O&",
+	                      WinObj_Convert, &window,
+	                      PyMac_GetRect, &boundsRect,
+	                      CFStringRefObj_Convert, &text,
+	                      ControlFontStyle_Convert, &style))
+		return NULL;
+	_err = CreateStaticTextControl(window,
+	                               &boundsRect,
+	                               text,
+	                               &style,
+	                               &outControl);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CtlObj_New, outControl);
+	return _res;
+}
+
+static PyObject *Ctl_CreatePictureControl(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr window;
+	Rect boundsRect;
+	ControlButtonContentInfo content;
+	Boolean dontTrack;
+	ControlHandle outControl;
+#ifndef CreatePictureControl
+	PyMac_PRECHECK(CreatePictureControl);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&b",
+	                      WinObj_Convert, &window,
+	                      PyMac_GetRect, &boundsRect,
+	                      ControlButtonContentInfo_Convert, &content,
+	                      &dontTrack))
+		return NULL;
+	_err = CreatePictureControl(window,
+	                            &boundsRect,
+	                            &content,
+	                            dontTrack,
+	                            &outControl);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CtlObj_New, outControl);
+	return _res;
+}
+
+static PyObject *Ctl_CreateIconControl(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr inWindow;
+	Rect inBoundsRect;
+	ControlButtonContentInfo inIconContent;
+	Boolean inDontTrack;
+	ControlHandle outControl;
+#ifndef CreateIconControl
+	PyMac_PRECHECK(CreateIconControl);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&b",
+	                      WinObj_Convert, &inWindow,
+	                      PyMac_GetRect, &inBoundsRect,
+	                      ControlButtonContentInfo_Convert, &inIconContent,
+	                      &inDontTrack))
+		return NULL;
+	_err = CreateIconControl(inWindow,
+	                         &inBoundsRect,
+	                         &inIconContent,
+	                         inDontTrack,
+	                         &outControl);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CtlObj_New, outControl);
+	return _res;
+}
+
+static PyObject *Ctl_CreateWindowHeaderControl(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr window;
+	Rect boundsRect;
+	Boolean isListHeader;
+	ControlHandle outControl;
+#ifndef CreateWindowHeaderControl
+	PyMac_PRECHECK(CreateWindowHeaderControl);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&b",
+	                      WinObj_Convert, &window,
+	                      PyMac_GetRect, &boundsRect,
+	                      &isListHeader))
+		return NULL;
+	_err = CreateWindowHeaderControl(window,
+	                                 &boundsRect,
+	                                 isListHeader,
+	                                 &outControl);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CtlObj_New, outControl);
+	return _res;
+}
+
+static PyObject *Ctl_CreatePushButtonControl(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr window;
+	Rect boundsRect;
+	CFStringRef title;
+	ControlHandle outControl;
+#ifndef CreatePushButtonControl
+	PyMac_PRECHECK(CreatePushButtonControl);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      WinObj_Convert, &window,
+	                      PyMac_GetRect, &boundsRect,
+	                      CFStringRefObj_Convert, &title))
+		return NULL;
+	_err = CreatePushButtonControl(window,
+	                               &boundsRect,
+	                               title,
+	                               &outControl);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CtlObj_New, outControl);
+	return _res;
+}
+
+static PyObject *Ctl_CreatePushButtonWithIconControl(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr window;
+	Rect boundsRect;
+	CFStringRef title;
+	ControlButtonContentInfo icon;
+	UInt16 iconAlignment;
+	ControlHandle outControl;
+#ifndef CreatePushButtonWithIconControl
+	PyMac_PRECHECK(CreatePushButtonWithIconControl);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&O&H",
+	                      WinObj_Convert, &window,
+	                      PyMac_GetRect, &boundsRect,
+	                      CFStringRefObj_Convert, &title,
+	                      ControlButtonContentInfo_Convert, &icon,
+	                      &iconAlignment))
+		return NULL;
+	_err = CreatePushButtonWithIconControl(window,
+	                                       &boundsRect,
+	                                       title,
+	                                       &icon,
+	                                       iconAlignment,
+	                                       &outControl);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CtlObj_New, outControl);
+	return _res;
+}
+
+static PyObject *Ctl_CreateRadioButtonControl(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr window;
+	Rect boundsRect;
+	CFStringRef title;
+	SInt32 initialValue;
+	Boolean autoToggle;
+	ControlHandle outControl;
+#ifndef CreateRadioButtonControl
+	PyMac_PRECHECK(CreateRadioButtonControl);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&lb",
+	                      WinObj_Convert, &window,
+	                      PyMac_GetRect, &boundsRect,
+	                      CFStringRefObj_Convert, &title,
+	                      &initialValue,
+	                      &autoToggle))
+		return NULL;
+	_err = CreateRadioButtonControl(window,
+	                                &boundsRect,
+	                                title,
+	                                initialValue,
+	                                autoToggle,
+	                                &outControl);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CtlObj_New, outControl);
+	return _res;
+}
+
+static PyObject *Ctl_CreateCheckBoxControl(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr window;
+	Rect boundsRect;
+	CFStringRef title;
+	SInt32 initialValue;
+	Boolean autoToggle;
+	ControlHandle outControl;
+#ifndef CreateCheckBoxControl
+	PyMac_PRECHECK(CreateCheckBoxControl);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&lb",
+	                      WinObj_Convert, &window,
+	                      PyMac_GetRect, &boundsRect,
+	                      CFStringRefObj_Convert, &title,
+	                      &initialValue,
+	                      &autoToggle))
+		return NULL;
+	_err = CreateCheckBoxControl(window,
+	                             &boundsRect,
+	                             title,
+	                             initialValue,
+	                             autoToggle,
+	                             &outControl);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CtlObj_New, outControl);
+	return _res;
+}
+
+static PyObject *Ctl_CreateScrollBarControl(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr window;
+	Rect boundsRect;
+	SInt32 value;
+	SInt32 minimum;
+	SInt32 maximum;
+	SInt32 viewSize;
+	Boolean liveTracking;
+	PyObject* liveTrackingProc;
+	UniversalProcPtr c_callback;
+	ControlHandle outControl;
+#ifndef CreateScrollBarControl
+	PyMac_PRECHECK(CreateScrollBarControl);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&llllbO",
+	                      WinObj_Convert, &window,
+	                      PyMac_GetRect, &boundsRect,
+	                      &value,
+	                      &minimum,
+	                      &maximum,
+	                      &viewSize,
+	                      &liveTracking,
+	                      &liveTrackingProc))
+		return NULL;
+	_err = CreateScrollBarControl(window,
+	                              &boundsRect,
+	                              value,
+	                              minimum,
+	                              maximum,
+	                              viewSize,
+	                              liveTracking,
+	                              myactionproc_upp,
+	                              &outControl);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CtlObj_New, outControl);
+	setcallback(_res, kMyControlActionProcTag, liveTrackingProc, &c_callback);
+	return _res;
+}
+
+static PyObject *Ctl_CreatePopupButtonControl(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr window;
+	Rect boundsRect;
+	CFStringRef title;
+	SInt16 menuID;
+	Boolean variableWidth;
+	SInt16 titleWidth;
+	SInt16 titleJustification;
+	Style titleStyle;
+	ControlHandle outControl;
+#ifndef CreatePopupButtonControl
+	PyMac_PRECHECK(CreatePopupButtonControl);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&hbhhb",
+	                      WinObj_Convert, &window,
+	                      PyMac_GetRect, &boundsRect,
+	                      CFStringRefObj_Convert, &title,
+	                      &menuID,
+	                      &variableWidth,
+	                      &titleWidth,
+	                      &titleJustification,
+	                      &titleStyle))
+		return NULL;
+	_err = CreatePopupButtonControl(window,
+	                                &boundsRect,
+	                                title,
+	                                menuID,
+	                                variableWidth,
+	                                titleWidth,
+	                                titleJustification,
+	                                titleStyle,
+	                                &outControl);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CtlObj_New, outControl);
+	return _res;
+}
+
+static PyObject *Ctl_CreateRadioGroupControl(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr window;
+	Rect boundsRect;
+	ControlHandle outControl;
+#ifndef CreateRadioGroupControl
+	PyMac_PRECHECK(CreateRadioGroupControl);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      WinObj_Convert, &window,
+	                      PyMac_GetRect, &boundsRect))
+		return NULL;
+	_err = CreateRadioGroupControl(window,
+	                               &boundsRect,
+	                               &outControl);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CtlObj_New, outControl);
+	return _res;
+}
+
+static PyObject *Ctl_CreateScrollingTextBoxControl(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr window;
+	Rect boundsRect;
+	SInt16 contentResID;
+	Boolean autoScroll;
+	UInt32 delayBeforeAutoScroll;
+	UInt32 delayBetweenAutoScroll;
+	UInt16 autoScrollAmount;
+	ControlHandle outControl;
+#ifndef CreateScrollingTextBoxControl
+	PyMac_PRECHECK(CreateScrollingTextBoxControl);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&hbllH",
+	                      WinObj_Convert, &window,
+	                      PyMac_GetRect, &boundsRect,
+	                      &contentResID,
+	                      &autoScroll,
+	                      &delayBeforeAutoScroll,
+	                      &delayBetweenAutoScroll,
+	                      &autoScrollAmount))
+		return NULL;
+	_err = CreateScrollingTextBoxControl(window,
+	                                     &boundsRect,
+	                                     contentResID,
+	                                     autoScroll,
+	                                     delayBeforeAutoScroll,
+	                                     delayBetweenAutoScroll,
+	                                     autoScrollAmount,
+	                                     &outControl);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CtlObj_New, outControl);
+	return _res;
+}
+
+static PyObject *Ctl_CreateDisclosureButtonControl(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr inWindow;
+	Rect inBoundsRect;
+	SInt32 inValue;
+	Boolean inAutoToggles;
+	ControlHandle outControl;
+#ifndef CreateDisclosureButtonControl
+	PyMac_PRECHECK(CreateDisclosureButtonControl);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&lb",
+	                      WinObj_Convert, &inWindow,
+	                      PyMac_GetRect, &inBoundsRect,
+	                      &inValue,
+	                      &inAutoToggles))
+		return NULL;
+	_err = CreateDisclosureButtonControl(inWindow,
+	                                     &inBoundsRect,
+	                                     inValue,
+	                                     inAutoToggles,
+	                                     &outControl);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CtlObj_New, outControl);
+	return _res;
+}
+
+static PyObject *Ctl_CreateRoundButtonControl(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr inWindow;
+	Rect inBoundsRect;
+	SInt16 inSize;
+	ControlButtonContentInfo inContent;
+	ControlHandle outControl;
+#ifndef CreateRoundButtonControl
+	PyMac_PRECHECK(CreateRoundButtonControl);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&hO&",
+	                      WinObj_Convert, &inWindow,
+	                      PyMac_GetRect, &inBoundsRect,
+	                      &inSize,
+	                      ControlButtonContentInfo_Convert, &inContent))
+		return NULL;
+	_err = CreateRoundButtonControl(inWindow,
+	                                &inBoundsRect,
+	                                inSize,
+	                                &inContent,
+	                                &outControl);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CtlObj_New, outControl);
+	return _res;
+}
+
+static PyObject *Ctl_CreateDataBrowserControl(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr window;
+	Rect boundsRect;
+	OSType style;
+	ControlHandle outControl;
+#ifndef CreateDataBrowserControl
+	PyMac_PRECHECK(CreateDataBrowserControl);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      WinObj_Convert, &window,
+	                      PyMac_GetRect, &boundsRect,
+	                      PyMac_GetOSType, &style))
+		return NULL;
+	_err = CreateDataBrowserControl(window,
+	                                &boundsRect,
+	                                style,
+	                                &outControl);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CtlObj_New, outControl);
+	return _res;
+}
+
+static PyObject *Ctl_CreateEditUnicodeTextControl(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr window;
+	Rect boundsRect;
+	CFStringRef text;
+	Boolean isPassword;
+	ControlFontStyleRec style;
+	ControlHandle outControl;
+#ifndef CreateEditUnicodeTextControl
+	PyMac_PRECHECK(CreateEditUnicodeTextControl);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&bO&",
+	                      WinObj_Convert, &window,
+	                      PyMac_GetRect, &boundsRect,
+	                      CFStringRefObj_Convert, &text,
+	                      &isPassword,
+	                      ControlFontStyle_Convert, &style))
+		return NULL;
+	_err = CreateEditUnicodeTextControl(window,
+	                                    &boundsRect,
+	                                    text,
+	                                    isPassword,
+	                                    &style,
+	                                    &outControl);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CtlObj_New, outControl);
+	return _res;
+}
+
+static PyObject *Ctl_FindControlUnderMouse(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ControlHandle _rv;
+	Point inWhere;
+	WindowPtr inWindow;
+	SInt16 outPart;
+#ifndef FindControlUnderMouse
+	PyMac_PRECHECK(FindControlUnderMouse);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetPoint, &inWhere,
+	                      WinObj_Convert, &inWindow))
+		return NULL;
+	_rv = FindControlUnderMouse(inWhere,
+	                            inWindow,
+	                            &outPart);
+	_res = Py_BuildValue("O&h",
+	                     CtlObj_WhichControl, _rv,
+	                     outPart);
+	return _res;
+}
+
+static PyObject *Ctl_as_Control(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ControlHandle _rv;
+	Handle h;
+#ifndef as_Control
+	PyMac_PRECHECK(as_Control);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &h))
+		return NULL;
+	_rv = as_Control(h);
+	_res = Py_BuildValue("O&",
+	                     CtlObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Ctl_CreateTabsControl(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr window;
+	Rect boundsRect;
+	UInt16 size;
+	UInt16 direction;
+	int i;
+	UInt16 numTabs;
+	ControlTabEntry tabArray[MAXTABS];
+	ControlHandle outControl;
+	PyObject *tabArrayObj, *tabEntry;
+
+#ifndef CreateTabsControl
+	PyMac_PRECHECK(CreateTabsControl);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&HHO",
+	                      WinObj_Convert, &window,
+	                      PyMac_GetRect, &boundsRect,
+	                      &size,
+	                      &direction,
+	                      &tabArrayObj))
+	        return NULL;
+
+	i = PySequence_Length(tabArrayObj);
+	if (i == -1)
+	        return NULL;
+	if (i > MAXTABS) {
+	        PyErr_SetString(Ctl_Error, "Too many tabs");
+	        return NULL;
+	}
+	numTabs = i;
+	for (i=0; i<numTabs; i++) {
+	        tabEntry = PySequence_GetItem(tabArrayObj, i);
+	        if (tabEntry == NULL)
+	                return NULL;
+	        if (!PyArg_Parse(tabEntry, "(O&O&B)",
+	                         ControlButtonContentInfo_Convert, &tabArray[i].icon,
+	                         CFStringRefObj_Convert, &tabArray[i].name,
+	                         &tabArray[i].enabled
+	                         ))
+	                return NULL;
+	}
+
+	_err = CreateTabsControl(window,
+	                         &boundsRect,
+	                         size,
+	                         direction,
+	                         numTabs,
+	                         tabArray,
+	                         &outControl);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CtlObj_New, outControl);
+	return _res;
+}
+
+static PyMethodDef Ctl_methods[] = {
+	{"NewControl", (PyCFunction)Ctl_NewControl, 1,
+	 PyDoc_STR("(WindowPtr owningWindow, Rect boundsRect, Str255 controlTitle, Boolean initiallyVisible, SInt16 initialValue, SInt16 minimumValue, SInt16 maximumValue, SInt16 procID, SInt32 controlReference) -> (ControlHandle _rv)")},
+	{"GetNewControl", (PyCFunction)Ctl_GetNewControl, 1,
+	 PyDoc_STR("(SInt16 resourceID, WindowPtr owningWindow) -> (ControlHandle _rv)")},
+	{"DrawControls", (PyCFunction)Ctl_DrawControls, 1,
+	 PyDoc_STR("(WindowPtr theWindow) -> None")},
+	{"UpdateControls", (PyCFunction)Ctl_UpdateControls, 1,
+	 PyDoc_STR("(WindowPtr inWindow, RgnHandle inUpdateRegion) -> None")},
+	{"FindControl", (PyCFunction)Ctl_FindControl, 1,
+	 PyDoc_STR("(Point testPoint, WindowPtr theWindow) -> (ControlPartCode _rv, ControlHandle theControl)")},
+	{"IdleControls", (PyCFunction)Ctl_IdleControls, 1,
+	 PyDoc_STR("(WindowPtr inWindow) -> None")},
+	{"GetControlByID", (PyCFunction)Ctl_GetControlByID, 1,
+	 PyDoc_STR("(WindowPtr inWindow, ControlID inID) -> (ControlHandle outControl)")},
+	{"DumpControlHierarchy", (PyCFunction)Ctl_DumpControlHierarchy, 1,
+	 PyDoc_STR("(WindowPtr inWindow, FSSpec inDumpFile) -> None")},
+	{"CreateRootControl", (PyCFunction)Ctl_CreateRootControl, 1,
+	 PyDoc_STR("(WindowPtr inWindow) -> (ControlHandle outControl)")},
+	{"GetRootControl", (PyCFunction)Ctl_GetRootControl, 1,
+	 PyDoc_STR("(WindowPtr inWindow) -> (ControlHandle outControl)")},
+	{"GetKeyboardFocus", (PyCFunction)Ctl_GetKeyboardFocus, 1,
+	 PyDoc_STR("(WindowPtr inWindow) -> (ControlHandle outControl)")},
+	{"SetKeyboardFocus", (PyCFunction)Ctl_SetKeyboardFocus, 1,
+	 PyDoc_STR("(WindowPtr inWindow, ControlHandle inControl, ControlFocusPart inPart) -> None")},
+	{"AdvanceKeyboardFocus", (PyCFunction)Ctl_AdvanceKeyboardFocus, 1,
+	 PyDoc_STR("(WindowPtr inWindow) -> None")},
+	{"ReverseKeyboardFocus", (PyCFunction)Ctl_ReverseKeyboardFocus, 1,
+	 PyDoc_STR("(WindowPtr inWindow) -> None")},
+	{"ClearKeyboardFocus", (PyCFunction)Ctl_ClearKeyboardFocus, 1,
+	 PyDoc_STR("(WindowPtr inWindow) -> None")},
+	{"SetAutomaticControlDragTrackingEnabledForWindow", (PyCFunction)Ctl_SetAutomaticControlDragTrackingEnabledForWindow, 1,
+	 PyDoc_STR("(WindowPtr inWindow, Boolean inTracks) -> None")},
+	{"IsAutomaticControlDragTrackingEnabledForWindow", (PyCFunction)Ctl_IsAutomaticControlDragTrackingEnabledForWindow, 1,
+	 PyDoc_STR("(WindowPtr inWindow) -> (Boolean outTracks)")},
+	{"CreateBevelButtonControl", (PyCFunction)Ctl_CreateBevelButtonControl, 1,
+	 PyDoc_STR("(WindowPtr window, Rect boundsRect, CFStringRef title, UInt16 thickness, UInt16 behavior, ControlButtonContentInfo info, SInt16 menuID, UInt16 menuBehavior, UInt16 menuPlacement) -> (ControlHandle outControl)")},
+	{"CreateSliderControl", (PyCFunction)Ctl_CreateSliderControl, 1,
+	 PyDoc_STR("(WindowPtr window, Rect boundsRect, SInt32 value, SInt32 minimum, SInt32 maximum, UInt16 orientation, UInt16 numTickMarks, Boolean liveTracking, PyObject* liveTrackingProc) -> (ControlHandle outControl)")},
+	{"CreateDisclosureTriangleControl", (PyCFunction)Ctl_CreateDisclosureTriangleControl, 1,
+	 PyDoc_STR("(WindowPtr inWindow, Rect inBoundsRect, UInt16 inOrientation, CFStringRef inTitle, SInt32 inInitialValue, Boolean inDrawTitle, Boolean inAutoToggles) -> (ControlHandle outControl)")},
+	{"CreateProgressBarControl", (PyCFunction)Ctl_CreateProgressBarControl, 1,
+	 PyDoc_STR("(WindowPtr window, Rect boundsRect, SInt32 value, SInt32 minimum, SInt32 maximum, Boolean indeterminate) -> (ControlHandle outControl)")},
+	{"CreateRelevanceBarControl", (PyCFunction)Ctl_CreateRelevanceBarControl, 1,
+	 PyDoc_STR("(WindowPtr window, Rect boundsRect, SInt32 value, SInt32 minimum, SInt32 maximum) -> (ControlHandle outControl)")},
+	{"CreateLittleArrowsControl", (PyCFunction)Ctl_CreateLittleArrowsControl, 1,
+	 PyDoc_STR("(WindowPtr window, Rect boundsRect, SInt32 value, SInt32 minimum, SInt32 maximum, SInt32 increment) -> (ControlHandle outControl)")},
+	{"CreateChasingArrowsControl", (PyCFunction)Ctl_CreateChasingArrowsControl, 1,
+	 PyDoc_STR("(WindowPtr window, Rect boundsRect) -> (ControlHandle outControl)")},
+	{"CreateSeparatorControl", (PyCFunction)Ctl_CreateSeparatorControl, 1,
+	 PyDoc_STR("(WindowPtr window, Rect boundsRect) -> (ControlHandle outControl)")},
+	{"CreateGroupBoxControl", (PyCFunction)Ctl_CreateGroupBoxControl, 1,
+	 PyDoc_STR("(WindowPtr window, Rect boundsRect, CFStringRef title, Boolean primary) -> (ControlHandle outControl)")},
+	{"CreateCheckGroupBoxControl", (PyCFunction)Ctl_CreateCheckGroupBoxControl, 1,
+	 PyDoc_STR("(WindowPtr window, Rect boundsRect, CFStringRef title, SInt32 initialValue, Boolean primary, Boolean autoToggle) -> (ControlHandle outControl)")},
+	{"CreatePopupGroupBoxControl", (PyCFunction)Ctl_CreatePopupGroupBoxControl, 1,
+	 PyDoc_STR("(WindowPtr window, Rect boundsRect, CFStringRef title, Boolean primary, SInt16 menuID, Boolean variableWidth, SInt16 titleWidth, SInt16 titleJustification, Style titleStyle) -> (ControlHandle outControl)")},
+	{"CreateImageWellControl", (PyCFunction)Ctl_CreateImageWellControl, 1,
+	 PyDoc_STR("(WindowPtr window, Rect boundsRect, ControlButtonContentInfo info) -> (ControlHandle outControl)")},
+	{"CreatePopupArrowControl", (PyCFunction)Ctl_CreatePopupArrowControl, 1,
+	 PyDoc_STR("(WindowPtr window, Rect boundsRect, UInt16 orientation, UInt16 size) -> (ControlHandle outControl)")},
+	{"CreatePlacardControl", (PyCFunction)Ctl_CreatePlacardControl, 1,
+	 PyDoc_STR("(WindowPtr window, Rect boundsRect) -> (ControlHandle outControl)")},
+	{"CreateClockControl", (PyCFunction)Ctl_CreateClockControl, 1,
+	 PyDoc_STR("(WindowPtr window, Rect boundsRect, UInt16 clockType, UInt32 clockFlags) -> (ControlHandle outControl)")},
+	{"CreateUserPaneControl", (PyCFunction)Ctl_CreateUserPaneControl, 1,
+	 PyDoc_STR("(WindowPtr window, Rect boundsRect, UInt32 features) -> (ControlHandle outControl)")},
+	{"CreateEditTextControl", (PyCFunction)Ctl_CreateEditTextControl, 1,
+	 PyDoc_STR("(WindowPtr window, Rect boundsRect, CFStringRef text, Boolean isPassword, Boolean useInlineInput, ControlFontStyleRec style) -> (ControlHandle outControl)")},
+	{"CreateStaticTextControl", (PyCFunction)Ctl_CreateStaticTextControl, 1,
+	 PyDoc_STR("(WindowPtr window, Rect boundsRect, CFStringRef text, ControlFontStyleRec style) -> (ControlHandle outControl)")},
+	{"CreatePictureControl", (PyCFunction)Ctl_CreatePictureControl, 1,
+	 PyDoc_STR("(WindowPtr window, Rect boundsRect, ControlButtonContentInfo content, Boolean dontTrack) -> (ControlHandle outControl)")},
+	{"CreateIconControl", (PyCFunction)Ctl_CreateIconControl, 1,
+	 PyDoc_STR("(WindowPtr inWindow, Rect inBoundsRect, ControlButtonContentInfo inIconContent, Boolean inDontTrack) -> (ControlHandle outControl)")},
+	{"CreateWindowHeaderControl", (PyCFunction)Ctl_CreateWindowHeaderControl, 1,
+	 PyDoc_STR("(WindowPtr window, Rect boundsRect, Boolean isListHeader) -> (ControlHandle outControl)")},
+	{"CreatePushButtonControl", (PyCFunction)Ctl_CreatePushButtonControl, 1,
+	 PyDoc_STR("(WindowPtr window, Rect boundsRect, CFStringRef title) -> (ControlHandle outControl)")},
+	{"CreatePushButtonWithIconControl", (PyCFunction)Ctl_CreatePushButtonWithIconControl, 1,
+	 PyDoc_STR("(WindowPtr window, Rect boundsRect, CFStringRef title, ControlButtonContentInfo icon, UInt16 iconAlignment) -> (ControlHandle outControl)")},
+	{"CreateRadioButtonControl", (PyCFunction)Ctl_CreateRadioButtonControl, 1,
+	 PyDoc_STR("(WindowPtr window, Rect boundsRect, CFStringRef title, SInt32 initialValue, Boolean autoToggle) -> (ControlHandle outControl)")},
+	{"CreateCheckBoxControl", (PyCFunction)Ctl_CreateCheckBoxControl, 1,
+	 PyDoc_STR("(WindowPtr window, Rect boundsRect, CFStringRef title, SInt32 initialValue, Boolean autoToggle) -> (ControlHandle outControl)")},
+	{"CreateScrollBarControl", (PyCFunction)Ctl_CreateScrollBarControl, 1,
+	 PyDoc_STR("(WindowPtr window, Rect boundsRect, SInt32 value, SInt32 minimum, SInt32 maximum, SInt32 viewSize, Boolean liveTracking, PyObject* liveTrackingProc) -> (ControlHandle outControl)")},
+	{"CreatePopupButtonControl", (PyCFunction)Ctl_CreatePopupButtonControl, 1,
+	 PyDoc_STR("(WindowPtr window, Rect boundsRect, CFStringRef title, SInt16 menuID, Boolean variableWidth, SInt16 titleWidth, SInt16 titleJustification, Style titleStyle) -> (ControlHandle outControl)")},
+	{"CreateRadioGroupControl", (PyCFunction)Ctl_CreateRadioGroupControl, 1,
+	 PyDoc_STR("(WindowPtr window, Rect boundsRect) -> (ControlHandle outControl)")},
+	{"CreateScrollingTextBoxControl", (PyCFunction)Ctl_CreateScrollingTextBoxControl, 1,
+	 PyDoc_STR("(WindowPtr window, Rect boundsRect, SInt16 contentResID, Boolean autoScroll, UInt32 delayBeforeAutoScroll, UInt32 delayBetweenAutoScroll, UInt16 autoScrollAmount) -> (ControlHandle outControl)")},
+	{"CreateDisclosureButtonControl", (PyCFunction)Ctl_CreateDisclosureButtonControl, 1,
+	 PyDoc_STR("(WindowPtr inWindow, Rect inBoundsRect, SInt32 inValue, Boolean inAutoToggles) -> (ControlHandle outControl)")},
+	{"CreateRoundButtonControl", (PyCFunction)Ctl_CreateRoundButtonControl, 1,
+	 PyDoc_STR("(WindowPtr inWindow, Rect inBoundsRect, SInt16 inSize, ControlButtonContentInfo inContent) -> (ControlHandle outControl)")},
+	{"CreateDataBrowserControl", (PyCFunction)Ctl_CreateDataBrowserControl, 1,
+	 PyDoc_STR("(WindowPtr window, Rect boundsRect, OSType style) -> (ControlHandle outControl)")},
+	{"CreateEditUnicodeTextControl", (PyCFunction)Ctl_CreateEditUnicodeTextControl, 1,
+	 PyDoc_STR("(WindowPtr window, Rect boundsRect, CFStringRef text, Boolean isPassword, ControlFontStyleRec style) -> (ControlHandle outControl)")},
+	{"FindControlUnderMouse", (PyCFunction)Ctl_FindControlUnderMouse, 1,
+	 PyDoc_STR("(Point inWhere, WindowPtr inWindow) -> (ControlHandle _rv, SInt16 outPart)")},
+	{"as_Control", (PyCFunction)Ctl_as_Control, 1,
+	 PyDoc_STR("(Handle h) -> (ControlHandle _rv)")},
+	{"CreateTabsControl", (PyCFunction)Ctl_CreateTabsControl, 1,
+	 PyDoc_STR("(WindowPtr window, Rect boundsRect, UInt16 size, UInt16 direction, ControlTabEntry tabArray) -> (ControlHandle outControl)")},
+	{NULL, NULL, 0}
+};
+
+
+
+static PyObject *
+CtlObj_NewUnmanaged(ControlHandle itself)
+{
+        ControlObject *it;
+        if (itself == NULL) return PyMac_Error(resNotFound);
+        it = PyObject_NEW(ControlObject, &Control_Type);
+        if (it == NULL) return NULL;
+        it->ob_itself = itself;
+        it->ob_callbackdict = NULL;
+        return (PyObject *)it;
+}
+
+static PyObject *
+CtlObj_WhichControl(ControlHandle c)
+{
+        PyObject *it;
+
+        if (c == NULL)
+                it = Py_None;
+        else {
+                it = (PyObject *) GetControlReference(c);
+                /*
+                ** If the refcon is zero or doesn't point back to the Python object
+                ** the control is not ours. Return a temporary object.
+                */
+                if (it == NULL || ((ControlObject *)it)->ob_itself != c)
+                        return CtlObj_NewUnmanaged(c);
+        }
+        Py_INCREF(it);
+        return it;
+}
+
+static int
+settrackfunc(PyObject *obj)
+{
+        if (tracker) {
+                PyErr_SetString(Ctl_Error, "Tracker function in use");
+                return 0;
+        }
+        tracker = obj;
+        Py_INCREF(tracker);
+        return 1;
+}
+
+static void
+clrtrackfunc(void)
+{
+        Py_XDECREF(tracker);
+        tracker = 0;
+}
+
+static pascal void
+mytracker(ControlHandle ctl, short part)
+{
+        PyObject *args, *rv=0;
+
+        args = Py_BuildValue("(O&i)", CtlObj_WhichControl, ctl, (int)part);
+        if (args && tracker) {
+                rv = PyEval_CallObject(tracker, args);
+                Py_DECREF(args);
+        }
+        if (rv)
+                Py_DECREF(rv);
+        else {
+                PySys_WriteStderr("TrackControl or HandleControlClick: exception in tracker function\n");
+                PyErr_Print();
+        }
+}
+
+static int
+setcallback(PyObject *myself, OSType which, PyObject *callback, UniversalProcPtr *uppp)
+{
+        ControlObject *self = (ControlObject *)myself;
+        char keybuf[9];
+
+        if ( which == kMyControlActionProcTag )
+                *uppp = (UniversalProcPtr)myactionproc_upp;
+        else if ( which == kControlUserPaneKeyDownProcTag )
+                *uppp = (UniversalProcPtr)mykeydownproc_upp;
+        else if ( which == kControlUserPaneFocusProcTag )
+                *uppp = (UniversalProcPtr)myfocusproc_upp;
+        else if ( which == kControlUserPaneDrawProcTag )
+                *uppp = (UniversalProcPtr)mydrawproc_upp;
+        else if ( which == kControlUserPaneIdleProcTag )
+                *uppp = (UniversalProcPtr)myidleproc_upp;
+        else if ( which == kControlUserPaneHitTestProcTag )
+                *uppp = (UniversalProcPtr)myhittestproc_upp;
+        else if ( which == kControlUserPaneTrackingProcTag )
+                *uppp = (UniversalProcPtr)mytrackingproc_upp;
+        else
+                return -1;
+        /* Only now do we test for clearing of the callback: */
+        if ( callback == Py_None )
+                *uppp = NULL;
+        /* Create the dict if it doesn't exist yet (so we don't get such a dict for every control) */
+        if ( self->ob_callbackdict == NULL )
+                if ( (self->ob_callbackdict = PyDict_New()) == NULL )
+                        return -1;
+        /* And store the Python callback */
+        sprintf(keybuf, "%x", (unsigned)which);
+        if (PyDict_SetItemString(self->ob_callbackdict, keybuf, callback) < 0)
+                return -1;
+        return 0;
+}
+
+static PyObject *
+callcallback(ControlObject *self, OSType which, PyObject *arglist)
+{
+        char keybuf[9];
+        PyObject *func, *rv;
+
+        sprintf(keybuf, "%x", (unsigned)which);
+        if ( self->ob_callbackdict == NULL ||
+                        (func = PyDict_GetItemString(self->ob_callbackdict, keybuf)) == NULL ) {
+                PySys_WriteStderr("Control callback %x without callback object\n", (unsigned)which);
+                return NULL;
+        }
+        rv = PyEval_CallObject(func, arglist);
+        if ( rv == NULL ) {
+                PySys_WriteStderr("Exception in control callback %x handler\n", (unsigned)which);
+                PyErr_Print();
+        }
+        return rv;
+}
+
+static pascal void
+myactionproc(ControlHandle control, SInt16 part)
+{
+        ControlObject *ctl_obj;
+        PyObject *arglist, *rv;
+
+        ctl_obj = (ControlObject *)CtlObj_WhichControl(control);
+        arglist = Py_BuildValue("Oh", ctl_obj, part);
+        rv = callcallback(ctl_obj, kMyControlActionProcTag, arglist);
+        Py_XDECREF(arglist);
+        Py_XDECREF(rv);
+}
+
+static pascal ControlPartCode
+mykeydownproc(ControlHandle control, SInt16 keyCode, SInt16 charCode, SInt16 modifiers)
+{
+        ControlObject *ctl_obj;
+        PyObject *arglist, *rv;
+        short c_rv = 0;
+
+        ctl_obj = (ControlObject *)CtlObj_WhichControl(control);
+        arglist = Py_BuildValue("Ohhh", ctl_obj, keyCode, charCode, modifiers);
+        rv = callcallback(ctl_obj, kControlUserPaneKeyDownProcTag, arglist);
+        Py_XDECREF(arglist);
+        if ( rv )
+                if (!PyArg_Parse(rv, "h", &c_rv))
+                        PyErr_Clear();
+        Py_XDECREF(rv);
+        return (ControlPartCode)c_rv;
+}
+
+static pascal ControlPartCode
+myfocusproc(ControlHandle control, ControlPartCode part)
+{
+        ControlObject *ctl_obj;
+        PyObject *arglist, *rv;
+        short c_rv = kControlFocusNoPart;
+
+        ctl_obj = (ControlObject *)CtlObj_WhichControl(control);
+        arglist = Py_BuildValue("Oh", ctl_obj, part);
+        rv = callcallback(ctl_obj, kControlUserPaneFocusProcTag, arglist);
+        Py_XDECREF(arglist);
+        if ( rv )
+                if (!PyArg_Parse(rv, "h", &c_rv))
+                        PyErr_Clear();
+        Py_XDECREF(rv);
+        return (ControlPartCode)c_rv;
+}
+
+static pascal void
+mydrawproc(ControlHandle control, SInt16 part)
+{
+        ControlObject *ctl_obj;
+        PyObject *arglist, *rv;
+
+        ctl_obj = (ControlObject *)CtlObj_WhichControl(control);
+        arglist = Py_BuildValue("Oh", ctl_obj, part);
+        rv = callcallback(ctl_obj, kControlUserPaneDrawProcTag, arglist);
+        Py_XDECREF(arglist);
+        Py_XDECREF(rv);
+}
+
+static pascal void
+myidleproc(ControlHandle control)
+{
+        ControlObject *ctl_obj;
+        PyObject *arglist, *rv;
+
+        ctl_obj = (ControlObject *)CtlObj_WhichControl(control);
+        arglist = Py_BuildValue("O", ctl_obj);
+        rv = callcallback(ctl_obj, kControlUserPaneIdleProcTag, arglist);
+        Py_XDECREF(arglist);
+        Py_XDECREF(rv);
+}
+
+static pascal ControlPartCode
+myhittestproc(ControlHandle control, Point where)
+{
+        ControlObject *ctl_obj;
+        PyObject *arglist, *rv;
+        short c_rv = -1;
+
+        ctl_obj = (ControlObject *)CtlObj_WhichControl(control);
+        arglist = Py_BuildValue("OO&", ctl_obj, PyMac_BuildPoint, where);
+        rv = callcallback(ctl_obj, kControlUserPaneHitTestProcTag, arglist);
+        Py_XDECREF(arglist);
+        /* Ignore errors, nothing we can do about them */
+        if ( rv )
+                if (!PyArg_Parse(rv, "h", &c_rv))
+                        PyErr_Clear();
+        Py_XDECREF(rv);
+        return (ControlPartCode)c_rv;
+}
+
+static pascal ControlPartCode
+mytrackingproc(ControlHandle control, Point startPt, ControlActionUPP actionProc)
+{
+        ControlObject *ctl_obj;
+        PyObject *arglist, *rv;
+        short c_rv = -1;
+
+        ctl_obj = (ControlObject *)CtlObj_WhichControl(control);
+        /* We cannot pass the actionProc without lots of work */
+        arglist = Py_BuildValue("OO&", ctl_obj, PyMac_BuildPoint, startPt);
+        rv = callcallback(ctl_obj, kControlUserPaneTrackingProcTag, arglist);
+        Py_XDECREF(arglist);
+        if ( rv )
+                if (!PyArg_Parse(rv, "h", &c_rv))
+                        PyErr_Clear();
+        Py_XDECREF(rv);
+        return (ControlPartCode)c_rv;
+}
+
+
+void init_Ctl(void)
+{
+	PyObject *m;
+	PyObject *d;
+
+
+
+	mytracker_upp = NewControlActionUPP(mytracker);
+	myactionproc_upp = NewControlActionUPP(myactionproc);
+	mykeydownproc_upp = NewControlUserPaneKeyDownUPP(mykeydownproc);
+	myfocusproc_upp = NewControlUserPaneFocusUPP(myfocusproc);
+	mydrawproc_upp = NewControlUserPaneDrawUPP(mydrawproc);
+	myidleproc_upp = NewControlUserPaneIdleUPP(myidleproc);
+	myhittestproc_upp = NewControlUserPaneHitTestUPP(myhittestproc);
+	mytrackingproc_upp = NewControlUserPaneTrackingUPP(mytrackingproc);
+	PyMac_INIT_TOOLBOX_OBJECT_NEW(ControlHandle, CtlObj_New);
+	PyMac_INIT_TOOLBOX_OBJECT_CONVERT(ControlHandle, CtlObj_Convert);
+
+
+	m = Py_InitModule("_Ctl", Ctl_methods);
+	d = PyModule_GetDict(m);
+	Ctl_Error = PyMac_GetOSErrException();
+	if (Ctl_Error == NULL ||
+	    PyDict_SetItemString(d, "Error", Ctl_Error) != 0)
+		return;
+	Control_Type.ob_type = &PyType_Type;
+	if (PyType_Ready(&Control_Type) < 0) return;
+	Py_INCREF(&Control_Type);
+	PyModule_AddObject(m, "Control", (PyObject *)&Control_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&Control_Type);
+	PyModule_AddObject(m, "ControlType", (PyObject *)&Control_Type);
+}
+
+/* ======================== End module _Ctl ========================= */
+

Added: vendor/Python/current/Mac/Modules/ctl/ctledit.py
===================================================================
--- vendor/Python/current/Mac/Modules/ctl/ctledit.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/ctl/ctledit.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,45 @@
+# FindControlUnderMouse() returns an existing control, not a new one,
+# so create this one by hand.
+f = Function(ExistingControlHandle, 'FindControlUnderMouse',
+    (Point, 'inWhere', InMode),
+    (WindowRef, 'inWindow', InMode),
+    (SInt16, 'outPart', OutMode),
+)
+functions.append(f)
+
+f = Function(ControlHandle, 'as_Control',
+        (Handle, 'h', InMode))
+functions.append(f)
+
+f = Method(Handle, 'as_Resource', (ControlHandle, 'ctl', InMode))
+methods.append(f)
+
+f = Method(void, 'GetControlRect', (ControlHandle, 'ctl', InMode), (Rect, 'rect', OutMode))
+methods.append(f)
+
+DisposeControl_body = """
+        if (!PyArg_ParseTuple(_args, ""))
+                return NULL;
+        if ( _self->ob_itself ) {
+                SetControlReference(_self->ob_itself, (long)0); /* Make it forget about us */
+                DisposeControl(_self->ob_itself);
+                _self->ob_itself = NULL;
+        }
+        Py_INCREF(Py_None);
+        _res = Py_None;
+        return _res;
+"""
+
+f = ManualGenerator("DisposeControl", DisposeControl_body)
+f.docstring = lambda : "() -> None"
+
+methods.append(f)
+
+# All CreateXxxXxxControl() functions return a new object in an output
+# parameter; these should however be managed by us (we're creating them
+# after all), so set the type to ControlRef.
+for f in functions:
+    if f.name.startswith("Create"):
+        v = f.argumentList[-1]
+        if v.type == ExistingControlHandle:
+            v.type = ControlRef

Added: vendor/Python/current/Mac/Modules/ctl/ctlscan.py
===================================================================
--- vendor/Python/current/Mac/Modules/ctl/ctlscan.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/ctl/ctlscan.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,172 @@
+# Scan <Controls.h>, generating ctlgen.py.
+import sys
+import os
+from bgenlocations import TOOLBOXDIR, BGENDIR
+sys.path.append(BGENDIR)
+
+from scantools import Scanner
+
+def main():
+#       input = "Controls.h" # Universal Headers < 3.3
+    input = ["Controls.h", "ControlDefinitions.h"] # Universal Headers >= 3.3
+    output = "ctlgen.py"
+    defsoutput = TOOLBOXDIR + "Controls.py"
+    scanner = MyScanner(input, output, defsoutput)
+    scanner.scan()
+    scanner.close()
+    print "=== Testing definitions output code ==="
+    execfile(defsoutput, {}, {})
+    print "=== Done scanning and generating, now doing 'import ctlsupport' ==="
+    import ctlsupport
+    print "=== Done.  It's up to you to compile Ctlmodule.c ==="
+
+class MyScanner(Scanner):
+
+    def destination(self, type, name, arglist):
+        classname = "Function"
+        listname = "functions"
+        if arglist:
+            t, n, m = arglist[0]
+            if t in ("ControlHandle", "ControlRef") and m == "InMode":
+                classname = "Method"
+                listname = "methods"
+        return classname, listname
+
+    def writeinitialdefs(self):
+        self.defsfile.write("def FOUR_CHAR_CODE(x): return x\n")
+        self.defsfile.write("from Carbon.TextEdit import *\n")
+        self.defsfile.write("from Carbon.QuickDraw import *\n")
+        self.defsfile.write("from Carbon.Dragconst import *\n")
+        self.defsfile.write("from Carbon.CarbonEvents import *\n")
+        self.defsfile.write("from Carbon.Appearance import *\n")
+        self.defsfile.write("kDataBrowserItemAnyState = -1\n")
+        self.defsfile.write("kControlBevelButtonCenterPopupGlyphTag = -1\n")
+        self.defsfile.write("kDataBrowserClientPropertyFlagsMask = 0xFF000000\n")
+        self.defsfile.write("\n")
+
+    def makeblacklistnames(self):
+        return [
+                'FindControlUnderMouse', # Generated manually, returns an existing control, not a new one.
+                'DisposeControl', # Generated manually
+                'KillControls', # Implied by close of dialog
+                'SetCtlAction',
+                'TrackControl', # Generated manually
+                'HandleControlClick',   # Generated manually
+                'SetControlData',       # Generated manually
+                'GetControlData',       # Generated manually
+                'kControlBevelButtonCenterPopupGlyphTag', # Constant with funny definition
+                'kDataBrowserClientPropertyFlagsMask',  # ditto
+                'kDataBrowserItemAnyState',   # and ditto
+                # The following are unavailable for static 68k (appearance manager)
+##                      'GetBevelButtonMenuValue',
+##                      'SetBevelButtonMenuValue',
+##                      'GetBevelButtonMenuHandle',
+##                      'SetBevelButtonTransform',
+                'SetBevelButtonGraphicAlignment',
+                'SetBevelButtonTextAlignment',
+                'SetBevelButtonTextPlacement',
+##                      'SetImageWellTransform',
+##                      'GetTabContentRect',
+##                      'SetTabEnabled',
+##                      'SetDisclosureTriangleLastValue',
+##                      # Unavailable in CW Pro 3 libraries
+##                      'SetUpControlTextColor',
+##                      # Unavailable in Jack's CW Pro 5.1 libraries
+##                      'GetControlRegion',
+##                      'RemoveControlProperty',
+##                      'IsValidControlHandle',
+##                      'SetControl32BitMinimum',
+##                      'GetControl32BitMinimum',
+##                      'SetControl32BitMaximum',
+##                      'GetControl32BitMaximum',
+##                      'SetControl32BitValue',
+##                      'GetControl32BitValue',
+##                      'SetControlViewSize',
+##                      'GetControlViewSize',
+                # Generally Bad News
+                'GetControlProperty',
+                'SetControlProperty',
+                'GetControlPropertySize',
+                'SendControlMessage', # Parameter changed from long to void* from UH3.3 to UH3.4
+                'CreateTabsControl',  # wrote manually
+                'GetControlAction',  # too much effort for too little usefulness
+
+                # too lazy for now
+                'GetImageWellContentInfo',
+                'GetBevelButtonContentInfo',
+                # OS8 only
+                'GetAuxiliaryControlRecord',
+                'SetControlColor',
+                ]
+
+    def makeblacklisttypes(self):
+        return [
+                'ProcPtr',
+#                       'ControlActionUPP',
+                'Ptr',
+                'ControlDefSpec', # Don't know how to do this yet
+                'ControlDefSpec_ptr', # ditto
+                'Collection', # Ditto
+                # not-yet-supported stuff in Universal Headers 3.4:
+                'ControlColorUPP',
+                'ControlKind',  # XXX easy: 2-tuple containing 2 OSType's
+#                       'ControlTabEntry_ptr', # XXX needed for tabs
+#                       'ControlButtonContentInfoPtr',
+#                       'ControlButtonContentInfo',  # XXX ugh: a union
+#                       'ControlButtonContentInfo_ptr',  # XXX ugh: a union
+                'ListDefSpec_ptr',  # XXX see _Listmodule.c, tricky but possible
+                'DataBrowserItemID_ptr',  # XXX array of UInt32, for BrowserView
+                'DataBrowserItemUPP',
+                'DataBrowserItemDataRef', # XXX void *
+                'DataBrowserCallbacks', # difficult struct
+                'DataBrowserCallbacks_ptr',
+                'DataBrowserCustomCallbacks',
+                'DataBrowserCustomCallbacks_ptr',
+##                      'DataBrowserTableViewColumnDesc',
+##                      'DataBrowserListViewColumnDesc',
+                'CFDataRef',
+                'DataBrowserListViewHeaderDesc', # difficult struct
+                ]
+
+    def makerepairinstructions(self):
+        return [
+                ([("void_ptr", "*", "InMode"), ("long", "*", "InMode")],
+                 [("InBuffer", "*", "*")]),
+
+                ([("void", "*", "OutMode"), ("long", "*", "InMode"),
+                                            ("long", "*", "OutMode")],
+                 [("VarVarOutBuffer", "*", "InOutMode")]),
+
+##                      # For TrackControl
+##                      ([("ProcPtr", "actionProc", "InMode")],
+##                       [("FakeType('(ControlActionUPP)0')", "*", "*")]),
+##                      ([("ControlActionUPP", "actionProc", "InMode")],
+##                       [("FakeType('(ControlActionUPP)0')", "*", "*")]),
+
+                # For GetControlTitle
+                ([('Str255', 'title', 'InMode')],
+                 [('Str255', 'title', 'OutMode')]),
+
+                ([("ControlHandle", "*", "OutMode")],
+                 [("ExistingControlHandle", "*", "*")]),
+                ([("ControlRef", "*", "OutMode")],      # Ditto, for Universal Headers
+                 [("ExistingControlHandle", "*", "*")]),
+
+                ([("Rect_ptr", "*", "ReturnMode")], # GetControlBounds
+                 [("void", "*", "ReturnMode")]),
+
+                ([("DataBrowserListViewColumnDesc", "*", "OutMode")],
+                 [("DataBrowserListViewColumnDesc", "*", "InMode")]),
+
+                ([("ControlButtonContentInfoPtr", 'outContent', "InMode")],
+                 [("ControlButtonContentInfoPtr", '*', "OutMode")]),
+
+                ([("ControlButtonContentInfo", '*', "OutMode")],
+                 [("ControlButtonContentInfo", '*', "InMode")]),
+
+                ([("ControlActionUPP", 'liveTrackingProc', "InMode")],
+                 [("ControlActionUPPNewControl", 'liveTrackingProc', "InMode")]),
+                ]
+
+if __name__ == "__main__":
+    main()

Added: vendor/Python/current/Mac/Modules/ctl/ctlsupport.py
===================================================================
--- vendor/Python/current/Mac/Modules/ctl/ctlsupport.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/ctl/ctlsupport.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,826 @@
+# This script generates a Python interface for an Apple Macintosh Manager.
+# It uses the "bgen" package to generate C code.
+# The function specifications are generated by scanning the mamager's header file,
+# using the "scantools" package (customized for this particular manager).
+
+import string
+
+# Declarations that change for each manager
+MACHEADERFILE = 'Controls.h'            # The Apple header file
+MODNAME = '_Ctl'                                # The name of the module
+OBJECTNAME = 'Control'                  # The basic name of the objects used here
+
+# The following is *usually* unchanged but may still require tuning
+MODPREFIX = 'Ctl'                       # The prefix for module-wide routines
+OBJECTTYPE = OBJECTNAME + 'Handle'      # The C type used to represent them
+OBJECTPREFIX = MODPREFIX + 'Obj'        # The prefix for object methods
+INPUTFILE = string.lower(MODPREFIX) + 'gen.py' # The file generated by the scanner
+OUTPUTFILE = MODNAME + "module.c"       # The file generated by this program
+
+from macsupport import *
+
+# Create the type objects
+
+ControlHandle = OpaqueByValueType(OBJECTTYPE, OBJECTPREFIX)
+ControlRef = ControlHandle
+ExistingControlHandle = OpaqueByValueType(OBJECTTYPE, "CtlObj_WhichControl", "BUG")
+
+RgnHandle = OpaqueByValueType("RgnHandle", "ResObj")
+CCTabHandle = OpaqueByValueType("CCTabHandle", "ResObj")
+AuxCtlHandle = OpaqueByValueType("AuxCtlHandle", "ResObj")
+ControlPartCode = Type("ControlPartCode", "h")
+DragConstraint = Type("DragConstraint", "H")
+ControlVariant = Type("ControlVariant", "h")
+IconTransformType = Type("IconTransformType", "h")
+EventModifiers = Type("EventModifiers", "H")
+ClickActivationResult = Type("ClickActivationResult", "l")
+ControlButtonGraphicAlignment = Type("ControlButtonGraphicAlignment", "h")
+ControlButtonTextAlignment = Type("ControlButtonTextAlignment", "h")
+ControlButtonTextPlacement = Type("ControlButtonTextPlacement", "h")
+ControlContentType = Type("ControlContentType", "h")
+ControlFocusPart = Type("ControlFocusPart", "h")
+
+ControlFontStyleRec = OpaqueType('ControlFontStyleRec', 'ControlFontStyle')
+ControlFontStyleRec_ptr = ControlFontStyleRec
+ControlID = OpaqueType('ControlID', 'PyControlID')
+ControlID_ptr = ControlID
+
+DragTrackingMessage = Type("DragTrackingMessage", "h")
+DragReference = OpaqueByValueType("DragReference", "DragObj")
+
+CFStringRef = OpaqueByValueType("CFStringRef", "CFStringRefObj")
+CFMutableStringRef = OpaqueByValueType("CFMutableStringRef", "CFMutableStringRefObj")
+CFDataRef = OpaqueByValueType("CFDataRef", "CFDataRefObj")
+
+ControlTabSize = UInt16
+ControlTabDirection = UInt16
+ControlPopupArrowOrientation = UInt16
+ControlPopupArrowSize = UInt16
+ControlClockType = UInt16
+ControlClockFlags = UInt32
+ControlRoundButtonSize = SInt16
+DataBrowserViewStyle = OSType
+DataBrowserItemID = UInt32
+DataBrowserEditCommand = UInt32
+DataBrowserSelectionAnchorDirection = UInt32
+DataBrowserItemState = UInt32
+DataBrowserPropertyID = UInt32
+DataBrowserRevealOptions = UInt8
+DataBrowserSortOrder = UInt16
+DataBrowserSelectionFlags = UInt32
+DataBrowserPropertyFlags = UInt32
+DataBrowserPropertyPart = OSType
+DataBrowserTableViewColumnID = DataBrowserPropertyID
+#DataBrowserTableViewColumnDesc = DataBrowserPropertyDesc
+DataBrowserTableViewHiliteStyle = UInt32
+DataBrowserTableViewRowIndex = UInt32
+DataBrowserTableViewColumnIndex = UInt32
+DataBrowserPropertyType = OSType
+ControlDisclosureTriangleOrientation = UInt16
+
+DataBrowserTableViewColumnDesc = OpaqueType("DataBrowserTableViewColumnDesc",
+                "DataBrowserTableViewColumnDesc")
+DataBrowserListViewColumnDesc = OpaqueType("DataBrowserListViewColumnDesc",
+                "DataBrowserListViewColumnDesc")
+ControlButtonContentInfo = OpaqueType("ControlButtonContentInfo",
+                "ControlButtonContentInfo")
+ControlButtonContentInfoPtr = ControlButtonContentInfo_ptr = ControlButtonContentInfo
+
+ControlTabEntry_ptr = OpaqueType("ControlTabEntry", "ControlTabEntry")
+
+ControlBevelThickness = UInt16
+ControlBevelButtonBehavior = UInt16
+ControlBevelButtonMenuBehavior = UInt16
+ControlBevelButtonMenuPlacement = UInt16
+ControlPushButtonIconAlignment = UInt16
+
+class ControlActionDefinition(Type):
+    def declare(self, name):
+        Output("%s %s;", self.typeName, name)
+        Output("UniversalProcPtr c_callback;")
+    def passInput(self, name):
+        return "myactionproc_upp"
+    def cleanup(self, name):
+        Output("setcallback((PyObject*)_self, kMyControlActionProcTag, actionProc, &c_callback);")
+
+class ControlActionDefinitionNewControl(ControlActionDefinition):
+    def cleanup(self, name):
+        Output("setcallback(_res, kMyControlActionProcTag, liveTrackingProc, &c_callback);")
+
+ControlActionUPP = ControlActionDefinition("PyObject*", "O")
+ControlActionUPPNewControl = ControlActionDefinitionNewControl("PyObject*", "O")
+ControlSliderOrientation = UInt16
+
+
+includestuff = includestuff + """
+#include <Carbon/Carbon.h>
+
+#ifdef USE_TOOLBOX_OBJECT_GLUE
+extern PyObject *_CtlObj_New(ControlHandle);
+extern int _CtlObj_Convert(PyObject *, ControlHandle *);
+
+#define CtlObj_New _CtlObj_New
+#define CtlObj_Convert _CtlObj_Convert
+#endif
+
+static PyObject *CtlObj_WhichControl(ControlHandle);
+
+#define as_Control(h) ((ControlHandle)h)
+#define as_Resource(ctl) ((Handle)ctl)
+#define GetControlRect(ctl, rectp) GetControlBounds(ctl, rectp)
+
+#define MAXTABS 32  /* maximum number of tabs that we support in a tabs control */
+/*
+** Parse/generate ControlFontStyleRec records
+*/
+#if 0 /* Not needed */
+static PyObject *
+ControlFontStyle_New(ControlFontStyleRec *itself)
+{
+
+        return Py_BuildValue("hhhhhhO&O&", itself->flags, itself->font,
+                itself->size, itself->style, itself->mode, itself->just,
+                QdRGB_New, &itself->foreColor, QdRGB_New, &itself->backColor);
+}
+#endif
+
+static int
+ControlFontStyle_Convert(PyObject *v, ControlFontStyleRec *itself)
+{
+        return PyArg_Parse(v, "(hhhhhhO&O&)", &itself->flags,
+                &itself->font, &itself->size, &itself->style, &itself->mode,
+                &itself->just, QdRGB_Convert, &itself->foreColor,
+                QdRGB_Convert, &itself->backColor);
+}
+
+/*
+** Parse/generate ControlID records
+*/
+static PyObject *
+PyControlID_New(ControlID *itself)
+{
+
+        return Py_BuildValue("O&l", PyMac_BuildOSType, itself->signature, itself->id);
+}
+
+static int
+PyControlID_Convert(PyObject *v, ControlID *itself)
+{
+        return PyArg_Parse(v, "(O&l)", PyMac_GetOSType, &itself->signature, &itself->id);
+}
+
+/*
+** generate DataBrowserListViewColumnDesc records
+*/
+static int
+DataBrowserTableViewColumnDesc_Convert(PyObject *v, DataBrowserTableViewColumnDesc *itself)
+{
+        return PyArg_Parse(v, "(lO&l)",
+                           &itself->propertyID,
+                           PyMac_GetOSType, &itself->propertyType,
+                           &itself->propertyFlags);
+}
+
+static int
+ControlButtonContentInfo_Convert(PyObject *v, ControlButtonContentInfo *itself)
+{
+        return PyArg_Parse(v, "(hO&)",
+                           &itself->contentType,
+                           OptResObj_Convert, &itself->u.iconSuite);
+}
+
+static int
+DataBrowserListViewHeaderDesc_Convert(PyObject *v, DataBrowserListViewHeaderDesc *itself)
+{
+        itself->version = kDataBrowserListViewLatestHeaderDesc;
+        return PyArg_Parse(v, "(HHhO&HO&O&)",
+                           &itself->minimumWidth,
+                           &itself->maximumWidth,
+                           &itself->titleOffset,
+                           CFStringRefObj_Convert, &itself->titleString,
+                           &itself->initialOrder,
+                           ControlFontStyle_Convert, &itself->btnFontStyle,
+                           ControlButtonContentInfo_Convert, &itself->btnContentInfo);
+}
+
+static int
+DataBrowserListViewColumnDesc_Convert(PyObject *v, DataBrowserListViewColumnDesc *itself)
+{
+        return PyArg_Parse(v, "(O&O&)",
+                           DataBrowserTableViewColumnDesc_Convert, &itself->propertyDesc,
+                           DataBrowserListViewHeaderDesc_Convert, &itself->headerBtnDesc);
+}
+
+/* TrackControl and HandleControlClick callback support */
+#define kMyControlActionProcTag 'ACTN'  /* not an official tag, only for internal use */
+static PyObject *tracker;
+static ControlActionUPP mytracker_upp;
+static ControlActionUPP myactionproc_upp;
+static ControlUserPaneKeyDownUPP mykeydownproc_upp;
+static ControlUserPaneFocusUPP myfocusproc_upp;
+static ControlUserPaneDrawUPP mydrawproc_upp;
+static ControlUserPaneIdleUPP myidleproc_upp;
+static ControlUserPaneHitTestUPP myhittestproc_upp;
+static ControlUserPaneTrackingUPP mytrackingproc_upp;
+
+static int settrackfunc(PyObject *);    /* forward */
+static void clrtrackfunc(void); /* forward */
+static int setcallback(PyObject *, OSType, PyObject *, UniversalProcPtr *);
+"""
+
+finalstuff = finalstuff + """
+static PyObject *
+CtlObj_NewUnmanaged(ControlHandle itself)
+{
+        ControlObject *it;
+        if (itself == NULL) return PyMac_Error(resNotFound);
+        it = PyObject_NEW(ControlObject, &Control_Type);
+        if (it == NULL) return NULL;
+        it->ob_itself = itself;
+        it->ob_callbackdict = NULL;
+        return (PyObject *)it;
+}
+
+static PyObject *
+CtlObj_WhichControl(ControlHandle c)
+{
+        PyObject *it;
+
+        if (c == NULL)
+                it = Py_None;
+        else {
+                it = (PyObject *) GetControlReference(c);
+                /*
+                ** If the refcon is zero or doesn't point back to the Python object
+                ** the control is not ours. Return a temporary object.
+                */
+                if (it == NULL || ((ControlObject *)it)->ob_itself != c)
+                        return CtlObj_NewUnmanaged(c);
+        }
+        Py_INCREF(it);
+        return it;
+}
+
+static int
+settrackfunc(PyObject *obj)
+{
+        if (tracker) {
+                PyErr_SetString(Ctl_Error, "Tracker function in use");
+                return 0;
+        }
+        tracker = obj;
+        Py_INCREF(tracker);
+        return 1;
+}
+
+static void
+clrtrackfunc(void)
+{
+        Py_XDECREF(tracker);
+        tracker = 0;
+}
+
+static pascal void
+mytracker(ControlHandle ctl, short part)
+{
+        PyObject *args, *rv=0;
+
+        args = Py_BuildValue("(O&i)", CtlObj_WhichControl, ctl, (int)part);
+        if (args && tracker) {
+                rv = PyEval_CallObject(tracker, args);
+                Py_DECREF(args);
+        }
+        if (rv)
+                Py_DECREF(rv);
+        else {
+                PySys_WriteStderr("TrackControl or HandleControlClick: exception in tracker function\\n");
+                PyErr_Print();
+        }
+}
+
+static int
+setcallback(PyObject *myself, OSType which, PyObject *callback, UniversalProcPtr *uppp)
+{
+        ControlObject *self = (ControlObject *)myself;
+        char keybuf[9];
+
+        if ( which == kMyControlActionProcTag )
+                *uppp = (UniversalProcPtr)myactionproc_upp;
+        else if ( which == kControlUserPaneKeyDownProcTag )
+                *uppp = (UniversalProcPtr)mykeydownproc_upp;
+        else if ( which == kControlUserPaneFocusProcTag )
+                *uppp = (UniversalProcPtr)myfocusproc_upp;
+        else if ( which == kControlUserPaneDrawProcTag )
+                *uppp = (UniversalProcPtr)mydrawproc_upp;
+        else if ( which == kControlUserPaneIdleProcTag )
+                *uppp = (UniversalProcPtr)myidleproc_upp;
+        else if ( which == kControlUserPaneHitTestProcTag )
+                *uppp = (UniversalProcPtr)myhittestproc_upp;
+        else if ( which == kControlUserPaneTrackingProcTag )
+                *uppp = (UniversalProcPtr)mytrackingproc_upp;
+        else
+                return -1;
+        /* Only now do we test for clearing of the callback: */
+        if ( callback == Py_None )
+                *uppp = NULL;
+        /* Create the dict if it doesn't exist yet (so we don't get such a dict for every control) */
+        if ( self->ob_callbackdict == NULL )
+                if ( (self->ob_callbackdict = PyDict_New()) == NULL )
+                        return -1;
+        /* And store the Python callback */
+        sprintf(keybuf, "%x", (unsigned)which);
+        if (PyDict_SetItemString(self->ob_callbackdict, keybuf, callback) < 0)
+                return -1;
+        return 0;
+}
+
+static PyObject *
+callcallback(ControlObject *self, OSType which, PyObject *arglist)
+{
+        char keybuf[9];
+        PyObject *func, *rv;
+
+        sprintf(keybuf, "%x", (unsigned)which);
+        if ( self->ob_callbackdict == NULL ||
+                        (func = PyDict_GetItemString(self->ob_callbackdict, keybuf)) == NULL ) {
+                PySys_WriteStderr("Control callback %x without callback object\\n", (unsigned)which);
+                return NULL;
+        }
+        rv = PyEval_CallObject(func, arglist);
+        if ( rv == NULL ) {
+                PySys_WriteStderr("Exception in control callback %x handler\\n", (unsigned)which);
+                PyErr_Print();
+        }
+        return rv;
+}
+
+static pascal void
+myactionproc(ControlHandle control, SInt16 part)
+{
+        ControlObject *ctl_obj;
+        PyObject *arglist, *rv;
+
+        ctl_obj = (ControlObject *)CtlObj_WhichControl(control);
+        arglist = Py_BuildValue("Oh", ctl_obj, part);
+        rv = callcallback(ctl_obj, kMyControlActionProcTag, arglist);
+        Py_XDECREF(arglist);
+        Py_XDECREF(rv);
+}
+
+static pascal ControlPartCode
+mykeydownproc(ControlHandle control, SInt16 keyCode, SInt16 charCode, SInt16 modifiers)
+{
+        ControlObject *ctl_obj;
+        PyObject *arglist, *rv;
+        short c_rv = 0;
+
+        ctl_obj = (ControlObject *)CtlObj_WhichControl(control);
+        arglist = Py_BuildValue("Ohhh", ctl_obj, keyCode, charCode, modifiers);
+        rv = callcallback(ctl_obj, kControlUserPaneKeyDownProcTag, arglist);
+        Py_XDECREF(arglist);
+        if ( rv )
+                if (!PyArg_Parse(rv, "h", &c_rv))
+                        PyErr_Clear();
+        Py_XDECREF(rv);
+        return (ControlPartCode)c_rv;
+}
+
+static pascal ControlPartCode
+myfocusproc(ControlHandle control, ControlPartCode part)
+{
+        ControlObject *ctl_obj;
+        PyObject *arglist, *rv;
+        short c_rv = kControlFocusNoPart;
+
+        ctl_obj = (ControlObject *)CtlObj_WhichControl(control);
+        arglist = Py_BuildValue("Oh", ctl_obj, part);
+        rv = callcallback(ctl_obj, kControlUserPaneFocusProcTag, arglist);
+        Py_XDECREF(arglist);
+        if ( rv )
+                if (!PyArg_Parse(rv, "h", &c_rv))
+                        PyErr_Clear();
+        Py_XDECREF(rv);
+        return (ControlPartCode)c_rv;
+}
+
+static pascal void
+mydrawproc(ControlHandle control, SInt16 part)
+{
+        ControlObject *ctl_obj;
+        PyObject *arglist, *rv;
+
+        ctl_obj = (ControlObject *)CtlObj_WhichControl(control);
+        arglist = Py_BuildValue("Oh", ctl_obj, part);
+        rv = callcallback(ctl_obj, kControlUserPaneDrawProcTag, arglist);
+        Py_XDECREF(arglist);
+        Py_XDECREF(rv);
+}
+
+static pascal void
+myidleproc(ControlHandle control)
+{
+        ControlObject *ctl_obj;
+        PyObject *arglist, *rv;
+
+        ctl_obj = (ControlObject *)CtlObj_WhichControl(control);
+        arglist = Py_BuildValue("O", ctl_obj);
+        rv = callcallback(ctl_obj, kControlUserPaneIdleProcTag, arglist);
+        Py_XDECREF(arglist);
+        Py_XDECREF(rv);
+}
+
+static pascal ControlPartCode
+myhittestproc(ControlHandle control, Point where)
+{
+        ControlObject *ctl_obj;
+        PyObject *arglist, *rv;
+        short c_rv = -1;
+
+        ctl_obj = (ControlObject *)CtlObj_WhichControl(control);
+        arglist = Py_BuildValue("OO&", ctl_obj, PyMac_BuildPoint, where);
+        rv = callcallback(ctl_obj, kControlUserPaneHitTestProcTag, arglist);
+        Py_XDECREF(arglist);
+        /* Ignore errors, nothing we can do about them */
+        if ( rv )
+                if (!PyArg_Parse(rv, "h", &c_rv))
+                        PyErr_Clear();
+        Py_XDECREF(rv);
+        return (ControlPartCode)c_rv;
+}
+
+static pascal ControlPartCode
+mytrackingproc(ControlHandle control, Point startPt, ControlActionUPP actionProc)
+{
+        ControlObject *ctl_obj;
+        PyObject *arglist, *rv;
+        short c_rv = -1;
+
+        ctl_obj = (ControlObject *)CtlObj_WhichControl(control);
+        /* We cannot pass the actionProc without lots of work */
+        arglist = Py_BuildValue("OO&", ctl_obj, PyMac_BuildPoint, startPt);
+        rv = callcallback(ctl_obj, kControlUserPaneTrackingProcTag, arglist);
+        Py_XDECREF(arglist);
+        if ( rv )
+                if (!PyArg_Parse(rv, "h", &c_rv))
+                        PyErr_Clear();
+        Py_XDECREF(rv);
+        return (ControlPartCode)c_rv;
+}
+"""
+
+initstuff = initstuff + """
+mytracker_upp = NewControlActionUPP(mytracker);
+myactionproc_upp = NewControlActionUPP(myactionproc);
+mykeydownproc_upp = NewControlUserPaneKeyDownUPP(mykeydownproc);
+myfocusproc_upp = NewControlUserPaneFocusUPP(myfocusproc);
+mydrawproc_upp = NewControlUserPaneDrawUPP(mydrawproc);
+myidleproc_upp = NewControlUserPaneIdleUPP(myidleproc);
+myhittestproc_upp = NewControlUserPaneHitTestUPP(myhittestproc);
+mytrackingproc_upp = NewControlUserPaneTrackingUPP(mytrackingproc);
+PyMac_INIT_TOOLBOX_OBJECT_NEW(ControlHandle, CtlObj_New);
+PyMac_INIT_TOOLBOX_OBJECT_CONVERT(ControlHandle, CtlObj_Convert);
+"""
+
+class MyObjectDefinition(PEP253Mixin, ObjectIdentityMixin, GlobalObjectDefinition):
+    def outputStructMembers(self):
+        GlobalObjectDefinition.outputStructMembers(self)
+        Output("PyObject *ob_callbackdict;")
+    def outputCheckNewArg(self):
+        Output("if (itself == NULL) return PyMac_Error(resNotFound);")
+    def outputInitStructMembers(self):
+        GlobalObjectDefinition.outputInitStructMembers(self)
+        Output("SetControlReference(itself, (long)it);")
+        Output("it->ob_callbackdict = NULL;")
+    def outputCleanupStructMembers(self):
+        Output("Py_XDECREF(self->ob_callbackdict);")
+        Output("if (self->ob_itself)SetControlReference(self->ob_itself, (long)0); /* Make it forget about us */")
+
+# Create the generator groups and link them
+module = MacModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff)
+object = MyObjectDefinition(OBJECTNAME, OBJECTPREFIX, OBJECTTYPE)
+module.addobject(object)
+
+# Create the generator classes used to populate the lists
+Function = OSErrWeakLinkFunctionGenerator
+Method = OSErrWeakLinkMethodGenerator
+
+# Create and populate the lists
+functions = []
+methods = []
+execfile(INPUTFILE)
+execfile('ctledit.py')
+
+# add the populated lists to the generator groups
+for f in functions: module.add(f)
+for f in methods: object.add(f)
+
+# Manual generator for TrackControl, due to callback ideosyncracies
+trackcontrol_body = """
+ControlPartCode _rv;
+Point startPoint;
+ControlActionUPP upp = 0;
+PyObject *callback = 0;
+
+if (!PyArg_ParseTuple(_args, "O&|O",
+                      PyMac_GetPoint, &startPoint, &callback))
+        return NULL;
+if (callback && callback != Py_None) {
+        if (PyInt_Check(callback) && PyInt_AS_LONG(callback) == -1)
+                upp = (ControlActionUPP)-1;
+        else {
+                settrackfunc(callback);
+                upp = mytracker_upp;
+        }
+}
+_rv = TrackControl(_self->ob_itself,
+                   startPoint,
+                   upp);
+clrtrackfunc();
+_res = Py_BuildValue("h",
+                     _rv);
+return _res;
+"""
+
+f = ManualGenerator("TrackControl", trackcontrol_body);
+f.docstring = lambda: "(Point startPoint [,trackercallback]) -> (ControlPartCode _rv)"
+object.add(f)
+
+# CJW - added 5/12/99
+# Manual generator for HandleControlClick, as for TrackControl
+handlecontrolclick_body = """
+ControlPartCode _rv;
+Point startPoint;
+SInt16 modifiers;
+ControlActionUPP upp = 0;
+PyObject *callback = 0;
+
+if (!PyArg_ParseTuple(_args, "O&h|O",
+                      PyMac_GetPoint, &startPoint,
+                      &modifiers,
+                      &callback))
+        return NULL;
+if (callback && callback != Py_None) {
+        if (PyInt_Check(callback) && PyInt_AS_LONG(callback) == -1)
+                upp = (ControlActionUPP)-1;
+        else {
+                settrackfunc(callback);
+                upp = mytracker_upp;
+        }
+}
+_rv = HandleControlClick(_self->ob_itself,
+                   startPoint,
+                   modifiers,
+                   upp);
+clrtrackfunc();
+_res = Py_BuildValue("h",
+                     _rv);
+return _res;
+"""
+
+f = ManualGenerator("HandleControlClick", handlecontrolclick_body);
+f.docstring = lambda: "(Point startPoint, Integer modifiers, [,trackercallback]) -> (ControlPartCode _rv)"
+object.add(f)
+
+# Manual Generator for SetControlData
+setcontroldata_body = """
+OSErr _err;
+ControlPartCode inPart;
+ResType inTagName;
+Size bufferSize;
+Ptr buffer;
+
+if (!PyArg_ParseTuple(_args, "hO&s#",
+                      &inPart,
+                      PyMac_GetOSType, &inTagName,
+                      &buffer, &bufferSize))
+        return NULL;
+
+_err = SetControlData(_self->ob_itself,
+                      inPart,
+                      inTagName,
+                      bufferSize,
+                      buffer);
+
+if (_err != noErr)
+        return PyMac_Error(_err);
+_res = Py_None;
+return _res;
+"""
+
+f = ManualGenerator("SetControlData", setcontroldata_body);
+f.docstring = lambda: "(stuff) -> None"
+object.add(f)
+
+# Manual Generator for GetControlData
+getcontroldata_body = """
+OSErr _err;
+ControlPartCode inPart;
+ResType inTagName;
+Size bufferSize;
+Ptr buffer;
+Size outSize;
+
+if (!PyArg_ParseTuple(_args, "hO&",
+                      &inPart,
+                      PyMac_GetOSType, &inTagName))
+        return NULL;
+
+/* allocate a buffer for the data */
+_err = GetControlDataSize(_self->ob_itself,
+                          inPart,
+                          inTagName,
+                          &bufferSize);
+if (_err != noErr)
+        return PyMac_Error(_err);
+buffer = PyMem_NEW(char, bufferSize);
+if (buffer == NULL)
+        return PyErr_NoMemory();
+
+_err = GetControlData(_self->ob_itself,
+                      inPart,
+                      inTagName,
+                      bufferSize,
+                      buffer,
+                      &outSize);
+
+if (_err != noErr) {
+        PyMem_DEL(buffer);
+        return PyMac_Error(_err);
+}
+_res = Py_BuildValue("s#", buffer, outSize);
+PyMem_DEL(buffer);
+return _res;
+"""
+
+f = ManualGenerator("GetControlData", getcontroldata_body);
+f.docstring = lambda: "(part, type) -> String"
+object.add(f)
+
+# Manual Generator for SetControlData_Handle
+setcontroldata_handle_body = """
+OSErr _err;
+ControlPartCode inPart;
+ResType inTagName;
+Handle buffer;
+
+if (!PyArg_ParseTuple(_args, "hO&O&",
+                      &inPart,
+                      PyMac_GetOSType, &inTagName,
+                      OptResObj_Convert, &buffer))
+        return NULL;
+
+_err = SetControlData(_self->ob_itself,
+                      inPart,
+                      inTagName,
+                      sizeof(buffer),
+                      (Ptr)&buffer);
+
+if (_err != noErr)
+        return PyMac_Error(_err);
+_res = Py_None;
+return _res;
+"""
+
+f = ManualGenerator("SetControlData_Handle", setcontroldata_handle_body);
+f.docstring = lambda: "(ResObj) -> None"
+object.add(f)
+
+# Manual Generator for GetControlData_Handle
+getcontroldata_handle_body = """
+OSErr _err;
+ControlPartCode inPart;
+ResType inTagName;
+Size bufferSize;
+Handle hdl;
+
+if (!PyArg_ParseTuple(_args, "hO&",
+                      &inPart,
+                      PyMac_GetOSType, &inTagName))
+        return NULL;
+
+/* Check it is handle-sized */
+_err = GetControlDataSize(_self->ob_itself,
+                          inPart,
+                          inTagName,
+                          &bufferSize);
+if (_err != noErr)
+        return PyMac_Error(_err);
+if (bufferSize != sizeof(Handle)) {
+        PyErr_SetString(Ctl_Error, "GetControlDataSize() != sizeof(Handle)");
+        return NULL;
+}
+
+_err = GetControlData(_self->ob_itself,
+                      inPart,
+                      inTagName,
+                      sizeof(Handle),
+                      (Ptr)&hdl,
+                      &bufferSize);
+
+if (_err != noErr) {
+        return PyMac_Error(_err);
+}
+_res = Py_BuildValue("O&", OptResObj_New, hdl);
+return _res;
+"""
+
+f = ManualGenerator("GetControlData_Handle", getcontroldata_handle_body);
+f.docstring = lambda: "(part, type) -> ResObj"
+object.add(f)
+
+# Manual Generator for SetControlData_Callback
+setcontroldata_callback_body = """
+OSErr _err;
+ControlPartCode inPart;
+ResType inTagName;
+PyObject *callback;
+UniversalProcPtr c_callback;
+
+if (!PyArg_ParseTuple(_args, "hO&O",
+                      &inPart,
+                      PyMac_GetOSType, &inTagName,
+                      &callback))
+        return NULL;
+
+if ( setcallback((PyObject *)_self, inTagName, callback, &c_callback) < 0 )
+        return NULL;
+_err = SetControlData(_self->ob_itself,
+                      inPart,
+                      inTagName,
+                      sizeof(c_callback),
+                      (Ptr)&c_callback);
+
+if (_err != noErr)
+        return PyMac_Error(_err);
+_res = Py_None;
+return _res;
+"""
+
+f = ManualGenerator("SetControlData_Callback", setcontroldata_callback_body);
+f.docstring = lambda: "(callbackfunc) -> None"
+object.add(f)
+
+
+
+createtabscontrol_body = """\
+OSStatus _err;
+WindowPtr window;
+Rect boundsRect;
+UInt16 size;
+UInt16 direction;
+int i;
+UInt16 numTabs;
+ControlTabEntry tabArray[MAXTABS];
+ControlHandle outControl;
+PyObject *tabArrayObj, *tabEntry;
+
+#ifndef CreateTabsControl
+PyMac_PRECHECK(CreateTabsControl);
+#endif
+if (!PyArg_ParseTuple(_args, "O&O&HHO",
+                      WinObj_Convert, &window,
+                      PyMac_GetRect, &boundsRect,
+                      &size,
+                      &direction,
+                      &tabArrayObj))
+        return NULL;
+
+i = PySequence_Length(tabArrayObj);
+if (i == -1)
+        return NULL;
+if (i > MAXTABS) {
+        PyErr_SetString(Ctl_Error, "Too many tabs");
+        return NULL;
+}
+numTabs = i;
+for (i=0; i<numTabs; i++) {
+        tabEntry = PySequence_GetItem(tabArrayObj, i);
+        if (tabEntry == NULL)
+                return NULL;
+        if (!PyArg_Parse(tabEntry, "(O&O&B)",
+                         ControlButtonContentInfo_Convert, &tabArray[i].icon,
+                         CFStringRefObj_Convert, &tabArray[i].name,
+                         &tabArray[i].enabled
+                         ))
+                return NULL;
+}
+
+_err = CreateTabsControl(window,
+                         &boundsRect,
+                         size,
+                         direction,
+                         numTabs,
+                         tabArray,
+                         &outControl);
+if (_err != noErr) return PyMac_Error(_err);
+_res = Py_BuildValue("O&",
+                     CtlObj_New, outControl);
+return _res;"""
+
+f = ManualGenerator("CreateTabsControl", createtabscontrol_body)
+f.docstring = lambda: "(WindowPtr window, Rect boundsRect, UInt16 size, UInt16 direction, ControlTabEntry tabArray) -> (ControlHandle outControl)"
+module.add(f)
+
+# generate output (open the output file as late as possible)
+SetOutputFileName(OUTPUTFILE)
+module.generate()

Added: vendor/Python/current/Mac/Modules/dlg/_Dlgmodule.c
===================================================================
--- vendor/Python/current/Mac/Modules/dlg/_Dlgmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/dlg/_Dlgmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1596 @@
+
+/* ========================== Module _Dlg =========================== */
+
+#include "Python.h"
+
+
+
+#include "pymactoolbox.h"
+
+/* Macro to test whether a weak-loaded CFM function exists */
+#define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL )  {\
+        PyErr_SetString(PyExc_NotImplementedError, \
+        "Not available in this shared library/OS version"); \
+        return NULL; \
+    }} while(0)
+
+
+#include <Carbon/Carbon.h>
+
+#ifdef USE_TOOLBOX_OBJECT_GLUE
+extern PyObject *_DlgObj_New(DialogRef);
+extern PyObject *_DlgObj_WhichDialog(DialogRef);
+extern int _DlgObj_Convert(PyObject *, DialogRef *);
+
+#define DlgObj_New _DlgObj_New
+#define DlgObj_WhichDialog _DlgObj_WhichDialog
+#define DlgObj_Convert _DlgObj_Convert
+#endif
+
+/* XXX Shouldn't this be a stack? */
+static PyObject *Dlg_FilterProc_callback = NULL;
+
+static pascal Boolean Dlg_UnivFilterProc(DialogPtr dialog,
+                                         EventRecord *event,
+                                         short *itemHit)
+{
+        Boolean rv;
+        PyObject *args, *res;
+        PyObject *callback = Dlg_FilterProc_callback;
+        if (callback == NULL)
+                return 0; /* Default behavior */
+        Dlg_FilterProc_callback = NULL; /* We'll restore it when call successful */
+        args = Py_BuildValue("O&O&", DlgObj_WhichDialog, dialog, PyMac_BuildEventRecord, event);
+        if (args == NULL)
+                res = NULL;
+        else {
+                res = PyEval_CallObject(callback, args);
+                Py_DECREF(args);
+        }
+        if (res == NULL) {
+                PySys_WriteStderr("Exception in Dialog Filter\n");
+                PyErr_Print();
+                *itemHit = -1; /* Fake return item */
+                return 1; /* We handled it */
+        }
+        else {
+                Dlg_FilterProc_callback = callback;
+                if (PyInt_Check(res)) {
+                        *itemHit = PyInt_AsLong(res);
+                        rv = 1;
+                }
+                else
+                        rv = PyObject_IsTrue(res);
+        }
+        Py_DECREF(res);
+        return rv;
+}
+
+static ModalFilterUPP
+Dlg_PassFilterProc(PyObject *callback)
+{
+        PyObject *tmp = Dlg_FilterProc_callback;
+        static ModalFilterUPP UnivFilterUpp = NULL;
+
+        Dlg_FilterProc_callback = NULL;
+        if (callback == Py_None) {
+                Py_XDECREF(tmp);
+                return NULL;
+        }
+        Py_INCREF(callback);
+        Dlg_FilterProc_callback = callback;
+        Py_XDECREF(tmp);
+        if ( UnivFilterUpp == NULL )
+                UnivFilterUpp = NewModalFilterUPP(&Dlg_UnivFilterProc);
+        return UnivFilterUpp;
+}
+
+static PyObject *Dlg_UserItemProc_callback = NULL;
+
+static pascal void Dlg_UnivUserItemProc(DialogPtr dialog,
+                                         short item)
+{
+        PyObject *args, *res;
+
+        if (Dlg_UserItemProc_callback == NULL)
+                return; /* Default behavior */
+        Dlg_FilterProc_callback = NULL; /* We'll restore it when call successful */
+        args = Py_BuildValue("O&h", DlgObj_WhichDialog, dialog, item);
+        if (args == NULL)
+                res = NULL;
+        else {
+                res = PyEval_CallObject(Dlg_UserItemProc_callback, args);
+                Py_DECREF(args);
+        }
+        if (res == NULL) {
+                PySys_WriteStderr("Exception in Dialog UserItem proc\n");
+                PyErr_Print();
+        }
+        Py_XDECREF(res);
+        return;
+}
+
+#if 0
+/*
+** Treating DialogObjects as WindowObjects is (I think) illegal under Carbon.
+** However, as they are still identical under MacOS9 Carbon this is a problem, even
+** if we neatly call GetDialogWindow() at the right places: there's one refcon field
+** and it points to the DialogObject, so WinObj_WhichWindow will smartly return the
+** dialog object, and therefore we still don't have a WindowObject.
+** I'll leave the chaining code in place for now, with this comment to warn the
+** unsuspecting victims (i.e. me, probably, in a few weeks:-)
+*/
+extern PyMethodChain WinObj_chain;
+#endif
+
+static PyObject *Dlg_Error;
+
+/* ----------------------- Object type Dialog ----------------------- */
+
+PyTypeObject Dialog_Type;
+
+#define DlgObj_Check(x) ((x)->ob_type == &Dialog_Type || PyObject_TypeCheck((x), &Dialog_Type))
+
+typedef struct DialogObject {
+	PyObject_HEAD
+	DialogPtr ob_itself;
+} DialogObject;
+
+PyObject *DlgObj_New(DialogPtr itself)
+{
+	DialogObject *it;
+	if (itself == NULL) { Py_INCREF(Py_None); return Py_None; }
+	it = PyObject_NEW(DialogObject, &Dialog_Type);
+	if (it == NULL) return NULL;
+	it->ob_itself = itself;
+	SetWRefCon(GetDialogWindow(itself), (long)it);
+	return (PyObject *)it;
+}
+
+int DlgObj_Convert(PyObject *v, DialogPtr *p_itself)
+{
+	if (v == Py_None) { *p_itself = NULL; return 1; }
+	if (PyInt_Check(v)) { *p_itself = (DialogPtr)PyInt_AsLong(v);
+	                      return 1; }
+	if (!DlgObj_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "Dialog required");
+		return 0;
+	}
+	*p_itself = ((DialogObject *)v)->ob_itself;
+	return 1;
+}
+
+static void DlgObj_dealloc(DialogObject *self)
+{
+	DisposeDialog(self->ob_itself);
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *DlgObj_DrawDialog(DialogObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef DrawDialog
+	PyMac_PRECHECK(DrawDialog);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	DrawDialog(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *DlgObj_UpdateDialog(DialogObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle updateRgn;
+#ifndef UpdateDialog
+	PyMac_PRECHECK(UpdateDialog);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &updateRgn))
+		return NULL;
+	UpdateDialog(_self->ob_itself,
+	             updateRgn);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *DlgObj_HideDialogItem(DialogObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	DialogItemIndex itemNo;
+#ifndef HideDialogItem
+	PyMac_PRECHECK(HideDialogItem);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &itemNo))
+		return NULL;
+	HideDialogItem(_self->ob_itself,
+	               itemNo);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *DlgObj_ShowDialogItem(DialogObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	DialogItemIndex itemNo;
+#ifndef ShowDialogItem
+	PyMac_PRECHECK(ShowDialogItem);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &itemNo))
+		return NULL;
+	ShowDialogItem(_self->ob_itself,
+	               itemNo);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *DlgObj_FindDialogItem(DialogObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	DialogItemIndexZeroBased _rv;
+	Point thePt;
+#ifndef FindDialogItem
+	PyMac_PRECHECK(FindDialogItem);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetPoint, &thePt))
+		return NULL;
+	_rv = FindDialogItem(_self->ob_itself,
+	                     thePt);
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *DlgObj_DialogCut(DialogObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef DialogCut
+	PyMac_PRECHECK(DialogCut);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	DialogCut(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *DlgObj_DialogPaste(DialogObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef DialogPaste
+	PyMac_PRECHECK(DialogPaste);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	DialogPaste(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *DlgObj_DialogCopy(DialogObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef DialogCopy
+	PyMac_PRECHECK(DialogCopy);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	DialogCopy(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *DlgObj_DialogDelete(DialogObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef DialogDelete
+	PyMac_PRECHECK(DialogDelete);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	DialogDelete(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *DlgObj_GetDialogItem(DialogObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	DialogItemIndex itemNo;
+	DialogItemType itemType;
+	Handle item;
+	Rect box;
+#ifndef GetDialogItem
+	PyMac_PRECHECK(GetDialogItem);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &itemNo))
+		return NULL;
+	GetDialogItem(_self->ob_itself,
+	              itemNo,
+	              &itemType,
+	              &item,
+	              &box);
+	_res = Py_BuildValue("hO&O&",
+	                     itemType,
+	                     OptResObj_New, item,
+	                     PyMac_BuildRect, &box);
+	return _res;
+}
+
+static PyObject *DlgObj_SetDialogItem(DialogObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	DialogItemIndex itemNo;
+	DialogItemType itemType;
+	Handle item;
+	Rect box;
+#ifndef SetDialogItem
+	PyMac_PRECHECK(SetDialogItem);
+#endif
+	if (!PyArg_ParseTuple(_args, "hhO&O&",
+	                      &itemNo,
+	                      &itemType,
+	                      ResObj_Convert, &item,
+	                      PyMac_GetRect, &box))
+		return NULL;
+	SetDialogItem(_self->ob_itself,
+	              itemNo,
+	              itemType,
+	              item,
+	              &box);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *DlgObj_SelectDialogItemText(DialogObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	DialogItemIndex itemNo;
+	SInt16 strtSel;
+	SInt16 endSel;
+#ifndef SelectDialogItemText
+	PyMac_PRECHECK(SelectDialogItemText);
+#endif
+	if (!PyArg_ParseTuple(_args, "hhh",
+	                      &itemNo,
+	                      &strtSel,
+	                      &endSel))
+		return NULL;
+	SelectDialogItemText(_self->ob_itself,
+	                     itemNo,
+	                     strtSel,
+	                     endSel);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *DlgObj_AppendDITL(DialogObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Handle theHandle;
+	DITLMethod method;
+#ifndef AppendDITL
+	PyMac_PRECHECK(AppendDITL);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      ResObj_Convert, &theHandle,
+	                      &method))
+		return NULL;
+	AppendDITL(_self->ob_itself,
+	           theHandle,
+	           method);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *DlgObj_CountDITL(DialogObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	DialogItemIndex _rv;
+#ifndef CountDITL
+	PyMac_PRECHECK(CountDITL);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CountDITL(_self->ob_itself);
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *DlgObj_ShortenDITL(DialogObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	DialogItemIndex numberItems;
+#ifndef ShortenDITL
+	PyMac_PRECHECK(ShortenDITL);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &numberItems))
+		return NULL;
+	ShortenDITL(_self->ob_itself,
+	            numberItems);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *DlgObj_InsertDialogItem(DialogObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	DialogItemIndex afterItem;
+	DialogItemType itemType;
+	Handle itemHandle;
+	Rect box;
+#ifndef InsertDialogItem
+	PyMac_PRECHECK(InsertDialogItem);
+#endif
+	if (!PyArg_ParseTuple(_args, "hhO&O&",
+	                      &afterItem,
+	                      &itemType,
+	                      ResObj_Convert, &itemHandle,
+	                      PyMac_GetRect, &box))
+		return NULL;
+	_err = InsertDialogItem(_self->ob_itself,
+	                        afterItem,
+	                        itemType,
+	                        itemHandle,
+	                        &box);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *DlgObj_RemoveDialogItems(DialogObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	DialogItemIndex itemNo;
+	DialogItemIndex amountToRemove;
+	Boolean disposeItemData;
+#ifndef RemoveDialogItems
+	PyMac_PRECHECK(RemoveDialogItems);
+#endif
+	if (!PyArg_ParseTuple(_args, "hhb",
+	                      &itemNo,
+	                      &amountToRemove,
+	                      &disposeItemData))
+		return NULL;
+	_err = RemoveDialogItems(_self->ob_itself,
+	                         itemNo,
+	                         amountToRemove,
+	                         disposeItemData);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *DlgObj_StdFilterProc(DialogObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	EventRecord event;
+	DialogItemIndex itemHit;
+#ifndef StdFilterProc
+	PyMac_PRECHECK(StdFilterProc);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      PyMac_GetEventRecord, &event,
+	                      &itemHit))
+		return NULL;
+	_rv = StdFilterProc(_self->ob_itself,
+	                    &event,
+	                    &itemHit);
+	_res = Py_BuildValue("bO&h",
+	                     _rv,
+	                     PyMac_BuildEventRecord, &event,
+	                     itemHit);
+	return _res;
+}
+
+static PyObject *DlgObj_SetDialogDefaultItem(DialogObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	DialogItemIndex newItem;
+#ifndef SetDialogDefaultItem
+	PyMac_PRECHECK(SetDialogDefaultItem);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &newItem))
+		return NULL;
+	_err = SetDialogDefaultItem(_self->ob_itself,
+	                            newItem);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *DlgObj_SetDialogCancelItem(DialogObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	DialogItemIndex newItem;
+#ifndef SetDialogCancelItem
+	PyMac_PRECHECK(SetDialogCancelItem);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &newItem))
+		return NULL;
+	_err = SetDialogCancelItem(_self->ob_itself,
+	                           newItem);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *DlgObj_SetDialogTracksCursor(DialogObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Boolean tracks;
+#ifndef SetDialogTracksCursor
+	PyMac_PRECHECK(SetDialogTracksCursor);
+#endif
+	if (!PyArg_ParseTuple(_args, "b",
+	                      &tracks))
+		return NULL;
+	_err = SetDialogTracksCursor(_self->ob_itself,
+	                             tracks);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *DlgObj_AutoSizeDialog(DialogObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+#ifndef AutoSizeDialog
+	PyMac_PRECHECK(AutoSizeDialog);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = AutoSizeDialog(_self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *DlgObj_GetDialogItemAsControl(DialogObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SInt16 inItemNo;
+	ControlHandle outControl;
+#ifndef GetDialogItemAsControl
+	PyMac_PRECHECK(GetDialogItemAsControl);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &inItemNo))
+		return NULL;
+	_err = GetDialogItemAsControl(_self->ob_itself,
+	                              inItemNo,
+	                              &outControl);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CtlObj_New, outControl);
+	return _res;
+}
+
+static PyObject *DlgObj_MoveDialogItem(DialogObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SInt16 inItemNo;
+	SInt16 inHoriz;
+	SInt16 inVert;
+#ifndef MoveDialogItem
+	PyMac_PRECHECK(MoveDialogItem);
+#endif
+	if (!PyArg_ParseTuple(_args, "hhh",
+	                      &inItemNo,
+	                      &inHoriz,
+	                      &inVert))
+		return NULL;
+	_err = MoveDialogItem(_self->ob_itself,
+	                      inItemNo,
+	                      inHoriz,
+	                      inVert);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *DlgObj_SizeDialogItem(DialogObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SInt16 inItemNo;
+	SInt16 inWidth;
+	SInt16 inHeight;
+#ifndef SizeDialogItem
+	PyMac_PRECHECK(SizeDialogItem);
+#endif
+	if (!PyArg_ParseTuple(_args, "hhh",
+	                      &inItemNo,
+	                      &inWidth,
+	                      &inHeight))
+		return NULL;
+	_err = SizeDialogItem(_self->ob_itself,
+	                      inItemNo,
+	                      inWidth,
+	                      inHeight);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *DlgObj_AppendDialogItemList(DialogObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SInt16 ditlID;
+	DITLMethod method;
+#ifndef AppendDialogItemList
+	PyMac_PRECHECK(AppendDialogItemList);
+#endif
+	if (!PyArg_ParseTuple(_args, "hh",
+	                      &ditlID,
+	                      &method))
+		return NULL;
+	_err = AppendDialogItemList(_self->ob_itself,
+	                            ditlID,
+	                            method);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *DlgObj_SetDialogTimeout(DialogObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	SInt16 inButtonToPress;
+	UInt32 inSecondsToWait;
+#ifndef SetDialogTimeout
+	PyMac_PRECHECK(SetDialogTimeout);
+#endif
+	if (!PyArg_ParseTuple(_args, "hl",
+	                      &inButtonToPress,
+	                      &inSecondsToWait))
+		return NULL;
+	_err = SetDialogTimeout(_self->ob_itself,
+	                        inButtonToPress,
+	                        inSecondsToWait);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *DlgObj_GetDialogTimeout(DialogObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	SInt16 outButtonToPress;
+	UInt32 outSecondsToWait;
+	UInt32 outSecondsRemaining;
+#ifndef GetDialogTimeout
+	PyMac_PRECHECK(GetDialogTimeout);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetDialogTimeout(_self->ob_itself,
+	                        &outButtonToPress,
+	                        &outSecondsToWait,
+	                        &outSecondsRemaining);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("hll",
+	                     outButtonToPress,
+	                     outSecondsToWait,
+	                     outSecondsRemaining);
+	return _res;
+}
+
+static PyObject *DlgObj_SetModalDialogEventMask(DialogObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	EventMask inMask;
+#ifndef SetModalDialogEventMask
+	PyMac_PRECHECK(SetModalDialogEventMask);
+#endif
+	if (!PyArg_ParseTuple(_args, "H",
+	                      &inMask))
+		return NULL;
+	_err = SetModalDialogEventMask(_self->ob_itself,
+	                               inMask);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *DlgObj_GetModalDialogEventMask(DialogObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	EventMask outMask;
+#ifndef GetModalDialogEventMask
+	PyMac_PRECHECK(GetModalDialogEventMask);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetModalDialogEventMask(_self->ob_itself,
+	                               &outMask);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("H",
+	                     outMask);
+	return _res;
+}
+
+static PyObject *DlgObj_GetDialogWindow(DialogObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	WindowPtr _rv;
+#ifndef GetDialogWindow
+	PyMac_PRECHECK(GetDialogWindow);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetDialogWindow(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     WinObj_New, _rv);
+	return _res;
+}
+
+static PyObject *DlgObj_GetDialogTextEditHandle(DialogObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	TEHandle _rv;
+#ifndef GetDialogTextEditHandle
+	PyMac_PRECHECK(GetDialogTextEditHandle);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetDialogTextEditHandle(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *DlgObj_GetDialogDefaultItem(DialogObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	SInt16 _rv;
+#ifndef GetDialogDefaultItem
+	PyMac_PRECHECK(GetDialogDefaultItem);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetDialogDefaultItem(_self->ob_itself);
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *DlgObj_GetDialogCancelItem(DialogObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	SInt16 _rv;
+#ifndef GetDialogCancelItem
+	PyMac_PRECHECK(GetDialogCancelItem);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetDialogCancelItem(_self->ob_itself);
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *DlgObj_GetDialogKeyboardFocusItem(DialogObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	SInt16 _rv;
+#ifndef GetDialogKeyboardFocusItem
+	PyMac_PRECHECK(GetDialogKeyboardFocusItem);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetDialogKeyboardFocusItem(_self->ob_itself);
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *DlgObj_SetPortDialogPort(DialogObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef SetPortDialogPort
+	PyMac_PRECHECK(SetPortDialogPort);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	SetPortDialogPort(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *DlgObj_GetDialogPort(DialogObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CGrafPtr _rv;
+#ifndef GetDialogPort
+	PyMac_PRECHECK(GetDialogPort);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetDialogPort(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     GrafObj_New, _rv);
+	return _res;
+}
+
+static PyMethodDef DlgObj_methods[] = {
+	{"DrawDialog", (PyCFunction)DlgObj_DrawDialog, 1,
+	 PyDoc_STR("() -> None")},
+	{"UpdateDialog", (PyCFunction)DlgObj_UpdateDialog, 1,
+	 PyDoc_STR("(RgnHandle updateRgn) -> None")},
+	{"HideDialogItem", (PyCFunction)DlgObj_HideDialogItem, 1,
+	 PyDoc_STR("(DialogItemIndex itemNo) -> None")},
+	{"ShowDialogItem", (PyCFunction)DlgObj_ShowDialogItem, 1,
+	 PyDoc_STR("(DialogItemIndex itemNo) -> None")},
+	{"FindDialogItem", (PyCFunction)DlgObj_FindDialogItem, 1,
+	 PyDoc_STR("(Point thePt) -> (DialogItemIndexZeroBased _rv)")},
+	{"DialogCut", (PyCFunction)DlgObj_DialogCut, 1,
+	 PyDoc_STR("() -> None")},
+	{"DialogPaste", (PyCFunction)DlgObj_DialogPaste, 1,
+	 PyDoc_STR("() -> None")},
+	{"DialogCopy", (PyCFunction)DlgObj_DialogCopy, 1,
+	 PyDoc_STR("() -> None")},
+	{"DialogDelete", (PyCFunction)DlgObj_DialogDelete, 1,
+	 PyDoc_STR("() -> None")},
+	{"GetDialogItem", (PyCFunction)DlgObj_GetDialogItem, 1,
+	 PyDoc_STR("(DialogItemIndex itemNo) -> (DialogItemType itemType, Handle item, Rect box)")},
+	{"SetDialogItem", (PyCFunction)DlgObj_SetDialogItem, 1,
+	 PyDoc_STR("(DialogItemIndex itemNo, DialogItemType itemType, Handle item, Rect box) -> None")},
+	{"SelectDialogItemText", (PyCFunction)DlgObj_SelectDialogItemText, 1,
+	 PyDoc_STR("(DialogItemIndex itemNo, SInt16 strtSel, SInt16 endSel) -> None")},
+	{"AppendDITL", (PyCFunction)DlgObj_AppendDITL, 1,
+	 PyDoc_STR("(Handle theHandle, DITLMethod method) -> None")},
+	{"CountDITL", (PyCFunction)DlgObj_CountDITL, 1,
+	 PyDoc_STR("() -> (DialogItemIndex _rv)")},
+	{"ShortenDITL", (PyCFunction)DlgObj_ShortenDITL, 1,
+	 PyDoc_STR("(DialogItemIndex numberItems) -> None")},
+	{"InsertDialogItem", (PyCFunction)DlgObj_InsertDialogItem, 1,
+	 PyDoc_STR("(DialogItemIndex afterItem, DialogItemType itemType, Handle itemHandle, Rect box) -> None")},
+	{"RemoveDialogItems", (PyCFunction)DlgObj_RemoveDialogItems, 1,
+	 PyDoc_STR("(DialogItemIndex itemNo, DialogItemIndex amountToRemove, Boolean disposeItemData) -> None")},
+	{"StdFilterProc", (PyCFunction)DlgObj_StdFilterProc, 1,
+	 PyDoc_STR("(EventRecord event, DialogItemIndex itemHit) -> (Boolean _rv, EventRecord event, DialogItemIndex itemHit)")},
+	{"SetDialogDefaultItem", (PyCFunction)DlgObj_SetDialogDefaultItem, 1,
+	 PyDoc_STR("(DialogItemIndex newItem) -> None")},
+	{"SetDialogCancelItem", (PyCFunction)DlgObj_SetDialogCancelItem, 1,
+	 PyDoc_STR("(DialogItemIndex newItem) -> None")},
+	{"SetDialogTracksCursor", (PyCFunction)DlgObj_SetDialogTracksCursor, 1,
+	 PyDoc_STR("(Boolean tracks) -> None")},
+	{"AutoSizeDialog", (PyCFunction)DlgObj_AutoSizeDialog, 1,
+	 PyDoc_STR("() -> None")},
+	{"GetDialogItemAsControl", (PyCFunction)DlgObj_GetDialogItemAsControl, 1,
+	 PyDoc_STR("(SInt16 inItemNo) -> (ControlHandle outControl)")},
+	{"MoveDialogItem", (PyCFunction)DlgObj_MoveDialogItem, 1,
+	 PyDoc_STR("(SInt16 inItemNo, SInt16 inHoriz, SInt16 inVert) -> None")},
+	{"SizeDialogItem", (PyCFunction)DlgObj_SizeDialogItem, 1,
+	 PyDoc_STR("(SInt16 inItemNo, SInt16 inWidth, SInt16 inHeight) -> None")},
+	{"AppendDialogItemList", (PyCFunction)DlgObj_AppendDialogItemList, 1,
+	 PyDoc_STR("(SInt16 ditlID, DITLMethod method) -> None")},
+	{"SetDialogTimeout", (PyCFunction)DlgObj_SetDialogTimeout, 1,
+	 PyDoc_STR("(SInt16 inButtonToPress, UInt32 inSecondsToWait) -> None")},
+	{"GetDialogTimeout", (PyCFunction)DlgObj_GetDialogTimeout, 1,
+	 PyDoc_STR("() -> (SInt16 outButtonToPress, UInt32 outSecondsToWait, UInt32 outSecondsRemaining)")},
+	{"SetModalDialogEventMask", (PyCFunction)DlgObj_SetModalDialogEventMask, 1,
+	 PyDoc_STR("(EventMask inMask) -> None")},
+	{"GetModalDialogEventMask", (PyCFunction)DlgObj_GetModalDialogEventMask, 1,
+	 PyDoc_STR("() -> (EventMask outMask)")},
+	{"GetDialogWindow", (PyCFunction)DlgObj_GetDialogWindow, 1,
+	 PyDoc_STR("() -> (WindowPtr _rv)")},
+	{"GetDialogTextEditHandle", (PyCFunction)DlgObj_GetDialogTextEditHandle, 1,
+	 PyDoc_STR("() -> (TEHandle _rv)")},
+	{"GetDialogDefaultItem", (PyCFunction)DlgObj_GetDialogDefaultItem, 1,
+	 PyDoc_STR("() -> (SInt16 _rv)")},
+	{"GetDialogCancelItem", (PyCFunction)DlgObj_GetDialogCancelItem, 1,
+	 PyDoc_STR("() -> (SInt16 _rv)")},
+	{"GetDialogKeyboardFocusItem", (PyCFunction)DlgObj_GetDialogKeyboardFocusItem, 1,
+	 PyDoc_STR("() -> (SInt16 _rv)")},
+	{"SetPortDialogPort", (PyCFunction)DlgObj_SetPortDialogPort, 1,
+	 PyDoc_STR("() -> None")},
+	{"GetDialogPort", (PyCFunction)DlgObj_GetDialogPort, 1,
+	 PyDoc_STR("() -> (CGrafPtr _rv)")},
+	{NULL, NULL, 0}
+};
+
+#define DlgObj_getsetlist NULL
+
+
+static int DlgObj_compare(DialogObject *self, DialogObject *other)
+{
+	if ( self->ob_itself > other->ob_itself ) return 1;
+	if ( self->ob_itself < other->ob_itself ) return -1;
+	return 0;
+}
+
+#define DlgObj_repr NULL
+
+static int DlgObj_hash(DialogObject *self)
+{
+	return (int)self->ob_itself;
+}
+#define DlgObj_tp_init 0
+
+#define DlgObj_tp_alloc PyType_GenericAlloc
+
+static PyObject *DlgObj_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *_self;
+	DialogPtr itself;
+	char *kw[] = {"itself", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, DlgObj_Convert, &itself)) return NULL;
+	if ((_self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	((DialogObject *)_self)->ob_itself = itself;
+	return _self;
+}
+
+#define DlgObj_tp_free PyObject_Del
+
+
+PyTypeObject Dialog_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"_Dlg.Dialog", /*tp_name*/
+	sizeof(DialogObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) DlgObj_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) DlgObj_compare, /*tp_compare*/
+	(reprfunc) DlgObj_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) DlgObj_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	DlgObj_methods, /* tp_methods */
+	0, /*tp_members*/
+	DlgObj_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	DlgObj_tp_init, /* tp_init */
+	DlgObj_tp_alloc, /* tp_alloc */
+	DlgObj_tp_new, /* tp_new */
+	DlgObj_tp_free, /* tp_free */
+};
+
+/* --------------------- End object type Dialog --------------------- */
+
+
+static PyObject *Dlg_NewDialog(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	DialogPtr _rv;
+	Rect boundsRect;
+	Str255 title;
+	Boolean visible;
+	SInt16 procID;
+	WindowPtr behind;
+	Boolean goAwayFlag;
+	SInt32 refCon;
+	Handle items;
+#ifndef NewDialog
+	PyMac_PRECHECK(NewDialog);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&bhO&blO&",
+	                      PyMac_GetRect, &boundsRect,
+	                      PyMac_GetStr255, title,
+	                      &visible,
+	                      &procID,
+	                      WinObj_Convert, &behind,
+	                      &goAwayFlag,
+	                      &refCon,
+	                      ResObj_Convert, &items))
+		return NULL;
+	_rv = NewDialog((void *)0,
+	                &boundsRect,
+	                title,
+	                visible,
+	                procID,
+	                behind,
+	                goAwayFlag,
+	                refCon,
+	                items);
+	_res = Py_BuildValue("O&",
+	                     DlgObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Dlg_GetNewDialog(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	DialogPtr _rv;
+	SInt16 dialogID;
+	WindowPtr behind;
+#ifndef GetNewDialog
+	PyMac_PRECHECK(GetNewDialog);
+#endif
+	if (!PyArg_ParseTuple(_args, "hO&",
+	                      &dialogID,
+	                      WinObj_Convert, &behind))
+		return NULL;
+	_rv = GetNewDialog(dialogID,
+	                   (void *)0,
+	                   behind);
+	_res = Py_BuildValue("O&",
+	                     DlgObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Dlg_NewColorDialog(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	DialogPtr _rv;
+	Rect boundsRect;
+	Str255 title;
+	Boolean visible;
+	SInt16 procID;
+	WindowPtr behind;
+	Boolean goAwayFlag;
+	SInt32 refCon;
+	Handle items;
+#ifndef NewColorDialog
+	PyMac_PRECHECK(NewColorDialog);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&bhO&blO&",
+	                      PyMac_GetRect, &boundsRect,
+	                      PyMac_GetStr255, title,
+	                      &visible,
+	                      &procID,
+	                      WinObj_Convert, &behind,
+	                      &goAwayFlag,
+	                      &refCon,
+	                      ResObj_Convert, &items))
+		return NULL;
+	_rv = NewColorDialog((void *)0,
+	                     &boundsRect,
+	                     title,
+	                     visible,
+	                     procID,
+	                     behind,
+	                     goAwayFlag,
+	                     refCon,
+	                     items);
+	_res = Py_BuildValue("O&",
+	                     DlgObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Dlg_ModalDialog(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PyObject* modalFilter;
+	DialogItemIndex itemHit;
+#ifndef ModalDialog
+	PyMac_PRECHECK(ModalDialog);
+#endif
+	if (!PyArg_ParseTuple(_args, "O",
+	                      &modalFilter))
+		return NULL;
+	ModalDialog(Dlg_PassFilterProc(modalFilter),
+	            &itemHit);
+	_res = Py_BuildValue("h",
+	                     itemHit);
+	return _res;
+}
+
+static PyObject *Dlg_IsDialogEvent(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	EventRecord theEvent;
+#ifndef IsDialogEvent
+	PyMac_PRECHECK(IsDialogEvent);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetEventRecord, &theEvent))
+		return NULL;
+	_rv = IsDialogEvent(&theEvent);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Dlg_DialogSelect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	EventRecord theEvent;
+	DialogPtr theDialog;
+	DialogItemIndex itemHit;
+#ifndef DialogSelect
+	PyMac_PRECHECK(DialogSelect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetEventRecord, &theEvent))
+		return NULL;
+	_rv = DialogSelect(&theEvent,
+	                   &theDialog,
+	                   &itemHit);
+	_res = Py_BuildValue("bO&h",
+	                     _rv,
+	                     DlgObj_WhichDialog, theDialog,
+	                     itemHit);
+	return _res;
+}
+
+static PyObject *Dlg_Alert(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	DialogItemIndex _rv;
+	SInt16 alertID;
+	PyObject* modalFilter;
+#ifndef Alert
+	PyMac_PRECHECK(Alert);
+#endif
+	if (!PyArg_ParseTuple(_args, "hO",
+	                      &alertID,
+	                      &modalFilter))
+		return NULL;
+	_rv = Alert(alertID,
+	            Dlg_PassFilterProc(modalFilter));
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Dlg_StopAlert(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	DialogItemIndex _rv;
+	SInt16 alertID;
+	PyObject* modalFilter;
+#ifndef StopAlert
+	PyMac_PRECHECK(StopAlert);
+#endif
+	if (!PyArg_ParseTuple(_args, "hO",
+	                      &alertID,
+	                      &modalFilter))
+		return NULL;
+	_rv = StopAlert(alertID,
+	                Dlg_PassFilterProc(modalFilter));
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Dlg_NoteAlert(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	DialogItemIndex _rv;
+	SInt16 alertID;
+	PyObject* modalFilter;
+#ifndef NoteAlert
+	PyMac_PRECHECK(NoteAlert);
+#endif
+	if (!PyArg_ParseTuple(_args, "hO",
+	                      &alertID,
+	                      &modalFilter))
+		return NULL;
+	_rv = NoteAlert(alertID,
+	                Dlg_PassFilterProc(modalFilter));
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Dlg_CautionAlert(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	DialogItemIndex _rv;
+	SInt16 alertID;
+	PyObject* modalFilter;
+#ifndef CautionAlert
+	PyMac_PRECHECK(CautionAlert);
+#endif
+	if (!PyArg_ParseTuple(_args, "hO",
+	                      &alertID,
+	                      &modalFilter))
+		return NULL;
+	_rv = CautionAlert(alertID,
+	                   Dlg_PassFilterProc(modalFilter));
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Dlg_ParamText(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Str255 param0;
+	Str255 param1;
+	Str255 param2;
+	Str255 param3;
+#ifndef ParamText
+	PyMac_PRECHECK(ParamText);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&O&",
+	                      PyMac_GetStr255, param0,
+	                      PyMac_GetStr255, param1,
+	                      PyMac_GetStr255, param2,
+	                      PyMac_GetStr255, param3))
+		return NULL;
+	ParamText(param0,
+	          param1,
+	          param2,
+	          param3);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Dlg_GetDialogItemText(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Handle item;
+	Str255 text;
+#ifndef GetDialogItemText
+	PyMac_PRECHECK(GetDialogItemText);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &item))
+		return NULL;
+	GetDialogItemText(item,
+	                  text);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildStr255, text);
+	return _res;
+}
+
+static PyObject *Dlg_SetDialogItemText(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Handle item;
+	Str255 text;
+#ifndef SetDialogItemText
+	PyMac_PRECHECK(SetDialogItemText);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      ResObj_Convert, &item,
+	                      PyMac_GetStr255, text))
+		return NULL;
+	SetDialogItemText(item,
+	                  text);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Dlg_GetAlertStage(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	SInt16 _rv;
+#ifndef GetAlertStage
+	PyMac_PRECHECK(GetAlertStage);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetAlertStage();
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Dlg_SetDialogFont(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	SInt16 fontNum;
+#ifndef SetDialogFont
+	PyMac_PRECHECK(SetDialogFont);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &fontNum))
+		return NULL;
+	SetDialogFont(fontNum);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Dlg_ResetAlertStage(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef ResetAlertStage
+	PyMac_PRECHECK(ResetAlertStage);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	ResetAlertStage();
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Dlg_GetParamText(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Str255 param0;
+	Str255 param1;
+	Str255 param2;
+	Str255 param3;
+#ifndef GetParamText
+	PyMac_PRECHECK(GetParamText);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&O&",
+	                      PyMac_GetStr255, param0,
+	                      PyMac_GetStr255, param1,
+	                      PyMac_GetStr255, param2,
+	                      PyMac_GetStr255, param3))
+		return NULL;
+	GetParamText(param0,
+	             param1,
+	             param2,
+	             param3);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Dlg_NewFeaturesDialog(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	DialogPtr _rv;
+	Rect inBoundsRect;
+	Str255 inTitle;
+	Boolean inIsVisible;
+	SInt16 inProcID;
+	WindowPtr inBehind;
+	Boolean inGoAwayFlag;
+	SInt32 inRefCon;
+	Handle inItemListHandle;
+	UInt32 inFlags;
+#ifndef NewFeaturesDialog
+	PyMac_PRECHECK(NewFeaturesDialog);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&bhO&blO&l",
+	                      PyMac_GetRect, &inBoundsRect,
+	                      PyMac_GetStr255, inTitle,
+	                      &inIsVisible,
+	                      &inProcID,
+	                      WinObj_Convert, &inBehind,
+	                      &inGoAwayFlag,
+	                      &inRefCon,
+	                      ResObj_Convert, &inItemListHandle,
+	                      &inFlags))
+		return NULL;
+	_rv = NewFeaturesDialog((void *)0,
+	                        &inBoundsRect,
+	                        inTitle,
+	                        inIsVisible,
+	                        inProcID,
+	                        inBehind,
+	                        inGoAwayFlag,
+	                        inRefCon,
+	                        inItemListHandle,
+	                        inFlags);
+	_res = Py_BuildValue("O&",
+	                     DlgObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Dlg_GetDialogFromWindow(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	DialogPtr _rv;
+	WindowPtr window;
+#ifndef GetDialogFromWindow
+	PyMac_PRECHECK(GetDialogFromWindow);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      WinObj_Convert, &window))
+		return NULL;
+	_rv = GetDialogFromWindow(window);
+	_res = Py_BuildValue("O&",
+	                     DlgObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Dlg_SetUserItemHandler(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+
+	        PyObject *new = NULL;
+
+
+	        if (!PyArg_ParseTuple(_args, "|O", &new))
+	                return NULL;
+
+	        if (Dlg_UserItemProc_callback && new && new != Py_None) {
+	                PyErr_SetString(Dlg_Error, "Another UserItemProc is already installed");
+	                return NULL;
+	        }
+
+	        if (new == NULL || new == Py_None) {
+	                new = NULL;
+	                _res = Py_None;
+	                Py_INCREF(Py_None);
+	        } else {
+	                Py_INCREF(new);
+	                _res = Py_BuildValue("O&", ResObj_New, (Handle)NewUserItemUPP(Dlg_UnivUserItemProc));
+	        }
+
+	        Dlg_UserItemProc_callback = new;
+	        return _res;
+
+}
+
+static PyMethodDef Dlg_methods[] = {
+	{"NewDialog", (PyCFunction)Dlg_NewDialog, 1,
+	 PyDoc_STR("(Rect boundsRect, Str255 title, Boolean visible, SInt16 procID, WindowPtr behind, Boolean goAwayFlag, SInt32 refCon, Handle items) -> (DialogPtr _rv)")},
+	{"GetNewDialog", (PyCFunction)Dlg_GetNewDialog, 1,
+	 PyDoc_STR("(SInt16 dialogID, WindowPtr behind) -> (DialogPtr _rv)")},
+	{"NewColorDialog", (PyCFunction)Dlg_NewColorDialog, 1,
+	 PyDoc_STR("(Rect boundsRect, Str255 title, Boolean visible, SInt16 procID, WindowPtr behind, Boolean goAwayFlag, SInt32 refCon, Handle items) -> (DialogPtr _rv)")},
+	{"ModalDialog", (PyCFunction)Dlg_ModalDialog, 1,
+	 PyDoc_STR("(PyObject* modalFilter) -> (DialogItemIndex itemHit)")},
+	{"IsDialogEvent", (PyCFunction)Dlg_IsDialogEvent, 1,
+	 PyDoc_STR("(EventRecord theEvent) -> (Boolean _rv)")},
+	{"DialogSelect", (PyCFunction)Dlg_DialogSelect, 1,
+	 PyDoc_STR("(EventRecord theEvent) -> (Boolean _rv, DialogPtr theDialog, DialogItemIndex itemHit)")},
+	{"Alert", (PyCFunction)Dlg_Alert, 1,
+	 PyDoc_STR("(SInt16 alertID, PyObject* modalFilter) -> (DialogItemIndex _rv)")},
+	{"StopAlert", (PyCFunction)Dlg_StopAlert, 1,
+	 PyDoc_STR("(SInt16 alertID, PyObject* modalFilter) -> (DialogItemIndex _rv)")},
+	{"NoteAlert", (PyCFunction)Dlg_NoteAlert, 1,
+	 PyDoc_STR("(SInt16 alertID, PyObject* modalFilter) -> (DialogItemIndex _rv)")},
+	{"CautionAlert", (PyCFunction)Dlg_CautionAlert, 1,
+	 PyDoc_STR("(SInt16 alertID, PyObject* modalFilter) -> (DialogItemIndex _rv)")},
+	{"ParamText", (PyCFunction)Dlg_ParamText, 1,
+	 PyDoc_STR("(Str255 param0, Str255 param1, Str255 param2, Str255 param3) -> None")},
+	{"GetDialogItemText", (PyCFunction)Dlg_GetDialogItemText, 1,
+	 PyDoc_STR("(Handle item) -> (Str255 text)")},
+	{"SetDialogItemText", (PyCFunction)Dlg_SetDialogItemText, 1,
+	 PyDoc_STR("(Handle item, Str255 text) -> None")},
+	{"GetAlertStage", (PyCFunction)Dlg_GetAlertStage, 1,
+	 PyDoc_STR("() -> (SInt16 _rv)")},
+	{"SetDialogFont", (PyCFunction)Dlg_SetDialogFont, 1,
+	 PyDoc_STR("(SInt16 fontNum) -> None")},
+	{"ResetAlertStage", (PyCFunction)Dlg_ResetAlertStage, 1,
+	 PyDoc_STR("() -> None")},
+	{"GetParamText", (PyCFunction)Dlg_GetParamText, 1,
+	 PyDoc_STR("(Str255 param0, Str255 param1, Str255 param2, Str255 param3) -> None")},
+	{"NewFeaturesDialog", (PyCFunction)Dlg_NewFeaturesDialog, 1,
+	 PyDoc_STR("(Rect inBoundsRect, Str255 inTitle, Boolean inIsVisible, SInt16 inProcID, WindowPtr inBehind, Boolean inGoAwayFlag, SInt32 inRefCon, Handle inItemListHandle, UInt32 inFlags) -> (DialogPtr _rv)")},
+	{"GetDialogFromWindow", (PyCFunction)Dlg_GetDialogFromWindow, 1,
+	 PyDoc_STR("(WindowPtr window) -> (DialogPtr _rv)")},
+	{"SetUserItemHandler", (PyCFunction)Dlg_SetUserItemHandler, 1,
+	 PyDoc_STR(NULL)},
+	{NULL, NULL, 0}
+};
+
+
+
+/* Return the WindowPtr corresponding to a DialogObject */
+#if 0
+WindowPtr
+DlgObj_ConvertToWindow(PyObject *self)
+{
+        if ( DlgObj_Check(self) )
+                return GetDialogWindow(((DialogObject *)self)->ob_itself);
+        return NULL;
+}
+#endif
+/* Return the object corresponding to the dialog, or None */
+
+PyObject *
+DlgObj_WhichDialog(DialogPtr d)
+{
+        PyObject *it;
+
+        if (d == NULL) {
+                it = Py_None;
+                Py_INCREF(it);
+        } else {
+                WindowPtr w = GetDialogWindow(d);
+
+                it = (PyObject *) GetWRefCon(w);
+                if (it == NULL || ((DialogObject *)it)->ob_itself != d || !DlgObj_Check(it)) {
+#if 0
+                        /* Should do this, but we don't have an ob_freeit for dialogs yet. */
+                        it = WinObj_New(w);
+                        ((WindowObject *)it)->ob_freeit = NULL;
+#else
+                        it = Py_None;
+                        Py_INCREF(it);
+#endif
+                } else {
+                        Py_INCREF(it);
+                }
+        }
+        return it;
+}
+
+
+void init_Dlg(void)
+{
+	PyObject *m;
+	PyObject *d;
+
+
+
+	        PyMac_INIT_TOOLBOX_OBJECT_NEW(DialogPtr, DlgObj_New);
+	        PyMac_INIT_TOOLBOX_OBJECT_NEW(DialogPtr, DlgObj_WhichDialog);
+	        PyMac_INIT_TOOLBOX_OBJECT_CONVERT(DialogPtr, DlgObj_Convert);
+
+
+	m = Py_InitModule("_Dlg", Dlg_methods);
+	d = PyModule_GetDict(m);
+	Dlg_Error = PyMac_GetOSErrException();
+	if (Dlg_Error == NULL ||
+	    PyDict_SetItemString(d, "Error", Dlg_Error) != 0)
+		return;
+	Dialog_Type.ob_type = &PyType_Type;
+	if (PyType_Ready(&Dialog_Type) < 0) return;
+	Py_INCREF(&Dialog_Type);
+	PyModule_AddObject(m, "Dialog", (PyObject *)&Dialog_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&Dialog_Type);
+	PyModule_AddObject(m, "DialogType", (PyObject *)&Dialog_Type);
+}
+
+/* ======================== End module _Dlg ========================= */
+

Added: vendor/Python/current/Mac/Modules/dlg/dlgscan.py
===================================================================
--- vendor/Python/current/Mac/Modules/dlg/dlgscan.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/dlg/dlgscan.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,116 @@
+# Scan an Apple header file, generating a Python file of generator calls.
+
+import sys
+import os
+from bgenlocations import TOOLBOXDIR, BGENDIR
+sys.path.append(BGENDIR)
+
+from scantools import Scanner
+
+LONG = "Dialogs"
+SHORT = "dlg"
+OBJECT = "DialogPtr"
+
+def main():
+    input = LONG + ".h"
+    output = SHORT + "gen.py"
+    defsoutput = TOOLBOXDIR + LONG + ".py"
+    scanner = MyScanner(input, output, defsoutput)
+    scanner.scan()
+    scanner.close()
+    print "=== Testing definitions output code ==="
+    execfile(defsoutput, {}, {})
+    print "=== Done scanning and generating, now importing the generated code... ==="
+    exec "import " + SHORT + "support"
+    print "=== Done.  It's up to you to compile it now! ==="
+
+class MyScanner(Scanner):
+
+    def destination(self, type, name, arglist):
+        classname = "Function"
+        listname = "functions"
+        if arglist:
+            t, n, m = arglist[0]
+            if t in ("DialogPtr", "DialogRef") and m == "InMode":
+                classname = "Method"
+                listname = "methods"
+        return classname, listname
+
+    def makeblacklistnames(self):
+        return [
+                'InitDialogs',
+                'ErrorSound',
+                # Dialogs are disposed when the object is deleted
+                'CloseDialog',
+                'DisposDialog',
+                'DisposeDialog',
+                'UpdtDialog',
+                'CouldAlert',
+                'FreeAlert',
+                'CouldDialog',
+                'FreeDialog',
+                'GetStdFilterProc',
+                'GetDialogParent',
+##                      # Can't find these in the CW Pro 3 libraries
+                'SetDialogMovableModal',
+                'GetDialogControlNotificationProc',
+                'SetGrafPortOfDialog', # Funny, and probably not useful
+                # Can't find these:
+                'CloseStandardSheet',
+                'RunStandardAlert',
+                ]
+
+    def makeblacklisttypes(self):
+        return [
+                "AlertStdAlertParamPtr",        # Too much work, for now
+                "AlertStdAlertParamRec",        # ditto
+                "AlertStdAlertParamRec_ptr",    # ditto
+                "AlertStdCFStringAlertParamPtr",        # ditto
+                "AlertStdCFStringAlertParamRec",
+                "AlertStdCFStringAlertParamRec_ptr",
+                "QTModelessCallbackProcPtr",
+                ]
+
+    def makerepairinstructions(self):
+        return [
+                ([("Str255", "*", "InMode")],
+                 [("*", "*", "OutMode")]),
+
+                ([("void_ptr", "*", "InMode"), ("long", "*", "InMode")],
+                 [("InBuffer", "*", "*")]),
+
+                ([("void", "*", "OutMode"), ("long", "*", "InMode"),
+                                            ("long", "*", "OutMode")],
+                 [("VarVarOutBuffer", "*", "InOutMode")]),
+
+                # GetDialogItem return handle is optional
+                ([("Handle", "item", "OutMode")],
+                 [("OptHandle", "item", "OutMode")]),
+
+                # NewDialog ETC.
+                ([("void", "*", "OutMode")],
+                 [("NullStorage", "*", "InMode")]),
+
+                ([("DialogPtr", "*", "OutMode")],
+                 [("ExistingDialogPtr", "*", "*")]),
+                ([("DialogRef", "*", "OutMode")],
+                 [("ExistingDialogPtr", "*", "*")]),
+                ([("WindowPtr", "*", "OutMode")],
+                 [("ExistingWindowPtr", "*", "*")]),
+                ([("WindowPtr", "*", "ReturnMode")],
+                 [("ExistingWindowPtr", "*", "*")]),
+
+                # StdFilterProc
+                ([('EventRecord', 'event', 'OutMode'),
+                  ('DialogItemIndex', 'itemHit', 'OutMode')],
+                 [('EventRecord', 'event', 'InOutMode'),
+                  ('DialogItemIndex', 'itemHit', 'InOutMode')])
+
+                ]
+
+    def writeinitialdefs(self):
+        self.defsfile.write("def FOUR_CHAR_CODE(x): return x\n")
+
+
+if __name__ == "__main__":
+    main()

Added: vendor/Python/current/Mac/Modules/dlg/dlgsupport.py
===================================================================
--- vendor/Python/current/Mac/Modules/dlg/dlgsupport.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/dlg/dlgsupport.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,278 @@
+# This script generates the Dialogs interface for Python.
+# It uses the "bgen" package to generate C code.
+# It execs the file dlggen.py which contain the function definitions
+# (dlggen.py was generated by dlgscan.py, scanning the <Dialogs.h> header file).
+
+from macsupport import *
+
+# Create the type objects
+
+DialogPtr = OpaqueByValueType("DialogPtr", "DlgObj")
+DialogRef = DialogPtr
+
+# An OptHandle is either a handle or None (in case NULL is passed in).
+# This is needed for GetDialogItem().
+OptHandle = OpaqueByValueType("Handle", "OptResObj")
+
+ModalFilterProcPtr = InputOnlyType("PyObject*", "O")
+ModalFilterProcPtr.passInput = lambda name: "Dlg_PassFilterProc(%s)" % name
+ModalFilterUPP = ModalFilterProcPtr
+
+RgnHandle = OpaqueByValueType("RgnHandle", "ResObj")
+TEHandle = OpaqueByValueType("TEHandle", "ResObj")
+CGrafPtr = OpaqueByValueType("CGrafPtr", "GrafObj")
+
+DITLMethod = Type("DITLMethod", "h")
+DialogItemIndex = Type("DialogItemIndex", "h")
+DialogItemType = Type("DialogItemType", "h")
+DialogItemIndexZeroBased = Type("DialogItemIndexZeroBased", "h")
+AlertType = Type("AlertType", "h")
+StringPtr = Str255
+EventMask = Type("EventMask", "H")
+
+includestuff = includestuff + """
+#include <Carbon/Carbon.h>
+
+#ifdef USE_TOOLBOX_OBJECT_GLUE
+extern PyObject *_DlgObj_New(DialogRef);
+extern PyObject *_DlgObj_WhichDialog(DialogRef);
+extern int _DlgObj_Convert(PyObject *, DialogRef *);
+
+#define DlgObj_New _DlgObj_New
+#define DlgObj_WhichDialog _DlgObj_WhichDialog
+#define DlgObj_Convert _DlgObj_Convert
+#endif
+
+/* XXX Shouldn't this be a stack? */
+static PyObject *Dlg_FilterProc_callback = NULL;
+
+static pascal Boolean Dlg_UnivFilterProc(DialogPtr dialog,
+                                         EventRecord *event,
+                                         short *itemHit)
+{
+        Boolean rv;
+        PyObject *args, *res;
+        PyObject *callback = Dlg_FilterProc_callback;
+        if (callback == NULL)
+                return 0; /* Default behavior */
+        Dlg_FilterProc_callback = NULL; /* We'll restore it when call successful */
+        args = Py_BuildValue("O&O&", DlgObj_WhichDialog, dialog, PyMac_BuildEventRecord, event);
+        if (args == NULL)
+                res = NULL;
+        else {
+                res = PyEval_CallObject(callback, args);
+                Py_DECREF(args);
+        }
+        if (res == NULL) {
+                PySys_WriteStderr("Exception in Dialog Filter\\n");
+                PyErr_Print();
+                *itemHit = -1; /* Fake return item */
+                return 1; /* We handled it */
+        }
+        else {
+                Dlg_FilterProc_callback = callback;
+                if (PyInt_Check(res)) {
+                        *itemHit = PyInt_AsLong(res);
+                        rv = 1;
+                }
+                else
+                        rv = PyObject_IsTrue(res);
+        }
+        Py_DECREF(res);
+        return rv;
+}
+
+static ModalFilterUPP
+Dlg_PassFilterProc(PyObject *callback)
+{
+        PyObject *tmp = Dlg_FilterProc_callback;
+        static ModalFilterUPP UnivFilterUpp = NULL;
+
+        Dlg_FilterProc_callback = NULL;
+        if (callback == Py_None) {
+                Py_XDECREF(tmp);
+                return NULL;
+        }
+        Py_INCREF(callback);
+        Dlg_FilterProc_callback = callback;
+        Py_XDECREF(tmp);
+        if ( UnivFilterUpp == NULL )
+                UnivFilterUpp = NewModalFilterUPP(&Dlg_UnivFilterProc);
+        return UnivFilterUpp;
+}
+
+static PyObject *Dlg_UserItemProc_callback = NULL;
+
+static pascal void Dlg_UnivUserItemProc(DialogPtr dialog,
+                                         short item)
+{
+        PyObject *args, *res;
+
+        if (Dlg_UserItemProc_callback == NULL)
+                return; /* Default behavior */
+        Dlg_FilterProc_callback = NULL; /* We'll restore it when call successful */
+        args = Py_BuildValue("O&h", DlgObj_WhichDialog, dialog, item);
+        if (args == NULL)
+                res = NULL;
+        else {
+                res = PyEval_CallObject(Dlg_UserItemProc_callback, args);
+                Py_DECREF(args);
+        }
+        if (res == NULL) {
+                PySys_WriteStderr("Exception in Dialog UserItem proc\\n");
+                PyErr_Print();
+        }
+        Py_XDECREF(res);
+        return;
+}
+
+#if 0
+/*
+** Treating DialogObjects as WindowObjects is (I think) illegal under Carbon.
+** However, as they are still identical under MacOS9 Carbon this is a problem, even
+** if we neatly call GetDialogWindow() at the right places: there's one refcon field
+** and it points to the DialogObject, so WinObj_WhichWindow will smartly return the
+** dialog object, and therefore we still don't have a WindowObject.
+** I'll leave the chaining code in place for now, with this comment to warn the
+** unsuspecting victims (i.e. me, probably, in a few weeks:-)
+*/
+extern PyMethodChain WinObj_chain;
+#endif
+"""
+
+finalstuff = finalstuff + """
+/* Return the WindowPtr corresponding to a DialogObject */
+#if 0
+WindowPtr
+DlgObj_ConvertToWindow(PyObject *self)
+{
+        if ( DlgObj_Check(self) )
+                return GetDialogWindow(((DialogObject *)self)->ob_itself);
+        return NULL;
+}
+#endif
+/* Return the object corresponding to the dialog, or None */
+
+PyObject *
+DlgObj_WhichDialog(DialogPtr d)
+{
+        PyObject *it;
+
+        if (d == NULL) {
+                it = Py_None;
+                Py_INCREF(it);
+        } else {
+                WindowPtr w = GetDialogWindow(d);
+
+                it = (PyObject *) GetWRefCon(w);
+                if (it == NULL || ((DialogObject *)it)->ob_itself != d || !DlgObj_Check(it)) {
+#if 0
+                        /* Should do this, but we don't have an ob_freeit for dialogs yet. */
+                        it = WinObj_New(w);
+                        ((WindowObject *)it)->ob_freeit = NULL;
+#else
+                        it = Py_None;
+                        Py_INCREF(it);
+#endif
+                } else {
+                        Py_INCREF(it);
+                }
+        }
+        return it;
+}
+"""
+
+initstuff = initstuff + """
+        PyMac_INIT_TOOLBOX_OBJECT_NEW(DialogPtr, DlgObj_New);
+        PyMac_INIT_TOOLBOX_OBJECT_NEW(DialogPtr, DlgObj_WhichDialog);
+        PyMac_INIT_TOOLBOX_OBJECT_CONVERT(DialogPtr, DlgObj_Convert);
+"""
+
+
+# Define a class which specializes our object definition
+class MyObjectDefinition(PEP253Mixin, GlobalObjectDefinition):
+    def __init__(self, name, prefix = None, itselftype = None):
+        GlobalObjectDefinition.__init__(self, name, prefix, itselftype)
+## This won't work in Carbon, so we disable it for all MacPythons:-(
+## But see the comment above:-((
+##              self.basechain = "&WinObj_chain"
+
+    def outputInitStructMembers(self):
+        GlobalObjectDefinition.outputInitStructMembers(self)
+        Output("SetWRefCon(GetDialogWindow(itself), (long)it);")
+
+    def outputCheckNewArg(self):
+        Output("if (itself == NULL) { Py_INCREF(Py_None); return Py_None; }")
+
+    def outputCheckConvertArg(self):
+        Output("if (v == Py_None) { *p_itself = NULL; return 1; }")
+        Output("if (PyInt_Check(v)) { *p_itself = (DialogPtr)PyInt_AsLong(v);")
+        Output("                      return 1; }")
+
+    def outputCompare(self):
+        Output()
+        Output("static int %s_compare(%s *self, %s *other)", self.prefix, self.objecttype, self.objecttype)
+        OutLbrace()
+        Output("if ( self->ob_itself > other->ob_itself ) return 1;")
+        Output("if ( self->ob_itself < other->ob_itself ) return -1;")
+        Output("return 0;")
+        OutRbrace()
+
+    def outputHash(self):
+        Output()
+        Output("static int %s_hash(%s *self)", self.prefix, self.objecttype)
+        OutLbrace()
+        Output("return (int)self->ob_itself;")
+        OutRbrace()
+
+    def outputFreeIt(self, itselfname):
+        Output("DisposeDialog(%s);", itselfname)
+
+# Create the generator groups and link them
+module = MacModule('_Dlg', 'Dlg', includestuff, finalstuff, initstuff)
+object = MyObjectDefinition('Dialog', 'DlgObj', 'DialogPtr')
+module.addobject(object)
+
+# Create the generator classes used to populate the lists
+Function = OSErrWeakLinkFunctionGenerator
+Method = OSErrWeakLinkMethodGenerator
+
+# Create and populate the lists
+functions = []
+methods = []
+execfile("dlggen.py")
+
+# add the populated lists to the generator groups
+for f in functions: module.add(f)
+for f in methods: object.add(f)
+
+setuseritembody = """
+        PyObject *new = NULL;
+
+
+        if (!PyArg_ParseTuple(_args, "|O", &new))
+                return NULL;
+
+        if (Dlg_UserItemProc_callback && new && new != Py_None) {
+                PyErr_SetString(Dlg_Error, "Another UserItemProc is already installed");
+                return NULL;
+        }
+
+        if (new == NULL || new == Py_None) {
+                new = NULL;
+                _res = Py_None;
+                Py_INCREF(Py_None);
+        } else {
+                Py_INCREF(new);
+                _res = Py_BuildValue("O&", ResObj_New, (Handle)NewUserItemUPP(Dlg_UnivUserItemProc));
+        }
+
+        Dlg_UserItemProc_callback = new;
+        return _res;
+"""
+f = ManualGenerator("SetUserItemHandler", setuseritembody)
+module.add(f)
+
+# generate output
+SetOutputFileName('_Dlgmodule.c')
+module.generate()

Added: vendor/Python/current/Mac/Modules/drag/_Dragmodule.c
===================================================================
--- vendor/Python/current/Mac/Modules/drag/_Dragmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/drag/_Dragmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1149 @@
+
+/* ========================== Module _Drag ========================== */
+
+#include "Python.h"
+
+
+
+#include "pymactoolbox.h"
+
+/* Macro to test whether a weak-loaded CFM function exists */
+#define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL )  {\
+        PyErr_SetString(PyExc_NotImplementedError, \
+        "Not available in this shared library/OS version"); \
+        return NULL; \
+    }} while(0)
+
+
+#include <Carbon/Carbon.h>
+
+/* Callback glue routines */
+DragTrackingHandlerUPP dragglue_TrackingHandlerUPP;
+DragReceiveHandlerUPP dragglue_ReceiveHandlerUPP;
+DragSendDataUPP dragglue_SendDataUPP;
+#if 0
+DragInputUPP dragglue_InputUPP;
+DragDrawingUPP dragglue_DrawingUPP;
+#endif
+
+#ifdef USE_TOOLBOX_OBJECT_GLUE
+extern PyObject *_DragObj_New(DragRef);
+extern int _DragObj_Convert(PyObject *, DragRef *);
+
+#define DragObj_New _DragObj_New
+#define DragObj_Convert _DragObj_Convert
+#endif
+
+static PyObject *Drag_Error;
+
+/* ---------------------- Object type DragObj ----------------------- */
+
+PyTypeObject DragObj_Type;
+
+#define DragObj_Check(x) ((x)->ob_type == &DragObj_Type || PyObject_TypeCheck((x), &DragObj_Type))
+
+typedef struct DragObjObject {
+	PyObject_HEAD
+	DragRef ob_itself;
+	PyObject *sendproc;
+} DragObjObject;
+
+PyObject *DragObj_New(DragRef itself)
+{
+	DragObjObject *it;
+	if (itself == NULL) {
+	                                PyErr_SetString(Drag_Error,"Cannot create null Drag");
+	                                return NULL;
+	                        }
+	it = PyObject_NEW(DragObjObject, &DragObj_Type);
+	if (it == NULL) return NULL;
+	it->ob_itself = itself;
+	it->sendproc = NULL;
+	return (PyObject *)it;
+}
+
+int DragObj_Convert(PyObject *v, DragRef *p_itself)
+{
+	if (!DragObj_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "DragObj required");
+		return 0;
+	}
+	*p_itself = ((DragObjObject *)v)->ob_itself;
+	return 1;
+}
+
+static void DragObj_dealloc(DragObjObject *self)
+{
+	Py_XDECREF(self->sendproc);
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *DragObj_DisposeDrag(DragObjObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+#ifndef DisposeDrag
+	PyMac_PRECHECK(DisposeDrag);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = DisposeDrag(_self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *DragObj_AddDragItemFlavor(DragObjObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	ItemReference theItemRef;
+	FlavorType theType;
+	char *dataPtr__in__;
+	long dataPtr__len__;
+	int dataPtr__in_len__;
+	FlavorFlags theFlags;
+#ifndef AddDragItemFlavor
+	PyMac_PRECHECK(AddDragItemFlavor);
+#endif
+	if (!PyArg_ParseTuple(_args, "lO&z#l",
+	                      &theItemRef,
+	                      PyMac_GetOSType, &theType,
+	                      &dataPtr__in__, &dataPtr__in_len__,
+	                      &theFlags))
+		return NULL;
+	dataPtr__len__ = dataPtr__in_len__;
+	_err = AddDragItemFlavor(_self->ob_itself,
+	                         theItemRef,
+	                         theType,
+	                         dataPtr__in__, dataPtr__len__,
+	                         theFlags);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *DragObj_SetDragItemFlavorData(DragObjObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	ItemReference theItemRef;
+	FlavorType theType;
+	char *dataPtr__in__;
+	long dataPtr__len__;
+	int dataPtr__in_len__;
+	UInt32 dataOffset;
+#ifndef SetDragItemFlavorData
+	PyMac_PRECHECK(SetDragItemFlavorData);
+#endif
+	if (!PyArg_ParseTuple(_args, "lO&z#l",
+	                      &theItemRef,
+	                      PyMac_GetOSType, &theType,
+	                      &dataPtr__in__, &dataPtr__in_len__,
+	                      &dataOffset))
+		return NULL;
+	dataPtr__len__ = dataPtr__in_len__;
+	_err = SetDragItemFlavorData(_self->ob_itself,
+	                             theItemRef,
+	                             theType,
+	                             dataPtr__in__, dataPtr__len__,
+	                             dataOffset);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *DragObj_SetDragImage(DragObjObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	PixMapHandle imagePixMap;
+	RgnHandle imageRgn;
+	Point imageOffsetPt;
+	DragImageFlags theImageFlags;
+#ifndef SetDragImage
+	PyMac_PRECHECK(SetDragImage);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&l",
+	                      ResObj_Convert, &imagePixMap,
+	                      ResObj_Convert, &imageRgn,
+	                      PyMac_GetPoint, &imageOffsetPt,
+	                      &theImageFlags))
+		return NULL;
+	_err = SetDragImage(_self->ob_itself,
+	                    imagePixMap,
+	                    imageRgn,
+	                    imageOffsetPt,
+	                    theImageFlags);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *DragObj_ChangeDragBehaviors(DragObjObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	DragBehaviors inBehaviorsToSet;
+	DragBehaviors inBehaviorsToClear;
+#ifndef ChangeDragBehaviors
+	PyMac_PRECHECK(ChangeDragBehaviors);
+#endif
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &inBehaviorsToSet,
+	                      &inBehaviorsToClear))
+		return NULL;
+	_err = ChangeDragBehaviors(_self->ob_itself,
+	                           inBehaviorsToSet,
+	                           inBehaviorsToClear);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *DragObj_TrackDrag(DragObjObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	EventRecord theEvent;
+	RgnHandle theRegion;
+#ifndef TrackDrag
+	PyMac_PRECHECK(TrackDrag);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetEventRecord, &theEvent,
+	                      ResObj_Convert, &theRegion))
+		return NULL;
+	_err = TrackDrag(_self->ob_itself,
+	                 &theEvent,
+	                 theRegion);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *DragObj_CountDragItems(DragObjObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	UInt16 numItems;
+#ifndef CountDragItems
+	PyMac_PRECHECK(CountDragItems);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = CountDragItems(_self->ob_itself,
+	                      &numItems);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("H",
+	                     numItems);
+	return _res;
+}
+
+static PyObject *DragObj_GetDragItemReferenceNumber(DragObjObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	UInt16 index;
+	ItemReference theItemRef;
+#ifndef GetDragItemReferenceNumber
+	PyMac_PRECHECK(GetDragItemReferenceNumber);
+#endif
+	if (!PyArg_ParseTuple(_args, "H",
+	                      &index))
+		return NULL;
+	_err = GetDragItemReferenceNumber(_self->ob_itself,
+	                                  index,
+	                                  &theItemRef);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     theItemRef);
+	return _res;
+}
+
+static PyObject *DragObj_CountDragItemFlavors(DragObjObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	ItemReference theItemRef;
+	UInt16 numFlavors;
+#ifndef CountDragItemFlavors
+	PyMac_PRECHECK(CountDragItemFlavors);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &theItemRef))
+		return NULL;
+	_err = CountDragItemFlavors(_self->ob_itself,
+	                            theItemRef,
+	                            &numFlavors);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("H",
+	                     numFlavors);
+	return _res;
+}
+
+static PyObject *DragObj_GetFlavorType(DragObjObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	ItemReference theItemRef;
+	UInt16 index;
+	FlavorType theType;
+#ifndef GetFlavorType
+	PyMac_PRECHECK(GetFlavorType);
+#endif
+	if (!PyArg_ParseTuple(_args, "lH",
+	                      &theItemRef,
+	                      &index))
+		return NULL;
+	_err = GetFlavorType(_self->ob_itself,
+	                     theItemRef,
+	                     index,
+	                     &theType);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildOSType, theType);
+	return _res;
+}
+
+static PyObject *DragObj_GetFlavorFlags(DragObjObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	ItemReference theItemRef;
+	FlavorType theType;
+	FlavorFlags theFlags;
+#ifndef GetFlavorFlags
+	PyMac_PRECHECK(GetFlavorFlags);
+#endif
+	if (!PyArg_ParseTuple(_args, "lO&",
+	                      &theItemRef,
+	                      PyMac_GetOSType, &theType))
+		return NULL;
+	_err = GetFlavorFlags(_self->ob_itself,
+	                      theItemRef,
+	                      theType,
+	                      &theFlags);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     theFlags);
+	return _res;
+}
+
+static PyObject *DragObj_GetFlavorDataSize(DragObjObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	ItemReference theItemRef;
+	FlavorType theType;
+	Size dataSize;
+#ifndef GetFlavorDataSize
+	PyMac_PRECHECK(GetFlavorDataSize);
+#endif
+	if (!PyArg_ParseTuple(_args, "lO&",
+	                      &theItemRef,
+	                      PyMac_GetOSType, &theType))
+		return NULL;
+	_err = GetFlavorDataSize(_self->ob_itself,
+	                         theItemRef,
+	                         theType,
+	                         &dataSize);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     dataSize);
+	return _res;
+}
+
+static PyObject *DragObj_GetFlavorData(DragObjObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	ItemReference theItemRef;
+	FlavorType theType;
+	char *dataPtr__out__;
+	long dataPtr__len__;
+	int dataPtr__in_len__;
+	UInt32 dataOffset;
+#ifndef GetFlavorData
+	PyMac_PRECHECK(GetFlavorData);
+#endif
+	if (!PyArg_ParseTuple(_args, "lO&il",
+	                      &theItemRef,
+	                      PyMac_GetOSType, &theType,
+	                      &dataPtr__in_len__,
+	                      &dataOffset))
+		return NULL;
+	if ((dataPtr__out__ = malloc(dataPtr__in_len__)) == NULL)
+	{
+		PyErr_NoMemory();
+		goto dataPtr__error__;
+	}
+	dataPtr__len__ = dataPtr__in_len__;
+	_err = GetFlavorData(_self->ob_itself,
+	                     theItemRef,
+	                     theType,
+	                     dataPtr__out__, &dataPtr__len__,
+	                     dataOffset);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("s#",
+	                     dataPtr__out__, (int)dataPtr__len__);
+	free(dataPtr__out__);
+ dataPtr__error__: ;
+	return _res;
+}
+
+static PyObject *DragObj_GetDragItemBounds(DragObjObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	ItemReference theItemRef;
+	Rect itemBounds;
+#ifndef GetDragItemBounds
+	PyMac_PRECHECK(GetDragItemBounds);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &theItemRef))
+		return NULL;
+	_err = GetDragItemBounds(_self->ob_itself,
+	                         theItemRef,
+	                         &itemBounds);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildRect, &itemBounds);
+	return _res;
+}
+
+static PyObject *DragObj_SetDragItemBounds(DragObjObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	ItemReference theItemRef;
+	Rect itemBounds;
+#ifndef SetDragItemBounds
+	PyMac_PRECHECK(SetDragItemBounds);
+#endif
+	if (!PyArg_ParseTuple(_args, "lO&",
+	                      &theItemRef,
+	                      PyMac_GetRect, &itemBounds))
+		return NULL;
+	_err = SetDragItemBounds(_self->ob_itself,
+	                         theItemRef,
+	                         &itemBounds);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *DragObj_GetDropLocation(DragObjObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	AEDesc dropLocation;
+#ifndef GetDropLocation
+	PyMac_PRECHECK(GetDropLocation);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetDropLocation(_self->ob_itself,
+	                       &dropLocation);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     AEDesc_New, &dropLocation);
+	return _res;
+}
+
+static PyObject *DragObj_SetDropLocation(DragObjObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	AEDesc dropLocation;
+#ifndef SetDropLocation
+	PyMac_PRECHECK(SetDropLocation);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      AEDesc_Convert, &dropLocation))
+		return NULL;
+	_err = SetDropLocation(_self->ob_itself,
+	                       &dropLocation);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *DragObj_GetDragAttributes(DragObjObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	DragAttributes flags;
+#ifndef GetDragAttributes
+	PyMac_PRECHECK(GetDragAttributes);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetDragAttributes(_self->ob_itself,
+	                         &flags);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     flags);
+	return _res;
+}
+
+static PyObject *DragObj_GetDragMouse(DragObjObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Point mouse;
+	Point globalPinnedMouse;
+#ifndef GetDragMouse
+	PyMac_PRECHECK(GetDragMouse);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetDragMouse(_self->ob_itself,
+	                    &mouse,
+	                    &globalPinnedMouse);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&O&",
+	                     PyMac_BuildPoint, mouse,
+	                     PyMac_BuildPoint, globalPinnedMouse);
+	return _res;
+}
+
+static PyObject *DragObj_SetDragMouse(DragObjObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Point globalPinnedMouse;
+#ifndef SetDragMouse
+	PyMac_PRECHECK(SetDragMouse);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetPoint, &globalPinnedMouse))
+		return NULL;
+	_err = SetDragMouse(_self->ob_itself,
+	                    globalPinnedMouse);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *DragObj_GetDragOrigin(DragObjObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Point globalInitialMouse;
+#ifndef GetDragOrigin
+	PyMac_PRECHECK(GetDragOrigin);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetDragOrigin(_self->ob_itself,
+	                     &globalInitialMouse);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildPoint, globalInitialMouse);
+	return _res;
+}
+
+static PyObject *DragObj_GetDragModifiers(DragObjObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SInt16 modifiers;
+	SInt16 mouseDownModifiers;
+	SInt16 mouseUpModifiers;
+#ifndef GetDragModifiers
+	PyMac_PRECHECK(GetDragModifiers);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetDragModifiers(_self->ob_itself,
+	                        &modifiers,
+	                        &mouseDownModifiers,
+	                        &mouseUpModifiers);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("hhh",
+	                     modifiers,
+	                     mouseDownModifiers,
+	                     mouseUpModifiers);
+	return _res;
+}
+
+static PyObject *DragObj_ShowDragHilite(DragObjObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	RgnHandle hiliteFrame;
+	Boolean inside;
+#ifndef ShowDragHilite
+	PyMac_PRECHECK(ShowDragHilite);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&b",
+	                      ResObj_Convert, &hiliteFrame,
+	                      &inside))
+		return NULL;
+	_err = ShowDragHilite(_self->ob_itself,
+	                      hiliteFrame,
+	                      inside);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *DragObj_HideDragHilite(DragObjObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+#ifndef HideDragHilite
+	PyMac_PRECHECK(HideDragHilite);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = HideDragHilite(_self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *DragObj_DragPreScroll(DragObjObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SInt16 dH;
+	SInt16 dV;
+#ifndef DragPreScroll
+	PyMac_PRECHECK(DragPreScroll);
+#endif
+	if (!PyArg_ParseTuple(_args, "hh",
+	                      &dH,
+	                      &dV))
+		return NULL;
+	_err = DragPreScroll(_self->ob_itself,
+	                     dH,
+	                     dV);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *DragObj_DragPostScroll(DragObjObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+#ifndef DragPostScroll
+	PyMac_PRECHECK(DragPostScroll);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = DragPostScroll(_self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *DragObj_UpdateDragHilite(DragObjObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	RgnHandle updateRgn;
+#ifndef UpdateDragHilite
+	PyMac_PRECHECK(UpdateDragHilite);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &updateRgn))
+		return NULL;
+	_err = UpdateDragHilite(_self->ob_itself,
+	                        updateRgn);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyMethodDef DragObj_methods[] = {
+	{"DisposeDrag", (PyCFunction)DragObj_DisposeDrag, 1,
+	 PyDoc_STR("() -> None")},
+	{"AddDragItemFlavor", (PyCFunction)DragObj_AddDragItemFlavor, 1,
+	 PyDoc_STR("(ItemReference theItemRef, FlavorType theType, Buffer dataPtr, FlavorFlags theFlags) -> None")},
+	{"SetDragItemFlavorData", (PyCFunction)DragObj_SetDragItemFlavorData, 1,
+	 PyDoc_STR("(ItemReference theItemRef, FlavorType theType, Buffer dataPtr, UInt32 dataOffset) -> None")},
+	{"SetDragImage", (PyCFunction)DragObj_SetDragImage, 1,
+	 PyDoc_STR("(PixMapHandle imagePixMap, RgnHandle imageRgn, Point imageOffsetPt, DragImageFlags theImageFlags) -> None")},
+	{"ChangeDragBehaviors", (PyCFunction)DragObj_ChangeDragBehaviors, 1,
+	 PyDoc_STR("(DragBehaviors inBehaviorsToSet, DragBehaviors inBehaviorsToClear) -> None")},
+	{"TrackDrag", (PyCFunction)DragObj_TrackDrag, 1,
+	 PyDoc_STR("(EventRecord theEvent, RgnHandle theRegion) -> None")},
+	{"CountDragItems", (PyCFunction)DragObj_CountDragItems, 1,
+	 PyDoc_STR("() -> (UInt16 numItems)")},
+	{"GetDragItemReferenceNumber", (PyCFunction)DragObj_GetDragItemReferenceNumber, 1,
+	 PyDoc_STR("(UInt16 index) -> (ItemReference theItemRef)")},
+	{"CountDragItemFlavors", (PyCFunction)DragObj_CountDragItemFlavors, 1,
+	 PyDoc_STR("(ItemReference theItemRef) -> (UInt16 numFlavors)")},
+	{"GetFlavorType", (PyCFunction)DragObj_GetFlavorType, 1,
+	 PyDoc_STR("(ItemReference theItemRef, UInt16 index) -> (FlavorType theType)")},
+	{"GetFlavorFlags", (PyCFunction)DragObj_GetFlavorFlags, 1,
+	 PyDoc_STR("(ItemReference theItemRef, FlavorType theType) -> (FlavorFlags theFlags)")},
+	{"GetFlavorDataSize", (PyCFunction)DragObj_GetFlavorDataSize, 1,
+	 PyDoc_STR("(ItemReference theItemRef, FlavorType theType) -> (Size dataSize)")},
+	{"GetFlavorData", (PyCFunction)DragObj_GetFlavorData, 1,
+	 PyDoc_STR("(ItemReference theItemRef, FlavorType theType, Buffer dataPtr, UInt32 dataOffset) -> (Buffer dataPtr)")},
+	{"GetDragItemBounds", (PyCFunction)DragObj_GetDragItemBounds, 1,
+	 PyDoc_STR("(ItemReference theItemRef) -> (Rect itemBounds)")},
+	{"SetDragItemBounds", (PyCFunction)DragObj_SetDragItemBounds, 1,
+	 PyDoc_STR("(ItemReference theItemRef, Rect itemBounds) -> None")},
+	{"GetDropLocation", (PyCFunction)DragObj_GetDropLocation, 1,
+	 PyDoc_STR("() -> (AEDesc dropLocation)")},
+	{"SetDropLocation", (PyCFunction)DragObj_SetDropLocation, 1,
+	 PyDoc_STR("(AEDesc dropLocation) -> None")},
+	{"GetDragAttributes", (PyCFunction)DragObj_GetDragAttributes, 1,
+	 PyDoc_STR("() -> (DragAttributes flags)")},
+	{"GetDragMouse", (PyCFunction)DragObj_GetDragMouse, 1,
+	 PyDoc_STR("() -> (Point mouse, Point globalPinnedMouse)")},
+	{"SetDragMouse", (PyCFunction)DragObj_SetDragMouse, 1,
+	 PyDoc_STR("(Point globalPinnedMouse) -> None")},
+	{"GetDragOrigin", (PyCFunction)DragObj_GetDragOrigin, 1,
+	 PyDoc_STR("() -> (Point globalInitialMouse)")},
+	{"GetDragModifiers", (PyCFunction)DragObj_GetDragModifiers, 1,
+	 PyDoc_STR("() -> (SInt16 modifiers, SInt16 mouseDownModifiers, SInt16 mouseUpModifiers)")},
+	{"ShowDragHilite", (PyCFunction)DragObj_ShowDragHilite, 1,
+	 PyDoc_STR("(RgnHandle hiliteFrame, Boolean inside) -> None")},
+	{"HideDragHilite", (PyCFunction)DragObj_HideDragHilite, 1,
+	 PyDoc_STR("() -> None")},
+	{"DragPreScroll", (PyCFunction)DragObj_DragPreScroll, 1,
+	 PyDoc_STR("(SInt16 dH, SInt16 dV) -> None")},
+	{"DragPostScroll", (PyCFunction)DragObj_DragPostScroll, 1,
+	 PyDoc_STR("() -> None")},
+	{"UpdateDragHilite", (PyCFunction)DragObj_UpdateDragHilite, 1,
+	 PyDoc_STR("(RgnHandle updateRgn) -> None")},
+	{NULL, NULL, 0}
+};
+
+#define DragObj_getsetlist NULL
+
+
+#define DragObj_compare NULL
+
+#define DragObj_repr NULL
+
+#define DragObj_hash NULL
+#define DragObj_tp_init 0
+
+#define DragObj_tp_alloc PyType_GenericAlloc
+
+static PyObject *DragObj_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *_self;
+	DragRef itself;
+	char *kw[] = {"itself", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, DragObj_Convert, &itself)) return NULL;
+	if ((_self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	((DragObjObject *)_self)->ob_itself = itself;
+	return _self;
+}
+
+#define DragObj_tp_free PyObject_Del
+
+
+PyTypeObject DragObj_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"_Drag.DragObj", /*tp_name*/
+	sizeof(DragObjObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) DragObj_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) DragObj_compare, /*tp_compare*/
+	(reprfunc) DragObj_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) DragObj_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	DragObj_methods, /* tp_methods */
+	0, /*tp_members*/
+	DragObj_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	DragObj_tp_init, /* tp_init */
+	DragObj_tp_alloc, /* tp_alloc */
+	DragObj_tp_new, /* tp_new */
+	DragObj_tp_free, /* tp_free */
+};
+
+/* -------------------- End object type DragObj --------------------- */
+
+
+static PyObject *Drag_NewDrag(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	DragRef theDrag;
+#ifndef NewDrag
+	PyMac_PRECHECK(NewDrag);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = NewDrag(&theDrag);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     DragObj_New, theDrag);
+	return _res;
+}
+
+static PyObject *Drag_GetDragHiliteColor(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	WindowPtr window;
+	RGBColor color;
+#ifndef GetDragHiliteColor
+	PyMac_PRECHECK(GetDragHiliteColor);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      WinObj_Convert, &window))
+		return NULL;
+	_err = GetDragHiliteColor(window,
+	                          &color);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     QdRGB_New, &color);
+	return _res;
+}
+
+static PyObject *Drag_WaitMouseMoved(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	Point initialMouse;
+#ifndef WaitMouseMoved
+	PyMac_PRECHECK(WaitMouseMoved);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetPoint, &initialMouse))
+		return NULL;
+	_rv = WaitMouseMoved(initialMouse);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Drag_ZoomRects(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Rect fromRect;
+	Rect toRect;
+	SInt16 zoomSteps;
+	ZoomAcceleration acceleration;
+#ifndef ZoomRects
+	PyMac_PRECHECK(ZoomRects);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&hh",
+	                      PyMac_GetRect, &fromRect,
+	                      PyMac_GetRect, &toRect,
+	                      &zoomSteps,
+	                      &acceleration))
+		return NULL;
+	_err = ZoomRects(&fromRect,
+	                 &toRect,
+	                 zoomSteps,
+	                 acceleration);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Drag_ZoomRegion(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	RgnHandle region;
+	Point zoomDistance;
+	SInt16 zoomSteps;
+	ZoomAcceleration acceleration;
+#ifndef ZoomRegion
+	PyMac_PRECHECK(ZoomRegion);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&hh",
+	                      ResObj_Convert, &region,
+	                      PyMac_GetPoint, &zoomDistance,
+	                      &zoomSteps,
+	                      &acceleration))
+		return NULL;
+	_err = ZoomRegion(region,
+	                  zoomDistance,
+	                  zoomSteps,
+	                  acceleration);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Drag_InstallTrackingHandler(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+
+	    PyObject *callback;
+	    WindowPtr theWindow = NULL;
+	    OSErr _err;
+
+	    if ( !PyArg_ParseTuple(_args, "O|O&", &callback, WinObj_Convert, &theWindow) )
+	        return NULL;
+	    Py_INCREF(callback);        /* Cannot decref later, too bad */
+	    _err = InstallTrackingHandler(dragglue_TrackingHandlerUPP, theWindow, (void *)callback);
+	        if (_err != noErr) return PyMac_Error(_err);
+	        Py_INCREF(Py_None);
+	        _res = Py_None;
+	        return _res;
+
+}
+
+static PyObject *Drag_InstallReceiveHandler(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+
+	    PyObject *callback;
+	    WindowPtr theWindow = NULL;
+	    OSErr _err;
+
+	    if ( !PyArg_ParseTuple(_args, "O|O&", &callback, WinObj_Convert, &theWindow) )
+	        return NULL;
+	    Py_INCREF(callback);        /* Cannot decref later, too bad */
+	    _err = InstallReceiveHandler(dragglue_ReceiveHandlerUPP, theWindow, (void *)callback);
+	        if (_err != noErr) return PyMac_Error(_err);
+	        Py_INCREF(Py_None);
+	        _res = Py_None;
+	        return _res;
+
+}
+
+static PyObject *Drag_RemoveTrackingHandler(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+
+	    WindowPtr theWindow = NULL;
+	    OSErr _err;
+
+	    if ( !PyArg_ParseTuple(_args, "|O&", WinObj_Convert, &theWindow) )
+	        return NULL;
+	    _err = RemoveTrackingHandler(dragglue_TrackingHandlerUPP, theWindow);
+	        if (_err != noErr) return PyMac_Error(_err);
+	        Py_INCREF(Py_None);
+	        _res = Py_None;
+	        return _res;
+
+}
+
+static PyObject *Drag_RemoveReceiveHandler(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+
+	    WindowPtr theWindow = NULL;
+	    OSErr _err;
+
+	    if ( !PyArg_ParseTuple(_args, "|O&", WinObj_Convert, &theWindow) )
+	        return NULL;
+	    _err = RemoveReceiveHandler(dragglue_ReceiveHandlerUPP, theWindow);
+	        if (_err != noErr) return PyMac_Error(_err);
+	        Py_INCREF(Py_None);
+	        _res = Py_None;
+	        return _res;
+
+}
+
+static PyMethodDef Drag_methods[] = {
+	{"NewDrag", (PyCFunction)Drag_NewDrag, 1,
+	 PyDoc_STR("() -> (DragRef theDrag)")},
+	{"GetDragHiliteColor", (PyCFunction)Drag_GetDragHiliteColor, 1,
+	 PyDoc_STR("(WindowPtr window) -> (RGBColor color)")},
+	{"WaitMouseMoved", (PyCFunction)Drag_WaitMouseMoved, 1,
+	 PyDoc_STR("(Point initialMouse) -> (Boolean _rv)")},
+	{"ZoomRects", (PyCFunction)Drag_ZoomRects, 1,
+	 PyDoc_STR("(Rect fromRect, Rect toRect, SInt16 zoomSteps, ZoomAcceleration acceleration) -> None")},
+	{"ZoomRegion", (PyCFunction)Drag_ZoomRegion, 1,
+	 PyDoc_STR("(RgnHandle region, Point zoomDistance, SInt16 zoomSteps, ZoomAcceleration acceleration) -> None")},
+	{"InstallTrackingHandler", (PyCFunction)Drag_InstallTrackingHandler, 1,
+	 PyDoc_STR(NULL)},
+	{"InstallReceiveHandler", (PyCFunction)Drag_InstallReceiveHandler, 1,
+	 PyDoc_STR(NULL)},
+	{"RemoveTrackingHandler", (PyCFunction)Drag_RemoveTrackingHandler, 1,
+	 PyDoc_STR(NULL)},
+	{"RemoveReceiveHandler", (PyCFunction)Drag_RemoveReceiveHandler, 1,
+	 PyDoc_STR(NULL)},
+	{NULL, NULL, 0}
+};
+
+
+
+static pascal OSErr
+dragglue_TrackingHandler(DragTrackingMessage theMessage, WindowPtr theWindow,
+                         void *handlerRefCon, DragReference theDrag)
+{
+        PyObject *args, *rv;
+        int i;
+
+        args = Py_BuildValue("hO&O&", theMessage, DragObj_New, theDrag, WinObj_WhichWindow, theWindow);
+        if ( args == NULL )
+                return -1;
+        rv = PyEval_CallObject((PyObject *)handlerRefCon, args);
+        Py_DECREF(args);
+        if ( rv == NULL ) {
+                PySys_WriteStderr("Drag: Exception in TrackingHandler\n");
+                PyErr_Print();
+                return -1;
+        }
+        i = -1;
+        if ( rv == Py_None )
+                i = 0;
+        else
+                PyArg_Parse(rv, "l", &i);
+        Py_DECREF(rv);
+        return i;
+}
+
+static pascal OSErr
+dragglue_ReceiveHandler(WindowPtr theWindow, void *handlerRefCon,
+                        DragReference theDrag)
+{
+        PyObject *args, *rv;
+        int i;
+
+        args = Py_BuildValue("O&O&", DragObj_New, theDrag, WinObj_WhichWindow, theWindow);
+        if ( args == NULL )
+                return -1;
+        rv = PyEval_CallObject((PyObject *)handlerRefCon, args);
+        Py_DECREF(args);
+        if ( rv == NULL ) {
+                PySys_WriteStderr("Drag: Exception in ReceiveHandler\n");
+                PyErr_Print();
+                return -1;
+        }
+        i = -1;
+        if ( rv == Py_None )
+                i = 0;
+        else
+                PyArg_Parse(rv, "l", &i);
+        Py_DECREF(rv);
+        return i;
+}
+
+static pascal OSErr
+dragglue_SendData(FlavorType theType, void *dragSendRefCon,
+                      ItemReference theItem, DragReference theDrag)
+{
+        DragObjObject *self = (DragObjObject *)dragSendRefCon;
+        PyObject *args, *rv;
+        int i;
+
+        if ( self->sendproc == NULL )
+                return -1;
+        args = Py_BuildValue("O&l", PyMac_BuildOSType, theType, theItem);
+        if ( args == NULL )
+                return -1;
+        rv = PyEval_CallObject(self->sendproc, args);
+        Py_DECREF(args);
+        if ( rv == NULL ) {
+                PySys_WriteStderr("Drag: Exception in SendDataHandler\n");
+                PyErr_Print();
+                return -1;
+        }
+        i = -1;
+        if ( rv == Py_None )
+                i = 0;
+        else
+                PyArg_Parse(rv, "l", &i);
+        Py_DECREF(rv);
+        return i;
+}
+
+#if 0
+static pascal OSErr
+dragglue_Input(Point *mouse, short *modifiers,
+                   void *dragSendRefCon, DragReference theDrag)
+{
+    return 0;
+}
+
+static pascal OSErr
+dragglue_Drawing(xxxx
+                   void *dragSendRefCon, DragReference theDrag)
+{
+    return 0;
+}
+#endif
+
+
+
+void init_Drag(void)
+{
+	PyObject *m;
+	PyObject *d;
+
+
+
+	        PyMac_INIT_TOOLBOX_OBJECT_NEW(DragRef, DragObj_New);
+	        PyMac_INIT_TOOLBOX_OBJECT_CONVERT(DragRef, DragObj_Convert);
+
+
+	m = Py_InitModule("_Drag", Drag_methods);
+	d = PyModule_GetDict(m);
+	Drag_Error = PyMac_GetOSErrException();
+	if (Drag_Error == NULL ||
+	    PyDict_SetItemString(d, "Error", Drag_Error) != 0)
+		return;
+	DragObj_Type.ob_type = &PyType_Type;
+	if (PyType_Ready(&DragObj_Type) < 0) return;
+	Py_INCREF(&DragObj_Type);
+	PyModule_AddObject(m, "DragObj", (PyObject *)&DragObj_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&DragObj_Type);
+	PyModule_AddObject(m, "DragObjType", (PyObject *)&DragObj_Type);
+
+	dragglue_TrackingHandlerUPP = NewDragTrackingHandlerUPP(dragglue_TrackingHandler);
+	dragglue_ReceiveHandlerUPP = NewDragReceiveHandlerUPP(dragglue_ReceiveHandler);
+	dragglue_SendDataUPP = NewDragSendDataUPP(dragglue_SendData);
+#if 0
+	dragglue_InputUPP = NewDragInputUPP(dragglue_Input);
+	dragglue_DrawingUPP = NewDragDrawingUPP(dragglue_Drawing);
+#endif
+
+
+}
+
+/* ======================== End module _Drag ======================== */
+

Added: vendor/Python/current/Mac/Modules/drag/dragscan.py
===================================================================
--- vendor/Python/current/Mac/Modules/drag/dragscan.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/drag/dragscan.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,80 @@
+# Scan <Drag.h>, generating draggen.py.
+import sys
+import os
+from bgenlocations import TOOLBOXDIR, BGENDIR, INCLUDEDIR
+sys.path.append(BGENDIR)
+
+from scantools import Scanner
+
+MISSING_DEFINES="""
+kDragHasLeftSenderWindow        = (1 << 0)
+kDragInsideSenderApplication = (1 << 1)
+kDragInsideSenderWindow         = (1 << 2)
+kDragRegionAndImage                     = (1 << 4)
+flavorSenderOnly                        = (1 << 0)
+flavorSenderTranslated          = (1 << 1)
+flavorNotSaved                          = (1 << 2)
+flavorSystemTranslated          = (1 << 8)
+"""
+
+
+def main():
+    input = INCLUDEDIR + "Drag.h"
+    output = "draggen.py"
+    defsoutput = TOOLBOXDIR + "Dragconst.py"
+    scanner = MyScanner(input, output, defsoutput)
+    scanner.scan()
+    scanner.close()
+    print "=== Testing definitions output code ==="
+    execfile(defsoutput, {}, {})
+    print "=== Done scanning and generating, now doing 'import dragsupport' ==="
+    import dragsupport
+    print "=== Done.  It's up to you to compile Dragmodule.c ==="
+
+class MyScanner(Scanner):
+
+    def destination(self, type, name, arglist):
+        classname = "Function"
+        listname = "functions"
+        if arglist:
+            t, n, m = arglist[0]
+            if t in ('DragReference', 'DragRef') and m == "InMode":
+                classname = "Method"
+                listname = "methods"
+        return classname, listname
+
+    def writeinitialdefs(self):
+        self.defsfile.write("def FOUR_CHAR_CODE(x): return x\n")
+        self.defsfile.write("from Carbon.TextEdit import *\n")
+        self.defsfile.write("from Carbon.QuickDraw import *\n")
+        self.defsfile.write("fkDragActionAll = -1\n")
+        self.defsfile.write("\n")
+        # Defines unparseable in Drag.h
+        self.defsfile.write(MISSING_DEFINES)
+
+    def makeblacklistnames(self):
+        return [
+                "kDragActionAll",
+                ]
+
+    def makeblacklisttypes(self):
+        return [
+                "DragTrackingHandlerUPP",
+                "DragReceiveHandlerUPP",
+                "DragSendDataUPP",
+                "DragInputUPP",
+                "DragDrawingUPP",
+                ]
+
+    def makerepairinstructions(self):
+        return [
+                ([("void_ptr", "*", "InMode"), ("Size", "*", "InMode")],
+                 [("OptionalInBuffer", "*", "*")]),
+
+                ([("void", "*", "OutMode"), ("Size", "*", "OutMode")],
+                 [("VarOutBuffer", "*", "InOutMode")]),
+
+                ]
+
+if __name__ == "__main__":
+    main()

Added: vendor/Python/current/Mac/Modules/drag/dragsupport.py
===================================================================
--- vendor/Python/current/Mac/Modules/drag/dragsupport.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/drag/dragsupport.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,293 @@
+# This script generates a Python interface for an Apple Macintosh Manager.
+# It uses the "bgen" package to generate C code.
+# The function specifications are generated by scanning the mamager's header file,
+# using the "scantools" package (customized for this particular manager).
+
+import string
+
+# Declarations that change for each manager
+MACHEADERFILE = 'Drag.h'                # The Apple header file
+MODNAME = '_Drag'                               # The name of the module
+OBJECTNAME = 'DragObj'                  # The basic name of the objects used here
+
+# The following is *usually* unchanged but may still require tuning
+MODPREFIX = 'Drag'                      # The prefix for module-wide routines
+OBJECTTYPE = 'DragRef'  # The C type used to represent them
+OBJECTPREFIX = MODPREFIX + 'Obj'        # The prefix for object methods
+INPUTFILE = string.lower(MODPREFIX) + 'gen.py' # The file generated by the scanner
+OUTPUTFILE = MODNAME + "module.c"       # The file generated by this program
+
+from macsupport import *
+
+# Create the type objects
+
+DragRef = OpaqueByValueType(OBJECTTYPE, OBJECTPREFIX)
+DragItemRef = Type("ItemReference", "l")
+# Old names
+DragReference = DragRef
+ItemReference = DragItemRef
+
+PixMapHandle = OpaqueByValueType("PixMapHandle", "ResObj")
+RgnHandle = OpaqueByValueType("RgnHandle", "ResObj")
+AEDesc = OpaqueType('AEDesc')
+AEDesc_ptr = AEDesc
+RGBColor = OpaqueType("RGBColor", "QdRGB")
+
+FlavorType = OSTypeType("FlavorType")
+DragAttributes = Type("DragAttributes", "l")
+DragBehaviors = Type("DragBehaviors", "l")
+DragImageFlags = Type("DragImageFlags", "l")
+DragImageTranslucency = Type("DragImageTranslucency", "l")
+DragRegionMessage = Type("DragRegionMessage", "h")
+ZoomAcceleration = Type("ZoomAcceleration", "h")
+FlavorFlags = Type("FlavorFlags", "l")
+DragTrackingMessage = Type("DragTrackingMessage", "h")
+
+includestuff = includestuff + """
+#include <Carbon/Carbon.h>
+
+/* Callback glue routines */
+DragTrackingHandlerUPP dragglue_TrackingHandlerUPP;
+DragReceiveHandlerUPP dragglue_ReceiveHandlerUPP;
+DragSendDataUPP dragglue_SendDataUPP;
+#if 0
+DragInputUPP dragglue_InputUPP;
+DragDrawingUPP dragglue_DrawingUPP;
+#endif
+
+#ifdef USE_TOOLBOX_OBJECT_GLUE
+extern PyObject *_DragObj_New(DragRef);
+extern int _DragObj_Convert(PyObject *, DragRef *);
+
+#define DragObj_New _DragObj_New
+#define DragObj_Convert _DragObj_Convert
+#endif
+"""
+
+finalstuff = finalstuff + """
+static pascal OSErr
+dragglue_TrackingHandler(DragTrackingMessage theMessage, WindowPtr theWindow,
+                         void *handlerRefCon, DragReference theDrag)
+{
+        PyObject *args, *rv;
+        int i;
+
+        args = Py_BuildValue("hO&O&", theMessage, DragObj_New, theDrag, WinObj_WhichWindow, theWindow);
+        if ( args == NULL )
+                return -1;
+        rv = PyEval_CallObject((PyObject *)handlerRefCon, args);
+        Py_DECREF(args);
+        if ( rv == NULL ) {
+                PySys_WriteStderr("Drag: Exception in TrackingHandler\\n");
+                PyErr_Print();
+                return -1;
+        }
+        i = -1;
+        if ( rv == Py_None )
+                i = 0;
+        else
+                PyArg_Parse(rv, "l", &i);
+        Py_DECREF(rv);
+        return i;
+}
+
+static pascal OSErr
+dragglue_ReceiveHandler(WindowPtr theWindow, void *handlerRefCon,
+                        DragReference theDrag)
+{
+        PyObject *args, *rv;
+        int i;
+
+        args = Py_BuildValue("O&O&", DragObj_New, theDrag, WinObj_WhichWindow, theWindow);
+        if ( args == NULL )
+                return -1;
+        rv = PyEval_CallObject((PyObject *)handlerRefCon, args);
+        Py_DECREF(args);
+        if ( rv == NULL ) {
+                PySys_WriteStderr("Drag: Exception in ReceiveHandler\\n");
+                PyErr_Print();
+                return -1;
+        }
+        i = -1;
+        if ( rv == Py_None )
+                i = 0;
+        else
+                PyArg_Parse(rv, "l", &i);
+        Py_DECREF(rv);
+        return i;
+}
+
+static pascal OSErr
+dragglue_SendData(FlavorType theType, void *dragSendRefCon,
+                      ItemReference theItem, DragReference theDrag)
+{
+        DragObjObject *self = (DragObjObject *)dragSendRefCon;
+        PyObject *args, *rv;
+        int i;
+
+        if ( self->sendproc == NULL )
+                return -1;
+        args = Py_BuildValue("O&l", PyMac_BuildOSType, theType, theItem);
+        if ( args == NULL )
+                return -1;
+        rv = PyEval_CallObject(self->sendproc, args);
+        Py_DECREF(args);
+        if ( rv == NULL ) {
+                PySys_WriteStderr("Drag: Exception in SendDataHandler\\n");
+                PyErr_Print();
+                return -1;
+        }
+        i = -1;
+        if ( rv == Py_None )
+                i = 0;
+        else
+                PyArg_Parse(rv, "l", &i);
+        Py_DECREF(rv);
+        return i;
+}
+
+#if 0
+static pascal OSErr
+dragglue_Input(Point *mouse, short *modifiers,
+                   void *dragSendRefCon, DragReference theDrag)
+{
+    return 0;
+}
+
+static pascal OSErr
+dragglue_Drawing(xxxx
+                   void *dragSendRefCon, DragReference theDrag)
+{
+    return 0;
+}
+#endif
+
+"""
+
+initstuff = initstuff + """
+        PyMac_INIT_TOOLBOX_OBJECT_NEW(DragRef, DragObj_New);
+        PyMac_INIT_TOOLBOX_OBJECT_CONVERT(DragRef, DragObj_Convert);
+"""
+
+variablestuff = """
+dragglue_TrackingHandlerUPP = NewDragTrackingHandlerUPP(dragglue_TrackingHandler);
+dragglue_ReceiveHandlerUPP = NewDragReceiveHandlerUPP(dragglue_ReceiveHandler);
+dragglue_SendDataUPP = NewDragSendDataUPP(dragglue_SendData);
+#if 0
+dragglue_InputUPP = NewDragInputUPP(dragglue_Input);
+dragglue_DrawingUPP = NewDragDrawingUPP(dragglue_Drawing);
+#endif
+"""
+
+class MyObjectDefinition(PEP253Mixin, GlobalObjectDefinition):
+    def outputCheckNewArg(self):
+        Output("""if (itself == NULL) {
+                                PyErr_SetString(Drag_Error,"Cannot create null Drag");
+                                return NULL;
+                        }""")
+    def outputFreeIt(self, itselfname):
+        ## Output("DisposeDrag(%s);", itselfname)
+        Output("Py_XDECREF(self->sendproc);")
+        ## Output("Py_XDECREF(self->inputproc);")
+        ## Output("Py_XDECREF(self->drawingproc);")
+
+    def outputStructMembers(self):
+        GlobalObjectDefinition.outputStructMembers(self)
+        Output("PyObject *sendproc;")
+        ## Output("PyObject *inputproc;")
+        ## Output("PyObject *drawingproc;")
+
+    def outputInitStructMembers(self):
+        GlobalObjectDefinition.outputInitStructMembers(self)
+        Output("it->sendproc = NULL;")
+        ## Output("it->inputproc = NULL;")
+        ## Output("it->drawingproc = NULL;")
+
+
+# Create the generator groups and link them
+module = MacModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff, variablestuff)
+object = MyObjectDefinition(OBJECTNAME, OBJECTPREFIX, OBJECTTYPE)
+module.addobject(object)
+
+# Create the generator classes used to populate the lists
+Function = OSErrWeakLinkFunctionGenerator
+Method = OSErrWeakLinkMethodGenerator
+
+# Create and populate the lists
+functions = []
+methods = []
+execfile(INPUTFILE)
+
+# add the populated lists to the generator groups
+for f in functions: module.add(f)
+for f in methods: object.add(f)
+
+# Manual generators for the callbacks
+
+installtracking_body = """
+    PyObject *callback;
+    WindowPtr theWindow = NULL;
+    OSErr _err;
+
+    if ( !PyArg_ParseTuple(_args, "O|O&", &callback, WinObj_Convert, &theWindow) )
+        return NULL;
+    Py_INCREF(callback);        /* Cannot decref later, too bad */
+    _err = InstallTrackingHandler(dragglue_TrackingHandlerUPP, theWindow, (void *)callback);
+        if (_err != noErr) return PyMac_Error(_err);
+        Py_INCREF(Py_None);
+        _res = Py_None;
+        return _res;
+"""
+installtracking = ManualGenerator("InstallTrackingHandler", installtracking_body)
+module.add(installtracking)
+
+installreceive_body = """
+    PyObject *callback;
+    WindowPtr theWindow = NULL;
+    OSErr _err;
+
+    if ( !PyArg_ParseTuple(_args, "O|O&", &callback, WinObj_Convert, &theWindow) )
+        return NULL;
+    Py_INCREF(callback);        /* Cannot decref later, too bad */
+    _err = InstallReceiveHandler(dragglue_ReceiveHandlerUPP, theWindow, (void *)callback);
+        if (_err != noErr) return PyMac_Error(_err);
+        Py_INCREF(Py_None);
+        _res = Py_None;
+        return _res;
+"""
+installreceive = ManualGenerator("InstallReceiveHandler", installreceive_body)
+module.add(installreceive)
+
+removetracking_body = """
+    WindowPtr theWindow = NULL;
+    OSErr _err;
+
+    if ( !PyArg_ParseTuple(_args, "|O&", WinObj_Convert, &theWindow) )
+        return NULL;
+    _err = RemoveTrackingHandler(dragglue_TrackingHandlerUPP, theWindow);
+        if (_err != noErr) return PyMac_Error(_err);
+        Py_INCREF(Py_None);
+        _res = Py_None;
+        return _res;
+"""
+removetracking = ManualGenerator("RemoveTrackingHandler", removetracking_body)
+module.add(removetracking)
+
+removereceive_body = """
+    WindowPtr theWindow = NULL;
+    OSErr _err;
+
+    if ( !PyArg_ParseTuple(_args, "|O&", WinObj_Convert, &theWindow) )
+        return NULL;
+    _err = RemoveReceiveHandler(dragglue_ReceiveHandlerUPP, theWindow);
+        if (_err != noErr) return PyMac_Error(_err);
+        Py_INCREF(Py_None);
+        _res = Py_None;
+        return _res;
+"""
+removereceive = ManualGenerator("RemoveReceiveHandler", removereceive_body)
+module.add(removereceive)
+
+# generate output (open the output file as late as possible)
+SetOutputFileName(OUTPUTFILE)
+module.generate()

Added: vendor/Python/current/Mac/Modules/evt/_Evtmodule.c
===================================================================
--- vendor/Python/current/Mac/Modules/evt/_Evtmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/evt/_Evtmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,548 @@
+
+/* ========================== Module _Evt =========================== */
+
+#include "Python.h"
+
+
+
+#include "pymactoolbox.h"
+
+/* Macro to test whether a weak-loaded CFM function exists */
+#define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL )  {\
+        PyErr_SetString(PyExc_NotImplementedError, \
+        "Not available in this shared library/OS version"); \
+        return NULL; \
+    }} while(0)
+
+
+#include <Carbon/Carbon.h>
+
+
+static PyObject *Evt_Error;
+
+static PyObject *Evt_GetMouse(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Point mouseLoc;
+#ifndef GetMouse
+	PyMac_PRECHECK(GetMouse);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	GetMouse(&mouseLoc);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildPoint, mouseLoc);
+	return _res;
+}
+
+static PyObject *Evt_Button(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+#ifndef Button
+	PyMac_PRECHECK(Button);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = Button();
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Evt_StillDown(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+#ifndef StillDown
+	PyMac_PRECHECK(StillDown);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = StillDown();
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Evt_WaitMouseUp(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+#ifndef WaitMouseUp
+	PyMac_PRECHECK(WaitMouseUp);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = WaitMouseUp();
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Evt_GetCaretTime(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	UInt32 _rv;
+#ifndef GetCaretTime
+	PyMac_PRECHECK(GetCaretTime);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetCaretTime();
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Evt_GetKeys(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	KeyMap theKeys__out__;
+#ifndef GetKeys
+	PyMac_PRECHECK(GetKeys);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	GetKeys(theKeys__out__);
+	_res = Py_BuildValue("s#",
+	                     (char *)&theKeys__out__, (int)sizeof(KeyMap));
+	return _res;
+}
+
+static PyObject *Evt_GetDblTime(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	UInt32 _rv;
+#ifndef GetDblTime
+	PyMac_PRECHECK(GetDblTime);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetDblTime();
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Evt_SetEventMask(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	EventMask value;
+#ifndef SetEventMask
+	PyMac_PRECHECK(SetEventMask);
+#endif
+	if (!PyArg_ParseTuple(_args, "H",
+	                      &value))
+		return NULL;
+	SetEventMask(value);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Evt_GetNextEvent(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	EventMask eventMask;
+	EventRecord theEvent;
+#ifndef GetNextEvent
+	PyMac_PRECHECK(GetNextEvent);
+#endif
+	if (!PyArg_ParseTuple(_args, "H",
+	                      &eventMask))
+		return NULL;
+	_rv = GetNextEvent(eventMask,
+	                   &theEvent);
+	_res = Py_BuildValue("bO&",
+	                     _rv,
+	                     PyMac_BuildEventRecord, &theEvent);
+	return _res;
+}
+
+static PyObject *Evt_EventAvail(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	EventMask eventMask;
+	EventRecord theEvent;
+#ifndef EventAvail
+	PyMac_PRECHECK(EventAvail);
+#endif
+	if (!PyArg_ParseTuple(_args, "H",
+	                      &eventMask))
+		return NULL;
+	_rv = EventAvail(eventMask,
+	                 &theEvent);
+	_res = Py_BuildValue("bO&",
+	                     _rv,
+	                     PyMac_BuildEventRecord, &theEvent);
+	return _res;
+}
+
+static PyObject *Evt_PostEvent(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	EventKind eventNum;
+	UInt32 eventMsg;
+#ifndef PostEvent
+	PyMac_PRECHECK(PostEvent);
+#endif
+	if (!PyArg_ParseTuple(_args, "Hl",
+	                      &eventNum,
+	                      &eventMsg))
+		return NULL;
+	_err = PostEvent(eventNum,
+	                 eventMsg);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Evt_FlushEvents(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	EventMask whichMask;
+	EventMask stopMask;
+#ifndef FlushEvents
+	PyMac_PRECHECK(FlushEvents);
+#endif
+	if (!PyArg_ParseTuple(_args, "HH",
+	                      &whichMask,
+	                      &stopMask))
+		return NULL;
+	FlushEvents(whichMask,
+	            stopMask);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Evt_GetGlobalMouse(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Point globalMouse;
+#ifndef GetGlobalMouse
+	PyMac_PRECHECK(GetGlobalMouse);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	GetGlobalMouse(&globalMouse);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildPoint, globalMouse);
+	return _res;
+}
+
+static PyObject *Evt_GetCurrentKeyModifiers(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	UInt32 _rv;
+#ifndef GetCurrentKeyModifiers
+	PyMac_PRECHECK(GetCurrentKeyModifiers);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetCurrentKeyModifiers();
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Evt_CheckEventQueueForUserCancel(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+#ifndef CheckEventQueueForUserCancel
+	PyMac_PRECHECK(CheckEventQueueForUserCancel);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CheckEventQueueForUserCancel();
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Evt_KeyScript(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short code;
+#ifndef KeyScript
+	PyMac_PRECHECK(KeyScript);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &code))
+		return NULL;
+	KeyScript(code);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Evt_IsCmdChar(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	EventRecord event;
+	short test;
+#ifndef IsCmdChar
+	PyMac_PRECHECK(IsCmdChar);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      PyMac_GetEventRecord, &event,
+	                      &test))
+		return NULL;
+	_rv = IsCmdChar(&event,
+	                test);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Evt_LMGetKeyThresh(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	SInt16 _rv;
+#ifndef LMGetKeyThresh
+	PyMac_PRECHECK(LMGetKeyThresh);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = LMGetKeyThresh();
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Evt_LMSetKeyThresh(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	SInt16 value;
+#ifndef LMSetKeyThresh
+	PyMac_PRECHECK(LMSetKeyThresh);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &value))
+		return NULL;
+	LMSetKeyThresh(value);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Evt_LMGetKeyRepThresh(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	SInt16 _rv;
+#ifndef LMGetKeyRepThresh
+	PyMac_PRECHECK(LMGetKeyRepThresh);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = LMGetKeyRepThresh();
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Evt_LMSetKeyRepThresh(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	SInt16 value;
+#ifndef LMSetKeyRepThresh
+	PyMac_PRECHECK(LMSetKeyRepThresh);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &value))
+		return NULL;
+	LMSetKeyRepThresh(value);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Evt_LMGetKbdLast(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	UInt8 _rv;
+#ifndef LMGetKbdLast
+	PyMac_PRECHECK(LMGetKbdLast);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = LMGetKbdLast();
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Evt_LMSetKbdLast(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	UInt8 value;
+#ifndef LMSetKbdLast
+	PyMac_PRECHECK(LMSetKbdLast);
+#endif
+	if (!PyArg_ParseTuple(_args, "b",
+	                      &value))
+		return NULL;
+	LMSetKbdLast(value);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Evt_LMGetKbdType(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	UInt8 _rv;
+#ifndef LMGetKbdType
+	PyMac_PRECHECK(LMGetKbdType);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = LMGetKbdType();
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Evt_LMSetKbdType(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	UInt8 value;
+#ifndef LMSetKbdType
+	PyMac_PRECHECK(LMSetKbdType);
+#endif
+	if (!PyArg_ParseTuple(_args, "b",
+	                      &value))
+		return NULL;
+	LMSetKbdType(value);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Evt_TickCount(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	UInt32 _rv;
+#ifndef TickCount
+	PyMac_PRECHECK(TickCount);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = TickCount();
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Evt_WaitNextEvent(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+
+	Boolean _rv;
+	EventMask eventMask;
+	EventRecord theEvent;
+	UInt32 sleep;
+	Handle mouseregion = (Handle)0;
+
+	if (!PyArg_ParseTuple(_args, "Hl|O&",
+	                      &eventMask,
+	                      &sleep,
+	                      OptResObj_Convert, &mouseregion))
+	        return NULL;
+	_rv = WaitNextEvent(eventMask,
+	                    &theEvent,
+	                    sleep,
+	                    (RgnHandle)mouseregion);
+	_res = Py_BuildValue("bO&",
+	                     _rv,
+	                     PyMac_BuildEventRecord, &theEvent);
+	return _res;
+
+}
+
+static PyMethodDef Evt_methods[] = {
+	{"GetMouse", (PyCFunction)Evt_GetMouse, 1,
+	 PyDoc_STR("() -> (Point mouseLoc)")},
+	{"Button", (PyCFunction)Evt_Button, 1,
+	 PyDoc_STR("() -> (Boolean _rv)")},
+	{"StillDown", (PyCFunction)Evt_StillDown, 1,
+	 PyDoc_STR("() -> (Boolean _rv)")},
+	{"WaitMouseUp", (PyCFunction)Evt_WaitMouseUp, 1,
+	 PyDoc_STR("() -> (Boolean _rv)")},
+	{"GetCaretTime", (PyCFunction)Evt_GetCaretTime, 1,
+	 PyDoc_STR("() -> (UInt32 _rv)")},
+	{"GetKeys", (PyCFunction)Evt_GetKeys, 1,
+	 PyDoc_STR("() -> (KeyMap theKeys)")},
+	{"GetDblTime", (PyCFunction)Evt_GetDblTime, 1,
+	 PyDoc_STR("() -> (UInt32 _rv)")},
+	{"SetEventMask", (PyCFunction)Evt_SetEventMask, 1,
+	 PyDoc_STR("(EventMask value) -> None")},
+	{"GetNextEvent", (PyCFunction)Evt_GetNextEvent, 1,
+	 PyDoc_STR("(EventMask eventMask) -> (Boolean _rv, EventRecord theEvent)")},
+	{"EventAvail", (PyCFunction)Evt_EventAvail, 1,
+	 PyDoc_STR("(EventMask eventMask) -> (Boolean _rv, EventRecord theEvent)")},
+	{"PostEvent", (PyCFunction)Evt_PostEvent, 1,
+	 PyDoc_STR("(EventKind eventNum, UInt32 eventMsg) -> None")},
+	{"FlushEvents", (PyCFunction)Evt_FlushEvents, 1,
+	 PyDoc_STR("(EventMask whichMask, EventMask stopMask) -> None")},
+	{"GetGlobalMouse", (PyCFunction)Evt_GetGlobalMouse, 1,
+	 PyDoc_STR("() -> (Point globalMouse)")},
+	{"GetCurrentKeyModifiers", (PyCFunction)Evt_GetCurrentKeyModifiers, 1,
+	 PyDoc_STR("() -> (UInt32 _rv)")},
+	{"CheckEventQueueForUserCancel", (PyCFunction)Evt_CheckEventQueueForUserCancel, 1,
+	 PyDoc_STR("() -> (Boolean _rv)")},
+	{"KeyScript", (PyCFunction)Evt_KeyScript, 1,
+	 PyDoc_STR("(short code) -> None")},
+	{"IsCmdChar", (PyCFunction)Evt_IsCmdChar, 1,
+	 PyDoc_STR("(EventRecord event, short test) -> (Boolean _rv)")},
+	{"LMGetKeyThresh", (PyCFunction)Evt_LMGetKeyThresh, 1,
+	 PyDoc_STR("() -> (SInt16 _rv)")},
+	{"LMSetKeyThresh", (PyCFunction)Evt_LMSetKeyThresh, 1,
+	 PyDoc_STR("(SInt16 value) -> None")},
+	{"LMGetKeyRepThresh", (PyCFunction)Evt_LMGetKeyRepThresh, 1,
+	 PyDoc_STR("() -> (SInt16 _rv)")},
+	{"LMSetKeyRepThresh", (PyCFunction)Evt_LMSetKeyRepThresh, 1,
+	 PyDoc_STR("(SInt16 value) -> None")},
+	{"LMGetKbdLast", (PyCFunction)Evt_LMGetKbdLast, 1,
+	 PyDoc_STR("() -> (UInt8 _rv)")},
+	{"LMSetKbdLast", (PyCFunction)Evt_LMSetKbdLast, 1,
+	 PyDoc_STR("(UInt8 value) -> None")},
+	{"LMGetKbdType", (PyCFunction)Evt_LMGetKbdType, 1,
+	 PyDoc_STR("() -> (UInt8 _rv)")},
+	{"LMSetKbdType", (PyCFunction)Evt_LMSetKbdType, 1,
+	 PyDoc_STR("(UInt8 value) -> None")},
+	{"TickCount", (PyCFunction)Evt_TickCount, 1,
+	 PyDoc_STR("() -> (UInt32 _rv)")},
+	{"WaitNextEvent", (PyCFunction)Evt_WaitNextEvent, 1,
+	 PyDoc_STR("(EventMask eventMask, UInt32 sleep [,RegionHandle]) -> (Boolean _rv, EventRecord theEvent)")},
+	{NULL, NULL, 0}
+};
+
+
+
+
+void init_Evt(void)
+{
+	PyObject *m;
+	PyObject *d;
+
+
+
+
+	m = Py_InitModule("_Evt", Evt_methods);
+	d = PyModule_GetDict(m);
+	Evt_Error = PyMac_GetOSErrException();
+	if (Evt_Error == NULL ||
+	    PyDict_SetItemString(d, "Error", Evt_Error) != 0)
+		return;
+}
+
+/* ======================== End module _Evt ========================= */
+

Added: vendor/Python/current/Mac/Modules/evt/evtedit.py
===================================================================
--- vendor/Python/current/Mac/Modules/evt/evtedit.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/evt/evtedit.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,9 @@
+f = Function(void, 'SystemClick',
+    (EventRecord_ptr, 'theEvent', InMode),
+    (WindowPtr, 'theWindow', InMode),
+)
+functions.append(f)
+
+f = Function(UInt32, 'TickCount',
+)
+functions.append(f)

Added: vendor/Python/current/Mac/Modules/evt/evtscan.py
===================================================================
--- vendor/Python/current/Mac/Modules/evt/evtscan.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/evt/evtscan.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,81 @@
+# Scan an Apple header file, generating a Python file of generator calls.
+
+import sys
+import os
+from bgenlocations import TOOLBOXDIR, BGENDIR
+sys.path.append(BGENDIR)
+from scantools import Scanner
+
+LONG = "Events"
+SHORT = "evt"
+OBJECT = "NOTUSED"
+
+def main():
+    input = LONG + ".h"
+    output = SHORT + "gen.py"
+    defsoutput = TOOLBOXDIR + LONG + ".py"
+    scanner = MyScanner(input, output, defsoutput)
+    scanner.scan()
+    scanner.close()
+    print "=== Testing definitions output code ==="
+    execfile(defsoutput, {}, {})
+    print "=== Done scanning and generating, now importing the generated code... ==="
+    exec "import " + SHORT + "support"
+    print "=== Done.  It's up to you to compile it now! ==="
+
+class MyScanner(Scanner):
+
+    def destination(self, type, name, arglist):
+        classname = "Function"
+        listname = "functions"
+        if arglist:
+            t, n, m = arglist[0]
+            # This is non-functional today
+            if t == OBJECT and m == "InMode":
+                classname = "Method"
+                listname = "methods"
+        return classname, listname
+
+    def makeblacklistnames(self):
+        return [
+                "KeyTranslate",
+                "GetEventMask",         # I cannot seem to find this routine...
+                "WaitNextEvent",        # Manually generated because of optional region
+                # Constants with funny definitions
+                "osEvtMessageMask",
+                # OS8 calls
+                'SystemEvent',
+                'SystemTask',
+                'SystemClick',
+                'GetOSEvent',
+                'OSEventAvail',
+                ]
+
+    def makeblacklisttypes(self):
+        return [
+                "EvQElPtr", "QHdrPtr"
+                ]
+
+    def makerepairinstructions(self):
+        return [
+                ([("void_ptr", "*", "InMode"), ("long", "*", "InMode")],
+                 [("InBuffer", "*", "*")]),
+
+                ([("void", "*", "OutMode"), ("long", "*", "InMode"),
+                                            ("long", "*", "OutMode")],
+                 [("VarVarOutBuffer", "*", "InOutMode")]),
+
+                ([("void", "wStorage", "OutMode")],
+                 [("NullStorage", "*", "InMode")]),
+
+                # GetKeys
+                ([('KeyMap', 'theKeys', 'InMode')],
+                 [('*', '*', 'OutMode')]),
+
+                # GetTicker
+                ([('unsigned long', '*', '*')],
+                 [('unsigned_long', '*', '*')]),
+                ]
+
+if __name__ == "__main__":
+    main()

Added: vendor/Python/current/Mac/Modules/evt/evtsupport.py
===================================================================
--- vendor/Python/current/Mac/Modules/evt/evtsupport.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/evt/evtsupport.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,92 @@
+# This script generates a Python interface for an Apple Macintosh Manager.
+# It uses the "bgen" package to generate C code.
+# The function specifications are generated by scanning the mamager's header file,
+# using the "scantools" package (customized for this particular manager).
+
+import string
+
+# Declarations that change for each manager
+MACHEADERFILE = 'Events.h'              # The Apple header file
+MODNAME = '_Evt'                                # The name of the module
+OBJECTNAME = 'Event'                    # The basic name of the objects used here
+KIND = 'Record'                         # Usually 'Ptr' or 'Handle'
+
+# The following is *usually* unchanged but may still require tuning
+MODPREFIX = 'Evt'                       # The prefix for module-wide routines
+OBJECTTYPE = OBJECTNAME + KIND          # The C type used to represent them
+OBJECTPREFIX = MODPREFIX + 'Obj'        # The prefix for object methods
+INPUTFILE = string.lower(MODPREFIX) + 'gen.py' # The file generated by the scanner
+OUTPUTFILE = MODNAME + "module.c"       # The file generated by this program
+
+from macsupport import *
+
+# Create the type objects
+
+#WindowPeek = OpaqueByValueType("WindowPeek", OBJECTPREFIX)
+
+RgnHandle = FakeType("(RgnHandle)0")
+# XXXX Should be next, but this will break a lot of code...
+# RgnHandle = OpaqueByValueType("RgnHandle", "OptResObj")
+
+KeyMap = ArrayOutputBufferType("KeyMap")
+##MacOSEventKind = Type("MacOSEventKind", "h") # Old-style
+##MacOSEventMask = Type("MacOSEventMask", "h") # Old-style
+EventMask = Type("EventMask", "H")
+EventKind = Type("EventKind", "H")
+
+includestuff = includestuff + """
+#include <Carbon/Carbon.h>
+
+"""
+
+# From here on it's basically all boiler plate...
+
+# Create the generator groups and link them
+module = MacModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff)
+
+# Create the generator classes used to populate the lists
+Function = OSErrWeakLinkFunctionGenerator
+##Method = OSErrWeakLinkMethodGenerator
+
+# Create and populate the lists
+functions = []
+execfile(INPUTFILE)
+
+# Move TickCount here, for convenience
+f = Function(UInt32, 'TickCount',
+)
+functions.append(f)
+
+# add the populated lists to the generator groups
+# (in a different wordl the scan program would generate this)
+for f in functions: module.add(f)
+
+WaitNextEvent_body = """
+Boolean _rv;
+EventMask eventMask;
+EventRecord theEvent;
+UInt32 sleep;
+Handle mouseregion = (Handle)0;
+
+if (!PyArg_ParseTuple(_args, "Hl|O&",
+                      &eventMask,
+                      &sleep,
+                      OptResObj_Convert, &mouseregion))
+        return NULL;
+_rv = WaitNextEvent(eventMask,
+                    &theEvent,
+                    sleep,
+                    (RgnHandle)mouseregion);
+_res = Py_BuildValue("bO&",
+                     _rv,
+                     PyMac_BuildEventRecord, &theEvent);
+return _res;
+"""
+f = ManualGenerator("WaitNextEvent", WaitNextEvent_body);
+f.docstring = lambda: "(EventMask eventMask, UInt32 sleep [,RegionHandle]) -> (Boolean _rv, EventRecord theEvent)"
+module.add(f)
+
+
+# generate output (open the output file as late as possible)
+SetOutputFileName(OUTPUTFILE)
+module.generate()

Added: vendor/Python/current/Mac/Modules/file/_Filemodule.c
===================================================================
--- vendor/Python/current/Mac/Modules/file/_Filemodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/file/_Filemodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,3296 @@
+
+/* ========================== Module _File ========================== */
+
+#include "Python.h"
+
+
+
+#include "pymactoolbox.h"
+
+/* Macro to test whether a weak-loaded CFM function exists */
+#define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL )  {\
+        PyErr_SetString(PyExc_NotImplementedError, \
+        "Not available in this shared library/OS version"); \
+        return NULL; \
+    }} while(0)
+
+
+#include <Carbon/Carbon.h>
+
+#ifdef USE_TOOLBOX_OBJECT_GLUE
+extern int _PyMac_GetFSSpec(PyObject *v, FSSpec *spec);
+extern int _PyMac_GetFSRef(PyObject *v, FSRef *fsr);
+extern PyObject *_PyMac_BuildFSSpec(FSSpec *spec);
+extern PyObject *_PyMac_BuildFSRef(FSRef *spec);
+
+#define PyMac_GetFSSpec _PyMac_GetFSSpec
+#define PyMac_GetFSRef _PyMac_GetFSRef
+#define PyMac_BuildFSSpec _PyMac_BuildFSSpec
+#define PyMac_BuildFSRef _PyMac_BuildFSRef
+#else
+extern int PyMac_GetFSSpec(PyObject *v, FSSpec *spec);
+extern int PyMac_GetFSRef(PyObject *v, FSRef *fsr);
+extern PyObject *PyMac_BuildFSSpec(FSSpec *spec);
+extern PyObject *PyMac_BuildFSRef(FSRef *spec);
+#endif
+
+/* Forward declarations */
+static PyObject *FInfo_New(FInfo *itself);
+static PyObject *FSRef_New(FSRef *itself);
+static PyObject *FSSpec_New(FSSpec *itself);
+static PyObject *Alias_New(AliasHandle itself);
+static int FInfo_Convert(PyObject *v, FInfo *p_itself);
+#define FSRef_Convert PyMac_GetFSRef
+#define FSSpec_Convert PyMac_GetFSSpec
+static int Alias_Convert(PyObject *v, AliasHandle *p_itself);
+
+/*
+** UTCDateTime records
+*/
+static int
+UTCDateTime_Convert(PyObject *v, UTCDateTime *ptr)
+{
+        return PyArg_Parse(v, "(HlH)", &ptr->highSeconds, &ptr->lowSeconds, &ptr->fraction);
+}
+
+static PyObject *
+UTCDateTime_New(UTCDateTime *ptr)
+{
+        return Py_BuildValue("(HlH)", ptr->highSeconds, ptr->lowSeconds, ptr->fraction);
+}
+
+/*
+** Optional fsspec and fsref pointers. None will pass NULL
+*/
+static int
+myPyMac_GetOptFSSpecPtr(PyObject *v, FSSpec **spec)
+{
+        if (v == Py_None) {
+                *spec = NULL;
+                return 1;
+        }
+        return PyMac_GetFSSpec(v, *spec);
+}
+
+static int
+myPyMac_GetOptFSRefPtr(PyObject *v, FSRef **ref)
+{
+        if (v == Py_None) {
+                *ref = NULL;
+                return 1;
+        }
+        return PyMac_GetFSRef(v, *ref);
+}
+
+/*
+** Parse/generate objsect
+*/
+static PyObject *
+PyMac_BuildHFSUniStr255(HFSUniStr255 *itself)
+{
+
+        return Py_BuildValue("u#", itself->unicode, itself->length);
+}
+
+static OSErr
+_PyMac_GetFullPathname(FSSpec *fss, char *path, int len)
+{
+	FSRef fsr;
+	OSErr err;
+
+	*path = '\0';
+	err = FSpMakeFSRef(fss, &fsr);
+	if (err == fnfErr) {
+		/* FSSpecs can point to non-existing files, fsrefs can't. */
+		FSSpec fss2;
+		int tocopy;
+
+		err = FSMakeFSSpec(fss->vRefNum, fss->parID,
+				   (unsigned char*)"", &fss2);
+		if (err)
+			return err;
+		err = FSpMakeFSRef(&fss2, &fsr);
+		if (err)
+			return err;
+		err = (OSErr)FSRefMakePath(&fsr, (unsigned char*)path, len-1);
+		if (err)
+			return err;
+		/* This part is not 100% safe: we append the filename part, but
+		** I'm not sure that we don't run afoul of the various 8bit
+		** encodings here. Will have to look this up at some point...
+		*/
+		strcat(path, "/");
+		tocopy = fss->name[0];
+		if ((strlen(path) + tocopy) >= len)
+			tocopy = len - strlen(path) - 1;
+		if (tocopy > 0)
+			strncat(path, (char*)fss->name+1, tocopy);
+	}
+	else {
+		if (err)
+			return err;
+		err = (OSErr)FSRefMakePath(&fsr, (unsigned char*)path, len);
+		if (err)
+			return err;
+	}
+	return 0;
+}
+
+
+static PyObject *File_Error;
+
+/* ------------------- Object type FSCatalogInfo -------------------- */
+
+static PyTypeObject FSCatalogInfo_Type;
+
+#define FSCatalogInfo_Check(x) ((x)->ob_type == &FSCatalogInfo_Type || PyObject_TypeCheck((x), &FSCatalogInfo_Type))
+
+typedef struct FSCatalogInfoObject {
+	PyObject_HEAD
+	FSCatalogInfo ob_itself;
+} FSCatalogInfoObject;
+
+static PyObject *FSCatalogInfo_New(FSCatalogInfo *itself)
+{
+	FSCatalogInfoObject *it;
+	if (itself == NULL) { Py_INCREF(Py_None); return Py_None; }
+	it = PyObject_NEW(FSCatalogInfoObject, &FSCatalogInfo_Type);
+	if (it == NULL) return NULL;
+	it->ob_itself = *itself;
+	return (PyObject *)it;
+}
+
+static int FSCatalogInfo_Convert(PyObject *v, FSCatalogInfo *p_itself)
+{
+	if (!FSCatalogInfo_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "FSCatalogInfo required");
+		return 0;
+	}
+	*p_itself = ((FSCatalogInfoObject *)v)->ob_itself;
+	return 1;
+}
+
+static void FSCatalogInfo_dealloc(FSCatalogInfoObject *self)
+{
+	/* Cleanup of self->ob_itself goes here */
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyMethodDef FSCatalogInfo_methods[] = {
+	{NULL, NULL, 0}
+};
+
+static PyObject *FSCatalogInfo_get_nodeFlags(FSCatalogInfoObject *self, void *closure)
+{
+	return Py_BuildValue("H", self->ob_itself.nodeFlags);
+}
+
+static int FSCatalogInfo_set_nodeFlags(FSCatalogInfoObject *self, PyObject *v, void *closure)
+{
+	return PyArg_Parse(v, "H", &self->ob_itself.nodeFlags)-1;
+	return 0;
+}
+
+static PyObject *FSCatalogInfo_get_volume(FSCatalogInfoObject *self, void *closure)
+{
+	return Py_BuildValue("h", self->ob_itself.volume);
+}
+
+static int FSCatalogInfo_set_volume(FSCatalogInfoObject *self, PyObject *v, void *closure)
+{
+	return PyArg_Parse(v, "h", &self->ob_itself.volume)-1;
+	return 0;
+}
+
+static PyObject *FSCatalogInfo_get_parentDirID(FSCatalogInfoObject *self, void *closure)
+{
+	return Py_BuildValue("l", self->ob_itself.parentDirID);
+}
+
+static int FSCatalogInfo_set_parentDirID(FSCatalogInfoObject *self, PyObject *v, void *closure)
+{
+	return PyArg_Parse(v, "l", &self->ob_itself.parentDirID)-1;
+	return 0;
+}
+
+static PyObject *FSCatalogInfo_get_nodeID(FSCatalogInfoObject *self, void *closure)
+{
+	return Py_BuildValue("l", self->ob_itself.nodeID);
+}
+
+static int FSCatalogInfo_set_nodeID(FSCatalogInfoObject *self, PyObject *v, void *closure)
+{
+	return PyArg_Parse(v, "l", &self->ob_itself.nodeID)-1;
+	return 0;
+}
+
+static PyObject *FSCatalogInfo_get_createDate(FSCatalogInfoObject *self, void *closure)
+{
+	return Py_BuildValue("O&", UTCDateTime_New, &self->ob_itself.createDate);
+}
+
+static int FSCatalogInfo_set_createDate(FSCatalogInfoObject *self, PyObject *v, void *closure)
+{
+	return PyArg_Parse(v, "O&", UTCDateTime_Convert, &self->ob_itself.createDate)-1;
+	return 0;
+}
+
+static PyObject *FSCatalogInfo_get_contentModDate(FSCatalogInfoObject *self, void *closure)
+{
+	return Py_BuildValue("O&", UTCDateTime_New, &self->ob_itself.contentModDate);
+}
+
+static int FSCatalogInfo_set_contentModDate(FSCatalogInfoObject *self, PyObject *v, void *closure)
+{
+	return PyArg_Parse(v, "O&", UTCDateTime_Convert, &self->ob_itself.contentModDate)-1;
+	return 0;
+}
+
+static PyObject *FSCatalogInfo_get_attributeModDate(FSCatalogInfoObject *self, void *closure)
+{
+	return Py_BuildValue("O&", UTCDateTime_New, &self->ob_itself.attributeModDate);
+}
+
+static int FSCatalogInfo_set_attributeModDate(FSCatalogInfoObject *self, PyObject *v, void *closure)
+{
+	return PyArg_Parse(v, "O&", UTCDateTime_Convert, &self->ob_itself.attributeModDate)-1;
+	return 0;
+}
+
+static PyObject *FSCatalogInfo_get_accessDate(FSCatalogInfoObject *self, void *closure)
+{
+	return Py_BuildValue("O&", UTCDateTime_New, &self->ob_itself.accessDate);
+}
+
+static int FSCatalogInfo_set_accessDate(FSCatalogInfoObject *self, PyObject *v, void *closure)
+{
+	return PyArg_Parse(v, "O&", UTCDateTime_Convert, &self->ob_itself.accessDate)-1;
+	return 0;
+}
+
+static PyObject *FSCatalogInfo_get_backupDate(FSCatalogInfoObject *self, void *closure)
+{
+	return Py_BuildValue("O&", UTCDateTime_New, &self->ob_itself.backupDate);
+}
+
+static int FSCatalogInfo_set_backupDate(FSCatalogInfoObject *self, PyObject *v, void *closure)
+{
+	return PyArg_Parse(v, "O&", UTCDateTime_Convert, &self->ob_itself.backupDate)-1;
+	return 0;
+}
+
+static PyObject *FSCatalogInfo_get_permissions(FSCatalogInfoObject *self, void *closure)
+{
+	return Py_BuildValue("(llll)", self->ob_itself.permissions[0], self->ob_itself.permissions[1], self->ob_itself.permissions[2], self->ob_itself.permissions[3]);
+}
+
+static int FSCatalogInfo_set_permissions(FSCatalogInfoObject *self, PyObject *v, void *closure)
+{
+	return PyArg_Parse(v, "(llll)", &self->ob_itself.permissions[0], &self->ob_itself.permissions[1], &self->ob_itself.permissions[2], &self->ob_itself.permissions[3])-1;
+	return 0;
+}
+
+static PyObject *FSCatalogInfo_get_valence(FSCatalogInfoObject *self, void *closure)
+{
+	return Py_BuildValue("l", self->ob_itself.valence);
+}
+
+static int FSCatalogInfo_set_valence(FSCatalogInfoObject *self, PyObject *v, void *closure)
+{
+	return PyArg_Parse(v, "l", &self->ob_itself.valence)-1;
+	return 0;
+}
+
+static PyObject *FSCatalogInfo_get_dataLogicalSize(FSCatalogInfoObject *self, void *closure)
+{
+	return Py_BuildValue("l", self->ob_itself.dataLogicalSize);
+}
+
+static int FSCatalogInfo_set_dataLogicalSize(FSCatalogInfoObject *self, PyObject *v, void *closure)
+{
+	return PyArg_Parse(v, "l", &self->ob_itself.dataLogicalSize)-1;
+	return 0;
+}
+
+static PyObject *FSCatalogInfo_get_dataPhysicalSize(FSCatalogInfoObject *self, void *closure)
+{
+	return Py_BuildValue("l", self->ob_itself.dataPhysicalSize);
+}
+
+static int FSCatalogInfo_set_dataPhysicalSize(FSCatalogInfoObject *self, PyObject *v, void *closure)
+{
+	return PyArg_Parse(v, "l", &self->ob_itself.dataPhysicalSize)-1;
+	return 0;
+}
+
+static PyObject *FSCatalogInfo_get_rsrcLogicalSize(FSCatalogInfoObject *self, void *closure)
+{
+	return Py_BuildValue("l", self->ob_itself.rsrcLogicalSize);
+}
+
+static int FSCatalogInfo_set_rsrcLogicalSize(FSCatalogInfoObject *self, PyObject *v, void *closure)
+{
+	return PyArg_Parse(v, "l", &self->ob_itself.rsrcLogicalSize)-1;
+	return 0;
+}
+
+static PyObject *FSCatalogInfo_get_rsrcPhysicalSize(FSCatalogInfoObject *self, void *closure)
+{
+	return Py_BuildValue("l", self->ob_itself.rsrcPhysicalSize);
+}
+
+static int FSCatalogInfo_set_rsrcPhysicalSize(FSCatalogInfoObject *self, PyObject *v, void *closure)
+{
+	return PyArg_Parse(v, "l", &self->ob_itself.rsrcPhysicalSize)-1;
+	return 0;
+}
+
+static PyObject *FSCatalogInfo_get_sharingFlags(FSCatalogInfoObject *self, void *closure)
+{
+	return Py_BuildValue("l", self->ob_itself.sharingFlags);
+}
+
+static int FSCatalogInfo_set_sharingFlags(FSCatalogInfoObject *self, PyObject *v, void *closure)
+{
+	return PyArg_Parse(v, "l", &self->ob_itself.sharingFlags)-1;
+	return 0;
+}
+
+static PyObject *FSCatalogInfo_get_userPrivileges(FSCatalogInfoObject *self, void *closure)
+{
+	return Py_BuildValue("b", self->ob_itself.userPrivileges);
+}
+
+static int FSCatalogInfo_set_userPrivileges(FSCatalogInfoObject *self, PyObject *v, void *closure)
+{
+	return PyArg_Parse(v, "b", &self->ob_itself.userPrivileges)-1;
+	return 0;
+}
+
+static PyGetSetDef FSCatalogInfo_getsetlist[] = {
+	{"nodeFlags", (getter)FSCatalogInfo_get_nodeFlags, (setter)FSCatalogInfo_set_nodeFlags, NULL},
+	{"volume", (getter)FSCatalogInfo_get_volume, (setter)FSCatalogInfo_set_volume, NULL},
+	{"parentDirID", (getter)FSCatalogInfo_get_parentDirID, (setter)FSCatalogInfo_set_parentDirID, NULL},
+	{"nodeID", (getter)FSCatalogInfo_get_nodeID, (setter)FSCatalogInfo_set_nodeID, NULL},
+	{"createDate", (getter)FSCatalogInfo_get_createDate, (setter)FSCatalogInfo_set_createDate, NULL},
+	{"contentModDate", (getter)FSCatalogInfo_get_contentModDate, (setter)FSCatalogInfo_set_contentModDate, NULL},
+	{"attributeModDate", (getter)FSCatalogInfo_get_attributeModDate, (setter)FSCatalogInfo_set_attributeModDate, NULL},
+	{"accessDate", (getter)FSCatalogInfo_get_accessDate, (setter)FSCatalogInfo_set_accessDate, NULL},
+	{"backupDate", (getter)FSCatalogInfo_get_backupDate, (setter)FSCatalogInfo_set_backupDate, NULL},
+	{"permissions", (getter)FSCatalogInfo_get_permissions, (setter)FSCatalogInfo_set_permissions, NULL},
+	{"valence", (getter)FSCatalogInfo_get_valence, (setter)FSCatalogInfo_set_valence, NULL},
+	{"dataLogicalSize", (getter)FSCatalogInfo_get_dataLogicalSize, (setter)FSCatalogInfo_set_dataLogicalSize, NULL},
+	{"dataPhysicalSize", (getter)FSCatalogInfo_get_dataPhysicalSize, (setter)FSCatalogInfo_set_dataPhysicalSize, NULL},
+	{"rsrcLogicalSize", (getter)FSCatalogInfo_get_rsrcLogicalSize, (setter)FSCatalogInfo_set_rsrcLogicalSize, NULL},
+	{"rsrcPhysicalSize", (getter)FSCatalogInfo_get_rsrcPhysicalSize, (setter)FSCatalogInfo_set_rsrcPhysicalSize, NULL},
+	{"sharingFlags", (getter)FSCatalogInfo_get_sharingFlags, (setter)FSCatalogInfo_set_sharingFlags, NULL},
+	{"userPrivileges", (getter)FSCatalogInfo_get_userPrivileges, (setter)FSCatalogInfo_set_userPrivileges, NULL},
+	{NULL, NULL, NULL, NULL},
+};
+
+
+#define FSCatalogInfo_compare NULL
+
+#define FSCatalogInfo_repr NULL
+
+#define FSCatalogInfo_hash NULL
+static int FSCatalogInfo_tp_init(PyObject *_self, PyObject *_args, PyObject *_kwds)
+{
+	static char *kw[] = {
+	            "nodeFlags",
+	            "volume",
+	            "parentDirID",
+	            "nodeID",
+	            "createDate",
+	            "contentModDate",
+	            "atributeModDate",
+	            "accessDate",
+	            "backupDate",
+	            "valence",
+	            "dataLogicalSize",
+	            "dataPhysicalSize",
+	            "rsrcLogicalSize",
+	            "rsrcPhysicalSize",
+	            "sharingFlags",
+	            "userPrivileges"
+	            , 0};
+
+	if (!PyArg_ParseTupleAndKeywords(_args, _kwds, "|HhllO&O&O&O&O&llllllb", kw, &((FSCatalogInfoObject *)_self)->ob_itself.nodeFlags,
+	            &((FSCatalogInfoObject *)_self)->ob_itself.volume,
+	            &((FSCatalogInfoObject *)_self)->ob_itself.parentDirID,
+	            &((FSCatalogInfoObject *)_self)->ob_itself.nodeID,
+	            UTCDateTime_Convert, &((FSCatalogInfoObject *)_self)->ob_itself.createDate,
+	            UTCDateTime_Convert, &((FSCatalogInfoObject *)_self)->ob_itself.contentModDate,
+	            UTCDateTime_Convert, &((FSCatalogInfoObject *)_self)->ob_itself.attributeModDate,
+	            UTCDateTime_Convert, &((FSCatalogInfoObject *)_self)->ob_itself.accessDate,
+	            UTCDateTime_Convert, &((FSCatalogInfoObject *)_self)->ob_itself.backupDate,
+	            &((FSCatalogInfoObject *)_self)->ob_itself.valence,
+	            &((FSCatalogInfoObject *)_self)->ob_itself.dataLogicalSize,
+	            &((FSCatalogInfoObject *)_self)->ob_itself.dataPhysicalSize,
+	            &((FSCatalogInfoObject *)_self)->ob_itself.rsrcLogicalSize,
+	            &((FSCatalogInfoObject *)_self)->ob_itself.rsrcPhysicalSize,
+	            &((FSCatalogInfoObject *)_self)->ob_itself.sharingFlags,
+	            &((FSCatalogInfoObject *)_self)->ob_itself.userPrivileges))
+	{
+		return -1;
+	}
+	return 0;
+}
+
+#define FSCatalogInfo_tp_alloc PyType_GenericAlloc
+
+static PyObject *FSCatalogInfo_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *self;
+
+	if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	memset(&((FSCatalogInfoObject *)self)->ob_itself, 0, sizeof(FSCatalogInfo));
+	return self;
+}
+
+#define FSCatalogInfo_tp_free PyObject_Del
+
+
+static PyTypeObject FSCatalogInfo_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"Carbon.File.FSCatalogInfo", /*tp_name*/
+	sizeof(FSCatalogInfoObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) FSCatalogInfo_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) FSCatalogInfo_compare, /*tp_compare*/
+	(reprfunc) FSCatalogInfo_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) FSCatalogInfo_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	FSCatalogInfo_methods, /* tp_methods */
+	0, /*tp_members*/
+	FSCatalogInfo_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	FSCatalogInfo_tp_init, /* tp_init */
+	FSCatalogInfo_tp_alloc, /* tp_alloc */
+	FSCatalogInfo_tp_new, /* tp_new */
+	FSCatalogInfo_tp_free, /* tp_free */
+};
+
+/* ----------------- End object type FSCatalogInfo ------------------ */
+
+
+/* ----------------------- Object type FInfo ------------------------ */
+
+static PyTypeObject FInfo_Type;
+
+#define FInfo_Check(x) ((x)->ob_type == &FInfo_Type || PyObject_TypeCheck((x), &FInfo_Type))
+
+typedef struct FInfoObject {
+	PyObject_HEAD
+	FInfo ob_itself;
+} FInfoObject;
+
+static PyObject *FInfo_New(FInfo *itself)
+{
+	FInfoObject *it;
+	if (itself == NULL) return PyMac_Error(resNotFound);
+	it = PyObject_NEW(FInfoObject, &FInfo_Type);
+	if (it == NULL) return NULL;
+	it->ob_itself = *itself;
+	return (PyObject *)it;
+}
+
+static int FInfo_Convert(PyObject *v, FInfo *p_itself)
+{
+	if (!FInfo_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "FInfo required");
+		return 0;
+	}
+	*p_itself = ((FInfoObject *)v)->ob_itself;
+	return 1;
+}
+
+static void FInfo_dealloc(FInfoObject *self)
+{
+	/* Cleanup of self->ob_itself goes here */
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyMethodDef FInfo_methods[] = {
+	{NULL, NULL, 0}
+};
+
+static PyObject *FInfo_get_Type(FInfoObject *self, void *closure)
+{
+	return Py_BuildValue("O&", PyMac_BuildOSType, self->ob_itself.fdType);
+}
+
+static int FInfo_set_Type(FInfoObject *self, PyObject *v, void *closure)
+{
+	return PyArg_Parse(v, "O&", PyMac_GetOSType, &self->ob_itself.fdType)-1;
+	return 0;
+}
+
+static PyObject *FInfo_get_Creator(FInfoObject *self, void *closure)
+{
+	return Py_BuildValue("O&", PyMac_BuildOSType, self->ob_itself.fdCreator);
+}
+
+static int FInfo_set_Creator(FInfoObject *self, PyObject *v, void *closure)
+{
+	return PyArg_Parse(v, "O&", PyMac_GetOSType, &self->ob_itself.fdCreator)-1;
+	return 0;
+}
+
+static PyObject *FInfo_get_Flags(FInfoObject *self, void *closure)
+{
+	return Py_BuildValue("H", self->ob_itself.fdFlags);
+}
+
+static int FInfo_set_Flags(FInfoObject *self, PyObject *v, void *closure)
+{
+	return PyArg_Parse(v, "H", &self->ob_itself.fdFlags)-1;
+	return 0;
+}
+
+static PyObject *FInfo_get_Location(FInfoObject *self, void *closure)
+{
+	return Py_BuildValue("O&", PyMac_BuildPoint, self->ob_itself.fdLocation);
+}
+
+static int FInfo_set_Location(FInfoObject *self, PyObject *v, void *closure)
+{
+	return PyArg_Parse(v, "O&", PyMac_GetPoint, &self->ob_itself.fdLocation)-1;
+	return 0;
+}
+
+static PyObject *FInfo_get_Fldr(FInfoObject *self, void *closure)
+{
+	return Py_BuildValue("h", self->ob_itself.fdFldr);
+}
+
+static int FInfo_set_Fldr(FInfoObject *self, PyObject *v, void *closure)
+{
+	return PyArg_Parse(v, "h", &self->ob_itself.fdFldr)-1;
+	return 0;
+}
+
+static PyGetSetDef FInfo_getsetlist[] = {
+	{"Type", (getter)FInfo_get_Type, (setter)FInfo_set_Type, "4-char file type"},
+	{"Creator", (getter)FInfo_get_Creator, (setter)FInfo_set_Creator, "4-char file creator"},
+	{"Flags", (getter)FInfo_get_Flags, (setter)FInfo_set_Flags, "Finder flag bits"},
+	{"Location", (getter)FInfo_get_Location, (setter)FInfo_set_Location, "(x, y) location of the file's icon in its parent finder window"},
+	{"Fldr", (getter)FInfo_get_Fldr, (setter)FInfo_set_Fldr, "Original folder, for 'put away'"},
+	{NULL, NULL, NULL, NULL},
+};
+
+
+#define FInfo_compare NULL
+
+#define FInfo_repr NULL
+
+#define FInfo_hash NULL
+static int FInfo_tp_init(PyObject *_self, PyObject *_args, PyObject *_kwds)
+{
+	FInfo *itself = NULL;
+	static char *kw[] = {"itself", 0};
+
+	if (PyArg_ParseTupleAndKeywords(_args, _kwds, "|O&", kw, FInfo_Convert, &itself))
+	{
+		if (itself) memcpy(&((FInfoObject *)_self)->ob_itself, itself, sizeof(FInfo));
+		return 0;
+	}
+	return -1;
+}
+
+#define FInfo_tp_alloc PyType_GenericAlloc
+
+static PyObject *FInfo_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *self;
+
+	if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	memset(&((FInfoObject *)self)->ob_itself, 0, sizeof(FInfo));
+	return self;
+}
+
+#define FInfo_tp_free PyObject_Del
+
+
+static PyTypeObject FInfo_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"Carbon.File.FInfo", /*tp_name*/
+	sizeof(FInfoObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) FInfo_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) FInfo_compare, /*tp_compare*/
+	(reprfunc) FInfo_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) FInfo_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	FInfo_methods, /* tp_methods */
+	0, /*tp_members*/
+	FInfo_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	FInfo_tp_init, /* tp_init */
+	FInfo_tp_alloc, /* tp_alloc */
+	FInfo_tp_new, /* tp_new */
+	FInfo_tp_free, /* tp_free */
+};
+
+/* --------------------- End object type FInfo ---------------------- */
+
+
+/* ----------------------- Object type Alias ------------------------ */
+
+static PyTypeObject Alias_Type;
+
+#define Alias_Check(x) ((x)->ob_type == &Alias_Type || PyObject_TypeCheck((x), &Alias_Type))
+
+typedef struct AliasObject {
+	PyObject_HEAD
+	AliasHandle ob_itself;
+	void (*ob_freeit)(AliasHandle ptr);
+} AliasObject;
+
+static PyObject *Alias_New(AliasHandle itself)
+{
+	AliasObject *it;
+	if (itself == NULL) return PyMac_Error(resNotFound);
+	it = PyObject_NEW(AliasObject, &Alias_Type);
+	if (it == NULL) return NULL;
+	it->ob_itself = itself;
+	it->ob_freeit = NULL;
+	return (PyObject *)it;
+}
+
+static int Alias_Convert(PyObject *v, AliasHandle *p_itself)
+{
+	if (!Alias_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "Alias required");
+		return 0;
+	}
+	*p_itself = ((AliasObject *)v)->ob_itself;
+	return 1;
+}
+
+static void Alias_dealloc(AliasObject *self)
+{
+	if (self->ob_freeit && self->ob_itself)
+	{
+		self->ob_freeit(self->ob_itself);
+	}
+	self->ob_itself = NULL;
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *Alias_ResolveAlias(AliasObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	FSSpec fromFile__buf__;
+	FSSpec *fromFile = &fromFile__buf__;
+	FSSpec target;
+	Boolean wasChanged;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      myPyMac_GetOptFSSpecPtr, &fromFile))
+		return NULL;
+	_err = ResolveAlias(fromFile,
+	                    _self->ob_itself,
+	                    &target,
+	                    &wasChanged);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&b",
+	                     FSSpec_New, &target,
+	                     wasChanged);
+	return _res;
+}
+
+static PyObject *Alias_GetAliasInfo(AliasObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	AliasInfoType index;
+	Str63 theString;
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &index))
+		return NULL;
+	_err = GetAliasInfo(_self->ob_itself,
+	                    index,
+	                    theString);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildStr255, theString);
+	return _res;
+}
+
+static PyObject *Alias_ResolveAliasWithMountFlags(AliasObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	FSSpec fromFile__buf__;
+	FSSpec *fromFile = &fromFile__buf__;
+	FSSpec target;
+	Boolean wasChanged;
+	unsigned long mountFlags;
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      myPyMac_GetOptFSSpecPtr, &fromFile,
+	                      &mountFlags))
+		return NULL;
+	_err = ResolveAliasWithMountFlags(fromFile,
+	                                  _self->ob_itself,
+	                                  &target,
+	                                  &wasChanged,
+	                                  mountFlags);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&b",
+	                     FSSpec_New, &target,
+	                     wasChanged);
+	return _res;
+}
+
+static PyObject *Alias_FollowFinderAlias(AliasObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	FSSpec fromFile__buf__;
+	FSSpec *fromFile = &fromFile__buf__;
+	Boolean logon;
+	FSSpec target;
+	Boolean wasChanged;
+	if (!PyArg_ParseTuple(_args, "O&b",
+	                      myPyMac_GetOptFSSpecPtr, &fromFile,
+	                      &logon))
+		return NULL;
+	_err = FollowFinderAlias(fromFile,
+	                         _self->ob_itself,
+	                         logon,
+	                         &target,
+	                         &wasChanged);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&b",
+	                     FSSpec_New, &target,
+	                     wasChanged);
+	return _res;
+}
+
+static PyObject *Alias_FSResolveAliasWithMountFlags(AliasObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	FSRef fromFile__buf__;
+	FSRef *fromFile = &fromFile__buf__;
+	FSRef target;
+	Boolean wasChanged;
+	unsigned long mountFlags;
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      myPyMac_GetOptFSRefPtr, &fromFile,
+	                      &mountFlags))
+		return NULL;
+	_err = FSResolveAliasWithMountFlags(fromFile,
+	                                    _self->ob_itself,
+	                                    &target,
+	                                    &wasChanged,
+	                                    mountFlags);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&b",
+	                     FSRef_New, &target,
+	                     wasChanged);
+	return _res;
+}
+
+static PyObject *Alias_FSResolveAlias(AliasObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	FSRef fromFile__buf__;
+	FSRef *fromFile = &fromFile__buf__;
+	FSRef target;
+	Boolean wasChanged;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      myPyMac_GetOptFSRefPtr, &fromFile))
+		return NULL;
+	_err = FSResolveAlias(fromFile,
+	                      _self->ob_itself,
+	                      &target,
+	                      &wasChanged);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&b",
+	                     FSRef_New, &target,
+	                     wasChanged);
+	return _res;
+}
+
+static PyObject *Alias_FSFollowFinderAlias(AliasObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	FSRef fromFile;
+	Boolean logon;
+	FSRef target;
+	Boolean wasChanged;
+	if (!PyArg_ParseTuple(_args, "b",
+	                      &logon))
+		return NULL;
+	_err = FSFollowFinderAlias(&fromFile,
+	                           _self->ob_itself,
+	                           logon,
+	                           &target,
+	                           &wasChanged);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&O&b",
+	                     FSRef_New, &fromFile,
+	                     FSRef_New, &target,
+	                     wasChanged);
+	return _res;
+}
+
+static PyMethodDef Alias_methods[] = {
+	{"ResolveAlias", (PyCFunction)Alias_ResolveAlias, 1,
+	 PyDoc_STR("(FSSpec fromFile) -> (FSSpec target, Boolean wasChanged)")},
+	{"GetAliasInfo", (PyCFunction)Alias_GetAliasInfo, 1,
+	 PyDoc_STR("(AliasInfoType index) -> (Str63 theString)")},
+	{"ResolveAliasWithMountFlags", (PyCFunction)Alias_ResolveAliasWithMountFlags, 1,
+	 PyDoc_STR("(FSSpec fromFile, unsigned long mountFlags) -> (FSSpec target, Boolean wasChanged)")},
+	{"FollowFinderAlias", (PyCFunction)Alias_FollowFinderAlias, 1,
+	 PyDoc_STR("(FSSpec fromFile, Boolean logon) -> (FSSpec target, Boolean wasChanged)")},
+	{"FSResolveAliasWithMountFlags", (PyCFunction)Alias_FSResolveAliasWithMountFlags, 1,
+	 PyDoc_STR("(FSRef fromFile, unsigned long mountFlags) -> (FSRef target, Boolean wasChanged)")},
+	{"FSResolveAlias", (PyCFunction)Alias_FSResolveAlias, 1,
+	 PyDoc_STR("(FSRef fromFile) -> (FSRef target, Boolean wasChanged)")},
+	{"FSFollowFinderAlias", (PyCFunction)Alias_FSFollowFinderAlias, 1,
+	 PyDoc_STR("(Boolean logon) -> (FSRef fromFile, FSRef target, Boolean wasChanged)")},
+	{NULL, NULL, 0}
+};
+
+static PyObject *Alias_get_data(AliasObject *self, void *closure)
+{
+	int size;
+	                    PyObject *rv;
+
+	                    size = GetHandleSize((Handle)self->ob_itself);
+	                    HLock((Handle)self->ob_itself);
+	                    rv = PyString_FromStringAndSize(*(Handle)self->ob_itself, size);
+	                    HUnlock((Handle)self->ob_itself);
+	                    return rv;
+	            
+}
+
+#define Alias_set_data NULL
+
+static PyGetSetDef Alias_getsetlist[] = {
+	{"data", (getter)Alias_get_data, (setter)Alias_set_data, "Raw data of the alias object"},
+	{NULL, NULL, NULL, NULL},
+};
+
+
+#define Alias_compare NULL
+
+#define Alias_repr NULL
+
+#define Alias_hash NULL
+static int Alias_tp_init(PyObject *_self, PyObject *_args, PyObject *_kwds)
+{
+	AliasHandle itself = NULL;
+	char *rawdata = NULL;
+	int rawdatalen = 0;
+	Handle h;
+	static char *kw[] = {"itself", "rawdata", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(_args, _kwds, "|O&s#", kw, Alias_Convert, &itself, &rawdata, &rawdatalen))
+	return -1;
+	if (itself && rawdata)
+	{
+		PyErr_SetString(PyExc_TypeError, "Only one of itself or rawdata may be specified");
+		return -1;
+	}
+	if (!itself && !rawdata)
+	{
+		PyErr_SetString(PyExc_TypeError, "One of itself or rawdata must be specified");
+		return -1;
+	}
+	if (rawdata)
+	{
+		if ((h = NewHandle(rawdatalen)) == NULL)
+		{
+			PyErr_NoMemory();
+			return -1;
+		}
+		HLock(h);
+		memcpy((char *)*h, rawdata, rawdatalen);
+		HUnlock(h);
+		((AliasObject *)_self)->ob_itself = (AliasHandle)h;
+		return 0;
+	}
+	((AliasObject *)_self)->ob_itself = itself;
+	return 0;
+}
+
+#define Alias_tp_alloc PyType_GenericAlloc
+
+static PyObject *Alias_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *self;
+
+	if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	((AliasObject *)self)->ob_itself = NULL;
+	return self;
+}
+
+#define Alias_tp_free PyObject_Del
+
+
+static PyTypeObject Alias_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"Carbon.File.Alias", /*tp_name*/
+	sizeof(AliasObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) Alias_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) Alias_compare, /*tp_compare*/
+	(reprfunc) Alias_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) Alias_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	Alias_methods, /* tp_methods */
+	0, /*tp_members*/
+	Alias_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	Alias_tp_init, /* tp_init */
+	Alias_tp_alloc, /* tp_alloc */
+	Alias_tp_new, /* tp_new */
+	Alias_tp_free, /* tp_free */
+};
+
+/* --------------------- End object type Alias ---------------------- */
+
+
+/* ----------------------- Object type FSSpec ----------------------- */
+
+static PyTypeObject FSSpec_Type;
+
+#define FSSpec_Check(x) ((x)->ob_type == &FSSpec_Type || PyObject_TypeCheck((x), &FSSpec_Type))
+
+typedef struct FSSpecObject {
+	PyObject_HEAD
+	FSSpec ob_itself;
+} FSSpecObject;
+
+static PyObject *FSSpec_New(FSSpec *itself)
+{
+	FSSpecObject *it;
+	if (itself == NULL) return PyMac_Error(resNotFound);
+	it = PyObject_NEW(FSSpecObject, &FSSpec_Type);
+	if (it == NULL) return NULL;
+	it->ob_itself = *itself;
+	return (PyObject *)it;
+}
+
+static void FSSpec_dealloc(FSSpecObject *self)
+{
+	/* Cleanup of self->ob_itself goes here */
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *FSSpec_FSpOpenDF(FSSpecObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SInt8 permission;
+	short refNum;
+	if (!PyArg_ParseTuple(_args, "b",
+	                      &permission))
+		return NULL;
+	_err = FSpOpenDF(&_self->ob_itself,
+	                 permission,
+	                 &refNum);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("h",
+	                     refNum);
+	return _res;
+}
+
+static PyObject *FSSpec_FSpOpenRF(FSSpecObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SInt8 permission;
+	short refNum;
+	if (!PyArg_ParseTuple(_args, "b",
+	                      &permission))
+		return NULL;
+	_err = FSpOpenRF(&_self->ob_itself,
+	                 permission,
+	                 &refNum);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("h",
+	                     refNum);
+	return _res;
+}
+
+static PyObject *FSSpec_FSpCreate(FSSpecObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	OSType creator;
+	OSType fileType;
+	ScriptCode scriptTag;
+	if (!PyArg_ParseTuple(_args, "O&O&h",
+	                      PyMac_GetOSType, &creator,
+	                      PyMac_GetOSType, &fileType,
+	                      &scriptTag))
+		return NULL;
+	_err = FSpCreate(&_self->ob_itself,
+	                 creator,
+	                 fileType,
+	                 scriptTag);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *FSSpec_FSpDirCreate(FSSpecObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	ScriptCode scriptTag;
+	long createdDirID;
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &scriptTag))
+		return NULL;
+	_err = FSpDirCreate(&_self->ob_itself,
+	                    scriptTag,
+	                    &createdDirID);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     createdDirID);
+	return _res;
+}
+
+static PyObject *FSSpec_FSpDelete(FSSpecObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = FSpDelete(&_self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *FSSpec_FSpGetFInfo(FSSpecObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	FInfo fndrInfo;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = FSpGetFInfo(&_self->ob_itself,
+	                   &fndrInfo);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     FInfo_New, &fndrInfo);
+	return _res;
+}
+
+static PyObject *FSSpec_FSpSetFInfo(FSSpecObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	FInfo fndrInfo;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      FInfo_Convert, &fndrInfo))
+		return NULL;
+	_err = FSpSetFInfo(&_self->ob_itself,
+	                   &fndrInfo);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *FSSpec_FSpSetFLock(FSSpecObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = FSpSetFLock(&_self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *FSSpec_FSpRstFLock(FSSpecObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = FSpRstFLock(&_self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *FSSpec_FSpRename(FSSpecObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Str255 newName;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetStr255, newName))
+		return NULL;
+	_err = FSpRename(&_self->ob_itself,
+	                 newName);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *FSSpec_FSpCatMove(FSSpecObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	FSSpec dest;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      FSSpec_Convert, &dest))
+		return NULL;
+	_err = FSpCatMove(&_self->ob_itself,
+	                  &dest);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *FSSpec_FSpExchangeFiles(FSSpecObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	FSSpec dest;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      FSSpec_Convert, &dest))
+		return NULL;
+	_err = FSpExchangeFiles(&_self->ob_itself,
+	                        &dest);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *FSSpec_FSpMakeFSRef(FSSpecObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	FSRef newRef;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = FSpMakeFSRef(&_self->ob_itself,
+	                    &newRef);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     FSRef_New, &newRef);
+	return _res;
+}
+
+static PyObject *FSSpec_NewAliasMinimal(FSSpecObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	AliasHandle alias;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = NewAliasMinimal(&_self->ob_itself,
+	                       &alias);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     Alias_New, alias);
+	return _res;
+}
+
+static PyObject *FSSpec_IsAliasFile(FSSpecObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Boolean aliasFileFlag;
+	Boolean folderFlag;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = IsAliasFile(&_self->ob_itself,
+	                   &aliasFileFlag,
+	                   &folderFlag);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("bb",
+	                     aliasFileFlag,
+	                     folderFlag);
+	return _res;
+}
+
+static PyObject *FSSpec_as_pathname(FSSpecObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+
+	char strbuf[1024];
+	OSErr err;
+
+	if (!PyArg_ParseTuple(_args, ""))
+	        return NULL;
+	err = _PyMac_GetFullPathname(&_self->ob_itself, strbuf, sizeof(strbuf));
+	if ( err ) {
+	        PyMac_Error(err);
+	        return NULL;
+	}
+	_res = PyString_FromString(strbuf);
+	return _res;
+
+}
+
+static PyObject *FSSpec_as_tuple(FSSpecObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+
+	if (!PyArg_ParseTuple(_args, ""))
+	        return NULL;
+	_res = Py_BuildValue("(iis#)", _self->ob_itself.vRefNum, _self->ob_itself.parID,
+	                                        &_self->ob_itself.name[1], _self->ob_itself.name[0]);
+	return _res;
+
+}
+
+static PyMethodDef FSSpec_methods[] = {
+	{"FSpOpenDF", (PyCFunction)FSSpec_FSpOpenDF, 1,
+	 PyDoc_STR("(SInt8 permission) -> (short refNum)")},
+	{"FSpOpenRF", (PyCFunction)FSSpec_FSpOpenRF, 1,
+	 PyDoc_STR("(SInt8 permission) -> (short refNum)")},
+	{"FSpCreate", (PyCFunction)FSSpec_FSpCreate, 1,
+	 PyDoc_STR("(OSType creator, OSType fileType, ScriptCode scriptTag) -> None")},
+	{"FSpDirCreate", (PyCFunction)FSSpec_FSpDirCreate, 1,
+	 PyDoc_STR("(ScriptCode scriptTag) -> (long createdDirID)")},
+	{"FSpDelete", (PyCFunction)FSSpec_FSpDelete, 1,
+	 PyDoc_STR("() -> None")},
+	{"FSpGetFInfo", (PyCFunction)FSSpec_FSpGetFInfo, 1,
+	 PyDoc_STR("() -> (FInfo fndrInfo)")},
+	{"FSpSetFInfo", (PyCFunction)FSSpec_FSpSetFInfo, 1,
+	 PyDoc_STR("(FInfo fndrInfo) -> None")},
+	{"FSpSetFLock", (PyCFunction)FSSpec_FSpSetFLock, 1,
+	 PyDoc_STR("() -> None")},
+	{"FSpRstFLock", (PyCFunction)FSSpec_FSpRstFLock, 1,
+	 PyDoc_STR("() -> None")},
+	{"FSpRename", (PyCFunction)FSSpec_FSpRename, 1,
+	 PyDoc_STR("(Str255 newName) -> None")},
+	{"FSpCatMove", (PyCFunction)FSSpec_FSpCatMove, 1,
+	 PyDoc_STR("(FSSpec dest) -> None")},
+	{"FSpExchangeFiles", (PyCFunction)FSSpec_FSpExchangeFiles, 1,
+	 PyDoc_STR("(FSSpec dest) -> None")},
+	{"FSpMakeFSRef", (PyCFunction)FSSpec_FSpMakeFSRef, 1,
+	 PyDoc_STR("() -> (FSRef newRef)")},
+	{"NewAliasMinimal", (PyCFunction)FSSpec_NewAliasMinimal, 1,
+	 PyDoc_STR("() -> (AliasHandle alias)")},
+	{"IsAliasFile", (PyCFunction)FSSpec_IsAliasFile, 1,
+	 PyDoc_STR("() -> (Boolean aliasFileFlag, Boolean folderFlag)")},
+	{"as_pathname", (PyCFunction)FSSpec_as_pathname, 1,
+	 PyDoc_STR("() -> string")},
+	{"as_tuple", (PyCFunction)FSSpec_as_tuple, 1,
+	 PyDoc_STR("() -> (vRefNum, dirID, name)")},
+	{NULL, NULL, 0}
+};
+
+static PyObject *FSSpec_get_data(FSSpecObject *self, void *closure)
+{
+	return PyString_FromStringAndSize((char *)&self->ob_itself, sizeof(self->ob_itself));
+}
+
+#define FSSpec_set_data NULL
+
+static PyGetSetDef FSSpec_getsetlist[] = {
+	{"data", (getter)FSSpec_get_data, (setter)FSSpec_set_data, "Raw data of the FSSpec object"},
+	{NULL, NULL, NULL, NULL},
+};
+
+
+#define FSSpec_compare NULL
+
+static PyObject * FSSpec_repr(FSSpecObject *self)
+{
+	char buf[512];
+	PyOS_snprintf(buf, sizeof(buf), "%s((%d, %ld, '%.*s'))",
+	        self->ob_type->tp_name,
+	        self->ob_itself.vRefNum,
+	        self->ob_itself.parID,
+	        self->ob_itself.name[0], self->ob_itself.name+1);
+	return PyString_FromString(buf);
+}
+
+#define FSSpec_hash NULL
+static int FSSpec_tp_init(PyObject *_self, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *v = NULL;
+	char *rawdata = NULL;
+	int rawdatalen = 0;
+	static char *kw[] = {"itself", "rawdata", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(_args, _kwds, "|Os#", kw, &v, &rawdata, &rawdatalen))
+	return -1;
+	if (v && rawdata)
+	{
+		PyErr_SetString(PyExc_TypeError, "Only one of itself or rawdata may be specified");
+		return -1;
+	}
+	if (!v && !rawdata)
+	{
+		PyErr_SetString(PyExc_TypeError, "One of itself or rawdata must be specified");
+		return -1;
+	}
+	if (rawdata)
+	{
+		if (rawdatalen != sizeof(FSSpec))
+		{
+			PyErr_SetString(PyExc_TypeError, "FSSpec rawdata incorrect size");
+			return -1;
+		}
+		memcpy(&((FSSpecObject *)_self)->ob_itself, rawdata, rawdatalen);
+		return 0;
+	}
+	if (PyMac_GetFSSpec(v, &((FSSpecObject *)_self)->ob_itself)) return 0;
+	return -1;
+}
+
+#define FSSpec_tp_alloc PyType_GenericAlloc
+
+static PyObject *FSSpec_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *self;
+
+	if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	memset(&((FSSpecObject *)self)->ob_itself, 0, sizeof(FSSpec));
+	return self;
+}
+
+#define FSSpec_tp_free PyObject_Del
+
+
+static PyTypeObject FSSpec_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"Carbon.File.FSSpec", /*tp_name*/
+	sizeof(FSSpecObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) FSSpec_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) FSSpec_compare, /*tp_compare*/
+	(reprfunc) FSSpec_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) FSSpec_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	FSSpec_methods, /* tp_methods */
+	0, /*tp_members*/
+	FSSpec_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	FSSpec_tp_init, /* tp_init */
+	FSSpec_tp_alloc, /* tp_alloc */
+	FSSpec_tp_new, /* tp_new */
+	FSSpec_tp_free, /* tp_free */
+};
+
+/* --------------------- End object type FSSpec --------------------- */
+
+
+/* ----------------------- Object type FSRef ------------------------ */
+
+static PyTypeObject FSRef_Type;
+
+#define FSRef_Check(x) ((x)->ob_type == &FSRef_Type || PyObject_TypeCheck((x), &FSRef_Type))
+
+typedef struct FSRefObject {
+	PyObject_HEAD
+	FSRef ob_itself;
+} FSRefObject;
+
+static PyObject *FSRef_New(FSRef *itself)
+{
+	FSRefObject *it;
+	if (itself == NULL) return PyMac_Error(resNotFound);
+	it = PyObject_NEW(FSRefObject, &FSRef_Type);
+	if (it == NULL) return NULL;
+	it->ob_itself = *itself;
+	return (PyObject *)it;
+}
+
+static void FSRef_dealloc(FSRefObject *self)
+{
+	/* Cleanup of self->ob_itself goes here */
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *FSRef_FSMakeFSRefUnicode(FSRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	UniChar *nameLength__in__;
+	UniCharCount nameLength__len__;
+	int nameLength__in_len__;
+	TextEncoding textEncodingHint;
+	FSRef newRef;
+	if (!PyArg_ParseTuple(_args, "u#l",
+	                      &nameLength__in__, &nameLength__in_len__,
+	                      &textEncodingHint))
+		return NULL;
+	nameLength__len__ = nameLength__in_len__;
+	_err = FSMakeFSRefUnicode(&_self->ob_itself,
+	                          nameLength__len__, nameLength__in__,
+	                          textEncodingHint,
+	                          &newRef);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     FSRef_New, &newRef);
+	return _res;
+}
+
+static PyObject *FSRef_FSCompareFSRefs(FSRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	FSRef ref2;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      FSRef_Convert, &ref2))
+		return NULL;
+	_err = FSCompareFSRefs(&_self->ob_itself,
+	                       &ref2);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *FSRef_FSCreateFileUnicode(FSRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	UniChar *nameLength__in__;
+	UniCharCount nameLength__len__;
+	int nameLength__in_len__;
+	FSCatalogInfoBitmap whichInfo;
+	FSCatalogInfo catalogInfo;
+	FSRef newRef;
+	FSSpec newSpec;
+	if (!PyArg_ParseTuple(_args, "u#lO&",
+	                      &nameLength__in__, &nameLength__in_len__,
+	                      &whichInfo,
+	                      FSCatalogInfo_Convert, &catalogInfo))
+		return NULL;
+	nameLength__len__ = nameLength__in_len__;
+	_err = FSCreateFileUnicode(&_self->ob_itself,
+	                           nameLength__len__, nameLength__in__,
+	                           whichInfo,
+	                           &catalogInfo,
+	                           &newRef,
+	                           &newSpec);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&O&",
+	                     FSRef_New, &newRef,
+	                     FSSpec_New, &newSpec);
+	return _res;
+}
+
+static PyObject *FSRef_FSCreateDirectoryUnicode(FSRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	UniChar *nameLength__in__;
+	UniCharCount nameLength__len__;
+	int nameLength__in_len__;
+	FSCatalogInfoBitmap whichInfo;
+	FSCatalogInfo catalogInfo;
+	FSRef newRef;
+	FSSpec newSpec;
+	UInt32 newDirID;
+	if (!PyArg_ParseTuple(_args, "u#lO&",
+	                      &nameLength__in__, &nameLength__in_len__,
+	                      &whichInfo,
+	                      FSCatalogInfo_Convert, &catalogInfo))
+		return NULL;
+	nameLength__len__ = nameLength__in_len__;
+	_err = FSCreateDirectoryUnicode(&_self->ob_itself,
+	                                nameLength__len__, nameLength__in__,
+	                                whichInfo,
+	                                &catalogInfo,
+	                                &newRef,
+	                                &newSpec,
+	                                &newDirID);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&O&l",
+	                     FSRef_New, &newRef,
+	                     FSSpec_New, &newSpec,
+	                     newDirID);
+	return _res;
+}
+
+static PyObject *FSRef_FSDeleteObject(FSRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = FSDeleteObject(&_self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *FSRef_FSMoveObject(FSRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	FSRef destDirectory;
+	FSRef newRef;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      FSRef_Convert, &destDirectory))
+		return NULL;
+	_err = FSMoveObject(&_self->ob_itself,
+	                    &destDirectory,
+	                    &newRef);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     FSRef_New, &newRef);
+	return _res;
+}
+
+static PyObject *FSRef_FSExchangeObjects(FSRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	FSRef destRef;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      FSRef_Convert, &destRef))
+		return NULL;
+	_err = FSExchangeObjects(&_self->ob_itself,
+	                         &destRef);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *FSRef_FSRenameUnicode(FSRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	UniChar *nameLength__in__;
+	UniCharCount nameLength__len__;
+	int nameLength__in_len__;
+	TextEncoding textEncodingHint;
+	FSRef newRef;
+	if (!PyArg_ParseTuple(_args, "u#l",
+	                      &nameLength__in__, &nameLength__in_len__,
+	                      &textEncodingHint))
+		return NULL;
+	nameLength__len__ = nameLength__in_len__;
+	_err = FSRenameUnicode(&_self->ob_itself,
+	                       nameLength__len__, nameLength__in__,
+	                       textEncodingHint,
+	                       &newRef);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     FSRef_New, &newRef);
+	return _res;
+}
+
+static PyObject *FSRef_FSGetCatalogInfo(FSRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	FSCatalogInfoBitmap whichInfo;
+	FSCatalogInfo catalogInfo;
+	HFSUniStr255 outName;
+	FSSpec fsSpec;
+	FSRef parentRef;
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &whichInfo))
+		return NULL;
+	_err = FSGetCatalogInfo(&_self->ob_itself,
+	                        whichInfo,
+	                        &catalogInfo,
+	                        &outName,
+	                        &fsSpec,
+	                        &parentRef);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&O&O&O&",
+	                     FSCatalogInfo_New, &catalogInfo,
+	                     PyMac_BuildHFSUniStr255, &outName,
+	                     FSSpec_New, &fsSpec,
+	                     FSRef_New, &parentRef);
+	return _res;
+}
+
+static PyObject *FSRef_FSSetCatalogInfo(FSRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	FSCatalogInfoBitmap whichInfo;
+	FSCatalogInfo catalogInfo;
+	if (!PyArg_ParseTuple(_args, "lO&",
+	                      &whichInfo,
+	                      FSCatalogInfo_Convert, &catalogInfo))
+		return NULL;
+	_err = FSSetCatalogInfo(&_self->ob_itself,
+	                        whichInfo,
+	                        &catalogInfo);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *FSRef_FSCreateFork(FSRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	UniChar *forkNameLength__in__;
+	UniCharCount forkNameLength__len__;
+	int forkNameLength__in_len__;
+	if (!PyArg_ParseTuple(_args, "u#",
+	                      &forkNameLength__in__, &forkNameLength__in_len__))
+		return NULL;
+	forkNameLength__len__ = forkNameLength__in_len__;
+	_err = FSCreateFork(&_self->ob_itself,
+	                    forkNameLength__len__, forkNameLength__in__);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *FSRef_FSDeleteFork(FSRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	UniChar *forkNameLength__in__;
+	UniCharCount forkNameLength__len__;
+	int forkNameLength__in_len__;
+	if (!PyArg_ParseTuple(_args, "u#",
+	                      &forkNameLength__in__, &forkNameLength__in_len__))
+		return NULL;
+	forkNameLength__len__ = forkNameLength__in_len__;
+	_err = FSDeleteFork(&_self->ob_itself,
+	                    forkNameLength__len__, forkNameLength__in__);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *FSRef_FSOpenFork(FSRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	UniChar *forkNameLength__in__;
+	UniCharCount forkNameLength__len__;
+	int forkNameLength__in_len__;
+	SInt8 permissions;
+	SInt16 forkRefNum;
+	if (!PyArg_ParseTuple(_args, "u#b",
+	                      &forkNameLength__in__, &forkNameLength__in_len__,
+	                      &permissions))
+		return NULL;
+	forkNameLength__len__ = forkNameLength__in_len__;
+	_err = FSOpenFork(&_self->ob_itself,
+	                  forkNameLength__len__, forkNameLength__in__,
+	                  permissions,
+	                  &forkRefNum);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("h",
+	                     forkRefNum);
+	return _res;
+}
+
+static PyObject *FSRef_FNNotify(FSRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	FNMessage message;
+	OptionBits flags;
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &message,
+	                      &flags))
+		return NULL;
+	_err = FNNotify(&_self->ob_itself,
+	                message,
+	                flags);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *FSRef_FSNewAliasMinimal(FSRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	AliasHandle inAlias;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = FSNewAliasMinimal(&_self->ob_itself,
+	                         &inAlias);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     Alias_New, inAlias);
+	return _res;
+}
+
+static PyObject *FSRef_FSIsAliasFile(FSRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Boolean aliasFileFlag;
+	Boolean folderFlag;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = FSIsAliasFile(&_self->ob_itself,
+	                     &aliasFileFlag,
+	                     &folderFlag);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("bb",
+	                     aliasFileFlag,
+	                     folderFlag);
+	return _res;
+}
+
+static PyObject *FSRef_FSRefMakePath(FSRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+
+	OSStatus _err;
+#define MAXPATHNAME 1024
+	UInt8 path[MAXPATHNAME];
+	UInt32 maxPathSize = MAXPATHNAME;
+
+	if (!PyArg_ParseTuple(_args, ""))
+	        return NULL;
+	_err = FSRefMakePath(&_self->ob_itself,
+	                                         path,
+	                                         maxPathSize);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("s", path);
+	return _res;
+
+}
+
+static PyObject *FSRef_as_pathname(FSRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+
+	if (!PyArg_ParseTuple(_args, ""))
+	        return NULL;
+	_res = FSRef_FSRefMakePath(_self, _args);
+	return _res;
+
+}
+
+static PyMethodDef FSRef_methods[] = {
+	{"FSMakeFSRefUnicode", (PyCFunction)FSRef_FSMakeFSRefUnicode, 1,
+	 PyDoc_STR("(Buffer nameLength, TextEncoding textEncodingHint) -> (FSRef newRef)")},
+	{"FSCompareFSRefs", (PyCFunction)FSRef_FSCompareFSRefs, 1,
+	 PyDoc_STR("(FSRef ref2) -> None")},
+	{"FSCreateFileUnicode", (PyCFunction)FSRef_FSCreateFileUnicode, 1,
+	 PyDoc_STR("(Buffer nameLength, FSCatalogInfoBitmap whichInfo, FSCatalogInfo catalogInfo) -> (FSRef newRef, FSSpec newSpec)")},
+	{"FSCreateDirectoryUnicode", (PyCFunction)FSRef_FSCreateDirectoryUnicode, 1,
+	 PyDoc_STR("(Buffer nameLength, FSCatalogInfoBitmap whichInfo, FSCatalogInfo catalogInfo) -> (FSRef newRef, FSSpec newSpec, UInt32 newDirID)")},
+	{"FSDeleteObject", (PyCFunction)FSRef_FSDeleteObject, 1,
+	 PyDoc_STR("() -> None")},
+	{"FSMoveObject", (PyCFunction)FSRef_FSMoveObject, 1,
+	 PyDoc_STR("(FSRef destDirectory) -> (FSRef newRef)")},
+	{"FSExchangeObjects", (PyCFunction)FSRef_FSExchangeObjects, 1,
+	 PyDoc_STR("(FSRef destRef) -> None")},
+	{"FSRenameUnicode", (PyCFunction)FSRef_FSRenameUnicode, 1,
+	 PyDoc_STR("(Buffer nameLength, TextEncoding textEncodingHint) -> (FSRef newRef)")},
+	{"FSGetCatalogInfo", (PyCFunction)FSRef_FSGetCatalogInfo, 1,
+	 PyDoc_STR("(FSCatalogInfoBitmap whichInfo) -> (FSCatalogInfo catalogInfo, HFSUniStr255 outName, FSSpec fsSpec, FSRef parentRef)")},
+	{"FSSetCatalogInfo", (PyCFunction)FSRef_FSSetCatalogInfo, 1,
+	 PyDoc_STR("(FSCatalogInfoBitmap whichInfo, FSCatalogInfo catalogInfo) -> None")},
+	{"FSCreateFork", (PyCFunction)FSRef_FSCreateFork, 1,
+	 PyDoc_STR("(Buffer forkNameLength) -> None")},
+	{"FSDeleteFork", (PyCFunction)FSRef_FSDeleteFork, 1,
+	 PyDoc_STR("(Buffer forkNameLength) -> None")},
+	{"FSOpenFork", (PyCFunction)FSRef_FSOpenFork, 1,
+	 PyDoc_STR("(Buffer forkNameLength, SInt8 permissions) -> (SInt16 forkRefNum)")},
+	{"FNNotify", (PyCFunction)FSRef_FNNotify, 1,
+	 PyDoc_STR("(FNMessage message, OptionBits flags) -> None")},
+	{"FSNewAliasMinimal", (PyCFunction)FSRef_FSNewAliasMinimal, 1,
+	 PyDoc_STR("() -> (AliasHandle inAlias)")},
+	{"FSIsAliasFile", (PyCFunction)FSRef_FSIsAliasFile, 1,
+	 PyDoc_STR("() -> (Boolean aliasFileFlag, Boolean folderFlag)")},
+	{"FSRefMakePath", (PyCFunction)FSRef_FSRefMakePath, 1,
+	 PyDoc_STR("() -> string")},
+	{"as_pathname", (PyCFunction)FSRef_as_pathname, 1,
+	 PyDoc_STR("() -> string")},
+	{NULL, NULL, 0}
+};
+
+static PyObject *FSRef_get_data(FSRefObject *self, void *closure)
+{
+	return PyString_FromStringAndSize((char *)&self->ob_itself, sizeof(self->ob_itself));
+}
+
+#define FSRef_set_data NULL
+
+static PyGetSetDef FSRef_getsetlist[] = {
+	{"data", (getter)FSRef_get_data, (setter)FSRef_set_data, "Raw data of the FSRef object"},
+	{NULL, NULL, NULL, NULL},
+};
+
+
+#define FSRef_compare NULL
+
+#define FSRef_repr NULL
+
+#define FSRef_hash NULL
+static int FSRef_tp_init(PyObject *_self, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *v = NULL;
+	char *rawdata = NULL;
+	int rawdatalen = 0;
+	static char *kw[] = {"itself", "rawdata", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(_args, _kwds, "|Os#", kw, &v, &rawdata, &rawdatalen))
+	return -1;
+	if (v && rawdata)
+	{
+		PyErr_SetString(PyExc_TypeError, "Only one of itself or rawdata may be specified");
+		return -1;
+	}
+	if (!v && !rawdata)
+	{
+		PyErr_SetString(PyExc_TypeError, "One of itself or rawdata must be specified");
+		return -1;
+	}
+	if (rawdata)
+	{
+		if (rawdatalen != sizeof(FSRef))
+		{
+			PyErr_SetString(PyExc_TypeError, "FSRef rawdata incorrect size");
+			return -1;
+		}
+		memcpy(&((FSRefObject *)_self)->ob_itself, rawdata, rawdatalen);
+		return 0;
+	}
+	if (PyMac_GetFSRef(v, &((FSRefObject *)_self)->ob_itself)) return 0;
+	return -1;
+}
+
+#define FSRef_tp_alloc PyType_GenericAlloc
+
+static PyObject *FSRef_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *self;
+
+	if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	memset(&((FSRefObject *)self)->ob_itself, 0, sizeof(FSRef));
+	return self;
+}
+
+#define FSRef_tp_free PyObject_Del
+
+
+static PyTypeObject FSRef_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"Carbon.File.FSRef", /*tp_name*/
+	sizeof(FSRefObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) FSRef_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) FSRef_compare, /*tp_compare*/
+	(reprfunc) FSRef_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) FSRef_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	FSRef_methods, /* tp_methods */
+	0, /*tp_members*/
+	FSRef_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	FSRef_tp_init, /* tp_init */
+	FSRef_tp_alloc, /* tp_alloc */
+	FSRef_tp_new, /* tp_new */
+	FSRef_tp_free, /* tp_free */
+};
+
+/* --------------------- End object type FSRef ---------------------- */
+
+
+static PyObject *File_UnmountVol(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Str63 volName;
+	short vRefNum;
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      PyMac_GetStr255, volName,
+	                      &vRefNum))
+		return NULL;
+	_err = UnmountVol(volName,
+	                  vRefNum);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *File_FlushVol(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Str63 volName;
+	short vRefNum;
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      PyMac_GetStr255, volName,
+	                      &vRefNum))
+		return NULL;
+	_err = FlushVol(volName,
+	                vRefNum);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *File_HSetVol(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Str63 volName;
+	short vRefNum;
+	long dirID;
+	if (!PyArg_ParseTuple(_args, "O&hl",
+	                      PyMac_GetStr255, volName,
+	                      &vRefNum,
+	                      &dirID))
+		return NULL;
+	_err = HSetVol(volName,
+	               vRefNum,
+	               dirID);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *File_FSClose(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short refNum;
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &refNum))
+		return NULL;
+	_err = FSClose(refNum);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *File_Allocate(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short refNum;
+	long count;
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &refNum))
+		return NULL;
+	_err = Allocate(refNum,
+	                &count);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     count);
+	return _res;
+}
+
+static PyObject *File_GetEOF(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short refNum;
+	long logEOF;
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &refNum))
+		return NULL;
+	_err = GetEOF(refNum,
+	              &logEOF);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     logEOF);
+	return _res;
+}
+
+static PyObject *File_SetEOF(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short refNum;
+	long logEOF;
+	if (!PyArg_ParseTuple(_args, "hl",
+	                      &refNum,
+	                      &logEOF))
+		return NULL;
+	_err = SetEOF(refNum,
+	              logEOF);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *File_GetFPos(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short refNum;
+	long filePos;
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &refNum))
+		return NULL;
+	_err = GetFPos(refNum,
+	               &filePos);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     filePos);
+	return _res;
+}
+
+static PyObject *File_SetFPos(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short refNum;
+	short posMode;
+	long posOff;
+	if (!PyArg_ParseTuple(_args, "hhl",
+	                      &refNum,
+	                      &posMode,
+	                      &posOff))
+		return NULL;
+	_err = SetFPos(refNum,
+	               posMode,
+	               posOff);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *File_GetVRefNum(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short fileRefNum;
+	short vRefNum;
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &fileRefNum))
+		return NULL;
+	_err = GetVRefNum(fileRefNum,
+	                  &vRefNum);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("h",
+	                     vRefNum);
+	return _res;
+}
+
+static PyObject *File_HGetVol(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	StringPtr volName;
+	short vRefNum;
+	long dirID;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetStr255, &volName))
+		return NULL;
+	_err = HGetVol(volName,
+	               &vRefNum,
+	               &dirID);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("hl",
+	                     vRefNum,
+	                     dirID);
+	return _res;
+}
+
+static PyObject *File_HOpen(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short vRefNum;
+	long dirID;
+	Str255 fileName;
+	SInt8 permission;
+	short refNum;
+	if (!PyArg_ParseTuple(_args, "hlO&b",
+	                      &vRefNum,
+	                      &dirID,
+	                      PyMac_GetStr255, fileName,
+	                      &permission))
+		return NULL;
+	_err = HOpen(vRefNum,
+	             dirID,
+	             fileName,
+	             permission,
+	             &refNum);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("h",
+	                     refNum);
+	return _res;
+}
+
+static PyObject *File_HOpenDF(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short vRefNum;
+	long dirID;
+	Str255 fileName;
+	SInt8 permission;
+	short refNum;
+	if (!PyArg_ParseTuple(_args, "hlO&b",
+	                      &vRefNum,
+	                      &dirID,
+	                      PyMac_GetStr255, fileName,
+	                      &permission))
+		return NULL;
+	_err = HOpenDF(vRefNum,
+	               dirID,
+	               fileName,
+	               permission,
+	               &refNum);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("h",
+	                     refNum);
+	return _res;
+}
+
+static PyObject *File_HOpenRF(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short vRefNum;
+	long dirID;
+	Str255 fileName;
+	SInt8 permission;
+	short refNum;
+	if (!PyArg_ParseTuple(_args, "hlO&b",
+	                      &vRefNum,
+	                      &dirID,
+	                      PyMac_GetStr255, fileName,
+	                      &permission))
+		return NULL;
+	_err = HOpenRF(vRefNum,
+	               dirID,
+	               fileName,
+	               permission,
+	               &refNum);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("h",
+	                     refNum);
+	return _res;
+}
+
+static PyObject *File_AllocContig(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short refNum;
+	long count;
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &refNum))
+		return NULL;
+	_err = AllocContig(refNum,
+	                   &count);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     count);
+	return _res;
+}
+
+static PyObject *File_HCreate(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short vRefNum;
+	long dirID;
+	Str255 fileName;
+	OSType creator;
+	OSType fileType;
+	if (!PyArg_ParseTuple(_args, "hlO&O&O&",
+	                      &vRefNum,
+	                      &dirID,
+	                      PyMac_GetStr255, fileName,
+	                      PyMac_GetOSType, &creator,
+	                      PyMac_GetOSType, &fileType))
+		return NULL;
+	_err = HCreate(vRefNum,
+	               dirID,
+	               fileName,
+	               creator,
+	               fileType);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *File_DirCreate(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short vRefNum;
+	long parentDirID;
+	Str255 directoryName;
+	long createdDirID;
+	if (!PyArg_ParseTuple(_args, "hlO&",
+	                      &vRefNum,
+	                      &parentDirID,
+	                      PyMac_GetStr255, directoryName))
+		return NULL;
+	_err = DirCreate(vRefNum,
+	                 parentDirID,
+	                 directoryName,
+	                 &createdDirID);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     createdDirID);
+	return _res;
+}
+
+static PyObject *File_HDelete(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short vRefNum;
+	long dirID;
+	Str255 fileName;
+	if (!PyArg_ParseTuple(_args, "hlO&",
+	                      &vRefNum,
+	                      &dirID,
+	                      PyMac_GetStr255, fileName))
+		return NULL;
+	_err = HDelete(vRefNum,
+	               dirID,
+	               fileName);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *File_HGetFInfo(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short vRefNum;
+	long dirID;
+	Str255 fileName;
+	FInfo fndrInfo;
+	if (!PyArg_ParseTuple(_args, "hlO&",
+	                      &vRefNum,
+	                      &dirID,
+	                      PyMac_GetStr255, fileName))
+		return NULL;
+	_err = HGetFInfo(vRefNum,
+	                 dirID,
+	                 fileName,
+	                 &fndrInfo);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     FInfo_New, &fndrInfo);
+	return _res;
+}
+
+static PyObject *File_HSetFInfo(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short vRefNum;
+	long dirID;
+	Str255 fileName;
+	FInfo fndrInfo;
+	if (!PyArg_ParseTuple(_args, "hlO&O&",
+	                      &vRefNum,
+	                      &dirID,
+	                      PyMac_GetStr255, fileName,
+	                      FInfo_Convert, &fndrInfo))
+		return NULL;
+	_err = HSetFInfo(vRefNum,
+	                 dirID,
+	                 fileName,
+	                 &fndrInfo);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *File_HSetFLock(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short vRefNum;
+	long dirID;
+	Str255 fileName;
+	if (!PyArg_ParseTuple(_args, "hlO&",
+	                      &vRefNum,
+	                      &dirID,
+	                      PyMac_GetStr255, fileName))
+		return NULL;
+	_err = HSetFLock(vRefNum,
+	                 dirID,
+	                 fileName);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *File_HRstFLock(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short vRefNum;
+	long dirID;
+	Str255 fileName;
+	if (!PyArg_ParseTuple(_args, "hlO&",
+	                      &vRefNum,
+	                      &dirID,
+	                      PyMac_GetStr255, fileName))
+		return NULL;
+	_err = HRstFLock(vRefNum,
+	                 dirID,
+	                 fileName);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *File_HRename(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short vRefNum;
+	long dirID;
+	Str255 oldName;
+	Str255 newName;
+	if (!PyArg_ParseTuple(_args, "hlO&O&",
+	                      &vRefNum,
+	                      &dirID,
+	                      PyMac_GetStr255, oldName,
+	                      PyMac_GetStr255, newName))
+		return NULL;
+	_err = HRename(vRefNum,
+	               dirID,
+	               oldName,
+	               newName);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *File_CatMove(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short vRefNum;
+	long dirID;
+	Str255 oldName;
+	long newDirID;
+	Str255 newName;
+	if (!PyArg_ParseTuple(_args, "hlO&lO&",
+	                      &vRefNum,
+	                      &dirID,
+	                      PyMac_GetStr255, oldName,
+	                      &newDirID,
+	                      PyMac_GetStr255, newName))
+		return NULL;
+	_err = CatMove(vRefNum,
+	               dirID,
+	               oldName,
+	               newDirID,
+	               newName);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *File_FSMakeFSSpec(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short vRefNum;
+	long dirID;
+	Str255 fileName;
+	FSSpec spec;
+	if (!PyArg_ParseTuple(_args, "hlO&",
+	                      &vRefNum,
+	                      &dirID,
+	                      PyMac_GetStr255, fileName))
+		return NULL;
+	_err = FSMakeFSSpec(vRefNum,
+	                    dirID,
+	                    fileName,
+	                    &spec);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     FSSpec_New, &spec);
+	return _res;
+}
+
+static PyObject *File_FSGetForkPosition(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SInt16 forkRefNum;
+	SInt64 position;
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &forkRefNum))
+		return NULL;
+	_err = FSGetForkPosition(forkRefNum,
+	                         &position);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("L",
+	                     position);
+	return _res;
+}
+
+static PyObject *File_FSSetForkPosition(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SInt16 forkRefNum;
+	UInt16 positionMode;
+	SInt64 positionOffset;
+	if (!PyArg_ParseTuple(_args, "hHL",
+	                      &forkRefNum,
+	                      &positionMode,
+	                      &positionOffset))
+		return NULL;
+	_err = FSSetForkPosition(forkRefNum,
+	                         positionMode,
+	                         positionOffset);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *File_FSGetForkSize(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SInt16 forkRefNum;
+	SInt64 forkSize;
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &forkRefNum))
+		return NULL;
+	_err = FSGetForkSize(forkRefNum,
+	                     &forkSize);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("L",
+	                     forkSize);
+	return _res;
+}
+
+static PyObject *File_FSSetForkSize(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SInt16 forkRefNum;
+	UInt16 positionMode;
+	SInt64 positionOffset;
+	if (!PyArg_ParseTuple(_args, "hHL",
+	                      &forkRefNum,
+	                      &positionMode,
+	                      &positionOffset))
+		return NULL;
+	_err = FSSetForkSize(forkRefNum,
+	                     positionMode,
+	                     positionOffset);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *File_FSAllocateFork(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SInt16 forkRefNum;
+	FSAllocationFlags flags;
+	UInt16 positionMode;
+	SInt64 positionOffset;
+	UInt64 requestCount;
+	UInt64 actualCount;
+	if (!PyArg_ParseTuple(_args, "hHHLL",
+	                      &forkRefNum,
+	                      &flags,
+	                      &positionMode,
+	                      &positionOffset,
+	                      &requestCount))
+		return NULL;
+	_err = FSAllocateFork(forkRefNum,
+	                      flags,
+	                      positionMode,
+	                      positionOffset,
+	                      requestCount,
+	                      &actualCount);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("L",
+	                     actualCount);
+	return _res;
+}
+
+static PyObject *File_FSFlushFork(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SInt16 forkRefNum;
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &forkRefNum))
+		return NULL;
+	_err = FSFlushFork(forkRefNum);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *File_FSCloseFork(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SInt16 forkRefNum;
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &forkRefNum))
+		return NULL;
+	_err = FSCloseFork(forkRefNum);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *File_FSGetDataForkName(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	HFSUniStr255 dataForkName;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = FSGetDataForkName(&dataForkName);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildHFSUniStr255, &dataForkName);
+	return _res;
+}
+
+static PyObject *File_FSGetResourceForkName(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	HFSUniStr255 resourceForkName;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = FSGetResourceForkName(&resourceForkName);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildHFSUniStr255, &resourceForkName);
+	return _res;
+}
+
+static PyObject *File_FSPathMakeRef(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt8 * path;
+	FSRef ref;
+	Boolean isDirectory;
+	if (!PyArg_ParseTuple(_args, "s",
+	                      &path))
+		return NULL;
+	_err = FSPathMakeRef(path,
+	                     &ref,
+	                     &isDirectory);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&b",
+	                     FSRef_New, &ref,
+	                     isDirectory);
+	return _res;
+}
+
+static PyObject *File_FNNotifyByPath(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt8 * path;
+	FNMessage message;
+	OptionBits flags;
+	if (!PyArg_ParseTuple(_args, "sll",
+	                      &path,
+	                      &message,
+	                      &flags))
+		return NULL;
+	_err = FNNotifyByPath(path,
+	                      message,
+	                      flags);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *File_FNNotifyAll(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	FNMessage message;
+	OptionBits flags;
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &message,
+	                      &flags))
+		return NULL;
+	_err = FNNotifyAll(message,
+	                   flags);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *File_NewAlias(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	FSSpec fromFile__buf__;
+	FSSpec *fromFile = &fromFile__buf__;
+	FSSpec target;
+	AliasHandle alias;
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      myPyMac_GetOptFSSpecPtr, &fromFile,
+	                      FSSpec_Convert, &target))
+		return NULL;
+	_err = NewAlias(fromFile,
+	                &target,
+	                &alias);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     Alias_New, alias);
+	return _res;
+}
+
+static PyObject *File_NewAliasMinimalFromFullPath(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	char *fullPath__in__;
+	int fullPath__len__;
+	int fullPath__in_len__;
+	Str32 zoneName;
+	Str31 serverName;
+	AliasHandle alias;
+	if (!PyArg_ParseTuple(_args, "s#O&O&",
+	                      &fullPath__in__, &fullPath__in_len__,
+	                      PyMac_GetStr255, zoneName,
+	                      PyMac_GetStr255, serverName))
+		return NULL;
+	fullPath__len__ = fullPath__in_len__;
+	_err = NewAliasMinimalFromFullPath(fullPath__len__, fullPath__in__,
+	                                   zoneName,
+	                                   serverName,
+	                                   &alias);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     Alias_New, alias);
+	return _res;
+}
+
+static PyObject *File_ResolveAliasFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	FSSpec theSpec;
+	Boolean resolveAliasChains;
+	Boolean targetIsFolder;
+	Boolean wasAliased;
+	if (!PyArg_ParseTuple(_args, "O&b",
+	                      FSSpec_Convert, &theSpec,
+	                      &resolveAliasChains))
+		return NULL;
+	_err = ResolveAliasFile(&theSpec,
+	                        resolveAliasChains,
+	                        &targetIsFolder,
+	                        &wasAliased);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&bb",
+	                     FSSpec_New, &theSpec,
+	                     targetIsFolder,
+	                     wasAliased);
+	return _res;
+}
+
+static PyObject *File_ResolveAliasFileWithMountFlags(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	FSSpec theSpec;
+	Boolean resolveAliasChains;
+	Boolean targetIsFolder;
+	Boolean wasAliased;
+	unsigned long mountFlags;
+	if (!PyArg_ParseTuple(_args, "O&bl",
+	                      FSSpec_Convert, &theSpec,
+	                      &resolveAliasChains,
+	                      &mountFlags))
+		return NULL;
+	_err = ResolveAliasFileWithMountFlags(&theSpec,
+	                                      resolveAliasChains,
+	                                      &targetIsFolder,
+	                                      &wasAliased,
+	                                      mountFlags);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&bb",
+	                     FSSpec_New, &theSpec,
+	                     targetIsFolder,
+	                     wasAliased);
+	return _res;
+}
+
+static PyObject *File_UpdateAlias(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	FSSpec fromFile__buf__;
+	FSSpec *fromFile = &fromFile__buf__;
+	FSSpec target;
+	AliasHandle alias;
+	Boolean wasChanged;
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      myPyMac_GetOptFSSpecPtr, &fromFile,
+	                      FSSpec_Convert, &target,
+	                      Alias_Convert, &alias))
+		return NULL;
+	_err = UpdateAlias(fromFile,
+	                   &target,
+	                   alias,
+	                   &wasChanged);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("b",
+	                     wasChanged);
+	return _res;
+}
+
+static PyObject *File_ResolveAliasFileWithMountFlagsNoUI(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	FSSpec theSpec;
+	Boolean resolveAliasChains;
+	Boolean targetIsFolder;
+	Boolean wasAliased;
+	unsigned long mountFlags;
+	if (!PyArg_ParseTuple(_args, "O&bl",
+	                      FSSpec_Convert, &theSpec,
+	                      &resolveAliasChains,
+	                      &mountFlags))
+		return NULL;
+	_err = ResolveAliasFileWithMountFlagsNoUI(&theSpec,
+	                                          resolveAliasChains,
+	                                          &targetIsFolder,
+	                                          &wasAliased,
+	                                          mountFlags);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&bb",
+	                     FSSpec_New, &theSpec,
+	                     targetIsFolder,
+	                     wasAliased);
+	return _res;
+}
+
+static PyObject *File_FSNewAlias(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	FSRef fromFile__buf__;
+	FSRef *fromFile = &fromFile__buf__;
+	FSRef target;
+	AliasHandle inAlias;
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      myPyMac_GetOptFSRefPtr, &fromFile,
+	                      FSRef_Convert, &target))
+		return NULL;
+	_err = FSNewAlias(fromFile,
+	                  &target,
+	                  &inAlias);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     Alias_New, inAlias);
+	return _res;
+}
+
+static PyObject *File_FSResolveAliasFileWithMountFlags(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	FSRef theRef;
+	Boolean resolveAliasChains;
+	Boolean targetIsFolder;
+	Boolean wasAliased;
+	unsigned long mountFlags;
+	if (!PyArg_ParseTuple(_args, "O&bl",
+	                      FSRef_Convert, &theRef,
+	                      &resolveAliasChains,
+	                      &mountFlags))
+		return NULL;
+	_err = FSResolveAliasFileWithMountFlags(&theRef,
+	                                        resolveAliasChains,
+	                                        &targetIsFolder,
+	                                        &wasAliased,
+	                                        mountFlags);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&bb",
+	                     FSRef_New, &theRef,
+	                     targetIsFolder,
+	                     wasAliased);
+	return _res;
+}
+
+static PyObject *File_FSResolveAliasFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	FSRef theRef;
+	Boolean resolveAliasChains;
+	Boolean targetIsFolder;
+	Boolean wasAliased;
+	if (!PyArg_ParseTuple(_args, "O&b",
+	                      FSRef_Convert, &theRef,
+	                      &resolveAliasChains))
+		return NULL;
+	_err = FSResolveAliasFile(&theRef,
+	                          resolveAliasChains,
+	                          &targetIsFolder,
+	                          &wasAliased);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&bb",
+	                     FSRef_New, &theRef,
+	                     targetIsFolder,
+	                     wasAliased);
+	return _res;
+}
+
+static PyObject *File_FSUpdateAlias(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	FSRef fromFile__buf__;
+	FSRef *fromFile = &fromFile__buf__;
+	FSRef target;
+	AliasHandle alias;
+	Boolean wasChanged;
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      myPyMac_GetOptFSRefPtr, &fromFile,
+	                      FSRef_Convert, &target,
+	                      Alias_Convert, &alias))
+		return NULL;
+	_err = FSUpdateAlias(fromFile,
+	                     &target,
+	                     alias,
+	                     &wasChanged);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("b",
+	                     wasChanged);
+	return _res;
+}
+
+static PyObject *File_pathname(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+
+	PyObject *obj;
+
+	if (!PyArg_ParseTuple(_args, "O", &obj))
+	        return NULL;
+	if (PyString_Check(obj)) {
+	        Py_INCREF(obj);
+	        return obj;
+	}
+	if (PyUnicode_Check(obj))
+	        return PyUnicode_AsEncodedString(obj, "utf8", "strict");
+	_res = PyObject_CallMethod(obj, "as_pathname", NULL);
+	return _res;
+
+}
+
+static PyMethodDef File_methods[] = {
+	{"UnmountVol", (PyCFunction)File_UnmountVol, 1,
+	 PyDoc_STR("(Str63 volName, short vRefNum) -> None")},
+	{"FlushVol", (PyCFunction)File_FlushVol, 1,
+	 PyDoc_STR("(Str63 volName, short vRefNum) -> None")},
+	{"HSetVol", (PyCFunction)File_HSetVol, 1,
+	 PyDoc_STR("(Str63 volName, short vRefNum, long dirID) -> None")},
+	{"FSClose", (PyCFunction)File_FSClose, 1,
+	 PyDoc_STR("(short refNum) -> None")},
+	{"Allocate", (PyCFunction)File_Allocate, 1,
+	 PyDoc_STR("(short refNum) -> (long count)")},
+	{"GetEOF", (PyCFunction)File_GetEOF, 1,
+	 PyDoc_STR("(short refNum) -> (long logEOF)")},
+	{"SetEOF", (PyCFunction)File_SetEOF, 1,
+	 PyDoc_STR("(short refNum, long logEOF) -> None")},
+	{"GetFPos", (PyCFunction)File_GetFPos, 1,
+	 PyDoc_STR("(short refNum) -> (long filePos)")},
+	{"SetFPos", (PyCFunction)File_SetFPos, 1,
+	 PyDoc_STR("(short refNum, short posMode, long posOff) -> None")},
+	{"GetVRefNum", (PyCFunction)File_GetVRefNum, 1,
+	 PyDoc_STR("(short fileRefNum) -> (short vRefNum)")},
+	{"HGetVol", (PyCFunction)File_HGetVol, 1,
+	 PyDoc_STR("(StringPtr volName) -> (short vRefNum, long dirID)")},
+	{"HOpen", (PyCFunction)File_HOpen, 1,
+	 PyDoc_STR("(short vRefNum, long dirID, Str255 fileName, SInt8 permission) -> (short refNum)")},
+	{"HOpenDF", (PyCFunction)File_HOpenDF, 1,
+	 PyDoc_STR("(short vRefNum, long dirID, Str255 fileName, SInt8 permission) -> (short refNum)")},
+	{"HOpenRF", (PyCFunction)File_HOpenRF, 1,
+	 PyDoc_STR("(short vRefNum, long dirID, Str255 fileName, SInt8 permission) -> (short refNum)")},
+	{"AllocContig", (PyCFunction)File_AllocContig, 1,
+	 PyDoc_STR("(short refNum) -> (long count)")},
+	{"HCreate", (PyCFunction)File_HCreate, 1,
+	 PyDoc_STR("(short vRefNum, long dirID, Str255 fileName, OSType creator, OSType fileType) -> None")},
+	{"DirCreate", (PyCFunction)File_DirCreate, 1,
+	 PyDoc_STR("(short vRefNum, long parentDirID, Str255 directoryName) -> (long createdDirID)")},
+	{"HDelete", (PyCFunction)File_HDelete, 1,
+	 PyDoc_STR("(short vRefNum, long dirID, Str255 fileName) -> None")},
+	{"HGetFInfo", (PyCFunction)File_HGetFInfo, 1,
+	 PyDoc_STR("(short vRefNum, long dirID, Str255 fileName) -> (FInfo fndrInfo)")},
+	{"HSetFInfo", (PyCFunction)File_HSetFInfo, 1,
+	 PyDoc_STR("(short vRefNum, long dirID, Str255 fileName, FInfo fndrInfo) -> None")},
+	{"HSetFLock", (PyCFunction)File_HSetFLock, 1,
+	 PyDoc_STR("(short vRefNum, long dirID, Str255 fileName) -> None")},
+	{"HRstFLock", (PyCFunction)File_HRstFLock, 1,
+	 PyDoc_STR("(short vRefNum, long dirID, Str255 fileName) -> None")},
+	{"HRename", (PyCFunction)File_HRename, 1,
+	 PyDoc_STR("(short vRefNum, long dirID, Str255 oldName, Str255 newName) -> None")},
+	{"CatMove", (PyCFunction)File_CatMove, 1,
+	 PyDoc_STR("(short vRefNum, long dirID, Str255 oldName, long newDirID, Str255 newName) -> None")},
+	{"FSMakeFSSpec", (PyCFunction)File_FSMakeFSSpec, 1,
+	 PyDoc_STR("(short vRefNum, long dirID, Str255 fileName) -> (FSSpec spec)")},
+	{"FSGetForkPosition", (PyCFunction)File_FSGetForkPosition, 1,
+	 PyDoc_STR("(SInt16 forkRefNum) -> (SInt64 position)")},
+	{"FSSetForkPosition", (PyCFunction)File_FSSetForkPosition, 1,
+	 PyDoc_STR("(SInt16 forkRefNum, UInt16 positionMode, SInt64 positionOffset) -> None")},
+	{"FSGetForkSize", (PyCFunction)File_FSGetForkSize, 1,
+	 PyDoc_STR("(SInt16 forkRefNum) -> (SInt64 forkSize)")},
+	{"FSSetForkSize", (PyCFunction)File_FSSetForkSize, 1,
+	 PyDoc_STR("(SInt16 forkRefNum, UInt16 positionMode, SInt64 positionOffset) -> None")},
+	{"FSAllocateFork", (PyCFunction)File_FSAllocateFork, 1,
+	 PyDoc_STR("(SInt16 forkRefNum, FSAllocationFlags flags, UInt16 positionMode, SInt64 positionOffset, UInt64 requestCount) -> (UInt64 actualCount)")},
+	{"FSFlushFork", (PyCFunction)File_FSFlushFork, 1,
+	 PyDoc_STR("(SInt16 forkRefNum) -> None")},
+	{"FSCloseFork", (PyCFunction)File_FSCloseFork, 1,
+	 PyDoc_STR("(SInt16 forkRefNum) -> None")},
+	{"FSGetDataForkName", (PyCFunction)File_FSGetDataForkName, 1,
+	 PyDoc_STR("() -> (HFSUniStr255 dataForkName)")},
+	{"FSGetResourceForkName", (PyCFunction)File_FSGetResourceForkName, 1,
+	 PyDoc_STR("() -> (HFSUniStr255 resourceForkName)")},
+	{"FSPathMakeRef", (PyCFunction)File_FSPathMakeRef, 1,
+	 PyDoc_STR("(UInt8 * path) -> (FSRef ref, Boolean isDirectory)")},
+	{"FNNotifyByPath", (PyCFunction)File_FNNotifyByPath, 1,
+	 PyDoc_STR("(UInt8 * path, FNMessage message, OptionBits flags) -> None")},
+	{"FNNotifyAll", (PyCFunction)File_FNNotifyAll, 1,
+	 PyDoc_STR("(FNMessage message, OptionBits flags) -> None")},
+	{"NewAlias", (PyCFunction)File_NewAlias, 1,
+	 PyDoc_STR("(FSSpec fromFile, FSSpec target) -> (AliasHandle alias)")},
+	{"NewAliasMinimalFromFullPath", (PyCFunction)File_NewAliasMinimalFromFullPath, 1,
+	 PyDoc_STR("(Buffer fullPath, Str32 zoneName, Str31 serverName) -> (AliasHandle alias)")},
+	{"ResolveAliasFile", (PyCFunction)File_ResolveAliasFile, 1,
+	 PyDoc_STR("(FSSpec theSpec, Boolean resolveAliasChains) -> (FSSpec theSpec, Boolean targetIsFolder, Boolean wasAliased)")},
+	{"ResolveAliasFileWithMountFlags", (PyCFunction)File_ResolveAliasFileWithMountFlags, 1,
+	 PyDoc_STR("(FSSpec theSpec, Boolean resolveAliasChains, unsigned long mountFlags) -> (FSSpec theSpec, Boolean targetIsFolder, Boolean wasAliased)")},
+	{"UpdateAlias", (PyCFunction)File_UpdateAlias, 1,
+	 PyDoc_STR("(FSSpec fromFile, FSSpec target, AliasHandle alias) -> (Boolean wasChanged)")},
+	{"ResolveAliasFileWithMountFlagsNoUI", (PyCFunction)File_ResolveAliasFileWithMountFlagsNoUI, 1,
+	 PyDoc_STR("(FSSpec theSpec, Boolean resolveAliasChains, unsigned long mountFlags) -> (FSSpec theSpec, Boolean targetIsFolder, Boolean wasAliased)")},
+	{"FSNewAlias", (PyCFunction)File_FSNewAlias, 1,
+	 PyDoc_STR("(FSRef fromFile, FSRef target) -> (AliasHandle inAlias)")},
+	{"FSResolveAliasFileWithMountFlags", (PyCFunction)File_FSResolveAliasFileWithMountFlags, 1,
+	 PyDoc_STR("(FSRef theRef, Boolean resolveAliasChains, unsigned long mountFlags) -> (FSRef theRef, Boolean targetIsFolder, Boolean wasAliased)")},
+	{"FSResolveAliasFile", (PyCFunction)File_FSResolveAliasFile, 1,
+	 PyDoc_STR("(FSRef theRef, Boolean resolveAliasChains) -> (FSRef theRef, Boolean targetIsFolder, Boolean wasAliased)")},
+	{"FSUpdateAlias", (PyCFunction)File_FSUpdateAlias, 1,
+	 PyDoc_STR("(FSRef fromFile, FSRef target, AliasHandle alias) -> (Boolean wasChanged)")},
+	{"pathname", (PyCFunction)File_pathname, 1,
+	 PyDoc_STR("(str|unicode|FSSpec|FSref) -> pathname")},
+	{NULL, NULL, 0}
+};
+
+
+
+int
+PyMac_GetFSSpec(PyObject *v, FSSpec *spec)
+{
+        Str255 path;
+        short refnum;
+        long parid;
+        OSErr err;
+        FSRef fsr;
+
+        if (FSSpec_Check(v)) {
+                *spec = ((FSSpecObject *)v)->ob_itself;
+                return 1;
+        }
+
+        if (PyArg_Parse(v, "(hlO&)",
+                                                &refnum, &parid, PyMac_GetStr255, &path)) {
+                err = FSMakeFSSpec(refnum, parid, path, spec);
+                if ( err && err != fnfErr ) {
+                        PyMac_Error(err);
+                        return 0;
+                }
+                return 1;
+        }
+        PyErr_Clear();
+        /* Otherwise we try to go via an FSRef. On OSX we go all the way,
+        ** on OS9 we accept only a real FSRef object
+        */
+        if ( PyMac_GetFSRef(v, &fsr) ) {
+                err = FSGetCatalogInfo(&fsr, kFSCatInfoNone, NULL, NULL, spec, NULL);
+                if (err != noErr) {
+                        PyMac_Error(err);
+                        return 0;
+                }
+                return 1;
+        }
+        return 0;
+}
+
+int
+PyMac_GetFSRef(PyObject *v, FSRef *fsr)
+{
+        OSStatus err;
+        FSSpec fss;
+
+        if (FSRef_Check(v)) {
+                *fsr = ((FSRefObject *)v)->ob_itself;
+                return 1;
+        }
+
+        /* On OSX we now try a pathname */
+        if ( PyString_Check(v) || PyUnicode_Check(v)) {
+                char *path = NULL;
+                if (!PyArg_Parse(v, "et", Py_FileSystemDefaultEncoding, &path))
+                        return 0;
+                if ( (err=FSPathMakeRef(path, fsr, NULL)) )
+                        PyMac_Error(err);
+                PyMem_Free(path);
+                return !err;
+        }
+        /* XXXX Should try unicode here too */
+        /* Otherwise we try to go via an FSSpec */
+        if (FSSpec_Check(v)) {
+                fss = ((FSSpecObject *)v)->ob_itself;
+                if ((err=FSpMakeFSRef(&fss, fsr)) == 0)
+                        return 1;
+                PyMac_Error(err);
+                return 0;
+        }
+        PyErr_SetString(PyExc_TypeError, "FSRef, FSSpec or pathname required");
+        return 0;
+}
+
+extern PyObject *
+PyMac_BuildFSSpec(FSSpec *spec)
+{
+        return FSSpec_New(spec);
+}
+
+extern PyObject *
+PyMac_BuildFSRef(FSRef *spec)
+{
+        return FSRef_New(spec);
+}
+
+
+void init_File(void)
+{
+	PyObject *m;
+	PyObject *d;
+
+
+
+	PyMac_INIT_TOOLBOX_OBJECT_NEW(FSSpec *, PyMac_BuildFSSpec);
+	PyMac_INIT_TOOLBOX_OBJECT_NEW(FSRef *, PyMac_BuildFSRef);
+	PyMac_INIT_TOOLBOX_OBJECT_CONVERT(FSSpec, PyMac_GetFSSpec);
+	PyMac_INIT_TOOLBOX_OBJECT_CONVERT(FSRef, PyMac_GetFSRef);
+
+
+	m = Py_InitModule("_File", File_methods);
+	d = PyModule_GetDict(m);
+	File_Error = PyMac_GetOSErrException();
+	if (File_Error == NULL ||
+	    PyDict_SetItemString(d, "Error", File_Error) != 0)
+		return;
+	FSCatalogInfo_Type.ob_type = &PyType_Type;
+	if (PyType_Ready(&FSCatalogInfo_Type) < 0) return;
+	Py_INCREF(&FSCatalogInfo_Type);
+	PyModule_AddObject(m, "FSCatalogInfo", (PyObject *)&FSCatalogInfo_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&FSCatalogInfo_Type);
+	PyModule_AddObject(m, "FSCatalogInfoType", (PyObject *)&FSCatalogInfo_Type);
+	FInfo_Type.ob_type = &PyType_Type;
+	if (PyType_Ready(&FInfo_Type) < 0) return;
+	Py_INCREF(&FInfo_Type);
+	PyModule_AddObject(m, "FInfo", (PyObject *)&FInfo_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&FInfo_Type);
+	PyModule_AddObject(m, "FInfoType", (PyObject *)&FInfo_Type);
+	Alias_Type.ob_type = &PyType_Type;
+	if (PyType_Ready(&Alias_Type) < 0) return;
+	Py_INCREF(&Alias_Type);
+	PyModule_AddObject(m, "Alias", (PyObject *)&Alias_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&Alias_Type);
+	PyModule_AddObject(m, "AliasType", (PyObject *)&Alias_Type);
+	FSSpec_Type.ob_type = &PyType_Type;
+	if (PyType_Ready(&FSSpec_Type) < 0) return;
+	Py_INCREF(&FSSpec_Type);
+	PyModule_AddObject(m, "FSSpec", (PyObject *)&FSSpec_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&FSSpec_Type);
+	PyModule_AddObject(m, "FSSpecType", (PyObject *)&FSSpec_Type);
+	FSRef_Type.ob_type = &PyType_Type;
+	if (PyType_Ready(&FSRef_Type) < 0) return;
+	Py_INCREF(&FSRef_Type);
+	PyModule_AddObject(m, "FSRef", (PyObject *)&FSRef_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&FSRef_Type);
+	PyModule_AddObject(m, "FSRefType", (PyObject *)&FSRef_Type);
+}
+
+/* ======================== End module _File ======================== */
+

Added: vendor/Python/current/Mac/Modules/file/filescan.py
===================================================================
--- vendor/Python/current/Mac/Modules/file/filescan.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/file/filescan.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,199 @@
+# Scan an Apple header file, generating a Python file of generator calls.
+
+import sys
+import os
+from bgenlocations import TOOLBOXDIR, BGENDIR
+sys.path.append(BGENDIR)
+from scantools import Scanner_OSX
+
+LONG = "Files"
+SHORT = "file"
+
+def main():
+    input = ["Files.h", "Aliases.h", "Finder.h"]
+    output = SHORT + "gen.py"
+    defsoutput = TOOLBOXDIR + LONG + ".py"
+    scanner = MyScanner(input, output, defsoutput)
+    scanner.scan()
+    scanner.close()
+    scanner.gentypetest(SHORT+"typetest.py")
+    print "=== Testing definitions output code ==="
+    execfile(defsoutput, {}, {})
+    print "=== Done scanning and generating, now importing the generated code... ==="
+    exec "import " + SHORT + "support"
+    print "=== Done.  It's up to you to compile it now! ==="
+
+class MyScanner(Scanner_OSX):
+
+    def destination(self, type, name, arglist):
+        classname = "Function"
+        listname = "functions"
+        if arglist:
+            # Funny special case
+            if len(arglist) > 2:
+                t, n, m = arglist[1]
+                if t == "AliasHandle" and m == "InMode":
+                    classname = "Arg2MethodGenerator"
+                    listname = "alias_methods"
+                    return classname, listname
+            # Normal cases
+            t, n, m = arglist[0]
+            if t == "AliasHandle" and m == "InMode":
+                classname = "Method"
+                listname = "alias_methods"
+            if t == "FSSpec_ptr" and m == "InMode":
+                classname = "Method"
+                listname = "fsspec_methods"
+            if t == "FSRef_ptr" and m == "InMode":
+                classname = "Method"
+                listname = "fsref_methods"
+        return classname, listname
+
+    def makeblacklistnames(self):
+        return [
+                # Constants with incompatible definitions
+                "kioACAccessOwnerMask",
+                "kFSCatInfoReserved",
+                "kFSIterateReserved",
+                "kSystemFolderType",
+
+                "FSRefMakePath", # Do this manually
+#                       "ResolveAlias", # Do this manually
+#                       "ResolveAliasWithMountFlags", # Do this manually
+#                       "FollowFinderAlias", # Do this manually
+
+                "FSRead", # Couldn't be bothered
+                "FSWrite", # ditto
+                "FSReadFork", # ditto
+                "FSWriteFork", # ditto
+
+                # Old routines:
+                "GetWDInfo",
+                "OpenWD",
+                "CloseWD",
+                "FInitQueue",
+                "rstflock",
+                "setflock",
+                "setfinfo",
+                "fsrename",
+                "fsdelete",
+                "create",
+                "flushvol",
+                "eject",
+                "umountvol",
+                "setvol",
+                "getvol",
+                "getfinfo",
+                "getvinfo",
+                "fsopen",
+                "RstFLock",
+                "SetFLock",
+                "SetFInfo",
+                "Rename",
+                "OpenRF",
+                "FSDelete",
+                "Create",
+                "GetVol",
+                "GetFInfo",
+                "GetVInfo",
+                "FSOpen",
+                "Eject",
+                "SetVol",
+                "openrf",
+                "unmountvol",
+                "OpenDF",
+
+                ]
+
+    def makeblacklisttypes(self):
+        return [
+                "CInfoPBPtr", # Old stuff
+                "CMovePBPtr", # Old stuff
+                "ParmBlkPtr", # Old stuff
+                "HParmBlkPtr", # Old stuff
+                "DTPBPtr", # Old stuff
+                "FCBPBPtr", # Old stuff
+                "QHdrPtr", # Old stuff
+                "CSParamPtr", # Old stuff
+                "FSCatalogBulkParam", # old stuff
+                "FSForkCBInfoParam", # old stuff
+                "FSForkIOParam", # old stuff
+                "FSRefParam",  # old stuff
+                "FSVolumeInfoParam", # old stuff
+                "WDPBPtr", # old stuff
+                "XCInfoPBPtr", # old stuff
+                "XVolumeParamPtr", # old stuff
+
+
+                "CatPositionRec", # State variable, not too difficult
+                "FSIterator", # Should become an object
+                "FSForkInfo", # Lots of fields, difficult struct
+                "FSSearchParams", # Also catsearch stuff
+                "FSVolumeInfo", # big struct
+                "FSVolumeInfo_ptr", # big struct
+
+                "IOCompletionProcPtr", # proc pointer
+                "IOCompletionUPP", # Proc pointer
+                "AliasFilterProcPtr",
+                "AliasFilterUPP",
+                "FNSubscriptionUPP",
+
+                "FNSubscriptionRef", # Lazy, for now.
+                ]
+
+    def makerepairinstructions(self):
+        return [
+                # Various ways to give pathnames
+                ([('char_ptr', '*', 'InMode')],
+                 [('stringptr', '*', 'InMode')]
+                ),
+
+                # Unicode filenames passed as length, buffer
+                ([('UniCharCount', '*', 'InMode'),
+                  ('UniChar_ptr', '*', 'InMode')],
+                 [('UnicodeReverseInBuffer', '*', 'InMode')]
+                ),
+                # Wrong guess
+                ([('Str63', 'theString', 'InMode')],
+                 [('Str63', 'theString', 'OutMode')]),
+
+                # Yet another way to give a pathname:-)
+                ([('short', 'fullPathLength', 'InMode'),
+                  ('void_ptr', 'fullPath', 'InMode')],
+                 [('FullPathName', 'fullPath', 'InMode')]),
+
+                # Various ResolveAliasFileXXXX functions
+                ([('FSSpec', 'theSpec', 'OutMode')],
+                 [('FSSpec_ptr', 'theSpec', 'InOutMode')]),
+
+                ([('FSRef', 'theRef', 'OutMode')],
+                 [('FSRef_ptr', 'theRef', 'InOutMode')]),
+
+                # The optional FSSpec to all ResolveAlias and NewAlias methods
+                ([('FSSpec_ptr', 'fromFile', 'InMode')],
+         [('OptFSSpecPtr', 'fromFile', 'InMode')]),
+
+                ([('FSRef_ptr', 'fromFile', 'InMode')],
+         [('OptFSRefPtr', 'fromFile', 'InMode')]),
+
+##              # FSCatalogInfo input handling
+##                      ([('FSCatalogInfoBitmap', 'whichInfo', 'InMode'),
+##                ('FSCatalogInfo_ptr', 'catalogInfo', 'InMode')],
+##               [('FSCatalogInfoAndBitmap_in', 'catalogInfo', 'InMode')]),
+##
+##              # FSCatalogInfo output handling
+##                      ([('FSCatalogInfoBitmap', 'whichInfo', 'InMode'),
+##                ('FSCatalogInfo', 'catalogInfo', 'OutMode')],
+##               [('FSCatalogInfoAndBitmap_out', 'catalogInfo', 'InOutMode')]),
+##
+
+        ]
+
+
+    def writeinitialdefs(self):
+        self.defsfile.write("def FOUR_CHAR_CODE(x): return x\n")
+        self.defsfile.write("true = True\n")
+        self.defsfile.write("false = False\n")
+
+if __name__ == "__main__":
+    main()

Added: vendor/Python/current/Mac/Modules/file/filesupport.py
===================================================================
--- vendor/Python/current/Mac/Modules/file/filesupport.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/file/filesupport.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,897 @@
+# This script generates a Python interface for an Apple Macintosh Manager.
+# It uses the "bgen" package to generate C code.
+# The function specifications are generated by scanning the mamager's header file,
+# using the "scantools" package (customized for this particular manager).
+#
+# XXXX TO DO:
+# - Implement correct missing FSSpec handling for Alias methods
+# - Implement FInfo
+
+import string
+
+# Declarations that change for each manager
+#MACHEADERFILE = 'Files.h'              # The Apple header file
+MODNAME = '_File'                               # The name of the module
+LONGMODNAME = 'Carbon.File'             # The "normal" external name of the module
+
+# The following is *usually* unchanged but may still require tuning
+MODPREFIX = 'File'                      # The prefix for module-wide routines
+INPUTFILE = string.lower(MODPREFIX) + 'gen.py' # The file generated by the scanner
+OUTPUTFILE = MODNAME + "module.c"       # The file generated by this program
+
+from macsupport import *
+
+# Various integers:
+SInt64 = Type("SInt64", "L")
+UInt64 = Type("UInt64", "L")
+FNMessage = Type("FNMessage", "l")
+FSAllocationFlags = Type("FSAllocationFlags", "H")
+FSCatalogInfoBitmap = Type("FSCatalogInfoBitmap", "l")
+FSIteratorFlags = Type("FSIteratorFlags", "l")
+FSVolumeRefNum = Type("FSVolumeRefNum", "h")
+AliasInfoType = Type("AliasInfoType", "h")
+
+# Various types of strings:
+#class UniCharCountBuffer(InputOnlyType):
+#       pass
+class VarReverseInputBufferType(ReverseInputBufferMixin, VarInputBufferType):
+    pass
+FullPathName = VarReverseInputBufferType()
+ConstStr31Param = OpaqueArrayType("Str31", "PyMac_BuildStr255", "PyMac_GetStr255")
+ConstStr32Param = OpaqueArrayType("Str32", "PyMac_BuildStr255", "PyMac_GetStr255")
+ConstStr63Param = OpaqueArrayType("Str63", "PyMac_BuildStr255", "PyMac_GetStr255")
+Str63 = OpaqueArrayType("Str63", "PyMac_BuildStr255", "PyMac_GetStr255")
+
+HFSUniStr255 = OpaqueType("HFSUniStr255", "PyMac_BuildHFSUniStr255", "PyMac_GetHFSUniStr255")
+UInt8_ptr = InputOnlyType("UInt8 *", "s")
+
+# Other types:
+class OptionalFSxxxType(OpaqueByValueType):
+    def declare(self, name):
+        Output("%s %s__buf__;", self.typeName, name)
+        Output("%s *%s = &%s__buf__;", self.typeName, name, name)
+
+class FSCatalogInfoAndBitmapType(InputOnlyType):
+
+    def __init__(self):
+        InputOnlyType.__init__(self, "BUG", "BUG")
+
+    def declare(self, name):
+        Output("PyObject *%s__object = NULL;", name)
+        Output("FSCatalogInfoBitmap %s__bitmap = 0;", name)
+        Output("FSCatalogInfo %s;", name)
+
+    def getargsFormat(self):
+        return "lO"
+
+    def getargsArgs(self, name):
+        return "%s__bitmap, %s__object"%(name, name)
+
+    def getargsCheck(self, name):
+        Output("if (!convert_FSCatalogInfo(%s__object, %s__bitmap, &%s)) return NULL;", name, name, name)
+
+    def passInput(self, name):
+        return "%s__bitmap, &%s"% (name, name)
+
+    def passOutput(self, name):
+        return "%s__bitmap, &%s"% (name, name)
+
+    def mkvalueFormat(self):
+        return "O"
+
+    def mkvalueArgs(self, name):
+        return "%s__object" % (name)
+
+    def xxxxmkvalueCheck(self, name):
+        Output("if ((%s__object = new_FSCatalogInfo(%s__bitmap, &%s)) == NULL) return NULL;", name, name)
+
+class FSCatalogInfoAndBitmap_inType(FSCatalogInfoAndBitmapType, InputOnlyMixIn):
+
+    def xxxxmkvalueCheck(self, name):
+        pass
+
+class FSCatalogInfoAndBitmap_outType(FSCatalogInfoAndBitmapType):
+
+    def getargsFormat(self):
+        return "l"
+
+    def getargsArgs(self, name):
+        return "%s__bitmap" % name
+
+    def getargsCheck(self, name):
+        pass
+
+FInfo = OpaqueType("FInfo", "FInfo")
+FInfo_ptr = OpaqueType("FInfo", "FInfo")
+AliasHandle = OpaqueByValueType("AliasHandle", "Alias")
+FSSpec = OpaqueType("FSSpec", "FSSpec")
+FSSpec_ptr = OpaqueType("FSSpec", "FSSpec")
+OptFSSpecPtr = OptionalFSxxxType("FSSpec", "BUG", "myPyMac_GetOptFSSpecPtr")
+FSRef = OpaqueType("FSRef", "FSRef")
+FSRef_ptr = OpaqueType("FSRef", "FSRef")
+OptFSRefPtr = OptionalFSxxxType("FSRef", "BUG", "myPyMac_GetOptFSRefPtr")
+FSCatalogInfo = OpaqueType("FSCatalogInfo", "FSCatalogInfo")
+FSCatalogInfo_ptr = OpaqueType("FSCatalogInfo", "FSCatalogInfo")
+
+# To be done:
+#CatPositionRec
+#FSCatalogInfo
+#FSForkInfo
+#FSIterator
+#FSVolumeInfo
+#FSSpecArrayPtr
+
+includestuff = includestuff + """
+#include <Carbon/Carbon.h>
+
+#ifdef USE_TOOLBOX_OBJECT_GLUE
+extern int _PyMac_GetFSSpec(PyObject *v, FSSpec *spec);
+extern int _PyMac_GetFSRef(PyObject *v, FSRef *fsr);
+extern PyObject *_PyMac_BuildFSSpec(FSSpec *spec);
+extern PyObject *_PyMac_BuildFSRef(FSRef *spec);
+
+#define PyMac_GetFSSpec _PyMac_GetFSSpec
+#define PyMac_GetFSRef _PyMac_GetFSRef
+#define PyMac_BuildFSSpec _PyMac_BuildFSSpec
+#define PyMac_BuildFSRef _PyMac_BuildFSRef
+#else
+extern int PyMac_GetFSSpec(PyObject *v, FSSpec *spec);
+extern int PyMac_GetFSRef(PyObject *v, FSRef *fsr);
+extern PyObject *PyMac_BuildFSSpec(FSSpec *spec);
+extern PyObject *PyMac_BuildFSRef(FSRef *spec);
+#endif
+
+/* Forward declarations */
+static PyObject *FInfo_New(FInfo *itself);
+static PyObject *FSRef_New(FSRef *itself);
+static PyObject *FSSpec_New(FSSpec *itself);
+static PyObject *Alias_New(AliasHandle itself);
+static int FInfo_Convert(PyObject *v, FInfo *p_itself);
+#define FSRef_Convert PyMac_GetFSRef
+#define FSSpec_Convert PyMac_GetFSSpec
+static int Alias_Convert(PyObject *v, AliasHandle *p_itself);
+
+/*
+** UTCDateTime records
+*/
+static int
+UTCDateTime_Convert(PyObject *v, UTCDateTime *ptr)
+{
+        return PyArg_Parse(v, "(HlH)", &ptr->highSeconds, &ptr->lowSeconds, &ptr->fraction);
+}
+
+static PyObject *
+UTCDateTime_New(UTCDateTime *ptr)
+{
+        return Py_BuildValue("(HlH)", ptr->highSeconds, ptr->lowSeconds, ptr->fraction);
+}
+
+/*
+** Optional fsspec and fsref pointers. None will pass NULL
+*/
+static int
+myPyMac_GetOptFSSpecPtr(PyObject *v, FSSpec **spec)
+{
+        if (v == Py_None) {
+                *spec = NULL;
+                return 1;
+        }
+        return PyMac_GetFSSpec(v, *spec);
+}
+
+static int
+myPyMac_GetOptFSRefPtr(PyObject *v, FSRef **ref)
+{
+        if (v == Py_None) {
+                *ref = NULL;
+                return 1;
+        }
+        return PyMac_GetFSRef(v, *ref);
+}
+
+/*
+** Parse/generate objsect
+*/
+static PyObject *
+PyMac_BuildHFSUniStr255(HFSUniStr255 *itself)
+{
+
+        return Py_BuildValue("u#", itself->unicode, itself->length);
+}
+
+/*
+** Get pathname for a given FSSpec
+*/
+static OSErr
+_PyMac_GetFullPathname(FSSpec *fss, char *path, int len)
+{
+        FSRef fsr;
+        OSErr err;
+
+        *path = '\0';
+        err = FSpMakeFSRef(fss, &fsr);
+        if (err == fnfErr) {
+                /* FSSpecs can point to non-existing files, fsrefs can't. */
+                FSSpec fss2;
+                int tocopy;
+
+                err = FSMakeFSSpec(fss->vRefNum, fss->parID, "", &fss2);
+                if (err)
+                        return err;
+                err = FSpMakeFSRef(&fss2, &fsr);
+                if (err)
+                        return err;
+                err = (OSErr)FSRefMakePath(&fsr, path, len-1);
+                if (err)
+                        return err;
+                /* This part is not 100% safe: we append the filename part, but
+                ** I'm not sure that we don't run afoul of the various 8bit
+                ** encodings here. Will have to look this up at some point...
+                */
+                strcat(path, "/");
+                tocopy = fss->name[0];
+                if ((strlen(path) + tocopy) >= len)
+                        tocopy = len - strlen(path) - 1;
+                if (tocopy > 0)
+                        strncat(path, fss->name+1, tocopy);
+        }
+        else {
+                if (err)
+                        return err;
+                err = (OSErr)FSRefMakePath(&fsr, path, len);
+                if (err)
+                        return err;
+        }
+        return 0;
+}
+
+"""
+
+finalstuff = finalstuff + """
+int
+PyMac_GetFSSpec(PyObject *v, FSSpec *spec)
+{
+        Str255 path;
+        short refnum;
+        long parid;
+        OSErr err;
+        FSRef fsr;
+
+        if (FSSpec_Check(v)) {
+                *spec = ((FSSpecObject *)v)->ob_itself;
+                return 1;
+        }
+
+        if (PyArg_Parse(v, "(hlO&)",
+                                                &refnum, &parid, PyMac_GetStr255, &path)) {
+                err = FSMakeFSSpec(refnum, parid, path, spec);
+                if ( err && err != fnfErr ) {
+                        PyMac_Error(err);
+                        return 0;
+                }
+                return 1;
+        }
+        PyErr_Clear();
+        /* Otherwise we try to go via an FSRef. On OSX we go all the way,
+        ** on OS9 we accept only a real FSRef object
+        */
+        if ( PyMac_GetFSRef(v, &fsr) ) {
+                err = FSGetCatalogInfo(&fsr, kFSCatInfoNone, NULL, NULL, spec, NULL);
+                if (err != noErr) {
+                        PyMac_Error(err);
+                        return 0;
+                }
+                return 1;
+        }
+        return 0;
+}
+
+int
+PyMac_GetFSRef(PyObject *v, FSRef *fsr)
+{
+        OSStatus err;
+        FSSpec fss;
+
+        if (FSRef_Check(v)) {
+                *fsr = ((FSRefObject *)v)->ob_itself;
+                return 1;
+        }
+
+        /* On OSX we now try a pathname */
+        if ( PyString_Check(v) || PyUnicode_Check(v)) {
+                char *path = NULL;
+                if (!PyArg_Parse(v, "et", Py_FileSystemDefaultEncoding, &path))
+                        return 0;
+                if ( (err=FSPathMakeRef(path, fsr, NULL)) )
+                        PyMac_Error(err);
+                PyMem_Free(path);
+                return !err;
+        }
+        /* XXXX Should try unicode here too */
+        /* Otherwise we try to go via an FSSpec */
+        if (FSSpec_Check(v)) {
+                fss = ((FSSpecObject *)v)->ob_itself;
+                if ((err=FSpMakeFSRef(&fss, fsr)) == 0)
+                        return 1;
+                PyMac_Error(err);
+                return 0;
+        }
+        PyErr_SetString(PyExc_TypeError, "FSRef, FSSpec or pathname required");
+        return 0;
+}
+
+extern PyObject *
+PyMac_BuildFSSpec(FSSpec *spec)
+{
+        return FSSpec_New(spec);
+}
+
+extern PyObject *
+PyMac_BuildFSRef(FSRef *spec)
+{
+        return FSRef_New(spec);
+}
+"""
+
+initstuff = initstuff + """
+PyMac_INIT_TOOLBOX_OBJECT_NEW(FSSpec *, PyMac_BuildFSSpec);
+PyMac_INIT_TOOLBOX_OBJECT_NEW(FSRef *, PyMac_BuildFSRef);
+PyMac_INIT_TOOLBOX_OBJECT_CONVERT(FSSpec, PyMac_GetFSSpec);
+PyMac_INIT_TOOLBOX_OBJECT_CONVERT(FSRef, PyMac_GetFSRef);
+"""
+
+execfile(string.lower(MODPREFIX) + 'typetest.py')
+
+# Our object types:
+class FSCatalogInfoDefinition(PEP253Mixin, ObjectDefinition):
+    getsetlist = [
+            ("nodeFlags",
+             "return Py_BuildValue(\"H\", self->ob_itself.nodeFlags);",
+             "return PyArg_Parse(v, \"H\", &self->ob_itself.nodeFlags)-1;",
+             None
+            ),
+            ("volume",
+             "return Py_BuildValue(\"h\", self->ob_itself.volume);",
+             "return PyArg_Parse(v, \"h\", &self->ob_itself.volume)-1;",
+             None
+            ),
+            ("parentDirID",
+             "return Py_BuildValue(\"l\", self->ob_itself.parentDirID);",
+             "return PyArg_Parse(v, \"l\", &self->ob_itself.parentDirID)-1;",
+             None
+            ),
+            ("nodeID",
+             "return Py_BuildValue(\"l\", self->ob_itself.nodeID);",
+             "return PyArg_Parse(v, \"l\", &self->ob_itself.nodeID)-1;",
+             None
+            ),
+            ("createDate",
+             "return Py_BuildValue(\"O&\", UTCDateTime_New, &self->ob_itself.createDate);",
+             "return PyArg_Parse(v, \"O&\", UTCDateTime_Convert, &self->ob_itself.createDate)-1;",
+             None
+            ),
+            ("contentModDate",
+             "return Py_BuildValue(\"O&\", UTCDateTime_New, &self->ob_itself.contentModDate);",
+             "return PyArg_Parse(v, \"O&\", UTCDateTime_Convert, &self->ob_itself.contentModDate)-1;",
+             None
+            ),
+            ("attributeModDate",
+             "return Py_BuildValue(\"O&\", UTCDateTime_New, &self->ob_itself.attributeModDate);",
+             "return PyArg_Parse(v, \"O&\", UTCDateTime_Convert, &self->ob_itself.attributeModDate)-1;",
+             None
+            ),
+            ("accessDate",
+             "return Py_BuildValue(\"O&\", UTCDateTime_New, &self->ob_itself.accessDate);",
+             "return PyArg_Parse(v, \"O&\", UTCDateTime_Convert, &self->ob_itself.accessDate)-1;",
+             None
+            ),
+            ("backupDate",
+             "return Py_BuildValue(\"O&\", UTCDateTime_New, &self->ob_itself.backupDate);",
+             "return PyArg_Parse(v, \"O&\", UTCDateTime_Convert, &self->ob_itself.backupDate)-1;",
+             None
+            ),
+            ("permissions",
+             "return Py_BuildValue(\"(llll)\", self->ob_itself.permissions[0], self->ob_itself.permissions[1], self->ob_itself.permissions[2], self->ob_itself.permissions[3]);",
+             "return PyArg_Parse(v, \"(llll)\", &self->ob_itself.permissions[0], &self->ob_itself.permissions[1], &self->ob_itself.permissions[2], &self->ob_itself.permissions[3])-1;",
+             None
+            ),
+            # XXXX FinderInfo TBD
+            # XXXX FinderXInfo TBD
+            ("valence",
+             "return Py_BuildValue(\"l\", self->ob_itself.valence);",
+             "return PyArg_Parse(v, \"l\", &self->ob_itself.valence)-1;",
+             None
+            ),
+            ("dataLogicalSize",
+             "return Py_BuildValue(\"l\", self->ob_itself.dataLogicalSize);",
+             "return PyArg_Parse(v, \"l\", &self->ob_itself.dataLogicalSize)-1;",
+             None
+            ),
+            ("dataPhysicalSize",
+             "return Py_BuildValue(\"l\", self->ob_itself.dataPhysicalSize);",
+             "return PyArg_Parse(v, \"l\", &self->ob_itself.dataPhysicalSize)-1;",
+             None
+            ),
+            ("rsrcLogicalSize",
+             "return Py_BuildValue(\"l\", self->ob_itself.rsrcLogicalSize);",
+             "return PyArg_Parse(v, \"l\", &self->ob_itself.rsrcLogicalSize)-1;",
+             None
+            ),
+            ("rsrcPhysicalSize",
+             "return Py_BuildValue(\"l\", self->ob_itself.rsrcPhysicalSize);",
+             "return PyArg_Parse(v, \"l\", &self->ob_itself.rsrcPhysicalSize)-1;",
+             None
+            ),
+            ("sharingFlags",
+             "return Py_BuildValue(\"l\", self->ob_itself.sharingFlags);",
+             "return PyArg_Parse(v, \"l\", &self->ob_itself.sharingFlags)-1;",
+             None
+            ),
+            ("userPrivileges",
+             "return Py_BuildValue(\"b\", self->ob_itself.userPrivileges);",
+             "return PyArg_Parse(v, \"b\", &self->ob_itself.userPrivileges)-1;",
+             None
+            ),
+    ]
+    # The same info, but in a different form
+    INITFORMAT = "HhllO&O&O&O&O&llllllb"
+    INITARGS = """&((FSCatalogInfoObject *)_self)->ob_itself.nodeFlags,
+            &((FSCatalogInfoObject *)_self)->ob_itself.volume,
+            &((FSCatalogInfoObject *)_self)->ob_itself.parentDirID,
+            &((FSCatalogInfoObject *)_self)->ob_itself.nodeID,
+            UTCDateTime_Convert, &((FSCatalogInfoObject *)_self)->ob_itself.createDate,
+            UTCDateTime_Convert, &((FSCatalogInfoObject *)_self)->ob_itself.contentModDate,
+            UTCDateTime_Convert, &((FSCatalogInfoObject *)_self)->ob_itself.attributeModDate,
+            UTCDateTime_Convert, &((FSCatalogInfoObject *)_self)->ob_itself.accessDate,
+            UTCDateTime_Convert, &((FSCatalogInfoObject *)_self)->ob_itself.backupDate,
+            &((FSCatalogInfoObject *)_self)->ob_itself.valence,
+            &((FSCatalogInfoObject *)_self)->ob_itself.dataLogicalSize,
+            &((FSCatalogInfoObject *)_self)->ob_itself.dataPhysicalSize,
+            &((FSCatalogInfoObject *)_self)->ob_itself.rsrcLogicalSize,
+            &((FSCatalogInfoObject *)_self)->ob_itself.rsrcPhysicalSize,
+            &((FSCatalogInfoObject *)_self)->ob_itself.sharingFlags,
+            &((FSCatalogInfoObject *)_self)->ob_itself.userPrivileges"""
+    INITNAMES = """
+            "nodeFlags",
+            "volume",
+            "parentDirID",
+            "nodeID",
+            "createDate",
+            "contentModDate",
+            "atributeModDate",
+            "accessDate",
+            "backupDate",
+            "valence",
+            "dataLogicalSize",
+            "dataPhysicalSize",
+            "rsrcLogicalSize",
+            "rsrcPhysicalSize",
+            "sharingFlags",
+            "userPrivileges"
+            """
+
+    def __init__(self, name, prefix, itselftype):
+        ObjectDefinition.__init__(self, name, prefix, itselftype)
+        self.argref = "*"       # Store FSSpecs, but pass them by address
+
+    def outputCheckNewArg(self):
+        Output("if (itself == NULL) { Py_INCREF(Py_None); return Py_None; }")
+
+    def output_tp_newBody(self):
+        Output("PyObject *self;");
+        Output()
+        Output("if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;")
+        Output("memset(&((%s *)self)->ob_itself, 0, sizeof(%s));",
+                self.objecttype, self.itselftype)
+        Output("return self;")
+
+    def output_tp_initBody(self):
+        Output("static char *kw[] = {%s, 0};", self.INITNAMES)
+        Output()
+        Output("if (!PyArg_ParseTupleAndKeywords(_args, _kwds, \"|%s\", kw, %s))",
+                self.INITFORMAT, self.INITARGS)
+        OutLbrace()
+        Output("return -1;")
+        OutRbrace()
+        Output("return 0;")
+
+class FInfoDefinition(PEP253Mixin, ObjectDefinition):
+    getsetlist = [
+            ("Type",
+             "return Py_BuildValue(\"O&\", PyMac_BuildOSType, self->ob_itself.fdType);",
+             "return PyArg_Parse(v, \"O&\", PyMac_GetOSType, &self->ob_itself.fdType)-1;",
+             "4-char file type"
+            ),
+            ("Creator",
+             "return Py_BuildValue(\"O&\", PyMac_BuildOSType, self->ob_itself.fdCreator);",
+             "return PyArg_Parse(v, \"O&\", PyMac_GetOSType, &self->ob_itself.fdCreator)-1;",
+             "4-char file creator"
+            ),
+            ("Flags",
+             "return Py_BuildValue(\"H\", self->ob_itself.fdFlags);",
+             "return PyArg_Parse(v, \"H\", &self->ob_itself.fdFlags)-1;",
+             "Finder flag bits"
+            ),
+            ("Location",
+             "return Py_BuildValue(\"O&\", PyMac_BuildPoint, self->ob_itself.fdLocation);",
+             "return PyArg_Parse(v, \"O&\", PyMac_GetPoint, &self->ob_itself.fdLocation)-1;",
+             "(x, y) location of the file's icon in its parent finder window"
+            ),
+            ("Fldr",
+             "return Py_BuildValue(\"h\", self->ob_itself.fdFldr);",
+             "return PyArg_Parse(v, \"h\", &self->ob_itself.fdFldr)-1;",
+             "Original folder, for 'put away'"
+            ),
+
+    ]
+
+    def __init__(self, name, prefix, itselftype):
+        ObjectDefinition.__init__(self, name, prefix, itselftype)
+        self.argref = "*"       # Store FSSpecs, but pass them by address
+
+    def outputCheckNewArg(self):
+        Output("if (itself == NULL) return PyMac_Error(resNotFound);")
+
+    def output_tp_newBody(self):
+        Output("PyObject *self;");
+        Output()
+        Output("if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;")
+        Output("memset(&((%s *)self)->ob_itself, 0, sizeof(%s));",
+                self.objecttype, self.itselftype)
+        Output("return self;")
+
+    def output_tp_initBody(self):
+        Output("%s *itself = NULL;", self.itselftype)
+        Output("static char *kw[] = {\"itself\", 0};")
+        Output()
+        Output("if (PyArg_ParseTupleAndKeywords(_args, _kwds, \"|O&\", kw, FInfo_Convert, &itself))")
+        OutLbrace()
+        Output("if (itself) memcpy(&((%s *)_self)->ob_itself, itself, sizeof(%s));",
+                self.objecttype, self.itselftype)
+        Output("return 0;")
+        OutRbrace()
+        Output("return -1;")
+
+class FSSpecDefinition(PEP253Mixin, ObjectDefinition):
+    getsetlist = [
+            ("data",
+             "return PyString_FromStringAndSize((char *)&self->ob_itself, sizeof(self->ob_itself));",
+             None,
+             "Raw data of the FSSpec object"
+            )
+    ]
+
+    def __init__(self, name, prefix, itselftype):
+        ObjectDefinition.__init__(self, name, prefix, itselftype)
+        self.argref = "*"       # Store FSSpecs, but pass them by address
+
+    def outputCheckNewArg(self):
+        Output("if (itself == NULL) return PyMac_Error(resNotFound);")
+
+    # We do Convert ourselves (with PyMac_GetFSxxx)
+    def outputConvert(self):
+        pass
+
+    def output_tp_newBody(self):
+        Output("PyObject *self;");
+        Output()
+        Output("if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;")
+        Output("memset(&((%s *)self)->ob_itself, 0, sizeof(%s));",
+                self.objecttype, self.itselftype)
+        Output("return self;")
+
+    def output_tp_initBody(self):
+        Output("PyObject *v = NULL;")
+        Output("char *rawdata = NULL;")
+        Output("int rawdatalen = 0;")
+        Output("static char *kw[] = {\"itself\", \"rawdata\", 0};")
+        Output()
+        Output("if (!PyArg_ParseTupleAndKeywords(_args, _kwds, \"|Os#\", kw, &v, &rawdata, &rawdatalen))")
+        Output("return -1;")
+        Output("if (v && rawdata)")
+        OutLbrace()
+        Output("PyErr_SetString(PyExc_TypeError, \"Only one of itself or rawdata may be specified\");")
+        Output("return -1;")
+        OutRbrace()
+        Output("if (!v && !rawdata)")
+        OutLbrace()
+        Output("PyErr_SetString(PyExc_TypeError, \"One of itself or rawdata must be specified\");")
+        Output("return -1;")
+        OutRbrace()
+        Output("if (rawdata)")
+        OutLbrace()
+        Output("if (rawdatalen != sizeof(%s))", self.itselftype)
+        OutLbrace()
+        Output("PyErr_SetString(PyExc_TypeError, \"%s rawdata incorrect size\");",
+                self.itselftype)
+        Output("return -1;")
+        OutRbrace()
+        Output("memcpy(&((%s *)_self)->ob_itself, rawdata, rawdatalen);", self.objecttype)
+        Output("return 0;")
+        OutRbrace()
+        Output("if (PyMac_GetFSSpec(v, &((%s *)_self)->ob_itself)) return 0;", self.objecttype)
+        Output("return -1;")
+
+    def outputRepr(self):
+        Output()
+        Output("static PyObject * %s_repr(%s *self)", self.prefix, self.objecttype)
+        OutLbrace()
+        Output("char buf[512];")
+        Output("""PyOS_snprintf(buf, sizeof(buf), \"%%s((%%d, %%ld, '%%.*s'))\",
+        self->ob_type->tp_name,
+        self->ob_itself.vRefNum,
+        self->ob_itself.parID,
+        self->ob_itself.name[0], self->ob_itself.name+1);""")
+        Output("return PyString_FromString(buf);")
+        OutRbrace()
+
+class FSRefDefinition(PEP253Mixin, ObjectDefinition):
+    getsetlist = [
+            ("data",
+             "return PyString_FromStringAndSize((char *)&self->ob_itself, sizeof(self->ob_itself));",
+             None,
+             "Raw data of the FSRef object"
+            )
+    ]
+
+    def __init__(self, name, prefix, itselftype):
+        ObjectDefinition.__init__(self, name, prefix, itselftype)
+        self.argref = "*"       # Store FSRefs, but pass them by address
+
+    def outputCheckNewArg(self):
+        Output("if (itself == NULL) return PyMac_Error(resNotFound);")
+
+    # We do Convert ourselves (with PyMac_GetFSxxx)
+    def outputConvert(self):
+        pass
+
+    def output_tp_newBody(self):
+        Output("PyObject *self;");
+        Output()
+        Output("if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;")
+        Output("memset(&((%s *)self)->ob_itself, 0, sizeof(%s));",
+                self.objecttype, self.itselftype)
+        Output("return self;")
+
+    def output_tp_initBody(self):
+        Output("PyObject *v = NULL;")
+        Output("char *rawdata = NULL;")
+        Output("int rawdatalen = 0;")
+        Output("static char *kw[] = {\"itself\", \"rawdata\", 0};")
+        Output()
+        Output("if (!PyArg_ParseTupleAndKeywords(_args, _kwds, \"|Os#\", kw, &v, &rawdata, &rawdatalen))")
+        Output("return -1;")
+        Output("if (v && rawdata)")
+        OutLbrace()
+        Output("PyErr_SetString(PyExc_TypeError, \"Only one of itself or rawdata may be specified\");")
+        Output("return -1;")
+        OutRbrace()
+        Output("if (!v && !rawdata)")
+        OutLbrace()
+        Output("PyErr_SetString(PyExc_TypeError, \"One of itself or rawdata must be specified\");")
+        Output("return -1;")
+        OutRbrace()
+        Output("if (rawdata)")
+        OutLbrace()
+        Output("if (rawdatalen != sizeof(%s))", self.itselftype)
+        OutLbrace()
+        Output("PyErr_SetString(PyExc_TypeError, \"%s rawdata incorrect size\");",
+                self.itselftype)
+        Output("return -1;")
+        OutRbrace()
+        Output("memcpy(&((%s *)_self)->ob_itself, rawdata, rawdatalen);", self.objecttype)
+        Output("return 0;")
+        OutRbrace()
+        Output("if (PyMac_GetFSRef(v, &((%s *)_self)->ob_itself)) return 0;", self.objecttype)
+        Output("return -1;")
+
+class AliasDefinition(PEP253Mixin, ObjectDefinition):
+    # XXXX Should inherit from resource?
+    getsetlist = [
+            ("data",
+             """int size;
+                    PyObject *rv;
+
+                    size = GetHandleSize((Handle)self->ob_itself);
+                    HLock((Handle)self->ob_itself);
+                    rv = PyString_FromStringAndSize(*(Handle)self->ob_itself, size);
+                    HUnlock((Handle)self->ob_itself);
+                    return rv;
+            """,
+             None,
+             "Raw data of the alias object"
+            )
+    ]
+
+    def outputCheckNewArg(self):
+        Output("if (itself == NULL) return PyMac_Error(resNotFound);")
+
+    def outputStructMembers(self):
+        ObjectDefinition.outputStructMembers(self)
+        Output("void (*ob_freeit)(%s ptr);", self.itselftype)
+
+    def outputInitStructMembers(self):
+        ObjectDefinition.outputInitStructMembers(self)
+        Output("it->ob_freeit = NULL;")
+
+    def outputCleanupStructMembers(self):
+        Output("if (self->ob_freeit && self->ob_itself)")
+        OutLbrace()
+        Output("self->ob_freeit(self->ob_itself);")
+        OutRbrace()
+        Output("self->ob_itself = NULL;")
+
+    def output_tp_newBody(self):
+        Output("PyObject *self;");
+        Output()
+        Output("if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;")
+        Output("((%s *)self)->ob_itself = NULL;", self.objecttype)
+        Output("return self;")
+
+    def output_tp_initBody(self):
+        Output("%s itself = NULL;", self.itselftype)
+        Output("char *rawdata = NULL;")
+        Output("int rawdatalen = 0;")
+        Output("Handle h;")
+        Output("static char *kw[] = {\"itself\", \"rawdata\", 0};")
+        Output()
+        Output("if (!PyArg_ParseTupleAndKeywords(_args, _kwds, \"|O&s#\", kw, %s_Convert, &itself, &rawdata, &rawdatalen))",
+                self.prefix)
+        Output("return -1;")
+        Output("if (itself && rawdata)")
+        OutLbrace()
+        Output("PyErr_SetString(PyExc_TypeError, \"Only one of itself or rawdata may be specified\");")
+        Output("return -1;")
+        OutRbrace()
+        Output("if (!itself && !rawdata)")
+        OutLbrace()
+        Output("PyErr_SetString(PyExc_TypeError, \"One of itself or rawdata must be specified\");")
+        Output("return -1;")
+        OutRbrace()
+        Output("if (rawdata)")
+        OutLbrace()
+        Output("if ((h = NewHandle(rawdatalen)) == NULL)")
+        OutLbrace()
+        Output("PyErr_NoMemory();")
+        Output("return -1;")
+        OutRbrace()
+        Output("HLock(h);")
+        Output("memcpy((char *)*h, rawdata, rawdatalen);")
+        Output("HUnlock(h);")
+        Output("((%s *)_self)->ob_itself = (%s)h;", self.objecttype, self.itselftype)
+        Output("return 0;")
+        OutRbrace()
+        Output("((%s *)_self)->ob_itself = itself;", self.objecttype)
+        Output("return 0;")
+
+# Alias methods come in two flavors: those with the alias as arg1 and
+# those with the alias as arg 2.
+class Arg2MethodGenerator(OSErrMethodGenerator):
+    """Similar to MethodGenerator, but has self as second argument"""
+
+    def parseArgumentList(self, args):
+        args0, arg1, argsrest = args[:1], args[1], args[2:]
+        t0, n0, m0 = arg1
+        args = args0 + argsrest
+        if m0 != InMode:
+            raise ValueError, "method's 'self' must be 'InMode'"
+        self.itself = Variable(t0, "_self->ob_itself", SelfMode)
+        FunctionGenerator.parseArgumentList(self, args)
+        self.argumentList.insert(2, self.itself)
+
+# From here on it's basically all boiler plate...
+
+# Create the generator groups and link them
+module = MacModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff,
+        longname=LONGMODNAME)
+
+fscataloginfoobject = FSCatalogInfoDefinition('FSCatalogInfo', 'FSCatalogInfo', 'FSCatalogInfo')
+finfoobject = FInfoDefinition('FInfo', 'FInfo', 'FInfo')
+aliasobject = AliasDefinition('Alias', 'Alias', 'AliasHandle')
+fsspecobject = FSSpecDefinition('FSSpec', 'FSSpec', 'FSSpec')
+fsrefobject = FSRefDefinition('FSRef', 'FSRef', 'FSRef')
+
+module.addobject(fscataloginfoobject)
+module.addobject(finfoobject)
+module.addobject(aliasobject)
+module.addobject(fsspecobject)
+module.addobject(fsrefobject)
+
+# Create the generator classes used to populate the lists
+Function = OSErrFunctionGenerator
+Method = OSErrMethodGenerator
+
+# Create and populate the lists
+functions = []
+alias_methods = []
+fsref_methods = []
+fsspec_methods = []
+execfile(INPUTFILE)
+
+# Manual generators:
+FSRefMakePath_body = """
+OSStatus _err;
+#define MAXPATHNAME 1024
+UInt8 path[MAXPATHNAME];
+UInt32 maxPathSize = MAXPATHNAME;
+
+if (!PyArg_ParseTuple(_args, ""))
+        return NULL;
+_err = FSRefMakePath(&_self->ob_itself,
+                                         path,
+                                         maxPathSize);
+if (_err != noErr) return PyMac_Error(_err);
+_res = Py_BuildValue("s", path);
+return _res;
+"""
+f = ManualGenerator("FSRefMakePath", FSRefMakePath_body)
+f.docstring = lambda: "() -> string"
+fsref_methods.append(f)
+
+FSRef_as_pathname_body = """
+if (!PyArg_ParseTuple(_args, ""))
+        return NULL;
+_res = FSRef_FSRefMakePath(_self, _args);
+return _res;
+"""
+f = ManualGenerator("as_pathname", FSRef_as_pathname_body)
+f.docstring = lambda: "() -> string"
+fsref_methods.append(f)
+
+FSSpec_as_pathname_body = """
+char strbuf[1024];
+OSErr err;
+
+if (!PyArg_ParseTuple(_args, ""))
+        return NULL;
+err = _PyMac_GetFullPathname(&_self->ob_itself, strbuf, sizeof(strbuf));
+if ( err ) {
+        PyMac_Error(err);
+        return NULL;
+}
+_res = PyString_FromString(strbuf);
+return _res;
+"""
+f = ManualGenerator("as_pathname", FSSpec_as_pathname_body)
+f.docstring = lambda: "() -> string"
+fsspec_methods.append(f)
+
+FSSpec_as_tuple_body = """
+if (!PyArg_ParseTuple(_args, ""))
+        return NULL;
+_res = Py_BuildValue("(iis#)", _self->ob_itself.vRefNum, _self->ob_itself.parID,
+                                        &_self->ob_itself.name[1], _self->ob_itself.name[0]);
+return _res;
+"""
+f = ManualGenerator("as_tuple", FSSpec_as_tuple_body)
+f.docstring = lambda: "() -> (vRefNum, dirID, name)"
+fsspec_methods.append(f)
+
+pathname_body = """
+PyObject *obj;
+
+if (!PyArg_ParseTuple(_args, "O", &obj))
+        return NULL;
+if (PyString_Check(obj)) {
+        Py_INCREF(obj);
+        return obj;
+}
+if (PyUnicode_Check(obj))
+        return PyUnicode_AsEncodedString(obj, "utf8", "strict");
+_res = PyObject_CallMethod(obj, "as_pathname", NULL);
+return _res;
+"""
+f = ManualGenerator("pathname", pathname_body)
+f.docstring = lambda: "(str|unicode|FSSpec|FSref) -> pathname"
+functions.append(f)
+
+# add the populated lists to the generator groups
+# (in a different wordl the scan program would generate this)
+for f in functions: module.add(f)
+for f in alias_methods: aliasobject.add(f)
+for f in fsspec_methods: fsspecobject.add(f)
+for f in fsref_methods: fsrefobject.add(f)
+
+# generate output (open the output file as late as possible)
+SetOutputFileName(OUTPUTFILE)
+module.generate()

Added: vendor/Python/current/Mac/Modules/fm/_Fmmodule.c
===================================================================
--- vendor/Python/current/Mac/Modules/fm/_Fmmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/fm/_Fmmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,358 @@
+
+/* =========================== Module _Fm =========================== */
+
+#include "Python.h"
+
+
+
+#include "pymactoolbox.h"
+
+/* Macro to test whether a weak-loaded CFM function exists */
+#define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL )  {\
+        PyErr_SetString(PyExc_NotImplementedError, \
+        "Not available in this shared library/OS version"); \
+        return NULL; \
+    }} while(0)
+
+
+#include <Carbon/Carbon.h>
+
+
+/*
+** Parse/generate ComponentDescriptor records
+*/
+static PyObject *
+FMRec_New(FMetricRec *itself)
+{
+
+        return Py_BuildValue("O&O&O&O&O&",
+                PyMac_BuildFixed, itself->ascent,
+                PyMac_BuildFixed, itself->descent,
+                PyMac_BuildFixed, itself->leading,
+                PyMac_BuildFixed, itself->widMax,
+                ResObj_New, itself->wTabHandle);
+}
+
+#if 0
+/* Not needed... */
+static int
+FMRec_Convert(PyObject *v, FMetricRec *p_itself)
+{
+        return PyArg_ParseTuple(v, "O&O&O&O&O&",
+                PyMac_GetFixed, &itself->ascent,
+                PyMac_GetFixed, &itself->descent,
+                PyMac_GetFixed, &itself->leading,
+                PyMac_GetFixed, &itself->widMax,
+                ResObj_Convert, &itself->wTabHandle);
+}
+#endif
+
+
+static PyObject *Fm_Error;
+
+static PyObject *Fm_GetFontName(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short familyID;
+	Str255 name;
+#ifndef GetFontName
+	PyMac_PRECHECK(GetFontName);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &familyID))
+		return NULL;
+	GetFontName(familyID,
+	            name);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildStr255, name);
+	return _res;
+}
+
+static PyObject *Fm_GetFNum(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Str255 name;
+	short familyID;
+#ifndef GetFNum
+	PyMac_PRECHECK(GetFNum);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetStr255, name))
+		return NULL;
+	GetFNum(name,
+	        &familyID);
+	_res = Py_BuildValue("h",
+	                     familyID);
+	return _res;
+}
+
+static PyObject *Fm_RealFont(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	short fontNum;
+	short size;
+#ifndef RealFont
+	PyMac_PRECHECK(RealFont);
+#endif
+	if (!PyArg_ParseTuple(_args, "hh",
+	                      &fontNum,
+	                      &size))
+		return NULL;
+	_rv = RealFont(fontNum,
+	               size);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Fm_SetFScaleDisable(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean fscaleDisable;
+#ifndef SetFScaleDisable
+	PyMac_PRECHECK(SetFScaleDisable);
+#endif
+	if (!PyArg_ParseTuple(_args, "b",
+	                      &fscaleDisable))
+		return NULL;
+	SetFScaleDisable(fscaleDisable);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Fm_FontMetrics(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	FMetricRec theMetrics;
+#ifndef FontMetrics
+	PyMac_PRECHECK(FontMetrics);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	FontMetrics(&theMetrics);
+	_res = Py_BuildValue("O&",
+	                     FMRec_New, &theMetrics);
+	return _res;
+}
+
+static PyObject *Fm_SetFractEnable(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean fractEnable;
+#ifndef SetFractEnable
+	PyMac_PRECHECK(SetFractEnable);
+#endif
+	if (!PyArg_ParseTuple(_args, "b",
+	                      &fractEnable))
+		return NULL;
+	SetFractEnable(fractEnable);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Fm_GetDefFontSize(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short _rv;
+#ifndef GetDefFontSize
+	PyMac_PRECHECK(GetDefFontSize);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetDefFontSize();
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Fm_IsOutline(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	Point numer;
+	Point denom;
+#ifndef IsOutline
+	PyMac_PRECHECK(IsOutline);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetPoint, &numer,
+	                      PyMac_GetPoint, &denom))
+		return NULL;
+	_rv = IsOutline(numer,
+	                denom);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Fm_SetOutlinePreferred(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean outlinePreferred;
+#ifndef SetOutlinePreferred
+	PyMac_PRECHECK(SetOutlinePreferred);
+#endif
+	if (!PyArg_ParseTuple(_args, "b",
+	                      &outlinePreferred))
+		return NULL;
+	SetOutlinePreferred(outlinePreferred);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Fm_GetOutlinePreferred(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+#ifndef GetOutlinePreferred
+	PyMac_PRECHECK(GetOutlinePreferred);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetOutlinePreferred();
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Fm_SetPreserveGlyph(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean preserveGlyph;
+#ifndef SetPreserveGlyph
+	PyMac_PRECHECK(SetPreserveGlyph);
+#endif
+	if (!PyArg_ParseTuple(_args, "b",
+	                      &preserveGlyph))
+		return NULL;
+	SetPreserveGlyph(preserveGlyph);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Fm_GetPreserveGlyph(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+#ifndef GetPreserveGlyph
+	PyMac_PRECHECK(GetPreserveGlyph);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetPreserveGlyph();
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Fm_GetSysFont(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short _rv;
+#ifndef GetSysFont
+	PyMac_PRECHECK(GetSysFont);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetSysFont();
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Fm_GetAppFont(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short _rv;
+#ifndef GetAppFont
+	PyMac_PRECHECK(GetAppFont);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetAppFont();
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Fm_QDTextBounds(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	char *inText__in__;
+	int inText__len__;
+	int inText__in_len__;
+	Rect bounds;
+#ifndef QDTextBounds
+	PyMac_PRECHECK(QDTextBounds);
+#endif
+	if (!PyArg_ParseTuple(_args, "s#",
+	                      &inText__in__, &inText__in_len__))
+		return NULL;
+	inText__len__ = inText__in_len__;
+	QDTextBounds(inText__len__, inText__in__,
+	             &bounds);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildRect, &bounds);
+	return _res;
+}
+
+static PyMethodDef Fm_methods[] = {
+	{"GetFontName", (PyCFunction)Fm_GetFontName, 1,
+	 PyDoc_STR("(short familyID) -> (Str255 name)")},
+	{"GetFNum", (PyCFunction)Fm_GetFNum, 1,
+	 PyDoc_STR("(Str255 name) -> (short familyID)")},
+	{"RealFont", (PyCFunction)Fm_RealFont, 1,
+	 PyDoc_STR("(short fontNum, short size) -> (Boolean _rv)")},
+	{"SetFScaleDisable", (PyCFunction)Fm_SetFScaleDisable, 1,
+	 PyDoc_STR("(Boolean fscaleDisable) -> None")},
+	{"FontMetrics", (PyCFunction)Fm_FontMetrics, 1,
+	 PyDoc_STR("() -> (FMetricRec theMetrics)")},
+	{"SetFractEnable", (PyCFunction)Fm_SetFractEnable, 1,
+	 PyDoc_STR("(Boolean fractEnable) -> None")},
+	{"GetDefFontSize", (PyCFunction)Fm_GetDefFontSize, 1,
+	 PyDoc_STR("() -> (short _rv)")},
+	{"IsOutline", (PyCFunction)Fm_IsOutline, 1,
+	 PyDoc_STR("(Point numer, Point denom) -> (Boolean _rv)")},
+	{"SetOutlinePreferred", (PyCFunction)Fm_SetOutlinePreferred, 1,
+	 PyDoc_STR("(Boolean outlinePreferred) -> None")},
+	{"GetOutlinePreferred", (PyCFunction)Fm_GetOutlinePreferred, 1,
+	 PyDoc_STR("() -> (Boolean _rv)")},
+	{"SetPreserveGlyph", (PyCFunction)Fm_SetPreserveGlyph, 1,
+	 PyDoc_STR("(Boolean preserveGlyph) -> None")},
+	{"GetPreserveGlyph", (PyCFunction)Fm_GetPreserveGlyph, 1,
+	 PyDoc_STR("() -> (Boolean _rv)")},
+	{"GetSysFont", (PyCFunction)Fm_GetSysFont, 1,
+	 PyDoc_STR("() -> (short _rv)")},
+	{"GetAppFont", (PyCFunction)Fm_GetAppFont, 1,
+	 PyDoc_STR("() -> (short _rv)")},
+	{"QDTextBounds", (PyCFunction)Fm_QDTextBounds, 1,
+	 PyDoc_STR("(Buffer inText) -> (Rect bounds)")},
+	{NULL, NULL, 0}
+};
+
+
+
+
+void init_Fm(void)
+{
+	PyObject *m;
+	PyObject *d;
+
+
+
+
+	m = Py_InitModule("_Fm", Fm_methods);
+	d = PyModule_GetDict(m);
+	Fm_Error = PyMac_GetOSErrException();
+	if (Fm_Error == NULL ||
+	    PyDict_SetItemString(d, "Error", Fm_Error) != 0)
+		return;
+}
+
+/* ========================= End module _Fm ========================= */
+

Added: vendor/Python/current/Mac/Modules/fm/fmscan.py
===================================================================
--- vendor/Python/current/Mac/Modules/fm/fmscan.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/fm/fmscan.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,72 @@
+# Scan an Apple header file, generating a Python file of generator calls.
+
+import sys
+import os
+from bgenlocations import TOOLBOXDIR, BGENDIR
+sys.path.append(BGENDIR)
+from scantools import Scanner
+
+LONG = "Fonts"
+SHORT = "fm"
+
+def main():
+    input = "Fonts.h"
+    output = SHORT + "gen.py"
+    defsoutput = TOOLBOXDIR + LONG + ".py"
+    scanner = MyScanner(input, output, defsoutput)
+    scanner.scan()
+    scanner.close()
+    print "=== Testing definitions output code ==="
+    execfile(defsoutput, {}, {})
+    print "=== Done scanning and generating, now importing the generated code... ==="
+    exec "import " + SHORT + "support"
+    print "=== Done.  It's up to you to compile it now! ==="
+
+class MyScanner(Scanner):
+
+    def destination(self, type, name, arglist):
+        classname = "Function"
+        listname = "functions"
+        return classname, listname
+
+    def makeblacklistnames(self):
+        return [
+                "OutlineMetrics",       # Too complicated
+                "AntiTextIsAntiAliased",        # XXXX Missing from library...
+                "AntiTextGetEnabled",
+                "AntiTextSetEnabled",
+                "AntiTextGetApplicationAware",
+                "AntiTextSetApplicationAware",
+                # These are tricky: they're not Carbon dependent or anything, but they
+                # exist only on 8.6 or later (both in Carbon and Classic).
+                # Disabling them is the easiest path.
+                'SetAntiAliasedTextEnabled',
+                'IsAntiAliasedTextEnabled',
+                # OS8-only
+                'InitFonts',
+                'SetFontLock',
+                'FlushFonts',
+                ]
+
+    def makeblacklisttypes(self):
+        return [
+                "FMInput_ptr",  # Not needed for now
+                "FMOutPtr",             # Ditto
+##                      "void_ptr",             # Don't know how to do this right now
+                "FontInfo",             # Ditto
+                ]
+
+    def makerepairinstructions(self):
+        return [
+                ([('Str255', '*', 'InMode')], [('Str255', '*', 'OutMode')]),
+                ([('FMetricRecPtr', 'theMetrics', 'InMode')], [('FMetricRecPtr', 'theMetrics', 'OutMode')]),
+                ([('short', 'byteCount', 'InMode'), ('void_ptr', 'textAddr', 'InMode'),],
+                 [('TextBuffer', 'inText', 'InMode')]),
+                ]
+
+    def writeinitialdefs(self):
+        self.defsfile.write("def FOUR_CHAR_CODE(x): return x\n")
+        self.defsfile.write("kNilOptions = 0\n")
+
+if __name__ == "__main__":
+    main()

Added: vendor/Python/current/Mac/Modules/fm/fmsupport.py
===================================================================
--- vendor/Python/current/Mac/Modules/fm/fmsupport.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/fm/fmsupport.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,81 @@
+# This script generates a Python interface for an Apple Macintosh Manager.
+# It uses the "bgen" package to generate C code.
+# The function specifications are generated by scanning the mamager's header file,
+# using the "scantools" package (customized for this particular manager).
+
+import string
+
+# Declarations that change for each manager
+MACHEADERFILE = 'Fonts.h'               # The Apple header file
+MODNAME = '_Fm'                         # The name of the module
+
+# The following is *usually* unchanged but may still require tuning
+MODPREFIX = 'Fm'                        # The prefix for module-wide routines
+INPUTFILE = string.lower(MODPREFIX) + 'gen.py' # The file generated by the scanner
+OUTPUTFILE = MODNAME + "module.c"       # The file generated by this program
+
+from macsupport import *
+
+# Create the type objects
+
+class RevVarInputBufferType(VarInputBufferType):
+    def passInput(self, name):
+        return "%s__len__, %s__in__" % (name, name)
+
+TextBuffer = RevVarInputBufferType()
+
+
+includestuff = includestuff + """
+#include <Carbon/Carbon.h>
+
+
+/*
+** Parse/generate ComponentDescriptor records
+*/
+static PyObject *
+FMRec_New(FMetricRec *itself)
+{
+
+        return Py_BuildValue("O&O&O&O&O&",
+                PyMac_BuildFixed, itself->ascent,
+                PyMac_BuildFixed, itself->descent,
+                PyMac_BuildFixed, itself->leading,
+                PyMac_BuildFixed, itself->widMax,
+                ResObj_New, itself->wTabHandle);
+}
+
+#if 0
+/* Not needed... */
+static int
+FMRec_Convert(PyObject *v, FMetricRec *p_itself)
+{
+        return PyArg_ParseTuple(v, "O&O&O&O&O&",
+                PyMac_GetFixed, &itself->ascent,
+                PyMac_GetFixed, &itself->descent,
+                PyMac_GetFixed, &itself->leading,
+                PyMac_GetFixed, &itself->widMax,
+                ResObj_Convert, &itself->wTabHandle);
+}
+#endif
+
+"""
+
+FMetricRecPtr = OpaqueType('FMetricRec', 'FMRec')
+
+# Create the generator groups and link them
+module = MacModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff)
+
+# Create the generator classes used to populate the lists
+Function = OSErrWeakLinkFunctionGenerator
+
+# Create and populate the lists
+functions = []
+execfile(INPUTFILE)
+
+# add the populated lists to the generator groups
+# (in a different wordl the scan program would generate this)
+for f in functions: module.add(f)
+
+# generate output (open the output file as late as possible)
+SetOutputFileName(OUTPUTFILE)
+module.generate()

Added: vendor/Python/current/Mac/Modules/folder/_Foldermodule.c
===================================================================
--- vendor/Python/current/Mac/Modules/folder/_Foldermodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/folder/_Foldermodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,338 @@
+
+/* ========================= Module _Folder ========================= */
+
+#include "Python.h"
+
+
+
+#include "pymactoolbox.h"
+
+/* Macro to test whether a weak-loaded CFM function exists */
+#define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL )  {\
+        PyErr_SetString(PyExc_NotImplementedError, \
+        "Not available in this shared library/OS version"); \
+        return NULL; \
+    }} while(0)
+
+
+#include <Carbon/Carbon.h>
+
+
+static PyObject *Folder_Error;
+
+static PyObject *Folder_FindFolder(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short vRefNum;
+	OSType folderType;
+	Boolean createFolder;
+	short foundVRefNum;
+	long foundDirID;
+	if (!PyArg_ParseTuple(_args, "hO&b",
+	                      &vRefNum,
+	                      PyMac_GetOSType, &folderType,
+	                      &createFolder))
+		return NULL;
+	_err = FindFolder(vRefNum,
+	                  folderType,
+	                  createFolder,
+	                  &foundVRefNum,
+	                  &foundDirID);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("hl",
+	                     foundVRefNum,
+	                     foundDirID);
+	return _res;
+}
+
+static PyObject *Folder_ReleaseFolder(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short vRefNum;
+	OSType folderType;
+	if (!PyArg_ParseTuple(_args, "hO&",
+	                      &vRefNum,
+	                      PyMac_GetOSType, &folderType))
+		return NULL;
+	_err = ReleaseFolder(vRefNum,
+	                     folderType);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Folder_FSFindFolder(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short vRefNum;
+	OSType folderType;
+	Boolean createFolder;
+	FSRef foundRef;
+	if (!PyArg_ParseTuple(_args, "hO&b",
+	                      &vRefNum,
+	                      PyMac_GetOSType, &folderType,
+	                      &createFolder))
+		return NULL;
+	_err = FSFindFolder(vRefNum,
+	                    folderType,
+	                    createFolder,
+	                    &foundRef);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildFSRef, &foundRef);
+	return _res;
+}
+
+static PyObject *Folder_AddFolderDescriptor(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	FolderType foldType;
+	FolderDescFlags flags;
+	FolderClass foldClass;
+	FolderLocation foldLocation;
+	OSType badgeSignature;
+	OSType badgeType;
+	Str255 name;
+	Boolean replaceFlag;
+	if (!PyArg_ParseTuple(_args, "O&lO&O&O&O&O&b",
+	                      PyMac_GetOSType, &foldType,
+	                      &flags,
+	                      PyMac_GetOSType, &foldClass,
+	                      PyMac_GetOSType, &foldLocation,
+	                      PyMac_GetOSType, &badgeSignature,
+	                      PyMac_GetOSType, &badgeType,
+	                      PyMac_GetStr255, name,
+	                      &replaceFlag))
+		return NULL;
+	_err = AddFolderDescriptor(foldType,
+	                           flags,
+	                           foldClass,
+	                           foldLocation,
+	                           badgeSignature,
+	                           badgeType,
+	                           name,
+	                           replaceFlag);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Folder_GetFolderTypes(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	UInt32 requestedTypeCount;
+	UInt32 totalTypeCount;
+	FolderType theTypes;
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &requestedTypeCount))
+		return NULL;
+	_err = GetFolderTypes(requestedTypeCount,
+	                      &totalTypeCount,
+	                      &theTypes);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("lO&",
+	                     totalTypeCount,
+	                     PyMac_BuildOSType, theTypes);
+	return _res;
+}
+
+static PyObject *Folder_RemoveFolderDescriptor(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	FolderType foldType;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetOSType, &foldType))
+		return NULL;
+	_err = RemoveFolderDescriptor(foldType);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Folder_GetFolderName(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short vRefNum;
+	OSType foldType;
+	short foundVRefNum;
+	Str255 name;
+	if (!PyArg_ParseTuple(_args, "hO&O&",
+	                      &vRefNum,
+	                      PyMac_GetOSType, &foldType,
+	                      PyMac_GetStr255, name))
+		return NULL;
+	_err = GetFolderName(vRefNum,
+	                     foldType,
+	                     &foundVRefNum,
+	                     name);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("h",
+	                     foundVRefNum);
+	return _res;
+}
+
+static PyObject *Folder_AddFolderRouting(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	OSType fileType;
+	FolderType routeFromFolder;
+	FolderType routeToFolder;
+	RoutingFlags flags;
+	Boolean replaceFlag;
+	if (!PyArg_ParseTuple(_args, "O&O&O&lb",
+	                      PyMac_GetOSType, &fileType,
+	                      PyMac_GetOSType, &routeFromFolder,
+	                      PyMac_GetOSType, &routeToFolder,
+	                      &flags,
+	                      &replaceFlag))
+		return NULL;
+	_err = AddFolderRouting(fileType,
+	                        routeFromFolder,
+	                        routeToFolder,
+	                        flags,
+	                        replaceFlag);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Folder_RemoveFolderRouting(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	OSType fileType;
+	FolderType routeFromFolder;
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetOSType, &fileType,
+	                      PyMac_GetOSType, &routeFromFolder))
+		return NULL;
+	_err = RemoveFolderRouting(fileType,
+	                           routeFromFolder);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Folder_FindFolderRouting(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	OSType fileType;
+	FolderType routeFromFolder;
+	FolderType routeToFolder;
+	RoutingFlags flags;
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetOSType, &fileType,
+	                      PyMac_GetOSType, &routeFromFolder))
+		return NULL;
+	_err = FindFolderRouting(fileType,
+	                         routeFromFolder,
+	                         &routeToFolder,
+	                         &flags);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&l",
+	                     PyMac_BuildOSType, routeToFolder,
+	                     flags);
+	return _res;
+}
+
+static PyObject *Folder_InvalidateFolderDescriptorCache(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short vRefNum;
+	long dirID;
+	if (!PyArg_ParseTuple(_args, "hl",
+	                      &vRefNum,
+	                      &dirID))
+		return NULL;
+	_err = InvalidateFolderDescriptorCache(vRefNum,
+	                                       dirID);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Folder_IdentifyFolder(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short vRefNum;
+	long dirID;
+	FolderType foldType;
+	if (!PyArg_ParseTuple(_args, "hl",
+	                      &vRefNum,
+	                      &dirID))
+		return NULL;
+	_err = IdentifyFolder(vRefNum,
+	                      dirID,
+	                      &foldType);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildOSType, foldType);
+	return _res;
+}
+
+static PyMethodDef Folder_methods[] = {
+	{"FindFolder", (PyCFunction)Folder_FindFolder, 1,
+	 PyDoc_STR("(short vRefNum, OSType folderType, Boolean createFolder) -> (short foundVRefNum, long foundDirID)")},
+	{"ReleaseFolder", (PyCFunction)Folder_ReleaseFolder, 1,
+	 PyDoc_STR("(short vRefNum, OSType folderType) -> None")},
+	{"FSFindFolder", (PyCFunction)Folder_FSFindFolder, 1,
+	 PyDoc_STR("(short vRefNum, OSType folderType, Boolean createFolder) -> (FSRef foundRef)")},
+	{"AddFolderDescriptor", (PyCFunction)Folder_AddFolderDescriptor, 1,
+	 PyDoc_STR("(FolderType foldType, FolderDescFlags flags, FolderClass foldClass, FolderLocation foldLocation, OSType badgeSignature, OSType badgeType, Str255 name, Boolean replaceFlag) -> None")},
+	{"GetFolderTypes", (PyCFunction)Folder_GetFolderTypes, 1,
+	 PyDoc_STR("(UInt32 requestedTypeCount) -> (UInt32 totalTypeCount, FolderType theTypes)")},
+	{"RemoveFolderDescriptor", (PyCFunction)Folder_RemoveFolderDescriptor, 1,
+	 PyDoc_STR("(FolderType foldType) -> None")},
+	{"GetFolderName", (PyCFunction)Folder_GetFolderName, 1,
+	 PyDoc_STR("(short vRefNum, OSType foldType, Str255 name) -> (short foundVRefNum)")},
+	{"AddFolderRouting", (PyCFunction)Folder_AddFolderRouting, 1,
+	 PyDoc_STR("(OSType fileType, FolderType routeFromFolder, FolderType routeToFolder, RoutingFlags flags, Boolean replaceFlag) -> None")},
+	{"RemoveFolderRouting", (PyCFunction)Folder_RemoveFolderRouting, 1,
+	 PyDoc_STR("(OSType fileType, FolderType routeFromFolder) -> None")},
+	{"FindFolderRouting", (PyCFunction)Folder_FindFolderRouting, 1,
+	 PyDoc_STR("(OSType fileType, FolderType routeFromFolder) -> (FolderType routeToFolder, RoutingFlags flags)")},
+	{"InvalidateFolderDescriptorCache", (PyCFunction)Folder_InvalidateFolderDescriptorCache, 1,
+	 PyDoc_STR("(short vRefNum, long dirID) -> None")},
+	{"IdentifyFolder", (PyCFunction)Folder_IdentifyFolder, 1,
+	 PyDoc_STR("(short vRefNum, long dirID) -> (FolderType foldType)")},
+	{NULL, NULL, 0}
+};
+
+
+
+
+void init_Folder(void)
+{
+	PyObject *m;
+	PyObject *d;
+
+
+
+
+	m = Py_InitModule("_Folder", Folder_methods);
+	d = PyModule_GetDict(m);
+	Folder_Error = PyMac_GetOSErrException();
+	if (Folder_Error == NULL ||
+	    PyDict_SetItemString(d, "Error", Folder_Error) != 0)
+		return;
+}
+
+/* ======================= End module _Folder ======================= */
+

Added: vendor/Python/current/Mac/Modules/folder/folderscan.py
===================================================================
--- vendor/Python/current/Mac/Modules/folder/folderscan.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/folder/folderscan.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,68 @@
+# Scan an Apple header file, generating a Python file of generator calls.
+
+import sys
+import os
+from bgenlocations import TOOLBOXDIR, BGENDIR
+sys.path.append(BGENDIR)
+from scantools import Scanner_OSX
+
+LONG = "Folders"
+SHORT = "folder"
+OBJECT = "NOTUSED"
+
+def main():
+    input = LONG + ".h"
+    output = SHORT + "gen.py"
+    defsoutput = TOOLBOXDIR + LONG + ".py"
+    scanner = MyScanner(input, output, defsoutput)
+    scanner.scan()
+    scanner.close()
+    scanner.gentypetest(SHORT+"typetest.py")
+    print "=== Testing definitions output code ==="
+    execfile(defsoutput, {}, {})
+    print "=== Done scanning and generating, now importing the generated code... ==="
+    exec "import " + SHORT + "support"
+    print "=== Done.  It's up to you to compile it now! ==="
+
+class MyScanner(Scanner_OSX):
+
+    def destination(self, type, name, arglist):
+        classname = "Function"
+        listname = "functions"
+        if arglist:
+            t, n, m = arglist[0]
+            # This is non-functional today
+            if t == OBJECT and m == "InMode":
+                classname = "Method"
+                listname = "methods"
+        return classname, listname
+
+    def makeblacklistnames(self):
+        return [
+                "FindFolderExtended", # Has funny void* argument
+                "FSFindFolderExtended", # ditto
+                "FolderManagerRegisterCallNotificationProcs", # ditto
+
+                "FindFolderEx", # Non-MacOS routine
+                ]
+
+    def makeblacklisttypes(self):
+        return [
+                "FolderManagerNotificationProcPtr",
+                "FolderManagerNotificationUPP",
+                "FolderRouting", # To be done, not difficult
+                "FolderDesc", # To be done, not difficult
+
+                ]
+
+    def makerepairinstructions(self):
+        return [
+                ]
+
+    def writeinitialdefs(self):
+        self.defsfile.write("def FOUR_CHAR_CODE(x): return x\n")
+        self.defsfile.write("true = True\n")
+        self.defsfile.write("false = False\n")
+
+if __name__ == "__main__":
+    main()

Added: vendor/Python/current/Mac/Modules/folder/foldersupport.py
===================================================================
--- vendor/Python/current/Mac/Modules/folder/foldersupport.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/folder/foldersupport.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,56 @@
+# This script generates a Python interface for an Apple Macintosh Manager.
+# It uses the "bgen" package to generate C code.
+# The function specifications are generated by scanning the mamager's header file,
+# using the "scantools" package (customized for this particular manager).
+
+import string
+
+# Declarations that change for each manager
+MACHEADERFILE = 'Folders.h'             # The Apple header file
+MODNAME = '_Folder'                             # The name of the module
+
+# The following is *usually* unchanged but may still require tuning
+MODPREFIX = 'Folder'                    # The prefix for module-wide routines
+INPUTFILE = string.lower(MODPREFIX) + 'gen.py' # The file generated by the scanner
+OUTPUTFILE = MODNAME + "module.c"       # The file generated by this program
+
+from macsupport import *
+
+# Create the type objects
+ConstStrFileNameParam = ConstStr255Param
+StrFileName = Str255
+FolderClass = OSTypeType("FolderClass")
+# FolderDesc
+FolderDescFlags = Type("FolderDescFlags", "l")
+FolderLocation = OSTypeType("FolderLocation")
+# FolderRouting
+FolderType = OSTypeType("FolderType")
+RoutingFlags = Type("RoutingFlags", "l")
+
+
+includestuff = includestuff + """
+#include <Carbon/Carbon.h>
+
+"""
+
+execfile(string.lower(MODPREFIX) + 'typetest.py')
+
+# From here on it's basically all boiler plate...
+
+# Create the generator groups and link them
+module = MacModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff)
+
+# Create the generator classes used to populate the lists
+Function = OSErrFunctionGenerator
+
+# Create and populate the lists
+functions = []
+execfile(INPUTFILE)
+
+# add the populated lists to the generator groups
+# (in a different wordl the scan program would generate this)
+for f in functions: module.add(f)
+
+# generate output (open the output file as late as possible)
+SetOutputFileName(OUTPUTFILE)
+module.generate()

Added: vendor/Python/current/Mac/Modules/gestaltmodule.c
===================================================================
--- vendor/Python/current/Mac/Modules/gestaltmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/gestaltmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,55 @@
+/***********************************************************
+Copyright 1991-1997 by Stichting Mathematisch Centrum, Amsterdam,
+The Netherlands.
+
+                        All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its 
+documentation for any purpose and without fee is hereby granted, 
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in 
+supporting documentation, and that the names of Stichting Mathematisch
+Centrum or CWI not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior permission.
+
+STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
+THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
+FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+******************************************************************/
+
+/* Macintosh Gestalt interface */
+
+#include "Python.h"
+#include "pymactoolbox.h"
+
+#include <Carbon/Carbon.h>
+
+static PyObject *
+gestalt_gestalt(PyObject *self, PyObject *args)
+{
+	OSErr iErr;
+	OSType selector;
+	long response;
+	if (!PyArg_ParseTuple(args, "O&", PyMac_GetOSType, &selector))
+		return NULL;
+	iErr = Gestalt ( selector, &response );
+	if (iErr != 0) 
+		return PyMac_Error(iErr);
+	return PyInt_FromLong(response);
+}
+
+static struct PyMethodDef gestalt_methods[] = {
+	{"gestalt", gestalt_gestalt, METH_VARARGS},
+	{NULL, NULL} /* Sentinel */
+};
+
+void
+initgestalt(void)
+{
+	Py_InitModule("gestalt", gestalt_methods);
+}

Added: vendor/Python/current/Mac/Modules/help/_Helpmodule.c
===================================================================
--- vendor/Python/current/Mac/Modules/help/_Helpmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/help/_Helpmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,187 @@
+
+/* ========================== Module _Help ========================== */
+
+#include "Python.h"
+
+
+
+#include "pymactoolbox.h"
+
+/* Macro to test whether a weak-loaded CFM function exists */
+#define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL )  {\
+        PyErr_SetString(PyExc_NotImplementedError, \
+        "Not available in this shared library/OS version"); \
+        return NULL; \
+    }} while(0)
+
+
+#include <Carbon/Carbon.h>
+
+static PyObject *Help_Error;
+
+static PyObject *Help_HMGetHelpMenu(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	MenuRef outHelpMenu;
+	MenuItemIndex outFirstCustomItemIndex;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = HMGetHelpMenu(&outHelpMenu,
+	                     &outFirstCustomItemIndex);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&H",
+	                     MenuObj_New, outHelpMenu,
+	                     outFirstCustomItemIndex);
+	return _res;
+}
+
+static PyObject *Help_HMAreHelpTagsDisplayed(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = HMAreHelpTagsDisplayed();
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Help_HMSetHelpTagsDisplayed(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Boolean inDisplayTags;
+	if (!PyArg_ParseTuple(_args, "b",
+	                      &inDisplayTags))
+		return NULL;
+	_err = HMSetHelpTagsDisplayed(inDisplayTags);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Help_HMSetTagDelay(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Duration inDelay;
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &inDelay))
+		return NULL;
+	_err = HMSetTagDelay(inDelay);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Help_HMGetTagDelay(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Duration outDelay;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = HMGetTagDelay(&outDelay);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     outDelay);
+	return _res;
+}
+
+static PyObject *Help_HMSetMenuHelpFromBalloonRsrc(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	MenuRef inMenu;
+	SInt16 inHmnuRsrcID;
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      MenuObj_Convert, &inMenu,
+	                      &inHmnuRsrcID))
+		return NULL;
+	_err = HMSetMenuHelpFromBalloonRsrc(inMenu,
+	                                    inHmnuRsrcID);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Help_HMSetDialogHelpFromBalloonRsrc(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	DialogPtr inDialog;
+	SInt16 inHdlgRsrcID;
+	SInt16 inItemStart;
+	if (!PyArg_ParseTuple(_args, "O&hh",
+	                      DlgObj_Convert, &inDialog,
+	                      &inHdlgRsrcID,
+	                      &inItemStart))
+		return NULL;
+	_err = HMSetDialogHelpFromBalloonRsrc(inDialog,
+	                                      inHdlgRsrcID,
+	                                      inItemStart);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Help_HMHideTag(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = HMHideTag();
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyMethodDef Help_methods[] = {
+	{"HMGetHelpMenu", (PyCFunction)Help_HMGetHelpMenu, 1,
+	 PyDoc_STR("() -> (MenuRef outHelpMenu, MenuItemIndex outFirstCustomItemIndex)")},
+	{"HMAreHelpTagsDisplayed", (PyCFunction)Help_HMAreHelpTagsDisplayed, 1,
+	 PyDoc_STR("() -> (Boolean _rv)")},
+	{"HMSetHelpTagsDisplayed", (PyCFunction)Help_HMSetHelpTagsDisplayed, 1,
+	 PyDoc_STR("(Boolean inDisplayTags) -> None")},
+	{"HMSetTagDelay", (PyCFunction)Help_HMSetTagDelay, 1,
+	 PyDoc_STR("(Duration inDelay) -> None")},
+	{"HMGetTagDelay", (PyCFunction)Help_HMGetTagDelay, 1,
+	 PyDoc_STR("() -> (Duration outDelay)")},
+	{"HMSetMenuHelpFromBalloonRsrc", (PyCFunction)Help_HMSetMenuHelpFromBalloonRsrc, 1,
+	 PyDoc_STR("(MenuRef inMenu, SInt16 inHmnuRsrcID) -> None")},
+	{"HMSetDialogHelpFromBalloonRsrc", (PyCFunction)Help_HMSetDialogHelpFromBalloonRsrc, 1,
+	 PyDoc_STR("(DialogPtr inDialog, SInt16 inHdlgRsrcID, SInt16 inItemStart) -> None")},
+	{"HMHideTag", (PyCFunction)Help_HMHideTag, 1,
+	 PyDoc_STR("() -> None")},
+	{NULL, NULL, 0}
+};
+
+
+
+
+void init_Help(void)
+{
+	PyObject *m;
+	PyObject *d;
+
+
+
+
+	m = Py_InitModule("_Help", Help_methods);
+	d = PyModule_GetDict(m);
+	Help_Error = PyMac_GetOSErrException();
+	if (Help_Error == NULL ||
+	    PyDict_SetItemString(d, "Error", Help_Error) != 0)
+		return;
+}
+
+/* ======================== End module _Help ======================== */
+

Added: vendor/Python/current/Mac/Modules/help/helpscan.py
===================================================================
--- vendor/Python/current/Mac/Modules/help/helpscan.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/help/helpscan.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,67 @@
+# Scan an Apple header file, generating a Python file of generator calls.
+
+import sys
+import os
+from bgenlocations import TOOLBOXDIR, BGENDIR
+sys.path.append(BGENDIR)
+from scantools import Scanner
+
+LONG = "MacHelp"
+SHORT = "help"
+OBJECT = "NOTUSED"
+
+def main():
+    input = LONG + ".h"
+    output = SHORT + "gen.py"
+    defsoutput = TOOLBOXDIR + LONG + ".py"
+    scanner = MyScanner(input, output, defsoutput)
+    scanner.scan()
+    scanner.close()
+    print "=== Testing definitions output code ==="
+    execfile(defsoutput, {}, {})
+    print "=== Done scanning and generating, now importing the generated code... ==="
+    exec "import " + SHORT + "support"
+    print "=== Done.  It's up to you to compile it now! ==="
+
+class MyScanner(Scanner):
+
+    def destination(self, type, name, arglist):
+        classname = "Function"
+        listname = "functions"
+        if arglist:
+            t, n, m = arglist[0]
+            # This is non-functional today
+            if t == OBJECT and m == "InMode":
+                classname = "Method"
+                listname = "methods"
+        return classname, listname
+
+    def writeinitialdefs(self):
+        self.defsfile.write("def FOUR_CHAR_CODE(x): return x\n")
+
+    def makeblacklistnames(self):
+        return [
+                ]
+
+    def makeblacklisttypes(self):
+        return [
+##                      "TipFunctionUPP",
+##                      "HMMessageRecord",
+##                      "HMMessageRecord_ptr",
+                "HMWindowContentUPP",
+                "HMMenuTitleContentUPP",
+                "HMControlContentUPP",
+                "HMMenuItemContentUPP",
+                # For the moment
+                "HMHelpContentRec",
+                "HMHelpContentRec_ptr",
+                ]
+
+    def makerepairinstructions(self):
+        return [
+##                      ([("WindowPtr", "*", "OutMode")],
+##                       [("ExistingWindowPtr", "*", "*")]),
+                ]
+
+if __name__ == "__main__":
+    main()

Added: vendor/Python/current/Mac/Modules/help/helpsupport.py
===================================================================
--- vendor/Python/current/Mac/Modules/help/helpsupport.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/help/helpsupport.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,78 @@
+# This script generates a Python interface for an Apple Macintosh Manager.
+# It uses the "bgen" package to generate C code.
+# The function specifications are generated by scanning the mamager's header file,
+# using the "scantools" package (customized for this particular manager).
+
+import string
+
+# Declarations that change for each manager
+MODNAME = '_Help'                               # The name of the module
+OBJECTNAME = 'UNUSED'                   # The basic name of the objects used here
+KIND = 'Record'                         # Usually 'Ptr' or 'Handle'
+
+# The following is *usually* unchanged but may still require tuning
+MODPREFIX = 'Help'                      # The prefix for module-wide routines
+OBJECTTYPE = OBJECTNAME + KIND          # The C type used to represent them
+OBJECTPREFIX = MODPREFIX + 'Obj'        # The prefix for object methods
+INPUTFILE = string.lower(MODPREFIX) + 'gen.py' # The file generated by the scanner
+OUTPUTFILE = MODNAME + "module.c"       # The file generated by this program
+
+from macsupport import *
+
+# Create the type objects
+MenuRef = OpaqueByValueType("MenuRef", "MenuObj")
+MenuItemIndex = Type("MenuItemIndex", "H")
+
+#WindowPeek = OpaqueByValueType("WindowPeek", OBJECTPREFIX)
+
+#RgnHandle = FakeType("(RgnHandle)0")
+# XXXX Should be next, but this will break a lot of code...
+# RgnHandle = OpaqueByValueType("RgnHandle", "OptResObj")
+
+#KeyMap = ArrayOutputBufferType("KeyMap")
+##MacOSEventKind = Type("MacOSEventKind", "h") # Old-style
+##MacOSEventMask = Type("MacOSEventMask", "h") # Old-style
+#EventMask = Type("EventMask", "H")
+#EventKind = Type("EventKind", "H")
+
+includestuff = includestuff + """
+#include <Carbon/Carbon.h>
+"""
+
+class MyObjectDefinition(PEP253Mixin, GlobalObjectDefinition):
+    def outputCheckNewArg(self):
+        Output("if (itself == NULL) return PyMac_Error(resNotFound);")
+    def outputCheckConvertArg(self):
+        OutLbrace("if (DlgObj_Check(v))")
+        Output("*p_itself = ((WindowObject *)v)->ob_itself;")
+        Output("return 1;")
+        OutRbrace()
+        Out("""
+        if (v == Py_None) { *p_itself = NULL; return 1; }
+        if (PyInt_Check(v)) { *p_itself = (WindowPtr)PyInt_AsLong(v); return 1; }
+        """)
+
+# From here on it's basically all boiler plate...
+
+# Create the generator groups and link them
+module = MacModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff)
+##object = MyObjectDefinition(OBJECTNAME, OBJECTPREFIX, OBJECTTYPE)
+##module.addobject(object)
+
+# Create the generator classes used to populate the lists
+Function = OSErrFunctionGenerator
+##Method = OSErrMethodGenerator
+
+# Create and populate the lists
+functions = []
+##methods = []
+execfile(INPUTFILE)
+
+# add the populated lists to the generator groups
+# (in a different wordl the scan program would generate this)
+for f in functions: module.add(f)
+##for f in methods: object.add(f)
+
+# generate output (open the output file as late as possible)
+SetOutputFileName(OUTPUTFILE)
+module.generate()

Added: vendor/Python/current/Mac/Modules/ibcarbon/IBCarbonscan.py
===================================================================
--- vendor/Python/current/Mac/Modules/ibcarbon/IBCarbonscan.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/ibcarbon/IBCarbonscan.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,49 @@
+# IBCarbonscan.py
+
+import sys
+import os
+import string
+
+from bgenlocations import TOOLBOXDIR, BGENDIR
+sys.path.append(BGENDIR)
+
+from scantools import Scanner_OSX
+
+def main():
+    print "---Scanning IBCarbonRuntime.h---"
+    input = ["IBCarbonRuntime.h"]
+    output = "IBCarbongen.py"
+    defsoutput = TOOLBOXDIR + "IBCarbonRuntime.py"
+    scanner = IBCarbon_Scanner(input, output, defsoutput)
+    scanner.scan()
+    scanner.close()
+    print "=== Testing definitions output code ==="
+    execfile(defsoutput, {}, {})
+    print "--done scanning, importing--"
+    import IBCarbonsupport
+    print "done"
+
+class IBCarbon_Scanner(Scanner_OSX):
+
+    def destination(self, type, name, arglist):
+        classname = "IBCarbonFunction"
+        listname = "functions"
+        if arglist:
+            t, n, m = arglist[0]
+            if t == "IBNibRef" and m == "InMode":
+                classname = "IBCarbonMethod"
+                listname = "methods"
+        return classname, listname
+
+    def makeblacklistnames(self):
+        return [
+                "DisposeNibReference",                          # taken care of by destructor
+                "CreateNibReferenceWithCFBundle",  ## need to wrap CFBundle.h properly first
+                ]
+
+    def makerepairinstructions(self):
+        return []
+
+
+if __name__ == "__main__":
+    main()

Added: vendor/Python/current/Mac/Modules/ibcarbon/IBCarbonsupport.py
===================================================================
--- vendor/Python/current/Mac/Modules/ibcarbon/IBCarbonsupport.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/ibcarbon/IBCarbonsupport.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,51 @@
+# IBCarbonsupport.py
+
+from macsupport import *
+
+IBNibRef = OpaqueByValueType('IBNibRef', 'IBNibRefObj')
+#CFBundleRef = OpaqueByValueType('CFBundleRef')
+
+IBCarbonFunction = OSErrFunctionGenerator
+IBCarbonMethod = OSErrMethodGenerator
+
+includestuff = """
+#include <Carbon/Carbon.h>
+#include "pymactoolbox.h"
+
+#ifdef USE_TOOLBOX_OBJECT_GLUE
+extern int _CFStringRefObj_Convert(PyObject *, CFStringRef *);
+#endif
+
+"""
+
+initstuff = """
+
+"""
+
+module = MacModule('_IBCarbon', 'IBCarbon', includestuff, finalstuff, initstuff)
+
+class CFReleaserObject(PEP253Mixin, GlobalObjectDefinition):
+    def outputFreeIt(self, name):
+        Output("CFRelease(%s);" % name)
+
+class CFNibDesc(PEP253Mixin, GlobalObjectDefinition):
+    def outputFreeIt(self, name):
+        Output("DisposeNibReference(%s);" % name)
+
+#cfstringobject = CFReleaserObject("CFStringRef")
+#module.addobject(cfstringobject)
+#cfbundleobject = CFReleaserObject("CFBundleRef")
+#module.addobject(cfbundleobject)
+ibnibobject = CFNibDesc("IBNibRef", "IBNibRefObj")
+module.addobject(ibnibobject)
+
+functions = []
+methods = []
+
+execfile('IBCarbongen.py')
+
+for f in functions: module.add(f)
+for m in methods: ibnibobject.add(m)
+
+SetOutputFileName('_IBCarbon.c')
+module.generate()

Added: vendor/Python/current/Mac/Modules/ibcarbon/_IBCarbon.c
===================================================================
--- vendor/Python/current/Mac/Modules/ibcarbon/_IBCarbon.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/ibcarbon/_IBCarbon.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,262 @@
+
+/* ======================== Module _IBCarbon ======================== */
+
+#include "Python.h"
+
+
+
+#include <Carbon/Carbon.h>
+#include "pymactoolbox.h"
+
+#ifdef USE_TOOLBOX_OBJECT_GLUE
+extern int _CFStringRefObj_Convert(PyObject *, CFStringRef *);
+#endif
+
+
+static PyObject *IBCarbon_Error;
+
+/* ---------------------- Object type IBNibRef ---------------------- */
+
+PyTypeObject IBNibRef_Type;
+
+#define IBNibRefObj_Check(x) ((x)->ob_type == &IBNibRef_Type || PyObject_TypeCheck((x), &IBNibRef_Type))
+
+typedef struct IBNibRefObject {
+	PyObject_HEAD
+	IBNibRef ob_itself;
+} IBNibRefObject;
+
+PyObject *IBNibRefObj_New(IBNibRef itself)
+{
+	IBNibRefObject *it;
+	it = PyObject_NEW(IBNibRefObject, &IBNibRef_Type);
+	if (it == NULL) return NULL;
+	it->ob_itself = itself;
+	return (PyObject *)it;
+}
+
+int IBNibRefObj_Convert(PyObject *v, IBNibRef *p_itself)
+{
+	if (!IBNibRefObj_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "IBNibRef required");
+		return 0;
+	}
+	*p_itself = ((IBNibRefObject *)v)->ob_itself;
+	return 1;
+}
+
+static void IBNibRefObj_dealloc(IBNibRefObject *self)
+{
+	DisposeNibReference(self->ob_itself);
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *IBNibRefObj_CreateWindowFromNib(IBNibRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	CFStringRef inName;
+	WindowPtr outWindow;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CFStringRefObj_Convert, &inName))
+		return NULL;
+	_err = CreateWindowFromNib(_self->ob_itself,
+	                           inName,
+	                           &outWindow);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     WinObj_New, outWindow);
+	return _res;
+}
+
+static PyObject *IBNibRefObj_CreateMenuFromNib(IBNibRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	CFStringRef inName;
+	MenuHandle outMenuRef;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CFStringRefObj_Convert, &inName))
+		return NULL;
+	_err = CreateMenuFromNib(_self->ob_itself,
+	                         inName,
+	                         &outMenuRef);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     MenuObj_New, outMenuRef);
+	return _res;
+}
+
+static PyObject *IBNibRefObj_CreateMenuBarFromNib(IBNibRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	CFStringRef inName;
+	Handle outMenuBar;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CFStringRefObj_Convert, &inName))
+		return NULL;
+	_err = CreateMenuBarFromNib(_self->ob_itself,
+	                            inName,
+	                            &outMenuBar);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, outMenuBar);
+	return _res;
+}
+
+static PyObject *IBNibRefObj_SetMenuBarFromNib(IBNibRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	CFStringRef inName;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CFStringRefObj_Convert, &inName))
+		return NULL;
+	_err = SetMenuBarFromNib(_self->ob_itself,
+	                         inName);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyMethodDef IBNibRefObj_methods[] = {
+	{"CreateWindowFromNib", (PyCFunction)IBNibRefObj_CreateWindowFromNib, 1,
+	 PyDoc_STR("(CFStringRef inName) -> (WindowPtr outWindow)")},
+	{"CreateMenuFromNib", (PyCFunction)IBNibRefObj_CreateMenuFromNib, 1,
+	 PyDoc_STR("(CFStringRef inName) -> (MenuHandle outMenuRef)")},
+	{"CreateMenuBarFromNib", (PyCFunction)IBNibRefObj_CreateMenuBarFromNib, 1,
+	 PyDoc_STR("(CFStringRef inName) -> (Handle outMenuBar)")},
+	{"SetMenuBarFromNib", (PyCFunction)IBNibRefObj_SetMenuBarFromNib, 1,
+	 PyDoc_STR("(CFStringRef inName) -> None")},
+	{NULL, NULL, 0}
+};
+
+#define IBNibRefObj_getsetlist NULL
+
+
+#define IBNibRefObj_compare NULL
+
+#define IBNibRefObj_repr NULL
+
+#define IBNibRefObj_hash NULL
+#define IBNibRefObj_tp_init 0
+
+#define IBNibRefObj_tp_alloc PyType_GenericAlloc
+
+static PyObject *IBNibRefObj_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *_self;
+	IBNibRef itself;
+	char *kw[] = {"itself", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, IBNibRefObj_Convert, &itself)) return NULL;
+	if ((_self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	((IBNibRefObject *)_self)->ob_itself = itself;
+	return _self;
+}
+
+#define IBNibRefObj_tp_free PyObject_Del
+
+
+PyTypeObject IBNibRef_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"_IBCarbon.IBNibRef", /*tp_name*/
+	sizeof(IBNibRefObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) IBNibRefObj_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) IBNibRefObj_compare, /*tp_compare*/
+	(reprfunc) IBNibRefObj_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) IBNibRefObj_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	IBNibRefObj_methods, /* tp_methods */
+	0, /*tp_members*/
+	IBNibRefObj_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	IBNibRefObj_tp_init, /* tp_init */
+	IBNibRefObj_tp_alloc, /* tp_alloc */
+	IBNibRefObj_tp_new, /* tp_new */
+	IBNibRefObj_tp_free, /* tp_free */
+};
+
+/* -------------------- End object type IBNibRef -------------------- */
+
+
+static PyObject *IBCarbon_CreateNibReference(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	CFStringRef inNibName;
+	IBNibRef outNibRef;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CFStringRefObj_Convert, &inNibName))
+		return NULL;
+	_err = CreateNibReference(inNibName,
+	                          &outNibRef);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     IBNibRefObj_New, outNibRef);
+	return _res;
+}
+
+static PyMethodDef IBCarbon_methods[] = {
+	{"CreateNibReference", (PyCFunction)IBCarbon_CreateNibReference, 1,
+	 PyDoc_STR("(CFStringRef inNibName) -> (IBNibRef outNibRef)")},
+	{NULL, NULL, 0}
+};
+
+
+
+
+void init_IBCarbon(void)
+{
+	PyObject *m;
+	PyObject *d;
+
+
+
+
+
+	m = Py_InitModule("_IBCarbon", IBCarbon_methods);
+	d = PyModule_GetDict(m);
+	IBCarbon_Error = PyMac_GetOSErrException();
+	if (IBCarbon_Error == NULL ||
+	    PyDict_SetItemString(d, "Error", IBCarbon_Error) != 0)
+		return;
+	IBNibRef_Type.ob_type = &PyType_Type;
+	if (PyType_Ready(&IBNibRef_Type) < 0) return;
+	Py_INCREF(&IBNibRef_Type);
+	PyModule_AddObject(m, "IBNibRef", (PyObject *)&IBNibRef_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&IBNibRef_Type);
+	PyModule_AddObject(m, "IBNibRefType", (PyObject *)&IBNibRef_Type);
+}
+
+/* ====================== End module _IBCarbon ====================== */
+

Added: vendor/Python/current/Mac/Modules/icgluemodule.c
===================================================================
--- vendor/Python/current/Mac/Modules/icgluemodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/icgluemodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,475 @@
+/***********************************************************
+Copyright 1991-1997 by Stichting Mathematisch Centrum, Amsterdam,
+The Netherlands.
+
+                        All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the names of Stichting Mathematisch
+Centrum or CWI or Corporation for National Research Initiatives or
+CNRI not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+While CWI is the initial source for this software, a modified version
+is made available by the Corporation for National Research Initiatives
+(CNRI) at the Internet address ftp://ftp.python.org.
+
+STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
+CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+
+******************************************************************/
+
+#include "Python.h"
+#include "pymactoolbox.h"
+
+extern int ResObj_Convert(PyObject *, Handle *); /* From Resmodule.c */
+
+#include <Carbon/Carbon.h>
+
+static PyObject *ErrorObject;
+
+/* ----------------------------------------------------- */
+
+/* Declarations for objects of type ic_instance */
+
+typedef struct {
+	PyObject_HEAD
+	ICInstance inst;
+} iciobject;
+
+static PyTypeObject Icitype;
+
+
+
+/* ---------------------------------------------------------------- */
+
+
+static char ici_ICGetSeed__doc__[] = 
+"()->int; Returns int that changes when configuration does"
+;
+
+static PyObject *
+ici_ICGetSeed(iciobject *self, PyObject *args)
+{
+	OSStatus err;
+	long seed;
+	
+	if (!PyArg_ParseTuple(args, ""))
+		return NULL;
+	if ((err=ICGetSeed(self->inst, &seed)) != 0 )
+		return PyMac_Error(err);
+	return Py_BuildValue("i", (int)seed);
+}
+
+
+static char ici_ICBegin__doc__[] = 
+"(perm)->None; Lock config file for read/write"
+;
+
+static PyObject *
+ici_ICBegin(iciobject *self, PyObject *args)
+{
+	OSStatus err;
+	int perm;
+	
+	if (!PyArg_ParseTuple(args, "i", &perm))
+		return NULL;
+	if ((err=ICBegin(self->inst, (ICPerm)perm)) != 0 )
+		return PyMac_Error(err);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+
+static char ici_ICFindPrefHandle__doc__[] = 
+"(key, handle)->attrs; Lookup key, store result in handle, return attributes"
+;
+
+static PyObject *
+ici_ICFindPrefHandle(iciobject *self, PyObject *args)
+{
+	OSStatus err;
+	Str255 key;
+	ICAttr attr;
+	Handle h;
+	
+	if (!PyArg_ParseTuple(args, "O&O&", PyMac_GetStr255, &key, ResObj_Convert, &h))
+		return NULL;
+	if ((err=ICFindPrefHandle(self->inst, key, &attr, h)) != 0 )
+		return PyMac_Error(err);
+	return Py_BuildValue("i", (int)attr);
+}
+
+
+static char ici_ICSetPref__doc__[] = 
+"(key, attr, data)->None; Set preference key to data with attributes"
+;
+
+static PyObject *
+ici_ICSetPref(iciobject *self, PyObject *args)
+{
+	OSStatus err;
+	Str255 key;
+	int attr;
+	char *data;
+	int datalen;
+	
+	if (!PyArg_ParseTuple(args, "O&is#", PyMac_GetStr255, &key, &attr, 
+					&data, &datalen))
+		return NULL;
+	if ((err=ICSetPref(self->inst, key, (ICAttr)attr, (Ptr)data, 
+			(long)datalen)) != 0)
+		return PyMac_Error(err);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+
+static char ici_ICCountPref__doc__[] = 
+"()->int; Return number of preferences"
+;
+
+static PyObject *
+ici_ICCountPref(iciobject *self, PyObject *args)
+{
+	OSStatus err;
+	long count;
+	
+	if (!PyArg_ParseTuple(args, ""))
+		return NULL;
+	if ((err=ICCountPref(self->inst, &count)) != 0 )
+		return PyMac_Error(err);
+	return Py_BuildValue("i", (int)count);
+}
+
+
+static char ici_ICGetIndPref__doc__[] = 
+"(num)->key; Return key of preference with given index"
+;
+
+static PyObject *
+ici_ICGetIndPref(iciobject *self, PyObject *args)
+{
+	OSStatus err;
+	long num;
+	Str255 key;
+	
+	if (!PyArg_ParseTuple(args, "l", &num))
+		return NULL;
+	if ((err=ICGetIndPref(self->inst, num, key)) != 0 )
+		return PyMac_Error(err);
+	return Py_BuildValue("O&", PyMac_BuildStr255, key);
+}
+
+
+static char ici_ICDeletePref__doc__[] = 
+"(key)->None; Delete preference"
+;
+
+static PyObject *
+ici_ICDeletePref(iciobject *self, PyObject *args)
+{
+	OSStatus err;
+	Str255 key;
+
+	if (!PyArg_ParseTuple(args, "O&", PyMac_GetStr255, key))
+		return NULL;
+	if ((err=ICDeletePref(self->inst, key)) != 0 )
+		return PyMac_Error(err);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+
+static char ici_ICEnd__doc__[] = 
+"()->None; Unlock file after ICBegin call"
+;
+
+static PyObject *
+ici_ICEnd(iciobject *self, PyObject *args)
+{
+	OSStatus err;
+	
+	if (!PyArg_ParseTuple(args, ""))
+		return NULL;
+	if ((err=ICEnd(self->inst)) != 0 )
+		return PyMac_Error(err);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+
+static char ici_ICEditPreferences__doc__[] = 
+"(key)->None; Ask user to edit preferences, staring with key"
+;
+
+static PyObject *
+ici_ICEditPreferences(iciobject *self, PyObject *args)
+{
+	OSStatus err;
+	Str255 key;
+	
+	if (!PyArg_ParseTuple(args, "O&", PyMac_GetStr255, key))
+		return NULL;
+	if ((err=ICEditPreferences(self->inst, key)) != 0 )
+		return PyMac_Error(err);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+
+static char ici_ICParseURL__doc__[] = 
+"(hint, data, selStart, selEnd, handle)->selStart, selEnd; Find an URL, return in handle"
+;
+
+static PyObject *
+ici_ICParseURL(iciobject *self, PyObject *args)
+{
+	OSStatus err;
+	Str255 hint;
+	char *data;
+	int datalen;
+	long selStart, selEnd;
+	Handle h;
+	
+	if (!PyArg_ParseTuple(args, "O&s#llO&", PyMac_GetStr255, hint, &data, &datalen,
+				&selStart, &selEnd, ResObj_Convert, &h))
+		return NULL;
+	if ((err=ICParseURL(self->inst, hint, (Ptr)data, (long)datalen,
+				&selStart, &selEnd, h)) != 0 )
+		return PyMac_Error(err);
+	return Py_BuildValue("ii", (int)selStart, (int)selEnd);
+}
+
+
+static char ici_ICLaunchURL__doc__[] = 
+"(hint, data, selStart, selEnd)->None; Find an URL and launch the correct app"
+;
+
+static PyObject *
+ici_ICLaunchURL(iciobject *self, PyObject *args)
+{
+	OSStatus err;
+	Str255 hint;
+	char *data;
+	int datalen;
+	long selStart, selEnd;
+	
+	if (!PyArg_ParseTuple(args, "O&s#ll", PyMac_GetStr255, hint, &data, &datalen,
+				&selStart, &selEnd))
+		return NULL;
+	if ((err=ICLaunchURL(self->inst, hint, (Ptr)data, (long)datalen,
+				&selStart, &selEnd)) != 0 )
+		return PyMac_Error(err);
+	return Py_BuildValue("ii", (int)selStart, (int)selEnd);
+}
+
+
+static char ici_ICMapFilename__doc__[] = 
+"(filename)->mapinfo; Get filemap info for given filename"
+;
+
+static PyObject *
+ici_ICMapFilename(iciobject *self, PyObject *args)
+{
+	OSStatus err;
+	Str255 filename;
+	ICMapEntry entry;
+	
+	if (!PyArg_ParseTuple(args, "O&", PyMac_GetStr255, filename))
+		return NULL;
+	if ((err=ICMapFilename(self->inst, filename, &entry)) != 0 )
+		return PyMac_Error(err);
+	return Py_BuildValue("hO&O&O&lO&O&O&O&O&", entry.version, 
+		PyMac_BuildOSType, entry.fileType,
+		PyMac_BuildOSType, entry.fileCreator, 
+		PyMac_BuildOSType, entry.postCreator, 
+		entry.flags,
+		PyMac_BuildStr255, entry.extension,
+		PyMac_BuildStr255, entry.creatorAppName,
+		PyMac_BuildStr255, entry.postAppName,
+		PyMac_BuildStr255, entry.MIMEType,
+		PyMac_BuildStr255, entry.entryName);
+}
+
+
+static char ici_ICMapTypeCreator__doc__[] = 
+"(type, creator, filename)->mapinfo; Get filemap info for given tp/cr/filename"
+;
+
+static PyObject *
+ici_ICMapTypeCreator(iciobject *self, PyObject *args)
+{
+	OSStatus err;
+	OSType type, creator;
+	Str255 filename;
+	ICMapEntry entry;
+	
+	if (!PyArg_ParseTuple(args, "O&O&O&",
+			PyMac_GetOSType, &type,
+			PyMac_GetOSType, &creator,
+			PyMac_GetStr255, filename))
+		return NULL;
+	if ((err=ICMapTypeCreator(self->inst, type, creator, filename, &entry)) != 0 )
+		return PyMac_Error(err);
+	return Py_BuildValue("hO&O&O&lO&O&O&O&O&", entry.version, 
+		PyMac_BuildOSType, entry.fileType,
+		PyMac_BuildOSType, entry.fileCreator, 
+		PyMac_BuildOSType, entry.postCreator, 
+		entry.flags,
+		PyMac_BuildStr255, entry.extension,
+		PyMac_BuildStr255, entry.creatorAppName,
+		PyMac_BuildStr255, entry.postAppName,
+		PyMac_BuildStr255, entry.MIMEType,
+		PyMac_BuildStr255, entry.entryName);
+}
+
+
+static struct PyMethodDef ici_methods[] = {
+ {"ICGetSeed",	(PyCFunction)ici_ICGetSeed,	METH_VARARGS,	ici_ICGetSeed__doc__},
+ {"ICBegin",	(PyCFunction)ici_ICBegin,	METH_VARARGS,	ici_ICBegin__doc__},
+ {"ICFindPrefHandle",	(PyCFunction)ici_ICFindPrefHandle,	METH_VARARGS,	ici_ICFindPrefHandle__doc__},
+ {"ICSetPref",	(PyCFunction)ici_ICSetPref,	METH_VARARGS,	ici_ICSetPref__doc__},
+ {"ICCountPref",	(PyCFunction)ici_ICCountPref,	METH_VARARGS,	ici_ICCountPref__doc__},
+ {"ICGetIndPref",	(PyCFunction)ici_ICGetIndPref,	METH_VARARGS,	ici_ICGetIndPref__doc__},
+ {"ICDeletePref",	(PyCFunction)ici_ICDeletePref,	METH_VARARGS,	ici_ICDeletePref__doc__},
+ {"ICEnd",	(PyCFunction)ici_ICEnd,	METH_VARARGS,	ici_ICEnd__doc__},
+ {"ICEditPreferences",	(PyCFunction)ici_ICEditPreferences,	METH_VARARGS,	ici_ICEditPreferences__doc__},
+ {"ICParseURL",	(PyCFunction)ici_ICParseURL,	METH_VARARGS,	ici_ICParseURL__doc__},
+ {"ICLaunchURL",	(PyCFunction)ici_ICLaunchURL,	METH_VARARGS,	ici_ICLaunchURL__doc__},
+ {"ICMapFilename",	(PyCFunction)ici_ICMapFilename,	METH_VARARGS,	ici_ICMapFilename__doc__},
+ {"ICMapTypeCreator",	(PyCFunction)ici_ICMapTypeCreator,	METH_VARARGS,	ici_ICMapTypeCreator__doc__},
+ 
+	{NULL,		NULL}		/* sentinel */
+};
+
+/* ---------- */
+
+
+static iciobject *
+newiciobject(OSType creator)
+{
+	iciobject *self;
+	OSStatus err;
+	
+	self = PyObject_NEW(iciobject, &Icitype);
+	if (self == NULL)
+		return NULL;
+	if ((err=ICStart(&self->inst, creator)) != 0 ) {
+		(void)PyMac_Error(err);
+		PyObject_DEL(self);
+		return NULL;
+	}
+	return self;
+}
+
+
+static void
+ici_dealloc(iciobject *self)
+{
+	(void)ICStop(self->inst);
+	PyObject_DEL(self);
+}
+
+static PyObject *
+ici_getattr(iciobject *self, char *name)
+{
+	return Py_FindMethod(ici_methods, (PyObject *)self, name);
+}
+
+static char Icitype__doc__[] = 
+"Internet Config instance"
+;
+
+static PyTypeObject Icitype = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,				/*ob_size*/
+	"icglue.ic_instance",		/*tp_name*/
+	sizeof(iciobject),		/*tp_basicsize*/
+	0,				/*tp_itemsize*/
+	/* methods */
+	(destructor)ici_dealloc,	/*tp_dealloc*/
+	(printfunc)0,		/*tp_print*/
+	(getattrfunc)ici_getattr,	/*tp_getattr*/
+	(setattrfunc)0,	/*tp_setattr*/
+	(cmpfunc)0,		/*tp_compare*/
+	(reprfunc)0,		/*tp_repr*/
+	0,			/*tp_as_number*/
+	0,		/*tp_as_sequence*/
+	0,		/*tp_as_mapping*/
+	(hashfunc)0,		/*tp_hash*/
+	(ternaryfunc)0,		/*tp_call*/
+	(reprfunc)0,		/*tp_str*/
+
+	/* Space for future expansion */
+	0L,0L,0L,0L,
+	Icitype__doc__ /* Documentation string */
+};
+
+/* End of code for ic_instance objects */
+/* -------------------------------------------------------- */
+
+
+static char ic_ICStart__doc__[] =
+"(OSType)->ic_instance; Create an Internet Config instance"
+;
+
+static PyObject *
+ic_ICStart(PyObject *self, PyObject *args)
+{
+	OSType creator;
+
+	if (!PyArg_ParseTuple(args, "O&", PyMac_GetOSType, &creator))
+		return NULL;
+	return (PyObject *)newiciobject(creator);
+}
+
+/* List of methods defined in the module */
+
+static struct PyMethodDef ic_methods[] = {
+	{"ICStart",	(PyCFunction)ic_ICStart,	METH_VARARGS,	ic_ICStart__doc__},
+ 
+	{NULL,	 (PyCFunction)NULL, 0, NULL}		/* sentinel */
+};
+
+
+/* Initialization function for the module (*must* be called initicglue) */
+
+static char icglue_module_documentation[] = 
+"Implements low-level Internet Config interface"
+;
+
+void
+initicglue(void)
+{
+	PyObject *m, *d;
+
+	/* Create the module and add the functions */
+	m = Py_InitModule4("icglue", ic_methods,
+		icglue_module_documentation,
+		(PyObject*)NULL,PYTHON_API_VERSION);
+
+	/* Add some symbolic constants to the module */
+	d = PyModule_GetDict(m);
+	ErrorObject = PyMac_GetOSErrException();
+	if (ErrorObject == NULL ||
+	    PyDict_SetItemString(d, "error", ErrorObject) != 0)
+		return;
+
+	/* XXXX Add constants here */
+	
+	/* Check for errors */
+	if (PyErr_Occurred())
+		Py_FatalError("can't initialize module icglue");
+}
+

Added: vendor/Python/current/Mac/Modules/icn/_Icnmodule.c
===================================================================
--- vendor/Python/current/Mac/Modules/icn/_Icnmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/icn/_Icnmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1599 @@
+
+/* ========================== Module _Icn =========================== */
+
+#include "Python.h"
+
+
+
+#include "pymactoolbox.h"
+
+/* Macro to test whether a weak-loaded CFM function exists */
+#define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL )  {\
+        PyErr_SetString(PyExc_NotImplementedError, \
+        "Not available in this shared library/OS version"); \
+        return NULL; \
+    }} while(0)
+
+
+#include <Carbon/Carbon.h>
+
+
+static PyObject *Icn_Error;
+
+static PyObject *Icn_GetCIcon(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CIconHandle _rv;
+	SInt16 iconID;
+#ifndef GetCIcon
+	PyMac_PRECHECK(GetCIcon);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &iconID))
+		return NULL;
+	_rv = GetCIcon(iconID);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Icn_PlotCIcon(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect theRect;
+	CIconHandle theIcon;
+#ifndef PlotCIcon
+	PyMac_PRECHECK(PlotCIcon);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetRect, &theRect,
+	                      ResObj_Convert, &theIcon))
+		return NULL;
+	PlotCIcon(&theRect,
+	          theIcon);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Icn_DisposeCIcon(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CIconHandle theIcon;
+#ifndef DisposeCIcon
+	PyMac_PRECHECK(DisposeCIcon);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &theIcon))
+		return NULL;
+	DisposeCIcon(theIcon);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Icn_GetIcon(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Handle _rv;
+	SInt16 iconID;
+#ifndef GetIcon
+	PyMac_PRECHECK(GetIcon);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &iconID))
+		return NULL;
+	_rv = GetIcon(iconID);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Icn_PlotIcon(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect theRect;
+	Handle theIcon;
+#ifndef PlotIcon
+	PyMac_PRECHECK(PlotIcon);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetRect, &theRect,
+	                      ResObj_Convert, &theIcon))
+		return NULL;
+	PlotIcon(&theRect,
+	         theIcon);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Icn_PlotIconID(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Rect theRect;
+	IconAlignmentType align;
+	IconTransformType transform;
+	SInt16 theResID;
+#ifndef PlotIconID
+	PyMac_PRECHECK(PlotIconID);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hhh",
+	                      PyMac_GetRect, &theRect,
+	                      &align,
+	                      &transform,
+	                      &theResID))
+		return NULL;
+	_err = PlotIconID(&theRect,
+	                  align,
+	                  transform,
+	                  theResID);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Icn_NewIconSuite(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	IconSuiteRef theIconSuite;
+#ifndef NewIconSuite
+	PyMac_PRECHECK(NewIconSuite);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = NewIconSuite(&theIconSuite);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, theIconSuite);
+	return _res;
+}
+
+static PyObject *Icn_AddIconToSuite(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Handle theIconData;
+	IconSuiteRef theSuite;
+	ResType theType;
+#ifndef AddIconToSuite
+	PyMac_PRECHECK(AddIconToSuite);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      ResObj_Convert, &theIconData,
+	                      ResObj_Convert, &theSuite,
+	                      PyMac_GetOSType, &theType))
+		return NULL;
+	_err = AddIconToSuite(theIconData,
+	                      theSuite,
+	                      theType);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Icn_GetIconFromSuite(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Handle theIconData;
+	IconSuiteRef theSuite;
+	ResType theType;
+#ifndef GetIconFromSuite
+	PyMac_PRECHECK(GetIconFromSuite);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      ResObj_Convert, &theSuite,
+	                      PyMac_GetOSType, &theType))
+		return NULL;
+	_err = GetIconFromSuite(&theIconData,
+	                        theSuite,
+	                        theType);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, theIconData);
+	return _res;
+}
+
+static PyObject *Icn_GetIconSuite(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	IconSuiteRef theIconSuite;
+	SInt16 theResID;
+	IconSelectorValue selector;
+#ifndef GetIconSuite
+	PyMac_PRECHECK(GetIconSuite);
+#endif
+	if (!PyArg_ParseTuple(_args, "hl",
+	                      &theResID,
+	                      &selector))
+		return NULL;
+	_err = GetIconSuite(&theIconSuite,
+	                    theResID,
+	                    selector);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, theIconSuite);
+	return _res;
+}
+
+static PyObject *Icn_DisposeIconSuite(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	IconSuiteRef theIconSuite;
+	Boolean disposeData;
+#ifndef DisposeIconSuite
+	PyMac_PRECHECK(DisposeIconSuite);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&b",
+	                      ResObj_Convert, &theIconSuite,
+	                      &disposeData))
+		return NULL;
+	_err = DisposeIconSuite(theIconSuite,
+	                        disposeData);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Icn_PlotIconSuite(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Rect theRect;
+	IconAlignmentType align;
+	IconTransformType transform;
+	IconSuiteRef theIconSuite;
+#ifndef PlotIconSuite
+	PyMac_PRECHECK(PlotIconSuite);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hhO&",
+	                      PyMac_GetRect, &theRect,
+	                      &align,
+	                      &transform,
+	                      ResObj_Convert, &theIconSuite))
+		return NULL;
+	_err = PlotIconSuite(&theRect,
+	                     align,
+	                     transform,
+	                     theIconSuite);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Icn_LoadIconCache(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Rect theRect;
+	IconAlignmentType align;
+	IconTransformType transform;
+	IconCacheRef theIconCache;
+#ifndef LoadIconCache
+	PyMac_PRECHECK(LoadIconCache);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hhO&",
+	                      PyMac_GetRect, &theRect,
+	                      &align,
+	                      &transform,
+	                      ResObj_Convert, &theIconCache))
+		return NULL;
+	_err = LoadIconCache(&theRect,
+	                     align,
+	                     transform,
+	                     theIconCache);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Icn_GetLabel(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SInt16 labelNumber;
+	RGBColor labelColor;
+	Str255 labelString;
+#ifndef GetLabel
+	PyMac_PRECHECK(GetLabel);
+#endif
+	if (!PyArg_ParseTuple(_args, "hO&",
+	                      &labelNumber,
+	                      PyMac_GetStr255, labelString))
+		return NULL;
+	_err = GetLabel(labelNumber,
+	                &labelColor,
+	                labelString);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     QdRGB_New, &labelColor);
+	return _res;
+}
+
+static PyObject *Icn_PtInIconID(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	Point testPt;
+	Rect iconRect;
+	IconAlignmentType align;
+	SInt16 iconID;
+#ifndef PtInIconID
+	PyMac_PRECHECK(PtInIconID);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&hh",
+	                      PyMac_GetPoint, &testPt,
+	                      PyMac_GetRect, &iconRect,
+	                      &align,
+	                      &iconID))
+		return NULL;
+	_rv = PtInIconID(testPt,
+	                 &iconRect,
+	                 align,
+	                 iconID);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Icn_PtInIconSuite(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	Point testPt;
+	Rect iconRect;
+	IconAlignmentType align;
+	IconSuiteRef theIconSuite;
+#ifndef PtInIconSuite
+	PyMac_PRECHECK(PtInIconSuite);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&hO&",
+	                      PyMac_GetPoint, &testPt,
+	                      PyMac_GetRect, &iconRect,
+	                      &align,
+	                      ResObj_Convert, &theIconSuite))
+		return NULL;
+	_rv = PtInIconSuite(testPt,
+	                    &iconRect,
+	                    align,
+	                    theIconSuite);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Icn_RectInIconID(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	Rect testRect;
+	Rect iconRect;
+	IconAlignmentType align;
+	SInt16 iconID;
+#ifndef RectInIconID
+	PyMac_PRECHECK(RectInIconID);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&hh",
+	                      PyMac_GetRect, &testRect,
+	                      PyMac_GetRect, &iconRect,
+	                      &align,
+	                      &iconID))
+		return NULL;
+	_rv = RectInIconID(&testRect,
+	                   &iconRect,
+	                   align,
+	                   iconID);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Icn_RectInIconSuite(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	Rect testRect;
+	Rect iconRect;
+	IconAlignmentType align;
+	IconSuiteRef theIconSuite;
+#ifndef RectInIconSuite
+	PyMac_PRECHECK(RectInIconSuite);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&hO&",
+	                      PyMac_GetRect, &testRect,
+	                      PyMac_GetRect, &iconRect,
+	                      &align,
+	                      ResObj_Convert, &theIconSuite))
+		return NULL;
+	_rv = RectInIconSuite(&testRect,
+	                      &iconRect,
+	                      align,
+	                      theIconSuite);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Icn_IconIDToRgn(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	RgnHandle theRgn;
+	Rect iconRect;
+	IconAlignmentType align;
+	SInt16 iconID;
+#ifndef IconIDToRgn
+	PyMac_PRECHECK(IconIDToRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&hh",
+	                      ResObj_Convert, &theRgn,
+	                      PyMac_GetRect, &iconRect,
+	                      &align,
+	                      &iconID))
+		return NULL;
+	_err = IconIDToRgn(theRgn,
+	                   &iconRect,
+	                   align,
+	                   iconID);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Icn_IconSuiteToRgn(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	RgnHandle theRgn;
+	Rect iconRect;
+	IconAlignmentType align;
+	IconSuiteRef theIconSuite;
+#ifndef IconSuiteToRgn
+	PyMac_PRECHECK(IconSuiteToRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&hO&",
+	                      ResObj_Convert, &theRgn,
+	                      PyMac_GetRect, &iconRect,
+	                      &align,
+	                      ResObj_Convert, &theIconSuite))
+		return NULL;
+	_err = IconSuiteToRgn(theRgn,
+	                      &iconRect,
+	                      align,
+	                      theIconSuite);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Icn_SetSuiteLabel(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	IconSuiteRef theSuite;
+	SInt16 theLabel;
+#ifndef SetSuiteLabel
+	PyMac_PRECHECK(SetSuiteLabel);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      ResObj_Convert, &theSuite,
+	                      &theLabel))
+		return NULL;
+	_err = SetSuiteLabel(theSuite,
+	                     theLabel);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Icn_GetSuiteLabel(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	SInt16 _rv;
+	IconSuiteRef theSuite;
+#ifndef GetSuiteLabel
+	PyMac_PRECHECK(GetSuiteLabel);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &theSuite))
+		return NULL;
+	_rv = GetSuiteLabel(theSuite);
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Icn_PlotIconHandle(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Rect theRect;
+	IconAlignmentType align;
+	IconTransformType transform;
+	Handle theIcon;
+#ifndef PlotIconHandle
+	PyMac_PRECHECK(PlotIconHandle);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hhO&",
+	                      PyMac_GetRect, &theRect,
+	                      &align,
+	                      &transform,
+	                      ResObj_Convert, &theIcon))
+		return NULL;
+	_err = PlotIconHandle(&theRect,
+	                      align,
+	                      transform,
+	                      theIcon);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Icn_PlotSICNHandle(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Rect theRect;
+	IconAlignmentType align;
+	IconTransformType transform;
+	Handle theSICN;
+#ifndef PlotSICNHandle
+	PyMac_PRECHECK(PlotSICNHandle);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hhO&",
+	                      PyMac_GetRect, &theRect,
+	                      &align,
+	                      &transform,
+	                      ResObj_Convert, &theSICN))
+		return NULL;
+	_err = PlotSICNHandle(&theRect,
+	                      align,
+	                      transform,
+	                      theSICN);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Icn_PlotCIconHandle(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Rect theRect;
+	IconAlignmentType align;
+	IconTransformType transform;
+	CIconHandle theCIcon;
+#ifndef PlotCIconHandle
+	PyMac_PRECHECK(PlotCIconHandle);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hhO&",
+	                      PyMac_GetRect, &theRect,
+	                      &align,
+	                      &transform,
+	                      ResObj_Convert, &theCIcon))
+		return NULL;
+	_err = PlotCIconHandle(&theRect,
+	                       align,
+	                       transform,
+	                       theCIcon);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Icn_IconRefToIconFamily(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	IconRef theIconRef;
+	IconSelectorValue whichIcons;
+	IconFamilyHandle iconFamily;
+#ifndef IconRefToIconFamily
+	PyMac_PRECHECK(IconRefToIconFamily);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      ResObj_Convert, &theIconRef,
+	                      &whichIcons))
+		return NULL;
+	_err = IconRefToIconFamily(theIconRef,
+	                           whichIcons,
+	                           &iconFamily);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, iconFamily);
+	return _res;
+}
+
+static PyObject *Icn_IconFamilyToIconSuite(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	IconFamilyHandle iconFamily;
+	IconSelectorValue whichIcons;
+	IconSuiteRef iconSuite;
+#ifndef IconFamilyToIconSuite
+	PyMac_PRECHECK(IconFamilyToIconSuite);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      ResObj_Convert, &iconFamily,
+	                      &whichIcons))
+		return NULL;
+	_err = IconFamilyToIconSuite(iconFamily,
+	                             whichIcons,
+	                             &iconSuite);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, iconSuite);
+	return _res;
+}
+
+static PyObject *Icn_IconSuiteToIconFamily(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	IconSuiteRef iconSuite;
+	IconSelectorValue whichIcons;
+	IconFamilyHandle iconFamily;
+#ifndef IconSuiteToIconFamily
+	PyMac_PRECHECK(IconSuiteToIconFamily);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      ResObj_Convert, &iconSuite,
+	                      &whichIcons))
+		return NULL;
+	_err = IconSuiteToIconFamily(iconSuite,
+	                             whichIcons,
+	                             &iconFamily);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, iconFamily);
+	return _res;
+}
+
+static PyObject *Icn_SetIconFamilyData(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	IconFamilyHandle iconFamily;
+	OSType iconType;
+	Handle h;
+#ifndef SetIconFamilyData
+	PyMac_PRECHECK(SetIconFamilyData);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      ResObj_Convert, &iconFamily,
+	                      PyMac_GetOSType, &iconType,
+	                      ResObj_Convert, &h))
+		return NULL;
+	_err = SetIconFamilyData(iconFamily,
+	                         iconType,
+	                         h);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Icn_GetIconFamilyData(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	IconFamilyHandle iconFamily;
+	OSType iconType;
+	Handle h;
+#ifndef GetIconFamilyData
+	PyMac_PRECHECK(GetIconFamilyData);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      ResObj_Convert, &iconFamily,
+	                      PyMac_GetOSType, &iconType,
+	                      ResObj_Convert, &h))
+		return NULL;
+	_err = GetIconFamilyData(iconFamily,
+	                         iconType,
+	                         h);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Icn_GetIconRefOwners(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	IconRef theIconRef;
+	UInt16 owners;
+#ifndef GetIconRefOwners
+	PyMac_PRECHECK(GetIconRefOwners);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &theIconRef))
+		return NULL;
+	_err = GetIconRefOwners(theIconRef,
+	                        &owners);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("H",
+	                     owners);
+	return _res;
+}
+
+static PyObject *Icn_AcquireIconRef(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	IconRef theIconRef;
+#ifndef AcquireIconRef
+	PyMac_PRECHECK(AcquireIconRef);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &theIconRef))
+		return NULL;
+	_err = AcquireIconRef(theIconRef);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Icn_ReleaseIconRef(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	IconRef theIconRef;
+#ifndef ReleaseIconRef
+	PyMac_PRECHECK(ReleaseIconRef);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &theIconRef))
+		return NULL;
+	_err = ReleaseIconRef(theIconRef);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Icn_GetIconRefFromFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	FSSpec theFile;
+	IconRef theIconRef;
+	SInt16 theLabel;
+#ifndef GetIconRefFromFile
+	PyMac_PRECHECK(GetIconRefFromFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetFSSpec, &theFile))
+		return NULL;
+	_err = GetIconRefFromFile(&theFile,
+	                          &theIconRef,
+	                          &theLabel);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&h",
+	                     ResObj_New, theIconRef,
+	                     theLabel);
+	return _res;
+}
+
+static PyObject *Icn_GetIconRef(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SInt16 vRefNum;
+	OSType creator;
+	OSType iconType;
+	IconRef theIconRef;
+#ifndef GetIconRef
+	PyMac_PRECHECK(GetIconRef);
+#endif
+	if (!PyArg_ParseTuple(_args, "hO&O&",
+	                      &vRefNum,
+	                      PyMac_GetOSType, &creator,
+	                      PyMac_GetOSType, &iconType))
+		return NULL;
+	_err = GetIconRef(vRefNum,
+	                  creator,
+	                  iconType,
+	                  &theIconRef);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, theIconRef);
+	return _res;
+}
+
+static PyObject *Icn_GetIconRefFromFolder(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SInt16 vRefNum;
+	SInt32 parentFolderID;
+	SInt32 folderID;
+	SInt8 attributes;
+	SInt8 accessPrivileges;
+	IconRef theIconRef;
+#ifndef GetIconRefFromFolder
+	PyMac_PRECHECK(GetIconRefFromFolder);
+#endif
+	if (!PyArg_ParseTuple(_args, "hllbb",
+	                      &vRefNum,
+	                      &parentFolderID,
+	                      &folderID,
+	                      &attributes,
+	                      &accessPrivileges))
+		return NULL;
+	_err = GetIconRefFromFolder(vRefNum,
+	                            parentFolderID,
+	                            folderID,
+	                            attributes,
+	                            accessPrivileges,
+	                            &theIconRef);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, theIconRef);
+	return _res;
+}
+
+static PyObject *Icn_RegisterIconRefFromIconFamily(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	OSType creator;
+	OSType iconType;
+	IconFamilyHandle iconFamily;
+	IconRef theIconRef;
+#ifndef RegisterIconRefFromIconFamily
+	PyMac_PRECHECK(RegisterIconRefFromIconFamily);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      PyMac_GetOSType, &creator,
+	                      PyMac_GetOSType, &iconType,
+	                      ResObj_Convert, &iconFamily))
+		return NULL;
+	_err = RegisterIconRefFromIconFamily(creator,
+	                                     iconType,
+	                                     iconFamily,
+	                                     &theIconRef);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, theIconRef);
+	return _res;
+}
+
+static PyObject *Icn_RegisterIconRefFromResource(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	OSType creator;
+	OSType iconType;
+	FSSpec resourceFile;
+	SInt16 resourceID;
+	IconRef theIconRef;
+#ifndef RegisterIconRefFromResource
+	PyMac_PRECHECK(RegisterIconRefFromResource);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&h",
+	                      PyMac_GetOSType, &creator,
+	                      PyMac_GetOSType, &iconType,
+	                      PyMac_GetFSSpec, &resourceFile,
+	                      &resourceID))
+		return NULL;
+	_err = RegisterIconRefFromResource(creator,
+	                                   iconType,
+	                                   &resourceFile,
+	                                   resourceID,
+	                                   &theIconRef);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, theIconRef);
+	return _res;
+}
+
+static PyObject *Icn_RegisterIconRefFromFSRef(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	OSType creator;
+	OSType iconType;
+	FSRef iconFile;
+	IconRef theIconRef;
+#ifndef RegisterIconRefFromFSRef
+	PyMac_PRECHECK(RegisterIconRefFromFSRef);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      PyMac_GetOSType, &creator,
+	                      PyMac_GetOSType, &iconType,
+	                      PyMac_GetFSRef, &iconFile))
+		return NULL;
+	_err = RegisterIconRefFromFSRef(creator,
+	                                iconType,
+	                                &iconFile,
+	                                &theIconRef);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, theIconRef);
+	return _res;
+}
+
+static PyObject *Icn_UnregisterIconRef(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	OSType creator;
+	OSType iconType;
+#ifndef UnregisterIconRef
+	PyMac_PRECHECK(UnregisterIconRef);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetOSType, &creator,
+	                      PyMac_GetOSType, &iconType))
+		return NULL;
+	_err = UnregisterIconRef(creator,
+	                         iconType);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Icn_UpdateIconRef(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	IconRef theIconRef;
+#ifndef UpdateIconRef
+	PyMac_PRECHECK(UpdateIconRef);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &theIconRef))
+		return NULL;
+	_err = UpdateIconRef(theIconRef);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Icn_OverrideIconRefFromResource(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	IconRef theIconRef;
+	FSSpec resourceFile;
+	SInt16 resourceID;
+#ifndef OverrideIconRefFromResource
+	PyMac_PRECHECK(OverrideIconRefFromResource);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&h",
+	                      ResObj_Convert, &theIconRef,
+	                      PyMac_GetFSSpec, &resourceFile,
+	                      &resourceID))
+		return NULL;
+	_err = OverrideIconRefFromResource(theIconRef,
+	                                   &resourceFile,
+	                                   resourceID);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Icn_OverrideIconRef(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	IconRef oldIconRef;
+	IconRef newIconRef;
+#ifndef OverrideIconRef
+	PyMac_PRECHECK(OverrideIconRef);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      ResObj_Convert, &oldIconRef,
+	                      ResObj_Convert, &newIconRef))
+		return NULL;
+	_err = OverrideIconRef(oldIconRef,
+	                       newIconRef);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Icn_RemoveIconRefOverride(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	IconRef theIconRef;
+#ifndef RemoveIconRefOverride
+	PyMac_PRECHECK(RemoveIconRefOverride);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &theIconRef))
+		return NULL;
+	_err = RemoveIconRefOverride(theIconRef);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Icn_CompositeIconRef(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	IconRef backgroundIconRef;
+	IconRef foregroundIconRef;
+	IconRef compositeIconRef;
+#ifndef CompositeIconRef
+	PyMac_PRECHECK(CompositeIconRef);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      ResObj_Convert, &backgroundIconRef,
+	                      ResObj_Convert, &foregroundIconRef))
+		return NULL;
+	_err = CompositeIconRef(backgroundIconRef,
+	                        foregroundIconRef,
+	                        &compositeIconRef);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, compositeIconRef);
+	return _res;
+}
+
+static PyObject *Icn_IsIconRefComposite(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	IconRef compositeIconRef;
+	IconRef backgroundIconRef;
+	IconRef foregroundIconRef;
+#ifndef IsIconRefComposite
+	PyMac_PRECHECK(IsIconRefComposite);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &compositeIconRef))
+		return NULL;
+	_err = IsIconRefComposite(compositeIconRef,
+	                          &backgroundIconRef,
+	                          &foregroundIconRef);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&O&",
+	                     ResObj_New, backgroundIconRef,
+	                     ResObj_New, foregroundIconRef);
+	return _res;
+}
+
+static PyObject *Icn_IsValidIconRef(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	IconRef theIconRef;
+#ifndef IsValidIconRef
+	PyMac_PRECHECK(IsValidIconRef);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &theIconRef))
+		return NULL;
+	_rv = IsValidIconRef(theIconRef);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Icn_PlotIconRef(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Rect theRect;
+	IconAlignmentType align;
+	IconTransformType transform;
+	IconServicesUsageFlags theIconServicesUsageFlags;
+	IconRef theIconRef;
+#ifndef PlotIconRef
+	PyMac_PRECHECK(PlotIconRef);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hhlO&",
+	                      PyMac_GetRect, &theRect,
+	                      &align,
+	                      &transform,
+	                      &theIconServicesUsageFlags,
+	                      ResObj_Convert, &theIconRef))
+		return NULL;
+	_err = PlotIconRef(&theRect,
+	                   align,
+	                   transform,
+	                   theIconServicesUsageFlags,
+	                   theIconRef);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Icn_PtInIconRef(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	Point testPt;
+	Rect iconRect;
+	IconAlignmentType align;
+	IconServicesUsageFlags theIconServicesUsageFlags;
+	IconRef theIconRef;
+#ifndef PtInIconRef
+	PyMac_PRECHECK(PtInIconRef);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&hlO&",
+	                      PyMac_GetPoint, &testPt,
+	                      PyMac_GetRect, &iconRect,
+	                      &align,
+	                      &theIconServicesUsageFlags,
+	                      ResObj_Convert, &theIconRef))
+		return NULL;
+	_rv = PtInIconRef(&testPt,
+	                  &iconRect,
+	                  align,
+	                  theIconServicesUsageFlags,
+	                  theIconRef);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Icn_RectInIconRef(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	Rect testRect;
+	Rect iconRect;
+	IconAlignmentType align;
+	IconServicesUsageFlags iconServicesUsageFlags;
+	IconRef theIconRef;
+#ifndef RectInIconRef
+	PyMac_PRECHECK(RectInIconRef);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&hlO&",
+	                      PyMac_GetRect, &testRect,
+	                      PyMac_GetRect, &iconRect,
+	                      &align,
+	                      &iconServicesUsageFlags,
+	                      ResObj_Convert, &theIconRef))
+		return NULL;
+	_rv = RectInIconRef(&testRect,
+	                    &iconRect,
+	                    align,
+	                    iconServicesUsageFlags,
+	                    theIconRef);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Icn_IconRefToRgn(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	RgnHandle theRgn;
+	Rect iconRect;
+	IconAlignmentType align;
+	IconServicesUsageFlags iconServicesUsageFlags;
+	IconRef theIconRef;
+#ifndef IconRefToRgn
+	PyMac_PRECHECK(IconRefToRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&hlO&",
+	                      ResObj_Convert, &theRgn,
+	                      PyMac_GetRect, &iconRect,
+	                      &align,
+	                      &iconServicesUsageFlags,
+	                      ResObj_Convert, &theIconRef))
+		return NULL;
+	_err = IconRefToRgn(theRgn,
+	                    &iconRect,
+	                    align,
+	                    iconServicesUsageFlags,
+	                    theIconRef);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Icn_GetIconSizesFromIconRef(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	IconSelectorValue iconSelectorInput;
+	IconSelectorValue iconSelectorOutputPtr;
+	IconServicesUsageFlags iconServicesUsageFlags;
+	IconRef theIconRef;
+#ifndef GetIconSizesFromIconRef
+	PyMac_PRECHECK(GetIconSizesFromIconRef);
+#endif
+	if (!PyArg_ParseTuple(_args, "llO&",
+	                      &iconSelectorInput,
+	                      &iconServicesUsageFlags,
+	                      ResObj_Convert, &theIconRef))
+		return NULL;
+	_err = GetIconSizesFromIconRef(iconSelectorInput,
+	                               &iconSelectorOutputPtr,
+	                               iconServicesUsageFlags,
+	                               theIconRef);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     iconSelectorOutputPtr);
+	return _res;
+}
+
+static PyObject *Icn_FlushIconRefs(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	OSType creator;
+	OSType iconType;
+#ifndef FlushIconRefs
+	PyMac_PRECHECK(FlushIconRefs);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetOSType, &creator,
+	                      PyMac_GetOSType, &iconType))
+		return NULL;
+	_err = FlushIconRefs(creator,
+	                     iconType);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Icn_FlushIconRefsByVolume(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SInt16 vRefNum;
+#ifndef FlushIconRefsByVolume
+	PyMac_PRECHECK(FlushIconRefsByVolume);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &vRefNum))
+		return NULL;
+	_err = FlushIconRefsByVolume(vRefNum);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Icn_SetCustomIconsEnabled(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SInt16 vRefNum;
+	Boolean enableCustomIcons;
+#ifndef SetCustomIconsEnabled
+	PyMac_PRECHECK(SetCustomIconsEnabled);
+#endif
+	if (!PyArg_ParseTuple(_args, "hb",
+	                      &vRefNum,
+	                      &enableCustomIcons))
+		return NULL;
+	_err = SetCustomIconsEnabled(vRefNum,
+	                             enableCustomIcons);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Icn_GetCustomIconsEnabled(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SInt16 vRefNum;
+	Boolean customIconsEnabled;
+#ifndef GetCustomIconsEnabled
+	PyMac_PRECHECK(GetCustomIconsEnabled);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &vRefNum))
+		return NULL;
+	_err = GetCustomIconsEnabled(vRefNum,
+	                             &customIconsEnabled);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("b",
+	                     customIconsEnabled);
+	return _res;
+}
+
+static PyObject *Icn_IsIconRefMaskEmpty(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	IconRef iconRef;
+#ifndef IsIconRefMaskEmpty
+	PyMac_PRECHECK(IsIconRefMaskEmpty);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &iconRef))
+		return NULL;
+	_rv = IsIconRefMaskEmpty(iconRef);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Icn_GetIconRefVariant(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	IconRef _rv;
+	IconRef inIconRef;
+	OSType inVariant;
+	IconTransformType outTransform;
+#ifndef GetIconRefVariant
+	PyMac_PRECHECK(GetIconRefVariant);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      ResObj_Convert, &inIconRef,
+	                      PyMac_GetOSType, &inVariant))
+		return NULL;
+	_rv = GetIconRefVariant(inIconRef,
+	                        inVariant,
+	                        &outTransform);
+	_res = Py_BuildValue("O&h",
+	                     ResObj_New, _rv,
+	                     outTransform);
+	return _res;
+}
+
+static PyObject *Icn_RegisterIconRefFromIconFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	OSType creator;
+	OSType iconType;
+	FSSpec iconFile;
+	IconRef theIconRef;
+#ifndef RegisterIconRefFromIconFile
+	PyMac_PRECHECK(RegisterIconRefFromIconFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      PyMac_GetOSType, &creator,
+	                      PyMac_GetOSType, &iconType,
+	                      PyMac_GetFSSpec, &iconFile))
+		return NULL;
+	_err = RegisterIconRefFromIconFile(creator,
+	                                   iconType,
+	                                   &iconFile,
+	                                   &theIconRef);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, theIconRef);
+	return _res;
+}
+
+static PyObject *Icn_ReadIconFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	FSSpec iconFile;
+	IconFamilyHandle iconFamily;
+#ifndef ReadIconFile
+	PyMac_PRECHECK(ReadIconFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetFSSpec, &iconFile))
+		return NULL;
+	_err = ReadIconFile(&iconFile,
+	                    &iconFamily);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, iconFamily);
+	return _res;
+}
+
+static PyObject *Icn_ReadIconFromFSRef(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	FSRef ref;
+	IconFamilyHandle iconFamily;
+#ifndef ReadIconFromFSRef
+	PyMac_PRECHECK(ReadIconFromFSRef);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetFSRef, &ref))
+		return NULL;
+	_err = ReadIconFromFSRef(&ref,
+	                         &iconFamily);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, iconFamily);
+	return _res;
+}
+
+static PyObject *Icn_WriteIconFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	IconFamilyHandle iconFamily;
+	FSSpec iconFile;
+#ifndef WriteIconFile
+	PyMac_PRECHECK(WriteIconFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      ResObj_Convert, &iconFamily,
+	                      PyMac_GetFSSpec, &iconFile))
+		return NULL;
+	_err = WriteIconFile(iconFamily,
+	                     &iconFile);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyMethodDef Icn_methods[] = {
+	{"GetCIcon", (PyCFunction)Icn_GetCIcon, 1,
+	 PyDoc_STR("(SInt16 iconID) -> (CIconHandle _rv)")},
+	{"PlotCIcon", (PyCFunction)Icn_PlotCIcon, 1,
+	 PyDoc_STR("(Rect theRect, CIconHandle theIcon) -> None")},
+	{"DisposeCIcon", (PyCFunction)Icn_DisposeCIcon, 1,
+	 PyDoc_STR("(CIconHandle theIcon) -> None")},
+	{"GetIcon", (PyCFunction)Icn_GetIcon, 1,
+	 PyDoc_STR("(SInt16 iconID) -> (Handle _rv)")},
+	{"PlotIcon", (PyCFunction)Icn_PlotIcon, 1,
+	 PyDoc_STR("(Rect theRect, Handle theIcon) -> None")},
+	{"PlotIconID", (PyCFunction)Icn_PlotIconID, 1,
+	 PyDoc_STR("(Rect theRect, IconAlignmentType align, IconTransformType transform, SInt16 theResID) -> None")},
+	{"NewIconSuite", (PyCFunction)Icn_NewIconSuite, 1,
+	 PyDoc_STR("() -> (IconSuiteRef theIconSuite)")},
+	{"AddIconToSuite", (PyCFunction)Icn_AddIconToSuite, 1,
+	 PyDoc_STR("(Handle theIconData, IconSuiteRef theSuite, ResType theType) -> None")},
+	{"GetIconFromSuite", (PyCFunction)Icn_GetIconFromSuite, 1,
+	 PyDoc_STR("(IconSuiteRef theSuite, ResType theType) -> (Handle theIconData)")},
+	{"GetIconSuite", (PyCFunction)Icn_GetIconSuite, 1,
+	 PyDoc_STR("(SInt16 theResID, IconSelectorValue selector) -> (IconSuiteRef theIconSuite)")},
+	{"DisposeIconSuite", (PyCFunction)Icn_DisposeIconSuite, 1,
+	 PyDoc_STR("(IconSuiteRef theIconSuite, Boolean disposeData) -> None")},
+	{"PlotIconSuite", (PyCFunction)Icn_PlotIconSuite, 1,
+	 PyDoc_STR("(Rect theRect, IconAlignmentType align, IconTransformType transform, IconSuiteRef theIconSuite) -> None")},
+	{"LoadIconCache", (PyCFunction)Icn_LoadIconCache, 1,
+	 PyDoc_STR("(Rect theRect, IconAlignmentType align, IconTransformType transform, IconCacheRef theIconCache) -> None")},
+	{"GetLabel", (PyCFunction)Icn_GetLabel, 1,
+	 PyDoc_STR("(SInt16 labelNumber, Str255 labelString) -> (RGBColor labelColor)")},
+	{"PtInIconID", (PyCFunction)Icn_PtInIconID, 1,
+	 PyDoc_STR("(Point testPt, Rect iconRect, IconAlignmentType align, SInt16 iconID) -> (Boolean _rv)")},
+	{"PtInIconSuite", (PyCFunction)Icn_PtInIconSuite, 1,
+	 PyDoc_STR("(Point testPt, Rect iconRect, IconAlignmentType align, IconSuiteRef theIconSuite) -> (Boolean _rv)")},
+	{"RectInIconID", (PyCFunction)Icn_RectInIconID, 1,
+	 PyDoc_STR("(Rect testRect, Rect iconRect, IconAlignmentType align, SInt16 iconID) -> (Boolean _rv)")},
+	{"RectInIconSuite", (PyCFunction)Icn_RectInIconSuite, 1,
+	 PyDoc_STR("(Rect testRect, Rect iconRect, IconAlignmentType align, IconSuiteRef theIconSuite) -> (Boolean _rv)")},
+	{"IconIDToRgn", (PyCFunction)Icn_IconIDToRgn, 1,
+	 PyDoc_STR("(RgnHandle theRgn, Rect iconRect, IconAlignmentType align, SInt16 iconID) -> None")},
+	{"IconSuiteToRgn", (PyCFunction)Icn_IconSuiteToRgn, 1,
+	 PyDoc_STR("(RgnHandle theRgn, Rect iconRect, IconAlignmentType align, IconSuiteRef theIconSuite) -> None")},
+	{"SetSuiteLabel", (PyCFunction)Icn_SetSuiteLabel, 1,
+	 PyDoc_STR("(IconSuiteRef theSuite, SInt16 theLabel) -> None")},
+	{"GetSuiteLabel", (PyCFunction)Icn_GetSuiteLabel, 1,
+	 PyDoc_STR("(IconSuiteRef theSuite) -> (SInt16 _rv)")},
+	{"PlotIconHandle", (PyCFunction)Icn_PlotIconHandle, 1,
+	 PyDoc_STR("(Rect theRect, IconAlignmentType align, IconTransformType transform, Handle theIcon) -> None")},
+	{"PlotSICNHandle", (PyCFunction)Icn_PlotSICNHandle, 1,
+	 PyDoc_STR("(Rect theRect, IconAlignmentType align, IconTransformType transform, Handle theSICN) -> None")},
+	{"PlotCIconHandle", (PyCFunction)Icn_PlotCIconHandle, 1,
+	 PyDoc_STR("(Rect theRect, IconAlignmentType align, IconTransformType transform, CIconHandle theCIcon) -> None")},
+	{"IconRefToIconFamily", (PyCFunction)Icn_IconRefToIconFamily, 1,
+	 PyDoc_STR("(IconRef theIconRef, IconSelectorValue whichIcons) -> (IconFamilyHandle iconFamily)")},
+	{"IconFamilyToIconSuite", (PyCFunction)Icn_IconFamilyToIconSuite, 1,
+	 PyDoc_STR("(IconFamilyHandle iconFamily, IconSelectorValue whichIcons) -> (IconSuiteRef iconSuite)")},
+	{"IconSuiteToIconFamily", (PyCFunction)Icn_IconSuiteToIconFamily, 1,
+	 PyDoc_STR("(IconSuiteRef iconSuite, IconSelectorValue whichIcons) -> (IconFamilyHandle iconFamily)")},
+	{"SetIconFamilyData", (PyCFunction)Icn_SetIconFamilyData, 1,
+	 PyDoc_STR("(IconFamilyHandle iconFamily, OSType iconType, Handle h) -> None")},
+	{"GetIconFamilyData", (PyCFunction)Icn_GetIconFamilyData, 1,
+	 PyDoc_STR("(IconFamilyHandle iconFamily, OSType iconType, Handle h) -> None")},
+	{"GetIconRefOwners", (PyCFunction)Icn_GetIconRefOwners, 1,
+	 PyDoc_STR("(IconRef theIconRef) -> (UInt16 owners)")},
+	{"AcquireIconRef", (PyCFunction)Icn_AcquireIconRef, 1,
+	 PyDoc_STR("(IconRef theIconRef) -> None")},
+	{"ReleaseIconRef", (PyCFunction)Icn_ReleaseIconRef, 1,
+	 PyDoc_STR("(IconRef theIconRef) -> None")},
+	{"GetIconRefFromFile", (PyCFunction)Icn_GetIconRefFromFile, 1,
+	 PyDoc_STR("(FSSpec theFile) -> (IconRef theIconRef, SInt16 theLabel)")},
+	{"GetIconRef", (PyCFunction)Icn_GetIconRef, 1,
+	 PyDoc_STR("(SInt16 vRefNum, OSType creator, OSType iconType) -> (IconRef theIconRef)")},
+	{"GetIconRefFromFolder", (PyCFunction)Icn_GetIconRefFromFolder, 1,
+	 PyDoc_STR("(SInt16 vRefNum, SInt32 parentFolderID, SInt32 folderID, SInt8 attributes, SInt8 accessPrivileges) -> (IconRef theIconRef)")},
+	{"RegisterIconRefFromIconFamily", (PyCFunction)Icn_RegisterIconRefFromIconFamily, 1,
+	 PyDoc_STR("(OSType creator, OSType iconType, IconFamilyHandle iconFamily) -> (IconRef theIconRef)")},
+	{"RegisterIconRefFromResource", (PyCFunction)Icn_RegisterIconRefFromResource, 1,
+	 PyDoc_STR("(OSType creator, OSType iconType, FSSpec resourceFile, SInt16 resourceID) -> (IconRef theIconRef)")},
+	{"RegisterIconRefFromFSRef", (PyCFunction)Icn_RegisterIconRefFromFSRef, 1,
+	 PyDoc_STR("(OSType creator, OSType iconType, FSRef iconFile) -> (IconRef theIconRef)")},
+	{"UnregisterIconRef", (PyCFunction)Icn_UnregisterIconRef, 1,
+	 PyDoc_STR("(OSType creator, OSType iconType) -> None")},
+	{"UpdateIconRef", (PyCFunction)Icn_UpdateIconRef, 1,
+	 PyDoc_STR("(IconRef theIconRef) -> None")},
+	{"OverrideIconRefFromResource", (PyCFunction)Icn_OverrideIconRefFromResource, 1,
+	 PyDoc_STR("(IconRef theIconRef, FSSpec resourceFile, SInt16 resourceID) -> None")},
+	{"OverrideIconRef", (PyCFunction)Icn_OverrideIconRef, 1,
+	 PyDoc_STR("(IconRef oldIconRef, IconRef newIconRef) -> None")},
+	{"RemoveIconRefOverride", (PyCFunction)Icn_RemoveIconRefOverride, 1,
+	 PyDoc_STR("(IconRef theIconRef) -> None")},
+	{"CompositeIconRef", (PyCFunction)Icn_CompositeIconRef, 1,
+	 PyDoc_STR("(IconRef backgroundIconRef, IconRef foregroundIconRef) -> (IconRef compositeIconRef)")},
+	{"IsIconRefComposite", (PyCFunction)Icn_IsIconRefComposite, 1,
+	 PyDoc_STR("(IconRef compositeIconRef) -> (IconRef backgroundIconRef, IconRef foregroundIconRef)")},
+	{"IsValidIconRef", (PyCFunction)Icn_IsValidIconRef, 1,
+	 PyDoc_STR("(IconRef theIconRef) -> (Boolean _rv)")},
+	{"PlotIconRef", (PyCFunction)Icn_PlotIconRef, 1,
+	 PyDoc_STR("(Rect theRect, IconAlignmentType align, IconTransformType transform, IconServicesUsageFlags theIconServicesUsageFlags, IconRef theIconRef) -> None")},
+	{"PtInIconRef", (PyCFunction)Icn_PtInIconRef, 1,
+	 PyDoc_STR("(Point testPt, Rect iconRect, IconAlignmentType align, IconServicesUsageFlags theIconServicesUsageFlags, IconRef theIconRef) -> (Boolean _rv)")},
+	{"RectInIconRef", (PyCFunction)Icn_RectInIconRef, 1,
+	 PyDoc_STR("(Rect testRect, Rect iconRect, IconAlignmentType align, IconServicesUsageFlags iconServicesUsageFlags, IconRef theIconRef) -> (Boolean _rv)")},
+	{"IconRefToRgn", (PyCFunction)Icn_IconRefToRgn, 1,
+	 PyDoc_STR("(RgnHandle theRgn, Rect iconRect, IconAlignmentType align, IconServicesUsageFlags iconServicesUsageFlags, IconRef theIconRef) -> None")},
+	{"GetIconSizesFromIconRef", (PyCFunction)Icn_GetIconSizesFromIconRef, 1,
+	 PyDoc_STR("(IconSelectorValue iconSelectorInput, IconServicesUsageFlags iconServicesUsageFlags, IconRef theIconRef) -> (IconSelectorValue iconSelectorOutputPtr)")},
+	{"FlushIconRefs", (PyCFunction)Icn_FlushIconRefs, 1,
+	 PyDoc_STR("(OSType creator, OSType iconType) -> None")},
+	{"FlushIconRefsByVolume", (PyCFunction)Icn_FlushIconRefsByVolume, 1,
+	 PyDoc_STR("(SInt16 vRefNum) -> None")},
+	{"SetCustomIconsEnabled", (PyCFunction)Icn_SetCustomIconsEnabled, 1,
+	 PyDoc_STR("(SInt16 vRefNum, Boolean enableCustomIcons) -> None")},
+	{"GetCustomIconsEnabled", (PyCFunction)Icn_GetCustomIconsEnabled, 1,
+	 PyDoc_STR("(SInt16 vRefNum) -> (Boolean customIconsEnabled)")},
+	{"IsIconRefMaskEmpty", (PyCFunction)Icn_IsIconRefMaskEmpty, 1,
+	 PyDoc_STR("(IconRef iconRef) -> (Boolean _rv)")},
+	{"GetIconRefVariant", (PyCFunction)Icn_GetIconRefVariant, 1,
+	 PyDoc_STR("(IconRef inIconRef, OSType inVariant) -> (IconRef _rv, IconTransformType outTransform)")},
+	{"RegisterIconRefFromIconFile", (PyCFunction)Icn_RegisterIconRefFromIconFile, 1,
+	 PyDoc_STR("(OSType creator, OSType iconType, FSSpec iconFile) -> (IconRef theIconRef)")},
+	{"ReadIconFile", (PyCFunction)Icn_ReadIconFile, 1,
+	 PyDoc_STR("(FSSpec iconFile) -> (IconFamilyHandle iconFamily)")},
+	{"ReadIconFromFSRef", (PyCFunction)Icn_ReadIconFromFSRef, 1,
+	 PyDoc_STR("(FSRef ref) -> (IconFamilyHandle iconFamily)")},
+	{"WriteIconFile", (PyCFunction)Icn_WriteIconFile, 1,
+	 PyDoc_STR("(IconFamilyHandle iconFamily, FSSpec iconFile) -> None")},
+	{NULL, NULL, 0}
+};
+
+
+
+
+void init_Icn(void)
+{
+	PyObject *m;
+	PyObject *d;
+
+
+
+
+	m = Py_InitModule("_Icn", Icn_methods);
+	d = PyModule_GetDict(m);
+	Icn_Error = PyMac_GetOSErrException();
+	if (Icn_Error == NULL ||
+	    PyDict_SetItemString(d, "Error", Icn_Error) != 0)
+		return;
+}
+
+/* ======================== End module _Icn ========================= */
+

Added: vendor/Python/current/Mac/Modules/icn/icnscan.py
===================================================================
--- vendor/Python/current/Mac/Modules/icn/icnscan.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/icn/icnscan.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,72 @@
+# Scan an Apple header file, generating a Python file of generator calls.
+
+import sys
+import os
+from bgenlocations import TOOLBOXDIR, BGENDIR
+sys.path.append(BGENDIR)
+from scantools import Scanner
+
+LONG = "Icons"
+SHORT = "icn"
+OBJECT = "NOTUSED"
+
+def main():
+    input = LONG + ".h"
+    output = SHORT + "gen.py"
+    defsoutput = TOOLBOXDIR + LONG + ".py"
+    scanner = MyScanner(input, output, defsoutput)
+    scanner.scan()
+    scanner.close()
+    print "=== Testing definitions output code ==="
+    execfile(defsoutput, {}, {})
+    print "=== Done scanning and generating, now importing the generated code... ==="
+    exec "import " + SHORT + "support"
+    print "=== Done.  It's up to you to compile it now! ==="
+
+class MyScanner(Scanner):
+
+    def destination(self, type, name, arglist):
+        classname = "Function"
+        listname = "functions"
+        if arglist:
+            t, n, m = arglist[0]
+            # This is non-functional today
+            if t == OBJECT and m == "InMode":
+                classname = "Method"
+                listname = "methods"
+        return classname, listname
+
+    def makeblacklistnames(self):
+        return [
+                "GetIconCacheData",
+                "SetIconCacheData",
+                # Constants with funny definitions
+                "kSelectorAllHugeData",
+                "kSelectorAllAvailableData",
+                "svAllAvailableData",
+                # Something in a comment accidentally seen as a const definition
+                "err",
+                # OS8 only
+                'IconServicesTerminate',
+                # Lazy, right now.
+                "GetIconRefFromFileInfo"
+                ]
+
+    def makeblacklisttypes(self):
+        return [
+                "IconActionUPP",
+                "IconGetterUPP",
+                "CFragInitBlockPtr",
+                "CGRect_ptr",
+                ]
+
+    def makerepairinstructions(self):
+        return [
+                ]
+
+    def writeinitialdefs(self):
+        self.defsfile.write("def FOUR_CHAR_CODE(x): return x\n")
+        self.defsfile.write("from Carbon.Files import *\n")
+
+if __name__ == "__main__":
+    main()

Added: vendor/Python/current/Mac/Modules/icn/icnsupport.py
===================================================================
--- vendor/Python/current/Mac/Modules/icn/icnsupport.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/icn/icnsupport.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,90 @@
+# This script generates a Python interface for an Apple Macintosh Manager.
+# It uses the "bgen" package to generate C code.
+# The function specifications are generated by scanning the mamager's header file,
+# using the "scantools" package (customized for this particular manager).
+
+import string
+
+# Declarations that change for each manager
+MACHEADERFILE = 'Icons.h'               # The Apple header file
+MODNAME = '_Icn'                                # The name of the module
+OBJECTNAME = 'Icon'                     # The basic name of the objects used here
+KIND = 'Handle'                         # Usually 'Ptr' or 'Handle'
+
+# The following is *usually* unchanged but may still require tuning
+MODPREFIX = 'Icn'                       # The prefix for module-wide routines
+OBJECTTYPE = OBJECTNAME + KIND          # The C type used to represent them
+OBJECTPREFIX = MODPREFIX + 'Obj'        # The prefix for object methods
+INPUTFILE = string.lower(MODPREFIX) + 'gen.py' # The file generated by the scanner
+OUTPUTFILE = MODNAME + "module.c"       # The file generated by this program
+
+from macsupport import *
+
+# Create the type objects
+CIconHandle = OpaqueByValueType("CIconHandle", "ResObj")
+IconSuiteRef = OpaqueByValueType("IconSuiteRef", "ResObj")
+IconCacheRef = OpaqueByValueType("IconCacheRef", "ResObj")
+IconRef = OpaqueByValueType("IconRef", "ResObj")
+IconFamilyHandle = OpaqueByValueType("IconFamilyHandle", "ResObj")
+RgnHandle = OpaqueByValueType("RgnHandle", "ResObj")
+IconAlignmentType = Type("IconAlignmentType", "h")
+IconTransformType = Type("IconTransformType", "h")
+IconSelectorValue = Type("IconSelectorValue", "l")
+IconServicesUsageFlags = Type("IconServicesUsageFlags", "l")
+RGBColor = OpaqueType("RGBColor", "QdRGB")
+CGContextRef = OpaqueByValueType("CGContextRef", "CGContextRefObj")
+
+#WindowPeek = OpaqueByValueType("WindowPeek", OBJECTPREFIX)
+
+# RgnHandle = FakeType("(RgnHandle)0")
+# XXXX Should be next, but this will break a lot of code...
+# RgnHandle = OpaqueByValueType("RgnHandle", "OptResObj")
+
+# KeyMap = ArrayOutputBufferType("KeyMap")
+#MacOSEventKind = Type("MacOSEventKind", "h") # Old-style
+#MacOSEventMask = Type("MacOSEventMask", "h") # Old-style
+#EventMask = Type("EventMask", "H")
+#EventKind = Type("EventKind", "H")
+
+includestuff = includestuff + """
+#include <Carbon/Carbon.h>
+
+"""
+
+class MyObjectDefinition(PEP253Mixin, GlobalObjectDefinition):
+    def outputCheckNewArg(self):
+        Output("if (itself == NULL) return PyMac_Error(resNotFound);")
+    def outputCheckConvertArg(self):
+        OutLbrace("if (DlgObj_Check(v))")
+        Output("*p_itself = ((WindowObject *)v)->ob_itself;")
+        Output("return 1;")
+        OutRbrace()
+        Out("""
+        if (v == Py_None) { *p_itself = NULL; return 1; }
+        if (PyInt_Check(v)) { *p_itself = (WindowPtr)PyInt_AsLong(v); return 1; }
+        """)
+
+# From here on it's basically all boiler plate...
+
+# Create the generator groups and link them
+module = MacModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff)
+##object = MyObjectDefinition(OBJECTNAME, OBJECTPREFIX, OBJECTTYPE)
+##module.addobject(object)
+
+# Create the generator classes used to populate the lists
+Function = OSErrWeakLinkFunctionGenerator
+##Method = OSErrMethodGenerator
+
+# Create and populate the lists
+functions = []
+##methods = []
+execfile(INPUTFILE)
+
+# add the populated lists to the generator groups
+# (in a different wordl the scan program would generate this)
+for f in functions: module.add(f)
+##for f in methods: object.add(f)
+
+# generate output (open the output file as late as possible)
+SetOutputFileName(OUTPUTFILE)
+module.generate()

Added: vendor/Python/current/Mac/Modules/launch/_Launchmodule.c
===================================================================
--- vendor/Python/current/Mac/Modules/launch/_Launchmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/launch/_Launchmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,473 @@
+
+/* ========================= Module _Launch ========================= */
+
+#include "Python.h"
+
+
+
+#include "pymactoolbox.h"
+
+/* Macro to test whether a weak-loaded CFM function exists */
+#define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL )  {\
+        PyErr_SetString(PyExc_NotImplementedError, \
+        "Not available in this shared library/OS version"); \
+        return NULL; \
+    }} while(0)
+
+
+#if PY_VERSION_HEX < 0x02040000
+PyObject *PyMac_GetOSErrException(void);
+#endif
+
+#include <ApplicationServices/ApplicationServices.h>
+
+/*
+** Optional CFStringRef. None will pass NULL
+*/
+static int
+OptCFStringRefObj_Convert(PyObject *v, CFStringRef *spec)
+{
+        if (v == Py_None) {
+                *spec = NULL;
+                return 1;
+        }
+        return CFStringRefObj_Convert(v, spec);
+}
+
+PyObject *
+OptCFStringRefObj_New(CFStringRef it)
+{
+        if (it == NULL) {
+                Py_INCREF(Py_None);
+                return Py_None;
+        }
+        return CFStringRefObj_New(it);
+}
+
+/*
+** Convert LSItemInfoRecord to Python.
+*/
+PyObject *
+LSItemInfoRecord_New(LSItemInfoRecord *it)
+{
+        return Py_BuildValue("{s:is:O&s:O&s:O&s:O&s:i}",
+                "flags", it->flags,
+                "filetype", PyMac_BuildOSType, it->filetype,
+                "creator", PyMac_BuildOSType, it->creator,
+                "extension", OptCFStringRefObj_New, it->extension,
+                "iconFileName", OptCFStringRefObj_New, it->iconFileName,
+                "kindID", it->kindID);
+}
+
+static PyObject *Launch_Error;
+
+static PyObject *Launch_LSCopyItemInfoForRef(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	FSRef inItemRef;
+	LSRequestedInfo inWhichInfo;
+	LSItemInfoRecord outItemInfo;
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      PyMac_GetFSRef, &inItemRef,
+	                      &inWhichInfo))
+		return NULL;
+	_err = LSCopyItemInfoForRef(&inItemRef,
+	                            inWhichInfo,
+	                            &outItemInfo);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     LSItemInfoRecord_New, &outItemInfo);
+	return _res;
+}
+
+static PyObject *Launch_LSCopyItemInfoForURL(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	CFURLRef inURL;
+	LSRequestedInfo inWhichInfo;
+	LSItemInfoRecord outItemInfo;
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CFURLRefObj_Convert, &inURL,
+	                      &inWhichInfo))
+		return NULL;
+	_err = LSCopyItemInfoForURL(inURL,
+	                            inWhichInfo,
+	                            &outItemInfo);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     LSItemInfoRecord_New, &outItemInfo);
+	return _res;
+}
+
+static PyObject *Launch_LSGetExtensionInfo(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UniChar *inNameLen__in__;
+	UniCharCount inNameLen__len__;
+	int inNameLen__in_len__;
+	UniCharCount outExtStartIndex;
+	if (!PyArg_ParseTuple(_args, "u#",
+	                      &inNameLen__in__, &inNameLen__in_len__))
+		return NULL;
+	inNameLen__len__ = inNameLen__in_len__;
+	_err = LSGetExtensionInfo(inNameLen__len__, inNameLen__in__,
+	                          &outExtStartIndex);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     outExtStartIndex);
+	return _res;
+}
+
+static PyObject *Launch_LSCopyDisplayNameForRef(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	FSRef inRef;
+	CFStringRef outDisplayName;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetFSRef, &inRef))
+		return NULL;
+	_err = LSCopyDisplayNameForRef(&inRef,
+	                               &outDisplayName);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, outDisplayName);
+	return _res;
+}
+
+static PyObject *Launch_LSCopyDisplayNameForURL(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	CFURLRef inURL;
+	CFStringRef outDisplayName;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CFURLRefObj_Convert, &inURL))
+		return NULL;
+	_err = LSCopyDisplayNameForURL(inURL,
+	                               &outDisplayName);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, outDisplayName);
+	return _res;
+}
+
+static PyObject *Launch_LSSetExtensionHiddenForRef(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	FSRef inRef;
+	Boolean inHide;
+	if (!PyArg_ParseTuple(_args, "O&b",
+	                      PyMac_GetFSRef, &inRef,
+	                      &inHide))
+		return NULL;
+	_err = LSSetExtensionHiddenForRef(&inRef,
+	                                  inHide);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Launch_LSSetExtensionHiddenForURL(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	CFURLRef inURL;
+	Boolean inHide;
+	if (!PyArg_ParseTuple(_args, "O&b",
+	                      CFURLRefObj_Convert, &inURL,
+	                      &inHide))
+		return NULL;
+	_err = LSSetExtensionHiddenForURL(inURL,
+	                                  inHide);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Launch_LSCopyKindStringForRef(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	FSRef inFSRef;
+	CFStringRef outKindString;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetFSRef, &inFSRef))
+		return NULL;
+	_err = LSCopyKindStringForRef(&inFSRef,
+	                              &outKindString);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, outKindString);
+	return _res;
+}
+
+static PyObject *Launch_LSCopyKindStringForURL(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	CFURLRef inURL;
+	CFStringRef outKindString;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CFURLRefObj_Convert, &inURL))
+		return NULL;
+	_err = LSCopyKindStringForURL(inURL,
+	                              &outKindString);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, outKindString);
+	return _res;
+}
+
+static PyObject *Launch_LSGetApplicationForItem(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	FSRef inItemRef;
+	LSRolesMask inRoleMask;
+	FSRef outAppRef;
+	CFURLRef outAppURL;
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      PyMac_GetFSRef, &inItemRef,
+	                      &inRoleMask))
+		return NULL;
+	_err = LSGetApplicationForItem(&inItemRef,
+	                               inRoleMask,
+	                               &outAppRef,
+	                               &outAppURL);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&O&",
+	                     PyMac_BuildFSRef, &outAppRef,
+	                     CFURLRefObj_New, outAppURL);
+	return _res;
+}
+
+static PyObject *Launch_LSGetApplicationForInfo(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	OSType inType;
+	OSType inCreator;
+	CFStringRef inExtension;
+	LSRolesMask inRoleMask;
+	FSRef outAppRef;
+	CFURLRef outAppURL;
+	if (!PyArg_ParseTuple(_args, "O&O&O&l",
+	                      PyMac_GetOSType, &inType,
+	                      PyMac_GetOSType, &inCreator,
+	                      OptCFStringRefObj_Convert, &inExtension,
+	                      &inRoleMask))
+		return NULL;
+	_err = LSGetApplicationForInfo(inType,
+	                               inCreator,
+	                               inExtension,
+	                               inRoleMask,
+	                               &outAppRef,
+	                               &outAppURL);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&O&",
+	                     PyMac_BuildFSRef, &outAppRef,
+	                     CFURLRefObj_New, outAppURL);
+	return _res;
+}
+
+static PyObject *Launch_LSGetApplicationForURL(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	CFURLRef inURL;
+	LSRolesMask inRoleMask;
+	FSRef outAppRef;
+	CFURLRef outAppURL;
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CFURLRefObj_Convert, &inURL,
+	                      &inRoleMask))
+		return NULL;
+	_err = LSGetApplicationForURL(inURL,
+	                              inRoleMask,
+	                              &outAppRef,
+	                              &outAppURL);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&O&",
+	                     PyMac_BuildFSRef, &outAppRef,
+	                     CFURLRefObj_New, outAppURL);
+	return _res;
+}
+
+static PyObject *Launch_LSFindApplicationForInfo(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	OSType inCreator;
+	CFStringRef inBundleID;
+	CFStringRef inName;
+	FSRef outAppRef;
+	CFURLRef outAppURL;
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      PyMac_GetOSType, &inCreator,
+	                      OptCFStringRefObj_Convert, &inBundleID,
+	                      OptCFStringRefObj_Convert, &inName))
+		return NULL;
+	_err = LSFindApplicationForInfo(inCreator,
+	                                inBundleID,
+	                                inName,
+	                                &outAppRef,
+	                                &outAppURL);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&O&",
+	                     PyMac_BuildFSRef, &outAppRef,
+	                     CFURLRefObj_New, outAppURL);
+	return _res;
+}
+
+static PyObject *Launch_LSCanRefAcceptItem(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	FSRef inItemFSRef;
+	FSRef inTargetRef;
+	LSRolesMask inRoleMask;
+	LSAcceptanceFlags inFlags;
+	Boolean outAcceptsItem;
+	if (!PyArg_ParseTuple(_args, "O&O&ll",
+	                      PyMac_GetFSRef, &inItemFSRef,
+	                      PyMac_GetFSRef, &inTargetRef,
+	                      &inRoleMask,
+	                      &inFlags))
+		return NULL;
+	_err = LSCanRefAcceptItem(&inItemFSRef,
+	                          &inTargetRef,
+	                          inRoleMask,
+	                          inFlags,
+	                          &outAcceptsItem);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("b",
+	                     outAcceptsItem);
+	return _res;
+}
+
+static PyObject *Launch_LSCanURLAcceptURL(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	CFURLRef inItemURL;
+	CFURLRef inTargetURL;
+	LSRolesMask inRoleMask;
+	LSAcceptanceFlags inFlags;
+	Boolean outAcceptsItem;
+	if (!PyArg_ParseTuple(_args, "O&O&ll",
+	                      CFURLRefObj_Convert, &inItemURL,
+	                      CFURLRefObj_Convert, &inTargetURL,
+	                      &inRoleMask,
+	                      &inFlags))
+		return NULL;
+	_err = LSCanURLAcceptURL(inItemURL,
+	                         inTargetURL,
+	                         inRoleMask,
+	                         inFlags,
+	                         &outAcceptsItem);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("b",
+	                     outAcceptsItem);
+	return _res;
+}
+
+static PyObject *Launch_LSOpenFSRef(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	FSRef inRef;
+	FSRef outLaunchedRef;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetFSRef, &inRef))
+		return NULL;
+	_err = LSOpenFSRef(&inRef,
+	                   &outLaunchedRef);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildFSRef, &outLaunchedRef);
+	return _res;
+}
+
+static PyObject *Launch_LSOpenCFURLRef(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	CFURLRef inURL;
+	CFURLRef outLaunchedURL;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CFURLRefObj_Convert, &inURL))
+		return NULL;
+	_err = LSOpenCFURLRef(inURL,
+	                      &outLaunchedURL);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CFURLRefObj_New, outLaunchedURL);
+	return _res;
+}
+
+static PyMethodDef Launch_methods[] = {
+	{"LSCopyItemInfoForRef", (PyCFunction)Launch_LSCopyItemInfoForRef, 1,
+	 PyDoc_STR("(FSRef inItemRef, LSRequestedInfo inWhichInfo) -> (LSItemInfoRecord outItemInfo)")},
+	{"LSCopyItemInfoForURL", (PyCFunction)Launch_LSCopyItemInfoForURL, 1,
+	 PyDoc_STR("(CFURLRef inURL, LSRequestedInfo inWhichInfo) -> (LSItemInfoRecord outItemInfo)")},
+	{"LSGetExtensionInfo", (PyCFunction)Launch_LSGetExtensionInfo, 1,
+	 PyDoc_STR("(Buffer inNameLen) -> (UniCharCount outExtStartIndex)")},
+	{"LSCopyDisplayNameForRef", (PyCFunction)Launch_LSCopyDisplayNameForRef, 1,
+	 PyDoc_STR("(FSRef inRef) -> (CFStringRef outDisplayName)")},
+	{"LSCopyDisplayNameForURL", (PyCFunction)Launch_LSCopyDisplayNameForURL, 1,
+	 PyDoc_STR("(CFURLRef inURL) -> (CFStringRef outDisplayName)")},
+	{"LSSetExtensionHiddenForRef", (PyCFunction)Launch_LSSetExtensionHiddenForRef, 1,
+	 PyDoc_STR("(FSRef inRef, Boolean inHide) -> None")},
+	{"LSSetExtensionHiddenForURL", (PyCFunction)Launch_LSSetExtensionHiddenForURL, 1,
+	 PyDoc_STR("(CFURLRef inURL, Boolean inHide) -> None")},
+	{"LSCopyKindStringForRef", (PyCFunction)Launch_LSCopyKindStringForRef, 1,
+	 PyDoc_STR("(FSRef inFSRef) -> (CFStringRef outKindString)")},
+	{"LSCopyKindStringForURL", (PyCFunction)Launch_LSCopyKindStringForURL, 1,
+	 PyDoc_STR("(CFURLRef inURL) -> (CFStringRef outKindString)")},
+	{"LSGetApplicationForItem", (PyCFunction)Launch_LSGetApplicationForItem, 1,
+	 PyDoc_STR("(FSRef inItemRef, LSRolesMask inRoleMask) -> (FSRef outAppRef, CFURLRef outAppURL)")},
+	{"LSGetApplicationForInfo", (PyCFunction)Launch_LSGetApplicationForInfo, 1,
+	 PyDoc_STR("(OSType inType, OSType inCreator, CFStringRef inExtension, LSRolesMask inRoleMask) -> (FSRef outAppRef, CFURLRef outAppURL)")},
+	{"LSGetApplicationForURL", (PyCFunction)Launch_LSGetApplicationForURL, 1,
+	 PyDoc_STR("(CFURLRef inURL, LSRolesMask inRoleMask) -> (FSRef outAppRef, CFURLRef outAppURL)")},
+	{"LSFindApplicationForInfo", (PyCFunction)Launch_LSFindApplicationForInfo, 1,
+	 PyDoc_STR("(OSType inCreator, CFStringRef inBundleID, CFStringRef inName) -> (FSRef outAppRef, CFURLRef outAppURL)")},
+	{"LSCanRefAcceptItem", (PyCFunction)Launch_LSCanRefAcceptItem, 1,
+	 PyDoc_STR("(FSRef inItemFSRef, FSRef inTargetRef, LSRolesMask inRoleMask, LSAcceptanceFlags inFlags) -> (Boolean outAcceptsItem)")},
+	{"LSCanURLAcceptURL", (PyCFunction)Launch_LSCanURLAcceptURL, 1,
+	 PyDoc_STR("(CFURLRef inItemURL, CFURLRef inTargetURL, LSRolesMask inRoleMask, LSAcceptanceFlags inFlags) -> (Boolean outAcceptsItem)")},
+	{"LSOpenFSRef", (PyCFunction)Launch_LSOpenFSRef, 1,
+	 PyDoc_STR("(FSRef inRef) -> (FSRef outLaunchedRef)")},
+	{"LSOpenCFURLRef", (PyCFunction)Launch_LSOpenCFURLRef, 1,
+	 PyDoc_STR("(CFURLRef inURL) -> (CFURLRef outLaunchedURL)")},
+	{NULL, NULL, 0}
+};
+
+
+
+
+void init_Launch(void)
+{
+	PyObject *m;
+	PyObject *d;
+
+
+
+
+	m = Py_InitModule("_Launch", Launch_methods);
+	d = PyModule_GetDict(m);
+	Launch_Error = PyMac_GetOSErrException();
+	if (Launch_Error == NULL ||
+	    PyDict_SetItemString(d, "Error", Launch_Error) != 0)
+		return;
+}
+
+/* ======================= End module _Launch ======================= */
+

Added: vendor/Python/current/Mac/Modules/launch/launchscan.py
===================================================================
--- vendor/Python/current/Mac/Modules/launch/launchscan.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/launch/launchscan.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,86 @@
+# Scan an Apple header file, generating a Python file of generator calls.
+
+import sys
+import os
+from bgenlocations import TOOLBOXDIR, BGENDIR
+sys.path.append(BGENDIR)
+from scantools import Scanner
+
+LONG = "LaunchServices"
+SHORT = "launch"
+OBJECT = "NOTUSED"
+
+def main():
+    input = LONG + ".h"
+    output = SHORT + "gen.py"
+    defsoutput = TOOLBOXDIR + LONG + ".py"
+    scanner = MyScanner(input, output, defsoutput)
+    scanner.scan()
+    scanner.close()
+    scanner.gentypetest(SHORT+"typetest.py")
+    print "=== Testing definitions output code ==="
+    execfile(defsoutput, {}, {})
+    print "=== Done scanning and generating, now importing the generated code... ==="
+    exec "import " + SHORT + "support"
+    print "=== Done.  It's up to you to compile it now! ==="
+
+class MyScanner(Scanner):
+
+    def destination(self, type, name, arglist):
+        classname = "Function"
+        listname = "functions"
+        if arglist:
+            t, n, m = arglist[0]
+            # This is non-functional today
+            if t == OBJECT and m == "InMode":
+                classname = "Method"
+                listname = "methods"
+        return classname, listname
+
+    def writeinitialdefs(self):
+        self.defsfile.write("def FOUR_CHAR_CODE(x): return x\n")
+        self.defsfile.write("from Carbon.Files import *\n")
+        self.defsfile.write("kLSRequestAllInfo = -1\n")
+        self.defsfile.write("kLSRolesAll = -1\n")
+        self.defsfile.write("kLSUnknownType = FOUR_CHAR_CODE('\\0\\0\\0\\0')\n")
+        self.defsfile.write("kLSUnknownCreator = FOUR_CHAR_CODE('\\0\\0\\0\\0')\n")
+        self.defsfile.write("kLSInvalidExtensionIndex = -1\n")
+
+    def makeblacklistnames(self):
+        return [
+                "LSInit",
+                "LSTerm",
+                "kLSRequestAllInfo",
+                "kLSRolesAll",
+                "kLSInvalidExtensionIndex",
+                "kLSUnknownType",
+                "kLSUnknownCreator"
+                ]
+
+    def makeblacklisttypes(self):
+        return [
+                "LSLaunchFSRefSpec_ptr",
+                "LSLaunchURLSpec_ptr",
+                ]
+
+    def makerepairinstructions(self):
+        return [
+                # LSGetApplicationForInfo
+                ([('CFStringRef', 'inExtension', 'InMode')],
+         [('OptCFStringRef', 'inExtension', 'InMode')]),
+
+                # LSFindApplicationForInfo
+                ([('CFStringRef', 'inBundleID', 'InMode')],
+         [('OptCFStringRef', 'inBundleID', 'InMode')]),
+                ([('CFStringRef', 'inName', 'InMode')],
+         [('OptCFStringRef', 'inName', 'InMode')]),
+
+                # Unicode filenames passed as length, buffer. LSGetExtensionInfo
+                ([('UniCharCount', '*', 'InMode'),
+                  ('UniChar_ptr', '*', 'InMode')],
+                 [('UnicodeReverseInBuffer', '*', 'InMode')]
+                ),
+                ]
+
+if __name__ == "__main__":
+    main()

Added: vendor/Python/current/Mac/Modules/launch/launchsupport.py
===================================================================
--- vendor/Python/current/Mac/Modules/launch/launchsupport.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/launch/launchsupport.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,101 @@
+# This script generates a Python interface for an Apple Macintosh Manager.
+# It uses the "bgen" package to generate C code.
+# The function specifications are generated by scanning the mamager's header file,
+# using the "scantools" package (customized for this particular manager).
+
+import string
+
+# Declarations that change for each manager
+MODNAME = '_Launch'                             # The name of the module
+OBJECTNAME = 'UNUSED'                   # The basic name of the objects used here
+KIND = 'Record'                         # Usually 'Ptr' or 'Handle'
+
+# The following is *usually* unchanged but may still require tuning
+MODPREFIX = 'Launch'                    # The prefix for module-wide routines
+OBJECTTYPE = OBJECTNAME + KIND          # The C type used to represent them
+OBJECTPREFIX = MODPREFIX + 'Obj'        # The prefix for object methods
+INPUTFILE = string.lower(MODPREFIX) + 'gen.py' # The file generated by the scanner
+OUTPUTFILE = MODNAME + "module.c"       # The file generated by this program
+
+from macsupport import *
+
+# Create the type objects
+LSAcceptanceFlags = Type("LSAcceptanceFlags", "l")
+LSInitializeFlags = Type("LSInitializeFlags", "l")
+LSRequestedInfo = Type("LSRequestedInfo", "l")
+LSRolesMask = Type("LSRolesMask", "l")
+UniCharCount = Type("UniCharCount", "l")
+OptCFStringRef = OpaqueByValueType("CFStringRef", "OptCFStringRefObj")
+LSItemInfoRecord = OpaqueType("LSItemInfoRecord", "LSItemInfoRecord")
+
+includestuff = includestuff + """
+#if PY_VERSION_HEX < 0x02040000
+PyObject *PyMac_GetOSErrException(void);
+#endif
+
+#include <ApplicationServices/ApplicationServices.h>
+
+/*
+** Optional CFStringRef. None will pass NULL
+*/
+static int
+OptCFStringRefObj_Convert(PyObject *v, CFStringRef *spec)
+{
+        if (v == Py_None) {
+                *spec = NULL;
+                return 1;
+        }
+        return CFStringRefObj_Convert(v, spec);
+}
+
+PyObject *
+OptCFStringRefObj_New(CFStringRef it)
+{
+        if (it == NULL) {
+                Py_INCREF(Py_None);
+                return Py_None;
+        }
+        return CFStringRefObj_New(it);
+}
+
+/*
+** Convert LSItemInfoRecord to Python.
+*/
+PyObject *
+LSItemInfoRecord_New(LSItemInfoRecord *it)
+{
+        return Py_BuildValue("{s:is:O&s:O&s:O&s:O&s:i}",
+                "flags", it->flags,
+                "filetype", PyMac_BuildOSType, it->filetype,
+                "creator", PyMac_BuildOSType, it->creator,
+                "extension", OptCFStringRefObj_New, it->extension,
+                "iconFileName", OptCFStringRefObj_New, it->iconFileName,
+                "kindID", it->kindID);
+}
+"""
+
+# From here on it's basically all boiler plate...
+execfile(string.lower(MODPREFIX) + 'typetest.py')
+
+# Create the generator groups and link them
+module = MacModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff)
+##object = MyObjectDefinition(OBJECTNAME, OBJECTPREFIX, OBJECTTYPE)
+##module.addobject(object)
+
+# Create the generator classes used to populate the lists
+Function = OSErrFunctionGenerator
+##Method = OSErrMethodGenerator
+
+# Create and populate the lists
+functions = []
+##methods = []
+execfile(INPUTFILE)
+
+# add the populated lists to the generator groups
+# (in a different wordl the scan program would generate this)
+for f in functions: module.add(f)
+##for f in methods: object.add(f)
+
+# generate output (open the output file as late as possible)
+SetOutputFileName(OUTPUTFILE)
+module.generate()

Added: vendor/Python/current/Mac/Modules/launch/setup.py
===================================================================
--- vendor/Python/current/Mac/Modules/launch/setup.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/launch/setup.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,13 @@
+# This is a temporary setup script to allow distribution of
+# MacPython 2.4 modules for MacPython 2.3.
+
+from distutils.core import Extension, setup
+
+setup(name="LaunchServices", version="0.2",
+        ext_modules=[
+                Extension('_Launch', ['_Launchmodule.c'],
+                extra_link_args=['-framework', 'ApplicationServices'])
+        ],
+        py_modules=['LaunchServices.Launch', 'LaunchServices.LaunchServices'],
+        package_dir={'LaunchServices':'../../../Lib/plat-mac/Carbon'}
+        )

Added: vendor/Python/current/Mac/Modules/list/_Listmodule.c
===================================================================
--- vendor/Python/current/Mac/Modules/list/_Listmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/list/_Listmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1130 @@
+
+/* ========================== Module _List ========================== */
+
+#include "Python.h"
+
+
+
+#include "pymactoolbox.h"
+
+/* Macro to test whether a weak-loaded CFM function exists */
+#define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL )  {\
+        PyErr_SetString(PyExc_NotImplementedError, \
+        "Not available in this shared library/OS version"); \
+        return NULL; \
+    }} while(0)
+
+
+#include <Carbon/Carbon.h>
+
+#ifdef USE_TOOLBOX_OBJECT_GLUE
+extern PyObject *_ListObj_New(ListHandle);
+extern int _ListObj_Convert(PyObject *, ListHandle *);
+
+#define ListObj_New _ListObj_New
+#define ListObj_Convert _ListObj_Convert
+#endif
+
+#define as_List(x) ((ListHandle)x)
+#define as_Resource(lh) ((Handle)lh)
+
+static ListDefUPP myListDefFunctionUPP;
+
+
+static PyObject *List_Error;
+
+/* ------------------------ Object type List ------------------------ */
+
+PyTypeObject List_Type;
+
+#define ListObj_Check(x) ((x)->ob_type == &List_Type || PyObject_TypeCheck((x), &List_Type))
+
+typedef struct ListObject {
+	PyObject_HEAD
+	ListHandle ob_itself;
+	PyObject *ob_ldef_func;
+	int ob_must_be_disposed;
+} ListObject;
+
+PyObject *ListObj_New(ListHandle itself)
+{
+	ListObject *it;
+	if (itself == NULL) {
+	                                PyErr_SetString(List_Error,"Cannot create null List");
+	                                return NULL;
+	                        }
+	it = PyObject_NEW(ListObject, &List_Type);
+	if (it == NULL) return NULL;
+	it->ob_itself = itself;
+	it->ob_ldef_func = NULL;
+	it->ob_must_be_disposed = 1;
+	SetListRefCon(itself, (long)it);
+	return (PyObject *)it;
+}
+
+int ListObj_Convert(PyObject *v, ListHandle *p_itself)
+{
+	if (!ListObj_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "List required");
+		return 0;
+	}
+	*p_itself = ((ListObject *)v)->ob_itself;
+	return 1;
+}
+
+static void ListObj_dealloc(ListObject *self)
+{
+	Py_XDECREF(self->ob_ldef_func);
+	self->ob_ldef_func = NULL;
+	SetListRefCon(self->ob_itself, (long)0);
+	if (self->ob_must_be_disposed && self->ob_itself) LDispose(self->ob_itself);
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *ListObj_LAddColumn(ListObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short _rv;
+	short count;
+	short colNum;
+	if (!PyArg_ParseTuple(_args, "hh",
+	                      &count,
+	                      &colNum))
+		return NULL;
+	_rv = LAddColumn(count,
+	                 colNum,
+	                 _self->ob_itself);
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *ListObj_LAddRow(ListObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short _rv;
+	short count;
+	short rowNum;
+	if (!PyArg_ParseTuple(_args, "hh",
+	                      &count,
+	                      &rowNum))
+		return NULL;
+	_rv = LAddRow(count,
+	              rowNum,
+	              _self->ob_itself);
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *ListObj_LDelColumn(ListObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short count;
+	short colNum;
+	if (!PyArg_ParseTuple(_args, "hh",
+	                      &count,
+	                      &colNum))
+		return NULL;
+	LDelColumn(count,
+	           colNum,
+	           _self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *ListObj_LDelRow(ListObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short count;
+	short rowNum;
+	if (!PyArg_ParseTuple(_args, "hh",
+	                      &count,
+	                      &rowNum))
+		return NULL;
+	LDelRow(count,
+	        rowNum,
+	        _self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *ListObj_LGetSelect(ListObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	Boolean next;
+	Point theCell;
+	if (!PyArg_ParseTuple(_args, "bO&",
+	                      &next,
+	                      PyMac_GetPoint, &theCell))
+		return NULL;
+	_rv = LGetSelect(next,
+	                 &theCell,
+	                 _self->ob_itself);
+	_res = Py_BuildValue("bO&",
+	                     _rv,
+	                     PyMac_BuildPoint, theCell);
+	return _res;
+}
+
+static PyObject *ListObj_LLastClick(ListObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Point _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = LLastClick(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildPoint, _rv);
+	return _res;
+}
+
+static PyObject *ListObj_LNextCell(ListObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	Boolean hNext;
+	Boolean vNext;
+	Point theCell;
+	if (!PyArg_ParseTuple(_args, "bbO&",
+	                      &hNext,
+	                      &vNext,
+	                      PyMac_GetPoint, &theCell))
+		return NULL;
+	_rv = LNextCell(hNext,
+	                vNext,
+	                &theCell,
+	                _self->ob_itself);
+	_res = Py_BuildValue("bO&",
+	                     _rv,
+	                     PyMac_BuildPoint, theCell);
+	return _res;
+}
+
+static PyObject *ListObj_LSize(ListObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short listWidth;
+	short listHeight;
+	if (!PyArg_ParseTuple(_args, "hh",
+	                      &listWidth,
+	                      &listHeight))
+		return NULL;
+	LSize(listWidth,
+	      listHeight,
+	      _self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *ListObj_LSetDrawingMode(ListObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean drawIt;
+	if (!PyArg_ParseTuple(_args, "b",
+	                      &drawIt))
+		return NULL;
+	LSetDrawingMode(drawIt,
+	                _self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *ListObj_LScroll(ListObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short dCols;
+	short dRows;
+	if (!PyArg_ParseTuple(_args, "hh",
+	                      &dCols,
+	                      &dRows))
+		return NULL;
+	LScroll(dCols,
+	        dRows,
+	        _self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *ListObj_LAutoScroll(ListObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	LAutoScroll(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *ListObj_LUpdate(ListObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle theRgn;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &theRgn))
+		return NULL;
+	LUpdate(theRgn,
+	        _self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *ListObj_LActivate(ListObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean act;
+	if (!PyArg_ParseTuple(_args, "b",
+	                      &act))
+		return NULL;
+	LActivate(act,
+	          _self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *ListObj_LCellSize(ListObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Point cSize;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetPoint, &cSize))
+		return NULL;
+	LCellSize(cSize,
+	          _self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *ListObj_LClick(ListObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	Point pt;
+	EventModifiers modifiers;
+	if (!PyArg_ParseTuple(_args, "O&H",
+	                      PyMac_GetPoint, &pt,
+	                      &modifiers))
+		return NULL;
+	_rv = LClick(pt,
+	             modifiers,
+	             _self->ob_itself);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *ListObj_LAddToCell(ListObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	char *dataPtr__in__;
+	short dataPtr__len__;
+	int dataPtr__in_len__;
+	Point theCell;
+	if (!PyArg_ParseTuple(_args, "s#O&",
+	                      &dataPtr__in__, &dataPtr__in_len__,
+	                      PyMac_GetPoint, &theCell))
+		return NULL;
+	dataPtr__len__ = dataPtr__in_len__;
+	LAddToCell(dataPtr__in__, dataPtr__len__,
+	           theCell,
+	           _self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *ListObj_LClrCell(ListObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Point theCell;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetPoint, &theCell))
+		return NULL;
+	LClrCell(theCell,
+	         _self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *ListObj_LGetCell(ListObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	char *dataPtr__out__;
+	short dataPtr__len__;
+	int dataPtr__in_len__;
+	Point theCell;
+	if (!PyArg_ParseTuple(_args, "iO&",
+	                      &dataPtr__in_len__,
+	                      PyMac_GetPoint, &theCell))
+		return NULL;
+	if ((dataPtr__out__ = malloc(dataPtr__in_len__)) == NULL)
+	{
+		PyErr_NoMemory();
+		goto dataPtr__error__;
+	}
+	dataPtr__len__ = dataPtr__in_len__;
+	LGetCell(dataPtr__out__, &dataPtr__len__,
+	         theCell,
+	         _self->ob_itself);
+	_res = Py_BuildValue("s#",
+	                     dataPtr__out__, (int)dataPtr__len__);
+	free(dataPtr__out__);
+ dataPtr__error__: ;
+	return _res;
+}
+
+static PyObject *ListObj_LRect(ListObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect cellRect;
+	Point theCell;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetPoint, &theCell))
+		return NULL;
+	LRect(&cellRect,
+	      theCell,
+	      _self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildRect, &cellRect);
+	return _res;
+}
+
+static PyObject *ListObj_LSetCell(ListObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	char *dataPtr__in__;
+	short dataPtr__len__;
+	int dataPtr__in_len__;
+	Point theCell;
+	if (!PyArg_ParseTuple(_args, "s#O&",
+	                      &dataPtr__in__, &dataPtr__in_len__,
+	                      PyMac_GetPoint, &theCell))
+		return NULL;
+	dataPtr__len__ = dataPtr__in_len__;
+	LSetCell(dataPtr__in__, dataPtr__len__,
+	         theCell,
+	         _self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *ListObj_LSetSelect(ListObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean setIt;
+	Point theCell;
+	if (!PyArg_ParseTuple(_args, "bO&",
+	                      &setIt,
+	                      PyMac_GetPoint, &theCell))
+		return NULL;
+	LSetSelect(setIt,
+	           theCell,
+	           _self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *ListObj_LDraw(ListObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Point theCell;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetPoint, &theCell))
+		return NULL;
+	LDraw(theCell,
+	      _self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *ListObj_LGetCellDataLocation(ListObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short offset;
+	short len;
+	Point theCell;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetPoint, &theCell))
+		return NULL;
+	LGetCellDataLocation(&offset,
+	                     &len,
+	                     theCell,
+	                     _self->ob_itself);
+	_res = Py_BuildValue("hh",
+	                     offset,
+	                     len);
+	return _res;
+}
+
+static PyObject *ListObj_GetListPort(ListObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CGrafPtr _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetListPort(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     GrafObj_New, _rv);
+	return _res;
+}
+
+static PyObject *ListObj_GetListVerticalScrollBar(ListObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ControlHandle _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetListVerticalScrollBar(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     CtlObj_New, _rv);
+	return _res;
+}
+
+static PyObject *ListObj_GetListHorizontalScrollBar(ListObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ControlHandle _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetListHorizontalScrollBar(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     CtlObj_New, _rv);
+	return _res;
+}
+
+static PyObject *ListObj_GetListActive(ListObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetListActive(_self->ob_itself);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *ListObj_GetListClickTime(ListObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	SInt32 _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetListClickTime(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *ListObj_GetListRefCon(ListObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	SInt32 _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetListRefCon(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *ListObj_GetListDefinition(ListObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Handle _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetListDefinition(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *ListObj_GetListUserHandle(ListObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Handle _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetListUserHandle(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *ListObj_GetListDataHandle(ListObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	DataHandle _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetListDataHandle(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *ListObj_GetListFlags(ListObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OptionBits _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetListFlags(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *ListObj_GetListSelectionFlags(ListObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OptionBits _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetListSelectionFlags(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *ListObj_as_Resource(ListObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Handle _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = as_Resource(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyMethodDef ListObj_methods[] = {
+	{"LAddColumn", (PyCFunction)ListObj_LAddColumn, 1,
+	 PyDoc_STR("(short count, short colNum) -> (short _rv)")},
+	{"LAddRow", (PyCFunction)ListObj_LAddRow, 1,
+	 PyDoc_STR("(short count, short rowNum) -> (short _rv)")},
+	{"LDelColumn", (PyCFunction)ListObj_LDelColumn, 1,
+	 PyDoc_STR("(short count, short colNum) -> None")},
+	{"LDelRow", (PyCFunction)ListObj_LDelRow, 1,
+	 PyDoc_STR("(short count, short rowNum) -> None")},
+	{"LGetSelect", (PyCFunction)ListObj_LGetSelect, 1,
+	 PyDoc_STR("(Boolean next, Point theCell) -> (Boolean _rv, Point theCell)")},
+	{"LLastClick", (PyCFunction)ListObj_LLastClick, 1,
+	 PyDoc_STR("() -> (Point _rv)")},
+	{"LNextCell", (PyCFunction)ListObj_LNextCell, 1,
+	 PyDoc_STR("(Boolean hNext, Boolean vNext, Point theCell) -> (Boolean _rv, Point theCell)")},
+	{"LSize", (PyCFunction)ListObj_LSize, 1,
+	 PyDoc_STR("(short listWidth, short listHeight) -> None")},
+	{"LSetDrawingMode", (PyCFunction)ListObj_LSetDrawingMode, 1,
+	 PyDoc_STR("(Boolean drawIt) -> None")},
+	{"LScroll", (PyCFunction)ListObj_LScroll, 1,
+	 PyDoc_STR("(short dCols, short dRows) -> None")},
+	{"LAutoScroll", (PyCFunction)ListObj_LAutoScroll, 1,
+	 PyDoc_STR("() -> None")},
+	{"LUpdate", (PyCFunction)ListObj_LUpdate, 1,
+	 PyDoc_STR("(RgnHandle theRgn) -> None")},
+	{"LActivate", (PyCFunction)ListObj_LActivate, 1,
+	 PyDoc_STR("(Boolean act) -> None")},
+	{"LCellSize", (PyCFunction)ListObj_LCellSize, 1,
+	 PyDoc_STR("(Point cSize) -> None")},
+	{"LClick", (PyCFunction)ListObj_LClick, 1,
+	 PyDoc_STR("(Point pt, EventModifiers modifiers) -> (Boolean _rv)")},
+	{"LAddToCell", (PyCFunction)ListObj_LAddToCell, 1,
+	 PyDoc_STR("(Buffer dataPtr, Point theCell) -> None")},
+	{"LClrCell", (PyCFunction)ListObj_LClrCell, 1,
+	 PyDoc_STR("(Point theCell) -> None")},
+	{"LGetCell", (PyCFunction)ListObj_LGetCell, 1,
+	 PyDoc_STR("(Buffer dataPtr, Point theCell) -> (Buffer dataPtr)")},
+	{"LRect", (PyCFunction)ListObj_LRect, 1,
+	 PyDoc_STR("(Point theCell) -> (Rect cellRect)")},
+	{"LSetCell", (PyCFunction)ListObj_LSetCell, 1,
+	 PyDoc_STR("(Buffer dataPtr, Point theCell) -> None")},
+	{"LSetSelect", (PyCFunction)ListObj_LSetSelect, 1,
+	 PyDoc_STR("(Boolean setIt, Point theCell) -> None")},
+	{"LDraw", (PyCFunction)ListObj_LDraw, 1,
+	 PyDoc_STR("(Point theCell) -> None")},
+	{"LGetCellDataLocation", (PyCFunction)ListObj_LGetCellDataLocation, 1,
+	 PyDoc_STR("(Point theCell) -> (short offset, short len)")},
+	{"GetListPort", (PyCFunction)ListObj_GetListPort, 1,
+	 PyDoc_STR("() -> (CGrafPtr _rv)")},
+	{"GetListVerticalScrollBar", (PyCFunction)ListObj_GetListVerticalScrollBar, 1,
+	 PyDoc_STR("() -> (ControlHandle _rv)")},
+	{"GetListHorizontalScrollBar", (PyCFunction)ListObj_GetListHorizontalScrollBar, 1,
+	 PyDoc_STR("() -> (ControlHandle _rv)")},
+	{"GetListActive", (PyCFunction)ListObj_GetListActive, 1,
+	 PyDoc_STR("() -> (Boolean _rv)")},
+	{"GetListClickTime", (PyCFunction)ListObj_GetListClickTime, 1,
+	 PyDoc_STR("() -> (SInt32 _rv)")},
+	{"GetListRefCon", (PyCFunction)ListObj_GetListRefCon, 1,
+	 PyDoc_STR("() -> (SInt32 _rv)")},
+	{"GetListDefinition", (PyCFunction)ListObj_GetListDefinition, 1,
+	 PyDoc_STR("() -> (Handle _rv)")},
+	{"GetListUserHandle", (PyCFunction)ListObj_GetListUserHandle, 1,
+	 PyDoc_STR("() -> (Handle _rv)")},
+	{"GetListDataHandle", (PyCFunction)ListObj_GetListDataHandle, 1,
+	 PyDoc_STR("() -> (DataHandle _rv)")},
+	{"GetListFlags", (PyCFunction)ListObj_GetListFlags, 1,
+	 PyDoc_STR("() -> (OptionBits _rv)")},
+	{"GetListSelectionFlags", (PyCFunction)ListObj_GetListSelectionFlags, 1,
+	 PyDoc_STR("() -> (OptionBits _rv)")},
+	{"as_Resource", (PyCFunction)ListObj_as_Resource, 1,
+	 PyDoc_STR("() -> (Handle _rv)")},
+	{NULL, NULL, 0}
+};
+
+static PyObject *ListObj_get_listFlags(ListObject *self, void *closure)
+{
+	return Py_BuildValue("l", (long)GetListFlags(self->ob_itself) & 0xff);
+}
+
+static int ListObj_set_listFlags(ListObject *self, PyObject *v, void *closure)
+{
+	if (!PyArg_Parse(v, "B", &(*self->ob_itself)->listFlags)) return -1;
+	return 0;
+}
+
+static PyObject *ListObj_get_selFlags(ListObject *self, void *closure)
+{
+	return Py_BuildValue("l", (long)GetListSelectionFlags(self->ob_itself) & 0xff);
+}
+
+static int ListObj_set_selFlags(ListObject *self, PyObject *v, void *closure)
+{
+	if (!PyArg_Parse(v, "B", &(*self->ob_itself)->selFlags)) return -1;
+	return 0;
+}
+
+static PyObject *ListObj_get_cellSize(ListObject *self, void *closure)
+{
+	return Py_BuildValue("O&", PyMac_BuildPoint, (*self->ob_itself)->cellSize);
+}
+
+static int ListObj_set_cellSize(ListObject *self, PyObject *v, void *closure)
+{
+	if (!PyArg_Parse(v, "O&", PyMac_GetPoint, &(*self->ob_itself)->cellSize)) return -1;
+	return 0;
+}
+
+static PyGetSetDef ListObj_getsetlist[] = {
+	{"listFlags", (getter)ListObj_get_listFlags, (setter)ListObj_set_listFlags, NULL},
+	{"selFlags", (getter)ListObj_get_selFlags, (setter)ListObj_set_selFlags, NULL},
+	{"cellSize", (getter)ListObj_get_cellSize, (setter)ListObj_set_cellSize, NULL},
+	{NULL, NULL, NULL, NULL},
+};
+
+
+#define ListObj_compare NULL
+
+#define ListObj_repr NULL
+
+#define ListObj_hash NULL
+#define ListObj_tp_init 0
+
+#define ListObj_tp_alloc PyType_GenericAlloc
+
+static PyObject *ListObj_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *_self;
+	ListHandle itself;
+	char *kw[] = {"itself", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, ListObj_Convert, &itself)) return NULL;
+	if ((_self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	((ListObject *)_self)->ob_itself = itself;
+	return _self;
+}
+
+#define ListObj_tp_free PyObject_Del
+
+
+PyTypeObject List_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"_List.List", /*tp_name*/
+	sizeof(ListObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) ListObj_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) ListObj_compare, /*tp_compare*/
+	(reprfunc) ListObj_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) ListObj_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	ListObj_methods, /* tp_methods */
+	0, /*tp_members*/
+	ListObj_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	ListObj_tp_init, /* tp_init */
+	ListObj_tp_alloc, /* tp_alloc */
+	ListObj_tp_new, /* tp_new */
+	ListObj_tp_free, /* tp_free */
+};
+
+/* ---------------------- End object type List ---------------------- */
+
+
+static PyObject *List_CreateCustomList(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect rView;
+	Rect dataBounds;
+	Point cellSize;
+
+	PyObject *listDefFunc;
+	ListDefSpec theSpec;
+	WindowPtr theWindow;
+	Boolean drawIt;
+	Boolean hasGrow;
+	Boolean scrollHoriz;
+	Boolean scrollVert;
+	ListHandle outList;
+
+	if (!PyArg_ParseTuple(_args, "O&O&O&(iO)O&bbbb",
+	                      PyMac_GetRect, &rView,
+	                      PyMac_GetRect, &dataBounds,
+	                      PyMac_GetPoint, &cellSize,
+	                      &theSpec.defType, &listDefFunc,
+	                      WinObj_Convert, &theWindow,
+	                      &drawIt,
+	                      &hasGrow,
+	                      &scrollHoriz,
+	                      &scrollVert))
+	        return NULL;
+
+
+	/* Carbon applications use the CreateCustomList API */
+	theSpec.u.userProc = myListDefFunctionUPP;
+	CreateCustomList(&rView,
+	                 &dataBounds,
+	                 cellSize,
+	                 &theSpec,
+	                 theWindow,
+	                 drawIt,
+	                 hasGrow,
+	                 scrollHoriz,
+	                 scrollVert,
+	                 &outList);
+
+
+	_res = ListObj_New(outList);
+	if (_res == NULL)
+	        return NULL;
+	Py_INCREF(listDefFunc);
+	((ListObject*)_res)->ob_ldef_func = listDefFunc;
+	return _res;
+}
+
+static PyObject *List_LNew(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ListHandle _rv;
+	Rect rView;
+	Rect dataBounds;
+	Point cSize;
+	short theProc;
+	WindowPtr theWindow;
+	Boolean drawIt;
+	Boolean hasGrow;
+	Boolean scrollHoriz;
+	Boolean scrollVert;
+	if (!PyArg_ParseTuple(_args, "O&O&O&hO&bbbb",
+	                      PyMac_GetRect, &rView,
+	                      PyMac_GetRect, &dataBounds,
+	                      PyMac_GetPoint, &cSize,
+	                      &theProc,
+	                      WinObj_Convert, &theWindow,
+	                      &drawIt,
+	                      &hasGrow,
+	                      &scrollHoriz,
+	                      &scrollVert))
+		return NULL;
+	_rv = LNew(&rView,
+	           &dataBounds,
+	           cSize,
+	           theProc,
+	           theWindow,
+	           drawIt,
+	           hasGrow,
+	           scrollHoriz,
+	           scrollVert);
+	_res = Py_BuildValue("O&",
+	                     ListObj_New, _rv);
+	return _res;
+}
+
+static PyObject *List_SetListViewBounds(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ListHandle list;
+	Rect view;
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      ListObj_Convert, &list,
+	                      PyMac_GetRect, &view))
+		return NULL;
+	SetListViewBounds(list,
+	                  &view);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *List_SetListPort(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ListHandle list;
+	CGrafPtr port;
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      ListObj_Convert, &list,
+	                      GrafObj_Convert, &port))
+		return NULL;
+	SetListPort(list,
+	            port);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *List_SetListCellIndent(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ListHandle list;
+	Point indent;
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      ListObj_Convert, &list,
+	                      PyMac_GetPoint, &indent))
+		return NULL;
+	SetListCellIndent(list,
+	                  &indent);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *List_SetListClickTime(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ListHandle list;
+	SInt32 time;
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      ListObj_Convert, &list,
+	                      &time))
+		return NULL;
+	SetListClickTime(list,
+	                 time);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *List_SetListRefCon(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ListHandle list;
+	SInt32 refCon;
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      ListObj_Convert, &list,
+	                      &refCon))
+		return NULL;
+	SetListRefCon(list,
+	              refCon);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *List_SetListUserHandle(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ListHandle list;
+	Handle userHandle;
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      ListObj_Convert, &list,
+	                      ResObj_Convert, &userHandle))
+		return NULL;
+	SetListUserHandle(list,
+	                  userHandle);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *List_SetListFlags(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ListHandle list;
+	OptionBits listFlags;
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      ListObj_Convert, &list,
+	                      &listFlags))
+		return NULL;
+	SetListFlags(list,
+	             listFlags);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *List_SetListSelectionFlags(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ListHandle list;
+	OptionBits selectionFlags;
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      ListObj_Convert, &list,
+	                      &selectionFlags))
+		return NULL;
+	SetListSelectionFlags(list,
+	                      selectionFlags);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *List_as_List(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+
+	Handle h;
+	ListObject *l;
+	if (!PyArg_ParseTuple(_args, "O&", ResObj_Convert, &h))
+	        return NULL;
+	l = (ListObject *)ListObj_New(as_List(h));
+	l->ob_must_be_disposed = 0;
+	_res = Py_BuildValue("O", l);
+	return _res;
+
+}
+
+static PyMethodDef List_methods[] = {
+	{"CreateCustomList", (PyCFunction)List_CreateCustomList, 1,
+	 PyDoc_STR("(Rect rView, Rect dataBounds, Point cellSize, ListDefSpec theSpec, WindowPtr theWindow, Boolean drawIt, Boolean hasGrow, Boolean scrollHoriz, Boolean scrollVert) -> (ListHandle outList)")},
+	{"LNew", (PyCFunction)List_LNew, 1,
+	 PyDoc_STR("(Rect rView, Rect dataBounds, Point cSize, short theProc, WindowPtr theWindow, Boolean drawIt, Boolean hasGrow, Boolean scrollHoriz, Boolean scrollVert) -> (ListHandle _rv)")},
+	{"SetListViewBounds", (PyCFunction)List_SetListViewBounds, 1,
+	 PyDoc_STR("(ListHandle list, Rect view) -> None")},
+	{"SetListPort", (PyCFunction)List_SetListPort, 1,
+	 PyDoc_STR("(ListHandle list, CGrafPtr port) -> None")},
+	{"SetListCellIndent", (PyCFunction)List_SetListCellIndent, 1,
+	 PyDoc_STR("(ListHandle list, Point indent) -> None")},
+	{"SetListClickTime", (PyCFunction)List_SetListClickTime, 1,
+	 PyDoc_STR("(ListHandle list, SInt32 time) -> None")},
+	{"SetListRefCon", (PyCFunction)List_SetListRefCon, 1,
+	 PyDoc_STR("(ListHandle list, SInt32 refCon) -> None")},
+	{"SetListUserHandle", (PyCFunction)List_SetListUserHandle, 1,
+	 PyDoc_STR("(ListHandle list, Handle userHandle) -> None")},
+	{"SetListFlags", (PyCFunction)List_SetListFlags, 1,
+	 PyDoc_STR("(ListHandle list, OptionBits listFlags) -> None")},
+	{"SetListSelectionFlags", (PyCFunction)List_SetListSelectionFlags, 1,
+	 PyDoc_STR("(ListHandle list, OptionBits selectionFlags) -> None")},
+	{"as_List", (PyCFunction)List_as_List, 1,
+	 PyDoc_STR("(Resource)->List.\nReturns List object (which is not auto-freed!)")},
+	{NULL, NULL, 0}
+};
+
+
+
+static void myListDefFunction(SInt16 message,
+                       Boolean selected,
+                       Rect *cellRect,
+                       Cell theCell,
+                       SInt16 dataOffset,
+                       SInt16 dataLen,
+                       ListHandle theList)
+{
+        PyObject *listDefFunc, *args, *rv=NULL;
+        ListObject *self;
+
+        self = (ListObject*)GetListRefCon(theList);
+        if (self == NULL || self->ob_itself != theList)
+                return;  /* nothing we can do */
+        listDefFunc = self->ob_ldef_func;
+        if (listDefFunc == NULL)
+                return;  /* nothing we can do */
+        args = Py_BuildValue("hbO&O&hhO", message,
+                                          selected,
+                                          PyMac_BuildRect, cellRect,
+                                          PyMac_BuildPoint, theCell,
+                                          dataOffset,
+                                          dataLen,
+                                          self);
+        if (args != NULL) {
+                rv = PyEval_CallObject(listDefFunc, args);
+                Py_DECREF(args);
+        }
+        if (rv == NULL) {
+                PySys_WriteStderr("error in list definition callback:\n");
+                PyErr_Print();
+        } else {
+                Py_DECREF(rv);
+        }
+}
+
+
+void init_List(void)
+{
+	PyObject *m;
+	PyObject *d;
+
+
+
+	myListDefFunctionUPP = NewListDefUPP((ListDefProcPtr)myListDefFunction);
+
+	PyMac_INIT_TOOLBOX_OBJECT_NEW(ListHandle, ListObj_New);
+	PyMac_INIT_TOOLBOX_OBJECT_CONVERT(ListHandle, ListObj_Convert);
+
+
+	m = Py_InitModule("_List", List_methods);
+	d = PyModule_GetDict(m);
+	List_Error = PyMac_GetOSErrException();
+	if (List_Error == NULL ||
+	    PyDict_SetItemString(d, "Error", List_Error) != 0)
+		return;
+	List_Type.ob_type = &PyType_Type;
+	if (PyType_Ready(&List_Type) < 0) return;
+	Py_INCREF(&List_Type);
+	PyModule_AddObject(m, "List", (PyObject *)&List_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&List_Type);
+	PyModule_AddObject(m, "ListType", (PyObject *)&List_Type);
+}
+
+/* ======================== End module _List ======================== */
+

Added: vendor/Python/current/Mac/Modules/list/listscan.py
===================================================================
--- vendor/Python/current/Mac/Modules/list/listscan.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/list/listscan.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,88 @@
+# Scan an Apple header file, generating a Python file of generator calls.
+
+import sys
+import os
+from bgenlocations import TOOLBOXDIR, BGENDIR
+sys.path.append(BGENDIR)
+from scantools import Scanner
+
+LONG = "Lists"
+SHORT = "list"
+OBJECT = "ListHandle"
+
+def main():
+    input = LONG + ".h"
+    output = SHORT + "gen.py"
+    defsoutput = TOOLBOXDIR + LONG + ".py"
+    scanner = MyScanner(input, output, defsoutput)
+    scanner.scan()
+    scanner.close()
+    print "=== Testing definitions output code ==="
+    execfile(defsoutput, {}, {})
+    print "=== Done scanning and generating, now importing the generated code... ==="
+    exec "import " + SHORT + "support"
+    print "=== Done.  It's up to you to compile it now! ==="
+
+class MyScanner(Scanner):
+
+    def destination(self, type, name, arglist):
+        classname = "Function"
+        listname = "functions"
+        if arglist:
+            t, n, m = arglist[-1]
+            # This is non-functional today
+            if t in ('ListHandle', 'ListRef') and m == "InMode":
+                classname = "Method"
+                listname = "methods"
+        return classname, listname
+
+    def makeblacklistnames(self):
+        return [
+                "LDispose",             # Done by removing the object
+                "LSearch",              # We don't want to handle procs just yet
+                "CreateCustomList",  # done manually
+                "SetListDefinitionProc",
+
+                # These have funny argument/return values
+                "GetListViewBounds",
+                "GetListCellIndent",
+                "GetListCellSize",
+                "GetListVisibleCells",
+                "GetListClickLocation",
+                "GetListMouseLocation",
+                "GetListDataBounds",
+                "SetListLastClick",
+                ]
+
+    def makeblacklisttypes(self):
+        return [
+                "ListClickLoopUPP",  # Too difficult for now
+                "ListDefSpecPtr", # later
+                ]
+
+    def makerepairinstructions(self):
+        return [
+                ([('ListBounds_ptr', '*', 'InMode')],
+                 [('Rect_ptr', '*', 'InMode')]),
+
+                ([("Cell", "theCell", "OutMode")],
+                 [("Cell", "theCell", "InOutMode")]),
+
+                ([("void_ptr", "*", "InMode"), ("short", "*", "InMode")],
+                 [("InBufferShortsize", "*", "*")]),
+
+                ([("void", "*", "OutMode"), ("short", "*", "OutMode")],
+                 [("VarOutBufferShortsize", "*", "InOutMode")]),
+
+                # SetListCellIndent doesn't have const
+                ([("Point", "indent", "OutMode")],
+                 [("Point_ptr", "indent", "InMode")]),
+
+                ]
+
+    def writeinitialdefs(self):
+        self.defsfile.write("def FOUR_CHAR_CODE(x): return x\n")
+
+
+if __name__ == "__main__":
+    main()

Added: vendor/Python/current/Mac/Modules/list/listsupport.py
===================================================================
--- vendor/Python/current/Mac/Modules/list/listsupport.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/list/listsupport.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,255 @@
+# This script generates a Python interface for an Apple Macintosh Manager.
+# It uses the "bgen" package to generate C code.
+# The function specifications are generated by scanning the mamager's header file,
+# using the "scantools" package (customized for this particular manager).
+
+import string
+
+# Declarations that change for each manager
+MACHEADERFILE = 'Lists.h'               # The Apple header file
+MODNAME = '_List'                               # The name of the module
+OBJECTNAME = 'List'                     # The basic name of the objects used here
+KIND = 'Handle'                         # Usually 'Ptr' or 'Handle'
+
+# The following is *usually* unchanged but may still require tuning
+MODPREFIX = 'List'                      # The prefix for module-wide routines
+OBJECTTYPE = "ListHandle"               # The C type used to represent them
+OBJECTPREFIX = MODPREFIX + 'Obj'        # The prefix for object methods
+INPUTFILE = string.lower(MODPREFIX) + 'gen.py' # The file generated by the scanner
+OUTPUTFILE = MODNAME + "module.c"       # The file generated by this program
+
+from macsupport import *
+
+# Create the type objects
+ListHandle = OpaqueByValueType("ListHandle", "ListObj")
+ListRef = ListHandle # Obsolete, but used in Lists.h
+Cell = Point
+ListBounds = Rect
+ListBounds_ptr = Rect_ptr
+
+ListDefSpec = ListDefSpec_ptr = OpaqueType("ListDefSpec", "PyMac_BuildListDefSpec", "PyMac_GetListDefSpec")
+
+VarOutBufferShortsize = VarHeapOutputBufferType('char', 'short', 's')   # (buf, &len)
+InBufferShortsize = VarInputBufferType('char', 'short', 's')            # (buf, len)
+
+RgnHandle = OpaqueByValueType("RgnHandle", "ResObj")
+DataHandle = OpaqueByValueType("DataHandle", "ResObj")
+Handle = OpaqueByValueType("Handle", "ResObj")
+CGrafPtr = OpaqueByValueType("CGrafPtr", "GrafObj")
+EventModifiers = Type("EventModifiers", "H")
+
+includestuff = includestuff + """
+#include <Carbon/Carbon.h>
+
+#ifdef USE_TOOLBOX_OBJECT_GLUE
+extern PyObject *_ListObj_New(ListHandle);
+extern int _ListObj_Convert(PyObject *, ListHandle *);
+
+#define ListObj_New _ListObj_New
+#define ListObj_Convert _ListObj_Convert
+#endif
+
+#define as_List(x) ((ListHandle)x)
+#define as_Resource(lh) ((Handle)lh)
+
+static ListDefUPP myListDefFunctionUPP;
+
+"""
+
+initstuff = initstuff + """
+myListDefFunctionUPP = NewListDefUPP((ListDefProcPtr)myListDefFunction);
+
+PyMac_INIT_TOOLBOX_OBJECT_NEW(ListHandle, ListObj_New);
+PyMac_INIT_TOOLBOX_OBJECT_CONVERT(ListHandle, ListObj_Convert);
+"""
+
+class ListMethodGenerator(MethodGenerator):
+    """Similar to MethodGenerator, but has self as last argument"""
+
+    def parseArgumentList(self, args):
+        args, a0 = args[:-1], args[-1]
+        t0, n0, m0 = a0
+        if m0 != InMode:
+            raise ValueError, "method's 'self' must be 'InMode'"
+        self.itself = Variable(t0, "_self->ob_itself", SelfMode)
+        FunctionGenerator.parseArgumentList(self, args)
+        self.argumentList.append(self.itself)
+
+class MyObjectDefinition(PEP253Mixin, GlobalObjectDefinition):
+    # XXXX Should inherit from Resource
+    getsetlist = [(
+            'listFlags',
+            'return Py_BuildValue("l", (long)GetListFlags(self->ob_itself) & 0xff);',
+            'if (!PyArg_Parse(v, "B", &(*self->ob_itself)->listFlags)) return -1;',
+            None,
+            ), (
+            'selFlags',
+            'return Py_BuildValue("l", (long)GetListSelectionFlags(self->ob_itself) & 0xff);',
+            'if (!PyArg_Parse(v, "B", &(*self->ob_itself)->selFlags)) return -1;',
+            None,
+            ), (
+            'cellSize',
+            'return Py_BuildValue("O&", PyMac_BuildPoint, (*self->ob_itself)->cellSize);',
+            'if (!PyArg_Parse(v, "O&", PyMac_GetPoint, &(*self->ob_itself)->cellSize)) return -1;',
+            None
+            )]
+
+    def outputStructMembers(self):
+        ObjectDefinition.outputStructMembers(self)
+        Output("PyObject *ob_ldef_func;")
+        Output("int ob_must_be_disposed;")
+
+    def outputCheckNewArg(self):
+        Output("""if (itself == NULL) {
+                                PyErr_SetString(List_Error,"Cannot create null List");
+                                return NULL;
+                        }""")
+
+    def outputInitStructMembers(self):
+        ObjectDefinition.outputInitStructMembers(self)
+        Output("it->ob_ldef_func = NULL;")
+        Output("it->ob_must_be_disposed = 1;")
+        Output("SetListRefCon(itself, (long)it);")
+
+    def outputFreeIt(self, itselfname):
+        Output("Py_XDECREF(self->ob_ldef_func);")
+        Output("self->ob_ldef_func = NULL;")
+        Output("SetListRefCon(self->ob_itself, (long)0);")
+        Output("if (self->ob_must_be_disposed && %s) LDispose(%s);", itselfname, itselfname)
+
+# From here on it's basically all boiler plate...
+
+finalstuff = finalstuff + """
+static void myListDefFunction(SInt16 message,
+                       Boolean selected,
+                       Rect *cellRect,
+                       Cell theCell,
+                       SInt16 dataOffset,
+                       SInt16 dataLen,
+                       ListHandle theList)
+{
+        PyObject *listDefFunc, *args, *rv=NULL;
+        ListObject *self;
+
+        self = (ListObject*)GetListRefCon(theList);
+        if (self == NULL || self->ob_itself != theList)
+                return;  /* nothing we can do */
+        listDefFunc = self->ob_ldef_func;
+        if (listDefFunc == NULL)
+                return;  /* nothing we can do */
+        args = Py_BuildValue("hbO&O&hhO", message,
+                                          selected,
+                                          PyMac_BuildRect, cellRect,
+                                          PyMac_BuildPoint, theCell,
+                                          dataOffset,
+                                          dataLen,
+                                          self);
+        if (args != NULL) {
+                rv = PyEval_CallObject(listDefFunc, args);
+                Py_DECREF(args);
+        }
+        if (rv == NULL) {
+                PySys_WriteStderr("error in list definition callback:\\n");
+                PyErr_Print();
+        } else {
+                Py_DECREF(rv);
+        }
+}
+"""
+
+# Create the generator groups and link them
+module = MacModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff)
+object = MyObjectDefinition(OBJECTNAME, OBJECTPREFIX, OBJECTTYPE)
+module.addobject(object)
+
+# Create the generator classes used to populate the lists
+Function = FunctionGenerator
+Method = ListMethodGenerator
+
+# Create and populate the lists
+functions = []
+methods = []
+execfile(INPUTFILE)
+
+# Function to convert any handle to a list and vv.
+##f = Function(ListHandle, 'as_List', (Handle, 'h', InMode))
+as_List_body = """
+Handle h;
+ListObject *l;
+if (!PyArg_ParseTuple(_args, "O&", ResObj_Convert, &h))
+        return NULL;
+l = (ListObject *)ListObj_New(as_List(h));
+l->ob_must_be_disposed = 0;
+_res = Py_BuildValue("O", l);
+return _res;
+"""
+f = ManualGenerator("as_List", as_List_body)
+f.docstring = lambda: "(Resource)->List.\nReturns List object (which is not auto-freed!)"
+functions.append(f)
+
+f = Method(Handle, 'as_Resource', (ListHandle, 'lh', InMode))
+methods.append(f)
+
+# Manual generator for CreateCustomList, due to callback ideosyncracies
+CreateCustomList_body = """\
+Rect rView;
+Rect dataBounds;
+Point cellSize;
+
+PyObject *listDefFunc;
+ListDefSpec theSpec;
+WindowPtr theWindow;
+Boolean drawIt;
+Boolean hasGrow;
+Boolean scrollHoriz;
+Boolean scrollVert;
+ListHandle outList;
+
+if (!PyArg_ParseTuple(_args, "O&O&O&(iO)O&bbbb",
+                      PyMac_GetRect, &rView,
+                      PyMac_GetRect, &dataBounds,
+                      PyMac_GetPoint, &cellSize,
+                      &theSpec.defType, &listDefFunc,
+                      WinObj_Convert, &theWindow,
+                      &drawIt,
+                      &hasGrow,
+                      &scrollHoriz,
+                      &scrollVert))
+        return NULL;
+
+
+/* Carbon applications use the CreateCustomList API */
+theSpec.u.userProc = myListDefFunctionUPP;
+CreateCustomList(&rView,
+                 &dataBounds,
+                 cellSize,
+                 &theSpec,
+                 theWindow,
+                 drawIt,
+                 hasGrow,
+                 scrollHoriz,
+                 scrollVert,
+                 &outList);
+
+
+_res = ListObj_New(outList);
+if (_res == NULL)
+        return NULL;
+Py_INCREF(listDefFunc);
+((ListObject*)_res)->ob_ldef_func = listDefFunc;
+return _res;\
+"""
+
+f = ManualGenerator("CreateCustomList", CreateCustomList_body);
+f.docstring = lambda: "(Rect rView, Rect dataBounds, Point cellSize, ListDefSpec theSpec, WindowPtr theWindow, Boolean drawIt, Boolean hasGrow, Boolean scrollHoriz, Boolean scrollVert) -> (ListHandle outList)"
+module.add(f)
+
+# add the populated lists to the generator groups
+# (in a different wordl the scan program would generate this)
+for f in functions: module.add(f)
+for f in methods: object.add(f)
+
+
+# generate output (open the output file as late as possible)
+SetOutputFileName(OUTPUTFILE)
+module.generate()

Added: vendor/Python/current/Mac/Modules/menu/_Menumodule.c
===================================================================
--- vendor/Python/current/Mac/Modules/menu/_Menumodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/menu/_Menumodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,3469 @@
+
+/* ========================== Module _Menu ========================== */
+
+#include "Python.h"
+
+
+
+#include "pymactoolbox.h"
+
+/* Macro to test whether a weak-loaded CFM function exists */
+#define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL )  {\
+        PyErr_SetString(PyExc_NotImplementedError, \
+        "Not available in this shared library/OS version"); \
+        return NULL; \
+    }} while(0)
+
+
+#include <Carbon/Carbon.h>
+
+
+#ifdef USE_TOOLBOX_OBJECT_GLUE
+
+extern PyObject *_MenuObj_New(MenuHandle);
+extern int _MenuObj_Convert(PyObject *, MenuHandle *);
+
+#define MenuObj_New _MenuObj_New
+#define MenuObj_Convert _MenuObj_Convert
+#endif
+
+#define as_Menu(h) ((MenuHandle)h)
+#define as_Resource(h) ((Handle)h)
+
+
+/* Alternative version of MenuObj_New, which returns None for NULL argument */
+PyObject *OptMenuObj_New(MenuRef itself)
+{
+        if (itself == NULL) {
+                Py_INCREF(Py_None);
+                return Py_None;
+        }
+        return MenuObj_New(itself);
+}
+
+/* Alternative version of MenuObj_Convert, which returns NULL for a None argument */
+int OptMenuObj_Convert(PyObject *v, MenuRef *p_itself)
+{
+        if ( v == Py_None ) {
+                *p_itself = NULL;
+                return 1;
+        }
+        return MenuObj_Convert(v, p_itself);
+}
+
+static PyObject *Menu_Error;
+
+/* ------------------------ Object type Menu ------------------------ */
+
+PyTypeObject Menu_Type;
+
+#define MenuObj_Check(x) ((x)->ob_type == &Menu_Type || PyObject_TypeCheck((x), &Menu_Type))
+
+typedef struct MenuObject {
+	PyObject_HEAD
+	MenuHandle ob_itself;
+} MenuObject;
+
+PyObject *MenuObj_New(MenuHandle itself)
+{
+	MenuObject *it;
+	it = PyObject_NEW(MenuObject, &Menu_Type);
+	if (it == NULL) return NULL;
+	it->ob_itself = itself;
+	return (PyObject *)it;
+}
+
+int MenuObj_Convert(PyObject *v, MenuHandle *p_itself)
+{
+	if (!MenuObj_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "Menu required");
+		return 0;
+	}
+	*p_itself = ((MenuObject *)v)->ob_itself;
+	return 1;
+}
+
+static void MenuObj_dealloc(MenuObject *self)
+{
+	/* Cleanup of self->ob_itself goes here */
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *MenuObj_DisposeMenu(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef DisposeMenu
+	PyMac_PRECHECK(DisposeMenu);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	DisposeMenu(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_CalcMenuSize(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef CalcMenuSize
+	PyMac_PRECHECK(CalcMenuSize);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	CalcMenuSize(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_CountMenuItems(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	UInt16 _rv;
+#ifndef CountMenuItems
+	PyMac_PRECHECK(CountMenuItems);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CountMenuItems(_self->ob_itself);
+	_res = Py_BuildValue("H",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MenuObj_GetMenuFont(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	SInt16 outFontID;
+	UInt16 outFontSize;
+#ifndef GetMenuFont
+	PyMac_PRECHECK(GetMenuFont);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetMenuFont(_self->ob_itself,
+	                   &outFontID,
+	                   &outFontSize);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("hH",
+	                     outFontID,
+	                     outFontSize);
+	return _res;
+}
+
+static PyObject *MenuObj_SetMenuFont(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	SInt16 inFontID;
+	UInt16 inFontSize;
+#ifndef SetMenuFont
+	PyMac_PRECHECK(SetMenuFont);
+#endif
+	if (!PyArg_ParseTuple(_args, "hH",
+	                      &inFontID,
+	                      &inFontSize))
+		return NULL;
+	_err = SetMenuFont(_self->ob_itself,
+	                   inFontID,
+	                   inFontSize);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_GetMenuExcludesMarkColumn(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+#ifndef GetMenuExcludesMarkColumn
+	PyMac_PRECHECK(GetMenuExcludesMarkColumn);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetMenuExcludesMarkColumn(_self->ob_itself);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MenuObj_SetMenuExcludesMarkColumn(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Boolean excludesMark;
+#ifndef SetMenuExcludesMarkColumn
+	PyMac_PRECHECK(SetMenuExcludesMarkColumn);
+#endif
+	if (!PyArg_ParseTuple(_args, "b",
+	                      &excludesMark))
+		return NULL;
+	_err = SetMenuExcludesMarkColumn(_self->ob_itself,
+	                                 excludesMark);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_IsValidMenu(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+#ifndef IsValidMenu
+	PyMac_PRECHECK(IsValidMenu);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = IsValidMenu(_self->ob_itself);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MenuObj_GetMenuRetainCount(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ItemCount _rv;
+#ifndef GetMenuRetainCount
+	PyMac_PRECHECK(GetMenuRetainCount);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetMenuRetainCount(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MenuObj_RetainMenu(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+#ifndef RetainMenu
+	PyMac_PRECHECK(RetainMenu);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = RetainMenu(_self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_ReleaseMenu(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+#ifndef ReleaseMenu
+	PyMac_PRECHECK(ReleaseMenu);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = ReleaseMenu(_self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_DuplicateMenu(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	MenuHandle outMenu;
+#ifndef DuplicateMenu
+	PyMac_PRECHECK(DuplicateMenu);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = DuplicateMenu(_self->ob_itself,
+	                     &outMenu);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     MenuObj_New, outMenu);
+	return _res;
+}
+
+static PyObject *MenuObj_CopyMenuTitleAsCFString(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	CFStringRef outString;
+#ifndef CopyMenuTitleAsCFString
+	PyMac_PRECHECK(CopyMenuTitleAsCFString);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = CopyMenuTitleAsCFString(_self->ob_itself,
+	                               &outString);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, outString);
+	return _res;
+}
+
+static PyObject *MenuObj_SetMenuTitleWithCFString(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	CFStringRef inString;
+#ifndef SetMenuTitleWithCFString
+	PyMac_PRECHECK(SetMenuTitleWithCFString);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CFStringRefObj_Convert, &inString))
+		return NULL;
+	_err = SetMenuTitleWithCFString(_self->ob_itself,
+	                                inString);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_InvalidateMenuSize(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+#ifndef InvalidateMenuSize
+	PyMac_PRECHECK(InvalidateMenuSize);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = InvalidateMenuSize(_self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_IsMenuSizeInvalid(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+#ifndef IsMenuSizeInvalid
+	PyMac_PRECHECK(IsMenuSizeInvalid);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = IsMenuSizeInvalid(_self->ob_itself);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MenuObj_MacAppendMenu(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Str255 data;
+#ifndef MacAppendMenu
+	PyMac_PRECHECK(MacAppendMenu);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetStr255, data))
+		return NULL;
+	MacAppendMenu(_self->ob_itself,
+	              data);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_InsertResMenu(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ResType theType;
+	short afterItem;
+#ifndef InsertResMenu
+	PyMac_PRECHECK(InsertResMenu);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      PyMac_GetOSType, &theType,
+	                      &afterItem))
+		return NULL;
+	InsertResMenu(_self->ob_itself,
+	              theType,
+	              afterItem);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_AppendResMenu(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ResType theType;
+#ifndef AppendResMenu
+	PyMac_PRECHECK(AppendResMenu);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetOSType, &theType))
+		return NULL;
+	AppendResMenu(_self->ob_itself,
+	              theType);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_MacInsertMenuItem(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Str255 itemString;
+	short afterItem;
+#ifndef MacInsertMenuItem
+	PyMac_PRECHECK(MacInsertMenuItem);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      PyMac_GetStr255, itemString,
+	                      &afterItem))
+		return NULL;
+	MacInsertMenuItem(_self->ob_itself,
+	                  itemString,
+	                  afterItem);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_DeleteMenuItem(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short item;
+#ifndef DeleteMenuItem
+	PyMac_PRECHECK(DeleteMenuItem);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &item))
+		return NULL;
+	DeleteMenuItem(_self->ob_itself,
+	               item);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_InsertFontResMenu(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short afterItem;
+	short scriptFilter;
+#ifndef InsertFontResMenu
+	PyMac_PRECHECK(InsertFontResMenu);
+#endif
+	if (!PyArg_ParseTuple(_args, "hh",
+	                      &afterItem,
+	                      &scriptFilter))
+		return NULL;
+	InsertFontResMenu(_self->ob_itself,
+	                  afterItem,
+	                  scriptFilter);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_InsertIntlResMenu(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ResType theType;
+	short afterItem;
+	short scriptFilter;
+#ifndef InsertIntlResMenu
+	PyMac_PRECHECK(InsertIntlResMenu);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hh",
+	                      PyMac_GetOSType, &theType,
+	                      &afterItem,
+	                      &scriptFilter))
+		return NULL;
+	InsertIntlResMenu(_self->ob_itself,
+	                  theType,
+	                  afterItem,
+	                  scriptFilter);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_AppendMenuItemText(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Str255 inString;
+#ifndef AppendMenuItemText
+	PyMac_PRECHECK(AppendMenuItemText);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetStr255, inString))
+		return NULL;
+	_err = AppendMenuItemText(_self->ob_itself,
+	                          inString);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_InsertMenuItemText(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Str255 inString;
+	MenuItemIndex afterItem;
+#ifndef InsertMenuItemText
+	PyMac_PRECHECK(InsertMenuItemText);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      PyMac_GetStr255, inString,
+	                      &afterItem))
+		return NULL;
+	_err = InsertMenuItemText(_self->ob_itself,
+	                          inString,
+	                          afterItem);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_CopyMenuItems(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	MenuItemIndex inFirstItem;
+	ItemCount inNumItems;
+	MenuHandle inDestMenu;
+	MenuItemIndex inInsertAfter;
+#ifndef CopyMenuItems
+	PyMac_PRECHECK(CopyMenuItems);
+#endif
+	if (!PyArg_ParseTuple(_args, "hlO&h",
+	                      &inFirstItem,
+	                      &inNumItems,
+	                      MenuObj_Convert, &inDestMenu,
+	                      &inInsertAfter))
+		return NULL;
+	_err = CopyMenuItems(_self->ob_itself,
+	                     inFirstItem,
+	                     inNumItems,
+	                     inDestMenu,
+	                     inInsertAfter);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_DeleteMenuItems(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	MenuItemIndex inFirstItem;
+	ItemCount inNumItems;
+#ifndef DeleteMenuItems
+	PyMac_PRECHECK(DeleteMenuItems);
+#endif
+	if (!PyArg_ParseTuple(_args, "hl",
+	                      &inFirstItem,
+	                      &inNumItems))
+		return NULL;
+	_err = DeleteMenuItems(_self->ob_itself,
+	                       inFirstItem,
+	                       inNumItems);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_AppendMenuItemTextWithCFString(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	CFStringRef inString;
+	MenuItemAttributes inAttributes;
+	MenuCommand inCommandID;
+	MenuItemIndex outNewItem;
+#ifndef AppendMenuItemTextWithCFString
+	PyMac_PRECHECK(AppendMenuItemTextWithCFString);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&ll",
+	                      CFStringRefObj_Convert, &inString,
+	                      &inAttributes,
+	                      &inCommandID))
+		return NULL;
+	_err = AppendMenuItemTextWithCFString(_self->ob_itself,
+	                                      inString,
+	                                      inAttributes,
+	                                      inCommandID,
+	                                      &outNewItem);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("h",
+	                     outNewItem);
+	return _res;
+}
+
+static PyObject *MenuObj_InsertMenuItemTextWithCFString(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	CFStringRef inString;
+	MenuItemIndex inAfterItem;
+	MenuItemAttributes inAttributes;
+	MenuCommand inCommandID;
+#ifndef InsertMenuItemTextWithCFString
+	PyMac_PRECHECK(InsertMenuItemTextWithCFString);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hll",
+	                      CFStringRefObj_Convert, &inString,
+	                      &inAfterItem,
+	                      &inAttributes,
+	                      &inCommandID))
+		return NULL;
+	_err = InsertMenuItemTextWithCFString(_self->ob_itself,
+	                                      inString,
+	                                      inAfterItem,
+	                                      inAttributes,
+	                                      inCommandID);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_PopUpMenuSelect(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long _rv;
+	short top;
+	short left;
+	short popUpItem;
+#ifndef PopUpMenuSelect
+	PyMac_PRECHECK(PopUpMenuSelect);
+#endif
+	if (!PyArg_ParseTuple(_args, "hhh",
+	                      &top,
+	                      &left,
+	                      &popUpItem))
+		return NULL;
+	_rv = PopUpMenuSelect(_self->ob_itself,
+	                      top,
+	                      left,
+	                      popUpItem);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MenuObj_InvalidateMenuEnabling(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+#ifndef InvalidateMenuEnabling
+	PyMac_PRECHECK(InvalidateMenuEnabling);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = InvalidateMenuEnabling(_self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_IsMenuBarInvalid(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+#ifndef IsMenuBarInvalid
+	PyMac_PRECHECK(IsMenuBarInvalid);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = IsMenuBarInvalid(_self->ob_itself);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MenuObj_MacInsertMenu(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	MenuID beforeID;
+#ifndef MacInsertMenu
+	PyMac_PRECHECK(MacInsertMenu);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &beforeID))
+		return NULL;
+	MacInsertMenu(_self->ob_itself,
+	              beforeID);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_SetRootMenu(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+#ifndef SetRootMenu
+	PyMac_PRECHECK(SetRootMenu);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = SetRootMenu(_self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_MacCheckMenuItem(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short item;
+	Boolean checked;
+#ifndef MacCheckMenuItem
+	PyMac_PRECHECK(MacCheckMenuItem);
+#endif
+	if (!PyArg_ParseTuple(_args, "hb",
+	                      &item,
+	                      &checked))
+		return NULL;
+	MacCheckMenuItem(_self->ob_itself,
+	                 item,
+	                 checked);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_SetMenuItemText(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short item;
+	Str255 itemString;
+#ifndef SetMenuItemText
+	PyMac_PRECHECK(SetMenuItemText);
+#endif
+	if (!PyArg_ParseTuple(_args, "hO&",
+	                      &item,
+	                      PyMac_GetStr255, itemString))
+		return NULL;
+	SetMenuItemText(_self->ob_itself,
+	                item,
+	                itemString);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_GetMenuItemText(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short item;
+	Str255 itemString;
+#ifndef GetMenuItemText
+	PyMac_PRECHECK(GetMenuItemText);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &item))
+		return NULL;
+	GetMenuItemText(_self->ob_itself,
+	                item,
+	                itemString);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildStr255, itemString);
+	return _res;
+}
+
+static PyObject *MenuObj_SetItemMark(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short item;
+	CharParameter markChar;
+#ifndef SetItemMark
+	PyMac_PRECHECK(SetItemMark);
+#endif
+	if (!PyArg_ParseTuple(_args, "hh",
+	                      &item,
+	                      &markChar))
+		return NULL;
+	SetItemMark(_self->ob_itself,
+	            item,
+	            markChar);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_GetItemMark(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short item;
+	CharParameter markChar;
+#ifndef GetItemMark
+	PyMac_PRECHECK(GetItemMark);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &item))
+		return NULL;
+	GetItemMark(_self->ob_itself,
+	            item,
+	            &markChar);
+	_res = Py_BuildValue("h",
+	                     markChar);
+	return _res;
+}
+
+static PyObject *MenuObj_SetItemCmd(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short item;
+	CharParameter cmdChar;
+#ifndef SetItemCmd
+	PyMac_PRECHECK(SetItemCmd);
+#endif
+	if (!PyArg_ParseTuple(_args, "hh",
+	                      &item,
+	                      &cmdChar))
+		return NULL;
+	SetItemCmd(_self->ob_itself,
+	           item,
+	           cmdChar);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_GetItemCmd(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short item;
+	CharParameter cmdChar;
+#ifndef GetItemCmd
+	PyMac_PRECHECK(GetItemCmd);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &item))
+		return NULL;
+	GetItemCmd(_self->ob_itself,
+	           item,
+	           &cmdChar);
+	_res = Py_BuildValue("h",
+	                     cmdChar);
+	return _res;
+}
+
+static PyObject *MenuObj_SetItemIcon(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short item;
+	short iconIndex;
+#ifndef SetItemIcon
+	PyMac_PRECHECK(SetItemIcon);
+#endif
+	if (!PyArg_ParseTuple(_args, "hh",
+	                      &item,
+	                      &iconIndex))
+		return NULL;
+	SetItemIcon(_self->ob_itself,
+	            item,
+	            iconIndex);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_GetItemIcon(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short item;
+	short iconIndex;
+#ifndef GetItemIcon
+	PyMac_PRECHECK(GetItemIcon);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &item))
+		return NULL;
+	GetItemIcon(_self->ob_itself,
+	            item,
+	            &iconIndex);
+	_res = Py_BuildValue("h",
+	                     iconIndex);
+	return _res;
+}
+
+static PyObject *MenuObj_SetItemStyle(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short item;
+	StyleParameter chStyle;
+#ifndef SetItemStyle
+	PyMac_PRECHECK(SetItemStyle);
+#endif
+	if (!PyArg_ParseTuple(_args, "hh",
+	                      &item,
+	                      &chStyle))
+		return NULL;
+	SetItemStyle(_self->ob_itself,
+	             item,
+	             chStyle);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_GetItemStyle(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short item;
+	Style chStyle;
+#ifndef GetItemStyle
+	PyMac_PRECHECK(GetItemStyle);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &item))
+		return NULL;
+	GetItemStyle(_self->ob_itself,
+	             item,
+	             &chStyle);
+	_res = Py_BuildValue("b",
+	                     chStyle);
+	return _res;
+}
+
+static PyObject *MenuObj_SetMenuItemCommandID(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SInt16 inItem;
+	MenuCommand inCommandID;
+#ifndef SetMenuItemCommandID
+	PyMac_PRECHECK(SetMenuItemCommandID);
+#endif
+	if (!PyArg_ParseTuple(_args, "hl",
+	                      &inItem,
+	                      &inCommandID))
+		return NULL;
+	_err = SetMenuItemCommandID(_self->ob_itself,
+	                            inItem,
+	                            inCommandID);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_GetMenuItemCommandID(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SInt16 inItem;
+	MenuCommand outCommandID;
+#ifndef GetMenuItemCommandID
+	PyMac_PRECHECK(GetMenuItemCommandID);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &inItem))
+		return NULL;
+	_err = GetMenuItemCommandID(_self->ob_itself,
+	                            inItem,
+	                            &outCommandID);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     outCommandID);
+	return _res;
+}
+
+static PyObject *MenuObj_SetMenuItemModifiers(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SInt16 inItem;
+	UInt8 inModifiers;
+#ifndef SetMenuItemModifiers
+	PyMac_PRECHECK(SetMenuItemModifiers);
+#endif
+	if (!PyArg_ParseTuple(_args, "hb",
+	                      &inItem,
+	                      &inModifiers))
+		return NULL;
+	_err = SetMenuItemModifiers(_self->ob_itself,
+	                            inItem,
+	                            inModifiers);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_GetMenuItemModifiers(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SInt16 inItem;
+	UInt8 outModifiers;
+#ifndef GetMenuItemModifiers
+	PyMac_PRECHECK(GetMenuItemModifiers);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &inItem))
+		return NULL;
+	_err = GetMenuItemModifiers(_self->ob_itself,
+	                            inItem,
+	                            &outModifiers);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("b",
+	                     outModifiers);
+	return _res;
+}
+
+static PyObject *MenuObj_SetMenuItemIconHandle(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SInt16 inItem;
+	UInt8 inIconType;
+	Handle inIconHandle;
+#ifndef SetMenuItemIconHandle
+	PyMac_PRECHECK(SetMenuItemIconHandle);
+#endif
+	if (!PyArg_ParseTuple(_args, "hbO&",
+	                      &inItem,
+	                      &inIconType,
+	                      ResObj_Convert, &inIconHandle))
+		return NULL;
+	_err = SetMenuItemIconHandle(_self->ob_itself,
+	                             inItem,
+	                             inIconType,
+	                             inIconHandle);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_GetMenuItemIconHandle(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SInt16 inItem;
+	UInt8 outIconType;
+	Handle outIconHandle;
+#ifndef GetMenuItemIconHandle
+	PyMac_PRECHECK(GetMenuItemIconHandle);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &inItem))
+		return NULL;
+	_err = GetMenuItemIconHandle(_self->ob_itself,
+	                             inItem,
+	                             &outIconType,
+	                             &outIconHandle);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("bO&",
+	                     outIconType,
+	                     ResObj_New, outIconHandle);
+	return _res;
+}
+
+static PyObject *MenuObj_SetMenuItemTextEncoding(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SInt16 inItem;
+	TextEncoding inScriptID;
+#ifndef SetMenuItemTextEncoding
+	PyMac_PRECHECK(SetMenuItemTextEncoding);
+#endif
+	if (!PyArg_ParseTuple(_args, "hl",
+	                      &inItem,
+	                      &inScriptID))
+		return NULL;
+	_err = SetMenuItemTextEncoding(_self->ob_itself,
+	                               inItem,
+	                               inScriptID);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_GetMenuItemTextEncoding(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SInt16 inItem;
+	TextEncoding outScriptID;
+#ifndef GetMenuItemTextEncoding
+	PyMac_PRECHECK(GetMenuItemTextEncoding);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &inItem))
+		return NULL;
+	_err = GetMenuItemTextEncoding(_self->ob_itself,
+	                               inItem,
+	                               &outScriptID);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     outScriptID);
+	return _res;
+}
+
+static PyObject *MenuObj_SetMenuItemHierarchicalID(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SInt16 inItem;
+	MenuID inHierID;
+#ifndef SetMenuItemHierarchicalID
+	PyMac_PRECHECK(SetMenuItemHierarchicalID);
+#endif
+	if (!PyArg_ParseTuple(_args, "hh",
+	                      &inItem,
+	                      &inHierID))
+		return NULL;
+	_err = SetMenuItemHierarchicalID(_self->ob_itself,
+	                                 inItem,
+	                                 inHierID);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_GetMenuItemHierarchicalID(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SInt16 inItem;
+	MenuID outHierID;
+#ifndef GetMenuItemHierarchicalID
+	PyMac_PRECHECK(GetMenuItemHierarchicalID);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &inItem))
+		return NULL;
+	_err = GetMenuItemHierarchicalID(_self->ob_itself,
+	                                 inItem,
+	                                 &outHierID);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("h",
+	                     outHierID);
+	return _res;
+}
+
+static PyObject *MenuObj_SetMenuItemFontID(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SInt16 inItem;
+	SInt16 inFontID;
+#ifndef SetMenuItemFontID
+	PyMac_PRECHECK(SetMenuItemFontID);
+#endif
+	if (!PyArg_ParseTuple(_args, "hh",
+	                      &inItem,
+	                      &inFontID))
+		return NULL;
+	_err = SetMenuItemFontID(_self->ob_itself,
+	                         inItem,
+	                         inFontID);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_GetMenuItemFontID(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SInt16 inItem;
+	SInt16 outFontID;
+#ifndef GetMenuItemFontID
+	PyMac_PRECHECK(GetMenuItemFontID);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &inItem))
+		return NULL;
+	_err = GetMenuItemFontID(_self->ob_itself,
+	                         inItem,
+	                         &outFontID);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("h",
+	                     outFontID);
+	return _res;
+}
+
+static PyObject *MenuObj_SetMenuItemRefCon(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SInt16 inItem;
+	UInt32 inRefCon;
+#ifndef SetMenuItemRefCon
+	PyMac_PRECHECK(SetMenuItemRefCon);
+#endif
+	if (!PyArg_ParseTuple(_args, "hl",
+	                      &inItem,
+	                      &inRefCon))
+		return NULL;
+	_err = SetMenuItemRefCon(_self->ob_itself,
+	                         inItem,
+	                         inRefCon);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_GetMenuItemRefCon(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SInt16 inItem;
+	UInt32 outRefCon;
+#ifndef GetMenuItemRefCon
+	PyMac_PRECHECK(GetMenuItemRefCon);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &inItem))
+		return NULL;
+	_err = GetMenuItemRefCon(_self->ob_itself,
+	                         inItem,
+	                         &outRefCon);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     outRefCon);
+	return _res;
+}
+
+static PyObject *MenuObj_SetMenuItemKeyGlyph(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SInt16 inItem;
+	SInt16 inGlyph;
+#ifndef SetMenuItemKeyGlyph
+	PyMac_PRECHECK(SetMenuItemKeyGlyph);
+#endif
+	if (!PyArg_ParseTuple(_args, "hh",
+	                      &inItem,
+	                      &inGlyph))
+		return NULL;
+	_err = SetMenuItemKeyGlyph(_self->ob_itself,
+	                           inItem,
+	                           inGlyph);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_GetMenuItemKeyGlyph(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SInt16 inItem;
+	SInt16 outGlyph;
+#ifndef GetMenuItemKeyGlyph
+	PyMac_PRECHECK(GetMenuItemKeyGlyph);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &inItem))
+		return NULL;
+	_err = GetMenuItemKeyGlyph(_self->ob_itself,
+	                           inItem,
+	                           &outGlyph);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("h",
+	                     outGlyph);
+	return _res;
+}
+
+static PyObject *MenuObj_MacEnableMenuItem(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	MenuItemIndex item;
+#ifndef MacEnableMenuItem
+	PyMac_PRECHECK(MacEnableMenuItem);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &item))
+		return NULL;
+	MacEnableMenuItem(_self->ob_itself,
+	                  item);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_DisableMenuItem(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	MenuItemIndex item;
+#ifndef DisableMenuItem
+	PyMac_PRECHECK(DisableMenuItem);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &item))
+		return NULL;
+	DisableMenuItem(_self->ob_itself,
+	                item);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_IsMenuItemEnabled(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	MenuItemIndex item;
+#ifndef IsMenuItemEnabled
+	PyMac_PRECHECK(IsMenuItemEnabled);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &item))
+		return NULL;
+	_rv = IsMenuItemEnabled(_self->ob_itself,
+	                        item);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MenuObj_EnableMenuItemIcon(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	MenuItemIndex item;
+#ifndef EnableMenuItemIcon
+	PyMac_PRECHECK(EnableMenuItemIcon);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &item))
+		return NULL;
+	EnableMenuItemIcon(_self->ob_itself,
+	                   item);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_DisableMenuItemIcon(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	MenuItemIndex item;
+#ifndef DisableMenuItemIcon
+	PyMac_PRECHECK(DisableMenuItemIcon);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &item))
+		return NULL;
+	DisableMenuItemIcon(_self->ob_itself,
+	                    item);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_IsMenuItemIconEnabled(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	MenuItemIndex item;
+#ifndef IsMenuItemIconEnabled
+	PyMac_PRECHECK(IsMenuItemIconEnabled);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &item))
+		return NULL;
+	_rv = IsMenuItemIconEnabled(_self->ob_itself,
+	                            item);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MenuObj_SetMenuItemHierarchicalMenu(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	MenuItemIndex inItem;
+	MenuHandle inHierMenu;
+#ifndef SetMenuItemHierarchicalMenu
+	PyMac_PRECHECK(SetMenuItemHierarchicalMenu);
+#endif
+	if (!PyArg_ParseTuple(_args, "hO&",
+	                      &inItem,
+	                      MenuObj_Convert, &inHierMenu))
+		return NULL;
+	_err = SetMenuItemHierarchicalMenu(_self->ob_itself,
+	                                   inItem,
+	                                   inHierMenu);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_GetMenuItemHierarchicalMenu(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	MenuItemIndex inItem;
+	MenuHandle outHierMenu;
+#ifndef GetMenuItemHierarchicalMenu
+	PyMac_PRECHECK(GetMenuItemHierarchicalMenu);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &inItem))
+		return NULL;
+	_err = GetMenuItemHierarchicalMenu(_self->ob_itself,
+	                                   inItem,
+	                                   &outHierMenu);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     OptMenuObj_New, outHierMenu);
+	return _res;
+}
+
+static PyObject *MenuObj_CopyMenuItemTextAsCFString(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	MenuItemIndex inItem;
+	CFStringRef outString;
+#ifndef CopyMenuItemTextAsCFString
+	PyMac_PRECHECK(CopyMenuItemTextAsCFString);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &inItem))
+		return NULL;
+	_err = CopyMenuItemTextAsCFString(_self->ob_itself,
+	                                  inItem,
+	                                  &outString);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, outString);
+	return _res;
+}
+
+static PyObject *MenuObj_SetMenuItemTextWithCFString(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	MenuItemIndex inItem;
+	CFStringRef inString;
+#ifndef SetMenuItemTextWithCFString
+	PyMac_PRECHECK(SetMenuItemTextWithCFString);
+#endif
+	if (!PyArg_ParseTuple(_args, "hO&",
+	                      &inItem,
+	                      CFStringRefObj_Convert, &inString))
+		return NULL;
+	_err = SetMenuItemTextWithCFString(_self->ob_itself,
+	                                   inItem,
+	                                   inString);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_GetMenuItemIndent(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	MenuItemIndex inItem;
+	UInt32 outIndent;
+#ifndef GetMenuItemIndent
+	PyMac_PRECHECK(GetMenuItemIndent);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &inItem))
+		return NULL;
+	_err = GetMenuItemIndent(_self->ob_itself,
+	                         inItem,
+	                         &outIndent);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     outIndent);
+	return _res;
+}
+
+static PyObject *MenuObj_SetMenuItemIndent(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	MenuItemIndex inItem;
+	UInt32 inIndent;
+#ifndef SetMenuItemIndent
+	PyMac_PRECHECK(SetMenuItemIndent);
+#endif
+	if (!PyArg_ParseTuple(_args, "hl",
+	                      &inItem,
+	                      &inIndent))
+		return NULL;
+	_err = SetMenuItemIndent(_self->ob_itself,
+	                         inItem,
+	                         inIndent);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_GetMenuItemCommandKey(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	MenuItemIndex inItem;
+	Boolean inGetVirtualKey;
+	UInt16 outKey;
+#ifndef GetMenuItemCommandKey
+	PyMac_PRECHECK(GetMenuItemCommandKey);
+#endif
+	if (!PyArg_ParseTuple(_args, "hb",
+	                      &inItem,
+	                      &inGetVirtualKey))
+		return NULL;
+	_err = GetMenuItemCommandKey(_self->ob_itself,
+	                             inItem,
+	                             inGetVirtualKey,
+	                             &outKey);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("H",
+	                     outKey);
+	return _res;
+}
+
+static PyObject *MenuObj_SetMenuItemCommandKey(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	MenuItemIndex inItem;
+	Boolean inSetVirtualKey;
+	UInt16 inKey;
+#ifndef SetMenuItemCommandKey
+	PyMac_PRECHECK(SetMenuItemCommandKey);
+#endif
+	if (!PyArg_ParseTuple(_args, "hbH",
+	                      &inItem,
+	                      &inSetVirtualKey,
+	                      &inKey))
+		return NULL;
+	_err = SetMenuItemCommandKey(_self->ob_itself,
+	                             inItem,
+	                             inSetVirtualKey,
+	                             inKey);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_GetMenuItemPropertyAttributes(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	MenuItemIndex item;
+	OSType propertyCreator;
+	OSType propertyTag;
+	UInt32 attributes;
+#ifndef GetMenuItemPropertyAttributes
+	PyMac_PRECHECK(GetMenuItemPropertyAttributes);
+#endif
+	if (!PyArg_ParseTuple(_args, "hO&O&",
+	                      &item,
+	                      PyMac_GetOSType, &propertyCreator,
+	                      PyMac_GetOSType, &propertyTag))
+		return NULL;
+	_err = GetMenuItemPropertyAttributes(_self->ob_itself,
+	                                     item,
+	                                     propertyCreator,
+	                                     propertyTag,
+	                                     &attributes);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     attributes);
+	return _res;
+}
+
+static PyObject *MenuObj_ChangeMenuItemPropertyAttributes(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	MenuItemIndex item;
+	OSType propertyCreator;
+	OSType propertyTag;
+	UInt32 attributesToSet;
+	UInt32 attributesToClear;
+#ifndef ChangeMenuItemPropertyAttributes
+	PyMac_PRECHECK(ChangeMenuItemPropertyAttributes);
+#endif
+	if (!PyArg_ParseTuple(_args, "hO&O&ll",
+	                      &item,
+	                      PyMac_GetOSType, &propertyCreator,
+	                      PyMac_GetOSType, &propertyTag,
+	                      &attributesToSet,
+	                      &attributesToClear))
+		return NULL;
+	_err = ChangeMenuItemPropertyAttributes(_self->ob_itself,
+	                                        item,
+	                                        propertyCreator,
+	                                        propertyTag,
+	                                        attributesToSet,
+	                                        attributesToClear);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_GetMenuAttributes(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	MenuAttributes outAttributes;
+#ifndef GetMenuAttributes
+	PyMac_PRECHECK(GetMenuAttributes);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetMenuAttributes(_self->ob_itself,
+	                         &outAttributes);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     outAttributes);
+	return _res;
+}
+
+static PyObject *MenuObj_ChangeMenuAttributes(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	MenuAttributes setTheseAttributes;
+	MenuAttributes clearTheseAttributes;
+#ifndef ChangeMenuAttributes
+	PyMac_PRECHECK(ChangeMenuAttributes);
+#endif
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &setTheseAttributes,
+	                      &clearTheseAttributes))
+		return NULL;
+	_err = ChangeMenuAttributes(_self->ob_itself,
+	                            setTheseAttributes,
+	                            clearTheseAttributes);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_GetMenuItemAttributes(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	MenuItemIndex item;
+	MenuItemAttributes outAttributes;
+#ifndef GetMenuItemAttributes
+	PyMac_PRECHECK(GetMenuItemAttributes);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &item))
+		return NULL;
+	_err = GetMenuItemAttributes(_self->ob_itself,
+	                             item,
+	                             &outAttributes);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     outAttributes);
+	return _res;
+}
+
+static PyObject *MenuObj_ChangeMenuItemAttributes(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	MenuItemIndex item;
+	MenuItemAttributes setTheseAttributes;
+	MenuItemAttributes clearTheseAttributes;
+#ifndef ChangeMenuItemAttributes
+	PyMac_PRECHECK(ChangeMenuItemAttributes);
+#endif
+	if (!PyArg_ParseTuple(_args, "hll",
+	                      &item,
+	                      &setTheseAttributes,
+	                      &clearTheseAttributes))
+		return NULL;
+	_err = ChangeMenuItemAttributes(_self->ob_itself,
+	                                item,
+	                                setTheseAttributes,
+	                                clearTheseAttributes);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_DisableAllMenuItems(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef DisableAllMenuItems
+	PyMac_PRECHECK(DisableAllMenuItems);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	DisableAllMenuItems(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_EnableAllMenuItems(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef EnableAllMenuItems
+	PyMac_PRECHECK(EnableAllMenuItems);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	EnableAllMenuItems(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_MenuHasEnabledItems(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+#ifndef MenuHasEnabledItems
+	PyMac_PRECHECK(MenuHasEnabledItems);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = MenuHasEnabledItems(_self->ob_itself);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MenuObj_GetMenuType(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt16 outType;
+#ifndef GetMenuType
+	PyMac_PRECHECK(GetMenuType);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetMenuType(_self->ob_itself,
+	                   &outType);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("H",
+	                     outType);
+	return _res;
+}
+
+static PyObject *MenuObj_CountMenuItemsWithCommandID(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ItemCount _rv;
+	MenuCommand inCommandID;
+#ifndef CountMenuItemsWithCommandID
+	PyMac_PRECHECK(CountMenuItemsWithCommandID);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &inCommandID))
+		return NULL;
+	_rv = CountMenuItemsWithCommandID(_self->ob_itself,
+	                                  inCommandID);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MenuObj_GetIndMenuItemWithCommandID(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	MenuCommand inCommandID;
+	UInt32 inItemIndex;
+	MenuHandle outMenu;
+	MenuItemIndex outIndex;
+#ifndef GetIndMenuItemWithCommandID
+	PyMac_PRECHECK(GetIndMenuItemWithCommandID);
+#endif
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &inCommandID,
+	                      &inItemIndex))
+		return NULL;
+	_err = GetIndMenuItemWithCommandID(_self->ob_itself,
+	                                   inCommandID,
+	                                   inItemIndex,
+	                                   &outMenu,
+	                                   &outIndex);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&h",
+	                     MenuObj_New, outMenu,
+	                     outIndex);
+	return _res;
+}
+
+static PyObject *MenuObj_EnableMenuCommand(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	MenuCommand inCommandID;
+#ifndef EnableMenuCommand
+	PyMac_PRECHECK(EnableMenuCommand);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &inCommandID))
+		return NULL;
+	EnableMenuCommand(_self->ob_itself,
+	                  inCommandID);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_DisableMenuCommand(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	MenuCommand inCommandID;
+#ifndef DisableMenuCommand
+	PyMac_PRECHECK(DisableMenuCommand);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &inCommandID))
+		return NULL;
+	DisableMenuCommand(_self->ob_itself,
+	                   inCommandID);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_IsMenuCommandEnabled(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	MenuCommand inCommandID;
+#ifndef IsMenuCommandEnabled
+	PyMac_PRECHECK(IsMenuCommandEnabled);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &inCommandID))
+		return NULL;
+	_rv = IsMenuCommandEnabled(_self->ob_itself,
+	                           inCommandID);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MenuObj_SetMenuCommandMark(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	MenuCommand inCommandID;
+	UniChar inMark;
+#ifndef SetMenuCommandMark
+	PyMac_PRECHECK(SetMenuCommandMark);
+#endif
+	if (!PyArg_ParseTuple(_args, "lh",
+	                      &inCommandID,
+	                      &inMark))
+		return NULL;
+	_err = SetMenuCommandMark(_self->ob_itself,
+	                          inCommandID,
+	                          inMark);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_GetMenuCommandMark(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	MenuCommand inCommandID;
+	UniChar outMark;
+#ifndef GetMenuCommandMark
+	PyMac_PRECHECK(GetMenuCommandMark);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &inCommandID))
+		return NULL;
+	_err = GetMenuCommandMark(_self->ob_itself,
+	                          inCommandID,
+	                          &outMark);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("h",
+	                     outMark);
+	return _res;
+}
+
+static PyObject *MenuObj_GetMenuCommandPropertySize(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	MenuCommand inCommandID;
+	OSType inPropertyCreator;
+	OSType inPropertyTag;
+	ByteCount outSize;
+#ifndef GetMenuCommandPropertySize
+	PyMac_PRECHECK(GetMenuCommandPropertySize);
+#endif
+	if (!PyArg_ParseTuple(_args, "lO&O&",
+	                      &inCommandID,
+	                      PyMac_GetOSType, &inPropertyCreator,
+	                      PyMac_GetOSType, &inPropertyTag))
+		return NULL;
+	_err = GetMenuCommandPropertySize(_self->ob_itself,
+	                                  inCommandID,
+	                                  inPropertyCreator,
+	                                  inPropertyTag,
+	                                  &outSize);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     outSize);
+	return _res;
+}
+
+static PyObject *MenuObj_RemoveMenuCommandProperty(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	MenuCommand inCommandID;
+	OSType inPropertyCreator;
+	OSType inPropertyTag;
+#ifndef RemoveMenuCommandProperty
+	PyMac_PRECHECK(RemoveMenuCommandProperty);
+#endif
+	if (!PyArg_ParseTuple(_args, "lO&O&",
+	                      &inCommandID,
+	                      PyMac_GetOSType, &inPropertyCreator,
+	                      PyMac_GetOSType, &inPropertyTag))
+		return NULL;
+	_err = RemoveMenuCommandProperty(_self->ob_itself,
+	                                 inCommandID,
+	                                 inPropertyCreator,
+	                                 inPropertyTag);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_IsMenuItemInvalid(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	MenuItemIndex inItem;
+#ifndef IsMenuItemInvalid
+	PyMac_PRECHECK(IsMenuItemInvalid);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &inItem))
+		return NULL;
+	_rv = IsMenuItemInvalid(_self->ob_itself,
+	                        inItem);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MenuObj_InvalidateMenuItems(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	MenuItemIndex inFirstItem;
+	ItemCount inNumItems;
+#ifndef InvalidateMenuItems
+	PyMac_PRECHECK(InvalidateMenuItems);
+#endif
+	if (!PyArg_ParseTuple(_args, "hl",
+	                      &inFirstItem,
+	                      &inNumItems))
+		return NULL;
+	_err = InvalidateMenuItems(_self->ob_itself,
+	                           inFirstItem,
+	                           inNumItems);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_UpdateInvalidMenuItems(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+#ifndef UpdateInvalidMenuItems
+	PyMac_PRECHECK(UpdateInvalidMenuItems);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = UpdateInvalidMenuItems(_self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_CreateStandardFontMenu(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	MenuItemIndex afterItem;
+	MenuID firstHierMenuID;
+	OptionBits options;
+	ItemCount outHierMenuCount;
+#ifndef CreateStandardFontMenu
+	PyMac_PRECHECK(CreateStandardFontMenu);
+#endif
+	if (!PyArg_ParseTuple(_args, "hhl",
+	                      &afterItem,
+	                      &firstHierMenuID,
+	                      &options))
+		return NULL;
+	_err = CreateStandardFontMenu(_self->ob_itself,
+	                              afterItem,
+	                              firstHierMenuID,
+	                              options,
+	                              &outHierMenuCount);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     outHierMenuCount);
+	return _res;
+}
+
+static PyObject *MenuObj_UpdateStandardFontMenu(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	ItemCount outHierMenuCount;
+#ifndef UpdateStandardFontMenu
+	PyMac_PRECHECK(UpdateStandardFontMenu);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = UpdateStandardFontMenu(_self->ob_itself,
+	                              &outHierMenuCount);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     outHierMenuCount);
+	return _res;
+}
+
+static PyObject *MenuObj_GetFontFamilyFromMenuSelection(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	MenuItemIndex item;
+	FMFontFamily outFontFamily;
+	FMFontStyle outStyle;
+#ifndef GetFontFamilyFromMenuSelection
+	PyMac_PRECHECK(GetFontFamilyFromMenuSelection);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &item))
+		return NULL;
+	_err = GetFontFamilyFromMenuSelection(_self->ob_itself,
+	                                      item,
+	                                      &outFontFamily,
+	                                      &outStyle);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("hh",
+	                     outFontFamily,
+	                     outStyle);
+	return _res;
+}
+
+static PyObject *MenuObj_GetMenuID(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	MenuID _rv;
+#ifndef GetMenuID
+	PyMac_PRECHECK(GetMenuID);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetMenuID(_self->ob_itself);
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MenuObj_GetMenuWidth(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	SInt16 _rv;
+#ifndef GetMenuWidth
+	PyMac_PRECHECK(GetMenuWidth);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetMenuWidth(_self->ob_itself);
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MenuObj_GetMenuHeight(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	SInt16 _rv;
+#ifndef GetMenuHeight
+	PyMac_PRECHECK(GetMenuHeight);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetMenuHeight(_self->ob_itself);
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MenuObj_SetMenuID(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	MenuID menuID;
+#ifndef SetMenuID
+	PyMac_PRECHECK(SetMenuID);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &menuID))
+		return NULL;
+	SetMenuID(_self->ob_itself,
+	          menuID);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_SetMenuWidth(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	SInt16 width;
+#ifndef SetMenuWidth
+	PyMac_PRECHECK(SetMenuWidth);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &width))
+		return NULL;
+	SetMenuWidth(_self->ob_itself,
+	             width);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_SetMenuHeight(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	SInt16 height;
+#ifndef SetMenuHeight
+	PyMac_PRECHECK(SetMenuHeight);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &height))
+		return NULL;
+	SetMenuHeight(_self->ob_itself,
+	              height);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_as_Resource(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Handle _rv;
+#ifndef as_Resource
+	PyMac_PRECHECK(as_Resource);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = as_Resource(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *MenuObj_AppendMenu(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Str255 data;
+#ifndef AppendMenu
+	PyMac_PRECHECK(AppendMenu);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetStr255, data))
+		return NULL;
+	AppendMenu(_self->ob_itself,
+	           data);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_InsertMenu(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short beforeID;
+#ifndef InsertMenu
+	PyMac_PRECHECK(InsertMenu);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &beforeID))
+		return NULL;
+	InsertMenu(_self->ob_itself,
+	           beforeID);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_InsertMenuItem(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Str255 itemString;
+	short afterItem;
+#ifndef InsertMenuItem
+	PyMac_PRECHECK(InsertMenuItem);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      PyMac_GetStr255, itemString,
+	                      &afterItem))
+		return NULL;
+	InsertMenuItem(_self->ob_itself,
+	               itemString,
+	               afterItem);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_EnableMenuItem(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	UInt16 item;
+#ifndef EnableMenuItem
+	PyMac_PRECHECK(EnableMenuItem);
+#endif
+	if (!PyArg_ParseTuple(_args, "H",
+	                      &item))
+		return NULL;
+	EnableMenuItem(_self->ob_itself,
+	               item);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MenuObj_CheckMenuItem(MenuObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short item;
+	Boolean checked;
+#ifndef CheckMenuItem
+	PyMac_PRECHECK(CheckMenuItem);
+#endif
+	if (!PyArg_ParseTuple(_args, "hb",
+	                      &item,
+	                      &checked))
+		return NULL;
+	CheckMenuItem(_self->ob_itself,
+	              item,
+	              checked);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyMethodDef MenuObj_methods[] = {
+	{"DisposeMenu", (PyCFunction)MenuObj_DisposeMenu, 1,
+	 PyDoc_STR("() -> None")},
+	{"CalcMenuSize", (PyCFunction)MenuObj_CalcMenuSize, 1,
+	 PyDoc_STR("() -> None")},
+	{"CountMenuItems", (PyCFunction)MenuObj_CountMenuItems, 1,
+	 PyDoc_STR("() -> (UInt16 _rv)")},
+	{"GetMenuFont", (PyCFunction)MenuObj_GetMenuFont, 1,
+	 PyDoc_STR("() -> (SInt16 outFontID, UInt16 outFontSize)")},
+	{"SetMenuFont", (PyCFunction)MenuObj_SetMenuFont, 1,
+	 PyDoc_STR("(SInt16 inFontID, UInt16 inFontSize) -> None")},
+	{"GetMenuExcludesMarkColumn", (PyCFunction)MenuObj_GetMenuExcludesMarkColumn, 1,
+	 PyDoc_STR("() -> (Boolean _rv)")},
+	{"SetMenuExcludesMarkColumn", (PyCFunction)MenuObj_SetMenuExcludesMarkColumn, 1,
+	 PyDoc_STR("(Boolean excludesMark) -> None")},
+	{"IsValidMenu", (PyCFunction)MenuObj_IsValidMenu, 1,
+	 PyDoc_STR("() -> (Boolean _rv)")},
+	{"GetMenuRetainCount", (PyCFunction)MenuObj_GetMenuRetainCount, 1,
+	 PyDoc_STR("() -> (ItemCount _rv)")},
+	{"RetainMenu", (PyCFunction)MenuObj_RetainMenu, 1,
+	 PyDoc_STR("() -> None")},
+	{"ReleaseMenu", (PyCFunction)MenuObj_ReleaseMenu, 1,
+	 PyDoc_STR("() -> None")},
+	{"DuplicateMenu", (PyCFunction)MenuObj_DuplicateMenu, 1,
+	 PyDoc_STR("() -> (MenuHandle outMenu)")},
+	{"CopyMenuTitleAsCFString", (PyCFunction)MenuObj_CopyMenuTitleAsCFString, 1,
+	 PyDoc_STR("() -> (CFStringRef outString)")},
+	{"SetMenuTitleWithCFString", (PyCFunction)MenuObj_SetMenuTitleWithCFString, 1,
+	 PyDoc_STR("(CFStringRef inString) -> None")},
+	{"InvalidateMenuSize", (PyCFunction)MenuObj_InvalidateMenuSize, 1,
+	 PyDoc_STR("() -> None")},
+	{"IsMenuSizeInvalid", (PyCFunction)MenuObj_IsMenuSizeInvalid, 1,
+	 PyDoc_STR("() -> (Boolean _rv)")},
+	{"MacAppendMenu", (PyCFunction)MenuObj_MacAppendMenu, 1,
+	 PyDoc_STR("(Str255 data) -> None")},
+	{"InsertResMenu", (PyCFunction)MenuObj_InsertResMenu, 1,
+	 PyDoc_STR("(ResType theType, short afterItem) -> None")},
+	{"AppendResMenu", (PyCFunction)MenuObj_AppendResMenu, 1,
+	 PyDoc_STR("(ResType theType) -> None")},
+	{"MacInsertMenuItem", (PyCFunction)MenuObj_MacInsertMenuItem, 1,
+	 PyDoc_STR("(Str255 itemString, short afterItem) -> None")},
+	{"DeleteMenuItem", (PyCFunction)MenuObj_DeleteMenuItem, 1,
+	 PyDoc_STR("(short item) -> None")},
+	{"InsertFontResMenu", (PyCFunction)MenuObj_InsertFontResMenu, 1,
+	 PyDoc_STR("(short afterItem, short scriptFilter) -> None")},
+	{"InsertIntlResMenu", (PyCFunction)MenuObj_InsertIntlResMenu, 1,
+	 PyDoc_STR("(ResType theType, short afterItem, short scriptFilter) -> None")},
+	{"AppendMenuItemText", (PyCFunction)MenuObj_AppendMenuItemText, 1,
+	 PyDoc_STR("(Str255 inString) -> None")},
+	{"InsertMenuItemText", (PyCFunction)MenuObj_InsertMenuItemText, 1,
+	 PyDoc_STR("(Str255 inString, MenuItemIndex afterItem) -> None")},
+	{"CopyMenuItems", (PyCFunction)MenuObj_CopyMenuItems, 1,
+	 PyDoc_STR("(MenuItemIndex inFirstItem, ItemCount inNumItems, MenuHandle inDestMenu, MenuItemIndex inInsertAfter) -> None")},
+	{"DeleteMenuItems", (PyCFunction)MenuObj_DeleteMenuItems, 1,
+	 PyDoc_STR("(MenuItemIndex inFirstItem, ItemCount inNumItems) -> None")},
+	{"AppendMenuItemTextWithCFString", (PyCFunction)MenuObj_AppendMenuItemTextWithCFString, 1,
+	 PyDoc_STR("(CFStringRef inString, MenuItemAttributes inAttributes, MenuCommand inCommandID) -> (MenuItemIndex outNewItem)")},
+	{"InsertMenuItemTextWithCFString", (PyCFunction)MenuObj_InsertMenuItemTextWithCFString, 1,
+	 PyDoc_STR("(CFStringRef inString, MenuItemIndex inAfterItem, MenuItemAttributes inAttributes, MenuCommand inCommandID) -> None")},
+	{"PopUpMenuSelect", (PyCFunction)MenuObj_PopUpMenuSelect, 1,
+	 PyDoc_STR("(short top, short left, short popUpItem) -> (long _rv)")},
+	{"InvalidateMenuEnabling", (PyCFunction)MenuObj_InvalidateMenuEnabling, 1,
+	 PyDoc_STR("() -> None")},
+	{"IsMenuBarInvalid", (PyCFunction)MenuObj_IsMenuBarInvalid, 1,
+	 PyDoc_STR("() -> (Boolean _rv)")},
+	{"MacInsertMenu", (PyCFunction)MenuObj_MacInsertMenu, 1,
+	 PyDoc_STR("(MenuID beforeID) -> None")},
+	{"SetRootMenu", (PyCFunction)MenuObj_SetRootMenu, 1,
+	 PyDoc_STR("() -> None")},
+	{"MacCheckMenuItem", (PyCFunction)MenuObj_MacCheckMenuItem, 1,
+	 PyDoc_STR("(short item, Boolean checked) -> None")},
+	{"SetMenuItemText", (PyCFunction)MenuObj_SetMenuItemText, 1,
+	 PyDoc_STR("(short item, Str255 itemString) -> None")},
+	{"GetMenuItemText", (PyCFunction)MenuObj_GetMenuItemText, 1,
+	 PyDoc_STR("(short item) -> (Str255 itemString)")},
+	{"SetItemMark", (PyCFunction)MenuObj_SetItemMark, 1,
+	 PyDoc_STR("(short item, CharParameter markChar) -> None")},
+	{"GetItemMark", (PyCFunction)MenuObj_GetItemMark, 1,
+	 PyDoc_STR("(short item) -> (CharParameter markChar)")},
+	{"SetItemCmd", (PyCFunction)MenuObj_SetItemCmd, 1,
+	 PyDoc_STR("(short item, CharParameter cmdChar) -> None")},
+	{"GetItemCmd", (PyCFunction)MenuObj_GetItemCmd, 1,
+	 PyDoc_STR("(short item) -> (CharParameter cmdChar)")},
+	{"SetItemIcon", (PyCFunction)MenuObj_SetItemIcon, 1,
+	 PyDoc_STR("(short item, short iconIndex) -> None")},
+	{"GetItemIcon", (PyCFunction)MenuObj_GetItemIcon, 1,
+	 PyDoc_STR("(short item) -> (short iconIndex)")},
+	{"SetItemStyle", (PyCFunction)MenuObj_SetItemStyle, 1,
+	 PyDoc_STR("(short item, StyleParameter chStyle) -> None")},
+	{"GetItemStyle", (PyCFunction)MenuObj_GetItemStyle, 1,
+	 PyDoc_STR("(short item) -> (Style chStyle)")},
+	{"SetMenuItemCommandID", (PyCFunction)MenuObj_SetMenuItemCommandID, 1,
+	 PyDoc_STR("(SInt16 inItem, MenuCommand inCommandID) -> None")},
+	{"GetMenuItemCommandID", (PyCFunction)MenuObj_GetMenuItemCommandID, 1,
+	 PyDoc_STR("(SInt16 inItem) -> (MenuCommand outCommandID)")},
+	{"SetMenuItemModifiers", (PyCFunction)MenuObj_SetMenuItemModifiers, 1,
+	 PyDoc_STR("(SInt16 inItem, UInt8 inModifiers) -> None")},
+	{"GetMenuItemModifiers", (PyCFunction)MenuObj_GetMenuItemModifiers, 1,
+	 PyDoc_STR("(SInt16 inItem) -> (UInt8 outModifiers)")},
+	{"SetMenuItemIconHandle", (PyCFunction)MenuObj_SetMenuItemIconHandle, 1,
+	 PyDoc_STR("(SInt16 inItem, UInt8 inIconType, Handle inIconHandle) -> None")},
+	{"GetMenuItemIconHandle", (PyCFunction)MenuObj_GetMenuItemIconHandle, 1,
+	 PyDoc_STR("(SInt16 inItem) -> (UInt8 outIconType, Handle outIconHandle)")},
+	{"SetMenuItemTextEncoding", (PyCFunction)MenuObj_SetMenuItemTextEncoding, 1,
+	 PyDoc_STR("(SInt16 inItem, TextEncoding inScriptID) -> None")},
+	{"GetMenuItemTextEncoding", (PyCFunction)MenuObj_GetMenuItemTextEncoding, 1,
+	 PyDoc_STR("(SInt16 inItem) -> (TextEncoding outScriptID)")},
+	{"SetMenuItemHierarchicalID", (PyCFunction)MenuObj_SetMenuItemHierarchicalID, 1,
+	 PyDoc_STR("(SInt16 inItem, MenuID inHierID) -> None")},
+	{"GetMenuItemHierarchicalID", (PyCFunction)MenuObj_GetMenuItemHierarchicalID, 1,
+	 PyDoc_STR("(SInt16 inItem) -> (MenuID outHierID)")},
+	{"SetMenuItemFontID", (PyCFunction)MenuObj_SetMenuItemFontID, 1,
+	 PyDoc_STR("(SInt16 inItem, SInt16 inFontID) -> None")},
+	{"GetMenuItemFontID", (PyCFunction)MenuObj_GetMenuItemFontID, 1,
+	 PyDoc_STR("(SInt16 inItem) -> (SInt16 outFontID)")},
+	{"SetMenuItemRefCon", (PyCFunction)MenuObj_SetMenuItemRefCon, 1,
+	 PyDoc_STR("(SInt16 inItem, UInt32 inRefCon) -> None")},
+	{"GetMenuItemRefCon", (PyCFunction)MenuObj_GetMenuItemRefCon, 1,
+	 PyDoc_STR("(SInt16 inItem) -> (UInt32 outRefCon)")},
+	{"SetMenuItemKeyGlyph", (PyCFunction)MenuObj_SetMenuItemKeyGlyph, 1,
+	 PyDoc_STR("(SInt16 inItem, SInt16 inGlyph) -> None")},
+	{"GetMenuItemKeyGlyph", (PyCFunction)MenuObj_GetMenuItemKeyGlyph, 1,
+	 PyDoc_STR("(SInt16 inItem) -> (SInt16 outGlyph)")},
+	{"MacEnableMenuItem", (PyCFunction)MenuObj_MacEnableMenuItem, 1,
+	 PyDoc_STR("(MenuItemIndex item) -> None")},
+	{"DisableMenuItem", (PyCFunction)MenuObj_DisableMenuItem, 1,
+	 PyDoc_STR("(MenuItemIndex item) -> None")},
+	{"IsMenuItemEnabled", (PyCFunction)MenuObj_IsMenuItemEnabled, 1,
+	 PyDoc_STR("(MenuItemIndex item) -> (Boolean _rv)")},
+	{"EnableMenuItemIcon", (PyCFunction)MenuObj_EnableMenuItemIcon, 1,
+	 PyDoc_STR("(MenuItemIndex item) -> None")},
+	{"DisableMenuItemIcon", (PyCFunction)MenuObj_DisableMenuItemIcon, 1,
+	 PyDoc_STR("(MenuItemIndex item) -> None")},
+	{"IsMenuItemIconEnabled", (PyCFunction)MenuObj_IsMenuItemIconEnabled, 1,
+	 PyDoc_STR("(MenuItemIndex item) -> (Boolean _rv)")},
+	{"SetMenuItemHierarchicalMenu", (PyCFunction)MenuObj_SetMenuItemHierarchicalMenu, 1,
+	 PyDoc_STR("(MenuItemIndex inItem, MenuHandle inHierMenu) -> None")},
+	{"GetMenuItemHierarchicalMenu", (PyCFunction)MenuObj_GetMenuItemHierarchicalMenu, 1,
+	 PyDoc_STR("(MenuItemIndex inItem) -> (MenuHandle outHierMenu)")},
+	{"CopyMenuItemTextAsCFString", (PyCFunction)MenuObj_CopyMenuItemTextAsCFString, 1,
+	 PyDoc_STR("(MenuItemIndex inItem) -> (CFStringRef outString)")},
+	{"SetMenuItemTextWithCFString", (PyCFunction)MenuObj_SetMenuItemTextWithCFString, 1,
+	 PyDoc_STR("(MenuItemIndex inItem, CFStringRef inString) -> None")},
+	{"GetMenuItemIndent", (PyCFunction)MenuObj_GetMenuItemIndent, 1,
+	 PyDoc_STR("(MenuItemIndex inItem) -> (UInt32 outIndent)")},
+	{"SetMenuItemIndent", (PyCFunction)MenuObj_SetMenuItemIndent, 1,
+	 PyDoc_STR("(MenuItemIndex inItem, UInt32 inIndent) -> None")},
+	{"GetMenuItemCommandKey", (PyCFunction)MenuObj_GetMenuItemCommandKey, 1,
+	 PyDoc_STR("(MenuItemIndex inItem, Boolean inGetVirtualKey) -> (UInt16 outKey)")},
+	{"SetMenuItemCommandKey", (PyCFunction)MenuObj_SetMenuItemCommandKey, 1,
+	 PyDoc_STR("(MenuItemIndex inItem, Boolean inSetVirtualKey, UInt16 inKey) -> None")},
+	{"GetMenuItemPropertyAttributes", (PyCFunction)MenuObj_GetMenuItemPropertyAttributes, 1,
+	 PyDoc_STR("(MenuItemIndex item, OSType propertyCreator, OSType propertyTag) -> (UInt32 attributes)")},
+	{"ChangeMenuItemPropertyAttributes", (PyCFunction)MenuObj_ChangeMenuItemPropertyAttributes, 1,
+	 PyDoc_STR("(MenuItemIndex item, OSType propertyCreator, OSType propertyTag, UInt32 attributesToSet, UInt32 attributesToClear) -> None")},
+	{"GetMenuAttributes", (PyCFunction)MenuObj_GetMenuAttributes, 1,
+	 PyDoc_STR("() -> (MenuAttributes outAttributes)")},
+	{"ChangeMenuAttributes", (PyCFunction)MenuObj_ChangeMenuAttributes, 1,
+	 PyDoc_STR("(MenuAttributes setTheseAttributes, MenuAttributes clearTheseAttributes) -> None")},
+	{"GetMenuItemAttributes", (PyCFunction)MenuObj_GetMenuItemAttributes, 1,
+	 PyDoc_STR("(MenuItemIndex item) -> (MenuItemAttributes outAttributes)")},
+	{"ChangeMenuItemAttributes", (PyCFunction)MenuObj_ChangeMenuItemAttributes, 1,
+	 PyDoc_STR("(MenuItemIndex item, MenuItemAttributes setTheseAttributes, MenuItemAttributes clearTheseAttributes) -> None")},
+	{"DisableAllMenuItems", (PyCFunction)MenuObj_DisableAllMenuItems, 1,
+	 PyDoc_STR("() -> None")},
+	{"EnableAllMenuItems", (PyCFunction)MenuObj_EnableAllMenuItems, 1,
+	 PyDoc_STR("() -> None")},
+	{"MenuHasEnabledItems", (PyCFunction)MenuObj_MenuHasEnabledItems, 1,
+	 PyDoc_STR("() -> (Boolean _rv)")},
+	{"GetMenuType", (PyCFunction)MenuObj_GetMenuType, 1,
+	 PyDoc_STR("() -> (UInt16 outType)")},
+	{"CountMenuItemsWithCommandID", (PyCFunction)MenuObj_CountMenuItemsWithCommandID, 1,
+	 PyDoc_STR("(MenuCommand inCommandID) -> (ItemCount _rv)")},
+	{"GetIndMenuItemWithCommandID", (PyCFunction)MenuObj_GetIndMenuItemWithCommandID, 1,
+	 PyDoc_STR("(MenuCommand inCommandID, UInt32 inItemIndex) -> (MenuHandle outMenu, MenuItemIndex outIndex)")},
+	{"EnableMenuCommand", (PyCFunction)MenuObj_EnableMenuCommand, 1,
+	 PyDoc_STR("(MenuCommand inCommandID) -> None")},
+	{"DisableMenuCommand", (PyCFunction)MenuObj_DisableMenuCommand, 1,
+	 PyDoc_STR("(MenuCommand inCommandID) -> None")},
+	{"IsMenuCommandEnabled", (PyCFunction)MenuObj_IsMenuCommandEnabled, 1,
+	 PyDoc_STR("(MenuCommand inCommandID) -> (Boolean _rv)")},
+	{"SetMenuCommandMark", (PyCFunction)MenuObj_SetMenuCommandMark, 1,
+	 PyDoc_STR("(MenuCommand inCommandID, UniChar inMark) -> None")},
+	{"GetMenuCommandMark", (PyCFunction)MenuObj_GetMenuCommandMark, 1,
+	 PyDoc_STR("(MenuCommand inCommandID) -> (UniChar outMark)")},
+	{"GetMenuCommandPropertySize", (PyCFunction)MenuObj_GetMenuCommandPropertySize, 1,
+	 PyDoc_STR("(MenuCommand inCommandID, OSType inPropertyCreator, OSType inPropertyTag) -> (ByteCount outSize)")},
+	{"RemoveMenuCommandProperty", (PyCFunction)MenuObj_RemoveMenuCommandProperty, 1,
+	 PyDoc_STR("(MenuCommand inCommandID, OSType inPropertyCreator, OSType inPropertyTag) -> None")},
+	{"IsMenuItemInvalid", (PyCFunction)MenuObj_IsMenuItemInvalid, 1,
+	 PyDoc_STR("(MenuItemIndex inItem) -> (Boolean _rv)")},
+	{"InvalidateMenuItems", (PyCFunction)MenuObj_InvalidateMenuItems, 1,
+	 PyDoc_STR("(MenuItemIndex inFirstItem, ItemCount inNumItems) -> None")},
+	{"UpdateInvalidMenuItems", (PyCFunction)MenuObj_UpdateInvalidMenuItems, 1,
+	 PyDoc_STR("() -> None")},
+	{"CreateStandardFontMenu", (PyCFunction)MenuObj_CreateStandardFontMenu, 1,
+	 PyDoc_STR("(MenuItemIndex afterItem, MenuID firstHierMenuID, OptionBits options) -> (ItemCount outHierMenuCount)")},
+	{"UpdateStandardFontMenu", (PyCFunction)MenuObj_UpdateStandardFontMenu, 1,
+	 PyDoc_STR("() -> (ItemCount outHierMenuCount)")},
+	{"GetFontFamilyFromMenuSelection", (PyCFunction)MenuObj_GetFontFamilyFromMenuSelection, 1,
+	 PyDoc_STR("(MenuItemIndex item) -> (FMFontFamily outFontFamily, FMFontStyle outStyle)")},
+	{"GetMenuID", (PyCFunction)MenuObj_GetMenuID, 1,
+	 PyDoc_STR("() -> (MenuID _rv)")},
+	{"GetMenuWidth", (PyCFunction)MenuObj_GetMenuWidth, 1,
+	 PyDoc_STR("() -> (SInt16 _rv)")},
+	{"GetMenuHeight", (PyCFunction)MenuObj_GetMenuHeight, 1,
+	 PyDoc_STR("() -> (SInt16 _rv)")},
+	{"SetMenuID", (PyCFunction)MenuObj_SetMenuID, 1,
+	 PyDoc_STR("(MenuID menuID) -> None")},
+	{"SetMenuWidth", (PyCFunction)MenuObj_SetMenuWidth, 1,
+	 PyDoc_STR("(SInt16 width) -> None")},
+	{"SetMenuHeight", (PyCFunction)MenuObj_SetMenuHeight, 1,
+	 PyDoc_STR("(SInt16 height) -> None")},
+	{"as_Resource", (PyCFunction)MenuObj_as_Resource, 1,
+	 PyDoc_STR("() -> (Handle _rv)")},
+	{"AppendMenu", (PyCFunction)MenuObj_AppendMenu, 1,
+	 PyDoc_STR("(Str255 data) -> None")},
+	{"InsertMenu", (PyCFunction)MenuObj_InsertMenu, 1,
+	 PyDoc_STR("(short beforeID) -> None")},
+	{"InsertMenuItem", (PyCFunction)MenuObj_InsertMenuItem, 1,
+	 PyDoc_STR("(Str255 itemString, short afterItem) -> None")},
+	{"EnableMenuItem", (PyCFunction)MenuObj_EnableMenuItem, 1,
+	 PyDoc_STR("(UInt16 item) -> None")},
+	{"CheckMenuItem", (PyCFunction)MenuObj_CheckMenuItem, 1,
+	 PyDoc_STR("(short item, Boolean checked) -> None")},
+	{NULL, NULL, 0}
+};
+
+#define MenuObj_getsetlist NULL
+
+
+#define MenuObj_compare NULL
+
+#define MenuObj_repr NULL
+
+#define MenuObj_hash NULL
+#define MenuObj_tp_init 0
+
+#define MenuObj_tp_alloc PyType_GenericAlloc
+
+static PyObject *MenuObj_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *_self;
+	MenuHandle itself;
+	char *kw[] = {"itself", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, MenuObj_Convert, &itself)) return NULL;
+	if ((_self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	((MenuObject *)_self)->ob_itself = itself;
+	return _self;
+}
+
+#define MenuObj_tp_free PyObject_Del
+
+
+PyTypeObject Menu_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"_Menu.Menu", /*tp_name*/
+	sizeof(MenuObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) MenuObj_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) MenuObj_compare, /*tp_compare*/
+	(reprfunc) MenuObj_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) MenuObj_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	MenuObj_methods, /* tp_methods */
+	0, /*tp_members*/
+	MenuObj_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	MenuObj_tp_init, /* tp_init */
+	MenuObj_tp_alloc, /* tp_alloc */
+	MenuObj_tp_new, /* tp_new */
+	MenuObj_tp_free, /* tp_free */
+};
+
+/* ---------------------- End object type Menu ---------------------- */
+
+
+static PyObject *Menu_NewMenu(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	MenuHandle _rv;
+	MenuID menuID;
+	Str255 menuTitle;
+#ifndef NewMenu
+	PyMac_PRECHECK(NewMenu);
+#endif
+	if (!PyArg_ParseTuple(_args, "hO&",
+	                      &menuID,
+	                      PyMac_GetStr255, menuTitle))
+		return NULL;
+	_rv = NewMenu(menuID,
+	              menuTitle);
+	_res = Py_BuildValue("O&",
+	                     MenuObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Menu_MacGetMenu(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	MenuHandle _rv;
+	short resourceID;
+#ifndef MacGetMenu
+	PyMac_PRECHECK(MacGetMenu);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &resourceID))
+		return NULL;
+	_rv = MacGetMenu(resourceID);
+	_res = Py_BuildValue("O&",
+	                     MenuObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Menu_CreateNewMenu(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	MenuID inMenuID;
+	MenuAttributes inMenuAttributes;
+	MenuHandle outMenuRef;
+#ifndef CreateNewMenu
+	PyMac_PRECHECK(CreateNewMenu);
+#endif
+	if (!PyArg_ParseTuple(_args, "hl",
+	                      &inMenuID,
+	                      &inMenuAttributes))
+		return NULL;
+	_err = CreateNewMenu(inMenuID,
+	                     inMenuAttributes,
+	                     &outMenuRef);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     MenuObj_New, outMenuRef);
+	return _res;
+}
+
+static PyObject *Menu_MenuKey(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long _rv;
+	CharParameter ch;
+#ifndef MenuKey
+	PyMac_PRECHECK(MenuKey);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &ch))
+		return NULL;
+	_rv = MenuKey(ch);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Menu_MenuSelect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long _rv;
+	Point startPt;
+#ifndef MenuSelect
+	PyMac_PRECHECK(MenuSelect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetPoint, &startPt))
+		return NULL;
+	_rv = MenuSelect(startPt);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Menu_MenuChoice(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long _rv;
+#ifndef MenuChoice
+	PyMac_PRECHECK(MenuChoice);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = MenuChoice();
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Menu_MenuEvent(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	UInt32 _rv;
+	EventRecord inEvent;
+#ifndef MenuEvent
+	PyMac_PRECHECK(MenuEvent);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetEventRecord, &inEvent))
+		return NULL;
+	_rv = MenuEvent(&inEvent);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Menu_GetMBarHeight(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short _rv;
+#ifndef GetMBarHeight
+	PyMac_PRECHECK(GetMBarHeight);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetMBarHeight();
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Menu_MacDrawMenuBar(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef MacDrawMenuBar
+	PyMac_PRECHECK(MacDrawMenuBar);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	MacDrawMenuBar();
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Menu_InvalMenuBar(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef InvalMenuBar
+	PyMac_PRECHECK(InvalMenuBar);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	InvalMenuBar();
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Menu_HiliteMenu(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	MenuID menuID;
+#ifndef HiliteMenu
+	PyMac_PRECHECK(HiliteMenu);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &menuID))
+		return NULL;
+	HiliteMenu(menuID);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Menu_GetNewMBar(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	MenuBarHandle _rv;
+	short menuBarID;
+#ifndef GetNewMBar
+	PyMac_PRECHECK(GetNewMBar);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &menuBarID))
+		return NULL;
+	_rv = GetNewMBar(menuBarID);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Menu_GetMenuBar(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	MenuBarHandle _rv;
+#ifndef GetMenuBar
+	PyMac_PRECHECK(GetMenuBar);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetMenuBar();
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Menu_SetMenuBar(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	MenuBarHandle mbar;
+#ifndef SetMenuBar
+	PyMac_PRECHECK(SetMenuBar);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &mbar))
+		return NULL;
+	SetMenuBar(mbar);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Menu_DuplicateMenuBar(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	MenuBarHandle inMbar;
+	MenuBarHandle outMbar;
+#ifndef DuplicateMenuBar
+	PyMac_PRECHECK(DuplicateMenuBar);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &inMbar))
+		return NULL;
+	_err = DuplicateMenuBar(inMbar,
+	                        &outMbar);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, outMbar);
+	return _res;
+}
+
+static PyObject *Menu_DisposeMenuBar(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	MenuBarHandle inMbar;
+#ifndef DisposeMenuBar
+	PyMac_PRECHECK(DisposeMenuBar);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &inMbar))
+		return NULL;
+	_err = DisposeMenuBar(inMbar);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Menu_GetMenuHandle(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	MenuHandle _rv;
+	MenuID menuID;
+#ifndef GetMenuHandle
+	PyMac_PRECHECK(GetMenuHandle);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &menuID))
+		return NULL;
+	_rv = GetMenuHandle(menuID);
+	_res = Py_BuildValue("O&",
+	                     MenuObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Menu_MacDeleteMenu(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	MenuID menuID;
+#ifndef MacDeleteMenu
+	PyMac_PRECHECK(MacDeleteMenu);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &menuID))
+		return NULL;
+	MacDeleteMenu(menuID);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Menu_ClearMenuBar(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef ClearMenuBar
+	PyMac_PRECHECK(ClearMenuBar);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	ClearMenuBar();
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Menu_SetMenuFlashCount(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short count;
+#ifndef SetMenuFlashCount
+	PyMac_PRECHECK(SetMenuFlashCount);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &count))
+		return NULL;
+	SetMenuFlashCount(count);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Menu_FlashMenuBar(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	MenuID menuID;
+#ifndef FlashMenuBar
+	PyMac_PRECHECK(FlashMenuBar);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &menuID))
+		return NULL;
+	FlashMenuBar(menuID);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Menu_IsMenuBarVisible(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+#ifndef IsMenuBarVisible
+	PyMac_PRECHECK(IsMenuBarVisible);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = IsMenuBarVisible();
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Menu_ShowMenuBar(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef ShowMenuBar
+	PyMac_PRECHECK(ShowMenuBar);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	ShowMenuBar();
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Menu_HideMenuBar(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef HideMenuBar
+	PyMac_PRECHECK(HideMenuBar);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	HideMenuBar();
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Menu_AcquireRootMenu(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	MenuHandle _rv;
+#ifndef AcquireRootMenu
+	PyMac_PRECHECK(AcquireRootMenu);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = AcquireRootMenu();
+	_res = Py_BuildValue("O&",
+	                     MenuObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Menu_DeleteMCEntries(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	MenuID menuID;
+	short menuItem;
+#ifndef DeleteMCEntries
+	PyMac_PRECHECK(DeleteMCEntries);
+#endif
+	if (!PyArg_ParseTuple(_args, "hh",
+	                      &menuID,
+	                      &menuItem))
+		return NULL;
+	DeleteMCEntries(menuID,
+	                menuItem);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Menu_InitContextualMenus(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+#ifndef InitContextualMenus
+	PyMac_PRECHECK(InitContextualMenus);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = InitContextualMenus();
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Menu_IsShowContextualMenuClick(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	EventRecord inEvent;
+#ifndef IsShowContextualMenuClick
+	PyMac_PRECHECK(IsShowContextualMenuClick);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetEventRecord, &inEvent))
+		return NULL;
+	_rv = IsShowContextualMenuClick(&inEvent);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Menu_LMGetTheMenu(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	SInt16 _rv;
+#ifndef LMGetTheMenu
+	PyMac_PRECHECK(LMGetTheMenu);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = LMGetTheMenu();
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Menu_as_Menu(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	MenuHandle _rv;
+	Handle h;
+#ifndef as_Menu
+	PyMac_PRECHECK(as_Menu);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &h))
+		return NULL;
+	_rv = as_Menu(h);
+	_res = Py_BuildValue("O&",
+	                     MenuObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Menu_GetMenu(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	MenuHandle _rv;
+	short resourceID;
+#ifndef GetMenu
+	PyMac_PRECHECK(GetMenu);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &resourceID))
+		return NULL;
+	_rv = GetMenu(resourceID);
+	_res = Py_BuildValue("O&",
+	                     MenuObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Menu_DeleteMenu(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short menuID;
+#ifndef DeleteMenu
+	PyMac_PRECHECK(DeleteMenu);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &menuID))
+		return NULL;
+	DeleteMenu(menuID);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Menu_DrawMenuBar(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef DrawMenuBar
+	PyMac_PRECHECK(DrawMenuBar);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	DrawMenuBar();
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Menu_CountMenuItemsWithCommandID(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ItemCount _rv;
+	MenuHandle inMenu;
+	MenuCommand inCommandID;
+#ifndef CountMenuItemsWithCommandID
+	PyMac_PRECHECK(CountMenuItemsWithCommandID);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      OptMenuObj_Convert, &inMenu,
+	                      &inCommandID))
+		return NULL;
+	_rv = CountMenuItemsWithCommandID(inMenu,
+	                                  inCommandID);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Menu_GetIndMenuItemWithCommandID(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	MenuHandle inMenu;
+	MenuCommand inCommandID;
+	UInt32 inItemIndex;
+	MenuHandle outMenu;
+	MenuItemIndex outIndex;
+#ifndef GetIndMenuItemWithCommandID
+	PyMac_PRECHECK(GetIndMenuItemWithCommandID);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&ll",
+	                      OptMenuObj_Convert, &inMenu,
+	                      &inCommandID,
+	                      &inItemIndex))
+		return NULL;
+	_err = GetIndMenuItemWithCommandID(inMenu,
+	                                   inCommandID,
+	                                   inItemIndex,
+	                                   &outMenu,
+	                                   &outIndex);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&h",
+	                     MenuObj_New, outMenu,
+	                     outIndex);
+	return _res;
+}
+
+static PyObject *Menu_EnableMenuCommand(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	MenuHandle inMenu;
+	MenuCommand inCommandID;
+#ifndef EnableMenuCommand
+	PyMac_PRECHECK(EnableMenuCommand);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      OptMenuObj_Convert, &inMenu,
+	                      &inCommandID))
+		return NULL;
+	EnableMenuCommand(inMenu,
+	                  inCommandID);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Menu_DisableMenuCommand(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	MenuHandle inMenu;
+	MenuCommand inCommandID;
+#ifndef DisableMenuCommand
+	PyMac_PRECHECK(DisableMenuCommand);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      OptMenuObj_Convert, &inMenu,
+	                      &inCommandID))
+		return NULL;
+	DisableMenuCommand(inMenu,
+	                   inCommandID);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Menu_IsMenuCommandEnabled(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	MenuHandle inMenu;
+	MenuCommand inCommandID;
+#ifndef IsMenuCommandEnabled
+	PyMac_PRECHECK(IsMenuCommandEnabled);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      OptMenuObj_Convert, &inMenu,
+	                      &inCommandID))
+		return NULL;
+	_rv = IsMenuCommandEnabled(inMenu,
+	                           inCommandID);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Menu_SetMenuCommandMark(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	MenuHandle inMenu;
+	MenuCommand inCommandID;
+	UniChar inMark;
+#ifndef SetMenuCommandMark
+	PyMac_PRECHECK(SetMenuCommandMark);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&lh",
+	                      OptMenuObj_Convert, &inMenu,
+	                      &inCommandID,
+	                      &inMark))
+		return NULL;
+	_err = SetMenuCommandMark(inMenu,
+	                          inCommandID,
+	                          inMark);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Menu_GetMenuCommandMark(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	MenuHandle inMenu;
+	MenuCommand inCommandID;
+	UniChar outMark;
+#ifndef GetMenuCommandMark
+	PyMac_PRECHECK(GetMenuCommandMark);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      OptMenuObj_Convert, &inMenu,
+	                      &inCommandID))
+		return NULL;
+	_err = GetMenuCommandMark(inMenu,
+	                          inCommandID,
+	                          &outMark);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("h",
+	                     outMark);
+	return _res;
+}
+
+static PyObject *Menu_GetMenuCommandPropertySize(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	MenuHandle inMenu;
+	MenuCommand inCommandID;
+	OSType inPropertyCreator;
+	OSType inPropertyTag;
+	ByteCount outSize;
+#ifndef GetMenuCommandPropertySize
+	PyMac_PRECHECK(GetMenuCommandPropertySize);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&lO&O&",
+	                      OptMenuObj_Convert, &inMenu,
+	                      &inCommandID,
+	                      PyMac_GetOSType, &inPropertyCreator,
+	                      PyMac_GetOSType, &inPropertyTag))
+		return NULL;
+	_err = GetMenuCommandPropertySize(inMenu,
+	                                  inCommandID,
+	                                  inPropertyCreator,
+	                                  inPropertyTag,
+	                                  &outSize);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     outSize);
+	return _res;
+}
+
+static PyObject *Menu_RemoveMenuCommandProperty(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	MenuHandle inMenu;
+	MenuCommand inCommandID;
+	OSType inPropertyCreator;
+	OSType inPropertyTag;
+#ifndef RemoveMenuCommandProperty
+	PyMac_PRECHECK(RemoveMenuCommandProperty);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&lO&O&",
+	                      OptMenuObj_Convert, &inMenu,
+	                      &inCommandID,
+	                      PyMac_GetOSType, &inPropertyCreator,
+	                      PyMac_GetOSType, &inPropertyTag))
+		return NULL;
+	_err = RemoveMenuCommandProperty(inMenu,
+	                                 inCommandID,
+	                                 inPropertyCreator,
+	                                 inPropertyTag);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyMethodDef Menu_methods[] = {
+	{"NewMenu", (PyCFunction)Menu_NewMenu, 1,
+	 PyDoc_STR("(MenuID menuID, Str255 menuTitle) -> (MenuHandle _rv)")},
+	{"MacGetMenu", (PyCFunction)Menu_MacGetMenu, 1,
+	 PyDoc_STR("(short resourceID) -> (MenuHandle _rv)")},
+	{"CreateNewMenu", (PyCFunction)Menu_CreateNewMenu, 1,
+	 PyDoc_STR("(MenuID inMenuID, MenuAttributes inMenuAttributes) -> (MenuHandle outMenuRef)")},
+	{"MenuKey", (PyCFunction)Menu_MenuKey, 1,
+	 PyDoc_STR("(CharParameter ch) -> (long _rv)")},
+	{"MenuSelect", (PyCFunction)Menu_MenuSelect, 1,
+	 PyDoc_STR("(Point startPt) -> (long _rv)")},
+	{"MenuChoice", (PyCFunction)Menu_MenuChoice, 1,
+	 PyDoc_STR("() -> (long _rv)")},
+	{"MenuEvent", (PyCFunction)Menu_MenuEvent, 1,
+	 PyDoc_STR("(EventRecord inEvent) -> (UInt32 _rv)")},
+	{"GetMBarHeight", (PyCFunction)Menu_GetMBarHeight, 1,
+	 PyDoc_STR("() -> (short _rv)")},
+	{"MacDrawMenuBar", (PyCFunction)Menu_MacDrawMenuBar, 1,
+	 PyDoc_STR("() -> None")},
+	{"InvalMenuBar", (PyCFunction)Menu_InvalMenuBar, 1,
+	 PyDoc_STR("() -> None")},
+	{"HiliteMenu", (PyCFunction)Menu_HiliteMenu, 1,
+	 PyDoc_STR("(MenuID menuID) -> None")},
+	{"GetNewMBar", (PyCFunction)Menu_GetNewMBar, 1,
+	 PyDoc_STR("(short menuBarID) -> (MenuBarHandle _rv)")},
+	{"GetMenuBar", (PyCFunction)Menu_GetMenuBar, 1,
+	 PyDoc_STR("() -> (MenuBarHandle _rv)")},
+	{"SetMenuBar", (PyCFunction)Menu_SetMenuBar, 1,
+	 PyDoc_STR("(MenuBarHandle mbar) -> None")},
+	{"DuplicateMenuBar", (PyCFunction)Menu_DuplicateMenuBar, 1,
+	 PyDoc_STR("(MenuBarHandle inMbar) -> (MenuBarHandle outMbar)")},
+	{"DisposeMenuBar", (PyCFunction)Menu_DisposeMenuBar, 1,
+	 PyDoc_STR("(MenuBarHandle inMbar) -> None")},
+	{"GetMenuHandle", (PyCFunction)Menu_GetMenuHandle, 1,
+	 PyDoc_STR("(MenuID menuID) -> (MenuHandle _rv)")},
+	{"MacDeleteMenu", (PyCFunction)Menu_MacDeleteMenu, 1,
+	 PyDoc_STR("(MenuID menuID) -> None")},
+	{"ClearMenuBar", (PyCFunction)Menu_ClearMenuBar, 1,
+	 PyDoc_STR("() -> None")},
+	{"SetMenuFlashCount", (PyCFunction)Menu_SetMenuFlashCount, 1,
+	 PyDoc_STR("(short count) -> None")},
+	{"FlashMenuBar", (PyCFunction)Menu_FlashMenuBar, 1,
+	 PyDoc_STR("(MenuID menuID) -> None")},
+	{"IsMenuBarVisible", (PyCFunction)Menu_IsMenuBarVisible, 1,
+	 PyDoc_STR("() -> (Boolean _rv)")},
+	{"ShowMenuBar", (PyCFunction)Menu_ShowMenuBar, 1,
+	 PyDoc_STR("() -> None")},
+	{"HideMenuBar", (PyCFunction)Menu_HideMenuBar, 1,
+	 PyDoc_STR("() -> None")},
+	{"AcquireRootMenu", (PyCFunction)Menu_AcquireRootMenu, 1,
+	 PyDoc_STR("() -> (MenuHandle _rv)")},
+	{"DeleteMCEntries", (PyCFunction)Menu_DeleteMCEntries, 1,
+	 PyDoc_STR("(MenuID menuID, short menuItem) -> None")},
+	{"InitContextualMenus", (PyCFunction)Menu_InitContextualMenus, 1,
+	 PyDoc_STR("() -> None")},
+	{"IsShowContextualMenuClick", (PyCFunction)Menu_IsShowContextualMenuClick, 1,
+	 PyDoc_STR("(EventRecord inEvent) -> (Boolean _rv)")},
+	{"LMGetTheMenu", (PyCFunction)Menu_LMGetTheMenu, 1,
+	 PyDoc_STR("() -> (SInt16 _rv)")},
+	{"as_Menu", (PyCFunction)Menu_as_Menu, 1,
+	 PyDoc_STR("(Handle h) -> (MenuHandle _rv)")},
+	{"GetMenu", (PyCFunction)Menu_GetMenu, 1,
+	 PyDoc_STR("(short resourceID) -> (MenuHandle _rv)")},
+	{"DeleteMenu", (PyCFunction)Menu_DeleteMenu, 1,
+	 PyDoc_STR("(short menuID) -> None")},
+	{"DrawMenuBar", (PyCFunction)Menu_DrawMenuBar, 1,
+	 PyDoc_STR("() -> None")},
+	{"CountMenuItemsWithCommandID", (PyCFunction)Menu_CountMenuItemsWithCommandID, 1,
+	 PyDoc_STR("(MenuHandle inMenu, MenuCommand inCommandID) -> (ItemCount _rv)")},
+	{"GetIndMenuItemWithCommandID", (PyCFunction)Menu_GetIndMenuItemWithCommandID, 1,
+	 PyDoc_STR("(MenuHandle inMenu, MenuCommand inCommandID, UInt32 inItemIndex) -> (MenuHandle outMenu, MenuItemIndex outIndex)")},
+	{"EnableMenuCommand", (PyCFunction)Menu_EnableMenuCommand, 1,
+	 PyDoc_STR("(MenuHandle inMenu, MenuCommand inCommandID) -> None")},
+	{"DisableMenuCommand", (PyCFunction)Menu_DisableMenuCommand, 1,
+	 PyDoc_STR("(MenuHandle inMenu, MenuCommand inCommandID) -> None")},
+	{"IsMenuCommandEnabled", (PyCFunction)Menu_IsMenuCommandEnabled, 1,
+	 PyDoc_STR("(MenuHandle inMenu, MenuCommand inCommandID) -> (Boolean _rv)")},
+	{"SetMenuCommandMark", (PyCFunction)Menu_SetMenuCommandMark, 1,
+	 PyDoc_STR("(MenuHandle inMenu, MenuCommand inCommandID, UniChar inMark) -> None")},
+	{"GetMenuCommandMark", (PyCFunction)Menu_GetMenuCommandMark, 1,
+	 PyDoc_STR("(MenuHandle inMenu, MenuCommand inCommandID) -> (UniChar outMark)")},
+	{"GetMenuCommandPropertySize", (PyCFunction)Menu_GetMenuCommandPropertySize, 1,
+	 PyDoc_STR("(MenuHandle inMenu, MenuCommand inCommandID, OSType inPropertyCreator, OSType inPropertyTag) -> (ByteCount outSize)")},
+	{"RemoveMenuCommandProperty", (PyCFunction)Menu_RemoveMenuCommandProperty, 1,
+	 PyDoc_STR("(MenuHandle inMenu, MenuCommand inCommandID, OSType inPropertyCreator, OSType inPropertyTag) -> None")},
+	{NULL, NULL, 0}
+};
+
+
+
+
+void init_Menu(void)
+{
+	PyObject *m;
+	PyObject *d;
+
+
+
+	        PyMac_INIT_TOOLBOX_OBJECT_NEW(MenuHandle, MenuObj_New);
+	        PyMac_INIT_TOOLBOX_OBJECT_CONVERT(MenuHandle, MenuObj_Convert);
+
+
+	m = Py_InitModule("_Menu", Menu_methods);
+	d = PyModule_GetDict(m);
+	Menu_Error = PyMac_GetOSErrException();
+	if (Menu_Error == NULL ||
+	    PyDict_SetItemString(d, "Error", Menu_Error) != 0)
+		return;
+	Menu_Type.ob_type = &PyType_Type;
+	if (PyType_Ready(&Menu_Type) < 0) return;
+	Py_INCREF(&Menu_Type);
+	PyModule_AddObject(m, "Menu", (PyObject *)&Menu_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&Menu_Type);
+	PyModule_AddObject(m, "MenuType", (PyObject *)&Menu_Type);
+}
+
+/* ======================== End module _Menu ======================== */
+

Added: vendor/Python/current/Mac/Modules/menu/menuedit.py
===================================================================
--- vendor/Python/current/Mac/Modules/menu/menuedit.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/menu/menuedit.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,123 @@
+f = Function(MenuHandle, 'as_Menu', (Handle, 'h', InMode))
+functions.append(f)
+
+f = Method(Handle, 'as_Resource', (MenuHandle, 'h', InMode))
+methods.append(f)
+
+# The following have "Mac" prepended to their names in the include file
+# since UH 3.1, sigh...
+f = Function(MenuHandle, 'GetMenu',
+    (short, 'resourceID', InMode),
+)
+functions.append(f)
+
+f = Method(void, 'AppendMenu',
+    (MenuHandle, 'menu', InMode),
+    (ConstStr255Param, 'data', InMode),
+)
+methods.append(f)
+
+f = Method(void, 'InsertMenu',
+    (MenuHandle, 'theMenu', InMode),
+    (short, 'beforeID', InMode),
+)
+methods.append(f)
+
+f = Function(void, 'DeleteMenu',
+    (short, 'menuID', InMode),
+)
+functions.append(f)
+
+f = Method(void, 'InsertMenuItem',
+    (MenuHandle, 'theMenu', InMode),
+    (ConstStr255Param, 'itemString', InMode),
+    (short, 'afterItem', InMode),
+)
+methods.append(f)
+
+f = Method(void, 'EnableMenuItem',
+    (MenuHandle, 'theMenu', InMode),
+    (UInt16, 'item', InMode),
+)
+methods.append(f)
+
+f = Method(void, 'CheckMenuItem',
+    (MenuRef, 'theMenu', InMode),
+    (short, 'item', InMode),
+    (Boolean, 'checked', InMode),
+)
+methods.append(f)
+
+
+f = Function(void, 'DrawMenuBar',
+)
+functions.append(f)
+
+
+#
+# The following functions take an *optional* MenuRef as their first argument
+#
+
+f = Function(ItemCount, 'CountMenuItemsWithCommandID',
+    (OptMenuRef, 'inMenu', InMode),
+    (MenuCommand, 'inCommandID', InMode),
+)
+functions.append(f)
+
+f = Function(OSStatus, 'GetIndMenuItemWithCommandID',
+    (OptMenuRef, 'inMenu', InMode),
+    (MenuCommand, 'inCommandID', InMode),
+    (UInt32, 'inItemIndex', InMode),
+    (MenuRef, 'outMenu', OutMode),
+    (MenuItemIndex, 'outIndex', OutMode),
+)
+functions.append(f)
+
+f = Function(void, 'EnableMenuCommand',
+    (OptMenuRef, 'inMenu', InMode),
+    (MenuCommand, 'inCommandID', InMode),
+)
+functions.append(f)
+
+f = Function(void, 'DisableMenuCommand',
+    (OptMenuRef, 'inMenu', InMode),
+    (MenuCommand, 'inCommandID', InMode),
+)
+functions.append(f)
+
+f = Function(Boolean, 'IsMenuCommandEnabled',
+    (OptMenuRef, 'inMenu', InMode),
+    (MenuCommand, 'inCommandID', InMode),
+)
+functions.append(f)
+
+f = Function(OSStatus, 'SetMenuCommandMark',
+    (OptMenuRef, 'inMenu', InMode),
+    (MenuCommand, 'inCommandID', InMode),
+    (UniChar, 'inMark', InMode),
+)
+functions.append(f)
+
+f = Function(OSStatus, 'GetMenuCommandMark',
+    (OptMenuRef, 'inMenu', InMode),
+    (MenuCommand, 'inCommandID', InMode),
+    (UniChar, 'outMark', OutMode),
+)
+functions.append(f)
+
+f = Function(OSStatus, 'GetMenuCommandPropertySize',
+    (OptMenuRef, 'inMenu', InMode),
+    (MenuCommand, 'inCommandID', InMode),
+    (OSType, 'inPropertyCreator', InMode),
+    (OSType, 'inPropertyTag', InMode),
+    (ByteCount, 'outSize', OutMode),
+)
+functions.append(f)
+
+f = Function(OSStatus, 'RemoveMenuCommandProperty',
+    (OptMenuRef, 'inMenu', InMode),
+    (MenuCommand, 'inCommandID', InMode),
+    (OSType, 'inPropertyCreator', InMode),
+    (OSType, 'inPropertyTag', InMode),
+)
+functions.append(f)

Added: vendor/Python/current/Mac/Modules/menu/menuscan.py
===================================================================
--- vendor/Python/current/Mac/Modules/menu/menuscan.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/menu/menuscan.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,97 @@
+# Scan <Menus.h>, generating menugen.py.
+import sys
+import os
+from bgenlocations import TOOLBOXDIR, BGENDIR
+sys.path.append(BGENDIR)
+
+from scantools import Scanner
+
+def main():
+    input = "Menus.h"
+    output = "menugen.py"
+    defsoutput = TOOLBOXDIR + "Menus.py"
+    scanner = MyScanner(input, output, defsoutput)
+    scanner.scan()
+    scanner.close()
+    print "=== Testing definitions output code ==="
+    execfile(defsoutput, {}, {})
+    print "=== Done scanning and generating, now doing 'import menusupport' ==="
+    import menusupport
+    print "=== Done.  It's up to you to compile Menumodule.c ==="
+
+class MyScanner(Scanner):
+
+    def destination(self, type, name, arglist):
+        classname = "Function"
+        listname = "functions"
+        if arglist:
+            t, n, m = arglist[0]
+            if t in ("MenuHandle", "MenuRef") and m == "InMode":
+                classname = "Method"
+                listname = "methods"
+        return classname, listname
+
+    def makeblacklistnames(self):
+        return [
+##                      "IsShowContextualMenuClick", # Can't find it in the library
+##                      "InitContextualMenus", # ditto
+                "GetMenuItemProperty",  # difficult for the moment
+                "GetMenuItemPropertySize",
+                "SetMenuItemProperty",
+                "RemoveMenuItemProperty",
+                "SetMenuCommandProperty",
+                "GetMenuCommandProperty",
+                "GetMenuTitle", # Funny arg/returnvalue
+                "SetMenuTitle",
+                "SetMenuTitleIcon", # void*
+                # OS8 calls:
+                'GetMenuItemRefCon2',
+                'SetMenuItemRefCon2',
+                'EnableItem',
+                'DisableItem',
+                'CheckItem',
+                'CountMItems',
+                'OpenDeskAcc',
+                'SystemEdit',
+                'SystemMenu',
+                'SetMenuFlash',
+                'InitMenus',
+                'InitProcMenu',
+                ]
+
+    def makeblacklisttypes(self):
+        return [
+                'MCTableHandle',
+                'MCEntryPtr',
+                'MCTablePtr',
+                'AEDesc_ptr', # For now: doable, but not easy
+                'ProcessSerialNumber', # ditto
+                "MenuDefSpecPtr", # Too difficult for now
+                "MenuDefSpec_ptr", # ditto
+                "MenuTrackingData",
+                "void_ptr",     # Don't know yet.
+                "EventRef",     # For now, not exported yet.
+                "MenuItemDataPtr", # Not yet.
+                "MenuItemDataRec_ptr",
+                ]
+
+    def makerepairinstructions(self):
+        return [
+                ([("Str255", "itemString", "InMode")],
+                 [("*", "*", "OutMode")]),
+
+                ([("void_ptr", "*", "InMode"), ("long", "*", "InMode")],
+                 [("InBuffer", "*", "*")]),
+
+                ([("void", "*", "OutMode"), ("long", "*", "InMode"),
+                                            ("long", "*", "OutMode")],
+                 [("VarVarOutBuffer", "*", "InOutMode")]),
+                ([("MenuRef", 'outHierMenu', "OutMode")],
+                 [("OptMenuRef", 'outHierMenu', "OutMode")]),
+                ]
+
+    def writeinitialdefs(self):
+        self.defsfile.write("def FOUR_CHAR_CODE(x): return x\n")
+
+if __name__ == "__main__":
+    main()

Added: vendor/Python/current/Mac/Modules/menu/menusupport.py
===================================================================
--- vendor/Python/current/Mac/Modules/menu/menusupport.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/menu/menusupport.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,108 @@
+# This script generates a Python interface for an Apple Macintosh Manager.
+# It uses the "bgen" package to generate C code.
+# The function specifications are generated by scanning the mamager's header file,
+# using the "scantools" package (customized for this particular manager).
+
+import string
+
+# Declarations that change for each manager
+MACHEADERFILE = 'Menus.h'               # The Apple header file
+MODNAME = '_Menu'                       # The name of the module
+OBJECTNAME = 'Menu'                     # The basic name of the objects used here
+
+# The following is *usually* unchanged but may still require tuning
+MODPREFIX = 'Menu'                      # The prefix for module-wide routines
+OBJECTTYPE = OBJECTNAME + 'Handle'      # The C type used to represent them
+OBJECTPREFIX = MODPREFIX + 'Obj'        # The prefix for object methods
+INPUTFILE = string.lower(MODPREFIX) + 'gen.py' # The file generated by the scanner
+EXTRAFILE = string.lower(MODPREFIX) + 'edit.py' # A similar file but hand-made
+OUTPUTFILE = MODNAME + "module.c"       # The file generated by this program
+
+from macsupport import *
+
+# Create the type objects
+
+MenuHandle = OpaqueByValueType(OBJECTTYPE, OBJECTPREFIX)
+MenuRef = MenuHandle
+OptMenuRef = OpaqueByValueType(OBJECTTYPE, "Opt" + OBJECTPREFIX)
+Handle = OpaqueByValueType("Handle", "ResObj")
+MenuBarHandle = OpaqueByValueType("MenuBarHandle", "ResObj")
+MenuID = Type("MenuID", "h")
+MenuItemIndex = Type("MenuItemIndex", "h")
+MenuItemID = Type("MenuItemID", "l")
+MenuCommand = Type("MenuCommand", "l")
+MenuAttributes = Type("MenuAttributes", "l")
+MenuItemAttributes = Type("MenuItemAttributes", "l")
+unsigned_char = Type('unsigned char', 'b')
+FMFontFamily = Type("FMFontFamily", "h")
+FMFontStyle = Type("FMFontStyle", "h")
+UniChar = Type("UniChar", "h")
+
+includestuff = includestuff + """
+#include <Carbon/Carbon.h>
+
+
+#ifdef USE_TOOLBOX_OBJECT_GLUE
+
+extern PyObject *_MenuObj_New(MenuHandle);
+extern int _MenuObj_Convert(PyObject *, MenuHandle *);
+
+#define MenuObj_New _MenuObj_New
+#define MenuObj_Convert _MenuObj_Convert
+#endif
+
+#define as_Menu(h) ((MenuHandle)h)
+#define as_Resource(h) ((Handle)h)
+
+
+/* Alternative version of MenuObj_New, which returns None for NULL argument */
+PyObject *OptMenuObj_New(MenuRef itself)
+{
+        if (itself == NULL) {
+                Py_INCREF(Py_None);
+                return Py_None;
+        }
+        return MenuObj_New(itself);
+}
+
+/* Alternative version of MenuObj_Convert, which returns NULL for a None argument */
+int OptMenuObj_Convert(PyObject *v, MenuRef *p_itself)
+{
+        if ( v == Py_None ) {
+                *p_itself = NULL;
+                return 1;
+        }
+        return MenuObj_Convert(v, p_itself);
+}
+"""
+
+initstuff = initstuff + """
+        PyMac_INIT_TOOLBOX_OBJECT_NEW(MenuHandle, MenuObj_New);
+        PyMac_INIT_TOOLBOX_OBJECT_CONVERT(MenuHandle, MenuObj_Convert);
+"""
+
+class MyObjectDefinition(PEP253Mixin, GlobalObjectDefinition):
+    pass
+
+# Create the generator groups and link them
+module = MacModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff)
+object = MyObjectDefinition(OBJECTNAME, OBJECTPREFIX, OBJECTTYPE)
+module.addobject(object)
+
+# Create the generator classes used to populate the lists
+Function = OSErrWeakLinkFunctionGenerator
+Method = OSErrWeakLinkMethodGenerator
+
+# Create and populate the lists
+functions = []
+methods = []
+execfile(INPUTFILE)
+execfile(EXTRAFILE)
+
+# add the populated lists to the generator groups
+for f in functions: module.add(f)
+for f in methods: object.add(f)
+
+# generate output (open the output file as late as possible)
+SetOutputFileName(OUTPUTFILE)
+module.generate()

Added: vendor/Python/current/Mac/Modules/mlte/_Mltemodule.c
===================================================================
--- vendor/Python/current/Mac/Modules/mlte/_Mltemodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/mlte/_Mltemodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1681 @@
+
+/* ========================== Module _Mlte ========================== */
+
+#include "Python.h"
+
+
+
+#include "pymactoolbox.h"
+
+/* Macro to test whether a weak-loaded CFM function exists */
+#define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL )  {\
+        PyErr_SetString(PyExc_NotImplementedError, \
+        "Not available in this shared library/OS version"); \
+        return NULL; \
+    }} while(0)
+
+
+#include <Carbon/Carbon.h>
+
+/* For now we declare them forward here. They'll go to mactoolbox later */
+static PyObject *TXNObj_New(TXNObject);
+static int TXNObj_Convert(PyObject *, TXNObject *);
+static PyObject *TXNFontMenuObj_New(TXNFontMenuObject);
+static int TXNFontMenuObj_Convert(PyObject *, TXNFontMenuObject *);
+
+// ADD declarations
+#ifdef NOTYET_USE_TOOLBOX_OBJECT_GLUE
+//extern PyObject *_CFTypeRefObj_New(CFTypeRef);
+//extern int _CFTypeRefObj_Convert(PyObject *, CFTypeRef *);
+
+//#define CFTypeRefObj_New _CFTypeRefObj_New
+//#define CFTypeRefObj_Convert _CFTypeRefObj_Convert
+#endif
+
+/*
+** Parse an optional fsspec
+*/
+static int
+OptFSSpecPtr_Convert(PyObject *v, FSSpec **p_itself)
+{
+        static FSSpec fss;
+        if (v == Py_None)
+        {
+                *p_itself = NULL;
+                return 1;
+        }
+        *p_itself = &fss;
+        return PyMac_GetFSSpec(v, *p_itself);
+}
+
+/*
+** Parse an optional GWorld
+*/
+static int
+OptGWorldObj_Convert(PyObject *v, GWorldPtr *p_itself)
+{
+        if (v == Py_None)
+        {
+                *p_itself = NULL;
+                return 1;
+        }
+        return GWorldObj_Convert(v, p_itself);
+}
+
+
+static PyObject *Mlte_Error;
+
+/* --------------------- Object type TXNObject ---------------------- */
+
+PyTypeObject TXNObject_Type;
+
+#define TXNObj_Check(x) ((x)->ob_type == &TXNObject_Type || PyObject_TypeCheck((x), &TXNObject_Type))
+
+typedef struct TXNObjectObject {
+	PyObject_HEAD
+	TXNObject ob_itself;
+} TXNObjectObject;
+
+PyObject *TXNObj_New(TXNObject itself)
+{
+	TXNObjectObject *it;
+	if (itself == NULL) return PyMac_Error(resNotFound);
+	it = PyObject_NEW(TXNObjectObject, &TXNObject_Type);
+	if (it == NULL) return NULL;
+	it->ob_itself = itself;
+	return (PyObject *)it;
+}
+
+int TXNObj_Convert(PyObject *v, TXNObject *p_itself)
+{
+	if (!TXNObj_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "TXNObject required");
+		return 0;
+	}
+	*p_itself = ((TXNObjectObject *)v)->ob_itself;
+	return 1;
+}
+
+static void TXNObj_dealloc(TXNObjectObject *self)
+{
+	/* Cleanup of self->ob_itself goes here */
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *TXNObj_TXNDeleteObject(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef TXNDeleteObject
+	PyMac_PRECHECK(TXNDeleteObject);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	TXNDeleteObject(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TXNObj_TXNResizeFrame(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	UInt32 iWidth;
+	UInt32 iHeight;
+	TXNFrameID iTXNFrameID;
+#ifndef TXNResizeFrame
+	PyMac_PRECHECK(TXNResizeFrame);
+#endif
+	if (!PyArg_ParseTuple(_args, "lll",
+	                      &iWidth,
+	                      &iHeight,
+	                      &iTXNFrameID))
+		return NULL;
+	TXNResizeFrame(_self->ob_itself,
+	               iWidth,
+	               iHeight,
+	               iTXNFrameID);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TXNObj_TXNSetFrameBounds(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	SInt32 iTop;
+	SInt32 iLeft;
+	SInt32 iBottom;
+	SInt32 iRight;
+	TXNFrameID iTXNFrameID;
+#ifndef TXNSetFrameBounds
+	PyMac_PRECHECK(TXNSetFrameBounds);
+#endif
+	if (!PyArg_ParseTuple(_args, "lllll",
+	                      &iTop,
+	                      &iLeft,
+	                      &iBottom,
+	                      &iRight,
+	                      &iTXNFrameID))
+		return NULL;
+	TXNSetFrameBounds(_self->ob_itself,
+	                  iTop,
+	                  iLeft,
+	                  iBottom,
+	                  iRight,
+	                  iTXNFrameID);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TXNObj_TXNKeyDown(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	EventRecord iEvent;
+#ifndef TXNKeyDown
+	PyMac_PRECHECK(TXNKeyDown);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetEventRecord, &iEvent))
+		return NULL;
+	TXNKeyDown(_self->ob_itself,
+	           &iEvent);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TXNObj_TXNAdjustCursor(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle ioCursorRgn;
+#ifndef TXNAdjustCursor
+	PyMac_PRECHECK(TXNAdjustCursor);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      OptResObj_Convert, &ioCursorRgn))
+		return NULL;
+	TXNAdjustCursor(_self->ob_itself,
+	                ioCursorRgn);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TXNObj_TXNClick(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	EventRecord iEvent;
+#ifndef TXNClick
+	PyMac_PRECHECK(TXNClick);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetEventRecord, &iEvent))
+		return NULL;
+	TXNClick(_self->ob_itself,
+	         &iEvent);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TXNObj_TXNSelectAll(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef TXNSelectAll
+	PyMac_PRECHECK(TXNSelectAll);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	TXNSelectAll(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TXNObj_TXNFocus(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean iBecomingFocused;
+#ifndef TXNFocus
+	PyMac_PRECHECK(TXNFocus);
+#endif
+	if (!PyArg_ParseTuple(_args, "b",
+	                      &iBecomingFocused))
+		return NULL;
+	TXNFocus(_self->ob_itself,
+	         iBecomingFocused);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TXNObj_TXNUpdate(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef TXNUpdate
+	PyMac_PRECHECK(TXNUpdate);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	TXNUpdate(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TXNObj_TXNDraw(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	GWorldPtr iDrawPort;
+#ifndef TXNDraw
+	PyMac_PRECHECK(TXNDraw);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      OptGWorldObj_Convert, &iDrawPort))
+		return NULL;
+	TXNDraw(_self->ob_itself,
+	        iDrawPort);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TXNObj_TXNForceUpdate(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef TXNForceUpdate
+	PyMac_PRECHECK(TXNForceUpdate);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	TXNForceUpdate(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TXNObj_TXNGetSleepTicks(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	UInt32 _rv;
+#ifndef TXNGetSleepTicks
+	PyMac_PRECHECK(TXNGetSleepTicks);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = TXNGetSleepTicks(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *TXNObj_TXNIdle(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef TXNIdle
+	PyMac_PRECHECK(TXNIdle);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	TXNIdle(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TXNObj_TXNGrowWindow(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	EventRecord iEvent;
+#ifndef TXNGrowWindow
+	PyMac_PRECHECK(TXNGrowWindow);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetEventRecord, &iEvent))
+		return NULL;
+	TXNGrowWindow(_self->ob_itself,
+	              &iEvent);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TXNObj_TXNZoomWindow(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	SInt16 iPart;
+#ifndef TXNZoomWindow
+	PyMac_PRECHECK(TXNZoomWindow);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &iPart))
+		return NULL;
+	TXNZoomWindow(_self->ob_itself,
+	              iPart);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TXNObj_TXNCanUndo(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	TXNActionKey oTXNActionKey;
+#ifndef TXNCanUndo
+	PyMac_PRECHECK(TXNCanUndo);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = TXNCanUndo(_self->ob_itself,
+	                 &oTXNActionKey);
+	_res = Py_BuildValue("bl",
+	                     _rv,
+	                     oTXNActionKey);
+	return _res;
+}
+
+static PyObject *TXNObj_TXNUndo(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef TXNUndo
+	PyMac_PRECHECK(TXNUndo);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	TXNUndo(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TXNObj_TXNCanRedo(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	TXNActionKey oTXNActionKey;
+#ifndef TXNCanRedo
+	PyMac_PRECHECK(TXNCanRedo);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = TXNCanRedo(_self->ob_itself,
+	                 &oTXNActionKey);
+	_res = Py_BuildValue("bl",
+	                     _rv,
+	                     oTXNActionKey);
+	return _res;
+}
+
+static PyObject *TXNObj_TXNRedo(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef TXNRedo
+	PyMac_PRECHECK(TXNRedo);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	TXNRedo(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TXNObj_TXNCut(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+#ifndef TXNCut
+	PyMac_PRECHECK(TXNCut);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = TXNCut(_self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TXNObj_TXNCopy(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+#ifndef TXNCopy
+	PyMac_PRECHECK(TXNCopy);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = TXNCopy(_self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TXNObj_TXNPaste(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+#ifndef TXNPaste
+	PyMac_PRECHECK(TXNPaste);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = TXNPaste(_self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TXNObj_TXNClear(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+#ifndef TXNClear
+	PyMac_PRECHECK(TXNClear);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = TXNClear(_self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TXNObj_TXNGetSelection(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	TXNOffset oStartOffset;
+	TXNOffset oEndOffset;
+#ifndef TXNGetSelection
+	PyMac_PRECHECK(TXNGetSelection);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	TXNGetSelection(_self->ob_itself,
+	                &oStartOffset,
+	                &oEndOffset);
+	_res = Py_BuildValue("ll",
+	                     oStartOffset,
+	                     oEndOffset);
+	return _res;
+}
+
+static PyObject *TXNObj_TXNShowSelection(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean iShowEnd;
+#ifndef TXNShowSelection
+	PyMac_PRECHECK(TXNShowSelection);
+#endif
+	if (!PyArg_ParseTuple(_args, "b",
+	                      &iShowEnd))
+		return NULL;
+	TXNShowSelection(_self->ob_itself,
+	                 iShowEnd);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TXNObj_TXNIsSelectionEmpty(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+#ifndef TXNIsSelectionEmpty
+	PyMac_PRECHECK(TXNIsSelectionEmpty);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = TXNIsSelectionEmpty(_self->ob_itself);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *TXNObj_TXNSetSelection(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	TXNOffset iStartOffset;
+	TXNOffset iEndOffset;
+#ifndef TXNSetSelection
+	PyMac_PRECHECK(TXNSetSelection);
+#endif
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &iStartOffset,
+	                      &iEndOffset))
+		return NULL;
+	_err = TXNSetSelection(_self->ob_itself,
+	                       iStartOffset,
+	                       iEndOffset);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TXNObj_TXNCountRunsInRange(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	TXNOffset iStartOffset;
+	TXNOffset iEndOffset;
+	ItemCount oRunCount;
+#ifndef TXNCountRunsInRange
+	PyMac_PRECHECK(TXNCountRunsInRange);
+#endif
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &iStartOffset,
+	                      &iEndOffset))
+		return NULL;
+	_err = TXNCountRunsInRange(_self->ob_itself,
+	                           iStartOffset,
+	                           iEndOffset,
+	                           &oRunCount);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     oRunCount);
+	return _res;
+}
+
+static PyObject *TXNObj_TXNDataSize(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ByteCount _rv;
+#ifndef TXNDataSize
+	PyMac_PRECHECK(TXNDataSize);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = TXNDataSize(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *TXNObj_TXNGetData(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	TXNOffset iStartOffset;
+	TXNOffset iEndOffset;
+	Handle oDataHandle;
+#ifndef TXNGetData
+	PyMac_PRECHECK(TXNGetData);
+#endif
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &iStartOffset,
+	                      &iEndOffset))
+		return NULL;
+	_err = TXNGetData(_self->ob_itself,
+	                  iStartOffset,
+	                  iEndOffset,
+	                  &oDataHandle);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, oDataHandle);
+	return _res;
+}
+
+static PyObject *TXNObj_TXNGetDataEncoded(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	TXNOffset iStartOffset;
+	TXNOffset iEndOffset;
+	Handle oDataHandle;
+	TXNDataType iEncoding;
+#ifndef TXNGetDataEncoded
+	PyMac_PRECHECK(TXNGetDataEncoded);
+#endif
+	if (!PyArg_ParseTuple(_args, "llO&",
+	                      &iStartOffset,
+	                      &iEndOffset,
+	                      PyMac_GetOSType, &iEncoding))
+		return NULL;
+	_err = TXNGetDataEncoded(_self->ob_itself,
+	                         iStartOffset,
+	                         iEndOffset,
+	                         &oDataHandle,
+	                         iEncoding);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, oDataHandle);
+	return _res;
+}
+
+static PyObject *TXNObj_TXNSetDataFromFile(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	SInt16 iFileRefNum;
+	OSType iFileType;
+	ByteCount iFileLength;
+	TXNOffset iStartOffset;
+	TXNOffset iEndOffset;
+#ifndef TXNSetDataFromFile
+	PyMac_PRECHECK(TXNSetDataFromFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "hO&lll",
+	                      &iFileRefNum,
+	                      PyMac_GetOSType, &iFileType,
+	                      &iFileLength,
+	                      &iStartOffset,
+	                      &iEndOffset))
+		return NULL;
+	_err = TXNSetDataFromFile(_self->ob_itself,
+	                          iFileRefNum,
+	                          iFileType,
+	                          iFileLength,
+	                          iStartOffset,
+	                          iEndOffset);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TXNObj_TXNGetChangeCount(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ItemCount _rv;
+#ifndef TXNGetChangeCount
+	PyMac_PRECHECK(TXNGetChangeCount);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = TXNGetChangeCount(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *TXNObj_TXNSave(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	TXNFileType iType;
+	OSType iResType;
+	TXNPermanentTextEncodingType iPermanentEncoding;
+	FSSpec iFileSpecification;
+	SInt16 iDataReference;
+	SInt16 iResourceReference;
+#ifndef TXNSave
+	PyMac_PRECHECK(TXNSave);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&lO&hh",
+	                      PyMac_GetOSType, &iType,
+	                      PyMac_GetOSType, &iResType,
+	                      &iPermanentEncoding,
+	                      PyMac_GetFSSpec, &iFileSpecification,
+	                      &iDataReference,
+	                      &iResourceReference))
+		return NULL;
+	_err = TXNSave(_self->ob_itself,
+	               iType,
+	               iResType,
+	               iPermanentEncoding,
+	               &iFileSpecification,
+	               iDataReference,
+	               iResourceReference);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TXNObj_TXNRevert(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+#ifndef TXNRevert
+	PyMac_PRECHECK(TXNRevert);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = TXNRevert(_self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TXNObj_TXNPageSetup(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+#ifndef TXNPageSetup
+	PyMac_PRECHECK(TXNPageSetup);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = TXNPageSetup(_self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TXNObj_TXNPrint(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+#ifndef TXNPrint
+	PyMac_PRECHECK(TXNPrint);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = TXNPrint(_self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TXNObj_TXNGetViewRect(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect oViewRect;
+#ifndef TXNGetViewRect
+	PyMac_PRECHECK(TXNGetViewRect);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	TXNGetViewRect(_self->ob_itself,
+	               &oViewRect);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildRect, &oViewRect);
+	return _res;
+}
+
+static PyObject *TXNObj_TXNSetViewRect(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect iViewRect;
+#ifndef TXNSetViewRect
+	PyMac_PRECHECK(TXNSetViewRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetRect, &iViewRect))
+		return NULL;
+	TXNSetViewRect(_self->ob_itself,
+	               &iViewRect);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TXNObj_TXNAttachObjectToWindow(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	GWorldPtr iWindow;
+	Boolean iIsActualWindow;
+#ifndef TXNAttachObjectToWindow
+	PyMac_PRECHECK(TXNAttachObjectToWindow);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&b",
+	                      GWorldObj_Convert, &iWindow,
+	                      &iIsActualWindow))
+		return NULL;
+	_err = TXNAttachObjectToWindow(_self->ob_itself,
+	                               iWindow,
+	                               iIsActualWindow);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TXNObj_TXNIsObjectAttachedToWindow(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+#ifndef TXNIsObjectAttachedToWindow
+	PyMac_PRECHECK(TXNIsObjectAttachedToWindow);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = TXNIsObjectAttachedToWindow(_self->ob_itself);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *TXNObj_TXNDragTracker(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	TXNFrameID iTXNFrameID;
+	DragTrackingMessage iMessage;
+	WindowPtr iWindow;
+	DragReference iDragReference;
+	Boolean iDifferentObjectSameWindow;
+#ifndef TXNDragTracker
+	PyMac_PRECHECK(TXNDragTracker);
+#endif
+	if (!PyArg_ParseTuple(_args, "lhO&O&b",
+	                      &iTXNFrameID,
+	                      &iMessage,
+	                      WinObj_Convert, &iWindow,
+	                      DragObj_Convert, &iDragReference,
+	                      &iDifferentObjectSameWindow))
+		return NULL;
+	_err = TXNDragTracker(_self->ob_itself,
+	                      iTXNFrameID,
+	                      iMessage,
+	                      iWindow,
+	                      iDragReference,
+	                      iDifferentObjectSameWindow);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TXNObj_TXNDragReceiver(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	TXNFrameID iTXNFrameID;
+	WindowPtr iWindow;
+	DragReference iDragReference;
+	Boolean iDifferentObjectSameWindow;
+#ifndef TXNDragReceiver
+	PyMac_PRECHECK(TXNDragReceiver);
+#endif
+	if (!PyArg_ParseTuple(_args, "lO&O&b",
+	                      &iTXNFrameID,
+	                      WinObj_Convert, &iWindow,
+	                      DragObj_Convert, &iDragReference,
+	                      &iDifferentObjectSameWindow))
+		return NULL;
+	_err = TXNDragReceiver(_self->ob_itself,
+	                       iTXNFrameID,
+	                       iWindow,
+	                       iDragReference,
+	                       iDifferentObjectSameWindow);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TXNObj_TXNActivate(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	TXNFrameID iTXNFrameID;
+	TXNScrollBarState iActiveState;
+#ifndef TXNActivate
+	PyMac_PRECHECK(TXNActivate);
+#endif
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &iTXNFrameID,
+	                      &iActiveState))
+		return NULL;
+	_err = TXNActivate(_self->ob_itself,
+	                   iTXNFrameID,
+	                   iActiveState);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TXNObj_TXNEchoMode(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UniChar iEchoCharacter;
+	TextEncoding iEncoding;
+	Boolean iOn;
+#ifndef TXNEchoMode
+	PyMac_PRECHECK(TXNEchoMode);
+#endif
+	if (!PyArg_ParseTuple(_args, "hlb",
+	                      &iEchoCharacter,
+	                      &iEncoding,
+	                      &iOn))
+		return NULL;
+	_err = TXNEchoMode(_self->ob_itself,
+	                   iEchoCharacter,
+	                   iEncoding,
+	                   iOn);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TXNObj_TXNDoFontMenuSelection(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	TXNFontMenuObject iTXNFontMenuObject;
+	SInt16 iMenuID;
+	SInt16 iMenuItem;
+#ifndef TXNDoFontMenuSelection
+	PyMac_PRECHECK(TXNDoFontMenuSelection);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hh",
+	                      TXNFontMenuObj_Convert, &iTXNFontMenuObject,
+	                      &iMenuID,
+	                      &iMenuItem))
+		return NULL;
+	_err = TXNDoFontMenuSelection(_self->ob_itself,
+	                              iTXNFontMenuObject,
+	                              iMenuID,
+	                              iMenuItem);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TXNObj_TXNPrepareFontMenu(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	TXNFontMenuObject iTXNFontMenuObject;
+#ifndef TXNPrepareFontMenu
+	PyMac_PRECHECK(TXNPrepareFontMenu);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      TXNFontMenuObj_Convert, &iTXNFontMenuObject))
+		return NULL;
+	_err = TXNPrepareFontMenu(_self->ob_itself,
+	                          iTXNFontMenuObject);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TXNObj_TXNPointToOffset(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Point iPoint;
+	TXNOffset oOffset;
+#ifndef TXNPointToOffset
+	PyMac_PRECHECK(TXNPointToOffset);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetPoint, &iPoint))
+		return NULL;
+	_err = TXNPointToOffset(_self->ob_itself,
+	                        iPoint,
+	                        &oOffset);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     oOffset);
+	return _res;
+}
+
+static PyObject *TXNObj_TXNOffsetToPoint(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	TXNOffset iOffset;
+	Point oPoint;
+#ifndef TXNOffsetToPoint
+	PyMac_PRECHECK(TXNOffsetToPoint);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &iOffset))
+		return NULL;
+	_err = TXNOffsetToPoint(_self->ob_itself,
+	                        iOffset,
+	                        &oPoint);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildPoint, oPoint);
+	return _res;
+}
+
+static PyObject *TXNObj_TXNGetLineCount(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	ItemCount oLineTotal;
+#ifndef TXNGetLineCount
+	PyMac_PRECHECK(TXNGetLineCount);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = TXNGetLineCount(_self->ob_itself,
+	                       &oLineTotal);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     oLineTotal);
+	return _res;
+}
+
+static PyObject *TXNObj_TXNGetLineMetrics(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 iLineNumber;
+	Fixed oLineWidth;
+	Fixed oLineHeight;
+#ifndef TXNGetLineMetrics
+	PyMac_PRECHECK(TXNGetLineMetrics);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &iLineNumber))
+		return NULL;
+	_err = TXNGetLineMetrics(_self->ob_itself,
+	                         iLineNumber,
+	                         &oLineWidth,
+	                         &oLineHeight);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&O&",
+	                     PyMac_BuildFixed, oLineWidth,
+	                     PyMac_BuildFixed, oLineHeight);
+	return _res;
+}
+
+static PyObject *TXNObj_TXNIsObjectAttachedToSpecificWindow(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr iWindow;
+	Boolean oAttached;
+#ifndef TXNIsObjectAttachedToSpecificWindow
+	PyMac_PRECHECK(TXNIsObjectAttachedToSpecificWindow);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      WinObj_Convert, &iWindow))
+		return NULL;
+	_err = TXNIsObjectAttachedToSpecificWindow(_self->ob_itself,
+	                                           iWindow,
+	                                           &oAttached);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("b",
+	                     oAttached);
+	return _res;
+}
+
+static PyObject *TXNObj_TXNRecalcTextLayout(TXNObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef TXNRecalcTextLayout
+	PyMac_PRECHECK(TXNRecalcTextLayout);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	TXNRecalcTextLayout(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyMethodDef TXNObj_methods[] = {
+	{"TXNDeleteObject", (PyCFunction)TXNObj_TXNDeleteObject, 1,
+	 PyDoc_STR("() -> None")},
+	{"TXNResizeFrame", (PyCFunction)TXNObj_TXNResizeFrame, 1,
+	 PyDoc_STR("(UInt32 iWidth, UInt32 iHeight, TXNFrameID iTXNFrameID) -> None")},
+	{"TXNSetFrameBounds", (PyCFunction)TXNObj_TXNSetFrameBounds, 1,
+	 PyDoc_STR("(SInt32 iTop, SInt32 iLeft, SInt32 iBottom, SInt32 iRight, TXNFrameID iTXNFrameID) -> None")},
+	{"TXNKeyDown", (PyCFunction)TXNObj_TXNKeyDown, 1,
+	 PyDoc_STR("(EventRecord iEvent) -> None")},
+	{"TXNAdjustCursor", (PyCFunction)TXNObj_TXNAdjustCursor, 1,
+	 PyDoc_STR("(RgnHandle ioCursorRgn) -> None")},
+	{"TXNClick", (PyCFunction)TXNObj_TXNClick, 1,
+	 PyDoc_STR("(EventRecord iEvent) -> None")},
+	{"TXNSelectAll", (PyCFunction)TXNObj_TXNSelectAll, 1,
+	 PyDoc_STR("() -> None")},
+	{"TXNFocus", (PyCFunction)TXNObj_TXNFocus, 1,
+	 PyDoc_STR("(Boolean iBecomingFocused) -> None")},
+	{"TXNUpdate", (PyCFunction)TXNObj_TXNUpdate, 1,
+	 PyDoc_STR("() -> None")},
+	{"TXNDraw", (PyCFunction)TXNObj_TXNDraw, 1,
+	 PyDoc_STR("(GWorldPtr iDrawPort) -> None")},
+	{"TXNForceUpdate", (PyCFunction)TXNObj_TXNForceUpdate, 1,
+	 PyDoc_STR("() -> None")},
+	{"TXNGetSleepTicks", (PyCFunction)TXNObj_TXNGetSleepTicks, 1,
+	 PyDoc_STR("() -> (UInt32 _rv)")},
+	{"TXNIdle", (PyCFunction)TXNObj_TXNIdle, 1,
+	 PyDoc_STR("() -> None")},
+	{"TXNGrowWindow", (PyCFunction)TXNObj_TXNGrowWindow, 1,
+	 PyDoc_STR("(EventRecord iEvent) -> None")},
+	{"TXNZoomWindow", (PyCFunction)TXNObj_TXNZoomWindow, 1,
+	 PyDoc_STR("(SInt16 iPart) -> None")},
+	{"TXNCanUndo", (PyCFunction)TXNObj_TXNCanUndo, 1,
+	 PyDoc_STR("() -> (Boolean _rv, TXNActionKey oTXNActionKey)")},
+	{"TXNUndo", (PyCFunction)TXNObj_TXNUndo, 1,
+	 PyDoc_STR("() -> None")},
+	{"TXNCanRedo", (PyCFunction)TXNObj_TXNCanRedo, 1,
+	 PyDoc_STR("() -> (Boolean _rv, TXNActionKey oTXNActionKey)")},
+	{"TXNRedo", (PyCFunction)TXNObj_TXNRedo, 1,
+	 PyDoc_STR("() -> None")},
+	{"TXNCut", (PyCFunction)TXNObj_TXNCut, 1,
+	 PyDoc_STR("() -> None")},
+	{"TXNCopy", (PyCFunction)TXNObj_TXNCopy, 1,
+	 PyDoc_STR("() -> None")},
+	{"TXNPaste", (PyCFunction)TXNObj_TXNPaste, 1,
+	 PyDoc_STR("() -> None")},
+	{"TXNClear", (PyCFunction)TXNObj_TXNClear, 1,
+	 PyDoc_STR("() -> None")},
+	{"TXNGetSelection", (PyCFunction)TXNObj_TXNGetSelection, 1,
+	 PyDoc_STR("() -> (TXNOffset oStartOffset, TXNOffset oEndOffset)")},
+	{"TXNShowSelection", (PyCFunction)TXNObj_TXNShowSelection, 1,
+	 PyDoc_STR("(Boolean iShowEnd) -> None")},
+	{"TXNIsSelectionEmpty", (PyCFunction)TXNObj_TXNIsSelectionEmpty, 1,
+	 PyDoc_STR("() -> (Boolean _rv)")},
+	{"TXNSetSelection", (PyCFunction)TXNObj_TXNSetSelection, 1,
+	 PyDoc_STR("(TXNOffset iStartOffset, TXNOffset iEndOffset) -> None")},
+	{"TXNCountRunsInRange", (PyCFunction)TXNObj_TXNCountRunsInRange, 1,
+	 PyDoc_STR("(TXNOffset iStartOffset, TXNOffset iEndOffset) -> (ItemCount oRunCount)")},
+	{"TXNDataSize", (PyCFunction)TXNObj_TXNDataSize, 1,
+	 PyDoc_STR("() -> (ByteCount _rv)")},
+	{"TXNGetData", (PyCFunction)TXNObj_TXNGetData, 1,
+	 PyDoc_STR("(TXNOffset iStartOffset, TXNOffset iEndOffset) -> (Handle oDataHandle)")},
+	{"TXNGetDataEncoded", (PyCFunction)TXNObj_TXNGetDataEncoded, 1,
+	 PyDoc_STR("(TXNOffset iStartOffset, TXNOffset iEndOffset, TXNDataType iEncoding) -> (Handle oDataHandle)")},
+	{"TXNSetDataFromFile", (PyCFunction)TXNObj_TXNSetDataFromFile, 1,
+	 PyDoc_STR("(SInt16 iFileRefNum, OSType iFileType, ByteCount iFileLength, TXNOffset iStartOffset, TXNOffset iEndOffset) -> None")},
+	{"TXNGetChangeCount", (PyCFunction)TXNObj_TXNGetChangeCount, 1,
+	 PyDoc_STR("() -> (ItemCount _rv)")},
+	{"TXNSave", (PyCFunction)TXNObj_TXNSave, 1,
+	 PyDoc_STR("(TXNFileType iType, OSType iResType, TXNPermanentTextEncodingType iPermanentEncoding, FSSpec iFileSpecification, SInt16 iDataReference, SInt16 iResourceReference) -> None")},
+	{"TXNRevert", (PyCFunction)TXNObj_TXNRevert, 1,
+	 PyDoc_STR("() -> None")},
+	{"TXNPageSetup", (PyCFunction)TXNObj_TXNPageSetup, 1,
+	 PyDoc_STR("() -> None")},
+	{"TXNPrint", (PyCFunction)TXNObj_TXNPrint, 1,
+	 PyDoc_STR("() -> None")},
+	{"TXNGetViewRect", (PyCFunction)TXNObj_TXNGetViewRect, 1,
+	 PyDoc_STR("() -> (Rect oViewRect)")},
+	{"TXNSetViewRect", (PyCFunction)TXNObj_TXNSetViewRect, 1,
+	 PyDoc_STR("(Rect iViewRect) -> None")},
+	{"TXNAttachObjectToWindow", (PyCFunction)TXNObj_TXNAttachObjectToWindow, 1,
+	 PyDoc_STR("(GWorldPtr iWindow, Boolean iIsActualWindow) -> None")},
+	{"TXNIsObjectAttachedToWindow", (PyCFunction)TXNObj_TXNIsObjectAttachedToWindow, 1,
+	 PyDoc_STR("() -> (Boolean _rv)")},
+	{"TXNDragTracker", (PyCFunction)TXNObj_TXNDragTracker, 1,
+	 PyDoc_STR("(TXNFrameID iTXNFrameID, DragTrackingMessage iMessage, WindowPtr iWindow, DragReference iDragReference, Boolean iDifferentObjectSameWindow) -> None")},
+	{"TXNDragReceiver", (PyCFunction)TXNObj_TXNDragReceiver, 1,
+	 PyDoc_STR("(TXNFrameID iTXNFrameID, WindowPtr iWindow, DragReference iDragReference, Boolean iDifferentObjectSameWindow) -> None")},
+	{"TXNActivate", (PyCFunction)TXNObj_TXNActivate, 1,
+	 PyDoc_STR("(TXNFrameID iTXNFrameID, TXNScrollBarState iActiveState) -> None")},
+	{"TXNEchoMode", (PyCFunction)TXNObj_TXNEchoMode, 1,
+	 PyDoc_STR("(UniChar iEchoCharacter, TextEncoding iEncoding, Boolean iOn) -> None")},
+	{"TXNDoFontMenuSelection", (PyCFunction)TXNObj_TXNDoFontMenuSelection, 1,
+	 PyDoc_STR("(TXNFontMenuObject iTXNFontMenuObject, SInt16 iMenuID, SInt16 iMenuItem) -> None")},
+	{"TXNPrepareFontMenu", (PyCFunction)TXNObj_TXNPrepareFontMenu, 1,
+	 PyDoc_STR("(TXNFontMenuObject iTXNFontMenuObject) -> None")},
+	{"TXNPointToOffset", (PyCFunction)TXNObj_TXNPointToOffset, 1,
+	 PyDoc_STR("(Point iPoint) -> (TXNOffset oOffset)")},
+	{"TXNOffsetToPoint", (PyCFunction)TXNObj_TXNOffsetToPoint, 1,
+	 PyDoc_STR("(TXNOffset iOffset) -> (Point oPoint)")},
+	{"TXNGetLineCount", (PyCFunction)TXNObj_TXNGetLineCount, 1,
+	 PyDoc_STR("() -> (ItemCount oLineTotal)")},
+	{"TXNGetLineMetrics", (PyCFunction)TXNObj_TXNGetLineMetrics, 1,
+	 PyDoc_STR("(UInt32 iLineNumber) -> (Fixed oLineWidth, Fixed oLineHeight)")},
+	{"TXNIsObjectAttachedToSpecificWindow", (PyCFunction)TXNObj_TXNIsObjectAttachedToSpecificWindow, 1,
+	 PyDoc_STR("(WindowPtr iWindow) -> (Boolean oAttached)")},
+	{"TXNRecalcTextLayout", (PyCFunction)TXNObj_TXNRecalcTextLayout, 1,
+	 PyDoc_STR("() -> None")},
+	{NULL, NULL, 0}
+};
+
+#define TXNObj_getsetlist NULL
+
+
+#define TXNObj_compare NULL
+
+#define TXNObj_repr NULL
+
+#define TXNObj_hash NULL
+#define TXNObj_tp_init 0
+
+#define TXNObj_tp_alloc PyType_GenericAlloc
+
+static PyObject *TXNObj_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *_self;
+	TXNObject itself;
+	char *kw[] = {"itself", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, TXNObj_Convert, &itself)) return NULL;
+	if ((_self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	((TXNObjectObject *)_self)->ob_itself = itself;
+	return _self;
+}
+
+#define TXNObj_tp_free PyObject_Del
+
+
+PyTypeObject TXNObject_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"_Mlte.TXNObject", /*tp_name*/
+	sizeof(TXNObjectObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) TXNObj_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) TXNObj_compare, /*tp_compare*/
+	(reprfunc) TXNObj_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) TXNObj_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	TXNObj_methods, /* tp_methods */
+	0, /*tp_members*/
+	TXNObj_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	TXNObj_tp_init, /* tp_init */
+	TXNObj_tp_alloc, /* tp_alloc */
+	TXNObj_tp_new, /* tp_new */
+	TXNObj_tp_free, /* tp_free */
+};
+
+/* ------------------- End object type TXNObject -------------------- */
+
+
+/* ----------------- Object type TXNFontMenuObject ------------------ */
+
+PyTypeObject TXNFontMenuObject_Type;
+
+#define TXNFontMenuObj_Check(x) ((x)->ob_type == &TXNFontMenuObject_Type || PyObject_TypeCheck((x), &TXNFontMenuObject_Type))
+
+typedef struct TXNFontMenuObjectObject {
+	PyObject_HEAD
+	TXNFontMenuObject ob_itself;
+} TXNFontMenuObjectObject;
+
+PyObject *TXNFontMenuObj_New(TXNFontMenuObject itself)
+{
+	TXNFontMenuObjectObject *it;
+	if (itself == NULL) return PyMac_Error(resNotFound);
+	it = PyObject_NEW(TXNFontMenuObjectObject, &TXNFontMenuObject_Type);
+	if (it == NULL) return NULL;
+	it->ob_itself = itself;
+	return (PyObject *)it;
+}
+
+int TXNFontMenuObj_Convert(PyObject *v, TXNFontMenuObject *p_itself)
+{
+	if (!TXNFontMenuObj_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "TXNFontMenuObject required");
+		return 0;
+	}
+	*p_itself = ((TXNFontMenuObjectObject *)v)->ob_itself;
+	return 1;
+}
+
+static void TXNFontMenuObj_dealloc(TXNFontMenuObjectObject *self)
+{
+	/* Cleanup of self->ob_itself goes here */
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *TXNFontMenuObj_TXNGetFontMenuHandle(TXNFontMenuObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	MenuHandle oFontMenuHandle;
+#ifndef TXNGetFontMenuHandle
+	PyMac_PRECHECK(TXNGetFontMenuHandle);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = TXNGetFontMenuHandle(_self->ob_itself,
+	                            &oFontMenuHandle);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     MenuObj_New, oFontMenuHandle);
+	return _res;
+}
+
+static PyObject *TXNFontMenuObj_TXNDisposeFontMenuObject(TXNFontMenuObjectObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+#ifndef TXNDisposeFontMenuObject
+	PyMac_PRECHECK(TXNDisposeFontMenuObject);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = TXNDisposeFontMenuObject(_self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyMethodDef TXNFontMenuObj_methods[] = {
+	{"TXNGetFontMenuHandle", (PyCFunction)TXNFontMenuObj_TXNGetFontMenuHandle, 1,
+	 PyDoc_STR("() -> (MenuHandle oFontMenuHandle)")},
+	{"TXNDisposeFontMenuObject", (PyCFunction)TXNFontMenuObj_TXNDisposeFontMenuObject, 1,
+	 PyDoc_STR("() -> None")},
+	{NULL, NULL, 0}
+};
+
+#define TXNFontMenuObj_getsetlist NULL
+
+
+#define TXNFontMenuObj_compare NULL
+
+#define TXNFontMenuObj_repr NULL
+
+#define TXNFontMenuObj_hash NULL
+#define TXNFontMenuObj_tp_init 0
+
+#define TXNFontMenuObj_tp_alloc PyType_GenericAlloc
+
+static PyObject *TXNFontMenuObj_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *_self;
+	TXNFontMenuObject itself;
+	char *kw[] = {"itself", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, TXNFontMenuObj_Convert, &itself)) return NULL;
+	if ((_self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	((TXNFontMenuObjectObject *)_self)->ob_itself = itself;
+	return _self;
+}
+
+#define TXNFontMenuObj_tp_free PyObject_Del
+
+
+PyTypeObject TXNFontMenuObject_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"_Mlte.TXNFontMenuObject", /*tp_name*/
+	sizeof(TXNFontMenuObjectObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) TXNFontMenuObj_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) TXNFontMenuObj_compare, /*tp_compare*/
+	(reprfunc) TXNFontMenuObj_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) TXNFontMenuObj_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	TXNFontMenuObj_methods, /* tp_methods */
+	0, /*tp_members*/
+	TXNFontMenuObj_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	TXNFontMenuObj_tp_init, /* tp_init */
+	TXNFontMenuObj_tp_alloc, /* tp_alloc */
+	TXNFontMenuObj_tp_new, /* tp_new */
+	TXNFontMenuObj_tp_free, /* tp_free */
+};
+
+/* --------------- End object type TXNFontMenuObject ---------------- */
+
+
+static PyObject *Mlte_TXNNewObject(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	FSSpec * iFileSpec;
+	WindowPtr iWindow;
+	Rect iFrame;
+	TXNFrameOptions iFrameOptions;
+	TXNFrameType iFrameType;
+	TXNFileType iFileType;
+	TXNPermanentTextEncodingType iPermanentEncoding;
+	TXNObject oTXNObject;
+	TXNFrameID oTXNFrameID;
+#ifndef TXNNewObject
+	PyMac_PRECHECK(TXNNewObject);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&llO&l",
+	                      OptFSSpecPtr_Convert, &iFileSpec,
+	                      WinObj_Convert, &iWindow,
+	                      PyMac_GetRect, &iFrame,
+	                      &iFrameOptions,
+	                      &iFrameType,
+	                      PyMac_GetOSType, &iFileType,
+	                      &iPermanentEncoding))
+		return NULL;
+	_err = TXNNewObject(iFileSpec,
+	                    iWindow,
+	                    &iFrame,
+	                    iFrameOptions,
+	                    iFrameType,
+	                    iFileType,
+	                    iPermanentEncoding,
+	                    &oTXNObject,
+	                    &oTXNFrameID,
+	                    (TXNObjectRefcon)0);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&l",
+	                     TXNObj_New, oTXNObject,
+	                     oTXNFrameID);
+	return _res;
+}
+
+static PyObject *Mlte_TXNTerminateTextension(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef TXNTerminateTextension
+	PyMac_PRECHECK(TXNTerminateTextension);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	TXNTerminateTextension();
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Mlte_TXNIsScrapPastable(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+#ifndef TXNIsScrapPastable
+	PyMac_PRECHECK(TXNIsScrapPastable);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = TXNIsScrapPastable();
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Mlte_TXNConvertToPublicScrap(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+#ifndef TXNConvertToPublicScrap
+	PyMac_PRECHECK(TXNConvertToPublicScrap);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = TXNConvertToPublicScrap();
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Mlte_TXNConvertFromPublicScrap(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+#ifndef TXNConvertFromPublicScrap
+	PyMac_PRECHECK(TXNConvertFromPublicScrap);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = TXNConvertFromPublicScrap();
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Mlte_TXNNewFontMenuObject(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	MenuHandle iFontMenuHandle;
+	SInt16 iMenuID;
+	SInt16 iStartHierMenuID;
+	TXNFontMenuObject oTXNFontMenuObject;
+#ifndef TXNNewFontMenuObject
+	PyMac_PRECHECK(TXNNewFontMenuObject);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hh",
+	                      MenuObj_Convert, &iFontMenuHandle,
+	                      &iMenuID,
+	                      &iStartHierMenuID))
+		return NULL;
+	_err = TXNNewFontMenuObject(iFontMenuHandle,
+	                            iMenuID,
+	                            iStartHierMenuID,
+	                            &oTXNFontMenuObject);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     TXNFontMenuObj_New, oTXNFontMenuObject);
+	return _res;
+}
+
+static PyObject *Mlte_TXNVersionInformation(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	TXNVersionValue _rv;
+	TXNFeatureBits oFeatureFlags;
+#ifndef TXNVersionInformation
+	PyMac_PRECHECK(TXNVersionInformation);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = TXNVersionInformation(&oFeatureFlags);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     oFeatureFlags);
+	return _res;
+}
+
+static PyObject *Mlte_TXNInitTextension(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+
+	OSStatus _err;
+	TXNMacOSPreferredFontDescription * iDefaultFonts = NULL;
+	ItemCount iCountDefaultFonts = 0;
+	TXNInitOptions iUsageFlags;
+	PyMac_PRECHECK(TXNInitTextension);
+	if (!PyArg_ParseTuple(_args, "l", &iUsageFlags))
+	        return NULL;
+	_err = TXNInitTextension(iDefaultFonts,
+	                         iCountDefaultFonts,
+	                         iUsageFlags);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+
+}
+
+static PyMethodDef Mlte_methods[] = {
+	{"TXNNewObject", (PyCFunction)Mlte_TXNNewObject, 1,
+	 PyDoc_STR("(FSSpec * iFileSpec, WindowPtr iWindow, Rect iFrame, TXNFrameOptions iFrameOptions, TXNFrameType iFrameType, TXNFileType iFileType, TXNPermanentTextEncodingType iPermanentEncoding) -> (TXNObject oTXNObject, TXNFrameID oTXNFrameID)")},
+	{"TXNTerminateTextension", (PyCFunction)Mlte_TXNTerminateTextension, 1,
+	 PyDoc_STR("() -> None")},
+	{"TXNIsScrapPastable", (PyCFunction)Mlte_TXNIsScrapPastable, 1,
+	 PyDoc_STR("() -> (Boolean _rv)")},
+	{"TXNConvertToPublicScrap", (PyCFunction)Mlte_TXNConvertToPublicScrap, 1,
+	 PyDoc_STR("() -> None")},
+	{"TXNConvertFromPublicScrap", (PyCFunction)Mlte_TXNConvertFromPublicScrap, 1,
+	 PyDoc_STR("() -> None")},
+	{"TXNNewFontMenuObject", (PyCFunction)Mlte_TXNNewFontMenuObject, 1,
+	 PyDoc_STR("(MenuHandle iFontMenuHandle, SInt16 iMenuID, SInt16 iStartHierMenuID) -> (TXNFontMenuObject oTXNFontMenuObject)")},
+	{"TXNVersionInformation", (PyCFunction)Mlte_TXNVersionInformation, 1,
+	 PyDoc_STR("() -> (TXNVersionValue _rv, TXNFeatureBits oFeatureFlags)")},
+	{"TXNInitTextension", (PyCFunction)Mlte_TXNInitTextension, 1,
+	 PyDoc_STR("(TXNInitOptions) -> None")},
+	{NULL, NULL, 0}
+};
+
+
+
+
+void init_Mlte(void)
+{
+	PyObject *m;
+	PyObject *d;
+
+
+
+	//      PyMac_INIT_TOOLBOX_OBJECT_NEW(xxxx);
+
+
+	m = Py_InitModule("_Mlte", Mlte_methods);
+	d = PyModule_GetDict(m);
+	Mlte_Error = PyMac_GetOSErrException();
+	if (Mlte_Error == NULL ||
+	    PyDict_SetItemString(d, "Error", Mlte_Error) != 0)
+		return;
+	TXNObject_Type.ob_type = &PyType_Type;
+	if (PyType_Ready(&TXNObject_Type) < 0) return;
+	Py_INCREF(&TXNObject_Type);
+	PyModule_AddObject(m, "TXNObject", (PyObject *)&TXNObject_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&TXNObject_Type);
+	PyModule_AddObject(m, "TXNObjectType", (PyObject *)&TXNObject_Type);
+	TXNFontMenuObject_Type.ob_type = &PyType_Type;
+	if (PyType_Ready(&TXNFontMenuObject_Type) < 0) return;
+	Py_INCREF(&TXNFontMenuObject_Type);
+	PyModule_AddObject(m, "TXNFontMenuObject", (PyObject *)&TXNFontMenuObject_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&TXNFontMenuObject_Type);
+	PyModule_AddObject(m, "TXNFontMenuObjectType", (PyObject *)&TXNFontMenuObject_Type);
+}
+
+/* ======================== End module _Mlte ======================== */
+

Added: vendor/Python/current/Mac/Modules/mlte/mltescan.py
===================================================================
--- vendor/Python/current/Mac/Modules/mlte/mltescan.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/mlte/mltescan.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,143 @@
+# Scan an Apple header file, generating a Python file of generator calls.
+
+import sys
+import os
+from bgenlocations import TOOLBOXDIR, BGENDIR
+sys.path.append(BGENDIR)
+from scantools import Scanner_OSX
+
+LONG = "MacTextEditor"
+SHORT = "mlte"
+OBJECTS = ("TXNObject", "TXNFontMenuObject")
+# ADD object typenames here
+
+def main():
+    input = "MacTextEditor.h"
+    output = SHORT + "gen.py"
+    defsoutput = TOOLBOXDIR + LONG + ".py"
+    scanner = MyScanner(input, output, defsoutput)
+    scanner.scan()
+    scanner.gentypetest(SHORT+"typetest.py")
+    scanner.close()
+    print "=== Testing definitions output code ==="
+    execfile(defsoutput, {}, {})
+    print "=== Done scanning and generating, now importing the generated code... ==="
+    exec "import " + SHORT + "support"
+    print "=== Done.  It's up to you to compile it now! ==="
+
+class MyScanner(Scanner_OSX):
+
+    def destination(self, type, name, arglist):
+        classname = "Function"
+        listname = "functions"
+        if arglist:
+            t, n, m = arglist[0]
+            if t in OBJECTS and m == "InMode":
+                classname = "Method"
+                listname = t + "_methods"
+        return classname, listname
+
+    def writeinitialdefs(self):
+        self.defsfile.write("""
+def FOUR_CHAR_CODE(x): return x
+false = 0
+true = 1
+kTXNClearThisControl = 0xFFFFFFFF
+kTXNClearTheseFontFeatures = 0x80000000
+kTXNDontCareTypeSize = 0xFFFFFFFF
+kTXNDecrementTypeSize = 0x80000000
+kTXNUseCurrentSelection = 0xFFFFFFFF
+kTXNStartOffset = 0
+kTXNEndOffset = 0x7FFFFFFF
+MovieFileType = FOUR_CHAR_CODE('moov')
+kTXNUseEncodingWordRulesMask = 0x80000000
+kTXNFontSizeAttributeSize = 4
+normal = 0
+""")
+
+    def makeblacklistnames(self):
+        return [
+                "TXNGetFontDefaults", # Arg is too difficult
+                "TXNSetFontDefaults", # Arg is too difficult
+                "TXNInitTextension", # done manually
+
+                # Constants with funny definitions
+                "kTXNClearThisControl",
+                "kTXNClearTheseFontFeatures",
+                "kTXNDontCareTypeSize",
+                "kTXNDecrementTypeSize",
+                "kTXNUseCurrentSelection",
+                "kTXNStartOffset",
+                "kTXNEndOffset",
+                "kTXNQDFontNameAttributeSize",
+                "kTXNQDFontFamilyIDAttributeSize",
+                "kTXNQDFontSizeAttributeSize",
+                "kTXNQDFontStyleAttributeSize",
+                "kTXNQDFontColorAttributeSize",
+                "kTXNTextEncodingAttributeSize",
+                "kTXNUseEncodingWordRulesMask",
+                "kTXNFontSizeAttributeSize",
+                "status",
+                "justification",
+                'TXNTSMCheck', # OS8
+                ]
+
+    def makeblacklisttypes(self):
+        return [
+                "TXNTab", # TBD
+                "TXNMargins", # TBD
+                "TXNControlData", #TBD
+                "TXNATSUIFeatures", #TBD
+                "TXNATSUIVariations", #TBD
+                "TXNAttributeData", #TBD
+                "TXNTypeAttributes", #TBD
+                "TXNMatchTextRecord", #TBD
+                "TXNBackground", #TBD
+                "TXNFindUPP",
+                "ATSUStyle", #TBD
+                "TXNBackground_ptr", #TBD
+                "TXNControlData_ptr", #TBD
+                "TXNControlTag_ptr", #TBD
+                "TXNLongRect", #TBD
+                "TXNLongRect_ptr", #TBD
+                "TXNTypeAttributes_ptr", #TBD
+
+                "TXNActionKeyMapperProcPtr",
+                "TXNActionKeyMapperUPP",
+                "TXNTextBoxOptionsData",
+                "TXNCountOptions",
+                "void_ptr",
+                ]
+
+    def makerepairinstructions(self):
+        return [
+                # TXNNewObject has a lot of optional parameters
+                ([("FSSpec_ptr", "iFileSpec", "InMode")],
+                 [("OptFSSpecPtr", "*", "*")]),
+                ([("Rect", "iFrame", "OutMode")],
+                 [("OptRectPtr", "*", "InMode")]),
+
+                # In UH 332 some of the "const" are missing for input parameters passed
+                # by reference. We fix that up here.
+                ([("EventRecord", "iEvent", "OutMode")],
+                 [("EventRecord_ptr", "*", "InMode")]),
+                ([("FSSpec", "iFileSpecification", "OutMode")],
+                 [("FSSpec_ptr", "*", "InMode")]),
+                ([("TXNMacOSPreferredFontDescription", "iFontDefaults", "OutMode")],
+                 [("TXNMacOSPreferredFontDescription_ptr", "*", "InMode")]),
+
+                # In buffers are passed as void *
+                ([("void", "*", "OutMode"), ("ByteCount", "*", "InMode")],
+                 [("MlteInBuffer", "*", "InMode")]),
+
+                # The AdjustCursor region handle is optional
+                ([("RgnHandle", "ioCursorRgn", "InMode")],
+                 [("OptRgnHandle", "*", "*")]),
+
+                # The GWorld for TXNDraw is optional
+                ([('GWorldPtr', 'iDrawPort', 'InMode')],
+                 [('OptGWorldPtr', '*', '*')]),
+                ]
+
+if __name__ == "__main__":
+    main()

Added: vendor/Python/current/Mac/Modules/mlte/mltesupport.py
===================================================================
--- vendor/Python/current/Mac/Modules/mlte/mltesupport.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/mlte/mltesupport.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,202 @@
+# This script generates a Python interface for an Apple Macintosh Manager.
+# It uses the "bgen" package to generate C code.
+# The function specifications are generated by scanning the mamager's header file,
+# using the "scantools" package (customized for this particular manager).
+
+#error missing SetActionFilter
+
+import string
+
+# Declarations that change for each manager
+MODNAME = '_Mlte'                               # The name of the module
+
+# The following is *usually* unchanged but may still require tuning
+MODPREFIX = 'Mlte'                      # The prefix for module-wide routines
+INPUTFILE = string.lower(MODPREFIX) + 'gen.py' # The file generated by the scanner
+OUTPUTFILE = MODNAME + "module.c"       # The file generated by this program
+
+from macsupport import *
+
+# Create the type objects
+
+includestuff = includestuff + """
+#include <Carbon/Carbon.h>
+
+/* For now we declare them forward here. They'll go to mactoolbox later */
+static PyObject *TXNObj_New(TXNObject);
+static int TXNObj_Convert(PyObject *, TXNObject *);
+static PyObject *TXNFontMenuObj_New(TXNFontMenuObject);
+static int TXNFontMenuObj_Convert(PyObject *, TXNFontMenuObject *);
+
+// ADD declarations
+#ifdef NOTYET_USE_TOOLBOX_OBJECT_GLUE
+//extern PyObject *_CFTypeRefObj_New(CFTypeRef);
+//extern int _CFTypeRefObj_Convert(PyObject *, CFTypeRef *);
+
+//#define CFTypeRefObj_New _CFTypeRefObj_New
+//#define CFTypeRefObj_Convert _CFTypeRefObj_Convert
+#endif
+
+/*
+** Parse an optional fsspec
+*/
+static int
+OptFSSpecPtr_Convert(PyObject *v, FSSpec **p_itself)
+{
+        static FSSpec fss;
+        if (v == Py_None)
+        {
+                *p_itself = NULL;
+                return 1;
+        }
+        *p_itself = &fss;
+        return PyMac_GetFSSpec(v, *p_itself);
+}
+
+/*
+** Parse an optional rect
+*/
+static int
+OptRectPtr_Convert(PyObject *v, Rect **p_itself)
+{
+        static Rect r;
+
+        if (v == Py_None)
+        {
+                *p_itself = NULL;
+                return 1;
+        }
+        *p_itself = &r;
+        return PyMac_GetRect(v, *p_itself);
+}
+
+/*
+** Parse an optional GWorld
+*/
+static int
+OptGWorldObj_Convert(PyObject *v, GWorldPtr *p_itself)
+{
+        if (v == Py_None)
+        {
+                *p_itself = NULL;
+                return 1;
+        }
+        return GWorldObj_Convert(v, p_itself);
+}
+
+"""
+
+initstuff = initstuff + """
+//      PyMac_INIT_TOOLBOX_OBJECT_NEW(xxxx);
+"""
+TXNObject = OpaqueByValueType("TXNObject", "TXNObj")
+TXNFontMenuObject = OpaqueByValueType("TXNFontMenuObject", "TXNFontMenuObj")
+
+TXNFrameID = Type("TXNFrameID", "l")
+TXNVersionValue = Type("TXNVersionValue", "l")
+TXNFeatureBits = Type("TXNFeatureBits", "l")
+TXNInitOptions = Type("TXNInitOptions", "l")
+TXNFrameOptions = Type("TXNFrameOptions", "l")
+TXNContinuousFlags = Type("TXNContinuousFlags", "l")
+TXNMatchOptions = Type("TXNMatchOptions", "l")
+TXNFileType = OSTypeType("TXNFileType")
+TXNFrameType = Type("TXNFrameType", "l")
+TXNDataType = OSTypeType("TXNDataType")
+TXNControlTag = OSTypeType("TXNControlTag")
+TXNActionKey = Type("TXNActionKey", "l")
+TXNTabType = Type("TXNTabType", "b")
+TXNScrollBarState = Type("TXNScrollBarState", "l")
+TXNOffset = Type("TXNOffset", "l")
+TXNObjectRefcon = FakeType("(TXNObjectRefcon)0") # XXXX For now...
+TXNErrors = OSErrType("TXNErrors", "l")
+TXNTypeRunAttributes = OSTypeType("TXNTypeRunAttributes")
+TXNTypeRunAttributeSizes = Type("TXNTypeRunAttributeSizes", "l")
+TXNPermanentTextEncodingType = Type("TXNPermanentTextEncodingType", "l")
+TXTNTag = OSTypeType("TXTNTag")
+TXNBackgroundType = Type("TXNBackgroundType", "l")
+DragReference = OpaqueByValueType("DragReference", "DragObj")
+DragTrackingMessage = Type("DragTrackingMessage", "h")
+RgnHandle = OpaqueByValueType("RgnHandle", "ResObj")
+OptRgnHandle = OpaqueByValueType("RgnHandle", "OptResObj")
+GWorldPtr = OpaqueByValueType("GWorldPtr", "GWorldObj")
+OptGWorldPtr = OpaqueByValueType("GWorldPtr", "OptGWorldObj")
+MlteInBuffer = VarInputBufferType('void *', 'ByteCount', 'l')
+
+OptFSSpecPtr = OpaqueByValueType("FSSpec *", "OptFSSpecPtr")
+OptRectPtr = OpaqueByValueType("Rect *", "OptRectPtr")
+
+UniChar = Type("UniChar", "h") # XXXX For now...
+# ADD object type here
+
+execfile("mltetypetest.py")
+
+# Our (opaque) objects
+
+class TXNObjDefinition(PEP253Mixin, GlobalObjectDefinition):
+    def outputCheckNewArg(self):
+        Output("if (itself == NULL) return PyMac_Error(resNotFound);")
+
+class TXNFontMenuObjDefinition(PEP253Mixin, GlobalObjectDefinition):
+    def outputCheckNewArg(self):
+        Output("if (itself == NULL) return PyMac_Error(resNotFound);")
+
+
+# ADD object class here
+
+# From here on it's basically all boiler plate...
+
+# Create the generator groups and link them
+module = MacModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff)
+TXNObject_object = TXNObjDefinition("TXNObject", "TXNObj", "TXNObject")
+TXNFontMenuObject_object = TXNFontMenuObjDefinition("TXNFontMenuObject", "TXNFontMenuObj", "TXNFontMenuObject")
+
+# ADD object here
+
+module.addobject(TXNObject_object)
+module.addobject(TXNFontMenuObject_object)
+# ADD addobject call here
+
+# Create the generator classes used to populate the lists
+Function = OSErrWeakLinkFunctionGenerator
+Method = OSErrWeakLinkMethodGenerator
+
+# Create and populate the lists
+functions = []
+TXNObject_methods = []
+TXNFontMenuObject_methods = []
+
+# ADD _methods initializer here
+execfile(INPUTFILE)
+
+
+# add the populated lists to the generator groups
+# (in a different wordl the scan program would generate this)
+for f in functions: module.add(f)
+for f in TXNObject_methods: TXNObject_object.add(f)
+for f in TXNFontMenuObject_methods: TXNFontMenuObject_object.add(f)
+
+# ADD Manual generators here
+inittextension_body = """
+OSStatus _err;
+TXNMacOSPreferredFontDescription * iDefaultFonts = NULL;
+ItemCount iCountDefaultFonts = 0;
+TXNInitOptions iUsageFlags;
+PyMac_PRECHECK(TXNInitTextension);
+if (!PyArg_ParseTuple(_args, "l", &iUsageFlags))
+        return NULL;
+_err = TXNInitTextension(iDefaultFonts,
+                         iCountDefaultFonts,
+                         iUsageFlags);
+if (_err != noErr) return PyMac_Error(_err);
+Py_INCREF(Py_None);
+_res = Py_None;
+return _res;
+"""
+
+f = ManualGenerator("TXNInitTextension", inittextension_body);
+f.docstring = lambda: "(TXNInitOptions) -> None"
+module.add(f)
+
+# generate output (open the output file as late as possible)
+SetOutputFileName(OUTPUTFILE)
+module.generate()

Added: vendor/Python/current/Mac/Modules/osa/_OSAmodule.c
===================================================================
--- vendor/Python/current/Mac/Modules/osa/_OSAmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/osa/_OSAmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1235 @@
+
+/* ========================== Module _OSA =========================== */
+
+#include "Python.h"
+
+
+
+#include "pymactoolbox.h"
+
+/* Macro to test whether a weak-loaded CFM function exists */
+#define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL )  {\
+        PyErr_SetString(PyExc_NotImplementedError, \
+        "Not available in this shared library/OS version"); \
+        return NULL; \
+    }} while(0)
+
+
+#if PY_VERSION_HEX < 0x02040000
+PyObject *PyMac_GetOSErrException(void);
+#endif
+#include <Carbon/Carbon.h>
+
+#ifdef USE_TOOLBOX_OBJECT_GLUE
+extern PyObject *_OSAObj_New(ComponentInstance);
+extern int _OSAObj_Convert(PyObject *, ComponentInstance *);
+
+#define OSAObj_New _OSAObj_New
+#define OSAObj_Convert _OSAObj_Convert
+#endif
+
+static PyObject *OSA_Error;
+
+/* ---------------- Object type OSAComponentInstance ---------------- */
+
+PyTypeObject OSAComponentInstance_Type;
+
+#define OSAObj_Check(x) ((x)->ob_type == &OSAComponentInstance_Type || PyObject_TypeCheck((x), &OSAComponentInstance_Type))
+
+typedef struct OSAComponentInstanceObject {
+	PyObject_HEAD
+	ComponentInstance ob_itself;
+} OSAComponentInstanceObject;
+
+PyObject *OSAObj_New(ComponentInstance itself)
+{
+	OSAComponentInstanceObject *it;
+	if (itself == NULL) {
+	                                PyErr_SetString(OSA_Error,"NULL ComponentInstance");
+	                                return NULL;
+	                        }
+	it = PyObject_NEW(OSAComponentInstanceObject, &OSAComponentInstance_Type);
+	if (it == NULL) return NULL;
+	it->ob_itself = itself;
+	return (PyObject *)it;
+}
+
+int OSAObj_Convert(PyObject *v, ComponentInstance *p_itself)
+{
+
+	                if (CmpInstObj_Convert(v, p_itself))
+	                        return 1;
+	                PyErr_Clear();
+	                
+	if (!OSAObj_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "OSAComponentInstance required");
+		return 0;
+	}
+	*p_itself = ((OSAComponentInstanceObject *)v)->ob_itself;
+	return 1;
+}
+
+static void OSAObj_dealloc(OSAComponentInstanceObject *self)
+{
+	/* Cleanup of self->ob_itself goes here */
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *OSAObj_OSALoad(OSAComponentInstanceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSAError _err;
+	AEDesc scriptData;
+	long modeFlags;
+	OSAID resultingScriptID;
+#ifndef OSALoad
+	PyMac_PRECHECK(OSALoad);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      AEDesc_Convert, &scriptData,
+	                      &modeFlags))
+		return NULL;
+	_err = OSALoad(_self->ob_itself,
+	               &scriptData,
+	               modeFlags,
+	               &resultingScriptID);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     resultingScriptID);
+	return _res;
+}
+
+static PyObject *OSAObj_OSAStore(OSAComponentInstanceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSAError _err;
+	OSAID scriptID;
+	DescType desiredType;
+	long modeFlags;
+	AEDesc resultingScriptData;
+#ifndef OSAStore
+	PyMac_PRECHECK(OSAStore);
+#endif
+	if (!PyArg_ParseTuple(_args, "lO&l",
+	                      &scriptID,
+	                      PyMac_GetOSType, &desiredType,
+	                      &modeFlags))
+		return NULL;
+	_err = OSAStore(_self->ob_itself,
+	                scriptID,
+	                desiredType,
+	                modeFlags,
+	                &resultingScriptData);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     AEDesc_New, &resultingScriptData);
+	return _res;
+}
+
+static PyObject *OSAObj_OSAExecute(OSAComponentInstanceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSAError _err;
+	OSAID compiledScriptID;
+	OSAID contextID;
+	long modeFlags;
+	OSAID resultingScriptValueID;
+#ifndef OSAExecute
+	PyMac_PRECHECK(OSAExecute);
+#endif
+	if (!PyArg_ParseTuple(_args, "lll",
+	                      &compiledScriptID,
+	                      &contextID,
+	                      &modeFlags))
+		return NULL;
+	_err = OSAExecute(_self->ob_itself,
+	                  compiledScriptID,
+	                  contextID,
+	                  modeFlags,
+	                  &resultingScriptValueID);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     resultingScriptValueID);
+	return _res;
+}
+
+static PyObject *OSAObj_OSADisplay(OSAComponentInstanceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSAError _err;
+	OSAID scriptValueID;
+	DescType desiredType;
+	long modeFlags;
+	AEDesc resultingText;
+#ifndef OSADisplay
+	PyMac_PRECHECK(OSADisplay);
+#endif
+	if (!PyArg_ParseTuple(_args, "lO&l",
+	                      &scriptValueID,
+	                      PyMac_GetOSType, &desiredType,
+	                      &modeFlags))
+		return NULL;
+	_err = OSADisplay(_self->ob_itself,
+	                  scriptValueID,
+	                  desiredType,
+	                  modeFlags,
+	                  &resultingText);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     AEDesc_New, &resultingText);
+	return _res;
+}
+
+static PyObject *OSAObj_OSAScriptError(OSAComponentInstanceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSAError _err;
+	OSType selector;
+	DescType desiredType;
+	AEDesc resultingErrorDescription;
+#ifndef OSAScriptError
+	PyMac_PRECHECK(OSAScriptError);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetOSType, &selector,
+	                      PyMac_GetOSType, &desiredType))
+		return NULL;
+	_err = OSAScriptError(_self->ob_itself,
+	                      selector,
+	                      desiredType,
+	                      &resultingErrorDescription);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     AEDesc_New, &resultingErrorDescription);
+	return _res;
+}
+
+static PyObject *OSAObj_OSADispose(OSAComponentInstanceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSAError _err;
+	OSAID scriptID;
+#ifndef OSADispose
+	PyMac_PRECHECK(OSADispose);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &scriptID))
+		return NULL;
+	_err = OSADispose(_self->ob_itself,
+	                  scriptID);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *OSAObj_OSASetScriptInfo(OSAComponentInstanceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSAError _err;
+	OSAID scriptID;
+	OSType selector;
+	long value;
+#ifndef OSASetScriptInfo
+	PyMac_PRECHECK(OSASetScriptInfo);
+#endif
+	if (!PyArg_ParseTuple(_args, "lO&l",
+	                      &scriptID,
+	                      PyMac_GetOSType, &selector,
+	                      &value))
+		return NULL;
+	_err = OSASetScriptInfo(_self->ob_itself,
+	                        scriptID,
+	                        selector,
+	                        value);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *OSAObj_OSAGetScriptInfo(OSAComponentInstanceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSAError _err;
+	OSAID scriptID;
+	OSType selector;
+	long result;
+#ifndef OSAGetScriptInfo
+	PyMac_PRECHECK(OSAGetScriptInfo);
+#endif
+	if (!PyArg_ParseTuple(_args, "lO&",
+	                      &scriptID,
+	                      PyMac_GetOSType, &selector))
+		return NULL;
+	_err = OSAGetScriptInfo(_self->ob_itself,
+	                        scriptID,
+	                        selector,
+	                        &result);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     result);
+	return _res;
+}
+
+static PyObject *OSAObj_OSAScriptingComponentName(OSAComponentInstanceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSAError _err;
+	AEDesc resultingScriptingComponentName;
+#ifndef OSAScriptingComponentName
+	PyMac_PRECHECK(OSAScriptingComponentName);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = OSAScriptingComponentName(_self->ob_itself,
+	                                 &resultingScriptingComponentName);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     AEDesc_New, &resultingScriptingComponentName);
+	return _res;
+}
+
+static PyObject *OSAObj_OSACompile(OSAComponentInstanceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSAError _err;
+	AEDesc sourceData;
+	long modeFlags;
+	OSAID previousAndResultingScriptID;
+#ifndef OSACompile
+	PyMac_PRECHECK(OSACompile);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      AEDesc_Convert, &sourceData,
+	                      &modeFlags))
+		return NULL;
+	_err = OSACompile(_self->ob_itself,
+	                  &sourceData,
+	                  modeFlags,
+	                  &previousAndResultingScriptID);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     previousAndResultingScriptID);
+	return _res;
+}
+
+static PyObject *OSAObj_OSACopyID(OSAComponentInstanceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSAError _err;
+	OSAID fromID;
+	OSAID toID;
+#ifndef OSACopyID
+	PyMac_PRECHECK(OSACopyID);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &fromID))
+		return NULL;
+	_err = OSACopyID(_self->ob_itself,
+	                 fromID,
+	                 &toID);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     toID);
+	return _res;
+}
+
+static PyObject *OSAObj_OSAGetSource(OSAComponentInstanceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSAError _err;
+	OSAID scriptID;
+	DescType desiredType;
+	AEDesc resultingSourceData;
+#ifndef OSAGetSource
+	PyMac_PRECHECK(OSAGetSource);
+#endif
+	if (!PyArg_ParseTuple(_args, "lO&",
+	                      &scriptID,
+	                      PyMac_GetOSType, &desiredType))
+		return NULL;
+	_err = OSAGetSource(_self->ob_itself,
+	                    scriptID,
+	                    desiredType,
+	                    &resultingSourceData);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     AEDesc_New, &resultingSourceData);
+	return _res;
+}
+
+static PyObject *OSAObj_OSACoerceFromDesc(OSAComponentInstanceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSAError _err;
+	AEDesc scriptData;
+	long modeFlags;
+	OSAID resultingScriptID;
+#ifndef OSACoerceFromDesc
+	PyMac_PRECHECK(OSACoerceFromDesc);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      AEDesc_Convert, &scriptData,
+	                      &modeFlags))
+		return NULL;
+	_err = OSACoerceFromDesc(_self->ob_itself,
+	                         &scriptData,
+	                         modeFlags,
+	                         &resultingScriptID);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     resultingScriptID);
+	return _res;
+}
+
+static PyObject *OSAObj_OSACoerceToDesc(OSAComponentInstanceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSAError _err;
+	OSAID scriptID;
+	DescType desiredType;
+	long modeFlags;
+	AEDesc result;
+#ifndef OSACoerceToDesc
+	PyMac_PRECHECK(OSACoerceToDesc);
+#endif
+	if (!PyArg_ParseTuple(_args, "lO&l",
+	                      &scriptID,
+	                      PyMac_GetOSType, &desiredType,
+	                      &modeFlags))
+		return NULL;
+	_err = OSACoerceToDesc(_self->ob_itself,
+	                       scriptID,
+	                       desiredType,
+	                       modeFlags,
+	                       &result);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     AEDesc_New, &result);
+	return _res;
+}
+
+static PyObject *OSAObj_OSASetDefaultTarget(OSAComponentInstanceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSAError _err;
+	AEAddressDesc target;
+#ifndef OSASetDefaultTarget
+	PyMac_PRECHECK(OSASetDefaultTarget);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      AEDesc_Convert, &target))
+		return NULL;
+	_err = OSASetDefaultTarget(_self->ob_itself,
+	                           &target);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *OSAObj_OSAStartRecording(OSAComponentInstanceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSAError _err;
+	OSAID compiledScriptToModifyID;
+#ifndef OSAStartRecording
+	PyMac_PRECHECK(OSAStartRecording);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = OSAStartRecording(_self->ob_itself,
+	                         &compiledScriptToModifyID);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     compiledScriptToModifyID);
+	return _res;
+}
+
+static PyObject *OSAObj_OSAStopRecording(OSAComponentInstanceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSAError _err;
+	OSAID compiledScriptID;
+#ifndef OSAStopRecording
+	PyMac_PRECHECK(OSAStopRecording);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &compiledScriptID))
+		return NULL;
+	_err = OSAStopRecording(_self->ob_itself,
+	                        compiledScriptID);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *OSAObj_OSALoadExecute(OSAComponentInstanceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSAError _err;
+	AEDesc scriptData;
+	OSAID contextID;
+	long modeFlags;
+	OSAID resultingScriptValueID;
+#ifndef OSALoadExecute
+	PyMac_PRECHECK(OSALoadExecute);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&ll",
+	                      AEDesc_Convert, &scriptData,
+	                      &contextID,
+	                      &modeFlags))
+		return NULL;
+	_err = OSALoadExecute(_self->ob_itself,
+	                      &scriptData,
+	                      contextID,
+	                      modeFlags,
+	                      &resultingScriptValueID);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     resultingScriptValueID);
+	return _res;
+}
+
+static PyObject *OSAObj_OSACompileExecute(OSAComponentInstanceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSAError _err;
+	AEDesc sourceData;
+	OSAID contextID;
+	long modeFlags;
+	OSAID resultingScriptValueID;
+#ifndef OSACompileExecute
+	PyMac_PRECHECK(OSACompileExecute);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&ll",
+	                      AEDesc_Convert, &sourceData,
+	                      &contextID,
+	                      &modeFlags))
+		return NULL;
+	_err = OSACompileExecute(_self->ob_itself,
+	                         &sourceData,
+	                         contextID,
+	                         modeFlags,
+	                         &resultingScriptValueID);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     resultingScriptValueID);
+	return _res;
+}
+
+static PyObject *OSAObj_OSADoScript(OSAComponentInstanceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSAError _err;
+	AEDesc sourceData;
+	OSAID contextID;
+	DescType desiredType;
+	long modeFlags;
+	AEDesc resultingText;
+#ifndef OSADoScript
+	PyMac_PRECHECK(OSADoScript);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&lO&l",
+	                      AEDesc_Convert, &sourceData,
+	                      &contextID,
+	                      PyMac_GetOSType, &desiredType,
+	                      &modeFlags))
+		return NULL;
+	_err = OSADoScript(_self->ob_itself,
+	                   &sourceData,
+	                   contextID,
+	                   desiredType,
+	                   modeFlags,
+	                   &resultingText);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     AEDesc_New, &resultingText);
+	return _res;
+}
+
+static PyObject *OSAObj_OSASetCurrentDialect(OSAComponentInstanceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSAError _err;
+	short dialectCode;
+#ifndef OSASetCurrentDialect
+	PyMac_PRECHECK(OSASetCurrentDialect);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &dialectCode))
+		return NULL;
+	_err = OSASetCurrentDialect(_self->ob_itself,
+	                            dialectCode);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *OSAObj_OSAGetCurrentDialect(OSAComponentInstanceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSAError _err;
+	short resultingDialectCode;
+#ifndef OSAGetCurrentDialect
+	PyMac_PRECHECK(OSAGetCurrentDialect);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = OSAGetCurrentDialect(_self->ob_itself,
+	                            &resultingDialectCode);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("h",
+	                     resultingDialectCode);
+	return _res;
+}
+
+static PyObject *OSAObj_OSAAvailableDialects(OSAComponentInstanceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSAError _err;
+	AEDesc resultingDialectInfoList;
+#ifndef OSAAvailableDialects
+	PyMac_PRECHECK(OSAAvailableDialects);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = OSAAvailableDialects(_self->ob_itself,
+	                            &resultingDialectInfoList);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     AEDesc_New, &resultingDialectInfoList);
+	return _res;
+}
+
+static PyObject *OSAObj_OSAGetDialectInfo(OSAComponentInstanceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSAError _err;
+	short dialectCode;
+	OSType selector;
+	AEDesc resultingDialectInfo;
+#ifndef OSAGetDialectInfo
+	PyMac_PRECHECK(OSAGetDialectInfo);
+#endif
+	if (!PyArg_ParseTuple(_args, "hO&",
+	                      &dialectCode,
+	                      PyMac_GetOSType, &selector))
+		return NULL;
+	_err = OSAGetDialectInfo(_self->ob_itself,
+	                         dialectCode,
+	                         selector,
+	                         &resultingDialectInfo);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     AEDesc_New, &resultingDialectInfo);
+	return _res;
+}
+
+static PyObject *OSAObj_OSAAvailableDialectCodeList(OSAComponentInstanceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSAError _err;
+	AEDesc resultingDialectCodeList;
+#ifndef OSAAvailableDialectCodeList
+	PyMac_PRECHECK(OSAAvailableDialectCodeList);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = OSAAvailableDialectCodeList(_self->ob_itself,
+	                                   &resultingDialectCodeList);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     AEDesc_New, &resultingDialectCodeList);
+	return _res;
+}
+
+static PyObject *OSAObj_OSAExecuteEvent(OSAComponentInstanceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSAError _err;
+	AppleEvent theAppleEvent;
+	OSAID contextID;
+	long modeFlags;
+	OSAID resultingScriptValueID;
+#ifndef OSAExecuteEvent
+	PyMac_PRECHECK(OSAExecuteEvent);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&ll",
+	                      AEDesc_Convert, &theAppleEvent,
+	                      &contextID,
+	                      &modeFlags))
+		return NULL;
+	_err = OSAExecuteEvent(_self->ob_itself,
+	                       &theAppleEvent,
+	                       contextID,
+	                       modeFlags,
+	                       &resultingScriptValueID);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     resultingScriptValueID);
+	return _res;
+}
+
+static PyObject *OSAObj_OSADoEvent(OSAComponentInstanceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSAError _err;
+	AppleEvent theAppleEvent;
+	OSAID contextID;
+	long modeFlags;
+	AppleEvent reply;
+#ifndef OSADoEvent
+	PyMac_PRECHECK(OSADoEvent);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&ll",
+	                      AEDesc_Convert, &theAppleEvent,
+	                      &contextID,
+	                      &modeFlags))
+		return NULL;
+	_err = OSADoEvent(_self->ob_itself,
+	                  &theAppleEvent,
+	                  contextID,
+	                  modeFlags,
+	                  &reply);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     AEDesc_New, &reply);
+	return _res;
+}
+
+static PyObject *OSAObj_OSAMakeContext(OSAComponentInstanceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSAError _err;
+	AEDesc contextName;
+	OSAID parentContext;
+	OSAID resultingContextID;
+#ifndef OSAMakeContext
+	PyMac_PRECHECK(OSAMakeContext);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      AEDesc_Convert, &contextName,
+	                      &parentContext))
+		return NULL;
+	_err = OSAMakeContext(_self->ob_itself,
+	                      &contextName,
+	                      parentContext,
+	                      &resultingContextID);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     resultingContextID);
+	return _res;
+}
+
+static PyObject *OSAObj_OSADebuggerCreateSession(OSAComponentInstanceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSAError _err;
+	OSAID inScript;
+	OSAID inContext;
+	OSADebugSessionRef outSession;
+#ifndef OSADebuggerCreateSession
+	PyMac_PRECHECK(OSADebuggerCreateSession);
+#endif
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &inScript,
+	                      &inContext))
+		return NULL;
+	_err = OSADebuggerCreateSession(_self->ob_itself,
+	                                inScript,
+	                                inContext,
+	                                &outSession);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     outSession);
+	return _res;
+}
+
+static PyObject *OSAObj_OSADebuggerGetSessionState(OSAComponentInstanceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSAError _err;
+	OSADebugSessionRef inSession;
+	AERecord outState;
+#ifndef OSADebuggerGetSessionState
+	PyMac_PRECHECK(OSADebuggerGetSessionState);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &inSession))
+		return NULL;
+	_err = OSADebuggerGetSessionState(_self->ob_itself,
+	                                  inSession,
+	                                  &outState);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     AEDesc_New, &outState);
+	return _res;
+}
+
+static PyObject *OSAObj_OSADebuggerSessionStep(OSAComponentInstanceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSAError _err;
+	OSADebugSessionRef inSession;
+	OSADebugStepKind inKind;
+#ifndef OSADebuggerSessionStep
+	PyMac_PRECHECK(OSADebuggerSessionStep);
+#endif
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &inSession,
+	                      &inKind))
+		return NULL;
+	_err = OSADebuggerSessionStep(_self->ob_itself,
+	                              inSession,
+	                              inKind);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *OSAObj_OSADebuggerDisposeSession(OSAComponentInstanceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSAError _err;
+	OSADebugSessionRef inSession;
+#ifndef OSADebuggerDisposeSession
+	PyMac_PRECHECK(OSADebuggerDisposeSession);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &inSession))
+		return NULL;
+	_err = OSADebuggerDisposeSession(_self->ob_itself,
+	                                 inSession);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *OSAObj_OSADebuggerGetStatementRanges(OSAComponentInstanceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSAError _err;
+	OSADebugSessionRef inSession;
+	AEDescList outStatementRangeArray;
+#ifndef OSADebuggerGetStatementRanges
+	PyMac_PRECHECK(OSADebuggerGetStatementRanges);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &inSession))
+		return NULL;
+	_err = OSADebuggerGetStatementRanges(_self->ob_itself,
+	                                     inSession,
+	                                     &outStatementRangeArray);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     AEDesc_New, &outStatementRangeArray);
+	return _res;
+}
+
+static PyObject *OSAObj_OSADebuggerGetBreakpoint(OSAComponentInstanceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSAError _err;
+	OSADebugSessionRef inSession;
+	UInt32 inSrcOffset;
+	OSAID outBreakpoint;
+#ifndef OSADebuggerGetBreakpoint
+	PyMac_PRECHECK(OSADebuggerGetBreakpoint);
+#endif
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &inSession,
+	                      &inSrcOffset))
+		return NULL;
+	_err = OSADebuggerGetBreakpoint(_self->ob_itself,
+	                                inSession,
+	                                inSrcOffset,
+	                                &outBreakpoint);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     outBreakpoint);
+	return _res;
+}
+
+static PyObject *OSAObj_OSADebuggerSetBreakpoint(OSAComponentInstanceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSAError _err;
+	OSADebugSessionRef inSession;
+	UInt32 inSrcOffset;
+	OSAID inBreakpoint;
+#ifndef OSADebuggerSetBreakpoint
+	PyMac_PRECHECK(OSADebuggerSetBreakpoint);
+#endif
+	if (!PyArg_ParseTuple(_args, "lll",
+	                      &inSession,
+	                      &inSrcOffset,
+	                      &inBreakpoint))
+		return NULL;
+	_err = OSADebuggerSetBreakpoint(_self->ob_itself,
+	                                inSession,
+	                                inSrcOffset,
+	                                inBreakpoint);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *OSAObj_OSADebuggerGetDefaultBreakpoint(OSAComponentInstanceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSAError _err;
+	OSADebugSessionRef inSession;
+	OSAID outBreakpoint;
+#ifndef OSADebuggerGetDefaultBreakpoint
+	PyMac_PRECHECK(OSADebuggerGetDefaultBreakpoint);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &inSession))
+		return NULL;
+	_err = OSADebuggerGetDefaultBreakpoint(_self->ob_itself,
+	                                       inSession,
+	                                       &outBreakpoint);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     outBreakpoint);
+	return _res;
+}
+
+static PyObject *OSAObj_OSADebuggerGetCurrentCallFrame(OSAComponentInstanceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSAError _err;
+	OSADebugSessionRef inSession;
+	OSADebugCallFrameRef outCallFrame;
+#ifndef OSADebuggerGetCurrentCallFrame
+	PyMac_PRECHECK(OSADebuggerGetCurrentCallFrame);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &inSession))
+		return NULL;
+	_err = OSADebuggerGetCurrentCallFrame(_self->ob_itself,
+	                                      inSession,
+	                                      &outCallFrame);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     outCallFrame);
+	return _res;
+}
+
+static PyObject *OSAObj_OSADebuggerGetCallFrameState(OSAComponentInstanceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSAError _err;
+	OSADebugCallFrameRef inCallFrame;
+	AERecord outState;
+#ifndef OSADebuggerGetCallFrameState
+	PyMac_PRECHECK(OSADebuggerGetCallFrameState);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &inCallFrame))
+		return NULL;
+	_err = OSADebuggerGetCallFrameState(_self->ob_itself,
+	                                    inCallFrame,
+	                                    &outState);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     AEDesc_New, &outState);
+	return _res;
+}
+
+static PyObject *OSAObj_OSADebuggerGetVariable(OSAComponentInstanceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSAError _err;
+	OSADebugCallFrameRef inCallFrame;
+	AEDesc inVariableName;
+	OSAID outVariable;
+#ifndef OSADebuggerGetVariable
+	PyMac_PRECHECK(OSADebuggerGetVariable);
+#endif
+	if (!PyArg_ParseTuple(_args, "lO&",
+	                      &inCallFrame,
+	                      AEDesc_Convert, &inVariableName))
+		return NULL;
+	_err = OSADebuggerGetVariable(_self->ob_itself,
+	                              inCallFrame,
+	                              &inVariableName,
+	                              &outVariable);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     outVariable);
+	return _res;
+}
+
+static PyObject *OSAObj_OSADebuggerSetVariable(OSAComponentInstanceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSAError _err;
+	OSADebugCallFrameRef inCallFrame;
+	AEDesc inVariableName;
+	OSAID inVariable;
+#ifndef OSADebuggerSetVariable
+	PyMac_PRECHECK(OSADebuggerSetVariable);
+#endif
+	if (!PyArg_ParseTuple(_args, "lO&l",
+	                      &inCallFrame,
+	                      AEDesc_Convert, &inVariableName,
+	                      &inVariable))
+		return NULL;
+	_err = OSADebuggerSetVariable(_self->ob_itself,
+	                              inCallFrame,
+	                              &inVariableName,
+	                              inVariable);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *OSAObj_OSADebuggerGetPreviousCallFrame(OSAComponentInstanceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSAError _err;
+	OSADebugCallFrameRef inCurrentFrame;
+	OSADebugCallFrameRef outPrevFrame;
+#ifndef OSADebuggerGetPreviousCallFrame
+	PyMac_PRECHECK(OSADebuggerGetPreviousCallFrame);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &inCurrentFrame))
+		return NULL;
+	_err = OSADebuggerGetPreviousCallFrame(_self->ob_itself,
+	                                       inCurrentFrame,
+	                                       &outPrevFrame);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     outPrevFrame);
+	return _res;
+}
+
+static PyObject *OSAObj_OSADebuggerDisposeCallFrame(OSAComponentInstanceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSAError _err;
+	OSADebugCallFrameRef inCallFrame;
+#ifndef OSADebuggerDisposeCallFrame
+	PyMac_PRECHECK(OSADebuggerDisposeCallFrame);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &inCallFrame))
+		return NULL;
+	_err = OSADebuggerDisposeCallFrame(_self->ob_itself,
+	                                   inCallFrame);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyMethodDef OSAObj_methods[] = {
+	{"OSALoad", (PyCFunction)OSAObj_OSALoad, 1,
+	 PyDoc_STR("(AEDesc scriptData, long modeFlags) -> (OSAID resultingScriptID)")},
+	{"OSAStore", (PyCFunction)OSAObj_OSAStore, 1,
+	 PyDoc_STR("(OSAID scriptID, DescType desiredType, long modeFlags) -> (AEDesc resultingScriptData)")},
+	{"OSAExecute", (PyCFunction)OSAObj_OSAExecute, 1,
+	 PyDoc_STR("(OSAID compiledScriptID, OSAID contextID, long modeFlags) -> (OSAID resultingScriptValueID)")},
+	{"OSADisplay", (PyCFunction)OSAObj_OSADisplay, 1,
+	 PyDoc_STR("(OSAID scriptValueID, DescType desiredType, long modeFlags) -> (AEDesc resultingText)")},
+	{"OSAScriptError", (PyCFunction)OSAObj_OSAScriptError, 1,
+	 PyDoc_STR("(OSType selector, DescType desiredType) -> (AEDesc resultingErrorDescription)")},
+	{"OSADispose", (PyCFunction)OSAObj_OSADispose, 1,
+	 PyDoc_STR("(OSAID scriptID) -> None")},
+	{"OSASetScriptInfo", (PyCFunction)OSAObj_OSASetScriptInfo, 1,
+	 PyDoc_STR("(OSAID scriptID, OSType selector, long value) -> None")},
+	{"OSAGetScriptInfo", (PyCFunction)OSAObj_OSAGetScriptInfo, 1,
+	 PyDoc_STR("(OSAID scriptID, OSType selector) -> (long result)")},
+	{"OSAScriptingComponentName", (PyCFunction)OSAObj_OSAScriptingComponentName, 1,
+	 PyDoc_STR("() -> (AEDesc resultingScriptingComponentName)")},
+	{"OSACompile", (PyCFunction)OSAObj_OSACompile, 1,
+	 PyDoc_STR("(AEDesc sourceData, long modeFlags) -> (OSAID previousAndResultingScriptID)")},
+	{"OSACopyID", (PyCFunction)OSAObj_OSACopyID, 1,
+	 PyDoc_STR("(OSAID fromID) -> (OSAID toID)")},
+	{"OSAGetSource", (PyCFunction)OSAObj_OSAGetSource, 1,
+	 PyDoc_STR("(OSAID scriptID, DescType desiredType) -> (AEDesc resultingSourceData)")},
+	{"OSACoerceFromDesc", (PyCFunction)OSAObj_OSACoerceFromDesc, 1,
+	 PyDoc_STR("(AEDesc scriptData, long modeFlags) -> (OSAID resultingScriptID)")},
+	{"OSACoerceToDesc", (PyCFunction)OSAObj_OSACoerceToDesc, 1,
+	 PyDoc_STR("(OSAID scriptID, DescType desiredType, long modeFlags) -> (AEDesc result)")},
+	{"OSASetDefaultTarget", (PyCFunction)OSAObj_OSASetDefaultTarget, 1,
+	 PyDoc_STR("(AEAddressDesc target) -> None")},
+	{"OSAStartRecording", (PyCFunction)OSAObj_OSAStartRecording, 1,
+	 PyDoc_STR("() -> (OSAID compiledScriptToModifyID)")},
+	{"OSAStopRecording", (PyCFunction)OSAObj_OSAStopRecording, 1,
+	 PyDoc_STR("(OSAID compiledScriptID) -> None")},
+	{"OSALoadExecute", (PyCFunction)OSAObj_OSALoadExecute, 1,
+	 PyDoc_STR("(AEDesc scriptData, OSAID contextID, long modeFlags) -> (OSAID resultingScriptValueID)")},
+	{"OSACompileExecute", (PyCFunction)OSAObj_OSACompileExecute, 1,
+	 PyDoc_STR("(AEDesc sourceData, OSAID contextID, long modeFlags) -> (OSAID resultingScriptValueID)")},
+	{"OSADoScript", (PyCFunction)OSAObj_OSADoScript, 1,
+	 PyDoc_STR("(AEDesc sourceData, OSAID contextID, DescType desiredType, long modeFlags) -> (AEDesc resultingText)")},
+	{"OSASetCurrentDialect", (PyCFunction)OSAObj_OSASetCurrentDialect, 1,
+	 PyDoc_STR("(short dialectCode) -> None")},
+	{"OSAGetCurrentDialect", (PyCFunction)OSAObj_OSAGetCurrentDialect, 1,
+	 PyDoc_STR("() -> (short resultingDialectCode)")},
+	{"OSAAvailableDialects", (PyCFunction)OSAObj_OSAAvailableDialects, 1,
+	 PyDoc_STR("() -> (AEDesc resultingDialectInfoList)")},
+	{"OSAGetDialectInfo", (PyCFunction)OSAObj_OSAGetDialectInfo, 1,
+	 PyDoc_STR("(short dialectCode, OSType selector) -> (AEDesc resultingDialectInfo)")},
+	{"OSAAvailableDialectCodeList", (PyCFunction)OSAObj_OSAAvailableDialectCodeList, 1,
+	 PyDoc_STR("() -> (AEDesc resultingDialectCodeList)")},
+	{"OSAExecuteEvent", (PyCFunction)OSAObj_OSAExecuteEvent, 1,
+	 PyDoc_STR("(AppleEvent theAppleEvent, OSAID contextID, long modeFlags) -> (OSAID resultingScriptValueID)")},
+	{"OSADoEvent", (PyCFunction)OSAObj_OSADoEvent, 1,
+	 PyDoc_STR("(AppleEvent theAppleEvent, OSAID contextID, long modeFlags) -> (AppleEvent reply)")},
+	{"OSAMakeContext", (PyCFunction)OSAObj_OSAMakeContext, 1,
+	 PyDoc_STR("(AEDesc contextName, OSAID parentContext) -> (OSAID resultingContextID)")},
+	{"OSADebuggerCreateSession", (PyCFunction)OSAObj_OSADebuggerCreateSession, 1,
+	 PyDoc_STR("(OSAID inScript, OSAID inContext) -> (OSADebugSessionRef outSession)")},
+	{"OSADebuggerGetSessionState", (PyCFunction)OSAObj_OSADebuggerGetSessionState, 1,
+	 PyDoc_STR("(OSADebugSessionRef inSession) -> (AERecord outState)")},
+	{"OSADebuggerSessionStep", (PyCFunction)OSAObj_OSADebuggerSessionStep, 1,
+	 PyDoc_STR("(OSADebugSessionRef inSession, OSADebugStepKind inKind) -> None")},
+	{"OSADebuggerDisposeSession", (PyCFunction)OSAObj_OSADebuggerDisposeSession, 1,
+	 PyDoc_STR("(OSADebugSessionRef inSession) -> None")},
+	{"OSADebuggerGetStatementRanges", (PyCFunction)OSAObj_OSADebuggerGetStatementRanges, 1,
+	 PyDoc_STR("(OSADebugSessionRef inSession) -> (AEDescList outStatementRangeArray)")},
+	{"OSADebuggerGetBreakpoint", (PyCFunction)OSAObj_OSADebuggerGetBreakpoint, 1,
+	 PyDoc_STR("(OSADebugSessionRef inSession, UInt32 inSrcOffset) -> (OSAID outBreakpoint)")},
+	{"OSADebuggerSetBreakpoint", (PyCFunction)OSAObj_OSADebuggerSetBreakpoint, 1,
+	 PyDoc_STR("(OSADebugSessionRef inSession, UInt32 inSrcOffset, OSAID inBreakpoint) -> None")},
+	{"OSADebuggerGetDefaultBreakpoint", (PyCFunction)OSAObj_OSADebuggerGetDefaultBreakpoint, 1,
+	 PyDoc_STR("(OSADebugSessionRef inSession) -> (OSAID outBreakpoint)")},
+	{"OSADebuggerGetCurrentCallFrame", (PyCFunction)OSAObj_OSADebuggerGetCurrentCallFrame, 1,
+	 PyDoc_STR("(OSADebugSessionRef inSession) -> (OSADebugCallFrameRef outCallFrame)")},
+	{"OSADebuggerGetCallFrameState", (PyCFunction)OSAObj_OSADebuggerGetCallFrameState, 1,
+	 PyDoc_STR("(OSADebugCallFrameRef inCallFrame) -> (AERecord outState)")},
+	{"OSADebuggerGetVariable", (PyCFunction)OSAObj_OSADebuggerGetVariable, 1,
+	 PyDoc_STR("(OSADebugCallFrameRef inCallFrame, AEDesc inVariableName) -> (OSAID outVariable)")},
+	{"OSADebuggerSetVariable", (PyCFunction)OSAObj_OSADebuggerSetVariable, 1,
+	 PyDoc_STR("(OSADebugCallFrameRef inCallFrame, AEDesc inVariableName, OSAID inVariable) -> None")},
+	{"OSADebuggerGetPreviousCallFrame", (PyCFunction)OSAObj_OSADebuggerGetPreviousCallFrame, 1,
+	 PyDoc_STR("(OSADebugCallFrameRef inCurrentFrame) -> (OSADebugCallFrameRef outPrevFrame)")},
+	{"OSADebuggerDisposeCallFrame", (PyCFunction)OSAObj_OSADebuggerDisposeCallFrame, 1,
+	 PyDoc_STR("(OSADebugCallFrameRef inCallFrame) -> None")},
+	{NULL, NULL, 0}
+};
+
+#define OSAObj_getsetlist NULL
+
+
+#define OSAObj_compare NULL
+
+#define OSAObj_repr NULL
+
+#define OSAObj_hash NULL
+#define OSAObj_tp_init 0
+
+#define OSAObj_tp_alloc PyType_GenericAlloc
+
+static PyObject *OSAObj_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *_self;
+	ComponentInstance itself;
+	char *kw[] = {"itself", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, OSAObj_Convert, &itself)) return NULL;
+	if ((_self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	((OSAComponentInstanceObject *)_self)->ob_itself = itself;
+	return _self;
+}
+
+#define OSAObj_tp_free PyObject_Del
+
+
+PyTypeObject OSAComponentInstance_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"_OSA.OSAComponentInstance", /*tp_name*/
+	sizeof(OSAComponentInstanceObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) OSAObj_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) OSAObj_compare, /*tp_compare*/
+	(reprfunc) OSAObj_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) OSAObj_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	OSAObj_methods, /* tp_methods */
+	0, /*tp_members*/
+	OSAObj_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	OSAObj_tp_init, /* tp_init */
+	OSAObj_tp_alloc, /* tp_alloc */
+	OSAObj_tp_new, /* tp_new */
+	OSAObj_tp_free, /* tp_free */
+};
+
+/* -------------- End object type OSAComponentInstance -------------- */
+
+
+static PyMethodDef OSA_methods[] = {
+	{NULL, NULL, 0}
+};
+
+
+
+
+void init_OSA(void)
+{
+	PyObject *m;
+	PyObject *d;
+
+
+
+	/*
+	        PyMac_INIT_TOOLBOX_OBJECT_NEW(ComponentInstance, OSAObj_New);
+	        PyMac_INIT_TOOLBOX_OBJECT_CONVERT(ComponentInstance, OSAObj_Convert);
+	*/
+
+
+	m = Py_InitModule("_OSA", OSA_methods);
+	d = PyModule_GetDict(m);
+	OSA_Error = PyMac_GetOSErrException();
+	if (OSA_Error == NULL ||
+	    PyDict_SetItemString(d, "Error", OSA_Error) != 0)
+		return;
+	OSAComponentInstance_Type.ob_type = &PyType_Type;
+	if (PyType_Ready(&OSAComponentInstance_Type) < 0) return;
+	Py_INCREF(&OSAComponentInstance_Type);
+	PyModule_AddObject(m, "OSAComponentInstance", (PyObject *)&OSAComponentInstance_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&OSAComponentInstance_Type);
+	PyModule_AddObject(m, "OSAComponentInstanceType", (PyObject *)&OSAComponentInstance_Type);
+}
+
+/* ======================== End module _OSA ========================= */
+

Added: vendor/Python/current/Mac/Modules/osa/osascan.py
===================================================================
--- vendor/Python/current/Mac/Modules/osa/osascan.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/osa/osascan.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,62 @@
+# Scan an Apple header file, generating a Python file of generator calls.
+
+import sys
+import os
+from bgenlocations import TOOLBOXDIR, BGENDIR
+sys.path.append(BGENDIR)
+from scantools import Scanner
+
+LONG = "OSAconst"
+SHORT = "osa"
+
+def main():
+    input = "OSA.h"
+    output = SHORT + "gen.py"
+    defsoutput = TOOLBOXDIR + LONG + ".py"
+    scanner = MyScanner(input, output, defsoutput)
+    scanner.scan()
+    scanner.close()
+    scanner.gentypetest(SHORT+"typetest.py")
+    print "=== Testing definitions output code ==="
+    execfile(defsoutput, {}, {})
+    print "=== Done scanning and generating, now importing the generated code... ==="
+    exec "import " + SHORT + "support"
+    print "=== Done.  It's up to you to compile it now! ==="
+
+class MyScanner(Scanner):
+
+    def destination(self, type, name, arglist):
+        classname = "Function"
+        listname = "functions"
+        if arglist:
+            t, n, m = arglist[0]
+            if t == "ComponentInstance" and m == "InMode":
+                classname = "Method"
+                listname = "methods"
+        return classname, listname
+
+    def writeinitialdefs(self):
+        self.defsfile.write("def FOUR_CHAR_CODE(x): return x\n")
+        self.defsfile.write("from Carbon.AppleEvents import *\n")
+        self.defsfile.write("kAEUseStandardDispatch = -1\n")
+
+    def makeblacklistnames(self):
+        return [
+                "OSACopyScript",
+                ]
+
+    def makeblacklisttypes(self):
+        return [
+                "OSALocalOrGlobal",
+                "OSACreateAppleEventUPP",
+                "OSAActiveUPP",
+                "AEEventHandlerUPP",
+                "OSASendUPP",
+                ]
+
+    def makerepairinstructions(self):
+        return [
+                ]
+
+if __name__ == "__main__":
+    main()

Added: vendor/Python/current/Mac/Modules/osa/osasupport.py
===================================================================
--- vendor/Python/current/Mac/Modules/osa/osasupport.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/osa/osasupport.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,105 @@
+# This script generates a Python interface for an Apple Macintosh Manager.
+# It uses the "bgen" package to generate C code.
+# The function specifications are generated by scanning the mamager's header file,
+# using the "scantools" package (customized for this particular manager).
+
+import string
+
+# Declarations that change for each manager
+MACHEADERFILE = 'OSA.h'         # The Apple header file
+MODNAME = '_OSA'                                # The name of the module
+
+# The following is *usually* unchanged but may still require tuning
+MODPREFIX = 'OSA'                       # The prefix for module-wide routines
+OBJECTPREFIX = 'OSAObj' # The prefix for object methods
+INPUTFILE = string.lower(MODPREFIX) + 'gen.py' # The file generated by the scanner
+OUTPUTFILE = MODNAME + "module.c"       # The file generated by this program
+
+from macsupport import *
+
+# Create the type objects
+
+includestuff = includestuff + """
+#if PY_VERSION_HEX < 0x02040000
+PyObject *PyMac_GetOSErrException(void);
+#endif
+#include <Carbon/Carbon.h>
+
+#ifdef USE_TOOLBOX_OBJECT_GLUE
+extern PyObject *_OSAObj_New(ComponentInstance);
+extern int _OSAObj_Convert(PyObject *, ComponentInstance *);
+
+#define OSAObj_New _OSAObj_New
+#define OSAObj_Convert _OSAObj_Convert
+#endif
+"""
+
+initstuff = initstuff + """
+/*
+        PyMac_INIT_TOOLBOX_OBJECT_NEW(ComponentInstance, OSAObj_New);
+        PyMac_INIT_TOOLBOX_OBJECT_CONVERT(ComponentInstance, OSAObj_Convert);
+*/
+"""
+
+ComponentInstance = OpaqueByValueType('ComponentInstance', OBJECTPREFIX)
+OSAError = OSErrType("OSAError", "l")
+# OSALocalOrGlobal = Type("OSALocalOrGlobal", "l")
+OSAID = Type("OSAID", "l")
+OSADebugCallFrameRef = Type("OSADebugCallFrameRef", "l")
+OSADebugSessionRef = Type("OSADebugSessionRef", "l")
+OSADebugStepKind = Type("OSADebugStepKind", "l")
+DescType = OSTypeType("DescType")
+AEDesc = OpaqueType('AEDesc')
+AEDesc_ptr = OpaqueType('AEDesc')
+AEAddressDesc = OpaqueType('AEAddressDesc', 'AEDesc')
+AEAddressDesc_ptr = OpaqueType('AEAddressDesc', 'AEDesc')
+AEDescList = OpaqueType('AEDescList', 'AEDesc')
+AEDescList_ptr = OpaqueType('AEDescList', 'AEDesc')
+AERecord = OpaqueType('AERecord', 'AEDesc')
+AERecord_ptr = OpaqueType('AERecord', 'AEDesc')
+AppleEvent = OpaqueType('AppleEvent', 'AEDesc')
+AppleEvent_ptr = OpaqueType('AppleEvent', 'AEDesc')
+
+# NOTE: at the moment OSA.ComponentInstance is not a subclass
+# of Cm.ComponentInstance. If this is a problem it can be fixed.
+class MyObjectDefinition(PEP253Mixin, GlobalObjectDefinition):
+    def outputCheckNewArg(self):
+        Output("""if (itself == NULL) {
+                                PyErr_SetString(OSA_Error,"NULL ComponentInstance");
+                                return NULL;
+                        }""")
+
+    def outputCheckConvertArg(self):
+        Output("""
+                if (CmpInstObj_Convert(v, p_itself))
+                        return 1;
+                PyErr_Clear();
+                """)
+
+
+# Create the generator groups and link them
+module = MacModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff)
+object = MyObjectDefinition('OSAComponentInstance', OBJECTPREFIX,
+                'ComponentInstance')
+module.addobject(object)
+
+# Create the generator classes used to populate the lists
+Function = OSErrWeakLinkFunctionGenerator
+Method = OSErrWeakLinkMethodGenerator
+
+# Test which types we are still missing.
+execfile(string.lower(MODPREFIX) + 'typetest.py')
+
+# Create and populate the lists
+functions = []
+methods = []
+execfile(INPUTFILE)
+
+# add the populated lists to the generator groups
+# (in a different wordl the scan program would generate this)
+for f in functions: module.add(f)
+for f in methods: object.add(f)
+
+# generate output (open the output file as late as possible)
+SetOutputFileName(OUTPUTFILE)
+module.generate()

Added: vendor/Python/current/Mac/Modules/osa/setup.py
===================================================================
--- vendor/Python/current/Mac/Modules/osa/setup.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/osa/setup.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,13 @@
+# This is a temporary setup script to allow distribution of
+# MacPython 2.4 modules for MacPython 2.3.
+
+from distutils.core import Extension, setup
+
+setup(name="OSA", version="0.1",
+        ext_modules=[
+                Extension('_OSA', ['_OSAmodule.c'],
+                extra_link_args=['-framework', 'Carbon'])
+        ],
+        py_modules=['OSA.OSA', 'OSA.OSAconst'],
+        package_dir={'OSA':'../../../Lib/plat-mac/Carbon'}
+        )

Added: vendor/Python/current/Mac/Modules/qd/_Qdmodule.c
===================================================================
--- vendor/Python/current/Mac/Modules/qd/_Qdmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/qd/_Qdmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,7144 @@
+
+/* =========================== Module _Qd =========================== */
+
+#include "Python.h"
+
+
+
+#include "pymactoolbox.h"
+
+/* Macro to test whether a weak-loaded CFM function exists */
+#define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL )  {\
+        PyErr_SetString(PyExc_NotImplementedError, \
+        "Not available in this shared library/OS version"); \
+        return NULL; \
+    }} while(0)
+
+
+#include <Carbon/Carbon.h>
+
+#ifdef USE_TOOLBOX_OBJECT_GLUE
+extern PyObject *_GrafObj_New(GrafPtr);
+extern int _GrafObj_Convert(PyObject *, GrafPtr *);
+extern PyObject *_BMObj_New(BitMapPtr);
+extern int _BMObj_Convert(PyObject *, BitMapPtr *);
+extern PyObject *_QdRGB_New(RGBColorPtr);
+extern int _QdRGB_Convert(PyObject *, RGBColorPtr);
+
+#define GrafObj_New _GrafObj_New
+#define GrafObj_Convert _GrafObj_Convert
+#define BMObj_New _BMObj_New
+#define BMObj_Convert _BMObj_Convert
+#define QdRGB_New _QdRGB_New
+#define QdRGB_Convert _QdRGB_Convert
+#endif
+
+static PyObject *BMObj_NewCopied(BitMapPtr);
+
+/*
+** Parse/generate RGB records
+*/
+PyObject *QdRGB_New(RGBColorPtr itself)
+{
+
+        return Py_BuildValue("lll", (long)itself->red, (long)itself->green, (long)itself->blue);
+}
+
+int QdRGB_Convert(PyObject *v, RGBColorPtr p_itself)
+{
+        long red, green, blue;
+
+        if( !PyArg_ParseTuple(v, "lll", &red, &green, &blue) )
+                return 0;
+        p_itself->red = (unsigned short)red;
+        p_itself->green = (unsigned short)green;
+        p_itself->blue = (unsigned short)blue;
+        return 1;
+}
+
+/*
+** Generate FontInfo records
+*/
+static
+PyObject *QdFI_New(FontInfo *itself)
+{
+
+        return Py_BuildValue("hhhh", itself->ascent, itself->descent,
+                        itself->widMax, itself->leading);
+}
+
+static PyObject *Qd_Error;
+
+/* ---------------------- Object type GrafPort ---------------------- */
+
+PyTypeObject GrafPort_Type;
+
+#define GrafObj_Check(x) ((x)->ob_type == &GrafPort_Type || PyObject_TypeCheck((x), &GrafPort_Type))
+
+typedef struct GrafPortObject {
+	PyObject_HEAD
+	GrafPtr ob_itself;
+} GrafPortObject;
+
+PyObject *GrafObj_New(GrafPtr itself)
+{
+	GrafPortObject *it;
+	if (itself == NULL) return PyMac_Error(resNotFound);
+	it = PyObject_NEW(GrafPortObject, &GrafPort_Type);
+	if (it == NULL) return NULL;
+	it->ob_itself = itself;
+	return (PyObject *)it;
+}
+
+int GrafObj_Convert(PyObject *v, GrafPtr *p_itself)
+{
+#if 1
+	{
+		WindowRef win;
+		if (WinObj_Convert(v, &win) && v) {
+			*p_itself = (GrafPtr)GetWindowPort(win);
+			return 1;
+		}
+		PyErr_Clear();
+	}
+#else
+	if (DlgObj_Check(v)) {
+		DialogRef dlg = (DialogRef)((GrafPortObject *)v)->ob_itself;
+		*p_itself = (GrafPtr)GetWindowPort(GetDialogWindow(dlg));
+		return 1;
+	}
+	if (WinObj_Check(v)) {
+		WindowRef win = (WindowRef)((GrafPortObject *)v)->ob_itself;
+		*p_itself = (GrafPtr)GetWindowPort(win);
+		return 1;
+	}
+#endif
+	if (!GrafObj_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "GrafPort required");
+		return 0;
+	}
+	*p_itself = ((GrafPortObject *)v)->ob_itself;
+	return 1;
+}
+
+static void GrafObj_dealloc(GrafPortObject *self)
+{
+	/* Cleanup of self->ob_itself goes here */
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *GrafObj_MacSetPort(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef MacSetPort
+	PyMac_PRECHECK(MacSetPort);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	MacSetPort(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *GrafObj_QDSwapPort(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	CGrafPtr outOldPort;
+#ifndef QDSwapPort
+	PyMac_PRECHECK(QDSwapPort);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = QDSwapPort(_self->ob_itself,
+	                 &outOldPort);
+	_res = Py_BuildValue("bO&",
+	                     _rv,
+	                     GrafObj_New, outOldPort);
+	return _res;
+}
+
+static PyObject *GrafObj_IsValidPort(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+#ifndef IsValidPort
+	PyMac_PRECHECK(IsValidPort);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = IsValidPort(_self->ob_itself);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *GrafObj_GetPortPixMap(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PixMapHandle _rv;
+#ifndef GetPortPixMap
+	PyMac_PRECHECK(GetPortPixMap);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetPortPixMap(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *GrafObj_GetPortBitMapForCopyBits(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	const BitMap * _rv;
+#ifndef GetPortBitMapForCopyBits
+	PyMac_PRECHECK(GetPortBitMapForCopyBits);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetPortBitMapForCopyBits(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     BMObj_New, _rv);
+	return _res;
+}
+
+static PyObject *GrafObj_GetPortBounds(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect rect;
+#ifndef GetPortBounds
+	PyMac_PRECHECK(GetPortBounds);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	GetPortBounds(_self->ob_itself,
+	              &rect);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildRect, &rect);
+	return _res;
+}
+
+static PyObject *GrafObj_GetPortForeColor(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RGBColor foreColor;
+#ifndef GetPortForeColor
+	PyMac_PRECHECK(GetPortForeColor);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	GetPortForeColor(_self->ob_itself,
+	                 &foreColor);
+	_res = Py_BuildValue("O&",
+	                     QdRGB_New, &foreColor);
+	return _res;
+}
+
+static PyObject *GrafObj_GetPortBackColor(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RGBColor backColor;
+#ifndef GetPortBackColor
+	PyMac_PRECHECK(GetPortBackColor);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	GetPortBackColor(_self->ob_itself,
+	                 &backColor);
+	_res = Py_BuildValue("O&",
+	                     QdRGB_New, &backColor);
+	return _res;
+}
+
+static PyObject *GrafObj_GetPortOpColor(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RGBColor opColor;
+#ifndef GetPortOpColor
+	PyMac_PRECHECK(GetPortOpColor);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	GetPortOpColor(_self->ob_itself,
+	               &opColor);
+	_res = Py_BuildValue("O&",
+	                     QdRGB_New, &opColor);
+	return _res;
+}
+
+static PyObject *GrafObj_GetPortHiliteColor(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RGBColor hiliteColor;
+#ifndef GetPortHiliteColor
+	PyMac_PRECHECK(GetPortHiliteColor);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	GetPortHiliteColor(_self->ob_itself,
+	                   &hiliteColor);
+	_res = Py_BuildValue("O&",
+	                     QdRGB_New, &hiliteColor);
+	return _res;
+}
+
+static PyObject *GrafObj_GetPortTextFont(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short _rv;
+#ifndef GetPortTextFont
+	PyMac_PRECHECK(GetPortTextFont);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetPortTextFont(_self->ob_itself);
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *GrafObj_GetPortTextFace(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Style _rv;
+#ifndef GetPortTextFace
+	PyMac_PRECHECK(GetPortTextFace);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetPortTextFace(_self->ob_itself);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *GrafObj_GetPortTextMode(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short _rv;
+#ifndef GetPortTextMode
+	PyMac_PRECHECK(GetPortTextMode);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetPortTextMode(_self->ob_itself);
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *GrafObj_GetPortTextSize(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short _rv;
+#ifndef GetPortTextSize
+	PyMac_PRECHECK(GetPortTextSize);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetPortTextSize(_self->ob_itself);
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *GrafObj_GetPortChExtra(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short _rv;
+#ifndef GetPortChExtra
+	PyMac_PRECHECK(GetPortChExtra);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetPortChExtra(_self->ob_itself);
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *GrafObj_GetPortFracHPenLocation(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short _rv;
+#ifndef GetPortFracHPenLocation
+	PyMac_PRECHECK(GetPortFracHPenLocation);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetPortFracHPenLocation(_self->ob_itself);
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *GrafObj_GetPortSpExtra(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Fixed _rv;
+#ifndef GetPortSpExtra
+	PyMac_PRECHECK(GetPortSpExtra);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetPortSpExtra(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildFixed, _rv);
+	return _res;
+}
+
+static PyObject *GrafObj_GetPortPenVisibility(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short _rv;
+#ifndef GetPortPenVisibility
+	PyMac_PRECHECK(GetPortPenVisibility);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetPortPenVisibility(_self->ob_itself);
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *GrafObj_GetPortVisibleRegion(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle _rv;
+	RgnHandle visRgn;
+#ifndef GetPortVisibleRegion
+	PyMac_PRECHECK(GetPortVisibleRegion);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &visRgn))
+		return NULL;
+	_rv = GetPortVisibleRegion(_self->ob_itself,
+	                           visRgn);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *GrafObj_GetPortClipRegion(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle _rv;
+	RgnHandle clipRgn;
+#ifndef GetPortClipRegion
+	PyMac_PRECHECK(GetPortClipRegion);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &clipRgn))
+		return NULL;
+	_rv = GetPortClipRegion(_self->ob_itself,
+	                        clipRgn);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *GrafObj_GetPortBackPixPat(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PixPatHandle _rv;
+	PixPatHandle backPattern;
+#ifndef GetPortBackPixPat
+	PyMac_PRECHECK(GetPortBackPixPat);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &backPattern))
+		return NULL;
+	_rv = GetPortBackPixPat(_self->ob_itself,
+	                        backPattern);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *GrafObj_GetPortPenPixPat(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PixPatHandle _rv;
+	PixPatHandle penPattern;
+#ifndef GetPortPenPixPat
+	PyMac_PRECHECK(GetPortPenPixPat);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &penPattern))
+		return NULL;
+	_rv = GetPortPenPixPat(_self->ob_itself,
+	                       penPattern);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *GrafObj_GetPortFillPixPat(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PixPatHandle _rv;
+	PixPatHandle fillPattern;
+#ifndef GetPortFillPixPat
+	PyMac_PRECHECK(GetPortFillPixPat);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &fillPattern))
+		return NULL;
+	_rv = GetPortFillPixPat(_self->ob_itself,
+	                        fillPattern);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *GrafObj_GetPortPenSize(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Point penSize;
+#ifndef GetPortPenSize
+	PyMac_PRECHECK(GetPortPenSize);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetPoint, &penSize))
+		return NULL;
+	GetPortPenSize(_self->ob_itself,
+	               &penSize);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildPoint, penSize);
+	return _res;
+}
+
+static PyObject *GrafObj_GetPortPenMode(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	SInt32 _rv;
+#ifndef GetPortPenMode
+	PyMac_PRECHECK(GetPortPenMode);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetPortPenMode(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *GrafObj_GetPortPenLocation(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Point penLocation;
+#ifndef GetPortPenLocation
+	PyMac_PRECHECK(GetPortPenLocation);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetPoint, &penLocation))
+		return NULL;
+	GetPortPenLocation(_self->ob_itself,
+	                   &penLocation);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildPoint, penLocation);
+	return _res;
+}
+
+static PyObject *GrafObj_IsPortRegionBeingDefined(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+#ifndef IsPortRegionBeingDefined
+	PyMac_PRECHECK(IsPortRegionBeingDefined);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = IsPortRegionBeingDefined(_self->ob_itself);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *GrafObj_IsPortPictureBeingDefined(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+#ifndef IsPortPictureBeingDefined
+	PyMac_PRECHECK(IsPortPictureBeingDefined);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = IsPortPictureBeingDefined(_self->ob_itself);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *GrafObj_IsPortPolyBeingDefined(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+#ifndef IsPortPolyBeingDefined
+	PyMac_PRECHECK(IsPortPolyBeingDefined);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = IsPortPolyBeingDefined(_self->ob_itself);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *GrafObj_IsPortOffscreen(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+#ifndef IsPortOffscreen
+	PyMac_PRECHECK(IsPortOffscreen);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = IsPortOffscreen(_self->ob_itself);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *GrafObj_IsPortColor(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+#ifndef IsPortColor
+	PyMac_PRECHECK(IsPortColor);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = IsPortColor(_self->ob_itself);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *GrafObj_IsPortVisibleRegionEmpty(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+#ifndef IsPortVisibleRegionEmpty
+	PyMac_PRECHECK(IsPortVisibleRegionEmpty);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = IsPortVisibleRegionEmpty(_self->ob_itself);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *GrafObj_IsPortClipRegionEmpty(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+#ifndef IsPortClipRegionEmpty
+	PyMac_PRECHECK(IsPortClipRegionEmpty);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = IsPortClipRegionEmpty(_self->ob_itself);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *GrafObj_SectRegionWithPortClipRegion(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle ioRegion;
+#ifndef SectRegionWithPortClipRegion
+	PyMac_PRECHECK(SectRegionWithPortClipRegion);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &ioRegion))
+		return NULL;
+	SectRegionWithPortClipRegion(_self->ob_itself,
+	                             ioRegion);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *GrafObj_SectRegionWithPortVisibleRegion(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle ioRegion;
+#ifndef SectRegionWithPortVisibleRegion
+	PyMac_PRECHECK(SectRegionWithPortVisibleRegion);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &ioRegion))
+		return NULL;
+	SectRegionWithPortVisibleRegion(_self->ob_itself,
+	                                ioRegion);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *GrafObj_SwapPortPicSaveHandle(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Handle _rv;
+	Handle inPicSaveHdl;
+#ifndef SwapPortPicSaveHandle
+	PyMac_PRECHECK(SwapPortPicSaveHandle);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &inPicSaveHdl))
+		return NULL;
+	_rv = SwapPortPicSaveHandle(_self->ob_itself,
+	                            inPicSaveHdl);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *GrafObj_SwapPortPolySaveHandle(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Handle _rv;
+	Handle inPolySaveHdl;
+#ifndef SwapPortPolySaveHandle
+	PyMac_PRECHECK(SwapPortPolySaveHandle);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &inPolySaveHdl))
+		return NULL;
+	_rv = SwapPortPolySaveHandle(_self->ob_itself,
+	                             inPolySaveHdl);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *GrafObj_SwapPortRegionSaveHandle(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Handle _rv;
+	Handle inRegionSaveHdl;
+#ifndef SwapPortRegionSaveHandle
+	PyMac_PRECHECK(SwapPortRegionSaveHandle);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &inRegionSaveHdl))
+		return NULL;
+	_rv = SwapPortRegionSaveHandle(_self->ob_itself,
+	                               inRegionSaveHdl);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *GrafObj_SetPortBounds(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect rect;
+#ifndef SetPortBounds
+	PyMac_PRECHECK(SetPortBounds);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetRect, &rect))
+		return NULL;
+	SetPortBounds(_self->ob_itself,
+	              &rect);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *GrafObj_SetPortOpColor(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RGBColor opColor;
+#ifndef SetPortOpColor
+	PyMac_PRECHECK(SetPortOpColor);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      QdRGB_Convert, &opColor))
+		return NULL;
+	SetPortOpColor(_self->ob_itself,
+	               &opColor);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *GrafObj_SetPortTextFont(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short txFont;
+#ifndef SetPortTextFont
+	PyMac_PRECHECK(SetPortTextFont);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &txFont))
+		return NULL;
+	SetPortTextFont(_self->ob_itself,
+	                txFont);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *GrafObj_SetPortTextSize(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short txSize;
+#ifndef SetPortTextSize
+	PyMac_PRECHECK(SetPortTextSize);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &txSize))
+		return NULL;
+	SetPortTextSize(_self->ob_itself,
+	                txSize);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *GrafObj_SetPortTextFace(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	StyleParameter face;
+#ifndef SetPortTextFace
+	PyMac_PRECHECK(SetPortTextFace);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &face))
+		return NULL;
+	SetPortTextFace(_self->ob_itself,
+	                face);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *GrafObj_SetPortTextMode(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short mode;
+#ifndef SetPortTextMode
+	PyMac_PRECHECK(SetPortTextMode);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &mode))
+		return NULL;
+	SetPortTextMode(_self->ob_itself,
+	                mode);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *GrafObj_SetPortVisibleRegion(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle visRgn;
+#ifndef SetPortVisibleRegion
+	PyMac_PRECHECK(SetPortVisibleRegion);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &visRgn))
+		return NULL;
+	SetPortVisibleRegion(_self->ob_itself,
+	                     visRgn);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *GrafObj_SetPortClipRegion(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle clipRgn;
+#ifndef SetPortClipRegion
+	PyMac_PRECHECK(SetPortClipRegion);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &clipRgn))
+		return NULL;
+	SetPortClipRegion(_self->ob_itself,
+	                  clipRgn);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *GrafObj_SetPortPenPixPat(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PixPatHandle penPattern;
+#ifndef SetPortPenPixPat
+	PyMac_PRECHECK(SetPortPenPixPat);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &penPattern))
+		return NULL;
+	SetPortPenPixPat(_self->ob_itself,
+	                 penPattern);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *GrafObj_SetPortFillPixPat(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PixPatHandle penPattern;
+#ifndef SetPortFillPixPat
+	PyMac_PRECHECK(SetPortFillPixPat);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &penPattern))
+		return NULL;
+	SetPortFillPixPat(_self->ob_itself,
+	                  penPattern);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *GrafObj_SetPortBackPixPat(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PixPatHandle backPattern;
+#ifndef SetPortBackPixPat
+	PyMac_PRECHECK(SetPortBackPixPat);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &backPattern))
+		return NULL;
+	SetPortBackPixPat(_self->ob_itself,
+	                  backPattern);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *GrafObj_SetPortPenSize(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Point penSize;
+#ifndef SetPortPenSize
+	PyMac_PRECHECK(SetPortPenSize);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetPoint, &penSize))
+		return NULL;
+	SetPortPenSize(_self->ob_itself,
+	               penSize);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *GrafObj_SetPortPenMode(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	SInt32 penMode;
+#ifndef SetPortPenMode
+	PyMac_PRECHECK(SetPortPenMode);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &penMode))
+		return NULL;
+	SetPortPenMode(_self->ob_itself,
+	               penMode);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *GrafObj_SetPortFracHPenLocation(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short pnLocHFrac;
+#ifndef SetPortFracHPenLocation
+	PyMac_PRECHECK(SetPortFracHPenLocation);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &pnLocHFrac))
+		return NULL;
+	SetPortFracHPenLocation(_self->ob_itself,
+	                        pnLocHFrac);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *GrafObj_DisposePort(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef DisposePort
+	PyMac_PRECHECK(DisposePort);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	DisposePort(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *GrafObj_QDLocalToGlobalPoint(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Point point;
+#ifndef QDLocalToGlobalPoint
+	PyMac_PRECHECK(QDLocalToGlobalPoint);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetPoint, &point))
+		return NULL;
+	QDLocalToGlobalPoint(_self->ob_itself,
+	                     &point);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildPoint, point);
+	return _res;
+}
+
+static PyObject *GrafObj_QDGlobalToLocalPoint(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Point point;
+#ifndef QDGlobalToLocalPoint
+	PyMac_PRECHECK(QDGlobalToLocalPoint);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetPoint, &point))
+		return NULL;
+	QDGlobalToLocalPoint(_self->ob_itself,
+	                     &point);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildPoint, point);
+	return _res;
+}
+
+static PyObject *GrafObj_QDLocalToGlobalRect(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect bounds;
+#ifndef QDLocalToGlobalRect
+	PyMac_PRECHECK(QDLocalToGlobalRect);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	QDLocalToGlobalRect(_self->ob_itself,
+	                    &bounds);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildRect, &bounds);
+	return _res;
+}
+
+static PyObject *GrafObj_QDGlobalToLocalRect(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect bounds;
+#ifndef QDGlobalToLocalRect
+	PyMac_PRECHECK(QDGlobalToLocalRect);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	QDGlobalToLocalRect(_self->ob_itself,
+	                    &bounds);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildRect, &bounds);
+	return _res;
+}
+
+static PyObject *GrafObj_QDLocalToGlobalRegion(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle _rv;
+	RgnHandle region;
+#ifndef QDLocalToGlobalRegion
+	PyMac_PRECHECK(QDLocalToGlobalRegion);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &region))
+		return NULL;
+	_rv = QDLocalToGlobalRegion(_self->ob_itself,
+	                            region);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *GrafObj_QDGlobalToLocalRegion(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle _rv;
+	RgnHandle region;
+#ifndef QDGlobalToLocalRegion
+	PyMac_PRECHECK(QDGlobalToLocalRegion);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &region))
+		return NULL;
+	_rv = QDGlobalToLocalRegion(_self->ob_itself,
+	                            region);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *GrafObj_QDIsPortBuffered(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+#ifndef QDIsPortBuffered
+	PyMac_PRECHECK(QDIsPortBuffered);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = QDIsPortBuffered(_self->ob_itself);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *GrafObj_QDIsPortBufferDirty(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+#ifndef QDIsPortBufferDirty
+	PyMac_PRECHECK(QDIsPortBufferDirty);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = QDIsPortBufferDirty(_self->ob_itself);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *GrafObj_QDFlushPortBuffer(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle region;
+#ifndef QDFlushPortBuffer
+	PyMac_PRECHECK(QDFlushPortBuffer);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      OptResObj_Convert, &region))
+		return NULL;
+	QDFlushPortBuffer(_self->ob_itself,
+	                  region);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *GrafObj_QDGetDirtyRegion(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	RgnHandle rgn;
+#ifndef QDGetDirtyRegion
+	PyMac_PRECHECK(QDGetDirtyRegion);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &rgn))
+		return NULL;
+	_err = QDGetDirtyRegion(_self->ob_itself,
+	                        rgn);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *GrafObj_QDSetDirtyRegion(GrafPortObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	RgnHandle rgn;
+#ifndef QDSetDirtyRegion
+	PyMac_PRECHECK(QDSetDirtyRegion);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &rgn))
+		return NULL;
+	_err = QDSetDirtyRegion(_self->ob_itself,
+	                        rgn);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyMethodDef GrafObj_methods[] = {
+	{"MacSetPort", (PyCFunction)GrafObj_MacSetPort, 1,
+	 PyDoc_STR("() -> None")},
+	{"QDSwapPort", (PyCFunction)GrafObj_QDSwapPort, 1,
+	 PyDoc_STR("() -> (Boolean _rv, CGrafPtr outOldPort)")},
+	{"IsValidPort", (PyCFunction)GrafObj_IsValidPort, 1,
+	 PyDoc_STR("() -> (Boolean _rv)")},
+	{"GetPortPixMap", (PyCFunction)GrafObj_GetPortPixMap, 1,
+	 PyDoc_STR("() -> (PixMapHandle _rv)")},
+	{"GetPortBitMapForCopyBits", (PyCFunction)GrafObj_GetPortBitMapForCopyBits, 1,
+	 PyDoc_STR("() -> (const BitMap * _rv)")},
+	{"GetPortBounds", (PyCFunction)GrafObj_GetPortBounds, 1,
+	 PyDoc_STR("() -> (Rect rect)")},
+	{"GetPortForeColor", (PyCFunction)GrafObj_GetPortForeColor, 1,
+	 PyDoc_STR("() -> (RGBColor foreColor)")},
+	{"GetPortBackColor", (PyCFunction)GrafObj_GetPortBackColor, 1,
+	 PyDoc_STR("() -> (RGBColor backColor)")},
+	{"GetPortOpColor", (PyCFunction)GrafObj_GetPortOpColor, 1,
+	 PyDoc_STR("() -> (RGBColor opColor)")},
+	{"GetPortHiliteColor", (PyCFunction)GrafObj_GetPortHiliteColor, 1,
+	 PyDoc_STR("() -> (RGBColor hiliteColor)")},
+	{"GetPortTextFont", (PyCFunction)GrafObj_GetPortTextFont, 1,
+	 PyDoc_STR("() -> (short _rv)")},
+	{"GetPortTextFace", (PyCFunction)GrafObj_GetPortTextFace, 1,
+	 PyDoc_STR("() -> (Style _rv)")},
+	{"GetPortTextMode", (PyCFunction)GrafObj_GetPortTextMode, 1,
+	 PyDoc_STR("() -> (short _rv)")},
+	{"GetPortTextSize", (PyCFunction)GrafObj_GetPortTextSize, 1,
+	 PyDoc_STR("() -> (short _rv)")},
+	{"GetPortChExtra", (PyCFunction)GrafObj_GetPortChExtra, 1,
+	 PyDoc_STR("() -> (short _rv)")},
+	{"GetPortFracHPenLocation", (PyCFunction)GrafObj_GetPortFracHPenLocation, 1,
+	 PyDoc_STR("() -> (short _rv)")},
+	{"GetPortSpExtra", (PyCFunction)GrafObj_GetPortSpExtra, 1,
+	 PyDoc_STR("() -> (Fixed _rv)")},
+	{"GetPortPenVisibility", (PyCFunction)GrafObj_GetPortPenVisibility, 1,
+	 PyDoc_STR("() -> (short _rv)")},
+	{"GetPortVisibleRegion", (PyCFunction)GrafObj_GetPortVisibleRegion, 1,
+	 PyDoc_STR("(RgnHandle visRgn) -> (RgnHandle _rv)")},
+	{"GetPortClipRegion", (PyCFunction)GrafObj_GetPortClipRegion, 1,
+	 PyDoc_STR("(RgnHandle clipRgn) -> (RgnHandle _rv)")},
+	{"GetPortBackPixPat", (PyCFunction)GrafObj_GetPortBackPixPat, 1,
+	 PyDoc_STR("(PixPatHandle backPattern) -> (PixPatHandle _rv)")},
+	{"GetPortPenPixPat", (PyCFunction)GrafObj_GetPortPenPixPat, 1,
+	 PyDoc_STR("(PixPatHandle penPattern) -> (PixPatHandle _rv)")},
+	{"GetPortFillPixPat", (PyCFunction)GrafObj_GetPortFillPixPat, 1,
+	 PyDoc_STR("(PixPatHandle fillPattern) -> (PixPatHandle _rv)")},
+	{"GetPortPenSize", (PyCFunction)GrafObj_GetPortPenSize, 1,
+	 PyDoc_STR("(Point penSize) -> (Point penSize)")},
+	{"GetPortPenMode", (PyCFunction)GrafObj_GetPortPenMode, 1,
+	 PyDoc_STR("() -> (SInt32 _rv)")},
+	{"GetPortPenLocation", (PyCFunction)GrafObj_GetPortPenLocation, 1,
+	 PyDoc_STR("(Point penLocation) -> (Point penLocation)")},
+	{"IsPortRegionBeingDefined", (PyCFunction)GrafObj_IsPortRegionBeingDefined, 1,
+	 PyDoc_STR("() -> (Boolean _rv)")},
+	{"IsPortPictureBeingDefined", (PyCFunction)GrafObj_IsPortPictureBeingDefined, 1,
+	 PyDoc_STR("() -> (Boolean _rv)")},
+	{"IsPortPolyBeingDefined", (PyCFunction)GrafObj_IsPortPolyBeingDefined, 1,
+	 PyDoc_STR("() -> (Boolean _rv)")},
+	{"IsPortOffscreen", (PyCFunction)GrafObj_IsPortOffscreen, 1,
+	 PyDoc_STR("() -> (Boolean _rv)")},
+	{"IsPortColor", (PyCFunction)GrafObj_IsPortColor, 1,
+	 PyDoc_STR("() -> (Boolean _rv)")},
+	{"IsPortVisibleRegionEmpty", (PyCFunction)GrafObj_IsPortVisibleRegionEmpty, 1,
+	 PyDoc_STR("() -> (Boolean _rv)")},
+	{"IsPortClipRegionEmpty", (PyCFunction)GrafObj_IsPortClipRegionEmpty, 1,
+	 PyDoc_STR("() -> (Boolean _rv)")},
+	{"SectRegionWithPortClipRegion", (PyCFunction)GrafObj_SectRegionWithPortClipRegion, 1,
+	 PyDoc_STR("(RgnHandle ioRegion) -> None")},
+	{"SectRegionWithPortVisibleRegion", (PyCFunction)GrafObj_SectRegionWithPortVisibleRegion, 1,
+	 PyDoc_STR("(RgnHandle ioRegion) -> None")},
+	{"SwapPortPicSaveHandle", (PyCFunction)GrafObj_SwapPortPicSaveHandle, 1,
+	 PyDoc_STR("(Handle inPicSaveHdl) -> (Handle _rv)")},
+	{"SwapPortPolySaveHandle", (PyCFunction)GrafObj_SwapPortPolySaveHandle, 1,
+	 PyDoc_STR("(Handle inPolySaveHdl) -> (Handle _rv)")},
+	{"SwapPortRegionSaveHandle", (PyCFunction)GrafObj_SwapPortRegionSaveHandle, 1,
+	 PyDoc_STR("(Handle inRegionSaveHdl) -> (Handle _rv)")},
+	{"SetPortBounds", (PyCFunction)GrafObj_SetPortBounds, 1,
+	 PyDoc_STR("(Rect rect) -> None")},
+	{"SetPortOpColor", (PyCFunction)GrafObj_SetPortOpColor, 1,
+	 PyDoc_STR("(RGBColor opColor) -> None")},
+	{"SetPortTextFont", (PyCFunction)GrafObj_SetPortTextFont, 1,
+	 PyDoc_STR("(short txFont) -> None")},
+	{"SetPortTextSize", (PyCFunction)GrafObj_SetPortTextSize, 1,
+	 PyDoc_STR("(short txSize) -> None")},
+	{"SetPortTextFace", (PyCFunction)GrafObj_SetPortTextFace, 1,
+	 PyDoc_STR("(StyleParameter face) -> None")},
+	{"SetPortTextMode", (PyCFunction)GrafObj_SetPortTextMode, 1,
+	 PyDoc_STR("(short mode) -> None")},
+	{"SetPortVisibleRegion", (PyCFunction)GrafObj_SetPortVisibleRegion, 1,
+	 PyDoc_STR("(RgnHandle visRgn) -> None")},
+	{"SetPortClipRegion", (PyCFunction)GrafObj_SetPortClipRegion, 1,
+	 PyDoc_STR("(RgnHandle clipRgn) -> None")},
+	{"SetPortPenPixPat", (PyCFunction)GrafObj_SetPortPenPixPat, 1,
+	 PyDoc_STR("(PixPatHandle penPattern) -> None")},
+	{"SetPortFillPixPat", (PyCFunction)GrafObj_SetPortFillPixPat, 1,
+	 PyDoc_STR("(PixPatHandle penPattern) -> None")},
+	{"SetPortBackPixPat", (PyCFunction)GrafObj_SetPortBackPixPat, 1,
+	 PyDoc_STR("(PixPatHandle backPattern) -> None")},
+	{"SetPortPenSize", (PyCFunction)GrafObj_SetPortPenSize, 1,
+	 PyDoc_STR("(Point penSize) -> None")},
+	{"SetPortPenMode", (PyCFunction)GrafObj_SetPortPenMode, 1,
+	 PyDoc_STR("(SInt32 penMode) -> None")},
+	{"SetPortFracHPenLocation", (PyCFunction)GrafObj_SetPortFracHPenLocation, 1,
+	 PyDoc_STR("(short pnLocHFrac) -> None")},
+	{"DisposePort", (PyCFunction)GrafObj_DisposePort, 1,
+	 PyDoc_STR("() -> None")},
+	{"QDLocalToGlobalPoint", (PyCFunction)GrafObj_QDLocalToGlobalPoint, 1,
+	 PyDoc_STR("(Point point) -> (Point point)")},
+	{"QDGlobalToLocalPoint", (PyCFunction)GrafObj_QDGlobalToLocalPoint, 1,
+	 PyDoc_STR("(Point point) -> (Point point)")},
+	{"QDLocalToGlobalRect", (PyCFunction)GrafObj_QDLocalToGlobalRect, 1,
+	 PyDoc_STR("() -> (Rect bounds)")},
+	{"QDGlobalToLocalRect", (PyCFunction)GrafObj_QDGlobalToLocalRect, 1,
+	 PyDoc_STR("() -> (Rect bounds)")},
+	{"QDLocalToGlobalRegion", (PyCFunction)GrafObj_QDLocalToGlobalRegion, 1,
+	 PyDoc_STR("(RgnHandle region) -> (RgnHandle _rv)")},
+	{"QDGlobalToLocalRegion", (PyCFunction)GrafObj_QDGlobalToLocalRegion, 1,
+	 PyDoc_STR("(RgnHandle region) -> (RgnHandle _rv)")},
+	{"QDIsPortBuffered", (PyCFunction)GrafObj_QDIsPortBuffered, 1,
+	 PyDoc_STR("() -> (Boolean _rv)")},
+	{"QDIsPortBufferDirty", (PyCFunction)GrafObj_QDIsPortBufferDirty, 1,
+	 PyDoc_STR("() -> (Boolean _rv)")},
+	{"QDFlushPortBuffer", (PyCFunction)GrafObj_QDFlushPortBuffer, 1,
+	 PyDoc_STR("(RgnHandle region) -> None")},
+	{"QDGetDirtyRegion", (PyCFunction)GrafObj_QDGetDirtyRegion, 1,
+	 PyDoc_STR("(RgnHandle rgn) -> None")},
+	{"QDSetDirtyRegion", (PyCFunction)GrafObj_QDSetDirtyRegion, 1,
+	 PyDoc_STR("(RgnHandle rgn) -> None")},
+	{NULL, NULL, 0}
+};
+
+static PyObject *GrafObj_get_visRgn(GrafPortObject *self, void *closure)
+{
+	RgnHandle h=NewRgn(); /* XXXX wrong dispose routine */
+	            return Py_BuildValue("O&", ResObj_New, (Handle)GetPortVisibleRegion(self->ob_itself, h));
+	            
+}
+
+#define GrafObj_set_visRgn NULL
+
+static PyObject *GrafObj_get_clipRgn(GrafPortObject *self, void *closure)
+{
+	RgnHandle h=NewRgn(); /* XXXX wrong dispose routine */
+	            return Py_BuildValue("O&", ResObj_New, (Handle)GetPortClipRegion(self->ob_itself, h));
+	            
+}
+
+#define GrafObj_set_clipRgn NULL
+
+static PyGetSetDef GrafObj_getsetlist[] = {
+	{"visRgn", (getter)GrafObj_get_visRgn, (setter)GrafObj_set_visRgn, "Convenience attribute: return a copy of the visible region"},
+	{"clipRgn", (getter)GrafObj_get_clipRgn, (setter)GrafObj_set_clipRgn, "Convenience attribute: return a copy of the clipping region"},
+	{NULL, NULL, NULL, NULL},
+};
+
+
+#define GrafObj_compare NULL
+
+#define GrafObj_repr NULL
+
+#define GrafObj_hash NULL
+#define GrafObj_tp_init 0
+
+#define GrafObj_tp_alloc PyType_GenericAlloc
+
+static PyObject *GrafObj_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *_self;
+	GrafPtr itself;
+	char *kw[] = {"itself", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, GrafObj_Convert, &itself)) return NULL;
+	if ((_self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	((GrafPortObject *)_self)->ob_itself = itself;
+	return _self;
+}
+
+#define GrafObj_tp_free PyObject_Del
+
+
+PyTypeObject GrafPort_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"_Qd.GrafPort", /*tp_name*/
+	sizeof(GrafPortObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) GrafObj_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) GrafObj_compare, /*tp_compare*/
+	(reprfunc) GrafObj_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) GrafObj_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	GrafObj_methods, /* tp_methods */
+	0, /*tp_members*/
+	GrafObj_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	GrafObj_tp_init, /* tp_init */
+	GrafObj_tp_alloc, /* tp_alloc */
+	GrafObj_tp_new, /* tp_new */
+	GrafObj_tp_free, /* tp_free */
+};
+
+/* -------------------- End object type GrafPort -------------------- */
+
+
+/* ----------------------- Object type BitMap ----------------------- */
+
+PyTypeObject BitMap_Type;
+
+#define BMObj_Check(x) ((x)->ob_type == &BitMap_Type || PyObject_TypeCheck((x), &BitMap_Type))
+
+typedef struct BitMapObject {
+	PyObject_HEAD
+	BitMapPtr ob_itself;
+	PyObject *referred_object;
+	BitMap *referred_bitmap;
+} BitMapObject;
+
+PyObject *BMObj_New(BitMapPtr itself)
+{
+	BitMapObject *it;
+	if (itself == NULL) return PyMac_Error(resNotFound);
+	it = PyObject_NEW(BitMapObject, &BitMap_Type);
+	if (it == NULL) return NULL;
+	it->ob_itself = itself;
+	it->referred_object = NULL;
+	it->referred_bitmap = NULL;
+	return (PyObject *)it;
+}
+
+int BMObj_Convert(PyObject *v, BitMapPtr *p_itself)
+{
+	if (!BMObj_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "BitMap required");
+		return 0;
+	}
+	*p_itself = ((BitMapObject *)v)->ob_itself;
+	return 1;
+}
+
+static void BMObj_dealloc(BitMapObject *self)
+{
+	Py_XDECREF(self->referred_object);
+	if (self->referred_bitmap) free(self->referred_bitmap);
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *BMObj_getdata(BitMapObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+
+	int from, length;
+	char *cp;
+
+	if ( !PyArg_ParseTuple(_args, "ii", &from, &length) )
+	        return NULL;
+	cp = _self->ob_itself->baseAddr+from;
+	_res = PyString_FromStringAndSize(cp, length);
+	return _res;
+
+}
+
+static PyObject *BMObj_putdata(BitMapObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+
+	int from, length;
+	char *cp, *icp;
+
+	if ( !PyArg_ParseTuple(_args, "is#", &from, &icp, &length) )
+	        return NULL;
+	cp = _self->ob_itself->baseAddr+from;
+	memcpy(cp, icp, length);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+
+}
+
+static PyMethodDef BMObj_methods[] = {
+	{"getdata", (PyCFunction)BMObj_getdata, 1,
+	 PyDoc_STR("(int start, int size) -> string. Return bytes from the bitmap")},
+	{"putdata", (PyCFunction)BMObj_putdata, 1,
+	 PyDoc_STR("(int start, string data). Store bytes into the bitmap")},
+	{NULL, NULL, 0}
+};
+
+static PyObject *BMObj_get_baseAddr(BitMapObject *self, void *closure)
+{
+	return PyInt_FromLong((long)self->ob_itself->baseAddr);
+}
+
+#define BMObj_set_baseAddr NULL
+
+static PyObject *BMObj_get_rowBytes(BitMapObject *self, void *closure)
+{
+	return PyInt_FromLong((long)self->ob_itself->rowBytes);
+}
+
+#define BMObj_set_rowBytes NULL
+
+static PyObject *BMObj_get_bounds(BitMapObject *self, void *closure)
+{
+	return Py_BuildValue("O&", PyMac_BuildRect, &self->ob_itself->bounds);
+}
+
+#define BMObj_set_bounds NULL
+
+static PyObject *BMObj_get_bitmap_data(BitMapObject *self, void *closure)
+{
+	return PyString_FromStringAndSize((char *)self->ob_itself, sizeof(BitMap));
+}
+
+#define BMObj_set_bitmap_data NULL
+
+static PyObject *BMObj_get_pixmap_data(BitMapObject *self, void *closure)
+{
+	return PyString_FromStringAndSize((char *)self->ob_itself, sizeof(PixMap));
+}
+
+#define BMObj_set_pixmap_data NULL
+
+static PyGetSetDef BMObj_getsetlist[] = {
+	{"baseAddr", (getter)BMObj_get_baseAddr, (setter)BMObj_set_baseAddr, NULL},
+	{"rowBytes", (getter)BMObj_get_rowBytes, (setter)BMObj_set_rowBytes, NULL},
+	{"bounds", (getter)BMObj_get_bounds, (setter)BMObj_set_bounds, NULL},
+	{"bitmap_data", (getter)BMObj_get_bitmap_data, (setter)BMObj_set_bitmap_data, NULL},
+	{"pixmap_data", (getter)BMObj_get_pixmap_data, (setter)BMObj_set_pixmap_data, NULL},
+	{NULL, NULL, NULL, NULL},
+};
+
+
+#define BMObj_compare NULL
+
+#define BMObj_repr NULL
+
+#define BMObj_hash NULL
+#define BMObj_tp_init 0
+
+#define BMObj_tp_alloc PyType_GenericAlloc
+
+static PyObject *BMObj_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *_self;
+	BitMapPtr itself;
+	char *kw[] = {"itself", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, BMObj_Convert, &itself)) return NULL;
+	if ((_self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	((BitMapObject *)_self)->ob_itself = itself;
+	return _self;
+}
+
+#define BMObj_tp_free PyObject_Del
+
+
+PyTypeObject BitMap_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"_Qd.BitMap", /*tp_name*/
+	sizeof(BitMapObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) BMObj_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) BMObj_compare, /*tp_compare*/
+	(reprfunc) BMObj_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) BMObj_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	BMObj_methods, /* tp_methods */
+	0, /*tp_members*/
+	BMObj_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	BMObj_tp_init, /* tp_init */
+	BMObj_tp_alloc, /* tp_alloc */
+	BMObj_tp_new, /* tp_new */
+	BMObj_tp_free, /* tp_free */
+};
+
+/* --------------------- End object type BitMap --------------------- */
+
+
+static PyObject *Qd_GetPort(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	GrafPtr port;
+#ifndef GetPort
+	PyMac_PRECHECK(GetPort);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	GetPort(&port);
+	_res = Py_BuildValue("O&",
+	                     GrafObj_New, port);
+	return _res;
+}
+
+static PyObject *Qd_GrafDevice(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short device;
+#ifndef GrafDevice
+	PyMac_PRECHECK(GrafDevice);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &device))
+		return NULL;
+	GrafDevice(device);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_SetPortBits(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	BitMapPtr bm;
+#ifndef SetPortBits
+	PyMac_PRECHECK(SetPortBits);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      BMObj_Convert, &bm))
+		return NULL;
+	SetPortBits(bm);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_PortSize(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short width;
+	short height;
+#ifndef PortSize
+	PyMac_PRECHECK(PortSize);
+#endif
+	if (!PyArg_ParseTuple(_args, "hh",
+	                      &width,
+	                      &height))
+		return NULL;
+	PortSize(width,
+	         height);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_MovePortTo(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short leftGlobal;
+	short topGlobal;
+#ifndef MovePortTo
+	PyMac_PRECHECK(MovePortTo);
+#endif
+	if (!PyArg_ParseTuple(_args, "hh",
+	                      &leftGlobal,
+	                      &topGlobal))
+		return NULL;
+	MovePortTo(leftGlobal,
+	           topGlobal);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_SetOrigin(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short h;
+	short v;
+#ifndef SetOrigin
+	PyMac_PRECHECK(SetOrigin);
+#endif
+	if (!PyArg_ParseTuple(_args, "hh",
+	                      &h,
+	                      &v))
+		return NULL;
+	SetOrigin(h,
+	          v);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_SetClip(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle rgn;
+#ifndef SetClip
+	PyMac_PRECHECK(SetClip);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &rgn))
+		return NULL;
+	SetClip(rgn);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_GetClip(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle rgn;
+#ifndef GetClip
+	PyMac_PRECHECK(GetClip);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &rgn))
+		return NULL;
+	GetClip(rgn);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_ClipRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect r;
+#ifndef ClipRect
+	PyMac_PRECHECK(ClipRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetRect, &r))
+		return NULL;
+	ClipRect(&r);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_BackPat(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Pattern *pat__in__;
+	int pat__in_len__;
+#ifndef BackPat
+	PyMac_PRECHECK(BackPat);
+#endif
+	if (!PyArg_ParseTuple(_args, "s#",
+	                      (char **)&pat__in__, &pat__in_len__))
+		return NULL;
+	if (pat__in_len__ != sizeof(Pattern))
+	{
+		PyErr_SetString(PyExc_TypeError, "buffer length should be sizeof(Pattern)");
+		goto pat__error__;
+	}
+	BackPat(pat__in__);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+ pat__error__: ;
+	return _res;
+}
+
+static PyObject *Qd_InitCursor(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef InitCursor
+	PyMac_PRECHECK(InitCursor);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	InitCursor();
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_MacSetCursor(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Cursor *crsr__in__;
+	int crsr__in_len__;
+#ifndef MacSetCursor
+	PyMac_PRECHECK(MacSetCursor);
+#endif
+	if (!PyArg_ParseTuple(_args, "s#",
+	                      (char **)&crsr__in__, &crsr__in_len__))
+		return NULL;
+	if (crsr__in_len__ != sizeof(Cursor))
+	{
+		PyErr_SetString(PyExc_TypeError, "buffer length should be sizeof(Cursor)");
+		goto crsr__error__;
+	}
+	MacSetCursor(crsr__in__);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+ crsr__error__: ;
+	return _res;
+}
+
+static PyObject *Qd_HideCursor(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef HideCursor
+	PyMac_PRECHECK(HideCursor);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	HideCursor();
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_MacShowCursor(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef MacShowCursor
+	PyMac_PRECHECK(MacShowCursor);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	MacShowCursor();
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_ObscureCursor(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef ObscureCursor
+	PyMac_PRECHECK(ObscureCursor);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	ObscureCursor();
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_HidePen(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef HidePen
+	PyMac_PRECHECK(HidePen);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	HidePen();
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_ShowPen(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef ShowPen
+	PyMac_PRECHECK(ShowPen);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	ShowPen();
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_GetPen(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Point pt;
+#ifndef GetPen
+	PyMac_PRECHECK(GetPen);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	GetPen(&pt);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildPoint, pt);
+	return _res;
+}
+
+static PyObject *Qd_GetPenState(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PenState pnState__out__;
+#ifndef GetPenState
+	PyMac_PRECHECK(GetPenState);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	GetPenState(&pnState__out__);
+	_res = Py_BuildValue("s#",
+	                     (char *)&pnState__out__, (int)sizeof(PenState));
+	return _res;
+}
+
+static PyObject *Qd_SetPenState(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PenState *pnState__in__;
+	int pnState__in_len__;
+#ifndef SetPenState
+	PyMac_PRECHECK(SetPenState);
+#endif
+	if (!PyArg_ParseTuple(_args, "s#",
+	                      (char **)&pnState__in__, &pnState__in_len__))
+		return NULL;
+	if (pnState__in_len__ != sizeof(PenState))
+	{
+		PyErr_SetString(PyExc_TypeError, "buffer length should be sizeof(PenState)");
+		goto pnState__error__;
+	}
+	SetPenState(pnState__in__);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+ pnState__error__: ;
+	return _res;
+}
+
+static PyObject *Qd_PenSize(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short width;
+	short height;
+#ifndef PenSize
+	PyMac_PRECHECK(PenSize);
+#endif
+	if (!PyArg_ParseTuple(_args, "hh",
+	                      &width,
+	                      &height))
+		return NULL;
+	PenSize(width,
+	        height);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_PenMode(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short mode;
+#ifndef PenMode
+	PyMac_PRECHECK(PenMode);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &mode))
+		return NULL;
+	PenMode(mode);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_PenPat(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Pattern *pat__in__;
+	int pat__in_len__;
+#ifndef PenPat
+	PyMac_PRECHECK(PenPat);
+#endif
+	if (!PyArg_ParseTuple(_args, "s#",
+	                      (char **)&pat__in__, &pat__in_len__))
+		return NULL;
+	if (pat__in_len__ != sizeof(Pattern))
+	{
+		PyErr_SetString(PyExc_TypeError, "buffer length should be sizeof(Pattern)");
+		goto pat__error__;
+	}
+	PenPat(pat__in__);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+ pat__error__: ;
+	return _res;
+}
+
+static PyObject *Qd_PenNormal(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef PenNormal
+	PyMac_PRECHECK(PenNormal);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	PenNormal();
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_MoveTo(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short h;
+	short v;
+#ifndef MoveTo
+	PyMac_PRECHECK(MoveTo);
+#endif
+	if (!PyArg_ParseTuple(_args, "hh",
+	                      &h,
+	                      &v))
+		return NULL;
+	MoveTo(h,
+	       v);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_Move(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short dh;
+	short dv;
+#ifndef Move
+	PyMac_PRECHECK(Move);
+#endif
+	if (!PyArg_ParseTuple(_args, "hh",
+	                      &dh,
+	                      &dv))
+		return NULL;
+	Move(dh,
+	     dv);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_MacLineTo(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short h;
+	short v;
+#ifndef MacLineTo
+	PyMac_PRECHECK(MacLineTo);
+#endif
+	if (!PyArg_ParseTuple(_args, "hh",
+	                      &h,
+	                      &v))
+		return NULL;
+	MacLineTo(h,
+	          v);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_Line(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short dh;
+	short dv;
+#ifndef Line
+	PyMac_PRECHECK(Line);
+#endif
+	if (!PyArg_ParseTuple(_args, "hh",
+	                      &dh,
+	                      &dv))
+		return NULL;
+	Line(dh,
+	     dv);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_ForeColor(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long color;
+#ifndef ForeColor
+	PyMac_PRECHECK(ForeColor);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &color))
+		return NULL;
+	ForeColor(color);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_BackColor(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long color;
+#ifndef BackColor
+	PyMac_PRECHECK(BackColor);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &color))
+		return NULL;
+	BackColor(color);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_ColorBit(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short whichBit;
+#ifndef ColorBit
+	PyMac_PRECHECK(ColorBit);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &whichBit))
+		return NULL;
+	ColorBit(whichBit);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_MacSetRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect r;
+	short left;
+	short top;
+	short right;
+	short bottom;
+#ifndef MacSetRect
+	PyMac_PRECHECK(MacSetRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "hhhh",
+	                      &left,
+	                      &top,
+	                      &right,
+	                      &bottom))
+		return NULL;
+	MacSetRect(&r,
+	           left,
+	           top,
+	           right,
+	           bottom);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildRect, &r);
+	return _res;
+}
+
+static PyObject *Qd_MacOffsetRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect r;
+	short dh;
+	short dv;
+#ifndef MacOffsetRect
+	PyMac_PRECHECK(MacOffsetRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hh",
+	                      PyMac_GetRect, &r,
+	                      &dh,
+	                      &dv))
+		return NULL;
+	MacOffsetRect(&r,
+	              dh,
+	              dv);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildRect, &r);
+	return _res;
+}
+
+static PyObject *Qd_MacInsetRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect r;
+	short dh;
+	short dv;
+#ifndef MacInsetRect
+	PyMac_PRECHECK(MacInsetRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hh",
+	                      PyMac_GetRect, &r,
+	                      &dh,
+	                      &dv))
+		return NULL;
+	MacInsetRect(&r,
+	             dh,
+	             dv);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildRect, &r);
+	return _res;
+}
+
+static PyObject *Qd_SectRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	Rect src1;
+	Rect src2;
+	Rect dstRect;
+#ifndef SectRect
+	PyMac_PRECHECK(SectRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetRect, &src1,
+	                      PyMac_GetRect, &src2))
+		return NULL;
+	_rv = SectRect(&src1,
+	               &src2,
+	               &dstRect);
+	_res = Py_BuildValue("bO&",
+	                     _rv,
+	                     PyMac_BuildRect, &dstRect);
+	return _res;
+}
+
+static PyObject *Qd_MacUnionRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect src1;
+	Rect src2;
+	Rect dstRect;
+#ifndef MacUnionRect
+	PyMac_PRECHECK(MacUnionRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetRect, &src1,
+	                      PyMac_GetRect, &src2))
+		return NULL;
+	MacUnionRect(&src1,
+	             &src2,
+	             &dstRect);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildRect, &dstRect);
+	return _res;
+}
+
+static PyObject *Qd_MacEqualRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	Rect rect1;
+	Rect rect2;
+#ifndef MacEqualRect
+	PyMac_PRECHECK(MacEqualRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetRect, &rect1,
+	                      PyMac_GetRect, &rect2))
+		return NULL;
+	_rv = MacEqualRect(&rect1,
+	                   &rect2);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qd_EmptyRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	Rect r;
+#ifndef EmptyRect
+	PyMac_PRECHECK(EmptyRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetRect, &r))
+		return NULL;
+	_rv = EmptyRect(&r);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qd_MacFrameRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect r;
+#ifndef MacFrameRect
+	PyMac_PRECHECK(MacFrameRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetRect, &r))
+		return NULL;
+	MacFrameRect(&r);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_PaintRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect r;
+#ifndef PaintRect
+	PyMac_PRECHECK(PaintRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetRect, &r))
+		return NULL;
+	PaintRect(&r);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_EraseRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect r;
+#ifndef EraseRect
+	PyMac_PRECHECK(EraseRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetRect, &r))
+		return NULL;
+	EraseRect(&r);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_MacInvertRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect r;
+#ifndef MacInvertRect
+	PyMac_PRECHECK(MacInvertRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetRect, &r))
+		return NULL;
+	MacInvertRect(&r);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_MacFillRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect r;
+	Pattern *pat__in__;
+	int pat__in_len__;
+#ifndef MacFillRect
+	PyMac_PRECHECK(MacFillRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&s#",
+	                      PyMac_GetRect, &r,
+	                      (char **)&pat__in__, &pat__in_len__))
+		return NULL;
+	if (pat__in_len__ != sizeof(Pattern))
+	{
+		PyErr_SetString(PyExc_TypeError, "buffer length should be sizeof(Pattern)");
+		goto pat__error__;
+	}
+	MacFillRect(&r,
+	            pat__in__);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+ pat__error__: ;
+	return _res;
+}
+
+static PyObject *Qd_FrameOval(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect r;
+#ifndef FrameOval
+	PyMac_PRECHECK(FrameOval);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetRect, &r))
+		return NULL;
+	FrameOval(&r);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_PaintOval(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect r;
+#ifndef PaintOval
+	PyMac_PRECHECK(PaintOval);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetRect, &r))
+		return NULL;
+	PaintOval(&r);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_EraseOval(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect r;
+#ifndef EraseOval
+	PyMac_PRECHECK(EraseOval);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetRect, &r))
+		return NULL;
+	EraseOval(&r);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_InvertOval(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect r;
+#ifndef InvertOval
+	PyMac_PRECHECK(InvertOval);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetRect, &r))
+		return NULL;
+	InvertOval(&r);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_FillOval(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect r;
+	Pattern *pat__in__;
+	int pat__in_len__;
+#ifndef FillOval
+	PyMac_PRECHECK(FillOval);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&s#",
+	                      PyMac_GetRect, &r,
+	                      (char **)&pat__in__, &pat__in_len__))
+		return NULL;
+	if (pat__in_len__ != sizeof(Pattern))
+	{
+		PyErr_SetString(PyExc_TypeError, "buffer length should be sizeof(Pattern)");
+		goto pat__error__;
+	}
+	FillOval(&r,
+	         pat__in__);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+ pat__error__: ;
+	return _res;
+}
+
+static PyObject *Qd_FrameRoundRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect r;
+	short ovalWidth;
+	short ovalHeight;
+#ifndef FrameRoundRect
+	PyMac_PRECHECK(FrameRoundRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hh",
+	                      PyMac_GetRect, &r,
+	                      &ovalWidth,
+	                      &ovalHeight))
+		return NULL;
+	FrameRoundRect(&r,
+	               ovalWidth,
+	               ovalHeight);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_PaintRoundRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect r;
+	short ovalWidth;
+	short ovalHeight;
+#ifndef PaintRoundRect
+	PyMac_PRECHECK(PaintRoundRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hh",
+	                      PyMac_GetRect, &r,
+	                      &ovalWidth,
+	                      &ovalHeight))
+		return NULL;
+	PaintRoundRect(&r,
+	               ovalWidth,
+	               ovalHeight);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_EraseRoundRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect r;
+	short ovalWidth;
+	short ovalHeight;
+#ifndef EraseRoundRect
+	PyMac_PRECHECK(EraseRoundRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hh",
+	                      PyMac_GetRect, &r,
+	                      &ovalWidth,
+	                      &ovalHeight))
+		return NULL;
+	EraseRoundRect(&r,
+	               ovalWidth,
+	               ovalHeight);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_InvertRoundRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect r;
+	short ovalWidth;
+	short ovalHeight;
+#ifndef InvertRoundRect
+	PyMac_PRECHECK(InvertRoundRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hh",
+	                      PyMac_GetRect, &r,
+	                      &ovalWidth,
+	                      &ovalHeight))
+		return NULL;
+	InvertRoundRect(&r,
+	                ovalWidth,
+	                ovalHeight);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_FillRoundRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect r;
+	short ovalWidth;
+	short ovalHeight;
+	Pattern *pat__in__;
+	int pat__in_len__;
+#ifndef FillRoundRect
+	PyMac_PRECHECK(FillRoundRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hhs#",
+	                      PyMac_GetRect, &r,
+	                      &ovalWidth,
+	                      &ovalHeight,
+	                      (char **)&pat__in__, &pat__in_len__))
+		return NULL;
+	if (pat__in_len__ != sizeof(Pattern))
+	{
+		PyErr_SetString(PyExc_TypeError, "buffer length should be sizeof(Pattern)");
+		goto pat__error__;
+	}
+	FillRoundRect(&r,
+	              ovalWidth,
+	              ovalHeight,
+	              pat__in__);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+ pat__error__: ;
+	return _res;
+}
+
+static PyObject *Qd_FrameArc(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect r;
+	short startAngle;
+	short arcAngle;
+#ifndef FrameArc
+	PyMac_PRECHECK(FrameArc);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hh",
+	                      PyMac_GetRect, &r,
+	                      &startAngle,
+	                      &arcAngle))
+		return NULL;
+	FrameArc(&r,
+	         startAngle,
+	         arcAngle);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_PaintArc(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect r;
+	short startAngle;
+	short arcAngle;
+#ifndef PaintArc
+	PyMac_PRECHECK(PaintArc);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hh",
+	                      PyMac_GetRect, &r,
+	                      &startAngle,
+	                      &arcAngle))
+		return NULL;
+	PaintArc(&r,
+	         startAngle,
+	         arcAngle);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_EraseArc(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect r;
+	short startAngle;
+	short arcAngle;
+#ifndef EraseArc
+	PyMac_PRECHECK(EraseArc);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hh",
+	                      PyMac_GetRect, &r,
+	                      &startAngle,
+	                      &arcAngle))
+		return NULL;
+	EraseArc(&r,
+	         startAngle,
+	         arcAngle);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_InvertArc(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect r;
+	short startAngle;
+	short arcAngle;
+#ifndef InvertArc
+	PyMac_PRECHECK(InvertArc);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hh",
+	                      PyMac_GetRect, &r,
+	                      &startAngle,
+	                      &arcAngle))
+		return NULL;
+	InvertArc(&r,
+	          startAngle,
+	          arcAngle);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_FillArc(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect r;
+	short startAngle;
+	short arcAngle;
+	Pattern *pat__in__;
+	int pat__in_len__;
+#ifndef FillArc
+	PyMac_PRECHECK(FillArc);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hhs#",
+	                      PyMac_GetRect, &r,
+	                      &startAngle,
+	                      &arcAngle,
+	                      (char **)&pat__in__, &pat__in_len__))
+		return NULL;
+	if (pat__in_len__ != sizeof(Pattern))
+	{
+		PyErr_SetString(PyExc_TypeError, "buffer length should be sizeof(Pattern)");
+		goto pat__error__;
+	}
+	FillArc(&r,
+	        startAngle,
+	        arcAngle,
+	        pat__in__);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+ pat__error__: ;
+	return _res;
+}
+
+static PyObject *Qd_NewRgn(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle _rv;
+#ifndef NewRgn
+	PyMac_PRECHECK(NewRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = NewRgn();
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Qd_OpenRgn(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef OpenRgn
+	PyMac_PRECHECK(OpenRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	OpenRgn();
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_CloseRgn(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle dstRgn;
+#ifndef CloseRgn
+	PyMac_PRECHECK(CloseRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &dstRgn))
+		return NULL;
+	CloseRgn(dstRgn);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_BitMapToRegion(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	RgnHandle region;
+	BitMapPtr bMap;
+#ifndef BitMapToRegion
+	PyMac_PRECHECK(BitMapToRegion);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      ResObj_Convert, &region,
+	                      BMObj_Convert, &bMap))
+		return NULL;
+	_err = BitMapToRegion(region,
+	                      bMap);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_RgnToHandle(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle region;
+	Handle flattenedRgnDataHdl;
+#ifndef RgnToHandle
+	PyMac_PRECHECK(RgnToHandle);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      ResObj_Convert, &region,
+	                      ResObj_Convert, &flattenedRgnDataHdl))
+		return NULL;
+	RgnToHandle(region,
+	            flattenedRgnDataHdl);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_DisposeRgn(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle rgn;
+#ifndef DisposeRgn
+	PyMac_PRECHECK(DisposeRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &rgn))
+		return NULL;
+	DisposeRgn(rgn);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_MacCopyRgn(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle srcRgn;
+	RgnHandle dstRgn;
+#ifndef MacCopyRgn
+	PyMac_PRECHECK(MacCopyRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      ResObj_Convert, &srcRgn,
+	                      ResObj_Convert, &dstRgn))
+		return NULL;
+	MacCopyRgn(srcRgn,
+	           dstRgn);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_SetEmptyRgn(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle rgn;
+#ifndef SetEmptyRgn
+	PyMac_PRECHECK(SetEmptyRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &rgn))
+		return NULL;
+	SetEmptyRgn(rgn);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_MacSetRectRgn(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle rgn;
+	short left;
+	short top;
+	short right;
+	short bottom;
+#ifndef MacSetRectRgn
+	PyMac_PRECHECK(MacSetRectRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hhhh",
+	                      ResObj_Convert, &rgn,
+	                      &left,
+	                      &top,
+	                      &right,
+	                      &bottom))
+		return NULL;
+	MacSetRectRgn(rgn,
+	              left,
+	              top,
+	              right,
+	              bottom);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_RectRgn(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle rgn;
+	Rect r;
+#ifndef RectRgn
+	PyMac_PRECHECK(RectRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      ResObj_Convert, &rgn,
+	                      PyMac_GetRect, &r))
+		return NULL;
+	RectRgn(rgn,
+	        &r);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_MacOffsetRgn(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle rgn;
+	short dh;
+	short dv;
+#ifndef MacOffsetRgn
+	PyMac_PRECHECK(MacOffsetRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hh",
+	                      ResObj_Convert, &rgn,
+	                      &dh,
+	                      &dv))
+		return NULL;
+	MacOffsetRgn(rgn,
+	             dh,
+	             dv);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_InsetRgn(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle rgn;
+	short dh;
+	short dv;
+#ifndef InsetRgn
+	PyMac_PRECHECK(InsetRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hh",
+	                      ResObj_Convert, &rgn,
+	                      &dh,
+	                      &dv))
+		return NULL;
+	InsetRgn(rgn,
+	         dh,
+	         dv);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_SectRgn(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle srcRgnA;
+	RgnHandle srcRgnB;
+	RgnHandle dstRgn;
+#ifndef SectRgn
+	PyMac_PRECHECK(SectRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      ResObj_Convert, &srcRgnA,
+	                      ResObj_Convert, &srcRgnB,
+	                      ResObj_Convert, &dstRgn))
+		return NULL;
+	SectRgn(srcRgnA,
+	        srcRgnB,
+	        dstRgn);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_MacUnionRgn(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle srcRgnA;
+	RgnHandle srcRgnB;
+	RgnHandle dstRgn;
+#ifndef MacUnionRgn
+	PyMac_PRECHECK(MacUnionRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      ResObj_Convert, &srcRgnA,
+	                      ResObj_Convert, &srcRgnB,
+	                      ResObj_Convert, &dstRgn))
+		return NULL;
+	MacUnionRgn(srcRgnA,
+	            srcRgnB,
+	            dstRgn);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_DiffRgn(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle srcRgnA;
+	RgnHandle srcRgnB;
+	RgnHandle dstRgn;
+#ifndef DiffRgn
+	PyMac_PRECHECK(DiffRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      ResObj_Convert, &srcRgnA,
+	                      ResObj_Convert, &srcRgnB,
+	                      ResObj_Convert, &dstRgn))
+		return NULL;
+	DiffRgn(srcRgnA,
+	        srcRgnB,
+	        dstRgn);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_MacXorRgn(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle srcRgnA;
+	RgnHandle srcRgnB;
+	RgnHandle dstRgn;
+#ifndef MacXorRgn
+	PyMac_PRECHECK(MacXorRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      ResObj_Convert, &srcRgnA,
+	                      ResObj_Convert, &srcRgnB,
+	                      ResObj_Convert, &dstRgn))
+		return NULL;
+	MacXorRgn(srcRgnA,
+	          srcRgnB,
+	          dstRgn);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_RectInRgn(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	Rect r;
+	RgnHandle rgn;
+#ifndef RectInRgn
+	PyMac_PRECHECK(RectInRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetRect, &r,
+	                      ResObj_Convert, &rgn))
+		return NULL;
+	_rv = RectInRgn(&r,
+	                rgn);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qd_MacEqualRgn(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	RgnHandle rgnA;
+	RgnHandle rgnB;
+#ifndef MacEqualRgn
+	PyMac_PRECHECK(MacEqualRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      ResObj_Convert, &rgnA,
+	                      ResObj_Convert, &rgnB))
+		return NULL;
+	_rv = MacEqualRgn(rgnA,
+	                  rgnB);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qd_EmptyRgn(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	RgnHandle rgn;
+#ifndef EmptyRgn
+	PyMac_PRECHECK(EmptyRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &rgn))
+		return NULL;
+	_rv = EmptyRgn(rgn);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qd_MacFrameRgn(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle rgn;
+#ifndef MacFrameRgn
+	PyMac_PRECHECK(MacFrameRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &rgn))
+		return NULL;
+	MacFrameRgn(rgn);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_MacPaintRgn(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle rgn;
+#ifndef MacPaintRgn
+	PyMac_PRECHECK(MacPaintRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &rgn))
+		return NULL;
+	MacPaintRgn(rgn);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_EraseRgn(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle rgn;
+#ifndef EraseRgn
+	PyMac_PRECHECK(EraseRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &rgn))
+		return NULL;
+	EraseRgn(rgn);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_MacInvertRgn(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle rgn;
+#ifndef MacInvertRgn
+	PyMac_PRECHECK(MacInvertRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &rgn))
+		return NULL;
+	MacInvertRgn(rgn);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_MacFillRgn(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle rgn;
+	Pattern *pat__in__;
+	int pat__in_len__;
+#ifndef MacFillRgn
+	PyMac_PRECHECK(MacFillRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&s#",
+	                      ResObj_Convert, &rgn,
+	                      (char **)&pat__in__, &pat__in_len__))
+		return NULL;
+	if (pat__in_len__ != sizeof(Pattern))
+	{
+		PyErr_SetString(PyExc_TypeError, "buffer length should be sizeof(Pattern)");
+		goto pat__error__;
+	}
+	MacFillRgn(rgn,
+	           pat__in__);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+ pat__error__: ;
+	return _res;
+}
+
+static PyObject *Qd_ScrollRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect r;
+	short dh;
+	short dv;
+	RgnHandle updateRgn;
+#ifndef ScrollRect
+	PyMac_PRECHECK(ScrollRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hhO&",
+	                      PyMac_GetRect, &r,
+	                      &dh,
+	                      &dv,
+	                      ResObj_Convert, &updateRgn))
+		return NULL;
+	ScrollRect(&r,
+	           dh,
+	           dv,
+	           updateRgn);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_CopyBits(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	BitMapPtr srcBits;
+	BitMapPtr dstBits;
+	Rect srcRect;
+	Rect dstRect;
+	short mode;
+	RgnHandle maskRgn;
+#ifndef CopyBits
+	PyMac_PRECHECK(CopyBits);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&O&hO&",
+	                      BMObj_Convert, &srcBits,
+	                      BMObj_Convert, &dstBits,
+	                      PyMac_GetRect, &srcRect,
+	                      PyMac_GetRect, &dstRect,
+	                      &mode,
+	                      OptResObj_Convert, &maskRgn))
+		return NULL;
+	CopyBits(srcBits,
+	         dstBits,
+	         &srcRect,
+	         &dstRect,
+	         mode,
+	         maskRgn);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_CopyMask(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	BitMapPtr srcBits;
+	BitMapPtr maskBits;
+	BitMapPtr dstBits;
+	Rect srcRect;
+	Rect maskRect;
+	Rect dstRect;
+#ifndef CopyMask
+	PyMac_PRECHECK(CopyMask);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&O&O&O&",
+	                      BMObj_Convert, &srcBits,
+	                      BMObj_Convert, &maskBits,
+	                      BMObj_Convert, &dstBits,
+	                      PyMac_GetRect, &srcRect,
+	                      PyMac_GetRect, &maskRect,
+	                      PyMac_GetRect, &dstRect))
+		return NULL;
+	CopyMask(srcBits,
+	         maskBits,
+	         dstBits,
+	         &srcRect,
+	         &maskRect,
+	         &dstRect);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_OpenPicture(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PicHandle _rv;
+	Rect picFrame;
+#ifndef OpenPicture
+	PyMac_PRECHECK(OpenPicture);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetRect, &picFrame))
+		return NULL;
+	_rv = OpenPicture(&picFrame);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Qd_PicComment(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short kind;
+	short dataSize;
+	Handle dataHandle;
+#ifndef PicComment
+	PyMac_PRECHECK(PicComment);
+#endif
+	if (!PyArg_ParseTuple(_args, "hhO&",
+	                      &kind,
+	                      &dataSize,
+	                      ResObj_Convert, &dataHandle))
+		return NULL;
+	PicComment(kind,
+	           dataSize,
+	           dataHandle);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_ClosePicture(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef ClosePicture
+	PyMac_PRECHECK(ClosePicture);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	ClosePicture();
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_DrawPicture(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PicHandle myPicture;
+	Rect dstRect;
+#ifndef DrawPicture
+	PyMac_PRECHECK(DrawPicture);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      ResObj_Convert, &myPicture,
+	                      PyMac_GetRect, &dstRect))
+		return NULL;
+	DrawPicture(myPicture,
+	            &dstRect);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_KillPicture(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PicHandle myPicture;
+#ifndef KillPicture
+	PyMac_PRECHECK(KillPicture);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &myPicture))
+		return NULL;
+	KillPicture(myPicture);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_OpenPoly(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PolyHandle _rv;
+#ifndef OpenPoly
+	PyMac_PRECHECK(OpenPoly);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = OpenPoly();
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Qd_ClosePoly(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef ClosePoly
+	PyMac_PRECHECK(ClosePoly);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	ClosePoly();
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_KillPoly(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PolyHandle poly;
+#ifndef KillPoly
+	PyMac_PRECHECK(KillPoly);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &poly))
+		return NULL;
+	KillPoly(poly);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_OffsetPoly(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PolyHandle poly;
+	short dh;
+	short dv;
+#ifndef OffsetPoly
+	PyMac_PRECHECK(OffsetPoly);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hh",
+	                      ResObj_Convert, &poly,
+	                      &dh,
+	                      &dv))
+		return NULL;
+	OffsetPoly(poly,
+	           dh,
+	           dv);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_FramePoly(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PolyHandle poly;
+#ifndef FramePoly
+	PyMac_PRECHECK(FramePoly);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &poly))
+		return NULL;
+	FramePoly(poly);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_PaintPoly(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PolyHandle poly;
+#ifndef PaintPoly
+	PyMac_PRECHECK(PaintPoly);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &poly))
+		return NULL;
+	PaintPoly(poly);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_ErasePoly(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PolyHandle poly;
+#ifndef ErasePoly
+	PyMac_PRECHECK(ErasePoly);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &poly))
+		return NULL;
+	ErasePoly(poly);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_InvertPoly(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PolyHandle poly;
+#ifndef InvertPoly
+	PyMac_PRECHECK(InvertPoly);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &poly))
+		return NULL;
+	InvertPoly(poly);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_FillPoly(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PolyHandle poly;
+	Pattern *pat__in__;
+	int pat__in_len__;
+#ifndef FillPoly
+	PyMac_PRECHECK(FillPoly);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&s#",
+	                      ResObj_Convert, &poly,
+	                      (char **)&pat__in__, &pat__in_len__))
+		return NULL;
+	if (pat__in_len__ != sizeof(Pattern))
+	{
+		PyErr_SetString(PyExc_TypeError, "buffer length should be sizeof(Pattern)");
+		goto pat__error__;
+	}
+	FillPoly(poly,
+	         pat__in__);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+ pat__error__: ;
+	return _res;
+}
+
+static PyObject *Qd_SetPt(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Point pt;
+	short h;
+	short v;
+#ifndef SetPt
+	PyMac_PRECHECK(SetPt);
+#endif
+	if (!PyArg_ParseTuple(_args, "hh",
+	                      &h,
+	                      &v))
+		return NULL;
+	SetPt(&pt,
+	      h,
+	      v);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildPoint, pt);
+	return _res;
+}
+
+static PyObject *Qd_LocalToGlobal(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Point pt;
+#ifndef LocalToGlobal
+	PyMac_PRECHECK(LocalToGlobal);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetPoint, &pt))
+		return NULL;
+	LocalToGlobal(&pt);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildPoint, pt);
+	return _res;
+}
+
+static PyObject *Qd_GlobalToLocal(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Point pt;
+#ifndef GlobalToLocal
+	PyMac_PRECHECK(GlobalToLocal);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetPoint, &pt))
+		return NULL;
+	GlobalToLocal(&pt);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildPoint, pt);
+	return _res;
+}
+
+static PyObject *Qd_Random(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short _rv;
+#ifndef Random
+	PyMac_PRECHECK(Random);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = Random();
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qd_MacGetPixel(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	short h;
+	short v;
+#ifndef MacGetPixel
+	PyMac_PRECHECK(MacGetPixel);
+#endif
+	if (!PyArg_ParseTuple(_args, "hh",
+	                      &h,
+	                      &v))
+		return NULL;
+	_rv = MacGetPixel(h,
+	                  v);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qd_ScalePt(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Point pt;
+	Rect srcRect;
+	Rect dstRect;
+#ifndef ScalePt
+	PyMac_PRECHECK(ScalePt);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      PyMac_GetPoint, &pt,
+	                      PyMac_GetRect, &srcRect,
+	                      PyMac_GetRect, &dstRect))
+		return NULL;
+	ScalePt(&pt,
+	        &srcRect,
+	        &dstRect);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildPoint, pt);
+	return _res;
+}
+
+static PyObject *Qd_MapPt(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Point pt;
+	Rect srcRect;
+	Rect dstRect;
+#ifndef MapPt
+	PyMac_PRECHECK(MapPt);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      PyMac_GetPoint, &pt,
+	                      PyMac_GetRect, &srcRect,
+	                      PyMac_GetRect, &dstRect))
+		return NULL;
+	MapPt(&pt,
+	      &srcRect,
+	      &dstRect);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildPoint, pt);
+	return _res;
+}
+
+static PyObject *Qd_MapRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect r;
+	Rect srcRect;
+	Rect dstRect;
+#ifndef MapRect
+	PyMac_PRECHECK(MapRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      PyMac_GetRect, &r,
+	                      PyMac_GetRect, &srcRect,
+	                      PyMac_GetRect, &dstRect))
+		return NULL;
+	MapRect(&r,
+	        &srcRect,
+	        &dstRect);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildRect, &r);
+	return _res;
+}
+
+static PyObject *Qd_MapRgn(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle rgn;
+	Rect srcRect;
+	Rect dstRect;
+#ifndef MapRgn
+	PyMac_PRECHECK(MapRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      ResObj_Convert, &rgn,
+	                      PyMac_GetRect, &srcRect,
+	                      PyMac_GetRect, &dstRect))
+		return NULL;
+	MapRgn(rgn,
+	       &srcRect,
+	       &dstRect);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_MapPoly(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PolyHandle poly;
+	Rect srcRect;
+	Rect dstRect;
+#ifndef MapPoly
+	PyMac_PRECHECK(MapPoly);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      ResObj_Convert, &poly,
+	                      PyMac_GetRect, &srcRect,
+	                      PyMac_GetRect, &dstRect))
+		return NULL;
+	MapPoly(poly,
+	        &srcRect,
+	        &dstRect);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_StdBits(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	BitMapPtr srcBits;
+	Rect srcRect;
+	Rect dstRect;
+	short mode;
+	RgnHandle maskRgn;
+#ifndef StdBits
+	PyMac_PRECHECK(StdBits);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&hO&",
+	                      BMObj_Convert, &srcBits,
+	                      PyMac_GetRect, &srcRect,
+	                      PyMac_GetRect, &dstRect,
+	                      &mode,
+	                      OptResObj_Convert, &maskRgn))
+		return NULL;
+	StdBits(srcBits,
+	        &srcRect,
+	        &dstRect,
+	        mode,
+	        maskRgn);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_AddPt(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Point src;
+	Point dst;
+#ifndef AddPt
+	PyMac_PRECHECK(AddPt);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetPoint, &src,
+	                      PyMac_GetPoint, &dst))
+		return NULL;
+	AddPt(src,
+	      &dst);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildPoint, dst);
+	return _res;
+}
+
+static PyObject *Qd_EqualPt(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	Point pt1;
+	Point pt2;
+#ifndef EqualPt
+	PyMac_PRECHECK(EqualPt);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetPoint, &pt1,
+	                      PyMac_GetPoint, &pt2))
+		return NULL;
+	_rv = EqualPt(pt1,
+	              pt2);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qd_MacPtInRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	Point pt;
+	Rect r;
+#ifndef MacPtInRect
+	PyMac_PRECHECK(MacPtInRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetPoint, &pt,
+	                      PyMac_GetRect, &r))
+		return NULL;
+	_rv = MacPtInRect(pt,
+	                  &r);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qd_Pt2Rect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Point pt1;
+	Point pt2;
+	Rect dstRect;
+#ifndef Pt2Rect
+	PyMac_PRECHECK(Pt2Rect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetPoint, &pt1,
+	                      PyMac_GetPoint, &pt2))
+		return NULL;
+	Pt2Rect(pt1,
+	        pt2,
+	        &dstRect);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildRect, &dstRect);
+	return _res;
+}
+
+static PyObject *Qd_PtToAngle(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect r;
+	Point pt;
+	short angle;
+#ifndef PtToAngle
+	PyMac_PRECHECK(PtToAngle);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetRect, &r,
+	                      PyMac_GetPoint, &pt))
+		return NULL;
+	PtToAngle(&r,
+	          pt,
+	          &angle);
+	_res = Py_BuildValue("h",
+	                     angle);
+	return _res;
+}
+
+static PyObject *Qd_SubPt(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Point src;
+	Point dst;
+#ifndef SubPt
+	PyMac_PRECHECK(SubPt);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetPoint, &src,
+	                      PyMac_GetPoint, &dst))
+		return NULL;
+	SubPt(src,
+	      &dst);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildPoint, dst);
+	return _res;
+}
+
+static PyObject *Qd_PtInRgn(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	Point pt;
+	RgnHandle rgn;
+#ifndef PtInRgn
+	PyMac_PRECHECK(PtInRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetPoint, &pt,
+	                      ResObj_Convert, &rgn))
+		return NULL;
+	_rv = PtInRgn(pt,
+	              rgn);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qd_NewPixMap(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PixMapHandle _rv;
+#ifndef NewPixMap
+	PyMac_PRECHECK(NewPixMap);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = NewPixMap();
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Qd_DisposePixMap(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PixMapHandle pm;
+#ifndef DisposePixMap
+	PyMac_PRECHECK(DisposePixMap);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &pm))
+		return NULL;
+	DisposePixMap(pm);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_CopyPixMap(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PixMapHandle srcPM;
+	PixMapHandle dstPM;
+#ifndef CopyPixMap
+	PyMac_PRECHECK(CopyPixMap);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      ResObj_Convert, &srcPM,
+	                      ResObj_Convert, &dstPM))
+		return NULL;
+	CopyPixMap(srcPM,
+	           dstPM);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_NewPixPat(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PixPatHandle _rv;
+#ifndef NewPixPat
+	PyMac_PRECHECK(NewPixPat);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = NewPixPat();
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Qd_DisposePixPat(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PixPatHandle pp;
+#ifndef DisposePixPat
+	PyMac_PRECHECK(DisposePixPat);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &pp))
+		return NULL;
+	DisposePixPat(pp);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_CopyPixPat(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PixPatHandle srcPP;
+	PixPatHandle dstPP;
+#ifndef CopyPixPat
+	PyMac_PRECHECK(CopyPixPat);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      ResObj_Convert, &srcPP,
+	                      ResObj_Convert, &dstPP))
+		return NULL;
+	CopyPixPat(srcPP,
+	           dstPP);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_PenPixPat(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PixPatHandle pp;
+#ifndef PenPixPat
+	PyMac_PRECHECK(PenPixPat);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &pp))
+		return NULL;
+	PenPixPat(pp);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_BackPixPat(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PixPatHandle pp;
+#ifndef BackPixPat
+	PyMac_PRECHECK(BackPixPat);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &pp))
+		return NULL;
+	BackPixPat(pp);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_GetPixPat(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PixPatHandle _rv;
+	short patID;
+#ifndef GetPixPat
+	PyMac_PRECHECK(GetPixPat);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &patID))
+		return NULL;
+	_rv = GetPixPat(patID);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Qd_MakeRGBPat(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PixPatHandle pp;
+	RGBColor myColor;
+#ifndef MakeRGBPat
+	PyMac_PRECHECK(MakeRGBPat);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      ResObj_Convert, &pp,
+	                      QdRGB_Convert, &myColor))
+		return NULL;
+	MakeRGBPat(pp,
+	           &myColor);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_FillCRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect r;
+	PixPatHandle pp;
+#ifndef FillCRect
+	PyMac_PRECHECK(FillCRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetRect, &r,
+	                      ResObj_Convert, &pp))
+		return NULL;
+	FillCRect(&r,
+	          pp);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_FillCOval(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect r;
+	PixPatHandle pp;
+#ifndef FillCOval
+	PyMac_PRECHECK(FillCOval);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetRect, &r,
+	                      ResObj_Convert, &pp))
+		return NULL;
+	FillCOval(&r,
+	          pp);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_FillCRoundRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect r;
+	short ovalWidth;
+	short ovalHeight;
+	PixPatHandle pp;
+#ifndef FillCRoundRect
+	PyMac_PRECHECK(FillCRoundRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hhO&",
+	                      PyMac_GetRect, &r,
+	                      &ovalWidth,
+	                      &ovalHeight,
+	                      ResObj_Convert, &pp))
+		return NULL;
+	FillCRoundRect(&r,
+	               ovalWidth,
+	               ovalHeight,
+	               pp);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_FillCArc(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect r;
+	short startAngle;
+	short arcAngle;
+	PixPatHandle pp;
+#ifndef FillCArc
+	PyMac_PRECHECK(FillCArc);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hhO&",
+	                      PyMac_GetRect, &r,
+	                      &startAngle,
+	                      &arcAngle,
+	                      ResObj_Convert, &pp))
+		return NULL;
+	FillCArc(&r,
+	         startAngle,
+	         arcAngle,
+	         pp);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_FillCRgn(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle rgn;
+	PixPatHandle pp;
+#ifndef FillCRgn
+	PyMac_PRECHECK(FillCRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      ResObj_Convert, &rgn,
+	                      ResObj_Convert, &pp))
+		return NULL;
+	FillCRgn(rgn,
+	         pp);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_FillCPoly(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PolyHandle poly;
+	PixPatHandle pp;
+#ifndef FillCPoly
+	PyMac_PRECHECK(FillCPoly);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      ResObj_Convert, &poly,
+	                      ResObj_Convert, &pp))
+		return NULL;
+	FillCPoly(poly,
+	          pp);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_RGBForeColor(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RGBColor color;
+#ifndef RGBForeColor
+	PyMac_PRECHECK(RGBForeColor);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      QdRGB_Convert, &color))
+		return NULL;
+	RGBForeColor(&color);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_RGBBackColor(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RGBColor color;
+#ifndef RGBBackColor
+	PyMac_PRECHECK(RGBBackColor);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      QdRGB_Convert, &color))
+		return NULL;
+	RGBBackColor(&color);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_SetCPixel(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short h;
+	short v;
+	RGBColor cPix;
+#ifndef SetCPixel
+	PyMac_PRECHECK(SetCPixel);
+#endif
+	if (!PyArg_ParseTuple(_args, "hhO&",
+	                      &h,
+	                      &v,
+	                      QdRGB_Convert, &cPix))
+		return NULL;
+	SetCPixel(h,
+	          v,
+	          &cPix);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_SetPortPix(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PixMapHandle pm;
+#ifndef SetPortPix
+	PyMac_PRECHECK(SetPortPix);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &pm))
+		return NULL;
+	SetPortPix(pm);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_GetCPixel(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short h;
+	short v;
+	RGBColor cPix;
+#ifndef GetCPixel
+	PyMac_PRECHECK(GetCPixel);
+#endif
+	if (!PyArg_ParseTuple(_args, "hh",
+	                      &h,
+	                      &v))
+		return NULL;
+	GetCPixel(h,
+	          v,
+	          &cPix);
+	_res = Py_BuildValue("O&",
+	                     QdRGB_New, &cPix);
+	return _res;
+}
+
+static PyObject *Qd_GetForeColor(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RGBColor color;
+#ifndef GetForeColor
+	PyMac_PRECHECK(GetForeColor);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	GetForeColor(&color);
+	_res = Py_BuildValue("O&",
+	                     QdRGB_New, &color);
+	return _res;
+}
+
+static PyObject *Qd_GetBackColor(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RGBColor color;
+#ifndef GetBackColor
+	PyMac_PRECHECK(GetBackColor);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	GetBackColor(&color);
+	_res = Py_BuildValue("O&",
+	                     QdRGB_New, &color);
+	return _res;
+}
+
+static PyObject *Qd_OpColor(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RGBColor color;
+#ifndef OpColor
+	PyMac_PRECHECK(OpColor);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      QdRGB_Convert, &color))
+		return NULL;
+	OpColor(&color);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_HiliteColor(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RGBColor color;
+#ifndef HiliteColor
+	PyMac_PRECHECK(HiliteColor);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      QdRGB_Convert, &color))
+		return NULL;
+	HiliteColor(&color);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_DisposeCTable(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CTabHandle cTable;
+#ifndef DisposeCTable
+	PyMac_PRECHECK(DisposeCTable);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &cTable))
+		return NULL;
+	DisposeCTable(cTable);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_GetCTable(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CTabHandle _rv;
+	short ctID;
+#ifndef GetCTable
+	PyMac_PRECHECK(GetCTable);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &ctID))
+		return NULL;
+	_rv = GetCTable(ctID);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Qd_GetCCursor(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CCrsrHandle _rv;
+	short crsrID;
+#ifndef GetCCursor
+	PyMac_PRECHECK(GetCCursor);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &crsrID))
+		return NULL;
+	_rv = GetCCursor(crsrID);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Qd_SetCCursor(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CCrsrHandle cCrsr;
+#ifndef SetCCursor
+	PyMac_PRECHECK(SetCCursor);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &cCrsr))
+		return NULL;
+	SetCCursor(cCrsr);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_AllocCursor(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef AllocCursor
+	PyMac_PRECHECK(AllocCursor);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	AllocCursor();
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_DisposeCCursor(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CCrsrHandle cCrsr;
+#ifndef DisposeCCursor
+	PyMac_PRECHECK(DisposeCCursor);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &cCrsr))
+		return NULL;
+	DisposeCCursor(cCrsr);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_GetMaxDevice(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	GDHandle _rv;
+	Rect globalRect;
+#ifndef GetMaxDevice
+	PyMac_PRECHECK(GetMaxDevice);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetRect, &globalRect))
+		return NULL;
+	_rv = GetMaxDevice(&globalRect);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Qd_GetCTSeed(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long _rv;
+#ifndef GetCTSeed
+	PyMac_PRECHECK(GetCTSeed);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetCTSeed();
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qd_GetDeviceList(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	GDHandle _rv;
+#ifndef GetDeviceList
+	PyMac_PRECHECK(GetDeviceList);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetDeviceList();
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Qd_GetMainDevice(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	GDHandle _rv;
+#ifndef GetMainDevice
+	PyMac_PRECHECK(GetMainDevice);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetMainDevice();
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Qd_GetNextDevice(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	GDHandle _rv;
+	GDHandle curDevice;
+#ifndef GetNextDevice
+	PyMac_PRECHECK(GetNextDevice);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &curDevice))
+		return NULL;
+	_rv = GetNextDevice(curDevice);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Qd_TestDeviceAttribute(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	GDHandle gdh;
+	short attribute;
+#ifndef TestDeviceAttribute
+	PyMac_PRECHECK(TestDeviceAttribute);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      ResObj_Convert, &gdh,
+	                      &attribute))
+		return NULL;
+	_rv = TestDeviceAttribute(gdh,
+	                          attribute);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qd_SetDeviceAttribute(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	GDHandle gdh;
+	short attribute;
+	Boolean value;
+#ifndef SetDeviceAttribute
+	PyMac_PRECHECK(SetDeviceAttribute);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hb",
+	                      ResObj_Convert, &gdh,
+	                      &attribute,
+	                      &value))
+		return NULL;
+	SetDeviceAttribute(gdh,
+	                   attribute,
+	                   value);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_InitGDevice(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short qdRefNum;
+	long mode;
+	GDHandle gdh;
+#ifndef InitGDevice
+	PyMac_PRECHECK(InitGDevice);
+#endif
+	if (!PyArg_ParseTuple(_args, "hlO&",
+	                      &qdRefNum,
+	                      &mode,
+	                      ResObj_Convert, &gdh))
+		return NULL;
+	InitGDevice(qdRefNum,
+	            mode,
+	            gdh);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_NewGDevice(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	GDHandle _rv;
+	short refNum;
+	long mode;
+#ifndef NewGDevice
+	PyMac_PRECHECK(NewGDevice);
+#endif
+	if (!PyArg_ParseTuple(_args, "hl",
+	                      &refNum,
+	                      &mode))
+		return NULL;
+	_rv = NewGDevice(refNum,
+	                 mode);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Qd_DisposeGDevice(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	GDHandle gdh;
+#ifndef DisposeGDevice
+	PyMac_PRECHECK(DisposeGDevice);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &gdh))
+		return NULL;
+	DisposeGDevice(gdh);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_SetGDevice(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	GDHandle gd;
+#ifndef SetGDevice
+	PyMac_PRECHECK(SetGDevice);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &gd))
+		return NULL;
+	SetGDevice(gd);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_GetGDevice(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	GDHandle _rv;
+#ifndef GetGDevice
+	PyMac_PRECHECK(GetGDevice);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetGDevice();
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Qd_Color2Index(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long _rv;
+	RGBColor myColor;
+#ifndef Color2Index
+	PyMac_PRECHECK(Color2Index);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      QdRGB_Convert, &myColor))
+		return NULL;
+	_rv = Color2Index(&myColor);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qd_Index2Color(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long index;
+	RGBColor aColor;
+#ifndef Index2Color
+	PyMac_PRECHECK(Index2Color);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &index))
+		return NULL;
+	Index2Color(index,
+	            &aColor);
+	_res = Py_BuildValue("O&",
+	                     QdRGB_New, &aColor);
+	return _res;
+}
+
+static PyObject *Qd_InvertColor(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RGBColor myColor;
+#ifndef InvertColor
+	PyMac_PRECHECK(InvertColor);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	InvertColor(&myColor);
+	_res = Py_BuildValue("O&",
+	                     QdRGB_New, &myColor);
+	return _res;
+}
+
+static PyObject *Qd_RealColor(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	RGBColor color;
+#ifndef RealColor
+	PyMac_PRECHECK(RealColor);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      QdRGB_Convert, &color))
+		return NULL;
+	_rv = RealColor(&color);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qd_GetSubTable(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CTabHandle myColors;
+	short iTabRes;
+	CTabHandle targetTbl;
+#ifndef GetSubTable
+	PyMac_PRECHECK(GetSubTable);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hO&",
+	                      ResObj_Convert, &myColors,
+	                      &iTabRes,
+	                      ResObj_Convert, &targetTbl))
+		return NULL;
+	GetSubTable(myColors,
+	            iTabRes,
+	            targetTbl);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_MakeITable(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CTabHandle cTabH;
+	ITabHandle iTabH;
+	short res;
+#ifndef MakeITable
+	PyMac_PRECHECK(MakeITable);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&h",
+	                      ResObj_Convert, &cTabH,
+	                      ResObj_Convert, &iTabH,
+	                      &res))
+		return NULL;
+	MakeITable(cTabH,
+	           iTabH,
+	           res);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_SetClientID(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short id;
+#ifndef SetClientID
+	PyMac_PRECHECK(SetClientID);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &id))
+		return NULL;
+	SetClientID(id);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_ProtectEntry(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short index;
+	Boolean protect;
+#ifndef ProtectEntry
+	PyMac_PRECHECK(ProtectEntry);
+#endif
+	if (!PyArg_ParseTuple(_args, "hb",
+	                      &index,
+	                      &protect))
+		return NULL;
+	ProtectEntry(index,
+	             protect);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_ReserveEntry(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short index;
+	Boolean reserve;
+#ifndef ReserveEntry
+	PyMac_PRECHECK(ReserveEntry);
+#endif
+	if (!PyArg_ParseTuple(_args, "hb",
+	                      &index,
+	                      &reserve))
+		return NULL;
+	ReserveEntry(index,
+	             reserve);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_QDError(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short _rv;
+#ifndef QDError
+	PyMac_PRECHECK(QDError);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = QDError();
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qd_CopyDeepMask(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	BitMapPtr srcBits;
+	BitMapPtr maskBits;
+	BitMapPtr dstBits;
+	Rect srcRect;
+	Rect maskRect;
+	Rect dstRect;
+	short mode;
+	RgnHandle maskRgn;
+#ifndef CopyDeepMask
+	PyMac_PRECHECK(CopyDeepMask);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&O&O&O&hO&",
+	                      BMObj_Convert, &srcBits,
+	                      BMObj_Convert, &maskBits,
+	                      BMObj_Convert, &dstBits,
+	                      PyMac_GetRect, &srcRect,
+	                      PyMac_GetRect, &maskRect,
+	                      PyMac_GetRect, &dstRect,
+	                      &mode,
+	                      OptResObj_Convert, &maskRgn))
+		return NULL;
+	CopyDeepMask(srcBits,
+	             maskBits,
+	             dstBits,
+	             &srcRect,
+	             &maskRect,
+	             &dstRect,
+	             mode,
+	             maskRgn);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_GetPattern(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PatHandle _rv;
+	short patternID;
+#ifndef GetPattern
+	PyMac_PRECHECK(GetPattern);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &patternID))
+		return NULL;
+	_rv = GetPattern(patternID);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Qd_MacGetCursor(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CursHandle _rv;
+	short cursorID;
+#ifndef MacGetCursor
+	PyMac_PRECHECK(MacGetCursor);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &cursorID))
+		return NULL;
+	_rv = MacGetCursor(cursorID);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Qd_GetPicture(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PicHandle _rv;
+	short pictureID;
+#ifndef GetPicture
+	PyMac_PRECHECK(GetPicture);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &pictureID))
+		return NULL;
+	_rv = GetPicture(pictureID);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Qd_DeltaPoint(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long _rv;
+	Point ptA;
+	Point ptB;
+#ifndef DeltaPoint
+	PyMac_PRECHECK(DeltaPoint);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetPoint, &ptA,
+	                      PyMac_GetPoint, &ptB))
+		return NULL;
+	_rv = DeltaPoint(ptA,
+	                 ptB);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qd_ShieldCursor(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect shieldRect;
+	Point offsetPt;
+#ifndef ShieldCursor
+	PyMac_PRECHECK(ShieldCursor);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetRect, &shieldRect,
+	                      PyMac_GetPoint, &offsetPt))
+		return NULL;
+	ShieldCursor(&shieldRect,
+	             offsetPt);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_ScreenRes(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short scrnHRes;
+	short scrnVRes;
+#ifndef ScreenRes
+	PyMac_PRECHECK(ScreenRes);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	ScreenRes(&scrnHRes,
+	          &scrnVRes);
+	_res = Py_BuildValue("hh",
+	                     scrnHRes,
+	                     scrnVRes);
+	return _res;
+}
+
+static PyObject *Qd_GetIndPattern(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Pattern thePat__out__;
+	short patternListID;
+	short index;
+#ifndef GetIndPattern
+	PyMac_PRECHECK(GetIndPattern);
+#endif
+	if (!PyArg_ParseTuple(_args, "hh",
+	                      &patternListID,
+	                      &index))
+		return NULL;
+	GetIndPattern(&thePat__out__,
+	              patternListID,
+	              index);
+	_res = Py_BuildValue("s#",
+	                     (char *)&thePat__out__, (int)sizeof(Pattern));
+	return _res;
+}
+
+static PyObject *Qd_SlopeFromAngle(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Fixed _rv;
+	short angle;
+#ifndef SlopeFromAngle
+	PyMac_PRECHECK(SlopeFromAngle);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &angle))
+		return NULL;
+	_rv = SlopeFromAngle(angle);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildFixed, _rv);
+	return _res;
+}
+
+static PyObject *Qd_AngleFromSlope(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short _rv;
+	Fixed slope;
+#ifndef AngleFromSlope
+	PyMac_PRECHECK(AngleFromSlope);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetFixed, &slope))
+		return NULL;
+	_rv = AngleFromSlope(slope);
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qd_GetPixBounds(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PixMapHandle pixMap;
+	Rect bounds;
+#ifndef GetPixBounds
+	PyMac_PRECHECK(GetPixBounds);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &pixMap))
+		return NULL;
+	GetPixBounds(pixMap,
+	             &bounds);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildRect, &bounds);
+	return _res;
+}
+
+static PyObject *Qd_GetPixDepth(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short _rv;
+	PixMapHandle pixMap;
+#ifndef GetPixDepth
+	PyMac_PRECHECK(GetPixDepth);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &pixMap))
+		return NULL;
+	_rv = GetPixDepth(pixMap);
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qd_GetQDGlobalsRandomSeed(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long _rv;
+#ifndef GetQDGlobalsRandomSeed
+	PyMac_PRECHECK(GetQDGlobalsRandomSeed);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetQDGlobalsRandomSeed();
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qd_GetQDGlobalsScreenBits(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	BitMap screenBits;
+#ifndef GetQDGlobalsScreenBits
+	PyMac_PRECHECK(GetQDGlobalsScreenBits);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	GetQDGlobalsScreenBits(&screenBits);
+	_res = Py_BuildValue("O&",
+	                     BMObj_NewCopied, &screenBits);
+	return _res;
+}
+
+static PyObject *Qd_GetQDGlobalsArrow(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Cursor arrow__out__;
+#ifndef GetQDGlobalsArrow
+	PyMac_PRECHECK(GetQDGlobalsArrow);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	GetQDGlobalsArrow(&arrow__out__);
+	_res = Py_BuildValue("s#",
+	                     (char *)&arrow__out__, (int)sizeof(Cursor));
+	return _res;
+}
+
+static PyObject *Qd_GetQDGlobalsDarkGray(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Pattern dkGray__out__;
+#ifndef GetQDGlobalsDarkGray
+	PyMac_PRECHECK(GetQDGlobalsDarkGray);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	GetQDGlobalsDarkGray(&dkGray__out__);
+	_res = Py_BuildValue("s#",
+	                     (char *)&dkGray__out__, (int)sizeof(Pattern));
+	return _res;
+}
+
+static PyObject *Qd_GetQDGlobalsLightGray(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Pattern ltGray__out__;
+#ifndef GetQDGlobalsLightGray
+	PyMac_PRECHECK(GetQDGlobalsLightGray);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	GetQDGlobalsLightGray(&ltGray__out__);
+	_res = Py_BuildValue("s#",
+	                     (char *)&ltGray__out__, (int)sizeof(Pattern));
+	return _res;
+}
+
+static PyObject *Qd_GetQDGlobalsGray(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Pattern gray__out__;
+#ifndef GetQDGlobalsGray
+	PyMac_PRECHECK(GetQDGlobalsGray);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	GetQDGlobalsGray(&gray__out__);
+	_res = Py_BuildValue("s#",
+	                     (char *)&gray__out__, (int)sizeof(Pattern));
+	return _res;
+}
+
+static PyObject *Qd_GetQDGlobalsBlack(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Pattern black__out__;
+#ifndef GetQDGlobalsBlack
+	PyMac_PRECHECK(GetQDGlobalsBlack);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	GetQDGlobalsBlack(&black__out__);
+	_res = Py_BuildValue("s#",
+	                     (char *)&black__out__, (int)sizeof(Pattern));
+	return _res;
+}
+
+static PyObject *Qd_GetQDGlobalsWhite(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Pattern white__out__;
+#ifndef GetQDGlobalsWhite
+	PyMac_PRECHECK(GetQDGlobalsWhite);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	GetQDGlobalsWhite(&white__out__);
+	_res = Py_BuildValue("s#",
+	                     (char *)&white__out__, (int)sizeof(Pattern));
+	return _res;
+}
+
+static PyObject *Qd_GetQDGlobalsThePort(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CGrafPtr _rv;
+#ifndef GetQDGlobalsThePort
+	PyMac_PRECHECK(GetQDGlobalsThePort);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetQDGlobalsThePort();
+	_res = Py_BuildValue("O&",
+	                     GrafObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Qd_SetQDGlobalsRandomSeed(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long randomSeed;
+#ifndef SetQDGlobalsRandomSeed
+	PyMac_PRECHECK(SetQDGlobalsRandomSeed);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &randomSeed))
+		return NULL;
+	SetQDGlobalsRandomSeed(randomSeed);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_SetQDGlobalsArrow(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Cursor *arrow__in__;
+	int arrow__in_len__;
+#ifndef SetQDGlobalsArrow
+	PyMac_PRECHECK(SetQDGlobalsArrow);
+#endif
+	if (!PyArg_ParseTuple(_args, "s#",
+	                      (char **)&arrow__in__, &arrow__in_len__))
+		return NULL;
+	if (arrow__in_len__ != sizeof(Cursor))
+	{
+		PyErr_SetString(PyExc_TypeError, "buffer length should be sizeof(Cursor)");
+		goto arrow__error__;
+	}
+	SetQDGlobalsArrow(arrow__in__);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+ arrow__error__: ;
+	return _res;
+}
+
+static PyObject *Qd_GetRegionBounds(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle region;
+	Rect bounds;
+#ifndef GetRegionBounds
+	PyMac_PRECHECK(GetRegionBounds);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &region))
+		return NULL;
+	GetRegionBounds(region,
+	                &bounds);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildRect, &bounds);
+	return _res;
+}
+
+static PyObject *Qd_IsRegionRectangular(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	RgnHandle region;
+#ifndef IsRegionRectangular
+	PyMac_PRECHECK(IsRegionRectangular);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &region))
+		return NULL;
+	_rv = IsRegionRectangular(region);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qd_CreateNewPort(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CGrafPtr _rv;
+#ifndef CreateNewPort
+	PyMac_PRECHECK(CreateNewPort);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CreateNewPort();
+	_res = Py_BuildValue("O&",
+	                     GrafObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Qd_SetQDError(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr err;
+#ifndef SetQDError
+	PyMac_PRECHECK(SetQDError);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &err))
+		return NULL;
+	SetQDError(err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_LMGetScrVRes(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	SInt16 _rv;
+#ifndef LMGetScrVRes
+	PyMac_PRECHECK(LMGetScrVRes);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = LMGetScrVRes();
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qd_LMSetScrVRes(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	SInt16 value;
+#ifndef LMSetScrVRes
+	PyMac_PRECHECK(LMSetScrVRes);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &value))
+		return NULL;
+	LMSetScrVRes(value);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_LMGetScrHRes(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	SInt16 _rv;
+#ifndef LMGetScrHRes
+	PyMac_PRECHECK(LMGetScrHRes);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = LMGetScrHRes();
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qd_LMSetScrHRes(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	SInt16 value;
+#ifndef LMSetScrHRes
+	PyMac_PRECHECK(LMSetScrHRes);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &value))
+		return NULL;
+	LMSetScrHRes(value);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_LMGetMainDevice(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	GDHandle _rv;
+#ifndef LMGetMainDevice
+	PyMac_PRECHECK(LMGetMainDevice);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = LMGetMainDevice();
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Qd_LMSetMainDevice(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	GDHandle value;
+#ifndef LMSetMainDevice
+	PyMac_PRECHECK(LMSetMainDevice);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &value))
+		return NULL;
+	LMSetMainDevice(value);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_LMGetDeviceList(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	GDHandle _rv;
+#ifndef LMGetDeviceList
+	PyMac_PRECHECK(LMGetDeviceList);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = LMGetDeviceList();
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Qd_LMSetDeviceList(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	GDHandle value;
+#ifndef LMSetDeviceList
+	PyMac_PRECHECK(LMSetDeviceList);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &value))
+		return NULL;
+	LMSetDeviceList(value);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_LMGetQDColors(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Handle _rv;
+#ifndef LMGetQDColors
+	PyMac_PRECHECK(LMGetQDColors);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = LMGetQDColors();
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Qd_LMSetQDColors(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Handle value;
+#ifndef LMSetQDColors
+	PyMac_PRECHECK(LMSetQDColors);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &value))
+		return NULL;
+	LMSetQDColors(value);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_LMGetWidthListHand(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Handle _rv;
+#ifndef LMGetWidthListHand
+	PyMac_PRECHECK(LMGetWidthListHand);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = LMGetWidthListHand();
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Qd_LMSetWidthListHand(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Handle value;
+#ifndef LMSetWidthListHand
+	PyMac_PRECHECK(LMSetWidthListHand);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &value))
+		return NULL;
+	LMSetWidthListHand(value);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_LMGetHiliteMode(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	UInt8 _rv;
+#ifndef LMGetHiliteMode
+	PyMac_PRECHECK(LMGetHiliteMode);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = LMGetHiliteMode();
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qd_LMSetHiliteMode(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	UInt8 value;
+#ifndef LMSetHiliteMode
+	PyMac_PRECHECK(LMSetHiliteMode);
+#endif
+	if (!PyArg_ParseTuple(_args, "b",
+	                      &value))
+		return NULL;
+	LMSetHiliteMode(value);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_LMGetWidthTabHandle(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Handle _rv;
+#ifndef LMGetWidthTabHandle
+	PyMac_PRECHECK(LMGetWidthTabHandle);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = LMGetWidthTabHandle();
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Qd_LMSetWidthTabHandle(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Handle value;
+#ifndef LMSetWidthTabHandle
+	PyMac_PRECHECK(LMSetWidthTabHandle);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &value))
+		return NULL;
+	LMSetWidthTabHandle(value);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_LMGetLastSPExtra(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	SInt32 _rv;
+#ifndef LMGetLastSPExtra
+	PyMac_PRECHECK(LMGetLastSPExtra);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = LMGetLastSPExtra();
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qd_LMSetLastSPExtra(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	SInt32 value;
+#ifndef LMSetLastSPExtra
+	PyMac_PRECHECK(LMSetLastSPExtra);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &value))
+		return NULL;
+	LMSetLastSPExtra(value);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_LMGetLastFOND(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Handle _rv;
+#ifndef LMGetLastFOND
+	PyMac_PRECHECK(LMGetLastFOND);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = LMGetLastFOND();
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Qd_LMSetLastFOND(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Handle value;
+#ifndef LMSetLastFOND
+	PyMac_PRECHECK(LMSetLastFOND);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &value))
+		return NULL;
+	LMSetLastFOND(value);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_LMGetFractEnable(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	UInt8 _rv;
+#ifndef LMGetFractEnable
+	PyMac_PRECHECK(LMGetFractEnable);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = LMGetFractEnable();
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qd_LMSetFractEnable(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	UInt8 value;
+#ifndef LMSetFractEnable
+	PyMac_PRECHECK(LMSetFractEnable);
+#endif
+	if (!PyArg_ParseTuple(_args, "b",
+	                      &value))
+		return NULL;
+	LMSetFractEnable(value);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_LMGetTheGDevice(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	GDHandle _rv;
+#ifndef LMGetTheGDevice
+	PyMac_PRECHECK(LMGetTheGDevice);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = LMGetTheGDevice();
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Qd_LMSetTheGDevice(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	GDHandle value;
+#ifndef LMSetTheGDevice
+	PyMac_PRECHECK(LMSetTheGDevice);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &value))
+		return NULL;
+	LMSetTheGDevice(value);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_LMGetHiliteRGB(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RGBColor hiliteRGBValue;
+#ifndef LMGetHiliteRGB
+	PyMac_PRECHECK(LMGetHiliteRGB);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	LMGetHiliteRGB(&hiliteRGBValue);
+	_res = Py_BuildValue("O&",
+	                     QdRGB_New, &hiliteRGBValue);
+	return _res;
+}
+
+static PyObject *Qd_LMSetHiliteRGB(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RGBColor hiliteRGBValue;
+#ifndef LMSetHiliteRGB
+	PyMac_PRECHECK(LMSetHiliteRGB);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      QdRGB_Convert, &hiliteRGBValue))
+		return NULL;
+	LMSetHiliteRGB(&hiliteRGBValue);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_LMGetCursorNew(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+#ifndef LMGetCursorNew
+	PyMac_PRECHECK(LMGetCursorNew);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = LMGetCursorNew();
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qd_LMSetCursorNew(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean value;
+#ifndef LMSetCursorNew
+	PyMac_PRECHECK(LMSetCursorNew);
+#endif
+	if (!PyArg_ParseTuple(_args, "b",
+	                      &value))
+		return NULL;
+	LMSetCursorNew(value);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_TextFont(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short font;
+#ifndef TextFont
+	PyMac_PRECHECK(TextFont);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &font))
+		return NULL;
+	TextFont(font);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_TextFace(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	StyleParameter face;
+#ifndef TextFace
+	PyMac_PRECHECK(TextFace);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &face))
+		return NULL;
+	TextFace(face);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_TextMode(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short mode;
+#ifndef TextMode
+	PyMac_PRECHECK(TextMode);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &mode))
+		return NULL;
+	TextMode(mode);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_TextSize(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short size;
+#ifndef TextSize
+	PyMac_PRECHECK(TextSize);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &size))
+		return NULL;
+	TextSize(size);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_SpaceExtra(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Fixed extra;
+#ifndef SpaceExtra
+	PyMac_PRECHECK(SpaceExtra);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetFixed, &extra))
+		return NULL;
+	SpaceExtra(extra);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_DrawChar(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CharParameter ch;
+#ifndef DrawChar
+	PyMac_PRECHECK(DrawChar);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &ch))
+		return NULL;
+	DrawChar(ch);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_DrawString(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Str255 s;
+#ifndef DrawString
+	PyMac_PRECHECK(DrawString);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetStr255, s))
+		return NULL;
+	DrawString(s);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_MacDrawText(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	char *textBuf__in__;
+	int textBuf__in_len__;
+	short firstByte;
+	short byteCount;
+#ifndef MacDrawText
+	PyMac_PRECHECK(MacDrawText);
+#endif
+	if (!PyArg_ParseTuple(_args, "s#hh",
+	                      &textBuf__in__, &textBuf__in_len__,
+	                      &firstByte,
+	                      &byteCount))
+		return NULL;
+	/* Fool compiler warnings */
+	textBuf__in_len__ = textBuf__in_len__;
+	MacDrawText(textBuf__in__,
+	            firstByte,
+	            byteCount);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_CharWidth(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short _rv;
+	CharParameter ch;
+#ifndef CharWidth
+	PyMac_PRECHECK(CharWidth);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &ch))
+		return NULL;
+	_rv = CharWidth(ch);
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qd_StringWidth(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short _rv;
+	Str255 s;
+#ifndef StringWidth
+	PyMac_PRECHECK(StringWidth);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetStr255, s))
+		return NULL;
+	_rv = StringWidth(s);
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qd_TextWidth(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short _rv;
+	char *textBuf__in__;
+	int textBuf__in_len__;
+	short firstByte;
+	short byteCount;
+#ifndef TextWidth
+	PyMac_PRECHECK(TextWidth);
+#endif
+	if (!PyArg_ParseTuple(_args, "s#hh",
+	                      &textBuf__in__, &textBuf__in_len__,
+	                      &firstByte,
+	                      &byteCount))
+		return NULL;
+	/* Fool compiler warnings */
+	textBuf__in_len__ = textBuf__in_len__;
+	_rv = TextWidth(textBuf__in__,
+	                firstByte,
+	                byteCount);
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qd_GetFontInfo(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	FontInfo info;
+#ifndef GetFontInfo
+	PyMac_PRECHECK(GetFontInfo);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	GetFontInfo(&info);
+	_res = Py_BuildValue("O&",
+	                     QdFI_New, &info);
+	return _res;
+}
+
+static PyObject *Qd_CharExtra(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Fixed extra;
+#ifndef CharExtra
+	PyMac_PRECHECK(CharExtra);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetFixed, &extra))
+		return NULL;
+	CharExtra(extra);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_TruncString(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short _rv;
+	short width;
+	Str255 theString;
+	TruncCode truncWhere;
+#ifndef TruncString
+	PyMac_PRECHECK(TruncString);
+#endif
+	if (!PyArg_ParseTuple(_args, "hO&h",
+	                      &width,
+	                      PyMac_GetStr255, theString,
+	                      &truncWhere))
+		return NULL;
+	_rv = TruncString(width,
+	                  theString,
+	                  truncWhere);
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qd_SetPort(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	GrafPtr thePort;
+#ifndef SetPort
+	PyMac_PRECHECK(SetPort);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      GrafObj_Convert, &thePort))
+		return NULL;
+	SetPort(thePort);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_GetCursor(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CursHandle _rv;
+	short cursorID;
+#ifndef GetCursor
+	PyMac_PRECHECK(GetCursor);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &cursorID))
+		return NULL;
+	_rv = GetCursor(cursorID);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Qd_SetCursor(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Cursor *crsr__in__;
+	int crsr__in_len__;
+#ifndef SetCursor
+	PyMac_PRECHECK(SetCursor);
+#endif
+	if (!PyArg_ParseTuple(_args, "s#",
+	                      (char **)&crsr__in__, &crsr__in_len__))
+		return NULL;
+	if (crsr__in_len__ != sizeof(Cursor))
+	{
+		PyErr_SetString(PyExc_TypeError, "buffer length should be sizeof(Cursor)");
+		goto crsr__error__;
+	}
+	SetCursor(crsr__in__);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+ crsr__error__: ;
+	return _res;
+}
+
+static PyObject *Qd_ShowCursor(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef ShowCursor
+	PyMac_PRECHECK(ShowCursor);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	ShowCursor();
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_LineTo(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short h;
+	short v;
+#ifndef LineTo
+	PyMac_PRECHECK(LineTo);
+#endif
+	if (!PyArg_ParseTuple(_args, "hh",
+	                      &h,
+	                      &v))
+		return NULL;
+	LineTo(h,
+	       v);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_SetRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect r;
+	short left;
+	short top;
+	short right;
+	short bottom;
+#ifndef SetRect
+	PyMac_PRECHECK(SetRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "hhhh",
+	                      &left,
+	                      &top,
+	                      &right,
+	                      &bottom))
+		return NULL;
+	SetRect(&r,
+	        left,
+	        top,
+	        right,
+	        bottom);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildRect, &r);
+	return _res;
+}
+
+static PyObject *Qd_OffsetRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect r;
+	short dh;
+	short dv;
+#ifndef OffsetRect
+	PyMac_PRECHECK(OffsetRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hh",
+	                      PyMac_GetRect, &r,
+	                      &dh,
+	                      &dv))
+		return NULL;
+	OffsetRect(&r,
+	           dh,
+	           dv);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildRect, &r);
+	return _res;
+}
+
+static PyObject *Qd_InsetRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect r;
+	short dh;
+	short dv;
+#ifndef InsetRect
+	PyMac_PRECHECK(InsetRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hh",
+	                      PyMac_GetRect, &r,
+	                      &dh,
+	                      &dv))
+		return NULL;
+	InsetRect(&r,
+	          dh,
+	          dv);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildRect, &r);
+	return _res;
+}
+
+static PyObject *Qd_UnionRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect src1;
+	Rect src2;
+	Rect dstRect;
+#ifndef UnionRect
+	PyMac_PRECHECK(UnionRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetRect, &src1,
+	                      PyMac_GetRect, &src2))
+		return NULL;
+	UnionRect(&src1,
+	          &src2,
+	          &dstRect);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildRect, &dstRect);
+	return _res;
+}
+
+static PyObject *Qd_EqualRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	Rect rect1;
+	Rect rect2;
+#ifndef EqualRect
+	PyMac_PRECHECK(EqualRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetRect, &rect1,
+	                      PyMac_GetRect, &rect2))
+		return NULL;
+	_rv = EqualRect(&rect1,
+	                &rect2);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qd_FrameRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect r;
+#ifndef FrameRect
+	PyMac_PRECHECK(FrameRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetRect, &r))
+		return NULL;
+	FrameRect(&r);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_InvertRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect r;
+#ifndef InvertRect
+	PyMac_PRECHECK(InvertRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetRect, &r))
+		return NULL;
+	InvertRect(&r);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_FillRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect r;
+	Pattern *pat__in__;
+	int pat__in_len__;
+#ifndef FillRect
+	PyMac_PRECHECK(FillRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&s#",
+	                      PyMac_GetRect, &r,
+	                      (char **)&pat__in__, &pat__in_len__))
+		return NULL;
+	if (pat__in_len__ != sizeof(Pattern))
+	{
+		PyErr_SetString(PyExc_TypeError, "buffer length should be sizeof(Pattern)");
+		goto pat__error__;
+	}
+	FillRect(&r,
+	         pat__in__);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+ pat__error__: ;
+	return _res;
+}
+
+static PyObject *Qd_CopyRgn(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle srcRgn;
+	RgnHandle dstRgn;
+#ifndef CopyRgn
+	PyMac_PRECHECK(CopyRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      ResObj_Convert, &srcRgn,
+	                      ResObj_Convert, &dstRgn))
+		return NULL;
+	CopyRgn(srcRgn,
+	        dstRgn);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_SetRectRgn(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle rgn;
+	short left;
+	short top;
+	short right;
+	short bottom;
+#ifndef SetRectRgn
+	PyMac_PRECHECK(SetRectRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hhhh",
+	                      ResObj_Convert, &rgn,
+	                      &left,
+	                      &top,
+	                      &right,
+	                      &bottom))
+		return NULL;
+	SetRectRgn(rgn,
+	           left,
+	           top,
+	           right,
+	           bottom);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_OffsetRgn(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle rgn;
+	short dh;
+	short dv;
+#ifndef OffsetRgn
+	PyMac_PRECHECK(OffsetRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hh",
+	                      ResObj_Convert, &rgn,
+	                      &dh,
+	                      &dv))
+		return NULL;
+	OffsetRgn(rgn,
+	          dh,
+	          dv);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_UnionRgn(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle srcRgnA;
+	RgnHandle srcRgnB;
+	RgnHandle dstRgn;
+#ifndef UnionRgn
+	PyMac_PRECHECK(UnionRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      ResObj_Convert, &srcRgnA,
+	                      ResObj_Convert, &srcRgnB,
+	                      ResObj_Convert, &dstRgn))
+		return NULL;
+	UnionRgn(srcRgnA,
+	         srcRgnB,
+	         dstRgn);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_XorRgn(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle srcRgnA;
+	RgnHandle srcRgnB;
+	RgnHandle dstRgn;
+#ifndef XorRgn
+	PyMac_PRECHECK(XorRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      ResObj_Convert, &srcRgnA,
+	                      ResObj_Convert, &srcRgnB,
+	                      ResObj_Convert, &dstRgn))
+		return NULL;
+	XorRgn(srcRgnA,
+	       srcRgnB,
+	       dstRgn);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_EqualRgn(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	RgnHandle rgnA;
+	RgnHandle rgnB;
+#ifndef EqualRgn
+	PyMac_PRECHECK(EqualRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      ResObj_Convert, &rgnA,
+	                      ResObj_Convert, &rgnB))
+		return NULL;
+	_rv = EqualRgn(rgnA,
+	               rgnB);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qd_FrameRgn(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle rgn;
+#ifndef FrameRgn
+	PyMac_PRECHECK(FrameRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &rgn))
+		return NULL;
+	FrameRgn(rgn);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_PaintRgn(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle rgn;
+#ifndef PaintRgn
+	PyMac_PRECHECK(PaintRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &rgn))
+		return NULL;
+	PaintRgn(rgn);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_InvertRgn(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle rgn;
+#ifndef InvertRgn
+	PyMac_PRECHECK(InvertRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &rgn))
+		return NULL;
+	InvertRgn(rgn);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_FillRgn(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle rgn;
+	Pattern *pat__in__;
+	int pat__in_len__;
+#ifndef FillRgn
+	PyMac_PRECHECK(FillRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&s#",
+	                      ResObj_Convert, &rgn,
+	                      (char **)&pat__in__, &pat__in_len__))
+		return NULL;
+	if (pat__in_len__ != sizeof(Pattern))
+	{
+		PyErr_SetString(PyExc_TypeError, "buffer length should be sizeof(Pattern)");
+		goto pat__error__;
+	}
+	FillRgn(rgn,
+	        pat__in__);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+ pat__error__: ;
+	return _res;
+}
+
+static PyObject *Qd_GetPixel(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	short h;
+	short v;
+#ifndef GetPixel
+	PyMac_PRECHECK(GetPixel);
+#endif
+	if (!PyArg_ParseTuple(_args, "hh",
+	                      &h,
+	                      &v))
+		return NULL;
+	_rv = GetPixel(h,
+	               v);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qd_PtInRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	Point pt;
+	Rect r;
+#ifndef PtInRect
+	PyMac_PRECHECK(PtInRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetPoint, &pt,
+	                      PyMac_GetRect, &r))
+		return NULL;
+	_rv = PtInRect(pt,
+	               &r);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qd_DrawText(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	char *textBuf__in__;
+	int textBuf__in_len__;
+	short firstByte;
+	short byteCount;
+#ifndef DrawText
+	PyMac_PRECHECK(DrawText);
+#endif
+	if (!PyArg_ParseTuple(_args, "s#hh",
+	                      &textBuf__in__, &textBuf__in_len__,
+	                      &firstByte,
+	                      &byteCount))
+		return NULL;
+	/* Fool compiler warnings */
+	textBuf__in_len__ = textBuf__in_len__;
+	DrawText(textBuf__in__,
+	         firstByte,
+	         byteCount);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qd_BitMap(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+
+	BitMap *ptr;
+	PyObject *source;
+	Rect bounds;
+	int rowbytes;
+	char *data;
+
+	if ( !PyArg_ParseTuple(_args, "O!iO&", &PyString_Type, &source, &rowbytes, PyMac_GetRect,
+	                &bounds) )
+	        return NULL;
+	data = PyString_AsString(source);
+	if ((ptr=(BitMap *)malloc(sizeof(BitMap))) == NULL )
+	        return PyErr_NoMemory();
+	ptr->baseAddr = (Ptr)data;
+	ptr->rowBytes = rowbytes;
+	ptr->bounds = bounds;
+	if ( (_res = BMObj_New(ptr)) == NULL ) {
+	        free(ptr);
+	        return NULL;
+	}
+	((BitMapObject *)_res)->referred_object = source;
+	Py_INCREF(source);
+	((BitMapObject *)_res)->referred_bitmap = ptr;
+	return _res;
+
+}
+
+static PyObject *Qd_RawBitMap(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+
+	BitMap *ptr;
+	PyObject *source;
+
+	if ( !PyArg_ParseTuple(_args, "O!", &PyString_Type, &source) )
+	        return NULL;
+	if ( PyString_Size(source) != sizeof(BitMap) && PyString_Size(source) != sizeof(PixMap) ) {
+	        PyErr_Format(PyExc_TypeError,
+	                "Argument size was %ld, should be %lu (sizeof BitMap) or %lu (sizeof PixMap)",
+	                PyString_Size(source), sizeof(BitMap), sizeof(PixMap));
+	        return NULL;
+	}
+	ptr = (BitMapPtr)PyString_AsString(source);
+	if ( (_res = BMObj_New(ptr)) == NULL ) {
+	        return NULL;
+	}
+	((BitMapObject *)_res)->referred_object = source;
+	Py_INCREF(source);
+	return _res;
+
+}
+
+static PyMethodDef Qd_methods[] = {
+	{"GetPort", (PyCFunction)Qd_GetPort, 1,
+	 PyDoc_STR("() -> (GrafPtr port)")},
+	{"GrafDevice", (PyCFunction)Qd_GrafDevice, 1,
+	 PyDoc_STR("(short device) -> None")},
+	{"SetPortBits", (PyCFunction)Qd_SetPortBits, 1,
+	 PyDoc_STR("(BitMapPtr bm) -> None")},
+	{"PortSize", (PyCFunction)Qd_PortSize, 1,
+	 PyDoc_STR("(short width, short height) -> None")},
+	{"MovePortTo", (PyCFunction)Qd_MovePortTo, 1,
+	 PyDoc_STR("(short leftGlobal, short topGlobal) -> None")},
+	{"SetOrigin", (PyCFunction)Qd_SetOrigin, 1,
+	 PyDoc_STR("(short h, short v) -> None")},
+	{"SetClip", (PyCFunction)Qd_SetClip, 1,
+	 PyDoc_STR("(RgnHandle rgn) -> None")},
+	{"GetClip", (PyCFunction)Qd_GetClip, 1,
+	 PyDoc_STR("(RgnHandle rgn) -> None")},
+	{"ClipRect", (PyCFunction)Qd_ClipRect, 1,
+	 PyDoc_STR("(Rect r) -> None")},
+	{"BackPat", (PyCFunction)Qd_BackPat, 1,
+	 PyDoc_STR("(Pattern pat) -> None")},
+	{"InitCursor", (PyCFunction)Qd_InitCursor, 1,
+	 PyDoc_STR("() -> None")},
+	{"MacSetCursor", (PyCFunction)Qd_MacSetCursor, 1,
+	 PyDoc_STR("(Cursor crsr) -> None")},
+	{"HideCursor", (PyCFunction)Qd_HideCursor, 1,
+	 PyDoc_STR("() -> None")},
+	{"MacShowCursor", (PyCFunction)Qd_MacShowCursor, 1,
+	 PyDoc_STR("() -> None")},
+	{"ObscureCursor", (PyCFunction)Qd_ObscureCursor, 1,
+	 PyDoc_STR("() -> None")},
+	{"HidePen", (PyCFunction)Qd_HidePen, 1,
+	 PyDoc_STR("() -> None")},
+	{"ShowPen", (PyCFunction)Qd_ShowPen, 1,
+	 PyDoc_STR("() -> None")},
+	{"GetPen", (PyCFunction)Qd_GetPen, 1,
+	 PyDoc_STR("() -> (Point pt)")},
+	{"GetPenState", (PyCFunction)Qd_GetPenState, 1,
+	 PyDoc_STR("() -> (PenState pnState)")},
+	{"SetPenState", (PyCFunction)Qd_SetPenState, 1,
+	 PyDoc_STR("(PenState pnState) -> None")},
+	{"PenSize", (PyCFunction)Qd_PenSize, 1,
+	 PyDoc_STR("(short width, short height) -> None")},
+	{"PenMode", (PyCFunction)Qd_PenMode, 1,
+	 PyDoc_STR("(short mode) -> None")},
+	{"PenPat", (PyCFunction)Qd_PenPat, 1,
+	 PyDoc_STR("(Pattern pat) -> None")},
+	{"PenNormal", (PyCFunction)Qd_PenNormal, 1,
+	 PyDoc_STR("() -> None")},
+	{"MoveTo", (PyCFunction)Qd_MoveTo, 1,
+	 PyDoc_STR("(short h, short v) -> None")},
+	{"Move", (PyCFunction)Qd_Move, 1,
+	 PyDoc_STR("(short dh, short dv) -> None")},
+	{"MacLineTo", (PyCFunction)Qd_MacLineTo, 1,
+	 PyDoc_STR("(short h, short v) -> None")},
+	{"Line", (PyCFunction)Qd_Line, 1,
+	 PyDoc_STR("(short dh, short dv) -> None")},
+	{"ForeColor", (PyCFunction)Qd_ForeColor, 1,
+	 PyDoc_STR("(long color) -> None")},
+	{"BackColor", (PyCFunction)Qd_BackColor, 1,
+	 PyDoc_STR("(long color) -> None")},
+	{"ColorBit", (PyCFunction)Qd_ColorBit, 1,
+	 PyDoc_STR("(short whichBit) -> None")},
+	{"MacSetRect", (PyCFunction)Qd_MacSetRect, 1,
+	 PyDoc_STR("(short left, short top, short right, short bottom) -> (Rect r)")},
+	{"MacOffsetRect", (PyCFunction)Qd_MacOffsetRect, 1,
+	 PyDoc_STR("(Rect r, short dh, short dv) -> (Rect r)")},
+	{"MacInsetRect", (PyCFunction)Qd_MacInsetRect, 1,
+	 PyDoc_STR("(Rect r, short dh, short dv) -> (Rect r)")},
+	{"SectRect", (PyCFunction)Qd_SectRect, 1,
+	 PyDoc_STR("(Rect src1, Rect src2) -> (Boolean _rv, Rect dstRect)")},
+	{"MacUnionRect", (PyCFunction)Qd_MacUnionRect, 1,
+	 PyDoc_STR("(Rect src1, Rect src2) -> (Rect dstRect)")},
+	{"MacEqualRect", (PyCFunction)Qd_MacEqualRect, 1,
+	 PyDoc_STR("(Rect rect1, Rect rect2) -> (Boolean _rv)")},
+	{"EmptyRect", (PyCFunction)Qd_EmptyRect, 1,
+	 PyDoc_STR("(Rect r) -> (Boolean _rv)")},
+	{"MacFrameRect", (PyCFunction)Qd_MacFrameRect, 1,
+	 PyDoc_STR("(Rect r) -> None")},
+	{"PaintRect", (PyCFunction)Qd_PaintRect, 1,
+	 PyDoc_STR("(Rect r) -> None")},
+	{"EraseRect", (PyCFunction)Qd_EraseRect, 1,
+	 PyDoc_STR("(Rect r) -> None")},
+	{"MacInvertRect", (PyCFunction)Qd_MacInvertRect, 1,
+	 PyDoc_STR("(Rect r) -> None")},
+	{"MacFillRect", (PyCFunction)Qd_MacFillRect, 1,
+	 PyDoc_STR("(Rect r, Pattern pat) -> None")},
+	{"FrameOval", (PyCFunction)Qd_FrameOval, 1,
+	 PyDoc_STR("(Rect r) -> None")},
+	{"PaintOval", (PyCFunction)Qd_PaintOval, 1,
+	 PyDoc_STR("(Rect r) -> None")},
+	{"EraseOval", (PyCFunction)Qd_EraseOval, 1,
+	 PyDoc_STR("(Rect r) -> None")},
+	{"InvertOval", (PyCFunction)Qd_InvertOval, 1,
+	 PyDoc_STR("(Rect r) -> None")},
+	{"FillOval", (PyCFunction)Qd_FillOval, 1,
+	 PyDoc_STR("(Rect r, Pattern pat) -> None")},
+	{"FrameRoundRect", (PyCFunction)Qd_FrameRoundRect, 1,
+	 PyDoc_STR("(Rect r, short ovalWidth, short ovalHeight) -> None")},
+	{"PaintRoundRect", (PyCFunction)Qd_PaintRoundRect, 1,
+	 PyDoc_STR("(Rect r, short ovalWidth, short ovalHeight) -> None")},
+	{"EraseRoundRect", (PyCFunction)Qd_EraseRoundRect, 1,
+	 PyDoc_STR("(Rect r, short ovalWidth, short ovalHeight) -> None")},
+	{"InvertRoundRect", (PyCFunction)Qd_InvertRoundRect, 1,
+	 PyDoc_STR("(Rect r, short ovalWidth, short ovalHeight) -> None")},
+	{"FillRoundRect", (PyCFunction)Qd_FillRoundRect, 1,
+	 PyDoc_STR("(Rect r, short ovalWidth, short ovalHeight, Pattern pat) -> None")},
+	{"FrameArc", (PyCFunction)Qd_FrameArc, 1,
+	 PyDoc_STR("(Rect r, short startAngle, short arcAngle) -> None")},
+	{"PaintArc", (PyCFunction)Qd_PaintArc, 1,
+	 PyDoc_STR("(Rect r, short startAngle, short arcAngle) -> None")},
+	{"EraseArc", (PyCFunction)Qd_EraseArc, 1,
+	 PyDoc_STR("(Rect r, short startAngle, short arcAngle) -> None")},
+	{"InvertArc", (PyCFunction)Qd_InvertArc, 1,
+	 PyDoc_STR("(Rect r, short startAngle, short arcAngle) -> None")},
+	{"FillArc", (PyCFunction)Qd_FillArc, 1,
+	 PyDoc_STR("(Rect r, short startAngle, short arcAngle, Pattern pat) -> None")},
+	{"NewRgn", (PyCFunction)Qd_NewRgn, 1,
+	 PyDoc_STR("() -> (RgnHandle _rv)")},
+	{"OpenRgn", (PyCFunction)Qd_OpenRgn, 1,
+	 PyDoc_STR("() -> None")},
+	{"CloseRgn", (PyCFunction)Qd_CloseRgn, 1,
+	 PyDoc_STR("(RgnHandle dstRgn) -> None")},
+	{"BitMapToRegion", (PyCFunction)Qd_BitMapToRegion, 1,
+	 PyDoc_STR("(RgnHandle region, BitMapPtr bMap) -> None")},
+	{"RgnToHandle", (PyCFunction)Qd_RgnToHandle, 1,
+	 PyDoc_STR("(RgnHandle region, Handle flattenedRgnDataHdl) -> None")},
+	{"DisposeRgn", (PyCFunction)Qd_DisposeRgn, 1,
+	 PyDoc_STR("(RgnHandle rgn) -> None")},
+	{"MacCopyRgn", (PyCFunction)Qd_MacCopyRgn, 1,
+	 PyDoc_STR("(RgnHandle srcRgn, RgnHandle dstRgn) -> None")},
+	{"SetEmptyRgn", (PyCFunction)Qd_SetEmptyRgn, 1,
+	 PyDoc_STR("(RgnHandle rgn) -> None")},
+	{"MacSetRectRgn", (PyCFunction)Qd_MacSetRectRgn, 1,
+	 PyDoc_STR("(RgnHandle rgn, short left, short top, short right, short bottom) -> None")},
+	{"RectRgn", (PyCFunction)Qd_RectRgn, 1,
+	 PyDoc_STR("(RgnHandle rgn, Rect r) -> None")},
+	{"MacOffsetRgn", (PyCFunction)Qd_MacOffsetRgn, 1,
+	 PyDoc_STR("(RgnHandle rgn, short dh, short dv) -> None")},
+	{"InsetRgn", (PyCFunction)Qd_InsetRgn, 1,
+	 PyDoc_STR("(RgnHandle rgn, short dh, short dv) -> None")},
+	{"SectRgn", (PyCFunction)Qd_SectRgn, 1,
+	 PyDoc_STR("(RgnHandle srcRgnA, RgnHandle srcRgnB, RgnHandle dstRgn) -> None")},
+	{"MacUnionRgn", (PyCFunction)Qd_MacUnionRgn, 1,
+	 PyDoc_STR("(RgnHandle srcRgnA, RgnHandle srcRgnB, RgnHandle dstRgn) -> None")},
+	{"DiffRgn", (PyCFunction)Qd_DiffRgn, 1,
+	 PyDoc_STR("(RgnHandle srcRgnA, RgnHandle srcRgnB, RgnHandle dstRgn) -> None")},
+	{"MacXorRgn", (PyCFunction)Qd_MacXorRgn, 1,
+	 PyDoc_STR("(RgnHandle srcRgnA, RgnHandle srcRgnB, RgnHandle dstRgn) -> None")},
+	{"RectInRgn", (PyCFunction)Qd_RectInRgn, 1,
+	 PyDoc_STR("(Rect r, RgnHandle rgn) -> (Boolean _rv)")},
+	{"MacEqualRgn", (PyCFunction)Qd_MacEqualRgn, 1,
+	 PyDoc_STR("(RgnHandle rgnA, RgnHandle rgnB) -> (Boolean _rv)")},
+	{"EmptyRgn", (PyCFunction)Qd_EmptyRgn, 1,
+	 PyDoc_STR("(RgnHandle rgn) -> (Boolean _rv)")},
+	{"MacFrameRgn", (PyCFunction)Qd_MacFrameRgn, 1,
+	 PyDoc_STR("(RgnHandle rgn) -> None")},
+	{"MacPaintRgn", (PyCFunction)Qd_MacPaintRgn, 1,
+	 PyDoc_STR("(RgnHandle rgn) -> None")},
+	{"EraseRgn", (PyCFunction)Qd_EraseRgn, 1,
+	 PyDoc_STR("(RgnHandle rgn) -> None")},
+	{"MacInvertRgn", (PyCFunction)Qd_MacInvertRgn, 1,
+	 PyDoc_STR("(RgnHandle rgn) -> None")},
+	{"MacFillRgn", (PyCFunction)Qd_MacFillRgn, 1,
+	 PyDoc_STR("(RgnHandle rgn, Pattern pat) -> None")},
+	{"ScrollRect", (PyCFunction)Qd_ScrollRect, 1,
+	 PyDoc_STR("(Rect r, short dh, short dv, RgnHandle updateRgn) -> None")},
+	{"CopyBits", (PyCFunction)Qd_CopyBits, 1,
+	 PyDoc_STR("(BitMapPtr srcBits, BitMapPtr dstBits, Rect srcRect, Rect dstRect, short mode, RgnHandle maskRgn) -> None")},
+	{"CopyMask", (PyCFunction)Qd_CopyMask, 1,
+	 PyDoc_STR("(BitMapPtr srcBits, BitMapPtr maskBits, BitMapPtr dstBits, Rect srcRect, Rect maskRect, Rect dstRect) -> None")},
+	{"OpenPicture", (PyCFunction)Qd_OpenPicture, 1,
+	 PyDoc_STR("(Rect picFrame) -> (PicHandle _rv)")},
+	{"PicComment", (PyCFunction)Qd_PicComment, 1,
+	 PyDoc_STR("(short kind, short dataSize, Handle dataHandle) -> None")},
+	{"ClosePicture", (PyCFunction)Qd_ClosePicture, 1,
+	 PyDoc_STR("() -> None")},
+	{"DrawPicture", (PyCFunction)Qd_DrawPicture, 1,
+	 PyDoc_STR("(PicHandle myPicture, Rect dstRect) -> None")},
+	{"KillPicture", (PyCFunction)Qd_KillPicture, 1,
+	 PyDoc_STR("(PicHandle myPicture) -> None")},
+	{"OpenPoly", (PyCFunction)Qd_OpenPoly, 1,
+	 PyDoc_STR("() -> (PolyHandle _rv)")},
+	{"ClosePoly", (PyCFunction)Qd_ClosePoly, 1,
+	 PyDoc_STR("() -> None")},
+	{"KillPoly", (PyCFunction)Qd_KillPoly, 1,
+	 PyDoc_STR("(PolyHandle poly) -> None")},
+	{"OffsetPoly", (PyCFunction)Qd_OffsetPoly, 1,
+	 PyDoc_STR("(PolyHandle poly, short dh, short dv) -> None")},
+	{"FramePoly", (PyCFunction)Qd_FramePoly, 1,
+	 PyDoc_STR("(PolyHandle poly) -> None")},
+	{"PaintPoly", (PyCFunction)Qd_PaintPoly, 1,
+	 PyDoc_STR("(PolyHandle poly) -> None")},
+	{"ErasePoly", (PyCFunction)Qd_ErasePoly, 1,
+	 PyDoc_STR("(PolyHandle poly) -> None")},
+	{"InvertPoly", (PyCFunction)Qd_InvertPoly, 1,
+	 PyDoc_STR("(PolyHandle poly) -> None")},
+	{"FillPoly", (PyCFunction)Qd_FillPoly, 1,
+	 PyDoc_STR("(PolyHandle poly, Pattern pat) -> None")},
+	{"SetPt", (PyCFunction)Qd_SetPt, 1,
+	 PyDoc_STR("(short h, short v) -> (Point pt)")},
+	{"LocalToGlobal", (PyCFunction)Qd_LocalToGlobal, 1,
+	 PyDoc_STR("(Point pt) -> (Point pt)")},
+	{"GlobalToLocal", (PyCFunction)Qd_GlobalToLocal, 1,
+	 PyDoc_STR("(Point pt) -> (Point pt)")},
+	{"Random", (PyCFunction)Qd_Random, 1,
+	 PyDoc_STR("() -> (short _rv)")},
+	{"MacGetPixel", (PyCFunction)Qd_MacGetPixel, 1,
+	 PyDoc_STR("(short h, short v) -> (Boolean _rv)")},
+	{"ScalePt", (PyCFunction)Qd_ScalePt, 1,
+	 PyDoc_STR("(Point pt, Rect srcRect, Rect dstRect) -> (Point pt)")},
+	{"MapPt", (PyCFunction)Qd_MapPt, 1,
+	 PyDoc_STR("(Point pt, Rect srcRect, Rect dstRect) -> (Point pt)")},
+	{"MapRect", (PyCFunction)Qd_MapRect, 1,
+	 PyDoc_STR("(Rect r, Rect srcRect, Rect dstRect) -> (Rect r)")},
+	{"MapRgn", (PyCFunction)Qd_MapRgn, 1,
+	 PyDoc_STR("(RgnHandle rgn, Rect srcRect, Rect dstRect) -> None")},
+	{"MapPoly", (PyCFunction)Qd_MapPoly, 1,
+	 PyDoc_STR("(PolyHandle poly, Rect srcRect, Rect dstRect) -> None")},
+	{"StdBits", (PyCFunction)Qd_StdBits, 1,
+	 PyDoc_STR("(BitMapPtr srcBits, Rect srcRect, Rect dstRect, short mode, RgnHandle maskRgn) -> None")},
+	{"AddPt", (PyCFunction)Qd_AddPt, 1,
+	 PyDoc_STR("(Point src, Point dst) -> (Point dst)")},
+	{"EqualPt", (PyCFunction)Qd_EqualPt, 1,
+	 PyDoc_STR("(Point pt1, Point pt2) -> (Boolean _rv)")},
+	{"MacPtInRect", (PyCFunction)Qd_MacPtInRect, 1,
+	 PyDoc_STR("(Point pt, Rect r) -> (Boolean _rv)")},
+	{"Pt2Rect", (PyCFunction)Qd_Pt2Rect, 1,
+	 PyDoc_STR("(Point pt1, Point pt2) -> (Rect dstRect)")},
+	{"PtToAngle", (PyCFunction)Qd_PtToAngle, 1,
+	 PyDoc_STR("(Rect r, Point pt) -> (short angle)")},
+	{"SubPt", (PyCFunction)Qd_SubPt, 1,
+	 PyDoc_STR("(Point src, Point dst) -> (Point dst)")},
+	{"PtInRgn", (PyCFunction)Qd_PtInRgn, 1,
+	 PyDoc_STR("(Point pt, RgnHandle rgn) -> (Boolean _rv)")},
+	{"NewPixMap", (PyCFunction)Qd_NewPixMap, 1,
+	 PyDoc_STR("() -> (PixMapHandle _rv)")},
+	{"DisposePixMap", (PyCFunction)Qd_DisposePixMap, 1,
+	 PyDoc_STR("(PixMapHandle pm) -> None")},
+	{"CopyPixMap", (PyCFunction)Qd_CopyPixMap, 1,
+	 PyDoc_STR("(PixMapHandle srcPM, PixMapHandle dstPM) -> None")},
+	{"NewPixPat", (PyCFunction)Qd_NewPixPat, 1,
+	 PyDoc_STR("() -> (PixPatHandle _rv)")},
+	{"DisposePixPat", (PyCFunction)Qd_DisposePixPat, 1,
+	 PyDoc_STR("(PixPatHandle pp) -> None")},
+	{"CopyPixPat", (PyCFunction)Qd_CopyPixPat, 1,
+	 PyDoc_STR("(PixPatHandle srcPP, PixPatHandle dstPP) -> None")},
+	{"PenPixPat", (PyCFunction)Qd_PenPixPat, 1,
+	 PyDoc_STR("(PixPatHandle pp) -> None")},
+	{"BackPixPat", (PyCFunction)Qd_BackPixPat, 1,
+	 PyDoc_STR("(PixPatHandle pp) -> None")},
+	{"GetPixPat", (PyCFunction)Qd_GetPixPat, 1,
+	 PyDoc_STR("(short patID) -> (PixPatHandle _rv)")},
+	{"MakeRGBPat", (PyCFunction)Qd_MakeRGBPat, 1,
+	 PyDoc_STR("(PixPatHandle pp, RGBColor myColor) -> None")},
+	{"FillCRect", (PyCFunction)Qd_FillCRect, 1,
+	 PyDoc_STR("(Rect r, PixPatHandle pp) -> None")},
+	{"FillCOval", (PyCFunction)Qd_FillCOval, 1,
+	 PyDoc_STR("(Rect r, PixPatHandle pp) -> None")},
+	{"FillCRoundRect", (PyCFunction)Qd_FillCRoundRect, 1,
+	 PyDoc_STR("(Rect r, short ovalWidth, short ovalHeight, PixPatHandle pp) -> None")},
+	{"FillCArc", (PyCFunction)Qd_FillCArc, 1,
+	 PyDoc_STR("(Rect r, short startAngle, short arcAngle, PixPatHandle pp) -> None")},
+	{"FillCRgn", (PyCFunction)Qd_FillCRgn, 1,
+	 PyDoc_STR("(RgnHandle rgn, PixPatHandle pp) -> None")},
+	{"FillCPoly", (PyCFunction)Qd_FillCPoly, 1,
+	 PyDoc_STR("(PolyHandle poly, PixPatHandle pp) -> None")},
+	{"RGBForeColor", (PyCFunction)Qd_RGBForeColor, 1,
+	 PyDoc_STR("(RGBColor color) -> None")},
+	{"RGBBackColor", (PyCFunction)Qd_RGBBackColor, 1,
+	 PyDoc_STR("(RGBColor color) -> None")},
+	{"SetCPixel", (PyCFunction)Qd_SetCPixel, 1,
+	 PyDoc_STR("(short h, short v, RGBColor cPix) -> None")},
+	{"SetPortPix", (PyCFunction)Qd_SetPortPix, 1,
+	 PyDoc_STR("(PixMapHandle pm) -> None")},
+	{"GetCPixel", (PyCFunction)Qd_GetCPixel, 1,
+	 PyDoc_STR("(short h, short v) -> (RGBColor cPix)")},
+	{"GetForeColor", (PyCFunction)Qd_GetForeColor, 1,
+	 PyDoc_STR("() -> (RGBColor color)")},
+	{"GetBackColor", (PyCFunction)Qd_GetBackColor, 1,
+	 PyDoc_STR("() -> (RGBColor color)")},
+	{"OpColor", (PyCFunction)Qd_OpColor, 1,
+	 PyDoc_STR("(RGBColor color) -> None")},
+	{"HiliteColor", (PyCFunction)Qd_HiliteColor, 1,
+	 PyDoc_STR("(RGBColor color) -> None")},
+	{"DisposeCTable", (PyCFunction)Qd_DisposeCTable, 1,
+	 PyDoc_STR("(CTabHandle cTable) -> None")},
+	{"GetCTable", (PyCFunction)Qd_GetCTable, 1,
+	 PyDoc_STR("(short ctID) -> (CTabHandle _rv)")},
+	{"GetCCursor", (PyCFunction)Qd_GetCCursor, 1,
+	 PyDoc_STR("(short crsrID) -> (CCrsrHandle _rv)")},
+	{"SetCCursor", (PyCFunction)Qd_SetCCursor, 1,
+	 PyDoc_STR("(CCrsrHandle cCrsr) -> None")},
+	{"AllocCursor", (PyCFunction)Qd_AllocCursor, 1,
+	 PyDoc_STR("() -> None")},
+	{"DisposeCCursor", (PyCFunction)Qd_DisposeCCursor, 1,
+	 PyDoc_STR("(CCrsrHandle cCrsr) -> None")},
+	{"GetMaxDevice", (PyCFunction)Qd_GetMaxDevice, 1,
+	 PyDoc_STR("(Rect globalRect) -> (GDHandle _rv)")},
+	{"GetCTSeed", (PyCFunction)Qd_GetCTSeed, 1,
+	 PyDoc_STR("() -> (long _rv)")},
+	{"GetDeviceList", (PyCFunction)Qd_GetDeviceList, 1,
+	 PyDoc_STR("() -> (GDHandle _rv)")},
+	{"GetMainDevice", (PyCFunction)Qd_GetMainDevice, 1,
+	 PyDoc_STR("() -> (GDHandle _rv)")},
+	{"GetNextDevice", (PyCFunction)Qd_GetNextDevice, 1,
+	 PyDoc_STR("(GDHandle curDevice) -> (GDHandle _rv)")},
+	{"TestDeviceAttribute", (PyCFunction)Qd_TestDeviceAttribute, 1,
+	 PyDoc_STR("(GDHandle gdh, short attribute) -> (Boolean _rv)")},
+	{"SetDeviceAttribute", (PyCFunction)Qd_SetDeviceAttribute, 1,
+	 PyDoc_STR("(GDHandle gdh, short attribute, Boolean value) -> None")},
+	{"InitGDevice", (PyCFunction)Qd_InitGDevice, 1,
+	 PyDoc_STR("(short qdRefNum, long mode, GDHandle gdh) -> None")},
+	{"NewGDevice", (PyCFunction)Qd_NewGDevice, 1,
+	 PyDoc_STR("(short refNum, long mode) -> (GDHandle _rv)")},
+	{"DisposeGDevice", (PyCFunction)Qd_DisposeGDevice, 1,
+	 PyDoc_STR("(GDHandle gdh) -> None")},
+	{"SetGDevice", (PyCFunction)Qd_SetGDevice, 1,
+	 PyDoc_STR("(GDHandle gd) -> None")},
+	{"GetGDevice", (PyCFunction)Qd_GetGDevice, 1,
+	 PyDoc_STR("() -> (GDHandle _rv)")},
+	{"Color2Index", (PyCFunction)Qd_Color2Index, 1,
+	 PyDoc_STR("(RGBColor myColor) -> (long _rv)")},
+	{"Index2Color", (PyCFunction)Qd_Index2Color, 1,
+	 PyDoc_STR("(long index) -> (RGBColor aColor)")},
+	{"InvertColor", (PyCFunction)Qd_InvertColor, 1,
+	 PyDoc_STR("() -> (RGBColor myColor)")},
+	{"RealColor", (PyCFunction)Qd_RealColor, 1,
+	 PyDoc_STR("(RGBColor color) -> (Boolean _rv)")},
+	{"GetSubTable", (PyCFunction)Qd_GetSubTable, 1,
+	 PyDoc_STR("(CTabHandle myColors, short iTabRes, CTabHandle targetTbl) -> None")},
+	{"MakeITable", (PyCFunction)Qd_MakeITable, 1,
+	 PyDoc_STR("(CTabHandle cTabH, ITabHandle iTabH, short res) -> None")},
+	{"SetClientID", (PyCFunction)Qd_SetClientID, 1,
+	 PyDoc_STR("(short id) -> None")},
+	{"ProtectEntry", (PyCFunction)Qd_ProtectEntry, 1,
+	 PyDoc_STR("(short index, Boolean protect) -> None")},
+	{"ReserveEntry", (PyCFunction)Qd_ReserveEntry, 1,
+	 PyDoc_STR("(short index, Boolean reserve) -> None")},
+	{"QDError", (PyCFunction)Qd_QDError, 1,
+	 PyDoc_STR("() -> (short _rv)")},
+	{"CopyDeepMask", (PyCFunction)Qd_CopyDeepMask, 1,
+	 PyDoc_STR("(BitMapPtr srcBits, BitMapPtr maskBits, BitMapPtr dstBits, Rect srcRect, Rect maskRect, Rect dstRect, short mode, RgnHandle maskRgn) -> None")},
+	{"GetPattern", (PyCFunction)Qd_GetPattern, 1,
+	 PyDoc_STR("(short patternID) -> (PatHandle _rv)")},
+	{"MacGetCursor", (PyCFunction)Qd_MacGetCursor, 1,
+	 PyDoc_STR("(short cursorID) -> (CursHandle _rv)")},
+	{"GetPicture", (PyCFunction)Qd_GetPicture, 1,
+	 PyDoc_STR("(short pictureID) -> (PicHandle _rv)")},
+	{"DeltaPoint", (PyCFunction)Qd_DeltaPoint, 1,
+	 PyDoc_STR("(Point ptA, Point ptB) -> (long _rv)")},
+	{"ShieldCursor", (PyCFunction)Qd_ShieldCursor, 1,
+	 PyDoc_STR("(Rect shieldRect, Point offsetPt) -> None")},
+	{"ScreenRes", (PyCFunction)Qd_ScreenRes, 1,
+	 PyDoc_STR("() -> (short scrnHRes, short scrnVRes)")},
+	{"GetIndPattern", (PyCFunction)Qd_GetIndPattern, 1,
+	 PyDoc_STR("(short patternListID, short index) -> (Pattern thePat)")},
+	{"SlopeFromAngle", (PyCFunction)Qd_SlopeFromAngle, 1,
+	 PyDoc_STR("(short angle) -> (Fixed _rv)")},
+	{"AngleFromSlope", (PyCFunction)Qd_AngleFromSlope, 1,
+	 PyDoc_STR("(Fixed slope) -> (short _rv)")},
+	{"GetPixBounds", (PyCFunction)Qd_GetPixBounds, 1,
+	 PyDoc_STR("(PixMapHandle pixMap) -> (Rect bounds)")},
+	{"GetPixDepth", (PyCFunction)Qd_GetPixDepth, 1,
+	 PyDoc_STR("(PixMapHandle pixMap) -> (short _rv)")},
+	{"GetQDGlobalsRandomSeed", (PyCFunction)Qd_GetQDGlobalsRandomSeed, 1,
+	 PyDoc_STR("() -> (long _rv)")},
+	{"GetQDGlobalsScreenBits", (PyCFunction)Qd_GetQDGlobalsScreenBits, 1,
+	 PyDoc_STR("() -> (BitMap screenBits)")},
+	{"GetQDGlobalsArrow", (PyCFunction)Qd_GetQDGlobalsArrow, 1,
+	 PyDoc_STR("() -> (Cursor arrow)")},
+	{"GetQDGlobalsDarkGray", (PyCFunction)Qd_GetQDGlobalsDarkGray, 1,
+	 PyDoc_STR("() -> (Pattern dkGray)")},
+	{"GetQDGlobalsLightGray", (PyCFunction)Qd_GetQDGlobalsLightGray, 1,
+	 PyDoc_STR("() -> (Pattern ltGray)")},
+	{"GetQDGlobalsGray", (PyCFunction)Qd_GetQDGlobalsGray, 1,
+	 PyDoc_STR("() -> (Pattern gray)")},
+	{"GetQDGlobalsBlack", (PyCFunction)Qd_GetQDGlobalsBlack, 1,
+	 PyDoc_STR("() -> (Pattern black)")},
+	{"GetQDGlobalsWhite", (PyCFunction)Qd_GetQDGlobalsWhite, 1,
+	 PyDoc_STR("() -> (Pattern white)")},
+	{"GetQDGlobalsThePort", (PyCFunction)Qd_GetQDGlobalsThePort, 1,
+	 PyDoc_STR("() -> (CGrafPtr _rv)")},
+	{"SetQDGlobalsRandomSeed", (PyCFunction)Qd_SetQDGlobalsRandomSeed, 1,
+	 PyDoc_STR("(long randomSeed) -> None")},
+	{"SetQDGlobalsArrow", (PyCFunction)Qd_SetQDGlobalsArrow, 1,
+	 PyDoc_STR("(Cursor arrow) -> None")},
+	{"GetRegionBounds", (PyCFunction)Qd_GetRegionBounds, 1,
+	 PyDoc_STR("(RgnHandle region) -> (Rect bounds)")},
+	{"IsRegionRectangular", (PyCFunction)Qd_IsRegionRectangular, 1,
+	 PyDoc_STR("(RgnHandle region) -> (Boolean _rv)")},
+	{"CreateNewPort", (PyCFunction)Qd_CreateNewPort, 1,
+	 PyDoc_STR("() -> (CGrafPtr _rv)")},
+	{"SetQDError", (PyCFunction)Qd_SetQDError, 1,
+	 PyDoc_STR("(OSErr err) -> None")},
+	{"LMGetScrVRes", (PyCFunction)Qd_LMGetScrVRes, 1,
+	 PyDoc_STR("() -> (SInt16 _rv)")},
+	{"LMSetScrVRes", (PyCFunction)Qd_LMSetScrVRes, 1,
+	 PyDoc_STR("(SInt16 value) -> None")},
+	{"LMGetScrHRes", (PyCFunction)Qd_LMGetScrHRes, 1,
+	 PyDoc_STR("() -> (SInt16 _rv)")},
+	{"LMSetScrHRes", (PyCFunction)Qd_LMSetScrHRes, 1,
+	 PyDoc_STR("(SInt16 value) -> None")},
+	{"LMGetMainDevice", (PyCFunction)Qd_LMGetMainDevice, 1,
+	 PyDoc_STR("() -> (GDHandle _rv)")},
+	{"LMSetMainDevice", (PyCFunction)Qd_LMSetMainDevice, 1,
+	 PyDoc_STR("(GDHandle value) -> None")},
+	{"LMGetDeviceList", (PyCFunction)Qd_LMGetDeviceList, 1,
+	 PyDoc_STR("() -> (GDHandle _rv)")},
+	{"LMSetDeviceList", (PyCFunction)Qd_LMSetDeviceList, 1,
+	 PyDoc_STR("(GDHandle value) -> None")},
+	{"LMGetQDColors", (PyCFunction)Qd_LMGetQDColors, 1,
+	 PyDoc_STR("() -> (Handle _rv)")},
+	{"LMSetQDColors", (PyCFunction)Qd_LMSetQDColors, 1,
+	 PyDoc_STR("(Handle value) -> None")},
+	{"LMGetWidthListHand", (PyCFunction)Qd_LMGetWidthListHand, 1,
+	 PyDoc_STR("() -> (Handle _rv)")},
+	{"LMSetWidthListHand", (PyCFunction)Qd_LMSetWidthListHand, 1,
+	 PyDoc_STR("(Handle value) -> None")},
+	{"LMGetHiliteMode", (PyCFunction)Qd_LMGetHiliteMode, 1,
+	 PyDoc_STR("() -> (UInt8 _rv)")},
+	{"LMSetHiliteMode", (PyCFunction)Qd_LMSetHiliteMode, 1,
+	 PyDoc_STR("(UInt8 value) -> None")},
+	{"LMGetWidthTabHandle", (PyCFunction)Qd_LMGetWidthTabHandle, 1,
+	 PyDoc_STR("() -> (Handle _rv)")},
+	{"LMSetWidthTabHandle", (PyCFunction)Qd_LMSetWidthTabHandle, 1,
+	 PyDoc_STR("(Handle value) -> None")},
+	{"LMGetLastSPExtra", (PyCFunction)Qd_LMGetLastSPExtra, 1,
+	 PyDoc_STR("() -> (SInt32 _rv)")},
+	{"LMSetLastSPExtra", (PyCFunction)Qd_LMSetLastSPExtra, 1,
+	 PyDoc_STR("(SInt32 value) -> None")},
+	{"LMGetLastFOND", (PyCFunction)Qd_LMGetLastFOND, 1,
+	 PyDoc_STR("() -> (Handle _rv)")},
+	{"LMSetLastFOND", (PyCFunction)Qd_LMSetLastFOND, 1,
+	 PyDoc_STR("(Handle value) -> None")},
+	{"LMGetFractEnable", (PyCFunction)Qd_LMGetFractEnable, 1,
+	 PyDoc_STR("() -> (UInt8 _rv)")},
+	{"LMSetFractEnable", (PyCFunction)Qd_LMSetFractEnable, 1,
+	 PyDoc_STR("(UInt8 value) -> None")},
+	{"LMGetTheGDevice", (PyCFunction)Qd_LMGetTheGDevice, 1,
+	 PyDoc_STR("() -> (GDHandle _rv)")},
+	{"LMSetTheGDevice", (PyCFunction)Qd_LMSetTheGDevice, 1,
+	 PyDoc_STR("(GDHandle value) -> None")},
+	{"LMGetHiliteRGB", (PyCFunction)Qd_LMGetHiliteRGB, 1,
+	 PyDoc_STR("() -> (RGBColor hiliteRGBValue)")},
+	{"LMSetHiliteRGB", (PyCFunction)Qd_LMSetHiliteRGB, 1,
+	 PyDoc_STR("(RGBColor hiliteRGBValue) -> None")},
+	{"LMGetCursorNew", (PyCFunction)Qd_LMGetCursorNew, 1,
+	 PyDoc_STR("() -> (Boolean _rv)")},
+	{"LMSetCursorNew", (PyCFunction)Qd_LMSetCursorNew, 1,
+	 PyDoc_STR("(Boolean value) -> None")},
+	{"TextFont", (PyCFunction)Qd_TextFont, 1,
+	 PyDoc_STR("(short font) -> None")},
+	{"TextFace", (PyCFunction)Qd_TextFace, 1,
+	 PyDoc_STR("(StyleParameter face) -> None")},
+	{"TextMode", (PyCFunction)Qd_TextMode, 1,
+	 PyDoc_STR("(short mode) -> None")},
+	{"TextSize", (PyCFunction)Qd_TextSize, 1,
+	 PyDoc_STR("(short size) -> None")},
+	{"SpaceExtra", (PyCFunction)Qd_SpaceExtra, 1,
+	 PyDoc_STR("(Fixed extra) -> None")},
+	{"DrawChar", (PyCFunction)Qd_DrawChar, 1,
+	 PyDoc_STR("(CharParameter ch) -> None")},
+	{"DrawString", (PyCFunction)Qd_DrawString, 1,
+	 PyDoc_STR("(Str255 s) -> None")},
+	{"MacDrawText", (PyCFunction)Qd_MacDrawText, 1,
+	 PyDoc_STR("(Buffer textBuf, short firstByte, short byteCount) -> None")},
+	{"CharWidth", (PyCFunction)Qd_CharWidth, 1,
+	 PyDoc_STR("(CharParameter ch) -> (short _rv)")},
+	{"StringWidth", (PyCFunction)Qd_StringWidth, 1,
+	 PyDoc_STR("(Str255 s) -> (short _rv)")},
+	{"TextWidth", (PyCFunction)Qd_TextWidth, 1,
+	 PyDoc_STR("(Buffer textBuf, short firstByte, short byteCount) -> (short _rv)")},
+	{"GetFontInfo", (PyCFunction)Qd_GetFontInfo, 1,
+	 PyDoc_STR("() -> (FontInfo info)")},
+	{"CharExtra", (PyCFunction)Qd_CharExtra, 1,
+	 PyDoc_STR("(Fixed extra) -> None")},
+	{"TruncString", (PyCFunction)Qd_TruncString, 1,
+	 PyDoc_STR("(short width, Str255 theString, TruncCode truncWhere) -> (short _rv)")},
+	{"SetPort", (PyCFunction)Qd_SetPort, 1,
+	 PyDoc_STR("(GrafPtr thePort) -> None")},
+	{"GetCursor", (PyCFunction)Qd_GetCursor, 1,
+	 PyDoc_STR("(short cursorID) -> (CursHandle _rv)")},
+	{"SetCursor", (PyCFunction)Qd_SetCursor, 1,
+	 PyDoc_STR("(Cursor crsr) -> None")},
+	{"ShowCursor", (PyCFunction)Qd_ShowCursor, 1,
+	 PyDoc_STR("() -> None")},
+	{"LineTo", (PyCFunction)Qd_LineTo, 1,
+	 PyDoc_STR("(short h, short v) -> None")},
+	{"SetRect", (PyCFunction)Qd_SetRect, 1,
+	 PyDoc_STR("(short left, short top, short right, short bottom) -> (Rect r)")},
+	{"OffsetRect", (PyCFunction)Qd_OffsetRect, 1,
+	 PyDoc_STR("(Rect r, short dh, short dv) -> (Rect r)")},
+	{"InsetRect", (PyCFunction)Qd_InsetRect, 1,
+	 PyDoc_STR("(Rect r, short dh, short dv) -> (Rect r)")},
+	{"UnionRect", (PyCFunction)Qd_UnionRect, 1,
+	 PyDoc_STR("(Rect src1, Rect src2) -> (Rect dstRect)")},
+	{"EqualRect", (PyCFunction)Qd_EqualRect, 1,
+	 PyDoc_STR("(Rect rect1, Rect rect2) -> (Boolean _rv)")},
+	{"FrameRect", (PyCFunction)Qd_FrameRect, 1,
+	 PyDoc_STR("(Rect r) -> None")},
+	{"InvertRect", (PyCFunction)Qd_InvertRect, 1,
+	 PyDoc_STR("(Rect r) -> None")},
+	{"FillRect", (PyCFunction)Qd_FillRect, 1,
+	 PyDoc_STR("(Rect r, Pattern pat) -> None")},
+	{"CopyRgn", (PyCFunction)Qd_CopyRgn, 1,
+	 PyDoc_STR("(RgnHandle srcRgn, RgnHandle dstRgn) -> None")},
+	{"SetRectRgn", (PyCFunction)Qd_SetRectRgn, 1,
+	 PyDoc_STR("(RgnHandle rgn, short left, short top, short right, short bottom) -> None")},
+	{"OffsetRgn", (PyCFunction)Qd_OffsetRgn, 1,
+	 PyDoc_STR("(RgnHandle rgn, short dh, short dv) -> None")},
+	{"UnionRgn", (PyCFunction)Qd_UnionRgn, 1,
+	 PyDoc_STR("(RgnHandle srcRgnA, RgnHandle srcRgnB, RgnHandle dstRgn) -> None")},
+	{"XorRgn", (PyCFunction)Qd_XorRgn, 1,
+	 PyDoc_STR("(RgnHandle srcRgnA, RgnHandle srcRgnB, RgnHandle dstRgn) -> None")},
+	{"EqualRgn", (PyCFunction)Qd_EqualRgn, 1,
+	 PyDoc_STR("(RgnHandle rgnA, RgnHandle rgnB) -> (Boolean _rv)")},
+	{"FrameRgn", (PyCFunction)Qd_FrameRgn, 1,
+	 PyDoc_STR("(RgnHandle rgn) -> None")},
+	{"PaintRgn", (PyCFunction)Qd_PaintRgn, 1,
+	 PyDoc_STR("(RgnHandle rgn) -> None")},
+	{"InvertRgn", (PyCFunction)Qd_InvertRgn, 1,
+	 PyDoc_STR("(RgnHandle rgn) -> None")},
+	{"FillRgn", (PyCFunction)Qd_FillRgn, 1,
+	 PyDoc_STR("(RgnHandle rgn, Pattern pat) -> None")},
+	{"GetPixel", (PyCFunction)Qd_GetPixel, 1,
+	 PyDoc_STR("(short h, short v) -> (Boolean _rv)")},
+	{"PtInRect", (PyCFunction)Qd_PtInRect, 1,
+	 PyDoc_STR("(Point pt, Rect r) -> (Boolean _rv)")},
+	{"DrawText", (PyCFunction)Qd_DrawText, 1,
+	 PyDoc_STR("(Buffer textBuf, short firstByte, short byteCount) -> None")},
+	{"BitMap", (PyCFunction)Qd_BitMap, 1,
+	 PyDoc_STR("Take (string, int, Rect) argument and create BitMap")},
+	{"RawBitMap", (PyCFunction)Qd_RawBitMap, 1,
+	 PyDoc_STR("Take string BitMap and turn into BitMap object")},
+	{NULL, NULL, 0}
+};
+
+
+
+/* Like BMObj_New, but the original bitmap data structure is copied (and
+** released when the object is released)
+*/
+PyObject *BMObj_NewCopied(BitMapPtr itself)
+{
+        BitMapObject *it;
+        BitMapPtr itself_copy;
+
+        if ((itself_copy=(BitMapPtr)malloc(sizeof(BitMap))) == NULL)
+                return PyErr_NoMemory();
+        *itself_copy = *itself;
+        it = (BitMapObject *)BMObj_New(itself_copy);
+        it->referred_bitmap = itself_copy;
+        return (PyObject *)it;
+}
+
+
+
+void init_Qd(void)
+{
+	PyObject *m;
+	PyObject *d;
+
+
+
+	        PyMac_INIT_TOOLBOX_OBJECT_NEW(BitMapPtr, BMObj_New);
+	        PyMac_INIT_TOOLBOX_OBJECT_CONVERT(BitMapPtr, BMObj_Convert);
+	        PyMac_INIT_TOOLBOX_OBJECT_NEW(GrafPtr, GrafObj_New);
+	        PyMac_INIT_TOOLBOX_OBJECT_CONVERT(GrafPtr, GrafObj_Convert);
+	        PyMac_INIT_TOOLBOX_OBJECT_NEW(RGBColorPtr, QdRGB_New);
+	        PyMac_INIT_TOOLBOX_OBJECT_CONVERT(RGBColor, QdRGB_Convert);
+
+
+	m = Py_InitModule("_Qd", Qd_methods);
+	d = PyModule_GetDict(m);
+	Qd_Error = PyMac_GetOSErrException();
+	if (Qd_Error == NULL ||
+	    PyDict_SetItemString(d, "Error", Qd_Error) != 0)
+		return;
+	GrafPort_Type.ob_type = &PyType_Type;
+	if (PyType_Ready(&GrafPort_Type) < 0) return;
+	Py_INCREF(&GrafPort_Type);
+	PyModule_AddObject(m, "GrafPort", (PyObject *)&GrafPort_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&GrafPort_Type);
+	PyModule_AddObject(m, "GrafPortType", (PyObject *)&GrafPort_Type);
+	BitMap_Type.ob_type = &PyType_Type;
+	if (PyType_Ready(&BitMap_Type) < 0) return;
+	Py_INCREF(&BitMap_Type);
+	PyModule_AddObject(m, "BitMap", (PyObject *)&BitMap_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&BitMap_Type);
+	PyModule_AddObject(m, "BitMapType", (PyObject *)&BitMap_Type);
+}
+
+/* ========================= End module _Qd ========================= */
+

Added: vendor/Python/current/Mac/Modules/qd/qdedit.py
===================================================================
--- vendor/Python/current/Mac/Modules/qd/qdedit.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/qd/qdedit.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,158 @@
+f = Function(void, 'SetPort',
+        (GrafPtr, 'thePort', InMode),
+)
+functions.append(f)
+
+f = Function(CursHandle, 'GetCursor',
+    (short, 'cursorID', InMode),
+)
+functions.append(f)
+
+f = Function(void, 'SetCursor',
+    (Cursor_ptr, 'crsr', InMode),
+)
+functions.append(f)
+
+f = Function(void, 'ShowCursor',
+)
+functions.append(f)
+
+f = Function(void, 'LineTo',
+    (short, 'h', InMode),
+    (short, 'v', InMode),
+)
+functions.append(f)
+
+f = Function(void, 'SetRect',
+    (Rect, 'r', OutMode),
+    (short, 'left', InMode),
+    (short, 'top', InMode),
+    (short, 'right', InMode),
+    (short, 'bottom', InMode),
+)
+functions.append(f)
+
+f = Function(void, 'OffsetRect',
+    (Rect, 'r', InOutMode),
+    (short, 'dh', InMode),
+    (short, 'dv', InMode),
+)
+functions.append(f)
+
+f = Function(void, 'InsetRect',
+    (Rect, 'r', InOutMode),
+    (short, 'dh', InMode),
+    (short, 'dv', InMode),
+)
+functions.append(f)
+
+f = Function(void, 'UnionRect',
+    (Rect_ptr, 'src1', InMode),
+    (Rect_ptr, 'src2', InMode),
+    (Rect, 'dstRect', OutMode),
+)
+functions.append(f)
+
+f = Function(Boolean, 'EqualRect',
+    (Rect_ptr, 'rect1', InMode),
+    (Rect_ptr, 'rect2', InMode),
+)
+functions.append(f)
+
+f = Function(void, 'FrameRect',
+    (Rect_ptr, 'r', InMode),
+)
+functions.append(f)
+
+f = Function(void, 'InvertRect',
+    (Rect_ptr, 'r', InMode),
+)
+functions.append(f)
+
+f = Function(void, 'FillRect',
+    (Rect_ptr, 'r', InMode),
+    (Pattern_ptr, 'pat', InMode),
+)
+functions.append(f)
+
+f = Function(void, 'CopyRgn',
+    (RgnHandle, 'srcRgn', InMode),
+    (RgnHandle, 'dstRgn', InMode),
+)
+functions.append(f)
+
+f = Function(void, 'SetRectRgn',
+    (RgnHandle, 'rgn', InMode),
+    (short, 'left', InMode),
+    (short, 'top', InMode),
+    (short, 'right', InMode),
+    (short, 'bottom', InMode),
+)
+functions.append(f)
+
+f = Function(void, 'OffsetRgn',
+    (RgnHandle, 'rgn', InMode),
+    (short, 'dh', InMode),
+    (short, 'dv', InMode),
+)
+functions.append(f)
+
+f = Function(void, 'UnionRgn',
+    (RgnHandle, 'srcRgnA', InMode),
+    (RgnHandle, 'srcRgnB', InMode),
+    (RgnHandle, 'dstRgn', InMode),
+)
+functions.append(f)
+
+f = Function(void, 'XorRgn',
+    (RgnHandle, 'srcRgnA', InMode),
+    (RgnHandle, 'srcRgnB', InMode),
+    (RgnHandle, 'dstRgn', InMode),
+)
+functions.append(f)
+
+f = Function(Boolean, 'EqualRgn',
+    (RgnHandle, 'rgnA', InMode),
+    (RgnHandle, 'rgnB', InMode),
+)
+functions.append(f)
+
+f = Function(void, 'FrameRgn',
+    (RgnHandle, 'rgn', InMode),
+)
+functions.append(f)
+
+f = Function(void, 'PaintRgn',
+    (RgnHandle, 'rgn', InMode),
+)
+functions.append(f)
+
+f = Function(void, 'InvertRgn',
+    (RgnHandle, 'rgn', InMode),
+)
+functions.append(f)
+
+f = Function(void, 'FillRgn',
+    (RgnHandle, 'rgn', InMode),
+    (Pattern_ptr, 'pat', InMode),
+)
+functions.append(f)
+
+f = Function(Boolean, 'GetPixel',
+    (short, 'h', InMode),
+    (short, 'v', InMode),
+)
+functions.append(f)
+
+f = Function(Boolean, 'PtInRect',
+    (Point, 'pt', InMode),
+    (Rect_ptr, 'r', InMode),
+)
+functions.append(f)
+
+f = Function(void, 'DrawText',
+    (TextThingie, 'textBuf', InMode),
+    (short, 'firstByte', InMode),
+    (short, 'byteCount', InMode),
+)
+functions.append(f)

Added: vendor/Python/current/Mac/Modules/qd/qdscan.py
===================================================================
--- vendor/Python/current/Mac/Modules/qd/qdscan.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/qd/qdscan.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,235 @@
+# Scan an Apple header file, generating a Python file of generator calls.
+
+import sys
+import os
+from bgenlocations import TOOLBOXDIR, BGENDIR
+sys.path.append(BGENDIR)
+
+from scantools import Scanner
+
+def main():
+    input = "QuickDraw.h"
+    output = "qdgen.py"
+    defsoutput = TOOLBOXDIR + "QuickDraw.py"
+    scanner = MyScanner(input, output, defsoutput)
+    scanner.scan()
+    scanner.close()
+
+    # Grmpf. Universal Headers have Text-stuff in a different include file...
+    input = "QuickDrawText.h"
+    output = "@qdgentext.py"
+    defsoutput = "@QuickDrawText.py"
+    have_extra = 0
+    try:
+        scanner = MyScanner(input, output, defsoutput)
+        scanner.scan()
+        scanner.close()
+        have_extra = 1
+    except IOError:
+        pass
+    if have_extra:
+        print "=== Copying QuickDrawText stuff into main files... ==="
+        ifp = open("@qdgentext.py")
+        ofp = open("qdgen.py", "a")
+        ofp.write(ifp.read())
+        ifp.close()
+        ofp.close()
+        ifp = open("@QuickDrawText.py")
+        ofp = open(TOOLBOXDIR + "QuickDraw.py", "a")
+        ofp.write(ifp.read())
+        ifp.close()
+        ofp.close()
+
+    print "=== Testing definitions output code ==="
+    execfile(defsoutput, {}, {})
+    print "=== Done scanning and generating, now importing the generated code... ==="
+    import qdsupport
+    print "=== Done.  It's up to you to compile it now! ==="
+
+class MyScanner(Scanner):
+
+    def destination(self, type, name, arglist):
+        classname = "Function"
+        listname = "functions"
+        if arglist:
+            t, n, m = arglist[0]
+            if t in ('GrafPtr', 'CGrafPtr') and m == 'InMode':
+                classname = "Method"
+                listname = "gr_methods"
+            elif t == 'BitMapPtr' and m == 'InMode':
+                classname = "Method"
+                listname = "bm_methods"
+##                      elif t == "PolyHandle" and m == "InMode":
+##                              classname = "Method"
+##                              listname = "p_methods"
+##                      elif t == "RgnHandle" and m == "InMode":
+##                              classname = "Method"
+##                              listname = "r_methods"
+        return classname, listname
+
+
+    def writeinitialdefs(self):
+        self.defsfile.write("""
+def FOUR_CHAR_CODE(x): return x
+normal                                          = 0
+bold                                            = 1
+italic                                          = 2
+underline                                       = 4
+outline                                         = 8
+shadow                                          = 0x10
+condense                                        = 0x20
+extend                                          = 0x40
+""")
+
+    def makeblacklistnames(self):
+        return [
+                'InitGraf',
+                'StuffHex',
+                'StdLine',
+                'StdComment',
+                'StdGetPic',
+                'OpenPort',
+                'InitPort',
+                'ClosePort',
+                'OpenCPort',
+                'InitCPort',
+                'CloseCPort',
+                'BitMapToRegionGlue',
+                'StdOpcode',    # XXXX Missing from library...
+                # The following are for non-macos use:
+                'LockPortBits',
+                'UnlockPortBits',
+                'UpdatePort',
+                'GetPortNativeWindow',
+                'GetNativeWindowPort',
+                'NativeRegionToMacRegion',
+                'MacRegionToNativeRegion',
+                'GetPortHWND',
+                'GetHWNDPort',
+                'GetPICTFromDIB',
+
+                'HandleToRgn', # Funny signature
+
+                # Need Cm, which we don't want to drag in just yet
+                'OpenCursorComponent',
+                'CloseCursorComponent',
+                'SetCursorComponent',
+                'CursorComponentChanged',
+                'CursorComponentSetData',
+                ]
+
+    def makeblacklisttypes(self):
+        return [
+                "QDRegionBitsRef", # Should do this, but too lazy now.
+                'CIconHandle', # Obsolete
+                'CQDProcs',
+                'CQDProcsPtr',
+                'CSpecArray',
+                'ColorComplementProcPtr',
+                'ColorComplementUPP',
+                'ColorSearchProcPtr',
+                'ColorSearchUPP',
+                'ConstPatternParam',
+                'DeviceLoopDrawingProcPtr',
+                'DeviceLoopFlags',
+                'GrafVerb',
+                'OpenCPicParams_ptr',
+                'Ptr',
+                'QDProcs',
+                'ReqListRec',
+                'void_ptr',
+                'CustomXFerProcPtr',
+                ]
+
+    def makerepairinstructions(self):
+        return [
+                ([('void_ptr', 'textBuf', 'InMode'),
+                  ('short', 'firstByte', 'InMode'),
+                  ('short', 'byteCount', 'InMode')],
+                 [('TextThingie', '*', '*'), ('*', '*', '*'), ('*', '*', '*')]),
+
+                # GetPen and SetPt use a point-pointer as output-only:
+                ('GetPen', [('Point', '*', 'OutMode')], [('*', '*', 'OutMode')]),
+                ('SetPt', [('Point', '*', 'OutMode')], [('*', '*', 'OutMode')]),
+
+                # All others use it as input/output:
+                ([('Point', '*', 'OutMode')],
+                 [('*', '*', 'InOutMode')]),
+
+                 # InsetRect, OffsetRect
+                 ([('Rect', 'r', 'OutMode'),
+                        ('short', 'dh', 'InMode'),
+                        ('short', 'dv', 'InMode')],
+                  [('Rect', 'r', 'InOutMode'),
+                        ('short', 'dh', 'InMode'),
+                        ('short', 'dv', 'InMode')]),
+
+                 # MapRect
+                 ([('Rect', 'r', 'OutMode'),
+                        ('Rect_ptr', 'srcRect', 'InMode'),
+                        ('Rect_ptr', 'dstRect', 'InMode')],
+                  [('Rect', 'r', 'InOutMode'),
+                        ('Rect_ptr', 'srcRect', 'InMode'),
+                        ('Rect_ptr', 'dstRect', 'InMode')]),
+
+                 # CopyBits and friends
+                 ([('RgnHandle', 'maskRgn', 'InMode')],
+                  [('OptRgnHandle', 'maskRgn', 'InMode')]),
+
+                 ('QDFlushPortBuffer',
+                  [('RgnHandle', '*', 'InMode')],
+                  [('OptRgnHandle', '*', 'InMode')]),
+
+                 # Accessors with reference argument also returned.
+                 ([('Rect_ptr', 'GetPortBounds', 'ReturnMode')],
+                  [('void', '*', 'ReturnMode')]),
+
+                 ([('RGBColor_ptr', 'GetPortForeColor', 'ReturnMode')],
+                  [('void', '*', 'ReturnMode')]),
+
+                 ([('RGBColor_ptr', 'GetPortBackColor', 'ReturnMode')],
+                  [('void', '*', 'ReturnMode')]),
+
+                 ([('RGBColor_ptr', 'GetPortOpColor', 'ReturnMode')],
+                  [('void', '*', 'ReturnMode')]),
+
+                 ([('RGBColor_ptr', 'GetPortHiliteColor', 'ReturnMode')],
+                  [('void', '*', 'ReturnMode')]),
+
+                 ([('Point_ptr', 'GetPortPenSize', 'ReturnMode')],
+                  [('void', '*', 'ReturnMode')]),
+
+                 ([('Point_ptr', 'GetPortPenLocation', 'ReturnMode')],
+                  [('void', '*', 'ReturnMode')]),
+
+                 ([('Rect_ptr', 'GetPixBounds', 'ReturnMode')],
+                  [('void', '*', 'ReturnMode')]),
+
+                 ([('BitMap_ptr', 'GetQDGlobalsScreenBits', 'ReturnMode')],
+                  [('void', '*', 'ReturnMode')]),
+
+                 ([('Cursor_ptr', 'GetQDGlobalsArrow', 'ReturnMode')],
+                  [('void', '*', 'ReturnMode')]),
+
+                 ([('Rect_ptr', 'GetRegionBounds', 'ReturnMode')],
+                  [('void', '*', 'ReturnMode')]),
+
+                 ([('Pattern_ptr', '*', 'ReturnMode')],
+                  [('void', '*', 'ReturnMode')]),
+
+                 ([('Point_ptr', 'QDLocalToGlobalPoint', 'ReturnMode')],
+                  [('void', '*', 'ReturnMode')]),
+
+                 ([('Rect_ptr', 'QDLocalToGlobalRect', 'ReturnMode')],
+                  [('void', '*', 'ReturnMode')]),
+
+                 ([('Point_ptr', 'QDGlobalToLocalPoint', 'ReturnMode')],
+                  [('void', '*', 'ReturnMode')]),
+
+                 ([('Rect_ptr', 'QDGlobalToLocalRect', 'ReturnMode')],
+                  [('void', '*', 'ReturnMode')]),
+
+                ]
+
+if __name__ == "__main__":
+    main()

Added: vendor/Python/current/Mac/Modules/qd/qdsupport.py
===================================================================
--- vendor/Python/current/Mac/Modules/qd/qdsupport.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/qd/qdsupport.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,377 @@
+# This script generates a Python interface for an Apple Macintosh Manager.
+# It uses the "bgen" package to generate C code.
+# The function specifications are generated by scanning the mamager's header file,
+# using the "scantools" package (customized for this particular manager).
+
+import string
+
+# Declarations that change for each manager
+MACHEADERFILE = 'QuickDraw.h'           # The Apple header file
+MODNAME = '_Qd'                         # The name of the module
+OBJECTNAME = 'Graf'                     # The basic name of the objects used here
+
+# The following is *usually* unchanged but may still require tuning
+MODPREFIX = 'Qd'                        # The prefix for module-wide routines
+OBJECTTYPE = OBJECTNAME + 'Ptr'         # The C type used to represent them
+OBJECTPREFIX = MODPREFIX + 'Obj'        # The prefix for object methods
+INPUTFILE = string.lower(MODPREFIX) + 'gen.py' # The file generated by the scanner
+EXTRAFILE = string.lower(MODPREFIX) + 'edit.py' # A similar file but hand-made
+OUTPUTFILE = MODNAME + "module.c"       # The file generated by this program
+
+from macsupport import *
+
+# Create the type objects
+
+class TextThingieClass(FixedInputBufferType):
+    def getargsCheck(self, name):
+        Output("/* Fool compiler warnings */")
+        Output("%s__in_len__ = %s__in_len__;", name, name)
+
+    def declareSize(self, name):
+        Output("int %s__in_len__;", name)
+
+TextThingie = TextThingieClass(None)
+
+# These are temporary!
+RgnHandle = OpaqueByValueType("RgnHandle", "ResObj")
+OptRgnHandle = OpaqueByValueType("RgnHandle", "OptResObj")
+PicHandle = OpaqueByValueType("PicHandle", "ResObj")
+PolyHandle = OpaqueByValueType("PolyHandle", "ResObj")
+PixMapHandle = OpaqueByValueType("PixMapHandle", "ResObj")
+PixPatHandle = OpaqueByValueType("PixPatHandle", "ResObj")
+PatHandle = OpaqueByValueType("PatHandle", "ResObj")
+CursHandle = OpaqueByValueType("CursHandle", "ResObj")
+CCrsrHandle = OpaqueByValueType("CCrsrHandle", "ResObj")
+CIconHandle = OpaqueByValueType("CIconHandle", "ResObj")
+CTabHandle = OpaqueByValueType("CTabHandle", "ResObj")
+ITabHandle = OpaqueByValueType("ITabHandle", "ResObj")
+GDHandle = OpaqueByValueType("GDHandle", "ResObj")
+CGrafPtr = OpaqueByValueType("CGrafPtr", "GrafObj")
+GrafPtr = OpaqueByValueType("GrafPtr", "GrafObj")
+BitMap_ptr = OpaqueByValueType("BitMapPtr", "BMObj")
+const_BitMap_ptr = OpaqueByValueType("const BitMap *", "BMObj")
+BitMap = OpaqueType("BitMap", "BMObj_NewCopied", "BUG")
+RGBColor = OpaqueType('RGBColor', 'QdRGB')
+RGBColor_ptr = RGBColor
+FontInfo = OpaqueType('FontInfo', 'QdFI')
+Component = OpaqueByValueType('Component', 'CmpObj')
+ComponentInstance = OpaqueByValueType('ComponentInstance', 'CmpInstObj')
+
+Cursor = StructOutputBufferType('Cursor')
+Cursor_ptr = StructInputBufferType('Cursor')
+Pattern = StructOutputBufferType('Pattern')
+Pattern_ptr = StructInputBufferType('Pattern')
+PenState = StructOutputBufferType('PenState')
+PenState_ptr = StructInputBufferType('PenState')
+TruncCode = Type("TruncCode", "h")
+
+includestuff = includestuff + """
+#include <Carbon/Carbon.h>
+
+#ifdef USE_TOOLBOX_OBJECT_GLUE
+extern PyObject *_GrafObj_New(GrafPtr);
+extern int _GrafObj_Convert(PyObject *, GrafPtr *);
+extern PyObject *_BMObj_New(BitMapPtr);
+extern int _BMObj_Convert(PyObject *, BitMapPtr *);
+extern PyObject *_QdRGB_New(RGBColorPtr);
+extern int _QdRGB_Convert(PyObject *, RGBColorPtr);
+
+#define GrafObj_New _GrafObj_New
+#define GrafObj_Convert _GrafObj_Convert
+#define BMObj_New _BMObj_New
+#define BMObj_Convert _BMObj_Convert
+#define QdRGB_New _QdRGB_New
+#define QdRGB_Convert _QdRGB_Convert
+#endif
+
+static PyObject *BMObj_NewCopied(BitMapPtr);
+
+/*
+** Parse/generate RGB records
+*/
+PyObject *QdRGB_New(RGBColorPtr itself)
+{
+
+        return Py_BuildValue("lll", (long)itself->red, (long)itself->green, (long)itself->blue);
+}
+
+int QdRGB_Convert(PyObject *v, RGBColorPtr p_itself)
+{
+        long red, green, blue;
+
+        if( !PyArg_ParseTuple(v, "lll", &red, &green, &blue) )
+                return 0;
+        p_itself->red = (unsigned short)red;
+        p_itself->green = (unsigned short)green;
+        p_itself->blue = (unsigned short)blue;
+        return 1;
+}
+
+/*
+** Generate FontInfo records
+*/
+static
+PyObject *QdFI_New(FontInfo *itself)
+{
+
+        return Py_BuildValue("hhhh", itself->ascent, itself->descent,
+                        itself->widMax, itself->leading);
+}
+"""
+
+finalstuff = finalstuff + """
+/* Like BMObj_New, but the original bitmap data structure is copied (and
+** released when the object is released)
+*/
+PyObject *BMObj_NewCopied(BitMapPtr itself)
+{
+        BitMapObject *it;
+        BitMapPtr itself_copy;
+
+        if ((itself_copy=(BitMapPtr)malloc(sizeof(BitMap))) == NULL)
+                return PyErr_NoMemory();
+        *itself_copy = *itself;
+        it = (BitMapObject *)BMObj_New(itself_copy);
+        it->referred_bitmap = itself_copy;
+        return (PyObject *)it;
+}
+
+"""
+
+variablestuff = ""
+
+initstuff = initstuff + """
+        PyMac_INIT_TOOLBOX_OBJECT_NEW(BitMapPtr, BMObj_New);
+        PyMac_INIT_TOOLBOX_OBJECT_CONVERT(BitMapPtr, BMObj_Convert);
+        PyMac_INIT_TOOLBOX_OBJECT_NEW(GrafPtr, GrafObj_New);
+        PyMac_INIT_TOOLBOX_OBJECT_CONVERT(GrafPtr, GrafObj_Convert);
+        PyMac_INIT_TOOLBOX_OBJECT_NEW(RGBColorPtr, QdRGB_New);
+        PyMac_INIT_TOOLBOX_OBJECT_CONVERT(RGBColor, QdRGB_Convert);
+"""
+
+## not yet...
+##
+##class Region_ObjectDefinition(GlobalObjectDefinition):
+##      def outputCheckNewArg(self):
+##              Output("if (itself == NULL) return PyMac_Error(resNotFound);")
+##      def outputFreeIt(self, itselfname):
+##              Output("DisposeRegion(%s);", itselfname)
+##
+##class Polygon_ObjectDefinition(GlobalObjectDefinition):
+##      def outputCheckNewArg(self):
+##              Output("if (itself == NULL) return PyMac_Error(resNotFound);")
+##      def outputFreeIt(self, itselfname):
+##              Output("KillPoly(%s);", itselfname)
+
+class MyGRObjectDefinition(PEP253Mixin, GlobalObjectDefinition):
+    getsetlist = [
+            ('visRgn',
+            """RgnHandle h=NewRgn(); /* XXXX wrong dispose routine */
+            return Py_BuildValue("O&", ResObj_New, (Handle)GetPortVisibleRegion(self->ob_itself, h));
+            """,
+            None,
+            "Convenience attribute: return a copy of the visible region"
+            ), (
+            'clipRgn',
+            """RgnHandle h=NewRgn(); /* XXXX wrong dispose routine */
+            return Py_BuildValue("O&", ResObj_New, (Handle)GetPortClipRegion(self->ob_itself, h));
+            """,
+            None,
+            "Convenience attribute: return a copy of the clipping region"
+            )]
+    def outputCheckNewArg(self):
+        Output("if (itself == NULL) return PyMac_Error(resNotFound);")
+    def outputCheckConvertArg(self):
+        Output("#if 1")
+        OutLbrace()
+        Output("WindowRef win;")
+        OutLbrace("if (WinObj_Convert(v, &win) && v)")
+        Output("*p_itself = (GrafPtr)GetWindowPort(win);")
+        Output("return 1;")
+        OutRbrace()
+        Output("PyErr_Clear();")
+        OutRbrace()
+        Output("#else")
+        OutLbrace("if (DlgObj_Check(v))")
+        Output("DialogRef dlg = (DialogRef)((GrafPortObject *)v)->ob_itself;")
+        Output("*p_itself = (GrafPtr)GetWindowPort(GetDialogWindow(dlg));")
+        Output("return 1;")
+        OutRbrace()
+        OutLbrace("if (WinObj_Check(v))")
+        Output("WindowRef win = (WindowRef)((GrafPortObject *)v)->ob_itself;")
+        Output("*p_itself = (GrafPtr)GetWindowPort(win);")
+        Output("return 1;")
+        OutRbrace()
+        Output("#endif")
+
+class MyBMObjectDefinition(PEP253Mixin, GlobalObjectDefinition):
+    getsetlist = [
+    (
+    'baseAddr',
+    'return PyInt_FromLong((long)self->ob_itself->baseAddr);',
+    None,
+    None
+    ), (
+    'rowBytes',
+    'return PyInt_FromLong((long)self->ob_itself->rowBytes);',
+    None,
+    None
+    ), (
+    'bounds',
+    'return Py_BuildValue("O&", PyMac_BuildRect, &self->ob_itself->bounds);',
+    None,
+    None
+    ), (
+    'bitmap_data',
+    'return PyString_FromStringAndSize((char *)self->ob_itself, sizeof(BitMap));',
+    None,
+    None
+    ), (
+    'pixmap_data',
+    'return PyString_FromStringAndSize((char *)self->ob_itself, sizeof(PixMap));',
+    None,
+    None
+    )]
+    def outputCheckNewArg(self):
+        Output("if (itself == NULL) return PyMac_Error(resNotFound);")
+    def outputStructMembers(self):
+        # We need to more items: a pointer to privately allocated data
+        # and a python object we're referring to.
+        Output("%s ob_itself;", self.itselftype)
+        Output("PyObject *referred_object;")
+        Output("BitMap *referred_bitmap;")
+    def outputInitStructMembers(self):
+        Output("it->ob_itself = %sitself;", self.argref)
+        Output("it->referred_object = NULL;")
+        Output("it->referred_bitmap = NULL;")
+    def outputCleanupStructMembers(self):
+        Output("Py_XDECREF(self->referred_object);")
+        Output("if (self->referred_bitmap) free(self->referred_bitmap);")
+
+# Create the generator groups and link them
+module = MacModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff, variablestuff)
+##r_object = Region_ObjectDefinition('Region', 'QdRgn', 'RgnHandle')
+##po_object = Polygon_ObjectDefinition('Polygon', 'QdPgn', 'PolyHandle')
+##module.addobject(r_object)
+##module.addobject(po_object)
+gr_object = MyGRObjectDefinition("GrafPort", "GrafObj", "GrafPtr")
+module.addobject(gr_object)
+bm_object = MyBMObjectDefinition("BitMap", "BMObj", "BitMapPtr")
+module.addobject(bm_object)
+
+
+# Create the generator classes used to populate the lists
+Function = OSErrWeakLinkFunctionGenerator
+Method = OSErrWeakLinkMethodGenerator
+
+# Create and populate the lists
+functions = []
+gr_methods = []
+bm_methods = []
+#methods = []
+execfile(INPUTFILE)
+execfile(EXTRAFILE)
+
+# add the populated lists to the generator groups
+# (in a different wordl the scan program would generate this)
+for f in functions: module.add(f)
+for f in gr_methods: gr_object.add(f)
+for f in bm_methods: bm_object.add(f)
+
+# Manual generator: get data out of a bitmap
+getdata_body = """
+int from, length;
+char *cp;
+
+if ( !PyArg_ParseTuple(_args, "ii", &from, &length) )
+        return NULL;
+cp = _self->ob_itself->baseAddr+from;
+_res = PyString_FromStringAndSize(cp, length);
+return _res;
+"""
+f = ManualGenerator("getdata", getdata_body)
+f.docstring = lambda: """(int start, int size) -> string. Return bytes from the bitmap"""
+bm_object.add(f)
+
+# Manual generator: store data in a bitmap
+putdata_body = """
+int from, length;
+char *cp, *icp;
+
+if ( !PyArg_ParseTuple(_args, "is#", &from, &icp, &length) )
+        return NULL;
+cp = _self->ob_itself->baseAddr+from;
+memcpy(cp, icp, length);
+Py_INCREF(Py_None);
+_res = Py_None;
+return _res;
+"""
+f = ManualGenerator("putdata", putdata_body)
+f.docstring = lambda: """(int start, string data). Store bytes into the bitmap"""
+bm_object.add(f)
+
+#
+# We manually generate a routine to create a BitMap from python data.
+#
+BitMap_body = """
+BitMap *ptr;
+PyObject *source;
+Rect bounds;
+int rowbytes;
+char *data;
+
+if ( !PyArg_ParseTuple(_args, "O!iO&", &PyString_Type, &source, &rowbytes, PyMac_GetRect,
+                &bounds) )
+        return NULL;
+data = PyString_AsString(source);
+if ((ptr=(BitMap *)malloc(sizeof(BitMap))) == NULL )
+        return PyErr_NoMemory();
+ptr->baseAddr = (Ptr)data;
+ptr->rowBytes = rowbytes;
+ptr->bounds = bounds;
+if ( (_res = BMObj_New(ptr)) == NULL ) {
+        free(ptr);
+        return NULL;
+}
+((BitMapObject *)_res)->referred_object = source;
+Py_INCREF(source);
+((BitMapObject *)_res)->referred_bitmap = ptr;
+return _res;
+"""
+
+f = ManualGenerator("BitMap", BitMap_body)
+f.docstring = lambda: """Take (string, int, Rect) argument and create BitMap"""
+module.add(f)
+
+#
+# And again, for turning a correctly-formatted structure into the object
+#
+RawBitMap_body = """
+BitMap *ptr;
+PyObject *source;
+
+if ( !PyArg_ParseTuple(_args, "O!", &PyString_Type, &source) )
+        return NULL;
+if ( PyString_Size(source) != sizeof(BitMap) && PyString_Size(source) != sizeof(PixMap) ) {
+        PyErr_Format(PyExc_TypeError,
+                "Argument size was %d, should be %d (sizeof BitMap) or %d (sizeof PixMap)",
+                PyString_Size(source), sizeof(BitMap), sizeof(PixMap));
+        return NULL;
+}
+ptr = (BitMapPtr)PyString_AsString(source);
+if ( (_res = BMObj_New(ptr)) == NULL ) {
+        return NULL;
+}
+((BitMapObject *)_res)->referred_object = source;
+Py_INCREF(source);
+return _res;
+"""
+
+f = ManualGenerator("RawBitMap", RawBitMap_body)
+f.docstring = lambda: """Take string BitMap and turn into BitMap object"""
+module.add(f)
+
+# generate output (open the output file as late as possible)
+SetOutputFileName(OUTPUTFILE)
+module.generate()
+SetOutputFile() # Close it

Added: vendor/Python/current/Mac/Modules/qdoffs/_Qdoffsmodule.c
===================================================================
--- vendor/Python/current/Mac/Modules/qdoffs/_Qdoffsmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/qdoffs/_Qdoffsmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,714 @@
+
+/* ========================= Module _Qdoffs ========================= */
+
+#include "Python.h"
+
+
+
+#include "pymactoolbox.h"
+
+/* Macro to test whether a weak-loaded CFM function exists */
+#define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL )  {\
+        PyErr_SetString(PyExc_NotImplementedError, \
+        "Not available in this shared library/OS version"); \
+        return NULL; \
+    }} while(0)
+
+
+#include <Carbon/Carbon.h>
+
+#ifdef USE_TOOLBOX_OBJECT_GLUE
+extern PyObject *_GWorldObj_New(GWorldPtr);
+extern int _GWorldObj_Convert(PyObject *, GWorldPtr *);
+
+#define GWorldObj_New _GWorldObj_New
+#define GWorldObj_Convert _GWorldObj_Convert
+#endif
+
+#define as_GrafPtr(gworld) ((GrafPtr)(gworld))
+
+
+static PyObject *Qdoffs_Error;
+
+/* ----------------------- Object type GWorld ----------------------- */
+
+PyTypeObject GWorld_Type;
+
+#define GWorldObj_Check(x) ((x)->ob_type == &GWorld_Type || PyObject_TypeCheck((x), &GWorld_Type))
+
+typedef struct GWorldObject {
+	PyObject_HEAD
+	GWorldPtr ob_itself;
+} GWorldObject;
+
+PyObject *GWorldObj_New(GWorldPtr itself)
+{
+	GWorldObject *it;
+	if (itself == NULL) return PyMac_Error(resNotFound);
+	it = PyObject_NEW(GWorldObject, &GWorld_Type);
+	if (it == NULL) return NULL;
+	it->ob_itself = itself;
+	return (PyObject *)it;
+}
+
+int GWorldObj_Convert(PyObject *v, GWorldPtr *p_itself)
+{
+	if (!GWorldObj_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "GWorld required");
+		return 0;
+	}
+	*p_itself = ((GWorldObject *)v)->ob_itself;
+	return 1;
+}
+
+static void GWorldObj_dealloc(GWorldObject *self)
+{
+	DisposeGWorld(self->ob_itself);
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *GWorldObj_GetGWorldDevice(GWorldObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	GDHandle _rv;
+#ifndef GetGWorldDevice
+	PyMac_PRECHECK(GetGWorldDevice);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetGWorldDevice(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *GWorldObj_GetGWorldPixMap(GWorldObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PixMapHandle _rv;
+#ifndef GetGWorldPixMap
+	PyMac_PRECHECK(GetGWorldPixMap);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetGWorldPixMap(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *GWorldObj_as_GrafPtr(GWorldObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	GrafPtr _rv;
+#ifndef as_GrafPtr
+	PyMac_PRECHECK(as_GrafPtr);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = as_GrafPtr(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     GrafObj_New, _rv);
+	return _res;
+}
+
+static PyMethodDef GWorldObj_methods[] = {
+	{"GetGWorldDevice", (PyCFunction)GWorldObj_GetGWorldDevice, 1,
+	 PyDoc_STR("() -> (GDHandle _rv)")},
+	{"GetGWorldPixMap", (PyCFunction)GWorldObj_GetGWorldPixMap, 1,
+	 PyDoc_STR("() -> (PixMapHandle _rv)")},
+	{"as_GrafPtr", (PyCFunction)GWorldObj_as_GrafPtr, 1,
+	 PyDoc_STR("() -> (GrafPtr _rv)")},
+	{NULL, NULL, 0}
+};
+
+#define GWorldObj_getsetlist NULL
+
+
+#define GWorldObj_compare NULL
+
+#define GWorldObj_repr NULL
+
+#define GWorldObj_hash NULL
+#define GWorldObj_tp_init 0
+
+#define GWorldObj_tp_alloc PyType_GenericAlloc
+
+static PyObject *GWorldObj_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *_self;
+	GWorldPtr itself;
+	char *kw[] = {"itself", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, GWorldObj_Convert, &itself)) return NULL;
+	if ((_self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	((GWorldObject *)_self)->ob_itself = itself;
+	return _self;
+}
+
+#define GWorldObj_tp_free PyObject_Del
+
+
+PyTypeObject GWorld_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"_Qdoffs.GWorld", /*tp_name*/
+	sizeof(GWorldObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) GWorldObj_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) GWorldObj_compare, /*tp_compare*/
+	(reprfunc) GWorldObj_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) GWorldObj_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	GWorldObj_methods, /* tp_methods */
+	0, /*tp_members*/
+	GWorldObj_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	GWorldObj_tp_init, /* tp_init */
+	GWorldObj_tp_alloc, /* tp_alloc */
+	GWorldObj_tp_new, /* tp_new */
+	GWorldObj_tp_free, /* tp_free */
+};
+
+/* --------------------- End object type GWorld --------------------- */
+
+
+static PyObject *Qdoffs_NewGWorld(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	QDErr _err;
+	GWorldPtr offscreenGWorld;
+	short PixelDepth;
+	Rect boundsRect;
+	CTabHandle cTable;
+	GDHandle aGDevice;
+	GWorldFlags flags;
+#ifndef NewGWorld
+	PyMac_PRECHECK(NewGWorld);
+#endif
+	if (!PyArg_ParseTuple(_args, "hO&O&O&l",
+	                      &PixelDepth,
+	                      PyMac_GetRect, &boundsRect,
+	                      OptResObj_Convert, &cTable,
+	                      OptResObj_Convert, &aGDevice,
+	                      &flags))
+		return NULL;
+	_err = NewGWorld(&offscreenGWorld,
+	                 PixelDepth,
+	                 &boundsRect,
+	                 cTable,
+	                 aGDevice,
+	                 flags);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     GWorldObj_New, offscreenGWorld);
+	return _res;
+}
+
+static PyObject *Qdoffs_LockPixels(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	PixMapHandle pm;
+#ifndef LockPixels
+	PyMac_PRECHECK(LockPixels);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &pm))
+		return NULL;
+	_rv = LockPixels(pm);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qdoffs_UnlockPixels(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PixMapHandle pm;
+#ifndef UnlockPixels
+	PyMac_PRECHECK(UnlockPixels);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &pm))
+		return NULL;
+	UnlockPixels(pm);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qdoffs_UpdateGWorld(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	GWorldFlags _rv;
+	GWorldPtr offscreenGWorld;
+	short pixelDepth;
+	Rect boundsRect;
+	CTabHandle cTable;
+	GDHandle aGDevice;
+	GWorldFlags flags;
+#ifndef UpdateGWorld
+	PyMac_PRECHECK(UpdateGWorld);
+#endif
+	if (!PyArg_ParseTuple(_args, "hO&O&O&l",
+	                      &pixelDepth,
+	                      PyMac_GetRect, &boundsRect,
+	                      OptResObj_Convert, &cTable,
+	                      OptResObj_Convert, &aGDevice,
+	                      &flags))
+		return NULL;
+	_rv = UpdateGWorld(&offscreenGWorld,
+	                   pixelDepth,
+	                   &boundsRect,
+	                   cTable,
+	                   aGDevice,
+	                   flags);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     GWorldObj_New, offscreenGWorld);
+	return _res;
+}
+
+static PyObject *Qdoffs_GetGWorld(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CGrafPtr port;
+	GDHandle gdh;
+#ifndef GetGWorld
+	PyMac_PRECHECK(GetGWorld);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	GetGWorld(&port,
+	          &gdh);
+	_res = Py_BuildValue("O&O&",
+	                     GrafObj_New, port,
+	                     ResObj_New, gdh);
+	return _res;
+}
+
+static PyObject *Qdoffs_SetGWorld(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CGrafPtr port;
+	GDHandle gdh;
+#ifndef SetGWorld
+	PyMac_PRECHECK(SetGWorld);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      GrafObj_Convert, &port,
+	                      OptResObj_Convert, &gdh))
+		return NULL;
+	SetGWorld(port,
+	          gdh);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qdoffs_CTabChanged(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CTabHandle ctab;
+#ifndef CTabChanged
+	PyMac_PRECHECK(CTabChanged);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      OptResObj_Convert, &ctab))
+		return NULL;
+	CTabChanged(ctab);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qdoffs_PixPatChanged(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PixPatHandle ppat;
+#ifndef PixPatChanged
+	PyMac_PRECHECK(PixPatChanged);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &ppat))
+		return NULL;
+	PixPatChanged(ppat);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qdoffs_PortChanged(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	GrafPtr port;
+#ifndef PortChanged
+	PyMac_PRECHECK(PortChanged);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      GrafObj_Convert, &port))
+		return NULL;
+	PortChanged(port);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qdoffs_GDeviceChanged(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	GDHandle gdh;
+#ifndef GDeviceChanged
+	PyMac_PRECHECK(GDeviceChanged);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      OptResObj_Convert, &gdh))
+		return NULL;
+	GDeviceChanged(gdh);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qdoffs_AllowPurgePixels(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PixMapHandle pm;
+#ifndef AllowPurgePixels
+	PyMac_PRECHECK(AllowPurgePixels);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &pm))
+		return NULL;
+	AllowPurgePixels(pm);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qdoffs_NoPurgePixels(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PixMapHandle pm;
+#ifndef NoPurgePixels
+	PyMac_PRECHECK(NoPurgePixels);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &pm))
+		return NULL;
+	NoPurgePixels(pm);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qdoffs_GetPixelsState(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	GWorldFlags _rv;
+	PixMapHandle pm;
+#ifndef GetPixelsState
+	PyMac_PRECHECK(GetPixelsState);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &pm))
+		return NULL;
+	_rv = GetPixelsState(pm);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qdoffs_SetPixelsState(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PixMapHandle pm;
+	GWorldFlags state;
+#ifndef SetPixelsState
+	PyMac_PRECHECK(SetPixelsState);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      ResObj_Convert, &pm,
+	                      &state))
+		return NULL;
+	SetPixelsState(pm,
+	               state);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qdoffs_GetPixRowBytes(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long _rv;
+	PixMapHandle pm;
+#ifndef GetPixRowBytes
+	PyMac_PRECHECK(GetPixRowBytes);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &pm))
+		return NULL;
+	_rv = GetPixRowBytes(pm);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qdoffs_NewScreenBuffer(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	QDErr _err;
+	Rect globalRect;
+	Boolean purgeable;
+	GDHandle gdh;
+	PixMapHandle offscreenPixMap;
+#ifndef NewScreenBuffer
+	PyMac_PRECHECK(NewScreenBuffer);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&b",
+	                      PyMac_GetRect, &globalRect,
+	                      &purgeable))
+		return NULL;
+	_err = NewScreenBuffer(&globalRect,
+	                       purgeable,
+	                       &gdh,
+	                       &offscreenPixMap);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&O&",
+	                     ResObj_New, gdh,
+	                     ResObj_New, offscreenPixMap);
+	return _res;
+}
+
+static PyObject *Qdoffs_DisposeScreenBuffer(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PixMapHandle offscreenPixMap;
+#ifndef DisposeScreenBuffer
+	PyMac_PRECHECK(DisposeScreenBuffer);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &offscreenPixMap))
+		return NULL;
+	DisposeScreenBuffer(offscreenPixMap);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qdoffs_QDDone(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	GrafPtr port;
+#ifndef QDDone
+	PyMac_PRECHECK(QDDone);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      GrafObj_Convert, &port))
+		return NULL;
+	_rv = QDDone(port);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qdoffs_OffscreenVersion(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long _rv;
+#ifndef OffscreenVersion
+	PyMac_PRECHECK(OffscreenVersion);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = OffscreenVersion();
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qdoffs_NewTempScreenBuffer(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	QDErr _err;
+	Rect globalRect;
+	Boolean purgeable;
+	GDHandle gdh;
+	PixMapHandle offscreenPixMap;
+#ifndef NewTempScreenBuffer
+	PyMac_PRECHECK(NewTempScreenBuffer);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&b",
+	                      PyMac_GetRect, &globalRect,
+	                      &purgeable))
+		return NULL;
+	_err = NewTempScreenBuffer(&globalRect,
+	                           purgeable,
+	                           &gdh,
+	                           &offscreenPixMap);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&O&",
+	                     ResObj_New, gdh,
+	                     ResObj_New, offscreenPixMap);
+	return _res;
+}
+
+static PyObject *Qdoffs_PixMap32Bit(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	PixMapHandle pmHandle;
+#ifndef PixMap32Bit
+	PyMac_PRECHECK(PixMap32Bit);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &pmHandle))
+		return NULL;
+	_rv = PixMap32Bit(pmHandle);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qdoffs_GetPixMapBytes(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+
+	PixMapHandle pm;
+	int from, length;
+	char *cp;
+
+	if ( !PyArg_ParseTuple(_args, "O&ii", ResObj_Convert, &pm, &from, &length) )
+	        return NULL;
+	cp = GetPixBaseAddr(pm)+from;
+	_res = PyString_FromStringAndSize(cp, length);
+	return _res;
+
+}
+
+static PyObject *Qdoffs_PutPixMapBytes(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+
+	PixMapHandle pm;
+	int from, length;
+	char *cp, *icp;
+
+	if ( !PyArg_ParseTuple(_args, "O&is#", ResObj_Convert, &pm, &from, &icp, &length) )
+	        return NULL;
+	cp = GetPixBaseAddr(pm)+from;
+	memcpy(cp, icp, length);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+
+}
+
+static PyMethodDef Qdoffs_methods[] = {
+	{"NewGWorld", (PyCFunction)Qdoffs_NewGWorld, 1,
+	 PyDoc_STR("(short PixelDepth, Rect boundsRect, CTabHandle cTable, GDHandle aGDevice, GWorldFlags flags) -> (GWorldPtr offscreenGWorld)")},
+	{"LockPixels", (PyCFunction)Qdoffs_LockPixels, 1,
+	 PyDoc_STR("(PixMapHandle pm) -> (Boolean _rv)")},
+	{"UnlockPixels", (PyCFunction)Qdoffs_UnlockPixels, 1,
+	 PyDoc_STR("(PixMapHandle pm) -> None")},
+	{"UpdateGWorld", (PyCFunction)Qdoffs_UpdateGWorld, 1,
+	 PyDoc_STR("(short pixelDepth, Rect boundsRect, CTabHandle cTable, GDHandle aGDevice, GWorldFlags flags) -> (GWorldFlags _rv, GWorldPtr offscreenGWorld)")},
+	{"GetGWorld", (PyCFunction)Qdoffs_GetGWorld, 1,
+	 PyDoc_STR("() -> (CGrafPtr port, GDHandle gdh)")},
+	{"SetGWorld", (PyCFunction)Qdoffs_SetGWorld, 1,
+	 PyDoc_STR("(CGrafPtr port, GDHandle gdh) -> None")},
+	{"CTabChanged", (PyCFunction)Qdoffs_CTabChanged, 1,
+	 PyDoc_STR("(CTabHandle ctab) -> None")},
+	{"PixPatChanged", (PyCFunction)Qdoffs_PixPatChanged, 1,
+	 PyDoc_STR("(PixPatHandle ppat) -> None")},
+	{"PortChanged", (PyCFunction)Qdoffs_PortChanged, 1,
+	 PyDoc_STR("(GrafPtr port) -> None")},
+	{"GDeviceChanged", (PyCFunction)Qdoffs_GDeviceChanged, 1,
+	 PyDoc_STR("(GDHandle gdh) -> None")},
+	{"AllowPurgePixels", (PyCFunction)Qdoffs_AllowPurgePixels, 1,
+	 PyDoc_STR("(PixMapHandle pm) -> None")},
+	{"NoPurgePixels", (PyCFunction)Qdoffs_NoPurgePixels, 1,
+	 PyDoc_STR("(PixMapHandle pm) -> None")},
+	{"GetPixelsState", (PyCFunction)Qdoffs_GetPixelsState, 1,
+	 PyDoc_STR("(PixMapHandle pm) -> (GWorldFlags _rv)")},
+	{"SetPixelsState", (PyCFunction)Qdoffs_SetPixelsState, 1,
+	 PyDoc_STR("(PixMapHandle pm, GWorldFlags state) -> None")},
+	{"GetPixRowBytes", (PyCFunction)Qdoffs_GetPixRowBytes, 1,
+	 PyDoc_STR("(PixMapHandle pm) -> (long _rv)")},
+	{"NewScreenBuffer", (PyCFunction)Qdoffs_NewScreenBuffer, 1,
+	 PyDoc_STR("(Rect globalRect, Boolean purgeable) -> (GDHandle gdh, PixMapHandle offscreenPixMap)")},
+	{"DisposeScreenBuffer", (PyCFunction)Qdoffs_DisposeScreenBuffer, 1,
+	 PyDoc_STR("(PixMapHandle offscreenPixMap) -> None")},
+	{"QDDone", (PyCFunction)Qdoffs_QDDone, 1,
+	 PyDoc_STR("(GrafPtr port) -> (Boolean _rv)")},
+	{"OffscreenVersion", (PyCFunction)Qdoffs_OffscreenVersion, 1,
+	 PyDoc_STR("() -> (long _rv)")},
+	{"NewTempScreenBuffer", (PyCFunction)Qdoffs_NewTempScreenBuffer, 1,
+	 PyDoc_STR("(Rect globalRect, Boolean purgeable) -> (GDHandle gdh, PixMapHandle offscreenPixMap)")},
+	{"PixMap32Bit", (PyCFunction)Qdoffs_PixMap32Bit, 1,
+	 PyDoc_STR("(PixMapHandle pmHandle) -> (Boolean _rv)")},
+	{"GetPixMapBytes", (PyCFunction)Qdoffs_GetPixMapBytes, 1,
+	 PyDoc_STR("(pixmap, int start, int size) -> string. Return bytes from the pixmap")},
+	{"PutPixMapBytes", (PyCFunction)Qdoffs_PutPixMapBytes, 1,
+	 PyDoc_STR("(pixmap, int start, string data). Store bytes into the pixmap")},
+	{NULL, NULL, 0}
+};
+
+
+
+
+void init_Qdoffs(void)
+{
+	PyObject *m;
+	PyObject *d;
+
+
+
+	        PyMac_INIT_TOOLBOX_OBJECT_NEW(GWorldPtr, GWorldObj_New);
+	        PyMac_INIT_TOOLBOX_OBJECT_CONVERT(GWorldPtr, GWorldObj_Convert);
+
+
+	m = Py_InitModule("_Qdoffs", Qdoffs_methods);
+	d = PyModule_GetDict(m);
+	Qdoffs_Error = PyMac_GetOSErrException();
+	if (Qdoffs_Error == NULL ||
+	    PyDict_SetItemString(d, "Error", Qdoffs_Error) != 0)
+		return;
+	GWorld_Type.ob_type = &PyType_Type;
+	if (PyType_Ready(&GWorld_Type) < 0) return;
+	Py_INCREF(&GWorld_Type);
+	PyModule_AddObject(m, "GWorld", (PyObject *)&GWorld_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&GWorld_Type);
+	PyModule_AddObject(m, "GWorldType", (PyObject *)&GWorld_Type);
+}
+
+/* ======================= End module _Qdoffs ======================= */
+

Added: vendor/Python/current/Mac/Modules/qdoffs/qdoffsscan.py
===================================================================
--- vendor/Python/current/Mac/Modules/qdoffs/qdoffsscan.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/qdoffs/qdoffsscan.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,66 @@
+# Scan an Apple header file, generating a Python file of generator calls.
+import sys
+import os
+from bgenlocations import TOOLBOXDIR, BGENDIR
+sys.path.append(BGENDIR)
+
+from scantools import Scanner
+
+def main():
+    input = "QDOffscreen.h"
+    output = "qdoffsgen.py"
+    defsoutput = TOOLBOXDIR + "QDOffscreen.py"
+    scanner = MyScanner(input, output, defsoutput)
+    scanner.scan()
+    scanner.close()
+    print "=== Testing definitions output code ==="
+    execfile(defsoutput, {}, {})
+    print "=== Done scanning and generating, now importing the generated code... ==="
+    import qdoffssupport
+    print "=== Done.  It's up to you to compile it now! ==="
+
+class MyScanner(Scanner):
+
+    def destination(self, type, name, arglist):
+        classname = "Function"
+        listname = "functions"
+        if arglist:
+            t, n, m = arglist[0]
+            if t == "GWorldPtr" and m in ("InMode", "InOutMode"):
+                classname = "Method"
+                listname = "methods"
+        return classname, listname
+
+    def writeinitialdefs(self):
+        self.defsfile.write("def FOUR_CHAR_CODE(x): return x\n")
+
+    def makeblacklistnames(self):
+        return [
+                'DisposeGWorld', # Implied when the object is deleted
+                'NewGWorldFromHBITMAP', # Don't know what the args do
+                'GetGDeviceAttributes', # Windows-only
+                ]
+
+    def makeblacklisttypes(self):
+        return [
+                "void_ptr",             # GetGDeviceSurface, blacklisted for now
+                "Ptr",                  # Again, for now (array is probably ok here)
+                ]
+
+    def makerepairinstructions(self):
+        return [
+
+##                      ("UpdateGWorld",
+##                       [("GWorldPtr", "*", "OutMode")],
+##                       [("*", "*", "InOutMode")]),
+
+                # This one is incorrect: we say that all input gdevices are
+                # optional, but some are not. Most are, however, so users passing
+                # None for non-optional gdevices will get a qd error, I guess, in
+                # stead of a python argument error.
+                ([("GDHandle", "*", "InMode")],
+                 [("OptGDHandle", "*", "InMode")]),
+                ]
+
+if __name__ == "__main__":
+    main()

Added: vendor/Python/current/Mac/Modules/qdoffs/qdoffssupport.py
===================================================================
--- vendor/Python/current/Mac/Modules/qdoffs/qdoffssupport.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/qdoffs/qdoffssupport.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,139 @@
+# This script generates a Python interface for an Apple Macintosh Manager.
+# It uses the "bgen" package to generate C code.
+# The function specifications are generated by scanning the mamager's header file,
+# using the "scantools" package (customized for this particular manager).
+
+import string
+
+# Declarations that change for each manager
+MACHEADERFILE = 'QDOffscreen.h'         # The Apple header file
+MODNAME = '_Qdoffs'                             # The name of the module
+OBJECTNAME = 'GWorld'                   # The basic name of the objects used here
+
+# The following is *usually* unchanged but may still require tuning
+MODPREFIX = 'Qdoffs'                    # The prefix for module-wide routines
+OBJECTTYPE = OBJECTNAME + 'Ptr'         # The C type used to represent them
+OBJECTPREFIX = OBJECTNAME + 'Obj'       # The prefix for object methods
+INPUTFILE = string.lower(MODPREFIX) + 'gen.py' # The file generated by the scanner
+#EDITFILE = string.lower(MODPREFIX) + 'edit.py' # The manual definitions
+OUTPUTFILE = MODNAME + "module.c"       # The file generated by this program
+
+from macsupport import *
+
+# Create the type objects
+
+GWorldPtr = OpaqueByValueType(OBJECTTYPE, OBJECTPREFIX)
+GWorldFlags = Type("GWorldFlags", "l")
+GDHandle = OpaqueByValueType("GDHandle", "ResObj")
+OptGDHandle = OpaqueByValueType("GDHandle", "OptResObj")
+CTabHandle = OpaqueByValueType("CTabHandle", "OptResObj")
+PixPatHandle = OpaqueByValueType("PixPatHandle", "ResObj")
+PixMapHandle = OpaqueByValueType("PixMapHandle", "ResObj")
+CGrafPtr = OpaqueByValueType("CGrafPtr", "GrafObj")
+GrafPtr = OpaqueByValueType("GrafPtr", "GrafObj")
+QDErr = OSErrType("QDErr", 'h')
+
+includestuff = includestuff + """
+#include <Carbon/Carbon.h>
+
+#ifdef USE_TOOLBOX_OBJECT_GLUE
+extern PyObject *_GWorldObj_New(GWorldPtr);
+extern int _GWorldObj_Convert(PyObject *, GWorldPtr *);
+
+#define GWorldObj_New _GWorldObj_New
+#define GWorldObj_Convert _GWorldObj_Convert
+#endif
+
+#define as_GrafPtr(gworld) ((GrafPtr)(gworld))
+
+"""
+
+initstuff = initstuff + """
+        PyMac_INIT_TOOLBOX_OBJECT_NEW(GWorldPtr, GWorldObj_New);
+        PyMac_INIT_TOOLBOX_OBJECT_CONVERT(GWorldPtr, GWorldObj_Convert);
+"""
+
+class MyObjectDefinition(PEP253Mixin, GlobalObjectDefinition):
+    # XXXX Should inherit from GrafPtr?
+    def outputCheckNewArg(self):
+        Output("if (itself == NULL) return PyMac_Error(resNotFound);")
+##      def outputInitStructMembers(self):
+##              GlobalObjectDefinition.outputInitStructMembers(self)
+##              Output("SetWRefCon(itself, (long)it);")
+##      def outputCheckConvertArg(self):
+##              OutLbrace("if (DlgObj_Check(v))")
+##              Output("*p_itself = ((WindowObject *)v)->ob_itself;")
+##              Output("return 1;")
+##              OutRbrace()
+##              Out("""
+##              if (v == Py_None) { *p_itself = NULL; return 1; }
+##              if (PyInt_Check(v)) { *p_itself = (WindowPtr)PyInt_AsLong(v); return 1; }
+##              """)
+    def outputFreeIt(self, itselfname):
+        Output("DisposeGWorld(%s);", itselfname)
+# From here on it's basically all boiler plate...
+
+# Create the generator groups and link them
+module = MacModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff)
+object = MyObjectDefinition(OBJECTNAME, OBJECTPREFIX, OBJECTTYPE)
+module.addobject(object)
+
+
+# Create the generator classes used to populate the lists
+Function = OSErrWeakLinkFunctionGenerator
+Method = OSErrWeakLinkMethodGenerator
+
+# Create and populate the lists
+functions = []
+methods = []
+execfile(INPUTFILE)
+
+# A method to convert a GWorldPtr to a GrafPtr
+f = Method(GrafPtr, 'as_GrafPtr', (GWorldPtr, 'p', InMode))
+methods.append(f)
+
+#
+# Manual generator: get data out of a pixmap
+pixmapgetbytes_body = """
+PixMapHandle pm;
+int from, length;
+char *cp;
+
+if ( !PyArg_ParseTuple(_args, "O&ii", ResObj_Convert, &pm, &from, &length) )
+        return NULL;
+cp = GetPixBaseAddr(pm)+from;
+_res = PyString_FromStringAndSize(cp, length);
+return _res;
+"""
+f = ManualGenerator("GetPixMapBytes", pixmapgetbytes_body)
+f.docstring = lambda: """(pixmap, int start, int size) -> string. Return bytes from the pixmap"""
+functions.append(f)
+
+# Manual generator: store data in a pixmap
+pixmapputbytes_body = """
+PixMapHandle pm;
+int from, length;
+char *cp, *icp;
+
+if ( !PyArg_ParseTuple(_args, "O&is#", ResObj_Convert, &pm, &from, &icp, &length) )
+        return NULL;
+cp = GetPixBaseAddr(pm)+from;
+memcpy(cp, icp, length);
+Py_INCREF(Py_None);
+_res = Py_None;
+return _res;
+"""
+f = ManualGenerator("PutPixMapBytes", pixmapputbytes_body)
+f.docstring = lambda: """(pixmap, int start, string data). Store bytes into the pixmap"""
+functions.append(f)
+
+# add the populated lists to the generator groups
+# (in a different wordl the scan program would generate this)
+for f in functions: module.add(f)
+for f in methods: object.add(f)
+
+
+
+# generate output (open the output file as late as possible)
+SetOutputFileName(OUTPUTFILE)
+module.generate()

Added: vendor/Python/current/Mac/Modules/qt/_Qtmodule.c
===================================================================
--- vendor/Python/current/Mac/Modules/qt/_Qtmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/qt/_Qtmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,28083 @@
+
+/* =========================== Module _Qt =========================== */
+
+#include "Python.h"
+
+
+
+#include "pymactoolbox.h"
+
+/* Macro to test whether a weak-loaded CFM function exists */
+#define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL )  {\
+        PyErr_SetString(PyExc_NotImplementedError, \
+        "Not available in this shared library/OS version"); \
+        return NULL; \
+    }} while(0)
+
+
+#include <QuickTime/QuickTime.h>
+
+
+#ifdef USE_TOOLBOX_OBJECT_GLUE
+extern PyObject *_TrackObj_New(Track);
+extern int _TrackObj_Convert(PyObject *, Track *);
+extern PyObject *_MovieObj_New(Movie);
+extern int _MovieObj_Convert(PyObject *, Movie *);
+extern PyObject *_MovieCtlObj_New(MovieController);
+extern int _MovieCtlObj_Convert(PyObject *, MovieController *);
+extern PyObject *_TimeBaseObj_New(TimeBase);
+extern int _TimeBaseObj_Convert(PyObject *, TimeBase *);
+extern PyObject *_UserDataObj_New(UserData);
+extern int _UserDataObj_Convert(PyObject *, UserData *);
+extern PyObject *_MediaObj_New(Media);
+extern int _MediaObj_Convert(PyObject *, Media *);
+
+#define TrackObj_New _TrackObj_New
+#define TrackObj_Convert _TrackObj_Convert
+#define MovieObj_New _MovieObj_New
+#define MovieObj_Convert _MovieObj_Convert
+#define MovieCtlObj_New _MovieCtlObj_New
+#define MovieCtlObj_Convert _MovieCtlObj_Convert
+#define TimeBaseObj_New _TimeBaseObj_New
+#define TimeBaseObj_Convert _TimeBaseObj_Convert
+#define UserDataObj_New _UserDataObj_New
+#define UserDataObj_Convert _UserDataObj_Convert
+#define MediaObj_New _MediaObj_New
+#define MediaObj_Convert _MediaObj_Convert
+#endif
+
+/* Macro to allow us to GetNextInterestingTime without duration */
+#define GetMediaNextInterestingTimeOnly(media, flags, time, rate, rv)                         GetMediaNextInterestingTime(media, flags, time, rate, rv, NULL)
+
+/*
+** Parse/generate time records
+*/
+static PyObject *
+QtTimeRecord_New(TimeRecord *itself)
+{
+        if (itself->base)
+                return Py_BuildValue("O&lO&", PyMac_Buildwide, &itself->value, itself->scale,
+                        TimeBaseObj_New, itself->base);
+        else
+                return  Py_BuildValue("O&lO", PyMac_Buildwide, &itself->value, itself->scale,
+                        Py_None);
+}
+
+static int
+QtTimeRecord_Convert(PyObject *v, TimeRecord *p_itself)
+{
+        PyObject *base = NULL;
+        if( !PyArg_ParseTuple(v, "O&l|O", PyMac_Getwide, &p_itself->value, &p_itself->scale,
+                        &base) )
+                return 0;
+        if ( base == NULL || base == Py_None )
+                p_itself->base = NULL;
+        else
+                if ( !TimeBaseObj_Convert(base, &p_itself->base) )
+                        return 0;
+        return 1;
+}
+
+static int
+QtMusicMIDIPacket_Convert(PyObject *v, MusicMIDIPacket *p_itself)
+{
+        int dummy;
+
+        if( !PyArg_ParseTuple(v, "hls#", &p_itself->length, &p_itself->reserved, p_itself->data, dummy) )
+                return 0;
+        return 1;
+}
+
+
+
+
+static PyObject *Qt_Error;
+
+/* -------------------- Object type IdleManager --------------------- */
+
+PyTypeObject IdleManager_Type;
+
+#define IdleManagerObj_Check(x) ((x)->ob_type == &IdleManager_Type || PyObject_TypeCheck((x), &IdleManager_Type))
+
+typedef struct IdleManagerObject {
+	PyObject_HEAD
+	IdleManager ob_itself;
+} IdleManagerObject;
+
+PyObject *IdleManagerObj_New(IdleManager itself)
+{
+	IdleManagerObject *it;
+	if (itself == NULL) {
+	                                PyErr_SetString(Qt_Error,"Cannot create IdleManager from NULL pointer");
+	                                return NULL;
+	                        }
+	it = PyObject_NEW(IdleManagerObject, &IdleManager_Type);
+	if (it == NULL) return NULL;
+	it->ob_itself = itself;
+	return (PyObject *)it;
+}
+
+int IdleManagerObj_Convert(PyObject *v, IdleManager *p_itself)
+{
+	if (v == Py_None)
+	{
+		*p_itself = NULL;
+		return 1;
+	}
+	if (!IdleManagerObj_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "IdleManager required");
+		return 0;
+	}
+	*p_itself = ((IdleManagerObject *)v)->ob_itself;
+	return 1;
+}
+
+static void IdleManagerObj_dealloc(IdleManagerObject *self)
+{
+	/* Cleanup of self->ob_itself goes here */
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyMethodDef IdleManagerObj_methods[] = {
+	{NULL, NULL, 0}
+};
+
+#define IdleManagerObj_getsetlist NULL
+
+
+#define IdleManagerObj_compare NULL
+
+#define IdleManagerObj_repr NULL
+
+#define IdleManagerObj_hash NULL
+#define IdleManagerObj_tp_init 0
+
+#define IdleManagerObj_tp_alloc PyType_GenericAlloc
+
+static PyObject *IdleManagerObj_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *_self;
+	IdleManager itself;
+	char *kw[] = {"itself", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, IdleManagerObj_Convert, &itself)) return NULL;
+	if ((_self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	((IdleManagerObject *)_self)->ob_itself = itself;
+	return _self;
+}
+
+#define IdleManagerObj_tp_free PyObject_Del
+
+
+PyTypeObject IdleManager_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"_Qt.IdleManager", /*tp_name*/
+	sizeof(IdleManagerObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) IdleManagerObj_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) IdleManagerObj_compare, /*tp_compare*/
+	(reprfunc) IdleManagerObj_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) IdleManagerObj_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	IdleManagerObj_methods, /* tp_methods */
+	0, /*tp_members*/
+	IdleManagerObj_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	IdleManagerObj_tp_init, /* tp_init */
+	IdleManagerObj_tp_alloc, /* tp_alloc */
+	IdleManagerObj_tp_new, /* tp_new */
+	IdleManagerObj_tp_free, /* tp_free */
+};
+
+/* ------------------ End object type IdleManager ------------------- */
+
+
+/* ------------------ Object type MovieController ------------------- */
+
+PyTypeObject MovieController_Type;
+
+#define MovieCtlObj_Check(x) ((x)->ob_type == &MovieController_Type || PyObject_TypeCheck((x), &MovieController_Type))
+
+typedef struct MovieControllerObject {
+	PyObject_HEAD
+	MovieController ob_itself;
+} MovieControllerObject;
+
+PyObject *MovieCtlObj_New(MovieController itself)
+{
+	MovieControllerObject *it;
+	if (itself == NULL) {
+	                                PyErr_SetString(Qt_Error,"Cannot create MovieController from NULL pointer");
+	                                return NULL;
+	                        }
+	it = PyObject_NEW(MovieControllerObject, &MovieController_Type);
+	if (it == NULL) return NULL;
+	it->ob_itself = itself;
+	return (PyObject *)it;
+}
+
+int MovieCtlObj_Convert(PyObject *v, MovieController *p_itself)
+{
+	if (v == Py_None)
+	{
+		*p_itself = NULL;
+		return 1;
+	}
+	if (!MovieCtlObj_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "MovieController required");
+		return 0;
+	}
+	*p_itself = ((MovieControllerObject *)v)->ob_itself;
+	return 1;
+}
+
+static void MovieCtlObj_dealloc(MovieControllerObject *self)
+{
+	if (self->ob_itself) DisposeMovieController(self->ob_itself);
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *MovieCtlObj_MCSetMovie(MovieControllerObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	Movie theMovie;
+	WindowPtr movieWindow;
+	Point where;
+#ifndef MCSetMovie
+	PyMac_PRECHECK(MCSetMovie);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      MovieObj_Convert, &theMovie,
+	                      WinObj_Convert, &movieWindow,
+	                      PyMac_GetPoint, &where))
+		return NULL;
+	_rv = MCSetMovie(_self->ob_itself,
+	                 theMovie,
+	                 movieWindow,
+	                 where);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MovieCtlObj_MCGetIndMovie(MovieControllerObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Movie _rv;
+	short index;
+#ifndef MCGetIndMovie
+	PyMac_PRECHECK(MCGetIndMovie);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &index))
+		return NULL;
+	_rv = MCGetIndMovie(_self->ob_itself,
+	                    index);
+	_res = Py_BuildValue("O&",
+	                     MovieObj_New, _rv);
+	return _res;
+}
+
+static PyObject *MovieCtlObj_MCRemoveAllMovies(MovieControllerObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+#ifndef MCRemoveAllMovies
+	PyMac_PRECHECK(MCRemoveAllMovies);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = MCRemoveAllMovies(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MovieCtlObj_MCRemoveAMovie(MovieControllerObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	Movie m;
+#ifndef MCRemoveAMovie
+	PyMac_PRECHECK(MCRemoveAMovie);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      MovieObj_Convert, &m))
+		return NULL;
+	_rv = MCRemoveAMovie(_self->ob_itself,
+	                     m);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MovieCtlObj_MCRemoveMovie(MovieControllerObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+#ifndef MCRemoveMovie
+	PyMac_PRECHECK(MCRemoveMovie);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = MCRemoveMovie(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MovieCtlObj_MCIsPlayerEvent(MovieControllerObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	EventRecord e;
+#ifndef MCIsPlayerEvent
+	PyMac_PRECHECK(MCIsPlayerEvent);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetEventRecord, &e))
+		return NULL;
+	_rv = MCIsPlayerEvent(_self->ob_itself,
+	                      &e);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MovieCtlObj_MCDoAction(MovieControllerObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	short action;
+	void * params;
+#ifndef MCDoAction
+	PyMac_PRECHECK(MCDoAction);
+#endif
+	if (!PyArg_ParseTuple(_args, "hs",
+	                      &action,
+	                      &params))
+		return NULL;
+	_rv = MCDoAction(_self->ob_itself,
+	                 action,
+	                 params);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MovieCtlObj_MCSetControllerAttached(MovieControllerObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	Boolean attach;
+#ifndef MCSetControllerAttached
+	PyMac_PRECHECK(MCSetControllerAttached);
+#endif
+	if (!PyArg_ParseTuple(_args, "b",
+	                      &attach))
+		return NULL;
+	_rv = MCSetControllerAttached(_self->ob_itself,
+	                              attach);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MovieCtlObj_MCIsControllerAttached(MovieControllerObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+#ifndef MCIsControllerAttached
+	PyMac_PRECHECK(MCIsControllerAttached);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = MCIsControllerAttached(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MovieCtlObj_MCSetControllerPort(MovieControllerObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	CGrafPtr gp;
+#ifndef MCSetControllerPort
+	PyMac_PRECHECK(MCSetControllerPort);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      GrafObj_Convert, &gp))
+		return NULL;
+	_rv = MCSetControllerPort(_self->ob_itself,
+	                          gp);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MovieCtlObj_MCGetControllerPort(MovieControllerObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CGrafPtr _rv;
+#ifndef MCGetControllerPort
+	PyMac_PRECHECK(MCGetControllerPort);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = MCGetControllerPort(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     GrafObj_New, _rv);
+	return _res;
+}
+
+static PyObject *MovieCtlObj_MCSetVisible(MovieControllerObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	Boolean visible;
+#ifndef MCSetVisible
+	PyMac_PRECHECK(MCSetVisible);
+#endif
+	if (!PyArg_ParseTuple(_args, "b",
+	                      &visible))
+		return NULL;
+	_rv = MCSetVisible(_self->ob_itself,
+	                   visible);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MovieCtlObj_MCGetVisible(MovieControllerObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+#ifndef MCGetVisible
+	PyMac_PRECHECK(MCGetVisible);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = MCGetVisible(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MovieCtlObj_MCGetControllerBoundsRect(MovieControllerObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	Rect bounds;
+#ifndef MCGetControllerBoundsRect
+	PyMac_PRECHECK(MCGetControllerBoundsRect);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = MCGetControllerBoundsRect(_self->ob_itself,
+	                                &bounds);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     PyMac_BuildRect, &bounds);
+	return _res;
+}
+
+static PyObject *MovieCtlObj_MCSetControllerBoundsRect(MovieControllerObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	Rect bounds;
+#ifndef MCSetControllerBoundsRect
+	PyMac_PRECHECK(MCSetControllerBoundsRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetRect, &bounds))
+		return NULL;
+	_rv = MCSetControllerBoundsRect(_self->ob_itself,
+	                                &bounds);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MovieCtlObj_MCGetControllerBoundsRgn(MovieControllerObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle _rv;
+#ifndef MCGetControllerBoundsRgn
+	PyMac_PRECHECK(MCGetControllerBoundsRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = MCGetControllerBoundsRgn(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *MovieCtlObj_MCGetWindowRgn(MovieControllerObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle _rv;
+	WindowPtr w;
+#ifndef MCGetWindowRgn
+	PyMac_PRECHECK(MCGetWindowRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      WinObj_Convert, &w))
+		return NULL;
+	_rv = MCGetWindowRgn(_self->ob_itself,
+	                     w);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *MovieCtlObj_MCMovieChanged(MovieControllerObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	Movie m;
+#ifndef MCMovieChanged
+	PyMac_PRECHECK(MCMovieChanged);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      MovieObj_Convert, &m))
+		return NULL;
+	_rv = MCMovieChanged(_self->ob_itself,
+	                     m);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MovieCtlObj_MCSetDuration(MovieControllerObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	TimeValue duration;
+#ifndef MCSetDuration
+	PyMac_PRECHECK(MCSetDuration);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &duration))
+		return NULL;
+	_rv = MCSetDuration(_self->ob_itself,
+	                    duration);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MovieCtlObj_MCGetCurrentTime(MovieControllerObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	TimeValue _rv;
+	TimeScale scale;
+#ifndef MCGetCurrentTime
+	PyMac_PRECHECK(MCGetCurrentTime);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = MCGetCurrentTime(_self->ob_itself,
+	                       &scale);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     scale);
+	return _res;
+}
+
+static PyObject *MovieCtlObj_MCNewAttachedController(MovieControllerObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	Movie theMovie;
+	WindowPtr w;
+	Point where;
+#ifndef MCNewAttachedController
+	PyMac_PRECHECK(MCNewAttachedController);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      MovieObj_Convert, &theMovie,
+	                      WinObj_Convert, &w,
+	                      PyMac_GetPoint, &where))
+		return NULL;
+	_rv = MCNewAttachedController(_self->ob_itself,
+	                              theMovie,
+	                              w,
+	                              where);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MovieCtlObj_MCDraw(MovieControllerObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	WindowPtr w;
+#ifndef MCDraw
+	PyMac_PRECHECK(MCDraw);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      WinObj_Convert, &w))
+		return NULL;
+	_rv = MCDraw(_self->ob_itself,
+	             w);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MovieCtlObj_MCActivate(MovieControllerObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	WindowPtr w;
+	Boolean activate;
+#ifndef MCActivate
+	PyMac_PRECHECK(MCActivate);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&b",
+	                      WinObj_Convert, &w,
+	                      &activate))
+		return NULL;
+	_rv = MCActivate(_self->ob_itself,
+	                 w,
+	                 activate);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MovieCtlObj_MCIdle(MovieControllerObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+#ifndef MCIdle
+	PyMac_PRECHECK(MCIdle);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = MCIdle(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MovieCtlObj_MCKey(MovieControllerObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SInt8 key;
+	long modifiers;
+#ifndef MCKey
+	PyMac_PRECHECK(MCKey);
+#endif
+	if (!PyArg_ParseTuple(_args, "bl",
+	                      &key,
+	                      &modifiers))
+		return NULL;
+	_rv = MCKey(_self->ob_itself,
+	            key,
+	            modifiers);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MovieCtlObj_MCClick(MovieControllerObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	WindowPtr w;
+	Point where;
+	long when;
+	long modifiers;
+#ifndef MCClick
+	PyMac_PRECHECK(MCClick);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&ll",
+	                      WinObj_Convert, &w,
+	                      PyMac_GetPoint, &where,
+	                      &when,
+	                      &modifiers))
+		return NULL;
+	_rv = MCClick(_self->ob_itself,
+	              w,
+	              where,
+	              when,
+	              modifiers);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MovieCtlObj_MCEnableEditing(MovieControllerObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	Boolean enabled;
+#ifndef MCEnableEditing
+	PyMac_PRECHECK(MCEnableEditing);
+#endif
+	if (!PyArg_ParseTuple(_args, "b",
+	                      &enabled))
+		return NULL;
+	_rv = MCEnableEditing(_self->ob_itself,
+	                      enabled);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MovieCtlObj_MCIsEditingEnabled(MovieControllerObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long _rv;
+#ifndef MCIsEditingEnabled
+	PyMac_PRECHECK(MCIsEditingEnabled);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = MCIsEditingEnabled(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MovieCtlObj_MCCopy(MovieControllerObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Movie _rv;
+#ifndef MCCopy
+	PyMac_PRECHECK(MCCopy);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = MCCopy(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     MovieObj_New, _rv);
+	return _res;
+}
+
+static PyObject *MovieCtlObj_MCCut(MovieControllerObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Movie _rv;
+#ifndef MCCut
+	PyMac_PRECHECK(MCCut);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = MCCut(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     MovieObj_New, _rv);
+	return _res;
+}
+
+static PyObject *MovieCtlObj_MCPaste(MovieControllerObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	Movie srcMovie;
+#ifndef MCPaste
+	PyMac_PRECHECK(MCPaste);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      MovieObj_Convert, &srcMovie))
+		return NULL;
+	_rv = MCPaste(_self->ob_itself,
+	              srcMovie);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MovieCtlObj_MCClear(MovieControllerObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+#ifndef MCClear
+	PyMac_PRECHECK(MCClear);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = MCClear(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MovieCtlObj_MCUndo(MovieControllerObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+#ifndef MCUndo
+	PyMac_PRECHECK(MCUndo);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = MCUndo(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MovieCtlObj_MCPositionController(MovieControllerObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	Rect movieRect;
+	Rect controllerRect;
+	long someFlags;
+#ifndef MCPositionController
+	PyMac_PRECHECK(MCPositionController);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&l",
+	                      PyMac_GetRect, &movieRect,
+	                      PyMac_GetRect, &controllerRect,
+	                      &someFlags))
+		return NULL;
+	_rv = MCPositionController(_self->ob_itself,
+	                           &movieRect,
+	                           &controllerRect,
+	                           someFlags);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MovieCtlObj_MCGetControllerInfo(MovieControllerObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	long someFlags;
+#ifndef MCGetControllerInfo
+	PyMac_PRECHECK(MCGetControllerInfo);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = MCGetControllerInfo(_self->ob_itself,
+	                          &someFlags);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     someFlags);
+	return _res;
+}
+
+static PyObject *MovieCtlObj_MCSetClip(MovieControllerObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	RgnHandle theClip;
+	RgnHandle movieClip;
+#ifndef MCSetClip
+	PyMac_PRECHECK(MCSetClip);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      ResObj_Convert, &theClip,
+	                      ResObj_Convert, &movieClip))
+		return NULL;
+	_rv = MCSetClip(_self->ob_itself,
+	                theClip,
+	                movieClip);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MovieCtlObj_MCGetClip(MovieControllerObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	RgnHandle theClip;
+	RgnHandle movieClip;
+#ifndef MCGetClip
+	PyMac_PRECHECK(MCGetClip);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = MCGetClip(_self->ob_itself,
+	                &theClip,
+	                &movieClip);
+	_res = Py_BuildValue("lO&O&",
+	                     _rv,
+	                     ResObj_New, theClip,
+	                     ResObj_New, movieClip);
+	return _res;
+}
+
+static PyObject *MovieCtlObj_MCDrawBadge(MovieControllerObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	RgnHandle movieRgn;
+	RgnHandle badgeRgn;
+#ifndef MCDrawBadge
+	PyMac_PRECHECK(MCDrawBadge);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &movieRgn))
+		return NULL;
+	_rv = MCDrawBadge(_self->ob_itself,
+	                  movieRgn,
+	                  &badgeRgn);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     ResObj_New, badgeRgn);
+	return _res;
+}
+
+static PyObject *MovieCtlObj_MCSetUpEditMenu(MovieControllerObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	long modifiers;
+	MenuHandle mh;
+#ifndef MCSetUpEditMenu
+	PyMac_PRECHECK(MCSetUpEditMenu);
+#endif
+	if (!PyArg_ParseTuple(_args, "lO&",
+	                      &modifiers,
+	                      MenuObj_Convert, &mh))
+		return NULL;
+	_rv = MCSetUpEditMenu(_self->ob_itself,
+	                      modifiers,
+	                      mh);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MovieCtlObj_MCGetMenuString(MovieControllerObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	long modifiers;
+	short item;
+	Str255 aString;
+#ifndef MCGetMenuString
+	PyMac_PRECHECK(MCGetMenuString);
+#endif
+	if (!PyArg_ParseTuple(_args, "lhO&",
+	                      &modifiers,
+	                      &item,
+	                      PyMac_GetStr255, aString))
+		return NULL;
+	_rv = MCGetMenuString(_self->ob_itself,
+	                      modifiers,
+	                      item,
+	                      aString);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MovieCtlObj_MCPtInController(MovieControllerObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	Point thePt;
+	Boolean inController;
+#ifndef MCPtInController
+	PyMac_PRECHECK(MCPtInController);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetPoint, &thePt))
+		return NULL;
+	_rv = MCPtInController(_self->ob_itself,
+	                       thePt,
+	                       &inController);
+	_res = Py_BuildValue("lb",
+	                     _rv,
+	                     inController);
+	return _res;
+}
+
+static PyObject *MovieCtlObj_MCInvalidate(MovieControllerObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	WindowPtr w;
+	RgnHandle invalidRgn;
+#ifndef MCInvalidate
+	PyMac_PRECHECK(MCInvalidate);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      WinObj_Convert, &w,
+	                      ResObj_Convert, &invalidRgn))
+		return NULL;
+	_rv = MCInvalidate(_self->ob_itself,
+	                   w,
+	                   invalidRgn);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MovieCtlObj_MCAdjustCursor(MovieControllerObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	WindowPtr w;
+	Point where;
+	long modifiers;
+#ifndef MCAdjustCursor
+	PyMac_PRECHECK(MCAdjustCursor);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&l",
+	                      WinObj_Convert, &w,
+	                      PyMac_GetPoint, &where,
+	                      &modifiers))
+		return NULL;
+	_rv = MCAdjustCursor(_self->ob_itself,
+	                     w,
+	                     where,
+	                     modifiers);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MovieCtlObj_MCGetInterfaceElement(MovieControllerObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MCInterfaceElement whichElement;
+	void * element;
+#ifndef MCGetInterfaceElement
+	PyMac_PRECHECK(MCGetInterfaceElement);
+#endif
+	if (!PyArg_ParseTuple(_args, "ls",
+	                      &whichElement,
+	                      &element))
+		return NULL;
+	_rv = MCGetInterfaceElement(_self->ob_itself,
+	                            whichElement,
+	                            element);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MovieCtlObj_MCAddMovieSegment(MovieControllerObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	Movie srcMovie;
+	Boolean scaled;
+#ifndef MCAddMovieSegment
+	PyMac_PRECHECK(MCAddMovieSegment);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&b",
+	                      MovieObj_Convert, &srcMovie,
+	                      &scaled))
+		return NULL;
+	_rv = MCAddMovieSegment(_self->ob_itself,
+	                        srcMovie,
+	                        scaled);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MovieCtlObj_MCTrimMovieSegment(MovieControllerObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+#ifndef MCTrimMovieSegment
+	PyMac_PRECHECK(MCTrimMovieSegment);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = MCTrimMovieSegment(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MovieCtlObj_MCSetIdleManager(MovieControllerObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	IdleManager im;
+#ifndef MCSetIdleManager
+	PyMac_PRECHECK(MCSetIdleManager);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      IdleManagerObj_Convert, &im))
+		return NULL;
+	_rv = MCSetIdleManager(_self->ob_itself,
+	                       im);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MovieCtlObj_MCSetControllerCapabilities(MovieControllerObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	long flags;
+	long flagsMask;
+#ifndef MCSetControllerCapabilities
+	PyMac_PRECHECK(MCSetControllerCapabilities);
+#endif
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &flags,
+	                      &flagsMask))
+		return NULL;
+	_rv = MCSetControllerCapabilities(_self->ob_itself,
+	                                  flags,
+	                                  flagsMask);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyMethodDef MovieCtlObj_methods[] = {
+	{"MCSetMovie", (PyCFunction)MovieCtlObj_MCSetMovie, 1,
+	 PyDoc_STR("(Movie theMovie, WindowPtr movieWindow, Point where) -> (ComponentResult _rv)")},
+	{"MCGetIndMovie", (PyCFunction)MovieCtlObj_MCGetIndMovie, 1,
+	 PyDoc_STR("(short index) -> (Movie _rv)")},
+	{"MCRemoveAllMovies", (PyCFunction)MovieCtlObj_MCRemoveAllMovies, 1,
+	 PyDoc_STR("() -> (ComponentResult _rv)")},
+	{"MCRemoveAMovie", (PyCFunction)MovieCtlObj_MCRemoveAMovie, 1,
+	 PyDoc_STR("(Movie m) -> (ComponentResult _rv)")},
+	{"MCRemoveMovie", (PyCFunction)MovieCtlObj_MCRemoveMovie, 1,
+	 PyDoc_STR("() -> (ComponentResult _rv)")},
+	{"MCIsPlayerEvent", (PyCFunction)MovieCtlObj_MCIsPlayerEvent, 1,
+	 PyDoc_STR("(EventRecord e) -> (ComponentResult _rv)")},
+	{"MCDoAction", (PyCFunction)MovieCtlObj_MCDoAction, 1,
+	 PyDoc_STR("(short action, void * params) -> (ComponentResult _rv)")},
+	{"MCSetControllerAttached", (PyCFunction)MovieCtlObj_MCSetControllerAttached, 1,
+	 PyDoc_STR("(Boolean attach) -> (ComponentResult _rv)")},
+	{"MCIsControllerAttached", (PyCFunction)MovieCtlObj_MCIsControllerAttached, 1,
+	 PyDoc_STR("() -> (ComponentResult _rv)")},
+	{"MCSetControllerPort", (PyCFunction)MovieCtlObj_MCSetControllerPort, 1,
+	 PyDoc_STR("(CGrafPtr gp) -> (ComponentResult _rv)")},
+	{"MCGetControllerPort", (PyCFunction)MovieCtlObj_MCGetControllerPort, 1,
+	 PyDoc_STR("() -> (CGrafPtr _rv)")},
+	{"MCSetVisible", (PyCFunction)MovieCtlObj_MCSetVisible, 1,
+	 PyDoc_STR("(Boolean visible) -> (ComponentResult _rv)")},
+	{"MCGetVisible", (PyCFunction)MovieCtlObj_MCGetVisible, 1,
+	 PyDoc_STR("() -> (ComponentResult _rv)")},
+	{"MCGetControllerBoundsRect", (PyCFunction)MovieCtlObj_MCGetControllerBoundsRect, 1,
+	 PyDoc_STR("() -> (ComponentResult _rv, Rect bounds)")},
+	{"MCSetControllerBoundsRect", (PyCFunction)MovieCtlObj_MCSetControllerBoundsRect, 1,
+	 PyDoc_STR("(Rect bounds) -> (ComponentResult _rv)")},
+	{"MCGetControllerBoundsRgn", (PyCFunction)MovieCtlObj_MCGetControllerBoundsRgn, 1,
+	 PyDoc_STR("() -> (RgnHandle _rv)")},
+	{"MCGetWindowRgn", (PyCFunction)MovieCtlObj_MCGetWindowRgn, 1,
+	 PyDoc_STR("(WindowPtr w) -> (RgnHandle _rv)")},
+	{"MCMovieChanged", (PyCFunction)MovieCtlObj_MCMovieChanged, 1,
+	 PyDoc_STR("(Movie m) -> (ComponentResult _rv)")},
+	{"MCSetDuration", (PyCFunction)MovieCtlObj_MCSetDuration, 1,
+	 PyDoc_STR("(TimeValue duration) -> (ComponentResult _rv)")},
+	{"MCGetCurrentTime", (PyCFunction)MovieCtlObj_MCGetCurrentTime, 1,
+	 PyDoc_STR("() -> (TimeValue _rv, TimeScale scale)")},
+	{"MCNewAttachedController", (PyCFunction)MovieCtlObj_MCNewAttachedController, 1,
+	 PyDoc_STR("(Movie theMovie, WindowPtr w, Point where) -> (ComponentResult _rv)")},
+	{"MCDraw", (PyCFunction)MovieCtlObj_MCDraw, 1,
+	 PyDoc_STR("(WindowPtr w) -> (ComponentResult _rv)")},
+	{"MCActivate", (PyCFunction)MovieCtlObj_MCActivate, 1,
+	 PyDoc_STR("(WindowPtr w, Boolean activate) -> (ComponentResult _rv)")},
+	{"MCIdle", (PyCFunction)MovieCtlObj_MCIdle, 1,
+	 PyDoc_STR("() -> (ComponentResult _rv)")},
+	{"MCKey", (PyCFunction)MovieCtlObj_MCKey, 1,
+	 PyDoc_STR("(SInt8 key, long modifiers) -> (ComponentResult _rv)")},
+	{"MCClick", (PyCFunction)MovieCtlObj_MCClick, 1,
+	 PyDoc_STR("(WindowPtr w, Point where, long when, long modifiers) -> (ComponentResult _rv)")},
+	{"MCEnableEditing", (PyCFunction)MovieCtlObj_MCEnableEditing, 1,
+	 PyDoc_STR("(Boolean enabled) -> (ComponentResult _rv)")},
+	{"MCIsEditingEnabled", (PyCFunction)MovieCtlObj_MCIsEditingEnabled, 1,
+	 PyDoc_STR("() -> (long _rv)")},
+	{"MCCopy", (PyCFunction)MovieCtlObj_MCCopy, 1,
+	 PyDoc_STR("() -> (Movie _rv)")},
+	{"MCCut", (PyCFunction)MovieCtlObj_MCCut, 1,
+	 PyDoc_STR("() -> (Movie _rv)")},
+	{"MCPaste", (PyCFunction)MovieCtlObj_MCPaste, 1,
+	 PyDoc_STR("(Movie srcMovie) -> (ComponentResult _rv)")},
+	{"MCClear", (PyCFunction)MovieCtlObj_MCClear, 1,
+	 PyDoc_STR("() -> (ComponentResult _rv)")},
+	{"MCUndo", (PyCFunction)MovieCtlObj_MCUndo, 1,
+	 PyDoc_STR("() -> (ComponentResult _rv)")},
+	{"MCPositionController", (PyCFunction)MovieCtlObj_MCPositionController, 1,
+	 PyDoc_STR("(Rect movieRect, Rect controllerRect, long someFlags) -> (ComponentResult _rv)")},
+	{"MCGetControllerInfo", (PyCFunction)MovieCtlObj_MCGetControllerInfo, 1,
+	 PyDoc_STR("() -> (ComponentResult _rv, long someFlags)")},
+	{"MCSetClip", (PyCFunction)MovieCtlObj_MCSetClip, 1,
+	 PyDoc_STR("(RgnHandle theClip, RgnHandle movieClip) -> (ComponentResult _rv)")},
+	{"MCGetClip", (PyCFunction)MovieCtlObj_MCGetClip, 1,
+	 PyDoc_STR("() -> (ComponentResult _rv, RgnHandle theClip, RgnHandle movieClip)")},
+	{"MCDrawBadge", (PyCFunction)MovieCtlObj_MCDrawBadge, 1,
+	 PyDoc_STR("(RgnHandle movieRgn) -> (ComponentResult _rv, RgnHandle badgeRgn)")},
+	{"MCSetUpEditMenu", (PyCFunction)MovieCtlObj_MCSetUpEditMenu, 1,
+	 PyDoc_STR("(long modifiers, MenuHandle mh) -> (ComponentResult _rv)")},
+	{"MCGetMenuString", (PyCFunction)MovieCtlObj_MCGetMenuString, 1,
+	 PyDoc_STR("(long modifiers, short item, Str255 aString) -> (ComponentResult _rv)")},
+	{"MCPtInController", (PyCFunction)MovieCtlObj_MCPtInController, 1,
+	 PyDoc_STR("(Point thePt) -> (ComponentResult _rv, Boolean inController)")},
+	{"MCInvalidate", (PyCFunction)MovieCtlObj_MCInvalidate, 1,
+	 PyDoc_STR("(WindowPtr w, RgnHandle invalidRgn) -> (ComponentResult _rv)")},
+	{"MCAdjustCursor", (PyCFunction)MovieCtlObj_MCAdjustCursor, 1,
+	 PyDoc_STR("(WindowPtr w, Point where, long modifiers) -> (ComponentResult _rv)")},
+	{"MCGetInterfaceElement", (PyCFunction)MovieCtlObj_MCGetInterfaceElement, 1,
+	 PyDoc_STR("(MCInterfaceElement whichElement, void * element) -> (ComponentResult _rv)")},
+	{"MCAddMovieSegment", (PyCFunction)MovieCtlObj_MCAddMovieSegment, 1,
+	 PyDoc_STR("(Movie srcMovie, Boolean scaled) -> (ComponentResult _rv)")},
+	{"MCTrimMovieSegment", (PyCFunction)MovieCtlObj_MCTrimMovieSegment, 1,
+	 PyDoc_STR("() -> (ComponentResult _rv)")},
+	{"MCSetIdleManager", (PyCFunction)MovieCtlObj_MCSetIdleManager, 1,
+	 PyDoc_STR("(IdleManager im) -> (ComponentResult _rv)")},
+	{"MCSetControllerCapabilities", (PyCFunction)MovieCtlObj_MCSetControllerCapabilities, 1,
+	 PyDoc_STR("(long flags, long flagsMask) -> (ComponentResult _rv)")},
+	{NULL, NULL, 0}
+};
+
+#define MovieCtlObj_getsetlist NULL
+
+
+#define MovieCtlObj_compare NULL
+
+#define MovieCtlObj_repr NULL
+
+#define MovieCtlObj_hash NULL
+#define MovieCtlObj_tp_init 0
+
+#define MovieCtlObj_tp_alloc PyType_GenericAlloc
+
+static PyObject *MovieCtlObj_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *_self;
+	MovieController itself;
+	char *kw[] = {"itself", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, MovieCtlObj_Convert, &itself)) return NULL;
+	if ((_self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	((MovieControllerObject *)_self)->ob_itself = itself;
+	return _self;
+}
+
+#define MovieCtlObj_tp_free PyObject_Del
+
+
+PyTypeObject MovieController_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"_Qt.MovieController", /*tp_name*/
+	sizeof(MovieControllerObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) MovieCtlObj_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) MovieCtlObj_compare, /*tp_compare*/
+	(reprfunc) MovieCtlObj_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) MovieCtlObj_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	MovieCtlObj_methods, /* tp_methods */
+	0, /*tp_members*/
+	MovieCtlObj_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	MovieCtlObj_tp_init, /* tp_init */
+	MovieCtlObj_tp_alloc, /* tp_alloc */
+	MovieCtlObj_tp_new, /* tp_new */
+	MovieCtlObj_tp_free, /* tp_free */
+};
+
+/* ---------------- End object type MovieController ----------------- */
+
+
+/* ---------------------- Object type TimeBase ---------------------- */
+
+PyTypeObject TimeBase_Type;
+
+#define TimeBaseObj_Check(x) ((x)->ob_type == &TimeBase_Type || PyObject_TypeCheck((x), &TimeBase_Type))
+
+typedef struct TimeBaseObject {
+	PyObject_HEAD
+	TimeBase ob_itself;
+} TimeBaseObject;
+
+PyObject *TimeBaseObj_New(TimeBase itself)
+{
+	TimeBaseObject *it;
+	if (itself == NULL) {
+	                                PyErr_SetString(Qt_Error,"Cannot create TimeBase from NULL pointer");
+	                                return NULL;
+	                        }
+	it = PyObject_NEW(TimeBaseObject, &TimeBase_Type);
+	if (it == NULL) return NULL;
+	it->ob_itself = itself;
+	return (PyObject *)it;
+}
+
+int TimeBaseObj_Convert(PyObject *v, TimeBase *p_itself)
+{
+	if (v == Py_None)
+	{
+		*p_itself = NULL;
+		return 1;
+	}
+	if (!TimeBaseObj_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "TimeBase required");
+		return 0;
+	}
+	*p_itself = ((TimeBaseObject *)v)->ob_itself;
+	return 1;
+}
+
+static void TimeBaseObj_dealloc(TimeBaseObject *self)
+{
+	/* Cleanup of self->ob_itself goes here */
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *TimeBaseObj_DisposeTimeBase(TimeBaseObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef DisposeTimeBase
+	PyMac_PRECHECK(DisposeTimeBase);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	DisposeTimeBase(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TimeBaseObj_GetTimeBaseTime(TimeBaseObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	TimeValue _rv;
+	TimeScale s;
+	TimeRecord tr;
+#ifndef GetTimeBaseTime
+	PyMac_PRECHECK(GetTimeBaseTime);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &s))
+		return NULL;
+	_rv = GetTimeBaseTime(_self->ob_itself,
+	                      s,
+	                      &tr);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     QtTimeRecord_New, &tr);
+	return _res;
+}
+
+static PyObject *TimeBaseObj_SetTimeBaseTime(TimeBaseObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	TimeRecord tr;
+#ifndef SetTimeBaseTime
+	PyMac_PRECHECK(SetTimeBaseTime);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      QtTimeRecord_Convert, &tr))
+		return NULL;
+	SetTimeBaseTime(_self->ob_itself,
+	                &tr);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TimeBaseObj_SetTimeBaseValue(TimeBaseObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	TimeValue t;
+	TimeScale s;
+#ifndef SetTimeBaseValue
+	PyMac_PRECHECK(SetTimeBaseValue);
+#endif
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &t,
+	                      &s))
+		return NULL;
+	SetTimeBaseValue(_self->ob_itself,
+	                 t,
+	                 s);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TimeBaseObj_GetTimeBaseRate(TimeBaseObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Fixed _rv;
+#ifndef GetTimeBaseRate
+	PyMac_PRECHECK(GetTimeBaseRate);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetTimeBaseRate(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildFixed, _rv);
+	return _res;
+}
+
+static PyObject *TimeBaseObj_SetTimeBaseRate(TimeBaseObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Fixed r;
+#ifndef SetTimeBaseRate
+	PyMac_PRECHECK(SetTimeBaseRate);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetFixed, &r))
+		return NULL;
+	SetTimeBaseRate(_self->ob_itself,
+	                r);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TimeBaseObj_GetTimeBaseStartTime(TimeBaseObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	TimeValue _rv;
+	TimeScale s;
+	TimeRecord tr;
+#ifndef GetTimeBaseStartTime
+	PyMac_PRECHECK(GetTimeBaseStartTime);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &s))
+		return NULL;
+	_rv = GetTimeBaseStartTime(_self->ob_itself,
+	                           s,
+	                           &tr);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     QtTimeRecord_New, &tr);
+	return _res;
+}
+
+static PyObject *TimeBaseObj_SetTimeBaseStartTime(TimeBaseObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	TimeRecord tr;
+#ifndef SetTimeBaseStartTime
+	PyMac_PRECHECK(SetTimeBaseStartTime);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      QtTimeRecord_Convert, &tr))
+		return NULL;
+	SetTimeBaseStartTime(_self->ob_itself,
+	                     &tr);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TimeBaseObj_GetTimeBaseStopTime(TimeBaseObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	TimeValue _rv;
+	TimeScale s;
+	TimeRecord tr;
+#ifndef GetTimeBaseStopTime
+	PyMac_PRECHECK(GetTimeBaseStopTime);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &s))
+		return NULL;
+	_rv = GetTimeBaseStopTime(_self->ob_itself,
+	                          s,
+	                          &tr);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     QtTimeRecord_New, &tr);
+	return _res;
+}
+
+static PyObject *TimeBaseObj_SetTimeBaseStopTime(TimeBaseObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	TimeRecord tr;
+#ifndef SetTimeBaseStopTime
+	PyMac_PRECHECK(SetTimeBaseStopTime);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      QtTimeRecord_Convert, &tr))
+		return NULL;
+	SetTimeBaseStopTime(_self->ob_itself,
+	                    &tr);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TimeBaseObj_GetTimeBaseFlags(TimeBaseObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long _rv;
+#ifndef GetTimeBaseFlags
+	PyMac_PRECHECK(GetTimeBaseFlags);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetTimeBaseFlags(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *TimeBaseObj_SetTimeBaseFlags(TimeBaseObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long timeBaseFlags;
+#ifndef SetTimeBaseFlags
+	PyMac_PRECHECK(SetTimeBaseFlags);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &timeBaseFlags))
+		return NULL;
+	SetTimeBaseFlags(_self->ob_itself,
+	                 timeBaseFlags);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TimeBaseObj_SetTimeBaseMasterTimeBase(TimeBaseObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	TimeBase master;
+	TimeRecord slaveZero;
+#ifndef SetTimeBaseMasterTimeBase
+	PyMac_PRECHECK(SetTimeBaseMasterTimeBase);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      TimeBaseObj_Convert, &master,
+	                      QtTimeRecord_Convert, &slaveZero))
+		return NULL;
+	SetTimeBaseMasterTimeBase(_self->ob_itself,
+	                          master,
+	                          &slaveZero);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TimeBaseObj_GetTimeBaseMasterTimeBase(TimeBaseObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	TimeBase _rv;
+#ifndef GetTimeBaseMasterTimeBase
+	PyMac_PRECHECK(GetTimeBaseMasterTimeBase);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetTimeBaseMasterTimeBase(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     TimeBaseObj_New, _rv);
+	return _res;
+}
+
+static PyObject *TimeBaseObj_SetTimeBaseMasterClock(TimeBaseObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Component clockMeister;
+	TimeRecord slaveZero;
+#ifndef SetTimeBaseMasterClock
+	PyMac_PRECHECK(SetTimeBaseMasterClock);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &clockMeister,
+	                      QtTimeRecord_Convert, &slaveZero))
+		return NULL;
+	SetTimeBaseMasterClock(_self->ob_itself,
+	                       clockMeister,
+	                       &slaveZero);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TimeBaseObj_GetTimeBaseMasterClock(TimeBaseObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentInstance _rv;
+#ifndef GetTimeBaseMasterClock
+	PyMac_PRECHECK(GetTimeBaseMasterClock);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetTimeBaseMasterClock(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     CmpInstObj_New, _rv);
+	return _res;
+}
+
+static PyObject *TimeBaseObj_GetTimeBaseStatus(TimeBaseObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long _rv;
+	TimeRecord unpinnedTime;
+#ifndef GetTimeBaseStatus
+	PyMac_PRECHECK(GetTimeBaseStatus);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetTimeBaseStatus(_self->ob_itself,
+	                        &unpinnedTime);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     QtTimeRecord_New, &unpinnedTime);
+	return _res;
+}
+
+static PyObject *TimeBaseObj_SetTimeBaseZero(TimeBaseObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	TimeRecord zero;
+#ifndef SetTimeBaseZero
+	PyMac_PRECHECK(SetTimeBaseZero);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      QtTimeRecord_Convert, &zero))
+		return NULL;
+	SetTimeBaseZero(_self->ob_itself,
+	                &zero);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TimeBaseObj_GetTimeBaseEffectiveRate(TimeBaseObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Fixed _rv;
+#ifndef GetTimeBaseEffectiveRate
+	PyMac_PRECHECK(GetTimeBaseEffectiveRate);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetTimeBaseEffectiveRate(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildFixed, _rv);
+	return _res;
+}
+
+static PyMethodDef TimeBaseObj_methods[] = {
+	{"DisposeTimeBase", (PyCFunction)TimeBaseObj_DisposeTimeBase, 1,
+	 PyDoc_STR("() -> None")},
+	{"GetTimeBaseTime", (PyCFunction)TimeBaseObj_GetTimeBaseTime, 1,
+	 PyDoc_STR("(TimeScale s) -> (TimeValue _rv, TimeRecord tr)")},
+	{"SetTimeBaseTime", (PyCFunction)TimeBaseObj_SetTimeBaseTime, 1,
+	 PyDoc_STR("(TimeRecord tr) -> None")},
+	{"SetTimeBaseValue", (PyCFunction)TimeBaseObj_SetTimeBaseValue, 1,
+	 PyDoc_STR("(TimeValue t, TimeScale s) -> None")},
+	{"GetTimeBaseRate", (PyCFunction)TimeBaseObj_GetTimeBaseRate, 1,
+	 PyDoc_STR("() -> (Fixed _rv)")},
+	{"SetTimeBaseRate", (PyCFunction)TimeBaseObj_SetTimeBaseRate, 1,
+	 PyDoc_STR("(Fixed r) -> None")},
+	{"GetTimeBaseStartTime", (PyCFunction)TimeBaseObj_GetTimeBaseStartTime, 1,
+	 PyDoc_STR("(TimeScale s) -> (TimeValue _rv, TimeRecord tr)")},
+	{"SetTimeBaseStartTime", (PyCFunction)TimeBaseObj_SetTimeBaseStartTime, 1,
+	 PyDoc_STR("(TimeRecord tr) -> None")},
+	{"GetTimeBaseStopTime", (PyCFunction)TimeBaseObj_GetTimeBaseStopTime, 1,
+	 PyDoc_STR("(TimeScale s) -> (TimeValue _rv, TimeRecord tr)")},
+	{"SetTimeBaseStopTime", (PyCFunction)TimeBaseObj_SetTimeBaseStopTime, 1,
+	 PyDoc_STR("(TimeRecord tr) -> None")},
+	{"GetTimeBaseFlags", (PyCFunction)TimeBaseObj_GetTimeBaseFlags, 1,
+	 PyDoc_STR("() -> (long _rv)")},
+	{"SetTimeBaseFlags", (PyCFunction)TimeBaseObj_SetTimeBaseFlags, 1,
+	 PyDoc_STR("(long timeBaseFlags) -> None")},
+	{"SetTimeBaseMasterTimeBase", (PyCFunction)TimeBaseObj_SetTimeBaseMasterTimeBase, 1,
+	 PyDoc_STR("(TimeBase master, TimeRecord slaveZero) -> None")},
+	{"GetTimeBaseMasterTimeBase", (PyCFunction)TimeBaseObj_GetTimeBaseMasterTimeBase, 1,
+	 PyDoc_STR("() -> (TimeBase _rv)")},
+	{"SetTimeBaseMasterClock", (PyCFunction)TimeBaseObj_SetTimeBaseMasterClock, 1,
+	 PyDoc_STR("(Component clockMeister, TimeRecord slaveZero) -> None")},
+	{"GetTimeBaseMasterClock", (PyCFunction)TimeBaseObj_GetTimeBaseMasterClock, 1,
+	 PyDoc_STR("() -> (ComponentInstance _rv)")},
+	{"GetTimeBaseStatus", (PyCFunction)TimeBaseObj_GetTimeBaseStatus, 1,
+	 PyDoc_STR("() -> (long _rv, TimeRecord unpinnedTime)")},
+	{"SetTimeBaseZero", (PyCFunction)TimeBaseObj_SetTimeBaseZero, 1,
+	 PyDoc_STR("(TimeRecord zero) -> None")},
+	{"GetTimeBaseEffectiveRate", (PyCFunction)TimeBaseObj_GetTimeBaseEffectiveRate, 1,
+	 PyDoc_STR("() -> (Fixed _rv)")},
+	{NULL, NULL, 0}
+};
+
+#define TimeBaseObj_getsetlist NULL
+
+
+#define TimeBaseObj_compare NULL
+
+#define TimeBaseObj_repr NULL
+
+#define TimeBaseObj_hash NULL
+#define TimeBaseObj_tp_init 0
+
+#define TimeBaseObj_tp_alloc PyType_GenericAlloc
+
+static PyObject *TimeBaseObj_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *_self;
+	TimeBase itself;
+	char *kw[] = {"itself", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, TimeBaseObj_Convert, &itself)) return NULL;
+	if ((_self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	((TimeBaseObject *)_self)->ob_itself = itself;
+	return _self;
+}
+
+#define TimeBaseObj_tp_free PyObject_Del
+
+
+PyTypeObject TimeBase_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"_Qt.TimeBase", /*tp_name*/
+	sizeof(TimeBaseObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) TimeBaseObj_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) TimeBaseObj_compare, /*tp_compare*/
+	(reprfunc) TimeBaseObj_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) TimeBaseObj_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	TimeBaseObj_methods, /* tp_methods */
+	0, /*tp_members*/
+	TimeBaseObj_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	TimeBaseObj_tp_init, /* tp_init */
+	TimeBaseObj_tp_alloc, /* tp_alloc */
+	TimeBaseObj_tp_new, /* tp_new */
+	TimeBaseObj_tp_free, /* tp_free */
+};
+
+/* -------------------- End object type TimeBase -------------------- */
+
+
+/* ---------------------- Object type UserData ---------------------- */
+
+PyTypeObject UserData_Type;
+
+#define UserDataObj_Check(x) ((x)->ob_type == &UserData_Type || PyObject_TypeCheck((x), &UserData_Type))
+
+typedef struct UserDataObject {
+	PyObject_HEAD
+	UserData ob_itself;
+} UserDataObject;
+
+PyObject *UserDataObj_New(UserData itself)
+{
+	UserDataObject *it;
+	if (itself == NULL) {
+	                                PyErr_SetString(Qt_Error,"Cannot create UserData from NULL pointer");
+	                                return NULL;
+	                        }
+	it = PyObject_NEW(UserDataObject, &UserData_Type);
+	if (it == NULL) return NULL;
+	it->ob_itself = itself;
+	return (PyObject *)it;
+}
+
+int UserDataObj_Convert(PyObject *v, UserData *p_itself)
+{
+	if (v == Py_None)
+	{
+		*p_itself = NULL;
+		return 1;
+	}
+	if (!UserDataObj_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "UserData required");
+		return 0;
+	}
+	*p_itself = ((UserDataObject *)v)->ob_itself;
+	return 1;
+}
+
+static void UserDataObj_dealloc(UserDataObject *self)
+{
+	if (self->ob_itself) DisposeUserData(self->ob_itself);
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *UserDataObj_GetUserData(UserDataObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Handle data;
+	OSType udType;
+	long index;
+#ifndef GetUserData
+	PyMac_PRECHECK(GetUserData);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&l",
+	                      ResObj_Convert, &data,
+	                      PyMac_GetOSType, &udType,
+	                      &index))
+		return NULL;
+	_err = GetUserData(_self->ob_itself,
+	                   data,
+	                   udType,
+	                   index);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *UserDataObj_AddUserData(UserDataObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Handle data;
+	OSType udType;
+#ifndef AddUserData
+	PyMac_PRECHECK(AddUserData);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      ResObj_Convert, &data,
+	                      PyMac_GetOSType, &udType))
+		return NULL;
+	_err = AddUserData(_self->ob_itself,
+	                   data,
+	                   udType);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *UserDataObj_RemoveUserData(UserDataObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	OSType udType;
+	long index;
+#ifndef RemoveUserData
+	PyMac_PRECHECK(RemoveUserData);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      PyMac_GetOSType, &udType,
+	                      &index))
+		return NULL;
+	_err = RemoveUserData(_self->ob_itself,
+	                      udType,
+	                      index);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *UserDataObj_CountUserDataType(UserDataObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short _rv;
+	OSType udType;
+#ifndef CountUserDataType
+	PyMac_PRECHECK(CountUserDataType);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetOSType, &udType))
+		return NULL;
+	_rv = CountUserDataType(_self->ob_itself,
+	                        udType);
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *UserDataObj_GetNextUserDataType(UserDataObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long _rv;
+	OSType udType;
+#ifndef GetNextUserDataType
+	PyMac_PRECHECK(GetNextUserDataType);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetOSType, &udType))
+		return NULL;
+	_rv = GetNextUserDataType(_self->ob_itself,
+	                          udType);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *UserDataObj_AddUserDataText(UserDataObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Handle data;
+	OSType udType;
+	long index;
+	short itlRegionTag;
+#ifndef AddUserDataText
+	PyMac_PRECHECK(AddUserDataText);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&lh",
+	                      ResObj_Convert, &data,
+	                      PyMac_GetOSType, &udType,
+	                      &index,
+	                      &itlRegionTag))
+		return NULL;
+	_err = AddUserDataText(_self->ob_itself,
+	                       data,
+	                       udType,
+	                       index,
+	                       itlRegionTag);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *UserDataObj_GetUserDataText(UserDataObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Handle data;
+	OSType udType;
+	long index;
+	short itlRegionTag;
+#ifndef GetUserDataText
+	PyMac_PRECHECK(GetUserDataText);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&lh",
+	                      ResObj_Convert, &data,
+	                      PyMac_GetOSType, &udType,
+	                      &index,
+	                      &itlRegionTag))
+		return NULL;
+	_err = GetUserDataText(_self->ob_itself,
+	                       data,
+	                       udType,
+	                       index,
+	                       itlRegionTag);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *UserDataObj_RemoveUserDataText(UserDataObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	OSType udType;
+	long index;
+	short itlRegionTag;
+#ifndef RemoveUserDataText
+	PyMac_PRECHECK(RemoveUserDataText);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&lh",
+	                      PyMac_GetOSType, &udType,
+	                      &index,
+	                      &itlRegionTag))
+		return NULL;
+	_err = RemoveUserDataText(_self->ob_itself,
+	                          udType,
+	                          index,
+	                          itlRegionTag);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *UserDataObj_PutUserDataIntoHandle(UserDataObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Handle h;
+#ifndef PutUserDataIntoHandle
+	PyMac_PRECHECK(PutUserDataIntoHandle);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &h))
+		return NULL;
+	_err = PutUserDataIntoHandle(_self->ob_itself,
+	                             h);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *UserDataObj_CopyUserData(UserDataObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	UserData dstUserData;
+	OSType copyRule;
+#ifndef CopyUserData
+	PyMac_PRECHECK(CopyUserData);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      UserDataObj_Convert, &dstUserData,
+	                      PyMac_GetOSType, &copyRule))
+		return NULL;
+	_err = CopyUserData(_self->ob_itself,
+	                    dstUserData,
+	                    copyRule);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyMethodDef UserDataObj_methods[] = {
+	{"GetUserData", (PyCFunction)UserDataObj_GetUserData, 1,
+	 PyDoc_STR("(Handle data, OSType udType, long index) -> None")},
+	{"AddUserData", (PyCFunction)UserDataObj_AddUserData, 1,
+	 PyDoc_STR("(Handle data, OSType udType) -> None")},
+	{"RemoveUserData", (PyCFunction)UserDataObj_RemoveUserData, 1,
+	 PyDoc_STR("(OSType udType, long index) -> None")},
+	{"CountUserDataType", (PyCFunction)UserDataObj_CountUserDataType, 1,
+	 PyDoc_STR("(OSType udType) -> (short _rv)")},
+	{"GetNextUserDataType", (PyCFunction)UserDataObj_GetNextUserDataType, 1,
+	 PyDoc_STR("(OSType udType) -> (long _rv)")},
+	{"AddUserDataText", (PyCFunction)UserDataObj_AddUserDataText, 1,
+	 PyDoc_STR("(Handle data, OSType udType, long index, short itlRegionTag) -> None")},
+	{"GetUserDataText", (PyCFunction)UserDataObj_GetUserDataText, 1,
+	 PyDoc_STR("(Handle data, OSType udType, long index, short itlRegionTag) -> None")},
+	{"RemoveUserDataText", (PyCFunction)UserDataObj_RemoveUserDataText, 1,
+	 PyDoc_STR("(OSType udType, long index, short itlRegionTag) -> None")},
+	{"PutUserDataIntoHandle", (PyCFunction)UserDataObj_PutUserDataIntoHandle, 1,
+	 PyDoc_STR("(Handle h) -> None")},
+	{"CopyUserData", (PyCFunction)UserDataObj_CopyUserData, 1,
+	 PyDoc_STR("(UserData dstUserData, OSType copyRule) -> None")},
+	{NULL, NULL, 0}
+};
+
+#define UserDataObj_getsetlist NULL
+
+
+#define UserDataObj_compare NULL
+
+#define UserDataObj_repr NULL
+
+#define UserDataObj_hash NULL
+#define UserDataObj_tp_init 0
+
+#define UserDataObj_tp_alloc PyType_GenericAlloc
+
+static PyObject *UserDataObj_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *_self;
+	UserData itself;
+	char *kw[] = {"itself", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, UserDataObj_Convert, &itself)) return NULL;
+	if ((_self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	((UserDataObject *)_self)->ob_itself = itself;
+	return _self;
+}
+
+#define UserDataObj_tp_free PyObject_Del
+
+
+PyTypeObject UserData_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"_Qt.UserData", /*tp_name*/
+	sizeof(UserDataObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) UserDataObj_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) UserDataObj_compare, /*tp_compare*/
+	(reprfunc) UserDataObj_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) UserDataObj_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	UserDataObj_methods, /* tp_methods */
+	0, /*tp_members*/
+	UserDataObj_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	UserDataObj_tp_init, /* tp_init */
+	UserDataObj_tp_alloc, /* tp_alloc */
+	UserDataObj_tp_new, /* tp_new */
+	UserDataObj_tp_free, /* tp_free */
+};
+
+/* -------------------- End object type UserData -------------------- */
+
+
+/* ----------------------- Object type Media ------------------------ */
+
+PyTypeObject Media_Type;
+
+#define MediaObj_Check(x) ((x)->ob_type == &Media_Type || PyObject_TypeCheck((x), &Media_Type))
+
+typedef struct MediaObject {
+	PyObject_HEAD
+	Media ob_itself;
+} MediaObject;
+
+PyObject *MediaObj_New(Media itself)
+{
+	MediaObject *it;
+	if (itself == NULL) {
+	                                PyErr_SetString(Qt_Error,"Cannot create Media from NULL pointer");
+	                                return NULL;
+	                        }
+	it = PyObject_NEW(MediaObject, &Media_Type);
+	if (it == NULL) return NULL;
+	it->ob_itself = itself;
+	return (PyObject *)it;
+}
+
+int MediaObj_Convert(PyObject *v, Media *p_itself)
+{
+	if (v == Py_None)
+	{
+		*p_itself = NULL;
+		return 1;
+	}
+	if (!MediaObj_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "Media required");
+		return 0;
+	}
+	*p_itself = ((MediaObject *)v)->ob_itself;
+	return 1;
+}
+
+static void MediaObj_dealloc(MediaObject *self)
+{
+	if (self->ob_itself) DisposeTrackMedia(self->ob_itself);
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *MediaObj_LoadMediaIntoRam(MediaObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	TimeValue time;
+	TimeValue duration;
+	long flags;
+#ifndef LoadMediaIntoRam
+	PyMac_PRECHECK(LoadMediaIntoRam);
+#endif
+	if (!PyArg_ParseTuple(_args, "lll",
+	                      &time,
+	                      &duration,
+	                      &flags))
+		return NULL;
+	_err = LoadMediaIntoRam(_self->ob_itself,
+	                        time,
+	                        duration,
+	                        flags);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MediaObj_GetMediaTrack(MediaObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Track _rv;
+#ifndef GetMediaTrack
+	PyMac_PRECHECK(GetMediaTrack);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetMediaTrack(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     TrackObj_New, _rv);
+	return _res;
+}
+
+static PyObject *MediaObj_GetMediaCreationTime(MediaObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	unsigned long _rv;
+#ifndef GetMediaCreationTime
+	PyMac_PRECHECK(GetMediaCreationTime);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetMediaCreationTime(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MediaObj_GetMediaModificationTime(MediaObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	unsigned long _rv;
+#ifndef GetMediaModificationTime
+	PyMac_PRECHECK(GetMediaModificationTime);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetMediaModificationTime(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MediaObj_GetMediaTimeScale(MediaObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	TimeScale _rv;
+#ifndef GetMediaTimeScale
+	PyMac_PRECHECK(GetMediaTimeScale);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetMediaTimeScale(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MediaObj_SetMediaTimeScale(MediaObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	TimeScale timeScale;
+#ifndef SetMediaTimeScale
+	PyMac_PRECHECK(SetMediaTimeScale);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &timeScale))
+		return NULL;
+	SetMediaTimeScale(_self->ob_itself,
+	                  timeScale);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MediaObj_GetMediaDuration(MediaObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	TimeValue _rv;
+#ifndef GetMediaDuration
+	PyMac_PRECHECK(GetMediaDuration);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetMediaDuration(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MediaObj_GetMediaLanguage(MediaObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short _rv;
+#ifndef GetMediaLanguage
+	PyMac_PRECHECK(GetMediaLanguage);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetMediaLanguage(_self->ob_itself);
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MediaObj_SetMediaLanguage(MediaObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short language;
+#ifndef SetMediaLanguage
+	PyMac_PRECHECK(SetMediaLanguage);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &language))
+		return NULL;
+	SetMediaLanguage(_self->ob_itself,
+	                 language);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MediaObj_GetMediaQuality(MediaObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short _rv;
+#ifndef GetMediaQuality
+	PyMac_PRECHECK(GetMediaQuality);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetMediaQuality(_self->ob_itself);
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MediaObj_SetMediaQuality(MediaObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short quality;
+#ifndef SetMediaQuality
+	PyMac_PRECHECK(SetMediaQuality);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &quality))
+		return NULL;
+	SetMediaQuality(_self->ob_itself,
+	                quality);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MediaObj_GetMediaHandlerDescription(MediaObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSType mediaType;
+	Str255 creatorName;
+	OSType creatorManufacturer;
+#ifndef GetMediaHandlerDescription
+	PyMac_PRECHECK(GetMediaHandlerDescription);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetStr255, creatorName))
+		return NULL;
+	GetMediaHandlerDescription(_self->ob_itself,
+	                           &mediaType,
+	                           creatorName,
+	                           &creatorManufacturer);
+	_res = Py_BuildValue("O&O&",
+	                     PyMac_BuildOSType, mediaType,
+	                     PyMac_BuildOSType, creatorManufacturer);
+	return _res;
+}
+
+static PyObject *MediaObj_GetMediaUserData(MediaObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	UserData _rv;
+#ifndef GetMediaUserData
+	PyMac_PRECHECK(GetMediaUserData);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetMediaUserData(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     UserDataObj_New, _rv);
+	return _res;
+}
+
+static PyObject *MediaObj_GetMediaHandler(MediaObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	MediaHandler _rv;
+#ifndef GetMediaHandler
+	PyMac_PRECHECK(GetMediaHandler);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetMediaHandler(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     CmpInstObj_New, _rv);
+	return _res;
+}
+
+static PyObject *MediaObj_SetMediaHandler(MediaObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	MediaHandlerComponent mH;
+#ifndef SetMediaHandler
+	PyMac_PRECHECK(SetMediaHandler);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &mH))
+		return NULL;
+	_err = SetMediaHandler(_self->ob_itself,
+	                       mH);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MediaObj_BeginMediaEdits(MediaObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+#ifndef BeginMediaEdits
+	PyMac_PRECHECK(BeginMediaEdits);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = BeginMediaEdits(_self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MediaObj_EndMediaEdits(MediaObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+#ifndef EndMediaEdits
+	PyMac_PRECHECK(EndMediaEdits);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = EndMediaEdits(_self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MediaObj_SetMediaDefaultDataRefIndex(MediaObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short index;
+#ifndef SetMediaDefaultDataRefIndex
+	PyMac_PRECHECK(SetMediaDefaultDataRefIndex);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &index))
+		return NULL;
+	_err = SetMediaDefaultDataRefIndex(_self->ob_itself,
+	                                   index);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MediaObj_GetMediaDataHandlerDescription(MediaObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short index;
+	OSType dhType;
+	Str255 creatorName;
+	OSType creatorManufacturer;
+#ifndef GetMediaDataHandlerDescription
+	PyMac_PRECHECK(GetMediaDataHandlerDescription);
+#endif
+	if (!PyArg_ParseTuple(_args, "hO&",
+	                      &index,
+	                      PyMac_GetStr255, creatorName))
+		return NULL;
+	GetMediaDataHandlerDescription(_self->ob_itself,
+	                               index,
+	                               &dhType,
+	                               creatorName,
+	                               &creatorManufacturer);
+	_res = Py_BuildValue("O&O&",
+	                     PyMac_BuildOSType, dhType,
+	                     PyMac_BuildOSType, creatorManufacturer);
+	return _res;
+}
+
+static PyObject *MediaObj_GetMediaDataHandler(MediaObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	DataHandler _rv;
+	short index;
+#ifndef GetMediaDataHandler
+	PyMac_PRECHECK(GetMediaDataHandler);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &index))
+		return NULL;
+	_rv = GetMediaDataHandler(_self->ob_itself,
+	                          index);
+	_res = Py_BuildValue("O&",
+	                     CmpInstObj_New, _rv);
+	return _res;
+}
+
+static PyObject *MediaObj_SetMediaDataHandler(MediaObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short index;
+	DataHandlerComponent dataHandler;
+#ifndef SetMediaDataHandler
+	PyMac_PRECHECK(SetMediaDataHandler);
+#endif
+	if (!PyArg_ParseTuple(_args, "hO&",
+	                      &index,
+	                      CmpObj_Convert, &dataHandler))
+		return NULL;
+	_err = SetMediaDataHandler(_self->ob_itself,
+	                           index,
+	                           dataHandler);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MediaObj_GetMediaSampleDescriptionCount(MediaObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long _rv;
+#ifndef GetMediaSampleDescriptionCount
+	PyMac_PRECHECK(GetMediaSampleDescriptionCount);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetMediaSampleDescriptionCount(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MediaObj_GetMediaSampleDescription(MediaObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long index;
+	SampleDescriptionHandle descH;
+#ifndef GetMediaSampleDescription
+	PyMac_PRECHECK(GetMediaSampleDescription);
+#endif
+	if (!PyArg_ParseTuple(_args, "lO&",
+	                      &index,
+	                      ResObj_Convert, &descH))
+		return NULL;
+	GetMediaSampleDescription(_self->ob_itself,
+	                          index,
+	                          descH);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MediaObj_SetMediaSampleDescription(MediaObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	long index;
+	SampleDescriptionHandle descH;
+#ifndef SetMediaSampleDescription
+	PyMac_PRECHECK(SetMediaSampleDescription);
+#endif
+	if (!PyArg_ParseTuple(_args, "lO&",
+	                      &index,
+	                      ResObj_Convert, &descH))
+		return NULL;
+	_err = SetMediaSampleDescription(_self->ob_itself,
+	                                 index,
+	                                 descH);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MediaObj_GetMediaSampleCount(MediaObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long _rv;
+#ifndef GetMediaSampleCount
+	PyMac_PRECHECK(GetMediaSampleCount);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetMediaSampleCount(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MediaObj_GetMediaSyncSampleCount(MediaObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long _rv;
+#ifndef GetMediaSyncSampleCount
+	PyMac_PRECHECK(GetMediaSyncSampleCount);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetMediaSyncSampleCount(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MediaObj_SampleNumToMediaTime(MediaObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long logicalSampleNum;
+	TimeValue sampleTime;
+	TimeValue sampleDuration;
+#ifndef SampleNumToMediaTime
+	PyMac_PRECHECK(SampleNumToMediaTime);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &logicalSampleNum))
+		return NULL;
+	SampleNumToMediaTime(_self->ob_itself,
+	                     logicalSampleNum,
+	                     &sampleTime,
+	                     &sampleDuration);
+	_res = Py_BuildValue("ll",
+	                     sampleTime,
+	                     sampleDuration);
+	return _res;
+}
+
+static PyObject *MediaObj_MediaTimeToSampleNum(MediaObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	TimeValue time;
+	long sampleNum;
+	TimeValue sampleTime;
+	TimeValue sampleDuration;
+#ifndef MediaTimeToSampleNum
+	PyMac_PRECHECK(MediaTimeToSampleNum);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &time))
+		return NULL;
+	MediaTimeToSampleNum(_self->ob_itself,
+	                     time,
+	                     &sampleNum,
+	                     &sampleTime,
+	                     &sampleDuration);
+	_res = Py_BuildValue("lll",
+	                     sampleNum,
+	                     sampleTime,
+	                     sampleDuration);
+	return _res;
+}
+
+static PyObject *MediaObj_AddMediaSample(MediaObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Handle dataIn;
+	long inOffset;
+	unsigned long size;
+	TimeValue durationPerSample;
+	SampleDescriptionHandle sampleDescriptionH;
+	long numberOfSamples;
+	short sampleFlags;
+	TimeValue sampleTime;
+#ifndef AddMediaSample
+	PyMac_PRECHECK(AddMediaSample);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&lllO&lh",
+	                      ResObj_Convert, &dataIn,
+	                      &inOffset,
+	                      &size,
+	                      &durationPerSample,
+	                      ResObj_Convert, &sampleDescriptionH,
+	                      &numberOfSamples,
+	                      &sampleFlags))
+		return NULL;
+	_err = AddMediaSample(_self->ob_itself,
+	                      dataIn,
+	                      inOffset,
+	                      size,
+	                      durationPerSample,
+	                      sampleDescriptionH,
+	                      numberOfSamples,
+	                      sampleFlags,
+	                      &sampleTime);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     sampleTime);
+	return _res;
+}
+
+static PyObject *MediaObj_AddMediaSampleReference(MediaObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	long dataOffset;
+	unsigned long size;
+	TimeValue durationPerSample;
+	SampleDescriptionHandle sampleDescriptionH;
+	long numberOfSamples;
+	short sampleFlags;
+	TimeValue sampleTime;
+#ifndef AddMediaSampleReference
+	PyMac_PRECHECK(AddMediaSampleReference);
+#endif
+	if (!PyArg_ParseTuple(_args, "lllO&lh",
+	                      &dataOffset,
+	                      &size,
+	                      &durationPerSample,
+	                      ResObj_Convert, &sampleDescriptionH,
+	                      &numberOfSamples,
+	                      &sampleFlags))
+		return NULL;
+	_err = AddMediaSampleReference(_self->ob_itself,
+	                               dataOffset,
+	                               size,
+	                               durationPerSample,
+	                               sampleDescriptionH,
+	                               numberOfSamples,
+	                               sampleFlags,
+	                               &sampleTime);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     sampleTime);
+	return _res;
+}
+
+static PyObject *MediaObj_GetMediaSample(MediaObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Handle dataOut;
+	long maxSizeToGrow;
+	long size;
+	TimeValue time;
+	TimeValue sampleTime;
+	TimeValue durationPerSample;
+	SampleDescriptionHandle sampleDescriptionH;
+	long sampleDescriptionIndex;
+	long maxNumberOfSamples;
+	long numberOfSamples;
+	short sampleFlags;
+#ifndef GetMediaSample
+	PyMac_PRECHECK(GetMediaSample);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&llO&l",
+	                      ResObj_Convert, &dataOut,
+	                      &maxSizeToGrow,
+	                      &time,
+	                      ResObj_Convert, &sampleDescriptionH,
+	                      &maxNumberOfSamples))
+		return NULL;
+	_err = GetMediaSample(_self->ob_itself,
+	                      dataOut,
+	                      maxSizeToGrow,
+	                      &size,
+	                      time,
+	                      &sampleTime,
+	                      &durationPerSample,
+	                      sampleDescriptionH,
+	                      &sampleDescriptionIndex,
+	                      maxNumberOfSamples,
+	                      &numberOfSamples,
+	                      &sampleFlags);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("lllllh",
+	                     size,
+	                     sampleTime,
+	                     durationPerSample,
+	                     sampleDescriptionIndex,
+	                     numberOfSamples,
+	                     sampleFlags);
+	return _res;
+}
+
+static PyObject *MediaObj_GetMediaSampleReference(MediaObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	long dataOffset;
+	long size;
+	TimeValue time;
+	TimeValue sampleTime;
+	TimeValue durationPerSample;
+	SampleDescriptionHandle sampleDescriptionH;
+	long sampleDescriptionIndex;
+	long maxNumberOfSamples;
+	long numberOfSamples;
+	short sampleFlags;
+#ifndef GetMediaSampleReference
+	PyMac_PRECHECK(GetMediaSampleReference);
+#endif
+	if (!PyArg_ParseTuple(_args, "lO&l",
+	                      &time,
+	                      ResObj_Convert, &sampleDescriptionH,
+	                      &maxNumberOfSamples))
+		return NULL;
+	_err = GetMediaSampleReference(_self->ob_itself,
+	                               &dataOffset,
+	                               &size,
+	                               time,
+	                               &sampleTime,
+	                               &durationPerSample,
+	                               sampleDescriptionH,
+	                               &sampleDescriptionIndex,
+	                               maxNumberOfSamples,
+	                               &numberOfSamples,
+	                               &sampleFlags);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("llllllh",
+	                     dataOffset,
+	                     size,
+	                     sampleTime,
+	                     durationPerSample,
+	                     sampleDescriptionIndex,
+	                     numberOfSamples,
+	                     sampleFlags);
+	return _res;
+}
+
+static PyObject *MediaObj_SetMediaPreferredChunkSize(MediaObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	long maxChunkSize;
+#ifndef SetMediaPreferredChunkSize
+	PyMac_PRECHECK(SetMediaPreferredChunkSize);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &maxChunkSize))
+		return NULL;
+	_err = SetMediaPreferredChunkSize(_self->ob_itself,
+	                                  maxChunkSize);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MediaObj_GetMediaPreferredChunkSize(MediaObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	long maxChunkSize;
+#ifndef GetMediaPreferredChunkSize
+	PyMac_PRECHECK(GetMediaPreferredChunkSize);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetMediaPreferredChunkSize(_self->ob_itself,
+	                                  &maxChunkSize);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     maxChunkSize);
+	return _res;
+}
+
+static PyObject *MediaObj_SetMediaShadowSync(MediaObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	long frameDiffSampleNum;
+	long syncSampleNum;
+#ifndef SetMediaShadowSync
+	PyMac_PRECHECK(SetMediaShadowSync);
+#endif
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &frameDiffSampleNum,
+	                      &syncSampleNum))
+		return NULL;
+	_err = SetMediaShadowSync(_self->ob_itself,
+	                          frameDiffSampleNum,
+	                          syncSampleNum);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MediaObj_GetMediaShadowSync(MediaObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	long frameDiffSampleNum;
+	long syncSampleNum;
+#ifndef GetMediaShadowSync
+	PyMac_PRECHECK(GetMediaShadowSync);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &frameDiffSampleNum))
+		return NULL;
+	_err = GetMediaShadowSync(_self->ob_itself,
+	                          frameDiffSampleNum,
+	                          &syncSampleNum);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     syncSampleNum);
+	return _res;
+}
+
+static PyObject *MediaObj_GetMediaDataSize(MediaObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long _rv;
+	TimeValue startTime;
+	TimeValue duration;
+#ifndef GetMediaDataSize
+	PyMac_PRECHECK(GetMediaDataSize);
+#endif
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &startTime,
+	                      &duration))
+		return NULL;
+	_rv = GetMediaDataSize(_self->ob_itself,
+	                       startTime,
+	                       duration);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MediaObj_GetMediaDataSize64(MediaObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	TimeValue startTime;
+	TimeValue duration;
+	wide dataSize;
+#ifndef GetMediaDataSize64
+	PyMac_PRECHECK(GetMediaDataSize64);
+#endif
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &startTime,
+	                      &duration))
+		return NULL;
+	_err = GetMediaDataSize64(_self->ob_itself,
+	                          startTime,
+	                          duration,
+	                          &dataSize);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     PyMac_Buildwide, dataSize);
+	return _res;
+}
+
+static PyObject *MediaObj_CopyMediaUserData(MediaObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Media dstMedia;
+	OSType copyRule;
+#ifndef CopyMediaUserData
+	PyMac_PRECHECK(CopyMediaUserData);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      MediaObj_Convert, &dstMedia,
+	                      PyMac_GetOSType, &copyRule))
+		return NULL;
+	_err = CopyMediaUserData(_self->ob_itself,
+	                         dstMedia,
+	                         copyRule);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MediaObj_GetMediaNextInterestingTime(MediaObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short interestingTimeFlags;
+	TimeValue time;
+	Fixed rate;
+	TimeValue interestingTime;
+	TimeValue interestingDuration;
+#ifndef GetMediaNextInterestingTime
+	PyMac_PRECHECK(GetMediaNextInterestingTime);
+#endif
+	if (!PyArg_ParseTuple(_args, "hlO&",
+	                      &interestingTimeFlags,
+	                      &time,
+	                      PyMac_GetFixed, &rate))
+		return NULL;
+	GetMediaNextInterestingTime(_self->ob_itself,
+	                            interestingTimeFlags,
+	                            time,
+	                            rate,
+	                            &interestingTime,
+	                            &interestingDuration);
+	_res = Py_BuildValue("ll",
+	                     interestingTime,
+	                     interestingDuration);
+	return _res;
+}
+
+static PyObject *MediaObj_GetMediaDataRef(MediaObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short index;
+	Handle dataRef;
+	OSType dataRefType;
+	long dataRefAttributes;
+#ifndef GetMediaDataRef
+	PyMac_PRECHECK(GetMediaDataRef);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &index))
+		return NULL;
+	_err = GetMediaDataRef(_self->ob_itself,
+	                       index,
+	                       &dataRef,
+	                       &dataRefType,
+	                       &dataRefAttributes);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&O&l",
+	                     ResObj_New, dataRef,
+	                     PyMac_BuildOSType, dataRefType,
+	                     dataRefAttributes);
+	return _res;
+}
+
+static PyObject *MediaObj_SetMediaDataRef(MediaObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short index;
+	Handle dataRef;
+	OSType dataRefType;
+#ifndef SetMediaDataRef
+	PyMac_PRECHECK(SetMediaDataRef);
+#endif
+	if (!PyArg_ParseTuple(_args, "hO&O&",
+	                      &index,
+	                      ResObj_Convert, &dataRef,
+	                      PyMac_GetOSType, &dataRefType))
+		return NULL;
+	_err = SetMediaDataRef(_self->ob_itself,
+	                       index,
+	                       dataRef,
+	                       dataRefType);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MediaObj_SetMediaDataRefAttributes(MediaObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short index;
+	long dataRefAttributes;
+#ifndef SetMediaDataRefAttributes
+	PyMac_PRECHECK(SetMediaDataRefAttributes);
+#endif
+	if (!PyArg_ParseTuple(_args, "hl",
+	                      &index,
+	                      &dataRefAttributes))
+		return NULL;
+	_err = SetMediaDataRefAttributes(_self->ob_itself,
+	                                 index,
+	                                 dataRefAttributes);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MediaObj_AddMediaDataRef(MediaObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short index;
+	Handle dataRef;
+	OSType dataRefType;
+#ifndef AddMediaDataRef
+	PyMac_PRECHECK(AddMediaDataRef);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      ResObj_Convert, &dataRef,
+	                      PyMac_GetOSType, &dataRefType))
+		return NULL;
+	_err = AddMediaDataRef(_self->ob_itself,
+	                       &index,
+	                       dataRef,
+	                       dataRefType);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("h",
+	                     index);
+	return _res;
+}
+
+static PyObject *MediaObj_GetMediaDataRefCount(MediaObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short count;
+#ifndef GetMediaDataRefCount
+	PyMac_PRECHECK(GetMediaDataRefCount);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetMediaDataRefCount(_self->ob_itself,
+	                            &count);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("h",
+	                     count);
+	return _res;
+}
+
+static PyObject *MediaObj_SetMediaPlayHints(MediaObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long flags;
+	long flagsMask;
+#ifndef SetMediaPlayHints
+	PyMac_PRECHECK(SetMediaPlayHints);
+#endif
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &flags,
+	                      &flagsMask))
+		return NULL;
+	SetMediaPlayHints(_self->ob_itself,
+	                  flags,
+	                  flagsMask);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MediaObj_GetMediaPlayHints(MediaObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long flags;
+#ifndef GetMediaPlayHints
+	PyMac_PRECHECK(GetMediaPlayHints);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	GetMediaPlayHints(_self->ob_itself,
+	                  &flags);
+	_res = Py_BuildValue("l",
+	                     flags);
+	return _res;
+}
+
+static PyObject *MediaObj_GetMediaNextInterestingTimeOnly(MediaObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short interestingTimeFlags;
+	TimeValue time;
+	Fixed rate;
+	TimeValue interestingTime;
+#ifndef GetMediaNextInterestingTimeOnly
+	PyMac_PRECHECK(GetMediaNextInterestingTimeOnly);
+#endif
+	if (!PyArg_ParseTuple(_args, "hlO&",
+	                      &interestingTimeFlags,
+	                      &time,
+	                      PyMac_GetFixed, &rate))
+		return NULL;
+	GetMediaNextInterestingTimeOnly(_self->ob_itself,
+	                                interestingTimeFlags,
+	                                time,
+	                                rate,
+	                                &interestingTime);
+	_res = Py_BuildValue("l",
+	                     interestingTime);
+	return _res;
+}
+
+static PyMethodDef MediaObj_methods[] = {
+	{"LoadMediaIntoRam", (PyCFunction)MediaObj_LoadMediaIntoRam, 1,
+	 PyDoc_STR("(TimeValue time, TimeValue duration, long flags) -> None")},
+	{"GetMediaTrack", (PyCFunction)MediaObj_GetMediaTrack, 1,
+	 PyDoc_STR("() -> (Track _rv)")},
+	{"GetMediaCreationTime", (PyCFunction)MediaObj_GetMediaCreationTime, 1,
+	 PyDoc_STR("() -> (unsigned long _rv)")},
+	{"GetMediaModificationTime", (PyCFunction)MediaObj_GetMediaModificationTime, 1,
+	 PyDoc_STR("() -> (unsigned long _rv)")},
+	{"GetMediaTimeScale", (PyCFunction)MediaObj_GetMediaTimeScale, 1,
+	 PyDoc_STR("() -> (TimeScale _rv)")},
+	{"SetMediaTimeScale", (PyCFunction)MediaObj_SetMediaTimeScale, 1,
+	 PyDoc_STR("(TimeScale timeScale) -> None")},
+	{"GetMediaDuration", (PyCFunction)MediaObj_GetMediaDuration, 1,
+	 PyDoc_STR("() -> (TimeValue _rv)")},
+	{"GetMediaLanguage", (PyCFunction)MediaObj_GetMediaLanguage, 1,
+	 PyDoc_STR("() -> (short _rv)")},
+	{"SetMediaLanguage", (PyCFunction)MediaObj_SetMediaLanguage, 1,
+	 PyDoc_STR("(short language) -> None")},
+	{"GetMediaQuality", (PyCFunction)MediaObj_GetMediaQuality, 1,
+	 PyDoc_STR("() -> (short _rv)")},
+	{"SetMediaQuality", (PyCFunction)MediaObj_SetMediaQuality, 1,
+	 PyDoc_STR("(short quality) -> None")},
+	{"GetMediaHandlerDescription", (PyCFunction)MediaObj_GetMediaHandlerDescription, 1,
+	 PyDoc_STR("(Str255 creatorName) -> (OSType mediaType, OSType creatorManufacturer)")},
+	{"GetMediaUserData", (PyCFunction)MediaObj_GetMediaUserData, 1,
+	 PyDoc_STR("() -> (UserData _rv)")},
+	{"GetMediaHandler", (PyCFunction)MediaObj_GetMediaHandler, 1,
+	 PyDoc_STR("() -> (MediaHandler _rv)")},
+	{"SetMediaHandler", (PyCFunction)MediaObj_SetMediaHandler, 1,
+	 PyDoc_STR("(MediaHandlerComponent mH) -> None")},
+	{"BeginMediaEdits", (PyCFunction)MediaObj_BeginMediaEdits, 1,
+	 PyDoc_STR("() -> None")},
+	{"EndMediaEdits", (PyCFunction)MediaObj_EndMediaEdits, 1,
+	 PyDoc_STR("() -> None")},
+	{"SetMediaDefaultDataRefIndex", (PyCFunction)MediaObj_SetMediaDefaultDataRefIndex, 1,
+	 PyDoc_STR("(short index) -> None")},
+	{"GetMediaDataHandlerDescription", (PyCFunction)MediaObj_GetMediaDataHandlerDescription, 1,
+	 PyDoc_STR("(short index, Str255 creatorName) -> (OSType dhType, OSType creatorManufacturer)")},
+	{"GetMediaDataHandler", (PyCFunction)MediaObj_GetMediaDataHandler, 1,
+	 PyDoc_STR("(short index) -> (DataHandler _rv)")},
+	{"SetMediaDataHandler", (PyCFunction)MediaObj_SetMediaDataHandler, 1,
+	 PyDoc_STR("(short index, DataHandlerComponent dataHandler) -> None")},
+	{"GetMediaSampleDescriptionCount", (PyCFunction)MediaObj_GetMediaSampleDescriptionCount, 1,
+	 PyDoc_STR("() -> (long _rv)")},
+	{"GetMediaSampleDescription", (PyCFunction)MediaObj_GetMediaSampleDescription, 1,
+	 PyDoc_STR("(long index, SampleDescriptionHandle descH) -> None")},
+	{"SetMediaSampleDescription", (PyCFunction)MediaObj_SetMediaSampleDescription, 1,
+	 PyDoc_STR("(long index, SampleDescriptionHandle descH) -> None")},
+	{"GetMediaSampleCount", (PyCFunction)MediaObj_GetMediaSampleCount, 1,
+	 PyDoc_STR("() -> (long _rv)")},
+	{"GetMediaSyncSampleCount", (PyCFunction)MediaObj_GetMediaSyncSampleCount, 1,
+	 PyDoc_STR("() -> (long _rv)")},
+	{"SampleNumToMediaTime", (PyCFunction)MediaObj_SampleNumToMediaTime, 1,
+	 PyDoc_STR("(long logicalSampleNum) -> (TimeValue sampleTime, TimeValue sampleDuration)")},
+	{"MediaTimeToSampleNum", (PyCFunction)MediaObj_MediaTimeToSampleNum, 1,
+	 PyDoc_STR("(TimeValue time) -> (long sampleNum, TimeValue sampleTime, TimeValue sampleDuration)")},
+	{"AddMediaSample", (PyCFunction)MediaObj_AddMediaSample, 1,
+	 PyDoc_STR("(Handle dataIn, long inOffset, unsigned long size, TimeValue durationPerSample, SampleDescriptionHandle sampleDescriptionH, long numberOfSamples, short sampleFlags) -> (TimeValue sampleTime)")},
+	{"AddMediaSampleReference", (PyCFunction)MediaObj_AddMediaSampleReference, 1,
+	 PyDoc_STR("(long dataOffset, unsigned long size, TimeValue durationPerSample, SampleDescriptionHandle sampleDescriptionH, long numberOfSamples, short sampleFlags) -> (TimeValue sampleTime)")},
+	{"GetMediaSample", (PyCFunction)MediaObj_GetMediaSample, 1,
+	 PyDoc_STR("(Handle dataOut, long maxSizeToGrow, TimeValue time, SampleDescriptionHandle sampleDescriptionH, long maxNumberOfSamples) -> (long size, TimeValue sampleTime, TimeValue durationPerSample, long sampleDescriptionIndex, long numberOfSamples, short sampleFlags)")},
+	{"GetMediaSampleReference", (PyCFunction)MediaObj_GetMediaSampleReference, 1,
+	 PyDoc_STR("(TimeValue time, SampleDescriptionHandle sampleDescriptionH, long maxNumberOfSamples) -> (long dataOffset, long size, TimeValue sampleTime, TimeValue durationPerSample, long sampleDescriptionIndex, long numberOfSamples, short sampleFlags)")},
+	{"SetMediaPreferredChunkSize", (PyCFunction)MediaObj_SetMediaPreferredChunkSize, 1,
+	 PyDoc_STR("(long maxChunkSize) -> None")},
+	{"GetMediaPreferredChunkSize", (PyCFunction)MediaObj_GetMediaPreferredChunkSize, 1,
+	 PyDoc_STR("() -> (long maxChunkSize)")},
+	{"SetMediaShadowSync", (PyCFunction)MediaObj_SetMediaShadowSync, 1,
+	 PyDoc_STR("(long frameDiffSampleNum, long syncSampleNum) -> None")},
+	{"GetMediaShadowSync", (PyCFunction)MediaObj_GetMediaShadowSync, 1,
+	 PyDoc_STR("(long frameDiffSampleNum) -> (long syncSampleNum)")},
+	{"GetMediaDataSize", (PyCFunction)MediaObj_GetMediaDataSize, 1,
+	 PyDoc_STR("(TimeValue startTime, TimeValue duration) -> (long _rv)")},
+	{"GetMediaDataSize64", (PyCFunction)MediaObj_GetMediaDataSize64, 1,
+	 PyDoc_STR("(TimeValue startTime, TimeValue duration) -> (wide dataSize)")},
+	{"CopyMediaUserData", (PyCFunction)MediaObj_CopyMediaUserData, 1,
+	 PyDoc_STR("(Media dstMedia, OSType copyRule) -> None")},
+	{"GetMediaNextInterestingTime", (PyCFunction)MediaObj_GetMediaNextInterestingTime, 1,
+	 PyDoc_STR("(short interestingTimeFlags, TimeValue time, Fixed rate) -> (TimeValue interestingTime, TimeValue interestingDuration)")},
+	{"GetMediaDataRef", (PyCFunction)MediaObj_GetMediaDataRef, 1,
+	 PyDoc_STR("(short index) -> (Handle dataRef, OSType dataRefType, long dataRefAttributes)")},
+	{"SetMediaDataRef", (PyCFunction)MediaObj_SetMediaDataRef, 1,
+	 PyDoc_STR("(short index, Handle dataRef, OSType dataRefType) -> None")},
+	{"SetMediaDataRefAttributes", (PyCFunction)MediaObj_SetMediaDataRefAttributes, 1,
+	 PyDoc_STR("(short index, long dataRefAttributes) -> None")},
+	{"AddMediaDataRef", (PyCFunction)MediaObj_AddMediaDataRef, 1,
+	 PyDoc_STR("(Handle dataRef, OSType dataRefType) -> (short index)")},
+	{"GetMediaDataRefCount", (PyCFunction)MediaObj_GetMediaDataRefCount, 1,
+	 PyDoc_STR("() -> (short count)")},
+	{"SetMediaPlayHints", (PyCFunction)MediaObj_SetMediaPlayHints, 1,
+	 PyDoc_STR("(long flags, long flagsMask) -> None")},
+	{"GetMediaPlayHints", (PyCFunction)MediaObj_GetMediaPlayHints, 1,
+	 PyDoc_STR("() -> (long flags)")},
+	{"GetMediaNextInterestingTimeOnly", (PyCFunction)MediaObj_GetMediaNextInterestingTimeOnly, 1,
+	 PyDoc_STR("(short interestingTimeFlags, TimeValue time, Fixed rate) -> (TimeValue interestingTime)")},
+	{NULL, NULL, 0}
+};
+
+#define MediaObj_getsetlist NULL
+
+
+#define MediaObj_compare NULL
+
+#define MediaObj_repr NULL
+
+#define MediaObj_hash NULL
+#define MediaObj_tp_init 0
+
+#define MediaObj_tp_alloc PyType_GenericAlloc
+
+static PyObject *MediaObj_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *_self;
+	Media itself;
+	char *kw[] = {"itself", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, MediaObj_Convert, &itself)) return NULL;
+	if ((_self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	((MediaObject *)_self)->ob_itself = itself;
+	return _self;
+}
+
+#define MediaObj_tp_free PyObject_Del
+
+
+PyTypeObject Media_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"_Qt.Media", /*tp_name*/
+	sizeof(MediaObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) MediaObj_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) MediaObj_compare, /*tp_compare*/
+	(reprfunc) MediaObj_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) MediaObj_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	MediaObj_methods, /* tp_methods */
+	0, /*tp_members*/
+	MediaObj_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	MediaObj_tp_init, /* tp_init */
+	MediaObj_tp_alloc, /* tp_alloc */
+	MediaObj_tp_new, /* tp_new */
+	MediaObj_tp_free, /* tp_free */
+};
+
+/* --------------------- End object type Media ---------------------- */
+
+
+/* ----------------------- Object type Track ------------------------ */
+
+PyTypeObject Track_Type;
+
+#define TrackObj_Check(x) ((x)->ob_type == &Track_Type || PyObject_TypeCheck((x), &Track_Type))
+
+typedef struct TrackObject {
+	PyObject_HEAD
+	Track ob_itself;
+} TrackObject;
+
+PyObject *TrackObj_New(Track itself)
+{
+	TrackObject *it;
+	if (itself == NULL) {
+	                                PyErr_SetString(Qt_Error,"Cannot create Track from NULL pointer");
+	                                return NULL;
+	                        }
+	it = PyObject_NEW(TrackObject, &Track_Type);
+	if (it == NULL) return NULL;
+	it->ob_itself = itself;
+	return (PyObject *)it;
+}
+
+int TrackObj_Convert(PyObject *v, Track *p_itself)
+{
+	if (v == Py_None)
+	{
+		*p_itself = NULL;
+		return 1;
+	}
+	if (!TrackObj_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "Track required");
+		return 0;
+	}
+	*p_itself = ((TrackObject *)v)->ob_itself;
+	return 1;
+}
+
+static void TrackObj_dealloc(TrackObject *self)
+{
+	if (self->ob_itself) DisposeMovieTrack(self->ob_itself);
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *TrackObj_LoadTrackIntoRam(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	TimeValue time;
+	TimeValue duration;
+	long flags;
+#ifndef LoadTrackIntoRam
+	PyMac_PRECHECK(LoadTrackIntoRam);
+#endif
+	if (!PyArg_ParseTuple(_args, "lll",
+	                      &time,
+	                      &duration,
+	                      &flags))
+		return NULL;
+	_err = LoadTrackIntoRam(_self->ob_itself,
+	                        time,
+	                        duration,
+	                        flags);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TrackObj_GetTrackPict(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PicHandle _rv;
+	TimeValue time;
+#ifndef GetTrackPict
+	PyMac_PRECHECK(GetTrackPict);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &time))
+		return NULL;
+	_rv = GetTrackPict(_self->ob_itself,
+	                   time);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *TrackObj_GetTrackClipRgn(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle _rv;
+#ifndef GetTrackClipRgn
+	PyMac_PRECHECK(GetTrackClipRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetTrackClipRgn(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *TrackObj_SetTrackClipRgn(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle theClip;
+#ifndef SetTrackClipRgn
+	PyMac_PRECHECK(SetTrackClipRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &theClip))
+		return NULL;
+	SetTrackClipRgn(_self->ob_itself,
+	                theClip);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TrackObj_GetTrackDisplayBoundsRgn(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle _rv;
+#ifndef GetTrackDisplayBoundsRgn
+	PyMac_PRECHECK(GetTrackDisplayBoundsRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetTrackDisplayBoundsRgn(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *TrackObj_GetTrackMovieBoundsRgn(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle _rv;
+#ifndef GetTrackMovieBoundsRgn
+	PyMac_PRECHECK(GetTrackMovieBoundsRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetTrackMovieBoundsRgn(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *TrackObj_GetTrackBoundsRgn(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle _rv;
+#ifndef GetTrackBoundsRgn
+	PyMac_PRECHECK(GetTrackBoundsRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetTrackBoundsRgn(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *TrackObj_GetTrackMatte(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PixMapHandle _rv;
+#ifndef GetTrackMatte
+	PyMac_PRECHECK(GetTrackMatte);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetTrackMatte(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *TrackObj_SetTrackMatte(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PixMapHandle theMatte;
+#ifndef SetTrackMatte
+	PyMac_PRECHECK(SetTrackMatte);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &theMatte))
+		return NULL;
+	SetTrackMatte(_self->ob_itself,
+	              theMatte);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TrackObj_GetTrackID(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long _rv;
+#ifndef GetTrackID
+	PyMac_PRECHECK(GetTrackID);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetTrackID(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *TrackObj_GetTrackMovie(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Movie _rv;
+#ifndef GetTrackMovie
+	PyMac_PRECHECK(GetTrackMovie);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetTrackMovie(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     MovieObj_New, _rv);
+	return _res;
+}
+
+static PyObject *TrackObj_GetTrackCreationTime(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	unsigned long _rv;
+#ifndef GetTrackCreationTime
+	PyMac_PRECHECK(GetTrackCreationTime);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetTrackCreationTime(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *TrackObj_GetTrackModificationTime(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	unsigned long _rv;
+#ifndef GetTrackModificationTime
+	PyMac_PRECHECK(GetTrackModificationTime);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetTrackModificationTime(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *TrackObj_GetTrackEnabled(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+#ifndef GetTrackEnabled
+	PyMac_PRECHECK(GetTrackEnabled);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetTrackEnabled(_self->ob_itself);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *TrackObj_SetTrackEnabled(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean isEnabled;
+#ifndef SetTrackEnabled
+	PyMac_PRECHECK(SetTrackEnabled);
+#endif
+	if (!PyArg_ParseTuple(_args, "b",
+	                      &isEnabled))
+		return NULL;
+	SetTrackEnabled(_self->ob_itself,
+	                isEnabled);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TrackObj_GetTrackUsage(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long _rv;
+#ifndef GetTrackUsage
+	PyMac_PRECHECK(GetTrackUsage);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetTrackUsage(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *TrackObj_SetTrackUsage(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long usage;
+#ifndef SetTrackUsage
+	PyMac_PRECHECK(SetTrackUsage);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &usage))
+		return NULL;
+	SetTrackUsage(_self->ob_itself,
+	              usage);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TrackObj_GetTrackDuration(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	TimeValue _rv;
+#ifndef GetTrackDuration
+	PyMac_PRECHECK(GetTrackDuration);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetTrackDuration(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *TrackObj_GetTrackOffset(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	TimeValue _rv;
+#ifndef GetTrackOffset
+	PyMac_PRECHECK(GetTrackOffset);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetTrackOffset(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *TrackObj_SetTrackOffset(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	TimeValue movieOffsetTime;
+#ifndef SetTrackOffset
+	PyMac_PRECHECK(SetTrackOffset);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &movieOffsetTime))
+		return NULL;
+	SetTrackOffset(_self->ob_itself,
+	               movieOffsetTime);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TrackObj_GetTrackLayer(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short _rv;
+#ifndef GetTrackLayer
+	PyMac_PRECHECK(GetTrackLayer);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetTrackLayer(_self->ob_itself);
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *TrackObj_SetTrackLayer(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short layer;
+#ifndef SetTrackLayer
+	PyMac_PRECHECK(SetTrackLayer);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &layer))
+		return NULL;
+	SetTrackLayer(_self->ob_itself,
+	              layer);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TrackObj_GetTrackAlternate(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Track _rv;
+#ifndef GetTrackAlternate
+	PyMac_PRECHECK(GetTrackAlternate);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetTrackAlternate(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     TrackObj_New, _rv);
+	return _res;
+}
+
+static PyObject *TrackObj_SetTrackAlternate(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Track alternateT;
+#ifndef SetTrackAlternate
+	PyMac_PRECHECK(SetTrackAlternate);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      TrackObj_Convert, &alternateT))
+		return NULL;
+	SetTrackAlternate(_self->ob_itself,
+	                  alternateT);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TrackObj_GetTrackVolume(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short _rv;
+#ifndef GetTrackVolume
+	PyMac_PRECHECK(GetTrackVolume);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetTrackVolume(_self->ob_itself);
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *TrackObj_SetTrackVolume(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short volume;
+#ifndef SetTrackVolume
+	PyMac_PRECHECK(SetTrackVolume);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &volume))
+		return NULL;
+	SetTrackVolume(_self->ob_itself,
+	               volume);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TrackObj_GetTrackDimensions(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Fixed width;
+	Fixed height;
+#ifndef GetTrackDimensions
+	PyMac_PRECHECK(GetTrackDimensions);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	GetTrackDimensions(_self->ob_itself,
+	                   &width,
+	                   &height);
+	_res = Py_BuildValue("O&O&",
+	                     PyMac_BuildFixed, width,
+	                     PyMac_BuildFixed, height);
+	return _res;
+}
+
+static PyObject *TrackObj_SetTrackDimensions(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Fixed width;
+	Fixed height;
+#ifndef SetTrackDimensions
+	PyMac_PRECHECK(SetTrackDimensions);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetFixed, &width,
+	                      PyMac_GetFixed, &height))
+		return NULL;
+	SetTrackDimensions(_self->ob_itself,
+	                   width,
+	                   height);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TrackObj_GetTrackUserData(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	UserData _rv;
+#ifndef GetTrackUserData
+	PyMac_PRECHECK(GetTrackUserData);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetTrackUserData(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     UserDataObj_New, _rv);
+	return _res;
+}
+
+static PyObject *TrackObj_GetTrackSoundLocalizationSettings(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Handle settings;
+#ifndef GetTrackSoundLocalizationSettings
+	PyMac_PRECHECK(GetTrackSoundLocalizationSettings);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetTrackSoundLocalizationSettings(_self->ob_itself,
+	                                         &settings);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, settings);
+	return _res;
+}
+
+static PyObject *TrackObj_SetTrackSoundLocalizationSettings(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Handle settings;
+#ifndef SetTrackSoundLocalizationSettings
+	PyMac_PRECHECK(SetTrackSoundLocalizationSettings);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &settings))
+		return NULL;
+	_err = SetTrackSoundLocalizationSettings(_self->ob_itself,
+	                                         settings);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TrackObj_NewTrackMedia(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Media _rv;
+	OSType mediaType;
+	TimeScale timeScale;
+	Handle dataRef;
+	OSType dataRefType;
+#ifndef NewTrackMedia
+	PyMac_PRECHECK(NewTrackMedia);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&lO&O&",
+	                      PyMac_GetOSType, &mediaType,
+	                      &timeScale,
+	                      ResObj_Convert, &dataRef,
+	                      PyMac_GetOSType, &dataRefType))
+		return NULL;
+	_rv = NewTrackMedia(_self->ob_itself,
+	                    mediaType,
+	                    timeScale,
+	                    dataRef,
+	                    dataRefType);
+	_res = Py_BuildValue("O&",
+	                     MediaObj_New, _rv);
+	return _res;
+}
+
+static PyObject *TrackObj_GetTrackMedia(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Media _rv;
+#ifndef GetTrackMedia
+	PyMac_PRECHECK(GetTrackMedia);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetTrackMedia(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     MediaObj_New, _rv);
+	return _res;
+}
+
+static PyObject *TrackObj_InsertMediaIntoTrack(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	TimeValue trackStart;
+	TimeValue mediaTime;
+	TimeValue mediaDuration;
+	Fixed mediaRate;
+#ifndef InsertMediaIntoTrack
+	PyMac_PRECHECK(InsertMediaIntoTrack);
+#endif
+	if (!PyArg_ParseTuple(_args, "lllO&",
+	                      &trackStart,
+	                      &mediaTime,
+	                      &mediaDuration,
+	                      PyMac_GetFixed, &mediaRate))
+		return NULL;
+	_err = InsertMediaIntoTrack(_self->ob_itself,
+	                            trackStart,
+	                            mediaTime,
+	                            mediaDuration,
+	                            mediaRate);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TrackObj_InsertTrackSegment(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Track dstTrack;
+	TimeValue srcIn;
+	TimeValue srcDuration;
+	TimeValue dstIn;
+#ifndef InsertTrackSegment
+	PyMac_PRECHECK(InsertTrackSegment);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&lll",
+	                      TrackObj_Convert, &dstTrack,
+	                      &srcIn,
+	                      &srcDuration,
+	                      &dstIn))
+		return NULL;
+	_err = InsertTrackSegment(_self->ob_itself,
+	                          dstTrack,
+	                          srcIn,
+	                          srcDuration,
+	                          dstIn);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TrackObj_InsertEmptyTrackSegment(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	TimeValue dstIn;
+	TimeValue dstDuration;
+#ifndef InsertEmptyTrackSegment
+	PyMac_PRECHECK(InsertEmptyTrackSegment);
+#endif
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &dstIn,
+	                      &dstDuration))
+		return NULL;
+	_err = InsertEmptyTrackSegment(_self->ob_itself,
+	                               dstIn,
+	                               dstDuration);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TrackObj_DeleteTrackSegment(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	TimeValue startTime;
+	TimeValue duration;
+#ifndef DeleteTrackSegment
+	PyMac_PRECHECK(DeleteTrackSegment);
+#endif
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &startTime,
+	                      &duration))
+		return NULL;
+	_err = DeleteTrackSegment(_self->ob_itself,
+	                          startTime,
+	                          duration);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TrackObj_ScaleTrackSegment(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	TimeValue startTime;
+	TimeValue oldDuration;
+	TimeValue newDuration;
+#ifndef ScaleTrackSegment
+	PyMac_PRECHECK(ScaleTrackSegment);
+#endif
+	if (!PyArg_ParseTuple(_args, "lll",
+	                      &startTime,
+	                      &oldDuration,
+	                      &newDuration))
+		return NULL;
+	_err = ScaleTrackSegment(_self->ob_itself,
+	                         startTime,
+	                         oldDuration,
+	                         newDuration);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TrackObj_IsScrapMovie(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Component _rv;
+#ifndef IsScrapMovie
+	PyMac_PRECHECK(IsScrapMovie);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = IsScrapMovie(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     CmpObj_New, _rv);
+	return _res;
+}
+
+static PyObject *TrackObj_CopyTrackSettings(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Track dstTrack;
+#ifndef CopyTrackSettings
+	PyMac_PRECHECK(CopyTrackSettings);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      TrackObj_Convert, &dstTrack))
+		return NULL;
+	_err = CopyTrackSettings(_self->ob_itself,
+	                         dstTrack);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TrackObj_AddEmptyTrackToMovie(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Movie dstMovie;
+	Handle dataRef;
+	OSType dataRefType;
+	Track dstTrack;
+#ifndef AddEmptyTrackToMovie
+	PyMac_PRECHECK(AddEmptyTrackToMovie);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      MovieObj_Convert, &dstMovie,
+	                      ResObj_Convert, &dataRef,
+	                      PyMac_GetOSType, &dataRefType))
+		return NULL;
+	_err = AddEmptyTrackToMovie(_self->ob_itself,
+	                            dstMovie,
+	                            dataRef,
+	                            dataRefType,
+	                            &dstTrack);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     TrackObj_New, dstTrack);
+	return _res;
+}
+
+static PyObject *TrackObj_AddClonedTrackToMovie(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Movie dstMovie;
+	long flags;
+	Track dstTrack;
+#ifndef AddClonedTrackToMovie
+	PyMac_PRECHECK(AddClonedTrackToMovie);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      MovieObj_Convert, &dstMovie,
+	                      &flags))
+		return NULL;
+	_err = AddClonedTrackToMovie(_self->ob_itself,
+	                             dstMovie,
+	                             flags,
+	                             &dstTrack);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     TrackObj_New, dstTrack);
+	return _res;
+}
+
+static PyObject *TrackObj_AddTrackReference(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Track refTrack;
+	OSType refType;
+	long addedIndex;
+#ifndef AddTrackReference
+	PyMac_PRECHECK(AddTrackReference);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      TrackObj_Convert, &refTrack,
+	                      PyMac_GetOSType, &refType))
+		return NULL;
+	_err = AddTrackReference(_self->ob_itself,
+	                         refTrack,
+	                         refType,
+	                         &addedIndex);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     addedIndex);
+	return _res;
+}
+
+static PyObject *TrackObj_DeleteTrackReference(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	OSType refType;
+	long index;
+#ifndef DeleteTrackReference
+	PyMac_PRECHECK(DeleteTrackReference);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      PyMac_GetOSType, &refType,
+	                      &index))
+		return NULL;
+	_err = DeleteTrackReference(_self->ob_itself,
+	                            refType,
+	                            index);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TrackObj_SetTrackReference(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Track refTrack;
+	OSType refType;
+	long index;
+#ifndef SetTrackReference
+	PyMac_PRECHECK(SetTrackReference);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&l",
+	                      TrackObj_Convert, &refTrack,
+	                      PyMac_GetOSType, &refType,
+	                      &index))
+		return NULL;
+	_err = SetTrackReference(_self->ob_itself,
+	                         refTrack,
+	                         refType,
+	                         index);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TrackObj_GetTrackReference(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Track _rv;
+	OSType refType;
+	long index;
+#ifndef GetTrackReference
+	PyMac_PRECHECK(GetTrackReference);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      PyMac_GetOSType, &refType,
+	                      &index))
+		return NULL;
+	_rv = GetTrackReference(_self->ob_itself,
+	                        refType,
+	                        index);
+	_res = Py_BuildValue("O&",
+	                     TrackObj_New, _rv);
+	return _res;
+}
+
+static PyObject *TrackObj_GetNextTrackReferenceType(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSType _rv;
+	OSType refType;
+#ifndef GetNextTrackReferenceType
+	PyMac_PRECHECK(GetNextTrackReferenceType);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetOSType, &refType))
+		return NULL;
+	_rv = GetNextTrackReferenceType(_self->ob_itself,
+	                                refType);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildOSType, _rv);
+	return _res;
+}
+
+static PyObject *TrackObj_GetTrackReferenceCount(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long _rv;
+	OSType refType;
+#ifndef GetTrackReferenceCount
+	PyMac_PRECHECK(GetTrackReferenceCount);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetOSType, &refType))
+		return NULL;
+	_rv = GetTrackReferenceCount(_self->ob_itself,
+	                             refType);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *TrackObj_GetTrackEditRate(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Fixed _rv;
+	TimeValue atTime;
+#ifndef GetTrackEditRate
+	PyMac_PRECHECK(GetTrackEditRate);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &atTime))
+		return NULL;
+	_rv = GetTrackEditRate(_self->ob_itself,
+	                       atTime);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildFixed, _rv);
+	return _res;
+}
+
+static PyObject *TrackObj_GetTrackDataSize(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long _rv;
+	TimeValue startTime;
+	TimeValue duration;
+#ifndef GetTrackDataSize
+	PyMac_PRECHECK(GetTrackDataSize);
+#endif
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &startTime,
+	                      &duration))
+		return NULL;
+	_rv = GetTrackDataSize(_self->ob_itself,
+	                       startTime,
+	                       duration);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *TrackObj_GetTrackDataSize64(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	TimeValue startTime;
+	TimeValue duration;
+	wide dataSize;
+#ifndef GetTrackDataSize64
+	PyMac_PRECHECK(GetTrackDataSize64);
+#endif
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &startTime,
+	                      &duration))
+		return NULL;
+	_err = GetTrackDataSize64(_self->ob_itself,
+	                          startTime,
+	                          duration,
+	                          &dataSize);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     PyMac_Buildwide, dataSize);
+	return _res;
+}
+
+static PyObject *TrackObj_PtInTrack(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	Point pt;
+#ifndef PtInTrack
+	PyMac_PRECHECK(PtInTrack);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetPoint, &pt))
+		return NULL;
+	_rv = PtInTrack(_self->ob_itself,
+	                pt);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *TrackObj_CopyTrackUserData(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Track dstTrack;
+	OSType copyRule;
+#ifndef CopyTrackUserData
+	PyMac_PRECHECK(CopyTrackUserData);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      TrackObj_Convert, &dstTrack,
+	                      PyMac_GetOSType, &copyRule))
+		return NULL;
+	_err = CopyTrackUserData(_self->ob_itself,
+	                         dstTrack,
+	                         copyRule);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TrackObj_GetTrackNextInterestingTime(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short interestingTimeFlags;
+	TimeValue time;
+	Fixed rate;
+	TimeValue interestingTime;
+	TimeValue interestingDuration;
+#ifndef GetTrackNextInterestingTime
+	PyMac_PRECHECK(GetTrackNextInterestingTime);
+#endif
+	if (!PyArg_ParseTuple(_args, "hlO&",
+	                      &interestingTimeFlags,
+	                      &time,
+	                      PyMac_GetFixed, &rate))
+		return NULL;
+	GetTrackNextInterestingTime(_self->ob_itself,
+	                            interestingTimeFlags,
+	                            time,
+	                            rate,
+	                            &interestingTime,
+	                            &interestingDuration);
+	_res = Py_BuildValue("ll",
+	                     interestingTime,
+	                     interestingDuration);
+	return _res;
+}
+
+static PyObject *TrackObj_GetTrackSegmentDisplayBoundsRgn(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle _rv;
+	TimeValue time;
+	TimeValue duration;
+#ifndef GetTrackSegmentDisplayBoundsRgn
+	PyMac_PRECHECK(GetTrackSegmentDisplayBoundsRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &time,
+	                      &duration))
+		return NULL;
+	_rv = GetTrackSegmentDisplayBoundsRgn(_self->ob_itself,
+	                                      time,
+	                                      duration);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *TrackObj_GetTrackStatus(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+#ifndef GetTrackStatus
+	PyMac_PRECHECK(GetTrackStatus);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetTrackStatus(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *TrackObj_SetTrackLoadSettings(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	TimeValue preloadTime;
+	TimeValue preloadDuration;
+	long preloadFlags;
+	long defaultHints;
+#ifndef SetTrackLoadSettings
+	PyMac_PRECHECK(SetTrackLoadSettings);
+#endif
+	if (!PyArg_ParseTuple(_args, "llll",
+	                      &preloadTime,
+	                      &preloadDuration,
+	                      &preloadFlags,
+	                      &defaultHints))
+		return NULL;
+	SetTrackLoadSettings(_self->ob_itself,
+	                     preloadTime,
+	                     preloadDuration,
+	                     preloadFlags,
+	                     defaultHints);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TrackObj_GetTrackLoadSettings(TrackObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	TimeValue preloadTime;
+	TimeValue preloadDuration;
+	long preloadFlags;
+	long defaultHints;
+#ifndef GetTrackLoadSettings
+	PyMac_PRECHECK(GetTrackLoadSettings);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	GetTrackLoadSettings(_self->ob_itself,
+	                     &preloadTime,
+	                     &preloadDuration,
+	                     &preloadFlags,
+	                     &defaultHints);
+	_res = Py_BuildValue("llll",
+	                     preloadTime,
+	                     preloadDuration,
+	                     preloadFlags,
+	                     defaultHints);
+	return _res;
+}
+
+static PyMethodDef TrackObj_methods[] = {
+	{"LoadTrackIntoRam", (PyCFunction)TrackObj_LoadTrackIntoRam, 1,
+	 PyDoc_STR("(TimeValue time, TimeValue duration, long flags) -> None")},
+	{"GetTrackPict", (PyCFunction)TrackObj_GetTrackPict, 1,
+	 PyDoc_STR("(TimeValue time) -> (PicHandle _rv)")},
+	{"GetTrackClipRgn", (PyCFunction)TrackObj_GetTrackClipRgn, 1,
+	 PyDoc_STR("() -> (RgnHandle _rv)")},
+	{"SetTrackClipRgn", (PyCFunction)TrackObj_SetTrackClipRgn, 1,
+	 PyDoc_STR("(RgnHandle theClip) -> None")},
+	{"GetTrackDisplayBoundsRgn", (PyCFunction)TrackObj_GetTrackDisplayBoundsRgn, 1,
+	 PyDoc_STR("() -> (RgnHandle _rv)")},
+	{"GetTrackMovieBoundsRgn", (PyCFunction)TrackObj_GetTrackMovieBoundsRgn, 1,
+	 PyDoc_STR("() -> (RgnHandle _rv)")},
+	{"GetTrackBoundsRgn", (PyCFunction)TrackObj_GetTrackBoundsRgn, 1,
+	 PyDoc_STR("() -> (RgnHandle _rv)")},
+	{"GetTrackMatte", (PyCFunction)TrackObj_GetTrackMatte, 1,
+	 PyDoc_STR("() -> (PixMapHandle _rv)")},
+	{"SetTrackMatte", (PyCFunction)TrackObj_SetTrackMatte, 1,
+	 PyDoc_STR("(PixMapHandle theMatte) -> None")},
+	{"GetTrackID", (PyCFunction)TrackObj_GetTrackID, 1,
+	 PyDoc_STR("() -> (long _rv)")},
+	{"GetTrackMovie", (PyCFunction)TrackObj_GetTrackMovie, 1,
+	 PyDoc_STR("() -> (Movie _rv)")},
+	{"GetTrackCreationTime", (PyCFunction)TrackObj_GetTrackCreationTime, 1,
+	 PyDoc_STR("() -> (unsigned long _rv)")},
+	{"GetTrackModificationTime", (PyCFunction)TrackObj_GetTrackModificationTime, 1,
+	 PyDoc_STR("() -> (unsigned long _rv)")},
+	{"GetTrackEnabled", (PyCFunction)TrackObj_GetTrackEnabled, 1,
+	 PyDoc_STR("() -> (Boolean _rv)")},
+	{"SetTrackEnabled", (PyCFunction)TrackObj_SetTrackEnabled, 1,
+	 PyDoc_STR("(Boolean isEnabled) -> None")},
+	{"GetTrackUsage", (PyCFunction)TrackObj_GetTrackUsage, 1,
+	 PyDoc_STR("() -> (long _rv)")},
+	{"SetTrackUsage", (PyCFunction)TrackObj_SetTrackUsage, 1,
+	 PyDoc_STR("(long usage) -> None")},
+	{"GetTrackDuration", (PyCFunction)TrackObj_GetTrackDuration, 1,
+	 PyDoc_STR("() -> (TimeValue _rv)")},
+	{"GetTrackOffset", (PyCFunction)TrackObj_GetTrackOffset, 1,
+	 PyDoc_STR("() -> (TimeValue _rv)")},
+	{"SetTrackOffset", (PyCFunction)TrackObj_SetTrackOffset, 1,
+	 PyDoc_STR("(TimeValue movieOffsetTime) -> None")},
+	{"GetTrackLayer", (PyCFunction)TrackObj_GetTrackLayer, 1,
+	 PyDoc_STR("() -> (short _rv)")},
+	{"SetTrackLayer", (PyCFunction)TrackObj_SetTrackLayer, 1,
+	 PyDoc_STR("(short layer) -> None")},
+	{"GetTrackAlternate", (PyCFunction)TrackObj_GetTrackAlternate, 1,
+	 PyDoc_STR("() -> (Track _rv)")},
+	{"SetTrackAlternate", (PyCFunction)TrackObj_SetTrackAlternate, 1,
+	 PyDoc_STR("(Track alternateT) -> None")},
+	{"GetTrackVolume", (PyCFunction)TrackObj_GetTrackVolume, 1,
+	 PyDoc_STR("() -> (short _rv)")},
+	{"SetTrackVolume", (PyCFunction)TrackObj_SetTrackVolume, 1,
+	 PyDoc_STR("(short volume) -> None")},
+	{"GetTrackDimensions", (PyCFunction)TrackObj_GetTrackDimensions, 1,
+	 PyDoc_STR("() -> (Fixed width, Fixed height)")},
+	{"SetTrackDimensions", (PyCFunction)TrackObj_SetTrackDimensions, 1,
+	 PyDoc_STR("(Fixed width, Fixed height) -> None")},
+	{"GetTrackUserData", (PyCFunction)TrackObj_GetTrackUserData, 1,
+	 PyDoc_STR("() -> (UserData _rv)")},
+	{"GetTrackSoundLocalizationSettings", (PyCFunction)TrackObj_GetTrackSoundLocalizationSettings, 1,
+	 PyDoc_STR("() -> (Handle settings)")},
+	{"SetTrackSoundLocalizationSettings", (PyCFunction)TrackObj_SetTrackSoundLocalizationSettings, 1,
+	 PyDoc_STR("(Handle settings) -> None")},
+	{"NewTrackMedia", (PyCFunction)TrackObj_NewTrackMedia, 1,
+	 PyDoc_STR("(OSType mediaType, TimeScale timeScale, Handle dataRef, OSType dataRefType) -> (Media _rv)")},
+	{"GetTrackMedia", (PyCFunction)TrackObj_GetTrackMedia, 1,
+	 PyDoc_STR("() -> (Media _rv)")},
+	{"InsertMediaIntoTrack", (PyCFunction)TrackObj_InsertMediaIntoTrack, 1,
+	 PyDoc_STR("(TimeValue trackStart, TimeValue mediaTime, TimeValue mediaDuration, Fixed mediaRate) -> None")},
+	{"InsertTrackSegment", (PyCFunction)TrackObj_InsertTrackSegment, 1,
+	 PyDoc_STR("(Track dstTrack, TimeValue srcIn, TimeValue srcDuration, TimeValue dstIn) -> None")},
+	{"InsertEmptyTrackSegment", (PyCFunction)TrackObj_InsertEmptyTrackSegment, 1,
+	 PyDoc_STR("(TimeValue dstIn, TimeValue dstDuration) -> None")},
+	{"DeleteTrackSegment", (PyCFunction)TrackObj_DeleteTrackSegment, 1,
+	 PyDoc_STR("(TimeValue startTime, TimeValue duration) -> None")},
+	{"ScaleTrackSegment", (PyCFunction)TrackObj_ScaleTrackSegment, 1,
+	 PyDoc_STR("(TimeValue startTime, TimeValue oldDuration, TimeValue newDuration) -> None")},
+	{"IsScrapMovie", (PyCFunction)TrackObj_IsScrapMovie, 1,
+	 PyDoc_STR("() -> (Component _rv)")},
+	{"CopyTrackSettings", (PyCFunction)TrackObj_CopyTrackSettings, 1,
+	 PyDoc_STR("(Track dstTrack) -> None")},
+	{"AddEmptyTrackToMovie", (PyCFunction)TrackObj_AddEmptyTrackToMovie, 1,
+	 PyDoc_STR("(Movie dstMovie, Handle dataRef, OSType dataRefType) -> (Track dstTrack)")},
+	{"AddClonedTrackToMovie", (PyCFunction)TrackObj_AddClonedTrackToMovie, 1,
+	 PyDoc_STR("(Movie dstMovie, long flags) -> (Track dstTrack)")},
+	{"AddTrackReference", (PyCFunction)TrackObj_AddTrackReference, 1,
+	 PyDoc_STR("(Track refTrack, OSType refType) -> (long addedIndex)")},
+	{"DeleteTrackReference", (PyCFunction)TrackObj_DeleteTrackReference, 1,
+	 PyDoc_STR("(OSType refType, long index) -> None")},
+	{"SetTrackReference", (PyCFunction)TrackObj_SetTrackReference, 1,
+	 PyDoc_STR("(Track refTrack, OSType refType, long index) -> None")},
+	{"GetTrackReference", (PyCFunction)TrackObj_GetTrackReference, 1,
+	 PyDoc_STR("(OSType refType, long index) -> (Track _rv)")},
+	{"GetNextTrackReferenceType", (PyCFunction)TrackObj_GetNextTrackReferenceType, 1,
+	 PyDoc_STR("(OSType refType) -> (OSType _rv)")},
+	{"GetTrackReferenceCount", (PyCFunction)TrackObj_GetTrackReferenceCount, 1,
+	 PyDoc_STR("(OSType refType) -> (long _rv)")},
+	{"GetTrackEditRate", (PyCFunction)TrackObj_GetTrackEditRate, 1,
+	 PyDoc_STR("(TimeValue atTime) -> (Fixed _rv)")},
+	{"GetTrackDataSize", (PyCFunction)TrackObj_GetTrackDataSize, 1,
+	 PyDoc_STR("(TimeValue startTime, TimeValue duration) -> (long _rv)")},
+	{"GetTrackDataSize64", (PyCFunction)TrackObj_GetTrackDataSize64, 1,
+	 PyDoc_STR("(TimeValue startTime, TimeValue duration) -> (wide dataSize)")},
+	{"PtInTrack", (PyCFunction)TrackObj_PtInTrack, 1,
+	 PyDoc_STR("(Point pt) -> (Boolean _rv)")},
+	{"CopyTrackUserData", (PyCFunction)TrackObj_CopyTrackUserData, 1,
+	 PyDoc_STR("(Track dstTrack, OSType copyRule) -> None")},
+	{"GetTrackNextInterestingTime", (PyCFunction)TrackObj_GetTrackNextInterestingTime, 1,
+	 PyDoc_STR("(short interestingTimeFlags, TimeValue time, Fixed rate) -> (TimeValue interestingTime, TimeValue interestingDuration)")},
+	{"GetTrackSegmentDisplayBoundsRgn", (PyCFunction)TrackObj_GetTrackSegmentDisplayBoundsRgn, 1,
+	 PyDoc_STR("(TimeValue time, TimeValue duration) -> (RgnHandle _rv)")},
+	{"GetTrackStatus", (PyCFunction)TrackObj_GetTrackStatus, 1,
+	 PyDoc_STR("() -> (ComponentResult _rv)")},
+	{"SetTrackLoadSettings", (PyCFunction)TrackObj_SetTrackLoadSettings, 1,
+	 PyDoc_STR("(TimeValue preloadTime, TimeValue preloadDuration, long preloadFlags, long defaultHints) -> None")},
+	{"GetTrackLoadSettings", (PyCFunction)TrackObj_GetTrackLoadSettings, 1,
+	 PyDoc_STR("() -> (TimeValue preloadTime, TimeValue preloadDuration, long preloadFlags, long defaultHints)")},
+	{NULL, NULL, 0}
+};
+
+#define TrackObj_getsetlist NULL
+
+
+#define TrackObj_compare NULL
+
+#define TrackObj_repr NULL
+
+#define TrackObj_hash NULL
+#define TrackObj_tp_init 0
+
+#define TrackObj_tp_alloc PyType_GenericAlloc
+
+static PyObject *TrackObj_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *_self;
+	Track itself;
+	char *kw[] = {"itself", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, TrackObj_Convert, &itself)) return NULL;
+	if ((_self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	((TrackObject *)_self)->ob_itself = itself;
+	return _self;
+}
+
+#define TrackObj_tp_free PyObject_Del
+
+
+PyTypeObject Track_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"_Qt.Track", /*tp_name*/
+	sizeof(TrackObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) TrackObj_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) TrackObj_compare, /*tp_compare*/
+	(reprfunc) TrackObj_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) TrackObj_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	TrackObj_methods, /* tp_methods */
+	0, /*tp_members*/
+	TrackObj_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	TrackObj_tp_init, /* tp_init */
+	TrackObj_tp_alloc, /* tp_alloc */
+	TrackObj_tp_new, /* tp_new */
+	TrackObj_tp_free, /* tp_free */
+};
+
+/* --------------------- End object type Track ---------------------- */
+
+
+/* ----------------------- Object type Movie ------------------------ */
+
+PyTypeObject Movie_Type;
+
+#define MovieObj_Check(x) ((x)->ob_type == &Movie_Type || PyObject_TypeCheck((x), &Movie_Type))
+
+typedef struct MovieObject {
+	PyObject_HEAD
+	Movie ob_itself;
+} MovieObject;
+
+PyObject *MovieObj_New(Movie itself)
+{
+	MovieObject *it;
+	if (itself == NULL) {
+	                                PyErr_SetString(Qt_Error,"Cannot create Movie from NULL pointer");
+	                                return NULL;
+	                        }
+	it = PyObject_NEW(MovieObject, &Movie_Type);
+	if (it == NULL) return NULL;
+	it->ob_itself = itself;
+	return (PyObject *)it;
+}
+
+int MovieObj_Convert(PyObject *v, Movie *p_itself)
+{
+	if (v == Py_None)
+	{
+		*p_itself = NULL;
+		return 1;
+	}
+	if (!MovieObj_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "Movie required");
+		return 0;
+	}
+	*p_itself = ((MovieObject *)v)->ob_itself;
+	return 1;
+}
+
+static void MovieObj_dealloc(MovieObject *self)
+{
+	if (self->ob_itself) DisposeMovie(self->ob_itself);
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *MovieObj_MoviesTask(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long maxMilliSecToUse;
+#ifndef MoviesTask
+	PyMac_PRECHECK(MoviesTask);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &maxMilliSecToUse))
+		return NULL;
+	MoviesTask(_self->ob_itself,
+	           maxMilliSecToUse);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_PrerollMovie(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	TimeValue time;
+	Fixed Rate;
+#ifndef PrerollMovie
+	PyMac_PRECHECK(PrerollMovie);
+#endif
+	if (!PyArg_ParseTuple(_args, "lO&",
+	                      &time,
+	                      PyMac_GetFixed, &Rate))
+		return NULL;
+	_err = PrerollMovie(_self->ob_itself,
+	                    time,
+	                    Rate);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_AbortPrePrerollMovie(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr err;
+#ifndef AbortPrePrerollMovie
+	PyMac_PRECHECK(AbortPrePrerollMovie);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &err))
+		return NULL;
+	AbortPrePrerollMovie(_self->ob_itself,
+	                     err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_LoadMovieIntoRam(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	TimeValue time;
+	TimeValue duration;
+	long flags;
+#ifndef LoadMovieIntoRam
+	PyMac_PRECHECK(LoadMovieIntoRam);
+#endif
+	if (!PyArg_ParseTuple(_args, "lll",
+	                      &time,
+	                      &duration,
+	                      &flags))
+		return NULL;
+	_err = LoadMovieIntoRam(_self->ob_itself,
+	                        time,
+	                        duration,
+	                        flags);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_SetMovieActive(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean active;
+#ifndef SetMovieActive
+	PyMac_PRECHECK(SetMovieActive);
+#endif
+	if (!PyArg_ParseTuple(_args, "b",
+	                      &active))
+		return NULL;
+	SetMovieActive(_self->ob_itself,
+	               active);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_GetMovieActive(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+#ifndef GetMovieActive
+	PyMac_PRECHECK(GetMovieActive);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetMovieActive(_self->ob_itself);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MovieObj_StartMovie(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef StartMovie
+	PyMac_PRECHECK(StartMovie);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	StartMovie(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_StopMovie(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef StopMovie
+	PyMac_PRECHECK(StopMovie);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	StopMovie(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_GoToBeginningOfMovie(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef GoToBeginningOfMovie
+	PyMac_PRECHECK(GoToBeginningOfMovie);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	GoToBeginningOfMovie(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_GoToEndOfMovie(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef GoToEndOfMovie
+	PyMac_PRECHECK(GoToEndOfMovie);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	GoToEndOfMovie(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_IsMovieDone(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+#ifndef IsMovieDone
+	PyMac_PRECHECK(IsMovieDone);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = IsMovieDone(_self->ob_itself);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MovieObj_GetMoviePreviewMode(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+#ifndef GetMoviePreviewMode
+	PyMac_PRECHECK(GetMoviePreviewMode);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetMoviePreviewMode(_self->ob_itself);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MovieObj_SetMoviePreviewMode(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean usePreview;
+#ifndef SetMoviePreviewMode
+	PyMac_PRECHECK(SetMoviePreviewMode);
+#endif
+	if (!PyArg_ParseTuple(_args, "b",
+	                      &usePreview))
+		return NULL;
+	SetMoviePreviewMode(_self->ob_itself,
+	                    usePreview);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_ShowMoviePoster(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef ShowMoviePoster
+	PyMac_PRECHECK(ShowMoviePoster);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	ShowMoviePoster(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_GetMovieTimeBase(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	TimeBase _rv;
+#ifndef GetMovieTimeBase
+	PyMac_PRECHECK(GetMovieTimeBase);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetMovieTimeBase(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     TimeBaseObj_New, _rv);
+	return _res;
+}
+
+static PyObject *MovieObj_SetMovieMasterTimeBase(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	TimeBase tb;
+	TimeRecord slaveZero;
+#ifndef SetMovieMasterTimeBase
+	PyMac_PRECHECK(SetMovieMasterTimeBase);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      TimeBaseObj_Convert, &tb,
+	                      QtTimeRecord_Convert, &slaveZero))
+		return NULL;
+	SetMovieMasterTimeBase(_self->ob_itself,
+	                       tb,
+	                       &slaveZero);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_SetMovieMasterClock(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Component clockMeister;
+	TimeRecord slaveZero;
+#ifndef SetMovieMasterClock
+	PyMac_PRECHECK(SetMovieMasterClock);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &clockMeister,
+	                      QtTimeRecord_Convert, &slaveZero))
+		return NULL;
+	SetMovieMasterClock(_self->ob_itself,
+	                    clockMeister,
+	                    &slaveZero);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_ChooseMovieClock(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long flags;
+#ifndef ChooseMovieClock
+	PyMac_PRECHECK(ChooseMovieClock);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &flags))
+		return NULL;
+	ChooseMovieClock(_self->ob_itself,
+	                 flags);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_GetMovieGWorld(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CGrafPtr port;
+	GDHandle gdh;
+#ifndef GetMovieGWorld
+	PyMac_PRECHECK(GetMovieGWorld);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	GetMovieGWorld(_self->ob_itself,
+	               &port,
+	               &gdh);
+	_res = Py_BuildValue("O&O&",
+	                     GrafObj_New, port,
+	                     OptResObj_New, gdh);
+	return _res;
+}
+
+static PyObject *MovieObj_SetMovieGWorld(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CGrafPtr port;
+	GDHandle gdh;
+#ifndef SetMovieGWorld
+	PyMac_PRECHECK(SetMovieGWorld);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      GrafObj_Convert, &port,
+	                      OptResObj_Convert, &gdh))
+		return NULL;
+	SetMovieGWorld(_self->ob_itself,
+	               port,
+	               gdh);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_GetMovieNaturalBoundsRect(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect naturalBounds;
+#ifndef GetMovieNaturalBoundsRect
+	PyMac_PRECHECK(GetMovieNaturalBoundsRect);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	GetMovieNaturalBoundsRect(_self->ob_itself,
+	                          &naturalBounds);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildRect, &naturalBounds);
+	return _res;
+}
+
+static PyObject *MovieObj_GetNextTrackForCompositing(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Track _rv;
+	Track theTrack;
+#ifndef GetNextTrackForCompositing
+	PyMac_PRECHECK(GetNextTrackForCompositing);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      TrackObj_Convert, &theTrack))
+		return NULL;
+	_rv = GetNextTrackForCompositing(_self->ob_itself,
+	                                 theTrack);
+	_res = Py_BuildValue("O&",
+	                     TrackObj_New, _rv);
+	return _res;
+}
+
+static PyObject *MovieObj_GetPrevTrackForCompositing(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Track _rv;
+	Track theTrack;
+#ifndef GetPrevTrackForCompositing
+	PyMac_PRECHECK(GetPrevTrackForCompositing);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      TrackObj_Convert, &theTrack))
+		return NULL;
+	_rv = GetPrevTrackForCompositing(_self->ob_itself,
+	                                 theTrack);
+	_res = Py_BuildValue("O&",
+	                     TrackObj_New, _rv);
+	return _res;
+}
+
+static PyObject *MovieObj_GetMoviePict(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PicHandle _rv;
+	TimeValue time;
+#ifndef GetMoviePict
+	PyMac_PRECHECK(GetMoviePict);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &time))
+		return NULL;
+	_rv = GetMoviePict(_self->ob_itself,
+	                   time);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *MovieObj_GetMoviePosterPict(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PicHandle _rv;
+#ifndef GetMoviePosterPict
+	PyMac_PRECHECK(GetMoviePosterPict);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetMoviePosterPict(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *MovieObj_UpdateMovie(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+#ifndef UpdateMovie
+	PyMac_PRECHECK(UpdateMovie);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = UpdateMovie(_self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_InvalidateMovieRegion(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	RgnHandle invalidRgn;
+#ifndef InvalidateMovieRegion
+	PyMac_PRECHECK(InvalidateMovieRegion);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &invalidRgn))
+		return NULL;
+	_err = InvalidateMovieRegion(_self->ob_itself,
+	                             invalidRgn);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_GetMovieBox(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect boxRect;
+#ifndef GetMovieBox
+	PyMac_PRECHECK(GetMovieBox);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	GetMovieBox(_self->ob_itself,
+	            &boxRect);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildRect, &boxRect);
+	return _res;
+}
+
+static PyObject *MovieObj_SetMovieBox(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect boxRect;
+#ifndef SetMovieBox
+	PyMac_PRECHECK(SetMovieBox);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetRect, &boxRect))
+		return NULL;
+	SetMovieBox(_self->ob_itself,
+	            &boxRect);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_GetMovieDisplayClipRgn(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle _rv;
+#ifndef GetMovieDisplayClipRgn
+	PyMac_PRECHECK(GetMovieDisplayClipRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetMovieDisplayClipRgn(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *MovieObj_SetMovieDisplayClipRgn(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle theClip;
+#ifndef SetMovieDisplayClipRgn
+	PyMac_PRECHECK(SetMovieDisplayClipRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &theClip))
+		return NULL;
+	SetMovieDisplayClipRgn(_self->ob_itself,
+	                       theClip);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_GetMovieClipRgn(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle _rv;
+#ifndef GetMovieClipRgn
+	PyMac_PRECHECK(GetMovieClipRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetMovieClipRgn(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *MovieObj_SetMovieClipRgn(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle theClip;
+#ifndef SetMovieClipRgn
+	PyMac_PRECHECK(SetMovieClipRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &theClip))
+		return NULL;
+	SetMovieClipRgn(_self->ob_itself,
+	                theClip);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_GetMovieDisplayBoundsRgn(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle _rv;
+#ifndef GetMovieDisplayBoundsRgn
+	PyMac_PRECHECK(GetMovieDisplayBoundsRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetMovieDisplayBoundsRgn(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *MovieObj_GetMovieBoundsRgn(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle _rv;
+#ifndef GetMovieBoundsRgn
+	PyMac_PRECHECK(GetMovieBoundsRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetMovieBoundsRgn(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *MovieObj_SetMovieVideoOutput(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentInstance vout;
+#ifndef SetMovieVideoOutput
+	PyMac_PRECHECK(SetMovieVideoOutput);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &vout))
+		return NULL;
+	SetMovieVideoOutput(_self->ob_itself,
+	                    vout);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_PutMovieIntoHandle(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Handle publicMovie;
+#ifndef PutMovieIntoHandle
+	PyMac_PRECHECK(PutMovieIntoHandle);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &publicMovie))
+		return NULL;
+	_err = PutMovieIntoHandle(_self->ob_itself,
+	                          publicMovie);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_PutMovieIntoDataFork(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short fRefNum;
+	long offset;
+	long maxSize;
+#ifndef PutMovieIntoDataFork
+	PyMac_PRECHECK(PutMovieIntoDataFork);
+#endif
+	if (!PyArg_ParseTuple(_args, "hll",
+	                      &fRefNum,
+	                      &offset,
+	                      &maxSize))
+		return NULL;
+	_err = PutMovieIntoDataFork(_self->ob_itself,
+	                            fRefNum,
+	                            offset,
+	                            maxSize);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_PutMovieIntoDataFork64(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	long fRefNum;
+	wide offset;
+	unsigned long maxSize;
+#ifndef PutMovieIntoDataFork64
+	PyMac_PRECHECK(PutMovieIntoDataFork64);
+#endif
+	if (!PyArg_ParseTuple(_args, "lO&l",
+	                      &fRefNum,
+	                      PyMac_Getwide, &offset,
+	                      &maxSize))
+		return NULL;
+	_err = PutMovieIntoDataFork64(_self->ob_itself,
+	                              fRefNum,
+	                              &offset,
+	                              maxSize);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_PutMovieIntoStorage(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	DataHandler dh;
+	wide offset;
+	unsigned long maxSize;
+#ifndef PutMovieIntoStorage
+	PyMac_PRECHECK(PutMovieIntoStorage);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&l",
+	                      CmpInstObj_Convert, &dh,
+	                      PyMac_Getwide, &offset,
+	                      &maxSize))
+		return NULL;
+	_err = PutMovieIntoStorage(_self->ob_itself,
+	                           dh,
+	                           &offset,
+	                           maxSize);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_PutMovieForDataRefIntoHandle(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Handle dataRef;
+	OSType dataRefType;
+	Handle publicMovie;
+#ifndef PutMovieForDataRefIntoHandle
+	PyMac_PRECHECK(PutMovieForDataRefIntoHandle);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      ResObj_Convert, &dataRef,
+	                      PyMac_GetOSType, &dataRefType,
+	                      ResObj_Convert, &publicMovie))
+		return NULL;
+	_err = PutMovieForDataRefIntoHandle(_self->ob_itself,
+	                                    dataRef,
+	                                    dataRefType,
+	                                    publicMovie);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_GetMovieCreationTime(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	unsigned long _rv;
+#ifndef GetMovieCreationTime
+	PyMac_PRECHECK(GetMovieCreationTime);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetMovieCreationTime(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MovieObj_GetMovieModificationTime(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	unsigned long _rv;
+#ifndef GetMovieModificationTime
+	PyMac_PRECHECK(GetMovieModificationTime);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetMovieModificationTime(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MovieObj_GetMovieTimeScale(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	TimeScale _rv;
+#ifndef GetMovieTimeScale
+	PyMac_PRECHECK(GetMovieTimeScale);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetMovieTimeScale(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MovieObj_SetMovieTimeScale(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	TimeScale timeScale;
+#ifndef SetMovieTimeScale
+	PyMac_PRECHECK(SetMovieTimeScale);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &timeScale))
+		return NULL;
+	SetMovieTimeScale(_self->ob_itself,
+	                  timeScale);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_GetMovieDuration(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	TimeValue _rv;
+#ifndef GetMovieDuration
+	PyMac_PRECHECK(GetMovieDuration);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetMovieDuration(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MovieObj_GetMovieRate(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Fixed _rv;
+#ifndef GetMovieRate
+	PyMac_PRECHECK(GetMovieRate);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetMovieRate(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildFixed, _rv);
+	return _res;
+}
+
+static PyObject *MovieObj_SetMovieRate(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Fixed rate;
+#ifndef SetMovieRate
+	PyMac_PRECHECK(SetMovieRate);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetFixed, &rate))
+		return NULL;
+	SetMovieRate(_self->ob_itself,
+	             rate);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_GetMoviePreferredRate(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Fixed _rv;
+#ifndef GetMoviePreferredRate
+	PyMac_PRECHECK(GetMoviePreferredRate);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetMoviePreferredRate(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildFixed, _rv);
+	return _res;
+}
+
+static PyObject *MovieObj_SetMoviePreferredRate(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Fixed rate;
+#ifndef SetMoviePreferredRate
+	PyMac_PRECHECK(SetMoviePreferredRate);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetFixed, &rate))
+		return NULL;
+	SetMoviePreferredRate(_self->ob_itself,
+	                      rate);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_GetMoviePreferredVolume(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short _rv;
+#ifndef GetMoviePreferredVolume
+	PyMac_PRECHECK(GetMoviePreferredVolume);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetMoviePreferredVolume(_self->ob_itself);
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MovieObj_SetMoviePreferredVolume(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short volume;
+#ifndef SetMoviePreferredVolume
+	PyMac_PRECHECK(SetMoviePreferredVolume);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &volume))
+		return NULL;
+	SetMoviePreferredVolume(_self->ob_itself,
+	                        volume);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_GetMovieVolume(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short _rv;
+#ifndef GetMovieVolume
+	PyMac_PRECHECK(GetMovieVolume);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetMovieVolume(_self->ob_itself);
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MovieObj_SetMovieVolume(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short volume;
+#ifndef SetMovieVolume
+	PyMac_PRECHECK(SetMovieVolume);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &volume))
+		return NULL;
+	SetMovieVolume(_self->ob_itself,
+	               volume);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_GetMoviePreviewTime(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	TimeValue previewTime;
+	TimeValue previewDuration;
+#ifndef GetMoviePreviewTime
+	PyMac_PRECHECK(GetMoviePreviewTime);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	GetMoviePreviewTime(_self->ob_itself,
+	                    &previewTime,
+	                    &previewDuration);
+	_res = Py_BuildValue("ll",
+	                     previewTime,
+	                     previewDuration);
+	return _res;
+}
+
+static PyObject *MovieObj_SetMoviePreviewTime(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	TimeValue previewTime;
+	TimeValue previewDuration;
+#ifndef SetMoviePreviewTime
+	PyMac_PRECHECK(SetMoviePreviewTime);
+#endif
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &previewTime,
+	                      &previewDuration))
+		return NULL;
+	SetMoviePreviewTime(_self->ob_itself,
+	                    previewTime,
+	                    previewDuration);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_GetMoviePosterTime(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	TimeValue _rv;
+#ifndef GetMoviePosterTime
+	PyMac_PRECHECK(GetMoviePosterTime);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetMoviePosterTime(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MovieObj_SetMoviePosterTime(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	TimeValue posterTime;
+#ifndef SetMoviePosterTime
+	PyMac_PRECHECK(SetMoviePosterTime);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &posterTime))
+		return NULL;
+	SetMoviePosterTime(_self->ob_itself,
+	                   posterTime);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_GetMovieSelection(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	TimeValue selectionTime;
+	TimeValue selectionDuration;
+#ifndef GetMovieSelection
+	PyMac_PRECHECK(GetMovieSelection);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	GetMovieSelection(_self->ob_itself,
+	                  &selectionTime,
+	                  &selectionDuration);
+	_res = Py_BuildValue("ll",
+	                     selectionTime,
+	                     selectionDuration);
+	return _res;
+}
+
+static PyObject *MovieObj_SetMovieSelection(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	TimeValue selectionTime;
+	TimeValue selectionDuration;
+#ifndef SetMovieSelection
+	PyMac_PRECHECK(SetMovieSelection);
+#endif
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &selectionTime,
+	                      &selectionDuration))
+		return NULL;
+	SetMovieSelection(_self->ob_itself,
+	                  selectionTime,
+	                  selectionDuration);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_SetMovieActiveSegment(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	TimeValue startTime;
+	TimeValue duration;
+#ifndef SetMovieActiveSegment
+	PyMac_PRECHECK(SetMovieActiveSegment);
+#endif
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &startTime,
+	                      &duration))
+		return NULL;
+	SetMovieActiveSegment(_self->ob_itself,
+	                      startTime,
+	                      duration);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_GetMovieActiveSegment(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	TimeValue startTime;
+	TimeValue duration;
+#ifndef GetMovieActiveSegment
+	PyMac_PRECHECK(GetMovieActiveSegment);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	GetMovieActiveSegment(_self->ob_itself,
+	                      &startTime,
+	                      &duration);
+	_res = Py_BuildValue("ll",
+	                     startTime,
+	                     duration);
+	return _res;
+}
+
+static PyObject *MovieObj_GetMovieTime(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	TimeValue _rv;
+	TimeRecord currentTime;
+#ifndef GetMovieTime
+	PyMac_PRECHECK(GetMovieTime);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetMovieTime(_self->ob_itself,
+	                   &currentTime);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     QtTimeRecord_New, &currentTime);
+	return _res;
+}
+
+static PyObject *MovieObj_SetMovieTime(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	TimeRecord newtime;
+#ifndef SetMovieTime
+	PyMac_PRECHECK(SetMovieTime);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      QtTimeRecord_Convert, &newtime))
+		return NULL;
+	SetMovieTime(_self->ob_itself,
+	             &newtime);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_SetMovieTimeValue(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	TimeValue newtime;
+#ifndef SetMovieTimeValue
+	PyMac_PRECHECK(SetMovieTimeValue);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &newtime))
+		return NULL;
+	SetMovieTimeValue(_self->ob_itself,
+	                  newtime);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_GetMovieUserData(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	UserData _rv;
+#ifndef GetMovieUserData
+	PyMac_PRECHECK(GetMovieUserData);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetMovieUserData(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     UserDataObj_New, _rv);
+	return _res;
+}
+
+static PyObject *MovieObj_GetMovieTrackCount(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long _rv;
+#ifndef GetMovieTrackCount
+	PyMac_PRECHECK(GetMovieTrackCount);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetMovieTrackCount(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MovieObj_GetMovieTrack(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Track _rv;
+	long trackID;
+#ifndef GetMovieTrack
+	PyMac_PRECHECK(GetMovieTrack);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &trackID))
+		return NULL;
+	_rv = GetMovieTrack(_self->ob_itself,
+	                    trackID);
+	_res = Py_BuildValue("O&",
+	                     TrackObj_New, _rv);
+	return _res;
+}
+
+static PyObject *MovieObj_GetMovieIndTrack(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Track _rv;
+	long index;
+#ifndef GetMovieIndTrack
+	PyMac_PRECHECK(GetMovieIndTrack);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &index))
+		return NULL;
+	_rv = GetMovieIndTrack(_self->ob_itself,
+	                       index);
+	_res = Py_BuildValue("O&",
+	                     TrackObj_New, _rv);
+	return _res;
+}
+
+static PyObject *MovieObj_GetMovieIndTrackType(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Track _rv;
+	long index;
+	OSType trackType;
+	long flags;
+#ifndef GetMovieIndTrackType
+	PyMac_PRECHECK(GetMovieIndTrackType);
+#endif
+	if (!PyArg_ParseTuple(_args, "lO&l",
+	                      &index,
+	                      PyMac_GetOSType, &trackType,
+	                      &flags))
+		return NULL;
+	_rv = GetMovieIndTrackType(_self->ob_itself,
+	                           index,
+	                           trackType,
+	                           flags);
+	_res = Py_BuildValue("O&",
+	                     TrackObj_New, _rv);
+	return _res;
+}
+
+static PyObject *MovieObj_NewMovieTrack(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Track _rv;
+	Fixed width;
+	Fixed height;
+	short trackVolume;
+#ifndef NewMovieTrack
+	PyMac_PRECHECK(NewMovieTrack);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&h",
+	                      PyMac_GetFixed, &width,
+	                      PyMac_GetFixed, &height,
+	                      &trackVolume))
+		return NULL;
+	_rv = NewMovieTrack(_self->ob_itself,
+	                    width,
+	                    height,
+	                    trackVolume);
+	_res = Py_BuildValue("O&",
+	                     TrackObj_New, _rv);
+	return _res;
+}
+
+static PyObject *MovieObj_SetAutoTrackAlternatesEnabled(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean enable;
+#ifndef SetAutoTrackAlternatesEnabled
+	PyMac_PRECHECK(SetAutoTrackAlternatesEnabled);
+#endif
+	if (!PyArg_ParseTuple(_args, "b",
+	                      &enable))
+		return NULL;
+	SetAutoTrackAlternatesEnabled(_self->ob_itself,
+	                              enable);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_SelectMovieAlternates(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef SelectMovieAlternates
+	PyMac_PRECHECK(SelectMovieAlternates);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	SelectMovieAlternates(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_InsertMovieSegment(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Movie dstMovie;
+	TimeValue srcIn;
+	TimeValue srcDuration;
+	TimeValue dstIn;
+#ifndef InsertMovieSegment
+	PyMac_PRECHECK(InsertMovieSegment);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&lll",
+	                      MovieObj_Convert, &dstMovie,
+	                      &srcIn,
+	                      &srcDuration,
+	                      &dstIn))
+		return NULL;
+	_err = InsertMovieSegment(_self->ob_itself,
+	                          dstMovie,
+	                          srcIn,
+	                          srcDuration,
+	                          dstIn);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_InsertEmptyMovieSegment(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	TimeValue dstIn;
+	TimeValue dstDuration;
+#ifndef InsertEmptyMovieSegment
+	PyMac_PRECHECK(InsertEmptyMovieSegment);
+#endif
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &dstIn,
+	                      &dstDuration))
+		return NULL;
+	_err = InsertEmptyMovieSegment(_self->ob_itself,
+	                               dstIn,
+	                               dstDuration);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_DeleteMovieSegment(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	TimeValue startTime;
+	TimeValue duration;
+#ifndef DeleteMovieSegment
+	PyMac_PRECHECK(DeleteMovieSegment);
+#endif
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &startTime,
+	                      &duration))
+		return NULL;
+	_err = DeleteMovieSegment(_self->ob_itself,
+	                          startTime,
+	                          duration);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_ScaleMovieSegment(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	TimeValue startTime;
+	TimeValue oldDuration;
+	TimeValue newDuration;
+#ifndef ScaleMovieSegment
+	PyMac_PRECHECK(ScaleMovieSegment);
+#endif
+	if (!PyArg_ParseTuple(_args, "lll",
+	                      &startTime,
+	                      &oldDuration,
+	                      &newDuration))
+		return NULL;
+	_err = ScaleMovieSegment(_self->ob_itself,
+	                         startTime,
+	                         oldDuration,
+	                         newDuration);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_CutMovieSelection(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Movie _rv;
+#ifndef CutMovieSelection
+	PyMac_PRECHECK(CutMovieSelection);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CutMovieSelection(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     MovieObj_New, _rv);
+	return _res;
+}
+
+static PyObject *MovieObj_CopyMovieSelection(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Movie _rv;
+#ifndef CopyMovieSelection
+	PyMac_PRECHECK(CopyMovieSelection);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CopyMovieSelection(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     MovieObj_New, _rv);
+	return _res;
+}
+
+static PyObject *MovieObj_PasteMovieSelection(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Movie src;
+#ifndef PasteMovieSelection
+	PyMac_PRECHECK(PasteMovieSelection);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      MovieObj_Convert, &src))
+		return NULL;
+	PasteMovieSelection(_self->ob_itself,
+	                    src);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_AddMovieSelection(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Movie src;
+#ifndef AddMovieSelection
+	PyMac_PRECHECK(AddMovieSelection);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      MovieObj_Convert, &src))
+		return NULL;
+	AddMovieSelection(_self->ob_itself,
+	                  src);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_ClearMovieSelection(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef ClearMovieSelection
+	PyMac_PRECHECK(ClearMovieSelection);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	ClearMovieSelection(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_PutMovieIntoTypedHandle(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Track targetTrack;
+	OSType handleType;
+	Handle publicMovie;
+	TimeValue start;
+	TimeValue dur;
+	long flags;
+	ComponentInstance userComp;
+#ifndef PutMovieIntoTypedHandle
+	PyMac_PRECHECK(PutMovieIntoTypedHandle);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&lllO&",
+	                      TrackObj_Convert, &targetTrack,
+	                      PyMac_GetOSType, &handleType,
+	                      ResObj_Convert, &publicMovie,
+	                      &start,
+	                      &dur,
+	                      &flags,
+	                      CmpInstObj_Convert, &userComp))
+		return NULL;
+	_err = PutMovieIntoTypedHandle(_self->ob_itself,
+	                               targetTrack,
+	                               handleType,
+	                               publicMovie,
+	                               start,
+	                               dur,
+	                               flags,
+	                               userComp);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_CopyMovieSettings(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Movie dstMovie;
+#ifndef CopyMovieSettings
+	PyMac_PRECHECK(CopyMovieSettings);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      MovieObj_Convert, &dstMovie))
+		return NULL;
+	_err = CopyMovieSettings(_self->ob_itself,
+	                         dstMovie);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_ConvertMovieToFile(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Track onlyTrack;
+	FSSpec outputFile;
+	OSType fileType;
+	OSType creator;
+	ScriptCode scriptTag;
+	short resID;
+	long flags;
+	ComponentInstance userComp;
+#ifndef ConvertMovieToFile
+	PyMac_PRECHECK(ConvertMovieToFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&O&hlO&",
+	                      TrackObj_Convert, &onlyTrack,
+	                      PyMac_GetFSSpec, &outputFile,
+	                      PyMac_GetOSType, &fileType,
+	                      PyMac_GetOSType, &creator,
+	                      &scriptTag,
+	                      &flags,
+	                      CmpInstObj_Convert, &userComp))
+		return NULL;
+	_err = ConvertMovieToFile(_self->ob_itself,
+	                          onlyTrack,
+	                          &outputFile,
+	                          fileType,
+	                          creator,
+	                          scriptTag,
+	                          &resID,
+	                          flags,
+	                          userComp);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("h",
+	                     resID);
+	return _res;
+}
+
+static PyObject *MovieObj_GetMovieDataSize(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long _rv;
+	TimeValue startTime;
+	TimeValue duration;
+#ifndef GetMovieDataSize
+	PyMac_PRECHECK(GetMovieDataSize);
+#endif
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &startTime,
+	                      &duration))
+		return NULL;
+	_rv = GetMovieDataSize(_self->ob_itself,
+	                       startTime,
+	                       duration);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MovieObj_GetMovieDataSize64(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	TimeValue startTime;
+	TimeValue duration;
+	wide dataSize;
+#ifndef GetMovieDataSize64
+	PyMac_PRECHECK(GetMovieDataSize64);
+#endif
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &startTime,
+	                      &duration))
+		return NULL;
+	_err = GetMovieDataSize64(_self->ob_itself,
+	                          startTime,
+	                          duration,
+	                          &dataSize);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     PyMac_Buildwide, dataSize);
+	return _res;
+}
+
+static PyObject *MovieObj_PtInMovie(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	Point pt;
+#ifndef PtInMovie
+	PyMac_PRECHECK(PtInMovie);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetPoint, &pt))
+		return NULL;
+	_rv = PtInMovie(_self->ob_itself,
+	                pt);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MovieObj_SetMovieLanguage(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long language;
+#ifndef SetMovieLanguage
+	PyMac_PRECHECK(SetMovieLanguage);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &language))
+		return NULL;
+	SetMovieLanguage(_self->ob_itself,
+	                 language);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_CopyMovieUserData(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Movie dstMovie;
+	OSType copyRule;
+#ifndef CopyMovieUserData
+	PyMac_PRECHECK(CopyMovieUserData);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      MovieObj_Convert, &dstMovie,
+	                      PyMac_GetOSType, &copyRule))
+		return NULL;
+	_err = CopyMovieUserData(_self->ob_itself,
+	                         dstMovie,
+	                         copyRule);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_GetMovieNextInterestingTime(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short interestingTimeFlags;
+	short numMediaTypes;
+	OSType whichMediaTypes;
+	TimeValue time;
+	Fixed rate;
+	TimeValue interestingTime;
+	TimeValue interestingDuration;
+#ifndef GetMovieNextInterestingTime
+	PyMac_PRECHECK(GetMovieNextInterestingTime);
+#endif
+	if (!PyArg_ParseTuple(_args, "hhO&lO&",
+	                      &interestingTimeFlags,
+	                      &numMediaTypes,
+	                      PyMac_GetOSType, &whichMediaTypes,
+	                      &time,
+	                      PyMac_GetFixed, &rate))
+		return NULL;
+	GetMovieNextInterestingTime(_self->ob_itself,
+	                            interestingTimeFlags,
+	                            numMediaTypes,
+	                            &whichMediaTypes,
+	                            time,
+	                            rate,
+	                            &interestingTime,
+	                            &interestingDuration);
+	_res = Py_BuildValue("ll",
+	                     interestingTime,
+	                     interestingDuration);
+	return _res;
+}
+
+static PyObject *MovieObj_AddMovieResource(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short resRefNum;
+	short resId;
+	Str255 resName;
+#ifndef AddMovieResource
+	PyMac_PRECHECK(AddMovieResource);
+#endif
+	if (!PyArg_ParseTuple(_args, "hO&",
+	                      &resRefNum,
+	                      PyMac_GetStr255, resName))
+		return NULL;
+	_err = AddMovieResource(_self->ob_itself,
+	                        resRefNum,
+	                        &resId,
+	                        resName);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("h",
+	                     resId);
+	return _res;
+}
+
+static PyObject *MovieObj_UpdateMovieResource(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short resRefNum;
+	short resId;
+	Str255 resName;
+#ifndef UpdateMovieResource
+	PyMac_PRECHECK(UpdateMovieResource);
+#endif
+	if (!PyArg_ParseTuple(_args, "hhO&",
+	                      &resRefNum,
+	                      &resId,
+	                      PyMac_GetStr255, resName))
+		return NULL;
+	_err = UpdateMovieResource(_self->ob_itself,
+	                           resRefNum,
+	                           resId,
+	                           resName);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_AddMovieToStorage(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	DataHandler dh;
+#ifndef AddMovieToStorage
+	PyMac_PRECHECK(AddMovieToStorage);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &dh))
+		return NULL;
+	_err = AddMovieToStorage(_self->ob_itself,
+	                         dh);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_UpdateMovieInStorage(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	DataHandler dh;
+#ifndef UpdateMovieInStorage
+	PyMac_PRECHECK(UpdateMovieInStorage);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &dh))
+		return NULL;
+	_err = UpdateMovieInStorage(_self->ob_itself,
+	                            dh);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_HasMovieChanged(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+#ifndef HasMovieChanged
+	PyMac_PRECHECK(HasMovieChanged);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = HasMovieChanged(_self->ob_itself);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *MovieObj_ClearMovieChanged(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef ClearMovieChanged
+	PyMac_PRECHECK(ClearMovieChanged);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	ClearMovieChanged(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_SetMovieDefaultDataRef(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Handle dataRef;
+	OSType dataRefType;
+#ifndef SetMovieDefaultDataRef
+	PyMac_PRECHECK(SetMovieDefaultDataRef);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      ResObj_Convert, &dataRef,
+	                      PyMac_GetOSType, &dataRefType))
+		return NULL;
+	_err = SetMovieDefaultDataRef(_self->ob_itself,
+	                              dataRef,
+	                              dataRefType);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_GetMovieDefaultDataRef(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Handle dataRef;
+	OSType dataRefType;
+#ifndef GetMovieDefaultDataRef
+	PyMac_PRECHECK(GetMovieDefaultDataRef);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetMovieDefaultDataRef(_self->ob_itself,
+	                              &dataRef,
+	                              &dataRefType);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&O&",
+	                     ResObj_New, dataRef,
+	                     PyMac_BuildOSType, dataRefType);
+	return _res;
+}
+
+static PyObject *MovieObj_SetMovieColorTable(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	CTabHandle ctab;
+#ifndef SetMovieColorTable
+	PyMac_PRECHECK(SetMovieColorTable);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &ctab))
+		return NULL;
+	_err = SetMovieColorTable(_self->ob_itself,
+	                          ctab);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_GetMovieColorTable(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	CTabHandle ctab;
+#ifndef GetMovieColorTable
+	PyMac_PRECHECK(GetMovieColorTable);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetMovieColorTable(_self->ob_itself,
+	                          &ctab);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, ctab);
+	return _res;
+}
+
+static PyObject *MovieObj_FlattenMovie(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long movieFlattenFlags;
+	FSSpec theFile;
+	OSType creator;
+	ScriptCode scriptTag;
+	long createMovieFileFlags;
+	short resId;
+	Str255 resName;
+#ifndef FlattenMovie
+	PyMac_PRECHECK(FlattenMovie);
+#endif
+	if (!PyArg_ParseTuple(_args, "lO&O&hlO&",
+	                      &movieFlattenFlags,
+	                      PyMac_GetFSSpec, &theFile,
+	                      PyMac_GetOSType, &creator,
+	                      &scriptTag,
+	                      &createMovieFileFlags,
+	                      PyMac_GetStr255, resName))
+		return NULL;
+	FlattenMovie(_self->ob_itself,
+	             movieFlattenFlags,
+	             &theFile,
+	             creator,
+	             scriptTag,
+	             createMovieFileFlags,
+	             &resId,
+	             resName);
+	_res = Py_BuildValue("h",
+	                     resId);
+	return _res;
+}
+
+static PyObject *MovieObj_FlattenMovieData(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Movie _rv;
+	long movieFlattenFlags;
+	FSSpec theFile;
+	OSType creator;
+	ScriptCode scriptTag;
+	long createMovieFileFlags;
+#ifndef FlattenMovieData
+	PyMac_PRECHECK(FlattenMovieData);
+#endif
+	if (!PyArg_ParseTuple(_args, "lO&O&hl",
+	                      &movieFlattenFlags,
+	                      PyMac_GetFSSpec, &theFile,
+	                      PyMac_GetOSType, &creator,
+	                      &scriptTag,
+	                      &createMovieFileFlags))
+		return NULL;
+	_rv = FlattenMovieData(_self->ob_itself,
+	                       movieFlattenFlags,
+	                       &theFile,
+	                       creator,
+	                       scriptTag,
+	                       createMovieFileFlags);
+	_res = Py_BuildValue("O&",
+	                     MovieObj_New, _rv);
+	return _res;
+}
+
+static PyObject *MovieObj_FlattenMovieDataToDataRef(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Movie _rv;
+	long movieFlattenFlags;
+	Handle dataRef;
+	OSType dataRefType;
+	OSType creator;
+	ScriptCode scriptTag;
+	long createMovieFileFlags;
+#ifndef FlattenMovieDataToDataRef
+	PyMac_PRECHECK(FlattenMovieDataToDataRef);
+#endif
+	if (!PyArg_ParseTuple(_args, "lO&O&O&hl",
+	                      &movieFlattenFlags,
+	                      ResObj_Convert, &dataRef,
+	                      PyMac_GetOSType, &dataRefType,
+	                      PyMac_GetOSType, &creator,
+	                      &scriptTag,
+	                      &createMovieFileFlags))
+		return NULL;
+	_rv = FlattenMovieDataToDataRef(_self->ob_itself,
+	                                movieFlattenFlags,
+	                                dataRef,
+	                                dataRefType,
+	                                creator,
+	                                scriptTag,
+	                                createMovieFileFlags);
+	_res = Py_BuildValue("O&",
+	                     MovieObj_New, _rv);
+	return _res;
+}
+
+static PyObject *MovieObj_MovieSearchText(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Ptr text;
+	long size;
+	long searchFlags;
+	Track searchTrack;
+	TimeValue searchTime;
+	long searchOffset;
+#ifndef MovieSearchText
+	PyMac_PRECHECK(MovieSearchText);
+#endif
+	if (!PyArg_ParseTuple(_args, "sll",
+	                      &text,
+	                      &size,
+	                      &searchFlags))
+		return NULL;
+	_err = MovieSearchText(_self->ob_itself,
+	                       text,
+	                       size,
+	                       searchFlags,
+	                       &searchTrack,
+	                       &searchTime,
+	                       &searchOffset);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&ll",
+	                     TrackObj_New, searchTrack,
+	                     searchTime,
+	                     searchOffset);
+	return _res;
+}
+
+static PyObject *MovieObj_GetPosterBox(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect boxRect;
+#ifndef GetPosterBox
+	PyMac_PRECHECK(GetPosterBox);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	GetPosterBox(_self->ob_itself,
+	             &boxRect);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildRect, &boxRect);
+	return _res;
+}
+
+static PyObject *MovieObj_SetPosterBox(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect boxRect;
+#ifndef SetPosterBox
+	PyMac_PRECHECK(SetPosterBox);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetRect, &boxRect))
+		return NULL;
+	SetPosterBox(_self->ob_itself,
+	             &boxRect);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_GetMovieSegmentDisplayBoundsRgn(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle _rv;
+	TimeValue time;
+	TimeValue duration;
+#ifndef GetMovieSegmentDisplayBoundsRgn
+	PyMac_PRECHECK(GetMovieSegmentDisplayBoundsRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &time,
+	                      &duration))
+		return NULL;
+	_rv = GetMovieSegmentDisplayBoundsRgn(_self->ob_itself,
+	                                      time,
+	                                      duration);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *MovieObj_GetMovieStatus(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	Track firstProblemTrack;
+#ifndef GetMovieStatus
+	PyMac_PRECHECK(GetMovieStatus);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetMovieStatus(_self->ob_itself,
+	                     &firstProblemTrack);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     TrackObj_New, firstProblemTrack);
+	return _res;
+}
+
+static PyObject *MovieObj_NewMovieController(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	MovieController _rv;
+	Rect movieRect;
+	long someFlags;
+#ifndef NewMovieController
+	PyMac_PRECHECK(NewMovieController);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      PyMac_GetRect, &movieRect,
+	                      &someFlags))
+		return NULL;
+	_rv = NewMovieController(_self->ob_itself,
+	                         &movieRect,
+	                         someFlags);
+	_res = Py_BuildValue("O&",
+	                     MovieCtlObj_New, _rv);
+	return _res;
+}
+
+static PyObject *MovieObj_PutMovieOnScrap(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	long movieScrapFlags;
+#ifndef PutMovieOnScrap
+	PyMac_PRECHECK(PutMovieOnScrap);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &movieScrapFlags))
+		return NULL;
+	_err = PutMovieOnScrap(_self->ob_itself,
+	                       movieScrapFlags);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_SetMoviePlayHints(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long flags;
+	long flagsMask;
+#ifndef SetMoviePlayHints
+	PyMac_PRECHECK(SetMoviePlayHints);
+#endif
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &flags,
+	                      &flagsMask))
+		return NULL;
+	SetMoviePlayHints(_self->ob_itself,
+	                  flags,
+	                  flagsMask);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *MovieObj_GetMaxLoadedTimeInMovie(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	TimeValue time;
+#ifndef GetMaxLoadedTimeInMovie
+	PyMac_PRECHECK(GetMaxLoadedTimeInMovie);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetMaxLoadedTimeInMovie(_self->ob_itself,
+	                               &time);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     time);
+	return _res;
+}
+
+static PyObject *MovieObj_QTMovieNeedsTimeTable(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Boolean needsTimeTable;
+#ifndef QTMovieNeedsTimeTable
+	PyMac_PRECHECK(QTMovieNeedsTimeTable);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = QTMovieNeedsTimeTable(_self->ob_itself,
+	                             &needsTimeTable);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("b",
+	                     needsTimeTable);
+	return _res;
+}
+
+static PyObject *MovieObj_QTGetDataRefMaxFileOffset(MovieObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	OSType dataRefType;
+	Handle dataRef;
+	long offset;
+#ifndef QTGetDataRefMaxFileOffset
+	PyMac_PRECHECK(QTGetDataRefMaxFileOffset);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetOSType, &dataRefType,
+	                      ResObj_Convert, &dataRef))
+		return NULL;
+	_err = QTGetDataRefMaxFileOffset(_self->ob_itself,
+	                                 dataRefType,
+	                                 dataRef,
+	                                 &offset);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     offset);
+	return _res;
+}
+
+static PyMethodDef MovieObj_methods[] = {
+	{"MoviesTask", (PyCFunction)MovieObj_MoviesTask, 1,
+	 PyDoc_STR("(long maxMilliSecToUse) -> None")},
+	{"PrerollMovie", (PyCFunction)MovieObj_PrerollMovie, 1,
+	 PyDoc_STR("(TimeValue time, Fixed Rate) -> None")},
+	{"AbortPrePrerollMovie", (PyCFunction)MovieObj_AbortPrePrerollMovie, 1,
+	 PyDoc_STR("(OSErr err) -> None")},
+	{"LoadMovieIntoRam", (PyCFunction)MovieObj_LoadMovieIntoRam, 1,
+	 PyDoc_STR("(TimeValue time, TimeValue duration, long flags) -> None")},
+	{"SetMovieActive", (PyCFunction)MovieObj_SetMovieActive, 1,
+	 PyDoc_STR("(Boolean active) -> None")},
+	{"GetMovieActive", (PyCFunction)MovieObj_GetMovieActive, 1,
+	 PyDoc_STR("() -> (Boolean _rv)")},
+	{"StartMovie", (PyCFunction)MovieObj_StartMovie, 1,
+	 PyDoc_STR("() -> None")},
+	{"StopMovie", (PyCFunction)MovieObj_StopMovie, 1,
+	 PyDoc_STR("() -> None")},
+	{"GoToBeginningOfMovie", (PyCFunction)MovieObj_GoToBeginningOfMovie, 1,
+	 PyDoc_STR("() -> None")},
+	{"GoToEndOfMovie", (PyCFunction)MovieObj_GoToEndOfMovie, 1,
+	 PyDoc_STR("() -> None")},
+	{"IsMovieDone", (PyCFunction)MovieObj_IsMovieDone, 1,
+	 PyDoc_STR("() -> (Boolean _rv)")},
+	{"GetMoviePreviewMode", (PyCFunction)MovieObj_GetMoviePreviewMode, 1,
+	 PyDoc_STR("() -> (Boolean _rv)")},
+	{"SetMoviePreviewMode", (PyCFunction)MovieObj_SetMoviePreviewMode, 1,
+	 PyDoc_STR("(Boolean usePreview) -> None")},
+	{"ShowMoviePoster", (PyCFunction)MovieObj_ShowMoviePoster, 1,
+	 PyDoc_STR("() -> None")},
+	{"GetMovieTimeBase", (PyCFunction)MovieObj_GetMovieTimeBase, 1,
+	 PyDoc_STR("() -> (TimeBase _rv)")},
+	{"SetMovieMasterTimeBase", (PyCFunction)MovieObj_SetMovieMasterTimeBase, 1,
+	 PyDoc_STR("(TimeBase tb, TimeRecord slaveZero) -> None")},
+	{"SetMovieMasterClock", (PyCFunction)MovieObj_SetMovieMasterClock, 1,
+	 PyDoc_STR("(Component clockMeister, TimeRecord slaveZero) -> None")},
+	{"ChooseMovieClock", (PyCFunction)MovieObj_ChooseMovieClock, 1,
+	 PyDoc_STR("(long flags) -> None")},
+	{"GetMovieGWorld", (PyCFunction)MovieObj_GetMovieGWorld, 1,
+	 PyDoc_STR("() -> (CGrafPtr port, GDHandle gdh)")},
+	{"SetMovieGWorld", (PyCFunction)MovieObj_SetMovieGWorld, 1,
+	 PyDoc_STR("(CGrafPtr port, GDHandle gdh) -> None")},
+	{"GetMovieNaturalBoundsRect", (PyCFunction)MovieObj_GetMovieNaturalBoundsRect, 1,
+	 PyDoc_STR("() -> (Rect naturalBounds)")},
+	{"GetNextTrackForCompositing", (PyCFunction)MovieObj_GetNextTrackForCompositing, 1,
+	 PyDoc_STR("(Track theTrack) -> (Track _rv)")},
+	{"GetPrevTrackForCompositing", (PyCFunction)MovieObj_GetPrevTrackForCompositing, 1,
+	 PyDoc_STR("(Track theTrack) -> (Track _rv)")},
+	{"GetMoviePict", (PyCFunction)MovieObj_GetMoviePict, 1,
+	 PyDoc_STR("(TimeValue time) -> (PicHandle _rv)")},
+	{"GetMoviePosterPict", (PyCFunction)MovieObj_GetMoviePosterPict, 1,
+	 PyDoc_STR("() -> (PicHandle _rv)")},
+	{"UpdateMovie", (PyCFunction)MovieObj_UpdateMovie, 1,
+	 PyDoc_STR("() -> None")},
+	{"InvalidateMovieRegion", (PyCFunction)MovieObj_InvalidateMovieRegion, 1,
+	 PyDoc_STR("(RgnHandle invalidRgn) -> None")},
+	{"GetMovieBox", (PyCFunction)MovieObj_GetMovieBox, 1,
+	 PyDoc_STR("() -> (Rect boxRect)")},
+	{"SetMovieBox", (PyCFunction)MovieObj_SetMovieBox, 1,
+	 PyDoc_STR("(Rect boxRect) -> None")},
+	{"GetMovieDisplayClipRgn", (PyCFunction)MovieObj_GetMovieDisplayClipRgn, 1,
+	 PyDoc_STR("() -> (RgnHandle _rv)")},
+	{"SetMovieDisplayClipRgn", (PyCFunction)MovieObj_SetMovieDisplayClipRgn, 1,
+	 PyDoc_STR("(RgnHandle theClip) -> None")},
+	{"GetMovieClipRgn", (PyCFunction)MovieObj_GetMovieClipRgn, 1,
+	 PyDoc_STR("() -> (RgnHandle _rv)")},
+	{"SetMovieClipRgn", (PyCFunction)MovieObj_SetMovieClipRgn, 1,
+	 PyDoc_STR("(RgnHandle theClip) -> None")},
+	{"GetMovieDisplayBoundsRgn", (PyCFunction)MovieObj_GetMovieDisplayBoundsRgn, 1,
+	 PyDoc_STR("() -> (RgnHandle _rv)")},
+	{"GetMovieBoundsRgn", (PyCFunction)MovieObj_GetMovieBoundsRgn, 1,
+	 PyDoc_STR("() -> (RgnHandle _rv)")},
+	{"SetMovieVideoOutput", (PyCFunction)MovieObj_SetMovieVideoOutput, 1,
+	 PyDoc_STR("(ComponentInstance vout) -> None")},
+	{"PutMovieIntoHandle", (PyCFunction)MovieObj_PutMovieIntoHandle, 1,
+	 PyDoc_STR("(Handle publicMovie) -> None")},
+	{"PutMovieIntoDataFork", (PyCFunction)MovieObj_PutMovieIntoDataFork, 1,
+	 PyDoc_STR("(short fRefNum, long offset, long maxSize) -> None")},
+	{"PutMovieIntoDataFork64", (PyCFunction)MovieObj_PutMovieIntoDataFork64, 1,
+	 PyDoc_STR("(long fRefNum, wide offset, unsigned long maxSize) -> None")},
+	{"PutMovieIntoStorage", (PyCFunction)MovieObj_PutMovieIntoStorage, 1,
+	 PyDoc_STR("(DataHandler dh, wide offset, unsigned long maxSize) -> None")},
+	{"PutMovieForDataRefIntoHandle", (PyCFunction)MovieObj_PutMovieForDataRefIntoHandle, 1,
+	 PyDoc_STR("(Handle dataRef, OSType dataRefType, Handle publicMovie) -> None")},
+	{"GetMovieCreationTime", (PyCFunction)MovieObj_GetMovieCreationTime, 1,
+	 PyDoc_STR("() -> (unsigned long _rv)")},
+	{"GetMovieModificationTime", (PyCFunction)MovieObj_GetMovieModificationTime, 1,
+	 PyDoc_STR("() -> (unsigned long _rv)")},
+	{"GetMovieTimeScale", (PyCFunction)MovieObj_GetMovieTimeScale, 1,
+	 PyDoc_STR("() -> (TimeScale _rv)")},
+	{"SetMovieTimeScale", (PyCFunction)MovieObj_SetMovieTimeScale, 1,
+	 PyDoc_STR("(TimeScale timeScale) -> None")},
+	{"GetMovieDuration", (PyCFunction)MovieObj_GetMovieDuration, 1,
+	 PyDoc_STR("() -> (TimeValue _rv)")},
+	{"GetMovieRate", (PyCFunction)MovieObj_GetMovieRate, 1,
+	 PyDoc_STR("() -> (Fixed _rv)")},
+	{"SetMovieRate", (PyCFunction)MovieObj_SetMovieRate, 1,
+	 PyDoc_STR("(Fixed rate) -> None")},
+	{"GetMoviePreferredRate", (PyCFunction)MovieObj_GetMoviePreferredRate, 1,
+	 PyDoc_STR("() -> (Fixed _rv)")},
+	{"SetMoviePreferredRate", (PyCFunction)MovieObj_SetMoviePreferredRate, 1,
+	 PyDoc_STR("(Fixed rate) -> None")},
+	{"GetMoviePreferredVolume", (PyCFunction)MovieObj_GetMoviePreferredVolume, 1,
+	 PyDoc_STR("() -> (short _rv)")},
+	{"SetMoviePreferredVolume", (PyCFunction)MovieObj_SetMoviePreferredVolume, 1,
+	 PyDoc_STR("(short volume) -> None")},
+	{"GetMovieVolume", (PyCFunction)MovieObj_GetMovieVolume, 1,
+	 PyDoc_STR("() -> (short _rv)")},
+	{"SetMovieVolume", (PyCFunction)MovieObj_SetMovieVolume, 1,
+	 PyDoc_STR("(short volume) -> None")},
+	{"GetMoviePreviewTime", (PyCFunction)MovieObj_GetMoviePreviewTime, 1,
+	 PyDoc_STR("() -> (TimeValue previewTime, TimeValue previewDuration)")},
+	{"SetMoviePreviewTime", (PyCFunction)MovieObj_SetMoviePreviewTime, 1,
+	 PyDoc_STR("(TimeValue previewTime, TimeValue previewDuration) -> None")},
+	{"GetMoviePosterTime", (PyCFunction)MovieObj_GetMoviePosterTime, 1,
+	 PyDoc_STR("() -> (TimeValue _rv)")},
+	{"SetMoviePosterTime", (PyCFunction)MovieObj_SetMoviePosterTime, 1,
+	 PyDoc_STR("(TimeValue posterTime) -> None")},
+	{"GetMovieSelection", (PyCFunction)MovieObj_GetMovieSelection, 1,
+	 PyDoc_STR("() -> (TimeValue selectionTime, TimeValue selectionDuration)")},
+	{"SetMovieSelection", (PyCFunction)MovieObj_SetMovieSelection, 1,
+	 PyDoc_STR("(TimeValue selectionTime, TimeValue selectionDuration) -> None")},
+	{"SetMovieActiveSegment", (PyCFunction)MovieObj_SetMovieActiveSegment, 1,
+	 PyDoc_STR("(TimeValue startTime, TimeValue duration) -> None")},
+	{"GetMovieActiveSegment", (PyCFunction)MovieObj_GetMovieActiveSegment, 1,
+	 PyDoc_STR("() -> (TimeValue startTime, TimeValue duration)")},
+	{"GetMovieTime", (PyCFunction)MovieObj_GetMovieTime, 1,
+	 PyDoc_STR("() -> (TimeValue _rv, TimeRecord currentTime)")},
+	{"SetMovieTime", (PyCFunction)MovieObj_SetMovieTime, 1,
+	 PyDoc_STR("(TimeRecord newtime) -> None")},
+	{"SetMovieTimeValue", (PyCFunction)MovieObj_SetMovieTimeValue, 1,
+	 PyDoc_STR("(TimeValue newtime) -> None")},
+	{"GetMovieUserData", (PyCFunction)MovieObj_GetMovieUserData, 1,
+	 PyDoc_STR("() -> (UserData _rv)")},
+	{"GetMovieTrackCount", (PyCFunction)MovieObj_GetMovieTrackCount, 1,
+	 PyDoc_STR("() -> (long _rv)")},
+	{"GetMovieTrack", (PyCFunction)MovieObj_GetMovieTrack, 1,
+	 PyDoc_STR("(long trackID) -> (Track _rv)")},
+	{"GetMovieIndTrack", (PyCFunction)MovieObj_GetMovieIndTrack, 1,
+	 PyDoc_STR("(long index) -> (Track _rv)")},
+	{"GetMovieIndTrackType", (PyCFunction)MovieObj_GetMovieIndTrackType, 1,
+	 PyDoc_STR("(long index, OSType trackType, long flags) -> (Track _rv)")},
+	{"NewMovieTrack", (PyCFunction)MovieObj_NewMovieTrack, 1,
+	 PyDoc_STR("(Fixed width, Fixed height, short trackVolume) -> (Track _rv)")},
+	{"SetAutoTrackAlternatesEnabled", (PyCFunction)MovieObj_SetAutoTrackAlternatesEnabled, 1,
+	 PyDoc_STR("(Boolean enable) -> None")},
+	{"SelectMovieAlternates", (PyCFunction)MovieObj_SelectMovieAlternates, 1,
+	 PyDoc_STR("() -> None")},
+	{"InsertMovieSegment", (PyCFunction)MovieObj_InsertMovieSegment, 1,
+	 PyDoc_STR("(Movie dstMovie, TimeValue srcIn, TimeValue srcDuration, TimeValue dstIn) -> None")},
+	{"InsertEmptyMovieSegment", (PyCFunction)MovieObj_InsertEmptyMovieSegment, 1,
+	 PyDoc_STR("(TimeValue dstIn, TimeValue dstDuration) -> None")},
+	{"DeleteMovieSegment", (PyCFunction)MovieObj_DeleteMovieSegment, 1,
+	 PyDoc_STR("(TimeValue startTime, TimeValue duration) -> None")},
+	{"ScaleMovieSegment", (PyCFunction)MovieObj_ScaleMovieSegment, 1,
+	 PyDoc_STR("(TimeValue startTime, TimeValue oldDuration, TimeValue newDuration) -> None")},
+	{"CutMovieSelection", (PyCFunction)MovieObj_CutMovieSelection, 1,
+	 PyDoc_STR("() -> (Movie _rv)")},
+	{"CopyMovieSelection", (PyCFunction)MovieObj_CopyMovieSelection, 1,
+	 PyDoc_STR("() -> (Movie _rv)")},
+	{"PasteMovieSelection", (PyCFunction)MovieObj_PasteMovieSelection, 1,
+	 PyDoc_STR("(Movie src) -> None")},
+	{"AddMovieSelection", (PyCFunction)MovieObj_AddMovieSelection, 1,
+	 PyDoc_STR("(Movie src) -> None")},
+	{"ClearMovieSelection", (PyCFunction)MovieObj_ClearMovieSelection, 1,
+	 PyDoc_STR("() -> None")},
+	{"PutMovieIntoTypedHandle", (PyCFunction)MovieObj_PutMovieIntoTypedHandle, 1,
+	 PyDoc_STR("(Track targetTrack, OSType handleType, Handle publicMovie, TimeValue start, TimeValue dur, long flags, ComponentInstance userComp) -> None")},
+	{"CopyMovieSettings", (PyCFunction)MovieObj_CopyMovieSettings, 1,
+	 PyDoc_STR("(Movie dstMovie) -> None")},
+	{"ConvertMovieToFile", (PyCFunction)MovieObj_ConvertMovieToFile, 1,
+	 PyDoc_STR("(Track onlyTrack, FSSpec outputFile, OSType fileType, OSType creator, ScriptCode scriptTag, long flags, ComponentInstance userComp) -> (short resID)")},
+	{"GetMovieDataSize", (PyCFunction)MovieObj_GetMovieDataSize, 1,
+	 PyDoc_STR("(TimeValue startTime, TimeValue duration) -> (long _rv)")},
+	{"GetMovieDataSize64", (PyCFunction)MovieObj_GetMovieDataSize64, 1,
+	 PyDoc_STR("(TimeValue startTime, TimeValue duration) -> (wide dataSize)")},
+	{"PtInMovie", (PyCFunction)MovieObj_PtInMovie, 1,
+	 PyDoc_STR("(Point pt) -> (Boolean _rv)")},
+	{"SetMovieLanguage", (PyCFunction)MovieObj_SetMovieLanguage, 1,
+	 PyDoc_STR("(long language) -> None")},
+	{"CopyMovieUserData", (PyCFunction)MovieObj_CopyMovieUserData, 1,
+	 PyDoc_STR("(Movie dstMovie, OSType copyRule) -> None")},
+	{"GetMovieNextInterestingTime", (PyCFunction)MovieObj_GetMovieNextInterestingTime, 1,
+	 PyDoc_STR("(short interestingTimeFlags, short numMediaTypes, OSType whichMediaTypes, TimeValue time, Fixed rate) -> (TimeValue interestingTime, TimeValue interestingDuration)")},
+	{"AddMovieResource", (PyCFunction)MovieObj_AddMovieResource, 1,
+	 PyDoc_STR("(short resRefNum, Str255 resName) -> (short resId)")},
+	{"UpdateMovieResource", (PyCFunction)MovieObj_UpdateMovieResource, 1,
+	 PyDoc_STR("(short resRefNum, short resId, Str255 resName) -> None")},
+	{"AddMovieToStorage", (PyCFunction)MovieObj_AddMovieToStorage, 1,
+	 PyDoc_STR("(DataHandler dh) -> None")},
+	{"UpdateMovieInStorage", (PyCFunction)MovieObj_UpdateMovieInStorage, 1,
+	 PyDoc_STR("(DataHandler dh) -> None")},
+	{"HasMovieChanged", (PyCFunction)MovieObj_HasMovieChanged, 1,
+	 PyDoc_STR("() -> (Boolean _rv)")},
+	{"ClearMovieChanged", (PyCFunction)MovieObj_ClearMovieChanged, 1,
+	 PyDoc_STR("() -> None")},
+	{"SetMovieDefaultDataRef", (PyCFunction)MovieObj_SetMovieDefaultDataRef, 1,
+	 PyDoc_STR("(Handle dataRef, OSType dataRefType) -> None")},
+	{"GetMovieDefaultDataRef", (PyCFunction)MovieObj_GetMovieDefaultDataRef, 1,
+	 PyDoc_STR("() -> (Handle dataRef, OSType dataRefType)")},
+	{"SetMovieColorTable", (PyCFunction)MovieObj_SetMovieColorTable, 1,
+	 PyDoc_STR("(CTabHandle ctab) -> None")},
+	{"GetMovieColorTable", (PyCFunction)MovieObj_GetMovieColorTable, 1,
+	 PyDoc_STR("() -> (CTabHandle ctab)")},
+	{"FlattenMovie", (PyCFunction)MovieObj_FlattenMovie, 1,
+	 PyDoc_STR("(long movieFlattenFlags, FSSpec theFile, OSType creator, ScriptCode scriptTag, long createMovieFileFlags, Str255 resName) -> (short resId)")},
+	{"FlattenMovieData", (PyCFunction)MovieObj_FlattenMovieData, 1,
+	 PyDoc_STR("(long movieFlattenFlags, FSSpec theFile, OSType creator, ScriptCode scriptTag, long createMovieFileFlags) -> (Movie _rv)")},
+	{"FlattenMovieDataToDataRef", (PyCFunction)MovieObj_FlattenMovieDataToDataRef, 1,
+	 PyDoc_STR("(long movieFlattenFlags, Handle dataRef, OSType dataRefType, OSType creator, ScriptCode scriptTag, long createMovieFileFlags) -> (Movie _rv)")},
+	{"MovieSearchText", (PyCFunction)MovieObj_MovieSearchText, 1,
+	 PyDoc_STR("(Ptr text, long size, long searchFlags) -> (Track searchTrack, TimeValue searchTime, long searchOffset)")},
+	{"GetPosterBox", (PyCFunction)MovieObj_GetPosterBox, 1,
+	 PyDoc_STR("() -> (Rect boxRect)")},
+	{"SetPosterBox", (PyCFunction)MovieObj_SetPosterBox, 1,
+	 PyDoc_STR("(Rect boxRect) -> None")},
+	{"GetMovieSegmentDisplayBoundsRgn", (PyCFunction)MovieObj_GetMovieSegmentDisplayBoundsRgn, 1,
+	 PyDoc_STR("(TimeValue time, TimeValue duration) -> (RgnHandle _rv)")},
+	{"GetMovieStatus", (PyCFunction)MovieObj_GetMovieStatus, 1,
+	 PyDoc_STR("() -> (ComponentResult _rv, Track firstProblemTrack)")},
+	{"NewMovieController", (PyCFunction)MovieObj_NewMovieController, 1,
+	 PyDoc_STR("(Rect movieRect, long someFlags) -> (MovieController _rv)")},
+	{"PutMovieOnScrap", (PyCFunction)MovieObj_PutMovieOnScrap, 1,
+	 PyDoc_STR("(long movieScrapFlags) -> None")},
+	{"SetMoviePlayHints", (PyCFunction)MovieObj_SetMoviePlayHints, 1,
+	 PyDoc_STR("(long flags, long flagsMask) -> None")},
+	{"GetMaxLoadedTimeInMovie", (PyCFunction)MovieObj_GetMaxLoadedTimeInMovie, 1,
+	 PyDoc_STR("() -> (TimeValue time)")},
+	{"QTMovieNeedsTimeTable", (PyCFunction)MovieObj_QTMovieNeedsTimeTable, 1,
+	 PyDoc_STR("() -> (Boolean needsTimeTable)")},
+	{"QTGetDataRefMaxFileOffset", (PyCFunction)MovieObj_QTGetDataRefMaxFileOffset, 1,
+	 PyDoc_STR("(OSType dataRefType, Handle dataRef) -> (long offset)")},
+	{NULL, NULL, 0}
+};
+
+#define MovieObj_getsetlist NULL
+
+
+#define MovieObj_compare NULL
+
+#define MovieObj_repr NULL
+
+#define MovieObj_hash NULL
+#define MovieObj_tp_init 0
+
+#define MovieObj_tp_alloc PyType_GenericAlloc
+
+static PyObject *MovieObj_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *_self;
+	Movie itself;
+	char *kw[] = {"itself", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, MovieObj_Convert, &itself)) return NULL;
+	if ((_self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	((MovieObject *)_self)->ob_itself = itself;
+	return _self;
+}
+
+#define MovieObj_tp_free PyObject_Del
+
+
+PyTypeObject Movie_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"_Qt.Movie", /*tp_name*/
+	sizeof(MovieObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) MovieObj_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) MovieObj_compare, /*tp_compare*/
+	(reprfunc) MovieObj_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) MovieObj_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	MovieObj_methods, /* tp_methods */
+	0, /*tp_members*/
+	MovieObj_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	MovieObj_tp_init, /* tp_init */
+	MovieObj_tp_alloc, /* tp_alloc */
+	MovieObj_tp_new, /* tp_new */
+	MovieObj_tp_free, /* tp_free */
+};
+
+/* --------------------- End object type Movie ---------------------- */
+
+
+/* ---------------------- Object type SGOutput ---------------------- */
+
+PyTypeObject SGOutput_Type;
+
+#define SGOutputObj_Check(x) ((x)->ob_type == &SGOutput_Type || PyObject_TypeCheck((x), &SGOutput_Type))
+
+typedef struct SGOutputObject {
+	PyObject_HEAD
+	SGOutput ob_itself;
+} SGOutputObject;
+
+PyObject *SGOutputObj_New(SGOutput itself)
+{
+	SGOutputObject *it;
+	if (itself == NULL) {
+	                                PyErr_SetString(Qt_Error,"Cannot create SGOutput from NULL pointer");
+	                                return NULL;
+	                        }
+	it = PyObject_NEW(SGOutputObject, &SGOutput_Type);
+	if (it == NULL) return NULL;
+	it->ob_itself = itself;
+	return (PyObject *)it;
+}
+
+int SGOutputObj_Convert(PyObject *v, SGOutput *p_itself)
+{
+	if (v == Py_None)
+	{
+		*p_itself = NULL;
+		return 1;
+	}
+	if (!SGOutputObj_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "SGOutput required");
+		return 0;
+	}
+	*p_itself = ((SGOutputObject *)v)->ob_itself;
+	return 1;
+}
+
+static void SGOutputObj_dealloc(SGOutputObject *self)
+{
+	/* Cleanup of self->ob_itself goes here */
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyMethodDef SGOutputObj_methods[] = {
+	{NULL, NULL, 0}
+};
+
+#define SGOutputObj_getsetlist NULL
+
+
+#define SGOutputObj_compare NULL
+
+#define SGOutputObj_repr NULL
+
+#define SGOutputObj_hash NULL
+#define SGOutputObj_tp_init 0
+
+#define SGOutputObj_tp_alloc PyType_GenericAlloc
+
+static PyObject *SGOutputObj_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *_self;
+	SGOutput itself;
+	char *kw[] = {"itself", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, SGOutputObj_Convert, &itself)) return NULL;
+	if ((_self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	((SGOutputObject *)_self)->ob_itself = itself;
+	return _self;
+}
+
+#define SGOutputObj_tp_free PyObject_Del
+
+
+PyTypeObject SGOutput_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"_Qt.SGOutput", /*tp_name*/
+	sizeof(SGOutputObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) SGOutputObj_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) SGOutputObj_compare, /*tp_compare*/
+	(reprfunc) SGOutputObj_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) SGOutputObj_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	SGOutputObj_methods, /* tp_methods */
+	0, /*tp_members*/
+	SGOutputObj_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	SGOutputObj_tp_init, /* tp_init */
+	SGOutputObj_tp_alloc, /* tp_alloc */
+	SGOutputObj_tp_new, /* tp_new */
+	SGOutputObj_tp_free, /* tp_free */
+};
+
+/* -------------------- End object type SGOutput -------------------- */
+
+
+static PyObject *Qt_EnterMovies(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+#ifndef EnterMovies
+	PyMac_PRECHECK(EnterMovies);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = EnterMovies();
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qt_ExitMovies(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef ExitMovies
+	PyMac_PRECHECK(ExitMovies);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	ExitMovies();
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qt_GetMoviesError(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+#ifndef GetMoviesError
+	PyMac_PRECHECK(GetMoviesError);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetMoviesError();
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qt_ClearMoviesStickyError(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef ClearMoviesStickyError
+	PyMac_PRECHECK(ClearMoviesStickyError);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	ClearMoviesStickyError();
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qt_GetMoviesStickyError(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+#ifndef GetMoviesStickyError
+	PyMac_PRECHECK(GetMoviesStickyError);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetMoviesStickyError();
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qt_QTGetWallClockTimeBase(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	TimeBase wallClockTimeBase;
+#ifndef QTGetWallClockTimeBase
+	PyMac_PRECHECK(QTGetWallClockTimeBase);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = QTGetWallClockTimeBase(&wallClockTimeBase);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     TimeBaseObj_New, wallClockTimeBase);
+	return _res;
+}
+
+static PyObject *Qt_QTIdleManagerOpen(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	IdleManager _rv;
+#ifndef QTIdleManagerOpen
+	PyMac_PRECHECK(QTIdleManagerOpen);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = QTIdleManagerOpen();
+	_res = Py_BuildValue("O&",
+	                     IdleManagerObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Qt_CreateMovieControl(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	WindowPtr theWindow;
+	Rect localRect;
+	Movie theMovie;
+	UInt32 options;
+	ControlHandle returnedControl;
+#ifndef CreateMovieControl
+	PyMac_PRECHECK(CreateMovieControl);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&l",
+	                      WinObj_Convert, &theWindow,
+	                      MovieObj_Convert, &theMovie,
+	                      &options))
+		return NULL;
+	_err = CreateMovieControl(theWindow,
+	                          &localRect,
+	                          theMovie,
+	                          options,
+	                          &returnedControl);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&O&",
+	                     PyMac_BuildRect, &localRect,
+	                     CtlObj_New, returnedControl);
+	return _res;
+}
+
+static PyObject *Qt_DisposeMatte(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PixMapHandle theMatte;
+#ifndef DisposeMatte
+	PyMac_PRECHECK(DisposeMatte);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &theMatte))
+		return NULL;
+	DisposeMatte(theMatte);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qt_NewMovie(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Movie _rv;
+	long flags;
+#ifndef NewMovie
+	PyMac_PRECHECK(NewMovie);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &flags))
+		return NULL;
+	_rv = NewMovie(flags);
+	_res = Py_BuildValue("O&",
+	                     MovieObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Qt_QTGetTimeUntilNextTask(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	long duration;
+	long scale;
+#ifndef QTGetTimeUntilNextTask
+	PyMac_PRECHECK(QTGetTimeUntilNextTask);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &scale))
+		return NULL;
+	_err = QTGetTimeUntilNextTask(&duration,
+	                              scale);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     duration);
+	return _res;
+}
+
+static PyObject *Qt_GetDataHandler(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Component _rv;
+	Handle dataRef;
+	OSType dataHandlerSubType;
+	long flags;
+#ifndef GetDataHandler
+	PyMac_PRECHECK(GetDataHandler);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&l",
+	                      ResObj_Convert, &dataRef,
+	                      PyMac_GetOSType, &dataHandlerSubType,
+	                      &flags))
+		return NULL;
+	_rv = GetDataHandler(dataRef,
+	                     dataHandlerSubType,
+	                     flags);
+	_res = Py_BuildValue("O&",
+	                     CmpObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Qt_PasteHandleIntoMovie(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Handle h;
+	OSType handleType;
+	Movie theMovie;
+	long flags;
+	ComponentInstance userComp;
+#ifndef PasteHandleIntoMovie
+	PyMac_PRECHECK(PasteHandleIntoMovie);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&lO&",
+	                      ResObj_Convert, &h,
+	                      PyMac_GetOSType, &handleType,
+	                      MovieObj_Convert, &theMovie,
+	                      &flags,
+	                      CmpInstObj_Convert, &userComp))
+		return NULL;
+	_err = PasteHandleIntoMovie(h,
+	                            handleType,
+	                            theMovie,
+	                            flags,
+	                            userComp);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qt_GetMovieImporterForDataRef(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	OSType dataRefType;
+	Handle dataRef;
+	long flags;
+	Component importer;
+#ifndef GetMovieImporterForDataRef
+	PyMac_PRECHECK(GetMovieImporterForDataRef);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&l",
+	                      PyMac_GetOSType, &dataRefType,
+	                      ResObj_Convert, &dataRef,
+	                      &flags))
+		return NULL;
+	_err = GetMovieImporterForDataRef(dataRefType,
+	                                  dataRef,
+	                                  flags,
+	                                  &importer);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CmpObj_New, importer);
+	return _res;
+}
+
+static PyObject *Qt_QTGetMIMETypeInfo(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	char* mimeStringStart;
+	short mimeStringLength;
+	OSType infoSelector;
+	void * infoDataPtr;
+	long infoDataSize;
+#ifndef QTGetMIMETypeInfo
+	PyMac_PRECHECK(QTGetMIMETypeInfo);
+#endif
+	if (!PyArg_ParseTuple(_args, "shO&s",
+	                      &mimeStringStart,
+	                      &mimeStringLength,
+	                      PyMac_GetOSType, &infoSelector,
+	                      &infoDataPtr))
+		return NULL;
+	_err = QTGetMIMETypeInfo(mimeStringStart,
+	                         mimeStringLength,
+	                         infoSelector,
+	                         infoDataPtr,
+	                         &infoDataSize);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     infoDataSize);
+	return _res;
+}
+
+static PyObject *Qt_TrackTimeToMediaTime(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	TimeValue _rv;
+	TimeValue value;
+	Track theTrack;
+#ifndef TrackTimeToMediaTime
+	PyMac_PRECHECK(TrackTimeToMediaTime);
+#endif
+	if (!PyArg_ParseTuple(_args, "lO&",
+	                      &value,
+	                      TrackObj_Convert, &theTrack))
+		return NULL;
+	_rv = TrackTimeToMediaTime(value,
+	                           theTrack);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_NewUserData(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	UserData theUserData;
+#ifndef NewUserData
+	PyMac_PRECHECK(NewUserData);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = NewUserData(&theUserData);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     UserDataObj_New, theUserData);
+	return _res;
+}
+
+static PyObject *Qt_NewUserDataFromHandle(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Handle h;
+	UserData theUserData;
+#ifndef NewUserDataFromHandle
+	PyMac_PRECHECK(NewUserDataFromHandle);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &h))
+		return NULL;
+	_err = NewUserDataFromHandle(h,
+	                             &theUserData);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     UserDataObj_New, theUserData);
+	return _res;
+}
+
+static PyObject *Qt_CreateMovieFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	FSSpec fileSpec;
+	OSType creator;
+	ScriptCode scriptTag;
+	long createMovieFileFlags;
+	short resRefNum;
+	Movie newmovie;
+#ifndef CreateMovieFile
+	PyMac_PRECHECK(CreateMovieFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&hl",
+	                      PyMac_GetFSSpec, &fileSpec,
+	                      PyMac_GetOSType, &creator,
+	                      &scriptTag,
+	                      &createMovieFileFlags))
+		return NULL;
+	_err = CreateMovieFile(&fileSpec,
+	                       creator,
+	                       scriptTag,
+	                       createMovieFileFlags,
+	                       &resRefNum,
+	                       &newmovie);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("hO&",
+	                     resRefNum,
+	                     MovieObj_New, newmovie);
+	return _res;
+}
+
+static PyObject *Qt_OpenMovieFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	FSSpec fileSpec;
+	short resRefNum;
+	SInt8 permission;
+#ifndef OpenMovieFile
+	PyMac_PRECHECK(OpenMovieFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&b",
+	                      PyMac_GetFSSpec, &fileSpec,
+	                      &permission))
+		return NULL;
+	_err = OpenMovieFile(&fileSpec,
+	                     &resRefNum,
+	                     permission);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("h",
+	                     resRefNum);
+	return _res;
+}
+
+static PyObject *Qt_CloseMovieFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short resRefNum;
+#ifndef CloseMovieFile
+	PyMac_PRECHECK(CloseMovieFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &resRefNum))
+		return NULL;
+	_err = CloseMovieFile(resRefNum);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qt_DeleteMovieFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	FSSpec fileSpec;
+#ifndef DeleteMovieFile
+	PyMac_PRECHECK(DeleteMovieFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetFSSpec, &fileSpec))
+		return NULL;
+	_err = DeleteMovieFile(&fileSpec);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qt_NewMovieFromFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Movie theMovie;
+	short resRefNum;
+	short resId;
+	short newMovieFlags;
+	Boolean dataRefWasChanged;
+#ifndef NewMovieFromFile
+	PyMac_PRECHECK(NewMovieFromFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "hhh",
+	                      &resRefNum,
+	                      &resId,
+	                      &newMovieFlags))
+		return NULL;
+	_err = NewMovieFromFile(&theMovie,
+	                        resRefNum,
+	                        &resId,
+	                        (StringPtr)0,
+	                        newMovieFlags,
+	                        &dataRefWasChanged);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&hb",
+	                     MovieObj_New, theMovie,
+	                     resId,
+	                     dataRefWasChanged);
+	return _res;
+}
+
+static PyObject *Qt_NewMovieFromHandle(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Movie theMovie;
+	Handle h;
+	short newMovieFlags;
+	Boolean dataRefWasChanged;
+#ifndef NewMovieFromHandle
+	PyMac_PRECHECK(NewMovieFromHandle);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      ResObj_Convert, &h,
+	                      &newMovieFlags))
+		return NULL;
+	_err = NewMovieFromHandle(&theMovie,
+	                          h,
+	                          newMovieFlags,
+	                          &dataRefWasChanged);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&b",
+	                     MovieObj_New, theMovie,
+	                     dataRefWasChanged);
+	return _res;
+}
+
+static PyObject *Qt_NewMovieFromDataFork(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Movie theMovie;
+	short fRefNum;
+	long fileOffset;
+	short newMovieFlags;
+	Boolean dataRefWasChanged;
+#ifndef NewMovieFromDataFork
+	PyMac_PRECHECK(NewMovieFromDataFork);
+#endif
+	if (!PyArg_ParseTuple(_args, "hlh",
+	                      &fRefNum,
+	                      &fileOffset,
+	                      &newMovieFlags))
+		return NULL;
+	_err = NewMovieFromDataFork(&theMovie,
+	                            fRefNum,
+	                            fileOffset,
+	                            newMovieFlags,
+	                            &dataRefWasChanged);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&b",
+	                     MovieObj_New, theMovie,
+	                     dataRefWasChanged);
+	return _res;
+}
+
+static PyObject *Qt_NewMovieFromDataFork64(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Movie theMovie;
+	long fRefNum;
+	wide fileOffset;
+	short newMovieFlags;
+	Boolean dataRefWasChanged;
+#ifndef NewMovieFromDataFork64
+	PyMac_PRECHECK(NewMovieFromDataFork64);
+#endif
+	if (!PyArg_ParseTuple(_args, "lO&h",
+	                      &fRefNum,
+	                      PyMac_Getwide, &fileOffset,
+	                      &newMovieFlags))
+		return NULL;
+	_err = NewMovieFromDataFork64(&theMovie,
+	                              fRefNum,
+	                              &fileOffset,
+	                              newMovieFlags,
+	                              &dataRefWasChanged);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&b",
+	                     MovieObj_New, theMovie,
+	                     dataRefWasChanged);
+	return _res;
+}
+
+static PyObject *Qt_NewMovieFromDataRef(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Movie m;
+	short flags;
+	short id;
+	Handle dataRef;
+	OSType dtaRefType;
+#ifndef NewMovieFromDataRef
+	PyMac_PRECHECK(NewMovieFromDataRef);
+#endif
+	if (!PyArg_ParseTuple(_args, "hO&O&",
+	                      &flags,
+	                      ResObj_Convert, &dataRef,
+	                      PyMac_GetOSType, &dtaRefType))
+		return NULL;
+	_err = NewMovieFromDataRef(&m,
+	                           flags,
+	                           &id,
+	                           dataRef,
+	                           dtaRefType);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&h",
+	                     MovieObj_New, m,
+	                     id);
+	return _res;
+}
+
+static PyObject *Qt_NewMovieFromStorageOffset(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Movie theMovie;
+	DataHandler dh;
+	wide fileOffset;
+	short newMovieFlags;
+	Boolean dataRefWasCataRefType;
+#ifndef NewMovieFromStorageOffset
+	PyMac_PRECHECK(NewMovieFromStorageOffset);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&h",
+	                      CmpInstObj_Convert, &dh,
+	                      PyMac_Getwide, &fileOffset,
+	                      &newMovieFlags))
+		return NULL;
+	_err = NewMovieFromStorageOffset(&theMovie,
+	                                 dh,
+	                                 &fileOffset,
+	                                 newMovieFlags,
+	                                 &dataRefWasCataRefType);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&b",
+	                     MovieObj_New, theMovie,
+	                     dataRefWasCataRefType);
+	return _res;
+}
+
+static PyObject *Qt_NewMovieForDataRefFromHandle(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Movie theMovie;
+	Handle h;
+	short newMovieFlags;
+	Boolean dataRefWasChanged;
+	Handle dataRef;
+	OSType dataRefType;
+#ifndef NewMovieForDataRefFromHandle
+	PyMac_PRECHECK(NewMovieForDataRefFromHandle);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hO&O&",
+	                      ResObj_Convert, &h,
+	                      &newMovieFlags,
+	                      ResObj_Convert, &dataRef,
+	                      PyMac_GetOSType, &dataRefType))
+		return NULL;
+	_err = NewMovieForDataRefFromHandle(&theMovie,
+	                                    h,
+	                                    newMovieFlags,
+	                                    &dataRefWasChanged,
+	                                    dataRef,
+	                                    dataRefType);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&b",
+	                     MovieObj_New, theMovie,
+	                     dataRefWasChanged);
+	return _res;
+}
+
+static PyObject *Qt_RemoveMovieResource(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short resRefNum;
+	short resId;
+#ifndef RemoveMovieResource
+	PyMac_PRECHECK(RemoveMovieResource);
+#endif
+	if (!PyArg_ParseTuple(_args, "hh",
+	                      &resRefNum,
+	                      &resId))
+		return NULL;
+	_err = RemoveMovieResource(resRefNum,
+	                           resId);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qt_CreateMovieStorage(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Handle dataRef;
+	OSType dataRefType;
+	OSType creator;
+	ScriptCode scriptTag;
+	long createMovieFileFlags;
+	DataHandler outDataHandler;
+	Movie newmovie;
+#ifndef CreateMovieStorage
+	PyMac_PRECHECK(CreateMovieStorage);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&hl",
+	                      ResObj_Convert, &dataRef,
+	                      PyMac_GetOSType, &dataRefType,
+	                      PyMac_GetOSType, &creator,
+	                      &scriptTag,
+	                      &createMovieFileFlags))
+		return NULL;
+	_err = CreateMovieStorage(dataRef,
+	                          dataRefType,
+	                          creator,
+	                          scriptTag,
+	                          createMovieFileFlags,
+	                          &outDataHandler,
+	                          &newmovie);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&O&",
+	                     CmpInstObj_New, outDataHandler,
+	                     MovieObj_New, newmovie);
+	return _res;
+}
+
+static PyObject *Qt_OpenMovieStorage(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Handle dataRef;
+	OSType dataRefType;
+	long flags;
+	DataHandler outDataHandler;
+#ifndef OpenMovieStorage
+	PyMac_PRECHECK(OpenMovieStorage);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&l",
+	                      ResObj_Convert, &dataRef,
+	                      PyMac_GetOSType, &dataRefType,
+	                      &flags))
+		return NULL;
+	_err = OpenMovieStorage(dataRef,
+	                        dataRefType,
+	                        flags,
+	                        &outDataHandler);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CmpInstObj_New, outDataHandler);
+	return _res;
+}
+
+static PyObject *Qt_CloseMovieStorage(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	DataHandler dh;
+#ifndef CloseMovieStorage
+	PyMac_PRECHECK(CloseMovieStorage);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &dh))
+		return NULL;
+	_err = CloseMovieStorage(dh);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qt_DeleteMovieStorage(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Handle dataRef;
+	OSType dataRefType;
+#ifndef DeleteMovieStorage
+	PyMac_PRECHECK(DeleteMovieStorage);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      ResObj_Convert, &dataRef,
+	                      PyMac_GetOSType, &dataRefType))
+		return NULL;
+	_err = DeleteMovieStorage(dataRef,
+	                          dataRefType);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qt_CreateShortcutMovieFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	FSSpec fileSpec;
+	OSType creator;
+	ScriptCode scriptTag;
+	long createMovieFileFlags;
+	Handle targetDataRef;
+	OSType targetDataRefType;
+#ifndef CreateShortcutMovieFile
+	PyMac_PRECHECK(CreateShortcutMovieFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&hlO&O&",
+	                      PyMac_GetFSSpec, &fileSpec,
+	                      PyMac_GetOSType, &creator,
+	                      &scriptTag,
+	                      &createMovieFileFlags,
+	                      ResObj_Convert, &targetDataRef,
+	                      PyMac_GetOSType, &targetDataRefType))
+		return NULL;
+	_err = CreateShortcutMovieFile(&fileSpec,
+	                               creator,
+	                               scriptTag,
+	                               createMovieFileFlags,
+	                               targetDataRef,
+	                               targetDataRefType);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qt_CanQuickTimeOpenFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	FSSpec fileSpec;
+	OSType fileType;
+	OSType fileNameExtension;
+	Boolean outCanOpenWithGraphicsImporter;
+	Boolean outCanOpenAsMovie;
+	Boolean outPreferGraphicsImporter;
+	UInt32 inFlags;
+#ifndef CanQuickTimeOpenFile
+	PyMac_PRECHECK(CanQuickTimeOpenFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&l",
+	                      PyMac_GetFSSpec, &fileSpec,
+	                      PyMac_GetOSType, &fileType,
+	                      PyMac_GetOSType, &fileNameExtension,
+	                      &inFlags))
+		return NULL;
+	_err = CanQuickTimeOpenFile(&fileSpec,
+	                            fileType,
+	                            fileNameExtension,
+	                            &outCanOpenWithGraphicsImporter,
+	                            &outCanOpenAsMovie,
+	                            &outPreferGraphicsImporter,
+	                            inFlags);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("bbb",
+	                     outCanOpenWithGraphicsImporter,
+	                     outCanOpenAsMovie,
+	                     outPreferGraphicsImporter);
+	return _res;
+}
+
+static PyObject *Qt_CanQuickTimeOpenDataRef(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Handle dataRef;
+	OSType dataRefType;
+	Boolean outCanOpenWithGraphicsImporter;
+	Boolean outCanOpenAsMovie;
+	Boolean outPreferGraphicsImporter;
+	UInt32 inFlags;
+#ifndef CanQuickTimeOpenDataRef
+	PyMac_PRECHECK(CanQuickTimeOpenDataRef);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&l",
+	                      ResObj_Convert, &dataRef,
+	                      PyMac_GetOSType, &dataRefType,
+	                      &inFlags))
+		return NULL;
+	_err = CanQuickTimeOpenDataRef(dataRef,
+	                               dataRefType,
+	                               &outCanOpenWithGraphicsImporter,
+	                               &outCanOpenAsMovie,
+	                               &outPreferGraphicsImporter,
+	                               inFlags);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("bbb",
+	                     outCanOpenWithGraphicsImporter,
+	                     outCanOpenAsMovie,
+	                     outPreferGraphicsImporter);
+	return _res;
+}
+
+static PyObject *Qt_NewMovieFromScrap(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Movie _rv;
+	long newMovieFlags;
+#ifndef NewMovieFromScrap
+	PyMac_PRECHECK(NewMovieFromScrap);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &newMovieFlags))
+		return NULL;
+	_rv = NewMovieFromScrap(newMovieFlags);
+	_res = Py_BuildValue("O&",
+	                     MovieObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Qt_QTNewAlias(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	FSSpec fss;
+	AliasHandle alias;
+	Boolean minimal;
+#ifndef QTNewAlias
+	PyMac_PRECHECK(QTNewAlias);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&b",
+	                      PyMac_GetFSSpec, &fss,
+	                      &minimal))
+		return NULL;
+	_err = QTNewAlias(&fss,
+	                  &alias,
+	                  minimal);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, alias);
+	return _res;
+}
+
+static PyObject *Qt_EndFullScreen(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Ptr fullState;
+	long flags;
+#ifndef EndFullScreen
+	PyMac_PRECHECK(EndFullScreen);
+#endif
+	if (!PyArg_ParseTuple(_args, "sl",
+	                      &fullState,
+	                      &flags))
+		return NULL;
+	_err = EndFullScreen(fullState,
+	                     flags);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qt_AddSoundDescriptionExtension(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SoundDescriptionHandle desc;
+	Handle extension;
+	OSType idType;
+#ifndef AddSoundDescriptionExtension
+	PyMac_PRECHECK(AddSoundDescriptionExtension);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      ResObj_Convert, &desc,
+	                      ResObj_Convert, &extension,
+	                      PyMac_GetOSType, &idType))
+		return NULL;
+	_err = AddSoundDescriptionExtension(desc,
+	                                    extension,
+	                                    idType);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qt_GetSoundDescriptionExtension(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SoundDescriptionHandle desc;
+	Handle extension;
+	OSType idType;
+#ifndef GetSoundDescriptionExtension
+	PyMac_PRECHECK(GetSoundDescriptionExtension);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      ResObj_Convert, &desc,
+	                      PyMac_GetOSType, &idType))
+		return NULL;
+	_err = GetSoundDescriptionExtension(desc,
+	                                    &extension,
+	                                    idType);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, extension);
+	return _res;
+}
+
+static PyObject *Qt_RemoveSoundDescriptionExtension(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SoundDescriptionHandle desc;
+	OSType idType;
+#ifndef RemoveSoundDescriptionExtension
+	PyMac_PRECHECK(RemoveSoundDescriptionExtension);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      ResObj_Convert, &desc,
+	                      PyMac_GetOSType, &idType))
+		return NULL;
+	_err = RemoveSoundDescriptionExtension(desc,
+	                                       idType);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qt_QTIsStandardParameterDialogEvent(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	EventRecord pEvent;
+	QTParameterDialog createdDialog;
+#ifndef QTIsStandardParameterDialogEvent
+	PyMac_PRECHECK(QTIsStandardParameterDialogEvent);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &createdDialog))
+		return NULL;
+	_err = QTIsStandardParameterDialogEvent(&pEvent,
+	                                        createdDialog);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildEventRecord, &pEvent);
+	return _res;
+}
+
+static PyObject *Qt_QTDismissStandardParameterDialog(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	QTParameterDialog createdDialog;
+#ifndef QTDismissStandardParameterDialog
+	PyMac_PRECHECK(QTDismissStandardParameterDialog);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &createdDialog))
+		return NULL;
+	_err = QTDismissStandardParameterDialog(createdDialog);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qt_QTStandardParameterDialogDoAction(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	QTParameterDialog createdDialog;
+	long action;
+	void * params;
+#ifndef QTStandardParameterDialogDoAction
+	PyMac_PRECHECK(QTStandardParameterDialogDoAction);
+#endif
+	if (!PyArg_ParseTuple(_args, "lls",
+	                      &createdDialog,
+	                      &action,
+	                      &params))
+		return NULL;
+	_err = QTStandardParameterDialogDoAction(createdDialog,
+	                                         action,
+	                                         params);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qt_QTRegisterAccessKey(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Str255 accessKeyType;
+	long flags;
+	Handle accessKey;
+#ifndef QTRegisterAccessKey
+	PyMac_PRECHECK(QTRegisterAccessKey);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&lO&",
+	                      PyMac_GetStr255, accessKeyType,
+	                      &flags,
+	                      ResObj_Convert, &accessKey))
+		return NULL;
+	_err = QTRegisterAccessKey(accessKeyType,
+	                           flags,
+	                           accessKey);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qt_QTUnregisterAccessKey(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Str255 accessKeyType;
+	long flags;
+	Handle accessKey;
+#ifndef QTUnregisterAccessKey
+	PyMac_PRECHECK(QTUnregisterAccessKey);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&lO&",
+	                      PyMac_GetStr255, accessKeyType,
+	                      &flags,
+	                      ResObj_Convert, &accessKey))
+		return NULL;
+	_err = QTUnregisterAccessKey(accessKeyType,
+	                             flags,
+	                             accessKey);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qt_QTGetSupportedRestrictions(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	OSType inRestrictionClass;
+	UInt32 outRestrictionIDs;
+#ifndef QTGetSupportedRestrictions
+	PyMac_PRECHECK(QTGetSupportedRestrictions);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetOSType, &inRestrictionClass))
+		return NULL;
+	_err = QTGetSupportedRestrictions(inRestrictionClass,
+	                                  &outRestrictionIDs);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     outRestrictionIDs);
+	return _res;
+}
+
+static PyObject *Qt_QTTextToNativeText(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Handle theText;
+	long encoding;
+	long flags;
+#ifndef QTTextToNativeText
+	PyMac_PRECHECK(QTTextToNativeText);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&ll",
+	                      ResObj_Convert, &theText,
+	                      &encoding,
+	                      &flags))
+		return NULL;
+	_err = QTTextToNativeText(theText,
+	                          encoding,
+	                          flags);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qt_VideoMediaResetStatistics(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+#ifndef VideoMediaResetStatistics
+	PyMac_PRECHECK(VideoMediaResetStatistics);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &mh))
+		return NULL;
+	_rv = VideoMediaResetStatistics(mh);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_VideoMediaGetStatistics(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+#ifndef VideoMediaGetStatistics
+	PyMac_PRECHECK(VideoMediaGetStatistics);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &mh))
+		return NULL;
+	_rv = VideoMediaGetStatistics(mh);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_VideoMediaGetStallCount(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	unsigned long stalls;
+#ifndef VideoMediaGetStallCount
+	PyMac_PRECHECK(VideoMediaGetStallCount);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &mh))
+		return NULL;
+	_rv = VideoMediaGetStallCount(mh,
+	                              &stalls);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     stalls);
+	return _res;
+}
+
+static PyObject *Qt_VideoMediaSetCodecParameter(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	CodecType cType;
+	OSType parameterID;
+	long parameterChangeSeed;
+	void * dataPtr;
+	long dataSize;
+#ifndef VideoMediaSetCodecParameter
+	PyMac_PRECHECK(VideoMediaSetCodecParameter);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&lsl",
+	                      CmpInstObj_Convert, &mh,
+	                      PyMac_GetOSType, &cType,
+	                      PyMac_GetOSType, &parameterID,
+	                      &parameterChangeSeed,
+	                      &dataPtr,
+	                      &dataSize))
+		return NULL;
+	_rv = VideoMediaSetCodecParameter(mh,
+	                                  cType,
+	                                  parameterID,
+	                                  parameterChangeSeed,
+	                                  dataPtr,
+	                                  dataSize);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_VideoMediaGetCodecParameter(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	CodecType cType;
+	OSType parameterID;
+	Handle outParameterData;
+#ifndef VideoMediaGetCodecParameter
+	PyMac_PRECHECK(VideoMediaGetCodecParameter);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&O&",
+	                      CmpInstObj_Convert, &mh,
+	                      PyMac_GetOSType, &cType,
+	                      PyMac_GetOSType, &parameterID,
+	                      ResObj_Convert, &outParameterData))
+		return NULL;
+	_rv = VideoMediaGetCodecParameter(mh,
+	                                  cType,
+	                                  parameterID,
+	                                  outParameterData);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_TextMediaAddTextSample(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	Ptr text;
+	unsigned long size;
+	short fontNumber;
+	short fontSize;
+	Style textFace;
+	RGBColor textColor;
+	RGBColor backColor;
+	short textJustification;
+	Rect textBox;
+	long displayFlags;
+	TimeValue scrollDelay;
+	short hiliteStart;
+	short hiliteEnd;
+	RGBColor rgbHiliteColor;
+	TimeValue duration;
+	TimeValue sampleTime;
+#ifndef TextMediaAddTextSample
+	PyMac_PRECHECK(TextMediaAddTextSample);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&slhhbhllhhl",
+	                      CmpInstObj_Convert, &mh,
+	                      &text,
+	                      &size,
+	                      &fontNumber,
+	                      &fontSize,
+	                      &textFace,
+	                      &textJustification,
+	                      &displayFlags,
+	                      &scrollDelay,
+	                      &hiliteStart,
+	                      &hiliteEnd,
+	                      &duration))
+		return NULL;
+	_rv = TextMediaAddTextSample(mh,
+	                             text,
+	                             size,
+	                             fontNumber,
+	                             fontSize,
+	                             textFace,
+	                             &textColor,
+	                             &backColor,
+	                             textJustification,
+	                             &textBox,
+	                             displayFlags,
+	                             scrollDelay,
+	                             hiliteStart,
+	                             hiliteEnd,
+	                             &rgbHiliteColor,
+	                             duration,
+	                             &sampleTime);
+	_res = Py_BuildValue("lO&O&O&O&l",
+	                     _rv,
+	                     QdRGB_New, &textColor,
+	                     QdRGB_New, &backColor,
+	                     PyMac_BuildRect, &textBox,
+	                     QdRGB_New, &rgbHiliteColor,
+	                     sampleTime);
+	return _res;
+}
+
+static PyObject *Qt_TextMediaAddTESample(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	TEHandle hTE;
+	RGBColor backColor;
+	short textJustification;
+	Rect textBox;
+	long displayFlags;
+	TimeValue scrollDelay;
+	short hiliteStart;
+	short hiliteEnd;
+	RGBColor rgbHiliteColor;
+	TimeValue duration;
+	TimeValue sampleTime;
+#ifndef TextMediaAddTESample
+	PyMac_PRECHECK(TextMediaAddTESample);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&hllhhl",
+	                      CmpInstObj_Convert, &mh,
+	                      ResObj_Convert, &hTE,
+	                      &textJustification,
+	                      &displayFlags,
+	                      &scrollDelay,
+	                      &hiliteStart,
+	                      &hiliteEnd,
+	                      &duration))
+		return NULL;
+	_rv = TextMediaAddTESample(mh,
+	                           hTE,
+	                           &backColor,
+	                           textJustification,
+	                           &textBox,
+	                           displayFlags,
+	                           scrollDelay,
+	                           hiliteStart,
+	                           hiliteEnd,
+	                           &rgbHiliteColor,
+	                           duration,
+	                           &sampleTime);
+	_res = Py_BuildValue("lO&O&O&l",
+	                     _rv,
+	                     QdRGB_New, &backColor,
+	                     PyMac_BuildRect, &textBox,
+	                     QdRGB_New, &rgbHiliteColor,
+	                     sampleTime);
+	return _res;
+}
+
+static PyObject *Qt_TextMediaAddHiliteSample(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	short hiliteStart;
+	short hiliteEnd;
+	RGBColor rgbHiliteColor;
+	TimeValue duration;
+	TimeValue sampleTime;
+#ifndef TextMediaAddHiliteSample
+	PyMac_PRECHECK(TextMediaAddHiliteSample);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hhl",
+	                      CmpInstObj_Convert, &mh,
+	                      &hiliteStart,
+	                      &hiliteEnd,
+	                      &duration))
+		return NULL;
+	_rv = TextMediaAddHiliteSample(mh,
+	                               hiliteStart,
+	                               hiliteEnd,
+	                               &rgbHiliteColor,
+	                               duration,
+	                               &sampleTime);
+	_res = Py_BuildValue("lO&l",
+	                     _rv,
+	                     QdRGB_New, &rgbHiliteColor,
+	                     sampleTime);
+	return _res;
+}
+
+static PyObject *Qt_TextMediaDrawRaw(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	GWorldPtr gw;
+	GDHandle gd;
+	void * data;
+	long dataSize;
+	TextDescriptionHandle tdh;
+#ifndef TextMediaDrawRaw
+	PyMac_PRECHECK(TextMediaDrawRaw);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&slO&",
+	                      CmpInstObj_Convert, &mh,
+	                      GWorldObj_Convert, &gw,
+	                      OptResObj_Convert, &gd,
+	                      &data,
+	                      &dataSize,
+	                      ResObj_Convert, &tdh))
+		return NULL;
+	_rv = TextMediaDrawRaw(mh,
+	                       gw,
+	                       gd,
+	                       data,
+	                       dataSize,
+	                       tdh);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_TextMediaSetTextProperty(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	TimeValue atMediaTime;
+	long propertyType;
+	void * data;
+	long dataSize;
+#ifndef TextMediaSetTextProperty
+	PyMac_PRECHECK(TextMediaSetTextProperty);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&llsl",
+	                      CmpInstObj_Convert, &mh,
+	                      &atMediaTime,
+	                      &propertyType,
+	                      &data,
+	                      &dataSize))
+		return NULL;
+	_rv = TextMediaSetTextProperty(mh,
+	                               atMediaTime,
+	                               propertyType,
+	                               data,
+	                               dataSize);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_TextMediaRawSetup(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	GWorldPtr gw;
+	GDHandle gd;
+	void * data;
+	long dataSize;
+	TextDescriptionHandle tdh;
+	TimeValue sampleDuration;
+#ifndef TextMediaRawSetup
+	PyMac_PRECHECK(TextMediaRawSetup);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&slO&l",
+	                      CmpInstObj_Convert, &mh,
+	                      GWorldObj_Convert, &gw,
+	                      OptResObj_Convert, &gd,
+	                      &data,
+	                      &dataSize,
+	                      ResObj_Convert, &tdh,
+	                      &sampleDuration))
+		return NULL;
+	_rv = TextMediaRawSetup(mh,
+	                        gw,
+	                        gd,
+	                        data,
+	                        dataSize,
+	                        tdh,
+	                        sampleDuration);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_TextMediaRawIdle(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	GWorldPtr gw;
+	GDHandle gd;
+	TimeValue sampleTime;
+	long flagsIn;
+	long flagsOut;
+#ifndef TextMediaRawIdle
+	PyMac_PRECHECK(TextMediaRawIdle);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&ll",
+	                      CmpInstObj_Convert, &mh,
+	                      GWorldObj_Convert, &gw,
+	                      OptResObj_Convert, &gd,
+	                      &sampleTime,
+	                      &flagsIn))
+		return NULL;
+	_rv = TextMediaRawIdle(mh,
+	                       gw,
+	                       gd,
+	                       sampleTime,
+	                       flagsIn,
+	                       &flagsOut);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     flagsOut);
+	return _res;
+}
+
+static PyObject *Qt_TextMediaGetTextProperty(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	TimeValue atMediaTime;
+	long propertyType;
+	void * data;
+	long dataSize;
+#ifndef TextMediaGetTextProperty
+	PyMac_PRECHECK(TextMediaGetTextProperty);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&llsl",
+	                      CmpInstObj_Convert, &mh,
+	                      &atMediaTime,
+	                      &propertyType,
+	                      &data,
+	                      &dataSize))
+		return NULL;
+	_rv = TextMediaGetTextProperty(mh,
+	                               atMediaTime,
+	                               propertyType,
+	                               data,
+	                               dataSize);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_TextMediaFindNextText(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	Ptr text;
+	long size;
+	short findFlags;
+	TimeValue startTime;
+	TimeValue foundTime;
+	TimeValue foundDuration;
+	long offset;
+#ifndef TextMediaFindNextText
+	PyMac_PRECHECK(TextMediaFindNextText);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&slhl",
+	                      CmpInstObj_Convert, &mh,
+	                      &text,
+	                      &size,
+	                      &findFlags,
+	                      &startTime))
+		return NULL;
+	_rv = TextMediaFindNextText(mh,
+	                            text,
+	                            size,
+	                            findFlags,
+	                            startTime,
+	                            &foundTime,
+	                            &foundDuration,
+	                            &offset);
+	_res = Py_BuildValue("llll",
+	                     _rv,
+	                     foundTime,
+	                     foundDuration,
+	                     offset);
+	return _res;
+}
+
+static PyObject *Qt_TextMediaHiliteTextSample(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	TimeValue sampleTime;
+	short hiliteStart;
+	short hiliteEnd;
+	RGBColor rgbHiliteColor;
+#ifndef TextMediaHiliteTextSample
+	PyMac_PRECHECK(TextMediaHiliteTextSample);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&lhh",
+	                      CmpInstObj_Convert, &mh,
+	                      &sampleTime,
+	                      &hiliteStart,
+	                      &hiliteEnd))
+		return NULL;
+	_rv = TextMediaHiliteTextSample(mh,
+	                                sampleTime,
+	                                hiliteStart,
+	                                hiliteEnd,
+	                                &rgbHiliteColor);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     QdRGB_New, &rgbHiliteColor);
+	return _res;
+}
+
+static PyObject *Qt_TextMediaSetTextSampleData(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	void * data;
+	OSType dataType;
+#ifndef TextMediaSetTextSampleData
+	PyMac_PRECHECK(TextMediaSetTextSampleData);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&sO&",
+	                      CmpInstObj_Convert, &mh,
+	                      &data,
+	                      PyMac_GetOSType, &dataType))
+		return NULL;
+	_rv = TextMediaSetTextSampleData(mh,
+	                                 data,
+	                                 dataType);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SpriteMediaSetProperty(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	short spriteIndex;
+	long propertyType;
+	void * propertyValue;
+#ifndef SpriteMediaSetProperty
+	PyMac_PRECHECK(SpriteMediaSetProperty);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hls",
+	                      CmpInstObj_Convert, &mh,
+	                      &spriteIndex,
+	                      &propertyType,
+	                      &propertyValue))
+		return NULL;
+	_rv = SpriteMediaSetProperty(mh,
+	                             spriteIndex,
+	                             propertyType,
+	                             propertyValue);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SpriteMediaGetProperty(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	short spriteIndex;
+	long propertyType;
+	void * propertyValue;
+#ifndef SpriteMediaGetProperty
+	PyMac_PRECHECK(SpriteMediaGetProperty);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hls",
+	                      CmpInstObj_Convert, &mh,
+	                      &spriteIndex,
+	                      &propertyType,
+	                      &propertyValue))
+		return NULL;
+	_rv = SpriteMediaGetProperty(mh,
+	                             spriteIndex,
+	                             propertyType,
+	                             propertyValue);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SpriteMediaHitTestSprites(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	long flags;
+	Point loc;
+	short spriteHitIndex;
+#ifndef SpriteMediaHitTestSprites
+	PyMac_PRECHECK(SpriteMediaHitTestSprites);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&lO&",
+	                      CmpInstObj_Convert, &mh,
+	                      &flags,
+	                      PyMac_GetPoint, &loc))
+		return NULL;
+	_rv = SpriteMediaHitTestSprites(mh,
+	                                flags,
+	                                loc,
+	                                &spriteHitIndex);
+	_res = Py_BuildValue("lh",
+	                     _rv,
+	                     spriteHitIndex);
+	return _res;
+}
+
+static PyObject *Qt_SpriteMediaCountSprites(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	short numSprites;
+#ifndef SpriteMediaCountSprites
+	PyMac_PRECHECK(SpriteMediaCountSprites);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &mh))
+		return NULL;
+	_rv = SpriteMediaCountSprites(mh,
+	                              &numSprites);
+	_res = Py_BuildValue("lh",
+	                     _rv,
+	                     numSprites);
+	return _res;
+}
+
+static PyObject *Qt_SpriteMediaCountImages(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	short numImages;
+#ifndef SpriteMediaCountImages
+	PyMac_PRECHECK(SpriteMediaCountImages);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &mh))
+		return NULL;
+	_rv = SpriteMediaCountImages(mh,
+	                             &numImages);
+	_res = Py_BuildValue("lh",
+	                     _rv,
+	                     numImages);
+	return _res;
+}
+
+static PyObject *Qt_SpriteMediaGetIndImageDescription(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	short imageIndex;
+	ImageDescriptionHandle imageDescription;
+#ifndef SpriteMediaGetIndImageDescription
+	PyMac_PRECHECK(SpriteMediaGetIndImageDescription);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hO&",
+	                      CmpInstObj_Convert, &mh,
+	                      &imageIndex,
+	                      ResObj_Convert, &imageDescription))
+		return NULL;
+	_rv = SpriteMediaGetIndImageDescription(mh,
+	                                        imageIndex,
+	                                        imageDescription);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SpriteMediaGetDisplayedSampleNumber(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	long sampleNum;
+#ifndef SpriteMediaGetDisplayedSampleNumber
+	PyMac_PRECHECK(SpriteMediaGetDisplayedSampleNumber);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &mh))
+		return NULL;
+	_rv = SpriteMediaGetDisplayedSampleNumber(mh,
+	                                          &sampleNum);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     sampleNum);
+	return _res;
+}
+
+static PyObject *Qt_SpriteMediaGetSpriteName(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	QTAtomID spriteID;
+	Str255 spriteName;
+#ifndef SpriteMediaGetSpriteName
+	PyMac_PRECHECK(SpriteMediaGetSpriteName);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&lO&",
+	                      CmpInstObj_Convert, &mh,
+	                      &spriteID,
+	                      PyMac_GetStr255, spriteName))
+		return NULL;
+	_rv = SpriteMediaGetSpriteName(mh,
+	                               spriteID,
+	                               spriteName);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SpriteMediaGetImageName(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	short imageIndex;
+	Str255 imageName;
+#ifndef SpriteMediaGetImageName
+	PyMac_PRECHECK(SpriteMediaGetImageName);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hO&",
+	                      CmpInstObj_Convert, &mh,
+	                      &imageIndex,
+	                      PyMac_GetStr255, imageName))
+		return NULL;
+	_rv = SpriteMediaGetImageName(mh,
+	                              imageIndex,
+	                              imageName);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SpriteMediaSetSpriteProperty(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	QTAtomID spriteID;
+	long propertyType;
+	void * propertyValue;
+#ifndef SpriteMediaSetSpriteProperty
+	PyMac_PRECHECK(SpriteMediaSetSpriteProperty);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&lls",
+	                      CmpInstObj_Convert, &mh,
+	                      &spriteID,
+	                      &propertyType,
+	                      &propertyValue))
+		return NULL;
+	_rv = SpriteMediaSetSpriteProperty(mh,
+	                                   spriteID,
+	                                   propertyType,
+	                                   propertyValue);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SpriteMediaGetSpriteProperty(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	QTAtomID spriteID;
+	long propertyType;
+	void * propertyValue;
+#ifndef SpriteMediaGetSpriteProperty
+	PyMac_PRECHECK(SpriteMediaGetSpriteProperty);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&lls",
+	                      CmpInstObj_Convert, &mh,
+	                      &spriteID,
+	                      &propertyType,
+	                      &propertyValue))
+		return NULL;
+	_rv = SpriteMediaGetSpriteProperty(mh,
+	                                   spriteID,
+	                                   propertyType,
+	                                   propertyValue);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SpriteMediaHitTestAllSprites(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	long flags;
+	Point loc;
+	QTAtomID spriteHitID;
+#ifndef SpriteMediaHitTestAllSprites
+	PyMac_PRECHECK(SpriteMediaHitTestAllSprites);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&lO&",
+	                      CmpInstObj_Convert, &mh,
+	                      &flags,
+	                      PyMac_GetPoint, &loc))
+		return NULL;
+	_rv = SpriteMediaHitTestAllSprites(mh,
+	                                   flags,
+	                                   loc,
+	                                   &spriteHitID);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     spriteHitID);
+	return _res;
+}
+
+static PyObject *Qt_SpriteMediaHitTestOneSprite(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	QTAtomID spriteID;
+	long flags;
+	Point loc;
+	Boolean wasHit;
+#ifndef SpriteMediaHitTestOneSprite
+	PyMac_PRECHECK(SpriteMediaHitTestOneSprite);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&llO&",
+	                      CmpInstObj_Convert, &mh,
+	                      &spriteID,
+	                      &flags,
+	                      PyMac_GetPoint, &loc))
+		return NULL;
+	_rv = SpriteMediaHitTestOneSprite(mh,
+	                                  spriteID,
+	                                  flags,
+	                                  loc,
+	                                  &wasHit);
+	_res = Py_BuildValue("lb",
+	                     _rv,
+	                     wasHit);
+	return _res;
+}
+
+static PyObject *Qt_SpriteMediaSpriteIndexToID(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	short spriteIndex;
+	QTAtomID spriteID;
+#ifndef SpriteMediaSpriteIndexToID
+	PyMac_PRECHECK(SpriteMediaSpriteIndexToID);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      CmpInstObj_Convert, &mh,
+	                      &spriteIndex))
+		return NULL;
+	_rv = SpriteMediaSpriteIndexToID(mh,
+	                                 spriteIndex,
+	                                 &spriteID);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     spriteID);
+	return _res;
+}
+
+static PyObject *Qt_SpriteMediaSpriteIDToIndex(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	QTAtomID spriteID;
+	short spriteIndex;
+#ifndef SpriteMediaSpriteIDToIndex
+	PyMac_PRECHECK(SpriteMediaSpriteIDToIndex);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &mh,
+	                      &spriteID))
+		return NULL;
+	_rv = SpriteMediaSpriteIDToIndex(mh,
+	                                 spriteID,
+	                                 &spriteIndex);
+	_res = Py_BuildValue("lh",
+	                     _rv,
+	                     spriteIndex);
+	return _res;
+}
+
+static PyObject *Qt_SpriteMediaSetActionVariable(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	QTAtomID variableID;
+	float value;
+#ifndef SpriteMediaSetActionVariable
+	PyMac_PRECHECK(SpriteMediaSetActionVariable);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&lf",
+	                      CmpInstObj_Convert, &mh,
+	                      &variableID,
+	                      &value))
+		return NULL;
+	_rv = SpriteMediaSetActionVariable(mh,
+	                                   variableID,
+	                                   &value);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SpriteMediaGetActionVariable(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	QTAtomID variableID;
+	float value;
+#ifndef SpriteMediaGetActionVariable
+	PyMac_PRECHECK(SpriteMediaGetActionVariable);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &mh,
+	                      &variableID))
+		return NULL;
+	_rv = SpriteMediaGetActionVariable(mh,
+	                                   variableID,
+	                                   &value);
+	_res = Py_BuildValue("lf",
+	                     _rv,
+	                     value);
+	return _res;
+}
+
+static PyObject *Qt_SpriteMediaDisposeSprite(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	QTAtomID spriteID;
+#ifndef SpriteMediaDisposeSprite
+	PyMac_PRECHECK(SpriteMediaDisposeSprite);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &mh,
+	                      &spriteID))
+		return NULL;
+	_rv = SpriteMediaDisposeSprite(mh,
+	                               spriteID);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SpriteMediaSetActionVariableToString(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	QTAtomID variableID;
+	Ptr theCString;
+#ifndef SpriteMediaSetActionVariableToString
+	PyMac_PRECHECK(SpriteMediaSetActionVariableToString);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&ls",
+	                      CmpInstObj_Convert, &mh,
+	                      &variableID,
+	                      &theCString))
+		return NULL;
+	_rv = SpriteMediaSetActionVariableToString(mh,
+	                                           variableID,
+	                                           theCString);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SpriteMediaGetActionVariableAsString(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	QTAtomID variableID;
+	Handle theCString;
+#ifndef SpriteMediaGetActionVariableAsString
+	PyMac_PRECHECK(SpriteMediaGetActionVariableAsString);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &mh,
+	                      &variableID))
+		return NULL;
+	_rv = SpriteMediaGetActionVariableAsString(mh,
+	                                           variableID,
+	                                           &theCString);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     ResObj_New, theCString);
+	return _res;
+}
+
+static PyObject *Qt_SpriteMediaNewImage(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	Handle dataRef;
+	OSType dataRefType;
+	QTAtomID desiredID;
+#ifndef SpriteMediaNewImage
+	PyMac_PRECHECK(SpriteMediaNewImage);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&l",
+	                      CmpInstObj_Convert, &mh,
+	                      ResObj_Convert, &dataRef,
+	                      PyMac_GetOSType, &dataRefType,
+	                      &desiredID))
+		return NULL;
+	_rv = SpriteMediaNewImage(mh,
+	                          dataRef,
+	                          dataRefType,
+	                          desiredID);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SpriteMediaDisposeImage(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	short imageIndex;
+#ifndef SpriteMediaDisposeImage
+	PyMac_PRECHECK(SpriteMediaDisposeImage);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      CmpInstObj_Convert, &mh,
+	                      &imageIndex))
+		return NULL;
+	_rv = SpriteMediaDisposeImage(mh,
+	                              imageIndex);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SpriteMediaImageIndexToID(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	short imageIndex;
+	QTAtomID imageID;
+#ifndef SpriteMediaImageIndexToID
+	PyMac_PRECHECK(SpriteMediaImageIndexToID);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      CmpInstObj_Convert, &mh,
+	                      &imageIndex))
+		return NULL;
+	_rv = SpriteMediaImageIndexToID(mh,
+	                                imageIndex,
+	                                &imageID);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     imageID);
+	return _res;
+}
+
+static PyObject *Qt_SpriteMediaImageIDToIndex(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	QTAtomID imageID;
+	short imageIndex;
+#ifndef SpriteMediaImageIDToIndex
+	PyMac_PRECHECK(SpriteMediaImageIDToIndex);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &mh,
+	                      &imageID))
+		return NULL;
+	_rv = SpriteMediaImageIDToIndex(mh,
+	                                imageID,
+	                                &imageIndex);
+	_res = Py_BuildValue("lh",
+	                     _rv,
+	                     imageIndex);
+	return _res;
+}
+
+static PyObject *Qt_FlashMediaSetPan(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	short xPercent;
+	short yPercent;
+#ifndef FlashMediaSetPan
+	PyMac_PRECHECK(FlashMediaSetPan);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hh",
+	                      CmpInstObj_Convert, &mh,
+	                      &xPercent,
+	                      &yPercent))
+		return NULL;
+	_rv = FlashMediaSetPan(mh,
+	                       xPercent,
+	                       yPercent);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_FlashMediaSetZoom(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	short factor;
+#ifndef FlashMediaSetZoom
+	PyMac_PRECHECK(FlashMediaSetZoom);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      CmpInstObj_Convert, &mh,
+	                      &factor))
+		return NULL;
+	_rv = FlashMediaSetZoom(mh,
+	                        factor);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_FlashMediaSetZoomRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	long left;
+	long top;
+	long right;
+	long bottom;
+#ifndef FlashMediaSetZoomRect
+	PyMac_PRECHECK(FlashMediaSetZoomRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&llll",
+	                      CmpInstObj_Convert, &mh,
+	                      &left,
+	                      &top,
+	                      &right,
+	                      &bottom))
+		return NULL;
+	_rv = FlashMediaSetZoomRect(mh,
+	                            left,
+	                            top,
+	                            right,
+	                            bottom);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_FlashMediaGetRefConBounds(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	long refCon;
+	long left;
+	long top;
+	long right;
+	long bottom;
+#ifndef FlashMediaGetRefConBounds
+	PyMac_PRECHECK(FlashMediaGetRefConBounds);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &mh,
+	                      &refCon))
+		return NULL;
+	_rv = FlashMediaGetRefConBounds(mh,
+	                                refCon,
+	                                &left,
+	                                &top,
+	                                &right,
+	                                &bottom);
+	_res = Py_BuildValue("lllll",
+	                     _rv,
+	                     left,
+	                     top,
+	                     right,
+	                     bottom);
+	return _res;
+}
+
+static PyObject *Qt_FlashMediaGetRefConID(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	long refCon;
+	long refConID;
+#ifndef FlashMediaGetRefConID
+	PyMac_PRECHECK(FlashMediaGetRefConID);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &mh,
+	                      &refCon))
+		return NULL;
+	_rv = FlashMediaGetRefConID(mh,
+	                            refCon,
+	                            &refConID);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     refConID);
+	return _res;
+}
+
+static PyObject *Qt_FlashMediaIDToRefCon(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	long refConID;
+	long refCon;
+#ifndef FlashMediaIDToRefCon
+	PyMac_PRECHECK(FlashMediaIDToRefCon);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &mh,
+	                      &refConID))
+		return NULL;
+	_rv = FlashMediaIDToRefCon(mh,
+	                           refConID,
+	                           &refCon);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     refCon);
+	return _res;
+}
+
+static PyObject *Qt_FlashMediaGetDisplayedFrameNumber(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	long flashFrameNumber;
+#ifndef FlashMediaGetDisplayedFrameNumber
+	PyMac_PRECHECK(FlashMediaGetDisplayedFrameNumber);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &mh))
+		return NULL;
+	_rv = FlashMediaGetDisplayedFrameNumber(mh,
+	                                        &flashFrameNumber);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     flashFrameNumber);
+	return _res;
+}
+
+static PyObject *Qt_FlashMediaFrameNumberToMovieTime(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	long flashFrameNumber;
+	TimeValue movieTime;
+#ifndef FlashMediaFrameNumberToMovieTime
+	PyMac_PRECHECK(FlashMediaFrameNumberToMovieTime);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &mh,
+	                      &flashFrameNumber))
+		return NULL;
+	_rv = FlashMediaFrameNumberToMovieTime(mh,
+	                                       flashFrameNumber,
+	                                       &movieTime);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     movieTime);
+	return _res;
+}
+
+static PyObject *Qt_FlashMediaFrameLabelToMovieTime(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	Ptr theLabel;
+	TimeValue movieTime;
+#ifndef FlashMediaFrameLabelToMovieTime
+	PyMac_PRECHECK(FlashMediaFrameLabelToMovieTime);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&s",
+	                      CmpInstObj_Convert, &mh,
+	                      &theLabel))
+		return NULL;
+	_rv = FlashMediaFrameLabelToMovieTime(mh,
+	                                      theLabel,
+	                                      &movieTime);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     movieTime);
+	return _res;
+}
+
+static PyObject *Qt_FlashMediaGetFlashVariable(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	char path;
+	char name;
+	Handle theVariableCStringOut;
+#ifndef FlashMediaGetFlashVariable
+	PyMac_PRECHECK(FlashMediaGetFlashVariable);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &mh))
+		return NULL;
+	_rv = FlashMediaGetFlashVariable(mh,
+	                                 &path,
+	                                 &name,
+	                                 &theVariableCStringOut);
+	_res = Py_BuildValue("lccO&",
+	                     _rv,
+	                     path,
+	                     name,
+	                     ResObj_New, theVariableCStringOut);
+	return _res;
+}
+
+static PyObject *Qt_FlashMediaSetFlashVariable(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	char path;
+	char name;
+	char value;
+	Boolean updateFocus;
+#ifndef FlashMediaSetFlashVariable
+	PyMac_PRECHECK(FlashMediaSetFlashVariable);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&b",
+	                      CmpInstObj_Convert, &mh,
+	                      &updateFocus))
+		return NULL;
+	_rv = FlashMediaSetFlashVariable(mh,
+	                                 &path,
+	                                 &name,
+	                                 &value,
+	                                 updateFocus);
+	_res = Py_BuildValue("lccc",
+	                     _rv,
+	                     path,
+	                     name,
+	                     value);
+	return _res;
+}
+
+static PyObject *Qt_FlashMediaDoButtonActions(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	char path;
+	long buttonID;
+	long transition;
+#ifndef FlashMediaDoButtonActions
+	PyMac_PRECHECK(FlashMediaDoButtonActions);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&ll",
+	                      CmpInstObj_Convert, &mh,
+	                      &buttonID,
+	                      &transition))
+		return NULL;
+	_rv = FlashMediaDoButtonActions(mh,
+	                                &path,
+	                                buttonID,
+	                                transition);
+	_res = Py_BuildValue("lc",
+	                     _rv,
+	                     path);
+	return _res;
+}
+
+static PyObject *Qt_FlashMediaGetSupportedSwfVersion(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	UInt8 swfVersion;
+#ifndef FlashMediaGetSupportedSwfVersion
+	PyMac_PRECHECK(FlashMediaGetSupportedSwfVersion);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &mh))
+		return NULL;
+	_rv = FlashMediaGetSupportedSwfVersion(mh,
+	                                       &swfVersion);
+	_res = Py_BuildValue("lb",
+	                     _rv,
+	                     swfVersion);
+	return _res;
+}
+
+static PyObject *Qt_Media3DGetCurrentGroup(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	void * group;
+#ifndef Media3DGetCurrentGroup
+	PyMac_PRECHECK(Media3DGetCurrentGroup);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&s",
+	                      CmpInstObj_Convert, &mh,
+	                      &group))
+		return NULL;
+	_rv = Media3DGetCurrentGroup(mh,
+	                             group);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_Media3DTranslateNamedObjectTo(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	char objectName;
+	Fixed x;
+	Fixed y;
+	Fixed z;
+#ifndef Media3DTranslateNamedObjectTo
+	PyMac_PRECHECK(Media3DTranslateNamedObjectTo);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&O&",
+	                      CmpInstObj_Convert, &mh,
+	                      PyMac_GetFixed, &x,
+	                      PyMac_GetFixed, &y,
+	                      PyMac_GetFixed, &z))
+		return NULL;
+	_rv = Media3DTranslateNamedObjectTo(mh,
+	                                    &objectName,
+	                                    x,
+	                                    y,
+	                                    z);
+	_res = Py_BuildValue("lc",
+	                     _rv,
+	                     objectName);
+	return _res;
+}
+
+static PyObject *Qt_Media3DScaleNamedObjectTo(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	char objectName;
+	Fixed xScale;
+	Fixed yScale;
+	Fixed zScale;
+#ifndef Media3DScaleNamedObjectTo
+	PyMac_PRECHECK(Media3DScaleNamedObjectTo);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&O&",
+	                      CmpInstObj_Convert, &mh,
+	                      PyMac_GetFixed, &xScale,
+	                      PyMac_GetFixed, &yScale,
+	                      PyMac_GetFixed, &zScale))
+		return NULL;
+	_rv = Media3DScaleNamedObjectTo(mh,
+	                                &objectName,
+	                                xScale,
+	                                yScale,
+	                                zScale);
+	_res = Py_BuildValue("lc",
+	                     _rv,
+	                     objectName);
+	return _res;
+}
+
+static PyObject *Qt_Media3DRotateNamedObjectTo(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	char objectName;
+	Fixed xDegrees;
+	Fixed yDegrees;
+	Fixed zDegrees;
+#ifndef Media3DRotateNamedObjectTo
+	PyMac_PRECHECK(Media3DRotateNamedObjectTo);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&O&",
+	                      CmpInstObj_Convert, &mh,
+	                      PyMac_GetFixed, &xDegrees,
+	                      PyMac_GetFixed, &yDegrees,
+	                      PyMac_GetFixed, &zDegrees))
+		return NULL;
+	_rv = Media3DRotateNamedObjectTo(mh,
+	                                 &objectName,
+	                                 xDegrees,
+	                                 yDegrees,
+	                                 zDegrees);
+	_res = Py_BuildValue("lc",
+	                     _rv,
+	                     objectName);
+	return _res;
+}
+
+static PyObject *Qt_Media3DSetCameraData(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	void * cameraData;
+#ifndef Media3DSetCameraData
+	PyMac_PRECHECK(Media3DSetCameraData);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&s",
+	                      CmpInstObj_Convert, &mh,
+	                      &cameraData))
+		return NULL;
+	_rv = Media3DSetCameraData(mh,
+	                           cameraData);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_Media3DGetCameraData(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	void * cameraData;
+#ifndef Media3DGetCameraData
+	PyMac_PRECHECK(Media3DGetCameraData);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&s",
+	                      CmpInstObj_Convert, &mh,
+	                      &cameraData))
+		return NULL;
+	_rv = Media3DGetCameraData(mh,
+	                           cameraData);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_Media3DSetCameraAngleAspect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	QTFloatSingle fov;
+	QTFloatSingle aspectRatioXToY;
+#ifndef Media3DSetCameraAngleAspect
+	PyMac_PRECHECK(Media3DSetCameraAngleAspect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&ff",
+	                      CmpInstObj_Convert, &mh,
+	                      &fov,
+	                      &aspectRatioXToY))
+		return NULL;
+	_rv = Media3DSetCameraAngleAspect(mh,
+	                                  fov,
+	                                  aspectRatioXToY);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_Media3DGetCameraAngleAspect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	QTFloatSingle fov;
+	QTFloatSingle aspectRatioXToY;
+#ifndef Media3DGetCameraAngleAspect
+	PyMac_PRECHECK(Media3DGetCameraAngleAspect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &mh))
+		return NULL;
+	_rv = Media3DGetCameraAngleAspect(mh,
+	                                  &fov,
+	                                  &aspectRatioXToY);
+	_res = Py_BuildValue("lff",
+	                     _rv,
+	                     fov,
+	                     aspectRatioXToY);
+	return _res;
+}
+
+static PyObject *Qt_Media3DSetCameraRange(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	void * tQ3CameraRange;
+#ifndef Media3DSetCameraRange
+	PyMac_PRECHECK(Media3DSetCameraRange);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&s",
+	                      CmpInstObj_Convert, &mh,
+	                      &tQ3CameraRange))
+		return NULL;
+	_rv = Media3DSetCameraRange(mh,
+	                            tQ3CameraRange);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_Media3DGetCameraRange(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	void * tQ3CameraRange;
+#ifndef Media3DGetCameraRange
+	PyMac_PRECHECK(Media3DGetCameraRange);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&s",
+	                      CmpInstObj_Convert, &mh,
+	                      &tQ3CameraRange))
+		return NULL;
+	_rv = Media3DGetCameraRange(mh,
+	                            tQ3CameraRange);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_NewTimeBase(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	TimeBase _rv;
+#ifndef NewTimeBase
+	PyMac_PRECHECK(NewTimeBase);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = NewTimeBase();
+	_res = Py_BuildValue("O&",
+	                     TimeBaseObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Qt_ConvertTime(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	TimeRecord theTime;
+	TimeBase newBase;
+#ifndef ConvertTime
+	PyMac_PRECHECK(ConvertTime);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      QtTimeRecord_Convert, &theTime,
+	                      TimeBaseObj_Convert, &newBase))
+		return NULL;
+	ConvertTime(&theTime,
+	            newBase);
+	_res = Py_BuildValue("O&",
+	                     QtTimeRecord_New, &theTime);
+	return _res;
+}
+
+static PyObject *Qt_ConvertTimeScale(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	TimeRecord theTime;
+	TimeScale newScale;
+#ifndef ConvertTimeScale
+	PyMac_PRECHECK(ConvertTimeScale);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      QtTimeRecord_Convert, &theTime,
+	                      &newScale))
+		return NULL;
+	ConvertTimeScale(&theTime,
+	                 newScale);
+	_res = Py_BuildValue("O&",
+	                     QtTimeRecord_New, &theTime);
+	return _res;
+}
+
+static PyObject *Qt_AddTime(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	TimeRecord dst;
+	TimeRecord src;
+#ifndef AddTime
+	PyMac_PRECHECK(AddTime);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      QtTimeRecord_Convert, &dst,
+	                      QtTimeRecord_Convert, &src))
+		return NULL;
+	AddTime(&dst,
+	        &src);
+	_res = Py_BuildValue("O&",
+	                     QtTimeRecord_New, &dst);
+	return _res;
+}
+
+static PyObject *Qt_SubtractTime(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	TimeRecord dst;
+	TimeRecord src;
+#ifndef SubtractTime
+	PyMac_PRECHECK(SubtractTime);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      QtTimeRecord_Convert, &dst,
+	                      QtTimeRecord_Convert, &src))
+		return NULL;
+	SubtractTime(&dst,
+	             &src);
+	_res = Py_BuildValue("O&",
+	                     QtTimeRecord_New, &dst);
+	return _res;
+}
+
+static PyObject *Qt_MusicMediaGetIndexedTunePlayer(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	ComponentInstance ti;
+	long sampleDescIndex;
+	ComponentInstance tp;
+#ifndef MusicMediaGetIndexedTunePlayer
+	PyMac_PRECHECK(MusicMediaGetIndexedTunePlayer);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &ti,
+	                      &sampleDescIndex))
+		return NULL;
+	_rv = MusicMediaGetIndexedTunePlayer(ti,
+	                                     sampleDescIndex,
+	                                     &tp);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     CmpInstObj_New, tp);
+	return _res;
+}
+
+static PyObject *Qt_CodecManagerVersion(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	long version;
+#ifndef CodecManagerVersion
+	PyMac_PRECHECK(CodecManagerVersion);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = CodecManagerVersion(&version);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     version);
+	return _res;
+}
+
+static PyObject *Qt_GetMaxCompressionSize(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	PixMapHandle src;
+	Rect srcRect;
+	short colorDepth;
+	CodecQ quality;
+	CodecType cType;
+	CompressorComponent codec;
+	long size;
+#ifndef GetMaxCompressionSize
+	PyMac_PRECHECK(GetMaxCompressionSize);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&hlO&O&",
+	                      ResObj_Convert, &src,
+	                      PyMac_GetRect, &srcRect,
+	                      &colorDepth,
+	                      &quality,
+	                      PyMac_GetOSType, &cType,
+	                      CmpObj_Convert, &codec))
+		return NULL;
+	_err = GetMaxCompressionSize(src,
+	                             &srcRect,
+	                             colorDepth,
+	                             quality,
+	                             cType,
+	                             codec,
+	                             &size);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     size);
+	return _res;
+}
+
+static PyObject *Qt_GetCompressionTime(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	PixMapHandle src;
+	Rect srcRect;
+	short colorDepth;
+	CodecType cType;
+	CompressorComponent codec;
+	CodecQ spatialQuality;
+	CodecQ temporalQuality;
+	unsigned long compressTime;
+#ifndef GetCompressionTime
+	PyMac_PRECHECK(GetCompressionTime);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&hO&O&",
+	                      ResObj_Convert, &src,
+	                      PyMac_GetRect, &srcRect,
+	                      &colorDepth,
+	                      PyMac_GetOSType, &cType,
+	                      CmpObj_Convert, &codec))
+		return NULL;
+	_err = GetCompressionTime(src,
+	                          &srcRect,
+	                          colorDepth,
+	                          cType,
+	                          codec,
+	                          &spatialQuality,
+	                          &temporalQuality,
+	                          &compressTime);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("lll",
+	                     spatialQuality,
+	                     temporalQuality,
+	                     compressTime);
+	return _res;
+}
+
+static PyObject *Qt_CompressImage(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	PixMapHandle src;
+	Rect srcRect;
+	CodecQ quality;
+	CodecType cType;
+	ImageDescriptionHandle desc;
+	Ptr data;
+#ifndef CompressImage
+	PyMac_PRECHECK(CompressImage);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&lO&O&s",
+	                      ResObj_Convert, &src,
+	                      PyMac_GetRect, &srcRect,
+	                      &quality,
+	                      PyMac_GetOSType, &cType,
+	                      ResObj_Convert, &desc,
+	                      &data))
+		return NULL;
+	_err = CompressImage(src,
+	                     &srcRect,
+	                     quality,
+	                     cType,
+	                     desc,
+	                     data);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qt_DecompressImage(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Ptr data;
+	ImageDescriptionHandle desc;
+	PixMapHandle dst;
+	Rect srcRect;
+	Rect dstRect;
+	short mode;
+	RgnHandle mask;
+#ifndef DecompressImage
+	PyMac_PRECHECK(DecompressImage);
+#endif
+	if (!PyArg_ParseTuple(_args, "sO&O&O&O&hO&",
+	                      &data,
+	                      ResObj_Convert, &desc,
+	                      ResObj_Convert, &dst,
+	                      PyMac_GetRect, &srcRect,
+	                      PyMac_GetRect, &dstRect,
+	                      &mode,
+	                      ResObj_Convert, &mask))
+		return NULL;
+	_err = DecompressImage(data,
+	                       desc,
+	                       dst,
+	                       &srcRect,
+	                       &dstRect,
+	                       mode,
+	                       mask);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qt_GetSimilarity(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	PixMapHandle src;
+	Rect srcRect;
+	ImageDescriptionHandle desc;
+	Ptr data;
+	Fixed similarity;
+#ifndef GetSimilarity
+	PyMac_PRECHECK(GetSimilarity);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&s",
+	                      ResObj_Convert, &src,
+	                      PyMac_GetRect, &srcRect,
+	                      ResObj_Convert, &desc,
+	                      &data))
+		return NULL;
+	_err = GetSimilarity(src,
+	                     &srcRect,
+	                     desc,
+	                     data,
+	                     &similarity);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildFixed, similarity);
+	return _res;
+}
+
+static PyObject *Qt_GetImageDescriptionCTable(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	ImageDescriptionHandle desc;
+	CTabHandle ctable;
+#ifndef GetImageDescriptionCTable
+	PyMac_PRECHECK(GetImageDescriptionCTable);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &desc))
+		return NULL;
+	_err = GetImageDescriptionCTable(desc,
+	                                 &ctable);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, ctable);
+	return _res;
+}
+
+static PyObject *Qt_SetImageDescriptionCTable(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	ImageDescriptionHandle desc;
+	CTabHandle ctable;
+#ifndef SetImageDescriptionCTable
+	PyMac_PRECHECK(SetImageDescriptionCTable);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      ResObj_Convert, &desc,
+	                      ResObj_Convert, &ctable))
+		return NULL;
+	_err = SetImageDescriptionCTable(desc,
+	                                 ctable);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qt_GetImageDescriptionExtension(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	ImageDescriptionHandle desc;
+	Handle extension;
+	long idType;
+	long index;
+#ifndef GetImageDescriptionExtension
+	PyMac_PRECHECK(GetImageDescriptionExtension);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&ll",
+	                      ResObj_Convert, &desc,
+	                      &idType,
+	                      &index))
+		return NULL;
+	_err = GetImageDescriptionExtension(desc,
+	                                    &extension,
+	                                    idType,
+	                                    index);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, extension);
+	return _res;
+}
+
+static PyObject *Qt_AddImageDescriptionExtension(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	ImageDescriptionHandle desc;
+	Handle extension;
+	long idType;
+#ifndef AddImageDescriptionExtension
+	PyMac_PRECHECK(AddImageDescriptionExtension);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&l",
+	                      ResObj_Convert, &desc,
+	                      ResObj_Convert, &extension,
+	                      &idType))
+		return NULL;
+	_err = AddImageDescriptionExtension(desc,
+	                                    extension,
+	                                    idType);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qt_RemoveImageDescriptionExtension(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	ImageDescriptionHandle desc;
+	long idType;
+	long index;
+#ifndef RemoveImageDescriptionExtension
+	PyMac_PRECHECK(RemoveImageDescriptionExtension);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&ll",
+	                      ResObj_Convert, &desc,
+	                      &idType,
+	                      &index))
+		return NULL;
+	_err = RemoveImageDescriptionExtension(desc,
+	                                       idType,
+	                                       index);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qt_CountImageDescriptionExtensionType(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	ImageDescriptionHandle desc;
+	long idType;
+	long count;
+#ifndef CountImageDescriptionExtensionType
+	PyMac_PRECHECK(CountImageDescriptionExtensionType);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      ResObj_Convert, &desc,
+	                      &idType))
+		return NULL;
+	_err = CountImageDescriptionExtensionType(desc,
+	                                          idType,
+	                                          &count);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     count);
+	return _res;
+}
+
+static PyObject *Qt_GetNextImageDescriptionExtensionType(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	ImageDescriptionHandle desc;
+	long idType;
+#ifndef GetNextImageDescriptionExtensionType
+	PyMac_PRECHECK(GetNextImageDescriptionExtensionType);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &desc))
+		return NULL;
+	_err = GetNextImageDescriptionExtensionType(desc,
+	                                            &idType);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     idType);
+	return _res;
+}
+
+static PyObject *Qt_FindCodec(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	CodecType cType;
+	CodecComponent specCodec;
+	CompressorComponent compressor;
+	DecompressorComponent decompressor;
+#ifndef FindCodec
+	PyMac_PRECHECK(FindCodec);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetOSType, &cType,
+	                      CmpObj_Convert, &specCodec))
+		return NULL;
+	_err = FindCodec(cType,
+	                 specCodec,
+	                 &compressor,
+	                 &decompressor);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&O&",
+	                     CmpObj_New, compressor,
+	                     CmpObj_New, decompressor);
+	return _res;
+}
+
+static PyObject *Qt_CompressPicture(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	PicHandle srcPicture;
+	PicHandle dstPicture;
+	CodecQ quality;
+	CodecType cType;
+#ifndef CompressPicture
+	PyMac_PRECHECK(CompressPicture);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&lO&",
+	                      ResObj_Convert, &srcPicture,
+	                      ResObj_Convert, &dstPicture,
+	                      &quality,
+	                      PyMac_GetOSType, &cType))
+		return NULL;
+	_err = CompressPicture(srcPicture,
+	                       dstPicture,
+	                       quality,
+	                       cType);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qt_CompressPictureFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short srcRefNum;
+	short dstRefNum;
+	CodecQ quality;
+	CodecType cType;
+#ifndef CompressPictureFile
+	PyMac_PRECHECK(CompressPictureFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "hhlO&",
+	                      &srcRefNum,
+	                      &dstRefNum,
+	                      &quality,
+	                      PyMac_GetOSType, &cType))
+		return NULL;
+	_err = CompressPictureFile(srcRefNum,
+	                           dstRefNum,
+	                           quality,
+	                           cType);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qt_ConvertImage(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	ImageDescriptionHandle srcDD;
+	Ptr srcData;
+	short colorDepth;
+	CTabHandle ctable;
+	CodecQ accuracy;
+	CodecQ quality;
+	CodecType cType;
+	CodecComponent codec;
+	ImageDescriptionHandle dstDD;
+	Ptr dstData;
+#ifndef ConvertImage
+	PyMac_PRECHECK(ConvertImage);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&shO&llO&O&O&s",
+	                      ResObj_Convert, &srcDD,
+	                      &srcData,
+	                      &colorDepth,
+	                      ResObj_Convert, &ctable,
+	                      &accuracy,
+	                      &quality,
+	                      PyMac_GetOSType, &cType,
+	                      CmpObj_Convert, &codec,
+	                      ResObj_Convert, &dstDD,
+	                      &dstData))
+		return NULL;
+	_err = ConvertImage(srcDD,
+	                    srcData,
+	                    colorDepth,
+	                    ctable,
+	                    accuracy,
+	                    quality,
+	                    cType,
+	                    codec,
+	                    dstDD,
+	                    dstData);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qt_AddFilePreview(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short resRefNum;
+	OSType previewType;
+	Handle previewData;
+#ifndef AddFilePreview
+	PyMac_PRECHECK(AddFilePreview);
+#endif
+	if (!PyArg_ParseTuple(_args, "hO&O&",
+	                      &resRefNum,
+	                      PyMac_GetOSType, &previewType,
+	                      ResObj_Convert, &previewData))
+		return NULL;
+	_err = AddFilePreview(resRefNum,
+	                      previewType,
+	                      previewData);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qt_GetBestDeviceRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	GDHandle gdh;
+	Rect rp;
+#ifndef GetBestDeviceRect
+	PyMac_PRECHECK(GetBestDeviceRect);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetBestDeviceRect(&gdh,
+	                         &rp);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&O&",
+	                     OptResObj_New, gdh,
+	                     PyMac_BuildRect, &rp);
+	return _res;
+}
+
+static PyObject *Qt_GDHasScale(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	GDHandle gdh;
+	short depth;
+	Fixed scale;
+#ifndef GDHasScale
+	PyMac_PRECHECK(GDHasScale);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      OptResObj_Convert, &gdh,
+	                      &depth))
+		return NULL;
+	_err = GDHasScale(gdh,
+	                  depth,
+	                  &scale);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildFixed, scale);
+	return _res;
+}
+
+static PyObject *Qt_GDGetScale(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	GDHandle gdh;
+	Fixed scale;
+	short flags;
+#ifndef GDGetScale
+	PyMac_PRECHECK(GDGetScale);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      OptResObj_Convert, &gdh))
+		return NULL;
+	_err = GDGetScale(gdh,
+	                  &scale,
+	                  &flags);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&h",
+	                     PyMac_BuildFixed, scale,
+	                     flags);
+	return _res;
+}
+
+static PyObject *Qt_GDSetScale(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	GDHandle gdh;
+	Fixed scale;
+	short flags;
+#ifndef GDSetScale
+	PyMac_PRECHECK(GDSetScale);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&h",
+	                      OptResObj_Convert, &gdh,
+	                      PyMac_GetFixed, &scale,
+	                      &flags))
+		return NULL;
+	_err = GDSetScale(gdh,
+	                  scale,
+	                  flags);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qt_GetGraphicsImporterForFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	FSSpec theFile;
+	ComponentInstance gi;
+#ifndef GetGraphicsImporterForFile
+	PyMac_PRECHECK(GetGraphicsImporterForFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetFSSpec, &theFile))
+		return NULL;
+	_err = GetGraphicsImporterForFile(&theFile,
+	                                  &gi);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CmpInstObj_New, gi);
+	return _res;
+}
+
+static PyObject *Qt_GetGraphicsImporterForDataRef(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Handle dataRef;
+	OSType dataRefType;
+	ComponentInstance gi;
+#ifndef GetGraphicsImporterForDataRef
+	PyMac_PRECHECK(GetGraphicsImporterForDataRef);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      ResObj_Convert, &dataRef,
+	                      PyMac_GetOSType, &dataRefType))
+		return NULL;
+	_err = GetGraphicsImporterForDataRef(dataRef,
+	                                     dataRefType,
+	                                     &gi);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CmpInstObj_New, gi);
+	return _res;
+}
+
+static PyObject *Qt_GetGraphicsImporterForFileWithFlags(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	FSSpec theFile;
+	ComponentInstance gi;
+	long flags;
+#ifndef GetGraphicsImporterForFileWithFlags
+	PyMac_PRECHECK(GetGraphicsImporterForFileWithFlags);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      PyMac_GetFSSpec, &theFile,
+	                      &flags))
+		return NULL;
+	_err = GetGraphicsImporterForFileWithFlags(&theFile,
+	                                           &gi,
+	                                           flags);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CmpInstObj_New, gi);
+	return _res;
+}
+
+static PyObject *Qt_GetGraphicsImporterForDataRefWithFlags(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Handle dataRef;
+	OSType dataRefType;
+	ComponentInstance gi;
+	long flags;
+#ifndef GetGraphicsImporterForDataRefWithFlags
+	PyMac_PRECHECK(GetGraphicsImporterForDataRefWithFlags);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&l",
+	                      ResObj_Convert, &dataRef,
+	                      PyMac_GetOSType, &dataRefType,
+	                      &flags))
+		return NULL;
+	_err = GetGraphicsImporterForDataRefWithFlags(dataRef,
+	                                              dataRefType,
+	                                              &gi,
+	                                              flags);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CmpInstObj_New, gi);
+	return _res;
+}
+
+static PyObject *Qt_MakeImageDescriptionForPixMap(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	PixMapHandle pixmap;
+	ImageDescriptionHandle idh;
+#ifndef MakeImageDescriptionForPixMap
+	PyMac_PRECHECK(MakeImageDescriptionForPixMap);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &pixmap))
+		return NULL;
+	_err = MakeImageDescriptionForPixMap(pixmap,
+	                                     &idh);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, idh);
+	return _res;
+}
+
+static PyObject *Qt_MakeImageDescriptionForEffect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	OSType effectType;
+	ImageDescriptionHandle idh;
+#ifndef MakeImageDescriptionForEffect
+	PyMac_PRECHECK(MakeImageDescriptionForEffect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetOSType, &effectType))
+		return NULL;
+	_err = MakeImageDescriptionForEffect(effectType,
+	                                     &idh);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, idh);
+	return _res;
+}
+
+static PyObject *Qt_QTGetPixelSize(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short _rv;
+	OSType PixelFormat;
+#ifndef QTGetPixelSize
+	PyMac_PRECHECK(QTGetPixelSize);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetOSType, &PixelFormat))
+		return NULL;
+	_rv = QTGetPixelSize(PixelFormat);
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_QTGetPixelFormatDepthForImageDescription(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short _rv;
+	OSType PixelFormat;
+#ifndef QTGetPixelFormatDepthForImageDescription
+	PyMac_PRECHECK(QTGetPixelFormatDepthForImageDescription);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetOSType, &PixelFormat))
+		return NULL;
+	_rv = QTGetPixelFormatDepthForImageDescription(PixelFormat);
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_QTGetPixMapHandleRowBytes(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long _rv;
+	PixMapHandle pm;
+#ifndef QTGetPixMapHandleRowBytes
+	PyMac_PRECHECK(QTGetPixMapHandleRowBytes);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &pm))
+		return NULL;
+	_rv = QTGetPixMapHandleRowBytes(pm);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_QTSetPixMapHandleRowBytes(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	PixMapHandle pm;
+	long rowBytes;
+#ifndef QTSetPixMapHandleRowBytes
+	PyMac_PRECHECK(QTSetPixMapHandleRowBytes);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      ResObj_Convert, &pm,
+	                      &rowBytes))
+		return NULL;
+	_err = QTSetPixMapHandleRowBytes(pm,
+	                                 rowBytes);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qt_QTGetPixMapHandleGammaLevel(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Fixed _rv;
+	PixMapHandle pm;
+#ifndef QTGetPixMapHandleGammaLevel
+	PyMac_PRECHECK(QTGetPixMapHandleGammaLevel);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &pm))
+		return NULL;
+	_rv = QTGetPixMapHandleGammaLevel(pm);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildFixed, _rv);
+	return _res;
+}
+
+static PyObject *Qt_QTSetPixMapHandleGammaLevel(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	PixMapHandle pm;
+	Fixed gammaLevel;
+#ifndef QTSetPixMapHandleGammaLevel
+	PyMac_PRECHECK(QTSetPixMapHandleGammaLevel);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      ResObj_Convert, &pm,
+	                      PyMac_GetFixed, &gammaLevel))
+		return NULL;
+	_err = QTSetPixMapHandleGammaLevel(pm,
+	                                   gammaLevel);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qt_QTGetPixMapHandleRequestedGammaLevel(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Fixed _rv;
+	PixMapHandle pm;
+#ifndef QTGetPixMapHandleRequestedGammaLevel
+	PyMac_PRECHECK(QTGetPixMapHandleRequestedGammaLevel);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &pm))
+		return NULL;
+	_rv = QTGetPixMapHandleRequestedGammaLevel(pm);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildFixed, _rv);
+	return _res;
+}
+
+static PyObject *Qt_QTSetPixMapHandleRequestedGammaLevel(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	PixMapHandle pm;
+	Fixed requestedGammaLevel;
+#ifndef QTSetPixMapHandleRequestedGammaLevel
+	PyMac_PRECHECK(QTSetPixMapHandleRequestedGammaLevel);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      ResObj_Convert, &pm,
+	                      PyMac_GetFixed, &requestedGammaLevel))
+		return NULL;
+	_err = QTSetPixMapHandleRequestedGammaLevel(pm,
+	                                            requestedGammaLevel);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qt_CompAdd(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	wide src;
+	wide dst;
+#ifndef CompAdd
+	PyMac_PRECHECK(CompAdd);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	CompAdd(&src,
+	        &dst);
+	_res = Py_BuildValue("O&O&",
+	                     PyMac_Buildwide, src,
+	                     PyMac_Buildwide, dst);
+	return _res;
+}
+
+static PyObject *Qt_CompSub(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	wide src;
+	wide dst;
+#ifndef CompSub
+	PyMac_PRECHECK(CompSub);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	CompSub(&src,
+	        &dst);
+	_res = Py_BuildValue("O&O&",
+	                     PyMac_Buildwide, src,
+	                     PyMac_Buildwide, dst);
+	return _res;
+}
+
+static PyObject *Qt_CompNeg(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	wide dst;
+#ifndef CompNeg
+	PyMac_PRECHECK(CompNeg);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	CompNeg(&dst);
+	_res = Py_BuildValue("O&",
+	                     PyMac_Buildwide, dst);
+	return _res;
+}
+
+static PyObject *Qt_CompShift(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	wide src;
+	short shift;
+#ifndef CompShift
+	PyMac_PRECHECK(CompShift);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &shift))
+		return NULL;
+	CompShift(&src,
+	          shift);
+	_res = Py_BuildValue("O&",
+	                     PyMac_Buildwide, src);
+	return _res;
+}
+
+static PyObject *Qt_CompMul(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long src1;
+	long src2;
+	wide dst;
+#ifndef CompMul
+	PyMac_PRECHECK(CompMul);
+#endif
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &src1,
+	                      &src2))
+		return NULL;
+	CompMul(src1,
+	        src2,
+	        &dst);
+	_res = Py_BuildValue("O&",
+	                     PyMac_Buildwide, dst);
+	return _res;
+}
+
+static PyObject *Qt_CompDiv(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long _rv;
+	wide numerator;
+	long denominator;
+	long remainder;
+#ifndef CompDiv
+	PyMac_PRECHECK(CompDiv);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &denominator))
+		return NULL;
+	_rv = CompDiv(&numerator,
+	              denominator,
+	              &remainder);
+	_res = Py_BuildValue("lO&l",
+	                     _rv,
+	                     PyMac_Buildwide, numerator,
+	                     remainder);
+	return _res;
+}
+
+static PyObject *Qt_CompFixMul(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	wide compSrc;
+	Fixed fixSrc;
+	wide compDst;
+#ifndef CompFixMul
+	PyMac_PRECHECK(CompFixMul);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetFixed, &fixSrc))
+		return NULL;
+	CompFixMul(&compSrc,
+	           fixSrc,
+	           &compDst);
+	_res = Py_BuildValue("O&O&",
+	                     PyMac_Buildwide, compSrc,
+	                     PyMac_Buildwide, compDst);
+	return _res;
+}
+
+static PyObject *Qt_CompMulDiv(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	wide co;
+	long mul;
+	long divisor;
+#ifndef CompMulDiv
+	PyMac_PRECHECK(CompMulDiv);
+#endif
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &mul,
+	                      &divisor))
+		return NULL;
+	CompMulDiv(&co,
+	           mul,
+	           divisor);
+	_res = Py_BuildValue("O&",
+	                     PyMac_Buildwide, co);
+	return _res;
+}
+
+static PyObject *Qt_CompMulDivTrunc(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	wide co;
+	long mul;
+	long divisor;
+	long remainder;
+#ifndef CompMulDivTrunc
+	PyMac_PRECHECK(CompMulDivTrunc);
+#endif
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &mul,
+	                      &divisor))
+		return NULL;
+	CompMulDivTrunc(&co,
+	                mul,
+	                divisor,
+	                &remainder);
+	_res = Py_BuildValue("O&l",
+	                     PyMac_Buildwide, co,
+	                     remainder);
+	return _res;
+}
+
+static PyObject *Qt_CompCompare(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long _rv;
+	wide a;
+	wide minusb;
+#ifndef CompCompare
+	PyMac_PRECHECK(CompCompare);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_Getwide, &a,
+	                      PyMac_Getwide, &minusb))
+		return NULL;
+	_rv = CompCompare(&a,
+	                  &minusb);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_CompSquareRoot(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	unsigned long _rv;
+	wide src;
+#ifndef CompSquareRoot
+	PyMac_PRECHECK(CompSquareRoot);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_Getwide, &src))
+		return NULL;
+	_rv = CompSquareRoot(&src);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_FixMulDiv(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Fixed _rv;
+	Fixed src;
+	Fixed mul;
+	Fixed divisor;
+#ifndef FixMulDiv
+	PyMac_PRECHECK(FixMulDiv);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      PyMac_GetFixed, &src,
+	                      PyMac_GetFixed, &mul,
+	                      PyMac_GetFixed, &divisor))
+		return NULL;
+	_rv = FixMulDiv(src,
+	                mul,
+	                divisor);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildFixed, _rv);
+	return _res;
+}
+
+static PyObject *Qt_UnsignedFixMulDiv(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Fixed _rv;
+	Fixed src;
+	Fixed mul;
+	Fixed divisor;
+#ifndef UnsignedFixMulDiv
+	PyMac_PRECHECK(UnsignedFixMulDiv);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      PyMac_GetFixed, &src,
+	                      PyMac_GetFixed, &mul,
+	                      PyMac_GetFixed, &divisor))
+		return NULL;
+	_rv = UnsignedFixMulDiv(src,
+	                        mul,
+	                        divisor);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildFixed, _rv);
+	return _res;
+}
+
+static PyObject *Qt_FixExp2(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Fixed _rv;
+	Fixed src;
+#ifndef FixExp2
+	PyMac_PRECHECK(FixExp2);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetFixed, &src))
+		return NULL;
+	_rv = FixExp2(src);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildFixed, _rv);
+	return _res;
+}
+
+static PyObject *Qt_FixLog2(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Fixed _rv;
+	Fixed src;
+#ifndef FixLog2
+	PyMac_PRECHECK(FixLog2);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetFixed, &src))
+		return NULL;
+	_rv = FixLog2(src);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildFixed, _rv);
+	return _res;
+}
+
+static PyObject *Qt_FixPow(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Fixed _rv;
+	Fixed base;
+	Fixed exp;
+#ifndef FixPow
+	PyMac_PRECHECK(FixPow);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetFixed, &base,
+	                      PyMac_GetFixed, &exp))
+		return NULL;
+	_rv = FixPow(base,
+	             exp);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildFixed, _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportSetDataReference(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	Handle dataRef;
+	OSType dataReType;
+#ifndef GraphicsImportSetDataReference
+	PyMac_PRECHECK(GraphicsImportSetDataReference);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      CmpObj_Convert, &ci,
+	                      ResObj_Convert, &dataRef,
+	                      PyMac_GetOSType, &dataReType))
+		return NULL;
+	_rv = GraphicsImportSetDataReference(ci,
+	                                     dataRef,
+	                                     dataReType);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportGetDataReference(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	Handle dataRef;
+	OSType dataReType;
+#ifndef GraphicsImportGetDataReference
+	PyMac_PRECHECK(GraphicsImportGetDataReference);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsImportGetDataReference(ci,
+	                                     &dataRef,
+	                                     &dataReType);
+	_res = Py_BuildValue("lO&O&",
+	                     _rv,
+	                     ResObj_New, dataRef,
+	                     PyMac_BuildOSType, dataReType);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportSetDataFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	FSSpec theFile;
+#ifndef GraphicsImportSetDataFile
+	PyMac_PRECHECK(GraphicsImportSetDataFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &ci,
+	                      PyMac_GetFSSpec, &theFile))
+		return NULL;
+	_rv = GraphicsImportSetDataFile(ci,
+	                                &theFile);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportGetDataFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	FSSpec theFile;
+#ifndef GraphicsImportGetDataFile
+	PyMac_PRECHECK(GraphicsImportGetDataFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &ci,
+	                      PyMac_GetFSSpec, &theFile))
+		return NULL;
+	_rv = GraphicsImportGetDataFile(ci,
+	                                &theFile);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportSetDataHandle(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	Handle h;
+#ifndef GraphicsImportSetDataHandle
+	PyMac_PRECHECK(GraphicsImportSetDataHandle);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &ci,
+	                      ResObj_Convert, &h))
+		return NULL;
+	_rv = GraphicsImportSetDataHandle(ci,
+	                                  h);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportGetDataHandle(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	Handle h;
+#ifndef GraphicsImportGetDataHandle
+	PyMac_PRECHECK(GraphicsImportGetDataHandle);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsImportGetDataHandle(ci,
+	                                  &h);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     ResObj_New, h);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportGetImageDescription(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	ImageDescriptionHandle desc;
+#ifndef GraphicsImportGetImageDescription
+	PyMac_PRECHECK(GraphicsImportGetImageDescription);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsImportGetImageDescription(ci,
+	                                        &desc);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     ResObj_New, desc);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportGetDataOffsetAndSize(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	unsigned long offset;
+	unsigned long size;
+#ifndef GraphicsImportGetDataOffsetAndSize
+	PyMac_PRECHECK(GraphicsImportGetDataOffsetAndSize);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsImportGetDataOffsetAndSize(ci,
+	                                         &offset,
+	                                         &size);
+	_res = Py_BuildValue("lll",
+	                     _rv,
+	                     offset,
+	                     size);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportReadData(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	void * dataPtr;
+	unsigned long dataOffset;
+	unsigned long dataSize;
+#ifndef GraphicsImportReadData
+	PyMac_PRECHECK(GraphicsImportReadData);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&sll",
+	                      CmpObj_Convert, &ci,
+	                      &dataPtr,
+	                      &dataOffset,
+	                      &dataSize))
+		return NULL;
+	_rv = GraphicsImportReadData(ci,
+	                             dataPtr,
+	                             dataOffset,
+	                             dataSize);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportSetClip(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	RgnHandle clipRgn;
+#ifndef GraphicsImportSetClip
+	PyMac_PRECHECK(GraphicsImportSetClip);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &ci,
+	                      ResObj_Convert, &clipRgn))
+		return NULL;
+	_rv = GraphicsImportSetClip(ci,
+	                            clipRgn);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportGetClip(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	RgnHandle clipRgn;
+#ifndef GraphicsImportGetClip
+	PyMac_PRECHECK(GraphicsImportGetClip);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsImportGetClip(ci,
+	                            &clipRgn);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     ResObj_New, clipRgn);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportSetSourceRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	Rect sourceRect;
+#ifndef GraphicsImportSetSourceRect
+	PyMac_PRECHECK(GraphicsImportSetSourceRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &ci,
+	                      PyMac_GetRect, &sourceRect))
+		return NULL;
+	_rv = GraphicsImportSetSourceRect(ci,
+	                                  &sourceRect);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportGetSourceRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	Rect sourceRect;
+#ifndef GraphicsImportGetSourceRect
+	PyMac_PRECHECK(GraphicsImportGetSourceRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsImportGetSourceRect(ci,
+	                                  &sourceRect);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     PyMac_BuildRect, &sourceRect);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportGetNaturalBounds(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	Rect naturalBounds;
+#ifndef GraphicsImportGetNaturalBounds
+	PyMac_PRECHECK(GraphicsImportGetNaturalBounds);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsImportGetNaturalBounds(ci,
+	                                     &naturalBounds);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     PyMac_BuildRect, &naturalBounds);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportDraw(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+#ifndef GraphicsImportDraw
+	PyMac_PRECHECK(GraphicsImportDraw);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsImportDraw(ci);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportSetGWorld(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	CGrafPtr port;
+	GDHandle gd;
+#ifndef GraphicsImportSetGWorld
+	PyMac_PRECHECK(GraphicsImportSetGWorld);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      CmpObj_Convert, &ci,
+	                      GrafObj_Convert, &port,
+	                      OptResObj_Convert, &gd))
+		return NULL;
+	_rv = GraphicsImportSetGWorld(ci,
+	                              port,
+	                              gd);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportGetGWorld(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	CGrafPtr port;
+	GDHandle gd;
+#ifndef GraphicsImportGetGWorld
+	PyMac_PRECHECK(GraphicsImportGetGWorld);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsImportGetGWorld(ci,
+	                              &port,
+	                              &gd);
+	_res = Py_BuildValue("lO&O&",
+	                     _rv,
+	                     GrafObj_New, port,
+	                     OptResObj_New, gd);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportSetBoundsRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	Rect bounds;
+#ifndef GraphicsImportSetBoundsRect
+	PyMac_PRECHECK(GraphicsImportSetBoundsRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &ci,
+	                      PyMac_GetRect, &bounds))
+		return NULL;
+	_rv = GraphicsImportSetBoundsRect(ci,
+	                                  &bounds);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportGetBoundsRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	Rect bounds;
+#ifndef GraphicsImportGetBoundsRect
+	PyMac_PRECHECK(GraphicsImportGetBoundsRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsImportGetBoundsRect(ci,
+	                                  &bounds);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     PyMac_BuildRect, &bounds);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportSaveAsPicture(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	FSSpec fss;
+	ScriptCode scriptTag;
+#ifndef GraphicsImportSaveAsPicture
+	PyMac_PRECHECK(GraphicsImportSaveAsPicture);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&h",
+	                      CmpObj_Convert, &ci,
+	                      PyMac_GetFSSpec, &fss,
+	                      &scriptTag))
+		return NULL;
+	_rv = GraphicsImportSaveAsPicture(ci,
+	                                  &fss,
+	                                  scriptTag);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportSetGraphicsMode(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	long graphicsMode;
+	RGBColor opColor;
+#ifndef GraphicsImportSetGraphicsMode
+	PyMac_PRECHECK(GraphicsImportSetGraphicsMode);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&lO&",
+	                      CmpObj_Convert, &ci,
+	                      &graphicsMode,
+	                      QdRGB_Convert, &opColor))
+		return NULL;
+	_rv = GraphicsImportSetGraphicsMode(ci,
+	                                    graphicsMode,
+	                                    &opColor);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportGetGraphicsMode(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	long graphicsMode;
+	RGBColor opColor;
+#ifndef GraphicsImportGetGraphicsMode
+	PyMac_PRECHECK(GraphicsImportGetGraphicsMode);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsImportGetGraphicsMode(ci,
+	                                    &graphicsMode,
+	                                    &opColor);
+	_res = Py_BuildValue("llO&",
+	                     _rv,
+	                     graphicsMode,
+	                     QdRGB_New, &opColor);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportSetQuality(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	CodecQ quality;
+#ifndef GraphicsImportSetQuality
+	PyMac_PRECHECK(GraphicsImportSetQuality);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpObj_Convert, &ci,
+	                      &quality))
+		return NULL;
+	_rv = GraphicsImportSetQuality(ci,
+	                               quality);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportGetQuality(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	CodecQ quality;
+#ifndef GraphicsImportGetQuality
+	PyMac_PRECHECK(GraphicsImportGetQuality);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsImportGetQuality(ci,
+	                               &quality);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     quality);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportSaveAsQuickTimeImageFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	FSSpec fss;
+	ScriptCode scriptTag;
+#ifndef GraphicsImportSaveAsQuickTimeImageFile
+	PyMac_PRECHECK(GraphicsImportSaveAsQuickTimeImageFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&h",
+	                      CmpObj_Convert, &ci,
+	                      PyMac_GetFSSpec, &fss,
+	                      &scriptTag))
+		return NULL;
+	_rv = GraphicsImportSaveAsQuickTimeImageFile(ci,
+	                                             &fss,
+	                                             scriptTag);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportSetDataReferenceOffsetAndLimit(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	unsigned long offset;
+	unsigned long limit;
+#ifndef GraphicsImportSetDataReferenceOffsetAndLimit
+	PyMac_PRECHECK(GraphicsImportSetDataReferenceOffsetAndLimit);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&ll",
+	                      CmpObj_Convert, &ci,
+	                      &offset,
+	                      &limit))
+		return NULL;
+	_rv = GraphicsImportSetDataReferenceOffsetAndLimit(ci,
+	                                                   offset,
+	                                                   limit);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportGetDataReferenceOffsetAndLimit(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	unsigned long offset;
+	unsigned long limit;
+#ifndef GraphicsImportGetDataReferenceOffsetAndLimit
+	PyMac_PRECHECK(GraphicsImportGetDataReferenceOffsetAndLimit);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsImportGetDataReferenceOffsetAndLimit(ci,
+	                                                   &offset,
+	                                                   &limit);
+	_res = Py_BuildValue("lll",
+	                     _rv,
+	                     offset,
+	                     limit);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportGetAliasedDataReference(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	Handle dataRef;
+	OSType dataRefType;
+#ifndef GraphicsImportGetAliasedDataReference
+	PyMac_PRECHECK(GraphicsImportGetAliasedDataReference);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsImportGetAliasedDataReference(ci,
+	                                            &dataRef,
+	                                            &dataRefType);
+	_res = Py_BuildValue("lO&O&",
+	                     _rv,
+	                     ResObj_New, dataRef,
+	                     PyMac_BuildOSType, dataRefType);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportValidate(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	Boolean valid;
+#ifndef GraphicsImportValidate
+	PyMac_PRECHECK(GraphicsImportValidate);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsImportValidate(ci,
+	                             &valid);
+	_res = Py_BuildValue("lb",
+	                     _rv,
+	                     valid);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportGetMetaData(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	void * userData;
+#ifndef GraphicsImportGetMetaData
+	PyMac_PRECHECK(GraphicsImportGetMetaData);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&s",
+	                      CmpObj_Convert, &ci,
+	                      &userData))
+		return NULL;
+	_rv = GraphicsImportGetMetaData(ci,
+	                                userData);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportGetMIMETypeList(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	void * qtAtomContainerPtr;
+#ifndef GraphicsImportGetMIMETypeList
+	PyMac_PRECHECK(GraphicsImportGetMIMETypeList);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&s",
+	                      CmpObj_Convert, &ci,
+	                      &qtAtomContainerPtr))
+		return NULL;
+	_rv = GraphicsImportGetMIMETypeList(ci,
+	                                    qtAtomContainerPtr);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportDoesDrawAllPixels(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	short drawsAllPixels;
+#ifndef GraphicsImportDoesDrawAllPixels
+	PyMac_PRECHECK(GraphicsImportDoesDrawAllPixels);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsImportDoesDrawAllPixels(ci,
+	                                      &drawsAllPixels);
+	_res = Py_BuildValue("lh",
+	                     _rv,
+	                     drawsAllPixels);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportGetAsPicture(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	PicHandle picture;
+#ifndef GraphicsImportGetAsPicture
+	PyMac_PRECHECK(GraphicsImportGetAsPicture);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsImportGetAsPicture(ci,
+	                                 &picture);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     ResObj_New, picture);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportExportImageFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	OSType fileType;
+	OSType fileCreator;
+	FSSpec fss;
+	ScriptCode scriptTag;
+#ifndef GraphicsImportExportImageFile
+	PyMac_PRECHECK(GraphicsImportExportImageFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&O&h",
+	                      CmpObj_Convert, &ci,
+	                      PyMac_GetOSType, &fileType,
+	                      PyMac_GetOSType, &fileCreator,
+	                      PyMac_GetFSSpec, &fss,
+	                      &scriptTag))
+		return NULL;
+	_rv = GraphicsImportExportImageFile(ci,
+	                                    fileType,
+	                                    fileCreator,
+	                                    &fss,
+	                                    scriptTag);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportGetExportImageTypeList(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	void * qtAtomContainerPtr;
+#ifndef GraphicsImportGetExportImageTypeList
+	PyMac_PRECHECK(GraphicsImportGetExportImageTypeList);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&s",
+	                      CmpObj_Convert, &ci,
+	                      &qtAtomContainerPtr))
+		return NULL;
+	_rv = GraphicsImportGetExportImageTypeList(ci,
+	                                           qtAtomContainerPtr);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportGetExportSettingsAsAtomContainer(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	void * qtAtomContainerPtr;
+#ifndef GraphicsImportGetExportSettingsAsAtomContainer
+	PyMac_PRECHECK(GraphicsImportGetExportSettingsAsAtomContainer);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&s",
+	                      CmpObj_Convert, &ci,
+	                      &qtAtomContainerPtr))
+		return NULL;
+	_rv = GraphicsImportGetExportSettingsAsAtomContainer(ci,
+	                                                     qtAtomContainerPtr);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportSetExportSettingsFromAtomContainer(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	void * qtAtomContainer;
+#ifndef GraphicsImportSetExportSettingsFromAtomContainer
+	PyMac_PRECHECK(GraphicsImportSetExportSettingsFromAtomContainer);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&s",
+	                      CmpObj_Convert, &ci,
+	                      &qtAtomContainer))
+		return NULL;
+	_rv = GraphicsImportSetExportSettingsFromAtomContainer(ci,
+	                                                       qtAtomContainer);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportGetImageCount(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	unsigned long imageCount;
+#ifndef GraphicsImportGetImageCount
+	PyMac_PRECHECK(GraphicsImportGetImageCount);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsImportGetImageCount(ci,
+	                                  &imageCount);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     imageCount);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportSetImageIndex(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	unsigned long imageIndex;
+#ifndef GraphicsImportSetImageIndex
+	PyMac_PRECHECK(GraphicsImportSetImageIndex);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpObj_Convert, &ci,
+	                      &imageIndex))
+		return NULL;
+	_rv = GraphicsImportSetImageIndex(ci,
+	                                  imageIndex);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportGetImageIndex(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	unsigned long imageIndex;
+#ifndef GraphicsImportGetImageIndex
+	PyMac_PRECHECK(GraphicsImportGetImageIndex);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsImportGetImageIndex(ci,
+	                                  &imageIndex);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     imageIndex);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportGetDataOffsetAndSize64(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	wide offset;
+	wide size;
+#ifndef GraphicsImportGetDataOffsetAndSize64
+	PyMac_PRECHECK(GraphicsImportGetDataOffsetAndSize64);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsImportGetDataOffsetAndSize64(ci,
+	                                           &offset,
+	                                           &size);
+	_res = Py_BuildValue("lO&O&",
+	                     _rv,
+	                     PyMac_Buildwide, offset,
+	                     PyMac_Buildwide, size);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportReadData64(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	void * dataPtr;
+	wide dataOffset;
+	unsigned long dataSize;
+#ifndef GraphicsImportReadData64
+	PyMac_PRECHECK(GraphicsImportReadData64);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&sO&l",
+	                      CmpObj_Convert, &ci,
+	                      &dataPtr,
+	                      PyMac_Getwide, &dataOffset,
+	                      &dataSize))
+		return NULL;
+	_rv = GraphicsImportReadData64(ci,
+	                               dataPtr,
+	                               &dataOffset,
+	                               dataSize);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportSetDataReferenceOffsetAndLimit64(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	wide offset;
+	wide limit;
+#ifndef GraphicsImportSetDataReferenceOffsetAndLimit64
+	PyMac_PRECHECK(GraphicsImportSetDataReferenceOffsetAndLimit64);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      CmpObj_Convert, &ci,
+	                      PyMac_Getwide, &offset,
+	                      PyMac_Getwide, &limit))
+		return NULL;
+	_rv = GraphicsImportSetDataReferenceOffsetAndLimit64(ci,
+	                                                     &offset,
+	                                                     &limit);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportGetDataReferenceOffsetAndLimit64(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	wide offset;
+	wide limit;
+#ifndef GraphicsImportGetDataReferenceOffsetAndLimit64
+	PyMac_PRECHECK(GraphicsImportGetDataReferenceOffsetAndLimit64);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsImportGetDataReferenceOffsetAndLimit64(ci,
+	                                                     &offset,
+	                                                     &limit);
+	_res = Py_BuildValue("lO&O&",
+	                     _rv,
+	                     PyMac_Buildwide, offset,
+	                     PyMac_Buildwide, limit);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportGetDefaultClip(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	RgnHandle defaultRgn;
+#ifndef GraphicsImportGetDefaultClip
+	PyMac_PRECHECK(GraphicsImportGetDefaultClip);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsImportGetDefaultClip(ci,
+	                                   &defaultRgn);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     ResObj_New, defaultRgn);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportGetDefaultGraphicsMode(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	long defaultGraphicsMode;
+	RGBColor defaultOpColor;
+#ifndef GraphicsImportGetDefaultGraphicsMode
+	PyMac_PRECHECK(GraphicsImportGetDefaultGraphicsMode);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsImportGetDefaultGraphicsMode(ci,
+	                                           &defaultGraphicsMode,
+	                                           &defaultOpColor);
+	_res = Py_BuildValue("llO&",
+	                     _rv,
+	                     defaultGraphicsMode,
+	                     QdRGB_New, &defaultOpColor);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportGetDefaultSourceRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	Rect defaultSourceRect;
+#ifndef GraphicsImportGetDefaultSourceRect
+	PyMac_PRECHECK(GraphicsImportGetDefaultSourceRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsImportGetDefaultSourceRect(ci,
+	                                         &defaultSourceRect);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     PyMac_BuildRect, &defaultSourceRect);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportGetColorSyncProfile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	Handle profile;
+#ifndef GraphicsImportGetColorSyncProfile
+	PyMac_PRECHECK(GraphicsImportGetColorSyncProfile);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsImportGetColorSyncProfile(ci,
+	                                        &profile);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     ResObj_New, profile);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportSetDestRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	Rect destRect;
+#ifndef GraphicsImportSetDestRect
+	PyMac_PRECHECK(GraphicsImportSetDestRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &ci,
+	                      PyMac_GetRect, &destRect))
+		return NULL;
+	_rv = GraphicsImportSetDestRect(ci,
+	                                &destRect);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportGetDestRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	Rect destRect;
+#ifndef GraphicsImportGetDestRect
+	PyMac_PRECHECK(GraphicsImportGetDestRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsImportGetDestRect(ci,
+	                                &destRect);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     PyMac_BuildRect, &destRect);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportSetFlags(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	long flags;
+#ifndef GraphicsImportSetFlags
+	PyMac_PRECHECK(GraphicsImportSetFlags);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpObj_Convert, &ci,
+	                      &flags))
+		return NULL;
+	_rv = GraphicsImportSetFlags(ci,
+	                             flags);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportGetFlags(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	long flags;
+#ifndef GraphicsImportGetFlags
+	PyMac_PRECHECK(GraphicsImportGetFlags);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsImportGetFlags(ci,
+	                             &flags);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     flags);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportGetBaseDataOffsetAndSize64(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+	wide offset;
+	wide size;
+#ifndef GraphicsImportGetBaseDataOffsetAndSize64
+	PyMac_PRECHECK(GraphicsImportGetBaseDataOffsetAndSize64);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsImportGetBaseDataOffsetAndSize64(ci,
+	                                               &offset,
+	                                               &size);
+	_res = Py_BuildValue("lO&O&",
+	                     _rv,
+	                     PyMac_Buildwide, offset,
+	                     PyMac_Buildwide, size);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImportSetImageIndexToThumbnail(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsImportComponent ci;
+#ifndef GraphicsImportSetImageIndexToThumbnail
+	PyMac_PRECHECK(GraphicsImportSetImageIndexToThumbnail);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsImportSetImageIndexToThumbnail(ci);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportDoExport(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	unsigned long actualSizeWritten;
+#ifndef GraphicsExportDoExport
+	PyMac_PRECHECK(GraphicsExportDoExport);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsExportDoExport(ci,
+	                             &actualSizeWritten);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     actualSizeWritten);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportCanTranscode(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	Boolean canTranscode;
+#ifndef GraphicsExportCanTranscode
+	PyMac_PRECHECK(GraphicsExportCanTranscode);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsExportCanTranscode(ci,
+	                                 &canTranscode);
+	_res = Py_BuildValue("lb",
+	                     _rv,
+	                     canTranscode);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportDoTranscode(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+#ifndef GraphicsExportDoTranscode
+	PyMac_PRECHECK(GraphicsExportDoTranscode);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsExportDoTranscode(ci);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportCanUseCompressor(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	Boolean canUseCompressor;
+	void * codecSettingsAtomContainerPtr;
+#ifndef GraphicsExportCanUseCompressor
+	PyMac_PRECHECK(GraphicsExportCanUseCompressor);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&s",
+	                      CmpObj_Convert, &ci,
+	                      &codecSettingsAtomContainerPtr))
+		return NULL;
+	_rv = GraphicsExportCanUseCompressor(ci,
+	                                     &canUseCompressor,
+	                                     codecSettingsAtomContainerPtr);
+	_res = Py_BuildValue("lb",
+	                     _rv,
+	                     canUseCompressor);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportDoUseCompressor(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	void * codecSettingsAtomContainer;
+	ImageDescriptionHandle outDesc;
+#ifndef GraphicsExportDoUseCompressor
+	PyMac_PRECHECK(GraphicsExportDoUseCompressor);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&s",
+	                      CmpObj_Convert, &ci,
+	                      &codecSettingsAtomContainer))
+		return NULL;
+	_rv = GraphicsExportDoUseCompressor(ci,
+	                                    codecSettingsAtomContainer,
+	                                    &outDesc);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     ResObj_New, outDesc);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportDoStandaloneExport(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+#ifndef GraphicsExportDoStandaloneExport
+	PyMac_PRECHECK(GraphicsExportDoStandaloneExport);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsExportDoStandaloneExport(ci);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportGetDefaultFileTypeAndCreator(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	OSType fileType;
+	OSType fileCreator;
+#ifndef GraphicsExportGetDefaultFileTypeAndCreator
+	PyMac_PRECHECK(GraphicsExportGetDefaultFileTypeAndCreator);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsExportGetDefaultFileTypeAndCreator(ci,
+	                                                 &fileType,
+	                                                 &fileCreator);
+	_res = Py_BuildValue("lO&O&",
+	                     _rv,
+	                     PyMac_BuildOSType, fileType,
+	                     PyMac_BuildOSType, fileCreator);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportGetDefaultFileNameExtension(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	OSType fileNameExtension;
+#ifndef GraphicsExportGetDefaultFileNameExtension
+	PyMac_PRECHECK(GraphicsExportGetDefaultFileNameExtension);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsExportGetDefaultFileNameExtension(ci,
+	                                                &fileNameExtension);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     PyMac_BuildOSType, fileNameExtension);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportGetMIMETypeList(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	void * qtAtomContainerPtr;
+#ifndef GraphicsExportGetMIMETypeList
+	PyMac_PRECHECK(GraphicsExportGetMIMETypeList);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&s",
+	                      CmpObj_Convert, &ci,
+	                      &qtAtomContainerPtr))
+		return NULL;
+	_rv = GraphicsExportGetMIMETypeList(ci,
+	                                    qtAtomContainerPtr);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportSetSettingsFromAtomContainer(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	void * qtAtomContainer;
+#ifndef GraphicsExportSetSettingsFromAtomContainer
+	PyMac_PRECHECK(GraphicsExportSetSettingsFromAtomContainer);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&s",
+	                      CmpObj_Convert, &ci,
+	                      &qtAtomContainer))
+		return NULL;
+	_rv = GraphicsExportSetSettingsFromAtomContainer(ci,
+	                                                 qtAtomContainer);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportGetSettingsAsAtomContainer(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	void * qtAtomContainerPtr;
+#ifndef GraphicsExportGetSettingsAsAtomContainer
+	PyMac_PRECHECK(GraphicsExportGetSettingsAsAtomContainer);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&s",
+	                      CmpObj_Convert, &ci,
+	                      &qtAtomContainerPtr))
+		return NULL;
+	_rv = GraphicsExportGetSettingsAsAtomContainer(ci,
+	                                               qtAtomContainerPtr);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportGetSettingsAsText(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	Handle theText;
+#ifndef GraphicsExportGetSettingsAsText
+	PyMac_PRECHECK(GraphicsExportGetSettingsAsText);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsExportGetSettingsAsText(ci,
+	                                      &theText);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     ResObj_New, theText);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportSetDontRecompress(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	Boolean dontRecompress;
+#ifndef GraphicsExportSetDontRecompress
+	PyMac_PRECHECK(GraphicsExportSetDontRecompress);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&b",
+	                      CmpObj_Convert, &ci,
+	                      &dontRecompress))
+		return NULL;
+	_rv = GraphicsExportSetDontRecompress(ci,
+	                                      dontRecompress);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportGetDontRecompress(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	Boolean dontRecompress;
+#ifndef GraphicsExportGetDontRecompress
+	PyMac_PRECHECK(GraphicsExportGetDontRecompress);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsExportGetDontRecompress(ci,
+	                                      &dontRecompress);
+	_res = Py_BuildValue("lb",
+	                     _rv,
+	                     dontRecompress);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportSetInterlaceStyle(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	unsigned long interlaceStyle;
+#ifndef GraphicsExportSetInterlaceStyle
+	PyMac_PRECHECK(GraphicsExportSetInterlaceStyle);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpObj_Convert, &ci,
+	                      &interlaceStyle))
+		return NULL;
+	_rv = GraphicsExportSetInterlaceStyle(ci,
+	                                      interlaceStyle);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportGetInterlaceStyle(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	unsigned long interlaceStyle;
+#ifndef GraphicsExportGetInterlaceStyle
+	PyMac_PRECHECK(GraphicsExportGetInterlaceStyle);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsExportGetInterlaceStyle(ci,
+	                                      &interlaceStyle);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     interlaceStyle);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportSetMetaData(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	void * userData;
+#ifndef GraphicsExportSetMetaData
+	PyMac_PRECHECK(GraphicsExportSetMetaData);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&s",
+	                      CmpObj_Convert, &ci,
+	                      &userData))
+		return NULL;
+	_rv = GraphicsExportSetMetaData(ci,
+	                                userData);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportGetMetaData(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	void * userData;
+#ifndef GraphicsExportGetMetaData
+	PyMac_PRECHECK(GraphicsExportGetMetaData);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&s",
+	                      CmpObj_Convert, &ci,
+	                      &userData))
+		return NULL;
+	_rv = GraphicsExportGetMetaData(ci,
+	                                userData);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportSetTargetDataSize(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	unsigned long targetDataSize;
+#ifndef GraphicsExportSetTargetDataSize
+	PyMac_PRECHECK(GraphicsExportSetTargetDataSize);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpObj_Convert, &ci,
+	                      &targetDataSize))
+		return NULL;
+	_rv = GraphicsExportSetTargetDataSize(ci,
+	                                      targetDataSize);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportGetTargetDataSize(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	unsigned long targetDataSize;
+#ifndef GraphicsExportGetTargetDataSize
+	PyMac_PRECHECK(GraphicsExportGetTargetDataSize);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsExportGetTargetDataSize(ci,
+	                                      &targetDataSize);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     targetDataSize);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportSetCompressionMethod(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	long compressionMethod;
+#ifndef GraphicsExportSetCompressionMethod
+	PyMac_PRECHECK(GraphicsExportSetCompressionMethod);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpObj_Convert, &ci,
+	                      &compressionMethod))
+		return NULL;
+	_rv = GraphicsExportSetCompressionMethod(ci,
+	                                         compressionMethod);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportGetCompressionMethod(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	long compressionMethod;
+#ifndef GraphicsExportGetCompressionMethod
+	PyMac_PRECHECK(GraphicsExportGetCompressionMethod);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsExportGetCompressionMethod(ci,
+	                                         &compressionMethod);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     compressionMethod);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportSetCompressionQuality(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	CodecQ spatialQuality;
+#ifndef GraphicsExportSetCompressionQuality
+	PyMac_PRECHECK(GraphicsExportSetCompressionQuality);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpObj_Convert, &ci,
+	                      &spatialQuality))
+		return NULL;
+	_rv = GraphicsExportSetCompressionQuality(ci,
+	                                          spatialQuality);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportGetCompressionQuality(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	CodecQ spatialQuality;
+#ifndef GraphicsExportGetCompressionQuality
+	PyMac_PRECHECK(GraphicsExportGetCompressionQuality);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsExportGetCompressionQuality(ci,
+	                                          &spatialQuality);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     spatialQuality);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportSetResolution(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	Fixed horizontalResolution;
+	Fixed verticalResolution;
+#ifndef GraphicsExportSetResolution
+	PyMac_PRECHECK(GraphicsExportSetResolution);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      CmpObj_Convert, &ci,
+	                      PyMac_GetFixed, &horizontalResolution,
+	                      PyMac_GetFixed, &verticalResolution))
+		return NULL;
+	_rv = GraphicsExportSetResolution(ci,
+	                                  horizontalResolution,
+	                                  verticalResolution);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportGetResolution(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	Fixed horizontalResolution;
+	Fixed verticalResolution;
+#ifndef GraphicsExportGetResolution
+	PyMac_PRECHECK(GraphicsExportGetResolution);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsExportGetResolution(ci,
+	                                  &horizontalResolution,
+	                                  &verticalResolution);
+	_res = Py_BuildValue("lO&O&",
+	                     _rv,
+	                     PyMac_BuildFixed, horizontalResolution,
+	                     PyMac_BuildFixed, verticalResolution);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportSetDepth(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	long depth;
+#ifndef GraphicsExportSetDepth
+	PyMac_PRECHECK(GraphicsExportSetDepth);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpObj_Convert, &ci,
+	                      &depth))
+		return NULL;
+	_rv = GraphicsExportSetDepth(ci,
+	                             depth);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportGetDepth(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	long depth;
+#ifndef GraphicsExportGetDepth
+	PyMac_PRECHECK(GraphicsExportGetDepth);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsExportGetDepth(ci,
+	                             &depth);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     depth);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportSetColorSyncProfile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	Handle colorSyncProfile;
+#ifndef GraphicsExportSetColorSyncProfile
+	PyMac_PRECHECK(GraphicsExportSetColorSyncProfile);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &ci,
+	                      ResObj_Convert, &colorSyncProfile))
+		return NULL;
+	_rv = GraphicsExportSetColorSyncProfile(ci,
+	                                        colorSyncProfile);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportGetColorSyncProfile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	Handle colorSyncProfile;
+#ifndef GraphicsExportGetColorSyncProfile
+	PyMac_PRECHECK(GraphicsExportGetColorSyncProfile);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsExportGetColorSyncProfile(ci,
+	                                        &colorSyncProfile);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     ResObj_New, colorSyncProfile);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportSetInputDataReference(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	Handle dataRef;
+	OSType dataRefType;
+	ImageDescriptionHandle desc;
+#ifndef GraphicsExportSetInputDataReference
+	PyMac_PRECHECK(GraphicsExportSetInputDataReference);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&O&",
+	                      CmpObj_Convert, &ci,
+	                      ResObj_Convert, &dataRef,
+	                      PyMac_GetOSType, &dataRefType,
+	                      ResObj_Convert, &desc))
+		return NULL;
+	_rv = GraphicsExportSetInputDataReference(ci,
+	                                          dataRef,
+	                                          dataRefType,
+	                                          desc);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportGetInputDataReference(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	Handle dataRef;
+	OSType dataRefType;
+#ifndef GraphicsExportGetInputDataReference
+	PyMac_PRECHECK(GraphicsExportGetInputDataReference);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsExportGetInputDataReference(ci,
+	                                          &dataRef,
+	                                          &dataRefType);
+	_res = Py_BuildValue("lO&O&",
+	                     _rv,
+	                     ResObj_New, dataRef,
+	                     PyMac_BuildOSType, dataRefType);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportSetInputFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	FSSpec theFile;
+	ImageDescriptionHandle desc;
+#ifndef GraphicsExportSetInputFile
+	PyMac_PRECHECK(GraphicsExportSetInputFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      CmpObj_Convert, &ci,
+	                      PyMac_GetFSSpec, &theFile,
+	                      ResObj_Convert, &desc))
+		return NULL;
+	_rv = GraphicsExportSetInputFile(ci,
+	                                 &theFile,
+	                                 desc);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportGetInputFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	FSSpec theFile;
+#ifndef GraphicsExportGetInputFile
+	PyMac_PRECHECK(GraphicsExportGetInputFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &ci,
+	                      PyMac_GetFSSpec, &theFile))
+		return NULL;
+	_rv = GraphicsExportGetInputFile(ci,
+	                                 &theFile);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportSetInputHandle(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	Handle h;
+	ImageDescriptionHandle desc;
+#ifndef GraphicsExportSetInputHandle
+	PyMac_PRECHECK(GraphicsExportSetInputHandle);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      CmpObj_Convert, &ci,
+	                      ResObj_Convert, &h,
+	                      ResObj_Convert, &desc))
+		return NULL;
+	_rv = GraphicsExportSetInputHandle(ci,
+	                                   h,
+	                                   desc);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportGetInputHandle(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	Handle h;
+#ifndef GraphicsExportGetInputHandle
+	PyMac_PRECHECK(GraphicsExportGetInputHandle);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsExportGetInputHandle(ci,
+	                                   &h);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     ResObj_New, h);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportSetInputPtr(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	Ptr p;
+	unsigned long size;
+	ImageDescriptionHandle desc;
+#ifndef GraphicsExportSetInputPtr
+	PyMac_PRECHECK(GraphicsExportSetInputPtr);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&slO&",
+	                      CmpObj_Convert, &ci,
+	                      &p,
+	                      &size,
+	                      ResObj_Convert, &desc))
+		return NULL;
+	_rv = GraphicsExportSetInputPtr(ci,
+	                                p,
+	                                size,
+	                                desc);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportSetInputGraphicsImporter(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	GraphicsImportComponent grip;
+#ifndef GraphicsExportSetInputGraphicsImporter
+	PyMac_PRECHECK(GraphicsExportSetInputGraphicsImporter);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &ci,
+	                      CmpObj_Convert, &grip))
+		return NULL;
+	_rv = GraphicsExportSetInputGraphicsImporter(ci,
+	                                             grip);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportGetInputGraphicsImporter(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	GraphicsImportComponent grip;
+#ifndef GraphicsExportGetInputGraphicsImporter
+	PyMac_PRECHECK(GraphicsExportGetInputGraphicsImporter);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsExportGetInputGraphicsImporter(ci,
+	                                             &grip);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     CmpObj_New, grip);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportSetInputPicture(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	PicHandle picture;
+#ifndef GraphicsExportSetInputPicture
+	PyMac_PRECHECK(GraphicsExportSetInputPicture);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &ci,
+	                      ResObj_Convert, &picture))
+		return NULL;
+	_rv = GraphicsExportSetInputPicture(ci,
+	                                    picture);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportGetInputPicture(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	PicHandle picture;
+#ifndef GraphicsExportGetInputPicture
+	PyMac_PRECHECK(GraphicsExportGetInputPicture);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsExportGetInputPicture(ci,
+	                                    &picture);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     ResObj_New, picture);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportSetInputGWorld(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	GWorldPtr gworld;
+#ifndef GraphicsExportSetInputGWorld
+	PyMac_PRECHECK(GraphicsExportSetInputGWorld);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &ci,
+	                      GWorldObj_Convert, &gworld))
+		return NULL;
+	_rv = GraphicsExportSetInputGWorld(ci,
+	                                   gworld);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportGetInputGWorld(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	GWorldPtr gworld;
+#ifndef GraphicsExportGetInputGWorld
+	PyMac_PRECHECK(GraphicsExportGetInputGWorld);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsExportGetInputGWorld(ci,
+	                                   &gworld);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     GWorldObj_New, gworld);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportSetInputPixmap(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	PixMapHandle pixmap;
+#ifndef GraphicsExportSetInputPixmap
+	PyMac_PRECHECK(GraphicsExportSetInputPixmap);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &ci,
+	                      ResObj_Convert, &pixmap))
+		return NULL;
+	_rv = GraphicsExportSetInputPixmap(ci,
+	                                   pixmap);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportGetInputPixmap(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	PixMapHandle pixmap;
+#ifndef GraphicsExportGetInputPixmap
+	PyMac_PRECHECK(GraphicsExportGetInputPixmap);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsExportGetInputPixmap(ci,
+	                                   &pixmap);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     ResObj_New, pixmap);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportSetInputOffsetAndLimit(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	unsigned long offset;
+	unsigned long limit;
+#ifndef GraphicsExportSetInputOffsetAndLimit
+	PyMac_PRECHECK(GraphicsExportSetInputOffsetAndLimit);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&ll",
+	                      CmpObj_Convert, &ci,
+	                      &offset,
+	                      &limit))
+		return NULL;
+	_rv = GraphicsExportSetInputOffsetAndLimit(ci,
+	                                           offset,
+	                                           limit);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportGetInputOffsetAndLimit(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	unsigned long offset;
+	unsigned long limit;
+#ifndef GraphicsExportGetInputOffsetAndLimit
+	PyMac_PRECHECK(GraphicsExportGetInputOffsetAndLimit);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsExportGetInputOffsetAndLimit(ci,
+	                                           &offset,
+	                                           &limit);
+	_res = Py_BuildValue("lll",
+	                     _rv,
+	                     offset,
+	                     limit);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportMayExporterReadInputData(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	Boolean mayReadInputData;
+#ifndef GraphicsExportMayExporterReadInputData
+	PyMac_PRECHECK(GraphicsExportMayExporterReadInputData);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsExportMayExporterReadInputData(ci,
+	                                             &mayReadInputData);
+	_res = Py_BuildValue("lb",
+	                     _rv,
+	                     mayReadInputData);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportGetInputDataSize(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	unsigned long size;
+#ifndef GraphicsExportGetInputDataSize
+	PyMac_PRECHECK(GraphicsExportGetInputDataSize);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsExportGetInputDataSize(ci,
+	                                     &size);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     size);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportReadInputData(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	void * dataPtr;
+	unsigned long dataOffset;
+	unsigned long dataSize;
+#ifndef GraphicsExportReadInputData
+	PyMac_PRECHECK(GraphicsExportReadInputData);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&sll",
+	                      CmpObj_Convert, &ci,
+	                      &dataPtr,
+	                      &dataOffset,
+	                      &dataSize))
+		return NULL;
+	_rv = GraphicsExportReadInputData(ci,
+	                                  dataPtr,
+	                                  dataOffset,
+	                                  dataSize);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportGetInputImageDescription(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	ImageDescriptionHandle desc;
+#ifndef GraphicsExportGetInputImageDescription
+	PyMac_PRECHECK(GraphicsExportGetInputImageDescription);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsExportGetInputImageDescription(ci,
+	                                             &desc);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     ResObj_New, desc);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportGetInputImageDimensions(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	Rect dimensions;
+#ifndef GraphicsExportGetInputImageDimensions
+	PyMac_PRECHECK(GraphicsExportGetInputImageDimensions);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsExportGetInputImageDimensions(ci,
+	                                            &dimensions);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     PyMac_BuildRect, &dimensions);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportGetInputImageDepth(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	long inputDepth;
+#ifndef GraphicsExportGetInputImageDepth
+	PyMac_PRECHECK(GraphicsExportGetInputImageDepth);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsExportGetInputImageDepth(ci,
+	                                       &inputDepth);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     inputDepth);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportDrawInputImage(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	CGrafPtr gw;
+	GDHandle gd;
+	Rect srcRect;
+	Rect dstRect;
+#ifndef GraphicsExportDrawInputImage
+	PyMac_PRECHECK(GraphicsExportDrawInputImage);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&O&O&",
+	                      CmpObj_Convert, &ci,
+	                      GrafObj_Convert, &gw,
+	                      OptResObj_Convert, &gd,
+	                      PyMac_GetRect, &srcRect,
+	                      PyMac_GetRect, &dstRect))
+		return NULL;
+	_rv = GraphicsExportDrawInputImage(ci,
+	                                   gw,
+	                                   gd,
+	                                   &srcRect,
+	                                   &dstRect);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportSetOutputDataReference(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	Handle dataRef;
+	OSType dataRefType;
+#ifndef GraphicsExportSetOutputDataReference
+	PyMac_PRECHECK(GraphicsExportSetOutputDataReference);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      CmpObj_Convert, &ci,
+	                      ResObj_Convert, &dataRef,
+	                      PyMac_GetOSType, &dataRefType))
+		return NULL;
+	_rv = GraphicsExportSetOutputDataReference(ci,
+	                                           dataRef,
+	                                           dataRefType);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportGetOutputDataReference(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	Handle dataRef;
+	OSType dataRefType;
+#ifndef GraphicsExportGetOutputDataReference
+	PyMac_PRECHECK(GraphicsExportGetOutputDataReference);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsExportGetOutputDataReference(ci,
+	                                           &dataRef,
+	                                           &dataRefType);
+	_res = Py_BuildValue("lO&O&",
+	                     _rv,
+	                     ResObj_New, dataRef,
+	                     PyMac_BuildOSType, dataRefType);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportSetOutputFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	FSSpec theFile;
+#ifndef GraphicsExportSetOutputFile
+	PyMac_PRECHECK(GraphicsExportSetOutputFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &ci,
+	                      PyMac_GetFSSpec, &theFile))
+		return NULL;
+	_rv = GraphicsExportSetOutputFile(ci,
+	                                  &theFile);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportGetOutputFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	FSSpec theFile;
+#ifndef GraphicsExportGetOutputFile
+	PyMac_PRECHECK(GraphicsExportGetOutputFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &ci,
+	                      PyMac_GetFSSpec, &theFile))
+		return NULL;
+	_rv = GraphicsExportGetOutputFile(ci,
+	                                  &theFile);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportSetOutputHandle(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	Handle h;
+#ifndef GraphicsExportSetOutputHandle
+	PyMac_PRECHECK(GraphicsExportSetOutputHandle);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &ci,
+	                      ResObj_Convert, &h))
+		return NULL;
+	_rv = GraphicsExportSetOutputHandle(ci,
+	                                    h);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportGetOutputHandle(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	Handle h;
+#ifndef GraphicsExportGetOutputHandle
+	PyMac_PRECHECK(GraphicsExportGetOutputHandle);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsExportGetOutputHandle(ci,
+	                                    &h);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     ResObj_New, h);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportSetOutputOffsetAndMaxSize(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	unsigned long offset;
+	unsigned long maxSize;
+	Boolean truncateFile;
+#ifndef GraphicsExportSetOutputOffsetAndMaxSize
+	PyMac_PRECHECK(GraphicsExportSetOutputOffsetAndMaxSize);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&llb",
+	                      CmpObj_Convert, &ci,
+	                      &offset,
+	                      &maxSize,
+	                      &truncateFile))
+		return NULL;
+	_rv = GraphicsExportSetOutputOffsetAndMaxSize(ci,
+	                                              offset,
+	                                              maxSize,
+	                                              truncateFile);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportGetOutputOffsetAndMaxSize(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	unsigned long offset;
+	unsigned long maxSize;
+	Boolean truncateFile;
+#ifndef GraphicsExportGetOutputOffsetAndMaxSize
+	PyMac_PRECHECK(GraphicsExportGetOutputOffsetAndMaxSize);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsExportGetOutputOffsetAndMaxSize(ci,
+	                                              &offset,
+	                                              &maxSize,
+	                                              &truncateFile);
+	_res = Py_BuildValue("lllb",
+	                     _rv,
+	                     offset,
+	                     maxSize,
+	                     truncateFile);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportSetOutputFileTypeAndCreator(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	OSType fileType;
+	OSType fileCreator;
+#ifndef GraphicsExportSetOutputFileTypeAndCreator
+	PyMac_PRECHECK(GraphicsExportSetOutputFileTypeAndCreator);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      CmpObj_Convert, &ci,
+	                      PyMac_GetOSType, &fileType,
+	                      PyMac_GetOSType, &fileCreator))
+		return NULL;
+	_rv = GraphicsExportSetOutputFileTypeAndCreator(ci,
+	                                                fileType,
+	                                                fileCreator);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportGetOutputFileTypeAndCreator(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	OSType fileType;
+	OSType fileCreator;
+#ifndef GraphicsExportGetOutputFileTypeAndCreator
+	PyMac_PRECHECK(GraphicsExportGetOutputFileTypeAndCreator);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsExportGetOutputFileTypeAndCreator(ci,
+	                                                &fileType,
+	                                                &fileCreator);
+	_res = Py_BuildValue("lO&O&",
+	                     _rv,
+	                     PyMac_BuildOSType, fileType,
+	                     PyMac_BuildOSType, fileCreator);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportSetOutputMark(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	unsigned long mark;
+#ifndef GraphicsExportSetOutputMark
+	PyMac_PRECHECK(GraphicsExportSetOutputMark);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpObj_Convert, &ci,
+	                      &mark))
+		return NULL;
+	_rv = GraphicsExportSetOutputMark(ci,
+	                                  mark);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportGetOutputMark(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	unsigned long mark;
+#ifndef GraphicsExportGetOutputMark
+	PyMac_PRECHECK(GraphicsExportGetOutputMark);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsExportGetOutputMark(ci,
+	                                  &mark);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     mark);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportReadOutputData(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	void * dataPtr;
+	unsigned long dataOffset;
+	unsigned long dataSize;
+#ifndef GraphicsExportReadOutputData
+	PyMac_PRECHECK(GraphicsExportReadOutputData);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&sll",
+	                      CmpObj_Convert, &ci,
+	                      &dataPtr,
+	                      &dataOffset,
+	                      &dataSize))
+		return NULL;
+	_rv = GraphicsExportReadOutputData(ci,
+	                                   dataPtr,
+	                                   dataOffset,
+	                                   dataSize);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportSetThumbnailEnabled(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	Boolean enableThumbnail;
+	long maxThumbnailWidth;
+	long maxThumbnailHeight;
+#ifndef GraphicsExportSetThumbnailEnabled
+	PyMac_PRECHECK(GraphicsExportSetThumbnailEnabled);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&bll",
+	                      CmpObj_Convert, &ci,
+	                      &enableThumbnail,
+	                      &maxThumbnailWidth,
+	                      &maxThumbnailHeight))
+		return NULL;
+	_rv = GraphicsExportSetThumbnailEnabled(ci,
+	                                        enableThumbnail,
+	                                        maxThumbnailWidth,
+	                                        maxThumbnailHeight);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportGetThumbnailEnabled(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	Boolean thumbnailEnabled;
+	long maxThumbnailWidth;
+	long maxThumbnailHeight;
+#ifndef GraphicsExportGetThumbnailEnabled
+	PyMac_PRECHECK(GraphicsExportGetThumbnailEnabled);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsExportGetThumbnailEnabled(ci,
+	                                        &thumbnailEnabled,
+	                                        &maxThumbnailWidth,
+	                                        &maxThumbnailHeight);
+	_res = Py_BuildValue("lbll",
+	                     _rv,
+	                     thumbnailEnabled,
+	                     maxThumbnailWidth,
+	                     maxThumbnailHeight);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportSetExifEnabled(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	Boolean enableExif;
+#ifndef GraphicsExportSetExifEnabled
+	PyMac_PRECHECK(GraphicsExportSetExifEnabled);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&b",
+	                      CmpObj_Convert, &ci,
+	                      &enableExif))
+		return NULL;
+	_rv = GraphicsExportSetExifEnabled(ci,
+	                                   enableExif);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsExportGetExifEnabled(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicsExportComponent ci;
+	Boolean exifEnabled;
+#ifndef GraphicsExportGetExifEnabled
+	PyMac_PRECHECK(GraphicsExportGetExifEnabled);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsExportGetExifEnabled(ci,
+	                                   &exifEnabled);
+	_res = Py_BuildValue("lb",
+	                     _rv,
+	                     exifEnabled);
+	return _res;
+}
+
+static PyObject *Qt_ImageTranscoderBeginSequence(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	ImageTranscoderComponent itc;
+	ImageDescriptionHandle srcDesc;
+	ImageDescriptionHandle dstDesc;
+	void * data;
+	long dataSize;
+#ifndef ImageTranscoderBeginSequence
+	PyMac_PRECHECK(ImageTranscoderBeginSequence);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&sl",
+	                      CmpObj_Convert, &itc,
+	                      ResObj_Convert, &srcDesc,
+	                      &data,
+	                      &dataSize))
+		return NULL;
+	_rv = ImageTranscoderBeginSequence(itc,
+	                                   srcDesc,
+	                                   &dstDesc,
+	                                   data,
+	                                   dataSize);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     ResObj_New, dstDesc);
+	return _res;
+}
+
+static PyObject *Qt_ImageTranscoderDisposeData(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	ImageTranscoderComponent itc;
+	void * dstData;
+#ifndef ImageTranscoderDisposeData
+	PyMac_PRECHECK(ImageTranscoderDisposeData);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&s",
+	                      CmpObj_Convert, &itc,
+	                      &dstData))
+		return NULL;
+	_rv = ImageTranscoderDisposeData(itc,
+	                                 dstData);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_ImageTranscoderEndSequence(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	ImageTranscoderComponent itc;
+#ifndef ImageTranscoderEndSequence
+	PyMac_PRECHECK(ImageTranscoderEndSequence);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &itc))
+		return NULL;
+	_rv = ImageTranscoderEndSequence(itc);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_ClockGetTime(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	ComponentInstance aClock;
+	TimeRecord out;
+#ifndef ClockGetTime
+	PyMac_PRECHECK(ClockGetTime);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &aClock))
+		return NULL;
+	_rv = ClockGetTime(aClock,
+	                   &out);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     QtTimeRecord_New, &out);
+	return _res;
+}
+
+static PyObject *Qt_ClockSetTimeBase(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	ComponentInstance aClock;
+	TimeBase tb;
+#ifndef ClockSetTimeBase
+	PyMac_PRECHECK(ClockSetTimeBase);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpInstObj_Convert, &aClock,
+	                      TimeBaseObj_Convert, &tb))
+		return NULL;
+	_rv = ClockSetTimeBase(aClock,
+	                       tb);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_ClockGetRate(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	ComponentInstance aClock;
+	Fixed rate;
+#ifndef ClockGetRate
+	PyMac_PRECHECK(ClockGetRate);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &aClock))
+		return NULL;
+	_rv = ClockGetRate(aClock,
+	                   &rate);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     PyMac_BuildFixed, rate);
+	return _res;
+}
+
+static PyObject *Qt_SCPositionRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	ComponentInstance ci;
+	Rect rp;
+	Point where;
+#ifndef SCPositionRect
+	PyMac_PRECHECK(SCPositionRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &ci))
+		return NULL;
+	_rv = SCPositionRect(ci,
+	                     &rp,
+	                     &where);
+	_res = Py_BuildValue("lO&O&",
+	                     _rv,
+	                     PyMac_BuildRect, &rp,
+	                     PyMac_BuildPoint, where);
+	return _res;
+}
+
+static PyObject *Qt_SCPositionDialog(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	ComponentInstance ci;
+	short id;
+	Point where;
+#ifndef SCPositionDialog
+	PyMac_PRECHECK(SCPositionDialog);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      CmpInstObj_Convert, &ci,
+	                      &id))
+		return NULL;
+	_rv = SCPositionDialog(ci,
+	                       id,
+	                       &where);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     PyMac_BuildPoint, where);
+	return _res;
+}
+
+static PyObject *Qt_SCSetTestImagePictHandle(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	ComponentInstance ci;
+	PicHandle testPict;
+	Rect testRect;
+	short testFlags;
+#ifndef SCSetTestImagePictHandle
+	PyMac_PRECHECK(SCSetTestImagePictHandle);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&h",
+	                      CmpInstObj_Convert, &ci,
+	                      ResObj_Convert, &testPict,
+	                      &testFlags))
+		return NULL;
+	_rv = SCSetTestImagePictHandle(ci,
+	                               testPict,
+	                               &testRect,
+	                               testFlags);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     PyMac_BuildRect, &testRect);
+	return _res;
+}
+
+static PyObject *Qt_SCSetTestImagePictFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	ComponentInstance ci;
+	short testFileRef;
+	Rect testRect;
+	short testFlags;
+#ifndef SCSetTestImagePictFile
+	PyMac_PRECHECK(SCSetTestImagePictFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hh",
+	                      CmpInstObj_Convert, &ci,
+	                      &testFileRef,
+	                      &testFlags))
+		return NULL;
+	_rv = SCSetTestImagePictFile(ci,
+	                             testFileRef,
+	                             &testRect,
+	                             testFlags);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     PyMac_BuildRect, &testRect);
+	return _res;
+}
+
+static PyObject *Qt_SCSetTestImagePixMap(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	ComponentInstance ci;
+	PixMapHandle testPixMap;
+	Rect testRect;
+	short testFlags;
+#ifndef SCSetTestImagePixMap
+	PyMac_PRECHECK(SCSetTestImagePixMap);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&h",
+	                      CmpInstObj_Convert, &ci,
+	                      ResObj_Convert, &testPixMap,
+	                      &testFlags))
+		return NULL;
+	_rv = SCSetTestImagePixMap(ci,
+	                           testPixMap,
+	                           &testRect,
+	                           testFlags);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     PyMac_BuildRect, &testRect);
+	return _res;
+}
+
+static PyObject *Qt_SCGetBestDeviceRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	ComponentInstance ci;
+	Rect r;
+#ifndef SCGetBestDeviceRect
+	PyMac_PRECHECK(SCGetBestDeviceRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &ci))
+		return NULL;
+	_rv = SCGetBestDeviceRect(ci,
+	                          &r);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     PyMac_BuildRect, &r);
+	return _res;
+}
+
+static PyObject *Qt_SCRequestImageSettings(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	ComponentInstance ci;
+#ifndef SCRequestImageSettings
+	PyMac_PRECHECK(SCRequestImageSettings);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &ci))
+		return NULL;
+	_rv = SCRequestImageSettings(ci);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SCCompressImage(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	ComponentInstance ci;
+	PixMapHandle src;
+	Rect srcRect;
+	ImageDescriptionHandle desc;
+	Handle data;
+#ifndef SCCompressImage
+	PyMac_PRECHECK(SCCompressImage);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      CmpInstObj_Convert, &ci,
+	                      ResObj_Convert, &src,
+	                      PyMac_GetRect, &srcRect))
+		return NULL;
+	_rv = SCCompressImage(ci,
+	                      src,
+	                      &srcRect,
+	                      &desc,
+	                      &data);
+	_res = Py_BuildValue("lO&O&",
+	                     _rv,
+	                     ResObj_New, desc,
+	                     ResObj_New, data);
+	return _res;
+}
+
+static PyObject *Qt_SCCompressPicture(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	ComponentInstance ci;
+	PicHandle srcPicture;
+	PicHandle dstPicture;
+#ifndef SCCompressPicture
+	PyMac_PRECHECK(SCCompressPicture);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      CmpInstObj_Convert, &ci,
+	                      ResObj_Convert, &srcPicture,
+	                      ResObj_Convert, &dstPicture))
+		return NULL;
+	_rv = SCCompressPicture(ci,
+	                        srcPicture,
+	                        dstPicture);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SCCompressPictureFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	ComponentInstance ci;
+	short srcRefNum;
+	short dstRefNum;
+#ifndef SCCompressPictureFile
+	PyMac_PRECHECK(SCCompressPictureFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hh",
+	                      CmpInstObj_Convert, &ci,
+	                      &srcRefNum,
+	                      &dstRefNum))
+		return NULL;
+	_rv = SCCompressPictureFile(ci,
+	                            srcRefNum,
+	                            dstRefNum);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SCRequestSequenceSettings(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	ComponentInstance ci;
+#ifndef SCRequestSequenceSettings
+	PyMac_PRECHECK(SCRequestSequenceSettings);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &ci))
+		return NULL;
+	_rv = SCRequestSequenceSettings(ci);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SCCompressSequenceBegin(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	ComponentInstance ci;
+	PixMapHandle src;
+	Rect srcRect;
+	ImageDescriptionHandle desc;
+#ifndef SCCompressSequenceBegin
+	PyMac_PRECHECK(SCCompressSequenceBegin);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      CmpInstObj_Convert, &ci,
+	                      ResObj_Convert, &src,
+	                      PyMac_GetRect, &srcRect))
+		return NULL;
+	_rv = SCCompressSequenceBegin(ci,
+	                              src,
+	                              &srcRect,
+	                              &desc);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     ResObj_New, desc);
+	return _res;
+}
+
+static PyObject *Qt_SCCompressSequenceFrame(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	ComponentInstance ci;
+	PixMapHandle src;
+	Rect srcRect;
+	Handle data;
+	long dataSize;
+	short notSyncFlag;
+#ifndef SCCompressSequenceFrame
+	PyMac_PRECHECK(SCCompressSequenceFrame);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      CmpInstObj_Convert, &ci,
+	                      ResObj_Convert, &src,
+	                      PyMac_GetRect, &srcRect))
+		return NULL;
+	_rv = SCCompressSequenceFrame(ci,
+	                              src,
+	                              &srcRect,
+	                              &data,
+	                              &dataSize,
+	                              &notSyncFlag);
+	_res = Py_BuildValue("lO&lh",
+	                     _rv,
+	                     ResObj_New, data,
+	                     dataSize,
+	                     notSyncFlag);
+	return _res;
+}
+
+static PyObject *Qt_SCCompressSequenceEnd(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	ComponentInstance ci;
+#ifndef SCCompressSequenceEnd
+	PyMac_PRECHECK(SCCompressSequenceEnd);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &ci))
+		return NULL;
+	_rv = SCCompressSequenceEnd(ci);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SCDefaultPictHandleSettings(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	ComponentInstance ci;
+	PicHandle srcPicture;
+	short motion;
+#ifndef SCDefaultPictHandleSettings
+	PyMac_PRECHECK(SCDefaultPictHandleSettings);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&h",
+	                      CmpInstObj_Convert, &ci,
+	                      ResObj_Convert, &srcPicture,
+	                      &motion))
+		return NULL;
+	_rv = SCDefaultPictHandleSettings(ci,
+	                                  srcPicture,
+	                                  motion);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SCDefaultPictFileSettings(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	ComponentInstance ci;
+	short srcRef;
+	short motion;
+#ifndef SCDefaultPictFileSettings
+	PyMac_PRECHECK(SCDefaultPictFileSettings);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hh",
+	                      CmpInstObj_Convert, &ci,
+	                      &srcRef,
+	                      &motion))
+		return NULL;
+	_rv = SCDefaultPictFileSettings(ci,
+	                                srcRef,
+	                                motion);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SCDefaultPixMapSettings(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	ComponentInstance ci;
+	PixMapHandle src;
+	short motion;
+#ifndef SCDefaultPixMapSettings
+	PyMac_PRECHECK(SCDefaultPixMapSettings);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&h",
+	                      CmpInstObj_Convert, &ci,
+	                      ResObj_Convert, &src,
+	                      &motion))
+		return NULL;
+	_rv = SCDefaultPixMapSettings(ci,
+	                              src,
+	                              motion);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SCGetInfo(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	ComponentInstance ci;
+	OSType infoType;
+	void * info;
+#ifndef SCGetInfo
+	PyMac_PRECHECK(SCGetInfo);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&s",
+	                      CmpInstObj_Convert, &ci,
+	                      PyMac_GetOSType, &infoType,
+	                      &info))
+		return NULL;
+	_rv = SCGetInfo(ci,
+	                infoType,
+	                info);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SCSetInfo(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	ComponentInstance ci;
+	OSType infoType;
+	void * info;
+#ifndef SCSetInfo
+	PyMac_PRECHECK(SCSetInfo);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&s",
+	                      CmpInstObj_Convert, &ci,
+	                      PyMac_GetOSType, &infoType,
+	                      &info))
+		return NULL;
+	_rv = SCSetInfo(ci,
+	                infoType,
+	                info);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SCSetCompressFlags(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	ComponentInstance ci;
+	long flags;
+#ifndef SCSetCompressFlags
+	PyMac_PRECHECK(SCSetCompressFlags);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &ci,
+	                      &flags))
+		return NULL;
+	_rv = SCSetCompressFlags(ci,
+	                         flags);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SCGetCompressFlags(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	ComponentInstance ci;
+	long flags;
+#ifndef SCGetCompressFlags
+	PyMac_PRECHECK(SCGetCompressFlags);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &ci))
+		return NULL;
+	_rv = SCGetCompressFlags(ci,
+	                         &flags);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     flags);
+	return _res;
+}
+
+static PyObject *Qt_SCGetSettingsAsText(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	ComponentInstance ci;
+	Handle text;
+#ifndef SCGetSettingsAsText
+	PyMac_PRECHECK(SCGetSettingsAsText);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &ci))
+		return NULL;
+	_rv = SCGetSettingsAsText(ci,
+	                          &text);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     ResObj_New, text);
+	return _res;
+}
+
+static PyObject *Qt_SCAsyncIdle(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	ComponentInstance ci;
+#ifndef SCAsyncIdle
+	PyMac_PRECHECK(SCAsyncIdle);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &ci))
+		return NULL;
+	_rv = SCAsyncIdle(ci);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_TweenerReset(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	TweenerComponent tc;
+#ifndef TweenerReset
+	PyMac_PRECHECK(TweenerReset);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &tc))
+		return NULL;
+	_rv = TweenerReset(tc);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_TCGetSourceRef(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	HandlerError _rv;
+	MediaHandler mh;
+	TimeCodeDescriptionHandle tcdH;
+	UserData srefH;
+#ifndef TCGetSourceRef
+	PyMac_PRECHECK(TCGetSourceRef);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpInstObj_Convert, &mh,
+	                      ResObj_Convert, &tcdH))
+		return NULL;
+	_rv = TCGetSourceRef(mh,
+	                     tcdH,
+	                     &srefH);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     UserDataObj_New, srefH);
+	return _res;
+}
+
+static PyObject *Qt_TCSetSourceRef(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	HandlerError _rv;
+	MediaHandler mh;
+	TimeCodeDescriptionHandle tcdH;
+	UserData srefH;
+#ifndef TCSetSourceRef
+	PyMac_PRECHECK(TCSetSourceRef);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      CmpInstObj_Convert, &mh,
+	                      ResObj_Convert, &tcdH,
+	                      UserDataObj_Convert, &srefH))
+		return NULL;
+	_rv = TCSetSourceRef(mh,
+	                     tcdH,
+	                     srefH);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_TCSetTimeCodeFlags(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	HandlerError _rv;
+	MediaHandler mh;
+	long flags;
+	long flagsMask;
+#ifndef TCSetTimeCodeFlags
+	PyMac_PRECHECK(TCSetTimeCodeFlags);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&ll",
+	                      CmpInstObj_Convert, &mh,
+	                      &flags,
+	                      &flagsMask))
+		return NULL;
+	_rv = TCSetTimeCodeFlags(mh,
+	                         flags,
+	                         flagsMask);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_TCGetTimeCodeFlags(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	HandlerError _rv;
+	MediaHandler mh;
+	long flags;
+#ifndef TCGetTimeCodeFlags
+	PyMac_PRECHECK(TCGetTimeCodeFlags);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &mh))
+		return NULL;
+	_rv = TCGetTimeCodeFlags(mh,
+	                         &flags);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     flags);
+	return _res;
+}
+
+static PyObject *Qt_MovieImportHandle(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MovieImportComponent ci;
+	Handle dataH;
+	Movie theMovie;
+	Track targetTrack;
+	Track usedTrack;
+	TimeValue atTime;
+	TimeValue addedDuration;
+	long inFlags;
+	long outFlags;
+#ifndef MovieImportHandle
+	PyMac_PRECHECK(MovieImportHandle);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&O&ll",
+	                      CmpObj_Convert, &ci,
+	                      ResObj_Convert, &dataH,
+	                      MovieObj_Convert, &theMovie,
+	                      TrackObj_Convert, &targetTrack,
+	                      &atTime,
+	                      &inFlags))
+		return NULL;
+	_rv = MovieImportHandle(ci,
+	                        dataH,
+	                        theMovie,
+	                        targetTrack,
+	                        &usedTrack,
+	                        atTime,
+	                        &addedDuration,
+	                        inFlags,
+	                        &outFlags);
+	_res = Py_BuildValue("lO&ll",
+	                     _rv,
+	                     TrackObj_New, usedTrack,
+	                     addedDuration,
+	                     outFlags);
+	return _res;
+}
+
+static PyObject *Qt_MovieImportFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MovieImportComponent ci;
+	FSSpec theFile;
+	Movie theMovie;
+	Track targetTrack;
+	Track usedTrack;
+	TimeValue atTime;
+	TimeValue addedDuration;
+	long inFlags;
+	long outFlags;
+#ifndef MovieImportFile
+	PyMac_PRECHECK(MovieImportFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&O&ll",
+	                      CmpObj_Convert, &ci,
+	                      PyMac_GetFSSpec, &theFile,
+	                      MovieObj_Convert, &theMovie,
+	                      TrackObj_Convert, &targetTrack,
+	                      &atTime,
+	                      &inFlags))
+		return NULL;
+	_rv = MovieImportFile(ci,
+	                      &theFile,
+	                      theMovie,
+	                      targetTrack,
+	                      &usedTrack,
+	                      atTime,
+	                      &addedDuration,
+	                      inFlags,
+	                      &outFlags);
+	_res = Py_BuildValue("lO&ll",
+	                     _rv,
+	                     TrackObj_New, usedTrack,
+	                     addedDuration,
+	                     outFlags);
+	return _res;
+}
+
+static PyObject *Qt_MovieImportSetSampleDuration(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MovieImportComponent ci;
+	TimeValue duration;
+	TimeScale scale;
+#ifndef MovieImportSetSampleDuration
+	PyMac_PRECHECK(MovieImportSetSampleDuration);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&ll",
+	                      CmpObj_Convert, &ci,
+	                      &duration,
+	                      &scale))
+		return NULL;
+	_rv = MovieImportSetSampleDuration(ci,
+	                                   duration,
+	                                   scale);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MovieImportSetSampleDescription(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MovieImportComponent ci;
+	SampleDescriptionHandle desc;
+	OSType mediaType;
+#ifndef MovieImportSetSampleDescription
+	PyMac_PRECHECK(MovieImportSetSampleDescription);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      CmpObj_Convert, &ci,
+	                      ResObj_Convert, &desc,
+	                      PyMac_GetOSType, &mediaType))
+		return NULL;
+	_rv = MovieImportSetSampleDescription(ci,
+	                                      desc,
+	                                      mediaType);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MovieImportSetMediaFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MovieImportComponent ci;
+	AliasHandle alias;
+#ifndef MovieImportSetMediaFile
+	PyMac_PRECHECK(MovieImportSetMediaFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &ci,
+	                      ResObj_Convert, &alias))
+		return NULL;
+	_rv = MovieImportSetMediaFile(ci,
+	                              alias);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MovieImportSetDimensions(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MovieImportComponent ci;
+	Fixed width;
+	Fixed height;
+#ifndef MovieImportSetDimensions
+	PyMac_PRECHECK(MovieImportSetDimensions);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      CmpObj_Convert, &ci,
+	                      PyMac_GetFixed, &width,
+	                      PyMac_GetFixed, &height))
+		return NULL;
+	_rv = MovieImportSetDimensions(ci,
+	                               width,
+	                               height);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MovieImportSetChunkSize(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MovieImportComponent ci;
+	long chunkSize;
+#ifndef MovieImportSetChunkSize
+	PyMac_PRECHECK(MovieImportSetChunkSize);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpObj_Convert, &ci,
+	                      &chunkSize))
+		return NULL;
+	_rv = MovieImportSetChunkSize(ci,
+	                              chunkSize);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MovieImportSetAuxiliaryData(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MovieImportComponent ci;
+	Handle data;
+	OSType handleType;
+#ifndef MovieImportSetAuxiliaryData
+	PyMac_PRECHECK(MovieImportSetAuxiliaryData);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      CmpObj_Convert, &ci,
+	                      ResObj_Convert, &data,
+	                      PyMac_GetOSType, &handleType))
+		return NULL;
+	_rv = MovieImportSetAuxiliaryData(ci,
+	                                  data,
+	                                  handleType);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MovieImportSetFromScrap(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MovieImportComponent ci;
+	Boolean fromScrap;
+#ifndef MovieImportSetFromScrap
+	PyMac_PRECHECK(MovieImportSetFromScrap);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&b",
+	                      CmpObj_Convert, &ci,
+	                      &fromScrap))
+		return NULL;
+	_rv = MovieImportSetFromScrap(ci,
+	                              fromScrap);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MovieImportDoUserDialog(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MovieImportComponent ci;
+	FSSpec theFile;
+	Handle theData;
+	Boolean canceled;
+#ifndef MovieImportDoUserDialog
+	PyMac_PRECHECK(MovieImportDoUserDialog);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      CmpObj_Convert, &ci,
+	                      PyMac_GetFSSpec, &theFile,
+	                      ResObj_Convert, &theData))
+		return NULL;
+	_rv = MovieImportDoUserDialog(ci,
+	                              &theFile,
+	                              theData,
+	                              &canceled);
+	_res = Py_BuildValue("lb",
+	                     _rv,
+	                     canceled);
+	return _res;
+}
+
+static PyObject *Qt_MovieImportSetDuration(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MovieImportComponent ci;
+	TimeValue duration;
+#ifndef MovieImportSetDuration
+	PyMac_PRECHECK(MovieImportSetDuration);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpObj_Convert, &ci,
+	                      &duration))
+		return NULL;
+	_rv = MovieImportSetDuration(ci,
+	                             duration);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MovieImportGetAuxiliaryDataType(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MovieImportComponent ci;
+	OSType auxType;
+#ifndef MovieImportGetAuxiliaryDataType
+	PyMac_PRECHECK(MovieImportGetAuxiliaryDataType);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = MovieImportGetAuxiliaryDataType(ci,
+	                                      &auxType);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     PyMac_BuildOSType, auxType);
+	return _res;
+}
+
+static PyObject *Qt_MovieImportValidate(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MovieImportComponent ci;
+	FSSpec theFile;
+	Handle theData;
+	Boolean valid;
+#ifndef MovieImportValidate
+	PyMac_PRECHECK(MovieImportValidate);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      CmpObj_Convert, &ci,
+	                      PyMac_GetFSSpec, &theFile,
+	                      ResObj_Convert, &theData))
+		return NULL;
+	_rv = MovieImportValidate(ci,
+	                          &theFile,
+	                          theData,
+	                          &valid);
+	_res = Py_BuildValue("lb",
+	                     _rv,
+	                     valid);
+	return _res;
+}
+
+static PyObject *Qt_MovieImportGetFileType(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MovieImportComponent ci;
+	OSType fileType;
+#ifndef MovieImportGetFileType
+	PyMac_PRECHECK(MovieImportGetFileType);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = MovieImportGetFileType(ci,
+	                             &fileType);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     PyMac_BuildOSType, fileType);
+	return _res;
+}
+
+static PyObject *Qt_MovieImportDataRef(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MovieImportComponent ci;
+	Handle dataRef;
+	OSType dataRefType;
+	Movie theMovie;
+	Track targetTrack;
+	Track usedTrack;
+	TimeValue atTime;
+	TimeValue addedDuration;
+	long inFlags;
+	long outFlags;
+#ifndef MovieImportDataRef
+	PyMac_PRECHECK(MovieImportDataRef);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&O&O&ll",
+	                      CmpObj_Convert, &ci,
+	                      ResObj_Convert, &dataRef,
+	                      PyMac_GetOSType, &dataRefType,
+	                      MovieObj_Convert, &theMovie,
+	                      TrackObj_Convert, &targetTrack,
+	                      &atTime,
+	                      &inFlags))
+		return NULL;
+	_rv = MovieImportDataRef(ci,
+	                         dataRef,
+	                         dataRefType,
+	                         theMovie,
+	                         targetTrack,
+	                         &usedTrack,
+	                         atTime,
+	                         &addedDuration,
+	                         inFlags,
+	                         &outFlags);
+	_res = Py_BuildValue("lO&ll",
+	                     _rv,
+	                     TrackObj_New, usedTrack,
+	                     addedDuration,
+	                     outFlags);
+	return _res;
+}
+
+static PyObject *Qt_MovieImportGetSampleDescription(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MovieImportComponent ci;
+	SampleDescriptionHandle desc;
+	OSType mediaType;
+#ifndef MovieImportGetSampleDescription
+	PyMac_PRECHECK(MovieImportGetSampleDescription);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = MovieImportGetSampleDescription(ci,
+	                                      &desc,
+	                                      &mediaType);
+	_res = Py_BuildValue("lO&O&",
+	                     _rv,
+	                     ResObj_New, desc,
+	                     PyMac_BuildOSType, mediaType);
+	return _res;
+}
+
+static PyObject *Qt_MovieImportSetOffsetAndLimit(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MovieImportComponent ci;
+	unsigned long offset;
+	unsigned long limit;
+#ifndef MovieImportSetOffsetAndLimit
+	PyMac_PRECHECK(MovieImportSetOffsetAndLimit);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&ll",
+	                      CmpObj_Convert, &ci,
+	                      &offset,
+	                      &limit))
+		return NULL;
+	_rv = MovieImportSetOffsetAndLimit(ci,
+	                                   offset,
+	                                   limit);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MovieImportSetOffsetAndLimit64(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MovieImportComponent ci;
+	wide offset;
+	wide limit;
+#ifndef MovieImportSetOffsetAndLimit64
+	PyMac_PRECHECK(MovieImportSetOffsetAndLimit64);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      CmpObj_Convert, &ci,
+	                      PyMac_Getwide, &offset,
+	                      PyMac_Getwide, &limit))
+		return NULL;
+	_rv = MovieImportSetOffsetAndLimit64(ci,
+	                                     &offset,
+	                                     &limit);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MovieImportIdle(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MovieImportComponent ci;
+	long inFlags;
+	long outFlags;
+#ifndef MovieImportIdle
+	PyMac_PRECHECK(MovieImportIdle);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpObj_Convert, &ci,
+	                      &inFlags))
+		return NULL;
+	_rv = MovieImportIdle(ci,
+	                      inFlags,
+	                      &outFlags);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     outFlags);
+	return _res;
+}
+
+static PyObject *Qt_MovieImportValidateDataRef(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MovieImportComponent ci;
+	Handle dataRef;
+	OSType dataRefType;
+	UInt8 valid;
+#ifndef MovieImportValidateDataRef
+	PyMac_PRECHECK(MovieImportValidateDataRef);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      CmpObj_Convert, &ci,
+	                      ResObj_Convert, &dataRef,
+	                      PyMac_GetOSType, &dataRefType))
+		return NULL;
+	_rv = MovieImportValidateDataRef(ci,
+	                                 dataRef,
+	                                 dataRefType,
+	                                 &valid);
+	_res = Py_BuildValue("lb",
+	                     _rv,
+	                     valid);
+	return _res;
+}
+
+static PyObject *Qt_MovieImportGetLoadState(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MovieImportComponent ci;
+	long importerLoadState;
+#ifndef MovieImportGetLoadState
+	PyMac_PRECHECK(MovieImportGetLoadState);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = MovieImportGetLoadState(ci,
+	                              &importerLoadState);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     importerLoadState);
+	return _res;
+}
+
+static PyObject *Qt_MovieImportGetMaxLoadedTime(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MovieImportComponent ci;
+	TimeValue time;
+#ifndef MovieImportGetMaxLoadedTime
+	PyMac_PRECHECK(MovieImportGetMaxLoadedTime);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = MovieImportGetMaxLoadedTime(ci,
+	                                  &time);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     time);
+	return _res;
+}
+
+static PyObject *Qt_MovieImportEstimateCompletionTime(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MovieImportComponent ci;
+	TimeRecord time;
+#ifndef MovieImportEstimateCompletionTime
+	PyMac_PRECHECK(MovieImportEstimateCompletionTime);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = MovieImportEstimateCompletionTime(ci,
+	                                        &time);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     QtTimeRecord_New, &time);
+	return _res;
+}
+
+static PyObject *Qt_MovieImportSetDontBlock(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MovieImportComponent ci;
+	Boolean dontBlock;
+#ifndef MovieImportSetDontBlock
+	PyMac_PRECHECK(MovieImportSetDontBlock);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&b",
+	                      CmpObj_Convert, &ci,
+	                      &dontBlock))
+		return NULL;
+	_rv = MovieImportSetDontBlock(ci,
+	                              dontBlock);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MovieImportGetDontBlock(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MovieImportComponent ci;
+	Boolean willBlock;
+#ifndef MovieImportGetDontBlock
+	PyMac_PRECHECK(MovieImportGetDontBlock);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = MovieImportGetDontBlock(ci,
+	                              &willBlock);
+	_res = Py_BuildValue("lb",
+	                     _rv,
+	                     willBlock);
+	return _res;
+}
+
+static PyObject *Qt_MovieImportSetIdleManager(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MovieImportComponent ci;
+	IdleManager im;
+#ifndef MovieImportSetIdleManager
+	PyMac_PRECHECK(MovieImportSetIdleManager);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &ci,
+	                      IdleManagerObj_Convert, &im))
+		return NULL;
+	_rv = MovieImportSetIdleManager(ci,
+	                                im);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MovieImportSetNewMovieFlags(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MovieImportComponent ci;
+	long newMovieFlags;
+#ifndef MovieImportSetNewMovieFlags
+	PyMac_PRECHECK(MovieImportSetNewMovieFlags);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpObj_Convert, &ci,
+	                      &newMovieFlags))
+		return NULL;
+	_rv = MovieImportSetNewMovieFlags(ci,
+	                                  newMovieFlags);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MovieImportGetDestinationMediaType(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MovieImportComponent ci;
+	OSType mediaType;
+#ifndef MovieImportGetDestinationMediaType
+	PyMac_PRECHECK(MovieImportGetDestinationMediaType);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = MovieImportGetDestinationMediaType(ci,
+	                                         &mediaType);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     PyMac_BuildOSType, mediaType);
+	return _res;
+}
+
+static PyObject *Qt_MovieExportToHandle(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MovieExportComponent ci;
+	Handle dataH;
+	Movie theMovie;
+	Track onlyThisTrack;
+	TimeValue startTime;
+	TimeValue duration;
+#ifndef MovieExportToHandle
+	PyMac_PRECHECK(MovieExportToHandle);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&O&ll",
+	                      CmpObj_Convert, &ci,
+	                      ResObj_Convert, &dataH,
+	                      MovieObj_Convert, &theMovie,
+	                      TrackObj_Convert, &onlyThisTrack,
+	                      &startTime,
+	                      &duration))
+		return NULL;
+	_rv = MovieExportToHandle(ci,
+	                          dataH,
+	                          theMovie,
+	                          onlyThisTrack,
+	                          startTime,
+	                          duration);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MovieExportToFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MovieExportComponent ci;
+	FSSpec theFile;
+	Movie theMovie;
+	Track onlyThisTrack;
+	TimeValue startTime;
+	TimeValue duration;
+#ifndef MovieExportToFile
+	PyMac_PRECHECK(MovieExportToFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&O&ll",
+	                      CmpObj_Convert, &ci,
+	                      PyMac_GetFSSpec, &theFile,
+	                      MovieObj_Convert, &theMovie,
+	                      TrackObj_Convert, &onlyThisTrack,
+	                      &startTime,
+	                      &duration))
+		return NULL;
+	_rv = MovieExportToFile(ci,
+	                        &theFile,
+	                        theMovie,
+	                        onlyThisTrack,
+	                        startTime,
+	                        duration);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MovieExportGetAuxiliaryData(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MovieExportComponent ci;
+	Handle dataH;
+	OSType handleType;
+#ifndef MovieExportGetAuxiliaryData
+	PyMac_PRECHECK(MovieExportGetAuxiliaryData);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &ci,
+	                      ResObj_Convert, &dataH))
+		return NULL;
+	_rv = MovieExportGetAuxiliaryData(ci,
+	                                  dataH,
+	                                  &handleType);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     PyMac_BuildOSType, handleType);
+	return _res;
+}
+
+static PyObject *Qt_MovieExportSetSampleDescription(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MovieExportComponent ci;
+	SampleDescriptionHandle desc;
+	OSType mediaType;
+#ifndef MovieExportSetSampleDescription
+	PyMac_PRECHECK(MovieExportSetSampleDescription);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      CmpObj_Convert, &ci,
+	                      ResObj_Convert, &desc,
+	                      PyMac_GetOSType, &mediaType))
+		return NULL;
+	_rv = MovieExportSetSampleDescription(ci,
+	                                      desc,
+	                                      mediaType);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MovieExportDoUserDialog(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MovieExportComponent ci;
+	Movie theMovie;
+	Track onlyThisTrack;
+	TimeValue startTime;
+	TimeValue duration;
+	Boolean canceled;
+#ifndef MovieExportDoUserDialog
+	PyMac_PRECHECK(MovieExportDoUserDialog);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&ll",
+	                      CmpObj_Convert, &ci,
+	                      MovieObj_Convert, &theMovie,
+	                      TrackObj_Convert, &onlyThisTrack,
+	                      &startTime,
+	                      &duration))
+		return NULL;
+	_rv = MovieExportDoUserDialog(ci,
+	                              theMovie,
+	                              onlyThisTrack,
+	                              startTime,
+	                              duration,
+	                              &canceled);
+	_res = Py_BuildValue("lb",
+	                     _rv,
+	                     canceled);
+	return _res;
+}
+
+static PyObject *Qt_MovieExportGetCreatorType(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MovieExportComponent ci;
+	OSType creator;
+#ifndef MovieExportGetCreatorType
+	PyMac_PRECHECK(MovieExportGetCreatorType);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = MovieExportGetCreatorType(ci,
+	                                &creator);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     PyMac_BuildOSType, creator);
+	return _res;
+}
+
+static PyObject *Qt_MovieExportToDataRef(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MovieExportComponent ci;
+	Handle dataRef;
+	OSType dataRefType;
+	Movie theMovie;
+	Track onlyThisTrack;
+	TimeValue startTime;
+	TimeValue duration;
+#ifndef MovieExportToDataRef
+	PyMac_PRECHECK(MovieExportToDataRef);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&O&O&ll",
+	                      CmpObj_Convert, &ci,
+	                      ResObj_Convert, &dataRef,
+	                      PyMac_GetOSType, &dataRefType,
+	                      MovieObj_Convert, &theMovie,
+	                      TrackObj_Convert, &onlyThisTrack,
+	                      &startTime,
+	                      &duration))
+		return NULL;
+	_rv = MovieExportToDataRef(ci,
+	                           dataRef,
+	                           dataRefType,
+	                           theMovie,
+	                           onlyThisTrack,
+	                           startTime,
+	                           duration);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MovieExportFromProceduresToDataRef(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MovieExportComponent ci;
+	Handle dataRef;
+	OSType dataRefType;
+#ifndef MovieExportFromProceduresToDataRef
+	PyMac_PRECHECK(MovieExportFromProceduresToDataRef);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      CmpObj_Convert, &ci,
+	                      ResObj_Convert, &dataRef,
+	                      PyMac_GetOSType, &dataRefType))
+		return NULL;
+	_rv = MovieExportFromProceduresToDataRef(ci,
+	                                         dataRef,
+	                                         dataRefType);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MovieExportValidate(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MovieExportComponent ci;
+	Movie theMovie;
+	Track onlyThisTrack;
+	Boolean valid;
+#ifndef MovieExportValidate
+	PyMac_PRECHECK(MovieExportValidate);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      CmpObj_Convert, &ci,
+	                      MovieObj_Convert, &theMovie,
+	                      TrackObj_Convert, &onlyThisTrack))
+		return NULL;
+	_rv = MovieExportValidate(ci,
+	                          theMovie,
+	                          onlyThisTrack,
+	                          &valid);
+	_res = Py_BuildValue("lb",
+	                     _rv,
+	                     valid);
+	return _res;
+}
+
+static PyObject *Qt_MovieExportGetFileNameExtension(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MovieExportComponent ci;
+	OSType extension;
+#ifndef MovieExportGetFileNameExtension
+	PyMac_PRECHECK(MovieExportGetFileNameExtension);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = MovieExportGetFileNameExtension(ci,
+	                                      &extension);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     PyMac_BuildOSType, extension);
+	return _res;
+}
+
+static PyObject *Qt_MovieExportGetShortFileTypeString(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MovieExportComponent ci;
+	Str255 typeString;
+#ifndef MovieExportGetShortFileTypeString
+	PyMac_PRECHECK(MovieExportGetShortFileTypeString);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &ci,
+	                      PyMac_GetStr255, typeString))
+		return NULL;
+	_rv = MovieExportGetShortFileTypeString(ci,
+	                                        typeString);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MovieExportGetSourceMediaType(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MovieExportComponent ci;
+	OSType mediaType;
+#ifndef MovieExportGetSourceMediaType
+	PyMac_PRECHECK(MovieExportGetSourceMediaType);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = MovieExportGetSourceMediaType(ci,
+	                                    &mediaType);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     PyMac_BuildOSType, mediaType);
+	return _res;
+}
+
+static PyObject *Qt_TextExportGetTimeFraction(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	TextExportComponent ci;
+	long movieTimeFraction;
+#ifndef TextExportGetTimeFraction
+	PyMac_PRECHECK(TextExportGetTimeFraction);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = TextExportGetTimeFraction(ci,
+	                                &movieTimeFraction);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     movieTimeFraction);
+	return _res;
+}
+
+static PyObject *Qt_TextExportSetTimeFraction(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	TextExportComponent ci;
+	long movieTimeFraction;
+#ifndef TextExportSetTimeFraction
+	PyMac_PRECHECK(TextExportSetTimeFraction);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpObj_Convert, &ci,
+	                      &movieTimeFraction))
+		return NULL;
+	_rv = TextExportSetTimeFraction(ci,
+	                                movieTimeFraction);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_TextExportGetSettings(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	TextExportComponent ci;
+	long setting;
+#ifndef TextExportGetSettings
+	PyMac_PRECHECK(TextExportGetSettings);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = TextExportGetSettings(ci,
+	                            &setting);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     setting);
+	return _res;
+}
+
+static PyObject *Qt_TextExportSetSettings(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	TextExportComponent ci;
+	long setting;
+#ifndef TextExportSetSettings
+	PyMac_PRECHECK(TextExportSetSettings);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpObj_Convert, &ci,
+	                      &setting))
+		return NULL;
+	_rv = TextExportSetSettings(ci,
+	                            setting);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MIDIImportGetSettings(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	TextExportComponent ci;
+	long setting;
+#ifndef MIDIImportGetSettings
+	PyMac_PRECHECK(MIDIImportGetSettings);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = MIDIImportGetSettings(ci,
+	                            &setting);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     setting);
+	return _res;
+}
+
+static PyObject *Qt_MIDIImportSetSettings(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	TextExportComponent ci;
+	long setting;
+#ifndef MIDIImportSetSettings
+	PyMac_PRECHECK(MIDIImportSetSettings);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpObj_Convert, &ci,
+	                      &setting))
+		return NULL;
+	_rv = MIDIImportSetSettings(ci,
+	                            setting);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImageImportSetSequenceEnabled(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicImageMovieImportComponent ci;
+	Boolean enable;
+#ifndef GraphicsImageImportSetSequenceEnabled
+	PyMac_PRECHECK(GraphicsImageImportSetSequenceEnabled);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&b",
+	                      CmpObj_Convert, &ci,
+	                      &enable))
+		return NULL;
+	_rv = GraphicsImageImportSetSequenceEnabled(ci,
+	                                            enable);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_GraphicsImageImportGetSequenceEnabled(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	GraphicImageMovieImportComponent ci;
+	Boolean enable;
+#ifndef GraphicsImageImportGetSequenceEnabled
+	PyMac_PRECHECK(GraphicsImageImportGetSequenceEnabled);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = GraphicsImageImportGetSequenceEnabled(ci,
+	                                            &enable);
+	_res = Py_BuildValue("lb",
+	                     _rv,
+	                     enable);
+	return _res;
+}
+
+static PyObject *Qt_PreviewShowData(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	pnotComponent p;
+	OSType dataType;
+	Handle data;
+	Rect inHere;
+#ifndef PreviewShowData
+	PyMac_PRECHECK(PreviewShowData);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&O&",
+	                      CmpObj_Convert, &p,
+	                      PyMac_GetOSType, &dataType,
+	                      ResObj_Convert, &data,
+	                      PyMac_GetRect, &inHere))
+		return NULL;
+	_rv = PreviewShowData(p,
+	                      dataType,
+	                      data,
+	                      &inHere);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_PreviewMakePreviewReference(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	pnotComponent p;
+	OSType previewType;
+	short resID;
+	FSSpec sourceFile;
+#ifndef PreviewMakePreviewReference
+	PyMac_PRECHECK(PreviewMakePreviewReference);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &p,
+	                      PyMac_GetFSSpec, &sourceFile))
+		return NULL;
+	_rv = PreviewMakePreviewReference(p,
+	                                  &previewType,
+	                                  &resID,
+	                                  &sourceFile);
+	_res = Py_BuildValue("lO&h",
+	                     _rv,
+	                     PyMac_BuildOSType, previewType,
+	                     resID);
+	return _res;
+}
+
+static PyObject *Qt_PreviewEvent(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	pnotComponent p;
+	EventRecord e;
+	Boolean handledEvent;
+#ifndef PreviewEvent
+	PyMac_PRECHECK(PreviewEvent);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &p))
+		return NULL;
+	_rv = PreviewEvent(p,
+	                   &e,
+	                   &handledEvent);
+	_res = Py_BuildValue("lO&b",
+	                     _rv,
+	                     PyMac_BuildEventRecord, &e,
+	                     handledEvent);
+	return _res;
+}
+
+static PyObject *Qt_DataCodecDecompress(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataCodecComponent dc;
+	void * srcData;
+	UInt32 srcSize;
+	void * dstData;
+	UInt32 dstBufferSize;
+#ifndef DataCodecDecompress
+	PyMac_PRECHECK(DataCodecDecompress);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&slsl",
+	                      CmpObj_Convert, &dc,
+	                      &srcData,
+	                      &srcSize,
+	                      &dstData,
+	                      &dstBufferSize))
+		return NULL;
+	_rv = DataCodecDecompress(dc,
+	                          srcData,
+	                          srcSize,
+	                          dstData,
+	                          dstBufferSize);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_DataCodecGetCompressBufferSize(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataCodecComponent dc;
+	UInt32 srcSize;
+	UInt32 dstSize;
+#ifndef DataCodecGetCompressBufferSize
+	PyMac_PRECHECK(DataCodecGetCompressBufferSize);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpObj_Convert, &dc,
+	                      &srcSize))
+		return NULL;
+	_rv = DataCodecGetCompressBufferSize(dc,
+	                                     srcSize,
+	                                     &dstSize);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     dstSize);
+	return _res;
+}
+
+static PyObject *Qt_DataCodecCompress(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataCodecComponent dc;
+	void * srcData;
+	UInt32 srcSize;
+	void * dstData;
+	UInt32 dstBufferSize;
+	UInt32 actualDstSize;
+	UInt32 decompressSlop;
+#ifndef DataCodecCompress
+	PyMac_PRECHECK(DataCodecCompress);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&slsl",
+	                      CmpObj_Convert, &dc,
+	                      &srcData,
+	                      &srcSize,
+	                      &dstData,
+	                      &dstBufferSize))
+		return NULL;
+	_rv = DataCodecCompress(dc,
+	                        srcData,
+	                        srcSize,
+	                        dstData,
+	                        dstBufferSize,
+	                        &actualDstSize,
+	                        &decompressSlop);
+	_res = Py_BuildValue("lll",
+	                     _rv,
+	                     actualDstSize,
+	                     decompressSlop);
+	return _res;
+}
+
+static PyObject *Qt_DataCodecBeginInterruptSafe(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataCodecComponent dc;
+	unsigned long maxSrcSize;
+#ifndef DataCodecBeginInterruptSafe
+	PyMac_PRECHECK(DataCodecBeginInterruptSafe);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpObj_Convert, &dc,
+	                      &maxSrcSize))
+		return NULL;
+	_rv = DataCodecBeginInterruptSafe(dc,
+	                                  maxSrcSize);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_DataCodecEndInterruptSafe(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataCodecComponent dc;
+#ifndef DataCodecEndInterruptSafe
+	PyMac_PRECHECK(DataCodecEndInterruptSafe);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &dc))
+		return NULL;
+	_rv = DataCodecEndInterruptSafe(dc);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_DataHGetData(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	Handle h;
+	long hOffset;
+	long offset;
+	long size;
+#ifndef DataHGetData
+	PyMac_PRECHECK(DataHGetData);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&lll",
+	                      CmpInstObj_Convert, &dh,
+	                      ResObj_Convert, &h,
+	                      &hOffset,
+	                      &offset,
+	                      &size))
+		return NULL;
+	_rv = DataHGetData(dh,
+	                   h,
+	                   hOffset,
+	                   offset,
+	                   size);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_DataHPutData(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	Handle h;
+	long hOffset;
+	long offset;
+	long size;
+#ifndef DataHPutData
+	PyMac_PRECHECK(DataHPutData);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&ll",
+	                      CmpInstObj_Convert, &dh,
+	                      ResObj_Convert, &h,
+	                      &hOffset,
+	                      &size))
+		return NULL;
+	_rv = DataHPutData(dh,
+	                   h,
+	                   hOffset,
+	                   &offset,
+	                   size);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     offset);
+	return _res;
+}
+
+static PyObject *Qt_DataHFlushData(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+#ifndef DataHFlushData
+	PyMac_PRECHECK(DataHFlushData);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &dh))
+		return NULL;
+	_rv = DataHFlushData(dh);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_DataHOpenForWrite(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+#ifndef DataHOpenForWrite
+	PyMac_PRECHECK(DataHOpenForWrite);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &dh))
+		return NULL;
+	_rv = DataHOpenForWrite(dh);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_DataHCloseForWrite(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+#ifndef DataHCloseForWrite
+	PyMac_PRECHECK(DataHCloseForWrite);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &dh))
+		return NULL;
+	_rv = DataHCloseForWrite(dh);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_DataHOpenForRead(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+#ifndef DataHOpenForRead
+	PyMac_PRECHECK(DataHOpenForRead);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &dh))
+		return NULL;
+	_rv = DataHOpenForRead(dh);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_DataHCloseForRead(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+#ifndef DataHCloseForRead
+	PyMac_PRECHECK(DataHCloseForRead);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &dh))
+		return NULL;
+	_rv = DataHCloseForRead(dh);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_DataHSetDataRef(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	Handle dataRef;
+#ifndef DataHSetDataRef
+	PyMac_PRECHECK(DataHSetDataRef);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpInstObj_Convert, &dh,
+	                      ResObj_Convert, &dataRef))
+		return NULL;
+	_rv = DataHSetDataRef(dh,
+	                      dataRef);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_DataHGetDataRef(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	Handle dataRef;
+#ifndef DataHGetDataRef
+	PyMac_PRECHECK(DataHGetDataRef);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &dh))
+		return NULL;
+	_rv = DataHGetDataRef(dh,
+	                      &dataRef);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     ResObj_New, dataRef);
+	return _res;
+}
+
+static PyObject *Qt_DataHCompareDataRef(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	Handle dataRef;
+	Boolean equal;
+#ifndef DataHCompareDataRef
+	PyMac_PRECHECK(DataHCompareDataRef);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpInstObj_Convert, &dh,
+	                      ResObj_Convert, &dataRef))
+		return NULL;
+	_rv = DataHCompareDataRef(dh,
+	                          dataRef,
+	                          &equal);
+	_res = Py_BuildValue("lb",
+	                     _rv,
+	                     equal);
+	return _res;
+}
+
+static PyObject *Qt_DataHTask(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+#ifndef DataHTask
+	PyMac_PRECHECK(DataHTask);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &dh))
+		return NULL;
+	_rv = DataHTask(dh);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_DataHFinishData(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	Ptr PlaceToPutDataPtr;
+	Boolean Cancel;
+#ifndef DataHFinishData
+	PyMac_PRECHECK(DataHFinishData);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&sb",
+	                      CmpInstObj_Convert, &dh,
+	                      &PlaceToPutDataPtr,
+	                      &Cancel))
+		return NULL;
+	_rv = DataHFinishData(dh,
+	                      PlaceToPutDataPtr,
+	                      Cancel);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_DataHFlushCache(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+#ifndef DataHFlushCache
+	PyMac_PRECHECK(DataHFlushCache);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &dh))
+		return NULL;
+	_rv = DataHFlushCache(dh);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_DataHResolveDataRef(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	Handle theDataRef;
+	Boolean wasChanged;
+	Boolean userInterfaceAllowed;
+#ifndef DataHResolveDataRef
+	PyMac_PRECHECK(DataHResolveDataRef);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&b",
+	                      CmpInstObj_Convert, &dh,
+	                      ResObj_Convert, &theDataRef,
+	                      &userInterfaceAllowed))
+		return NULL;
+	_rv = DataHResolveDataRef(dh,
+	                          theDataRef,
+	                          &wasChanged,
+	                          userInterfaceAllowed);
+	_res = Py_BuildValue("lb",
+	                     _rv,
+	                     wasChanged);
+	return _res;
+}
+
+static PyObject *Qt_DataHGetFileSize(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	long fileSize;
+#ifndef DataHGetFileSize
+	PyMac_PRECHECK(DataHGetFileSize);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &dh))
+		return NULL;
+	_rv = DataHGetFileSize(dh,
+	                       &fileSize);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     fileSize);
+	return _res;
+}
+
+static PyObject *Qt_DataHCanUseDataRef(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	Handle dataRef;
+	long useFlags;
+#ifndef DataHCanUseDataRef
+	PyMac_PRECHECK(DataHCanUseDataRef);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpInstObj_Convert, &dh,
+	                      ResObj_Convert, &dataRef))
+		return NULL;
+	_rv = DataHCanUseDataRef(dh,
+	                         dataRef,
+	                         &useFlags);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     useFlags);
+	return _res;
+}
+
+static PyObject *Qt_DataHPreextend(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	unsigned long maxToAdd;
+	unsigned long spaceAdded;
+#ifndef DataHPreextend
+	PyMac_PRECHECK(DataHPreextend);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &dh,
+	                      &maxToAdd))
+		return NULL;
+	_rv = DataHPreextend(dh,
+	                     maxToAdd,
+	                     &spaceAdded);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     spaceAdded);
+	return _res;
+}
+
+static PyObject *Qt_DataHSetFileSize(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	long fileSize;
+#ifndef DataHSetFileSize
+	PyMac_PRECHECK(DataHSetFileSize);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &dh,
+	                      &fileSize))
+		return NULL;
+	_rv = DataHSetFileSize(dh,
+	                       fileSize);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_DataHGetFreeSpace(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	unsigned long freeSize;
+#ifndef DataHGetFreeSpace
+	PyMac_PRECHECK(DataHGetFreeSpace);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &dh))
+		return NULL;
+	_rv = DataHGetFreeSpace(dh,
+	                        &freeSize);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     freeSize);
+	return _res;
+}
+
+static PyObject *Qt_DataHCreateFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	OSType creator;
+	Boolean deleteExisting;
+#ifndef DataHCreateFile
+	PyMac_PRECHECK(DataHCreateFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&b",
+	                      CmpInstObj_Convert, &dh,
+	                      PyMac_GetOSType, &creator,
+	                      &deleteExisting))
+		return NULL;
+	_rv = DataHCreateFile(dh,
+	                      creator,
+	                      deleteExisting);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_DataHGetPreferredBlockSize(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	long blockSize;
+#ifndef DataHGetPreferredBlockSize
+	PyMac_PRECHECK(DataHGetPreferredBlockSize);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &dh))
+		return NULL;
+	_rv = DataHGetPreferredBlockSize(dh,
+	                                 &blockSize);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     blockSize);
+	return _res;
+}
+
+static PyObject *Qt_DataHGetDeviceIndex(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	long deviceIndex;
+#ifndef DataHGetDeviceIndex
+	PyMac_PRECHECK(DataHGetDeviceIndex);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &dh))
+		return NULL;
+	_rv = DataHGetDeviceIndex(dh,
+	                          &deviceIndex);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     deviceIndex);
+	return _res;
+}
+
+static PyObject *Qt_DataHIsStreamingDataHandler(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	Boolean yes;
+#ifndef DataHIsStreamingDataHandler
+	PyMac_PRECHECK(DataHIsStreamingDataHandler);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &dh))
+		return NULL;
+	_rv = DataHIsStreamingDataHandler(dh,
+	                                  &yes);
+	_res = Py_BuildValue("lb",
+	                     _rv,
+	                     yes);
+	return _res;
+}
+
+static PyObject *Qt_DataHGetDataInBuffer(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	long startOffset;
+	long size;
+#ifndef DataHGetDataInBuffer
+	PyMac_PRECHECK(DataHGetDataInBuffer);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &dh,
+	                      &startOffset))
+		return NULL;
+	_rv = DataHGetDataInBuffer(dh,
+	                           startOffset,
+	                           &size);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     size);
+	return _res;
+}
+
+static PyObject *Qt_DataHGetScheduleAheadTime(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	long millisecs;
+#ifndef DataHGetScheduleAheadTime
+	PyMac_PRECHECK(DataHGetScheduleAheadTime);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &dh))
+		return NULL;
+	_rv = DataHGetScheduleAheadTime(dh,
+	                                &millisecs);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     millisecs);
+	return _res;
+}
+
+static PyObject *Qt_DataHSetCacheSizeLimit(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	Size cacheSizeLimit;
+#ifndef DataHSetCacheSizeLimit
+	PyMac_PRECHECK(DataHSetCacheSizeLimit);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &dh,
+	                      &cacheSizeLimit))
+		return NULL;
+	_rv = DataHSetCacheSizeLimit(dh,
+	                             cacheSizeLimit);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_DataHGetCacheSizeLimit(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	Size cacheSizeLimit;
+#ifndef DataHGetCacheSizeLimit
+	PyMac_PRECHECK(DataHGetCacheSizeLimit);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &dh))
+		return NULL;
+	_rv = DataHGetCacheSizeLimit(dh,
+	                             &cacheSizeLimit);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     cacheSizeLimit);
+	return _res;
+}
+
+static PyObject *Qt_DataHGetMovie(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	Movie theMovie;
+	short id;
+#ifndef DataHGetMovie
+	PyMac_PRECHECK(DataHGetMovie);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &dh))
+		return NULL;
+	_rv = DataHGetMovie(dh,
+	                    &theMovie,
+	                    &id);
+	_res = Py_BuildValue("lO&h",
+	                     _rv,
+	                     MovieObj_New, theMovie,
+	                     id);
+	return _res;
+}
+
+static PyObject *Qt_DataHAddMovie(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	Movie theMovie;
+	short id;
+#ifndef DataHAddMovie
+	PyMac_PRECHECK(DataHAddMovie);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpInstObj_Convert, &dh,
+	                      MovieObj_Convert, &theMovie))
+		return NULL;
+	_rv = DataHAddMovie(dh,
+	                    theMovie,
+	                    &id);
+	_res = Py_BuildValue("lh",
+	                     _rv,
+	                     id);
+	return _res;
+}
+
+static PyObject *Qt_DataHUpdateMovie(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	Movie theMovie;
+	short id;
+#ifndef DataHUpdateMovie
+	PyMac_PRECHECK(DataHUpdateMovie);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&h",
+	                      CmpInstObj_Convert, &dh,
+	                      MovieObj_Convert, &theMovie,
+	                      &id))
+		return NULL;
+	_rv = DataHUpdateMovie(dh,
+	                       theMovie,
+	                       id);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_DataHDoesBuffer(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	Boolean buffersReads;
+	Boolean buffersWrites;
+#ifndef DataHDoesBuffer
+	PyMac_PRECHECK(DataHDoesBuffer);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &dh))
+		return NULL;
+	_rv = DataHDoesBuffer(dh,
+	                      &buffersReads,
+	                      &buffersWrites);
+	_res = Py_BuildValue("lbb",
+	                     _rv,
+	                     buffersReads,
+	                     buffersWrites);
+	return _res;
+}
+
+static PyObject *Qt_DataHGetFileName(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	Str255 str;
+#ifndef DataHGetFileName
+	PyMac_PRECHECK(DataHGetFileName);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpInstObj_Convert, &dh,
+	                      PyMac_GetStr255, str))
+		return NULL;
+	_rv = DataHGetFileName(dh,
+	                       str);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_DataHGetAvailableFileSize(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	long fileSize;
+#ifndef DataHGetAvailableFileSize
+	PyMac_PRECHECK(DataHGetAvailableFileSize);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &dh))
+		return NULL;
+	_rv = DataHGetAvailableFileSize(dh,
+	                                &fileSize);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     fileSize);
+	return _res;
+}
+
+static PyObject *Qt_DataHGetMacOSFileType(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	OSType fileType;
+#ifndef DataHGetMacOSFileType
+	PyMac_PRECHECK(DataHGetMacOSFileType);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &dh))
+		return NULL;
+	_rv = DataHGetMacOSFileType(dh,
+	                            &fileType);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     PyMac_BuildOSType, fileType);
+	return _res;
+}
+
+static PyObject *Qt_DataHGetMIMEType(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	Str255 mimeType;
+#ifndef DataHGetMIMEType
+	PyMac_PRECHECK(DataHGetMIMEType);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpInstObj_Convert, &dh,
+	                      PyMac_GetStr255, mimeType))
+		return NULL;
+	_rv = DataHGetMIMEType(dh,
+	                       mimeType);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_DataHSetDataRefWithAnchor(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	Handle anchorDataRef;
+	OSType dataRefType;
+	Handle dataRef;
+#ifndef DataHSetDataRefWithAnchor
+	PyMac_PRECHECK(DataHSetDataRefWithAnchor);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&O&",
+	                      CmpInstObj_Convert, &dh,
+	                      ResObj_Convert, &anchorDataRef,
+	                      PyMac_GetOSType, &dataRefType,
+	                      ResObj_Convert, &dataRef))
+		return NULL;
+	_rv = DataHSetDataRefWithAnchor(dh,
+	                                anchorDataRef,
+	                                dataRefType,
+	                                dataRef);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_DataHGetDataRefWithAnchor(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	Handle anchorDataRef;
+	OSType dataRefType;
+	Handle dataRef;
+#ifndef DataHGetDataRefWithAnchor
+	PyMac_PRECHECK(DataHGetDataRefWithAnchor);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      CmpInstObj_Convert, &dh,
+	                      ResObj_Convert, &anchorDataRef,
+	                      PyMac_GetOSType, &dataRefType))
+		return NULL;
+	_rv = DataHGetDataRefWithAnchor(dh,
+	                                anchorDataRef,
+	                                dataRefType,
+	                                &dataRef);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     ResObj_New, dataRef);
+	return _res;
+}
+
+static PyObject *Qt_DataHSetMacOSFileType(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	OSType fileType;
+#ifndef DataHSetMacOSFileType
+	PyMac_PRECHECK(DataHSetMacOSFileType);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpInstObj_Convert, &dh,
+	                      PyMac_GetOSType, &fileType))
+		return NULL;
+	_rv = DataHSetMacOSFileType(dh,
+	                            fileType);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_DataHSetTimeBase(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	TimeBase tb;
+#ifndef DataHSetTimeBase
+	PyMac_PRECHECK(DataHSetTimeBase);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpInstObj_Convert, &dh,
+	                      TimeBaseObj_Convert, &tb))
+		return NULL;
+	_rv = DataHSetTimeBase(dh,
+	                       tb);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_DataHGetInfoFlags(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	UInt32 flags;
+#ifndef DataHGetInfoFlags
+	PyMac_PRECHECK(DataHGetInfoFlags);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &dh))
+		return NULL;
+	_rv = DataHGetInfoFlags(dh,
+	                        &flags);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     flags);
+	return _res;
+}
+
+static PyObject *Qt_DataHGetFileSize64(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	wide fileSize;
+#ifndef DataHGetFileSize64
+	PyMac_PRECHECK(DataHGetFileSize64);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &dh))
+		return NULL;
+	_rv = DataHGetFileSize64(dh,
+	                         &fileSize);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     PyMac_Buildwide, fileSize);
+	return _res;
+}
+
+static PyObject *Qt_DataHPreextend64(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	wide maxToAdd;
+	wide spaceAdded;
+#ifndef DataHPreextend64
+	PyMac_PRECHECK(DataHPreextend64);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpInstObj_Convert, &dh,
+	                      PyMac_Getwide, &maxToAdd))
+		return NULL;
+	_rv = DataHPreextend64(dh,
+	                       &maxToAdd,
+	                       &spaceAdded);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     PyMac_Buildwide, spaceAdded);
+	return _res;
+}
+
+static PyObject *Qt_DataHSetFileSize64(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	wide fileSize;
+#ifndef DataHSetFileSize64
+	PyMac_PRECHECK(DataHSetFileSize64);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpInstObj_Convert, &dh,
+	                      PyMac_Getwide, &fileSize))
+		return NULL;
+	_rv = DataHSetFileSize64(dh,
+	                         &fileSize);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_DataHGetFreeSpace64(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	wide freeSize;
+#ifndef DataHGetFreeSpace64
+	PyMac_PRECHECK(DataHGetFreeSpace64);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &dh))
+		return NULL;
+	_rv = DataHGetFreeSpace64(dh,
+	                          &freeSize);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     PyMac_Buildwide, freeSize);
+	return _res;
+}
+
+static PyObject *Qt_DataHAppend64(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	void * data;
+	wide fileOffset;
+	unsigned long size;
+#ifndef DataHAppend64
+	PyMac_PRECHECK(DataHAppend64);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&sl",
+	                      CmpInstObj_Convert, &dh,
+	                      &data,
+	                      &size))
+		return NULL;
+	_rv = DataHAppend64(dh,
+	                    data,
+	                    &fileOffset,
+	                    size);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     PyMac_Buildwide, fileOffset);
+	return _res;
+}
+
+static PyObject *Qt_DataHPollRead(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	void * dataPtr;
+	UInt32 dataSizeSoFar;
+#ifndef DataHPollRead
+	PyMac_PRECHECK(DataHPollRead);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&s",
+	                      CmpInstObj_Convert, &dh,
+	                      &dataPtr))
+		return NULL;
+	_rv = DataHPollRead(dh,
+	                    dataPtr,
+	                    &dataSizeSoFar);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     dataSizeSoFar);
+	return _res;
+}
+
+static PyObject *Qt_DataHGetDataAvailability(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	long offset;
+	long len;
+	long missing_offset;
+	long missing_len;
+#ifndef DataHGetDataAvailability
+	PyMac_PRECHECK(DataHGetDataAvailability);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&ll",
+	                      CmpInstObj_Convert, &dh,
+	                      &offset,
+	                      &len))
+		return NULL;
+	_rv = DataHGetDataAvailability(dh,
+	                               offset,
+	                               len,
+	                               &missing_offset,
+	                               &missing_len);
+	_res = Py_BuildValue("lll",
+	                     _rv,
+	                     missing_offset,
+	                     missing_len);
+	return _res;
+}
+
+static PyObject *Qt_DataHGetDataRefAsType(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	OSType requestedType;
+	Handle dataRef;
+#ifndef DataHGetDataRefAsType
+	PyMac_PRECHECK(DataHGetDataRefAsType);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpInstObj_Convert, &dh,
+	                      PyMac_GetOSType, &requestedType))
+		return NULL;
+	_rv = DataHGetDataRefAsType(dh,
+	                            requestedType,
+	                            &dataRef);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     ResObj_New, dataRef);
+	return _res;
+}
+
+static PyObject *Qt_DataHSetDataRefExtension(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	Handle extension;
+	OSType idType;
+#ifndef DataHSetDataRefExtension
+	PyMac_PRECHECK(DataHSetDataRefExtension);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      CmpInstObj_Convert, &dh,
+	                      ResObj_Convert, &extension,
+	                      PyMac_GetOSType, &idType))
+		return NULL;
+	_rv = DataHSetDataRefExtension(dh,
+	                               extension,
+	                               idType);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_DataHGetDataRefExtension(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	Handle extension;
+	OSType idType;
+#ifndef DataHGetDataRefExtension
+	PyMac_PRECHECK(DataHGetDataRefExtension);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpInstObj_Convert, &dh,
+	                      PyMac_GetOSType, &idType))
+		return NULL;
+	_rv = DataHGetDataRefExtension(dh,
+	                               &extension,
+	                               idType);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     ResObj_New, extension);
+	return _res;
+}
+
+static PyObject *Qt_DataHGetMovieWithFlags(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	Movie theMovie;
+	short id;
+	short flags;
+#ifndef DataHGetMovieWithFlags
+	PyMac_PRECHECK(DataHGetMovieWithFlags);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      CmpInstObj_Convert, &dh,
+	                      &flags))
+		return NULL;
+	_rv = DataHGetMovieWithFlags(dh,
+	                             &theMovie,
+	                             &id,
+	                             flags);
+	_res = Py_BuildValue("lO&h",
+	                     _rv,
+	                     MovieObj_New, theMovie,
+	                     id);
+	return _res;
+}
+
+static PyObject *Qt_DataHGetFileTypeOrdering(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	DataHFileTypeOrderingHandle orderingListHandle;
+#ifndef DataHGetFileTypeOrdering
+	PyMac_PRECHECK(DataHGetFileTypeOrdering);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &dh))
+		return NULL;
+	_rv = DataHGetFileTypeOrdering(dh,
+	                               &orderingListHandle);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     ResObj_New, orderingListHandle);
+	return _res;
+}
+
+static PyObject *Qt_DataHCreateFileWithFlags(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	OSType creator;
+	Boolean deleteExisting;
+	UInt32 flags;
+#ifndef DataHCreateFileWithFlags
+	PyMac_PRECHECK(DataHCreateFileWithFlags);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&bl",
+	                      CmpInstObj_Convert, &dh,
+	                      PyMac_GetOSType, &creator,
+	                      &deleteExisting,
+	                      &flags))
+		return NULL;
+	_rv = DataHCreateFileWithFlags(dh,
+	                               creator,
+	                               deleteExisting,
+	                               flags);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_DataHGetInfo(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	OSType what;
+	void * info;
+#ifndef DataHGetInfo
+	PyMac_PRECHECK(DataHGetInfo);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&s",
+	                      CmpInstObj_Convert, &dh,
+	                      PyMac_GetOSType, &what,
+	                      &info))
+		return NULL;
+	_rv = DataHGetInfo(dh,
+	                   what,
+	                   info);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_DataHSetIdleManager(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	IdleManager im;
+#ifndef DataHSetIdleManager
+	PyMac_PRECHECK(DataHSetIdleManager);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpInstObj_Convert, &dh,
+	                      IdleManagerObj_Convert, &im))
+		return NULL;
+	_rv = DataHSetIdleManager(dh,
+	                          im);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_DataHDeleteFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+#ifndef DataHDeleteFile
+	PyMac_PRECHECK(DataHDeleteFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &dh))
+		return NULL;
+	_rv = DataHDeleteFile(dh);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_DataHSetMovieUsageFlags(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	long flags;
+#ifndef DataHSetMovieUsageFlags
+	PyMac_PRECHECK(DataHSetMovieUsageFlags);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &dh,
+	                      &flags))
+		return NULL;
+	_rv = DataHSetMovieUsageFlags(dh,
+	                              flags);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_DataHUseTemporaryDataRef(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	long inFlags;
+#ifndef DataHUseTemporaryDataRef
+	PyMac_PRECHECK(DataHUseTemporaryDataRef);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &dh,
+	                      &inFlags))
+		return NULL;
+	_rv = DataHUseTemporaryDataRef(dh,
+	                               inFlags);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_DataHGetTemporaryDataRefCapabilities(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	long outUnderstoodFlags;
+#ifndef DataHGetTemporaryDataRefCapabilities
+	PyMac_PRECHECK(DataHGetTemporaryDataRefCapabilities);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &dh))
+		return NULL;
+	_rv = DataHGetTemporaryDataRefCapabilities(dh,
+	                                           &outUnderstoodFlags);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     outUnderstoodFlags);
+	return _res;
+}
+
+static PyObject *Qt_DataHRenameFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	Handle newDataRef;
+#ifndef DataHRenameFile
+	PyMac_PRECHECK(DataHRenameFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpInstObj_Convert, &dh,
+	                      ResObj_Convert, &newDataRef))
+		return NULL;
+	_rv = DataHRenameFile(dh,
+	                      newDataRef);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_DataHPlaybackHints(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	long flags;
+	unsigned long minFileOffset;
+	unsigned long maxFileOffset;
+	long bytesPerSecond;
+#ifndef DataHPlaybackHints
+	PyMac_PRECHECK(DataHPlaybackHints);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&llll",
+	                      CmpInstObj_Convert, &dh,
+	                      &flags,
+	                      &minFileOffset,
+	                      &maxFileOffset,
+	                      &bytesPerSecond))
+		return NULL;
+	_rv = DataHPlaybackHints(dh,
+	                         flags,
+	                         minFileOffset,
+	                         maxFileOffset,
+	                         bytesPerSecond);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_DataHPlaybackHints64(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	long flags;
+	wide minFileOffset;
+	wide maxFileOffset;
+	long bytesPerSecond;
+#ifndef DataHPlaybackHints64
+	PyMac_PRECHECK(DataHPlaybackHints64);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&lO&O&l",
+	                      CmpInstObj_Convert, &dh,
+	                      &flags,
+	                      PyMac_Getwide, &minFileOffset,
+	                      PyMac_Getwide, &maxFileOffset,
+	                      &bytesPerSecond))
+		return NULL;
+	_rv = DataHPlaybackHints64(dh,
+	                           flags,
+	                           &minFileOffset,
+	                           &maxFileOffset,
+	                           bytesPerSecond);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_DataHGetDataRate(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	long flags;
+	long bytesPerSecond;
+#ifndef DataHGetDataRate
+	PyMac_PRECHECK(DataHGetDataRate);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &dh,
+	                      &flags))
+		return NULL;
+	_rv = DataHGetDataRate(dh,
+	                       flags,
+	                       &bytesPerSecond);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     bytesPerSecond);
+	return _res;
+}
+
+static PyObject *Qt_DataHSetTimeHints(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	DataHandler dh;
+	long flags;
+	long bandwidthPriority;
+	TimeScale scale;
+	TimeValue minTime;
+	TimeValue maxTime;
+#ifndef DataHSetTimeHints
+	PyMac_PRECHECK(DataHSetTimeHints);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&lllll",
+	                      CmpInstObj_Convert, &dh,
+	                      &flags,
+	                      &bandwidthPriority,
+	                      &scale,
+	                      &minTime,
+	                      &maxTime))
+		return NULL;
+	_rv = DataHSetTimeHints(dh,
+	                        flags,
+	                        bandwidthPriority,
+	                        scale,
+	                        minTime,
+	                        maxTime);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_VDGetMaxSrcRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	short inputStd;
+	Rect maxSrcRect;
+#ifndef VDGetMaxSrcRect
+	PyMac_PRECHECK(VDGetMaxSrcRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      CmpObj_Convert, &ci,
+	                      &inputStd))
+		return NULL;
+	_rv = VDGetMaxSrcRect(ci,
+	                      inputStd,
+	                      &maxSrcRect);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     PyMac_BuildRect, &maxSrcRect);
+	return _res;
+}
+
+static PyObject *Qt_VDGetActiveSrcRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	short inputStd;
+	Rect activeSrcRect;
+#ifndef VDGetActiveSrcRect
+	PyMac_PRECHECK(VDGetActiveSrcRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      CmpObj_Convert, &ci,
+	                      &inputStd))
+		return NULL;
+	_rv = VDGetActiveSrcRect(ci,
+	                         inputStd,
+	                         &activeSrcRect);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     PyMac_BuildRect, &activeSrcRect);
+	return _res;
+}
+
+static PyObject *Qt_VDSetDigitizerRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	Rect digitizerRect;
+#ifndef VDSetDigitizerRect
+	PyMac_PRECHECK(VDSetDigitizerRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = VDSetDigitizerRect(ci,
+	                         &digitizerRect);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     PyMac_BuildRect, &digitizerRect);
+	return _res;
+}
+
+static PyObject *Qt_VDGetDigitizerRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	Rect digitizerRect;
+#ifndef VDGetDigitizerRect
+	PyMac_PRECHECK(VDGetDigitizerRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = VDGetDigitizerRect(ci,
+	                         &digitizerRect);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     PyMac_BuildRect, &digitizerRect);
+	return _res;
+}
+
+static PyObject *Qt_VDGetVBlankRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	short inputStd;
+	Rect vBlankRect;
+#ifndef VDGetVBlankRect
+	PyMac_PRECHECK(VDGetVBlankRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      CmpObj_Convert, &ci,
+	                      &inputStd))
+		return NULL;
+	_rv = VDGetVBlankRect(ci,
+	                      inputStd,
+	                      &vBlankRect);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     PyMac_BuildRect, &vBlankRect);
+	return _res;
+}
+
+static PyObject *Qt_VDGetMaskPixMap(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	PixMapHandle maskPixMap;
+#ifndef VDGetMaskPixMap
+	PyMac_PRECHECK(VDGetMaskPixMap);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &ci,
+	                      ResObj_Convert, &maskPixMap))
+		return NULL;
+	_rv = VDGetMaskPixMap(ci,
+	                      maskPixMap);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_VDUseThisCLUT(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	CTabHandle colorTableHandle;
+#ifndef VDUseThisCLUT
+	PyMac_PRECHECK(VDUseThisCLUT);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &ci,
+	                      ResObj_Convert, &colorTableHandle))
+		return NULL;
+	_rv = VDUseThisCLUT(ci,
+	                    colorTableHandle);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_VDSetInputGammaValue(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	Fixed channel1;
+	Fixed channel2;
+	Fixed channel3;
+#ifndef VDSetInputGammaValue
+	PyMac_PRECHECK(VDSetInputGammaValue);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&O&",
+	                      CmpObj_Convert, &ci,
+	                      PyMac_GetFixed, &channel1,
+	                      PyMac_GetFixed, &channel2,
+	                      PyMac_GetFixed, &channel3))
+		return NULL;
+	_rv = VDSetInputGammaValue(ci,
+	                           channel1,
+	                           channel2,
+	                           channel3);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_VDGetInputGammaValue(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	Fixed channel1;
+	Fixed channel2;
+	Fixed channel3;
+#ifndef VDGetInputGammaValue
+	PyMac_PRECHECK(VDGetInputGammaValue);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = VDGetInputGammaValue(ci,
+	                           &channel1,
+	                           &channel2,
+	                           &channel3);
+	_res = Py_BuildValue("lO&O&O&",
+	                     _rv,
+	                     PyMac_BuildFixed, channel1,
+	                     PyMac_BuildFixed, channel2,
+	                     PyMac_BuildFixed, channel3);
+	return _res;
+}
+
+static PyObject *Qt_VDSetBrightness(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	unsigned short brightness;
+#ifndef VDSetBrightness
+	PyMac_PRECHECK(VDSetBrightness);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = VDSetBrightness(ci,
+	                      &brightness);
+	_res = Py_BuildValue("lH",
+	                     _rv,
+	                     brightness);
+	return _res;
+}
+
+static PyObject *Qt_VDGetBrightness(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	unsigned short brightness;
+#ifndef VDGetBrightness
+	PyMac_PRECHECK(VDGetBrightness);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = VDGetBrightness(ci,
+	                      &brightness);
+	_res = Py_BuildValue("lH",
+	                     _rv,
+	                     brightness);
+	return _res;
+}
+
+static PyObject *Qt_VDSetContrast(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	unsigned short contrast;
+#ifndef VDSetContrast
+	PyMac_PRECHECK(VDSetContrast);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = VDSetContrast(ci,
+	                    &contrast);
+	_res = Py_BuildValue("lH",
+	                     _rv,
+	                     contrast);
+	return _res;
+}
+
+static PyObject *Qt_VDSetHue(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	unsigned short hue;
+#ifndef VDSetHue
+	PyMac_PRECHECK(VDSetHue);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = VDSetHue(ci,
+	               &hue);
+	_res = Py_BuildValue("lH",
+	                     _rv,
+	                     hue);
+	return _res;
+}
+
+static PyObject *Qt_VDSetSharpness(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	unsigned short sharpness;
+#ifndef VDSetSharpness
+	PyMac_PRECHECK(VDSetSharpness);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = VDSetSharpness(ci,
+	                     &sharpness);
+	_res = Py_BuildValue("lH",
+	                     _rv,
+	                     sharpness);
+	return _res;
+}
+
+static PyObject *Qt_VDSetSaturation(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	unsigned short saturation;
+#ifndef VDSetSaturation
+	PyMac_PRECHECK(VDSetSaturation);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = VDSetSaturation(ci,
+	                      &saturation);
+	_res = Py_BuildValue("lH",
+	                     _rv,
+	                     saturation);
+	return _res;
+}
+
+static PyObject *Qt_VDGetContrast(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	unsigned short contrast;
+#ifndef VDGetContrast
+	PyMac_PRECHECK(VDGetContrast);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = VDGetContrast(ci,
+	                    &contrast);
+	_res = Py_BuildValue("lH",
+	                     _rv,
+	                     contrast);
+	return _res;
+}
+
+static PyObject *Qt_VDGetHue(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	unsigned short hue;
+#ifndef VDGetHue
+	PyMac_PRECHECK(VDGetHue);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = VDGetHue(ci,
+	               &hue);
+	_res = Py_BuildValue("lH",
+	                     _rv,
+	                     hue);
+	return _res;
+}
+
+static PyObject *Qt_VDGetSharpness(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	unsigned short sharpness;
+#ifndef VDGetSharpness
+	PyMac_PRECHECK(VDGetSharpness);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = VDGetSharpness(ci,
+	                     &sharpness);
+	_res = Py_BuildValue("lH",
+	                     _rv,
+	                     sharpness);
+	return _res;
+}
+
+static PyObject *Qt_VDGetSaturation(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	unsigned short saturation;
+#ifndef VDGetSaturation
+	PyMac_PRECHECK(VDGetSaturation);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = VDGetSaturation(ci,
+	                      &saturation);
+	_res = Py_BuildValue("lH",
+	                     _rv,
+	                     saturation);
+	return _res;
+}
+
+static PyObject *Qt_VDGrabOneFrame(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+#ifndef VDGrabOneFrame
+	PyMac_PRECHECK(VDGrabOneFrame);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = VDGrabOneFrame(ci);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_VDGetMaxAuxBuffer(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	PixMapHandle pm;
+	Rect r;
+#ifndef VDGetMaxAuxBuffer
+	PyMac_PRECHECK(VDGetMaxAuxBuffer);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = VDGetMaxAuxBuffer(ci,
+	                        &pm,
+	                        &r);
+	_res = Py_BuildValue("lO&O&",
+	                     _rv,
+	                     ResObj_New, pm,
+	                     PyMac_BuildRect, &r);
+	return _res;
+}
+
+static PyObject *Qt_VDGetCurrentFlags(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	long inputCurrentFlag;
+	long outputCurrentFlag;
+#ifndef VDGetCurrentFlags
+	PyMac_PRECHECK(VDGetCurrentFlags);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = VDGetCurrentFlags(ci,
+	                        &inputCurrentFlag,
+	                        &outputCurrentFlag);
+	_res = Py_BuildValue("lll",
+	                     _rv,
+	                     inputCurrentFlag,
+	                     outputCurrentFlag);
+	return _res;
+}
+
+static PyObject *Qt_VDSetKeyColor(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	long index;
+#ifndef VDSetKeyColor
+	PyMac_PRECHECK(VDSetKeyColor);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpObj_Convert, &ci,
+	                      &index))
+		return NULL;
+	_rv = VDSetKeyColor(ci,
+	                    index);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_VDGetKeyColor(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	long index;
+#ifndef VDGetKeyColor
+	PyMac_PRECHECK(VDGetKeyColor);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = VDGetKeyColor(ci,
+	                    &index);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     index);
+	return _res;
+}
+
+static PyObject *Qt_VDAddKeyColor(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	long index;
+#ifndef VDAddKeyColor
+	PyMac_PRECHECK(VDAddKeyColor);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = VDAddKeyColor(ci,
+	                    &index);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     index);
+	return _res;
+}
+
+static PyObject *Qt_VDGetNextKeyColor(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	long index;
+#ifndef VDGetNextKeyColor
+	PyMac_PRECHECK(VDGetNextKeyColor);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpObj_Convert, &ci,
+	                      &index))
+		return NULL;
+	_rv = VDGetNextKeyColor(ci,
+	                        index);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_VDSetKeyColorRange(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	RGBColor minRGB;
+	RGBColor maxRGB;
+#ifndef VDSetKeyColorRange
+	PyMac_PRECHECK(VDSetKeyColorRange);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = VDSetKeyColorRange(ci,
+	                         &minRGB,
+	                         &maxRGB);
+	_res = Py_BuildValue("lO&O&",
+	                     _rv,
+	                     QdRGB_New, &minRGB,
+	                     QdRGB_New, &maxRGB);
+	return _res;
+}
+
+static PyObject *Qt_VDGetKeyColorRange(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	RGBColor minRGB;
+	RGBColor maxRGB;
+#ifndef VDGetKeyColorRange
+	PyMac_PRECHECK(VDGetKeyColorRange);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = VDGetKeyColorRange(ci,
+	                         &minRGB,
+	                         &maxRGB);
+	_res = Py_BuildValue("lO&O&",
+	                     _rv,
+	                     QdRGB_New, &minRGB,
+	                     QdRGB_New, &maxRGB);
+	return _res;
+}
+
+static PyObject *Qt_VDSetInputColorSpaceMode(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	short colorSpaceMode;
+#ifndef VDSetInputColorSpaceMode
+	PyMac_PRECHECK(VDSetInputColorSpaceMode);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      CmpObj_Convert, &ci,
+	                      &colorSpaceMode))
+		return NULL;
+	_rv = VDSetInputColorSpaceMode(ci,
+	                               colorSpaceMode);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_VDGetInputColorSpaceMode(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	short colorSpaceMode;
+#ifndef VDGetInputColorSpaceMode
+	PyMac_PRECHECK(VDGetInputColorSpaceMode);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = VDGetInputColorSpaceMode(ci,
+	                               &colorSpaceMode);
+	_res = Py_BuildValue("lh",
+	                     _rv,
+	                     colorSpaceMode);
+	return _res;
+}
+
+static PyObject *Qt_VDSetClipState(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	short clipEnable;
+#ifndef VDSetClipState
+	PyMac_PRECHECK(VDSetClipState);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      CmpObj_Convert, &ci,
+	                      &clipEnable))
+		return NULL;
+	_rv = VDSetClipState(ci,
+	                     clipEnable);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_VDGetClipState(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	short clipEnable;
+#ifndef VDGetClipState
+	PyMac_PRECHECK(VDGetClipState);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = VDGetClipState(ci,
+	                     &clipEnable);
+	_res = Py_BuildValue("lh",
+	                     _rv,
+	                     clipEnable);
+	return _res;
+}
+
+static PyObject *Qt_VDSetClipRgn(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	RgnHandle clipRegion;
+#ifndef VDSetClipRgn
+	PyMac_PRECHECK(VDSetClipRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &ci,
+	                      ResObj_Convert, &clipRegion))
+		return NULL;
+	_rv = VDSetClipRgn(ci,
+	                   clipRegion);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_VDClearClipRgn(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	RgnHandle clipRegion;
+#ifndef VDClearClipRgn
+	PyMac_PRECHECK(VDClearClipRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &ci,
+	                      ResObj_Convert, &clipRegion))
+		return NULL;
+	_rv = VDClearClipRgn(ci,
+	                     clipRegion);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_VDGetCLUTInUse(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	CTabHandle colorTableHandle;
+#ifndef VDGetCLUTInUse
+	PyMac_PRECHECK(VDGetCLUTInUse);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = VDGetCLUTInUse(ci,
+	                     &colorTableHandle);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     ResObj_New, colorTableHandle);
+	return _res;
+}
+
+static PyObject *Qt_VDSetPLLFilterType(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	short pllType;
+#ifndef VDSetPLLFilterType
+	PyMac_PRECHECK(VDSetPLLFilterType);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      CmpObj_Convert, &ci,
+	                      &pllType))
+		return NULL;
+	_rv = VDSetPLLFilterType(ci,
+	                         pllType);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_VDGetPLLFilterType(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	short pllType;
+#ifndef VDGetPLLFilterType
+	PyMac_PRECHECK(VDGetPLLFilterType);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = VDGetPLLFilterType(ci,
+	                         &pllType);
+	_res = Py_BuildValue("lh",
+	                     _rv,
+	                     pllType);
+	return _res;
+}
+
+static PyObject *Qt_VDGetMaskandValue(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	unsigned short blendLevel;
+	long mask;
+	long value;
+#ifndef VDGetMaskandValue
+	PyMac_PRECHECK(VDGetMaskandValue);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&H",
+	                      CmpObj_Convert, &ci,
+	                      &blendLevel))
+		return NULL;
+	_rv = VDGetMaskandValue(ci,
+	                        blendLevel,
+	                        &mask,
+	                        &value);
+	_res = Py_BuildValue("lll",
+	                     _rv,
+	                     mask,
+	                     value);
+	return _res;
+}
+
+static PyObject *Qt_VDSetMasterBlendLevel(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	unsigned short blendLevel;
+#ifndef VDSetMasterBlendLevel
+	PyMac_PRECHECK(VDSetMasterBlendLevel);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = VDSetMasterBlendLevel(ci,
+	                            &blendLevel);
+	_res = Py_BuildValue("lH",
+	                     _rv,
+	                     blendLevel);
+	return _res;
+}
+
+static PyObject *Qt_VDSetPlayThruOnOff(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	short state;
+#ifndef VDSetPlayThruOnOff
+	PyMac_PRECHECK(VDSetPlayThruOnOff);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      CmpObj_Convert, &ci,
+	                      &state))
+		return NULL;
+	_rv = VDSetPlayThruOnOff(ci,
+	                         state);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_VDSetFieldPreference(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	short fieldFlag;
+#ifndef VDSetFieldPreference
+	PyMac_PRECHECK(VDSetFieldPreference);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      CmpObj_Convert, &ci,
+	                      &fieldFlag))
+		return NULL;
+	_rv = VDSetFieldPreference(ci,
+	                           fieldFlag);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_VDGetFieldPreference(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	short fieldFlag;
+#ifndef VDGetFieldPreference
+	PyMac_PRECHECK(VDGetFieldPreference);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = VDGetFieldPreference(ci,
+	                           &fieldFlag);
+	_res = Py_BuildValue("lh",
+	                     _rv,
+	                     fieldFlag);
+	return _res;
+}
+
+static PyObject *Qt_VDPreflightGlobalRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	GrafPtr theWindow;
+	Rect globalRect;
+#ifndef VDPreflightGlobalRect
+	PyMac_PRECHECK(VDPreflightGlobalRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &ci,
+	                      GrafObj_Convert, &theWindow))
+		return NULL;
+	_rv = VDPreflightGlobalRect(ci,
+	                            theWindow,
+	                            &globalRect);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     PyMac_BuildRect, &globalRect);
+	return _res;
+}
+
+static PyObject *Qt_VDSetPlayThruGlobalRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	GrafPtr theWindow;
+	Rect globalRect;
+#ifndef VDSetPlayThruGlobalRect
+	PyMac_PRECHECK(VDSetPlayThruGlobalRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &ci,
+	                      GrafObj_Convert, &theWindow))
+		return NULL;
+	_rv = VDSetPlayThruGlobalRect(ci,
+	                              theWindow,
+	                              &globalRect);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     PyMac_BuildRect, &globalRect);
+	return _res;
+}
+
+static PyObject *Qt_VDSetBlackLevelValue(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	unsigned short blackLevel;
+#ifndef VDSetBlackLevelValue
+	PyMac_PRECHECK(VDSetBlackLevelValue);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = VDSetBlackLevelValue(ci,
+	                           &blackLevel);
+	_res = Py_BuildValue("lH",
+	                     _rv,
+	                     blackLevel);
+	return _res;
+}
+
+static PyObject *Qt_VDGetBlackLevelValue(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	unsigned short blackLevel;
+#ifndef VDGetBlackLevelValue
+	PyMac_PRECHECK(VDGetBlackLevelValue);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = VDGetBlackLevelValue(ci,
+	                           &blackLevel);
+	_res = Py_BuildValue("lH",
+	                     _rv,
+	                     blackLevel);
+	return _res;
+}
+
+static PyObject *Qt_VDSetWhiteLevelValue(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	unsigned short whiteLevel;
+#ifndef VDSetWhiteLevelValue
+	PyMac_PRECHECK(VDSetWhiteLevelValue);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = VDSetWhiteLevelValue(ci,
+	                           &whiteLevel);
+	_res = Py_BuildValue("lH",
+	                     _rv,
+	                     whiteLevel);
+	return _res;
+}
+
+static PyObject *Qt_VDGetWhiteLevelValue(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	unsigned short whiteLevel;
+#ifndef VDGetWhiteLevelValue
+	PyMac_PRECHECK(VDGetWhiteLevelValue);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = VDGetWhiteLevelValue(ci,
+	                           &whiteLevel);
+	_res = Py_BuildValue("lH",
+	                     _rv,
+	                     whiteLevel);
+	return _res;
+}
+
+static PyObject *Qt_VDGetVideoDefaults(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	unsigned short blackLevel;
+	unsigned short whiteLevel;
+	unsigned short brightness;
+	unsigned short hue;
+	unsigned short saturation;
+	unsigned short contrast;
+	unsigned short sharpness;
+#ifndef VDGetVideoDefaults
+	PyMac_PRECHECK(VDGetVideoDefaults);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = VDGetVideoDefaults(ci,
+	                         &blackLevel,
+	                         &whiteLevel,
+	                         &brightness,
+	                         &hue,
+	                         &saturation,
+	                         &contrast,
+	                         &sharpness);
+	_res = Py_BuildValue("lHHHHHHH",
+	                     _rv,
+	                     blackLevel,
+	                     whiteLevel,
+	                     brightness,
+	                     hue,
+	                     saturation,
+	                     contrast,
+	                     sharpness);
+	return _res;
+}
+
+static PyObject *Qt_VDGetNumberOfInputs(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	short inputs;
+#ifndef VDGetNumberOfInputs
+	PyMac_PRECHECK(VDGetNumberOfInputs);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = VDGetNumberOfInputs(ci,
+	                          &inputs);
+	_res = Py_BuildValue("lh",
+	                     _rv,
+	                     inputs);
+	return _res;
+}
+
+static PyObject *Qt_VDGetInputFormat(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	short input;
+	short format;
+#ifndef VDGetInputFormat
+	PyMac_PRECHECK(VDGetInputFormat);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      CmpObj_Convert, &ci,
+	                      &input))
+		return NULL;
+	_rv = VDGetInputFormat(ci,
+	                       input,
+	                       &format);
+	_res = Py_BuildValue("lh",
+	                     _rv,
+	                     format);
+	return _res;
+}
+
+static PyObject *Qt_VDSetInput(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	short input;
+#ifndef VDSetInput
+	PyMac_PRECHECK(VDSetInput);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      CmpObj_Convert, &ci,
+	                      &input))
+		return NULL;
+	_rv = VDSetInput(ci,
+	                 input);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_VDGetInput(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	short input;
+#ifndef VDGetInput
+	PyMac_PRECHECK(VDGetInput);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = VDGetInput(ci,
+	                 &input);
+	_res = Py_BuildValue("lh",
+	                     _rv,
+	                     input);
+	return _res;
+}
+
+static PyObject *Qt_VDSetInputStandard(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	short inputStandard;
+#ifndef VDSetInputStandard
+	PyMac_PRECHECK(VDSetInputStandard);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      CmpObj_Convert, &ci,
+	                      &inputStandard))
+		return NULL;
+	_rv = VDSetInputStandard(ci,
+	                         inputStandard);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_VDSetupBuffers(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	VdigBufferRecListHandle bufferList;
+#ifndef VDSetupBuffers
+	PyMac_PRECHECK(VDSetupBuffers);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &ci,
+	                      ResObj_Convert, &bufferList))
+		return NULL;
+	_rv = VDSetupBuffers(ci,
+	                     bufferList);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_VDGrabOneFrameAsync(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	short buffer;
+#ifndef VDGrabOneFrameAsync
+	PyMac_PRECHECK(VDGrabOneFrameAsync);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      CmpObj_Convert, &ci,
+	                      &buffer))
+		return NULL;
+	_rv = VDGrabOneFrameAsync(ci,
+	                          buffer);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_VDDone(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	short buffer;
+#ifndef VDDone
+	PyMac_PRECHECK(VDDone);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      CmpObj_Convert, &ci,
+	                      &buffer))
+		return NULL;
+	_rv = VDDone(ci,
+	             buffer);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_VDSetCompression(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	OSType compressType;
+	short depth;
+	Rect bounds;
+	CodecQ spatialQuality;
+	CodecQ temporalQuality;
+	long keyFrameRate;
+#ifndef VDSetCompression
+	PyMac_PRECHECK(VDSetCompression);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&hlll",
+	                      CmpObj_Convert, &ci,
+	                      PyMac_GetOSType, &compressType,
+	                      &depth,
+	                      &spatialQuality,
+	                      &temporalQuality,
+	                      &keyFrameRate))
+		return NULL;
+	_rv = VDSetCompression(ci,
+	                       compressType,
+	                       depth,
+	                       &bounds,
+	                       spatialQuality,
+	                       temporalQuality,
+	                       keyFrameRate);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     PyMac_BuildRect, &bounds);
+	return _res;
+}
+
+static PyObject *Qt_VDCompressOneFrameAsync(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+#ifndef VDCompressOneFrameAsync
+	PyMac_PRECHECK(VDCompressOneFrameAsync);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = VDCompressOneFrameAsync(ci);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_VDGetImageDescription(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	ImageDescriptionHandle desc;
+#ifndef VDGetImageDescription
+	PyMac_PRECHECK(VDGetImageDescription);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &ci,
+	                      ResObj_Convert, &desc))
+		return NULL;
+	_rv = VDGetImageDescription(ci,
+	                            desc);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_VDResetCompressSequence(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+#ifndef VDResetCompressSequence
+	PyMac_PRECHECK(VDResetCompressSequence);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = VDResetCompressSequence(ci);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_VDSetCompressionOnOff(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	Boolean state;
+#ifndef VDSetCompressionOnOff
+	PyMac_PRECHECK(VDSetCompressionOnOff);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&b",
+	                      CmpObj_Convert, &ci,
+	                      &state))
+		return NULL;
+	_rv = VDSetCompressionOnOff(ci,
+	                            state);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_VDGetCompressionTypes(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	VDCompressionListHandle h;
+#ifndef VDGetCompressionTypes
+	PyMac_PRECHECK(VDGetCompressionTypes);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &ci,
+	                      ResObj_Convert, &h))
+		return NULL;
+	_rv = VDGetCompressionTypes(ci,
+	                            h);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_VDSetTimeBase(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	TimeBase t;
+#ifndef VDSetTimeBase
+	PyMac_PRECHECK(VDSetTimeBase);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &ci,
+	                      TimeBaseObj_Convert, &t))
+		return NULL;
+	_rv = VDSetTimeBase(ci,
+	                    t);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_VDSetFrameRate(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	Fixed framesPerSecond;
+#ifndef VDSetFrameRate
+	PyMac_PRECHECK(VDSetFrameRate);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &ci,
+	                      PyMac_GetFixed, &framesPerSecond))
+		return NULL;
+	_rv = VDSetFrameRate(ci,
+	                     framesPerSecond);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_VDGetDataRate(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	long milliSecPerFrame;
+	Fixed framesPerSecond;
+	long bytesPerSecond;
+#ifndef VDGetDataRate
+	PyMac_PRECHECK(VDGetDataRate);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = VDGetDataRate(ci,
+	                    &milliSecPerFrame,
+	                    &framesPerSecond,
+	                    &bytesPerSecond);
+	_res = Py_BuildValue("llO&l",
+	                     _rv,
+	                     milliSecPerFrame,
+	                     PyMac_BuildFixed, framesPerSecond,
+	                     bytesPerSecond);
+	return _res;
+}
+
+static PyObject *Qt_VDGetSoundInputDriver(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	Str255 soundDriverName;
+#ifndef VDGetSoundInputDriver
+	PyMac_PRECHECK(VDGetSoundInputDriver);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &ci,
+	                      PyMac_GetStr255, soundDriverName))
+		return NULL;
+	_rv = VDGetSoundInputDriver(ci,
+	                            soundDriverName);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_VDGetDMADepths(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	long depthArray;
+	long preferredDepth;
+#ifndef VDGetDMADepths
+	PyMac_PRECHECK(VDGetDMADepths);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = VDGetDMADepths(ci,
+	                     &depthArray,
+	                     &preferredDepth);
+	_res = Py_BuildValue("lll",
+	                     _rv,
+	                     depthArray,
+	                     preferredDepth);
+	return _res;
+}
+
+static PyObject *Qt_VDGetPreferredTimeScale(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	TimeScale preferred;
+#ifndef VDGetPreferredTimeScale
+	PyMac_PRECHECK(VDGetPreferredTimeScale);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = VDGetPreferredTimeScale(ci,
+	                              &preferred);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     preferred);
+	return _res;
+}
+
+static PyObject *Qt_VDReleaseAsyncBuffers(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+#ifndef VDReleaseAsyncBuffers
+	PyMac_PRECHECK(VDReleaseAsyncBuffers);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = VDReleaseAsyncBuffers(ci);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_VDSetDataRate(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	long bytesPerSecond;
+#ifndef VDSetDataRate
+	PyMac_PRECHECK(VDSetDataRate);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpObj_Convert, &ci,
+	                      &bytesPerSecond))
+		return NULL;
+	_rv = VDSetDataRate(ci,
+	                    bytesPerSecond);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_VDGetTimeCode(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	TimeRecord atTime;
+	void * timeCodeFormat;
+	void * timeCodeTime;
+#ifndef VDGetTimeCode
+	PyMac_PRECHECK(VDGetTimeCode);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&ss",
+	                      CmpObj_Convert, &ci,
+	                      &timeCodeFormat,
+	                      &timeCodeTime))
+		return NULL;
+	_rv = VDGetTimeCode(ci,
+	                    &atTime,
+	                    timeCodeFormat,
+	                    timeCodeTime);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     QtTimeRecord_New, &atTime);
+	return _res;
+}
+
+static PyObject *Qt_VDUseSafeBuffers(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	Boolean useSafeBuffers;
+#ifndef VDUseSafeBuffers
+	PyMac_PRECHECK(VDUseSafeBuffers);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&b",
+	                      CmpObj_Convert, &ci,
+	                      &useSafeBuffers))
+		return NULL;
+	_rv = VDUseSafeBuffers(ci,
+	                       useSafeBuffers);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_VDGetSoundInputSource(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	long videoInput;
+	long soundInput;
+#ifndef VDGetSoundInputSource
+	PyMac_PRECHECK(VDGetSoundInputSource);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpObj_Convert, &ci,
+	                      &videoInput))
+		return NULL;
+	_rv = VDGetSoundInputSource(ci,
+	                            videoInput,
+	                            &soundInput);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     soundInput);
+	return _res;
+}
+
+static PyObject *Qt_VDGetCompressionTime(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	OSType compressionType;
+	short depth;
+	Rect srcRect;
+	CodecQ spatialQuality;
+	CodecQ temporalQuality;
+	unsigned long compressTime;
+#ifndef VDGetCompressionTime
+	PyMac_PRECHECK(VDGetCompressionTime);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&h",
+	                      CmpObj_Convert, &ci,
+	                      PyMac_GetOSType, &compressionType,
+	                      &depth))
+		return NULL;
+	_rv = VDGetCompressionTime(ci,
+	                           compressionType,
+	                           depth,
+	                           &srcRect,
+	                           &spatialQuality,
+	                           &temporalQuality,
+	                           &compressTime);
+	_res = Py_BuildValue("lO&lll",
+	                     _rv,
+	                     PyMac_BuildRect, &srcRect,
+	                     spatialQuality,
+	                     temporalQuality,
+	                     compressTime);
+	return _res;
+}
+
+static PyObject *Qt_VDSetPreferredPacketSize(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	long preferredPacketSizeInBytes;
+#ifndef VDSetPreferredPacketSize
+	PyMac_PRECHECK(VDSetPreferredPacketSize);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpObj_Convert, &ci,
+	                      &preferredPacketSizeInBytes))
+		return NULL;
+	_rv = VDSetPreferredPacketSize(ci,
+	                               preferredPacketSizeInBytes);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_VDSetPreferredImageDimensions(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	long width;
+	long height;
+#ifndef VDSetPreferredImageDimensions
+	PyMac_PRECHECK(VDSetPreferredImageDimensions);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&ll",
+	                      CmpObj_Convert, &ci,
+	                      &width,
+	                      &height))
+		return NULL;
+	_rv = VDSetPreferredImageDimensions(ci,
+	                                    width,
+	                                    height);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_VDGetPreferredImageDimensions(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	long width;
+	long height;
+#ifndef VDGetPreferredImageDimensions
+	PyMac_PRECHECK(VDGetPreferredImageDimensions);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &ci))
+		return NULL;
+	_rv = VDGetPreferredImageDimensions(ci,
+	                                    &width,
+	                                    &height);
+	_res = Py_BuildValue("lll",
+	                     _rv,
+	                     width,
+	                     height);
+	return _res;
+}
+
+static PyObject *Qt_VDGetInputName(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	long videoInput;
+	Str255 name;
+#ifndef VDGetInputName
+	PyMac_PRECHECK(VDGetInputName);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&lO&",
+	                      CmpObj_Convert, &ci,
+	                      &videoInput,
+	                      PyMac_GetStr255, name))
+		return NULL;
+	_rv = VDGetInputName(ci,
+	                     videoInput,
+	                     name);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_VDSetDestinationPort(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	CGrafPtr destPort;
+#ifndef VDSetDestinationPort
+	PyMac_PRECHECK(VDSetDestinationPort);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &ci,
+	                      GrafObj_Convert, &destPort))
+		return NULL;
+	_rv = VDSetDestinationPort(ci,
+	                           destPort);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_VDGetDeviceNameAndFlags(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	Str255 outName;
+	UInt32 outNameFlags;
+#ifndef VDGetDeviceNameAndFlags
+	PyMac_PRECHECK(VDGetDeviceNameAndFlags);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &ci,
+	                      PyMac_GetStr255, outName))
+		return NULL;
+	_rv = VDGetDeviceNameAndFlags(ci,
+	                              outName,
+	                              &outNameFlags);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     outNameFlags);
+	return _res;
+}
+
+static PyObject *Qt_VDCaptureStateChanging(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	VideoDigitizerComponent ci;
+	UInt32 inStateFlags;
+#ifndef VDCaptureStateChanging
+	PyMac_PRECHECK(VDCaptureStateChanging);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpObj_Convert, &ci,
+	                      &inStateFlags))
+		return NULL;
+	_rv = VDCaptureStateChanging(ci,
+	                             inStateFlags);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_XMLParseGetDetailedParseError(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	ComponentInstance aParser;
+	long errorLine;
+	StringPtr errDesc;
+#ifndef XMLParseGetDetailedParseError
+	PyMac_PRECHECK(XMLParseGetDetailedParseError);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&s",
+	                      CmpInstObj_Convert, &aParser,
+	                      &errDesc))
+		return NULL;
+	_rv = XMLParseGetDetailedParseError(aParser,
+	                                    &errorLine,
+	                                    errDesc);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     errorLine);
+	return _res;
+}
+
+static PyObject *Qt_XMLParseAddElement(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	ComponentInstance aParser;
+	char elementName;
+	UInt32 nameSpaceID;
+	UInt32 elementID;
+	long elementFlags;
+#ifndef XMLParseAddElement
+	PyMac_PRECHECK(XMLParseAddElement);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&ll",
+	                      CmpInstObj_Convert, &aParser,
+	                      &nameSpaceID,
+	                      &elementFlags))
+		return NULL;
+	_rv = XMLParseAddElement(aParser,
+	                         &elementName,
+	                         nameSpaceID,
+	                         &elementID,
+	                         elementFlags);
+	_res = Py_BuildValue("lcl",
+	                     _rv,
+	                     elementName,
+	                     elementID);
+	return _res;
+}
+
+static PyObject *Qt_XMLParseAddAttribute(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	ComponentInstance aParser;
+	UInt32 elementID;
+	UInt32 nameSpaceID;
+	char attributeName;
+	UInt32 attributeID;
+#ifndef XMLParseAddAttribute
+	PyMac_PRECHECK(XMLParseAddAttribute);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&ll",
+	                      CmpInstObj_Convert, &aParser,
+	                      &elementID,
+	                      &nameSpaceID))
+		return NULL;
+	_rv = XMLParseAddAttribute(aParser,
+	                           elementID,
+	                           nameSpaceID,
+	                           &attributeName,
+	                           &attributeID);
+	_res = Py_BuildValue("lcl",
+	                     _rv,
+	                     attributeName,
+	                     attributeID);
+	return _res;
+}
+
+static PyObject *Qt_XMLParseAddMultipleAttributes(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	ComponentInstance aParser;
+	UInt32 elementID;
+	UInt32 nameSpaceIDs;
+	char attributeNames;
+	UInt32 attributeIDs;
+#ifndef XMLParseAddMultipleAttributes
+	PyMac_PRECHECK(XMLParseAddMultipleAttributes);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &aParser,
+	                      &elementID))
+		return NULL;
+	_rv = XMLParseAddMultipleAttributes(aParser,
+	                                    elementID,
+	                                    &nameSpaceIDs,
+	                                    &attributeNames,
+	                                    &attributeIDs);
+	_res = Py_BuildValue("llcl",
+	                     _rv,
+	                     nameSpaceIDs,
+	                     attributeNames,
+	                     attributeIDs);
+	return _res;
+}
+
+static PyObject *Qt_XMLParseAddAttributeAndValue(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	ComponentInstance aParser;
+	UInt32 elementID;
+	UInt32 nameSpaceID;
+	char attributeName;
+	UInt32 attributeID;
+	UInt32 attributeValueKind;
+	void * attributeValueKindInfo;
+#ifndef XMLParseAddAttributeAndValue
+	PyMac_PRECHECK(XMLParseAddAttributeAndValue);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&llls",
+	                      CmpInstObj_Convert, &aParser,
+	                      &elementID,
+	                      &nameSpaceID,
+	                      &attributeValueKind,
+	                      &attributeValueKindInfo))
+		return NULL;
+	_rv = XMLParseAddAttributeAndValue(aParser,
+	                                   elementID,
+	                                   nameSpaceID,
+	                                   &attributeName,
+	                                   &attributeID,
+	                                   attributeValueKind,
+	                                   attributeValueKindInfo);
+	_res = Py_BuildValue("lcl",
+	                     _rv,
+	                     attributeName,
+	                     attributeID);
+	return _res;
+}
+
+static PyObject *Qt_XMLParseAddAttributeValueKind(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	ComponentInstance aParser;
+	UInt32 elementID;
+	UInt32 attributeID;
+	UInt32 attributeValueKind;
+	void * attributeValueKindInfo;
+#ifndef XMLParseAddAttributeValueKind
+	PyMac_PRECHECK(XMLParseAddAttributeValueKind);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&llls",
+	                      CmpInstObj_Convert, &aParser,
+	                      &elementID,
+	                      &attributeID,
+	                      &attributeValueKind,
+	                      &attributeValueKindInfo))
+		return NULL;
+	_rv = XMLParseAddAttributeValueKind(aParser,
+	                                    elementID,
+	                                    attributeID,
+	                                    attributeValueKind,
+	                                    attributeValueKindInfo);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_XMLParseAddNameSpace(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	ComponentInstance aParser;
+	char nameSpaceURL;
+	UInt32 nameSpaceID;
+#ifndef XMLParseAddNameSpace
+	PyMac_PRECHECK(XMLParseAddNameSpace);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &aParser))
+		return NULL;
+	_rv = XMLParseAddNameSpace(aParser,
+	                           &nameSpaceURL,
+	                           &nameSpaceID);
+	_res = Py_BuildValue("lcl",
+	                     _rv,
+	                     nameSpaceURL,
+	                     nameSpaceID);
+	return _res;
+}
+
+static PyObject *Qt_XMLParseSetOffsetAndLimit(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	ComponentInstance aParser;
+	UInt32 offset;
+	UInt32 limit;
+#ifndef XMLParseSetOffsetAndLimit
+	PyMac_PRECHECK(XMLParseSetOffsetAndLimit);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&ll",
+	                      CmpInstObj_Convert, &aParser,
+	                      &offset,
+	                      &limit))
+		return NULL;
+	_rv = XMLParseSetOffsetAndLimit(aParser,
+	                                offset,
+	                                limit);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_XMLParseSetEventParseRefCon(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	ComponentInstance aParser;
+	long refcon;
+#ifndef XMLParseSetEventParseRefCon
+	PyMac_PRECHECK(XMLParseSetEventParseRefCon);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &aParser,
+	                      &refcon))
+		return NULL;
+	_rv = XMLParseSetEventParseRefCon(aParser,
+	                                  refcon);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGInitialize(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+#ifndef SGInitialize
+	PyMac_PRECHECK(SGInitialize);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &s))
+		return NULL;
+	_rv = SGInitialize(s);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGSetDataOutput(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	FSSpec movieFile;
+	long whereFlags;
+#ifndef SGSetDataOutput
+	PyMac_PRECHECK(SGSetDataOutput);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&l",
+	                      CmpObj_Convert, &s,
+	                      PyMac_GetFSSpec, &movieFile,
+	                      &whereFlags))
+		return NULL;
+	_rv = SGSetDataOutput(s,
+	                      &movieFile,
+	                      whereFlags);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGGetDataOutput(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	FSSpec movieFile;
+	long whereFlags;
+#ifndef SGGetDataOutput
+	PyMac_PRECHECK(SGGetDataOutput);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &s,
+	                      PyMac_GetFSSpec, &movieFile))
+		return NULL;
+	_rv = SGGetDataOutput(s,
+	                      &movieFile,
+	                      &whereFlags);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     whereFlags);
+	return _res;
+}
+
+static PyObject *Qt_SGSetGWorld(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	CGrafPtr gp;
+	GDHandle gd;
+#ifndef SGSetGWorld
+	PyMac_PRECHECK(SGSetGWorld);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      CmpObj_Convert, &s,
+	                      GrafObj_Convert, &gp,
+	                      OptResObj_Convert, &gd))
+		return NULL;
+	_rv = SGSetGWorld(s,
+	                  gp,
+	                  gd);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGGetGWorld(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	CGrafPtr gp;
+	GDHandle gd;
+#ifndef SGGetGWorld
+	PyMac_PRECHECK(SGGetGWorld);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &s))
+		return NULL;
+	_rv = SGGetGWorld(s,
+	                  &gp,
+	                  &gd);
+	_res = Py_BuildValue("lO&O&",
+	                     _rv,
+	                     GrafObj_New, gp,
+	                     OptResObj_New, gd);
+	return _res;
+}
+
+static PyObject *Qt_SGNewChannel(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	OSType channelType;
+	SGChannel ref;
+#ifndef SGNewChannel
+	PyMac_PRECHECK(SGNewChannel);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &s,
+	                      PyMac_GetOSType, &channelType))
+		return NULL;
+	_rv = SGNewChannel(s,
+	                   channelType,
+	                   &ref);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     CmpInstObj_New, ref);
+	return _res;
+}
+
+static PyObject *Qt_SGDisposeChannel(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	SGChannel c;
+#ifndef SGDisposeChannel
+	PyMac_PRECHECK(SGDisposeChannel);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &s,
+	                      CmpInstObj_Convert, &c))
+		return NULL;
+	_rv = SGDisposeChannel(s,
+	                       c);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGStartPreview(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+#ifndef SGStartPreview
+	PyMac_PRECHECK(SGStartPreview);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &s))
+		return NULL;
+	_rv = SGStartPreview(s);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGStartRecord(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+#ifndef SGStartRecord
+	PyMac_PRECHECK(SGStartRecord);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &s))
+		return NULL;
+	_rv = SGStartRecord(s);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGIdle(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+#ifndef SGIdle
+	PyMac_PRECHECK(SGIdle);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &s))
+		return NULL;
+	_rv = SGIdle(s);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGStop(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+#ifndef SGStop
+	PyMac_PRECHECK(SGStop);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &s))
+		return NULL;
+	_rv = SGStop(s);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGPause(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	Boolean pause;
+#ifndef SGPause
+	PyMac_PRECHECK(SGPause);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&b",
+	                      CmpObj_Convert, &s,
+	                      &pause))
+		return NULL;
+	_rv = SGPause(s,
+	              pause);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGPrepare(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	Boolean prepareForPreview;
+	Boolean prepareForRecord;
+#ifndef SGPrepare
+	PyMac_PRECHECK(SGPrepare);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&bb",
+	                      CmpObj_Convert, &s,
+	                      &prepareForPreview,
+	                      &prepareForRecord))
+		return NULL;
+	_rv = SGPrepare(s,
+	                prepareForPreview,
+	                prepareForRecord);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGRelease(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+#ifndef SGRelease
+	PyMac_PRECHECK(SGRelease);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &s))
+		return NULL;
+	_rv = SGRelease(s);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGGetMovie(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Movie _rv;
+	SeqGrabComponent s;
+#ifndef SGGetMovie
+	PyMac_PRECHECK(SGGetMovie);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &s))
+		return NULL;
+	_rv = SGGetMovie(s);
+	_res = Py_BuildValue("O&",
+	                     MovieObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGSetMaximumRecordTime(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	unsigned long ticks;
+#ifndef SGSetMaximumRecordTime
+	PyMac_PRECHECK(SGSetMaximumRecordTime);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpObj_Convert, &s,
+	                      &ticks))
+		return NULL;
+	_rv = SGSetMaximumRecordTime(s,
+	                             ticks);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGGetMaximumRecordTime(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	unsigned long ticks;
+#ifndef SGGetMaximumRecordTime
+	PyMac_PRECHECK(SGGetMaximumRecordTime);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &s))
+		return NULL;
+	_rv = SGGetMaximumRecordTime(s,
+	                             &ticks);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     ticks);
+	return _res;
+}
+
+static PyObject *Qt_SGGetStorageSpaceRemaining(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	unsigned long bytes;
+#ifndef SGGetStorageSpaceRemaining
+	PyMac_PRECHECK(SGGetStorageSpaceRemaining);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &s))
+		return NULL;
+	_rv = SGGetStorageSpaceRemaining(s,
+	                                 &bytes);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     bytes);
+	return _res;
+}
+
+static PyObject *Qt_SGGetTimeRemaining(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	long ticksLeft;
+#ifndef SGGetTimeRemaining
+	PyMac_PRECHECK(SGGetTimeRemaining);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &s))
+		return NULL;
+	_rv = SGGetTimeRemaining(s,
+	                         &ticksLeft);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     ticksLeft);
+	return _res;
+}
+
+static PyObject *Qt_SGGrabPict(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	PicHandle p;
+	Rect bounds;
+	short offscreenDepth;
+	long grabPictFlags;
+#ifndef SGGrabPict
+	PyMac_PRECHECK(SGGrabPict);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&hl",
+	                      CmpObj_Convert, &s,
+	                      PyMac_GetRect, &bounds,
+	                      &offscreenDepth,
+	                      &grabPictFlags))
+		return NULL;
+	_rv = SGGrabPict(s,
+	                 &p,
+	                 &bounds,
+	                 offscreenDepth,
+	                 grabPictFlags);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     ResObj_New, p);
+	return _res;
+}
+
+static PyObject *Qt_SGGetLastMovieResID(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	short resID;
+#ifndef SGGetLastMovieResID
+	PyMac_PRECHECK(SGGetLastMovieResID);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &s))
+		return NULL;
+	_rv = SGGetLastMovieResID(s,
+	                          &resID);
+	_res = Py_BuildValue("lh",
+	                     _rv,
+	                     resID);
+	return _res;
+}
+
+static PyObject *Qt_SGSetFlags(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	long sgFlags;
+#ifndef SGSetFlags
+	PyMac_PRECHECK(SGSetFlags);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpObj_Convert, &s,
+	                      &sgFlags))
+		return NULL;
+	_rv = SGSetFlags(s,
+	                 sgFlags);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGGetFlags(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	long sgFlags;
+#ifndef SGGetFlags
+	PyMac_PRECHECK(SGGetFlags);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &s))
+		return NULL;
+	_rv = SGGetFlags(s,
+	                 &sgFlags);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     sgFlags);
+	return _res;
+}
+
+static PyObject *Qt_SGNewChannelFromComponent(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	SGChannel newChannel;
+	Component sgChannelComponent;
+#ifndef SGNewChannelFromComponent
+	PyMac_PRECHECK(SGNewChannelFromComponent);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &s,
+	                      CmpObj_Convert, &sgChannelComponent))
+		return NULL;
+	_rv = SGNewChannelFromComponent(s,
+	                                &newChannel,
+	                                sgChannelComponent);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     CmpInstObj_New, newChannel);
+	return _res;
+}
+
+static PyObject *Qt_SGSetSettings(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	UserData ud;
+	long flags;
+#ifndef SGSetSettings
+	PyMac_PRECHECK(SGSetSettings);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&l",
+	                      CmpObj_Convert, &s,
+	                      UserDataObj_Convert, &ud,
+	                      &flags))
+		return NULL;
+	_rv = SGSetSettings(s,
+	                    ud,
+	                    flags);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGGetSettings(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	UserData ud;
+	long flags;
+#ifndef SGGetSettings
+	PyMac_PRECHECK(SGGetSettings);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpObj_Convert, &s,
+	                      &flags))
+		return NULL;
+	_rv = SGGetSettings(s,
+	                    &ud,
+	                    flags);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     UserDataObj_New, ud);
+	return _res;
+}
+
+static PyObject *Qt_SGGetIndChannel(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	short index;
+	SGChannel ref;
+	OSType chanType;
+#ifndef SGGetIndChannel
+	PyMac_PRECHECK(SGGetIndChannel);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      CmpObj_Convert, &s,
+	                      &index))
+		return NULL;
+	_rv = SGGetIndChannel(s,
+	                      index,
+	                      &ref,
+	                      &chanType);
+	_res = Py_BuildValue("lO&O&",
+	                     _rv,
+	                     CmpInstObj_New, ref,
+	                     PyMac_BuildOSType, chanType);
+	return _res;
+}
+
+static PyObject *Qt_SGUpdate(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	RgnHandle updateRgn;
+#ifndef SGUpdate
+	PyMac_PRECHECK(SGUpdate);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &s,
+	                      ResObj_Convert, &updateRgn))
+		return NULL;
+	_rv = SGUpdate(s,
+	               updateRgn);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGGetPause(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	Boolean paused;
+#ifndef SGGetPause
+	PyMac_PRECHECK(SGGetPause);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &s))
+		return NULL;
+	_rv = SGGetPause(s,
+	                 &paused);
+	_res = Py_BuildValue("lb",
+	                     _rv,
+	                     paused);
+	return _res;
+}
+
+static PyObject *Qt_SGSetChannelSettings(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	SGChannel c;
+	UserData ud;
+	long flags;
+#ifndef SGSetChannelSettings
+	PyMac_PRECHECK(SGSetChannelSettings);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&l",
+	                      CmpObj_Convert, &s,
+	                      CmpInstObj_Convert, &c,
+	                      UserDataObj_Convert, &ud,
+	                      &flags))
+		return NULL;
+	_rv = SGSetChannelSettings(s,
+	                           c,
+	                           ud,
+	                           flags);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGGetChannelSettings(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	SGChannel c;
+	UserData ud;
+	long flags;
+#ifndef SGGetChannelSettings
+	PyMac_PRECHECK(SGGetChannelSettings);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&l",
+	                      CmpObj_Convert, &s,
+	                      CmpInstObj_Convert, &c,
+	                      &flags))
+		return NULL;
+	_rv = SGGetChannelSettings(s,
+	                           c,
+	                           &ud,
+	                           flags);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     UserDataObj_New, ud);
+	return _res;
+}
+
+static PyObject *Qt_SGGetMode(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	Boolean previewMode;
+	Boolean recordMode;
+#ifndef SGGetMode
+	PyMac_PRECHECK(SGGetMode);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &s))
+		return NULL;
+	_rv = SGGetMode(s,
+	                &previewMode,
+	                &recordMode);
+	_res = Py_BuildValue("lbb",
+	                     _rv,
+	                     previewMode,
+	                     recordMode);
+	return _res;
+}
+
+static PyObject *Qt_SGSetDataRef(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	Handle dataRef;
+	OSType dataRefType;
+	long whereFlags;
+#ifndef SGSetDataRef
+	PyMac_PRECHECK(SGSetDataRef);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&l",
+	                      CmpObj_Convert, &s,
+	                      ResObj_Convert, &dataRef,
+	                      PyMac_GetOSType, &dataRefType,
+	                      &whereFlags))
+		return NULL;
+	_rv = SGSetDataRef(s,
+	                   dataRef,
+	                   dataRefType,
+	                   whereFlags);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGGetDataRef(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	Handle dataRef;
+	OSType dataRefType;
+	long whereFlags;
+#ifndef SGGetDataRef
+	PyMac_PRECHECK(SGGetDataRef);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &s))
+		return NULL;
+	_rv = SGGetDataRef(s,
+	                   &dataRef,
+	                   &dataRefType,
+	                   &whereFlags);
+	_res = Py_BuildValue("lO&O&l",
+	                     _rv,
+	                     ResObj_New, dataRef,
+	                     PyMac_BuildOSType, dataRefType,
+	                     whereFlags);
+	return _res;
+}
+
+static PyObject *Qt_SGNewOutput(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	Handle dataRef;
+	OSType dataRefType;
+	long whereFlags;
+	SGOutput sgOut;
+#ifndef SGNewOutput
+	PyMac_PRECHECK(SGNewOutput);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&l",
+	                      CmpObj_Convert, &s,
+	                      ResObj_Convert, &dataRef,
+	                      PyMac_GetOSType, &dataRefType,
+	                      &whereFlags))
+		return NULL;
+	_rv = SGNewOutput(s,
+	                  dataRef,
+	                  dataRefType,
+	                  whereFlags,
+	                  &sgOut);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     SGOutputObj_New, sgOut);
+	return _res;
+}
+
+static PyObject *Qt_SGDisposeOutput(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	SGOutput sgOut;
+#ifndef SGDisposeOutput
+	PyMac_PRECHECK(SGDisposeOutput);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &s,
+	                      SGOutputObj_Convert, &sgOut))
+		return NULL;
+	_rv = SGDisposeOutput(s,
+	                      sgOut);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGSetOutputFlags(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	SGOutput sgOut;
+	long whereFlags;
+#ifndef SGSetOutputFlags
+	PyMac_PRECHECK(SGSetOutputFlags);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&l",
+	                      CmpObj_Convert, &s,
+	                      SGOutputObj_Convert, &sgOut,
+	                      &whereFlags))
+		return NULL;
+	_rv = SGSetOutputFlags(s,
+	                       sgOut,
+	                       whereFlags);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGSetChannelOutput(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	SGChannel c;
+	SGOutput sgOut;
+#ifndef SGSetChannelOutput
+	PyMac_PRECHECK(SGSetChannelOutput);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      CmpObj_Convert, &s,
+	                      CmpInstObj_Convert, &c,
+	                      SGOutputObj_Convert, &sgOut))
+		return NULL;
+	_rv = SGSetChannelOutput(s,
+	                         c,
+	                         sgOut);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGGetDataOutputStorageSpaceRemaining(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	SGOutput sgOut;
+	unsigned long space;
+#ifndef SGGetDataOutputStorageSpaceRemaining
+	PyMac_PRECHECK(SGGetDataOutputStorageSpaceRemaining);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &s,
+	                      SGOutputObj_Convert, &sgOut))
+		return NULL;
+	_rv = SGGetDataOutputStorageSpaceRemaining(s,
+	                                           sgOut,
+	                                           &space);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     space);
+	return _res;
+}
+
+static PyObject *Qt_SGHandleUpdateEvent(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	EventRecord event;
+	Boolean handled;
+#ifndef SGHandleUpdateEvent
+	PyMac_PRECHECK(SGHandleUpdateEvent);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &s,
+	                      PyMac_GetEventRecord, &event))
+		return NULL;
+	_rv = SGHandleUpdateEvent(s,
+	                          &event,
+	                          &handled);
+	_res = Py_BuildValue("lb",
+	                     _rv,
+	                     handled);
+	return _res;
+}
+
+static PyObject *Qt_SGSetOutputNextOutput(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	SGOutput sgOut;
+	SGOutput nextOut;
+#ifndef SGSetOutputNextOutput
+	PyMac_PRECHECK(SGSetOutputNextOutput);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      CmpObj_Convert, &s,
+	                      SGOutputObj_Convert, &sgOut,
+	                      SGOutputObj_Convert, &nextOut))
+		return NULL;
+	_rv = SGSetOutputNextOutput(s,
+	                            sgOut,
+	                            nextOut);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGGetOutputNextOutput(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	SGOutput sgOut;
+	SGOutput nextOut;
+#ifndef SGGetOutputNextOutput
+	PyMac_PRECHECK(SGGetOutputNextOutput);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &s,
+	                      SGOutputObj_Convert, &sgOut))
+		return NULL;
+	_rv = SGGetOutputNextOutput(s,
+	                            sgOut,
+	                            &nextOut);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     SGOutputObj_New, nextOut);
+	return _res;
+}
+
+static PyObject *Qt_SGSetOutputMaximumOffset(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	SGOutput sgOut;
+	wide maxOffset;
+#ifndef SGSetOutputMaximumOffset
+	PyMac_PRECHECK(SGSetOutputMaximumOffset);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      CmpObj_Convert, &s,
+	                      SGOutputObj_Convert, &sgOut,
+	                      PyMac_Getwide, &maxOffset))
+		return NULL;
+	_rv = SGSetOutputMaximumOffset(s,
+	                               sgOut,
+	                               &maxOffset);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGGetOutputMaximumOffset(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	SGOutput sgOut;
+	wide maxOffset;
+#ifndef SGGetOutputMaximumOffset
+	PyMac_PRECHECK(SGGetOutputMaximumOffset);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &s,
+	                      SGOutputObj_Convert, &sgOut))
+		return NULL;
+	_rv = SGGetOutputMaximumOffset(s,
+	                               sgOut,
+	                               &maxOffset);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     PyMac_Buildwide, maxOffset);
+	return _res;
+}
+
+static PyObject *Qt_SGGetOutputDataReference(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	SGOutput sgOut;
+	Handle dataRef;
+	OSType dataRefType;
+#ifndef SGGetOutputDataReference
+	PyMac_PRECHECK(SGGetOutputDataReference);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &s,
+	                      SGOutputObj_Convert, &sgOut))
+		return NULL;
+	_rv = SGGetOutputDataReference(s,
+	                               sgOut,
+	                               &dataRef,
+	                               &dataRefType);
+	_res = Py_BuildValue("lO&O&",
+	                     _rv,
+	                     ResObj_New, dataRef,
+	                     PyMac_BuildOSType, dataRefType);
+	return _res;
+}
+
+static PyObject *Qt_SGWriteExtendedMovieData(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	SGChannel c;
+	Ptr p;
+	long len;
+	wide offset;
+	SGOutput sgOut;
+#ifndef SGWriteExtendedMovieData
+	PyMac_PRECHECK(SGWriteExtendedMovieData);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&sl",
+	                      CmpObj_Convert, &s,
+	                      CmpInstObj_Convert, &c,
+	                      &p,
+	                      &len))
+		return NULL;
+	_rv = SGWriteExtendedMovieData(s,
+	                               c,
+	                               p,
+	                               len,
+	                               &offset,
+	                               &sgOut);
+	_res = Py_BuildValue("lO&O&",
+	                     _rv,
+	                     PyMac_Buildwide, offset,
+	                     SGOutputObj_New, sgOut);
+	return _res;
+}
+
+static PyObject *Qt_SGGetStorageSpaceRemaining64(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	wide bytes;
+#ifndef SGGetStorageSpaceRemaining64
+	PyMac_PRECHECK(SGGetStorageSpaceRemaining64);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &s))
+		return NULL;
+	_rv = SGGetStorageSpaceRemaining64(s,
+	                                   &bytes);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     PyMac_Buildwide, bytes);
+	return _res;
+}
+
+static PyObject *Qt_SGGetDataOutputStorageSpaceRemaining64(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	SGOutput sgOut;
+	wide space;
+#ifndef SGGetDataOutputStorageSpaceRemaining64
+	PyMac_PRECHECK(SGGetDataOutputStorageSpaceRemaining64);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &s,
+	                      SGOutputObj_Convert, &sgOut))
+		return NULL;
+	_rv = SGGetDataOutputStorageSpaceRemaining64(s,
+	                                             sgOut,
+	                                             &space);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     PyMac_Buildwide, space);
+	return _res;
+}
+
+static PyObject *Qt_SGWriteMovieData(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	SGChannel c;
+	Ptr p;
+	long len;
+	long offset;
+#ifndef SGWriteMovieData
+	PyMac_PRECHECK(SGWriteMovieData);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&sl",
+	                      CmpObj_Convert, &s,
+	                      CmpInstObj_Convert, &c,
+	                      &p,
+	                      &len))
+		return NULL;
+	_rv = SGWriteMovieData(s,
+	                       c,
+	                       p,
+	                       len,
+	                       &offset);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     offset);
+	return _res;
+}
+
+static PyObject *Qt_SGGetTimeBase(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	TimeBase tb;
+#ifndef SGGetTimeBase
+	PyMac_PRECHECK(SGGetTimeBase);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &s))
+		return NULL;
+	_rv = SGGetTimeBase(s,
+	                    &tb);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     TimeBaseObj_New, tb);
+	return _res;
+}
+
+static PyObject *Qt_SGAddMovieData(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	SGChannel c;
+	Ptr p;
+	long len;
+	long offset;
+	long chRefCon;
+	TimeValue time;
+	short writeType;
+#ifndef SGAddMovieData
+	PyMac_PRECHECK(SGAddMovieData);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&slllh",
+	                      CmpObj_Convert, &s,
+	                      CmpInstObj_Convert, &c,
+	                      &p,
+	                      &len,
+	                      &chRefCon,
+	                      &time,
+	                      &writeType))
+		return NULL;
+	_rv = SGAddMovieData(s,
+	                     c,
+	                     p,
+	                     len,
+	                     &offset,
+	                     chRefCon,
+	                     time,
+	                     writeType);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     offset);
+	return _res;
+}
+
+static PyObject *Qt_SGChangedSource(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	SGChannel c;
+#ifndef SGChangedSource
+	PyMac_PRECHECK(SGChangedSource);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &s,
+	                      CmpInstObj_Convert, &c))
+		return NULL;
+	_rv = SGChangedSource(s,
+	                      c);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGAddExtendedMovieData(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	SGChannel c;
+	Ptr p;
+	long len;
+	wide offset;
+	long chRefCon;
+	TimeValue time;
+	short writeType;
+	SGOutput whichOutput;
+#ifndef SGAddExtendedMovieData
+	PyMac_PRECHECK(SGAddExtendedMovieData);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&slllh",
+	                      CmpObj_Convert, &s,
+	                      CmpInstObj_Convert, &c,
+	                      &p,
+	                      &len,
+	                      &chRefCon,
+	                      &time,
+	                      &writeType))
+		return NULL;
+	_rv = SGAddExtendedMovieData(s,
+	                             c,
+	                             p,
+	                             len,
+	                             &offset,
+	                             chRefCon,
+	                             time,
+	                             writeType,
+	                             &whichOutput);
+	_res = Py_BuildValue("lO&O&",
+	                     _rv,
+	                     PyMac_Buildwide, offset,
+	                     SGOutputObj_New, whichOutput);
+	return _res;
+}
+
+static PyObject *Qt_SGAddOutputDataRefToMedia(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	SGOutput sgOut;
+	Media theMedia;
+	SampleDescriptionHandle desc;
+#ifndef SGAddOutputDataRefToMedia
+	PyMac_PRECHECK(SGAddOutputDataRefToMedia);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&O&",
+	                      CmpObj_Convert, &s,
+	                      SGOutputObj_Convert, &sgOut,
+	                      MediaObj_Convert, &theMedia,
+	                      ResObj_Convert, &desc))
+		return NULL;
+	_rv = SGAddOutputDataRefToMedia(s,
+	                                sgOut,
+	                                theMedia,
+	                                desc);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGSetSettingsSummary(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	Handle summaryText;
+#ifndef SGSetSettingsSummary
+	PyMac_PRECHECK(SGSetSettingsSummary);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &s,
+	                      ResObj_Convert, &summaryText))
+		return NULL;
+	_rv = SGSetSettingsSummary(s,
+	                           summaryText);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGSetChannelUsage(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	long usage;
+#ifndef SGSetChannelUsage
+	PyMac_PRECHECK(SGSetChannelUsage);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &c,
+	                      &usage))
+		return NULL;
+	_rv = SGSetChannelUsage(c,
+	                        usage);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGGetChannelUsage(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	long usage;
+#ifndef SGGetChannelUsage
+	PyMac_PRECHECK(SGGetChannelUsage);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &c))
+		return NULL;
+	_rv = SGGetChannelUsage(c,
+	                        &usage);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     usage);
+	return _res;
+}
+
+static PyObject *Qt_SGSetChannelBounds(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	Rect bounds;
+#ifndef SGSetChannelBounds
+	PyMac_PRECHECK(SGSetChannelBounds);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpInstObj_Convert, &c,
+	                      PyMac_GetRect, &bounds))
+		return NULL;
+	_rv = SGSetChannelBounds(c,
+	                         &bounds);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGGetChannelBounds(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	Rect bounds;
+#ifndef SGGetChannelBounds
+	PyMac_PRECHECK(SGGetChannelBounds);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &c))
+		return NULL;
+	_rv = SGGetChannelBounds(c,
+	                         &bounds);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     PyMac_BuildRect, &bounds);
+	return _res;
+}
+
+static PyObject *Qt_SGSetChannelVolume(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	short volume;
+#ifndef SGSetChannelVolume
+	PyMac_PRECHECK(SGSetChannelVolume);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      CmpInstObj_Convert, &c,
+	                      &volume))
+		return NULL;
+	_rv = SGSetChannelVolume(c,
+	                         volume);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGGetChannelVolume(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	short volume;
+#ifndef SGGetChannelVolume
+	PyMac_PRECHECK(SGGetChannelVolume);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &c))
+		return NULL;
+	_rv = SGGetChannelVolume(c,
+	                         &volume);
+	_res = Py_BuildValue("lh",
+	                     _rv,
+	                     volume);
+	return _res;
+}
+
+static PyObject *Qt_SGGetChannelInfo(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	long channelInfo;
+#ifndef SGGetChannelInfo
+	PyMac_PRECHECK(SGGetChannelInfo);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &c))
+		return NULL;
+	_rv = SGGetChannelInfo(c,
+	                       &channelInfo);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     channelInfo);
+	return _res;
+}
+
+static PyObject *Qt_SGSetChannelPlayFlags(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	long playFlags;
+#ifndef SGSetChannelPlayFlags
+	PyMac_PRECHECK(SGSetChannelPlayFlags);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &c,
+	                      &playFlags))
+		return NULL;
+	_rv = SGSetChannelPlayFlags(c,
+	                            playFlags);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGGetChannelPlayFlags(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	long playFlags;
+#ifndef SGGetChannelPlayFlags
+	PyMac_PRECHECK(SGGetChannelPlayFlags);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &c))
+		return NULL;
+	_rv = SGGetChannelPlayFlags(c,
+	                            &playFlags);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     playFlags);
+	return _res;
+}
+
+static PyObject *Qt_SGSetChannelMaxFrames(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	long frameCount;
+#ifndef SGSetChannelMaxFrames
+	PyMac_PRECHECK(SGSetChannelMaxFrames);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &c,
+	                      &frameCount))
+		return NULL;
+	_rv = SGSetChannelMaxFrames(c,
+	                            frameCount);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGGetChannelMaxFrames(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	long frameCount;
+#ifndef SGGetChannelMaxFrames
+	PyMac_PRECHECK(SGGetChannelMaxFrames);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &c))
+		return NULL;
+	_rv = SGGetChannelMaxFrames(c,
+	                            &frameCount);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     frameCount);
+	return _res;
+}
+
+static PyObject *Qt_SGSetChannelRefCon(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	long refCon;
+#ifndef SGSetChannelRefCon
+	PyMac_PRECHECK(SGSetChannelRefCon);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &c,
+	                      &refCon))
+		return NULL;
+	_rv = SGSetChannelRefCon(c,
+	                         refCon);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGSetChannelClip(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	RgnHandle theClip;
+#ifndef SGSetChannelClip
+	PyMac_PRECHECK(SGSetChannelClip);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpInstObj_Convert, &c,
+	                      ResObj_Convert, &theClip))
+		return NULL;
+	_rv = SGSetChannelClip(c,
+	                       theClip);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGGetChannelClip(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	RgnHandle theClip;
+#ifndef SGGetChannelClip
+	PyMac_PRECHECK(SGGetChannelClip);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &c))
+		return NULL;
+	_rv = SGGetChannelClip(c,
+	                       &theClip);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     ResObj_New, theClip);
+	return _res;
+}
+
+static PyObject *Qt_SGGetChannelSampleDescription(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	Handle sampleDesc;
+#ifndef SGGetChannelSampleDescription
+	PyMac_PRECHECK(SGGetChannelSampleDescription);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpInstObj_Convert, &c,
+	                      ResObj_Convert, &sampleDesc))
+		return NULL;
+	_rv = SGGetChannelSampleDescription(c,
+	                                    sampleDesc);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGSetChannelDevice(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	StringPtr name;
+#ifndef SGSetChannelDevice
+	PyMac_PRECHECK(SGSetChannelDevice);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&s",
+	                      CmpInstObj_Convert, &c,
+	                      &name))
+		return NULL;
+	_rv = SGSetChannelDevice(c,
+	                         name);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGGetChannelTimeScale(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	TimeScale scale;
+#ifndef SGGetChannelTimeScale
+	PyMac_PRECHECK(SGGetChannelTimeScale);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &c))
+		return NULL;
+	_rv = SGGetChannelTimeScale(c,
+	                            &scale);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     scale);
+	return _res;
+}
+
+static PyObject *Qt_SGChannelPutPicture(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+#ifndef SGChannelPutPicture
+	PyMac_PRECHECK(SGChannelPutPicture);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &c))
+		return NULL;
+	_rv = SGChannelPutPicture(c);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGChannelSetRequestedDataRate(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	long bytesPerSecond;
+#ifndef SGChannelSetRequestedDataRate
+	PyMac_PRECHECK(SGChannelSetRequestedDataRate);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &c,
+	                      &bytesPerSecond))
+		return NULL;
+	_rv = SGChannelSetRequestedDataRate(c,
+	                                    bytesPerSecond);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGChannelGetRequestedDataRate(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	long bytesPerSecond;
+#ifndef SGChannelGetRequestedDataRate
+	PyMac_PRECHECK(SGChannelGetRequestedDataRate);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &c))
+		return NULL;
+	_rv = SGChannelGetRequestedDataRate(c,
+	                                    &bytesPerSecond);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     bytesPerSecond);
+	return _res;
+}
+
+static PyObject *Qt_SGChannelSetDataSourceName(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	Str255 name;
+	ScriptCode scriptTag;
+#ifndef SGChannelSetDataSourceName
+	PyMac_PRECHECK(SGChannelSetDataSourceName);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&h",
+	                      CmpInstObj_Convert, &c,
+	                      PyMac_GetStr255, name,
+	                      &scriptTag))
+		return NULL;
+	_rv = SGChannelSetDataSourceName(c,
+	                                 name,
+	                                 scriptTag);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGChannelGetDataSourceName(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	Str255 name;
+	ScriptCode scriptTag;
+#ifndef SGChannelGetDataSourceName
+	PyMac_PRECHECK(SGChannelGetDataSourceName);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpInstObj_Convert, &c,
+	                      PyMac_GetStr255, name))
+		return NULL;
+	_rv = SGChannelGetDataSourceName(c,
+	                                 name,
+	                                 &scriptTag);
+	_res = Py_BuildValue("lh",
+	                     _rv,
+	                     scriptTag);
+	return _res;
+}
+
+static PyObject *Qt_SGChannelSetCodecSettings(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	Handle settings;
+#ifndef SGChannelSetCodecSettings
+	PyMac_PRECHECK(SGChannelSetCodecSettings);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpInstObj_Convert, &c,
+	                      ResObj_Convert, &settings))
+		return NULL;
+	_rv = SGChannelSetCodecSettings(c,
+	                                settings);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGChannelGetCodecSettings(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	Handle settings;
+#ifndef SGChannelGetCodecSettings
+	PyMac_PRECHECK(SGChannelGetCodecSettings);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &c))
+		return NULL;
+	_rv = SGChannelGetCodecSettings(c,
+	                                &settings);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     ResObj_New, settings);
+	return _res;
+}
+
+static PyObject *Qt_SGGetChannelTimeBase(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	TimeBase tb;
+#ifndef SGGetChannelTimeBase
+	PyMac_PRECHECK(SGGetChannelTimeBase);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &c))
+		return NULL;
+	_rv = SGGetChannelTimeBase(c,
+	                           &tb);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     TimeBaseObj_New, tb);
+	return _res;
+}
+
+static PyObject *Qt_SGGetChannelRefCon(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	long refCon;
+#ifndef SGGetChannelRefCon
+	PyMac_PRECHECK(SGGetChannelRefCon);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &c))
+		return NULL;
+	_rv = SGGetChannelRefCon(c,
+	                         &refCon);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     refCon);
+	return _res;
+}
+
+static PyObject *Qt_SGGetChannelDeviceAndInputNames(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	Str255 outDeviceName;
+	Str255 outInputName;
+	short outInputNumber;
+#ifndef SGGetChannelDeviceAndInputNames
+	PyMac_PRECHECK(SGGetChannelDeviceAndInputNames);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      CmpInstObj_Convert, &c,
+	                      PyMac_GetStr255, outDeviceName,
+	                      PyMac_GetStr255, outInputName))
+		return NULL;
+	_rv = SGGetChannelDeviceAndInputNames(c,
+	                                      outDeviceName,
+	                                      outInputName,
+	                                      &outInputNumber);
+	_res = Py_BuildValue("lh",
+	                     _rv,
+	                     outInputNumber);
+	return _res;
+}
+
+static PyObject *Qt_SGSetChannelDeviceInput(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	short inInputNumber;
+#ifndef SGSetChannelDeviceInput
+	PyMac_PRECHECK(SGSetChannelDeviceInput);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      CmpInstObj_Convert, &c,
+	                      &inInputNumber))
+		return NULL;
+	_rv = SGSetChannelDeviceInput(c,
+	                              inInputNumber);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGSetChannelSettingsStateChanging(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	UInt32 inFlags;
+#ifndef SGSetChannelSettingsStateChanging
+	PyMac_PRECHECK(SGSetChannelSettingsStateChanging);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &c,
+	                      &inFlags))
+		return NULL;
+	_rv = SGSetChannelSettingsStateChanging(c,
+	                                        inFlags);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGInitChannel(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	SeqGrabComponent owner;
+#ifndef SGInitChannel
+	PyMac_PRECHECK(SGInitChannel);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpInstObj_Convert, &c,
+	                      CmpObj_Convert, &owner))
+		return NULL;
+	_rv = SGInitChannel(c,
+	                    owner);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGWriteSamples(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	Movie m;
+	AliasHandle theFile;
+#ifndef SGWriteSamples
+	PyMac_PRECHECK(SGWriteSamples);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      CmpInstObj_Convert, &c,
+	                      MovieObj_Convert, &m,
+	                      ResObj_Convert, &theFile))
+		return NULL;
+	_rv = SGWriteSamples(c,
+	                     m,
+	                     theFile);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGGetDataRate(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	long bytesPerSecond;
+#ifndef SGGetDataRate
+	PyMac_PRECHECK(SGGetDataRate);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &c))
+		return NULL;
+	_rv = SGGetDataRate(c,
+	                    &bytesPerSecond);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     bytesPerSecond);
+	return _res;
+}
+
+static PyObject *Qt_SGAlignChannelRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	Rect r;
+#ifndef SGAlignChannelRect
+	PyMac_PRECHECK(SGAlignChannelRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &c))
+		return NULL;
+	_rv = SGAlignChannelRect(c,
+	                         &r);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     PyMac_BuildRect, &r);
+	return _res;
+}
+
+static PyObject *Qt_SGPanelGetDitl(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	Handle ditl;
+#ifndef SGPanelGetDitl
+	PyMac_PRECHECK(SGPanelGetDitl);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &s))
+		return NULL;
+	_rv = SGPanelGetDitl(s,
+	                     &ditl);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     ResObj_New, ditl);
+	return _res;
+}
+
+static PyObject *Qt_SGPanelGetTitle(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	Str255 title;
+#ifndef SGPanelGetTitle
+	PyMac_PRECHECK(SGPanelGetTitle);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &s,
+	                      PyMac_GetStr255, title))
+		return NULL;
+	_rv = SGPanelGetTitle(s,
+	                      title);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGPanelCanRun(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	SGChannel c;
+#ifndef SGPanelCanRun
+	PyMac_PRECHECK(SGPanelCanRun);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &s,
+	                      CmpInstObj_Convert, &c))
+		return NULL;
+	_rv = SGPanelCanRun(s,
+	                    c);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGPanelInstall(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	SGChannel c;
+	DialogPtr d;
+	short itemOffset;
+#ifndef SGPanelInstall
+	PyMac_PRECHECK(SGPanelInstall);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&h",
+	                      CmpObj_Convert, &s,
+	                      CmpInstObj_Convert, &c,
+	                      DlgObj_Convert, &d,
+	                      &itemOffset))
+		return NULL;
+	_rv = SGPanelInstall(s,
+	                     c,
+	                     d,
+	                     itemOffset);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGPanelEvent(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	SGChannel c;
+	DialogPtr d;
+	short itemOffset;
+	EventRecord theEvent;
+	short itemHit;
+	Boolean handled;
+#ifndef SGPanelEvent
+	PyMac_PRECHECK(SGPanelEvent);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&hO&",
+	                      CmpObj_Convert, &s,
+	                      CmpInstObj_Convert, &c,
+	                      DlgObj_Convert, &d,
+	                      &itemOffset,
+	                      PyMac_GetEventRecord, &theEvent))
+		return NULL;
+	_rv = SGPanelEvent(s,
+	                   c,
+	                   d,
+	                   itemOffset,
+	                   &theEvent,
+	                   &itemHit,
+	                   &handled);
+	_res = Py_BuildValue("lhb",
+	                     _rv,
+	                     itemHit,
+	                     handled);
+	return _res;
+}
+
+static PyObject *Qt_SGPanelItem(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	SGChannel c;
+	DialogPtr d;
+	short itemOffset;
+	short itemNum;
+#ifndef SGPanelItem
+	PyMac_PRECHECK(SGPanelItem);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&hh",
+	                      CmpObj_Convert, &s,
+	                      CmpInstObj_Convert, &c,
+	                      DlgObj_Convert, &d,
+	                      &itemOffset,
+	                      &itemNum))
+		return NULL;
+	_rv = SGPanelItem(s,
+	                  c,
+	                  d,
+	                  itemOffset,
+	                  itemNum);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGPanelRemove(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	SGChannel c;
+	DialogPtr d;
+	short itemOffset;
+#ifndef SGPanelRemove
+	PyMac_PRECHECK(SGPanelRemove);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&h",
+	                      CmpObj_Convert, &s,
+	                      CmpInstObj_Convert, &c,
+	                      DlgObj_Convert, &d,
+	                      &itemOffset))
+		return NULL;
+	_rv = SGPanelRemove(s,
+	                    c,
+	                    d,
+	                    itemOffset);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGPanelSetGrabber(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	SeqGrabComponent sg;
+#ifndef SGPanelSetGrabber
+	PyMac_PRECHECK(SGPanelSetGrabber);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &s,
+	                      CmpObj_Convert, &sg))
+		return NULL;
+	_rv = SGPanelSetGrabber(s,
+	                        sg);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGPanelSetResFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	short resRef;
+#ifndef SGPanelSetResFile
+	PyMac_PRECHECK(SGPanelSetResFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      CmpObj_Convert, &s,
+	                      &resRef))
+		return NULL;
+	_rv = SGPanelSetResFile(s,
+	                        resRef);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGPanelGetSettings(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	SGChannel c;
+	UserData ud;
+	long flags;
+#ifndef SGPanelGetSettings
+	PyMac_PRECHECK(SGPanelGetSettings);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&l",
+	                      CmpObj_Convert, &s,
+	                      CmpInstObj_Convert, &c,
+	                      &flags))
+		return NULL;
+	_rv = SGPanelGetSettings(s,
+	                         c,
+	                         &ud,
+	                         flags);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     UserDataObj_New, ud);
+	return _res;
+}
+
+static PyObject *Qt_SGPanelSetSettings(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	SGChannel c;
+	UserData ud;
+	long flags;
+#ifndef SGPanelSetSettings
+	PyMac_PRECHECK(SGPanelSetSettings);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&l",
+	                      CmpObj_Convert, &s,
+	                      CmpInstObj_Convert, &c,
+	                      UserDataObj_Convert, &ud,
+	                      &flags))
+		return NULL;
+	_rv = SGPanelSetSettings(s,
+	                         c,
+	                         ud,
+	                         flags);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGPanelValidateInput(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	Boolean ok;
+#ifndef SGPanelValidateInput
+	PyMac_PRECHECK(SGPanelValidateInput);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &s))
+		return NULL;
+	_rv = SGPanelValidateInput(s,
+	                           &ok);
+	_res = Py_BuildValue("lb",
+	                     _rv,
+	                     ok);
+	return _res;
+}
+
+static PyObject *Qt_SGPanelGetDITLForSize(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SeqGrabComponent s;
+	Handle ditl;
+	Point requestedSize;
+#ifndef SGPanelGetDITLForSize
+	PyMac_PRECHECK(SGPanelGetDITLForSize);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &s))
+		return NULL;
+	_rv = SGPanelGetDITLForSize(s,
+	                            &ditl,
+	                            &requestedSize);
+	_res = Py_BuildValue("lO&O&",
+	                     _rv,
+	                     ResObj_New, ditl,
+	                     PyMac_BuildPoint, requestedSize);
+	return _res;
+}
+
+static PyObject *Qt_SGGetSrcVideoBounds(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	Rect r;
+#ifndef SGGetSrcVideoBounds
+	PyMac_PRECHECK(SGGetSrcVideoBounds);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &c))
+		return NULL;
+	_rv = SGGetSrcVideoBounds(c,
+	                          &r);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     PyMac_BuildRect, &r);
+	return _res;
+}
+
+static PyObject *Qt_SGSetVideoRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	Rect r;
+#ifndef SGSetVideoRect
+	PyMac_PRECHECK(SGSetVideoRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpInstObj_Convert, &c,
+	                      PyMac_GetRect, &r))
+		return NULL;
+	_rv = SGSetVideoRect(c,
+	                     &r);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGGetVideoRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	Rect r;
+#ifndef SGGetVideoRect
+	PyMac_PRECHECK(SGGetVideoRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &c))
+		return NULL;
+	_rv = SGGetVideoRect(c,
+	                     &r);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     PyMac_BuildRect, &r);
+	return _res;
+}
+
+static PyObject *Qt_SGGetVideoCompressorType(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	OSType compressorType;
+#ifndef SGGetVideoCompressorType
+	PyMac_PRECHECK(SGGetVideoCompressorType);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &c))
+		return NULL;
+	_rv = SGGetVideoCompressorType(c,
+	                               &compressorType);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     PyMac_BuildOSType, compressorType);
+	return _res;
+}
+
+static PyObject *Qt_SGSetVideoCompressorType(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	OSType compressorType;
+#ifndef SGSetVideoCompressorType
+	PyMac_PRECHECK(SGSetVideoCompressorType);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpInstObj_Convert, &c,
+	                      PyMac_GetOSType, &compressorType))
+		return NULL;
+	_rv = SGSetVideoCompressorType(c,
+	                               compressorType);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGSetVideoCompressor(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	short depth;
+	CompressorComponent compressor;
+	CodecQ spatialQuality;
+	CodecQ temporalQuality;
+	long keyFrameRate;
+#ifndef SGSetVideoCompressor
+	PyMac_PRECHECK(SGSetVideoCompressor);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hO&lll",
+	                      CmpInstObj_Convert, &c,
+	                      &depth,
+	                      CmpObj_Convert, &compressor,
+	                      &spatialQuality,
+	                      &temporalQuality,
+	                      &keyFrameRate))
+		return NULL;
+	_rv = SGSetVideoCompressor(c,
+	                           depth,
+	                           compressor,
+	                           spatialQuality,
+	                           temporalQuality,
+	                           keyFrameRate);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGGetVideoCompressor(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	short depth;
+	CompressorComponent compressor;
+	CodecQ spatialQuality;
+	CodecQ temporalQuality;
+	long keyFrameRate;
+#ifndef SGGetVideoCompressor
+	PyMac_PRECHECK(SGGetVideoCompressor);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &c))
+		return NULL;
+	_rv = SGGetVideoCompressor(c,
+	                           &depth,
+	                           &compressor,
+	                           &spatialQuality,
+	                           &temporalQuality,
+	                           &keyFrameRate);
+	_res = Py_BuildValue("lhO&lll",
+	                     _rv,
+	                     depth,
+	                     CmpObj_New, compressor,
+	                     spatialQuality,
+	                     temporalQuality,
+	                     keyFrameRate);
+	return _res;
+}
+
+static PyObject *Qt_SGGetVideoDigitizerComponent(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentInstance _rv;
+	SGChannel c;
+#ifndef SGGetVideoDigitizerComponent
+	PyMac_PRECHECK(SGGetVideoDigitizerComponent);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &c))
+		return NULL;
+	_rv = SGGetVideoDigitizerComponent(c);
+	_res = Py_BuildValue("O&",
+	                     CmpInstObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGSetVideoDigitizerComponent(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	ComponentInstance vdig;
+#ifndef SGSetVideoDigitizerComponent
+	PyMac_PRECHECK(SGSetVideoDigitizerComponent);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpInstObj_Convert, &c,
+	                      CmpInstObj_Convert, &vdig))
+		return NULL;
+	_rv = SGSetVideoDigitizerComponent(c,
+	                                   vdig);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGVideoDigitizerChanged(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+#ifndef SGVideoDigitizerChanged
+	PyMac_PRECHECK(SGVideoDigitizerChanged);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &c))
+		return NULL;
+	_rv = SGVideoDigitizerChanged(c);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGGrabFrame(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	short bufferNum;
+#ifndef SGGrabFrame
+	PyMac_PRECHECK(SGGrabFrame);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      CmpInstObj_Convert, &c,
+	                      &bufferNum))
+		return NULL;
+	_rv = SGGrabFrame(c,
+	                  bufferNum);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGGrabFrameComplete(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	short bufferNum;
+	Boolean done;
+#ifndef SGGrabFrameComplete
+	PyMac_PRECHECK(SGGrabFrameComplete);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      CmpInstObj_Convert, &c,
+	                      &bufferNum))
+		return NULL;
+	_rv = SGGrabFrameComplete(c,
+	                          bufferNum,
+	                          &done);
+	_res = Py_BuildValue("lb",
+	                     _rv,
+	                     done);
+	return _res;
+}
+
+static PyObject *Qt_SGCompressFrame(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	short bufferNum;
+#ifndef SGCompressFrame
+	PyMac_PRECHECK(SGCompressFrame);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      CmpInstObj_Convert, &c,
+	                      &bufferNum))
+		return NULL;
+	_rv = SGCompressFrame(c,
+	                      bufferNum);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGSetCompressBuffer(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	short depth;
+	Rect compressSize;
+#ifndef SGSetCompressBuffer
+	PyMac_PRECHECK(SGSetCompressBuffer);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hO&",
+	                      CmpInstObj_Convert, &c,
+	                      &depth,
+	                      PyMac_GetRect, &compressSize))
+		return NULL;
+	_rv = SGSetCompressBuffer(c,
+	                          depth,
+	                          &compressSize);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGGetCompressBuffer(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	short depth;
+	Rect compressSize;
+#ifndef SGGetCompressBuffer
+	PyMac_PRECHECK(SGGetCompressBuffer);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &c))
+		return NULL;
+	_rv = SGGetCompressBuffer(c,
+	                          &depth,
+	                          &compressSize);
+	_res = Py_BuildValue("lhO&",
+	                     _rv,
+	                     depth,
+	                     PyMac_BuildRect, &compressSize);
+	return _res;
+}
+
+static PyObject *Qt_SGGetBufferInfo(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	short bufferNum;
+	PixMapHandle bufferPM;
+	Rect bufferRect;
+	GWorldPtr compressBuffer;
+	Rect compressBufferRect;
+#ifndef SGGetBufferInfo
+	PyMac_PRECHECK(SGGetBufferInfo);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      CmpInstObj_Convert, &c,
+	                      &bufferNum))
+		return NULL;
+	_rv = SGGetBufferInfo(c,
+	                      bufferNum,
+	                      &bufferPM,
+	                      &bufferRect,
+	                      &compressBuffer,
+	                      &compressBufferRect);
+	_res = Py_BuildValue("lO&O&O&O&",
+	                     _rv,
+	                     ResObj_New, bufferPM,
+	                     PyMac_BuildRect, &bufferRect,
+	                     GWorldObj_New, compressBuffer,
+	                     PyMac_BuildRect, &compressBufferRect);
+	return _res;
+}
+
+static PyObject *Qt_SGSetUseScreenBuffer(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	Boolean useScreenBuffer;
+#ifndef SGSetUseScreenBuffer
+	PyMac_PRECHECK(SGSetUseScreenBuffer);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&b",
+	                      CmpInstObj_Convert, &c,
+	                      &useScreenBuffer))
+		return NULL;
+	_rv = SGSetUseScreenBuffer(c,
+	                           useScreenBuffer);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGGetUseScreenBuffer(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	Boolean useScreenBuffer;
+#ifndef SGGetUseScreenBuffer
+	PyMac_PRECHECK(SGGetUseScreenBuffer);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &c))
+		return NULL;
+	_rv = SGGetUseScreenBuffer(c,
+	                           &useScreenBuffer);
+	_res = Py_BuildValue("lb",
+	                     _rv,
+	                     useScreenBuffer);
+	return _res;
+}
+
+static PyObject *Qt_SGSetFrameRate(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	Fixed frameRate;
+#ifndef SGSetFrameRate
+	PyMac_PRECHECK(SGSetFrameRate);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpInstObj_Convert, &c,
+	                      PyMac_GetFixed, &frameRate))
+		return NULL;
+	_rv = SGSetFrameRate(c,
+	                     frameRate);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGGetFrameRate(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	Fixed frameRate;
+#ifndef SGGetFrameRate
+	PyMac_PRECHECK(SGGetFrameRate);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &c))
+		return NULL;
+	_rv = SGGetFrameRate(c,
+	                     &frameRate);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     PyMac_BuildFixed, frameRate);
+	return _res;
+}
+
+static PyObject *Qt_SGSetPreferredPacketSize(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	long preferredPacketSizeInBytes;
+#ifndef SGSetPreferredPacketSize
+	PyMac_PRECHECK(SGSetPreferredPacketSize);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &c,
+	                      &preferredPacketSizeInBytes))
+		return NULL;
+	_rv = SGSetPreferredPacketSize(c,
+	                               preferredPacketSizeInBytes);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGGetPreferredPacketSize(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	long preferredPacketSizeInBytes;
+#ifndef SGGetPreferredPacketSize
+	PyMac_PRECHECK(SGGetPreferredPacketSize);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &c))
+		return NULL;
+	_rv = SGGetPreferredPacketSize(c,
+	                               &preferredPacketSizeInBytes);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     preferredPacketSizeInBytes);
+	return _res;
+}
+
+static PyObject *Qt_SGSetUserVideoCompressorList(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	Handle compressorTypes;
+#ifndef SGSetUserVideoCompressorList
+	PyMac_PRECHECK(SGSetUserVideoCompressorList);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpInstObj_Convert, &c,
+	                      ResObj_Convert, &compressorTypes))
+		return NULL;
+	_rv = SGSetUserVideoCompressorList(c,
+	                                   compressorTypes);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGGetUserVideoCompressorList(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	Handle compressorTypes;
+#ifndef SGGetUserVideoCompressorList
+	PyMac_PRECHECK(SGGetUserVideoCompressorList);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &c))
+		return NULL;
+	_rv = SGGetUserVideoCompressorList(c,
+	                                   &compressorTypes);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     ResObj_New, compressorTypes);
+	return _res;
+}
+
+static PyObject *Qt_SGSetSoundInputDriver(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	Str255 driverName;
+#ifndef SGSetSoundInputDriver
+	PyMac_PRECHECK(SGSetSoundInputDriver);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpInstObj_Convert, &c,
+	                      PyMac_GetStr255, driverName))
+		return NULL;
+	_rv = SGSetSoundInputDriver(c,
+	                            driverName);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGGetSoundInputDriver(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long _rv;
+	SGChannel c;
+#ifndef SGGetSoundInputDriver
+	PyMac_PRECHECK(SGGetSoundInputDriver);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &c))
+		return NULL;
+	_rv = SGGetSoundInputDriver(c);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGSoundInputDriverChanged(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+#ifndef SGSoundInputDriverChanged
+	PyMac_PRECHECK(SGSoundInputDriverChanged);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &c))
+		return NULL;
+	_rv = SGSoundInputDriverChanged(c);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGSetSoundRecordChunkSize(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	long seconds;
+#ifndef SGSetSoundRecordChunkSize
+	PyMac_PRECHECK(SGSetSoundRecordChunkSize);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &c,
+	                      &seconds))
+		return NULL;
+	_rv = SGSetSoundRecordChunkSize(c,
+	                                seconds);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGGetSoundRecordChunkSize(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long _rv;
+	SGChannel c;
+#ifndef SGGetSoundRecordChunkSize
+	PyMac_PRECHECK(SGGetSoundRecordChunkSize);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &c))
+		return NULL;
+	_rv = SGGetSoundRecordChunkSize(c);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGSetSoundInputRate(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	Fixed rate;
+#ifndef SGSetSoundInputRate
+	PyMac_PRECHECK(SGSetSoundInputRate);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpInstObj_Convert, &c,
+	                      PyMac_GetFixed, &rate))
+		return NULL;
+	_rv = SGSetSoundInputRate(c,
+	                          rate);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGGetSoundInputRate(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Fixed _rv;
+	SGChannel c;
+#ifndef SGGetSoundInputRate
+	PyMac_PRECHECK(SGGetSoundInputRate);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &c))
+		return NULL;
+	_rv = SGGetSoundInputRate(c);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildFixed, _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGSetSoundInputParameters(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	short sampleSize;
+	short numChannels;
+	OSType compressionType;
+#ifndef SGSetSoundInputParameters
+	PyMac_PRECHECK(SGSetSoundInputParameters);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hhO&",
+	                      CmpInstObj_Convert, &c,
+	                      &sampleSize,
+	                      &numChannels,
+	                      PyMac_GetOSType, &compressionType))
+		return NULL;
+	_rv = SGSetSoundInputParameters(c,
+	                                sampleSize,
+	                                numChannels,
+	                                compressionType);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGGetSoundInputParameters(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	short sampleSize;
+	short numChannels;
+	OSType compressionType;
+#ifndef SGGetSoundInputParameters
+	PyMac_PRECHECK(SGGetSoundInputParameters);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &c))
+		return NULL;
+	_rv = SGGetSoundInputParameters(c,
+	                                &sampleSize,
+	                                &numChannels,
+	                                &compressionType);
+	_res = Py_BuildValue("lhhO&",
+	                     _rv,
+	                     sampleSize,
+	                     numChannels,
+	                     PyMac_BuildOSType, compressionType);
+	return _res;
+}
+
+static PyObject *Qt_SGSetAdditionalSoundRates(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	Handle rates;
+#ifndef SGSetAdditionalSoundRates
+	PyMac_PRECHECK(SGSetAdditionalSoundRates);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpInstObj_Convert, &c,
+	                      ResObj_Convert, &rates))
+		return NULL;
+	_rv = SGSetAdditionalSoundRates(c,
+	                                rates);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGGetAdditionalSoundRates(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	Handle rates;
+#ifndef SGGetAdditionalSoundRates
+	PyMac_PRECHECK(SGGetAdditionalSoundRates);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &c))
+		return NULL;
+	_rv = SGGetAdditionalSoundRates(c,
+	                                &rates);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     ResObj_New, rates);
+	return _res;
+}
+
+static PyObject *Qt_SGSetFontName(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	StringPtr pstr;
+#ifndef SGSetFontName
+	PyMac_PRECHECK(SGSetFontName);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&s",
+	                      CmpInstObj_Convert, &c,
+	                      &pstr))
+		return NULL;
+	_rv = SGSetFontName(c,
+	                    pstr);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGSetFontSize(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	short fontSize;
+#ifndef SGSetFontSize
+	PyMac_PRECHECK(SGSetFontSize);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      CmpInstObj_Convert, &c,
+	                      &fontSize))
+		return NULL;
+	_rv = SGSetFontSize(c,
+	                    fontSize);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGSetTextForeColor(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	RGBColor theColor;
+#ifndef SGSetTextForeColor
+	PyMac_PRECHECK(SGSetTextForeColor);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &c))
+		return NULL;
+	_rv = SGSetTextForeColor(c,
+	                         &theColor);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     QdRGB_New, &theColor);
+	return _res;
+}
+
+static PyObject *Qt_SGSetTextBackColor(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	RGBColor theColor;
+#ifndef SGSetTextBackColor
+	PyMac_PRECHECK(SGSetTextBackColor);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &c))
+		return NULL;
+	_rv = SGSetTextBackColor(c,
+	                         &theColor);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     QdRGB_New, &theColor);
+	return _res;
+}
+
+static PyObject *Qt_SGSetJustification(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	short just;
+#ifndef SGSetJustification
+	PyMac_PRECHECK(SGSetJustification);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      CmpInstObj_Convert, &c,
+	                      &just))
+		return NULL;
+	_rv = SGSetJustification(c,
+	                         just);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_SGGetTextReturnToSpaceValue(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	short rettospace;
+#ifndef SGGetTextReturnToSpaceValue
+	PyMac_PRECHECK(SGGetTextReturnToSpaceValue);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &c))
+		return NULL;
+	_rv = SGGetTextReturnToSpaceValue(c,
+	                                  &rettospace);
+	_res = Py_BuildValue("lh",
+	                     _rv,
+	                     rettospace);
+	return _res;
+}
+
+static PyObject *Qt_SGSetTextReturnToSpaceValue(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	SGChannel c;
+	short rettospace;
+#ifndef SGSetTextReturnToSpaceValue
+	PyMac_PRECHECK(SGSetTextReturnToSpaceValue);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      CmpInstObj_Convert, &c,
+	                      &rettospace))
+		return NULL;
+	_rv = SGSetTextReturnToSpaceValue(c,
+	                                  rettospace);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_QTVideoOutputGetCurrentClientName(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	QTVideoOutputComponent vo;
+	Str255 str;
+#ifndef QTVideoOutputGetCurrentClientName
+	PyMac_PRECHECK(QTVideoOutputGetCurrentClientName);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &vo,
+	                      PyMac_GetStr255, str))
+		return NULL;
+	_rv = QTVideoOutputGetCurrentClientName(vo,
+	                                        str);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_QTVideoOutputSetClientName(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	QTVideoOutputComponent vo;
+	Str255 str;
+#ifndef QTVideoOutputSetClientName
+	PyMac_PRECHECK(QTVideoOutputSetClientName);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &vo,
+	                      PyMac_GetStr255, str))
+		return NULL;
+	_rv = QTVideoOutputSetClientName(vo,
+	                                 str);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_QTVideoOutputGetClientName(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	QTVideoOutputComponent vo;
+	Str255 str;
+#ifndef QTVideoOutputGetClientName
+	PyMac_PRECHECK(QTVideoOutputGetClientName);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &vo,
+	                      PyMac_GetStr255, str))
+		return NULL;
+	_rv = QTVideoOutputGetClientName(vo,
+	                                 str);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_QTVideoOutputBegin(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	QTVideoOutputComponent vo;
+#ifndef QTVideoOutputBegin
+	PyMac_PRECHECK(QTVideoOutputBegin);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &vo))
+		return NULL;
+	_rv = QTVideoOutputBegin(vo);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_QTVideoOutputEnd(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	QTVideoOutputComponent vo;
+#ifndef QTVideoOutputEnd
+	PyMac_PRECHECK(QTVideoOutputEnd);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &vo))
+		return NULL;
+	_rv = QTVideoOutputEnd(vo);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_QTVideoOutputSetDisplayMode(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	QTVideoOutputComponent vo;
+	long displayModeID;
+#ifndef QTVideoOutputSetDisplayMode
+	PyMac_PRECHECK(QTVideoOutputSetDisplayMode);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpObj_Convert, &vo,
+	                      &displayModeID))
+		return NULL;
+	_rv = QTVideoOutputSetDisplayMode(vo,
+	                                  displayModeID);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_QTVideoOutputGetDisplayMode(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	QTVideoOutputComponent vo;
+	long displayModeID;
+#ifndef QTVideoOutputGetDisplayMode
+	PyMac_PRECHECK(QTVideoOutputGetDisplayMode);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &vo))
+		return NULL;
+	_rv = QTVideoOutputGetDisplayMode(vo,
+	                                  &displayModeID);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     displayModeID);
+	return _res;
+}
+
+static PyObject *Qt_QTVideoOutputGetGWorld(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	QTVideoOutputComponent vo;
+	GWorldPtr gw;
+#ifndef QTVideoOutputGetGWorld
+	PyMac_PRECHECK(QTVideoOutputGetGWorld);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &vo))
+		return NULL;
+	_rv = QTVideoOutputGetGWorld(vo,
+	                             &gw);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     GWorldObj_New, gw);
+	return _res;
+}
+
+static PyObject *Qt_QTVideoOutputGetIndSoundOutput(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	QTVideoOutputComponent vo;
+	long index;
+	Component outputComponent;
+#ifndef QTVideoOutputGetIndSoundOutput
+	PyMac_PRECHECK(QTVideoOutputGetIndSoundOutput);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpObj_Convert, &vo,
+	                      &index))
+		return NULL;
+	_rv = QTVideoOutputGetIndSoundOutput(vo,
+	                                     index,
+	                                     &outputComponent);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     CmpObj_New, outputComponent);
+	return _res;
+}
+
+static PyObject *Qt_QTVideoOutputGetClock(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	QTVideoOutputComponent vo;
+	ComponentInstance clock;
+#ifndef QTVideoOutputGetClock
+	PyMac_PRECHECK(QTVideoOutputGetClock);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpObj_Convert, &vo))
+		return NULL;
+	_rv = QTVideoOutputGetClock(vo,
+	                            &clock);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     CmpInstObj_New, clock);
+	return _res;
+}
+
+static PyObject *Qt_QTVideoOutputSetEchoPort(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	QTVideoOutputComponent vo;
+	CGrafPtr echoPort;
+#ifndef QTVideoOutputSetEchoPort
+	PyMac_PRECHECK(QTVideoOutputSetEchoPort);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &vo,
+	                      GrafObj_Convert, &echoPort))
+		return NULL;
+	_rv = QTVideoOutputSetEchoPort(vo,
+	                               echoPort);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_QTVideoOutputGetIndImageDecompressor(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	QTVideoOutputComponent vo;
+	long index;
+	Component codec;
+#ifndef QTVideoOutputGetIndImageDecompressor
+	PyMac_PRECHECK(QTVideoOutputGetIndImageDecompressor);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpObj_Convert, &vo,
+	                      &index))
+		return NULL;
+	_rv = QTVideoOutputGetIndImageDecompressor(vo,
+	                                           index,
+	                                           &codec);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     CmpObj_New, codec);
+	return _res;
+}
+
+static PyObject *Qt_QTVideoOutputBaseSetEchoPort(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	QTVideoOutputComponent vo;
+	CGrafPtr echoPort;
+#ifndef QTVideoOutputBaseSetEchoPort
+	PyMac_PRECHECK(QTVideoOutputBaseSetEchoPort);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpObj_Convert, &vo,
+	                      GrafObj_Convert, &echoPort))
+		return NULL;
+	_rv = QTVideoOutputBaseSetEchoPort(vo,
+	                                   echoPort);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MediaSetChunkManagementFlags(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	UInt32 flags;
+	UInt32 flagsMask;
+#ifndef MediaSetChunkManagementFlags
+	PyMac_PRECHECK(MediaSetChunkManagementFlags);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&ll",
+	                      CmpInstObj_Convert, &mh,
+	                      &flags,
+	                      &flagsMask))
+		return NULL;
+	_rv = MediaSetChunkManagementFlags(mh,
+	                                   flags,
+	                                   flagsMask);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MediaGetChunkManagementFlags(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	UInt32 flags;
+#ifndef MediaGetChunkManagementFlags
+	PyMac_PRECHECK(MediaGetChunkManagementFlags);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &mh))
+		return NULL;
+	_rv = MediaGetChunkManagementFlags(mh,
+	                                   &flags);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     flags);
+	return _res;
+}
+
+static PyObject *Qt_MediaSetPurgeableChunkMemoryAllowance(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	Size allowance;
+#ifndef MediaSetPurgeableChunkMemoryAllowance
+	PyMac_PRECHECK(MediaSetPurgeableChunkMemoryAllowance);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &mh,
+	                      &allowance))
+		return NULL;
+	_rv = MediaSetPurgeableChunkMemoryAllowance(mh,
+	                                            allowance);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MediaGetPurgeableChunkMemoryAllowance(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	Size allowance;
+#ifndef MediaGetPurgeableChunkMemoryAllowance
+	PyMac_PRECHECK(MediaGetPurgeableChunkMemoryAllowance);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &mh))
+		return NULL;
+	_rv = MediaGetPurgeableChunkMemoryAllowance(mh,
+	                                            &allowance);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     allowance);
+	return _res;
+}
+
+static PyObject *Qt_MediaEmptyAllPurgeableChunks(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+#ifndef MediaEmptyAllPurgeableChunks
+	PyMac_PRECHECK(MediaEmptyAllPurgeableChunks);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &mh))
+		return NULL;
+	_rv = MediaEmptyAllPurgeableChunks(mh);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MediaSetHandlerCapabilities(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	long flags;
+	long flagsMask;
+#ifndef MediaSetHandlerCapabilities
+	PyMac_PRECHECK(MediaSetHandlerCapabilities);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&ll",
+	                      CmpInstObj_Convert, &mh,
+	                      &flags,
+	                      &flagsMask))
+		return NULL;
+	_rv = MediaSetHandlerCapabilities(mh,
+	                                  flags,
+	                                  flagsMask);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MediaIdle(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	TimeValue atMediaTime;
+	long flagsIn;
+	long flagsOut;
+	TimeRecord movieTime;
+#ifndef MediaIdle
+	PyMac_PRECHECK(MediaIdle);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&llO&",
+	                      CmpInstObj_Convert, &mh,
+	                      &atMediaTime,
+	                      &flagsIn,
+	                      QtTimeRecord_Convert, &movieTime))
+		return NULL;
+	_rv = MediaIdle(mh,
+	                atMediaTime,
+	                flagsIn,
+	                &flagsOut,
+	                &movieTime);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     flagsOut);
+	return _res;
+}
+
+static PyObject *Qt_MediaGetMediaInfo(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	Handle h;
+#ifndef MediaGetMediaInfo
+	PyMac_PRECHECK(MediaGetMediaInfo);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpInstObj_Convert, &mh,
+	                      ResObj_Convert, &h))
+		return NULL;
+	_rv = MediaGetMediaInfo(mh,
+	                        h);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MediaPutMediaInfo(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	Handle h;
+#ifndef MediaPutMediaInfo
+	PyMac_PRECHECK(MediaPutMediaInfo);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpInstObj_Convert, &mh,
+	                      ResObj_Convert, &h))
+		return NULL;
+	_rv = MediaPutMediaInfo(mh,
+	                        h);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MediaSetActive(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	Boolean enableMedia;
+#ifndef MediaSetActive
+	PyMac_PRECHECK(MediaSetActive);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&b",
+	                      CmpInstObj_Convert, &mh,
+	                      &enableMedia))
+		return NULL;
+	_rv = MediaSetActive(mh,
+	                     enableMedia);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MediaSetRate(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	Fixed rate;
+#ifndef MediaSetRate
+	PyMac_PRECHECK(MediaSetRate);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpInstObj_Convert, &mh,
+	                      PyMac_GetFixed, &rate))
+		return NULL;
+	_rv = MediaSetRate(mh,
+	                   rate);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MediaGGetStatus(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	ComponentResult statusErr;
+#ifndef MediaGGetStatus
+	PyMac_PRECHECK(MediaGGetStatus);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &mh))
+		return NULL;
+	_rv = MediaGGetStatus(mh,
+	                      &statusErr);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     statusErr);
+	return _res;
+}
+
+static PyObject *Qt_MediaTrackEdited(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+#ifndef MediaTrackEdited
+	PyMac_PRECHECK(MediaTrackEdited);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &mh))
+		return NULL;
+	_rv = MediaTrackEdited(mh);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MediaSetMediaTimeScale(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	TimeScale newTimeScale;
+#ifndef MediaSetMediaTimeScale
+	PyMac_PRECHECK(MediaSetMediaTimeScale);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &mh,
+	                      &newTimeScale))
+		return NULL;
+	_rv = MediaSetMediaTimeScale(mh,
+	                             newTimeScale);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MediaSetMovieTimeScale(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	TimeScale newTimeScale;
+#ifndef MediaSetMovieTimeScale
+	PyMac_PRECHECK(MediaSetMovieTimeScale);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &mh,
+	                      &newTimeScale))
+		return NULL;
+	_rv = MediaSetMovieTimeScale(mh,
+	                             newTimeScale);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MediaSetGWorld(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	CGrafPtr aPort;
+	GDHandle aGD;
+#ifndef MediaSetGWorld
+	PyMac_PRECHECK(MediaSetGWorld);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      CmpInstObj_Convert, &mh,
+	                      GrafObj_Convert, &aPort,
+	                      OptResObj_Convert, &aGD))
+		return NULL;
+	_rv = MediaSetGWorld(mh,
+	                     aPort,
+	                     aGD);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MediaSetDimensions(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	Fixed width;
+	Fixed height;
+#ifndef MediaSetDimensions
+	PyMac_PRECHECK(MediaSetDimensions);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      CmpInstObj_Convert, &mh,
+	                      PyMac_GetFixed, &width,
+	                      PyMac_GetFixed, &height))
+		return NULL;
+	_rv = MediaSetDimensions(mh,
+	                         width,
+	                         height);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MediaSetClip(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	RgnHandle theClip;
+#ifndef MediaSetClip
+	PyMac_PRECHECK(MediaSetClip);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpInstObj_Convert, &mh,
+	                      ResObj_Convert, &theClip))
+		return NULL;
+	_rv = MediaSetClip(mh,
+	                   theClip);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MediaGetTrackOpaque(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	Boolean trackIsOpaque;
+#ifndef MediaGetTrackOpaque
+	PyMac_PRECHECK(MediaGetTrackOpaque);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &mh))
+		return NULL;
+	_rv = MediaGetTrackOpaque(mh,
+	                          &trackIsOpaque);
+	_res = Py_BuildValue("lb",
+	                     _rv,
+	                     trackIsOpaque);
+	return _res;
+}
+
+static PyObject *Qt_MediaSetGraphicsMode(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	long mode;
+	RGBColor opColor;
+#ifndef MediaSetGraphicsMode
+	PyMac_PRECHECK(MediaSetGraphicsMode);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&lO&",
+	                      CmpInstObj_Convert, &mh,
+	                      &mode,
+	                      QdRGB_Convert, &opColor))
+		return NULL;
+	_rv = MediaSetGraphicsMode(mh,
+	                           mode,
+	                           &opColor);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MediaGetGraphicsMode(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	long mode;
+	RGBColor opColor;
+#ifndef MediaGetGraphicsMode
+	PyMac_PRECHECK(MediaGetGraphicsMode);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &mh))
+		return NULL;
+	_rv = MediaGetGraphicsMode(mh,
+	                           &mode,
+	                           &opColor);
+	_res = Py_BuildValue("llO&",
+	                     _rv,
+	                     mode,
+	                     QdRGB_New, &opColor);
+	return _res;
+}
+
+static PyObject *Qt_MediaGSetVolume(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	short volume;
+#ifndef MediaGSetVolume
+	PyMac_PRECHECK(MediaGSetVolume);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      CmpInstObj_Convert, &mh,
+	                      &volume))
+		return NULL;
+	_rv = MediaGSetVolume(mh,
+	                      volume);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MediaSetSoundBalance(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	short balance;
+#ifndef MediaSetSoundBalance
+	PyMac_PRECHECK(MediaSetSoundBalance);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      CmpInstObj_Convert, &mh,
+	                      &balance))
+		return NULL;
+	_rv = MediaSetSoundBalance(mh,
+	                           balance);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MediaGetSoundBalance(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	short balance;
+#ifndef MediaGetSoundBalance
+	PyMac_PRECHECK(MediaGetSoundBalance);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &mh))
+		return NULL;
+	_rv = MediaGetSoundBalance(mh,
+	                           &balance);
+	_res = Py_BuildValue("lh",
+	                     _rv,
+	                     balance);
+	return _res;
+}
+
+static PyObject *Qt_MediaGetNextBoundsChange(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	TimeValue when;
+#ifndef MediaGetNextBoundsChange
+	PyMac_PRECHECK(MediaGetNextBoundsChange);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &mh))
+		return NULL;
+	_rv = MediaGetNextBoundsChange(mh,
+	                               &when);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     when);
+	return _res;
+}
+
+static PyObject *Qt_MediaGetSrcRgn(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	RgnHandle rgn;
+	TimeValue atMediaTime;
+#ifndef MediaGetSrcRgn
+	PyMac_PRECHECK(MediaGetSrcRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&l",
+	                      CmpInstObj_Convert, &mh,
+	                      ResObj_Convert, &rgn,
+	                      &atMediaTime))
+		return NULL;
+	_rv = MediaGetSrcRgn(mh,
+	                     rgn,
+	                     atMediaTime);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MediaPreroll(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	TimeValue time;
+	Fixed rate;
+#ifndef MediaPreroll
+	PyMac_PRECHECK(MediaPreroll);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&lO&",
+	                      CmpInstObj_Convert, &mh,
+	                      &time,
+	                      PyMac_GetFixed, &rate))
+		return NULL;
+	_rv = MediaPreroll(mh,
+	                   time,
+	                   rate);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MediaSampleDescriptionChanged(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	long index;
+#ifndef MediaSampleDescriptionChanged
+	PyMac_PRECHECK(MediaSampleDescriptionChanged);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &mh,
+	                      &index))
+		return NULL;
+	_rv = MediaSampleDescriptionChanged(mh,
+	                                    index);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MediaHasCharacteristic(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	OSType characteristic;
+	Boolean hasIt;
+#ifndef MediaHasCharacteristic
+	PyMac_PRECHECK(MediaHasCharacteristic);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpInstObj_Convert, &mh,
+	                      PyMac_GetOSType, &characteristic))
+		return NULL;
+	_rv = MediaHasCharacteristic(mh,
+	                             characteristic,
+	                             &hasIt);
+	_res = Py_BuildValue("lb",
+	                     _rv,
+	                     hasIt);
+	return _res;
+}
+
+static PyObject *Qt_MediaGetOffscreenBufferSize(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	Rect bounds;
+	short depth;
+	CTabHandle ctab;
+#ifndef MediaGetOffscreenBufferSize
+	PyMac_PRECHECK(MediaGetOffscreenBufferSize);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hO&",
+	                      CmpInstObj_Convert, &mh,
+	                      &depth,
+	                      ResObj_Convert, &ctab))
+		return NULL;
+	_rv = MediaGetOffscreenBufferSize(mh,
+	                                  &bounds,
+	                                  depth,
+	                                  ctab);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     PyMac_BuildRect, &bounds);
+	return _res;
+}
+
+static PyObject *Qt_MediaSetHints(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	long hints;
+#ifndef MediaSetHints
+	PyMac_PRECHECK(MediaSetHints);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &mh,
+	                      &hints))
+		return NULL;
+	_rv = MediaSetHints(mh,
+	                    hints);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MediaGetName(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	Str255 name;
+	long requestedLanguage;
+	long actualLanguage;
+#ifndef MediaGetName
+	PyMac_PRECHECK(MediaGetName);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&l",
+	                      CmpInstObj_Convert, &mh,
+	                      PyMac_GetStr255, name,
+	                      &requestedLanguage))
+		return NULL;
+	_rv = MediaGetName(mh,
+	                   name,
+	                   requestedLanguage,
+	                   &actualLanguage);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     actualLanguage);
+	return _res;
+}
+
+static PyObject *Qt_MediaForceUpdate(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	long forceUpdateFlags;
+#ifndef MediaForceUpdate
+	PyMac_PRECHECK(MediaForceUpdate);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &mh,
+	                      &forceUpdateFlags))
+		return NULL;
+	_rv = MediaForceUpdate(mh,
+	                       forceUpdateFlags);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MediaGetDrawingRgn(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	RgnHandle partialRgn;
+#ifndef MediaGetDrawingRgn
+	PyMac_PRECHECK(MediaGetDrawingRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &mh))
+		return NULL;
+	_rv = MediaGetDrawingRgn(mh,
+	                         &partialRgn);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     ResObj_New, partialRgn);
+	return _res;
+}
+
+static PyObject *Qt_MediaGSetActiveSegment(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	TimeValue activeStart;
+	TimeValue activeDuration;
+#ifndef MediaGSetActiveSegment
+	PyMac_PRECHECK(MediaGSetActiveSegment);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&ll",
+	                      CmpInstObj_Convert, &mh,
+	                      &activeStart,
+	                      &activeDuration))
+		return NULL;
+	_rv = MediaGSetActiveSegment(mh,
+	                             activeStart,
+	                             activeDuration);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MediaInvalidateRegion(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	RgnHandle invalRgn;
+#ifndef MediaInvalidateRegion
+	PyMac_PRECHECK(MediaInvalidateRegion);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpInstObj_Convert, &mh,
+	                      ResObj_Convert, &invalRgn))
+		return NULL;
+	_rv = MediaInvalidateRegion(mh,
+	                            invalRgn);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MediaGetNextStepTime(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	short flags;
+	TimeValue mediaTimeIn;
+	TimeValue mediaTimeOut;
+	Fixed rate;
+#ifndef MediaGetNextStepTime
+	PyMac_PRECHECK(MediaGetNextStepTime);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hlO&",
+	                      CmpInstObj_Convert, &mh,
+	                      &flags,
+	                      &mediaTimeIn,
+	                      PyMac_GetFixed, &rate))
+		return NULL;
+	_rv = MediaGetNextStepTime(mh,
+	                           flags,
+	                           mediaTimeIn,
+	                           &mediaTimeOut,
+	                           rate);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     mediaTimeOut);
+	return _res;
+}
+
+static PyObject *Qt_MediaChangedNonPrimarySource(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	long inputIndex;
+#ifndef MediaChangedNonPrimarySource
+	PyMac_PRECHECK(MediaChangedNonPrimarySource);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &mh,
+	                      &inputIndex))
+		return NULL;
+	_rv = MediaChangedNonPrimarySource(mh,
+	                                   inputIndex);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MediaTrackReferencesChanged(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+#ifndef MediaTrackReferencesChanged
+	PyMac_PRECHECK(MediaTrackReferencesChanged);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &mh))
+		return NULL;
+	_rv = MediaTrackReferencesChanged(mh);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MediaReleaseSampleDataPointer(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	long sampleNum;
+#ifndef MediaReleaseSampleDataPointer
+	PyMac_PRECHECK(MediaReleaseSampleDataPointer);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &mh,
+	                      &sampleNum))
+		return NULL;
+	_rv = MediaReleaseSampleDataPointer(mh,
+	                                    sampleNum);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MediaTrackPropertyAtomChanged(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+#ifndef MediaTrackPropertyAtomChanged
+	PyMac_PRECHECK(MediaTrackPropertyAtomChanged);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &mh))
+		return NULL;
+	_rv = MediaTrackPropertyAtomChanged(mh);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MediaSetVideoParam(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	long whichParam;
+	unsigned short value;
+#ifndef MediaSetVideoParam
+	PyMac_PRECHECK(MediaSetVideoParam);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &mh,
+	                      &whichParam))
+		return NULL;
+	_rv = MediaSetVideoParam(mh,
+	                         whichParam,
+	                         &value);
+	_res = Py_BuildValue("lH",
+	                     _rv,
+	                     value);
+	return _res;
+}
+
+static PyObject *Qt_MediaGetVideoParam(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	long whichParam;
+	unsigned short value;
+#ifndef MediaGetVideoParam
+	PyMac_PRECHECK(MediaGetVideoParam);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &mh,
+	                      &whichParam))
+		return NULL;
+	_rv = MediaGetVideoParam(mh,
+	                         whichParam,
+	                         &value);
+	_res = Py_BuildValue("lH",
+	                     _rv,
+	                     value);
+	return _res;
+}
+
+static PyObject *Qt_MediaCompare(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	Boolean isOK;
+	Media srcMedia;
+	ComponentInstance srcMediaComponent;
+#ifndef MediaCompare
+	PyMac_PRECHECK(MediaCompare);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      CmpInstObj_Convert, &mh,
+	                      MediaObj_Convert, &srcMedia,
+	                      CmpInstObj_Convert, &srcMediaComponent))
+		return NULL;
+	_rv = MediaCompare(mh,
+	                   &isOK,
+	                   srcMedia,
+	                   srcMediaComponent);
+	_res = Py_BuildValue("lb",
+	                     _rv,
+	                     isOK);
+	return _res;
+}
+
+static PyObject *Qt_MediaGetClock(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	ComponentInstance clock;
+#ifndef MediaGetClock
+	PyMac_PRECHECK(MediaGetClock);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &mh))
+		return NULL;
+	_rv = MediaGetClock(mh,
+	                    &clock);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     CmpInstObj_New, clock);
+	return _res;
+}
+
+static PyObject *Qt_MediaSetSoundOutputComponent(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	Component outputComponent;
+#ifndef MediaSetSoundOutputComponent
+	PyMac_PRECHECK(MediaSetSoundOutputComponent);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpInstObj_Convert, &mh,
+	                      CmpObj_Convert, &outputComponent))
+		return NULL;
+	_rv = MediaSetSoundOutputComponent(mh,
+	                                   outputComponent);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MediaGetSoundOutputComponent(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	Component outputComponent;
+#ifndef MediaGetSoundOutputComponent
+	PyMac_PRECHECK(MediaGetSoundOutputComponent);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &mh))
+		return NULL;
+	_rv = MediaGetSoundOutputComponent(mh,
+	                                   &outputComponent);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     CmpObj_New, outputComponent);
+	return _res;
+}
+
+static PyObject *Qt_MediaSetSoundLocalizationData(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	Handle data;
+#ifndef MediaSetSoundLocalizationData
+	PyMac_PRECHECK(MediaSetSoundLocalizationData);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpInstObj_Convert, &mh,
+	                      ResObj_Convert, &data))
+		return NULL;
+	_rv = MediaSetSoundLocalizationData(mh,
+	                                    data);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MediaGetInvalidRegion(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	RgnHandle rgn;
+#ifndef MediaGetInvalidRegion
+	PyMac_PRECHECK(MediaGetInvalidRegion);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpInstObj_Convert, &mh,
+	                      ResObj_Convert, &rgn))
+		return NULL;
+	_rv = MediaGetInvalidRegion(mh,
+	                            rgn);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MediaSampleDescriptionB2N(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	SampleDescriptionHandle sampleDescriptionH;
+#ifndef MediaSampleDescriptionB2N
+	PyMac_PRECHECK(MediaSampleDescriptionB2N);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpInstObj_Convert, &mh,
+	                      ResObj_Convert, &sampleDescriptionH))
+		return NULL;
+	_rv = MediaSampleDescriptionB2N(mh,
+	                                sampleDescriptionH);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MediaSampleDescriptionN2B(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	SampleDescriptionHandle sampleDescriptionH;
+#ifndef MediaSampleDescriptionN2B
+	PyMac_PRECHECK(MediaSampleDescriptionN2B);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpInstObj_Convert, &mh,
+	                      ResObj_Convert, &sampleDescriptionH))
+		return NULL;
+	_rv = MediaSampleDescriptionN2B(mh,
+	                                sampleDescriptionH);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MediaFlushNonPrimarySourceData(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	long inputIndex;
+#ifndef MediaFlushNonPrimarySourceData
+	PyMac_PRECHECK(MediaFlushNonPrimarySourceData);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &mh,
+	                      &inputIndex))
+		return NULL;
+	_rv = MediaFlushNonPrimarySourceData(mh,
+	                                     inputIndex);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MediaGetURLLink(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	Point displayWhere;
+	Handle urlLink;
+#ifndef MediaGetURLLink
+	PyMac_PRECHECK(MediaGetURLLink);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpInstObj_Convert, &mh,
+	                      PyMac_GetPoint, &displayWhere))
+		return NULL;
+	_rv = MediaGetURLLink(mh,
+	                      displayWhere,
+	                      &urlLink);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     ResObj_New, urlLink);
+	return _res;
+}
+
+static PyObject *Qt_MediaHitTestForTargetRefCon(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	long flags;
+	Point loc;
+	long targetRefCon;
+#ifndef MediaHitTestForTargetRefCon
+	PyMac_PRECHECK(MediaHitTestForTargetRefCon);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&lO&",
+	                      CmpInstObj_Convert, &mh,
+	                      &flags,
+	                      PyMac_GetPoint, &loc))
+		return NULL;
+	_rv = MediaHitTestForTargetRefCon(mh,
+	                                  flags,
+	                                  loc,
+	                                  &targetRefCon);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     targetRefCon);
+	return _res;
+}
+
+static PyObject *Qt_MediaHitTestTargetRefCon(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	long targetRefCon;
+	long flags;
+	Point loc;
+	Boolean wasHit;
+#ifndef MediaHitTestTargetRefCon
+	PyMac_PRECHECK(MediaHitTestTargetRefCon);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&llO&",
+	                      CmpInstObj_Convert, &mh,
+	                      &targetRefCon,
+	                      &flags,
+	                      PyMac_GetPoint, &loc))
+		return NULL;
+	_rv = MediaHitTestTargetRefCon(mh,
+	                               targetRefCon,
+	                               flags,
+	                               loc,
+	                               &wasHit);
+	_res = Py_BuildValue("lb",
+	                     _rv,
+	                     wasHit);
+	return _res;
+}
+
+static PyObject *Qt_MediaDisposeTargetRefCon(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	long targetRefCon;
+#ifndef MediaDisposeTargetRefCon
+	PyMac_PRECHECK(MediaDisposeTargetRefCon);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &mh,
+	                      &targetRefCon))
+		return NULL;
+	_rv = MediaDisposeTargetRefCon(mh,
+	                               targetRefCon);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MediaTargetRefConsEqual(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	long firstRefCon;
+	long secondRefCon;
+	Boolean equal;
+#ifndef MediaTargetRefConsEqual
+	PyMac_PRECHECK(MediaTargetRefConsEqual);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&ll",
+	                      CmpInstObj_Convert, &mh,
+	                      &firstRefCon,
+	                      &secondRefCon))
+		return NULL;
+	_rv = MediaTargetRefConsEqual(mh,
+	                              firstRefCon,
+	                              secondRefCon,
+	                              &equal);
+	_res = Py_BuildValue("lb",
+	                     _rv,
+	                     equal);
+	return _res;
+}
+
+static PyObject *Qt_MediaPrePrerollCancel(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	void * refcon;
+#ifndef MediaPrePrerollCancel
+	PyMac_PRECHECK(MediaPrePrerollCancel);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&s",
+	                      CmpInstObj_Convert, &mh,
+	                      &refcon))
+		return NULL;
+	_rv = MediaPrePrerollCancel(mh,
+	                            refcon);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MediaEnterEmptyEdit(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+#ifndef MediaEnterEmptyEdit
+	PyMac_PRECHECK(MediaEnterEmptyEdit);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &mh))
+		return NULL;
+	_rv = MediaEnterEmptyEdit(mh);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MediaCurrentMediaQueuedData(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	long milliSecs;
+#ifndef MediaCurrentMediaQueuedData
+	PyMac_PRECHECK(MediaCurrentMediaQueuedData);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &mh))
+		return NULL;
+	_rv = MediaCurrentMediaQueuedData(mh,
+	                                  &milliSecs);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     milliSecs);
+	return _res;
+}
+
+static PyObject *Qt_MediaGetEffectiveVolume(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	short volume;
+#ifndef MediaGetEffectiveVolume
+	PyMac_PRECHECK(MediaGetEffectiveVolume);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &mh))
+		return NULL;
+	_rv = MediaGetEffectiveVolume(mh,
+	                              &volume);
+	_res = Py_BuildValue("lh",
+	                     _rv,
+	                     volume);
+	return _res;
+}
+
+static PyObject *Qt_MediaGetSoundLevelMeteringEnabled(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	Boolean enabled;
+#ifndef MediaGetSoundLevelMeteringEnabled
+	PyMac_PRECHECK(MediaGetSoundLevelMeteringEnabled);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &mh))
+		return NULL;
+	_rv = MediaGetSoundLevelMeteringEnabled(mh,
+	                                        &enabled);
+	_res = Py_BuildValue("lb",
+	                     _rv,
+	                     enabled);
+	return _res;
+}
+
+static PyObject *Qt_MediaSetSoundLevelMeteringEnabled(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	Boolean enable;
+#ifndef MediaSetSoundLevelMeteringEnabled
+	PyMac_PRECHECK(MediaSetSoundLevelMeteringEnabled);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&b",
+	                      CmpInstObj_Convert, &mh,
+	                      &enable))
+		return NULL;
+	_rv = MediaSetSoundLevelMeteringEnabled(mh,
+	                                        enable);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MediaGetEffectiveSoundBalance(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	short balance;
+#ifndef MediaGetEffectiveSoundBalance
+	PyMac_PRECHECK(MediaGetEffectiveSoundBalance);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &mh))
+		return NULL;
+	_rv = MediaGetEffectiveSoundBalance(mh,
+	                                    &balance);
+	_res = Py_BuildValue("lh",
+	                     _rv,
+	                     balance);
+	return _res;
+}
+
+static PyObject *Qt_MediaSetScreenLock(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	Boolean lockIt;
+#ifndef MediaSetScreenLock
+	PyMac_PRECHECK(MediaSetScreenLock);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&b",
+	                      CmpInstObj_Convert, &mh,
+	                      &lockIt))
+		return NULL;
+	_rv = MediaSetScreenLock(mh,
+	                         lockIt);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MediaGetErrorString(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	ComponentResult theError;
+	Str255 errorString;
+#ifndef MediaGetErrorString
+	PyMac_PRECHECK(MediaGetErrorString);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&lO&",
+	                      CmpInstObj_Convert, &mh,
+	                      &theError,
+	                      PyMac_GetStr255, errorString))
+		return NULL;
+	_rv = MediaGetErrorString(mh,
+	                          theError,
+	                          errorString);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MediaGetSoundEqualizerBandLevels(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	UInt8 bandLevels;
+#ifndef MediaGetSoundEqualizerBandLevels
+	PyMac_PRECHECK(MediaGetSoundEqualizerBandLevels);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &mh))
+		return NULL;
+	_rv = MediaGetSoundEqualizerBandLevels(mh,
+	                                       &bandLevels);
+	_res = Py_BuildValue("lb",
+	                     _rv,
+	                     bandLevels);
+	return _res;
+}
+
+static PyObject *Qt_MediaDoIdleActions(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+#ifndef MediaDoIdleActions
+	PyMac_PRECHECK(MediaDoIdleActions);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &mh))
+		return NULL;
+	_rv = MediaDoIdleActions(mh);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MediaSetSoundBassAndTreble(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	short bass;
+	short treble;
+#ifndef MediaSetSoundBassAndTreble
+	PyMac_PRECHECK(MediaSetSoundBassAndTreble);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hh",
+	                      CmpInstObj_Convert, &mh,
+	                      &bass,
+	                      &treble))
+		return NULL;
+	_rv = MediaSetSoundBassAndTreble(mh,
+	                                 bass,
+	                                 treble);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MediaGetSoundBassAndTreble(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	short bass;
+	short treble;
+#ifndef MediaGetSoundBassAndTreble
+	PyMac_PRECHECK(MediaGetSoundBassAndTreble);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &mh))
+		return NULL;
+	_rv = MediaGetSoundBassAndTreble(mh,
+	                                 &bass,
+	                                 &treble);
+	_res = Py_BuildValue("lhh",
+	                     _rv,
+	                     bass,
+	                     treble);
+	return _res;
+}
+
+static PyObject *Qt_MediaTimeBaseChanged(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+#ifndef MediaTimeBaseChanged
+	PyMac_PRECHECK(MediaTimeBaseChanged);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &mh))
+		return NULL;
+	_rv = MediaTimeBaseChanged(mh);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MediaMCIsPlayerEvent(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	EventRecord e;
+	Boolean handledIt;
+#ifndef MediaMCIsPlayerEvent
+	PyMac_PRECHECK(MediaMCIsPlayerEvent);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpInstObj_Convert, &mh,
+	                      PyMac_GetEventRecord, &e))
+		return NULL;
+	_rv = MediaMCIsPlayerEvent(mh,
+	                           &e,
+	                           &handledIt);
+	_res = Py_BuildValue("lb",
+	                     _rv,
+	                     handledIt);
+	return _res;
+}
+
+static PyObject *Qt_MediaGetMediaLoadState(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	long mediaLoadState;
+#ifndef MediaGetMediaLoadState
+	PyMac_PRECHECK(MediaGetMediaLoadState);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &mh))
+		return NULL;
+	_rv = MediaGetMediaLoadState(mh,
+	                             &mediaLoadState);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     mediaLoadState);
+	return _res;
+}
+
+static PyObject *Qt_MediaVideoOutputChanged(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	ComponentInstance vout;
+#ifndef MediaVideoOutputChanged
+	PyMac_PRECHECK(MediaVideoOutputChanged);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpInstObj_Convert, &mh,
+	                      CmpInstObj_Convert, &vout))
+		return NULL;
+	_rv = MediaVideoOutputChanged(mh,
+	                              vout);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MediaEmptySampleCache(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	long sampleNum;
+	long sampleCount;
+#ifndef MediaEmptySampleCache
+	PyMac_PRECHECK(MediaEmptySampleCache);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&ll",
+	                      CmpInstObj_Convert, &mh,
+	                      &sampleNum,
+	                      &sampleCount))
+		return NULL;
+	_rv = MediaEmptySampleCache(mh,
+	                            sampleNum,
+	                            sampleCount);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MediaGetPublicInfo(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	OSType infoSelector;
+	void * infoDataPtr;
+	Size ioDataSize;
+#ifndef MediaGetPublicInfo
+	PyMac_PRECHECK(MediaGetPublicInfo);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&s",
+	                      CmpInstObj_Convert, &mh,
+	                      PyMac_GetOSType, &infoSelector,
+	                      &infoDataPtr))
+		return NULL;
+	_rv = MediaGetPublicInfo(mh,
+	                         infoSelector,
+	                         infoDataPtr,
+	                         &ioDataSize);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     ioDataSize);
+	return _res;
+}
+
+static PyObject *Qt_MediaSetPublicInfo(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	OSType infoSelector;
+	void * infoDataPtr;
+	Size dataSize;
+#ifndef MediaSetPublicInfo
+	PyMac_PRECHECK(MediaSetPublicInfo);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&sl",
+	                      CmpInstObj_Convert, &mh,
+	                      PyMac_GetOSType, &infoSelector,
+	                      &infoDataPtr,
+	                      &dataSize))
+		return NULL;
+	_rv = MediaSetPublicInfo(mh,
+	                         infoSelector,
+	                         infoDataPtr,
+	                         dataSize);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MediaRefConSetProperty(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	long refCon;
+	long propertyType;
+	void * propertyValue;
+#ifndef MediaRefConSetProperty
+	PyMac_PRECHECK(MediaRefConSetProperty);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&lls",
+	                      CmpInstObj_Convert, &mh,
+	                      &refCon,
+	                      &propertyType,
+	                      &propertyValue))
+		return NULL;
+	_rv = MediaRefConSetProperty(mh,
+	                             refCon,
+	                             propertyType,
+	                             propertyValue);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MediaRefConGetProperty(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	long refCon;
+	long propertyType;
+	void * propertyValue;
+#ifndef MediaRefConGetProperty
+	PyMac_PRECHECK(MediaRefConGetProperty);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&lls",
+	                      CmpInstObj_Convert, &mh,
+	                      &refCon,
+	                      &propertyType,
+	                      &propertyValue))
+		return NULL;
+	_rv = MediaRefConGetProperty(mh,
+	                             refCon,
+	                             propertyType,
+	                             propertyValue);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MediaNavigateTargetRefCon(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	long navigation;
+	long refCon;
+#ifndef MediaNavigateTargetRefCon
+	PyMac_PRECHECK(MediaNavigateTargetRefCon);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &mh,
+	                      &navigation))
+		return NULL;
+	_rv = MediaNavigateTargetRefCon(mh,
+	                                navigation,
+	                                &refCon);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     refCon);
+	return _res;
+}
+
+static PyObject *Qt_MediaGGetIdleManager(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	IdleManager pim;
+#ifndef MediaGGetIdleManager
+	PyMac_PRECHECK(MediaGGetIdleManager);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &mh))
+		return NULL;
+	_rv = MediaGGetIdleManager(mh,
+	                           &pim);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     IdleManagerObj_New, pim);
+	return _res;
+}
+
+static PyObject *Qt_MediaGSetIdleManager(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MediaHandler mh;
+	IdleManager im;
+#ifndef MediaGSetIdleManager
+	PyMac_PRECHECK(MediaGSetIdleManager);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpInstObj_Convert, &mh,
+	                      IdleManagerObj_Convert, &im))
+		return NULL;
+	_rv = MediaGSetIdleManager(mh,
+	                           im);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_QTMIDIGetMIDIPorts(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	QTMIDIComponent ci;
+	QTMIDIPortListHandle inputPorts;
+	QTMIDIPortListHandle outputPorts;
+#ifndef QTMIDIGetMIDIPorts
+	PyMac_PRECHECK(QTMIDIGetMIDIPorts);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &ci))
+		return NULL;
+	_rv = QTMIDIGetMIDIPorts(ci,
+	                         &inputPorts,
+	                         &outputPorts);
+	_res = Py_BuildValue("lO&O&",
+	                     _rv,
+	                     ResObj_New, inputPorts,
+	                     ResObj_New, outputPorts);
+	return _res;
+}
+
+static PyObject *Qt_QTMIDIUseSendPort(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	QTMIDIComponent ci;
+	long portIndex;
+	long inUse;
+#ifndef QTMIDIUseSendPort
+	PyMac_PRECHECK(QTMIDIUseSendPort);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&ll",
+	                      CmpInstObj_Convert, &ci,
+	                      &portIndex,
+	                      &inUse))
+		return NULL;
+	_rv = QTMIDIUseSendPort(ci,
+	                        portIndex,
+	                        inUse);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_QTMIDISendMIDI(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	QTMIDIComponent ci;
+	long portIndex;
+	MusicMIDIPacket mp;
+#ifndef QTMIDISendMIDI
+	PyMac_PRECHECK(QTMIDISendMIDI);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&lO&",
+	                      CmpInstObj_Convert, &ci,
+	                      &portIndex,
+	                      QtMusicMIDIPacket_Convert, &mp))
+		return NULL;
+	_rv = QTMIDISendMIDI(ci,
+	                     portIndex,
+	                     &mp);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MusicGetPart(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MusicComponent mc;
+	long part;
+	long midiChannel;
+	long polyphony;
+#ifndef MusicGetPart
+	PyMac_PRECHECK(MusicGetPart);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &mc,
+	                      &part))
+		return NULL;
+	_rv = MusicGetPart(mc,
+	                   part,
+	                   &midiChannel,
+	                   &polyphony);
+	_res = Py_BuildValue("lll",
+	                     _rv,
+	                     midiChannel,
+	                     polyphony);
+	return _res;
+}
+
+static PyObject *Qt_MusicSetPart(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MusicComponent mc;
+	long part;
+	long midiChannel;
+	long polyphony;
+#ifndef MusicSetPart
+	PyMac_PRECHECK(MusicSetPart);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&lll",
+	                      CmpInstObj_Convert, &mc,
+	                      &part,
+	                      &midiChannel,
+	                      &polyphony))
+		return NULL;
+	_rv = MusicSetPart(mc,
+	                   part,
+	                   midiChannel,
+	                   polyphony);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MusicSetPartInstrumentNumber(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MusicComponent mc;
+	long part;
+	long instrumentNumber;
+#ifndef MusicSetPartInstrumentNumber
+	PyMac_PRECHECK(MusicSetPartInstrumentNumber);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&ll",
+	                      CmpInstObj_Convert, &mc,
+	                      &part,
+	                      &instrumentNumber))
+		return NULL;
+	_rv = MusicSetPartInstrumentNumber(mc,
+	                                   part,
+	                                   instrumentNumber);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MusicGetPartInstrumentNumber(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MusicComponent mc;
+	long part;
+#ifndef MusicGetPartInstrumentNumber
+	PyMac_PRECHECK(MusicGetPartInstrumentNumber);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &mc,
+	                      &part))
+		return NULL;
+	_rv = MusicGetPartInstrumentNumber(mc,
+	                                   part);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MusicStorePartInstrument(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MusicComponent mc;
+	long part;
+	long instrumentNumber;
+#ifndef MusicStorePartInstrument
+	PyMac_PRECHECK(MusicStorePartInstrument);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&ll",
+	                      CmpInstObj_Convert, &mc,
+	                      &part,
+	                      &instrumentNumber))
+		return NULL;
+	_rv = MusicStorePartInstrument(mc,
+	                               part,
+	                               instrumentNumber);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MusicGetPartAtomicInstrument(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MusicComponent mc;
+	long part;
+	AtomicInstrument ai;
+	long flags;
+#ifndef MusicGetPartAtomicInstrument
+	PyMac_PRECHECK(MusicGetPartAtomicInstrument);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&ll",
+	                      CmpInstObj_Convert, &mc,
+	                      &part,
+	                      &flags))
+		return NULL;
+	_rv = MusicGetPartAtomicInstrument(mc,
+	                                   part,
+	                                   &ai,
+	                                   flags);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     ResObj_New, ai);
+	return _res;
+}
+
+static PyObject *Qt_MusicSetPartAtomicInstrument(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MusicComponent mc;
+	long part;
+	AtomicInstrumentPtr aiP;
+	long flags;
+#ifndef MusicSetPartAtomicInstrument
+	PyMac_PRECHECK(MusicSetPartAtomicInstrument);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&lsl",
+	                      CmpInstObj_Convert, &mc,
+	                      &part,
+	                      &aiP,
+	                      &flags))
+		return NULL;
+	_rv = MusicSetPartAtomicInstrument(mc,
+	                                   part,
+	                                   aiP,
+	                                   flags);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MusicGetPartKnob(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MusicComponent mc;
+	long part;
+	long knobID;
+#ifndef MusicGetPartKnob
+	PyMac_PRECHECK(MusicGetPartKnob);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&ll",
+	                      CmpInstObj_Convert, &mc,
+	                      &part,
+	                      &knobID))
+		return NULL;
+	_rv = MusicGetPartKnob(mc,
+	                       part,
+	                       knobID);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MusicSetPartKnob(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MusicComponent mc;
+	long part;
+	long knobID;
+	long knobValue;
+#ifndef MusicSetPartKnob
+	PyMac_PRECHECK(MusicSetPartKnob);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&lll",
+	                      CmpInstObj_Convert, &mc,
+	                      &part,
+	                      &knobID,
+	                      &knobValue))
+		return NULL;
+	_rv = MusicSetPartKnob(mc,
+	                       part,
+	                       knobID,
+	                       knobValue);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MusicGetKnob(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MusicComponent mc;
+	long knobID;
+#ifndef MusicGetKnob
+	PyMac_PRECHECK(MusicGetKnob);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &mc,
+	                      &knobID))
+		return NULL;
+	_rv = MusicGetKnob(mc,
+	                   knobID);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MusicSetKnob(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MusicComponent mc;
+	long knobID;
+	long knobValue;
+#ifndef MusicSetKnob
+	PyMac_PRECHECK(MusicSetKnob);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&ll",
+	                      CmpInstObj_Convert, &mc,
+	                      &knobID,
+	                      &knobValue))
+		return NULL;
+	_rv = MusicSetKnob(mc,
+	                   knobID,
+	                   knobValue);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MusicGetPartName(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MusicComponent mc;
+	long part;
+	StringPtr name;
+#ifndef MusicGetPartName
+	PyMac_PRECHECK(MusicGetPartName);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&ls",
+	                      CmpInstObj_Convert, &mc,
+	                      &part,
+	                      &name))
+		return NULL;
+	_rv = MusicGetPartName(mc,
+	                       part,
+	                       name);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MusicSetPartName(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MusicComponent mc;
+	long part;
+	StringPtr name;
+#ifndef MusicSetPartName
+	PyMac_PRECHECK(MusicSetPartName);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&ls",
+	                      CmpInstObj_Convert, &mc,
+	                      &part,
+	                      &name))
+		return NULL;
+	_rv = MusicSetPartName(mc,
+	                       part,
+	                       name);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MusicPlayNote(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MusicComponent mc;
+	long part;
+	long pitch;
+	long velocity;
+#ifndef MusicPlayNote
+	PyMac_PRECHECK(MusicPlayNote);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&lll",
+	                      CmpInstObj_Convert, &mc,
+	                      &part,
+	                      &pitch,
+	                      &velocity))
+		return NULL;
+	_rv = MusicPlayNote(mc,
+	                    part,
+	                    pitch,
+	                    velocity);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MusicResetPart(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MusicComponent mc;
+	long part;
+#ifndef MusicResetPart
+	PyMac_PRECHECK(MusicResetPart);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &mc,
+	                      &part))
+		return NULL;
+	_rv = MusicResetPart(mc,
+	                     part);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MusicSetPartController(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MusicComponent mc;
+	long part;
+	MusicController controllerNumber;
+	long controllerValue;
+#ifndef MusicSetPartController
+	PyMac_PRECHECK(MusicSetPartController);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&lll",
+	                      CmpInstObj_Convert, &mc,
+	                      &part,
+	                      &controllerNumber,
+	                      &controllerValue))
+		return NULL;
+	_rv = MusicSetPartController(mc,
+	                             part,
+	                             controllerNumber,
+	                             controllerValue);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MusicGetPartController(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MusicComponent mc;
+	long part;
+	MusicController controllerNumber;
+#ifndef MusicGetPartController
+	PyMac_PRECHECK(MusicGetPartController);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&ll",
+	                      CmpInstObj_Convert, &mc,
+	                      &part,
+	                      &controllerNumber))
+		return NULL;
+	_rv = MusicGetPartController(mc,
+	                             part,
+	                             controllerNumber);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MusicGetInstrumentNames(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MusicComponent mc;
+	long modifiableInstruments;
+	Handle instrumentNames;
+	Handle instrumentCategoryLasts;
+	Handle instrumentCategoryNames;
+#ifndef MusicGetInstrumentNames
+	PyMac_PRECHECK(MusicGetInstrumentNames);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &mc,
+	                      &modifiableInstruments))
+		return NULL;
+	_rv = MusicGetInstrumentNames(mc,
+	                              modifiableInstruments,
+	                              &instrumentNames,
+	                              &instrumentCategoryLasts,
+	                              &instrumentCategoryNames);
+	_res = Py_BuildValue("lO&O&O&",
+	                     _rv,
+	                     ResObj_New, instrumentNames,
+	                     ResObj_New, instrumentCategoryLasts,
+	                     ResObj_New, instrumentCategoryNames);
+	return _res;
+}
+
+static PyObject *Qt_MusicGetDrumNames(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MusicComponent mc;
+	long modifiableInstruments;
+	Handle instrumentNumbers;
+	Handle instrumentNames;
+#ifndef MusicGetDrumNames
+	PyMac_PRECHECK(MusicGetDrumNames);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &mc,
+	                      &modifiableInstruments))
+		return NULL;
+	_rv = MusicGetDrumNames(mc,
+	                        modifiableInstruments,
+	                        &instrumentNumbers,
+	                        &instrumentNames);
+	_res = Py_BuildValue("lO&O&",
+	                     _rv,
+	                     ResObj_New, instrumentNumbers,
+	                     ResObj_New, instrumentNames);
+	return _res;
+}
+
+static PyObject *Qt_MusicGetMasterTune(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MusicComponent mc;
+#ifndef MusicGetMasterTune
+	PyMac_PRECHECK(MusicGetMasterTune);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &mc))
+		return NULL;
+	_rv = MusicGetMasterTune(mc);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MusicSetMasterTune(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MusicComponent mc;
+	long masterTune;
+#ifndef MusicSetMasterTune
+	PyMac_PRECHECK(MusicSetMasterTune);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &mc,
+	                      &masterTune))
+		return NULL;
+	_rv = MusicSetMasterTune(mc,
+	                         masterTune);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MusicGetDeviceConnection(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MusicComponent mc;
+	long index;
+	long id1;
+	long id2;
+#ifndef MusicGetDeviceConnection
+	PyMac_PRECHECK(MusicGetDeviceConnection);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &mc,
+	                      &index))
+		return NULL;
+	_rv = MusicGetDeviceConnection(mc,
+	                               index,
+	                               &id1,
+	                               &id2);
+	_res = Py_BuildValue("lll",
+	                     _rv,
+	                     id1,
+	                     id2);
+	return _res;
+}
+
+static PyObject *Qt_MusicUseDeviceConnection(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MusicComponent mc;
+	long id1;
+	long id2;
+#ifndef MusicUseDeviceConnection
+	PyMac_PRECHECK(MusicUseDeviceConnection);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&ll",
+	                      CmpInstObj_Convert, &mc,
+	                      &id1,
+	                      &id2))
+		return NULL;
+	_rv = MusicUseDeviceConnection(mc,
+	                               id1,
+	                               id2);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MusicGetKnobSettingStrings(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MusicComponent mc;
+	long knobIndex;
+	long isGlobal;
+	Handle settingsNames;
+	Handle settingsCategoryLasts;
+	Handle settingsCategoryNames;
+#ifndef MusicGetKnobSettingStrings
+	PyMac_PRECHECK(MusicGetKnobSettingStrings);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&ll",
+	                      CmpInstObj_Convert, &mc,
+	                      &knobIndex,
+	                      &isGlobal))
+		return NULL;
+	_rv = MusicGetKnobSettingStrings(mc,
+	                                 knobIndex,
+	                                 isGlobal,
+	                                 &settingsNames,
+	                                 &settingsCategoryLasts,
+	                                 &settingsCategoryNames);
+	_res = Py_BuildValue("lO&O&O&",
+	                     _rv,
+	                     ResObj_New, settingsNames,
+	                     ResObj_New, settingsCategoryLasts,
+	                     ResObj_New, settingsCategoryNames);
+	return _res;
+}
+
+static PyObject *Qt_MusicGetMIDIPorts(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MusicComponent mc;
+	long inputPortCount;
+	long outputPortCount;
+#ifndef MusicGetMIDIPorts
+	PyMac_PRECHECK(MusicGetMIDIPorts);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &mc))
+		return NULL;
+	_rv = MusicGetMIDIPorts(mc,
+	                        &inputPortCount,
+	                        &outputPortCount);
+	_res = Py_BuildValue("lll",
+	                     _rv,
+	                     inputPortCount,
+	                     outputPortCount);
+	return _res;
+}
+
+static PyObject *Qt_MusicSendMIDI(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MusicComponent mc;
+	long portIndex;
+	MusicMIDIPacket mp;
+#ifndef MusicSendMIDI
+	PyMac_PRECHECK(MusicSendMIDI);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&lO&",
+	                      CmpInstObj_Convert, &mc,
+	                      &portIndex,
+	                      QtMusicMIDIPacket_Convert, &mp))
+		return NULL;
+	_rv = MusicSendMIDI(mc,
+	                    portIndex,
+	                    &mp);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MusicSetOfflineTimeTo(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MusicComponent mc;
+	long newTimeStamp;
+#ifndef MusicSetOfflineTimeTo
+	PyMac_PRECHECK(MusicSetOfflineTimeTo);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &mc,
+	                      &newTimeStamp))
+		return NULL;
+	_rv = MusicSetOfflineTimeTo(mc,
+	                            newTimeStamp);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MusicGetInfoText(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MusicComponent mc;
+	long selector;
+	Handle textH;
+	Handle styleH;
+#ifndef MusicGetInfoText
+	PyMac_PRECHECK(MusicGetInfoText);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &mc,
+	                      &selector))
+		return NULL;
+	_rv = MusicGetInfoText(mc,
+	                       selector,
+	                       &textH,
+	                       &styleH);
+	_res = Py_BuildValue("lO&O&",
+	                     _rv,
+	                     ResObj_New, textH,
+	                     ResObj_New, styleH);
+	return _res;
+}
+
+static PyObject *Qt_MusicGetInstrumentInfo(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MusicComponent mc;
+	long getInstrumentInfoFlags;
+	InstrumentInfoListHandle infoListH;
+#ifndef MusicGetInstrumentInfo
+	PyMac_PRECHECK(MusicGetInstrumentInfo);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &mc,
+	                      &getInstrumentInfoFlags))
+		return NULL;
+	_rv = MusicGetInstrumentInfo(mc,
+	                             getInstrumentInfoFlags,
+	                             &infoListH);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     ResObj_New, infoListH);
+	return _res;
+}
+
+static PyObject *Qt_MusicTask(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MusicComponent mc;
+#ifndef MusicTask
+	PyMac_PRECHECK(MusicTask);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &mc))
+		return NULL;
+	_rv = MusicTask(mc);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MusicSetPartInstrumentNumberInterruptSafe(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MusicComponent mc;
+	long part;
+	long instrumentNumber;
+#ifndef MusicSetPartInstrumentNumberInterruptSafe
+	PyMac_PRECHECK(MusicSetPartInstrumentNumberInterruptSafe);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&ll",
+	                      CmpInstObj_Convert, &mc,
+	                      &part,
+	                      &instrumentNumber))
+		return NULL;
+	_rv = MusicSetPartInstrumentNumberInterruptSafe(mc,
+	                                                part,
+	                                                instrumentNumber);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MusicSetPartSoundLocalization(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MusicComponent mc;
+	long part;
+	Handle data;
+#ifndef MusicSetPartSoundLocalization
+	PyMac_PRECHECK(MusicSetPartSoundLocalization);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&lO&",
+	                      CmpInstObj_Convert, &mc,
+	                      &part,
+	                      ResObj_Convert, &data))
+		return NULL;
+	_rv = MusicSetPartSoundLocalization(mc,
+	                                    part,
+	                                    data);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MusicGenericConfigure(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MusicComponent mc;
+	long mode;
+	long flags;
+	long baseResID;
+#ifndef MusicGenericConfigure
+	PyMac_PRECHECK(MusicGenericConfigure);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&lll",
+	                      CmpInstObj_Convert, &mc,
+	                      &mode,
+	                      &flags,
+	                      &baseResID))
+		return NULL;
+	_rv = MusicGenericConfigure(mc,
+	                            mode,
+	                            flags,
+	                            baseResID);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MusicGenericGetKnobList(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MusicComponent mc;
+	long knobType;
+	GenericKnobDescriptionListHandle gkdlH;
+#ifndef MusicGenericGetKnobList
+	PyMac_PRECHECK(MusicGenericGetKnobList);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &mc,
+	                      &knobType))
+		return NULL;
+	_rv = MusicGenericGetKnobList(mc,
+	                              knobType,
+	                              &gkdlH);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     ResObj_New, gkdlH);
+	return _res;
+}
+
+static PyObject *Qt_MusicGenericSetResourceNumbers(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MusicComponent mc;
+	Handle resourceIDH;
+#ifndef MusicGenericSetResourceNumbers
+	PyMac_PRECHECK(MusicGenericSetResourceNumbers);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpInstObj_Convert, &mc,
+	                      ResObj_Convert, &resourceIDH))
+		return NULL;
+	_rv = MusicGenericSetResourceNumbers(mc,
+	                                     resourceIDH);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MusicDerivedMIDISend(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MusicComponent mc;
+	MusicMIDIPacket packet;
+#ifndef MusicDerivedMIDISend
+	PyMac_PRECHECK(MusicDerivedMIDISend);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpInstObj_Convert, &mc,
+	                      QtMusicMIDIPacket_Convert, &packet))
+		return NULL;
+	_rv = MusicDerivedMIDISend(mc,
+	                           &packet);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MusicDerivedOpenResFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MusicComponent mc;
+#ifndef MusicDerivedOpenResFile
+	PyMac_PRECHECK(MusicDerivedOpenResFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &mc))
+		return NULL;
+	_rv = MusicDerivedOpenResFile(mc);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_MusicDerivedCloseResFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	MusicComponent mc;
+	short resRefNum;
+#ifndef MusicDerivedCloseResFile
+	PyMac_PRECHECK(MusicDerivedCloseResFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      CmpInstObj_Convert, &mc,
+	                      &resRefNum))
+		return NULL;
+	_rv = MusicDerivedCloseResFile(mc,
+	                               resRefNum);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_NAUnregisterMusicDevice(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	NoteAllocator na;
+	long index;
+#ifndef NAUnregisterMusicDevice
+	PyMac_PRECHECK(NAUnregisterMusicDevice);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &na,
+	                      &index))
+		return NULL;
+	_rv = NAUnregisterMusicDevice(na,
+	                              index);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_NASaveMusicConfiguration(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	NoteAllocator na;
+#ifndef NASaveMusicConfiguration
+	PyMac_PRECHECK(NASaveMusicConfiguration);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &na))
+		return NULL;
+	_rv = NASaveMusicConfiguration(na);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_NAGetMIDIPorts(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	NoteAllocator na;
+	QTMIDIPortListHandle inputPorts;
+	QTMIDIPortListHandle outputPorts;
+#ifndef NAGetMIDIPorts
+	PyMac_PRECHECK(NAGetMIDIPorts);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &na))
+		return NULL;
+	_rv = NAGetMIDIPorts(na,
+	                     &inputPorts,
+	                     &outputPorts);
+	_res = Py_BuildValue("lO&O&",
+	                     _rv,
+	                     ResObj_New, inputPorts,
+	                     ResObj_New, outputPorts);
+	return _res;
+}
+
+static PyObject *Qt_NATask(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	NoteAllocator na;
+#ifndef NATask
+	PyMac_PRECHECK(NATask);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &na))
+		return NULL;
+	_rv = NATask(na);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_TuneSetHeader(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	TunePlayer tp;
+	unsigned long * header;
+#ifndef TuneSetHeader
+	PyMac_PRECHECK(TuneSetHeader);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&s",
+	                      CmpInstObj_Convert, &tp,
+	                      &header))
+		return NULL;
+	_rv = TuneSetHeader(tp,
+	                    header);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_TuneGetTimeBase(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	TunePlayer tp;
+	TimeBase tb;
+#ifndef TuneGetTimeBase
+	PyMac_PRECHECK(TuneGetTimeBase);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &tp))
+		return NULL;
+	_rv = TuneGetTimeBase(tp,
+	                      &tb);
+	_res = Py_BuildValue("lO&",
+	                     _rv,
+	                     TimeBaseObj_New, tb);
+	return _res;
+}
+
+static PyObject *Qt_TuneSetTimeScale(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	TunePlayer tp;
+	TimeScale scale;
+#ifndef TuneSetTimeScale
+	PyMac_PRECHECK(TuneSetTimeScale);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &tp,
+	                      &scale))
+		return NULL;
+	_rv = TuneSetTimeScale(tp,
+	                       scale);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_TuneGetTimeScale(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	TunePlayer tp;
+	TimeScale scale;
+#ifndef TuneGetTimeScale
+	PyMac_PRECHECK(TuneGetTimeScale);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &tp))
+		return NULL;
+	_rv = TuneGetTimeScale(tp,
+	                       &scale);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     scale);
+	return _res;
+}
+
+static PyObject *Qt_TuneInstant(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	TunePlayer tp;
+	unsigned long tune;
+	unsigned long tunePosition;
+#ifndef TuneInstant
+	PyMac_PRECHECK(TuneInstant);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &tp,
+	                      &tunePosition))
+		return NULL;
+	_rv = TuneInstant(tp,
+	                  &tune,
+	                  tunePosition);
+	_res = Py_BuildValue("ll",
+	                     _rv,
+	                     tune);
+	return _res;
+}
+
+static PyObject *Qt_TuneStop(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	TunePlayer tp;
+	long stopFlags;
+#ifndef TuneStop
+	PyMac_PRECHECK(TuneStop);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &tp,
+	                      &stopFlags))
+		return NULL;
+	_rv = TuneStop(tp,
+	               stopFlags);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_TuneSetVolume(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	TunePlayer tp;
+	Fixed volume;
+#ifndef TuneSetVolume
+	PyMac_PRECHECK(TuneSetVolume);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpInstObj_Convert, &tp,
+	                      PyMac_GetFixed, &volume))
+		return NULL;
+	_rv = TuneSetVolume(tp,
+	                    volume);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_TuneGetVolume(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	TunePlayer tp;
+#ifndef TuneGetVolume
+	PyMac_PRECHECK(TuneGetVolume);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &tp))
+		return NULL;
+	_rv = TuneGetVolume(tp);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_TunePreroll(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	TunePlayer tp;
+#ifndef TunePreroll
+	PyMac_PRECHECK(TunePreroll);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &tp))
+		return NULL;
+	_rv = TunePreroll(tp);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_TuneUnroll(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	TunePlayer tp;
+#ifndef TuneUnroll
+	PyMac_PRECHECK(TuneUnroll);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &tp))
+		return NULL;
+	_rv = TuneUnroll(tp);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_TuneSetPartTranspose(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	TunePlayer tp;
+	unsigned long part;
+	long transpose;
+	long velocityShift;
+#ifndef TuneSetPartTranspose
+	PyMac_PRECHECK(TuneSetPartTranspose);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&lll",
+	                      CmpInstObj_Convert, &tp,
+	                      &part,
+	                      &transpose,
+	                      &velocityShift))
+		return NULL;
+	_rv = TuneSetPartTranspose(tp,
+	                           part,
+	                           transpose,
+	                           velocityShift);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_TuneGetNoteAllocator(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	NoteAllocator _rv;
+	TunePlayer tp;
+#ifndef TuneGetNoteAllocator
+	PyMac_PRECHECK(TuneGetNoteAllocator);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &tp))
+		return NULL;
+	_rv = TuneGetNoteAllocator(tp);
+	_res = Py_BuildValue("O&",
+	                     CmpInstObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Qt_TuneSetSofter(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	TunePlayer tp;
+	long softer;
+#ifndef TuneSetSofter
+	PyMac_PRECHECK(TuneSetSofter);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &tp,
+	                      &softer))
+		return NULL;
+	_rv = TuneSetSofter(tp,
+	                    softer);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_TuneTask(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	TunePlayer tp;
+#ifndef TuneTask
+	PyMac_PRECHECK(TuneTask);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CmpInstObj_Convert, &tp))
+		return NULL;
+	_rv = TuneTask(tp);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_TuneSetBalance(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	TunePlayer tp;
+	long balance;
+#ifndef TuneSetBalance
+	PyMac_PRECHECK(TuneSetBalance);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &tp,
+	                      &balance))
+		return NULL;
+	_rv = TuneSetBalance(tp,
+	                     balance);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_TuneSetSoundLocalization(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	TunePlayer tp;
+	Handle data;
+#ifndef TuneSetSoundLocalization
+	PyMac_PRECHECK(TuneSetSoundLocalization);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CmpInstObj_Convert, &tp,
+	                      ResObj_Convert, &data))
+		return NULL;
+	_rv = TuneSetSoundLocalization(tp,
+	                               data);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_TuneSetHeaderWithSize(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	TunePlayer tp;
+	unsigned long * header;
+	unsigned long size;
+#ifndef TuneSetHeaderWithSize
+	PyMac_PRECHECK(TuneSetHeaderWithSize);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&sl",
+	                      CmpInstObj_Convert, &tp,
+	                      &header,
+	                      &size))
+		return NULL;
+	_rv = TuneSetHeaderWithSize(tp,
+	                            header,
+	                            size);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_TuneSetPartMix(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	TunePlayer tp;
+	unsigned long partNumber;
+	long volume;
+	long balance;
+	long mixFlags;
+#ifndef TuneSetPartMix
+	PyMac_PRECHECK(TuneSetPartMix);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&llll",
+	                      CmpInstObj_Convert, &tp,
+	                      &partNumber,
+	                      &volume,
+	                      &balance,
+	                      &mixFlags))
+		return NULL;
+	_rv = TuneSetPartMix(tp,
+	                     partNumber,
+	                     volume,
+	                     balance,
+	                     mixFlags);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Qt_TuneGetPartMix(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ComponentResult _rv;
+	TunePlayer tp;
+	unsigned long partNumber;
+	long volumeOut;
+	long balanceOut;
+	long mixFlagsOut;
+#ifndef TuneGetPartMix
+	PyMac_PRECHECK(TuneGetPartMix);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      CmpInstObj_Convert, &tp,
+	                      &partNumber))
+		return NULL;
+	_rv = TuneGetPartMix(tp,
+	                     partNumber,
+	                     &volumeOut,
+	                     &balanceOut,
+	                     &mixFlagsOut);
+	_res = Py_BuildValue("llll",
+	                     _rv,
+	                     volumeOut,
+	                     balanceOut,
+	                     mixFlagsOut);
+	return _res;
+}
+
+static PyObject *Qt_AlignWindow(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	WindowPtr wp;
+	Boolean front;
+#ifndef AlignWindow
+	PyMac_PRECHECK(AlignWindow);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&b",
+	                      WinObj_Convert, &wp,
+	                      &front))
+		return NULL;
+	AlignWindow(wp,
+	            front,
+	            (Rect *)0,
+	            (ICMAlignmentProcRecordPtr)0);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qt_DragAlignedWindow(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	WindowPtr wp;
+	Point startPt;
+	Rect boundsRect;
+#ifndef DragAlignedWindow
+	PyMac_PRECHECK(DragAlignedWindow);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      WinObj_Convert, &wp,
+	                      PyMac_GetPoint, &startPt,
+	                      PyMac_GetRect, &boundsRect))
+		return NULL;
+	DragAlignedWindow(wp,
+	                  startPt,
+	                  &boundsRect,
+	                  (Rect *)0,
+	                  (ICMAlignmentProcRecordPtr)0);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Qt_MoviesTask(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long maxMilliSecToUse;
+#ifndef MoviesTask
+	PyMac_PRECHECK(MoviesTask);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &maxMilliSecToUse))
+		return NULL;
+	MoviesTask((Movie)0,
+	           maxMilliSecToUse);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyMethodDef Qt_methods[] = {
+	{"EnterMovies", (PyCFunction)Qt_EnterMovies, 1,
+	 PyDoc_STR("() -> None")},
+	{"ExitMovies", (PyCFunction)Qt_ExitMovies, 1,
+	 PyDoc_STR("() -> None")},
+	{"GetMoviesError", (PyCFunction)Qt_GetMoviesError, 1,
+	 PyDoc_STR("() -> None")},
+	{"ClearMoviesStickyError", (PyCFunction)Qt_ClearMoviesStickyError, 1,
+	 PyDoc_STR("() -> None")},
+	{"GetMoviesStickyError", (PyCFunction)Qt_GetMoviesStickyError, 1,
+	 PyDoc_STR("() -> None")},
+	{"QTGetWallClockTimeBase", (PyCFunction)Qt_QTGetWallClockTimeBase, 1,
+	 PyDoc_STR("() -> (TimeBase wallClockTimeBase)")},
+	{"QTIdleManagerOpen", (PyCFunction)Qt_QTIdleManagerOpen, 1,
+	 PyDoc_STR("() -> (IdleManager _rv)")},
+	{"CreateMovieControl", (PyCFunction)Qt_CreateMovieControl, 1,
+	 PyDoc_STR("(WindowPtr theWindow, Movie theMovie, UInt32 options) -> (Rect localRect, ControlHandle returnedControl)")},
+	{"DisposeMatte", (PyCFunction)Qt_DisposeMatte, 1,
+	 PyDoc_STR("(PixMapHandle theMatte) -> None")},
+	{"NewMovie", (PyCFunction)Qt_NewMovie, 1,
+	 PyDoc_STR("(long flags) -> (Movie _rv)")},
+	{"QTGetTimeUntilNextTask", (PyCFunction)Qt_QTGetTimeUntilNextTask, 1,
+	 PyDoc_STR("(long scale) -> (long duration)")},
+	{"GetDataHandler", (PyCFunction)Qt_GetDataHandler, 1,
+	 PyDoc_STR("(Handle dataRef, OSType dataHandlerSubType, long flags) -> (Component _rv)")},
+	{"PasteHandleIntoMovie", (PyCFunction)Qt_PasteHandleIntoMovie, 1,
+	 PyDoc_STR("(Handle h, OSType handleType, Movie theMovie, long flags, ComponentInstance userComp) -> None")},
+	{"GetMovieImporterForDataRef", (PyCFunction)Qt_GetMovieImporterForDataRef, 1,
+	 PyDoc_STR("(OSType dataRefType, Handle dataRef, long flags) -> (Component importer)")},
+	{"QTGetMIMETypeInfo", (PyCFunction)Qt_QTGetMIMETypeInfo, 1,
+	 PyDoc_STR("(char* mimeStringStart, short mimeStringLength, OSType infoSelector, void * infoDataPtr) -> (long infoDataSize)")},
+	{"TrackTimeToMediaTime", (PyCFunction)Qt_TrackTimeToMediaTime, 1,
+	 PyDoc_STR("(TimeValue value, Track theTrack) -> (TimeValue _rv)")},
+	{"NewUserData", (PyCFunction)Qt_NewUserData, 1,
+	 PyDoc_STR("() -> (UserData theUserData)")},
+	{"NewUserDataFromHandle", (PyCFunction)Qt_NewUserDataFromHandle, 1,
+	 PyDoc_STR("(Handle h) -> (UserData theUserData)")},
+	{"CreateMovieFile", (PyCFunction)Qt_CreateMovieFile, 1,
+	 PyDoc_STR("(FSSpec fileSpec, OSType creator, ScriptCode scriptTag, long createMovieFileFlags) -> (short resRefNum, Movie newmovie)")},
+	{"OpenMovieFile", (PyCFunction)Qt_OpenMovieFile, 1,
+	 PyDoc_STR("(FSSpec fileSpec, SInt8 permission) -> (short resRefNum)")},
+	{"CloseMovieFile", (PyCFunction)Qt_CloseMovieFile, 1,
+	 PyDoc_STR("(short resRefNum) -> None")},
+	{"DeleteMovieFile", (PyCFunction)Qt_DeleteMovieFile, 1,
+	 PyDoc_STR("(FSSpec fileSpec) -> None")},
+	{"NewMovieFromFile", (PyCFunction)Qt_NewMovieFromFile, 1,
+	 PyDoc_STR("(short resRefNum, short resId, short newMovieFlags) -> (Movie theMovie, short resId, Boolean dataRefWasChanged)")},
+	{"NewMovieFromHandle", (PyCFunction)Qt_NewMovieFromHandle, 1,
+	 PyDoc_STR("(Handle h, short newMovieFlags) -> (Movie theMovie, Boolean dataRefWasChanged)")},
+	{"NewMovieFromDataFork", (PyCFunction)Qt_NewMovieFromDataFork, 1,
+	 PyDoc_STR("(short fRefNum, long fileOffset, short newMovieFlags) -> (Movie theMovie, Boolean dataRefWasChanged)")},
+	{"NewMovieFromDataFork64", (PyCFunction)Qt_NewMovieFromDataFork64, 1,
+	 PyDoc_STR("(long fRefNum, wide fileOffset, short newMovieFlags) -> (Movie theMovie, Boolean dataRefWasChanged)")},
+	{"NewMovieFromDataRef", (PyCFunction)Qt_NewMovieFromDataRef, 1,
+	 PyDoc_STR("(short flags, Handle dataRef, OSType dtaRefType) -> (Movie m, short id)")},
+	{"NewMovieFromStorageOffset", (PyCFunction)Qt_NewMovieFromStorageOffset, 1,
+	 PyDoc_STR("(DataHandler dh, wide fileOffset, short newMovieFlags) -> (Movie theMovie, Boolean dataRefWasCataRefType)")},
+	{"NewMovieForDataRefFromHandle", (PyCFunction)Qt_NewMovieForDataRefFromHandle, 1,
+	 PyDoc_STR("(Handle h, short newMovieFlags, Handle dataRef, OSType dataRefType) -> (Movie theMovie, Boolean dataRefWasChanged)")},
+	{"RemoveMovieResource", (PyCFunction)Qt_RemoveMovieResource, 1,
+	 PyDoc_STR("(short resRefNum, short resId) -> None")},
+	{"CreateMovieStorage", (PyCFunction)Qt_CreateMovieStorage, 1,
+	 PyDoc_STR("(Handle dataRef, OSType dataRefType, OSType creator, ScriptCode scriptTag, long createMovieFileFlags) -> (DataHandler outDataHandler, Movie newmovie)")},
+	{"OpenMovieStorage", (PyCFunction)Qt_OpenMovieStorage, 1,
+	 PyDoc_STR("(Handle dataRef, OSType dataRefType, long flags) -> (DataHandler outDataHandler)")},
+	{"CloseMovieStorage", (PyCFunction)Qt_CloseMovieStorage, 1,
+	 PyDoc_STR("(DataHandler dh) -> None")},
+	{"DeleteMovieStorage", (PyCFunction)Qt_DeleteMovieStorage, 1,
+	 PyDoc_STR("(Handle dataRef, OSType dataRefType) -> None")},
+	{"CreateShortcutMovieFile", (PyCFunction)Qt_CreateShortcutMovieFile, 1,
+	 PyDoc_STR("(FSSpec fileSpec, OSType creator, ScriptCode scriptTag, long createMovieFileFlags, Handle targetDataRef, OSType targetDataRefType) -> None")},
+	{"CanQuickTimeOpenFile", (PyCFunction)Qt_CanQuickTimeOpenFile, 1,
+	 PyDoc_STR("(FSSpec fileSpec, OSType fileType, OSType fileNameExtension, UInt32 inFlags) -> (Boolean outCanOpenWithGraphicsImporter, Boolean outCanOpenAsMovie, Boolean outPreferGraphicsImporter)")},
+	{"CanQuickTimeOpenDataRef", (PyCFunction)Qt_CanQuickTimeOpenDataRef, 1,
+	 PyDoc_STR("(Handle dataRef, OSType dataRefType, UInt32 inFlags) -> (Boolean outCanOpenWithGraphicsImporter, Boolean outCanOpenAsMovie, Boolean outPreferGraphicsImporter)")},
+	{"NewMovieFromScrap", (PyCFunction)Qt_NewMovieFromScrap, 1,
+	 PyDoc_STR("(long newMovieFlags) -> (Movie _rv)")},
+	{"QTNewAlias", (PyCFunction)Qt_QTNewAlias, 1,
+	 PyDoc_STR("(FSSpec fss, Boolean minimal) -> (AliasHandle alias)")},
+	{"EndFullScreen", (PyCFunction)Qt_EndFullScreen, 1,
+	 PyDoc_STR("(Ptr fullState, long flags) -> None")},
+	{"AddSoundDescriptionExtension", (PyCFunction)Qt_AddSoundDescriptionExtension, 1,
+	 PyDoc_STR("(SoundDescriptionHandle desc, Handle extension, OSType idType) -> None")},
+	{"GetSoundDescriptionExtension", (PyCFunction)Qt_GetSoundDescriptionExtension, 1,
+	 PyDoc_STR("(SoundDescriptionHandle desc, OSType idType) -> (Handle extension)")},
+	{"RemoveSoundDescriptionExtension", (PyCFunction)Qt_RemoveSoundDescriptionExtension, 1,
+	 PyDoc_STR("(SoundDescriptionHandle desc, OSType idType) -> None")},
+	{"QTIsStandardParameterDialogEvent", (PyCFunction)Qt_QTIsStandardParameterDialogEvent, 1,
+	 PyDoc_STR("(QTParameterDialog createdDialog) -> (EventRecord pEvent)")},
+	{"QTDismissStandardParameterDialog", (PyCFunction)Qt_QTDismissStandardParameterDialog, 1,
+	 PyDoc_STR("(QTParameterDialog createdDialog) -> None")},
+	{"QTStandardParameterDialogDoAction", (PyCFunction)Qt_QTStandardParameterDialogDoAction, 1,
+	 PyDoc_STR("(QTParameterDialog createdDialog, long action, void * params) -> None")},
+	{"QTRegisterAccessKey", (PyCFunction)Qt_QTRegisterAccessKey, 1,
+	 PyDoc_STR("(Str255 accessKeyType, long flags, Handle accessKey) -> None")},
+	{"QTUnregisterAccessKey", (PyCFunction)Qt_QTUnregisterAccessKey, 1,
+	 PyDoc_STR("(Str255 accessKeyType, long flags, Handle accessKey) -> None")},
+	{"QTGetSupportedRestrictions", (PyCFunction)Qt_QTGetSupportedRestrictions, 1,
+	 PyDoc_STR("(OSType inRestrictionClass) -> (UInt32 outRestrictionIDs)")},
+	{"QTTextToNativeText", (PyCFunction)Qt_QTTextToNativeText, 1,
+	 PyDoc_STR("(Handle theText, long encoding, long flags) -> None")},
+	{"VideoMediaResetStatistics", (PyCFunction)Qt_VideoMediaResetStatistics, 1,
+	 PyDoc_STR("(MediaHandler mh) -> (ComponentResult _rv)")},
+	{"VideoMediaGetStatistics", (PyCFunction)Qt_VideoMediaGetStatistics, 1,
+	 PyDoc_STR("(MediaHandler mh) -> (ComponentResult _rv)")},
+	{"VideoMediaGetStallCount", (PyCFunction)Qt_VideoMediaGetStallCount, 1,
+	 PyDoc_STR("(MediaHandler mh) -> (ComponentResult _rv, unsigned long stalls)")},
+	{"VideoMediaSetCodecParameter", (PyCFunction)Qt_VideoMediaSetCodecParameter, 1,
+	 PyDoc_STR("(MediaHandler mh, CodecType cType, OSType parameterID, long parameterChangeSeed, void * dataPtr, long dataSize) -> (ComponentResult _rv)")},
+	{"VideoMediaGetCodecParameter", (PyCFunction)Qt_VideoMediaGetCodecParameter, 1,
+	 PyDoc_STR("(MediaHandler mh, CodecType cType, OSType parameterID, Handle outParameterData) -> (ComponentResult _rv)")},
+	{"TextMediaAddTextSample", (PyCFunction)Qt_TextMediaAddTextSample, 1,
+	 PyDoc_STR("(MediaHandler mh, Ptr text, unsigned long size, short fontNumber, short fontSize, Style textFace, short textJustification, long displayFlags, TimeValue scrollDelay, short hiliteStart, short hiliteEnd, TimeValue duration) -> (ComponentResult _rv, RGBColor textColor, RGBColor backColor, Rect textBox, RGBColor rgbHiliteColor, TimeValue sampleTime)")},
+	{"TextMediaAddTESample", (PyCFunction)Qt_TextMediaAddTESample, 1,
+	 PyDoc_STR("(MediaHandler mh, TEHandle hTE, short textJustification, long displayFlags, TimeValue scrollDelay, short hiliteStart, short hiliteEnd, TimeValue duration) -> (ComponentResult _rv, RGBColor backColor, Rect textBox, RGBColor rgbHiliteColor, TimeValue sampleTime)")},
+	{"TextMediaAddHiliteSample", (PyCFunction)Qt_TextMediaAddHiliteSample, 1,
+	 PyDoc_STR("(MediaHandler mh, short hiliteStart, short hiliteEnd, TimeValue duration) -> (ComponentResult _rv, RGBColor rgbHiliteColor, TimeValue sampleTime)")},
+	{"TextMediaDrawRaw", (PyCFunction)Qt_TextMediaDrawRaw, 1,
+	 PyDoc_STR("(MediaHandler mh, GWorldPtr gw, GDHandle gd, void * data, long dataSize, TextDescriptionHandle tdh) -> (ComponentResult _rv)")},
+	{"TextMediaSetTextProperty", (PyCFunction)Qt_TextMediaSetTextProperty, 1,
+	 PyDoc_STR("(MediaHandler mh, TimeValue atMediaTime, long propertyType, void * data, long dataSize) -> (ComponentResult _rv)")},
+	{"TextMediaRawSetup", (PyCFunction)Qt_TextMediaRawSetup, 1,
+	 PyDoc_STR("(MediaHandler mh, GWorldPtr gw, GDHandle gd, void * data, long dataSize, TextDescriptionHandle tdh, TimeValue sampleDuration) -> (ComponentResult _rv)")},
+	{"TextMediaRawIdle", (PyCFunction)Qt_TextMediaRawIdle, 1,
+	 PyDoc_STR("(MediaHandler mh, GWorldPtr gw, GDHandle gd, TimeValue sampleTime, long flagsIn) -> (ComponentResult _rv, long flagsOut)")},
+	{"TextMediaGetTextProperty", (PyCFunction)Qt_TextMediaGetTextProperty, 1,
+	 PyDoc_STR("(MediaHandler mh, TimeValue atMediaTime, long propertyType, void * data, long dataSize) -> (ComponentResult _rv)")},
+	{"TextMediaFindNextText", (PyCFunction)Qt_TextMediaFindNextText, 1,
+	 PyDoc_STR("(MediaHandler mh, Ptr text, long size, short findFlags, TimeValue startTime) -> (ComponentResult _rv, TimeValue foundTime, TimeValue foundDuration, long offset)")},
+	{"TextMediaHiliteTextSample", (PyCFunction)Qt_TextMediaHiliteTextSample, 1,
+	 PyDoc_STR("(MediaHandler mh, TimeValue sampleTime, short hiliteStart, short hiliteEnd) -> (ComponentResult _rv, RGBColor rgbHiliteColor)")},
+	{"TextMediaSetTextSampleData", (PyCFunction)Qt_TextMediaSetTextSampleData, 1,
+	 PyDoc_STR("(MediaHandler mh, void * data, OSType dataType) -> (ComponentResult _rv)")},
+	{"SpriteMediaSetProperty", (PyCFunction)Qt_SpriteMediaSetProperty, 1,
+	 PyDoc_STR("(MediaHandler mh, short spriteIndex, long propertyType, void * propertyValue) -> (ComponentResult _rv)")},
+	{"SpriteMediaGetProperty", (PyCFunction)Qt_SpriteMediaGetProperty, 1,
+	 PyDoc_STR("(MediaHandler mh, short spriteIndex, long propertyType, void * propertyValue) -> (ComponentResult _rv)")},
+	{"SpriteMediaHitTestSprites", (PyCFunction)Qt_SpriteMediaHitTestSprites, 1,
+	 PyDoc_STR("(MediaHandler mh, long flags, Point loc) -> (ComponentResult _rv, short spriteHitIndex)")},
+	{"SpriteMediaCountSprites", (PyCFunction)Qt_SpriteMediaCountSprites, 1,
+	 PyDoc_STR("(MediaHandler mh) -> (ComponentResult _rv, short numSprites)")},
+	{"SpriteMediaCountImages", (PyCFunction)Qt_SpriteMediaCountImages, 1,
+	 PyDoc_STR("(MediaHandler mh) -> (ComponentResult _rv, short numImages)")},
+	{"SpriteMediaGetIndImageDescription", (PyCFunction)Qt_SpriteMediaGetIndImageDescription, 1,
+	 PyDoc_STR("(MediaHandler mh, short imageIndex, ImageDescriptionHandle imageDescription) -> (ComponentResult _rv)")},
+	{"SpriteMediaGetDisplayedSampleNumber", (PyCFunction)Qt_SpriteMediaGetDisplayedSampleNumber, 1,
+	 PyDoc_STR("(MediaHandler mh) -> (ComponentResult _rv, long sampleNum)")},
+	{"SpriteMediaGetSpriteName", (PyCFunction)Qt_SpriteMediaGetSpriteName, 1,
+	 PyDoc_STR("(MediaHandler mh, QTAtomID spriteID, Str255 spriteName) -> (ComponentResult _rv)")},
+	{"SpriteMediaGetImageName", (PyCFunction)Qt_SpriteMediaGetImageName, 1,
+	 PyDoc_STR("(MediaHandler mh, short imageIndex, Str255 imageName) -> (ComponentResult _rv)")},
+	{"SpriteMediaSetSpriteProperty", (PyCFunction)Qt_SpriteMediaSetSpriteProperty, 1,
+	 PyDoc_STR("(MediaHandler mh, QTAtomID spriteID, long propertyType, void * propertyValue) -> (ComponentResult _rv)")},
+	{"SpriteMediaGetSpriteProperty", (PyCFunction)Qt_SpriteMediaGetSpriteProperty, 1,
+	 PyDoc_STR("(MediaHandler mh, QTAtomID spriteID, long propertyType, void * propertyValue) -> (ComponentResult _rv)")},
+	{"SpriteMediaHitTestAllSprites", (PyCFunction)Qt_SpriteMediaHitTestAllSprites, 1,
+	 PyDoc_STR("(MediaHandler mh, long flags, Point loc) -> (ComponentResult _rv, QTAtomID spriteHitID)")},
+	{"SpriteMediaHitTestOneSprite", (PyCFunction)Qt_SpriteMediaHitTestOneSprite, 1,
+	 PyDoc_STR("(MediaHandler mh, QTAtomID spriteID, long flags, Point loc) -> (ComponentResult _rv, Boolean wasHit)")},
+	{"SpriteMediaSpriteIndexToID", (PyCFunction)Qt_SpriteMediaSpriteIndexToID, 1,
+	 PyDoc_STR("(MediaHandler mh, short spriteIndex) -> (ComponentResult _rv, QTAtomID spriteID)")},
+	{"SpriteMediaSpriteIDToIndex", (PyCFunction)Qt_SpriteMediaSpriteIDToIndex, 1,
+	 PyDoc_STR("(MediaHandler mh, QTAtomID spriteID) -> (ComponentResult _rv, short spriteIndex)")},
+	{"SpriteMediaSetActionVariable", (PyCFunction)Qt_SpriteMediaSetActionVariable, 1,
+	 PyDoc_STR("(MediaHandler mh, QTAtomID variableID, float value) -> (ComponentResult _rv)")},
+	{"SpriteMediaGetActionVariable", (PyCFunction)Qt_SpriteMediaGetActionVariable, 1,
+	 PyDoc_STR("(MediaHandler mh, QTAtomID variableID) -> (ComponentResult _rv, float value)")},
+	{"SpriteMediaDisposeSprite", (PyCFunction)Qt_SpriteMediaDisposeSprite, 1,
+	 PyDoc_STR("(MediaHandler mh, QTAtomID spriteID) -> (ComponentResult _rv)")},
+	{"SpriteMediaSetActionVariableToString", (PyCFunction)Qt_SpriteMediaSetActionVariableToString, 1,
+	 PyDoc_STR("(MediaHandler mh, QTAtomID variableID, Ptr theCString) -> (ComponentResult _rv)")},
+	{"SpriteMediaGetActionVariableAsString", (PyCFunction)Qt_SpriteMediaGetActionVariableAsString, 1,
+	 PyDoc_STR("(MediaHandler mh, QTAtomID variableID) -> (ComponentResult _rv, Handle theCString)")},
+	{"SpriteMediaNewImage", (PyCFunction)Qt_SpriteMediaNewImage, 1,
+	 PyDoc_STR("(MediaHandler mh, Handle dataRef, OSType dataRefType, QTAtomID desiredID) -> (ComponentResult _rv)")},
+	{"SpriteMediaDisposeImage", (PyCFunction)Qt_SpriteMediaDisposeImage, 1,
+	 PyDoc_STR("(MediaHandler mh, short imageIndex) -> (ComponentResult _rv)")},
+	{"SpriteMediaImageIndexToID", (PyCFunction)Qt_SpriteMediaImageIndexToID, 1,
+	 PyDoc_STR("(MediaHandler mh, short imageIndex) -> (ComponentResult _rv, QTAtomID imageID)")},
+	{"SpriteMediaImageIDToIndex", (PyCFunction)Qt_SpriteMediaImageIDToIndex, 1,
+	 PyDoc_STR("(MediaHandler mh, QTAtomID imageID) -> (ComponentResult _rv, short imageIndex)")},
+	{"FlashMediaSetPan", (PyCFunction)Qt_FlashMediaSetPan, 1,
+	 PyDoc_STR("(MediaHandler mh, short xPercent, short yPercent) -> (ComponentResult _rv)")},
+	{"FlashMediaSetZoom", (PyCFunction)Qt_FlashMediaSetZoom, 1,
+	 PyDoc_STR("(MediaHandler mh, short factor) -> (ComponentResult _rv)")},
+	{"FlashMediaSetZoomRect", (PyCFunction)Qt_FlashMediaSetZoomRect, 1,
+	 PyDoc_STR("(MediaHandler mh, long left, long top, long right, long bottom) -> (ComponentResult _rv)")},
+	{"FlashMediaGetRefConBounds", (PyCFunction)Qt_FlashMediaGetRefConBounds, 1,
+	 PyDoc_STR("(MediaHandler mh, long refCon) -> (ComponentResult _rv, long left, long top, long right, long bottom)")},
+	{"FlashMediaGetRefConID", (PyCFunction)Qt_FlashMediaGetRefConID, 1,
+	 PyDoc_STR("(MediaHandler mh, long refCon) -> (ComponentResult _rv, long refConID)")},
+	{"FlashMediaIDToRefCon", (PyCFunction)Qt_FlashMediaIDToRefCon, 1,
+	 PyDoc_STR("(MediaHandler mh, long refConID) -> (ComponentResult _rv, long refCon)")},
+	{"FlashMediaGetDisplayedFrameNumber", (PyCFunction)Qt_FlashMediaGetDisplayedFrameNumber, 1,
+	 PyDoc_STR("(MediaHandler mh) -> (ComponentResult _rv, long flashFrameNumber)")},
+	{"FlashMediaFrameNumberToMovieTime", (PyCFunction)Qt_FlashMediaFrameNumberToMovieTime, 1,
+	 PyDoc_STR("(MediaHandler mh, long flashFrameNumber) -> (ComponentResult _rv, TimeValue movieTime)")},
+	{"FlashMediaFrameLabelToMovieTime", (PyCFunction)Qt_FlashMediaFrameLabelToMovieTime, 1,
+	 PyDoc_STR("(MediaHandler mh, Ptr theLabel) -> (ComponentResult _rv, TimeValue movieTime)")},
+	{"FlashMediaGetFlashVariable", (PyCFunction)Qt_FlashMediaGetFlashVariable, 1,
+	 PyDoc_STR("(MediaHandler mh) -> (ComponentResult _rv, char path, char name, Handle theVariableCStringOut)")},
+	{"FlashMediaSetFlashVariable", (PyCFunction)Qt_FlashMediaSetFlashVariable, 1,
+	 PyDoc_STR("(MediaHandler mh, Boolean updateFocus) -> (ComponentResult _rv, char path, char name, char value)")},
+	{"FlashMediaDoButtonActions", (PyCFunction)Qt_FlashMediaDoButtonActions, 1,
+	 PyDoc_STR("(MediaHandler mh, long buttonID, long transition) -> (ComponentResult _rv, char path)")},
+	{"FlashMediaGetSupportedSwfVersion", (PyCFunction)Qt_FlashMediaGetSupportedSwfVersion, 1,
+	 PyDoc_STR("(MediaHandler mh) -> (ComponentResult _rv, UInt8 swfVersion)")},
+	{"Media3DGetCurrentGroup", (PyCFunction)Qt_Media3DGetCurrentGroup, 1,
+	 PyDoc_STR("(MediaHandler mh, void * group) -> (ComponentResult _rv)")},
+	{"Media3DTranslateNamedObjectTo", (PyCFunction)Qt_Media3DTranslateNamedObjectTo, 1,
+	 PyDoc_STR("(MediaHandler mh, Fixed x, Fixed y, Fixed z) -> (ComponentResult _rv, char objectName)")},
+	{"Media3DScaleNamedObjectTo", (PyCFunction)Qt_Media3DScaleNamedObjectTo, 1,
+	 PyDoc_STR("(MediaHandler mh, Fixed xScale, Fixed yScale, Fixed zScale) -> (ComponentResult _rv, char objectName)")},
+	{"Media3DRotateNamedObjectTo", (PyCFunction)Qt_Media3DRotateNamedObjectTo, 1,
+	 PyDoc_STR("(MediaHandler mh, Fixed xDegrees, Fixed yDegrees, Fixed zDegrees) -> (ComponentResult _rv, char objectName)")},
+	{"Media3DSetCameraData", (PyCFunction)Qt_Media3DSetCameraData, 1,
+	 PyDoc_STR("(MediaHandler mh, void * cameraData) -> (ComponentResult _rv)")},
+	{"Media3DGetCameraData", (PyCFunction)Qt_Media3DGetCameraData, 1,
+	 PyDoc_STR("(MediaHandler mh, void * cameraData) -> (ComponentResult _rv)")},
+	{"Media3DSetCameraAngleAspect", (PyCFunction)Qt_Media3DSetCameraAngleAspect, 1,
+	 PyDoc_STR("(MediaHandler mh, QTFloatSingle fov, QTFloatSingle aspectRatioXToY) -> (ComponentResult _rv)")},
+	{"Media3DGetCameraAngleAspect", (PyCFunction)Qt_Media3DGetCameraAngleAspect, 1,
+	 PyDoc_STR("(MediaHandler mh) -> (ComponentResult _rv, QTFloatSingle fov, QTFloatSingle aspectRatioXToY)")},
+	{"Media3DSetCameraRange", (PyCFunction)Qt_Media3DSetCameraRange, 1,
+	 PyDoc_STR("(MediaHandler mh, void * tQ3CameraRange) -> (ComponentResult _rv)")},
+	{"Media3DGetCameraRange", (PyCFunction)Qt_Media3DGetCameraRange, 1,
+	 PyDoc_STR("(MediaHandler mh, void * tQ3CameraRange) -> (ComponentResult _rv)")},
+	{"NewTimeBase", (PyCFunction)Qt_NewTimeBase, 1,
+	 PyDoc_STR("() -> (TimeBase _rv)")},
+	{"ConvertTime", (PyCFunction)Qt_ConvertTime, 1,
+	 PyDoc_STR("(TimeRecord theTime, TimeBase newBase) -> (TimeRecord theTime)")},
+	{"ConvertTimeScale", (PyCFunction)Qt_ConvertTimeScale, 1,
+	 PyDoc_STR("(TimeRecord theTime, TimeScale newScale) -> (TimeRecord theTime)")},
+	{"AddTime", (PyCFunction)Qt_AddTime, 1,
+	 PyDoc_STR("(TimeRecord dst, TimeRecord src) -> (TimeRecord dst)")},
+	{"SubtractTime", (PyCFunction)Qt_SubtractTime, 1,
+	 PyDoc_STR("(TimeRecord dst, TimeRecord src) -> (TimeRecord dst)")},
+	{"MusicMediaGetIndexedTunePlayer", (PyCFunction)Qt_MusicMediaGetIndexedTunePlayer, 1,
+	 PyDoc_STR("(ComponentInstance ti, long sampleDescIndex) -> (ComponentResult _rv, ComponentInstance tp)")},
+	{"CodecManagerVersion", (PyCFunction)Qt_CodecManagerVersion, 1,
+	 PyDoc_STR("() -> (long version)")},
+	{"GetMaxCompressionSize", (PyCFunction)Qt_GetMaxCompressionSize, 1,
+	 PyDoc_STR("(PixMapHandle src, Rect srcRect, short colorDepth, CodecQ quality, CodecType cType, CompressorComponent codec) -> (long size)")},
+	{"GetCompressionTime", (PyCFunction)Qt_GetCompressionTime, 1,
+	 PyDoc_STR("(PixMapHandle src, Rect srcRect, short colorDepth, CodecType cType, CompressorComponent codec) -> (CodecQ spatialQuality, CodecQ temporalQuality, unsigned long compressTime)")},
+	{"CompressImage", (PyCFunction)Qt_CompressImage, 1,
+	 PyDoc_STR("(PixMapHandle src, Rect srcRect, CodecQ quality, CodecType cType, ImageDescriptionHandle desc, Ptr data) -> None")},
+	{"DecompressImage", (PyCFunction)Qt_DecompressImage, 1,
+	 PyDoc_STR("(Ptr data, ImageDescriptionHandle desc, PixMapHandle dst, Rect srcRect, Rect dstRect, short mode, RgnHandle mask) -> None")},
+	{"GetSimilarity", (PyCFunction)Qt_GetSimilarity, 1,
+	 PyDoc_STR("(PixMapHandle src, Rect srcRect, ImageDescriptionHandle desc, Ptr data) -> (Fixed similarity)")},
+	{"GetImageDescriptionCTable", (PyCFunction)Qt_GetImageDescriptionCTable, 1,
+	 PyDoc_STR("(ImageDescriptionHandle desc) -> (CTabHandle ctable)")},
+	{"SetImageDescriptionCTable", (PyCFunction)Qt_SetImageDescriptionCTable, 1,
+	 PyDoc_STR("(ImageDescriptionHandle desc, CTabHandle ctable) -> None")},
+	{"GetImageDescriptionExtension", (PyCFunction)Qt_GetImageDescriptionExtension, 1,
+	 PyDoc_STR("(ImageDescriptionHandle desc, long idType, long index) -> (Handle extension)")},
+	{"AddImageDescriptionExtension", (PyCFunction)Qt_AddImageDescriptionExtension, 1,
+	 PyDoc_STR("(ImageDescriptionHandle desc, Handle extension, long idType) -> None")},
+	{"RemoveImageDescriptionExtension", (PyCFunction)Qt_RemoveImageDescriptionExtension, 1,
+	 PyDoc_STR("(ImageDescriptionHandle desc, long idType, long index) -> None")},
+	{"CountImageDescriptionExtensionType", (PyCFunction)Qt_CountImageDescriptionExtensionType, 1,
+	 PyDoc_STR("(ImageDescriptionHandle desc, long idType) -> (long count)")},
+	{"GetNextImageDescriptionExtensionType", (PyCFunction)Qt_GetNextImageDescriptionExtensionType, 1,
+	 PyDoc_STR("(ImageDescriptionHandle desc) -> (long idType)")},
+	{"FindCodec", (PyCFunction)Qt_FindCodec, 1,
+	 PyDoc_STR("(CodecType cType, CodecComponent specCodec) -> (CompressorComponent compressor, DecompressorComponent decompressor)")},
+	{"CompressPicture", (PyCFunction)Qt_CompressPicture, 1,
+	 PyDoc_STR("(PicHandle srcPicture, PicHandle dstPicture, CodecQ quality, CodecType cType) -> None")},
+	{"CompressPictureFile", (PyCFunction)Qt_CompressPictureFile, 1,
+	 PyDoc_STR("(short srcRefNum, short dstRefNum, CodecQ quality, CodecType cType) -> None")},
+	{"ConvertImage", (PyCFunction)Qt_ConvertImage, 1,
+	 PyDoc_STR("(ImageDescriptionHandle srcDD, Ptr srcData, short colorDepth, CTabHandle ctable, CodecQ accuracy, CodecQ quality, CodecType cType, CodecComponent codec, ImageDescriptionHandle dstDD, Ptr dstData) -> None")},
+	{"AddFilePreview", (PyCFunction)Qt_AddFilePreview, 1,
+	 PyDoc_STR("(short resRefNum, OSType previewType, Handle previewData) -> None")},
+	{"GetBestDeviceRect", (PyCFunction)Qt_GetBestDeviceRect, 1,
+	 PyDoc_STR("() -> (GDHandle gdh, Rect rp)")},
+	{"GDHasScale", (PyCFunction)Qt_GDHasScale, 1,
+	 PyDoc_STR("(GDHandle gdh, short depth) -> (Fixed scale)")},
+	{"GDGetScale", (PyCFunction)Qt_GDGetScale, 1,
+	 PyDoc_STR("(GDHandle gdh) -> (Fixed scale, short flags)")},
+	{"GDSetScale", (PyCFunction)Qt_GDSetScale, 1,
+	 PyDoc_STR("(GDHandle gdh, Fixed scale, short flags) -> None")},
+	{"GetGraphicsImporterForFile", (PyCFunction)Qt_GetGraphicsImporterForFile, 1,
+	 PyDoc_STR("(FSSpec theFile) -> (ComponentInstance gi)")},
+	{"GetGraphicsImporterForDataRef", (PyCFunction)Qt_GetGraphicsImporterForDataRef, 1,
+	 PyDoc_STR("(Handle dataRef, OSType dataRefType) -> (ComponentInstance gi)")},
+	{"GetGraphicsImporterForFileWithFlags", (PyCFunction)Qt_GetGraphicsImporterForFileWithFlags, 1,
+	 PyDoc_STR("(FSSpec theFile, long flags) -> (ComponentInstance gi)")},
+	{"GetGraphicsImporterForDataRefWithFlags", (PyCFunction)Qt_GetGraphicsImporterForDataRefWithFlags, 1,
+	 PyDoc_STR("(Handle dataRef, OSType dataRefType, long flags) -> (ComponentInstance gi)")},
+	{"MakeImageDescriptionForPixMap", (PyCFunction)Qt_MakeImageDescriptionForPixMap, 1,
+	 PyDoc_STR("(PixMapHandle pixmap) -> (ImageDescriptionHandle idh)")},
+	{"MakeImageDescriptionForEffect", (PyCFunction)Qt_MakeImageDescriptionForEffect, 1,
+	 PyDoc_STR("(OSType effectType) -> (ImageDescriptionHandle idh)")},
+	{"QTGetPixelSize", (PyCFunction)Qt_QTGetPixelSize, 1,
+	 PyDoc_STR("(OSType PixelFormat) -> (short _rv)")},
+	{"QTGetPixelFormatDepthForImageDescription", (PyCFunction)Qt_QTGetPixelFormatDepthForImageDescription, 1,
+	 PyDoc_STR("(OSType PixelFormat) -> (short _rv)")},
+	{"QTGetPixMapHandleRowBytes", (PyCFunction)Qt_QTGetPixMapHandleRowBytes, 1,
+	 PyDoc_STR("(PixMapHandle pm) -> (long _rv)")},
+	{"QTSetPixMapHandleRowBytes", (PyCFunction)Qt_QTSetPixMapHandleRowBytes, 1,
+	 PyDoc_STR("(PixMapHandle pm, long rowBytes) -> None")},
+	{"QTGetPixMapHandleGammaLevel", (PyCFunction)Qt_QTGetPixMapHandleGammaLevel, 1,
+	 PyDoc_STR("(PixMapHandle pm) -> (Fixed _rv)")},
+	{"QTSetPixMapHandleGammaLevel", (PyCFunction)Qt_QTSetPixMapHandleGammaLevel, 1,
+	 PyDoc_STR("(PixMapHandle pm, Fixed gammaLevel) -> None")},
+	{"QTGetPixMapHandleRequestedGammaLevel", (PyCFunction)Qt_QTGetPixMapHandleRequestedGammaLevel, 1,
+	 PyDoc_STR("(PixMapHandle pm) -> (Fixed _rv)")},
+	{"QTSetPixMapHandleRequestedGammaLevel", (PyCFunction)Qt_QTSetPixMapHandleRequestedGammaLevel, 1,
+	 PyDoc_STR("(PixMapHandle pm, Fixed requestedGammaLevel) -> None")},
+	{"CompAdd", (PyCFunction)Qt_CompAdd, 1,
+	 PyDoc_STR("() -> (wide src, wide dst)")},
+	{"CompSub", (PyCFunction)Qt_CompSub, 1,
+	 PyDoc_STR("() -> (wide src, wide dst)")},
+	{"CompNeg", (PyCFunction)Qt_CompNeg, 1,
+	 PyDoc_STR("() -> (wide dst)")},
+	{"CompShift", (PyCFunction)Qt_CompShift, 1,
+	 PyDoc_STR("(short shift) -> (wide src)")},
+	{"CompMul", (PyCFunction)Qt_CompMul, 1,
+	 PyDoc_STR("(long src1, long src2) -> (wide dst)")},
+	{"CompDiv", (PyCFunction)Qt_CompDiv, 1,
+	 PyDoc_STR("(long denominator) -> (long _rv, wide numerator, long remainder)")},
+	{"CompFixMul", (PyCFunction)Qt_CompFixMul, 1,
+	 PyDoc_STR("(Fixed fixSrc) -> (wide compSrc, wide compDst)")},
+	{"CompMulDiv", (PyCFunction)Qt_CompMulDiv, 1,
+	 PyDoc_STR("(long mul, long divisor) -> (wide co)")},
+	{"CompMulDivTrunc", (PyCFunction)Qt_CompMulDivTrunc, 1,
+	 PyDoc_STR("(long mul, long divisor) -> (wide co, long remainder)")},
+	{"CompCompare", (PyCFunction)Qt_CompCompare, 1,
+	 PyDoc_STR("(wide a, wide minusb) -> (long _rv)")},
+	{"CompSquareRoot", (PyCFunction)Qt_CompSquareRoot, 1,
+	 PyDoc_STR("(wide src) -> (unsigned long _rv)")},
+	{"FixMulDiv", (PyCFunction)Qt_FixMulDiv, 1,
+	 PyDoc_STR("(Fixed src, Fixed mul, Fixed divisor) -> (Fixed _rv)")},
+	{"UnsignedFixMulDiv", (PyCFunction)Qt_UnsignedFixMulDiv, 1,
+	 PyDoc_STR("(Fixed src, Fixed mul, Fixed divisor) -> (Fixed _rv)")},
+	{"FixExp2", (PyCFunction)Qt_FixExp2, 1,
+	 PyDoc_STR("(Fixed src) -> (Fixed _rv)")},
+	{"FixLog2", (PyCFunction)Qt_FixLog2, 1,
+	 PyDoc_STR("(Fixed src) -> (Fixed _rv)")},
+	{"FixPow", (PyCFunction)Qt_FixPow, 1,
+	 PyDoc_STR("(Fixed base, Fixed exp) -> (Fixed _rv)")},
+	{"GraphicsImportSetDataReference", (PyCFunction)Qt_GraphicsImportSetDataReference, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci, Handle dataRef, OSType dataReType) -> (ComponentResult _rv)")},
+	{"GraphicsImportGetDataReference", (PyCFunction)Qt_GraphicsImportGetDataReference, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci) -> (ComponentResult _rv, Handle dataRef, OSType dataReType)")},
+	{"GraphicsImportSetDataFile", (PyCFunction)Qt_GraphicsImportSetDataFile, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci, FSSpec theFile) -> (ComponentResult _rv)")},
+	{"GraphicsImportGetDataFile", (PyCFunction)Qt_GraphicsImportGetDataFile, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci, FSSpec theFile) -> (ComponentResult _rv)")},
+	{"GraphicsImportSetDataHandle", (PyCFunction)Qt_GraphicsImportSetDataHandle, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci, Handle h) -> (ComponentResult _rv)")},
+	{"GraphicsImportGetDataHandle", (PyCFunction)Qt_GraphicsImportGetDataHandle, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci) -> (ComponentResult _rv, Handle h)")},
+	{"GraphicsImportGetImageDescription", (PyCFunction)Qt_GraphicsImportGetImageDescription, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci) -> (ComponentResult _rv, ImageDescriptionHandle desc)")},
+	{"GraphicsImportGetDataOffsetAndSize", (PyCFunction)Qt_GraphicsImportGetDataOffsetAndSize, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci) -> (ComponentResult _rv, unsigned long offset, unsigned long size)")},
+	{"GraphicsImportReadData", (PyCFunction)Qt_GraphicsImportReadData, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci, void * dataPtr, unsigned long dataOffset, unsigned long dataSize) -> (ComponentResult _rv)")},
+	{"GraphicsImportSetClip", (PyCFunction)Qt_GraphicsImportSetClip, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci, RgnHandle clipRgn) -> (ComponentResult _rv)")},
+	{"GraphicsImportGetClip", (PyCFunction)Qt_GraphicsImportGetClip, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci) -> (ComponentResult _rv, RgnHandle clipRgn)")},
+	{"GraphicsImportSetSourceRect", (PyCFunction)Qt_GraphicsImportSetSourceRect, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci, Rect sourceRect) -> (ComponentResult _rv)")},
+	{"GraphicsImportGetSourceRect", (PyCFunction)Qt_GraphicsImportGetSourceRect, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci) -> (ComponentResult _rv, Rect sourceRect)")},
+	{"GraphicsImportGetNaturalBounds", (PyCFunction)Qt_GraphicsImportGetNaturalBounds, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci) -> (ComponentResult _rv, Rect naturalBounds)")},
+	{"GraphicsImportDraw", (PyCFunction)Qt_GraphicsImportDraw, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci) -> (ComponentResult _rv)")},
+	{"GraphicsImportSetGWorld", (PyCFunction)Qt_GraphicsImportSetGWorld, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci, CGrafPtr port, GDHandle gd) -> (ComponentResult _rv)")},
+	{"GraphicsImportGetGWorld", (PyCFunction)Qt_GraphicsImportGetGWorld, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci) -> (ComponentResult _rv, CGrafPtr port, GDHandle gd)")},
+	{"GraphicsImportSetBoundsRect", (PyCFunction)Qt_GraphicsImportSetBoundsRect, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci, Rect bounds) -> (ComponentResult _rv)")},
+	{"GraphicsImportGetBoundsRect", (PyCFunction)Qt_GraphicsImportGetBoundsRect, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci) -> (ComponentResult _rv, Rect bounds)")},
+	{"GraphicsImportSaveAsPicture", (PyCFunction)Qt_GraphicsImportSaveAsPicture, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci, FSSpec fss, ScriptCode scriptTag) -> (ComponentResult _rv)")},
+	{"GraphicsImportSetGraphicsMode", (PyCFunction)Qt_GraphicsImportSetGraphicsMode, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci, long graphicsMode, RGBColor opColor) -> (ComponentResult _rv)")},
+	{"GraphicsImportGetGraphicsMode", (PyCFunction)Qt_GraphicsImportGetGraphicsMode, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci) -> (ComponentResult _rv, long graphicsMode, RGBColor opColor)")},
+	{"GraphicsImportSetQuality", (PyCFunction)Qt_GraphicsImportSetQuality, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci, CodecQ quality) -> (ComponentResult _rv)")},
+	{"GraphicsImportGetQuality", (PyCFunction)Qt_GraphicsImportGetQuality, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci) -> (ComponentResult _rv, CodecQ quality)")},
+	{"GraphicsImportSaveAsQuickTimeImageFile", (PyCFunction)Qt_GraphicsImportSaveAsQuickTimeImageFile, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci, FSSpec fss, ScriptCode scriptTag) -> (ComponentResult _rv)")},
+	{"GraphicsImportSetDataReferenceOffsetAndLimit", (PyCFunction)Qt_GraphicsImportSetDataReferenceOffsetAndLimit, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci, unsigned long offset, unsigned long limit) -> (ComponentResult _rv)")},
+	{"GraphicsImportGetDataReferenceOffsetAndLimit", (PyCFunction)Qt_GraphicsImportGetDataReferenceOffsetAndLimit, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci) -> (ComponentResult _rv, unsigned long offset, unsigned long limit)")},
+	{"GraphicsImportGetAliasedDataReference", (PyCFunction)Qt_GraphicsImportGetAliasedDataReference, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci) -> (ComponentResult _rv, Handle dataRef, OSType dataRefType)")},
+	{"GraphicsImportValidate", (PyCFunction)Qt_GraphicsImportValidate, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci) -> (ComponentResult _rv, Boolean valid)")},
+	{"GraphicsImportGetMetaData", (PyCFunction)Qt_GraphicsImportGetMetaData, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci, void * userData) -> (ComponentResult _rv)")},
+	{"GraphicsImportGetMIMETypeList", (PyCFunction)Qt_GraphicsImportGetMIMETypeList, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci, void * qtAtomContainerPtr) -> (ComponentResult _rv)")},
+	{"GraphicsImportDoesDrawAllPixels", (PyCFunction)Qt_GraphicsImportDoesDrawAllPixels, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci) -> (ComponentResult _rv, short drawsAllPixels)")},
+	{"GraphicsImportGetAsPicture", (PyCFunction)Qt_GraphicsImportGetAsPicture, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci) -> (ComponentResult _rv, PicHandle picture)")},
+	{"GraphicsImportExportImageFile", (PyCFunction)Qt_GraphicsImportExportImageFile, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci, OSType fileType, OSType fileCreator, FSSpec fss, ScriptCode scriptTag) -> (ComponentResult _rv)")},
+	{"GraphicsImportGetExportImageTypeList", (PyCFunction)Qt_GraphicsImportGetExportImageTypeList, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci, void * qtAtomContainerPtr) -> (ComponentResult _rv)")},
+	{"GraphicsImportGetExportSettingsAsAtomContainer", (PyCFunction)Qt_GraphicsImportGetExportSettingsAsAtomContainer, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci, void * qtAtomContainerPtr) -> (ComponentResult _rv)")},
+	{"GraphicsImportSetExportSettingsFromAtomContainer", (PyCFunction)Qt_GraphicsImportSetExportSettingsFromAtomContainer, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci, void * qtAtomContainer) -> (ComponentResult _rv)")},
+	{"GraphicsImportGetImageCount", (PyCFunction)Qt_GraphicsImportGetImageCount, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci) -> (ComponentResult _rv, unsigned long imageCount)")},
+	{"GraphicsImportSetImageIndex", (PyCFunction)Qt_GraphicsImportSetImageIndex, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci, unsigned long imageIndex) -> (ComponentResult _rv)")},
+	{"GraphicsImportGetImageIndex", (PyCFunction)Qt_GraphicsImportGetImageIndex, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci) -> (ComponentResult _rv, unsigned long imageIndex)")},
+	{"GraphicsImportGetDataOffsetAndSize64", (PyCFunction)Qt_GraphicsImportGetDataOffsetAndSize64, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci) -> (ComponentResult _rv, wide offset, wide size)")},
+	{"GraphicsImportReadData64", (PyCFunction)Qt_GraphicsImportReadData64, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci, void * dataPtr, wide dataOffset, unsigned long dataSize) -> (ComponentResult _rv)")},
+	{"GraphicsImportSetDataReferenceOffsetAndLimit64", (PyCFunction)Qt_GraphicsImportSetDataReferenceOffsetAndLimit64, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci, wide offset, wide limit) -> (ComponentResult _rv)")},
+	{"GraphicsImportGetDataReferenceOffsetAndLimit64", (PyCFunction)Qt_GraphicsImportGetDataReferenceOffsetAndLimit64, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci) -> (ComponentResult _rv, wide offset, wide limit)")},
+	{"GraphicsImportGetDefaultClip", (PyCFunction)Qt_GraphicsImportGetDefaultClip, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci) -> (ComponentResult _rv, RgnHandle defaultRgn)")},
+	{"GraphicsImportGetDefaultGraphicsMode", (PyCFunction)Qt_GraphicsImportGetDefaultGraphicsMode, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci) -> (ComponentResult _rv, long defaultGraphicsMode, RGBColor defaultOpColor)")},
+	{"GraphicsImportGetDefaultSourceRect", (PyCFunction)Qt_GraphicsImportGetDefaultSourceRect, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci) -> (ComponentResult _rv, Rect defaultSourceRect)")},
+	{"GraphicsImportGetColorSyncProfile", (PyCFunction)Qt_GraphicsImportGetColorSyncProfile, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci) -> (ComponentResult _rv, Handle profile)")},
+	{"GraphicsImportSetDestRect", (PyCFunction)Qt_GraphicsImportSetDestRect, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci, Rect destRect) -> (ComponentResult _rv)")},
+	{"GraphicsImportGetDestRect", (PyCFunction)Qt_GraphicsImportGetDestRect, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci) -> (ComponentResult _rv, Rect destRect)")},
+	{"GraphicsImportSetFlags", (PyCFunction)Qt_GraphicsImportSetFlags, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci, long flags) -> (ComponentResult _rv)")},
+	{"GraphicsImportGetFlags", (PyCFunction)Qt_GraphicsImportGetFlags, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci) -> (ComponentResult _rv, long flags)")},
+	{"GraphicsImportGetBaseDataOffsetAndSize64", (PyCFunction)Qt_GraphicsImportGetBaseDataOffsetAndSize64, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci) -> (ComponentResult _rv, wide offset, wide size)")},
+	{"GraphicsImportSetImageIndexToThumbnail", (PyCFunction)Qt_GraphicsImportSetImageIndexToThumbnail, 1,
+	 PyDoc_STR("(GraphicsImportComponent ci) -> (ComponentResult _rv)")},
+	{"GraphicsExportDoExport", (PyCFunction)Qt_GraphicsExportDoExport, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci) -> (ComponentResult _rv, unsigned long actualSizeWritten)")},
+	{"GraphicsExportCanTranscode", (PyCFunction)Qt_GraphicsExportCanTranscode, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci) -> (ComponentResult _rv, Boolean canTranscode)")},
+	{"GraphicsExportDoTranscode", (PyCFunction)Qt_GraphicsExportDoTranscode, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci) -> (ComponentResult _rv)")},
+	{"GraphicsExportCanUseCompressor", (PyCFunction)Qt_GraphicsExportCanUseCompressor, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci, void * codecSettingsAtomContainerPtr) -> (ComponentResult _rv, Boolean canUseCompressor)")},
+	{"GraphicsExportDoUseCompressor", (PyCFunction)Qt_GraphicsExportDoUseCompressor, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci, void * codecSettingsAtomContainer) -> (ComponentResult _rv, ImageDescriptionHandle outDesc)")},
+	{"GraphicsExportDoStandaloneExport", (PyCFunction)Qt_GraphicsExportDoStandaloneExport, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci) -> (ComponentResult _rv)")},
+	{"GraphicsExportGetDefaultFileTypeAndCreator", (PyCFunction)Qt_GraphicsExportGetDefaultFileTypeAndCreator, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci) -> (ComponentResult _rv, OSType fileType, OSType fileCreator)")},
+	{"GraphicsExportGetDefaultFileNameExtension", (PyCFunction)Qt_GraphicsExportGetDefaultFileNameExtension, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci) -> (ComponentResult _rv, OSType fileNameExtension)")},
+	{"GraphicsExportGetMIMETypeList", (PyCFunction)Qt_GraphicsExportGetMIMETypeList, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci, void * qtAtomContainerPtr) -> (ComponentResult _rv)")},
+	{"GraphicsExportSetSettingsFromAtomContainer", (PyCFunction)Qt_GraphicsExportSetSettingsFromAtomContainer, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci, void * qtAtomContainer) -> (ComponentResult _rv)")},
+	{"GraphicsExportGetSettingsAsAtomContainer", (PyCFunction)Qt_GraphicsExportGetSettingsAsAtomContainer, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci, void * qtAtomContainerPtr) -> (ComponentResult _rv)")},
+	{"GraphicsExportGetSettingsAsText", (PyCFunction)Qt_GraphicsExportGetSettingsAsText, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci) -> (ComponentResult _rv, Handle theText)")},
+	{"GraphicsExportSetDontRecompress", (PyCFunction)Qt_GraphicsExportSetDontRecompress, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci, Boolean dontRecompress) -> (ComponentResult _rv)")},
+	{"GraphicsExportGetDontRecompress", (PyCFunction)Qt_GraphicsExportGetDontRecompress, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci) -> (ComponentResult _rv, Boolean dontRecompress)")},
+	{"GraphicsExportSetInterlaceStyle", (PyCFunction)Qt_GraphicsExportSetInterlaceStyle, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci, unsigned long interlaceStyle) -> (ComponentResult _rv)")},
+	{"GraphicsExportGetInterlaceStyle", (PyCFunction)Qt_GraphicsExportGetInterlaceStyle, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci) -> (ComponentResult _rv, unsigned long interlaceStyle)")},
+	{"GraphicsExportSetMetaData", (PyCFunction)Qt_GraphicsExportSetMetaData, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci, void * userData) -> (ComponentResult _rv)")},
+	{"GraphicsExportGetMetaData", (PyCFunction)Qt_GraphicsExportGetMetaData, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci, void * userData) -> (ComponentResult _rv)")},
+	{"GraphicsExportSetTargetDataSize", (PyCFunction)Qt_GraphicsExportSetTargetDataSize, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci, unsigned long targetDataSize) -> (ComponentResult _rv)")},
+	{"GraphicsExportGetTargetDataSize", (PyCFunction)Qt_GraphicsExportGetTargetDataSize, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci) -> (ComponentResult _rv, unsigned long targetDataSize)")},
+	{"GraphicsExportSetCompressionMethod", (PyCFunction)Qt_GraphicsExportSetCompressionMethod, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci, long compressionMethod) -> (ComponentResult _rv)")},
+	{"GraphicsExportGetCompressionMethod", (PyCFunction)Qt_GraphicsExportGetCompressionMethod, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci) -> (ComponentResult _rv, long compressionMethod)")},
+	{"GraphicsExportSetCompressionQuality", (PyCFunction)Qt_GraphicsExportSetCompressionQuality, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci, CodecQ spatialQuality) -> (ComponentResult _rv)")},
+	{"GraphicsExportGetCompressionQuality", (PyCFunction)Qt_GraphicsExportGetCompressionQuality, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci) -> (ComponentResult _rv, CodecQ spatialQuality)")},
+	{"GraphicsExportSetResolution", (PyCFunction)Qt_GraphicsExportSetResolution, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci, Fixed horizontalResolution, Fixed verticalResolution) -> (ComponentResult _rv)")},
+	{"GraphicsExportGetResolution", (PyCFunction)Qt_GraphicsExportGetResolution, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci) -> (ComponentResult _rv, Fixed horizontalResolution, Fixed verticalResolution)")},
+	{"GraphicsExportSetDepth", (PyCFunction)Qt_GraphicsExportSetDepth, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci, long depth) -> (ComponentResult _rv)")},
+	{"GraphicsExportGetDepth", (PyCFunction)Qt_GraphicsExportGetDepth, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci) -> (ComponentResult _rv, long depth)")},
+	{"GraphicsExportSetColorSyncProfile", (PyCFunction)Qt_GraphicsExportSetColorSyncProfile, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci, Handle colorSyncProfile) -> (ComponentResult _rv)")},
+	{"GraphicsExportGetColorSyncProfile", (PyCFunction)Qt_GraphicsExportGetColorSyncProfile, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci) -> (ComponentResult _rv, Handle colorSyncProfile)")},
+	{"GraphicsExportSetInputDataReference", (PyCFunction)Qt_GraphicsExportSetInputDataReference, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci, Handle dataRef, OSType dataRefType, ImageDescriptionHandle desc) -> (ComponentResult _rv)")},
+	{"GraphicsExportGetInputDataReference", (PyCFunction)Qt_GraphicsExportGetInputDataReference, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci) -> (ComponentResult _rv, Handle dataRef, OSType dataRefType)")},
+	{"GraphicsExportSetInputFile", (PyCFunction)Qt_GraphicsExportSetInputFile, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci, FSSpec theFile, ImageDescriptionHandle desc) -> (ComponentResult _rv)")},
+	{"GraphicsExportGetInputFile", (PyCFunction)Qt_GraphicsExportGetInputFile, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci, FSSpec theFile) -> (ComponentResult _rv)")},
+	{"GraphicsExportSetInputHandle", (PyCFunction)Qt_GraphicsExportSetInputHandle, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci, Handle h, ImageDescriptionHandle desc) -> (ComponentResult _rv)")},
+	{"GraphicsExportGetInputHandle", (PyCFunction)Qt_GraphicsExportGetInputHandle, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci) -> (ComponentResult _rv, Handle h)")},
+	{"GraphicsExportSetInputPtr", (PyCFunction)Qt_GraphicsExportSetInputPtr, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci, Ptr p, unsigned long size, ImageDescriptionHandle desc) -> (ComponentResult _rv)")},
+	{"GraphicsExportSetInputGraphicsImporter", (PyCFunction)Qt_GraphicsExportSetInputGraphicsImporter, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci, GraphicsImportComponent grip) -> (ComponentResult _rv)")},
+	{"GraphicsExportGetInputGraphicsImporter", (PyCFunction)Qt_GraphicsExportGetInputGraphicsImporter, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci) -> (ComponentResult _rv, GraphicsImportComponent grip)")},
+	{"GraphicsExportSetInputPicture", (PyCFunction)Qt_GraphicsExportSetInputPicture, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci, PicHandle picture) -> (ComponentResult _rv)")},
+	{"GraphicsExportGetInputPicture", (PyCFunction)Qt_GraphicsExportGetInputPicture, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci) -> (ComponentResult _rv, PicHandle picture)")},
+	{"GraphicsExportSetInputGWorld", (PyCFunction)Qt_GraphicsExportSetInputGWorld, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci, GWorldPtr gworld) -> (ComponentResult _rv)")},
+	{"GraphicsExportGetInputGWorld", (PyCFunction)Qt_GraphicsExportGetInputGWorld, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci) -> (ComponentResult _rv, GWorldPtr gworld)")},
+	{"GraphicsExportSetInputPixmap", (PyCFunction)Qt_GraphicsExportSetInputPixmap, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci, PixMapHandle pixmap) -> (ComponentResult _rv)")},
+	{"GraphicsExportGetInputPixmap", (PyCFunction)Qt_GraphicsExportGetInputPixmap, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci) -> (ComponentResult _rv, PixMapHandle pixmap)")},
+	{"GraphicsExportSetInputOffsetAndLimit", (PyCFunction)Qt_GraphicsExportSetInputOffsetAndLimit, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci, unsigned long offset, unsigned long limit) -> (ComponentResult _rv)")},
+	{"GraphicsExportGetInputOffsetAndLimit", (PyCFunction)Qt_GraphicsExportGetInputOffsetAndLimit, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci) -> (ComponentResult _rv, unsigned long offset, unsigned long limit)")},
+	{"GraphicsExportMayExporterReadInputData", (PyCFunction)Qt_GraphicsExportMayExporterReadInputData, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci) -> (ComponentResult _rv, Boolean mayReadInputData)")},
+	{"GraphicsExportGetInputDataSize", (PyCFunction)Qt_GraphicsExportGetInputDataSize, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci) -> (ComponentResult _rv, unsigned long size)")},
+	{"GraphicsExportReadInputData", (PyCFunction)Qt_GraphicsExportReadInputData, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci, void * dataPtr, unsigned long dataOffset, unsigned long dataSize) -> (ComponentResult _rv)")},
+	{"GraphicsExportGetInputImageDescription", (PyCFunction)Qt_GraphicsExportGetInputImageDescription, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci) -> (ComponentResult _rv, ImageDescriptionHandle desc)")},
+	{"GraphicsExportGetInputImageDimensions", (PyCFunction)Qt_GraphicsExportGetInputImageDimensions, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci) -> (ComponentResult _rv, Rect dimensions)")},
+	{"GraphicsExportGetInputImageDepth", (PyCFunction)Qt_GraphicsExportGetInputImageDepth, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci) -> (ComponentResult _rv, long inputDepth)")},
+	{"GraphicsExportDrawInputImage", (PyCFunction)Qt_GraphicsExportDrawInputImage, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci, CGrafPtr gw, GDHandle gd, Rect srcRect, Rect dstRect) -> (ComponentResult _rv)")},
+	{"GraphicsExportSetOutputDataReference", (PyCFunction)Qt_GraphicsExportSetOutputDataReference, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci, Handle dataRef, OSType dataRefType) -> (ComponentResult _rv)")},
+	{"GraphicsExportGetOutputDataReference", (PyCFunction)Qt_GraphicsExportGetOutputDataReference, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci) -> (ComponentResult _rv, Handle dataRef, OSType dataRefType)")},
+	{"GraphicsExportSetOutputFile", (PyCFunction)Qt_GraphicsExportSetOutputFile, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci, FSSpec theFile) -> (ComponentResult _rv)")},
+	{"GraphicsExportGetOutputFile", (PyCFunction)Qt_GraphicsExportGetOutputFile, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci, FSSpec theFile) -> (ComponentResult _rv)")},
+	{"GraphicsExportSetOutputHandle", (PyCFunction)Qt_GraphicsExportSetOutputHandle, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci, Handle h) -> (ComponentResult _rv)")},
+	{"GraphicsExportGetOutputHandle", (PyCFunction)Qt_GraphicsExportGetOutputHandle, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci) -> (ComponentResult _rv, Handle h)")},
+	{"GraphicsExportSetOutputOffsetAndMaxSize", (PyCFunction)Qt_GraphicsExportSetOutputOffsetAndMaxSize, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci, unsigned long offset, unsigned long maxSize, Boolean truncateFile) -> (ComponentResult _rv)")},
+	{"GraphicsExportGetOutputOffsetAndMaxSize", (PyCFunction)Qt_GraphicsExportGetOutputOffsetAndMaxSize, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci) -> (ComponentResult _rv, unsigned long offset, unsigned long maxSize, Boolean truncateFile)")},
+	{"GraphicsExportSetOutputFileTypeAndCreator", (PyCFunction)Qt_GraphicsExportSetOutputFileTypeAndCreator, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci, OSType fileType, OSType fileCreator) -> (ComponentResult _rv)")},
+	{"GraphicsExportGetOutputFileTypeAndCreator", (PyCFunction)Qt_GraphicsExportGetOutputFileTypeAndCreator, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci) -> (ComponentResult _rv, OSType fileType, OSType fileCreator)")},
+	{"GraphicsExportSetOutputMark", (PyCFunction)Qt_GraphicsExportSetOutputMark, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci, unsigned long mark) -> (ComponentResult _rv)")},
+	{"GraphicsExportGetOutputMark", (PyCFunction)Qt_GraphicsExportGetOutputMark, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci) -> (ComponentResult _rv, unsigned long mark)")},
+	{"GraphicsExportReadOutputData", (PyCFunction)Qt_GraphicsExportReadOutputData, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci, void * dataPtr, unsigned long dataOffset, unsigned long dataSize) -> (ComponentResult _rv)")},
+	{"GraphicsExportSetThumbnailEnabled", (PyCFunction)Qt_GraphicsExportSetThumbnailEnabled, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci, Boolean enableThumbnail, long maxThumbnailWidth, long maxThumbnailHeight) -> (ComponentResult _rv)")},
+	{"GraphicsExportGetThumbnailEnabled", (PyCFunction)Qt_GraphicsExportGetThumbnailEnabled, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci) -> (ComponentResult _rv, Boolean thumbnailEnabled, long maxThumbnailWidth, long maxThumbnailHeight)")},
+	{"GraphicsExportSetExifEnabled", (PyCFunction)Qt_GraphicsExportSetExifEnabled, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci, Boolean enableExif) -> (ComponentResult _rv)")},
+	{"GraphicsExportGetExifEnabled", (PyCFunction)Qt_GraphicsExportGetExifEnabled, 1,
+	 PyDoc_STR("(GraphicsExportComponent ci) -> (ComponentResult _rv, Boolean exifEnabled)")},
+	{"ImageTranscoderBeginSequence", (PyCFunction)Qt_ImageTranscoderBeginSequence, 1,
+	 PyDoc_STR("(ImageTranscoderComponent itc, ImageDescriptionHandle srcDesc, void * data, long dataSize) -> (ComponentResult _rv, ImageDescriptionHandle dstDesc)")},
+	{"ImageTranscoderDisposeData", (PyCFunction)Qt_ImageTranscoderDisposeData, 1,
+	 PyDoc_STR("(ImageTranscoderComponent itc, void * dstData) -> (ComponentResult _rv)")},
+	{"ImageTranscoderEndSequence", (PyCFunction)Qt_ImageTranscoderEndSequence, 1,
+	 PyDoc_STR("(ImageTranscoderComponent itc) -> (ComponentResult _rv)")},
+	{"ClockGetTime", (PyCFunction)Qt_ClockGetTime, 1,
+	 PyDoc_STR("(ComponentInstance aClock) -> (ComponentResult _rv, TimeRecord out)")},
+	{"ClockSetTimeBase", (PyCFunction)Qt_ClockSetTimeBase, 1,
+	 PyDoc_STR("(ComponentInstance aClock, TimeBase tb) -> (ComponentResult _rv)")},
+	{"ClockGetRate", (PyCFunction)Qt_ClockGetRate, 1,
+	 PyDoc_STR("(ComponentInstance aClock) -> (ComponentResult _rv, Fixed rate)")},
+	{"SCPositionRect", (PyCFunction)Qt_SCPositionRect, 1,
+	 PyDoc_STR("(ComponentInstance ci) -> (ComponentResult _rv, Rect rp, Point where)")},
+	{"SCPositionDialog", (PyCFunction)Qt_SCPositionDialog, 1,
+	 PyDoc_STR("(ComponentInstance ci, short id) -> (ComponentResult _rv, Point where)")},
+	{"SCSetTestImagePictHandle", (PyCFunction)Qt_SCSetTestImagePictHandle, 1,
+	 PyDoc_STR("(ComponentInstance ci, PicHandle testPict, short testFlags) -> (ComponentResult _rv, Rect testRect)")},
+	{"SCSetTestImagePictFile", (PyCFunction)Qt_SCSetTestImagePictFile, 1,
+	 PyDoc_STR("(ComponentInstance ci, short testFileRef, short testFlags) -> (ComponentResult _rv, Rect testRect)")},
+	{"SCSetTestImagePixMap", (PyCFunction)Qt_SCSetTestImagePixMap, 1,
+	 PyDoc_STR("(ComponentInstance ci, PixMapHandle testPixMap, short testFlags) -> (ComponentResult _rv, Rect testRect)")},
+	{"SCGetBestDeviceRect", (PyCFunction)Qt_SCGetBestDeviceRect, 1,
+	 PyDoc_STR("(ComponentInstance ci) -> (ComponentResult _rv, Rect r)")},
+	{"SCRequestImageSettings", (PyCFunction)Qt_SCRequestImageSettings, 1,
+	 PyDoc_STR("(ComponentInstance ci) -> (ComponentResult _rv)")},
+	{"SCCompressImage", (PyCFunction)Qt_SCCompressImage, 1,
+	 PyDoc_STR("(ComponentInstance ci, PixMapHandle src, Rect srcRect) -> (ComponentResult _rv, ImageDescriptionHandle desc, Handle data)")},
+	{"SCCompressPicture", (PyCFunction)Qt_SCCompressPicture, 1,
+	 PyDoc_STR("(ComponentInstance ci, PicHandle srcPicture, PicHandle dstPicture) -> (ComponentResult _rv)")},
+	{"SCCompressPictureFile", (PyCFunction)Qt_SCCompressPictureFile, 1,
+	 PyDoc_STR("(ComponentInstance ci, short srcRefNum, short dstRefNum) -> (ComponentResult _rv)")},
+	{"SCRequestSequenceSettings", (PyCFunction)Qt_SCRequestSequenceSettings, 1,
+	 PyDoc_STR("(ComponentInstance ci) -> (ComponentResult _rv)")},
+	{"SCCompressSequenceBegin", (PyCFunction)Qt_SCCompressSequenceBegin, 1,
+	 PyDoc_STR("(ComponentInstance ci, PixMapHandle src, Rect srcRect) -> (ComponentResult _rv, ImageDescriptionHandle desc)")},
+	{"SCCompressSequenceFrame", (PyCFunction)Qt_SCCompressSequenceFrame, 1,
+	 PyDoc_STR("(ComponentInstance ci, PixMapHandle src, Rect srcRect) -> (ComponentResult _rv, Handle data, long dataSize, short notSyncFlag)")},
+	{"SCCompressSequenceEnd", (PyCFunction)Qt_SCCompressSequenceEnd, 1,
+	 PyDoc_STR("(ComponentInstance ci) -> (ComponentResult _rv)")},
+	{"SCDefaultPictHandleSettings", (PyCFunction)Qt_SCDefaultPictHandleSettings, 1,
+	 PyDoc_STR("(ComponentInstance ci, PicHandle srcPicture, short motion) -> (ComponentResult _rv)")},
+	{"SCDefaultPictFileSettings", (PyCFunction)Qt_SCDefaultPictFileSettings, 1,
+	 PyDoc_STR("(ComponentInstance ci, short srcRef, short motion) -> (ComponentResult _rv)")},
+	{"SCDefaultPixMapSettings", (PyCFunction)Qt_SCDefaultPixMapSettings, 1,
+	 PyDoc_STR("(ComponentInstance ci, PixMapHandle src, short motion) -> (ComponentResult _rv)")},
+	{"SCGetInfo", (PyCFunction)Qt_SCGetInfo, 1,
+	 PyDoc_STR("(ComponentInstance ci, OSType infoType, void * info) -> (ComponentResult _rv)")},
+	{"SCSetInfo", (PyCFunction)Qt_SCSetInfo, 1,
+	 PyDoc_STR("(ComponentInstance ci, OSType infoType, void * info) -> (ComponentResult _rv)")},
+	{"SCSetCompressFlags", (PyCFunction)Qt_SCSetCompressFlags, 1,
+	 PyDoc_STR("(ComponentInstance ci, long flags) -> (ComponentResult _rv)")},
+	{"SCGetCompressFlags", (PyCFunction)Qt_SCGetCompressFlags, 1,
+	 PyDoc_STR("(ComponentInstance ci) -> (ComponentResult _rv, long flags)")},
+	{"SCGetSettingsAsText", (PyCFunction)Qt_SCGetSettingsAsText, 1,
+	 PyDoc_STR("(ComponentInstance ci) -> (ComponentResult _rv, Handle text)")},
+	{"SCAsyncIdle", (PyCFunction)Qt_SCAsyncIdle, 1,
+	 PyDoc_STR("(ComponentInstance ci) -> (ComponentResult _rv)")},
+	{"TweenerReset", (PyCFunction)Qt_TweenerReset, 1,
+	 PyDoc_STR("(TweenerComponent tc) -> (ComponentResult _rv)")},
+	{"TCGetSourceRef", (PyCFunction)Qt_TCGetSourceRef, 1,
+	 PyDoc_STR("(MediaHandler mh, TimeCodeDescriptionHandle tcdH) -> (HandlerError _rv, UserData srefH)")},
+	{"TCSetSourceRef", (PyCFunction)Qt_TCSetSourceRef, 1,
+	 PyDoc_STR("(MediaHandler mh, TimeCodeDescriptionHandle tcdH, UserData srefH) -> (HandlerError _rv)")},
+	{"TCSetTimeCodeFlags", (PyCFunction)Qt_TCSetTimeCodeFlags, 1,
+	 PyDoc_STR("(MediaHandler mh, long flags, long flagsMask) -> (HandlerError _rv)")},
+	{"TCGetTimeCodeFlags", (PyCFunction)Qt_TCGetTimeCodeFlags, 1,
+	 PyDoc_STR("(MediaHandler mh) -> (HandlerError _rv, long flags)")},
+	{"MovieImportHandle", (PyCFunction)Qt_MovieImportHandle, 1,
+	 PyDoc_STR("(MovieImportComponent ci, Handle dataH, Movie theMovie, Track targetTrack, TimeValue atTime, long inFlags) -> (ComponentResult _rv, Track usedTrack, TimeValue addedDuration, long outFlags)")},
+	{"MovieImportFile", (PyCFunction)Qt_MovieImportFile, 1,
+	 PyDoc_STR("(MovieImportComponent ci, FSSpec theFile, Movie theMovie, Track targetTrack, TimeValue atTime, long inFlags) -> (ComponentResult _rv, Track usedTrack, TimeValue addedDuration, long outFlags)")},
+	{"MovieImportSetSampleDuration", (PyCFunction)Qt_MovieImportSetSampleDuration, 1,
+	 PyDoc_STR("(MovieImportComponent ci, TimeValue duration, TimeScale scale) -> (ComponentResult _rv)")},
+	{"MovieImportSetSampleDescription", (PyCFunction)Qt_MovieImportSetSampleDescription, 1,
+	 PyDoc_STR("(MovieImportComponent ci, SampleDescriptionHandle desc, OSType mediaType) -> (ComponentResult _rv)")},
+	{"MovieImportSetMediaFile", (PyCFunction)Qt_MovieImportSetMediaFile, 1,
+	 PyDoc_STR("(MovieImportComponent ci, AliasHandle alias) -> (ComponentResult _rv)")},
+	{"MovieImportSetDimensions", (PyCFunction)Qt_MovieImportSetDimensions, 1,
+	 PyDoc_STR("(MovieImportComponent ci, Fixed width, Fixed height) -> (ComponentResult _rv)")},
+	{"MovieImportSetChunkSize", (PyCFunction)Qt_MovieImportSetChunkSize, 1,
+	 PyDoc_STR("(MovieImportComponent ci, long chunkSize) -> (ComponentResult _rv)")},
+	{"MovieImportSetAuxiliaryData", (PyCFunction)Qt_MovieImportSetAuxiliaryData, 1,
+	 PyDoc_STR("(MovieImportComponent ci, Handle data, OSType handleType) -> (ComponentResult _rv)")},
+	{"MovieImportSetFromScrap", (PyCFunction)Qt_MovieImportSetFromScrap, 1,
+	 PyDoc_STR("(MovieImportComponent ci, Boolean fromScrap) -> (ComponentResult _rv)")},
+	{"MovieImportDoUserDialog", (PyCFunction)Qt_MovieImportDoUserDialog, 1,
+	 PyDoc_STR("(MovieImportComponent ci, FSSpec theFile, Handle theData) -> (ComponentResult _rv, Boolean canceled)")},
+	{"MovieImportSetDuration", (PyCFunction)Qt_MovieImportSetDuration, 1,
+	 PyDoc_STR("(MovieImportComponent ci, TimeValue duration) -> (ComponentResult _rv)")},
+	{"MovieImportGetAuxiliaryDataType", (PyCFunction)Qt_MovieImportGetAuxiliaryDataType, 1,
+	 PyDoc_STR("(MovieImportComponent ci) -> (ComponentResult _rv, OSType auxType)")},
+	{"MovieImportValidate", (PyCFunction)Qt_MovieImportValidate, 1,
+	 PyDoc_STR("(MovieImportComponent ci, FSSpec theFile, Handle theData) -> (ComponentResult _rv, Boolean valid)")},
+	{"MovieImportGetFileType", (PyCFunction)Qt_MovieImportGetFileType, 1,
+	 PyDoc_STR("(MovieImportComponent ci) -> (ComponentResult _rv, OSType fileType)")},
+	{"MovieImportDataRef", (PyCFunction)Qt_MovieImportDataRef, 1,
+	 PyDoc_STR("(MovieImportComponent ci, Handle dataRef, OSType dataRefType, Movie theMovie, Track targetTrack, TimeValue atTime, long inFlags) -> (ComponentResult _rv, Track usedTrack, TimeValue addedDuration, long outFlags)")},
+	{"MovieImportGetSampleDescription", (PyCFunction)Qt_MovieImportGetSampleDescription, 1,
+	 PyDoc_STR("(MovieImportComponent ci) -> (ComponentResult _rv, SampleDescriptionHandle desc, OSType mediaType)")},
+	{"MovieImportSetOffsetAndLimit", (PyCFunction)Qt_MovieImportSetOffsetAndLimit, 1,
+	 PyDoc_STR("(MovieImportComponent ci, unsigned long offset, unsigned long limit) -> (ComponentResult _rv)")},
+	{"MovieImportSetOffsetAndLimit64", (PyCFunction)Qt_MovieImportSetOffsetAndLimit64, 1,
+	 PyDoc_STR("(MovieImportComponent ci, wide offset, wide limit) -> (ComponentResult _rv)")},
+	{"MovieImportIdle", (PyCFunction)Qt_MovieImportIdle, 1,
+	 PyDoc_STR("(MovieImportComponent ci, long inFlags) -> (ComponentResult _rv, long outFlags)")},
+	{"MovieImportValidateDataRef", (PyCFunction)Qt_MovieImportValidateDataRef, 1,
+	 PyDoc_STR("(MovieImportComponent ci, Handle dataRef, OSType dataRefType) -> (ComponentResult _rv, UInt8 valid)")},
+	{"MovieImportGetLoadState", (PyCFunction)Qt_MovieImportGetLoadState, 1,
+	 PyDoc_STR("(MovieImportComponent ci) -> (ComponentResult _rv, long importerLoadState)")},
+	{"MovieImportGetMaxLoadedTime", (PyCFunction)Qt_MovieImportGetMaxLoadedTime, 1,
+	 PyDoc_STR("(MovieImportComponent ci) -> (ComponentResult _rv, TimeValue time)")},
+	{"MovieImportEstimateCompletionTime", (PyCFunction)Qt_MovieImportEstimateCompletionTime, 1,
+	 PyDoc_STR("(MovieImportComponent ci) -> (ComponentResult _rv, TimeRecord time)")},
+	{"MovieImportSetDontBlock", (PyCFunction)Qt_MovieImportSetDontBlock, 1,
+	 PyDoc_STR("(MovieImportComponent ci, Boolean dontBlock) -> (ComponentResult _rv)")},
+	{"MovieImportGetDontBlock", (PyCFunction)Qt_MovieImportGetDontBlock, 1,
+	 PyDoc_STR("(MovieImportComponent ci) -> (ComponentResult _rv, Boolean willBlock)")},
+	{"MovieImportSetIdleManager", (PyCFunction)Qt_MovieImportSetIdleManager, 1,
+	 PyDoc_STR("(MovieImportComponent ci, IdleManager im) -> (ComponentResult _rv)")},
+	{"MovieImportSetNewMovieFlags", (PyCFunction)Qt_MovieImportSetNewMovieFlags, 1,
+	 PyDoc_STR("(MovieImportComponent ci, long newMovieFlags) -> (ComponentResult _rv)")},
+	{"MovieImportGetDestinationMediaType", (PyCFunction)Qt_MovieImportGetDestinationMediaType, 1,
+	 PyDoc_STR("(MovieImportComponent ci) -> (ComponentResult _rv, OSType mediaType)")},
+	{"MovieExportToHandle", (PyCFunction)Qt_MovieExportToHandle, 1,
+	 PyDoc_STR("(MovieExportComponent ci, Handle dataH, Movie theMovie, Track onlyThisTrack, TimeValue startTime, TimeValue duration) -> (ComponentResult _rv)")},
+	{"MovieExportToFile", (PyCFunction)Qt_MovieExportToFile, 1,
+	 PyDoc_STR("(MovieExportComponent ci, FSSpec theFile, Movie theMovie, Track onlyThisTrack, TimeValue startTime, TimeValue duration) -> (ComponentResult _rv)")},
+	{"MovieExportGetAuxiliaryData", (PyCFunction)Qt_MovieExportGetAuxiliaryData, 1,
+	 PyDoc_STR("(MovieExportComponent ci, Handle dataH) -> (ComponentResult _rv, OSType handleType)")},
+	{"MovieExportSetSampleDescription", (PyCFunction)Qt_MovieExportSetSampleDescription, 1,
+	 PyDoc_STR("(MovieExportComponent ci, SampleDescriptionHandle desc, OSType mediaType) -> (ComponentResult _rv)")},
+	{"MovieExportDoUserDialog", (PyCFunction)Qt_MovieExportDoUserDialog, 1,
+	 PyDoc_STR("(MovieExportComponent ci, Movie theMovie, Track onlyThisTrack, TimeValue startTime, TimeValue duration) -> (ComponentResult _rv, Boolean canceled)")},
+	{"MovieExportGetCreatorType", (PyCFunction)Qt_MovieExportGetCreatorType, 1,
+	 PyDoc_STR("(MovieExportComponent ci) -> (ComponentResult _rv, OSType creator)")},
+	{"MovieExportToDataRef", (PyCFunction)Qt_MovieExportToDataRef, 1,
+	 PyDoc_STR("(MovieExportComponent ci, Handle dataRef, OSType dataRefType, Movie theMovie, Track onlyThisTrack, TimeValue startTime, TimeValue duration) -> (ComponentResult _rv)")},
+	{"MovieExportFromProceduresToDataRef", (PyCFunction)Qt_MovieExportFromProceduresToDataRef, 1,
+	 PyDoc_STR("(MovieExportComponent ci, Handle dataRef, OSType dataRefType) -> (ComponentResult _rv)")},
+	{"MovieExportValidate", (PyCFunction)Qt_MovieExportValidate, 1,
+	 PyDoc_STR("(MovieExportComponent ci, Movie theMovie, Track onlyThisTrack) -> (ComponentResult _rv, Boolean valid)")},
+	{"MovieExportGetFileNameExtension", (PyCFunction)Qt_MovieExportGetFileNameExtension, 1,
+	 PyDoc_STR("(MovieExportComponent ci) -> (ComponentResult _rv, OSType extension)")},
+	{"MovieExportGetShortFileTypeString", (PyCFunction)Qt_MovieExportGetShortFileTypeString, 1,
+	 PyDoc_STR("(MovieExportComponent ci, Str255 typeString) -> (ComponentResult _rv)")},
+	{"MovieExportGetSourceMediaType", (PyCFunction)Qt_MovieExportGetSourceMediaType, 1,
+	 PyDoc_STR("(MovieExportComponent ci) -> (ComponentResult _rv, OSType mediaType)")},
+	{"TextExportGetTimeFraction", (PyCFunction)Qt_TextExportGetTimeFraction, 1,
+	 PyDoc_STR("(TextExportComponent ci) -> (ComponentResult _rv, long movieTimeFraction)")},
+	{"TextExportSetTimeFraction", (PyCFunction)Qt_TextExportSetTimeFraction, 1,
+	 PyDoc_STR("(TextExportComponent ci, long movieTimeFraction) -> (ComponentResult _rv)")},
+	{"TextExportGetSettings", (PyCFunction)Qt_TextExportGetSettings, 1,
+	 PyDoc_STR("(TextExportComponent ci) -> (ComponentResult _rv, long setting)")},
+	{"TextExportSetSettings", (PyCFunction)Qt_TextExportSetSettings, 1,
+	 PyDoc_STR("(TextExportComponent ci, long setting) -> (ComponentResult _rv)")},
+	{"MIDIImportGetSettings", (PyCFunction)Qt_MIDIImportGetSettings, 1,
+	 PyDoc_STR("(TextExportComponent ci) -> (ComponentResult _rv, long setting)")},
+	{"MIDIImportSetSettings", (PyCFunction)Qt_MIDIImportSetSettings, 1,
+	 PyDoc_STR("(TextExportComponent ci, long setting) -> (ComponentResult _rv)")},
+	{"GraphicsImageImportSetSequenceEnabled", (PyCFunction)Qt_GraphicsImageImportSetSequenceEnabled, 1,
+	 PyDoc_STR("(GraphicImageMovieImportComponent ci, Boolean enable) -> (ComponentResult _rv)")},
+	{"GraphicsImageImportGetSequenceEnabled", (PyCFunction)Qt_GraphicsImageImportGetSequenceEnabled, 1,
+	 PyDoc_STR("(GraphicImageMovieImportComponent ci) -> (ComponentResult _rv, Boolean enable)")},
+	{"PreviewShowData", (PyCFunction)Qt_PreviewShowData, 1,
+	 PyDoc_STR("(pnotComponent p, OSType dataType, Handle data, Rect inHere) -> (ComponentResult _rv)")},
+	{"PreviewMakePreviewReference", (PyCFunction)Qt_PreviewMakePreviewReference, 1,
+	 PyDoc_STR("(pnotComponent p, FSSpec sourceFile) -> (ComponentResult _rv, OSType previewType, short resID)")},
+	{"PreviewEvent", (PyCFunction)Qt_PreviewEvent, 1,
+	 PyDoc_STR("(pnotComponent p) -> (ComponentResult _rv, EventRecord e, Boolean handledEvent)")},
+	{"DataCodecDecompress", (PyCFunction)Qt_DataCodecDecompress, 1,
+	 PyDoc_STR("(DataCodecComponent dc, void * srcData, UInt32 srcSize, void * dstData, UInt32 dstBufferSize) -> (ComponentResult _rv)")},
+	{"DataCodecGetCompressBufferSize", (PyCFunction)Qt_DataCodecGetCompressBufferSize, 1,
+	 PyDoc_STR("(DataCodecComponent dc, UInt32 srcSize) -> (ComponentResult _rv, UInt32 dstSize)")},
+	{"DataCodecCompress", (PyCFunction)Qt_DataCodecCompress, 1,
+	 PyDoc_STR("(DataCodecComponent dc, void * srcData, UInt32 srcSize, void * dstData, UInt32 dstBufferSize) -> (ComponentResult _rv, UInt32 actualDstSize, UInt32 decompressSlop)")},
+	{"DataCodecBeginInterruptSafe", (PyCFunction)Qt_DataCodecBeginInterruptSafe, 1,
+	 PyDoc_STR("(DataCodecComponent dc, unsigned long maxSrcSize) -> (ComponentResult _rv)")},
+	{"DataCodecEndInterruptSafe", (PyCFunction)Qt_DataCodecEndInterruptSafe, 1,
+	 PyDoc_STR("(DataCodecComponent dc) -> (ComponentResult _rv)")},
+	{"DataHGetData", (PyCFunction)Qt_DataHGetData, 1,
+	 PyDoc_STR("(DataHandler dh, Handle h, long hOffset, long offset, long size) -> (ComponentResult _rv)")},
+	{"DataHPutData", (PyCFunction)Qt_DataHPutData, 1,
+	 PyDoc_STR("(DataHandler dh, Handle h, long hOffset, long size) -> (ComponentResult _rv, long offset)")},
+	{"DataHFlushData", (PyCFunction)Qt_DataHFlushData, 1,
+	 PyDoc_STR("(DataHandler dh) -> (ComponentResult _rv)")},
+	{"DataHOpenForWrite", (PyCFunction)Qt_DataHOpenForWrite, 1,
+	 PyDoc_STR("(DataHandler dh) -> (ComponentResult _rv)")},
+	{"DataHCloseForWrite", (PyCFunction)Qt_DataHCloseForWrite, 1,
+	 PyDoc_STR("(DataHandler dh) -> (ComponentResult _rv)")},
+	{"DataHOpenForRead", (PyCFunction)Qt_DataHOpenForRead, 1,
+	 PyDoc_STR("(DataHandler dh) -> (ComponentResult _rv)")},
+	{"DataHCloseForRead", (PyCFunction)Qt_DataHCloseForRead, 1,
+	 PyDoc_STR("(DataHandler dh) -> (ComponentResult _rv)")},
+	{"DataHSetDataRef", (PyCFunction)Qt_DataHSetDataRef, 1,
+	 PyDoc_STR("(DataHandler dh, Handle dataRef) -> (ComponentResult _rv)")},
+	{"DataHGetDataRef", (PyCFunction)Qt_DataHGetDataRef, 1,
+	 PyDoc_STR("(DataHandler dh) -> (ComponentResult _rv, Handle dataRef)")},
+	{"DataHCompareDataRef", (PyCFunction)Qt_DataHCompareDataRef, 1,
+	 PyDoc_STR("(DataHandler dh, Handle dataRef) -> (ComponentResult _rv, Boolean equal)")},
+	{"DataHTask", (PyCFunction)Qt_DataHTask, 1,
+	 PyDoc_STR("(DataHandler dh) -> (ComponentResult _rv)")},
+	{"DataHFinishData", (PyCFunction)Qt_DataHFinishData, 1,
+	 PyDoc_STR("(DataHandler dh, Ptr PlaceToPutDataPtr, Boolean Cancel) -> (ComponentResult _rv)")},
+	{"DataHFlushCache", (PyCFunction)Qt_DataHFlushCache, 1,
+	 PyDoc_STR("(DataHandler dh) -> (ComponentResult _rv)")},
+	{"DataHResolveDataRef", (PyCFunction)Qt_DataHResolveDataRef, 1,
+	 PyDoc_STR("(DataHandler dh, Handle theDataRef, Boolean userInterfaceAllowed) -> (ComponentResult _rv, Boolean wasChanged)")},
+	{"DataHGetFileSize", (PyCFunction)Qt_DataHGetFileSize, 1,
+	 PyDoc_STR("(DataHandler dh) -> (ComponentResult _rv, long fileSize)")},
+	{"DataHCanUseDataRef", (PyCFunction)Qt_DataHCanUseDataRef, 1,
+	 PyDoc_STR("(DataHandler dh, Handle dataRef) -> (ComponentResult _rv, long useFlags)")},
+	{"DataHPreextend", (PyCFunction)Qt_DataHPreextend, 1,
+	 PyDoc_STR("(DataHandler dh, unsigned long maxToAdd) -> (ComponentResult _rv, unsigned long spaceAdded)")},
+	{"DataHSetFileSize", (PyCFunction)Qt_DataHSetFileSize, 1,
+	 PyDoc_STR("(DataHandler dh, long fileSize) -> (ComponentResult _rv)")},
+	{"DataHGetFreeSpace", (PyCFunction)Qt_DataHGetFreeSpace, 1,
+	 PyDoc_STR("(DataHandler dh) -> (ComponentResult _rv, unsigned long freeSize)")},
+	{"DataHCreateFile", (PyCFunction)Qt_DataHCreateFile, 1,
+	 PyDoc_STR("(DataHandler dh, OSType creator, Boolean deleteExisting) -> (ComponentResult _rv)")},
+	{"DataHGetPreferredBlockSize", (PyCFunction)Qt_DataHGetPreferredBlockSize, 1,
+	 PyDoc_STR("(DataHandler dh) -> (ComponentResult _rv, long blockSize)")},
+	{"DataHGetDeviceIndex", (PyCFunction)Qt_DataHGetDeviceIndex, 1,
+	 PyDoc_STR("(DataHandler dh) -> (ComponentResult _rv, long deviceIndex)")},
+	{"DataHIsStreamingDataHandler", (PyCFunction)Qt_DataHIsStreamingDataHandler, 1,
+	 PyDoc_STR("(DataHandler dh) -> (ComponentResult _rv, Boolean yes)")},
+	{"DataHGetDataInBuffer", (PyCFunction)Qt_DataHGetDataInBuffer, 1,
+	 PyDoc_STR("(DataHandler dh, long startOffset) -> (ComponentResult _rv, long size)")},
+	{"DataHGetScheduleAheadTime", (PyCFunction)Qt_DataHGetScheduleAheadTime, 1,
+	 PyDoc_STR("(DataHandler dh) -> (ComponentResult _rv, long millisecs)")},
+	{"DataHSetCacheSizeLimit", (PyCFunction)Qt_DataHSetCacheSizeLimit, 1,
+	 PyDoc_STR("(DataHandler dh, Size cacheSizeLimit) -> (ComponentResult _rv)")},
+	{"DataHGetCacheSizeLimit", (PyCFunction)Qt_DataHGetCacheSizeLimit, 1,
+	 PyDoc_STR("(DataHandler dh) -> (ComponentResult _rv, Size cacheSizeLimit)")},
+	{"DataHGetMovie", (PyCFunction)Qt_DataHGetMovie, 1,
+	 PyDoc_STR("(DataHandler dh) -> (ComponentResult _rv, Movie theMovie, short id)")},
+	{"DataHAddMovie", (PyCFunction)Qt_DataHAddMovie, 1,
+	 PyDoc_STR("(DataHandler dh, Movie theMovie) -> (ComponentResult _rv, short id)")},
+	{"DataHUpdateMovie", (PyCFunction)Qt_DataHUpdateMovie, 1,
+	 PyDoc_STR("(DataHandler dh, Movie theMovie, short id) -> (ComponentResult _rv)")},
+	{"DataHDoesBuffer", (PyCFunction)Qt_DataHDoesBuffer, 1,
+	 PyDoc_STR("(DataHandler dh) -> (ComponentResult _rv, Boolean buffersReads, Boolean buffersWrites)")},
+	{"DataHGetFileName", (PyCFunction)Qt_DataHGetFileName, 1,
+	 PyDoc_STR("(DataHandler dh, Str255 str) -> (ComponentResult _rv)")},
+	{"DataHGetAvailableFileSize", (PyCFunction)Qt_DataHGetAvailableFileSize, 1,
+	 PyDoc_STR("(DataHandler dh) -> (ComponentResult _rv, long fileSize)")},
+	{"DataHGetMacOSFileType", (PyCFunction)Qt_DataHGetMacOSFileType, 1,
+	 PyDoc_STR("(DataHandler dh) -> (ComponentResult _rv, OSType fileType)")},
+	{"DataHGetMIMEType", (PyCFunction)Qt_DataHGetMIMEType, 1,
+	 PyDoc_STR("(DataHandler dh, Str255 mimeType) -> (ComponentResult _rv)")},
+	{"DataHSetDataRefWithAnchor", (PyCFunction)Qt_DataHSetDataRefWithAnchor, 1,
+	 PyDoc_STR("(DataHandler dh, Handle anchorDataRef, OSType dataRefType, Handle dataRef) -> (ComponentResult _rv)")},
+	{"DataHGetDataRefWithAnchor", (PyCFunction)Qt_DataHGetDataRefWithAnchor, 1,
+	 PyDoc_STR("(DataHandler dh, Handle anchorDataRef, OSType dataRefType) -> (ComponentResult _rv, Handle dataRef)")},
+	{"DataHSetMacOSFileType", (PyCFunction)Qt_DataHSetMacOSFileType, 1,
+	 PyDoc_STR("(DataHandler dh, OSType fileType) -> (ComponentResult _rv)")},
+	{"DataHSetTimeBase", (PyCFunction)Qt_DataHSetTimeBase, 1,
+	 PyDoc_STR("(DataHandler dh, TimeBase tb) -> (ComponentResult _rv)")},
+	{"DataHGetInfoFlags", (PyCFunction)Qt_DataHGetInfoFlags, 1,
+	 PyDoc_STR("(DataHandler dh) -> (ComponentResult _rv, UInt32 flags)")},
+	{"DataHGetFileSize64", (PyCFunction)Qt_DataHGetFileSize64, 1,
+	 PyDoc_STR("(DataHandler dh) -> (ComponentResult _rv, wide fileSize)")},
+	{"DataHPreextend64", (PyCFunction)Qt_DataHPreextend64, 1,
+	 PyDoc_STR("(DataHandler dh, wide maxToAdd) -> (ComponentResult _rv, wide spaceAdded)")},
+	{"DataHSetFileSize64", (PyCFunction)Qt_DataHSetFileSize64, 1,
+	 PyDoc_STR("(DataHandler dh, wide fileSize) -> (ComponentResult _rv)")},
+	{"DataHGetFreeSpace64", (PyCFunction)Qt_DataHGetFreeSpace64, 1,
+	 PyDoc_STR("(DataHandler dh) -> (ComponentResult _rv, wide freeSize)")},
+	{"DataHAppend64", (PyCFunction)Qt_DataHAppend64, 1,
+	 PyDoc_STR("(DataHandler dh, void * data, unsigned long size) -> (ComponentResult _rv, wide fileOffset)")},
+	{"DataHPollRead", (PyCFunction)Qt_DataHPollRead, 1,
+	 PyDoc_STR("(DataHandler dh, void * dataPtr) -> (ComponentResult _rv, UInt32 dataSizeSoFar)")},
+	{"DataHGetDataAvailability", (PyCFunction)Qt_DataHGetDataAvailability, 1,
+	 PyDoc_STR("(DataHandler dh, long offset, long len) -> (ComponentResult _rv, long missing_offset, long missing_len)")},
+	{"DataHGetDataRefAsType", (PyCFunction)Qt_DataHGetDataRefAsType, 1,
+	 PyDoc_STR("(DataHandler dh, OSType requestedType) -> (ComponentResult _rv, Handle dataRef)")},
+	{"DataHSetDataRefExtension", (PyCFunction)Qt_DataHSetDataRefExtension, 1,
+	 PyDoc_STR("(DataHandler dh, Handle extension, OSType idType) -> (ComponentResult _rv)")},
+	{"DataHGetDataRefExtension", (PyCFunction)Qt_DataHGetDataRefExtension, 1,
+	 PyDoc_STR("(DataHandler dh, OSType idType) -> (ComponentResult _rv, Handle extension)")},
+	{"DataHGetMovieWithFlags", (PyCFunction)Qt_DataHGetMovieWithFlags, 1,
+	 PyDoc_STR("(DataHandler dh, short flags) -> (ComponentResult _rv, Movie theMovie, short id)")},
+	{"DataHGetFileTypeOrdering", (PyCFunction)Qt_DataHGetFileTypeOrdering, 1,
+	 PyDoc_STR("(DataHandler dh) -> (ComponentResult _rv, DataHFileTypeOrderingHandle orderingListHandle)")},
+	{"DataHCreateFileWithFlags", (PyCFunction)Qt_DataHCreateFileWithFlags, 1,
+	 PyDoc_STR("(DataHandler dh, OSType creator, Boolean deleteExisting, UInt32 flags) -> (ComponentResult _rv)")},
+	{"DataHGetInfo", (PyCFunction)Qt_DataHGetInfo, 1,
+	 PyDoc_STR("(DataHandler dh, OSType what, void * info) -> (ComponentResult _rv)")},
+	{"DataHSetIdleManager", (PyCFunction)Qt_DataHSetIdleManager, 1,
+	 PyDoc_STR("(DataHandler dh, IdleManager im) -> (ComponentResult _rv)")},
+	{"DataHDeleteFile", (PyCFunction)Qt_DataHDeleteFile, 1,
+	 PyDoc_STR("(DataHandler dh) -> (ComponentResult _rv)")},
+	{"DataHSetMovieUsageFlags", (PyCFunction)Qt_DataHSetMovieUsageFlags, 1,
+	 PyDoc_STR("(DataHandler dh, long flags) -> (ComponentResult _rv)")},
+	{"DataHUseTemporaryDataRef", (PyCFunction)Qt_DataHUseTemporaryDataRef, 1,
+	 PyDoc_STR("(DataHandler dh, long inFlags) -> (ComponentResult _rv)")},
+	{"DataHGetTemporaryDataRefCapabilities", (PyCFunction)Qt_DataHGetTemporaryDataRefCapabilities, 1,
+	 PyDoc_STR("(DataHandler dh) -> (ComponentResult _rv, long outUnderstoodFlags)")},
+	{"DataHRenameFile", (PyCFunction)Qt_DataHRenameFile, 1,
+	 PyDoc_STR("(DataHandler dh, Handle newDataRef) -> (ComponentResult _rv)")},
+	{"DataHPlaybackHints", (PyCFunction)Qt_DataHPlaybackHints, 1,
+	 PyDoc_STR("(DataHandler dh, long flags, unsigned long minFileOffset, unsigned long maxFileOffset, long bytesPerSecond) -> (ComponentResult _rv)")},
+	{"DataHPlaybackHints64", (PyCFunction)Qt_DataHPlaybackHints64, 1,
+	 PyDoc_STR("(DataHandler dh, long flags, wide minFileOffset, wide maxFileOffset, long bytesPerSecond) -> (ComponentResult _rv)")},
+	{"DataHGetDataRate", (PyCFunction)Qt_DataHGetDataRate, 1,
+	 PyDoc_STR("(DataHandler dh, long flags) -> (ComponentResult _rv, long bytesPerSecond)")},
+	{"DataHSetTimeHints", (PyCFunction)Qt_DataHSetTimeHints, 1,
+	 PyDoc_STR("(DataHandler dh, long flags, long bandwidthPriority, TimeScale scale, TimeValue minTime, TimeValue maxTime) -> (ComponentResult _rv)")},
+	{"VDGetMaxSrcRect", (PyCFunction)Qt_VDGetMaxSrcRect, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci, short inputStd) -> (ComponentResult _rv, Rect maxSrcRect)")},
+	{"VDGetActiveSrcRect", (PyCFunction)Qt_VDGetActiveSrcRect, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci, short inputStd) -> (ComponentResult _rv, Rect activeSrcRect)")},
+	{"VDSetDigitizerRect", (PyCFunction)Qt_VDSetDigitizerRect, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci) -> (ComponentResult _rv, Rect digitizerRect)")},
+	{"VDGetDigitizerRect", (PyCFunction)Qt_VDGetDigitizerRect, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci) -> (ComponentResult _rv, Rect digitizerRect)")},
+	{"VDGetVBlankRect", (PyCFunction)Qt_VDGetVBlankRect, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci, short inputStd) -> (ComponentResult _rv, Rect vBlankRect)")},
+	{"VDGetMaskPixMap", (PyCFunction)Qt_VDGetMaskPixMap, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci, PixMapHandle maskPixMap) -> (ComponentResult _rv)")},
+	{"VDUseThisCLUT", (PyCFunction)Qt_VDUseThisCLUT, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci, CTabHandle colorTableHandle) -> (ComponentResult _rv)")},
+	{"VDSetInputGammaValue", (PyCFunction)Qt_VDSetInputGammaValue, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci, Fixed channel1, Fixed channel2, Fixed channel3) -> (ComponentResult _rv)")},
+	{"VDGetInputGammaValue", (PyCFunction)Qt_VDGetInputGammaValue, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci) -> (ComponentResult _rv, Fixed channel1, Fixed channel2, Fixed channel3)")},
+	{"VDSetBrightness", (PyCFunction)Qt_VDSetBrightness, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci) -> (ComponentResult _rv, unsigned short brightness)")},
+	{"VDGetBrightness", (PyCFunction)Qt_VDGetBrightness, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci) -> (ComponentResult _rv, unsigned short brightness)")},
+	{"VDSetContrast", (PyCFunction)Qt_VDSetContrast, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci) -> (ComponentResult _rv, unsigned short contrast)")},
+	{"VDSetHue", (PyCFunction)Qt_VDSetHue, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci) -> (ComponentResult _rv, unsigned short hue)")},
+	{"VDSetSharpness", (PyCFunction)Qt_VDSetSharpness, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci) -> (ComponentResult _rv, unsigned short sharpness)")},
+	{"VDSetSaturation", (PyCFunction)Qt_VDSetSaturation, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci) -> (ComponentResult _rv, unsigned short saturation)")},
+	{"VDGetContrast", (PyCFunction)Qt_VDGetContrast, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci) -> (ComponentResult _rv, unsigned short contrast)")},
+	{"VDGetHue", (PyCFunction)Qt_VDGetHue, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci) -> (ComponentResult _rv, unsigned short hue)")},
+	{"VDGetSharpness", (PyCFunction)Qt_VDGetSharpness, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci) -> (ComponentResult _rv, unsigned short sharpness)")},
+	{"VDGetSaturation", (PyCFunction)Qt_VDGetSaturation, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci) -> (ComponentResult _rv, unsigned short saturation)")},
+	{"VDGrabOneFrame", (PyCFunction)Qt_VDGrabOneFrame, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci) -> (ComponentResult _rv)")},
+	{"VDGetMaxAuxBuffer", (PyCFunction)Qt_VDGetMaxAuxBuffer, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci) -> (ComponentResult _rv, PixMapHandle pm, Rect r)")},
+	{"VDGetCurrentFlags", (PyCFunction)Qt_VDGetCurrentFlags, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci) -> (ComponentResult _rv, long inputCurrentFlag, long outputCurrentFlag)")},
+	{"VDSetKeyColor", (PyCFunction)Qt_VDSetKeyColor, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci, long index) -> (ComponentResult _rv)")},
+	{"VDGetKeyColor", (PyCFunction)Qt_VDGetKeyColor, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci) -> (ComponentResult _rv, long index)")},
+	{"VDAddKeyColor", (PyCFunction)Qt_VDAddKeyColor, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci) -> (ComponentResult _rv, long index)")},
+	{"VDGetNextKeyColor", (PyCFunction)Qt_VDGetNextKeyColor, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci, long index) -> (ComponentResult _rv)")},
+	{"VDSetKeyColorRange", (PyCFunction)Qt_VDSetKeyColorRange, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci) -> (ComponentResult _rv, RGBColor minRGB, RGBColor maxRGB)")},
+	{"VDGetKeyColorRange", (PyCFunction)Qt_VDGetKeyColorRange, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci) -> (ComponentResult _rv, RGBColor minRGB, RGBColor maxRGB)")},
+	{"VDSetInputColorSpaceMode", (PyCFunction)Qt_VDSetInputColorSpaceMode, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci, short colorSpaceMode) -> (ComponentResult _rv)")},
+	{"VDGetInputColorSpaceMode", (PyCFunction)Qt_VDGetInputColorSpaceMode, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci) -> (ComponentResult _rv, short colorSpaceMode)")},
+	{"VDSetClipState", (PyCFunction)Qt_VDSetClipState, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci, short clipEnable) -> (ComponentResult _rv)")},
+	{"VDGetClipState", (PyCFunction)Qt_VDGetClipState, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci) -> (ComponentResult _rv, short clipEnable)")},
+	{"VDSetClipRgn", (PyCFunction)Qt_VDSetClipRgn, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci, RgnHandle clipRegion) -> (ComponentResult _rv)")},
+	{"VDClearClipRgn", (PyCFunction)Qt_VDClearClipRgn, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci, RgnHandle clipRegion) -> (ComponentResult _rv)")},
+	{"VDGetCLUTInUse", (PyCFunction)Qt_VDGetCLUTInUse, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci) -> (ComponentResult _rv, CTabHandle colorTableHandle)")},
+	{"VDSetPLLFilterType", (PyCFunction)Qt_VDSetPLLFilterType, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci, short pllType) -> (ComponentResult _rv)")},
+	{"VDGetPLLFilterType", (PyCFunction)Qt_VDGetPLLFilterType, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci) -> (ComponentResult _rv, short pllType)")},
+	{"VDGetMaskandValue", (PyCFunction)Qt_VDGetMaskandValue, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci, unsigned short blendLevel) -> (ComponentResult _rv, long mask, long value)")},
+	{"VDSetMasterBlendLevel", (PyCFunction)Qt_VDSetMasterBlendLevel, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci) -> (ComponentResult _rv, unsigned short blendLevel)")},
+	{"VDSetPlayThruOnOff", (PyCFunction)Qt_VDSetPlayThruOnOff, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci, short state) -> (ComponentResult _rv)")},
+	{"VDSetFieldPreference", (PyCFunction)Qt_VDSetFieldPreference, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci, short fieldFlag) -> (ComponentResult _rv)")},
+	{"VDGetFieldPreference", (PyCFunction)Qt_VDGetFieldPreference, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci) -> (ComponentResult _rv, short fieldFlag)")},
+	{"VDPreflightGlobalRect", (PyCFunction)Qt_VDPreflightGlobalRect, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci, GrafPtr theWindow) -> (ComponentResult _rv, Rect globalRect)")},
+	{"VDSetPlayThruGlobalRect", (PyCFunction)Qt_VDSetPlayThruGlobalRect, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci, GrafPtr theWindow) -> (ComponentResult _rv, Rect globalRect)")},
+	{"VDSetBlackLevelValue", (PyCFunction)Qt_VDSetBlackLevelValue, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci) -> (ComponentResult _rv, unsigned short blackLevel)")},
+	{"VDGetBlackLevelValue", (PyCFunction)Qt_VDGetBlackLevelValue, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci) -> (ComponentResult _rv, unsigned short blackLevel)")},
+	{"VDSetWhiteLevelValue", (PyCFunction)Qt_VDSetWhiteLevelValue, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci) -> (ComponentResult _rv, unsigned short whiteLevel)")},
+	{"VDGetWhiteLevelValue", (PyCFunction)Qt_VDGetWhiteLevelValue, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci) -> (ComponentResult _rv, unsigned short whiteLevel)")},
+	{"VDGetVideoDefaults", (PyCFunction)Qt_VDGetVideoDefaults, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci) -> (ComponentResult _rv, unsigned short blackLevel, unsigned short whiteLevel, unsigned short brightness, unsigned short hue, unsigned short saturation, unsigned short contrast, unsigned short sharpness)")},
+	{"VDGetNumberOfInputs", (PyCFunction)Qt_VDGetNumberOfInputs, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci) -> (ComponentResult _rv, short inputs)")},
+	{"VDGetInputFormat", (PyCFunction)Qt_VDGetInputFormat, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci, short input) -> (ComponentResult _rv, short format)")},
+	{"VDSetInput", (PyCFunction)Qt_VDSetInput, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci, short input) -> (ComponentResult _rv)")},
+	{"VDGetInput", (PyCFunction)Qt_VDGetInput, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci) -> (ComponentResult _rv, short input)")},
+	{"VDSetInputStandard", (PyCFunction)Qt_VDSetInputStandard, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci, short inputStandard) -> (ComponentResult _rv)")},
+	{"VDSetupBuffers", (PyCFunction)Qt_VDSetupBuffers, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci, VdigBufferRecListHandle bufferList) -> (ComponentResult _rv)")},
+	{"VDGrabOneFrameAsync", (PyCFunction)Qt_VDGrabOneFrameAsync, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci, short buffer) -> (ComponentResult _rv)")},
+	{"VDDone", (PyCFunction)Qt_VDDone, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci, short buffer) -> (ComponentResult _rv)")},
+	{"VDSetCompression", (PyCFunction)Qt_VDSetCompression, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci, OSType compressType, short depth, CodecQ spatialQuality, CodecQ temporalQuality, long keyFrameRate) -> (ComponentResult _rv, Rect bounds)")},
+	{"VDCompressOneFrameAsync", (PyCFunction)Qt_VDCompressOneFrameAsync, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci) -> (ComponentResult _rv)")},
+	{"VDGetImageDescription", (PyCFunction)Qt_VDGetImageDescription, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci, ImageDescriptionHandle desc) -> (ComponentResult _rv)")},
+	{"VDResetCompressSequence", (PyCFunction)Qt_VDResetCompressSequence, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci) -> (ComponentResult _rv)")},
+	{"VDSetCompressionOnOff", (PyCFunction)Qt_VDSetCompressionOnOff, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci, Boolean state) -> (ComponentResult _rv)")},
+	{"VDGetCompressionTypes", (PyCFunction)Qt_VDGetCompressionTypes, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci, VDCompressionListHandle h) -> (ComponentResult _rv)")},
+	{"VDSetTimeBase", (PyCFunction)Qt_VDSetTimeBase, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci, TimeBase t) -> (ComponentResult _rv)")},
+	{"VDSetFrameRate", (PyCFunction)Qt_VDSetFrameRate, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci, Fixed framesPerSecond) -> (ComponentResult _rv)")},
+	{"VDGetDataRate", (PyCFunction)Qt_VDGetDataRate, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci) -> (ComponentResult _rv, long milliSecPerFrame, Fixed framesPerSecond, long bytesPerSecond)")},
+	{"VDGetSoundInputDriver", (PyCFunction)Qt_VDGetSoundInputDriver, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci, Str255 soundDriverName) -> (ComponentResult _rv)")},
+	{"VDGetDMADepths", (PyCFunction)Qt_VDGetDMADepths, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci) -> (ComponentResult _rv, long depthArray, long preferredDepth)")},
+	{"VDGetPreferredTimeScale", (PyCFunction)Qt_VDGetPreferredTimeScale, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci) -> (ComponentResult _rv, TimeScale preferred)")},
+	{"VDReleaseAsyncBuffers", (PyCFunction)Qt_VDReleaseAsyncBuffers, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci) -> (ComponentResult _rv)")},
+	{"VDSetDataRate", (PyCFunction)Qt_VDSetDataRate, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci, long bytesPerSecond) -> (ComponentResult _rv)")},
+	{"VDGetTimeCode", (PyCFunction)Qt_VDGetTimeCode, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci, void * timeCodeFormat, void * timeCodeTime) -> (ComponentResult _rv, TimeRecord atTime)")},
+	{"VDUseSafeBuffers", (PyCFunction)Qt_VDUseSafeBuffers, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci, Boolean useSafeBuffers) -> (ComponentResult _rv)")},
+	{"VDGetSoundInputSource", (PyCFunction)Qt_VDGetSoundInputSource, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci, long videoInput) -> (ComponentResult _rv, long soundInput)")},
+	{"VDGetCompressionTime", (PyCFunction)Qt_VDGetCompressionTime, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci, OSType compressionType, short depth) -> (ComponentResult _rv, Rect srcRect, CodecQ spatialQuality, CodecQ temporalQuality, unsigned long compressTime)")},
+	{"VDSetPreferredPacketSize", (PyCFunction)Qt_VDSetPreferredPacketSize, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci, long preferredPacketSizeInBytes) -> (ComponentResult _rv)")},
+	{"VDSetPreferredImageDimensions", (PyCFunction)Qt_VDSetPreferredImageDimensions, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci, long width, long height) -> (ComponentResult _rv)")},
+	{"VDGetPreferredImageDimensions", (PyCFunction)Qt_VDGetPreferredImageDimensions, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci) -> (ComponentResult _rv, long width, long height)")},
+	{"VDGetInputName", (PyCFunction)Qt_VDGetInputName, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci, long videoInput, Str255 name) -> (ComponentResult _rv)")},
+	{"VDSetDestinationPort", (PyCFunction)Qt_VDSetDestinationPort, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci, CGrafPtr destPort) -> (ComponentResult _rv)")},
+	{"VDGetDeviceNameAndFlags", (PyCFunction)Qt_VDGetDeviceNameAndFlags, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci, Str255 outName) -> (ComponentResult _rv, UInt32 outNameFlags)")},
+	{"VDCaptureStateChanging", (PyCFunction)Qt_VDCaptureStateChanging, 1,
+	 PyDoc_STR("(VideoDigitizerComponent ci, UInt32 inStateFlags) -> (ComponentResult _rv)")},
+	{"XMLParseGetDetailedParseError", (PyCFunction)Qt_XMLParseGetDetailedParseError, 1,
+	 PyDoc_STR("(ComponentInstance aParser, StringPtr errDesc) -> (ComponentResult _rv, long errorLine)")},
+	{"XMLParseAddElement", (PyCFunction)Qt_XMLParseAddElement, 1,
+	 PyDoc_STR("(ComponentInstance aParser, UInt32 nameSpaceID, long elementFlags) -> (ComponentResult _rv, char elementName, UInt32 elementID)")},
+	{"XMLParseAddAttribute", (PyCFunction)Qt_XMLParseAddAttribute, 1,
+	 PyDoc_STR("(ComponentInstance aParser, UInt32 elementID, UInt32 nameSpaceID) -> (ComponentResult _rv, char attributeName, UInt32 attributeID)")},
+	{"XMLParseAddMultipleAttributes", (PyCFunction)Qt_XMLParseAddMultipleAttributes, 1,
+	 PyDoc_STR("(ComponentInstance aParser, UInt32 elementID) -> (ComponentResult _rv, UInt32 nameSpaceIDs, char attributeNames, UInt32 attributeIDs)")},
+	{"XMLParseAddAttributeAndValue", (PyCFunction)Qt_XMLParseAddAttributeAndValue, 1,
+	 PyDoc_STR("(ComponentInstance aParser, UInt32 elementID, UInt32 nameSpaceID, UInt32 attributeValueKind, void * attributeValueKindInfo) -> (ComponentResult _rv, char attributeName, UInt32 attributeID)")},
+	{"XMLParseAddAttributeValueKind", (PyCFunction)Qt_XMLParseAddAttributeValueKind, 1,
+	 PyDoc_STR("(ComponentInstance aParser, UInt32 elementID, UInt32 attributeID, UInt32 attributeValueKind, void * attributeValueKindInfo) -> (ComponentResult _rv)")},
+	{"XMLParseAddNameSpace", (PyCFunction)Qt_XMLParseAddNameSpace, 1,
+	 PyDoc_STR("(ComponentInstance aParser) -> (ComponentResult _rv, char nameSpaceURL, UInt32 nameSpaceID)")},
+	{"XMLParseSetOffsetAndLimit", (PyCFunction)Qt_XMLParseSetOffsetAndLimit, 1,
+	 PyDoc_STR("(ComponentInstance aParser, UInt32 offset, UInt32 limit) -> (ComponentResult _rv)")},
+	{"XMLParseSetEventParseRefCon", (PyCFunction)Qt_XMLParseSetEventParseRefCon, 1,
+	 PyDoc_STR("(ComponentInstance aParser, long refcon) -> (ComponentResult _rv)")},
+	{"SGInitialize", (PyCFunction)Qt_SGInitialize, 1,
+	 PyDoc_STR("(SeqGrabComponent s) -> (ComponentResult _rv)")},
+	{"SGSetDataOutput", (PyCFunction)Qt_SGSetDataOutput, 1,
+	 PyDoc_STR("(SeqGrabComponent s, FSSpec movieFile, long whereFlags) -> (ComponentResult _rv)")},
+	{"SGGetDataOutput", (PyCFunction)Qt_SGGetDataOutput, 1,
+	 PyDoc_STR("(SeqGrabComponent s, FSSpec movieFile) -> (ComponentResult _rv, long whereFlags)")},
+	{"SGSetGWorld", (PyCFunction)Qt_SGSetGWorld, 1,
+	 PyDoc_STR("(SeqGrabComponent s, CGrafPtr gp, GDHandle gd) -> (ComponentResult _rv)")},
+	{"SGGetGWorld", (PyCFunction)Qt_SGGetGWorld, 1,
+	 PyDoc_STR("(SeqGrabComponent s) -> (ComponentResult _rv, CGrafPtr gp, GDHandle gd)")},
+	{"SGNewChannel", (PyCFunction)Qt_SGNewChannel, 1,
+	 PyDoc_STR("(SeqGrabComponent s, OSType channelType) -> (ComponentResult _rv, SGChannel ref)")},
+	{"SGDisposeChannel", (PyCFunction)Qt_SGDisposeChannel, 1,
+	 PyDoc_STR("(SeqGrabComponent s, SGChannel c) -> (ComponentResult _rv)")},
+	{"SGStartPreview", (PyCFunction)Qt_SGStartPreview, 1,
+	 PyDoc_STR("(SeqGrabComponent s) -> (ComponentResult _rv)")},
+	{"SGStartRecord", (PyCFunction)Qt_SGStartRecord, 1,
+	 PyDoc_STR("(SeqGrabComponent s) -> (ComponentResult _rv)")},
+	{"SGIdle", (PyCFunction)Qt_SGIdle, 1,
+	 PyDoc_STR("(SeqGrabComponent s) -> (ComponentResult _rv)")},
+	{"SGStop", (PyCFunction)Qt_SGStop, 1,
+	 PyDoc_STR("(SeqGrabComponent s) -> (ComponentResult _rv)")},
+	{"SGPause", (PyCFunction)Qt_SGPause, 1,
+	 PyDoc_STR("(SeqGrabComponent s, Boolean pause) -> (ComponentResult _rv)")},
+	{"SGPrepare", (PyCFunction)Qt_SGPrepare, 1,
+	 PyDoc_STR("(SeqGrabComponent s, Boolean prepareForPreview, Boolean prepareForRecord) -> (ComponentResult _rv)")},
+	{"SGRelease", (PyCFunction)Qt_SGRelease, 1,
+	 PyDoc_STR("(SeqGrabComponent s) -> (ComponentResult _rv)")},
+	{"SGGetMovie", (PyCFunction)Qt_SGGetMovie, 1,
+	 PyDoc_STR("(SeqGrabComponent s) -> (Movie _rv)")},
+	{"SGSetMaximumRecordTime", (PyCFunction)Qt_SGSetMaximumRecordTime, 1,
+	 PyDoc_STR("(SeqGrabComponent s, unsigned long ticks) -> (ComponentResult _rv)")},
+	{"SGGetMaximumRecordTime", (PyCFunction)Qt_SGGetMaximumRecordTime, 1,
+	 PyDoc_STR("(SeqGrabComponent s) -> (ComponentResult _rv, unsigned long ticks)")},
+	{"SGGetStorageSpaceRemaining", (PyCFunction)Qt_SGGetStorageSpaceRemaining, 1,
+	 PyDoc_STR("(SeqGrabComponent s) -> (ComponentResult _rv, unsigned long bytes)")},
+	{"SGGetTimeRemaining", (PyCFunction)Qt_SGGetTimeRemaining, 1,
+	 PyDoc_STR("(SeqGrabComponent s) -> (ComponentResult _rv, long ticksLeft)")},
+	{"SGGrabPict", (PyCFunction)Qt_SGGrabPict, 1,
+	 PyDoc_STR("(SeqGrabComponent s, Rect bounds, short offscreenDepth, long grabPictFlags) -> (ComponentResult _rv, PicHandle p)")},
+	{"SGGetLastMovieResID", (PyCFunction)Qt_SGGetLastMovieResID, 1,
+	 PyDoc_STR("(SeqGrabComponent s) -> (ComponentResult _rv, short resID)")},
+	{"SGSetFlags", (PyCFunction)Qt_SGSetFlags, 1,
+	 PyDoc_STR("(SeqGrabComponent s, long sgFlags) -> (ComponentResult _rv)")},
+	{"SGGetFlags", (PyCFunction)Qt_SGGetFlags, 1,
+	 PyDoc_STR("(SeqGrabComponent s) -> (ComponentResult _rv, long sgFlags)")},
+	{"SGNewChannelFromComponent", (PyCFunction)Qt_SGNewChannelFromComponent, 1,
+	 PyDoc_STR("(SeqGrabComponent s, Component sgChannelComponent) -> (ComponentResult _rv, SGChannel newChannel)")},
+	{"SGSetSettings", (PyCFunction)Qt_SGSetSettings, 1,
+	 PyDoc_STR("(SeqGrabComponent s, UserData ud, long flags) -> (ComponentResult _rv)")},
+	{"SGGetSettings", (PyCFunction)Qt_SGGetSettings, 1,
+	 PyDoc_STR("(SeqGrabComponent s, long flags) -> (ComponentResult _rv, UserData ud)")},
+	{"SGGetIndChannel", (PyCFunction)Qt_SGGetIndChannel, 1,
+	 PyDoc_STR("(SeqGrabComponent s, short index) -> (ComponentResult _rv, SGChannel ref, OSType chanType)")},
+	{"SGUpdate", (PyCFunction)Qt_SGUpdate, 1,
+	 PyDoc_STR("(SeqGrabComponent s, RgnHandle updateRgn) -> (ComponentResult _rv)")},
+	{"SGGetPause", (PyCFunction)Qt_SGGetPause, 1,
+	 PyDoc_STR("(SeqGrabComponent s) -> (ComponentResult _rv, Boolean paused)")},
+	{"SGSetChannelSettings", (PyCFunction)Qt_SGSetChannelSettings, 1,
+	 PyDoc_STR("(SeqGrabComponent s, SGChannel c, UserData ud, long flags) -> (ComponentResult _rv)")},
+	{"SGGetChannelSettings", (PyCFunction)Qt_SGGetChannelSettings, 1,
+	 PyDoc_STR("(SeqGrabComponent s, SGChannel c, long flags) -> (ComponentResult _rv, UserData ud)")},
+	{"SGGetMode", (PyCFunction)Qt_SGGetMode, 1,
+	 PyDoc_STR("(SeqGrabComponent s) -> (ComponentResult _rv, Boolean previewMode, Boolean recordMode)")},
+	{"SGSetDataRef", (PyCFunction)Qt_SGSetDataRef, 1,
+	 PyDoc_STR("(SeqGrabComponent s, Handle dataRef, OSType dataRefType, long whereFlags) -> (ComponentResult _rv)")},
+	{"SGGetDataRef", (PyCFunction)Qt_SGGetDataRef, 1,
+	 PyDoc_STR("(SeqGrabComponent s) -> (ComponentResult _rv, Handle dataRef, OSType dataRefType, long whereFlags)")},
+	{"SGNewOutput", (PyCFunction)Qt_SGNewOutput, 1,
+	 PyDoc_STR("(SeqGrabComponent s, Handle dataRef, OSType dataRefType, long whereFlags) -> (ComponentResult _rv, SGOutput sgOut)")},
+	{"SGDisposeOutput", (PyCFunction)Qt_SGDisposeOutput, 1,
+	 PyDoc_STR("(SeqGrabComponent s, SGOutput sgOut) -> (ComponentResult _rv)")},
+	{"SGSetOutputFlags", (PyCFunction)Qt_SGSetOutputFlags, 1,
+	 PyDoc_STR("(SeqGrabComponent s, SGOutput sgOut, long whereFlags) -> (ComponentResult _rv)")},
+	{"SGSetChannelOutput", (PyCFunction)Qt_SGSetChannelOutput, 1,
+	 PyDoc_STR("(SeqGrabComponent s, SGChannel c, SGOutput sgOut) -> (ComponentResult _rv)")},
+	{"SGGetDataOutputStorageSpaceRemaining", (PyCFunction)Qt_SGGetDataOutputStorageSpaceRemaining, 1,
+	 PyDoc_STR("(SeqGrabComponent s, SGOutput sgOut) -> (ComponentResult _rv, unsigned long space)")},
+	{"SGHandleUpdateEvent", (PyCFunction)Qt_SGHandleUpdateEvent, 1,
+	 PyDoc_STR("(SeqGrabComponent s, EventRecord event) -> (ComponentResult _rv, Boolean handled)")},
+	{"SGSetOutputNextOutput", (PyCFunction)Qt_SGSetOutputNextOutput, 1,
+	 PyDoc_STR("(SeqGrabComponent s, SGOutput sgOut, SGOutput nextOut) -> (ComponentResult _rv)")},
+	{"SGGetOutputNextOutput", (PyCFunction)Qt_SGGetOutputNextOutput, 1,
+	 PyDoc_STR("(SeqGrabComponent s, SGOutput sgOut) -> (ComponentResult _rv, SGOutput nextOut)")},
+	{"SGSetOutputMaximumOffset", (PyCFunction)Qt_SGSetOutputMaximumOffset, 1,
+	 PyDoc_STR("(SeqGrabComponent s, SGOutput sgOut, wide maxOffset) -> (ComponentResult _rv)")},
+	{"SGGetOutputMaximumOffset", (PyCFunction)Qt_SGGetOutputMaximumOffset, 1,
+	 PyDoc_STR("(SeqGrabComponent s, SGOutput sgOut) -> (ComponentResult _rv, wide maxOffset)")},
+	{"SGGetOutputDataReference", (PyCFunction)Qt_SGGetOutputDataReference, 1,
+	 PyDoc_STR("(SeqGrabComponent s, SGOutput sgOut) -> (ComponentResult _rv, Handle dataRef, OSType dataRefType)")},
+	{"SGWriteExtendedMovieData", (PyCFunction)Qt_SGWriteExtendedMovieData, 1,
+	 PyDoc_STR("(SeqGrabComponent s, SGChannel c, Ptr p, long len) -> (ComponentResult _rv, wide offset, SGOutput sgOut)")},
+	{"SGGetStorageSpaceRemaining64", (PyCFunction)Qt_SGGetStorageSpaceRemaining64, 1,
+	 PyDoc_STR("(SeqGrabComponent s) -> (ComponentResult _rv, wide bytes)")},
+	{"SGGetDataOutputStorageSpaceRemaining64", (PyCFunction)Qt_SGGetDataOutputStorageSpaceRemaining64, 1,
+	 PyDoc_STR("(SeqGrabComponent s, SGOutput sgOut) -> (ComponentResult _rv, wide space)")},
+	{"SGWriteMovieData", (PyCFunction)Qt_SGWriteMovieData, 1,
+	 PyDoc_STR("(SeqGrabComponent s, SGChannel c, Ptr p, long len) -> (ComponentResult _rv, long offset)")},
+	{"SGGetTimeBase", (PyCFunction)Qt_SGGetTimeBase, 1,
+	 PyDoc_STR("(SeqGrabComponent s) -> (ComponentResult _rv, TimeBase tb)")},
+	{"SGAddMovieData", (PyCFunction)Qt_SGAddMovieData, 1,
+	 PyDoc_STR("(SeqGrabComponent s, SGChannel c, Ptr p, long len, long chRefCon, TimeValue time, short writeType) -> (ComponentResult _rv, long offset)")},
+	{"SGChangedSource", (PyCFunction)Qt_SGChangedSource, 1,
+	 PyDoc_STR("(SeqGrabComponent s, SGChannel c) -> (ComponentResult _rv)")},
+	{"SGAddExtendedMovieData", (PyCFunction)Qt_SGAddExtendedMovieData, 1,
+	 PyDoc_STR("(SeqGrabComponent s, SGChannel c, Ptr p, long len, long chRefCon, TimeValue time, short writeType) -> (ComponentResult _rv, wide offset, SGOutput whichOutput)")},
+	{"SGAddOutputDataRefToMedia", (PyCFunction)Qt_SGAddOutputDataRefToMedia, 1,
+	 PyDoc_STR("(SeqGrabComponent s, SGOutput sgOut, Media theMedia, SampleDescriptionHandle desc) -> (ComponentResult _rv)")},
+	{"SGSetSettingsSummary", (PyCFunction)Qt_SGSetSettingsSummary, 1,
+	 PyDoc_STR("(SeqGrabComponent s, Handle summaryText) -> (ComponentResult _rv)")},
+	{"SGSetChannelUsage", (PyCFunction)Qt_SGSetChannelUsage, 1,
+	 PyDoc_STR("(SGChannel c, long usage) -> (ComponentResult _rv)")},
+	{"SGGetChannelUsage", (PyCFunction)Qt_SGGetChannelUsage, 1,
+	 PyDoc_STR("(SGChannel c) -> (ComponentResult _rv, long usage)")},
+	{"SGSetChannelBounds", (PyCFunction)Qt_SGSetChannelBounds, 1,
+	 PyDoc_STR("(SGChannel c, Rect bounds) -> (ComponentResult _rv)")},
+	{"SGGetChannelBounds", (PyCFunction)Qt_SGGetChannelBounds, 1,
+	 PyDoc_STR("(SGChannel c) -> (ComponentResult _rv, Rect bounds)")},
+	{"SGSetChannelVolume", (PyCFunction)Qt_SGSetChannelVolume, 1,
+	 PyDoc_STR("(SGChannel c, short volume) -> (ComponentResult _rv)")},
+	{"SGGetChannelVolume", (PyCFunction)Qt_SGGetChannelVolume, 1,
+	 PyDoc_STR("(SGChannel c) -> (ComponentResult _rv, short volume)")},
+	{"SGGetChannelInfo", (PyCFunction)Qt_SGGetChannelInfo, 1,
+	 PyDoc_STR("(SGChannel c) -> (ComponentResult _rv, long channelInfo)")},
+	{"SGSetChannelPlayFlags", (PyCFunction)Qt_SGSetChannelPlayFlags, 1,
+	 PyDoc_STR("(SGChannel c, long playFlags) -> (ComponentResult _rv)")},
+	{"SGGetChannelPlayFlags", (PyCFunction)Qt_SGGetChannelPlayFlags, 1,
+	 PyDoc_STR("(SGChannel c) -> (ComponentResult _rv, long playFlags)")},
+	{"SGSetChannelMaxFrames", (PyCFunction)Qt_SGSetChannelMaxFrames, 1,
+	 PyDoc_STR("(SGChannel c, long frameCount) -> (ComponentResult _rv)")},
+	{"SGGetChannelMaxFrames", (PyCFunction)Qt_SGGetChannelMaxFrames, 1,
+	 PyDoc_STR("(SGChannel c) -> (ComponentResult _rv, long frameCount)")},
+	{"SGSetChannelRefCon", (PyCFunction)Qt_SGSetChannelRefCon, 1,
+	 PyDoc_STR("(SGChannel c, long refCon) -> (ComponentResult _rv)")},
+	{"SGSetChannelClip", (PyCFunction)Qt_SGSetChannelClip, 1,
+	 PyDoc_STR("(SGChannel c, RgnHandle theClip) -> (ComponentResult _rv)")},
+	{"SGGetChannelClip", (PyCFunction)Qt_SGGetChannelClip, 1,
+	 PyDoc_STR("(SGChannel c) -> (ComponentResult _rv, RgnHandle theClip)")},
+	{"SGGetChannelSampleDescription", (PyCFunction)Qt_SGGetChannelSampleDescription, 1,
+	 PyDoc_STR("(SGChannel c, Handle sampleDesc) -> (ComponentResult _rv)")},
+	{"SGSetChannelDevice", (PyCFunction)Qt_SGSetChannelDevice, 1,
+	 PyDoc_STR("(SGChannel c, StringPtr name) -> (ComponentResult _rv)")},
+	{"SGGetChannelTimeScale", (PyCFunction)Qt_SGGetChannelTimeScale, 1,
+	 PyDoc_STR("(SGChannel c) -> (ComponentResult _rv, TimeScale scale)")},
+	{"SGChannelPutPicture", (PyCFunction)Qt_SGChannelPutPicture, 1,
+	 PyDoc_STR("(SGChannel c) -> (ComponentResult _rv)")},
+	{"SGChannelSetRequestedDataRate", (PyCFunction)Qt_SGChannelSetRequestedDataRate, 1,
+	 PyDoc_STR("(SGChannel c, long bytesPerSecond) -> (ComponentResult _rv)")},
+	{"SGChannelGetRequestedDataRate", (PyCFunction)Qt_SGChannelGetRequestedDataRate, 1,
+	 PyDoc_STR("(SGChannel c) -> (ComponentResult _rv, long bytesPerSecond)")},
+	{"SGChannelSetDataSourceName", (PyCFunction)Qt_SGChannelSetDataSourceName, 1,
+	 PyDoc_STR("(SGChannel c, Str255 name, ScriptCode scriptTag) -> (ComponentResult _rv)")},
+	{"SGChannelGetDataSourceName", (PyCFunction)Qt_SGChannelGetDataSourceName, 1,
+	 PyDoc_STR("(SGChannel c, Str255 name) -> (ComponentResult _rv, ScriptCode scriptTag)")},
+	{"SGChannelSetCodecSettings", (PyCFunction)Qt_SGChannelSetCodecSettings, 1,
+	 PyDoc_STR("(SGChannel c, Handle settings) -> (ComponentResult _rv)")},
+	{"SGChannelGetCodecSettings", (PyCFunction)Qt_SGChannelGetCodecSettings, 1,
+	 PyDoc_STR("(SGChannel c) -> (ComponentResult _rv, Handle settings)")},
+	{"SGGetChannelTimeBase", (PyCFunction)Qt_SGGetChannelTimeBase, 1,
+	 PyDoc_STR("(SGChannel c) -> (ComponentResult _rv, TimeBase tb)")},
+	{"SGGetChannelRefCon", (PyCFunction)Qt_SGGetChannelRefCon, 1,
+	 PyDoc_STR("(SGChannel c) -> (ComponentResult _rv, long refCon)")},
+	{"SGGetChannelDeviceAndInputNames", (PyCFunction)Qt_SGGetChannelDeviceAndInputNames, 1,
+	 PyDoc_STR("(SGChannel c, Str255 outDeviceName, Str255 outInputName) -> (ComponentResult _rv, short outInputNumber)")},
+	{"SGSetChannelDeviceInput", (PyCFunction)Qt_SGSetChannelDeviceInput, 1,
+	 PyDoc_STR("(SGChannel c, short inInputNumber) -> (ComponentResult _rv)")},
+	{"SGSetChannelSettingsStateChanging", (PyCFunction)Qt_SGSetChannelSettingsStateChanging, 1,
+	 PyDoc_STR("(SGChannel c, UInt32 inFlags) -> (ComponentResult _rv)")},
+	{"SGInitChannel", (PyCFunction)Qt_SGInitChannel, 1,
+	 PyDoc_STR("(SGChannel c, SeqGrabComponent owner) -> (ComponentResult _rv)")},
+	{"SGWriteSamples", (PyCFunction)Qt_SGWriteSamples, 1,
+	 PyDoc_STR("(SGChannel c, Movie m, AliasHandle theFile) -> (ComponentResult _rv)")},
+	{"SGGetDataRate", (PyCFunction)Qt_SGGetDataRate, 1,
+	 PyDoc_STR("(SGChannel c) -> (ComponentResult _rv, long bytesPerSecond)")},
+	{"SGAlignChannelRect", (PyCFunction)Qt_SGAlignChannelRect, 1,
+	 PyDoc_STR("(SGChannel c) -> (ComponentResult _rv, Rect r)")},
+	{"SGPanelGetDitl", (PyCFunction)Qt_SGPanelGetDitl, 1,
+	 PyDoc_STR("(SeqGrabComponent s) -> (ComponentResult _rv, Handle ditl)")},
+	{"SGPanelGetTitle", (PyCFunction)Qt_SGPanelGetTitle, 1,
+	 PyDoc_STR("(SeqGrabComponent s, Str255 title) -> (ComponentResult _rv)")},
+	{"SGPanelCanRun", (PyCFunction)Qt_SGPanelCanRun, 1,
+	 PyDoc_STR("(SeqGrabComponent s, SGChannel c) -> (ComponentResult _rv)")},
+	{"SGPanelInstall", (PyCFunction)Qt_SGPanelInstall, 1,
+	 PyDoc_STR("(SeqGrabComponent s, SGChannel c, DialogPtr d, short itemOffset) -> (ComponentResult _rv)")},
+	{"SGPanelEvent", (PyCFunction)Qt_SGPanelEvent, 1,
+	 PyDoc_STR("(SeqGrabComponent s, SGChannel c, DialogPtr d, short itemOffset, EventRecord theEvent) -> (ComponentResult _rv, short itemHit, Boolean handled)")},
+	{"SGPanelItem", (PyCFunction)Qt_SGPanelItem, 1,
+	 PyDoc_STR("(SeqGrabComponent s, SGChannel c, DialogPtr d, short itemOffset, short itemNum) -> (ComponentResult _rv)")},
+	{"SGPanelRemove", (PyCFunction)Qt_SGPanelRemove, 1,
+	 PyDoc_STR("(SeqGrabComponent s, SGChannel c, DialogPtr d, short itemOffset) -> (ComponentResult _rv)")},
+	{"SGPanelSetGrabber", (PyCFunction)Qt_SGPanelSetGrabber, 1,
+	 PyDoc_STR("(SeqGrabComponent s, SeqGrabComponent sg) -> (ComponentResult _rv)")},
+	{"SGPanelSetResFile", (PyCFunction)Qt_SGPanelSetResFile, 1,
+	 PyDoc_STR("(SeqGrabComponent s, short resRef) -> (ComponentResult _rv)")},
+	{"SGPanelGetSettings", (PyCFunction)Qt_SGPanelGetSettings, 1,
+	 PyDoc_STR("(SeqGrabComponent s, SGChannel c, long flags) -> (ComponentResult _rv, UserData ud)")},
+	{"SGPanelSetSettings", (PyCFunction)Qt_SGPanelSetSettings, 1,
+	 PyDoc_STR("(SeqGrabComponent s, SGChannel c, UserData ud, long flags) -> (ComponentResult _rv)")},
+	{"SGPanelValidateInput", (PyCFunction)Qt_SGPanelValidateInput, 1,
+	 PyDoc_STR("(SeqGrabComponent s) -> (ComponentResult _rv, Boolean ok)")},
+	{"SGPanelGetDITLForSize", (PyCFunction)Qt_SGPanelGetDITLForSize, 1,
+	 PyDoc_STR("(SeqGrabComponent s) -> (ComponentResult _rv, Handle ditl, Point requestedSize)")},
+	{"SGGetSrcVideoBounds", (PyCFunction)Qt_SGGetSrcVideoBounds, 1,
+	 PyDoc_STR("(SGChannel c) -> (ComponentResult _rv, Rect r)")},
+	{"SGSetVideoRect", (PyCFunction)Qt_SGSetVideoRect, 1,
+	 PyDoc_STR("(SGChannel c, Rect r) -> (ComponentResult _rv)")},
+	{"SGGetVideoRect", (PyCFunction)Qt_SGGetVideoRect, 1,
+	 PyDoc_STR("(SGChannel c) -> (ComponentResult _rv, Rect r)")},
+	{"SGGetVideoCompressorType", (PyCFunction)Qt_SGGetVideoCompressorType, 1,
+	 PyDoc_STR("(SGChannel c) -> (ComponentResult _rv, OSType compressorType)")},
+	{"SGSetVideoCompressorType", (PyCFunction)Qt_SGSetVideoCompressorType, 1,
+	 PyDoc_STR("(SGChannel c, OSType compressorType) -> (ComponentResult _rv)")},
+	{"SGSetVideoCompressor", (PyCFunction)Qt_SGSetVideoCompressor, 1,
+	 PyDoc_STR("(SGChannel c, short depth, CompressorComponent compressor, CodecQ spatialQuality, CodecQ temporalQuality, long keyFrameRate) -> (ComponentResult _rv)")},
+	{"SGGetVideoCompressor", (PyCFunction)Qt_SGGetVideoCompressor, 1,
+	 PyDoc_STR("(SGChannel c) -> (ComponentResult _rv, short depth, CompressorComponent compressor, CodecQ spatialQuality, CodecQ temporalQuality, long keyFrameRate)")},
+	{"SGGetVideoDigitizerComponent", (PyCFunction)Qt_SGGetVideoDigitizerComponent, 1,
+	 PyDoc_STR("(SGChannel c) -> (ComponentInstance _rv)")},
+	{"SGSetVideoDigitizerComponent", (PyCFunction)Qt_SGSetVideoDigitizerComponent, 1,
+	 PyDoc_STR("(SGChannel c, ComponentInstance vdig) -> (ComponentResult _rv)")},
+	{"SGVideoDigitizerChanged", (PyCFunction)Qt_SGVideoDigitizerChanged, 1,
+	 PyDoc_STR("(SGChannel c) -> (ComponentResult _rv)")},
+	{"SGGrabFrame", (PyCFunction)Qt_SGGrabFrame, 1,
+	 PyDoc_STR("(SGChannel c, short bufferNum) -> (ComponentResult _rv)")},
+	{"SGGrabFrameComplete", (PyCFunction)Qt_SGGrabFrameComplete, 1,
+	 PyDoc_STR("(SGChannel c, short bufferNum) -> (ComponentResult _rv, Boolean done)")},
+	{"SGCompressFrame", (PyCFunction)Qt_SGCompressFrame, 1,
+	 PyDoc_STR("(SGChannel c, short bufferNum) -> (ComponentResult _rv)")},
+	{"SGSetCompressBuffer", (PyCFunction)Qt_SGSetCompressBuffer, 1,
+	 PyDoc_STR("(SGChannel c, short depth, Rect compressSize) -> (ComponentResult _rv)")},
+	{"SGGetCompressBuffer", (PyCFunction)Qt_SGGetCompressBuffer, 1,
+	 PyDoc_STR("(SGChannel c) -> (ComponentResult _rv, short depth, Rect compressSize)")},
+	{"SGGetBufferInfo", (PyCFunction)Qt_SGGetBufferInfo, 1,
+	 PyDoc_STR("(SGChannel c, short bufferNum) -> (ComponentResult _rv, PixMapHandle bufferPM, Rect bufferRect, GWorldPtr compressBuffer, Rect compressBufferRect)")},
+	{"SGSetUseScreenBuffer", (PyCFunction)Qt_SGSetUseScreenBuffer, 1,
+	 PyDoc_STR("(SGChannel c, Boolean useScreenBuffer) -> (ComponentResult _rv)")},
+	{"SGGetUseScreenBuffer", (PyCFunction)Qt_SGGetUseScreenBuffer, 1,
+	 PyDoc_STR("(SGChannel c) -> (ComponentResult _rv, Boolean useScreenBuffer)")},
+	{"SGSetFrameRate", (PyCFunction)Qt_SGSetFrameRate, 1,
+	 PyDoc_STR("(SGChannel c, Fixed frameRate) -> (ComponentResult _rv)")},
+	{"SGGetFrameRate", (PyCFunction)Qt_SGGetFrameRate, 1,
+	 PyDoc_STR("(SGChannel c) -> (ComponentResult _rv, Fixed frameRate)")},
+	{"SGSetPreferredPacketSize", (PyCFunction)Qt_SGSetPreferredPacketSize, 1,
+	 PyDoc_STR("(SGChannel c, long preferredPacketSizeInBytes) -> (ComponentResult _rv)")},
+	{"SGGetPreferredPacketSize", (PyCFunction)Qt_SGGetPreferredPacketSize, 1,
+	 PyDoc_STR("(SGChannel c) -> (ComponentResult _rv, long preferredPacketSizeInBytes)")},
+	{"SGSetUserVideoCompressorList", (PyCFunction)Qt_SGSetUserVideoCompressorList, 1,
+	 PyDoc_STR("(SGChannel c, Handle compressorTypes) -> (ComponentResult _rv)")},
+	{"SGGetUserVideoCompressorList", (PyCFunction)Qt_SGGetUserVideoCompressorList, 1,
+	 PyDoc_STR("(SGChannel c) -> (ComponentResult _rv, Handle compressorTypes)")},
+	{"SGSetSoundInputDriver", (PyCFunction)Qt_SGSetSoundInputDriver, 1,
+	 PyDoc_STR("(SGChannel c, Str255 driverName) -> (ComponentResult _rv)")},
+	{"SGGetSoundInputDriver", (PyCFunction)Qt_SGGetSoundInputDriver, 1,
+	 PyDoc_STR("(SGChannel c) -> (long _rv)")},
+	{"SGSoundInputDriverChanged", (PyCFunction)Qt_SGSoundInputDriverChanged, 1,
+	 PyDoc_STR("(SGChannel c) -> (ComponentResult _rv)")},
+	{"SGSetSoundRecordChunkSize", (PyCFunction)Qt_SGSetSoundRecordChunkSize, 1,
+	 PyDoc_STR("(SGChannel c, long seconds) -> (ComponentResult _rv)")},
+	{"SGGetSoundRecordChunkSize", (PyCFunction)Qt_SGGetSoundRecordChunkSize, 1,
+	 PyDoc_STR("(SGChannel c) -> (long _rv)")},
+	{"SGSetSoundInputRate", (PyCFunction)Qt_SGSetSoundInputRate, 1,
+	 PyDoc_STR("(SGChannel c, Fixed rate) -> (ComponentResult _rv)")},
+	{"SGGetSoundInputRate", (PyCFunction)Qt_SGGetSoundInputRate, 1,
+	 PyDoc_STR("(SGChannel c) -> (Fixed _rv)")},
+	{"SGSetSoundInputParameters", (PyCFunction)Qt_SGSetSoundInputParameters, 1,
+	 PyDoc_STR("(SGChannel c, short sampleSize, short numChannels, OSType compressionType) -> (ComponentResult _rv)")},
+	{"SGGetSoundInputParameters", (PyCFunction)Qt_SGGetSoundInputParameters, 1,
+	 PyDoc_STR("(SGChannel c) -> (ComponentResult _rv, short sampleSize, short numChannels, OSType compressionType)")},
+	{"SGSetAdditionalSoundRates", (PyCFunction)Qt_SGSetAdditionalSoundRates, 1,
+	 PyDoc_STR("(SGChannel c, Handle rates) -> (ComponentResult _rv)")},
+	{"SGGetAdditionalSoundRates", (PyCFunction)Qt_SGGetAdditionalSoundRates, 1,
+	 PyDoc_STR("(SGChannel c) -> (ComponentResult _rv, Handle rates)")},
+	{"SGSetFontName", (PyCFunction)Qt_SGSetFontName, 1,
+	 PyDoc_STR("(SGChannel c, StringPtr pstr) -> (ComponentResult _rv)")},
+	{"SGSetFontSize", (PyCFunction)Qt_SGSetFontSize, 1,
+	 PyDoc_STR("(SGChannel c, short fontSize) -> (ComponentResult _rv)")},
+	{"SGSetTextForeColor", (PyCFunction)Qt_SGSetTextForeColor, 1,
+	 PyDoc_STR("(SGChannel c) -> (ComponentResult _rv, RGBColor theColor)")},
+	{"SGSetTextBackColor", (PyCFunction)Qt_SGSetTextBackColor, 1,
+	 PyDoc_STR("(SGChannel c) -> (ComponentResult _rv, RGBColor theColor)")},
+	{"SGSetJustification", (PyCFunction)Qt_SGSetJustification, 1,
+	 PyDoc_STR("(SGChannel c, short just) -> (ComponentResult _rv)")},
+	{"SGGetTextReturnToSpaceValue", (PyCFunction)Qt_SGGetTextReturnToSpaceValue, 1,
+	 PyDoc_STR("(SGChannel c) -> (ComponentResult _rv, short rettospace)")},
+	{"SGSetTextReturnToSpaceValue", (PyCFunction)Qt_SGSetTextReturnToSpaceValue, 1,
+	 PyDoc_STR("(SGChannel c, short rettospace) -> (ComponentResult _rv)")},
+	{"QTVideoOutputGetCurrentClientName", (PyCFunction)Qt_QTVideoOutputGetCurrentClientName, 1,
+	 PyDoc_STR("(QTVideoOutputComponent vo, Str255 str) -> (ComponentResult _rv)")},
+	{"QTVideoOutputSetClientName", (PyCFunction)Qt_QTVideoOutputSetClientName, 1,
+	 PyDoc_STR("(QTVideoOutputComponent vo, Str255 str) -> (ComponentResult _rv)")},
+	{"QTVideoOutputGetClientName", (PyCFunction)Qt_QTVideoOutputGetClientName, 1,
+	 PyDoc_STR("(QTVideoOutputComponent vo, Str255 str) -> (ComponentResult _rv)")},
+	{"QTVideoOutputBegin", (PyCFunction)Qt_QTVideoOutputBegin, 1,
+	 PyDoc_STR("(QTVideoOutputComponent vo) -> (ComponentResult _rv)")},
+	{"QTVideoOutputEnd", (PyCFunction)Qt_QTVideoOutputEnd, 1,
+	 PyDoc_STR("(QTVideoOutputComponent vo) -> (ComponentResult _rv)")},
+	{"QTVideoOutputSetDisplayMode", (PyCFunction)Qt_QTVideoOutputSetDisplayMode, 1,
+	 PyDoc_STR("(QTVideoOutputComponent vo, long displayModeID) -> (ComponentResult _rv)")},
+	{"QTVideoOutputGetDisplayMode", (PyCFunction)Qt_QTVideoOutputGetDisplayMode, 1,
+	 PyDoc_STR("(QTVideoOutputComponent vo) -> (ComponentResult _rv, long displayModeID)")},
+	{"QTVideoOutputGetGWorld", (PyCFunction)Qt_QTVideoOutputGetGWorld, 1,
+	 PyDoc_STR("(QTVideoOutputComponent vo) -> (ComponentResult _rv, GWorldPtr gw)")},
+	{"QTVideoOutputGetIndSoundOutput", (PyCFunction)Qt_QTVideoOutputGetIndSoundOutput, 1,
+	 PyDoc_STR("(QTVideoOutputComponent vo, long index) -> (ComponentResult _rv, Component outputComponent)")},
+	{"QTVideoOutputGetClock", (PyCFunction)Qt_QTVideoOutputGetClock, 1,
+	 PyDoc_STR("(QTVideoOutputComponent vo) -> (ComponentResult _rv, ComponentInstance clock)")},
+	{"QTVideoOutputSetEchoPort", (PyCFunction)Qt_QTVideoOutputSetEchoPort, 1,
+	 PyDoc_STR("(QTVideoOutputComponent vo, CGrafPtr echoPort) -> (ComponentResult _rv)")},
+	{"QTVideoOutputGetIndImageDecompressor", (PyCFunction)Qt_QTVideoOutputGetIndImageDecompressor, 1,
+	 PyDoc_STR("(QTVideoOutputComponent vo, long index) -> (ComponentResult _rv, Component codec)")},
+	{"QTVideoOutputBaseSetEchoPort", (PyCFunction)Qt_QTVideoOutputBaseSetEchoPort, 1,
+	 PyDoc_STR("(QTVideoOutputComponent vo, CGrafPtr echoPort) -> (ComponentResult _rv)")},
+	{"MediaSetChunkManagementFlags", (PyCFunction)Qt_MediaSetChunkManagementFlags, 1,
+	 PyDoc_STR("(MediaHandler mh, UInt32 flags, UInt32 flagsMask) -> (ComponentResult _rv)")},
+	{"MediaGetChunkManagementFlags", (PyCFunction)Qt_MediaGetChunkManagementFlags, 1,
+	 PyDoc_STR("(MediaHandler mh) -> (ComponentResult _rv, UInt32 flags)")},
+	{"MediaSetPurgeableChunkMemoryAllowance", (PyCFunction)Qt_MediaSetPurgeableChunkMemoryAllowance, 1,
+	 PyDoc_STR("(MediaHandler mh, Size allowance) -> (ComponentResult _rv)")},
+	{"MediaGetPurgeableChunkMemoryAllowance", (PyCFunction)Qt_MediaGetPurgeableChunkMemoryAllowance, 1,
+	 PyDoc_STR("(MediaHandler mh) -> (ComponentResult _rv, Size allowance)")},
+	{"MediaEmptyAllPurgeableChunks", (PyCFunction)Qt_MediaEmptyAllPurgeableChunks, 1,
+	 PyDoc_STR("(MediaHandler mh) -> (ComponentResult _rv)")},
+	{"MediaSetHandlerCapabilities", (PyCFunction)Qt_MediaSetHandlerCapabilities, 1,
+	 PyDoc_STR("(MediaHandler mh, long flags, long flagsMask) -> (ComponentResult _rv)")},
+	{"MediaIdle", (PyCFunction)Qt_MediaIdle, 1,
+	 PyDoc_STR("(MediaHandler mh, TimeValue atMediaTime, long flagsIn, TimeRecord movieTime) -> (ComponentResult _rv, long flagsOut)")},
+	{"MediaGetMediaInfo", (PyCFunction)Qt_MediaGetMediaInfo, 1,
+	 PyDoc_STR("(MediaHandler mh, Handle h) -> (ComponentResult _rv)")},
+	{"MediaPutMediaInfo", (PyCFunction)Qt_MediaPutMediaInfo, 1,
+	 PyDoc_STR("(MediaHandler mh, Handle h) -> (ComponentResult _rv)")},
+	{"MediaSetActive", (PyCFunction)Qt_MediaSetActive, 1,
+	 PyDoc_STR("(MediaHandler mh, Boolean enableMedia) -> (ComponentResult _rv)")},
+	{"MediaSetRate", (PyCFunction)Qt_MediaSetRate, 1,
+	 PyDoc_STR("(MediaHandler mh, Fixed rate) -> (ComponentResult _rv)")},
+	{"MediaGGetStatus", (PyCFunction)Qt_MediaGGetStatus, 1,
+	 PyDoc_STR("(MediaHandler mh) -> (ComponentResult _rv, ComponentResult statusErr)")},
+	{"MediaTrackEdited", (PyCFunction)Qt_MediaTrackEdited, 1,
+	 PyDoc_STR("(MediaHandler mh) -> (ComponentResult _rv)")},
+	{"MediaSetMediaTimeScale", (PyCFunction)Qt_MediaSetMediaTimeScale, 1,
+	 PyDoc_STR("(MediaHandler mh, TimeScale newTimeScale) -> (ComponentResult _rv)")},
+	{"MediaSetMovieTimeScale", (PyCFunction)Qt_MediaSetMovieTimeScale, 1,
+	 PyDoc_STR("(MediaHandler mh, TimeScale newTimeScale) -> (ComponentResult _rv)")},
+	{"MediaSetGWorld", (PyCFunction)Qt_MediaSetGWorld, 1,
+	 PyDoc_STR("(MediaHandler mh, CGrafPtr aPort, GDHandle aGD) -> (ComponentResult _rv)")},
+	{"MediaSetDimensions", (PyCFunction)Qt_MediaSetDimensions, 1,
+	 PyDoc_STR("(MediaHandler mh, Fixed width, Fixed height) -> (ComponentResult _rv)")},
+	{"MediaSetClip", (PyCFunction)Qt_MediaSetClip, 1,
+	 PyDoc_STR("(MediaHandler mh, RgnHandle theClip) -> (ComponentResult _rv)")},
+	{"MediaGetTrackOpaque", (PyCFunction)Qt_MediaGetTrackOpaque, 1,
+	 PyDoc_STR("(MediaHandler mh) -> (ComponentResult _rv, Boolean trackIsOpaque)")},
+	{"MediaSetGraphicsMode", (PyCFunction)Qt_MediaSetGraphicsMode, 1,
+	 PyDoc_STR("(MediaHandler mh, long mode, RGBColor opColor) -> (ComponentResult _rv)")},
+	{"MediaGetGraphicsMode", (PyCFunction)Qt_MediaGetGraphicsMode, 1,
+	 PyDoc_STR("(MediaHandler mh) -> (ComponentResult _rv, long mode, RGBColor opColor)")},
+	{"MediaGSetVolume", (PyCFunction)Qt_MediaGSetVolume, 1,
+	 PyDoc_STR("(MediaHandler mh, short volume) -> (ComponentResult _rv)")},
+	{"MediaSetSoundBalance", (PyCFunction)Qt_MediaSetSoundBalance, 1,
+	 PyDoc_STR("(MediaHandler mh, short balance) -> (ComponentResult _rv)")},
+	{"MediaGetSoundBalance", (PyCFunction)Qt_MediaGetSoundBalance, 1,
+	 PyDoc_STR("(MediaHandler mh) -> (ComponentResult _rv, short balance)")},
+	{"MediaGetNextBoundsChange", (PyCFunction)Qt_MediaGetNextBoundsChange, 1,
+	 PyDoc_STR("(MediaHandler mh) -> (ComponentResult _rv, TimeValue when)")},
+	{"MediaGetSrcRgn", (PyCFunction)Qt_MediaGetSrcRgn, 1,
+	 PyDoc_STR("(MediaHandler mh, RgnHandle rgn, TimeValue atMediaTime) -> (ComponentResult _rv)")},
+	{"MediaPreroll", (PyCFunction)Qt_MediaPreroll, 1,
+	 PyDoc_STR("(MediaHandler mh, TimeValue time, Fixed rate) -> (ComponentResult _rv)")},
+	{"MediaSampleDescriptionChanged", (PyCFunction)Qt_MediaSampleDescriptionChanged, 1,
+	 PyDoc_STR("(MediaHandler mh, long index) -> (ComponentResult _rv)")},
+	{"MediaHasCharacteristic", (PyCFunction)Qt_MediaHasCharacteristic, 1,
+	 PyDoc_STR("(MediaHandler mh, OSType characteristic) -> (ComponentResult _rv, Boolean hasIt)")},
+	{"MediaGetOffscreenBufferSize", (PyCFunction)Qt_MediaGetOffscreenBufferSize, 1,
+	 PyDoc_STR("(MediaHandler mh, short depth, CTabHandle ctab) -> (ComponentResult _rv, Rect bounds)")},
+	{"MediaSetHints", (PyCFunction)Qt_MediaSetHints, 1,
+	 PyDoc_STR("(MediaHandler mh, long hints) -> (ComponentResult _rv)")},
+	{"MediaGetName", (PyCFunction)Qt_MediaGetName, 1,
+	 PyDoc_STR("(MediaHandler mh, Str255 name, long requestedLanguage) -> (ComponentResult _rv, long actualLanguage)")},
+	{"MediaForceUpdate", (PyCFunction)Qt_MediaForceUpdate, 1,
+	 PyDoc_STR("(MediaHandler mh, long forceUpdateFlags) -> (ComponentResult _rv)")},
+	{"MediaGetDrawingRgn", (PyCFunction)Qt_MediaGetDrawingRgn, 1,
+	 PyDoc_STR("(MediaHandler mh) -> (ComponentResult _rv, RgnHandle partialRgn)")},
+	{"MediaGSetActiveSegment", (PyCFunction)Qt_MediaGSetActiveSegment, 1,
+	 PyDoc_STR("(MediaHandler mh, TimeValue activeStart, TimeValue activeDuration) -> (ComponentResult _rv)")},
+	{"MediaInvalidateRegion", (PyCFunction)Qt_MediaInvalidateRegion, 1,
+	 PyDoc_STR("(MediaHandler mh, RgnHandle invalRgn) -> (ComponentResult _rv)")},
+	{"MediaGetNextStepTime", (PyCFunction)Qt_MediaGetNextStepTime, 1,
+	 PyDoc_STR("(MediaHandler mh, short flags, TimeValue mediaTimeIn, Fixed rate) -> (ComponentResult _rv, TimeValue mediaTimeOut)")},
+	{"MediaChangedNonPrimarySource", (PyCFunction)Qt_MediaChangedNonPrimarySource, 1,
+	 PyDoc_STR("(MediaHandler mh, long inputIndex) -> (ComponentResult _rv)")},
+	{"MediaTrackReferencesChanged", (PyCFunction)Qt_MediaTrackReferencesChanged, 1,
+	 PyDoc_STR("(MediaHandler mh) -> (ComponentResult _rv)")},
+	{"MediaReleaseSampleDataPointer", (PyCFunction)Qt_MediaReleaseSampleDataPointer, 1,
+	 PyDoc_STR("(MediaHandler mh, long sampleNum) -> (ComponentResult _rv)")},
+	{"MediaTrackPropertyAtomChanged", (PyCFunction)Qt_MediaTrackPropertyAtomChanged, 1,
+	 PyDoc_STR("(MediaHandler mh) -> (ComponentResult _rv)")},
+	{"MediaSetVideoParam", (PyCFunction)Qt_MediaSetVideoParam, 1,
+	 PyDoc_STR("(MediaHandler mh, long whichParam) -> (ComponentResult _rv, unsigned short value)")},
+	{"MediaGetVideoParam", (PyCFunction)Qt_MediaGetVideoParam, 1,
+	 PyDoc_STR("(MediaHandler mh, long whichParam) -> (ComponentResult _rv, unsigned short value)")},
+	{"MediaCompare", (PyCFunction)Qt_MediaCompare, 1,
+	 PyDoc_STR("(MediaHandler mh, Media srcMedia, ComponentInstance srcMediaComponent) -> (ComponentResult _rv, Boolean isOK)")},
+	{"MediaGetClock", (PyCFunction)Qt_MediaGetClock, 1,
+	 PyDoc_STR("(MediaHandler mh) -> (ComponentResult _rv, ComponentInstance clock)")},
+	{"MediaSetSoundOutputComponent", (PyCFunction)Qt_MediaSetSoundOutputComponent, 1,
+	 PyDoc_STR("(MediaHandler mh, Component outputComponent) -> (ComponentResult _rv)")},
+	{"MediaGetSoundOutputComponent", (PyCFunction)Qt_MediaGetSoundOutputComponent, 1,
+	 PyDoc_STR("(MediaHandler mh) -> (ComponentResult _rv, Component outputComponent)")},
+	{"MediaSetSoundLocalizationData", (PyCFunction)Qt_MediaSetSoundLocalizationData, 1,
+	 PyDoc_STR("(MediaHandler mh, Handle data) -> (ComponentResult _rv)")},
+	{"MediaGetInvalidRegion", (PyCFunction)Qt_MediaGetInvalidRegion, 1,
+	 PyDoc_STR("(MediaHandler mh, RgnHandle rgn) -> (ComponentResult _rv)")},
+	{"MediaSampleDescriptionB2N", (PyCFunction)Qt_MediaSampleDescriptionB2N, 1,
+	 PyDoc_STR("(MediaHandler mh, SampleDescriptionHandle sampleDescriptionH) -> (ComponentResult _rv)")},
+	{"MediaSampleDescriptionN2B", (PyCFunction)Qt_MediaSampleDescriptionN2B, 1,
+	 PyDoc_STR("(MediaHandler mh, SampleDescriptionHandle sampleDescriptionH) -> (ComponentResult _rv)")},
+	{"MediaFlushNonPrimarySourceData", (PyCFunction)Qt_MediaFlushNonPrimarySourceData, 1,
+	 PyDoc_STR("(MediaHandler mh, long inputIndex) -> (ComponentResult _rv)")},
+	{"MediaGetURLLink", (PyCFunction)Qt_MediaGetURLLink, 1,
+	 PyDoc_STR("(MediaHandler mh, Point displayWhere) -> (ComponentResult _rv, Handle urlLink)")},
+	{"MediaHitTestForTargetRefCon", (PyCFunction)Qt_MediaHitTestForTargetRefCon, 1,
+	 PyDoc_STR("(MediaHandler mh, long flags, Point loc) -> (ComponentResult _rv, long targetRefCon)")},
+	{"MediaHitTestTargetRefCon", (PyCFunction)Qt_MediaHitTestTargetRefCon, 1,
+	 PyDoc_STR("(MediaHandler mh, long targetRefCon, long flags, Point loc) -> (ComponentResult _rv, Boolean wasHit)")},
+	{"MediaDisposeTargetRefCon", (PyCFunction)Qt_MediaDisposeTargetRefCon, 1,
+	 PyDoc_STR("(MediaHandler mh, long targetRefCon) -> (ComponentResult _rv)")},
+	{"MediaTargetRefConsEqual", (PyCFunction)Qt_MediaTargetRefConsEqual, 1,
+	 PyDoc_STR("(MediaHandler mh, long firstRefCon, long secondRefCon) -> (ComponentResult _rv, Boolean equal)")},
+	{"MediaPrePrerollCancel", (PyCFunction)Qt_MediaPrePrerollCancel, 1,
+	 PyDoc_STR("(MediaHandler mh, void * refcon) -> (ComponentResult _rv)")},
+	{"MediaEnterEmptyEdit", (PyCFunction)Qt_MediaEnterEmptyEdit, 1,
+	 PyDoc_STR("(MediaHandler mh) -> (ComponentResult _rv)")},
+	{"MediaCurrentMediaQueuedData", (PyCFunction)Qt_MediaCurrentMediaQueuedData, 1,
+	 PyDoc_STR("(MediaHandler mh) -> (ComponentResult _rv, long milliSecs)")},
+	{"MediaGetEffectiveVolume", (PyCFunction)Qt_MediaGetEffectiveVolume, 1,
+	 PyDoc_STR("(MediaHandler mh) -> (ComponentResult _rv, short volume)")},
+	{"MediaGetSoundLevelMeteringEnabled", (PyCFunction)Qt_MediaGetSoundLevelMeteringEnabled, 1,
+	 PyDoc_STR("(MediaHandler mh) -> (ComponentResult _rv, Boolean enabled)")},
+	{"MediaSetSoundLevelMeteringEnabled", (PyCFunction)Qt_MediaSetSoundLevelMeteringEnabled, 1,
+	 PyDoc_STR("(MediaHandler mh, Boolean enable) -> (ComponentResult _rv)")},
+	{"MediaGetEffectiveSoundBalance", (PyCFunction)Qt_MediaGetEffectiveSoundBalance, 1,
+	 PyDoc_STR("(MediaHandler mh) -> (ComponentResult _rv, short balance)")},
+	{"MediaSetScreenLock", (PyCFunction)Qt_MediaSetScreenLock, 1,
+	 PyDoc_STR("(MediaHandler mh, Boolean lockIt) -> (ComponentResult _rv)")},
+	{"MediaGetErrorString", (PyCFunction)Qt_MediaGetErrorString, 1,
+	 PyDoc_STR("(MediaHandler mh, ComponentResult theError, Str255 errorString) -> (ComponentResult _rv)")},
+	{"MediaGetSoundEqualizerBandLevels", (PyCFunction)Qt_MediaGetSoundEqualizerBandLevels, 1,
+	 PyDoc_STR("(MediaHandler mh) -> (ComponentResult _rv, UInt8 bandLevels)")},
+	{"MediaDoIdleActions", (PyCFunction)Qt_MediaDoIdleActions, 1,
+	 PyDoc_STR("(MediaHandler mh) -> (ComponentResult _rv)")},
+	{"MediaSetSoundBassAndTreble", (PyCFunction)Qt_MediaSetSoundBassAndTreble, 1,
+	 PyDoc_STR("(MediaHandler mh, short bass, short treble) -> (ComponentResult _rv)")},
+	{"MediaGetSoundBassAndTreble", (PyCFunction)Qt_MediaGetSoundBassAndTreble, 1,
+	 PyDoc_STR("(MediaHandler mh) -> (ComponentResult _rv, short bass, short treble)")},
+	{"MediaTimeBaseChanged", (PyCFunction)Qt_MediaTimeBaseChanged, 1,
+	 PyDoc_STR("(MediaHandler mh) -> (ComponentResult _rv)")},
+	{"MediaMCIsPlayerEvent", (PyCFunction)Qt_MediaMCIsPlayerEvent, 1,
+	 PyDoc_STR("(MediaHandler mh, EventRecord e) -> (ComponentResult _rv, Boolean handledIt)")},
+	{"MediaGetMediaLoadState", (PyCFunction)Qt_MediaGetMediaLoadState, 1,
+	 PyDoc_STR("(MediaHandler mh) -> (ComponentResult _rv, long mediaLoadState)")},
+	{"MediaVideoOutputChanged", (PyCFunction)Qt_MediaVideoOutputChanged, 1,
+	 PyDoc_STR("(MediaHandler mh, ComponentInstance vout) -> (ComponentResult _rv)")},
+	{"MediaEmptySampleCache", (PyCFunction)Qt_MediaEmptySampleCache, 1,
+	 PyDoc_STR("(MediaHandler mh, long sampleNum, long sampleCount) -> (ComponentResult _rv)")},
+	{"MediaGetPublicInfo", (PyCFunction)Qt_MediaGetPublicInfo, 1,
+	 PyDoc_STR("(MediaHandler mh, OSType infoSelector, void * infoDataPtr) -> (ComponentResult _rv, Size ioDataSize)")},
+	{"MediaSetPublicInfo", (PyCFunction)Qt_MediaSetPublicInfo, 1,
+	 PyDoc_STR("(MediaHandler mh, OSType infoSelector, void * infoDataPtr, Size dataSize) -> (ComponentResult _rv)")},
+	{"MediaRefConSetProperty", (PyCFunction)Qt_MediaRefConSetProperty, 1,
+	 PyDoc_STR("(MediaHandler mh, long refCon, long propertyType, void * propertyValue) -> (ComponentResult _rv)")},
+	{"MediaRefConGetProperty", (PyCFunction)Qt_MediaRefConGetProperty, 1,
+	 PyDoc_STR("(MediaHandler mh, long refCon, long propertyType, void * propertyValue) -> (ComponentResult _rv)")},
+	{"MediaNavigateTargetRefCon", (PyCFunction)Qt_MediaNavigateTargetRefCon, 1,
+	 PyDoc_STR("(MediaHandler mh, long navigation) -> (ComponentResult _rv, long refCon)")},
+	{"MediaGGetIdleManager", (PyCFunction)Qt_MediaGGetIdleManager, 1,
+	 PyDoc_STR("(MediaHandler mh) -> (ComponentResult _rv, IdleManager pim)")},
+	{"MediaGSetIdleManager", (PyCFunction)Qt_MediaGSetIdleManager, 1,
+	 PyDoc_STR("(MediaHandler mh, IdleManager im) -> (ComponentResult _rv)")},
+	{"QTMIDIGetMIDIPorts", (PyCFunction)Qt_QTMIDIGetMIDIPorts, 1,
+	 PyDoc_STR("(QTMIDIComponent ci) -> (ComponentResult _rv, QTMIDIPortListHandle inputPorts, QTMIDIPortListHandle outputPorts)")},
+	{"QTMIDIUseSendPort", (PyCFunction)Qt_QTMIDIUseSendPort, 1,
+	 PyDoc_STR("(QTMIDIComponent ci, long portIndex, long inUse) -> (ComponentResult _rv)")},
+	{"QTMIDISendMIDI", (PyCFunction)Qt_QTMIDISendMIDI, 1,
+	 PyDoc_STR("(QTMIDIComponent ci, long portIndex, MusicMIDIPacket mp) -> (ComponentResult _rv)")},
+	{"MusicGetPart", (PyCFunction)Qt_MusicGetPart, 1,
+	 PyDoc_STR("(MusicComponent mc, long part) -> (ComponentResult _rv, long midiChannel, long polyphony)")},
+	{"MusicSetPart", (PyCFunction)Qt_MusicSetPart, 1,
+	 PyDoc_STR("(MusicComponent mc, long part, long midiChannel, long polyphony) -> (ComponentResult _rv)")},
+	{"MusicSetPartInstrumentNumber", (PyCFunction)Qt_MusicSetPartInstrumentNumber, 1,
+	 PyDoc_STR("(MusicComponent mc, long part, long instrumentNumber) -> (ComponentResult _rv)")},
+	{"MusicGetPartInstrumentNumber", (PyCFunction)Qt_MusicGetPartInstrumentNumber, 1,
+	 PyDoc_STR("(MusicComponent mc, long part) -> (ComponentResult _rv)")},
+	{"MusicStorePartInstrument", (PyCFunction)Qt_MusicStorePartInstrument, 1,
+	 PyDoc_STR("(MusicComponent mc, long part, long instrumentNumber) -> (ComponentResult _rv)")},
+	{"MusicGetPartAtomicInstrument", (PyCFunction)Qt_MusicGetPartAtomicInstrument, 1,
+	 PyDoc_STR("(MusicComponent mc, long part, long flags) -> (ComponentResult _rv, AtomicInstrument ai)")},
+	{"MusicSetPartAtomicInstrument", (PyCFunction)Qt_MusicSetPartAtomicInstrument, 1,
+	 PyDoc_STR("(MusicComponent mc, long part, AtomicInstrumentPtr aiP, long flags) -> (ComponentResult _rv)")},
+	{"MusicGetPartKnob", (PyCFunction)Qt_MusicGetPartKnob, 1,
+	 PyDoc_STR("(MusicComponent mc, long part, long knobID) -> (ComponentResult _rv)")},
+	{"MusicSetPartKnob", (PyCFunction)Qt_MusicSetPartKnob, 1,
+	 PyDoc_STR("(MusicComponent mc, long part, long knobID, long knobValue) -> (ComponentResult _rv)")},
+	{"MusicGetKnob", (PyCFunction)Qt_MusicGetKnob, 1,
+	 PyDoc_STR("(MusicComponent mc, long knobID) -> (ComponentResult _rv)")},
+	{"MusicSetKnob", (PyCFunction)Qt_MusicSetKnob, 1,
+	 PyDoc_STR("(MusicComponent mc, long knobID, long knobValue) -> (ComponentResult _rv)")},
+	{"MusicGetPartName", (PyCFunction)Qt_MusicGetPartName, 1,
+	 PyDoc_STR("(MusicComponent mc, long part, StringPtr name) -> (ComponentResult _rv)")},
+	{"MusicSetPartName", (PyCFunction)Qt_MusicSetPartName, 1,
+	 PyDoc_STR("(MusicComponent mc, long part, StringPtr name) -> (ComponentResult _rv)")},
+	{"MusicPlayNote", (PyCFunction)Qt_MusicPlayNote, 1,
+	 PyDoc_STR("(MusicComponent mc, long part, long pitch, long velocity) -> (ComponentResult _rv)")},
+	{"MusicResetPart", (PyCFunction)Qt_MusicResetPart, 1,
+	 PyDoc_STR("(MusicComponent mc, long part) -> (ComponentResult _rv)")},
+	{"MusicSetPartController", (PyCFunction)Qt_MusicSetPartController, 1,
+	 PyDoc_STR("(MusicComponent mc, long part, MusicController controllerNumber, long controllerValue) -> (ComponentResult _rv)")},
+	{"MusicGetPartController", (PyCFunction)Qt_MusicGetPartController, 1,
+	 PyDoc_STR("(MusicComponent mc, long part, MusicController controllerNumber) -> (ComponentResult _rv)")},
+	{"MusicGetInstrumentNames", (PyCFunction)Qt_MusicGetInstrumentNames, 1,
+	 PyDoc_STR("(MusicComponent mc, long modifiableInstruments) -> (ComponentResult _rv, Handle instrumentNames, Handle instrumentCategoryLasts, Handle instrumentCategoryNames)")},
+	{"MusicGetDrumNames", (PyCFunction)Qt_MusicGetDrumNames, 1,
+	 PyDoc_STR("(MusicComponent mc, long modifiableInstruments) -> (ComponentResult _rv, Handle instrumentNumbers, Handle instrumentNames)")},
+	{"MusicGetMasterTune", (PyCFunction)Qt_MusicGetMasterTune, 1,
+	 PyDoc_STR("(MusicComponent mc) -> (ComponentResult _rv)")},
+	{"MusicSetMasterTune", (PyCFunction)Qt_MusicSetMasterTune, 1,
+	 PyDoc_STR("(MusicComponent mc, long masterTune) -> (ComponentResult _rv)")},
+	{"MusicGetDeviceConnection", (PyCFunction)Qt_MusicGetDeviceConnection, 1,
+	 PyDoc_STR("(MusicComponent mc, long index) -> (ComponentResult _rv, long id1, long id2)")},
+	{"MusicUseDeviceConnection", (PyCFunction)Qt_MusicUseDeviceConnection, 1,
+	 PyDoc_STR("(MusicComponent mc, long id1, long id2) -> (ComponentResult _rv)")},
+	{"MusicGetKnobSettingStrings", (PyCFunction)Qt_MusicGetKnobSettingStrings, 1,
+	 PyDoc_STR("(MusicComponent mc, long knobIndex, long isGlobal) -> (ComponentResult _rv, Handle settingsNames, Handle settingsCategoryLasts, Handle settingsCategoryNames)")},
+	{"MusicGetMIDIPorts", (PyCFunction)Qt_MusicGetMIDIPorts, 1,
+	 PyDoc_STR("(MusicComponent mc) -> (ComponentResult _rv, long inputPortCount, long outputPortCount)")},
+	{"MusicSendMIDI", (PyCFunction)Qt_MusicSendMIDI, 1,
+	 PyDoc_STR("(MusicComponent mc, long portIndex, MusicMIDIPacket mp) -> (ComponentResult _rv)")},
+	{"MusicSetOfflineTimeTo", (PyCFunction)Qt_MusicSetOfflineTimeTo, 1,
+	 PyDoc_STR("(MusicComponent mc, long newTimeStamp) -> (ComponentResult _rv)")},
+	{"MusicGetInfoText", (PyCFunction)Qt_MusicGetInfoText, 1,
+	 PyDoc_STR("(MusicComponent mc, long selector) -> (ComponentResult _rv, Handle textH, Handle styleH)")},
+	{"MusicGetInstrumentInfo", (PyCFunction)Qt_MusicGetInstrumentInfo, 1,
+	 PyDoc_STR("(MusicComponent mc, long getInstrumentInfoFlags) -> (ComponentResult _rv, InstrumentInfoListHandle infoListH)")},
+	{"MusicTask", (PyCFunction)Qt_MusicTask, 1,
+	 PyDoc_STR("(MusicComponent mc) -> (ComponentResult _rv)")},
+	{"MusicSetPartInstrumentNumberInterruptSafe", (PyCFunction)Qt_MusicSetPartInstrumentNumberInterruptSafe, 1,
+	 PyDoc_STR("(MusicComponent mc, long part, long instrumentNumber) -> (ComponentResult _rv)")},
+	{"MusicSetPartSoundLocalization", (PyCFunction)Qt_MusicSetPartSoundLocalization, 1,
+	 PyDoc_STR("(MusicComponent mc, long part, Handle data) -> (ComponentResult _rv)")},
+	{"MusicGenericConfigure", (PyCFunction)Qt_MusicGenericConfigure, 1,
+	 PyDoc_STR("(MusicComponent mc, long mode, long flags, long baseResID) -> (ComponentResult _rv)")},
+	{"MusicGenericGetKnobList", (PyCFunction)Qt_MusicGenericGetKnobList, 1,
+	 PyDoc_STR("(MusicComponent mc, long knobType) -> (ComponentResult _rv, GenericKnobDescriptionListHandle gkdlH)")},
+	{"MusicGenericSetResourceNumbers", (PyCFunction)Qt_MusicGenericSetResourceNumbers, 1,
+	 PyDoc_STR("(MusicComponent mc, Handle resourceIDH) -> (ComponentResult _rv)")},
+	{"MusicDerivedMIDISend", (PyCFunction)Qt_MusicDerivedMIDISend, 1,
+	 PyDoc_STR("(MusicComponent mc, MusicMIDIPacket packet) -> (ComponentResult _rv)")},
+	{"MusicDerivedOpenResFile", (PyCFunction)Qt_MusicDerivedOpenResFile, 1,
+	 PyDoc_STR("(MusicComponent mc) -> (ComponentResult _rv)")},
+	{"MusicDerivedCloseResFile", (PyCFunction)Qt_MusicDerivedCloseResFile, 1,
+	 PyDoc_STR("(MusicComponent mc, short resRefNum) -> (ComponentResult _rv)")},
+	{"NAUnregisterMusicDevice", (PyCFunction)Qt_NAUnregisterMusicDevice, 1,
+	 PyDoc_STR("(NoteAllocator na, long index) -> (ComponentResult _rv)")},
+	{"NASaveMusicConfiguration", (PyCFunction)Qt_NASaveMusicConfiguration, 1,
+	 PyDoc_STR("(NoteAllocator na) -> (ComponentResult _rv)")},
+	{"NAGetMIDIPorts", (PyCFunction)Qt_NAGetMIDIPorts, 1,
+	 PyDoc_STR("(NoteAllocator na) -> (ComponentResult _rv, QTMIDIPortListHandle inputPorts, QTMIDIPortListHandle outputPorts)")},
+	{"NATask", (PyCFunction)Qt_NATask, 1,
+	 PyDoc_STR("(NoteAllocator na) -> (ComponentResult _rv)")},
+	{"TuneSetHeader", (PyCFunction)Qt_TuneSetHeader, 1,
+	 PyDoc_STR("(TunePlayer tp, unsigned long * header) -> (ComponentResult _rv)")},
+	{"TuneGetTimeBase", (PyCFunction)Qt_TuneGetTimeBase, 1,
+	 PyDoc_STR("(TunePlayer tp) -> (ComponentResult _rv, TimeBase tb)")},
+	{"TuneSetTimeScale", (PyCFunction)Qt_TuneSetTimeScale, 1,
+	 PyDoc_STR("(TunePlayer tp, TimeScale scale) -> (ComponentResult _rv)")},
+	{"TuneGetTimeScale", (PyCFunction)Qt_TuneGetTimeScale, 1,
+	 PyDoc_STR("(TunePlayer tp) -> (ComponentResult _rv, TimeScale scale)")},
+	{"TuneInstant", (PyCFunction)Qt_TuneInstant, 1,
+	 PyDoc_STR("(TunePlayer tp, unsigned long tunePosition) -> (ComponentResult _rv, unsigned long tune)")},
+	{"TuneStop", (PyCFunction)Qt_TuneStop, 1,
+	 PyDoc_STR("(TunePlayer tp, long stopFlags) -> (ComponentResult _rv)")},
+	{"TuneSetVolume", (PyCFunction)Qt_TuneSetVolume, 1,
+	 PyDoc_STR("(TunePlayer tp, Fixed volume) -> (ComponentResult _rv)")},
+	{"TuneGetVolume", (PyCFunction)Qt_TuneGetVolume, 1,
+	 PyDoc_STR("(TunePlayer tp) -> (ComponentResult _rv)")},
+	{"TunePreroll", (PyCFunction)Qt_TunePreroll, 1,
+	 PyDoc_STR("(TunePlayer tp) -> (ComponentResult _rv)")},
+	{"TuneUnroll", (PyCFunction)Qt_TuneUnroll, 1,
+	 PyDoc_STR("(TunePlayer tp) -> (ComponentResult _rv)")},
+	{"TuneSetPartTranspose", (PyCFunction)Qt_TuneSetPartTranspose, 1,
+	 PyDoc_STR("(TunePlayer tp, unsigned long part, long transpose, long velocityShift) -> (ComponentResult _rv)")},
+	{"TuneGetNoteAllocator", (PyCFunction)Qt_TuneGetNoteAllocator, 1,
+	 PyDoc_STR("(TunePlayer tp) -> (NoteAllocator _rv)")},
+	{"TuneSetSofter", (PyCFunction)Qt_TuneSetSofter, 1,
+	 PyDoc_STR("(TunePlayer tp, long softer) -> (ComponentResult _rv)")},
+	{"TuneTask", (PyCFunction)Qt_TuneTask, 1,
+	 PyDoc_STR("(TunePlayer tp) -> (ComponentResult _rv)")},
+	{"TuneSetBalance", (PyCFunction)Qt_TuneSetBalance, 1,
+	 PyDoc_STR("(TunePlayer tp, long balance) -> (ComponentResult _rv)")},
+	{"TuneSetSoundLocalization", (PyCFunction)Qt_TuneSetSoundLocalization, 1,
+	 PyDoc_STR("(TunePlayer tp, Handle data) -> (ComponentResult _rv)")},
+	{"TuneSetHeaderWithSize", (PyCFunction)Qt_TuneSetHeaderWithSize, 1,
+	 PyDoc_STR("(TunePlayer tp, unsigned long * header, unsigned long size) -> (ComponentResult _rv)")},
+	{"TuneSetPartMix", (PyCFunction)Qt_TuneSetPartMix, 1,
+	 PyDoc_STR("(TunePlayer tp, unsigned long partNumber, long volume, long balance, long mixFlags) -> (ComponentResult _rv)")},
+	{"TuneGetPartMix", (PyCFunction)Qt_TuneGetPartMix, 1,
+	 PyDoc_STR("(TunePlayer tp, unsigned long partNumber) -> (ComponentResult _rv, long volumeOut, long balanceOut, long mixFlagsOut)")},
+	{"AlignWindow", (PyCFunction)Qt_AlignWindow, 1,
+	 PyDoc_STR("(WindowPtr wp, Boolean front) -> None")},
+	{"DragAlignedWindow", (PyCFunction)Qt_DragAlignedWindow, 1,
+	 PyDoc_STR("(WindowPtr wp, Point startPt, Rect boundsRect) -> None")},
+	{"MoviesTask", (PyCFunction)Qt_MoviesTask, 1,
+	 PyDoc_STR("(long maxMilliSecToUse) -> None")},
+	{NULL, NULL, 0}
+};
+
+
+
+
+void init_Qt(void)
+{
+	PyObject *m;
+	PyObject *d;
+
+
+
+	        PyMac_INIT_TOOLBOX_OBJECT_NEW(Track, TrackObj_New);
+	        PyMac_INIT_TOOLBOX_OBJECT_CONVERT(Track, TrackObj_Convert);
+	        PyMac_INIT_TOOLBOX_OBJECT_NEW(Movie, MovieObj_New);
+	        PyMac_INIT_TOOLBOX_OBJECT_CONVERT(Movie, MovieObj_Convert);
+	        PyMac_INIT_TOOLBOX_OBJECT_NEW(MovieController, MovieCtlObj_New);
+	        PyMac_INIT_TOOLBOX_OBJECT_CONVERT(MovieController, MovieCtlObj_Convert);
+	        PyMac_INIT_TOOLBOX_OBJECT_NEW(TimeBase, TimeBaseObj_New);
+	        PyMac_INIT_TOOLBOX_OBJECT_CONVERT(TimeBase, TimeBaseObj_Convert);
+	        PyMac_INIT_TOOLBOX_OBJECT_NEW(UserData, UserDataObj_New);
+	        PyMac_INIT_TOOLBOX_OBJECT_CONVERT(UserData, UserDataObj_Convert);
+	        PyMac_INIT_TOOLBOX_OBJECT_NEW(Media, MediaObj_New);
+	        PyMac_INIT_TOOLBOX_OBJECT_CONVERT(Media, MediaObj_Convert);
+
+
+	m = Py_InitModule("_Qt", Qt_methods);
+	d = PyModule_GetDict(m);
+	Qt_Error = PyMac_GetOSErrException();
+	if (Qt_Error == NULL ||
+	    PyDict_SetItemString(d, "Error", Qt_Error) != 0)
+		return;
+	IdleManager_Type.ob_type = &PyType_Type;
+	if (PyType_Ready(&IdleManager_Type) < 0) return;
+	Py_INCREF(&IdleManager_Type);
+	PyModule_AddObject(m, "IdleManager", (PyObject *)&IdleManager_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&IdleManager_Type);
+	PyModule_AddObject(m, "IdleManagerType", (PyObject *)&IdleManager_Type);
+	MovieController_Type.ob_type = &PyType_Type;
+	if (PyType_Ready(&MovieController_Type) < 0) return;
+	Py_INCREF(&MovieController_Type);
+	PyModule_AddObject(m, "MovieController", (PyObject *)&MovieController_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&MovieController_Type);
+	PyModule_AddObject(m, "MovieControllerType", (PyObject *)&MovieController_Type);
+	TimeBase_Type.ob_type = &PyType_Type;
+	if (PyType_Ready(&TimeBase_Type) < 0) return;
+	Py_INCREF(&TimeBase_Type);
+	PyModule_AddObject(m, "TimeBase", (PyObject *)&TimeBase_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&TimeBase_Type);
+	PyModule_AddObject(m, "TimeBaseType", (PyObject *)&TimeBase_Type);
+	UserData_Type.ob_type = &PyType_Type;
+	if (PyType_Ready(&UserData_Type) < 0) return;
+	Py_INCREF(&UserData_Type);
+	PyModule_AddObject(m, "UserData", (PyObject *)&UserData_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&UserData_Type);
+	PyModule_AddObject(m, "UserDataType", (PyObject *)&UserData_Type);
+	Media_Type.ob_type = &PyType_Type;
+	if (PyType_Ready(&Media_Type) < 0) return;
+	Py_INCREF(&Media_Type);
+	PyModule_AddObject(m, "Media", (PyObject *)&Media_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&Media_Type);
+	PyModule_AddObject(m, "MediaType", (PyObject *)&Media_Type);
+	Track_Type.ob_type = &PyType_Type;
+	if (PyType_Ready(&Track_Type) < 0) return;
+	Py_INCREF(&Track_Type);
+	PyModule_AddObject(m, "Track", (PyObject *)&Track_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&Track_Type);
+	PyModule_AddObject(m, "TrackType", (PyObject *)&Track_Type);
+	Movie_Type.ob_type = &PyType_Type;
+	if (PyType_Ready(&Movie_Type) < 0) return;
+	Py_INCREF(&Movie_Type);
+	PyModule_AddObject(m, "Movie", (PyObject *)&Movie_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&Movie_Type);
+	PyModule_AddObject(m, "MovieType", (PyObject *)&Movie_Type);
+	SGOutput_Type.ob_type = &PyType_Type;
+	if (PyType_Ready(&SGOutput_Type) < 0) return;
+	Py_INCREF(&SGOutput_Type);
+	PyModule_AddObject(m, "SGOutput", (PyObject *)&SGOutput_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&SGOutput_Type);
+	PyModule_AddObject(m, "SGOutputType", (PyObject *)&SGOutput_Type);
+}
+
+/* ========================= End module _Qt ========================= */
+

Added: vendor/Python/current/Mac/Modules/qt/qtscan.py
===================================================================
--- vendor/Python/current/Mac/Modules/qt/qtscan.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/qt/qtscan.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,319 @@
+# Scan an Apple header file, generating a Python file of generator calls.
+
+import sys
+import os
+from bgenlocations import TOOLBOXDIR, BGENDIR
+sys.path.append(BGENDIR)
+from scantools import Scanner
+
+LONG = "QuickTime"
+SHORT = "qt"
+HEADERFILES= (
+#       "Components.h"  -- In Carbon.Cm
+        "Movies.h",
+        "ImageCompression.h",
+        "QuickTimeComponents.h",
+#       "ImageCodec.h"  -- seems not too useful, and difficult.
+#       "IsochronousDataHandlers.h" -- Is this useful?
+        "MediaHandlers.h",
+#       "QTML.h", -- Windows only, needs separate module
+#       "QuickTimeStreaming.h", -- Difficult
+#       "QTStreamingComponents.h", -- Needs QTStreaming
+        "QuickTimeMusic.h",
+#       "QuickTimeVR.h", -- Not done yet
+#       "Sound.h", -- In Carbon.Snd
+        )
+OBJECTS = ("Movie", "Track", "Media", "UserData", "TimeBase", "MovieController",
+        "IdleManager", "SGOutput")
+
+def main():
+    input = HEADERFILES
+    output = SHORT + "gen.py"
+    defsoutput = TOOLBOXDIR + LONG + ".py"
+    scanner = MyScanner(input, output, defsoutput)
+    scanner.scan()
+    scanner.close()
+    scanner.gentypetest(SHORT+"typetest.py")
+    print "=== Testing definitions output code ==="
+    execfile(defsoutput, {}, {})
+    print "=== Done scanning and generating, now importing the generated code... ==="
+    exec "import " + SHORT + "support"
+    print "=== Done.  It's up to you to compile it now! ==="
+
+class MyScanner(Scanner):
+
+    def destination(self, type, name, arglist):
+        classname = "Function"
+        listname = "functions"
+        if arglist:
+            t, n, m = arglist[0]
+            if t in OBJECTS and m == "InMode":
+                classname = "Method"
+                listname = t + "_methods"
+        return classname, listname
+
+    def writeinitialdefs(self):
+        self.defsfile.write("def FOUR_CHAR_CODE(x): return x\n")
+        self.defsfile.write("xmlIdentifierUnrecognized = -1\n")
+        self.defsfile.write("kControllerMinimum = -0xf777\n")
+        self.defsfile.write("notImplementedMusicOSErr      = -2071\n")
+        self.defsfile.write("cantSendToSynthesizerOSErr    = -2072\n")
+        self.defsfile.write("cantReceiveFromSynthesizerOSErr = -2073\n")
+        self.defsfile.write("illegalVoiceAllocationOSErr   = -2074\n")
+        self.defsfile.write("illegalPartOSErr              = -2075\n")
+        self.defsfile.write("illegalChannelOSErr           = -2076\n")
+        self.defsfile.write("illegalKnobOSErr              = -2077\n")
+        self.defsfile.write("illegalKnobValueOSErr         = -2078\n")
+        self.defsfile.write("illegalInstrumentOSErr        = -2079\n")
+        self.defsfile.write("illegalControllerOSErr        = -2080\n")
+        self.defsfile.write("midiManagerAbsentOSErr        = -2081\n")
+        self.defsfile.write("synthesizerNotRespondingOSErr = -2082\n")
+        self.defsfile.write("synthesizerOSErr              = -2083\n")
+        self.defsfile.write("illegalNoteChannelOSErr       = -2084\n")
+        self.defsfile.write("noteChannelNotAllocatedOSErr  = -2085\n")
+        self.defsfile.write("tunePlayerFullOSErr           = -2086\n")
+        self.defsfile.write("tuneParseOSErr                = -2087\n")
+
+    def makeblacklistnames(self):
+        return [
+                "xmlIdentifierUnrecognized", # const with incompatible definition
+                "DisposeMovie",         # Done on python-object disposal
+                "DisposeMovieTrack",    # ditto
+                "DisposeTrackMedia",    # ditto
+                "DisposeUserData",              # ditto
+#                       "DisposeTimeBase",              # ditto
+                "DisposeMovieController", # ditto
+
+                # The following 4 use 'void *' in an uncontrolled way
+                # TBD when I've read the manual...
+                "GetUserDataItem",
+                "SetUserDataItem",
+                "SetTextSampleData",
+                "BeginFullScreen",
+                # bgen gets the argument in/out wrong..
+                "AddTextSample",
+                "AddTESample",
+                "AddHiliteSample",
+                "HiliteTextSample",
+
+                "MakeTrackTimeTable", # Uses long * return?
+                "MakeMediaTimeTable", # ditto
+##                      "VideoMediaGetStallCount", # Undefined in CW Pro 3 library
+                # OS8 only:
+                'SpriteMediaGetIndImageProperty',       # XXXX Why isn't this in carbon?
+                'CheckQuickTimeRegistration',
+                'SetMovieAnchorDataRef',
+                'GetMovieAnchorDataRef',
+                'GetMovieLoadState',
+                'OpenADataHandler',
+                'MovieMediaGetCurrentMovieProperty',
+                'MovieMediaGetCurrentTrackProperty',
+                'MovieMediaGetChildMovieDataReference',
+                'MovieMediaSetChildMovieDataReference',
+                'MovieMediaLoadChildMovieFromDataReference',
+                'Media3DGetViewObject',
+
+    # these are ImageCompression blacklists
+                "GraphicsExportGetInputPtr",
+
+                # QuickTimeComponents
+                # These two need some help: the first returns a point to a databuffer that
+                # the second disposes. Generate manually?
+                "VDCompressDone",
+                "VDReleaseCompressBuffer",
+                "QTVideoOutputGetGWorldParameters", # How useful is this?
+
+                # MediaHandlers
+                "MediaMakeMediaTimeTable", # just lazy
+                "MediaGetSampleDataPointer", # funny output pointer
+
+                # QuickTimeMusic
+                "kControllerMinimum",
+                # These are artefacts of a macro definition
+                "ulen",
+                "_ext",
+                "x",
+                "w1",
+                "w2",
+                ]
+
+    def makeblacklisttypes(self):
+        return [
+                # I don't think we want to do these
+                "QTSyncTaskPtr",
+                # We dont do callbacks yet, so no need for these
+                "QTCallBack",
+                # Skipped for now, due to laziness
+                "TrackEditState",
+                "MovieEditState",
+                "MatrixRecord",
+                "MatrixRecord_ptr",
+                "SampleReferencePtr",
+                "QTTweener",
+                "QTErrorReplacementPtr",
+                "QTRestrictionSet",
+                "QTUUID",
+                "QTUUID_ptr",
+
+                # Routine pointers, not yet.
+                "MoviesErrorUPP",
+                "MoviePreviewCallOutUPP",
+                "MovieDrawingCompleteUPP",
+                "QTCallBackUPP",
+                "TextMediaUPP",
+                "MovieProgressUPP",
+                "MovieRgnCoverUPP",
+                "MCActionFilterUPP",
+                "MCActionFilterWithRefConUPP",
+                "GetMovieUPP",
+                "ModalFilterUPP",
+                "TrackTransferUPP",
+                "MoviePrePrerollCompleteUPP",
+                "MovieExecuteWiredActionsUPP",
+                "QTBandwidthNotificationUPP",
+                "DoMCActionUPP",
+                "QTNextTaskNeededSoonerCallbackUPP",
+
+                "SampleReference64Ptr", # Don't know what this does, yet
+                "QTRuntimeSpriteDescPtr",
+                "QTBandwidthReference",
+                "QTScheduledBandwidthReference",
+                "QTAtomContainer",
+                "SpriteWorld",
+                "Sprite",
+
+    # these are ImageCompression blacklists
+    "ICMDataUPP",
+    "ICMFlushUPP",
+    "ICMCompletionUPP",
+    "ICMProgressUPP",
+    "StdPixUPP",
+    "QDPixUPP",
+    "ICMAlignmentUPP",
+    "ICMCursorShieldedUPP",
+    "ICMMemoryDisposedUPP",
+    "ICMConvertDataFormatUPP",
+    "ModalFilterYDUPP",
+                "FileFilterUPP",
+
+    "CodecNameSpecListPtr",
+    "CodecInfo",
+     "ImageSequence",
+    "MatrixRecordPtr",
+    "ICMDataProcRecordPtr",
+    "OpenCPicParams",
+    "ICMProgressProcRecordPtr",
+    "ICMAlignmentProcRecordPtr",
+    "ICMPixelFormatInfoPtr",
+    "ImageSequenceDataSource",
+    "ConstStrFileNameParam",
+    "ImageTranscodeSequence",
+    "ImageFieldSequence",
+    "Fract",
+    "PixMapPtr",
+    "GWorldFlags",
+    "void_ptr",   # XXX Being lazy, this one is doable.
+
+    # These are from QuickTimeComponents
+    "CDataHandlerUPP",
+    "CharDataHandlerUPP",
+    "CommentHandlerUPP",
+    "DataHCompletionUPP",
+    "'MovieExportGetDataUPP",
+    "MovieExportGetPropertyUPP",
+    "PreprocessInstructionHandlerUPP",
+    "SGModalFilterUPP",
+    "StartDocumentHandlerUPP",
+    "StartElementHandlerUPP",
+    "VdigIntUPP",
+    "SGDataUPP",
+    "EndDocumentHandlerUPP",
+    "EndElementHandlerUPP",
+    "VideoBottles", # Record full of UPPs
+
+    "SCParams",
+    "ICMCompletionProcRecordPtr",
+    "DataHVolumeList",
+    "DigitizerInfo",
+    "SGCompressInfo",
+    "SeqGrabExtendedFrameInfoPtr",
+    "SeqGrabFrameInfoPtr",
+    "TCTextOptionsPtr",
+    "SGCompressInfo_ptr",
+    "SGDeviceList",
+    "TextDisplayData",
+    "TimeCodeDef",
+    "TimeCodeRecord",
+    "TweenRecord",
+    "VDGamRecPtr",
+    "ToneDescription",  # XXXX Just lazy: this one is easy.
+    "XMLDoc",
+    "UInt64",   # XXXX lazy
+    "UInt64_ptr", # XXXX lazy
+
+    # From MediaHandlers
+    "ActionsUPP",
+    "PrePrerollCompleteUPP",
+    "CodecComponentHandle", # Difficult: handle containing list of components.
+    "GetMovieCompleteParams", # Immense struct
+    "LevelMeterInfoPtr", # Lazy. Also: can be an output parameter!!
+    "MediaEQSpectrumBandsRecordPtr", # ditto
+
+    # From QuickTimeMusic
+    "MusicMIDISendUPP",
+    "MusicOfflineDataUPP",
+    "TuneCallBackUPP",
+    "TunePlayCallBackUPP",
+    "GCPart", # Struct with lots of fields
+    "GCPart_ptr",
+    "GenericKnobDescription", # Struct with lots of fields
+    "KnobDescription",  # Struct with lots of fields
+    "InstrumentAboutInfo", # Struct, not too difficult
+    "NoteChannel", # XXXX Lazy. Could be opaque, I think
+    "NoteRequest", # XXXX Lazy. Not-too-difficult struct
+    "SynthesizerConnections", # Struct with lots of fields
+    "SynthesizerDescription", # Struct with lots of fields
+    "TuneStatus", # Struct with lots of fields
+
+                ]
+
+    def makerepairinstructions(self):
+        return [
+                ([('FSSpec', '*', 'OutMode')], [('FSSpec_ptr', '*', 'InMode')]),
+
+                # Movie controller creation
+                ([('ComponentInstance', 'NewMovieController', 'ReturnMode')],
+                 [('MovieController', '*', 'ReturnMode')]),
+
+                # NewMovieFromFile
+                ([('short', 'resId', 'OutMode'), ('StringPtr', 'resName', 'InMode')],
+                 [('short', 'resId', 'InOutMode'), ('dummyStringPtr', 'resName', 'InMode')]),
+
+                # MCDoAction and more
+                ([('void', '*', 'OutMode')], [('mcactionparams', '*', 'InMode')]),
+
+                # SetTimeBaseZero. Does not handle NULLs, unfortunately
+                ([('TimeRecord', 'zero', 'OutMode')], [('TimeRecord', 'zero', 'InMode')]),
+
+                # ConvertTime and ConvertTimeScale
+                ([('TimeRecord', 'inout', 'OutMode')], [('TimeRecord', 'inout', 'InOutMode')]),
+                ([('TimeRecord', 'theTime', 'OutMode')], [('TimeRecord', 'theTime', 'InOutMode')]),
+
+                # AddTime and SubtractTime
+                ([('TimeRecord', 'dst', 'OutMode')], [('TimeRecord', 'dst', 'InOutMode')]),
+
+                # Funny definitions
+                ([('char_ptr', '*', 'InMode')], [('stringptr', '*', 'InMode')]),
+                ([('FSSpecPtr', '*', 'InMode')], [('FSSpec_ptr', '*', 'InMode')]),
+                ([('unsigned_char', 'swfVersion', 'OutMode')], [('UInt8', 'swfVersion', 'OutMode')]),
+
+                # It seems MusicMIDIPacket if never flagged with const but always used
+                # for sending only. If that ever changes this needs to be fixed.
+                ([('MusicMIDIPacket', '*', 'OutMode')], [('MusicMIDIPacket_ptr', '*', 'InMode')]),
+
+                # QTMusic const-less input parameters
+                ([('unsigned_long', 'header', 'OutMode')], [('UnsignedLongPtr', 'header', 'InMode')]),
+                ]
+
+if __name__ == "__main__":
+    main()

Added: vendor/Python/current/Mac/Modules/qt/qtsupport.py
===================================================================
--- vendor/Python/current/Mac/Modules/qt/qtsupport.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/qt/qtsupport.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,379 @@
+# This script generates a Python interface for an Apple Macintosh Manager.
+# It uses the "bgen" package to generate C code.
+# The function specifications are generated by scanning the mamager's header file,
+# using the "scantools" package (customized for this particular manager).
+
+#error missing SetActionFilter
+
+import string
+
+# Declarations that change for each manager
+MACHEADERFILE = 'Movies.h'              # The Apple header file
+MODNAME = '_Qt'                         # The name of the module
+OBJECTNAME = 'Movie'                    # The basic name of the objects used here
+
+# The following is *usually* unchanged but may still require tuning
+MODPREFIX = 'Qt'                        # The prefix for module-wide routines
+OBJECTTYPE = "Movie"            # The C type used to represent them
+OBJECTPREFIX = MODPREFIX + 'Obj'        # The prefix for object methods
+INPUTFILE = string.lower(MODPREFIX) + 'gen.py' # The file generated by the scanner
+OUTPUTFILE = MODNAME + "module.c"       # The file generated by this program
+
+from macsupport import *
+
+# Create the type objects
+
+includestuff = includestuff + """
+#include <QuickTime/QuickTime.h>
+
+
+#ifdef USE_TOOLBOX_OBJECT_GLUE
+extern PyObject *_TrackObj_New(Track);
+extern int _TrackObj_Convert(PyObject *, Track *);
+extern PyObject *_MovieObj_New(Movie);
+extern int _MovieObj_Convert(PyObject *, Movie *);
+extern PyObject *_MovieCtlObj_New(MovieController);
+extern int _MovieCtlObj_Convert(PyObject *, MovieController *);
+extern PyObject *_TimeBaseObj_New(TimeBase);
+extern int _TimeBaseObj_Convert(PyObject *, TimeBase *);
+extern PyObject *_UserDataObj_New(UserData);
+extern int _UserDataObj_Convert(PyObject *, UserData *);
+extern PyObject *_MediaObj_New(Media);
+extern int _MediaObj_Convert(PyObject *, Media *);
+
+#define TrackObj_New _TrackObj_New
+#define TrackObj_Convert _TrackObj_Convert
+#define MovieObj_New _MovieObj_New
+#define MovieObj_Convert _MovieObj_Convert
+#define MovieCtlObj_New _MovieCtlObj_New
+#define MovieCtlObj_Convert _MovieCtlObj_Convert
+#define TimeBaseObj_New _TimeBaseObj_New
+#define TimeBaseObj_Convert _TimeBaseObj_Convert
+#define UserDataObj_New _UserDataObj_New
+#define UserDataObj_Convert _UserDataObj_Convert
+#define MediaObj_New _MediaObj_New
+#define MediaObj_Convert _MediaObj_Convert
+#endif
+
+/* Macro to allow us to GetNextInterestingTime without duration */
+#define GetMediaNextInterestingTimeOnly(media, flags, time, rate, rv) \
+                        GetMediaNextInterestingTime(media, flags, time, rate, rv, NULL)
+
+/*
+** Parse/generate time records
+*/
+static PyObject *
+QtTimeRecord_New(TimeRecord *itself)
+{
+        if (itself->base)
+                return Py_BuildValue("O&lO&", PyMac_Buildwide, &itself->value, itself->scale,
+                        TimeBaseObj_New, itself->base);
+        else
+                return  Py_BuildValue("O&lO", PyMac_Buildwide, &itself->value, itself->scale,
+                        Py_None);
+}
+
+static int
+QtTimeRecord_Convert(PyObject *v, TimeRecord *p_itself)
+{
+        PyObject *base = NULL;
+        if( !PyArg_ParseTuple(v, "O&l|O", PyMac_Getwide, &p_itself->value, &p_itself->scale,
+                        &base) )
+                return 0;
+        if ( base == NULL || base == Py_None )
+                p_itself->base = NULL;
+        else
+                if ( !TimeBaseObj_Convert(base, &p_itself->base) )
+                        return 0;
+        return 1;
+}
+
+static int
+QtMusicMIDIPacket_Convert(PyObject *v, MusicMIDIPacket *p_itself)
+{
+        int dummy;
+
+        if( !PyArg_ParseTuple(v, "hls#", &p_itself->length, &p_itself->reserved, p_itself->data, dummy) )
+                return 0;
+        return 1;
+}
+
+
+
+"""
+
+initstuff = initstuff + """
+        PyMac_INIT_TOOLBOX_OBJECT_NEW(Track, TrackObj_New);
+        PyMac_INIT_TOOLBOX_OBJECT_CONVERT(Track, TrackObj_Convert);
+        PyMac_INIT_TOOLBOX_OBJECT_NEW(Movie, MovieObj_New);
+        PyMac_INIT_TOOLBOX_OBJECT_CONVERT(Movie, MovieObj_Convert);
+        PyMac_INIT_TOOLBOX_OBJECT_NEW(MovieController, MovieCtlObj_New);
+        PyMac_INIT_TOOLBOX_OBJECT_CONVERT(MovieController, MovieCtlObj_Convert);
+        PyMac_INIT_TOOLBOX_OBJECT_NEW(TimeBase, TimeBaseObj_New);
+        PyMac_INIT_TOOLBOX_OBJECT_CONVERT(TimeBase, TimeBaseObj_Convert);
+        PyMac_INIT_TOOLBOX_OBJECT_NEW(UserData, UserDataObj_New);
+        PyMac_INIT_TOOLBOX_OBJECT_CONVERT(UserData, UserDataObj_Convert);
+        PyMac_INIT_TOOLBOX_OBJECT_NEW(Media, MediaObj_New);
+        PyMac_INIT_TOOLBOX_OBJECT_CONVERT(Media, MediaObj_Convert);
+"""
+
+# Our (opaque) objects
+Movie = OpaqueByValueType('Movie', 'MovieObj')
+NullMovie = FakeType("(Movie)0")
+Track = OpaqueByValueType('Track', 'TrackObj')
+Media = OpaqueByValueType('Media', 'MediaObj')
+UserData = OpaqueByValueType('UserData', 'UserDataObj')
+TimeBase = OpaqueByValueType('TimeBase', 'TimeBaseObj')
+MovieController = OpaqueByValueType('MovieController', 'MovieCtlObj')
+IdleManager = OpaqueByValueType('IdleManager', 'IdleManagerObj')
+SGOutput = OpaqueByValueType('SGOutput', 'SGOutputObj')
+
+# Other opaque objects
+Component = OpaqueByValueType('Component', 'CmpObj')
+MediaHandlerComponent = OpaqueByValueType('MediaHandlerComponent', 'CmpObj')
+DataHandlerComponent = OpaqueByValueType('DataHandlerComponent', 'CmpObj')
+CompressorComponent = OpaqueByValueType('CompressorComponent', 'CmpObj')
+DecompressorComponent = OpaqueByValueType('DecompressorComponent', 'CmpObj')
+CodecComponent = OpaqueByValueType('CodecComponent', 'CmpObj')
+GraphicsImportComponent = OpaqueByValueType('GraphicsImportComponent', 'CmpObj')
+GraphicsExportComponent = OpaqueByValueType('GraphicsExportComponent', 'CmpObj')
+ImageTranscoderComponent = OpaqueByValueType('ImageTranscoderComponent', 'CmpObj')
+DataCodecComponent = OpaqueByValueType('DataCodecComponent', 'CmpObj')
+GraphicImageMovieImportComponent = OpaqueByValueType('GraphicImageMovieImportComponent', 'CmpObj')
+MovieExportComponent = OpaqueByValueType('MovieExportComponent', 'CmpObj')
+MovieImportComponent = OpaqueByValueType('MovieImportComponent', 'CmpObj')
+QTVideoOutputComponent = OpaqueByValueType('QTVideoOutputComponent', 'CmpObj')
+SeqGrabComponent = OpaqueByValueType('SeqGrabComponent', 'CmpObj')
+TextExportComponent = OpaqueByValueType('TextExportComponent', 'CmpObj')
+TweenerComponent = OpaqueByValueType('TweenerComponent', 'CmpObj')
+pnotComponent = OpaqueByValueType('pnotComponent', 'CmpObj')
+VideoDigitizerComponent = OpaqueByValueType('VideoDigitizerComponent', 'CmpObj')
+
+ComponentInstance = OpaqueByValueType('ComponentInstance', 'CmpInstObj')
+MediaHandler = OpaqueByValueType('MediaHandler', 'CmpInstObj')
+DataHandler = OpaqueByValueType('DataHandler', 'CmpInstObj')
+SGChannel = OpaqueByValueType('SGChannel', 'CmpInstObj')
+TunePlayer = OpaqueByValueType('TunePlayer', 'CmpInstObj')
+MusicComponent = OpaqueByValueType('MusicComponent', 'CmpInstObj')
+NoteAllocator = OpaqueByValueType('NoteAllocator', 'CmpInstObj')
+QTMIDIComponent = OpaqueByValueType('QTMIDIComponent', 'CmpInstObj')
+
+ConstFSSpecPtr = FSSpec_ptr
+GrafPtr = OpaqueByValueType("GrafPtr", "GrafObj")
+Byte = Boolean # XXXX For GetPaused and SetPaused
+
+RgnHandle = OpaqueByValueType("RgnHandle", "ResObj")
+PicHandle = OpaqueByValueType("PicHandle", "ResObj")
+CTabHandle = OpaqueByValueType("CTabHandle", "ResObj")
+PixMapHandle = OpaqueByValueType("PixMapHandle", "ResObj")
+SampleDescriptionHandle = OpaqueByValueType("SampleDescriptionHandle", "ResObj")
+ImageDescriptionHandle = OpaqueByValueType("ImageDescriptionHandle", "ResObj")
+TextDescriptionHandle = OpaqueByValueType("TextDescriptionHandle", "ResObj")
+TEHandle = OpaqueByValueType("TEHandle", "ResObj")
+CGrafPtr = OpaqueByValueType("CGrafPtr", "GrafObj")
+GDHandle = OpaqueByValueType("GDHandle", "OptResObj")
+AliasHandle = OpaqueByValueType("AliasHandle", "ResObj")
+SoundDescriptionHandle = OpaqueByValueType("SoundDescriptionHandle", "ResObj")
+VdigBufferRecListHandle = OpaqueByValueType("VdigBufferRecListHandle", "ResObj")
+VDCompressionListHandle = OpaqueByValueType("VDCompressionListHandle", "ResObj")
+TimeCodeDescriptionHandle = OpaqueByValueType("TimeCodeDescriptionHandle", "ResObj")
+DataHFileTypeOrderingHandle = OpaqueByValueType("DataHFileTypeOrderingHandle", "ResObj")
+QTMIDIPortListHandle = OpaqueByValueType("QTMIDIPortListHandle", "ResObj")
+GenericKnobDescriptionListHandle =  OpaqueByValueType("GenericKnobDescriptionListHandle", "ResObj")
+InstrumentInfoListHandle = OpaqueByValueType("InstrumentInfoListHandle", "ResObj")
+# Silly Apple, passing an OStype by reference...
+OSType_ptr = OpaqueType("OSType", "PyMac_BuildOSType", "PyMac_GetOSType")
+# And even sillier: passing floats by address
+float_ptr = ByAddressType("float", "f")
+
+RGBColor = OpaqueType("RGBColor", "QdRGB")
+RGBColor_ptr = RGBColor
+TimeRecord = OpaqueType("TimeRecord", "QtTimeRecord")
+TimeRecord_ptr = TimeRecord
+MusicMIDIPacket = OpaqueType("MusicMIDIPacket", "QtMusicMIDIPacket")
+MusicMIDIPacket_ptr = MusicMIDIPacket
+
+# Non-opaque types, mostly integer-ish
+TimeValue = Type("TimeValue", "l")
+TimeScale = Type("TimeScale", "l")
+TimeBaseFlags = Type("TimeBaseFlags", "l")
+QTCallBackFlags = Type("QTCallBackFlags", "H")
+TimeBaseStatus = Type("TimeBaseStatus", "l")
+QTCallBackType = Type("QTCallBackType", "H")
+nextTimeFlagsEnum = Type("nextTimeFlagsEnum", "H")
+createMovieFileFlagsEnum = Type("createMovieFileFlagsEnum", "l")
+movieFlattenFlagsEnum = Type("movieFlattenFlagsEnum", "l")
+dataRefAttributesFlags = Type("dataRefAttributesFlags", "l")
+playHintsEnum = Type("playHintsEnum", "l")
+mediaHandlerFlagsEnum = Type("mediaHandlerFlagsEnum", "l")
+ComponentResult = Type("ComponentResult", "l")
+VideoDigitizerError = Type("ComponentResult", "l")
+HandlerError = Type("HandlerError", "l")
+Ptr = InputOnlyType("Ptr", "s")
+StringPtr = Type("StringPtr", "s")
+UnsignedLongPtr = Type("unsigned long *", "s")
+mcactionparams = InputOnlyType("void *", "s")
+QTParameterDialog = Type("QTParameterDialog", "l")
+QTAtomID = Type("QTAtomID", "l")
+MCInterfaceElement = Type("MCInterfaceElement", "l")
+CodecType = OSTypeType("CodecType")
+GWorldPtr = OpaqueByValueType("GWorldPtr", "GWorldObj")
+QTFloatSingle = Type("QTFloatSingle", "f")
+CodecQ = Type("CodecQ", "l")
+MusicController = Type("MusicController", "l")
+
+# Could-not-be-bothered-types (NewMovieFromFile)
+dummyshortptr = FakeType('(short *)0')
+dummyStringPtr = FakeType('(StringPtr)0')
+
+# Not-quite-sure-this-is-okay types
+AtomicInstrument = OpaqueByValueType("AtomicInstrument", "ResObj")
+AtomicInstrumentPtr = InputOnlyType("AtomicInstrumentPtr", "s")
+
+# XXXX Need to override output_tp_newBody() to allow for None initializer.
+class QtGlobalObjectDefinition(PEP253Mixin, GlobalObjectDefinition):
+    def outputCheckNewArg(self):
+        # We don't allow NULL pointers to be returned by QuickTime API calls,
+        # in stead we raise an exception
+        Output("""if (itself == NULL) {
+                                PyErr_SetString(Qt_Error,"Cannot create %s from NULL pointer");
+                                return NULL;
+                        }""", self.name)
+
+    def outputCheckConvertArg(self):
+        # But what we do allow is passing None whereever a quicktime object is
+        # expected, and pass this as NULL to the API routines. Note you can
+        # call methods too by creating an object with None as the initializer.
+        Output("if (v == Py_None)")
+        OutLbrace()
+        Output("*p_itself = NULL;")
+        Output("return 1;")
+        OutRbrace()
+
+class MovieObjectDefinition(QtGlobalObjectDefinition):
+    def outputFreeIt(self, itselfname):
+        Output("if (%s) DisposeMovie(%s);", itselfname, itselfname)
+
+class TrackObjectDefinition(QtGlobalObjectDefinition):
+    def outputFreeIt(self, itselfname):
+        Output("if (%s) DisposeMovieTrack(%s);", itselfname, itselfname)
+
+class MediaObjectDefinition(QtGlobalObjectDefinition):
+    def outputFreeIt(self, itselfname):
+        Output("if (%s) DisposeTrackMedia(%s);", itselfname, itselfname)
+
+class UserDataObjectDefinition(QtGlobalObjectDefinition):
+    def outputFreeIt(self, itselfname):
+        Output("if (%s) DisposeUserData(%s);", itselfname, itselfname)
+
+class TimeBaseObjectDefinition(QtGlobalObjectDefinition):
+    pass
+
+class MovieCtlObjectDefinition(QtGlobalObjectDefinition):
+    def outputFreeIt(self, itselfname):
+        Output("if (%s) DisposeMovieController(%s);", itselfname, itselfname)
+
+class IdleManagerObjectDefinition(QtGlobalObjectDefinition):
+    pass
+
+class SGOutputObjectDefinition(QtGlobalObjectDefinition):
+    # XXXX I'm not sure I fully understand how SGOutput works. It seems it's always tied
+    # to a specific SeqGrabComponent, but I'm not 100% sure. Also, I'm not sure all the
+    # routines that return an SGOutput actually return a *new* SGOutput. Need to read up on
+    # this.
+    pass
+
+
+# From here on it's basically all boiler plate...
+
+# Create the generator groups and link them
+module = MacModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff)
+Movie_object = MovieObjectDefinition('Movie', 'MovieObj', 'Movie')
+Track_object = TrackObjectDefinition('Track', 'TrackObj', 'Track')
+Media_object = MediaObjectDefinition('Media', 'MediaObj', 'Media')
+UserData_object = UserDataObjectDefinition('UserData', 'UserDataObj', 'UserData')
+TimeBase_object = TimeBaseObjectDefinition('TimeBase', 'TimeBaseObj', 'TimeBase')
+MovieController_object = MovieCtlObjectDefinition('MovieController', 'MovieCtlObj', 'MovieController')
+IdleManager_object = IdleManagerObjectDefinition('IdleManager', 'IdleManagerObj', 'IdleManager')
+SGOutput_object = SGOutputObjectDefinition('SGOutput', 'SGOutputObj', 'SGOutput')
+
+module.addobject(IdleManager_object)
+module.addobject(MovieController_object)
+module.addobject(TimeBase_object)
+module.addobject(UserData_object)
+module.addobject(Media_object)
+module.addobject(Track_object)
+module.addobject(Movie_object)
+module.addobject(SGOutput_object)
+
+# Test which types we are still missing.
+execfile(string.lower(MODPREFIX) + 'typetest.py')
+
+# Create the generator classes used to populate the lists
+Function = OSErrWeakLinkFunctionGenerator
+Method = OSErrWeakLinkMethodGenerator
+
+# Create and populate the lists
+functions = []
+IdleManager_methods = []
+MovieController_methods = []
+TimeBase_methods = []
+UserData_methods = []
+Media_methods = []
+Track_methods = []
+Movie_methods = []
+SGOutput_methods = []
+execfile(INPUTFILE)
+
+#
+# Some functions from ImageCompression.h that we need:
+ICMAlignmentProcRecordPtr = FakeType('(ICMAlignmentProcRecordPtr)0')
+dummyRect = FakeType('(Rect *)0')
+
+f = Function(void, 'AlignWindow',
+        (WindowPtr, 'wp', InMode),
+        (Boolean, 'front', InMode),
+        (dummyRect, 'alignmentRect', InMode),
+        (ICMAlignmentProcRecordPtr, 'alignmentProc', InMode),
+)
+functions.append(f)
+
+f = Function(void, 'DragAlignedWindow',
+        (WindowPtr, 'wp', InMode),
+        (Point, 'startPt', InMode),
+        (Rect_ptr, 'boundsRect', InMode),
+        (dummyRect, 'alignmentRect', InMode),
+        (ICMAlignmentProcRecordPtr, 'alignmentProc', InMode),
+)
+functions.append(f)
+
+# And we want the version of MoviesTask without a movie argument
+f = Function(void, 'MoviesTask',
+    (NullMovie, 'theMovie', InMode),
+    (long, 'maxMilliSecToUse', InMode),
+)
+functions.append(f)
+
+# And we want a GetMediaNextInterestingTime without duration
+f = Method(void, 'GetMediaNextInterestingTimeOnly',
+    (Media, 'theMedia', InMode),
+    (short, 'interestingTimeFlags', InMode),
+    (TimeValue, 'time', InMode),
+    (Fixed, 'rate', InMode),
+    (TimeValue, 'interestingTime', OutMode),
+)
+Media_methods.append(f)
+
+# add the populated lists to the generator groups
+# (in a different wordl the scan program would generate this)
+for f in functions: module.add(f)
+for f in MovieController_methods: MovieController_object.add(f)
+for f in TimeBase_methods: TimeBase_object.add(f)
+for f in UserData_methods: UserData_object.add(f)
+for f in Media_methods: Media_object.add(f)
+for f in Track_methods: Track_object.add(f)
+for f in Movie_methods: Movie_object.add(f)
+
+# generate output (open the output file as late as possible)
+SetOutputFileName(OUTPUTFILE)
+module.generate()

Added: vendor/Python/current/Mac/Modules/qt/setup.py
===================================================================
--- vendor/Python/current/Mac/Modules/qt/setup.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/qt/setup.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,13 @@
+# This is a temporary setup script to allow distribution of
+# MacPython 2.4 modules for MacPython 2.3.
+
+from distutils.core import Extension, setup
+
+setup(name="QuickTime", version="0.2",
+        ext_modules=[
+                Extension('QuickTime._Qt', ['_Qtmodule.c'],
+                extra_link_args=['-framework', 'Carbon', '-framework', 'QuickTime'])
+        ],
+        py_modules=['QuickTime.Qt', 'QuickTime.QuickTime'],
+        package_dir={'QuickTime':'../../../Lib/plat-mac/Carbon'}
+        )


Property changes on: vendor/Python/current/Mac/Modules/qt/setup.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Mac/Modules/res/_Resmodule.c
===================================================================
--- vendor/Python/current/Mac/Modules/res/_Resmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/res/_Resmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1744 @@
+
+/* ========================== Module _Res =========================== */
+
+#include "Python.h"
+
+
+
+#include "pymactoolbox.h"
+
+/* Macro to test whether a weak-loaded CFM function exists */
+#define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL )  {\
+        PyErr_SetString(PyExc_NotImplementedError, \
+        "Not available in this shared library/OS version"); \
+        return NULL; \
+    }} while(0)
+
+
+#include <Carbon/Carbon.h>
+
+#ifdef USE_TOOLBOX_OBJECT_GLUE
+extern PyObject *_ResObj_New(Handle);
+extern int _ResObj_Convert(PyObject *, Handle *);
+extern PyObject *_OptResObj_New(Handle);
+extern int _OptResObj_Convert(PyObject *, Handle *);
+#define ResObj_New _ResObj_New
+#define ResObj_Convert _ResObj_Convert
+#define OptResObj_New _OptResObj_New
+#define OptResObj_Convert _OptResObj_Convert
+#endif
+
+/* Function to dispose a resource, with a "normal" calling sequence */
+static void
+PyMac_AutoDisposeHandle(Handle h)
+{
+        DisposeHandle(h);
+}
+
+static PyObject *Res_Error;
+
+/* ---------------------- Object type Resource ---------------------- */
+
+PyTypeObject Resource_Type;
+
+#define ResObj_Check(x) ((x)->ob_type == &Resource_Type || PyObject_TypeCheck((x), &Resource_Type))
+
+typedef struct ResourceObject {
+	PyObject_HEAD
+	Handle ob_itself;
+	void (*ob_freeit)(Handle ptr);
+} ResourceObject;
+
+PyObject *ResObj_New(Handle itself)
+{
+	ResourceObject *it;
+	if (itself == NULL) return PyMac_Error(resNotFound);
+	it = PyObject_NEW(ResourceObject, &Resource_Type);
+	if (it == NULL) return NULL;
+	it->ob_itself = itself;
+	it->ob_freeit = NULL;
+	return (PyObject *)it;
+}
+
+int ResObj_Convert(PyObject *v, Handle *p_itself)
+{
+	if (!ResObj_Check(v))
+	{
+		PyObject *tmp;
+		if ( (tmp=PyObject_CallMethod(v, "as_Resource", "")) )
+		{
+			*p_itself = ((ResourceObject *)tmp)->ob_itself;
+			Py_DECREF(tmp);
+			return 1;
+		}
+		PyErr_Clear();
+	}
+	if (!ResObj_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "Resource required");
+		return 0;
+	}
+	*p_itself = ((ResourceObject *)v)->ob_itself;
+	return 1;
+}
+
+static void ResObj_dealloc(ResourceObject *self)
+{
+	if (self->ob_freeit && self->ob_itself)
+	{
+		self->ob_freeit(self->ob_itself);
+	}
+	self->ob_itself = NULL;
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *ResObj_HomeResFile(ResourceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short _rv;
+#ifndef HomeResFile
+	PyMac_PRECHECK(HomeResFile);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = HomeResFile(_self->ob_itself);
+	{
+		OSErr _err = ResError();
+		if (_err != noErr) return PyMac_Error(_err);
+	}
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *ResObj_MacLoadResource(ResourceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef MacLoadResource
+	PyMac_PRECHECK(MacLoadResource);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	MacLoadResource(_self->ob_itself);
+	{
+		OSErr _err = ResError();
+		if (_err != noErr) return PyMac_Error(_err);
+	}
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *ResObj_ReleaseResource(ResourceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef ReleaseResource
+	PyMac_PRECHECK(ReleaseResource);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	ReleaseResource(_self->ob_itself);
+	{
+		OSErr _err = ResError();
+		if (_err != noErr) return PyMac_Error(_err);
+	}
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *ResObj_DetachResource(ResourceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef DetachResource
+	PyMac_PRECHECK(DetachResource);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	DetachResource(_self->ob_itself);
+	{
+		OSErr _err = ResError();
+		if (_err != noErr) return PyMac_Error(_err);
+	}
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *ResObj_GetResAttrs(ResourceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short _rv;
+#ifndef GetResAttrs
+	PyMac_PRECHECK(GetResAttrs);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetResAttrs(_self->ob_itself);
+	{
+		OSErr _err = ResError();
+		if (_err != noErr) return PyMac_Error(_err);
+	}
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *ResObj_GetResInfo(ResourceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short theID;
+	ResType theType;
+	Str255 name;
+#ifndef GetResInfo
+	PyMac_PRECHECK(GetResInfo);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	GetResInfo(_self->ob_itself,
+	           &theID,
+	           &theType,
+	           name);
+	{
+		OSErr _err = ResError();
+		if (_err != noErr) return PyMac_Error(_err);
+	}
+	_res = Py_BuildValue("hO&O&",
+	                     theID,
+	                     PyMac_BuildOSType, theType,
+	                     PyMac_BuildStr255, name);
+	return _res;
+}
+
+static PyObject *ResObj_SetResInfo(ResourceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short theID;
+	Str255 name;
+#ifndef SetResInfo
+	PyMac_PRECHECK(SetResInfo);
+#endif
+	if (!PyArg_ParseTuple(_args, "hO&",
+	                      &theID,
+	                      PyMac_GetStr255, name))
+		return NULL;
+	SetResInfo(_self->ob_itself,
+	           theID,
+	           name);
+	{
+		OSErr _err = ResError();
+		if (_err != noErr) return PyMac_Error(_err);
+	}
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *ResObj_AddResource(ResourceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ResType theType;
+	short theID;
+	Str255 name;
+#ifndef AddResource
+	PyMac_PRECHECK(AddResource);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hO&",
+	                      PyMac_GetOSType, &theType,
+	                      &theID,
+	                      PyMac_GetStr255, name))
+		return NULL;
+	AddResource(_self->ob_itself,
+	            theType,
+	            theID,
+	            name);
+	{
+		OSErr _err = ResError();
+		if (_err != noErr) return PyMac_Error(_err);
+	}
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *ResObj_GetResourceSizeOnDisk(ResourceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long _rv;
+#ifndef GetResourceSizeOnDisk
+	PyMac_PRECHECK(GetResourceSizeOnDisk);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetResourceSizeOnDisk(_self->ob_itself);
+	{
+		OSErr _err = ResError();
+		if (_err != noErr) return PyMac_Error(_err);
+	}
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *ResObj_GetMaxResourceSize(ResourceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long _rv;
+#ifndef GetMaxResourceSize
+	PyMac_PRECHECK(GetMaxResourceSize);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetMaxResourceSize(_self->ob_itself);
+	{
+		OSErr _err = ResError();
+		if (_err != noErr) return PyMac_Error(_err);
+	}
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *ResObj_SetResAttrs(ResourceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short attrs;
+#ifndef SetResAttrs
+	PyMac_PRECHECK(SetResAttrs);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &attrs))
+		return NULL;
+	SetResAttrs(_self->ob_itself,
+	            attrs);
+	{
+		OSErr _err = ResError();
+		if (_err != noErr) return PyMac_Error(_err);
+	}
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *ResObj_ChangedResource(ResourceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef ChangedResource
+	PyMac_PRECHECK(ChangedResource);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	ChangedResource(_self->ob_itself);
+	{
+		OSErr _err = ResError();
+		if (_err != noErr) return PyMac_Error(_err);
+	}
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *ResObj_RemoveResource(ResourceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef RemoveResource
+	PyMac_PRECHECK(RemoveResource);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	RemoveResource(_self->ob_itself);
+	{
+		OSErr _err = ResError();
+		if (_err != noErr) return PyMac_Error(_err);
+	}
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *ResObj_WriteResource(ResourceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef WriteResource
+	PyMac_PRECHECK(WriteResource);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	WriteResource(_self->ob_itself);
+	{
+		OSErr _err = ResError();
+		if (_err != noErr) return PyMac_Error(_err);
+	}
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *ResObj_SetResourceSize(ResourceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long newSize;
+#ifndef SetResourceSize
+	PyMac_PRECHECK(SetResourceSize);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &newSize))
+		return NULL;
+	SetResourceSize(_self->ob_itself,
+	                newSize);
+	{
+		OSErr _err = ResError();
+		if (_err != noErr) return PyMac_Error(_err);
+	}
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *ResObj_GetNextFOND(ResourceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Handle _rv;
+#ifndef GetNextFOND
+	PyMac_PRECHECK(GetNextFOND);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetNextFOND(_self->ob_itself);
+	{
+		OSErr _err = ResError();
+		if (_err != noErr) return PyMac_Error(_err);
+	}
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *ResObj_as_Control(ResourceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+
+	_res = CtlObj_New((ControlHandle)_self->ob_itself);
+	return _res;
+
+}
+
+static PyObject *ResObj_as_Menu(ResourceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+
+	_res = MenuObj_New((MenuHandle)_self->ob_itself);
+	return _res;
+
+}
+
+static PyObject *ResObj_LoadResource(ResourceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef LoadResource
+	PyMac_PRECHECK(LoadResource);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	LoadResource(_self->ob_itself);
+	{
+		OSErr _err = ResError();
+		if (_err != noErr) return PyMac_Error(_err);
+	}
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *ResObj_AutoDispose(ResourceObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+
+	int onoff, old = 0;
+	if (!PyArg_ParseTuple(_args, "i", &onoff))
+	        return NULL;
+	if ( _self->ob_freeit )
+	        old = 1;
+	if ( onoff )
+	        _self->ob_freeit = PyMac_AutoDisposeHandle;
+	else
+	        _self->ob_freeit = NULL;
+	_res = Py_BuildValue("i", old);
+	return _res;
+
+}
+
+static PyMethodDef ResObj_methods[] = {
+	{"HomeResFile", (PyCFunction)ResObj_HomeResFile, 1,
+	 PyDoc_STR("() -> (short _rv)")},
+	{"MacLoadResource", (PyCFunction)ResObj_MacLoadResource, 1,
+	 PyDoc_STR("() -> None")},
+	{"ReleaseResource", (PyCFunction)ResObj_ReleaseResource, 1,
+	 PyDoc_STR("() -> None")},
+	{"DetachResource", (PyCFunction)ResObj_DetachResource, 1,
+	 PyDoc_STR("() -> None")},
+	{"GetResAttrs", (PyCFunction)ResObj_GetResAttrs, 1,
+	 PyDoc_STR("() -> (short _rv)")},
+	{"GetResInfo", (PyCFunction)ResObj_GetResInfo, 1,
+	 PyDoc_STR("() -> (short theID, ResType theType, Str255 name)")},
+	{"SetResInfo", (PyCFunction)ResObj_SetResInfo, 1,
+	 PyDoc_STR("(short theID, Str255 name) -> None")},
+	{"AddResource", (PyCFunction)ResObj_AddResource, 1,
+	 PyDoc_STR("(ResType theType, short theID, Str255 name) -> None")},
+	{"GetResourceSizeOnDisk", (PyCFunction)ResObj_GetResourceSizeOnDisk, 1,
+	 PyDoc_STR("() -> (long _rv)")},
+	{"GetMaxResourceSize", (PyCFunction)ResObj_GetMaxResourceSize, 1,
+	 PyDoc_STR("() -> (long _rv)")},
+	{"SetResAttrs", (PyCFunction)ResObj_SetResAttrs, 1,
+	 PyDoc_STR("(short attrs) -> None")},
+	{"ChangedResource", (PyCFunction)ResObj_ChangedResource, 1,
+	 PyDoc_STR("() -> None")},
+	{"RemoveResource", (PyCFunction)ResObj_RemoveResource, 1,
+	 PyDoc_STR("() -> None")},
+	{"WriteResource", (PyCFunction)ResObj_WriteResource, 1,
+	 PyDoc_STR("() -> None")},
+	{"SetResourceSize", (PyCFunction)ResObj_SetResourceSize, 1,
+	 PyDoc_STR("(long newSize) -> None")},
+	{"GetNextFOND", (PyCFunction)ResObj_GetNextFOND, 1,
+	 PyDoc_STR("() -> (Handle _rv)")},
+	{"as_Control", (PyCFunction)ResObj_as_Control, 1,
+	 PyDoc_STR("Return this resource/handle as a Control")},
+	{"as_Menu", (PyCFunction)ResObj_as_Menu, 1,
+	 PyDoc_STR("Return this resource/handle as a Menu")},
+	{"LoadResource", (PyCFunction)ResObj_LoadResource, 1,
+	 PyDoc_STR("() -> None")},
+	{"AutoDispose", (PyCFunction)ResObj_AutoDispose, 1,
+	 PyDoc_STR("(int)->int. Automatically DisposeHandle the object on Python object cleanup")},
+	{NULL, NULL, 0}
+};
+
+static PyObject *ResObj_get_data(ResourceObject *self, void *closure)
+{
+
+	            PyObject *res;
+	            char state;
+
+	            state = HGetState(self->ob_itself);
+	            HLock(self->ob_itself);
+	            res = PyString_FromStringAndSize(
+	                    *self->ob_itself,
+	                    GetHandleSize(self->ob_itself));
+	            HUnlock(self->ob_itself);
+	            HSetState(self->ob_itself, state);
+	            return res;
+	            
+}
+
+static int ResObj_set_data(ResourceObject *self, PyObject *v, void *closure)
+{
+
+	            char *data;
+	            long size;
+
+	            if ( v == NULL )
+	                    return -1;
+	            if ( !PyString_Check(v) )
+	                    return -1;
+	            size = PyString_Size(v);
+	            data = PyString_AsString(v);
+	            /* XXXX Do I need the GetState/SetState calls? */
+	            SetHandleSize(self->ob_itself, size);
+	            if ( MemError())
+	                    return -1;
+	            HLock(self->ob_itself);
+	            memcpy((char *)*self->ob_itself, data, size);
+	            HUnlock(self->ob_itself);
+	            /* XXXX Should I do the Changed call immedeately? */
+	            return 0;
+	            
+	return 0;
+}
+
+static PyObject *ResObj_get_size(ResourceObject *self, void *closure)
+{
+	return PyInt_FromLong(GetHandleSize(self->ob_itself));
+}
+
+#define ResObj_set_size NULL
+
+static PyGetSetDef ResObj_getsetlist[] = {
+	{"data", (getter)ResObj_get_data, (setter)ResObj_set_data, "The resource data"},
+	{"size", (getter)ResObj_get_size, (setter)ResObj_set_size, "The length of the resource data"},
+	{NULL, NULL, NULL, NULL},
+};
+
+
+#define ResObj_compare NULL
+
+#define ResObj_repr NULL
+
+#define ResObj_hash NULL
+static int ResObj_tp_init(PyObject *_self, PyObject *_args, PyObject *_kwds)
+{
+	char *srcdata = NULL;
+	int srclen = 0;
+	Handle itself;
+	char *kw[] = {"itself", 0};
+
+	if (PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, ResObj_Convert, &itself))
+	{
+		((ResourceObject *)_self)->ob_itself = itself;
+		return 0;
+	}
+	PyErr_Clear();
+	if (!PyArg_ParseTupleAndKeywords(_args, _kwds, "|s#", kw, &srcdata, &srclen)) return -1;
+	if ((itself = NewHandle(srclen)) == NULL)
+	{
+		PyErr_NoMemory();
+		return 0;
+	}
+	((ResourceObject *)_self)->ob_itself = itself;
+	if (srclen && srcdata)
+	{
+		HLock(itself);
+		memcpy(*itself, srcdata, srclen);
+		HUnlock(itself);
+	}
+	return 0;
+}
+
+#define ResObj_tp_alloc PyType_GenericAlloc
+
+static PyObject *ResObj_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *self;
+	if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	((ResourceObject *)self)->ob_itself = NULL;
+	((ResourceObject *)self)->ob_freeit = NULL;
+	return self;
+}
+
+#define ResObj_tp_free PyObject_Del
+
+
+PyTypeObject Resource_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"_Res.Resource", /*tp_name*/
+	sizeof(ResourceObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) ResObj_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) ResObj_compare, /*tp_compare*/
+	(reprfunc) ResObj_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) ResObj_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	ResObj_methods, /* tp_methods */
+	0, /*tp_members*/
+	ResObj_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	ResObj_tp_init, /* tp_init */
+	ResObj_tp_alloc, /* tp_alloc */
+	ResObj_tp_new, /* tp_new */
+	ResObj_tp_free, /* tp_free */
+};
+
+/* -------------------- End object type Resource -------------------- */
+
+
+static PyObject *Res_CloseResFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short refNum;
+#ifndef CloseResFile
+	PyMac_PRECHECK(CloseResFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &refNum))
+		return NULL;
+	CloseResFile(refNum);
+	{
+		OSErr _err = ResError();
+		if (_err != noErr) return PyMac_Error(_err);
+	}
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Res_ResError(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+#ifndef ResError
+	PyMac_PRECHECK(ResError);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = ResError();
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Res_CurResFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short _rv;
+#ifndef CurResFile
+	PyMac_PRECHECK(CurResFile);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CurResFile();
+	{
+		OSErr _err = ResError();
+		if (_err != noErr) return PyMac_Error(_err);
+	}
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Res_UseResFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short refNum;
+#ifndef UseResFile
+	PyMac_PRECHECK(UseResFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &refNum))
+		return NULL;
+	UseResFile(refNum);
+	{
+		OSErr _err = ResError();
+		if (_err != noErr) return PyMac_Error(_err);
+	}
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Res_CountTypes(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short _rv;
+#ifndef CountTypes
+	PyMac_PRECHECK(CountTypes);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CountTypes();
+	{
+		OSErr _err = ResError();
+		if (_err != noErr) return PyMac_Error(_err);
+	}
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Res_Count1Types(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short _rv;
+#ifndef Count1Types
+	PyMac_PRECHECK(Count1Types);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = Count1Types();
+	{
+		OSErr _err = ResError();
+		if (_err != noErr) return PyMac_Error(_err);
+	}
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Res_GetIndType(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ResType theType;
+	short index;
+#ifndef GetIndType
+	PyMac_PRECHECK(GetIndType);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &index))
+		return NULL;
+	GetIndType(&theType,
+	           index);
+	{
+		OSErr _err = ResError();
+		if (_err != noErr) return PyMac_Error(_err);
+	}
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildOSType, theType);
+	return _res;
+}
+
+static PyObject *Res_Get1IndType(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ResType theType;
+	short index;
+#ifndef Get1IndType
+	PyMac_PRECHECK(Get1IndType);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &index))
+		return NULL;
+	Get1IndType(&theType,
+	            index);
+	{
+		OSErr _err = ResError();
+		if (_err != noErr) return PyMac_Error(_err);
+	}
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildOSType, theType);
+	return _res;
+}
+
+static PyObject *Res_SetResLoad(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean load;
+#ifndef SetResLoad
+	PyMac_PRECHECK(SetResLoad);
+#endif
+	if (!PyArg_ParseTuple(_args, "b",
+	                      &load))
+		return NULL;
+	SetResLoad(load);
+	{
+		OSErr _err = ResError();
+		if (_err != noErr) return PyMac_Error(_err);
+	}
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Res_CountResources(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short _rv;
+	ResType theType;
+#ifndef CountResources
+	PyMac_PRECHECK(CountResources);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetOSType, &theType))
+		return NULL;
+	_rv = CountResources(theType);
+	{
+		OSErr _err = ResError();
+		if (_err != noErr) return PyMac_Error(_err);
+	}
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Res_Count1Resources(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short _rv;
+	ResType theType;
+#ifndef Count1Resources
+	PyMac_PRECHECK(Count1Resources);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetOSType, &theType))
+		return NULL;
+	_rv = Count1Resources(theType);
+	{
+		OSErr _err = ResError();
+		if (_err != noErr) return PyMac_Error(_err);
+	}
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Res_GetIndResource(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Handle _rv;
+	ResType theType;
+	short index;
+#ifndef GetIndResource
+	PyMac_PRECHECK(GetIndResource);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      PyMac_GetOSType, &theType,
+	                      &index))
+		return NULL;
+	_rv = GetIndResource(theType,
+	                     index);
+	{
+		OSErr _err = ResError();
+		if (_err != noErr) return PyMac_Error(_err);
+	}
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Res_Get1IndResource(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Handle _rv;
+	ResType theType;
+	short index;
+#ifndef Get1IndResource
+	PyMac_PRECHECK(Get1IndResource);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      PyMac_GetOSType, &theType,
+	                      &index))
+		return NULL;
+	_rv = Get1IndResource(theType,
+	                      index);
+	{
+		OSErr _err = ResError();
+		if (_err != noErr) return PyMac_Error(_err);
+	}
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Res_GetResource(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Handle _rv;
+	ResType theType;
+	short theID;
+#ifndef GetResource
+	PyMac_PRECHECK(GetResource);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      PyMac_GetOSType, &theType,
+	                      &theID))
+		return NULL;
+	_rv = GetResource(theType,
+	                  theID);
+	{
+		OSErr _err = ResError();
+		if (_err != noErr) return PyMac_Error(_err);
+	}
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Res_Get1Resource(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Handle _rv;
+	ResType theType;
+	short theID;
+#ifndef Get1Resource
+	PyMac_PRECHECK(Get1Resource);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      PyMac_GetOSType, &theType,
+	                      &theID))
+		return NULL;
+	_rv = Get1Resource(theType,
+	                   theID);
+	{
+		OSErr _err = ResError();
+		if (_err != noErr) return PyMac_Error(_err);
+	}
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Res_GetNamedResource(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Handle _rv;
+	ResType theType;
+	Str255 name;
+#ifndef GetNamedResource
+	PyMac_PRECHECK(GetNamedResource);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetOSType, &theType,
+	                      PyMac_GetStr255, name))
+		return NULL;
+	_rv = GetNamedResource(theType,
+	                       name);
+	{
+		OSErr _err = ResError();
+		if (_err != noErr) return PyMac_Error(_err);
+	}
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Res_Get1NamedResource(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Handle _rv;
+	ResType theType;
+	Str255 name;
+#ifndef Get1NamedResource
+	PyMac_PRECHECK(Get1NamedResource);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetOSType, &theType,
+	                      PyMac_GetStr255, name))
+		return NULL;
+	_rv = Get1NamedResource(theType,
+	                        name);
+	{
+		OSErr _err = ResError();
+		if (_err != noErr) return PyMac_Error(_err);
+	}
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Res_UniqueID(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short _rv;
+	ResType theType;
+#ifndef UniqueID
+	PyMac_PRECHECK(UniqueID);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetOSType, &theType))
+		return NULL;
+	_rv = UniqueID(theType);
+	{
+		OSErr _err = ResError();
+		if (_err != noErr) return PyMac_Error(_err);
+	}
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Res_Unique1ID(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short _rv;
+	ResType theType;
+#ifndef Unique1ID
+	PyMac_PRECHECK(Unique1ID);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetOSType, &theType))
+		return NULL;
+	_rv = Unique1ID(theType);
+	{
+		OSErr _err = ResError();
+		if (_err != noErr) return PyMac_Error(_err);
+	}
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Res_UpdateResFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short refNum;
+#ifndef UpdateResFile
+	PyMac_PRECHECK(UpdateResFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &refNum))
+		return NULL;
+	UpdateResFile(refNum);
+	{
+		OSErr _err = ResError();
+		if (_err != noErr) return PyMac_Error(_err);
+	}
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Res_SetResPurge(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean install;
+#ifndef SetResPurge
+	PyMac_PRECHECK(SetResPurge);
+#endif
+	if (!PyArg_ParseTuple(_args, "b",
+	                      &install))
+		return NULL;
+	SetResPurge(install);
+	{
+		OSErr _err = ResError();
+		if (_err != noErr) return PyMac_Error(_err);
+	}
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Res_GetResFileAttrs(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short _rv;
+	short refNum;
+#ifndef GetResFileAttrs
+	PyMac_PRECHECK(GetResFileAttrs);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &refNum))
+		return NULL;
+	_rv = GetResFileAttrs(refNum);
+	{
+		OSErr _err = ResError();
+		if (_err != noErr) return PyMac_Error(_err);
+	}
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Res_SetResFileAttrs(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short refNum;
+	short attrs;
+#ifndef SetResFileAttrs
+	PyMac_PRECHECK(SetResFileAttrs);
+#endif
+	if (!PyArg_ParseTuple(_args, "hh",
+	                      &refNum,
+	                      &attrs))
+		return NULL;
+	SetResFileAttrs(refNum,
+	                attrs);
+	{
+		OSErr _err = ResError();
+		if (_err != noErr) return PyMac_Error(_err);
+	}
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Res_OpenRFPerm(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short _rv;
+	Str255 fileName;
+	short vRefNum;
+	SignedByte permission;
+#ifndef OpenRFPerm
+	PyMac_PRECHECK(OpenRFPerm);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hb",
+	                      PyMac_GetStr255, fileName,
+	                      &vRefNum,
+	                      &permission))
+		return NULL;
+	_rv = OpenRFPerm(fileName,
+	                 vRefNum,
+	                 permission);
+	{
+		OSErr _err = ResError();
+		if (_err != noErr) return PyMac_Error(_err);
+	}
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Res_HOpenResFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short _rv;
+	short vRefNum;
+	long dirID;
+	Str255 fileName;
+	SignedByte permission;
+#ifndef HOpenResFile
+	PyMac_PRECHECK(HOpenResFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "hlO&b",
+	                      &vRefNum,
+	                      &dirID,
+	                      PyMac_GetStr255, fileName,
+	                      &permission))
+		return NULL;
+	_rv = HOpenResFile(vRefNum,
+	                   dirID,
+	                   fileName,
+	                   permission);
+	{
+		OSErr _err = ResError();
+		if (_err != noErr) return PyMac_Error(_err);
+	}
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Res_HCreateResFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short vRefNum;
+	long dirID;
+	Str255 fileName;
+#ifndef HCreateResFile
+	PyMac_PRECHECK(HCreateResFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "hlO&",
+	                      &vRefNum,
+	                      &dirID,
+	                      PyMac_GetStr255, fileName))
+		return NULL;
+	HCreateResFile(vRefNum,
+	               dirID,
+	               fileName);
+	{
+		OSErr _err = ResError();
+		if (_err != noErr) return PyMac_Error(_err);
+	}
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Res_FSpOpenResFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short _rv;
+	FSSpec spec;
+	SignedByte permission;
+#ifndef FSpOpenResFile
+	PyMac_PRECHECK(FSpOpenResFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&b",
+	                      PyMac_GetFSSpec, &spec,
+	                      &permission))
+		return NULL;
+	_rv = FSpOpenResFile(&spec,
+	                     permission);
+	{
+		OSErr _err = ResError();
+		if (_err != noErr) return PyMac_Error(_err);
+	}
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Res_FSpCreateResFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	FSSpec spec;
+	OSType creator;
+	OSType fileType;
+	ScriptCode scriptTag;
+#ifndef FSpCreateResFile
+	PyMac_PRECHECK(FSpCreateResFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&h",
+	                      PyMac_GetFSSpec, &spec,
+	                      PyMac_GetOSType, &creator,
+	                      PyMac_GetOSType, &fileType,
+	                      &scriptTag))
+		return NULL;
+	FSpCreateResFile(&spec,
+	                 creator,
+	                 fileType,
+	                 scriptTag);
+	{
+		OSErr _err = ResError();
+		if (_err != noErr) return PyMac_Error(_err);
+	}
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Res_InsertResourceFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SInt16 refNum;
+	RsrcChainLocation where;
+#ifndef InsertResourceFile
+	PyMac_PRECHECK(InsertResourceFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "hh",
+	                      &refNum,
+	                      &where))
+		return NULL;
+	_err = InsertResourceFile(refNum,
+	                          where);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Res_DetachResourceFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SInt16 refNum;
+#ifndef DetachResourceFile
+	PyMac_PRECHECK(DetachResourceFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &refNum))
+		return NULL;
+	_err = DetachResourceFile(refNum);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Res_FSpResourceFileAlreadyOpen(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	FSSpec resourceFile;
+	Boolean inChain;
+	SInt16 refNum;
+#ifndef FSpResourceFileAlreadyOpen
+	PyMac_PRECHECK(FSpResourceFileAlreadyOpen);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetFSSpec, &resourceFile))
+		return NULL;
+	_rv = FSpResourceFileAlreadyOpen(&resourceFile,
+	                                 &inChain,
+	                                 &refNum);
+	{
+		OSErr _err = ResError();
+		if (_err != noErr) return PyMac_Error(_err);
+	}
+	_res = Py_BuildValue("bbh",
+	                     _rv,
+	                     inChain,
+	                     refNum);
+	return _res;
+}
+
+static PyObject *Res_FSpOpenOrphanResFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	FSSpec spec;
+	SignedByte permission;
+	SInt16 refNum;
+#ifndef FSpOpenOrphanResFile
+	PyMac_PRECHECK(FSpOpenOrphanResFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&b",
+	                      PyMac_GetFSSpec, &spec,
+	                      &permission))
+		return NULL;
+	_err = FSpOpenOrphanResFile(&spec,
+	                            permission,
+	                            &refNum);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("h",
+	                     refNum);
+	return _res;
+}
+
+static PyObject *Res_GetTopResourceFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SInt16 refNum;
+#ifndef GetTopResourceFile
+	PyMac_PRECHECK(GetTopResourceFile);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetTopResourceFile(&refNum);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("h",
+	                     refNum);
+	return _res;
+}
+
+static PyObject *Res_GetNextResourceFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SInt16 curRefNum;
+	SInt16 nextRefNum;
+#ifndef GetNextResourceFile
+	PyMac_PRECHECK(GetNextResourceFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &curRefNum))
+		return NULL;
+	_err = GetNextResourceFile(curRefNum,
+	                           &nextRefNum);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("h",
+	                     nextRefNum);
+	return _res;
+}
+
+static PyObject *Res_FSOpenResFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short _rv;
+	FSRef ref;
+	SignedByte permission;
+#ifndef FSOpenResFile
+	PyMac_PRECHECK(FSOpenResFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&b",
+	                      PyMac_GetFSRef, &ref,
+	                      &permission))
+		return NULL;
+	_rv = FSOpenResFile(&ref,
+	                    permission);
+	{
+		OSErr _err = ResError();
+		if (_err != noErr) return PyMac_Error(_err);
+	}
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Res_FSCreateResFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	FSRef parentRef;
+	UniChar *nameLength__in__;
+	UniCharCount nameLength__len__;
+	int nameLength__in_len__;
+	FSRef newRef;
+	FSSpec newSpec;
+#ifndef FSCreateResFile
+	PyMac_PRECHECK(FSCreateResFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&u#",
+	                      PyMac_GetFSRef, &parentRef,
+	                      &nameLength__in__, &nameLength__in_len__))
+		return NULL;
+	nameLength__len__ = nameLength__in_len__;
+	FSCreateResFile(&parentRef,
+	                nameLength__len__, nameLength__in__,
+	                0,
+	                (FSCatalogInfo *)0,
+	                &newRef,
+	                &newSpec);
+	{
+		OSErr _err = ResError();
+		if (_err != noErr) return PyMac_Error(_err);
+	}
+	_res = Py_BuildValue("O&O&",
+	                     PyMac_BuildFSRef, &newRef,
+	                     PyMac_BuildFSSpec, &newSpec);
+	return _res;
+}
+
+static PyObject *Res_FSResourceFileAlreadyOpen(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	FSRef resourceFileRef;
+	Boolean inChain;
+	SInt16 refNum;
+#ifndef FSResourceFileAlreadyOpen
+	PyMac_PRECHECK(FSResourceFileAlreadyOpen);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetFSRef, &resourceFileRef))
+		return NULL;
+	_rv = FSResourceFileAlreadyOpen(&resourceFileRef,
+	                                &inChain,
+	                                &refNum);
+	{
+		OSErr _err = ResError();
+		if (_err != noErr) return PyMac_Error(_err);
+	}
+	_res = Py_BuildValue("bbh",
+	                     _rv,
+	                     inChain,
+	                     refNum);
+	return _res;
+}
+
+static PyObject *Res_FSCreateResourceFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	FSRef parentRef;
+	UniChar *nameLength__in__;
+	UniCharCount nameLength__len__;
+	int nameLength__in_len__;
+	UniChar *forkNameLength__in__;
+	UniCharCount forkNameLength__len__;
+	int forkNameLength__in_len__;
+	FSRef newRef;
+	FSSpec newSpec;
+#ifndef FSCreateResourceFile
+	PyMac_PRECHECK(FSCreateResourceFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&u#u#",
+	                      PyMac_GetFSRef, &parentRef,
+	                      &nameLength__in__, &nameLength__in_len__,
+	                      &forkNameLength__in__, &forkNameLength__in_len__))
+		return NULL;
+	nameLength__len__ = nameLength__in_len__;
+	forkNameLength__len__ = forkNameLength__in_len__;
+	_err = FSCreateResourceFile(&parentRef,
+	                            nameLength__len__, nameLength__in__,
+	                            0,
+	                            (FSCatalogInfo *)0,
+	                            forkNameLength__len__, forkNameLength__in__,
+	                            &newRef,
+	                            &newSpec);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&O&",
+	                     PyMac_BuildFSRef, &newRef,
+	                     PyMac_BuildFSSpec, &newSpec);
+	return _res;
+}
+
+static PyObject *Res_FSOpenResourceFile(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	FSRef ref;
+	UniChar *forkNameLength__in__;
+	UniCharCount forkNameLength__len__;
+	int forkNameLength__in_len__;
+	SignedByte permissions;
+	SInt16 refNum;
+#ifndef FSOpenResourceFile
+	PyMac_PRECHECK(FSOpenResourceFile);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&u#b",
+	                      PyMac_GetFSRef, &ref,
+	                      &forkNameLength__in__, &forkNameLength__in_len__,
+	                      &permissions))
+		return NULL;
+	forkNameLength__len__ = forkNameLength__in_len__;
+	_err = FSOpenResourceFile(&ref,
+	                          forkNameLength__len__, forkNameLength__in__,
+	                          permissions,
+	                          &refNum);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("h",
+	                     refNum);
+	return _res;
+}
+
+static PyObject *Res_Handle(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+
+	char *buf;
+	int len;
+	Handle h;
+	ResourceObject *rv;
+
+	if (!PyArg_ParseTuple(_args, "s#", &buf, &len))
+	        return NULL;
+	h = NewHandle(len);
+	if ( h == NULL ) {
+	        PyErr_NoMemory();
+	        return NULL;
+	}
+	HLock(h);
+	memcpy(*h, buf, len);
+	HUnlock(h);
+	rv = (ResourceObject *)ResObj_New(h);
+	rv->ob_freeit = PyMac_AutoDisposeHandle;
+	_res = (PyObject *)rv;
+	return _res;
+
+}
+
+static PyMethodDef Res_methods[] = {
+	{"CloseResFile", (PyCFunction)Res_CloseResFile, 1,
+	 PyDoc_STR("(short refNum) -> None")},
+	{"ResError", (PyCFunction)Res_ResError, 1,
+	 PyDoc_STR("() -> None")},
+	{"CurResFile", (PyCFunction)Res_CurResFile, 1,
+	 PyDoc_STR("() -> (short _rv)")},
+	{"UseResFile", (PyCFunction)Res_UseResFile, 1,
+	 PyDoc_STR("(short refNum) -> None")},
+	{"CountTypes", (PyCFunction)Res_CountTypes, 1,
+	 PyDoc_STR("() -> (short _rv)")},
+	{"Count1Types", (PyCFunction)Res_Count1Types, 1,
+	 PyDoc_STR("() -> (short _rv)")},
+	{"GetIndType", (PyCFunction)Res_GetIndType, 1,
+	 PyDoc_STR("(short index) -> (ResType theType)")},
+	{"Get1IndType", (PyCFunction)Res_Get1IndType, 1,
+	 PyDoc_STR("(short index) -> (ResType theType)")},
+	{"SetResLoad", (PyCFunction)Res_SetResLoad, 1,
+	 PyDoc_STR("(Boolean load) -> None")},
+	{"CountResources", (PyCFunction)Res_CountResources, 1,
+	 PyDoc_STR("(ResType theType) -> (short _rv)")},
+	{"Count1Resources", (PyCFunction)Res_Count1Resources, 1,
+	 PyDoc_STR("(ResType theType) -> (short _rv)")},
+	{"GetIndResource", (PyCFunction)Res_GetIndResource, 1,
+	 PyDoc_STR("(ResType theType, short index) -> (Handle _rv)")},
+	{"Get1IndResource", (PyCFunction)Res_Get1IndResource, 1,
+	 PyDoc_STR("(ResType theType, short index) -> (Handle _rv)")},
+	{"GetResource", (PyCFunction)Res_GetResource, 1,
+	 PyDoc_STR("(ResType theType, short theID) -> (Handle _rv)")},
+	{"Get1Resource", (PyCFunction)Res_Get1Resource, 1,
+	 PyDoc_STR("(ResType theType, short theID) -> (Handle _rv)")},
+	{"GetNamedResource", (PyCFunction)Res_GetNamedResource, 1,
+	 PyDoc_STR("(ResType theType, Str255 name) -> (Handle _rv)")},
+	{"Get1NamedResource", (PyCFunction)Res_Get1NamedResource, 1,
+	 PyDoc_STR("(ResType theType, Str255 name) -> (Handle _rv)")},
+	{"UniqueID", (PyCFunction)Res_UniqueID, 1,
+	 PyDoc_STR("(ResType theType) -> (short _rv)")},
+	{"Unique1ID", (PyCFunction)Res_Unique1ID, 1,
+	 PyDoc_STR("(ResType theType) -> (short _rv)")},
+	{"UpdateResFile", (PyCFunction)Res_UpdateResFile, 1,
+	 PyDoc_STR("(short refNum) -> None")},
+	{"SetResPurge", (PyCFunction)Res_SetResPurge, 1,
+	 PyDoc_STR("(Boolean install) -> None")},
+	{"GetResFileAttrs", (PyCFunction)Res_GetResFileAttrs, 1,
+	 PyDoc_STR("(short refNum) -> (short _rv)")},
+	{"SetResFileAttrs", (PyCFunction)Res_SetResFileAttrs, 1,
+	 PyDoc_STR("(short refNum, short attrs) -> None")},
+	{"OpenRFPerm", (PyCFunction)Res_OpenRFPerm, 1,
+	 PyDoc_STR("(Str255 fileName, short vRefNum, SignedByte permission) -> (short _rv)")},
+	{"HOpenResFile", (PyCFunction)Res_HOpenResFile, 1,
+	 PyDoc_STR("(short vRefNum, long dirID, Str255 fileName, SignedByte permission) -> (short _rv)")},
+	{"HCreateResFile", (PyCFunction)Res_HCreateResFile, 1,
+	 PyDoc_STR("(short vRefNum, long dirID, Str255 fileName) -> None")},
+	{"FSpOpenResFile", (PyCFunction)Res_FSpOpenResFile, 1,
+	 PyDoc_STR("(FSSpec spec, SignedByte permission) -> (short _rv)")},
+	{"FSpCreateResFile", (PyCFunction)Res_FSpCreateResFile, 1,
+	 PyDoc_STR("(FSSpec spec, OSType creator, OSType fileType, ScriptCode scriptTag) -> None")},
+	{"InsertResourceFile", (PyCFunction)Res_InsertResourceFile, 1,
+	 PyDoc_STR("(SInt16 refNum, RsrcChainLocation where) -> None")},
+	{"DetachResourceFile", (PyCFunction)Res_DetachResourceFile, 1,
+	 PyDoc_STR("(SInt16 refNum) -> None")},
+	{"FSpResourceFileAlreadyOpen", (PyCFunction)Res_FSpResourceFileAlreadyOpen, 1,
+	 PyDoc_STR("(FSSpec resourceFile) -> (Boolean _rv, Boolean inChain, SInt16 refNum)")},
+	{"FSpOpenOrphanResFile", (PyCFunction)Res_FSpOpenOrphanResFile, 1,
+	 PyDoc_STR("(FSSpec spec, SignedByte permission) -> (SInt16 refNum)")},
+	{"GetTopResourceFile", (PyCFunction)Res_GetTopResourceFile, 1,
+	 PyDoc_STR("() -> (SInt16 refNum)")},
+	{"GetNextResourceFile", (PyCFunction)Res_GetNextResourceFile, 1,
+	 PyDoc_STR("(SInt16 curRefNum) -> (SInt16 nextRefNum)")},
+	{"FSOpenResFile", (PyCFunction)Res_FSOpenResFile, 1,
+	 PyDoc_STR("(FSRef ref, SignedByte permission) -> (short _rv)")},
+	{"FSCreateResFile", (PyCFunction)Res_FSCreateResFile, 1,
+	 PyDoc_STR("(FSRef parentRef, Buffer nameLength) -> (FSRef newRef, FSSpec newSpec)")},
+	{"FSResourceFileAlreadyOpen", (PyCFunction)Res_FSResourceFileAlreadyOpen, 1,
+	 PyDoc_STR("(FSRef resourceFileRef) -> (Boolean _rv, Boolean inChain, SInt16 refNum)")},
+	{"FSCreateResourceFile", (PyCFunction)Res_FSCreateResourceFile, 1,
+	 PyDoc_STR("(FSRef parentRef, Buffer nameLength, Buffer forkNameLength) -> (FSRef newRef, FSSpec newSpec)")},
+	{"FSOpenResourceFile", (PyCFunction)Res_FSOpenResourceFile, 1,
+	 PyDoc_STR("(FSRef ref, Buffer forkNameLength, SignedByte permissions) -> (SInt16 refNum)")},
+	{"Handle", (PyCFunction)Res_Handle, 1,
+	 PyDoc_STR("Convert a string to a Handle object.\n\nResource() and Handle() are very similar, but objects created with Handle() are\nby default automatically DisposeHandle()d upon object cleanup. Use AutoDispose()\nto change this.\n")},
+	{NULL, NULL, 0}
+};
+
+
+
+
+/* Alternative version of ResObj_New, which returns None for null argument */
+PyObject *OptResObj_New(Handle itself)
+{
+        if (itself == NULL) {
+                Py_INCREF(Py_None);
+                return Py_None;
+        }
+        return ResObj_New(itself);
+}
+
+int OptResObj_Convert(PyObject *v, Handle *p_itself)
+{
+        PyObject *tmp;
+
+        if ( v == Py_None ) {
+                *p_itself = NULL;
+                return 1;
+        }
+        if (ResObj_Check(v))
+        {
+                *p_itself = ((ResourceObject *)v)->ob_itself;
+                return 1;
+        }
+        /* If it isn't a resource yet see whether it is convertible */
+        if ( (tmp=PyObject_CallMethod(v, "as_Resource", "")) ) {
+                *p_itself = ((ResourceObject *)tmp)->ob_itself;
+                Py_DECREF(tmp);
+                return 1;
+        }
+        PyErr_Clear();
+        PyErr_SetString(PyExc_TypeError, "Resource required");
+        return 0;
+}
+
+
+void init_Res(void)
+{
+	PyObject *m;
+	PyObject *d;
+
+
+
+	        PyMac_INIT_TOOLBOX_OBJECT_NEW(Handle, ResObj_New);
+	        PyMac_INIT_TOOLBOX_OBJECT_CONVERT(Handle, ResObj_Convert);
+	        PyMac_INIT_TOOLBOX_OBJECT_NEW(Handle, OptResObj_New);
+	        PyMac_INIT_TOOLBOX_OBJECT_CONVERT(Handle, OptResObj_Convert);
+
+
+	m = Py_InitModule("_Res", Res_methods);
+	d = PyModule_GetDict(m);
+	Res_Error = PyMac_GetOSErrException();
+	if (Res_Error == NULL ||
+	    PyDict_SetItemString(d, "Error", Res_Error) != 0)
+		return;
+	Resource_Type.ob_type = &PyType_Type;
+	if (PyType_Ready(&Resource_Type) < 0) return;
+	Py_INCREF(&Resource_Type);
+	PyModule_AddObject(m, "Resource", (PyObject *)&Resource_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&Resource_Type);
+	PyModule_AddObject(m, "ResourceType", (PyObject *)&Resource_Type);
+}
+
+/* ======================== End module _Res ========================= */
+

Added: vendor/Python/current/Mac/Modules/res/resedit.py
===================================================================
--- vendor/Python/current/Mac/Modules/res/resedit.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/res/resedit.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,102 @@
+##resource_body = """
+##char *buf;
+##int len;
+##Handle h;
+##
+##if (!PyArg_ParseTuple(_args, "s#", &buf, &len))
+##      return NULL;
+##h = NewHandle(len);
+##if ( h == NULL ) {
+##      PyErr_NoMemory();
+##      return NULL;
+##}
+##HLock(h);
+##memcpy(*h, buf, len);
+##HUnlock(h);
+##_res = ResObj_New(h);
+##return _res;
+##"""
+##
+##f = ManualGenerator("Resource", resource_body)
+##f.docstring = lambda: """Convert a string to a resource object.
+##
+##The created resource object is actually just a handle,
+##apply AddResource() to write it to a resource file.
+##See also the Handle() docstring.
+##"""
+##functions.append(f)
+
+handle_body = """
+char *buf;
+int len;
+Handle h;
+ResourceObject *rv;
+
+if (!PyArg_ParseTuple(_args, "s#", &buf, &len))
+        return NULL;
+h = NewHandle(len);
+if ( h == NULL ) {
+        PyErr_NoMemory();
+        return NULL;
+}
+HLock(h);
+memcpy(*h, buf, len);
+HUnlock(h);
+rv = (ResourceObject *)ResObj_New(h);
+rv->ob_freeit = PyMac_AutoDisposeHandle;
+_res = (PyObject *)rv;
+return _res;
+"""
+
+f = ManualGenerator("Handle", handle_body)
+f.docstring = lambda: """Convert a string to a Handle object.
+
+Resource() and Handle() are very similar, but objects created with Handle() are
+by default automatically DisposeHandle()d upon object cleanup. Use AutoDispose()
+to change this.
+"""
+functions.append(f)
+
+# Convert resources to other things.
+
+as_xxx_body = """
+_res = %sObj_New((%sHandle)_self->ob_itself);
+return _res;
+"""
+
+def genresconverter(longname, shortname):
+
+    f = ManualGenerator("as_%s"%longname, as_xxx_body%(shortname, longname))
+    docstring =  "Return this resource/handle as a %s"%longname
+    f.docstring = lambda docstring=docstring: docstring
+    return f
+
+resmethods.append(genresconverter("Control", "Ctl"))
+resmethods.append(genresconverter("Menu", "Menu"))
+
+# The definition of this one is MacLoadResource, so we do it by hand...
+
+f = ResMethod(void, 'LoadResource',
+    (Handle, 'theResource', InMode),
+)
+resmethods.append(f)
+
+#
+# A method to set the auto-dispose flag
+#
+AutoDispose_body = """
+int onoff, old = 0;
+if (!PyArg_ParseTuple(_args, "i", &onoff))
+        return NULL;
+if ( _self->ob_freeit )
+        old = 1;
+if ( onoff )
+        _self->ob_freeit = PyMac_AutoDisposeHandle;
+else
+        _self->ob_freeit = NULL;
+_res = Py_BuildValue("i", old);
+return _res;
+"""
+f = ManualGenerator("AutoDispose", AutoDispose_body)
+f.docstring = lambda: "(int)->int. Automatically DisposeHandle the object on Python object cleanup"
+resmethods.append(f)

Added: vendor/Python/current/Mac/Modules/res/resscan.py
===================================================================
--- vendor/Python/current/Mac/Modules/res/resscan.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/res/resscan.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,85 @@
+# Scan Resources.h header file, generate resgen.py and Resources.py files.
+# Then run ressupport to generate Resmodule.c.
+# (Should learn how to tell the compiler to compile it as well.)
+
+import sys
+import os
+import string
+import MacOS
+
+from bgenlocations import TOOLBOXDIR, BGENDIR
+sys.path.append(BGENDIR)
+
+from scantools import Scanner
+
+def main():
+    input = "Resources.h"
+    output = "resgen.py"
+    defsoutput = TOOLBOXDIR + "Resources.py"
+    scanner = ResourcesScanner(input, output, defsoutput)
+    scanner.scan()
+    scanner.close()
+    print "=== Testing definitions output code ==="
+    execfile(defsoutput, {}, {})
+    print "=== Done scanning and generating, now doing 'import ressupport' ==="
+    import ressupport
+    print "=== Done 'import ressupport'.  It's up to you to compile Resmodule.c ==="
+
+class ResourcesScanner(Scanner):
+
+    def destination(self, type, name, arglist):
+        classname = "ResFunction"
+        listname = "functions"
+        if arglist:
+            t, n, m = arglist[0]
+            if t == "Handle" and m == "InMode":
+                classname = "ResMethod"
+                listname = "resmethods"
+        return classname, listname
+
+    def makeblacklistnames(self):
+        return [
+                "ReadPartialResource",
+                "WritePartialResource",
+                "TempInsertROMMap",
+##                      "RmveResource",         # RemoveResource
+##                      "SizeResource",         # GetResourceSizeOnDisk
+##                      "MaxSizeRsrc",          # GetMaxResourceSize
+                # OS8 only
+                'RGetResource',
+                'OpenResFile',
+                'CreateResFile',
+                'RsrcZoneInit',
+                'InitResources',
+                'RsrcMapEntry',
+                ]
+
+    def makeblacklisttypes(self):
+        return [
+                ]
+
+    def makerepairinstructions(self):
+        return [
+                ([("Str255", "*", "InMode")],
+                 [("*", "*", "OutMode")]),
+
+                ([("void_ptr", "*", "InMode"), ("long", "*", "InMode")],
+                 [("InBuffer", "*", "*")]),
+
+                ([("void", "*", "OutMode"), ("long", "*", "InMode")],
+                 [("InOutBuffer", "*", "*")]),
+
+                ([("void", "*", "OutMode"), ("long", "*", "InMode"),
+                                            ("long", "*", "OutMode")],
+                 [("OutBuffer", "*", "InOutMode")]),
+
+                ([("SInt8", "*", "*")],
+                 [("SignedByte", "*", "*")]),
+
+
+                ([("UniCharCount", "*", "InMode"), ("UniChar_ptr", "*", "InMode")],
+                 [("UnicodeReverseInBuffer", "*", "*")]),
+                ]
+
+if __name__ == "__main__":
+    main()

Added: vendor/Python/current/Mac/Modules/res/ressupport.py
===================================================================
--- vendor/Python/current/Mac/Modules/res/ressupport.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/res/ressupport.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,221 @@
+# This script will generate the Resources interface for Python.
+# It uses the "bgen" package to generate C code.
+# It execs the file resgen.py which contain the function definitions
+# (resgen.py was generated by resscan.py, scanning the <Resources.h> header file).
+
+from macsupport import *
+
+class ResMixIn:
+
+    def checkit(self):
+        if self.returntype.__class__ != OSErrType:
+            OutLbrace()
+            Output("OSErr _err = ResError();")
+            Output("if (_err != noErr) return PyMac_Error(_err);")
+            OutRbrace()
+        FunctionGenerator.checkit(self) # XXX
+
+class ResFunction(ResMixIn, OSErrWeakLinkFunctionGenerator): pass
+class ResMethod(ResMixIn, OSErrWeakLinkMethodGenerator): pass
+
+RsrcChainLocation = Type("RsrcChainLocation", "h")
+FSCatalogInfoBitmap = FakeType("0") # Type("FSCatalogInfoBitmap", "l")
+FSCatalogInfo_ptr = FakeType("(FSCatalogInfo *)0")
+
+# includestuff etc. are imported from macsupport
+
+includestuff = includestuff + """
+#include <Carbon/Carbon.h>
+
+#ifdef USE_TOOLBOX_OBJECT_GLUE
+extern PyObject *_ResObj_New(Handle);
+extern int _ResObj_Convert(PyObject *, Handle *);
+extern PyObject *_OptResObj_New(Handle);
+extern int _OptResObj_Convert(PyObject *, Handle *);
+#define ResObj_New _ResObj_New
+#define ResObj_Convert _ResObj_Convert
+#define OptResObj_New _OptResObj_New
+#define OptResObj_Convert _OptResObj_Convert
+#endif
+
+/* Function to dispose a resource, with a "normal" calling sequence */
+static void
+PyMac_AutoDisposeHandle(Handle h)
+{
+        DisposeHandle(h);
+}
+"""
+
+finalstuff = finalstuff + """
+
+/* Alternative version of ResObj_New, which returns None for null argument */
+PyObject *OptResObj_New(Handle itself)
+{
+        if (itself == NULL) {
+                Py_INCREF(Py_None);
+                return Py_None;
+        }
+        return ResObj_New(itself);
+}
+
+int OptResObj_Convert(PyObject *v, Handle *p_itself)
+{
+        PyObject *tmp;
+
+        if ( v == Py_None ) {
+                *p_itself = NULL;
+                return 1;
+        }
+        if (ResObj_Check(v))
+        {
+                *p_itself = ((ResourceObject *)v)->ob_itself;
+                return 1;
+        }
+        /* If it isn't a resource yet see whether it is convertible */
+        if ( (tmp=PyObject_CallMethod(v, "as_Resource", "")) ) {
+                *p_itself = ((ResourceObject *)tmp)->ob_itself;
+                Py_DECREF(tmp);
+                return 1;
+        }
+        PyErr_Clear();
+        PyErr_SetString(PyExc_TypeError, "Resource required");
+        return 0;
+}
+"""
+
+initstuff = initstuff + """
+        PyMac_INIT_TOOLBOX_OBJECT_NEW(Handle, ResObj_New);
+        PyMac_INIT_TOOLBOX_OBJECT_CONVERT(Handle, ResObj_Convert);
+        PyMac_INIT_TOOLBOX_OBJECT_NEW(Handle, OptResObj_New);
+        PyMac_INIT_TOOLBOX_OBJECT_CONVERT(Handle, OptResObj_Convert);
+"""
+
+module = MacModule('_Res', 'Res', includestuff, finalstuff, initstuff)
+
+class ResDefinition(PEP253Mixin, GlobalObjectDefinition):
+    getsetlist = [
+            ('data',
+            """
+            PyObject *res;
+            char state;
+
+            state = HGetState(self->ob_itself);
+            HLock(self->ob_itself);
+            res = PyString_FromStringAndSize(
+                    *self->ob_itself,
+                    GetHandleSize(self->ob_itself));
+            HUnlock(self->ob_itself);
+            HSetState(self->ob_itself, state);
+            return res;
+            """,
+            """
+            char *data;
+            long size;
+
+            if ( v == NULL )
+                    return -1;
+            if ( !PyString_Check(v) )
+                    return -1;
+            size = PyString_Size(v);
+            data = PyString_AsString(v);
+            /* XXXX Do I need the GetState/SetState calls? */
+            SetHandleSize(self->ob_itself, size);
+            if ( MemError())
+                    return -1;
+            HLock(self->ob_itself);
+            memcpy((char *)*self->ob_itself, data, size);
+            HUnlock(self->ob_itself);
+            /* XXXX Should I do the Changed call immedeately? */
+            return 0;
+            """,
+            'The resource data'
+            ), (
+            'size',
+            'return PyInt_FromLong(GetHandleSize(self->ob_itself));',
+            None,
+            'The length of the resource data'
+            )]
+
+    def outputCheckNewArg(self):
+        Output("if (itself == NULL) return PyMac_Error(resNotFound);")
+
+    def outputCheckConvertArg(self):
+        # if it isn't a resource we may be able to coerce it
+        Output("if (!%s_Check(v))", self.prefix)
+        OutLbrace()
+        Output("PyObject *tmp;")
+        Output('if ( (tmp=PyObject_CallMethod(v, "as_Resource", "")) )')
+        OutLbrace()
+        Output("*p_itself = ((ResourceObject *)tmp)->ob_itself;")
+        Output("Py_DECREF(tmp);")
+        Output("return 1;")
+        OutRbrace()
+        Output("PyErr_Clear();")
+        OutRbrace()
+
+    def outputStructMembers(self):
+        GlobalObjectDefinition.outputStructMembers(self)
+        Output("void (*ob_freeit)(%s ptr);", self.itselftype)
+
+    def outputInitStructMembers(self):
+        GlobalObjectDefinition.outputInitStructMembers(self)
+        Output("it->ob_freeit = NULL;")
+
+    def outputCleanupStructMembers(self):
+        Output("if (self->ob_freeit && self->ob_itself)")
+        OutLbrace()
+        Output("self->ob_freeit(self->ob_itself);")
+        OutRbrace()
+        Output("self->ob_itself = NULL;")
+
+    def output_tp_newBody(self):
+        Output("PyObject *self;")
+        Output
+        Output("if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;")
+        Output("((%s *)self)->ob_itself = NULL;", self.objecttype)
+        Output("((%s *)self)->ob_freeit = NULL;", self.objecttype)
+        Output("return self;")
+
+    def output_tp_initBody(self):
+        Output("char *srcdata = NULL;")
+        Output("int srclen = 0;")
+        Output("%s itself;", self.itselftype);
+        Output("char *kw[] = {\"itself\", 0};")
+        Output()
+        Output("if (PyArg_ParseTupleAndKeywords(_args, _kwds, \"O&\", kw, %s_Convert, &itself))",
+                self.prefix);
+        OutLbrace()
+        Output("((%s *)_self)->ob_itself = itself;", self.objecttype)
+        Output("return 0;")
+        OutRbrace()
+        Output("PyErr_Clear();")
+        Output("if (!PyArg_ParseTupleAndKeywords(_args, _kwds, \"|s#\", kw, &srcdata, &srclen)) return -1;")
+        Output("if ((itself = NewHandle(srclen)) == NULL)")
+        OutLbrace()
+        Output("PyErr_NoMemory();")
+        Output("return 0;")
+        OutRbrace()
+        Output("((%s *)_self)->ob_itself = itself;", self.objecttype)
+# XXXX          Output("((%s *)self)->ob_freeit = PyMac_AutoDisposeHandle;")
+        Output("if (srclen && srcdata)")
+        OutLbrace()
+        Output("HLock(itself);")
+        Output("memcpy(*itself, srcdata, srclen);")
+        Output("HUnlock(itself);")
+        OutRbrace()
+        Output("return 0;")
+
+resobject = ResDefinition('Resource', 'ResObj', 'Handle')
+module.addobject(resobject)
+
+functions = []
+resmethods = []
+
+execfile('resgen.py')
+execfile('resedit.py')
+
+for f in functions: module.add(f)
+for f in resmethods: resobject.add(f)
+
+SetOutputFileName('_Resmodule.c')
+module.generate()

Added: vendor/Python/current/Mac/Modules/scrap/_Scrapmodule.c
===================================================================
--- vendor/Python/current/Mac/Modules/scrap/_Scrapmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/scrap/_Scrapmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,357 @@
+
+/* ========================= Module _Scrap ========================== */
+
+#include "Python.h"
+
+
+
+#include "pymactoolbox.h"
+
+/* Macro to test whether a weak-loaded CFM function exists */
+#define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL )  {\
+        PyErr_SetString(PyExc_NotImplementedError, \
+        "Not available in this shared library/OS version"); \
+        return NULL; \
+    }} while(0)
+
+
+#include <Carbon/Carbon.h>
+
+static PyObject *Scrap_Error;
+
+/* ----------------------- Object type Scrap ------------------------ */
+
+PyTypeObject Scrap_Type;
+
+#define ScrapObj_Check(x) ((x)->ob_type == &Scrap_Type || PyObject_TypeCheck((x), &Scrap_Type))
+
+typedef struct ScrapObject {
+	PyObject_HEAD
+	ScrapRef ob_itself;
+} ScrapObject;
+
+PyObject *ScrapObj_New(ScrapRef itself)
+{
+	ScrapObject *it;
+	it = PyObject_NEW(ScrapObject, &Scrap_Type);
+	if (it == NULL) return NULL;
+	it->ob_itself = itself;
+	return (PyObject *)it;
+}
+int ScrapObj_Convert(PyObject *v, ScrapRef *p_itself)
+{
+	if (!ScrapObj_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "Scrap required");
+		return 0;
+	}
+	*p_itself = ((ScrapObject *)v)->ob_itself;
+	return 1;
+}
+
+static void ScrapObj_dealloc(ScrapObject *self)
+{
+	/* Cleanup of self->ob_itself goes here */
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *ScrapObj_GetScrapFlavorFlags(ScrapObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	ScrapFlavorType flavorType;
+	ScrapFlavorFlags flavorFlags;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetOSType, &flavorType))
+		return NULL;
+	_err = GetScrapFlavorFlags(_self->ob_itself,
+	                           flavorType,
+	                           &flavorFlags);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     flavorFlags);
+	return _res;
+}
+
+static PyObject *ScrapObj_GetScrapFlavorSize(ScrapObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	ScrapFlavorType flavorType;
+	Size byteCount;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetOSType, &flavorType))
+		return NULL;
+	_err = GetScrapFlavorSize(_self->ob_itself,
+	                          flavorType,
+	                          &byteCount);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     byteCount);
+	return _res;
+}
+
+static PyObject *ScrapObj_GetScrapFlavorData(ScrapObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	ScrapFlavorType flavorType;
+	Size byteCount;
+
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetOSType, &flavorType))
+		return NULL;
+	_err = GetScrapFlavorSize(_self->ob_itself,
+	                          flavorType,
+	                          &byteCount);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = PyString_FromStringAndSize(NULL, (int)byteCount);
+	if ( _res == NULL ) return NULL;
+	_err = GetScrapFlavorData(_self->ob_itself,
+	                          flavorType,
+	                          &byteCount,
+	                          PyString_AS_STRING(_res));
+	if (_err != noErr) {
+		Py_XDECREF(_res);
+		return PyMac_Error(_err);
+	}
+	return _res;
+}
+
+static PyObject *ScrapObj_PutScrapFlavor(ScrapObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	ScrapFlavorType flavorType;
+	ScrapFlavorFlags flavorFlags;
+	char *flavorData__in__;
+	int flavorData__in_len__;
+	if (!PyArg_ParseTuple(_args, "O&Ks#",
+	                      PyMac_GetOSType, &flavorType,
+	                      &flavorFlags,
+	                      &flavorData__in__, &flavorData__in_len__))
+		return NULL;
+	_err = PutScrapFlavor(_self->ob_itself,
+	                      flavorType,
+	                      flavorFlags,
+	                      (Size)flavorData__in_len__,
+	                      flavorData__in__);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *ScrapObj_GetScrapFlavorCount(ScrapObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 infoCount;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetScrapFlavorCount(_self->ob_itself,
+	                           &infoCount);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     infoCount);
+	return _res;
+}
+
+static PyObject *ScrapObj_GetScrapFlavorInfoList(ScrapObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PyObject *item;
+	OSStatus _err;
+	UInt32 infoCount;
+	ScrapFlavorInfo *infolist = NULL;
+	int i;
+	
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetScrapFlavorCount(_self->ob_itself,
+	                           &infoCount);
+	if (_err != noErr) return PyMac_Error(_err);
+	if (infoCount == 0) return Py_BuildValue("[]");
+	
+	if ((infolist = (ScrapFlavorInfo *)malloc(infoCount*sizeof(ScrapFlavorInfo))) == NULL )
+		return PyErr_NoMemory();
+	
+	_err = GetScrapFlavorInfoList(_self->ob_itself, &infoCount, infolist);
+	if (_err != noErr) {
+		free(infolist);
+		return NULL;
+	}
+	if ((_res = PyList_New(infoCount)) == NULL ) {
+		free(infolist);
+		return NULL;
+	}
+	for(i=0; i<infoCount; i++) {
+		item = Py_BuildValue("O&l", PyMac_BuildOSType, infolist[i].flavorType,
+			infolist[i].flavorFlags);
+		if ( !item || PyList_SetItem(_res, i, item) < 0 ) {
+			Py_DECREF(_res);
+			free(infolist);
+			return NULL;
+		}
+	}
+	free(infolist);
+	return _res;
+}
+
+static PyMethodDef ScrapObj_methods[] = {
+	{"GetScrapFlavorFlags", (PyCFunction)ScrapObj_GetScrapFlavorFlags, 1,
+	 PyDoc_STR("(ScrapFlavorType flavorType) -> (ScrapFlavorFlags flavorFlags)")},
+	{"GetScrapFlavorSize", (PyCFunction)ScrapObj_GetScrapFlavorSize, 1,
+	 PyDoc_STR("(ScrapFlavorType flavorType) -> (Size byteCount)")},
+	{"GetScrapFlavorData", (PyCFunction)ScrapObj_GetScrapFlavorData, 1,
+	 PyDoc_STR("(ScrapFlavorType flavorType, Buffer destination) -> (Size byteCount)")},
+	{"PutScrapFlavor", (PyCFunction)ScrapObj_PutScrapFlavor, 1,
+	 PyDoc_STR("(ScrapFlavorType flavorType, ScrapFlavorFlags flavorFlags, Size flavorSize, Buffer flavorData) -> None")},
+	{"GetScrapFlavorCount", (PyCFunction)ScrapObj_GetScrapFlavorCount, 1,
+	 PyDoc_STR("() -> (UInt32 infoCount)")},
+	{"GetScrapFlavorInfoList", (PyCFunction)ScrapObj_GetScrapFlavorInfoList, 1,
+	 PyDoc_STR("() -> ([(ScrapFlavorType, ScrapFlavorInfo), ...])")},
+	{NULL, NULL, 0}
+};
+
+PyMethodChain ScrapObj_chain = { ScrapObj_methods, NULL };
+
+static PyObject *ScrapObj_getattr(ScrapObject *self, char *name)
+{
+	return Py_FindMethodInChain(&ScrapObj_chain, (PyObject *)self, name);
+}
+
+#define ScrapObj_setattr NULL
+
+#define ScrapObj_compare NULL
+
+#define ScrapObj_repr NULL
+
+#define ScrapObj_hash NULL
+
+PyTypeObject Scrap_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"_Scrap.Scrap", /*tp_name*/
+	sizeof(ScrapObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) ScrapObj_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc) ScrapObj_getattr, /*tp_getattr*/
+	(setattrfunc) ScrapObj_setattr, /*tp_setattr*/
+	(cmpfunc) ScrapObj_compare, /*tp_compare*/
+	(reprfunc) ScrapObj_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) ScrapObj_hash, /*tp_hash*/
+};
+
+/* --------------------- End object type Scrap ---------------------- */
+
+static PyObject *Scrap_LoadScrap(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = LoadScrap();
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Scrap_UnloadScrap(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = UnloadScrap();
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Scrap_GetCurrentScrap(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	ScrapRef scrap;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetCurrentScrap(&scrap);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     ScrapObj_New, scrap);
+	return _res;
+}
+
+static PyObject *Scrap_ClearCurrentScrap(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = ClearCurrentScrap();
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Scrap_CallInScrapPromises(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = CallInScrapPromises();
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyMethodDef Scrap_methods[] = {
+	{"LoadScrap", (PyCFunction)Scrap_LoadScrap, 1,
+	 PyDoc_STR("() -> None")},
+	{"UnloadScrap", (PyCFunction)Scrap_UnloadScrap, 1,
+	 PyDoc_STR("() -> None")},
+	{"GetCurrentScrap", (PyCFunction)Scrap_GetCurrentScrap, 1,
+	 PyDoc_STR("() -> (ScrapRef scrap)")},
+	{"ClearCurrentScrap", (PyCFunction)Scrap_ClearCurrentScrap, 1,
+	 PyDoc_STR("() -> None")},
+	{"CallInScrapPromises", (PyCFunction)Scrap_CallInScrapPromises, 1,
+	 PyDoc_STR("() -> None")},
+	{NULL, NULL, 0}
+};
+
+
+
+
+void init_Scrap(void)
+{
+	PyObject *m;
+	PyObject *d;
+
+
+
+
+	m = Py_InitModule("_Scrap", Scrap_methods);
+	d = PyModule_GetDict(m);
+	Scrap_Error = PyMac_GetOSErrException();
+	if (Scrap_Error == NULL ||
+	    PyDict_SetItemString(d, "Error", Scrap_Error) != 0)
+		return;
+	Scrap_Type.ob_type = &PyType_Type;
+	Py_INCREF(&Scrap_Type);
+	if (PyDict_SetItemString(d, "ScrapType", (PyObject *)&Scrap_Type) != 0)
+		Py_FatalError("can't initialize ScrapType");
+}
+
+/* ======================= End module _Scrap ======================== */
+

Added: vendor/Python/current/Mac/Modules/scrap/scrapscan.py
===================================================================
--- vendor/Python/current/Mac/Modules/scrap/scrapscan.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/scrap/scrapscan.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,61 @@
+# Scan an Apple header file, generating a Python file of generator calls.
+#
+# Note that the scrap-manager include file is so weird that this
+# generates a boilerplate to be edited by hand.
+
+import sys
+import os
+from bgenlocations import TOOLBOXDIR, BGENDIR
+sys.path.append(BGENDIR)
+from scantools import Scanner
+
+LONG = "Scrap"
+SHORT = "scrap"
+
+def main():
+    input = "Scrap.h"
+    output = SHORT + "gen.py"
+    defsoutput = "@Scrap.py"
+    scanner = MyScanner(input, output, defsoutput)
+    scanner.scan()
+    scanner.close()
+##      print "=== Testing definitions output code ==="
+##      execfile(defsoutput, {}, {})
+    print "=== Done scanning and generating, now importing the generated code... ==="
+    exec "import " + SHORT + "support"
+    print "=== Done.  It's up to you to compile it now! ==="
+
+class MyScanner(Scanner):
+
+    def destination(self, type, name, arglist):
+        classname = "Function"
+        listname = "functions"
+        if arglist:
+            t, n, m = arglist[0]
+            if t == 'ScrapRef' and m == "InMode":
+                classname = "Method"
+                listname = "methods"
+        return classname, listname
+
+    def makeblacklistnames(self):
+        return [
+                "GetScrapFlavorInfoList",
+                'InfoScrap',
+                'GetScrap',
+                'ZeroScrap',
+                'PutScrap',
+                ]
+
+    def makeblacklisttypes(self):
+        return [
+                'ScrapPromiseKeeperUPP',
+                ]
+
+    def makerepairinstructions(self):
+        return [
+                ([('void', '*', 'OutMode')], [('putscrapbuffer', '*', 'InMode')]),
+                ([('void_ptr', '*', 'InMode')], [('putscrapbuffer', '*', 'InMode')]),
+                ]
+
+if __name__ == "__main__":
+    main()

Added: vendor/Python/current/Mac/Modules/scrap/scrapsupport.py
===================================================================
--- vendor/Python/current/Mac/Modules/scrap/scrapsupport.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/scrap/scrapsupport.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,75 @@
+# This script generates a Python interface for an Apple Macintosh Manager.
+# It uses the "bgen" package to generate C code.
+# The function specifications are generated by scanning the mamager's header file,
+# using the "scantools" package (customized for this particular manager).
+
+# NOTE: the scrap include file is so bad that the bgen output has to be
+# massaged by hand.
+
+import string
+
+# Declarations that change for each manager
+MACHEADERFILE = 'Scrap.h'               # The Apple header file
+MODNAME = '_Scrap'                              # The name of the module
+OBJECTNAME = 'Scrap'                    # The basic name of the objects used here
+
+# The following is *usually* unchanged but may still require tuning
+MODPREFIX = 'Scrap'                     # The prefix for module-wide routines
+OBJECTTYPE = OBJECTNAME + 'Ref' # The C type used to represent them
+OBJECTPREFIX = MODPREFIX + 'Obj'        # The prefix for object methods
+INPUTFILE = string.lower(MODPREFIX) + 'gen.py' # The file generated by the scanner
+OUTPUTFILE = '@' + MODNAME + "module.c" # The file generated by this program
+
+from macsupport import *
+
+# Create the type objects
+ScrapRef = OpaqueByValueType(OBJECTTYPE, OBJECTPREFIX)
+
+includestuff = includestuff + """
+#include <Carbon/Carbon.h>
+
+/*
+** Generate ScrapInfo records
+*/
+static PyObject *
+SCRRec_New(itself)
+        ScrapStuff *itself;
+{
+
+        return Py_BuildValue("lO&hhO&", itself->scrapSize,
+                ResObj_New, itself->scrapHandle, itself->scrapCount, itself->scrapState,
+                PyMac_BuildStr255, itself->scrapName);
+}
+"""
+
+ScrapStuffPtr = OpaqueByValueType('ScrapStuffPtr', 'SCRRec')
+ScrapFlavorType = OSTypeType('ScrapFlavorType')
+ScrapFlavorFlags = Type('ScrapFlavorFlags', 'l')
+#ScrapFlavorInfo = OpaqueType('ScrapFlavorInfo', 'ScrapFlavorInfo')
+putscrapbuffer = FixedInputBufferType('void *')
+
+class MyObjectDefinition(PEP253Mixin, GlobalObjectDefinition):
+    pass
+
+# Create the generator groups and link them
+module = MacModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff)
+object = MyObjectDefinition(OBJECTNAME, OBJECTPREFIX, OBJECTTYPE)
+module.addobject(object)
+
+# Create the generator classes used to populate the lists
+Function = OSErrFunctionGenerator
+Method = OSErrMethodGenerator
+
+# Create and populate the lists
+functions = []
+methods = []
+execfile(INPUTFILE)
+
+# add the populated lists to the generator groups
+# (in a different wordl the scan program would generate this)
+for f in functions: module.add(f)
+for f in methods: object.add(f)
+
+# generate output (open the output file as late as possible)
+SetOutputFileName(OUTPUTFILE)
+module.generate()

Added: vendor/Python/current/Mac/Modules/snd/_Sndihooks.c
===================================================================
--- vendor/Python/current/Mac/Modules/snd/_Sndihooks.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/snd/_Sndihooks.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,512 @@
+/***********************************************************
+Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
+The Netherlands.
+
+                        All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the names of Stichting Mathematisch
+Centrum or CWI or Corporation for National Research Initiatives or
+CNRI not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+While CWI is the initial source for this software, a modified version
+is made available by the Corporation for National Research Initiatives
+(CNRI) at the Internet address ftp://ftp.python.org.
+
+STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
+CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+
+******************************************************************/
+
+#include "Python.h"
+#include "pymactoolbox.h"
+#include <Sound.h>
+
+#pragma options align=mac68k
+struct SampleRateAvailable_arg {
+	short	numrates;
+	Handle	rates;
+};
+
+struct SampleSizeAvailable_arg {
+	short	numsizes;
+	Handle	sizes;
+};
+
+#pragma options align=reset
+
+static PyObject *ErrorObject;
+
+
+/* Convert Python object to unsigned Fixed */
+static int
+PyMac_GetUFixed(PyObject *v, Fixed *f)
+{
+	double d;
+	unsigned long uns;
+	
+	if( !PyArg_Parse(v, "d", &d))
+		return 0;
+	uns = (unsigned long)(d * 0x10000);
+	*f = (Fixed)uns;
+	return 1;
+}
+
+/* Convert a Point to a Python object */
+static PyObject *
+PyMac_BuildUFixed(Fixed f)
+{
+	double d;
+	unsigned long funs;
+	
+	funs = (unsigned long)f;
+	
+	d = funs;
+	d = d / 0x10000;
+	return Py_BuildValue("d", d);
+}
+
+
+/* ----------------------------------------------------- */
+
+static char sndih_getChannelAvailable__doc__[] =
+""
+;
+
+static PyObject *
+sndih_getChannelAvailable(self, args)
+	PyObject *self;	/* Not used */
+	PyObject *args;
+{
+	long inRefNum;
+	short nchannel;
+	OSErr err;
+
+	if (!PyArg_ParseTuple(args, "l", &inRefNum))
+		return NULL;
+	
+	if( (err=SPBGetDeviceInfo(inRefNum, siChannelAvailable, (Ptr)&nchannel)) != noErr )
+		return PyMac_Error(err);
+	return Py_BuildValue("h", nchannel);
+}
+
+static char sndih_getNumberChannels__doc__[] =
+""
+;
+
+static PyObject *
+sndih_getNumberChannels(self, args)
+	PyObject *self;	/* Not used */
+	PyObject *args;
+{
+	long inRefNum;
+	short nchannel;
+	OSErr err;
+
+	if (!PyArg_ParseTuple(args, "l", &inRefNum))
+		return NULL;
+	
+	if( (err=SPBGetDeviceInfo(inRefNum, siNumberChannels, (Ptr)&nchannel)) != noErr )
+		return PyMac_Error(err);
+	return Py_BuildValue("h", nchannel);
+}
+
+static char sndih_setNumberChannels__doc__[] =
+""
+;
+
+static PyObject *
+sndih_setNumberChannels(self, args)
+	PyObject *self;	/* Not used */
+	PyObject *args;
+{
+	long inRefNum;
+	short nchannel;
+	OSErr err;
+
+	if (!PyArg_ParseTuple(args, "lh", &inRefNum, &nchannel))
+		return NULL;
+	
+	if( (err=SPBSetDeviceInfo(inRefNum, siNumberChannels, (Ptr)&nchannel)) != noErr )
+		return PyMac_Error(err);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static char sndih_getContinuous__doc__[] =
+""
+;
+
+static PyObject *
+sndih_getContinuous(self, args)
+	PyObject *self;	/* Not used */
+	PyObject *args;
+{
+	long inRefNum;
+	short onoff;
+	OSErr err;
+
+	if (!PyArg_ParseTuple(args, "l", &inRefNum))
+		return NULL;
+	
+	if( (err=SPBGetDeviceInfo(inRefNum, siContinuous, (Ptr)&onoff)) != noErr )
+		return PyMac_Error(err);
+	return Py_BuildValue("h", onoff);
+}
+
+static char sndih_setContinuous__doc__[] =
+""
+;
+
+static PyObject *
+sndih_setContinuous(self, args)
+	PyObject *self;	/* Not used */
+	PyObject *args;
+{
+	long inRefNum;
+	short onoff;
+	OSErr err;
+
+	if (!PyArg_ParseTuple(args, "lh", &inRefNum, &onoff))
+		return NULL;
+	
+	if( (err=SPBSetDeviceInfo(inRefNum, siContinuous, (Ptr)&onoff)) != noErr )
+		return PyMac_Error(err);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static char sndih_getInputSourceNames__doc__[] =
+""
+;
+
+static PyObject *
+sndih_getInputSourceNames(self, args)
+	PyObject *self;	/* Not used */
+	PyObject *args;
+{
+	long inRefNum;
+	Handle names;
+	OSErr err;
+
+	if (!PyArg_ParseTuple(args, "l", &inRefNum))
+		return NULL;
+	
+	if( (err=SPBGetDeviceInfo(inRefNum, siInputSourceNames, (Ptr)&names)) != noErr )
+		return PyMac_Error(err);
+	return Py_BuildValue("O&", ResObj_New, names);
+}
+
+static char sndih_getInputSource__doc__[] =
+""
+;
+
+static PyObject *
+sndih_getInputSource(self, args)
+	PyObject *self;	/* Not used */
+	PyObject *args;
+{
+	long inRefNum;
+	short source;
+	OSErr err;
+
+	if (!PyArg_ParseTuple(args, "l", &inRefNum))
+		return NULL;
+	
+	if( (err=SPBGetDeviceInfo(inRefNum, siInputSource, (Ptr)&source)) != noErr )
+		return PyMac_Error(err);
+	return Py_BuildValue("h", source);
+}
+
+static char sndih_setInputSource__doc__[] =
+""
+;
+
+static PyObject *
+sndih_setInputSource(self, args)
+	PyObject *self;	/* Not used */
+	PyObject *args;
+{
+	long inRefNum;
+	short source;
+	OSErr err;
+
+	if (!PyArg_ParseTuple(args, "lh", &inRefNum, &source))
+		return NULL;
+	
+	if( (err=SPBSetDeviceInfo(inRefNum, siInputSource, (Ptr)&source)) != noErr )
+		return PyMac_Error(err);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static char sndih_getPlayThruOnOff__doc__[] =
+""
+;
+
+static PyObject *
+sndih_getPlayThruOnOff(self, args)
+	PyObject *self;	/* Not used */
+	PyObject *args;
+{
+	long inRefNum;
+	short onoff;
+	OSErr err;
+
+	if (!PyArg_ParseTuple(args, "l", &inRefNum))
+		return NULL;
+	
+	if( (err=SPBGetDeviceInfo(inRefNum, siPlayThruOnOff, (Ptr)&onoff)) != noErr )
+		return PyMac_Error(err);
+	return Py_BuildValue("h", onoff);
+}
+
+static char sndih_setPlayThruOnOff__doc__[] =
+""
+;
+
+static PyObject *
+sndih_setPlayThruOnOff(self, args)
+	PyObject *self;	/* Not used */
+	PyObject *args;
+{
+	long inRefNum;
+	short onoff;
+	OSErr err;
+
+	if (!PyArg_ParseTuple(args, "lh", &inRefNum, &onoff))
+		return NULL;
+	
+	if( (err=SPBSetDeviceInfo(inRefNum, siPlayThruOnOff, (Ptr)&onoff)) != noErr )
+		return PyMac_Error(err);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static char sndih_getSampleRate__doc__[] =
+""
+;
+
+static PyObject *
+sndih_getSampleRate(self, args)
+	PyObject *self;	/* Not used */
+	PyObject *args;
+{
+	long inRefNum;
+	Fixed sample_rate;
+	OSErr err;
+
+	if (!PyArg_ParseTuple(args, "l", &inRefNum))
+		return NULL;
+	
+	if( (err=SPBGetDeviceInfo(inRefNum, siSampleRate, (Ptr)&sample_rate)) != noErr )
+		return PyMac_Error(err);
+	return Py_BuildValue("O&", PyMac_BuildUFixed, sample_rate);
+}
+
+static char sndih_setSampleRate__doc__[] =
+""
+;
+
+static PyObject *
+sndih_setSampleRate(self, args)
+	PyObject *self;	/* Not used */
+	PyObject *args;
+{
+	long inRefNum;
+	Fixed sample_rate;
+	OSErr err;
+
+	if (!PyArg_ParseTuple(args, "lO&", &inRefNum, PyMac_GetUFixed, &sample_rate))
+		return NULL;
+	
+	if( (err=SPBSetDeviceInfo(inRefNum, siSampleRate, (Ptr)&sample_rate)) != noErr )
+		return PyMac_Error(err);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static char sndih_getSampleSize__doc__[] =
+""
+;
+
+static PyObject *
+sndih_getSampleSize(self, args)
+	PyObject *self;	/* Not used */
+	PyObject *args;
+{
+	long inRefNum;
+	short bits;
+	OSErr err;
+
+	if (!PyArg_ParseTuple(args, "l", &inRefNum))
+		return NULL;
+	
+	if( (err=SPBGetDeviceInfo(inRefNum, siSampleSize, (Ptr)&bits)) != noErr )
+		return PyMac_Error(err);
+	return Py_BuildValue("h", bits);
+}
+
+static char sndih_setSampleSize__doc__[] =
+""
+;
+
+static PyObject *
+sndih_setSampleSize(self, args)
+	PyObject *self;	/* Not used */
+	PyObject *args;
+{
+	long inRefNum;
+	short size;
+	OSErr err;
+
+	if (!PyArg_ParseTuple(args, "lh", &inRefNum, &size))
+		return NULL;
+	
+	if( (err=SPBSetDeviceInfo(inRefNum, siSampleSize, (Ptr)&size)) != noErr )
+		return PyMac_Error(err);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static char sndih_getSampleSizeAvailable__doc__[] =
+""
+;
+
+static PyObject *
+sndih_getSampleSizeAvailable(self, args)
+	PyObject *self;	/* Not used */
+	PyObject *args;
+{
+	long inRefNum;
+	struct SampleSizeAvailable_arg arg;
+	OSErr err;
+	PyObject *rsizes;
+	short *fsizes;
+	int i;
+
+	arg.sizes = NULL;
+	rsizes = NULL;
+	if (!PyArg_ParseTuple(args, "l", &inRefNum))
+		return NULL;
+	
+	if( (err=SPBGetDeviceInfo(inRefNum, siSampleSizeAvailable, (Ptr)&arg)) != noErr ) {
+		return PyMac_Error(err);
+	}
+	fsizes = (short *)*(arg.sizes);
+	/* Handle contains a list of rates */
+	if( (rsizes = PyTuple_New(arg.numsizes)) == NULL)
+		return NULL;
+	for( i=0; i<arg.numsizes; i++ )
+		PyTuple_SetItem(rsizes, i, PyInt_FromLong((long)fsizes[i]));
+	return rsizes;
+}
+
+static char sndih_getSampleRateAvailable__doc__[] =
+""
+;
+
+static PyObject *
+sndih_getSampleRateAvailable(self, args)
+	PyObject *self;	/* Not used */
+	PyObject *args;
+{
+	long inRefNum;
+	struct SampleRateAvailable_arg arg;
+	OSErr err;
+	PyObject *rrates, *obj;
+	Fixed *frates;
+	int i;
+
+	arg.rates = NULL;
+	rrates = NULL;
+	if (!PyArg_ParseTuple(args, "l", &inRefNum))
+		return NULL;
+	
+	if( (err=SPBGetDeviceInfo(inRefNum, siSampleRateAvailable, (Ptr)&arg)) != noErr ) {
+		return PyMac_Error(err);
+	}
+	frates = (Fixed *)*(arg.rates);
+	if( arg.numrates == 0 ) {
+		/* The handle contains upper and lowerbound */
+		rrates = Py_BuildValue("O&O&", frates[0], frates[1]);
+		if (rrates == NULL) return NULL;
+	} else {
+		/* Handle contains a list of rates */
+		if( (rrates = PyTuple_New(arg.numrates)) == NULL)
+			return NULL;
+		for( i=0; i<arg.numrates; i++ ) {
+			if( (obj = Py_BuildValue("O&", PyMac_BuildUFixed, frates[i]))==NULL)
+				goto out;
+			PyTuple_SetItem(rrates, i, obj);
+		}
+	}
+	return Py_BuildValue("hO", arg.numrates, rrates);
+out:
+	Py_XDECREF(rrates);
+	return NULL;
+}
+
+/* List of methods defined in the module */
+
+static struct PyMethodDef sndih_methods[] = {
+ {"getChannelAvailable",	(PyCFunction)sndih_getChannelAvailable,	METH_VARARGS,	sndih_getChannelAvailable__doc__},
+ {"getNumberChannels",	(PyCFunction)sndih_getNumberChannels,	METH_VARARGS,	sndih_getNumberChannels__doc__},
+ {"setNumberChannels",	(PyCFunction)sndih_setNumberChannels,	METH_VARARGS,	sndih_setNumberChannels__doc__},
+ {"getContinuous",	(PyCFunction)sndih_getContinuous,	METH_VARARGS,	sndih_getContinuous__doc__},
+ {"setContinuous",	(PyCFunction)sndih_setContinuous,	METH_VARARGS,	sndih_setContinuous__doc__},
+ {"getInputSourceNames",	(PyCFunction)sndih_getInputSourceNames,	METH_VARARGS,	sndih_getInputSourceNames__doc__},
+ {"getInputSource",	(PyCFunction)sndih_getInputSource,	METH_VARARGS,	sndih_getInputSource__doc__},
+ {"setInputSource",	(PyCFunction)sndih_setInputSource,	METH_VARARGS,	sndih_setInputSource__doc__},
+ {"getPlayThruOnOff",	(PyCFunction)sndih_getPlayThruOnOff,	METH_VARARGS,	sndih_getPlayThruOnOff__doc__},
+ {"setPlayThruOnOff",	(PyCFunction)sndih_setPlayThruOnOff,	METH_VARARGS,	sndih_setPlayThruOnOff__doc__},
+ {"getSampleRate",	(PyCFunction)sndih_getSampleRate,	METH_VARARGS,	sndih_getSampleRate__doc__},
+ {"setSampleRate",	(PyCFunction)sndih_setSampleRate,	METH_VARARGS,	sndih_setSampleRate__doc__},
+ {"getSampleSize",	(PyCFunction)sndih_getSampleSize,	METH_VARARGS,	sndih_getSampleSize__doc__},
+ {"setSampleSize",	(PyCFunction)sndih_setSampleSize,	METH_VARARGS,	sndih_setSampleSize__doc__},
+ {"getSampleSizeAvailable",	(PyCFunction)sndih_getSampleSizeAvailable,	METH_VARARGS,	sndih_getSampleSizeAvailable__doc__},
+ {"getSampleRateAvailable",	(PyCFunction)sndih_getSampleRateAvailable,	METH_VARARGS,	sndih_getSampleRateAvailable__doc__},
+ 
+	{NULL,	 (PyCFunction)NULL, 0, NULL}		/* sentinel */
+};
+
+
+/* Initialization function for the module (*must* be called initSndihooks) */
+
+static char Sndihooks_module_documentation[] = 
+""
+;
+
+void
+init_Sndihooks()
+{
+	PyObject *m, *d;
+
+	/* Create the module and add the functions */
+	m = Py_InitModule4("_Sndihooks", sndih_methods,
+		Sndihooks_module_documentation,
+		(PyObject*)NULL,PYTHON_API_VERSION);
+
+	/* Add some symbolic constants to the module */
+	d = PyModule_GetDict(m);
+	ErrorObject = PyString_FromString("Sndihooks.error");
+	PyDict_SetItemString(d, "error", ErrorObject);
+
+	/* XXXX Add constants here */
+	
+	/* Check for errors */
+	if (PyErr_Occurred())
+		Py_FatalError("can't initialize module Sndihooks");
+}
+

Added: vendor/Python/current/Mac/Modules/snd/_Sndmodule.c
===================================================================
--- vendor/Python/current/Mac/Modules/snd/_Sndmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/snd/_Sndmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1151 @@
+
+/* ========================== Module _Snd =========================== */
+
+#include "Python.h"
+
+
+
+#include "pymactoolbox.h"
+
+/* Macro to test whether a weak-loaded CFM function exists */
+#define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL )  {\
+        PyErr_SetString(PyExc_NotImplementedError, \
+        "Not available in this shared library/OS version"); \
+        return NULL; \
+    }} while(0)
+
+
+#include <Carbon/Carbon.h>
+
+/* Convert a SndCommand argument */
+static int
+SndCmd_Convert(PyObject *v, SndCommand *pc)
+{
+        int len;
+        pc->param1 = 0;
+        pc->param2 = 0;
+        if (PyTuple_Check(v)) {
+                if (PyArg_ParseTuple(v, "h|hl", &pc->cmd, &pc->param1, &pc->param2))
+                        return 1;
+                PyErr_Clear();
+                return PyArg_ParseTuple(v, "Hhs#", &pc->cmd, &pc->param1, &pc->param2, &len);
+        }
+        return PyArg_Parse(v, "H", &pc->cmd);
+}
+
+static pascal void SndCh_UserRoutine(SndChannelPtr chan, SndCommand *cmd); /* Forward */
+static pascal void SPB_completion(SPBPtr my_spb); /* Forward */
+
+static PyObject *Snd_Error;
+
+/* --------------------- Object type SndChannel --------------------- */
+
+static PyTypeObject SndChannel_Type;
+
+#define SndCh_Check(x) ((x)->ob_type == &SndChannel_Type || PyObject_TypeCheck((x), &SndChannel_Type))
+
+typedef struct SndChannelObject {
+	PyObject_HEAD
+	SndChannelPtr ob_itself;
+	/* Members used to implement callbacks: */
+	PyObject *ob_callback;
+	long ob_A5;
+	SndCommand ob_cmd;
+} SndChannelObject;
+
+static PyObject *SndCh_New(SndChannelPtr itself)
+{
+	SndChannelObject *it;
+	it = PyObject_NEW(SndChannelObject, &SndChannel_Type);
+	if (it == NULL) return NULL;
+	it->ob_itself = itself;
+	it->ob_callback = NULL;
+	it->ob_A5 = SetCurrentA5();
+	return (PyObject *)it;
+}
+
+static void SndCh_dealloc(SndChannelObject *self)
+{
+	SndDisposeChannel(self->ob_itself, 1);
+	Py_XDECREF(self->ob_callback);
+	PyObject_Free((PyObject *)self);
+}
+
+static PyObject *SndCh_SndDoCommand(SndChannelObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SndCommand cmd;
+	Boolean noWait;
+	if (!PyArg_ParseTuple(_args, "O&b",
+	                      SndCmd_Convert, &cmd,
+	                      &noWait))
+		return NULL;
+	_err = SndDoCommand(_self->ob_itself,
+	                    &cmd,
+	                    noWait);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *SndCh_SndDoImmediate(SndChannelObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SndCommand cmd;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      SndCmd_Convert, &cmd))
+		return NULL;
+	_err = SndDoImmediate(_self->ob_itself,
+	                      &cmd);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *SndCh_SndPlay(SndChannelObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SndListHandle sndHandle;
+	Boolean async;
+	if (!PyArg_ParseTuple(_args, "O&b",
+	                      ResObj_Convert, &sndHandle,
+	                      &async))
+		return NULL;
+	_err = SndPlay(_self->ob_itself,
+	               sndHandle,
+	               async);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *SndCh_SndChannelStatus(SndChannelObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short theLength;
+	SCStatus theStatus__out__;
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &theLength))
+		return NULL;
+	_err = SndChannelStatus(_self->ob_itself,
+	                        theLength,
+	                        &theStatus__out__);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("s#",
+	                     (char *)&theStatus__out__, (int)sizeof(SCStatus));
+	return _res;
+}
+
+static PyObject *SndCh_SndGetInfo(SndChannelObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	OSType selector;
+	void * infoPtr;
+	if (!PyArg_ParseTuple(_args, "O&w",
+	                      PyMac_GetOSType, &selector,
+	                      &infoPtr))
+		return NULL;
+	_err = SndGetInfo(_self->ob_itself,
+	                  selector,
+	                  infoPtr);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *SndCh_SndSetInfo(SndChannelObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	OSType selector;
+	void * infoPtr;
+	if (!PyArg_ParseTuple(_args, "O&w",
+	                      PyMac_GetOSType, &selector,
+	                      &infoPtr))
+		return NULL;
+	_err = SndSetInfo(_self->ob_itself,
+	                  selector,
+	                  infoPtr);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyMethodDef SndCh_methods[] = {
+	{"SndDoCommand", (PyCFunction)SndCh_SndDoCommand, 1,
+	 PyDoc_STR("(SndCommand cmd, Boolean noWait) -> None")},
+	{"SndDoImmediate", (PyCFunction)SndCh_SndDoImmediate, 1,
+	 PyDoc_STR("(SndCommand cmd) -> None")},
+	{"SndPlay", (PyCFunction)SndCh_SndPlay, 1,
+	 PyDoc_STR("(SndListHandle sndHandle, Boolean async) -> None")},
+	{"SndChannelStatus", (PyCFunction)SndCh_SndChannelStatus, 1,
+	 PyDoc_STR("(short theLength) -> (SCStatus theStatus)")},
+	{"SndGetInfo", (PyCFunction)SndCh_SndGetInfo, 1,
+	 PyDoc_STR("(OSType selector, void * infoPtr) -> None")},
+	{"SndSetInfo", (PyCFunction)SndCh_SndSetInfo, 1,
+	 PyDoc_STR("(OSType selector, void * infoPtr) -> None")},
+	{NULL, NULL, 0}
+};
+
+#define SndCh_getsetlist NULL
+
+
+#define SndCh_compare NULL
+
+#define SndCh_repr NULL
+
+#define SndCh_hash NULL
+
+static PyTypeObject SndChannel_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"_Snd.SndChannel", /*tp_name*/
+	sizeof(SndChannelObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) SndCh_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) SndCh_compare, /*tp_compare*/
+	(reprfunc) SndCh_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) SndCh_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	SndCh_methods, /* tp_methods */
+	0, /*tp_members*/
+	SndCh_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	0, /*tp_init*/
+	0, /*tp_alloc*/
+	0, /*tp_new*/
+	0, /*tp_free*/
+};
+
+/* ------------------- End object type SndChannel ------------------- */
+
+
+/* ------------------------ Object type SPB ------------------------- */
+
+static PyTypeObject SPB_Type;
+
+#define SPBObj_Check(x) ((x)->ob_type == &SPB_Type || PyObject_TypeCheck((x), &SPB_Type))
+
+typedef struct SPBObject {
+	PyObject_HEAD
+	/* Members used to implement callbacks: */
+	PyObject *ob_completion;
+	PyObject *ob_interrupt;
+	PyObject *ob_thiscallback;
+	long ob_A5;
+	SPB ob_spb;
+} SPBObject;
+
+static PyObject *SPBObj_New(void)
+{
+	SPBObject *it;
+	it = PyObject_NEW(SPBObject, &SPB_Type);
+	if (it == NULL) return NULL;
+	it->ob_completion = NULL;
+	it->ob_interrupt = NULL;
+	it->ob_thiscallback = NULL;
+	it->ob_A5 = SetCurrentA5();
+	memset((char *)&it->ob_spb, 0, sizeof(it->ob_spb));
+	it->ob_spb.userLong = (long)it;
+	return (PyObject *)it;
+}
+static int SPBObj_Convert(PyObject *v, SPBPtr *p_itself)
+{
+	if (!SPBObj_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "SPB required");
+		return 0;
+	}
+	*p_itself = &((SPBObject *)v)->ob_spb;
+	return 1;
+}
+
+static void SPBObj_dealloc(SPBObject *self)
+{
+	/* Cleanup of self->ob_itself goes here */
+	self->ob_spb.userLong = 0;
+	self->ob_thiscallback = 0;
+	Py_XDECREF(self->ob_completion);
+	Py_XDECREF(self->ob_interrupt);
+	PyObject_Free((PyObject *)self);
+}
+
+static PyMethodDef SPBObj_methods[] = {
+	{NULL, NULL, 0}
+};
+
+static PyObject *SPBObj_get_inRefNum(SPBObject *self, void *closure)
+{
+	return Py_BuildValue("l", self->ob_spb.inRefNum);
+}
+
+static int SPBObj_set_inRefNum(SPBObject *self, PyObject *v, void *closure)
+{
+	return -1 + PyArg_Parse(v, "l", &self->ob_spb.inRefNum);
+	return 0;
+}
+
+static PyObject *SPBObj_get_count(SPBObject *self, void *closure)
+{
+	return Py_BuildValue("l", self->ob_spb.count);
+}
+
+static int SPBObj_set_count(SPBObject *self, PyObject *v, void *closure)
+{
+	return -1 + PyArg_Parse(v, "l", &self->ob_spb.count);
+	return 0;
+}
+
+static PyObject *SPBObj_get_milliseconds(SPBObject *self, void *closure)
+{
+	return Py_BuildValue("l", self->ob_spb.milliseconds);
+}
+
+static int SPBObj_set_milliseconds(SPBObject *self, PyObject *v, void *closure)
+{
+	return -1 + PyArg_Parse(v, "l", &self->ob_spb.milliseconds);
+	return 0;
+}
+
+static PyObject *SPBObj_get_error(SPBObject *self, void *closure)
+{
+	return Py_BuildValue("h", self->ob_spb.error);
+}
+
+#define SPBObj_set_error NULL
+
+#define SPBObj_get_completionRoutine NULL
+
+static int SPBObj_set_completionRoutine(SPBObject *self, PyObject *v, void *closure)
+{
+	self->ob_spb.completionRoutine = NewSICompletionUPP(SPB_completion);
+	            self->ob_completion = v;
+	            Py_INCREF(v);
+	            return 0;
+	return 0;
+}
+
+static PyGetSetDef SPBObj_getsetlist[] = {
+	{"inRefNum", (getter)SPBObj_get_inRefNum, (setter)SPBObj_set_inRefNum, NULL},
+	{"count", (getter)SPBObj_get_count, (setter)SPBObj_set_count, NULL},
+	{"milliseconds", (getter)SPBObj_get_milliseconds, (setter)SPBObj_set_milliseconds, NULL},
+	{"error", (getter)SPBObj_get_error, (setter)SPBObj_set_error, NULL},
+	{"completionRoutine", (getter)SPBObj_get_completionRoutine, (setter)SPBObj_set_completionRoutine, NULL},
+	{NULL, NULL, NULL, NULL},
+};
+
+
+#define SPBObj_compare NULL
+
+#define SPBObj_repr NULL
+
+#define SPBObj_hash NULL
+
+static PyTypeObject SPB_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"_Snd.SPB", /*tp_name*/
+	sizeof(SPBObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) SPBObj_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) SPBObj_compare, /*tp_compare*/
+	(reprfunc) SPBObj_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) SPBObj_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	SPBObj_methods, /* tp_methods */
+	0, /*tp_members*/
+	SPBObj_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	0, /*tp_init*/
+	0, /*tp_alloc*/
+	0, /*tp_new*/
+	0, /*tp_free*/
+};
+
+/* ---------------------- End object type SPB ----------------------- */
+
+
+static PyObject *Snd_SPB(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	_res = SPBObj_New(); return _res;
+}
+
+static PyObject *Snd_SysBeep(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short duration;
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &duration))
+		return NULL;
+	SysBeep(duration);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Snd_SndNewChannel(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SndChannelPtr chan = 0;
+	short synth;
+	long init;
+	PyObject* userRoutine;
+	if (!PyArg_ParseTuple(_args, "hlO",
+	                      &synth,
+	                      &init,
+	                      &userRoutine))
+		return NULL;
+	if (userRoutine != Py_None && !PyCallable_Check(userRoutine))
+	{
+		PyErr_SetString(PyExc_TypeError, "callback must be callable");
+		goto userRoutine__error__;
+	}
+	_err = SndNewChannel(&chan,
+	                     synth,
+	                     init,
+	                     NewSndCallBackUPP(SndCh_UserRoutine));
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     SndCh_New, chan);
+	if (_res != NULL && userRoutine != Py_None)
+	{
+		SndChannelObject *p = (SndChannelObject *)_res;
+		p->ob_itself->userInfo = (long)p;
+		Py_INCREF(userRoutine);
+		p->ob_callback = userRoutine;
+	}
+ userRoutine__error__: ;
+	return _res;
+}
+
+static PyObject *Snd_SndSoundManagerVersion(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	NumVersion _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = SndSoundManagerVersion();
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildNumVersion, _rv);
+	return _res;
+}
+
+static PyObject *Snd_SndManagerStatus(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short theLength;
+	SMStatus theStatus__out__;
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &theLength))
+		return NULL;
+	_err = SndManagerStatus(theLength,
+	                        &theStatus__out__);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("s#",
+	                     (char *)&theStatus__out__, (int)sizeof(SMStatus));
+	return _res;
+}
+
+static PyObject *Snd_SndGetSysBeepState(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short sysBeepState;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	SndGetSysBeepState(&sysBeepState);
+	_res = Py_BuildValue("h",
+	                     sysBeepState);
+	return _res;
+}
+
+static PyObject *Snd_SndSetSysBeepState(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short sysBeepState;
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &sysBeepState))
+		return NULL;
+	_err = SndSetSysBeepState(sysBeepState);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Snd_GetSysBeepVolume(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	long level;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetSysBeepVolume(&level);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     level);
+	return _res;
+}
+
+static PyObject *Snd_SetSysBeepVolume(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	long level;
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &level))
+		return NULL;
+	_err = SetSysBeepVolume(level);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Snd_GetDefaultOutputVolume(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	long level;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetDefaultOutputVolume(&level);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     level);
+	return _res;
+}
+
+static PyObject *Snd_SetDefaultOutputVolume(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	long level;
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &level))
+		return NULL;
+	_err = SetDefaultOutputVolume(level);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Snd_GetSoundHeaderOffset(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SndListHandle sndHandle;
+	long offset;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &sndHandle))
+		return NULL;
+	_err = GetSoundHeaderOffset(sndHandle,
+	                            &offset);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     offset);
+	return _res;
+}
+
+static PyObject *Snd_GetCompressionInfo(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short compressionID;
+	OSType format;
+	short numChannels;
+	short sampleSize;
+	CompressionInfo cp__out__;
+	if (!PyArg_ParseTuple(_args, "hO&hh",
+	                      &compressionID,
+	                      PyMac_GetOSType, &format,
+	                      &numChannels,
+	                      &sampleSize))
+		return NULL;
+	_err = GetCompressionInfo(compressionID,
+	                          format,
+	                          numChannels,
+	                          sampleSize,
+	                          &cp__out__);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("s#",
+	                     (char *)&cp__out__, (int)sizeof(CompressionInfo));
+	return _res;
+}
+
+static PyObject *Snd_SetSoundPreference(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	OSType theType;
+	Str255 name;
+	Handle settings;
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetOSType, &theType,
+	                      ResObj_Convert, &settings))
+		return NULL;
+	_err = SetSoundPreference(theType,
+	                          name,
+	                          settings);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildStr255, name);
+	return _res;
+}
+
+static PyObject *Snd_GetSoundPreference(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	OSType theType;
+	Str255 name;
+	Handle settings;
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetOSType, &theType,
+	                      ResObj_Convert, &settings))
+		return NULL;
+	_err = GetSoundPreference(theType,
+	                          name,
+	                          settings);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildStr255, name);
+	return _res;
+}
+
+static PyObject *Snd_GetCompressionName(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	OSType compressionType;
+	Str255 compressionName;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetOSType, &compressionType))
+		return NULL;
+	_err = GetCompressionName(compressionType,
+	                          compressionName);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildStr255, compressionName);
+	return _res;
+}
+
+static PyObject *Snd_SPBVersion(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	NumVersion _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = SPBVersion();
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildNumVersion, _rv);
+	return _res;
+}
+
+static PyObject *Snd_SndRecord(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Point corner;
+	OSType quality;
+	SndListHandle sndHandle;
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetPoint, &corner,
+	                      PyMac_GetOSType, &quality))
+		return NULL;
+	_err = SndRecord((ModalFilterUPP)0,
+	                 corner,
+	                 quality,
+	                 &sndHandle);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, sndHandle);
+	return _res;
+}
+
+static PyObject *Snd_SPBSignInDevice(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short deviceRefNum;
+	Str255 deviceName;
+	if (!PyArg_ParseTuple(_args, "hO&",
+	                      &deviceRefNum,
+	                      PyMac_GetStr255, deviceName))
+		return NULL;
+	_err = SPBSignInDevice(deviceRefNum,
+	                       deviceName);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Snd_SPBSignOutDevice(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short deviceRefNum;
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &deviceRefNum))
+		return NULL;
+	_err = SPBSignOutDevice(deviceRefNum);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Snd_SPBGetIndexedDevice(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	short count;
+	Str255 deviceName;
+	Handle deviceIconHandle;
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &count))
+		return NULL;
+	_err = SPBGetIndexedDevice(count,
+	                           deviceName,
+	                           &deviceIconHandle);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&O&",
+	                     PyMac_BuildStr255, deviceName,
+	                     ResObj_New, deviceIconHandle);
+	return _res;
+}
+
+static PyObject *Snd_SPBOpenDevice(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	Str255 deviceName;
+	short permission;
+	long inRefNum;
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      PyMac_GetStr255, deviceName,
+	                      &permission))
+		return NULL;
+	_err = SPBOpenDevice(deviceName,
+	                     permission,
+	                     &inRefNum);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     inRefNum);
+	return _res;
+}
+
+static PyObject *Snd_SPBCloseDevice(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	long inRefNum;
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &inRefNum))
+		return NULL;
+	_err = SPBCloseDevice(inRefNum);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Snd_SPBRecord(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	SPBPtr inParamPtr;
+	Boolean asynchFlag;
+	if (!PyArg_ParseTuple(_args, "O&b",
+	                      SPBObj_Convert, &inParamPtr,
+	                      &asynchFlag))
+		return NULL;
+	_err = SPBRecord(inParamPtr,
+	                 asynchFlag);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Snd_SPBPauseRecording(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	long inRefNum;
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &inRefNum))
+		return NULL;
+	_err = SPBPauseRecording(inRefNum);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Snd_SPBResumeRecording(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	long inRefNum;
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &inRefNum))
+		return NULL;
+	_err = SPBResumeRecording(inRefNum);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Snd_SPBStopRecording(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	long inRefNum;
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &inRefNum))
+		return NULL;
+	_err = SPBStopRecording(inRefNum);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Snd_SPBGetRecordingStatus(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	long inRefNum;
+	short recordingStatus;
+	short meterLevel;
+	unsigned long totalSamplesToRecord;
+	unsigned long numberOfSamplesRecorded;
+	unsigned long totalMsecsToRecord;
+	unsigned long numberOfMsecsRecorded;
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &inRefNum))
+		return NULL;
+	_err = SPBGetRecordingStatus(inRefNum,
+	                             &recordingStatus,
+	                             &meterLevel,
+	                             &totalSamplesToRecord,
+	                             &numberOfSamplesRecorded,
+	                             &totalMsecsToRecord,
+	                             &numberOfMsecsRecorded);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("hhllll",
+	                     recordingStatus,
+	                     meterLevel,
+	                     totalSamplesToRecord,
+	                     numberOfSamplesRecorded,
+	                     totalMsecsToRecord,
+	                     numberOfMsecsRecorded);
+	return _res;
+}
+
+static PyObject *Snd_SPBGetDeviceInfo(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	long inRefNum;
+	OSType infoType;
+	void * infoData;
+	if (!PyArg_ParseTuple(_args, "lO&w",
+	                      &inRefNum,
+	                      PyMac_GetOSType, &infoType,
+	                      &infoData))
+		return NULL;
+	_err = SPBGetDeviceInfo(inRefNum,
+	                        infoType,
+	                        infoData);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Snd_SPBSetDeviceInfo(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	long inRefNum;
+	OSType infoType;
+	void * infoData;
+	if (!PyArg_ParseTuple(_args, "lO&w",
+	                      &inRefNum,
+	                      PyMac_GetOSType, &infoType,
+	                      &infoData))
+		return NULL;
+	_err = SPBSetDeviceInfo(inRefNum,
+	                        infoType,
+	                        infoData);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Snd_SPBMillisecondsToBytes(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	long inRefNum;
+	long milliseconds;
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &inRefNum))
+		return NULL;
+	_err = SPBMillisecondsToBytes(inRefNum,
+	                              &milliseconds);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     milliseconds);
+	return _res;
+}
+
+static PyObject *Snd_SPBBytesToMilliseconds(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	long inRefNum;
+	long byteCount;
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &inRefNum))
+		return NULL;
+	_err = SPBBytesToMilliseconds(inRefNum,
+	                              &byteCount);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     byteCount);
+	return _res;
+}
+
+static PyMethodDef Snd_methods[] = {
+	{"SPB", (PyCFunction)Snd_SPB, 1,
+	 PyDoc_STR(NULL)},
+	{"SysBeep", (PyCFunction)Snd_SysBeep, 1,
+	 PyDoc_STR("(short duration) -> None")},
+	{"SndNewChannel", (PyCFunction)Snd_SndNewChannel, 1,
+	 PyDoc_STR("(short synth, long init, PyObject* userRoutine) -> (SndChannelPtr chan)")},
+	{"SndSoundManagerVersion", (PyCFunction)Snd_SndSoundManagerVersion, 1,
+	 PyDoc_STR("() -> (NumVersion _rv)")},
+	{"SndManagerStatus", (PyCFunction)Snd_SndManagerStatus, 1,
+	 PyDoc_STR("(short theLength) -> (SMStatus theStatus)")},
+	{"SndGetSysBeepState", (PyCFunction)Snd_SndGetSysBeepState, 1,
+	 PyDoc_STR("() -> (short sysBeepState)")},
+	{"SndSetSysBeepState", (PyCFunction)Snd_SndSetSysBeepState, 1,
+	 PyDoc_STR("(short sysBeepState) -> None")},
+	{"GetSysBeepVolume", (PyCFunction)Snd_GetSysBeepVolume, 1,
+	 PyDoc_STR("() -> (long level)")},
+	{"SetSysBeepVolume", (PyCFunction)Snd_SetSysBeepVolume, 1,
+	 PyDoc_STR("(long level) -> None")},
+	{"GetDefaultOutputVolume", (PyCFunction)Snd_GetDefaultOutputVolume, 1,
+	 PyDoc_STR("() -> (long level)")},
+	{"SetDefaultOutputVolume", (PyCFunction)Snd_SetDefaultOutputVolume, 1,
+	 PyDoc_STR("(long level) -> None")},
+	{"GetSoundHeaderOffset", (PyCFunction)Snd_GetSoundHeaderOffset, 1,
+	 PyDoc_STR("(SndListHandle sndHandle) -> (long offset)")},
+	{"GetCompressionInfo", (PyCFunction)Snd_GetCompressionInfo, 1,
+	 PyDoc_STR("(short compressionID, OSType format, short numChannels, short sampleSize) -> (CompressionInfo cp)")},
+	{"SetSoundPreference", (PyCFunction)Snd_SetSoundPreference, 1,
+	 PyDoc_STR("(OSType theType, Handle settings) -> (Str255 name)")},
+	{"GetSoundPreference", (PyCFunction)Snd_GetSoundPreference, 1,
+	 PyDoc_STR("(OSType theType, Handle settings) -> (Str255 name)")},
+	{"GetCompressionName", (PyCFunction)Snd_GetCompressionName, 1,
+	 PyDoc_STR("(OSType compressionType) -> (Str255 compressionName)")},
+	{"SPBVersion", (PyCFunction)Snd_SPBVersion, 1,
+	 PyDoc_STR("() -> (NumVersion _rv)")},
+	{"SndRecord", (PyCFunction)Snd_SndRecord, 1,
+	 PyDoc_STR("(Point corner, OSType quality) -> (SndListHandle sndHandle)")},
+	{"SPBSignInDevice", (PyCFunction)Snd_SPBSignInDevice, 1,
+	 PyDoc_STR("(short deviceRefNum, Str255 deviceName) -> None")},
+	{"SPBSignOutDevice", (PyCFunction)Snd_SPBSignOutDevice, 1,
+	 PyDoc_STR("(short deviceRefNum) -> None")},
+	{"SPBGetIndexedDevice", (PyCFunction)Snd_SPBGetIndexedDevice, 1,
+	 PyDoc_STR("(short count) -> (Str255 deviceName, Handle deviceIconHandle)")},
+	{"SPBOpenDevice", (PyCFunction)Snd_SPBOpenDevice, 1,
+	 PyDoc_STR("(Str255 deviceName, short permission) -> (long inRefNum)")},
+	{"SPBCloseDevice", (PyCFunction)Snd_SPBCloseDevice, 1,
+	 PyDoc_STR("(long inRefNum) -> None")},
+	{"SPBRecord", (PyCFunction)Snd_SPBRecord, 1,
+	 PyDoc_STR("(SPBPtr inParamPtr, Boolean asynchFlag) -> None")},
+	{"SPBPauseRecording", (PyCFunction)Snd_SPBPauseRecording, 1,
+	 PyDoc_STR("(long inRefNum) -> None")},
+	{"SPBResumeRecording", (PyCFunction)Snd_SPBResumeRecording, 1,
+	 PyDoc_STR("(long inRefNum) -> None")},
+	{"SPBStopRecording", (PyCFunction)Snd_SPBStopRecording, 1,
+	 PyDoc_STR("(long inRefNum) -> None")},
+	{"SPBGetRecordingStatus", (PyCFunction)Snd_SPBGetRecordingStatus, 1,
+	 PyDoc_STR("(long inRefNum) -> (short recordingStatus, short meterLevel, unsigned long totalSamplesToRecord, unsigned long numberOfSamplesRecorded, unsigned long totalMsecsToRecord, unsigned long numberOfMsecsRecorded)")},
+	{"SPBGetDeviceInfo", (PyCFunction)Snd_SPBGetDeviceInfo, 1,
+	 PyDoc_STR("(long inRefNum, OSType infoType, void * infoData) -> None")},
+	{"SPBSetDeviceInfo", (PyCFunction)Snd_SPBSetDeviceInfo, 1,
+	 PyDoc_STR("(long inRefNum, OSType infoType, void * infoData) -> None")},
+	{"SPBMillisecondsToBytes", (PyCFunction)Snd_SPBMillisecondsToBytes, 1,
+	 PyDoc_STR("(long inRefNum) -> (long milliseconds)")},
+	{"SPBBytesToMilliseconds", (PyCFunction)Snd_SPBBytesToMilliseconds, 1,
+	 PyDoc_STR("(long inRefNum) -> (long byteCount)")},
+	{NULL, NULL, 0}
+};
+
+
+
+/* Routine passed to Py_AddPendingCall -- call the Python callback */
+static int
+SndCh_CallCallBack(void *arg)
+{
+        SndChannelObject *p = (SndChannelObject *)arg;
+        PyObject *args;
+        PyObject *res;
+        args = Py_BuildValue("(O(hhl))",
+                             p, p->ob_cmd.cmd, p->ob_cmd.param1, p->ob_cmd.param2);
+        res = PyEval_CallObject(p->ob_callback, args);
+        Py_DECREF(args);
+        if (res == NULL)
+                return -1;
+        Py_DECREF(res);
+        return 0;
+}
+
+/* Routine passed to NewSndChannel -- schedule a call to SndCh_CallCallBack */
+static pascal void
+SndCh_UserRoutine(SndChannelPtr chan, SndCommand *cmd)
+{
+        SndChannelObject *p = (SndChannelObject *)(chan->userInfo);
+        if (p->ob_callback != NULL) {
+                long A5 = SetA5(p->ob_A5);
+                p->ob_cmd = *cmd;
+                Py_AddPendingCall(SndCh_CallCallBack, (void *)p);
+                SetA5(A5);
+        }
+}
+
+/* SPB callbacks - Schedule callbacks to Python */
+static int
+SPB_CallCallBack(void *arg)
+{
+        SPBObject *p = (SPBObject *)arg;
+        PyObject *args;
+        PyObject *res;
+
+        if ( p->ob_thiscallback == 0 ) return 0;
+        args = Py_BuildValue("(O)", p);
+        res = PyEval_CallObject(p->ob_thiscallback, args);
+        p->ob_thiscallback = 0;
+        Py_DECREF(args);
+        if (res == NULL)
+                return -1;
+        Py_DECREF(res);
+        return 0;
+}
+
+static pascal void
+SPB_completion(SPBPtr my_spb)
+{
+        SPBObject *p = (SPBObject *)(my_spb->userLong);
+
+        if (p && p->ob_completion) {
+                long A5 = SetA5(p->ob_A5);
+                p->ob_thiscallback = p->ob_completion;  /* Hope we cannot get two at the same time */
+                Py_AddPendingCall(SPB_CallCallBack, (void *)p);
+                SetA5(A5);
+        }
+}
+
+
+
+void init_Snd(void)
+{
+	PyObject *m;
+	PyObject *d;
+
+
+
+
+
+	m = Py_InitModule("_Snd", Snd_methods);
+	d = PyModule_GetDict(m);
+	Snd_Error = PyMac_GetOSErrException();
+	if (Snd_Error == NULL ||
+	    PyDict_SetItemString(d, "Error", Snd_Error) != 0)
+		return;
+	SndChannel_Type.ob_type = &PyType_Type;
+	if (PyType_Ready(&SndChannel_Type) < 0) return;
+	Py_INCREF(&SndChannel_Type);
+	PyModule_AddObject(m, "SndChannel", (PyObject *)&SndChannel_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&SndChannel_Type);
+	PyModule_AddObject(m, "SndChannelType", (PyObject *)&SndChannel_Type);
+	SPB_Type.ob_type = &PyType_Type;
+	if (PyType_Ready(&SPB_Type) < 0) return;
+	Py_INCREF(&SPB_Type);
+	PyModule_AddObject(m, "SPB", (PyObject *)&SPB_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&SPB_Type);
+	PyModule_AddObject(m, "SPBType", (PyObject *)&SPB_Type);
+}
+
+/* ======================== End module _Snd ========================= */
+

Added: vendor/Python/current/Mac/Modules/snd/sndscan.py
===================================================================
--- vendor/Python/current/Mac/Modules/snd/sndscan.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/snd/sndscan.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,128 @@
+# Scan Sound.h header file, generate sndgen.py and Sound.py files.
+# Then import sndsupport (which execs sndgen.py) to generate Sndmodule.c.
+# (Should learn how to tell the compiler to compile it as well.)
+
+import sys
+import os
+from bgenlocations import TOOLBOXDIR, BGENDIR
+sys.path.append(BGENDIR)
+
+from scantools import Scanner
+
+def main():
+    input = "Sound.h"
+    output = "sndgen.py"
+    defsoutput = TOOLBOXDIR + "Sound.py"
+    scanner = SoundScanner(input, output, defsoutput)
+    scanner.scan()
+    scanner.close()
+    print "=== Testing definitions output code ==="
+    execfile(defsoutput, {}, {})
+    print "=== Done scanning and generating, now doing 'import sndsupport' ==="
+    import sndsupport
+    print "=== Done.  It's up to you to compile Sndmodule.c ==="
+
+class SoundScanner(Scanner):
+
+    def destination(self, type, name, arglist):
+        classname = "SndFunction"
+        listname = "functions"
+        if arglist:
+            t, n, m = arglist[0]
+            if t == "SndChannelPtr" and m == "InMode":
+                classname = "SndMethod"
+                listname = "sndmethods"
+        return classname, listname
+
+    def writeinitialdefs(self):
+        self.defsfile.write("def FOUR_CHAR_CODE(x): return x\n")
+
+    def makeblacklistnames(self):
+        return [
+                'SndDisposeChannel',            # automatic on deallocation
+                'SndAddModifier',               # for internal use only
+                'SndPlayDoubleBuffer',          # very low level routine
+                # Missing from libraries (UH332)
+                'SoundManagerSetInfo',
+                'SoundManagerGetInfo',
+                # Constants with funny definitions
+                'rate48khz',
+                'rate44khz',
+                'kInvalidSource',
+                # OS8 only:
+                'MACEVersion',
+                'SPBRecordToFile',
+                'Exp1to6',
+                'Comp6to1',
+                'Exp1to3',
+                'Comp3to1',
+                'SndControl',
+                'SndStopFilePlay',
+                'SndStartFilePlay',
+                'SndPauseFilePlay',
+                'SndRecordToFile',
+
+                ]
+
+    def makeblacklisttypes(self):
+        return [
+                "GetSoundVol",
+                "SetSoundVol",
+                "UnsignedFixed",
+                # Don't have the time to dig into this...
+                "Component",
+                "ComponentInstance",
+                "SoundComponentDataPtr",
+                "SoundComponentData",
+                "SoundComponentData_ptr",
+                "SoundConverter",
+                ]
+
+    def makerepairinstructions(self):
+        return [
+                ([("Str255", "*", "InMode")],
+                 [("*", "*", "OutMode")]),
+
+                ([("void_ptr", "*", "InMode"), ("long", "*", "InMode")],
+                 [("InBuffer", "*", "*")]),
+
+                ([("void", "*", "OutMode"), ("long", "*", "InMode"),
+                                            ("long", "*", "OutMode")],
+                 [("VarVarOutBuffer", "*", "InOutMode")]),
+
+                ([("SCStatusPtr", "*", "InMode")],
+                 [("SCStatus", "*", "OutMode")]),
+
+                ([("SMStatusPtr", "*", "InMode")],
+                 [("SMStatus", "*", "OutMode")]),
+
+                ([("CompressionInfoPtr", "*", "InMode")],
+                 [("CompressionInfo", "*", "OutMode")]),
+
+                # For SndPlay's SndListHandle argument
+                ([("Handle", "sndHdl", "InMode")],
+                 [("SndListHandle", "*", "*")]),
+
+                # For SndStartFilePlay
+                ([("long", "bufferSize", "InMode"), ("void", "theBuffer", "OutMode")],
+                 [("*", "*", "*"), ("FakeType('0')", "*", "InMode")]),
+
+                # For Comp3to1 etc.
+                ([("void_ptr", "inBuffer", "InMode"),
+                  ("void", "outBuffer", "OutMode"),
+                  ("unsigned_long", "cnt", "InMode")],
+                 [("InOutBuffer", "buffer", "InOutMode")]),
+
+                # Ditto
+##                      ([("void_ptr", "inState", "InMode"), ("void", "outState", "OutMode")],
+##                       [("InOutBuf128", "state", "InOutMode")]),
+                ([("StateBlockPtr", "inState", "InMode"), ("StateBlockPtr", "outState", "InMode")],
+                 [("StateBlock", "state", "InOutMode")]),
+
+                # Catch-all for the last couple of void pointers
+                ([("void", "*", "OutMode")],
+                 [("void_ptr", "*", "InMode")]),
+                ]
+
+if __name__ == "__main__":
+    main()

Added: vendor/Python/current/Mac/Modules/snd/sndsupport.py
===================================================================
--- vendor/Python/current/Mac/Modules/snd/sndsupport.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/snd/sndsupport.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,319 @@
+# This script generates the Sound interface for Python.
+# It uses the "bgen" package to generate C code.
+# It execs the file sndgen.py which contain the function definitions
+# (sndgen.py was generated by sndscan.py, scanning the <Sound.h> header file).
+
+from macsupport import *
+
+
+# define our own function and module generators
+
+class SndMixIn: pass
+
+class SndFunction(SndMixIn, OSErrFunctionGenerator): pass
+class SndMethod(SndMixIn, OSErrMethodGenerator): pass
+
+
+# includestuff etc. are imported from macsupport
+
+includestuff = includestuff + """
+#include <Carbon/Carbon.h>
+"""
+
+initstuff = initstuff + """
+"""
+
+
+# define types used for arguments (in addition to standard and macsupport types)
+
+class SndChannelPtrType(OpaqueByValueType):
+    def declare(self, name):
+        # Initializing all SndChannelPtr objects to 0 saves
+        # special-casing NewSndChannel(), where it is formally an
+        # input-output parameter but we treat it as output-only
+        # (since Python users are not supposed to allocate memory)
+        Output("SndChannelPtr %s = 0;", name)
+
+SndChannelPtr = SndChannelPtrType('SndChannelPtr', 'SndCh')
+
+SndCommand = OpaqueType('SndCommand', 'SndCmd')
+SndCommand_ptr = OpaqueType('SndCommand', 'SndCmd')
+SndListHandle = OpaqueByValueType("SndListHandle", "ResObj")
+SPBPtr = OpaqueByValueType("SPBPtr", "SPBObj")
+ModalFilterUPP = FakeType("(ModalFilterUPP)0")
+
+#
+# NOTE: the following is pretty dangerous. For void pointers we pass buffer addresses
+# but we have no way to check that the buffer is big enough. This is the same problem
+# as in C, though (but Pythoneers may not be suspecting this...)
+void_ptr = Type("void *", "w")
+
+class SndCallBackType(InputOnlyType):
+    def __init__(self):
+        Type.__init__(self, 'PyObject*', 'O')
+    def getargsCheck(self, name):
+        Output("if (%s != Py_None && !PyCallable_Check(%s))", name, name)
+        OutLbrace()
+        Output('PyErr_SetString(PyExc_TypeError, "callback must be callable");')
+        Output("goto %s__error__;", name)
+        OutRbrace()
+    def passInput(self, name):
+        return "NewSndCallBackUPP(SndCh_UserRoutine)"
+    def cleanup(self, name):
+        # XXX This knows it is executing inside the SndNewChannel wrapper
+        Output("if (_res != NULL && %s != Py_None)", name)
+        OutLbrace()
+        Output("SndChannelObject *p = (SndChannelObject *)_res;")
+        Output("p->ob_itself->userInfo = (long)p;")
+        Output("Py_INCREF(%s);", name)
+        Output("p->ob_callback = %s;", name)
+        OutRbrace()
+        DedentLevel()
+        Output(" %s__error__: ;", name)
+        IndentLevel()
+
+SndCallBackProcPtr = SndCallBackType()
+SndCallBackUPP = SndCallBackProcPtr
+
+SndCompletionProcPtr = FakeType('(SndCompletionProcPtr)0') # XXX
+SndCompletionUPP = SndCompletionProcPtr
+
+##InOutBuf128 = FixedInputOutputBufferType(128)
+StateBlock = StructInputOutputBufferType('StateBlock')
+
+AudioSelectionPtr = FakeType('0') # XXX
+
+ProcPtr = FakeType('0') # XXX
+FilePlayCompletionUPP = FakeType('0') # XXX
+
+SCStatus = StructOutputBufferType('SCStatus')
+SMStatus = StructOutputBufferType('SMStatus')
+CompressionInfo = StructOutputBufferType('CompressionInfo')
+
+includestuff = includestuff + """
+/* Convert a SndCommand argument */
+static int
+SndCmd_Convert(PyObject *v, SndCommand *pc)
+{
+        int len;
+        pc->param1 = 0;
+        pc->param2 = 0;
+        if (PyTuple_Check(v)) {
+                if (PyArg_ParseTuple(v, "h|hl", &pc->cmd, &pc->param1, &pc->param2))
+                        return 1;
+                PyErr_Clear();
+                return PyArg_ParseTuple(v, "Hhs#", &pc->cmd, &pc->param1, &pc->param2, &len);
+        }
+        return PyArg_Parse(v, "H", &pc->cmd);
+}
+
+static pascal void SndCh_UserRoutine(SndChannelPtr chan, SndCommand *cmd); /* Forward */
+static pascal void SPB_completion(SPBPtr my_spb); /* Forward */
+"""
+
+
+finalstuff = finalstuff + """
+/* Routine passed to Py_AddPendingCall -- call the Python callback */
+static int
+SndCh_CallCallBack(void *arg)
+{
+        SndChannelObject *p = (SndChannelObject *)arg;
+        PyObject *args;
+        PyObject *res;
+        args = Py_BuildValue("(O(hhl))",
+                             p, p->ob_cmd.cmd, p->ob_cmd.param1, p->ob_cmd.param2);
+        res = PyEval_CallObject(p->ob_callback, args);
+        Py_DECREF(args);
+        if (res == NULL)
+                return -1;
+        Py_DECREF(res);
+        return 0;
+}
+
+/* Routine passed to NewSndChannel -- schedule a call to SndCh_CallCallBack */
+static pascal void
+SndCh_UserRoutine(SndChannelPtr chan, SndCommand *cmd)
+{
+        SndChannelObject *p = (SndChannelObject *)(chan->userInfo);
+        if (p->ob_callback != NULL) {
+                long A5 = SetA5(p->ob_A5);
+                p->ob_cmd = *cmd;
+                Py_AddPendingCall(SndCh_CallCallBack, (void *)p);
+                SetA5(A5);
+        }
+}
+
+/* SPB callbacks - Schedule callbacks to Python */
+static int
+SPB_CallCallBack(void *arg)
+{
+        SPBObject *p = (SPBObject *)arg;
+        PyObject *args;
+        PyObject *res;
+
+        if ( p->ob_thiscallback == 0 ) return 0;
+        args = Py_BuildValue("(O)", p);
+        res = PyEval_CallObject(p->ob_thiscallback, args);
+        p->ob_thiscallback = 0;
+        Py_DECREF(args);
+        if (res == NULL)
+                return -1;
+        Py_DECREF(res);
+        return 0;
+}
+
+static pascal void
+SPB_completion(SPBPtr my_spb)
+{
+        SPBObject *p = (SPBObject *)(my_spb->userLong);
+
+        if (p && p->ob_completion) {
+                long A5 = SetA5(p->ob_A5);
+                p->ob_thiscallback = p->ob_completion;  /* Hope we cannot get two at the same time */
+                Py_AddPendingCall(SPB_CallCallBack, (void *)p);
+                SetA5(A5);
+        }
+}
+
+"""
+
+
+# create the module and object definition and link them
+
+class SndObjectDefinition(PEP252Mixin, ObjectDefinition):
+
+    def outputStructMembers(self):
+        ObjectDefinition.outputStructMembers(self)
+        Output("/* Members used to implement callbacks: */")
+        Output("PyObject *ob_callback;")
+        Output("long ob_A5;");
+        Output("SndCommand ob_cmd;")
+
+    def outputInitStructMembers(self):
+        ObjectDefinition.outputInitStructMembers(self)
+        Output("it->ob_callback = NULL;")
+        Output("it->ob_A5 = SetCurrentA5();");
+
+    def outputCleanupStructMembers(self):
+        ObjectDefinition.outputCleanupStructMembers(self)
+        Output("Py_XDECREF(self->ob_callback);")
+
+    def outputFreeIt(self, itselfname):
+        Output("SndDisposeChannel(%s, 1);", itselfname)
+
+    def outputConvert(self):
+        pass # Not needed
+
+#
+
+class SpbObjectDefinition(PEP252Mixin, ObjectDefinition):
+    getsetlist = [
+            (
+            'inRefNum',
+            'return Py_BuildValue("l", self->ob_spb.inRefNum);',
+            'return -1 + PyArg_Parse(v, "l", &self->ob_spb.inRefNum);',
+            None,
+            ), (
+            'count',
+            'return Py_BuildValue("l", self->ob_spb.count);',
+            'return -1 + PyArg_Parse(v, "l", &self->ob_spb.count);',
+            None
+            ), (
+            'milliseconds',
+            'return Py_BuildValue("l", self->ob_spb.milliseconds);',
+            'return -1 + PyArg_Parse(v, "l", &self->ob_spb.milliseconds);',
+            None,
+            ), (
+            'error',
+            'return Py_BuildValue("h", self->ob_spb.error);',
+            None,
+            None
+            ), (
+            'completionRoutine',
+            None,
+            """self->ob_spb.completionRoutine = NewSICompletionUPP(SPB_completion);
+            self->ob_completion = v;
+            Py_INCREF(v);
+            return 0;""",
+            None,
+            )]
+
+    def outputStructMembers(self):
+        Output("/* Members used to implement callbacks: */")
+        Output("PyObject *ob_completion;")
+        Output("PyObject *ob_interrupt;")
+        Output("PyObject *ob_thiscallback;");
+        Output("long ob_A5;")
+        Output("SPB ob_spb;")
+
+    def outputNew(self):
+        Output()
+        Output("%sPyObject *%s_New(void)", self.static, self.prefix)
+        OutLbrace()
+        Output("%s *it;", self.objecttype)
+        self.outputCheckNewArg()
+        Output("it = PyObject_NEW(%s, &%s);", self.objecttype, self.typename)
+        Output("if (it == NULL) return NULL;")
+        self.outputInitStructMembers()
+        Output("return (PyObject *)it;")
+        OutRbrace()
+
+    def outputInitStructMembers(self):
+        Output("it->ob_completion = NULL;")
+        Output("it->ob_interrupt = NULL;")
+        Output("it->ob_thiscallback = NULL;")
+        Output("it->ob_A5 = SetCurrentA5();")
+        Output("memset((char *)&it->ob_spb, 0, sizeof(it->ob_spb));")
+        Output("it->ob_spb.userLong = (long)it;")
+
+    def outputCleanupStructMembers(self):
+        ObjectDefinition.outputCleanupStructMembers(self)
+        Output("self->ob_spb.userLong = 0;")
+        Output("self->ob_thiscallback = 0;")
+        Output("Py_XDECREF(self->ob_completion);")
+        Output("Py_XDECREF(self->ob_interrupt);")
+
+    def outputConvert(self):
+        Output("%sint %s_Convert(PyObject *v, %s *p_itself)", self.static, self.prefix, self.itselftype)
+        OutLbrace()
+        self.outputCheckConvertArg()
+        Output("if (!%s_Check(v))", self.prefix)
+        OutLbrace()
+        Output('PyErr_SetString(PyExc_TypeError, "%s required");', self.name)
+        Output("return 0;")
+        OutRbrace()
+        Output("*p_itself = &((%s *)v)->ob_spb;", self.objecttype)
+        Output("return 1;")
+        OutRbrace()
+
+
+sndobject = SndObjectDefinition('SndChannel', 'SndCh', 'SndChannelPtr')
+spbobject = SpbObjectDefinition('SPB', 'SPBObj', 'SPBPtr')
+spbgenerator = ManualGenerator("SPB", "_res = SPBObj_New(); return _res;")
+module = MacModule('_Snd', 'Snd', includestuff, finalstuff, initstuff)
+module.addobject(sndobject)
+module.addobject(spbobject)
+module.add(spbgenerator)
+
+
+# create lists of functions and object methods
+
+functions = []
+sndmethods = []
+
+
+# populate the lists
+
+execfile('sndgen.py')
+
+
+# add the functions and methods to the module and object, respectively
+
+for f in functions: module.add(f)
+for f in sndmethods: sndobject.add(f)
+
+
+# generate output
+
+SetOutputFileName('_Sndmodule.c')
+module.generate()

Added: vendor/Python/current/Mac/Modules/te/_TEmodule.c
===================================================================
--- vendor/Python/current/Mac/Modules/te/_TEmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/te/_TEmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1331 @@
+
+/* =========================== Module _TE =========================== */
+
+#include "Python.h"
+
+
+
+#include "pymactoolbox.h"
+
+/* Macro to test whether a weak-loaded CFM function exists */
+#define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL )  {\
+        PyErr_SetString(PyExc_NotImplementedError, \
+        "Not available in this shared library/OS version"); \
+        return NULL; \
+    }} while(0)
+
+
+#include <Carbon/Carbon.h>
+
+#ifdef USE_TOOLBOX_OBJECT_GLUE
+extern PyObject *_TEObj_New(TEHandle);
+extern int _TEObj_Convert(PyObject *, TEHandle *);
+
+#define TEObj_New _TEObj_New
+#define TEObj_Convert _TEObj_Convert
+#endif
+
+#define as_TE(h) ((TEHandle)h)
+#define as_Resource(teh) ((Handle)teh)
+
+/*
+** Parse/generate TextStyle records
+*/
+static PyObject *
+TextStyle_New(TextStylePtr itself)
+{
+
+        return Py_BuildValue("lllO&", (long)itself->tsFont, (long)itself->tsFace, (long)itself->tsSize, QdRGB_New,
+                                &itself->tsColor);
+}
+
+static int
+TextStyle_Convert(PyObject *v, TextStylePtr p_itself)
+{
+        long font, face, size;
+
+        if( !PyArg_ParseTuple(v, "lllO&", &font, &face, &size, QdRGB_Convert, &p_itself->tsColor) )
+                return 0;
+        p_itself->tsFont = (short)font;
+        p_itself->tsFace = (Style)face;
+        p_itself->tsSize = (short)size;
+        return 1;
+}
+
+static PyObject *TE_Error;
+
+/* ------------------------- Object type TE ------------------------- */
+
+PyTypeObject TE_Type;
+
+#define TEObj_Check(x) ((x)->ob_type == &TE_Type || PyObject_TypeCheck((x), &TE_Type))
+
+typedef struct TEObject {
+	PyObject_HEAD
+	TEHandle ob_itself;
+} TEObject;
+
+PyObject *TEObj_New(TEHandle itself)
+{
+	TEObject *it;
+	if (itself == NULL) {
+	                                PyErr_SetString(TE_Error,"Cannot create null TE");
+	                                return NULL;
+	                        }
+	it = PyObject_NEW(TEObject, &TE_Type);
+	if (it == NULL) return NULL;
+	it->ob_itself = itself;
+	return (PyObject *)it;
+}
+
+int TEObj_Convert(PyObject *v, TEHandle *p_itself)
+{
+	if (!TEObj_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "TE required");
+		return 0;
+	}
+	*p_itself = ((TEObject *)v)->ob_itself;
+	return 1;
+}
+
+static void TEObj_dealloc(TEObject *self)
+{
+	TEDispose(self->ob_itself);
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *TEObj_TESetText(TEObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	char *text__in__;
+	long text__len__;
+	int text__in_len__;
+#ifndef TESetText
+	PyMac_PRECHECK(TESetText);
+#endif
+	if (!PyArg_ParseTuple(_args, "s#",
+	                      &text__in__, &text__in_len__))
+		return NULL;
+	text__len__ = text__in_len__;
+	TESetText(text__in__, text__len__,
+	          _self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TEObj_TEGetText(TEObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CharsHandle _rv;
+#ifndef TEGetText
+	PyMac_PRECHECK(TEGetText);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = TEGetText(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *TEObj_TEIdle(TEObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef TEIdle
+	PyMac_PRECHECK(TEIdle);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	TEIdle(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TEObj_TESetSelect(TEObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long selStart;
+	long selEnd;
+#ifndef TESetSelect
+	PyMac_PRECHECK(TESetSelect);
+#endif
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &selStart,
+	                      &selEnd))
+		return NULL;
+	TESetSelect(selStart,
+	            selEnd,
+	            _self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TEObj_TEActivate(TEObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef TEActivate
+	PyMac_PRECHECK(TEActivate);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	TEActivate(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TEObj_TEDeactivate(TEObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef TEDeactivate
+	PyMac_PRECHECK(TEDeactivate);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	TEDeactivate(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TEObj_TEKey(TEObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CharParameter key;
+#ifndef TEKey
+	PyMac_PRECHECK(TEKey);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &key))
+		return NULL;
+	TEKey(key,
+	      _self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TEObj_TECut(TEObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef TECut
+	PyMac_PRECHECK(TECut);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	TECut(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TEObj_TECopy(TEObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef TECopy
+	PyMac_PRECHECK(TECopy);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	TECopy(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TEObj_TEPaste(TEObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef TEPaste
+	PyMac_PRECHECK(TEPaste);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	TEPaste(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TEObj_TEDelete(TEObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef TEDelete
+	PyMac_PRECHECK(TEDelete);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	TEDelete(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TEObj_TEInsert(TEObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	char *text__in__;
+	long text__len__;
+	int text__in_len__;
+#ifndef TEInsert
+	PyMac_PRECHECK(TEInsert);
+#endif
+	if (!PyArg_ParseTuple(_args, "s#",
+	                      &text__in__, &text__in_len__))
+		return NULL;
+	text__len__ = text__in_len__;
+	TEInsert(text__in__, text__len__,
+	         _self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TEObj_TESetAlignment(TEObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short just;
+#ifndef TESetAlignment
+	PyMac_PRECHECK(TESetAlignment);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &just))
+		return NULL;
+	TESetAlignment(just,
+	               _self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TEObj_TEUpdate(TEObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect rUpdate;
+#ifndef TEUpdate
+	PyMac_PRECHECK(TEUpdate);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetRect, &rUpdate))
+		return NULL;
+	TEUpdate(&rUpdate,
+	         _self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TEObj_TEScroll(TEObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short dh;
+	short dv;
+#ifndef TEScroll
+	PyMac_PRECHECK(TEScroll);
+#endif
+	if (!PyArg_ParseTuple(_args, "hh",
+	                      &dh,
+	                      &dv))
+		return NULL;
+	TEScroll(dh,
+	         dv,
+	         _self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TEObj_TESelView(TEObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef TESelView
+	PyMac_PRECHECK(TESelView);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	TESelView(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TEObj_TEPinScroll(TEObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short dh;
+	short dv;
+#ifndef TEPinScroll
+	PyMac_PRECHECK(TEPinScroll);
+#endif
+	if (!PyArg_ParseTuple(_args, "hh",
+	                      &dh,
+	                      &dv))
+		return NULL;
+	TEPinScroll(dh,
+	            dv,
+	            _self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TEObj_TEAutoView(TEObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean fAuto;
+#ifndef TEAutoView
+	PyMac_PRECHECK(TEAutoView);
+#endif
+	if (!PyArg_ParseTuple(_args, "b",
+	                      &fAuto))
+		return NULL;
+	TEAutoView(fAuto,
+	           _self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TEObj_TECalText(TEObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef TECalText
+	PyMac_PRECHECK(TECalText);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	TECalText(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TEObj_TEGetOffset(TEObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short _rv;
+	Point pt;
+#ifndef TEGetOffset
+	PyMac_PRECHECK(TEGetOffset);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetPoint, &pt))
+		return NULL;
+	_rv = TEGetOffset(pt,
+	                  _self->ob_itself);
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *TEObj_TEGetPoint(TEObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Point _rv;
+	short offset;
+#ifndef TEGetPoint
+	PyMac_PRECHECK(TEGetPoint);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &offset))
+		return NULL;
+	_rv = TEGetPoint(offset,
+	                 _self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildPoint, _rv);
+	return _res;
+}
+
+static PyObject *TEObj_TEClick(TEObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Point pt;
+	Boolean fExtend;
+#ifndef TEClick
+	PyMac_PRECHECK(TEClick);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&b",
+	                      PyMac_GetPoint, &pt,
+	                      &fExtend))
+		return NULL;
+	TEClick(pt,
+	        fExtend,
+	        _self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TEObj_TESetStyleHandle(TEObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	TEStyleHandle theHandle;
+#ifndef TESetStyleHandle
+	PyMac_PRECHECK(TESetStyleHandle);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &theHandle))
+		return NULL;
+	TESetStyleHandle(theHandle,
+	                 _self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TEObj_TEGetStyleHandle(TEObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	TEStyleHandle _rv;
+#ifndef TEGetStyleHandle
+	PyMac_PRECHECK(TEGetStyleHandle);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = TEGetStyleHandle(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *TEObj_TEGetStyle(TEObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short offset;
+	TextStyle theStyle;
+	short lineHeight;
+	short fontAscent;
+#ifndef TEGetStyle
+	PyMac_PRECHECK(TEGetStyle);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &offset))
+		return NULL;
+	TEGetStyle(offset,
+	           &theStyle,
+	           &lineHeight,
+	           &fontAscent,
+	           _self->ob_itself);
+	_res = Py_BuildValue("O&hh",
+	                     TextStyle_New, &theStyle,
+	                     lineHeight,
+	                     fontAscent);
+	return _res;
+}
+
+static PyObject *TEObj_TEStylePaste(TEObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef TEStylePaste
+	PyMac_PRECHECK(TEStylePaste);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	TEStylePaste(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TEObj_TESetStyle(TEObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short mode;
+	TextStyle newStyle;
+	Boolean fRedraw;
+#ifndef TESetStyle
+	PyMac_PRECHECK(TESetStyle);
+#endif
+	if (!PyArg_ParseTuple(_args, "hO&b",
+	                      &mode,
+	                      TextStyle_Convert, &newStyle,
+	                      &fRedraw))
+		return NULL;
+	TESetStyle(mode,
+	           &newStyle,
+	           fRedraw,
+	           _self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TEObj_TEReplaceStyle(TEObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short mode;
+	TextStyle oldStyle;
+	TextStyle newStyle;
+	Boolean fRedraw;
+#ifndef TEReplaceStyle
+	PyMac_PRECHECK(TEReplaceStyle);
+#endif
+	if (!PyArg_ParseTuple(_args, "hO&O&b",
+	                      &mode,
+	                      TextStyle_Convert, &oldStyle,
+	                      TextStyle_Convert, &newStyle,
+	                      &fRedraw))
+		return NULL;
+	TEReplaceStyle(mode,
+	               &oldStyle,
+	               &newStyle,
+	               fRedraw,
+	               _self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TEObj_TEGetStyleScrapHandle(TEObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	StScrpHandle _rv;
+#ifndef TEGetStyleScrapHandle
+	PyMac_PRECHECK(TEGetStyleScrapHandle);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = TEGetStyleScrapHandle(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *TEObj_TEStyleInsert(TEObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	char *text__in__;
+	long text__len__;
+	int text__in_len__;
+	StScrpHandle hST;
+#ifndef TEStyleInsert
+	PyMac_PRECHECK(TEStyleInsert);
+#endif
+	if (!PyArg_ParseTuple(_args, "s#O&",
+	                      &text__in__, &text__in_len__,
+	                      ResObj_Convert, &hST))
+		return NULL;
+	text__len__ = text__in_len__;
+	TEStyleInsert(text__in__, text__len__,
+	              hST,
+	              _self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TEObj_TEGetHeight(TEObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long _rv;
+	long endLine;
+	long startLine;
+#ifndef TEGetHeight
+	PyMac_PRECHECK(TEGetHeight);
+#endif
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &endLine,
+	                      &startLine))
+		return NULL;
+	_rv = TEGetHeight(endLine,
+	                  startLine,
+	                  _self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *TEObj_TEContinuousStyle(TEObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	short mode;
+	TextStyle aStyle;
+#ifndef TEContinuousStyle
+	PyMac_PRECHECK(TEContinuousStyle);
+#endif
+	if (!PyArg_ParseTuple(_args, "hO&",
+	                      &mode,
+	                      TextStyle_Convert, &aStyle))
+		return NULL;
+	_rv = TEContinuousStyle(&mode,
+	                        &aStyle,
+	                        _self->ob_itself);
+	_res = Py_BuildValue("bhO&",
+	                     _rv,
+	                     mode,
+	                     TextStyle_New, &aStyle);
+	return _res;
+}
+
+static PyObject *TEObj_TEUseStyleScrap(TEObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long rangeStart;
+	long rangeEnd;
+	StScrpHandle newStyles;
+	Boolean fRedraw;
+#ifndef TEUseStyleScrap
+	PyMac_PRECHECK(TEUseStyleScrap);
+#endif
+	if (!PyArg_ParseTuple(_args, "llO&b",
+	                      &rangeStart,
+	                      &rangeEnd,
+	                      ResObj_Convert, &newStyles,
+	                      &fRedraw))
+		return NULL;
+	TEUseStyleScrap(rangeStart,
+	                rangeEnd,
+	                newStyles,
+	                fRedraw,
+	                _self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TEObj_TENumStyles(TEObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long _rv;
+	long rangeStart;
+	long rangeEnd;
+#ifndef TENumStyles
+	PyMac_PRECHECK(TENumStyles);
+#endif
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &rangeStart,
+	                      &rangeEnd))
+		return NULL;
+	_rv = TENumStyles(rangeStart,
+	                  rangeEnd,
+	                  _self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *TEObj_TEFeatureFlag(TEObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short _rv;
+	short feature;
+	short action;
+#ifndef TEFeatureFlag
+	PyMac_PRECHECK(TEFeatureFlag);
+#endif
+	if (!PyArg_ParseTuple(_args, "hh",
+	                      &feature,
+	                      &action))
+		return NULL;
+	_rv = TEFeatureFlag(feature,
+	                    action,
+	                    _self->ob_itself);
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *TEObj_TEGetHiliteRgn(TEObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+	RgnHandle region;
+#ifndef TEGetHiliteRgn
+	PyMac_PRECHECK(TEGetHiliteRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &region))
+		return NULL;
+	_err = TEGetHiliteRgn(region,
+	                      _self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TEObj_as_Resource(TEObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Handle _rv;
+#ifndef as_Resource
+	PyMac_PRECHECK(as_Resource);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = as_Resource(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyMethodDef TEObj_methods[] = {
+	{"TESetText", (PyCFunction)TEObj_TESetText, 1,
+	 PyDoc_STR("(Buffer text) -> None")},
+	{"TEGetText", (PyCFunction)TEObj_TEGetText, 1,
+	 PyDoc_STR("() -> (CharsHandle _rv)")},
+	{"TEIdle", (PyCFunction)TEObj_TEIdle, 1,
+	 PyDoc_STR("() -> None")},
+	{"TESetSelect", (PyCFunction)TEObj_TESetSelect, 1,
+	 PyDoc_STR("(long selStart, long selEnd) -> None")},
+	{"TEActivate", (PyCFunction)TEObj_TEActivate, 1,
+	 PyDoc_STR("() -> None")},
+	{"TEDeactivate", (PyCFunction)TEObj_TEDeactivate, 1,
+	 PyDoc_STR("() -> None")},
+	{"TEKey", (PyCFunction)TEObj_TEKey, 1,
+	 PyDoc_STR("(CharParameter key) -> None")},
+	{"TECut", (PyCFunction)TEObj_TECut, 1,
+	 PyDoc_STR("() -> None")},
+	{"TECopy", (PyCFunction)TEObj_TECopy, 1,
+	 PyDoc_STR("() -> None")},
+	{"TEPaste", (PyCFunction)TEObj_TEPaste, 1,
+	 PyDoc_STR("() -> None")},
+	{"TEDelete", (PyCFunction)TEObj_TEDelete, 1,
+	 PyDoc_STR("() -> None")},
+	{"TEInsert", (PyCFunction)TEObj_TEInsert, 1,
+	 PyDoc_STR("(Buffer text) -> None")},
+	{"TESetAlignment", (PyCFunction)TEObj_TESetAlignment, 1,
+	 PyDoc_STR("(short just) -> None")},
+	{"TEUpdate", (PyCFunction)TEObj_TEUpdate, 1,
+	 PyDoc_STR("(Rect rUpdate) -> None")},
+	{"TEScroll", (PyCFunction)TEObj_TEScroll, 1,
+	 PyDoc_STR("(short dh, short dv) -> None")},
+	{"TESelView", (PyCFunction)TEObj_TESelView, 1,
+	 PyDoc_STR("() -> None")},
+	{"TEPinScroll", (PyCFunction)TEObj_TEPinScroll, 1,
+	 PyDoc_STR("(short dh, short dv) -> None")},
+	{"TEAutoView", (PyCFunction)TEObj_TEAutoView, 1,
+	 PyDoc_STR("(Boolean fAuto) -> None")},
+	{"TECalText", (PyCFunction)TEObj_TECalText, 1,
+	 PyDoc_STR("() -> None")},
+	{"TEGetOffset", (PyCFunction)TEObj_TEGetOffset, 1,
+	 PyDoc_STR("(Point pt) -> (short _rv)")},
+	{"TEGetPoint", (PyCFunction)TEObj_TEGetPoint, 1,
+	 PyDoc_STR("(short offset) -> (Point _rv)")},
+	{"TEClick", (PyCFunction)TEObj_TEClick, 1,
+	 PyDoc_STR("(Point pt, Boolean fExtend) -> None")},
+	{"TESetStyleHandle", (PyCFunction)TEObj_TESetStyleHandle, 1,
+	 PyDoc_STR("(TEStyleHandle theHandle) -> None")},
+	{"TEGetStyleHandle", (PyCFunction)TEObj_TEGetStyleHandle, 1,
+	 PyDoc_STR("() -> (TEStyleHandle _rv)")},
+	{"TEGetStyle", (PyCFunction)TEObj_TEGetStyle, 1,
+	 PyDoc_STR("(short offset) -> (TextStyle theStyle, short lineHeight, short fontAscent)")},
+	{"TEStylePaste", (PyCFunction)TEObj_TEStylePaste, 1,
+	 PyDoc_STR("() -> None")},
+	{"TESetStyle", (PyCFunction)TEObj_TESetStyle, 1,
+	 PyDoc_STR("(short mode, TextStyle newStyle, Boolean fRedraw) -> None")},
+	{"TEReplaceStyle", (PyCFunction)TEObj_TEReplaceStyle, 1,
+	 PyDoc_STR("(short mode, TextStyle oldStyle, TextStyle newStyle, Boolean fRedraw) -> None")},
+	{"TEGetStyleScrapHandle", (PyCFunction)TEObj_TEGetStyleScrapHandle, 1,
+	 PyDoc_STR("() -> (StScrpHandle _rv)")},
+	{"TEStyleInsert", (PyCFunction)TEObj_TEStyleInsert, 1,
+	 PyDoc_STR("(Buffer text, StScrpHandle hST) -> None")},
+	{"TEGetHeight", (PyCFunction)TEObj_TEGetHeight, 1,
+	 PyDoc_STR("(long endLine, long startLine) -> (long _rv)")},
+	{"TEContinuousStyle", (PyCFunction)TEObj_TEContinuousStyle, 1,
+	 PyDoc_STR("(short mode, TextStyle aStyle) -> (Boolean _rv, short mode, TextStyle aStyle)")},
+	{"TEUseStyleScrap", (PyCFunction)TEObj_TEUseStyleScrap, 1,
+	 PyDoc_STR("(long rangeStart, long rangeEnd, StScrpHandle newStyles, Boolean fRedraw) -> None")},
+	{"TENumStyles", (PyCFunction)TEObj_TENumStyles, 1,
+	 PyDoc_STR("(long rangeStart, long rangeEnd) -> (long _rv)")},
+	{"TEFeatureFlag", (PyCFunction)TEObj_TEFeatureFlag, 1,
+	 PyDoc_STR("(short feature, short action) -> (short _rv)")},
+	{"TEGetHiliteRgn", (PyCFunction)TEObj_TEGetHiliteRgn, 1,
+	 PyDoc_STR("(RgnHandle region) -> None")},
+	{"as_Resource", (PyCFunction)TEObj_as_Resource, 1,
+	 PyDoc_STR("() -> (Handle _rv)")},
+	{NULL, NULL, 0}
+};
+
+static PyObject *TEObj_get_destRect(TEObject *self, void *closure)
+{
+	return Py_BuildValue("O&", PyMac_BuildRect, &(*self->ob_itself)->destRect);
+}
+
+#define TEObj_set_destRect NULL
+
+static PyObject *TEObj_get_viewRect(TEObject *self, void *closure)
+{
+	return Py_BuildValue("O&", PyMac_BuildRect, &(*self->ob_itself)->viewRect);
+}
+
+#define TEObj_set_viewRect NULL
+
+static PyObject *TEObj_get_selRect(TEObject *self, void *closure)
+{
+	return Py_BuildValue("O&", PyMac_BuildRect, &(*self->ob_itself)->selRect);
+}
+
+#define TEObj_set_selRect NULL
+
+static PyObject *TEObj_get_lineHeight(TEObject *self, void *closure)
+{
+	return Py_BuildValue("h", (*self->ob_itself)->lineHeight);
+}
+
+#define TEObj_set_lineHeight NULL
+
+static PyObject *TEObj_get_fontAscent(TEObject *self, void *closure)
+{
+	return Py_BuildValue("h", (*self->ob_itself)->fontAscent);
+}
+
+#define TEObj_set_fontAscent NULL
+
+static PyObject *TEObj_get_selPoint(TEObject *self, void *closure)
+{
+	return Py_BuildValue("O&", PyMac_BuildPoint, (*self->ob_itself)->selPoint);
+}
+
+#define TEObj_set_selPoint NULL
+
+static PyObject *TEObj_get_selStart(TEObject *self, void *closure)
+{
+	return Py_BuildValue("h", (*self->ob_itself)->selStart);
+}
+
+#define TEObj_set_selStart NULL
+
+static PyObject *TEObj_get_selEnd(TEObject *self, void *closure)
+{
+	return Py_BuildValue("h", (*self->ob_itself)->selEnd);
+}
+
+#define TEObj_set_selEnd NULL
+
+static PyObject *TEObj_get_active(TEObject *self, void *closure)
+{
+	return Py_BuildValue("h", (*self->ob_itself)->active);
+}
+
+#define TEObj_set_active NULL
+
+static PyObject *TEObj_get_just(TEObject *self, void *closure)
+{
+	return Py_BuildValue("h", (*self->ob_itself)->just);
+}
+
+#define TEObj_set_just NULL
+
+static PyObject *TEObj_get_teLength(TEObject *self, void *closure)
+{
+	return Py_BuildValue("h", (*self->ob_itself)->teLength);
+}
+
+#define TEObj_set_teLength NULL
+
+static PyObject *TEObj_get_txFont(TEObject *self, void *closure)
+{
+	return Py_BuildValue("h", (*self->ob_itself)->txFont);
+}
+
+#define TEObj_set_txFont NULL
+
+static PyObject *TEObj_get_txFace(TEObject *self, void *closure)
+{
+	return Py_BuildValue("h", (*self->ob_itself)->txFace);
+}
+
+#define TEObj_set_txFace NULL
+
+static PyObject *TEObj_get_txMode(TEObject *self, void *closure)
+{
+	return Py_BuildValue("h", (*self->ob_itself)->txMode);
+}
+
+#define TEObj_set_txMode NULL
+
+static PyObject *TEObj_get_txSize(TEObject *self, void *closure)
+{
+	return Py_BuildValue("h", (*self->ob_itself)->txSize);
+}
+
+#define TEObj_set_txSize NULL
+
+static PyObject *TEObj_get_nLines(TEObject *self, void *closure)
+{
+	return Py_BuildValue("h", (*self->ob_itself)->nLines);
+}
+
+#define TEObj_set_nLines NULL
+
+static PyGetSetDef TEObj_getsetlist[] = {
+	{"destRect", (getter)TEObj_get_destRect, (setter)TEObj_set_destRect, "Destination rectangle"},
+	{"viewRect", (getter)TEObj_get_viewRect, (setter)TEObj_set_viewRect, "Viewing rectangle"},
+	{"selRect", (getter)TEObj_get_selRect, (setter)TEObj_set_selRect, "Selection rectangle"},
+	{"lineHeight", (getter)TEObj_get_lineHeight, (setter)TEObj_set_lineHeight, "Height of a line"},
+	{"fontAscent", (getter)TEObj_get_fontAscent, (setter)TEObj_set_fontAscent, "Ascent of a line"},
+	{"selPoint", (getter)TEObj_get_selPoint, (setter)TEObj_set_selPoint, "Selection Point"},
+	{"selStart", (getter)TEObj_get_selStart, (setter)TEObj_set_selStart, "Start of selection"},
+	{"selEnd", (getter)TEObj_get_selEnd, (setter)TEObj_set_selEnd, "End of selection"},
+	{"active", (getter)TEObj_get_active, (setter)TEObj_set_active, "TBD"},
+	{"just", (getter)TEObj_get_just, (setter)TEObj_set_just, "Justification"},
+	{"teLength", (getter)TEObj_get_teLength, (setter)TEObj_set_teLength, "TBD"},
+	{"txFont", (getter)TEObj_get_txFont, (setter)TEObj_set_txFont, "Current font"},
+	{"txFace", (getter)TEObj_get_txFace, (setter)TEObj_set_txFace, "Current font variant"},
+	{"txMode", (getter)TEObj_get_txMode, (setter)TEObj_set_txMode, "Current text-drawing mode"},
+	{"txSize", (getter)TEObj_get_txSize, (setter)TEObj_set_txSize, "Current font size"},
+	{"nLines", (getter)TEObj_get_nLines, (setter)TEObj_set_nLines, "TBD"},
+	{NULL, NULL, NULL, NULL},
+};
+
+
+#define TEObj_compare NULL
+
+#define TEObj_repr NULL
+
+#define TEObj_hash NULL
+#define TEObj_tp_init 0
+
+#define TEObj_tp_alloc PyType_GenericAlloc
+
+static PyObject *TEObj_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *_self;
+	TEHandle itself;
+	char *kw[] = {"itself", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, TEObj_Convert, &itself)) return NULL;
+	if ((_self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	((TEObject *)_self)->ob_itself = itself;
+	return _self;
+}
+
+#define TEObj_tp_free PyObject_Del
+
+
+PyTypeObject TE_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"_TE.TE", /*tp_name*/
+	sizeof(TEObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) TEObj_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) TEObj_compare, /*tp_compare*/
+	(reprfunc) TEObj_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) TEObj_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	TEObj_methods, /* tp_methods */
+	0, /*tp_members*/
+	TEObj_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	TEObj_tp_init, /* tp_init */
+	TEObj_tp_alloc, /* tp_alloc */
+	TEObj_tp_new, /* tp_new */
+	TEObj_tp_free, /* tp_free */
+};
+
+/* ----------------------- End object type TE ----------------------- */
+
+
+static PyObject *TE_TEScrapHandle(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Handle _rv;
+#ifndef TEScrapHandle
+	PyMac_PRECHECK(TEScrapHandle);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = TEScrapHandle();
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *TE_TEGetScrapLength(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long _rv;
+#ifndef TEGetScrapLength
+	PyMac_PRECHECK(TEGetScrapLength);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = TEGetScrapLength();
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *TE_TENew(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	TEHandle _rv;
+	Rect destRect;
+	Rect viewRect;
+#ifndef TENew
+	PyMac_PRECHECK(TENew);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetRect, &destRect,
+	                      PyMac_GetRect, &viewRect))
+		return NULL;
+	_rv = TENew(&destRect,
+	            &viewRect);
+	_res = Py_BuildValue("O&",
+	                     TEObj_New, _rv);
+	return _res;
+}
+
+static PyObject *TE_TETextBox(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	char *text__in__;
+	long text__len__;
+	int text__in_len__;
+	Rect box;
+	short just;
+#ifndef TETextBox
+	PyMac_PRECHECK(TETextBox);
+#endif
+	if (!PyArg_ParseTuple(_args, "s#O&h",
+	                      &text__in__, &text__in_len__,
+	                      PyMac_GetRect, &box,
+	                      &just))
+		return NULL;
+	text__len__ = text__in_len__;
+	TETextBox(text__in__, text__len__,
+	          &box,
+	          just);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TE_TEStyleNew(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	TEHandle _rv;
+	Rect destRect;
+	Rect viewRect;
+#ifndef TEStyleNew
+	PyMac_PRECHECK(TEStyleNew);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetRect, &destRect,
+	                      PyMac_GetRect, &viewRect))
+		return NULL;
+	_rv = TEStyleNew(&destRect,
+	                 &viewRect);
+	_res = Py_BuildValue("O&",
+	                     TEObj_New, _rv);
+	return _res;
+}
+
+static PyObject *TE_TESetScrapLength(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long length;
+#ifndef TESetScrapLength
+	PyMac_PRECHECK(TESetScrapLength);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &length))
+		return NULL;
+	TESetScrapLength(length);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TE_TEFromScrap(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+#ifndef TEFromScrap
+	PyMac_PRECHECK(TEFromScrap);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = TEFromScrap();
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TE_TEToScrap(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSErr _err;
+#ifndef TEToScrap
+	PyMac_PRECHECK(TEToScrap);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = TEToScrap();
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TE_TEGetScrapHandle(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Handle _rv;
+#ifndef TEGetScrapHandle
+	PyMac_PRECHECK(TEGetScrapHandle);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = TEGetScrapHandle();
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *TE_TESetScrapHandle(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Handle value;
+#ifndef TESetScrapHandle
+	PyMac_PRECHECK(TESetScrapHandle);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &value))
+		return NULL;
+	TESetScrapHandle(value);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TE_LMGetWordRedraw(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	UInt8 _rv;
+#ifndef LMGetWordRedraw
+	PyMac_PRECHECK(LMGetWordRedraw);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = LMGetWordRedraw();
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *TE_LMSetWordRedraw(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	UInt8 value;
+#ifndef LMSetWordRedraw
+	PyMac_PRECHECK(LMSetWordRedraw);
+#endif
+	if (!PyArg_ParseTuple(_args, "b",
+	                      &value))
+		return NULL;
+	LMSetWordRedraw(value);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *TE_as_TE(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	TEHandle _rv;
+	Handle h;
+#ifndef as_TE
+	PyMac_PRECHECK(as_TE);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &h))
+		return NULL;
+	_rv = as_TE(h);
+	_res = Py_BuildValue("O&",
+	                     TEObj_New, _rv);
+	return _res;
+}
+
+static PyMethodDef TE_methods[] = {
+	{"TEScrapHandle", (PyCFunction)TE_TEScrapHandle, 1,
+	 PyDoc_STR("() -> (Handle _rv)")},
+	{"TEGetScrapLength", (PyCFunction)TE_TEGetScrapLength, 1,
+	 PyDoc_STR("() -> (long _rv)")},
+	{"TENew", (PyCFunction)TE_TENew, 1,
+	 PyDoc_STR("(Rect destRect, Rect viewRect) -> (TEHandle _rv)")},
+	{"TETextBox", (PyCFunction)TE_TETextBox, 1,
+	 PyDoc_STR("(Buffer text, Rect box, short just) -> None")},
+	{"TEStyleNew", (PyCFunction)TE_TEStyleNew, 1,
+	 PyDoc_STR("(Rect destRect, Rect viewRect) -> (TEHandle _rv)")},
+	{"TESetScrapLength", (PyCFunction)TE_TESetScrapLength, 1,
+	 PyDoc_STR("(long length) -> None")},
+	{"TEFromScrap", (PyCFunction)TE_TEFromScrap, 1,
+	 PyDoc_STR("() -> None")},
+	{"TEToScrap", (PyCFunction)TE_TEToScrap, 1,
+	 PyDoc_STR("() -> None")},
+	{"TEGetScrapHandle", (PyCFunction)TE_TEGetScrapHandle, 1,
+	 PyDoc_STR("() -> (Handle _rv)")},
+	{"TESetScrapHandle", (PyCFunction)TE_TESetScrapHandle, 1,
+	 PyDoc_STR("(Handle value) -> None")},
+	{"LMGetWordRedraw", (PyCFunction)TE_LMGetWordRedraw, 1,
+	 PyDoc_STR("() -> (UInt8 _rv)")},
+	{"LMSetWordRedraw", (PyCFunction)TE_LMSetWordRedraw, 1,
+	 PyDoc_STR("(UInt8 value) -> None")},
+	{"as_TE", (PyCFunction)TE_as_TE, 1,
+	 PyDoc_STR("(Handle h) -> (TEHandle _rv)")},
+	{NULL, NULL, 0}
+};
+
+
+
+
+void init_TE(void)
+{
+	PyObject *m;
+	PyObject *d;
+
+
+
+	        PyMac_INIT_TOOLBOX_OBJECT_NEW(TEHandle, TEObj_New);
+	        PyMac_INIT_TOOLBOX_OBJECT_CONVERT(TEHandle, TEObj_Convert);
+
+
+	m = Py_InitModule("_TE", TE_methods);
+	d = PyModule_GetDict(m);
+	TE_Error = PyMac_GetOSErrException();
+	if (TE_Error == NULL ||
+	    PyDict_SetItemString(d, "Error", TE_Error) != 0)
+		return;
+	TE_Type.ob_type = &PyType_Type;
+	if (PyType_Ready(&TE_Type) < 0) return;
+	Py_INCREF(&TE_Type);
+	PyModule_AddObject(m, "TE", (PyObject *)&TE_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&TE_Type);
+	PyModule_AddObject(m, "TEType", (PyObject *)&TE_Type);
+}
+
+/* ========================= End module _TE ========================= */
+

Added: vendor/Python/current/Mac/Modules/te/tescan.py
===================================================================
--- vendor/Python/current/Mac/Modules/te/tescan.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/te/tescan.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,67 @@
+# Scan an Apple header file, generating a Python file of generator calls.
+
+import sys
+import os
+from bgenlocations import TOOLBOXDIR, BGENDIR
+sys.path.append(BGENDIR)
+from scantools import Scanner
+
+LONG = "TextEdit"
+SHORT = "te"
+OBJECT = "TEHandle"
+
+def main():
+    input = LONG + ".h"
+    output = SHORT + "gen.py"
+    defsoutput = TOOLBOXDIR + LONG + ".py"
+    scanner = MyScanner(input, output, defsoutput)
+    scanner.scan()
+    scanner.close()
+    print "=== Testing definitions output code ==="
+    execfile(defsoutput, {}, {})
+    print "=== Done scanning and generating, now importing the generated code... ==="
+    exec "import " + SHORT + "support"
+    print "=== Done.  It's up to you to compile it now! ==="
+
+class MyScanner(Scanner):
+
+    def destination(self, type, name, arglist):
+        classname = "Function"
+        listname = "functions"
+        if arglist:
+            t, n, m = arglist[-1]
+            # This is non-functional today
+            if t == OBJECT and m == "InMode":
+                classname = "Method"
+                listname = "methods"
+        return classname, listname
+
+    def makeblacklistnames(self):
+        return [
+                "TEDispose",
+                "TEInit",
+##                      "TEGetHiliteRgn",
+                ]
+
+    def makeblacklisttypes(self):
+        return [
+                "TEClickLoopUPP",
+                "UniversalProcPtr",
+                "WordBreakUPP",
+                "TEDoTextUPP",
+                "TERecalcUPP",
+                "TEFindWordUPP",
+                ]
+
+    def makerepairinstructions(self):
+        return [
+                ([("void_ptr", "*", "InMode"), ("long", "*", "InMode")],
+                 [("InBuffer", "*", "*")]),
+
+                # TEContinuousStyle
+                ([("short", "mode", "OutMode"), ("TextStyle", "aStyle", "OutMode")],
+                 [("short", "mode", "InOutMode"), ("TextStyle", "aStyle", "InOutMode")])
+                ]
+
+if __name__ == "__main__":
+    main()

Added: vendor/Python/current/Mac/Modules/te/tesupport.py
===================================================================
--- vendor/Python/current/Mac/Modules/te/tesupport.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/te/tesupport.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,216 @@
+# This script generates a Python interface for an Apple Macintosh Manager.
+# It uses the "bgen" package to generate C code.
+# The function specifications are generated by scanning the mamager's header file,
+# using the "scantools" package (customized for this particular manager).
+
+import string
+
+# Declarations that change for each manager
+MACHEADERFILE = 'TextEdit.h'            # The Apple header file
+MODNAME = '_TE'                         # The name of the module
+OBJECTNAME = 'TE'                       # The basic name of the objects used here
+KIND = 'Handle'                         # Usually 'Ptr' or 'Handle'
+
+# The following is *usually* unchanged but may still require tuning
+MODPREFIX = 'TE'                        # The prefix for module-wide routines
+OBJECTTYPE = "TEHandle"         # The C type used to represent them
+OBJECTPREFIX = MODPREFIX + 'Obj'        # The prefix for object methods
+INPUTFILE = string.lower(MODPREFIX) + 'gen.py' # The file generated by the scanner
+OUTPUTFILE = MODNAME + "module.c"       # The file generated by this program
+
+from macsupport import *
+
+# Create the type objects
+TEHandle = OpaqueByValueType("TEHandle", "TEObj")
+CharsHandle = OpaqueByValueType("CharsHandle", "ResObj")
+Handle = OpaqueByValueType("Handle", "ResObj")
+StScrpHandle = OpaqueByValueType("StScrpHandle", "ResObj")
+TEStyleHandle = OpaqueByValueType("TEStyleHandle", "ResObj")
+RgnHandle = OpaqueByValueType("RgnHandle", "ResObj")
+
+TextStyle = OpaqueType("TextStyle", "TextStyle")
+TextStyle_ptr = TextStyle
+
+includestuff = includestuff + """
+#include <Carbon/Carbon.h>
+
+#ifdef USE_TOOLBOX_OBJECT_GLUE
+extern PyObject *_TEObj_New(TEHandle);
+extern int _TEObj_Convert(PyObject *, TEHandle *);
+
+#define TEObj_New _TEObj_New
+#define TEObj_Convert _TEObj_Convert
+#endif
+
+#define as_TE(h) ((TEHandle)h)
+#define as_Resource(teh) ((Handle)teh)
+
+/*
+** Parse/generate TextStyle records
+*/
+static PyObject *
+TextStyle_New(TextStylePtr itself)
+{
+
+        return Py_BuildValue("lllO&", (long)itself->tsFont, (long)itself->tsFace, (long)itself->tsSize, QdRGB_New,
+                                &itself->tsColor);
+}
+
+static int
+TextStyle_Convert(PyObject *v, TextStylePtr p_itself)
+{
+        long font, face, size;
+
+        if( !PyArg_ParseTuple(v, "lllO&", &font, &face, &size, QdRGB_Convert, &p_itself->tsColor) )
+                return 0;
+        p_itself->tsFont = (short)font;
+        p_itself->tsFace = (Style)face;
+        p_itself->tsSize = (short)size;
+        return 1;
+}
+"""
+
+initstuff = initstuff + """
+        PyMac_INIT_TOOLBOX_OBJECT_NEW(TEHandle, TEObj_New);
+        PyMac_INIT_TOOLBOX_OBJECT_CONVERT(TEHandle, TEObj_Convert);
+"""
+
+class TEMethodGenerator(OSErrWeakLinkMethodGenerator):
+    """Similar to MethodGenerator, but has self as last argument"""
+
+    def parseArgumentList(self, args):
+        args, a0 = args[:-1], args[-1]
+        t0, n0, m0 = a0
+        if m0 != InMode:
+            raise ValueError, "method's 'self' must be 'InMode'"
+        self.itself = Variable(t0, "_self->ob_itself", SelfMode)
+        FunctionGenerator.parseArgumentList(self, args)
+        self.argumentList.append(self.itself)
+
+
+
+class MyObjectDefinition(PEP253Mixin, GlobalObjectDefinition):
+    # XXXX Could be subtype of Resource
+    # Attributes that can be set.
+    getsetlist = [
+            (
+            'destRect',
+            'return Py_BuildValue("O&", PyMac_BuildRect, &(*self->ob_itself)->destRect);',
+            None,
+            'Destination rectangle'
+            ), (
+            'viewRect',
+            'return Py_BuildValue("O&", PyMac_BuildRect, &(*self->ob_itself)->viewRect);',
+            None,
+            'Viewing rectangle'
+            ), (
+            'selRect',
+            'return Py_BuildValue("O&", PyMac_BuildRect, &(*self->ob_itself)->selRect);',
+            None,
+            'Selection rectangle'
+            ), (
+            'lineHeight',
+            'return Py_BuildValue("h", (*self->ob_itself)->lineHeight);',
+            None,
+            'Height of a line'
+            ), (
+            'fontAscent',
+            'return Py_BuildValue("h", (*self->ob_itself)->fontAscent);',
+            None,
+            'Ascent of a line'
+            ), (
+            "selPoint",
+            'return Py_BuildValue("O&", PyMac_BuildPoint, (*self->ob_itself)->selPoint);',
+            None,
+            'Selection Point'
+            ), (
+            'selStart',
+            'return Py_BuildValue("h", (*self->ob_itself)->selStart);',
+            None,
+            'Start of selection'
+            ), (
+            'selEnd',
+            'return Py_BuildValue("h", (*self->ob_itself)->selEnd);',
+            None,
+            'End of selection'
+            ), (
+            'active',
+            'return Py_BuildValue("h", (*self->ob_itself)->active);',
+            None,
+            'TBD'
+            ), (
+            'just',
+            'return Py_BuildValue("h", (*self->ob_itself)->just);',
+            None,
+            'Justification'
+            ), (
+            'teLength',
+            'return Py_BuildValue("h", (*self->ob_itself)->teLength);',
+            None,
+            'TBD'
+            ), (
+            'txFont',
+            'return Py_BuildValue("h", (*self->ob_itself)->txFont);',
+            None,
+            'Current font'
+            ), (
+            'txFace',
+            'return Py_BuildValue("h", (*self->ob_itself)->txFace);',
+            None,
+            'Current font variant'
+            ), (
+            'txMode',
+            'return Py_BuildValue("h", (*self->ob_itself)->txMode);',
+            None,
+            'Current text-drawing mode'
+            ), (
+            'txSize',
+            'return Py_BuildValue("h", (*self->ob_itself)->txSize);',
+            None,
+            'Current font size'
+            ), (
+            'nLines',
+            'return Py_BuildValue("h", (*self->ob_itself)->nLines);',
+            None,
+            'TBD'
+            )]
+
+    def outputCheckNewArg(self):
+        Output("""if (itself == NULL) {
+                                PyErr_SetString(TE_Error,"Cannot create null TE");
+                                return NULL;
+                        }""")
+    def outputFreeIt(self, itselfname):
+        Output("TEDispose(%s);", itselfname)
+
+
+# From here on it's basically all boiler plate...
+
+# Create the generator groups and link them
+module = MacModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff)
+object = MyObjectDefinition(OBJECTNAME, OBJECTPREFIX, OBJECTTYPE)
+module.addobject(object)
+
+# Create the generator classes used to populate the lists
+Function = OSErrWeakLinkFunctionGenerator
+Method = TEMethodGenerator
+
+# Create and populate the lists
+functions = []
+methods = []
+execfile(INPUTFILE)
+
+# Converter from/to handle
+f = Function(TEHandle, 'as_TE', (Handle, 'h', InMode))
+functions.append(f)
+f = Method(Handle, 'as_Resource', (TEHandle, 'teh', InMode))
+methods.append(f)
+
+# add the populated lists to the generator groups
+# (in a different wordl the scan program would generate this)
+for f in functions: module.add(f)
+for f in methods: object.add(f)
+
+# generate output (open the output file as late as possible)
+SetOutputFileName(OUTPUTFILE)
+module.generate()

Added: vendor/Python/current/Mac/Modules/win/_Winmodule.c
===================================================================
--- vendor/Python/current/Mac/Modules/win/_Winmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/win/_Winmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,3258 @@
+
+/* ========================== Module _Win =========================== */
+
+#include "Python.h"
+
+
+
+#include "pymactoolbox.h"
+
+/* Macro to test whether a weak-loaded CFM function exists */
+#define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL )  {\
+        PyErr_SetString(PyExc_NotImplementedError, \
+        "Not available in this shared library/OS version"); \
+        return NULL; \
+    }} while(0)
+
+
+#include <Carbon/Carbon.h>
+
+#ifdef USE_TOOLBOX_OBJECT_GLUE
+extern PyObject *_WinObj_New(WindowRef);
+extern PyObject *_WinObj_WhichWindow(WindowRef);
+extern int _WinObj_Convert(PyObject *, WindowRef *);
+
+#define WinObj_New _WinObj_New
+#define WinObj_WhichWindow _WinObj_WhichWindow
+#define WinObj_Convert _WinObj_Convert
+#endif
+
+/* Classic calls that we emulate in carbon mode */
+#define GetWindowUpdateRgn(win, rgn) GetWindowRegion((win), kWindowUpdateRgn, (rgn))
+#define GetWindowStructureRgn(win, rgn) GetWindowRegion((win), kWindowStructureRgn, (rgn))
+#define GetWindowContentRgn(win, rgn) GetWindowRegion((win), kWindowContentRgn, (rgn))
+
+/* Function to dispose a window, with a "normal" calling sequence */
+static void
+PyMac_AutoDisposeWindow(WindowPtr w)
+{
+        DisposeWindow(w);
+}
+
+static PyObject *Win_Error;
+
+/* ----------------------- Object type Window ----------------------- */
+
+PyTypeObject Window_Type;
+
+#define WinObj_Check(x) ((x)->ob_type == &Window_Type || PyObject_TypeCheck((x), &Window_Type))
+
+typedef struct WindowObject {
+	PyObject_HEAD
+	WindowPtr ob_itself;
+	void (*ob_freeit)(WindowPtr ptr);
+} WindowObject;
+
+PyObject *WinObj_New(WindowPtr itself)
+{
+	WindowObject *it;
+	if (itself == NULL) return PyMac_Error(resNotFound);
+	/* XXXX Or should we use WhichWindow code here? */
+	it = PyObject_NEW(WindowObject, &Window_Type);
+	if (it == NULL) return NULL;
+	it->ob_itself = itself;
+	it->ob_freeit = NULL;
+	if (GetWRefCon(itself) == 0)
+	{
+		SetWRefCon(itself, (long)it);
+		it->ob_freeit = PyMac_AutoDisposeWindow;
+	}
+	return (PyObject *)it;
+}
+
+int WinObj_Convert(PyObject *v, WindowPtr *p_itself)
+{
+
+	if (v == Py_None) { *p_itself = NULL; return 1; }
+	if (PyInt_Check(v)) { *p_itself = (WindowPtr)PyInt_AsLong(v); return 1; }
+
+	{
+		DialogRef dlg;
+		if (DlgObj_Convert(v, &dlg) && dlg) {
+			*p_itself = GetDialogWindow(dlg);
+			return 1;
+		}
+		PyErr_Clear();
+	}
+	if (!WinObj_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "Window required");
+		return 0;
+	}
+	*p_itself = ((WindowObject *)v)->ob_itself;
+	return 1;
+}
+
+static void WinObj_dealloc(WindowObject *self)
+{
+	if (self->ob_freeit && self->ob_itself)
+	{
+		SetWRefCon(self->ob_itself, 0);
+		self->ob_freeit(self->ob_itself);
+	}
+	self->ob_itself = NULL;
+	self->ob_freeit = NULL;
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *WinObj_GetWindowOwnerCount(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 outCount;
+#ifndef GetWindowOwnerCount
+	PyMac_PRECHECK(GetWindowOwnerCount);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetWindowOwnerCount(_self->ob_itself,
+	                           &outCount);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     outCount);
+	return _res;
+}
+
+static PyObject *WinObj_CloneWindow(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+#ifndef CloneWindow
+	PyMac_PRECHECK(CloneWindow);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = CloneWindow(_self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_GetWindowRetainCount(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	ItemCount _rv;
+#ifndef GetWindowRetainCount
+	PyMac_PRECHECK(GetWindowRetainCount);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetWindowRetainCount(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *WinObj_RetainWindow(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+#ifndef RetainWindow
+	PyMac_PRECHECK(RetainWindow);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = RetainWindow(_self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_ReleaseWindow(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+#ifndef ReleaseWindow
+	PyMac_PRECHECK(ReleaseWindow);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = ReleaseWindow(_self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_ReshapeCustomWindow(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+#ifndef ReshapeCustomWindow
+	PyMac_PRECHECK(ReshapeCustomWindow);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = ReshapeCustomWindow(_self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_GetWindowWidgetHilite(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowDefPartCode outHilite;
+#ifndef GetWindowWidgetHilite
+	PyMac_PRECHECK(GetWindowWidgetHilite);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetWindowWidgetHilite(_self->ob_itself,
+	                             &outHilite);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("h",
+	                     outHilite);
+	return _res;
+}
+
+static PyObject *WinObj_GetWindowClass(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowClass outClass;
+#ifndef GetWindowClass
+	PyMac_PRECHECK(GetWindowClass);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetWindowClass(_self->ob_itself,
+	                      &outClass);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     outClass);
+	return _res;
+}
+
+static PyObject *WinObj_GetWindowAttributes(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowAttributes outAttributes;
+#ifndef GetWindowAttributes
+	PyMac_PRECHECK(GetWindowAttributes);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetWindowAttributes(_self->ob_itself,
+	                           &outAttributes);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     outAttributes);
+	return _res;
+}
+
+static PyObject *WinObj_ChangeWindowAttributes(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowAttributes setTheseAttributes;
+	WindowAttributes clearTheseAttributes;
+#ifndef ChangeWindowAttributes
+	PyMac_PRECHECK(ChangeWindowAttributes);
+#endif
+	if (!PyArg_ParseTuple(_args, "ll",
+	                      &setTheseAttributes,
+	                      &clearTheseAttributes))
+		return NULL;
+	_err = ChangeWindowAttributes(_self->ob_itself,
+	                              setTheseAttributes,
+	                              clearTheseAttributes);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_SetWindowClass(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowClass inWindowClass;
+#ifndef SetWindowClass
+	PyMac_PRECHECK(SetWindowClass);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &inWindowClass))
+		return NULL;
+	_err = SetWindowClass(_self->ob_itself,
+	                      inWindowClass);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_SetWindowModality(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowModality inModalKind;
+	WindowPtr inUnavailableWindow;
+#ifndef SetWindowModality
+	PyMac_PRECHECK(SetWindowModality);
+#endif
+	if (!PyArg_ParseTuple(_args, "lO&",
+	                      &inModalKind,
+	                      WinObj_Convert, &inUnavailableWindow))
+		return NULL;
+	_err = SetWindowModality(_self->ob_itself,
+	                         inModalKind,
+	                         inUnavailableWindow);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_GetWindowModality(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowModality outModalKind;
+	WindowPtr outUnavailableWindow;
+#ifndef GetWindowModality
+	PyMac_PRECHECK(GetWindowModality);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetWindowModality(_self->ob_itself,
+	                         &outModalKind,
+	                         &outUnavailableWindow);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("lO&",
+	                     outModalKind,
+	                     WinObj_WhichWindow, outUnavailableWindow);
+	return _res;
+}
+
+static PyObject *WinObj_SetWindowContentColor(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	RGBColor color;
+#ifndef SetWindowContentColor
+	PyMac_PRECHECK(SetWindowContentColor);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      QdRGB_Convert, &color))
+		return NULL;
+	_err = SetWindowContentColor(_self->ob_itself,
+	                             &color);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_GetWindowContentColor(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	RGBColor color;
+#ifndef GetWindowContentColor
+	PyMac_PRECHECK(GetWindowContentColor);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetWindowContentColor(_self->ob_itself,
+	                             &color);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     QdRGB_New, &color);
+	return _res;
+}
+
+static PyObject *WinObj_GetWindowContentPattern(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	PixPatHandle outPixPat;
+#ifndef GetWindowContentPattern
+	PyMac_PRECHECK(GetWindowContentPattern);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &outPixPat))
+		return NULL;
+	_err = GetWindowContentPattern(_self->ob_itself,
+	                               outPixPat);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_SetWindowContentPattern(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	PixPatHandle pixPat;
+#ifndef SetWindowContentPattern
+	PyMac_PRECHECK(SetWindowContentPattern);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &pixPat))
+		return NULL;
+	_err = SetWindowContentPattern(_self->ob_itself,
+	                               pixPat);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_ScrollWindowRect(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Rect inScrollRect;
+	SInt16 inHPixels;
+	SInt16 inVPixels;
+	ScrollWindowOptions inOptions;
+	RgnHandle outExposedRgn;
+#ifndef ScrollWindowRect
+	PyMac_PRECHECK(ScrollWindowRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hhlO&",
+	                      PyMac_GetRect, &inScrollRect,
+	                      &inHPixels,
+	                      &inVPixels,
+	                      &inOptions,
+	                      ResObj_Convert, &outExposedRgn))
+		return NULL;
+	_err = ScrollWindowRect(_self->ob_itself,
+	                        &inScrollRect,
+	                        inHPixels,
+	                        inVPixels,
+	                        inOptions,
+	                        outExposedRgn);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_ScrollWindowRegion(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	RgnHandle inScrollRgn;
+	SInt16 inHPixels;
+	SInt16 inVPixels;
+	ScrollWindowOptions inOptions;
+	RgnHandle outExposedRgn;
+#ifndef ScrollWindowRegion
+	PyMac_PRECHECK(ScrollWindowRegion);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&hhlO&",
+	                      ResObj_Convert, &inScrollRgn,
+	                      &inHPixels,
+	                      &inVPixels,
+	                      &inOptions,
+	                      ResObj_Convert, &outExposedRgn))
+		return NULL;
+	_err = ScrollWindowRegion(_self->ob_itself,
+	                          inScrollRgn,
+	                          inHPixels,
+	                          inVPixels,
+	                          inOptions,
+	                          outExposedRgn);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_ClipAbove(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef ClipAbove
+	PyMac_PRECHECK(ClipAbove);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	ClipAbove(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_PaintOne(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle clobberedRgn;
+#ifndef PaintOne
+	PyMac_PRECHECK(PaintOne);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &clobberedRgn))
+		return NULL;
+	PaintOne(_self->ob_itself,
+	         clobberedRgn);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_PaintBehind(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle clobberedRgn;
+#ifndef PaintBehind
+	PyMac_PRECHECK(PaintBehind);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &clobberedRgn))
+		return NULL;
+	PaintBehind(_self->ob_itself,
+	            clobberedRgn);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_CalcVis(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef CalcVis
+	PyMac_PRECHECK(CalcVis);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	CalcVis(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_CalcVisBehind(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle clobberedRgn;
+#ifndef CalcVisBehind
+	PyMac_PRECHECK(CalcVisBehind);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &clobberedRgn))
+		return NULL;
+	CalcVisBehind(_self->ob_itself,
+	              clobberedRgn);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_BringToFront(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef BringToFront
+	PyMac_PRECHECK(BringToFront);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	BringToFront(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_SendBehind(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	WindowPtr behindWindow;
+#ifndef SendBehind
+	PyMac_PRECHECK(SendBehind);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      WinObj_Convert, &behindWindow))
+		return NULL;
+	SendBehind(_self->ob_itself,
+	           behindWindow);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_SelectWindow(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef SelectWindow
+	PyMac_PRECHECK(SelectWindow);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	SelectWindow(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_GetNextWindowOfClass(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	WindowPtr _rv;
+	WindowClass inWindowClass;
+	Boolean mustBeVisible;
+#ifndef GetNextWindowOfClass
+	PyMac_PRECHECK(GetNextWindowOfClass);
+#endif
+	if (!PyArg_ParseTuple(_args, "lb",
+	                      &inWindowClass,
+	                      &mustBeVisible))
+		return NULL;
+	_rv = GetNextWindowOfClass(_self->ob_itself,
+	                           inWindowClass,
+	                           mustBeVisible);
+	_res = Py_BuildValue("O&",
+	                     WinObj_New, _rv);
+	return _res;
+}
+
+static PyObject *WinObj_SetWindowAlternateTitle(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	CFStringRef inTitle;
+#ifndef SetWindowAlternateTitle
+	PyMac_PRECHECK(SetWindowAlternateTitle);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CFStringRefObj_Convert, &inTitle))
+		return NULL;
+	_err = SetWindowAlternateTitle(_self->ob_itself,
+	                               inTitle);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_CopyWindowAlternateTitle(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	CFStringRef outTitle;
+#ifndef CopyWindowAlternateTitle
+	PyMac_PRECHECK(CopyWindowAlternateTitle);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = CopyWindowAlternateTitle(_self->ob_itself,
+	                                &outTitle);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, outTitle);
+	return _res;
+}
+
+static PyObject *WinObj_HiliteWindow(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean fHilite;
+#ifndef HiliteWindow
+	PyMac_PRECHECK(HiliteWindow);
+#endif
+	if (!PyArg_ParseTuple(_args, "b",
+	                      &fHilite))
+		return NULL;
+	HiliteWindow(_self->ob_itself,
+	             fHilite);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_SetWRefCon(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long data;
+#ifndef SetWRefCon
+	PyMac_PRECHECK(SetWRefCon);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &data))
+		return NULL;
+	SetWRefCon(_self->ob_itself,
+	           data);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_GetWRefCon(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long _rv;
+#ifndef GetWRefCon
+	PyMac_PRECHECK(GetWRefCon);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetWRefCon(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *WinObj_SetWindowPic(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PicHandle pic;
+#ifndef SetWindowPic
+	PyMac_PRECHECK(SetWindowPic);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &pic))
+		return NULL;
+	SetWindowPic(_self->ob_itself,
+	             pic);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_GetWindowPic(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	PicHandle _rv;
+#ifndef GetWindowPic
+	PyMac_PRECHECK(GetWindowPic);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetWindowPic(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *WinObj_GetWVariant(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short _rv;
+#ifndef GetWVariant
+	PyMac_PRECHECK(GetWVariant);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetWVariant(_self->ob_itself);
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *WinObj_GetWindowFeatures(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	UInt32 outFeatures;
+#ifndef GetWindowFeatures
+	PyMac_PRECHECK(GetWindowFeatures);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetWindowFeatures(_self->ob_itself,
+	                         &outFeatures);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     outFeatures);
+	return _res;
+}
+
+static PyObject *WinObj_GetWindowRegion(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowRegionCode inRegionCode;
+	RgnHandle ioWinRgn;
+#ifndef GetWindowRegion
+	PyMac_PRECHECK(GetWindowRegion);
+#endif
+	if (!PyArg_ParseTuple(_args, "HO&",
+	                      &inRegionCode,
+	                      ResObj_Convert, &ioWinRgn))
+		return NULL;
+	_err = GetWindowRegion(_self->ob_itself,
+	                       inRegionCode,
+	                       ioWinRgn);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_GetWindowStructureWidths(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Rect outRect;
+#ifndef GetWindowStructureWidths
+	PyMac_PRECHECK(GetWindowStructureWidths);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetWindowStructureWidths(_self->ob_itself,
+	                                &outRect);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildRect, &outRect);
+	return _res;
+}
+
+static PyObject *WinObj_BeginUpdate(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef BeginUpdate
+	PyMac_PRECHECK(BeginUpdate);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	BeginUpdate(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_EndUpdate(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef EndUpdate
+	PyMac_PRECHECK(EndUpdate);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	EndUpdate(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_InvalWindowRgn(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	RgnHandle region;
+#ifndef InvalWindowRgn
+	PyMac_PRECHECK(InvalWindowRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &region))
+		return NULL;
+	_err = InvalWindowRgn(_self->ob_itself,
+	                      region);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_InvalWindowRect(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Rect bounds;
+#ifndef InvalWindowRect
+	PyMac_PRECHECK(InvalWindowRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetRect, &bounds))
+		return NULL;
+	_err = InvalWindowRect(_self->ob_itself,
+	                       &bounds);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_ValidWindowRgn(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	RgnHandle region;
+#ifndef ValidWindowRgn
+	PyMac_PRECHECK(ValidWindowRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &region))
+		return NULL;
+	_err = ValidWindowRgn(_self->ob_itself,
+	                      region);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_ValidWindowRect(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Rect bounds;
+#ifndef ValidWindowRect
+	PyMac_PRECHECK(ValidWindowRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetRect, &bounds))
+		return NULL;
+	_err = ValidWindowRect(_self->ob_itself,
+	                       &bounds);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_DrawGrowIcon(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef DrawGrowIcon
+	PyMac_PRECHECK(DrawGrowIcon);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	DrawGrowIcon(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_SetWTitle(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Str255 title;
+#ifndef SetWTitle
+	PyMac_PRECHECK(SetWTitle);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetStr255, title))
+		return NULL;
+	SetWTitle(_self->ob_itself,
+	          title);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_GetWTitle(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Str255 title;
+#ifndef GetWTitle
+	PyMac_PRECHECK(GetWTitle);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	GetWTitle(_self->ob_itself,
+	          title);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildStr255, title);
+	return _res;
+}
+
+static PyObject *WinObj_SetWindowTitleWithCFString(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	CFStringRef inString;
+#ifndef SetWindowTitleWithCFString
+	PyMac_PRECHECK(SetWindowTitleWithCFString);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CFStringRefObj_Convert, &inString))
+		return NULL;
+	_err = SetWindowTitleWithCFString(_self->ob_itself,
+	                                  inString);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_CopyWindowTitleAsCFString(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	CFStringRef outString;
+#ifndef CopyWindowTitleAsCFString
+	PyMac_PRECHECK(CopyWindowTitleAsCFString);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = CopyWindowTitleAsCFString(_self->ob_itself,
+	                                 &outString);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, outString);
+	return _res;
+}
+
+static PyObject *WinObj_SetWindowProxyFSSpec(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	FSSpec inFile;
+#ifndef SetWindowProxyFSSpec
+	PyMac_PRECHECK(SetWindowProxyFSSpec);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetFSSpec, &inFile))
+		return NULL;
+	_err = SetWindowProxyFSSpec(_self->ob_itself,
+	                            &inFile);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_GetWindowProxyFSSpec(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	FSSpec outFile;
+#ifndef GetWindowProxyFSSpec
+	PyMac_PRECHECK(GetWindowProxyFSSpec);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetWindowProxyFSSpec(_self->ob_itself,
+	                            &outFile);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildFSSpec, &outFile);
+	return _res;
+}
+
+static PyObject *WinObj_SetWindowProxyAlias(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	AliasHandle inAlias;
+#ifndef SetWindowProxyAlias
+	PyMac_PRECHECK(SetWindowProxyAlias);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &inAlias))
+		return NULL;
+	_err = SetWindowProxyAlias(_self->ob_itself,
+	                           inAlias);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_GetWindowProxyAlias(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	AliasHandle alias;
+#ifndef GetWindowProxyAlias
+	PyMac_PRECHECK(GetWindowProxyAlias);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetWindowProxyAlias(_self->ob_itself,
+	                           &alias);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, alias);
+	return _res;
+}
+
+static PyObject *WinObj_SetWindowProxyCreatorAndType(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	OSType fileCreator;
+	OSType fileType;
+	SInt16 vRefNum;
+#ifndef SetWindowProxyCreatorAndType
+	PyMac_PRECHECK(SetWindowProxyCreatorAndType);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&h",
+	                      PyMac_GetOSType, &fileCreator,
+	                      PyMac_GetOSType, &fileType,
+	                      &vRefNum))
+		return NULL;
+	_err = SetWindowProxyCreatorAndType(_self->ob_itself,
+	                                    fileCreator,
+	                                    fileType,
+	                                    vRefNum);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_GetWindowProxyIcon(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	IconRef outIcon;
+#ifndef GetWindowProxyIcon
+	PyMac_PRECHECK(GetWindowProxyIcon);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetWindowProxyIcon(_self->ob_itself,
+	                          &outIcon);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, outIcon);
+	return _res;
+}
+
+static PyObject *WinObj_SetWindowProxyIcon(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	IconRef icon;
+#ifndef SetWindowProxyIcon
+	PyMac_PRECHECK(SetWindowProxyIcon);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &icon))
+		return NULL;
+	_err = SetWindowProxyIcon(_self->ob_itself,
+	                          icon);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_RemoveWindowProxy(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+#ifndef RemoveWindowProxy
+	PyMac_PRECHECK(RemoveWindowProxy);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = RemoveWindowProxy(_self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_BeginWindowProxyDrag(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	DragReference outNewDrag;
+	RgnHandle outDragOutlineRgn;
+#ifndef BeginWindowProxyDrag
+	PyMac_PRECHECK(BeginWindowProxyDrag);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &outDragOutlineRgn))
+		return NULL;
+	_err = BeginWindowProxyDrag(_self->ob_itself,
+	                            &outNewDrag,
+	                            outDragOutlineRgn);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     DragObj_New, outNewDrag);
+	return _res;
+}
+
+static PyObject *WinObj_EndWindowProxyDrag(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	DragReference theDrag;
+#ifndef EndWindowProxyDrag
+	PyMac_PRECHECK(EndWindowProxyDrag);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      DragObj_Convert, &theDrag))
+		return NULL;
+	_err = EndWindowProxyDrag(_self->ob_itself,
+	                          theDrag);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_TrackWindowProxyFromExistingDrag(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Point startPt;
+	DragReference drag;
+	RgnHandle inDragOutlineRgn;
+#ifndef TrackWindowProxyFromExistingDrag
+	PyMac_PRECHECK(TrackWindowProxyFromExistingDrag);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&O&",
+	                      PyMac_GetPoint, &startPt,
+	                      DragObj_Convert, &drag,
+	                      ResObj_Convert, &inDragOutlineRgn))
+		return NULL;
+	_err = TrackWindowProxyFromExistingDrag(_self->ob_itself,
+	                                        startPt,
+	                                        drag,
+	                                        inDragOutlineRgn);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_TrackWindowProxyDrag(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Point startPt;
+#ifndef TrackWindowProxyDrag
+	PyMac_PRECHECK(TrackWindowProxyDrag);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetPoint, &startPt))
+		return NULL;
+	_err = TrackWindowProxyDrag(_self->ob_itself,
+	                            startPt);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_IsWindowModified(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+#ifndef IsWindowModified
+	PyMac_PRECHECK(IsWindowModified);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = IsWindowModified(_self->ob_itself);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *WinObj_SetWindowModified(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Boolean modified;
+#ifndef SetWindowModified
+	PyMac_PRECHECK(SetWindowModified);
+#endif
+	if (!PyArg_ParseTuple(_args, "b",
+	                      &modified))
+		return NULL;
+	_err = SetWindowModified(_self->ob_itself,
+	                         modified);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_IsWindowPathSelectClick(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	EventRecord event;
+#ifndef IsWindowPathSelectClick
+	PyMac_PRECHECK(IsWindowPathSelectClick);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetEventRecord, &event))
+		return NULL;
+	_rv = IsWindowPathSelectClick(_self->ob_itself,
+	                              &event);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *WinObj_WindowPathSelect(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	MenuHandle menu;
+	SInt32 outMenuResult;
+#ifndef WindowPathSelect
+	PyMac_PRECHECK(WindowPathSelect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      MenuObj_Convert, &menu))
+		return NULL;
+	_err = WindowPathSelect(_self->ob_itself,
+	                        menu,
+	                        &outMenuResult);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     outMenuResult);
+	return _res;
+}
+
+static PyObject *WinObj_HiliteWindowFrameForDrag(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Boolean hilited;
+#ifndef HiliteWindowFrameForDrag
+	PyMac_PRECHECK(HiliteWindowFrameForDrag);
+#endif
+	if (!PyArg_ParseTuple(_args, "b",
+	                      &hilited))
+		return NULL;
+	_err = HiliteWindowFrameForDrag(_self->ob_itself,
+	                                hilited);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_TransitionWindow(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowTransitionEffect inEffect;
+	WindowTransitionAction inAction;
+	Rect inRect;
+#ifndef TransitionWindow
+	PyMac_PRECHECK(TransitionWindow);
+#endif
+	if (!PyArg_ParseTuple(_args, "llO&",
+	                      &inEffect,
+	                      &inAction,
+	                      PyMac_GetRect, &inRect))
+		return NULL;
+	_err = TransitionWindow(_self->ob_itself,
+	                        inEffect,
+	                        inAction,
+	                        &inRect);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_TransitionWindowAndParent(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr inParentWindow;
+	WindowTransitionEffect inEffect;
+	WindowTransitionAction inAction;
+	Rect inRect;
+#ifndef TransitionWindowAndParent
+	PyMac_PRECHECK(TransitionWindowAndParent);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&llO&",
+	                      WinObj_Convert, &inParentWindow,
+	                      &inEffect,
+	                      &inAction,
+	                      PyMac_GetRect, &inRect))
+		return NULL;
+	_err = TransitionWindowAndParent(_self->ob_itself,
+	                                 inParentWindow,
+	                                 inEffect,
+	                                 inAction,
+	                                 &inRect);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_MacMoveWindow(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short hGlobal;
+	short vGlobal;
+	Boolean front;
+#ifndef MacMoveWindow
+	PyMac_PRECHECK(MacMoveWindow);
+#endif
+	if (!PyArg_ParseTuple(_args, "hhb",
+	                      &hGlobal,
+	                      &vGlobal,
+	                      &front))
+		return NULL;
+	MacMoveWindow(_self->ob_itself,
+	              hGlobal,
+	              vGlobal,
+	              front);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_SizeWindow(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short w;
+	short h;
+	Boolean fUpdate;
+#ifndef SizeWindow
+	PyMac_PRECHECK(SizeWindow);
+#endif
+	if (!PyArg_ParseTuple(_args, "hhb",
+	                      &w,
+	                      &h,
+	                      &fUpdate))
+		return NULL;
+	SizeWindow(_self->ob_itself,
+	           w,
+	           h,
+	           fUpdate);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_GrowWindow(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long _rv;
+	Point startPt;
+	Rect bBox;
+#ifndef GrowWindow
+	PyMac_PRECHECK(GrowWindow);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetPoint, &startPt,
+	                      PyMac_GetRect, &bBox))
+		return NULL;
+	_rv = GrowWindow(_self->ob_itself,
+	                 startPt,
+	                 &bBox);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *WinObj_DragWindow(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Point startPt;
+	Rect boundsRect;
+#ifndef DragWindow
+	PyMac_PRECHECK(DragWindow);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetPoint, &startPt,
+	                      PyMac_GetRect, &boundsRect))
+		return NULL;
+	DragWindow(_self->ob_itself,
+	           startPt,
+	           &boundsRect);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_ZoomWindow(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	WindowPartCode partCode;
+	Boolean front;
+#ifndef ZoomWindow
+	PyMac_PRECHECK(ZoomWindow);
+#endif
+	if (!PyArg_ParseTuple(_args, "hb",
+	                      &partCode,
+	                      &front))
+		return NULL;
+	ZoomWindow(_self->ob_itself,
+	           partCode,
+	           front);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_IsWindowCollapsable(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+#ifndef IsWindowCollapsable
+	PyMac_PRECHECK(IsWindowCollapsable);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = IsWindowCollapsable(_self->ob_itself);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *WinObj_IsWindowCollapsed(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+#ifndef IsWindowCollapsed
+	PyMac_PRECHECK(IsWindowCollapsed);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = IsWindowCollapsed(_self->ob_itself);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *WinObj_CollapseWindow(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Boolean collapse;
+#ifndef CollapseWindow
+	PyMac_PRECHECK(CollapseWindow);
+#endif
+	if (!PyArg_ParseTuple(_args, "b",
+	                      &collapse))
+		return NULL;
+	_err = CollapseWindow(_self->ob_itself,
+	                      collapse);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_GetWindowBounds(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowRegionCode regionCode;
+	Rect globalBounds;
+#ifndef GetWindowBounds
+	PyMac_PRECHECK(GetWindowBounds);
+#endif
+	if (!PyArg_ParseTuple(_args, "H",
+	                      &regionCode))
+		return NULL;
+	_err = GetWindowBounds(_self->ob_itself,
+	                       regionCode,
+	                       &globalBounds);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildRect, &globalBounds);
+	return _res;
+}
+
+static PyObject *WinObj_ResizeWindow(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	Point inStartPoint;
+	Rect inSizeConstraints;
+	Rect outNewContentRect;
+#ifndef ResizeWindow
+	PyMac_PRECHECK(ResizeWindow);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetPoint, &inStartPoint,
+	                      PyMac_GetRect, &inSizeConstraints))
+		return NULL;
+	_rv = ResizeWindow(_self->ob_itself,
+	                   inStartPoint,
+	                   &inSizeConstraints,
+	                   &outNewContentRect);
+	_res = Py_BuildValue("bO&",
+	                     _rv,
+	                     PyMac_BuildRect, &outNewContentRect);
+	return _res;
+}
+
+static PyObject *WinObj_SetWindowBounds(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowRegionCode regionCode;
+	Rect globalBounds;
+#ifndef SetWindowBounds
+	PyMac_PRECHECK(SetWindowBounds);
+#endif
+	if (!PyArg_ParseTuple(_args, "HO&",
+	                      &regionCode,
+	                      PyMac_GetRect, &globalBounds))
+		return NULL;
+	_err = SetWindowBounds(_self->ob_itself,
+	                       regionCode,
+	                       &globalBounds);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_RepositionWindow(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr parentWindow;
+	WindowPositionMethod method;
+#ifndef RepositionWindow
+	PyMac_PRECHECK(RepositionWindow);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      WinObj_Convert, &parentWindow,
+	                      &method))
+		return NULL;
+	_err = RepositionWindow(_self->ob_itself,
+	                        parentWindow,
+	                        method);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_MoveWindowStructure(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	short hGlobal;
+	short vGlobal;
+#ifndef MoveWindowStructure
+	PyMac_PRECHECK(MoveWindowStructure);
+#endif
+	if (!PyArg_ParseTuple(_args, "hh",
+	                      &hGlobal,
+	                      &vGlobal))
+		return NULL;
+	_err = MoveWindowStructure(_self->ob_itself,
+	                           hGlobal,
+	                           vGlobal);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_IsWindowInStandardState(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	Point inIdealSize;
+	Rect outIdealStandardState;
+#ifndef IsWindowInStandardState
+	PyMac_PRECHECK(IsWindowInStandardState);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetPoint, &inIdealSize))
+		return NULL;
+	_rv = IsWindowInStandardState(_self->ob_itself,
+	                              &inIdealSize,
+	                              &outIdealStandardState);
+	_res = Py_BuildValue("bO&",
+	                     _rv,
+	                     PyMac_BuildRect, &outIdealStandardState);
+	return _res;
+}
+
+static PyObject *WinObj_ZoomWindowIdeal(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPartCode inPartCode;
+	Point ioIdealSize;
+#ifndef ZoomWindowIdeal
+	PyMac_PRECHECK(ZoomWindowIdeal);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &inPartCode))
+		return NULL;
+	_err = ZoomWindowIdeal(_self->ob_itself,
+	                       inPartCode,
+	                       &ioIdealSize);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildPoint, ioIdealSize);
+	return _res;
+}
+
+static PyObject *WinObj_GetWindowIdealUserState(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Rect outUserState;
+#ifndef GetWindowIdealUserState
+	PyMac_PRECHECK(GetWindowIdealUserState);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetWindowIdealUserState(_self->ob_itself,
+	                               &outUserState);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildRect, &outUserState);
+	return _res;
+}
+
+static PyObject *WinObj_SetWindowIdealUserState(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Rect inUserState;
+#ifndef SetWindowIdealUserState
+	PyMac_PRECHECK(SetWindowIdealUserState);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetRect, &inUserState))
+		return NULL;
+	_err = SetWindowIdealUserState(_self->ob_itself,
+	                               &inUserState);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_GetWindowGreatestAreaDevice(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowRegionCode inRegion;
+	GDHandle outGreatestDevice;
+	Rect outGreatestDeviceRect;
+#ifndef GetWindowGreatestAreaDevice
+	PyMac_PRECHECK(GetWindowGreatestAreaDevice);
+#endif
+	if (!PyArg_ParseTuple(_args, "H",
+	                      &inRegion))
+		return NULL;
+	_err = GetWindowGreatestAreaDevice(_self->ob_itself,
+	                                   inRegion,
+	                                   &outGreatestDevice,
+	                                   &outGreatestDeviceRect);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&O&",
+	                     ResObj_New, outGreatestDevice,
+	                     PyMac_BuildRect, &outGreatestDeviceRect);
+	return _res;
+}
+
+static PyObject *WinObj_ConstrainWindowToScreen(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowRegionCode inRegionCode;
+	WindowConstrainOptions inOptions;
+	Rect inScreenRect;
+	Rect outStructure;
+#ifndef ConstrainWindowToScreen
+	PyMac_PRECHECK(ConstrainWindowToScreen);
+#endif
+	if (!PyArg_ParseTuple(_args, "HlO&",
+	                      &inRegionCode,
+	                      &inOptions,
+	                      PyMac_GetRect, &inScreenRect))
+		return NULL;
+	_err = ConstrainWindowToScreen(_self->ob_itself,
+	                               inRegionCode,
+	                               inOptions,
+	                               &inScreenRect,
+	                               &outStructure);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildRect, &outStructure);
+	return _res;
+}
+
+static PyObject *WinObj_HideWindow(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef HideWindow
+	PyMac_PRECHECK(HideWindow);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	HideWindow(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_MacShowWindow(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef MacShowWindow
+	PyMac_PRECHECK(MacShowWindow);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	MacShowWindow(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_ShowHide(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean showFlag;
+#ifndef ShowHide
+	PyMac_PRECHECK(ShowHide);
+#endif
+	if (!PyArg_ParseTuple(_args, "b",
+	                      &showFlag))
+		return NULL;
+	ShowHide(_self->ob_itself,
+	         showFlag);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_MacIsWindowVisible(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+#ifndef MacIsWindowVisible
+	PyMac_PRECHECK(MacIsWindowVisible);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = MacIsWindowVisible(_self->ob_itself);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *WinObj_ShowSheetWindow(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr inParentWindow;
+#ifndef ShowSheetWindow
+	PyMac_PRECHECK(ShowSheetWindow);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      WinObj_Convert, &inParentWindow))
+		return NULL;
+	_err = ShowSheetWindow(_self->ob_itself,
+	                       inParentWindow);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_HideSheetWindow(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+#ifndef HideSheetWindow
+	PyMac_PRECHECK(HideSheetWindow);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = HideSheetWindow(_self->ob_itself);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_GetSheetWindowParent(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowPtr outParentWindow;
+#ifndef GetSheetWindowParent
+	PyMac_PRECHECK(GetSheetWindowParent);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = GetSheetWindowParent(_self->ob_itself,
+	                            &outParentWindow);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     WinObj_WhichWindow, outParentWindow);
+	return _res;
+}
+
+static PyObject *WinObj_GetWindowPropertyAttributes(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	OSType propertyCreator;
+	OSType propertyTag;
+	UInt32 attributes;
+#ifndef GetWindowPropertyAttributes
+	PyMac_PRECHECK(GetWindowPropertyAttributes);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetOSType, &propertyCreator,
+	                      PyMac_GetOSType, &propertyTag))
+		return NULL;
+	_err = GetWindowPropertyAttributes(_self->ob_itself,
+	                                   propertyCreator,
+	                                   propertyTag,
+	                                   &attributes);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("l",
+	                     attributes);
+	return _res;
+}
+
+static PyObject *WinObj_ChangeWindowPropertyAttributes(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	OSType propertyCreator;
+	OSType propertyTag;
+	UInt32 attributesToSet;
+	UInt32 attributesToClear;
+#ifndef ChangeWindowPropertyAttributes
+	PyMac_PRECHECK(ChangeWindowPropertyAttributes);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&ll",
+	                      PyMac_GetOSType, &propertyCreator,
+	                      PyMac_GetOSType, &propertyTag,
+	                      &attributesToSet,
+	                      &attributesToClear))
+		return NULL;
+	_err = ChangeWindowPropertyAttributes(_self->ob_itself,
+	                                      propertyCreator,
+	                                      propertyTag,
+	                                      attributesToSet,
+	                                      attributesToClear);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_TrackBox(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	Point thePt;
+	WindowPartCode partCode;
+#ifndef TrackBox
+	PyMac_PRECHECK(TrackBox);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&h",
+	                      PyMac_GetPoint, &thePt,
+	                      &partCode))
+		return NULL;
+	_rv = TrackBox(_self->ob_itself,
+	               thePt,
+	               partCode);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *WinObj_TrackGoAway(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	Point thePt;
+#ifndef TrackGoAway
+	PyMac_PRECHECK(TrackGoAway);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetPoint, &thePt))
+		return NULL;
+	_rv = TrackGoAway(_self->ob_itself,
+	                  thePt);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *WinObj_GetWindowPort(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CGrafPtr _rv;
+#ifndef GetWindowPort
+	PyMac_PRECHECK(GetWindowPort);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetWindowPort(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     GrafObj_New, _rv);
+	return _res;
+}
+
+static PyObject *WinObj_GetWindowStructurePort(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CGrafPtr _rv;
+#ifndef GetWindowStructurePort
+	PyMac_PRECHECK(GetWindowStructurePort);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetWindowStructurePort(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     GrafObj_New, _rv);
+	return _res;
+}
+
+static PyObject *WinObj_GetWindowKind(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short _rv;
+#ifndef GetWindowKind
+	PyMac_PRECHECK(GetWindowKind);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetWindowKind(_self->ob_itself);
+	_res = Py_BuildValue("h",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *WinObj_IsWindowHilited(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+#ifndef IsWindowHilited
+	PyMac_PRECHECK(IsWindowHilited);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = IsWindowHilited(_self->ob_itself);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *WinObj_IsWindowUpdatePending(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+#ifndef IsWindowUpdatePending
+	PyMac_PRECHECK(IsWindowUpdatePending);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = IsWindowUpdatePending(_self->ob_itself);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *WinObj_MacGetNextWindow(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	WindowPtr _rv;
+#ifndef MacGetNextWindow
+	PyMac_PRECHECK(MacGetNextWindow);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = MacGetNextWindow(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     WinObj_New, _rv);
+	return _res;
+}
+
+static PyObject *WinObj_GetWindowStandardState(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect rect;
+#ifndef GetWindowStandardState
+	PyMac_PRECHECK(GetWindowStandardState);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	GetWindowStandardState(_self->ob_itself,
+	                       &rect);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildRect, &rect);
+	return _res;
+}
+
+static PyObject *WinObj_GetWindowUserState(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect rect;
+#ifndef GetWindowUserState
+	PyMac_PRECHECK(GetWindowUserState);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	GetWindowUserState(_self->ob_itself,
+	                   &rect);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildRect, &rect);
+	return _res;
+}
+
+static PyObject *WinObj_SetWindowKind(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short kind;
+#ifndef SetWindowKind
+	PyMac_PRECHECK(SetWindowKind);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &kind))
+		return NULL;
+	SetWindowKind(_self->ob_itself,
+	              kind);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_SetWindowStandardState(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect rect;
+#ifndef SetWindowStandardState
+	PyMac_PRECHECK(SetWindowStandardState);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetRect, &rect))
+		return NULL;
+	SetWindowStandardState(_self->ob_itself,
+	                       &rect);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_SetWindowUserState(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect rect;
+#ifndef SetWindowUserState
+	PyMac_PRECHECK(SetWindowUserState);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetRect, &rect))
+		return NULL;
+	SetWindowUserState(_self->ob_itself,
+	                   &rect);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_SetPortWindowPort(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef SetPortWindowPort
+	PyMac_PRECHECK(SetPortWindowPort);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	SetPortWindowPort(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_GetWindowPortBounds(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Rect bounds;
+#ifndef GetWindowPortBounds
+	PyMac_PRECHECK(GetWindowPortBounds);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	GetWindowPortBounds(_self->ob_itself,
+	                    &bounds);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildRect, &bounds);
+	return _res;
+}
+
+static PyObject *WinObj_IsWindowVisible(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+#ifndef IsWindowVisible
+	PyMac_PRECHECK(IsWindowVisible);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = IsWindowVisible(_self->ob_itself);
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *WinObj_GetWindowStructureRgn(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle r;
+#ifndef GetWindowStructureRgn
+	PyMac_PRECHECK(GetWindowStructureRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &r))
+		return NULL;
+	GetWindowStructureRgn(_self->ob_itself,
+	                      r);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_GetWindowContentRgn(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle r;
+#ifndef GetWindowContentRgn
+	PyMac_PRECHECK(GetWindowContentRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &r))
+		return NULL;
+	GetWindowContentRgn(_self->ob_itself,
+	                    r);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_GetWindowUpdateRgn(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle r;
+#ifndef GetWindowUpdateRgn
+	PyMac_PRECHECK(GetWindowUpdateRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &r))
+		return NULL;
+	GetWindowUpdateRgn(_self->ob_itself,
+	                   r);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_GetNextWindow(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	WindowPtr _rv;
+#ifndef GetNextWindow
+	PyMac_PRECHECK(GetNextWindow);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetNextWindow(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     WinObj_WhichWindow, _rv);
+	return _res;
+}
+
+static PyObject *WinObj_MoveWindow(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short hGlobal;
+	short vGlobal;
+	Boolean front;
+#ifndef MoveWindow
+	PyMac_PRECHECK(MoveWindow);
+#endif
+	if (!PyArg_ParseTuple(_args, "hhb",
+	                      &hGlobal,
+	                      &vGlobal,
+	                      &front))
+		return NULL;
+	MoveWindow(_self->ob_itself,
+	           hGlobal,
+	           vGlobal,
+	           front);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_ShowWindow(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+#ifndef ShowWindow
+	PyMac_PRECHECK(ShowWindow);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	ShowWindow(_self->ob_itself);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *WinObj_AutoDispose(WindowObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+
+	int onoff, old = 0;
+	if (!PyArg_ParseTuple(_args, "i", &onoff))
+	        return NULL;
+	if ( _self->ob_freeit )
+	        old = 1;
+	if ( onoff )
+	        _self->ob_freeit = PyMac_AutoDisposeWindow;
+	else
+	        _self->ob_freeit = NULL;
+	_res = Py_BuildValue("i", old);
+	return _res;
+
+}
+
+static PyMethodDef WinObj_methods[] = {
+	{"GetWindowOwnerCount", (PyCFunction)WinObj_GetWindowOwnerCount, 1,
+	 PyDoc_STR("() -> (UInt32 outCount)")},
+	{"CloneWindow", (PyCFunction)WinObj_CloneWindow, 1,
+	 PyDoc_STR("() -> None")},
+	{"GetWindowRetainCount", (PyCFunction)WinObj_GetWindowRetainCount, 1,
+	 PyDoc_STR("() -> (ItemCount _rv)")},
+	{"RetainWindow", (PyCFunction)WinObj_RetainWindow, 1,
+	 PyDoc_STR("() -> None")},
+	{"ReleaseWindow", (PyCFunction)WinObj_ReleaseWindow, 1,
+	 PyDoc_STR("() -> None")},
+	{"ReshapeCustomWindow", (PyCFunction)WinObj_ReshapeCustomWindow, 1,
+	 PyDoc_STR("() -> None")},
+	{"GetWindowWidgetHilite", (PyCFunction)WinObj_GetWindowWidgetHilite, 1,
+	 PyDoc_STR("() -> (WindowDefPartCode outHilite)")},
+	{"GetWindowClass", (PyCFunction)WinObj_GetWindowClass, 1,
+	 PyDoc_STR("() -> (WindowClass outClass)")},
+	{"GetWindowAttributes", (PyCFunction)WinObj_GetWindowAttributes, 1,
+	 PyDoc_STR("() -> (WindowAttributes outAttributes)")},
+	{"ChangeWindowAttributes", (PyCFunction)WinObj_ChangeWindowAttributes, 1,
+	 PyDoc_STR("(WindowAttributes setTheseAttributes, WindowAttributes clearTheseAttributes) -> None")},
+	{"SetWindowClass", (PyCFunction)WinObj_SetWindowClass, 1,
+	 PyDoc_STR("(WindowClass inWindowClass) -> None")},
+	{"SetWindowModality", (PyCFunction)WinObj_SetWindowModality, 1,
+	 PyDoc_STR("(WindowModality inModalKind, WindowPtr inUnavailableWindow) -> None")},
+	{"GetWindowModality", (PyCFunction)WinObj_GetWindowModality, 1,
+	 PyDoc_STR("() -> (WindowModality outModalKind, WindowPtr outUnavailableWindow)")},
+	{"SetWindowContentColor", (PyCFunction)WinObj_SetWindowContentColor, 1,
+	 PyDoc_STR("(RGBColor color) -> None")},
+	{"GetWindowContentColor", (PyCFunction)WinObj_GetWindowContentColor, 1,
+	 PyDoc_STR("() -> (RGBColor color)")},
+	{"GetWindowContentPattern", (PyCFunction)WinObj_GetWindowContentPattern, 1,
+	 PyDoc_STR("(PixPatHandle outPixPat) -> None")},
+	{"SetWindowContentPattern", (PyCFunction)WinObj_SetWindowContentPattern, 1,
+	 PyDoc_STR("(PixPatHandle pixPat) -> None")},
+	{"ScrollWindowRect", (PyCFunction)WinObj_ScrollWindowRect, 1,
+	 PyDoc_STR("(Rect inScrollRect, SInt16 inHPixels, SInt16 inVPixels, ScrollWindowOptions inOptions, RgnHandle outExposedRgn) -> None")},
+	{"ScrollWindowRegion", (PyCFunction)WinObj_ScrollWindowRegion, 1,
+	 PyDoc_STR("(RgnHandle inScrollRgn, SInt16 inHPixels, SInt16 inVPixels, ScrollWindowOptions inOptions, RgnHandle outExposedRgn) -> None")},
+	{"ClipAbove", (PyCFunction)WinObj_ClipAbove, 1,
+	 PyDoc_STR("() -> None")},
+	{"PaintOne", (PyCFunction)WinObj_PaintOne, 1,
+	 PyDoc_STR("(RgnHandle clobberedRgn) -> None")},
+	{"PaintBehind", (PyCFunction)WinObj_PaintBehind, 1,
+	 PyDoc_STR("(RgnHandle clobberedRgn) -> None")},
+	{"CalcVis", (PyCFunction)WinObj_CalcVis, 1,
+	 PyDoc_STR("() -> None")},
+	{"CalcVisBehind", (PyCFunction)WinObj_CalcVisBehind, 1,
+	 PyDoc_STR("(RgnHandle clobberedRgn) -> None")},
+	{"BringToFront", (PyCFunction)WinObj_BringToFront, 1,
+	 PyDoc_STR("() -> None")},
+	{"SendBehind", (PyCFunction)WinObj_SendBehind, 1,
+	 PyDoc_STR("(WindowPtr behindWindow) -> None")},
+	{"SelectWindow", (PyCFunction)WinObj_SelectWindow, 1,
+	 PyDoc_STR("() -> None")},
+	{"GetNextWindowOfClass", (PyCFunction)WinObj_GetNextWindowOfClass, 1,
+	 PyDoc_STR("(WindowClass inWindowClass, Boolean mustBeVisible) -> (WindowPtr _rv)")},
+	{"SetWindowAlternateTitle", (PyCFunction)WinObj_SetWindowAlternateTitle, 1,
+	 PyDoc_STR("(CFStringRef inTitle) -> None")},
+	{"CopyWindowAlternateTitle", (PyCFunction)WinObj_CopyWindowAlternateTitle, 1,
+	 PyDoc_STR("() -> (CFStringRef outTitle)")},
+	{"HiliteWindow", (PyCFunction)WinObj_HiliteWindow, 1,
+	 PyDoc_STR("(Boolean fHilite) -> None")},
+	{"SetWRefCon", (PyCFunction)WinObj_SetWRefCon, 1,
+	 PyDoc_STR("(long data) -> None")},
+	{"GetWRefCon", (PyCFunction)WinObj_GetWRefCon, 1,
+	 PyDoc_STR("() -> (long _rv)")},
+	{"SetWindowPic", (PyCFunction)WinObj_SetWindowPic, 1,
+	 PyDoc_STR("(PicHandle pic) -> None")},
+	{"GetWindowPic", (PyCFunction)WinObj_GetWindowPic, 1,
+	 PyDoc_STR("() -> (PicHandle _rv)")},
+	{"GetWVariant", (PyCFunction)WinObj_GetWVariant, 1,
+	 PyDoc_STR("() -> (short _rv)")},
+	{"GetWindowFeatures", (PyCFunction)WinObj_GetWindowFeatures, 1,
+	 PyDoc_STR("() -> (UInt32 outFeatures)")},
+	{"GetWindowRegion", (PyCFunction)WinObj_GetWindowRegion, 1,
+	 PyDoc_STR("(WindowRegionCode inRegionCode, RgnHandle ioWinRgn) -> None")},
+	{"GetWindowStructureWidths", (PyCFunction)WinObj_GetWindowStructureWidths, 1,
+	 PyDoc_STR("() -> (Rect outRect)")},
+	{"BeginUpdate", (PyCFunction)WinObj_BeginUpdate, 1,
+	 PyDoc_STR("() -> None")},
+	{"EndUpdate", (PyCFunction)WinObj_EndUpdate, 1,
+	 PyDoc_STR("() -> None")},
+	{"InvalWindowRgn", (PyCFunction)WinObj_InvalWindowRgn, 1,
+	 PyDoc_STR("(RgnHandle region) -> None")},
+	{"InvalWindowRect", (PyCFunction)WinObj_InvalWindowRect, 1,
+	 PyDoc_STR("(Rect bounds) -> None")},
+	{"ValidWindowRgn", (PyCFunction)WinObj_ValidWindowRgn, 1,
+	 PyDoc_STR("(RgnHandle region) -> None")},
+	{"ValidWindowRect", (PyCFunction)WinObj_ValidWindowRect, 1,
+	 PyDoc_STR("(Rect bounds) -> None")},
+	{"DrawGrowIcon", (PyCFunction)WinObj_DrawGrowIcon, 1,
+	 PyDoc_STR("() -> None")},
+	{"SetWTitle", (PyCFunction)WinObj_SetWTitle, 1,
+	 PyDoc_STR("(Str255 title) -> None")},
+	{"GetWTitle", (PyCFunction)WinObj_GetWTitle, 1,
+	 PyDoc_STR("() -> (Str255 title)")},
+	{"SetWindowTitleWithCFString", (PyCFunction)WinObj_SetWindowTitleWithCFString, 1,
+	 PyDoc_STR("(CFStringRef inString) -> None")},
+	{"CopyWindowTitleAsCFString", (PyCFunction)WinObj_CopyWindowTitleAsCFString, 1,
+	 PyDoc_STR("() -> (CFStringRef outString)")},
+	{"SetWindowProxyFSSpec", (PyCFunction)WinObj_SetWindowProxyFSSpec, 1,
+	 PyDoc_STR("(FSSpec inFile) -> None")},
+	{"GetWindowProxyFSSpec", (PyCFunction)WinObj_GetWindowProxyFSSpec, 1,
+	 PyDoc_STR("() -> (FSSpec outFile)")},
+	{"SetWindowProxyAlias", (PyCFunction)WinObj_SetWindowProxyAlias, 1,
+	 PyDoc_STR("(AliasHandle inAlias) -> None")},
+	{"GetWindowProxyAlias", (PyCFunction)WinObj_GetWindowProxyAlias, 1,
+	 PyDoc_STR("() -> (AliasHandle alias)")},
+	{"SetWindowProxyCreatorAndType", (PyCFunction)WinObj_SetWindowProxyCreatorAndType, 1,
+	 PyDoc_STR("(OSType fileCreator, OSType fileType, SInt16 vRefNum) -> None")},
+	{"GetWindowProxyIcon", (PyCFunction)WinObj_GetWindowProxyIcon, 1,
+	 PyDoc_STR("() -> (IconRef outIcon)")},
+	{"SetWindowProxyIcon", (PyCFunction)WinObj_SetWindowProxyIcon, 1,
+	 PyDoc_STR("(IconRef icon) -> None")},
+	{"RemoveWindowProxy", (PyCFunction)WinObj_RemoveWindowProxy, 1,
+	 PyDoc_STR("() -> None")},
+	{"BeginWindowProxyDrag", (PyCFunction)WinObj_BeginWindowProxyDrag, 1,
+	 PyDoc_STR("(RgnHandle outDragOutlineRgn) -> (DragReference outNewDrag)")},
+	{"EndWindowProxyDrag", (PyCFunction)WinObj_EndWindowProxyDrag, 1,
+	 PyDoc_STR("(DragReference theDrag) -> None")},
+	{"TrackWindowProxyFromExistingDrag", (PyCFunction)WinObj_TrackWindowProxyFromExistingDrag, 1,
+	 PyDoc_STR("(Point startPt, DragReference drag, RgnHandle inDragOutlineRgn) -> None")},
+	{"TrackWindowProxyDrag", (PyCFunction)WinObj_TrackWindowProxyDrag, 1,
+	 PyDoc_STR("(Point startPt) -> None")},
+	{"IsWindowModified", (PyCFunction)WinObj_IsWindowModified, 1,
+	 PyDoc_STR("() -> (Boolean _rv)")},
+	{"SetWindowModified", (PyCFunction)WinObj_SetWindowModified, 1,
+	 PyDoc_STR("(Boolean modified) -> None")},
+	{"IsWindowPathSelectClick", (PyCFunction)WinObj_IsWindowPathSelectClick, 1,
+	 PyDoc_STR("(EventRecord event) -> (Boolean _rv)")},
+	{"WindowPathSelect", (PyCFunction)WinObj_WindowPathSelect, 1,
+	 PyDoc_STR("(MenuHandle menu) -> (SInt32 outMenuResult)")},
+	{"HiliteWindowFrameForDrag", (PyCFunction)WinObj_HiliteWindowFrameForDrag, 1,
+	 PyDoc_STR("(Boolean hilited) -> None")},
+	{"TransitionWindow", (PyCFunction)WinObj_TransitionWindow, 1,
+	 PyDoc_STR("(WindowTransitionEffect inEffect, WindowTransitionAction inAction, Rect inRect) -> None")},
+	{"TransitionWindowAndParent", (PyCFunction)WinObj_TransitionWindowAndParent, 1,
+	 PyDoc_STR("(WindowPtr inParentWindow, WindowTransitionEffect inEffect, WindowTransitionAction inAction, Rect inRect) -> None")},
+	{"MacMoveWindow", (PyCFunction)WinObj_MacMoveWindow, 1,
+	 PyDoc_STR("(short hGlobal, short vGlobal, Boolean front) -> None")},
+	{"SizeWindow", (PyCFunction)WinObj_SizeWindow, 1,
+	 PyDoc_STR("(short w, short h, Boolean fUpdate) -> None")},
+	{"GrowWindow", (PyCFunction)WinObj_GrowWindow, 1,
+	 PyDoc_STR("(Point startPt, Rect bBox) -> (long _rv)")},
+	{"DragWindow", (PyCFunction)WinObj_DragWindow, 1,
+	 PyDoc_STR("(Point startPt, Rect boundsRect) -> None")},
+	{"ZoomWindow", (PyCFunction)WinObj_ZoomWindow, 1,
+	 PyDoc_STR("(WindowPartCode partCode, Boolean front) -> None")},
+	{"IsWindowCollapsable", (PyCFunction)WinObj_IsWindowCollapsable, 1,
+	 PyDoc_STR("() -> (Boolean _rv)")},
+	{"IsWindowCollapsed", (PyCFunction)WinObj_IsWindowCollapsed, 1,
+	 PyDoc_STR("() -> (Boolean _rv)")},
+	{"CollapseWindow", (PyCFunction)WinObj_CollapseWindow, 1,
+	 PyDoc_STR("(Boolean collapse) -> None")},
+	{"GetWindowBounds", (PyCFunction)WinObj_GetWindowBounds, 1,
+	 PyDoc_STR("(WindowRegionCode regionCode) -> (Rect globalBounds)")},
+	{"ResizeWindow", (PyCFunction)WinObj_ResizeWindow, 1,
+	 PyDoc_STR("(Point inStartPoint, Rect inSizeConstraints) -> (Boolean _rv, Rect outNewContentRect)")},
+	{"SetWindowBounds", (PyCFunction)WinObj_SetWindowBounds, 1,
+	 PyDoc_STR("(WindowRegionCode regionCode, Rect globalBounds) -> None")},
+	{"RepositionWindow", (PyCFunction)WinObj_RepositionWindow, 1,
+	 PyDoc_STR("(WindowPtr parentWindow, WindowPositionMethod method) -> None")},
+	{"MoveWindowStructure", (PyCFunction)WinObj_MoveWindowStructure, 1,
+	 PyDoc_STR("(short hGlobal, short vGlobal) -> None")},
+	{"IsWindowInStandardState", (PyCFunction)WinObj_IsWindowInStandardState, 1,
+	 PyDoc_STR("(Point inIdealSize) -> (Boolean _rv, Rect outIdealStandardState)")},
+	{"ZoomWindowIdeal", (PyCFunction)WinObj_ZoomWindowIdeal, 1,
+	 PyDoc_STR("(WindowPartCode inPartCode) -> (Point ioIdealSize)")},
+	{"GetWindowIdealUserState", (PyCFunction)WinObj_GetWindowIdealUserState, 1,
+	 PyDoc_STR("() -> (Rect outUserState)")},
+	{"SetWindowIdealUserState", (PyCFunction)WinObj_SetWindowIdealUserState, 1,
+	 PyDoc_STR("(Rect inUserState) -> None")},
+	{"GetWindowGreatestAreaDevice", (PyCFunction)WinObj_GetWindowGreatestAreaDevice, 1,
+	 PyDoc_STR("(WindowRegionCode inRegion) -> (GDHandle outGreatestDevice, Rect outGreatestDeviceRect)")},
+	{"ConstrainWindowToScreen", (PyCFunction)WinObj_ConstrainWindowToScreen, 1,
+	 PyDoc_STR("(WindowRegionCode inRegionCode, WindowConstrainOptions inOptions, Rect inScreenRect) -> (Rect outStructure)")},
+	{"HideWindow", (PyCFunction)WinObj_HideWindow, 1,
+	 PyDoc_STR("() -> None")},
+	{"MacShowWindow", (PyCFunction)WinObj_MacShowWindow, 1,
+	 PyDoc_STR("() -> None")},
+	{"ShowHide", (PyCFunction)WinObj_ShowHide, 1,
+	 PyDoc_STR("(Boolean showFlag) -> None")},
+	{"MacIsWindowVisible", (PyCFunction)WinObj_MacIsWindowVisible, 1,
+	 PyDoc_STR("() -> (Boolean _rv)")},
+	{"ShowSheetWindow", (PyCFunction)WinObj_ShowSheetWindow, 1,
+	 PyDoc_STR("(WindowPtr inParentWindow) -> None")},
+	{"HideSheetWindow", (PyCFunction)WinObj_HideSheetWindow, 1,
+	 PyDoc_STR("() -> None")},
+	{"GetSheetWindowParent", (PyCFunction)WinObj_GetSheetWindowParent, 1,
+	 PyDoc_STR("() -> (WindowPtr outParentWindow)")},
+	{"GetWindowPropertyAttributes", (PyCFunction)WinObj_GetWindowPropertyAttributes, 1,
+	 PyDoc_STR("(OSType propertyCreator, OSType propertyTag) -> (UInt32 attributes)")},
+	{"ChangeWindowPropertyAttributes", (PyCFunction)WinObj_ChangeWindowPropertyAttributes, 1,
+	 PyDoc_STR("(OSType propertyCreator, OSType propertyTag, UInt32 attributesToSet, UInt32 attributesToClear) -> None")},
+	{"TrackBox", (PyCFunction)WinObj_TrackBox, 1,
+	 PyDoc_STR("(Point thePt, WindowPartCode partCode) -> (Boolean _rv)")},
+	{"TrackGoAway", (PyCFunction)WinObj_TrackGoAway, 1,
+	 PyDoc_STR("(Point thePt) -> (Boolean _rv)")},
+	{"GetWindowPort", (PyCFunction)WinObj_GetWindowPort, 1,
+	 PyDoc_STR("() -> (CGrafPtr _rv)")},
+	{"GetWindowStructurePort", (PyCFunction)WinObj_GetWindowStructurePort, 1,
+	 PyDoc_STR("() -> (CGrafPtr _rv)")},
+	{"GetWindowKind", (PyCFunction)WinObj_GetWindowKind, 1,
+	 PyDoc_STR("() -> (short _rv)")},
+	{"IsWindowHilited", (PyCFunction)WinObj_IsWindowHilited, 1,
+	 PyDoc_STR("() -> (Boolean _rv)")},
+	{"IsWindowUpdatePending", (PyCFunction)WinObj_IsWindowUpdatePending, 1,
+	 PyDoc_STR("() -> (Boolean _rv)")},
+	{"MacGetNextWindow", (PyCFunction)WinObj_MacGetNextWindow, 1,
+	 PyDoc_STR("() -> (WindowPtr _rv)")},
+	{"GetWindowStandardState", (PyCFunction)WinObj_GetWindowStandardState, 1,
+	 PyDoc_STR("() -> (Rect rect)")},
+	{"GetWindowUserState", (PyCFunction)WinObj_GetWindowUserState, 1,
+	 PyDoc_STR("() -> (Rect rect)")},
+	{"SetWindowKind", (PyCFunction)WinObj_SetWindowKind, 1,
+	 PyDoc_STR("(short kind) -> None")},
+	{"SetWindowStandardState", (PyCFunction)WinObj_SetWindowStandardState, 1,
+	 PyDoc_STR("(Rect rect) -> None")},
+	{"SetWindowUserState", (PyCFunction)WinObj_SetWindowUserState, 1,
+	 PyDoc_STR("(Rect rect) -> None")},
+	{"SetPortWindowPort", (PyCFunction)WinObj_SetPortWindowPort, 1,
+	 PyDoc_STR("() -> None")},
+	{"GetWindowPortBounds", (PyCFunction)WinObj_GetWindowPortBounds, 1,
+	 PyDoc_STR("() -> (Rect bounds)")},
+	{"IsWindowVisible", (PyCFunction)WinObj_IsWindowVisible, 1,
+	 PyDoc_STR("() -> (Boolean _rv)")},
+	{"GetWindowStructureRgn", (PyCFunction)WinObj_GetWindowStructureRgn, 1,
+	 PyDoc_STR("(RgnHandle r) -> None")},
+	{"GetWindowContentRgn", (PyCFunction)WinObj_GetWindowContentRgn, 1,
+	 PyDoc_STR("(RgnHandle r) -> None")},
+	{"GetWindowUpdateRgn", (PyCFunction)WinObj_GetWindowUpdateRgn, 1,
+	 PyDoc_STR("(RgnHandle r) -> None")},
+	{"GetNextWindow", (PyCFunction)WinObj_GetNextWindow, 1,
+	 PyDoc_STR("() -> (WindowPtr _rv)")},
+	{"MoveWindow", (PyCFunction)WinObj_MoveWindow, 1,
+	 PyDoc_STR("(short hGlobal, short vGlobal, Boolean front) -> None")},
+	{"ShowWindow", (PyCFunction)WinObj_ShowWindow, 1,
+	 PyDoc_STR("() -> None")},
+	{"AutoDispose", (PyCFunction)WinObj_AutoDispose, 1,
+	 PyDoc_STR("(int)->int. Automatically DisposeHandle the object on Python object cleanup")},
+	{NULL, NULL, 0}
+};
+
+#define WinObj_getsetlist NULL
+
+
+static int WinObj_compare(WindowObject *self, WindowObject *other)
+{
+	if ( self->ob_itself > other->ob_itself ) return 1;
+	if ( self->ob_itself < other->ob_itself ) return -1;
+	return 0;
+}
+
+static PyObject * WinObj_repr(WindowObject *self)
+{
+	char buf[100];
+	sprintf(buf, "<Window object at 0x%8.8x for 0x%8.8x>", (unsigned)self, (unsigned)self->ob_itself);
+	return PyString_FromString(buf);
+}
+
+static int WinObj_hash(WindowObject *self)
+{
+	return (int)self->ob_itself;
+}
+#define WinObj_tp_init 0
+
+#define WinObj_tp_alloc PyType_GenericAlloc
+
+static PyObject *WinObj_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
+{
+	PyObject *_self;
+	WindowPtr itself;
+	char *kw[] = {"itself", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, WinObj_Convert, &itself)) return NULL;
+	if ((_self = type->tp_alloc(type, 0)) == NULL) return NULL;
+	((WindowObject *)_self)->ob_itself = itself;
+	return _self;
+}
+
+#define WinObj_tp_free PyObject_Del
+
+
+PyTypeObject Window_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0, /*ob_size*/
+	"_Win.Window", /*tp_name*/
+	sizeof(WindowObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) WinObj_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc)0, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	(cmpfunc) WinObj_compare, /*tp_compare*/
+	(reprfunc) WinObj_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) WinObj_hash, /*tp_hash*/
+	0, /*tp_call*/
+	0, /*tp_str*/
+	PyObject_GenericGetAttr, /*tp_getattro*/
+	PyObject_GenericSetAttr, /*tp_setattro */
+	0, /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0, /*tp_doc*/
+	0, /*tp_traverse*/
+	0, /*tp_clear*/
+	0, /*tp_richcompare*/
+	0, /*tp_weaklistoffset*/
+	0, /*tp_iter*/
+	0, /*tp_iternext*/
+	WinObj_methods, /* tp_methods */
+	0, /*tp_members*/
+	WinObj_getsetlist, /*tp_getset*/
+	0, /*tp_base*/
+	0, /*tp_dict*/
+	0, /*tp_descr_get*/
+	0, /*tp_descr_set*/
+	0, /*tp_dictoffset*/
+	WinObj_tp_init, /* tp_init */
+	WinObj_tp_alloc, /* tp_alloc */
+	WinObj_tp_new, /* tp_new */
+	WinObj_tp_free, /* tp_free */
+};
+
+/* --------------------- End object type Window --------------------- */
+
+
+static PyObject *Win_GetNewCWindow(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	WindowPtr _rv;
+	short windowID;
+	WindowPtr behind;
+#ifndef GetNewCWindow
+	PyMac_PRECHECK(GetNewCWindow);
+#endif
+	if (!PyArg_ParseTuple(_args, "hO&",
+	                      &windowID,
+	                      WinObj_Convert, &behind))
+		return NULL;
+	_rv = GetNewCWindow(windowID,
+	                    (void *)0,
+	                    behind);
+	_res = Py_BuildValue("O&",
+	                     WinObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Win_NewWindow(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	WindowPtr _rv;
+	Rect boundsRect;
+	Str255 title;
+	Boolean visible;
+	short theProc;
+	WindowPtr behind;
+	Boolean goAwayFlag;
+	long refCon;
+#ifndef NewWindow
+	PyMac_PRECHECK(NewWindow);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&bhO&bl",
+	                      PyMac_GetRect, &boundsRect,
+	                      PyMac_GetStr255, title,
+	                      &visible,
+	                      &theProc,
+	                      WinObj_Convert, &behind,
+	                      &goAwayFlag,
+	                      &refCon))
+		return NULL;
+	_rv = NewWindow((void *)0,
+	                &boundsRect,
+	                title,
+	                visible,
+	                theProc,
+	                behind,
+	                goAwayFlag,
+	                refCon);
+	_res = Py_BuildValue("O&",
+	                     WinObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Win_GetNewWindow(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	WindowPtr _rv;
+	short windowID;
+	WindowPtr behind;
+#ifndef GetNewWindow
+	PyMac_PRECHECK(GetNewWindow);
+#endif
+	if (!PyArg_ParseTuple(_args, "hO&",
+	                      &windowID,
+	                      WinObj_Convert, &behind))
+		return NULL;
+	_rv = GetNewWindow(windowID,
+	                   (void *)0,
+	                   behind);
+	_res = Py_BuildValue("O&",
+	                     WinObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Win_NewCWindow(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	WindowPtr _rv;
+	Rect boundsRect;
+	Str255 title;
+	Boolean visible;
+	short procID;
+	WindowPtr behind;
+	Boolean goAwayFlag;
+	long refCon;
+#ifndef NewCWindow
+	PyMac_PRECHECK(NewCWindow);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&bhO&bl",
+	                      PyMac_GetRect, &boundsRect,
+	                      PyMac_GetStr255, title,
+	                      &visible,
+	                      &procID,
+	                      WinObj_Convert, &behind,
+	                      &goAwayFlag,
+	                      &refCon))
+		return NULL;
+	_rv = NewCWindow((void *)0,
+	                 &boundsRect,
+	                 title,
+	                 visible,
+	                 procID,
+	                 behind,
+	                 goAwayFlag,
+	                 refCon);
+	_res = Py_BuildValue("O&",
+	                     WinObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Win_CreateNewWindow(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	WindowClass windowClass;
+	WindowAttributes attributes;
+	Rect contentBounds;
+	WindowPtr outWindow;
+#ifndef CreateNewWindow
+	PyMac_PRECHECK(CreateNewWindow);
+#endif
+	if (!PyArg_ParseTuple(_args, "llO&",
+	                      &windowClass,
+	                      &attributes,
+	                      PyMac_GetRect, &contentBounds))
+		return NULL;
+	_err = CreateNewWindow(windowClass,
+	                       attributes,
+	                       &contentBounds,
+	                       &outWindow);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     WinObj_New, outWindow);
+	return _res;
+}
+
+static PyObject *Win_CreateWindowFromResource(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	SInt16 resID;
+	WindowPtr outWindow;
+#ifndef CreateWindowFromResource
+	PyMac_PRECHECK(CreateWindowFromResource);
+#endif
+	if (!PyArg_ParseTuple(_args, "h",
+	                      &resID))
+		return NULL;
+	_err = CreateWindowFromResource(resID,
+	                                &outWindow);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     WinObj_New, outWindow);
+	return _res;
+}
+
+static PyObject *Win_ShowFloatingWindows(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+#ifndef ShowFloatingWindows
+	PyMac_PRECHECK(ShowFloatingWindows);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = ShowFloatingWindows();
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Win_HideFloatingWindows(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+#ifndef HideFloatingWindows
+	PyMac_PRECHECK(HideFloatingWindows);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = HideFloatingWindows();
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Win_AreFloatingWindowsVisible(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+#ifndef AreFloatingWindowsVisible
+	PyMac_PRECHECK(AreFloatingWindowsVisible);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = AreFloatingWindowsVisible();
+	_res = Py_BuildValue("b",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Win_CheckUpdate(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	EventRecord theEvent;
+#ifndef CheckUpdate
+	PyMac_PRECHECK(CheckUpdate);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CheckUpdate(&theEvent);
+	_res = Py_BuildValue("bO&",
+	                     _rv,
+	                     PyMac_BuildEventRecord, &theEvent);
+	return _res;
+}
+
+static PyObject *Win_MacFindWindow(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	WindowPartCode _rv;
+	Point thePoint;
+	WindowPtr window;
+#ifndef MacFindWindow
+	PyMac_PRECHECK(MacFindWindow);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetPoint, &thePoint))
+		return NULL;
+	_rv = MacFindWindow(thePoint,
+	                    &window);
+	_res = Py_BuildValue("hO&",
+	                     _rv,
+	                     WinObj_WhichWindow, window);
+	return _res;
+}
+
+static PyObject *Win_FrontWindow(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	WindowPtr _rv;
+#ifndef FrontWindow
+	PyMac_PRECHECK(FrontWindow);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = FrontWindow();
+	_res = Py_BuildValue("O&",
+	                     WinObj_WhichWindow, _rv);
+	return _res;
+}
+
+static PyObject *Win_FrontNonFloatingWindow(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	WindowPtr _rv;
+#ifndef FrontNonFloatingWindow
+	PyMac_PRECHECK(FrontNonFloatingWindow);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = FrontNonFloatingWindow();
+	_res = Py_BuildValue("O&",
+	                     WinObj_WhichWindow, _rv);
+	return _res;
+}
+
+static PyObject *Win_GetFrontWindowOfClass(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	WindowPtr _rv;
+	WindowClass inWindowClass;
+	Boolean mustBeVisible;
+#ifndef GetFrontWindowOfClass
+	PyMac_PRECHECK(GetFrontWindowOfClass);
+#endif
+	if (!PyArg_ParseTuple(_args, "lb",
+	                      &inWindowClass,
+	                      &mustBeVisible))
+		return NULL;
+	_rv = GetFrontWindowOfClass(inWindowClass,
+	                            mustBeVisible);
+	_res = Py_BuildValue("O&",
+	                     WinObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Win_FindWindowOfClass(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Point where;
+	WindowClass inWindowClass;
+	WindowPtr outWindow;
+	WindowPartCode outWindowPart;
+#ifndef FindWindowOfClass
+	PyMac_PRECHECK(FindWindowOfClass);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&l",
+	                      PyMac_GetPoint, &where,
+	                      &inWindowClass))
+		return NULL;
+	_err = FindWindowOfClass(&where,
+	                         inWindowClass,
+	                         &outWindow,
+	                         &outWindowPart);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&h",
+	                     WinObj_WhichWindow, outWindow,
+	                     outWindowPart);
+	return _res;
+}
+
+static PyObject *Win_CreateStandardWindowMenu(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	OptionBits inOptions;
+	MenuHandle outMenu;
+#ifndef CreateStandardWindowMenu
+	PyMac_PRECHECK(CreateStandardWindowMenu);
+#endif
+	if (!PyArg_ParseTuple(_args, "l",
+	                      &inOptions))
+		return NULL;
+	_err = CreateStandardWindowMenu(inOptions,
+	                                &outMenu);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     MenuObj_New, outMenu);
+	return _res;
+}
+
+static PyObject *Win_CollapseAllWindows(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	Boolean collapse;
+#ifndef CollapseAllWindows
+	PyMac_PRECHECK(CollapseAllWindows);
+#endif
+	if (!PyArg_ParseTuple(_args, "b",
+	                      &collapse))
+		return NULL;
+	_err = CollapseAllWindows(collapse);
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Win_GetAvailableWindowPositioningBounds(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+	GDHandle inDevice;
+	Rect outAvailableRect;
+#ifndef GetAvailableWindowPositioningBounds
+	PyMac_PRECHECK(GetAvailableWindowPositioningBounds);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      ResObj_Convert, &inDevice))
+		return NULL;
+	_err = GetAvailableWindowPositioningBounds(inDevice,
+	                                           &outAvailableRect);
+	if (_err != noErr) return PyMac_Error(_err);
+	_res = Py_BuildValue("O&",
+	                     PyMac_BuildRect, &outAvailableRect);
+	return _res;
+}
+
+static PyObject *Win_DisableScreenUpdates(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+#ifndef DisableScreenUpdates
+	PyMac_PRECHECK(DisableScreenUpdates);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = DisableScreenUpdates();
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Win_EnableScreenUpdates(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	OSStatus _err;
+#ifndef EnableScreenUpdates
+	PyMac_PRECHECK(EnableScreenUpdates);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_err = EnableScreenUpdates();
+	if (_err != noErr) return PyMac_Error(_err);
+	Py_INCREF(Py_None);
+	_res = Py_None;
+	return _res;
+}
+
+static PyObject *Win_PinRect(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	long _rv;
+	Rect theRect;
+	Point thePt;
+#ifndef PinRect
+	PyMac_PRECHECK(PinRect);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      PyMac_GetRect, &theRect,
+	                      PyMac_GetPoint, &thePt))
+		return NULL;
+	_rv = PinRect(&theRect,
+	              thePt);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *Win_GetGrayRgn(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	RgnHandle _rv;
+#ifndef GetGrayRgn
+	PyMac_PRECHECK(GetGrayRgn);
+#endif
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = GetGrayRgn();
+	_res = Py_BuildValue("O&",
+	                     ResObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Win_GetWindowFromPort(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	WindowPtr _rv;
+	CGrafPtr port;
+#ifndef GetWindowFromPort
+	PyMac_PRECHECK(GetWindowFromPort);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      GrafObj_Convert, &port))
+		return NULL;
+	_rv = GetWindowFromPort(port);
+	_res = Py_BuildValue("O&",
+	                     WinObj_New, _rv);
+	return _res;
+}
+
+static PyObject *Win_WhichWindow(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+
+	long ptr;
+
+	if ( !PyArg_ParseTuple(_args, "i", &ptr) )
+	        return NULL;
+	_res = WinObj_WhichWindow((WindowPtr)ptr);
+	return _res;
+
+}
+
+static PyObject *Win_FindWindow(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	short _rv;
+	Point thePoint;
+	WindowPtr theWindow;
+#ifndef FindWindow
+	PyMac_PRECHECK(FindWindow);
+#endif
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      PyMac_GetPoint, &thePoint))
+		return NULL;
+	_rv = FindWindow(thePoint,
+	                 &theWindow);
+	_res = Py_BuildValue("hO&",
+	                     _rv,
+	                     WinObj_WhichWindow, theWindow);
+	return _res;
+}
+
+static PyMethodDef Win_methods[] = {
+	{"GetNewCWindow", (PyCFunction)Win_GetNewCWindow, 1,
+	 PyDoc_STR("(short windowID, WindowPtr behind) -> (WindowPtr _rv)")},
+	{"NewWindow", (PyCFunction)Win_NewWindow, 1,
+	 PyDoc_STR("(Rect boundsRect, Str255 title, Boolean visible, short theProc, WindowPtr behind, Boolean goAwayFlag, long refCon) -> (WindowPtr _rv)")},
+	{"GetNewWindow", (PyCFunction)Win_GetNewWindow, 1,
+	 PyDoc_STR("(short windowID, WindowPtr behind) -> (WindowPtr _rv)")},
+	{"NewCWindow", (PyCFunction)Win_NewCWindow, 1,
+	 PyDoc_STR("(Rect boundsRect, Str255 title, Boolean visible, short procID, WindowPtr behind, Boolean goAwayFlag, long refCon) -> (WindowPtr _rv)")},
+	{"CreateNewWindow", (PyCFunction)Win_CreateNewWindow, 1,
+	 PyDoc_STR("(WindowClass windowClass, WindowAttributes attributes, Rect contentBounds) -> (WindowPtr outWindow)")},
+	{"CreateWindowFromResource", (PyCFunction)Win_CreateWindowFromResource, 1,
+	 PyDoc_STR("(SInt16 resID) -> (WindowPtr outWindow)")},
+	{"ShowFloatingWindows", (PyCFunction)Win_ShowFloatingWindows, 1,
+	 PyDoc_STR("() -> None")},
+	{"HideFloatingWindows", (PyCFunction)Win_HideFloatingWindows, 1,
+	 PyDoc_STR("() -> None")},
+	{"AreFloatingWindowsVisible", (PyCFunction)Win_AreFloatingWindowsVisible, 1,
+	 PyDoc_STR("() -> (Boolean _rv)")},
+	{"CheckUpdate", (PyCFunction)Win_CheckUpdate, 1,
+	 PyDoc_STR("() -> (Boolean _rv, EventRecord theEvent)")},
+	{"MacFindWindow", (PyCFunction)Win_MacFindWindow, 1,
+	 PyDoc_STR("(Point thePoint) -> (WindowPartCode _rv, WindowPtr window)")},
+	{"FrontWindow", (PyCFunction)Win_FrontWindow, 1,
+	 PyDoc_STR("() -> (WindowPtr _rv)")},
+	{"FrontNonFloatingWindow", (PyCFunction)Win_FrontNonFloatingWindow, 1,
+	 PyDoc_STR("() -> (WindowPtr _rv)")},
+	{"GetFrontWindowOfClass", (PyCFunction)Win_GetFrontWindowOfClass, 1,
+	 PyDoc_STR("(WindowClass inWindowClass, Boolean mustBeVisible) -> (WindowPtr _rv)")},
+	{"FindWindowOfClass", (PyCFunction)Win_FindWindowOfClass, 1,
+	 PyDoc_STR("(Point where, WindowClass inWindowClass) -> (WindowPtr outWindow, WindowPartCode outWindowPart)")},
+	{"CreateStandardWindowMenu", (PyCFunction)Win_CreateStandardWindowMenu, 1,
+	 PyDoc_STR("(OptionBits inOptions) -> (MenuHandle outMenu)")},
+	{"CollapseAllWindows", (PyCFunction)Win_CollapseAllWindows, 1,
+	 PyDoc_STR("(Boolean collapse) -> None")},
+	{"GetAvailableWindowPositioningBounds", (PyCFunction)Win_GetAvailableWindowPositioningBounds, 1,
+	 PyDoc_STR("(GDHandle inDevice) -> (Rect outAvailableRect)")},
+	{"DisableScreenUpdates", (PyCFunction)Win_DisableScreenUpdates, 1,
+	 PyDoc_STR("() -> None")},
+	{"EnableScreenUpdates", (PyCFunction)Win_EnableScreenUpdates, 1,
+	 PyDoc_STR("() -> None")},
+	{"PinRect", (PyCFunction)Win_PinRect, 1,
+	 PyDoc_STR("(Rect theRect, Point thePt) -> (long _rv)")},
+	{"GetGrayRgn", (PyCFunction)Win_GetGrayRgn, 1,
+	 PyDoc_STR("() -> (RgnHandle _rv)")},
+	{"GetWindowFromPort", (PyCFunction)Win_GetWindowFromPort, 1,
+	 PyDoc_STR("(CGrafPtr port) -> (WindowPtr _rv)")},
+	{"WhichWindow", (PyCFunction)Win_WhichWindow, 1,
+	 PyDoc_STR("Resolve an integer WindowPtr address to a Window object")},
+	{"FindWindow", (PyCFunction)Win_FindWindow, 1,
+	 PyDoc_STR("(Point thePoint) -> (short _rv, WindowPtr theWindow)")},
+	{NULL, NULL, 0}
+};
+
+
+
+/* Return the object corresponding to the window, or NULL */
+
+PyObject *
+WinObj_WhichWindow(WindowPtr w)
+{
+        PyObject *it;
+
+        if (w == NULL) {
+                it = Py_None;
+                Py_INCREF(it);
+        } else {
+                it = (PyObject *) GetWRefCon(w);
+                if (it == NULL || !IsPointerValid((Ptr)it) || ((WindowObject *)it)->ob_itself != w || !WinObj_Check(it)) {
+                        it = WinObj_New(w);
+                        ((WindowObject *)it)->ob_freeit = NULL;
+                } else {
+                        Py_INCREF(it);
+                }
+        }
+        return it;
+}
+
+
+void init_Win(void)
+{
+	PyObject *m;
+	PyObject *d;
+
+
+
+	        PyMac_INIT_TOOLBOX_OBJECT_NEW(WindowPtr, WinObj_New);
+	        PyMac_INIT_TOOLBOX_OBJECT_NEW(WindowPtr, WinObj_WhichWindow);
+	        PyMac_INIT_TOOLBOX_OBJECT_CONVERT(WindowPtr, WinObj_Convert);
+
+
+	m = Py_InitModule("_Win", Win_methods);
+	d = PyModule_GetDict(m);
+	Win_Error = PyMac_GetOSErrException();
+	if (Win_Error == NULL ||
+	    PyDict_SetItemString(d, "Error", Win_Error) != 0)
+		return;
+	Window_Type.ob_type = &PyType_Type;
+	if (PyType_Ready(&Window_Type) < 0) return;
+	Py_INCREF(&Window_Type);
+	PyModule_AddObject(m, "Window", (PyObject *)&Window_Type);
+	/* Backward-compatible name */
+	Py_INCREF(&Window_Type);
+	PyModule_AddObject(m, "WindowType", (PyObject *)&Window_Type);
+}
+
+/* ======================== End module _Win ========================= */
+

Added: vendor/Python/current/Mac/Modules/win/winedit.py
===================================================================
--- vendor/Python/current/Mac/Modules/win/winedit.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/win/winedit.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,69 @@
+# These are inline-routines/defines, so we do them "by hand"
+#
+
+f = Method(Boolean, 'IsWindowVisible',
+    (WindowRef, 'theWindow', InMode),
+)
+methods.append(f)
+
+f = Method(void, 'GetWindowStructureRgn',
+        (WindowRef, 'theWindow', InMode),
+        (RgnHandle, 'r', InMode),
+)
+methods.append(f)
+
+f = Method(void, 'GetWindowContentRgn',
+        (WindowRef, 'theWindow', InMode),
+        (RgnHandle, 'r', InMode),
+)
+methods.append(f)
+
+f = Method(void, 'GetWindowUpdateRgn',
+        (WindowRef, 'theWindow', InMode),
+        (RgnHandle, 'r', InMode),
+)
+methods.append(f)
+
+f = Method(ExistingWindowPtr, 'GetNextWindow',
+        (WindowRef, 'theWindow', InMode),
+)
+methods.append(f)
+
+f = Function(short, 'FindWindow',
+    (Point, 'thePoint', InMode),
+    (ExistingWindowPtr, 'theWindow', OutMode),
+)
+functions.append(f)
+
+f = Method(void, 'MoveWindow',
+    (WindowPtr, 'theWindow', InMode),
+    (short, 'hGlobal', InMode),
+    (short, 'vGlobal', InMode),
+    (Boolean, 'front', InMode),
+)
+methods.append(f)
+
+f = Method(void, 'ShowWindow',
+    (WindowPtr, 'theWindow', InMode),
+)
+methods.append(f)
+
+#
+# A method to set the auto-dispose flag
+#
+AutoDispose_body = """
+int onoff, old = 0;
+if (!PyArg_ParseTuple(_args, "i", &onoff))
+        return NULL;
+if ( _self->ob_freeit )
+        old = 1;
+if ( onoff )
+        _self->ob_freeit = PyMac_AutoDisposeWindow;
+else
+        _self->ob_freeit = NULL;
+_res = Py_BuildValue("i", old);
+return _res;
+"""
+f = ManualGenerator("AutoDispose", AutoDispose_body)
+f.docstring = lambda: "(int)->int. Automatically DisposeHandle the object on Python object cleanup"
+methods.append(f)

Added: vendor/Python/current/Mac/Modules/win/winscan.py
===================================================================
--- vendor/Python/current/Mac/Modules/win/winscan.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/win/winscan.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,130 @@
+# Scan an Apple header file, generating a Python file of generator calls.
+import sys
+import os
+from bgenlocations import TOOLBOXDIR, BGENDIR
+sys.path.append(BGENDIR)
+
+from scantools import Scanner
+
+def main():
+    input = "MacWindows.h"
+    output = "wingen.py"
+    defsoutput = TOOLBOXDIR + "Windows.py"
+    scanner = MyScanner(input, output, defsoutput)
+    scanner.scan()
+    scanner.close()
+    print "=== Testing definitions output code ==="
+    execfile(defsoutput, {}, {})
+    print "=== Done scanning and generating, now importing the generated code... ==="
+    import winsupport
+    print "=== Done.  It's up to you to compile it now! ==="
+
+class MyScanner(Scanner):
+
+    def destination(self, type, name, arglist):
+        classname = "Function"
+        listname = "functions"
+        if arglist:
+            t, n, m = arglist[0]
+            if t in ("WindowPtr", "WindowPeek", "WindowRef") and m == "InMode":
+                classname = "Method"
+                listname = "methods"
+        return classname, listname
+
+    def writeinitialdefs(self):
+        self.defsfile.write("def FOUR_CHAR_CODE(x): return x\n")
+        self.defsfile.write("false = 0\n")
+        self.defsfile.write("true = 1\n")
+        self.defsfile.write("kWindowNoConstrainAttribute = 0x80000000\n")
+
+    def makeblacklistnames(self):
+        return [
+                'DisposeWindow', # Implied when the object is deleted
+                'CloseWindow',
+                'SetWindowProperty',    # For the moment
+                'GetWindowProperty',
+                'GetWindowPropertySize',
+                'RemoveWindowProperty',
+                'MacCloseWindow',
+                'GetWindowList', # Don't know whether this is safe...
+                # Constants with funny definitions
+                'kMouseUpOutOfSlop',
+                'kAllWindowClasses',
+                'kWindowNoConstrainAttribute',
+                # OS8 only:
+                'GetAuxWin',
+                'GetWindowDataHandle',
+                'SaveOld',
+                'DrawNew',
+                'SetWinColor',
+                'SetDeskCPat',
+                'InitWindows',
+                'InitFloatingWindows',
+                'GetWMgrPort',
+                'GetCWMgrPort',
+                'ValidRgn',             # Use versions with Window in their name
+                'ValidRect',
+                'InvalRgn',
+                'InvalRect',
+                'IsValidWindowPtr', # I think this is useless for Python, but not sure...
+                'GetWindowZoomFlag',    # Not available in Carbon
+                'GetWindowTitleWidth',  # Ditto
+                'GetWindowGoAwayFlag',
+                'GetWindowSpareFlag',
+                ]
+
+    def makeblacklisttypes(self):
+        return [
+                'ProcPtr',
+                'DragGrayRgnUPP',
+                'WindowPaintUPP',
+                'Collection',           # For now, to be done later
+                'WindowDefSpec',        # Too difficult for now
+                'WindowDefSpec_ptr',
+                'EventRef', #TBD
+                ]
+
+    def makerepairinstructions(self):
+        return [
+
+                # GetWTitle
+                ([("Str255", "*", "InMode")],
+                 [("*", "*", "OutMode")]),
+
+                ([("void_ptr", "*", "InMode"), ("long", "*", "InMode")],
+                 [("InBuffer", "*", "*")]),
+
+                ([("void", "*", "OutMode"), ("long", "*", "InMode"),
+                                            ("long", "*", "OutMode")],
+                 [("VarVarOutBuffer", "*", "InOutMode")]),
+
+                ([("void", "wStorage", "OutMode")],
+                 [("NullStorage", "*", "InMode")]),
+
+                # match FindWindowOfClass
+                ([("WindowRef", "outWindow", "OutMode"), ("WindowPartCode", "outWindowPart", "OutMode")],
+                 [("ExistingWindowPtr", "*", "OutMode"), ("WindowPartCode", "outWindowPart", "OutMode")]),
+            # then match CreateNewWindow and CreateWindowFromResource
+                ([("WindowRef", "outWindow", "OutMode")],
+                 [("WindowRef", "*", "*")]),
+
+                ([("WindowPtr", "*", "OutMode")],
+                 [("ExistingWindowPtr", "*", "*")]),
+                ([("WindowRef", "*", "OutMode")],       # Same, but other style headerfiles
+                 [("ExistingWindowPtr", "*", "*")]),
+
+                ([("WindowPtr", "FrontWindow", "ReturnMode")],
+                 [("ExistingWindowPtr", "*", "*")]),
+                ([("WindowRef", "FrontWindow", "ReturnMode")],  # Ditto
+                 [("ExistingWindowPtr", "*", "*")]),
+                ([("WindowPtr", "FrontNonFloatingWindow", "ReturnMode")],
+                 [("ExistingWindowPtr", "*", "*")]),
+                ([("WindowRef", "FrontNonFloatingWindow", "ReturnMode")],       # Ditto
+                 [("ExistingWindowPtr", "*", "*")]),
+
+                ([("Rect_ptr", "*", "ReturnMode")], # GetWindowXXXState accessors
+                 [("void", "*", "ReturnMode")]),
+                ]
+
+if __name__ == "__main__":
+    main()

Added: vendor/Python/current/Mac/Modules/win/winsupport.py
===================================================================
--- vendor/Python/current/Mac/Modules/win/winsupport.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Modules/win/winsupport.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,226 @@
+# This script generates a Python interface for an Apple Macintosh Manager.
+# It uses the "bgen" package to generate C code.
+# The function specifications are generated by scanning the mamager's header file,
+# using the "scantools" package (customized for this particular manager).
+
+import string
+
+# Declarations that change for each manager
+MACHEADERFILE = 'Windows.h'             # The Apple header file
+MODNAME = '_Win'                                # The name of the module
+OBJECTNAME = 'Window'                   # The basic name of the objects used here
+
+# The following is *usually* unchanged but may still require tuning
+MODPREFIX = 'Win'                       # The prefix for module-wide routines
+OBJECTTYPE = OBJECTNAME + 'Ptr'         # The C type used to represent them
+OBJECTPREFIX = MODPREFIX + 'Obj'        # The prefix for object methods
+INPUTFILE = string.lower(MODPREFIX) + 'gen.py' # The file generated by the scanner
+EDITFILE = string.lower(MODPREFIX) + 'edit.py' # The manual definitions
+OUTPUTFILE = MODNAME + "module.c"       # The file generated by this program
+
+from macsupport import *
+
+# Create the type objects
+
+WindowPtr = OpaqueByValueType(OBJECTTYPE, OBJECTPREFIX)
+WindowRef = WindowPtr
+WindowPeek = OpaqueByValueType("WindowPeek", OBJECTPREFIX)
+WindowPeek.passInput = lambda name: "(WindowPeek)(%s)" % name
+CGrafPtr = OpaqueByValueType("CGrafPtr", "GrafObj")
+GrafPtr = OpaqueByValueType("GrafPtr", "GrafObj")
+
+DragReference = OpaqueByValueType("DragReference", "DragObj")
+
+RgnHandle = OpaqueByValueType("RgnHandle", "ResObj")
+PicHandle = OpaqueByValueType("PicHandle", "ResObj")
+WCTabHandle = OpaqueByValueType("WCTabHandle", "ResObj")
+AuxWinHandle = OpaqueByValueType("AuxWinHandle", "ResObj")
+PixPatHandle = OpaqueByValueType("PixPatHandle", "ResObj")
+AliasHandle = OpaqueByValueType("AliasHandle", "ResObj")
+IconRef = OpaqueByValueType("IconRef", "ResObj")
+
+WindowRegionCode = Type("WindowRegionCode", "H")
+WindowClass = Type("WindowClass", "l")
+WindowAttributes = Type("WindowAttributes", "l")
+WindowPositionMethod = Type("WindowPositionMethod", "l")
+WindowTransitionEffect = Type("WindowTransitionEffect", "l")
+WindowTransitionAction = Type("WindowTransitionAction", "l")
+RGBColor = OpaqueType("RGBColor", "QdRGB")
+RGBColor_ptr = RGBColor
+ScrollWindowOptions = Type("ScrollWindowOptions", "l")
+WindowPartCode = Type("WindowPartCode", "h")
+WindowDefPartCode = Type("WindowDefPartCode", "h")
+WindowModality = Type("WindowModality", "l")
+GDHandle = OpaqueByValueType("GDHandle", "ResObj")
+WindowConstrainOptions = Type("WindowConstrainOptions", "l")
+
+PropertyCreator = OSTypeType("PropertyCreator")
+PropertyTag = OSTypeType("PropertyTag")
+
+includestuff = includestuff + """
+#include <Carbon/Carbon.h>
+
+#ifdef USE_TOOLBOX_OBJECT_GLUE
+extern PyObject *_WinObj_New(WindowRef);
+extern PyObject *_WinObj_WhichWindow(WindowRef);
+extern int _WinObj_Convert(PyObject *, WindowRef *);
+
+#define WinObj_New _WinObj_New
+#define WinObj_WhichWindow _WinObj_WhichWindow
+#define WinObj_Convert _WinObj_Convert
+#endif
+
+/* Classic calls that we emulate in carbon mode */
+#define GetWindowUpdateRgn(win, rgn) GetWindowRegion((win), kWindowUpdateRgn, (rgn))
+#define GetWindowStructureRgn(win, rgn) GetWindowRegion((win), kWindowStructureRgn, (rgn))
+#define GetWindowContentRgn(win, rgn) GetWindowRegion((win), kWindowContentRgn, (rgn))
+
+/* Function to dispose a window, with a "normal" calling sequence */
+static void
+PyMac_AutoDisposeWindow(WindowPtr w)
+{
+        DisposeWindow(w);
+}
+"""
+
+finalstuff = finalstuff + """
+/* Return the object corresponding to the window, or NULL */
+
+PyObject *
+WinObj_WhichWindow(WindowPtr w)
+{
+        PyObject *it;
+
+        if (w == NULL) {
+                it = Py_None;
+                Py_INCREF(it);
+        } else {
+                it = (PyObject *) GetWRefCon(w);
+                if (it == NULL || !IsPointerValid((Ptr)it) || ((WindowObject *)it)->ob_itself != w || !WinObj_Check(it)) {
+                        it = WinObj_New(w);
+                        ((WindowObject *)it)->ob_freeit = NULL;
+                } else {
+                        Py_INCREF(it);
+                }
+        }
+        return it;
+}
+"""
+
+initstuff = initstuff + """
+        PyMac_INIT_TOOLBOX_OBJECT_NEW(WindowPtr, WinObj_New);
+        PyMac_INIT_TOOLBOX_OBJECT_NEW(WindowPtr, WinObj_WhichWindow);
+        PyMac_INIT_TOOLBOX_OBJECT_CONVERT(WindowPtr, WinObj_Convert);
+"""
+
+class MyObjectDefinition(PEP253Mixin, GlobalObjectDefinition):
+    def outputCheckNewArg(self):
+        Output("if (itself == NULL) return PyMac_Error(resNotFound);")
+        Output("/* XXXX Or should we use WhichWindow code here? */")
+    def outputStructMembers(self):
+        GlobalObjectDefinition.outputStructMembers(self)
+        Output("void (*ob_freeit)(%s ptr);", self.itselftype)
+    def outputInitStructMembers(self):
+        GlobalObjectDefinition.outputInitStructMembers(self)
+        Output("it->ob_freeit = NULL;")
+        Output("if (GetWRefCon(itself) == 0)")
+        OutLbrace()
+        Output("SetWRefCon(itself, (long)it);")
+        Output("it->ob_freeit = PyMac_AutoDisposeWindow;")
+        OutRbrace()
+    def outputCheckConvertArg(self):
+        Out("""
+        if (v == Py_None) { *p_itself = NULL; return 1; }
+        if (PyInt_Check(v)) { *p_itself = (WindowPtr)PyInt_AsLong(v); return 1; }
+        """)
+        OutLbrace()
+        Output("DialogRef dlg;")
+        OutLbrace("if (DlgObj_Convert(v, &dlg) && dlg)")
+        Output("*p_itself = GetDialogWindow(dlg);")
+        Output("return 1;")
+        OutRbrace()
+        Output("PyErr_Clear();")
+        OutRbrace()
+    def outputCleanupStructMembers(self):
+        Output("if (self->ob_freeit && self->ob_itself)")
+        OutLbrace()
+        Output("SetWRefCon(self->ob_itself, 0);")
+        Output("self->ob_freeit(self->ob_itself);")
+        OutRbrace()
+        Output("self->ob_itself = NULL;")
+        Output("self->ob_freeit = NULL;")
+
+    def outputCompare(self):
+        Output()
+        Output("static int %s_compare(%s *self, %s *other)", self.prefix, self.objecttype, self.objecttype)
+        OutLbrace()
+        Output("if ( self->ob_itself > other->ob_itself ) return 1;")
+        Output("if ( self->ob_itself < other->ob_itself ) return -1;")
+        Output("return 0;")
+        OutRbrace()
+
+    def outputHash(self):
+        Output()
+        Output("static int %s_hash(%s *self)", self.prefix, self.objecttype)
+        OutLbrace()
+        Output("return (int)self->ob_itself;")
+        OutRbrace()
+
+    def outputRepr(self):
+        Output()
+        Output("static PyObject * %s_repr(%s *self)", self.prefix, self.objecttype)
+        OutLbrace()
+        Output("char buf[100];")
+        Output("""sprintf(buf, "<Window object at 0x%%8.8x for 0x%%8.8x>", (unsigned)self, (unsigned)self->ob_itself);""")
+        Output("return PyString_FromString(buf);")
+        OutRbrace()
+
+##      def outputFreeIt(self, itselfname):
+##              Output("DisposeWindow(%s);", itselfname)
+# From here on it's basically all boiler plate...
+
+# Create the generator groups and link them
+module = MacModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff)
+object = MyObjectDefinition(OBJECTNAME, OBJECTPREFIX, OBJECTTYPE)
+module.addobject(object)
+
+# Create the generator classes used to populate the lists
+Function = OSErrWeakLinkFunctionGenerator
+Method = OSErrWeakLinkMethodGenerator
+
+# Create and populate the lists
+functions = []
+methods = []
+execfile(INPUTFILE)
+
+# Add manual routines for converting integer WindowPtr's (as returned by
+# various event routines)  and Dialog objects to a WindowObject.
+whichwin_body = """
+long ptr;
+
+if ( !PyArg_ParseTuple(_args, "i", &ptr) )
+        return NULL;
+_res = WinObj_WhichWindow((WindowPtr)ptr);
+return _res;
+"""
+
+f = ManualGenerator("WhichWindow", whichwin_body)
+f.docstring = lambda : "Resolve an integer WindowPtr address to a Window object"
+
+functions.append(f)
+
+# And add the routines that access the internal bits of a window struct. They
+# are currently #defined in Windows.h, they will be real routines in Copland
+# (at which time this execfile can go)
+execfile(EDITFILE)
+
+# add the populated lists to the generator groups
+# (in a different wordl the scan program would generate this)
+for f in functions: module.add(f)
+for f in methods: object.add(f)
+
+
+
+# generate output (open the output file as late as possible)
+SetOutputFileName(OUTPUTFILE)
+module.generate()

Added: vendor/Python/current/Mac/PythonLauncher/English.lproj/Credits.rtf
===================================================================
--- vendor/Python/current/Mac/PythonLauncher/English.lproj/Credits.rtf	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/PythonLauncher/English.lproj/Credits.rtf	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,30 @@
+{\rtf1\mac\ansicpg10000\cocoartf100
+{\fonttbl\f0\fswiss\fcharset77 Helvetica-Bold;\f1\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
+
+\f0\b\fs24 \cf0 Engineering:
+\f1\b0 \
+	Jack Jansen\
+\
+
+\f0\b Human Interface Design:
+\f1\b0 \
+	Jack Jansen\
+\
+
+\f0\b Testing:
+\f1\b0 \
+	Jack Jansen\
+        Pythonmac-SIG at python.org\
+\
+
+\f0\b Documentation:
+\f1\b0 \
+	Missing\
+\
+
+\f0\b With special thanks to:
+\f1\b0 \
+	Guido, of course\
+}
\ No newline at end of file

Added: vendor/Python/current/Mac/PythonLauncher/English.lproj/MainMenu.nib/classes.nib
===================================================================
--- vendor/Python/current/Mac/PythonLauncher/English.lproj/MainMenu.nib/classes.nib	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/PythonLauncher/English.lproj/MainMenu.nib/classes.nib	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,12 @@
+{
+    IBClasses = (
+        {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, 
+        {
+            ACTIONS = {showPreferences = id; }; 
+            CLASS = MyAppDelegate; 
+            LANGUAGE = ObjC; 
+            SUPERCLASS = NSObject; 
+        }
+    ); 
+    IBVersion = 1; 
+}
\ No newline at end of file

Added: vendor/Python/current/Mac/PythonLauncher/English.lproj/MainMenu.nib/info.nib
===================================================================
--- vendor/Python/current/Mac/PythonLauncher/English.lproj/MainMenu.nib/info.nib	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/PythonLauncher/English.lproj/MainMenu.nib/info.nib	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
+<plist version="0.9">
+<dict>
+	<key>IBDocumentLocation</key>
+	<string>99 33 356 240 0 0 800 578 </string>
+	<key>IBEditorPositions</key>
+	<dict>
+		<key>29</key>
+		<string>82 396 318 44 0 0 800 578 </string>
+	</dict>
+	<key>IBFramework Version</key>
+	<string>263.2</string>
+	<key>IBOpenObjects</key>
+	<array>
+		<integer>29</integer>
+	</array>
+	<key>IBSystem Version</key>
+	<string>5S66</string>
+</dict>
+</plist>

Added: vendor/Python/current/Mac/PythonLauncher/English.lproj/MainMenu.nib/objects.nib
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Mac/PythonLauncher/English.lproj/MainMenu.nib/objects.nib
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Mac/PythonLauncher/English.lproj/MyDocument.nib/classes.nib
===================================================================
--- vendor/Python/current/Mac/PythonLauncher/English.lproj/MyDocument.nib/classes.nib	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/PythonLauncher/English.lproj/MyDocument.nib/classes.nib	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,26 @@
+{
+    IBClasses = (
+        {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, 
+        {
+            ACTIONS = {"do_apply" = id; "do_cancel" = id; "do_reset" = id; "do_run" = id; }; 
+            CLASS = MyDocument; 
+            LANGUAGE = ObjC; 
+            OUTLETS = {
+                commandline = NSTextField; 
+                debug = NSButton; 
+                honourhashbang = NSButton; 
+                inspect = NSButton; 
+                interpreter = NSTextField; 
+                nosite = NSButton; 
+                optimize = NSButton; 
+                others = NSTextField; 
+                scriptargs = NSTextField; 
+                tabs = NSButton; 
+                verbose = NSButton; 
+                "with_terminal" = NSButton; 
+            }; 
+            SUPERCLASS = NSDocument; 
+        }
+    ); 
+    IBVersion = 1; 
+}
\ No newline at end of file

Added: vendor/Python/current/Mac/PythonLauncher/English.lproj/MyDocument.nib/info.nib
===================================================================
--- vendor/Python/current/Mac/PythonLauncher/English.lproj/MyDocument.nib/info.nib	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/PythonLauncher/English.lproj/MyDocument.nib/info.nib	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>IBDocumentLocation</key>
+	<string>398 60 356 240 0 0 1024 746 </string>
+	<key>IBFramework Version</key>
+	<string>291.0</string>
+	<key>IBOpenObjects</key>
+	<array>
+		<integer>5</integer>
+	</array>
+	<key>IBSystem Version</key>
+	<string>6L60</string>
+</dict>
+</plist>

Added: vendor/Python/current/Mac/PythonLauncher/English.lproj/MyDocument.nib/objects.nib
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Mac/PythonLauncher/English.lproj/MyDocument.nib/objects.nib
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Mac/PythonLauncher/English.lproj/PreferenceWindow.nib/classes.nib
===================================================================
--- vendor/Python/current/Mac/PythonLauncher/English.lproj/PreferenceWindow.nib/classes.nib	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/PythonLauncher/English.lproj/PreferenceWindow.nib/classes.nib	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,26 @@
+{
+    IBClasses = (
+        {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, 
+        {
+            ACTIONS = {"do_apply" = id; "do_filetype" = id; "do_reset" = id; }; 
+            CLASS = PreferencesWindowController; 
+            LANGUAGE = ObjC; 
+            OUTLETS = {
+                commandline = NSTextField; 
+                debug = NSButton; 
+                filetype = NSPopUpButton; 
+                honourhashbang = NSButton; 
+                inspect = NSButton; 
+                interpreter = NSTextField; 
+                nosite = NSButton; 
+                optimize = NSButton; 
+                others = NSTextField; 
+                tabs = NSButton; 
+                verbose = NSButton; 
+                "with_terminal" = NSButton; 
+            }; 
+            SUPERCLASS = NSWindowController; 
+        }
+    ); 
+    IBVersion = 1; 
+}
\ No newline at end of file

Added: vendor/Python/current/Mac/PythonLauncher/English.lproj/PreferenceWindow.nib/info.nib
===================================================================
--- vendor/Python/current/Mac/PythonLauncher/English.lproj/PreferenceWindow.nib/info.nib	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/PythonLauncher/English.lproj/PreferenceWindow.nib/info.nib	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>IBDocumentLocation</key>
+	<string>565 235 519 534 0 0 1280 1002 </string>
+	<key>IBFramework Version</key>
+	<string>364.0</string>
+	<key>IBOpenObjects</key>
+	<array>
+		<integer>5</integer>
+	</array>
+	<key>IBSystem Version</key>
+	<string>7H63</string>
+</dict>
+</plist>

Added: vendor/Python/current/Mac/PythonLauncher/English.lproj/PreferenceWindow.nib/objects.nib
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Mac/PythonLauncher/English.lproj/PreferenceWindow.nib/objects.nib
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Mac/PythonLauncher/FileSettings.h
===================================================================
--- vendor/Python/current/Mac/PythonLauncher/FileSettings.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/PythonLauncher/FileSettings.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,64 @@
+//
+//  FileSettings.h
+//  PythonLauncher
+//
+//  Created by Jack Jansen on Sun Jul 21 2002.
+//  Copyright (c) 2002 __MyCompanyName__. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+ at protocol FileSettingsSource
+- (NSString *) interpreter;
+- (BOOL) honourhashbang;
+- (BOOL) debug;
+- (BOOL) verbose;
+- (BOOL) inspect;
+- (BOOL) optimize;
+- (BOOL) nosite;
+- (BOOL) tabs;
+- (NSString *) others;
+- (BOOL) with_terminal;
+- (NSString *) scriptargs;
+ at end
+
+ at interface FileSettings : NSObject <FileSettingsSource>
+{
+    NSString *interpreter;	// The pathname of the interpreter to use
+    NSArray *interpreters;	// List of known interpreters
+    BOOL honourhashbang;	// #! line overrides interpreter
+    BOOL debug;			// -d option: debug parser
+    BOOL verbose;		// -v option: verbose import
+    BOOL inspect;		// -i option: interactive mode after script
+    BOOL optimize;		// -O option: optimize bytecode
+    BOOL nosite;		// -S option: don't import site.py
+    BOOL tabs;			// -t option: warn about inconsistent tabs
+    NSString *others;		// other options
+    NSString *scriptargs;	// script arguments (not for preferences)
+    BOOL with_terminal;		// Run in terminal window
+
+    FileSettings *origsource;
+    NSString *prefskey;
+}
+
++ (id)getDefaultsForFileType: (NSString *)filetype;
++ (id)getFactorySettingsForFileType: (NSString *)filetype;
++ (id)newSettingsForFileType: (NSString *)filetype;
+
+//- (id)init;
+- (id)initForFileType: (NSString *)filetype;
+- (id)initForFSDefaultFileType: (NSString *)filetype;
+- (id)initForDefaultFileType: (NSString *)filetype;
+//- (id)initWithFileSettings: (FileSettings *)source;
+
+- (void)updateFromSource: (id <FileSettingsSource>)source;
+- (NSString *)commandLineForScript: (NSString *)script;
+
+//- (void)applyFactorySettingsForFileType: (NSString *)filetype;
+//- (void)saveDefaults;
+//- (void)applyUserDefaults: (NSString *)filetype;
+- (void)applyValuesFromDict: (NSDictionary *)dict;
+- (void)reset;
+- (NSArray *) interpreters;
+
+ at end


Property changes on: vendor/Python/current/Mac/PythonLauncher/FileSettings.h
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Mac/PythonLauncher/FileSettings.m
===================================================================
--- vendor/Python/current/Mac/PythonLauncher/FileSettings.m	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/PythonLauncher/FileSettings.m	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,313 @@
+//
+//  FileSettings.m
+//  PythonLauncher
+//
+//  Created by Jack Jansen on Sun Jul 21 2002.
+//  Copyright (c) 2002 __MyCompanyName__. All rights reserved.
+//
+
+#import "FileSettings.h"
+
+ at implementation FileSettings
+
++ (id)getFactorySettingsForFileType: (NSString *)filetype
+{
+    static FileSettings *fsdefault_py, *fsdefault_pyw, *fsdefault_pyc;
+    FileSettings **curdefault;
+    
+    if ([filetype isEqualToString: @"Python Script"]) {
+        curdefault = &fsdefault_py;
+    } else if ([filetype isEqualToString: @"Python GUI Script"]) {
+        curdefault = &fsdefault_pyw;
+    } else if ([filetype isEqualToString: @"Python Bytecode Document"]) {
+        curdefault = &fsdefault_pyc;
+    } else {
+        NSLog(@"Funny File Type: %@\n", filetype);
+        curdefault = &fsdefault_py;
+        filetype = @"Python Script";
+    }
+    if (!*curdefault) {
+        *curdefault = [[FileSettings new] initForFSDefaultFileType: filetype];
+    }
+    return *curdefault;
+}
+
++ (id)getDefaultsForFileType: (NSString *)filetype
+{
+    static FileSettings *default_py, *default_pyw, *default_pyc;
+    FileSettings **curdefault;
+    
+    if ([filetype isEqualToString: @"Python Script"]) {
+        curdefault = &default_py;
+    } else if ([filetype isEqualToString: @"Python GUI Script"]) {
+        curdefault = &default_pyw;
+    } else if ([filetype isEqualToString: @"Python Bytecode Document"]) {
+        curdefault = &default_pyc;
+    } else {
+        NSLog(@"Funny File Type: %@\n", filetype);
+        curdefault = &default_py;
+        filetype = @"Python Script";
+    }
+    if (!*curdefault) {
+        *curdefault = [[FileSettings new] initForDefaultFileType: filetype];
+    }
+    return *curdefault;
+}
+
++ (id)newSettingsForFileType: (NSString *)filetype
+{
+    FileSettings *cur;
+    
+    cur = [FileSettings new];
+    [cur initForFileType: filetype];
+    return [cur retain];
+}
+
+- (id)initWithFileSettings: (FileSettings *)source
+{
+    self = [super init];
+    if (!self) return self;
+    
+    interpreter = [source->interpreter retain];
+    honourhashbang = source->honourhashbang;
+    debug = source->debug;
+    verbose = source->verbose;
+    inspect = source->inspect;
+    optimize = source->optimize;
+    nosite = source->nosite;
+    tabs = source->tabs;
+    others = [source->others retain];
+    scriptargs = [source->scriptargs retain];
+    with_terminal = source->with_terminal;
+    prefskey = source->prefskey;
+    if (prefskey) [prefskey retain];
+    
+    return self;
+}
+
+- (id)initForFileType: (NSString *)filetype
+{
+    FileSettings *defaults;
+    
+    defaults = [FileSettings getDefaultsForFileType: filetype];
+    self = [self initWithFileSettings: defaults];
+    origsource = [defaults retain];
+    return self;
+}
+
+//- (id)init
+//{
+//    self = [self initForFileType: @"Python Script"];
+//    return self;
+//}
+
+- (id)initForFSDefaultFileType: (NSString *)filetype
+{
+    int i;
+    NSString *filename;
+    NSDictionary *dict;
+    static NSDictionary *factorySettings;
+    
+    self = [super init];
+    if (!self) return self;
+    
+    if (factorySettings == NULL) {
+        NSBundle *bdl = [NSBundle mainBundle];
+        NSString *path = [ bdl pathForResource: @"factorySettings"
+                ofType: @"plist"];
+        factorySettings = [[NSDictionary dictionaryWithContentsOfFile:
+            path] retain];
+        if (factorySettings == NULL) {
+            NSLog(@"Missing %@", path);
+            return NULL;
+        }
+    }
+    dict = [factorySettings objectForKey: filetype];
+    if (dict == NULL) {
+        NSLog(@"factorySettings.plist misses file type \"%@\"", filetype);
+        interpreter = [@"no default found" retain];
+        return NULL;
+    }
+    [self applyValuesFromDict: dict];
+    interpreters = [dict objectForKey: @"interpreter_list"];
+    interpreter = NULL;
+    for (i=0; i < [interpreters count]; i++) {
+        filename = [interpreters objectAtIndex: i];
+        filename = [filename stringByExpandingTildeInPath];
+        if ([[NSFileManager defaultManager] fileExistsAtPath: filename]) {
+            interpreter = [filename retain];
+            break;
+        }
+    }
+    if (interpreter == NULL)
+        interpreter = [@"no default found" retain];
+    origsource = NULL;
+    return self;
+}
+
+- (void)applyUserDefaults: (NSString *)filetype
+{
+    NSUserDefaults *defaults;
+    NSDictionary *dict;
+    
+    defaults = [NSUserDefaults standardUserDefaults];
+    dict = [defaults dictionaryForKey: filetype];
+    if (!dict)
+        return;
+    [self applyValuesFromDict: dict];
+}
+    
+- (id)initForDefaultFileType: (NSString *)filetype
+{
+    FileSettings *fsdefaults;
+    
+    fsdefaults = [FileSettings getFactorySettingsForFileType: filetype];
+    self = [self initWithFileSettings: fsdefaults];
+    if (!self) return self;
+    interpreters = [fsdefaults->interpreters retain];
+    scriptargs = [@"" retain];
+    [self applyUserDefaults: filetype];
+    prefskey = [filetype retain];
+    return self;
+}
+
+- (void)reset
+{
+    if (origsource) {
+        [self updateFromSource: origsource];
+    } else {
+        FileSettings *fsdefaults;
+        fsdefaults = [FileSettings getFactorySettingsForFileType: prefskey];
+        [self updateFromSource: fsdefaults];
+    }
+}
+
+- (void)updateFromSource: (id <FileSettingsSource>)source
+{
+    interpreter = [[source interpreter] retain];
+    honourhashbang = [source honourhashbang];
+    debug = [source debug];
+    verbose = [source verbose];
+    inspect = [source inspect];
+    optimize = [source optimize];
+    nosite = [source nosite];
+    tabs = [source tabs];
+    others = [[source others] retain];
+    scriptargs = [[source scriptargs] retain];
+    with_terminal = [source with_terminal];
+    // And if this is a user defaults object we also save the
+    // values
+    if (!origsource) {
+        NSUserDefaults *defaults;
+        NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
+            interpreter, @"interpreter",
+            [NSNumber numberWithBool: honourhashbang], @"honourhashbang",
+            [NSNumber numberWithBool: debug], @"debug",
+            [NSNumber numberWithBool: verbose], @"verbose",
+            [NSNumber numberWithBool: inspect], @"inspect",
+            [NSNumber numberWithBool: optimize], @"optimize",
+            [NSNumber numberWithBool: nosite], @"nosite",
+            [NSNumber numberWithBool: tabs], @"tabs",
+            others, @"others",
+            scriptargs, @"scriptargs",
+            [NSNumber numberWithBool: with_terminal], @"with_terminal",
+            nil];
+        defaults = [NSUserDefaults standardUserDefaults];
+        [defaults setObject: dict forKey: prefskey];
+    }
+}
+
+- (void)applyValuesFromDict: (NSDictionary *)dict
+{
+    id value;
+    
+    value = [dict objectForKey: @"interpreter"];
+    if (value) interpreter = [value retain];
+    value = [dict objectForKey: @"honourhashbang"];
+    if (value) honourhashbang = [value boolValue];
+    value = [dict objectForKey: @"debug"];
+    if (value) debug = [value boolValue];
+    value = [dict objectForKey: @"verbose"];
+    if (value) verbose = [value boolValue];
+    value = [dict objectForKey: @"inspect"];
+    if (value) inspect = [value boolValue];
+    value = [dict objectForKey: @"optimize"];
+    if (value) optimize = [value boolValue];
+    value = [dict objectForKey: @"nosite"];
+    if (value) nosite = [value boolValue];
+    value = [dict objectForKey: @"tabs"];
+    if (value) tabs = [value boolValue];
+    value = [dict objectForKey: @"others"];
+    if (value) others = [value retain];
+    value = [dict objectForKey: @"scriptargs"];
+    if (value) scriptargs = [value retain];
+    value = [dict objectForKey: @"with_terminal"];
+    if (value) with_terminal = [value boolValue];
+}
+
+- (NSString*)_replaceSingleQuotes: (NSString*)string
+{
+	/* Replace all single-quotes by '"'"', that way shellquoting will
+	 * be correct when the result value is delimited  using single quotes.
+	 */
+	NSArray* components = [string componentsSeparatedByString:@"'"];
+
+	return [components componentsJoinedByString:@"'\"'\"'"];
+}
+
+- (NSString *)commandLineForScript: (NSString *)script
+{
+    NSString *cur_interp = NULL;
+    NSString* script_dir = NULL;
+    char hashbangbuf[1024];
+    FILE *fp;
+    char *p;
+
+    script_dir = [script substringToIndex:
+	    [script length]-[[script lastPathComponent] length]];
+    
+    if (honourhashbang &&
+       (fp=fopen([script cString], "r")) &&
+       fgets(hashbangbuf, sizeof(hashbangbuf), fp) &&
+       strncmp(hashbangbuf, "#!", 2) == 0 &&
+       (p=strchr(hashbangbuf, '\n'))) {
+            *p = '\0';
+            p = hashbangbuf + 2;
+            while (*p == ' ') p++;
+            cur_interp = [NSString stringWithCString: p];
+    }
+    if (!cur_interp)
+        cur_interp = interpreter;
+        
+    return [NSString stringWithFormat:
+        @"cd '%@' && '%@'%s%s%s%s%s%s %@ '%@' %@ %s",
+    	[self _replaceSingleQuotes:script_dir],
+        [self _replaceSingleQuotes:cur_interp],
+        debug?" -d":"",
+        verbose?" -v":"",
+        inspect?" -i":"",
+        optimize?" -O":"",
+        nosite?" -S":"",
+        tabs?" -t":"",
+        others,
+        [self _replaceSingleQuotes:script],
+        scriptargs ? scriptargs : @"",
+        with_terminal? "&& echo Exit status: $? && exit 1" : " &"];
+}
+
+- (NSArray *) interpreters { return interpreters;};
+
+// FileSettingsSource protocol 
+- (NSString *) interpreter { return interpreter;};
+- (BOOL) honourhashbang { return honourhashbang; };
+- (BOOL) debug { return debug;};
+- (BOOL) verbose { return verbose;};
+- (BOOL) inspect { return inspect;};
+- (BOOL) optimize { return optimize;};
+- (BOOL) nosite { return nosite;};
+- (BOOL) tabs { return tabs;};
+- (NSString *) others { return others;};
+- (NSString *) scriptargs { return scriptargs;};
+- (BOOL) with_terminal { return with_terminal;};
+
+ at end


Property changes on: vendor/Python/current/Mac/PythonLauncher/FileSettings.m
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Mac/PythonLauncher/Info.plist.in
===================================================================
--- vendor/Python/current/Mac/PythonLauncher/Info.plist.in	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/PythonLauncher/Info.plist.in	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleDocumentTypes</key>
+	<array>
+		<dict>
+			<key>CFBundleTypeExtensions</key>
+			<array>
+				<string>py</string>
+				<string>pyw</string>
+			</array>
+			<key>CFBundleTypeIconFile</key>
+			<string>PythonSource.icns</string>
+			<key>CFBundleTypeName</key>
+			<string>Python Script</string>
+			<key>CFBundleTypeRole</key>
+			<string>Viewer</string>
+			<key>NSDocumentClass</key>
+			<string>MyDocument</string>
+		</dict>
+		<dict>
+			<key>CFBundleTypeExtensions</key>
+			<array>
+				<string>pyc</string>
+				<string>pyo</string>
+			</array>
+			<key>CFBundleTypeIconFile</key>
+			<string>PythonCompiled.icns</string>
+			<key>CFBundleTypeName</key>
+			<string>Python Bytecode Document</string>
+			<key>CFBundleTypeRole</key>
+			<string>Viewer</string>
+			<key>NSDocumentClass</key>
+			<string>MyDocument</string>
+		</dict>
+	</array>
+	<key>CFBundleExecutable</key>
+	<string>PythonLauncher</string>
+	<key>CFBundleGetInfoString</key>
+	<string>%VERSION%, © 001-2006 Python Software Foundation</string>
+	<key>CFBundleIconFile</key>
+	<string>PythonLauncher.icns</string>
+	<key>CFBundleIdentifier</key>
+	<string>org.python.PythonLauncher</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>Python Launcher</string>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>%VERSION%</string>
+	<key>CFBundleSignature</key>
+	<string>PytL</string>
+	<key>CFBundleVersion</key>
+	<string>%VERSION%</string>
+	<key>NSMainNibFile</key>
+	<string>MainMenu</string>
+	<key>NSPrincipalClass</key>
+	<string>NSApplication</string>
+</dict>
+</plist>

Added: vendor/Python/current/Mac/PythonLauncher/MyAppDelegate.h
===================================================================
--- vendor/Python/current/Mac/PythonLauncher/MyAppDelegate.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/PythonLauncher/MyAppDelegate.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,15 @@
+/* MyAppDelegate */
+
+#import <Cocoa/Cocoa.h>
+
+ at interface MyAppDelegate : NSObject
+{
+    BOOL	initial_action_done;
+    BOOL	should_terminate;
+}
+- (id)init;
+- (IBAction)showPreferences:(id)sender;
+- (BOOL)shouldShowUI;
+- (BOOL)shouldTerminate;
+- (void)testFileTypeBinding;
+ at end

Added: vendor/Python/current/Mac/PythonLauncher/MyAppDelegate.m
===================================================================
--- vendor/Python/current/Mac/PythonLauncher/MyAppDelegate.m	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/PythonLauncher/MyAppDelegate.m	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,96 @@
+#import "MyAppDelegate.h"
+#import "PreferencesWindowController.h"
+#import <Carbon/Carbon.h>
+#import <ApplicationServices/ApplicationServices.h>
+
+ at implementation MyAppDelegate
+
+- (id)init
+{
+    self = [super init];
+    initial_action_done = NO;
+    should_terminate = NO;
+    return self;
+}
+
+- (IBAction)showPreferences:(id)sender
+{
+    [PreferencesWindowController getPreferencesWindow];
+}
+
+- (void)applicationDidFinishLaunching:(NSNotification *)notification
+{
+    // Test that the file mappings are correct
+    [self testFileTypeBinding];
+    // If we were opened because of a file drag or doubleclick
+    // we've set initial_action_done in shouldShowUI
+    // Otherwise we open a preferences dialog.
+    if (!initial_action_done) {
+        initial_action_done = YES;
+        [self showPreferences: self];
+    }
+}
+
+- (BOOL)shouldShowUI
+{
+    // if this call comes before applicationDidFinishLaunching: we 
+    // should terminate immedeately after starting the script.
+    if (!initial_action_done)
+        should_terminate = YES;
+    initial_action_done = YES;
+    if( GetCurrentKeyModifiers() & optionKey )
+        return YES;
+    return NO;
+}
+
+- (BOOL)shouldTerminate
+{
+    return should_terminate;
+}
+
+- (BOOL)applicationShouldOpenUntitledFile:(NSApplication *)sender
+{
+    return NO;
+}
+
+- (void)testFileTypeBinding
+{
+    NSURL *ourUrl;
+    OSStatus err;
+    FSRef appRef;
+    NSURL *appUrl;
+    static NSString *extensions[] = { @"py", @"pyw", @"pyc", NULL};
+    NSString **ext_p;
+    int i;
+    
+    if ([[NSUserDefaults standardUserDefaults] boolForKey: @"SkipFileBindingTest"])
+        return;
+    ourUrl = [NSURL fileURLWithPath: [[NSBundle mainBundle] bundlePath]];
+    for( ext_p = extensions; *ext_p; ext_p++ ) {
+        err = LSGetApplicationForInfo(
+            kLSUnknownType,
+            kLSUnknownCreator,
+            (CFStringRef)*ext_p,
+            kLSRolesViewer,
+            &appRef,
+            (CFURLRef *)&appUrl);
+        if (err || ![appUrl isEqual: ourUrl] ) {
+            i = NSRunAlertPanel(@"File type binding",
+                @"PythonLauncher is not the default application for all " \
+                  @"Python script types. You should fix this with the " \
+                  @"Finder's \"Get Info\" command.\n\n" \
+                  @"See \"Changing the application that opens a file\" in " \
+                  @"Mac Help for details.",
+                @"OK",
+                @"Don't show this warning again",
+                NULL);
+            if ( i == 0 ) { // Don't show again
+                [[NSUserDefaults standardUserDefaults]
+                    setObject:@"YES" forKey:@"SkipFileBindingTest"];
+            }
+            return;
+        }
+    }
+}
+        
+ at end

Added: vendor/Python/current/Mac/PythonLauncher/MyDocument.h
===================================================================
--- vendor/Python/current/Mac/PythonLauncher/MyDocument.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/PythonLauncher/MyDocument.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,41 @@
+//
+//  MyDocument.h
+//  PythonLauncher
+//
+//  Created by Jack Jansen on Fri Jul 19 2002.
+//  Copyright (c) 2002 __MyCompanyName__. All rights reserved.
+//
+
+
+#import <Cocoa/Cocoa.h>
+
+#import "FileSettings.h"
+
+ at interface MyDocument : NSDocument <FileSettingsSource>
+{
+    IBOutlet NSTextField *interpreter;
+    IBOutlet NSButton *honourhashbang;
+    IBOutlet NSButton *debug;
+    IBOutlet NSButton *verbose;
+    IBOutlet NSButton *inspect;
+    IBOutlet NSButton *optimize;
+    IBOutlet NSButton *nosite;
+    IBOutlet NSButton *tabs;
+    IBOutlet NSTextField *others;
+    IBOutlet NSButton *with_terminal;
+    IBOutlet NSTextField *scriptargs;
+    IBOutlet NSTextField *commandline;
+
+    NSString *script;
+    NSString *filetype;
+    FileSettings *settings;
+}
+
+- (IBAction)do_run:(id)sender;
+- (IBAction)do_cancel:(id)sender;
+- (IBAction)do_reset:(id)sender;
+- (IBAction)do_apply:(id)sender;
+
+- (void)controlTextDidChange:(NSNotification *)aNotification;
+
+ at end


Property changes on: vendor/Python/current/Mac/PythonLauncher/MyDocument.h
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Mac/PythonLauncher/MyDocument.m
===================================================================
--- vendor/Python/current/Mac/PythonLauncher/MyDocument.m	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/PythonLauncher/MyDocument.m	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,175 @@
+//
+//  MyDocument.m
+//  PythonLauncher
+//
+//  Created by Jack Jansen on Fri Jul 19 2002.
+//  Copyright (c) 2002 __MyCompanyName__. All rights reserved.
+//
+
+#import "MyDocument.h"
+#import "MyAppDelegate.h"
+#import "doscript.h"
+
+ at implementation MyDocument
+
+- (id)init
+{
+    self = [super init];
+    if (self) {
+    
+        // Add your subclass-specific initialization here.
+        // If an error occurs here, send a [self dealloc] message and return nil.
+        script = [@"<no script>.py" retain];
+        filetype = [@"Python Script" retain];
+        settings = NULL;
+    }
+    return self;
+}
+
+- (NSString *)windowNibName
+{
+    // Override returning the nib file name of the document
+    // If you need to use a subclass of NSWindowController or if your document supports multiple NSWindowControllers, you should remove this method and override -makeWindowControllers instead.
+    return @"MyDocument";
+}
+
+- (void)close
+{
+    NSApplication *app = [NSApplication sharedApplication];
+    [super close];
+    if ([[app delegate] shouldTerminate])
+        [app terminate: self];
+}
+
+- (void)load_defaults
+{
+//    if (settings) [settings release];
+    settings = [FileSettings newSettingsForFileType: filetype];
+}
+
+- (void)update_display
+{
+//    [[self window] setTitle: script];
+    
+    [interpreter setStringValue: [settings interpreter]];
+    [honourhashbang setState: [settings honourhashbang]];
+    [debug setState: [settings debug]];
+    [verbose setState: [settings verbose]];
+    [inspect setState: [settings inspect]];
+    [optimize setState: [settings optimize]];
+    [nosite setState: [settings nosite]];
+    [tabs setState: [settings tabs]];
+    [others setStringValue: [settings others]];
+    [scriptargs setStringValue: [settings scriptargs]];
+    [with_terminal setState: [settings with_terminal]];
+    
+    [commandline setStringValue: [settings commandLineForScript: script]];
+}
+
+- (void)update_settings
+{
+    [settings updateFromSource: self];
+}
+
+- (BOOL)run
+{
+    const char *cmdline;
+    int sts;
+    
+     cmdline = [[settings commandLineForScript: script] cString];
+   if ([settings with_terminal]) {
+        sts = doscript(cmdline);
+    } else {
+        sts = system(cmdline);
+    }
+    if (sts) {
+        NSLog(@"Exit status: %d\n", sts);
+        return NO;
+    }
+    return YES;
+}
+
+- (void)windowControllerDidLoadNib:(NSWindowController *) aController
+{
+    [super windowControllerDidLoadNib:aController];
+    // Add any code here that need to be executed once the windowController has loaded the document's window.
+    [self load_defaults];
+    [self update_display];
+}
+
+- (NSData *)dataRepresentationOfType:(NSString *)aType
+{
+    // Insert code here to write your document from the given data.  You can also choose to override -fileWrapperRepresentationOfType: or -writeToFile:ofType: instead.
+    return nil;
+}
+
+- (BOOL)readFromFile:(NSString *)fileName ofType:(NSString *)type;
+{
+    // Insert code here to read your document from the given data.  You can also choose to override -loadFileWrapperRepresentation:ofType: or -readFromFile:ofType: instead.
+    BOOL show_ui;
+    
+    // ask the app delegate whether we should show the UI or not. 
+    show_ui = [[[NSApplication sharedApplication] delegate] shouldShowUI];
+    [script release];
+    script = [fileName retain];
+    [filetype release];
+    filetype = [type retain];
+//    if (settings) [settings release];
+    settings = [FileSettings newSettingsForFileType: filetype];
+    if (show_ui) {
+        [self update_display];
+        return YES;
+    } else {
+        [self run];
+        [self close];
+        return NO;
+    }
+}
+
+- (IBAction)do_run:(id)sender
+{
+    [self update_settings];
+    [self update_display];
+    if ([self run])
+        [self close];
+}
+
+- (IBAction)do_cancel:(id)sender
+{
+    [self close];
+}
+
+
+- (IBAction)do_reset:(id)sender
+{
+    [settings reset];
+    [self update_display];
+}
+
+- (IBAction)do_apply:(id)sender
+{
+    [self update_settings];
+    [self update_display];
+}
+
+// FileSettingsSource protocol 
+- (NSString *) interpreter { return [interpreter stringValue];};
+- (BOOL) honourhashbang { return [honourhashbang state];};
+- (BOOL) debug { return [debug state];};
+- (BOOL) verbose { return [verbose state];};
+- (BOOL) inspect { return [inspect state];};
+- (BOOL) optimize { return [optimize state];};
+- (BOOL) nosite { return [nosite state];};
+- (BOOL) tabs { return [tabs state];};
+- (NSString *) others { return [others stringValue];};
+- (NSString *) scriptargs { return [scriptargs stringValue];};
+- (BOOL) with_terminal { return [with_terminal state];};
+
+// Delegates
+- (void)controlTextDidChange:(NSNotification *)aNotification
+{
+    [self update_settings];
+    [self update_display];
+};
+
+ at end


Property changes on: vendor/Python/current/Mac/PythonLauncher/MyDocument.m
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Mac/PythonLauncher/PreferencesWindowController.h
===================================================================
--- vendor/Python/current/Mac/PythonLauncher/PreferencesWindowController.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/PythonLauncher/PreferencesWindowController.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,38 @@
+/* PreferencesWindowController */
+
+#import <Cocoa/Cocoa.h>
+
+#import "FileSettings.h"
+
+ at interface PreferencesWindowController : NSWindowController <FileSettingsSource>
+{
+    IBOutlet NSPopUpButton *filetype;
+    IBOutlet NSComboBox *interpreter;
+    IBOutlet NSButton *honourhashbang;
+    IBOutlet NSButton *debug;
+    IBOutlet NSButton *verbose;
+    IBOutlet NSButton *inspect;
+    IBOutlet NSButton *optimize;
+    IBOutlet NSButton *nosite;
+    IBOutlet NSButton *tabs;
+    IBOutlet NSTextField *others;
+    IBOutlet NSButton *with_terminal;
+    IBOutlet NSTextField *commandline;
+
+    FileSettings *settings;
+}
+
++ getPreferencesWindow;
+
+- (IBAction)do_reset:(id)sender;
+- (IBAction)do_apply:(id)sender;
+- (IBAction)do_filetype:(id)sender;
+
+- (void)controlTextDidChange:(NSNotification *)aNotification;
+
+- (unsigned int)comboBox:(NSComboBox *)aComboBox indexOfItemWithStringValue:(NSString *)aString;
+- (id)comboBox:(NSComboBox *)aComboBox objectValueForItemAtIndex:(int)index;
+- (int)numberOfItemsInComboBox:(NSComboBox *)aComboBox;
+
+
+ at end

Added: vendor/Python/current/Mac/PythonLauncher/PreferencesWindowController.m
===================================================================
--- vendor/Python/current/Mac/PythonLauncher/PreferencesWindowController.m	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/PythonLauncher/PreferencesWindowController.m	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,121 @@
+#import "PreferencesWindowController.h"
+
+ at implementation PreferencesWindowController
+
++ getPreferencesWindow
+{
+    static PreferencesWindowController *_singleton;
+    
+    if (!_singleton)
+        _singleton = [[PreferencesWindowController alloc] init];
+    [_singleton showWindow: _singleton];
+    return _singleton;
+}
+
+- (id) init
+{
+    self = [self initWithWindowNibName: @"PreferenceWindow"];
+    return self;
+}
+
+- (void)load_defaults
+{
+    NSString *title = [filetype titleOfSelectedItem];
+    
+    settings = [FileSettings getDefaultsForFileType: title];
+}
+
+- (void)update_display
+{
+//    [[self window] setTitle: script];
+    
+	[interpreter reloadData];
+    [interpreter setStringValue: [settings interpreter]];
+    [honourhashbang setState: [settings honourhashbang]];
+    [debug setState: [settings debug]];
+    [verbose setState: [settings verbose]];
+    [inspect setState: [settings inspect]];
+    [optimize setState: [settings optimize]];
+    [nosite setState: [settings nosite]];
+    [tabs setState: [settings tabs]];
+    [others setStringValue: [settings others]];
+    [with_terminal setState: [settings with_terminal]];
+    // Not scriptargs, it isn't for preferences
+    
+    [commandline setStringValue: [settings commandLineForScript: @"<your script here>"]];
+}
+
+- (void) windowDidLoad
+{
+    [super windowDidLoad];
+    [self load_defaults];
+    [self update_display];
+}
+
+- (void)update_settings
+{
+    [settings updateFromSource: self];
+}
+
+- (IBAction)do_filetype:(id)sender
+{
+    [self load_defaults];
+    [self update_display];
+}
+
+- (IBAction)do_reset:(id)sender
+{
+    [settings reset];
+    [self update_display];
+}
+
+- (IBAction)do_apply:(id)sender
+{
+    [self update_settings];
+    [self update_display];
+}
+
+// FileSettingsSource protocol 
+- (NSString *) interpreter { return [interpreter stringValue];};
+- (BOOL) honourhashbang { return [honourhashbang state]; };
+- (BOOL) debug { return [debug state];};
+- (BOOL) verbose { return [verbose state];};
+- (BOOL) inspect { return [inspect state];};
+- (BOOL) optimize { return [optimize state];};
+- (BOOL) nosite { return [nosite state];};
+- (BOOL) tabs { return [tabs state];};
+- (NSString *) others { return [others stringValue];};
+- (BOOL) with_terminal { return [with_terminal state];};
+- (NSString *) scriptargs { return @"";};
+
+// Delegates
+- (void)controlTextDidChange:(NSNotification *)aNotification
+{
+    [self update_settings];
+    [self update_display];
+};
+
+// NSComboBoxDataSource protocol
+- (unsigned int)comboBox:(NSComboBox *)aComboBox indexOfItemWithStringValue:(NSString *)aString
+{
+	NSArray *interp_list = [settings interpreters];
+    unsigned int rv = [interp_list indexOfObjectIdenticalTo: aString];
+	return rv;
+}
+
+- (id)comboBox:(NSComboBox *)aComboBox objectValueForItemAtIndex:(int)index
+{
+	NSArray *interp_list = [settings interpreters];
+    id rv = [interp_list objectAtIndex: index];
+	return rv;
+}
+
+- (int)numberOfItemsInComboBox:(NSComboBox *)aComboBox
+{
+	NSArray *interp_list = [settings interpreters];
+    int rv = [interp_list count];
+	return rv;
+}
+
+
+ at end

Added: vendor/Python/current/Mac/PythonLauncher/doscript.h
===================================================================
--- vendor/Python/current/Mac/PythonLauncher/doscript.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/PythonLauncher/doscript.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,12 @@
+/*
+ *  doscript.h
+ *  PythonLauncher
+ *
+ *  Created by Jack Jansen on Wed Jul 31 2002.
+ *  Copyright (c) 2002 __MyCompanyName__. All rights reserved.
+ *
+ */
+
+#include <Carbon/Carbon.h>
+
+extern int doscript(const char *command);
\ No newline at end of file

Added: vendor/Python/current/Mac/PythonLauncher/doscript.m
===================================================================
--- vendor/Python/current/Mac/PythonLauncher/doscript.m	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/PythonLauncher/doscript.m	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,118 @@
+/*
+ *  doscript.c
+ *  PythonLauncher
+ *
+ *  Created by Jack Jansen on Wed Jul 31 2002.
+ *  Copyright (c) 2002 __MyCompanyName__. All rights reserved.
+ *
+ */
+
+#import <Cocoa/Cocoa.h>
+#import <ApplicationServices/ApplicationServices.h>
+#import "doscript.h"
+
+/* I assume I could pick these up from somewhere, but where... */
+#define CREATOR 'trmx'
+
+#define ACTIVATE_CMD 'misc'
+#define ACTIVATE_SUITE 'actv'
+
+#define DOSCRIPT_CMD 'dosc'
+#define DOSCRIPT_SUITE 'core'
+#define WITHCOMMAND 'cmnd'
+
+/* ... and there's probably also a better way to do this... */
+#define START_TERMINAL "/Applications/Utilities/Terminal.app/Contents/MacOS/Terminal &"
+
+extern int 
+doscript(const char *command)
+{
+    OSErr err;
+    AppleEvent theAEvent, theReply;
+    AEAddressDesc terminalAddress;
+    AEDesc commandDesc;
+    OSType terminalCreator = CREATOR;
+    
+    /* set up locals  */
+    AECreateDesc(typeNull, NULL, 0, &theAEvent);
+    AECreateDesc(typeNull, NULL, 0, &terminalAddress);
+    AECreateDesc(typeNull, NULL, 0, &theReply);
+    AECreateDesc(typeNull, NULL, 0, &commandDesc);
+    
+    /* create the "activate" event for Terminal */
+    err = AECreateDesc(typeApplSignature, (Ptr) &terminalCreator,
+            sizeof(terminalCreator), &terminalAddress);
+    if (err != noErr) {
+        NSLog(@"doscript: AECreateDesc: error %d\n", err);
+        goto bail;
+    }
+    err = AECreateAppleEvent(ACTIVATE_SUITE, ACTIVATE_CMD,
+            &terminalAddress, kAutoGenerateReturnID,
+            kAnyTransactionID, &theAEvent);
+    
+    if (err != noErr) {
+        NSLog(@"doscript: AECreateAppleEvent(activate): error %d\n", err);
+        goto bail;
+    }
+    /* send the event  */
+    err = AESend(&theAEvent, &theReply, kAEWaitReply,
+            kAENormalPriority, kAEDefaultTimeout, NULL, NULL);
+    if ( err == -600 ) {
+        int count=10;
+        /* If it failed with "no such process" try to start Terminal */
+        err = system(START_TERMINAL);
+        if ( err ) {
+            NSLog(@"doscript: system(): %s\n", strerror(errno));
+            goto bail;
+        }
+        do {
+            sleep(1);
+            /* send the event again */
+            err = AESend(&theAEvent, &theReply, kAEWaitReply,
+                    kAENormalPriority, kAEDefaultTimeout, NULL, NULL);
+        } while (err == -600 && --count > 0);
+        if ( err == -600 )
+            NSLog(@"doscript: Could not activate Terminal\n");
+    }
+    if (err != noErr) {
+        NSLog(@"doscript: AESend(activate): error %d\n", err);
+        goto bail;
+    }
+            
+    /* create the "doscript with command" event for Terminal */
+    err = AECreateAppleEvent(DOSCRIPT_SUITE, DOSCRIPT_CMD,
+            &terminalAddress, kAutoGenerateReturnID,
+            kAnyTransactionID, &theAEvent);
+    if (err != noErr) {
+        NSLog(@"doscript: AECreateAppleEvent(doscript): error %d\n", err);
+        goto bail;
+    }
+    
+    /* add the command to the apple event */
+    err = AECreateDesc(typeChar, command, strlen(command), &commandDesc);
+    if (err != noErr) {
+        NSLog(@"doscript: AECreateDesc(command): error %d\n", err);
+        goto bail;
+    }
+    err = AEPutParamDesc(&theAEvent, WITHCOMMAND, &commandDesc);
+    if (err != noErr) {
+        NSLog(@"doscript: AEPutParamDesc: error %d\n", err);
+        goto bail;
+    }
+
+    /* send the command event to Terminal.app */
+    err = AESend(&theAEvent, &theReply, kAEWaitReply,
+            kAENormalPriority, kAEDefaultTimeout, NULL, NULL);
+    
+    if (err != noErr) {
+        NSLog(@"doscript: AESend(docommand): error %d\n", err);
+        goto bail;
+    }
+    /* clean up and leave */
+bail:
+    AEDisposeDesc(&commandDesc);
+    AEDisposeDesc(&theAEvent);
+    AEDisposeDesc(&terminalAddress);
+    AEDisposeDesc(&theReply);
+    return err;
+}

Added: vendor/Python/current/Mac/PythonLauncher/factorySettings.plist
===================================================================
--- vendor/Python/current/Mac/PythonLauncher/factorySettings.plist	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/PythonLauncher/factorySettings.plist	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+        <key>Python GUI Script</key>
+        <dict>
+                <key>debug</key>
+                <false/>
+                <key>inspect</key>
+                <false/>
+                <key>interpreter_list</key>
+                <array>
+                    <string>/usr/local/bin/pythonw</string>
+                    <string>/usr/bin/pythonw</string>
+                    <string>/sw/bin/pythonw</string>
+                </array>
+                <key>honourhashbang</key>
+                <false/>
+                <key>nosite</key>
+                <false/>
+                <key>optimize</key>
+                <false/>
+                <key>others</key>
+                <string></string>
+                <key>verbose</key>
+                <false/>
+                <key>with_terminal</key>
+                <false/>
+        </dict>
+        <key>Python Script</key>
+        <dict>
+                <key>debug</key>
+                <false/>
+                <key>inspect</key>
+                <false/>
+                <key>interpreter_list</key>
+                <array>
+                    <string>/usr/local/bin/pythonw</string>
+                    <string>/usr/local/bin/python</string>
+                    <string>/usr/bin/pythonw</string>
+                    <string>/usr/bin/python</string>
+                    <string>/sw/bin/pythonw</string>
+                    <string>/sw/bin/python</string>
+                </array>
+                <key>honourhashbang</key>
+                <false/>
+                <key>nosite</key>
+                <false/>
+                <key>optimize</key>
+                <false/>
+                <key>others</key>
+                <string></string>
+                <key>verbose</key>
+                <false/>
+                <key>with_terminal</key>
+                <true/>
+        </dict>
+        <key>Python Bytecode Document</key>
+        <dict>
+                <key>debug</key>
+                <false/>
+                <key>inspect</key>
+                <false/>
+                <key>interpreter_list</key>
+                <array>
+                    <string>/usr/local/bin/pythonw</string>
+                    <string>/usr/local/bin/python</string>
+                    <string>/usr/bin/pythonw</string>
+                    <string>/usr/bin/python</string>
+                    <string>/sw/bin/pythonw</string>
+                    <string>/sw/bin/python</string>
+                </array>
+                <key>honourhashbang</key>
+                <false/>
+                 <key>nosite</key>
+                <false/>
+                <key>optimize</key>
+                <false/>
+                <key>others</key>
+                <string></string>
+                <key>verbose</key>
+                <false/>
+                <key>with_terminal</key>
+                <true/>
+        </dict>
+</dict>
+</plist>

Added: vendor/Python/current/Mac/PythonLauncher/main.m
===================================================================
--- vendor/Python/current/Mac/PythonLauncher/main.m	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/PythonLauncher/main.m	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,17 @@
+//
+//  main.m
+//  PythonLauncher
+//
+//  Created by Jack Jansen on Fri Jul 19 2002.
+//  Copyright (c) 2002 __MyCompanyName__. All rights reserved.
+//
+
+#import <Cocoa/Cocoa.h>
+#include <unistd.h>
+
+int main(int argc, const char *argv[])
+{
+	char *home = getenv("HOME");
+	if (home) chdir(home);
+    return NSApplicationMain(argc, argv);
+}


Property changes on: vendor/Python/current/Mac/PythonLauncher/main.m
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Mac/README
===================================================================
--- vendor/Python/current/Mac/README	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/README	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,163 @@
+============
+MacOSX Notes
+============
+
+This document provides a quick overview of some Mac OS X specific features in
+the Python distribution.
+
+
+Building and using a universal binary of Python on Mac OS X
+===========================================================
+
+1. What is a universal binary
+-----------------------------
+
+A universal binary build of Python contains object code for both PPC and i386
+and can therefore run at native speed on both classic powerpc based macs and
+the newer intel based macs.
+
+2. How do I build a universal binary
+------------------------------------
+
+You can enable universal binaries by specifying the "--enable-universalsdk"
+flag to configure::
+
+  $ ./configure --enable-universalsdk
+  $ make
+  $ make install
+
+This flag can be used a framework build of python, but also with a classic
+unix build. Either way you will have to build python on Mac OS X 10.4 (or later)
+with Xcode 2.1 (or later). You also have to install the 10.4u SDK when 
+installing Xcode.
+
+
+Building and using a framework-based Python on Mac OS X.
+========================================================
+
+
+1. Why would I want a framework Python instead of a normal static Python?
+--------------------------------------------------------------------------
+
+The main reason is because you want to create GUI programs in Python. With the
+exception of X11/XDarwin-based GUI toolkits all GUI programs need to be run 
+from a fullblown MacOSX application (a ".app" bundle).
+
+While it is technically possible to create a .app without using frameworks you
+will have to do the work yourself if you really want this.
+
+A second reason for using frameworks is that they put Python-related items in
+only two places: "/Library/Framework/Python.framework" and 
+"/Applications/MacPython 2.5".  This simplifies matters for users installing 
+Python from a binary distribution if they want to get rid of it again. Moreover,
+due to the way frameworks work a user without admin privileges can install a 
+binary distribution in his or her home directory without recompilation.
+
+2. How does a framework Python differ from a normal static Python?
+------------------------------------------------------------------
+
+In everyday use there is no difference, except that things are stored in
+a different place. If you look in /Library/Frameworks/Python.framework
+you will see lots of relative symlinks, see the Apple documentation for
+details. If you are used to a normal unix Python file layout go down to
+Versions/Current and you will see the familiar bin and lib directories.
+
+3. Do I need extra packages?
+----------------------------
+
+Yes, probably.  If you want Tkinter support you need to get the OSX AquaTk 
+distribution, this is installed by default on Mac OS X 10.4 or later. If
+you want wxPython you need to get that. If you want Cocoa you need to get
+PyObjC. 
+
+4. How do I build a framework Python?
+-------------------------------------
+
+This directory contains a Makefile that will create a couple of python-related
+applications (fullblown OSX .app applications, that is) in
+"/Applications/MacPython 2.5", and a hidden helper application Python.app 
+inside the Python.framework, and unix tools "python" and "pythonw" into 
+/usr/local/bin.  In addition it has a target "installmacsubtree" that installs 
+the relevant portions of the Mac subtree into the Python.framework.
+
+It is normally invoked indirectly through the main Makefile, as the last step
+in the sequence
+
+ 1. ./configure --enable-framework
+
+ 2. make
+ 
+ 3. make install
+
+This sequence will put the framework in /Library/Framework/Python.framework,
+the applications in "/Applications/MacPython 2.5" and the unix tools in 
+/usr/local/bin.
+
+Installing in another place, for instance $HOME/Library/Frameworks if you have
+no admin privileges on your machine, has only been tested very lightly. This
+can be done by configuring with --enable-framework=$HOME/Library/Frameworks.
+The other two directories, "/Applications/MacPython 2.5" and /usr/local/bin, 
+will then also be deposited in $HOME. This is sub-optimal for the unix tools, 
+which you would want in $HOME/bin, but there is no easy way to fix this right 
+now.
+
+If you want to install some part, but not all, read the main Makefile. The
+frameworkinstall is composed of a couple of sub-targets that install the
+framework itself, the Mac subtree, the applications and the unix tools.
+
+There is an extra target frameworkinstallextras that is not part of the
+normal frameworkinstall which installs the Demo and Tools directories
+into "/Applications/MacPython 2.5", this is useful for binary distributions.
+
+What do all these programs do?
+===============================
+
+"IDLE.app" is an integrated development environment for Python: editor,
+debugger, etc.
+
+"PythonLauncher.app" is a helper application that will handle things when you
+double-click a .py, .pyc or .pyw file. For the first two it creates a Terminal
+window and runs the scripts with the normal command-line Python. For the
+latter it runs the script in the Python.app interpreter so the script can do
+GUI-things. Keep the "alt" key depressed while dragging or double-clicking a
+script to set runtime options. These options can be set once and for all
+through PythonLauncher's preferences dialog.
+
+"BuildApplet.app" creates an applet from a Python script. Drop the script on it
+and out comes a full-featured MacOS application. There is much more to this,
+to be supplied later. Some useful (but outdated) info can be found in
+Mac/Demo.
+
+The commandline scripts /usr/local/bin/python and pythonw can be used to run
+non-GUI and GUI python scripts from the command line, respectively.
+
+How do I create a binary distribution?
+======================================
+
+Go to the directory "Mac/OSX/BuildScript". There you'll find a script 
+"build-installer.py" that does all the work. This will download and build
+a number of 3th-party libaries, configures and builds a framework Python,
+installs it, creates the installer pacakge files and then packs this in a 
+DMG image.
+
+The script will build a universal binary, you'll therefore have to run this
+script on Mac OS X 10.4 or later and with Xcode 2.1 or later installed.
+
+All of this is normally done completely isolated in /tmp/_py, so it does not
+use your normal build directory nor does it install into /.
+
+Because of the way the script locates the files it needs you have to run it
+from within the BuildScript directory. The script accepts a number of 
+command-line arguments, run it with --help for more information.
+
+Odds and ends
+=============
+
+Something to take note of is that the ".rsrc" files in the distribution are
+not actually resource files, they're AppleSingle encoded resource files. The
+macresource module and the Mac/OSX/Makefile cater for this, and create
+".rsrc.df.rsrc" files on the fly that are normal datafork-based resource
+files.
+
+	Jack Jansen, Jack.Jansen at cwi.nl, 15-Jul-2004.
+	Ronald Oussoren, RonaldOussoren at mac.com, 26-May-2006

Added: vendor/Python/current/Mac/Resources/app/Info.plist
===================================================================
--- vendor/Python/current/Mac/Resources/app/Info.plist	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Resources/app/Info.plist	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleDocumentTypes</key>
+	<array>
+		<dict>
+			<key>CFBundleTypeOSTypes</key>
+			<array>
+				<string>****</string>
+				<string>fold</string>
+				<string>disk</string>
+			</array>
+			<key>CFBundleTypeRole</key>
+			<string>Viewer</string>
+		</dict>
+	</array>
+	<key>CFBundleExecutable</key>
+	<string>Python</string>
+	<key>CFBundleGetInfoString</key>
+	<string>2.5alpha0, (c) 2004 Python Software Foundation.</string>
+	<key>CFBundleHelpBookFolder</key>
+	<array>
+		<string>Documentation</string>
+		<string>PythonDocumentation</string>
+	</array>
+	<key>CFBundleHelpBookName</key>
+	<string>MacPython Help</string>
+	<key>CFBundleHelpTOCFile</key>
+	<string>index.html</string>
+	<key>CFBundleIconFile</key>
+	<string>PythonInterpreter.icns</string>
+	<key>CFBundleIdentifier</key>
+	<string>org.python.python</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleLongVersionString</key>
+	<string>2.5alpha0, (c) 2004 Python Software Foundation.</string>
+	<key>CFBundleName</key>
+	<string>Python</string>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>2.5alpha0</string>
+	<key>CFBundleSignature</key>
+	<string>PytX</string>
+	<key>CFBundleVersion</key>
+	<string>2.5alpha0</string>
+	<key>CSResourcesFileMapped</key>
+	<true/>
+	<key>LSRequiresCarbon</key>
+	<true/>
+	<key>NSAppleScriptEnabled</key>
+	<true/>
+	<key>NSHumanReadableCopyright</key>
+	<string>(c) 2004 Python Software Foundation.</string>
+</dict>
+</plist>

Added: vendor/Python/current/Mac/Resources/app/PkgInfo
===================================================================
--- vendor/Python/current/Mac/Resources/app/PkgInfo	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Resources/app/PkgInfo	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1 @@
+APPLPytX
\ No newline at end of file

Added: vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/PackageManager.gif
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/PackageManager.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/community.html
===================================================================
--- vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/community.html	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/community.html	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,69 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+        "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
+<html lang="en">
+<head>
+	<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+	<title>What is MacPython?</title>
+	<meta name="generator" content="BBEdit 6.5.3">
+	<link rel="SHORTCUT ICON" href="pythonsmall.gif">
+	<META NAME="AppleIcon" CONTENT="pythonsmall.gif">
+</head>
+<body>
+		<table>
+		<tr>
+			<td>
+				<img src="python.gif" width="128" height="128" align="top" alt="">
+			</td>
+			<td>
+				<h1>MacPython Community</h1>	
+			</td>
+		</tr>
+		</table>
+		<hr>
+
+<h2>Web Sites</h2>
+
+<p>The MacPython homepage, <a href="http://www.cwi.nl/~jack/macpython.html">
+www.cwi.nl/~jack/macpython.html</a>
+is where you can find installers, documents, links to useful packages and more. 
+And, of course,
+<a href="http://www.python.org">www.python.org</a> has a much larger collection
+of material on Python that is not Mac-specific.</p>
+
+<h2>News groups and Mailing lists</h2>
+
+<p>There are a lot of mailing lists on Python. Some of the more interesting
+ones are:</p>
+<ul>
+<li><a href="mailto:python-help at python.org">python-help at python.org</a> where
+you can send questions for individual support. Please check the websites mentioned
+above first, though!</li>
+<li>The <a href="news:comp.lang.python">comp.lang.python</a> newsgroup for general
+discussion. Also available as a 
+<a href="http://www.python.org/mailman/listinfo/python-list">mailing list</a>.</li>
+<li>The <a href="news:comp.lang.python.announce">comp.lang.python.announce</a> 
+newsgroup for announcements. Low-volume and moderated. Also available as a 
+<a href="http://www.python.org/mailman/listinfo/python-announce-list">mailing list</a>.</li>
+<li>Last but not least, the <a href="http://www.python.org/sigs/pythonmac-sig/">pythonmac-sig</a>
+mailing list is specifically for MacPython. Discussions on the implementation of new
+features, but beginners questions are welcome too.</li>
+</ul>
+
+<p>In addition there are Python <a href="http://www.python.org/sigs/">Special Interest Group</a>
+mailing lists on a wide variety of topics such as image processing, numerical algorithms
+and more.</p>
+
+<h2>More</h2>
+
+<p>An index of conferences, Wiki's, bookshops and more can be found at the
+<a href="http://www.python.org/psa/">Community</a> section of the Python website.</p>
+
+<p>If you find a bug you are kindly requested to report it, preferrably through the
+automatic bug tracker at <a href="http://www.python.org">www.python.org</a></p>
+
+<p>If you want to become an active developer you are very welcome! Join the
+pythonmac-sig mailing list mentioned above, and read the
+<a href="http://www.python.org/dev/">Developer</a> section on the Python website.</p>
+
+</body>
+</html>

Added: vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/doc/index.html
===================================================================
--- vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/doc/index.html	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/doc/index.html	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+        "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
+<html lang="en">
+<head>
+	<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+	<title>Python Language Documentation</title>
+	<meta name="generator" content="BBEdit 6.5.3">
+</head>
+<body>
+<h1>Python Language and runtime documentation</h1>
+
+<p>This volume of documentation is rather big (17 Megabytes) and contains
+a tutorial, full description of the Python library (all the modules
+and packages included), formal description of the language and more.</p>
+
+<p>You can <a href="http://www.python.org/doc">view it online</a>, where
+you can also download PDFs for printing, or you can download and install it
+through the <a href="../packman.html">Package Manager</a> for viewing and
+searching via Apple Help Viewer.</p>
+</body>
+</html>

Added: vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/finder.html
===================================================================
--- vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/finder.html	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/finder.html	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+        "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
+<html lang="en">
+<head>
+	<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+	<title>Python and the Finder</title>
+	<meta name="generator" content="BBEdit 6.5.3">
+	<link rel="SHORTCUT ICON" href="pythonsmall.gif">
+	<META NAME="AppleIcon" CONTENT="pythonsmall.gif">
+</head>
+<body>
+<h1>Running Python scripts from the Finder</h1>
+		<table>
+		<tr>
+			<td>
+				<img src="python.gif" width="128" height="128" align="top" alt="">
+			</td>
+			<td>
+				<p>The application PythonLauncher will start a Python interpreter
+				when you drop a Python source file onto it, any file with a <tt>.py</tt>
+				or <tt>.pyw</tt> extension. If you set PythonLauncher as the default
+				application to open a file
+(<a href="help:search=Changing%20the%20application%20that%20opens%20a%20file bookID=Mac%20Help">
+tell me more</a>) this also works when you double click a Python script.</p>
+
+				<p>PythonLauncher has preferences per filetype for selecting
+				the interpreter to use, and how to launch it: in a Terminal window
+				or not, etc. Holding the Option key while launching your script will
+				bring up a window that allows changing these settings for a single
+				run. </p>
+			</td>
+		</tr>
+		</table>
+		<hr>
+</body>
+</html>

Added: vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/gui.html
===================================================================
--- vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/gui.html	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/gui.html	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,54 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+        "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
+<html lang="en">
+<head>
+	<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+	<title>Creating a User Interface with MacPython</title>
+	<meta name="generator" content="BBEdit 6.5.3">
+	<link rel="SHORTCUT ICON" href="pythonsmall.gif">
+	<META NAME="AppleIcon" CONTENT="pythonsmall.gif">
+</head>
+<body>
+<h1>Creating a User Interface with MacPython</h1>
+
+<p>There are a number of packages that allow creation of a user interface
+for your Python code, each of which has its own merits:</p>
+
+<ul>
+	<li> The Carbon package gives low-level access to the old Macintosh toolbox
+	calls for windows, events, dialogs and more. The <tt>FrameWork</tt> module
+	wraps these in a minimal framework. For documentation see the Macintosh
+	Library section of the <a href="doc/index.html">Python Language and runtime 
+	documentation</a> and the Human Interface Toolbox section of 
+	<a href="help:openbook=Carbon">Apple's Carbon Documentation</a>. 
+	This solution is compatible with MacPython-OS9.</li>
+	<li> The <tt>W</tt> framework is built on top of this, and easier to use.
+	The MacPython IDE uses W. Some documentation is available on 
+	<a href="http://www.nevada.edu/~cwebster/Python/index.html">Corran Webster's website</a>.
+	Compatible with MacPython-OS9.</li>
+</ul>
+
+<p>For new work, however, one of the following packages may be better suited.
+They may be available out of the box in this distribution, otherwise you
+can install them through the <a href="packman.html">Package Manager</a>:</p>
+
+<ul>
+	<li> <a href="http://pyobjc.sourceforge.net/">PyObjC</a> allows complete access to Cocoa. 
+	In technical terms it is a
+	bidirectional bridge between Python and Objectve-C, similar to Apple's Java
+	bridge. Probably the best choice for Mac OS X-only applications, but at the
+	time of this writing PyObjC is still in beta.</li>
+	
+	<li> <a href="http://wxpython.sourceforge.net/">wxPython</a> gives Python programs
+	access to the wxWindows  GUI toolkit. Many people consider this
+	the best open source cross-platform GUI solution available today.</li>
+	
+	<li> Tkinter is the oldest cross-platform GUI toolkit for Python, bridging Python
+	to Tcl/Tk. If you install AquaTk it creates a native user interface on Mac OS X.
+	Documented in the Library section, Tkinter subsection of the 
+	<a href="doc/index.html">Python Language and runtime documentation</a>. Tkinter
+	is not available for MacPython-OS9.</li>
+</ul>
+				
+</body>
+</html>

Added: vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/ide/IDE.gif
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/ide/IDE.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/ide/entering_in_new_window.gif
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/ide/entering_in_new_window.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/ide/hello_world.gif
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/ide/hello_world.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/ide/index.html
===================================================================
--- vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/ide/index.html	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/ide/index.html	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,222 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+        "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
+<html lang="en">
+<head>
+	<title>One Day of MacPython IDE Toying</title>
+	<link rel="SHORTCUT ICON" href="../pythonsmall.gif">
+	<META NAME="AppleIcon" CONTENT="../pythonsmall.gif">
+</head>
+<body bgcolor="#ffffff">
+		<h1>One Day of MacPython IDE Toying</h1>
+		<table>
+		<tr>
+			<td>
+				<img src="IDE.gif" alt="">
+			</td>
+			<td>
+				<p>This document gives a very basic introduction to the
+				MacPython <b>I</b>ntegrated <b>D</b>evelopment <b>E</b>nvironment (IDE) on Mac OS. It was
+				written specifically for MacPython 2.3 on Mac OS X, but most of
+				it  is applicable to MacPython-OS9 too. It is based on 
+				<a href="http://www-hkn.eecs.berkeley.edu/~dyoo/python/idle_intro/">&quot;One
+				Day of IDLE Toying&quot;</a> by Danny Yoo, which you should read if
+				you want to use the cross-platform IDLE Python development
+				environment.</p>
+	
+			</td>
+		</tr>
+		</table>
+		<hr>
+		<br style="page-break-after: always">
+
+<p>Ok, let's assume that we've already installed Python. (If not, we can
+visit: <a href="http://www.cwi.nl/~jack/macpython.html">http://www.cwi.nl/~jack/macpython.html</a>
+or <a href="http://python.org">http://python.org</a>
+and download the most recent Python interpreter. Get the Mac OSX binary
+installer.) The first thing we'd like to do is actually start running it!
+We can do this by opening up the IDE, which should be in Applications
+under the newly-created MacPython program folder: </p><p><img
+src="loading_ide.gif" border=1 alt="image of IDE icon"></p>
+
+<hr><br style="page-break-after: always">
+
+<p>The IDE starts up and shows an interactive window: </p>
+<p><img src="new_ide_window.gif" alt="image of new window"></p>
+
+<p>If the window does not show up (because you have run the IDE before
+and closed it: it remembers that between runs) open it with the <tt>Windows-&gt;Python Interactive</tt>
+menu entry. </p>
+
+<p>This is the interactive window to the IDE, it allows us to enter
+commands directly into Python, and as soon as we enter a command,
+Python will execute it and spit its result back to us.  We'll be
+using this interactive window a lot when we're exploring Python: it's
+very nice because we get back our results immediately.  If it helps,
+we can think of it as a very powerful calculator.</p>
+
+<hr><br style="page-break-after: always">
+
+<p>Let's try something now!  As per tradition, let's get Python to say
+the immortal words, "Hello World".  <img src="hello_world.gif"
+border=1 alt="image of hello world program"></p> <p>Those '<tt>&gt;&gt;&gt;</tt>' signs act as a prompt
+for us: Python is ready to read in a new command by giving us that
+visual cue.  Also, we notice that as we enter commands, Python will
+give us its output immediately.
+</p>
+
+<hr><br style="page-break-after: always">
+
+<p>Ok, this seems pretty simple enough.  Let's try a few more
+commands.  If we look below:</p>
+
+<p><img src="simple_commands.gif" border=1 alt="image of command window"></p>
+
+<p>we'll see the result of running a few more commands.  Don't worry
+too much about knowing the exact rules for making programs yet: the
+idea is that we can experiment with Python by typing in commands.  If
+things don't work, then we can correct the mistake, and try it
+again.</p>
+
+<p>If you got to this point, you now know enough to start playing
+around with Python!  Crack open one of the tutorials from the <a
+href="http://python.org/doc/Newbies.html">Python For Beginners</a> web
+page, and start exploring with the interpreter.  No time limit here.  *grin*</p>
+
+<hr><br style="page-break-after: always">
+
+<p>Now that we've paddled long enough, we might be asking: ok, this is
+neat, but if we close down Python and start it up again, how do we get
+the computer to remember what we typed?</p>
+
+<p>The solution is a little subtle: we can't directly save what's in
+the interpreter window, because it will include both our commands and
+the system's responses.  What we'd like is to make a prepared file,
+with just our own commands, and to be able to save that file as a
+document.  When we're in the mood, we can later open that file and
+"run" Python over it, saving us the time of retyping the whole
+thing over again.</p>
+
+<p>Let's try this.  First, let's start with a clean slate by opening
+up a new window.</p> 
+
+<p><img src="making_new_window.gif" border=1 alt="image of making new window"></p>
+
+<p>Here's the result of that menu command:</p>
+
+<p><img src="new_window_made.gif" border=1 alt="image of new window"></p>
+
+<p>We notice that there's nothing in this new window.  What this means
+is that this file is purely for our commands: Python won't interject
+with its own responses as we enter the program, that is, not until we
+tell it to.  This is called an edit window, and it is very similar
+to edit windows in other editors such as TextEdit or BBEdit.</p>
+
+<hr><br style="page-break-after: always">
+
+<p>What we wanted to do before was save some of the stuff we had
+tried out on the interpreter window.  Let's do that by typing (or
+copy/pasting) those commands into our edit window.</p>
+<p><img src="entering_in_new_window.gif" border=1 alt="image of entering commands"></p>
+
+<p>Ok, we're done with copying and pasting.  
+One big thing to notice
+is that we're careful to get rid of the "<tt>&gt;&gt;&gt;</tt>"
+prompts because they're not really part of our program.  The
+interpreter uses them just to tell us that we're in the interpreter,
+but now that we're editing in a separate file, we can remove the
+artifacts that the interpreter introduces.
+I have added
+an extra empty print statement so our output ends with a newline.
+</p>
+
+<hr><br style="page-break-after: always">
+
+<p>Let's save the file now.  The Save command is located under the <tt>File</tt> menu:</p>
+<p><img src="saving_edited_file.gif" border=1 alt="image of saving file"></p>
+
+
+<hr><br style="page-break-after: always">
+
+<p>Now that we've saved the program, how do we run the program? Use the
+Run All button at the top of the editing window, or the equivalent
+menu command <tt>Python-&gt;Run Window</tt>. The output will appear in a new
+window called Output Window. </p>
+
+<p>By the way, one thing to notice is that I made a typo: I didn't
+quite copy exactly what I had entered in the interpreter window
+before.  Does this affect things?</p>
+
+<p><img src="syntax_error.gif" border=1 alt="image of syntax error"></p>
+
+<p>Ooops.  Here is an example of what Python calls a "syntax error".
+Python sees that we made a typo, and warns us to take a much closer
+look at our program.  The designers of Python feel that having the
+system point out the error is better than trying to guess at what the
+programmer meant.  Press the Edit button and you will be brought to
+the trouble spot. </p>
+
+<p>Python is often perceptive enough to direct us toward the problem,
+and in this case, it's telling us that we forgot to put something at
+the end of this line.  In this case, we need to add a
+quotation mark at the end.  Let's add that in now.</p>
+
+<p>Other errors, which usually occur later, when your program has
+already done something, result in a different dialog that allows you
+to look at variables and such in addition to showing you where
+the error occurred. </p>
+
+<hr><br style="page-break-after: always">
+
+<p>Ok, let's say that we fixed that silly typo.  Let's try to run the
+program again. This gives us a new window, the Output window, showing
+the output of our program:</p>
+<p><img src="output_window.gif" border=1 alt="image of output window"></p>
+
+<hr><br style="page-break-after: always">
+
+<p>As we play with Python, we'll find ourselves "switching modes"
+between the Interpreter window and the edit window.  However,
+if we try anything more complicated than two or three lines it
+is often a good idea to work in an edit window. Align
+your edit and output window such that you can see them at the same time.</p>
+
+<p>This is pretty much all we need to know about the MacPython IDE to actually do
+interesting things.  There is a lot more to the IDE, here is a quick
+breakdown of things to see and explore:</p>
+
+<ul>
+	<li>All sorts of edit commands such as find and replace can be
+	used in the editor windows. See the <tt>Edit</tt> menu.</li>
+	
+	<li>The bottom of the edit window has the scrollbar, but at the
+	left are two navigation devices: a line number box that you can type
+	numbers into to quickly go to a specific place, and a popup menu
+	that lists all classes, functions and methods in your file.</li>
+	
+	<li>Above the vertical scrollbar you find another popup menu, this
+	influences how the Run command works. You should try the debugger
+	some time! If you do, and you wonder what the new small column on
+	the left of your script is: you can click in it to make Python stop
+	when it reaches this line so you can inspect things. The profiler
+	is also nifty: it shows you where your program is spending its time.</li>
+	
+	<li>The module browser (<tt>Python-&gt;Module Browser</tt>) shows you all Python
+	modules currently loaded. You can look at the contents of the module with
+	Browse... and (for modules written in Python) at the source with Source...</li>
+	
+	<li>The Package Manager (under the <tt>File</tt> menu, also available as a
+	separate application) allows you to easily install Python extension packages
+	for all sorts of things: scientific computation, image processing,
+	building user interfaces and more. </li>
+	
+	<li>The <tt>Help</tt> menu gives you quick access to both the Python documentation,
+	if you have installed it with the Package Manager, and the Apple Developer
+	documentation. </li>
+	
+	<li>The <tt>File-&gt;Save as Applet</tt> menu command saves your script as a MacOSX
+	application. This allows you to create a script that you can drop files on,
+	and much more. The IDE itself is such an applet, completely written in Python. </li>
+	
+</ul>
+</body>
+</html>

Added: vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/ide/loading_ide.gif
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/ide/loading_ide.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/ide/making_new_window.gif
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/ide/making_new_window.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/ide/new_ide_window.gif
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/ide/new_ide_window.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/ide/new_window_made.gif
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/ide/new_window_made.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/ide/output_window.gif
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/ide/output_window.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/ide/saving_edited_file.gif
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/ide/saving_edited_file.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/ide/simple_commands.gif
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/ide/simple_commands.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/ide/syntax_error.gif
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/ide/syntax_error.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/index.html
===================================================================
--- vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/index.html	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/index.html	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,51 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+        "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
+<html lang="en">
+<head>
+	<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+	<title>MacPython Help</title>
+	<meta name="generator" content="BBEdit 6.5.3">
+	<link rel="SHORTCUT ICON" href="pythonsmall.gif">
+	<META NAME="AppleIcon" CONTENT="pythonsmall.gif">
+	<META NAME="AppleTitle" CONTENT="MacPython Help">
+</head>
+<body>
+
+<h1>MacPython Help</h1>
+		<table>
+		<tr>
+			<td>
+				<img src="python.gif" width="128" height="128" align="top" alt="">
+			</td>
+			<td>
+<p>Choose a topic, or enter keywords into the search field:</p>
+<ul>
+	<li><a href="intro.html">What is MacPython?</a>
+	</li>
+	<li><a href="ide/index.html">MacPython 
+	Integrated Development Environment Introduction</a>
+	</li>
+	<li><a href="doc/index.html">Python Language and runtime documentation</a>
+	</li>
+	<li><a href="finder.html">Running Python scripts from the Finder</a>
+	</li>
+	<li><a href="shell.html">Running Python scripts from the Unix Shell</a>
+	</li>
+	<li><a href="gui.html">Creating a User Interface with MacPython</a>
+	</li>
+	<li><a href="scripting.html">Controlling other Applications from MacPython</a>
+	</li>
+	<li><a href="packman.html">Installing additional functionality with the
+	Package Manager</a>
+	</li>
+	<li><a href="community.html">MacPython community</a>
+	</li>
+</ul>
+	
+			</td>
+		</tr>
+		</table>
+		<hr>
+
+</body>
+</html>

Added: vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/intro.html
===================================================================
--- vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/intro.html	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/intro.html	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,76 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+        "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
+<html lang="en">
+<head>
+	<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+	<title>What is MacPython?</title>
+	<meta name="generator" content="BBEdit 6.5.3">
+	<link rel="SHORTCUT ICON" href="pythonsmall.gif">
+	<META NAME="AppleIcon" CONTENT="pythonsmall.gif">
+</head>
+<body>
+<h1>What is MacPython?</h1>
+		<table>
+		<tr>
+			<td>
+				<img src="python.gif" width="128" height="128" align="top" alt="">
+			</td>
+			<td>
+<p>Python is a programming language. MacPython is a package containing
+that programming language plus Mac-specific tools and extensions.</p>
+	
+			</td>
+		</tr>
+		</table>
+		<hr>
+
+<h2>The Python Language</h2>
+<p>The Python programming language is available for many hardware
+platforms, and most general documentation is Unix- or Windows-centered. Keep
+this in mind when reading the rest of this help, or information on the web.
+</p>
+
+<p>The Python website, <a href="http://www.python.org">www.python.org</a>,
+has a <em>Beginners Guide</em> section including an 
+<a href="http://python.org/doc/essays/blurb.html">executive summary</a> on
+the language and a 
+<a href="http://python.org/doc/essays/comparisons.html">comparison</a> of Python
+to other languages. Or read the (rather longwinded) Python
+Tutorial in the <a href="doc/index.html">Python Language and runtime documentation</a>.</p>
+
+<p>MacPython contains a complete <a href="shell.html">unix interpreter</a> so
+if you are familiar with Python on unix you should feel right at home.</p>
+
+<h2>MacPython additions</h2>
+
+<p>The MacPython Integrated Development Environment (IDE) allows
+easy editing, running and debugging of scripts. Read the 
+<a href="ide/index.html">Introduction
+to the IDE</a> to whet your appetite.</p>
+
+<p>MacPython comes with lots of modules that allow access to 
+MacOS-specific technology, such as Carbon, Quicktime and AppleScript. 
+See the <em>Macintosh
+Modules</em> section of the
+<a href="doc/index.html">Python Language and runtime documentation</a>,
+but please keep in mind that some information there still pertains to
+Mac OS 9.
+
+Full access to the Cocoa APIs
+and tools such as Interface Builder is available separately through the
+<a href="packman.html">Package Manager</a>.</p>
+
+<p>The <a href="packman.html">Package Manager</a> also gives you access to extension
+packages for cross-platform GUI development (Tkinter, wxPython, PyOpenGL), 
+image processing (PIL), scientific
+computing (Numeric) and much more. <em>PyObjC</em> deserves a special mention: it allows
+transparent access to Cocoa and Interface Builder, similar to what Java provides,
+thereby making Python a first class citizen in the Mac OS X developer world. </p>
+
+<p>Python scripts can be saved as <em>applets</em>, semi-standalone applications
+that work just like a normal application. Additionally you can even create
+true standalone application that have everything embedded and can be
+shipped to anyone, without the need to install Python. You do <em>not</em>
+need to install the Apple Developer Tools for this. </p>
+</body>
+</html>

Added: vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/packman.html
===================================================================
--- vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/packman.html	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/packman.html	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,64 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+        "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
+<html lang="en">
+<head>
+	<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+	<title>Python Package Manager</title>
+	<meta name="generator" content="BBEdit 6.5.3">
+	<link rel="SHORTCUT ICON" href="pythonsmall.gif">
+	<META NAME="AppleIcon" CONTENT="pythonsmall.gif">
+</head>
+<body>
+<h1>Installing additional Python Packages</h1>
+		<table>
+		<tr>
+			<td>
+				<img src="PackageManager.gif" width="128" height="128" align="top" alt="">
+			</td>
+			<td>
+				<p>The Python Package Manager helps you installing additional
+				packages that enhance Python. It determines the exact MacOS version
+				and Python version you have and uses that information to download
+				a database that has packages that are test and tried on that
+				combination. In other words: if something is in your Package Manager
+				window but does not work you are free to blame the database maintainer.</p>
+				
+				<p>PackageManager then checks which of the packages you have installed
+				and which ones not. This should also work when you have installed packages
+				outside of PackageManager.
+				You can select packages and install them, and PackageManager will work 
+				out the requirements and install these too.</p>
+				
+				<p>Often PackageManager will list a package in two flavors: binary
+				and source. Binary should always work, source will only work if
+				you have installed the Apple Developer Tools. PackageManager will warn
+				you about this, and also about other external dependencies.</p>
+				
+				<p>PackageManager is available as a separate application and also
+				as a function of the IDE, through the <tt>File-&gt;Package Manager</tt> menu
+				entry. </p>
+				
+				<h2>Troubleshooting</h2>
+				
+				<p>If package manager fails to open the database first check that you are
+				connected to the internet. If you are connected then the problem
+				could be that there is no database (yet?) for your version of Mac OS X.
+				You may be able to find an alternative
+				database that works for your system at
+				<a href="http://www.python.org/packman">http://www.python.org/packman</a>.
+				In the standalone Package Manager you can then open such an alternative database
+				with the <tt>File-&gt;Open URL...</tt> command, but you should realize that
+				you are now on untested ground.</p>
+				
+				<p>Another potential problem source is that you are behind a firewall. This version
+				of PackageManager uses the Unix method of setting a firewall: you need to set the
+				environment variable <tt>http_proxy</tt> to <tt>"http://<i>proxyhost</i>:<i>port</i>"</tt>.
+				See <a href="http://developer.apple.com/qa/qa2001/qa1067.html">Apple Technical
+				Q&amp;A QA1067</a> for instructions.</p>
+				
+			</td>
+		</tr>
+		</table>
+		<hr>
+</body>
+</html>

Added: vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/python.gif
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/python.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/pythonsmall.gif
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/pythonsmall.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/scripting.html
===================================================================
--- vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/scripting.html	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/scripting.html	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,53 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+        "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
+<html lang="en">
+<head>
+	<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+	<title>Controlling other Applications from MacPython</title>
+	<meta name="generator" content="BBEdit 6.5.3">
+	<link rel="SHORTCUT ICON" href="pythonsmall.gif">
+	<META NAME="AppleIcon" CONTENT="pythonsmall.gif">
+</head>
+<body>
+<h1>Controlling other Applications from MacPython</h1>
+
+<p>Python has a fairly complete implementation of the Open Scripting
+Architecure (OSA, also commonly referred to as AppleScript), allowing
+you to control scriptable applications from your Python program,
+and with a fairly pythonic interface. This piece of
+Python:</p>
+	
+<blockquote><pre><tt>
+import Finder
+
+f = Finder.Finder()
+print f.get(f.window(1).name)
+</tt></pre></blockquote>
+
+<p>is identical to the following piece of AppleScript:</p>
+
+<blockquote><pre><tt>
+tell application "Finder"
+	get name of window 1
+end tell
+</tt></pre></blockquote>
+
+<p>To send AppleEvents to an application you must first create the Python
+modules interfacing to the terminology of the application (what
+<tt>Script Editor</tt> calls the "Dictionary"). Use the IDE menu command
+<tt>File-&gt;Generate OSA Suite...</tt> for this. For more control run</p>
+
+<blockquote><tt>
+pythonw .../Lib/plat-mac/gensuitemodule.py --help
+</tt></blockquote>
+
+<p>from a terminal window.</p>
+
+<h2>Creating a scriptable application in Python</h2>
+
+You can also create a scriptable application in Python, but this is not
+very well documented. For Carbon
+applications you should look at the <tt>MiniAEFrame</tt> module.
+
+</body>
+</html>

Added: vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/shell.html
===================================================================
--- vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/shell.html	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Resources/app/Resources/English.lproj/Documentation/shell.html	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,52 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+        "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
+<html lang="en">
+<head>
+	<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+	<title>Python and the Unix Shell</title>
+	<meta name="generator" content="BBEdit 6.5.3">
+	<link rel="SHORTCUT ICON" href="pythonsmall.gif">
+	<META NAME="AppleIcon" CONTENT="pythonsmall.gif">
+</head>
+<body>
+<h1>Running Python scripts from the Unix Shell</h1>
+		<table>
+		<tr>
+			<td>
+				<img src="python.gif" width="128" height="128" align="top" alt="">
+			</td>
+			<td>
+				<p>MacPython 2.3 installs a perfectly normal Unix commandline
+				python interpreter in <tt>/usr/local/bin/python</tt>. As of Mac OS X 10.2, however,
+				<tt>/usr/local/bin</tt> is not on the search path of your shell. Moreover,
+				Apple's python 2.2, which lives in <tt>/usr/bin</tt> <em>is</em> on your
+				search path, so this can lead to confusion.</p>
+				
+				<p>If you use <tt>tcsh</tt> you should add the following line
+				to the file <tt>.login</tt> in your home directory and restart Terminal:
+				<br>
+				<tt>setenv PATH /usr/local/bin:$PATH</tt>
+				</p>
+				
+				<p>If you use <tt>bash</tt> or <tt>zsh</tt>
+				you should add the following line
+				to the file <tt>.profile</tt> in your home directory and restart Terminal:
+				<br>
+				<tt>export PATH=/usr/local/bin:$PATH</tt>
+				</p>
+				
+				<h2>GUI scripts</h2>
+				
+				<p>Due to the way MacOS handles windowing applications you need to run 
+				<em>all</em> scripts that use the window manager (be it through
+				Carbon, Cocoa, Tkinter, wxPython, PyOpenGL or anything else) with the
+				<tt>pythonw</tt> interpreter, also installed in <tt>/usr/local/bin</tt>.</p>
+				
+				<p>Running with <tt>python</tt> results in an inability to bring the
+				script to the front, or interacting with it. </p>
+			</td>
+		</tr>
+		</table>
+		<hr>
+</body>
+</html>

Added: vendor/Python/current/Mac/Resources/app/Resources/English.lproj/InfoPlist.strings
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Mac/Resources/app/Resources/English.lproj/InfoPlist.strings
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Mac/Resources/app/Resources/PythonApplet.icns
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Mac/Resources/app/Resources/PythonApplet.icns
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Mac/Resources/app/Resources/PythonInterpreter.icns
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Mac/Resources/app/Resources/PythonInterpreter.icns
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Mac/Resources/framework/English.lproj/InfoPlist.strings
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Mac/Resources/framework/English.lproj/InfoPlist.strings
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Mac/Resources/framework/Info.plist
===================================================================
--- vendor/Python/current/Mac/Resources/framework/Info.plist	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Resources/framework/Info.plist	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
+<plist version="0.9">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleExecutable</key>
+	<string>Python</string>
+	<key>CFBundleGetInfoString</key>
+	<string>Python Runtime and Library</string>
+	<key>CFBundleIdentifier</key>
+	<string>org.python.python</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>Python</string>
+	<key>CFBundlePackageType</key>
+	<string>FMWK</string>
+	<key>CFBundleShortVersionString</key>
+	<string>2.5</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>2.5</string>
+</dict>
+</plist>

Added: vendor/Python/current/Mac/Resources/framework/version.plist
===================================================================
--- vendor/Python/current/Mac/Resources/framework/version.plist	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Resources/framework/version.plist	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>BuildVersion</key>
+	<string>1</string>
+	<key>CFBundleShortVersionString</key>
+	<string>2.5alpha0</string>
+	<key>CFBundleVersion</key>
+	<string>2.5alpha0</string>
+	<key>ProjectName</key>
+	<string>Python</string>
+	<key>ReleaseStatus</key>
+	<string>alfa</string>
+	<key>SourceVersion</key>
+	<string>2.4a0</string>
+</dict>
+</plist>

Added: vendor/Python/current/Mac/Resources/iconsrc/IDE.psd
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Mac/Resources/iconsrc/IDE.psd
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Mac/Resources/iconsrc/PackageManager.psd
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Mac/Resources/iconsrc/PackageManager.psd
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Mac/Resources/iconsrc/PythonApplet.psd
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Mac/Resources/iconsrc/PythonApplet.psd
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Mac/Resources/iconsrc/PythonCompiled.psd
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Mac/Resources/iconsrc/PythonCompiled.psd
___________________________________________________________________
Name: svn:executable
   + 
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Mac/Resources/iconsrc/PythonIcon.psd
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Mac/Resources/iconsrc/PythonIcon.psd
___________________________________________________________________
Name: svn:executable
   + 
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Mac/Resources/iconsrc/PythonSource.psd
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Mac/Resources/iconsrc/PythonSource.psd
___________________________________________________________________
Name: svn:executable
   + 
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Mac/Resources/iconsrc/PythonWSource.psd
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Mac/Resources/iconsrc/PythonWSource.psd
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Mac/Tools/Doc/HelpIndexingTool/Help_Indexing_Tool_Suite.py
===================================================================
--- vendor/Python/current/Mac/Tools/Doc/HelpIndexingTool/Help_Indexing_Tool_Suite.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Tools/Doc/HelpIndexingTool/Help_Indexing_Tool_Suite.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,110 @@
+"""Suite Help Indexing Tool Suite: Special events that just the Help Indexing Tool supports.
+Level 0, version 0
+
+Generated from /Developer/Applications/Apple Help Indexing Tool.app
+AETE/AEUT resource version 1/1, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'HIT '
+
+class Help_Indexing_Tool_Suite_Events:
+
+    def turn_anchor_indexing(self, _object, _attributes={}, **_arguments):
+        """turn anchor indexing: Turns anchor indexing on or off.
+        Required argument: \xd2on\xd3 or \xd2off\xd3, to turn anchor indexing on or off
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'HIT '
+        _subcode = 'tAnc'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_turn_remote_root = {
+        'with_root_url' : 'rURL',
+    }
+
+    def turn_remote_root(self, _object, _attributes={}, **_arguments):
+        """turn remote root: Turn usage of remote root for content on the web on or off. If turning \xd2on\xd3, supply a string as second parameter.
+        Required argument: \xd2on\xd3 or \xd2off\xd3, to turn remote root on or off
+        Keyword argument with_root_url: The remote root to use, in the form of \xd2http://www.apple.com/help/\xd3.
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'HIT '
+        _subcode = 'tRem'
+
+        aetools.keysubst(_arguments, self._argmap_turn_remote_root)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def use_tokenizer(self, _object, _attributes={}, **_arguments):
+        """use tokenizer: Tells the indexing tool which tokenizer to use.
+        Required argument: Specify \xd2English\xd3, \xd2European\xd3, \xd2Japanese\xd3, \xd2Korean\xd3, or \xd2Simple\xd3.
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'HIT '
+        _subcode = 'uTok'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+
+class application(aetools.ComponentItem):
+    """application - Application class """
+    want = 'capp'
+class _Prop_idleStatus(aetools.NProperty):
+    """idleStatus -  """
+    which = 'sIdl'
+    want = 'bool'
+application._superclassnames = []
+application._privpropdict = {
+    'idleStatus' : _Prop_idleStatus,
+}
+application._privelemdict = {
+}
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+    'capp' : application,
+}
+
+_propdeclarations = {
+    'sIdl' : _Prop_idleStatus,
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+}

Added: vendor/Python/current/Mac/Tools/Doc/HelpIndexingTool/Miscellaneous_Standards.py
===================================================================
--- vendor/Python/current/Mac/Tools/Doc/HelpIndexingTool/Miscellaneous_Standards.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Tools/Doc/HelpIndexingTool/Miscellaneous_Standards.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,49 @@
+"""Suite Miscellaneous Standards: Useful events that aren\xd5t in any other suite
+Level 0, version 0
+
+Generated from /Developer/Applications/Apple Help Indexing Tool.app
+AETE/AEUT resource version 1/1, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'misc'
+
+class Miscellaneous_Standards_Events:
+
+    def revert(self, _object, _attributes={}, **_arguments):
+        """revert: Revert an object to the most recently saved version
+        Required argument: object to revert
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'misc'
+        _subcode = 'rvrt'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+}
+
+_propdeclarations = {
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+}

Added: vendor/Python/current/Mac/Tools/Doc/HelpIndexingTool/Required_Suite.py
===================================================================
--- vendor/Python/current/Mac/Tools/Doc/HelpIndexingTool/Required_Suite.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Tools/Doc/HelpIndexingTool/Required_Suite.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,32 @@
+"""Suite Required Suite: Terms that every application should support
+Level 1, version 1
+
+Generated from /Developer/Applications/Apple Help Indexing Tool.app
+AETE/AEUT resource version 1/1, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'reqd'
+
+from StdSuites.Required_Suite import *
+class Required_Suite_Events(Required_Suite_Events):
+
+    pass
+
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+}
+
+_propdeclarations = {
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+}

Added: vendor/Python/current/Mac/Tools/Doc/HelpIndexingTool/Standard_Suite.py
===================================================================
--- vendor/Python/current/Mac/Tools/Doc/HelpIndexingTool/Standard_Suite.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Tools/Doc/HelpIndexingTool/Standard_Suite.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,343 @@
+"""Suite Standard Suite: Common terms for most applications
+Level 1, version 1
+
+Generated from /Developer/Applications/Apple Help Indexing Tool.app
+AETE/AEUT resource version 1/1, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'CoRe'
+
+from StdSuites.Standard_Suite import *
+class Standard_Suite_Events(Standard_Suite_Events):
+
+    _argmap_close = {
+        'saving' : 'savo',
+        'in_' : 'kfil',
+    }
+
+    def close(self, _object, _attributes={}, **_arguments):
+        """close: Close an object
+        Required argument: the objects to close
+        Keyword argument saving: specifies whether or not changes should be saved before closing
+        Keyword argument in_: the file in which to save the object
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'core'
+        _subcode = 'clos'
+
+        aetools.keysubst(_arguments, self._argmap_close)
+        _arguments['----'] = _object
+
+        aetools.enumsubst(_arguments, 'savo', _Enum_savo)
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def data_size(self, _object, _attributes={}, **_arguments):
+        """data size: Return the size in bytes of an object
+        Required argument: the object whose data size is to be returned
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: the size of the object in bytes
+        """
+        _code = 'core'
+        _subcode = 'dsiz'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def get(self, _object, _attributes={}, **_arguments):
+        """get: Get the data for an object
+        Required argument: the object whose data is to be returned
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: The data from the object
+        """
+        _code = 'core'
+        _subcode = 'getd'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_make = {
+        'new' : 'kocl',
+        'at' : 'insh',
+        'with_data' : 'data',
+        'with_properties' : 'prdt',
+    }
+
+    def make(self, _no_object=None, _attributes={}, **_arguments):
+        """make: Make a new element
+        Keyword argument new: the class of the new element
+        Keyword argument at: the location at which to insert the element
+        Keyword argument with_data: the initial data for the element
+        Keyword argument with_properties: the initial values for the properties of the element
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        Returns: Object specifier for the new element
+        """
+        _code = 'core'
+        _subcode = 'crel'
+
+        aetools.keysubst(_arguments, self._argmap_make)
+        if _no_object != None: raise TypeError, 'No direct arg expected'
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def open(self, _object, _attributes={}, **_arguments):
+        """open: Open the specified object(s)
+        Required argument: Objects to open. Can be a list of files or an object specifier.
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'aevt'
+        _subcode = 'odoc'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    def print_(self, _object, _attributes={}, **_arguments):
+        """print: Print the specified object(s)
+        Required argument: Objects to print. Can be a list of files or an object specifier.
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'aevt'
+        _subcode = 'pdoc'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_save = {
+        'in_' : 'kfil',
+        'as' : 'fltp',
+    }
+
+    def save(self, _object, _attributes={}, **_arguments):
+        """save: save a set of objects
+        Required argument: Objects to save.
+        Keyword argument in_: the file in which to save the object(s)
+        Keyword argument as: the file type of the document in which to save the data
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'core'
+        _subcode = 'save'
+
+        aetools.keysubst(_arguments, self._argmap_save)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+    _argmap_set = {
+        'to' : 'data',
+    }
+
+    def set(self, _object, _attributes={}, **_arguments):
+        """set: Set an object\xd5s data
+        Required argument: the object to change
+        Keyword argument to: the new value
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'core'
+        _subcode = 'setd'
+
+        aetools.keysubst(_arguments, self._argmap_set)
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+
+class application(aetools.ComponentItem):
+    """application - An application program """
+    want = 'capp'
+#        element 'cwin' as ['indx', 'name', 'rele']
+#        element 'docu' as ['name']
+
+class window(aetools.ComponentItem):
+    """window - A Window """
+    want = 'cwin'
+class _Prop_bounds(aetools.NProperty):
+    """bounds - the boundary rectangle for the window """
+    which = 'pbnd'
+    want = 'qdrt'
+class _Prop_closeable(aetools.NProperty):
+    """closeable - Does the window have a close box? """
+    which = 'hclb'
+    want = 'bool'
+class _Prop_floating(aetools.NProperty):
+    """floating - Does the window float? """
+    which = 'isfl'
+    want = 'bool'
+class _Prop_index(aetools.NProperty):
+    """index - the number of the window """
+    which = 'pidx'
+    want = 'long'
+class _Prop_modal(aetools.NProperty):
+    """modal - Is the window modal? """
+    which = 'pmod'
+    want = 'bool'
+class _Prop_name(aetools.NProperty):
+    """name - the title of the window """
+    which = 'pnam'
+    want = 'itxt'
+class _Prop_position(aetools.NProperty):
+    """position - upper left coordinates of window """
+    which = 'ppos'
+    want = 'QDpt'
+class _Prop_resizable(aetools.NProperty):
+    """resizable - Is the window resizable? """
+    which = 'prsz'
+    want = 'bool'
+class _Prop_titled(aetools.NProperty):
+    """titled - Does the window have a title bar? """
+    which = 'ptit'
+    want = 'bool'
+class _Prop_visible(aetools.NProperty):
+    """visible - is the window visible? """
+    which = 'pvis'
+    want = 'bool'
+class _Prop_zoomable(aetools.NProperty):
+    """zoomable - Is the window zoomable? """
+    which = 'iszm'
+    want = 'bool'
+class _Prop_zoomed(aetools.NProperty):
+    """zoomed - Is the window zoomed? """
+    which = 'pzum'
+    want = 'bool'
+
+class document(aetools.ComponentItem):
+    """document - A Document """
+    want = 'docu'
+class _Prop_modified(aetools.NProperty):
+    """modified - Has the document been modified since the last save? """
+    which = 'imod'
+    want = 'bool'
+application._superclassnames = []
+application._privpropdict = {
+}
+application._privelemdict = {
+    'document' : document,
+    'window' : window,
+}
+window._superclassnames = []
+window._privpropdict = {
+    'bounds' : _Prop_bounds,
+    'closeable' : _Prop_closeable,
+    'floating' : _Prop_floating,
+    'index' : _Prop_index,
+    'modal' : _Prop_modal,
+    'name' : _Prop_name,
+    'position' : _Prop_position,
+    'resizable' : _Prop_resizable,
+    'titled' : _Prop_titled,
+    'visible' : _Prop_visible,
+    'zoomable' : _Prop_zoomable,
+    'zoomed' : _Prop_zoomed,
+}
+window._privelemdict = {
+}
+document._superclassnames = []
+document._privpropdict = {
+    'modified' : _Prop_modified,
+    'name' : _Prop_name,
+}
+document._privelemdict = {
+}
+_Enum_savo = {
+    'yes' : 'yes ',     # Save objects now
+    'no' : 'no  ',      # Do not save objects
+    'ask' : 'ask ',     # Ask the user whether to save
+}
+
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+    'capp' : application,
+    'cwin' : window,
+    'docu' : document,
+}
+
+_propdeclarations = {
+    'hclb' : _Prop_closeable,
+    'imod' : _Prop_modified,
+    'isfl' : _Prop_floating,
+    'iszm' : _Prop_zoomable,
+    'pbnd' : _Prop_bounds,
+    'pidx' : _Prop_index,
+    'pmod' : _Prop_modal,
+    'pnam' : _Prop_name,
+    'ppos' : _Prop_position,
+    'prsz' : _Prop_resizable,
+    'ptit' : _Prop_titled,
+    'pvis' : _Prop_visible,
+    'pzum' : _Prop_zoomed,
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+    'savo' : _Enum_savo,
+}

Added: vendor/Python/current/Mac/Tools/Doc/HelpIndexingTool/__init__.py
===================================================================
--- vendor/Python/current/Mac/Tools/Doc/HelpIndexingTool/__init__.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Tools/Doc/HelpIndexingTool/__init__.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,78 @@
+"""
+Package generated from /Developer/Applications/Apple Help Indexing Tool.app
+"""
+import aetools
+Error = aetools.Error
+import Standard_Suite
+import Help_Indexing_Tool_Suite
+import odds_and_ends
+import Miscellaneous_Standards
+import Required_Suite
+
+
+_code_to_module = {
+    'CoRe' : Standard_Suite,
+    'HIT ' : Help_Indexing_Tool_Suite,
+    'Odds' : odds_and_ends,
+    'misc' : Miscellaneous_Standards,
+    'reqd' : Required_Suite,
+}
+
+
+
+_code_to_fullname = {
+    'CoRe' : ('HelpIndexingTool.Standard_Suite', 'Standard_Suite'),
+    'HIT ' : ('HelpIndexingTool.Help_Indexing_Tool_Suite', 'Help_Indexing_Tool_Suite'),
+    'Odds' : ('HelpIndexingTool.odds_and_ends', 'odds_and_ends'),
+    'misc' : ('HelpIndexingTool.Miscellaneous_Standards', 'Miscellaneous_Standards'),
+    'reqd' : ('HelpIndexingTool.Required_Suite', 'Required_Suite'),
+}
+
+from Standard_Suite import *
+from Help_Indexing_Tool_Suite import *
+from odds_and_ends import *
+from Miscellaneous_Standards import *
+from Required_Suite import *
+
+def getbaseclasses(v):
+    if not getattr(v, '_propdict', None):
+        v._propdict = {}
+        v._elemdict = {}
+        for superclassname in getattr(v, '_superclassnames', []):
+            superclass = eval(superclassname)
+            getbaseclasses(superclass)
+            v._propdict.update(getattr(superclass, '_propdict', {}))
+            v._elemdict.update(getattr(superclass, '_elemdict', {}))
+        v._propdict.update(getattr(v, '_privpropdict', {}))
+        v._elemdict.update(getattr(v, '_privelemdict', {}))
+
+import StdSuites
+
+#
+# Set property and element dictionaries now that all classes have been defined
+#
+getbaseclasses(window)
+getbaseclasses(application)
+getbaseclasses(document)
+getbaseclasses(application)
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+    'cwin' : window,
+    'capp' : application,
+    'docu' : document,
+    'capp' : application,
+}
+
+
+class HelpIndexingTool(Standard_Suite_Events,
+        Help_Indexing_Tool_Suite_Events,
+        odds_and_ends_Events,
+        Miscellaneous_Standards_Events,
+        Required_Suite_Events,
+        aetools.TalkTo):
+    _signature = 'hiti'
+
+    _moduleName = 'HelpIndexingTool'

Added: vendor/Python/current/Mac/Tools/Doc/HelpIndexingTool/odds_and_ends.py
===================================================================
--- vendor/Python/current/Mac/Tools/Doc/HelpIndexingTool/odds_and_ends.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Tools/Doc/HelpIndexingTool/odds_and_ends.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,49 @@
+"""Suite odds and ends: Things that should be in some standard suite, but aren\xd5t
+Level 1, version 1
+
+Generated from /Developer/Applications/Apple Help Indexing Tool.app
+AETE/AEUT resource version 1/1, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'Odds'
+
+class odds_and_ends_Events:
+
+    def select(self, _object=None, _attributes={}, **_arguments):
+        """select: Select the specified object
+        Required argument: the object to select
+        Keyword argument _attributes: AppleEvent attribute dictionary
+        """
+        _code = 'misc'
+        _subcode = 'slct'
+
+        if _arguments: raise TypeError, 'No optional args expected'
+        _arguments['----'] = _object
+
+
+        _reply, _arguments, _attributes = self.send(_code, _subcode,
+                _arguments, _attributes)
+        if _arguments.get('errn', 0):
+            raise aetools.Error, aetools.decodeerror(_arguments)
+        # XXXX Optionally decode result
+        if _arguments.has_key('----'):
+            return _arguments['----']
+
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+}
+
+_propdeclarations = {
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+}

Added: vendor/Python/current/Mac/Tools/Doc/README
===================================================================
--- vendor/Python/current/Mac/Tools/Doc/README	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Tools/Doc/README	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,35 @@
+In this directory you can build the Python documentation in a form that
+is suitable for access with Apple Help Viewer. This will enable the
+"Python Documentation" menu entries in the MacPython IDE Help menu.
+
+Unfortunately the procedure to build the docs is not very streamlined.
+
+First, edit setup.py. At the top, edit MAJOR_VERSION and MINOR_VERSION,
+and check that DESTDIR makes sense. The documentation will be installed
+inside PythonIDE.app.
+
+In DocBuild.initialize_options, set self.download to True if you want to
+download the docs. Set it to False if you want to build the docs from
+the source tree, but this requires LaTex and lots of other stuff.
+Doable, but not easy.
+
+Second, if you want to download the docs you may need to do a couple
+more edits. The way the docs are packaged will often change between
+major releases. Fiddle DocBuild.downloadDocs to make it do the right
+thing (download the docs from python.org, unpack them, rename the
+directory to "build/html").
+
+After these edits you should be ready to roll. "pythonw setup.py build"
+should download and unpack (or build) the docs. Next, it will do some
+magic to make the docs indexable. Finally, it will run the Apple Help
+Indexing Tool. (This last step is the reason you must use "pythonw" as
+opposed to "python"). Usually it will time out while waiting for AHIT to
+do its work. Wait until AHIT is done.
+
+Now you're ready to install with "python setup.py install".
+
+After this is done test your work. Fire up PythonIDE, and check that
+Help->Python Documentation brings up the documentation in the Help Viewer.
+Also open an IDE edit window, type something like "import sys", select
+"import", and use Help->Lookup in Python Documentation to check that the
+index has been generated correctly.

Added: vendor/Python/current/Mac/Tools/Doc/setup.py
===================================================================
--- vendor/Python/current/Mac/Tools/Doc/setup.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Tools/Doc/setup.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,214 @@
+# Build and install an Apple Help Viewer compatible version of the Python
+# documentation into the framework.
+# Code by Bill Fancher, with some modifications by Jack Jansen.
+#
+# You must run this as a two-step process
+# 1. python setupDocs.py build
+# 2. Wait for Apple Help Indexing Tool to finish
+# 3. python setupDocs.py install
+#
+# To do:
+# - test whether the docs are available locally before downloading
+# - fix buildDocsFromSource
+# - Get documentation version from sys.version, fallback to 2.2.1
+# - See if we can somehow detect that Apple Help Indexing Tool is finished
+# - data_files to setup() doesn't seem the right way to pass the arguments
+#
+import sys, os, re
+from distutils.cmd import Command
+from distutils.command.build import build
+from distutils.core import setup
+from distutils.file_util import copy_file
+from distutils.dir_util import copy_tree
+from distutils.log import log
+from distutils.spawn import spawn
+from distutils import sysconfig, dep_util
+from distutils.util import change_root
+import HelpIndexingTool
+import Carbon.File
+import time
+
+MAJOR_VERSION='2.4'
+MINOR_VERSION='2.4.1'
+DESTDIR='/Applications/MacPython-%s/PythonIDE.app/Contents/Resources/English.lproj/PythonDocumentation' % MAJOR_VERSION
+
+class DocBuild(build):
+    def initialize_options(self):
+        build.initialize_options(self)
+        self.build_html = None
+        self.build_dest = None
+        self.download = 1
+        self.doc_version = MINOR_VERSION # Only needed if download is true
+
+    def finalize_options(self):
+        build.finalize_options(self)
+        if self.build_html is None:
+            self.build_html = os.path.join(self.build_base, 'html')
+        if self.build_dest is None:
+            self.build_dest = os.path.join(self.build_base, 'PythonDocumentation')
+
+    def spawn(self, *args):
+        spawn(args, 1,  self.verbose, self.dry_run)
+
+    def downloadDocs(self):
+        workdir = os.getcwd()
+        # XXX Note: the next strings may change from version to version
+        url = 'http://www.python.org/ftp/python/doc/%s/html-%s.tar.bz2' % \
+                (self.doc_version,self.doc_version)
+        tarfile = 'html-%s.tar.bz2' % self.doc_version
+        dirname = 'Python-Docs-%s' % self.doc_version
+
+        if os.path.exists(self.build_html):
+            raise RuntimeError, '%s: already exists, please remove and try again' % self.build_html
+        os.chdir(self.build_base)
+        self.spawn('curl','-O', url)
+        self.spawn('tar', '-xjf', tarfile)
+        os.rename(dirname, 'html')
+        os.chdir(workdir)
+##        print "** Please unpack %s" % os.path.join(self.build_base, tarfile)
+##        print "** Unpack the files into %s" % self.build_html
+##        raise RuntimeError, "You need to unpack the docs manually"
+
+    def buildDocsFromSource(self):
+        srcdir = '../../..'
+        docdir = os.path.join(srcdir, 'Doc')
+        htmldir = os.path.join(docdir, 'html')
+        spawn(('make','--directory', docdir, 'html'), 1, self.verbose, self.dry_run)
+        self.mkpath(self.build_html)
+        copy_tree(htmldir, self.build_html)
+
+    def ensureHtml(self):
+        if not os.path.exists(self.build_html):
+            if self.download:
+                self.downloadDocs()
+            else:
+                self.buildDocsFromSource()
+
+    def hackIndex(self):
+        ind_html = 'index.html'
+        #print 'self.build_dest =', self.build_dest
+        hackedIndex = file(os.path.join(self.build_dest, ind_html),'w')
+        origIndex = file(os.path.join(self.build_html,ind_html))
+        r = re.compile('<style type="text/css">.*</style>', re.DOTALL)
+        hackedIndex.write(r.sub('<META NAME="AppleTitle" CONTENT="Python Documentation">',origIndex.read()))
+
+    def hackFile(self,d,f):
+        origPath = os.path.join(d,f)
+        assert(origPath[:len(self.build_html)] == self.build_html)
+        outPath = os.path.join(self.build_dest, d[len(self.build_html)+1:], f)
+        (name, ext) = os.path.splitext(f)
+        if os.path.isdir(origPath):
+            self.mkpath(outPath)
+        elif ext == '.html':
+            if self.verbose: print 'hacking %s to %s' % (origPath,outPath)
+            hackedFile = file(outPath, 'w')
+            origFile = file(origPath,'r')
+            hackedFile.write(self.r.sub('<dl><dt><dd>', origFile.read()))
+        else:
+            copy_file(origPath, outPath)
+
+    def hackHtml(self):
+        self.r = re.compile('<dl><dd>')
+        os.path.walk(self.build_html, self.visit, None)
+
+    def visit(self, dummy, dirname, filenames):
+        for f in filenames:
+            self.hackFile(dirname, f)
+
+    def makeHelpIndex(self):
+        app = '/Developer/Applications/Apple Help Indexing Tool.app'
+        self.spawn('open', '-a', app , self.build_dest)
+        print "Please wait until Apple Help Indexing Tool finishes before installing"
+
+    def makeHelpIndex(self):
+        app = HelpIndexingTool.HelpIndexingTool(start=1)
+        app.open(Carbon.File.FSSpec(self.build_dest))
+        sys.stderr.write("Waiting for Help Indexing Tool to start...")
+        while 1:
+            # This is bad design in the suite generation code!
+            idle = app._get(HelpIndexingTool.Help_Indexing_Tool_Suite._Prop_idleStatus())
+            time.sleep(10)
+            if not idle: break
+            sys.stderr.write(".")
+        sys.stderr.write("\n")
+        sys.stderr.write("Waiting for Help Indexing Tool to finish...")
+        while 1:
+            # This is bad design in the suite generation code!
+            idle = app._get(HelpIndexingTool.Help_Indexing_Tool_Suite._Prop_idleStatus())
+            time.sleep(10)
+            if idle: break
+            sys.stderr.write(".")
+        sys.stderr.write("\n")
+
+
+    def run(self):
+        self.ensure_finalized()
+        self.mkpath(self.build_base)
+        self.ensureHtml()
+        if not os.path.isdir(self.build_html):
+            raise RuntimeError, \
+            "Can't find source folder for documentation."
+        self.mkpath(self.build_dest)
+        if dep_util.newer(os.path.join(self.build_html,'index.html'), os.path.join(self.build_dest,'index.html')):
+            self.mkpath(self.build_dest)
+            self.hackHtml()
+            self.hackIndex()
+            self.makeHelpIndex()
+
+class AHVDocInstall(Command):
+    description = "install Apple Help Viewer html files"
+    user_options = [('install-doc=', 'd',
+            'directory to install HTML tree'),
+             ('root=', None,
+             "install everything relative to this alternate root directory"),
+            ]
+
+    def initialize_options(self):
+        self.build_dest = None
+        self.install_doc = None
+        self.prefix = None
+        self.root = None
+
+    def finalize_options(self):
+        self.set_undefined_options('install',
+                ('prefix', 'prefix'),
+                ('root', 'root'))
+#               import pdb ; pdb.set_trace()
+        build_cmd = self.get_finalized_command('build')
+        if self.build_dest == None:
+            build_cmd = self.get_finalized_command('build')
+            self.build_dest = build_cmd.build_dest
+        if self.install_doc == None:
+            self.install_doc = os.path.join(self.prefix, DESTDIR)
+        print 'INSTALL', self.build_dest, '->', self.install_doc
+
+    def run(self):
+        self.finalize_options()
+        self.ensure_finalized()
+        print "Running Installer"
+        instloc = self.install_doc
+        if self.root:
+            instloc = change_root(self.root, instloc)
+        self.mkpath(instloc)
+        copy_tree(self.build_dest, instloc)
+        print "Installation complete"
+
+def mungeVersion(infile, outfile):
+    i = file(infile,'r')
+    o = file(outfile,'w')
+    o.write(re.sub('\$\(VERSION\)',sysconfig.get_config_var('VERSION'),i.read()))
+    i.close()
+    o.close()
+
+def main():
+    # turn off warnings when deprecated modules are imported
+##      import warnings
+##      warnings.filterwarnings("ignore",category=DeprecationWarning)
+    setup(name = 'Documentation',
+            version = '%d.%d' % sys.version_info[:2],
+            cmdclass = {'install_data':AHVDocInstall, 'build':DocBuild},
+            data_files = ['dummy'],
+            )
+
+if __name__ == '__main__':
+    main()

Added: vendor/Python/current/Mac/Tools/fixapplepython23.py
===================================================================
--- vendor/Python/current/Mac/Tools/fixapplepython23.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Tools/fixapplepython23.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,130 @@
+#!/usr/bin/python
+"""fixapplepython23 - Fix Apple-installed Python 2.3 (on Mac OS X 10.3)
+
+Python 2.3 (and 2.3.X for X<5) have the problem that building an extension
+for a framework installation may accidentally pick up the framework
+of a newer Python, in stead of the one that was used to build the extension.
+
+This script modifies the Makefile (in .../lib/python2.3/config) to use
+the newer method of linking extensions with "-undefined dynamic_lookup"
+which fixes this problem.
+
+The script will first check all prerequisites, and return a zero exit
+status also when nothing needs to be fixed.
+"""
+import sys
+import os
+import gestalt
+
+MAKEFILE='/System/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3/config/Makefile'
+CHANGES=((
+    'LDSHARED=\t$(CC) $(LDFLAGS) -bundle -framework $(PYTHONFRAMEWORK)\n',
+    'LDSHARED=\t$(CC) $(LDFLAGS) -bundle -undefined dynamic_lookup\n'
+    ),(
+    'BLDSHARED=\t$(CC) $(LDFLAGS) -bundle -framework $(PYTHONFRAMEWORK)\n',
+    'BLDSHARED=\t$(CC) $(LDFLAGS) -bundle -undefined dynamic_lookup\n'
+    ),(
+    'CC=\t\tgcc\n',
+    'CC=\t\t/System/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3/config/PantherPythonFix/run-gcc\n'
+    ),(
+    'CXX=\t\tc++\n',
+    'CXX=\t\t/System/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3/config/PantherPythonFix/run-g++\n'
+))
+
+GCC_SCRIPT='/System/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3/config/PantherPythonFix/run-gcc'
+GXX_SCRIPT='/System/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3/config/PantherPythonFix/run-g++'
+SCRIPT="""#!/bin/sh
+export MACOSX_DEPLOYMENT_TARGET=10.3
+exec %s "${@}"
+"""
+
+def findline(lines, start):
+    """return line starting with given string or -1"""
+    for i in range(len(lines)):
+        if lines[i][:len(start)] == start:
+            return i
+    return -1
+
+def fix(makefile, do_apply):
+    """Fix the Makefile, if required."""
+    fixed = False
+    lines = open(makefile).readlines()
+
+    for old, new in CHANGES:
+        i = findline(lines, new)
+        if i >= 0:
+            # Already fixed
+            continue
+        i = findline(lines, old)
+        if i < 0:
+            print 'fixapplepython23: Python installation not fixed (appears broken)'
+            print 'fixapplepython23: missing line:', old
+            return 2
+        lines[i] = new
+        fixed = True
+
+    if fixed:
+        if do_apply:
+            print 'fixapplepython23: Fix to Apple-installed Python 2.3 applied'
+            os.rename(makefile, makefile + '~')
+            open(makefile, 'w').writelines(lines)
+            return 0
+        else:
+            print 'fixapplepython23: Fix to Apple-installed Python 2.3 should be applied'
+            return 1
+    else:
+        print 'fixapplepython23: No fix needed, appears to have been applied before'
+        return 0
+
+def makescript(filename, compiler):
+    """Create a wrapper script for a compiler"""
+    dirname = os.path.split(filename)[0]
+    if not os.access(dirname, os.X_OK):
+        os.mkdir(dirname, 0755)
+    fp = open(filename, 'w')
+    fp.write(SCRIPT % compiler)
+    fp.close()
+    os.chmod(filename, 0755)
+    print 'fixapplepython23: Created', filename
+
+def main():
+    # Check for -n option
+    if len(sys.argv) > 1 and sys.argv[1] == '-n':
+        do_apply = False
+    else:
+        do_apply = True
+    # First check OS version
+    if sys.byteorder == 'little':
+        # All intel macs are fine
+        print "fixapplypython23: no fix is needed on MacOSX on Intel"
+        sys.exit(0)
+
+    if gestalt.gestalt('sysv') < 0x1030:
+        print 'fixapplepython23: no fix needed on MacOSX < 10.3'
+        sys.exit(0)
+
+    if gestalt.gestalt('sysv') >= 0x1040:
+        print 'fixapplepython23: no fix needed on MacOSX >= 10.4'
+        sys.exit(0)
+
+    # Test that a framework Python is indeed installed
+    if not os.path.exists(MAKEFILE):
+        print 'fixapplepython23: Python framework does not appear to be installed (?), nothing fixed'
+        sys.exit(0)
+    # Check that we can actually write the file
+    if do_apply and not os.access(MAKEFILE, os.W_OK):
+        print 'fixapplepython23: No write permission, please run with "sudo"'
+        sys.exit(2)
+    # Create the shell scripts
+    if do_apply:
+        if not os.access(GCC_SCRIPT, os.X_OK):
+            makescript(GCC_SCRIPT, "gcc")
+        if not os.access(GXX_SCRIPT, os.X_OK):
+            makescript(GXX_SCRIPT, "g++")
+    #  Finally fix the makefile
+    rv = fix(MAKEFILE, do_apply)
+    #sys.exit(rv)
+    sys.exit(0)
+
+if __name__ == '__main__':
+    main()

Added: vendor/Python/current/Mac/Tools/pythonw.c
===================================================================
--- vendor/Python/current/Mac/Tools/pythonw.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/Tools/pythonw.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,17 @@
+/*
+ * This wrapper program executes a python executable hidden inside an
+ * application bundle inside the Python framework. This is needed to run
+ * GUI code: some GUI API's don't work unless the program is inside an
+ * application bundle.
+ */
+#include <unistd.h>
+#include <err.h>
+
+static char Python[] = PYTHONWEXECUTABLE;
+
+int main(int argc, char **argv) {
+	argv[0] = Python;
+	execv(Python, argv);
+	err(1, "execv: %s", Python);
+	/* NOTREACHED */
+}

Added: vendor/Python/current/Mac/scripts/BuildApplet.icns
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Mac/scripts/BuildApplet.icns
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Mac/scripts/BuildApplet.plist
===================================================================
--- vendor/Python/current/Mac/scripts/BuildApplet.plist	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/scripts/BuildApplet.plist	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleDocumentTypes</key>
+	<array>
+		<dict>
+			<key>CFBundleTypeExtensions</key>
+			<array>
+				<string>py</string>
+			</array>
+			<key>CFBundleTypeIconFile</key>
+			<string>PythonSource.icns</string>
+			<key>CFBundleTypeName</key>
+			<string>Python Module</string>
+			<key>CFBundleTypeOSTypes</key>
+			<array>
+				<string>TEXT</string>
+			</array>
+			<key>CFBundleTypeRole</key>
+			<string>Viewer</string>
+		</dict>
+	</array>
+	<key>CFBundleExecutable</key>
+	<string>BuildApplet</string>
+	<key>CFBundleGetInfoString</key>
+	<string>2.5alpha0, (c) 2004 Python Software Foundation.</string>
+	<key>CFBundleIconFile</key>
+	<string>BuildApplet.icns</string>
+	<key>CFBundleIdentifier</key>
+	<string>org.python.buildapplet</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleLongVersionString</key>
+	<string>2.5alpha0, (c) 2004 Python Software Foundation.</string>
+	<key>CFBundleName</key>
+	<string>PythonIDE</string>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>2.5alpha0</string>
+	<key>CFBundleSignature</key>
+	<string>Pide</string>
+	<key>CFBundleVersion</key>
+	<string>2.5alpha0</string>
+	<key>CSResourcesFileMapped</key>
+	<true/>
+	<key>LSRequiresCarbon</key>
+	<true/>
+	<key>NSHumanReadableCopyright</key>
+	<string>(c) 2004 Python Software Foundation.</string>
+</dict>
+</plist>

Added: vendor/Python/current/Mac/scripts/BuildApplet.py
===================================================================
--- vendor/Python/current/Mac/scripts/BuildApplet.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/scripts/BuildApplet.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,149 @@
+"""Create an applet from a Python script.
+
+This puts up a dialog asking for a Python source file ('TEXT').
+The output is a file with the same name but its ".py" suffix dropped.
+It is created by copying an applet template and then adding a 'PYC '
+resource named __main__ containing the compiled, marshalled script.
+"""
+
+
+import sys
+sys.stdout = sys.stderr
+
+import os
+import MacOS
+import EasyDialogs
+import buildtools
+import getopt
+
+if not sys.executable.startswith(sys.exec_prefix):
+    # Oh, the joys of using a python script to bootstrap applicatin bundles
+    # sys.executable points inside the current application bundle. Because this
+    # path contains blanks (two of them actually) this path isn't usable on
+    # #! lines. Reset sys.executable to point to the embedded python interpreter
+    sys.executable = os.path.join(sys.prefix,
+            'Resources/Python.app/Contents/MacOS/Python')
+
+    # Just in case we're not in a framework:
+    if not os.path.exists(sys.executable):
+        sys.executable = os.path.join(sys.exec_prefix,  'bin/python')
+
+def main():
+    try:
+        buildapplet()
+    except buildtools.BuildError, detail:
+        EasyDialogs.Message(detail)
+
+
+def buildapplet():
+    buildtools.DEBUG=1
+
+    # Find the template
+    # (there's no point in proceeding if we can't find it)
+
+    template = buildtools.findtemplate()
+
+    # Ask for source text if not specified in sys.argv[1:]
+
+    if not sys.argv[1:]:
+        filename = EasyDialogs.AskFileForOpen(message='Select Python source or applet:',
+                typeList=('TEXT', 'APPL'))
+        if not filename:
+            return
+        tp, tf = os.path.split(filename)
+        if tf[-3:] == '.py':
+            tf = tf[:-3]
+        else:
+            tf = tf + '.applet'
+        dstfilename = EasyDialogs.AskFileForSave(message='Save application as:',
+                savedFileName=tf)
+        if not dstfilename: return
+        cr, tp = MacOS.GetCreatorAndType(filename)
+        if tp == 'APPL':
+            buildtools.update(template, filename, dstfilename)
+        else:
+            buildtools.process(template, filename, dstfilename, 1)
+    else:
+
+        SHORTOPTS = "o:r:ne:v?PR"
+        LONGOPTS=("output=", "resource=", "noargv", "extra=", "verbose", "help", "python=", "destroot=")
+        try:
+            options, args = getopt.getopt(sys.argv[1:], SHORTOPTS, LONGOPTS)
+        except getopt.error:
+            usage()
+        if options and len(args) > 1:
+            sys.stderr.write("Cannot use options when specifying multiple input files")
+            sys.exit(1)
+        dstfilename = None
+        rsrcfilename = None
+        raw = 0
+        extras = []
+        verbose = None
+        destroot = ''
+        for opt, arg in options:
+            if opt in ('-o', '--output'):
+                dstfilename = arg
+            elif opt in ('-r', '--resource'):
+                rsrcfilename = arg
+            elif opt in ('-n', '--noargv'):
+                raw = 1
+            elif opt in ('-e', '--extra'):
+                if ':' in arg:
+                    arg = arg.split(':')
+                extras.append(arg)
+            elif opt in ('-P', '--python'):
+                # This is a very dirty trick. We set sys.executable
+                # so that bundlebuilder will use this in the #! line
+                # for the applet bootstrap.
+                sys.executable = arg
+            elif opt in ('-v', '--verbose'):
+                verbose = Verbose()
+            elif opt in ('-?', '--help'):
+                usage()
+            elif opt in ('-d', '--destroot'):
+                destroot = arg
+        # On OS9 always be verbose
+        if sys.platform == 'mac' and not verbose:
+            verbose = 'default'
+        # Loop over all files to be processed
+        for filename in args:
+            cr, tp = MacOS.GetCreatorAndType(filename)
+            if tp == 'APPL':
+                buildtools.update(template, filename, dstfilename)
+            else:
+                buildtools.process(template, filename, dstfilename, 1,
+                        rsrcname=rsrcfilename, others=extras, raw=raw,
+                        progress=verbose, destroot=destroot)
+
+def usage():
+    print "BuildApplet creates an application from a Python source file"
+    print "Usage:"
+    print "  BuildApplet     interactive, single file, no options"
+    print "  BuildApplet src1.py src2.py ...   non-interactive multiple file"
+    print "  BuildApplet [options] src.py    non-interactive single file"
+    print "Options:"
+    print "  --output o        Output file; default based on source filename, short -o"
+    print "  --resource r      Resource file; default based on source filename, short -r"
+    print "  --noargv          Build applet without drag-and-drop sys.argv emulation, short -n, OSX only"
+    print "  --extra src[:dst] Extra file to put in .app bundle, short -e, OSX only"
+    print "  --verbose         Verbose, short -v"
+    print "  --help            This message, short -?"
+    sys.exit(1)
+
+class Verbose:
+    """This class mimics EasyDialogs.ProgressBar but prints to stderr"""
+    def __init__(self, *args):
+        if args and args[0]:
+            self.label(args[0])
+
+    def set(self, *args):
+        pass
+
+    def inc(self, *args):
+        pass
+
+    def label(self, str):
+        sys.stderr.write(str+'\n')
+
+if __name__ == '__main__':
+    main()

Added: vendor/Python/current/Mac/scripts/BuildApplet.rsrc
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/Mac/scripts/BuildApplet.rsrc
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/Mac/scripts/bgenall.py
===================================================================
--- vendor/Python/current/Mac/scripts/bgenall.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/scripts/bgenall.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,56 @@
+# bgenall - Generate all bgen-generated modules
+#
+import sys
+import os
+import string
+
+def bgenone(dirname, shortname):
+    os.chdir(dirname)
+    print '%s:'%shortname
+    # Sigh, we don't want to lose CVS history, so two
+    # modules have funny names:
+    if shortname == 'carbonevt':
+        modulename = 'CarbonEvtscan'
+    elif shortname == 'ibcarbon':
+        modulename = 'IBCarbonscan'
+    else:
+        modulename = shortname + 'scan'
+    try:
+        m = __import__(modulename)
+    except:
+        print "Error:", shortname, sys.exc_info()[1]
+        return 0
+    try:
+        m.main()
+    except:
+        print "Error:", shortname, sys.exc_info()[1]
+        return 0
+    return 1
+
+def main():
+    success = []
+    failure = []
+    sys.path.insert(0, os.curdir)
+    if len(sys.argv) > 1:
+        srcdir = sys.argv[1]
+    else:
+        srcdir = os.path.join(os.path.join(sys.prefix, 'Mac'), 'Modules')
+    srcdir = os.path.abspath(srcdir)
+    contents = os.listdir(srcdir)
+    for name in contents:
+        moduledir = os.path.join(srcdir, name)
+        scanmodule = os.path.join(moduledir, name +'scan.py')
+        if os.path.exists(scanmodule):
+            if bgenone(moduledir, name):
+                success.append(name)
+            else:
+                failure.append(name)
+    print 'Done:', string.join(success, ' ')
+    if failure:
+        print 'Failed:', string.join(failure, ' ')
+        return 0
+    return 1
+
+if __name__ == '__main__':
+    rv = main()
+    sys.exit(not rv)

Added: vendor/Python/current/Mac/scripts/buildpkg.py
===================================================================
--- vendor/Python/current/Mac/scripts/buildpkg.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/scripts/buildpkg.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,484 @@
+#!/usr/bin/env python
+
+"""buildpkg.py -- Build OS X packages for Apple's Installer.app.
+
+This is an experimental command-line tool for building packages to be
+installed with the Mac OS X Installer.app application.
+
+It is much inspired by Apple's GUI tool called PackageMaker.app, that
+seems to be part of the OS X developer tools installed in the folder
+/Developer/Applications. But apparently there are other free tools to
+do the same thing which are also named PackageMaker like Brian Hill's
+one:
+
+  http://personalpages.tds.net/~brian_hill/packagemaker.html
+
+Beware of the multi-package features of Installer.app (which are not
+yet supported here) that can potentially screw-up your installation
+and are discussed in these articles on Stepwise:
+
+  http://www.stepwise.com/Articles/Technical/Packages/InstallerWoes.html
+  http://www.stepwise.com/Articles/Technical/Packages/InstallerOnX.html
+
+Beside using the PackageMaker class directly, by importing it inside
+another module, say, there are additional ways of using this module:
+the top-level buildPackage() function provides a shortcut to the same
+feature and is also called when using this module from the command-
+line.
+
+    ****************************************************************
+    NOTE: For now you should be able to run this even on a non-OS X
+          system and get something similar to a package, but without
+          the real archive (needs pax) and bom files (needs mkbom)
+          inside! This is only for providing a chance for testing to
+          folks without OS X.
+    ****************************************************************
+
+TODO:
+  - test pre-process and post-process scripts (Python ones?)
+  - handle multi-volume packages (?)
+  - integrate into distutils (?)
+
+Dinu C. Gherman,
+gherman at europemail.com
+November 2001
+
+!! USE AT YOUR OWN RISK !!
+"""
+
+__version__ = 0.2
+__license__ = "FreeBSD"
+
+
+import os, sys, glob, fnmatch, shutil, string, copy, getopt
+from os.path import basename, dirname, join, islink, isdir, isfile
+
+Error = "buildpkg.Error"
+
+PKG_INFO_FIELDS = """\
+Title
+Version
+Description
+DefaultLocation
+DeleteWarning
+NeedsAuthorization
+DisableStop
+UseUserMask
+Application
+Relocatable
+Required
+InstallOnly
+RequiresReboot
+RootVolumeOnly
+LongFilenames
+LibrarySubdirectory
+AllowBackRev
+OverwritePermissions
+InstallFat\
+"""
+
+######################################################################
+# Helpers
+######################################################################
+
+# Convenience class, as suggested by /F.
+
+class GlobDirectoryWalker:
+    "A forward iterator that traverses files in a directory tree."
+
+    def __init__(self, directory, pattern="*"):
+        self.stack = [directory]
+        self.pattern = pattern
+        self.files = []
+        self.index = 0
+
+
+    def __getitem__(self, index):
+        while 1:
+            try:
+                file = self.files[self.index]
+                self.index = self.index + 1
+            except IndexError:
+                # pop next directory from stack
+                self.directory = self.stack.pop()
+                self.files = os.listdir(self.directory)
+                self.index = 0
+            else:
+                # got a filename
+                fullname = join(self.directory, file)
+                if isdir(fullname) and not islink(fullname):
+                    self.stack.append(fullname)
+                if fnmatch.fnmatch(file, self.pattern):
+                    return fullname
+
+
+######################################################################
+# The real thing
+######################################################################
+
+class PackageMaker:
+    """A class to generate packages for Mac OS X.
+
+    This is intended to create OS X packages (with extension .pkg)
+    containing archives of arbitrary files that the Installer.app
+    will be able to handle.
+
+    As of now, PackageMaker instances need to be created with the
+    title, version and description of the package to be built.
+    The package is built after calling the instance method
+    build(root, **options). It has the same name as the constructor's
+    title argument plus a '.pkg' extension and is located in the same
+    parent folder that contains the root folder.
+
+    E.g. this will create a package folder /my/space/distutils.pkg/:
+
+      pm = PackageMaker("distutils", "1.0.2", "Python distutils.")
+      pm.build("/my/space/distutils")
+    """
+
+    packageInfoDefaults = {
+        'Title': None,
+        'Version': None,
+        'Description': '',
+        'DefaultLocation': '/',
+        'DeleteWarning': '',
+        'NeedsAuthorization': 'NO',
+        'DisableStop': 'NO',
+        'UseUserMask': 'YES',
+        'Application': 'NO',
+        'Relocatable': 'YES',
+        'Required': 'NO',
+        'InstallOnly': 'NO',
+        'RequiresReboot': 'NO',
+        'RootVolumeOnly' : 'NO',
+        'InstallFat': 'NO',
+        'LongFilenames': 'YES',
+        'LibrarySubdirectory': 'Standard',
+        'AllowBackRev': 'YES',
+        'OverwritePermissions': 'NO',
+        }
+
+
+    def __init__(self, title, version, desc):
+        "Init. with mandatory title/version/description arguments."
+
+        info = {"Title": title, "Version": version, "Description": desc}
+        self.packageInfo = copy.deepcopy(self.packageInfoDefaults)
+        self.packageInfo.update(info)
+
+        # variables set later
+        self.packageRootFolder = None
+        self.packageResourceFolder = None
+        self.sourceFolder = None
+        self.resourceFolder = None
+
+
+    def build(self, root, resources=None, **options):
+        """Create a package for some given root folder.
+
+        With no 'resources' argument set it is assumed to be the same
+        as the root directory. Option items replace the default ones
+        in the package info.
+        """
+
+        # set folder attributes
+        self.sourceFolder = root
+        if resources == None:
+            self.resourceFolder = root
+        else:
+            self.resourceFolder = resources
+
+        # replace default option settings with user ones if provided
+        fields = self. packageInfoDefaults.keys()
+        for k, v in options.items():
+            if k in fields:
+                self.packageInfo[k] = v
+            elif not k in ["OutputDir"]:
+                raise Error, "Unknown package option: %s" % k
+
+        # Check where we should leave the output. Default is current directory
+        outputdir = options.get("OutputDir", os.getcwd())
+        packageName = self.packageInfo["Title"]
+        self.PackageRootFolder = os.path.join(outputdir, packageName + ".pkg")
+
+        # do what needs to be done
+        self._makeFolders()
+        self._addInfo()
+        self._addBom()
+        self._addArchive()
+        self._addResources()
+        self._addSizes()
+        self._addLoc()
+
+
+    def _makeFolders(self):
+        "Create package folder structure."
+
+        # Not sure if the package name should contain the version or not...
+        # packageName = "%s-%s" % (self.packageInfo["Title"],
+        #                          self.packageInfo["Version"]) # ??
+
+        contFolder = join(self.PackageRootFolder, "Contents")
+        self.packageResourceFolder = join(contFolder, "Resources")
+        os.mkdir(self.PackageRootFolder)
+        os.mkdir(contFolder)
+        os.mkdir(self.packageResourceFolder)
+
+    def _addInfo(self):
+        "Write .info file containing installing options."
+
+        # Not sure if options in PKG_INFO_FIELDS are complete...
+
+        info = ""
+        for f in string.split(PKG_INFO_FIELDS, "\n"):
+            if self.packageInfo.has_key(f):
+                info = info + "%s %%(%s)s\n" % (f, f)
+        info = info % self.packageInfo
+        base = self.packageInfo["Title"] + ".info"
+        path = join(self.packageResourceFolder, base)
+        f = open(path, "w")
+        f.write(info)
+
+
+    def _addBom(self):
+        "Write .bom file containing 'Bill of Materials'."
+
+        # Currently ignores if the 'mkbom' tool is not available.
+
+        try:
+            base = self.packageInfo["Title"] + ".bom"
+            bomPath = join(self.packageResourceFolder, base)
+            cmd = "mkbom %s %s" % (self.sourceFolder, bomPath)
+            res = os.system(cmd)
+        except:
+            pass
+
+
+    def _addArchive(self):
+        "Write .pax.gz file, a compressed archive using pax/gzip."
+
+        # Currently ignores if the 'pax' tool is not available.
+
+        cwd = os.getcwd()
+
+        # create archive
+        os.chdir(self.sourceFolder)
+        base = basename(self.packageInfo["Title"]) + ".pax"
+        self.archPath = join(self.packageResourceFolder, base)
+        cmd = "pax -w -f %s %s" % (self.archPath, ".")
+        res = os.system(cmd)
+
+        # compress archive
+        cmd = "gzip %s" % self.archPath
+        res = os.system(cmd)
+        os.chdir(cwd)
+
+
+    def _addResources(self):
+        "Add Welcome/ReadMe/License files, .lproj folders and scripts."
+
+        # Currently we just copy everything that matches the allowed
+        # filenames. So, it's left to Installer.app to deal with the
+        # same file available in multiple formats...
+
+        if not self.resourceFolder:
+            return
+
+        # find candidate resource files (txt html rtf rtfd/ or lproj/)
+        allFiles = []
+        for pat in string.split("*.txt *.html *.rtf *.rtfd *.lproj", " "):
+            pattern = join(self.resourceFolder, pat)
+            allFiles = allFiles + glob.glob(pattern)
+
+        # find pre-process and post-process scripts
+        # naming convention: packageName.{pre,post}_{upgrade,install}
+        # Alternatively the filenames can be {pre,post}_{upgrade,install}
+        # in which case we prepend the package name
+        packageName = self.packageInfo["Title"]
+        for pat in ("*upgrade", "*install", "*flight"):
+            pattern = join(self.resourceFolder, packageName + pat)
+            pattern2 = join(self.resourceFolder, pat)
+            allFiles = allFiles + glob.glob(pattern)
+            allFiles = allFiles + glob.glob(pattern2)
+
+        # check name patterns
+        files = []
+        for f in allFiles:
+            for s in ("Welcome", "License", "ReadMe"):
+                if string.find(basename(f), s) == 0:
+                    files.append((f, f))
+            if f[-6:] == ".lproj":
+                files.append((f, f))
+            elif basename(f) in ["pre_upgrade", "pre_install", "post_upgrade", "post_install"]:
+                files.append((f, packageName+"."+basename(f)))
+            elif basename(f) in ["preflight", "postflight"]:
+                files.append((f, f))
+            elif f[-8:] == "_upgrade":
+                files.append((f,f))
+            elif f[-8:] == "_install":
+                files.append((f,f))
+
+        # copy files
+        for src, dst in files:
+            src = basename(src)
+            dst = basename(dst)
+            f = join(self.resourceFolder, src)
+            if isfile(f):
+                shutil.copy(f, os.path.join(self.packageResourceFolder, dst))
+            elif isdir(f):
+                # special case for .rtfd and .lproj folders...
+                d = join(self.packageResourceFolder, dst)
+                os.mkdir(d)
+                files = GlobDirectoryWalker(f)
+                for file in files:
+                    shutil.copy(file, d)
+
+
+    def _addSizes(self):
+        "Write .sizes file with info about number and size of files."
+
+        # Not sure if this is correct, but 'installedSize' and
+        # 'zippedSize' are now in Bytes. Maybe blocks are needed?
+        # Well, Installer.app doesn't seem to care anyway, saying
+        # the installation needs 100+ MB...
+
+        numFiles = 0
+        installedSize = 0
+        zippedSize = 0
+
+        files = GlobDirectoryWalker(self.sourceFolder)
+        for f in files:
+            numFiles = numFiles + 1
+            installedSize = installedSize + os.lstat(f)[6]
+
+        try:
+            zippedSize = os.stat(self.archPath+ ".gz")[6]
+        except OSError: # ignore error
+            pass
+        base = self.packageInfo["Title"] + ".sizes"
+        f = open(join(self.packageResourceFolder, base), "w")
+        format = "NumFiles %d\nInstalledSize %d\nCompressedSize %d\n"
+        f.write(format % (numFiles, installedSize, zippedSize))
+
+    def _addLoc(self):
+        "Write .loc file."
+        base = self.packageInfo["Title"] + ".loc"
+        f = open(join(self.packageResourceFolder, base), "w")
+        f.write('/')
+
+# Shortcut function interface
+
+def buildPackage(*args, **options):
+    "A Shortcut function for building a package."
+
+    o = options
+    title, version, desc = o["Title"], o["Version"], o["Description"]
+    pm = PackageMaker(title, version, desc)
+    apply(pm.build, list(args), options)
+
+
+######################################################################
+# Tests
+######################################################################
+
+def test0():
+    "Vanilla test for the distutils distribution."
+
+    pm = PackageMaker("distutils2", "1.0.2", "Python distutils package.")
+    pm.build("/Users/dinu/Desktop/distutils2")
+
+
+def test1():
+    "Test for the reportlab distribution with modified options."
+
+    pm = PackageMaker("reportlab", "1.10",
+                      "ReportLab's Open Source PDF toolkit.")
+    pm.build(root="/Users/dinu/Desktop/reportlab",
+             DefaultLocation="/Applications/ReportLab",
+             Relocatable="YES")
+
+def test2():
+    "Shortcut test for the reportlab distribution with modified options."
+
+    buildPackage(
+        "/Users/dinu/Desktop/reportlab",
+        Title="reportlab",
+        Version="1.10",
+        Description="ReportLab's Open Source PDF toolkit.",
+        DefaultLocation="/Applications/ReportLab",
+        Relocatable="YES")
+
+
+######################################################################
+# Command-line interface
+######################################################################
+
+def printUsage():
+    "Print usage message."
+
+    format = "Usage: %s <opts1> [<opts2>] <root> [<resources>]"
+    print format % basename(sys.argv[0])
+    print
+    print "       with arguments:"
+    print "           (mandatory) root:         the package root folder"
+    print "           (optional)  resources:    the package resources folder"
+    print
+    print "       and options:"
+    print "           (mandatory) opts1:"
+    mandatoryKeys = string.split("Title Version Description", " ")
+    for k in mandatoryKeys:
+        print "               --%s" % k
+    print "           (optional) opts2: (with default values)"
+
+    pmDefaults = PackageMaker.packageInfoDefaults
+    optionalKeys = pmDefaults.keys()
+    for k in mandatoryKeys:
+        optionalKeys.remove(k)
+    optionalKeys.sort()
+    maxKeyLen = max(map(len, optionalKeys))
+    for k in optionalKeys:
+        format = "               --%%s:%s %%s"
+        format = format % (" " * (maxKeyLen-len(k)))
+        print format % (k, repr(pmDefaults[k]))
+
+
+def main():
+    "Command-line interface."
+
+    shortOpts = ""
+    keys = PackageMaker.packageInfoDefaults.keys()
+    longOpts = map(lambda k: k+"=", keys)
+
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], shortOpts, longOpts)
+    except getopt.GetoptError, details:
+        print details
+        printUsage()
+        return
+
+    optsDict = {}
+    for k, v in opts:
+        optsDict[k[2:]] = v
+
+    ok = optsDict.keys()
+    if not (1 <= len(args) <= 2):
+        print "No argument given!"
+    elif not ("Title" in ok and \
+              "Version" in ok and \
+              "Description" in ok):
+        print "Missing mandatory option!"
+    else:
+        apply(buildPackage, args, optsDict)
+        return
+
+    printUsage()
+
+    # sample use:
+    # buildpkg.py --Title=distutils \
+    #             --Version=1.0.2 \
+    #             --Description="Python distutils package." \
+    #             /Users/dinu/Desktop/distutils
+
+
+if __name__ == "__main__":
+    main()

Added: vendor/Python/current/Mac/scripts/cachersrc.py
===================================================================
--- vendor/Python/current/Mac/scripts/cachersrc.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/scripts/cachersrc.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,44 @@
+# Scan the tree passed as argv[0] for .rsrc files, skipping .rsrc.df.rsrc
+# files, and open these. The effect of this is to create the .rsrc.df.rsrc
+# cache files if needed.
+# These are needed on OSX: the .rsrc files are in reality AppleSingle-encoded
+# files. We decode the resources into a datafork-based resource file.
+
+import macresource
+import os
+import sys
+import getopt
+
+class NoArgsError(Exception):
+    pass
+
+def handler((verbose, force), dirname, fnames):
+    for fn in fnames:
+        if fn[-5:] == '.rsrc' and fn[-13:] != '.rsrc.df.rsrc':
+            if force:
+                try:
+                    os.unlink(os.path.join(dirname, fn + '.df.rsrc'))
+                except IOError:
+                    pass
+            macresource.open_pathname(os.path.join(dirname, fn), verbose=verbose)
+
+def main():
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], 'vf')
+        if not args:
+            raise NoArgsError
+    except (getopt.GetoptError, NoArgsError):
+        sys.stderr.write('Usage: cachersrc.py dirname ...\n')
+        sys.exit(1)
+    verbose = 0
+    force = 0
+    for o, v in opts:
+        if o == '-v':
+            verbose = 1
+        if o == '-f':
+            force = 1
+    for dir in sys.argv[1:]:
+        os.path.walk(dir, handler, (verbose, force))
+
+if __name__ == '__main__':
+    main()

Added: vendor/Python/current/Mac/scripts/errors.txt
===================================================================
--- vendor/Python/current/Mac/scripts/errors.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/scripts/errors.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1852 @@
+-32768	svTempDisable	svTempDisable
+-32640	svDisabled	Reserve range -32640 to -32768 for Apple temp disables.
+-32615	fontNotOutlineErr	bitmap font passed to routine that does outlines only
+-30788	kURL68kNotSupportedError	kURL68kNotSupportedError
+-30787	kURLAccessNotAvailableError	kURLAccessNotAvailableError
+-30786	kURLInvalidConfigurationError	kURLInvalidConfigurationError
+-30785	kURLExtensionFailureError	kURLExtensionFailureError
+-30783	kURLFileEmptyError	kURLFileEmptyError
+-30781	kURLInvalidCallError	kURLInvalidCallError
+-30780	kURLUnsettablePropertyError	kURLUnsettablePropertyError
+-30779	kURLPropertyBufferTooSmallError	kURLPropertyBufferTooSmallError
+-30778	kURLUnknownPropertyError	kURLUnknownPropertyError
+-30777	kURLPropertyNotYetKnownError	kURLPropertyNotYetKnownError
+-30776	kURLAuthenticationError	kURLAuthenticationError
+-30775	kURLServerBusyError	kURLServerBusyError
+-30774	kURLUnsupportedSchemeError	kURLUnsupportedSchemeError
+-30773	kURLInvalidURLError	kURLInvalidURLError
+-30772	kURLDestinationExistsError	kURLDestinationExistsError
+-30771	kURLProgressAlreadyDisplayedError	kURLProgressAlreadyDisplayedError
+-30770	kURLInvalidURLReferenceError	kURLInvalidURLReferenceError
+-30599	controlHandleInvalidErr	controlHandleInvalidErr
+-30597	controlInvalidDataVersionErr	controlInvalidDataVersionErr
+-30596	errItemNotControl	errItemNotControl
+-30595	errCantEmbedRoot	errCantEmbedRoot
+-30594	errCantEmbedIntoSelf	errCantEmbedIntoSelf
+-30593	errWindowRegionCodeInvalid	errWindowRegionCodeInvalid
+-30592	errControlHiddenOrDisabled	errControlHiddenOrDisabled
+-30591	errDataSizeMismatch	errDataSizeMismatch
+-30590	errControlIsNotEmbedder	errControlIsNotEmbedder
+-30589	errControlsAlreadyExist	errControlsAlreadyExist
+-30588	errInvalidPartCode	errInvalidPartCode
+-30587	errRootAlreadyExists	errRootAlreadyExists
+-30586	errNoRootControl	errNoRootControl
+-30585	errCouldntSetFocus	errCouldntSetFocus
+-30584	errUnknownControl	errUnknownControl
+-30583	errWindowDoesntSupportFocus	errWindowDoesntSupportFocus
+-30582	errControlDoesntSupportFocus	errControlDoesntSupportFocus
+-30581	errDataNotSupported	errDataNotSupported
+-30580	errMessageNotSupported	errMessageNotSupported
+-30567	themeMonitorDepthNotSupportedErr	theme not supported at monitor depth
+-30566	themeScriptFontNotFoundErr	theme font requested for uninstalled script system
+-30565	themeBadCursorIndexErr	themeBadCursorIndexErr
+-30564	themeHasNoAccentsErr	themeHasNoAccentsErr
+-30563	themeBadTextColorErr	themeBadTextColorErr
+-30562	themeProcessNotRegisteredErr	themeProcessNotRegisteredErr
+-30561	themeProcessRegisteredErr	themeProcessRegisteredErr
+-30560	themeInvalidBrushErr	pattern index invalid
+-30555	qtvrUninitialized	qtvrUninitialized
+-30554	qtvrLibraryLoadErr	qtvrLibraryLoadErr
+-30553	streamingNodeNotReadyErr	streamingNodeNotReadyErr
+-30552	noMemoryNodeFailedInitialize	noMemoryNodeFailedInitialize
+-30551	invalidHotSpotIDErr	invalidHotSpotIDErr
+-30550	invalidNodeFormatErr	invalidNodeFormatErr
+-30549	limitReachedErr	limitReachedErr
+-30548	settingNotSupportedByNodeErr	settingNotSupportedByNodeErr
+-30547	propertyNotSupportedByNodeErr	propertyNotSupportedByNodeErr
+-30546	timeNotInViewErr	timeNotInViewErr
+-30545	invalidViewStateErr	invalidViewStateErr
+-30544	invalidNodeIDErr	invalidNodeIDErr
+-30543	selectorNotSupportedByNodeErr	selectorNotSupportedByNodeErr
+-30542	callNotSupportedByNodeErr	callNotSupportedByNodeErr
+-30541	constraintReachedErr	constraintReachedErr
+-30540	notAQTVRMovieErr	notAQTVRMovieErr
+-30532	kFBCnoSuchHit	kFBCnoSuchHit
+-30531	kFBCbadSearchSession	kFBCbadSearchSession
+-30530	kFBCindexDiskIOFailed	kFBCindexDiskIOFailed
+-30529	kFBCsummarizationCanceled	kFBCsummarizationCanceled
+-30528	kFBCbadIndexFileVersion	kFBCbadIndexFileVersion
+-30527	kFBCanalysisNotAvailable	kFBCanalysisNotAvailable
+-30526	kFBCillegalSessionChange	tried to add/remove vols to a session
+-30525	kFBCsomeFilesNotIndexed	kFBCsomeFilesNotIndexed
+-30524	kFBCsearchFailed	kFBCsearchFailed
+-30523	kFBCindexNotAvailable	kFBCindexNotAvailable
+-30522	kFBCindexFileDestroyed	kFBCindexFileDestroyed
+-30521	kFBCaccessCanceled	kFBCaccessCanceled
+-30520	kFBCindexingCanceled	kFBCindexingCanceled
+-30519	kFBCnoSearchSession	kFBCnoSearchSession
+-30518	kFBCindexNotFound	kFBCindexNotFound
+-30517	kFBCflushFailed	kFBCflushFailed
+-30516	kFBCaddDocFailed	kFBCaddDocFailed
+-30515	kFBCaccessorStoreFailed	kFBCaccessorStoreFailed
+-30514	kFBCindexCreationFailed	couldn't create index
+-30513	kFBCmergingFailed	couldn't merge index files
+-30512	kFBCtokenizationFailed	couldn't read from document or query
+-30511	kFBCmoveFailed	V-Twin exception caught
+-30510	kFBCdeletionFailed	V-Twin exception caught
+-30509	kFBCcommitFailed	V-Twin exception caught
+-30508	kFBCindexingFailed	V-Twin exception caught
+-30507	kFBCvalidationFailed	V-Twin exception caught
+-30506	kFBCcompactionFailed	V-Twin exception caught
+-30505	kFBCbadIndexFile	bad FSSpec, or bad data in file
+-30504	kFBCfileNotIndexed	kFBCfileNotIndexed
+-30503	kFBCbadParam	kFBCbadParam
+-30502	kFBCallocFailed	probably low memory
+-30501	kFBCnoIndexesFound	kFBCnoIndexesFound
+-30500	kFBCvTwinExceptionErr	no telling what it was
+-30450	kDSpStereoContextErr	kDSpStereoContextErr
+-30449	kDSpInternalErr	kDSpInternalErr
+-30448	kDSpConfirmSwitchWarning	kDSpConfirmSwitchWarning
+-30447	kDSpFrameRateNotReadyErr	kDSpFrameRateNotReadyErr
+-30446	kDSpContextNotFoundErr	kDSpContextNotFoundErr
+-30445	kDSpContextNotReservedErr	kDSpContextNotReservedErr
+-30444	kDSpContextAlreadyReservedErr	kDSpContextAlreadyReservedErr
+-30443	kDSpInvalidAttributesErr	kDSpInvalidAttributesErr
+-30442	kDSpInvalidContextErr	kDSpInvalidContextErr
+-30441	kDSpSystemSWTooOldErr	kDSpSystemSWTooOldErr
+-30440	kDSpNotInitializedErr	kDSpNotInitializedErr
+-30429	kISpListBusyErr	kISpListBusyErr
+-30428	kISpDeviceActiveErr	kISpDeviceActiveErr
+-30427	kISpSystemActiveErr	kISpSystemActiveErr
+-30426	kISpDeviceInactiveErr	kISpDeviceInactiveErr
+-30425	kISpSystemInactiveErr	kISpSystemInactiveErr
+-30424	kISpElementNotInListErr	kISpElementNotInListErr
+-30423	kISpElementInListErr	kISpElementInListErr
+-30422	kISpBufferToSmallErr	kISpBufferToSmallErr
+-30421	kISpSystemListErr	kISpSystemListErr
+-30420	kISpInternalErr	kISpInternalErr
+-30399	kNSpJoinFailedErr	kNSpJoinFailedErr
+-30398	kNSpCantBlockErr	kNSpCantBlockErr
+-30397	kNSpMessageTooBigErr	kNSpMessageTooBigErr
+-30396	kNSpSendFailedErr	kNSpSendFailedErr
+-30395	kNSpConnectFailedErr	kNSpConnectFailedErr
+-30394	kNSpGameTerminatedErr	kNSpGameTerminatedErr
+-30393	kNSpTimeoutErr	kNSpTimeoutErr
+-30392	kNSpInvalidProtocolListErr	kNSpInvalidProtocolListErr
+-30391	kNSpInvalidProtocolRefErr	kNSpInvalidProtocolRefErr
+-30390	kNSpInvalidDefinitionErr	kNSpInvalidDefinitionErr
+-30389	kNSpAddPlayerFailedErr	kNSpAddPlayerFailedErr
+-30388	kNSpCreateGroupFailedErr	kNSpCreateGroupFailedErr
+-30387	kNSpNoHostVolunteersErr	kNSpNoHostVolunteersErr
+-30386	kNSpNoGroupsErr	kNSpNoGroupsErr
+-30385	kNSpNoPlayersErr	kNSpNoPlayersErr
+-30384	kNSpInvalidGroupIDErr	kNSpInvalidGroupIDErr
+-30383	kNSpInvalidPlayerIDErr	kNSpInvalidPlayerIDErr
+-30382	kNSpNameRequiredErr	kNSpNameRequiredErr
+-30381	kNSpFeatureNotImplementedErr	kNSpFeatureNotImplementedErr
+-30380	kNSpAddressInUseErr	kNSpAddressInUseErr
+-30379	kNSpRemovePlayerFailedErr	kNSpRemovePlayerFailedErr
+-30378	kNSpFreeQExhaustedErr	kNSpFreeQExhaustedErr
+-30377	kNSpInvalidAddressErr	kNSpInvalidAddressErr
+-30376	kNSpNotAdvertisingErr	kNSpNotAdvertisingErr
+-30374	kNSpAlreadyAdvertisingErr	kNSpAlreadyAdvertisingErr
+-30373	kNSpMemAllocationErr	kNSpMemAllocationErr
+-30371	kNSpOTVersionTooOldErr	kNSpOTVersionTooOldErr
+-30370	kNSpOTNotPresentErr	kNSpOTNotPresentErr
+-30369	kNSpInvalidParameterErr	kNSpInvalidParameterErr
+-30367	kNSpInvalidGameRefErr	kNSpInvalidGameRefErr
+-30366	kNSpProtocolNotAvailableErr	kNSpProtocolNotAvailableErr
+-30365	kNSpHostFailedErr	kNSpHostFailedErr
+-30364	kNSpPipeFullErr	kNSpPipeFullErr
+-30362	kNSpTopologyNotSupportedErr	kNSpTopologyNotSupportedErr
+-30361	kNSpAlreadyInitializedErr	kNSpAlreadyInitializedErr
+-30360	kNSpInitializationFailedErr	kNSpInitializationFailedErr
+-30344	kSSpScaleToZeroErr	kSSpScaleToZeroErr
+-30343	kSSpParallelUpVectorErr	kSSpParallelUpVectorErr
+-30342	kSSpCantInstallErr	kSSpCantInstallErr
+-30341	kSSpVersionErr	kSSpVersionErr
+-30340	kSSpInternalErr	kSSpInternalErr
+-30049	kALMInternalErr	kALMInternalErr
+-30048	kALMGroupNotFoundErr	kALMGroupNotFoundErr
+-30047	kALMNoSuchModuleErr	kALMNoSuchModuleErr
+-30046	kALMModuleCommunicationErr	kALMModuleCommunicationErr
+-30045	kALMDuplicateModuleErr	kALMDuplicateModuleErr
+-30044	kALMInstallationErr	kALMInstallationErr
+-30043	kALMDeferSwitchErr	kALMDeferSwitchErr
+-30042	kALMRebootFlagsLevelErr	kALMRebootFlagsLevelErr
+-30029	kLocalesDefaultDisplayStatus	Requested display locale unavailable, used default
+-30002	kLocalesTableFormatErr	kLocalesTableFormatErr
+-30001	kLocalesBufferTooSmallErr	kLocalesBufferTooSmallErr
+-29589	kFNSNameNotFoundErr	The name with the requested paramters was not found
+-29587	kFNSBadFlattenedSizeErr	flattened size didn't match input or was too small
+-29586	kFNSInsufficientDataErr	insufficient data for the operation
+-29585	kFNSMismatchErr	reference didn't match or wasn't found in profile
+-29584	kFNSDuplicateReferenceErr	the ref. being added is already in the profile
+-29583	kFNSBadProfileVersionErr	profile version is out of known range
+-29582	kFNSInvalidProfileErr	profile is NULL or otherwise bad
+-29581	kFNSBadReferenceVersionErr	ref. version is out of known range
+-29580	kFNSInvalidReferenceErr	ref. was NULL or otherwise bad
+-29507	kCollateInvalidCollationRef	kCollateInvalidCollationRef
+-29506	kCollateBufferTooSmall	kCollateBufferTooSmall
+-29505	kCollateInvalidChar	kCollateInvalidChar
+-29504	kCollatePatternNotFoundErr	kCollatePatternNotFoundErr
+-29503	kCollateUnicodeConvertFailedErr	kCollateUnicodeConvertFailedErr
+-29502	kCollateMissingUnicodeTableErr	kCollateMissingUnicodeTableErr
+-29501	kCollateInvalidOptions	kCollateInvalidOptions
+-29500	kCollateAttributesNotFoundErr	kCollateAttributesNotFoundErr
+-29299	kMPInvalidIDErr	kMPInvalidIDErr
+-29298	kMPInsufficientResourcesErr	kMPInsufficientResourcesErr
+-29297	kMPTaskAbortedErr	kMPTaskAbortedErr
+-29296	kMPTimeoutErr	kMPTimeoutErr
+-29295	kMPDeletedErr	kMPDeletedErr
+-29293	kMPBlueBlockingErr	kMPBlueBlockingErr
+-29292	kMPTaskStoppedErr	A convention used with MPThrowException.
+-29291	kMPTaskBlockedErr	kMPTaskBlockedErr
+-29290	kMPTaskCreatedErr	kMPTaskCreatedErr
+-29289	kMPProcessTerminatedErr	kMPProcessTerminatedErr
+-29288	kMPProcessCreatedErr	kMPProcessCreatedErr
+-29276	kMPPrivilegedErr	kMPPrivilegedErr
+-29275	kMPIterationEndErr	kMPIterationEndErr
+-25341	kUCTextBreakLocatorMissingType	Unicode text break error
+-25340	kUCOutputBufferTooSmall	Output buffer too small for Unicode string result
+-25318	errKCCreateChainFailed	errKCCreateChainFailed
+-25317	errKCDataNotModifiable	errKCDataNotModifiable
+-25316	errKCDataNotAvailable	errKCDataNotAvailable
+-25315	errKCInteractionRequired	errKCInteractionRequired
+-25314	errKCNoPolicyModule	errKCNoPolicyModule
+-25313	errKCNoCertificateModule	errKCNoCertificateModule
+-25312	errKCNoStorageModule	errKCNoStorageModule
+-25311	errKCKeySizeNotAllowed	errKCKeySizeNotAllowed
+-25310	errKCWrongKCVersion	errKCWrongKCVersion
+-25309	errKCReadOnlyAttr	errKCReadOnlyAttr
+-25308	errKCInteractionNotAllowed	errKCInteractionNotAllowed
+-25307	errKCNoDefaultKeychain	errKCNoDefaultKeychain
+-25306	errKCNoSuchClass	errKCNoSuchClass
+-25305	errKCInvalidSearchRef	errKCInvalidSearchRef
+-25304	errKCInvalidItemRef	errKCInvalidItemRef
+-25303	errKCNoSuchAttr	errKCNoSuchAttr
+-25302	errKCDataTooLarge	errKCDataTooLarge
+-25301	errKCBufferTooSmall	errKCBufferTooSmall
+-25300	errKCItemNotFound	errKCItemNotFound
+-25299	errKCDuplicateItem	errKCDuplicateItem
+-25298	errKCInvalidCallback	errKCInvalidCallback
+-25297	errKCDuplicateCallback	errKCDuplicateCallback
+-25296	errKCDuplicateKeychain	errKCDuplicateKeychain
+-25295	errKCInvalidKeychain	errKCInvalidKeychain
+-25294	errKCNoSuchKeychain	errKCNoSuchKeychain
+-25293	errKCAuthFailed	errKCAuthFailed
+-25292	errKCReadOnly	errKCReadOnly
+-25291	errKCNotAvailable	errKCNotAvailable
+-25280	printerStatusOpCodeNotSupportedErr	printerStatusOpCodeNotSupportedErr
+-22018	kTXNOutsideOfFrameErr	kTXNOutsideOfFrameErr
+-22017	kTXNOutsideOfLineErr	kTXNOutsideOfLineErr
+-22016	kTXNATSUIIsNotInstalledErr	kTXNATSUIIsNotInstalledErr
+-22015	kTXNDataTypeNotAllowedErr	kTXNDataTypeNotAllowedErr
+-22014	kTXNCopyNotAllowedInEchoModeErr	kTXNCopyNotAllowedInEchoModeErr
+-22013	kTXNCannotTurnTSMOffWhenUsingUnicodeErr	kTXNCannotTurnTSMOffWhenUsingUnicodeErr
+-22012	kTXNAlreadyInitializedErr	kTXNAlreadyInitializedErr
+-22011	kTXNInvalidRunIndex	kTXNInvalidRunIndex
+-22010	kTXNSomeOrAllTagsInvalidForRunErr	kTXNSomeOrAllTagsInvalidForRunErr
+-22009	kTXNAttributeTagInvalidForRunErr	dataValue is set to this per invalid tag
+-22008	kTXNNoMatchErr	kTXNNoMatchErr
+-22007	kTXNRunIndexOutofBoundsErr	kTXNRunIndexOutofBoundsErr
+-22006	kTXNCannotSetAutoIndentErr	kTXNCannotSetAutoIndentErr
+-22005	kTXNBadDefaultFileTypeWarning	kTXNBadDefaultFileTypeWarning
+-22004	kTXNUserCanceledOperationErr	kTXNUserCanceledOperationErr
+-22003	kTXNIllegalToCrossDataBoundariesErr	kTXNIllegalToCrossDataBoundariesErr
+-22002	kTXNInvalidFrameIDErr	kTXNInvalidFrameIDErr
+-22001	kTXNCannotAddFrameErr	kTXNCannotAddFrameErr
+-22000	kTXNEndIterationErr	kTXNEndIterationErr
+-20002	invalidIndexErr	The recordIndex parameter is not valid.
+-20001	recordDataTooBigErr	The record data is bigger than buffer size (1024 bytes).
+-20000	unknownInsertModeErr	There is no such an insert mode.
+-14002	kModemScriptMissing	kModemScriptMissing
+-14001	kModemPreferencesMissing	kModemPreferencesMissing
+-14000	kModemOutOfMemory	kModemOutOfMemory
+-13950	kHIDBaseError	kHIDBaseError
+-13949	kHIDNullStateErr	kHIDNullStateErr
+-13948	kHIDBufferTooSmallErr	kHIDBufferTooSmallErr
+-13947	kHIDValueOutOfRangeErr	kHIDValueOutOfRangeErr
+-13946	kHIDUsageNotFoundErr	kHIDUsageNotFoundErr
+-13945	kHIDNotValueArrayErr	kHIDNotValueArrayErr
+-13944	kHIDInvalidPreparsedDataErr	kHIDInvalidPreparsedDataErr
+-13943	kHIDIncompatibleReportErr	kHIDIncompatibleReportErr
+-13942	kHIDBadLogPhysValuesErr	kHIDBadLogPhysValuesErr
+-13941	kHIDInvalidReportTypeErr	kHIDInvalidReportTypeErr
+-13940	kHIDInvalidReportLengthErr	kHIDInvalidReportLengthErr
+-13939	kHIDNullPointerErr	kHIDNullPointerErr
+-13938	kHIDBadParameterErr	kHIDBadParameterErr
+-13937	kHIDNotEnoughMemoryErr	kHIDNotEnoughMemoryErr
+-13936	kHIDEndOfDescriptorErr	kHIDEndOfDescriptorErr
+-13935	kHIDUsagePageZeroErr	kHIDUsagePageZeroErr
+-13934	kHIDBadLogicalMinimumErr	kHIDBadLogicalMinimumErr
+-13933	kHIDBadLogicalMaximumErr	kHIDBadLogicalMaximumErr
+-13932	kHIDInvertedLogicalRangeErr	kHIDInvertedLogicalRangeErr
+-13931	kHIDInvertedPhysicalRangeErr	kHIDInvertedPhysicalRangeErr
+-13930	kHIDUnmatchedUsageRangeErr	kHIDUnmatchedUsageRangeErr
+-13929	kHIDInvertedUsageRangeErr	kHIDInvertedUsageRangeErr
+-13928	kHIDUnmatchedStringRangeErr	kHIDUnmatchedStringRangeErr
+-13927	kHIDUnmatchedDesignatorRangeErr	kHIDUnmatchedDesignatorRangeErr
+-13926	kHIDReportSizeZeroErr	kHIDReportSizeZeroErr
+-13925	kHIDReportCountZeroErr	kHIDReportCountZeroErr
+-13924	kHIDReportIDZeroErr	kHIDReportIDZeroErr
+-13923	kHIDInvalidRangePageErr	kHIDInvalidRangePageErr
+-13910	kHIDDeviceNotReady	The device is still initializing, try again later
+-13909	kHIDVersionIncompatibleErr	kHIDVersionIncompatibleErr
+-13887	debuggingNoMatchErr	debugging component or option not found at this index
+-13886	debuggingNoCallbackErr	debugging component has no callback
+-13885	debuggingInvalidNameErr	componentName or optionName is invalid (NULL)
+-13884	debuggingInvalidOptionErr	optionSelectorNum is not registered
+-13883	debuggingInvalidSignatureErr	componentSignature not registered
+-13882	debuggingDuplicateOptionErr	optionSelectorNum already registered
+-13881	debuggingDuplicateSignatureErr	componentSignature already registered
+-13880	debuggingExecutionContextErr	routine cannot be called at this time
+-13038	kBridgeSoftwareRunningCantSleep	kBridgeSoftwareRunningCantSleep
+-13020	kNoSuchPowerSource	kNoSuchPowerSource
+-13014	kProcessorTempRoutineRequiresMPLib2	kProcessorTempRoutineRequiresMPLib2
+-13013	kCantReportProcessorTemperatureErr	kCantReportProcessorTemperatureErr
+-13010	kPowerMgtRequestDenied	kPowerMgtRequestDenied
+-13009	kPowerMgtMessageNotHandled	kPowerMgtMessageNotHandled
+-13008	kPowerHandlerNotFoundForProcErr	kPowerHandlerNotFoundForProcErr
+-13007	kPowerHandlerNotFoundForDeviceErr	kPowerHandlerNotFoundForDeviceErr
+-13006	kPowerHandlerExistsForDeviceErr	kPowerHandlerExistsForDeviceErr
+-13005	pmRecvEndErr	during receive, pmgr did not finish hs configured for this connection
+-13004	pmRecvStartErr	during receive, pmgr did not start hs
+-13003	pmSendEndErr	during send, pmgr did not finish hs
+-13002	pmSendStartErr	during send, pmgr did not start hs
+-13001	pmReplyTOErr	Timed out waiting for reply
+-13000	pmBusyErr	Power Mgr never ready to start handshake
+-11005	pictureDataErr	the picture data was invalid
+-11004	colorsRequestedErr	the number of colors requested was illegal
+-11003	cantLoadPickMethodErr	unable to load the custom pick proc
+-11002	pictInfoVerbErr	the passed verb was invalid
+-11001	pictInfoIDErr	the internal consistancy check for the PictInfoID is wrong
+-11000	pictInfoVersionErr	wrong version of the PictInfo structure
+-10780	errTaskNotFound	no task with that task id exists
+-10116	telNotEnoughdspBW	not enough real-time for allocation
+-10115	telBadSampleRate	incompatible sample rate
+-10114	telBadSWErr	Software not installed properly
+-10113	telDetAlreadyOn	detection is already turned on
+-10112	telAutoAnsNotOn	autoAnswer in not turned on
+-10111	telValidateFailed	telValidate failed
+-10110	telBadProcID	invalid procID
+-10109	telDeviceNotFound	device not found
+-10108	telBadCodeResource	code resource not found
+-10107	telInitFailed	initialization failed
+-10106	telNoCommFolder	Communications/Extensions € not found
+-10103	telUnknownErr	unable to set config
+-10102	telNoSuchTool	unable to find tool with name specified
+-10091	telBadFunction	bad msgCode specified
+-10090	telPBErr	parameter block error, bad format
+-10082	telCANotDeflectable	CA not "deflectable"
+-10081	telCANotRejectable	CA not "rejectable"
+-10080	telCANotAcceptable	CA not "acceptable"
+-10072	telTermNotOpen	terminal not opened via TELOpenTerm
+-10071	telStillNeeded	terminal driver still needed by someone else
+-10070	telAlreadyOpen	terminal already open
+-10064	telNoCallbackRef	no call back reference was specified, but is required
+-10063	telDisplayModeNotSupp	display mode not supported by tool
+-10062	telBadDisplayMode	bad display mode specified
+-10061	telFwdTypeNotSupp	forward type not supported by tool
+-10060	telDNTypeNotSupp	DN type not supported by tool
+-10059	telBadRate	bad rate specified
+-10058	telBadBearerType	bad bearerType specified
+-10057	telBadSelect	unable to select or deselect DN
+-10056	telBadParkID	bad park id specified
+-10055	telBadPickupGroupID	bad pickup group ID specified
+-10054	telBadFwdType	bad fwdType specified
+-10053	telBadFeatureID	bad feature ID specified
+-10052	telBadIntercomID	bad intercom ID specified
+-10051	telBadPageID	bad page ID specified
+-10050	telBadDNType	DN type invalid
+-10047	telConfLimitExceeded	attempt to exceed switch conference limits
+-10046	telCBErr	call back feature not set previously
+-10045	telTransferRej	transfer request rejected
+-10044	telTransferErr	transfer not prepared
+-10043	telConfRej	conference request was rejected
+-10042	telConfErr	conference was not prepared
+-10041	telConfNoLimit	no limit was specified but required
+-10040	telConfLimitErr	limit specified is too high for this configuration
+-10033	telFeatNotSupp	feature program call not supported by this tool
+-10032	telFeatActive	feature already active
+-10031	telFeatNotAvail	feature subscribed but not available
+-10030	telFeatNotSub	feature not subscribed
+-10025	errAEPropertiesClash	illegal combination of properties settings for Set Data, make new, or duplicate
+-10024	errAECantPutThatThere	in make new, duplicate, etc. class can't be an element of container
+-10023	errAENotAnEnumMember	enumerated value in SetData is not allowed for this property
+-10022	telIntExtNotSupp	internal external type not supported by this tool
+-10021	telBadIntExt	bad internal external error
+-10020	telStateNotSupp	device state not supported by tool
+-10019	telBadStateErr	bad device state specified
+-10018	telIndexNotSupp	index not supported by this tool
+-10017	telBadIndex	bad index specified
+-10016	telAPattNotSupp	alerting pattern not supported by tool
+-10015	telBadAPattErr	bad alerting pattern specified
+-10014	telVTypeNotSupp	volume type not supported by this tool
+-10013	telBadVTypeErr	bad volume type error
+-10012	telBadLevelErr	bad volume level setting
+-10011	telHTypeNotSupp	hook type not supported by this tool
+-10010	telBadHTypeErr	bad hook type specified
+-10009	errAECantSupplyType	errAECantSupplyType
+-10008	telNoOpenErr	unable to open terminal
+-10007	telNoMemErr	no memory to allocate handle
+-10006	errOSACantAssign	Signaled when an object cannot be set in a container.
+-10005	telBadProcErr	bad msgProc specified
+-10004	telBadHandErr	bad handle specified
+-10003	OSAIllegalAssign	Signaled when an object can never be set in a container
+-10002	telBadDNErr	TELDNHandle not found or invalid
+-10001	telBadTermErr	invalid TELHandle or handle not found
+-10000	errAEEventFailed	errAEEventFailed
+-9999	cannotMoveAttachedController	cannotMoveAttachedController
+-9998	controllerHasFixedHeight	controllerHasFixedHeight
+-9997	cannotSetWidthOfAttachedController	cannotSetWidthOfAttachedController
+-9996	controllerBoundsNotExact	controllerBoundsNotExact
+-9995	editingNotAllowed	editingNotAllowed
+-9994	badControllerHeight	badControllerHeight
+-9408	deviceCantMeetRequest	deviceCantMeetRequest
+-9407	seqGrabInfoNotAvailable	seqGrabInfoNotAvailable
+-9406	badSGChannel	badSGChannel
+-9405	couldntGetRequiredComponent	couldntGetRequiredComponent
+-9404	notEnoughDiskSpaceToGrab	notEnoughDiskSpaceToGrab
+-9403	notEnoughMemoryToGrab	notEnoughMemoryToGrab
+-9402	cantDoThatInCurrentMode	cantDoThatInCurrentMode
+-9401	grabTimeComplete	grabTimeComplete
+-9400	noDeviceForChannel	noDeviceForChannel
+-9109	kNoCardBusCISErr	No valid CIS exists for this CardBus card
+-9108	kNotZVCapableErr	This socket does not support Zoomed Video
+-9107	kCardPowerOffErr	Power to the card has been turned off
+-9106	kAttemptDupCardEntryErr	The Enabler was asked to create a duplicate card entry
+-9105	kAlreadySavedStateErr	The state has been saved on previous call
+-9104	kTooManyIOWindowsErr	device requested more than one I/O window
+-9103	kNotReadyErr	PC Card failed to go ready
+-9102	kClientRequestDenied	CS Clients should return this code inorder to
+-9101	kNoCompatibleNameErr	There is no compatible driver name for this device
+-9100	kNoEnablerForCardErr	No Enablers were found that can support the card
+-9099	kNoCardEnablersFoundErr	No Enablers were found
+-9098	kUnsupportedCardErr	Card not supported by generic enabler
+-9097	kNoClientTableErr	The client table has not be initialized yet
+-9096	kNoMoreInterruptSlotsErr	All internal Interrupt slots are in use
+-9095	kNoMoreTimerClientsErr	All timer callbacks are in use
+-9094	kNoIOWindowRequestedErr	Request I/O window before calling configuration
+-9093	kBadCustomIFIDErr	Custom interface ID is invalid
+-9092	kBadTupleDataErr	Data in tuple is invalid
+-9091	kInvalidCSClientErr	Card Services ClientID is not registered
+-9090	kUnsupportedVsErr	Unsupported Voltage Sense
+-9089	kInvalidDeviceNumber	kInvalidDeviceNumber
+-9088	kPostCardEventErr	_PCCSLPostCardEvent failed and dropped an event
+-9087	kCantConfigureCardErr	kCantConfigureCardErr
+-9086	kPassCallToChainErr	kPassCallToChainErr
+-9085	kCardBusCardErr	kCardBusCardErr
+-9084	k16BitCardErr	k16BitCardErr
+-9083	kBadDeviceErr	kBadDeviceErr
+-9082	kBadLinkErr	kBadLinkErr
+-9081	kInvalidRegEntryErr	kInvalidRegEntryErr
+-9080	kNoCardSevicesSocketsErr	kNoCardSevicesSocketsErr
+-9079	kOutOfResourceErr	Card Services has exhausted the resource
+-9078	kNoMoreItemsErr	there are no more of the requested item
+-9077	kInUseErr	requested resource is being used by a client
+-9076	kConfigurationLockedErr	a configuration has already been locked
+-9075	kWriteProtectedErr	media is write-protected
+-9074	kBusyErr	unable to process request at this time - try later
+-9073	kUnsupportedModeErr	mode is not supported
+-9072	kUnsupportedFunctionErr	function is not supported by this implementation
+-9071	kNoCardErr	no PC card in the socket
+-9070	kGeneralFailureErr	an undefined error has occurred
+-9069	kWriteFailureErr	unable to complete write request
+-9068	kReadFailureErr	unable to complete read request
+-9067	kBadSpeedErr	specified speed is unavailable
+-9066	kBadCISErr	CIS on card is invalid
+-9065	kBadHandleErr	clientHandle is invalid
+-9064	kBadArgsErr	values in argument packet are invalid
+-9063	kBadArgLengthErr	ArgLength argument is invalid
+-9062	kBadWindowErr	specified window is invalid
+-9061	kBadVppErr	specified Vpp1 or Vpp2 power level index is invalid
+-9060	kBadVccErr	specified Vcc power level index is invalid
+-9059	kBadTypeErr	specified window or interface type is invalid
+-9058	kBadSocketErr	specified logical or physical socket number is invalid
+-9057	kBadSizeErr	specified size is invalid
+-9056	kBadPageErr	specified page is invalid
+-9055	kBadOffsetErr	specified PC card memory array offset is invalid
+-9054	kBadIRQErr	specified IRQ level is invalid
+-9053	kBadEDCErr	specified EDC generator specified is invalid
+-9052	kBadBaseErr	specified base system memory address is invalid
+-9051	kBadAttributeErr	specified attributes field value is invalid
+-9050	kBadAdapterErr	invalid adapter number
+-8992	codecOffscreenFailedPleaseRetryErr	codecOffscreenFailedPleaseRetryErr
+-8991	lockPortBitsWrongGDeviceErr	lockPortBitsWrongGDeviceErr
+-8990	directXObjectAlreadyExists	directXObjectAlreadyExists
+-8989	codecDroppedFrameErr	returned from ImageCodecDrawBand
+-8988	codecOffscreenFailedErr	codecOffscreenFailedErr
+-8987	codecNeedAccessKeyErr	codec needs password in order to decompress
+-8986	codecParameterDialogConfirm	codecParameterDialogConfirm
+-8985	lockPortBitsSurfaceLostErr	lockPortBitsSurfaceLostErr
+-8984	lockPortBitsBadPortErr	lockPortBitsBadPortErr
+-8983	lockPortBitsWindowClippedErr	lockPortBitsWindowClippedErr
+-8982	lockPortBitsWindowResizedErr	lockPortBitsWindowResizedErr
+-8981	lockPortBitsWindowMovedErr	lockPortBitsWindowMovedErr
+-8980	lockPortBitsBadSurfaceErr	lockPortBitsBadSurfaceErr
+-8979	codecNeedToFlushChainErr	codecNeedToFlushChainErr
+-8978	codecDisabledErr	codec disabled itself -- pass codecFlagReenable to reset
+-8977	codecNoMemoryPleaseWaitErr	codecNoMemoryPleaseWaitErr
+-8976	codecNothingToBlitErr	codecNothingToBlitErr
+-8975	codecCantQueueErr	codecCantQueueErr
+-8974	codecCantWhenErr	codecCantWhenErr
+-8973	codecOpenErr	codecOpenErr
+-8972	codecConditionErr	codecConditionErr
+-8971	codecExtensionNotFoundErr	codecExtensionNotFoundErr
+-8970	codecDataVersErr	codecDataVersErr
+-8969	codecBadDataErr	codecBadDataErr
+-8968	codecWouldOffscreenErr	codecWouldOffscreenErr
+-8967	codecAbortErr	codecAbortErr
+-8966	codecSpoolErr	codecSpoolErr
+-8965	codecImageBufErr	codecImageBufErr
+-8964	codecScreenBufErr	codecScreenBufErr
+-8963	codecSizeErr	codecSizeErr
+-8962	codecUnimpErr	codecUnimpErr
+-8961	noCodecErr	noCodecErr
+-8960	codecErr	codecErr
+-8852	kIllegalClockValueErr	kIllegalClockValueErr
+-8851	kUTCOverflowErr	kUTCOverflowErr
+-8850	kUTCUnderflowErr	kUTCUnderflowErr
+-8809	kATSULastErr	The last ATSUI error code.
+-8808	kATSULineBreakInWord	This is not an error code but is returned by ATSUBreakLine to
+-8807	kATSUCoordinateOverflowErr	Used to indicate the coordinates provided to an ATSUI routine caused
+-8806	kATSUNoFontScalerAvailableErr	Used when no font scaler is available for the font passed
+-8805	kATSUNoFontCmapAvailableErr	Used when no CMAP table can be accessed or synthesized for the
+-8804	kATSULowLevelErr	Used when an error was encountered within the low level ATS
+-8803	kATSUQuickDrawTextErr	Used when QuickDraw Text encounters an error rendering or measuring
+-8802	kATSUNoStyleRunsAssignedErr	Used when an attempt was made to measure, highlight or draw
+-8801	kATSUNotSetErr	Used when the client attempts to retrieve an attribute,
+-8800	kATSUInvalidCacheErr	Used when an attempt was made to read in style data
+-8799	kATSUInvalidAttributeTagErr	Used when an attempt was made to use a tag value that
+-8798	kATSUInvalidAttributeSizeErr	Used when an attempt was made to use an attribute with a
+-8797	kATSUInvalidAttributeValueErr	Used when an attempt was made to use an attribute with
+-8796	kATSUInvalidFontErr	Used when an attempt was made to use an invalid font ID.
+-8795	kATSUNoCorrespondingFontErr	This value is retrned by font ID conversion
+-8794	kATSUFontsNotMatched	This value is returned by ATSUMatchFontsToText()
+-8793	kATSUFontsMatched	This is not an error code but is returned by
+-8792	kATSUInvalidTextRangeErr	An attempt was made to extract information
+-8791	kATSUInvalidStyleErr	An attempt was made to use a ATSUStyle which
+-8790	kATSUInvalidTextLayoutErr	An attempt was made to use a ATSUTextLayout
+-8785	kTECOutputBufferFullStatus	output buffer has no room for conversion of next input text element (partial conversion)
+-8784	kTECNeedFlushStatus	kTECNeedFlushStatus
+-8783	kTECUsedFallbacksStatus	kTECUsedFallbacksStatus
+-8771	kTECItemUnavailableErr	item (e.g. name) not available for specified region (& encoding if relevant)
+-8770	kTECGlobalsUnavailableErr	globals have already been deallocated (premature TERM)
+-8769	unicodeChecksumErr	unicodeChecksumErr
+-8768	unicodeNoTableErr	unicodeNoTableErr
+-8767	unicodeVariantErr	unicodeVariantErr
+-8766	unicodeFallbacksErr	unicodeFallbacksErr
+-8765	unicodePartConvertErr	unicodePartConvertErr
+-8764	unicodeBufErr	unicodeBufErr
+-8763	unicodeCharErr	unicodeCharErr
+-8762	unicodeElementErr	unicodeElementErr
+-8761	unicodeNotFoundErr	unicodeNotFoundErr
+-8760	unicodeTableFormatErr	unicodeTableFormatErr
+-8759	unicodeDirectionErr	unicodeDirectionErr
+-8758	unicodeContextualErr	unicodeContextualErr
+-8757	unicodeTextEncodingDataErr	unicodeTextEncodingDataErr
+-8756	kTECDirectionErr	direction stack overflow, etc.
+-8755	kTECIncompleteElementErr	text element may be incomplete or is too long for internal buffers
+-8754	kTECUnmappableElementErr	kTECUnmappableElementErr
+-8753	kTECPartialCharErr	input buffer ends in the middle of a multibyte character, conversion stopped
+-8752	kTECBadTextRunErr	kTECBadTextRunErr
+-8751	kTECArrayFullErr	supplied name buffer or TextRun, TextEncoding, or UnicodeMapping array is too small
+-8750	kTECBufferBelowMinimumSizeErr	output buffer too small to allow processing of first input text element
+-8749	kTECNoConversionPathErr	kTECNoConversionPathErr
+-8748	kTECCorruptConverterErr	invalid converter object reference
+-8747	kTECTableFormatErr	kTECTableFormatErr
+-8746	kTECTableChecksumErr	kTECTableChecksumErr
+-8745	kTECMissingTableErr	kTECMissingTableErr
+-8740	kTextUndefinedElementErr	text conversion errors
+-8739	kTextMalformedInputErr	in DBCS, for example, high byte followed by invalid low byte
+-8738	kTextUnsupportedEncodingErr	specified encoding not supported for this operation
+-7139	kRANotEnabled	kRANotEnabled
+-7138	kRACallBackFailed	kRACallBackFailed
+-7137	kRADuplicateIPAddr	kRADuplicateIPAddr
+-7136	kRANCPRejectedbyPeer	kRANCPRejectedbyPeer
+-7135	kRAExtAuthenticationFailed	kRAExtAuthenticationFailed
+-7134	kRAATalkInactive	kRAATalkInactive
+-7133	kRAPeerNotResponding	kRAPeerNotResponding
+-7132	kRAPPPPeerDisconnected	kRAPPPPeerDisconnected
+-7131	kRAPPPUserDisconnected	kRAPPPUserDisconnected
+-7130	kRAPPPNegotiationFailed	kRAPPPNegotiationFailed
+-7129	kRAPPPAuthenticationFailed	kRAPPPAuthenticationFailed
+-7128	kRAPPPProtocolRejected	kRAPPPProtocolRejected
+-7127	dcmBufferOverflowErr	data is larger than buffer size
+-7126	kRANotPrimaryInterface	when IPCP is not primary TCP/IP intf.
+-7125	kRATCPIPNotConfigured	TCP/IP not configured, could be loaded
+-7124	kRATCPIPInactive	TCP/IP inactive, cannot be loaded
+-7123	kRARemoteAccessNotReady	kRARemoteAccessNotReady
+-7122	kRAInitOpenTransportFailed	kRAInitOpenTransportFailed
+-7121	dcmProtectedErr	need keyword to use dictionary
+-7120	kRAUserPwdEntryRequired	kRAUserPwdEntryRequired
+-7119	kRAUserPwdChangeRequired	kRAUserPwdChangeRequired
+-7118	dcmBadFindMethodErr	no such find method supported
+-7117	kRAInvalidSerialProtocol	kRAInvalidSerialProtocol
+-7116	kRAInvalidPortState	kRAInvalidPortState
+-7115	dcmBadKeyErr	bad key information
+-7114	kRAPortBusy	kRAPortBusy
+-7113	kRAInstallationDamaged	kRAInstallationDamaged
+-7112	dcmBadFieldTypeErr	no such field type supported
+-7111	dcmBadFieldInfoErr	incomplete information
+-7110	dcmNecessaryFieldErr	lack required/identify field
+-7109	dcmDupRecordErr	same record already exist
+-7108	kRANotConnected	kRANotConnected
+-7107	dcmBlockFullErr	dictionary block full
+-7106	kRAMissingResources	kRAMissingResources
+-7105	dcmDictionaryBusyErr	dictionary is busy
+-7104	dcmDictionaryNotOpenErr	dictionary not opened
+-7103	dcmPermissionErr	invalid permission
+-7102	dcmBadDictionaryErr	invalid dictionary
+-7101	dcmNotDictionaryErr	not dictionary
+-7100	kRAInvalidParameter	kRAInvalidParameter
+-7000	laEngineNotFoundErr	can't find the engine
+-6999	laPropertyErr	Error in properties
+-6998	kUSBUnknownDeviceErr	device ref not recognised
+-6997	laPropertyIsReadOnlyErr	the property is read only
+-6996	laPropertyUnknownErr	the property is unknown to this environment
+-6995	laPropertyValueErr	Invalid property value
+-6994	laDictionaryTooManyErr	too many dictionaries
+-6993	laDictionaryUnknownErr	can't use this dictionary with this environment
+-6992	laDictionaryNotOpenedErr	the dictionary is not opened
+-6991	laTextOverFlowErr	text is too long
+-6990	laFailAnalysisErr	analysis failed
+-6989	laNoMoreMorphemeErr	nothing to read
+-6988	laInvalidPathErr	path is not correct
+-6987	kUSBNotHandled	Notification was not handled   (same as NotFound)
+-6986	laEnvironmentNotFoundErr	can't fint the specified environment
+-6985	laEnvironmentBusyErr	specified environment is used
+-6984	laTooSmallBufferErr	output buffer is too small to store any result
+-6983	kUSBFlagsError	Unused flags not zeroed
+-6982	kUSBAbortedError	Pipe aborted
+-6981	kUSBNoBandwidthError	Not enough bandwidth available
+-6980	kUSBPipeIdleError	Pipe is Idle, it will not accept transactions
+-6979	kUSBPipeStalledError	Pipe has stalled, error needs to be cleared
+-6978	kUSBUnknownInterfaceErr	Interface ref not recognised
+-6977	kUSBDeviceBusy	Device is already being configured
+-6976	kUSBDevicePowerProblem	Device has a power problem
+-6975	kUSBInvalidBuffer	bad buffer, usually nil
+-6974	kUSBDeviceSuspended	Device is suspended
+-6973	kUSBDeviceNotSuspended	device is not suspended for resume
+-6972	kUSBDeviceDisconnected	Disconnected during suspend or reset
+-6971	kUSBTimedOut	Transaction timed out.
+-6970	kUSBQueueAborted	Pipe zero stall cleared.
+-6969	kUSBPortDisabled	The port you are attached to is disabled, use USBDeviceReset.
+-6950	kUSBBadDispatchTable	Improper driver dispatch table
+-6949	kUSBUnknownNotification	Notification type not defined
+-6948	kUSBQueueFull	Internal queue maxxed
+-6916	kUSBLinkErr	kUSBLinkErr
+-6915	kUSBCRCErr	Pipe stall, bad CRC
+-6914	kUSBBitstufErr	Pipe stall, bitstuffing
+-6913	kUSBDataToggleErr	Pipe stall, Bad data toggle
+-6912	kUSBEndpointStallErr	Device didn't understand
+-6911	kUSBNotRespondingErr	Pipe stall, No device, device hung
+-6910	kUSBPIDCheckErr	Pipe stall, PID CRC error
+-6909	kUSBWrongPIDErr	Pipe stall, Bad or wrong PID
+-6908	kUSBOverRunErr	Packet too large or more data than buffer
+-6907	kUSBUnderRunErr	Less data than buffer
+-6906	kUSBRes1Err	kUSBRes1Err
+-6905	kUSBRes2Err	kUSBRes2Err
+-6904	kUSBBufOvrRunErr	Host hardware failure on data in, PCI busy?
+-6903	kUSBBufUnderRunErr	Host hardware failure on data out, PCI busy?
+-6902	kUSBNotSent1Err	Transaction not sent
+-6901	kUSBNotSent2Err	Transaction not sent
+-6232	kDMFoundErr	Did not proceed because we found an item
+-6231	kDMMainDisplayCannotMoveErr	Trying to move main display (or a display mirrored to it)
+-6230	kDMDisplayAlreadyInstalledErr	Attempt to add an already installed display.
+-6229	kDMDisplayNotFoundErr	Could not find item (will someday remove).
+-6228	kDMDriverNotDisplayMgrAwareErr	Video Driver does not support display manager.
+-6227	kDMSWNotInitializedErr	Required software not initialized (eg windowmanager or display mgr).
+-6226	kSysSWTooOld	Missing critical pieces of System Software.
+-6225	kDMMirroringNotOn	Returned by all calls that need mirroring to be on to do their thing.
+-6224	kDMCantBlock	Mirroring is already on, canÕt Block now (call DMUnMirror() first).
+-6223	kDMMirroringBlocked	DMBlockMirroring() has been called.
+-6222	kDMWrongNumberOfDisplays	Can only handle 2 displays for now.
+-6221	kDMMirroringOnAlready	Returned by all calls that need mirroring to be off to do their thing.
+-6220	kDMGenErr	Unexpected Error
+-6150	kQTSSUnknownErr	kQTSSUnknownErr
+-5753	collectionVersionErr	collectionVersionErr
+-5752	collectionIndexRangeErr	collectionIndexRangeErr
+-5751	collectionItemNotFoundErr	collectionItemNotFoundErr
+-5750	collectionItemLockedErr	collectionItemLockedErr
+-5699	kNavMissingKindStringErr	kNavMissingKindStringErr
+-5698	kNavInvalidCustomControlMessageErr	kNavInvalidCustomControlMessageErr
+-5697	kNavCustomControlMessageFailedErr	kNavCustomControlMessageFailedErr
+-5696	kNavInvalidSystemConfigErr	kNavInvalidSystemConfigErr
+-5695	kNavWrongDialogClassErr	kNavWrongDialogClassErr
+-5694	kNavWrongDialogStateErr	kNavWrongDialogStateErr
+-5640	dialogNoTimeoutErr	dialogNoTimeoutErr
+-5623	menuInvalidErr	menu is invalid
+-5622	menuItemNotFoundErr	specified menu item wasn't found
+-5621	menuUsesSystemDefErr	GetMenuDefinition failed because the menu uses the system MDEF
+-5620	menuNotFoundErr	specified menu or menu ID wasn't found
+-5615	windowWrongStateErr	window is not in a state that is valid for the current action
+-5614	windowManagerInternalErr	something really weird happened inside the window manager
+-5613	windowAttributesConflictErr	passed some attributes that are mutually exclusive
+-5612	windowAttributeImmutableErr	tried to change attributes which can't be changed
+-5611	errWindowDoesNotFitOnscreen	ConstrainWindowToScreen could not make the window fit onscreen
+-5610	errWindowNotFound	returned from FindWindowOfClass
+-5609	errFloatingWindowsNotInitialized	called HideFloatingWindows or ShowFloatingWindows without calling InitFloatingWindows
+-5608	errWindowsAlreadyInitialized	tried to call InitFloatingWindows twice, or called InitWindows and then floating windows
+-5607	errUserWantsToDragWindow	if returned from TrackWindowProxyDrag, you should call DragWindow on the window
+-5606	errCorruptWindowDescription	tried to load a corrupt window description (size or version fields incorrect)
+-5605	errUnrecognizedWindowClass	tried to create a window with a bad WindowClass
+-5604	errWindowPropertyNotFound	tried to get a nonexistent property
+-5603	errInvalidWindowProperty	tried to access a property tag with private creator
+-5602	errWindowDoesNotHaveProxy	tried to do something requiring a proxy to a window which doesnÕt have a proxy
+-5601	errUnsupportedWindowAttributesForClass	tried to create a window with WindowAttributes not supported by the WindowClass
+-5600	errInvalidWindowPtr	tried to pass a bad WindowRef argument
+-5553	gestaltLocationErr	gestalt function ptr wasn't in sysheap
+-5552	gestaltDupSelectorErr	tried to add an entry that already existed
+-5551	gestaltUndefSelectorErr	undefined selector was passed to Gestalt
+-5550	gestaltUnknownErr	value returned if Gestalt doesn't know the answer
+-5502	envVersTooBig	Version bigger than call can handle
+-5501	envBadVers	Version non-positive
+-5500	envNotPresent	returned by glue.
+-5421	qtsAddressBusyErr	qtsAddressBusyErr
+-5420	qtsConnectionFailedErr	qtsConnectionFailedErr
+-5408	qtsTimeoutErr	qtsTimeoutErr
+-5407	qtsUnknownValueErr	qtsUnknownValueErr
+-5406	qtsTooMuchDataErr	qtsTooMuchDataErr
+-5405	qtsUnsupportedFeatureErr	qtsUnsupportedFeatureErr
+-5404	qtsUnsupportedRateErr	qtsUnsupportedRateErr
+-5403	qtsUnsupportedDataTypeErr	qtsUnsupportedDataTypeErr
+-5402	qtsBadDataErr	something is wrong with the data
+-5401	qtsBadStateErr	qtsBadStateErr
+-5400	qtsBadSelectorErr	qtsBadSelectorErr
+-5388	errIAEndOfTextRun	errIAEndOfTextRun
+-5387	errIATextExtractionErr	errIATextExtractionErr
+-5386	errIAInvalidDocument	errIAInvalidDocument
+-5385	errIACanceled	errIACanceled
+-5384	errIABufferTooSmall	errIABufferTooSmall
+-5383	errIANoMoreItems	errIANoMoreItems
+-5382	errIAParamErr	errIAParamErr
+-5381	errIAAllocationErr	errIAAllocationErr
+-5380	errIAUnknownErr	errIAUnknownErr
+-5363	hrURLNotHandledErr	hrURLNotHandledErr
+-5362	hrUnableToResizeHandleErr	hrUnableToResizeHandleErr
+-5361	hrMiscellaneousExceptionErr	hrMiscellaneousExceptionErr
+-5360	hrHTMLRenderingLibNotInstalledErr	hrHTMLRenderingLibNotInstalledErr
+-5253	errCannotUndo	errCannotUndo
+-5252	errNonContiuousAttribute	errNonContiuousAttribute
+-5251	errUnknownElement	errUnknownElement
+-5250	errReadOnlyText	errReadOnlyText
+-5249	errEmptyScrap	errEmptyScrap
+-5248	errNoHiliteText	errNoHiliteText
+-5247	errOffsetNotOnElementBounday	errOffsetNotOnElementBounday
+-5246	errInvalidRange	errInvalidRange
+-5245	errIteratorReachedEnd	errIteratorReachedEnd
+-5244	errEngineNotFound	errEngineNotFound
+-5243	errAlreadyInImagingMode	errAlreadyInImagingMode
+-5242	errNotInImagingMode	errNotInImagingMode
+-5241	errMarginWilllNotFit	errMarginWilllNotFit
+-5240	errUnknownAttributeTag	errUnknownAttributeTag
+-5063	afpSameNodeErr	An Attempt was made to connect to a file server running on the same machine
+-5062	afpAlreadyMounted	The volume is already mounted
+-5061	afpCantMountMoreSrvre	The Maximum number of server connections has been reached
+-5060	afpBadDirIDType	afpBadDirIDType
+-5048	afpCallNotAllowed	The server knows what you wanted to do, but won't let you do it just now
+-5047	afpAlreadyLoggedInErr	User has been authenticated but is already logged in from another machine (and that's not allowed on this server)
+-5046	afpPwdPolicyErr	Password does not conform to servers password policy
+-5045	afpPwdNeedsChangeErr	The password needs to be changed
+-5044	afpInsideTrashErr	The folder being shared is inside the trash folder OR the shared folder is being moved into the trash folder
+-5043	afpInsideSharedErr	The folder being shared is inside a shared folder OR the folder contains a shared folder and is being moved into a shared folder
+-5042	afpPwdExpiredErr	The password being used is too old: this requires the user to change the password before log-in can continue
+-5041	afpPwdTooShortErr	The password being set is too short: there is a minimum length that must be met or exceeded
+-5040	afpPwdSameErr	Someone tried to change their password to the same password on a mantadory password change
+-5039	afpBadIDErr	afpBadIDErr
+-5038	afpSameObjectErr	afpSameObjectErr
+-5037	afpCatalogChanged	afpCatalogChanged
+-5036	afpDiffVolErr	afpDiffVolErr
+-5035	afpIDExists	afpIDExists
+-5034	afpIDNotFound	afpIDNotFound
+-5033	afpContainsSharedErr	the folder being shared contains a shared folder
+-5032	afpObjectLocked	Object is M/R/D/W inhibited
+-5031	afpVolLocked	Volume is Read-Only
+-5030	afpIconTypeError	Icon size specified different from existing icon size
+-5029	afpDirNotFound	Unknown directory specified
+-5028	afpCantRename	AFPRename cannot rename volume
+-5027	afpServerGoingDown	Server is shutting down
+-5026	afpTooManyFilesOpen	Maximum open file count reached
+-5025	afpObjectTypeErr	File/Directory specified where Directory/File expected
+-5024	afpCallNotSupported	Unsupported AFP call was made
+-5023	afpUserNotAuth	No AFPLogin call has successfully been made for this session
+-5022	afpSessClosed	Session closed
+-5021	afpRangeOverlap	Some or all of range already locked by same user
+-5020	afpRangeNotLocked	Tried to unlock range that was not locked by user
+-5019	afpParmErr	A specified parameter was out of allowable range
+-5018	afpObjectNotFound	Specified file or directory does not exist
+-5017	afpObjectExists	Specified destination file or directory already exists
+-5016	afpNoServer	Server not responding
+-5015	afpNoMoreLocks	Maximum lock limit reached
+-5014	afpMiscErr	Unexpected error encountered during execution
+-5013	afpLockErr	Some or all of requested range is locked by another user
+-5012	afpItemNotFound	Unknown UserName/UserID or missing comment/APPL entry
+-5011	afpFlatVol	Cannot create directory on specified volume
+-5010	afpFileBusy	Cannot delete an open file
+-5009	afpEofError	Read beyond logical end-of-file
+-5008	afpDiskFull	Insufficient free space on volume for operation
+-5007	afpDirNotEmpty	Cannot delete non-empty directory
+-5006	afpDenyConflict	Specified open/deny modes conflict with current open modes
+-5005	afpCantMove	Move destination is offspring of source, or root was specified
+-5004	afpBitmapErr	Bitmap contained bits undefined for call
+-5003	afpBadVersNum	Unknown AFP protocol version number specified
+-5002	afpBadUAM	Unknown user authentication method specified
+-5001	afpAuthContinue	Further information required to complete AFPLogin call
+-5000	afpAccessDenied	Insufficient access privileges for operation
+-4999	illegalScrapFlavorSizeErr	illegalScrapFlavorSizeErr
+-4998	illegalScrapFlavorTypeErr	illegalScrapFlavorTypeErr
+-4997	illegalScrapFlavorFlagsErr	illegalScrapFlavorFlagsErr
+-4996	scrapFlavorSizeMismatchErr	scrapFlavorSizeMismatchErr
+-4995	scrapFlavorFlagsMismatchErr	scrapFlavorFlagsMismatchErr
+-4994	nilScrapFlavorDataErr	nilScrapFlavorDataErr
+-4993	noScrapPromiseKeeperErr	noScrapPromiseKeeperErr
+-4992	scrapPromiseNotKeptErr	scrapPromiseNotKeptErr
+-4991	processStateIncorrectErr	processStateIncorrectErr
+-4990	badScrapRefErr	badScrapRefErr
+-4989	duplicateScrapFlavorErr	duplicateScrapFlavorErr
+-4988	internalScrapErr	internalScrapErr
+-4960	coreFoundationUnknownErr	coreFoundationUnknownErr
+-4276	badRoutingSizeErr	badRoutingSizeErr
+-4275	routingNotFoundErr	routingNotFoundErr
+-4274	duplicateRoutingErr	duplicateRoutingErr
+-4273	invalidFolderTypeErr	invalidFolderTypeErr
+-4272	noMoreFolderDescErr	noMoreFolderDescErr
+-4271	duplicateFolderDescErr	duplicateFolderDescErr
+-4270	badFolderDescErr	badFolderDescErr
+-4217	cmCantGamutCheckError	Gammut checking not supported by this ColorWorld
+-4216	cmNamedColorNotFound	NamedColor not found
+-4215	cmCantCopyModifiedV1Profile	Illegal to copy version 1 profiles that have been modified
+-4214	cmRangeOverFlow	Color conversion warning that some output color values over/underflowed and were clipped
+-4213	cmInvalidProfileComment	Bad Profile comment during drawpicture
+-4212	cmNoGDevicesError	Begin/End Matching -- no gdevices available
+-4211	cmInvalidDstMap	Destination pix/bit map was invalid
+-4210	cmInvalidSrcMap	Source pix/bit map was invalid
+-4209	cmInvalidColorSpace	Profile colorspace does not match bitmap type
+-4208	cmErrIncompatibleProfile	Other ColorSync Errors
+-4207	cmSearchError	cmSearchError
+-4206	cmInvalidSearch	Bad Search Handle
+-4205	cmInvalidProfileLocation	Operation not supported for this profile location
+-4204	cmInvalidProfile	A Profile must contain a 'cs1 ' tag to be valid
+-4203	cmFatalProfileErr	cmFatalProfileErr
+-4202	cmCantDeleteElement	cmCantDeleteElement
+-4201	cmIndexRangeErr	Tag index out of range
+-4200	kNSLInitializationFailed	UNABLE TO INITIALIZE THE MANAGER!!!!! DO NOT CONTINUE!!!!
+-4199	kNSLNotInitialized	kNSLNotInitialized
+-4198	kNSLInsufficientSysVer	kNSLInsufficientSysVer
+-4197	kNSLInsufficientOTVer	kNSLInsufficientOTVer
+-4196	kNSLNoElementsInList	kNSLNoElementsInList
+-4195	kNSLBadReferenceErr	kNSLBadReferenceErr
+-4194	kNSLBadServiceTypeErr	kNSLBadServiceTypeErr
+-4193	kNSLBadDataTypeErr	kNSLBadDataTypeErr
+-4192	kNSLBadNetConnection	kNSLBadNetConnection
+-4191	kNSLNoSupportForService	kNSLNoSupportForService
+-4190	kNSLInvalidPluginSpec	kNSLInvalidPluginSpec
+-4189	kNSLRequestBufferAlreadyInList	kNSLRequestBufferAlreadyInList
+-4188	kNSLNoContextAvailable	(ContinueLookup function ptr invalid)
+-4187	kNSLBufferTooSmallForData	(Client buffer too small for data from plugin)
+-4186	kNSLCannotContinueLookup	(Can't continue lookup; error or bad state)
+-4185	kNSLBadClientInfoPtr	(nil ClientAsyncInfoPtr; no reference available)
+-4184	kNSLNullListPtr	(client is trying to add items to a nil list)
+-4183	kNSLBadProtocolTypeErr	(client is trying to add a null protocol type)
+-4182	kNSLPluginLoadFailed	(manager unable to load one of the plugins)
+-4181	kNSLNoPluginsFound	(manager didn't find any valid plugins to load)
+-4180	kNSLSearchAlreadyInProgress	(you can only have one ongoing search per clientRef)
+-4179	kNSLNoPluginsForSearch	(no plugins will respond to search request; bad protocol(s)?)
+-4178	kNSLNullNeighborhoodPtr	(client passed a null neighborhood ptr)
+-4177	kNSLSomePluginsFailedToLoad	(one or more plugins failed to load, but at least one did load; this error isn't fatal)
+-4176	kNSLErrNullPtrError	kNSLErrNullPtrError
+-4175	kNSLNotImplementedYet	kNSLNotImplementedYet
+-4174	kNSLUILibraryNotAvailable	The NSL UI Library needs to be in the Extensions Folder
+-4173	kNSLNoCarbonLib	kNSLNoCarbonLib
+-4172	kNSLBadURLSyntax	URL contains illegal characters
+-4171	kNSLSchedulerError	A custom thread routine encountered an error
+-4170	kNSL68kContextNotSupported	no 68k allowed
+-4009	noHelpForItem	noHelpForItem
+-4008	badProfileError	badProfileError
+-4007	colorSyncNotInstalled	colorSyncNotInstalled
+-4006	pickerCantLive	pickerCantLive
+-4005	cantLoadPackage	cantLoadPackage
+-4004	cantCreatePickerWindow	cantCreatePickerWindow
+-4003	cantLoadPicker	cantLoadPicker
+-4002	pickerResourceError	pickerResourceError
+-4001	requiredFlagsDontMatch	requiredFlagsDontMatch
+-4000	firstPickerError	firstPickerError
+-3285	kOTPortLostConnection	
+-3284	kOTUserRequestedErr	
+-3283	kOTConfigurationChangedErr	
+-3282	kOTBadConfigurationErr	
+-3281	kOTPortWasEjectedErr	
+-3280	kOTPortHasDiedErr	
+-3279	kOTClientNotInittedErr	
+-3278	kENOMSGErr	
+-3277	kESRCHErr	
+-3276	kEINPROGRESSErr	
+-3275	kENODATAErr	
+-3274	kENOSTRErr	
+-3273	kECANCELErr	
+-3272	kEBADMSGErr	
+-3271	kENOSRErr	
+-3270	kETIMEErr	
+-3269	kEPROTOErr	‚‚‚ fill out missing codes ‚‚‚
+-3264	kEHOSTUNREACHErr	No route to host
+-3263	kEHOSTDOWNErr	Host is down
+-3260	kECONNREFUSEDErr	Connection refused
+-3259	kETIMEDOUTErr	Connection timed out
+-3258	kETOOMANYREFSErr	Too many references: can't splice
+-3257	kESHUTDOWNErr	Can't send after socket shutdown
+-3256	kENOTCONNErr	Socket is not connected
+-3255	kEISCONNErr	Socket is already connected
+-3254	kENOBUFSErr	No buffer space available
+-3253	kECONNRESETErr	Connection reset by peer
+-3252	kECONNABORTEDErr	Software caused connection abort
+-3251	kENETRESETErr	Network dropped connection on reset
+-3250	kENETUNREACHErr	Network is unreachable
+-3249	kENETDOWNErr	Network is down
+-3248	kEADDRNOTAVAILErr	Can't assign requested address
+-3247	kEADDRINUSEErr	Address already in use
+-3244	kEOPNOTSUPPErr	Operation not supported on socket
+-3243	kESOCKTNOSUPPORTErr	Socket type not supported
+-3242	kEPROTONOSUPPORTErr	Protocol not supported
+-3241	kENOPROTOOPTErr	Protocol not available
+-3240	kEPROTOTYPEErr	Protocol wrong type for socket
+-3239	kEMSGSIZEErr	Message too long
+-3238	kEDESTADDRREQErr	Destination address required
+-3237	kENOTSOCKErr	Socket operation on non-socket
+-3236	kEALREADYErr	
+-3234	kEWOULDBLOCKErr	Call would block, so was aborted
+-3233	kERANGEErr	Message size too large for STREAM
+-3231	kEPIPEErr	Broken pipe
+-3224	kENOTTYErr	Not a character device
+-3221	kEINVALErr	Invalid argument
+-3218	kENODEVErr	No such device
+-3216	kOTDuplicateFoundErr	OT generic duplicate found error
+-3215	kEBUSYErr	Device or resource busy
+-3213	kEFAULTErr	Bad address
+-3212	kEACCESErr	Permission denied
+-3211	kOTOutOfMemoryErr	OT ran out of memory, may be a temporary
+-3210	kEAGAINErr	Try operation again later
+-3208	kEBADFErr	Bad file number
+-3205	kENXIOErr	No such device or address
+-3204	kEIOErr	I/O error
+-3203	kEINTRErr	Interrupted system service
+-3202	kENORSRCErr	No such resource
+-3201	kOTNotFoundErr	OT generic not found error
+-3200	kEPERMErr	Permission denied
+-3180	kOTCanceledErr	XTI2OSStatus(TCANCELED) The command was cancelled
+-3179	kOTBadSyncErr	XTI2OSStatus(TBADSYNC) A synchronous call at interrupt time
+-3178	kOTProtocolErr	XTI2OSStatus(TPROTO) An unspecified provider error occurred
+-3177	kOTQFullErr	XTI2OSStatus(TQFULL)
+-3176	kOTResAddressErr	XTI2OSStatus(TRESADDR)
+-3175	kOTResQLenErr	XTI2OSStatus(TRESQLEN)
+-3174	kOTProviderMismatchErr	XTI2OSStatus(TPROVMISMATCH) Tried to accept on incompatible endpoint
+-3173	kOTIndOutErr	XTI2OSStatus(TINDOUT) Accept failed because of pending listen
+-3172	kOTAddressBusyErr	XTI2OSStatus(TADDRBUSY) Address requested is already in use
+-3171	kOTBadQLenErr	XTI2OSStatus(TBADQLEN) A Bind to an in-use addr with qlen > 0
+-3170	kOTBadNameErr	XTI2OSStatus(TBADNAME) A bad endpoint name was supplied
+-3169	kOTNoStructureTypeErr	XTI2OSStatus(TNOSTRUCTYPE) Bad structure type requested for OTAlloc
+-3168	kOTStateChangeErr	XTI2OSStatus(TSTATECHNG) State is changing - try again later
+-3167	kOTNotSupportedErr	XTI2OSStatus(TNOTSUPPORT) Command is not supported
+-3166	kOTNoReleaseErr	XTI2OSStatus(TNOREL) No orderly release indication available
+-3165	kOTBadFlagErr	XTI2OSStatus(TBADFLAG) A Bad flag value was supplied
+-3164	kOTNoUDErrErr	XTI2OSStatus(TNOUDERR) No Unit Data Error indication available
+-3163	kOTNoDisconnectErr	XTI2OSStatus(TNODIS) No disconnect indication available
+-3162	kOTNoDataErr	XTI2OSStatus(TNODATA) No data available for reading
+-3161	kOTFlowErr	XTI2OSStatus(TFLOW) Provider is flow-controlled
+-3160	kOTBufferOverflowErr	XTI2OSStatus(TBUFOVFLW) Passed buffer not big enough
+-3159	kOTBadDataErr	XTI2OSStatus(TBADDATA) An illegal amount of data was specified
+-3158	kOTLookErr	XTI2OSStatus(TLOOK) An event occurred - call Look()
+-3157	kOTSysErrorErr	XTI2OSStatus(TSYSERR) A system error occurred
+-3156	kOTBadSequenceErr	XTI2OSStatus(TBADSEQ) Sequence specified does not exist
+-3155	kOTOutStateErr	XTI2OSStatus(TOUTSTATE) Call issued in wrong state
+-3154	kOTNoAddressErr	XTI2OSStatus(TNOADDR) No address was specified
+-3153	kOTBadReferenceErr	XTI2OSStatus(TBADF) Bad provider reference
+-3152	kOTAccessErr	XTI2OSStatus(TACCES) Missing access permission
+-3151	kOTBadOptionErr	XTI2OSStatus(TBADOPT) A Bad option was specified
+-3150	kOTBadAddressErr	XTI2OSStatus(TBADADDR) A Bad address was specified
+-3109	sktClosedErr	sktClosedErr
+-3108	recNotFnd	recNotFnd
+-3107	atpBadRsp	atpBadRsp
+-3106	atpLenErr	atpLenErr
+-3105	readQErr	readQErr
+-3104	extractErr	extractErr
+-3103	ckSumErr	ckSumErr
+-3102	noMPPErr	noMPPErr
+-3101	buf2SmallErr	buf2SmallErr
+-3032	noPrefAppErr	noPrefAppErr
+-3031	badTranslationSpecErr	badTranslationSpecErr
+-3030	noTranslationPathErr	noTranslationPathErr
+-3026	couldNotParseSourceFileErr	Source document does not contain source type
+-3025	invalidTranslationPathErr	Source type to destination type not a valid path
+-3005	retryComponentRegistrationErr	retryComponentRegistrationErr
+-3004	unresolvedComponentDLLErr	unresolvedComponentDLLErr
+-3003	componentDontRegister	componentDontRegister
+-3002	componentNotCaptured	componentNotCaptured
+-3001	validInstancesExist	validInstancesExist
+-3000	invalidComponentID	invalidComponentID
+-2899	cfragLastErrCode	The last value in the range of CFM errors.
+-2831	cfragOutputLengthErr	An output parameter is too small to hold the value.
+-2830	cfragAbortClosureErr	Used by notification handlers to abort a closure.
+-2829	cfragClosureIDErr	The closure ID was not valid.
+-2828	cfragContainerIDErr	The fragment container ID was not valid.
+-2827	cfragNoRegistrationErr	The registration name was not found.
+-2826	cfragNotClosureErr	The closure ID was actually a connection ID.
+-2825	cfragFileSizeErr	A file was too large to be mapped.
+-2824	cfragFragmentUsageErr	A semantic error in usage of the fragment.
+-2823	cfragArchitectureErr	A fragment has an unacceptable architecture.
+-2822	cfragNoApplicationErr	No application member found in the cfrg resource.
+-2821	cfragInitFunctionErr	A fragment's initialization routine returned an error.
+-2820	cfragFragmentCorruptErr	A fragment's container was corrupt (known format).
+-2819	cfragCFMInternalErr	An internal inconstistancy has been detected.
+-2818	cfragCFMStartupErr	Internal error during CFM initialization.
+-2817	cfragLibConnErr	
+-2816	cfragInitAtBootErr	A boot library has an initialization function.  (System 7 only)
+-2815	cfragInitLoopErr	Circularity in required initialization order.
+-2814	cfragImportTooNewErr	An import library was too new for a client.
+-2813	cfragImportTooOldErr	An import library was too old for a client.
+-2812	cfragInitOrderErr	
+-2811	cfragNoIDsErr	No more CFM IDs for contexts, connections, etc.
+-2810	cfragNoClientMemErr	Out of memory for fragment mapping or section instances.
+-2809	cfragNoPrivateMemErr	Out of memory for internal bookkeeping.
+-2808	cfragNoPositionErr	The registration insertion point was not found.
+-2807	cfragUnresolvedErr	A fragment had "hard" unresolved imports.
+-2806	cfragFragmentFormatErr	A fragment's container format is unknown.
+-2805	cfragDupRegistrationErr	The registration name was already in use.
+-2804	cfragNoLibraryErr	The named library was not found.
+-2803	cfragNoSectionErr	The specified section was not found.
+-2802	cfragNoSymbolErr	The specified symbol was not found.
+-2801	cfragConnectionIDErr	The connection ID was not valid.
+-2800	cfragFirstErrCode	The first value in the range of CFM errors.
+-2780	errASInconsistentNames	English errors:
+-2763	errASNoResultReturned	The range -2780 thru -2799 is reserved for dialect specific error codes. (Error codes from different dialects may overlap.)
+-2762	errASParameterNotForEvent	errASParameterNotForEvent
+-2761	errASIllegalFormalParameter	errASIllegalFormalParameter
+-2760	errASTerminologyNestingTooDeep	errASTerminologyNestingTooDeep
+-2755	OSAControlFlowError	Signaled when illegal control flow occurs in an application (no catcher for throw, non-lexical loop exit, etc.)
+-2754	OSAInconsistentDeclarations	Signaled when a variable is declared inconsistently in the same scope, such as both local and global
+-2753	OSAUndefinedVariable	Signaled when a variable is accessed that has no value
+-2752	OSADuplicateHandler	Signaled when more than one handler is defined with the same name in a scope where the language doesn't allow it
+-2751	OSADuplicateProperty	Signaled when a formal parameter, local variable, or instance variable is specified more than once.
+-2750	OSADuplicateParameter	Signaled when a formal parameter, local variable, or instance variable is specified more than once
+-2742	OSATokenTooLong	Signaled when a name or number is too long to be parsed
+-2741	OSASyntaxTypeError	Signaled when another form of syntax was expected. (e.g. "expected a <type> but found <this>")
+-2740	OSASyntaxError	Signaled when a syntax error occurs. (e.g. "Syntax error" or "<this> can't go after <that>")
+-2721	errASCantCompareMoreThan32k	Parser/Compiler errors:
+-2720	errASCantConsiderAndIgnore	errASCantConsiderAndIgnore
+-2710	errOSACantCreate	errOSACantCreate
+-2709	errOSACantGetTerminology	errOSACantGetTerminology
+-2708	errOSADataBlockTooLarge	Signaled when an intrinsic limitation is exceeded for the size of a value or data structure.
+-2707	errOSAInternalTableOverflow	Signaled when a runtime internal data structure overflows
+-2706	errOSAStackOverflow	Signaled when the runtime stack overflows
+-2705	errOSACorruptTerminology	Signaled when an application's terminology resource is not readable
+-2704	errOSAAppNotHighLevelEventAware	Signaled when an application can't respond to AppleEvents
+-2703	errOSACantLaunch	Signaled when application can't be launched or when it is remote and program linking is not enabled
+-2702	errOSANumericOverflow	Signaled when integer or real value is too large to be represented
+-2701	errOSADivideByZero	Signaled when there is an attempt to divide by zero
+-2700	errOSAGeneralError	Signaled by user scripts or applications when no actual error code is to be returned.
+-2582	noIconDataAvailableErr	The necessary icon data is not available
+-2581	noSuchIconErr	The requested icon could not be found
+-2580	invalidIconRefErr	The icon ref is not valid
+-2557	nrCallNotSupported	This call is not available or supported on this machine
+-2556	nrTransactionAborted	transaction was aborted
+-2555	nrExitedIteratorScope	outer scope of iterator was exited
+-2554	nrIterationDone	iteration operation is done
+-2553	nrPropertyAlreadyExists	property already exists
+-2552	nrInvalidEntryIterationOp	invalid entry iteration operation
+-2551	nrPathBufferTooSmall	buffer for path is too small
+-2550	nrPathNotFound	a path component lookup failed
+-2549	nrResultCodeBase	nrResultCodeBase
+-2548	nrOverrunErr	nrOverrunErr
+-2547	nrNotModifiedErr	nrNotModifiedErr
+-2546	nrTypeMismatchErr	nrTypeMismatchErr
+-2545	nrPowerSwitchAbortErr	nrPowerSwitchAbortErr
+-2544	nrPowerErr	nrPowerErr
+-2543	nrDataTruncatedErr	nrDataTruncatedErr
+-2542	nrNotSlotDeviceErr	nrNotSlotDeviceErr
+-2541	nrNameErr	nrNameErr
+-2540	nrNotCreatedErr	nrNotCreatedErr
+-2539	nrNotFoundErr	nrNotFoundErr
+-2538	nrInvalidNodeErr	nrInvalidNodeErr
+-2537	nrNotEnoughMemoryErr	nrNotEnoughMemoryErr
+-2536	nrLockedErr	nrLockedErr
+-2526	mmInternalError	mmInternalError
+-2524	tsmDefaultIsNotInputMethodErr	Current Input source is KCHR or uchr, not Input Method  (GetDefaultInputMethod)
+-2523	tsmNoStem	No stem exists for the token
+-2522	tsmNoMoreTokens	No more tokens are available for the source text
+-2521	tsmNoHandler	No Callback Handler exists for callback
+-2520	tsmInvalidContext	Invalid TSMContext specified in call
+-2519	tsmUnknownErr	any other errors
+-2518	tsmUnsupportedTypeErr	unSupported interface type error
+-2517	tsmScriptHasNoIMErr	script has no imput method or is using old IM
+-2516	tsmInputMethodIsOldErr	returned by GetDefaultInputMethod
+-2515	tsmComponentAlreadyOpenErr	text service already opened for the document
+-2514	tsmTSNotOpenErr	text service is not open
+-2513	tsmTSHasNoMenuErr	the text service has no menu
+-2512	tsmUseInputWindowErr	not TSM aware because we are using input window
+-2511	tsmDocumentOpenErr	there are open documents
+-2510	tsmTextServiceNotFoundErr	no text service found
+-2509	tsmCantOpenComponentErr	canÕt open the component
+-2508	tsmNoOpenTSErr	no open text service
+-2507	tsmDocNotActiveErr	document is NOT active
+-2506	tsmTSMDocBusyErr	document is still active
+-2505	tsmInvalidDocIDErr	invalid TSM documentation id
+-2504	tsmNeverRegisteredErr	app never registered error (not TSM aware)
+-2503	tsmAlreadyRegisteredErr	want to register again error
+-2502	tsmNotAnAppErr	not an application error
+-2501	tsmInputMethodNotFoundErr	tsmInputMethodNotFoundErr
+-2500	tsmUnsupScriptLanguageErr	tsmUnsupScriptLanguageErr
+-2499	kernelUnrecoverableErr	kernelUnrecoverableErr
+-2422	kernelReturnValueErr	kernelReturnValueErr
+-2421	kernelAlreadyFreeErr	kernelAlreadyFreeErr
+-2419	kernelIDErr	kernelIDErr
+-2418	kernelExceptionErr	kernelExceptionErr
+-2417	kernelTerminatedErr	kernelTerminatedErr
+-2416	kernelInUseErr	kernelInUseErr
+-2415	kernelTimeoutErr	kernelTimeoutErr
+-2414	kernelAsyncReceiveLimitErr	kernelAsyncReceiveLimitErr
+-2413	kernelAsyncSendLimitErr	kernelAsyncSendLimitErr
+-2412	kernelAttributeErr	kernelAttributeErr
+-2411	kernelExecutionLevelErr	kernelExecutionLevelErr
+-2410	kernelDeletePermissionErr	kernelDeletePermissionErr
+-2409	kernelExecutePermissionErr	kernelExecutePermissionErr
+-2408	kernelReadPermissionErr	kernelReadPermissionErr
+-2407	kernelWritePermissionErr	kernelWritePermissionErr
+-2406	kernelObjectExistsErr	kernelObjectExistsErr
+-2405	kernelUnsupportedErr	kernelUnsupportedErr
+-2404	kernelPrivilegeErr	kernelPrivilegeErr
+-2403	kernelOptionsErr	kernelOptionsErr
+-2402	kernelCanceledErr	kernelCanceledErr
+-2401	kernelIncompleteErr	kernelIncompleteErr
+-2209	badCallOrderErr	Usually due to a status call being called prior to being setup first
+-2208	noDMAErr	CanÕt do DMA digitizing (i.e. can't go to requested dest
+-2207	badDepthErr	CanÕt digitize into this depth
+-2206	notExactSizeErr	CanÕt do exact size requested
+-2205	noMoreKeyColorsErr	all key indexes in use
+-2204	notExactMatrixErr	warning of bad matrix, digitizer did its best
+-2203	matrixErr	bad matrix, digitizer did nothing
+-2202	qtParamErr	bad input parameter (out of range, etc)
+-2201	digiUnimpErr	feature unimplemented
+-2159	qtXMLApplicationErr	qtXMLApplicationErr
+-2158	qtXMLParseErr	qtXMLParseErr
+-2157	qtActionNotHandledErr	qtActionNotHandledErr
+-2149	notEnoughDataErr	notEnoughDataErr
+-2148	urlDataHFTPURLErr	urlDataHFTPURLErr
+-2147	urlDataHFTPServerDisconnectedErr	urlDataHFTPServerDisconnectedErr
+-2146	urlDataHFTPNoPasswordErr	urlDataHFTPNoPasswordErr
+-2145	urlDataHFTPNeedPasswordErr	urlDataHFTPNeedPasswordErr
+-2144	urlDataHFTPBadNameListErr	urlDataHFTPBadNameListErr
+-2143	urlDataHFTPNoNetDriverErr	urlDataHFTPNoNetDriverErr
+-2142	urlDataHFTPFilenameErr	urlDataHFTPFilenameErr
+-2141	urlDataHFTPPermissionsErr	urlDataHFTPPermissionsErr
+-2140	urlDataHFTPQuotaErr	urlDataHFTPQuotaErr
+-2139	urlDataHFTPNoDirectoryErr	urlDataHFTPNoDirectoryErr
+-2138	urlDataHFTPDataConnectionErr	urlDataHFTPDataConnectionErr
+-2137	urlDataHFTPServerErr	urlDataHFTPServerErr
+-2136	urlDataHFTPBadPasswordErr	urlDataHFTPBadPasswordErr
+-2135	urlDataHFTPBadUserErr	urlDataHFTPBadUserErr
+-2134	urlDataHFTPShutdownErr	urlDataHFTPShutdownErr
+-2133	urlDataHFTPProtocolErr	urlDataHFTPProtocolErr
+-2132	urlDataHHTTPRedirectErr	urlDataHHTTPRedirectErr
+-2131	urlDataHHTTPURLErr	urlDataHHTTPURLErr
+-2130	urlDataHHTTPNoNetDriverErr	urlDataHHTTPNoNetDriverErr
+-2129	urlDataHHTTPProtocolErr	urlDataHHTTPProtocolErr
+-2127	qtNetworkAlreadyAllocatedErr	qtNetworkAlreadyAllocatedErr
+-2126	notAllowedToSaveMovieErr	notAllowedToSaveMovieErr
+-2125	fileOffsetTooBigErr	fileOffsetTooBigErr
+-2124	ASDEntryNotFoundErr	ASDEntryNotFoundErr
+-2123	ASDBadForkErr	ASDBadForkErr
+-2122	ASDBadHeaderErr	ASDBadHeaderErr
+-2121	AAPNotFoundErr	AAPNotFoundErr
+-2120	AAPNotCreatedErr	AAPNotCreatedErr
+-2119	qfcbNotCreatedErr	qfcbNotCreatedErr
+-2118	qfcbNotFoundErr	qfcbNotFoundErr
+-2117	wackBadMetaDataErr	wackBadMetaDataErr
+-2116	wackForkNotFoundErr	wackForkNotFoundErr
+-2115	wackBadFileErr	wackBadFileErr
+-2114	unknownFormatErr	unknownFormatErr
+-2113	pathNotVerifiedErr	pathNotVerifiedErr
+-2112	noPathMappingErr	noPathMappingErr
+-2111	emptyPathErr	emptyPathErr
+-2110	pathTooLongErr	pathTooLongErr
+-2109	cannotBeLeafAtomErr	cannotBeLeafAtomErr
+-2108	invalidAtomTypeErr	invalidAtomTypeErr
+-2107	invalidAtomContainerErr	invalidAtomContainerErr
+-2106	invalidAtomErr	invalidAtomErr
+-2105	duplicateAtomTypeAndIDErr	duplicateAtomTypeAndIDErr
+-2104	atomIndexInvalidErr	atomIndexInvalidErr
+-2103	atomsNotOfSameTypeErr	atomsNotOfSameTypeErr
+-2102	notLeafAtomErr	notLeafAtomErr
+-2101	cannotFindAtomErr	cannotFindAtomErr
+-2097	unsupportedProcessorErr	unsupportedProcessorErr
+-2096	unsupportedOSErr	unsupportedOSErr
+-2095	qtmlUninitialized	qtmlUninitialized
+-2094	qtmlDllEntryNotFoundErr	Windows specific errors (when qtml is loading)
+-2093	qtmlDllLoadErr	Windows specific errors (when qtml is loading)
+-2092	componentDllEntryNotFoundErr	Windows specific errors (when component is loading)
+-2091	componentDllLoadErr	Windows specific errors (when component is loading)
+-2090	videoOutputInUseErr	videoOutputInUseErr
+-2089	noExportProcAvailableErr	noExportProcAvailableErr
+-2087	tuneParseOSErr	tuneParseOSErr
+-2086	tunePlayerFullOSErr	tunePlayerFullOSErr
+-2085	noteChannelNotAllocatedOSErr	noteChannelNotAllocatedOSErr
+-2084	illegalNoteChannelOSErr	illegalNoteChannelOSErr
+-2083	synthesizerOSErr	synthesizerOSErr
+-2082	synthesizerNotRespondingOSErr	synthesizerNotRespondingOSErr
+-2081	midiManagerAbsentOSErr	midiManagerAbsentOSErr
+-2080	illegalControllerOSErr	illegalControllerOSErr
+-2079	illegalInstrumentOSErr	illegalInstrumentOSErr
+-2078	illegalKnobValueOSErr	illegalKnobValueOSErr
+-2077	illegalKnobOSErr	illegalKnobOSErr
+-2076	illegalChannelOSErr	illegalChannelOSErr
+-2075	illegalPartOSErr	illegalPartOSErr
+-2074	illegalVoiceAllocationOSErr	illegalVoiceAllocationOSErr
+-2073	cantReceiveFromSynthesizerOSErr	cantReceiveFromSynthesizerOSErr
+-2072	cantSendToSynthesizerOSErr	cantSendToSynthesizerOSErr
+-2071	notImplementedMusicOSErr	notImplementedMusicOSErr
+-2070	internalComponentErr	internalComponentErr
+-2069	invalidSpriteIDErr	invalidSpriteIDErr
+-2068	invalidImageIndexErr	invalidImageIndexErr
+-2067	invalidSpriteIndexErr	invalidSpriteIndexErr
+-2066	gWorldsNotSameDepthAndSizeErr	gWorldsNotSameDepthAndSizeErr
+-2065	invalidSpritePropertyErr	invalidSpritePropertyErr
+-2064	invalidSpriteWorldPropertyErr	invalidSpriteWorldPropertyErr
+-2063	missingRequiredParameterErr	missingRequiredParameterErr
+-2062	movieTextNotFoundErr	movieTextNotFoundErr
+-2061	sourceNotFoundErr	sourceNotFoundErr
+-2060	noSourceTreeFoundErr	noSourceTreeFoundErr
+-2059	samplesAlreadyInMediaErr	samplesAlreadyInMediaErr
+-2058	auxiliaryExportDataUnavailable	auxiliaryExportDataUnavailable
+-2057	unsupportedAuxiliaryImportData	unsupportedAuxiliaryImportData
+-2056	soundSupportNotAvailableErr	QT for Windows error
+-2055	noSoundTrackInMovieErr	QT for Windows error
+-2054	noVideoTrackInMovieErr	QT for Windows error
+-2053	featureUnsupported	featureUnsupported
+-2052	couldNotUseAnExistingSample	couldNotUseAnExistingSample
+-2051	noDefaultDataRef	noDefaultDataRef
+-2050	badDataRefIndex	badDataRefIndex
+-2049	invalidDataRefContainer	invalidDataRefContainer
+-2048	noMovieFound	noMovieFound
+-2047	dataNoDataRef	dataNoDataRef
+-2046	endOfDataReached	endOfDataReached
+-2045	dataAlreadyClosed	dataAlreadyClosed
+-2044	dataAlreadyOpenForWrite	dataAlreadyOpenForWrite
+-2043	dataNotOpenForWrite	dataNotOpenForWrite
+-2042	dataNotOpenForRead	dataNotOpenForRead
+-2041	invalidSampleDescription	invalidSampleDescription
+-2040	invalidChunkCache	invalidChunkCache
+-2039	invalidSampleDescIndex	invalidSampleDescIndex
+-2038	invalidChunkNum	invalidChunkNum
+-2037	invalidSampleNum	invalidSampleNum
+-2036	invalidRect	invalidRect
+-2035	cantEnableTrack	cantEnableTrack
+-2034	internalQuickTimeError	internalQuickTimeError
+-2033	badEditIndex	badEditIndex
+-2032	timeNotInMedia	timeNotInMedia
+-2031	timeNotInTrack	timeNotInTrack
+-2030	trackNotInMovie	trackNotInMovie
+-2029	trackIDNotFound	trackIDNotFound
+-2028	badTrackIndex	badTrackIndex
+-2027	maxSizeToGrowTooSmall	maxSizeToGrowTooSmall
+-2026	userDataItemNotFound	userDataItemNotFound
+-2025	staleEditState	staleEditState
+-2024	nonMatchingEditState	nonMatchingEditState
+-2023	invalidEditState	invalidEditState
+-2022	cantCreateSingleForkFile	happens when file already exists
+-2021	wfFileNotFound	wfFileNotFound
+-2020	movieToolboxUninitialized	movieToolboxUninitialized
+-2019	progressProcAborted	progressProcAborted
+-2018	mediaTypesDontMatch	mediaTypesDontMatch
+-2017	badEditList	badEditList
+-2016	cantPutPublicMovieAtom	cantPutPublicMovieAtom
+-2015	invalidTime	invalidTime
+-2014	invalidDuration	invalidDuration
+-2013	invalidHandler	invalidHandler
+-2012	invalidDataRef	invalidDataRef
+-2011	invalidSampleTable	invalidSampleTable
+-2010	invalidMovie	invalidMovie
+-2009	invalidTrack	invalidTrack
+-2008	invalidMedia	invalidMedia
+-2007	noDataHandler	noDataHandler
+-2006	noMediaHandler	noMediaHandler
+-2005	badComponentType	badComponentType
+-2004	cantOpenHandler	cantOpenHandler
+-2003	cantFindHandler	cantFindHandler
+-2002	badPublicMovieAtom	badPublicMovieAtom
+-2001	badImageDescription	badImageDescription
+-2000	couldNotResolveDataRef	couldNotResolveDataRef
+-1862	nonDragOriginatorErr	illegal attempt at originator only data
+-1861	badImageErr	bad translucent image PixMap
+-1860	badImageRgnErr	bad translucent image region
+-1859	noSuitableDisplaysErr	no displays support translucency
+-1858	unsupportedForPlatformErr	call is for PowerPC only
+-1857	dragNotAcceptedErr	drag was not accepted by receiver
+-1856	handlerNotFoundErr	handler not found
+-1855	duplicateHandlerErr	handler already exists
+-1854	cantGetFlavorErr	error while trying to get flavor data
+-1853	duplicateFlavorErr	flavor type already exists
+-1852	badDragFlavorErr	unknown flavor type
+-1851	badDragItemErr	unknown drag item reference
+-1850	badDragRefErr	unknown drag reference
+-1813	errEndOfBody	errEndOfBody
+-1812	errEndOfDocument	errEndOfDocument
+-1811	errTopOfBody	errTopOfBody
+-1810	errTopOfDocument	errTopOfDocument
+-1801	errOffsetIsOutsideOfView	errOffsetIsOutsideOfView
+-1800	errOffsetInvalid	errOffsetInvalid
+-1762	errOSACantOpenComponent	Can't connect to scripting system with that ID
+-1761	errOSAComponentMismatch	Parameters are from 2 different components
+-1759	errOSADataFormatTooNew	errOSADataFormatTooNew
+-1758	errOSADataFormatObsolete	errOSADataFormatObsolete
+-1757	errOSANoSuchDialect	errOSANoSuchDialect
+-1756	errOSASourceNotAvailable	errOSASourceNotAvailable
+-1754	errOSABadSelector	errOSABadSelector
+-1753	errOSAScriptError	errOSAScriptError
+-1752	errOSABadStorageType	errOSABadStorageType
+-1751	errOSAInvalidID	errOSAInvalidID
+-1750	errOSASystemError	errOSASystemError
+-1741	errAEBufferTooSmall	buffer for AEFlattenDesc too small
+-1740	errAEBuildSyntaxError	AEBuildDesc and friends detected a syntax error
+-1739	errAEDescIsNull	attempting to perform an invalid operation on a null descriptor
+-1738	errAEStreamAlreadyConverted	attempt to convert a stream that has already been converted
+-1737	errAEStreamBadNesting	nesting violation while streaming
+-1736	errAEDuplicateHandler	attempt to install handler in table for identical class and id (1.1 or greater)
+-1735	errAEEventFiltered	event has been filtered, and should not be propogated (1.1 or greater)
+-1734	errAEReceiveEscapeCurrent	break out of only lowest level of AEReceive (1.1 or greater)
+-1733	errAEReceiveTerminate	break out of all levels of AEReceive to the topmost (1.1 or greater)
+-1732	errAERecordingIsAlreadyOn	available only in version 1.0.1 or greater
+-1731	errAEUnknownObjectType	available only in version 1.0.1 or greater
+-1730	errAEEmptyListContainer	Attempt to pass empty list as container to accessor
+-1729	errAENegativeCount	CountProc returned negative value
+-1728	errAENoSuchObject	e.g.,: specifier asked for the 3rd, but there are only 2. Basically, this indicates a run-time resolution error.
+-1727	errAENotAnObjSpec	Param to AEResolve not of type 'obj '
+-1726	errAEBadTestKey	Test is neither typeLogicalDescriptor nor typeCompDescriptor
+-1725	errAENoSuchLogical	Something other than AND, OR, or NOT
+-1723	errAEAccessorNotFound	Accessor proc matching wantClass and containerType or wildcards not found
+-1721	errAEWrongNumberArgs	Logical op kAENOT used with other than 1 term
+-1720	errAEImpossibleRange	A range like 3rd to 2nd, or 1st to all.
+-1719	errAEIllegalIndex	index is out of range in a put operation
+-1718	errAEReplyNotArrived	the contents of the reply you are accessing have not arrived yet
+-1717	errAEHandlerNotFound	no handler in the dispatch tables fits the parameters to AEGetEventHandler or AEGetCoercionHandler
+-1716	errAEUnknownAddressType	the target address type is not known
+-1715	errAEParamMissed	a required parameter was not accessed
+-1714	errAENotASpecialFunction	there is no special function for/with this keyword
+-1713	errAENoUserInteraction	no user interaction is allowed
+-1712	errAETimeout	the AppleEvent timed out
+-1711	errAEWaitCanceled	in AESend, the user cancelled out of wait loop for reply or receipt
+-1710	errAEUnknownSendMode	mode wasn't NoReply, WaitReply, or QueueReply or Interaction level is unknown
+-1709	errAEReplyNotValid	AEResetTimer was passed an invalid reply parameter
+-1708	errAEEventNotHandled	the AppleEvent was not handled by any handler
+-1707	errAENotAppleEvent	the event is not in AppleEvent format
+-1706	errAENewerVersion	need newer version of the AppleEvent manager
+-1705	errAEBadListItem	the specified list item does not exist
+-1704	errAENotAEDesc	errAENotAEDesc
+-1703	errAEWrongDataType	errAEWrongDataType
+-1702	errAECorruptData	errAECorruptData
+-1701	errAEDescNotFound	errAEDescNotFound
+-1700	errAECoercionFail	bad parameter data or unable to coerce the data supplied
+-1424	errFSIteratorNotSupported	The iterator's flags or container are not supported by this call
+-1423	errFSIteratorNotFound	Passed FSIterator is not an open iterator
+-1422	errFSBadIteratorFlags	Flags passed to FSOpenIterator are bad
+-1421	errFSForkExists	Named fork already exists.
+-1420	errFSRefsDifferent	FSCompareFSRefs; refs are for different objects
+-1419	errFSBadSearchParams	Something wrong with CatalogSearch searchParams
+-1418	errFSBadItemCount	maximumItems was zero
+-1417	errFSNoMoreItems	Iteration ran out of items to return
+-1413	errFSBadAllocFlags	Invalid bits set in allocationFlags
+-1412	errFSBadPosMode	Newline bits set in positionMode
+-1411	errFSMissingName	A Unicode name parameter was NULL or nameLength parameter was zero
+-1410	errFSNameTooLong	File/fork name is too long to create/rename
+-1409	errFSForkNotFound	Named fork does not exist
+-1407	errFSNotAFolder	Expected a folder, got a file
+-1406	errFSMissingCatInfo	A CatalogInfo parameter was NULL
+-1405	errFSBadInfoBitmap	A CatalogInfoBitmap or VolumeInfoBitmap has reserved or invalid bits set
+-1404	errFSBadForkRef	A ForkRefNum parameter was bad
+-1403	errFSBadBuffer	A buffer parameter was bad
+-1402	errFSBadForkName	Fork name parameter is bad
+-1401	errFSBadFSRef	FSRef parameter is bad
+-1400	errFSUnknownCall	selector is not recognized by this filesystem
+-1327	badFCBErr	FCBRecPtr is not valid
+-1311	volVMBusyErr	can't eject because volume is in use by VM
+-1310	fsDataTooBigErr	file or volume is too big for system
+-1309	fileBoundsErr	file's EOF, offset, mark or size is too big
+-1308	notARemountErr	when _Mount allows only remounts and doesn't get one
+-1307	badFidErr	file id is dangling or doesn't match with the file number
+-1306	sameFileErr	can't exchange a file with itself
+-1305	desktopDamagedErr	desktop database files are corrupted
+-1304	catChangedErr	the catalog has been modified
+-1303	diffVolErr	files on different volumes
+-1302	notAFileErr	directory specified
+-1301	fidExists	file id already exists
+-1300	fidNotFound	no file thread exists.
+-1280	errRefNum	bad connection refNum
+-1279	errAborted	control call was aborted
+-1278	errState	bad connection state for this operation
+-1277	errOpening	open connection request failed
+-1276	errAttention	attention message too long
+-1275	errFwdReset	read terminated by forward reset
+-1274	errDSPQueueSize	DSP Read/Write Queue Too small
+-1273	errOpenDenied	open connection request was denied
+-1105	reqAborted	reqAborted
+-1104	noDataArea	noDataArea
+-1103	noSendResp	noSendResp
+-1102	cbNotFound	cbNotFound
+-1101	noRelErr	noRelErr
+-1100	badBuffNum	badBuffNum
+-1099	badATPSkt	badATPSkt
+-1098	tooManySkts	tooManySkts
+-1097	tooManyReqs	tooManyReqs
+-1096	reqFailed	reqFailed
+-1075	aspNoAck	No ack on attention request (server err)
+-1074	aspTooMany	Too many clients (server error)
+-1073	aspSizeErr	Command block too big
+-1072	aspSessClosed	Session closed
+-1071	aspServerBusy	Server cannot open another session
+-1070	aspParamErr	Parameter error
+-1069	aspNoServers	No servers at that address
+-1068	aspNoMoreSess	No more sessions on server
+-1067	aspBufTooSmall	Buffer too small
+-1066	aspBadVersNum	Server cannot support this ASP version
+-1029	nbpNISErr	Error trying to open the NIS
+-1028	nbpNotFound	Name not found on remove
+-1027	nbpDuplicate	Duplicate name exists already
+-1026	nbpConfDiff	Name confirmed at different socket
+-1025	nbpNoConfirm	nbpNoConfirm
+-1024	nbpBuffOvr	Buffer overflow in LookupName
+-1000	noMaskFoundErr	Icon Utilties Error
+-985	kFMFontContainerAccessErr	kFMFontContainerAccessErr
+-984	kFMFontTableAccessErr	kFMFontTableAccessErr
+-983	kFMIterationScopeModifiedErr	kFMIterationScopeModifiedErr
+-982	kFMInvalidFontErr	kFMInvalidFontErr
+-981	kFMInvalidFontFamilyErr	kFMInvalidFontFamilyErr
+-980	kFMIterationCompleted	kFMIterationCompleted
+-932	guestNotAllowedErr	destination port requires authentication
+-931	badLocNameErr	location name malformed
+-930	badServiceMethodErr	illegal service type, or not supported
+-928	noUserRecErr	Invalid user reference number
+-927	authFailErr	unable to authenticate user at destination
+-926	noInformErr	PPCStart failed because destination did not have inform pending
+-925	networkErr	An error has occurred in the network, not too likely
+-924	noUserRefErr	unable to create a new userRefNum
+-923	notLoggedInErr	The default userRefNum does not yet exist
+-922	noDefaultUserErr	user hasn't typed in owners name in Network Setup Control Pannel
+-919	badPortNameErr	PPCPortRec malformed
+-917	sessClosedErr	session was closed
+-916	portClosedErr	port was closed
+-915	noResponseErr	unable to contact destination
+-914	noToolboxNameErr	A system resource is missing, not too likely
+-913	noMachineNameErr	user hasn't named his Macintosh in the Network Setup Control Panel
+-912	userRejectErr	Destination rejected the session request
+-911	noUserNameErr	user name unknown on destination machine
+-910	portNameExistsErr	port is already open (perhaps in another app)
+-909	badReqErr	bad parameter or invalid state for operation
+-908	noSessionErr	Invalid session reference number
+-907	sessTableErr	Out of session tables, try again later
+-906	destPortErr	Port does not exist at destination
+-905	localOnlyErr	Network activity is currently disabled
+-904	noGlobalsErr	The system is hosed, better re-boot
+-903	noPortErr	Unable to open port or bad portRefNum.  If you're calling
+-902	nameTypeErr	Invalid or inappropriate locationKindSelector in locationName
+-900	notInitErr	PPCToolBox not initialized
+-877	notAppropriateForClassic	This application won't or shouldn't run on Classic (Problem 2481058).
+-876	appVersionTooOld	The application's creator and version are incompatible with the current version of Mac OS.
+-875	wrongApplicationPlatform	The application could not launch because the required platform is not available
+-863	hmCloseViewActive	Returned from HMRemoveBalloon if CloseView was active
+-862	hmNoBalloonUp	Returned from HMRemoveBalloon if no balloon was visible when call was made
+-861	hmOperationUnsupported	Returned from HMShowBalloon call if bad method passed to routine
+-859	hmUnknownHelpType	Returned if help msg record contained a bad type
+-858	hmWrongVersion	Returned if help mgr resource was the wrong version
+-857	hmSkippedBalloon	Returned from calls if helpmsg specified a skip balloon
+-855	hmHelpManagerNotInited	Returned from HMGetHelpMenuHandle if help menu not setup
+-854	hmSameAsLastBalloon	Returned from HMShowMenuBalloon if menu & item is same as last time
+-853	hmBalloonAborted	Returned if mouse was moving or mouse wasn't in window port rect
+-850	hmHelpDisabled	Show Balloons mode was off, call to routine ignored
+-813	rcDBPackNotInited	attempt to call other routine before InitDBPack
+-812	rcDBWrongVersion	incompatible versions
+-811	rcDBNoHandler	no app handler for specified data type
+-810	rcDBBadAsyncPB	tried to kill a bad pb
+-809	rcDBAsyncNotSupp	ddev does not support async calls
+-808	rcDBBadDDEV	bad ddev specified on DBInit
+-807	rcDBBadSessNum	bad session number for DBGetConnInfo
+-806	rcDBBadSessID	rcDBBadSessID
+-805	rcDBExec	rcDBExec
+-804	rcDBBreak	rcDBBreak
+-803	rcDBBadType	rcDBBadType
+-802	rcDBError	rcDBError
+-801	rcDBValue	rcDBValue
+-800	rcDBNull	rcDBNull
+-677	icTooManyProfilesErr	too many profiles in database
+-676	icProfileNotFoundErr	profile not found
+-675	icConfigInappropriateErr	incorrect manufacturer code
+-674	icConfigNotFoundErr	no internet configuration was found
+-673	icNoURLErr	no URL found
+-672	icNothingToOverrideErr	no component for the override component to capture
+-671	icNoMoreWritersErr	you cannot begin a write session because someone else is already doing it
+-670	icTruncatedErr	more data was present than was returned
+-669	icInternalErr	Internet Config internal error
+-668	icPrefDataErr	problem with preference data
+-667	icPermErr	cannot set preference
+-666	icPrefNotFoundErr	Internet preference not found
+-648	vmInvalidOwningProcessErr	current process does not own the BackingFileID or FileViewID
+-647	vmAddressNotInFileViewErr	address is not in a FileView
+-646	vmNoMoreFileViewsErr	no more FileViews were found
+-645	vmFileViewAccessErr	requested FileViewAccess cannot be obtained
+-644	vmInvalidFileViewIDErr	invalid FileViewID
+-643	vmNoMoreBackingFilesErr	no more BackingFiles were found
+-642	vmBusyBackingFileErr	open views found on BackingFile
+-641	vmMappingPrivilegesErr	requested MappingPrivileges cannot be obtained
+-640	vmInvalidBackingFileIDErr	invalid BackingFileID
+-626	noMMUErr	no MMU present
+-625	cannotDeferErr	unable to defer additional functions
+-624	interruptsMaskedErr	donÕt call with interrupts masked
+-623	notLockedErr	specified range of memory is not locked
+-622	cannotMakeContiguousErr	cannot make specified range contiguous
+-621	notHeldErr	specified range of memory is not held
+-620	notEnoughMemoryErr	insufficient physical memory
+-619	threadProtocolErr	threadProtocolErr
+-618	threadNotFoundErr	threadNotFoundErr
+-617	threadTooManyReqsErr	threadTooManyReqsErr
+-610	noUserInteractionAllowed	no user interaction allowed
+-609	connectionInvalid	connectionInvalid
+-608	noOutstandingHLE	noOutstandingHLE
+-607	bufferIsSmall	error returns from Post and Accept
+-606	appIsDaemon	app is BG-only, and launch flags disallow this
+-605	appMemFullErr	application SIZE not big enough for launch
+-604	hardwareConfigErr	hardware configuration not correct for call
+-603	protocolErr	app made module calls in improper order
+-602	appModeErr	memory mode is 32-bit, but app not 32-bit clean
+-601	memFragErr	not enough room to launch app w/special requirements
+-600	procNotFound	no eligible process with specified descriptor
+-503	driverHardwareGoneErr	disk driver's hardware was disconnected
+-502	hwParamErr	bad selector for _HWPriv
+-501	teScrapSizeErr	scrap item too big for text edit record
+-500	rgnTooBigErr	rgnTooBigErr
+-492	exUserBreak	user debugger break; execute debugger commands on stack
+-491	strUserBreak	user debugger break; display string on stack
+-490	userBreak	user debugger break
+-463	notThePublisherWrn	not the first registered publisher for that container
+-462	containerAlreadyOpenWrn	container already opened by this section
+-461	containerNotFoundWrn	could not find editionContainer at this time
+-460	multiplePublisherWrn	A Publisher is already registered for that container
+-454	badSubPartErr	can not use sub parts in this release
+-453	badEditionFileErr	edition file is corrupt
+-452	notRegisteredSectionErr	not a registered SectionRecord
+-451	badSectionErr	not a valid SectionRecord
+-450	editionMgrInitErr	edition manager not inited by this app
+-438	fsmUnknownFSMMessageErr	unknown message passed to FSM
+-437	fsmNoAlternateStackErr	no alternate stack for HFS CI
+-436	fsmBadFSDVersionErr	FSM version incompatible with FSD
+-435	fsmDuplicateFSIDErr	FSID already exists on InstallFS
+-434	fsmBadFSDLenErr	FSD size incompatible with current FSM vers
+-433	fsmBadFFSNameErr	Name length not 1 <= length <= 31
+-432	fsmBusyFFSErr	File system is busy, cannot be removed
+-431	fsmFFSNotFoundErr	Foreign File system does not exist - new Pack2 could return this error too
+-417	btKeyAttrErr	There is no such a key attribute.
+-416	btKeyLenErr	Maximum key length is too long or equal to zero.
+-415	btRecNotFnd	Record cannot be found.
+-414	btDupRecErr	Record already exists.
+-413	btNoSpace	Can't allocate disk space.
+-410	notBTree	The file is not a dictionary.
+-400	gcrOnMFMErr	gcr format on high density media error
+-360	slotNumErr	invalid slot # error
+-351	smRecNotFnd	Record not found in the SRT.
+-350	smSRTOvrFlErr	SRT over flow.
+-349	smNoGoodOpens	No opens were successfull in the loop.
+-348	smOffsetErr	Offset was too big (temporary error
+-347	smByteLanesErr	NumByteLanes was determined to be zero.
+-346	smBadsPtrErr	Bad pointer was passed to sCalcsPointer
+-345	smsGetDrvrErr	Error occurred during _sGetDriver.
+-344	smNoMoresRsrcs	No more sResources
+-343	smDisDrvrNamErr	Error occurred during _sDisDrvrName.
+-342	smGetDrvrNamErr	Error occurred during _sGetDrvrName.
+-341	smCkStatusErr	Status of slot = fail.
+-340	smBlkMoveErr	_BlockMove error
+-339	smNewPErr	_NewPtr error
+-338	smSelOOBErr	Selector out of bounds error
+-337	smSlotOOBErr	Slot out of bounds error
+-336	smNilsBlockErr	Nil sBlock error (Dont allocate and try to use a nil sBlock)
+-335	smsPointerNil	LPointer is nil From sOffsetData. If this error occurs; check sInfo rec for more information.
+-334	smCPUErr	Code revision is wrong
+-333	smCodeRevErr	Code revision is wrong
+-332	smReservedErr	Reserved field not zero
+-331	smBadsList	Bad sList: Id1 < Id2 < Id3 ...format is not followed.
+-330	smBadRefId	Reference Id not found in List
+-320	smBusErrTO	BusError time out.
+-319	smBadBoardId	BoardId was wrong; re-init the PRAM record.
+-318	smReservedSlot	slot is reserved, VM should not use this address space.
+-317	smInitTblVErr	An error occurred while trying to initialize the Slot Resource Table.
+-316	smInitStatVErr	The InitStatusV field was negative after primary or secondary init.
+-315	smNoBoardId	No Board Id.
+-314	smGetPRErr	Error occurred during _sGetPRAMRec (See SIMStatus).
+-313	smNoBoardSRsrc	No Board sResource.
+-312	smDisposePErr	_DisposePointer error
+-311	smFHBlkDispErr	Error occurred during _sDisposePtr (Dispose of FHeader block).
+-310	smFHBlockRdErr	Error occurred during _sGetFHeader.
+-309	smBLFieldBad	ByteLanes field was bad.
+-308	smUnExBusErr	Unexpected BusError
+-307	smResrvErr	Fatal reserved error. Resreved field <> 0.
+-306	smNosInfoArray	No sInfoArray. Memory Mgr error.
+-305	smDisabledSlot	This slot is disabled (-305 use to be smLWTstBad)
+-304	smNoDir	Directory offset is Nil
+-303	smRevisionErr	Wrong revison level
+-302	smFormatErr	FHeader Format is not Apple's
+-301	smCRCFail	CRC check failed for declaration data
+-300	smEmptySlot	No card in slot
+-299	nmTypErr	Notification Manager:wrong queue type
+-293	smPriInitErr	Error; Cards could not be initialized.
+-292	smPRAMInitErr	Error; Slot Resource Table could not be initialized.
+-291	smSRTInitErr	Error; Slot Resource Table could not be initialized.
+-290	smSDMInitErr	Error; SDM could not be initialized.
+-261	midiInvalidCmdErr	command not supported for port type
+-260	midiDupIDErr	duplicate client ID
+-259	midiNameLenErr	name supplied is longer than 31 characters
+-258	midiWriteErr	MIDIWritePacket couldn't write to all connected ports
+-257	midiNoConErr	no connection exists between specified ports
+-256	midiVConnectRmvd	pending virtual connection removed
+-255	midiVConnectMade	pending virtual connection resolved
+-254	midiVConnectErr	pending virtual connection created
+-253	midiTooManyConsErr	too many connections made
+-252	midiTooManyPortsErr	too many ports already installed in the system
+-251	midiNoPortErr	no port with that ID found
+-250	midiNoClientErr	no client with that ID found
+-247	badInputText	badInputText
+-246	badDictFormat	badDictFormat
+-245	incompatibleVoice	incompatibleVoice
+-244	voiceNotFound	voiceNotFound
+-243	bufTooSmall	bufTooSmall
+-242	synthNotReady	synthNotReady
+-241	synthOpenFailed	synthOpenFailed
+-240	noSynthFound	noSynthFound
+-232	siUnknownQuality	invalid quality selector (returned by driver)
+-231	siUnknownInfoType	invalid info type selector (returned by driver)
+-230	siInputDeviceErr	input device hardware failure
+-229	siBadRefNum	invalid input device reference number
+-228	siBadDeviceName	input device could not be opened
+-227	siDeviceBusyErr	input device already in use
+-226	siInvalidSampleSize	invalid sample size
+-225	siInvalidSampleRate	invalid sample rate
+-224	siHardDriveTooSlow	hard drive too slow to record to disk
+-223	siInvalidCompression	invalid compression type
+-222	siNoBufferSpecified	returned by synchronous SPBRecord if nil buffer passed
+-221	siBadSoundInDevice	invalid index passed to SoundInGetIndexedDevice
+-220	siNoSoundInHardware	no Sound Input hardware
+-213	siVBRCompressionNotSupported	vbr audio compression not supported for this operation
+-212	noMoreRealTime	not enough CPU cycles left to add another task
+-211	channelNotBusy	channelNotBusy
+-210	buffersTooSmall	can not operate in the memory allowed
+-209	channelBusy	the Channel is being used for a PFD already
+-208	badFileFormat	was not type AIFF or was of bad format,corrupt
+-207	notEnoughBufferSpace	could not allocate enough memory
+-206	badFormat	Sound Manager Error Returns
+-205	badChannel	Sound Manager Error Returns
+-204	resProblem	Sound Manager Error Returns
+-203	queueFull	Sound Manager Error Returns
+-201	notEnoughHardwareErr	Sound Manager Error Returns
+-200	noHardwareErr	Sound Manager Error Returns
+-199	mapReadErr	map inconsistent with operation
+-198	resAttrErr	attribute inconsistent with operation
+-197	rmvRefFailed	RmveReference failed
+-196	rmvResFailed	RmveResource failed
+-195	addRefFailed	AddReference failed
+-194	addResFailed	AddResource failed
+-193	resFNotFound	Resource file not found
+-192	resNotFound	Resource not found
+-190	inputOutOfBounds	Offset of Count out of bounds
+-189	writingPastEnd	Writing past end of file
+-188	resourceInMemory	Resource already in memory
+-186	CantDecompress	resource bent ("the bends") - can't decompress a compressed resource
+-185	badExtResource	extended resource has a bad format.
+-182	cmNoCurrentProfile	Responder error
+-181	cmUnsupportedDataType	Responder error
+-180	cmCantDeleteProfile	Responder error
+-179	cmCantXYZ	CMM cant handle XYZ space
+-178	cmCantConcatenateError	Profile can't be concatenated
+-177	cmProfilesIdentical	Profiles the same
+-176	cmProfileNotFound	Responder error
+-175	cmMethodNotFound	CMM not present
+-171	cmMethodError	cmMethodError
+-170	cmProfileError	cmProfileError
+-157	cDepthErr	invalid pixel depth
+-156	cResErr	invalid resolution for MakeITable
+-155	cDevErr	invalid type of graphics device
+-154	cProtectErr	colorTable entry protection violation
+-153	cRangeErr	range error on colorTable request
+-152	cNoMemErr	failed to allocate memory for structure
+-151	cTempMemErr	failed to allocate memory for temporary structures
+-150	cMatchErr	Color2Index failed to find an index
+-149	insufficientStackErr	insufficientStackErr
+-148	pixMapTooDeepErr	pixMapTooDeepErr
+-147	rgnOverflowErr	rgnOverflowErr
+-145	noMemForPictPlaybackErr	noMemForPictPlaybackErr
+-128	userCanceledErr	userCanceledErr
+-127	hMenuFindErr	could not find HMenu's parent in MenuKey (wrong error code - obsolete)
+-126	mBarNFnd	system error code for MBDF not found
+-125	updPixMemErr	insufficient memory to update a pixmap
+-124	volGoneErr	Server volume has been disconnected.
+-123	wrgVolTypErr	Wrong volume type error [operation not supported for MFS]
+-122	badMovErr	Move into offspring error
+-121	tmwdoErr	No free WDCB available
+-120	dirNFErr	Directory not found
+-117	memLockedErr	trying to move a locked block (MoveHHi)
+-116	memSCErr	Size Check failed
+-115	memBCErr	Block Check failed
+-114	memPCErr	Pointer Check failed
+-113	memAZErr	Address in zone check failed
+-112	memPurErr	trying to purge a locked or non-purgeable block
+-111	memWZErr	WhichZone failed (applied to free block)
+-110	memAdrErr	address was odd; or out of range
+-109	nilHandleErr	Master Pointer was NIL in HandleZone or other
+-108	memFullErr	Not enough room in heap zone
+-102	noTypeErr	No object of that type in scrap
+-100	noScrapErr	No scrap exists error
+-99	memROZWarn	soft error in ROZ
+-98	portNotCf	driver Open error code (parameter RAM not configured for this connection)
+-97	portInUse	driver Open error code (port is in use)
+-96	portNotPwr	serial port not currently powered
+-95	excessCollsns	excessive collisions on write
+-94	lapProtErr	error in attaching/detaching protocol
+-93	noBridgeErr	no network bridge for non-local send
+-92	eLenErr	Length error ddpLenErr
+-91	eMultiErr	Multicast address error ddpSktErr
+-90	breakRecd	Break received (SCC)
+-89	rcvrErr	SCC receiver error (framing; parity; OR)
+-88	prInitErr	InitUtil found the parameter ram uninitialized
+-87	prWrErr	parameter ram written didn't read-verify
+-86	clkWrErr	time written did not verify
+-85	clkRdErr	unable to read same clock value twice
+-84	verErr	track failed to verify
+-83	fmt2Err	can't get enough sync
+-82	fmt1Err	can't find sector 0 after track format
+-81	sectNFErr	sector number never found on a track
+-80	seekErr	track number wrong on address mark
+-79	spdAdjErr	unable to correctly adjust disk speed
+-78	twoSideErr	tried to read 2nd side on a 1-sided drive
+-77	initIWMErr	unable to initialize IWM
+-76	tk0BadErr	track 0 detect doesn't change
+-75	cantStepErr	step handshake failed
+-74	wrUnderrun	write underrun occurred
+-73	badDBtSlp	bad data mark bit slip nibbles
+-72	badDCksum	bad data mark checksum
+-71	noDtaMkErr	couldn't find a data mark header
+-70	badBtSlpErr	bad addr mark bit slip nibbles
+-69	badCksmErr	addr mark checksum didn't check
+-68	dataVerErr	read verify compare failed
+-67	noAdrMkErr	couldn't find valid addr mark
+-66	noNybErr	couldn't find 5 nybbles in 200 tries
+-65	offLinErr	r/w requested for an off-line drive
+-64	fontDecError	error during font declaration
+-61	wrPermErr	write permissions error
+-60	badMDBErr	bad master directory block
+-59	fsRnErr	file system internal error:during rename the old entry was deleted but could not be restored.
+-58	extFSErr	volume in question belongs to an external fs
+-57	noMacDskErr	not a mac diskette (sig bytes are wrong)
+-56	nsDrvErr	no such drive (tried to mount a bad drive num)
+-55	volOnLinErr	drive volume already on-line at MountVol
+-54	permErr	permissions error (on file open)
+-53	volOffLinErr	volume not on line error (was Ejected)
+-52	gfpErr	get file position error
+-51	rfNumErr	refnum error
+-50	paramErr	error in user parameter list
+-49	opWrErr	file already open with with write permission
+-48	dupFNErr	duplicate filename (rename)
+-47	fBsyErr	File is busy (delete)
+-46	vLckdErr	volume is locked
+-45	fLckdErr	file is locked
+-44	wPrErr	diskette is write protected.
+-43	fnfErr	File not found
+-42	tmfoErr	too many files open
+-41	mFulErr	memory full (open) or file won't fit (load)
+-40	posErr	tried to position to before start of file (r/w)
+-39	eofErr	End of file
+-38	fnOpnErr	File not open
+-37	bdNamErr	there may be no bad names in the final system!
+-36	ioErr	I/O error (bummers)
+-35	nsvErr	no such volume
+-34	dskFulErr	disk full
+-33	dirFulErr	Directory full
+-30	dceExtErr	dce extension error
+-29	unitTblFullErr	unit table has no more entries
+-28	notOpenErr	Couldn't rd/wr/ctl/sts cause driver not opened
+-27	iIOAbortErr	IO abort error (Printing Manager)
+-26	dInstErr	DrvrInstall couldn't find driver in resources
+-25	dRemovErr	tried to remove an open driver
+-24	closErr	I/O System Errors
+-23	openErr	I/O System Errors
+-22	unitEmptyErr	I/O System Errors
+-21	badUnitErr	I/O System Errors
+-20	writErr	I/O System Errors
+-19	readErr	I/O System Errors
+-18	statusErr	I/O System Errors
+-17	controlErr	I/O System Errors
+-13	dsExtensionsDisabled	say –Extensions Disabled”
+-12	dsHD20Installed	say –HD20 Startup”
+-11	dsDisassemblerInstalled	say –Disassembler Installed”
+-10	dsMacsBugInstalled	say –MacsBug Installed”
+-8	seNoDB	no debugger installed to handle debugger command
+-5	SlpTypeErr	invalid queue element
+-4	unimpErr	unimplemented core routine
+-3	corErr	core routine number out of range
+-2	dsNoExtsDisassembler	not a SysErr, just a placeholder
+-1	qErr	queue element not found during deletion
+0	tsmComponentNoErr	component result = no error
+1	EPERM	Operation not permitted
+2	ENOENT	No such file or directory
+3	ESRCH	No such process
+4	EINTR	Interrupted system call
+5	EIO	Input/output error
+6	ENXIO	Device not configured
+7	E2BIG	Argument list too long
+8	ENOEXEC	Exec format error
+9	EBADF	Bad file descriptor
+10	ECHILD	No child processes
+11	EDEADLK	Resource deadlock avoided
+12	ENOMEM	Cannot allocate memory
+13	EACCES	Permission denied
+14	EFAULT	Bad address
+15	ECANCELED	Operation cancelled
+16	EBUSY	Device busy
+17	EEXIST	File exists
+18	EXDEV	Cross-device link
+19	ENODEV	Operation not supported by device
+20	ENOTDIR	Not a directory
+21	EISDIR	Is a directory
+22	EINVAL	Invalid argument
+23	ENFILE	Too many open files in system
+24	EMFILE	Too many open files
+25	ENOTTY	Inappropriate ioctl for device
+26	ESIGPARM	Signal error
+27	EFBIG	File too large
+28	ENOSPC	No space left on device
+29	ESPIPE	Illegal seek
+30	EROFS	Read-only file system
+31	EMLINK	Too many links
+32	EPIPE	Broken pipe
+33	EDOM	Numerical argument out of domain
+34	ERANGE	Result too large
+35	EAGAIN	Resource temporarily unavailable
+36	EINPROGRESS	Operation now in progress
+37	EALREADY	Operation already in progress
+38	ENOTSOCK	Socket operation on non-socket
+39	EDESTADDRREQ	Destination address required
+40	EMSGSIZE	Message too long
+41	EPROTOTYPE	Protocol wrong type for socket
+42	ENOPROTOOPT	Protocol not available
+43	EPROTONOSUPPORT	Protocol not supported
+44	ESOCKTNOSUPPORT	Socket type not supported
+45	EOPNOTSUPP	Operation not supported
+46	EPFNOSUPPORT	Protocol family not supported
+47	EAFNOSUPPORT	Address family not supported by protocol family
+48	EADDRINUSE	Address already in use
+49	EADDRNOTAVAIL	Can't assign requested address
+50	ENETDOWN	Network is down
+51	ENETUNREACH	Network is unreachable
+52	ENETRESET	Network dropped connection on reset
+53	ECONNABORTED	Software caused connection abort
+54	ECONNRESET	Connection reset by peer
+55	ENOBUFS	No buffer space available
+56	EISCONN	Socket is already connected
+57	ENOTCONN	Socket is not connected
+58	ESHUTDOWN	Can't send after socket shutdown
+59	ETOOMANYREFS	Too many references: can't splice
+60	ETIMEDOUT	Operation timed out
+61	ECONNREFUSED	Connection refused
+62	ELOOP	Too many levels of symbolic links
+63	ENAMETOOLONG	File name too long
+64	EHOSTDOWN	Host is down
+65	EHOSTUNREACH	No route to host
+66	ENOTEMPTY	Directory not empty
+67	ELOOK	Internal mapping for kOTLookErr, don't return to client
+77	ENOLCK	No locks available
+78	ENOSYS	Function not implemented
+88	EILSEQ	Wide character encoding error
+99	EUNKNOWN	Unknown error

Added: vendor/Python/current/Mac/scripts/genallsuites.py
===================================================================
--- vendor/Python/current/Mac/scripts/genallsuites.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/scripts/genallsuites.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,52 @@
+# Generate all the standard scripting suite packages.
+# Note that this module needs *serious* hand-crafting because of all the
+# absolute paths. It is, however, a great leap forward compared to the time
+# when this information was only stored in Jack's brain:-)
+
+import sys
+import os
+import gensuitemodule
+
+verbose=sys.stdout
+
+DSTDIR="/Users/jack/src/python/Lib/plat-mac/lib-scriptpackages"
+OS9DISK="/Volumes/Moes"
+
+APPLESCRIPT=OS9DISK + "/Systeemmap/Extensies/AppleScript"
+SYSTEMEVENTS="/System/Library/CoreServices/System Events.app"
+
+CODEWARRIOR=OS9DISK + "/Applications (Mac OS 9)/Metrowerks CodeWarrior 7.0/Metrowerks CodeWarrior/CodeWarrior IDE 4.2.6"
+EXPLORER="/Applications/Internet Explorer.app"
+FINDER="/System/Library/CoreServices/Finder.app"
+NETSCAPE=OS9DISK + "/Applications (Mac OS 9)/Netscape Communicator\xe2\x84\xa2 Folder/Netscape Communicator\xe2\x84\xa2"
+TERMINAL="/Applications/Utilities/Terminal.app"
+
+gensuitemodule.processfile_fromresource(APPLESCRIPT,
+        output=os.path.join(DSTDIR, 'StdSuites'),
+        basepkgname='_builtinSuites',
+        edit_modnames=[], verbose=verbose)
+gensuitemodule.processfile(SYSTEMEVENTS,
+        output=os.path.join(DSTDIR, 'SystemEvents'),
+        basepkgname='StdSuites',
+        edit_modnames=[('Disk_2d_Folder_2d_File_Suite', 'Disk_Folder_File_Suite')],
+        verbose=verbose)
+gensuitemodule.processfile(CODEWARRIOR,
+        output=os.path.join(DSTDIR, 'CodeWarrior'),
+        basepkgname='StdSuites',
+        edit_modnames=[], verbose=verbose)
+gensuitemodule.processfile(EXPLORER,
+        output=os.path.join(DSTDIR, 'Explorer'),
+        basepkgname='StdSuites',
+        edit_modnames=[], verbose=verbose)
+gensuitemodule.processfile(FINDER,
+        output=os.path.join(DSTDIR, 'Finder'),
+        basepkgname='StdSuites',
+        edit_modnames=[], verbose=verbose)
+gensuitemodule.processfile(NETSCAPE,
+        output=os.path.join(DSTDIR, 'Netscape'),
+        basepkgname='StdSuites',
+        edit_modnames=[('WorldWideWeb_suite_2c__as_d', 'WorldWideWeb_suite')], verbose=verbose)
+gensuitemodule.processfile(TERMINAL,
+        output=os.path.join(DSTDIR, 'Terminal'),
+        basepkgname='StdSuites',
+        edit_modnames=[], verbose=verbose)

Added: vendor/Python/current/Mac/scripts/mkestrres-errno.h
===================================================================
--- vendor/Python/current/Mac/scripts/mkestrres-errno.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/scripts/mkestrres-errno.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,7 @@
+/* These are defined in MSL errno.h, but unfortunately not documented */
+#define EFPOS		35		/* File positioning error */
+#define	ESIGPARM	36		/* Signal argument error */
+#define	ENOMEM		37		/* Cannot allocate memory */
+#define	EACCES		38		/* Permission denied */
+#define	ENOENT		39		/* No such file or directory */
+#define	ENOSYS		40		/* Function not implemented */

Added: vendor/Python/current/Mac/scripts/mkestrres-macerrors.h
===================================================================
--- vendor/Python/current/Mac/scripts/mkestrres-macerrors.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/scripts/mkestrres-macerrors.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,13 @@
+ /* Errors from InternetConfig.h */
+  icPrefNotFoundErr             = -666, /* Internet preference not found */
+  icPermErr                     = -667, /* cannot set preference  */
+  icPrefDataErr                 = -668, /* problem with preference data  */
+  icInternalErr                 = -669, /* Internet Config internal error  */
+  icTruncatedErr                = -670, /* more data was present than was returned  */
+  icNoMoreWritersErr            = -671, /* you cannot begin a write session because someone else is already doing it  */
+  icNothingToOverrideErr        = -672, /* no component for the override component to capture  */
+  icNoURLErr                    = -673, /* no URL found  */
+  icConfigNotFoundErr           = -674, /* no internet configuration was found  */
+  icConfigInappropriateErr      = -675, /* incorrect manufacturer code  */
+  icProfileNotFoundErr          = -676, /* profile not found  */
+  icTooManyProfilesErr          = -677  /* too many profiles in database  */


Property changes on: vendor/Python/current/Mac/scripts/mkestrres-macerrors.h
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Mac/scripts/mkestrres.py
===================================================================
--- vendor/Python/current/Mac/scripts/mkestrres.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/scripts/mkestrres.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,157 @@
+"""Parse sys/errno.h and Errors.h and create Estr resource"""
+
+import re
+import string
+from Carbon import Res
+import os
+
+READ = 1
+WRITE = 2
+smAllScripts = -3
+
+ERRNO_PROG="#define[ \t]+" \
+                   "([A-Z0-9a-z_]+)" \
+                   "[ \t]+" \
+                   "([0-9]+)" \
+                   "[ \t]*/\*[ \t]*" \
+                   "(.*)" \
+                   "[ \t]*\*/"
+
+ERRORS_PROG="[ \t]*" \
+                        "([A-Z0-9a-z_]+)" \
+                        "[ \t]*=[ \t]*" \
+                        "([-0-9]+)" \
+                        "[, \t]*/\*[ \t]*" \
+                        "(.*)" \
+                        "[ \t]*\*/"
+
+ERRORS_PROG_2="[ \t]*" \
+                        "([A-Z0-9a-z_]+)" \
+                        "[ \t]*=[ \t]*" \
+                        "([-0-9]+)" \
+                        "[, \t]*"
+
+def Pstring(str):
+    if len(str) > 255:
+        raise ValueError, 'String too large'
+    return chr(len(str))+str
+
+def writeestr(dst, edict):
+    """Create Estr resource file given a dictionary of errors."""
+
+    os.unlink(dst.as_pathname())
+    Res.FSpCreateResFile(dst, 'RSED', 'rsrc', smAllScripts)
+    output = Res.FSpOpenResFile(dst, WRITE)
+    Res.UseResFile(output)
+    for num in edict.keys():
+        res = Res.Resource(Pstring(edict[num][0]))
+        res.AddResource('Estr', num, '')
+        res.WriteResource()
+    Res.CloseResFile(output)
+
+def writepython(fp, dict):
+    k = dict.keys()
+    k.sort()
+    for i in k:
+        fp.write("%s\t=\t%d\t#%s\n"%(dict[i][1], i, dict[i][0]))
+
+
+def parse_errno_h(fp, dict):
+    errno_prog = re.compile(ERRNO_PROG)
+    for line in fp.readlines():
+        m = errno_prog.match(line)
+        if m:
+            number = string.atoi(m.group(2))
+            name = m.group(1)
+            desc = string.strip(m.group(3))
+
+            if not dict.has_key(number):
+                dict[number] = desc, name
+            else:
+                print 'DUPLICATE', number
+                print '\t', dict[number]
+                print '\t', (desc, name)
+
+def parse_errors_h(fp, dict):
+    errno_prog = re.compile(ERRORS_PROG)
+    errno_prog_2 = re.compile(ERRORS_PROG_2)
+    for line in fp.readlines():
+        match = 0
+        m = errno_prog.match(line)
+        m2 = errno_prog_2.match(line)
+        if m:
+            number = string.atoi(m.group(2))
+            name = m.group(1)
+            desc = string.strip(m.group(3))
+            match=1
+        elif m2:
+            number = string.atoi(m2.group(2))
+            name = m2.group(1)
+            desc = name
+            match=1
+        if match:
+            if number > 0: continue
+
+            if not dict.has_key(number):
+                dict[number] = desc, name
+            else:
+                print 'DUPLICATE', number
+                print '\t', dict[number]
+                print '\t', (desc, name)
+                if len(desc) > len(dict[number][0]):
+                    print 'Pick second one'
+                    dict[number] = desc, name
+
+def main():
+    dict = {}
+    pathname = EasyDialogs.AskFileForOpen(message="Where is GUSI sys/errno.h?")
+    if pathname:
+        fp = open(pathname)
+        parse_errno_h(fp, dict)
+        fp.close()
+
+    pathname = EasyDialogs.AskFileForOpen(message="Select cerrno (MSL) or cancel")
+    if pathname:
+        fp = open(pathname)
+        parse_errno_h(fp, dict)
+        fp.close()
+
+    pathname = EasyDialogs.AskFileForOpen(message="Where is MacErrors.h?")
+    if pathname:
+        fp = open(pathname)
+        parse_errors_h(fp, dict)
+        fp.close()
+
+    pathname = EasyDialogs.AskFileForOpen(message="Where is mkestrres-MacErrors.h?")
+    if pathname:
+        fp = open(pathname)
+        parse_errors_h(fp, dict)
+        fp.close()
+
+    if not dict:
+        return
+
+    pathname = EasyDialogs.AskFileForSave(message="Resource output file?", savedFileName="errors.rsrc")
+    if pathname:
+        writeestr(fss, dict)
+
+    pathname = EasyDialogs.AskFileForSave(message="Python output file?", savedFileName="macerrors.py")
+    if pathname:
+        fp = open(pathname, "w")
+        writepython(fp, dict)
+        fp.close()
+        fss.SetCreatorType('Pyth', 'TEXT')
+
+    pathname = EasyDialogs.AskFileForSave(message="Text output file?", savedFileName="errors.txt")
+    if pathname:
+        fp = open(pathname, "w")
+
+        k = dict.keys()
+        k.sort()
+        for i in k:
+            fp.write("%d\t%s\t%s\n"%(i, dict[i][1], dict[i][0]))
+        fp.close()
+
+
+if __name__ == '__main__':
+    main()

Added: vendor/Python/current/Mac/scripts/zappycfiles.py
===================================================================
--- vendor/Python/current/Mac/scripts/zappycfiles.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Mac/scripts/zappycfiles.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,36 @@
+#!/usr/local/bin/python
+"""Recursively zap all .pyc and .pyo files"""
+import os
+import sys
+
+# set doit true to actually delete files
+# set doit false to just print what would be deleted
+doit = 1
+
+def main():
+    if not sys.argv[1:]:
+        if os.name == 'mac':
+            import EasyDialogs
+            dir = EasyDialogs.AskFolder(message='Directory to zap pyc files in')
+            if not dir:
+                sys.exit(0)
+            zappyc(dir)
+        else:
+            print 'Usage: zappyc dir ...'
+            sys.exit(1)
+    for dir in sys.argv[1:]:
+        zappyc(dir)
+
+def zappyc(dir):
+    os.path.walk(dir, walker, None)
+
+def walker(dummy, top, names):
+    for name in names:
+        if name[-4:] in ('.pyc', '.pyo'):
+            path = os.path.join(top, name)
+            print 'Zapping', path
+            if doit:
+                os.unlink(path)
+
+if __name__ == '__main__':
+    main()

Added: vendor/Python/current/Makefile.pre.in
===================================================================
--- vendor/Python/current/Makefile.pre.in	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Makefile.pre.in	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1088 @@
+# Top-level Makefile for Python
+#
+# As distributed, this file is called Makefile.pre.in; it is processed
+# into the real Makefile by running the script ./configure, which
+# replaces things like @spam@ with values appropriate for your system.
+# This means that if you edit Makefile, your changes get lost the next
+# time you run the configure script.  Ideally, you can do:
+#
+#	./configure
+#	make
+#	make test
+#	make install
+#
+# If you have a previous version of Python installed that you don't
+# want to overwrite, you can use "make altinstall" instead of "make
+# install".  Refer to the "Installing" section in the README file for
+# additional details.
+#
+# See also the section "Build instructions" in the README file.
+
+# === Variables set by makesetup ===
+
+MODOBJS=        _MODOBJS_
+MODLIBS=        _MODLIBS_
+
+# === Variables set by configure
+VERSION=	@VERSION@
+srcdir=		@srcdir@
+VPATH=		@srcdir@
+
+CC=		@CC@
+CXX=		@CXX@
+MAINCC=		@MAINCC@
+LINKCC=		@LINKCC@
+AR=		@AR@
+RANLIB=		@RANLIB@
+SVNVERSION=	@SVNVERSION@
+
+# Shell used by make (some versions default to the login shell, which is bad)
+SHELL=		/bin/sh
+
+# Use this to make a link between python$(VERSION) and python in $(BINDIR)
+LN=		@LN@
+
+# Portable install script (configure doesn't always guess right)
+INSTALL=	@INSTALL@
+INSTALL_PROGRAM=@INSTALL_PROGRAM@
+INSTALL_SCRIPT= @INSTALL_SCRIPT@
+INSTALL_DATA=	@INSTALL_DATA@
+# Shared libraries must be installed with executable mode on some systems;
+# rather than figuring out exactly which, we always give them executable mode.
+# Also, making them read-only seems to be a good idea...
+INSTALL_SHARED= ${INSTALL} -m 555
+
+MAKESETUP=      $(srcdir)/Modules/makesetup
+
+# Compiler options
+OPT=		@OPT@
+BASECFLAGS=	@BASECFLAGS@
+CFLAGS=		$(BASECFLAGS) $(OPT) $(EXTRA_CFLAGS)
+# Both CPPFLAGS and LDFLAGS need to contain the shell's value for setup.py to
+# be able to build extension modules using the directories specified in the
+# environment variables
+CPPFLAGS=	-I. -I$(srcdir)/Include @CPPFLAGS@
+LDFLAGS=	@LDFLAGS@
+LDLAST=		@LDLAST@
+SGI_ABI=	@SGI_ABI@
+CCSHARED=	@CCSHARED@
+LINKFORSHARED=	@LINKFORSHARED@
+# Extra C flags added for building the interpreter object files.
+CFLAGSFORSHARED=@CFLAGSFORSHARED@
+# C flags used for building the interpreter object files
+PY_CFLAGS=	$(CFLAGS) $(CPPFLAGS) $(CFLAGSFORSHARED) -DPy_BUILD_CORE
+
+
+# Machine-dependent subdirectories
+MACHDEP=	@MACHDEP@
+
+# Install prefix for architecture-independent files
+prefix=		@prefix@
+
+# Install prefix for architecture-dependent files
+exec_prefix=	@exec_prefix@
+
+# Expanded directories
+BINDIR=		$(exec_prefix)/bin
+LIBDIR=		$(exec_prefix)/lib
+MANDIR=		@mandir@
+INCLUDEDIR=	@includedir@
+CONFINCLUDEDIR=	$(exec_prefix)/include
+SCRIPTDIR=	$(prefix)/lib
+
+# Detailed destination directories
+BINLIBDEST=	$(LIBDIR)/python$(VERSION)
+LIBDEST=	$(SCRIPTDIR)/python$(VERSION)
+INCLUDEPY=	$(INCLUDEDIR)/python$(VERSION)
+CONFINCLUDEPY=	$(CONFINCLUDEDIR)/python$(VERSION)
+LIBP=		$(LIBDIR)/python$(VERSION)
+
+# Symbols used for using shared libraries
+SO=		@SO@
+LDSHARED=	@LDSHARED@
+BLDSHARED=	@BLDSHARED@
+DESTSHARED=	$(BINLIBDEST)/lib-dynload
+
+# Executable suffix (.exe on Windows and Mac OS X)
+EXE=		@EXEEXT@
+BUILDEXE=	@BUILDEXEEXT@
+
+# Short name and location for Mac OS X Python framework
+UNIVERSALSDK=@UNIVERSALSDK@
+PYTHONFRAMEWORK=	@PYTHONFRAMEWORK@
+PYTHONFRAMEWORKDIR=	@PYTHONFRAMEWORKDIR@
+PYTHONFRAMEWORKPREFIX=	@PYTHONFRAMEWORKPREFIX@
+PYTHONFRAMEWORKINSTALLDIR= @PYTHONFRAMEWORKINSTALLDIR@
+# Deployment target selected during configure, to be checked
+# by distutils. The export statement is needed to ensure that the
+# deployment target is active during build.
+MACOSX_DEPLOYMENT_TARGET=@CONFIGURE_MACOSX_DEPLOYMENT_TARGET@
+ at EXPORT_MACOSX_DEPLOYMENT_TARGET@export MACOSX_DEPLOYMENT_TARGET
+
+# Options to enable prebinding (for fast startup prior to Mac OS X 10.3)
+OTHER_LIBTOOL_OPT=@OTHER_LIBTOOL_OPT@
+
+# Environment to run shared python without installed libraries
+RUNSHARED=       @RUNSHARED@
+
+# Modes for directories, executables and data files created by the
+# install process.  Default to user-only-writable for all file types.
+DIRMODE=	755
+EXEMODE=	755
+FILEMODE=	644
+
+# configure script arguments
+CONFIG_ARGS=	@CONFIG_ARGS@
+
+
+# Subdirectories with code
+SRCDIRS= 	@SRCDIRS@
+
+# Other subdirectories
+SUBDIRSTOO=	Include Lib Misc Demo
+
+# Files and directories to be distributed
+CONFIGFILES=	configure configure.in acconfig.h pyconfig.h.in Makefile.pre.in
+DISTFILES=	README ChangeLog $(CONFIGFILES)
+DISTDIRS=	$(SUBDIRS) $(SUBDIRSTOO) Ext-dummy
+DIST=		$(DISTFILES) $(DISTDIRS)
+
+
+LIBRARY=	@LIBRARY@
+LDLIBRARY=      @LDLIBRARY@
+BLDLIBRARY=     @BLDLIBRARY@
+DLLLIBRARY=	@DLLLIBRARY@
+LDLIBRARYDIR=   @LDLIBRARYDIR@
+INSTSONAME=	@INSTSONAME@
+
+
+LIBS=		@LIBS@
+LIBM=		@LIBM@
+LIBC=		@LIBC@
+SYSLIBS=	$(LIBM) $(LIBC)
+SHLIBS=		@SHLIBS@
+
+THREADOBJ=	@THREADOBJ@
+DLINCLDIR=	@DLINCLDIR@
+DYNLOADFILE=	@DYNLOADFILE@
+MACHDEP_OBJS=	@MACHDEP_OBJS@
+UNICODE_OBJS=   @UNICODE_OBJS@
+
+PYTHON=		python$(EXE)
+BUILDPYTHON=	python$(BUILDEXE)
+
+# === Definitions added by makesetup ===
+
+
+##########################################################################
+# Modules
+MODULE_OBJS=	\
+		Modules/config.o \
+		Modules/getpath.o \
+		Modules/main.o \
+		Modules/gcmodule.o
+
+# Used of signalmodule.o is not available
+SIGNAL_OBJS=	@SIGNAL_OBJS@
+
+
+##########################################################################
+# Grammar
+GRAMMAR_H=	$(srcdir)/Include/graminit.h
+GRAMMAR_C=	$(srcdir)/Python/graminit.c
+GRAMMAR_INPUT=	$(srcdir)/Grammar/Grammar
+
+
+##########################################################################
+# Parser
+PGEN=		Parser/pgen$(EXE)
+
+POBJS=		\
+		Parser/acceler.o \
+		Parser/grammar1.o \
+		Parser/listnode.o \
+		Parser/node.o \
+		Parser/parser.o \
+		Parser/parsetok.o \
+		Parser/bitset.o \
+		Parser/metagrammar.o \
+		Parser/firstsets.o \
+		Parser/grammar.o \
+		Parser/pgen.o
+
+PARSER_OBJS=	$(POBJS) Parser/myreadline.o Parser/tokenizer.o
+
+PGOBJS=		\
+		Objects/obmalloc.o \
+		Python/mysnprintf.o \
+		Parser/tokenizer_pgen.o \
+		Parser/printgrammar.o \
+		Parser/pgenmain.o
+
+PGENOBJS=	$(PGENMAIN) $(POBJS) $(PGOBJS)
+
+##########################################################################
+# AST
+AST_H_DIR=	$(srcdir)/Include
+AST_H=		$(AST_H_DIR)/Python-ast.h
+AST_C_DIR=	$(srcdir)/Python
+AST_C=		$(AST_C_DIR)/Python-ast.c
+AST_ASDL=	$(srcdir)/Parser/Python.asdl
+
+ASDLGEN_FILES=	$(srcdir)/Parser/asdl.py $(srcdir)/Parser/asdl_c.py
+# XXX Note that a build now requires Python exist before the build starts
+ASDLGEN=	$(srcdir)/Parser/asdl_c.py
+
+##########################################################################
+# Python
+PYTHON_OBJS=	\
+		Python/Python-ast.o \
+		Python/asdl.o \
+		Python/ast.o \
+		Python/bltinmodule.o \
+		Python/ceval.o \
+		Python/compile.o \
+		Python/codecs.o \
+		Python/errors.o \
+		Python/frozen.o \
+		Python/frozenmain.o \
+		Python/future.o \
+		Python/getargs.o \
+		Python/getcompiler.o \
+		Python/getcopyright.o \
+		Python/getmtime.o \
+		Python/getplatform.o \
+		Python/getversion.o \
+		Python/graminit.o \
+		Python/import.o \
+		Python/importdl.o \
+		Python/marshal.o \
+		Python/modsupport.o \
+		Python/mystrtoul.o \
+		Python/mysnprintf.o \
+		Python/pyarena.o \
+		Python/pyfpe.o \
+		Python/pystate.o \
+		Python/pythonrun.o \
+		Python/structmember.o \
+		Python/symtable.o \
+		Python/sysmodule.o \
+		Python/traceback.o \
+		Python/getopt.o \
+		Python/pystrtod.o \
+		Python/$(DYNLOADFILE) \
+		$(MACHDEP_OBJS) \
+		$(THREADOBJ)
+
+
+##########################################################################
+# Objects
+OBJECT_OBJS=	\
+		Objects/abstract.o \
+		Objects/boolobject.o \
+		Objects/bufferobject.o \
+		Objects/cellobject.o \
+		Objects/classobject.o \
+		Objects/cobject.o \
+		Objects/codeobject.o \
+		Objects/complexobject.o \
+		Objects/descrobject.o \
+		Objects/enumobject.o \
+		Objects/exceptions.o \
+		Objects/genobject.o \
+		Objects/fileobject.o \
+		Objects/floatobject.o \
+		Objects/frameobject.o \
+		Objects/funcobject.o \
+		Objects/intobject.o \
+		Objects/iterobject.o \
+		Objects/listobject.o \
+		Objects/longobject.o \
+		Objects/dictobject.o \
+		Objects/methodobject.o \
+		Objects/moduleobject.o \
+		Objects/object.o \
+		Objects/obmalloc.o \
+		Objects/rangeobject.o \
+                Objects/setobject.o \
+		Objects/sliceobject.o \
+		Objects/stringobject.o \
+		Objects/structseq.o \
+		Objects/tupleobject.o \
+		Objects/typeobject.o \
+		Objects/weakrefobject.o \
+		$(UNICODE_OBJS)
+
+
+##########################################################################
+# objects that get linked into the Python library
+LIBRARY_OBJS=	\
+		Modules/_typesmodule.o \
+		Modules/getbuildinfo.o \
+		$(PARSER_OBJS) \
+		$(OBJECT_OBJS) \
+		$(PYTHON_OBJS) \
+		$(MODULE_OBJS) \
+		$(SIGNAL_OBJS) \
+		$(MODOBJS)
+
+#########################################################################
+# Rules
+
+# Default target
+all:		$(BUILDPYTHON) oldsharedmods sharedmods
+
+# Build the interpreter
+$(BUILDPYTHON):	Modules/python.o $(LIBRARY) $(LDLIBRARY)
+		$(LINKCC) $(LDFLAGS) $(LINKFORSHARED) -o $@ \
+			Modules/python.o \
+			$(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS) $(LDLAST)
+
+platform: $(BUILDPYTHON)
+	$(RUNSHARED) ./$(BUILDPYTHON) -E -c 'import sys ; from distutils.util import get_platform ; print get_platform()+"-"+sys.version[0:3]' >platform
+
+
+# Build the shared modules
+sharedmods: $(BUILDPYTHON)
+	case $$MAKEFLAGS in \
+	*-s*) $(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' ./$(BUILDPYTHON) -E $(srcdir)/setup.py -q build;; \
+	*) $(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' ./$(BUILDPYTHON) -E $(srcdir)/setup.py build;; \
+	esac
+
+# Build static library
+# avoid long command lines, same as LIBRARY_OBJS
+$(LIBRARY): $(LIBRARY_OBJS)
+	-rm -f $@
+	$(AR) cr $@ Modules/getbuildinfo.o
+	$(AR) cr $@ Modules/_typesmodule.o
+	$(AR) cr $@ $(PARSER_OBJS)
+	$(AR) cr $@ $(OBJECT_OBJS)
+	$(AR) cr $@ $(PYTHON_OBJS)
+	$(AR) cr $@ $(MODULE_OBJS) $(SIGNAL_OBJS)
+	$(AR) cr $@ $(MODOBJS)
+	$(RANLIB) $@
+
+libpython$(VERSION).so: $(LIBRARY_OBJS)
+	if test $(INSTSONAME) != $(LDLIBRARY); then \
+		$(LDSHARED) -Wl,-h$(INSTSONAME) -o $(INSTSONAME) $(LIBRARY_OBJS) $(SHLIBS) $(LIBC) $(LIBM); \
+		$(LN) -f $(INSTSONAME) $@; \
+	else\
+		$(LDSHARED) -o $@ $(LIBRARY_OBJS) $(SHLIBS) $(LIBC) $(LIBM); \
+	fi
+
+libpython$(VERSION).sl: $(LIBRARY_OBJS)
+	$(LDSHARED) -o $@ $(LIBRARY_OBJS) $(SHLIBS) $(LIBC) $(LIBM)
+
+# This rule is here for OPENSTEP/Rhapsody/MacOSX. It builds a temporary
+# minimal framework (not including the Lib directory and such) in the current
+# directory.
+RESSRCDIR=$(srcdir)/Mac/Resources/framework
+$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK): \
+		$(LIBRARY) \
+		$(RESSRCDIR)/Info.plist \
+                $(RESSRCDIR)/version.plist \
+                $(RESSRCDIR)/English.lproj/InfoPlist.strings
+	$(INSTALL) -d -m $(DIRMODE) $(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)
+	if test "${UNIVERSALSDK}"; then \
+		$(CC) -o $(LDLIBRARY) -arch i386 -arch ppc -dynamiclib \
+			-isysroot "${UNIVERSALSDK}" \
+			-all_load $(LIBRARY) -Wl,-single_module \
+			-install_name $(DESTDIR)$(PYTHONFRAMEWORKINSTALLDIR)/Versions/$(VERSION)/Python \
+			-compatibility_version $(VERSION) \
+			-current_version $(VERSION); \
+        else \
+		libtool -o $(LDLIBRARY) -dynamic $(OTHER_LIBTOOL_OPT) $(LIBRARY) \
+			@LIBTOOL_CRUFT@ ;\
+	fi
+	$(INSTALL) -d -m $(DIRMODE)  \
+		$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/Resources/English.lproj
+	$(INSTALL_DATA) $(RESSRCDIR)/Info.plist \
+		$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/Resources/Info.plist
+	$(INSTALL_DATA) $(RESSRCDIR)/version.plist \
+		$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/Resources/version.plist
+	$(INSTALL_DATA) $(RESSRCDIR)/English.lproj/InfoPlist.strings \
+		$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/Resources/English.lproj/InfoPlist.strings
+	$(LN) -fsn $(VERSION) $(PYTHONFRAMEWORKDIR)/Versions/Current
+	$(LN) -fsn Versions/Current/$(PYTHONFRAMEWORK) $(PYTHONFRAMEWORKDIR)/$(PYTHONFRAMEWORK)
+	$(LN) -fsn Versions/Current/Headers $(PYTHONFRAMEWORKDIR)/Headers
+	$(LN) -fsn Versions/Current/Resources $(PYTHONFRAMEWORKDIR)/Resources
+
+# This rule builds the Cygwin Python DLL and import library if configured
+# for a shared core library; otherwise, this rule is a noop.
+$(DLLLIBRARY) libpython$(VERSION).dll.a: $(LIBRARY_OBJS)
+	if test -n "$(DLLLIBRARY)"; then \
+		$(LDSHARED) -Wl,--out-implib=$@ -o $(DLLLIBRARY) $^ \
+			$(LIBS) $(MODLIBS) $(SYSLIBS); \
+	else true; \
+	fi
+
+
+oldsharedmods: $(SHAREDMODS)
+
+
+Makefile Modules/config.c: Makefile.pre \
+				$(srcdir)/Modules/config.c.in \
+				$(MAKESETUP) \
+				Modules/Setup.config \
+				Modules/Setup \
+				Modules/Setup.local
+	$(SHELL) $(MAKESETUP) -c $(srcdir)/Modules/config.c.in \
+				-s Modules \
+				Modules/Setup.config \
+				Modules/Setup.local \
+				Modules/Setup
+	@mv config.c Modules
+	@echo "The Makefile was updated, you may need to re-run make."
+
+
+Modules/Setup: $(srcdir)/Modules/Setup.dist
+	@if test -f Modules/Setup; then \
+		echo "-----------------------------------------------"; \
+		echo "Modules/Setup.dist is newer than Modules/Setup;"; \
+		echo "check to make sure you have all the updates you"; \
+		echo "need in your Modules/Setup file."; \
+		echo "Usually, copying Setup.dist to Setup will work."; \
+		echo "-----------------------------------------------"; \
+	fi
+
+############################################################################
+# Special rules for object files
+
+Modules/getbuildinfo.o: $(PARSER_OBJS) \
+		$(OBJECT_OBJS) \
+		$(PYTHON_OBJS) \
+		$(MODULE_OBJS) \
+		$(SIGNAL_OBJS) \
+		$(MODOBJS) \
+		$(srcdir)/Modules/getbuildinfo.c
+	$(CC) -c $(PY_CFLAGS) -DSVNVERSION=\"`LC_ALL=C $(SVNVERSION)`\" -o $@ $(srcdir)/Modules/getbuildinfo.c
+
+Modules/getpath.o: $(srcdir)/Modules/getpath.c Makefile
+	$(CC) -c $(PY_CFLAGS) -DPYTHONPATH='"$(PYTHONPATH)"' \
+		-DPREFIX='"$(prefix)"' \
+		-DEXEC_PREFIX='"$(exec_prefix)"' \
+		-DVERSION='"$(VERSION)"' \
+		-DVPATH='"$(VPATH)"' \
+		-o $@ $(srcdir)/Modules/getpath.c
+
+Modules/python.o: $(srcdir)/Modules/python.c
+	$(MAINCC) -c $(PY_CFLAGS) -o $@ $(srcdir)/Modules/python.c
+
+
+$(GRAMMAR_H) $(GRAMMAR_C): $(PGEN) $(GRAMMAR_INPUT)
+		-$(PGEN) $(GRAMMAR_INPUT) $(GRAMMAR_H) $(GRAMMAR_C)
+
+$(PGEN):	$(PGENOBJS)
+		$(CC) $(OPT) $(LDFLAGS) $(PGENOBJS) $(LIBS) -o $(PGEN)
+
+Parser/grammar.o:	$(srcdir)/Parser/grammar.c \
+				$(srcdir)/Include/token.h \
+				$(srcdir)/Include/grammar.h
+Parser/metagrammar.o:	$(srcdir)/Parser/metagrammar.c
+
+Parser/tokenizer_pgen.o:	$(srcdir)/Parser/tokenizer.c
+
+$(AST_H): $(AST_ASDL) $(ASDLGEN_FILES)
+	$(ASDLGEN) -h $(AST_H_DIR) $(AST_ASDL)
+
+$(AST_C): $(AST_ASDL) $(ASDLGEN_FILES)
+	$(ASDLGEN) -c $(AST_C_DIR) $(AST_ASDL)
+
+Python/compile.o Python/symtable.o: $(GRAMMAR_H) $(AST_H)
+
+Python/getplatform.o: $(srcdir)/Python/getplatform.c
+		$(CC) -c $(PY_CFLAGS) -DPLATFORM='"$(MACHDEP)"' -o $@ $(srcdir)/Python/getplatform.c
+
+Python/importdl.o: $(srcdir)/Python/importdl.c
+		$(CC) -c $(PY_CFLAGS) -I$(DLINCLDIR) -o $@ $(srcdir)/Python/importdl.c
+
+Objects/unicodectype.o:	$(srcdir)/Objects/unicodectype.c \
+				$(srcdir)/Objects/unicodetype_db.h
+
+############################################################################
+# Header files
+
+PYTHON_HEADERS= \
+		Include/Python.h \
+		Include/Python-ast.h \
+		Include/asdl.h \
+		Include/abstract.h \
+		Include/boolobject.h \
+		Include/bufferobject.h \
+		Include/ceval.h \
+		Include/classobject.h \
+		Include/cobject.h \
+		Include/code.h \
+		Include/codecs.h \
+		Include/compile.h \
+		Include/complexobject.h \
+		Include/descrobject.h \
+		Include/dictobject.h \
+		Include/enumobject.h \
+		Include/genobject.h \
+		Include/fileobject.h \
+		Include/floatobject.h \
+		Include/funcobject.h \
+		Include/import.h \
+		Include/intobject.h \
+		Include/intrcheck.h \
+		Include/iterobject.h \
+		Include/listobject.h \
+		Include/longobject.h \
+		Include/methodobject.h \
+		Include/modsupport.h \
+		Include/moduleobject.h \
+		Include/object.h \
+		Include/objimpl.h \
+		Include/patchlevel.h \
+		Include/pyarena.h \
+		Include/pydebug.h \
+		Include/pyerrors.h \
+		Include/pyfpe.h \
+		Include/pymem.h \
+		Include/pyport.h \
+		Include/pystate.h \
+		Include/pythonrun.h \
+		Include/rangeobject.h \
+                Include/setobject.h \
+		Include/sliceobject.h \
+		Include/stringobject.h \
+		Include/structseq.h \
+		Include/structmember.h \
+		Include/symtable.h \
+		Include/sysmodule.h \
+		Include/traceback.h \
+		Include/tupleobject.h \
+		Include/unicodeobject.h \
+		Include/weakrefobject.h \
+		pyconfig.h
+
+$(LIBRARY_OBJS) $(MODOBJS) Modules/python.o: $(PYTHON_HEADERS)
+
+
+######################################################################
+
+# Test the interpreter (twice, once without .pyc files, once with)
+# In the past, we've had problems where bugs in the marshalling or
+# elsewhere caused bytecode read from .pyc files to behave differently
+# than bytecode generated directly from a .py source file.  Sometimes
+# the bytecode read from a .pyc file had the bug, somtimes the directly
+# generated bytecode.  This is sometimes a very shy bug needing a lot of
+# sample data.
+
+TESTOPTS=	-l $(EXTRATESTOPTS)
+TESTPROG=	$(srcdir)/Lib/test/regrtest.py
+TESTPYTHON=	$(RUNSHARED) ./$(BUILDPYTHON) -E -tt
+test:		all platform
+		-find $(srcdir)/Lib -name '*.py[co]' -print | xargs rm -f
+		-$(TESTPYTHON) $(TESTPROG) $(TESTOPTS)
+		$(TESTPYTHON) $(TESTPROG) $(TESTOPTS)
+
+testall:	all platform
+		-find $(srcdir)/Lib -name '*.py[co]' -print | xargs rm -f
+		-$(TESTPYTHON) $(TESTPROG) $(TESTOPTS) -uall
+		$(TESTPYTHON) $(TESTPROG) $(TESTOPTS) -uall
+
+#  Run the unitests for both architectures in a Universal build on OSX
+#  Must be run on an Intel box.
+testuniversal:	all platform
+		if [ `arch` != 'i386' ];then \
+			echo "This can only be used on OSX/i386" ;\
+			exit 1 ;\
+		fi
+		-find $(srcdir)/Lib -name '*.py[co]' -print | xargs rm -f
+		-$(TESTPYTHON) $(TESTPROG) $(TESTOPTS) -uall
+		$(TESTPYTHON) $(TESTPROG) $(TESTOPTS) -uall
+		$(RUNSHARED) /usr/libexec/oah/translate ./$(BUILDPYTHON) -E -tt $(TESTPROG) $(TESTOPTS) -uall
+
+
+# Like testall, but with a single pass only
+buildbottest:	all platform
+		$(TESTPYTHON) $(TESTPROG) $(TESTOPTS) -uall -rw
+
+QUICKTESTOPTS=	$(TESTOPTS) -x test_thread test_signal test_strftime \
+		test_unicodedata test_re test_sre test_select test_poll \
+		test_linuxaudiodev test_struct test_sunaudiodev test_zlib
+quicktest:	all platform
+		-find $(srcdir)/Lib -name '*.py[co]' -print | xargs rm -f
+		-$(TESTPYTHON) $(TESTPROG) $(QUICKTESTOPTS)
+		$(TESTPYTHON) $(TESTPROG) $(QUICKTESTOPTS)
+
+MEMTESTOPTS=    $(QUICKTESTOPTS) -x test_dl test___all__ test_fork1 \
+		test_longexp
+memtest:	all platform
+		-rm -f $(srcdir)/Lib/test/*.py[co]
+		-$(TESTPYTHON) $(TESTPROG) $(MEMTESTOPTS)
+		$(TESTPYTHON) $(TESTPROG) $(MEMTESTOPTS)
+
+# Install everything
+install:	@FRAMEWORKINSTALLFIRST@ altinstall bininstall maninstall @FRAMEWORKINSTALLLAST@
+
+# Install almost everything without disturbing previous versions
+altinstall:	@FRAMEWORKALTINSTALLFIRST@ altbininstall libinstall inclinstall libainstall \
+                sharedinstall oldsharedinstall @FRAMEWORKALTINSTALLLAST@
+
+# Install shared libraries enabled by Setup
+DESTDIRS=	$(exec_prefix) $(LIBDIR) $(BINLIBDEST) $(DESTSHARED)
+
+oldsharedinstall: $(DESTSHARED) $(SHAREDMODS)
+		@for i in X $(SHAREDMODS); do \
+		  if test $$i != X; then \
+		    echo $(INSTALL_SHARED) $$i $(DESTSHARED)/`basename $$i`; \
+		    $(INSTALL_SHARED) $$i $(DESTDIR)$(DESTSHARED)/`basename $$i`; \
+		  fi; \
+		done
+
+$(DESTSHARED):
+		@for i in $(DESTDIRS); \
+		do \
+			if test ! -d $(DESTDIR)$$i; then \
+				echo "Creating directory $$i"; \
+				$(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$$i; \
+			else    true; \
+			fi; \
+		done
+
+
+# Install the interpreter (by creating a hard link to python$(VERSION))
+bininstall:	altbininstall
+	-if test -f $(DESTDIR)$(BINDIR)/$(PYTHON) -o -h $(DESTDIR)$(BINDIR)/$(PYTHON); \
+	then rm -f $(DESTDIR)$(BINDIR)/$(PYTHON); \
+	else true; \
+	fi
+	(cd $(DESTDIR)$(BINDIR); $(LN) python$(VERSION)$(EXE) $(PYTHON))
+	(cd $(DESTDIR)$(BINDIR); $(LN) -sf python$(VERSION)-config python-config)
+
+# Install the interpreter with $(VERSION) affixed
+# This goes into $(exec_prefix)
+altbininstall:	$(BUILDPYTHON)
+	@for i in $(BINDIR) $(LIBDIR); \
+	do \
+		if test ! -d $(DESTDIR)$$i; then \
+			echo "Creating directory $$i"; \
+			$(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$$i; \
+		else	true; \
+		fi; \
+	done
+	$(INSTALL_PROGRAM) $(BUILDPYTHON) $(DESTDIR)$(BINDIR)/python$(VERSION)$(EXE)
+	if test -f libpython$(VERSION)$(SO); then \
+		if test "$(SO)" = .dll; then \
+			$(INSTALL_SHARED) libpython$(VERSION)$(SO) $(DESTDIR)$(BINDIR); \
+		else \
+			$(INSTALL_SHARED) libpython$(VERSION)$(SO) $(DESTDIR)$(LIBDIR)/$(INSTSONAME); \
+			if test libpython$(VERSION)$(SO) != $(INSTSONAME); then \
+				(cd $(DESTDIR)$(LIBDIR); $(LN) -sf $(INSTSONAME) libpython$(VERSION)$(SO)); \
+			fi \
+		fi; \
+	else	true; \
+	fi
+
+# Install the manual page
+maninstall:
+	@for i in $(MANDIR) $(MANDIR)/man1; \
+	do \
+		if test ! -d $(DESTDIR)$$i; then \
+			echo "Creating directory $$i"; \
+			$(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$$i; \
+		else	true; \
+		fi; \
+	done
+	$(INSTALL_DATA) $(srcdir)/Misc/python.man \
+		$(DESTDIR)$(MANDIR)/man1/python.1
+
+# Install the library
+PLATDIR=	plat-$(MACHDEP)
+EXTRAPLATDIR= @EXTRAPLATDIR@
+EXTRAMACHDEPPATH=@EXTRAMACHDEPPATH@
+MACHDEPS=	$(PLATDIR) $(EXTRAPLATDIR)
+XMLLIBSUBDIRS=  xml xml/dom xml/etree xml/parsers xml/sax
+PLATMACDIRS= plat-mac plat-mac/Carbon plat-mac/lib-scriptpackages \
+	plat-mac/lib-scriptpackages/_builtinSuites \
+	plat-mac/lib-scriptpackages/CodeWarrior \
+	plat-mac/lib-scriptpackages/Explorer \
+	plat-mac/lib-scriptpackages/Finder \
+	plat-mac/lib-scriptpackages/Netscape \
+	plat-mac/lib-scriptpackages/StdSuites \
+	plat-mac/lib-scriptpackages/SystemEvents \
+	plat-mac/lib-scriptpackages/Terminal 
+PLATMACPATH=:plat-mac:plat-mac/lib-scriptpackages
+LIBSUBDIRS=	lib-tk site-packages test test/output test/data \
+		test/decimaltestdata \
+		encodings compiler hotshot \
+		email email/mime email/test email/test/data \
+		sqlite3 sqlite3/test \
+		logging bsddb bsddb/test csv wsgiref \
+		ctypes ctypes/test ctypes/macholib idlelib idlelib/Icons \
+		distutils distutils/command distutils/tests $(XMLLIBSUBDIRS) \
+		setuptools setuptools/command setuptools/tests setuptools.egg-info \
+		curses $(MACHDEPS)
+libinstall:	$(BUILDPYTHON) $(srcdir)/Lib/$(PLATDIR)
+	@for i in $(SCRIPTDIR) $(LIBDEST); \
+	do \
+		if test ! -d $(DESTDIR)$$i; then \
+			echo "Creating directory $$i"; \
+			$(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$$i; \
+		else	true; \
+		fi; \
+	done
+	@for d in $(LIBSUBDIRS); \
+	do \
+		a=$(srcdir)/Lib/$$d; \
+		if test ! -d $$a; then continue; else true; fi; \
+		b=$(LIBDEST)/$$d; \
+		if test ! -d $(DESTDIR)$$b; then \
+			echo "Creating directory $$b"; \
+			$(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$$b; \
+		else	true; \
+		fi; \
+	done
+	@for i in $(srcdir)/Lib/*.py $(srcdir)/Lib/*.doc $(srcdir)/Lib/*.egg-info ; \
+	do \
+		if test -x $$i; then \
+			$(INSTALL_SCRIPT) $$i $(DESTDIR)$(LIBDEST); \
+			echo $(INSTALL_SCRIPT) $$i $(LIBDEST); \
+		else \
+			$(INSTALL_DATA) $$i $(DESTDIR)$(LIBDEST); \
+			echo $(INSTALL_DATA) $$i $(LIBDEST); \
+		fi; \
+	done
+	@for d in $(LIBSUBDIRS); \
+	do \
+		a=$(srcdir)/Lib/$$d; \
+		if test ! -d $$a; then continue; else true; fi; \
+		if test `ls $$a | wc -l` -lt 1; then continue; fi; \
+		b=$(LIBDEST)/$$d; \
+		for i in $$a/*; \
+		do \
+			case $$i in \
+			*CVS) ;; \
+			*.py[co]) ;; \
+			*.orig) ;; \
+			*~) ;; \
+			*) \
+				if test -d $$i; then continue; fi; \
+				if test -x $$i; then \
+				    echo $(INSTALL_SCRIPT) $$i $$b; \
+				    $(INSTALL_SCRIPT) $$i $(DESTDIR)$$b; \
+				else \
+				    echo $(INSTALL_DATA) $$i $$b; \
+				    $(INSTALL_DATA) $$i $(DESTDIR)$$b; \
+				fi;; \
+			esac; \
+		done; \
+	done
+	$(INSTALL_DATA) $(srcdir)/LICENSE $(DESTDIR)$(LIBDEST)/LICENSE.txt
+	PYTHONPATH=$(DESTDIR)$(LIBDEST)  $(RUNSHARED) \
+		./$(BUILDPYTHON) -Wi -tt $(DESTDIR)$(LIBDEST)/compileall.py \
+		-d $(LIBDEST) -f \
+		-x 'bad_coding|badsyntax|site-packages' $(DESTDIR)$(LIBDEST)
+	PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
+		./$(BUILDPYTHON) -Wi -tt -O $(DESTDIR)$(LIBDEST)/compileall.py \
+		-d $(LIBDEST) -f \
+		-x 'bad_coding|badsyntax|site-packages' $(DESTDIR)$(LIBDEST)
+	-PYTHONPATH=$(DESTDIR)$(LIBDEST)  $(RUNSHARED) \
+		./$(BUILDPYTHON) -Wi -t $(DESTDIR)$(LIBDEST)/compileall.py \
+		-d $(LIBDEST)/site-packages -f \
+		-x badsyntax $(DESTDIR)$(LIBDEST)/site-packages
+	-PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
+		./$(BUILDPYTHON) -Wi -t -O $(DESTDIR)$(LIBDEST)/compileall.py \
+		-d $(LIBDEST)/site-packages -f \
+		-x badsyntax $(DESTDIR)$(LIBDEST)/site-packages
+
+# Create the PLATDIR source directory, if one wasn't distributed..
+$(srcdir)/Lib/$(PLATDIR):
+	mkdir $(srcdir)/Lib/$(PLATDIR)
+	cp $(srcdir)/Lib/plat-generic/regen $(srcdir)/Lib/$(PLATDIR)/regen
+	export PATH; PATH="`pwd`:$$PATH"; \
+	export PYTHONPATH; PYTHONPATH="`pwd`/Lib"; \
+	export DYLD_FRAMEWORK_PATH; DYLD_FRAMEWORK_PATH="`pwd`"; \
+	export EXE; EXE="$(BUILDEXE)"; \
+	cd $(srcdir)/Lib/$(PLATDIR); ./regen
+
+# Install the include files
+INCLDIRSTOMAKE=$(INCLUDEDIR) $(CONFINCLUDEDIR) $(INCLUDEPY) $(CONFINCLUDEPY)
+inclinstall:
+	@for i in $(INCLDIRSTOMAKE); \
+	do \
+		if test ! -d $(DESTDIR)$$i; then \
+			echo "Creating directory $$i"; \
+			$(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$$i; \
+		else	true; \
+		fi; \
+	done
+	@for i in $(srcdir)/Include/*.h; \
+	do \
+		echo $(INSTALL_DATA) $$i $(INCLUDEPY); \
+		$(INSTALL_DATA) $$i $(DESTDIR)$(INCLUDEPY); \
+	done
+	$(INSTALL_DATA) pyconfig.h $(DESTDIR)$(CONFINCLUDEPY)/pyconfig.h
+
+# Install the library and miscellaneous stuff needed for extending/embedding
+# This goes into $(exec_prefix)
+LIBPL=		$(LIBP)/config
+libainstall:	all
+	@for i in $(LIBDIR) $(LIBP) $(LIBPL); \
+	do \
+		if test ! -d $(DESTDIR)$$i; then \
+			echo "Creating directory $$i"; \
+			$(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$$i; \
+		else	true; \
+		fi; \
+	done
+	@if test -d $(LIBRARY); then :; else \
+		if test "$(PYTHONFRAMEWORKDIR)" = no-framework; then \
+			if test "$(SO)" = .dll; then \
+				$(INSTALL_DATA) $(LDLIBRARY) $(DESTDIR)$(LIBPL) ; \
+			else \
+				$(INSTALL_DATA) $(LIBRARY) $(DESTDIR)$(LIBPL)/$(LIBRARY) ; \
+				$(RANLIB) $(DESTDIR)$(LIBPL)/$(LIBRARY) ; \
+			fi; \
+		else \
+			echo Skip install of $(LIBRARY) - use make frameworkinstall; \
+		fi; \
+	fi
+	$(INSTALL_DATA) Modules/config.c $(DESTDIR)$(LIBPL)/config.c
+	$(INSTALL_DATA) Modules/python.o $(DESTDIR)$(LIBPL)/python.o
+	$(INSTALL_DATA) $(srcdir)/Modules/config.c.in $(DESTDIR)$(LIBPL)/config.c.in
+	$(INSTALL_DATA) Makefile $(DESTDIR)$(LIBPL)/Makefile
+	$(INSTALL_DATA) Modules/Setup $(DESTDIR)$(LIBPL)/Setup
+	$(INSTALL_DATA) Modules/Setup.local $(DESTDIR)$(LIBPL)/Setup.local
+	$(INSTALL_DATA) Modules/Setup.config $(DESTDIR)$(LIBPL)/Setup.config
+	$(INSTALL_SCRIPT) $(srcdir)/Modules/makesetup $(DESTDIR)$(LIBPL)/makesetup
+	$(INSTALL_SCRIPT) $(srcdir)/install-sh $(DESTDIR)$(LIBPL)/install-sh
+	# Substitution happens here, as the completely-expanded BINDIR
+	# is not available in configure
+	sed -e "s, at EXENAME@,$(BINDIR)/python$(VERSION)$(EXE)," < $(srcdir)/Misc/python-config.in >python-config
+	$(INSTALL_SCRIPT) python-config $(DESTDIR)$(BINDIR)/python$(VERSION)-config
+	rm python-config
+	@if [ -s Modules/python.exp -a \
+		"`echo $(MACHDEP) | sed 's/^\(...\).*/\1/'`" = "aix" ]; then \
+		echo; echo "Installing support files for building shared extension modules on AIX:"; \
+		$(INSTALL_DATA) Modules/python.exp		\
+				$(DESTDIR)$(LIBPL)/python.exp;		\
+		echo; echo "$(LIBPL)/python.exp";		\
+		$(INSTALL_SCRIPT) $(srcdir)/Modules/makexp_aix	\
+				$(DESTDIR)$(LIBPL)/makexp_aix;		\
+		echo "$(LIBPL)/makexp_aix";			\
+		$(INSTALL_SCRIPT) $(srcdir)/Modules/ld_so_aix	\
+				$(DESTDIR)$(LIBPL)/ld_so_aix;		\
+		echo "$(LIBPL)/ld_so_aix";			\
+		echo; echo "See Misc/AIX-NOTES for details.";	\
+	else true; \
+	fi
+	@case "$(MACHDEP)" in beos*) \
+		echo; echo "Installing support files for building shared extension modules on BeOS:"; \
+		$(INSTALL_DATA) Misc/BeOS-NOTES $(DESTDIR)$(LIBPL)/README;	\
+		echo; echo "$(LIBPL)/README";			\
+		$(INSTALL_SCRIPT) Modules/ar_beos $(DESTDIR)$(LIBPL)/ar_beos; \
+		echo "$(LIBPL)/ar_beos";			\
+		$(INSTALL_SCRIPT) Modules/ld_so_beos $(DESTDIR)$(LIBPL)/ld_so_beos; \
+		echo "$(LIBPL)/ld_so_beos";			\
+		echo; echo "See Misc/BeOS-NOTES for details.";	\
+		;; \
+	esac
+
+# Install the dynamically loadable modules
+# This goes into $(exec_prefix)
+sharedinstall:
+	$(RUNSHARED) ./$(BUILDPYTHON) -E $(srcdir)/setup.py install \
+	   	--prefix=$(prefix) \
+		--install-scripts=$(BINDIR) \
+		--install-platlib=$(DESTSHARED) \
+		--root=/$(DESTDIR)
+
+# Here are a couple of targets for MacOSX again, to install a full
+# framework-based Python. frameworkinstall installs everything, the
+# subtargets install specific parts. Much of the actual work is offloaded to
+# the Makefile in Mac
+#
+#
+# This target is here for backward compatiblity, previous versions of Python
+# hadn't integrated framework installation in the normal install process.
+frameworkinstall: install
+
+# On install, we re-make the framework
+# structure in the install location, /Library/Frameworks/ or the argument to
+# --enable-framework. If --enable-framework has been specified then we have
+# automatically set prefix to the location deep down in the framework, so we
+# only have to cater for the structural bits of the framework.
+
+frameworkinstallframework: frameworkinstallstructure install frameworkinstallmaclib
+
+frameworkinstallstructure:	$(LDLIBRARY)
+	@if test "$(PYTHONFRAMEWORKDIR)" = no-framework; then \
+		echo Not configured with --enable-framework; \
+		exit 1; \
+	else true; \
+	fi
+	@for i in $(prefix)/Resources/English.lproj $(prefix)/lib; do\
+		if test ! -d $(DESTDIR)$$i; then \
+			echo "Creating directory $(DESTDIR)$$i"; \
+			$(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$$i; \
+		else	true; \
+		fi; \
+	done
+	$(LN) -fsn include/python$(VERSION) $(DESTDIR)$(prefix)/Headers
+	$(INSTALL_DATA) $(RESSRCDIR)/Info.plist $(DESTDIR)$(prefix)/Resources/Info.plist
+	$(INSTALL_DATA) $(RESSRCDIR)/version.plist $(DESTDIR)$(prefix)/Resources/version.plist
+	$(INSTALL_DATA) $(RESSRCDIR)/English.lproj/InfoPlist.strings \
+		$(DESTDIR)$(prefix)/Resources/English.lproj/InfoPlist.strings
+	$(LN) -fsn $(VERSION) $(DESTDIR)$(PYTHONFRAMEWORKINSTALLDIR)/Versions/Current
+	$(LN) -fsn Versions/Current/Python $(DESTDIR)$(PYTHONFRAMEWORKINSTALLDIR)/Python
+	$(LN) -fsn Versions/Current/Headers $(DESTDIR)$(PYTHONFRAMEWORKINSTALLDIR)/Headers
+	$(LN) -fsn Versions/Current/Resources $(DESTDIR)$(PYTHONFRAMEWORKINSTALLDIR)/Resources
+	$(INSTALL_SHARED) $(LDLIBRARY) $(DESTDIR)$(PYTHONFRAMEWORKPREFIX)/$(LDLIBRARY)
+
+# This installs Mac/Lib into the framework
+# Install a number of symlinks to keep software that expects a normal unix
+# install (which includes python-config) happy.
+frameworkinstallmaclib:
+	ln -fs "../../../Python" "$(DESTDIR)$(prefix)/lib/python$(VERSION)/config/libpython$(VERSION).a"
+	cd Mac && $(MAKE) installmacsubtree DESTDIR="$(DESTDIR)"
+
+# This installs the IDE, the Launcher and other apps into /Applications
+frameworkinstallapps:
+	cd Mac && $(MAKE) installapps DESTDIR="$(DESTDIR)"
+
+# This install the unix python and pythonw tools in /usr/local/bin
+frameworkinstallunixtools:
+	cd Mac && $(MAKE) installunixtools DESTDIR="$(DESTDIR)"
+
+frameworkaltinstallunixtools:
+	cd Mac && $(MAKE) altinstallunixtools DESTDIR="$(DESTDIR)"
+
+# This installs the Demos and Tools into the applications directory.
+# It is not part of a normal frameworkinstall
+frameworkinstallextras:
+	cd Mac && Make installextras DESTDIR="$(DESTDIR)"
+
+# This installs a few of the useful scripts in Tools/scripts
+scriptsinstall:
+	SRCDIR=$(srcdir) $(RUNSHARED) \
+	./$(BUILDPYTHON) $(srcdir)/Tools/scripts/setup.py install \
+	--prefix=$(prefix) \
+	--install-scripts=$(BINDIR) \
+	--root=/$(DESTDIR)
+
+# Build the toplevel Makefile
+Makefile.pre: Makefile.pre.in config.status
+	CONFIG_FILES=Makefile.pre CONFIG_HEADERS= $(SHELL) config.status
+	$(MAKE) -f Makefile.pre Makefile
+
+# Run the configure script.
+config.status:	$(srcdir)/configure
+	$(SHELL) $(srcdir)/configure $(CONFIG_ARGS)
+
+.PRECIOUS: config.status $(BUILDPYTHON) Makefile Makefile.pre
+
+# Some make's put the object file in the current directory
+.c.o:
+	$(CC) -c $(PY_CFLAGS) -o $@ $<
+
+# Run reindent on the library
+reindent:
+	./python$(EXEEXT) $(srcdir)/Tools/scripts/reindent.py -r $(srcdir)/Lib
+
+# Rerun configure with the same options as it was run last time,
+# provided the config.status script exists
+recheck:
+	$(SHELL) config.status --recheck
+	$(SHELL) config.status
+
+# Rebuild the configure script from configure.in; also rebuild pyconfig.h.in
+autoconf:
+	(cd $(srcdir); autoconf)
+	(cd $(srcdir); autoheader)
+
+# Create a tags file for vi
+tags::
+	cd $(srcdir); \
+	ctags -w -t Include/*.h; \
+	for i in $(SRCDIRS); do ctags -w -t -a $$i/*.[ch]; \
+	done; \
+	sort -o tags tags
+
+# Create a tags file for GNU Emacs
+TAGS::
+	cd $(srcdir); \
+	etags Include/*.h; \
+	for i in $(SRCDIRS); do etags -a $$i/*.[ch]; done
+
+# Sanitation targets -- clean leaves libraries, executables and tags
+# files, which clobber removes those as well
+pycremoval:
+	find $(srcdir) -name '*.py[co]' -exec rm -f {} ';'
+
+clean: pycremoval
+	find . -name '*.o' -exec rm -f {} ';'
+	find . -name '*.s[ol]' -exec rm -f {} ';'
+	find $(srcdir)/build -name 'fficonfig.h' -exec rm -f {} ';' || true
+	find $(srcdir)/build -name 'fficonfig.py' -exec rm -f {} ';' || true
+
+clobber: clean
+	-rm -f $(BUILDPYTHON) $(PGEN) $(LIBRARY) $(LDLIBRARY) $(DLLLIBRARY) \
+		tags TAGS \
+		config.cache config.log pyconfig.h Modules/config.c
+	-rm -rf build platform
+	-rm -rf $(PYTHONFRAMEWORKDIR)
+
+# Make things extra clean, before making a distribution:
+# remove all generated files, even Makefile[.pre]
+# Keep configure and Python-ast.[ch], it's possible they can't be generated
+distclean: clobber
+	-rm -f core Makefile Makefile.pre config.status \
+		Modules/Setup Modules/Setup.local Modules/Setup.config
+	find $(srcdir) '(' -name '*.fdc' -o -name '*~' \
+			   -o -name '[@,#]*' -o -name '*.old' \
+			   -o -name '*.orig' -o -name '*.rej' \
+			   -o -name '*.bak' ')' \
+			   -exec rm -f {} ';'
+
+# Check for smelly exported symbols (not starting with Py/_Py)
+smelly: all
+	nm -p $(LIBRARY) | \
+		sed -n "/ [TDB] /s/.* //p" | grep -v "^_*Py" | sort -u; \
+
+# Find files with funny names
+funny:
+	find $(DISTDIRS) -type d \
+		-o -name '*.[chs]' \
+		-o -name '*.py' \
+		-o -name '*.doc' \
+		-o -name '*.sty' \
+		-o -name '*.bib' \
+		-o -name '*.dat' \
+		-o -name '*.el' \
+		-o -name '*.fd' \
+		-o -name '*.in' \
+		-o -name '*.tex' \
+		-o -name '*,[vpt]' \
+		-o -name 'Setup' \
+		-o -name 'Setup.*' \
+		-o -name README \
+		-o -name Makefile \
+		-o -name ChangeLog \
+		-o -name Repository \
+		-o -name Root \
+		-o -name Entries \
+		-o -name Tag \
+		-o -name tags \
+		-o -name TAGS \
+		-o -name .cvsignore \
+		-o -name MANIFEST \
+		-o -print
+
+# Dependencies
+
+Python/thread.o: @THREADHEADERS@
+
+# Declare targets that aren't real files
+.PHONY: all sharedmods oldsharedmods test quicktest memtest
+.PHONY: install altinstall oldsharedinstall bininstall altbininstall
+.PHONY: maninstall libinstall inclinstall libainstall sharedinstall
+.PHONY: frameworkinstall frameworkinstallframework frameworkinstallstructure
+.PHONY: frameworkinstallmaclib frameworkinstallapps frameworkinstallunixtools
+.PHONY: frameworkaltinstallunixtools recheck autoconf clean clobber distclean 
+.PHONY: smelly funny
+
+# IF YOU PUT ANYTHING HERE IT WILL GO AWAY

Added: vendor/Python/current/Misc/ACKS
===================================================================
--- vendor/Python/current/Misc/ACKS	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Misc/ACKS	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,698 @@
+Acknowledgements
+----------------
+
+This list is not complete and not in any useful order, but I would
+like to thank everybody who contributed in any way, with code, hints,
+bug reports, ideas, moral support, endorsement, or even complaints....
+Without you I would've stopped working on Python long ago!
+
+	--Guido
+
+PS: In the standard Python distribution this file is encoded in Latin-1.
+
+David Abrahams
+Jim Ahlstrom
+Jyrki Alakuijala
+Billy G. Allie
+Kevin Altis
+Mark Anacker
+Anders Andersen
+Erik Andersén
+John Anderson
+Oliver Andrich
+Ross Andrus
+Jason Asbahr
+David Ascher
+Peter Åstrand
+Chris AtLee
+John Aycock
+Donovan Baarda
+Attila Babo
+Alfonso Baciero
+Stig Bakken
+Greg Ball
+Luigi Ballabio
+Michael J. Barber
+Chris Barker
+Quentin Barnes
+Cesar Eduardo Barros
+Des Barry
+Ulf Bartelt
+Nick Bastin
+Jeff Bauer
+Michael R Bax
+Anthony Baxter
+Samuel L. Bayer
+Donald Beaudry
+David Beazley
+Neal Becker
+Robin Becker
+Bill Bedford
+Reimer Behrends
+Ben Bell
+Thomas Bellman
+Juan M. Bello Rivas
+Alexander Belopolsky
+Andrew Bennetts
+Andy Bensky
+Michel Van den Bergh
+Eric Beser
+Steven Bethard
+Stephen Bevan
+Ron Bickers
+Dominic Binks
+Philippe Biondi
+Stuart Bishop
+Roy Bixler
+Mike Bland
+Martin Bless
+Pablo Bleyer
+Erik van Blokland
+Eric Blossom
+Finn Bock
+Paul Boddie
+Matthew Boedicker
+David Bolen
+Gregory Bond
+Jurjen Bos
+Peter Bosch
+Eric Bouck
+Thierry Bousch
+Monty Brandenberg
+Georg Brandl
+Terrence Brannon
+Dave Brennan
+Tom Bridgman
+Richard Brodie
+Gary S. Brown
+Daniel Brotsky
+Oleg Broytmann
+Dave Brueck
+Stan Bubrouski
+Erik de Bueger
+Jan-Hein B"uhrman
+Dick Bulterman
+Bill Bumgarner
+Jimmy Burgett
+Tommy Burnette
+Roger Burnham
+Alastair Burt
+Tarn Weisner Burton
+Lee Busby
+Ralph Butler
+Jp Calderone
+Daniel Calvelo
+Tony Campbell
+Brett Cannon
+Mike Carlton
+Terry Carroll
+Luke Kenneth Casson Leighton
+Donn Cave
+Per Cederqvist
+Octavian Cerna
+Hye-Shik Chang
+Jeffrey Chang
+Brad Chapman
+Greg Chapman
+Mitch Chapman
+David Chaum
+Nicolas Chauvat
+Michael Chermside
+Albert Chin-A-Young
+Adal Chiriliuc
+Tom Christiansen
+Vadim Chugunov
+David Cinege
+Mike Clarkson
+Brad Clements
+Steve Clift
+Nick Coghlan
+Josh Cogliati
+Dave Cole
+Benjamin Collar
+Jeffery Collins
+Matt Conway
+David M. Cooke
+Greg Copeland
+Aldo Cortesi
+David Costanzo
+Scott Cotton
+Greg Couch
+Steve Cousins
+Alex Coventry
+Matthew Dixon Cowles
+Christopher A. Craig
+Laura Creighton
+Drew Csillag
+Tom Culliton
+John Cugini
+Andrew Dalke
+Lars Damerow
+Eric Daniel
+Scott David Daniels
+Ben Darnell
+Jonathan Dasteel
+John DeGood
+Vincent Delft
+Roger Dev
+Toby Dickenson
+Yves Dionne
+Daniel Dittmar
+Walter Dörwald
+Jaromir Dolecek
+Dima Dorfman
+Cesar Douady
+Dean Draayer
+Fred L. Drake, Jr.
+John DuBois
+Paul Dubois
+Quinn Dunkan
+Robin Dunn
+Luke Dunstan
+Andy Dustman
+Gary Duzan
+Eugene Dvurechenski
+Maxim Dzumanenko
+Hans Eckardt
+Grant Edwards
+John Ehresman
+Andrew Eland
+Lance Ellinghaus
+David Ely
+Jeff Epler
+Tom Epperly
+Stoffel Erasmus
+Jürgen A. Erhard
+Michael Ernst
+Ben Escoto
+Andy Eskilsson
+Stefan Esser
+Carey Evans
+Stephen D Evans
+Tim Everett
+Paul Everitt
+David Everly
+Greg Ewing
+Martijn Faassen
+Andreas Faerber
+Bill Fancher
+Mark Favas
+Niels Ferguson
+Sebastian Fernandez
+Vincent Fiack
+Russell Finn
+Nils Fischbeck
+Frederik Fix
+Matt Fleming
+Hernán Martínez Foffani
+Doug Fort
+John Fouhy
+Martin Franklin
+Robin Friedrich
+Ivan Frohne
+Jim Fulton
+Tadayoshi Funaba
+Gyro Funch
+Peter Funk
+Geoff Furnish
+Lele Gaifax
+Yitzchak Gale
+Raymund Galvin
+Nitin Ganatra
+Fred Gansevles
+Lars Marius Garshol
+Dan Gass
+Andrew Gaul
+Stephen M. Gava
+Harry Henry Gebel
+Marius Gedminas
+Thomas Gellekum
+Christos Georgiou
+Ben Gertzfield
+Dinu Gherman
+Jonathan Giddy
+Johannes Gijsbers
+Michael Gilfix
+Chris Gonnerman
+David Goodger
+Hans de Graaff
+Eddy De Greef
+Duncan Grisby
+Dag Gruneau
+Michael Guravage
+Lars Gustäbel
+Barry Haddow
+Václav Haisman
+Paul ten Hagen
+Rasmus Hahn
+Peter Haight
+Bob Halley
+Jesse Hallio
+Jun Hamano
+Mark Hammond
+Manus Hand
+Milton L. Hankins
+Stephen Hansen
+Barry Hantman
+Lynda Hardman
+Derek Harland
+Jason Harper
+Gerhard Häring
+Larry Hastings
+Shane Hathaway
+Rycharde Hawkes
+Jochen Hayek
+Thomas Heller
+Lance Finn Helsten
+Jonathan Hendry
+James Henstridge
+Chris Herborth
+Ivan Herman
+Jürgen Hermann
+Gary Herron
+Bernhard Herzog
+Magnus L. Hetland
+Raymond Hettinger
+Kevan Heydon
+Jason Hildebrand
+Richie Hindle
+Konrad Hinsen
+David Hobley
+Tim Hochberg
+Joerg-Cyril Hoehle
+Gregor Hoffleit
+Chris Hoffman
+Albert Hofkamp
+Jonathan Hogg
+Gerrit Holl
+Rune Holm
+Philip Homburg
+Naofumi Honda
+Jeffrey Honig
+Rob Hooft
+Brian Hooper
+Randall Hopper
+Nadav Horesh
+Ken Howard
+Brad Howes
+Chih-Hao Huang
+Lawrence Hudson
+Michael Hudson
+Jim Hugunin
+Greg Humphreys
+Eric Huss
+Jeremy Hylton
+Mihai Ibanescu
+Juan David Ibáñez Palomar
+Lars Immisch
+Tony Ingraldi
+John Interrante
+Bob Ippolito
+Ben Jackson
+Paul Jackson
+David Jacobs
+Kevin Jacobs
+Kjetil Jacobsen
+Geert Jansen
+Jack Jansen
+Bill Janssen
+Drew Jenkins
+Flemming Kjær Jensen
+Jiba
+Orjan Johansen
+Gregory K. Johnson
+Simon Johnston
+Evan Jones
+Richard Jones
+Irmen de Jong
+Lucas de Jonge
+Jens B. Jorgensen
+John Jorgensen
+Andreas Jung
+Tattoo Mabonzo K.
+Bob Kahn
+Kurt B. Kaiser
+Tamito Kajiyama
+Peter van Kampen
+Jacob Kaplan-Moss
+Lou Kates
+Sebastien Keim
+Randall Kern
+Robert Kern
+Magnus Kessler
+Lawrence Kesteloot
+Vivek Khera
+Mads Kiilerich
+Steve Kirsch
+Ron Klatchko
+Bastian Kleineidam
+Bob Kline
+Matthias Klose
+Kim Knapp
+Lenny Kneler
+Pat Knight
+Greg Kochanski
+Joseph Koshy
+Bob Kras
+Holger Krekel
+Hannu Krosing
+Andrew Kuchling
+Vladimir Kushnir
+Arnaud Mazin
+Cameron Laird
+Tino Lange
+Andrew Langmead
+Detlef Lannert
+Soren Larsen
+Piers Lauder
+Ben Laurie
+Simon Law
+Chris Lawrence
+Christopher Lee
+Inyeol Lee
+John J. Lee
+Thomas Lee
+Luc Lefebvre
+Kip Lehman
+Joerg Lehmann
+Marc-Andre Lemburg
+William Lewis
+Robert van Liere
+Martin Ligr
+Christopher Lindblad
+Eric Lindvall
+Per Lindqvist
+Nick Lockwood
+Stephanie Lockwood
+Martin von Löwis
+Anne Lord
+Tom Loredo
+Jason Lowe
+Tony Lownds
+Ray Loyzaga
+Loren Luke
+Fredrik Lundh
+Mark Lutz
+Jim Lynch
+Mikael Lyngvig
+Alan McIntyre
+Andrew I MacIntyre
+Tim MacKenzie
+Nick Maclaren
+Steve Majewski
+Grzegorz Makarewicz
+Ken Manheimer
+Vladimir Marangozov
+Doug Marien
+Alex Martelli
+Anthony Martin
+Roger Masse
+Nick Mathewson
+Graham Matthews
+Dieter Maurer
+Greg McFarlane
+Michael McLay
+Gordon McMillan
+Jay T. Miller
+Chris McDonough
+Andrew McNamara
+Caolan McNamara
+Craig McPheeters
+Lambert Meertens
+Bill van Melle
+Luke Mewburn
+Mike Meyer
+Steven Miale
+Trent Mick
+Chad Miller
+Roman Milner
+Dom Mitchell
+Doug Moen
+Paul Moore
+The Dragon De Monsyne
+Skip Montanaro
+James A Morrison
+Sape Mullender
+Sjoerd Mullender
+Michael Muller
+Takahiro Nakayama
+Travers Naran
+Fredrik Nehr
+Tony Nelson
+Chad Netzer
+Max Neunhöffer
+George Neville-Neil
+Johannes Nicolai
+Samuel Nicolary
+Gustavo Niemeyer
+Oscar Nierstrasz
+Hrvoje Niksic
+Bill Noon
+Stefan Norberg
+Tim Northover
+Joe Norton
+Neal Norwitz
+Nigel O'Brian
+Kevin O'Connor
+Tim O'Malley
+Pascal Oberndoerfer
+Jeffrey Ollie
+Grant Olson
+Piet van Oostrum
+Jason Orendorff
+Douglas Orr
+Denis S. Otkidach
+Russel Owen
+Mike Pall
+Todd R. Palmer
+Jan Palus
+Alexandre Parenteau
+Dan Parisien
+Harri Pasanen
+Randy Pausch
+Ondrej Palkovsky
+M. Papillon
+Marcel van der Peijl
+Samuele Pedroni
+Steven Pemberton
+Eduardo Pérez
+Fernando Pérez
+Mark Perrego
+Trevor Perrin
+Tim Peters
+Chris Petrilli
+Bjorn Pettersen
+Geoff Philbrick
+Gavrie Philipson
+Adrian Phillips
+Christopher J. Phoenix
+Neale Pickett
+Jean-François Piéronne
+Dan Pierson
+Martijn Pieters
+François Pinard
+Zach Pincus
+Michael Piotrowski
+Iustin Pop
+John Popplewell
+Amrit Prem
+Paul Prescod
+Donovan Preston
+Steve Purcell
+Brian Quinlan
+Anders Qvist
+Burton Radons
+Eric Raymond
+Edward K. Ream
+Marc Recht
+John Redford
+Terry Reedy
+Steve Reeves
+Ofir Reichenberg
+Sean Reifschneider
+Michael P. Reilly
+Bernhard Reiter
+Steven Reiz
+Roeland Rengelink
+Tim Rice
+Jan Pieter Riegel
+Armin Rigo
+Nicholas Riley
+Jean-Claude Rimbault
+Anthony Roach
+Andy Robinson
+Jim Robinson
+Kevin Rodgers
+Mike Romberg
+Case Roole
+Timothy Roscoe
+Craig Rowland
+Jim Roskind
+Erik van Blokland
+Just van Rossum
+Hugo van Rossum
+Saskia van Rossum
+Donald Wallace Rouse II
+Liam Routt
+Sam Ruby
+Paul Rubin
+Audun S. Runde
+Jeff Rush
+Sam Rushing
+Mark Russell
+Nick Russo
+Hajime Saitou
+Rich Salz
+Kevin Samborn
+Ty Sarna
+Ben Sayer
+Michael Scharf
+Neil Schemenauer
+David Scherer
+Gregor Schmid
+Ralf Schmitt
+Peter Schneider-Kamp
+Chad J. Schroeder
+Sam Schulenburg
+Stefan Schwarzer
+Dietmar Schwertberger
+Barry Scott
+Steven Scott
+Nick Seidenman
+Žiga Seilnach
+Fred Sells
+Jiwon Seo
+Denis Severson
+Ha Shao
+Bruce Sherwood
+Pete Shinners
+Michael Shiplett
+John W. Shipman
+Joel Shprentz
+Itamar Shtull-Trauring
+Eric Siegerman
+Paul Sijben
+Kirill Simonov
+Nathan Paul Simons
+Janne Sinkkonen
+George Sipe
+J. Sipprell
+Kragen Sitaker
+Christopher Smith
+Gregory P. Smith
+Rafal Smotrzyk
+Dirk Soede
+Paul Sokolovsky
+Clay Spence
+Per Spilling
+Joshua Spoerri
+Noah Spurrier
+Nathan Srebro
+RajGopal Srinivasan
+Jim St. Pierre
+Quentin Stafford-Fraser
+Frank Stajano
+Oliver Steele
+Greg Stein
+Chris Stern
+Richard Stoakley
+Peter Stoehr
+Casper Stoel
+Michael Stone
+Ken Stox
+Dan Stromberg
+Daniel Stutzbach
+Nathan Sullivan
+Mark Summerfield
+Hisao Suzuki
+Kalle Svensson
+Paul Swartz
+Thenault Sylvain
+Geoff Talvola
+William Tanksley
+Christian Tanzer
+Steven Taschuk
+Amy Taylor
+Tobias Thelen
+Robin Thomas
+Eric Tiedemann
+Tracy Tims
+Oren Tirosh
+Jason Tishler
+Christian Tismer
+Frank J. Tobin
+R Lindsay Todd
+Bennett Todd
+Richard Townsend
+Laurence Tratt
+John Tromp
+Jason Trowbridge
+Anthony Tuininga
+Christopher Tur Lesniewski-Laas
+Stephen Turner
+Bill Tutt
+Doobee R. Tzeck
+Lionel Ulmer
+Michael Urman
+Hector Urtubia
+Dmitry Vasiliev
+Frank Vercruesse
+Jaap Vermeulen
+Al Vezza
+Jacques A. Vidrine
+John Viega
+Kannan Vijayan
+Kurt Vile
+Norman Vine
+Frank Visser
+Niki W. Waibel
+Wojtek Walczak
+Charles Waldman
+Richard Walker
+Larry Wall
+Greg Ward
+Barry Warsaw
+Steve Waterbury
+Bob Watson
+Aaron Watters
+Henrik Weber
+Corran Webster
+Zack Weinberg
+Edward Welbourne
+Cliff Wells
+Rickard Westman
+Mats Wichmann
+Truida Wiedijk
+Felix Wiemann
+Gerry Wiener
+Bryce "Zooko" Wilcox-O'Hearn
+Gerald S. Williams
+John Williams
+Sue Williams
+Frank Willison
+Greg V. Wilson
+Jody Winston
+Collin Winter
+Dik Winter
+Blake Winton
+Jean-Claude Wippler
+Lars Wirzenius
+Stefan Witzel
+Klaus-Juergen Wolf
+Dan Wolfe
+Richard Wolff
+Gordon Worley
+Thomas Wouters
+Doug Wyatt
+Ka-Ping Yee
+Bob Yodlowski
+Danny Yoo
+George Yoshida
+Masazumi Yoshikawa
+Bernard Yue
+Moshe Zadka
+Milan Zamazal
+Artur Zaprzala
+Mike Zarnstorff
+Siebren van der Zee
+Uwe Zessin

Added: vendor/Python/current/Misc/AIX-NOTES
===================================================================
--- vendor/Python/current/Misc/AIX-NOTES	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Misc/AIX-NOTES	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,155 @@
+Subject: AIX - Misc/AIX-NOTES
+From: Vladimir Marangozov <Vladimir.Marangozov at imag.fr>
+To: guido at CNRI.Reston.Va.US (Guido van Rossum)
+Date: Wed, 6 Aug 1997 11:41:00 +0200 (EET)
+
+==============================================================================
+                              COMPILER INFORMATION
+------------------------------------------------------------------------------
+
+(1) A problem has been reported with "make test" failing because of "weird
+    indentation."  Searching the comp.lang.python newsgroup reveals several
+    threads on this subject, and it seems to be a compiler bug in an old
+    version of the AIX CC compiler.  However, the compiler/OS combination
+    which has this problem is not identified.  In preparation for the 1.4
+    release, Vladimir Marangozov (Vladimir.Marangozov at imag.fr) and Manus Hand
+    (mhand at csn.net) reported no such troubles for the following compilers and
+    operating system versions:
+       AIX C compiler version 3.1.2 on AIX 4.1.3 and AIX 4.1.4
+       AIX C compiler version 1.3.0 on AIX 3.2.5
+    If you have this problem, please report the compiler/OS version.
+
+(2) Stefan Esser (se at MI.Uni-Koeln.DE), in work done to compile Python
+    1.0.0 on AIX 3.2.4, reports that AIX compilers don't like the LANG
+    environment varaiable set to European locales.  This makes the compiler
+    generate floating point constants using "," as the decimal seperator,
+    which the assembler doesn't understand (or perhaps it is the other way
+    around, with the assembler expecting, but not getting "," in float
+    numbers).  "LANG=C; export LANG" solves the problem, as does
+    "LANG=C $(MAKE) ..." in the master Makefile.
+
+(3) The cc (or xlc) compiler considers "Python/ceval.c" too complex to
+    optimize, except when invoked with "-qmaxmem=4000"
+
+(4) Some problems (due to _AIX not being #defined) when python 1.0.0 was
+    compiled using 'gcc -ansi' were reported by Stefan Esser, but were not
+    investigated.
+
+(5) The cc compiler has internal variables named "__abs" and "__div".  These
+    names are reserved and may not be used as program variables in compiled
+    source.  (As an anecdote in support of this, the implementation of
+    Python/operator.c had this problem in the 1.4 beta releases, and the
+    solution was to re#define some core-source variables having these names,
+    to give these python variables different names if the build is being done
+    on AIX.)
+
+(6) As mentioned in the README, builds done immediately after previous builds
+    (without "make clean" or "make clobber") sometimes fail for mysterious
+    reasons.  There are some unpredictable results when the configuration
+    is changed (that is, if you "configure" with different parameters) or if
+    intermediate changes are made to some files.  Performing "make clean" or
+    "make clobber" resolves the problems.
+
+==============================================================================
+                                THREAD SUPPORT
+------------------------------------------------------------------------------
+
+As of AIX version 4, there are two (incompatible) types of pthreads on AIX:
+        a)  AIX DCE pthreads (on AIX 3.2.5)
+        b)  AIX 4 pthreads (on AIX 4.1 and up)
+Support has been added to Python to handle the distinction.
+
+The cc and gcc compilers do not initialize pthreads properly. The only
+compilers that can initialize pthreads properly are IBM *_r* compilers,
+which use the crt0_r.o module, and which invoke ld with the reentrant
+version of libc (libc_r).
+
+In order to enable thread support, follow these steps:
+   1.  Uncomment the thread module in Modules/Setup
+   2.  configure --without-gcc --with-thread ...
+   3.  make CC="cc_r" OPT="-O -qmaxmem=4000"
+
+For example, to make with both threads and readline, use:
+  ./configure --without-gcc --with-thread --with-readline=/usr/local/lib
+  make CC=cc_r OPT="-O2 -qmaxmem=4000"
+
+If the "make" which is used ignores the "CC=cc_r" directive, one could alias
+the cc command to cc_r (for example, in C-shell, perform an "alias cc cc_r").
+
+Vladimir Marangozov (Vladimir.Marangozov at imag.fr) provided this information,
+and he reports that a cc_r build initializes threads properly and that all
+demos on threads run okay with cc_r.
+
+==============================================================================
+                            SHARED LIBRARY SUPPORT
+------------------------------------------------------------------------------
+
+AIX shared library support was added to Python in the 1.4 release by Manus
+Hand (mhand at csn.net) and Vladimir Marangozov (Vladimir.Marangozov at imag.fr).
+
+Python modules may now be built as shared libraries on AIX using the normal
+process of uncommenting the "*shared*" line in Modules/Setup before the
+build.
+
+AIX shared libraries require that an "export" and "import" file be provided
+at compile time to list all extern symbols which may be shared between
+modules.  The "export" file (named python.exp) for the modules and the
+libraries that belong to the Python core is created by the "makexp_aix"
+script before performing the link of the python binary. It lists all global
+symbols (exported during the link) of the modules and the libraries that
+make up the python executable.
+
+When shared library modules (.so files) are made, a second shell script
+is invoked.  This script is named "ld_so_aix" and is also provided with
+the distribution in the Modules subdirectory.  This script acts as an "ld"
+wrapper which hides the explicit management of "export" and "import" files;
+it adds the appropriate arguments (in the appropriate order) to the link
+command that creates the shared module.  Among other things, it specifies
+that the "python.exp" file is an "import" file for the shared module.
+
+At the time of this writing, neither the python.exp file nor the makexp_aix
+or ld_so_aix scripts are installed by the make procedure, so you should
+remember to keep these and/or copy them to a different location for
+safekeeping if you wish to use them to add shared extension modules to
+python.  However, if the make process has been updated since this writing,
+these files MAY have been installed for you during the make by the
+LIBAINSTALL rule, in which case the need to make safe copies is obviated.
+
+If you wish to add a shared extension module to the language, you would follow
+the steps given in the example below (the example adds the shared extension
+module "spam" to python):
+    1.  Make sure that "ld_so_aix" and "makexp_aix" are in your path.
+    2.  The "python.exp" file should be in the current directory.
+    3.  Issue the following commands or include them in your Makefile:
+            cc -c spammodule.c
+            ld_so_aix cc spammodule.o -o spammodule.so
+
+For more detailed information on the shared library support, examine the
+contents of the "ld_so_aix" and "makexp_aix" scripts or refer to the AIX
+documentation.
+
+NOTE:  If the extension module is written in C++ and contains templates,
+       an alternative to "ld_so_aix" is the /usr/lpp/xlC/bin/makeC++SharedLib
+       script.  Chris Myers (myers at TC.Cornell.EDU) reports that ld_so_aix
+       works well for some C++ (including the C++ that is generated
+       automatically by the Python SWIG package [SWIG can be found at
+       http://www.cs.utah.edu/~beazley/SWIG/swig.html]).  However, it is not
+       known whether makeC++SharedLib can be used as a complete substitute
+       for ld_so_aix.
+
+According to Gary Hook from IBM, the format of the export file changed
+in AIX 4.2.  For AIX 4.2 and later, a period "." is required on the
+first line after "#!".  If python crashes while importing a shared
+library, you can try modifying the LINKCC variable in the Makefile.
+It probably looks like this:
+
+	LINKCC=     $(srcdir)/Modules/makexp_aix Modules/python.exp \"\" $(LIBRARY); $(PURIFY) $(CXX)
+
+You should modify the \"\" to be a period:
+
+	LINKCC=     $(srcdir)/Modules/makexp_aix Modules/python.exp . $(LIBRARY); $(PURIFY) $(CXX)
+
+Using a period fixed the problem in the snake farm.  YMMV.
+This fix has been incorporated into Python 2.3.
+
+==============================================================================

Added: vendor/Python/current/Misc/BeOS-NOTES
===================================================================
--- vendor/Python/current/Misc/BeOS-NOTES	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Misc/BeOS-NOTES	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,43 @@
+Python for BeOS R5
+
+In Python-2.1, the standard version of the new setup.py program
+will not build the full complement of modules on BeOS.  Instead,
+please replace it with the special BeOS version in Misc/BeOS-setup.py.
+
+To build,
+
+   1)  cp Misc/BeOS-setup.py setup.py
+   2)  ./configure --prefix=/boot/home/config
+   3)  make
+
+The modules will all build, except termios which assumes some flags
+we don't have.  Put a libreadline.a in /boot/home/config/lib to get
+a readline.so for your interactive editing convenience;  NB, not
+libreadline.so, you want to link a static readline library into the
+dynamically loaded Python module.
+
+Test:
+
+   make test
+
+   The BeOS is Not UNIX category:
+ - test_select crashed -- select.error : (-2147459072, 'Bad file descriptor')
+ - test_socket crashed -- exceptions.AttributeError : SOCK_RAW
+ - test_fcntl crashed -- exceptions.IOError: [Errno -2147483643] Invalid argument
+
+   This one is funny!  BeOS does support large files, and that's why
+       we get this error:  the file is too big for my filesystem!
+ - test_largefile crashed -- exceptions.IOError: [Errno -2147459065]
+       No space left on device
+
+ - test_pickle crashed.  This is apparently a serious problem, "complex"
+       number objects reconstructed from a pickle don't compare equal to
+       their ancestors.  But it happens on BeOS PPC only, not Intel.
+
+Install:
+
+   make install
+
+
+- Donn Cave (donn at oz.net)
+  October 4, 2000

Added: vendor/Python/current/Misc/BeOS-setup.py
===================================================================
--- vendor/Python/current/Misc/BeOS-setup.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Misc/BeOS-setup.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,574 @@
+# Autodetecting setup.py script for building the Python extensions
+#
+# Modified for BeOS build.  Donn Cave, March 27 2001.
+
+__version__ = "special BeOS after 1.37"
+
+import sys, os, getopt
+from distutils import sysconfig
+from distutils import text_file
+from distutils.errors import *
+from distutils.core import Extension, setup
+from distutils.command.build_ext import build_ext
+
+# This global variable is used to hold the list of modules to be disabled.
+disabled_module_list = ['dbm', 'mmap', 'resource', 'nis']
+
+def find_file(filename, std_dirs, paths):
+    """Searches for the directory where a given file is located,
+    and returns a possibly-empty list of additional directories, or None
+    if the file couldn't be found at all.
+
+    'filename' is the name of a file, such as readline.h or libcrypto.a.
+    'std_dirs' is the list of standard system directories; if the
+        file is found in one of them, no additional directives are needed.
+    'paths' is a list of additional locations to check; if the file is
+        found in one of them, the resulting list will contain the directory.
+    """
+
+    # Check the standard locations
+    for dir in std_dirs:
+        f = os.path.join(dir, filename)
+        if os.path.exists(f): return []
+
+    # Check the additional directories
+    for dir in paths:
+        f = os.path.join(dir, filename)
+        if os.path.exists(f):
+            return [dir]
+
+    # Not found anywhere
+    return None
+
+def find_library_file(compiler, libname, std_dirs, paths):
+    filename = compiler.library_filename(libname, lib_type='shared')
+    result = find_file(filename, std_dirs, paths)
+    if result is not None: return result
+
+    filename = compiler.library_filename(libname, lib_type='static')
+    result = find_file(filename, std_dirs, paths)
+    return result
+
+def module_enabled(extlist, modname):
+    """Returns whether the module 'modname' is present in the list
+    of extensions 'extlist'."""
+    extlist = [ext for ext in extlist if ext.name == modname]
+    return len(extlist)
+
+class PyBuildExt(build_ext):
+
+    def build_extensions(self):
+
+        # Detect which modules should be compiled
+        self.detect_modules()
+
+        # Remove modules that are present on the disabled list
+        self.extensions = [ext for ext in self.extensions
+                           if ext.name not in disabled_module_list]
+
+        # Fix up the autodetected modules, prefixing all the source files
+        # with Modules/ and adding Python's include directory to the path.
+        (srcdir,) = sysconfig.get_config_vars('srcdir')
+
+        # Figure out the location of the source code for extension modules
+        moddir = os.path.join(os.getcwd(), srcdir, 'Modules')
+        moddir = os.path.normpath(moddir)
+        srcdir, tail = os.path.split(moddir)
+        srcdir = os.path.normpath(srcdir)
+        moddir = os.path.normpath(moddir)
+
+        # Fix up the paths for scripts, too
+        self.distribution.scripts = [os.path.join(srcdir, filename)
+                                     for filename in self.distribution.scripts]
+
+        for ext in self.extensions[:]:
+            ext.sources = [ os.path.join(moddir, filename)
+                            for filename in ext.sources ]
+            ext.include_dirs.append( '.' ) # to get config.h
+            ext.include_dirs.append( os.path.join(srcdir, './Include') )
+
+            # If a module has already been built statically,
+            # don't build it here
+            if ext.name in sys.builtin_module_names:
+                self.extensions.remove(ext)
+
+        # Parse Modules/Setup to figure out which modules are turned
+        # on in the file.
+        input = text_file.TextFile('Modules/Setup', join_lines=1)
+        remove_modules = []
+        while 1:
+            line = input.readline()
+            if not line: break
+            line = line.split()
+            remove_modules.append( line[0] )
+        input.close()
+
+        for ext in self.extensions[:]:
+            if ext.name in remove_modules:
+                self.extensions.remove(ext)
+
+        # When you run "make CC=altcc" or something similar, you really want
+        # those environment variables passed into the setup.py phase.  Here's
+        # a small set of useful ones.
+        compiler = os.environ.get('CC')
+        linker_so = os.environ.get('LDSHARED')
+        args = {}
+        # unfortunately, distutils doesn't let us provide separate C and C++
+        # compilers
+        if compiler is not None:
+            args['compiler_so'] = compiler
+        if linker_so is not None:
+            args['linker_so'] = linker_so + ' -shared'
+        self.compiler.set_executables(**args)
+
+        build_ext.build_extensions(self)
+
+    def build_extension(self, ext):
+
+        try:
+            build_ext.build_extension(self, ext)
+        except (CCompilerError, DistutilsError), why:
+            self.announce('WARNING: building of extension "%s" failed: %s' %
+                          (ext.name, sys.exc_info()[1]))
+
+    def get_platform (self):
+        # Get value of sys.platform
+        platform = sys.platform
+        if platform[:6] =='cygwin':
+            platform = 'cygwin'
+        elif platform[:4] =='beos':
+            platform = 'beos'
+
+        return platform
+
+    def detect_modules(self):
+        try:
+            belibs = os.environ['BELIBRARIES'].split(';')
+        except KeyError:
+            belibs = ['/boot/beos/system/lib']
+        belibs.append('/boot/home/config/lib')
+        self.compiler.library_dirs.append('/boot/home/config/lib')
+        try:
+            beincl = os.environ['BEINCLUDES'].split(';')
+        except KeyError:
+            beincl = []
+        beincl.append('/boot/home/config/include')
+        self.compiler.include_dirs.append('/boot/home/config/include')
+        # lib_dirs and inc_dirs are used to search for files;
+        # if a file is found in one of those directories, it can
+        # be assumed that no additional -I,-L directives are needed.
+        lib_dirs = belibs
+        inc_dirs = beincl
+        exts = []
+
+        platform = self.get_platform()
+
+        # Check for MacOS X, which doesn't need libm.a at all
+        math_libs = ['m']
+        if platform in ['Darwin1.2', 'beos']:
+            math_libs = []
+
+        # XXX Omitted modules: gl, pure, dl, SGI-specific modules
+
+        #
+        # The following modules are all pretty straightforward, and compile
+        # on pretty much any POSIXish platform.
+        #
+
+        # Some modules that are normally always on:
+        exts.append( Extension('_weakref', ['_weakref.c']) )
+        exts.append( Extension('_symtable', ['symtablemodule.c']) )
+
+        # array objects
+        exts.append( Extension('array', ['arraymodule.c']) )
+        # complex math library functions
+        exts.append( Extension('cmath', ['cmathmodule.c'],
+                               libraries=math_libs) )
+
+        # math library functions, e.g. sin()
+        exts.append( Extension('math',  ['mathmodule.c'],
+                               libraries=math_libs) )
+        # fast string operations implemented in C
+        exts.append( Extension('strop', ['stropmodule.c']) )
+        # time operations and variables
+        exts.append( Extension('time', ['timemodule.c'],
+                               libraries=math_libs) )
+        # operator.add() and similar goodies
+        exts.append( Extension('operator', ['operator.c']) )
+        # access to the builtin codecs and codec registry
+        exts.append( Extension('_codecs', ['_codecsmodule.c']) )
+        # Python C API test module
+        exts.append( Extension('_testcapi', ['_testcapimodule.c']) )
+        # static Unicode character database
+        exts.append( Extension('unicodedata', ['unicodedata.c']) )
+        # access to ISO C locale support
+        exts.append( Extension('_locale', ['_localemodule.c']) )
+
+        # Modules with some UNIX dependencies -- on by default:
+        # (If you have a really backward UNIX, select and socket may not be
+        # supported...)
+
+        # fcntl(2) and ioctl(2)
+        exts.append( Extension('fcntl', ['fcntlmodule.c']) )
+        # pwd(3)
+        exts.append( Extension('pwd', ['pwdmodule.c']) )
+        # grp(3)
+        exts.append( Extension('grp', ['grpmodule.c']) )
+        # posix (UNIX) errno values
+        exts.append( Extension('errno', ['errnomodule.c']) )
+        # select(2); not on ancient System V
+        exts.append( Extension('select', ['selectmodule.c']) )
+
+        # The md5 module implements the RSA Data Security, Inc. MD5
+        # Message-Digest Algorithm, described in RFC 1321.  The necessary files
+        # md5c.c and md5.h are included here.
+        exts.append( Extension('md5', ['md5module.c', 'md5c.c']) )
+
+        # The sha module implements the SHA checksum algorithm.
+        # (NIST's Secure Hash Algorithm.)
+        exts.append( Extension('sha', ['shamodule.c']) )
+
+        # Helper module for various ascii-encoders
+        exts.append( Extension('binascii', ['binascii.c']) )
+
+        # Fred Drake's interface to the Python parser
+        exts.append( Extension('parser', ['parsermodule.c']) )
+
+        # cStringIO and cPickle
+        exts.append( Extension('cStringIO', ['cStringIO.c']) )
+        exts.append( Extension('cPickle', ['cPickle.c']) )
+
+        # Memory-mapped files (also works on Win32).
+        exts.append( Extension('mmap', ['mmapmodule.c']) )
+
+        # Lance Ellinghaus's syslog daemon interface
+        exts.append( Extension('syslog', ['syslogmodule.c']) )
+
+        # George Neville-Neil's timing module:
+        exts.append( Extension('timing', ['timingmodule.c']) )
+
+        #
+        # Here ends the simple stuff.  From here on, modules need certain
+        # libraries, are platform-specific, or present other surprises.
+        #
+
+        # Multimedia modules
+        # These don't work for 64-bit platforms!!!
+        # These represent audio samples or images as strings:
+
+        # Disabled on 64-bit platforms
+        if sys.maxint != 9223372036854775807L:
+            # Operations on audio samples
+            exts.append( Extension('audioop', ['audioop.c']) )
+            # Operations on images
+            exts.append( Extension('imageop', ['imageop.c']) )
+            # Read SGI RGB image files (but coded portably)
+            exts.append( Extension('rgbimg', ['rgbimgmodule.c']) )
+
+        # readline
+        if self.compiler.find_library_file(lib_dirs, 'readline'):
+            readline_libs = ['readline']
+            if self.compiler.find_library_file(lib_dirs +
+                                               ['/usr/lib/termcap'],
+                                               'termcap'):
+                readline_libs.append('termcap')
+            exts.append( Extension('readline', ['readline.c'],
+                                   library_dirs=['/usr/lib/termcap'],
+                                   libraries=readline_libs) )
+
+        # The crypt module is now disabled by default because it breaks builds
+        # on many systems (where -lcrypt is needed), e.g. Linux (I believe).
+
+        if self.compiler.find_library_file(lib_dirs, 'crypt'):
+            libs = ['crypt']
+        else:
+            libs = []
+        exts.append( Extension('crypt', ['cryptmodule.c'], libraries=libs) )
+
+        # socket(2)
+        # Detect SSL support for the socket module
+        ssl_incs = find_file('openssl/ssl.h', inc_dirs,
+                             ['/usr/local/ssl/include',
+                              '/usr/contrib/ssl/include/'
+                             ]
+                             )
+        ssl_libs = find_library_file(self.compiler, 'ssl',lib_dirs,
+                                     ['/usr/local/ssl/lib',
+                                      '/usr/contrib/ssl/lib/'
+                                     ] )
+
+        if (ssl_incs is not None and
+            ssl_libs is not None):
+            exts.append( Extension('_socket', ['socketmodule.c'],
+                                   include_dirs = ssl_incs,
+                                   library_dirs = ssl_libs,
+                                   libraries = ['ssl', 'crypto'],
+                                   define_macros = [('USE_SSL',1)] ) )
+        else:
+            exts.append( Extension('_socket', ['socketmodule.c']) )
+
+        # Modules that provide persistent dictionary-like semantics.  You will
+        # probably want to arrange for at least one of them to be available on
+        # your machine, though none are defined by default because of library
+        # dependencies.  The Python module anydbm.py provides an
+        # implementation independent wrapper for these; dumbdbm.py provides
+        # similar functionality (but slower of course) implemented in Python.
+
+        # The standard Unix dbm module:
+        if platform not in ['cygwin']:
+            if (self.compiler.find_library_file(lib_dirs, 'ndbm')):
+                exts.append( Extension('dbm', ['dbmmodule.c'],
+                                       libraries = ['ndbm'] ) )
+            else:
+                exts.append( Extension('dbm', ['dbmmodule.c']) )
+
+        # Anthony Baxter's gdbm module.  GNU dbm(3) will require -lgdbm:
+        if (self.compiler.find_library_file(lib_dirs, 'gdbm')):
+            exts.append( Extension('gdbm', ['gdbmmodule.c'],
+                                   libraries = ['gdbm'] ) )
+
+        # Berkeley DB interface.
+        #
+        # This requires the Berkeley DB code, see
+        # ftp://ftp.cs.berkeley.edu/pub/4bsd/db.1.85.tar.gz
+        #
+        # Edit the variables DB and DBPORT to point to the db top directory
+        # and the subdirectory of PORT where you built it.
+        #
+        # (See http://electricrain.com/greg/python/bsddb3/ for an interface to
+        # BSD DB 3.x.)
+
+        dblib = []
+        if self.compiler.find_library_file(lib_dirs, 'db'):
+            dblib = ['db']
+
+        db185_incs = find_file('db_185.h', inc_dirs,
+                               ['/usr/include/db3', '/usr/include/db2'])
+        db_inc = find_file('db.h', inc_dirs, ['/usr/include/db1'])
+        if db185_incs is not None:
+            exts.append( Extension('bsddb', ['bsddbmodule.c'],
+                                   include_dirs = db185_incs,
+                                   define_macros=[('HAVE_DB_185_H',1)],
+                                   libraries = dblib ) )
+        elif db_inc is not None:
+            exts.append( Extension('bsddb', ['bsddbmodule.c'],
+                                   include_dirs = db_inc,
+                                   libraries = dblib) )
+
+        # Unix-only modules
+        if platform not in ['mac', 'win32']:
+            # Steen Lumholt's termios module
+            exts.append( Extension('termios', ['termios.c']) )
+            # Jeremy Hylton's rlimit interface
+            if platform not in ['cygwin']:
+                exts.append( Extension('resource', ['resource.c']) )
+
+            # Generic dynamic loading module
+            #exts.append( Extension('dl', ['dlmodule.c']) )
+
+            # Sun yellow pages. Some systems have the functions in libc.
+            if platform not in ['cygwin']:
+                if (self.compiler.find_library_file(lib_dirs, 'nsl')):
+                    libs = ['nsl']
+                else:
+                    libs = []
+                exts.append( Extension('nis', ['nismodule.c'],
+                                       libraries = libs) )
+
+        # Curses support, requring the System V version of curses, often
+        # provided by the ncurses library.
+        if (self.compiler.find_library_file(lib_dirs, 'ncurses')):
+            curses_libs = ['ncurses']
+            exts.append( Extension('_curses', ['_cursesmodule.c'],
+                                   libraries = curses_libs) )
+        elif (self.compiler.find_library_file(lib_dirs, 'curses')):
+            if (self.compiler.find_library_file(lib_dirs, 'terminfo')):
+                curses_libs = ['curses', 'terminfo']
+            else:
+                curses_libs = ['curses', 'termcap']
+
+            exts.append( Extension('_curses', ['_cursesmodule.c'],
+                                   libraries = curses_libs) )
+
+        # If the curses module is enabled, check for the panel module
+        if (os.path.exists('Modules/_curses_panel.c') and
+            module_enabled(exts, '_curses') and
+            self.compiler.find_library_file(lib_dirs, 'panel')):
+            exts.append( Extension('_curses_panel', ['_curses_panel.c'],
+                                   libraries = ['panel'] + curses_libs) )
+
+
+
+        # Lee Busby's SIGFPE modules.
+        # The library to link fpectl with is platform specific.
+        # Choose *one* of the options below for fpectl:
+
+        if platform == 'irix5':
+            # For SGI IRIX (tested on 5.3):
+            exts.append( Extension('fpectl', ['fpectlmodule.c'],
+                                   libraries=['fpe']) )
+        elif 0: # XXX how to detect SunPro?
+            # For Solaris with SunPro compiler (tested on Solaris 2.5 with SunPro C 4.2):
+            # (Without the compiler you don't have -lsunmath.)
+            #fpectl fpectlmodule.c -R/opt/SUNWspro/lib -lsunmath -lm
+            pass
+        else:
+            # For other systems: see instructions in fpectlmodule.c.
+            #fpectl fpectlmodule.c ...
+            exts.append( Extension('fpectl', ['fpectlmodule.c']) )
+
+
+        # Andrew Kuchling's zlib module.
+        # This require zlib 1.1.3 (or later).
+        # See http://www.gzip.org/zlib/
+        if (self.compiler.find_library_file(lib_dirs, 'z')):
+            exts.append( Extension('zlib', ['zlibmodule.c'],
+                                   libraries = ['z']) )
+
+        # Interface to the Expat XML parser
+        #
+        # Expat is written by James Clark and must be downloaded separately
+        # (see below).  The pyexpat module was written by Paul Prescod after a
+        # prototype by Jack Jansen.
+        #
+        # The Expat dist includes Windows .lib and .dll files.  Home page is
+        # at http://www.jclark.com/xml/expat.html, the current production
+        # release is always ftp://ftp.jclark.com/pub/xml/expat.zip.
+        #
+        # EXPAT_DIR, below, should point to the expat/ directory created by
+        # unpacking the Expat source distribution.
+        #
+        # Note: the expat build process doesn't yet build a libexpat.a; you
+        # can do this manually while we try convince the author to add it.  To
+        # do so, cd to EXPAT_DIR, run "make" if you have not done so, then
+        # run:
+        #
+        #    ar cr libexpat.a xmltok/*.o xmlparse/*.o
+        #
+        expat_defs = []
+        expat_incs = find_file('expat.h', inc_dirs, [])
+        if expat_incs is not None:
+            # expat.h was found
+            expat_defs = [('HAVE_EXPAT_H', 1)]
+        else:
+            expat_incs = find_file('xmlparse.h', inc_dirs, [])
+
+        if (expat_incs is not None and
+            self.compiler.find_library_file(lib_dirs, 'expat')):
+            exts.append( Extension('pyexpat', ['pyexpat.c'],
+                                   define_macros = expat_defs,
+                                   libraries = ['expat']) )
+
+        # Platform-specific libraries
+        if platform == 'linux2':
+            # Linux-specific modules
+            exts.append( Extension('linuxaudiodev', ['linuxaudiodev.c']) )
+
+        if platform == 'sunos5':
+            # SunOS specific modules
+            exts.append( Extension('sunaudiodev', ['sunaudiodev.c']) )
+
+        self.extensions.extend(exts)
+
+        # Call the method for detecting whether _tkinter can be compiled
+        self.detect_tkinter(inc_dirs, lib_dirs)
+
+
+    def detect_tkinter(self, inc_dirs, lib_dirs):
+        # The _tkinter module.
+
+        # Assume we haven't found any of the libraries or include files
+        tcllib = tklib = tcl_includes = tk_includes = None
+        for version in ['8.4', '8.3', '8.2', '8.1', '8.0']:
+            tklib = self.compiler.find_library_file(lib_dirs,
+                                                    'tk' + version )
+            tcllib = self.compiler.find_library_file(lib_dirs,
+                                                     'tcl' + version )
+            if tklib and tcllib:
+                # Exit the loop when we've found the Tcl/Tk libraries
+                break
+
+        # Now check for the header files
+        if tklib and tcllib:
+            # Check for the include files on Debian, where
+            # they're put in /usr/include/{tcl,tk}X.Y
+            debian_tcl_include = [ '/usr/include/tcl' + version ]
+            debian_tk_include =  [ '/usr/include/tk'  + version ] + debian_tcl_include
+            tcl_includes = find_file('tcl.h', inc_dirs, debian_tcl_include)
+            tk_includes = find_file('tk.h', inc_dirs, debian_tk_include)
+
+        if (tcllib is None or tklib is None and
+            tcl_includes is None or tk_includes is None):
+            # Something's missing, so give up
+            return
+
+        # OK... everything seems to be present for Tcl/Tk.
+
+        include_dirs = [] ; libs = [] ; defs = [] ; added_lib_dirs = []
+        for dir in tcl_includes + tk_includes:
+            if dir not in include_dirs:
+                include_dirs.append(dir)
+
+        # Check for various platform-specific directories
+        platform = self.get_platform()
+        if platform == 'sunos5':
+            include_dirs.append('/usr/openwin/include')
+            added_lib_dirs.append('/usr/openwin/lib')
+        elif os.path.exists('/usr/X11R6/include'):
+            include_dirs.append('/usr/X11R6/include')
+            added_lib_dirs.append('/usr/X11R6/lib')
+        elif os.path.exists('/usr/X11R5/include'):
+            include_dirs.append('/usr/X11R5/include')
+            added_lib_dirs.append('/usr/X11R5/lib')
+        else:
+            # Assume default location for X11
+            include_dirs.append('/usr/X11/include')
+            added_lib_dirs.append('/usr/X11/lib')
+
+        # Check for BLT extension
+        if self.compiler.find_library_file(lib_dirs + added_lib_dirs, 'BLT8.0'):
+            defs.append( ('WITH_BLT', 1) )
+            libs.append('BLT8.0')
+
+        # Add the Tcl/Tk libraries
+        libs.append('tk'+version)
+        libs.append('tcl'+version)
+
+        if platform in ['aix3', 'aix4']:
+            libs.append('ld')
+
+        # Finally, link with the X11 libraries
+        libs.append('X11')
+
+        ext = Extension('_tkinter', ['_tkinter.c', 'tkappinit.c'],
+                        define_macros=[('WITH_APPINIT', 1)] + defs,
+                        include_dirs = include_dirs,
+                        libraries = libs,
+                        library_dirs = added_lib_dirs,
+                        )
+        self.extensions.append(ext)
+
+        # XXX handle these, but how to detect?
+        # *** Uncomment and edit for PIL (TkImaging) extension only:
+        #       -DWITH_PIL -I../Extensions/Imaging/libImaging  tkImaging.c \
+        # *** Uncomment and edit for TOGL extension only:
+        #       -DWITH_TOGL togl.c \
+        # *** Uncomment these for TOGL extension only:
+        #       -lGL -lGLU -lXext -lXmu \
+
+def main():
+    setup(name = 'Python standard library',
+          version = '%d.%d' % sys.version_info[:2],
+          cmdclass = {'build_ext':PyBuildExt},
+          # The struct module is defined here, because build_ext won't be
+          # called unless there's at least one extension module defined.
+          ext_modules=[Extension('struct', ['structmodule.c'])],
+
+          # Scripts to install
+          scripts = ['Tools/scripts/pydoc']
+        )
+
+# --install-platlib
+if __name__ == '__main__':
+    sysconfig.set_python_build()
+    main()

Added: vendor/Python/current/Misc/HISTORY
===================================================================
--- vendor/Python/current/Misc/HISTORY	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Misc/HISTORY	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,15303 @@
+Python History
+--------------
+
+This file contains the release messages for previous Python releases.
+As you read on you go back to the dark ages of Python's history.
+
+
+======================================================================
+
+
+What's New in Python 2.4 final?
+===============================
+
+*Release date: 30-NOV-2004*
+
+Core and builtins
+-----------------
+
+- Bug 875692: Improve signal handling, especially when using threads, by
+  forcing an early re-execution of PyEval_EvalFrame() "periodic" code when
+  things_to_do is not cleared by Py_MakePendingCalls().
+
+
+What's New in Python 2.4 (release candidate 1)
+==============================================
+
+*Release date: 18-NOV-2004*
+
+Core and builtins
+-----------------
+
+- Bug 1061968:  Fixes in 2.4a3 to address thread bug 1010677 reintroduced
+  the years-old thread shutdown race bug 225673.  Numeric history lesson
+  aside, all bugs in all three reports are fixed now.
+
+
+Library
+-------
+
+- Bug 1052242: If exceptions are raised by an atexit handler function an
+  attempt is made to execute the remaining handlers.  The last exception
+  raised is re-raised.
+
+- ``doctest``'s new support for adding ``pdb.set_trace()`` calls to
+  doctests was broken in a dramatic but shallow way.  Fixed.
+
+- Bug 1065388:  ``calendar``'s ``day_name``, ``day_abbr``, ``month_name``,
+  and ``month_abbr`` attributes emulate sequences of locale-correct
+  spellings of month and day names.  Because the locale can change at
+  any time, the correct spelling is recomputed whenever one of these is
+  indexed.  In the worst case, the index may be a slice object, so these
+  recomputed every day or month name each time they were indexed.  This is
+  much slower than necessary in the usual case, when the index is just an
+  integer.  In that case, only the single spelling needed is recomputed
+  now; and, when the index is a slice object, only the spellings needed
+  by the slice are recomputed now.
+
+- Patch 1061679: Added ``__all__`` to pickletools.py.
+
+Build
+-----
+
+- Bug 1034277 / Patch 1035255: Remove compilation of core against CoreServices
+  and CoreFoundation on OS X.  Involved removing PyMac_GetAppletScriptFile()
+  which has no known users.  Thanks Bob Ippolito.
+
+C API
+-----
+
+- The PyRange_New() function is deprecated.
+
+
+What's New in Python 2.4 beta 2?
+================================
+
+*Release date: 03-NOV-2004*
+
+License
+-------
+
+The Python Software Foundation changed the license under which Python
+is released, to remove Python version numbers.  There were no other
+changes to the license.  So, for example, wherever the license for
+Python 2.3 said "Python 2.3", the new license says "Python".  The
+intent is to make it possible to refer to the PSF license in a more
+durable way.  For example, some people say they're confused by that
+the Open Source Initiative's entry for the Python Software Foundation
+License::
+
+      http://www.opensource.org/licenses/PythonSoftFoundation.php
+
+says "Python 2.1.1" all over it, wondering whether it applies only
+to Python 2.1.1.
+
+The official name of the new license is the Python Software Foundation
+License Version 2.
+
+Core and builtins
+-----------------
+
+- Bug #1055820 Cyclic garbage collection was not protecting against that
+  calling a live weakref to a piece of cyclic trash could resurrect an
+  insane mutation of the trash if any Python code ran during gc (via
+  running a dead object's __del__ method, running another callback on a
+  weakref to a dead object, or via any Python code run in any other thread
+  that managed to obtain the GIL while a __del__ or callback was running
+  in the thread doing gc).  The most likely symptom was "impossible"
+  ``AttributeError`` exceptions, appearing seemingly at random, on weakly
+  referenced objects.  The cure was to clear all weakrefs to unreachable
+  objects before allowing any callbacks to run.
+
+- Bug #1054139 _PyString_Resize() now invalidates its cached hash value.
+
+Extension Modules
+-----------------
+
+- Bug #1048870:  the compiler now generates distinct code objects for
+  functions with identical bodies.  This was producing confusing
+  traceback messages which pointed to the function where the code
+  object was first defined rather than the function being executed.
+
+Library
+-------
+
+- Patch #1056967 changes the semantics of Template.safe_substitute() so that
+  no ValueError is raised on an 'invalid' match group.  Now the delimiter is
+  returned.
+
+- Bug #1052503 pdb.runcall() was not passing along keyword arguments.
+
+- Bug #902037: XML.sax.saxutils.prepare_input_source() now combines relative
+  paths with a base path before checking os.path.isfile().
+
+- The whichdb module can now be run from the command line.
+
+- Bug #1045381: time.strptime() can now infer the date using %U or %W (week of
+  the year) when the day of the week and year are also specified.
+
+- Bug #1048816: fix bug in Ctrl-K at start of line in curses.textpad.Textbox
+
+- Bug #1017553: fix bug in tarfile.filemode()
+
+- Patch #737473: fix bug that old source code is shown in tracebacks even if
+  the source code is updated and reloaded.
+
+Build
+-----
+
+- Patch #1044395: --enable-shared is allowed in FreeBSD also.
+
+What's New in Python 2.4 beta 1?
+================================
+
+*Release date: 15-OCT-2004*
+
+Core and builtins
+-----------------
+
+- Patch #975056: Restartable signals were not correctly disabled on
+  BSD systems. Consistently use PyOS_setsig() instead of signal().
+
+- The internal portable implementation of thread-local storage (TLS), used
+  by the ``PyGILState_Ensure()``/``PyGILState_Release()`` API, was not
+  thread-correct.  This could lead to a variety of problems, up to and
+  including segfaults.  See bug 1041645 for an example.
+
+- Added a command line option, -m module, which searches sys.path for the
+  module and then runs it.  (Contributed by Nick Coghlan.)
+
+- The bytecode optimizer now folds tuples of constants into a single
+  constant.
+
+- SF bug #513866:  Float/long comparison anomaly.  Prior to 2.4b1, when
+  an integer was compared to a float, the integer was coerced to a float.
+  That could yield spurious overflow errors (if the integer was very
+  large), and to anomalies such as
+  ``long(1e200)+1 == 1e200 == long(1e200)-1``.  Coercion to float is no
+  longer performed, and cases like ``long(1e200)-1 < 1e200``,
+  ``long(1e200)+1 > 1e200`` and ``(1 << 20000) > 1e200`` are computed
+  correctly now.
+
+Extension modules
+-----------------
+
+- ``collections.deque`` objects didn't play quite right with garbage
+  collection, which could lead to a segfault in a release build, or
+  an assert failure in a debug build.  Also, added overflow checks,
+  better detection of mutation during iteration, and shielded deque
+  comparisons from unusual subclass overrides of the __iter__() method.
+
+Library
+-------
+
+- Patch 1046644: distutils build_ext grew two new options - --swig for
+  specifying the swig executable to use, and --swig-opts to specify
+  options to pass to swig. --swig-opts="-c++" is the new way to spell
+  --swig-cpp.
+
+- Patch 983206: distutils now obeys environment variable LDSHARED, if
+  it is set.
+
+- Added Peter Astrand's subprocess.py module.  See PEP 324 for details.
+
+- time.strptime() now properly escapes timezones and all other locale-specific
+  strings for regex-specific symbols.  Was breaking under Japanese Windows when
+  the timezone was specified as "Tokyo (standard time)".
+  Closes bug #1039270.
+
+- Updates for the email package:
+
+  + email.Utils.formatdate() grew a 'usegmt' argument for HTTP support.
+  + All deprecated APIs that in email 2.x issued warnings have been removed:
+    _encoder argument to the MIMEText constructor, Message.add_payload(),
+    Utils.dump_address_pair(), Utils.decode(), Utils.encode()
+  + New deprecations: Generator.__call__(), Message.get_type(),
+    Message.get_main_type(), Message.get_subtype(), the 'strict' argument to
+    the Parser constructor.  These will be removed in email 3.1.
+  + Support for Python earlier than 2.3 has been removed (see PEP 291).
+  + All defect classes have been renamed to end in 'Defect'.
+  + Some FeedParser fixes; also a MultipartInvariantViolationDefect will be
+    added to messages that claim to be multipart but really aren't.
+  + Updates to documentation.
+
+- re's findall() and finditer() functions now take an optional flags argument
+  just like the compile(), search(), and match() functions.  Also, documented
+  the previously existing start and stop parameters for the findall() and
+  finditer() methods of regular expression objects.
+
+- rfc822 Messages now support iterating over the headers.
+
+- The (undocumented) tarfile.Tarfile.membernames has been removed;
+  applications should use the getmember function.
+
+- httplib now offers symbolic constants for the HTTP status codes.
+
+- SF bug #1028306:  Trying to compare a ``datetime.date`` to a
+  ``datetime.datetime`` mistakenly compared only the year, month and day.
+  Now it acts like a mixed-type comparison:  ``False`` for ``==``,
+  ``True`` for ``!=``, and raises ``TypeError`` for other comparison
+  operators.  Because datetime is a subclass of date, comparing only the
+  base class (date) members can still be done, if that's desired, by
+  forcing using of the approprate date method; e.g.,
+  ``a_date.__eq__(a_datetime)`` is true if and only if the year, month
+  and day members of ``a_date`` and ``a_datetime`` are equal.
+
+- bdist_rpm now supports command line options --force-arch,
+  {pre,post}-install,  {pre,post}-uninstall, and
+  {prep,build,install,clean,verify}-script.
+
+- SF patch #998993: The UTF-8 and the UTF-16 stateful decoders now support
+  decoding incomplete input (when the input stream is temporarily exhausted).
+  ``codecs.StreamReader`` now implements buffering, which enables proper
+  readline support for the UTF-16 decoders. ``codecs.StreamReader.read()``
+  has a new argument ``chars`` which specifies the number of characters to
+  return. ``codecs.StreamReader.readline()`` and
+  ``codecs.StreamReader.readlines()`` have a new argument ``keepends``.
+  Trailing "\n"s will be stripped from the lines if ``keepends`` is false.
+
+- The documentation for doctest is greatly expanded, and now covers all
+  the new public features (of which there are many).
+
+- ``doctest.master`` was put back in, and ``doctest.testmod()`` once again
+  updates it.  This isn't good, because every ``testmod()`` call
+  contributes to bloating the "hidden" state of ``doctest.master``, but
+  some old code apparently relies on it.  For now, all we can do is
+  encourage people to stitch doctests together via doctest's unittest
+  integration features instead.
+
+- httplib now handles ipv6 address/port pairs.
+
+- SF bug #1017864: ConfigParser now correctly handles default keys,
+  processing them with ``ConfigParser.optionxform`` when supplied,
+  consistent with the handling of config file entries and runtime-set
+  options.
+
+- SF bug #997050: Document, test, & check for non-string values in
+  ConfigParser.  Moved the new string-only restriction added in
+  rev. 1.65 to the SafeConfigParser class, leaving existing
+  ConfigParser & RawConfigParser behavior alone, and documented the
+  conditions under which non-string values work.
+
+Build
+-----
+
+- Building on darwin now includes /opt/local/include and /opt/local/lib for
+  building extension modules.  This is so as to include software installed as
+  a DarwinPorts port <http://darwinports.opendarwin.org/>
+
+- pyport.h now defines a Py_IS_NAN macro.  It works as-is when the
+  platform C computes true for ``x != x`` if and only if X is a NaN.
+  Other platforms can override the default definition with a platform-
+  specific spelling in that platform's pyconfig.h.  You can also override
+  pyport.h's default Py_IS_INFINITY definition now.
+
+C API
+-----
+
+- SF patch 1044089:  New function ``PyEval_ThreadsInitialized()`` returns
+  non-zero if PyEval_InitThreads() has been called.
+
+- The undocumented and unused extern int ``_PyThread_Started`` was removed.
+
+- The C API calls ``PyInterpreterState_New()`` and ``PyThreadState_New()``
+  are two of the very few advertised as being safe to call without holding
+  the GIL.  However, this wasn't true in a debug build, as bug 1041645
+  demonstrated.  In a debug build, Python redirects the ``PyMem`` family
+  of calls to Python's small-object allocator, to get the benefit of
+  its extra debugging capabilities.  But Python's small-object allocator
+  isn't threadsafe, relying on the GIL to avoid the expense of doing its
+  own locking.  ``PyInterpreterState_New()`` and ``PyThreadState_New()``
+  call the platform ``malloc()`` directly now, regardless of build type.
+
+- PyLong_AsUnsignedLong[Mask] now support int objects as well.
+
+- SF patch #998993: ``PyUnicode_DecodeUTF8Stateful`` and
+  ``PyUnicode_DecodeUTF16Stateful`` have been added, which implement stateful
+  decoding.
+
+Tests
+-----
+
+- test__locale ported to unittest
+
+Mac
+---
+
+- ``plistlib`` now supports non-dict root objects.  There is also a new
+  interface for reading and writing plist files: ``readPlist(pathOrFile)``
+  and ``writePlist(rootObject, pathOrFile)``
+
+Tools/Demos
+-----------
+
+- The text file comparison scripts ``ndiff.py`` and ``diff.py`` now
+  read the input files in universal-newline mode.  This spares them
+  from consuming a great deal of time to deduce the useless result that,
+  e.g., a file with Windows line ends and a file with Linux line ends
+  have no lines in common.
+
+
+What's New in Python 2.4 alpha 3?
+=================================
+
+*Release date: 02-SEP-2004*
+
+Core and builtins
+-----------------
+
+- SF patch #1007189: ``from ... import ...`` statements now allow the name
+  list to be surrounded by parentheses.
+
+- Some speedups for long arithmetic, thanks to Trevor Perrin.  Gradeschool
+  multiplication was sped a little by optimizing the C code.  Gradeschool
+  squaring was sped by about a factor of 2, by exploiting that about half
+  the digit products are duplicates in a square.  Because exponentiation
+  uses squaring often, this also speeds long power.  For example, the time
+  to compute 17**1000000 dropped from about 14 seconds to 9 on my box due
+  to this much.  The cutoff for Karatsuba multiplication was raised,
+  since gradeschool multiplication got quicker, and the cutoff was
+  aggressively small regardless.  The exponentiation algorithm was switched
+  from right-to-left to left-to-right, which is more efficient for small
+  bases.  In addition, if the exponent is large, the algorithm now does
+  5 bits (instead of 1 bit) at a time.  That cut the time to compute
+  17**1000000 on my box in half again, down to about 4.5 seconds.
+
+- OverflowWarning is no longer generated.  PEP 237 scheduled this to
+  occur in Python 2.3, but since OverflowWarning was disabled by default,
+  nobody realized it was still being generated.  On the chance that user
+  code is still using them, the Python builtin OverflowWarning, and
+  corresponding C API PyExc_OverflowWarning, will exist until Python 2.5.
+
+- Py_InitializeEx has been added.
+
+- Fix the order of application of decorators.  The proper order is bottom-up;
+  the first decorator listed is the last one called.
+
+- SF patch #1005778.  Fix a seg fault if the list size changed while
+  calling list.index().  This could happen if a rich comparison function
+  modified the list.
+
+- The ``func_name`` (a.k.a. ``__name__``) attribute of user-defined
+  functions is now writable.
+
+- code_new (a.k.a new.code()) now checks its arguments sufficiently
+  carefully that passing them on to PyCode_New() won't trigger calls
+  to Py_FatalError() or PyErr_BadInternalCall().  It is still the case
+  that the returned code object might be entirely insane.
+
+- Subclasses of string can no longer be interned.  The semantics of
+  interning were not clear here -- a subclass could be mutable, for
+  example -- and had bugs.  Explicitly interning a subclass of string
+  via intern() will raise a TypeError.  Internal operations that attempt
+  to intern a string subclass will have no effect.
+
+- Bug 1003935:  xrange() could report bogus OverflowErrors.  Documented
+  what xrange() intends, and repaired tests accordingly.
+
+Extension modules
+-----------------
+
+- difflib now supports HTML side-by-side diff.
+
+- os.urandom has been added for systems that support sources of random
+  data.
+
+- Patch 1012740:  truncate() on a writeable cStringIO now resets the
+  position to the end of the stream.  This is consistent with the original
+  StringIO module and avoids inadvertently resurrecting data that was
+  supposed to have been truncated away.
+
+- Added socket.socketpair().
+
+- Added CurrentByteIndex, CurrentColumnNumber, CurrentLineNumber
+  members to xml.parsers.expat.XMLParser object.
+
+- The mpz, rotor, and xreadlines modules, all deprecated in earlier
+  versions of Python, have now been removed.
+
+Library
+-------
+
+- Patch #934356: if a module defines __all__, believe that rather than using
+  heuristics for filtering out imported names.
+
+- Patch #941486: added os.path.lexists(), which returns True for broken
+  symlinks, unlike os.path.exists().
+
+- the random module now uses os.urandom() for seeding if it is available.
+  Added a new generator based on os.urandom().
+
+- difflib and diff.py can now generate HTML.
+
+- bdist_rpm now includes version and release in the BuildRoot, and
+  replaces - by ``_`` in version and release.
+
+- distutils build/build_scripts now has an -e option to specify the
+  path to the Python interpreter for installed scripts.
+
+- PEP 292 classes Template and SafeTemplate are added to the string module.
+
+- tarfile now generates GNU tar files by default.
+
+- HTTPResponse has now a getheaders method.
+
+- Patch #1006219: let inspect.getsource handle '@' decorators. Thanks Simon
+  Percivall.
+
+- logging.handlers.SMTPHandler.date_time has been removed;
+  the class now uses email.Utils.formatdate to generate the time stamp.
+
+- A new function tkFont.nametofont was added to return an existing
+  font. The Font class constructor now has an additional exists argument
+  which, if True, requests to return/configure an existing font, rather
+  than creating a new one.
+
+- Updated the decimal package's min() and max() methods to match the
+  latest revision of the General Decimal Arithmetic Specification.
+  Quiet NaNs are ignored and equal values are sorted based on sign
+  and exponent.
+
+- The decimal package's Context.copy() method now returns deep copies.
+
+- Deprecated sys.exitfunc in favor of the atexit module.  The sys.exitfunc
+  attribute will be kept around for backwards compatibility and atexit
+  will just become the one preferred way to do it.
+
+- patch #675551: Add get_history_item and replace_history_item functions
+  to the readline module.
+
+- bug #989672: pdb.doc and the help messages for the help_d and help_u methods
+  of the pdb.Pdb class gives have been corrected. d(own) goes to a newer
+  frame, u(p) to an older frame, not the other way around.
+
+- bug #990669: os.path.realpath() will resolve symlinks before normalizing the
+  path, as normalizing the path may alter the meaning of the path if it
+  contains symlinks.
+
+- bug #851123: shutil.copyfile will raise an exception when trying to copy a
+  file onto a link to itself. Thanks Gregory Ball.
+
+- bug #570300: Fix inspect to resolve file locations using os.path.realpath()
+  so as to properly list all functions in a module when the module itself is
+  reached through a symlink.  Thanks Johannes Gijsbers.
+
+- doctest refactoring continued.  See the docs for details.  As part of
+  this effort, some old and little- (never?) used features are now
+  deprecated:  the Tester class, the module is_private() function, and the
+  isprivate argument to testmod().  The Tester class supplied a feeble
+  "by hand" way to combine multiple doctests, if you knew exactly what
+  you were doing.  The newer doctest features for unittest integration
+  already did a better job of that, are stronger now than ever, and the
+  new DocTestRunner class is a saner foundation if you want to do it by
+  hand.  The "private name" filtering gimmick was a mistake from the
+  start, and testmod() changed long ago to ignore it by default.  If
+  you want to filter out tests, the new DocTestFinder class can be used
+  to return a list of all doctests, and you can filter that list by
+  any computable criteria before passing it to a DocTestRunner instance.
+
+- Bug #891637, patch #1005466: fix inspect.getargs() crash on def foo((bar)).
+
+Tools/Demos
+-----------
+
+- IDLE's shortcut keys for windows are now case insensitive so that
+  Control-V works the same as Control-v.
+
+- pygettext.py: Generate POT-Creation-Date header in ISO format.
+
+Build
+-----
+
+- Backward incompatibility:  longintrepr.h now triggers a compile-time
+  error if SHIFT (the number of bits in a Python long "digit") isn't
+  divisible by 5.  This new requirement allows simple code for the new
+  5-bits-at-a-time long_pow() implementation.  If necessary, the
+  restriction could be removed (by complicating long_pow(), or by
+  falling back to the 1-bit-at-a-time algorithm), but there are no
+  plans to do so.
+
+- bug #991962: When building with --disable-toolbox-glue on Darwin no
+  attempt to build Mac-specific modules occurs.
+
+- The --with-tsc flag to configure to enable VM profiling with the
+  processor's timestamp counter now works on PPC platforms.
+
+- patch #1006629: Define _XOPEN_SOURCE to 500 on Solaris 8/9 to match
+  GCC's definition and avoid redefinition warnings.
+
+- Detect pthreads support (provided by gnu pth pthread emulation) on
+  GNU/k*BSD systems.
+
+- bug #1005737, #1007249: Fixed several build problems and warnings
+  found on old/legacy C compilers of HP-UX, IRIX and Tru64.
+
+C API
+-----
+
+..
+
+Documentation
+-------------
+
+- patch #1005936, bug #1009373: fix index entries which contain
+  an underscore when viewed with Acrobat.
+
+- bug #990669: os.path.normpath may alter the meaning of a path if
+  it contains symbolic links. This has been documented in a comment
+  since 1992, but is now in the library reference as well.
+
+New platforms
+-------------
+
+- FreeBSD 6 is now supported.
+
+Tests
+-----
+
+..
+
+Windows
+-------
+
+- Boosted the stack reservation for python.exe and pythonw.exe from
+  the default 1MB to 2MB.  Stack frames under VC 7.1 for 2.4 are enough
+  bigger than under VC 6.0 for 2.3.4 that deeply recursive progams
+  within the default sys.getrecursionlimit() default value of 1000 were
+  able to suffer undetected C stack overflows.  The standard test program
+  test_compiler was one such program.  If a Python process on Windows
+  "just vanishes" without a trace, and without an error message of any
+  kind, but with an exit code of 128, undetected stack overflow may be
+  the problem.
+
+Mac
+---
+
+..
+
+
+What's New in Python 2.4 alpha 2?
+=================================
+
+*Release date: 05-AUG-2004*
+
+Core and builtins
+-----------------
+
+- Patch #980695:  Implements efficient string concatenation for statements
+  of the form s=s+t and s+=t.  This will vary across implementations.
+  Accordingly, the str.join() method is strongly preferred for performance
+  sensitive code.
+
+- PEP-0318, Function Decorators have been added to the language. These are
+  implemented using the Java-style @decorator syntax, like so::
+
+     @staticmethod
+     def foo(bar):
+
+  (The PEP needs to be updated to reflect the current state)
+
+- When importing a module M raises an exception, Python no longer leaves M
+  in sys.modules.  Before 2.4a2 it did, and a subsequent import of M would
+  succeed, picking up a module object from sys.modules reflecting as much
+  of the initialization of M as completed before the exception was raised.
+  Subsequent imports got no indication that M was in a partially-
+  initialized state, and the importers could get into arbitrarily bad
+  trouble as a result (the M they got was in an unintended state,
+  arbitrarily far removed from M's author's intent).  Now subsequent
+  imports of M will continue raising exceptions (but if, for example, the
+  source code for M is edited between import attempts, then perhaps later
+  attempts will succeed, or raise a different exception).
+
+  This can break existing code, but in such cases the code was probably
+  working before by accident.  In the Python source, the only case of
+  breakage discovered was in a test accidentally relying on a damaged
+  module remaining in sys.modules.  Cases are also known where tests
+  deliberately provoking import errors remove damaged modules from
+  sys.modules themselves, and such tests will break now if they do an
+  unconditional del sys.modules[M].
+
+- u'%s' % obj will now try obj.__unicode__() first and fallback to
+  obj.__str__() if no __unicode__ method can be found.
+
+- Patch #550732: Add PyArg_VaParseTupleAndKeywords().  Analogous to
+  PyArg_VaParse().  Both are now documented.  Thanks Greg Chapman.
+
+- Allow string and unicode return types from .encode()/.decode()
+  methods on string and unicode objects.  Added unicode.decode()
+  which was missing for no apparent reason.
+
+- An attempt to fix the mess that is Python's behaviour with
+  signal handlers and threads, complicated by readline's behaviour.
+  It's quite possible that there are still bugs here.
+
+- Added C macros Py_CLEAR and Py_VISIT to ease the implementation of
+  types that support garbage collection.
+
+- Compiler now treats None as a constant.
+
+- The type of values returned by __int__, __float__, __long__,
+  __oct__, and __hex__ are now checked.  Returning an invalid type
+  will cause a TypeError to be raised.  This matches the behavior of
+  Jython.
+
+- Implemented bind_textdomain_codeset() in locale module.
+
+- Added a workaround for proper string operations in BSDs.  str.split
+  and str.is* methods can now work correctly with UTF-8 locales.
+
+- Bug #989185: unicode.iswide() and unicode.width() is dropped and
+  the East Asian Width support is moved to unicodedata extension
+  module.
+
+- Patch #941229: The source code encoding in interactive mode
+  now refers sys.stdin.encoding not just ISO-8859-1 anymore.  This
+  allows for non-latin-1 users to write unicode strings directly.
+
+Extension modules
+-----------------
+
+- cpickle now supports the same keyword arguments as pickle.
+
+Library
+-------
+
+- Added new codecs and aliases for ISO_8859-11, ISO_8859-16 and
+  TIS-620
+
+- Thanks to Edward Loper, doctest has been massively refactored, and
+  many new features were added.  Full docs will appear later.  For now
+  the doctest module comments and new test cases give good coverage.
+  The refactoring provides many hook points for customizing behavior
+  (such as how to report errors, and how to compare expected to actual
+  output).  New features include a <BLANKLINE> marker for expected
+  output containing blank lines, options to produce unified or context
+  diffs when actual output doesn't match expectations, an option to
+  normalize whitespace before comparing, and an option to use an
+  ellipsis to signify "don't care" regions of output.
+
+- Tkinter now supports the wish -sync and -use options.
+
+- The following methods in time support passing of None: ctime(), gmtime(),
+  and localtime().  If None is provided, the current time is used (the
+  same as when the argument is omitted).
+  [SF bug 658254, patch 663482]
+
+- nntplib does now allow to ignore a .netrc file.
+
+- urllib2 now recognizes Basic authentication even if other authentication
+  schemes are offered.
+
+- Bug #1001053.  wave.open() now accepts unicode filenames.
+
+- gzip.GzipFile has a new fileno() method, to retrieve the handle of the
+  underlying file object (provided it has a fileno() method).  This is
+  needed if you want to use os.fsync() on a GzipFile.
+
+- imaplib has two new methods: deleteacl and myrights.
+
+- nntplib has two new methods: description and descriptions. They
+  use a more RFC-compliant way of getting a newsgroup description.
+
+- Bug #993394.  Fix a possible red herring of KeyError in 'threading' being
+  raised during interpreter shutdown from a registered function with atexit
+  when dummy_threading is being used.
+
+- Bug #857297/Patch #916874.  Fix an error when extracting a hard link
+  from a tarfile.
+
+- Patch #846659.  Fix an error in tarfile.py when using
+  GNU longname/longlink creation.
+
+- The obsolete FCNTL.py has been deleted.  The builtin fcntl module
+  has been available (on platforms that support fcntl) since Python
+  1.5a3, and all FCNTL.py did is export fcntl's names, after generating
+  a deprecation warning telling you to use fcntl directly.
+
+- Several new unicode codecs are added: big5hkscs, euc_jis_2004,
+  iso2022_jp_2004, shift_jis_2004.
+
+- Bug #788520.  Queue.{get, get_nowait, put, put_nowait} have new
+  implementations, exploiting Conditions (which didn't exist at the time
+  Queue was introduced).  A minor semantic change is that the Full and
+  Empty exceptions raised by non-blocking calls now occur only if the
+  queue truly was full or empty at the instant the queue was checked (of
+  course the Queue may no longer be full or empty by the time a calling
+  thread sees those exceptions, though).  Before, the exceptions could
+  also be raised if it was "merely inconvenient" for the implementation
+  to determine the true state of the Queue (because the Queue was locked
+  by some other method in progress).
+
+- Bugs #979794 and #980117: difflib.get_grouped_opcodes() now handles the
+  case of comparing two empty lists.  This affected both context_diff() and
+  unified_diff(),
+
+- Bug #980938: smtplib now prints debug output to sys.stderr.
+
+- Bug #930024: posixpath.realpath() now handles infinite loops in symlinks by
+  returning the last point in the path that was not part of any loop.  Thanks
+  AM Kuchling.
+
+- Bug #980327: ntpath not handles compressing erroneous slashes between the
+  drive letter and the rest of the path.  Also clearly handles UNC addresses now
+  as well.  Thanks Paul Moore.
+
+- bug #679953: zipfile.py should now work for files over 2 GB.  The packed data
+  for file sizes (compressed and uncompressed) was being stored as signed
+  instead of unsigned.
+
+- decimal.py now only uses signals in the IBM spec.  The other conditions are
+  no longer part of the public API.
+
+- codecs module now has two new generic APIs: encode() and decode()
+  which don't restrict the return types (unlike the unicode and
+  string methods of the same name).
+
+- Non-blocking SSL sockets work again; they were broken in Python 2.3.
+  SF patch 945642.
+
+- doctest unittest integration improvements:
+
+  o Improved the unitest test output for doctest-based unit tests
+
+  o Can now pass setUp and tearDown functions when creating
+    DocTestSuites.
+
+- The threading module has a new class, local, for creating objects
+  that provide thread-local data.
+
+- Bug #990307: when keep_empty_values is True, cgi.parse_qsl()
+  no longer returns spurious empty fields.
+
+- Implemented bind_textdomain_codeset() in gettext module.
+
+- Introduced in gettext module the l*gettext() family of functions,
+  which return translation strings encoded in the preferred encoding,
+  as informed by locale module's getpreferredencoding().
+
+- optparse module (and tests) upgraded to Optik 1.5a1.  Changes:
+
+  - Add expansion of default values in help text: the string
+    "%default" in an option's help string is expanded to str() of
+    that option's default value, or "none" if no default value.
+
+  - Bug #955889: option default values that happen to be strings are
+    now processed in the same way as values from the command line; this
+    allows generation of nicer help when using custom types.  Can
+    be disabled with parser.set_process_default_values(False).
+
+  - Bug #960515: don't crash when generating help for callback
+    options that specify 'type', but not 'dest' or 'metavar'.
+
+  - Feature #815264: change the default help format for short options
+    that take an argument from e.g. "-oARG" to "-o ARG"; add
+    set_short_opt_delimiter() and set_long_opt_delimiter() methods to
+    HelpFormatter to allow (slight) customization of the formatting.
+
+  - Patch #736940: internationalize Optik: all built-in user-
+    targeted literal strings are passed through gettext.gettext().  (If
+    you want translations (.po files), they're not included with Python
+    -- you'll find them in the Optik source distribution from
+    http://optik.sourceforge.net/ .)
+
+  - Bug #878453: respect $COLUMNS environment variable for
+    wrapping help output.
+
+  - Feature #988122: expand "%prog" in the 'description' passed
+    to OptionParser, just like in the 'usage' and 'version' strings.
+    (This is *not* done in the 'description' passed to OptionGroup.)
+
+C API
+-----
+
+- PyImport_ExecCodeModule() and PyImport_ExecCodeModuleEx():  if an
+  error occurs while loading the module, these now delete the module's
+  entry from sys.modules.  All ways of loading modules eventually call
+  one of these, so this is an error-case change in semantics for all
+  ways of loading modules.  In rare cases, a module loader may wish
+  to keep a module object in sys.modules despite that the module's
+  code cannot be executed.  In such cases, the module loader must
+  arrange to reinsert the name and module object in sys.modules.
+  PyImport_ReloadModule() has been changed to reinsert the original
+  module object into sys.modules if the module reload fails, so that
+  its visible semantics have not changed.
+
+- A large pile of datetime field-extraction macros is now documented,
+  thanks to Anthony Tuininga (patch #986010).
+
+Documentation
+-------------
+
+- Improved the tutorial on creating types in C.
+
+  - point out the importance of reassigning data members before
+    assigning their values
+
+  - correct my misconception about return values from visitprocs. Sigh.
+
+  - mention the labor saving Py_VISIT and Py_CLEAR macros.
+
+- Major rewrite of the math module docs, to address common confusions.
+
+Tests
+-----
+
+- The test data files for the decimal test suite are now installed on
+  platforms that use the Makefile.
+
+- SF patch 995225:  The test file testtar.tar accidentally contained
+  CVS keywords (like $Id: HISTORY 43159 2006-03-20 06:30:41Z anthony.baxter $), which could cause spurious failures in
+  test_tarfile.py depending on how the test file was checked out.
+
+
+What's New in Python 2.4 alpha 1?
+=================================
+
+*Release date: 08-JUL-2004*
+
+Core and builtins
+-----------------
+
+- weakref.ref is now the type object also known as
+  weakref.ReferenceType; it can be subclassed like any other new-style
+  class.  There's less per-entry overhead in WeakValueDictionary
+  objects now (one object instead of three).
+
+- Bug #951851: Python crashed when reading import table of certain
+  Windows DLLs.
+
+- Bug #215126.  The locals argument to eval(), execfile(), and exec now
+  accept any mapping type.
+
+- marshal now shares interned strings. This change introduces
+  a new .pyc magic.
+
+- Bug #966623. classes created with type() in an exec(, {}) don't
+  have a __module__, but code in typeobject assumed it would always
+  be there.
+
+- Python no longer relies on the LC_NUMERIC locale setting to be
+  the "C" locale; as a result, it no longer tries to prevent changing
+  the LC_NUMERIC category.
+
+- Bug #952807:  Unpickling pickled instances of subclasses of
+  datetime.date, datetime.datetime and datetime.time could yield insane
+  objects.  Thanks to Jiwon Seo for a fix.
+
+- Bug #845802: Python crashes when __init__.py is a directory.
+
+- Unicode objects received two new methods: iswide() and width().
+  These query East Asian width information, as specified in Unicode
+  TR11.
+
+- Improved the tuple hashing algorithm to give fewer collisions in
+  common cases.  Fixes bug  #942952.
+
+- Implemented generator expressions (PEP 289).  Coded by Jiwon Seo.
+
+- Enabled the profiling of C extension functions (and builtins) - check
+  new documentation and modified profile and bdb modules for more details
+
+- Set file.name to the object passed to open (instead of a new string)
+
+- Moved tracebackobject into traceback.h and renamed to PyTracebackObject
+
+- Optimized the byte coding for multiple assignments like "a,b=b,a" and
+  "a,b,c=1,2,3".  Improves their speed by 25% to 30%.
+
+- Limit the nested depth of a tuple for the second argument to isinstance()
+  and issubclass() to the recursion limit of the interpreter.
+  Fixes bug  #858016 .
+
+- Optimized dict iterators, creating separate types for each
+  and having them reveal their length.  Also optimized the
+  methods:  keys(), values(), and items().
+
+- Implemented a newcode opcode, LIST_APPEND, that simplifies
+  the generated bytecode for list comprehensions and further
+  improves their performance (about 35%).
+
+- Implemented rich comparisons for floats, which seems to make
+  comparisons involving NaNs somewhat less surprising when the
+  underlying C compiler actually implements C99 semantics.
+
+- Optimized list.extend() to save memory and no longer create
+  intermediate sequences.  Also, extend() now pre-allocates the
+  needed memory whenever the length of the iterable is known in
+  advance -- this halves the time to extend the list.
+
+- Optimized list resize operations to make fewer calls to the system
+  realloc().  Significantly speeds up list appends, list pops,
+  list comprehensions, and the list constructor (when the input iterable
+  length is not known).
+
+- Changed the internal list over-allocation scheme.  For larger lists,
+  overallocation ranged between 3% and 25%.  Now, it is a constant 12%.
+  For smaller lists (n<8), overallocation was upto eight elements.  Now,
+  the overallocation is no more than three elements -- this improves space
+  utilization for applications that have large numbers of small lists.
+
+- Most list bodies now get re-used rather than freed.  Speeds up list
+  instantiation and deletion by saving calls to malloc() and free().
+
+- The dict.update() method now accepts all the same argument forms
+  as the dict() constructor.  This now includes item lists and/or
+  keyword arguments.
+
+- Support for arbitrary objects supporting the read-only buffer
+  interface as the co_code field of code objects (something that was
+  only possible to create from C code) has been removed.
+
+- Made omitted callback and None equivalent for weakref.ref() and
+  weakref.proxy(); the None case wasn't handled correctly in all
+  cases.
+
+- Fixed problem where PyWeakref_NewRef() and PyWeakref_NewProxy()
+  assumed that initial existing entries in an object's weakref list
+  would not be removed while allocating a new weakref object.  Since
+  GC could be invoked at that time, however, that assumption was
+  invalid.  In a truly obscure case of GC being triggered during
+  creation for a new weakref object for an referent which already
+  has a weakref without a callback which is only referenced from
+  cyclic trash, a memory error can occur.  This consistently created a
+  segfault in a debug build, but provided less predictable behavior in
+  a release build.
+
+- input() builtin function now respects compiler flags such as
+  __future__ statements.  SF patch 876178.
+
+- Removed PendingDeprecationWarning from apply().  apply() remains
+  deprecated, but the nuisance warning will not be issued.
+
+- At Python shutdown time (Py_Finalize()), 2.3 called cyclic garbage
+  collection twice, both before and after tearing down modules.  The
+  call after tearing down modules has been disabled, because too much
+  of Python has been torn down then for __del__ methods and weakref
+  callbacks to execute sanely.  The most common symptom was a sequence
+  of uninformative messages on stderr when Python shut down, produced
+  by threads trying to raise exceptions, but unable to report the nature
+  of their problems because too much of the sys module had already been
+  destroyed.
+
+- Removed FutureWarnings related to hex/oct literals and conversions
+  and left shifts.  (Thanks to Kalle Svensson for SF patch 849227.)
+  This addresses most of the remaining semantic changes promised by
+  PEP 237, except for repr() of a long, which still shows the trailing
+  'L'.  The PEP appears to promise warnings for operations that
+  changed semantics compared to Python 2.3, but this is not
+  implemented; we've suffered through enough warnings related to
+  hex/oct literals and I think it's best to be silent now.
+
+- For str and unicode objects, the ljust(), center(), and rjust()
+  methods now accept an optional argument specifying a fill
+  character other than a space.
+
+- When method objects have an attribute that can be satisfied either
+  by the function object or by the method object, the function
+  object's attribute usually wins.  Christian Tismer pointed out that
+  that this is really a mistake, because this only happens for special
+  methods (like __reduce__) where the method object's version is
+  really more appropriate than the function's attribute.  So from now
+  on, all method attributes will have precedence over function
+  attributes with the same name.
+
+- Critical bugfix, for SF bug 839548:  if a weakref with a callback,
+  its callback, and its weakly referenced object, all became part of
+  cyclic garbage during a single run of garbage collection, the order
+  in which they were torn down was unpredictable.  It was possible for
+  the callback to see partially-torn-down objects, leading to immediate
+  segfaults, or, if the callback resurrected garbage objects, to
+  resurrect insane objects that caused segfaults (or other surprises)
+  later.  In one sense this wasn't surprising, because Python's cyclic gc
+  had no knowledge of Python's weakref objects.  It does now.  When
+  weakrefs with callbacks become part of cyclic garbage now, those
+  weakrefs are cleared first.  The callbacks don't trigger then,
+  preventing the problems.  If you need callbacks to trigger, then just
+  as when cyclic gc is not involved, you need to write your code so
+  that weakref objects outlive the objects they weakly reference.
+
+- Critical bugfix, for SF bug 840829:  if cyclic garbage collection
+  happened to occur during a weakref callback for a new-style class
+  instance, subtle memory corruption was the result (in a release build;
+  in a debug build, a segfault occurred reliably very soon after).
+  This has been repaired.
+
+- Compiler flags set in PYTHONSTARTUP are now active in __main__.
+
+- Added two builtin types, set() and frozenset().
+
+- Added a reversed() builtin function that returns a reverse iterator
+  over a sequence.
+
+- Added a sorted() builtin function that returns a new sorted list
+  from any iterable.
+
+- CObjects are now mutable (on the C level) through PyCObject_SetVoidPtr.
+
+- list.sort() now supports three keyword arguments:  cmp, key, and reverse.
+  The key argument can be a function of one argument that extracts a
+  comparison key from the original record:  mylist.sort(key=str.lower).
+  The reverse argument is a boolean value and if True will change the
+  sort order as if the comparison arguments were reversed.  In addition,
+  the documentation has been amended to provide a guarantee that all sorts
+  starting with Py2.3 are guaranteed to be stable (the relative order of
+  records with equal keys is unchanged).
+
+- Added test whether wchar_t is signed or not. A signed wchar_t is not
+  usable as internal unicode type base for Py_UNICODE since the
+  unicode implementation assumes an unsigned type.
+
+- Fixed a bug in the cache of length-one Unicode strings that could
+  lead to a seg fault.  The specific problem occurred when an earlier,
+  non-fatal error left an uninitialized Unicode object in the
+  freelist.
+
+- The % formatting operator now supports '%F' which is equivalent to
+  '%f'.  This has always been documented but never implemented.
+
+- complex(obj) could leak a little memory if obj wasn't a string or
+  number.
+
+- zip() with no arguments now returns an empty list instead of raising
+  a TypeError exception.
+
+- obj.__contains__() now returns True/False instead of 1/0.  SF patch
+  820195.
+
+- Python no longer tries to be smart about recursive comparisons.
+  When comparing containers with cyclic references to themselves it
+  will now just hit the recursion limit.  See SF patch 825639.
+
+- str and unicode builtin types now have an rsplit() method that is
+  same as split() except that it scans the string from the end
+  working towards the beginning.  See SF feature request 801847.
+
+- Fixed a bug in object.__reduce_ex__ when using protocol 2.  Failure
+  to clear the error when attempts to get the __getstate__ attribute
+  fail caused intermittent errors and odd behavior.
+
+- buffer objects based on other objects no longer cache a pointer to
+  the data and the data length.  Instead, the appropriate tp_as_buffer
+  method is called as necessary.
+
+- fixed: if a file is opened with an explicit buffer size >= 1, repeated
+  close() calls would attempt to free() the buffer already free()ed on
+  the first call.
+
+
+Extension modules
+-----------------
+
+- Added socket.getservbyport(), and make the second argument in
+  getservbyname() and getservbyport() optional.
+
+- time module code that deals with input POSIX timestamps will now raise
+  ValueError if more than a second is lost in precision when the
+  timestamp is cast to the platform C time_t type.  There's no chance
+  that the platform will do anything sensible with the result in such
+  cases.  This includes ctime(), localtime() and gmtime().  Assorted
+  fromtimestamp() and utcfromtimestamp() methods in the datetime module
+  were also protected.  Closes bugs #919012 and 975996.
+
+- fcntl.ioctl now warns if the mutate flag is not specified.
+
+- nt now properly allows to refer to UNC roots, e.g. in nt.stat().
+
+- the weakref module now supports additional objects:  array.array,
+  sre.pattern_objects, file objects, and sockets.
+
+- operator.isMappingType() and operator.isSequenceType() now give
+  fewer false positives.
+
+- socket.sslerror is now a subclass of socket.error .  Also added
+  socket.error to the socket module's C API.
+
+- Bug #920575: A problem where the _locale module segfaults on
+  nl_langinfo(ERA) caused by GNU libc's illegal NULL return is fixed.
+
+- array objects now support the copy module.  Also, their resizing
+  scheme has been updated to match that used for list objects.  This improves
+  the performance (speed and memory usage) of append() operations.
+  Also, array.array() and array.extend() now accept any iterable argument
+  for repeated appends without needing to create another temporary array.
+
+- cStringIO.writelines() now accepts any iterable argument and writes
+  the lines one at a time rather than joining them and writing once.
+  Made a parallel change to StringIO.writelines().  Saves memory and
+  makes suitable for use with generator expressions.
+
+- time.strftime() now checks that the values in its time tuple argument
+  are within the proper boundaries to prevent possible crashes from the
+  platform's C library implementation of strftime().  Can possibly
+  break code that uses values outside the range that didn't cause
+  problems previously (such as sitting day of year to 0).  Fixes bug
+  #897625.
+
+- The socket module now supports Bluetooth sockets, if the
+  system has <bluetooth/bluetooth.h>
+
+- Added a collections module containing a new datatype, deque(),
+  offering high-performance, thread-safe, memory friendly appends
+  and pops on either side of the deque.
+
+- Several modules now take advantage of collections.deque() for
+  improved performance:  Queue, mutex, shlex, threading, and pydoc.
+
+- The operator module has two new functions, attrgetter() and
+  itemgetter() which are useful for creating fast data extractor
+  functions for map(), list.sort(), itertools.groupby(), and
+  other functions that expect a function argument.
+
+- socket.SHUT_{RD,WR,RDWR} was added.
+
+- os.getsid was added.
+
+- The pwd module incorrectly advertised its struct type as
+  struct_pwent; this has been renamed to struct_passwd.  (The old name
+  is still supported for backwards compatibility.)
+
+- The xml.parsers.expat module now provides Expat 1.95.7.
+
+- socket.IPPROTO_IPV6 was added.
+
+- readline.clear_history was added.
+
+- select.select() now accepts sequences for its first three arguments.
+
+- cStringIO now supports the f.closed attribute.
+
+- The signal module now exposes SIGRTMIN and SIGRTMAX (if available).
+
+- curses module now supports use_default_colors().  [patch #739124]
+
+- Bug #811028: ncurses.h breakage on FreeBSD/MacOS X
+
+- Bug #814613: INET_ADDRSTRLEN fix needed for all compilers on SGI
+
+- Implemented non-recursive SRE matching scheme (#757624).
+
+- Implemented (?(id/name)yes|no) support in SRE (#572936).
+
+- random.seed() with no arguments or None uses time.time() as a default
+  seed.  Modified to match Py2.2 behavior and use fractional seconds so
+  that successive runs are more likely to produce different sequences.
+
+- random.Random has a new method, getrandbits(k), which returns an int
+  with k random bits.  This method is now an optional part of the API
+  for user defined generators.  Any generator that defines genrandbits()
+  can now use randrange() for ranges with a length >= 2**53.  Formerly,
+  randrange would return only even numbers for ranges that large (see
+  SF bug #812202).  Generators that do not define genrandbits() now
+  issue a warning when randrange() is called with a range that large.
+
+- itertools has a new function, groupby() for aggregating iterables
+  into groups sharing the same key (as determined by a key function).
+  It offers some of functionality of SQL's groupby keyword and of
+  the Unix uniq filter.
+
+- itertools now has a new tee() function which produces two independent
+  iterators from a single iterable.
+
+- itertools.izip() with no arguments now returns an empty iterator instead
+  of raising a TypeError exception.
+
+- Fixed #853061: allow BZ2Compressor.compress() to receive an empty string
+  as parameter.
+
+Library
+-------
+
+- Added a new module: cProfile, a C profiler with the same interface as the
+  profile module.  cProfile avoids some of the drawbacks of the hotshot
+  profiler and provides a bit more information than the other two profilers.
+  Based on "lsprof" (patch #1212837).
+
+- Bug #1266283: The new function "lexists" is now in os.path.__all__.
+
+- Bug #981530: Fix UnboundLocalError in shutil.rmtree().  This affects
+  the documented behavior: the function passed to the onerror()
+  handler can now also be os.listdir.
+
+- Bug #754449: threading.Thread objects no longer mask exceptions raised during
+  interpreter shutdown with another exception from attempting to handle the
+  original exception.
+
+- Added decimal.py per PEP 327.
+
+- Bug #981299: rsync is now a recognized protocol in urlparse that uses a
+  "netloc" portion of a URL.
+
+- Bug #919012: shutil.move() will not try to move a directory into itself.
+  Thanks Johannes Gijsbers.
+
+- Bug #934282: pydoc.stripid() is now case-insensitive.  Thanks Robin Becker.
+
+- Bug #823209:  cmath.log() now takes an optional base argument so that its
+  API matches math.log().
+
+- Bug #957381: distutils bdist_rpm no longer fails on recent RPM versions
+  that generate a -debuginfo.rpm
+
+- os.path.devnull has been added for all supported platforms.
+
+- Fixed #877165: distutils now picks the right C++ compiler command
+  on cygwin and mingw32.
+
+- urllib.urlopen().readline() now handles HTTP/0.9 correctly.
+
+- refactored site.py into functions.  Also wrote regression tests for the
+  module.
+
+- The distutils install command now supports the --home option and
+  installation scheme for all platforms.
+
+- asyncore.loop now has a repeat count parameter that defaults to
+  looping forever.
+
+- The distutils sdist command now ignores all .svn directories, in
+  addition to CVS and RCS directories.  .svn directories hold
+  administrative files for the Subversion source control system.
+
+- Added a new module: cookielib.  Automatic cookie handling for HTTP
+  clients.  Also, support for cookielib has been added to urllib2, so
+  urllib2.urlopen() can transparently handle cookies.
+
+- stringprep.py now uses built-in set() instead of sets.Set().
+
+- Bug #876278: Unbounded recursion in modulefinder
+
+- Bug #780300: Swap public and system ID in LexicalHandler.startDTD.
+  Applications relying on the wrong order need to be corrected.
+
+- Bug #926075: Fixed a bug that returns a wrong pattern object
+  for a string or unicode object in sre.compile() when a different
+  type pattern with the same value exists.
+
+- Added countcallers arg to trace.Trace class (--trackcalls command line arg
+  when run from the command prompt).
+
+- Fixed a caching bug in platform.platform() where the argument of 'terse' was
+  not taken into consideration when caching value.
+
+- Added two new command-line arguments for profile (output file and
+  default sort).
+
+- Added global runctx function to profile module
+
+- Add hlist missing entryconfigure and entrycget methods.
+
+- The ptcp154 codec was added for Kazakh character set support.
+
+- Support non-anonymous ftp URLs in urllib2.
+
+- The encodings package will now apply codec name aliases
+  first before starting to try the import of the codec module.
+  This simplifies overriding built-in codecs with external
+  packages, e.g. the included CJK codecs with the JapaneseCodecs
+  package, by adjusting the aliases dictionary in encodings.aliases
+  accordingly.
+
+- base64 now supports RFC 3548 Base16, Base32, and Base64 encoding and
+  decoding standards.
+
+- urllib2 now supports processors.  A processor is a handler that
+  implements an xxx_request or xxx_response method.  These methods are
+  called for all requests.
+
+- distutils compilers now compile source files in the same order as
+  they are passed to the compiler.
+
+- pprint.pprint() and pprint.pformat() now have additional parameters
+  indent, width and depth.
+
+- Patch #750542: pprint now will pretty print subclasses of list, tuple
+  and dict too, as long as they don't overwrite __repr__().
+
+- Bug #848614: distutils' msvccompiler fails to find the MSVC6
+  compiler because of incomplete registry entries.
+
+- httplib.HTTP.putrequest now offers to omit the implicit Accept-Encoding.
+
+- Patch #841977: modulefinder didn't find extension modules in packages
+
+- imaplib.IMAP4.thread was added.
+
+- Plugged a minor hole in tempfile.mktemp() due to the use of
+  os.path.exists(), switched to using os.lstat() directly if possible.
+
+- bisect.py and heapq.py now have underlying C implementations
+  for better performance.
+
+- heapq.py has two new functions, nsmallest() and nlargest().
+
+- traceback.format_exc has been added (similar to print_exc but it returns
+  a string).
+
+- xmlrpclib.MultiCall has been added.
+
+- poplib.POP3_SSL has been added.
+
+- tmpfile.mkstemp now returns an absolute path even if dir is relative.
+
+- urlparse is RFC 2396 compliant.
+
+- The fieldnames argument to the csv module's DictReader constructor is now
+  optional.  If omitted, the first row of the file will be used as the
+  list of fieldnames.
+
+- encodings.bz2_codec was added for access to bz2 compression
+  using "a long string".encode('bz2')
+
+- Various improvements to unittest.py, realigned with PyUnit CVS.
+
+- dircache now passes exceptions to the caller, instead of returning
+  empty lists.
+
+- The bsddb module and dbhash module now support the iterator and
+  mapping protocols which make them more substitutable for dictionaries
+  and shelves.
+
+- The csv module's DictReader and DictWriter classes now accept keyword
+  arguments.  This was an omission in the initial implementation.
+
+- The email package handles some RFC 2231 parameters with missing
+  CHARSET fields better.  It also includes a patch to parameter
+  parsing when semicolons appear inside quotes.
+
+- sets.py now runs under Py2.2.  In addition, the argument restrictions
+  for most set methods (but not the operators) have been relaxed to
+  allow any iterable.
+
+- _strptime.py now has a behind-the-scenes caching mechanism for the most
+  recent TimeRE instance used along with the last five unique directive
+  patterns.  The overall module was also made more thread-safe.
+
+- random.cunifvariate() and random.stdgamma() were deprecated in Py2.3
+  and removed in Py2.4.
+
+- Bug #823328: urllib2.py's HTTP Digest Auth support works again.
+
+- Patch #873597: CJK codecs are imported into rank of default codecs.
+
+Tools/Demos
+-----------
+
+- A hotshotmain script was added to the Tools/scripts directory that
+  makes it easy to run a script under control of the hotshot profiler.
+
+- The db2pickle and pickle2db scripts can now dump/load gdbm files.
+
+- The file order on the command line of the pickle2db script was reversed.
+  It is now [ picklefile ] dbfile.  This provides better symmetry with
+  db2pickle.  The file arguments to both scripts are now source followed by
+  destination in situations where both files are given.
+
+- The pydoc script will display a link to the module documentation for
+  modules determined to be part of the core distribution.  The documentation
+  base directory defaults to http://www.python.org/doc/current/lib/ but can
+  be changed by setting the PYTHONDOCS environment variable.
+
+- texcheck.py now detects double word errors.
+
+- md5sum.py mistakenly opened input files in text mode by default, a
+  silent and dangerous change from previous releases.  It once again
+  opens input files in binary mode by default.  The -t and -b flags
+  remain for compatibility with the 2.3 release, but -b is the default
+  now.
+
+- py-electric-colon now works when pending-delete/delete-selection mode is
+  in effect
+
+- py-help-at-point is no longer bound to the F1 key - it's still bound to
+  C-c C-h
+
+- Pynche was fixed to not crash when there is no ~/.pynche file and no
+  -d option was given.
+
+Build
+-----
+
+- Bug #978645: Modules/getpath.c now builds properly in --disable-framework
+  build under OS X.
+
+- Profiling using gprof is now available if Python is configured with
+  --enable-profiling.
+
+- Profiling the VM using the Pentium TSC is now possible if Python
+  is configured --with-tsc.
+
+- In order to find libraries, setup.py now also looks in /lib64, for use
+  on AMD64.
+
+- Bug #934635: Fixed a bug where the configure script couldn't detect
+  getaddrinfo() properly if the KAME stack had SCTP support.
+
+- Support for missing ANSI C header files (limits.h, stddef.h, etc) was
+  removed.
+
+- Systems requiring the D4, D6 or D7 variants of pthreads are no longer
+  supported (see PEP 11).
+
+- Universal newline support can no longer be disabled (see PEP 11).
+
+- Support for DGUX, SunOS 4, IRIX 4 and Minix was removed (see PEP 11).
+
+- Support for systems requiring --with-dl-dld or --with-sgi-dl was removed
+  (see PEP 11).
+
+- Tests for sizeof(char) were removed since ANSI C mandates that
+  sizeof(char) must be 1.
+
+C API
+-----
+
+- Thanks to Anthony Tuininga, the datetime module now supplies a C API
+  containing type-check macros and constructors.  See new docs in the
+  Python/C API Reference Manual for details.
+
+- Private function _PyTime_DoubleToTimet added, to convert a Python
+  timestamp (C double) to platform time_t with some out-of-bounds
+  checking.  Declared in new header file timefuncs.h.  It would be
+  good to expose some other internal timemodule.c functions there.
+
+- New public functions PyEval_EvaluateFrame and PyGen_New to expose
+  generator objects.
+
+- New public functions Py_IncRef() and Py_DecRef(), exposing the
+  functionality of the Py_XINCREF() and Py_XDECREF macros. Useful for
+  runtime dynamic embedding of Python.  See patch #938302, by Bob
+  Ippolito.
+
+- Added a new macro, PySequence_Fast_ITEMS, which retrieves a fast sequence's
+  underlying array of PyObject pointers.  Useful for high speed looping.
+
+- Created a new method flag, METH_COEXIST, which causes a method to be loaded
+  even if already defined by a slot wrapper.  This allows a __contains__
+  method, for example, to co-exist with a defined sq_contains slot.  This
+  is helpful because the PyCFunction can take advantage of optimized calls
+  whenever METH_O or METH_NOARGS flags are defined.
+
+- Added a new function, PyDict_Contains(d, k) which is like
+  PySequence_Contains() but is specific to dictionaries and executes
+  about 10% faster.
+
+- Added three new macros: Py_RETURN_NONE, Py_RETURN_TRUE, and Py_RETURN_FALSE.
+  Each return the singleton they mention after Py_INCREF()ing them.
+
+- Added a new function, PyTuple_Pack(n, ...) for constructing tuples from a
+  variable length argument list of Python objects without having to invoke
+  the more complex machinery of Py_BuildValue().  PyTuple_Pack(3, a, b, c)
+  is equivalent to Py_BuildValue("(OOO)", a, b, c).
+
+Windows
+-------
+
+- The _winreg module could segfault when reading very large registry
+  values, due to unchecked alloca() calls (SF bug 851056).  The fix is
+  uses either PyMem_Malloc(n) or PyString_FromStringAndSize(NULL, n),
+  as appropriate, followed by a size check.
+
+- file.truncate() could misbehave if the file was open for update
+  (modes r+, rb+, w+, wb+), and the most recent file operation before
+  the truncate() call was an input operation.  SF bug 801631.
+
+
+What's New in Python 2.3 final?
+===============================
+
+*Release date: 29-Jul-2003*
+
+IDLE
+----
+
+- Bug 778400:  IDLE hangs when selecting "Edit with IDLE" from explorer.
+  This was unique to Windows, and was fixed by adding an -n switch to
+  the command the Windows installer creates to execute "Edit with IDLE"
+  context-menu actions.
+
+- IDLE displays a new message upon startup:  some "personal firewall"
+  kinds of programs (for example, ZoneAlarm) open a dialog of their
+  own when any program opens a socket.  IDLE does use sockets, talking
+  on the computer's internal loopback interface.  This connection is not
+  visible on any external interface and no data is sent to or received
+  from the Internet.  So, if you get such a dialog when opening IDLE,
+  asking whether to let pythonw.exe talk to address 127.0.0.1, say yes,
+  and rest assured no communication external to your machine is taking
+  place.  If you don't allow it, IDLE won't be able to start.
+
+
+What's New in Python 2.3 release candidate 2?
+=============================================
+
+*Release date: 24-Jul-2003*
+
+Core and builtins
+-----------------
+
+- It is now possible to import from zipfiles containing additional
+  data bytes before the zip compatible archive.  Zipfiles containing a
+  comment at the end are still unsupported.
+
+Extension modules
+-----------------
+
+- A longstanding bug in the parser module's initialization could cause
+  fatal internal refcount confusion when the module got initialized more
+  than once.  This has been fixed.
+
+- Fixed memory leak in pyexpat; using the parser's ParseFile() method
+  with open files that aren't instances of the standard file type
+  caused an instance of the bound .read() method to be leaked on every
+  call.
+
+- Fixed some leaks in the locale module.
+
+Library
+-------
+
+- Lib/encodings/rot_13.py when used as a script, now more properly
+  uses the first Python interpreter on your path.
+
+- Removed caching of TimeRE (and thus LocaleTime) in _strptime.py to
+  fix a locale related bug in the test suite.  Although another patch
+  was needed to actually fix the problem, the cache code was not
+  restored.
+
+IDLE
+----
+
+- Calltips patches.
+
+Build
+-----
+
+- For MacOSX, added -mno-fused-madd to BASECFLAGS to fix test_coercion
+  on Panther (OSX 10.3).
+
+C API
+-----
+
+Windows
+-------
+
+- The tempfile module could do insane imports on Windows if PYTHONCASEOK
+  was set, making temp file creation impossible.  Repaired.
+
+- Add a patch to workaround pthread_sigmask() bugs in Cygwin.
+
+Mac
+---
+
+- Various fixes to pimp.
+
+- Scripts runs with pythonw no longer had full window manager access.
+
+- Don't force boot-disk-only install, for reasons unknown it causes
+  more problems than it solves.
+
+
+What's New in Python 2.3 release candidate 1?
+=============================================
+
+*Release date: 18-Jul-2003*
+
+Core and builtins
+-----------------
+
+- The new function sys.getcheckinterval() returns the last value set
+  by sys.setcheckinterval().
+
+- Several bugs in the symbol table phase of the compiler have been
+  fixed.  Errors could be lost and compilation could fail without
+  reporting an error.  SF patch 763201.
+
+- The interpreter is now more robust about importing the warnings
+  module.  In an executable generated by freeze or similar programs,
+  earlier versions of 2.3 would fail if the warnings module could
+  not be found on the file system.  Fixes SF bug 771097.
+
+- A warning about assignments to module attributes that shadow
+  builtins, present in earlier releases of 2.3, has been removed.
+
+- It is not possible to create subclasses of builtin types like str
+  and tuple that define an itemsize.  Earlier releases of Python 2.3
+  allowed this by mistake, leading to crashes and other problems.
+
+- The thread_id is now initialized to 0 in a non-thread build.  SF bug
+  770247.
+
+- SF bug 762891: "del p[key]" on proxy object no longer raises SystemError.
+
+Extension modules
+-----------------
+
+- weakref.proxy() can now handle "del obj[i]" for proxy objects
+  defining __delitem__.  Formerly, it generated a SystemError.
+
+- SSL no longer crashes the interpreter when the remote side disconnects.
+
+- On Unix the mmap module can again be used to map device files.
+
+- time.strptime now exclusively uses the Python implementation
+  contained within the _strptime module.
+
+- The print slot of weakref proxy objects was removed, because it was
+  not consistent with the object's repr slot.
+
+- The mmap module only checks file size for regular files, not
+  character or block devices.  SF patch 708374.
+
+- The cPickle Pickler garbage collection support was fixed to traverse
+  the find_class attribute, if present.
+
+- There are several fixes for the bsddb3 wrapper module.
+
+  bsddb3 no longer crashes if an environment is closed before a cursor
+  (SF bug 763298).
+
+  The DB and DBEnv set_get_returns_none function was extended to take
+  a level instead of a boolean flag.  The new level 2 means that in
+  addition, cursor.set()/.get() methods return None instead of raising
+  an exception.
+
+  A typo was fixed in DBCursor.join_item(), preventing a crash.
+
+Library
+-------
+
+- distutils now supports MSVC 7.1
+
+- doctest now examines all docstrings by default.  Previously, it would
+  skip over functions with private names (as indicated by the underscore
+  naming convention).  The old default created too much of a risk that
+  user tests were being skipped inadvertently.  Note, this change could
+  break code in the unlikely case that someone had intentionally put
+  failing tests in the docstrings of private functions.  The breakage
+  is easily fixable by specifying the old behavior when calling testmod()
+  or Tester().
+
+- There were several fixes to the way dumbdbms are closed.  It's vital
+  that a dumbdbm database be closed properly, else the on-disk data
+  and directory files can be left in mutually inconsistent states.
+  dumbdbm.py's _Database.__del__() method attempted to close the
+  database properly, but a shutdown race in _Database._commit() could
+  prevent this from working, so that a program trusting __del__() to
+  get the on-disk files in synch could be badly surprised.  The race
+  has been repaired.  A sync() method was also added so that shelve
+  can guarantee data is written to disk.
+
+  The close() method can now be called more than once without complaint.
+
+- The classes in threading.py are now new-style classes.  That they
+  weren't before was an oversight.
+
+- The urllib2 digest authentication handlers now define the correct
+  auth_header.  The earlier versions would fail at runtime.
+
+- SF bug 763023: fix uncaught ZeroDivisionError in difflib ratio methods
+  when there are no lines.
+
+- SF bug 763637: fix exception in Tkinter with after_cancel
+  which could occur with Tk 8.4
+
+- SF bug 770601: CGIHTTPServer.py now passes the entire environment
+  to child processes.
+
+- SF bug 765238: add filter to fnmatch's __all__.
+
+- SF bug 748201: make time.strptime() error messages more helpful.
+
+- SF patch 764470: Do not dump the args attribute of a Fault object in
+  xmlrpclib.
+
+- SF patch 549151: urllib and urllib2 now redirect POSTs on 301
+  responses.
+
+- SF patch 766650: The whichdb module was fixed to recognize dbm files
+  generated by gdbm on OS/2 EMX.
+
+- SF bugs 763047 and 763052: fixes bug of timezone value being left as
+  -1 when ``time.tzname[0] == time.tzname[1] and not time.daylight``
+  is true when it should only when time.daylight is true.
+
+- SF bug 764548: re now allows subclasses of str and unicode to be
+  used as patterns.
+
+- SF bug 763637: In Tkinter, change after_cancel() to handle tuples
+  of varying sizes.  Tk 8.4 returns a different number of values
+  than Tk 8.3.
+
+- SF bug 763023: difflib.ratio() did not catch zero division.
+
+- The Queue module now has an __all__ attribute.
+
+Tools/Demos
+-----------
+
+- See Lib/idlelib/NEWS.txt for IDLE news.
+
+- SF bug 753592: webchecker/wsgui now handles user supplied directories.
+
+- The trace.py script has been removed.  It is now in the standard library.
+
+Build
+-----
+
+- Python now compiles with -fno-strict-aliasing if possible (SF bug 766696).
+
+- The socket module compiles on IRIX 6.5.10.
+
+- An irix64 system is treated the same way as an irix6 system (SF
+  patch 764560).
+
+- Several definitions were missing on FreeBSD 5.x unless the
+  __BSD_VISIBLE symbol was defined.  configure now defines it as
+  needed.
+
+C API
+-----
+
+- Unicode objects now support mbcs as a built-in encoding, so the C
+  API can use it without deferring to the encodings package.
+
+Windows
+-------
+
+- The Windows implementation of PyThread_start_new_thread() never
+  checked error returns from Windows functions correctly.  As a result,
+  it could claim to start a new thread even when the Microsoft
+  _beginthread() function failed (due to "too many threads" -- this is
+  on the order of thousands when it happens).  In these cases, the
+  Python exception ::
+
+      thread.error: can't start new thread
+
+  is raised now.
+
+- SF bug 766669: Prevent a GPF on interpreter exit when sockets are in
+  use.  The interpreter now calls WSACleanup() from Py_Finalize()
+  instead of from DLL teardown.
+
+Mac
+---
+
+- Bundlebuilder now inherits default values in the right way.  It was
+  previously possible for app bundles to get a type of "BNDL" instead
+  of "APPL."  Other improvements include, a --build-id option to
+  specify the CFBundleIdentifier and using the --python option to set
+  the executable in the bundle.
+
+- Fixed two bugs in MacOSX framework handling.
+
+- pythonw did not allow user interaction in 2.3rc1, this has been fixed.
+
+- Python is now compiled with -mno-fused-madd, making all tests pass
+  on Panther.
+
+What's New in Python 2.3 beta 2?
+================================
+
+*Release date: 29-Jun-2003*
+
+Core and builtins
+-----------------
+
+- A program can now set the environment variable PYTHONINSPECT to some
+  string value in Python, and cause the interpreter to enter the
+  interactive prompt at program exit, as if Python had been invoked
+  with the -i option.
+
+- list.index() now accepts optional start and stop arguments.  Similar
+  changes were made to UserList.index(). SF feature request 754014.
+
+- SF patch 751998 fixes an unwanted side effect of the previous fix
+  for SF bug 742860 (the next item).
+
+- SF bug 742860: "WeakKeyDictionary __delitem__ uses iterkeys".  This
+  wasn't threadsafe, was very inefficient (expected time O(len(dict))
+  instead of O(1)), and could raise a spurious RuntimeError if another
+  thread mutated the dict during __delitem__, or if a comparison function
+  mutated it.  It also neglected to raise KeyError when the key wasn't
+  present; didn't raise TypeError when the key wasn't of a weakly
+  referencable type; and broke various more-or-less obscure dict
+  invariants by using a sequence of equality comparisons over the whole
+  set of dict keys instead of computing the key's hash code to narrow
+  the search to those keys with the same hash code.  All of these are
+  considered to be bugs.  A new implementation of __delitem__ repairs all
+  that, but note that fixing these bugs may change visible behavior in
+  code relying (whether intentionally or accidentally) on old behavior.
+
+- SF bug 734869: Fixed a compiler bug that caused a fatal error when
+  compiling a list comprehension that contained another list comprehension
+  embedded in a lambda expression.
+
+- SF bug 705231:  builtin pow() no longer lets the platform C pow()
+  raise -1.0 to integer powers, because (at least) glibc gets it wrong
+  in some cases.  The result should be -1.0 if the power is odd and 1.0
+  if the power is even, and any float with a sufficiently large exponent
+  is (mathematically) an exact even integer.
+
+- SF bug 759227: A new-style class that implements __nonzero__() must
+  return a bool or int (but not an int subclass) from that method.  This
+  matches the restriction on classic classes.
+
+- The encoding attribute has been added for file objects, and set to
+  the terminal encoding on Unix and Windows.
+
+- The softspace attribute of file objects became read-only by oversight.
+  It's writable again.
+
+- Reverted a 2.3 beta 1 change to iterators for subclasses of list and
+  tuple.  By default, the iterators now access data elements directly
+  instead of going through __getitem__.  If __getitem__ access is
+  preferred, then __iter__ can be overridden.
+
+- SF bug 735247: The staticmethod and super types participate in
+  garbage collection. Before this change, it was possible for leaks to
+  occur in functions with non-global free variables that used these types.
+
+Extension modules
+-----------------
+
+- the socket module has a new exception, socket.timeout, to allow
+  timeouts to be handled separately from other socket errors.
+
+- SF bug 751276: cPickle has fixed to propagate exceptions raised in
+  user code.  In earlier versions, cPickle caught and ignored any
+  exception when it performed operations that it expected to raise
+  specific exceptions like AttributeError.
+
+- cPickle Pickler and Unpickler objects now participate in garbage
+  collection.
+
+- mimetools.choose_boundary() could return duplicate strings at times,
+  especially likely on Windows.  The strings returned are now guaranteed
+  unique within a single program run.
+
+- thread.interrupt_main() raises KeyboardInterrupt in the main thread.
+  dummy_thread has also been modified to try to simulate the behavior.
+
+- array.array.insert() now treats negative indices as being relative
+  to the end of the array, just like list.insert() does. (SF bug #739313)
+
+- The datetime module classes datetime, time, and timedelta are now
+  properly subclassable.
+
+- _tkinter.{get|set}busywaitinterval was added.
+
+- itertools.islice() now accepts stop=None as documented.
+  Fixes SF bug #730685.
+
+- the bsddb185 module is built in one restricted instance -
+  /usr/include/db.h exists and defines HASHVERSION to be 2.  This is true
+  for many BSD-derived systems.
+
+
+Library
+-------
+
+- Some happy doctest extensions from Jim Fulton have been added to
+  doctest.py.  These are already being used in Zope3.  The two
+  primary ones:
+
+  doctest.debug(module, name) extracts the doctests from the named object
+  in the given module, puts them in a temp file, and starts pdb running
+  on that file.  This is great when a doctest fails.
+
+  doctest.DocTestSuite(module=None) returns a synthesized unittest
+  TestSuite instance, to be run by the unittest framework, which
+  runs all the doctests in the module.  This allows writing tests in
+  doctest style (which can be clearer and shorter than writing tests
+  in unittest style), without losing unittest's powerful testing
+  framework features (which doctest lacks).
+
+- For compatibility with doctests created before 2.3, if an expected
+  output block consists solely of "1" and the actual output block
+  consists solely of "True", it's accepted as a match; similarly
+  for "0" and "False".  This is quite un-doctest-like, but is practical.
+  The behavior can be disabled by passing the new doctest module
+  constant DONT_ACCEPT_TRUE_FOR_1 to the new optionflags optional
+  argument.
+
+- ZipFile.testzip() now only traps BadZipfile exceptions.  Previously,
+  a bare except caught to much and reported all errors as a problem
+  in the archive.
+
+- The logging module now has a new function, makeLogRecord() making
+  LogHandler easier to interact with DatagramHandler and SocketHandler.
+
+- The cgitb module has been extended to support plain text display (SF patch
+  569574).
+
+- A brand new version of IDLE (from the IDLEfork project at
+  SourceForge) is now included as Lib/idlelib.  The old Tools/idle is
+  no more.
+
+- Added a new module: trace (documentation missing).  This module used
+  to be distributed in Tools/scripts.  It uses sys.settrace() to trace
+  code execution -- either function calls or individual lines.  It can
+  generate tracing output during execution or a post-mortem report of
+  code coverage.
+
+- The threading module has new functions settrace() and setprofile()
+  that cooperate with the functions of the same name in the sys
+  module.  A function registered with the threading module will
+  be used for all threads it creates.  The new trace module uses this
+  to provide tracing for code running in threads.
+
+- copy.py: applied SF patch 707900, fixing bug 702858, by Steven
+  Taschuk.  Copying a new-style class that had a reference to itself
+  didn't work.  (The same thing worked fine for old-style classes.)
+  Builtin functions are now treated as atomic, fixing bug #746304.
+
+- difflib.py has two new functions:  context_diff() and unified_diff().
+
+- More fixes to urllib (SF 549151): (a) When redirecting, always use
+  GET.  This is common practice and more-or-less sanctioned by the
+  HTTP standard. (b) Add a handler for 307 redirection, which becomes
+  an error for POST, but a regular redirect for GET and HEAD
+
+- Added optional 'onerror' argument to os.walk(), to control error
+  handling.
+
+- inspect.is{method|data}descriptor was added, to allow pydoc display
+  __doc__ of data descriptors.
+
+- Fixed socket speed loss caused by use of the _socketobject wrapper class
+  in socket.py.
+
+- timeit.py now checks the current directory for imports.
+
+- urllib2.py now knows how to order proxy classes, so the user doesn't
+  have to insert it in front of other classes, nor do dirty tricks like
+  inserting a "dummy" HTTPHandler after a ProxyHandler when building an
+  opener with proxy support.
+
+- Iterators have been added for dbm keys.
+
+- random.Random objects can now be pickled.
+
+Tools/Demos
+-----------
+
+- pydoc now offers help on keywords and topics.
+
+- Tools/idle is gone; long live Lib/idlelib.
+
+- diff.py prints file diffs in context, unified, or ndiff formats,
+  providing a command line interface to difflib.py.
+
+- texcheck.py is a new script for making a rough validation of Python LaTeX
+  files.
+
+Build
+-----
+
+- Setting DESTDIR during 'make install' now allows specifying a
+  different root directory.
+
+C API
+-----
+
+- PyType_Ready():  If a type declares that it participates in gc
+  (Py_TPFLAGS_HAVE_GC), and its base class does not, and its base class's
+  tp_free slot is the default _PyObject_Del, and type does not define
+  a tp_free slot itself, _PyObject_GC_Del is assigned to type->tp_free.
+  Previously _PyObject_Del was inherited, which could at best lead to a
+  segfault.  In addition, if even after this magic the type's tp_free
+  slot is _PyObject_Del or NULL, and the type is a base type
+  (Py_TPFLAGS_BASETYPE), TypeError is raised:  since the type is a base
+  type, its dealloc function must call type->tp_free, and since the type
+  is gc'able, tp_free must not be NULL or _PyObject_Del.
+
+- PyThreadState_SetAsyncExc(): A new API (deliberately accessible only
+  from C) to interrupt a thread by sending it an exception.  It is
+  intentional that you have to write your own C extension to call it
+  from Python.
+
+
+New platforms
+-------------
+
+None this time.
+
+Tests
+-----
+
+- test_imp rewritten so that it doesn't raise RuntimeError if run as a
+  side effect of being imported ("import test.autotest").
+
+Windows
+-------
+
+- The Windows installer ships with Tcl/Tk 8.4.3 (upgraded from 8.4.1).
+
+- The installer always suggested that Python be installed on the C:
+  drive, due to a hardcoded "C:" generated by the Wise installation
+  wizard.  People with machines where C: is not the system drive
+  usually want Python installed on whichever drive is their system drive
+  instead.  We removed the hardcoded "C:", and two testers on machines
+  where C: is not the system drive report that the installer now
+  suggests their system drive.  Note that you can always select the
+  directory you want in the "Select Destination Directory" dialog --
+  that's what it's for.
+
+Mac
+---
+
+- There's a new module called "autoGIL", which offers a mechanism to
+  automatically release the Global Interpreter Lock when an event loop
+  goes to sleep, allowing other threads to run. It's currently only
+  supported on OSX, in the Mach-O version.
+- The OSA modules now allow direct access to properties of the
+  toplevel application class (in AppleScript terminology).
+- The Package Manager can now update itself.
+
+SourceForge Bugs and Patches Applied
+------------------------------------
+
+430160, 471893, 501716, 542562, 549151, 569574, 595837, 596434,
+598163, 604210, 604716, 610332, 612627, 614770, 620190, 621891,
+622042, 639139, 640236, 644345, 649742, 649742, 658233, 660022,
+661318, 661676, 662807, 662923, 666219, 672855, 678325, 682347,
+683486, 684981, 685773, 686254, 692776, 692959, 693094, 696777,
+697989, 700827, 703666, 708495, 708604, 708901, 710733, 711902,
+713722, 715782, 718286, 719359, 719367, 723136, 723831, 723962,
+724588, 724767, 724767, 725942, 726150, 726446, 726869, 727051,
+727719, 727719, 727805, 728277, 728563, 728656, 729096, 729103,
+729293, 729297, 729300, 729317, 729395, 729622, 729817, 730170,
+730296, 730594, 730685, 730826, 730963, 731209, 731403, 731504,
+731514, 731626, 731635, 731643, 731644, 731644, 731689, 732124,
+732143, 732234, 732284, 732284, 732479, 732761, 732783, 732951,
+733667, 733781, 734118, 734231, 734869, 735051, 735293, 735527,
+735613, 735694, 736962, 736962, 737970, 738066, 739313, 740055,
+740234, 740301, 741806, 742126, 742741, 742860, 742860, 742911,
+744041, 744104, 744238, 744687, 744877, 745055, 745478, 745525,
+745620, 746012, 746304, 746366, 746801, 746953, 747348, 747667,
+747954, 748846, 748849, 748973, 748975, 749191, 749210, 749759,
+749831, 749911, 750008, 750092, 750542, 750595, 751038, 751107,
+751276, 751451, 751916, 751941, 751956, 751998, 752671, 753451,
+753602, 753617, 753845, 753925, 754014, 754340, 754447, 755031,
+755087, 755147, 755245, 755683, 755987, 756032, 756996, 757058,
+757229, 757818, 757821, 757822, 758112, 758910, 759227, 759889,
+760257, 760703, 760792, 761104, 761337, 761519, 761830, 762455
+
+
+What's New in Python 2.3 beta 1?
+================================
+
+*Release date: 25-Apr-2003*
+
+Core and builtins
+-----------------
+
+- New format codes B, H, I, k and K have been implemented for
+  PyArg_ParseTuple and PyBuild_Value.
+
+- New builtin function sum(seq, start=0) returns the sum of all the
+  items in iterable object seq, plus start (items are normally numbers,
+  and cannot be strings).
+
+- bool() called without arguments now returns False rather than
+  raising an exception.  This is consistent with calling the
+  constructors for the other builtin types -- called without argument
+  they all return the false value of that type.  (SF patch #724135)
+
+- In support of PEP 269 (making the pgen parser generator accessible
+  from Python), some changes to the pgen code structure were made; a
+  few files that used to be linked only with pgen are now linked with
+  Python itself.
+
+- The repr() of a weakref object now shows the __name__ attribute of
+  the referenced object, if it has one.
+
+- super() no longer ignores data descriptors, except __class__.  See
+  the thread started at
+  http://mail.python.org/pipermail/python-dev/2003-April/034338.html
+
+- list.insert(i, x) now interprets negative i as it would be
+  interpreted by slicing, so negative values count from the end of the
+  list.  This was the only place where such an interpretation was not
+  placed on a list index.
+
+- range() now works even if the arguments are longs with magnitude
+  larger than sys.maxint, as long as the total length of the sequence
+  fits.  E.g., range(2**100, 2**101, 2**100) is the following list:
+  [1267650600228229401496703205376L].  (SF patch #707427.)
+
+- Some horridly obscure problems were fixed involving interaction
+  between garbage collection and old-style classes with "ambitious"
+  getattr hooks.  If an old-style instance didn't have a __del__ method,
+  but did have a __getattr__ hook, and the instance became reachable
+  only from an unreachable cycle, and the hook resurrected or deleted
+  unreachable objects when asked to resolve "__del__", anything up to
+  a segfault could happen.  That's been repaired.
+
+- dict.pop now takes an optional argument specifying a default
+  value to return if the key is not in the dict.  If a default is not
+  given and the key is not found, a KeyError will still be raised.
+  Parallel changes were made to UserDict.UserDict and UserDict.DictMixin.
+  [SF patch #693753] (contributed by Michael Stone.)
+
+- sys.getfilesystemencoding() was added to expose
+  Py_FileSystemDefaultEncoding.
+
+- New function sys.exc_clear() clears the current exception.  This is
+  rarely needed, but can sometimes be useful to release objects
+  referenced by the traceback held in sys.exc_info()[2].  (SF patch
+  #693195.)
+
+- On 64-bit systems, a dictionary could contain duplicate long/int keys
+  if the key value was larger than 2**32.  See SF bug #689659.
+
+- Fixed SF bug #663074. The codec system was using global static
+  variables to store internal data. As a result, any attempts to use the
+  unicode system with multiple active interpreters, or successive
+  interpreter executions, would fail.
+
+- "%c" % u"a" now returns a unicode string instead of raising a
+  TypeError. u"%c" % 0xffffffff now raises a OverflowError instead
+  of a ValueError to be consistent with "%c" % 256. See SF patch #710127.
+
+Extension modules
+-----------------
+
+- The socket module now provides the functions inet_pton and inet_ntop
+  for converting between string and packed representation of IP
+  addresses.  There is also a new module variable, has_ipv6, which is
+  True iff the current Python has IPv6 support.  See SF patch #658327.
+
+- Tkinter wrappers around Tcl variables now pass objects directly
+  to Tcl, instead of first converting them to strings.
+
+- The .*? pattern in the re module is now special-cased to avoid the
+  recursion limit.  (SF patch #720991 -- many thanks to Gary Herron
+  and Greg Chapman.)
+
+- New function sys.call_tracing() allows pdb to debug code
+  recursively.
+
+- New function gc.get_referents(obj) returns a list of objects
+  directly referenced by obj.  In effect, it exposes what the object's
+  tp_traverse slot does, and can be helpful when debugging memory
+  leaks.
+
+- The iconv module has been removed from this release.
+
+- The platform-independent routines for packing floats in IEEE formats
+  (struct.pack's <f, >f, <d, and >d codes; pickle and cPickle's protocol 1
+  pickling of floats) ignored that rounding can cause a carry to
+  propagate.  The worst consequence was that, in rare cases, <f and >f
+  could produce strings that, when unpacked again, were a factor of 2
+  away from the original float.  This has been fixed.  See SF bug
+  #705836.
+
+- New function time.tzset() provides access to the C library tzset()
+  function, if supported.  (SF patch #675422.)
+
+- Using createfilehandler, deletefilehandler, createtimerhandler functions
+  on Tkinter.tkinter (_tkinter module) no longer crashes the interpreter.
+  See SF bug #692416.
+
+- Modified the fcntl.ioctl() function to allow modification of a passed
+  mutable buffer (for details see the reference documentation).
+
+- Made user requested changes to the itertools module.
+  Subsumed the times() function into repeat().
+  Added chain() and cycle().
+
+- The rotor module is now deprecated; the encryption algorithm it uses
+  is not believed to be secure, and including crypto code with Python
+  has implications for exporting and importing it in various countries.
+
+- The socket module now always uses the _socketobject wrapper class, even on
+  platforms which have dup(2).  The makefile() method is built directly
+  on top of the socket without duplicating the file descriptor, allowing
+  timeouts to work properly.
+
+Library
+-------
+
+- New generator function os.walk() is an easy-to-use alternative to
+  os.path.walk().  See os module docs for details.  os.path.walk()
+  isn't deprecated at this time, but may become deprecated in a
+  future release.
+
+- Added new module "platform" which provides a wide range of tools
+  for querying platform dependent features.
+
+- netrc now allows ASCII punctuation characters in passwords.
+
+- shelve now supports the optional writeback argument, and exposes
+  pickle protocol versions.
+
+- Several methods of nntplib.NNTP have grown an optional file argument
+  which specifies a file where to divert the command's output
+  (already supported by the body() method).  (SF patch #720468)
+
+- The self-documenting XML server library DocXMLRPCServer was added.
+
+- Support for internationalized domain names has been added through
+  the 'idna' and 'punycode' encodings, the 'stringprep' module, the
+  'mkstringprep' tool, and enhancements to the socket and httplib
+  modules.
+
+- htmlentitydefs has two new dictionaries: name2codepoint maps
+  HTML entity names to Unicode codepoints (as integers).
+  codepoint2name is the reverse mapping. See SF patch #722017.
+
+- pdb has a new command, "debug", which lets you step through
+  arbitrary code from the debugger's (pdb) prompt.
+
+- unittest.failUnlessEqual and its equivalent unittest.assertEqual now
+  return 'not a == b' rather than 'a != b'.  This gives the desired
+  result for classes that define __eq__ without defining __ne__.
+
+- sgmllib now supports SGML marked sections, in particular the
+  MS Office extensions.
+
+- The urllib module now offers support for the iterator protocol.
+  SF patch 698520 contributed by Brett Cannon.
+
+- New module timeit provides a simple framework for timing the
+  execution speed of expressions and statements.
+
+- sets.Set objects now support mixed-type __eq__ and __ne__, instead
+  of raising TypeError.  If x is a Set object and y is a non-Set object,
+  x == y is False, and x != y is True.  This is akin to the change made
+  for mixed-type comparisons of datetime objects in 2.3a2; more info
+  about the rationale is in the NEWS entry for that.  See also SF bug
+  report <http://www.python.org/sf/693121>.
+
+- On Unix platforms, if os.listdir() is called with a Unicode argument,
+  it now returns Unicode strings.  (This behavior was added earlier
+  to the Windows NT/2k/XP version of os.listdir().)
+
+- Distutils: both 'py_modules' and 'packages' keywords can now be specified
+  in core.setup().  Previously you could supply one or the other, but
+  not both of them.  (SF patch #695090 from Bernhard Herzog)
+
+- New csv package makes it easy to read/write CSV files.
+
+- Module shlex has been extended to allow posix-like shell parsings,
+  including a split() function for easy spliting of quoted strings and
+  commands. An iterator interface was also implemented.
+
+Tools/Demos
+-----------
+
+- New script combinerefs.py helps analyze new PYTHONDUMPREFS output.
+  See the module docstring for details.
+
+Build
+-----
+
+- Fix problem building on OSF1 because the compiler only accepted
+  preprocessor directives that start in column 1.  (SF bug #691793.)
+
+C API
+-----
+
+- Added PyGC_Collect(), equivalent to calling gc.collect().
+
+- PyThreadState_GetDict() was changed not to raise an exception or
+  issue a fatal error when no current thread state is available.  This
+  makes it possible to print dictionaries when no thread is active.
+
+- LONG_LONG was renamed to PY_LONG_LONG.  Extensions that use this and
+  need compatibility with previous versions can use this:
+
+    #ifndef  PY_LONG_LONG
+    #define  PY_LONG_LONG  LONG_LONG
+    #endif
+
+- Added PyObject_SelfIter() to fill the tp_iter slot for the
+  typical case where the method returns its self argument.
+
+- The extended type structure used for heap types (new-style
+  classes defined by Python code using a class statement) is now
+  exported from object.h as PyHeapTypeObject.  (SF patch #696193.)
+
+New platforms
+-------------
+
+None this time.
+
+Tests
+-----
+
+- test_timeout now requires -u network to be passed to regrtest to run.
+  See SF bug #692988.
+
+Windows
+-------
+
+- os.fsync() now exists on Windows, and calls the Microsoft _commit()
+  function.
+
+- New function winsound.MessageBeep() wraps the Win32 API
+  MessageBeep().
+
+Mac
+---
+
+- os.listdir() now returns Unicode strings on MacOS X when called with
+  a Unicode argument. See the general news item under "Library".
+
+- A new method MacOS.WMAvailable() returns true if it is safe to access
+  the window manager, false otherwise.
+
+- EasyDialogs dialogs are now movable-modal, and if the application is
+  currently in the background they will ask to be moved to the foreground
+  before displaying.
+
+- OSA Scripting support has improved a lot, and gensuitemodule.py can now
+  be used by mere mortals. The documentation is now also more or less
+  complete.
+
+- The IDE (in a framework build) now includes introductory documentation
+  in Apple Help Viewer format.
+
+
+What's New in Python 2.3 alpha 2?
+=================================
+
+*Release date: 19-Feb-2003*
+
+Core and builtins
+-----------------
+
+- Negative positions returned from PEP 293 error callbacks are now
+  treated as being relative to the end of the input string. Positions
+  that are out of bounds raise an IndexError.
+
+- sys.path[0] (the directory from which the script is loaded) is now
+  turned into an absolute pathname, unless it is the empty string.
+  (SF patch #664376.)
+
+- Finally fixed the bug in compile() and exec where a string ending
+  with an indented code block but no newline would raise SyntaxError.
+  This would have been a four-line change in parsetok.c...  Except
+  codeop.py depends on this behavior, so a compilation flag had to be
+  invented that causes the tokenizer to revert to the old behavior;
+  this required extra changes to 2 .h files, 2 .c files, and 2 .py
+  files.  (Fixes SF bug #501622.)
+
+- If a new-style class defines neither __new__ nor __init__, its
+  constructor would ignore all arguments.  This is changed now: the
+  constructor refuses arguments in this case.  This might break code
+  that worked under Python 2.2.  The simplest fix is to add a no-op
+  __init__: ``def __init__(self, *args, **kw): pass``.
+
+- Through a bytecode optimizer bug (and I bet you didn't even know
+  Python *had* a bytecode optimizer :-), "unsigned" hex/oct constants
+  with a leading minus sign would come out with the wrong sign.
+  ("Unsigned" hex/oct constants are those with a face value in the
+  range sys.maxint+1 through sys.maxint*2+1, inclusive; these have
+  always been interpreted as negative numbers through sign folding.)
+  E.g. 0xffffffff is -1, and -(0xffffffff) is 1, but -0xffffffff would
+  come out as -4294967295.  This was the case in Python 2.2 through
+  2.2.2 and 2.3a1, and in Python 2.4 it will once again have that
+  value, but according to PEP 237 it really needs to be 1 now.  This
+  will be backported to Python 2.2.3 a well.  (SF #660455)
+
+- int(s, base) sometimes sign-folds hex and oct constants; it only
+  does this when base is 0 and s.strip() starts with a '0'.  When the
+  sign is actually folded, as in int("0xffffffff", 0) on a 32-bit
+  machine, which returns -1, a FutureWarning is now issued; in Python
+  2.4, this will return 4294967295L, as do int("+0xffffffff", 0) and
+  int("0xffffffff", 16) right now.  (PEP 347)
+
+- super(X, x): x may now be a proxy for an X instance, i.e.
+  issubclass(x.__class__, X) but not issubclass(type(x), X).
+
+- isinstance(x, X): if X is a new-style class, this is now equivalent
+  to issubclass(type(x), X) or issubclass(x.__class__, X).  Previously
+  only type(x) was tested.  (For classic classes this was already the
+  case.)
+
+- compile(), eval() and the exec statement now fully support source code
+  passed as unicode strings.
+
+- int subclasses can be initialized with longs if the value fits in an int.
+  See SF bug #683467.
+
+- long(string, base) takes time linear in len(string) when base is a power
+  of 2 now.  It used to take time quadratic in len(string).
+
+- filter returns now Unicode results for Unicode arguments.
+
+- raw_input can now return Unicode objects.
+
+- List objects' sort() method now accepts None as the comparison function.
+  Passing None is semantically identical to calling sort() with no
+  arguments.
+
+- Fixed crash when printing a subclass of str and __str__ returned self.
+  See SF bug #667147.
+
+- Fixed an invalid RuntimeWarning and an undetected error when trying
+  to convert a long integer into a float which couldn't fit.
+  See SF bug #676155.
+
+- Function objects now have a __module__ attribute that is bound to
+  the name of the module in which the function was defined.  This
+  applies for C functions and methods as well as functions and methods
+  defined in Python.  This attribute is used by pickle.whichmodule(),
+  which changes the behavior of whichmodule slightly.  In Python 2.2
+  whichmodule() returns "__main__" for functions that are not defined
+  at the top-level of a module (examples: methods, nested functions).
+  Now whichmodule() will return the proper module name.
+
+Extension modules
+-----------------
+
+- operator.isNumberType() now checks that the object has a nb_int or
+  nb_float slot, rather than simply checking whether it has a non-NULL
+  tp_as_number pointer.
+
+- The imp module now has ways to acquire and release the "import
+  lock": imp.acquire_lock() and imp.release_lock().  Note: this is a
+  reentrant lock, so releasing the lock only truly releases it when
+  this is the last release_lock() call.  You can check with
+  imp.lock_held().  (SF bug #580952 and patch #683257.)
+
+- Change to cPickle to match pickle.py (see below and PEP 307).
+
+- Fix some bugs in the parser module.  SF bug #678518.
+
+- Thanks to Scott David Daniels, a subtle bug in how the zlib
+  extension implemented flush() was fixed.  Scott also rewrote the
+  zlib test suite using the unittest module.  (SF bug #640230 and
+  patch #678531.)
+
+- Added an itertools module containing high speed, memory efficient
+  looping constructs inspired by tools from Haskell and SML.
+
+- The SSL module now handles sockets with a timeout set correctly (SF
+  patch #675750, fixing SF bug #675552).
+
+- os/posixmodule has grown the sysexits.h constants (EX_OK and friends).
+
+- Fixed broken threadstate swap in readline that could cause fatal
+  errors when a readline hook was being invoked while a background
+  thread was active.  (SF bugs #660476 and #513033.)
+
+- fcntl now exposes the strops.h I_* constants.
+
+- Fix a crash on Solaris that occurred when calling close() on
+  an mmap'ed file which was already closed.  (SF patch #665913)
+
+- Fixed several serious bugs in the zipimport implementation.
+
+- datetime changes:
+
+  The date class is now properly subclassable.  (SF bug #720908)
+
+  The datetime and datetimetz classes have been collapsed into a single
+  datetime class, and likewise the time and timetz classes into a single
+  time class.  Previously, a datetimetz object with tzinfo=None acted
+  exactly like a datetime object, and similarly for timetz.  This wasn't
+  enough of a difference to justify distinct classes, and life is simpler
+  now.
+
+  today() and now() now round system timestamps to the closest
+  microsecond <http://www.python.org/sf/661086>.  This repairs an
+  irritation most likely seen on Windows systems.
+
+  In dt.astimezone(tz), if tz.utcoffset(dt) returns a duration,
+  ValueError is raised if tz.dst(dt) returns None (2.3a1 treated it
+  as 0 instead, but a tzinfo subclass wishing to participate in
+  time zone conversion has to take a stand on whether it supports
+  DST; if you don't care about DST, then code dst() to return 0 minutes,
+  meaning that DST is never in effect).
+
+  The tzinfo methods utcoffset() and dst() must return a timedelta object
+  (or None) now.  In 2.3a1 they could also return an int or long, but that
+  was an unhelpfully redundant leftover from an earlier version wherein
+  they couldn't return a timedelta.  TOOWTDI.
+
+  The example tzinfo class for local time had a bug.  It was replaced
+  by a later example coded by Guido.
+
+  datetime.astimezone(tz) no longer raises an exception when the
+  input datetime has no UTC equivalent in tz.  For typical "hybrid" time
+  zones (a single tzinfo subclass modeling both standard and daylight
+  time), this case can arise one hour per year, at the hour daylight time
+  ends.  See new docs for details.  In short, the new behavior mimics
+  the local wall clock's behavior of repeating an hour in local time.
+
+  dt.astimezone() can no longer be used to convert between naive and aware
+  datetime objects.  If you merely want to attach, or remove, a tzinfo
+  object, without any conversion of date and time members, use
+  dt.replace(tzinfo=whatever) instead, where "whatever" is None or a
+  tzinfo subclass instance.
+
+  A new method tzinfo.fromutc(dt) can be overridden in tzinfo subclasses
+  to give complete control over how a UTC time is to be converted to
+  a local time.  The default astimezone() implementation calls fromutc()
+  as its last step, so a tzinfo subclass can affect that too by overriding
+  fromutc().  It's expected that the default fromutc() implementation will
+  be suitable as-is for "almost all" time zone subclasses, but the
+  creativity of political time zone fiddling appears unbounded -- fromutc()
+  allows the highly motivated to emulate any scheme expressible in Python.
+
+  datetime.now():  The optional tzinfo argument was undocumented (that's
+  repaired), and its name was changed to tz ("tzinfo" is overloaded enough
+  already).  With a tz argument, now(tz) used to return the local date
+  and time, and attach tz to it, without any conversion of date and time
+  members.  This was less than useful.  Now now(tz) returns the current
+  date and time as local time in tz's time zone, akin to ::
+
+      tz.fromutc(datetime.utcnow().replace(tzinfo=utc))
+
+  where "utc" is an instance of a tzinfo subclass modeling UTC.  Without
+  a tz argument, now() continues to return the current local date and time,
+  as a naive datetime object.
+
+  datetime.fromtimestamp():  Like datetime.now() above, this had less than
+  useful behavior when the optional tinzo argument was specified.  See
+  also SF bug report <http://www.python.org/sf/660872>.
+
+  date and datetime comparison:  In order to prevent comparison from
+  falling back to the default compare-object-addresses strategy, these
+  raised TypeError whenever they didn't understand the other object type.
+  They still do, except when the other object has a "timetuple" attribute,
+  in which case they return NotImplemented now.  This gives other
+  datetime objects (e.g., mxDateTime) a chance to intercept the
+  comparison.
+
+  date, time, datetime and timedelta comparison:  When the exception
+  for mixed-type comparisons in the last paragraph doesn't apply, if
+  the comparison is == then False is returned, and if the comparison is
+  != then True is returned.  Because dict lookup and the "in" operator
+  only invoke __eq__, this allows, for example, ::
+
+      if some_datetime in some_sequence:
+
+  and ::
+
+      some_dict[some_timedelta] = whatever
+
+  to work as expected, without raising TypeError just because the
+  sequence is heterogeneous, or the dict has mixed-type keys.  [This
+  seems like a good idea to implement for all mixed-type comparisons
+  that don't want to allow falling back to address comparison.]
+
+  The constructors building a datetime from a timestamp could raise
+  ValueError if the platform C localtime()/gmtime() inserted "leap
+  seconds".  Leap seconds are ignored now.  On such platforms, it's
+  possible to have timestamps that differ by a second, yet where
+  datetimes constructed from them are equal.
+
+  The pickle format of date, time and datetime objects has changed
+  completely.  The undocumented pickler and unpickler functions no
+  longer exist.  The undocumented __setstate__() and __getstate__()
+  methods no longer exist either.
+
+Library
+-------
+
+- The logging module was updated slightly; the WARN level was renamed
+  to WARNING, and the matching function/method warn() to warning().
+
+- The pickle and cPickle modules were updated with a new pickling
+  protocol (documented by pickletools.py, see below) and several
+  extensions to the pickle customization API (__reduce__, __setstate__
+  etc.).  The copy module now uses more of the pickle customization
+  API to copy objects that don't implement __copy__ or __deepcopy__.
+  See PEP 307 for details.
+
+- The distutils "register" command now uses http://www.python.org/pypi
+  as the default repository.  (See PEP 301.)
+
+- the platform dependent path related variables sep, altsep, extsep,
+  pathsep, curdir, pardir and defpath are now defined in the platform
+  dependent path modules (e.g. ntpath.py) rather than os.py, so these
+  variables are now available via os.path.  They continue to be
+  available from the os module.
+  (see <http://www.python.org/sf/680789>).
+
+- array.array was added to the types repr.py knows about (see
+  <http://www.python.org/sf/680789>).
+
+- The new pickletools.py contains lots of documentation about pickle
+  internals, and supplies some helpers for working with pickles, such as
+  a symbolic pickle disassembler.
+
+- Xmlrpclib.py now supports the builtin boolean type.
+
+- py_compile has a new 'doraise' flag and a new PyCompileError
+  exception.
+
+- SimpleXMLRPCServer now supports CGI through the CGIXMLRPCRequestHandler
+  class.
+
+- The sets module now raises TypeError in __cmp__, to clarify that
+  sets are not intended to be three-way-compared; the comparison
+  operators are overloaded as subset/superset tests.
+
+- Bastion.py and rexec.py are disabled.  These modules are not safe in
+  Python 2.2. or 2.3.
+
+- realpath is now exported when doing ``from poxixpath import *``.
+  It is also exported for ntpath, macpath, and os2emxpath.
+  See SF bug #659228.
+
+- New module tarfile from Lars Gustäbel provides a comprehensive interface
+  to tar archive files with transparent gzip and bzip2 compression.
+  See SF patch #651082.
+
+- urlparse can now parse imap:// URLs.  See SF feature request #618024.
+
+- Tkinter.Canvas.scan_dragto() provides an optional parameter to support
+  the gain value which is passed to Tk.  SF bug# 602259.
+
+- Fix logging.handlers.SysLogHandler protocol when using UNIX domain sockets.
+  See SF patch #642974.
+
+- The dospath module was deleted.  Use the ntpath module when manipulating
+  DOS paths from other platforms.
+
+Tools/Demos
+-----------
+
+- Two new scripts (db2pickle.py and pickle2db.py) were added to the
+  Tools/scripts directory to facilitate conversion from the old bsddb module
+  to the new one.  While the user-visible API of the new module is
+  compatible with the old one, it's likely that the version of the
+  underlying database library has changed.  To convert from the old library,
+  run the db2pickle.py script using the old version of Python to convert it
+  to a pickle file.  After upgrading Python, run the pickle2db.py script
+  using the new version of Python to reconstitute your database.  For
+  example:
+
+    % python2.2 db2pickle.py -h some.db > some.pickle
+    % python2.3 pickle2db.py -h some.db.new < some.pickle
+
+  Run the scripts without any args to get a usage message.
+
+
+Build
+-----
+
+- The audio driver tests (test_ossaudiodev.py and
+  test_linuxaudiodev.py) are no longer run by default.  This is
+  because they don't always work, depending on your hardware and
+  software.  To run these tests, you must use an invocation like ::
+
+    ./python Lib/test/regrtest.py -u audio test_ossaudiodev
+
+- On systems which build using the configure script, compiler flags which
+  used to be lumped together using the OPT flag have been split into two
+  groups, OPT and BASECFLAGS.  OPT is meant to carry just optimization- and
+  debug-related flags like "-g" and "-O3".  BASECFLAGS is meant to carry
+  compiler flags that are required to get a clean compile.  On some
+  platforms (many Linux flavors in particular) BASECFLAGS will be empty by
+  default.  On others, such as Mac OS X and SCO, it will contain required
+  flags.  This change allows people building Python to override OPT without
+  fear of clobbering compiler flags which are required to get a clean build.
+
+- On Darwin/Mac OS X platforms, /sw/lib and /sw/include are added to the
+  relevant search lists in setup.py.  This allows users building Python to
+  take advantage of the many packages available from the fink project
+  <http://fink.sf.net/>.
+
+- A new Makefile target, scriptsinstall, installs a number of useful scripts
+  from the Tools/scripts directory.
+
+C API
+-----
+
+- PyEval_GetFrame() is now declared to return a ``PyFrameObject *``
+  instead of a plain ``PyObject *``.  (SF patch #686601.)
+
+- PyNumber_Check() now checks that the object has a nb_int or nb_float
+  slot, rather than simply checking whether it has a non-NULL
+  tp_as_number pointer.
+
+- A C type that inherits from a base type that defines tp_as_buffer
+  will now inherit the tp_as_buffer pointer if it doesn't define one.
+  (SF #681367)
+
+- The PyArg_Parse functions now issue a DeprecationWarning if a float
+  argument is provided when an integer is specified (this affects the 'b',
+  'B', 'h', 'H', 'i', and 'l' codes).  Future versions of Python will
+  raise a TypeError.
+
+Tests
+-----
+
+- Several tests weren't being run from regrtest.py (test_timeout.py,
+  test_tarfile.py, test_netrc.py, test_multifile.py,
+  test_importhooks.py and test_imp.py).  Now they are.  (Note to
+  developers: please read Lib/test/README when creating a new test, to
+  make sure to do it right!  All tests need to use either unittest or
+  pydoc.)
+
+- Added test_posix.py, a test suite for the posix module.
+
+- Added test_hexoct.py, a test suite for hex/oct constant folding.
+
+Windows
+-------
+
+- The timeout code for socket connect() didn't work right; this has
+  now been fixed.  test_timeout.py should pass (at least most of the
+  time).
+
+- distutils' msvccompiler class now passes the preprocessor options to
+  the resource compiler.  See SF patch #669198.
+
+- The bsddb module now ships with Sleepycat's 4.1.25.NC, the latest
+  release without strong cryptography.
+
+- sys.path[0], if it contains a directory name, is now always an
+  absolute pathname. (SF patch #664376.)
+
+- The new logging package is now installed by the Windows installer.  It
+  wasn't in 2.3a1 due to oversight.
+
+Mac
+---
+
+- There are new dialogs EasyDialogs.AskFileForOpen, AskFileForSave
+  and AskFolder. The old macfs.StandardGetFile and friends are deprecated.
+
+- Most of the standard library now uses pathnames or FSRefs in preference
+  of FSSpecs, and use the underlying Carbon.File and Carbon.Folder modules
+  in stead of macfs. macfs will probably be deprecated in the future.
+
+- Type Carbon.File.FSCatalogInfo and supporting methods have been implemented.
+  This also makes macfs.FSSpec.SetDates() work again.
+
+- There is a new module pimp, the package install manager for Python, and
+  accompanying applet PackageManager. These allow you to easily download
+  and install pretested extension packages either in source or binary
+  form. Only in MacPython-OSX.
+
+- Applets are now built with bundlebuilder in MacPython-OSX, which should make
+  them more robust and also provides a path towards BuildApplication. The
+  downside of this change is that applets can no longer be run from the
+  Terminal window, this will hopefully be fixed in the 2.3b1.
+
+
+What's New in Python 2.3 alpha 1?
+=================================
+
+*Release date: 31-Dec-2002*
+
+Type/class unification and new-style classes
+--------------------------------------------
+
+- One can now assign to __bases__ and __name__ of new-style classes.
+
+- dict() now accepts keyword arguments so that dict(one=1, two=2)
+  is the equivalent of {"one": 1, "two": 2}.  Accordingly,
+  the existing (but undocumented) 'items' keyword argument has
+  been eliminated.  This means that dict(items=someMapping) now has
+  a different meaning than before.
+
+- int() now returns a long object if the argument is outside the
+  integer range, so int("4" * 1000), int(1e200) and int(1L<<1000) will
+  all return long objects instead of raising an OverflowError.
+
+- Assignment to __class__ is disallowed if either the old or the new
+  class is a statically allocated type object (such as defined by an
+  extension module).  This prevents anomalies like 2.__class__ = bool.
+
+- New-style object creation and deallocation have been sped up
+  significantly; they are now faster than classic instance creation
+  and deallocation.
+
+- The __slots__ variable can now mention "private" names, and the
+  right thing will happen (e.g. __slots__ = ["__foo"]).
+
+- The built-ins slice() and buffer() are now callable types.  The
+  types classobj (formerly class), code, function, instance, and
+  instancemethod (formerly instance-method), which have no built-in
+  names but are accessible through the types module, are now also
+  callable.  The type dict-proxy is renamed to dictproxy.
+
+- Cycles going through the __class__ link of a new-style instance are
+  now detected by the garbage collector.
+
+- Classes using __slots__ are now properly garbage collected.
+  [SF bug 519621]
+
+- Tightened the __slots__ rules: a slot name must be a valid Python
+  identifier.
+
+- The constructor for the module type now requires a name argument and
+  takes an optional docstring argument.  Previously, this constructor
+  ignored its arguments.  As a consequence, deriving a class from a
+  module (not from the module type) is now illegal; previously this
+  created an unnamed module, just like invoking the module type did.
+  [SF bug 563060]
+
+- A new type object, 'basestring', is added.  This is a common base type
+  for 'str' and 'unicode', and can be used instead of
+  types.StringTypes, e.g. to test whether something is "a string":
+  isinstance(x, basestring) is True for Unicode and 8-bit strings.  This
+  is an abstract base class and cannot be instantiated directly.
+
+- Changed new-style class instantiation so that when C's __new__
+  method returns something that's not a C instance, its __init__ is
+  not called.  [SF bug #537450]
+
+- Fixed super() to work correctly with class methods.  [SF bug #535444]
+
+- If you try to pickle an instance of a class that has __slots__ but
+  doesn't define or override __getstate__, a TypeError is now raised.
+  This is done by adding a bozo __getstate__ to the class that always
+  raises TypeError.  (Before, this would appear to be pickled, but the
+  state of the slots would be lost.)
+
+Core and builtins
+-----------------
+
+- Import from zipfiles is now supported.  The name of a zipfile placed
+  on sys.path causes the import statement to look for importable Python
+  modules (with .py, pyc and .pyo extensions) and packages inside the
+  zipfile.  The zipfile import follows the specification (though not
+  the sample implementation) of PEP 273.  The semantics of __path__ are
+  compatible with those that have been implemented in Jython since
+  Jython 2.1.
+
+- PEP 302 has been accepted.  Although it was initially developed to
+  support zipimport, it offers a new, general import hook mechanism.
+  Several new variables have been added to the sys module:
+  sys.meta_path, sys.path_hooks, and sys.path_importer_cache; these
+  make extending the import statement much more convenient than
+  overriding the __import__ built-in function.  For a description of
+  these, see PEP 302.
+
+- A frame object's f_lineno attribute can now be written to from a
+  trace function to change which line will execute next.  A command to
+  exploit this from pdb has been added.  [SF patch #643835]
+
+- The _codecs support module for codecs.py was turned into a builtin
+  module to assure that at least the builtin codecs are available
+  to the Python parser for source code decoding according to PEP 263.
+
+- issubclass now supports a tuple as the second argument, just like
+  isinstance does. ``issubclass(X, (A, B))`` is equivalent to
+  ``issubclass(X, A) or issubclass(X, B)``.
+
+- Thanks to Armin Rigo, the last known way to provoke a system crash
+  by cleverly arranging for a comparison function to mutate a list
+  during a list.sort() operation has been fixed.  The effect of
+  attempting to mutate a list, or even to inspect its contents or
+  length, while a sort is in progress, is not defined by the language.
+  The C implementation of Python 2.3 attempts to detect mutations,
+  and raise ValueError if one occurs, but there's no guarantee that
+  all mutations will be caught, or that any will be caught across
+  releases or implementations.
+
+- Unicode file name processing for Windows (PEP 277) is implemented.
+  All platforms now have an os.path.supports_unicode_filenames attribute,
+  which is set to True on Windows NT/2000/XP, and False elsewhere.
+
+- Codec error handling callbacks (PEP 293) are implemented.
+  Error handling in unicode.encode or str.decode can now be customized.
+
+- A subtle change to the semantics of the built-in function intern():
+  interned strings are no longer immortal.  You must keep a reference
+  to the return value intern() around to get the benefit.
+
+- Use of 'None' as a variable, argument or attribute name now
+  issues a SyntaxWarning.  In the future, None may become a keyword.
+
+- SET_LINENO is gone.  co_lnotab is now consulted to determine when to
+  call the trace function.  C code that accessed f_lineno should call
+  PyCode_Addr2Line instead (f_lineno is still there, but only kept up
+  to date when there is a trace function set).
+
+- There's a new warning category, FutureWarning.  This is used to warn
+  about a number of situations where the value or sign of an integer
+  result will change in Python 2.4 as a result of PEP 237 (integer
+  unification).  The warnings implement stage B0 mentioned in that
+  PEP.  The warnings are about the following situations:
+
+    - Octal and hex literals without 'L' prefix in the inclusive range
+      [0x80000000..0xffffffff]; these are currently negative ints, but
+      in Python 2.4 they will be positive longs with the same bit
+      pattern.
+
+    - Left shifts on integer values that cause the outcome to lose
+      bits or have a different sign than the left operand.  To be
+      precise: x<<n where this currently doesn't yield the same value
+      as long(x)<<n; in Python 2.4, the outcome will be long(x)<<n.
+
+    - Conversions from ints to string that show negative values as
+      unsigned ints in the inclusive range [0x80000000..0xffffffff];
+      this affects the functions hex() and oct(), and the string
+      formatting codes %u, %o, %x, and %X.  In Python 2.4, these will
+      show signed values (e.g. hex(-1) currently returns "0xffffffff";
+      in Python 2.4 it will return "-0x1").
+
+- The bits manipulated under the cover by sys.setcheckinterval() have
+  been changed.  Both the check interval and the ticker used to be
+  per-thread values.  They are now just a pair of global variables.
+  In addition, the default check interval was boosted from 10 to 100
+  bytecode instructions.  This may have some effect on systems that
+  relied on the old default value.  In particular, in multi-threaded
+  applications which try to be highly responsive, response time will
+  increase by some (perhaps imperceptible) amount.
+
+- When multiplying very large integers, a version of the so-called
+  Karatsuba algorithm is now used.  This is most effective if the
+  inputs have roughly the same size.  If they both have about N digits,
+  Karatsuba multiplication has O(N**1.58) runtime (the exponent is
+  log_base_2(3)) instead of the previous O(N**2).  Measured results may
+  be better or worse than that, depending on platform quirks.  Besides
+  the O() improvement in raw instruction count, the Karatsuba algorithm
+  appears to have much better cache behavior on extremely large integers
+  (starting in the ballpark of a million bits).  Note that this is a
+  simple implementation, and there's no intent here to compete with,
+  e.g., GMP.  It gives a very nice speedup when it applies, but a package
+  devoted to fast large-integer arithmetic should run circles around it.
+
+- u'%c' will now raise a ValueError in case the argument is an
+  integer outside the valid range of Unicode code point ordinals.
+
+- The tempfile module has been overhauled for enhanced security.  The
+  mktemp() function is now deprecated; new, safe replacements are
+  mkstemp() (for files) and mkdtemp() (for directories), and the
+  higher-level functions NamedTemporaryFile() and TemporaryFile().
+  Use of some global variables in this module is also deprecated; the
+  new functions have keyword arguments to provide the same
+  functionality.  All Lib, Tools and Demo modules that used the unsafe
+  interfaces have been updated to use the safe replacements.  Thanks
+  to Zack Weinberg!
+
+- When x is an object whose class implements __mul__ and __rmul__,
+  1.0*x would correctly invoke __rmul__, but 1*x would erroneously
+  invoke __mul__.  This was due to the sequence-repeat code in the int
+  type.  This has been fixed now.
+
+- Previously, "str1 in str2" required str1 to be a string of length 1.
+  This restriction has been relaxed to allow str1 to be a string of
+  any length.  Thus "'el' in 'hello world'" returns True now.
+
+- File objects are now their own iterators.  For a file f, iter(f) now
+  returns f (unless f is closed), and f.next() is similar to
+  f.readline() when EOF is not reached; however, f.next() uses a
+  readahead buffer that messes up the file position, so mixing
+  f.next() and f.readline() (or other methods) doesn't work right.
+  Calling f.seek() drops the readahead buffer, but other operations
+  don't.  It so happens that this gives a nice additional speed boost
+  to "for line in file:"; the xreadlines method and corresponding
+  module are now obsolete.  Thanks to Oren Tirosh!
+
+- Encoding declarations (PEP 263, phase 1) have been implemented.  A
+  comment of the form "# -*- coding: <encodingname> -*-" in the first
+  or second line of a Python source file indicates the encoding.
+
+- list.sort() has a new implementation.  While cross-platform results
+  may vary, and in data-dependent ways, this is much faster on many
+  kinds of partially ordered lists than the previous implementation,
+  and reported to be just as fast on randomly ordered lists on
+  several major platforms.  This sort is also stable (if A==B and A
+  precedes B in the list at the start, A precedes B after the sort too),
+  although the language definition does not guarantee stability.  A
+  potential drawback is that list.sort() may require temp space of
+  len(list)*2 bytes (``*4`` on a 64-bit machine).  It's therefore possible
+  for list.sort() to raise MemoryError now, even if a comparison function
+  does not.  See <http://www.python.org/sf/587076> for full details.
+
+- All standard iterators now ensure that, once StopIteration has been
+  raised, all future calls to next() on the same iterator will also
+  raise StopIteration.  There used to be various counterexamples to
+  this behavior, which could caused confusion or subtle program
+  breakage, without any benefits.  (Note that this is still an
+  iterator's responsibility; the iterator framework does not enforce
+  this.)
+
+- Ctrl+C handling on Windows has been made more consistent with
+  other platforms.  KeyboardInterrupt can now reliably be caught,
+  and Ctrl+C at an interactive prompt no longer terminates the
+  process under NT/2k/XP (it never did under Win9x).  Ctrl+C will
+  interrupt time.sleep() in the main thread, and any child processes
+  created via the popen family (on win2k; we can't make win9x work
+  reliably) are also interrupted (as generally happens on for Linux/Unix.)
+  [SF bugs 231273, 439992 and 581232]
+
+- sys.getwindowsversion() has been added on Windows.  This
+  returns a tuple with information about the version of Windows
+  currently running.
+
+- Slices and repetitions of buffer objects now consistently return
+  a string.  Formerly, strings would be returned most of the time,
+  but a buffer object would be returned when the repetition count
+  was one or when the slice range was all inclusive.
+
+- Unicode objects in sys.path are no longer ignored but treated
+  as directory names.
+
+- Fixed string.startswith and string.endswith builtin methods
+  so they accept negative indices.  [SF bug 493951]
+
+- Fixed a bug with a continue inside a try block and a yield in the
+  finally clause.  [SF bug 567538]
+
+- Most builtin sequences now support "extended slices", i.e. slices
+  with a third "stride" parameter.  For example, "hello world"[::-1]
+  gives "dlrow olleh".
+
+- A new warning PendingDeprecationWarning was added to provide
+  direction on features which are in the process of being deprecated.
+  The warning will not be printed by default.  To see the pending
+  deprecations, use -Walways::PendingDeprecationWarning::
+  as a command line option or warnings.filterwarnings() in code.
+
+- Deprecated features of xrange objects have been removed as
+  promised.  The start, stop, and step attributes and the tolist()
+  method no longer exist.  xrange repetition and slicing have been
+  removed.
+
+- New builtin function enumerate(x), from PEP 279.  Example:
+  enumerate("abc") is an iterator returning (0,"a"), (1,"b"), (2,"c").
+  The argument can be an arbitrary iterable object.
+
+- The assert statement no longer tests __debug__ at runtime.  This means
+  that assert statements cannot be disabled by assigning a false value
+  to __debug__.
+
+- A method zfill() was added to str and unicode, that fills a numeric
+  string to the left with zeros.  For example,
+  "+123".zfill(6) -> "+00123".
+
+- Complex numbers supported divmod() and the // and % operators, but
+  these make no sense.  Since this was documented, they're being
+  deprecated now.
+
+- String and unicode methods lstrip(), rstrip() and strip() now take
+  an optional argument that specifies the characters to strip.  For
+  example, "Foo!!!?!?!?".rstrip("?!") -> "Foo".
+
+- There's a new dictionary constructor (a class method of the dict
+  class), dict.fromkeys(iterable, value=None).  It constructs a
+  dictionary with keys taken from the iterable and all values set to a
+  single value.  It can be used for building sets and for removing
+  duplicates from sequences.
+
+- Added a new dict method pop(key).  This removes and returns the
+  value corresponding to key.  [SF patch #539949]
+
+- A new built-in type, bool, has been added, as well as built-in
+  names for its two values, True and False.  Comparisons and sundry
+  other operations that return a truth value have been changed to
+  return a bool instead.  Read PEP 285 for an explanation of why this
+  is backward compatible.
+
+- Fixed two bugs reported as SF #535905: under certain conditions,
+  deallocating a deeply nested structure could cause a segfault in the
+  garbage collector, due to interaction with the "trashcan" code;
+  access to the current frame during destruction of a local variable
+  could access a pointer to freed memory.
+
+- The optional object allocator ("pymalloc") has been enabled by
+  default.  The recommended practice for memory allocation and
+  deallocation has been streamlined.  A header file is included,
+  Misc/pymemcompat.h, which can be bundled with 3rd party extensions
+  and lets them use the same API with Python versions from 1.5.2
+  onwards.
+
+- PyErr_Display will provide file and line information for all exceptions
+  that have an attribute print_file_and_line, not just SyntaxErrors.
+
+- The UTF-8 codec will now encode and decode Unicode surrogates
+  correctly and without raising exceptions for unpaired ones.
+
+- Universal newlines (PEP 278) is implemented.  Briefly, using 'U'
+  instead of 'r' when opening a text file for reading changes the line
+  ending convention so that any of '\r', '\r\n', and '\n' is
+  recognized (even mixed in one file); all three are converted to
+  '\n', the standard Python line end character.
+
+- file.xreadlines() now raises a ValueError if the file is closed:
+  Previously, an xreadlines object was returned which would raise
+  a ValueError when the xreadlines.next() method was called.
+
+- sys.exit() inadvertently allowed more than one argument.
+  An exception will now be raised if more than one argument is used.
+
+- Changed evaluation order of dictionary literals to conform to the
+  general left to right evaluation order rule. Now {f1(): f2()} will
+  evaluate f1 first.
+
+- Fixed bug #521782: when a file was in non-blocking mode, file.read()
+  could silently lose data or wrongly throw an unknown error.
+
+- The sq_repeat, sq_inplace_repeat, sq_concat and sq_inplace_concat
+  slots are now always tried after trying the corresponding nb_* slots.
+  This fixes a number of minor bugs (see bug #624807).
+
+- Fix problem with dynamic loading on 64-bit AIX (see bug #639945).
+
+Extension modules
+-----------------
+
+- Added three operators to the operator module:
+    operator.pow(a,b) which is equivalent to:  a**b.
+    operator.is_(a,b) which is equivalent to:  a is b.
+    operator.is_not(a,b) which is equivalent to:  a is not b.
+
+- posix.openpty now works on all systems that have /dev/ptmx.
+
+- A module zipimport exists to support importing code from zip
+  archives.
+
+- The new datetime module supplies classes for manipulating dates and
+  times.  The basic design came from the Zope "fishbowl process", and
+  favors practical commercial applications over calendar esoterica.  See
+
+      http://www.zope.org/Members/fdrake/DateTimeWiki/FrontPage
+
+- _tkinter now returns Tcl objects, instead of strings. Objects which
+  have Python equivalents are converted to Python objects, other objects
+  are wrapped. This can be configured through the wantobjects method,
+  or Tkinter.wantobjects.
+
+- The PyBSDDB wrapper around the Sleepycat Berkeley DB library has
+  been added as the package bsddb.  The traditional bsddb module is
+  still available in source code, but not built automatically anymore,
+  and is now named bsddb185.  This supports Berkeley DB versions from
+  3.0 to 4.1.  For help converting your databases from the old module (which
+  probably used an obsolete version of Berkeley DB) to the new module, see
+  the db2pickle.py and pickle2db.py scripts described in the Tools/Demos
+  section above.
+
+- unicodedata was updated to Unicode 3.2. It supports normalization
+  and names for Hangul syllables and CJK unified ideographs.
+
+- resource.getrlimit() now returns longs instead of ints.
+
+- readline now dynamically adjusts its input/output stream if
+  sys.stdin/stdout changes.
+
+- The _tkinter module (and hence Tkinter) has dropped support for
+  Tcl/Tk 8.0 and 8.1.  Only Tcl/Tk versions 8.2, 8.3 and 8.4 are
+  supported.
+
+- cPickle.BadPickleGet is now a class.
+
+- The time stamps in os.stat_result are floating point numbers
+  after stat_float_times has been called.
+
+- If the size passed to mmap.mmap() is larger than the length of the
+  file on non-Windows platforms, a ValueError is raised. [SF bug 585792]
+
+- The xreadlines module is slated for obsolescence.
+
+- The strptime function in the time module is now always available (a
+  Python implementation is used when the C library doesn't define it).
+
+- The 'new' module is no longer an extension, but a Python module that
+  only exists for backwards compatibility.  Its contents are no longer
+  functions but callable type objects.
+
+- The bsddb.*open functions can now take 'None' as a filename.
+  This will create a temporary in-memory bsddb that won't be
+  written to disk.
+
+- posix.getloadavg, posix.lchown, posix.killpg, posix.mknod, and
+  posix.getpgid have been added where available.
+
+- The locale module now exposes the C library's gettext interface. It
+  also has a new function getpreferredencoding.
+
+- A security hole ("double free") was found in zlib-1.1.3, a popular
+  third party compression library used by some Python modules.  The
+  hole was quickly plugged in zlib-1.1.4, and the Windows build of
+  Python now ships with zlib-1.1.4.
+
+- pwd, grp, and resource return enhanced tuples now, with symbolic
+  field names.
+
+- array.array is now a type object. A new format character
+  'u' indicates Py_UNICODE arrays. For those, .tounicode and
+  .fromunicode methods are available. Arrays now support __iadd__
+  and __imul__.
+
+- dl now builds on every system that has dlfcn.h.  Failure in case
+  of sizeof(int)!=sizeof(long)!=sizeof(void*) is delayed until dl.open
+  is called.
+
+- The sys module acquired a new attribute, api_version, which evaluates
+  to the value of the PYTHON_API_VERSION macro with which the
+  interpreter was compiled.
+
+- Fixed bug #470582: sre module would return a tuple (None, 'a', 'ab')
+  when applying the regular expression '^((a)c)?(ab)$' on 'ab'. It now
+  returns (None, None, 'ab'), as expected. Also fixed handling of
+  lastindex/lastgroup match attributes in similar cases. For example,
+  when running the expression r'(a)(b)?b' over 'ab', lastindex must be
+  1, not 2.
+
+- Fixed bug #581080: sre scanner was not checking the buffer limit
+  before increasing the current pointer. This was creating an infinite
+  loop in the search function, once the pointer exceeded the buffer
+  limit.
+
+- The os.fdopen function now enforces a file mode starting with the
+  letter 'r', 'w' or 'a', otherwise a ValueError is raised. This fixes
+  bug #623464.
+
+- The linuxaudiodev module is now deprecated; it is being replaced by
+  ossaudiodev.  The interface has been extended to cover a lot more of
+  OSS (see www.opensound.com), including most DSP ioctls and the
+  OSS mixer API.  Documentation forthcoming in 2.3a2.
+
+Library
+-------
+
+- imaplib.py now supports SSL (Tino Lange and Piers Lauder).
+
+- Freeze's modulefinder.py has been moved to the standard library;
+  slightly improved so it will issue less false missing submodule
+  reports (see sf path #643711 for details).  Documentation will follow
+  with Python 2.3a2.
+
+- os.path exposes getctime.
+
+- unittest.py now has two additional methods called assertAlmostEqual()
+  and failIfAlmostEqual().  They implement an approximate comparison
+  by rounding the difference between the two arguments and comparing
+  the result to zero.  Approximate comparison is essential for
+  unit tests of floating point results.
+
+- calendar.py now depends on the new datetime module rather than
+  the time module.  As a result, the range of allowable dates
+  has been increased.
+
+- pdb has a new 'j(ump)' command to select the next line to be
+  executed.
+
+- The distutils created windows installers now can run a
+  postinstallation script.
+
+- doctest.testmod can now be called without argument, which means to
+  test the current module.
+
+- When canceling a server that implemented threading with a keyboard
+  interrupt, the server would shut down but not terminate (waiting on
+  client threads). A new member variable, daemon_threads, was added to
+  the ThreadingMixIn class in SocketServer.py to make it explicit that
+  this behavior needs to be controlled.
+
+- A new module, optparse, provides a fancy alternative to getopt for
+  command line parsing.  It is a slightly modified version of Greg
+  Ward's Optik package.
+
+- UserDict.py now defines a DictMixin class which defines all dictionary
+  methods for classes that already have a minimum mapping interface.
+  This greatly simplifies writing classes that need to be substitutable
+  for dictionaries (such as the shelve module).
+
+- shelve.py now subclasses from UserDict.DictMixin.  Now shelve supports
+  all dictionary methods.  This eases the transition to persistent
+  storage for scripts originally written with dictionaries in mind.
+
+- shelve.open and the various classes in shelve.py now accept an optional
+  binary flag, which defaults to False.  If True, the values stored in the
+  shelf are binary pickles.
+
+- A new package, logging, implements the logging API defined by PEP
+  282.  The code is written by Vinay Sajip.
+
+- StreamReader, StreamReaderWriter and StreamRecoder in the codecs
+  modules are iterators now.
+
+- gzip.py now handles files exceeding 2GB.  Files over 4GB also work
+  now (provided the OS supports it, and Python is configured with large
+  file support), but in that case the underlying gzip file format can
+  record only the least-significant 32 bits of the file size, so that
+  some tools working with gzipped files may report an incorrect file
+  size.
+
+- xml.sax.saxutils.unescape has been added, to replace entity references
+  with their entity value.
+
+- Queue.Queue.{put,get} now support an optional timeout argument.
+
+- Various features of Tk 8.4 are exposed in Tkinter.py. The multiple
+  option of tkFileDialog is exposed as function askopenfile{,name}s.
+
+- Various configure methods of Tkinter have been stream-lined, so that
+  tag_configure, image_configure, window_configure now return a
+  dictionary when invoked with no argument.
+
+- Importing the readline module now no longer has the side effect of
+  calling setlocale(LC_CTYPE, "").  The initial "C" locale, or
+  whatever locale is explicitly set by the user, is preserved.  If you
+  want repr() of 8-bit strings in your preferred encoding to preserve
+  all printable characters of that encoding, you have to add the
+  following code to your $PYTHONSTARTUP file or to your application's
+  main():
+
+    import locale
+    locale.setlocale(locale.LC_CTYPE, "")
+
+- shutil.move was added. shutil.copytree now reports errors as an
+  exception at the end, instead of printing error messages.
+
+- Encoding name normalization was generalized to not only
+  replace hyphens with underscores, but also all other non-alphanumeric
+  characters (with the exception of the dot which is used for Python
+  package names during lookup). The aliases.py mapping was updated
+  to the new standard.
+
+- mimetypes has two new functions: guess_all_extensions() which
+  returns a list of all known extensions for a mime type, and
+  add_type() which adds one mapping between a mime type and
+  an extension to the database.
+
+- New module: sets, defines the class Set that implements a mutable
+  set type using the keys of a dict to represent the set.  There's
+  also a class ImmutableSet which is useful when you need sets of sets
+  or when you need to use sets as dict keys, and a class BaseSet which
+  is the base class of the two.
+
+- Added random.sample(population,k) for random sampling without replacement.
+  Returns a k length list of unique elements chosen from the population.
+
+- random.randrange(-sys.maxint-1, sys.maxint) no longer raises
+  OverflowError.  That is, it now accepts any combination of 'start'
+  and 'stop' arguments so long as each is in the range of Python's
+  bounded integers.
+
+- Thanks to Raymond Hettinger, random.random() now uses a new core
+  generator.  The Mersenne Twister algorithm is implemented in C,
+  threadsafe, faster than the previous generator, has an astronomically
+  large period (2**19937-1), creates random floats to full 53-bit
+  precision, and may be the most widely tested random number generator
+  in existence.
+
+  The random.jumpahead(n) method has different semantics for the new
+  generator.  Instead of jumping n steps ahead, it uses n and the
+  existing state to create a new state.  This means that jumpahead()
+  continues to support multi-threaded code needing generators of
+  non-overlapping sequences.  However, it will break code which relies
+  on jumpahead moving a specific number of steps forward.
+
+  The attributes random.whseed and random.__whseed have no meaning for
+  the new generator.  Code using these attributes should switch to a
+  new class, random.WichmannHill which is provided for backward
+  compatibility and to make an alternate generator available.
+
+- New "algorithms" module: heapq, implements a heap queue.  Thanks to
+  Kevin O'Connor for the code and François Pinard for an entertaining
+  write-up explaining the theory and practical uses of heaps.
+
+- New encoding for the Palm OS character set: palmos.
+
+- binascii.crc32() and the zipfile module had problems on some 64-bit
+  platforms.  These have been fixed.  On a platform with 8-byte C longs,
+  crc32() now returns a signed-extended 4-byte result, so that its value
+  as a Python int is equal to the value computed a 32-bit platform.
+
+- xml.dom.minidom.toxml and toprettyxml now take an optional encoding
+  argument.
+
+- Some fixes in the copy module: when an object is copied through its
+  __reduce__ method, there was no check for a __setstate__ method on
+  the result [SF patch 565085]; deepcopy should treat instances of
+  custom metaclasses the same way it treats instances of type 'type'
+  [SF patch 560794].
+
+- Sockets now support timeout mode.  After s.settimeout(T), where T is
+  a float expressing seconds, subsequent operations raise an exception
+  if they cannot be completed within T seconds.  To disable timeout
+  mode, use s.settimeout(None).  There's also a module function,
+  socket.setdefaulttimeout(T), which sets the default for all sockets
+  created henceforth.
+
+- getopt.gnu_getopt was added.  This supports GNU-style option
+  processing, where options can be mixed with non-option arguments.
+
+- Stop using strings for exceptions.  String objects used for
+  exceptions are now classes deriving from Exception.  The objects
+  changed were: Tkinter.TclError, bdb.BdbQuit, macpath.norm_error,
+  tabnanny.NannyNag, and xdrlib.Error.
+
+- Constants BOM_UTF8, BOM_UTF16, BOM_UTF16_LE, BOM_UTF16_BE,
+  BOM_UTF32, BOM_UTF32_LE and BOM_UTF32_BE that represent the Byte
+  Order Mark in UTF-8, UTF-16 and UTF-32 encodings for little and
+  big endian systems were added to the codecs module. The old names
+  BOM32_* and BOM64_* were off by a factor of 2.
+
+- Added conversion functions math.degrees() and math.radians().
+
+- math.log() now takes an optional argument:  math.log(x[, base]).
+
+- ftplib.retrlines() now tests for callback is None rather than testing
+  for False.  Was causing an error when given a callback object which
+  was callable but also returned len() as zero.  The change may
+  create new breakage if the caller relied on the undocumented behavior
+  and called with callback set to [] or some other False value not
+  identical to None.
+
+- random.gauss() uses a piece of hidden state used by nothing else,
+  and the .seed() and .whseed() methods failed to reset it.  In other
+  words, setting the seed didn't completely determine the sequence of
+  results produced by random.gauss().  It does now.  Programs repeatedly
+  mixing calls to a seed method with calls to gauss() may see different
+  results now.
+
+- The pickle.Pickler class grew a clear_memo() method to mimic that
+  provided by cPickle.Pickler.
+
+- difflib's SequenceMatcher class now does a dynamic analysis of
+  which elements are so frequent as to constitute noise.  For
+  comparing files as sequences of lines, this generally works better
+  than the IS_LINE_JUNK function, and function ndiff's linejunk
+  argument defaults to None now as a result.  A happy benefit is
+  that SequenceMatcher may run much faster now when applied
+  to large files with many duplicate lines (for example, C program
+  text with lots of repeated "}" and "return NULL;" lines).
+
+- New Text.dump() method in Tkinter module.
+
+- New distutils commands for building packagers were added to
+  support pkgtool on Solaris and swinstall on HP-UX.
+
+- distutils now has a new abstract binary packager base class
+  command/bdist_packager, which simplifies writing packagers.
+  This will hopefully provide the missing bits to encourage
+  people to submit more packagers, e.g. for Debian, FreeBSD
+  and other systems.
+
+- The UTF-16, -LE and -BE stream readers now raise a
+  NotImplementedError for all calls to .readline(). Previously, they
+  used to just produce garbage or fail with an encoding error --
+  UTF-16 is a 2-byte encoding and the C lib's line reading APIs don't
+  work well with these.
+
+- compileall now supports quiet operation.
+
+- The BaseHTTPServer now implements optional HTTP/1.1 persistent
+  connections.
+
+- socket module: the SSL support was broken out of the main
+  _socket module C helper and placed into a new _ssl helper
+  which now gets imported by socket.py if available and working.
+
+- encodings package: added aliases for all supported IANA character
+  sets
+
+- ftplib: to safeguard the user's privacy, anonymous login will use
+  "anonymous@" as default password, rather than the real user and host
+  name.
+
+- webbrowser: tightened up the command passed to os.system() so that
+  arbitrary shell code can't be executed because a bogus URL was
+  passed in.
+
+- gettext.translation has an optional fallback argument, and
+  gettext.find an optional all argument. Translations will now fallback
+  on a per-message basis. The module supports plural forms, by means
+  of gettext.[d]ngettext and Translation.[u]ngettext.
+
+- distutils bdist commands now offer a --skip-build option.
+
+- warnings.warn now accepts a Warning instance as first argument.
+
+- The xml.sax.expatreader.ExpatParser class will no longer create
+  circular references by using itself as the locator that gets passed
+  to the content handler implementation.  [SF bug #535474]
+
+- The email.Parser.Parser class now properly parses strings regardless
+  of their line endings, which can be any of \r, \n, or \r\n (CR, LF,
+  or CRLF).  Also, the Header class's constructor default arguments
+  has changed slightly so that an explicit maxlinelen value is always
+  honored, and so unicode conversion error handling can be specified.
+
+- distutils' build_ext command now links C++ extensions with the C++
+  compiler available in the Makefile or CXX environment variable, if
+  running under \*nix.
+
+- New module bz2: provides a comprehensive interface for the bz2 compression
+  library.  It implements a complete file interface, one-shot (de)compression
+  functions, and types for sequential (de)compression.
+
+- New pdb command 'pp' which is like 'p' except that it pretty-prints
+  the value of its expression argument.
+
+- Now bdist_rpm distutils command understands a verify_script option in
+  the config file, including the contents of the referred filename in
+  the "%verifyscript" section of the rpm spec file.
+
+- Fixed bug #495695: webbrowser module would run graphic browsers in a
+  unix environment even if DISPLAY was not set. Also, support for
+  skipstone browser was included.
+
+- Fixed bug #636769: rexec would run unallowed code if subclasses of
+  strings were used as parameters for certain functions.
+
+Tools/Demos
+-----------
+
+- pygettext.py now supports globbing on Windows, and accepts module
+  names in addition to accepting file names.
+
+- The SGI demos (Demo/sgi) have been removed.  Nobody thought they
+  were interesting any more.  (The SGI library modules and extensions
+  are still there; it is believed that at least some of these are
+  still used and useful.)
+
+- IDLE supports the new encoding declarations (PEP 263); it can also
+  deal with legacy 8-bit files if they use the locale's encoding. It
+  allows non-ASCII strings in the interactive shell and executes them
+  in the locale's encoding.
+
+- freeze.py now produces binaries which can import shared modules,
+  unlike before when this failed due to missing symbol exports in
+  the generated binary.
+
+Build
+-----
+
+- On Unix, IDLE is now installed automatically.
+
+- The fpectl module is not built by default; it's dangerous or useless
+  except in the hands of experts.
+
+- The public Python C API will generally be declared using PyAPI_FUNC
+  and PyAPI_DATA macros, while Python extension module init functions
+  will be declared with PyMODINIT_FUNC.  DL_EXPORT/DL_IMPORT macros
+  are deprecated.
+
+- A bug was fixed that could cause COUNT_ALLOCS builds to segfault, or
+  get into infinite loops, when a new-style class got garbage-collected.
+  Unfortunately, to avoid this, the way COUNT_ALLOCS works requires
+  that new-style classes be immortal in COUNT_ALLOCS builds.  Note that
+  COUNT_ALLOCS is not enabled by default, in either release or debug
+  builds, and that new-style classes are immortal only in COUNT_ALLOCS
+  builds.
+
+- Compiling out the cyclic garbage collector is no longer an option.
+  The old symbol WITH_CYCLE_GC is now ignored, and Python.h arranges
+  that it's always defined (for the benefit of any extension modules
+  that may be conditionalizing on it).  A bonus is that any extension
+  type participating in cyclic gc can choose to participate in the
+  Py_TRASHCAN mechanism now too; in the absence of cyclic gc, this used
+  to require editing the core to teach the trashcan mechanism about the
+  new type.
+
+- According to Annex F of the current C standard,
+
+    The Standard C macro HUGE_VAL and its float and long double analogs,
+    HUGE_VALF and HUGE_VALL, expand to expressions whose values are
+    positive infinities.
+
+  Python only uses the double HUGE_VAL, and only to #define its own symbol
+  Py_HUGE_VAL.  Some platforms have incorrect definitions for HUGE_VAL.
+  pyport.h used to try to worm around that, but the workarounds triggered
+  other bugs on other platforms, so we gave up.  If your platform defines
+  HUGE_VAL incorrectly, you'll need to #define Py_HUGE_VAL to something
+  that works on your platform.  The only instance of this I'm sure about
+  is on an unknown subset of Cray systems, described here:
+
+  http://www.cray.com/swpubs/manuals/SN-2194_2.0/html-SN-2194_2.0/x3138.htm
+
+  Presumably 2.3a1 breaks such systems.  If anyone uses such a system, help!
+
+- The configure option --without-doc-strings can be used to remove the
+  doc strings from the builtin functions and modules; this reduces the
+  size of the executable.
+
+- The universal newlines option (PEP 278) is on by default.  On Unix
+  it can be disabled by passing --without-universal-newlines to the
+  configure script.  On other platforms, remove
+  WITH_UNIVERSAL_NEWLINES from pyconfig.h.
+
+- On Unix, a shared libpython2.3.so can be created with --enable-shared.
+
+- All uses of the CACHE_HASH, INTERN_STRINGS, and DONT_SHARE_SHORT_STRINGS
+  preprocessor symbols were eliminated.  The internal decisions they
+  controlled stopped being experimental long ago.
+
+- The tools used to build the documentation now work under Cygwin as
+  well as Unix.
+
+- The bsddb and dbm module builds have been changed to try and avoid version
+  skew problems and disable linkage with Berkeley DB 1.85 unless the
+  installer knows what s/he's doing.  See the section on building these
+  modules in the README file for details.
+
+C API
+-----
+
+- PyNumber_Check() now returns true for string and unicode objects.
+  This is a result of these types having a partially defined
+  tp_as_number slot.  (This is not a feature, but an indication that
+  PyNumber_Check() is not very useful to determine numeric behavior.
+  It may be deprecated.)
+
+- The string object's layout has changed: the pointer member
+  ob_sinterned has been replaced by an int member ob_sstate.  On some
+  platforms (e.g. most 64-bit systems) this may change the offset of
+  the ob_sval member, so as a precaution the API_VERSION has been
+  incremented.  The apparently unused feature of "indirect interned
+  strings", supported by the ob_sinterned member, is gone.  Interned
+  strings are now usually mortal; there is a new API,
+  PyString_InternImmortal() that creates immortal interned strings.
+  (The ob_sstate member can only take three values; however, while
+  making it a char saves a few bytes per string object on average, in
+  it also slowed things down a bit because ob_sval was no longer
+  aligned.)
+
+- The Py_InitModule*() functions now accept NULL for the 'methods'
+  argument.  Modules without global functions are becoming more common
+  now that factories can be types rather than functions.
+
+- New C API PyUnicode_FromOrdinal() which exposes unichr() at C
+  level.
+
+- New functions PyErr_SetExcFromWindowsErr() and
+  PyErr_SetExcFromWindowsErrWithFilename(). Similar to
+  PyErr_SetFromWindowsErrWithFilename() and
+  PyErr_SetFromWindowsErr(), but they allow to specify
+  the exception type to raise. Available on Windows.
+
+- Py_FatalError() is now declared as taking a const char* argument.  It
+  was previously declared without const.  This should not affect working
+  code.
+
+- Added new macro PySequence_ITEM(o, i) that directly calls
+  sq_item without rechecking that o is a sequence and without
+  adjusting for negative indices.
+
+- PyRange_New() now raises ValueError if the fourth argument is not 1.
+  This is part of the removal of deprecated features of the xrange
+  object.
+
+- PyNumber_Coerce() and PyNumber_CoerceEx() now also invoke the type's
+  coercion if both arguments have the same type but this type has the
+  CHECKTYPES flag set.  This is to better support proxies.
+
+- The type of tp_free has been changed from "``void (*)(PyObject *)``" to
+  "``void (*)(void *)``".
+
+- PyObject_Del, PyObject_GC_Del are now functions instead of macros.
+
+- A type can now inherit its metatype from its base type.  Previously,
+  when PyType_Ready() was called, if ob_type was found to be NULL, it
+  was always set to &PyType_Type; now it is set to base->ob_type,
+  where base is tp_base, defaulting to &PyObject_Type.
+
+- PyType_Ready() accidentally did not inherit tp_is_gc; now it does.
+
+- The PyCore_* family of APIs have been removed.
+
+- The "u#" parser marker will now pass through Unicode objects as-is
+  without going through the buffer API.
+
+- The enumerators of cmp_op have been renamed to use the prefix ``PyCmp_``.
+
+- An old #define of ANY as void has been removed from pyport.h.  This
+  hasn't been used since Python's pre-ANSI days, and the #define has
+  been marked as obsolete since then.  SF bug 495548 says it created
+  conflicts with other packages, so keeping it around wasn't harmless.
+
+- Because Python's magic number scheme broke on January 1st, we decided
+  to stop Python development.  Thanks for all the fish!
+
+- Some of us don't like fish, so we changed Python's magic number
+  scheme to a new one. See Python/import.c for details.
+
+New platforms
+-------------
+
+- OpenVMS is now supported.
+
+- AtheOS is now supported.
+
+- the EMX runtime environment on OS/2 is now supported.
+
+- GNU/Hurd is now supported.
+
+Tests
+-----
+
+- The regrtest.py script's -u option now provides a way to say "allow
+  all resources except this one."  For example, to allow everything
+  except bsddb, give the option '-uall,-bsddb'.
+
+Windows
+-------
+
+- The Windows distribution now ships with version 4.0.14 of the
+  Sleepycat Berkeley database library.  This should be a huge
+  improvement over the previous Berkeley DB 1.85, which had many
+  bugs.
+  XXX What are the licensing issues here?
+  XXX If a user has a database created with a previous version of
+  XXX     Python, what must they do to convert it?
+  XXX I'm still not sure how to link this thing (see PCbuild/readme.txt).
+  XXX The version # is likely to change before 2.3a1.
+
+- The Windows distribution now ships with a Secure Sockets Library (SLL)
+   module (_ssl.pyd)
+
+- The Windows distribution now ships with Tcl/Tk version 8.4.1 (it
+  previously shipped with Tcl/Tk 8.3.2).
+
+- When Python is built under a Microsoft compiler, sys.version now
+  includes the compiler version number (_MSC_VER).  For example, under
+  MSVC 6, sys.version contains the substring "MSC v.1200 ".  1200 is
+  the value of _MSC_VER under MSVC 6.
+
+- Sometimes the uninstall executable (UNWISE.EXE) vanishes.  One cause
+  of that has been fixed in the installer (disabled Wise's "delete in-
+  use files" uninstall option).
+
+- Fixed a bug in urllib's proxy handling in Windows.  [SF bug #503031]
+
+- The installer now installs Start menu shortcuts under (the local
+  equivalent of) "All Users" when doing an Admin install.
+
+- file.truncate([newsize]) now works on Windows for all newsize values.
+  It used to fail if newsize didn't fit in 32 bits, reflecting a
+  limitation of MS _chsize (which is no longer used).
+
+- os.waitpid() is now implemented for Windows, and can be used to block
+  until a specified process exits.  This is similar to, but not exactly
+  the same as, os.waitpid() on POSIX systems.  If you're waiting for
+  a specific process whose pid was obtained from one of the spawn()
+  functions, the same Python os.waitpid() code works across platforms.
+  See the docs for details.  The docs were changed to clarify that
+  spawn functions return, and waitpid requires, a process handle on
+  Windows (not the same thing as a Windows process id).
+
+- New tempfile.TemporaryFile implementation for Windows:  this doesn't
+  need a TemporaryFileWrapper wrapper anymore, and should be immune
+  to a nasty problem:  before 2.3, if you got a temp file on Windows, it
+  got wrapped in an object whose close() method first closed the
+  underlying file, then deleted the file.  This usually worked fine.
+  However, the spawn family of functions on Windows create (at a low C
+  level) the same set of open files in the spawned process Q as were
+  open in the spawning process P.  If a temp file f was among them, then
+  doing f.close() in P first closed P's C-level file handle on f, but Q's
+  C-level file handle on f remained open, so the attempt in P to delete f
+  blew up with a "Permission denied" error (Windows doesn't allow
+  deleting open files).  This was surprising, subtle, and difficult to
+  work around.
+
+- The os module now exports all the symbolic constants usable with the
+  low-level os.open() on Windows:  the new constants in 2.3 are
+  O_NOINHERIT, O_SHORT_LIVED, O_TEMPORARY, O_RANDOM and O_SEQUENTIAL.
+  The others were also available in 2.2:  O_APPEND, O_BINARY, O_CREAT,
+  O_EXCL, O_RDONLY, O_RDWR, O_TEXT, O_TRUNC and O_WRONLY.  Contrary
+  to Microsoft docs, O_SHORT_LIVED does not seem to imply O_TEMPORARY
+  (so specify both if you want both; note that neither is useful unless
+  specified with O_CREAT too).
+
+Mac
+----
+
+- Mac/Relnotes is gone, the release notes are now here.
+
+- Python (the OSX-only, unix-based version, not the OS9-compatible CFM
+  version) now fully supports unicode strings as arguments to various file
+  system calls, eg. open(), file(), os.stat() and os.listdir().
+
+- The current naming convention for Python on the Macintosh is that MacPython
+  refers to the unix-based OSX-only version, and MacPython-OS9 refers to the
+  CFM-based version that runs on both OS9 and OSX.
+
+- All MacPython-OS9 functionality is now available in an OSX unix build,
+  including the Carbon modules, the IDE, OSA support, etc. A lot of this
+  will only work correctly in a framework build, though, because you cannot
+  talk to the window manager unless your application is run from a .app
+  bundle. There is a command line tool "pythonw" that runs your script
+  with an interpreter living in such a .app bundle, this interpreter should
+  be used to run any Python script using the window manager (including
+  Tkinter or wxPython scripts).
+
+- Most of Mac/Lib has moved to Lib/plat-mac, which is again used both in
+  MacPython-OSX and MacPython-OS9. The only modules remaining in Mac/Lib
+  are specifically for MacPython-OS9 (CFM support, preference resources, etc).
+
+- A new utility PythonLauncher will start a Python interpreter when a .py or
+  .pyw script is double-clicked in the Finder. By default .py scripts are
+  run with a normal Python interpreter in a Terminal window and .pyw
+  files are run with a window-aware pythonw interpreter without a Terminal
+  window, but all this can be customized.
+
+- MacPython-OS9 is now Carbon-only, so it runs on Mac OS 9 or Mac OS X and
+  possibly on Mac OS 8.6 with the right CarbonLib installed, but not on earlier
+  releases.
+
+- Many tools such as BuildApplet.py and gensuitemodule.py now support a command
+  line interface too.
+
+- All the Carbon classes are now PEP253 compliant, meaning that you can
+  subclass them from Python. Most of the attributes have gone, you should
+  now use the accessor function call API, which is also what Apple's
+  documentation uses. Some attributes such as grafport.visRgn are still
+  available for convenience.
+
+- New Carbon modules File (implementing the APIs in Files.h and Aliases.h)
+  and Folder (APIs from Folders.h). The old macfs builtin module is
+  gone, and replaced by a Python wrapper around the new modules.
+
+- Pathname handling should now be fully consistent: MacPython-OSX always uses
+  unix pathnames and MacPython-OS9 always uses colon-separated Mac pathnames
+  (also when running on Mac OS X).
+
+- New Carbon modules Help and AH give access to the Carbon Help Manager.
+  There are hooks in the IDE to allow accessing the Python documentation
+  (and Apple's Carbon and Cocoa documentation) through the Help Viewer.
+  See Mac/OSX/README for converting the Python documentation to a
+  Help Viewer compatible form and installing it.
+
+- OSA support has been redesigned and the generated Python classes now
+  mirror the inheritance defined by the underlying OSA classes.
+
+- MacPython no longer maps both \r and \n to \n on input for any text file.
+  This feature has been replaced by universal newline support (PEP278).
+
+- The default encoding for Python sourcefiles in MacPython-OS9 is no longer
+  mac-roman (or whatever your local Mac encoding was) but "ascii", like on
+  other platforms. If you really need sourcefiles with Mac characters in them
+  you can change this in site.py.
+
+
+What's New in Python 2.2 final?
+===============================
+
+*Release date: 21-Dec-2001*
+
+Type/class unification and new-style classes
+--------------------------------------------
+
+- pickle.py, cPickle: allow pickling instances of new-style classes
+  with a custom metaclass.
+
+Core and builtins
+-----------------
+
+- weakref proxy object: when comparing, unwrap both arguments if both
+  are proxies.
+
+Extension modules
+-----------------
+
+- binascii.b2a_base64(): fix a potential buffer overrun when encoding
+  very short strings.
+
+- cPickle: the obscure "fast" mode was suspected of causing stack
+  overflows on the Mac.  Hopefully fixed this by setting the recursion
+  limit much smaller.  If the limit is too low (it only affects
+  performance), you can change it by defining PY_CPICKLE_FAST_LIMIT
+  when compiling cPickle.c (or in pyconfig.h).
+
+Library
+-------
+
+- dumbdbm.py: fixed a dumb old bug (the file didn't get synched at
+  close or delete time).
+
+- rfc822.py: fixed a bug where the address '<>' was converted to None
+  instead of an empty string (also fixes the email.Utils module).
+
+- xmlrpclib.py: version 1.0.0; uses precision for doubles.
+
+- test suite: the pickle and cPickle tests were not executing any code
+  when run from the standard regression test.
+
+Tools/Demos
+-----------
+
+Build
+-----
+
+C API
+-----
+
+New platforms
+-------------
+
+Tests
+-----
+
+Windows
+-------
+
+- distutils package: fixed broken Windows installers (bdist_wininst).
+
+- tempfile.py: prevent mysterious warnings when TemporaryFileWrapper
+  instances are deleted at process exit time.
+
+- socket.py: prevent mysterious warnings when socket instances are
+  deleted at process exit time.
+
+- posixmodule.c: fix a Windows crash with stat() of a filename ending
+  in backslash.
+
+Mac
+----
+
+- The Carbon toolbox modules have been upgraded to Universal Headers
+  3.4, and experimental CoreGraphics and CarbonEvents modules have
+  been added.  All only for framework-enabled MacOSX.
+
+
+What's New in Python 2.2c1?
+===========================
+
+*Release date: 14-Dec-2001*
+
+Type/class unification and new-style classes
+--------------------------------------------
+
+- Guido's tutorial introduction to the new type/class features has
+  been extensively updated.  See
+
+      http://www.python.org/2.2/descrintro.html
+
+  That remains the primary documentation in this area.
+
+- Fixed a leak: instance variables declared with __slots__ were never
+  deleted!
+
+- The "delete attribute" method of descriptor objects is called
+  __delete__, not __del__.  In previous releases, it was mistakenly
+  called __del__, which created an unfortunate overloading condition
+  with finalizers.  (The "get attribute" and "set attribute" methods
+  are still called __get__ and __set__, respectively.)
+
+- Some subtle issues with the super built-in were fixed:
+
+  (a) When super itself is subclassed, its __get__ method would still
+      return an instance of the base class (i.e., of super).
+
+  (b) super(C, C()).__class__ would return C rather than super.  This
+      is confusing.  To fix this, I decided to change the semantics of
+      super so that it only applies to code attributes, not to data
+      attributes.  After all, overriding data attributes is not
+      supported anyway.
+
+  (c) The __get__ method didn't check whether the argument was an
+      instance of the type used in creation of the super instance.
+
+- Previously, hash() of an instance of a subclass of a mutable type
+  (list or dictionary) would return some value, rather than raising
+  TypeError.  This has been fixed.  Also, directly calling
+  dict.__hash__ and list.__hash__ now raises the same TypeError
+  (previously, these were the same as object.__hash__).
+
+- New-style objects now support deleting their __dict__.  This is for
+  all intents and purposes equivalent to assigning a brand new empty
+  dictionary, but saves space if the object is not used further.
+
+Core and builtins
+-----------------
+
+- -Qnew now works as documented in PEP 238:  when -Qnew is passed on
+  the command line, all occurrences of "/" use true division instead
+  of classic division.  See the PEP for details.  Note that "all"
+  means all instances in library and 3rd-party modules, as well as in
+  your own code.  As the PEP says, -Qnew is intended for use only in
+  educational environments with control over the libraries in use.
+  Note that test_coercion.py in the standard Python test suite fails
+  under -Qnew; this is expected, and won't be repaired until true
+  division becomes the default (in the meantime, test_coercion is
+  testing the current rules).
+
+- complex() now only allows the first argument to be a string
+  argument, and raises TypeError if either the second arg is a string
+  or if the second arg is specified when the first is a string.
+
+Extension modules
+-----------------
+
+- gc.get_referents was renamed to gc.get_referrers.
+
+Library
+-------
+
+- Functions in the os.spawn() family now release the global interpreter
+  lock around calling the platform spawn.  They should always have done
+  this, but did not before 2.2c1.  Multithreaded programs calling
+  an os.spawn function with P_WAIT will no longer block all Python threads
+  until the spawned program completes.  It's possible that some programs
+  relies on blocking, although more likely by accident than by design.
+
+- webbrowser defaults to netscape.exe on OS/2 now.
+
+- Tix.ResizeHandle exposes detach_widget, hide, and show.
+
+- The charset alias windows_1252 has been added.
+
+- types.StringTypes is a tuple containing the defined string types;
+  usually this will be (str, unicode), but if Python was compiled
+  without Unicode support it will be just (str,).
+
+- The pulldom and minidom modules were synchronized to PyXML.
+
+Tools/Demos
+-----------
+
+- A new script called Tools/scripts/google.py was added, which fires
+  off a search on Google.
+
+Build
+-----
+
+- Note that release builds of Python should arrange to define the
+  preprocessor symbol NDEBUG on the command line (or equivalent).
+  In the 2.2 pre-release series we tried to define this by magic in
+  Python.h instead, but it proved to cause problems for extension
+  authors.  The Unix, Windows and Mac builds now all define NDEBUG in
+  release builds via cmdline (or equivalent) instead.  Ports to
+  other platforms should do likewise.
+
+- It is no longer necessary to use --with-suffix when building on a
+  case-insensitive file system (such as Mac OS X HFS+). In the build
+  directory an extension is used, but not in the installed python.
+
+C API
+-----
+
+- New function PyDict_MergeFromSeq2() exposes the builtin dict
+  constructor's logic for updating a dictionary from an iterable object
+  producing key-value pairs.
+
+- PyArg_ParseTupleAndKeywords() requires that the number of entries in
+  the keyword list equal the number of argument specifiers.  This
+  wasn't checked correctly, and PyArg_ParseTupleAndKeywords could even
+  dump core in some bad cases.  This has been repaired.  As a result,
+  PyArg_ParseTupleAndKeywords may raise RuntimeError in bad cases that
+  previously went unchallenged.
+
+New platforms
+-------------
+
+Tests
+-----
+
+Windows
+-------
+
+Mac
+----
+
+- In unix-Python on Mac OS X (and darwin) sys.platform is now "darwin",
+  without any trailing digits.
+
+- Changed logic for finding python home in Mac OS X framework Pythons.
+  Now sys.executable points to the executable again, in stead of to
+  the shared library. The latter is used only for locating the python
+  home.
+
+
+What's New in Python 2.2b2?
+===========================
+
+*Release date: 16-Nov-2001*
+
+Type/class unification and new-style classes
+--------------------------------------------
+
+- Multiple inheritance mixing new-style and classic classes in the
+  list of base classes is now allowed, so this works now:
+
+      class Classic: pass
+      class Mixed(Classic, object): pass
+
+  The MRO (method resolution order) for each base class is respected
+  according to its kind, but the MRO for the derived class is computed
+  using new-style MRO rules if any base class is a new-style class.
+  This needs to be documented.
+
+- The new builtin dictionary() constructor, and dictionary type, have
+  been renamed to dict.  This reflects a decade of common usage.
+
+- dict() now accepts an iterable object producing 2-sequences.  For
+  example, dict(d.items()) == d for any dictionary d.  The argument,
+  and the elements of the argument, can be any iterable objects.
+
+- New-style classes can now have a __del__ method, which is called
+  when the instance is deleted (just like for classic classes).
+
+- Assignment to object.__dict__ is now possible, for objects that are
+  instances of new-style classes that have a __dict__ (unless the base
+  class forbids it).
+
+- Methods of built-in types now properly check for keyword arguments
+  (formerly these were silently ignored).  The only built-in methods
+  that take keyword arguments are __call__, __init__ and __new__.
+
+- The socket function has been converted to a type; see below.
+
+Core and builtins
+-----------------
+
+- Assignment to __debug__ raises SyntaxError at compile-time.  This
+  was promised when 2.1c1 was released as "What's New in Python 2.1c1"
+  (see below) says.
+
+- Clarified the error messages for unsupported operands to an operator
+  (like 1 + '').
+
+Extension modules
+-----------------
+
+- mmap has a new keyword argument, "access", allowing a uniform way for
+  both Windows and Unix users to create read-only, write-through and
+  copy-on-write memory mappings.  This was previously possible only on
+  Unix.  A new keyword argument was required to support this in a
+  uniform way because the mmap() signatures had diverged across
+  platforms.  Thanks to Jay T Miller for repairing this!
+
+- By default, the gc.garbage list now contains only those instances in
+  unreachable cycles that have __del__ methods; in 2.1 it contained all
+  instances in unreachable cycles.  "Instances" here has been generalized
+  to include instances of both new-style and old-style classes.
+
+- The socket module defines a new method for socket objects,
+  sendall().  This is like send() but may make multiple calls to
+  send() until all data has been sent.  Also, the socket function has
+  been converted to a subclassable type, like list and tuple (etc.)
+  before it; socket and SocketType are now the same thing.
+
+- Various bugfixes to the curses module.  There is now a test suite
+  for the curses module (you have to run it manually).
+
+- binascii.b2a_base64 no longer places an arbitrary restriction of 57
+  bytes on its input.
+
+Library
+-------
+
+- tkFileDialog exposes a Directory class and askdirectory
+  convenience function.
+
+- Symbolic group names in regular expressions must be unique.  For
+  example, the regexp r'(?P<abc>)(?P<abc>)' is not allowed, because a
+  single name can't mean both "group 1" and "group 2" simultaneously.
+  Python 2.2 detects this error at regexp compilation time;
+  previously, the error went undetected, and results were
+  unpredictable.  Also in sre, the pattern.split(), pattern.sub(), and
+  pattern.subn() methods have been rewritten in C.  Also, an
+  experimental function/method finditer() has been added, which works
+  like findall() but returns an iterator.
+
+- Tix exposes more commands through the classes DirSelectBox,
+  DirSelectDialog, ListNoteBook, Meter, CheckList, and the
+  methods tix_addbitmapdir, tix_cget, tix_configure, tix_filedialog,
+  tix_getbitmap, tix_getimage, tix_option_get, and tix_resetoptions.
+
+- Traceback objects are now scanned by cyclic garbage collection, so
+  cycles created by casual use of sys.exc_info() no longer cause
+  permanent memory leaks (provided garbage collection is enabled).
+
+- os.extsep -- a new variable needed by the RISCOS support.  It is the
+  separator used by extensions, and is '.' on all platforms except
+  RISCOS, where it is '/'.  There is no need to use this variable
+  unless you have a masochistic desire to port your code to RISCOS.
+
+- mimetypes.py has optional support for non-standard, but commonly
+  found types.  guess_type() and guess_extension() now accept an
+  optional 'strict' flag, defaulting to true, which controls whether
+  recognize non-standard types or not.  A few non-standard types we
+  know about have been added.  Also, when run as a script, there are
+  new -l and -e options.
+
+- statcache is now deprecated.
+
+- email.Utils.formatdate() now produces the preferred RFC 2822 style
+  dates with numeric timezones (it used to produce obsolete dates
+  hard coded to "GMT" timezone).  An optional 'localtime' flag is
+  added to produce dates in the local timezone, with daylight savings
+  time properly taken into account.
+
+- In pickle and cPickle, instead of masking errors in load() by
+  transforming them into SystemError, we let the original exception
+  propagate out.  Also, implement support for __safe_for_unpickling__
+  in pickle, as it already was supported in cPickle.
+
+Tools/Demos
+-----------
+
+Build
+-----
+
+- The dbm module is built using libdb1 if available.  The bsddb module
+  is built with libdb3 if available.
+
+- Misc/Makefile.pre.in has been removed by BDFL pronouncement.
+
+C API
+-----
+
+- New function PySequence_Fast_GET_SIZE() returns the size of a non-
+  NULL result from PySequence_Fast(), more quickly than calling
+  PySequence_Size().
+
+- New argument unpacking function PyArg_UnpackTuple() added.
+
+- New functions PyObject_CallFunctionObjArgs() and
+  PyObject_CallMethodObjArgs() have been added to make it more
+  convenient and efficient to call functions and methods from C.
+
+- PyArg_ParseTupleAndKeywords() no longer masks errors, so it's
+  possible that this will propagate errors it didn't before.
+
+- New function PyObject_CheckReadBuffer(), which returns true if its
+  argument supports the single-segment readable buffer interface.
+
+New platforms
+-------------
+
+- We've finally confirmed that this release builds on HP-UX 11.00,
+  *with* threads, and passes the test suite.
+
+- Thanks to a series of patches from Michael Muller, Python may build
+  again under OS/2 Visual Age C++.
+
+- Updated RISCOS port by Dietmar Schwertberger.
+
+Tests
+-----
+
+- Added a test script for the curses module.  It isn't run automatically;
+  regrtest.py must be run with '-u curses' to enable it.
+
+Windows
+-------
+
+Mac
+----
+
+- PythonScript has been moved to unsupported and is slated to be
+  removed completely in the next release.
+
+- It should now be possible to build applets that work on both OS9 and
+  OSX.
+
+- The core is now linked with CoreServices not Carbon; as a side
+  result, default 8bit encoding on OSX is now ASCII.
+
+- Python should now build on OSX 10.1.1
+
+
+What's New in Python 2.2b1?
+===========================
+
+*Release date: 19-Oct-2001*
+
+Type/class unification and new-style classes
+--------------------------------------------
+
+- New-style classes are now always dynamic (except for built-in and
+  extension types).  There is no longer a performance penalty, and I
+  no longer see another reason to keep this baggage around.  One relic
+  remains: the __dict__ of a new-style class is a read-only proxy; you
+  must set the class's attribute to modify it.  As a consequence, the
+  __defined__ attribute of new-style types no longer exists, for lack
+  of need: there is once again only one __dict__ (although in the
+  future a __cache__ may be resurrected with a similar function, if I
+  can prove that it actually speeds things up).
+
+- C.__doc__ now works as expected for new-style classes (in 2.2a4 it
+  always returned None, even when there was a class docstring).
+
+- doctest now finds and runs docstrings attached to new-style classes,
+  class methods, static methods, and properties.
+
+Core and builtins
+-----------------
+
+- A very subtle syntactical pitfall in list comprehensions was fixed.
+  For example: [a+b for a in 'abc', for b in 'def'].  The comma in
+  this example is a mistake.  Previously, this would silently let 'a'
+  iterate over the singleton tuple ('abc',), yielding ['abcd', 'abce',
+  'abcf'] rather than the intended ['ad', 'ae', 'af', 'bd', 'be',
+  'bf', 'cd', 'ce', 'cf'].  Now, this is flagged as a syntax error.
+  Note that [a for a in <singleton>] is a convoluted way to say
+  [<singleton>] anyway, so it's not like any expressiveness is lost.
+
+- getattr(obj, name, default) now only catches AttributeError, as
+  documented, rather than returning the default value for all
+  exceptions (which could mask bugs in a __getattr__ hook, for
+  example).
+
+- Weak reference objects are now part of the core and offer a C API.
+  A bug which could allow a core dump when binary operations involved
+  proxy reference has been fixed.  weakref.ReferenceError is now a
+  built-in exception.
+
+- unicode(obj) now behaves more like str(obj), accepting arbitrary
+  objects, and calling a __unicode__ method if it exists.
+  unicode(obj, encoding) and unicode(obj, encoding, errors) still
+  require an 8-bit string or character buffer argument.
+
+- isinstance() now allows any object as the first argument and a
+  class, a type or something with a __bases__ tuple attribute for the
+  second argument.  The second argument may also be a tuple of a
+  class, type, or something with __bases__, in which case isinstance()
+  will return true if the first argument is an instance of any of the
+  things contained in the second argument tuple.  E.g.
+
+  isinstance(x, (A, B))
+
+  returns true if x is an instance of A or B.
+
+Extension modules
+-----------------
+
+- thread.start_new_thread() now returns the thread ID (previously None).
+
+- binascii has now two quopri support functions, a2b_qp and b2a_qp.
+
+- readline now supports setting the startup_hook and the
+  pre_event_hook, and adds the add_history() function.
+
+- os and posix supports chroot(), setgroups() and unsetenv() where
+  available.  The stat(), fstat(), statvfs() and fstatvfs() functions
+  now return "pseudo-sequences" -- the various fields can now be
+  accessed as attributes (e.g. os.stat("/").st_mtime) but for
+  backwards compatibility they also behave as a fixed-length sequence.
+  Some platform-specific fields (e.g. st_rdev) are only accessible as
+  attributes.
+
+- time: localtime(), gmtime() and strptime() now return a
+  pseudo-sequence similar to the os.stat() return value, with
+  attributes like tm_year etc.
+
+- Decompression objects in the zlib module now accept an optional
+  second parameter to decompress() that specifies the maximum amount
+  of memory to use for the uncompressed data.
+
+- optional SSL support in the socket module now exports OpenSSL
+  functions RAND_add(), RAND_egd(), and RAND_status().  These calls
+  are useful on platforms like Solaris where OpenSSL does not
+  automatically seed its PRNG.  Also, the keyfile and certfile
+  arguments to socket.ssl() are now optional.
+
+- posixmodule (and by extension, the os module on POSIX platforms) now
+  exports O_LARGEFILE, O_DIRECT, O_DIRECTORY, and O_NOFOLLOW.
+
+Library
+-------
+
+- doctest now excludes functions and classes not defined by the module
+  being tested, thanks to Tim Hochberg.
+
+- HotShot, a new profiler implemented using a C-based callback, has
+  been added.  This substantially reduces the overhead of profiling,
+  but it is still quite preliminary.  Support modules and
+  documentation will be added in upcoming releases (before 2.2 final).
+
+- profile now produces correct output in situations where an exception
+  raised in Python is cleared by C code (e.g. hasattr()).  This used
+  to cause wrong output, including spurious claims of recursive
+  functions and attribution of time spent to the wrong function.
+
+  The code and documentation for the derived OldProfile and HotProfile
+  profiling classes was removed.  The code hasn't worked for years (if
+  you tried to use them, they raised exceptions).  OldProfile
+  intended to reproduce the behavior of the profiler Python used more
+  than 7 years ago, and isn't interesting anymore.  HotProfile intended
+  to provide a faster profiler (but producing less information), and
+  that's a worthy goal we intend to meet via a different approach (but
+  without losing information).
+
+- Profile.calibrate() has a new implementation that should deliver
+  a much better system-specific calibration constant.  The constant can
+  now be specified in an instance constructor, or as a Profile class or
+  instance variable, instead of by editing profile.py's source code.
+  Calibration must still be done manually (see the docs for the profile
+  module).
+
+  Note that Profile.calibrate() must be overridden by subclasses.
+  Improving the accuracy required exploiting detailed knowledge of
+  profiler internals; the earlier method abstracted away the details
+  and measured a simplified model instead, but consequently computed
+  a constant too small by a factor of 2 on some modern machines.
+
+- quopri's encode and decode methods take an optional header parameter,
+  which indicates whether output is intended for the header 'Q'
+  encoding.
+
+- The SocketServer.ThreadingMixIn class now closes the request after
+  finish_request() returns.  (Not when it errors out though.)
+
+- The nntplib module's NNTP.body() method has grown a 'file' argument
+  to allow saving the message body to a file.
+
+- The email package has added a class email.Parser.HeaderParser which
+  only parses headers and does not recurse into the message's body.
+  Also, the module/class MIMEAudio has been added for representing
+  audio data (contributed by Anthony Baxter).
+
+- ftplib should be able to handle files > 2GB.
+
+- ConfigParser.getboolean() now also interprets TRUE, FALSE, YES, NO,
+  ON, and OFF.
+
+- xml.dom.minidom NodeList objects now support the length attribute
+  and item() method as required by the DOM specifications.
+
+Tools/Demos
+-----------
+
+- Demo/dns was removed.  It no longer serves any purpose; a package
+  derived from it is now maintained by Anthony Baxter, see
+  http://PyDNS.SourceForge.net.
+
+- The freeze tool has been made more robust, and two new options have
+  been added: -X and -E.
+
+Build
+-----
+
+- configure will use CXX in LINKCC if CXX is used to build main() and
+  the system requires to link a C++ main using the C++ compiler.
+
+C API
+-----
+
+- The documentation for the tp_compare slot is updated to require that
+  the return value must be -1, 0, 1; an arbitrary number <0 or >0 is
+  not correct.  This is not yet enforced but will be enforced in
+  Python 2.3; even later, we may use -2 to indicate errors and +2 for
+  "NotImplemented".  Right now, -1 should be used for an error return.
+
+- PyLong_AsLongLong() now accepts int (as well as long) arguments.
+  Consequently, PyArg_ParseTuple's 'L' code also accepts int (as well
+  as long) arguments.
+
+- PyThread_start_new_thread() now returns a long int giving the thread
+  ID, if one can be calculated; it returns -1 for error, 0 if no
+  thread ID is calculated (this is an incompatible change, but only
+  the thread module used this API).  This code has only really been
+  tested on Linux and Windows; other platforms please beware (and
+  report any bugs or strange behavior).
+
+- PyUnicode_FromEncodedObject() no longer accepts Unicode objects as
+  input.
+
+New platforms
+-------------
+
+Tests
+-----
+
+Windows
+-------
+
+- Installer:  If you install IDLE, and don't disable file-extension
+  registration, a new "Edit with IDLE" context (right-click) menu entry
+  is created for .py and .pyw files.
+
+- The signal module now supports SIGBREAK on Windows, thanks to Steven
+  Scott.  Note that SIGBREAK is unique to Windows.  The default SIGBREAK
+  action remains to call Win32 ExitProcess().  This can be changed via
+  signal.signal().  For example::
+
+      # Make Ctrl+Break raise KeyboardInterrupt, like Python's default Ctrl+C
+      # (SIGINT) behavior.
+      import signal
+      signal.signal(signal.SIGBREAK, signal.default_int_handler)
+
+      try:
+          while 1:
+              pass
+      except KeyboardInterrupt:
+          # We get here on Ctrl+C or Ctrl+Break now; if we had not changed
+          # SIGBREAK, only on Ctrl+C (and Ctrl+Break would terminate the
+          # program without the possibility for any Python-level cleanup).
+          print "Clean exit"
+
+
+What's New in Python 2.2a4?
+===========================
+
+*Release date: 28-Sep-2001*
+
+Type/class unification and new-style classes
+--------------------------------------------
+
+- pydoc and inspect are now aware of new-style classes;
+  e.g. help(list) at the interactive prompt now shows proper
+  documentation for all operations on list objects.
+
+- Applications using Jim Fulton's ExtensionClass module can now safely
+  be used with Python 2.2.  In particular, Zope 2.4.1 now works with
+  Python 2.2 (as well as with Python 2.1.1).  The Demo/metaclass
+  examples also work again.  It is hoped that Gtk and Boost also work
+  with 2.2a4 and beyond.  (If you can confirm this, please write
+  webmaster at python.org; if there are still problems, please open a bug
+  report on SourceForge.)
+
+- property() now takes 4 keyword arguments:  fget, fset, fdel and doc.
+  These map to read-only attributes 'fget', 'fset', 'fdel', and '__doc__'
+  in the constructed property object.  fget, fset and fdel weren't
+  discoverable from Python in 2.2a3.  __doc__ is new, and allows to
+  associate a docstring with a property.
+
+- Comparison overloading is now more completely implemented.  For
+  example, a str subclass instance can properly be compared to a str
+  instance, and it can properly overload comparison.  Ditto for most
+  other built-in object types.
+
+- The repr() of new-style classes has changed; instead of <type
+  'M.Foo'> a new-style class is now rendered as <class 'M.Foo'>,
+  *except* for built-in types, which are still rendered as <type
+  'Foo'> (to avoid upsetting existing code that might parse or
+  otherwise rely on repr() of certain type objects).
+
+- The repr() of new-style objects is now always <Foo object at XXX>;
+  previously, it was sometimes <Foo instance at XXX>.
+
+- For new-style classes, what was previously called __getattr__ is now
+  called __getattribute__.  This method, if defined, is called for
+  *every* attribute access.  A new __getattr__ hook more similar to the
+  one in classic classes is defined which is called only if regular
+  attribute access raises AttributeError; to catch *all* attribute
+  access, you can use __getattribute__ (for new-style classes).  If
+  both are defined, __getattribute__ is called first, and if it raises
+  AttributeError, __getattr__ is called.
+
+- The __class__ attribute of new-style objects can be assigned to.
+  The new class must have the same C-level object layout as the old
+  class.
+
+- The builtin file type can be subclassed now.  In the usual pattern,
+  "file" is the name of the builtin type, and file() is a new builtin
+  constructor, with the same signature as the builtin open() function.
+  file() is now the preferred way to open a file.
+
+- Previously, __new__ would only see sequential arguments passed to
+  the type in a constructor call; __init__ would see both sequential
+  and keyword arguments.  This made no sense whatsoever any more, so
+  now both __new__ and __init__ see all arguments.
+
+- Previously, hash() applied to an instance of a subclass of str or
+  unicode always returned 0.  This has been repaired.
+
+- Previously, an operation on an instance of a subclass of an
+  immutable type (int, long, float, complex, tuple, str, unicode),
+  where the subtype didn't override the operation (and so the
+  operation was handled by the builtin type), could return that
+  instance instead a value of the base type.  For example, if s was of
+  a str subclass type, s[:] returned s as-is.  Now it returns a str
+  with the same value as s.
+
+- Provisional support for pickling new-style objects has been added.
+
+Core
+----
+
+- file.writelines() now accepts any iterable object producing strings.
+
+- PyUnicode_FromEncodedObject() now works very much like
+  PyObject_Str(obj) in that it tries to use __str__/tp_str
+  on the object if the object is not a string or buffer. This
+  makes unicode() behave like str() when applied to non-string/buffer
+  objects.
+
+- PyFile_WriteObject now passes Unicode objects to the file's write
+  method. As a result, all file-like objects which may be the target
+  of a print statement must support Unicode objects, i.e. they must
+  at least convert them into ASCII strings.
+
+- Thread scheduling on Solaris should be improved; it is no longer
+  necessary to insert a small sleep at the start of a thread in order
+  to let other runnable threads be scheduled.
+
+Library
+-------
+
+- StringIO.StringIO instances and cStringIO.StringIO instances support
+  read character buffer compatible objects for their .write() methods.
+  These objects are converted to strings and then handled as such
+  by the instances.
+
+- The "email" package has been added.  This is basically a port of the
+  mimelib package <http://sf.net/projects/mimelib> with API changes
+  and some implementations updated to use iterators and generators.
+
+- difflib.ndiff() and difflib.Differ.compare() are generators now.  This
+  restores the ability of Tools/scripts/ndiff.py to start producing output
+  before the entire comparison is complete.
+
+- StringIO.StringIO instances and cStringIO.StringIO instances support
+  iteration just like file objects (i.e. their .readline() method is
+  called for each iteration until it returns an empty string).
+
+- The codecs module has grown four new helper APIs to access
+  builtin codecs: getencoder(), getdecoder(), getreader(),
+  getwriter().
+
+- SimpleXMLRPCServer: a new module (based upon SimpleHTMLServer)
+  simplifies writing XML RPC servers.
+
+- os.path.realpath(): a new function that returns the absolute pathname
+  after interpretation of symbolic links.  On non-Unix systems, this
+  is an alias for os.path.abspath().
+
+- operator.indexOf() (PySequence_Index() in the C API) now works with any
+  iterable object.
+
+- smtplib now supports various authentication and security features of
+  the SMTP protocol through the new login() and starttls() methods.
+
+- hmac: a new module implementing keyed hashing for message
+  authentication.
+
+- mimetypes now recognizes more extensions and file types.  At the
+  same time, some mappings not sanctioned by IANA were removed.
+
+- The "compiler" package has been brought up to date to the state of
+  Python 2.2 bytecode generation.  It has also been promoted from a
+  Tool to a standard library package.  (Tools/compiler still exists as
+  a sample driver.)
+
+Build
+-----
+
+- Large file support (LFS) is now automatic when the platform supports
+  it; no more manual configuration tweaks are needed.  On Linux, at
+  least, it's possible to have a system whose C library supports large
+  files but whose kernel doesn't; in this case, large file support is
+  still enabled but doesn't do you any good unless you upgrade your
+  kernel or share your Python executable with another system whose
+  kernel has large file support.
+
+- The configure script now supplies plausible defaults in a
+  cross-compilation environment.  This doesn't mean that the supplied
+  values are always correct, or that cross-compilation now works
+  flawlessly -- but it's a first step (and it shuts up most of
+  autoconf's warnings about AC_TRY_RUN).
+
+- The Unix build is now a bit less chatty, courtesy of the parser
+  generator.  The build is completely silent (except for errors) when
+  using "make -s", thanks to a -q option to setup.py.
+
+C API
+-----
+
+- The "structmember" API now supports some new flag bits to deny read
+  and/or write access to attributes in restricted execution mode.
+
+New platforms
+-------------
+
+- Compaq's iPAQ handheld, running the "familiar" Linux distribution
+  (http://familiar.handhelds.org).
+
+Tests
+-----
+
+- The "classic" standard tests, which work by comparing stdout to
+  an expected-output file under Lib/test/output/, no longer stop at
+  the first mismatch.  Instead the test is run to completion, and a
+  variant of ndiff-style comparison is used to report all differences.
+  This is much easier to understand than the previous style of reporting.
+
+- The unittest-based standard tests now use regrtest's test_main()
+  convention, instead of running as a side-effect of merely being
+  imported.  This allows these tests to be run in more natural and
+  flexible ways as unittests, outside the regrtest framework.
+
+- regrtest.py is much better integrated with unittest and doctest now,
+  especially in regard to reporting errors.
+
+Windows
+-------
+
+- Large file support now also works for files > 4GB, on filesystems
+  that support it (NTFS under Windows 2000).  See "What's New in
+  Python 2.2a3" for more detail.
+
+
+What's New in Python 2.2a3?
+===========================
+
+*Release Date: 07-Sep-2001*
+
+Core
+----
+
+- Conversion of long to float now raises OverflowError if the long is too
+  big to represent as a C double.
+
+- The 3-argument builtin pow() no longer allows a third non-None argument
+  if either of the first two arguments is a float, or if both are of
+  integer types and the second argument is negative (in which latter case
+  the arguments are converted to float, so this is really the same
+  restriction).
+
+- The builtin dir() now returns more information, and sometimes much
+  more, generally naming all attributes of an object, and all attributes
+  reachable from the object via its class, and from its class's base
+  classes, and so on from them too.  Example:  in 2.2a2, dir([]) returned
+  an empty list.  In 2.2a3,
+
+  >>> dir([])
+  ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__',
+   '__eq__', '__ge__', '__getattr__', '__getitem__', '__getslice__',
+   '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__le__',
+   '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__repr__',
+   '__rmul__', '__setattr__', '__setitem__', '__setslice__', '__str__',
+   'append', 'count', 'extend', 'index', 'insert', 'pop', 'remove',
+   'reverse', 'sort']
+
+  dir(module) continues to return only the module's attributes, though.
+
+- Overflowing operations on plain ints now return a long int rather
+  than raising OverflowError.  This is a partial implementation of PEP
+  237.  You can use -Wdefault::OverflowWarning to enable a warning for
+  this situation, and -Werror::OverflowWarning to revert to the old
+  OverflowError exception.
+
+- A new command line option, -Q<arg>, is added to control run-time
+  warnings for the use of classic division.  (See PEP 238.)  Possible
+  values are -Qold, -Qwarn, -Qwarnall, and -Qnew.  The default is
+  -Qold, meaning the / operator has its classic meaning and no
+  warnings are issued.  Using -Qwarn issues a run-time warning about
+  all uses of classic division for int and long arguments; -Qwarnall
+  also warns about classic division for float and complex arguments
+  (for use with fixdiv.py).
+  [Note:  the remainder of this item (preserved below) became
+  obsolete in 2.2c1 -- -Qnew has global effect in 2.2] ::
+
+    Using -Qnew is questionable; it turns on new division by default, but
+    only in the __main__ module.  You can usefully combine -Qwarn or
+    -Qwarnall and -Qnew: this gives the __main__ module new division, and
+    warns about classic division everywhere else.
+
+- Many built-in types can now be subclassed.  This applies to int,
+  long, float, str, unicode, and tuple.  (The types complex, list and
+  dictionary can also be subclassed; this was introduced earlier.)
+  Note that restrictions apply when subclassing immutable built-in
+  types: you can only affect the value of the instance by overloading
+  __new__.  You can add mutable attributes, and the subclass instances
+  will have a __dict__ attribute, but you cannot change the "value"
+  (as implemented by the base class) of an immutable subclass instance
+  once it is created.
+
+- The dictionary constructor now takes an optional argument, a
+  mapping-like object, and initializes the dictionary from its
+  (key, value) pairs.
+
+- A new built-in type, super, has been added.  This facilitates making
+  "cooperative super calls" in a multiple inheritance setting.  For an
+  explanation, see http://www.python.org/2.2/descrintro.html#cooperation
+
+- A new built-in type, property, has been added.  This enables the
+  creation of "properties".  These are attributes implemented by
+  getter and setter functions (or only one of these for read-only or
+  write-only attributes), without the need to override __getattr__.
+  See http://www.python.org/2.2/descrintro.html#property
+
+- The syntax of floating-point and imaginary literals has been
+  liberalized, to allow leading zeroes.  Examples of literals now
+  legal that were SyntaxErrors before:
+
+      00.0    0e3   0100j   07.5   00000000000000000008.
+
+- An old tokenizer bug allowed floating point literals with an incomplete
+  exponent, such as 1e and 3.1e-.  Such literals now raise SyntaxError.
+
+Library
+-------
+
+- telnetlib includes symbolic names for the options, and support for
+  setting an option negotiation callback. It also supports processing
+  of suboptions.
+
+- The new C standard no longer requires that math libraries set errno to
+  ERANGE on overflow.  For platform libraries that exploit this new
+  freedom, Python's overflow-checking was wholly broken.  A new overflow-
+  checking scheme attempts to repair that, but may not be reliable on all
+  platforms (C doesn't seem to provide anything both useful and portable
+  in this area anymore).
+
+- Asynchronous timeout actions are available through the new class
+  threading.Timer.
+
+- math.log and math.log10 now return sensible results for even huge
+  long arguments.  For example, math.log10(10 ** 10000) ~= 10000.0.
+
+- A new function, imp.lock_held(), returns 1 when the import lock is
+  currently held.  See the docs for the imp module.
+
+- pickle, cPickle and marshal on 32-bit platforms can now correctly read
+  dumps containing ints written on platforms where Python ints are 8 bytes.
+  When read on a box where Python ints are 4 bytes, such values are
+  converted to Python longs.
+
+- In restricted execution mode (using the rexec module), unmarshalling
+  code objects is no longer allowed.  This plugs a security hole.
+
+- unittest.TestResult instances no longer store references to tracebacks
+  generated by test failures. This prevents unexpected dangling references
+  to objects that should be garbage collected between tests.
+
+Tools
+-----
+
+- Tools/scripts/fixdiv.py has been added which can be used to fix
+  division operators as per PEP 238.
+
+Build
+-----
+
+- If you are an adventurous person using Mac OS X you may want to look at
+  Mac/OSX. There is a Makefile there that will build Python as a real Mac
+  application, which can be used for experimenting with Carbon or Cocoa.
+  Discussion of this on pythonmac-sig, please.
+
+C API
+-----
+
+- New function PyObject_Dir(obj), like Python __builtin__.dir(obj).
+
+- Note that PyLong_AsDouble can fail!  This has always been true, but no
+  callers checked for it.  It's more likely to fail now, because overflow
+  errors are properly detected now.  The proper way to check::
+
+      double x = PyLong_AsDouble(some_long_object);
+      if (x == -1.0 && PyErr_Occurred()) {
+              /* The conversion failed. */
+      }
+
+- The GC API has been changed.  Extensions that use the old API will still
+  compile but will not participate in GC.  To upgrade an extension
+  module:
+
+    - rename Py_TPFLAGS_GC to PyTPFLAGS_HAVE_GC
+
+    - use PyObject_GC_New or PyObject_GC_NewVar to allocate objects and
+      PyObject_GC_Del to deallocate them
+
+    - rename PyObject_GC_Init to PyObject_GC_Track and PyObject_GC_Fini
+      to PyObject_GC_UnTrack
+
+    - remove PyGC_HEAD_SIZE from object size calculations
+
+    - remove calls to PyObject_AS_GC and PyObject_FROM_GC
+
+- Two new functions: PyString_FromFormat() and PyString_FromFormatV().
+  These can be used safely to construct string objects from a
+  sprintf-style format string (similar to the format string supported
+  by PyErr_Format()).
+
+New platforms
+-------------
+
+- Stephen Hansen contributed patches sufficient to get a clean compile
+  under Borland C (Windows), but he reports problems running it and ran
+  out of time to complete the port.  Volunteers?  Expect a MemoryError
+  when importing the types module; this is probably shallow, and
+  causing later failures too.
+
+Tests
+-----
+
+Windows
+-------
+
+- Large file support is now enabled on Win32 platforms as well as on
+  Win64.  This means that, for example, you can use f.tell() and f.seek()
+  to manipulate files larger than 2 gigabytes (provided you have enough
+  disk space, and are using a Windows filesystem that supports large
+  partitions).  Windows filesystem limits:  FAT has a 2GB (gigabyte)
+  filesize limit, and large file support makes no difference there.
+  FAT32's limit is 4GB, and files >= 2GB are easier to use from Python now.
+  NTFS has no practical limit on file size, and files of any size can be
+  used from Python now.
+
+- The w9xpopen hack is now used on Windows NT and 2000 too when COMPSPEC
+  points to command.com (patch from Brian Quinlan).
+
+
+What's New in Python 2.2a2?
+===========================
+
+*Release Date: 22-Aug-2001*
+
+Build
+-----
+
+- Tim Peters developed a brand new Windows installer using Wise 8.1,
+  generously donated to us by Wise Solutions.
+
+- configure supports a new option --enable-unicode, with the values
+  ucs2 and ucs4 (new in 2.2a1). With --disable-unicode, the Unicode
+  type and supporting code is completely removed from the interpreter.
+
+- A new configure option --enable-framework builds a Mac OS X framework,
+  which "make frameworkinstall" will install. This provides a starting
+  point for more mac-like functionality, join pythonmac-sig at python.org
+  if you are interested in helping.
+
+- The NeXT platform is no longer supported.
+
+- The 'new' module is now statically linked.
+
+Tools
+-----
+
+- The new Tools/scripts/cleanfuture.py can be used to automatically
+  edit out obsolete future statements from Python source code.  See
+  the module docstring for details.
+
+Tests
+-----
+
+- regrtest.py now knows which tests are expected to be skipped on some
+  platforms, allowing to give clearer test result output.  regrtest
+  also has optional --use/-u switch to run normally disabled tests
+  which require network access or consume significant disk resources.
+
+- Several new tests in the standard test suite, with special thanks to
+  Nick Mathewson.
+
+Core
+----
+
+- The floor division operator // has been added as outlined in PEP
+  238.  The / operator still provides classic division (and will until
+  Python 3.0) unless "from __future__ import division" is included, in
+  which case the / operator will provide true division.  The operator
+  module provides truediv() and floordiv() functions.  Augmented
+  assignment variants are included, as are the equivalent overloadable
+  methods and C API methods.  See the PEP for a full discussion:
+  <http://python.sf.net/peps/pep-0238.html>
+
+- Future statements are now effective in simulated interactive shells
+  (like IDLE).  This should "just work" by magic, but read Michael
+  Hudson's "Future statements in simulated shells" PEP 264 for full
+  details:  <http://python.sf.net/peps/pep-0264.html>.
+
+- The type/class unification (PEP 252-253) was integrated into the
+  trunk and is not so tentative any more (the exact specification of
+  some features is still tentative).  A lot of work has done on fixing
+  bugs and adding robustness and features (performance still has to
+  come a long way).
+
+- Warnings about a mismatch in the Python API during extension import
+  now use the Python warning framework (which makes it possible to
+  write filters for these warnings).
+
+- A function's __dict__ (aka func_dict) will now always be a
+  dictionary.  It used to be possible to delete it or set it to None,
+  but now both actions raise TypeErrors.  It is still legal to set it
+  to a dictionary object.  Getting func.__dict__ before any attributes
+  have been assigned now returns an empty dictionary instead of None.
+
+- A new command line option, -E, was added which disables the use of
+  all environment variables, or at least those that are specifically
+  significant to Python.  Usually those have a name starting with
+  "PYTHON".  This was used to fix a problem where the tests fail if
+  the user happens to have PYTHONHOME or PYTHONPATH pointing to an
+  older distribution.
+
+Library
+-------
+
+- New class Differ and new functions ndiff() and restore() in difflib.py.
+  These package the algorithms used by the popular Tools/scripts/ndiff.py,
+  for programmatic reuse.
+
+- New function xml.sax.saxutils.quoteattr():  Quote an XML attribute
+  value using the minimal quoting required for the value; more
+  reliable than using xml.sax.saxutils.escape() for attribute values.
+
+- Readline completion support for cmd.Cmd was added.
+
+- Calling os.tempnam() or os.tmpnam() generate RuntimeWarnings.
+
+- Added function threading.BoundedSemaphore()
+
+- Added Ka-Ping Yee's cgitb.py module.
+
+- The 'new' module now exposes the CO_xxx flags.
+
+- The gc module offers the get_referents function.
+
+New platforms
+-------------
+
+C API
+-----
+
+- Two new APIs PyOS_snprintf() and PyOS_vsnprintf() were added
+  which provide a cross-platform implementations for the
+  relatively new snprintf()/vsnprintf() C lib APIs. In contrast to
+  the standard sprintf() and vsprintf() C lib APIs, these versions
+  apply bounds checking on the used buffer which enhances protection
+  against buffer overruns.
+
+- Unicode APIs now use name mangling to assure that mixing interpreters
+  and extensions using different Unicode widths is rendered next to
+  impossible. Trying to import an incompatible Unicode-aware extension
+  will result in an ImportError.  Unicode extensions writers must make
+  sure to check the Unicode width compatibility in their extensions by
+  using at least one of the mangled Unicode APIs in the extension.
+
+- Two new flags METH_NOARGS and METH_O are available in method definition
+  tables to simplify implementation of methods with no arguments and a
+  single untyped argument. Calling such methods is more efficient than
+  calling corresponding METH_VARARGS methods. METH_OLDARGS is now
+  deprecated.
+
+Windows
+-------
+
+- "import module" now compiles module.pyw if it exists and nothing else
+  relevant is found.
+
+
+What's New in Python 2.2a1?
+===========================
+
+*Release date: 18-Jul-2001*
+
+Core
+----
+
+- TENTATIVELY, a large amount of code implementing much of what's
+  described in PEP 252 (Making Types Look More Like Classes) and PEP
+  253 (Subtyping Built-in Types) was added.  This will be released
+  with Python 2.2a1.  Documentation will be provided separately
+  through http://www.python.org/2.2/.  The purpose of releasing this
+  with Python 2.2a1 is to test backwards compatibility.  It is
+  possible, though not likely, that a decision is made not to release
+  this code as part of 2.2 final, if any serious backwards
+  incompatibilities are found during alpha testing that cannot be
+  repaired.
+
+- Generators were added; this is a new way to create an iterator (see
+  below) using what looks like a simple function containing one or
+  more 'yield' statements.  See PEP 255.  Since this adds a new
+  keyword to the language, this feature must be enabled by including a
+  future statement: "from __future__ import generators" (see PEP 236).
+  Generators will become a standard feature in a future release
+  (probably 2.3).  Without this future statement, 'yield' remains an
+  ordinary identifier, but a warning is issued each time it is used.
+  (These warnings currently don't conform to the warnings framework of
+  PEP 230; we intend to fix this in 2.2a2.)
+
+- The UTF-16 codec was modified to be more RFC compliant. It will now
+  only remove BOM characters at the start of the string and then
+  only if running in native mode (UTF-16-LE and -BE won't remove a
+  leading BMO character).
+
+- Strings now have a new method .decode() to complement the already
+  existing .encode() method. These two methods provide direct access
+  to the corresponding decoders and encoders of the registered codecs.
+
+  To enhance the usability of the .encode() method, the special
+  casing of Unicode object return values was dropped (Unicode objects
+  were auto-magically converted to string using the default encoding).
+
+  Both methods will now return whatever the codec in charge of the
+  requested encoding returns as object, e.g. Unicode codecs will
+  return Unicode objects when decoding is requested ("äöü".decode("latin-1")
+  will return u"äöü"). This enables codec writer to create codecs
+  for various simple to use conversions.
+
+  New codecs were added to demonstrate these new features (the .encode()
+  and .decode() columns indicate the type of the returned objects):
+
+  +---------+-----------+-----------+-----------------------------+
+  |Name     | .encode() | .decode() | Description                 |
+  +=========+===========+===========+=============================+
+  |uu       | string    | string    | UU codec (e.g. for email)   |
+  +---------+-----------+-----------+-----------------------------+
+  |base64   | string    | string    | base64 codec                |
+  +---------+-----------+-----------+-----------------------------+
+  |quopri   | string    | string    | quoted-printable codec      |
+  +---------+-----------+-----------+-----------------------------+
+  |zlib     | string    | string    | zlib compression            |
+  +---------+-----------+-----------+-----------------------------+
+  |hex      | string    | string    | 2-byte hex codec            |
+  +---------+-----------+-----------+-----------------------------+
+  |rot-13   | string    | Unicode   | ROT-13 Unicode charmap codec|
+  +---------+-----------+-----------+-----------------------------+
+
+- Some operating systems now support the concept of a default Unicode
+  encoding for file system operations.  Notably, Windows supports 'mbcs'
+  as the default.  The Macintosh will also adopt this concept in the medium
+  term, although the default encoding for that platform will be other than
+  'mbcs'.
+
+  On operating system that support non-ASCII filenames, it is common for
+  functions that return filenames (such as os.listdir()) to return Python
+  string objects pre-encoded using the default file system encoding for
+  the platform.  As this encoding is likely to be different from Python's
+  default encoding, converting this name to a Unicode object before passing
+  it back to the Operating System would result in a Unicode error, as Python
+  would attempt to use its default encoding (generally ASCII) rather than
+  the default encoding for the file system.
+
+  In general, this change simply removes surprises when working with
+  Unicode and the file system, making these operations work as you expect,
+  increasing the transparency of Unicode objects in this context.
+  See [????] for more details, including examples.
+
+- Float (and complex) literals in source code were evaluated to full
+  precision only when running from a .py file; the same code loaded from a
+  .pyc (or .pyo) file could suffer numeric differences starting at about the
+  12th significant decimal digit.  For example, on a machine with IEEE-754
+  floating arithmetic,
+
+      x = 9007199254740992.0
+      print long(x)
+
+  printed 9007199254740992 if run directly from .py, but 9007199254740000
+  if from a compiled (.pyc or .pyo) file.  This was due to marshal using
+  str(float) instead of repr(float) when building code objects.  marshal
+  now uses repr(float) instead, which should reproduce floats to full
+  machine precision (assuming the platform C float<->string I/O conversion
+  functions are of good quality).
+
+  This may cause floating-point results to change in some cases, and
+  usually for the better, but may also cause numerically unstable
+  algorithms to break.
+
+- The implementation of dicts suffers fewer collisions, which has speed
+  benefits.  However, the order in which dict entries appear in dict.keys(),
+  dict.values() and dict.items() may differ from previous releases for a
+  given dict.  Nothing is defined about this order, so no program should
+  rely on it.  Nevertheless, it's easy to write test cases that rely on the
+  order by accident, typically because of printing the str() or repr() of a
+  dict to an "expected results" file.  See Lib/test/test_support.py's new
+  sortdict(dict) function for a simple way to display a dict in sorted
+  order.
+
+- Many other small changes to dicts were made, resulting in faster
+  operation along the most common code paths.
+
+- Dictionary objects now support the "in" operator: "x in dict" means
+  the same as dict.has_key(x).
+
+- The update() method of dictionaries now accepts generic mapping
+  objects.  Specifically the argument object must support the .keys()
+  and __getitem__() methods.  This allows you to say, for example,
+  {}.update(UserDict())
+
+- Iterators were added; this is a generalized way of providing values
+  to a for loop.  See PEP 234.  There's a new built-in function iter()
+  to return an iterator.  There's a new protocol to get the next value
+  from an iterator using the next() method (in Python) or the
+  tp_iternext slot (in C).  There's a new protocol to get iterators
+  using the __iter__() method (in Python) or the tp_iter slot (in C).
+  Iterating (i.e. a for loop) over a dictionary generates its keys.
+  Iterating over a file generates its lines.
+
+- The following functions were generalized to work nicely with iterator
+  arguments::
+
+    map(), filter(), reduce(), zip()
+    list(), tuple() (PySequence_Tuple() and PySequence_Fast() in C API)
+    max(), min()
+    join() method of strings
+    extend() method of lists
+    'x in y' and 'x not in y' (PySequence_Contains() in C API)
+    operator.countOf() (PySequence_Count() in C API)
+    right-hand side of assignment statements with multiple targets, such as ::
+        x, y, z = some_iterable_object_returning_exactly_3_values
+
+- Accessing module attributes is significantly faster (for example,
+  random.random or os.path or yourPythonModule.yourAttribute).
+
+- Comparing dictionary objects via == and != is faster, and now works even
+  if the keys and values don't support comparisons other than ==.
+
+- Comparing dictionaries in ways other than == and != is slower:  there were
+  insecurities in the dict comparison implementation that could cause Python
+  to crash if the element comparison routines for the dict keys and/or
+  values mutated the dicts.  Making the code bulletproof slowed it down.
+
+- Collisions in dicts are resolved via a new approach, which can help
+  dramatically in bad cases.  For example, looking up every key in a dict
+  d with d.keys() == [i << 16 for i in range(20000)] is approximately 500x
+  faster now.  Thanks to Christian Tismer for pointing out the cause and
+  the nature of an effective cure (last December! better late than never).
+
+- repr() is much faster for large containers (dict, list, tuple).
+
+
+Library
+-------
+
+- The constants ascii_letters, ascii_lowercase. and ascii_uppercase
+  were added to the string module.  These a locale-independent
+  constants, unlike letters, lowercase, and uppercase.  These are now
+  use in appropriate locations in the standard library.
+
+- The flags used in dlopen calls can now be configured using
+  sys.setdlopenflags and queried using sys.getdlopenflags.
+
+- Fredrik Lundh's xmlrpclib is now a standard library module.  This
+  provides full client-side XML-RPC support.  In addition,
+  Demo/xmlrpc/ contains two server frameworks (one SocketServer-based,
+  one asyncore-based).  Thanks to Eric Raymond for the documentation.
+
+- The xrange() object is simplified: it no longer supports slicing,
+  repetition, comparisons, efficient 'in' checking, the tolist()
+  method, or the start, stop and step attributes.  See PEP 260.
+
+- A new function fnmatch.filter to filter lists of file names was added.
+
+- calendar.py uses month and day names based on the current locale.
+
+- strop is now *really* obsolete (this was announced before with 1.6),
+  and issues DeprecationWarning when used (except for the four items
+  that are still imported into string.py).
+
+- Cookie.py now sorts key+value pairs by key in output strings.
+
+- pprint.isrecursive(object) didn't correctly identify recursive objects.
+  Now it does.
+
+- pprint functions now much faster for large containers (tuple, list, dict).
+
+- New 'q' and 'Q' format codes in the struct module, corresponding to C
+  types "long long" and "unsigned long long" (on Windows, __int64).  In
+  native mode, these can be used only when the platform C compiler supports
+  these types (when HAVE_LONG_LONG is #define'd by the Python config
+  process), and then they inherit the sizes and alignments of the C types.
+  In standard mode, 'q' and 'Q' are supported on all platforms, and are
+  8-byte integral types.
+
+- The site module installs a new built-in function 'help' that invokes
+  pydoc.help.  It must be invoked as 'help()'; when invoked as 'help',
+  it displays a message reminding the user to use 'help()' or
+  'help(object)'.
+
+Tests
+-----
+
+- New test_mutants.py runs dict comparisons where the key and value
+  comparison operators mutate the dicts randomly during comparison.  This
+  rapidly causes Python to crash under earlier releases (not for the faint
+  of heart:  it can also cause Win9x to freeze or reboot!).
+
+- New test_pprint.py verifies that pprint.isrecursive() and
+  pprint.isreadable() return sensible results.  Also verifies that simple
+  cases produce correct output.
+
+C API
+-----
+
+- Removed the unused last_is_sticky argument from the internal
+  _PyTuple_Resize().  If this affects you, you were cheating.
+
+What's New in Python 2.1 (final)?
+=================================
+
+We only changed a few things since the last release candidate, all in
+Python library code:
+
+- A bug in the locale module was fixed that affected locales which
+  define no grouping for numeric formatting.
+
+- A few bugs in the weakref module's implementations of weak
+  dictionaries (WeakValueDictionary and WeakKeyDictionary) were fixed,
+  and the test suite was updated to check for these bugs.
+
+- An old bug in the os.path.walk() function (introduced in Python
+  2.0!) was fixed: a non-existent file would cause an exception
+  instead of being ignored.
+
+- Fixed a few bugs in the new symtable module found by Neil Norwitz's
+  PyChecker.
+
+
+What's New in Python 2.1c2?
+===========================
+
+A flurry of small changes, and one showstopper fixed in the nick of
+time made it necessary to release another release candidate.  The list
+here is the *complete* list of patches (except version updates):
+
+Core
+
+- Tim discovered a nasty bug in the dictionary code, caused by
+  PyDict_Next() calling dict_resize(), and the GC code's use of
+  PyDict_Next() violating an assumption in dict_items().  This was
+  fixed with considerable amounts of band-aid, but the net effect is a
+  saner and more robust implementation.
+
+- Made a bunch of symbols static that were accidentally global.
+
+Build and Ports
+
+- The setup.py script didn't check for a new enough version of zlib
+  (1.1.3 is needed).  Now it does.
+
+- Changed "make clean" target to also remove shared libraries.
+
+- Added a more general warning about the SGI Irix optimizer to README.
+
+Library
+
+- Fix a bug in urllib.basejoin("http://host", "../file.html") which
+  omitted the slash between host and file.html.
+
+- The mailbox module's _Mailbox class contained a completely broken
+  and undocumented seek() method.  Ripped it out.
+
+- Fixed a bunch of typos in various library modules (urllib2, smtpd,
+  sgmllib, netrc, chunk) found by Neil Norwitz's PyChecker.
+
+- Fixed a few last-minute bugs in unittest.
+
+Extensions
+
+- Reverted the patch to the OpenSSL code in socketmodule.c to support
+  RAND_status() and the EGD, and the subsequent patch that tried to
+  fix it for pre-0.9.5 versions; the problem with the patch is that on
+  some systems it issues a warning whenever socket is imported, and
+  that's unacceptable.
+
+Tests
+
+- Fixed the pickle tests to work with "import test.test_pickle".
+
+- Tweaked test_locale.py to actually run the test Windows.
+
+- In distutils/archive_util.py, call zipfile.ZipFile() with mode "w",
+  not "wb" (which is not a valid mode at all).
+
+- Fix pstats browser crashes.  Import readline if it exists to make
+  the user interface nicer.
+
+- Add "import thread" to the top of test modules that import the
+  threading module (test_asynchat and test_threadedtempfile).  This
+  prevents test failures caused by a broken threading module resulting
+  from a previously caught failed import.
+
+- Changed test_asynchat.py to set the SO_REUSEADDR option; this was
+  needed on some platforms (e.g. Solaris 8) when the tests are run
+  twice in succession.
+
+- Skip rather than fail test_sunaudiodev if no audio device is found.
+
+
+What's New in Python 2.1c1?
+===========================
+
+This list was significantly updated when 2.1c2 was released; the 2.1c1
+release didn't mention most changes that were actually part of 2.1c1:
+
+Legal
+
+- Copyright was assigned to the Python Software Foundation (PSF) and a
+  PSF license (very similar to the CNRI license) was added.
+
+- The CNRI copyright notice was updated to include 2001.
+
+Core
+
+- After a public outcry, assignment to __debug__ is no longer illegal;
+  instead, a warning is issued.  It will become illegal in 2.2.
+
+- Fixed a core dump with "%#x" % 0, and changed the semantics so that
+  "%#x" now always prepends "0x", even if the value is zero.
+
+- Fixed some nits in the bytecode compiler.
+
+- Fixed core dumps when calling certain kinds of non-functions.
+
+- Fixed various core dumps caused by reference count bugs.
+
+Build and Ports
+
+- Use INSTALL_SCRIPT to install script files.
+
+- New port: SCO Unixware 7, by Billy G. Allie.
+
+- Updated RISCOS port.
+
+- Updated BeOS port and notes.
+
+- Various other porting problems resolved.
+
+Library
+
+- The TERMIOS and SOCKET modules are now truly obsolete and
+  unnecessary.  Their symbols are incorporated in the termios and
+  socket modules.
+
+- Fixed some 64-bit bugs in pickle, cPickle, and struct, and added
+  better tests for pickling.
+
+- threading: make Condition.wait() robust against KeyboardInterrupt.
+
+- zipfile: add support to zipfile to support opening an archive
+  represented by an open file rather than a file name.  Fix bug where
+  the archive was not properly closed.  Fixed a bug in this bugfix
+  where flush() was called for a read-only file.
+
+- imputil: added an uninstall() method to the ImportManager.
+
+- Canvas: fixed bugs in lower() and tkraise() methods.
+
+- SocketServer: API change (added overridable close_request() method)
+  so that the TCP server can explicitly close the request.
+
+- pstats: Eric Raymond added a simple interactive statistics browser,
+  invoked when the module is run as a script.
+
+- locale: fixed a problem in format().
+
+- webbrowser: made it work when the BROWSER environment variable has a
+  value like "/usr/bin/netscape".  Made it auto-detect Konqueror for
+  KDE 2.  Fixed some other nits.
+
+- unittest: changes to allow using a different exception than
+  AssertionError, and added a few more function aliases.  Some other
+  small changes.
+
+- urllib, urllib2: fixed redirect problems and a coupleof other nits.
+
+- asynchat: fixed a critical bug in asynchat that slipped through the
+  2.1b2 release.  Fixed another rare bug.
+
+- Fix some unqualified except: clauses (always a bad code example).
+
+XML
+
+- pyexpat: new API get_version_string().
+
+- Fixed some minidom bugs.
+
+Extensions
+
+- Fixed a core dump in _weakref.  Removed the weakref.mapping()
+  function (it adds nothing to the API).
+
+- Rationalized the use of header files in the readline module, to make
+  it compile (albeit with some warnings) with the very recent readline
+  4.2, without breaking for earlier versions.
+
+- Hopefully fixed a buffering problem in linuxaudiodev.
+
+- Attempted a fix to make the OpenSSL support in the socket module
+  work again with pre-0.9.5 versions of OpenSSL.
+
+Tests
+
+- Added a test case for asynchat and asyncore.
+
+- Removed coupling between tests where one test failing could break
+  another.
+
+Tools
+
+- Ping added an interactive help browser to pydoc, fixed some nits
+  in the rest of the pydoc code, and added some features to his
+  inspect module.
+
+- An updated python-mode.el version 4.1 which integrates Ken
+  Manheimer's pdbtrack.el.  This makes debugging Python code via pdb
+  much nicer in XEmacs and Emacs.  When stepping through your program
+  with pdb, in either the shell window or the *Python* window, the
+  source file and line will be tracked by an arrow.  Very cool!
+
+- IDLE: syntax warnings in interactive mode are changed into errors.
+
+- Some improvements to Tools/webchecker (ignore some more URL types,
+  follow some more links).
+
+- Brought the Tools/compiler package up to date.
+
+
+What's New in Python 2.1 beta 2?
+================================
+
+(Unlisted are many fixed bugs, more documentation, etc.)
+
+Core language, builtins, and interpreter
+
+- The nested scopes work (enabled by "from __future__ import
+  nested_scopes") is completed; in particular, the future now extends
+  into code executed through exec, eval() and execfile(), and into the
+  interactive interpreter.
+
+- When calling a base class method (e.g. BaseClass.__init__(self)),
+  this is now allowed even if self is not strictly spoken a class
+  instance (e.g. when using metaclasses or the Don Beaudry hook).
+
+- Slice objects are now comparable but not hashable; this prevents
+  dict[:] from being accepted but meaningless.
+
+- Complex division is now calculated using less braindead algorithms.
+  This doesn't change semantics except it's more likely to give useful
+  results in extreme cases.  Complex repr() now uses full precision
+  like float repr().
+
+- sgmllib.py now calls handle_decl() for simple <!...> declarations.
+
+- It is illegal to assign to the name __debug__, which is set when the
+  interpreter starts.  It is effectively a compile-time constant.
+
+- A warning will be issued if a global statement for a variable
+  follows a use or assignment of that variable.
+
+Standard library
+
+- unittest.py, a unit testing framework by Steve Purcell (PyUNIT,
+  inspired by JUnit), is now part of the standard library.  You now
+  have a choice of two testing frameworks: unittest requires you to
+  write testcases as separate code, doctest gathers them from
+  docstrings.  Both approaches have their advantages and
+  disadvantages.
+
+- A new module Tix was added, which wraps the Tix extension library
+  for Tk.  With that module, it is not necessary to statically link
+  Tix with _tkinter, since Tix will be loaded with Tcl's "package
+  require" command.  See Demo/tix/.
+
+- tzparse.py is now obsolete.
+
+- In gzip.py, the seek() and tell() methods are removed -- they were
+  non-functional anyway, and it's better if callers can test for their
+  existence with hasattr().
+
+Python/C API
+
+- PyDict_Next(): it is now safe to call PyDict_SetItem() with a key
+  that's already in the dictionary during a PyDict_Next() iteration.
+  This used to fail occasionally when a dictionary resize operation
+  could be triggered that would rehash all the keys.  All other
+  modifications to the dictionary are still off-limits during a
+  PyDict_Next() iteration!
+
+- New extended APIs related to passing compiler variables around.
+
+- New abstract APIs PyObject_IsInstance(), PyObject_IsSubclass()
+  implement isinstance() and issubclass().
+
+- Py_BuildValue() now has a "D" conversion to create a Python complex
+  number from a Py_complex C value.
+
+- Extensions types which support weak references must now set the
+  field allocated for the weak reference machinery to NULL themselves;
+  this is done to avoid the cost of checking each object for having a
+  weakly referencable type in PyObject_INIT(), since most types are
+  not weakly referencable.
+
+- PyFrame_FastToLocals() and PyFrame_LocalsToFast() copy bindings for
+  free variables and cell variables to and from the frame's f_locals.
+
+- Variants of several functions defined in pythonrun.h have been added
+  to support the nested_scopes future statement.  The variants all end
+  in Flags and take an extra argument, a PyCompilerFlags *; examples:
+  PyRun_AnyFileExFlags(), PyRun_InteractiveLoopFlags().  These
+  variants may be removed in Python 2.2, when nested scopes are
+  mandatory.
+
+Distutils
+
+- the sdist command now writes a PKG-INFO file, as described in PEP 241,
+  into the release tree.
+
+- several enhancements to the bdist_wininst command from Thomas Heller
+  (an uninstaller, more customization of the installer's display)
+
+- from Jack Jansen: added Mac-specific code to generate a dialog for
+  users to specify the command-line (because providing a command-line with
+  MacPython is awkward).  Jack also made various fixes for the Mac
+  and the Metrowerks compiler.
+
+- added 'platforms' and 'keywords' to the set of metadata that can be
+  specified for a distribution.
+
+- applied patches from Jason Tishler to make the compiler class work with
+  Cygwin.
+
+
+What's New in Python 2.1 beta 1?
+================================
+
+Core language, builtins, and interpreter
+
+- Following an outcry from the community about the amount of code
+  broken by the nested scopes feature introduced in 2.1a2, we decided
+  to make this feature optional, and to wait until Python 2.2 (or at
+  least 6 months) to make it standard.  The option can be enabled on a
+  per-module basis by adding "from __future__ import nested_scopes" at
+  the beginning of a module (before any other statements, but after
+  comments and an optional docstring).  See PEP 236 (Back to the
+  __future__) for a description of the __future__ statement.  PEP 227
+  (Statically Nested Scopes) has been updated to reflect this change,
+  and to clarify the semantics in a number of endcases.
+
+- The nested scopes code, when enabled, has been hardened, and most
+  bugs and memory leaks in it have been fixed.
+
+- Compile-time warnings are now generated for a number of conditions
+  that will break or change in meaning when nested scopes are enabled:
+
+  - Using "from...import *" or "exec" without in-clause in a function
+    scope that also defines a lambda or nested function with one or
+    more free (non-local) variables.  The presence of the import* or
+    bare exec makes it impossible for the compiler to determine the
+    exact set of local variables in the outer scope, which makes it
+    impossible to determine the bindings for free variables in the
+    inner scope.  To avoid the warning about import *, change it into
+    an import of explicitly name object, or move the import* statement
+    to the global scope; to avoid the warning about bare exec, use
+    exec...in... (a good idea anyway -- there's a possibility that
+    bare exec will be deprecated in the future).
+
+  - Use of a global variable in a nested scope with the same name as a
+    local variable in a surrounding scope.  This will change in
+    meaning with nested scopes: the name in the inner scope will
+    reference the variable in the outer scope rather than the global
+    of the same name.  To avoid the warning, either rename the outer
+    variable, or use a global statement in the inner function.
+
+- An optional object allocator has been included.  This allocator is
+  optimized for Python objects and should be faster and use less memory
+  than the standard system allocator.  It is not enabled by default
+  because of possible thread safety problems.  The allocator is only
+  protected by the Python interpreter lock and it is possible that some
+  extension modules require a thread safe allocator.  The object
+  allocator can be enabled by providing the "--with-pymalloc" option to
+  configure.
+
+Standard library
+
+- pyexpat now detects the expat version if expat.h defines it. A
+  number of additional handlers are provided, which are only available
+  since expat 1.95. In addition, the methods SetParamEntityParsing and
+  GetInputContext of Parser objects are available with 1.95.x
+  only. Parser objects now provide the ordered_attributes and
+  specified_attributes attributes. A new module expat.model was added,
+  which offers a number of additional constants if 1.95.x is used.
+
+- xml.dom offers the new functions registerDOMImplementation and
+  getDOMImplementation.
+
+- xml.dom.minidom offers a toprettyxml method. A number of DOM
+  conformance issues have been resolved. In particular, Element now
+  has an hasAttributes method, and the handling of namespaces was
+  improved.
+
+- Ka-Ping Yee contributed two new modules: inspect.py, a module for
+  getting information about live Python code, and pydoc.py, a module
+  for interactively converting docstrings to HTML or text.
+  Tools/scripts/pydoc, which is now automatically installed into
+  <prefix>/bin, uses pydoc.py to display documentation; try running
+  "pydoc -h" for instructions.  "pydoc -g" pops up a small GUI that
+  lets you browse the module docstrings using a web browser.
+
+- New library module difflib.py, primarily packaging the SequenceMatcher
+  class at the heart of the popular ndiff.py file-comparison tool.
+
+- doctest.py (a framework for verifying Python code examples in docstrings)
+  is now part of the std library.
+
+Windows changes
+
+- A new entry in the Start menu, "Module Docs", runs "pydoc -g" -- a
+  small GUI that lets you browse the module docstrings using your
+  default web browser.
+
+- Import is now case-sensitive.  PEP 235 (Import on Case-Insensitive
+  Platforms) is implemented.  See
+
+      http://python.sourceforge.net/peps/pep-0235.html
+
+  for full details, especially the "Current Lower-Left Semantics" section.
+  The new Windows import rules are simpler than before:
+
+  A. If the PYTHONCASEOK environment variable exists, same as
+     before:  silently accept the first case-insensitive match of any
+     kind; raise ImportError if none found.
+
+  B. Else search sys.path for the first case-sensitive match; raise
+     ImportError if none found.
+
+  The same rules have been implemented on other platforms with case-
+  insensitive but case-preserving filesystems too (including Cygwin, and
+  several flavors of Macintosh operating systems).
+
+- winsound module:  Under Win9x, winsound.Beep() now attempts to simulate
+  what it's supposed to do (and does do under NT and 2000) via direct
+  port manipulation.  It's unknown whether this will work on all systems,
+  but it does work on my Win98SE systems now and was known to be useless on
+  all Win9x systems before.
+
+- Build:  Subproject _test (effectively) renamed to _testcapi.
+
+New platforms
+
+- 2.1 should compile and run out of the box under MacOS X, even using HFS+.
+  Thanks to Steven Majewski!
+
+- 2.1 should compile and run out of the box on Cygwin.  Thanks to Jason
+  Tishler!
+
+- 2.1 contains new files and patches for RISCOS, thanks to Dietmar
+  Schwertberger!  See RISCOS/README for more information -- it seems
+  that because of the bizarre filename conventions on RISCOS, no port
+  to that platform is easy.
+
+
+What's New in Python 2.1 alpha 2?
+=================================
+
+Core language, builtins, and interpreter
+
+- Scopes nest.  If a name is used in a function or class, but is not
+  local, the definition in the nearest enclosing function scope will
+  be used.  One consequence of this change is that lambda statements
+  could reference variables in the namespaces where the lambda is
+  defined.  In some unusual cases, this change will break code.
+
+  In all previous version of Python, names were resolved in exactly
+  three namespaces -- the local namespace, the global namespace, and
+  the builtin namespace.  According to this old definition, if a
+  function A is defined within a function B, the names bound in B are
+  not visible in A.  The new rules make names bound in B visible in A,
+  unless A contains a name binding that hides the binding in B.
+
+  Section 4.1 of the reference manual describes the new scoping rules
+  in detail.  The test script in Lib/test/test_scope.py demonstrates
+  some of the effects of the change.
+
+  The new rules will cause existing code to break if it defines nested
+  functions where an outer function has local variables with the same
+  name as globals or builtins used by the inner function.  Example:
+
+    def munge(str):
+        def helper(x):
+            return str(x)
+        if type(str) != type(''):
+            str = helper(str)
+        return str.strip()
+
+  Under the old rules, the name str in helper() is bound to the
+  builtin function str().  Under the new rules, it will be bound to
+  the argument named str and an error will occur when helper() is
+  called.
+
+- The compiler will report a SyntaxError if "from ... import *" occurs
+  in a function or class scope.  The language reference has documented
+  that this case is illegal, but the compiler never checked for it.
+  The recent introduction of nested scope makes the meaning of this
+  form of name binding ambiguous.  In a future release, the compiler
+  may allow this form when there is no possibility of ambiguity.
+
+- repr(string) is easier to read, now using hex escapes instead of octal,
+  and using \t, \n and \r instead of \011, \012 and \015 (respectively):
+
+  >>> "\texample \r\n" + chr(0) + chr(255)
+  '\texample \r\n\x00\xff'         # in 2.1
+  '\011example \015\012\000\377'   # in 2.0
+
+- Functions are now compared and hashed by identity, not by value, since
+  the func_code attribute is writable.
+
+- Weak references (PEP 205) have been added.  This involves a few
+  changes in the core, an extension module (_weakref), and a Python
+  module (weakref).  The weakref module is the public interface.  It
+  includes support for "explicit" weak references, proxy objects, and
+  mappings with weakly held values.
+
+- A 'continue' statement can now appear in a try block within the body
+  of a loop.  It is still not possible to use continue in a finally
+  clause.
+
+Standard library
+
+- mailbox.py now has a new class, PortableUnixMailbox which is
+  identical to UnixMailbox but uses a more portable scheme for
+  determining From_ separators.  Also, the constructors for all the
+  classes in this module have a new optional `factory' argument, which
+  is a callable used when new message classes must be instantiated by
+  the next() method.
+
+- random.py is now self-contained, and offers all the functionality of
+  the now-deprecated whrandom.py.  See the docs for details.  random.py
+  also supports new functions getstate() and setstate(), for saving
+  and restoring the internal state of the generator; and jumpahead(n),
+  for quickly forcing the internal state to be the same as if n calls to
+  random() had been made.  The latter is particularly useful for multi-
+  threaded programs, creating one instance of the random.Random() class for
+  each thread, then using .jumpahead() to force each instance to use a
+  non-overlapping segment of the full period.
+
+- random.py's seed() function is new.  For bit-for-bit compatibility with
+  prior releases, use the whseed function instead.  The new seed function
+  addresses two problems:  (1) The old function couldn't produce more than
+  about 2**24 distinct internal states; the new one about 2**45 (the best
+  that can be done in the Wichmann-Hill generator).  (2) The old function
+  sometimes produced identical internal states when passed distinct
+  integers, and there was no simple way to predict when that would happen;
+  the new one guarantees to produce distinct internal states for all
+  arguments in [0, 27814431486576L).
+
+- The socket module now supports raw packets on Linux.  The socket
+  family is AF_PACKET.
+
+- test_capi.py is a start at running tests of the Python C API.  The tests
+  are implemented by the new Modules/_testmodule.c.
+
+- A new extension module, _symtable, provides provisional access to the
+  internal symbol table used by the Python compiler.  A higher-level
+  interface will be added on top of _symtable in a future release.
+
+- Removed the obsolete soundex module.
+
+- xml.dom.minidom now uses the standard DOM exceptions. Node supports
+  the isSameNode method; NamedNodeMap the get method.
+
+- xml.sax.expatreader supports the lexical handler property; it
+  generates comment, startCDATA, and endCDATA events.
+
+Windows changes
+
+- Build procedure:  the zlib project is built in a different way that
+  ensures the zlib header files used can no longer get out of synch with
+  the zlib binary used.  See PCbuild\readme.txt for details.  Your old
+  zlib-related directories can be deleted; you'll need to download fresh
+  source for zlib and unpack it into a new directory.
+
+- Build:  New subproject _test for the benefit of test_capi.py (see above).
+
+- Build:  New subproject _symtable, for new DLL _symtable.pyd (a nascent
+  interface to some Python compiler internals).
+
+- Build:  Subproject ucnhash is gone, since the code was folded into the
+  unicodedata subproject.
+
+What's New in Python 2.1 alpha 1?
+=================================
+
+Core language, builtins, and interpreter
+
+- There is a new Unicode companion to the PyObject_Str() API
+  called PyObject_Unicode(). It behaves in the same way as the
+  former, but assures that the returned value is an Unicode object
+  (applying the usual coercion if necessary).
+
+- The comparison operators support "rich comparison overloading" (PEP
+  207).  C extension types can provide a rich comparison function in
+  the new tp_richcompare slot in the type object.  The cmp() function
+  and the C function PyObject_Compare() first try the new rich
+  comparison operators before trying the old 3-way comparison.  There
+  is also a new C API PyObject_RichCompare() (which also falls back on
+  the old 3-way comparison, but does not constrain the outcome of the
+  rich comparison to a Boolean result).
+
+  The rich comparison function takes two objects (at least one of
+  which is guaranteed to have the type that provided the function) and
+  an integer indicating the opcode, which can be Py_LT, Py_LE, Py_EQ,
+  Py_NE, Py_GT, Py_GE (for <, <=, ==, !=, >, >=), and returns a Python
+  object, which may be NotImplemented (in which case the tp_compare
+  slot function is used as a fallback, if defined).
+
+  Classes can overload individual comparison operators by defining one
+  or more of the methods__lt__, __le__, __eq__, __ne__, __gt__,
+  __ge__.  There are no explicit "reflected argument" versions of
+  these; instead, __lt__ and __gt__ are each other's reflection,
+  likewise for__le__ and __ge__; __eq__ and __ne__ are their own
+  reflection (similar at the C level).  No other implications are
+  made; in particular, Python does not assume that == is the Boolean
+  inverse of !=, or that < is the Boolean inverse of >=.  This makes
+  it possible to define types with partial orderings.
+
+  Classes or types that want to implement (in)equality tests but not
+  the ordering operators (i.e. unordered types) should implement ==
+  and !=, and raise an error for the ordering operators.
+
+  It is possible to define types whose rich comparison results are not
+  Boolean; e.g. a matrix type might want to return a matrix of bits
+  for A < B, giving elementwise comparisons.  Such types should ensure
+  that any interpretation of their value in a Boolean context raises
+  an exception, e.g. by defining __nonzero__ (or the tp_nonzero slot
+  at the C level) to always raise an exception.
+
+- Complex numbers use rich comparisons to define == and != but raise
+  an exception for <, <=, > and >=.  Unfortunately, this also means
+  that cmp() of two complex numbers raises an exception when the two
+  numbers differ.  Since it is not mathematically meaningful to compare
+  complex numbers except for equality, I hope that this doesn't break
+  too much code.
+
+- The outcome of comparing non-numeric objects of different types is
+  not defined by the language, other than that it's arbitrary but
+  consistent (see the Reference Manual).  An implementation detail changed
+  in 2.1a1 such that None now compares less than any other object.  Code
+  relying on this new behavior (like code that relied on the previous
+  behavior) does so at its own risk.
+
+- Functions and methods now support getting and setting arbitrarily
+  named attributes (PEP 232).  Functions have a new __dict__
+  (a.k.a. func_dict) which hold the function attributes.  Methods get
+  and set attributes on their underlying im_func.  It is a TypeError
+  to set an attribute on a bound method.
+
+- The xrange() object implementation has been improved so that
+  xrange(sys.maxint) can be used on 64-bit platforms.  There's still a
+  limitation that in this case len(xrange(sys.maxint)) can't be
+  calculated, but the common idiom "for i in xrange(sys.maxint)" will
+  work fine as long as the index i doesn't actually reach 2**31.
+  (Python uses regular ints for sequence and string indices; fixing
+  that is much more work.)
+
+- Two changes to from...import:
+
+  1) "from M import X" now works even if (after loading module M)
+     sys.modules['M'] is not a real module; it's basically a getattr()
+     operation with AttributeError exceptions changed into ImportError.
+
+  2) "from M import *" now looks for M.__all__ to decide which names to
+     import; if M.__all__ doesn't exist, it uses M.__dict__.keys() but
+     filters out names starting with '_' as before.  Whether or not
+     __all__ exists, there's no restriction on the type of M.
+
+- File objects have a new method, xreadlines().  This is the fastest
+  way to iterate over all lines in a file:
+
+  for line in file.xreadlines():
+      ...do something to line...
+
+  See the xreadlines module (mentioned below) for how to do this for
+  other file-like objects.
+
+- Even if you don't use file.xreadlines(), you may expect a speedup on
+  line-by-line input.  The file.readline() method has been optimized
+  quite a bit in platform-specific ways:  on systems (like Linux) that
+  support flockfile(), getc_unlocked(), and funlockfile(), those are
+  used by default.  On systems (like Windows) without getc_unlocked(),
+  a complicated (but still thread-safe) method using fgets() is used by
+  default.
+
+  You can force use of the fgets() method by #define'ing
+  USE_FGETS_IN_GETLINE at build time (it may be faster than
+  getc_unlocked()).
+
+  You can force fgets() not to be used by #define'ing
+  DONT_USE_FGETS_IN_GETLINE (this is the first thing to try if std test
+  test_bufio.py fails -- and let us know if it does!).
+
+- In addition, the fileinput module, while still slower than the other
+  methods on most platforms, has been sped up too, by using
+  file.readlines(sizehint).
+
+- Support for run-time warnings has been added, including a new
+  command line option (-W) to specify the disposition of warnings.
+  See the description of the warnings module below.
+
+- Extensive changes have been made to the coercion code.  This mostly
+  affects extension modules (which can now implement mixed-type
+  numerical operators without having to use coercion), but
+  occasionally, in boundary cases the coercion semantics have changed
+  subtly.  Since this was a terrible gray area of the language, this
+  is considered an improvement.  Also note that __rcmp__ is no longer
+  supported -- instead of calling __rcmp__, __cmp__ is called with
+  reflected arguments.
+
+- In connection with the coercion changes, a new built-in singleton
+  object, NotImplemented is defined.  This can be returned for
+  operations that wish to indicate they are not implemented for a
+  particular combination of arguments.  From C, this is
+  Py_NotImplemented.
+
+- The interpreter accepts now bytecode files on the command line even
+  if they do not have a .pyc or .pyo extension. On Linux, after executing
+
+import imp,sys,string
+magic = string.join(["\\x%.2x" % ord(c) for c in imp.get_magic()],"")
+reg = ':pyc:M::%s::%s:' % (magic, sys.executable)
+open("/proc/sys/fs/binfmt_misc/register","wb").write(reg)
+
+  any byte code file can be used as an executable (i.e. as an argument
+  to execve(2)).
+
+- %[xXo] formats of negative Python longs now produce a sign
+  character.  In 1.6 and earlier, they never produced a sign,
+  and raised an error if the value of the long was too large
+  to fit in a Python int.  In 2.0, they produced a sign if and
+  only if too large to fit in an int.  This was inconsistent
+  across platforms (because the size of an int varies across
+  platforms), and inconsistent with hex() and oct().  Example:
+
+  >>> "%x" % -0x42L
+  '-42'      # in 2.1
+  'ffffffbe' # in 2.0 and before, on 32-bit machines
+  >>> hex(-0x42L)
+  '-0x42L'   # in all versions of Python
+
+  The behavior of %d formats for negative Python longs remains
+  the same as in 2.0 (although in 1.6 and before, they raised
+  an error if the long didn't fit in a Python int).
+
+  %u formats don't make sense for Python longs, but are allowed
+  and treated the same as %d in 2.1.  In 2.0, a negative long
+  formatted via %u produced a sign if and only if too large to
+  fit in an int.  In 1.6 and earlier, a negative long formatted
+  via %u raised an error if it was too big to fit in an int.
+
+- Dictionary objects have an odd new method, popitem().  This removes
+  an arbitrary item from the dictionary and returns it (in the form of
+  a (key, value) pair).  This can be useful for algorithms that use a
+  dictionary as a bag of "to do" items and repeatedly need to pick one
+  item.  Such algorithms normally end up running in quadratic time;
+  using popitem() they can usually be made to run in linear time.
+
+Standard library
+
+- In the time module, the time argument to the functions strftime,
+  localtime, gmtime, asctime and ctime is now optional, defaulting to
+  the current time (in the local timezone).
+
+- The ftplib module now defaults to passive mode, which is deemed a
+  more useful default given that clients are often inside firewalls
+  these days.  Note that this could break if ftplib is used to connect
+  to a *server* that is inside a firewall, from outside; this is
+  expected to be a very rare situation.  To fix that, you can call
+  ftp.set_pasv(0).
+
+- The module site now treats .pth files not only for path configuration,
+  but also supports extensions to the initialization code: Lines starting
+  with import are executed.
+
+- There's a new module, warnings, which implements a mechanism for
+  issuing and filtering warnings.  There are some new built-in
+  exceptions that serve as warning categories, and a new command line
+  option, -W, to control warnings (e.g. -Wi ignores all warnings, -We
+  turns warnings into errors).  warnings.warn(message[, category])
+  issues a warning message; this can also be called from C as
+  PyErr_Warn(category, message).
+
+- A new module xreadlines was added.  This exports a single factory
+  function, xreadlines().  The intention is that this code is the
+  absolutely fastest way to iterate over all lines in an open
+  file(-like) object:
+
+  import xreadlines
+  for line in xreadlines.xreadlines(file):
+      ...do something to line...
+
+  This is equivalent to the previous the speed record holder using
+  file.readlines(sizehint).  Note that if file is a real file object
+  (as opposed to a file-like object), this is equivalent:
+
+  for line in file.xreadlines():
+      ...do something to line...
+
+- The bisect module has new functions bisect_left, insort_left,
+  bisect_right and insort_right.  The old names bisect and insort
+  are now aliases for bisect_right and insort_right.  XXX_right
+  and XXX_left methods differ in what happens when the new element
+  compares equal to one or more elements already in the list:  the
+  XXX_left methods insert to the left, the XXX_right methods to the
+  right.  Code that doesn't care where equal elements end up should
+  continue to use the old, short names ("bisect" and "insort").
+
+- The new curses.panel module wraps the panel library that forms part
+  of SYSV curses and ncurses.  Contributed by Thomas Gellekum.
+
+- The SocketServer module now sets the allow_reuse_address flag by
+  default in the TCPServer class.
+
+- A new function, sys._getframe(), returns the stack frame pointer of
+  the caller.  This is intended only as a building block for
+  higher-level mechanisms such as string interpolation.
+
+- The pyexpat module supports a number of new handlers, which are
+  available only in expat 1.2. If invocation of a callback fails, it
+  will report an additional frame in the traceback. Parser objects
+  participate now in garbage collection. If expat reports an unknown
+  encoding, pyexpat will try to use a Python codec; that works only
+  for single-byte charsets. The parser type objects is exposed as
+  XMLParserObject.
+
+- xml.dom now offers standard definitions for symbolic node type and
+  exception code constants, and a hierarchy of DOM exceptions. minidom
+  was adjusted to use them.
+
+- The conformance of xml.dom.minidom to the DOM specification was
+  improved. It detects a number of additional error cases; the
+  previous/next relationship works even when the tree is modified;
+  Node supports the normalize() method; NamedNodeMap, DocumentType and
+  DOMImplementation classes were added; Element supports the
+  hasAttribute and hasAttributeNS methods; and Text supports the splitText
+  method.
+
+Build issues
+
+- For Unix (and Unix-compatible) builds, configuration and building of
+  extension modules is now greatly automated.  Rather than having to
+  edit the Modules/Setup file to indicate which modules should be
+  built and where their include files and libraries are, a
+  distutils-based setup.py script now takes care of building most
+  extension modules.  All extension modules built this way are built
+  as shared libraries.  Only a few modules that must be linked
+  statically are still listed in the Setup file; you won't need to
+  edit their configuration.
+
+- Python should now build out of the box on Cygwin.  If it doesn't,
+  mail to Jason Tishler (jlt63 at users.sourceforge.net).
+
+- Python now always uses its own (renamed) implementation of getopt()
+  -- there's too much variation among C library getopt()
+  implementations.
+
+- C++ compilers are better supported; the CXX macro is always set to a
+  C++ compiler if one is found.
+
+Windows changes
+
+- select module:  By default under Windows, a select() call
+  can specify no more than 64 sockets.  Python now boosts
+  this Microsoft default to 512.  If you need even more than
+  that, see the MS docs (you'll need to #define FD_SETSIZE
+  and recompile Python from source).
+
+- Support for Windows 3.1, DOS and OS/2 is gone.  The Lib/dos-8x3
+  subdirectory is no more!
+
+
+What's New in Python 2.0?
+=========================
+
+Below is a list of all relevant changes since release 1.6.  Older
+changes are in the file HISTORY.  If you are making the jump directly
+from Python 1.5.2 to 2.0, make sure to read the section for 1.6 in the
+HISTORY file!  Many important changes listed there.
+
+Alternatively, a good overview of the changes between 1.5.2 and 2.0 is
+the document "What's New in Python 2.0" by Kuchling and Moshe Zadka:
+http://www.amk.ca/python/2.0/.
+
+--Guido van Rossum (home page: http://www.pythonlabs.com/~guido/)
+
+======================================================================
+
+What's new in 2.0 (since release candidate 1)?
+==============================================
+
+Standard library
+
+- The copy_reg module was modified to clarify its intended use: to
+  register pickle support for extension types, not for classes.
+  pickle() will raise a TypeError if it is passed a class.
+
+- Fixed a bug in gettext's "normalize and expand" code that prevented
+  it from finding an existing .mo file.
+
+- Restored support for HTTP/0.9 servers in httplib.
+
+- The math module was changed to stop raising OverflowError in case of
+  underflow, and return 0 instead in underflow cases.  Whether Python
+  used to raise OverflowError in case of underflow was platform-
+  dependent (it did when the platform math library set errno to ERANGE
+  on underflow).
+
+- Fixed a bug in StringIO that occurred when the file position was not
+  at the end of the file and write() was called with enough data to
+  extend past the end of the file.
+
+- Fixed a bug that caused Tkinter error messages to get lost on
+  Windows.  The bug was fixed by replacing direct use of
+  interp->result with Tcl_GetStringResult(interp).
+
+- Fixed bug in urllib2 that caused it to fail when it received an HTTP
+  redirect response.
+
+- Several changes were made to distutils: Some debugging code was
+  removed from util.  Fixed the installer used when an external zip
+  program (like WinZip) is not found; the source code for this
+  installer is in Misc/distutils.  check_lib() was modified to behave
+  more like AC_CHECK_LIB by add other_libraries() as a parameter.  The
+  test for whether installed modules are on sys.path was changed to
+  use both normcase() and normpath().
+
+- Several minor bugs were fixed in the xml package (the minidom,
+  pulldom, expatreader, and saxutils modules).
+
+- The regression test driver (regrtest.py) behavior when invoked with
+  -l changed: It now reports a count of objects that are recognized as
+  garbage but not freed by the garbage collector.
+
+- The regression test for the math module was changed to test
+  exceptional behavior when the test is run in verbose mode.  Python
+  cannot yet guarantee consistent exception behavior across platforms,
+  so the exception part of test_math is run only in verbose mode, and
+  may fail on your platform.
+
+Internals
+
+- PyOS_CheckStack() has been disabled on Win64, where it caused
+  test_sre to fail.
+
+Build issues
+
+- Changed compiler flags, so that gcc is always invoked with -Wall and
+  -Wstrict-prototypes.  Users compiling Python with GCC should see
+  exactly one warning, except if they have passed configure the
+  --with-pydebug flag.  The expected warning is for getopt() in
+  Modules/main.c.  This warning will be fixed for Python 2.1.
+
+- Fixed configure to add -threads argument during linking on OSF1.
+
+Tools and other miscellany
+
+- The compiler in Tools/compiler was updated to support the new
+  language features introduced in 2.0: extended print statement, list
+  comprehensions, and augmented assignments.  The new compiler should
+  also be backwards compatible with Python 1.5.2; the compiler will
+  always generate code for the version of the interpreter it runs
+  under.
+
+What's new in 2.0 release candidate 1 (since beta 2)?
+=====================================================
+
+What is release candidate 1?
+
+We believe that release candidate 1 will fix all known bugs that we
+intend to fix for the 2.0 final release.  This release should be a bit
+more stable than the previous betas.  We would like to see even more
+widespread testing before the final release, so we are producing this
+release candidate.  The final release will be exactly the same unless
+any show-stopping (or brown bag) bugs are found by testers of the
+release candidate.
+
+All the changes since the last beta release are bug fixes or changes
+to support building Python for specific platforms.
+
+Core language, builtins, and interpreter
+
+- A bug that caused crashes when __coerce__ was used with augmented
+  assignment, e.g. +=, was fixed.
+
+- Raise ZeroDivisionError when raising zero to a negative number,
+  e.g. 0.0 ** -2.0.  Note that math.pow is unrelated to the builtin
+  power operator and the result of math.pow(0.0, -2.0) will vary by
+  platform.  On Linux, it raises a ValueError.
+
+- A bug in Unicode string interpolation was fixed that occasionally
+  caused errors with formats including "%%".  For example, the
+  following expression "%% %s" % u"abc" no longer raises a TypeError.
+
+- Compilation of deeply nested expressions raises MemoryError instead
+  of SyntaxError, e.g. eval("[" * 50 + "]" * 50).
+
+- In 2.0b2 on Windows, the interpreter wrote .pyc files in text mode,
+  rendering them useless.  They are now written in binary mode again.
+
+Standard library
+
+- Keyword arguments are now accepted for most pattern and match object
+  methods in SRE, the standard regular expression engine.
+
+- In SRE, fixed error with negative lookahead and lookbehind that
+  manifested itself as a runtime error in patterns like "(?<!abc)(def)".
+
+- Several bugs in the Unicode handling and error handling in _tkinter
+  were fixed.
+
+- Fix memory management errors in Merge() and Tkapp_Call() routines.
+
+- Several changes were made to cStringIO to make it compatible with
+  the file-like object interface and with StringIO.  If operations are
+  performed on a closed object, an exception is raised.  The truncate
+  method now accepts a position argument and readline accepts a size
+  argument.
+
+- There were many changes made to the linuxaudiodev module and its
+  test suite; as a result, a short, unexpected audio sample should now
+  play when the regression test is run.
+
+  Note that this module is named poorly, because it should work
+  correctly on any platform that supports the Open Sound System
+  (OSS).
+
+  The module now raises exceptions when errors occur instead of
+  crashing.  It also defines the AFMT_A_LAW format (logarithmic A-law
+  audio) and defines a getptr() method that calls the
+  SNDCTL_DSP_GETxPTR ioctl defined in the OSS Programmer's Guide.
+
+- The library_version attribute, introduced in an earlier beta, was
+  removed because it can not be supported with early versions of the C
+  readline library, which provides no way to determine the version at
+  compile-time.
+
+- The binascii module is now enabled on Win64.
+
+- tokenize.py no longer suffers "recursion depth" errors when parsing
+  programs with very long string literals.
+
+Internals
+
+- Fixed several buffer overflow vulnerabilities in calculate_path(),
+  which is called when the interpreter starts up to determine where
+  the standard library is installed.  These vulnerabilities affect all
+  previous versions of Python and can be exploited by setting very
+  long values for PYTHONHOME or argv[0].  The risk is greatest for a
+  setuid Python script, although use of the wrapper in
+  Misc/setuid-prog.c will eliminate the vulnerability.
+
+- Fixed garbage collection bugs in instance creation that were
+  triggered when errors occurred during initialization.  The solution,
+  applied in cPickle and in PyInstance_New(), is to call
+  PyObject_GC_Init() after the initialization of the object's
+  container attributes is complete.
+
+- pyexpat adds definitions of PyModule_AddStringConstant and
+  PyModule_AddObject if the Python version is less than 2.0, which
+  provides compatibility with PyXML on Python 1.5.2.
+
+- If the platform has a bogus definition for LONG_BIT (the number of
+  bits in a long), an error will be reported at compile time.
+
+- Fix bugs in _PyTuple_Resize() which caused hard-to-interpret garbage
+  collection crashes and possibly other, unreported crashes.
+
+- Fixed a memory leak in _PyUnicode_Fini().
+
+Build issues
+
+- configure now accepts a --with-suffix option that specifies the
+  executable suffix.  This is useful for builds on Cygwin and Mac OS
+  X, for example.
+
+- The mmap.PAGESIZE constant is now initialized using sysconf when
+  possible, which eliminates a dependency on -lucb for Reliant UNIX.
+
+- The md5 file should now compile on all platforms.
+
+- The select module now compiles on platforms that do not define
+  POLLRDNORM and related constants.
+
+- Darwin (Mac OS X):  Initial support for static builds on this
+  platform.
+
+- BeOS: A number of changes were made to the build and installation
+  process.  ar-fake now operates on a directory of object files.
+  dl_export.h is gone, and its macros now appear on the mwcc command
+  line during build on PPC BeOS.
+
+- Platform directory in lib/python2.0 is "plat-beos5" (or
+  "plat-beos4", if building on BeOS 4.5), rather than "plat-beos".
+
+- Cygwin: Support for shared libraries, Tkinter, and sockets.
+
+- SunOS 4.1.4_JL: Fix test for directory existence in configure.
+
+Tools and other miscellany
+
+- Removed debugging prints from main used with freeze.
+
+- IDLE auto-indent no longer crashes when it encounters Unicode
+  characters.
+
+What's new in 2.0 beta 2 (since beta 1)?
+========================================
+
+Core language, builtins, and interpreter
+
+- Add support for unbounded ints in %d,i,u,x,X,o formats; for example
+  "%d" % 2L**64 == "18446744073709551616".
+
+- Add -h and -V command line options to print the usage message and
+  Python version number and exit immediately.
+
+- eval() and exec accept Unicode objects as code parameters.
+
+- getattr() and setattr() now also accept Unicode objects for the
+  attribute name, which are converted to strings using the default
+  encoding before lookup.
+
+- Multiplication on string and Unicode now does proper bounds
+  checking; e.g. 'a' * 65536 * 65536 will raise ValueError, "repeated
+  string is too long."
+
+- Better error message when continue is found in try statement in a
+  loop.
+
+
+Standard library and extensions
+
+- socket module: the OpenSSL code now adds support for RAND_status()
+  and EGD (Entropy Gathering Device).
+
+- array: reverse() method of array now works.  buffer_info() now does
+  argument checking; it still takes no arguments.
+
+- asyncore/asynchat: Included most recent version from Sam Rushing.
+
+- cgi: Accept '&' or ';' as separator characters when parsing form data.
+
+- CGIHTTPServer: Now works on Windows (and perhaps even Mac).
+
+- ConfigParser: When reading the file, options spelled in upper case
+  letters are now correctly converted to lowercase.
+
+- copy: Copy Unicode objects atomically.
+
+- cPickle: Fail gracefully when copy_reg can't be imported.
+
+- cStringIO: Implemented readlines() method.
+
+- dbm: Add get() and setdefault() methods to dbm object.  Add constant
+  `library' to module that names the library used.  Added doc strings
+  and method names to error messages.  Uses configure to determine
+  which ndbm.h file to include; Berkeley DB's nbdm and GDBM's ndbm is
+  now available options.
+
+- distutils: Update to version 0.9.3.
+
+- dl: Add several dl.RTLD_ constants.
+
+- fpectl: Now supported on FreeBSD.
+
+- gc: Add DEBUG_SAVEALL option.  When enabled all garbage objects
+  found by the collector will be saved in gc.garbage.  This is useful
+  for debugging a program that creates reference cycles.
+
+- httplib: Three changes: Restore support for set_debuglevel feature
+  of HTTP class.  Do not close socket on zero-length response.  Do not
+  crash when server sends invalid content-length header.
+
+- mailbox: Mailbox class conforms better to qmail specifications.
+
+- marshal: When reading a short, sign-extend on platforms where shorts
+  are bigger than 16 bits.  When reading a long, repair the unportable
+  sign extension that was being done for 64-bit machines.  (It assumed
+  that signed right shift sign-extends.)
+
+- operator: Add contains(), invert(), __invert__() as aliases for
+  __contains__(), inv(), and __inv__() respectively.
+
+- os: Add support for popen2() and popen3() on all platforms where
+  fork() exists.  (popen4() is still in the works.)
+
+- os: (Windows only:) Add startfile() function that acts like double-
+  clicking on a file in Explorer (or passing the file name to the
+  DOS "start" command).
+
+- os.path: (Windows, DOS:) Treat trailing colon correctly in
+  os.path.join.  os.path.join("a:", "b") yields "a:b".
+
+- pickle: Now raises ValueError when an invalid pickle that contains
+  a non-string repr where a string repr was expected.  This behavior
+  matches cPickle.
+
+- posixfile: Remove broken __del__() method.
+
+- py_compile: support CR+LF line terminators in source file.
+
+- readline: Does not immediately exit when ^C is hit when readline and
+  threads are configured.  Adds definition of rl_library_version.  (The
+  latter addition requires GNU readline 2.2 or later.)
+
+- rfc822: Domain literals returned by AddrlistClass method
+  getdomainliteral() are now properly wrapped in brackets.
+
+- site: sys.setdefaultencoding() should only be called in case the
+  standard default encoding ("ascii") is changed. This saves quite a
+  few cycles during startup since the first call to
+  setdefaultencoding() will initialize the codec registry and the
+  encodings package.
+
+- socket: Support for size hint in readlines() method of object returned
+  by makefile().
+
+- sre: Added experimental expand() method to match objects.  Does not
+  use buffer interface on Unicode strings.  Does not hang if group id
+  is followed by whitespace.
+
+- StringIO: Size hint in readlines() is now supported as documented.
+
+- struct: Check ranges for bytes and shorts.
+
+- urllib: Improved handling of win32 proxy settings. Fixed quote and
+  quote_plus functions so that the always encode a comma.
+
+- Tkinter: Image objects are now guaranteed to have unique ids.  Set
+  event.delta to zero if Tk version doesn't support mousewheel.
+  Removed some debugging prints.
+
+- UserList: now implements __contains__().
+
+- webbrowser: On Windows, use os.startfile() instead of os.popen(),
+  which works around a bug in Norton AntiVirus 2000 that leads directly
+  to a Blue Screen freeze.
+
+- xml: New version detection code allows PyXML to override standard
+  XML package if PyXML version is greater than 0.6.1.
+
+- xml.dom: DOM level 1 support for basic XML.  Includes xml.dom.minidom
+  (conventional DOM), and xml.dom.pulldom, which allows building the DOM
+  tree only for nodes which are sufficiently interesting to a specific
+  application.  Does not provide the HTML-specific extensions.  Still
+  undocumented.
+
+- xml.sax: SAX 2 support for Python, including all the handler
+  interfaces needed to process XML 1.0 compliant XML.  Some
+  documentation is already available.
+
+- pyexpat: Renamed to xml.parsers.expat since this is part of the new,
+  packagized XML support.
+
+
+C API
+
+- Add three new convenience functions for module initialization --
+  PyModule_AddObject(), PyModule_AddIntConstant(), and
+  PyModule_AddStringConstant().
+
+- Cleaned up definition of NULL in C source code; all definitions were
+  removed and add #error to Python.h if NULL isn't defined after
+  #include of stdio.h.
+
+- Py_PROTO() macros that were removed in 2.0b1 have been restored for
+  backwards compatibility (at the source level) with old extensions.
+
+- A wrapper API was added for signal() and sigaction().  Instead of
+  either function, always use PyOS_getsig() to get a signal handler
+  and PyOS_setsig() to set one.  A new convenience typedef
+  PyOS_sighandler_t is defined for the type of signal handlers.
+
+- Add PyString_AsStringAndSize() function that provides access to the
+  internal data buffer and size of a string object -- or the default
+  encoded version of a Unicode object.
+
+- PyString_Size() and PyString_AsString() accept Unicode objects.
+
+- The standard header <limits.h> is now included by Python.h (if it
+  exists).  INT_MAX and LONG_MAX will always be defined, even if
+  <limits.h> is not available.
+
+- PyFloat_FromString takes a second argument, pend, that was
+  effectively useless.  It is now officially useless but preserved for
+  backwards compatibility.  If the pend argument is not NULL, *pend is
+  set to NULL.
+
+- PyObject_GetAttr() and PyObject_SetAttr() now accept Unicode objects
+  for the attribute name.  See note on getattr() above.
+
+- A few bug fixes to argument processing for Unicode.
+  PyArg_ParseTupleAndKeywords() now accepts "es#" and "es".
+  PyArg_Parse() special cases "s#" for Unicode objects; it returns a
+  pointer to the default encoded string data instead of to the raw
+  UTF-16.
+
+- Py_BuildValue accepts B format (for bgen-generated code).
+
+
+Internals
+
+- On Unix, fix code for finding Python installation directory so that
+  it works when argv[0] is a relative path.
+
+- Added a true unicode_internal_encode() function and fixed the
+  unicode_internal_decode function() to support Unicode objects directly
+  rather than by generating a copy of the object.
+
+- Several of the internal Unicode tables are much smaller now, and
+  the source code should be much friendlier to weaker compilers.
+
+- In the garbage collector: Fixed bug in collection of tuples.  Fixed
+  bug that caused some instances to be removed from the container set
+  while they were still live.  Fixed parsing in gc.set_debug() for
+  platforms where sizeof(long) > sizeof(int).
+
+- Fixed refcount problem in instance deallocation that only occurred
+  when Py_REF_DEBUG was defined and Py_TRACE_REFS was not.
+
+- On Windows, getpythonregpath is now protected against null data in
+  registry key.
+
+- On Unix, create .pyc/.pyo files with O_EXCL flag to avoid a race
+  condition.
+
+
+Build and platform-specific issues
+
+- Better support of GNU Pth via --with-pth configure option.
+
+- Python/C API now properly exposed to dynamically-loaded extension
+  modules on Reliant UNIX.
+
+- Changes for the benefit of SunOS 4.1.4 (really!).  mmapmodule.c:
+  Don't define MS_SYNC to be zero when it is undefined.  Added missing
+  prototypes in posixmodule.c.
+
+- Improved support for HP-UX build.  Threads should now be correctly
+  configured (on HP-UX 10.20 and 11.00).
+
+- Fix largefile support on older NetBSD systems and OpenBSD by adding
+  define for TELL64.
+
+
+Tools and other miscellany
+
+- ftpmirror: Call to main() is wrapped in if __name__ == "__main__".
+
+- freeze: The modulefinder now works with 2.0 opcodes.
+
+- IDLE:
+  Move hackery of sys.argv until after the Tk instance has been
+  created, which allows the application-specific Tkinter
+  initialization to be executed if present; also pass an explicit
+  className parameter to the Tk() constructor.
+
+
+What's new in 2.0 beta 1?
+=========================
+
+Source Incompatibilities
+------------------------
+
+None.  Note that 1.6 introduced several incompatibilities with 1.5.2,
+such as single-argument append(), connect() and bind(), and changes to
+str(long) and repr(float).
+
+
+Binary Incompatibilities
+------------------------
+
+- Third party extensions built for Python 1.5.x or 1.6 cannot be used
+with Python 2.0; these extensions will have to be rebuilt for Python
+2.0.
+
+- On Windows, attempting to import a third party extension built for
+Python 1.5.x or 1.6 results in an immediate crash; there's not much we
+can do about this.  Check your PYTHONPATH environment variable!
+
+- Python bytecode files (*.pyc and *.pyo) are not compatible between
+releases.
+
+
+Overview of Changes Since 1.6
+-----------------------------
+
+There are many new modules (including brand new XML support through
+the xml package, and i18n support through the gettext module); a list
+of all new modules is included below.  Lots of bugs have been fixed.
+
+The process for making major new changes to the language has changed
+since Python 1.6.  Enhancements must now be documented by a Python
+Enhancement Proposal (PEP) before they can be accepted.
+
+There are several important syntax enhancements, described in more
+detail below:
+
+  - Augmented assignment, e.g. x += 1
+
+  - List comprehensions, e.g. [x**2 for x in range(10)]
+
+  - Extended import statement, e.g. import Module as Name
+
+  - Extended print statement, e.g. print >> file, "Hello"
+
+Other important changes:
+
+  - Optional collection of cyclical garbage
+
+Python Enhancement Proposal (PEP)
+---------------------------------
+
+PEP stands for Python Enhancement Proposal.  A PEP is a design
+document providing information to the Python community, or describing
+a new feature for Python.  The PEP should provide a concise technical
+specification of the feature and a rationale for the feature.
+
+We intend PEPs to be the primary mechanisms for proposing new
+features, for collecting community input on an issue, and for
+documenting the design decisions that have gone into Python.  The PEP
+author is responsible for building consensus within the community and
+documenting dissenting opinions.
+
+The PEPs are available at http://python.sourceforge.net/peps/.
+
+Augmented Assignment
+--------------------
+
+This must have been the most-requested feature of the past years!
+Eleven new assignment operators were added:
+
+    += -= *= /= %= **= <<= >>= &= ^= |=
+
+For example,
+
+    A += B
+
+is similar to
+
+    A = A + B
+
+except that A is evaluated only once (relevant when A is something
+like dict[index].attr).
+
+However, if A is a mutable object, A may be modified in place.  Thus,
+if A is a number or a string, A += B has the same effect as A = A+B
+(except A is only evaluated once); but if a is a list, A += B has the
+same effect as A.extend(B)!
+
+Classes and built-in object types can override the new operators in
+order to implement the in-place behavior; the not-in-place behavior is
+used automatically as a fallback when an object doesn't implement the
+in-place behavior.  For classes, the method name is derived from the
+method name for the corresponding not-in-place operator by inserting
+an 'i' in front of the name, e.g. __iadd__ implements in-place
+__add__.
+
+Augmented assignment was implemented by Thomas Wouters.
+
+
+List Comprehensions
+-------------------
+
+This is a flexible new notation for lists whose elements are computed
+from another list (or lists).  The simplest form is:
+
+    [<expression> for <variable> in <sequence>]
+
+For example, [i**2 for i in range(4)] yields the list [0, 1, 4, 9].
+This is more efficient than a for loop with a list.append() call.
+
+You can also add a condition:
+
+    [<expression> for <variable> in <sequence> if <condition>]
+
+For example, [w for w in words if w == w.lower()] would yield the list
+of words that contain no uppercase characters.  This is more efficient
+than a for loop with an if statement and a list.append() call.
+
+You can also have nested for loops and more than one 'if' clause.  For
+example, here's a function that flattens a sequence of sequences::
+
+    def flatten(seq):
+        return [x for subseq in seq for x in subseq]
+
+    flatten([[0], [1,2,3], [4,5], [6,7,8,9], []])
+
+This prints
+
+    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+
+List comprehensions originated as a patch set from Greg Ewing; Skip
+Montanaro and Thomas Wouters also contributed.  Described by PEP 202.
+
+
+Extended Import Statement
+-------------------------
+
+Many people have asked for a way to import a module under a different
+name.  This can be accomplished like this:
+
+    import foo
+    bar = foo
+    del foo
+
+but this common idiom gets old quickly.  A simple extension of the
+import statement now allows this to be written as follows:
+
+    import foo as bar
+
+There's also a variant for 'from ... import':
+
+    from foo import bar as spam
+
+This also works with packages; e.g. you can write this:
+
+    import test.regrtest as regrtest
+
+Note that 'as' is not a new keyword -- it is recognized only in this
+context (this is only possible because the syntax for the import
+statement doesn't involve expressions).
+
+Implemented by Thomas Wouters.  Described by PEP 221.
+
+
+Extended Print Statement
+------------------------
+
+Easily the most controversial new feature, this extension to the print
+statement adds an option to make the output go to a different file
+than the default sys.stdout.
+
+For example, to write an error message to sys.stderr, you can now
+write:
+
+    print >> sys.stderr, "Error: bad dog!"
+
+As a special feature, if the expression used to indicate the file
+evaluates to None, the current value of sys.stdout is used.  Thus:
+
+    print >> None, "Hello world"
+
+is equivalent to
+
+    print "Hello world"
+
+Design and implementation by Barry Warsaw.  Described by PEP 214.
+
+
+Optional Collection of Cyclical Garbage
+---------------------------------------
+
+Python is now equipped with a garbage collector that can hunt down
+cyclical references between Python objects.  It's no replacement for
+reference counting; in fact, it depends on the reference counts being
+correct, and decides that a set of objects belong to a cycle if all
+their reference counts can be accounted for from their references to
+each other.  This devious scheme was first proposed by Eric Tiedemann,
+and brought to implementation by Neil Schemenauer.
+
+There's a module "gc" that lets you control some parameters of the
+garbage collection.  There's also an option to the configure script
+that lets you enable or disable the garbage collection.  In 2.0b1,
+it's on by default, so that we (hopefully) can collect decent user
+experience with this new feature.  There are some questions about its
+performance.  If it proves to be too much of a problem, we'll turn it
+off by default in the final 2.0 release.
+
+
+Smaller Changes
+---------------
+
+A new function zip() was added.  zip(seq1, seq2, ...) is equivalent to
+map(None, seq1, seq2, ...) when the sequences have the same length;
+i.e. zip([1,2,3], [10,20,30]) returns [(1,10), (2,20), (3,30)].  When
+the lists are not all the same length, the shortest list wins:
+zip([1,2,3], [10,20]) returns [(1,10), (2,20)].  See PEP 201.
+
+sys.version_info is a tuple (major, minor, micro, level, serial).
+
+Dictionaries have an odd new method, setdefault(key, default).
+dict.setdefault(key, default) returns dict[key] if it exists; if not,
+it sets dict[key] to default and returns that value.  Thus:
+
+    dict.setdefault(key, []).append(item)
+
+does the same work as this common idiom:
+
+    if not dict.has_key(key):
+        dict[key] = []
+    dict[key].append(item)
+
+There are two new variants of SyntaxError that are raised for
+indentation-related errors: IndentationError and TabError.
+
+Changed \x to consume exactly two hex digits; see PEP 223.  Added \U
+escape that consumes exactly eight hex digits.
+
+The limits on the size of expressions and file in Python source code
+have been raised from 2**16 to 2**32.  Previous versions of Python
+were limited because the maximum argument size the Python VM accepted
+was 2**16.  This limited the size of object constructor expressions,
+e.g. [1,2,3] or {'a':1, 'b':2}, and the size of source files.  This
+limit was raised thanks to a patch by Charles Waldman that effectively
+fixes the problem.  It is now much more likely that you will be
+limited by available memory than by an arbitrary limit in Python.
+
+The interpreter's maximum recursion depth can be modified by Python
+programs using sys.getrecursionlimit and sys.setrecursionlimit.  This
+limit is the maximum number of recursive calls that can be made by
+Python code.  The limit exists to prevent infinite recursion from
+overflowing the C stack and causing a core dump.  The default value is
+1000.  The maximum safe value for a particular platform can be found
+by running Misc/find_recursionlimit.py.
+
+New Modules and Packages
+------------------------
+
+atexit - for registering functions to be called when Python exits.
+
+imputil - Greg Stein's alternative API for writing custom import
+hooks.
+
+pyexpat - an interface to the Expat XML parser, contributed by Paul
+Prescod.
+
+xml - a new package with XML support code organized (so far) in three
+subpackages: xml.dom, xml.sax, and xml.parsers.  Describing these
+would fill a volume.  There's a special feature whereby a
+user-installed package named _xmlplus overrides the standard
+xmlpackage; this is intended to give the XML SIG a hook to distribute
+backwards-compatible updates to the standard xml package.
+
+webbrowser - a platform-independent API to launch a web browser.
+
+
+Changed Modules
+---------------
+
+array -- new methods for array objects: count, extend, index, pop, and
+remove
+
+binascii -- new functions b2a_hex and a2b_hex that convert between
+binary data and its hex representation
+
+calendar -- Many new functions that support features including control
+over which day of the week is the first day, returning strings instead
+of printing them.  Also new symbolic constants for days of week,
+e.g. MONDAY, ..., SUNDAY.
+
+cgi -- FieldStorage objects have a getvalue method that works like a
+dictionary's get method and returns the value attribute of the object.
+
+ConfigParser -- The parser object has new methods has_option,
+remove_section, remove_option, set, and write.  They allow the module
+to be used for writing config files as well as reading them.
+
+ftplib -- ntransfercmd(), transfercmd(), and retrbinary() all now
+optionally support the RFC 959 REST command.
+
+gzip -- readline and readlines now accept optional size arguments
+
+httplib -- New interfaces and support for HTTP/1.1 by Greg Stein.  See
+the module doc strings for details.
+
+locale -- implement getdefaultlocale for Win32 and Macintosh
+
+marshal -- no longer dumps core when marshaling deeply nested or
+recursive data structures
+
+os -- new functions isatty, seteuid, setegid, setreuid, setregid
+
+os/popen2 -- popen2/popen3/popen4 support under Windows.  popen2/popen3
+support under Unix.
+
+os/pty -- support for openpty and forkpty
+
+os.path -- fix semantics of os.path.commonprefix
+
+smtplib -- support for sending very long messages
+
+socket -- new function getfqdn()
+
+readline -- new functions to read, write and truncate history files.
+The readline section of the library reference manual contains an
+example.
+
+select -- add interface to poll system call
+
+shutil -- new copyfileobj function
+
+SimpleHTTPServer, CGIHTTPServer -- Fix problems with buffering in the
+HTTP server.
+
+Tkinter -- optimization of function flatten
+
+urllib -- scans environment variables for proxy configuration,
+e.g. http_proxy.
+
+whichdb -- recognizes dumbdbm format
+
+
+Obsolete Modules
+----------------
+
+None.  However note that 1.6 made a whole slew of modules obsolete:
+stdwin, soundex, cml, cmpcache, dircache, dump, find, grep, packmail,
+poly, zmod, strop, util, whatsound.
+
+
+Changed, New, Obsolete Tools
+----------------------------
+
+None.
+
+
+C-level Changes
+---------------
+
+Several cleanup jobs were carried out throughout the source code.
+
+All C code was converted to ANSI C; we got rid of all uses of the
+Py_PROTO() macro, which makes the header files a lot more readable.
+
+Most of the portability hacks were moved to a new header file,
+pyport.h; several other new header files were added and some old
+header files were removed, in an attempt to create a more rational set
+of header files.  (Few of these ever need to be included explicitly;
+they are all included by Python.h.)
+
+Trent Mick ensured portability to 64-bit platforms, under both Linux
+and Win64, especially for the new Intel Itanium processor.  Mick also
+added large file support for Linux64 and Win64.
+
+The C APIs to return an object's size have been update to consistently
+use the form PyXXX_Size, e.g. PySequence_Size and PyDict_Size.  In
+previous versions, the abstract interfaces used PyXXX_Length and the
+concrete interfaces used PyXXX_Size.  The old names,
+e.g. PyObject_Length, are still available for backwards compatibility
+at the API level, but are deprecated.
+
+The PyOS_CheckStack function has been implemented on Windows by
+Fredrik Lundh.  It prevents Python from failing with a stack overflow
+on Windows.
+
+The GC changes resulted in creation of two new slots on object,
+tp_traverse and tp_clear.  The augmented assignment changes result in
+the creation of a new slot for each in-place operator.
+
+The GC API creates new requirements for container types implemented in
+C extension modules.  See Include/objimpl.h for details.
+
+PyErr_Format has been updated to automatically calculate the size of
+the buffer needed to hold the formatted result string.  This change
+prevents crashes caused by programmer error.
+
+New C API calls: PyObject_AsFileDescriptor, PyErr_WriteUnraisable.
+
+PyRun_AnyFileEx, PyRun_SimpleFileEx, PyRun_FileEx -- New functions
+that are the same as their non-Ex counterparts except they take an
+extra flag argument that tells them to close the file when done.
+
+XXX There were other API changes that should be fleshed out here.
+
+
+Windows Changes
+---------------
+
+New popen2/popen3/peopen4 in os module (see Changed Modules above).
+
+os.popen is much more usable on Windows 95 and 98.  See Microsoft
+Knowledge Base article Q150956.  The Win9x workaround described there
+is implemented by the new w9xpopen.exe helper in the root of your
+Python installation.  Note that Python uses this internally; it is not
+a standalone program.
+
+Administrator privileges are no longer required to install Python
+on Windows NT or Windows 2000.  If you have administrator privileges,
+Python's registry info will be written under HKEY_LOCAL_MACHINE.
+Otherwise the installer backs off to writing Python's registry info
+under HKEY_CURRENT_USER.  The latter is sufficient for all "normal"
+uses of Python, but will prevent some advanced uses from working
+(for example, running a Python script as an NT service, or possibly
+from CGI).
+
+[This was new in 1.6] The installer no longer runs a separate Tcl/Tk
+installer; instead, it installs the needed Tcl/Tk files directly in the
+Python directory.  If you already have a Tcl/Tk installation, this
+wastes some disk space (about 4 Megs) but avoids problems with
+conflicting Tcl/Tk installations, and makes it much easier for Python
+to ensure that Tcl/Tk can find all its files.
+
+[This was new in 1.6] The Windows installer now installs by default in
+\Python20\ on the default volume, instead of \Program Files\Python-2.0\.
+
+
+Updates to the changes between 1.5.2 and 1.6
+--------------------------------------------
+
+The 1.6 NEWS file can't be changed after the release is done, so here
+is some late-breaking news:
+
+New APIs in locale.py: normalize(), getdefaultlocale(), resetlocale(),
+and changes to getlocale() and setlocale().
+
+The new module is now enabled per default.
+
+It is not true that the encodings codecs cannot be used for normal
+strings: the string.encode() (which is also present on 8-bit strings
+!) allows using them for 8-bit strings too, e.g. to convert files from
+cp1252 (Windows) to latin-1 or vice-versa.
+
+Japanese codecs are available from Tamito KAJIYAMA:
+http://pseudo.grad.sccs.chukyo-u.ac.jp/~kajiyama/python/
+
+
+======================================================================
+
+
+=======================================
+==> Release 1.6 (September 5, 2000) <==
+=======================================
+
+What's new in release 1.6?
+==========================
+
+Below is a list of all relevant changes since release 1.5.2.
+
+
+Source Incompatibilities
+------------------------
+
+Several small incompatible library changes may trip you up:
+
+  - The append() method for lists can no longer be invoked with more
+  than one argument.  This used to append a single tuple made out of
+  all arguments, but was undocumented.  To append a tuple, use
+  e.g. l.append((a, b, c)).
+
+  - The connect(), connect_ex() and bind() methods for sockets require
+  exactly one argument.  Previously, you could call s.connect(host,
+  port), but this was undocumented. You must now write
+  s.connect((host, port)).
+
+  - The str() and repr() functions are now different more often.  For
+  long integers, str() no longer appends a 'L'.  Thus, str(1L) == '1',
+  which used to be '1L'; repr(1L) is unchanged and still returns '1L'.
+  For floats, repr() now gives 17 digits of precision, to ensure no
+  precision is lost (on all current hardware).
+
+  - The -X option is gone.  Built-in exceptions are now always
+  classes.  Many more library modules also have been converted to
+  class-based exceptions.
+
+
+Binary Incompatibilities
+------------------------
+
+- Third party extensions built for Python 1.5.x cannot be used with
+Python 1.6; these extensions will have to be rebuilt for Python 1.6.
+
+- On Windows, attempting to import a third party extension built for
+Python 1.5.x results in an immediate crash; there's not much we can do
+about this.  Check your PYTHONPATH environment variable!
+
+
+Overview of Changes since 1.5.2
+-------------------------------
+
+For this overview, I have borrowed from the document "What's New in
+Python 2.0" by Andrew Kuchling and Moshe Zadka:
+http://www.amk.ca/python/2.0/ .
+
+There are lots of new modules and lots of bugs have been fixed.  A
+list of all new modules is included below.
+
+Probably the most pervasive change is the addition of Unicode support.
+We've added a new fundamental datatype, the Unicode string, a new
+build-in function unicode(), an numerous C APIs to deal with Unicode
+and encodings.  See the file Misc/unicode.txt for details, or
+http://starship.python.net/crew/lemburg/unicode-proposal.txt.
+
+Two other big changes, related to the Unicode support, are the
+addition of string methods and (yet another) new regular expression
+engine.
+
+  - String methods mean that you can now say s.lower() etc. instead of
+  importing the string module and saying string.lower(s) etc.  One
+  peculiarity is that the equivalent of string.join(sequence,
+  delimiter) is delimiter.join(sequence).  Use " ".join(sequence) for
+  the effect of string.join(sequence); to make this more readable, try
+  space=" " first.  Note that the maxsplit argument defaults in
+  split() and replace() have changed from 0 to -1.
+
+  - The new regular expression engine, SRE by Fredrik Lundh, is fully
+  backwards compatible with the old engine, and is in fact invoked
+  using the same interface (the "re" module).  You can explicitly
+  invoke the old engine by import pre, or the SRE engine by importing
+  sre.  SRE is faster than pre, and supports Unicode (which was the
+  main reason to put effort in yet another new regular expression
+  engine -- this is at least the fourth!).
+
+
+Other Changes
+-------------
+
+Other changes that won't break code but are nice to know about:
+
+Deleting objects is now safe even for deeply nested data structures.
+
+Long/int unifications: long integers can be used in seek() calls, as
+slice indexes.
+
+String formatting (s % args) has a new formatting option, '%r', which
+acts like '%s' but inserts repr(arg) instead of str(arg). (Not yet in
+alpha 1.)
+
+Greg Ward's "distutils" package is included: this will make
+installing, building and distributing third party packages much
+simpler.
+
+There's now special syntax that you can use instead of the apply()
+function.  f(*args, **kwds) is equivalent to apply(f, args, kwds).
+You can also use variations f(a1, a2, *args, **kwds) and you can leave
+one or the other out: f(*args), f(**kwds).
+
+The built-ins int() and long() take an optional second argument to
+indicate the conversion base -- of course only if the first argument
+is a string.  This makes string.atoi() and string.atol() obsolete.
+(string.atof() was already obsolete).
+
+When a local variable is known to the compiler but undefined when
+used, a new exception UnboundLocalError is raised.  This is a class
+derived from NameError so code catching NameError should still work.
+The purpose is to provide better diagnostics in the following example:
+  x = 1
+  def f():
+      print x
+      x = x+1
+This used to raise a NameError on the print statement, which confused
+even experienced Python programmers (especially if there are several
+hundreds of lines of code between the reference and the assignment to
+x :-).
+
+You can now override the 'in' operator by defining a __contains__
+method.  Note that it has its arguments backwards: x in a causes
+a.__contains__(x) to be called.  That's why the name isn't __in__.
+
+The exception AttributeError will have a more friendly error message,
+e.g.: <code>'Spam' instance has no attribute 'eggs'</code>.  This may
+<b>break code</b> that expects the message to be exactly the attribute
+name.
+
+
+New Modules in 1.6
+------------------
+
+UserString - base class for deriving from the string type.
+
+distutils - tools for distributing Python modules.
+
+robotparser - parse a robots.txt file, for writing web spiders.
+(Moved from Tools/webchecker/.)
+
+linuxaudiodev - audio for Linux.
+
+mmap - treat a file as a memory buffer.  (Windows and Unix.)
+
+sre - regular expressions (fast, supports unicode).  Currently, this
+code is very rough.  Eventually, the re module will be reimplemented
+using sre (without changes to the re API).
+
+filecmp - supersedes the old cmp.py and dircmp.py modules.
+
+tabnanny - check Python sources for tab-width dependance.  (Moved from
+Tools/scripts/.)
+
+urllib2 - new and improved but incompatible version of urllib (still
+experimental).
+
+zipfile - read and write zip archives.
+
+codecs - support for Unicode encoders/decoders.
+
+unicodedata - provides access to the Unicode 3.0 database.
+
+_winreg - Windows registry access.
+
+encodings - package which provides a large set of standard codecs --
+currently only for the new Unicode support. It has a drop-in extension
+mechanism which allows you to add new codecs by simply copying them
+into the encodings package directory. Asian codec support will
+probably be made available as separate distribution package built upon
+this technique and the new distutils package.
+
+
+Changed Modules
+---------------
+
+readline, ConfigParser, cgi, calendar, posix, readline, xmllib, aifc,
+chunk, wave, random, shelve, nntplib - minor enhancements.
+
+socket, httplib, urllib - optional OpenSSL support (Unix only).
+
+_tkinter - support for 8.0 up to 8.3.  Support for versions older than
+8.0 has been dropped.
+
+string - most of this module is deprecated now that strings have
+methods.  This no longer uses the built-in strop module, but takes
+advantage of the new string methods to provide transparent support for
+both Unicode and ordinary strings.
+
+
+Changes on Windows
+------------------
+
+The installer no longer runs a separate Tcl/Tk installer; instead, it
+installs the needed Tcl/Tk files directly in the Python directory.  If
+you already have a Tcl/Tk installation, this wastes some disk space
+(about 4 Megs) but avoids problems with conflincting Tcl/Tk
+installations, and makes it much easier for Python to ensure that
+Tcl/Tk can find all its files.  Note: the alpha installers don't
+include the documentation.
+
+The Windows installer now installs by default in \Python16\ on the
+default volume, instead of \Program Files\Python-1.6\.
+
+
+Changed Tools
+-------------
+
+IDLE - complete overhaul.  See the <a href="../idle/">IDLE home
+page</a> for more information.  (Python 1.6 alpha 1 will come with
+IDLE 0.6.)
+
+Tools/i18n/pygettext.py - Python equivalent of xgettext(1).  A message
+text extraction tool used for internationalizing applications written
+in Python.
+
+
+Obsolete Modules
+----------------
+
+stdwin and everything that uses it.  (Get Python 1.5.2 if you need
+it. :-)
+
+soundex.  (Skip Montanaro has a version in Python but it won't be
+included in the Python release.)
+
+cmp, cmpcache, dircmp.  (Replaced by filecmp.)
+
+dump.  (Use pickle.)
+
+find.  (Easily coded using os.walk().)
+
+grep.  (Not very useful as a library module.)
+
+packmail.  (No longer has any use.)
+
+poly, zmod.  (These were poor examples at best.)
+
+strop.  (No longer needed by the string module.)
+
+util.  (This functionality was long ago built in elsewhere).
+
+whatsound.  (Use sndhdr.)
+
+
+Detailed Changes from 1.6b1 to 1.6
+----------------------------------
+
+- Slight changes to the CNRI license.  A copyright notice has been
+added; the requirement to indicate the nature of modifications now
+applies when making a derivative work available "to others" instead of
+just "to the public"; the version and date are updated.  The new
+license has a new handle.
+
+- Added the Tools/compiler package.  This is a project led by Jeremy
+Hylton to write the Python bytecode generator in Python.
+
+- The function math.rint() is removed.
+
+- In Python.h, "#define _GNU_SOURCE 1" was added.
+
+- Version 0.9.1 of Greg Ward's distutils is included (instead of
+version 0.9).
+
+- A new version of SRE is included.  It is more stable, and more
+compatible with the old RE module.  Non-matching ranges are indicated
+by -1, not None.  (The documentation said None, but the PRE
+implementation used -1; changing to None would break existing code.)
+
+- The winreg module has been renamed to _winreg.  (There are plans for
+a higher-level API called winreg, but this has not yet materialized in
+a form that is acceptable to the experts.)
+
+- The _locale module is enabled by default.
+
+- Fixed the configuration line for the _curses module.
+
+- A few crashes have been fixed, notably <file>.writelines() with a
+list containing non-string objects would crash, and there were
+situations where a lost SyntaxError could dump core.
+
+- The <list>.extend() method now accepts an arbitrary sequence
+argument.
+
+- If __str__() or __repr__() returns a Unicode object, this is
+converted to an 8-bit string.
+
+- Unicode string comparisons is no longer aware of UTF-16
+encoding peculiarities; it's a straight 16-bit compare.
+
+- The Windows installer now installs the LICENSE file and no longer
+registers the Python DLL version in the registry (this is no longer
+needed).  It now uses Tcl/Tk 8.3.2.
+
+- A few portability problems have been fixed, in particular a
+compilation error involving socklen_t.
+
+- The PC configuration is slightly friendlier to non-Microsoft
+compilers.
+
+
+======================================================================
+
+
+======================================
+==> Release 1.5.2 (April 13, 1999) <==
+======================================
+
+From 1.5.2c1 to 1.5.2 (final)
+=============================
+
+Tue Apr 13 15:44:49 1999  Guido van Rossum  <guido at eric.cnri.reston.va.us>
+
+	* PCbuild/python15.wse: Bump version to 1.5.2 (final)
+
+	* PCbuild/python15.dsp: Added shamodule.c
+
+	* PC/config.c: Added sha module!
+
+	* README, Include/patchlevel.h: Prepare for final release.
+
+	* Misc/ACKS:
+	More (Cameron Laird is honorary; the others are 1.5.2c1 testers).
+
+	* Python/thread_solaris.h:
+	While I can't really test this thoroughly, Pat Knight and the Solaris
+	man pages suggest that the proper thing to do is to add THR_NEW_LWP to
+	the flags on thr_create(), and that there really isn't a downside, so
+	I'll do that.
+
+	* Misc/ACKS:
+	Bunch of new names who helped iron out the last wrinkles of 1.5.2.
+
+	* PC/python_nt.rc:
+	Bump the myusterious M$ version number from 1,5,2,1 to 1,5,2,3.
+	(I can't even display this on NT, maybe Win/98 can?)
+
+	* Lib/pstats.py:
+	Fix mysterious references to jprofile that were in the source since
+	its creation.  I'm assuming these were once valid references to "Jim
+	Roskind's profile"...
+
+	* Lib/Attic/threading_api.py:
+	Removed; since long subsumed in Doc/lib/libthreading.tex
+
+	* Modules/socketmodule.c:
+	Put back __osf__ support for gethostbyname_r(); the real bug was that
+	it was being used even without threads.  This of course might be an
+	all-platform problem so now we only use the _r variant when we are
+	using threads.
+
+Mon Apr 12 22:51:20 1999  Guido van Rossum  <guido at eric.cnri.reston.va.us>
+
+	* Modules/cPickle.c:
+	Fix accidentally reversed NULL test in load_mark().  Suggested by
+	Tamito Kajiyama.  (This caused a bug only on platforms where malloc(0)
+	returns NULL.)
+
+	* README:
+	Add note about popen2 problem on Linux noticed by Pablo Bleyer.
+
+	* README: Add note about -D_REENTRANT for HP-UX 10.20.
+
+	* Modules/Makefile.pre.in: 'clean' target should remove hassignal.
+
+	* PC/Attic/vc40.mak, PC/readme.txt:
+	Remove all VC++ info (except VC 1.5) from readme.txt;
+	remove the VC++ 4.0 project file; remove the unused _tkinter extern defs.
+
+	* README: Clarify PC build instructions (point to PCbuild).
+
+	* Modules/zlibmodule.c: Cast added by Jack Jansen (for Mac port).
+
+	* Lib/plat-sunos5/CDIO.py, Lib/plat-linux2/CDROM.py:
+	Forgot to add this file.  CDROM device parameters.
+
+	* Lib/gzip.py: Two different changes.
+
+	1. Jack Jansen reports that on the Mac, the time may be negative, and
+	solves this by adding a write32u() function that writes an unsigned
+	long.
+
+	2. On 64-bit platforms the CRC comparison fails; I've fixed this by
+	casting both values to be compared to "unsigned long" i.e. modulo
+	0x100000000L.
+
+Sat Apr 10 18:42:02 1999  Guido van Rossum  <guido at eric.cnri.reston.va.us>
+
+	* PC/Attic/_tkinter.def: No longer needed.
+
+	* Misc/ACKS: Correct missed character in Andrew Dalke's name.
+
+	* README: Add DEC Ultrix notes (from Donn Cave's email).
+
+	* configure: The usual
+
+	* configure.in:
+	Quote a bunch of shell variables used in test, related to long-long.
+
+	* Objects/fileobject.c, Modules/shamodule.c, Modules/regexpr.c:
+	casts for picky compilers.
+
+	* Modules/socketmodule.c:
+	3-arg gethostbyname_r doesn't really work on OSF/1.
+
+	* PC/vc15_w31/_.c, PC/vc15_lib/_.c, Tools/pynche/__init__.py:
+	Avoid totally empty files.
+
+Fri Apr  9 14:56:35 1999  Guido van Rossum  <guido at eric.cnri.reston.va.us>
+
+	* Tools/scripts/fixps.py: Use re instead of regex.
+	Don't rewrite the file in place.
+	(Reported by Andy Dustman.)
+
+	* Lib/netrc.py, Lib/shlex.py: Get rid of #! line
+
+Thu Apr  8 23:13:37 1999  Guido van Rossum  <guido at eric.cnri.reston.va.us>
+
+	* PCbuild/python15.wse: Use the Tcl 8.0.5 installer.
+	Add a variable %_TCL_% that makes it easier to switch to a different version.
+
+
+======================================================================
+
+
+From 1.5.2b2 to 1.5.2c1
+=======================
+
+Thu Apr  8 23:13:37 1999  Guido van Rossum  <guido at eric.cnri.reston.va.us>
+
+	* PCbuild/python15.wse:
+	Release 1.5.2c1.  Add IDLE and Uninstall to program group.
+	Don't distribute zlib.dll.  Tweak some comments.
+
+	* PCbuild/zlib.dsp: Now using static zlib 1.1.3
+
+	* Lib/dos-8x3/userdict.py, Lib/dos-8x3/userlist.py, Lib/dos-8x3/test_zli.py, Lib/dos-8x3/test_use.py, Lib/dos-8x3/test_pop.py, Lib/dos-8x3/test_pic.py, Lib/dos-8x3/test_ntp.py, Lib/dos-8x3/test_gzi.py, Lib/dos-8x3/test_fcn.py, Lib/dos-8x3/test_cpi.py, Lib/dos-8x3/test_bsd.py, Lib/dos-8x3/posixfil.py, Lib/dos-8x3/mimetype.py, Lib/dos-8x3/nturl2pa.py, Lib/dos-8x3/compilea.py, Lib/dos-8x3/exceptio.py, Lib/dos-8x3/basehttp.py:
+	The usual
+
+	* Include/patchlevel.h: Release 1.5.2c1
+
+	* README: Release 1.5.2c1.
+
+	* Misc/NEWS: News for the 1.5.2c1 release.
+
+	* Lib/test/test_strftime.py:
+	On Windows, we suddenly find, strftime() may return "" for an
+	unsupported format string.  (I guess this is because the logic for
+	deciding whether to reallocate the buffer or not has been improved.)
+	This caused the test code to crash on result[0].  Fix this by assuming
+	an empty result also means the format is not supported.
+
+	* Demo/tkinter/matt/window-creation-w-location.py:
+	This demo imported some private code from Matt.  Make it cripple along.
+
+	* Lib/lib-tk/Tkinter.py:
+	Delete an accidentally checked-in feature that actually broke more
+	than was worth it: when deleting a canvas item, it would try to
+	automatically delete the bindings for that item.  Since there's
+	nothing that says you can't reuse the tag and still have the bindings,
+	this is not correct.  Also, it broke at least one demo
+	(Demo/tkinter/matt/rubber-band-box-demo-1.py).
+
+	* Python/thread_wince.h: Win/CE thread support by Mark Hammond.
+
+Wed Apr  7 20:23:17 1999  Guido van Rossum  <guido at eric.cnri.reston.va.us>
+
+	* Modules/zlibmodule.c:
+	Patch by Andrew Kuchling to unflush() (flush() for deflating).
+	Without this, if inflate() returned Z_BUF_ERROR asking for more output
+	space, we would report the error; now, we increase the buffer size and
+	try again, just as for Z_OK.
+
+	* Lib/test/test_gzip.py: Use binary mode for all gzip files we open.
+
+	* Tools/idle/ChangeLog: New change log.
+
+	* Tools/idle/README.txt, Tools/idle/NEWS.txt: New version.
+
+	* Python/pythonrun.c:
+	Alas, get rid of the Win specific hack to ask the user to press Return
+	before exiting when an error happened.  This didn't work right when
+	Python is invoked from a daemon.
+
+	* Tools/idle/idlever.py: Version bump awaiting impending new release.
+	(Not much has changed :-( )
+
+	* Lib/lib-tk/Tkinter.py:
+	lower, tkraise/lift hide Misc.lower, Misc.tkraise/lift,
+	so the preferred name for them is tag_lower, tag_raise
+	(similar to tag_bind, and similar to the Text widget);
+	unfortunately can't delete the old ones yet (maybe in 1.6)
+
+	* Python/thread.c, Python/strtod.c, Python/mystrtoul.c, Python/import.c, Python/ceval.c:
+	Changes by Mark Hammond for Windows CE.  Mostly of the form
+	  #ifdef DONT_HAVE_header_H ... #endif around #include <header.h>.
+
+	* Python/bltinmodule.c:
+	Remove unused variable from complex_from_string() code.
+
+	* Include/patchlevel.h:
+	Add the possibility of a gamma release (release candidate).
+	Add '+' to string version number to indicate we're beyond b2 now.
+
+	* Modules/posixmodule.c: Add extern decl for fsync() for SunOS 4.x.
+
+	* Lib/smtplib.py: Changes by Per Cederquist and The Dragon.
+
+	Per writes:
+
+	"""
+	The application where Signum Support uses smtplib needs to be able to
+	report good error messages to the user when sending email fails.  To
+	help in diagnosing problems it is useful to be able to report the
+	entire message sent by the server, not only the SMTP error code of the
+	offending command.
+
+	A lot of the functions in sendmail.py unfortunately discards the
+	message, leaving only the code.  The enclosed patch fixes that
+	problem.
+
+	The enclosed patch also introduces a base class for exceptions that
+	include an SMTP error code and error message, and make the code and
+	message available on separate attributes, so that surrounding code can
+	deal with them in whatever way it sees fit.  I've also added some
+	documentation to the exception classes.
+
+	The constructor will now raise an exception if it cannot connect to
+	the SMTP server.
+
+	The data() method will raise an SMTPDataError if it doesn't receive
+	the expected 354 code in the middle of the exchange.
+
+	According to section 5.2.10 of RFC 1123 a smtp client must accept "any
+	text, including no text at all" after the error code.  If the response
+	of a HELO command contains no text self.helo_resp will be set to the
+	empty string ("").  The patch fixes the test in the sendmail() method
+	so that helo_resp is tested against None; if it has the empty string
+	as value the sendmail() method would invoke the helo() method again.
+
+	The code no longer accepts a -1 reply from the ehlo() method in
+	sendmail().
+
+	[Text about removing SMTPRecipientsRefused deleted --GvR]
+	"""
+
+	and also:
+
+	"""
+	smtplib.py appends an extra blank line to the outgoing mail if the
+	`msg' argument to the sendmail method already contains a trailing
+	newline.  This patch should fix the problem.
+	"""
+
+	The Dragon writes:
+
+	"""
+		Mostly I just re-added the SMTPRecipientsRefused exception
+	(the exeption object now has the appropriate info in it ) [Per had
+	removed this in his patch --GvR] and tweaked the behavior of the
+	sendmail method whence it throws the newly added SMTPHeloException (it
+	was closing the connection, which it shouldn't.  whatever catches the
+	exception should do that. )
+
+		I pondered the change of the return values to tuples all around,
+	and after some thinking I decided that regularizing the return values was
+	too much of the Right Thing (tm) to not do.
+
+		My one concern is that code expecting an integer & getting a tuple
+	may fail silently.
+
+	(i.e. if it's doing :
+
+	      x.somemethod() >= 400:
+	expecting an integer, the expression will always be true if it gets a
+	tuple instead. )
+
+		However, most smtplib code I've seen only really uses the
+	sendmail() method, so this wouldn't bother it.  Usually code I've seen
+	that calls the other methods usually only calls helo() and ehlo() for
+	doing ESMTP, a feature which was not in the smtplib included with 1.5.1,
+	and thus I would think not much code uses it yet.
+	"""
+
+Tue Apr  6 19:38:18 1999  Guido van Rossum  <guido at eric.cnri.reston.va.us>
+
+	* Lib/test/test_ntpath.py:
+	Fix the tests now that splitdrive() no longer treats UNC paths special.
+	(Some tests converted to splitunc() tests.)
+
+	* Lib/ntpath.py:
+	Withdraw the UNC support from splitdrive().  Instead, a new function
+	splitunc() parses UNC paths.  The contributor of the UNC parsing in
+	splitdrive() doesn't like it, but I haven't heard a good reason to
+	keep it, and it causes some problems.  (I think there's a
+	philosophical problem -- to me, the split*() functions are purely
+	syntactical, and the fact that \\foo is not a valid path doesn't mean
+	that it shouldn't be considered an absolute path.)
+
+	Also (quite separately, but strangely related to the philosophical
+	issue above) fix abspath() so that if win32api exists, it doesn't fail
+	when the path doesn't actually exist -- if GetFullPathName() fails,
+	fall back on the old strategy (join with getcwd() if neccessary, and
+	then use normpath()).
+
+	* configure.in, configure, config.h.in, acconfig.h:
+	For BeOS PowerPC.  Chris Herborth.
+
+Mon Apr  5 21:54:14 1999  Guido van Rossum  <guido at eric.cnri.reston.va.us>
+
+	* Modules/timemodule.c:
+	Jonathan Giddy notes, and Chris Lawrence agrees, that some comments on
+	#else/#endif are wrong, and that #if HAVE_TM_ZONE should be #ifdef.
+
+	* Misc/ACKS:
+	Bunch of new contributors, including 9 who contributed to the Docs,
+	reported by Fred.
+
+Mon Apr  5 18:37:59 1999  Fred Drake  <fdrake at eric.cnri.reston.va.us>
+
+	* Lib/gzip.py:
+	Oops, missed mode parameter to open().
+
+	* Lib/gzip.py:
+	Made the default mode 'rb' instead of 'r', for better cross-platform
+	support.  (Based on comment on the documentation by Bernhard Reiter
+	<bernhard at csd.uwm.edu>).
+
+Fri Apr  2 22:18:25 1999  Guido van Rossum  <guido at eric.cnri.reston.va.us>
+
+	* Tools/scripts/dutree.py:
+	For reasons I dare not explain, this script should always execute
+	main() when imported (in other words, it is not usable as a module).
+
+Thu Apr  1 15:32:30 1999  Guido van Rossum  <guido at eric.cnri.reston.va.us>
+
+	* Lib/test/test_cpickle.py: Jonathan Giddy write:
+
+	In test_cpickle.py, the module os got imported, but the line to remove
+	the temp file has gone missing.
+
+Tue Mar 30 20:17:31 1999  Guido van Rossum  <guido at eric.cnri.reston.va.us>
+
+	* Lib/BaseHTTPServer.py: Per Cederqvist writes:
+
+	If you send something like "PUT / HTTP/1.0" to something derived from
+	BaseHTTPServer that doesn't define do_PUT, you will get a response
+	that begins like this:
+
+		HTTP/1.0 501 Unsupported method ('do_PUT')
+		Server: SimpleHTTP/0.3 Python/1.5
+		Date: Tue, 30 Mar 1999 18:53:53 GMT
+
+	The server should complain about 'PUT' instead of 'do_PUT'.  This
+	patch should fix the problem.
+
+Mon Mar 29 20:33:21 1999  Guido van Rossum  <guido at eric.cnri.reston.va.us>
+
+	* Lib/smtplib.py: Patch by Per Cederqvist, who writes:
+
+	"""
+	 - It needlessly used the makefile() method for each response that is
+	   read from the SMTP server.
+
+	 - If the remote SMTP server closes the connection unexpectedly the
+	   code raised an IndexError.  It now raises an SMTPServerDisconnected
+	   exception instead.
+
+	 - The code now checks that all lines in a multiline response actually
+	   contains an error code.
+	"""
+
+	The Dragon approves.
+
+Mon Mar 29 20:25:40 1999  Fred Drake  <fdrake at eric.cnri.reston.va.us>
+
+	* Lib/compileall.py:
+	When run as a script, report failures in the exit code as well.
+	Patch largely based on changes by Andrew Dalke, as discussed in the
+	distutils-sig.
+
+Mon Mar 29 20:23:41 1999  Guido van Rossum  <guido at eric.cnri.reston.va.us>
+
+	* Lib/urllib.py:
+	Hack so that if a 302 or 301 redirect contains a relative URL, the
+	right thing "just happens" (basejoin() with old URL).
+
+	* Modules/cPickle.c:
+	Protection against picling to/from closed (real) file.
+	The problem was reported by Moshe Zadka.
+
+	* Lib/test/test_cpickle.py:
+	Test protection against picling to/from closed (real) file.
+
+	* Modules/timemodule.c: Chris Lawrence writes:
+
+	"""
+	The GNU folks, in their infinite wisdom, have decided not to implement
+	altzone in libc6; this would not be horrible, except that timezone
+	(which is implemented) includes the current DST setting (i.e. timezone
+	for Central is 18000 in summer and 21600 in winter).  So Python's
+	timezone and altzone variables aren't set correctly during DST.
+
+	Here's a patch relative to 1.5.2b2 that (a) makes timezone and altzone
+	show the "right" thing on Linux (by using the tm_gmtoff stuff
+	available in BSD, which is how the GLIBC manual claims things should
+	be done) and (b) should cope with the southern hemisphere.  In pursuit
+	of (b), I also took the liberty of renaming the "summer" and "winter"
+	variables to "july" and "jan".  This patch should also make certain
+	time calculations on Linux actually work right (like the tz-aware
+	functions in the rfc822 module).
+
+	(It's hard to find DST that's currently being used in the southern
+	hemisphere; I tested using Africa/Windhoek.)
+	"""
+
+	* Lib/test/output/test_gzip:
+	Jonathan Giddy discovered this file was missing.
+
+	* Modules/shamodule.c:
+	Avoid warnings from AIX compiler.  Reported by Vladimir (AIX is my
+	middlename) Marangozov, patch coded by Greg Stein.
+
+	* Tools/idle/ScriptBinding.py, Tools/idle/PyShell.py:
+	At Tim Peters' recommendation, add a dummy flush() method to PseudoFile.
+
+Sun Mar 28 17:55:32 1999  Guido van Rossum  <guido at eric.cnri.reston.va.us>
+
+	* Tools/scripts/ndiff.py: Tim Peters writes:
+
+	I should have waited overnight <wink/sigh>.  Nothing wrong with the one I
+	sent, but I couldn't resist going on to add new -r1 / -r2 cmdline options
+	for recreating the original files from ndiff's output.  That's attached, if
+	you're game!  Us Windows guys don't usually have a sed sitting around
+	<wink>.
+
+Sat Mar 27 13:34:01 1999  Guido van Rossum  <guido at eric.cnri.reston.va.us>
+
+	* Tools/scripts/ndiff.py: Tim Peters writes:
+
+	Attached is a cleaned-up version of ndiff (added useful module
+	docstring, now echo'ed in case of cmd line mistake); added -q option
+	to suppress initial file identification lines; + other minor cleanups,
+	& a slightly faster match engine.
+
+Fri Mar 26 22:36:00 1999  Fred Drake  <fdrake at eric.cnri.reston.va.us>
+
+	* Tools/scripts/dutree.py:
+	During display, if EPIPE is raised, it's probably because a pager was
+	killed.  Discard the error in that case, but propogate it otherwise.
+
+Fri Mar 26 16:20:45 1999  Guido van Rossum  <guido at eric.cnri.reston.va.us>
+
+	* Lib/test/output/test_userlist, Lib/test/test_userlist.py:
+	Test suite for UserList.
+
+	* Lib/UserList.py: Use isinstance() where appropriate.
+	Reformatted with 4-space indent.
+
+Fri Mar 26 16:11:40 1999  Barry Warsaw  <bwarsaw at eric.cnri.reston.va.us>
+
+	* Tools/pynche/PyncheWidget.py:
+	Helpwin.__init__(): The text widget should get focus.
+
+	* Tools/pynche/pyColorChooser.py:
+	Removed unnecessary import `from PyncheWidget import PyncheWidget'
+
+Fri Mar 26 15:32:05 1999  Guido van Rossum  <guido at eric.cnri.reston.va.us>
+
+	* Lib/test/output/test_userdict, Lib/test/test_userdict.py:
+	Test suite for UserDict
+
+	* Lib/UserDict.py: Improved a bunch of things.
+	The constructor now takes an optional dictionary.
+	Use isinstance() where appropriate.
+
+Thu Mar 25 22:38:49 1999  Guido van Rossum  <guido at eric.cnri.reston.va.us>
+
+	* Lib/test/output/test_pickle, Lib/test/output/test_cpickle, Lib/test/test_pickle.py, Lib/test/test_cpickle.py:
+	Basic regr tests for pickle/cPickle
+
+	* Lib/pickle.py:
+	Don't use "exec" in find_class().  It's slow, unnecessary, and (as AMK
+	points out) it doesn't work in JPython Applets.
+
+Thu Mar 25 21:50:27 1999  Andrew Kuchling  <akuchlin at eric.cnri.reston.va.us>
+
+	* Lib/test/test_gzip.py:
+	Added a simple test suite for gzip.  It simply opens a temp file,
+	writes a chunk of compressed data, closes it, writes another chunk, and
+	reads the contents back to verify that they are the same.
+
+	* Lib/gzip.py:
+	Based on a suggestion from bruce at hams.com, make a trivial change to
+	allow using the 'a' flag as a mode for opening a GzipFile.  gzip
+	files, surprisingly enough, can be concatenated and then decompressed;
+	the effect is to concatenate the two chunks of data.
+
+	If we support it on writing, it should also be supported on reading.
+	This *wasn't* trivial, and required rearranging the code in the
+	reading path, particularly the _read() method.
+
+	Raise IOError instead of RuntimeError in two cases, 'Not a gzipped file'
+	and 'Unknown compression method'
+
+Thu Mar 25 21:25:01 1999  Guido van Rossum  <guido at eric.cnri.reston.va.us>
+
+	* Lib/test/test_b1.py:
+	Add tests for float() and complex() with string args (Nick/Stephanie
+	Lockwood).
+
+Thu Mar 25 21:21:08 1999  Andrew Kuchling  <akuchlin at eric.cnri.reston.va.us>
+
+	* Modules/zlibmodule.c:
+	Add an .unused_data attribute to decompressor objects.  If .unused_data
+	is not an empty string, this means that you have arrived at the
+	end of the stream of compressed data, and the contents of .unused_data are
+	whatever follows the compressed stream.
+
+Thu Mar 25 21:16:07 1999  Guido van Rossum  <guido at eric.cnri.reston.va.us>
+
+	* Python/bltinmodule.c:
+	Patch by Nick and Stephanie Lockwood to implement complex() with a string
+	argument.  This closes TODO item 2.19.
+
+Wed Mar 24 19:09:00 1999  Guido van Rossum  <guido at eric.cnri.reston.va.us>
+
+	* Tools/webchecker/wcnew.py: Added Samuel Bayer's new webchecker.
+	Unfortunately his code breaks wcgui.py in a way that's not easy
+	to fix.  I expect that this is a temporary situation --
+	eventually Sam's changes will be merged back in.
+	(The changes add a -t option to specify exceptions to the -x
+	option, and explicit checking for #foo style fragment ids.)
+
+	* Objects/dictobject.c:
+	Vladimir Marangozov contributed updated comments.
+
+	* Objects/bufferobject.c: Folded long lines.
+
+	* Lib/test/output/test_sha, Lib/test/test_sha.py:
+	Added Jeremy's test code for the sha module.
+
+	* Modules/shamodule.c, Modules/Setup.in:
+	Added Greg Stein and Andrew Kuchling's sha module.
+	Fix comments about zlib version and URL.
+
+	* Lib/test/test_bsddb.py: Remove the temp file when we're done.
+
+	* Include/pythread.h: Conform to standard boilerplate.
+
+	* configure.in, configure, BeOS/linkmodule, BeOS/ar-fake:
+	Chris Herborth: the new compiler in R4.1 needs some new options to work...
+
+	* Modules/socketmodule.c:
+	Implement two suggestions by Jonathan Giddy: (1) in AIX, clear the
+	data struct before calling gethostby{name,addr}_r(); (2) ignore the
+	3/5/6 args determinations made by the configure script and switch on
+	platform identifiers instead:
+
+	AIX, OSF have 3 args
+	Sun, SGI have 5 args
+	Linux has 6 args
+
+	On all other platforms, undef HAVE_GETHOSTBYNAME_R altogether.
+
+	* Modules/socketmodule.c:
+	Vladimir Marangozov implements the AIX 3-arg gethostbyname_r code.
+
+	* Lib/mailbox.py:
+	Add readlines() to _Subfile class.  Not clear who would need it, but
+	Chris Lawrence sent me a broken version; this one is a tad simpler and
+	more conforming to the standard.
+
+Tue Mar 23 23:05:34 1999  Jeremy Hylton  <jhylton at eric.cnri.reston.va.us>
+
+	* Lib/gzip.py: use struct instead of bit-manipulate in Python
+
+Tue Mar 23 19:00:55 1999  Guido van Rossum  <guido at eric.cnri.reston.va.us>
+
+	* Modules/Makefile.pre.in:
+	Add $(EXE) to various occurrences of python so it will work on Cygwin
+	with egcs (after setting EXE=.exe).  Patch by Norman Vine.
+
+	* configure, configure.in:
+	Ack!  It never defined HAVE_GETHOSTBYNAME_R so that code was never tested!
+
+Mon Mar 22 22:25:39 1999  Guido van Rossum  <guido at eric.cnri.reston.va.us>
+
+	* Include/thread.h:
+	Adding thread.h -- unused but for b/w compatibility.
+	As requested by Bill Janssen.
+
+	* configure.in, configure:
+	Add code to test for all sorts of gethostbyname_r variants,
+	donated by David Arnold.
+
+	* config.h.in, acconfig.h:
+	Add symbols for gethostbyname_r variants (sigh).
+
+	* Modules/socketmodule.c: Clean up pass for the previous patches.
+
+	- Use HAVE_GETHOSTBYNAME_R_6_ARG instead of testing for Linux and
+	glibc2.
+
+	- If gethostbyname takes 3 args, undefine HAVE_GETHOSTBYNAME_R --
+	don't know what code should be used.
+
+	- New symbol USE_GETHOSTBYNAME_LOCK defined iff the lock should be used.
+
+	- Modify the gethostbyaddr() code to also hold on to the lock until
+	after it is safe to release, overlapping with the Python lock.
+
+	(Note: I think that it could in theory be possible that Python code
+	executed while gethostbyname_lock is held could attempt to reacquire
+	the lock -- e.g. in a signal handler or destructor.  I will simply say
+	"don't do that then.")
+
+	* Modules/socketmodule.c: Jonathan Giddy writes:
+
+	Here's a patch to fix the race condition, which wasn't fixed by Rob's
+	patch.  It holds the gethostbyname lock until the results are copied out,
+	which means that this lock and the Python global lock are held at the same
+	time.  This shouldn't be a problem as long as the gethostbyname lock is
+	always acquired when the global lock is not held.
+
+Mon Mar 22 19:25:30 1999  Andrew Kuchling  <akuchlin at eric.cnri.reston.va.us>
+
+	* Modules/zlibmodule.c:
+	Fixed the flush() method of compression objects; the test for
+	    the end of loop was incorrect, and failed when the flushmode != Z_FINISH.
+	    Logic cleaned up and commented.
+
+	* Lib/test/test_zlib.py:
+	Added simple test for the flush() method of compression objects, trying the
+	    different flush values Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FULL_FLUSH.
+
+Mon Mar 22 15:28:08 1999  Guido van Rossum  <guido at eric.cnri.reston.va.us>
+
+	* Lib/shlex.py:
+	Bug reported by Tobias Thelen: missing "self." in assignment target.
+
+Fri Mar 19 21:50:11 1999  Guido van Rossum  <guido at eric.cnri.reston.va.us>
+
+	* Modules/arraymodule.c:
+	Use an unsigned cast to avoid a warning in VC++.
+
+	* Lib/dospath.py, Lib/ntpath.py:
+	New code for split() by Tim Peters, behaves more like posixpath.split().
+
+	* Objects/floatobject.c:
+	Fix a problem with Vladimir's PyFloat_Fini code: clear the free list; if
+	a block cannot be freed, add its free items back to the free list.
+	This is necessary to avoid leaking when Python is reinitialized later.
+
+	* Objects/intobject.c:
+	Fix a problem with Vladimir's PyInt_Fini code: clear the free list; if
+	a block cannot be freed, add its free items back to the free list, and
+	add its valid ints back to the small_ints array if they are in range.
+	This is necessary to avoid leaking when Python is reinitialized later.
+
+	* Lib/types.py:
+	Added BufferType, the type returned by the new builtin buffer().  Greg Stein.
+
+	* Python/bltinmodule.c:
+	New builtin buffer() creates a derived read-only buffer from any
+	object that supports the buffer interface (e.g. strings, arrays).
+
+	* Objects/bufferobject.c:
+	Added check for negative offset for PyBuffer_FromObject and check for
+	negative size for PyBuffer_FromMemory.  Greg Stein.
+
+Thu Mar 18 15:10:44 1999  Guido van Rossum  <guido at eric.cnri.reston.va.us>
+
+	* Lib/urlparse.py: Sjoerd Mullender writes:
+
+	If a filename on Windows starts with \\, it is converted to a URL
+	which starts with ////.  If this URL is passed to urlparse.urlparse
+	you get a path that starts with // (and an empty netloc).  If you pass
+	the result back to urlparse.urlunparse, you get a URL that starts with
+	//, which is parsed differently by urlparse.urlparse.  The fix is to
+	add the (empty) netloc with accompanying slashes if the path in
+	urlunparse starts with //.  Do this for all schemes that use a netloc.
+
+	* Lib/nturl2path.py: Sjoerd Mullender writes:
+
+	Pathnames of files on other hosts in the same domain
+	(\\host\path\to\file) are not translated correctly to URLs and back.
+	The URL should be something like file:////host/path/to/file.
+	Note that a combination of drive letter and remote host is not
+	possible.
+
+Wed Mar 17 22:30:10 1999  Guido van Rossum  <guido at eric.cnri.reston.va.us>
+
+	* Lib/urlparse.py:
+	Delete non-standard-conforming code in urljoin() that would use the
+	netloc from the base url as the default netloc for the resulting url
+	even if the schemes differ.
+
+	Once upon a time, when the web was wild, this was a valuable hack
+	because some people had a URL referencing an ftp server colocated with
+	an http server without having the host in the ftp URL (so they could
+	replicate it or change the hostname easily).
+
+	More recently, after the file: scheme got added back to the list of
+	schemes that accept a netloc, it turns out that this caused weirdness
+	when joining an http: URL with a file: URL -- the resulting file: URL
+	would always inherit the host from the http: URL because the file:
+	scheme supports a netloc but in practice never has one.
+
+	There are two reasons to get rid of the old, once-valuable hack,
+	instead of removing the file: scheme from the uses_netloc list.  One,
+	the RFC says that file: uses the netloc syntax, and does not endorse
+	the old hack.  Two, neither netscape 4.5 nor IE 4.0 support the old
+	hack.
+
+	* Include/ceval.h, Include/abstract.h:
+	Add DLL level b/w compat for PySequence_In and PyEval_CallObject
+
+Tue Mar 16 21:54:50 1999  Guido van Rossum  <guido at eric.cnri.reston.va.us>
+
+	* Lib/lib-tk/Tkinter.py: Bug reported by Jim Robinson:
+
+	An attempt to execute grid_slaves with arguments (0,0) results in
+	*all* of the slaves being returned, not just the slave associated with
+	row 0, column 0.  This is because the test for arguments in the method
+	does not test to see if row (and column) does not equal None, but
+	rather just whether is evaluates to non-false.  A value of 0 fails
+	this test.
+
+Tue Mar 16 14:17:48 1999  Fred Drake  <fdrake at eric.cnri.reston.va.us>
+
+	* Modules/cmathmodule.c:
+	Docstring fix:  acosh() returns the hyperbolic arccosine, not the
+	hyperbolic cosine.  Problem report via David Ascher by one of his
+	students.
+
+Mon Mar 15 21:40:59 1999  Guido van Rossum  <guido at eric.cnri.reston.va.us>
+
+	* configure.in:
+	Should test for gethost*by*name_r, not for gethostname_r (which
+	doesn't exist and doesn't make sense).
+
+	* Modules/socketmodule.c:
+	Patch by Rob Riggs for Linux -- glibc2 has a different argument
+	converntion for gethostbyname_r() etc. than Solaris!
+
+	* Python/thread_pthread.h: Rob Riggs wrote:
+
+	"""
+	Spec says that on success pthread_create returns 0. It does not say
+	that an error code will be < 0. Linux glibc2 pthread_create() returns
+	ENOMEM (12) when one exceed process limits. (It looks like it should
+	return EAGAIN, but that's another story.)
+
+	For reference, see:
+	http://www.opengroup.org/onlinepubs/7908799/xsh/pthread_create.html
+	"""
+
+	[I have a feeling that similar bugs were fixed before; perhaps someone
+	could check that all error checks no check for != 0?]
+
+	* Tools/bgen/bgen/bgenObjectDefinition.py:
+	New mixin class that defines cmp and hash that use
+	the ob_itself pointer.  This allows (when using the mixin)
+	different Python objects pointing to the same C object and
+	behaving well as dictionary keys.
+
+	Or so sez Jack Jansen...
+
+	* Lib/urllib.py: Yet another patch by Sjoerd Mullender:
+
+	Don't convert URLs to URLs using pathname2url.
+
+Fri Mar 12 22:15:43 1999  Guido van Rossum  <guido at eric.cnri.reston.va.us>
+
+	* Lib/cmd.py: Patch by Michael Scharf.  He writes:
+
+	    The module cmd requires for each do_xxx command a help_xxx
+	    function. I think this is a little old fashioned.
+
+	    Here is a patch: use the docstring as help if no help_xxx
+	    function can be found.
+
+	[I'm tempted to rip out all the help_* functions from pdb, but I'll
+	resist it.  Any takers?  --Guido]
+
+	* Tools/freeze/freeze.py: Bug submitted by Wayne Knowles, who writes:
+
+	   Under Windows, python freeze.py -o hello hello.py
+	   creates all the correct files in the hello subdirectory, but the
+	   Makefile has the directory prefix in it for frozen_extensions.c
+	   nmake fails because it tries to locate hello/frozen_extensions.c
+
+	(His fix adds a call to os.path.basename() in the appropriate place.)
+
+	* Objects/floatobject.c, Objects/intobject.c:
+	Vladimir has restructured his code somewhat so that the blocks are now
+	represented by an explicit structure.  (There are still too many casts
+	in the code, but that may be unavoidable.)
+
+	Also added code so that with -vv it is very chatty about what it does.
+
+	* Demo/zlib/zlibdemo.py, Demo/zlib/minigzip.py:
+	Change #! line to modern usage; also chmod +x
+
+	* Demo/pdist/rrcs, Demo/pdist/rcvs, Demo/pdist/rcsbump:
+	Change #! line to modern usage
+
+	* Lib/nturl2path.py, Lib/urllib.py: From: Sjoerd Mullender
+
+	The filename to URL conversion didn't properly quote special
+	characters.
+	The URL to filename didn't properly unquote special chatacters.
+
+	* Objects/floatobject.c:
+	OK, try again.  Vladimir gave me a fix for the alignment bus error,
+	so here's his patch again.  This time it works (at least on Solaris,
+	Linux and Irix).
+
+Thu Mar 11 23:21:23 1999  Guido van Rossum  <guido at eric.cnri.reston.va.us>
+
+	* Tools/idle/PathBrowser.py:
+	Don't crash when sys.path contains an empty string.
+
+	* Tools/idle/PathBrowser.py:
+	- Don't crash in the case where a superclass is a string instead of a
+	pyclbr.Class object; this can happen when the superclass is
+	unrecognizable (to pyclbr), e.g. when module renaming is used.
+
+	- Show a watch cursor when calling pyclbr (since it may take a while
+	recursively parsing imported modules!).
+
+Thu Mar 11 16:04:04 1999  Fred Drake  <fdrake at eric.cnri.reston.va.us>
+
+	* Lib/mimetypes.py:
+	Added .rdf and .xsl as application/xml types.  (.rdf is for the
+	Resource Description Framework, a metadata encoding, and .xsl is for
+	the Extensible Stylesheet Language.)
+
+Thu Mar 11 13:26:23 1999  Guido van Rossum  <guido at eric.cnri.reston.va.us>
+
+	* Lib/test/output/test_popen2, Lib/test/test_popen2.py:
+	Test for popen2 module, by Chris Tismer.
+
+	* Objects/floatobject.c:
+	Alas, Vladimir's patch caused a bus error (probably double
+	alignment?), and I didn't test it.  Withdrawing it for now.
+
+Wed Mar 10 22:55:47 1999  Guido van Rossum  <guido at eric.cnri.reston.va.us>
+
+	* Objects/floatobject.c:
+	Patch by Vladimir Marangoz to allow freeing of the allocated blocks of
+	floats on finalization.
+
+	* Objects/intobject.c:
+	Patch by Vladimir Marangoz to allow freeing of the allocated blocks of
+	integers on finalization.
+
+	* Tools/idle/EditorWindow.py, Tools/idle/Bindings.py:
+	Add PathBrowser to File module
+
+	* Tools/idle/PathBrowser.py:
+	"Path browser" - 4 scrolled lists displaying:
+	    directories on sys.path
+	    modules in selected directory
+	    classes in selected module
+	    methods of selected class
+
+	Sinlge clicking in a directory, module or class item updates the next
+	column with info about the selected item.  Double clicking in a
+	module, class or method item opens the file (and selects the clicked
+	item if it is a class or method).
+
+	I guess eventually I should be using a tree widget for this, but the
+	ones I've seen don't work well enough, so for now I use the old
+	Smalltalk or NeXT style multi-column hierarchical browser.
+
+	* Tools/idle/MultiScrolledLists.py:
+	New utility: multiple scrolled lists in parallel
+
+	* Tools/idle/ScrolledList.py: - White background.
+	- Display "(None)" (or text of your choosing) when empty.
+	- Don't set the focus.
+
+Tue Mar  9 19:31:21 1999  Guido van Rossum  <guido at eric.cnri.reston.va.us>
+
+	* Lib/urllib.py:
+	open_http also had the 'data is None' test backwards.  don't call with the
+	extra argument if data is None.
+
+	* Demo/embed/demo.c:
+	Call Py_SetProgramName() instead of redefining getprogramname(),
+	reflecting changes in the runtime around 1.5 or earlier.
+
+	* Python/ceval.c:
+	Always test for an error return (usually NULL or -1) without setting
+	an exception.
+
+	* Modules/timemodule.c: Patch by Chris Herborth for BeOS code.
+	He writes:
+
+	I had an off-by-1000 error in floatsleep(),
+	and the problem with time.clock() is that it's not implemented properly
+	on QNX... ANSI says it's supposed to return _CPU_ time used by the
+	process, but on QNX it returns the amount of real time used... so I was
+	confused.
+
+	* Tools/bgen/bgen/macsupport.py: Small change by Jack Jansen.
+	Test for self.returntype behaving like OSErr rather than being it.
+
+Thu Feb 25 16:14:58 1999  Jeremy Hylton  <jhylton at eric.cnri.reston.va.us>
+
+	* Lib/urllib.py:
+	http_error had the 'data is None' test backwards.  don't call with the
+	extra argument if data is None.
+
+	* Lib/urllib.py: change indentation from 8 spaces to 4 spaces
+
+	* Lib/urllib.py: pleasing the tabnanny
+
+Thu Feb 25 14:26:02 1999  Fred Drake  <fdrake at eric.cnri.reston.va.us>
+
+	* Lib/colorsys.py:
+	Oops, one more "x, y, z" to convert...
+
+	* Lib/colorsys.py:
+	Adjusted comment at the top to be less confusing, following Fredrik
+	Lundh's example.
+
+	Converted comment to docstring.
+
+Wed Feb 24 18:49:15 1999  Fred Drake  <fdrake at eric.cnri.reston.va.us>
+
+	* Lib/toaiff.py:
+	Use sndhdr instead of the obsolete whatsound module.
+
+Wed Feb 24 18:42:38 1999  Jeremy Hylton  <jhylton at eric.cnri.reston.va.us>
+
+	* Lib/urllib.py:
+	When performing a POST request, i.e. when the second argument to
+	urlopen is used to specify form data, make sure the second argument is
+	threaded through all of the http_error_NNN calls.  This allows error
+	handlers like the redirect and authorization handlers to properly
+	re-start the connection.
+
+Wed Feb 24 16:25:17 1999  Guido van Rossum  <guido at eric.cnri.reston.va.us>
+
+	* Lib/mhlib.py: Patch by Lars Wirzenius:
+
+		o the initial comment is wrong: creating messages is already
+		  implemented
+
+		o Message.getbodytext: if the mail or it's part contains an
+		  empty content-transfer-encoding header, the code used to
+		  break; the change below treats an empty encoding value the same
+		  as the other types that do not need decoding
+
+		o SubMessage.getbodytext was missing the decode argument; the
+		  change below adds it; I also made it unconditionally return
+		  the raw text if decoding was not desired, because my own
+		  routines needed that (and it was easier than rewriting my
+		  own routines ;-)
+
+Wed Feb 24 00:35:43 1999  Barry Warsaw  <bwarsaw at eric.cnri.reston.va.us>
+
+	* Python/bltinmodule.c (initerrors):
+	Make sure that the exception tuples ("base-classes" when
+	string-based exceptions are used) reflect the real class hierarchy,
+	i.e. that SystemExit derives from Exception not StandardError.
+
+	* Lib/exceptions.py:
+	Document the correct class hierarchy for SystemExit.  It is not an
+	error and so it derives from Exception and not SystemError.  The
+	docstring was incorrect but the implementation was fine.
+
+Tue Feb 23 23:07:51 1999  Guido van Rossum  <guido at eric.cnri.reston.va.us>
+
+	* Lib/shutil.py:
+	Add import sys, needed by reference to sys.exc_info() in rmtree().
+	Discovered by Mitch Chapman.
+
+	* config.h.in:
+	Now that we don't have AC_CHECK_LIB(m, pow), the HAVE_LIBM symbol
+	disappears.  It wasn't used anywhere anyway...
+
+	* Modules/arraymodule.c:
+	Carefully check for overflow when allocating the memory for fromfile
+	-- someone tried to pass in sys.maxint and got bitten by the bogus
+	calculations.
+
+	* configure.in:
+	Get rid of AC_CHECK_LIB(m, pow) since this is taken care of later with
+	LIBM (from --with-libm=...); this actually broke the customizability
+	offered by the latter option.  Thanks go to Clay Spence for reporting
+	this.
+
+	* Lib/test/test_dl.py:
+	1. Print the error message (carefully) when a dl.open() fails in verbose mode.
+	2. When no test case worked, raise ImportError instead of failing.
+
+	* Python/bltinmodule.c:
+	Patch by Tim Peters to improve the range checks for range() and
+	xrange(), especially for platforms where int and long are different
+	sizes (so sys.maxint isn't actually the theoretical limit for the
+	length of a list, but the largest C int is -- sys.maxint is the
+	largest Python int, which is actually a C long).
+
+	* Makefile.in:
+	1. Augment the DG/UX rule so it doesn't break the BeOS build.
+	2. Add $(EXE) to various occurrences of python so it will work on
+	   Cygwin with egcs (after setting EXE=.exe).  These patches by
+	   Norman Vine.
+
+	* Lib/posixfile.py:
+	According to Jeffrey Honig, bsd/os 2.0 - 4.0 should be added to the
+	list (of bsd variants that have a different lock structure).
+
+	* Lib/test/test_fcntl.py:
+	According to Jeffrey Honig, bsd/os 4.0 should be added to the list.
+
+	* Modules/timemodule.c:
+	Patch by Tadayoshi Funaba (with some changes) to be smarter about
+	guessing what happened when strftime() returns 0.  Is it buffer
+	overflow or was the result simply 0 bytes long?  (This happens for an
+	empty format string, or when the format string is a single %Z and the
+	timezone is unknown.)  if the buffer is at least 256 times as long as
+	the format, assume the latter.
+
+Mon Feb 22 19:01:42 1999  Guido van Rossum  <guido at eric.cnri.reston.va.us>
+
+	* Lib/urllib.py:
+	As Des Barry points out, we need to call pathname2url(file) in two
+	calls to addinfourl() in open_file().
+
+	* Modules/Setup.in: Document *static* -- in two places!
+
+	* Modules/timemodule.c:
+	We don't support leap seconds, so the seconds field of a time 9-tuple
+	should be in the range [0-59].  Noted by Tadayoshi Funaba.
+
+	* Modules/stropmodule.c:
+	In atoi(), don't use isxdigit() to test whether the last character
+	converted was a "digit" -- use isalnum().  This test is there only to
+	guard against "+" or "-" being interpreted as a valid int literal.
+	Reported by Takahiro Nakayama.
+
+	* Lib/os.py:
+	As Finn Bock points out, _P_WAIT etc. don't have a leading underscore
+	so they don't need to be treated specially here.
+
+Mon Feb 22 15:38:58 1999  Fred Drake  <fdrake at eric.cnri.reston.va.us>
+
+	* Misc/NEWS:
+	Typo:  "apparentlt" --> "apparently"
+
+Mon Feb 22 15:38:46 1999  Guido van Rossum  <guido at eric.cnri.reston.va.us>
+
+	* Lib/urlparse.py: Steve Clift pointed out that 'file' allows a netloc.
+
+	* Modules/posixmodule.c:
+	The docstring for ttyname(..) claims a second "mode" argument. The
+	actual code does not allow such an argument.  (Finn Bock.)
+
+	* Lib/lib-old/poly.py:
+	Dang.  Even though this is obsolete code, somebody found a bug, and I
+	fix it.  Oh well.
+
+Thu Feb 18 20:51:50 1999  Fred Drake  <fdrake at eric.cnri.reston.va.us>
+
+	* Lib/pyclbr.py:
+	Bow to font-lock at the end of the docstring, since it throws stuff
+	off.
+
+	Make sure the path paramter to readmodule() is a list before adding it
+	with sys.path, or the addition could fail.
+
+
+======================================================================
+
+
+From 1.5.2b1 to 1.5.2b2
+=======================
+
+General
+-------
+
+- Many memory leaks fixed.
+
+- Many small bugs fixed.
+
+- Command line option -OO (or -O -O) suppresses inclusion of doc
+strings in resulting bytecode.
+
+Windows-specific changes
+------------------------
+
+- New built-in module winsound provides an interface to the Win32
+PlaySound() call.
+
+- Re-enable the audioop module in the config.c file.
+
+- On Windows, support spawnv() and associated P_* symbols.
+
+- Fixed the conversion of times() return values on Windows.
+
+- Removed freeze from the installer -- it doesn't work without the
+source tree.  (See FAQ 8.11.)
+
+- On Windows 95/98, the Tkinter module now is smart enough to find
+Tcl/Tk even when the PATH environment variable hasn't been set -- when
+the import of _tkinter fails, it searches in a standard locations,
+patches os.environ["PATH"], and tries again.  When it still fails, a
+clearer error message is produced.  This should avoid most
+installation problems with Tkinter use (e.g. in IDLE).
+
+- The -i option doesn't make any calls to set[v]buf() for stdin --
+this apparently screwed up _kbhit() and the _tkinter main loop.
+
+- The ntpath module (and hence, os.path on Windows) now parses out UNC
+paths (e.g. \\host\mountpoint\dir\file) as "drive letters", so that
+splitdrive() will \\host\mountpoint as the drive and \dir\file as the
+path.  ** EXPERIMENTAL **
+
+- Added a hack to the exit code so that if (1) the exit status is
+nonzero and (2) we think we have our own DOS box (i.e. we're not
+started from a command line shell), we print a message and wait for
+the user to hit a key before the DOS box is closed.
+
+- Updated the installer to WISE 5.0g.  Added a dialog warning about
+the imminent Tcl installation.  Added a dialog to specify the program
+group name in the start menu.  Upgraded the Tcl installer to Tcl
+8.0.4.
+
+Changes to intrinsics
+---------------------
+
+- The repr() or str() of a module object now shows the __file__
+attribute (i.e., the file which it was loaded), or the string
+"(built-in)" if there is no __file__ attribute.
+
+- The range() function now avoids overflow during its calculations (if
+at all possible).
+
+- New info string sys.hexversion, which is an integer encoding the
+version in hexadecimal.  In other words, hex(sys.hexversion) ==
+0x010502b2 for Python 1.5.2b2.
+
+New or improved ports
+---------------------
+
+- Support for Nextstep descendants (future Mac systems).
+
+- Improved BeOS support.
+
+- Support dynamic loading of shared libraries on NetBSD platforms that 
+use ELF (i.e., MIPS and Alpha systems).
+
+Configuration/build changes
+---------------------------
+
+- The Lib/test directory is no longer included in the default module
+search path (sys.path) -- "test" has been a package ever since 1.5.
+
+- Now using autoconf 2.13.
+
+New library modules
+-------------------
+
+- New library modules asyncore and asynchat: these form Sam Rushing's
+famous asynchronous socket library.  Sam has gracefully allowed me to
+incorporate these in the standard Python library.
+
+- New module statvfs contains indexing constants for [f]statvfs()
+return tuple.
+
+Changes to the library
+----------------------
+
+- The wave module (platform-independent support for Windows sound
+files) has been fixed to actually make it work.
+
+- The sunau module (platform-independent support for Sun/NeXT sound
+files) has been fixed to work across platforms.  Also, a weird
+encoding bug in the header of the audio test data file has been
+corrected.
+
+- Fix a bug in the urllib module that occasionally tripped up
+webchecker and other ftp retrieves.
+
+- ConfigParser's get() method now accepts an optional keyword argument
+(vars) that is substituted on top of the defaults that were setup in
+__init__.  You can now also have recusive references in your
+configuration file.
+
+- Some improvements to the Queue module, including a put_nowait()
+module and an optional "block" second argument, to get() and put(),
+defaulting to 1.
+
+- The updated xmllib module is once again compatible with the version
+present in Python 1.5.1 (this was accidentally broken in 1.5.2b1).
+
+- The bdb module (base class for the debugger) now supports
+canonicalizing pathnames used in breakpoints.  The derived class must
+override the new canonical() method for this to work.  Also changed
+clear_break() to the backwards compatible old signature, and added
+clear_bpbynumber() for the new functionality.
+
+- In sgmllib (and hence htmllib), recognize attributes even if they
+don't have space in front of them.  I.e.  '<a
+name="foo"href="bar.html">' will now have two attributes recognized.
+
+- In the debugger (pdb), change clear syntax to support three
+alternatives: clear; clear file:line; clear bpno bpno ...
+
+- The os.path module now pretends to be a submodule within the os
+"package", so you can do things like "from os.path import exists".
+
+- The standard exceptions now have doc strings.
+
+- In the smtplib module, exceptions are now classes.  Also avoid
+inserting a non-standard space after "TO" in rcpt() command.
+
+- The rfc822 module's getaddrlist() method now uses all occurrences of
+the specified header instead of just the first.  Some other bugfixes
+too (to handle more weird addresses found in a very large test set,
+and to avoid crashes on certain invalid dates), and a small test
+module has been added.
+
+- Fixed bug in urlparse in the common-case code for HTTP URLs; it
+would lose the query, fragment, and/or parameter information.
+
+- The sndhdr module no longer supports whatraw() -- it depended on a
+rare extenral program.
+
+- The UserList module/class now supports the extend() method, like
+real list objects.
+
+- The uu module now deals better with trailing garbage generated by
+some broke uuencoders.
+
+- The telnet module now has an my_interact() method which uses threads
+instead of select.  The interact() method uses this by default on
+Windows (where the single-threaded version doesn't work).
+
+- Add a class to mailbox.py for dealing with qmail directory
+mailboxes.  The test code was extended to notice these being used as
+well.
+
+Changes to extension modules
+----------------------------
+
+- Support for the [f]statvfs() system call, where it exists.
+
+- Fixed some bugs in cPickle where bad input could cause it to dump
+core.
+
+- Fixed cStringIO to make the writelines() function actually work.
+
+- Added strop.expandtabs() so string.expandtabs() is now much faster.
+
+- Added fsync() and fdatasync(), if they appear to exist.
+
+- Support for "long files" (64-bit seek pointers).
+
+- Fixed a bug in the zlib module's flush() function.
+
+- Added access() system call.  It returns 1 if access granted, 0 if
+not.
+
+- The curses module implements an optional nlines argument to
+w.scroll().  (It then calls wscrl(win, nlines) instead of scoll(win).)
+
+Changes to tools
+----------------
+
+- Some changes to IDLE; see Tools/idle/NEWS.txt.
+
+- Latest version of Misc/python-mode.el included.
+
+Changes to Tkinter
+------------------
+
+- Avoid tracebacks when an image is deleted after its root has been
+destroyed.
+
+Changes to the Python/C API
+---------------------------
+
+- When parentheses are used in a PyArg_Parse[Tuple]() call, any
+sequence is now accepted, instead of requiring a tuple.  This is in
+line with the general trend towards accepting arbitrary sequences.
+
+- Added PyModule_GetFilename().
+
+- In PyNumber_Power(), remove unneeded and even harmful test for float
+to the negative power (which is already and better done in
+floatobject.c).
+
+- New version identification symbols; read patchlevel.h for info.  The
+version numbers are now exported by Python.h.
+
+- Rolled back the API version change -- it's back to 1007!
+
+- The frozenmain.c function calls PyInitFrozenExtensions().
+
+- Added 'N' format character to Py_BuildValue -- like 'O' but doesn't
+INCREF.
+
+
+======================================================================
+
+
+From 1.5.2a2 to 1.5.2b1
+=======================
+
+Changes to intrinsics
+---------------------
+
+- New extension NotImplementedError, derived from RuntimeError.  Not
+used, but recommended use is for "abstract" methods to raise this.
+
+- The parser will now spit out a warning or error when -t or -tt is
+used for parser input coming from a string, too.
+
+- The code generator now inserts extra SET_LINENO opcodes when
+compiling multi-line argument lists.
+
+- When comparing bound methods, use identity test on the objects, not
+equality test.
+
+New or improved ports
+---------------------
+
+- Chris Herborth has redone his BeOS port; it now works on PowerPC
+(R3/R4) and x86 (R4 only).  Threads work too in this port.
+
+Renaming
+--------
+
+- Thanks to Chris Herborth, the thread primitives now have proper Py*
+names in the source code (they already had those for the linker,
+through some smart macros; but the source still had the old, un-Py
+names).
+
+Configuration/build changes
+---------------------------
+
+- Improved support for FreeBSD/3.
+
+- Check for pthread_detach instead of pthread_create in libc.
+
+- The makesetup script now searches EXECINCLUDEPY before INCLUDEPY.
+
+- Misc/Makefile.pre.in now also looks at Setup.thread and Setup.local.
+Otherwise modules such as thread didn't get incorporated in extensions.
+
+New library modules
+-------------------
+
+- shlex.py by Eric Raymond provides a lexical analyzer class for
+simple shell-like syntaxes.
+
+- netrc.py by Eric Raymond provides a parser for .netrc files.  (The
+undocumented Netrc class in ftplib.py is now obsolete.)
+
+- codeop.py is a new module that contains the compile_command()
+function that was previously in code.py.  This is so that JPython can
+provide its own version of this function, while still sharing the
+higher-level classes in code.py.
+
+- turtle.py is a new module for simple turtle graphics.  I'm still
+working on it; let me know if you use this to teach Python to children 
+or other novices without prior programming experience.
+
+Obsoleted library modules
+-------------------------
+
+- poly.py and zmod.py have been moved to Lib/lib-old to emphasize
+their status of obsoleteness.  They don't do a particularly good job
+and don't seem particularly relevant to the Python core.
+
+New tools
+---------
+
+- I've added IDLE: my Integrated DeveLopment Environment for Python.
+Requires Tcl/Tk (and Tkinter).  Works on Windows and Unix (and should
+work on Macintosh, but I haven't been able to test it there; it does
+depend on new features in 1.5.2 and perhaps even new features in
+1.5.2b1, especially the new code module).  This is very much a work in
+progress.  I'd like to hear how people like it compared to PTUI (or
+any other IDE they are familiar with).
+
+- New tools by Barry Warsaw:
+
+  = audiopy: controls the Solaris Audio device
+  = pynche:  The PYthonically Natural Color and Hue Editor
+  = world:   Print mappings between country names and DNS country codes
+
+New demos
+---------
+
+- Demo/scripts/beer.py prints the lyrics to an arithmetic drinking
+song.
+
+- Demo/tkinter/guido/optionmenu.py shows how to do an option menu in
+Tkinter.  (By Fredrik Lundh -- not by me!)
+
+Changes to the library
+----------------------
+
+- compileall.py now avoids recompiling .py files that haven't changed;
+it adds a -f option to force recompilation.
+
+- New version of xmllib.py by Sjoerd Mullender (0.2 with latest
+patches).
+
+- nntplib.py: statparse() no longer lowercases the message-id.
+
+- types.py: use type(__stdin__) for FileType.
+
+- urllib.py: fix translations for filenames with "funny" characters.
+Patch by Sjoerd Mullender.  Note that if you subclass one of the
+URLopener classes, and you have copied code from the old urllib.py,
+your subclass may stop working.  A long-term solution is to provide
+more methods so that you don't have to copy code.
+
+- cgi.py: In read_multi, allow a subclass to override the class we
+instantiate when we create a recursive instance, by setting the class
+variable 'FieldStorageClass' to the desired class.  By default, this
+is set to None, in which case we use self.__class__ (as before).
+Also, a patch by Jim Fulton to pass additional arguments to recursive
+calls to the FieldStorage constructor from its read_multi method.
+
+- UserList.py: In __getslice__, use self.__class__ instead of
+UserList.
+
+- In SimpleHTTPServer.py, the server specified in test() should be
+BaseHTTPServer.HTTPServer, in case the request handler should want to
+reference the two attributes added by BaseHTTPServer.server_bind.  (By
+Jeff Rush, for Bobo).  Also open the file in binary mode, so serving
+images from a Windows box might actually work.
+
+- In CGIHTTPServer.py, the list of acceptable formats is -split-
+on spaces but -joined- on commas, resulting in double commas
+in the joined text.  (By Jeff Rush.)
+
+- SocketServer.py, patch by Jeff Bauer: a minor change to declare two
+new threaded versions of Unix Server classes, using the ThreadingMixIn
+class: ThreadingUnixStreamServer, ThreadingUnixDatagramServer.
+
+- bdb.py: fix bomb on deleting a temporary breakpoint: there's no
+method do_delete(); do_clear() was meant.  By Greg Ward.
+
+- getopt.py: accept a non-list sequence for the long options (request
+by Jack Jansen).  Because it might be a common mistake to pass a
+single string, this situation is treated separately.  Also added
+docstrings (copied from the library manual) and removed the (now
+redundant) module comments.
+
+- tempfile.py: improvements to avoid security leaks.
+
+- code.py: moved compile_command() to new module codeop.py.
+
+- pickle.py: support pickle format 1.3 (binary float added).  By Jim
+Fulton. Also get rid of the undocumented obsolete Pickler dump_special
+method.
+
+- uu.py: Move 'import sys' to top of module, as noted by Tim Peters.
+
+- imaplib.py: fix problem with some versions of IMAP4 servers that
+choose to mix the case in their CAPABILITIES response.
+
+- cmp.py: use (f1, f2) as cache key instead of f1 + ' ' + f2.  Noted
+by Fredrik Lundh.
+
+Changes to extension modules
+----------------------------
+
+- More doc strings for several modules were contributed by Chris
+Petrilli: math, cmath, fcntl.
+
+- Fixed a bug in zlibmodule.c that could cause core dumps on
+decompression of rarely occurring input.
+
+- cPickle.c: new version from Jim Fulton, with Open Source copyright
+notice.  Also, initialize self->safe_constructors early on to prevent
+crash in early dealloc.
+
+- cStringIO.c: new version from Jim Fulton, with Open Source copyright
+notice.  Also fixed a core dump in cStringIO.c when doing seeks.
+
+- mpzmodule.c: fix signed character usage in mpz.mpz(stringobjecty).
+
+- readline.c: Bernard Herzog pointed out that rl_parse_and_bind
+modifies its argument string (bad function!), so we make a temporary
+copy.
+
+- sunaudiodev.c: Barry Warsaw added more smarts to get the device and
+control pseudo-device, per audio(7I).
+
+Changes to tools
+----------------
+
+- New, improved version of Barry Warsaw's Misc/python-mode.el (editing 
+support for Emacs).
+
+- tabnanny.py: added a -q ('quiet') option to tabnanny, which causes
+only the names of offending files to be printed.
+
+- freeze: when printing missing modules, also print the module they
+were imported from.
+
+- untabify.py: patch by Detlef Lannert to implement -t option
+(set tab size).
+
+Changes to Tkinter
+------------------
+
+- grid_bbox(): support new Tk API: grid bbox ?column row? ?column2
+row2?
+
+- _tkinter.c: RajGopal Srinivasan noted that the latest code (1.5.2a2)
+doesn't work when running in a non-threaded environment.  He added
+some #ifdefs that fix this.
+
+Changes to the Python/C API
+---------------------------
+
+- Bumped API version number to 1008 -- enough things have changed!
+
+- There's a new macro, PyThreadState_GET(), which does the same work
+as PyThreadState_Get() without the overhead of a function call (it
+also avoids the error check).  The two top calling locations of
+PyThreadState_Get() have been changed to use this macro.
+
+- All symbols intended for export from a DLL or shared library are now
+marked as such (with the DL_IMPORT() macro) in the header file that
+declares them.  This was needed for the BeOS port, and should also
+make some other ports easier.  The PC port no longer needs the file
+with exported symbols (PC/python_nt.def).  There's also a DL_EXPORT
+macro which is only used for init methods in extension modules, and
+for Py_Main().
+
+Invisible changes to internals
+------------------------------
+
+- Fixed a bug in new_buffersize() in fileobject.c which could
+return a buffer size that was way too large.
+
+- Use PySys_WriteStderr instead of fprintf in most places.
+
+- dictobject.c: remove dead code discovered by Vladimir Marangozov.
+
+- tupleobject.c: make tuples less hungry -- an extra item was
+allocated but never used.  Tip by Vladimir Marangozov.
+
+- mymath.h: Metrowerks PRO4 finally fixes the hypot snafu.  (Jack
+Jansen)
+
+- import.c: Jim Fulton fixes a reference count bug in
+PyEval_GetGlobals.
+
+- glmodule.c: check in the changed version after running the stubber
+again -- this solves the conflict with curses over the 'clear' entry
+point much nicer.  (Jack Jansen had checked in the changes to cstubs
+eons ago, but I never regenrated glmodule.c :-( )
+
+- frameobject.c: fix reference count bug in PyFrame_New.  Vladimir
+Marangozov.
+
+- stropmodule.c: add a missing DECREF in an error exit.  Submitted by
+Jonathan Giddy.
+
+
+======================================================================
+
+
+From 1.5.2a1 to 1.5.2a2
+=======================
+
+General
+-------
+
+- It is now a syntax error to have a function argument without a
+default following one with a default.
+
+- __file__ is now set to the .py file if it was parsed (it used to
+always be the .pyc/.pyo file).
+
+- Don't exit with a fatal error during initialization when there's a
+problem with the exceptions.py module.
+
+- New environment variable PYTHONOPTIMIZE can be used to set -O.
+
+- New version of python-mode.el for Emacs.
+
+Miscellaneous fixed bugs
+------------------------
+
+- No longer print the (confusing) error message about stack underflow
+while compiling.
+
+- Some threading and locking bugs fixed.
+
+- When errno is zero, report "Error", not "Success".
+
+Documentation
+-------------
+
+- Documentation will be released separately.
+
+- Doc strings added to array and md5 modules by Chris Petrilli.
+
+Ports and build procedure
+-------------------------
+
+- Stop installing when a move or copy fails.
+
+- New version of the OS/2 port code by Jeff Rush.
+
+- The makesetup script handles absolute filenames better.
+
+- The 'new' module is now enabled by default in the Setup file.
+
+- I *think* I've solved the problem with the Linux build blowing up
+sometimes due to a conflict between sigcheck/intrcheck and
+signalmodule.
+
+Built-in functions
+------------------
+
+- The second argument to apply() can now be any sequence, not just a
+tuple.
+
+Built-in types
+--------------
+
+- Lists have a new method: L1.extend(L2) is equivalent to the common
+idiom L1[len(L1):] = L2.
+
+- Better error messages when a sequence is indexed with a non-integer.
+
+- Bettter error message when calling a non-callable object (include
+the type in the message).
+
+Python services
+---------------
+
+- New version of cPickle.c fixes some bugs.
+
+- pickle.py: improved instantiation error handling.
+
+- code.py: reworked quite a bit.  New base class
+InteractiveInterpreter and derived class InteractiveConsole.  Fixed
+several problems in compile_command().
+
+- py_compile.py: print error message and continue on syntax errors.
+Also fixed an old bug with the fstat code (it was never used).
+
+- pyclbr.py: support submodules of packages.
+
+String Services
+---------------
+
+- StringIO.py: raise the right exception (ValueError) for attempted
+I/O on closed StringIO objects.
+
+- re.py: fixed a bug in subn(), which caused .groups() to fail inside
+the replacement function called by sub().
+
+- The struct module has a new format 'P': void * in native mode.
+
+Generic OS Services
+-------------------
+
+- Module time: Y2K robustness.  2-digit year acceptance depends on
+value of time.accept2dyear, initialized from env var PYTHONY2K,
+default 0.  Years 00-68 mean 2000-2068, while 69-99 mean 1969-1999
+(POSIX or X/Open recommendation).
+
+- os.path: normpath(".//x") should return "x", not "/x".
+
+- getpass.py: fall back on default_getpass() when sys.stdin.fileno()
+doesn't work.
+
+- tempfile.py: regenerate the template after a fork() call.
+
+Optional OS Services
+--------------------
+
+- In the signal module, disable restarting interrupted system calls
+when we have siginterrupt().
+
+Debugger
+--------
+
+- No longer set __args__; this feature is no longer supported and can
+affect the debugged code.
+
+- cmd.py, pdb.py and bdb.py have been overhauled by Richard Wolff, who
+added aliases and some other useful new features, e.g. much better
+breakpoint support: temporary breakpoint, disabled breakpoints,
+breakpoints with ignore counts, and conditions; breakpoints can be set
+on a file before it is loaded.
+
+Profiler
+--------
+
+- Changes so that JPython can use it.  Also fix the calibration code
+so it actually works again
+.
+Internet Protocols and Support
+------------------------------
+
+- imaplib.py: new version from Piers Lauder.
+
+- smtplib.py: change sendmail() method to accept a single string or a
+list or strings as the destination (commom newbie mistake).
+
+- poplib.py: LIST with a msg argument fixed.
+
+- urlparse.py: some optimizations for common case (http).
+
+- urllib.py: support content-length in info() for ftp protocol;
+support for a progress meter through a third argument to
+urlretrieve(); commented out gopher test (the test site is dead).
+
+Internet Data handling
+----------------------
+
+- sgmllib.py: support tags with - or . in their name.
+
+- mimetypes.py: guess_type() understands 'data' URLs.
+
+Restricted Execution
+--------------------
+
+- The classes rexec.RModuleLoader and rexec.RModuleImporter no
+longer exist.
+
+Tkinter
+-------
+
+- When reporting an exception, store its info in sys.last_*.  Also,
+write all of it to stderr.
+
+- Added NS, EW, and NSEW constants, for grid's sticky option.
+
+- Fixed last-minute bug in 1.5.2a1 release: need to include "mytime.h".
+
+- Make bind variants without a sequence return a tuple of sequences
+(formerly it returned a string, which wasn't very convenient).
+
+- Add image commands to the Text widget (these are new in Tk 8.0).
+
+- Added new listbox and canvas methods: {xview,yview}_{scroll,moveto}.)
+
+- Improved the thread code (but you still can't call update() from
+another thread on Windows).
+
+- Fixed unnecessary references to _default_root in the new dialog
+modules.
+
+- Miscellaneous problems fixed.
+
+
+Windows General
+---------------
+
+- Call LoadLibraryEx(..., ..., LOAD_WITH_ALTERED_SEARCH_PATH) to
+search for dependent dlls in the directory containing the .pyd.
+
+- In debugging mode, call DebugBreak() in Py_FatalError().
+
+Windows Installer
+-----------------
+
+- Install zlib.dll in the DLLs directory instead of in the win32
+system directory, to avoid conflicts with other applications that have 
+their own zlib.dll.
+
+Test Suite
+----------
+
+- test_long.py: new test for long integers, by Tim Peters.
+
+- regrtest.py: improved so it can be used for other test suites as
+well.
+
+- test_strftime.py: use re to compare test results, to support legal
+variants (e.g. on Linux).
+
+Tools and Demos
+---------------
+
+- Four new scripts in Tools/scripts: crlf.py and lfcr.py (to
+remove/add Windows style '\r\n' line endings), untabify.py (to remove
+tabs), and rgrep.yp (reverse grep).
+
+- Improvements to Tools/freeze/.  Each Python module is now written to
+its own C file.  This prevents some compilers or assemblers from
+blowing up on large frozen programs, and saves recompilation time if
+only a few modules are changed.  Other changes too, e.g. new command
+line options -x and -i.
+
+- Much improved (and smaller!) version of Tools/scripts/mailerdaemon.py.
+
+Python/C API
+------------
+
+- New mechanism to support extensions of the type object while
+remaining backward compatible with extensions compiled for previous
+versions of Python 1.5.  A flags field indicates presence of certain
+fields.
+
+- Addition to the buffer API to differentiate access to bytes and
+8-bit characters (in anticipation of Unicode characters).
+
+- New argument parsing format t# ("text") to indicate 8-bit
+characters; s# simply means 8-bit bytes, for backwards compatibility.
+
+- New object type, bufferobject.c is an example and can be used to
+create buffers from memory.
+
+- Some support for 64-bit longs, including some MS platforms.
+
+- Many calls to fprintf(stderr, ...) have been replaced with calls to
+PySys_WriteStderr(...).
+
+- The calling context for PyOS_Readline() has changed: it must now be
+called with the interpreter lock held!  It releases the lock around
+the call to the function pointed to by PyOS_ReadlineFunctionPointer
+(default PyOS_StdioReadline()).
+
+- New APIs PyLong_FromVoidPtr() and PyLong_AsVoidPtr().
+
+- Renamed header file "thread.h" to "pythread.h".
+
+- The code string of code objects may now be anything that supports the
+buffer API.
+
+
+======================================================================
+
+
+From 1.5.1 to 1.5.2a1
+=====================
+
+General
+-------
+
+- When searching for the library, a landmark that is a compiled module
+(string.pyc or string.pyo) is also accepted.
+
+- When following symbolic links to the python executable, use a loop
+so that a symlink to a symlink can work.
+
+- Added a hack so that when you type 'quit' or 'exit' at the
+interpreter, you get a friendly explanation of how to press Ctrl-D (or 
+Ctrl-Z) to exit.
+
+- New and improved Misc/python-mode.el (Python mode for Emacs).
+
+- Revert a new feature in Unix dynamic loading: for one or two
+revisions, modules were loaded using the RTLD_GLOBAL flag.  It turned
+out to be a bad idea.
+
+Miscellaneous fixed bugs
+------------------------
+
+- All patches on the patch page have been integrated.  (But much more
+has been done!)
+
+- Several memory leaks plugged (e.g. the one for classes with a
+__getattr__ method).
+
+- Removed the only use of calloc().  This triggered an obscure bug on
+multiprocessor Sparc Solaris 2.6.
+
+- Fix a peculiar bug that would allow "import sys.time" to succeed
+(believing the built-in time module to be a part of the sys package).
+
+- Fix a bug in the overflow checking when converting a Python long to
+a C long (failed to convert -2147483648L, and some other cases).
+
+Documentation
+-------------
+
+- Doc strings have been added to many extension modules: __builtin__,
+errno, select, signal, socket, sys, thread, time.  Also to methods of
+list objects (try [].append.__doc__).  A doc string on a type will now
+automatically be propagated to an instance if the instance has methods
+that are accessed in the usual way.
+
+- The documentation has been expanded and the formatting improved.
+(Remember that the documentation is now unbundled and has its own
+release cycle though; see http://www.python.org/doc/.)
+
+- Added Misc/Porting -- a mini-FAQ on porting to a new platform.
+
+Ports and build procedure
+-------------------------
+
+- The BeOS port is now integrated.  Courtesy Chris Herborth.
+
+- Symbol files for FreeBSD 2.x and 3.x have been contributed
+(Lib/plat-freebsd[23]/*).
+
+- Support HPUX 10.20 DCE threads.
+
+- Finally fixed the configure script so that (on SGI) if -OPT:Olimit=0
+works, it won't also use -Olimit 1500 (which gives a warning for every
+file).  Also support the SGI_ABI environment variable better.
+
+- The makesetup script now understands absolute pathnames ending in .o
+in the module -- it assumes it's a file for which we have no source.
+
+- Other miscellaneous improvements to the configure script and
+Makefiles.
+
+- The test suite now uses a different sound sample.
+
+Built-in functions
+------------------
+
+- Better checks for invalid input to int(), long(), string.atoi(),
+string.atol().  (Formerly, a sign without digits would be accepted as
+a legal ways to spell zero.)
+
+- Changes to map() and filter() to use the length of a sequence only
+as a hint -- if an IndexError happens earlier, take that.  (Formerly,
+this was considered an error.)
+
+- Experimental feature in getattr(): a third argument can specify a
+default (instead of raising AttributeError).
+
+- Implement round() slightly different, so that for negative ndigits
+no additional errors happen in the last step.
+
+- The open() function now adds the filename to the exception when it
+fails.
+
+Built-in exceptions
+-------------------
+
+- New standard exceptions EnvironmentError and PosixError.
+EnvironmentError is the base class for IOError and PosixError;
+PosixError is the same as os.error.  All this so that either exception
+class can be instantiated with a third argument indicating a filename.
+The built-in function open() and most os/posix functions that take a
+filename argument now use this.
+
+Built-in types
+--------------
+
+- List objects now have an experimental pop() method; l.pop() returns
+and removes the last item; l.pop(i) returns and removes the item at
+i.  Also, the sort() method is faster again.  Sorting is now also
+safer: it is impossible for the sorting function to modify the list
+while the sort is going on (which could cause core dumps).
+
+- Changes to comparisons: numbers are now smaller than any other type.
+This is done to prevent the circularity where [] < 0L < 1 < [] is
+true.  As a side effect, cmp(None, 0) is now positive instead of
+negative.  This *shouldn't* affect any working code, but I've found
+that the change caused several "sleeping" bugs to become active, so
+beware!
+
+- Instance methods may now have other callable objects than just
+Python functions as their im_func.  Use new.instancemethod() or write
+your own C code to create them; new.instancemethod() may be called
+with None for the instance to create an unbound method.
+
+- Assignment to __name__, __dict__ or __bases__ of a class object is
+now allowed (with stringent type checks); also allow assignment to
+__getattr__ etc.  The cached values for __getattr__ etc. are
+recomputed after such assignments (but not for derived classes :-( ).
+
+- Allow assignment to some attributes of function objects: func_code,
+func_defaults and func_doc / __doc__.  (With type checks except for
+__doc__ / func_doc .)
+
+Python services
+---------------
+
+- New tests (in Lib/test): reperf.py (regular expression benchmark),
+sortperf.py (list sorting benchmark), test_MimeWriter.py (test case
+for the MimeWriter module).
+
+- Generalized test/regrtest.py so that it is useful for testing other
+packages.
+
+- The ihooks.py module now understands package imports.
+
+- In code.py, add a class that subsumes Fredrik Lundh's
+PythonInterpreter class.  The interact() function now uses this.
+
+- In rlcompleter.py, in completer(), return None instead of raising an
+IndexError when there are no more completions left.
+
+- Fixed the marshal module to test for certain common kinds of invalid
+input.  (It's still not foolproof!)
+
+- In the operator module, add an alias (now the preferred name)
+"contains" for "sequenceincludes".
+
+String Services
+---------------
+
+- In the string and strop modules, in the replace() function, treat an
+empty pattern as an error (since it's not clear what was meant!).
+
+- Some speedups to re.py, especially the string substitution and split
+functions.  Also added new function/method findall(), to find all
+occurrences of a given substring.
+
+- In cStringIO, add better argument type checking and support the
+readonly 'closed' attribute (like regular files).
+
+- In the struct module, unsigned 1-2 byte sized formats no longer
+result in long integer values.
+
+Miscellaneous services
+----------------------
+
+- In whrandom.py, added new method and function randrange(), same as
+choice(range(start, stop, step)) but faster.  This addresses the
+problem that randint() was accidentally defined as taking an inclusive
+range.  Also, randint(a, b) is now redefined as randrange(a, b+1),
+adding extra range and type checking to its arguments!
+
+- Add some semi-thread-safety to random.gauss() (it used to be able to 
+crash when invoked from separate threads; now the worst it can do is
+give a duplicate result occasionally).
+
+- Some restructuring and generalization done to cmd.py.
+
+- Major upgrade to ConfigParser.py; converted to using 're', added new 
+exceptions, support underscore in section header and option name.  No
+longer add 'name' option to every section; instead, add '__name__'.
+
+- In getpass.py, don't use raw_input() to ask for the password -- we
+don't want it to show up in the readline history!  Also don't catch
+interrupts (the try-finally already does all necessary cleanup).
+
+Generic OS Services
+-------------------
+
+- New functions in os.py: makedirs(), removedirs(), renames().  New
+variable: linesep (the line separator as found in binary files,
+i.e. '\n' on Unix, '\r\n' on DOS/Windows, '\r' on Mac.  Do *not* use
+this with files opened in (default) text mode; the line separator used
+will always be '\n'!
+
+- Changes to the 'os.path' submodule of os.py: added getsize(),
+getmtime(), getatime() -- these fetch the most popular items from the
+stat return tuple.
+
+- In the time module, add strptime(), if it exists.  (This parses a
+time according to a format -- the inverse of strftime().)  Also,
+remove the call to mktime() from strftime() -- it messed up the
+formatting of some non-local times.
+
+- In the socket module, added a new function gethostbyname_ex().
+Also, don't use #ifdef to test for some symbols that are enums on some
+platforms (and should exist everywhere).
+
+Optional OS Services
+--------------------
+
+- Some fixes to gzip.py.  In particular, the readlines() method now
+returns the lines *with* trailing newline characters, like readlines()
+of regular file objects.  Also, it didn't work together with cPickle;
+fixed that.
+
+- In whichdb.py, support byte-swapped dbhash (bsddb) files.
+
+- In anydbm.py, look at the type of an existing database to determine
+which module to use to open it.  (The anydbm.error exception is now a
+tuple.)
+
+Unix Services
+-------------
+
+- In the termios module, in tcsetattr(), initialize the structure vy
+calling tcgetattr().
+
+- Added some of the "wait status inspection" macros as functions to
+the posix module (and thus to the os module): WEXITSTATUS(),
+WIFEXITED(), WIFSIGNALED(), WIFSTOPPED(), WSTOPSIG(), WTERMSIG().
+
+- In the syslog module, make the default facility more intuitive
+(matching the docs).
+
+Debugger
+--------
+
+- In pdb.py, support for setting breaks on files/modules that haven't
+been loaded yet.
+
+Internet Protocols and Support
+------------------------------
+
+- Changes in urllib.py; sped up unquote() and quote().  Fixed an
+obscure bug in quote_plus().  Added urlencode(dict) -- convenience
+function for sending a POST request with urlopen().  Use the getpass
+module to ask for a password.  Rewrote the (test) main program so that
+when used as a script, it can retrieve one or more URLs to stdout.
+Use -t to run the self-test.  Made the proxy code work again.
+
+- In cgi.py, treat "HEAD" the same as "GET", so that CGI scripts don't
+fail when someone asks for their HEAD.  Also, for POST, set the
+default content-type to application/x-www-form-urlencoded.  Also, in
+FieldStorage.__init__(), when method='GET', always get the query
+string from environ['QUERY_STRING'] or sys.argv[1] -- ignore an
+explicitly passed in fp.
+
+- The smtplib.py module now supports ESMTP and has improved standard
+compliance, for picky servers.
+
+- Improved imaplib.py.
+
+- Fixed UDP support in SocketServer.py (it never worked).
+
+- Fixed a small bug in CGIHTTPServer.py.
+
+Internet Data handling
+----------------------
+
+- In rfc822.py, add a new class AddressList.  Also support a new
+overridable method, isheader().  Also add a get() method similar to
+dictionaries (and make getheader() an alias for it).  Also, be smarter
+about seekable (test whether fp.tell() works) and test for presence of
+unread() method before trying seeks.
+
+- In sgmllib.py, restore the call to report_unbalanced() that was lost
+long ago.  Also some other improvements: handle <? processing
+instructions >, allow . and - in entity names, and allow \r\n as line
+separator.
+
+- Some restructuring and generalization done to multifile.py; support
+a 'seekable' flag.
+
+Restricted Execution
+--------------------
+
+- Improvements to rexec.py: package support; support a (minimal)
+sys.exc_info().  Also made the (test) main program a bit fancier (you
+can now use it to run arbitrary Python scripts in restricted mode).
+
+Tkinter
+-------
+
+- On Unix, Tkinter can now safely be used from a multi-threaded
+application.  (Formerly, no threads would make progress while
+Tkinter's mainloop() was active, because it didn't release the Python
+interpreter lock.)  Unfortunately, on Windows, threads other than the
+main thread should not call update() or update_idletasks() because
+this will deadlock the application.
+
+- An interactive interpreter that uses readline and Tkinter no longer
+uses up all available CPU time.
+
+- Even if readline is not used, Tk windows created in an interactive
+interpreter now get continuously updated.  (This even works in Windows
+as long as you don't hit a key.)
+
+- New demos in Demo/tkinter/guido/: brownian.py, redemo.py, switch.py.
+
+- No longer register Tcl_finalize() as a low-level exit handler.  It
+may call back into Python, and that's a bad idea.
+
+- Allow binding of Tcl commands (given as a string).
+
+- Some minor speedups; replace explicitly coded getint() with int() in
+most places.
+
+- In FileDialog.py, remember the directory of the selected file, if
+given.
+
+- Change the names of all methods in the Wm class: they are now
+wm_title(), etc.  The old names (title() etc.) are still defined as
+aliases.
+
+- Add a new method of interpreter objects, interpaddr().  This returns
+the address of the Tcl interpreter object, as an integer.  Not very
+useful for the Python programmer, but this can be called by another C
+extension that needs to make calls into the Tcl/Tk C API and needs to
+get the address of the Tcl interpreter object.  A simple cast of the
+return value to (Tcl_Interp *) will do the trick.
+
+Windows General
+---------------
+
+- Don't insist on proper case for module source files if the filename
+is all uppercase (e.g. FOO.PY now matches foo; but FOO.py still
+doesn't).  This should address problems with this feature on
+oldfashioned filesystems (Novell servers?).
+
+Windows Library
+---------------
+
+- os.environ is now all uppercase, but accesses are case insensitive,
+and the putenv() calls made as a side effect of changing os.environ
+are case preserving.
+
+- Removed samefile(), sameopenfile(), samestat() from os.path (aka
+ntpath.py) -- these cannot be made to work reliably (at least I
+wouldn't know how).
+
+- Fixed os.pipe() so that it returns file descriptors acceptable to
+os.read() and os.write() (like it does on Unix), rather than Windows
+file handles.
+
+- Added a table of WSA error codes to socket.py.
+
+- In the select module, put the (huge) file descriptor arrays on the
+heap.
+
+- The getpass module now raises KeyboardInterrupt when it sees ^C.
+
+- In mailbox.py, fix tell/seek when using files opened in text mode.
+
+- In rfc822.py, fix tell/seek when using files opened in text mode.
+
+- In the msvcrt extension module, release the interpreter lock for
+calls that may block: _locking(), _getch(), _getche().  Also fix a
+bogus error return when open_osfhandle() doesn't have the right
+argument list.
+
+Windows Installer
+-----------------
+
+- The registry key used is now "1.5" instead of "1.5.x" -- so future
+versions of 1.5 and Mark Hammond's win32all installer don't need to be 
+resynchronized.
+
+Windows Tools
+-------------
+
+- Several improvements to freeze specifically for Windows.
+
+Windows Build Procedure
+-----------------------
+
+- The VC++ project files and the WISE installer have been moved to the
+PCbuild subdirectory, so they are distributed in the same subdirectory
+where they must be used.  This avoids confusion.
+
+- New project files for Windows 3.1 port by Jim Ahlstrom.
+
+- Got rid of the obsolete subdirectory PC/setup_nt/.
+
+- The projects now use distinct filenames for the .exe, .dll, .lib and
+.pyd files built in debug mode (by appending "_d" to the base name,
+before the extension).  This makes it easier to switch between the two
+and get the right versions.  There's a pragma in config.h that directs
+the linker to include the appropriate .lib file (so python15.lib no
+longer needs to be explicit in your project).
+
+- The installer now installs more files (e.g. config.h).  The idea is
+that you shouldn't need the source distribution if you want build your
+own extensions in C or C++.
+
+Tools and Demos
+---------------
+
+- New script nm2def.py by Marc-Andre Lemburg, to construct
+PC/python_nt.def automatically (some hand editing still required).
+
+- New tool ndiff.py: Tim Peters' text diffing tool.
+
+- Various and sundry improvements to the freeze script.
+
+- The script texi2html.py (which was part of the Doc tree but is no
+longer used there) has been moved to the Tools/scripts subdirectory.
+
+- Some generalizations in the webchecker code.  There's now a
+primnitive gui for websucker.py: wsgui.py.  (In Tools/webchecker/.)
+
+- The ftpmirror.py script now handles symbolic links properly, and
+also files with multiple spaces in their names.
+
+- The 1.5.1 tabnanny.py suffers an assert error if fed a script whose
+last line is both indented and lacks a newline.  This is now fixed.
+
+Python/C API
+------------
+
+- Added missing prototypes for PyEval_CallFunction() and
+PyEval_CallMethod().
+
+- New macro PyList_SET_ITEM().
+
+- New macros to access object members for PyFunction, PyCFunction
+objects.
+
+- New APIs PyImport_AppendInittab() an PyImport_ExtendInittab() to
+dynamically add one or many entries to the table of built-in modules.
+
+- New macro Py_InitModule3(name, methods, doc) which calls
+Py_InitModule4() with appropriate arguments.  (The -4 variant requires 
+you to pass an obscure version number constant which is always the same.)
+
+- New APIs PySys_WriteStdout() and PySys_WriteStderr() to write to
+sys.stdout or sys.stderr using a printf-like interface.  (Used in
+_tkinter.c, for example.)
+
+- New APIs for conversion between Python longs and C 'long long' if
+your compiler supports it.
+
+- PySequence_In() is now called PySequence_Contains().
+(PySequence_In() is still supported for b/w compatibility; it is
+declared obsolete because its argument order is confusing.)
+
+- PyDict_GetItem() and PyDict_GetItemString() are changed so that they
+*never* raise an exception -- (even if the hash() fails, simply clear
+the error).  This was necessary because there is lots of code out
+there that already assumes this.
+
+- Changes to PySequence_Tuple() and PySequence_List() to use the
+length of a sequence only as a hint -- if an IndexError happens
+earlier, take that.  (Formerly, this was considered an error.)
+
+- Reformatted abstract.c to give it a more familiar "look" and fixed
+many error checking bugs.
+
+- Add NULL pointer checks to all calls of a C function through a type
+object and extensions (e.g. nb_add).
+
+- The code that initializes sys.path now calls Py_GetPythonHome()
+instead of getenv("PYTHONHOME").  This, together with the new API
+Py_SetPythonHome(), makes it easier for embedding applications to
+change the notion of Python's "home" directory (where the libraries
+etc. are sought).
+
+- Fixed a very old bug in the parsing of "O?" format specifiers.
+
+
+======================================================================
+
+
+========================================
+==> Release 1.5.1 (October 31, 1998) <==
+========================================
+
+From 1.5 to 1.5.1
+=================
+
+General
+-------
+
+- The documentation is now unbundled.  It has also been extensively
+modified (mostly to implement a new and more uniform formatting
+style).  We figure that most people will prefer to download one of the
+preformatted documentation sets (HTML, PostScript or PDF) and that
+only a minority have a need for the LaTeX or FrameMaker sources.  Of
+course, the unbundled documentation sources still released -- just not
+in the same archive file, and perhaps not on the same date.
+
+- All bugs noted on the errors page (and many unnoted) are fixed.  All
+new bugs take their places.
+
+- No longer a core dump when attempting to print (or repr(), or str())
+a list or dictionary that contains an instance of itself; instead, the
+recursive entry is printed as [...] or {...}.  See Py_ReprEnter() and
+Py_ReprLeave() below.  Comparisons of such objects still go beserk,
+since this requires a different kind of fix; fortunately, this is a
+less common scenario in practice.
+
+Syntax change
+-------------
+
+- The raise statement can now be used without arguments, to re-raise 
+a previously set exception.  This should be used after catching an
+exception with an except clause only, either in the except clause or
+later in the same function.
+
+Import and module handling
+--------------------------
+
+- The implementation of import has changed to use a mutex (when
+threading is supported).  This means that when two threads
+simultaneously import the same module, the import statements are
+serialized.  Recursive imports are not affected.
+
+- Rewrote the finalization code almost completely, to be much more
+careful with the order in which modules are destroyed.  Destructors
+will now generally be able to reference built-in names such as None
+without trouble.
+
+- Case-insensitive platforms such as Mac and Windows require the case
+of a module's filename to match the case of the module name as
+specified in the import statement (see below).
+
+- The code for figuring out the default path now distinguishes between
+files, modules, executable files, and directories.  When expecting a
+module, we also look for the .pyc or .pyo file.
+
+Parser/tokenizer changes
+------------------------
+
+- The tokenizer can now warn you when your source code mixes tabs and
+spaces for indentation in a manner that depends on how much a tab is
+worth in spaces.  Use "python -t" or "python -v" to enable this
+option.  Use "python -tt" to turn the warnings into errors.  (See also
+tabnanny.py and tabpolice.py below.)
+
+- Return unsigned characters from tok_nextc(), so '\377' isn't
+mistaken for an EOF character.
+
+- Fixed two pernicious bugs in the tokenizer that only affected AIX.
+One was actually a general bug that was triggered by AIX's smaller I/O
+buffer size.  The other was a bug in the AIX optimizer's loop
+unrolling code; swapping two statements made the problem go away.
+
+Tools, demos and miscellaneous files
+------------------------------------
+
+- There's a new version of Misc/python-mode.el (the Emacs mode for
+Python) which is much smarter about guessing the indentation style
+used in a particular file.  Lots of other cool features too!
+
+- There are two new tools in Tools/scripts: tabnanny.py and
+tabpolice.py, implementing two different ways of checking whether a
+file uses indentation in a way that is sensitive to the interpretation
+of a tab.  The preferred module is tabnanny.py (by Tim Peters).
+
+- Some new demo programs:
+
+	Demo/tkinter/guido/paint.py -- Dave Mitchell
+	Demo/sockets/unixserver.py -- Piet van Oostrum
+	
+
+- Much better freeze support.  The freeze script can now freeze
+hierarchical module names (with a corresponding change to import.c),
+and has a few extra options (e.g. to suppress freezing specific
+modules).  It also does much more on Windows NT.
+
+- Version 1.0 of the faq wizard is included (only very small changes
+since version 0.9.0).
+
+- New feature for the ftpmirror script: when removing local files
+(i.e., only when -r is used), do a recursive delete.
+
+Configuring and building Python
+-------------------------------
+
+- Get rid of the check for -linet -- recent Sequent Dynix systems don't
+need this any more and apparently it screws up their configuration.
+
+- Some changes because gcc on SGI doesn't support '-all'.
+
+- Changed the build rules to use $(LIBRARY) instead of
+  -L.. -lpython$(VERSION)
+since the latter trips up the SunOS 4.1.x linker (sigh).
+
+- Fix the bug where the '# dgux is broken' comment in the Makefile
+tripped over Make on some platforms.
+
+- Changes for AIX: install the python.exp file; properly use
+$(srcdir); the makexp_aix script now removes C++ entries of the form
+Class::method.
+
+- Deleted some Makefile targets only used by the (long obsolete)
+gMakefile hacks.
+
+Extension modules
+-----------------
+
+- Performance and threading improvements to the socket and bsddb
+modules, by Christopher Lindblad of Infoseek.
+
+- Added operator.__not__ and operator.not_.
+
+- In the thread module, when a thread exits due to an unhandled
+exception, don't store the exception information in sys.last_*; it
+prevents proper calling of destructors of local variables.
+
+- Fixed a number of small bugs in the cPickle module.
+
+- Changed find() and rfind() in the strop module so that
+find("x","",2) returns -1, matching the implementation in string.py.
+
+- In the time module, be more careful with the result of ctime(), and
+test for HAVE_MKTIME before usinmg mktime().
+
+- Doc strings contributed by Mitch Chapman to the termios, pwd, gdbm
+modules.
+
+- Added the LOG_SYSLOG constant to the syslog module, if defined.
+
+Standard library modules
+------------------------
+
+- All standard library modules have been converted to an indentation
+style using either only tabs or only spaces -- never a mixture -- if
+they weren't already consistent according to tabnanny.  This means
+that the new -t option (see above) won't complain about standard
+library modules.
+
+- New standard library modules:
+
+	threading -- GvR and the thread-sig
+		Java style thread objects -- USE THIS!!!
+
+	getpass -- Piers Lauder
+		simple utilities to prompt for a password and to
+		retrieve the current username
+
+	imaplib -- Piers Lauder
+		interface for the IMAP4 protocol
+
+	poplib -- David Ascher, Piers Lauder
+		interface for the POP3 protocol
+
+	smtplib -- Dragon De Monsyne
+		interface for the SMTP protocol
+
+- Some obsolete modules moved to a separate directory (Lib/lib-old)
+which is *not* in the default module search path:
+
+	Para
+	addpack
+	codehack
+	fmt
+	lockfile
+	newdir
+	ni
+	rand
+	tb
+
+- New version of the PCRE code (Perl Compatible Regular Expressions --
+the re module and the supporting pcre extension) by Andrew Kuchling.
+Incompatible new feature in re.sub(): the handling of escapes in the
+replacement string has changed.
+
+- Interface change in the copy module: a __deepcopy__ method is now
+called with the memo dictionary as an argument.
+
+- Feature change in the tokenize module: differentiate between NEWLINE
+token (an official newline) and NL token (a newline that the grammar
+ignores).
+
+- Several bugfixes to the urllib module.  It is now truly thread-safe,
+and several bugs and a portability problem have been fixed.  New
+features, all due to Sjoerd Mullender: When creating a temporary file,
+it gives it an appropriate suffix.  Support the "data:" URL scheme.
+The open() method uses the tempcache.
+
+- New version of the xmllib module (this time with a test suite!) by
+Sjoerd Mullender.
+
+- Added debugging code to the telnetlib module, to be able to trace
+the actual traffic.
+
+- In the rfc822 module, added support for deleting a header (still no
+support for adding headers, though).  Also fixed a bug where an
+illegal address would cause a crash in getrouteaddr(), fixed a
+sign reversal in mktime_tz(), and use the local timezone by default
+(the latter two due to Bill van Melle).
+
+- The normpath() function in the dospath and ntpath modules no longer
+does case normalization -- for that, use the separate function
+normcase() (which always existed); normcase() has been sped up and
+fixed (it was the cause of a crash in Mark Hammond's installer in
+certain locales).
+
+- New command supported by the ftplib module: rmd(); also fixed some
+minor bugs.
+
+- The profile module now uses a different timer function by default -- 
+time.clock() is generally better than os.times().  This makes it work
+better on Windows NT, too.
+
+- The tempfile module now recovers when os.getcwd() raises an
+exception.
+
+- Fixed some bugs in the random module; gauss() was subtly wrong, and
+vonmisesvariate() should return a full circle.  Courtesy Mike Miller,
+Lambert Meertens (gauss()), and Magnus Kessler (vonmisesvariate()).
+
+- Better default seed in the whrandom module, courtesy Andrew Kuchling.
+
+- Fix slow close() in shelve module.
+
+- The Unix mailbox class in the mailbox module is now more robust when
+a line begins with the string "From " but is definitely not the start
+of a new message.  The pattern used can be changed by overriding a
+method or class variable.
+
+- Added a rmtree() function to the copy module.
+
+- Fixed several typos in the pickle module.  Also fixed problems when
+unpickling in restricted execution environments.
+
+- Added docstrings and fixed a typo in the py_compile and compileall
+modules.  At Mark Hammond's repeated request, py_compile now append a
+newline to the source if it needs one.  Both modules support an extra
+parameter to specify the purported source filename (to be used in
+error messages).
+
+- Some performance tweaks by Jeremy Hylton to the gzip module.
+
+- Fixed a bug in the merge order of dictionaries in the ConfigParser
+module.  Courtesy Barry Warsaw.
+
+- In the multifile module, support the optional second parameter to
+seek() when possible.
+
+- Several fixes to the gopherlib module by Lars Marius Garshol.  Also, 
+urlparse now correctly handles Gopher URLs with query strings.
+
+- Fixed a tiny bug in format_exception() in the traceback module.
+Also rewrite tb_lineno() to be compatible with JPython (and not
+disturb the current exception!); by Jim Hugunin.
+
+- The httplib module is more robust when servers send a short response 
+-- courtesy Tim O'Malley.
+
+Tkinter and friends
+-------------------
+
+- Various typos and bugs fixed.
+
+- New module Tkdnd implements a drag-and-drop protocol (within one
+application only).
+
+- The event_*() widget methods have been restructured slightly -- they
+no longer use the default root.
+
+- The interfaces for the bind*() and unbind() widget methods have been
+redesigned; the bind*() methods now return the name of the Tcl command 
+created for the callback, and this can be passed as a optional
+argument to unbind() in order to delete the command (normally, such
+commands are automatically unbound when the widget is destroyed, but
+for some applications this isn't enough).
+
+- Variable objects now have trace methods to interface to Tcl's
+variable tracing facilities.
+
+- Image objects now have an optional keyword argument, 'master', to
+specify a widget (tree) to which they belong.  The image_names() and
+image_types() calls are now also widget methods.
+
+- There's a new global call, Tkinter.NoDefaultRoot(), which disables
+all use of the default root by the Tkinter library.  This is useful to
+debug applications that are in the process of being converted from
+relying on the default root to explicit specification of the root
+widget.
+
+- The 'exit' command is deleted from the Tcl interpreter, since it
+provided a loophole by which one could (accidentally) exit the Python
+interpreter without invoking any cleanup code.
+
+- Tcl_Finalize() is now registered as a Python low-level exit handle,
+so Tcl will be finalized when Python exits.
+
+The Python/C API
+----------------
+
+- New function PyThreadState_GetDict() returns a per-thread dictionary
+intended for storing thread-local global variables.
+
+- New functions Py_ReprEnter() and Py_ReprLeave() use the per-thread
+dictionary to allow recursive container types to detect recursion in
+their repr(), str() and print implementations.
+
+- New function PyObject_Not(x) calculates (not x) according to Python's 
+standard rules (basically, it negates the outcome PyObject_IsTrue(x).
+
+- New function _PyModule_Clear(), which clears a module's dictionary
+carefully without removing the __builtins__ entry.  This is implied
+when a module object is deallocated (this used to clear the dictionary
+completely).
+
+- New function PyImport_ExecCodeModuleEx(), which extends
+PyImport_ExecCodeModule() by adding an extra parameter to pass it the
+true file.
+
+- New functions Py_GetPythonHome() and Py_SetPythonHome(), intended to
+allow embedded applications to force a different value for PYTHONHOME.
+
+- New global flag Py_FrozenFlag is set when this is a "frozen" Python
+binary; it suppresses warnings about not being able to find the
+standard library directories.
+
+- New global flag Py_TabcheckFlag is incremented by the -t option and
+causes the tokenizer to issue warnings or errors about inconsistent
+mixing of tabs and spaces for indentation.
+
+Miscellaneous minor changes and bug fixes
+-----------------------------------------
+
+- Improved the error message when an attribute of an attribute-less
+object is requested -- include the name of the attribute and the type
+of the object in the message.
+
+- Sped up int(), long(), float() a bit.
+
+- Fixed a bug in list.sort() that would occasionally dump core.
+
+- Fixed a bug in PyNumber_Power() that caused numeric arrays to fail
+when taken tothe real power.
+
+- Fixed a number of bugs in the file reading code, at least one of
+which could cause a core dump on NT, and one of which would
+occasionally cause file.read() to return less than the full contents
+of the file.
+
+- Performance hack by Vladimir Marangozov for stack frame creation.
+
+- Make sure setvbuf() isn't used unless HAVE_SETVBUF is defined.
+
+Windows 95/NT
+-------------
+
+- The .lib files are now part of the distribution; they are collected
+in the subdirectory "libs" of the installation directory.
+
+- The extension modules (.pyd files) are now collected in a separate
+subdirectory of the installation directory named "DLLs".
+
+- The case of a module's filename must now match the case of the
+module name as specified in the import statement.  This is an
+experimental feature -- if it turns out to break in too many
+situations, it will be removed (or disabled by default) in the future.
+It can be disabled on a per-case basis by setting the environment
+variable PYTHONCASEOK (to any value).
+
+
+======================================================================
+
+
+=====================================
+==> Release 1.5 (January 3, 1998) <==
+=====================================
+
+
+From 1.5b2 to 1.5
+=================
+
+- Newly documentated module: BaseHTTPServer.py, thanks to Greg Stein.
+
+- Added doc strings to string.py, stropmodule.c, structmodule.c,
+thanks to Charles Waldman.
+
+- Many nits fixed in the manuals, thanks to Fred Drake and many others
+(especially Rob Hooft and Andrew Kuchling).  The HTML version now uses
+HTML markup instead of inline GIF images for tables; only two images
+are left (for obsure bits of math).  The index of the HTML version has
+also been much improved.  Finally, it is once again possible to
+generate an Emacs info file from the library manual (but I don't
+commit to supporting this in future versions).
+
+- New module: telnetlib.py (a simple telnet client library).
+
+- New tool: Tools/versioncheck/, by Jack Jansen.
+
+- Ported zlibmodule.c and bsddbmodule.c to NT; The project file for MS
+DevStudio 5.0 now includes new subprojects to build the zlib and bsddb
+extension modules.
+
+- Many small changes again to Tkinter.py -- mostly bugfixes and adding
+missing routines.  Thanks to Greg McFarlane for reporting a bunch of
+problems and proofreading my fixes.
+
+- The re module and its documentation are up to date with the latest
+version released to the string-sig (Dec. 22).
+
+- Stop test_grp.py from failing when the /etc/group file is empty
+(yes, this happens!).
+
+- Fix bug in integer conversion (mystrtoul.c) that caused
+4294967296==0 to be true!
+
+- The VC++ 4.2 project file should be complete again.
+
+- In tempfile.py, use a better template on NT, and add a new optional
+argument "suffix" with default "" to specify a specific extension for
+the temporary filename (needed sometimes on NT but perhaps also handy
+elsewhere).
+
+- Fixed some bugs in the FAQ wizard, and converted it to use re
+instead of regex.
+
+- Fixed a mysteriously undetected error in dlmodule.c (it was using a
+totally bogus routine name to raise an exception).
+
+- Fixed bug in import.c which wasn't using the new "dos-8x3" name yet.
+
+- Hopefully harmless changes to the build process to support shared
+libraries on DG/UX.  This adds a target to create
+libpython$(VERSION).so; however this target is *only* for DG/UX.
+
+- Fixed a bug in the new format string error checking in getargs.c.
+
+- A simple fix for infinite recursion when printing __builtins__:
+reset '_' to None before printing and set it to the printed variable
+*after* printing (and only when printing is successful).
+
+- Fixed lib-tk/SimpleDialog.py to keep the dialog visible even if the
+parent window is not (Skip Montanaro).
+
+- Fixed the two most annoying problems with ftp URLs in
+urllib.urlopen(); an empty file now correctly raises an error, and it
+is no longer required to explicitly close the returned "file" object
+before opening another ftp URL to the same host and directory.
+
+
+======================================================================
+
+
+From 1.5b1 to 1.5b2
+===================
+
+- Fixed a bug in cPickle.c that caused it to crash right away because
+the version string had a different format.
+
+- Changes in pickle.py and cPickle.c: when unpickling an instance of a
+class that doesn't define the __getinitargs__() method, the __init__()
+constructor is no longer called.  This makes a much larger group of
+classes picklable by default, but may occasionally change semantics.
+To force calling __init__() on unpickling, define a __getinitargs__()
+method.  Other changes too, in particular cPickle now handles classes
+defined in packages correctly.  The same change applies to copying
+instances with copy.py.  The cPickle.c changes and some pickle.py
+changes are courtesy Jim Fulton.
+
+- Locale support in he "re" (Perl regular expressions) module.  Use 
+the flag re.L (or re.LOCALE) to enable locale-specific matching
+rules for \w and \b.  The in-line syntax for this flag is (?L).
+
+- The built-in function isinstance(x, y) now also succeeds when y is
+a type object and type(x) is y.
+
+- repr() and str() of class and instance objects now reflect the
+package/module in which the class is defined.
+
+- Module "ni" has been removed.  (If you really need it, it's been
+renamed to "ni1".  Let me know if this causes any problems for you.
+Package authors are encouraged to write __init__.py files that
+support both ni and 1.5 package support, so the same version can be
+used with Python 1.4 as well as 1.5.)
+
+- The thread module is now automatically included when threads are
+configured.  (You must remove it from your existing Setup file,
+since it is now in its own Setup.thread file.)
+
+- New command line option "-x" to skip the first line of the script;
+handy to make executable scripts on non-Unix platforms.
+
+- In importdl.c, add the RTLD_GLOBAL to the dlopen() flags.  I
+haven't checked how this affects things, but it should make symbols
+in one shared library available to the next one.
+
+- The Windows installer now installs in the "Program Files" folder on
+the proper volume by default.
+
+- The Windows configuration adds a new main program, "pythonw", and
+registers a new extension, ".pyw" that invokes this.  This is a
+pstandard Python interpreter that does not pop up a console window;
+handy for pure Tkinter applications.  All output to the original
+stdout and stderr is lost; reading from the original stdin yields
+EOF.  Also, both python.exe and pythonw.exe now have a pretty icon
+(a green snake in a box, courtesy Mark Hammond).
+
+- Lots of improvements to emacs-mode.el again.  See Barry's web page:
+http://www.python.org/ftp/emacs/pmdetails.html.
+
+- Lots of improvements and additions to the library reference manual;
+many by Fred Drake.
+
+- Doc strings for the following modules: rfc822.py, posixpath.py,
+ntpath.py, httplib.py.  Thanks to Mitch Chapman and Charles Waldman.
+
+- Some more regression testing.
+
+- An optional 4th (maxsplit) argument to strop.replace().
+
+- Fixed handling of maxsplit in string.splitfields().
+
+- Tweaked os.environ so it can be pickled and copied.
+
+- The portability problems caused by indented preprocessor commands
+and C++ style comments should be gone now.
+
+- In random.py, added Pareto and Weibull distributions.
+
+- The crypt module is now disabled in Modules/Setup.in by default; it
+is rarely needed and causes errors on some systems where users often
+don't know how to deal with those.
+
+- Some improvements to the _tkinter build line suggested by Case Roole.
+
+- A full suite of platform specific files for NetBSD 1.x, submitted by 
+Anders Andersen.
+
+- New Solaris specific header STROPTS.py.
+
+- Moved a confusing occurrence of *shared* from the comments in
+Modules/Setup.in (people would enable this one instead of the real
+one, and get disappointing results).
+
+- Changed the default mode for directories to be group-writable when
+the installation process creates them.
+
+- Check for pthread support in "-l_r" for FreeBSD/NetBSD, and support
+shared libraries for both.
+
+- Support FreeBSD and NetBSD in posixfile.py.
+
+- Support for the "event" command, new in Tk 4.2.  By Case Roole.
+
+- Add Tix_SafeInit() support to tkappinit.c.
+
+- Various bugs fixed in "re.py" and "pcre.c".
+
+- Fixed a bug (broken use of the syntax table) in the old "regexpr.c".
+
+- In frozenmain.c, stdin is made unbuffered too when PYTHONUNBUFFERED
+is set.
+
+- Provide default blocksize for retrbinary in ftplib.py (Skip
+Montanaro).
+
+- In NT, pick the username up from different places in user.py (Jeff
+Bauer).
+
+- Patch to urlparse.urljoin() for ".." and "..#1", Marc Lemburg.
+
+- Many small improvements to Jeff Rush' OS/2 support.
+
+- ospath.py is gone; it's been obsolete for so many years now...
+
+- The reference manual is now set up to prepare better HTML (still
+using webmaker, alas).
+
+- Add special handling to /Tools/freeze for Python modules that are
+imported implicitly by the Python runtime: 'site' and 'exceptions'.
+
+- Tools/faqwiz 0.8.3 -- add an option to suppress URL processing
+inside <PRE>, by "Scott".
+
+- Added ConfigParser.py, a generic parser for sectioned configuration
+files.
+
+- In _localemodule.c, LC_MESSAGES is not always defined; put it
+between #ifdefs.
+
+- Typo in resource.c: RUSAGE_CHILDERN -> RUSAGE_CHILDREN.
+
+- Demo/scripts/newslist.py: Fix the way the version number is gotten
+out of the RCS revision.
+
+- PyArg_Parse[Tuple] now explicitly check for bad characters at the
+end of the format string.
+
+- Revamped PC/example_nt to support VC++ 5.x.
+
+- <listobject>.sort() now uses a modified quicksort by Raymund Galvin,
+after studying the GNU libg++ quicksort.  This should be much faster
+if there are lots of duplicates, and otherwise at least as good.
+
+- Added "uue" as an alias for "uuencode" to mimetools.py.  (Hm, the
+uudecode bug where it complaints about trailing garbage is still there 
+:-( ).
+
+- pickle.py requires integers in text mode to be in decimal notation
+(it used to accept octal and hex, even though it would only generate
+decimal numbers).
+
+- In string.atof(), don't fail when the "re" module is unavailable.
+Plug the ensueing security leak by supplying an empty __builtins__
+directory to eval().
+
+- A bunch of small fixes and improvements to Tkinter.py.
+
+- Fixed a buffer overrun in PC/getpathp.c.
+
+
+======================================================================
+
+
+From 1.5a4 to 1.5b1
+===================
+
+- The Windows NT/95 installer now includes full HTML of all manuals.
+It also has a checkbox that lets you decide whether to install the
+interpreter and library.  The WISE installer script for the installer
+is included in the source tree as PC/python15.wse, and so are the
+icons used for Python files.  The config.c file for the Windows build
+is now complete with the pcre module.
+
+- sys.ps1 and sys.ps2 can now arbitrary objects; their str() is
+evaluated for the prompt.
+
+- The reference manual is brought up to date (more or less -- it still
+needs work, e.g. in the area of package import).
+
+- The icons used by latex2html are now included in the Doc
+subdirectory (mostly so that tarring up the HTML files can be fully
+automated).  A simple index.html is also added to Doc (it only works
+after you have successfully run latex2html).
+
+- For all you would-be proselytizers out there: a new version of
+Misc/BLURB describes Python more concisely, and Misc/comparisons
+compares Python to several other languages.  Misc/BLURB.WINDOWS
+contains a blurb specifically aimed at Windows programmers (by Mark
+Hammond).
+
+- A new version of the Python mode for Emacs is included as
+Misc/python-mode.el.  There are too many new features to list here.
+See http://www.python.org/ftp/emacs/pmdetails.html for more info.
+
+- New module fileinput makes iterating over the lines of a list of
+files easier.  (This still needs some more thinking to make it more
+extensible.)
+
+- There's full OS/2 support, courtesy Jeff Rush.  To build the OS/2
+version, see PC/readme.txt and PC/os2vacpp.  This is for IBM's Visual
+Age C++ compiler.  I expect that Jeff will also provide a binary
+release for this platform.
+
+- On Linux, the configure script now uses '-Xlinker -export-dynamic'
+instead of '-rdynamic' to link the main program so that it exports its
+symbols to shared libraries it loads dynamically.  I hope this doesn't
+break on older Linux versions; it is needed for mklinux and appears to
+work on Linux 2.0.30.
+
+- Some Tkinter resstructuring: the geometry methods that apply to a
+master are now properly usable on toplevel master widgets.  There's a
+new (internal) widget class, BaseWidget.  New, longer "official" names
+for the geometry manager methods have been added,
+e.g. "grid_columnconfigure()" instead of "columnconfigure()".  The old
+shorter names still work, and where there's ambiguity, pack wins over
+place wins over grid.  Also, the bind_class method now returns its
+value.
+
+- New, RFC-822 conformant parsing of email addresses and address lists
+in the rfc822 module, courtesy Ben Escoto.
+
+- New, revamped tkappinit.c with support for popular packages (PIL,
+TIX, BLT, TOGL).  For the last three, you need to execute the Tcl
+command "load {} Tix" (or Blt, or Togl) to gain access to them.
+The Modules/Setup line for the _tkinter module has been rewritten
+using the cool line-breaking feature of most Bourne shells.
+
+- New socket method connect_ex() returns the error code from connect()
+instead of raising an exception on errors; this makes the logic
+required for asynchronous connects simpler and more efficient.
+
+- New "locale" module with (still experimental) interface to the
+standard C library locale interface, courtesy Martin von Loewis.  This
+does not repeat my mistake in 1.5a4 of always calling
+setlocale(LC_ALL, "").  In fact, we've pretty much decided that
+Python's standard numerical formatting operations should always use
+the conventions for the C locale; the locale module contains utility
+functions to format numbers according to the user specified locale.
+(All this is accomplished by an explicit call to setlocale(LC_NUMERIC,
+"C") after locale-changing calls.)  See the library manual. (Alas, the
+promised changes to the "re" module for locale support have not been
+materialized yet.  If you care, volunteer!)
+
+- Memory leak plugged in Py_BuildValue when building a dictionary.
+
+- Shared modules can now live inside packages (hierarchical module
+namespaces).  No changes to the shared module itself are needed.
+
+- Improved policy for __builtins__: this is a module in __main__ and a
+dictionary everywhere else.
+
+- Python no longer catches SIGHUP and SIGTERM by default.  This was
+impossible to get right in the light of thread contexts.  If you want
+your program to clean up when a signal happens, use the signal module
+to set up your own signal handler.
+
+- New Python/C API PyNumber_CoerceEx() does not return an exception
+when no coercion is possible.  This is used to fix a problem where
+comparing incompatible numbers for equality would raise an exception
+rather than return false as in Python 1.4 -- it once again will return
+false.
+
+- The errno module is changed again -- the table of error messages
+(errorstr) is removed.  Instead, you can use os.strerror().  This
+removes redundance and a potential locale dependency.
+
+- New module xmllib, to parse XML files.  By Sjoerd Mullender.
+
+- New C API PyOS_AfterFork() is called after fork() in posixmodule.c.
+It resets the signal module's notion of what the current process ID
+and thread are, so that signal handlers will work after (and across)
+calls to os.fork().
+
+- Fixed most occurrences of fatal errors due to missing thread state.
+
+- For vgrind (a flexible source pretty printer) fans, there's a simple
+Python definition in Misc/vgrindefs, courtesy Neale Pickett.
+
+- Fixed memory leak in exec statement.
+
+- The test.pystone module has a new function, pystones(loops=LOOPS),
+which returns a (benchtime, stones) tuple.  The main() function now
+calls this and prints the report.
+
+- Package directories now *require* the presence of an __init__.py (or
+__init__.pyc) file before they are considered as packages.  This is
+done to prevent accidental subdirectories with common names from
+overriding modules with the same name.
+
+- Fixed some strange exceptions in __del__ methods in library modules
+(e.g. urllib).  This happens because the builtin names are already
+deleted by the time __del__ is called.  The solution (a hack, but it
+works) is to set some instance variables to 0 instead of None.
+
+- The table of built-in module initializers is replaced by a pointer
+variable.  This makes it possible to switch to a different table at
+run time, e.g. when a collection of modules is loaded from a shared
+library.  (No example code of how to do this is given, but it is
+possible.)  The table is still there of course, its name prefixed with
+an underscore and used to initialize the pointer.
+
+- The warning about a thread still having a frame now only happens in
+verbose mode.
+
+- Change the signal finialization so that it also resets the signal
+handlers.  After this has been called, our signal handlers are no
+longer active!
+
+- New version of tokenize.py (by Ka-Ping Yee) recognizes raw string
+literals.  There's now also a test fort this module.
+
+- The copy module now also uses __dict__.update(state) instead of
+going through individual attribute assignments, for class instances
+without a __setstate__ method.
+
+- New module reconvert translates old-style (regex module) regular
+expressions to new-style (re module, Perl-style) regular expressions.
+
+- Most modules that used to use the regex module now use the re
+module.  The grep module has a new pgrep() function which uses
+Perl-style regular expressions.
+
+- The (very old, backwards compatibility) regexp.py module has been
+deleted.
+
+- Restricted execution (rexec): added the pcre module (support for the
+re module) to the list of trusted extension modules.
+
+- New version of Jim Fulton's CObject object type, adds
+PyCObject_FromVoidPtrAndDesc() and PyCObject_GetDesc() APIs.
+
+- Some patches to Lee Busby's fpectl mods that accidentally didn't
+make it into 1.5a4.
+
+- In the string module, add an optional 4th argument to count(),
+matching find() etc.
+
+- Patch for the nntplib module by Charles Waldman to add optional user
+and password arguments to NNTP.__init__(), for nntp servers that need
+them.
+
+- The str() function for class objects now returns
+"modulename.classname" instead of returning the same as repr().
+
+- The parsing of \xXX escapes no longer relies on sscanf().
+
+- The "sharedmodules" subdirectory of the installation is renamed to
+"lib-dynload".  (You may have to edit your Modules/Setup file to fix
+this in an existing installation!)
+
+- Fixed Don Beaudry's mess-up with the OPT test in the configure
+script.  Certain SGI platforms will still issue a warning for each
+compile; there's not much I can do about this since the compiler's
+exit status doesn't indicate that I was using an obsolete option.
+
+- Fixed Barry's mess-up with {}.get(), and added test cases for it.
+
+- Shared libraries didn't quite work under AIX because of the change
+in status of the GNU readline interface.  Fix due to by Vladimir
+Marangozov.
+
+
+======================================================================
+
+
+From 1.5a3 to 1.5a4
+===================
+
+- faqwiz.py: version 0.8; Recognize https:// as URL; <html>...</html>
+feature; better install instructions; removed faqmain.py (which was an
+older version).
+
+- nntplib.py: Fixed some bugs reported by Lars Wirzenius (to Debian)
+about the treatment of lines starting with '.'.  Added a minimal test
+function.
+
+- struct module: ignore most whitespace in format strings.
+
+- urllib.py: close the socket and temp file in URLopener.retrieve() so
+that multiple retrievals using the same connection work.
+
+- All standard exceptions are now classes by default; use -X to make
+them strings (for backward compatibility only).
+
+- There's a new standard exception hierarchy, defined in the standard
+library module exceptions.py (which you never need to import
+explicitly).  See
+http://grail.cnri.reston.va.us/python/essays/stdexceptions.html for
+more info.
+
+- Three new C API functions:
+
+  - int PyErr_GivenExceptionMatches(obj1, obj2)
+
+    Returns 1 if obj1 and obj2 are the same object, or if obj1 is an
+    instance of type obj2, or of a class derived from obj2
+
+  - int PyErr_ExceptionMatches(obj)
+
+    Higher level wrapper around PyErr_GivenExceptionMatches() which uses
+    PyErr_Occurred() as obj1.  This will be the more commonly called
+    function.
+
+  - void PyErr_NormalizeException(typeptr, valptr, tbptr)
+
+    Normalizes exceptions, and places the normalized values in the
+    arguments.  If type is not a class, this does nothing.  If type is a
+    class, then it makes sure that value is an instance of the class by:
+
+    1. if instance is of the type, or a class derived from type, it does
+       nothing.
+
+    2. otherwise it instantiates the class, using the value as an
+       argument.  If value is None, it uses an empty arg tuple, and if
+       the value is a tuple, it uses just that.
+
+- Another new C API function: PyErr_NewException() creates a new
+exception class derived from Exception; when -X is given, it creates a
+new string exception.
+
+- core interpreter: remove the distinction between tuple and list
+unpacking; allow an arbitrary sequence on the right hand side of any
+unpack instruction.  (UNPACK_LIST and UNPACK_TUPLE now do the same
+thing, which should really be called UNPACK_SEQUENCE.)
+
+- classes: Allow assignments to an instance's __dict__ or __class__,
+so you can change ivars (including shared ivars -- shock horror) and
+change classes dynamically.  Also make the check on read-only
+attributes of classes less draconic -- only the specials names
+__dict__, __bases__, __name__ and __{get,set,del}attr__ can't be
+assigned.
+
+- Two new built-in functions: issubclass() and isinstance().  Both
+take classes as their second arguments.  The former takes a class as
+the first argument and returns true iff first is second, or is a
+subclass of second.  The latter takes any object as the first argument
+and returns true iff first is an instance of the second, or any
+subclass of second.
+
+- configure: Added configuration tests for presence of alarm(),
+pause(), and getpwent().
+
+- Doc/Makefile: changed latex2html targets.
+
+- classes: Reverse the search order for the Don Beaudry hook so that
+the first class with an applicable hook wins.  Makes more sense.
+
+- Changed the checks made in Py_Initialize() and Py_Finalize().  It is
+now legal to call these more than once.  The first call to
+Py_Initialize() initializes, the first call to Py_Finalize()
+finalizes.  There's also a new API, Py_IsInitalized() which checks
+whether we are already initialized (in case you want to leave things
+as they were).
+
+- Completely disable the declarations for malloc(), realloc() and
+free().  Any 90's C compiler has these in header files, and the tests
+to decide whether to suppress the declarations kept failing on some
+platforms.
+
+- *Before* (instead of after) signalmodule.o is added, remove both
+intrcheck.o and sigcheck.o.  This should get rid of warnings in ar or
+ld on various systems.
+
+- Added reop to PC/config.c
+
+- configure: Decided to use -Aa -D_HPUX_SOURCE on HP-UX platforms.
+Removed outdated HP-UX comments from README.  Added Cray T3E comments.
+
+- Various renames of statically defined functions that had name
+conflicts on some systems, e.g. strndup (GNU libc), join (Cray),
+roundup (sys/types.h).
+
+- urllib.py: Interpret three slashes in file: URL as local file (for
+Netscape on Windows/Mac).
+
+- copy.py: Make sure the objects returned by __getinitargs__() are
+kept alive (in the memo) to avoid a certain kind of nasty crash.  (Not
+easily reproducable because it requires a later call to
+__getinitargs__() to return a tuple that happens to be allocated at
+the same address.)
+
+- Added definition of AR to toplevel Makefile.  Renamed @buildno temp
+file to buildno1.
+
+- Moved Include/assert.h to Parser/assert.h, which seems to be the
+only place where it's needed.
+
+- Tweaked the dictionary lookup code again for some more speed
+(Vladimir Marangozov).
+
+- NT build: Changed the way python15.lib is included in the other
+projects.  Per Mark Hammond's suggestion, add it to the extra libs in
+Settings instead of to the project's source files.
+
+- regrtest.py: Change default verbosity so that there are only three
+levels left: -q, default and -v.  In default mode, the name of each
+test is now printed.  -v is the same as the old -vv.  -q is more quiet
+than the old default mode.
+
+- Removed the old FAQ from the distribution.  You now have to get it
+from the web!
+
+- Removed the PC/make_nt.in file from the distribution; it is no
+longer needed.
+
+- Changed the build sequence so that shared modules are built last.
+This fixes things for AIX and doesn't hurt elsewhere.
+
+- Improved test for GNU MP v1 in mpzmodule.c
+
+- fileobject.c: ftell() on Linux discards all buffered data; changed
+read() code to use lseek() instead to get the same effect
+
+- configure.in, configure, importdl.c: NeXT sharedlib fixes
+
+- tupleobject.c: PyTuple_SetItem asserts refcnt==1
+
+- resource.c: Different strategy regarding whether to declare
+getrusage() and getpagesize() -- #ifdef doesn't work, Linux has
+conflicting decls in its headers.  Choice: only declare the return
+type, not the argument prototype, and not on Linux.
+
+- importdl.c, configure*: set sharedlib extensions properly for NeXT
+
+- configure*, Makefile.in, Modules/Makefile.pre.in: AIX shared libraries
+fixed; moved addition of PURIFY to LINKCC to configure
+
+- reopmodule.c, regexmodule.c, regexpr.c, zlibmodule.c: needed casts
+added to shup up various compilers.
+
+- _tkinter.c: removed buggy mac #ifndef
+
+- Doc: various Mac documentation changes, added docs for 'ic' module
+
+- PC/make_nt.in: deleted
+
+- test_time.py, test_strftime.py: tweaks to catch %Z (which may return
+"")
+
+- test_rotor.py: print b -> print `b`
+
+- Tkinter.py: (tagOrId) -> (tagOrId,)
+
+- Tkinter.py: the Tk class now also has a configure() method and
+friends (they have been moved to the Misc class to accomplish this).
+
+- dict.get(key[, default]) returns dict[key] if it exists, or default
+if it doesn't.  The default defaults to None.  This is quicker for
+some applications than using either has_key() or try:...except
+KeyError:....
+
+- Tools/webchecker/: some small changes to webchecker.py; added
+websucker.py (a simple web site mirroring script).
+
+- Dictionary objects now have a get() method (also in UserDict.py).
+dict.get(key, default) returns dict[key] if it exists and default
+otherwise; default defaults to None.
+
+- Tools/scripts/logmerge.py: print the author, too.
+
+- Changes to import: support for "import a.b.c" is now built in.  See
+http://grail.cnri.reston.va.us/python/essays/packages.html
+for more info.  Most important deviations from "ni.py": __init__.py is
+executed in the package's namespace instead of as a submodule; and
+there's no support for "__" or "__domain__".  Note that "ni.py" is not
+changed to match this -- it is simply declared obsolete (while at the
+same time, it is documented...:-( ).
+Unfortunately, "ihooks.py" has not been upgraded (but see "knee.py"
+for an example implementation of hierarchical module import written in
+Python).
+
+- More changes to import: the site.py module is now imported by
+default when Python is initialized; use -S to disable it.  The site.py
+module extends the path with several more directories: site-packages
+inside the lib/python1.5/ directory, site-python in the lib/
+directory, and pathnames mentioned in *.pth files found in either of
+those directories.  See
+http://grail.cnri.reston.va.us/python/essays/packages.html
+for more info.
+
+- Changes to standard library subdirectory names: those subdirectories
+that are not packages have been renamed with a hypen in their name,
+e.g. lib-tk, lib-stdwin, plat-win, plat-linux2, plat-sunos5, dos-8x3.
+The test suite is now a package -- to run a test, you must now use
+"import test.test_foo".
+
+- A completely new re.py module is provided (thanks to Andrew
+Kuchling, Tim Peters and Jeffrey Ollie) which uses Philip Hazel's
+"pcre" re compiler and engine.  For a while, the "old" re.py (which
+was new in 1.5a3!) will be kept around as re1.py.  The "old" regex
+module and underlying parser and engine are still present -- while
+regex is now officially obsolete, it will probably take several major
+release cycles before it can be removed.
+
+- The posix module now has a strerror() function which translates an
+error code to a string.
+
+- The emacs.py module (which was long obsolete) has been removed.
+
+- The universal makefile Misc/Makefile.pre.in now features an
+"install" target.  By default, installed shared libraries go into
+$exec_prefix/lib/python$VERSION/site-packages/.
+
+- The install-sh script is installed with the other configuration
+specific files (in the config/ subdirectory).
+
+- It turns out whatsound.py and sndhdr.py were identical modules.
+Since there's also an imghdr.py file, I propose to make sndhdr.py the
+official one.  For compatibility, whatsound.py imports * from
+sndhdr.py.
+
+- Class objects have a new attribute, __module__, giving the name of
+the module in which they were declared.  This is useful for pickle and
+for printing the full name of a class exception.
+
+- Many extension modules no longer issue a fatal error when their
+initialization fails; the importing code now checks whether an error
+occurred during module initialization, and correctly propagates the
+exception to the import statement.
+
+- Most extension modules now raise class-based exceptions (except when
+-X is used).
+
+- Subtle changes to PyEval_{Save,Restore}Thread(): always swap the
+thread state -- just don't manipulate the lock if it isn't there.
+
+- Fixed a bug in Python/getopt.c that made it do the wrong thing when
+an option was a single '-'.  Thanks to Andrew Kuchling.
+
+- New module mimetypes.py will guess a MIME type from a filename's
+extension.
+
+- Windows: the DLL version is now settable via a resource rather than
+being hardcoded.  This can be used for "branding" a binary Python
+distribution.
+
+- urllib.py is now threadsafe -- it now uses re instead of regex, and
+sys.exc_info() instead of sys.exc_{type,value}.
+
+- Many other library modules that used to use
+sys.exc_{type,value,traceback} are now more thread-safe by virtue of
+using sys.exc_info().
+
+- The functions in popen2 have an optional buffer size parameter.
+Also, the command argument can now be either a string (passed to the
+shell) or a list of arguments (passed directly to execv).
+
+- Alas, the thread support for _tkinter released with 1.5a3 didn't
+work.  It's been rewritten.  The bad news is that it now requires a
+modified version of a file in the standard Tcl distribution, which you
+must compile with a -I option pointing to the standard Tcl source
+tree.  For this reason, the thread support is disabled by default.
+
+- The errno extension module adds two tables: errorcode maps errno
+numbers to errno names (e.g. EINTR), and errorstr maps them to
+message strings.  (The latter is redundant because the new call
+posix.strerror() now does the same, but alla...)  (Marc-Andre Lemburg)
+
+- The readline extension module now provides some interfaces to
+internal readline routines that make it possible to write a completer
+in Python.  An example completer, rlcompleter.py, is provided.
+
+	When completing a simple identifier, it completes keywords,
+	built-ins and globals in __main__; when completing
+	NAME.NAME..., it evaluates (!) the expression up to the last
+	dot and completes its attributes.
+
+	It's very cool to do "import string" type "string.", hit the
+	completion key (twice), and see the list of names defined by
+	the string module!
+
+	Tip: to use the tab key as the completion key, call
+
+	    readline.parse_and_bind("tab: complete")
+
+- The traceback.py module has a new function tb_lineno() by Marc-Andre
+Lemburg which extracts the line number from the linenumber table in
+the code object.  Apparently the traceback object doesn't contains the
+right linenumber when -O is used.  Rather than guessing whether -O is
+on or off, the module itself uses tb_lineno() unconditionally.
+
+- Fixed Demo/tkinter/matt/canvas-moving-or-creating.py: change bind()
+to tag_bind() so it works again.
+
+- The pystone script is now a standard library module.  Example use:
+"import test.pystone; test.pystone.main()".
+
+- The import of the readline module in interactive mode is now also
+attempted when -i is specified.  (Yes, I know, giving in to Marc-Andre
+Lemburg, who asked for this. :-)
+
+- rfc822.py: Entirely rewritten parseaddr() function by Sjoerd
+Mullender, to be closer to the standard.  This fixes the getaddr()
+method.  Unfortunately, getaddrlist() is as broken as ever, since it
+splits on commas without regard for RFC 822 quoting conventions.
+
+- pprint.py: correctly emit trailing "," in singleton tuples.
+
+- _tkinter.c: export names for its type objects, TkappType and
+TkttType.
+
+- pickle.py: use __module__ when defined; fix a particularly hard to
+reproduce bug that confuses the memo when temporary objects are
+returned by custom pickling interfaces; and a semantic change: when
+unpickling the instance variables of an instance, use
+inst.__dict__.update(value) instead of a for loop with setattr() over
+the value.keys().  This is more consistent (the pickling doesn't use
+getattr() either but pickles inst.__dict__) and avoids problems with
+instances that have a __setattr__ hook.  But it *is* a semantic change
+(because the setattr hook is no longer used).  So beware!
+
+- config.h is now installed (at last) in
+$exec_prefix/include/python1.5/.  For most sites, this means that it
+is actually in $prefix/include/python1.5/, with all the other Python
+include files, since $prefix and $exec_prefix are the same by
+default.
+
+- The imp module now supports parts of the functionality to implement
+import of hierarchical module names.  It now supports find_module()
+and load_module() for all types of modules.  Docstrings have been
+added for those functions in the built-in imp module that are still
+relevant (some old interfaces are obsolete).  For a sample
+implementation of hierarchical module import in Python, see the new
+library module knee.py.
+
+- The % operator on string objects now allows arbitrary nested parens
+in a %(...)X style format.  (Brad Howes)
+
+- Reverse the order in which Setup and Setup.local are passed to the
+makesetup script.  This allows variable definitions in Setup.local to
+override definitions in Setup.  (But you'll still have to edit Setup
+if you want to disable modules that are enabled by default, or if such
+modules need non-standard options.)
+
+- Added PyImport_ImportModuleEx(name, globals, locals, fromlist); this
+is like PyImport_ImporModule(name) but receives the globals and locals
+dict and the fromlist arguments as well.  (The name is a char*; the
+others are PyObject*s).
+
+- The 'p' format in the struct extension module alloded to above is
+new in 1.5a4.
+
+- The types.py module now uses try-except in a few places to make it
+more likely that it can be imported in restricted mode.  Some type
+names are undefined in that case, e.g. CodeType (inaccessible),
+FileType (not always accessible), and TracebackType and FrameType
+(inaccessible).
+
+- In urllib.py: added separate administration of temporary files
+created y URLopener.retrieve() so cleanup() can properly remove them.
+The old code removed everything in tempcache which was a bad idea if
+the user had passed a non-temp file into it.  Also, in basejoin(),
+interpret relative paths starting in "../".  This is necessary if the
+server uses symbolic links.
+
+- The Windows build procedure and project files are now based on
+Microsoft Visual C++ 5.x.  The build now takes place in the PCbuild
+directory.  It is much more robust, and properly builds separate Debug
+and Release versions.  (The installer will be added shortly.)
+
+- Added casts and changed some return types in regexpr.c to avoid
+compiler warnings or errors on some platforms.
+
+- The AIX build tools for shared libraries now supports VPATH.  (Donn
+Cave)
+
+- By default, disable the "portable" multimedia modules audioop,
+imageop, and rgbimg, since they don't work on 64-bit platforms.
+
+- Fixed a nasty bug in cStringIO.c when code was actually using the
+close() method (the destructors would try to free certain fields a
+second time).
+
+- For those who think they need it, there's a "user.py" module.  This
+is *not* imported by default, but can be imported to run user-specific
+setup commands, ~/.pythonrc.py.
+
+- Various speedups suggested by Fredrik Lundh, Marc-Andre Lemburg,
+Vladimir Marangozov, and others.
+
+- Added os.altsep; this is '/' on DOS/Windows, and None on systems
+with a sane filename syntax.
+
+- os.py: Write out the dynamic OS choice, to avoid exec statements.
+Adding support for a new OS is now a bit more work, but I bet that
+'dos' or 'nt' will cover most situations...
+
+- The obsolete exception AccessError is now really gone.
+
+- Tools/faqwiz/: New installation instructions show how to maintain
+multiple FAQs.  Removed bootstrap script from end of faqwiz.py module.
+Added instructions to bootstrap script, too.  Version bumped to 0.8.1.
+Added <html>...</html> feature suggested by Skip Montanaro.  Added
+leading text for Roulette, default to 'Hit Reload ...'.  Fix typo in
+default SRCDIR.
+
+- Documentation for the relatively new modules "keyword" and "symbol"
+has been added (to the end of the section on the parser extension
+module).
+
+- In module bisect.py, but functions have two optional argument 'lo'
+and 'hi' which allow you to specify a subsequence of the array to
+operate on.
+
+- In ftplib.py, changed most methods to return their status (even when
+it is always "200 OK") rather than swallowing it.
+
+- main() now calls setlocale(LC_ALL, ""), if setlocale() and
+<locale.h> are defined.
+
+- Changes to configure.in, the configure script, and both
+Makefile.pre.in files, to support SGI's SGI_ABI platform selection
+environment variable.
+
+
+======================================================================
+
+
+From 1.4 to 1.5a3
+=================
+
+Security
+--------
+
+- If you are using the setuid script C wrapper (Misc/setuid-prog.c),
+please use the new version.  The old version has a huge security leak.
+
+Miscellaneous
+-------------
+
+- Because of various (small) incompatible changes in the Python
+bytecode interpreter, the magic number for .pyc files has changed
+again.
+
+- The default module search path is now much saner.  Both on Unix and
+Windows, it is essentially derived from the path to the executable
+(which can be overridden by setting the environment variable
+$PYTHONHOME).  The value of $PYTHONPATH on Windows is now inserted in
+front of the default path, like in Unix (instead of overriding the
+default path).  On Windows, the directory containing the executable is
+added to the end of the path.
+
+- A new version of python-mode.el for Emacs has been included.  Also,
+a new file ccpy-style.el has been added to configure Emacs cc-mode for
+the preferred style in Python C sources.
+
+- On Unix, when using sys.argv[0] to insert the script directory in
+front of sys.path, expand a symbolic link.  You can now install a
+program in a private directory and have a symbolic link to it in a
+public bin directory, and it will put the private directory in the
+module search path.  Note that the symlink is expanded in sys.path[0]
+but not in sys.argv[0], so you can still tell the name by which you
+were invoked.
+
+- It is now recommended to use ``#!/usr/bin/env python'' instead of
+``#!/usr/local/bin/python'' at the start of executable scripts, except
+for CGI scripts.  It has been determined that the use of /usr/bin/env
+is more portable than that of /usr/local/bin/python -- scripts almost
+never have to be edited when the Python interpreter lives in a
+non-standard place.  Note that this doesn't work for CGI scripts since
+the python executable often doesn't live in the HTTP server's default
+search path.
+
+- The silly -s command line option and the corresponding
+PYTHONSUPPRESS environment variable (and the Py_SuppressPrint global
+flag in the Python/C API) are gone.
+
+- Most problems on 64-bit platforms should now be fixed.  Andrew
+Kuchling helped.  Some uncommon extension modules are still not
+clean (image and audio ops?).
+
+- Fixed a bug where multiple anonymous tuple arguments would be mixed up
+when using the debugger or profiler (reported by Just van Rossum).
+The simplest example is ``def f((a,b),(c,d)): print a,b,c,d''; this
+would print the wrong value when run under the debugger or profiler.
+
+- The hacks that the dictionary implementation used to speed up
+repeated lookups of the same C string were removed; these were a
+source of subtle problems and don't seem to serve much of a purpose
+any longer.
+
+- All traces of support for the long dead access statement have been
+removed from the sources.
+
+- Plugged the two-byte memory leak in the tokenizer when reading an
+interactive EOF.
+
+- There's a -O option to the interpreter that removes SET_LINENO
+instructions and assert statements (see below); it uses and produces
+.pyo files instead of .pyc files.  The speedup is only a few percent
+in most cases.  The line numbers are still available in the .pyo file,
+as a separate table (which is also available in .pyc files).  However,
+the removal of the SET_LINENO instructions means that the debugger
+(pdb) can't set breakpoints on lines in -O mode.  The traceback module
+contains a function to extract a line number from the code object
+referenced in a traceback object.  In the future it should be possible
+to write external bytecode optimizers that create better optimized
+.pyo files, and there should be more control over optimization;
+consider the -O option a "teaser".  Without -O, the assert statement
+actually generates code that first checks __debug__; if this variable
+is false, the assertion is not checked.  __debug__ is a built-in
+variable whose value is initialized to track the -O flag (it's true
+iff -O is not specified).  With -O, no code is generated for assert
+statements, nor for code of the form ``if __debug__: <something>''.
+Sorry, no further constant folding happens.
+
+
+Performance
+-----------
+
+- It's much faster (almost twice for pystone.py -- see
+Tools/scripts).  See the entry on string interning below.
+
+- Some speedup by using separate free lists for method objects (both
+the C and the Python variety) and for floating point numbers.
+
+- Big speedup by allocating frame objects with a single malloc() call.
+The Python/C API for frames is changed (you shouldn't be using this
+anyway).
+
+- Significant speedup by inlining some common opcodes for common operand 
+types (e.g.  i+i, i-i, and list[i]).  Fredrik Lundh.
+
+- Small speedup by reordering the method tables of some common
+objects (e.g. list.append is now first).
+
+- Big optimization to the read() method of file objects.  A read()
+without arguments now attempts to use fstat to allocate a buffer of
+the right size; for pipes and sockets, it will fall back to doubling
+the buffer size.  While that the improvement is real on all systems,
+it is most dramatic on Windows.
+
+
+Documentation
+-------------
+
+- Many new pieces of library documentation were contributed, mostly by
+Andrew Kuchling.  Even cmath is now documented!  There's also a
+chapter of the library manual, "libundoc.tex", which provides a
+listing of all undocumented modules, plus their status (e.g. internal,
+obsolete, or in need of documentation).  Also contributions by Sue
+Williams, Skip Montanaro, and some module authors who succumbed to
+pressure to document their own contributed modules :-).  Note that
+printing the documentation now kills fewer trees -- the margins have
+been reduced.
+
+- I have started documenting the Python/C API. Unfortunately this project 
+hasn't been completed yet.  It will be complete before the final release of 
+Python 1.5, though.  At the moment, it's better to read the LaTeX source 
+than to attempt to run it through LaTeX and print the resulting dvi file.
+
+- The posix module (and hence os.py) now has doc strings!  Thanks to Neil 
+Schemenauer.  I received a few other contributions of doc strings.  In most 
+other places, doc strings are still wishful thinking...
+
+
+Language changes
+----------------
+
+- Private variables with leading double underscore are now a permanent 
+feature of the language.  (These were experimental in release 1.4.  I have 
+favorable experience using them; I can't label them "experimental" 
+forever.)
+
+- There's new string literal syntax for "raw strings".  Prefixing a string 
+literal with the letter r (or R) disables all escape processing in the 
+string; for example, r'\n' is a two-character string consisting of a 
+backslash followed by the letter n.  This combines with all forms of string 
+quotes; it is actually useful for triple quoted doc strings which might 
+contain references to \n or \t.  An embedded quote prefixed with a 
+backslash does not terminate the string, but the backslash is still 
+included in the string; for example, r'\'' is a two-character string 
+consisting of a backslash and a quote.  (Raw strings are also 
+affectionately known as Robin strings, after their inventor, Robin 
+Friedrich.)
+
+- There's a simple assert statement, and a new exception
+AssertionError.  For example, ``assert foo > 0'' is equivalent to ``if
+not foo > 0: raise AssertionError''.  Sorry, the text of the asserted
+condition is not available; it would be too complicated to generate
+code for this (since the code is generated from a parse tree).
+However, the text is displayed as part of the traceback!
+
+- The raise statement has a new feature: when using "raise SomeClass,
+somevalue" where somevalue is not an instance of SomeClass, it
+instantiates SomeClass(somevalue).  In 1.5a4, if somevalue is an
+instance of a *derived* class of SomeClass, the exception class raised
+is set to somevalue.__class__, and SomeClass is ignored after that.
+
+- Duplicate keyword arguments are now detected at compile time;
+f(a=1,a=2) is now a syntax error.
+
+
+Changes to builtin features
+---------------------------
+
+- There's a new exception FloatingPointError (used only by Lee Busby's
+patches to catch floating point exceptions, at the moment).
+
+- The obsolete exception ConflictError (presumably used by the long
+obsolete access statement) has been deleted.
+
+- There's a new function sys.exc_info() which returns the tuple 
+(sys.exc_type, sys.exc_value, sys.exc_traceback) in a thread-safe way.
+
+- There's a new variable sys.executable, pointing to the executable file 
+for the Python interpreter.
+
+- The sort() methods for lists no longer uses the C library qsort(); I
+wrote my own quicksort implementation, with lots of help (in the form
+of a kind of competition) from Tim Peters.  This solves a bug in
+dictionary comparisons on some Solaris versions when Python is built
+with threads, and makes sorting lists even faster.
+
+- The semantics of comparing two dictionaries have changed, to make
+comparison of unequal dictionaries faster.  A shorter dictionary is
+always considered smaller than a larger dictionary.  For dictionaries
+of the same size, the smallest differing element determines the
+outcome (which yields the same results as before in this case, without
+explicit sorting).  Thanks to Aaron Watters for suggesting something
+like this.
+
+- The semantics of try-except have changed subtly so that calling a
+function in an exception handler that itself raises and catches an
+exception no longer overwrites the sys.exc_* variables.  This also
+alleviates the problem that objects referenced in a stack frame that
+caught an exception are kept alive until another exception is caught
+-- the sys.exc_* variables are restored to their previous value when
+returning from a function that caught an exception.
+
+- There's a new "buffer" interface.  Certain objects (e.g. strings and
+arrays) now support the "buffer" protocol.  Buffer objects are acceptable 
+whenever formerly a string was required for a write operation; mutable 
+buffer objects can be the target of a read operation using the call
+f.readinto(buffer).  A cool feature is that regular expression matching now 
+also work on array objects.  Contribution by Jack Jansen.  (Needs 
+documentation.)
+
+- String interning: dictionary lookups are faster when the lookup
+string object is the same object as the key in the dictionary, not
+just a string with the same value.  This is done by having a pool of
+"interned" strings.  Most names generated by the interpreter are now
+automatically interned, and there's a new built-in function intern(s)
+that returns the interned version of a string.  Interned strings are
+not a different object type, and interning is totally optional, but by
+interning most keys a speedup of about 15% was obtained for the
+pystone benchmark.
+
+- Dictionary objects have several new methods; clear() and copy() have
+the obvious semantics, while update(d) merges the contents of another
+dictionary d into this one, overriding existing keys.  The dictionary
+implementation file is now called dictobject.c rather than the
+confusing mappingobject.c.
+
+- The intrinsic function dir() is much smarter; it looks in __dict__,
+__members__ and __methods__.
+
+- The intrinsic functions int(), long() and float() can now take a
+string argument and then do the same thing as string.atoi(),
+string.atol(), and string.atof().  No second 'base' argument is
+allowed, and complex() does not take a string (nobody cared enough).
+
+- When a module is deleted, its globals are now deleted in two phases.
+In the first phase, all variables whose name begins with exactly one
+underscore are replaced by None; in the second phase, all variables
+are deleted.  This makes it possible to have global objects whose
+destructors depend on other globals.  The deletion order within each
+phase is still random.
+
+- It is no longer an error for a function to be called without a
+global variable __builtins__ -- an empty directory will be provided
+by default.
+
+- Guido's corollary to the "Don Beaudry hook": it is now possible to
+do metaprogramming by using an instance as a base class.  Not for the
+faint of heart; and undocumented as yet, but basically if a base class
+is an instance, its class will be instantiated to create the new
+class.  Jim Fulton will love it -- it also works with instances of his
+"extension classes", since it is triggered by the presence of a
+__class__ attribute on the purported base class.  See
+Demo/metaclasses/index.html for an explanation and see that directory
+for examples.
+
+- Another change is that the Don Beaudry hook is now invoked when
+*any* base class is special.  (Up to 1.5a3, the *last* special base
+class is used; in 1.5a4, the more rational choice of the *first*
+special base class is used.)
+
+- New optional parameter to the readlines() method of file objects.
+This indicates the number of bytes to read (the actual number of bytes
+read will be somewhat larger due to buffering reading until the end of
+the line).  Some optimizations have also been made to speed it up (but
+not as much as read()).
+
+- Complex numbers no longer have the ".conj" pseudo attribute; use
+z.conjugate() instead, or complex(z.real, -z.imag).  Complex numbers
+now *do* support the __members__ and __methods__ special attributes.
+
+- The complex() function now looks for a __complex__() method on class
+instances before giving up.
+
+- Long integers now support arbitrary shift counts, so you can now
+write 1L<<1000000, memory permitting.  (Python 1.4 reports "outrageous
+shift count for this.)
+
+- The hex() and oct() functions have been changed so that for regular
+integers, they never emit a minus sign.  For example, on a 32-bit
+machine, oct(-1) now returns '037777777777' and hex(-1) returns
+'0xffffffff'.  While this may seem inconsistent, it is much more
+useful.  (For long integers, a minus sign is used as before, to fit
+the result in memory :-)
+
+- The hash() function computes better hashes for several data types,
+including strings, floating point numbers, and complex numbers.
+
+
+New extension modules
+---------------------
+
+- New extension modules cStringIO.c and cPickle.c, written by Jim
+Fulton and other folks at Digital Creations.  These are much more
+efficient than their Python counterparts StringIO.py and pickle.py,
+but don't support subclassing.  cPickle.c clocks up to 1000 times
+faster than pickle.py; cStringIO.c's improvement is less dramatic but
+still significant.
+
+- New extension module zlibmodule.c, interfacing to the free zlib
+library (gzip compatible compression).  There's also a module gzip.py
+which provides a higher level interface.  Written by Andrew Kuchling
+and Jeremy Hylton.
+
+- New module readline; see the "miscellaneous" section above.
+
+- New Unix extension module resource.c, by Jeremy Hylton, provides
+access to getrlimit(), getrusage(), setrusage(), getpagesize(), and
+related symbolic constants.
+
+- New extension puremodule.c, by Barry Warsaw, which interfaces to the
+Purify(TM) C API.  See also the file Misc/PURIFY.README.  It is also
+possible to enable Purify by simply setting the PURIFY Makefile
+variable in the Modules/Setup file.
+
+
+Changes in extension modules
+----------------------------
+
+- The struct extension module has several new features to control byte
+order and word size.  It supports reading and writing IEEE floats even
+on platforms where this is not the native format.  It uses uppercase
+format codes for unsigned integers of various sizes (always using
+Python long ints for 'I' and 'L'), 's' with a size prefix for strings,
+and 'p' for "Pascal strings" (with a leading length byte, included in
+the size; blame Hannu Krosing; new in 1.5a4).  A prefix '>' forces
+big-endian data and '<' forces little-endian data; these also select
+standard data sizes and disable automatic alignment (use pad bytes as
+needed).
+
+- The array module supports uppercase format codes for unsigned data
+formats (like the struct module).
+
+- The fcntl extension module now exports the needed symbolic
+constants.  (Formerly these were in FCNTL.py which was not available
+or correct for all platforms.)
+
+- The extension modules dbm, gdbm and bsddb now check that the
+database is still open before making any new calls.
+
+- The dbhash module is no more.  Use bsddb instead.  (There's a third
+party interface for the BSD 2.x code somewhere on the web; support for
+bsddb will be deprecated.)
+
+- The gdbm module now supports a sync() method.
+
+- The socket module now has some new functions: getprotobyname(), and
+the set {ntoh,hton}{s,l}().
+
+- Various modules now export their type object: socket.SocketType,
+array.ArrayType.
+
+- The socket module's accept() method now returns unknown addresses as
+a tuple rather than raising an exception.  (This can happen in
+promiscuous mode.)  Theres' also a new function getprotobyname().
+
+- The pthread support for the thread module now works on most platforms.
+
+- STDWIN is now officially obsolete.  Support for it will eventually
+be removed from the distribution.
+
+- The binascii extension module is now hopefully fully debugged.
+(XXX Oops -- Fredrik Lundh promised me a uuencode fix that I never
+received.)
+
+- audioop.c: added a ratecv() function; better handling of overflow in
+add().
+
+- posixmodule.c: now exports the O_* flags (O_APPEND etc.).  On
+Windows, also O_TEXT and O_BINARY.  The 'error' variable (the
+exception is raises) is renamed -- its string value is now "os.error",
+so newbies don't believe they have to import posix (or nt) to catch
+it when they see os.error reported as posix.error.  The execve()
+function now accepts any mapping object for the environment.
+
+- A new version of the al (audio library) module for SGI was
+contributed by Sjoerd Mullender.
+
+- The regex module has a new function get_syntax() which retrieves the
+syntax setting set by set_syntax().  The code was also sanitized,
+removing worries about unclean error handling.  See also below for its
+successor, re.py.
+
+- The "new" module (which creates new objects of various types) once
+again has a fully functioning new.function() method.  Dangerous as
+ever!  Also, new.code() has several new arguments.
+
+- A problem has been fixed in the rotor module: on systems with signed
+characters, rotor-encoded data was not portable when the key contained
+8-bit characters.  Also, setkey() now requires its argument rather
+than having broken code to default it.
+
+- The sys.builtin_module_names variable is now a tuple.  Another new
+variables in sys is sys.executable (the full path to the Python
+binary, if known).
+
+- The specs for time.strftime() have undergone some revisions.  It
+appears that not all format characters are supported in the same way
+on all platforms.  Rather than reimplement it, we note these
+differences in the documentation, and emphasize the shared set of
+features.  There's also a thorough test set (that occasionally finds
+problems in the C library implementation, e.g. on some Linuxes),
+thanks to Skip Montanaro.
+
+- The nis module seems broken when used with NIS+; unfortunately
+nobody knows how to fix it.  It should still work with old NIS.
+
+
+New library modules
+-------------------
+
+- New (still experimental) Perl-style regular expression module,
+re.py, which uses a new interface for matching as well as a new
+syntax; the new interface avoids the thread-unsafety of the regex
+interface.  This comes with a helper extension reopmodule.c and vastly
+rewritten regexpr.c.  Most work on this was done by Jeffrey Ollie, Tim
+Peters, and Andrew Kuchling.  See the documentation libre.tex.  In
+1.5, the old regex module is still fully supported; in the future, it
+will become obsolete.
+
+- New module gzip.py; see zlib above.
+
+- New module keyword.py exports knowledge about Python's built-in
+keywords.  (New version by Ka-Ping Yee.)
+
+- New module pprint.py (with documentation) which supports
+pretty-printing of lists, tuples, & dictionaries recursively.  By Fred
+Drake.
+
+- New module code.py.  The function code.compile_command() can
+determine whether an interactively entered command is complete or not,
+distinguishing incomplete from invalid input.  (XXX Unfortunately,
+this seems broken at this moment, and I don't have the time to fix
+it.  It's probably better to add an explicit interface to the parser
+for this.)
+
+- There is now a library module xdrlib.py which can read and write the
+XDR data format as used by Sun RPC, for example.  It uses the struct
+module.
+
+
+Changes in library modules
+--------------------------
+
+- Module codehack.py is now completely obsolete.
+
+- The pickle.py module has been updated to make it compatible with the
+new binary format that cPickle.c produces.  By default it produces the
+old all-ASCII format compatible with the old pickle.py, still much
+faster than pickle.py; it will read both formats automatically.  A few
+other updates have been made.
+
+- A new helper module, copy_reg.py, is provided to register extensions
+to the pickling code.
+
+- Revamped module tokenize.py is much more accurate and has an
+interface that makes it a breeze to write code to colorize Python
+source code.  Contributed by Ka-Ping Yee.
+
+- In ihooks.py, ModuleLoader.load_module() now closes the file under
+all circumstances.
+
+- The tempfile.py module has a new class, TemporaryFile, which creates
+an open temporary file that will be deleted automatically when
+closed.  This works on Windows and MacOS as well as on Unix.  (Jim
+Fulton.)
+
+- Changes to the cgi.py module: Most imports are now done at the
+top of the module, which provides a speedup when using ni (Jim
+Fulton).  The problem with file upload to a Windows platform is solved
+by using the new tempfile.TemporaryFile class; temporary files are now
+always opened in binary mode (Jim Fulton).  The cgi.escape() function
+now takes an optional flag argument that quotes '"' to '&quot;'.  It
+is now possible to invoke cgi.py from a command line script, to test
+cgi scripts more easily outside an http server.  There's an optional
+limit to the size of uploads to POST (Skip Montanaro).  Added a
+'strict_parsing' option to all parsing functions (Jim Fulton).  The
+function parse_qs() now uses urllib.unquote() on the name as well as
+the value of fields (Clarence Gardner).  The FieldStorage class now
+has a __len__() method.
+
+- httplib.py: the socket object is no longer closed; all HTTP/1.*
+responses are now accepted; and it is now thread-safe (by not using
+the regex module).
+
+- BaseHTTPModule.py: treat all HTTP/1.* versions the same.
+
+- The popen2.py module is now rewritten using a class, which makes
+access to the standard error stream and the process id of the
+subprocess possible.
+
+- Added timezone support to the rfc822.py module, in the form of a
+getdate_tz() method and a parsedate_tz() function; also a mktime_tz().
+Also added recognition of some non-standard date formats, by Lars
+Wirzenius, and RFC 850 dates (Chris Lawrence).
+
+- mhlib.py: various enhancements, including almost compatible parsing
+of message sequence specifiers without invoking a subprocess.  Also
+added a createmessage() method by Lars Wirzenius.
+
+- The StringIO.StringIO class now supports readline(nbytes).  (Lars 
+Wirzenius.)  (Of course, you should be using cStringIO for performance.)
+
+- UserDict.py supports the new dictionary methods as well.
+
+- Improvements for whrandom.py by Tim Peters: use 32-bit arithmetic to
+speed it up, and replace 0 seed values by 1 to avoid degeneration.
+A bug was fixed in the test for invalid arguments.
+
+- Module ftplib.py: added support for parsing a .netrc file (Fred
+Drake).  Also added an ntransfercmd() method to the FTP class, which
+allows access to the expected size of a transfer when available, and a
+parse150() function to the module which parses the corresponding 150
+response.
+
+- urllib.py: the ftp cache is now limited to 10 entries.  Added
+quote_plus() and unquote_plus() functions which are like quote() and
+unquote() but also replace spaces with '+' or vice versa, for
+encoding/decoding CGI form arguments.  Catch all errors from the ftp
+module.  HTTP requests now add the Host: header line.  The proxy
+variable names are now mapped to lower case, for Windows.  The
+spliturl() function no longer erroneously throws away all data past
+the first newline.  The basejoin() function now intereprets "../"
+correctly.  I *believe* that the problems with "exception raised in
+__del__" under certain circumstances have been fixed (mostly by
+changes elsewher in the interpreter).
+
+- In urlparse.py, there is a cache for results in urlparse.urlparse();
+its size limit is set to 20.  Also, new URL schemes shttp, https, and
+snews are "supported".
+
+- shelve.py: use cPickle and cStringIO when available.  Also added
+a sync() method, which calls the database's sync() method if there is
+one.
+
+- The mimetools.py module now uses the available Python modules for
+decoding quoted-printable, uuencode and base64 formats, rather than
+creating a subprocess.
+
+- The python debugger (pdb.py, and its base class bdb.py) now support
+conditional breakpoints.  See the docs.
+
+- The modules base64.py, uu.py and quopri.py can now be used as simple
+command line utilities.
+
+- Various small fixes to the nntplib.py module that I can't bother to
+document in detail.
+
+- Sjoerd Mullender's mimify.py module now supports base64 encoding and 
+includes functions to handle the funny encoding you sometimes see in mail 
+headers.  It is now documented.
+
+- mailbox.py: Added BabylMailbox.  Improved the way the mailbox is
+gotten from the environment.
+
+- Many more modules now correctly open files in binary mode when this
+is necessary on non-Unix platforms.
+
+- The copying functions in the undocumented module shutil.py are
+smarter.
+
+- The Writer classes in the formatter.py module now have a flush()
+method.
+
+- The sgmllib.py module accepts hyphens and periods in the middle of
+attribute names.  While this is against the SGML standard, there is
+some HTML out there that uses this...
+
+- The interface for the Python bytecode disassembler module, dis.py,
+has been enhanced quite a bit.  There's now one main function,
+dis.dis(), which takes almost any kind of object (function, module,
+class, instance, method, code object) and disassembles it; without
+arguments it disassembles the last frame of the last traceback.  The
+other functions have changed slightly, too.
+
+- The imghdr.py module recognizes new image types: BMP, PNG.
+
+- The string.py module has a new function replace(str, old, new,
+[maxsplit]) which does substring replacements.  It is actually
+implemented in C in the strop module.  The functions [r]find() an
+[r]index() have an optional 4th argument indicating the end of the
+substring to search, alsoo implemented by their strop counterparts.
+(Remember, never import strop -- import string uses strop when
+available with zero overhead.)
+
+- The string.join() function now accepts any sequence argument, not
+just lists and tuples.
+
+- The string.maketrans() requires its first two arguments to be
+present.  The old version didn't require them, but there's not much
+point without them, and the documentation suggests that they are
+required, so we fixed the code to match the documentation.
+
+- The regsub.py module has a function clear_cache(), which clears its
+internal cache of compiled regular expressions.  Also, the cache now
+takes the current syntax setting into account.  (However, this module
+is now obsolete -- use the sub() or subn() functions or methods in the
+re module.)
+
+- The undocumented module Complex.py has been removed, now that Python
+has built-in complex numbers.  A similar module remains as
+Demo/classes/Complex.py, as an example.
+
+
+Changes to the build process
+----------------------------
+
+- The way GNU readline is configured is totally different.  The
+--with-readline configure option is gone.  It is now an extension
+module, which may be loaded dynamically.  You must enable it (and
+specify the correct linraries to link with) in the Modules/Setup file.
+Importing the module installs some hooks which enable command line
+editing.  When the interpreter shell is invoked interactively, it
+attempts to import the readline module; when this fails, the default
+input mechanism is used.  The hook variables are PyOS_InputHook and
+PyOS_ReadlineFunctionPointer.  (Code contributed by Lee Busby, with
+ideas from William Magro.)
+
+- New build procedure: a single library, libpython1.5.a, is now built,
+which contains absolutely everything except for a one-line main()
+program (which calls Py_Main(argc, argv) to start the interpreter
+shell).  This makes life much simpler for applications that need to
+embed Python.  The serial number of the build is now included in the
+version string (sys.version).
+
+- As far as I can tell, neither gcc -Wall nor the Microsoft compiler
+emits a single warning any more when compiling Python.
+
+- A number of new Makefile variables have been added for special
+situations, e.g. LDLAST is appended to the link command.  These are
+used by editing the Makefile or passing them on the make command
+line.
+
+- A set of patches from Lee Busby has been integrated that make it
+possible to catch floating point exceptions.  Use the configure option
+--with-fpectl to enable the patches; the extension modules fpectl and
+fpetest provide control to enable/disable and test the feature,
+respectively.
+
+- The support for shared libraries under AIX is now simpler and more
+robust.  Thanks to Vladimir Marangozov for revamping his own patches!
+
+- The Modules/makesetup script now reads a file Setup.local as well as
+a file Setup.  Most changes to the Setup script can be done by editing
+Setup.local instead, which makes it easier to carry a particular setup
+over from one release to the next.
+
+- The Modules/makesetup script now copies any "include" lines it
+encounters verbatim into the output Makefile.  It also recognizes .cxx
+and .cpp as C++ source files.
+
+- The configure script is smarter about C compiler options; e.g. with
+gcc it uses -O2 and -g when possible, and on some other platforms it
+uses -Olimit 1500 to avoid a warning from the optimizer about the main
+loop in ceval.c (which has more than 1000 basic blocks).
+
+- The configure script now detects whether malloc(0) returns a NULL
+pointer or a valid block (of length zero).  This avoids the nonsense
+of always adding one byte to all malloc() arguments on most platforms.
+
+- The configure script has a new option, --with-dec-threads, to enable
+DEC threads on DEC Alpha platforms.  Also, --with-threads is now an
+alias for --with-thread (this was the Most Common Typo in configure
+arguments).
+
+- Many changes in Doc/Makefile; amongst others, latex2html is now used
+to generate HTML from all latex documents.
+
+
+Change to the Python/C API
+--------------------------
+
+- Because some interfaces have changed, the PYTHON_API macro has been
+bumped.  Most extensions built for the old API version will still run,
+but I can't guarantee this.  Python prints a warning message on
+version mismatches; it dumps core when the version mismatch causes a
+serious problem :-)
+
+- I've completed the Grand Renaming, with the help of Roger Masse and
+Barry Warsaw.  This makes reading or debugging the code much easier.
+Many other unrelated code reorganizations have also been carried out.
+The allobjects.h header file is gone; instead, you would have to
+include Python.h followed by rename2.h.  But you're better off running
+Tools/scripts/fixcid.py -s Misc/RENAME on your source, so you can omit
+the rename2.h; it will disappear in the next release.
+
+- Various and sundry small bugs in the "abstract" interfaces have been
+fixed.  Thanks to all the (involuntary) testers of the Python 1.4
+version!  Some new functions have been added, e.g. PySequence_List(o),
+equivalent to list(o) in Python.
+
+- New API functions PyLong_FromUnsignedLong() and
+PyLong_AsUnsignedLong().
+
+- The API functions in the file cgensupport.c are no longer
+supported.  This file has been moved to Modules and is only ever
+compiled when the SGI specific 'gl' module is built.
+
+- PyObject_Compare() can now raise an exception.  Check with
+PyErr_Occurred().  The comparison function in an object type may also
+raise an exception.
+
+- The slice interface uses an upper bound of INT_MAX when no explicit
+upper bound is given (e.x. for a[1:]).  It used to ask the object for
+its length and do the calculations.
+
+- Support for multiple independent interpreters.  See Doc/api.tex,
+functions Py_NewInterpreter() and Py_EndInterpreter().  Since the
+documentation is incomplete, also see the new Demo/pysvr example
+(which shows how to use these in a threaded application) and the
+source code.
+
+- There is now a Py_Finalize() function which "de-initializes"
+Python.  It is possible to completely restart the interpreter
+repeatedly by calling Py_Finalize() followed by Py_Initialize().  A
+change of functionality in Py_Initialize() means that it is now a
+fatal error to call it while the interpreter is already initialized.
+The old, half-hearted Py_Cleanup() routine is gone.  Use of Py_Exit()
+is deprecated (it is nothing more than Py_Finalize() followed by
+exit()).
+
+- There are no known memory leaks left.  While Py_Finalize() doesn't
+free *all* allocated memory (some of it is hard to track down),
+repeated calls to Py_Finalize() and Py_Initialize() do not create
+unaccessible heap blocks.
+
+- There is now explicit per-thread state.  (Inspired by, but not the
+same as, Greg Stein's free threading patches.)
+
+- There is now better support for threading C applications.  There are
+now explicit APIs to manipulate the interpreter lock.  Read the source
+or the Demo/pysvr example; the new functions are
+PyEval_{Acquire,Release}{Lock,Thread}().
+
+- The test macro DEBUG has changed to Py_DEBUG, to avoid interference
+with other libraries' DEBUG macros.  Likewise for any other test
+macros that didn't yet start with Py_.
+
+- New wrappers around malloc() and friends: Py_Malloc() etc. call
+malloc() and call PyErr_NoMemory() when it fails; PyMem_Malloc() call
+just malloc().  Use of these wrappers could be essential if multiple
+memory allocators exist (e.g. when using certain DLL setups under
+Windows).  (Idea by Jim Fulton.)
+
+- New C API PyImport_Import() which uses whatever __import__() hook
+that is installed for the current execution environment.  By Jim
+Fulton.
+
+- It is now possible for an extension module's init function to fail
+non-fatally, by calling one of the PyErr_* functions and returning.
+
+- The PyInt_AS_LONG() and PyFloat_AS_DOUBLE() macros now cast their
+argument to the proper type, like the similar PyString macros already
+did.  (Suggestion by Marc-Andre Lemburg.)  Similar for PyList_GET_SIZE
+and PyList_GET_ITEM.
+
+- Some of the Py_Get* function, like Py_GetVersion() (but not yet
+Py_GetPath()) are now declared as returning a const char *.  (More
+should follow.)
+
+- Changed the run-time library to check for exceptions after object
+comparisons.  PyObject_Compare() can now return an exception; use
+PyErr_Occurred() to check (there is *no* special return value).
+
+- PyFile_WriteString() and Py_Flushline() now return error indicators
+instead of clearing exceptions.  This fixes an obscure bug where using
+these would clear a pending exception, discovered by Just van Rossum.
+
+- There's a new function, PyArg_ParseTupleAndKeywords(), which parses
+an argument list including keyword arguments.  Contributed by Geoff
+Philbrick.
+
+- PyArg_GetInt() is gone.
+
+- It's no longer necessary to include graminit.h when calling one of
+the extended parser API functions.  The three public grammar start
+symbols are now in Python.h as Py_single_input, Py_file_input, and
+Py_eval_input.
+
+- The CObject interface has a new function,
+PyCObject_Import(module, name).  It calls PyCObject_AsVoidPtr()
+on the object referenced by "module.name".
+
+
+Tkinter
+-------
+
+- On popular demand, _tkinter once again installs a hook for readline
+that processes certain Tk events while waiting for the user to type
+(using PyOS_InputHook).
+
+- A patch by Craig McPheeters plugs the most obnoxious memory leaks,
+caused by command definitions referencing widget objects beyond their
+lifetime.
+
+- New standard dialog modules: tkColorChooser.py, tkCommonDialog.py,
+tkMessageBox.py, tkFileDialog.py, tkSimpleDialog.py These interface
+with the new Tk dialog scripts, and provide more "native platform"
+style file selection dialog boxes on some platforms.  Contributed by
+Fredrik Lundh.
+
+- Tkinter.py: when the first Tk object is destroyed, it sets the
+hiddel global _default_root to None, so that when another Tk object is
+created it becomes the new default root.  Other miscellaneous
+changes and fixes.
+
+- The Image class now has a configure method.
+
+- Added a bunch of new winfo options to Tkinter.py; we should now be
+up to date with Tk 4.2.  The new winfo options supported are:
+mananger, pointerx, pointerxy, pointery, server, viewable, visualid,
+visualsavailable.
+
+- The broken bind() method on Canvas objects defined in the Canvas.py
+module has been fixed.  The CanvasItem and Group classes now also have
+an unbind() method.
+
+- The problem with Tkinter.py falling back to trying to import
+"tkinter" when "_tkinter" is not found has been fixed -- it no longer
+tries "tkinter", ever.  This makes diagnosing the problem "_tkinter
+not configured" much easier and will hopefully reduce the newsgroup
+traffic on this topic.
+
+- The ScrolledText module once again supports the 'cnf' parameter, to
+be compatible with the examples in Mark Lutz' book (I know, I know,
+too late...)
+
+- The _tkinter.c extension module has been revamped.  It now support
+Tk versions 4.1 through 8.0; support for 4.0 has been dropped.  It
+works well under Windows and Mac (with the latest Tk ports to those
+platforms).  It also supports threading -- it is safe for one
+(Python-created) thread to be blocked in _tkinter.mainloop() while
+other threads modify widgets.  To make the changes visible, those
+threads must use update_idletasks()method.  (The patch for threading
+in 1.5a3 was broken; in 1.5a4, it is back in a different version,
+which requires access to the Tcl sources to get it to work -- hence it
+is disabled by default.)
+
+- A bug in _tkinter.c has been fixed, where Split() with a string
+containing an unmatched '"' could cause an exception or core dump.
+
+- Unfortunately, on Windows and Mac, Tk 8.0 no longer supports
+CreateFileHandler, so _tkinter.createfilehandler is not available on
+those platforms when using Tk 8.0 or later.  I will have to rethink
+how to interface with Tcl's lower-level event mechanism, or with its
+channels (which are like Python's file-like objects).  Jack Jansen has
+provided a fix for the Mac, so createfilehandler *is* actually
+supported there; maybe I can adapt his fix for Windows.
+
+
+Tools and Demos
+---------------
+
+- A new regression test suite is provided, which tests most of the
+standard and built-in modules.  The regression test is run by invoking
+the script Lib/test/regrtest.py.  Barry Warsaw wrote the test harnass;
+he and Roger Masse contributed most of the new tests.
+
+- New tool: faqwiz -- the CGI script that is used to maintain the
+Python FAQ (http://grail.cnri.reston.va.us/cgi-bin/faqw.py).  In
+Tools/faqwiz.
+
+- New tool: webchecker -- a simple extensible web robot that, when
+aimed at a web server, checks that server for dead links.  Available
+are a command line utility as well as a Tkinter based GUI version.  In
+Tools/webchecker.  A simplified version of this program is dissected
+in my article in O'Reilly's WWW Journal, the issue on Scripting
+Languages (Vol 2, No 2); Scripting the Web with Python (pp 97-120).
+Includes a parser for robots.txt files by Skip Montanaro.
+
+- New small tools: cvsfiles.py (prints a list of all files under CVS
+n a particular directory tree), treesync.py (a rather Guido-specific
+script to synchronize two source trees, one on Windows NT, the other
+one on Unix under CVS but accessible from the NT box), and logmerge.py
+(sort a collection of RCS or CVS logs by date).  In Tools/scripts.
+
+- The freeze script now also works under Windows (NT).  Another
+feature allows the -p option to be pointed at the Python source tree
+instead of the installation prefix.  This was loosely based on part of
+xfreeze by Sam Rushing and Bill Tutt.
+
+- New examples (Demo/extend) that show how to use the generic
+extension makefile (Misc/Makefile.pre.in).
+
+- Tools/scripts/h2py.py now supports C++ comments.
+
+- Tools/scripts/pystone.py script is upgraded to version 1.1; there
+was a bug in version 1.0 (distributed with Python 1.4) that leaked
+memory.  Also, in 1.1, the LOOPS variable is incremented to 10000.
+
+- Demo/classes/Rat.py completely rewritten by Sjoerd Mullender.
+
+
+Windows (NT and 95)
+-------------------
+
+- New project files for Developer Studio (Visual C++) 5.0 for Windows
+NT (the old VC++ 4.2 Makefile is also still supported, but will
+eventually be withdrawn due to its bulkiness).
+
+- See the note on the new module search path in the "Miscellaneous" section 
+above.
+
+- Support for Win32s (the 32-bit Windows API under Windows 3.1) is
+basically withdrawn.  If it still works for you, you're lucky.
+
+- There's a new extension module, msvcrt.c, which provides various 
+low-level operations defined in the Microsoft Visual C++ Runtime Library.  
+These include locking(), setmode(), get_osfhandle(), set_osfhandle(), and 
+console I/O functions like kbhit(), getch() and putch().
+
+- The -u option not only sets the standard I/O streams to unbuffered
+status, but also sets them in binary mode.  (This can also be done
+using msvcrt.setmode(), by the way.)
+
+- The, sys.prefix and sys.exec_prefix variables point to the directory 
+where Python is installed, or to the top of the source tree, if it was run 
+from there.
+
+- The various os.path modules (posixpath, ntpath, macpath) now support
+passing more than two arguments to the join() function, so
+os.path.join(a, b, c) is the same as os.path.join(a, os.path.join(b,
+c)).
+
+- The ntpath module (normally used as os.path) supports ~ to $HOME 
+expansion in expanduser().
+
+- The freeze tool now works on Windows.
+
+- See also the Tkinter category for a sad note on
+_tkinter.createfilehandler().
+
+- The truncate() method for file objects now works on Windows.
+
+- Py_Initialize() is no longer called when the DLL is loaded.  You
+must call it yourself.
+
+- The time module's clock() function now has good precision through
+the use of the Win32 API QueryPerformanceCounter().
+
+- Mark Hammond will release Python 1.5 versions of PythonWin and his
+other Windows specific code: the win32api extensions, COM/ActiveX
+support, and the MFC interface.
+
+
+Mac
+---
+
+- As always, the Macintosh port will be done by Jack Jansen.  He will
+make a separate announcement for the Mac specific source code and the
+binary distribution(s) when these are ready.
+
+
+======================================================================
+
+
+=====================================
+==> Release 1.4 (October 25 1996) <==
+=====================================
+
+(Starting in reverse chronological order:)
+
+- Changed disclaimer notice.
+
+- Added SHELL=/bin/sh to Misc/Makefile.pre.in -- some Make versions
+default to the user's login shell.
+
+- In Lib/tkinter/Tkinter.py, removed bogus binding of <Delete> in Text
+widget, and bogus bspace() function.
+
+- In Lib/cgi.py, bumped __version__ to 2.0 and restored a truncated
+paragraph.
+
+- Fixed the NT Makefile (PC/vc40.mak) for VC 4.0 to set /MD for all
+subprojects, and to remove the (broken) experimental NumPy
+subprojects.
+
+- In Lib/py_compile.py, cast mtime to long() so it will work on Mac
+(where os.stat() returns mtimes as floats.)
+- Set self.rfile unbuffered (like self.wfile) in SocketServer.py, to
+fix POST in CGIHTTPServer.py.
+
+- Version 2.83 of Misc/python-mode.el for Emacs is included.
+
+- In Modules/regexmodule.c, fixed symcomp() to correctly handle a new
+group starting immediately after a group tag.
+
+- In Lib/SocketServer.py, changed the mode for rfile to unbuffered.
+
+- In Objects/stringobject.c, fixed the compare function to do the
+first char comparison in unsigned mode, for consistency with the way
+other characters are compared by memcmp().
+
+- In Lib/tkinter/Tkinter.py, fixed Scale.get() to support floats.
+
+- In Lib/urllib.py, fix another case where openedurl wasn't set.
+
+(XXX Sorry, the rest is in totally random order.  No time to fix it.)
+
+- SyntaxError exceptions detected during code generation
+(e.g. assignment to an expression) now include a line number.
+
+- Don't leave trailing / or \ in script directory inserted in front of
+sys.path.
+
+- Added a note to Tools/scripts/classfix.py abouts its historical
+importance.
+
+- Added Misc/Makefile.pre.in, a universal Makefile for extensions
+built outside the distribution.
+
+- Rewritten Misc/faq2html.py, by Ka-Ping Yee.
+
+- Install shared modules with mode 555 (needed for performance on some
+platforms).
+
+- Some changes to standard library modules to avoid calling append()
+with more than one argument -- while supported, this should be
+outlawed, and I don't want to set a bad example.
+
+- bdb.py (and hence pdb.py) supports calling run() with a code object
+instead of a code string.
+
+- Fixed an embarrassing bug cgi.py which prevented correct uploading
+of binary files from Netscape (which doesn't distinguish between
+binary and text files).  Also added dormant logging support, which
+makes it easier to debug the cgi module itself.
+
+- Added default writer to constructor of NullFormatter class.
+
+- Use binary mode for socket.makefile() calls in ftplib.py.
+
+- The ihooks module no longer "installs" itself upon import -- this
+was an experimental feature that helped ironing out some bugs but that
+slowed down code that imported it without the need to install it
+(e.g. the rexec module).  Also close the file in some cases and add
+the __file__ attribute to loaded modules.
+
+- The test program for mailbox.py is now more useful.
+
+- Added getparamnames() to Message class in mimetools.py -- it returns
+the names of parameters to the content-type header.
+
+- Fixed a typo in ni that broke the loop stripping "__." from names.
+
+- Fix sys.path[0] for scripts run via pdb.py's new main program.
+
+- profile.py can now also run a script, like pdb.
+
+- Fix a small bug in pyclbr -- don't add names starting with _ when
+emulating from ... import *.
+
+- Fixed a series of embarrassing typos in rexec's handling of standard
+I/O redirection.  Added some more "safe" built-in modules: cmath,
+errno, operator.
+
+- Fixed embarrassing typo in shelve.py.
+
+- Added SliceType and EllipsisType to types.py.
+
+- In urllib.py, added handling for error 301 (same as 302); added
+geturl() method to get the URL after redirection.
+
+- Fixed embarrassing typo in xdrlib.py.  Also fixed typo in Setup.in
+for _xdrmodule.c and removed redundant #include from _xdrmodule.c.
+
+- Fixed bsddbmodule.c to add binary mode indicator on platforms that
+have it.  This should make it working on Windows NT.
+
+- Changed last uses of #ifdef NT to #ifdef MS_WINDOWS or MS_WIN32,
+whatever applies.  Also rationalized some other tests for various MS
+platforms.
+
+- Added the sources for the NT installer script used for Python
+1.4beta3.  Not tested with this release, but better than nothing.
+
+- A compromise in pickle's defenses against Trojan horses: a
+user-defined function is now okay where a class is expected.  A
+built-in function is not okay, to prevent pickling something that
+will execute os.system("rm -f *") when unpickling.
+
+- dis.py will print the name of local variables referenced by local
+load/store/delete instructions.
+
+- Improved portability of SimpleHTTPServer module to non-Unix
+platform.
+
+- The thread.h interface adds an extra argument to down_sema().  This
+only affects other C code that uses thread.c; the Python thread module
+doesn't use semaphores (which aren't provided on all platforms where
+Python threads are supported).  Note: on NT, this change is not
+implemented.
+
+- Fixed some typos in abstract.h; corrected signature of
+PyNumber_Coerce, added PyMapping_DelItem.  Also fixed a bug in
+abstract.c's PyObject_CallMethod().
+
+- apply(classname, (), {}) now works even if the class has no
+__init__() method.
+
+- Implemented complex remainder and divmod() (these would dump core!).
+Conversion of complex numbers to int, long int or float now raises an
+exception, since there is no meaningful way to do it without losing
+information.
+
+- Fixed bug in built-in complex() function which gave the wrong result
+for two real arguments.
+
+- Change the hash algorithm for strings -- the multiplier is now
+1000003 instead of 3, which gives better spread for short strings.
+
+- New default path for Windows NT, the registry structure now supports
+default paths for different install packages.  (Mark Hammond -- the
+next PythonWin release will use this.)
+
+- Added more symbols to the python_nt.def file.
+
+- When using GNU readline, set rl_readline_name to "python".
+
+- The Ellipses built-in name has been renamed to Ellipsis -- this is
+the correct singular form.  Thanks to Ka-Ping Yee, who saved us from
+eternal embarrassment.
+
+- Bumped the PYTHON_API_VERSION to 1006, due to the Ellipses ->
+Ellipsis name change.
+
+- Updated the library reference manual.  Added documentation of
+restricted mode (rexec, Bastion) and the formatter module (for use
+with the htmllib module).  Fixed the documentation of htmllib
+(finally).
+
+- The reference manual is now maintained in FrameMaker.
+
+- Upgraded scripts Doc/partparse.py and Doc/texi2html.py.
+
+- Slight improvements to Doc/Makefile.
+
+- Added fcntl.lockf(). This should be used for Unix file locking
+instead of the posixfile module; lockf() is more portable.
+
+- The getopt module now supports long option names, thanks to Lars
+Wizenius.
+
+- Plenty of changes to Tkinter and Canvas, mostly due to Fred Drake
+and Nils Fischbeck.
+
+- Use more bits of time.time() in whrandom's default seed().
+
+- Performance hack for regex module's regs attribute.
+
+- Don't close already closed socket in socket module.
+
+- Correctly handle separators containing embedded nulls in
+strop.split, strop.find and strop.rfind.  Also added more detail to
+error message for strop.atoi and friends.
+
+- Moved fallback definition for hypot() to Python/hypot.c.
+
+- Added fallback definition for strdup, in Python/strdup.c.
+
+- Fixed some bugs where a function would return 0 to indicate an error
+where it should return -1.
+
+- Test for error returned by time.localtime(), and rationalized its MS
+tests.
+
+- Added Modules/Setup.local file, which is processed after Setup.
+
+- Corrected bug in toplevel Makefile.in -- execution of regen script
+would not use the right PATH and PYTHONPATH.
+
+- Various and sundry NeXT configuration changes (sigh).
+
+- Support systems where libreadline needs neither termcap nor curses.
+
+- Improved ld_so_aix script and python.exp file (for AIX).
+
+- More stringent test for working <stdarg.h> in configure script.
+
+- Removed Demo/www subdirectory -- it was totally out of date.
+
+- Improved demos and docs for Fred Drake's parser module; fixed one
+typo in the module itself.
+
+
+=========================================
+==> Release 1.4beta3 (August 26 1996) <==
+=========================================
+
+
+(XXX This is less readable that it should.  I promise to restructure
+it for the final 1.4 release.)
+
+
+What's new in 1.4beta3 (since beta2)?
+-------------------------------------
+
+- Name mangling to implement a simple form of class-private variables.
+A name of the form "__spam" can't easily be used outside the class.
+(This was added in 1.4beta3, but left out of the 1.4beta3 release
+message.)
+
+- In urllib.urlopen(): HTTP URLs containing user:passwd at host are now
+handled correctly when using a proxy server.
+
+- In ntpath.normpath(): don't truncate to 8+3 format.
+
+- In mimetools.choose_boundary(): don't die when getuid() or getpid()
+aren't defined.
+
+- Module urllib: some optimizations to (un)quoting.
+
+- New module MimeWriter for writing MIME documents.
+
+- More changes to formatter module.
+
+- The freeze script works once again and is much more robust (using
+sys.prefix etc.).  It also supports a -o option to specify an
+output directory.
+
+- New module whichdb recognizes dbm, gdbm and bsddb/dbhash files.
+
+- The Doc/Makefile targets have been reorganized somewhat to remove the 
+insistence on always generating PostScript.
+
+- The texinfo to html filter (Doc/texi2html.py) has been improved somewhat.
+
+- "errors.h" has been renamed to "pyerrors.h" to resolve a long-standing 
+name conflict on the Mac.
+
+- Linking a module compiled with a different setting for Py_TRACE_REFS now 
+generates a linker error rather than a core dump.
+
+- The cgi module has a new convenience function print_exception(), which 
+formats a python exception using HTML.  It also fixes a bug in the 
+compatibility code and adds a dubious feature which makes it possible to 
+have two query strings, one in the URL and one in the POST data.
+
+- A subtle change in the unpickling of class instances makes it possible 
+to unpickle in restricted execution mode, where the __dict__ attribute is 
+not available (but setattr() is).
+
+- Documentation for os.path.splitext() (== posixpath.splitext()) has been 
+cleared up.  It splits at the *last* dot.
+
+- posixfile locking is now also correctly supported on AIX.
+
+- The tempfile module once again honors an initial setting of tmpdir.  It 
+now works on Windows, too.
+
+- The traceback module has some new functions to extract, format and print 
+the active stack.
+
+- Some translation functions in the urllib module have been made a little 
+less sluggish.
+
+- The addtag_* methods for Canvas widgets in Tkinter as well as in the 
+separate Canvas class have been fixed so they actually do something 
+meaningful.
+
+- A tiny _test() function has been added to Tkinter.py.
+
+- A generic Makefile for dynamically loaded modules is provided in the Misc 
+subdirectory (Misc/gMakefile).
+
+- A new version of python-mode.el for Emacs is provided.  See
+http://www.python.org/ftp/emacs/pmdetails.html for details.  The
+separate file pyimenu.el is no longer needed, imenu support is folded
+into python-mode.el.
+
+- The configure script can finally correctly find the readline library in a 
+non-standard location.  The LDFLAGS variable is passed on the Makefiles 
+from the configure script.
+
+- Shared libraries are now installed as programs (i.e. with executable 
+permission).  This is required on HP-UX and won't hurt on other systems.
+
+- The objc.c module is no longer part of the distribution.  Objective-C 
+support may become available as contributed software on the ftp site.
+
+- The sybase module is no longer part of the distribution.  A much
+improved sybase module is available as contributed software from the
+ftp site.
+
+- _tkinter is now compatible with Tcl 7.5 / Tk 4.1 patch1 on Windows and 
+Mac (don't use unpatched Tcl/Tk!).  The default line in the Setup.in file 
+now links with Tcl 7.5 / Tk 4.1 rather than 7.4/4.0.
+
+- In Setup, you can now write "*shared*" instead of "*noconfig*", and you 
+can use *.so and *.sl as shared libraries.
+
+- Some more fidgeting for AIX shared libraries.
+
+- The mpz module is now compatible with GMP 2.x.  (Not tested by me.)
+(Note -- a complete replacement by Niels Mo"ller, called gpmodule, is
+available from the contrib directory on the ftp site.)
+
+- A warning is written to sys.stderr when a __del__ method raises an 
+exception (formerly, such exceptions were completely ignored).
+
+- The configure script now defines HAVE_OLD_CPP if the C preprocessor is 
+incapable of ANSI style token concatenation and stringification.
+
+- All source files (except a few platform specific modules) are once again 
+compatible with K&R C compilers as well as ANSI compilers.  In particular,
+ANSI-isms have been removed or made conditional in complexobject.c, 
+getargs.c and operator.c.
+
+- The abstract object API has three new functions, PyObject_DelItem, 
+PySequence_DelItem, and PySequence_DelSlice.
+
+- The operator module has new functions delitem and delslice, and the 
+functions "or" and "and" are renamed to "or_" and "and_" (since "or" and 
+"and" are reserved words).  ("__or__" and "__and__" are unchanged.)
+
+- The environment module is no longer supported; putenv() is now a function 
+in posixmodule (also under NT).
+
+- Error in filter(<function>, "") has been fixed.
+
+- Unrecognized keyword arguments raise TypeError, not KeyError.
+
+- Better portability, fewer bugs and memory leaks, fewer compiler warnings, 
+some more documentation.
+
+- Bug in float power boundary case (0.0 to the negative integer power) 
+fixed.
+
+- The test of negative number to the float power has been moved from the 
+built-in pow() functin to floatobject.c (so complex numbers can yield the 
+correct result).
+
+- The bug introduced in beta2 where shared libraries loaded (using 
+dlopen()) from the current directory would fail, has been fixed.
+
+- Modules imported as shared libraries now also have a __file__ attribute, 
+giving the filename from which they were loaded.  The only modules without 
+a __file__ attribute now are built-in modules.
+
+- On the Mac, dynamically loaded modules can end in either ".slb" or 
+".<platform>.slb" where <platform> is either "CFM68K" or "ppc".  The ".slb" 
+extension should only be used for "fat" binaries.
+
+- C API addition: marshal.c now supports 
+PyMarshal_WriteObjectToString(object).
+
+- C API addition: getargs.c now supports
+PyArg_ParseTupleAndKeywords(args, kwdict, format, kwnames, ...)
+to parse keyword arguments.
+
+- The PC versioning scheme (sys.winver) has changed once again.  the 
+version number is now "<digit>.<digit>.<digit>.<apiversion>", where the 
+first three <digit>s are the Python version (e.g. "1.4.0" for Python 1.4, 
+"1.4.1" for Python 1.4.1 -- the beta level is not included) and 
+<apiversion> is the four-digit PYTHON_API_VERSION (currently 1005).
+
+- h2py.py accepts whitespace before the # in CPP directives
+
+- On Solaris 2.5, it should now be possible to use either Posix threads or 
+Solaris threads (XXX: how do you select which is used???).  (Note: the 
+Python pthreads interface doesn't fully support semaphores yet -- anyone 
+care to fix this?)
+
+- Thread support should now work on AIX, using either DCE threads or 
+pthreads.
+
+- New file Demo/sockets/unicast.py
+
+- Working Mac port, with CFM68K support, with Tk 4.1 support (though not 
+both) (XXX)
+
+- New project setup for PC port, now compatible with PythonWin, with 
+_tkinter and NumPy support (XXX)
+
+- New module site.py (XXX)
+
+- New module xdrlib.py and optional support module _xdrmodule.c (XXX)
+
+- parser module adapted to new grammar, complete w/ Doc & Demo (XXX)
+
+- regen script fixed (XXX)
+
+- new machdep subdirectories Lib/{aix3,aix4,next3_3,freebsd2,linux2} (XXX)
+
+- testall now also tests math module (XXX)
+
+- string.atoi c.s. now raise an exception for an empty input string.
+
+- At last, it is no longer necessary to define HAVE_CONFIG_H in order to 
+have config.h included at various places.
+
+- Unrecognized keyword arguments now raise TypeError rather than KeyError.
+
+- The makesetup script recognizes files with extension .so or .sl as
+(shared) libraries.
+
+- 'access' is no longer a reserved word, and all code related to its 
+implementation is gone (or at least #ifdef'ed out).  This should make 
+Python a little speedier too!
+
+- Performance enhancements suggested by Sjoerd Mullender.  This includes 
+the introduction of two new optional function pointers in type object, 
+getattro and setattro, which are like getattr and setattr but take a 
+string object instead of a C string pointer.
+
+- New operations in string module: lstrip(s) and rstrip(s) strip whitespace 
+only on the left or only on the right, A new optional third argument to 
+split() specifies the maximum number of separators honored (so 
+splitfields(s, sep, n) returns a list of at most n+1 elements).  (Since 
+1.3, splitfields(s, None) is totally equivalent to split(s).)
+string.capwords() has an optional second argument specifying the 
+separator (which is passed to split()).
+
+- regsub.split() has the same addition as string.split().  regsub.splitx(s, 
+sep, maxsep) implements the functionality that was regsub.split(s, 1) in 
+1.4beta2 (return a list containing the delimiters as well as the words).
+
+- Final touch for AIX loading, rewritten Misc/AIX-NOTES.
+
+- In Modules/_tkinter.c, when using Tk 4.1 or higher, use className
+argument to _tkinter.create() to set Tcl's argv0 variable, so X
+resources use the right resource class again.
+
+- Add #undef fabs to Modules/mathmodule.c for macintosh.
+
+- Added some macro renames for AIX in Modules/operator.c.
+
+- Removed spurious 'E' from Doc/liberrno.tex.
+
+- Got rid of some cruft in Misc/ (dlMakefile, pyimenu.el); added new
+Misc/gMakefile and new version of Misc/python-mode.el.
+
+- Fixed typo in Lib/ntpath.py (islink has "return false" which gives a
+NameError).
+
+- Added missing "from types import *" to Lib/tkinter/Canvas.py.
+
+- Added hint about using default args for __init__ to pickle docs.
+
+- Corrected typo in Inclide/abstract.h: PySequence_Lenth ->
+PySequence_Length.
+
+- Some improvements to Doc/texi2html.py.
+
+- In Python/import.c, Cast unsigned char * in struct _frozen to char *
+in calls to rds_object().
+
+- In doc/ref4.tex, added note about scope of lambda bodies.
+
+What's new in 1.4beta2 (since beta1)?
+-------------------------------------
+
+- Portability bug in the md5.h header solved.
+
+- The PC build procedure now really works, and sets sys.platform to a
+meaningful value (a few things were botched in beta 1).  Lib/dos_8x3
+is now a standard part of the distribution (alas).
+
+- More improvements to the installation procedure.  Typing "make install" 
+now inserts the version number in the pathnames of almost everything 
+installed, and creates the machine dependent modules (FCNTL.py etc.) if not 
+supplied by the distribution.  (XXX There's still a problem with the latter 
+because the "regen" script requires that Python is installed.  Some manual 
+intervention may still be required.) (This has been fixed in 1.4beta3.)
+
+- New modules: errno, operator (XXX).
+
+- Changes for use with Numerical Python: builtin function slice() and
+Ellipses object, and corresponding syntax:
+
+	x[lo:hi:stride]		==	x[slice(lo, hi, stride)]
+	x[a, ..., z]		==	x[(a, Ellipses, z)]
+
+- New documentation for errno and cgi modules.
+
+- The directory containing the script passed to the interpreter is
+inserted in from of sys.path; "." is no longer a default path
+component.
+
+- Optional third string argument to string.translate() specifies
+characters to delete.  New function string.maketrans() creates a
+translation table for translate() or for regex.compile().
+
+- Module posix (and hence module os under Unix) now supports putenv().
+Moreover, module os is enhanced so that if putenv() is supported,
+assignments to os.environ entries make the appropriate putenv() call.
+(XXX the putenv() implementation can leak a small amount of memory per
+call.)
+
+- pdb.py can now be invoked from the command line to debug a script:
+python pdb.py <script> <arg> ...
+
+- Much improved parseaddr() in rfc822.
+
+- In cgi.py, you can now pass an alternative value for environ to
+nearly all functions.
+
+- You can now assign to instance variables whose name begins and ends
+with '__'.
+
+- New version of Fred Drake's parser module and associates (token,
+symbol, AST).
+
+- New PYTHON_API_VERSION value and .pyc file magic number (again!).
+
+- The "complex" internal structure type is now called "Py_complex" to
+avoid name conflicts.
+
+- Numerous small bugs fixed.
+
+- Slight pickle speedups.
+
+- Some slight speedups suggested by Sjoerd (more coming in 1.4 final).
+
+- NeXT portability mods by Bill Bumgarner integrated.
+
+- Modules regexmodule.c, bsddbmodule.c and xxmodule.c have been
+converted to new naming style.
+
+
+What's new in 1.4beta1 (since 1.3)?
+-----------------------------------
+
+- Added sys.platform and sys.exec_platform for Bill Janssen.
+
+- Installation has been completely overhauled.  "make install" now installs 
+everything, not just the python binary.  Installation uses the install-sh 
+script (borrowed from X11) to install each file.
+
+- New functions in the posix module: mkfifo, plock, remove (== unlink),
+and ftruncate.  More functions are also available under NT.
+
+- New function in the fcntl module: flock.
+
+- Shared library support for FreeBSD.
+
+- The --with-readline option can now be used without a DIRECTORY argument, 
+for systems where libreadline.* is in one of the standard places.  It is 
+also possible for it to be a shared library.
+
+- The extension tkinter has been renamed to _tkinter, to avoid confusion 
+with Tkinter.py oncase insensitive file systems.  It now supports Tk 4.1 as 
+well as 4.0.
+
+- Author's change of address from CWI in Amsterdam, The Netherlands, to 
+CNRI in Reston, VA, USA.
+
+- The math.hypot() function is now always available (if it isn't found in 
+the C math library, Python provides its own implementation).
+
+- The latex documentation is now compatible with latex2e, thanks to David 
+Ascher.
+
+- The expression x**y is now equivalent to pow(x, y).
+
+- The indexing expression x[a, b, c] is now equivalent to x[(a, b, c)].
+
+- Complex numbers are now supported.  Imaginary constants are written with 
+a 'j' or 'J' prefix, general complex numbers can be formed by adding a real 
+part to an imaginary part, like 3+4j.  Complex numbers are always stored in 
+floating point form, so this is equivalent to 3.0+4.0j.  It is also 
+possible to create complex numbers with the new built-in function 
+complex(re, [im]).  For the footprint-conscious, complex number support can 
+be disabled by defining the symbol WITHOUT_COMPLEX.
+
+- New built-in function list() is the long-awaited counterpart of tuple().
+
+- There's a new "cmath" module which provides the same functions as the 
+"math" library but with complex arguments and results.  (There are very 
+good reasons why math.sqrt(-1) still raises an exception -- you have to use 
+cmath.sqrt(-1) to get 1j for an answer.)
+
+- The Python.h header file (which is really the same as allobjects.h except 
+it disables support for old style names) now includes several more files, 
+so you have to have fewer #include statements in the average extension.
+
+- The NDEBUG symbol is no longer used.  Code that used to be dependent on 
+the presence of NDEBUG is now present on the absence of DEBUG.  TRACE_REFS 
+and REF_DEBUG have been renamed to Py_TRACE_REFS and Py_REF_DEBUG, 
+respectively.  At long last, the source actually compiles and links without 
+errors when this symbol is defined.
+
+- Several symbols that didn't follow the new naming scheme have been 
+renamed (usually by adding to rename2.h) to use a Py or _Py prefix.  There 
+are no external symbols left without a Py or _Py prefix, not even those 
+defined by sources that were incorporated from elsewhere (regexpr.c, 
+md5c.c).  (Macros are a different story...)
+
+- There are now typedefs for the structures defined in config.c and 
+frozen.c.
+
+- New PYTHON_API_VERSION value and .pyc file magic number.
+
+- New module Bastion.  (XXX)
+
+- Improved performance of StringIO module.
+
+- UserList module now supports + and * operators.
+
+- The binhex and binascii modules now actually work.
+
+- The cgi module has been almost totally rewritten and documented.
+It now supports file upload and a new data type to handle forms more 
+flexibly.
+
+- The formatter module (for use with htmllib) has been overhauled (again).
+
+- The ftplib module now supports passive mode and has doc strings.
+
+- In (ideally) all places where binary files are read or written, the file 
+is now correctly opened in binary mode ('rb' or 'wb') so the code will work 
+on Mac or PC.
+
+- Dummy versions of os.path.expandvars() and expanduser() are now provided 
+on non-Unix platforms.
+
+- Module urllib now has two new functions url2pathname and pathname2url 
+which turn local filenames into "file:..." URLs using the same rules as 
+Netscape (why be different).  it also supports urlretrieve() with a 
+pathname parameter, and honors the proxy environment variables (http_proxy 
+etc.).  The URL parsing has been improved somewhat, too.
+
+- Micro improvements to urlparse.  Added urlparse.urldefrag() which 
+removes a trailing ``#fragment'' if any.
+
+- The mailbox module now supports MH style message delimiters as well.
+
+- The mhlib module contains some new functionality: setcontext() to set the 
+current folder and parsesequence() to parse a sequence as commonly passed 
+to MH commands (e.g. 1-10 or last:5).
+
+- New module mimify for conversion to and from MIME format of email 
+messages.
+
+- Module ni now automatically installs itself when first imported -- this 
+is against the normal rule that modules should define classes and functions 
+but not invoke them, but appears more useful in the case that two 
+different, independent modules want to use ni's features.
+
+- Some small performance enhancements in module pickle.
+
+- Small interface change to the profile.run*() family of functions -- more 
+sensible handling of return values.
+
+- The officially registered Mac creator for Python files is 'Pyth'.  This 
+replaces 'PYTH' which was used before but never registered.
+
+- Added regsub.capwords().  (XXX)
+
+- Added string.capwords(), string.capitalize() and string.translate().  
+(XXX)
+
+- Fixed an interface bug in the rexec module: it was impossible to pass a 
+hooks instance to the RExec class.  rexec now also supports the dynamic 
+loading of modules from shared libraries.  Some other interfaces have been 
+added too.
+
+- Module rfc822 now caches the headers in a dictionary for more efficient 
+lookup.
+
+- The sgmllib module now understands a limited number of SGML "shorthands" 
+like <A/.../ for <A>...</A>.  (It's not clear that this was a good idea...)
+
+- The tempfile module actually tries a number of different places to find a 
+usable temporary directory.  (This was prompted by certain Linux 
+installations that appear to be missing a /usr/tmp directory.) [A bug in 
+the implementation that would ignore a pre-existing tmpdir global has been 
+fixed in beta3.]
+
+- Much improved and enhanved FileDialog module for Tkinter.
+
+- Many small changes to Tkinter, to bring it more in line with Tk 4.0 (as 
+well as Tk 4.1).
+
+- New socket interfaces include ntohs(), ntohl(), htons(), htonl(), and 
+s.dup().  Sockets now work correctly on Windows.  On Windows, the built-in 
+extension is called _socket and a wrapper module win/socket.py provides 
+"makefile()" and "dup()" functionality.  On Windows, the select module 
+works only with socket objects.
+
+- Bugs in bsddb module fixed (e.g. missing default argument values).
+
+- The curses extension now includes <ncurses.h> when available.
+
+- The gdbm module now supports opening databases in "fast" mode by 
+specifying 'f' as the second character or the mode string.
+
+- new variables sys.prefix and sys.exec_prefix pass corresponding 
+configuration options / Makefile variables to the Python programmer.
+
+- The ``new'' module now supports creating new user-defined classes as well 
+as instances thereof.
+
+- The soundex module now sports get_soundex() to get the soundex value for an 
+arbitrary string (formerly it would only do soundex-based string 
+comparison) as well as doc strings.
+
+- New object type "cobject" to safely wrap void pointers for passing them 
+between various extension modules.
+
+- More efficient computation of float**smallint.
+
+- The mysterious bug whereby "x.x" (two occurrences of the same 
+one-character name) typed from the commandline would sometimes fail 
+mysteriously.
+
+- The initialization of the readline function can now be invoked by a C 
+extension through PyOS_ReadlineInit().
+
+- There's now an externally visible pointer PyImport_FrozenModules which 
+can be changed by an embedding application.
+
+- The argument parsing functions now support a new format character 'D' to 
+specify complex numbers.
+
+- Various memory leaks plugged and bugs fixed.
+
+- Improved support for posix threads (now that real implementations are 
+beginning to apepar).  Still no fully functioning semaphores.
+
+- Some various and sundry improvements and new entries in the Tools 
+directory.
+
+
+=====================================
+==> Release 1.3 (13 October 1995) <==
+=====================================
+
+Major change
+============
+
+Two words: Keyword Arguments.  See the first section of Chapter 12 of
+the Tutorial.
+
+(The rest of this file is textually the same as the remaining sections
+of that chapter.)
+
+
+Changes to the WWW and Internet tools
+=====================================
+
+The "htmllib" module has been rewritten in an incompatible fashion.
+The new version is considerably more complete (HTML 2.0 except forms,
+but including all ISO-8859-1 entity definitions), and easy to use.
+Small changes to "sgmllib" have also been made, to better match the
+tokenization of HTML as recognized by other web tools.
+
+A new module "formatter" has been added, for use with the new
+"htmllib" module.
+
+The "urllib"and "httplib" modules have been changed somewhat to allow
+overriding unknown URL types and to support authentication.  They now
+use "mimetools.Message" instead of "rfc822.Message" to parse headers.
+The "endrequest()" method has been removed from the HTTP class since
+it breaks the interaction with some servers.
+
+The "rfc822.Message" class has been changed to allow a flag to be
+passed in that says that the file is unseekable.
+
+The "ftplib" module has been fixed to be (hopefully) more robust on
+Linux.
+
+Several new operations that are optionally supported by servers have
+been added to "nntplib": "xover", "xgtitle", "xpath" and "date".
+
+Other Language Changes
+======================
+
+The "raise" statement now takes an optional argument which specifies
+the traceback to be used when printing the exception's stack trace.
+This must be a traceback object, such as found in "sys.exc_traceback".
+When omitted or given as "None", the old behavior (to generate a stack
+trace entry for the current stack frame) is used.
+
+The tokenizer is now more tolerant of alien whitespace.  Control-L in
+the leading whitespace of a line resets the column number to zero,
+while Control-R just before the end of the line is ignored.
+
+Changes to Built-in Operations
+==============================
+
+For file objects, "f.read(0)" and "f.readline(0)" now return an empty
+string rather than reading an unlimited number of bytes.  For the
+latter, omit the argument altogether or pass a negative value.
+
+A new system variable, "sys.platform", has been added.  It specifies
+the current platform, e.g. "sunos5" or "linux1".
+
+The built-in functions "input()" and "raw_input()" now use the GNU
+readline library when it has been configured (formerly, only
+interactive input to the interpreter itself was read using GNU
+readline).  The GNU readline library provides elaborate line editing
+and history.  The Python debugger ("pdb") is the first beneficiary of
+this change.
+
+Two new built-in functions, "globals()" and "locals()", provide access
+to dictionaries containming current global and local variables,
+respectively.  (These augment rather than replace "vars()", which
+returns the current local variables when called without an argument,
+and a module's global variables when called with an argument of type
+module.)
+
+The built-in function "compile()" now takes a third possible value for
+the kind of code to be compiled: specifying "'single'" generates code
+for a single interactive statement, which prints the output of
+expression statements that evaluate to something else than "None".
+
+Library Changes
+===============
+
+There are new module "ni" and "ihooks" that support importing modules
+with hierarchical names such as "A.B.C".  This is enabled by writing
+"import ni; ni.ni()" at the very top of the main program.  These
+modules are amply documented in the Python source.
+
+The module "rexec" has been rewritten (incompatibly) to define a class
+and to use "ihooks".
+
+The "string.split()" and "string.splitfields()" functions are now the
+same function (the presence or absence of the second argument
+determines which operation is invoked); similar for "string.join()"
+and "string.joinfields()".
+
+The "Tkinter" module and its helper "Dialog" have been revamped to use
+keyword arguments.  Tk 4.0 is now the standard.  A new module
+"FileDialog" has been added which implements standard file selection
+dialogs.
+
+The optional built-in modules "dbm" and "gdbm" are more coordinated
+--- their "open()" functions now take the same values for their "flag"
+argument, and the "flag" and "mode" argument have default values (to
+open the database for reading only, and to create the database with
+mode "0666" minuse the umask, respectively).  The memory leaks have
+finally been fixed.
+
+A new dbm-like module, "bsddb", has been added, which uses the BSD DB
+package's hash method.
+
+A portable (though slow) dbm-clone, implemented in Python, has been
+added for systems where none of the above is provided.  It is aptly
+dubbed "dumbdbm".
+
+The module "anydbm" provides a unified interface to "bsddb", "gdbm",
+"dbm", and "dumbdbm", choosing the first one available.
+
+A new extension module, "binascii", provides a variety of operations
+for conversion of text-encoded binary data.
+
+There are three new or rewritten companion modules implemented in
+Python that can encode and decode the most common such formats: "uu"
+(uuencode), "base64" and "binhex".
+
+A module to handle the MIME encoding quoted-printable has also been
+added: "quopri".
+
+The parser module (which provides an interface to the Python parser's
+abstract syntax trees) has been rewritten (incompatibly) by Fred
+Drake.  It now lets you change the parse tree and compile the result!
+
+The \code{syslog} module has been upgraded and documented.
+
+Other Changes
+=============
+
+The dynamic module loader recognizes the fact that different filenames
+point to the same shared library and loads the library only once, so
+you can have a single shared library that defines multiple modules.
+(SunOS / SVR4 style shared libraries only.)
+
+Jim Fulton's ``abstract object interface'' has been incorporated into
+the run-time API.  For more detailes, read the files
+"Include/abstract.h" and "Objects/abstract.c".
+
+The Macintosh version is much more robust now.
+
+Numerous things I have forgotten or that are so obscure no-one will
+notice them anyway :-)
+
+
+===================================
+==> Release 1.2 (13 April 1995) <==
+===================================
+
+- Changes to Misc/python-mode.el:
+  - Wrapping and indentation within triple quote strings should work
+    properly now.
+  - `Standard' bug reporting mechanism (use C-c C-b)
+  - py-mark-block was moved to C-c C-m
+  - C-c C-v shows you the python-mode version
+  - a basic python-font-lock-keywords has been added for Emacs 19
+    font-lock colorizations.
+  - proper interaction with pending-del and del-sel modes.
+  - New py-electric-colon (:) command for improved outdenting.  Also
+    py-indent-line (TAB) should handle outdented lines better.
+  - New commands py-outdent-left (C-c C-l) and py-indent-right (C-c C-r)
+
+- The Library Reference has been restructured, and many new and
+existing modules are now documented, in particular the debugger and
+the profiler, as well as the persistency and the WWW/Internet support
+modules.
+
+- All known bugs have been fixed.  For example the pow(2,2,3L) bug on
+Linux has been fixed.  Also the re-entrancy problems with __del__ have
+been fixed.
+
+- All known memory leaks have been fixed.
+
+- Phase 2 of the Great Renaming has been executed.  The header files
+now use the new names (PyObject instead of object, etc.).  The linker
+also sees the new names.  Most source files still use the old names,
+by virtue of the rename2.h header file.  If you include Python.h, you
+only see the new names.  Dynamically linked modules have to be
+recompiled.  (Phase 3, fixing the rest of the sources, will be
+executed gradually with the release later versions.)
+
+- The hooks for implementing "safe-python" (better called "restricted
+execution") are in place.  Specifically, the import statement is
+implemented by calling the built-in function __import__, and the
+built-in names used in a particular scope are taken from the
+dictionary __builtins__ in that scope's global dictionary.  See also
+the new (unsupported, undocumented) module rexec.py.
+
+- The import statement now supports the syntax "import a.b.c" and
+"from a.b.c import name".  No officially supported implementation
+exists, but one can be prototyped by replacing the built-in __import__
+function.  A proposal by Ken Manheimer is provided as newimp.py.
+
+- All machinery used by the import statement (or the built-in
+__import__ function) is now exposed through the new built-in module
+"imp" (see the library reference manual).  All dynamic loading
+machinery is moved to the new file importdl.c.
+
+- Persistent storage is supported through the use of the modules
+"pickle" and "shelve" (implemented in Python).  There's also a "copy"
+module implementing deepcopy and normal (shallow) copy operations.
+See the library reference manual.
+
+- Documentation strings for many objects types are accessible through
+the __doc__ attribute.  Modules, classes and functions support special
+syntax to initialize the __doc__ attribute: if the first statement
+consists of just a string literal, that string literal becomes the
+value of the __doc__ attribute.  The default __doc__ attribute is
+None.  Documentation strings are also supported for built-in
+functions, types and modules; however this feature hasn't been widely
+used yet.  See the 'new' module for an example.  (Basically, the type
+object's tp_doc field contains the doc string for the type, and the
+4th member of the methodlist structure contains the doc string for the
+method.)
+
+- The __coerce__ and __cmp__ methods for user-defined classes once
+again work as expected.  As an example, there's a new standard class
+Complex in the library.
+
+- The functions posix.popen() and posix.fdopen() now have an optional
+third argument to specify the buffer size, and default their second
+(mode) argument to 'r' -- in analogy to the builtin open() function.
+The same applies to posixfile.open() and the socket method makefile().
+
+- The thread.exit_thread() function now raises SystemExit so that
+'finally' clauses are honored and a memory leak is plugged.
+
+- Improved X11 and Motif support, by Sjoerd Mullender.  This extension
+is being maintained and distributed separately.
+
+- Improved support for the Apple Macintosh, in part by Jack Jansen,
+e.g. interfaces to (a few) resource mananger functions, get/set file
+type and creator, gestalt, sound manager, speech manager, MacTCP, comm
+toolbox, and the think C console library.  This is being maintained
+and distributed separately.
+
+- Improved version for Windows NT, by Mark Hammond.  This is being
+maintained and distributed separately.
+
+- Used autoconf 2.0 to generate the configure script.  Adapted
+configure.in to use the new features in autoconf 2.0.
+
+- It now builds on the NeXT without intervention, even on the 3.3
+Sparc pre-release.
+
+- Characters passed to isspace() and friends are masked to nonnegative
+values.
+
+- Correctly compute pow(-3.0, 3).
+
+- Fix portability problems with getopt (configure now checks for a
+non-GNU getopt).
+
+- Don't add frozenmain.o to libPython.a.
+
+- Exceptions can now be classes.  ALl built-in exceptions are still
+string objects, but this will change in the future.
+
+- The socket module exports a long list of socket related symbols.
+(More built-in modules will export their symbolic constants instead of
+relying on a separately generated Python module.)
+
+- When a module object is deleted, it clears out its own dictionary.
+This fixes a circularity in the references between functions and
+their global dictionary.
+
+- Changed the error handling by [new]getargs() e.g. for "O&".
+
+- Dynamic loading of modules using shared libraries is supported for
+several new platforms.
+
+- Support "O&", "[...]" and "{...}" in mkvalue().
+
+- Extension to findmethod(): findmethodinchain() (where a chain is a
+linked list of methodlist arrays).  The calling interface for
+findmethod() has changed: it now gets a pointer to the (static!)
+methodlist structure rather than just to the function name -- this
+saves copying flags etc. into the (short-lived) method object.
+
+- The callable() function is now public.
+
+- Object types can define a few new operations by setting function
+pointers in the type object structure: tp_call defines how an object
+is called, and tp_str defines how an object's str() is computed.
+
+
+===================================
+==> Release 1.1.1 (10 Nov 1994) <==
+===================================
+
+This is a pure bugfix release again.  See the ChangeLog file for details.
+
+One exception: a few new features were added to tkinter.
+
+
+=================================
+==> Release 1.1 (11 Oct 1994) <==
+=================================
+
+This release adds several new features, improved configuration and
+portability, and fixes more bugs than I can list here (including some
+memory leaks).
+
+The source compiles and runs out of the box on more platforms than
+ever -- including Windows NT.  Makefiles or projects for a variety of
+non-UNIX platforms are provided.
+
+APOLOGY: some new features are badly documented or not at all.  I had
+the choice -- postpone the new release indefinitely, or release it
+now, with working code but some undocumented areas.  The problem with
+postponing the release is that people continue to suffer from existing
+bugs, and send me patches based on the previous release -- which I
+can't apply directly because my own source has changed.  Also, some
+new modules (like signal) have been ready for release for quite some
+time, and people are anxiously waiting for them.  In the case of
+signal, the interface is simple enough to figure out without
+documentation (if you're anxious enough :-).  In this case it was not
+simple to release the module on its own, since it relies on many small
+patches elsewhere in the source.
+
+For most new Python modules, the source code contains comments that
+explain how to use them.  Documentation for the Tk interface, written
+by Matt Conway, is available as tkinter-doc.tar.gz from the Python
+home and mirror ftp sites (see Misc/FAQ for ftp addresses).  For the
+new operator overloading facilities, have a look at Demo/classes:
+Complex.py and Rat.py show how to implement a numeric type without and
+with __coerce__ method.  Also have a look at the end of the Tutorial
+document (Doc/tut.tex).  If you're still confused: use the newsgroup
+or mailing list.
+
+
+New language features:
+
+    - More flexible operator overloading for user-defined classes
+    (INCOMPATIBLE WITH PREVIOUS VERSIONS!)  See end of tutorial.
+
+    - Classes can define methods named __getattr__, __setattr__ and
+    __delattr__ to trap attribute accesses.  See end of tutorial.
+
+    - Classes can define method __call__ so instances can be called
+    directly.  See end of tutorial.
+
+
+New support facilities:
+
+    - The Makefiles (for the base interpreter as well as for extensions)
+    now support creating dynamically loadable modules if the platform
+    supports shared libraries.
+
+    - Passing the interpreter a .pyc file as script argument will execute
+    the code in that file.  (On the Mac such files can be double-clicked!)
+
+    - New Freeze script, to create independently distributable "binaries"
+    of Python programs -- look in Demo/freeze
+
+    - Improved h2py script (in Demo/scripts) follows #includes and
+    supports macros with one argument
+
+    - New module compileall generates .pyc files for all modules in a
+    directory (tree) without also executing them
+
+    - Threads should work on more platforms
+
+
+New built-in modules:
+
+    - tkinter (support for Tcl's Tk widget set) is now part of the base
+    distribution
+
+    - signal allows catching or ignoring UNIX signals (unfortunately still
+    undocumented -- any taker?)
+
+    - termios provides portable access to POSIX tty settings
+
+    - curses provides an interface to the System V curses library
+
+    - syslog provides an interface to the (BSD?) syslog daemon
+
+    - 'new' provides interfaces to create new built-in object types
+    (e.g. modules and functions)
+
+    - sybase provides an interface to SYBASE database
+
+
+New/obsolete built-in methods:
+
+    - callable(x) tests whether x can be called
+
+    - sockets now have a setblocking() method
+
+    - sockets no longer have an allowbroadcast() method
+
+    - socket methods send() and sendto() return byte count
+
+
+New standard library modules:
+
+    - types.py defines standard names for built-in types, e.g. StringType
+
+    - urlparse.py parses URLs according to the latest Internet draft
+
+    - uu.py does uuencode/uudecode (not the fastest in the world, but
+    quicker than installing uuencode on a non-UNIX machine :-)
+
+    - New, faster and more powerful profile module.py
+
+    - mhlib.py provides interface to MH folders and messages
+
+
+New facilities for extension writers (unfortunately still
+undocumented):
+
+    - newgetargs() supports optional arguments and improved error messages
+
+    - O!, O& O? formats for getargs allow more versatile type checking of
+    non-standard types
+
+    - can register pending asynchronous callback, to be called the next
+    time the Python VM begins a new instruction (Py_AddPendingCall)
+
+    - can register cleanup routines to be called when Python exits
+    (Py_AtExit)
+
+    - makesetup script understands C++ files in Setup file (use file.C
+    or file.cc)
+
+    - Make variable OPT is passed on to sub-Makefiles
+
+    - An init<module>() routine may signal an error by not entering
+    the module in the module table and raising an exception instead
+
+    - For long module names, instead of foobarbletchmodule.c you can
+    use foobarbletch.c
+
+    - getintvalue() and getfloatvalue() try to convert any object
+    instead of requiring an "intobject" or "floatobject"
+
+    - All the [new]getargs() formats that retrieve an integer value
+    will now also work if a float is passed
+
+    - C function listtuple() converts list to tuple, fast
+
+    - You should now call sigcheck() instead of intrcheck();
+    sigcheck() also sets an exception when it returns nonzero
+
+
+====================================
+==> Release 1.0.3 (14 July 1994) <==
+====================================
+
+This release consists entirely of bug fixes to the C sources; see the
+head of ../ChangeLog for a complete list.  Most important bugs fixed:
+
+- Sometimes the format operator (string%expr) would drop the last
+character of the format string
+
+- Tokenizer looped when last line did not end in \n
+
+- Bug when triple-quoted string ended in quote plus newline
+
+- Typo in socketmodule (listen) (== instead of =)
+
+- typing vars() at the >>> prompt would cause recursive output
+
+
+==================================
+==> Release 1.0.2 (4 May 1994) <==
+==================================
+
+Overview of the most visible changes.  Bug fixes are not listed.  See
+also ChangeLog.
+
+Tokens
+------
+
+* String literals follow Standard C rules: they may be continued on
+the next line using a backslash; adjacent literals are concatenated
+at compile time.
+
+* A new kind of string literals, surrounded by triple quotes (""" or
+'''), can be continued on the next line without a backslash.
+
+Syntax
+------
+
+* Function arguments may have a default value, e.g. def f(a, b=1);
+defaults are evaluated at function definition time.  This also applies
+to lambda.
+
+* The try-except statement has an optional else clause, which is
+executed when no exception occurs in the try clause.
+
+Interpreter
+-----------
+
+* The result of a statement-level expression is no longer printed,
+except_ for expressions entered interactively.  Consequently, the -k
+command line option is gone.
+
+* The result of the last printed interactive expression is assigned to
+the variable '_'.
+
+* Access to implicit global variables has been speeded up by removing
+an always-failing dictionary lookup in the dictionary of local
+variables (mod suggested by Steve Makewski and Tim Peters).
+
+* There is a new command line option, -u, to force stdout and stderr
+to be unbuffered.
+
+* Incorporated Steve Majewski's mods to import.c for dynamic loading
+under AIX.
+
+* Fewer chances of dumping core when trying to reload or re-import
+static built-in, dynamically loaded built-in, or frozen modules.
+
+* Loops over sequences now don't ask for the sequence's length when
+they start, but try to access items 0, 1, 2, and so on until they hit
+an IndexError.  This makes it possible to create classes that generate
+infinite or indefinite sequences a la Steve Majewski.  This affects
+for loops, the (not) in operator, and the built-in functions filter(),
+map(), max(), min(), reduce().
+
+Changed Built-in operations
+---------------------------
+
+* The '%' operator on strings (printf-style formatting) supports a new
+feature (adapted from a patch by Donald Beaudry) to allow
+'%(<key>)<format>' % {...} to take values from a dictionary by name
+instead of from a tuple by position (see also the new function
+vars()).
+
+* The '%s' formatting operator is changed to accept any type and
+convert it to a string using str().
+
+* Dictionaries with more than 20,000 entries can now be created
+(thanks to Steve Kirsch).
+
+New Built-in Functions
+----------------------
+
+* vars() returns a dictionary containing the local variables; vars(m)
+returns a dictionary containing the variables of module m.  Note:
+dir(x) is now equivalent to vars(x).keys().
+
+Changed Built-in Functions
+--------------------------
+
+* open() has an optional third argument to specify the buffer size: 0
+for unbuffered, 1 for line buffered, >1 for explicit buffer size, <0
+for default.
+
+* open()'s second argument is now optional; it defaults to "r".
+
+* apply() now checks that its second argument is indeed a tuple.
+
+New Built-in Modules
+--------------------
+
+Changed Built-in Modules
+------------------------
+
+The thread module no longer supports exit_prog().
+
+New Python Modules
+------------------
+
+* Module addpack contains a standard interface to modify sys.path to
+find optional packages (groups of related modules).
+
+* Module urllib contains a number of functions to access
+World-Wide-Web files specified by their URL.
+
+* Module httplib implements the client side of the HTTP protocol used
+by World-Wide-Web servers.
+
+* Module gopherlib implements the client side of the Gopher protocol.
+
+* Module mailbox (by Jack Jansen) contains a parser for UNIX and MMDF
+style mailbox files.
+
+* Module random contains various random distributions, e.g. gauss().
+
+* Module lockfile locks and unlocks open files using fcntl (inspired
+by a similar module by Andy Bensky).
+
+* Module ntpath (by Jaap Vermeulen) implements path operations for
+Windows/NT.
+
+* Module test_thread (in Lib/test) contains a small test set for the
+thread module.
+
+Changed Python Modules
+----------------------
+
+* The string module's expandvars() function is now documented and is
+implemented in Python (using regular expressions) instead of forking
+off a shell process.
+
+* Module rfc822 now supports accessing the header fields using the
+mapping/dictionary interface, e.g. h['subject'].
+
+* Module pdb now makes it possible to set a break on a function
+(syntax: break <expression>, where <expression> yields a function
+object).
+
+Changed Demos
+-------------
+
+* The Demo/scripts/freeze.py script is working again (thanks to Jaap
+Vermeulen).
+
+New Demos
+---------
+
+* Demo/threads/Generator.py is a proposed interface for restartable
+functions a la Tim Peters.
+
+* Demo/scripts/newslist.py, by Quentin Stafford-Fraser, generates a
+directory full of HTML pages which between them contain links to all
+the newsgroups available on your server.
+
+* Demo/dns contains a DNS (Domain Name Server) client.
+
+* Demo/lutz contains miscellaneous demos by Mark Lutz (e.g. psh.py, a
+nice enhanced Python shell!!!).
+
+* Demo/turing contains a Turing machine by Amrit Prem.
+
+Documentation
+-------------
+
+* Documented new language features mentioned above (but not all new
+modules).
+
+* Added a chapter to the Tutorial describing recent additions to
+Python.
+
+* Clarified some sentences in the reference manual,
+e.g. break/continue, local/global scope, slice assignment.
+
+Source Structure
+----------------
+
+* Moved Include/tokenizer.h to Parser/tokenizer.h.
+
+* Added Python/getopt.c for systems that don't have it.
+
+Emacs mode
+----------
+
+* Indentation of continuated lines is done more intelligently;
+consequently the variable py-continuation-offset is gone.
+
+
+========================================
+==> Release 1.0.1 (15 February 1994) <==
+========================================
+
+* Many portability fixes should make it painless to build Python on
+several new platforms, e.g. NeXT, SEQUENT, WATCOM, DOS, and Windows.
+
+* Fixed test for <stdarg.h> -- this broke on some platforms.
+
+* Fixed test for shared library dynalic loading -- this broke on SunOS
+4.x using the GNU loader.
+
+* Changed order and number of SVR4 networking libraries (it is now
+-lsocket -linet -lnsl, if these libraries exist).
+
+* Installing the build intermediate stages with "make libainstall" now
+also installs config.c.in, Setup and makesetup, which are used by the
+new Extensions mechanism.
+
+* Improved README file contains more hints and new troubleshooting
+section.
+
+* The built-in module strop now defines fast versions of three more
+functions of the standard string module: atoi(), atol() and atof().
+The strop versions of atoi() and atol() support an optional second
+argument to specify the base (default 10).  NOTE: you don't have to
+explicitly import strop to use the faster versions -- the string
+module contains code to let versions from stop override the default
+versions.
+
+* There is now a working Lib/dospath.py for those who use Python under
+DOS (or Windows).  Thanks, Jaap!
+
+* There is now a working Modules/dosmodule.c for DOS (or Windows)
+system calls.
+
+* Lib.os.py has been reorganized (making it ready for more operating
+systems).
+
+* Lib/ospath.py is now obsolete (use os.path instead).
+
+* Many fixes to the tutorial to make it match Python 1.0.  Thanks,
+Tim!
+
+* Fixed Doc/Makefile, Doc/README and various scripts there.
+
+* Added missing description of fdopen to Doc/libposix.tex.
+
+* Made cleanup() global, for the benefit of embedded applications.
+
+* Added parsing of addresses and dates to Lib/rfc822.py.
+
+* Small fixes to Lib/aifc.py, Lib/sunau.py, Lib/tzparse.py to make
+them usable at all.
+
+* New module Lib/wave.py reads RIFF (*.wav) audio files.
+
+* Module Lib/filewin.py moved to Lib/stdwin/filewin.py where it
+belongs.
+
+* New options and comments for Modules/makesetup (used by new
+Extension mechanism).
+
+* Misc/HYPE contains text of announcement of 1.0.0 in comp.lang.misc
+and elsewhere.
+
+* Fixed coredump in filter(None, 'abcdefg').
+
+
+=======================================
+==> Release 1.0.0 (26 January 1994) <==
+=======================================
+
+As is traditional, so many things have changed that I can't pretend to
+be complete in these release notes, but I'll try anyway :-)
+
+Note that the very last section is labeled "remaining bugs".
+
+
+Source organization and build process
+-------------------------------------
+
+* The sources have finally been split: instead of a single src
+subdirectory there are now separate directories Include, Parser,
+Grammar, Objects, Python and Modules.  Other directories also start
+with a capital letter: Misc, Doc, Lib, Demo.
+
+* A few extensions (notably Amoeba and X support) have been moved to a
+separate subtree Extensions, which is no longer in the core
+distribution, but separately ftp'able as extensions.tar.Z.  (The
+distribution contains a placeholder Ext-dummy with a description of
+the Extensions subtree as well as the most recent versions of the
+scripts used there.)
+
+* A few large specialized demos (SGI video and www) have been
+moved to a separate subdirectory Demo2, which is no longer in the core
+distribution, but separately ftp'able as demo2.tar.Z.
+
+* Parts of the standard library have been moved to subdirectories:
+there are now standard subdirectories stdwin, test, sgi and sun4.
+
+* The configuration process has radically changed: I now use GNU
+autoconf.  This makes it much easier to build on new Unix flavors, as
+well as fully supporting VPATH (if your Make has it).  The scripts
+Configure.py and Addmodule.sh are no longer needed.  Many source files
+have been adapted in order to work with the symbols that the configure
+script generated by autoconf defines (or not); the resulting source is
+much more portable to different C compilers and operating systems,
+even non Unix systems (a Mac port was done in an afternoon).  See the
+toplevel README file for a description of the new build process.
+
+* GNU readline (a slightly newer version) is now a subdirectory of the
+Python toplevel.  It is still not automatically configured (being
+totally autoconf-unaware :-).  One problem has been solved: typing
+Control-C to a readline prompt will now work.  The distribution no
+longer contains a "super-level" directory (above the python toplevel
+directory), and dl, dl-dld and GNU dld are no longer part of the
+Python distribution (you can still ftp them from
+ftp.cwi.nl:/pub/dynload).
+
+* The DOS functions have been taken out of posixmodule.c and moved
+into a separate file dosmodule.c.
+
+* There's now a separate file version.c which contains nothing but
+the version number.
+
+* The actual main program is now contained in config.c (unless NO_MAIN
+is defined); pythonmain.c now contains a function realmain() which is
+called from config.c's main().
+
+* All files needed to use the built-in module md5 are now contained in
+the distribution.  The module has been cleaned up considerably.
+
+
+Documentation
+-------------
+
+* The library manual has been split into many more small latex files,
+so it is easier to edit Doc/lib.tex file to create a custom library
+manual, describing only those modules supported on your system.  (This
+is not automated though.)
+
+* A fourth manual has been added, titled "Extending and Embedding the
+Python Interpreter" (Doc/ext.tex), which collects information about
+the interpreter which was previously spread over several files in the
+misc subdirectory.
+
+* The entire documentation is now also available on-line for those who
+have a WWW browser (e.g. NCSA Mosaic).  Point your browser to the URL
+"http://www.cwi.nl/~guido/Python.html".
+
+
+Syntax
+------
+
+* Strings may now be enclosed in double quotes as well as in single
+quotes.  There is no difference in interpretation.  The repr() of
+string objects will use double quotes if the string contains a single
+quote and no double quotes.  Thanks to Amrit Prem for these changes!
+
+* There is a new keyword 'exec'.  This replaces the exec() built-in
+function.  If a function contains an exec statement, local variable
+optimization is not performed for that particular function, thus
+making assignment to local variables in exec statements less
+confusing.  (As a consequence, os.exec and python.exec have been
+renamed to execv.)
+
+* There is a new keyword 'lambda'.  An expression of the form
+
+	lambda <parameters> : <expression>
+
+yields an anonymous function.  This is really only syntactic sugar;
+you can just as well define a local function using
+
+	def some_temporary_name(<parameters>): return <expression>
+
+Lambda expressions are particularly useful in combination with map(),
+filter() and reduce(), described below.  Thanks to Amrit Prem for
+submitting this code (as well as map(), filter(), reduce() and
+xrange())!
+
+
+Built-in functions
+------------------
+
+* The built-in module containing the built-in functions is called
+__builtin__ instead of builtin.
+
+* New built-in functions map(), filter() and reduce() perform standard
+functional programming operations (though not lazily):
+
+- map(f, seq) returns a new sequence whose items are the items from
+seq with f() applied to them.
+
+- filter(f, seq) returns a subsequence of seq consisting of those
+items for which f() is true.
+
+- reduce(f, seq, initial) returns a value computed as follows:
+	acc = initial
+	for item in seq: acc = f(acc, item)
+	return acc
+
+* New function xrange() creates a "range object".  Its arguments are
+the same as those of range(), and when used in a for loop a range
+objects also behaves identical.  The advantage of xrange() over
+range() is that its representation (if the range contains many
+elements) is much more compact than that of range().  The disadvantage
+is that the result cannot be used to initialize a list object or for
+the "Python idiom" [RED, GREEN, BLUE] = range(3).  On some modern
+architectures, benchmarks have shown that "for i in range(...): ..."
+actually executes *faster* than "for i in xrange(...): ...", but on
+memory starved machines like PCs running DOS range(100000) may be just
+too big to be represented at all...
+
+* Built-in function exec() has been replaced by the exec statement --
+see above.
+
+
+The interpreter
+---------------
+
+* Syntax errors are now not printed to stderr by the parser, but
+rather the offending line and other relevant information are packed up
+in the SyntaxError exception argument.  When the main loop catches a
+SyntaxError exception it will print the error in the same format as
+previously, but at the proper position in the stack traceback.
+
+* You can now set a maximum to the number of traceback entries
+printed by assigning to sys.tracebacklimit.  The default is 1000.
+
+* The version number in .pyc files has changed yet again.
+
+* It is now possible to have a .pyc file without a corresponding .py
+file.  (Warning: this may break existing installations if you have an
+old .pyc file lingering around somewhere on your module search path
+without a corresponding .py file, when there is a .py file for a
+module of the same name further down the path -- the new interpreter
+will find the first .pyc file and complain about it, while the old
+interpreter would ignore it and use the .py file further down.)
+
+* The list sys.builtin_module_names is now sorted and also contains
+the names of a few hardwired built-in modules (sys, __main__ and
+__builtin__).
+
+* A module can now find its own name by accessing the global variable
+__name__.  Assigning to this variable essentially renames the module
+(it should also be stored under a different key in sys.modules).
+A neat hack follows from this: a module that wants to execute a main
+program when called as a script no longer needs to compare
+sys.argv[0]; it can simply do "if __name__ == '__main__': main()".
+
+* When an object is printed by the print statement, its implementation
+of str() is used.  This means that classes can define __str__(self) to
+direct how their instances are printed.  This is different from
+__repr__(self), which should define an unambigous string
+representation of the instance.  (If __str__() is not defined, it
+defaults to __repr__().)
+
+* Functions and code objects can now be compared meaningfully.
+
+* On systems supporting SunOS or SVR4 style shared libraries, dynamic
+loading of modules using shared libraries is automatically configured.
+Thanks to Bill Jansen and Denis Severson for contributing this change!
+
+
+Built-in objects
+----------------
+
+* File objects have acquired a new method writelines() which is the
+reverse of readlines().  (It does not actually write lines, just a
+list of strings, but the symmetry makes the choice of name OK.)
+
+
+Built-in modules
+----------------
+
+* Socket objects no longer support the avail() method.  Use the select
+module instead, or use this function to replace it:
+
+	def avail(f):
+		import select
+		return f in select.select([f], [], [], 0)[0]
+
+* Initialization of stdwin is done differently.  It actually modifies
+sys.argv (taking out the options the X version of stdwin recognizes)
+the first time it is imported.
+
+* A new built-in module parser provides a rudimentary interface to the
+python parser.  Corresponding standard library modules token and symbol
+defines the numeric values of tokens and non-terminal symbols.
+
+* The posix module has aquired new functions setuid(), setgid(),
+execve(), and exec() has been renamed to execv().
+
+* The array module is extended with 8-byte object swaps, the 'i'
+format character, and a reverse() method.  The read() and write()
+methods are renamed to fromfile() and tofile().
+
+* The rotor module has freed of portability bugs.  This introduces a
+backward compatibility problem: strings encoded with the old rotor
+module can't be decoded by the new version.
+
+* For select.select(), a timeout (4th) argument of None means the same
+as leaving the timeout argument out.
+
+* Module strop (and hence standard library module string) has aquired
+a new function: rindex().  Thanks to Amrit Prem!
+
+* Module regex defines a new function symcomp() which uses an extended
+regular expression syntax: parenthesized subexpressions may be labeled
+using the form "\(<labelname>...\)", and the group() method can return
+sub-expressions by name.  Thanks to Tracy Tims for these changes!
+
+* Multiple threads are now supported on Solaris 2.  Thanks to Sjoerd
+Mullender!
+
+
+Standard library modules
+------------------------
+
+* The library is now split in several subdirectories: all stuff using
+stdwin is in Lib/stdwin, all SGI specific (or SGI Indigo or GL) stuff
+is in Lib/sgi, all Sun Sparc specific stuff is in Lib/sun4, and all
+test modules are in Lib/test.  The default module search path will
+include all relevant subdirectories by default.
+
+* Module os now knows about trying to import dos.  It defines
+functions execl(), execle(), execlp() and execvp().
+
+* New module dospath (should be attacked by a DOS hacker though).
+
+* All modules defining classes now define __init__() constructors
+instead of init() methods.  THIS IS AN INCOMPATIBLE CHANGE!
+
+* Some minor changes and bugfixes module ftplib (mostly Steve
+Majewski's suggestions); the debug() method is renamed to
+set_debuglevel().
+
+* Some new test modules (not run automatically by testall though):
+test_audioop, test_md5, test_rgbimg, test_select.
+
+* Module string now defines rindex() and rfind() in analogy of index()
+and find().  It also defines atof() and atol() (and corresponding
+exceptions) in analogy to atoi().
+
+* Added help() functions to modules profile and pdb.
+
+* The wdb debugger (now in Lib/stdwin) now shows class or instance
+variables on a double click.  Thanks to Sjoerd Mullender!
+
+* The (undocumented) module lambda has gone -- you couldn't import it
+any more, and it was basically more a demo than a library module...
+
+
+Multimedia extensions
+---------------------
+
+* The optional built-in modules audioop and imageop are now standard
+parts of the interpreter.  Thanks to Sjoerd Mullender and Jack Jansen
+for contributing this code!
+
+* There's a new operation in audioop: minmax().
+
+* There's a new built-in module called rgbimg which supports portable
+efficient reading of SGI RCG image files.  Thanks also to Paul
+Haeberli for the original code!  (Who will contribute a GIF reader?)
+
+* The module aifc is gone -- you should now always use aifc, which has
+received a facelift.
+
+* There's a new module sunau., for reading Sun (and NeXT) audio files.
+
+* There's a new module audiodev which provides a uniform interface to
+(SGI Indigo and Sun Sparc) audio hardware.
+
+* There's a new module sndhdr which recognizes various sound files by
+looking in their header and checking for various magic words.
+
+
+Optimizations
+-------------
+
+* Most optimizations below can be configured by compile-time flags.
+Thanks to Sjoerd Mullender for submitting these optimizations!
+
+* Small integers (default -1..99) are shared -- i.e. if two different
+functions compute the same value it is possible (but not
+guaranteed!!!) that they return the same *object*.  Python programs
+can detect this but should *never* rely on it.
+
+* Empty tuples (which all compare equal) are shared in the same
+manner.
+
+* Tuples of size up to 20 (default) are put in separate free lists
+when deallocated.
+
+* There is a compile-time option to cache a string's hash function,
+but this appeared to have a negligeable effect, and as it costs 4
+bytes per string it is disabled by default.
+
+
+Embedding Python
+----------------
+
+* The initialization interface has been simplified somewhat.  You now
+only call "initall()" to initialize the interpreter.
+
+* The previously announced renaming of externally visible identifiers
+has not been carried out.  It will happen in a later release.  Sorry.
+
+
+Miscellaneous bugs that have been fixed
+---------------------------------------
+
+* All known portability bugs.
+
+* Version 0.9.9 dumped core in <listobject>.sort() which has been
+fixed.  Thanks to Jaap Vermeulen for fixing this and posting the fix
+on the mailing list while I was away!
+
+* Core dump on a format string ending in '%', e.g. in the expression
+'%' % None.
+
+* The array module yielded a bogus result for concatenation (a+b would
+yield a+a).
+
+* Some serious memory leaks in strop.split() and strop.splitfields().
+
+* Several problems with the nis module.
+
+* Subtle problem when copying a class method from another class
+through assignment (the method could not be called).
+
+
+Remaining bugs
+--------------
+
+* One problem with 64-bit machines remains -- since .pyc files are
+portable and use only 4 bytes to represent an integer object, 64-bit
+integer literals are silently truncated when written into a .pyc file.
+Work-around: use eval('123456789101112').
+
+* The freeze script doesn't work any more.  A new and more portable
+one can probably be cooked up using tricks from Extensions/mkext.py.
+
+* The dos support hasn't been tested yet.  (Really Soon Now we should
+have a PC with a working C compiler!)
+
+
+===================================
+==> Release 0.9.9 (29 Jul 1993) <==
+===================================
+
+I *believe* these are the main user-visible changes in this release,
+but there may be others.  SGI users may scan the {src,lib}/ChangeLog
+files for improvements of some SGI specific modules, e.g. aifc and
+cl.  Developers of extension modules should also read src/ChangeLog.
+
+
+Naming of C symbols used by the Python interpreter
+--------------------------------------------------
+
+* This is the last release using the current naming conventions.  New
+naming conventions are explained in the file misc/NAMING.
+Summarizing, all externally visible symbols get (at least) a "Py"
+prefix, and most functions are renamed to the standard form
+PyModule_FunctionName.
+
+* Writers of extensions are urged to start using the new naming
+conventions.  The next release will use the new naming conventions
+throughout (it will also have a different source directory
+structure).
+
+* As a result of the preliminary work for the great renaming, many
+functions that were accidentally global have been made static.
+
+
+BETA X11 support
+----------------
+
+* There are now modules interfacing to the X11 Toolkit Intrinsics, the
+Athena widgets, and the Motif 1.1 widget set.  These are not yet
+documented except through the examples and README file in the demo/x11
+directory.  It is expected that this interface will be replaced by a
+more powerful and correct one in the future, which may or may not be
+backward compatible.  In other words, this part of the code is at most
+BETA level software!  (Note: the rest of Python is rock solid as ever!)
+
+* I understand that the above may be a bit of a disappointment,
+however my current schedule does not allow me to change this situation
+before putting the release out of the door.  By releasing it
+undocumented and buggy, at least some of the (working!) demo programs,
+like itr (my Internet Talk Radio browser) become available to a larger
+audience.
+
+* There are also modules interfacing to SGI's "Glx" widget (a GL
+window wrapped in a widget) and to NCSA's "HTML" widget (which can
+format HyperText Markup Language, the document format used by the
+World Wide Web).
+
+* I've experienced some problems when building the X11 support.  In
+particular, the Xm and Xaw widget sets don't go together, and it
+appears that using X11R5 is better than using X11R4.  Also the threads
+module and its link time options may spoil things.  My own strategy is
+to build two Python binaries: one for use with X11 and one without
+it, which can contain a richer set of built-in modules.  Don't even
+*think* of loading the X11 modules dynamically...
+
+
+Environmental changes
+---------------------
+
+* Compiled files (*.pyc files) created by this Python version are
+incompatible with those created by the previous version.  Both
+versions detect this and silently create a correct version, but it
+means that it is not a good idea to use the same library directory for
+an old and a new interpreter, since they will start to "fight" over
+the *.pyc files...
+
+* When a stack trace is printed, the exception is printed last instead
+of first.  This means that if the beginning of the stack trace
+scrolled out of your window you can still see what exception caused
+it.
+
+* Sometimes interrupting a Python operation does not work because it
+hangs in a blocking system call.  You can now kill the interpreter by
+interrupting it three times.  The second time you interrupt it, a
+message will be printed telling you that the third interrupt will kill
+the interpreter.  The "sys.exitfunc" feature still makes limited
+clean-up possible in this case.
+
+
+Changes to the command line interface
+-------------------------------------
+
+* The python usage message is now much more informative.
+
+* New option -i enters interactive mode after executing a script --
+useful for debugging.
+
+* New option -k raises an exception when an expression statement
+yields a value other than None.
+
+* For each option there is now also a corresponding environment
+variable.
+
+
+Using Python as an embedded language
+------------------------------------
+
+* The distribution now contains (some) documentation on the use of
+Python as an "embedded language" in other applications, as well as a
+simple example.  See the file misc/EMBEDDING and the directory embed/.
+
+
+Speed improvements
+------------------
+
+* Function local variables are now generally stored in an array and
+accessed using an integer indexing operation, instead of through a
+dictionary lookup.  (This compensates the somewhat slower dictionary
+lookup caused by the generalization of the dictionary module.)
+
+
+Changes to the syntax
+---------------------
+
+* Continuation lines can now *sometimes* be written without a
+backslash: if the continuation is contained within nesting (), [] or
+{} brackets the \ may be omitted.  There's a much improved
+python-mode.el in the misc directory which knows about this as well.
+
+* You can no longer use an empty set of parentheses to define a class
+without base classes.  That is, you no longer write this:
+
+	class Foo(): # syntax error
+		...
+
+You must write this instead:
+
+	class Foo:
+		...
+
+This was already the preferred syntax in release 0.9.8 but many
+people seemed not to have picked it up.  There's a Python script that
+fixes old code: demo/scripts/classfix.py.
+
+* There's a new reserved word: "access".  The syntax and semantics are
+still subject of of research and debate (as well as undocumented), but
+the parser knows about the keyword so you must not use it as a
+variable, function, or attribute name.
+
+
+Changes to the semantics of the language proper
+-----------------------------------------------
+
+* The following compatibility hack is removed: if a function was
+defined with two or more arguments, and called with a single argument
+that was a tuple with just as many arguments, the items of this tuple
+would be used as the arguments.  This is no longer supported.
+
+
+Changes to the semantics of classes and instances
+-------------------------------------------------
+
+* Class variables are now also accessible as instance variables for
+reading (assignment creates an instance variable which overrides the
+class variable of the same name though).
+
+* If a class attribute is a user-defined function, a new kind of
+object is returned: an "unbound method".  This contains a pointer to
+the class and can only be called with a first argument which is a
+member of that class (or a derived class).
+
+* If a class defines a method __init__(self, arg1, ...) then this
+method is called when a class instance is created by the classname()
+construct.  Arguments passed to classname() are passed to the
+__init__() method.  The __init__() methods of base classes are not
+automatically called; the derived __init__() method must call these if
+necessary (this was done so the derived __init__() method can choose
+the call order and arguments for the base __init__() methods).
+
+* If a class defines a method __del__(self) then this method is called
+when an instance of the class is about to be destroyed.  This makes it
+possible to implement clean-up of external resources attached to the
+instance.  As with __init__(), the __del__() methods of base classes
+are not automatically called.  If __del__ manages to store a reference
+to the object somewhere, its destruction is postponed; when the object
+is again about to be destroyed its __del__() method will be called
+again.
+
+* Classes may define a method __hash__(self) to allow their instances
+to be used as dictionary keys.  This must return a 32-bit integer.
+
+
+Minor improvements
+------------------
+
+* Function and class objects now know their name (the name given in
+the 'def' or 'class' statement that created them).
+
+* Class instances now know their class name.
+
+
+Additions to built-in operations
+--------------------------------
+
+* The % operator with a string left argument implements formatting
+similar to sprintf() in C.  The right argument is either a single
+value or a tuple of values.  All features of Standard C sprintf() are
+supported except %p.
+
+* Dictionaries now support almost any key type, instead of just
+strings.  (The key type must be an immutable type or must be a class
+instance where the class defines a method __hash__(), in order to
+avoid losing track of keys whose value may change.)
+
+* Built-in methods are now compared properly: when comparing x.meth1
+and y.meth2, if x is equal to y and the methods are defined by the
+same function, x.meth1 compares equal to y.meth2.
+
+
+Additions to built-in functions
+-------------------------------
+
+* str(x) returns a string version of its argument.  If the argument is
+a string it is returned unchanged, otherwise it returns `x`.
+
+* repr(x) returns the same as `x`.  (Some users found it easier to
+have this as a function.)
+
+* round(x) returns the floating point number x rounded to an whole
+number, represented as a floating point number.  round(x, n) returns x
+rounded to n digits.
+
+* hasattr(x, name) returns true when x has an attribute with the given
+name.
+
+* hash(x) returns a hash code (32-bit integer) of an arbitrary
+immutable object's value.
+
+* id(x) returns a unique identifier (32-bit integer) of an arbitrary
+object.
+
+* compile() compiles a string to a Python code object.
+
+* exec() and eval() now support execution of code objects.
+
+
+Changes to the documented part of the library (standard modules)
+----------------------------------------------------------------
+
+* os.path.normpath() (a.k.a. posixpath.normpath()) has been fixed so
+the border case '/foo/..' returns '/' instead of ''.
+
+* A new function string.find() is added with similar semantics to
+string.index(); however when it does not find the given substring it
+returns -1 instead of raising string.index_error.
+
+
+Changes to built-in modules
+---------------------------
+
+* New optional module 'array' implements operations on sequences of
+integers or floating point numbers of a particular size.  This is
+useful to manipulate large numerical arrays or to read and write
+binary files consisting of numerical data.
+
+* Regular expression objects created by module regex now support a new
+method named group(), which returns one or more \(...\) groups by number.
+The number of groups is increased from 10 to 100.
+
+* Function compile() in module regex now supports an optional mapping
+argument; a variable casefold is added to the module which can be used
+as a standard uppercase to lowercase mapping.
+
+* Module time now supports many routines that are defined in the
+Standard C time interface (<time.h>): gmtime(), localtime(),
+asctime(), ctime(), mktime(), as well as these variables (taken from
+System V): timezone, altzone, daylight and tzname.  (The corresponding
+functions in the undocumented module calendar have been removed; the
+undocumented and unfinished module tzparse is now obsolete and will
+disappear in a future release.)
+
+* Module strop (the fast built-in version of standard module string)
+now uses C's definition of whitespace instead of fixing it to space,
+tab and newline; in practice this usually means that vertical tab,
+form feed and return are now also considered whitespace.  It exports
+the string of characters that are considered whitespace as well as the
+characters that are considered lowercase or uppercase.
+
+* Module sys now defines the variable builtin_module_names, a list of
+names of modules built into the current interpreter (including not
+yet imported, but excluding two special modules that always have to be
+defined -- sys and builtin).
+
+* Objects created by module sunaudiodev now also support flush() and
+close() methods.
+
+* Socket objects created by module socket now support an optional
+flags argument for their methods sendto() and recvfrom().
+
+* Module marshal now supports dumping to and loading from strings,
+through the functions dumps() and loads().
+
+* Module stdwin now supports some new functionality.  You may have to
+ftp the latest version: ftp.cwi.nl:/pub/stdwin/stdwinforviews.tar.Z.)
+
+
+Bugs fixed
+----------
+
+* Fixed comparison of negative long integers.
+
+* The tokenizer no longer botches input lines longer than BUFSIZ.
+
+* Fixed several severe memory leaks in module select.
+
+* Fixed memory leaks in modules socket and sv.
+
+* Fixed memory leak in divmod() for long integers.
+
+* Problems with definition of floatsleep() on Suns fixed.
+
+* Many portability bugs fixed (and undoubtedly new ones added :-).
+
+
+Changes to the build procedure
+------------------------------
+
+* The Makefile supports some new targets: "make default" and "make
+all".  Both are by normally equivalent to "make python".
+
+* The Makefile no longer uses $> since it's not supported by all
+versions of Make.
+
+* The header files now all contain #ifdef constructs designed to make
+it safe to include the same header file twice, as well as support for
+inclusion from C++ programs (automatic extern "C" { ... } added).
+
+
+Freezing Python scripts
+-----------------------
+
+* There is now some support for "freezing" a Python script as a
+stand-alone executable binary file.  See the script
+demo/scripts/freeze.py.  It will require some site-specific tailoring
+of the script to get this working, but is quite worthwhile if you write
+Python code for other who may not have built and installed Python.
+
+
+MS-DOS
+------
+
+* A new MS-DOS port has been done, using MSC 6.0 (I believe).  Thanks,
+Marcel van der Peijl!  This requires fewer compatibility hacks in
+posixmodule.c.  The executable is not yet available but will be soon
+(check the mailing list).
+
+* The default PYTHONPATH has changed.
+
+
+Changes for developers of extension modules
+-------------------------------------------
+
+* Read src/ChangeLog for full details.
+
+
+SGI specific changes
+--------------------
+
+* Read src/ChangeLog for full details.
+
+
+==================================
+==> Release 0.9.8 (9 Jan 1993) <==
+==================================
+
+I claim no completeness here, but I've tried my best to scan the log
+files throughout my source tree for interesting bits of news.  A more
+complete account of the changes is to be found in the various
+ChangeLog files. See also "News for release 0.9.7beta" below if you're
+still using release 0.9.6, and the file HISTORY if you have an even
+older release.
+
+	--Guido
+
+
+Changes to the language proper
+------------------------------
+
+There's only one big change: the conformance checking for function
+argument lists (of user-defined functions only) is stricter.  Earlier,
+you could get away with the following:
+
+	(a) define a function of one argument and call it with any
+	    number of arguments; if the actual argument count wasn't
+	    one, the function would receive a tuple containing the
+	    arguments arguments (an empty tuple if there were none).
+
+	(b) define a function of two arguments, and call it with more
+	    than two arguments; if there were more than two arguments,
+	    the second argument would be passed as a tuple containing
+	    the second and further actual arguments.
+
+(Note that an argument (formal or actual) that is a tuple is counted as
+one; these rules don't apply inside such tuples, only at the top level
+of the argument list.)
+
+Case (a) was needed to accommodate variable-length argument lists;
+there is now an explicit "varargs" feature (precede the last argument
+with a '*').  Case (b) was needed for compatibility with old class
+definitions: up to release 0.9.4 a method with more than one argument
+had to be declared as "def meth(self, (arg1, arg2, ...)): ...".
+Version 0.9.6 provide better ways to handle both casees, bot provided
+backward compatibility; version 0.9.8 retracts the compatibility hacks
+since they also cause confusing behavior if a function is called with
+the wrong number of arguments.
+
+There's a script that helps converting classes that still rely on (b),
+provided their methods' first argument is called "self":
+demo/scripts/methfix.py.
+
+If this change breaks lots of code you have developed locally, try
+#defining COMPAT_HACKS in ceval.c.
+
+(There's a third compatibility hack, which is the reverse of (a): if a
+function is defined with two or more arguments, and called with a
+single argument that is a tuple with just as many arguments, the items
+of this tuple will be used as the arguments.  Although this can (and
+should!) be done using the built-in function apply() instead, it isn't
+withdrawn yet.)
+
+
+One minor change: comparing instance methods works like expected, so
+that if x is an instance of a user-defined class and has a method m,
+then (x.m==x.m) yields 1.
+
+
+The following was already present in 0.9.7beta, but not explicitly
+mentioned in the NEWS file: user-defined classes can now define types
+that behave in almost allrespects like numbers.  See
+demo/classes/Rat.py for a simple example.
+
+
+Changes to the build process
+----------------------------
+
+The Configure.py script and the Makefile has been made somewhat more
+bullet-proof, after reports of (minor) trouble on certain platforms.
+
+There is now a script to patch Makefile and config.c to add a new
+optional built-in module: Addmodule.sh.  Read the script before using!
+
+Useing Addmodule.sh, all optional modules can now be configured at
+compile time using Configure.py, so there are no modules left that
+require dynamic loading.
+
+The Makefile has been fixed to make it easier to use with the VPATH
+feature of some Make versions (e.g. SunOS).
+
+
+Changes affecting portability
+-----------------------------
+
+Several minor portability problems have been solved, e.g. "malloc.h"
+has been renamed to "mymalloc.h", "strdup.c" is no longer used, and
+the system now tolerates malloc(0) returning 0.
+
+For dynamic loading on the SGI, Jack Jansen's dl 1.6 is now
+distributed with Python.  This solves several minor problems, in
+particular scripts invoked using #! can now use dynamic loading.
+
+
+Changes to the interpreter interface
+------------------------------------
+
+On popular demand, there's finally a "profile" feature for interactive
+use of the interpreter.  If the environment variable $PYTHONSTARTUP is
+set to the name of an existing file, Python statements in this file
+are executed when the interpreter is started in interactive mode.
+
+There is a new clean-up mechanism, complementing try...finally: if you
+assign a function object to sys.exitfunc, it will be called when
+Python exits or receives a SIGTERM or SIGHUP signal.
+
+The interpreter is now generally assumed to live in
+/usr/local/bin/python (as opposed to /usr/local/python).  The script
+demo/scripts/fixps.py will update old scripts in place (you can easily
+modify it to do other similar changes).
+
+Most I/O that uses sys.stdin/stdout/stderr will now use any object
+assigned to those names as long as the object supports readline() or
+write() methods.
+
+The parser stack has been increased to 500 to accommodate more
+complicated expressions (7 levels used to be the practical maximum,
+it's now about 38).
+
+The limit on the size of the *run-time* stack has completely been
+removed -- this means that tuple or list displays can contain any
+number of elements (formerly more than 50 would crash the
+interpreter). 
+
+
+Changes to existing built-in functions and methods
+--------------------------------------------------
+
+The built-in functions int(), long(), float(), oct() and hex() now
+also apply to class instalces that define corresponding methods
+(__int__ etc.).
+
+
+New built-in functions
+----------------------
+
+The new functions str() and repr() convert any object to a string.
+The function repr(x) is in all respects equivalent to `x` -- some
+people prefer a function for this.  The function str(x) does the same
+except if x is already a string -- then it returns x unchanged
+(repr(x) adds quotes and escapes "funny" characters as octal escapes).
+
+The new function cmp(x, y) returns -1 if x<y, 0 if x==y, 1 if x>y.
+
+
+Changes to general built-in modules
+-----------------------------------
+
+The time module's functions are more general: time() returns a
+floating point number and sleep() accepts one.  Their accuracies
+depends on the precision of the system clock.  Millisleep is no longer
+needed (although it still exists for now), but millitimer is still
+needed since on some systems wall clock time is only available with
+seconds precision, while a source of more precise time exists that
+isn't synchronized with the wall clock.  (On UNIX systems that support
+the BSD gettimeofday() function, time.time() is as time.millitimer().)
+
+The string representation of a file object now includes an address:
+'<file 'filename', mode 'r' at #######>' where ###### is a hex number
+(the object's address) to make it unique.
+
+New functions added to posix: nice(), setpgrp(), and if your system
+supports them: setsid(), setpgid(), tcgetpgrp(), tcsetpgrp().
+
+Improvements to the socket module: socket objects have new methods
+getpeername() and getsockname(), and the {get,set}sockopt methods can
+now get/set any kind of option using strings built with the new struct
+module.  And there's a new function fromfd() which creates a socket
+object given a file descriptor (useful for servers started by inetd,
+which have a socket connected to stdin and stdout).
+
+
+Changes to SGI-specific built-in modules
+----------------------------------------
+
+The FORMS library interface (fl) now requires FORMS 2.1a.  Some new
+functions have been added and some bugs have been fixed.
+
+Additions to al (audio library interface): added getname(),
+getdefault() and getminmax().
+
+The gl modules doesn't call "foreground()" when initialized (this
+caused some problems) like it dit in 0.9.7beta (but not before).
+There's a new gl function 'gversion() which returns a version string.
+
+The interface to sv (Indigo video interface) has totally changed.
+(Sorry, still no documentation, but see the examples in
+demo/sgi/{sv,video}.)
+
+
+Changes to standard library modules
+-----------------------------------
+
+Most functions in module string are now much faster: they're actually
+implemented in C.  The module containing the C versions is called
+"strop" but you should still import "string" since strop doesn't
+provide all the interfaces defined in string (and strop may be renamed
+to string when it is complete in a future release).
+
+string.index() now accepts an optional third argument giving an index
+where to start searching in the first argument, so you can find second
+and further occurrences (this is similar to the regular expression
+functions in regex).
+
+The definition of what string.splitfields(anything, '') should return
+is changed for the last time: it returns a singleton list containing
+its whole first argument unchanged.  This is compatible with
+regsub.split() which also ignores empty delimiter matches.
+
+posixpath, macpath: added dirname() and normpath() (and basename() to
+macpath).
+
+The mainloop module (for use with stdwin) can now demultiplex input
+from other sources, as long as they can be polled with select().
+
+
+New built-in modules
+--------------------
+
+Module struct defines functions to pack/unpack values to/from strings
+representing binary values in native byte order.
+
+Module strop implements C versions of many functions from string (see
+above).
+
+Optional module fcntl defines interfaces to fcntl() and ioctl() --
+UNIX only.  (Not yet properly documented -- see however src/fcntl.doc.)
+
+Optional module mpz defines an interface to an altaernative long
+integer implementation, the GNU MPZ library.
+
+Optional module md5 uses the GNU MPZ library to calculate MD5
+signatures of strings.
+
+There are also optional new modules specific to SGI machines: imageop
+defines some simple operations to images represented as strings; sv
+interfaces to the Indigo video board; cl interfaces to the (yet
+unreleased) compression library.
+
+
+New standard library modules
+----------------------------
+
+(Unfortunately the following modules are not all documented; read the
+sources to find out more about them!)
+
+autotest: run testall without showing any output unless it differs
+from the expected output
+
+bisect: use bisection to insert or find an item in a sorted list
+
+colorsys: defines conversions between various color systems (e.g. RGB
+<-> YUV)
+
+nntplib: a client interface to NNTP servers
+
+pipes: utility to construct pipeline from templates, e.g. for
+conversion from one file format to another using several utilities.
+
+regsub: contains three functions that are more or less compatible with
+awk functions of the same name: sub() and gsub() do string
+substitution, split() splits a string using a regular expression to
+define how separators are define.
+
+test_types: test operations on the built-in types of Python
+
+toaiff: convert various audio file formats to AIFF format
+
+tzparse: parse the TZ environment parameter (this may be less general
+than it could be, let me know if you fix it).
+
+(Note that the obsolete module "path" no longer exists.)
+
+
+New SGI-specific library modules
+--------------------------------
+
+CL: constants for use with the built-in compression library interface (cl)
+
+Queue: a multi-producer, multi-consumer queue class implemented for
+use with the built-in thread module
+
+SOCKET: constants for use with built-in module socket, e.g. to set/get
+socket options.  This is SGI-specific because the constants to be
+passed are system-dependent.  You can generate a version for your own
+system by running the script demo/scripts/h2py.py with
+/usr/include/sys/socket.h as input.
+
+cddb: interface to the database used by the CD player
+
+torgb: convert various image file types to rgb format (requires pbmplus)
+
+
+New demos
+---------
+
+There's an experimental interface to define Sun RPC clients and
+servers in demo/rpc.
+
+There's a collection of interfaces to WWW, WAIS and Gopher (both
+Python classes and program providing a user interface) in demo/www.
+This includes a program texi2html.py which converts texinfo files to
+HTML files (the format used hy WWW).
+
+The ibrowse demo has moved from demo/stdwin/ibrowse to demo/ibrowse.
+
+For SGI systems, there's a whole collection of programs and classes
+that make use of the Indigo video board in demo/sgi/{sv,video}.  This
+represents a significant amount of work that we're giving away!
+
+There are demos "rsa" and "md5test" that exercise the mpz and md5
+modules, respectively.  The rsa demo is a complete implementation of
+the RSA public-key cryptosystem!
+
+A bunch of games and examples submitted by Stoffel Erasmus have been
+included in demo/stoffel.
+
+There are miscellaneous new files in some existing demo
+subdirectories: classes/bitvec.py, scripts/{fixps,methfix}.py,
+sgi/al/cmpaf.py, sockets/{mcast,gopher}.py.
+
+There are also many minor changes to existing files, but I'm too lazy
+to run a diff and note the differences -- you can do this yourself if
+you save the old distribution's demos.  One highlight: the
+stdwin/python.py demo is much improved!
+
+
+Changes to the documentation
+----------------------------
+
+The LaTeX source for the library uses different macros to enable it to
+be converted to texinfo, and from there to INFO or HTML format so it
+can be browsed as a hypertext.  The net result is that you can now
+read the Python library documentation in Emacs info mode!
+
+
+Changes to the source code that affect C extension writers
+----------------------------------------------------------
+
+The function strdup() no longer exists (it was used only in one places
+and is somewhat of a a portability problem sice some systems have the
+same function in their C library.
+
+The functions NEW() and RENEW() allocate one spare byte to guard
+against a NULL return from malloc(0) being taken for an error, but
+this should not be relied upon.
+
+
+=========================
+==> Release 0.9.7beta <==
+=========================
+
+
+Changes to the language proper
+------------------------------
+
+User-defined classes can now implement operations invoked through
+special syntax, such as x[i] or `x` by defining methods named
+__getitem__(self, i) or __repr__(self), etc.
+
+
+Changes to the build process
+----------------------------
+
+Instead of extensive manual editing of the Makefile to select
+compile-time options, you can now run a Configure.py script.
+The Makefile as distributed builds a minimal interpreter sufficient to
+run Configure.py.  See also misc/BUILD
+
+The Makefile now includes more "utility" targets, e.g. install and
+tags/TAGS
+
+Using the provided strtod.c and strtol.c are now separate options, as
+on the Sun the provided strtod.c dumps core :-(
+
+The regex module is now an option chosen by the Makefile, since some
+(old) C compilers choke on regexpr.c
+
+
+Changes affecting portability
+-----------------------------
+
+You need STDWIN version 0.9.7 (released 30 June 1992) for the stdwin
+interface
+
+Dynamic loading is now supported for Sun (and other non-COFF systems)
+throug dld-3.2.3, as well as for SGI (a new version of Jack Jansen's
+DL is out, 1.4)
+
+The system-dependent code for the use of the select() system call is
+moved to one file: myselect.h
+
+Thanks to Jaap Vermeulen, the code should now port cleanly to the
+SEQUENT
+
+
+Changes to the interpreter interface
+------------------------------------
+
+The interpretation of $PYTHONPATH in the environment is different: it
+is inserted in front of the default path instead of overriding it
+
+
+Changes to existing built-in functions and methods
+--------------------------------------------------
+
+List objects now support an optional argument to their sort() method,
+which is a comparison function similar to qsort(3) in C
+
+File objects now have a method fileno(), used by the new select module
+(see below)
+
+
+New built-in function
+---------------------
+
+coerce(x, y): take two numbers and return a tuple containing them
+both converted to a common type
+
+
+Changes to built-in modules
+---------------------------
+
+sys: fixed core dumps in settrace() and setprofile()
+
+socket: added socket methods setsockopt() and getsockopt(); and
+fileno(), used by the new select module (see below)
+
+stdwin: added fileno() == connectionnumber(), in support of new module
+select (see below)
+
+posix: added get{eg,eu,g,u}id(); waitpid() is now a separate function.
+
+gl: added qgetfd()
+
+fl: added several new functions, fixed several obscure bugs, adapted
+to FORMS 2.1
+
+
+Changes to standard modules
+---------------------------
+
+posixpath: changed implementation of ismount()
+
+string: atoi() no longer mistakes leading zero for octal number
+
+...
+
+
+New built-in modules
+--------------------
+
+Modules marked "dynamic only" are not configured at compile time but
+can be loaded dynamically.  You need to turn on the DL or DLD option in
+the Makefile for support dynamic loading of modules (this requires
+external code).
+
+select: interfaces to the BSD select() system call
+
+dbm: interfaces to the (new) dbm library (dynamic only)
+
+nis: interfaces to some NIS functions (aka yellow pages)
+
+thread: limited form of multiple threads (sgi only)
+
+audioop: operations useful for audio programs, e.g. u-LAW and ADPCM
+coding (dynamic only)
+
+cd: interface to Indigo SCSI CDROM player audio library (sgi only)
+
+jpeg: read files in JPEG format (dynamic only, sgi only; needs
+external code)
+
+imgfile: read SGI image files (dynamic only, sgi only)
+
+sunaudiodev: interface to sun's /dev/audio (dynamic only, sun only)
+
+sv: interface to Indigo video library (sgi only)
+
+pc: a minimal set of MS-DOS interfaces (MS-DOS only)
+
+rotor: encryption, by Lance Ellinghouse (dynamic only)
+
+
+New standard modules
+--------------------
+
+Not all these modules are documented.  Read the source:
+lib/<modulename>.py.  Sometimes a file lib/<modulename>.doc contains
+additional documentation.
+
+imghdr: recognizes image file headers
+
+sndhdr: recognizes sound file headers
+
+profile: print run-time statistics of Python code
+
+readcd, cdplayer: companion modules for built-in module cd (sgi only)
+
+emacs: interface to Emacs using py-connect.el (see below).
+
+SOCKET: symbolic constant definitions for socket options
+
+SUNAUDIODEV: symbolic constant definitions for sunaudiodef (sun only)
+
+SV: symbolic constat definitions for sv (sgi only)
+
+CD: symbolic constat definitions for cd (sgi only)
+
+
+New demos
+---------
+
+scripts/pp.py: execute Python as a filter with a Perl-like command
+line interface
+
+classes/: examples using the new class features
+
+threads/: examples using the new thread module
+
+sgi/cd/: examples using the new cd module
+
+
+Changes to the documentation
+----------------------------
+
+The last-minute syntax changes of release 0.9.6 are now reflected
+everywhere in the manuals
+
+The reference manual has a new section (3.2) on implementing new kinds
+of numbers, sequences or mappings with user classes
+
+Classes are now treated extensively in the tutorial (chapter 9)
+
+Slightly restructured the system-dependent chapters of the library
+manual
+
+The file misc/EXTENDING incorporates documentation for mkvalue() and
+a new section on error handling
+
+The files misc/CLASSES and misc/ERRORS are no longer necessary
+
+The doc/Makefile now creates PostScript files automatically
+
+
+Miscellaneous changes
+---------------------
+
+Incorporated Tim Peters' changes to python-mode.el, it's now version
+1.06
+
+A python/Emacs bridge (provided by Terrence M. Brannon) lets a Python
+program running in an Emacs buffer execute Emacs lisp code.  The
+necessary Python code is in lib/emacs.py.  The Emacs code is
+misc/py-connect.el (it needs some external Emacs lisp code)
+
+
+Changes to the source code that affect C extension writers
+----------------------------------------------------------
+
+New service function mkvalue() to construct a Python object from C
+values according to a "format" string a la getargs()
+
+Most functions from pythonmain.c moved to new pythonrun.c which is
+in libpython.a.  This should make embedded versions of Python easier
+
+ceval.h is split in eval.h (which needs compile.h and only declares
+eval_code) and ceval.h (which doesn't need compile.hand declares the
+rest)
+
+ceval.h defines macros BGN_SAVE / END_SAVE for use with threads (to
+improve the parallellism of multi-threaded programs by letting other
+Python code run when a blocking system call or something similar is
+made)
+
+In structmember.[ch], new member types BYTE, CHAR and unsigned
+variants have been added
+
+New file xxmodule.c is a template for new extension modules.
+
+
+==================================
+==> Release 0.9.6 (6 Apr 1992) <==
+==================================
+
+Misc news in 0.9.6:
+- Restructured the misc subdirectory
+- Reference manual completed, library manual much extended (with indexes!)
+- the GNU Readline library is now distributed standard with Python
+- the script "../demo/scripts/classfix.py" fixes Python modules using old
+  class syntax
+- Emacs python-mode.el (was python.el) vastly improved (thanks, Tim!)
+- Because of the GNU copyleft business I am not using the GNU regular
+  expression implementation but a free re-implementation by Tatu Ylonen
+  that recently appeared in comp.sources.misc (Bravo, Tatu!)
+
+New features in 0.9.6:
+- stricter try stmt syntax: cannot mix except and finally clauses on 1 try
+- New module 'os' supplants modules 'mac' and 'posix' for most cases;
+  module 'path' is replaced by 'os.path'
+- os.path.split() return value differs from that of old path.split()
+- sys.exc_type, sys.exc_value, sys.exc_traceback are set to the exception
+  currently being handled
+- sys.last_type, sys.last_value, sys.last_traceback remember last unhandled
+  exception
+- New function string.expandtabs() expands tabs in a string
+- Added times() interface to posix (user & sys time of process & children)
+- Added uname() interface to posix (returns OS type, hostname, etc.)
+- New built-in function execfile() is like exec() but from a file
+- Functions exec() and eval() are less picky about whitespace/newlines
+- New built-in functions getattr() and setattr() access arbitrary attributes
+- More generic argument handling in built-in functions (see "./EXTENDING")
+- Dynamic loading of modules written in C or C++ (see "./DYNLOAD")
+- Division and modulo for long and plain integers with negative operands
+  have changed; a/b is now floor(float(a)/float(b)) and a%b is defined
+  as a-(a/b)*b.  So now the outcome of divmod(a,b) is the same as
+  (a/b, a%b) for integers.  For floats, % is also changed, but of course
+  / is unchanged, and divmod(x,y) does not yield (x/y, x%y)...
+- A function with explicit variable-length argument list can be declared
+  like this: def f(*args): ...; or even like this: def f(a, b, *rest): ...
+- Code tracing and profiling features have been added, and two source
+  code debuggers are provided in the library (pdb.py, tty-oriented,
+  and wdb, window-oriented); you can now step through Python programs!
+  See sys.settrace() and sys.setprofile(), and "../lib/pdb.doc"
+- '==' is now the only equality operator; "../demo/scripts/eqfix.py" is
+  a script that fixes old Python modules
+- Plain integer right shift now uses sign extension
+- Long integer shift/mask operations now simulate 2's complement
+  to give more useful results for negative operands
+- Changed/added range checks for long/plain integer shifts
+- Options found after "-c command" are now passed to the command in sys.argv
+  (note subtle incompatiblity with "python -c command -- -options"!)
+- Module stdwin is better protected against touching objects after they've
+  been closed; menus can now also be closed explicitly
+- Stdwin now uses its own exception (stdwin.error)
+
+New features in 0.9.5 (released as Macintosh application only, 2 Jan 1992):
+- dictionary objects can now be compared properly; e.g., {}=={} is true
+- new exception SystemExit causes termination if not caught;
+  it is raised by sys.exit() so that 'finally' clauses can clean up,
+  and it may even be caught.  It does work interactively!
+- new module "regex" implements GNU Emacs style regular expressions;
+  module "regexp" is rewritten in Python for backward compatibility
+- formal parameter lists may contain trailing commas
+
+Bugs fixed in 0.9.6:
+- assigning to or deleting a list item with a negative index dumped core
+- divmod(-10L,5L) returned (-3L, 5L) instead of (-2L, 0L)
+
+Bugs fixed in 0.9.5:
+- masking operations involving negative long integers gave wrong results
+
+
+===================================
+==> Release 0.9.4 (24 Dec 1991) <==
+===================================
+
+- new function argument handling (see below)
+- built-in apply(func, args) means func(args[0], args[1], ...)
+- new, more refined exceptions
+- new exception string values (NameError = 'NameError' etc.)
+- better checking for math exceptions
+- for sequences (string/tuple/list), x[-i] is now equivalent to x[len(x)-i]
+- fixed list assignment bug: "a[1:1] = a" now works correctly
+- new class syntax, without extraneous parentheses
+- new 'global' statement to assign global variables from within a function
+
+
+New class syntax
+----------------
+
+You can now declare a base class as follows:
+
+	class B:			# Was: class B():
+		def some_method(self): ...
+		...
+
+and a derived class thusly:
+
+	class D(B):			# Was: class D() = B():
+		def another_method(self, arg): ...
+
+Multiple inheritance looks like this:
+
+	class M(B, D):			# Was: class M() = B(), D():
+		def this_or_that_method(self, arg): ...
+
+The old syntax is still accepted by Python 0.9.4, but will disappear
+in Python 1.0 (to be posted to comp.sources).
+
+
+New 'global' statement
+----------------------
+
+Every now and then you have a global variable in a module that you
+want to change from within a function in that module -- say, a count
+of calls to a function, or an option flag, etc.  Until now this was
+not directly possible.  While several kludges are known that
+circumvent the problem, and often the need for a global variable can
+be avoided by rewriting the module as a class, this does not always
+lead to clearer code.
+
+The 'global' statement solves this dilemma.  Its occurrence in a
+function body means that, for the duration of that function, the
+names listed there refer to global variables.  For instance:
+
+	total = 0.0
+	count = 0
+
+	def add_to_total(amount):
+		global total, count
+		total = total + amount
+		count = count + 1
+
+'global' must be repeated in each function where it is needed.  The
+names listed in a 'global' statement must not be used in the function
+before the statement is reached.
+
+Remember that you don't need to use 'global' if you only want to *use*
+a global variable in a function; nor do you need ot for assignments to
+parts of global variables (e.g., list or dictionary items or
+attributes of class instances).  This has not changed; in fact
+assignment to part of a global variable was the standard workaround.
+
+
+New exceptions
+--------------
+
+Several new exceptions have been defined, to distinguish more clearly
+between different types of errors.
+
+name			meaning					was
+
+AttributeError		reference to non-existing attribute	NameError
+IOError			unexpected I/O error			RuntimeError
+ImportError		import of non-existing module or name	NameError
+IndexError		invalid string, tuple or list index	RuntimeError
+KeyError		key not in dictionary			RuntimeError
+OverflowError		numeric overflow			RuntimeError
+SyntaxError		invalid syntax				RuntimeError
+ValueError		invalid argument value			RuntimeError
+ZeroDivisionError	division by zero			RuntimeError
+
+The string value of each exception is now its name -- this makes it
+easier to experimentally find out which operations raise which
+exceptions; e.g.:
+
+	>>> KeyboardInterrupt
+	'KeyboardInterrupt'
+	>>>
+
+
+New argument passing semantics
+------------------------------
+
+Off-line discussions with Steve Majewski and Daniel LaLiberte have
+convinced me that Python's parameter mechanism could be changed in a
+way that made both of them happy (I hope), kept me happy, fixed a
+number of outstanding problems, and, given some backward compatibility
+provisions, would only break a very small amount of existing code --
+probably all mine anyway.  In fact I suspect that most Python users
+will hardly notice the difference.  And yet it has cost me at least
+one sleepless night to decide to make the change...
+
+Philosophically, the change is quite radical (to me, anyway): a
+function is no longer called with either zero or one argument, which
+is a tuple if there appear to be more arguments.  Every function now
+has an argument list containing 0, 1 or more arguments.  This list is
+always implemented as a tuple, and it is a (run-time) error if a
+function is called with a different number of arguments than expected.
+
+What's the difference? you may ask.  The answer is, very little unless
+you want to write variadic functions -- functions that may be called
+with a variable number of arguments.  Formerly, you could write a
+function that accepted one or more arguments with little trouble, but
+writing a function that could be called with either 0 or 1 argument
+(or more) was next to impossible.  This is now a piece of cake: you
+can simply declare an argument that receives the entire argument
+tuple, and check its length -- it will be of size 0 if there are no
+arguments.
+
+Another anomaly of the old system was the way multi-argument methods
+(in classes) had to be declared, e.g.:
+
+	class Point():
+		def init(self, (x, y, color)): ...
+		def setcolor(self, color): ...
+		dev moveto(self, (x, y)): ...
+		def draw(self): ...
+
+Using the new scheme there is no need to enclose the method arguments
+in an extra set of parentheses, so the above class could become:
+
+	class Point:
+		def init(self, x, y, color): ...
+		def setcolor(self, color): ...
+		dev moveto(self, x, y): ...
+		def draw(self): ...
+
+That is, the equivalence rule between methods and functions has
+changed so that now p.moveto(x,y) is equivalent to Point.moveto(p,x,y)
+while formerly it was equivalent to Point.moveto(p,(x,y)).
+
+A special backward compatibility rule makes that the old version also
+still works: whenever a function with exactly two arguments (at the top
+level) is called with more than two arguments, the second and further
+arguments are packed into a tuple and passed as the second argument.
+This rule is invoked independently of whether the function is actually a
+method, so there is a slight chance that some erroneous calls of
+functions expecting two arguments with more than that number of
+arguments go undetected at first -- when the function tries to use the
+second argument it may find it is a tuple instead of what was expected.
+Note that this rule will be removed from future versions of the
+language; it is a backward compatibility provision *only*.
+
+Two other rules and a new built-in function handle conversion between
+tuples and argument lists:
+
+Rule (a): when a function with more than one argument is called with a
+single argument that is a tuple of the right size, the tuple's items
+are used as arguments.
+
+Rule (b): when a function with exactly one argument receives no
+arguments or more than one, that one argument will receive a tuple
+containing the arguments (the tuple will be empty if there were no
+arguments).
+
+
+A new built-in function, apply(), was added to support functions that
+need to call other functions with a constructed argument list.  The call
+
+	apply(function, tuple)
+
+is equivalent to
+
+	function(tuple[0], tuple[1], ..., tuple[len(tuple)-1])
+
+
+While no new argument syntax was added in this phase, it would now be
+quite sensible to add explicit syntax to Python for default argument
+values (as in C++ or Modula-3), or a "rest" argument to receive the
+remaining arguments of a variable-length argument list.
+
+
+========================================================
+==> Release 0.9.3 (never made available outside CWI) <==
+========================================================
+
+- string sys.version shows current version (also printed on interactive entry)
+- more detailed exceptions, e.g., IOError, ZeroDivisionError, etc.
+- 'global' statement to declare module-global variables assigned in functions.
+- new class declaration syntax: class C(Base1, Base2, ...): suite
+  (the old syntax is still accepted -- be sure to convert your classes now!)
+- C shifting and masking operators: << >> ~ & ^ | (for ints and longs).
+- C comparison operators: == != (the old = and <> remain valid).
+- floating point numbers may now start with a period (e.g., .14).
+- definition of integer division tightened (always truncates towards zero).
+- new builtins hex(x), oct(x) return hex/octal string from (long) integer.
+- new list method l.count(x) returns the number of occurrences of x in l.
+- new SGI module: al (Indigo and 4D/35 audio library).
+- the FORMS interface (modules fl and FL) now uses FORMS 2.0
+- module gl: added lrect{read,write}, rectzoom and pixmode;
+  added (non-GL) functions (un)packrect.
+- new socket method: s.allowbroadcast(flag).
+- many objects support __dict__, __methods__ or __members__.
+- dir() lists anything that has __dict__.
+- class attributes are no longer read-only.
+- classes support __bases__, instances support __class__ (and __dict__).
+- divmod() now also works for floats.
+- fixed obscure bug in eval('1            ').
+
+
+===================================
+==> Release 0.9.2 (Autumn 1991) <==
+===================================
+
+Highlights
+----------
+
+- tutorial now (almost) complete; library reference reorganized
+- new syntax: continue statement; semicolons; dictionary constructors;
+  restrictions on blank lines in source files removed
+- dramatically improved module load time through precompiled modules
+- arbitrary precision integers: compute 2 to the power 1000 and more...
+- arithmetic operators now accept mixed type operands, e.g., 3.14/4
+- more operations on list: remove, index, reverse; repetition
+- improved/new file operations: readlines, seek, tell, flush, ...
+- process management added to the posix module: fork/exec/wait/kill etc.
+- BSD socket operations (with example servers and clients!)
+- many new STDWIN features (color, fonts, polygons, ...)
+- new SGI modules: font manager and FORMS library interface
+
+
+Extended list of changes in 0.9.2
+---------------------------------
+
+Here is a summary of the most important user-visible changes in 0.9.2,
+in somewhat arbitrary order.  Changes in later versions are listed in
+the "highlights" section above.
+
+
+1. Changes to the interpreter proper
+
+- Simple statements can now be separated by semicolons.
+  If you write "if t: s1; s2", both s1 and s2 are executed
+  conditionally.
+- The 'continue' statement was added, with semantics as in C.
+- Dictionary displays are now allowed on input: {key: value, ...}.
+- Blank lines and lines bearing only a comment no longer need to
+  be indented properly.  (A completely empty line still ends a multi-
+  line statement interactively.)
+- Mixed arithmetic is supported, 1 compares equal to 1.0, etc.
+- Option "-c command" to execute statements from the command line
+- Compiled versions of modules are cached in ".pyc" files, giving a
+  dramatic improvement of start-up time
+- Other, smaller speed improvements, e.g., extracting characters from
+  strings, looking up single-character keys, and looking up global
+  variables
+- Interrupting a print operation raises KeyboardInterrupt instead of
+  only cancelling the print operation
+- Fixed various portability problems (it now passes gcc with only
+  warnings -- more Standard C compatibility will be provided in later
+  versions)
+- Source is prepared for porting to MS-DOS
+- Numeric constants are now checked for overflow (this requires
+  standard-conforming strtol() and strtod() functions; a correct
+  strtol() implementation is provided, but the strtod() provided
+  relies on atof() for everything, including error checking
+
+
+2. Changes to the built-in types, functions and modules
+
+- New module socket: interface to BSD socket primitives
+- New modules pwd and grp: access the UNIX password and group databases
+- (SGI only:) New module "fm" interfaces to the SGI IRIX Font Manager
+- (SGI only:) New module "fl" interfaces to Mark Overmars' FORMS library
+- New numeric type: long integer, for unlimited precision
+	- integer constants suffixed with 'L' or 'l' are long integers
+	- new built-in function long(x) converts int or float to long
+	- int() and float() now also convert from long integers
+- New built-in function:
+	- pow(x, y) returns x to the power y
+- New operation and methods for lists:
+	- l*n returns a new list consisting of n concatenated copies of l
+	- l.remove(x) removes the first occurrence of the value x from l
+	- l.index(x) returns the index of the first occurrence of x in l
+	- l.reverse() reverses l in place
+- New operation for tuples:
+	- t*n returns a tuple consisting of n concatenated copies of t
+- Improved file handling:
+	- f.readline() no longer restricts the line length, is faster,
+	  and isn't confused by null bytes; same for raw_input()
+	- f.read() without arguments reads the entire (rest of the) file
+	- mixing of print and sys.stdout.write() has different effect
+- New methods for files:
+	- f.readlines() returns a list containing the lines of the file,
+	  as read with f.readline()
+	- f.flush(), f.tell(), f.seek() call their stdio counterparts
+	- f.isatty() tests for "tty-ness"
+- New posix functions:
+	- _exit(), exec(), fork(), getpid(), getppid(), kill(), wait()
+	- popen() returns a file object connected to a pipe
+	- utime() replaces utimes() (the latter is not a POSIX name)
+- New stdwin features, including:
+	- font handling
+	- color drawing
+	- scroll bars made optional
+	- polygons
+	- filled and xor shapes
+	- text editing objects now have a 'settext' method
+
+
+3. Changes to the standard library
+
+- Name change: the functions path.cat and macpath.cat are now called
+  path.join and macpath.join
+- Added new modules: formatter, mutex, persist, sched, mainloop
+- Added some modules and functionality to the "widget set" (which is
+  still under development, so please bear with me):
+	DirList, FormSplit, TextEdit, WindowSched
+- Fixed module testall to work non-interactively
+- Module string:
+	- added functions join() and joinfields()
+	- fixed center() to work correct and make it "transitive"
+- Obsolete modules were removed: util, minmax
+- Some modules were moved to the demo directory
+
+
+4. Changes to the demonstration programs
+
+- Added new useful scipts: byteyears, eptags, fact, from, lfact,
+  objgraph, pdeps, pi, primes, ptags, which
+- Added a bunch of socket demos
+- Doubled the speed of ptags
+- Added new stdwin demos: microedit, miniedit
+- Added a windowing interface to the Python interpreter: python (most
+  useful on the Mac)
+- Added a browser for Emacs info files: demo/stdwin/ibrowse
+  (yes, I plan to put all STDWIN and Python documentation in texinfo
+  form in the future)
+
+
+5. Other changes to the distribution
+
+- An Emacs Lisp file "python.el" is provided to facilitate editing
+  Python programs in GNU Emacs (slightly improved since posted to
+  gnu.emacs.sources)
+- Some info on writing an extension in C is provided
+- Some info on building Python on non-UNIX platforms is provided
+
+
+=====================================
+==> Release 0.9.1 (February 1991) <==
+=====================================
+
+- Micro changes only
+- Added file "patchlevel.h"
+
+
+=====================================
+==> Release 0.9.0 (February 1991) <==
+=====================================
+
+Original posting to alt.sources.

Added: vendor/Python/current/Misc/NEWS
===================================================================
--- vendor/Python/current/Misc/NEWS	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Misc/NEWS	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2782 @@
++++++++++++
+Python News
++++++++++++
+
+(editors: check NEWS.help for information about editing NEWS using ReST.)
+
+What's New in Python 2.5.1?
+=============================
+
+*Release date: 18-APR-2007*
+
+Core and builtins
+-----------------
+
+- Revert SF #1615701: dict.update() does *not* call __getitem__() or keys()
+  if subclassed.  This is to remain consistent with 2.5.
+  Also revert revision 53667 with made a similar change to set.update().
+
+
+What's New in Python 2.5.1c1?
+=============================
+
+*Release date: 05-APR-2007*
+
+Core and builtins
+-----------------
+
+- Patch #1682205: a TypeError while unpacking an iterable is no longer
+  masked by a generic one with the message "unpack non-sequence".
+
+- Patch #1642547: Fix an error/crash when encountering syntax errors in
+  complex if statements.
+
+- Patch #1462488: Python no longer segfaults when ``object.__reduce_ex__()``
+  is called with an object that is faking its type.
+
+- Patch #1680015: Don't modify __slots__ tuple if it contains an unicode
+  name.
+
+- Patch #922167: Python no longer segfaults when faced with infinitely
+  self-recursive reload() calls (as reported by bug #742342).
+
+- Patch #1675981: remove unreachable code from ``type.__new__()`` method.
+
+- Patch #1638879: don't accept strings with embedded NUL bytes in long().
+
+- Bug #1674503: close the file opened by execfile() in an error condition.
+
+- Patch #1674228: when assigning a slice (old-style), check for the
+  sq_ass_slice instead of the sq_slice slot.
+
+- Bug #1669182: prevent crash when trying to print an unraisable error
+  from a string exception.
+
+- The peephole optimizer left None as a global in functions with a docstring
+  and an explicit return value.
+
+- Bug #1653736: Properly discard third argument to slot_nb_inplace_power.
+
+- SF #151204:  enumerate() now raises an Overflow error at sys.maxint items.
+
+- Bug #1377858: Fix the segfaulting of the interpreter when an object created
+  a weakref on itself during a __del__ call for new-style classes (classic
+  classes still have the bug).
+
+- Bug #1648179:  set.update() did not recognize an overridden __iter__ 
+  method in subclasses of dict.
+
+- Bug #1579370: Make PyTraceBack_Here use the current thread, not the
+  frame's thread state.
+
+- patch #1630975: Fix crash when replacing sys.stdout in sitecustomize.py
+
+- Bug #1637022: Prefix AST symbols with _Py_.
+
+- Prevent seg fault on shutdown which could occur if an object
+  raised a warning.
+
+- Bug #1566280: Explicitly invoke threading._shutdown from Py_Main,
+  to avoid relying on atexit.
+
+- Bug #1590891: random.randrange don't return correct value for big number
+
+- Bug #1456209: In some obscure cases it was possible for a class with a
+  custom ``__eq__()`` method to confuse set internals when class instances
+  were used as a set's elements and the ``__eq__()`` method mutated the set.
+
+- The repr for self-referential sets and fronzensets now shows "..." instead
+  of falling into infinite recursion.
+
+- Eliminated unnecessary repeated calls to hash() by set.intersection() and
+  set.symmetric_difference_update().
+
+- Bug #1591996: Correctly forward exception in instance_contains().
+
+- Bug #1588287: fix invalid assertion for `1,2` in debug builds.
+
+- Bug #1576657: when setting a KeyError for a tuple key, make sure that
+  the tuple isn't used as the "exception arguments tuple".  Applied to
+  both sets and dictionaries.
+
+- Bug #1565514, SystemError not raised on too many nested blocks.
+
+- Bug #1576174: WindowsError now displays the windows error code
+  again, no longer the posix error code.
+
+- Patch #1549049: Support long values in structmember.
+
+- Bug #1542016: make sys.callstats() match its docstring and return an
+  11-tuple (only relevant when Python is compiled with -DCALL_PROFILE).
+
+- Bug #1545497: when given an explicit base, int() did ignore NULs
+  embedded in the string to convert.
+
+- Bug #1569998: break inside a try statement (outside a loop) is now
+  recognized and rejected.
+
+- Patch #1542451: disallow continue anywhere under a finally.
+
+- list.pop(x) accepts any object x following the __index__ protocol.
+
+- Fix some leftovers from the conversion from int to Py_ssize_t
+  (relevant to strings and sequences of more than 2**31 items).
+
+- A number of places, including integer negation and absolute value,
+  were fixed to not rely on undefined behaviour of the C compiler
+  anymore.
+
+- Bug #1566800: make sure that EnvironmentError can be called with any
+  number of arguments, as was the case in Python 2.4.
+
+- Patch #1567691: super() and new.instancemethod() now don't accept
+  keyword arguments any more (previously they accepted them, but didn't
+  use them).
+
+- Fix a bug in the parser's future statement handling that led to "with"
+  not being recognized as a keyword after, e.g., this statement:
+  from __future__ import division, with_statement
+
+- Bug #1557232: fix seg fault with def f((((x)))) and def f(((x),)).
+
+- Fix %zd string formatting on Mac OS X so it prints negative numbers.
+
+- Allow exception instances to be directly sliced again.
+
+
+Extension Modules
+-----------------
+
+- Bug #1563759: struct.unpack doens't support buffer protocol objects
+
+- Bug #1686475: Support stat'ing open files on Windows again.
+
+- Bug #1647541: Array module's buffer interface can now handle empty arrays.
+
+- Bug #1693079: The array module can now successfully pickle empty arrays.
+
+- Bug #1688393: Prevent crash in socket.recvfrom if length is negative.
+
+- Bug #1622896: fix a rare corner case where the bz2 module raised an
+  error in spite of a succesful compression.
+
+- Patch #1654417: make operator.{get,set,del}slice use the full range
+  of Py_ssize_t.
+
+- Patch #1646728: datetime.fromtimestamp fails with negative
+  fractional times.  With unittest.
+
+- Patch #1494140: Add documentation for the new struct.Struct object.
+
+- Patch #1657276: Make NETLINK_DNRTMSG conditional.
+
+- Bug #1653736: Fix signature of time_isoformat.
+
+- operator.count() now raises an OverflowError when the count reaches sys.maxint.
+
+- Bug #1575169: operator.isSequenceType() now returns False for subclasses of dict.
+
+- collections.defaultdict() now verifies that the factory function is callable.
+
+- Bug #1486663: don't reject keyword arguments for subclasses of builtin
+  types.
+
+- The version number of the ctypes package was changed to "1.0.2".
+
+- Bug #1664966: Fix crash in exec if Unicode filename can't be decoded.
+
+- Patch #1544279: Improve thread-safety of the socket module by moving
+  the sock_addr_t storage out of the socket object.
+
+- Patch #1615868: make bz2.BZFile.seek() work for offsets >2GiB.
+
+- Bug #1563807: _ctypes built on AIX fails with ld ffi error.
+
+- Bug #1598620: A ctypes Structure cannot contain itself.
+ 
+- Bug #1588217: don't parse "= " as a soft line break in binascii's
+  a2b_qp() function, instead leave it in the string as quopri.decode()
+  does.
+
+- Patch #838546: Make terminal become controlling in pty.fork()
+
+- Patch #1560695: Add .note.GNU-stack to ctypes' sysv.S so that
+  ctypes isn't considered as requiring executable stacks.
+
+- Bug #1567666: Emulate GetFileAttributesExA for Win95.
+
+- Bug #1548891: The cStringIO.StringIO() constructor now encodes unicode
+  arguments with the system default encoding just like the write()
+  method does, instead of converting it to a raw buffer.
+
+- Bug #1565150: Fix subsecond processing for os.utime on Windows.
+
+- Patch #1572724: fix typo ('=' instead of '==') in _msi.c.
+
+- Bug #1572832: fix a bug in ISO-2022 codecs which may cause segfault
+  when encoding non-BMP unicode characters.
+
+- Bug #1556784: allow format strings longer than 127 characters in
+  datetime's strftime function.
+
+- Fix itertools.count(n) to work with negative numbers again.
+
+- Make regex engine raise MemoryError if allocating memory fails.
+
+- fixed a bug with bsddb.DB.stat: the flags and txn keyword arguments
+  were transposed.
+
+- Added support for linking the bsddb module against BerkeleyDB 4.5.x.
+
+- Modifying an empty deque during iteration now raises RuntimeError
+  instead of StopIteration.
+
+- Bug #1552726: fix polling at the interpreter prompt when certain
+  versions of the readline library are in use.
+
+- Bug #1633621: if curses.resizeterm() or curses.resize_term() is called,
+  update _curses.LINES, _curses.COLS, curses.LINES and curses.COLS.
+
+- Fix an off-by-one bug in locale.strxfrm().
+
+Library
+-------
+
+- Patch #1685563: remove (don't add) duplicate paths in distutils.MSVCCompiler.
+
+- Bug #978833: Revert r50844, as it broke _socketobject.dup.
+
+- Bug #1675967: re patterns pickled with Python 2.4 and earlier can
+  now be unpickled with Python 2.5.
+
+- Bug #1684254: webbrowser now uses shlex to split any command lines
+  given to get(). It also detects when you use '&' as the last argument
+  and creates a BackgroundBrowser then.
+
+- Patch #1681153: the wave module now closes a file object it opened if
+  initialization failed.
+
+- Bug #767111: fix long-standing bug in urllib which caused an
+  AttributeError instead of an IOError when the server's response didn't
+  contain a valid HTTP status line.
+
+- Bug #1629369: Correctly parse multiline comment in address field.
+
+- Bug #1582282: Fix email.header.decode_header() to properly treat encoded
+  words with no delimiting whitespace as a single word.
+
+- Patch #1449244: Support Unicode strings in
+  email.message.Message.{set_charset,get_content_charset}.
+
+- Patch #1542681: add entries for "with", "as" and "CONTEXTMANAGERS" to
+  pydoc's help keywords.
+
+- Patch #1192590: Fix pdb's "ignore" and "condition" commands so they trap
+  the IndexError caused by passing in an invalid breakpoint number.
+
+- Bug #1531963: Make SocketServer.TCPServer's server_address always
+  be equal to calling getsockname() on the server's socket. Fixed by patch
+  #1545011.
+
+- Bug #1651235: When a tuple was passed to a ctypes function call,
+  Python would crash instead of raising an error.
+
+- Fix bug #1646630: ctypes.string_at(buf, 0) and ctypes.wstring_at(buf, 0)
+  returned string up to the first NUL character.
+
+- Bug #1637850:  make_table in difflib did not work with unicode
+
+- Bugs #1676321:  the empty() function in sched.py returned the wrong result
+
+- unittest now verifies more of its assumptions. In particular, TestCase
+  and TestSuite subclasses (not instances) are no longer accepted in
+  TestSuite.addTest(). This should cause no incompatibility since it
+  never made sense with ordinary subclasses -- the failure just occurred
+  later, with a more cumbersome exception.
+
+- Patch #685268: Consider a package's __path__ in imputil.
+
+- Patch 1463026: Support default namespace in XMLGenerator.
+
+- Patch 1571379: Make trace's --ignore-dir facility work in the face of
+  relative directory names.
+
+- Bug #1600860: Search for shared python library in LIBDIR, not lib/python/config,
+  on "linux" and "gnu" systems.
+
+- Bug #1124861: Automatically create pipes if GetStdHandle fails in
+  subprocess. 
+
+- Patch #783050: the pty.fork() function now closes the slave fd
+  correctly.
+
+- Patch #1638243: the compiler package is now able to correctly compile
+  a with statement; previously, executing code containing a with statement
+  compiled by the compiler package crashed the interpreter.
+
+- Bug #1643943: Fix %U handling for time.strptime.
+
+- Bug #1598181: Avoid O(N**2) bottleneck in subprocess communicate(). 
+
+- Patch #1627441: close sockets properly in urllib2.
+
+- Bug #1610795: ctypes.util.find_library works now on BSD systems.
+
+- Fix sort stability in heapq.nlargest() and nsmallest().
+
+- Patch #1504073: Fix tarfile.open() for mode "r" with a fileobj argument.
+
+- Patch #1262036: Prevent TarFiles from being added to themselves under
+  certain conditions.
+
+- Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
+  work correctly together with readline().
+
+- Bug #737202: Make CGIHTTPServer work for scripts in subdirectories.
+  Fix by Titus Brown.
+
+- Patch #827559: Make SimpleHTTPServer redirect when a directory URL
+  is missing the trailing slash, so that relative links work correctly.
+  Patch by Chris Gonnerman.
+
+- Patch #1608267: fix a race condition in os.makedirs() is the directory
+  to be created is already there.
+
+- Patch #1610437: fix a tarfile bug with long filename headers.
+
+- Patch #1472877: Fix Tix subwidget name resolution.
+
+- Patch #1594554: Always close a tkSimpleDialog on ok(), even
+  if an exception occurs.
+
+- Patch #1538878: Don't make tkSimpleDialog dialogs transient if
+  the parent window is withdrawn.
+
+- Patch #1360200: Use unmangled_version RPM spec field to deal with
+  file name mangling.
+
+- Patch #1359217: Process 2xx response in an ftplib transfer
+  that precedes an 1xx response.
+
+- Patch #1060577: Extract list of RPM files from spec file in
+  bdist_rpm
+
+- Bug #1586613: fix zlib and bz2 codecs' incremental en/decoders.
+
+- Patch #1583880: fix tarfile's problems with long names and posix/
+  GNU modes.
+
+- Fix codecs.EncodedFile which did not use file_encoding in 2.5.0, and
+  fix all codecs file wrappers to work correctly with the "with"
+  statement (bug #1586513).
+
+- ctypes callback functions only support 'fundamental' data types as
+  result type.  Raise an error when something else is used.  This is a
+  partial fix for Bug #1574584.
+
+- Bug #813342: Start the IDLE subprocess with -Qnew if the parent
+  is started with that option.
+
+- Bug #1446043: correctly raise a LookupError if an encoding name given
+  to encodings.search_function() contains a dot.
+
+- Bug #1545341: The 'classifier' keyword argument to the Distutils setup() 
+  function now accepts tuples as well as lists.
+
+- Bug #1560617: in pyclbr, return full module name not only for classes,
+  but also for functions.
+
+- Bug #1566602: correct failure of posixpath unittest when $HOME ends
+  with a slash.
+
+- Bug #1565661: in webbrowser, split() the command for the default
+  GNOME browser in case it is a command with args.
+
+- Bug #1569790: mailbox.py: Maildir.get_folder() and MH.get_folder()
+  weren't passing the message factory on to newly created Maildir/MH
+  objects.
+
+- Bug #1575506: mailbox.py: Single-file mailboxes didn't re-lock
+  properly in their flush() method.
+
+- Patch #1514543: mailbox.py: In the Maildir class, report errors if there's 
+  a filename clash instead of possibly losing a message.  (Patch by David
+  Watson.)
+
+- Patch #1514544: mailbox.py: Try to ensure that messages/indexes have
+  been physically written to disk after calling .flush() or
+  .close(). (Patch by David Watson.)
+
+- mailbox.py: Change MH.pack() to not lock individual message files; this
+  wasn't consistent with existing implementations of message packing, and
+  was buggy on some platforms.
+
+- Bug #1633678: change old mailbox.UnixMailbox class to parse 
+  'From' lines less strictly.
+
+- Bug #1576241: fix functools.wraps() to work on built-in functions.
+
+- Patch #1574068: fix urllib/urllib2 to not insert line breaks when
+  HTTP authentication data was very long.
+
+- Patch #1617413: fix urllib's support for  HTTP Basic authentication via HTTPS
+  (patch by Dug Song).
+
+- Fix a bug in traceback.format_exception_only() that led to an error
+  being raised when print_exc() was called without an exception set.
+  In version 2.4, this printed "None", restored that behavior.
+
+- Make webbrowser.BackgroundBrowser usable in Windows (it wasn't because
+  the close_fds arg to subprocess.Popen is not supported).
+
+
+Tools/Demos
+-----------
+
+- Patch #1552024: add decorator support to unparse.py demo script.
+
+- idle: Honor the "Cancel" action in the save dialog (Debian bug #299092).
+
+
+Tests
+-----
+
+- Cause test.test_socket_ssl:test_basic to raise
+  test.test_support.ResourceDenied when an HTTPS connection times out.
+
+- Remove passwd.adjunct.byname from list of maps
+  for test_nis.
+
+
+Build
+-----
+
+- Bug #1655392: don't add -L/usr/lib/pythonX.Y/config to the LDFLAGS
+  returned by python-config if Python was built with --enable-shared
+  because that prevented the shared library from being used.
+
+- Patch #1569798: fix a bug in distutils when building Python from a
+  directory within sys.exec_prefix.
+
+- Bug #1675511: Use -Kpic instead of -xcode=pic32 on Solaris/x86.
+
+- Disable _XOPEN_SOURCE on NetBSD 1.x.
+
+- Bug #1578513: Cross compilation was broken by a change to configure.
+  Repair so that it's back to how it was in 2.4.3.
+
+- Patch #1576954: Update VC6 build directory; remove redundant
+  files in VC7.
+
+- Fix build failure on kfreebsd and on the hurd.
+
+- Fix the build of the library reference in info format.
+
+
+Windows
+-------
+
+- Conditionalize definition of _CRT_SECURE_NO_DEPRECATE
+  and _CRT_NONSTDC_NO_DEPRECATE.
+
+
+Documentation
+-------------
+
+- Patch #1489771: the syntax rules in Python Reference Manual were
+  updated to reflect the current Python syntax.
+
+- Patch #1686451: Fix return type for
+  PySequence_{Count,Index,Fast_GET_SIZE}.
+
+
+What's New in Python 2.5 (final)
+================================
+
+*Release date: 19-SEP-2006*
+
+No changes since release candidate 2.
+
+
+What's New in Python 2.5 release candidate 2?
+=============================================
+
+*Release date: 12-SEP-2006*
+
+Core and builtins
+-----------------
+
+- Make _PyGILState_NoteThreadState() static, it was not used anywhere
+  outside of pystate.c and should not be necessary.
+
+- Bug #1551432: Exceptions do not define an explicit __unicode__ method.  This
+  allows calling unicode() on exceptions classes directly to succeed.
+
+- Bug #1542051: Exceptions now correctly call PyObject_GC_UnTrack.
+  Also make sure that every exception class has __module__ set to
+  'exceptions'.
+
+- Bug #1550983: emit better error messages for erroneous relative
+  imports (if not in package and if beyond toplevel package).
+
+- Overflow checking code in integer division ran afoul of new gcc
+  optimizations.  Changed to be more standard-conforming.
+
+- Patch #1541585: fix buffer overrun when performing repr() on
+  a unicode string in a build with wide unicode (UCS-4) support.
+
+- Patch #1546288: fix seg fault in dict_equal due to ref counting bug.
+
+- The return tuple from str.rpartition(sep) is (tail, sep, head) where
+  head is the original string if sep was not found.
+
+- Bug #1520864: unpacking singleton tuples in list comprehensions and
+  generator expressions (x for x, in ... ) works again.  Fixing this problem
+  required changing the .pyc magic number.  This means that .pyc files
+  generated before 2.5c2 will be regenerated.
+
+
+Library
+-------
+
+- Reverted patch #1504333 because it introduced an infinite loop.
+
+- Patch #1553314: Fix the inspect.py slowdown that was hurting IPython & SAGE
+  by adding smarter caching in inspect.getmodule().
+
+- Fix missing import of the types module in logging.config.
+
+- Patch #1550886: Fix decimal module context management implementation
+  to match the localcontext() example from PEP 343.
+
+- Bug #1541863: uuid.uuid1 failed to generate unique identifiers
+  on systems with low clock resolution.
+
+- Bug #1543303, patch #1543897: remove NUL padding from tarfiles.
+
+- Bug #1531862: Do not close standard file descriptors in subprocess.
+
+
+Extension Modules
+-----------------
+
+- Bug #1599782: fix segfault on bsddb.db.DB().type().
+
+- Fix bugs in ctypes:
+  - anonymous structure fields that have a bit-width specified did not work
+  - cast function did not accept c_char_p or c_wchar_p instances as first arg
+
+- Bug #1551427: fix a wrong NULL pointer check in the win32 version
+  of os.urandom().
+
+- Bug #1548092: fix curses.tparm seg fault on invalid input.
+
+- Bug #1550714: fix SystemError from itertools.tee on negative value for n.
+
+- Fixed a few bugs on cjkcodecs:
+  - gbk and gb18030 codec now handle U+30FB KATAKANA MIDDLE DOT correctly.
+  - iso2022_jp_2 codec now encodes into G0 for KS X 1001, GB2312
+    codepoints to conform the standard.
+  - iso2022_jp_3 and iso2022_jp_2004 codec can encode JIS X 0213:2
+    codepoints now.
+
+Tests
+-----
+
+- Patch #1559413: Fix test_cmd_line if sys.executable contains a space.
+
+- Fix bsddb test_basics.test06_Transactions to check the version
+  number properly.
+
+
+Documentation
+-------------
+
+- Patch #1679379: add documentation for fnmatch.translate().
+
+- Patch #1671450: add a section about subclassing builtin types to the
+  "extending and embedding" tutorial.
+
+- Bug #1629125: fix wrong data type (int -> Py_ssize_t) in PyDict_Next
+  docs.
+
+- Bug #1565919: document set types in the Language Reference.
+
+- Bug #1546052: clarify that PyString_FromString(AndSize) copies the
+  string pointed to by its parameter.
+
+- Bug #1566663: remove obsolete example from datetime docs.
+
+- Bug #1541682: Fix example in the "Refcount details" API docs.
+  Additionally, remove a faulty example showing PySequence_SetItem applied
+  to a newly created list object and add notes that this isn't a good idea.
+
+
+Tools
+-----
+
+- Bug #1546372: Fixed small bugglet in pybench that caused a missing
+  file not to get reported properly.
+
+
+Build
+-----
+
+- Bug #1568842: Fix test for uintptr_t.
+
+- Patch #1540470, for OpenBSD 4.0.
+
+- Patch #1545507: Exclude ctypes package in Win64 MSI file.
+
+- Fix OpenSSL debug build process.
+
+
+C API
+-----
+
+- Bug #1542693: remove semi-colon at end of PyImport_ImportModuleEx macro
+  so it can be used as an expression.
+
+
+What's New in Python 2.5 release candidate 1?
+=============================================
+
+*Release date: 17-AUG-2006*
+
+Core and builtins
+-----------------
+
+- Fix infinite recursion when subclassing long and overriding __hash__.
+
+- Fix concatenation (+=) of long strings.
+
+- Unicode objects will no longer raise an exception when being
+  compared equal or unequal to a string and a UnicodeDecodeError
+  exception occurs, e.g. as result of a decoding failure.
+
+  Instead, the equal (==) and unequal (!=) comparison operators will
+  now issue a UnicodeWarning and interpret the two objects as
+  unequal. The UnicodeWarning can be filtered as desired using
+  the warning framework, e.g. silenced completely, turned into an
+  exception, logged, etc.
+
+  Note that compare operators other than equal and unequal will still
+  raise UnicodeDecodeError exceptions as they've always done.
+
+- Fix segfault when doing string formatting on subclasses of long.
+
+- Fix bug related to __len__ functions using values > 2**32 on 64-bit machines
+  with new-style classes.
+
+- Fix bug related to __len__ functions returning negative values with
+  classic classes.
+
+- Patch #1538606, Fix __index__() clipping.  There were some problems
+  discovered with the API and how integers that didn't fit into Py_ssize_t
+  were handled.  This patch attempts to provide enough alternatives
+  to effectively use __index__.
+
+- Bug #1536021: __hash__ may now return long int; the final hash
+  value is obtained by invoking hash on the long int.
+
+- Bug #1536786: buffer comparison could emit a RuntimeWarning.
+
+- Bug #1535165: fixed a segfault in input() and raw_input() when
+  sys.stdin is closed.
+
+- On Windows, the PyErr_Warn function is now exported from
+  the Python dll again.
+
+- Bug #1191458: tracing over for loops now produces a line event
+  on each iteration.  Fixing this problem required changing the .pyc
+  magic number.  This means that .pyc files generated before 2.5c1
+  will be regenerated.
+
+- Bug #1333982: string/number constants were inappropriately stored
+  in the byte code and co_consts even if they were not used, ie
+  immediately popped off the stack.
+
+- Fixed a reference-counting problem in property().
+
+
+Library
+-------
+
+- Fix a bug in the ``compiler`` package that caused invalid code to be
+  generated for generator expressions.
+
+- The distutils version has been changed to 2.5.0. The change to
+  keep it programmatically in sync with the Python version running
+  the code (introduced in 2.5b3) has been reverted. It will continue
+  to be maintained manually as static string literal.
+
+- If the Python part of a ctypes callback function returns None,
+  and this cannot be converted to the required C type, an exception is
+  printed with PyErr_WriteUnraisable.  Before this change, the C
+  callback returned arbitrary values to the calling code.
+
+- The __repr__ method of a NULL ctypes.py_object() no longer raises
+  an exception.
+
+- uuid.UUID now has a bytes_le attribute. This returns the UUID in
+  little-endian byte order for Windows. In addition, uuid.py gained some
+  workarounds for clocks with low resolution, to stop the code yielding
+  duplicate UUIDs.
+
+- Patch #1540892: site.py Quitter() class attempts to close sys.stdin
+  before raising SystemExit, allowing IDLE to honor quit() and exit().
+
+- Bug #1224621: make tabnanny recognize IndentationErrors raised by tokenize.
+
+- Patch #1536071: trace.py should now find the full module name of a
+  file correctly even on Windows.
+
+- logging's atexit hook now runs even if the rest of the module has
+  already been cleaned up.
+
+- Bug #1112549, fix DoS attack on cgi.FieldStorage.
+
+- Bug #1531405, format_exception no longer raises an exception if
+  str(exception) raised an exception.
+
+- Fix a bug in the ``compiler`` package that caused invalid code to be
+  generated for nested functions.
+
+
+Extension Modules
+-----------------
+
+- Ignore data that arrives before the opening start tag in C etree.
+
+- Patch #1511317: don't crash on invalid hostname (alias) info.
+
+- Patch #1535500: fix segfault in BZ2File.writelines and make sure it
+  raises the correct exceptions.
+
+- Patch # 1536908: enable building ctypes on OpenBSD/AMD64.  The
+  '-no-stack-protector' compiler flag for OpenBSD has been removed.
+
+- Patch #1532975 was applied, which fixes Bug #1533481: ctypes now
+  uses the _as_parameter_ attribute when objects are passed to foreign
+  function calls.  The ctypes version number was changed to 1.0.1.
+
+- Bug #1530559, struct.pack raises TypeError where it used to convert.
+  Passing float arguments to struct.pack when integers are expected
+  now triggers a DeprecationWarning.
+
+
+Tests
+-----
+
+- test_socketserver should now work on cygwin and not fail sporadically
+  on other platforms.
+
+- test_mailbox should now work on cygwin versions 2006-08-10 and later.
+
+- Bug #1535182: really test the xreadlines() method of bz2 objects.
+
+- test_threading now skips testing alternate thread stack sizes on
+  platforms that don't support changing thread stack size.
+
+
+Documentation
+-------------
+
+- Patch #1534922: unittest docs were corrected and enhanced.
+
+
+Build
+-----
+
+- Bug #1535502, build _hashlib on Windows, and use masm assembler
+  code in OpenSSL.
+
+- Bug #1534738, win32 debug version of _msi should be _msi_d.pyd.
+
+- Bug #1530448, ctypes build failure on Solaris 10 was fixed.
+
+
+C API
+-----
+
+- New API for Unicode rich comparisons: PyUnicode_RichCompare()
+
+- Bug #1069160.  Internal correctness changes were made to
+  ``PyThreadState_SetAsyncExc()``.  A test case was added, and
+  the documentation was changed to state that the return value
+  is always 1 (normal) or 0 (if the specified thread wasn't found).
+
+
+What's New in Python 2.5 beta 3?
+================================
+
+*Release date: 03-AUG-2006*
+
+Core and builtins
+-----------------
+
+- _PyWeakref_GetWeakrefCount() now returns a Py_ssize_t; it previously
+  returned a long (see PEP 353).
+
+- Bug #1515471: string.replace() accepts character buffers again.
+
+- Add PyErr_WarnEx() so C code can pass the stacklevel to warnings.warn().
+  This provides the proper warning for struct.pack().
+  PyErr_Warn() is now deprecated in favor of PyErr_WarnEx().
+
+- Patch #1531113: Fix augmented assignment with yield expressions.
+  Also fix a SystemError when trying to assign to yield expressions.
+
+- Bug #1529871: The speed enhancement patch #921466 broke Python's compliance
+  with PEP 302.  This was fixed by adding an ``imp.NullImporter`` type that is
+  used in ``sys.path_importer_cache`` to cache non-directory paths and avoid
+  excessive filesystem operations during imports.
+
+- Bug #1521947: When checking for overflow, ``PyOS_strtol()`` used some
+  operations on signed longs that are formally undefined by C.
+  Unfortunately, at least one compiler now cares about that, so complicated
+  the code to make that compiler happy again.
+
+- Bug #1524310: Properly report errors from FindNextFile in os.listdir.
+
+- Patch #1232023: Stop including current directory in search
+  path on Windows.
+
+- Fix some potential crashes found with failmalloc.
+
+- Fix warnings reported by Klocwork's static analysis tool.
+
+- Bug #1512814, Fix incorrect lineno's when code within a function
+  had more than 255 blank lines.
+
+- Patch #1521179: Python now accepts the standard options ``--help`` and
+  ``--version`` as well as ``/?`` on Windows.
+
+- Bug #1520864: unpacking singleton tuples in a 'for' loop (for x, in) works
+  again.  Fixing this problem required changing the .pyc magic number.
+  This means that .pyc files generated before 2.5b3 will be regenerated.
+
+- Bug #1524317:  Compiling Python ``--without-threads`` failed.
+  The Python core compiles again, and, in a build without threads, the
+  new ``sys._current_frames()`` returns a dictionary with one entry,
+  mapping the faux "thread id" 0 to the current frame.
+
+- Bug #1525447: build on MacOS X on a case-sensitive filesystem.
+
+
+Library
+-------
+
+- Correction of patch #1455898: In the mbcs decoder, set final=False
+  for stream decoder, but final=True for the decode function.
+
+- os.urandom no longer masks unrelated exceptions like SystemExit or
+  KeyboardInterrupt.
+
+- Bug #1525866: Don't copy directory stat times in
+  shutil.copytree on Windows
+
+- Bug #1002398: The documentation for os.path.sameopenfile now correctly
+  refers to file descriptors, not file objects.
+
+- The renaming of the xml package to xmlcore, and the import hackery done
+  to make it appear at both names, has been removed.  Bug #1511497,
+  #1513611, and probably others.
+
+- Bug #1441397: The compiler module now recognizes module and function
+  docstrings correctly as it did in Python 2.4.
+
+- Bug #1529297:  The rewrite of doctest for Python 2.4 unintentionally
+  lost that tests are sorted by name before being run.  This rarely
+  matters for well-written tests, but can create baffling symptoms if
+  side effects from one test to the next affect outcomes.  ``DocTestFinder``
+  has been changed to sort the list of tests it returns.
+
+- The distutils version has been changed to 2.5.0, and is now kept
+  in sync with sys.version_info[:3].
+
+- Bug #978833: Really close underlying socket in _socketobject.close.
+
+- Bug #1459963: urllib and urllib2 now normalize HTTP header names with
+  title().
+
+- Patch #1525766: In pkgutil.walk_packages, correctly pass the onerror callback
+  to recursive calls and call it with the failing package name.
+
+- Bug #1525817: Don't truncate short lines in IDLE's tool tips.
+
+- Patch #1515343: Fix printing of deprecated string exceptions with a
+  value in the traceback module.
+
+- Resync optparse with Optik 1.5.3: minor tweaks for/to tests.
+
+- Patch #1524429: Use repr() instead of backticks in Tkinter again.
+
+- Bug #1520914: Change time.strftime() to accept a zero for any position in its
+  argument tuple.  For arguments where zero is illegal, the value is forced to
+  the minimum value that is correct.  This is to support an undocumented but
+  common way people used  to fill in inconsequential information in the time
+  tuple pre-2.4.
+
+- Patch #1220874: Update the binhex module for Mach-O.
+
+- The email package has improved RFC 2231 support, specifically for
+  recognizing the difference between encoded (name*0*=<blah>) and non-encoded
+  (name*0=<blah>) parameter continuations.  This may change the types of
+  values returned from email.message.Message.get_param() and friends.
+  Specifically in some cases where non-encoded continuations were used,
+  get_param() used to return a 3-tuple of (None, None, string) whereas now it
+  will just return the string (since non-encoded continuations don't have
+  charset and language parts).
+
+  Also, whereas % values were decoded in all parameter continuations, they are
+  now only decoded in encoded parameter parts.
+
+- Bug #1517990: IDLE keybindings on MacOS X now work correctly
+
+- Bug #1517996: IDLE now longer shows the default Tk menu when a
+  path browser, class browser or debugger is the frontmost window on MacOS X
+
+- Patch #1520294: Support for getset and member descriptors in types.py,
+  inspect.py, and pydoc.py.  Specifically, this allows for querying the type
+  of an object against these built-in types and more importantly, for getting
+  their docstrings printed in the interactive interpreter's help() function.
+
+
+Extension Modules
+-----------------
+
+- Patch #1519025 and bug #926423: If a KeyboardInterrupt occurs during
+  a socket operation on a socket with a timeout, the exception will be
+  caught correctly.  Previously, the exception was not caught.
+
+- Patch #1529514: The _ctypes extension is now compiled on more
+  openbsd target platforms.
+
+- The ``__reduce__()`` method of the new ``collections.defaultdict`` had
+  a memory leak, affecting pickles and deep copies.
+
+- Bug #1471938: Fix curses module build problem on Solaris 8; patch by
+  Paul Eggert.
+
+- Patch #1448199: Release interpreter lock in _winreg.ConnectRegistry.
+
+- Patch #1521817: Index range checking on ctypes arrays containing
+  exactly one element enabled again.  This allows iterating over these
+  arrays, without the need to check the array size before.
+
+- Bug #1521375: When the code in ctypes.util.find_library was
+  run with root privileges, it could overwrite or delete
+  /dev/null in certain cases; this is now fixed.
+
+- Bug #1467450: On Mac OS X 10.3, RTLD_GLOBAL is now used as the
+  default mode for loading shared libraries in ctypes.
+
+- Because of a misspelled preprocessor symbol, ctypes was always
+  compiled without thread support; this is now fixed.
+
+- pybsddb Bug #1527939: bsddb module DBEnv dbremove and dbrename
+  methods now allow their database parameter to be None as the
+  sleepycat API allows.
+
+- Bug #1526460: Fix socketmodule compile on NetBSD as it has a different
+  bluetooth API compared with Linux and FreeBSD.
+
+Tests
+-----
+
+- Bug #1501330: Change test_ossaudiodev to be much more tolerant in terms of
+  how long the test file should take to play.  Now accepts taking 2.93 secs
+  (exact time) +/- 10% instead of the hard-coded 3.1 sec.
+
+- Patch #1529686: The standard tests ``test_defaultdict``, ``test_iterlen``,
+  ``test_uuid`` and ``test_email_codecs`` didn't actually run any tests when
+  run via ``regrtest.py``. Now they do.
+
+Build
+-----
+
+- Bug #1439538: Drop usage of test -e in configure as it is not portable.
+
+Mac
+---
+
+- PythonLauncher now works correctly when the path to the script contains
+  characters that are treated specially by the shell (such as quotes).
+
+- Bug #1527397: PythonLauncher now launches scripts with the working directory
+  set to the directory that contains the script instead of the user home
+  directory. That latter was an implementation accident and not what users
+  expect.
+
+
+What's New in Python 2.5 beta 2?
+================================
+
+*Release date: 11-JUL-2006*
+
+Core and builtins
+-----------------
+
+- Bug #1441486: The literal representation of -(sys.maxint - 1)
+  again evaluates to a int object, not a long.
+
+- Bug #1501934: The scope of global variables that are locally assigned
+  using augmented assignment is now correctly determined.
+
+- Bug #927248: Recursive method-wrapper objects can now safely
+  be released.
+
+- Bug #1417699: Reject locale-specific decimal point in float()
+  and atof().
+
+- Bug #1511381: codec_getstreamcodec() in codec.c is corrected to
+  omit a default "error" argument for NULL pointer.  This allows
+  the parser to take a codec from cjkcodecs again.
+
+- Bug #1519018: 'as' is now validated properly in import statements.
+
+- On 64 bit systems, int literals that use less than 64 bits are
+  now ints rather than longs.
+
+- Bug #1512814, Fix incorrect lineno's when code at module scope
+  started after line 256.
+
+- New function ``sys._current_frames()`` returns a dict mapping thread
+  id to topmost thread stack frame.  This is for expert use, and is
+  especially useful for debugging application deadlocks.  The functionality
+  was previously available in Fazal Majid's ``threadframe`` extension
+  module, but it wasn't possible to do this in a wholly threadsafe way from
+  an extension.
+
+Library
+-------
+
+- Bug #1257728: Mention Cygwin in distutils error message about a missing
+  VS 2003.
+
+- Patch #1519566: Update turtle demo, make begin_fill idempotent.
+
+- Bug #1508010: msvccompiler now requires the DISTUTILS_USE_SDK
+  environment variable to be set in order to the SDK environment
+  for finding the compiler, include files, etc.
+
+- Bug #1515998: Properly generate logical ids for files in bdist_msi.
+
+- warnings.py now ignores ImportWarning by default
+
+- string.Template() now correctly handles tuple-values. Previously,
+  multi-value tuples would raise an exception and single-value tuples would
+  be treated as the value they contain, instead.
+
+- Bug #822974: Honor timeout in telnetlib.{expect,read_until}
+  even if some data are received.
+
+- Bug #1267547: Put proper recursive setup.py call into the
+  spec file generated by bdist_rpm.
+
+- Bug #1514693: Update turtle's heading when switching between
+  degrees and radians.
+
+- Reimplement turtle.circle using a polyline, to allow correct
+  filling of arcs.
+
+- Bug #1514703: Only setup canvas window in turtle when the canvas
+  is created.
+
+- Bug #1513223: .close() of a _socketobj now releases the underlying
+  socket again, which then gets closed as it becomes unreferenced.
+
+- Bug #1504333: Make sgmllib support angle brackets in quoted
+  attribute values.
+
+- Bug #853506: Fix IPv6 address parsing in unquoted attributes in
+  sgmllib ('[' and ']' were not accepted).
+
+- Fix a bug in the turtle module's end_fill function.
+
+- Bug #1510580: The 'warnings' module improperly required that a Warning
+  category be either a types.ClassType and a subclass of Warning.  The proper
+  check is just that it is a subclass with Warning as the documentation states.
+
+- The compiler module now correctly compiles the new try-except-finally
+  statement (bug #1509132).
+
+- The wsgiref package is now installed properly on Unix.
+
+- A bug was fixed in logging.config.fileConfig() which caused a crash on
+  shutdown when fileConfig() was called multiple times.
+
+- The sqlite3 module did cut off data from the SQLite database at the first
+  null character before sending it to a custom converter. This has been fixed
+  now.
+
+Extension Modules
+-----------------
+
+- #1494314: Fix a regression with high-numbered sockets in 2.4.3. This
+  means that select() on sockets > FD_SETSIZE (typically 1024) work again.
+  The patch makes sockets use poll() internally where available.
+
+- Assigning None to pointer type fields in ctypes structures possible
+  overwrote the wrong fields, this is fixed now.
+
+- Fixed a segfault in _ctypes when ctypes.wintypes were imported
+  on non-Windows platforms.
+
+- Bug #1518190: The ctypes.c_void_p constructor now accepts any
+  integer or long, without range checking.
+
+- Patch #1517790: It is now possible to use custom objects in the ctypes
+  foreign function argtypes sequence as long as they provide a from_param
+  method, no longer is it required that the object is a ctypes type.
+
+- The '_ctypes' extension module now works when Python is configured
+  with the --without-threads option.
+
+- Bug #1513646: os.access on Windows now correctly determines write
+  access, again.
+
+- Bug #1512695: cPickle.loads could crash if it was interrupted with
+  a KeyboardInterrupt.
+
+- Bug #1296433: parsing XML with a non-default encoding and
+  a CharacterDataHandler could crash the interpreter in pyexpat.
+
+- Patch #1516912: improve Modules support for OpenVMS.
+
+Build
+-----
+
+- Automate Windows build process for the Win64 SSL module.
+
+- 'configure' now detects the zlib library the same way as distutils.
+  Previously, the slight difference could cause compilation errors of the
+  'zlib' module on systems with more than one version of zlib.
+
+- The MSI compileall step was fixed to also support a TARGETDIR
+  with spaces in it.
+
+- Bug #1517388: sqlite3.dll is now installed on Windows independent
+  of Tcl/Tk.
+
+- Bug #1513032: 'make install' failed on FreeBSD 5.3 due to lib-old
+  trying to be installed even though it's empty.
+
+Tests
+-----
+
+- Call os.waitpid() at the end of tests that spawn child processes in order
+  to minimize resources (zombies).
+
+Documentation
+-------------
+
+- Cover ImportWarning, PendingDeprecationWarning and simplefilter() in the
+  documentation for the warnings module.
+
+- Patch #1509163: MS Toolkit Compiler no longer available.
+
+- Patch #1504046: Add documentation for xml.etree.
+
+
+What's New in Python 2.5 beta 1?
+================================
+
+*Release date: 20-JUN-2006*
+
+Core and builtins
+-----------------
+
+- Patch #1507676: Error messages returned by invalid abstract object operations
+  (such as iterating over an integer) have been improved and now include the
+  type of the offending object to help with debugging.
+
+- Bug #992017: A classic class that defined a __coerce__() method that returned
+  its arguments swapped would infinitely recurse and segfault the interpreter.
+
+- Fix the socket tests so they can be run concurrently.
+
+- Removed 5 integers from C frame objects (PyFrameObject).
+  f_nlocals, f_ncells, f_nfreevars, f_stack_size, f_restricted.
+
+- Bug #532646: object.__call__() will continue looking for the __call__
+  attribute on objects until one without one is found.  This leads to recursion
+  when you take a class and set its __call__ attribute to an instance of the
+  class.  Originally fixed for classic classes, but this fix is for new-style.
+  Removes the infinite_rec_3 crasher.
+
+- The string and unicode methods startswith() and endswith() now accept
+  a tuple of prefixes/suffixes to look for. Implements RFE #1491485.
+
+- Buffer objects, at the C level, never used the char buffer
+  implementation even when the char buffer for the wrapped object was
+  explicitly requested (originally returned the read or write buffer).
+  Now a TypeError is raised if the char buffer is not present but is
+  requested.
+
+- Patch #1346214: Statements like "if 0: suite" are now again optimized
+  away like they were in Python 2.4.
+
+- Builtin exceptions are now full-blown new-style classes instead of
+  instances pretending to be classes, which speeds up exception handling
+  by about 80% in comparison to 2.5a2.
+
+- Patch #1494554: Update unicodedata.numeric and unicode.isnumeric to
+  Unicode 4.1.
+
+- Patch #921466: sys.path_importer_cache is now used to cache valid and
+  invalid file paths for the built-in import machinery which leads to
+  fewer open calls on startup.
+
+- Patch #1442927: ``long(str, base)`` is now up to 6x faster for non-power-
+  of-2 bases.  The largest speedup is for inputs with about 1000 decimal
+  digits.  Conversion from non-power-of-2 bases remains quadratic-time in
+  the number of input digits (it was and remains linear-time for bases
+  2, 4, 8, 16 and 32).
+
+- Bug #1334662: ``int(string, base)`` could deliver a wrong answer
+  when ``base`` was not 2, 4, 8, 10, 16 or 32, and ``string`` represented
+  an integer close to ``sys.maxint``.  This was repaired by patch
+  #1335972, which also gives a nice speedup.
+
+- Patch #1337051: reduced size of frame objects.
+
+- PyErr_NewException now accepts a tuple of base classes as its
+  "base" parameter.
+
+- Patch #876206: function call speedup by retaining allocated frame
+  objects.
+
+- Bug #1462152: file() now checks more thoroughly for invalid mode
+  strings and removes a possible "U" before passing the mode to the
+  C library function.
+
+- Patch #1488312, Fix memory alignment problem on SPARC in unicode
+
+- Bug #1487966: Fix SystemError with conditional expression in assignment
+
+- WindowsError now has two error code attributes: errno, which carries
+  the error values from errno.h, and winerror, which carries the error
+  values from winerror.h. Previous versions put the winerror.h values
+  (from GetLastError()) into the errno attribute.
+
+- Patch #1475845: Raise IndentationError for unexpected indent.
+
+- Patch #1479181: split open() and file() from being aliases for each other.
+
+- Patch #1497053 & bug #1275608: Exceptions occurring in ``__eq__()``
+  methods were always silently ignored by dictionaries when comparing keys.
+  They are now passed through (except when using the C API function
+  ``PyDict_GetItem()``, whose semantics did not change).
+
+- Bug #1456209: In some obscure cases it was possible for a class with a
+  custom ``__eq__()`` method to confuse dict internals when class instances
+  were used as a dict's keys and the ``__eq__()`` method mutated the dict.
+  No, you don't have any code that did this ;-)
+
+Extension Modules
+-----------------
+
+- Bug #1295808: expat symbols should be namespaced in pyexpat
+
+- Patch #1462338: Upgrade pyexpat to expat 2.0.0
+
+- Change binascii.hexlify to accept a read-only buffer instead of only a char
+  buffer and actually follow its documentation.
+
+- Fixed a potentially invalid memory access of CJKCodecs' shift-jis decoder.
+
+- Patch #1478788 (modified version): The functional extension module has
+  been renamed to _functools and a functools Python wrapper module added.
+  This provides a home for additional function related utilities that are
+  not specifically about functional programming. See PEP 309.
+
+- Patch #1493701: performance enhancements for struct module.
+
+- Patch #1490224: time.altzone is now set correctly on Cygwin.
+
+- Patch #1435422: zlib's compress and decompress objects now have a
+  copy() method.
+
+- Patch #1454481: thread stack size is now tunable at runtime for thread
+  enabled builds on Windows and systems with Posix threads support.
+
+- On Win32, os.listdir now supports arbitrarily-long Unicode path names
+  (up to the system limit of 32K characters).
+
+- Use Win32 API to implement os.{access,chdir,chmod,mkdir,remove,rename,rmdir,utime}.
+  As a result, these functions now raise WindowsError instead of OSError.
+
+- ``time.clock()`` on Win64 should use the high-performance Windows
+  ``QueryPerformanceCounter()`` now (as was already the case on 32-bit
+  Windows platforms).
+
+- Calling Tk_Init twice is refused if the first call failed as that
+  may deadlock.
+
+- bsddb: added the DB_ARCH_REMOVE flag and fixed db.DBEnv.log_archive() to
+  accept it without potentially using an uninitialized pointer.
+
+- bsddb: added support for the DBEnv.log_stat() and DBEnv.lsn_reset() methods
+  assuming BerkeleyDB >= 4.0 and 4.4 respectively.  [pybsddb project SF
+  patch numbers 1494885 and 1494902]
+
+- bsddb: added an interface for the BerkeleyDB >= 4.3 DBSequence class.
+  [pybsddb project SF patch number 1466734]
+
+- bsddb: fix DBCursor.pget() bug with keyword argument names when no data
+  parameter is supplied.  [SF pybsddb bug #1477863]
+
+- bsddb: the __len__ method of a DB object has been fixed to return correct
+  results.  It could previously incorrectly return 0 in some cases.
+  Fixes SF bug 1493322 (pybsddb bug 1184012).
+
+- bsddb: the bsddb.dbtables Modify method now raises the proper error and
+  aborts the db transaction safely when a modifier callback fails.
+  Fixes SF python patch/bug #1408584.
+
+- bsddb: multithreaded DB access using the simple bsddb module interface
+  now works reliably.  It has been updated to use automatic BerkeleyDB
+  deadlock detection and the bsddb.dbutils.DeadlockWrap wrapper to retry
+  database calls that would previously deadlock. [SF python bug #775414]
+
+- Patch #1446489: add support for the ZIP64 extensions to zipfile.
+
+- Patch #1506645: add Python wrappers for the curses functions
+  is_term_resized, resize_term and resizeterm.
+
+Library
+-------
+
+- Patch #815924: Restore ability to pass type= and icon= in tkMessageBox
+  functions.
+
+- Patch #812986: Update turtle output even if not tracing.
+
+- Patch #1494750: Destroy master after deleting children in
+  Tkinter.BaseWidget.
+
+- Patch #1096231: Add ``default`` argument to Tkinter.Wm.wm_iconbitmap.
+
+- Patch #763580: Add name and value arguments to Tkinter variable
+  classes.
+
+- Bug #1117556: SimpleHTTPServer now tries to find and use the system's
+  mime.types file for determining MIME types.
+
+- Bug #1339007: Shelf objects now don't raise an exception in their
+  __del__ method when initialization failed.
+
+- Patch #1455898: The MBCS codec now supports the incremental mode for
+  double-byte encodings.
+
+- ``difflib``'s ``SequenceMatcher.get_matching_blocks()`` was changed to
+  guarantee that adjacent triples in the return list always describe
+  non-adjacent blocks.  Previously, a pair of matching blocks could end
+  up being described by multiple adjacent triples that formed a partition
+  of the matching pair.
+
+- Bug #1498146: fix optparse to handle Unicode strings in option help,
+  description, and epilog.
+
+- Bug #1366250: minor optparse documentation error.
+
+- Bug #1361643: fix textwrap.dedent() so it handles tabs appropriately;
+  clarify docs.
+
+- The wsgiref package has been added to the standard library.
+
+- The functions update_wrapper() and wraps() have been added to the functools
+  module. These make it easier to copy relevant metadata from the original
+  function when writing wrapper functions.
+
+- The optional ``isprivate`` argument to ``doctest.testmod()``, and the
+  ``doctest.is_private()`` function, both deprecated in 2.4, were removed.
+
+- Patch #1359618: Speed up charmap encoder by using a trie structure
+  for lookup.
+
+- The functions in the ``pprint`` module now sort dictionaries by key
+  before computing the display.  Before 2.5, ``pprint`` sorted a dictionary
+  if and only if its display required more than one line, although that
+  wasn't documented.  The new behavior increases predictability; e.g.,
+  using ``pprint.pprint(a_dict)`` in a doctest is now reliable.
+
+- Patch #1497027: try HTTP digest auth before basic auth in urllib2
+  (thanks for J. J. Lee).
+
+- Patch #1496206: improve urllib2 handling of passwords with respect to
+  default HTTP and HTTPS ports.
+
+- Patch #1080727: add "encoding" parameter to doctest.DocFileSuite.
+
+- Patch #1281707: speed up gzip.readline.
+
+- Patch #1180296: Two new functions were added to the locale module:
+  format_string() to get the effect of  "format % items" but locale-aware,
+  and currency() to format a monetary number with currency sign.
+
+- Patch #1486962: Several bugs in the turtle Tk demo module were fixed
+  and several features added, such as speed and geometry control.
+
+- Patch #1488881: add support for external file objects in bz2 compressed
+  tarfiles.
+
+- Patch #721464: pdb.Pdb instances can now be given explicit stdin and
+  stdout arguments, making it possible to redirect input and output
+  for remote debugging.
+
+- Patch #1484695: Update the tarfile module to version 0.8. This fixes
+  a couple of issues, notably handling of long file names using the
+  GNU LONGNAME extension.
+
+- Patch #1478292. ``doctest.register_optionflag(name)`` shouldn't create a
+  new flag when ``name`` is already the name of an option flag.
+
+- Bug #1385040: don't allow "def foo(a=1, b): pass" in the compiler
+  package.
+
+- Patch #1472854: make the rlcompleter.Completer class usable on non-
+  UNIX platforms.
+
+- Patch #1470846: fix urllib2 ProxyBasicAuthHandler.
+
+- Bug #1472827: correctly escape newlines and tabs in attribute values in
+  the saxutils.XMLGenerator class.
+
+
+Build
+-----
+
+- Bug #1502728: Correctly link against librt library on HP-UX.
+
+- OpenBSD 3.9 is supported now.
+
+- Patch #1492356: Port to Windows CE.
+
+- Bug/Patch #1481770: Use .so extension for shared libraries on HP-UX for ia64.
+
+- Patch #1471883: Add --enable-universalsdk.
+
+C API
+-----
+
+Tests
+-----
+
+Tools
+-----
+
+Documentation
+-------------
+
+
+
+What's New in Python 2.5 alpha 2?
+=================================
+
+*Release date: 27-APR-2006*
+
+Core and builtins
+-----------------
+
+- Bug #1465834: 'bdist_wininst preinstall script support' was fixed
+  by converting these apis from macros into exported functions again:
+
+    PyParser_SimpleParseFile PyParser_SimpleParseString PyRun_AnyFile
+    PyRun_AnyFileEx PyRun_AnyFileFlags PyRun_File PyRun_FileEx
+    PyRun_FileFlags PyRun_InteractiveLoop PyRun_InteractiveOne
+    PyRun_SimpleFile PyRun_SimpleFileEx PyRun_SimpleString
+    PyRun_String Py_CompileString
+
+- Under COUNT_ALLOCS, types are not necessarily immortal anymore.
+
+- All uses of PyStructSequence_InitType have been changed to initialize
+  the type objects only once, even if the interpreter is initialized
+  multiple times.
+
+- Bug #1454485, array.array('u') could crash the interpreter.  This was
+  due to PyArgs_ParseTuple(args, 'u#', ...) trying to convert buffers (strings)
+  to unicode when it didn't make sense.  'u#' now requires a unicode string.
+
+- Py_UNICODE is unsigned.  It was always documented as unsigned, but
+  due to a bug had a signed value in previous versions.
+
+- Patch #837242: ``id()`` of any Python object always gives a positive
+  number now, which might be a long integer. ``PyLong_FromVoidPtr`` and
+  ``PyLong_AsVoidPtr`` have been changed accordingly.  Note that it has
+  never been correct to implement a ``__hash()__`` method that returns the
+  ``id()`` of an object:
+
+      def __hash__(self):
+          return id(self)  # WRONG
+
+  because a hash result must be a (short) Python int but it was always
+  possible for ``id()`` to return a Python long.  However, because ``id()``
+  could return negative values before, on a 32-bit box an ``id()`` result
+  was always usable as a hash value before this patch.  That's no longer
+  necessarily so.
+
+- Python on OS X 10.3 and above now uses dlopen() (via dynload_shlib.c)
+  to load extension modules and now provides the dl module. As a result,
+  sys.setdlopenflags() now works correctly on these systems. (SF patch
+  #1454844)
+
+- Patch #1463867: enhanced garbage collection to allow cleanup of cycles
+  involving generators that have paused outside of any ``try`` or ``with``
+  blocks.  (In 2.5a1, a paused generator that was part of a reference
+  cycle could not be garbage collected, regardless of whether it was
+  paused in a ``try`` or ``with`` block.)
+
+Extension Modules
+-----------------
+
+- Patch #1191065: Fix preprocessor problems on systems where recvfrom
+  is a macro.
+
+- Bug #1467952: os.listdir() now correctly raises an error if readdir()
+  fails with an error condition.
+
+- Fixed bsddb.db.DBError derived exceptions so they can be unpickled.
+
+- Bug #1117761: bsddb.*open() no longer raises an exception when using
+  the cachesize parameter.
+
+- Bug #1149413: bsddb.*open() no longer raises an exception when using
+  a temporary db (file=None) with the 'n' flag to truncate on open.
+
+- Bug #1332852: bsddb module minimum BerkeleyDB version raised to 3.3
+  as older versions cause excessive test failures.
+
+- Patch #1062014: AF_UNIX sockets under Linux have a special
+  abstract namespace that is now fully supported.
+
+Library
+-------
+
+- Bug #1223937: subprocess.CalledProcessError reports the exit status
+  of the process using the returncode attribute, instead of
+  abusing errno.
+
+- Patch #1475231: ``doctest`` has a new ``SKIP`` option, which causes
+  a doctest to be skipped (the code is not run, and the expected output
+  or exception is ignored).
+
+- Fixed contextlib.nested to cope with exceptions being raised and
+  caught inside exit handlers.
+
+- Updated optparse module to Optik 1.5.1 (allow numeric constants in
+  hex, octal, or binary; add ``append_const`` action; keep going if
+  gettext cannot be imported; added ``OptionParser.destroy()`` method;
+  added ``epilog`` for better help generation).
+
+- Bug #1473760: ``tempfile.TemporaryFile()`` could hang on Windows, when
+  called from a thread spawned as a side effect of importing a module.
+
+- The pydoc module now supports documenting packages contained in
+  .zip or .egg files.
+
+- The pkgutil module now has several new utility functions, such
+  as ``walk_packages()`` to support working with packages that are either
+  in the filesystem or zip files.
+
+- The mailbox module can now modify and delete messages from
+  mailboxes, in addition to simply reading them.  Thanks to Gregory
+  K. Johnson for writing the code, and to the 2005 Google Summer of
+  Code for funding his work.
+
+- The ``__del__`` method of class ``local`` in module ``_threading_local``
+  returned before accomplishing any of its intended cleanup.
+
+- Patch #790710: Add breakpoint command lists in pdb.
+
+- Patch #1063914: Add Tkinter.Misc.clipboard_get().
+
+- Patch #1191700: Adjust column alignment in bdb breakpoint lists.
+
+- SimpleXMLRPCServer relied on the fcntl module, which is unavailable on
+  Windows. Bug #1469163.
+
+- The warnings, linecache, inspect, traceback, site, and doctest modules
+  were updated to work correctly with modules imported from zipfiles or
+  via other PEP 302 __loader__ objects.
+
+- Patch #1467770: Reduce usage of subprocess._active to processes which
+  the application hasn't waited on.
+
+- Patch #1462222: Fix Tix.Grid.
+
+- Fix exception when doing glob.glob('anything*/')
+
+- The pstats.Stats class accepts an optional stream keyword argument to
+  direct output to an alternate file-like object.
+
+Build
+-----
+
+- The Makefile now has a reindent target, which runs reindent.py on
+  the library.
+
+- Patch #1470875: Building Python with MS Free Compiler
+
+- Patch #1161914: Add a python-config script.
+
+- Patch #1324762:Remove ccpython.cc; replace --with-cxx with
+  --with-cxx-main. Link with C++ compiler only if --with-cxx-main was
+  specified. (Can be overridden by explicitly setting LINKCC.) Decouple
+  CXX from --with-cxx-main, see description in README.
+
+- Patch #1429775: Link extension modules with the shared libpython.
+
+- Fixed a libffi build problem on MIPS systems.
+
+- ``PyString_FromFormat``, ``PyErr_Format``, and ``PyString_FromFormatV``
+  now accept formats "%u" for unsigned ints, "%lu" for unsigned longs,
+  and "%zu" for unsigned integers of type ``size_t``.
+
+Tests
+-----
+
+- test_contextlib now checks contextlib.nested can cope with exceptions
+  being raised and caught inside exit handlers.
+
+- test_cmd_line now checks operation of the -m and -c command switches
+
+- The test_contextlib test in 2.5a1 wasn't actually run unless you ran
+  it separately and by hand.  It also wasn't cleaning up its changes to
+  the current Decimal context.
+
+- regrtest.py now has a -M option to run tests that test the new limits of
+  containers, on 64-bit architectures. Running these tests is only sensible
+  on 64-bit machines with more than two gigabytes of memory. The argument
+  passed is the maximum amount of memory for the tests to use.
+
+Tools
+-----
+
+- Added the Python benchmark suite pybench to the Tools/ directory;
+  contributed by Marc-Andre Lemburg.
+
+Documentation
+-------------
+
+- Patch #1473132: Improve docs for ``tp_clear`` and ``tp_traverse``.
+
+- PEP 343: Added Context Types section to the library reference
+  and attempted to bring other PEP 343 related documentation into
+  line with the implementation and/or python-dev discussions.
+
+- Bug #1337990: clarified that ``doctest`` does not support examples
+  requiring both expected output and an exception.
+
+
+What's New in Python 2.5 alpha 1?
+=================================
+
+*Release date: 05-APR-2006*
+
+Core and builtins
+-----------------
+
+- PEP 338: -m command line switch now delegates to runpy.run_module
+  allowing it to support modules in packages and zipfiles
+
+- On Windows, .DLL is not an accepted file name extension for
+  extension modules anymore; extensions are only found if they
+  end in .PYD.
+
+- Bug #1421664: sys.stderr.encoding is now set to the same value as
+  sys.stdout.encoding.
+
+- __import__ accepts keyword arguments.
+
+- Patch #1460496: round() now accepts keyword arguments.
+
+- Fixed bug #1459029 - unicode reprs were double-escaped.
+
+- Patch #1396919: The system scope threads are reenabled on FreeBSD
+  5.4 and later versions.
+
+- Bug #1115379: Compiling a Unicode string with an encoding declaration
+  now gives a SyntaxError.
+
+- Previously, Python code had no easy way to access the contents of a
+  cell object. Now, a ``cell_contents`` attribute has been added
+  (closes patch #1170323).
+
+- Patch #1123430: Python's small-object allocator now returns an arena to
+  the system ``free()`` when all memory within an arena becomes unused
+  again.  Prior to Python 2.5, arenas (256KB chunks of memory) were never
+  freed.  Some applications will see a drop in virtual memory size now,
+  especially long-running applications that, from time to time, temporarily
+  use a large number of small objects.  Note that when Python returns an
+  arena to the platform C's ``free()``, there's no guarantee that the
+  platform C library will in turn return that memory to the operating system.
+  The effect of the patch is to stop making that impossible, and in tests it
+  appears to be effective at least on Microsoft C and gcc-based systems.
+  Thanks to Evan Jones for hard work and patience.
+
+- Patch #1434038: property() now uses the getter's docstring if there is
+  no "doc" argument given. This makes it possible to legitimately use
+  property() as a decorator to produce a read-only property.
+
+- PEP 357, patch 1436368: add an __index__ method to int/long and a matching
+  nb_index slot to the PyNumberMethods struct.  The slot is consulted instead
+  of requiring an int or long in slicing and a few other contexts, enabling
+  other objects (e.g. Numeric Python's integers) to be used as slice indices.
+
+- Fixed various bugs reported by Coverity's Prevent tool.
+
+- PEP 352, patch #1104669: Make exceptions new-style objects.  Introduced the
+  new exception base class, BaseException, which has a new message attribute.
+  KeyboardInterrupt and SystemExit to directly inherit from BaseException now.
+  Raising a string exception now raises a DeprecationWarning.
+
+- Patch #1438387, PEP 328: relative and absolute imports. Imports can now be
+  explicitly relative, using 'from .module import name' to mean 'from the same
+  package as this module is in. Imports without dots still default to the
+  old relative-then-absolute, unless 'from __future__ import
+  absolute_import' is used.
+
+- Properly check if 'warnings' raises an exception (usually when a filter set
+  to "error" is triggered) when raising a warning for raising string
+  exceptions.
+
+- CO_GENERATOR_ALLOWED is no longer defined. This behavior is the default.
+  The name was removed from Include/code.h.
+
+- PEP 308: conditional expressions were added: (x if cond else y).
+
+- Patch 1433928:
+  - The copy module now "copies" function objects (as atomic objects).
+  - dict.__getitem__ now looks for a __missing__ hook before raising
+    KeyError.
+
+- PEP 343: with statement implemented. Needs ``from __future__ import
+  with_statement``. Use of 'with' as a variable will generate a warning.
+  Use of 'as' as a variable will also generate a warning (unless it's
+  part of an import statement).
+  The following objects have __context__ methods:
+  - The built-in file type.
+  - The thread.LockType type.
+  - The following types defined by the threading module:
+    Lock, RLock, Condition, Semaphore, BoundedSemaphore.
+  - The decimal.Context class.
+
+- Fix the encodings package codec search function to only search
+  inside its own package. Fixes problem reported in patch #1433198.
+
+  Note: Codec packages should implement and register their own
+  codec search function. PEP 100 has the details.
+
+- PEP 353: Using ``Py_ssize_t`` as the index type.
+
+- ``PYMALLOC_DEBUG`` builds now add ``4*sizeof(size_t)`` bytes of debugging
+  info to each allocated block, since the ``Py_ssize_t`` changes (PEP 353)
+  now allow Python to make use of memory blocks exceeding 2**32 bytes for
+  some purposes on 64-bit boxes.  A ``PYMALLOC_DEBUG`` build was limited
+  to 4-byte allocations before.
+
+- Patch #1400181, fix unicode string formatting to not use the locale.
+  This is how string objects work.  u'%f' could use , instead of .
+  for the decimal point.  Now both strings and unicode always use periods.
+
+- Bug #1244610, #1392915, fix build problem on OpenBSD 3.7 and 3.8.
+  configure would break checking curses.h.
+
+- Bug #959576: The pwd module is now builtin. This allows Python to be
+  built on UNIX platforms without $HOME set.
+
+- Bug #1072182, fix some potential problems if characters are signed.
+
+- Bug #889500, fix line number on SyntaxWarning for global declarations.
+
+- Bug #1378022, UTF-8 files with a leading BOM crashed the interpreter.
+
+- Support for converting hex strings to floats no longer works.
+  This was not portable.  float('0x3') now raises a ValueError.
+
+- Patch #1382163: Expose Subversion revision number to Python.  New C API
+  function Py_GetBuildNumber().  New attribute sys.subversion.  Build number
+  is now displayed in interactive prompt banner.
+
+- Implementation of PEP 341 - Unification of try/except and try/finally.
+  "except" clauses can now be written together with a "finally" clause in
+  one try statement instead of two nested ones.  Patch #1355913.
+
+- Bug #1379994: Builtin unicode_escape and raw_unicode_escape codec
+  now encodes backslash correctly.
+
+- Patch #1350409: Work around signal handling bug in Visual Studio 2005.
+
+- Bug #1281408: Py_BuildValue now works correctly even with unsigned longs
+  and long longs.
+
+- SF Bug #1350188, "setdlopenflags" leads to crash upon "import"
+  It was possible for dlerror() to return a NULL pointer, so
+  it will now use a default error message in this case.
+
+- Replaced most Unicode charmap codecs with new ones using the
+  new Unicode translate string feature in the builtin charmap
+  codec; the codecs were created from the mapping tables available
+  at ftp.unicode.org and contain a few updates (e.g. the Mac OS
+  encodings now include a mapping for the Apple logo)
+
+- Added a few more codecs for Mac OS encodings
+
+- Sped up some Unicode operations.
+
+- A new AST parser implementation was completed. The abstract
+  syntax tree is available for read-only (non-compile) access
+  to Python code; an _ast module was added.
+
+- SF bug #1167751: fix incorrect code being produced for generator expressions.
+  The following code now raises a SyntaxError:  foo(a = i for i in range(10))
+
+- SF Bug #976608: fix SystemError when mtime of an imported file is -1.
+
+- SF Bug #887946: fix segfault when redirecting stdin from a directory.
+  Provide a warning when a directory is passed on the command line.
+
+- Fix segfault with invalid coding.
+
+- SF bug #772896: unknown encoding results in MemoryError.
+
+- All iterators now have a Boolean value of True.  Formerly, some iterators
+  supported a __len__() method which evaluated to False when the iterator
+  was empty.
+
+- On 64-bit platforms, when __len__() returns a value that cannot be
+  represented as a C int, raise OverflowError.
+
+- test__locale is skipped on OS X < 10.4 (only partial locale support is
+  present).
+
+- SF bug #893549: parsing keyword arguments was broken with a few format
+  codes.
+
+- Changes donated by Elemental Security to make it work on AIX 5.3
+  with IBM's 64-bit compiler (SF patch #1284289).  This also closes SF
+  bug #105470: test_pwd fails on 64bit system (Opteron).
+
+- Changes donated by Elemental Security to make it work on HP-UX 11 on
+  Itanium2 with HP's 64-bit compiler (SF patch #1225212).
+
+- Disallow keyword arguments for type constructors that don't use them
+  (fixes bug #1119418).
+
+- Forward UnicodeDecodeError into SyntaxError for source encoding errors.
+
+- SF bug #900092: When tracing (e.g. for hotshot), restore 'return' events for
+  exceptions that cause a function to exit.
+
+- The implementation of set() and frozenset() was revised to use its
+  own internal data structure.  Memory consumption is reduced by 1/3
+  and there are modest speed-ups as well.  The API is unchanged.
+
+- SF bug #1238681:  freed pointer is used in longobject.c:long_pow().
+
+- SF bug #1229429: PyObject_CallMethod failed to decrement some
+  reference counts in some error exit cases.
+
+- SF bug #1185883:  Python's small-object memory allocator took over
+  a block managed by the platform C library whenever a realloc specified
+  a small new size.  However, there's no portable way to know then how
+  much of the address space following the pointer is valid, so there's no
+  portable way to copy data from the C-managed block into Python's
+  small-object space without risking a memory fault.  Python's small-object
+  realloc now leaves such blocks under the control of the platform C
+  realloc.
+
+- SF bug #1232517: An overflow error was not detected properly when
+  attempting to convert a large float to an int in os.utime().
+
+- SF bug #1224347: hex longs now print with lowercase letters just
+  like their int counterparts.
+
+- SF bug #1163563: the original fix for bug #1010677 ("thread Module
+  Breaks PyGILState_Ensure()") broke badly in the case of multiple
+  interpreter states; back out that fix and do a better job (see
+  http://mail.python.org/pipermail/python-dev/2005-June/054258.html
+  for a longer write-up of the problem).
+
+- SF patch #1180995: marshal now uses a binary format by default when
+  serializing floats.
+
+- SF patch #1181301: on platforms that appear to use IEEE 754 floats,
+  the routines that promise to produce IEEE 754 binary representations
+  of floats now simply copy bytes around.
+
+- bug #967182: disallow opening files with 'wU' or 'aU' as specified by PEP
+  278.
+
+- patch #1109424: int, long, float, complex, and unicode now check for the
+  proper magic slot for type conversions when subclassed.  Previously the
+  magic slot was ignored during conversion.  Semantics now match the way
+  subclasses of str always behaved.  int/long/float, conversion of an instance
+  to the base class has been moved to the proper nb_* magic slot and out of
+  PyNumber_*().
+  Thanks Walter D�rwald.
+
+- Descriptors defined in C with a PyGetSetDef structure, where the setter is
+  NULL, now raise an AttributeError when attempting to set or delete the
+  attribute.  Previously a TypeError was raised, but this was inconsistent
+  with the equivalent pure-Python implementation.
+
+- It is now safe to call PyGILState_Release() before
+  PyEval_InitThreads() (note that if there is reason to believe there
+  are multiple threads around you still must call PyEval_InitThreads()
+  before using the Python API; this fix is for extension modules that
+  have no way of knowing if Python is multi-threaded yet).
+
+- Typing Ctrl-C whilst raw_input() was waiting in a build with threads
+  disabled caused a crash.
+
+- Bug #1165306: instancemethod_new allowed the creation of a method
+  with im_class == im_self == NULL, which caused a crash when called.
+
+- Move exception finalisation later in the shutdown process - this
+  fixes the crash seen in bug #1165761
+
+- Added two new builtins, any() and all().
+
+- Defining a class with empty parentheses is now allowed
+  (e.g., ``class C(): pass`` is no longer a syntax error).
+  Patch #1176012 added support to the 'parser' module and 'compiler' package
+  (thanks to logistix for that added support).
+
+- Patch #1115086: Support PY_LONGLONG in structmember.
+
+- Bug #1155938: new style classes did not check that __init__() was
+  returning None.
+
+- Patch #802188: Report characters after line continuation character
+  ('\') with a specific error message.
+
+- Bug #723201: Raise a TypeError for passing bad objects to 'L' format.
+
+- Bug #1124295: the __name__ attribute of file objects was
+  inadvertently made inaccessible in restricted mode.
+
+- Bug #1074011: closing sys.std{out,err} now causes a flush() and
+  an ferror() call.
+
+- min() and max() now support key= arguments with the same meaning as in
+  list.sort().
+
+- The peephole optimizer now performs simple constant folding in expressions:
+      (2+3) --> (5).
+
+- set and frozenset objects can now be marshalled.  SF #1098985.
+
+- Bug #1077106: Poor argument checking could cause memory corruption
+  in calls to os.read().
+
+- The parser did not complain about future statements in illegal
+  positions.  It once again reports a syntax error if a future
+  statement occurs after anything other than a doc string.
+
+- Change the %s format specifier for str objects so that it returns a
+  unicode instance if the argument is not an instance of basestring and
+  calling __str__ on the argument returns a unicode instance.
+
+- Patch #1413181:  changed ``PyThreadState_Delete()`` to forget about the
+  current thread state when the auto-GIL-state machinery knows about
+  it (since the thread state is being deleted, continuing to remember it
+  can't help, but can hurt if another thread happens to get created with
+  the same thread id).
+
+Extension Modules
+-----------------
+
+- Patch #1380952: fix SSL objects timing out on consecutive read()s
+
+- Patch #1309579: wait3 and wait4 were added to the posix module.
+
+- Patch #1231053: The audioop module now supports encoding/decoding of alaw.
+  In addition, the existing ulaw code was updated.
+
+- RFE #567972: Socket objects' family, type and proto properties are
+  now exposed via new attributes.
+
+- Everything under lib-old was removed.  This includes the following modules:
+    Para, addpack, cmp, cmpcache, codehack, dircmp, dump, find, fmt, grep,
+    lockfile, newdir, ni, packmail, poly, rand, statcache, tb, tzparse,
+    util, whatsound, whrandom, zmod
+
+- The following modules were removed:  regsub, reconvert, regex, regex_syntax.
+
+- re and sre were swapped, so help(re) provides full help.  importing sre
+  is deprecated.  The undocumented re.engine variable no longer exists.
+
+- Bug #1448490: Fixed a bug that ISO-2022 codecs could not handle
+  SS2 (single-shift 2) escape sequences correctly.
+
+- The unicodedata module was updated to the 4.1 version of the Unicode
+  database. The 3.2 version is still available as unicodedata.db_3_2_0
+  for applications that require this specific version (such as IDNA).
+
+- The timing module is no longer built by default.  It was deprecated
+  in PEP 4 in Python 2.0 or earlier.
+
+- Patch 1433928: Added a new type, defaultdict, to the collections module.
+  This uses the new __missing__ hook behavior added to dict (see above).
+
+- Bug #854823: socketmodule now builds on Sun platforms even when
+  INET_ADDRSTRLEN is not defined.
+
+- Patch #1393157: os.startfile() now has an optional argument to specify
+  a "command verb" to invoke on the file.
+
+- Bug #876637, prevent stack corruption when socket descriptor
+  is larger than FD_SETSIZE.
+
+- Patch #1407135, bug #1424041: harmonize mmap behavior of anonymous memory.
+  mmap.mmap(-1, size) now returns anonymous memory in both Unix and Windows.
+  mmap.mmap(0, size) should not be used on Windows for anonymous memory.
+
+- Patch #1422385: The nis module now supports access to domains other
+  than the system default domain.
+
+- Use Win32 API to implement os.stat/fstat. As a result, subsecond timestamps
+  are reported, the limit on path name lengths is removed, and stat reports
+  WindowsError now (instead of OSError).
+
+- Add bsddb.db.DBEnv.set_tx_timestamp allowing time based database recovery.
+
+- Bug #1413192, fix seg fault in bsddb if a transaction was deleted
+  before the env.
+
+- Patch #1103116: Basic AF_NETLINK support.
+
+- Bug #1402308, (possible) segfault when using mmap.mmap(-1, ...)
+
+- Bug #1400822, _curses over{lay,write} doesn't work when passing 6 ints.
+  Also fix ungetmouse() which did not accept arguments properly.
+  The code now conforms to the documented signature.
+
+- Bug #1400115, Fix segfault when calling curses.panel.userptr()
+  without prior setting of the userptr.
+
+- Fix 64-bit problems in bsddb.
+
+- Patch #1365916: fix some unsafe 64-bit mmap methods.
+
+- Bug #1290333: Added a workaround for cjkcodecs' _codecs_cn build
+  problem on AIX.
+
+- Bug #869197: os.setgroups rejects long integer arguments
+
+- Bug #1346533, select.poll() doesn't raise an error if timeout > sys.maxint
+
+- Bug #1344508, Fix UNIX mmap leaking file descriptors
+
+- Patch #1338314, Bug #1336623: fix tarfile so it can extract
+  REGTYPE directories from tarfiles written by old programs.
+
+- Patch #1407992, fixes broken bsddb module db associate when using
+  BerkeleyDB 3.3, 4.0 or 4.1.
+
+- Get bsddb module to build with BerkeleyDB version 4.4
+
+- Get bsddb module to build with BerkeleyDB version 3.2
+
+- Patch #1309009, Fix segfault in pyexpat when the XML document is in latin_1,
+  but Python incorrectly assumes it is in UTF-8 format
+
+- Fix parse errors in the readline module when compiling without threads.
+
+- Patch #1288833: Removed thread lock from socket.getaddrinfo on
+  FreeBSD 5.3 and later versions which got thread-safe getaddrinfo(3).
+
+- Patches #1298449 and #1298499: Add some missing checks for error
+  returns in cStringIO.c.
+
+- Patch #1297028: fix segfault if call type on MultibyteCodec,
+  MultibyteStreamReader, or MultibyteStreamWriter
+
+- Fix memory leak in posix.access().
+
+- Patch #1213831: Fix typo in unicodedata._getcode.
+
+- Bug #1007046: os.startfile() did not accept unicode strings encoded in
+  the file system encoding.
+
+- Patch #756021: Special-case socket.inet_aton('255.255.255.255') for
+  platforms that don't have inet_aton().
+
+- Bug #1215928: Fix bz2.BZ2File.seek() for 64-bit file offsets.
+
+- Bug #1191043: Fix bz2.BZ2File.(x)readlines for files containing one
+  line without newlines.
+
+- Bug #728515: mmap.resize() now resizes the file on Unix as it did
+  on Windows.
+
+- Patch #1180695: Add nanosecond stat resolution, and st_gen,
+  st_birthtime for FreeBSD.
+
+- Patch #1231069: The fcntl.ioctl function now uses the 'I' code for
+  the request code argument, which results in more C-like behaviour
+  for large or negative values.
+
+- Bug #1234979: For the argument of thread.Lock.acquire, the Windows
+  implementation treated all integer values except 1 as false.
+
+- Bug #1194181: bz2.BZ2File didn't handle mode 'U' correctly.
+
+- Patch #1212117: os.stat().st_flags is now accessible as a attribute
+  if available on the platform.
+
+- Patch #1103951: Expose O_SHLOCK and O_EXLOCK in the posix module if
+  available on the platform.
+
+- Bug #1166660: The readline module could segfault if hook functions
+  were set in a different thread than that which called readline.
+
+- collections.deque objects now support a remove() method.
+
+- operator.itemgetter() and operator.attrgetter() now support retrieving
+  multiple fields.  This provides direct support for sorting on multiple
+  keys (primary, secondary, etc).
+
+- os.access now supports Unicode path names on non-Win32 systems.
+
+- Patches #925152, #1118602: Avoid reading after the end of the buffer
+  in pyexpat.GetInputContext.
+
+- Patches #749830, #1144555: allow UNIX mmap size to default to current
+  file size.
+
+- Added functional.partial().  See PEP309.
+
+- Patch #1093585: raise a ValueError for negative history items in readline.
+  {remove_history,replace_history}
+
+- The spwd module has been added, allowing access to the shadow password
+  database.
+
+- stat_float_times is now True.
+
+- array.array objects are now picklable.
+
+- the cPickle module no longer accepts the deprecated None option in the
+  args tuple returned by __reduce__().
+
+- itertools.islice() now accepts None for the start and step arguments.
+  This allows islice() to work more readily with slices:
+      islice(s.start, s.stop, s.step)
+
+- datetime.datetime() now has a strptime class method which can be used to
+  create datetime object using a string and format.
+
+- Patch #1117961: Replace the MD5 implementation from RSA Data Security Inc
+  with the implementation from http://sourceforge.net/projects/libmd5-rfc/.
+
+Library
+-------
+
+- Patch #1388073: Numerous __-prefixed attributes of unittest.TestCase have
+  been renamed to have only a single underscore prefix.  This was done to
+  make subclassing easier.
+
+- PEP 338: new module runpy defines a run_module function to support
+  executing modules which provide access to source code or a code object
+  via the PEP 302 import mechanisms.
+
+- The email module's parsedate_tz function now sets the daylight savings
+  flag to -1 (unknown) since it can't tell from the date whether it should
+  be set.
+
+- Patch #624325: urlparse.urlparse() and urlparse.urlsplit() results
+  now sport attributes that provide access to the parts of the result.
+
+- Patch #1462498: sgmllib now handles entity and character references
+  in attribute values.
+
+- Added the sqlite3 package. This is based on pysqlite2.1.3, and provides
+  a DB-API interface in the standard library. You'll need sqlite 3.0.8 or
+  later to build this - if you have an earlier version, the C extension
+  module will not be built.
+
+- Bug #1460340: ``random.sample(dict)`` failed in various ways.  Dicts
+  aren't officially supported here, and trying to use them will probably
+  raise an exception some day.  But dicts have been allowed, and "mostly
+  worked", so support for them won't go away without warning.
+
+- Bug #1445068: getpass.getpass() can now be given an explicit stream
+  argument to specify where to write the prompt.
+
+- Patch #1462313, bug #1443328: the pickle modules now can handle classes
+  that have __private names in their __slots__.
+
+- Bug #1250170: mimetools now handles socket.gethostname() failures gracefully.
+
+- patch #1457316: "setup.py upload" now supports --identity to select the
+  key to be used for signing the uploaded code.
+
+- Queue.Queue objects now support .task_done() and .join() methods
+  to make it easier to monitor when daemon threads have completed
+  processing all enqueued tasks.  Patch #1455676.
+
+- popen2.Popen objects now preserve the command in a .cmd attribute.
+
+- Added the ctypes ffi package.
+
+- email 4.0 package now integrated.  This is largely the same as the email 3.0
+  package that was included in Python 2.3, except that PEP 8 module names are
+  now used (e.g. mail.message instead of email.Message).  The MIME classes
+  have been moved to a subpackage (e.g. email.mime.text instead of
+  email.MIMEText).  The old names are still supported for now.  Several
+  deprecated Message methods have been removed and lots of bugs have been
+  fixed.  More details can be found in the email package documentation.
+
+- Patches #1436130/#1443155: codecs.lookup() now returns a CodecInfo object
+  (a subclass of tuple) that provides incremental decoders and encoders
+  (a way to use stateful codecs without the stream API). Python functions
+  codecs.getincrementaldecoder() and codecs.getincrementalencoder() as well
+  as C functions PyCodec_IncrementalEncoder() and PyCodec_IncrementalDecoder()
+  have been added.
+
+- Patch #1359365: Calling next() on a closed StringIO.String object raises
+  a ValueError instead of a StopIteration now (like file and cString.String do).
+  cStringIO.StringIO.isatty() will raise a ValueError now if close() has been
+  called before (like file and StringIO.StringIO do).
+
+- A regrtest option -w was added to re-run failed tests in verbose mode.
+
+- Patch #1446372: quit and exit can now be called from the interactive
+  interpreter to exit.
+
+- The function get_count() has been added to the gc module, and gc.collect()
+  grew an optional 'generation' argument.
+
+- A library msilib to generate Windows Installer files, and a distutils
+  command bdist_msi have been added.
+
+- PEP 343: new module contextlib.py defines decorator @contextmanager
+  and helpful context managers nested() and closing().
+
+- The compiler package now supports future imports after the module docstring.
+
+- Bug #1413790: zipfile now sanitizes absolute archive names that are
+  not allowed by the specs.
+
+- Patch #1215184: FileInput now can be given an opening hook which can
+  be used to control how files are opened.
+
+- Patch #1212287: fileinput.input() now has a mode parameter for
+  specifying the file mode input files should be opened with.
+
+- Patch #1215184: fileinput now has a fileno() function for getting the
+  current file number.
+
+- Patch #1349274: gettext.install() now optionally installs additional
+  translation functions other than _() in the builtin namespace.
+
+- Patch #1337756: fileinput now accepts Unicode filenames.
+
+- Patch #1373643: The chunk module can now read chunks larger than
+  two gigabytes.
+
+- Patch #1417555: SimpleHTTPServer now returns Last-Modified headers.
+
+- Bug #1430298: It is now possible to send a mail with an empty
+  return address using smtplib.
+
+- Bug #1432260: The names of lambda functions are now properly displayed
+  in pydoc.
+
+- Patch #1412872: zipfile now sets the creator system to 3 (Unix)
+  unless the system is Win32.
+
+- Patch #1349118: urllib now supports user:pass@ style proxy
+  specifications, raises IOErrors when proxies for unsupported protocols
+  are defined, and uses the https proxy on https redirections.
+
+- Bug #902075: urllib2 now supports 'host:port' style proxy specifications.
+
+- Bug #1407902: Add support for sftp:// URIs to urlparse.
+
+- Bug #1371247: Update Windows locale identifiers in locale.py.
+
+- Bug #1394565: SimpleHTTPServer now doesn't choke on query parameters
+  any more.
+
+- Bug #1403410: The warnings module now doesn't get confused
+  when it can't find out the module name it generates a warning for.
+
+- Patch #1177307: Added a new codec utf_8_sig for UTF-8 with a BOM signature.
+
+- Patch #1157027: cookielib mishandles RFC 2109 cookies in Netscape mode
+
+- Patch #1117398: cookielib.LWPCookieJar and .MozillaCookieJar now raise
+  LoadError as documented, instead of IOError.  For compatibility,
+  LoadError subclasses IOError.
+
+- Added the hashlib module.  It provides secure hash functions for MD5 and
+  SHA1, 224, 256, 384, and 512.  Note that recent developments make the
+  historic MD5 and SHA1 unsuitable for cryptographic-strength applications.
+  In <http://mail.python.org/pipermail/python-dev/2005-December/058850.html>
+  Ronald L. Rivest offered this advice for Python:
+
+      "The consensus of researchers in this area (at least as
+      expressed at the NIST Hash Function Workshop 10/31/05),
+      is that SHA-256 is a good choice for the time being, but
+      that research should continue, and other alternatives may
+      arise from this research.  The larger SHA's also seem OK."
+
+- Added a subset of Fredrik Lundh's ElementTree package.  Available
+  modules are xml.etree.ElementTree, xml.etree.ElementPath, and
+  xml.etree.ElementInclude, from ElementTree 1.2.6.
+
+- Patch #1162825: Support non-ASCII characters in IDLE window titles.
+
+- Bug #1365984: urllib now opens "data:" URLs again.
+
+- Patch #1314396: prevent deadlock for threading.Thread.join() when an exception
+  is raised within the method itself on a previous call (e.g., passing in an
+  illegal argument)
+
+- Bug #1340337: change time.strptime() to always return ValueError when there
+  is an error in the format string.
+
+- Patch #754022: Greatly enhanced webbrowser.py (by Oleg Broytmann).
+
+- Bug #729103: pydoc.py: Fix docother() method to accept additional
+  "parent" argument.
+
+- Patch #1300515: xdrlib.py: Fix pack_fstring() to really use null bytes
+  for padding.
+
+- Bug #1296004: httplib.py: Limit maximal amount of data read from the
+  socket to avoid a MemoryError on Windows.
+
+- Patch #1166948: locale.py: Prefer LC_ALL, LC_CTYPE and LANG over LANGUAGE
+  to get the correct encoding.
+
+- Patch #1166938: locale.py: Parse LANGUAGE as a colon separated list of
+  languages.
+
+- Patch #1268314: Cache lines in StreamReader.readlines for performance.
+
+- Bug #1290505: Fix clearing the regex cache for time.strptime().
+
+- Bug #1167128: Fix size of a symlink in a tarfile to be 0.
+
+- Patch #810023: Fix off-by-one bug in urllib.urlretrieve reporthook
+  functionality.
+
+- Bug #1163178: Make IDNA return an empty string when the input is empty.
+
+- Patch #848017: Make Cookie more RFC-compliant. Use CRLF as default output
+  separator and do not output trailing semicolon.
+
+- Patch #1062060: urllib.urlretrieve() now raises a new exception, named
+  ContentTooShortException, when the actually downloaded size does not
+  match the Content-Length header.
+
+- Bug #1121494: distutils.dir_utils.mkpath now accepts Unicode strings.
+
+- Bug #1178484: Return complete lines from codec stream readers
+  even if there is an exception in later lines, resulting in
+  correct line numbers for decoding errors in source code.
+
+- Bug #1192315: Disallow negative arguments to clear() in pdb.
+
+- Patch #827386: Support absolute source paths in msvccompiler.py.
+
+- Patch #1105730: Apply the new implementation of commonprefix in posixpath
+  to ntpath, macpath, os2emxpath and riscospath.
+
+- Fix a problem in Tkinter introduced by SF patch #869468: delete bogus
+  __hasattr__ and __delattr__ methods on class Tk that were breaking
+  Tkdnd.
+
+- Bug #1015140: disambiguated the term "article id" in nntplib docs and
+  docstrings to either "article number" or "message id".
+
+- Bug #1238170: threading.Thread.__init__ no longer has "kwargs={}" as a
+  parameter, but uses the usual "kwargs=None".
+
+- textwrap now processes text chunks at O(n) speed instead of O(n**2).
+  Patch #1209527 (Contributed by Connelly).
+
+- urllib2 has now an attribute 'httpresponses' mapping from HTTP status code
+  to W3C name (404 -> 'Not Found'). RFE #1216944.
+
+- Bug #1177468: Don't cache the /dev/urandom file descriptor for os.urandom,
+  as this can cause problems with apps closing all file descriptors.
+
+- Bug #839151: Fix an attempt to access sys.argv in the warnings module;
+  it can be missing in embedded interpreters
+
+- Bug #1155638: Fix a bug which affected HTTP 0.9 responses in httplib.
+
+- Bug #1100201: Cross-site scripting was possible on BaseHTTPServer via
+  error messages.
+
+- Bug #1108948: Cookie.py produced invalid JavaScript code.
+
+- The tokenize module now detects and reports indentation errors.
+  Bug #1224621.
+
+- The tokenize module has a new untokenize() function to support a full
+  roundtrip from lexed tokens back to Python source code.  In addition,
+  the generate_tokens() function now accepts a callable argument that
+  terminates by raising StopIteration.
+
+- Bug #1196315: fix weakref.WeakValueDictionary constructor.
+
+- Bug #1213894: os.path.realpath didn't resolve symlinks that were the first
+  component of the path.
+
+- Patch #1120353: The xmlrpclib module provides better, more transparent,
+  support for datetime.{datetime,date,time} objects.  With use_datetime set
+  to True, applications shouldn't have to fiddle with the DateTime wrapper
+  class at all.
+
+- distutils.commands.upload was added to support uploading distribution
+  files to PyPI.
+
+- distutils.commands.register now encodes the data as UTF-8 before posting
+  them to PyPI.
+
+- decimal operator and comparison methods now return NotImplemented
+  instead of raising a TypeError when interacting with other types.  This
+  allows other classes to implement __radd__ style methods and have them
+  work as expected.
+
+- Bug #1163325:  Decimal infinities failed to hash.  Attempting to
+  hash a NaN raised an InvalidOperation instead of a TypeError.
+
+- Patch #918101: Add tarfile open mode r|* for auto-detection of the
+  stream compression; add, for symmetry reasons, r:* as a synonym of r.
+
+- Patch #1043890: Add extractall method to tarfile.
+
+- Patch #1075887: Don't require MSVC in distutils if there is nothing
+  to build.
+
+- Patch #1103407: Properly deal with tarfile iterators when untarring
+  symbolic links on Windows.
+
+- Patch #645894: Use getrusage for computing the time consumption in
+  profile.py if available.
+
+- Patch #1046831: Use get_python_version where appropriate in sysconfig.py.
+
+- Patch #1117454: Remove code to special-case cookies without values
+  in LWPCookieJar.
+
+- Patch #1117339: Add cookielib special name tests.
+
+- Patch #1112812: Make bsddb/__init__.py more friendly for modulefinder.
+
+- Patch #1110248: SYNC_FLUSH the zlib buffer for GZipFile.flush.
+
+- Patch #1107973: Allow to iterate over the lines of a tarfile.ExFileObject.
+
+- Patch #1104111: Alter setup.py --help and --help-commands.
+
+- Patch #1121234: Properly cleanup _exit and tkerror commands.
+
+- Patch #1049151: xdrlib now unpacks booleans as True or False.
+
+- Fixed bug in a NameError bug in cookielib.  Patch #1116583.
+
+- Applied a security fix to SimpleXMLRPCserver (PSF-2005-001).  This
+  disables recursive traversal through instance attributes, which can
+  be exploited in various ways.
+
+- Bug #1222790: in SimpleXMLRPCServer, set the reuse-address and close-on-exec
+  flags on the HTTP listening socket.
+
+- Bug #792570: SimpleXMLRPCServer had problems if the request grew too large.
+  Fixed by reading the HTTP body in chunks instead of one big socket.read().
+
+- Patches #893642, #1039083: add allow_none, encoding arguments to
+  constructors of SimpleXMLRPCServer and CGIXMLRPCRequestHandler.
+
+- Bug #1110478: Revert os.environ.update to do putenv again.
+
+- Bug #1103844: fix distutils.install.dump_dirs() with negated options.
+
+- os.{SEEK_SET, SEEK_CUR, SEEK_END} have been added for convenience.
+
+- Enhancements to the csv module:
+
+  + Dialects are now validated by the underlying C code, better
+    reflecting its capabilities, and improving its compliance with
+    PEP 305.
+  + Dialect parameter parsing has been re-implemented to improve error
+    reporting.
+  + quotechar=None and quoting=QUOTE_NONE now work the way PEP 305
+    dictates.
+  + the parser now removes the escapechar prefix from escaped characters.
+  + when quoting=QUOTE_NONNUMERIC, the writer now tests for numeric
+    types, rather than any object that can be represented as a numeric.
+  + when quoting=QUOTE_NONNUMERIC, the reader now casts unquoted fields
+    to floats.
+  + reader now allows \r characters to be quoted (previously it only allowed
+    \n to be quoted).
+  + writer doublequote handling improved.
+  + Dialect classes passed to the module are no longer instantiated by
+    the module before being parsed (the former validation scheme required
+    this, but the mechanism was unreliable).
+  + The dialect registry now contains instances of the internal
+    C-coded dialect type, rather than references to python objects.
+  + the internal c-coded dialect type is now immutable.
+  + register_dialect now accepts the same keyword dialect specifications
+    as the reader and writer, allowing the user to register dialects
+    without first creating a dialect class.
+  + a configurable limit to the size of parsed fields has been added -
+    previously, an unmatched quote character could result in the entire
+    file being read into the field buffer before an error was reported.
+  + A new module method csv.field_size_limit() has been added that sets
+    the parser field size limit (returning the former limit). The initial
+    limit is 128kB.
+  + A line_num attribute has been added to the reader object, which tracks
+    the number of lines read from the source iterator. This is not
+    the same as the number of records returned, as records can span
+    multiple lines.
+  + reader and writer objects were not being registered with the cyclic-GC.
+    This has been fixed.
+
+- _DummyThread objects in the threading module now delete self.__block that is
+  inherited from _Thread since it uses up a lock allocated by 'thread'.  The
+  lock primitives tend to be limited in number and thus should not be wasted on
+  a _DummyThread object.  Fixes bug #1089632.
+
+- The imghdr module now detects Exif files.
+
+- StringIO.truncate() now correctly adjusts the size attribute.
+  (Bug #951915).
+
+- locale.py now uses an updated locale alias table (built using
+  Tools/i18n/makelocalealias.py, a tool to parse the X11 locale
+  alias file); the encoding lookup was enhanced to use Python's
+  encoding alias table.
+
+- moved deprecated modules to Lib/lib-old:  whrandom, tzparse, statcache.
+
+- the pickle module no longer accepts the deprecated None option in the
+  args tuple returned by __reduce__().
+
+- optparse now optionally imports gettext.  This allows its use in setup.py.
+
+- the pickle module no longer uses the deprecated bin parameter.
+
+- the shelve module no longer uses the deprecated binary parameter.
+
+- the pstats module no longer uses the deprecated ignore() method.
+
+- the filecmp module no longer uses the deprecated use_statcache argument.
+
+- unittest.TestCase.run() and unittest.TestSuite.run() can now be successfully
+  extended or overridden by subclasses.  Formerly, the subclassed method would
+  be ignored by the rest of the module.  (Bug #1078905).
+
+- heapq.nsmallest() and heapq.nlargest() now support key= arguments with
+  the same meaning as in list.sort().
+
+- Bug #1076985: ``codecs.StreamReader.readline()`` now calls ``read()`` only
+  once when a size argument is given. This prevents a buffer overflow in the
+  tokenizer with very long source lines.
+
+- Bug #1083110: ``zlib.decompress.flush()`` would segfault if called
+  immediately after creating the object, without any intervening
+  ``.decompress()`` calls.
+
+- The reconvert.quote function can now emit triple-quoted strings.  The
+  reconvert module now has some simple documentation.
+
+- ``UserString.MutableString`` now supports negative indices in
+  ``__setitem__`` and ``__delitem__``
+
+- Bug #1149508: ``textwrap`` now handles hyphenated numbers (eg. "2004-03-05")
+  correctly.
+
+- Partial fixes for SF bugs #1163244 and #1175396: If a chunk read by
+  ``codecs.StreamReader.readline()`` has a trailing "\r", read one more
+  character even if the user has passed a size parameter to get a proper
+  line ending. Remove the special handling of a "\r\n" that has been split
+  between two lines.
+
+- Bug #1251300: On UCS-4 builds the "unicode-internal" codec will now complain
+  about illegal code points. The codec now supports PEP 293 style error
+  handlers.
+
+- Bug #1235646: ``codecs.StreamRecoder.next()`` now reencodes the data it reads
+  from the input stream, so that the output is a byte string in the correct
+  encoding instead of a unicode string.
+
+- Bug #1202493: Fixing SRE parser to handle '{}' as perl does, rather than
+  considering it exactly like a '*'.
+
+- Bug #1245379: Add "unicode-1-1-utf-7" as an alias for "utf-7" to
+  ``encodings.aliases``.
+
+- ` uu.encode()`` and ``uu.decode()`` now support unicode filenames.
+
+- Patch #1413711: Certain patterns of differences were making difflib
+  touch the recursion limit.
+
+- Bug #947906: An object oriented interface has been added to the calendar
+  module. It's possible to generate HTML calendar now and the module can be
+  called as a script (e.g. via ``python -mcalendar``). Localized month and
+  weekday names can be ouput (even if an exotic encoding is used) using
+  special classes that use unicode.
+
+Build
+-----
+
+- Fix test_float, test_long, and test_struct failures on Tru64 with gcc
+  by using -mieee gcc option.
+
+- Patch #1432345: Make python compile on DragonFly.
+
+- Build support for Win64-AMD64 was added.
+
+- Patch #1428494: Prefer linking against ncursesw over ncurses library.
+
+- Patch #881820: look for openpty and forkpty also in libbsd.
+
+- The sources of zlib are now part of the Python distribution (zlib 1.2.3).
+  The zlib module is now builtin on Windows.
+
+- Use -xcode=pic32 for CCSHARED on Solaris with SunPro.
+
+- Bug #1189330: configure did not correctly determine the necessary
+  value of LINKCC if python was built with GCC 4.0.
+
+- Upgrade Windows build to zlib 1.2.3 which eliminates a potential security
+  vulnerability in zlib 1.2.1 and 1.2.2.
+
+- EXTRA_CFLAGS has been introduced as an environment variable to hold compiler
+  flags that change binary compatibility.  Changes were also made to
+  distutils.sysconfig to also use the environment variable when used during
+  compilation of the interpreter and of C extensions through distutils.
+
+- SF patch 1171735: Darwin 8's headers are anal about POSIX compliance,
+  and linking has changed (prebinding is now deprecated, and libcc_dynamic
+  no longer exists). This configure patch makes things right.
+
+- Bug #1158607: Build with --disable-unicode again.
+
+- spwdmodule.c is built only if either HAVE_GETSPNAM or HAVE_HAVE_GETSPENT is
+  defined.  Discovered as a result of not being able to build on OS X.
+
+- setup.py now uses the directories specified in LDFLAGS using the -L option
+  and in CPPFLAGS using the -I option for adding library and include
+  directories, respectively, for compiling extension modules against.  This has
+  led to the core being compiled using the values in CPPFLAGS.  It also removes
+  the need for the special-casing of both DarwinPorts and Fink for darwin since
+  the proper directories can be specified in LDFLAGS (``-L/sw/lib`` for Fink,
+  ``-L/opt/local/lib`` for DarwinPorts) and CPPFLAGS (``-I/sw/include`` for
+  Fink, ``-I/opt/local/include`` for DarwinPorts).
+
+- Test in configure.in that checks for tzset no longer dependent on tm->tm_zone
+  to exist in the struct (not required by either ISO C nor the UNIX 2 spec).
+  Tests for sanity in tzname when HAVE_TZNAME defined were also defined.
+  Closes bug #1096244.  Thanks Gregory Bond.
+
+C API
+-----
+
+- ``PyMem_{Del, DEL}`` and ``PyMem_{Free, FREE}`` no longer map to
+  ``PyObject_{Free, FREE}``.  They map to the system ``free()`` now.  If memory
+  is obtained via the ``PyObject_`` family, it must be released via the
+  ``PyObject_`` family, and likewise for the ``PyMem_`` family.  This has
+  always been officially true, but when Python's small-object allocator was
+  introduced, an attempt was made to cater to a few extension modules
+  discovered at the time that obtained memory via ``PyObject_New`` but
+  released it via ``PyMem_DEL``.  It's years later, and if such code still
+  exists it will fail now (probably with segfaults, but calling wrong
+  low-level memory management functions can yield many symptoms).
+
+- Added a C API for set and frozenset objects.
+
+- Removed PyRange_New().
+
+- Patch #1313939: PyUnicode_DecodeCharmap() accepts a unicode string as the
+  mapping argument now. This string is used as a mapping table. Byte values
+  greater than the length of the string and 0xFFFE are treated as undefined
+  mappings.
+
+
+Tests
+-----
+
+- In test_os, st_?time is now truncated before comparing it with ST_?TIME.
+
+- Patch #1276356: New resource "urlfetch" is implemented.  This enables
+  even impatient people to run tests that require remote files.
+
+
+Documentation
+-------------
+
+- Bug #1402224: Add warning to dl docs about crashes.
+
+- Bug #1396471: Document that Windows' ftell() can return invalid
+  values for text files with UNIX-style line endings.
+
+- Bug #1274828: Document os.path.splitunc().
+
+- Bug #1190204: Clarify which directories are searched by site.py.
+
+- Bug #1193849: Clarify os.path.expanduser() documentation.
+
+- Bug #1243192: re.UNICODE and re.LOCALE affect \d, \D, \s and \S.
+
+- Bug #755617: Document the effects of os.chown() on Windows.
+
+- Patch #1180012: The documentation for modulefinder is now in the library reference.
+
+- Patch #1213031: Document that os.chown() accepts argument values of -1.
+
+- Bug #1190563: Document os.waitpid() return value with WNOHANG flag.
+
+- Bug #1175022: Correct the example code for property().
+
+- Document the IterableUserDict class in the UserDict module.
+  Closes bug #1166582.
+
+- Remove all latent references for "Macintosh" that referred to semantics for
+  Mac OS 9 and change to reflect the state for OS X.
+  Closes patch #1095802.  Thanks Jack Jansen.
+
+Mac
+---
+
+
+New platforms
+-------------
+
+- FreeBSD 7 support is added.
+
+
+Tools/Demos
+-----------
+
+- Created Misc/Vim/vim_syntax.py to auto-generate a python.vim file in that
+  directory for syntax highlighting in Vim.  Vim directory was added and placed
+  vimrc to it (was previous up a level).
+
+- Added two new files to Tools/scripts: pysource.py, which recursively
+  finds Python source files, and findnocoding.py, which finds Python
+  source files that need an encoding declaration.
+  Patch #784089, credits to Oleg Broytmann.
+
+- Bug #1072853: pindent.py used an uninitialized variable.
+
+- Patch #1177597: Correct Complex.__init__.
+
+- Fixed a display glitch in Pynche, which could cause the right arrow to
+  wiggle over by a pixel.
+
+----
+
+**(For information about older versions, consult the HISTORY file.)**

Added: vendor/Python/current/Misc/NEWS.help
===================================================================
--- vendor/Python/current/Misc/NEWS.help	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Misc/NEWS.help	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,73 @@
+							-*- text -*-
+
+If you edited Misc/NEWS before it was converted to ReST format skimming this
+file should help make the transition a bit easier.  For full details about
+Docutils and ReST, go to the Docutils website:
+
+    http://docutils.sourceforge.net/
+
+To process Misc/NEWS using Docutils, you'll need the latest docutils
+snapshot:
+
+    http://docutils.sf.net/docutils-snapshot.tgz
+
+Docutils works with Python 2.2 or newer.
+
+To process NEWS into NEWS.html, first install Docutils, and then run
+this command:
+
+    python .../docutils/tools/rst2html.py NEWS NEWS.html
+
+Here ".../docutils" is the directory into which the above snapshot was
+extracted.  (I hope this recipe will change for the better.)
+
+David Goodger made a change to the allowable structure of internal
+references which greatly simplified initial conversion of the file.
+
+The changes required fell into the following categories:
+
+* The top-level "What's New" section headers changed to:
+
+    What's New in Python 2.3 alpha 1?
+    =================================
+
+    *Release date: DD-MMM-2002*
+
+  Note that the release date line is emphasized, with a "*" at each
+  end.
+
+* Subsections are underlined with a single row of hyphens:
+
+    Type/class unification and new-style classes
+    --------------------------------------------
+
+* Places where "balanced" single quotes were used were changed to use
+  apostrophes as both the opening and closing quote (`string' -> 'string').
+
+* In a few places asterisks needed to be escaped which would otherwise have
+  been interpreted as beginning blocks of italic or bold text, e.g.:
+
+    - The type of tp_free has been changed from "``void (*)(PyObject *)``"
+      to "``void (*)(void *)``".
+
+  Note that only the asterisks preceded by whitespace needed to be escaped.
+
+* One instance of a word ending with an underscore needed to be quoted
+  ("PyCmp_" became "``PyCmp_``").
+
+* One table was converted to ReST form (search Misc/NEWS for "New codecs"
+  for this example).
+
+* A few places where chunks of code or indented text were displayed needed
+  to be properly introduced (preceding paragraph terminated by "::" and the
+  chunk of code or text indented w.r.t. the paragraph).  For example:
+
+    - Note that PyLong_AsDouble can fail!  This has always been true,
+      but no callers checked for it.  It's more likely to fail now,
+      because overflow errors are properly detected now.  The proper way
+      to check::
+
+          double x = PyLong_AsDouble(some_long_object);
+          if (x == -1.0 && PyErr_Occurred()) {
+              /* The conversion failed. */
+              }

Added: vendor/Python/current/Misc/PURIFY.README
===================================================================
--- vendor/Python/current/Misc/PURIFY.README	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Misc/PURIFY.README	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,97 @@
+Purify (tm) and Quantify (tm) are commercial software quality
+assurance tools available from IBM <http://www.ibm.com/software/rational/>.
+Purify is essentially a memory access
+verifier and leak detector; Quantify is a C level profiler.  The rest
+of this file assumes you generally know how to use Purify and
+Quantify, and that you have installed valid licenses for these
+products.  If you haven't installed such licenses, you can ignore the
+following since it won't help you a bit!
+
+You can easily build a Purify or Quantify instrumented version of the
+Python interpreter by passing the PURIFY variable to the make command
+at the top of the Python tree:
+
+    make PURIFY=purify
+
+This assumes that the `purify' program is on your $PATH.  Note that
+you cannot both Purify and Quantify the Python interpreter (or any
+program for that matter) at the same time.  If you want to build a
+Quantify'd interpreter, do this:
+
+    make PURIFY=quantify
+
+Starting with Python 2.3, pymalloc is enabled by default.  This
+will cause many supurious warnings.  Modify Objects/obmalloc.c
+and enable Py_USING_MEMORY_DEBUGGER by uncommenting it.
+README.valgrind has more details about why this is necessary.
+See below about setting up suppressions.  Some tests may not
+run well with Purify due to heavy memory or CPU usage.  These
+tests may include: test_largefile, test_import, and test_long.
+
+Please report any findings (problems or no warnings) to python-dev at python.org.
+It may be useful to submit a bug report for any problems.  
+
+When running the regression test (make test), I have found it useful
+to set my PURIFYOPTIONS environment variable using the following
+(bash) shell function.  Check out the Purify documentation for
+details:
+
+p() {
+  chainlen='-chain-length=12'
+  ignoresigs='-ignore-signals="SIGHUP,SIGINT,SIGQUIT,SIGILL,SIGTRAP,SIGAVRT,SIGEMT,SIGFPE,SIGKILL,SIGBUS,SIGSEGV,SIGPIPE,SIGTERM,SIGUSR1,SIGUSR2,SIGPOLL,SIGXCPU,SIGXFSZ,SIGFREEZE,SIGTHAW,SIGRTMIN,SIGRTMAX"'
+  followchild='-follow-child-processes=yes'
+  threads='-max-threads=50'
+  export PURIFYOPTIONS="$chainlen $ignoresigs $followchild $threads"
+  echo $PURIFYOPTIONS
+}
+
+Note that you may want to crank -chain-length up even further.  A
+value of 20 should get you the entire stack up into the Python C code
+in all situations.
+
+With the regression test on a fatly configured interpreter
+(i.e. including as many modules as possible in your Modules/Setup
+file), you'll probably get a gabillion UMR errors, and a few MLK
+errors.  I think most of these can be safely suppressed by putting the
+following in your .purify file:
+
+    suppress umr ...; "socketmodule.c"
+    suppress umr ...; time_strftime
+    suppress umr ...; "dbmmodule.c"
+    suppress umr ...; "gdbmmodule.c"
+    suppress umr ...; "grpmodule.c"
+    suppress umr ...; "nismodule.c"
+    suppress umr ...; "pwdmodule.c"
+
+Note: this list is very old and may not be accurate any longer.
+It's possible some of these no longer need to be suppressed.
+You will also need to suppress warnings (at least umr)
+from Py_ADDRESS_IN_RANGE.
+
+This will still leave you with just a few UMR, mostly in the readline
+library, which you can safely ignore.  A lot of work has gone into
+Python 1.5 to plug as many leaks as possible.
+
+Using Purify or Quantify in this way will give you coarse grained
+reports on the whole Python interpreter.  You can actually get more
+fine grained control over both by linking with the optional `pure'
+module, which exports (most of) the Purify and Quantify C API's into
+Python.  To link in this module (it must be statically linked), edit
+your Modules/Setup file for your site, and rebuild the interpreter.
+You might want to check out the comments in the Modules/puremodule.c
+file for some idiosyncrasies.
+
+Using this module, you can actually profile or leak test a small
+section of code, instead of the whole interpreter.  Using this in
+conjuction with pdb.py, dbx, or the profiler.py module really gives
+you quite a bit of introspective power.
+
+Naturally there are a couple of caveats.  This has only been tested
+with Purify 4.0.1 and Quantify 2.1-beta on Solaris 2.5.  Purify 4.0.1
+does not work with Solaris 2.6, but Purify 4.1 which reportedly will,
+is currently in beta test.  There are funky problems when Purify'ing a 
+Python interpreter build with threads.  I've had a lot of problems
+getting this to work, so I generally don't build with threads when I'm 
+Purify'ing.  If you get this to work, let us know!
+
+-Barry Warsaw <bwarsaw at cnri.reston.va.us>

Added: vendor/Python/current/Misc/Porting
===================================================================
--- vendor/Python/current/Misc/Porting	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Misc/Porting	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,42 @@
+Q. I want to port Python to a new platform.  How do I begin?
+
+A. I guess the two things to start with is to familiarize yourself
+with are the development system for your target platform and the
+generic build process for Python.  Make sure you can compile and run a
+simple hello-world program on your target platform.  Make sure you can
+compile and run the Python interpreter on a platform to which it has
+already been ported (preferably Unix, but Mac or Windows will do,
+too).
+
+I also would never start something like this without at least
+medium-level understanding of your target platform (i.e. how it is
+generally used, how to write platform specific apps etc.) and Python
+(or else you'll never know how to test the results).
+
+The build process for Python, in particular the Makefiles in the
+source distribution, will give you a hint on which files to compile
+for Python.  Not all source files are relevant -- some are platform
+specific, others are only used in emergencies (e.g. getopt.c).  The
+Makefiles tell the story.
+
+You'll also need a pyconfig.h file tailored for your platform.  You can
+start with pyconfig.h.in, read the comments and turn on definitions that
+apply to your platform.
+
+And you'll need a config.c file, which lists the built-in modules you
+support.  Start with Modules/config.c.in.
+
+Finally, you'll run into some things that aren't supported on your
+target platform.  Forget about the posix module for now -- simply take 
+it out of the config.c file.
+
+Bang on it until you get a >>> prompt.  (You may have to disable the
+importing of "site.py" and "exceptions.py" by passing -X and -S
+options.
+
+Then bang on it until it executes very simple Python statements.
+
+Now bang on it some more.  At some point you'll want to use the os
+module; this is the time to start thinking about what to to with the
+posix module.  It's okay to simply #ifdef out those functions that
+cause problems; the remaining ones will be quite useful.

Added: vendor/Python/current/Misc/README
===================================================================
--- vendor/Python/current/Misc/README	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Misc/README	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,33 @@
+Python Misc subdirectory
+========================
+
+This directory contains files that wouldn't fit in elsewhere.  Some
+documents are only of historic importance.
+
+Files found here
+----------------
+
+ACKS		Acknowledgements
+AIX-NOTES	Notes for building Python on AIX
+BeOS-NOTES	Notes for building on BeOS
+BeOS-setup.py	setup.py replacement for BeOS, see BeOS-NOTES
+cheatsheet	Quick summary of Python by Ken Manheimer
+find_recursionlimit.py  Script to find a value for sys.maxrecursionlimit
+gdbinit		Handy stuff to put in your .gdbinit file, if you use gdb
+HISTORY		News from previous releases -- oldest last
+HPUX-NOTES	Notes about dynamic loading under HP-UX
+indent.pro	GNU indent profile approximating my C style
+NEWS		News for this release (for some meaning of "this")
+Porting		Mini-FAQ on porting to new platforms
+PURIFY.README	Information for Purify users
+pymemcompat.h	Memory interface compatibility file.
+python.man	UNIX man page for the python interpreter
+python-mode.el	Emacs mode for editing Python programs
+README		The file you're reading now
+README.valgrind	Information for Valgrind users, see valgrind-python.supp
+RFD		Request For Discussion about a Python newsgroup
+RPM		(Old) tools to build RPMs
+SpecialBuilds.txt     Describes extra symbols you can set for debug builds
+setuid-prog.c	C helper program for set-uid Python scripts
+vgrindefs	Python configuration for vgrind (a generic pretty printer)
+valgrind-python.supp	Valgrind suppression file, see README.valgrind

Added: vendor/Python/current/Misc/README.OpenBSD
===================================================================
--- vendor/Python/current/Misc/README.OpenBSD	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Misc/README.OpenBSD	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,38 @@
+
+2005-01-08
+
+If you are have a problem building on OpenBSD and see output like this
+while running configure:
+
+checking curses.h presence... yes
+configure: WARNING: curses.h: present but cannot be compiled
+configure: WARNING: curses.h: check for missing prerequisite headers?
+configure: WARNING: curses.h: see the Autoconf documentation
+configure: WARNING: curses.h: section "Present But Cannot Be Compiled"
+configure: WARNING: curses.h: proceeding with the preprocessor's result
+configure: WARNING: curses.h: in the future, the compiler will take precedence
+
+there is likely a problem that will prevent building python.  
+If you see the messages above and are able to completely build python,
+please tell python-dev at python.org indicating your version of OpenBSD
+and any other relevant system configuration.
+
+The build error that occurs while making may look something like this:
+
+    /usr/include/sys/event.h:53: error: syntax error before "u_int"
+    /usr/include/sys/event.h:55: error: syntax error before "u_short"
+
+To fix this problem, you will probably need update Python's configure
+script to disable certain options.  Search for a line that looks like:
+
+    OpenBSD/2.* | OpenBSD/3.@<:@012345678@:>@)
+
+If your version is not in that list, e.g., 3.9, add the version
+number.  In this case, you would just need to add a 9 after the 8.
+If you modify configure.in, you will need to regenerate configure
+with autoconf.
+
+If your version is already in the list, this is not a known problem.
+Please submit a bug report here:
+
+    http://sourceforge.net/tracker/?group_id=5470&atid=105470

Added: vendor/Python/current/Misc/README.coverity
===================================================================
--- vendor/Python/current/Misc/README.coverity	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Misc/README.coverity	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,22 @@
+
+Coverity has a static analysis tool (Prevent) which is similar to Klocwork.
+They run their tool on the Python source code (SVN head) on a daily basis.
+The results are available at:
+
+     http://scan.coverity.com/
+
+About 20 people have access to the analysis reports.  Other
+people can be added by request.
+
+Prevent was first run on the Python 2.5 source code in March 2006.
+There were originally about 100 defects reported.  Some of these
+were false positives.  Over 70 issues were uncovered.
+
+Each warning has a unique id and comments that can be made on it.
+When checking in changes due to a warning, the unique id
+as reported by the tool was added to the SVN commit message.
+
+False positives were annotated so that the comments can
+be reviewed and reversed if the analysis was incorrect.
+
+Contact python-dev at python.org for more information.

Added: vendor/Python/current/Misc/README.klocwork
===================================================================
--- vendor/Python/current/Misc/README.klocwork	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Misc/README.klocwork	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,30 @@
+
+Klocwork has a static analysis tool (K7) which is similar to Coverity.
+They will run their tool on the Python source code on demand.
+The results are available at:
+
+     https://opensource.klocwork.com/
+
+Currently, only Neal Norwitz has access to the analysis reports.  Other
+people can be added by request.
+
+K7 was first run on the Python 2.5 source code in mid-July 2006.
+This is after Coverity had been making their results available.
+There were originally 175 defects reported.  Most of these
+were false positives.  However, there were numerous real issues 
+also uncovered.
+
+Each warning has a unique id and comments that can be made on it.
+When checking in changes due to a K7 report, the unique id
+as reported by the tool was added to the SVN commit message.
+A comment was added to the K7 warning indicating the SVN revision
+in addition to any analysis.
+
+False positives were also annotated so that the comments can
+be reviewed and reversed if the analysis was incorrect.
+
+A second run was performed on 10-Aug-2006.  The tool was tuned to remove
+some false positives and perform some additional checks.  ~150 new
+warnings were produced, primarily related to dereferencing NULL pointers.
+
+Contact python-dev at python.org for more information.

Added: vendor/Python/current/Misc/README.valgrind
===================================================================
--- vendor/Python/current/Misc/README.valgrind	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Misc/README.valgrind	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,97 @@
+This document describes some caveats about the use of Valgrind with
+Python.  Valgrind is used periodically by Python developers to try
+to ensure there are no memory leaks or invalid memory reads/writes.
+
+If you don't want to read about the details of using Valgrind, there
+are still two things you must do to suppress the warnings.  First,
+you must use a suppressions file.  One is supplied in
+Misc/valgrind-python.supp.  Second, you must do one of the following:
+
+  * Uncomment Py_USING_MEMORY_DEBUGGER in Objects/obmalloc.c,
+    then rebuild Python
+  * Uncomment the lines in Misc/valgrind-python.supp that
+    suppress the warnings for PyObject_Free and PyObject_Realloc
+
+If you want to use Valgrind more effectively and catch even more
+memory leaks, you will need to configure python --without-pymalloc.
+PyMalloc allocates a few blocks in big chunks and most object
+allocations don't call malloc, they use chunks doled about by PyMalloc
+from the big blocks.  This means Valgrind can't detect
+many allocations (and frees), except for those that are forwarded
+to the system malloc.  Note: configuring python --without-pymalloc
+makes Python run much slower, especially when running under Valgrind.
+You may need to run the tests in batches under Valgrind to keep
+the memory usage down to allow the tests to complete.  It seems to take
+about 5 times longer to run --without-pymalloc.
+
+Apr 15, 2006:
+  test_ctypes causes Valgrind 3.1.1 to fail (crash).
+  test_socket_ssl should be skipped when running valgrind.
+	The reason is that it purposely uses uninitialized memory.
+	This causes many spurious warnings, so it's easier to just skip it.
+
+
+Details:
+--------
+Python uses its own small-object allocation scheme on top of malloc,
+called PyMalloc.
+
+Valgrind may show some unexpected results when PyMalloc is used.
+Starting with Python 2.3, PyMalloc is used by default.  You can disable
+PyMalloc when configuring python by adding the --without-pymalloc option.
+If you disable PyMalloc, most of the information in this document and
+the supplied suppressions file will not be useful.  As discussed above,
+disabling PyMalloc can catch more problems.
+
+If you use valgrind on a default build of Python,  you will see
+many errors like:
+
+        ==6399== Use of uninitialised value of size 4
+        ==6399== at 0x4A9BDE7E: PyObject_Free (obmalloc.c:711)
+        ==6399== by 0x4A9B8198: dictresize (dictobject.c:477)
+
+These are expected and not a problem.  Tim Peters explains
+the situation:
+
+        PyMalloc needs to know whether an arbitrary address is one
+	that's managed by it, or is managed by the system malloc.
+	The current scheme allows this to be determined in constant
+	time, regardless of how many memory areas are under pymalloc's
+	control.
+
+        The memory pymalloc manages itself is in one or more "arenas",
+	each a large contiguous memory area obtained from malloc.
+	The base address of each arena is saved by pymalloc
+	in a vector.  Each arena is carved into "pools", and a field at
+	the start of each pool contains the index of that pool's arena's
+	base address in that vector.
+
+        Given an arbitrary address, pymalloc computes the pool base
+	address corresponding to it, then looks at "the index" stored
+	near there.  If the index read up is out of bounds for the
+	vector of arena base addresses pymalloc maintains, then
+	pymalloc knows for certain that this address is not under
+	pymalloc's control.  Otherwise the index is in bounds, and
+	pymalloc compares
+
+            the arena base address stored at that index in the vector
+
+        to
+
+            the arbitrary address pymalloc is investigating
+
+        pymalloc controls this arbitrary address if and only if it lies
+        in the arena the address's pool's index claims it lies in.
+
+        It doesn't matter whether the memory pymalloc reads up ("the
+	index") is initialized.  If it's not initialized, then
+	whatever trash gets read up will lead pymalloc to conclude
+	(correctly) that the address isn't controlled by it, either
+	because the index is out of bounds, or the index is in bounds
+	but the arena it represents doesn't contain the address.
+
+        This determination has to be made on every call to one of
+	pymalloc's free/realloc entry points, so its speed is critical
+	(Python allocates and frees dynamic memory at a ferocious rate
+	-- everything in Python, from integers to "stack frames",
+	lives in the heap).

Added: vendor/Python/current/Misc/RFD
===================================================================
--- vendor/Python/current/Misc/RFD	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Misc/RFD	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,114 @@
+To:  python-list
+Subject: comp.lang.python RFD again
+From: Guido.van.Rossum at cwi.nl
+
+I've followed the recent discussion and trimmed the blurb RFD down a bit
+(and added the word "object-oriented" to the blurb).
+
+I don't think it's too early to *try* to create the newsgroup --
+whether we will succeed may depend on how many Python supporters there
+are outside the mailing list.
+
+I'm personally not worried about moderation, and anyway I haven't
+heard from any volunteers for moderation (and I won't volunteer
+myself) so I suggest that we'll continue to ask for one unmoderated
+newsgroup.
+
+My next action will be to post an updated FAQ (which will hint at the
+upcoming RFD) to comp.lang.misc; then finalize the 1.0.0 release and
+put it on the ftp site.  I'll also try to get it into
+comp.sources.unix or .misc.  And all this before the end of January!
+
+--Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum at cwi.nl>
+URL:  <http://www.cwi.nl/cwi/people/Guido.van.Rossum.html>
+
+======================================================================
+
+These are the steps required (in case you don't know about the
+newsgroup creation process):
+
+First, we need to draw up an RFD (Request For Discussion).  This is a
+document that tells what the purpose of the group is, and gives a case
+for its creation.  We post this to relevant groups (comp.lang.misc,
+the mailing list, news.groups, etc.)  Discussion is held on
+news.groups.
+
+Then, after a few weeks, we run the official CFV (Call For Votes).
+The votes are then collected over a period of weeks.  We need 100 more
+yes votes than no votes, and a 2/3 majority, to get the group.
+
+There are some restrictions on the vote taker: [s]he cannot actively
+campaign for/against the group during the vote process.  So the main
+benefit to Steve instead of me running the vote is that I will be free
+to campaign for its creation!
+
+The following is our current draft for the RFD.
+
+======================================================================
+
+Request For Discussion: comp.lang.python
+
+
+Purpose
+-------
+
+The newsgroup will be for discussion on the Python computer language.
+Possible topics include requests for information, general programming,
+development, and bug reports. The group will be unmoderated.
+
+
+What is Python?
+---------------
+
+Python is a relatively new very-high-level language developed in
+Amsterdam.  Python is a simple, object-oriented procedural language,
+with features taken from ABC, Icon, Modula-3, and C/C++.
+
+Its central goal is to provide the best of both worlds: the dynamic
+nature of scripting languages like Perl/TCL/REXX, but also support for
+general programming found in the more traditional languages like Icon,
+C, Modula,...
+
+Python may be FTP'd from the following sites:
+
+	ftp.cwi.nl in directory /pub/python (its "home site", also has a FAQ)
+	ftp.uu.net in directory /languages/python
+	gatekeeper.dec.com in directory /pub/plan/python/cwi
+
+
+Rationale
+---------
+
+Currently there is a mailing list with over 130 subscribers.
+The activity of this list is high, and to make handling the
+traffic more reasonable, a newsgroup is being proposed. We
+also feel that comp.lang.misc would not be a suitable forum
+for this volume of discussion on a particular language.
+
+
+Charter
+-------
+
+Comp.lang.python is an unmoderated newsgroup which will serve
+as a forum for discussing the Python computer language. The
+group will serve both those who just program in Python and
+those who work on developing the language. Topics that
+may be discussed include:
+
+	- announcements of new versions of the language and
+	  applications written in Python.
+
+	- discussion on the internals of the Python language.
+
+	- general information about the language.
+
+	- discussion on programming in Python.
+
+
+Discussion
+----------
+
+Any objections to this RFD will be considered and, if determined
+to be appropriate, will be incorporated. The discussion period
+will be for a period of 21 days after which the first CFV will be
+issued.

Added: vendor/Python/current/Misc/RPM/README
===================================================================
--- vendor/Python/current/Misc/RPM/README	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Misc/RPM/README	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,16 @@
+This directory contains support file used to build RPM releases of
+Python.  Its contents are maintained by Sean Reifschneider
+<jafo at tummy.com>.
+
+It is recommended that RPM builders use the python*.src.rpm file
+downloaded from the "ftp.python.org:/pub/python/<version>/rpms".  These
+may be more up to date than the files included in the base Python
+release tar-file.
+
+If you wish to build RPMs from the base Python release tar-file, note
+that you will have to download the
+"doc/<version>/html-<version>.tar.bz2"
+file from python.org and place it into your "SOURCES" directory for
+the build to complete.  This is the same directory that you place the
+Python-2.3.1 release tar-file in.  You can then use the ".spec" file in
+this directory to build RPMs.

Added: vendor/Python/current/Misc/RPM/python-2.5.spec
===================================================================
--- vendor/Python/current/Misc/RPM/python-2.5.spec	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Misc/RPM/python-2.5.spec	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,395 @@
+##########################
+#  User-modifiable configs
+##########################
+
+#  Is the resulting package and the installed binary named "python" or
+#  "python2"?
+#WARNING: Commenting out doesn't work.  Last line is what's used.
+%define config_binsuffix none
+%define config_binsuffix 2.5
+
+#  Build tkinter?  "auto" enables it if /usr/bin/wish exists.
+#WARNING: Commenting out doesn't work.  Last line is what's used.
+%define config_tkinter no
+%define config_tkinter yes
+%define config_tkinter auto
+
+#  Use pymalloc?  The last line (commented or not) determines wether
+#  pymalloc is used.
+#WARNING: Commenting out doesn't work.  Last line is what's used.
+%define config_pymalloc no
+%define config_pymalloc yes
+
+#  Enable IPV6?
+#WARNING: Commenting out doesn't work.  Last line is what's used.
+%define config_ipv6 yes
+%define config_ipv6 no
+
+#  Location of the HTML directory.
+%define config_htmldir /var/www/html/python
+
+#################################
+#  End of user-modifiable configs
+#################################
+
+%define name python
+%define version 2.5.1
+%define libvers 2.5
+%define release 1pydotorg
+%define __prefix /usr
+
+#  kludge to get around rpm <percent>define weirdness
+%define ipv6 %(if [ "%{config_ipv6}" = yes ]; then echo --enable-ipv6; else echo --disable-ipv6; fi)
+%define pymalloc %(if [ "%{config_pymalloc}" = yes ]; then echo --with-pymalloc; else echo --without-pymalloc; fi)
+%define binsuffix %(if [ "%{config_binsuffix}" = none ]; then echo ; else echo "%{config_binsuffix}"; fi)
+%define include_tkinter %(if [ \\( "%{config_tkinter}" = auto -a -f /usr/bin/wish \\) -o "%{config_tkinter}" = yes ]; then echo 1; else echo 0; fi)
+%define libdirname %(( uname -m | egrep -q '_64$' && [ -d /usr/lib64 ] && echo lib64 ) || echo lib)
+
+#  detect if documentation is available
+%define include_docs %(if [ -f "%{_sourcedir}/html-%{version}.tar.bz2" ]; then echo 1; else echo 0; fi)
+
+Summary: An interpreted, interactive, object-oriented programming language.
+Name: %{name}%{binsuffix}
+Version: %{version}
+Release: %{release}
+License: Python Software Foundation
+Group: Development/Languages
+Source: Python-%{version}.tar.bz2
+%if %{include_docs}
+Source1: html-%{version}.tar.bz2
+%endif
+BuildRoot: %{_tmppath}/%{name}-%{version}-root
+BuildPrereq: expat-devel
+BuildPrereq: db4-devel
+BuildPrereq: gdbm-devel
+BuildPrereq: sqlite-devel
+Prefix: %{__prefix}
+Packager: Sean Reifschneider <jafo-rpms at tummy.com>
+
+%description
+Python is an interpreted, interactive, object-oriented programming
+language.  It incorporates modules, exceptions, dynamic typing, very high
+level dynamic data types, and classes. Python combines remarkable power
+with very clear syntax. It has interfaces to many system calls and
+libraries, as well as to various window systems, and is extensible in C or
+C++. It is also usable as an extension language for applications that need
+a programmable interface.  Finally, Python is portable: it runs on many
+brands of UNIX, on PCs under Windows, MS-DOS, and OS/2, and on the
+Mac.
+
+%package devel
+Summary: The libraries and header files needed for Python extension development.
+Prereq: python%{binsuffix} = %{PACKAGE_VERSION}
+Group: Development/Libraries
+
+%description devel
+The Python programming language's interpreter can be extended with
+dynamically loaded extensions and can be embedded in other programs.
+This package contains the header files and libraries needed to do
+these types of tasks.
+
+Install python-devel if you want to develop Python extensions.  The
+python package will also need to be installed.  You'll probably also
+want to install the python-docs package, which contains Python
+documentation.
+
+%if %{include_tkinter}
+%package tkinter
+Summary: A graphical user interface for the Python scripting language.
+Group: Development/Languages
+Prereq: python%{binsuffix} = %{PACKAGE_VERSION}-%{release}
+
+%description tkinter
+The Tkinter (Tk interface) program is an graphical user interface for
+the Python scripting language.
+
+You should install the tkinter package if you'd like to use a graphical
+user interface for Python programming.
+%endif
+
+%package tools
+Summary: A collection of development tools included with Python.
+Group: Development/Tools
+Prereq: python%{binsuffix} = %{PACKAGE_VERSION}-%{release}
+
+%description tools
+The Python package includes several development tools that are used
+to build python programs.  This package contains a selection of those
+tools, including the IDLE Python IDE.
+
+Install python-tools if you want to use these tools to develop
+Python programs.  You will also need to install the python and
+tkinter packages.
+
+%if %{include_docs}
+%package docs
+Summary: Python-related documentation.
+Group: Development/Documentation
+
+%description docs
+Documentation relating to the Python programming language in HTML and info
+formats.
+%endif
+
+%changelog
+* Mon Dec 20 2004 Sean Reifschneider <jafo-rpms at tummy.com> [2.4-2pydotorg]
+- Changing the idle wrapper so that it passes arguments to idle.
+
+* Tue Oct 19 2004 Sean Reifschneider <jafo-rpms at tummy.com> [2.4b1-1pydotorg]
+- Updating to 2.4.
+
+* Thu Jul 22 2004 Sean Reifschneider <jafo-rpms at tummy.com> [2.3.4-3pydotorg]
+- Paul Tiemann fixes for %{prefix}.
+- Adding permission changes for directory as suggested by reimeika.ca
+- Adding code to detect when it should be using lib64.
+- Adding a define for the location of /var/www/html for docs.
+
+* Thu May 27 2004 Sean Reifschneider <jafo-rpms at tummy.com> [2.3.4-2pydotorg]
+- Including changes from Ian Holsman to build under Red Hat 7.3.
+- Fixing some problems with the /usr/local path change.
+
+* Sat Mar 27 2004 Sean Reifschneider <jafo-rpms at tummy.com> [2.3.2-3pydotorg]
+- Being more agressive about finding the paths to fix for
+  #!/usr/local/bin/python.
+
+* Sat Feb 07 2004 Sean Reifschneider <jafo-rpms at tummy.com> [2.3.3-2pydotorg]
+- Adding code to remove "#!/usr/local/bin/python" from particular files and
+  causing the RPM build to terminate if there are any unexpected files
+  which have that line in them.
+
+* Mon Oct 13 2003 Sean Reifschneider <jafo-rpms at tummy.com> [2.3.2-1pydotorg]
+- Adding code to detect wether documentation is available to build.
+
+* Fri Sep 19 2003 Sean Reifschneider <jafo-rpms at tummy.com> [2.3.1-1pydotorg]
+- Updating to the 2.3.1 release.
+
+* Mon Feb 24 2003 Sean Reifschneider <jafo-rpms at tummy.com> [2.3b1-1pydotorg]
+- Updating to 2.3b1 release.
+
+* Mon Feb 17 2003 Sean Reifschneider <jafo-rpms at tummy.com> [2.3a1-1]
+- Updating to 2.3 release.
+
+* Sun Dec 23 2001 Sean Reifschneider <jafo-rpms at tummy.com>
+[Release 2.2-2]
+- Added -docs package.
+- Added "auto" config_tkinter setting which only enables tk if
+  /usr/bin/wish exists.
+
+* Sat Dec 22 2001 Sean Reifschneider <jafo-rpms at tummy.com>
+[Release 2.2-1]
+- Updated to 2.2.
+- Changed the extension to "2" from "2.2".
+
+* Tue Nov 18 2001 Sean Reifschneider <jafo-rpms at tummy.com>
+[Release 2.2c1-1]
+- Updated to 2.2c1.
+
+* Thu Nov  1 2001 Sean Reifschneider <jafo-rpms at tummy.com>
+[Release 2.2b1-3]
+- Changed the way the sed for fixing the #! in pydoc works.
+
+* Wed Oct  24 2001 Sean Reifschneider <jafo-rpms at tummy.com>
+[Release 2.2b1-2]
+- Fixed missing "email" package, thanks to anonymous report on sourceforge.
+- Fixed missing "compiler" package.
+
+* Mon Oct 22 2001 Sean Reifschneider <jafo-rpms at tummy.com>
+[Release 2.2b1-1]
+- Updated to 2.2b1.
+
+* Mon Oct  9 2001 Sean Reifschneider <jafo-rpms at tummy.com>
+[Release 2.2a4-4]
+- otto at balinor.mat.unimi.it mentioned that the license file is missing.
+
+* Sun Sep 30 2001 Sean Reifschneider <jafo-rpms at tummy.com>
+[Release 2.2a4-3]
+- Ignacio Vazquez-Abrams pointed out that I had a spruious double-quote in
+  the spec files.  Thanks.
+
+* Wed Jul 25 2001 Sean Reifschneider <jafo-rpms at tummy.com>
+[Release 2.2a1-1]
+- Updated to 2.2a1 release.
+- Changed idle and pydoc to use binsuffix macro
+
+#######
+#  PREP
+#######
+%prep
+%setup -n Python-%{version}
+
+########
+#  BUILD
+########
+%build
+./configure --enable-unicode=ucs4 %{ipv6} %{pymalloc} --prefix=%{__prefix}
+make
+
+##########
+#  INSTALL
+##########
+%install
+#  set the install path
+echo '[install_scripts]' >setup.cfg
+echo 'install_dir='"${RPM_BUILD_ROOT}%{__prefix}/bin" >>setup.cfg
+
+[ -d "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT
+mkdir -p $RPM_BUILD_ROOT%{__prefix}/%{libdirname}/python%{libvers}/lib-dynload
+make prefix=$RPM_BUILD_ROOT%{__prefix} install
+
+#  REPLACE PATH IN PYDOC
+if [ ! -z "%{binsuffix}" ]
+then
+   for file in pydoc python-config; do
+      (
+         cd $RPM_BUILD_ROOT%{__prefix}/bin
+         mv "$file" "$file".old
+         sed 's|#!.*|#!%{__prefix}/bin/env python'%{binsuffix}'|' \
+               "$file".old >"$file"
+         chmod 755 "$file"
+         rm -f "$file".old
+      )
+   done
+fi
+
+#  add the binsuffix
+if [ ! -z "%{binsuffix}" ]
+then
+   ( cd $RPM_BUILD_ROOT%{__prefix}/bin; rm -f python[0-9a-zA-Z]*;
+         mv -f python python"%{binsuffix}" )
+   ( cd $RPM_BUILD_ROOT%{__prefix}/man/man1; mv python.1 python%{binsuffix}.1 )
+   ( cd $RPM_BUILD_ROOT%{__prefix}/bin; mv -f smtpd.py python-smtpd )
+   for file in pydoc idle python-config python-smtpd; do
+      ( cd $RPM_BUILD_ROOT%{__prefix}/bin; mv -f "$file" "$file""%{binsuffix}" )
+   done
+fi
+
+########
+#  Tools
+echo '#!%{__prefix}/bin/env python%{binsuffix}' >${RPM_BUILD_ROOT}%{__prefix}/bin/idle%{binsuffix}
+echo 'import os, sys' >>${RPM_BUILD_ROOT}%{__prefix}/bin/idle%{binsuffix}
+echo 'os.execvp("%{__prefix}/bin/python%{binsuffix}", ["%{__prefix}/bin/python%{binsuffix}", "%{__prefix}/lib/python%{libvers}/idlelib/idle.py"] + sys.argv[1:])' >>${RPM_BUILD_ROOT}%{__prefix}/bin/idle%{binsuffix}
+echo 'print "Failed to exec Idle"' >>${RPM_BUILD_ROOT}%{__prefix}/bin/idle%{binsuffix}
+echo 'sys.exit(1)' >>${RPM_BUILD_ROOT}%{__prefix}/bin/idle%{binsuffix}
+chmod 755 $RPM_BUILD_ROOT%{__prefix}/bin/idle%{binsuffix}
+cp -a Tools $RPM_BUILD_ROOT%{__prefix}/%{libdirname}/python%{libvers}
+
+#  MAKE FILE LISTS
+rm -f mainpkg.files
+find "$RPM_BUILD_ROOT""%{__prefix}"/%{libdirname}/python%{libvers}/lib-dynload -type f |
+	sed "s|^${RPM_BUILD_ROOT}|/|" |
+	grep -v -e '_tkinter.so$' >mainpkg.files
+find "$RPM_BUILD_ROOT""%{__prefix}"/bin -type f |
+	sed "s|^${RPM_BUILD_ROOT}|/|" |
+	grep -v -e '/bin/setup-config%{binsuffix}$' |
+	grep -v -e '/bin/idle%{binsuffix}$' >>mainpkg.files
+
+rm -f tools.files
+find "$RPM_BUILD_ROOT""%{__prefix}"/%{libdirname}/python%{libvers}/idlelib \
+      "$RPM_BUILD_ROOT""%{__prefix}"/%{libdirname}/python%{libvers}/Tools -type f |
+      grep -v -e '\.pyc$' -e '\.pyo$' |
+      sed "s|^${RPM_BUILD_ROOT}|/|" >tools.files
+echo "%{__prefix}"/bin/idle%{binsuffix} >>tools.files
+grep '\.py$' tools.files | sed 's/$/c/' | grep -v /idlelib/ >tools.files.tmp
+grep '\.py$' tools.files | sed 's/$/o/' | grep -v /idlelib/ >>tools.files.tmp
+cat tools.files.tmp >>tools.files
+rm tools.files.tmp
+
+######
+# Docs
+%if %{include_docs}
+mkdir -p "$RPM_BUILD_ROOT"%{config_htmldir}
+(
+   cd "$RPM_BUILD_ROOT"%{config_htmldir}
+   bunzip2 < %{SOURCE1} | tar x
+)
+%endif
+
+#  fix the #! line in installed files
+find "$RPM_BUILD_ROOT" -type f -print0 |
+      xargs -0 grep -l /usr/local/bin/python | while read file
+do
+   FIXFILE="$file"
+   sed 's|^#!.*python|#!%{__prefix}/bin/env python'"%{binsuffix}"'|' \
+         "$FIXFILE" >/tmp/fix-python-path.$$
+   cat /tmp/fix-python-path.$$ >"$FIXFILE"
+   rm -f /tmp/fix-python-path.$$
+done
+
+#  check to see if there are any straggling #! lines
+find "$RPM_BUILD_ROOT" -type f | xargs egrep -n '^#! */usr/local/bin/python' \
+      | grep ':1:#!' >/tmp/python-rpm-files.$$ || true
+if [ -s /tmp/python-rpm-files.$$ ]
+then
+   echo '*****************************************************'
+   cat /tmp/python-rpm-files.$$
+   cat <<@EOF
+   *****************************************************
+     There are still files referencing /usr/local/bin/python in the
+     install directory.  They are listed above.  Please fix the .spec
+     file and try again.  If you are an end-user, you probably want
+     to report this to jafo-rpms at tummy.com as well.
+   *****************************************************
+ at EOF
+   rm -f /tmp/python-rpm-files.$$
+   exit 1
+fi
+rm -f /tmp/python-rpm-files.$$
+
+########
+#  CLEAN
+########
+%clean
+[ -n "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ] && rm -rf $RPM_BUILD_ROOT
+rm -f mainpkg.files tools.files
+
+########
+#  FILES
+########
+%files -f mainpkg.files
+%defattr(-,root,root)
+%doc Misc/README Misc/cheatsheet Misc/Porting
+%doc LICENSE Misc/ACKS Misc/HISTORY Misc/NEWS
+%{__prefix}/man/man1/python%{binsuffix}.1*
+
+%attr(755,root,root) %dir %{__prefix}/include/python%{libvers}
+%attr(755,root,root) %dir %{__prefix}/%{libdirname}/python%{libvers}/
+%{__prefix}/%{libdirname}/python%{libvers}/*.txt
+%{__prefix}/%{libdirname}/python%{libvers}/*.py*
+%{__prefix}/%{libdirname}/python%{libvers}/pdb.doc
+%{__prefix}/%{libdirname}/python%{libvers}/curses
+%{__prefix}/%{libdirname}/python%{libvers}/distutils
+%{__prefix}/%{libdirname}/python%{libvers}/encodings
+%{__prefix}/%{libdirname}/python%{libvers}/plat-linux2
+%{__prefix}/%{libdirname}/python%{libvers}/site-packages
+%{__prefix}/%{libdirname}/python%{libvers}/test
+%{__prefix}/%{libdirname}/python%{libvers}/xml
+%{__prefix}/%{libdirname}/python%{libvers}/email
+%{__prefix}/%{libdirname}/python%{libvers}/sqlite3
+%{__prefix}/%{libdirname}/python%{libvers}/compiler
+%{__prefix}/%{libdirname}/python%{libvers}/bsddb
+%{__prefix}/%{libdirname}/python%{libvers}/hotshot
+%{__prefix}/%{libdirname}/python%{libvers}/logging
+%{__prefix}/%{libdirname}/python%{libvers}/wsgiref
+%{__prefix}/%{libdirname}/python%{libvers}/ctypes
+%{__prefix}/%{libdirname}/python%{libvers}/wsgiref.egg-info
+
+%files devel
+%defattr(-,root,root)
+%{__prefix}/include/python%{libvers}/*.h
+%{__prefix}/%{libdirname}/python%{libvers}/config
+
+%files -f tools.files tools
+%defattr(-,root,root)
+
+%if %{include_tkinter}
+%files tkinter
+%defattr(-,root,root)
+%{__prefix}/%{libdirname}/python%{libvers}/lib-tk
+%{__prefix}/%{libdirname}/python%{libvers}/lib-dynload/_tkinter.so*
+%endif
+
+%if %{include_docs}
+%files docs
+%defattr(-,root,root)
+%{config_htmldir}/*
+%endif

Added: vendor/Python/current/Misc/SpecialBuilds.txt
===================================================================
--- vendor/Python/current/Misc/SpecialBuilds.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Misc/SpecialBuilds.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,261 @@
+This file describes some special Python build types enabled via
+compile-time preprocessor defines.
+
+It is best to define these options in the EXTRA_CFLAGS make variable;
+``make EXTRA_CFLAGS="-DPy_REF_DEBUG"``.
+
+---------------------------------------------------------------------------
+Py_REF_DEBUG                                              introduced in 1.4
+                                                 named REF_DEBUG before 1.4
+
+Turn on aggregate reference counting.  This arranges that extern
+_Py_RefTotal hold a count of all references, the sum of ob_refcnt across
+all objects.  In a debug-mode build, this is where the "8288" comes from
+in
+
+    >>> 23
+    23
+    [8288 refs]
+    >>>
+
+Note that if this count increases when you're not storing away new objects,
+there's probably a leak.  Remember, though, that in interactive mode the
+special name "_" holds a reference to the last result displayed!
+
+Py_REF_DEBUG also checks after every decref to verify that the refcount
+hasn't gone negative, and causes an immediate fatal error if it has.
+
+Special gimmicks:
+
+sys.gettotalrefcount()
+    Return current total of all refcounts.
+    Available under Py_REF_DEBUG in Python 2.3.
+    Before 2.3, Py_TRACE_REFS was required to enable this function.
+---------------------------------------------------------------------------
+Py_TRACE_REFS                                             introduced in 1.4
+                                                named TRACE_REFS before 1.4
+
+Turn on heavy reference debugging.  This is major surgery.  Every PyObject
+grows two more pointers, to maintain a doubly-linked list of all live
+heap-allocated objects.  Most builtin type objects are not in this list,
+as they're statically allocated.  Starting in Python 2.3, if COUNT_ALLOCS
+(see below) is also defined, a static type object T does appear in this
+list if at least one object of type T has been created.
+
+Note that because the fundamental PyObject layout changes, Python modules
+compiled with Py_TRACE_REFS are incompatible with modules compiled without
+it.
+
+Py_TRACE_REFS implies Py_REF_DEBUG.
+
+Special gimmicks:
+
+sys.getobjects(max[, type])
+    Return list of the (no more than) max most-recently allocated objects,
+    most recently allocated first in the list, least-recently allocated
+    last in the list.  max=0 means no limit on list length.
+    If an optional type object is passed, the list is also restricted to
+    objects of that type.
+    The return list itself, and some temp objects created just to call
+    sys.getobjects(), are excluded from the return list.  Note that the
+    list returned is just another object, though, so may appear in the
+    return list the next time you call getobjects(); note that every
+    object in the list is kept alive too, simply by virtue of being in
+    the list.
+
+envar PYTHONDUMPREFS
+    If this envar exists, Py_Finalize() arranges to print a list of
+    all still-live heap objects.  This is printed twice, in different
+    formats, before and after Py_Finalize has cleaned up everything it
+    can clean up.  The first output block produces the repr() of each
+    object so is more informative; however, a lot of stuff destined to
+    die is still alive then.  The second output block is much harder
+    to work with (repr() can't be invoked anymore -- the interpreter
+    has been torn down too far), but doesn't list any objects that will
+    die.  The tool script combinerefs.py can be run over this to combine
+    the info from both output blocks.  The second output block, and
+    combinerefs.py, were new in Python 2.3b1.
+---------------------------------------------------------------------------
+PYMALLOC_DEBUG                                            introduced in 2.3
+
+When pymalloc is enabled (WITH_PYMALLOC is defined), calls to the PyObject_
+memory routines are handled by Python's own small-object allocator, while
+calls to the PyMem_ memory routines are directed to the system malloc/
+realloc/free.  If PYMALLOC_DEBUG is also defined, calls to both PyObject_
+and PyMem_ memory routines are directed to a special debugging mode of
+Python's small-object allocator.
+
+This mode fills dynamically allocated memory blocks with special,
+recognizable bit patterns, and adds debugging info on each end of
+dynamically allocated memory blocks.  The special bit patterns are:
+
+#define CLEANBYTE     0xCB   /* clean (newly allocated) memory */
+#define DEADBYTE      0xDB   /* dead (newly freed) memory */
+#define FORBIDDENBYTE 0xFB   /* fordidden -- untouchable bytes */
+
+Strings of these bytes are unlikely to be valid addresses, floats, or 7-bit
+ASCII strings.
+
+Let S = sizeof(size_t). 2*S bytes are added at each end of each block of N
+bytes requested.  The memory layout is like so, where p represents the
+address returned by a malloc-like or realloc-like function (p[i:j] means
+the slice of bytes from *(p+i) inclusive up to *(p+j) exclusive; note that
+the treatment of negative indices differs from a Python slice):
+
+p[-2*S:-S]
+    Number of bytes originally asked for.  This is a size_t, big-endian
+    (easier to read in a memory dump).
+p[-S:0]
+    Copies of FORBIDDENBYTE.  Used to catch under- writes and reads.
+p[0:N]
+    The requested memory, filled with copies of CLEANBYTE, used to catch
+    reference to uninitialized memory.
+    When a realloc-like function is called requesting a larger memory
+    block, the new excess bytes are also filled with CLEANBYTE.
+    When a free-like function is called, these are overwritten with
+    DEADBYTE, to catch reference to freed memory.  When a realloc-
+    like function is called requesting a smaller memory block, the excess
+    old bytes are also filled with DEADBYTE.
+p[N:N+S]
+    Copies of FORBIDDENBYTE.  Used to catch over- writes and reads.
+p[N+S:N+2*S]
+    A serial number, incremented by 1 on each call to a malloc-like or
+    realloc-like function.
+    Big-endian size_t.
+    If "bad memory" is detected later, the serial number gives an
+    excellent way to set a breakpoint on the next run, to capture the
+    instant at which this block was passed out.  The static function
+    bumpserialno() in obmalloc.c is the only place the serial number
+    is incremented, and exists so you can set such a breakpoint easily.
+
+A realloc-like or free-like function first checks that the FORBIDDENBYTEs
+at each end are intact.  If they've been altered, diagnostic output is
+written to stderr, and the program is aborted via Py_FatalError().  The
+other main failure mode is provoking a memory error when a program
+reads up one of the special bit patterns and tries to use it as an address.
+If you get in a debugger then and look at the object, you're likely
+to see that it's entirely filled with 0xDB (meaning freed memory is
+getting used) or 0xCB (meaning uninitialized memory is getting used).
+
+Note that PYMALLOC_DEBUG requires WITH_PYMALLOC.
+
+Special gimmicks:
+
+envar PYTHONMALLOCSTATS
+    If this envar exists, a report of pymalloc summary statistics is
+    printed to stderr whenever a new arena is allocated, and also
+    by Py_Finalize().
+
+Changed in 2.5:  The number of extra bytes allocated is 4*sizeof(size_t).
+Before it was 16 on all boxes, reflecting that Python couldn't make use of
+allocations >= 2**32 bytes even on 64-bit boxes before 2.5.
+---------------------------------------------------------------------------
+Py_DEBUG                                                  introduced in 1.5
+                                                     named DEBUG before 1.5
+
+This is what is generally meant by "a debug build" of Python.
+
+Py_DEBUG implies LLTRACE, Py_REF_DEBUG, Py_TRACE_REFS, and
+PYMALLOC_DEBUG (if WITH_PYMALLOC is enabled).  In addition, C
+assert()s are enabled (via the C way: by not defining NDEBUG), and
+some routines do additional sanity checks inside "#ifdef Py_DEBUG"
+blocks.
+---------------------------------------------------------------------------
+COUNT_ALLOCS                                            introduced in 0.9.9
+                                             partly broken in 2.2 and 2.2.1
+
+Each type object grows three new members:
+
+    /* Number of times an object of this type was allocated. */
+    int tp_allocs;
+
+    /* Number of times an object of this type was deallocated. */
+    int tp_frees;
+
+    /* Highwater mark:  the maximum value of tp_allocs - tp_frees so
+     * far; or, IOW, the largest number of objects of this type alive at
+     * the same time.
+     */
+    int tp_maxalloc;
+
+Allocation and deallocation code keeps these counts up to date.
+Py_Finalize() displays a summary of the info returned by sys.getcounts()
+(see below), along with assorted other special allocation counts (like
+the number of tuple allocations satisfied by a tuple free-list, the number
+of 1-character strings allocated, etc).
+
+Before Python 2.2, type objects were immortal, and the COUNT_ALLOCS
+implementation relies on that.  As of Python 2.2, heap-allocated type/
+class objects can go away.  COUNT_ALLOCS can blow up in 2.2 and 2.2.1
+because of this; this was fixed in 2.2.2.  Use of COUNT_ALLOCS makes
+all heap-allocated type objects immortal, except for those for which no
+object of that type is ever allocated.
+
+Starting with Python 2.3, If Py_TRACE_REFS is also defined, COUNT_ALLOCS
+arranges to ensure that the type object for each allocated object
+appears in the doubly-linked list of all objects maintained by
+Py_TRACE_REFS.
+
+Special gimmicks:
+
+sys.getcounts()
+    Return a list of 4-tuples, one entry for each type object for which
+    at least one object of that type was allocated.  Each tuple is of
+    the form:
+
+        (tp_name, tp_allocs, tp_frees, tp_maxalloc)
+
+    Each distinct type object gets a distinct entry in this list, even
+    if two or more type objects have the same tp_name (in which case
+    there's no way to distinguish them by looking at this list).  The
+    list is ordered by time of first object allocation:  the type object
+    for which the first allocation of an object of that type occurred
+    most recently is at the front of the list.
+---------------------------------------------------------------------------
+LLTRACE                                          introduced well before 1.0
+
+Compile in support for Low Level TRACE-ing of the main interpreter loop.
+
+When this preprocessor symbol is defined, before PyEval_EvalFrame
+(eval_frame in 2.3 and 2.2, eval_code2 before that) executes a frame's code
+it checks the frame's global namespace for a variable "__lltrace__".  If
+such a variable is found, mounds of information about what the interpreter
+is doing are sprayed to stdout, such as every opcode and opcode argument
+and values pushed onto and popped off the value stack.
+
+Not useful very often, but very useful when needed.
+
+---------------------------------------------------------------------------
+CALL_PROFILE                                      introduced for Python 2.3
+
+Count the number of function calls executed.
+
+When this symbol is defined, the ceval mainloop and helper functions
+count the number of function calls made.  It keeps detailed statistics
+about what kind of object was called and whether the call hit any of
+the special fast paths in the code.
+
+---------------------------------------------------------------------------
+WITH_TSC                                          introduced for Python 2.4
+
+Super-lowlevel profiling of the interpreter.  When enabled, the sys
+module grows a new function:
+
+settscdump(bool)
+    If true, tell the Python interpreter to dump VM measurements to
+    stderr.  If false, turn off dump.  The measurements are based on the
+    processor's time-stamp counter.
+
+This build option requires a small amount of platform specific code.
+Currently this code is present for linux/x86 and any PowerPC platform
+that uses GCC (i.e. OS X and linux/ppc).
+
+On the PowerPC the rate at which the time base register is incremented
+is not defined by the architecture specification, so you'll need to
+find the manual for your specific processor.  For the 750CX, 750CXe
+and 750FX (all sold as the G3) we find:
+
+    The time base counter is clocked at a frequency that is
+    one-fourth that of the bus clock.
+
+This build is enabled by the --with-tsc flag to configure.

Added: vendor/Python/current/Misc/Vim/python.vim
===================================================================
--- vendor/Python/current/Misc/Vim/python.vim	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Misc/Vim/python.vim	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,147 @@
+" Auto-generated Vim syntax file for Python
+"
+" To use: copy or symlink to ~/.vim/syntax/python.vim
+
+
+if exists("b:current_syntax")
+  finish
+endif
+
+if exists("python_highlight_all")
+  let python_highlight_numbers = 1
+  let python_highlight_builtins = 1
+  let python_highlight_exceptions = 1
+  let python_highlight_space_errors = 1
+endif
+
+syn keyword pythonStatement    as assert break continue del except exec finally
+syn keyword pythonStatement    global lambda pass print raise return try with
+syn keyword pythonStatement    yield
+
+syn keyword pythonStatement    def class nextgroup=pythonFunction skipwhite
+
+syn match pythonFunction    "[a-zA-Z_][a-zA-Z0-9_]*" contained
+
+syn keyword pythonRepeat    for while
+
+syn keyword pythonConditional    if elif else
+
+syn keyword pythonOperator    and in is not or
+
+syn keyword pythonPreCondit    import from
+
+syn match pythonComment    "#.*$" contains=pythonTodo
+
+syn keyword pythonTodo    TODO FIXME XXX contained
+
+syn region pythonString    matchgroup=Normal start=+[uU]\='+ end=+'+ skip=+\\\\\|\\'+ contains=pythonEscape
+syn region pythonString    matchgroup=Normal start=+[uU]\="+ end=+"+ skip=+\\\\\|\\"+ contains=pythonEscape
+syn region pythonString    matchgroup=Normal start=+[uU]\="""+ end=+"""+  contains=pythonEscape
+syn region pythonString    matchgroup=Normal start=+[uU]\='''+ end=+'''+  contains=pythonEscape
+syn region pythonString    matchgroup=Normal start=+[uU]\=[rR]'+ end=+'+ skip=+\\\\\|\\'+ 
+syn region pythonString    matchgroup=Normal start=+[uU]\=[rR]"+ end=+"+ skip=+\\\\\|\\"+ 
+syn region pythonString    matchgroup=Normal start=+[uU]\=[rR]"""+ end=+"""+  
+syn region pythonString    matchgroup=Normal start=+[uU]\=[rR]'''+ end=+'''+  
+
+syn match pythonEscape    +\\[abfnrtv\'"\\]+ contained
+syn match pythonEscape    "\\\o\{1,3}" contained
+syn match pythonEscape    "\\x\x\{2}" contained
+syn match pythonEscape    "\(\\u\x\{4}\|\\U\x\{8}\)" contained
+
+syn match pythonEscape    "\\$"
+
+
+if exists("python_highlight_numbers")
+  syn match pythonNumber    "\<0x\x\+[Ll]\=\>"
+  syn match pythonNumber    "\<\d\+[LljJ]\=\>"
+  syn match pythonNumber    "\.\d\+\([eE][+-]\=\d\+\)\=[jJ]\=\>"
+  syn match pythonNumber    "\<\d\+\.\([eE][+-]\=\d\+\)\=[jJ]\=\>"
+  syn match pythonNumber    "\<\d\+\.\d\+\([eE][+-]\=\d\+\)\=[jJ]\=\>"
+
+endif
+
+
+if exists("python_highlight_builtins")
+  syn keyword pythonBuiltin    unichr all set abs vars int __import__ unicode
+  syn keyword pythonBuiltin    enumerate reduce coerce intern exit issubclass
+  syn keyword pythonBuiltin    divmod file Ellipsis apply isinstance open any
+  syn keyword pythonBuiltin    locals help filter basestring slice copyright min
+  syn keyword pythonBuiltin    super sum tuple hex execfile long id xrange chr
+  syn keyword pythonBuiltin    complex bool zip pow dict True oct NotImplemented
+  syn keyword pythonBuiltin    map None float hash getattr buffer max reversed
+  syn keyword pythonBuiltin    object quit len repr callable credits setattr
+  syn keyword pythonBuiltin    eval frozenset sorted ord __debug__ hasattr
+  syn keyword pythonBuiltin    delattr False input license classmethod type
+  syn keyword pythonBuiltin    raw_input list iter compile reload range globals
+  syn keyword pythonBuiltin    staticmethod str property round dir cmp
+
+endif
+
+
+if exists("python_highlight_exceptions")
+  syn keyword pythonException    GeneratorExit ImportError RuntimeError
+  syn keyword pythonException    UnicodeTranslateError MemoryError StopIteration
+  syn keyword pythonException    PendingDeprecationWarning EnvironmentError
+  syn keyword pythonException    LookupError OSError DeprecationWarning
+  syn keyword pythonException    UnicodeError UnicodeEncodeError
+  syn keyword pythonException    FloatingPointError ReferenceError NameError
+  syn keyword pythonException    IOError SyntaxError
+  syn keyword pythonException    FutureWarning ImportWarning SystemExit
+  syn keyword pythonException    Exception EOFError StandardError ValueError
+  syn keyword pythonException    TabError KeyError ZeroDivisionError SystemError
+  syn keyword pythonException    UnicodeDecodeError IndentationError
+  syn keyword pythonException    AssertionError TypeError IndexError
+  syn keyword pythonException    RuntimeWarning KeyboardInterrupt UserWarning
+  syn keyword pythonException    SyntaxWarning UnboundLocalError ArithmeticError
+  syn keyword pythonException    Warning NotImplementedError AttributeError
+  syn keyword pythonException    OverflowError BaseException
+
+endif
+
+
+if exists("python_highlight_space_errors")
+  syn match pythonSpaceError    display excludenl "\S\s\+$"ms=s+1
+  syn match pythonSpaceError    display " \+\t"
+  syn match pythonSpaceError    display "\t\+ "
+
+endif
+
+
+  hi def link pythonStatement Statement
+  hi def link pythonStatement Statement
+  hi def link pythonFunction Function
+  hi def link pythonRepeat Repeat
+  hi def link pythonConditional Conditional
+  hi def link pythonOperator Operator
+  hi def link pythonPreCondit PreCondit
+  hi def link pythonComment Comment
+  hi def link pythonTodo Todo
+  hi def link pythonString String
+  hi def link pythonEscape Special
+  hi def link pythonEscape Special
+
+  if exists("python_highlight_numbers")
+    hi def link pythonNumber Number
+  endif
+
+  if exists("python_highlight_builtins")
+    hi def link pythonBuiltin Function
+  endif
+
+  if exists("python_highlight_exceptions")
+    hi def link pythonException Exception
+  endif
+
+  if exists("python_highlight_space_errors")
+    hi def link pythonSpaceError Error
+  endif
+
+
+" Uncomment the 'minlines' statement line and comment out the 'maxlines'
+" statement line; changes behaviour to look at least 2000 lines previously for
+" syntax matches instead of at most 200 lines
+syn sync match pythonSync grouphere NONE "):$"
+syn sync maxlines=200
+"syn sync minlines=2000
+
+let b:current_syntax = "python"

Added: vendor/Python/current/Misc/Vim/syntax_test.py
===================================================================
--- vendor/Python/current/Misc/Vim/syntax_test.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Misc/Vim/syntax_test.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,63 @@
+"""Test file for syntax highlighting of editors.
+
+Meant to cover a wide range of different types of statements and expressions.
+Not necessarily sensical or comprehensive (assume that if one exception is
+highlighted that all are, for instance).
+
+Highlighting extraneous whitespace at the end of the line is not represented
+here as all trailing whitespace is automatically removed from .py files in the
+repository.
+
+"""
+# Comment
+# OPTIONAL: XXX catch your attention
+
+# Statements
+from __future__ import with_statement  # Import
+from sys import path as thing
+assert True # keyword
+def foo():  # function definition
+    return []
+class Bar(object):  # Class definition
+    def __enter__(self):
+        pass
+    def __exit__(self, *args):
+        pass
+foo()  # UNCOLOURED: function call
+while False:  # 'while'
+    continue
+for x in foo():  # 'for'
+    break
+with Bar() as stuff:
+    pass
+if False: pass  # 'if'
+elif False: pass
+else: pass
+
+# Constants
+'single-quote', u'unicode' # Strings of all kinds; prefixes not highlighted
+"double-quote"
+"""triple double-quote"""
+'''triple single-quote'''
+r'raw'
+ur'unicode raw'
+'escape\n'
+'\04'  # octal
+'\xFF' # hex
+'\u1111' # unicode character
+1  # Integral
+1L
+1.0  # Float
+.1
+1+2j  # Complex
+
+# Expressions
+1 and 2 or 3  # Boolean operators
+2 < 3  # UNCOLOURED: comparison operators
+spam = 42  # UNCOLOURED: assignment
+2 + 3  # UNCOLOURED: number operators
+[]  # UNCOLOURED: list
+{}  # UNCOLOURED: dict
+(1,)  # UNCOLOURED: tuple
+all  # Built-in functions
+GeneratorExit  # Exceptions

Added: vendor/Python/current/Misc/Vim/vim_syntax.py
===================================================================
--- vendor/Python/current/Misc/Vim/vim_syntax.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Misc/Vim/vim_syntax.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,226 @@
+from __future__ import with_statement
+
+import keyword
+import exceptions
+import __builtin__
+from string import Template
+
+comment_header = """" Auto-generated Vim syntax file for Python
+"
+" To use: copy or symlink to ~/.vim/syntax/python.vim"""
+
+statement_header = """
+if exists("b:current_syntax")
+  finish
+endif"""
+
+statement_footer = '''
+" Uncomment the 'minlines' statement line and comment out the 'maxlines'
+" statement line; changes behaviour to look at least 2000 lines previously for
+" syntax matches instead of at most 200 lines
+syn sync match pythonSync grouphere NONE "):$"
+syn sync maxlines=200
+"syn sync minlines=2000
+
+let b:current_syntax = "python"'''
+
+looping = ('for', 'while')
+conditionals = ('if', 'elif', 'else')
+boolean_ops = ('and', 'in', 'is', 'not', 'or')
+import_stmts = ('import', 'from')
+object_defs = ('def', 'class')
+
+exception_names = frozenset(exc for exc in dir(exceptions)
+                                if not exc.startswith('__'))
+
+# Need to include functions that start with '__' (e.g., __import__), but
+# nothing that comes with modules (e.g., __name__), so just exclude anything in
+# the 'exceptions' module since we want to ignore exceptions *and* what any
+# module would have
+builtin_names = frozenset(builtin for builtin in dir(__builtin__)
+                            if builtin not in dir(exceptions))
+
+escapes = (r'+\\[abfnrtv\'"\\]+', r'"\\\o\{1,3}"', r'"\\x\x\{2}"',
+            r'"\(\\u\x\{4}\|\\U\x\{8}\)"', r'"\\$"')
+
+todos = ("TODO", "FIXME", "XXX")
+
+# XXX codify?
+numbers = (r'"\<0x\x\+[Ll]\=\>"', r'"\<\d\+[LljJ]\=\>"',
+            '"\.\d\+\([eE][+-]\=\d\+\)\=[jJ]\=\>"',
+            '"\<\d\+\.\([eE][+-]\=\d\+\)\=[jJ]\=\>"',
+            '"\<\d\+\.\d\+\([eE][+-]\=\d\+\)\=[jJ]\=\>"')
+
+contained = lambda x: "%s contained" % x
+
+def str_regexes():
+    """Generator to yield various combinations of strings regexes"""
+    regex_template = Template('matchgroup=Normal ' +
+                                'start=+[uU]\=${raw}${sep}+ ' +
+                                'end=+${sep}+ ' +
+                                '${skip} ' +
+                                '${contains}')
+    skip_regex = Template(r'skip=+\\\\\|\\${sep}+')
+    for raw in ('', '[rR]'):
+        for separator in ("'", '"', '"""', "'''"):
+            if len(separator) == 1:
+                skip = skip_regex.substitute(sep=separator)
+            else:
+                skip = ''
+            contains = 'contains=pythonEscape' if not raw else ''
+            yield regex_template.substitute(raw=raw, sep=separator, skip=skip,
+                                            contains = contains)
+
+space_errors = (r'excludenl "\S\s\+$"ms=s+1', r'" \+\t"', r'"\t\+ "')
+
+statements = (
+                ('',
+                    # XXX Might need to change pythonStatement since have
+                    # specific Repeat, Conditional, Operator, etc. for 'while',
+                    # etc.
+                    [("Statement", "pythonStatement", "keyword",
+                        (kw for kw in keyword.kwlist
+                            if kw not in (looping + conditionals + boolean_ops +
+                                        import_stmts + object_defs))
+                      ),
+                     ("Statement", "pythonStatement", "keyword",
+                         (' '.join(object_defs) +
+                             ' nextgroup=pythonFunction skipwhite')),
+                     ("Function","pythonFunction", "match",
+                         contained('"[a-zA-Z_][a-zA-Z0-9_]*"')),
+                     ("Repeat", "pythonRepeat", "keyword", looping),
+                     ("Conditional", "pythonConditional", "keyword",
+                         conditionals),
+                     ("Operator", "pythonOperator", "keyword", boolean_ops),
+                     ("PreCondit", "pythonPreCondit", "keyword", import_stmts),
+                     ("Comment", "pythonComment", "match",
+                         '"#.*$" contains=pythonTodo'),
+                     ("Todo", "pythonTodo", "keyword",
+                         contained(' '.join(todos))),
+                     ("String", "pythonString", "region", str_regexes()),
+                     ("Special", "pythonEscape", "match",
+                         (contained(esc) for esc in escapes
+                             if not '$' in esc)),
+                     ("Special", "pythonEscape", "match", r'"\\$"'),
+                    ]
+                ),
+                ("python_highlight_numbers",
+                    [("Number", "pythonNumber", "match", numbers)]
+                ),
+                ("python_highlight_builtins",
+                    [("Function", "pythonBuiltin", "keyword", builtin_names)]
+                ),
+                ("python_highlight_exceptions",
+                    [("Exception", "pythonException", "keyword",
+                        exception_names)]
+                ),
+                ("python_highlight_space_errors",
+                    [("Error", "pythonSpaceError", "match",
+                        ("display " + err for err in space_errors))]
+                )
+             )
+
+def syn_prefix(type_, kind):
+    return 'syn %s %s    ' % (type_, kind)
+
+def fill_stmt(iterable, fill_len):
+    """Yield a string that fills at most fill_len characters with strings
+    returned by 'iterable' and separated by a space"""
+    # Deal with trailing char to handle ' '.join() calculation
+    fill_len += 1
+    overflow = None
+    it = iter(iterable)
+    while True:
+        buffer_ = []
+        total_len = 0
+        if overflow:
+            buffer_.append(overflow)
+            total_len += len(overflow) + 1
+            overflow = None
+        while total_len < fill_len:
+            try:
+                new_item = it.next()
+                buffer_.append(new_item)
+                total_len += len(new_item) + 1
+            except StopIteration:
+                if buffer_:
+                    break
+                if overflow:
+                    yield overflow
+                return
+        if total_len > fill_len:
+            overflow = buffer_.pop()
+            total_len -= len(overflow) - 1
+        ret = ' '.join(buffer_)
+        assert len(ret) <= fill_len
+        yield ret
+
+FILL = 80
+
+def main(file_path):
+    with open(file_path, 'w') as FILE:
+        # Comment for file
+        print>>FILE, comment_header
+        print>>FILE, ''
+        # Statements at start of file
+        print>>FILE, statement_header
+        print>>FILE, ''
+        # Generate case for python_highlight_all
+        print>>FILE, 'if exists("python_highlight_all")'
+        for statement_var, statement_parts in statements:
+            if statement_var:
+                print>>FILE, '  let %s = 1' % statement_var
+        else:
+            print>>FILE, 'endif'
+            print>>FILE, ''
+        # Generate Python groups
+        for statement_var, statement_parts in statements:
+            if statement_var:
+                print>>FILE, 'if exists("%s")' % statement_var
+                indent = '  '
+            else:
+                indent = ''
+            for colour_group, group, type_, arguments in statement_parts:
+                if not isinstance(arguments, basestring):
+                    prefix = syn_prefix(type_, group)
+                    if type_ == 'keyword':
+                        stmt_iter = fill_stmt(arguments,
+                                            FILL - len(prefix) - len(indent))
+                        try:
+                            while True:
+                                print>>FILE, indent + prefix + stmt_iter.next()
+                        except StopIteration:
+                            print>>FILE, ''
+                    else:
+                        for argument in arguments:
+                            print>>FILE, indent + prefix + argument
+                        else:
+                            print>>FILE, ''
+
+                else:
+                    print>>FILE, indent + syn_prefix(type_, group) + arguments
+                    print>>FILE, ''
+            else:
+                if statement_var:
+                    print>>FILE, 'endif'
+                    print>>FILE, ''
+            print>>FILE, ''
+        # Associating Python group with Vim colour group
+        for statement_var, statement_parts in statements:
+            if statement_var:
+                print>>FILE, '  if exists("%s")' % statement_var
+                indent = '    '
+            else:
+                indent = '  '
+            for colour_group, group, type_, arguments in statement_parts:
+                print>>FILE, (indent + "hi def link %s %s" %
+                                (group, colour_group))
+            else:
+                if statement_var:
+                    print>>FILE, '  endif'
+                print>>FILE, ''
+        # Statements at the end of the file
+        print>>FILE, statement_footer
+
+if __name__ == '__main__':
+    main("python.vim")

Added: vendor/Python/current/Misc/Vim/vimrc
===================================================================
--- vendor/Python/current/Misc/Vim/vimrc	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Misc/Vim/vimrc	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,95 @@
+" vimrc file for following the coding standards specified in PEP 7 & 8.
+"
+" To use this file, source it in your own personal .vimrc file (``source
+" <filename>``) or, if you don't have a .vimrc file, you can just symlink to it
+" (``ln -s <this file> ~/.vimrc``).  All options are protected by autocmds
+" (read below for an explanation of the command) so blind sourcing of this file
+" is safe and will not affect your settings for non-Python or non-C files.
+"
+"
+" All setting are protected by 'au' ('autocmd') statements.  Only files ending
+" in .py or .pyw will trigger the Python settings while files ending in *.c or
+" *.h will trigger the C settings.  This makes the file "safe" in terms of only
+" adjusting settings for Python and C files.
+"
+" Only basic settings needed to enforce the style guidelines are set.
+" Some suggested options are listed but commented out at the end of this file.
+
+
+" Number of spaces to use for an indent.
+" This will affect Ctrl-T and 'autoindent'.
+" Python: 4 spaces
+" C: tab (8 spaces)
+au BufRead,BufNewFile *.py,*pyw set shiftwidth=4
+au BufRead,BufNewFile *.c,*.h set shiftwidth=4
+
+" Number of spaces that a pre-existing tab is equal to.
+" For the amount of space used for a new tab use shiftwidth.
+" Python: 8
+" C: 8
+au BufRead,BufNewFile *py,*pyw,*.c,*.h set tabstop=8
+
+" Replace tabs with the equivalent number of spaces.
+" Also have an autocmd for Makefiles since they require hard tabs.
+" Python: yes
+" C: no
+" Makefile: no
+au BufRead,BufNewFile *.py,*.pyw set expandtab
+au BufRead,BufNewFile *.c,*.h set noexpandtab
+au BufRead,BufNewFile Makefile* set noexpandtab
+
+" Use the below highlight group when displaying bad whitespace is desired
+highlight BadWhitespace ctermbg=red guibg=red
+
+" Display tabs at the beginning of a line in Python mode as bad
+au BufRead,BufNewFile *.py,*.pyw match BadWhitespace /^\t\+/
+
+" Wrap text after a certain number of characters
+" Python: 79 
+" C: 79
+au BufRead,BufNewFile *.py,*.pyw,*.c,*.h set textwidth=79
+
+" Turn off settings in 'formatoptions' relating to comment formatting.
+" - c : do not automatically insert the comment leader when wrapping based on
+"    'textwidth'
+" - o : do not insert the comment leader when using 'o' or 'O' from command mode
+" - r : do not insert the comment leader when hitting <Enter> in insert mode
+" Python: not needed
+" C: prevents insertion of '*' at the beginning of every line in a comment
+au BufRead,BufNewFile *.c,*.h set formatoptions-=c formatoptions-=o formatoptions-=r
+
+" Use UNIX (\n) line endings.
+" Only used for new files so as to not force existing files to change their
+" line endings.
+" Python: yes
+" C: yes
+au BufNewFile *.py,*.pyw,*.c,*.h set fileformat=unix
+
+
+" ----------------------------------------------------------------------------
+" The following section contains suggested settings.  While in no way required
+" to meet coding standards, they are helpful.
+
+" Set the default file encoding to UTF-8: ``set encoding=utf-8``
+
+" Puts a marker at the beginning of the file to differentiate between UTF and
+" UCS encoding (WARNING: can trick shells into thinking a text file is actually
+" a binary file when executing the text file): ``set bomb``
+
+" For full syntax highlighting:
+"``let python_highlight_all=1``
+"``syntax on``
+
+" Automatically indent based on file type: ``filetype indent on``
+" Keep indentation level from previous line: ``set autoindent``
+
+" Folding based on indentation: ``set foldmethod=indent``
+
+" Make trailing whitespace explicit (left off since this will automatically
+" insert the highlight or characters *as you type*, which can get annoying):
+"``match BadWhitespace /\s\+$/``
+"
+" or, for a non-colored, character-based solution:
+"
+"``set list listchars=trail:-``
+

Added: vendor/Python/current/Misc/build.sh
===================================================================
--- vendor/Python/current/Misc/build.sh	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Misc/build.sh	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,227 @@
+#!/bin/sh
+
+## Script to build and test the latest python from svn.  It basically
+## does this:
+##   svn up ; ./configure ; make ; make test ; make install ; cd Doc ; make
+##
+## Logs are kept and rsync'ed to the host.  If there are test failure(s),
+## information about the failure(s) is mailed.
+##
+## This script is run on the PSF's machine as user neal via crontab.
+##
+## Yes, this script would probably be easier in python, but then
+## there's a bootstrap problem.  What if Python doesn't build?
+##
+## This script should be fairly clean Bourne shell, ie not too many
+## bash-isms.  We should try to keep it portable to other Unixes.
+## Even though it will probably only run on Linux.  I'm sure there are
+## several GNU-isms currently (date +%s and readlink).
+##
+## Perhaps this script should be broken up into 2 (or more) components.
+## Building doc is orthogonal to the rest of the python build/test.
+##
+
+## FIXME: we should detect test hangs (eg, if they take more than 45 minutes)
+
+## FIXME: we should run valgrind
+## FIXME: we should run code coverage
+
+## Utilities invoked in this script include:
+##    basename, date, dirname, expr, grep, readlink, uname
+##    cksum, make, mutt, rsync, svn
+
+## remember where did we started from
+DIR=`dirname $0`
+if [ "$DIR" = "" ]; then
+   DIR="."
+fi
+
+## make directory absolute
+DIR=`readlink -f $DIR`
+FULLPATHNAME="$DIR/`basename $0`"
+## we want Misc/..
+DIR=`dirname $DIR`
+
+## Configurable options
+
+FAILURE_SUBJECT="Python Regression Test Failures"
+#FAILURE_MAILTO="YOUR_ACCOUNT at gmail.com"
+FAILURE_MAILTO="python-checkins at python.org"
+
+REMOTE_SYSTEM="neal at dinsdale.python.org"
+REMOTE_DIR="/data/ftp.python.org/pub/docs.python.org/dev/"
+RESULT_FILE="$DIR/build/index.html"
+INSTALL_DIR="/tmp/python-test/local"
+RSYNC_OPTS="-aC -e ssh"
+
+# Always run the installed version of Python.
+PYTHON=$INSTALL_DIR/bin/python
+
+# Python options and regression test program that should always be run.
+REGRTEST_ARGS="-E -tt $INSTALL_DIR/lib/python2.5/test/regrtest.py"
+
+REFLOG="build/reflog.txt.out"
+# These tests are not stable and falsely report leaks sometimes.
+# The entire leak report will be mailed if any test not in this list leaks.
+# Note: test_XXX (none currently) really leak, but are disabled
+# so we don't send spam.  Any test which really leaks should only 
+# be listed here if there are also test cases under Lib/test/leakers.
+LEAKY_TESTS="test_(XXX)"  # Currently no tests should report spurious leaks.
+
+# Skip these tests altogether when looking for leaks.  These tests
+# do not need to be stored above in LEAKY_TESTS too.
+# test_compiler almost never finishes with the same number of refs
+# since it depends on other modules, skip it.
+# test_logging causes hangs, skip it.
+LEAKY_SKIPS="-x test_compiler test_logging"
+
+# Change this flag to "yes" for old releases to only update/build the docs.
+BUILD_DISABLED="no"
+
+## utility functions
+current_time() {
+    date +%s
+}
+
+update_status() {
+    now=`current_time`
+    time=`expr $now - $3`
+    echo "<li><a href=\"$2\">$1</a> <font size=\"-1\">($time seconds)</font></li>" >> $RESULT_FILE
+}
+
+mail_on_failure() {
+    if [ "$NUM_FAILURES" != "0" ]; then
+        mutt -s "$FAILURE_SUBJECT $1 ($NUM_FAILURES)" $FAILURE_MAILTO < $2
+    fi
+}
+
+## setup
+cd $DIR
+mkdir -p build
+rm -f $RESULT_FILE build/*.out
+rm -rf $INSTALL_DIR
+
+## create results file
+TITLE="Automated Python Build Results"
+echo "<html>" >> $RESULT_FILE
+echo "  <head>" >> $RESULT_FILE
+echo "    <title>$TITLE</title>" >> $RESULT_FILE
+echo "    <meta http-equiv=\"refresh\" content=\"43200\">" >> $RESULT_FILE
+echo "  </head>" >> $RESULT_FILE
+echo "<body>" >> $RESULT_FILE
+echo "<h2>Automated Python Build Results</h2>" >> $RESULT_FILE
+echo "<table>" >> $RESULT_FILE
+echo "  <tr>" >> $RESULT_FILE
+echo "    <td>Built on:</td><td>`date`</td>" >> $RESULT_FILE
+echo "  </tr><tr>" >> $RESULT_FILE
+echo "    <td>Hostname:</td><td>`uname -n`</td>" >> $RESULT_FILE
+echo "  </tr><tr>" >> $RESULT_FILE
+echo "    <td>Platform:</td><td>`uname -srmpo`</td>" >> $RESULT_FILE
+echo "  </tr>" >> $RESULT_FILE
+echo "</table>" >> $RESULT_FILE
+echo "<ul>" >> $RESULT_FILE
+
+## update, build, and test
+ORIG_CHECKSUM=`cksum $FULLPATHNAME`
+F=svn-update.out
+start=`current_time`
+svn update >& build/$F
+err=$?
+update_status "Updating" "$F" $start
+if [ $err = 0 -a "$BUILD_DISABLED" != "yes" ]; then
+    ## FIXME: we should check if this file has changed.
+    ##  If it has changed, we should re-run the script to pick up changes.
+    if [ "$ORIG_CHECKSUM" != "$ORIG_CHECKSUM" ]; then
+        exec $FULLPATHNAME $@
+    fi
+
+    F=svn-stat.out
+    start=`current_time`
+    svn stat >& build/$F
+    ## ignore some of the diffs
+    NUM_DIFFS=`egrep -vc '^.      (@test|db_home|Lib/test/(regrtest\.py|db_home))$' build/$F`
+    update_status "svn stat ($NUM_DIFFS possibly important diffs)" "$F" $start
+
+    F=configure.out
+    start=`current_time`
+    ./configure --prefix=$INSTALL_DIR --with-pydebug >& build/$F
+    err=$?
+    update_status "Configuring" "$F" $start
+    if [ $err = 0 ]; then
+        F=make.out
+        start=`current_time`
+        make >& build/$F
+        err=$?
+        warnings=`grep warning build/$F | egrep -vc "te?mpnam(_r|)' is dangerous,"`
+        update_status "Building ($warnings warnings)" "$F" $start
+        if [ $err = 0 ]; then
+            ## make install
+            F=make-install.out
+            start=`current_time`
+            make install >& build/$F
+            update_status "Installing" "$F" $start
+
+            if [ ! -x $PYTHON ]; then
+                ln -s ${PYTHON}2.* $PYTHON
+            fi
+
+            ## make and run basic tests
+            F=make-test.out
+            start=`current_time`
+            $PYTHON $REGRTEST_ARGS >& build/$F
+            NUM_FAILURES=`grep -ic " failed:" build/$F`
+            update_status "Testing basics ($NUM_FAILURES failures)" "$F" $start
+            mail_on_failure "basics" build/$F
+
+            F=make-test-opt.out
+            start=`current_time`
+            $PYTHON -O $REGRTEST_ARGS >& build/$F
+            NUM_FAILURES=`grep -ic " failed:" build/$F`
+            update_status "Testing opt ($NUM_FAILURES failures)" "$F" $start
+            mail_on_failure "opt" build/$F
+
+            ## run the tests looking for leaks
+            F=make-test-refleak.out
+            start=`current_time`
+            ## ensure that the reflog exists so the grep doesn't fail
+            touch $REFLOG
+            $PYTHON $REGRTEST_ARGS -R 4:3:$REFLOG -u network $LEAKY_SKIPS >& build/$F
+            NUM_FAILURES=`egrep -vc "$LEAKY_TESTS" $REFLOG`
+            update_status "Testing refleaks ($NUM_FAILURES failures)" "$F" $start
+            mail_on_failure "refleak" $REFLOG
+
+            ## now try to run all the tests
+            F=make-testall.out
+            start=`current_time`
+            ## skip curses when running from cron since there's no terminal
+            ## skip sound since it's not setup on the PSF box (/dev/dsp)
+            $PYTHON $REGRTEST_ARGS -uall -x test_curses test_linuxaudiodev test_ossaudiodev >& build/$F
+            NUM_FAILURES=`grep -ic " failed:" build/$F`
+            update_status "Testing all except curses and sound ($NUM_FAILURES failures)" "$F" $start
+            mail_on_failure "all" build/$F
+        fi
+    fi
+fi
+
+
+## make doc
+cd $DIR/Doc
+F="make-doc.out"
+start=`current_time`
+make >& ../build/$F
+err=$?
+update_status "Making doc" "$F" $start
+if [ $err != 0 ]; then
+    NUM_FAILURES=1
+    mail_on_failure "doc" ../build/$F
+fi
+
+echo "</ul>" >> $RESULT_FILE
+echo "</body>" >> $RESULT_FILE
+echo "</html>" >> $RESULT_FILE
+
+## copy results
+rsync $RSYNC_OPTS html/* $REMOTE_SYSTEM:$REMOTE_DIR
+cd ../build
+rsync $RSYNC_OPTS index.html *.out $REMOTE_SYSTEM:$REMOTE_DIR/results/
+


Property changes on: vendor/Python/current/Misc/build.sh
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Misc/cheatsheet
===================================================================
--- vendor/Python/current/Misc/cheatsheet	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Misc/cheatsheet	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2279 @@
+                          Python 2.3 Quick Reference
+
+
+ 25 Jan 2003  upgraded by Raymond Hettinger for Python 2.3
+ 16 May 2001  upgraded by Richard Gruet and Simon Brunning for Python 2.0
+ 2000/07/18  upgraded by Richard Gruet, rgruet at intraware.com for Python 1.5.2
+from V1.3 ref
+1995/10/30, by Chris Hoffmann, choffman at vicorp.com
+
+Based on:
+    Python Bestiary, Author: Ken Manheimer, ken.manheimer at nist.gov
+    Python manuals, Authors: Guido van Rossum and Fred Drake
+    What's new in Python 2.0, Authors: A.M. Kuchling and Moshe Zadka
+    python-mode.el, Author: Tim Peters, tim_one at email.msn.com
+
+    and the readers of comp.lang.python
+
+Python's nest: http://www.python.org     Developement: http://
+python.sourceforge.net/    ActivePython : http://www.ActiveState.com/ASPN/
+Python/
+newsgroup: comp.lang.python  Help desk: help at python.org
+Resources: http://starship.python.net/
+           http://www.vex.net/parnassus/
+           http://aspn.activestate.com/ASPN/Cookbook/Python
+FAQ:       http://www.python.org/cgi-bin/faqw.py
+Full documentation: http://www.python.org/doc/
+Excellent reference books:
+           Python Essential Reference by David Beazley (New Riders)
+           Python Pocket Reference by Mark Lutz (O'Reilly)
+
+
+Invocation Options
+
+python [-diOStuUvxX?] [-c command | script | - ] [args]
+
+                              Invocation Options
+Option                                  Effect
+-c cmd  program passed in as string (terminates option list)
+-d      Outputs parser debugging information (also PYTHONDEBUG=x)
+-E      ignore environment variables (such as PYTHONPATH)
+-h      print this help message and exit
+-i      Inspect interactively after running script (also PYTHONINSPECT=x) and
+        force prompts, even if stdin appears not to be a terminal
+-O      optimize generated bytecode (a tad; also PYTHONOPTIMIZE=x)
+-OO     remove doc-strings in addition to the -O optimizations
+-Q arg  division options: -Qold (default), -Qwarn, -Qwarnall, -Qnew
+-S      Don't perform 'import site' on initialization
+-t      Issue warnings about inconsistent tab usage (-tt: issue errors)
+-u      Unbuffered binary stdout and stderr (also PYTHONUNBUFFERED=x).
+-v      Verbose (trace import statements) (also PYTHONVERBOSE=x)
+-W arg : warning control (arg is action:message:category:module:lineno)
+-x      Skip first line of source, allowing use of non-unix Forms of #!cmd
+-?      Help!
+-c      Specify the command to execute (see next section). This terminates the
+command option list (following options are passed as arguments to the command).
+        the name of a python file (.py) to execute read from stdin.
+script  Anything afterward is passed as options to python script or command,
+        not interpreted as an option to interpreter itself.
+args    passed to script or command (in sys.argv[1:])
+        If no script or command, Python enters interactive mode.
+
+  * Available IDEs in std distrib: IDLE (tkinter based, portable), Pythonwin
+    (Windows).
+
+
+
+Environment variables
+
+                             Environment variables
+    Variable                                 Effect
+PYTHONHOME       Alternate prefix directory (or prefix;exec_prefix). The
+                 default module search path uses prefix/lib
+                 Augments the default search path for module files. The format
+                 is the same as the shell's $PATH: one or more directory
+                 pathnames separated by ':' or ';' without spaces around
+                 (semi-)colons!
+PYTHONPATH       On Windows first search for Registry key HKEY_LOCAL_MACHINE\
+                 Software\Python\PythonCore\x.y\PythonPath (default value). You
+                 may also define a key named after your application with a
+                 default string value giving the root directory path of your
+                 app.
+                 If this is the name of a readable file, the Python commands in
+PYTHONSTARTUP    that file are executed before the first prompt is displayed in
+                 interactive mode (no default).
+PYTHONDEBUG      If non-empty, same as -d option
+PYTHONINSPECT    If non-empty, same as -i option
+PYTHONSUPPRESS   If non-empty, same as -s option
+PYTHONUNBUFFERED If non-empty, same as -u option
+PYTHONVERBOSE    If non-empty, same as -v option
+PYTHONCASEOK     If non-empty, ignore case in file/module names (imports)
+
+
+
+
+Notable lexical entities
+
+Keywords
+
+    and       del       for       is        raise
+    assert    elif      from      lambda    return
+    break     else      global    not       try
+    class     except    if        or        while
+    continue  exec      import    pass      yield
+    def       finally   in        print
+
+  * (list of keywords in std module: keyword)
+  * Illegitimate Tokens (only valid in strings): @ $ ?
+  * A statement must all be on a single line. To break a statement over
+    multiple lines use "\", as with the C preprocessor.
+    Exception: can always break when inside any (), [], or {} pair, or in
+    triple-quoted strings.
+  * More than one statement can appear on a line if they are separated with
+    semicolons (";").
+  * Comments start with "#" and continue to end of line.
+
+Identifiers
+
+        (letter | "_")  (letter | digit | "_")*
+
+  * Python identifiers keywords, attributes, etc. are case-sensitive.
+  * Special forms: _ident (not imported by 'from module import *'); __ident__
+    (system defined name);
+               __ident (class-private name mangling)
+
+Strings
+
+    "a string enclosed by double quotes"
+    'another string delimited by single quotes and with a " inside'
+    '''a string containing embedded newlines and quote (') marks, can be
+    delimited with triple quotes.'''
+    """ may also use 3- double quotes as delimiters """
+    u'a unicode string'   U"Another unicode string"
+    r'a raw string where \ are kept (literalized): handy for regular
+    expressions and windows paths!'
+    R"another raw string"    -- raw strings cannot end with a \
+    ur'a unicode raw string'   UR"another raw unicode"
+
+        Use \ at end of line to continue a string on next line.
+        adjacent strings are concatened, e.g. 'Monty' ' Python' is the same as
+        'Monty Python'.
+        u'hello' + ' world'  --> u'hello world'   (coerced to unicode)
+
+    String Literal Escapes
+
+     \newline  Ignored (escape newline)
+     \\ Backslash (\)        \e Escape (ESC)        \v Vertical Tab (VT)
+     \' Single quote (')     \f Formfeed (FF)       \OOO char with octal value OOO
+     \" Double quote (")     \n Linefeed (LF)
+     \a Bell (BEL)           \r Carriage Return (CR) \xHH  char with hex value HH
+     \b Backspace (BS)       \t Horizontal Tab (TAB)
+     \uHHHH  unicode char with hex value HHHH, can only be used in unicode string
+     \UHHHHHHHH  unicode char with hex value HHHHHHHH, can only be used in unicode string
+     \AnyOtherChar is left as-is
+
+  * NUL byte (\000) is NOT an end-of-string marker; NULs may be embedded in
+    strings.
+  * Strings (and tuples) are immutable: they cannot be modified.
+
+Numbers
+
+    Decimal integer: 1234, 1234567890546378940L        (or l)
+    Octal integer: 0177, 0177777777777777777 (begin with a 0)
+    Hex integer: 0xFF, 0XFFFFffffFFFFFFFFFF (begin with 0x or 0X)
+    Long integer (unlimited precision): 1234567890123456
+    Float (double precision): 3.14e-10, .001, 10., 1E3
+    Complex: 1J, 2+3J, 4+5j (ends with J or j, + separates (float) real and
+    imaginary parts)
+
+Sequences
+
+  * String of length 0, 1, 2 (see above)
+    '', '1', "12", 'hello\n'
+  * Tuple of length 0, 1, 2, etc:
+    () (1,) (1,2)     # parentheses are optional if len > 0
+  * List of length 0, 1, 2, etc:
+    [] [1] [1,2]
+
+Indexing is 0-based. Negative indices (usually) mean count backwards from end
+of sequence.
+
+Sequence slicing [starting-at-index : but-less-than-index]. Start defaults to
+'0'; End defaults to 'sequence-length'.
+
+a = (0,1,2,3,4,5,6,7)
+    a[3] ==> 3
+    a[-1] ==> 7
+    a[2:4] ==> (2, 3)
+    a[1:] ==> (1, 2, 3, 4, 5, 6, 7)
+    a[:3] ==> (0, 1, 2)
+    a[:] ==> (0,1,2,3,4,5,6,7)  # makes a copy of the sequence.
+
+Dictionaries (Mappings)
+
+    {}                              # Zero length empty dictionary
+    {1 : 'first'}                   # Dictionary with one (key, value) pair
+    {1 : 'first',  'next': 'second'}
+    dict([('one',1),('two',2)])     # Construct a dict from an item list
+    dict('one'=1, 'two'=2)          # Construct a dict using keyword args
+    dict.fromkeys(['one', 'keys'])  # Construct a dict from a sequence
+
+Operators and their evaluation order
+
+                     Operators and their evaluation order
+Highest             Operator                             Comment
+        (...) [...] {...} `...`           Tuple, list & dict. creation; string
+                                          conv.
+        s[i]  s[i:j]  s.attr f(...)       indexing & slicing; attributes, fct
+                                          calls
+        +x, -x, ~x                        Unary operators
+        x**y                              Power
+        x*y  x/y  x%y x//y                mult, division, modulo, floor division
+        x+y  x-y                          addition, subtraction
+        x<<y   x>>y                       Bit shifting
+        x&y                               Bitwise and
+        x^y                               Bitwise exclusive or
+        x|y                               Bitwise or
+        x<y  x<=y  x>y  x>=y  x==y x!=y   Comparison,
+        x<>y                              identity,
+        x is y   x is not y               membership
+        x in s   x not in s
+        not x                             boolean negation
+        x and y                           boolean and
+        x or y                            boolean or
+Lowest  lambda args: expr                 anonymous function
+
+Alternate names are defined in module operator (e.g. __add__ and add for +)
+Most operators are overridable.
+
+Many binary operators also support augmented assignment:
+        x += 1                            # Same as x = x + 1
+
+
+Basic Types and Their Operations
+
+Comparisons (defined between *any* types)
+
+               Comparisons
+Comparison         Meaning          Notes
+<          strictly less than        (1)
+<=         less than or equal to
+>          strictly greater than
+>=         greater than or equal to
+==         equal to
+!= or <>   not equal to
+is         object identity           (2)
+is not     negated object identity   (2)
+
+Notes :
+    Comparison behavior can be overridden for a given class by defining special
+method __cmp__.
+    The above comparisons return True or False which are of type bool
+(a subclass of int) and behave exactly as 1 or 0 except for their type and
+that they print as True or False instead of 1 or 0.
+    (1) X < Y < Z < W has expected meaning, unlike C
+    (2) Compare object identities (i.e. id(object)), not object values.
+
+Boolean values and operators
+
+                         Boolean values and operators
+              Value or Operator                         Returns           Notes
+None, numeric zeros, empty sequences and      False
+mappings
+all other values                              True
+not x                                         True if x is False, else
+                                              True
+x or y                                        if x is False then y, else   (1)
+                                              x
+x and y                                       if x is False then x, else   (1)
+                                              y
+
+Notes :
+    Truth testing behavior can be overridden for a given class by defining
+special method __nonzero__.
+    (1) Evaluate second arg only if necessary to determine outcome.
+
+None
+
+    None is used as default return value on functions. Built-in single object
+    with type NoneType.
+    Input that evaluates to None does not print when running Python
+    interactively.
+
+Numeric types
+
+Floats, integers and long integers.
+
+    Floats are implemented with C doubles.
+    Integers are implemented with C longs.
+    Long integers have unlimited size (only limit is system resources)
+
+Operators on all numeric types
+
+           Operators on all numeric types
+ Operation                    Result
+abs(x)       the absolute value of x
+int(x)       x converted to integer
+long(x)      x converted to long integer
+float(x)     x converted to floating point
+-x           x negated
++x           x unchanged
+x + y        the sum of x and y
+x - y        difference of x and y
+x * y        product of x and y
+x / y        quotient of x and y
+x % y        remainder of x / y
+divmod(x, y) the tuple (x/y, x%y)
+x ** y       x to the power y (the same as pow(x, y))
+
+Bit operators on integers and long integers
+
+              Bit operators
+Operation             >Result
+~x        the bits of x inverted
+x ^ y     bitwise exclusive or of x and y
+x & y     bitwise and of x and y
+x | y     bitwise or of x and y
+x << n    x shifted left by n bits
+x >> n    x shifted right by n bits
+
+Complex Numbers
+
+  * represented as a pair of machine-level double precision floating point
+    numbers.
+  * The real and imaginary value of a complex number z can be retrieved through
+    the attributes z.real and z.imag.
+
+Numeric exceptions
+
+TypeError
+    raised on application of arithmetic operation to non-number
+OverflowError
+     numeric bounds exceeded
+ZeroDivisionError
+     raised when zero second argument of div or modulo op
+FloatingPointError
+     raised when a floating point operation fails
+
+Operations on all sequence types (lists, tuples, strings)
+
+                Operations on all sequence types
+Operation                     Result                     Notes
+x in s     True if an item of s is equal to x, else False
+x not in s False if an item of s is equal to x, else True
+for x in s: loops over the sequence
+s + t      the concatenation of s and t
+s * n, n*s n copies of s concatenated
+s[i]       i'th item of s, origin 0                       (1)
+s[i:j]     slice of s from i (included) to j (excluded) (1), (2)
+len(s)     length of s
+min(s)     smallest item of s
+max(s)     largest item of (s)
+iter(s)    returns an iterator over s.  iterators define __iter__ and next()
+
+Notes :
+    (1) if i or j is negative, the index is relative to the end of the string,
+ie len(s)+ i or len(s)+j is
+         substituted. But note that -0 is still 0.
+    (2) The slice of s from i to j is defined as the sequence of items with
+index k such that i <= k < j.
+          If i or j is greater than len(s), use len(s). If i is omitted, use
+len(s). If i is greater than or
+          equal to j, the slice is empty.
+
+Operations on mutable (=modifiable) sequences (lists)
+
+                 Operations on mutable sequences
+   Operation                      Result                   Notes
+s[i] =x          item i of s is replaced by x
+s[i:j] = t       slice of s from i to j is replaced by t
+del s[i:j]       same as s[i:j] = []
+s.append(x)      same as s[len(s) : len(s)] = [x]
+s.count(x)       return number of i's for which s[i] == x
+s.extend(x)      same as s[len(s):len(s)]= x
+s.index(x)       return smallest i such that s[i] == x      (1)
+s.insert(i, x)   same as s[i:i] = [x] if i >= 0
+s.pop([i])       same as x = s[i]; del s[i]; return x       (4)
+s.remove(x)      same as del s[s.index(x)]                  (1)
+s.reverse()      reverse the items of s in place            (3)
+s.sort([cmpFct]) sort the items of s in place             (2), (3)
+
+Notes :
+    (1) raise a ValueError exception when x is not found in s (i.e. out of
+range).
+     (2) The sort() method takes an optional argument specifying a comparison
+fct of 2 arguments (list items) which should
+          return -1, 0, or 1 depending on whether the 1st argument is
+considered smaller than, equal to, or larger than the 2nd
+          argument. Note that this slows the sorting process down considerably.
+     (3) The sort() and reverse() methods modify the list in place for economy
+of space when sorting or reversing a large list.
+           They don't return the sorted or reversed list to remind you of this
+side effect.
+     (4) [New 1.5.2] The optional  argument i defaults to -1, so that by default the last
+item is removed and returned.
+
+
+
+Operations on mappings (dictionaries)
+
+                         Operations on mappings
+        Operation                          Result                  Notes
+len(d)                     the number of items in d
+d[k]                       the item of d with key k                 (1)
+d[k] = x                   set d[k] to x
+del d[k]                   remove d[k] from d                       (1)
+d.clear()                  remove all items from d
+d.copy()                   a shallow copy of d
+d.get(k,defaultval)        the item of d with key k                 (4)
+d.has_key(k)               True if d has key k, else False
+d.items()                  a copy of d's list of (key, item) pairs  (2)
+d.iteritems()              an iterator over (key, value) pairs      (7)
+d.iterkeys()               an iterator over the keys of d           (7)
+d.itervalues()             an iterator over the values of d         (7)
+d.keys()                   a copy of d's list of keys               (2)
+d1.update(d2)              for k, v in d2.items(): d1[k] = v        (3)
+d.values()                 a copy of d's list of values             (2)
+d.pop(k)                   remove d[k] and return its value
+d.popitem()                remove and return an arbitrary           (6)
+                           (key, item) pair
+d.setdefault(k,defaultval) the item of d with key k                 (5)
+
+    Notes :
+      TypeError is raised if key is not acceptable
+      (1) KeyError is raised if key k is not in the map
+      (2) Keys and values are listed in random order
+      (3) d2 must be of the same type as d1
+      (4) Never raises an exception if k is not in the map, instead it returns
+    defaultVal.
+          defaultVal is optional, when not provided and k is not in the map,
+    None is returned.
+      (5) Never raises an exception if k is not in the map, instead it returns
+    defaultVal, and adds k to map with value defaultVal. defaultVal is
+    optional. When not provided and k is not in the map, None is returned and
+    added to map.
+      (6) Raises a KeyError if the dictionary is emtpy.
+      (7) While iterating over a dictionary, the values may be updated but
+          the keys cannot be changed.
+
+Operations on strings
+
+Note that these string methods largely (but not completely) supersede the
+functions available in the string module.
+
+
+                             Operations on strings
+    Operation                             Result                          Notes
+s.capitalize()    return a copy of s with only its first character
+                  capitalized.
+s.center(width)   return a copy of s centered in a string of length width  (1)
+                  .
+s.count(sub[      return the number of occurrences of substring sub in     (2)
+,start[,end]])    string s.
+s.decode(([       return a decoded version of s.                           (3)
+  encoding
+  [,errors]])
+s.encode([        return an encoded version of s. Default encoding is the
+  encoding        current default string encoding.                         (3)
+  [,errors]])
+s.endswith(suffix return true if s ends with the specified suffix,         (2)
+  [,start[,end]]) otherwise return False.
+s.expandtabs([    return a copy of s where all tab characters are          (4)
+tabsize])         expanded using spaces.
+s.find(sub[,start return the lowest index in s where substring sub is      (2)
+[,end]])          found. Return -1 if sub is not found.
+s.index(sub[      like find(), but raise ValueError when the substring is  (2)
+,start[,end]])    not found.
+s.isalnum()       return True if all characters in s are alphanumeric,     (5)
+                  False otherwise.
+s.isalpha()       return True if all characters in s are alphabetic,       (5)
+                  False otherwise.
+s.isdigit()       return True if all characters in s are digit             (5)
+                  characters, False otherwise.
+s.islower()       return True if all characters in s are lowercase, False  (6)
+                  otherwise.
+s.isspace()       return True if all characters in s are whitespace        (5)
+                  characters, False otherwise.
+s.istitle()       return True if string s is a titlecased string, False    (7)
+                  otherwise.
+s.isupper()       return True if all characters in s are uppercase, False  (6)
+                  otherwise.
+s.join(seq)       return a concatenation of the strings in the sequence
+                  seq, seperated by 's's.
+s.ljust(width)    return s left justified in a string of length width.    (1),
+                                                                           (8)
+s.lower()         return a copy of s converted to lowercase.
+s.lstrip()        return a copy of s with leading whitespace removed.
+s.replace(old,    return a copy of s with all occurrences of substring     (9)
+new[, maxsplit])  old replaced by new.
+s.rfind(sub[      return the highest index in s where substring sub is     (2)
+,start[,end]])    found. Return -1 if sub is not found.
+s.rindex(sub[     like rfind(), but raise ValueError when the substring    (2)
+,start[,end]])    is not found.
+s.rjust(width)    return s right justified in a string of length width.   (1),
+                                                                           (8)
+s.rstrip()        return a copy of s with trailing whitespace removed.
+s.split([sep[     return a list of the words in s, using sep as the       (10)
+,maxsplit]])      delimiter string.
+s.splitlines([    return a list of the lines in s, breaking at line       (11)
+keepends])        boundaries.
+s.startswith      return true if s starts with the specified prefix,
+(prefix[,start[   otherwise return false.                                  (2)
+,end]])
+s.strip()         return a copy of s with leading and trailing whitespace
+                  removed.
+s.swapcase()      return a copy of s with uppercase characters converted
+                  to lowercase and vice versa.
+                  return a titlecased copy of s, i.e. words start with
+s.title()         uppercase characters, all remaining cased characters
+                  are lowercase.
+s.translate(table return a copy of s mapped through translation table     (12)
+[,deletechars])   table.
+s.upper()         return a copy of s converted to uppercase.
+s.zfill(width)    return a string padded with zeroes on the left side and
+                  sliding a minus sign left if necessary.  never truncates.
+
+Notes :
+    (1) Padding is done using spaces.
+    (2) If optional argument start is supplied, substring s[start:] is
+processed. If optional arguments start and end are supplied, substring s[start:
+end] is processed.
+    (3) Optional argument errors may be given to set a different error handling
+scheme. The default for errors is 'strict', meaning that encoding errors raise
+a ValueError. Other possible values are 'ignore' and 'replace'.
+    (4) If optional argument tabsize is not given, a tab size of 8 characters
+is assumed.
+    (5) Returns false if string s does not contain at least one character.
+    (6) Returns false if string s does not contain at least one cased
+character.
+    (7) A titlecased string is a string in which uppercase characters may only
+follow uncased characters and lowercase characters only cased ones.
+    (8) s is returned if width is less than len(s).
+    (9) If the optional argument maxsplit is given, only the first maxsplit
+occurrences are replaced.
+    (10) If sep is not specified or None, any whitespace string is a separator.
+If maxsplit is given, at most maxsplit splits are done.
+    (11) Line breaks are not included in the resulting list unless keepends is
+given and true.
+    (12) table must be a string of length 256. All characters occurring in the
+optional argument deletechars are removed prior to translation.
+
+String formatting with the % operator
+
+formatString % args--> evaluates to a string
+
+  * formatString uses C printf format codes : %, c, s, i, d, u, o, x, X, e, E,
+    f, g, G, r (details below).
+  * Width and precision may be a * to specify that an integer argument gives
+    the actual width or precision.
+  * The flag characters -, +, blank, # and 0 are understood. (details below)
+  * %s will convert any type argument to string (uses str() function)
+  * args may be a single arg or a tuple of args
+
+        '%s has %03d quote types.' % ('Python', 2)  # => 'Python has 002 quote types.'
+
+  * Right-hand-side can also be a mapping:
+
+        a = '%(lang)s has %(c)03d quote types.' % {'c':2, 'lang':'Python}
+(vars() function very handy to use on right-hand-side.)
+
+                                 Format codes
+Conversion                               Meaning
+d          Signed integer decimal.
+i          Signed integer decimal.
+o          Unsigned octal.
+u          Unsigned decimal.
+x          Unsigned hexidecimal (lowercase).
+X          Unsigned hexidecimal (uppercase).
+e          Floating point exponential format (lowercase).
+E          Floating point exponential format (uppercase).
+f          Floating point decimal format.
+F          Floating point decimal format.
+g          Same as "e" if exponent is greater than -4 or less than precision,
+           "f" otherwise.
+G          Same as "E" if exponent is greater than -4 or less than precision,
+           "F" otherwise.
+c          Single character (accepts integer or single character string).
+r          String (converts any python object using repr()).
+s          String (converts any python object using str()).
+%          No argument is converted, results in a "%" character in the result.
+           (The complete specification is %%.)
+
+                          Conversion flag characters
+Flag                                  Meaning
+#    The value conversion will use the ``alternate form''.
+0    The conversion will be zero padded.
+-    The converted value is left adjusted (overrides "-").
+     (a space) A blank should be left before a positive number (or empty
+     string) produced by a signed conversion.
++    A sign character ("+" or "-") will precede the conversion (overrides a
+     "space" flag).
+
+File Objects
+
+Created with built-in function open; may be created by other modules' functions
+as well.
+
+Operators on file objects
+
+                                File operations
+    Operation                                Result
+f.close()         Close file f.
+f.fileno()        Get fileno (fd) for file f.
+f.flush()         Flush file f's internal buffer.
+f.isatty()        True if file f is connected to a tty-like dev, else False.
+f.read([size])    Read at most size bytes from file f and return as a string
+                  object. If size omitted, read to EOF.
+f.readline()      Read one entire line from file f.
+f.readlines()     Read until EOF with readline() and return list of lines read.
+                  Set file f's position, like "stdio's fseek()".
+f.seek(offset[,   whence == 0 then use absolute indexing.
+whence=0])        whence == 1 then offset relative to current pos.
+                  whence == 2 then offset relative to file end.
+f.tell()          Return file f's current position (byte offset).
+f.write(str)      Write string to file f.
+f.writelines(list Write list of strings to file f.
+)
+
+File Exceptions
+
+  EOFError
+     End-of-file hit when reading (may be raised many times, e.g. if f is a
+    tty).
+  IOError
+     Other I/O-related I/O operation failure.
+  OSError
+     OS system call failed.
+
+
+    Advanced Types
+
+    -See manuals for more details -
+      + Module objects
+      + Class objects
+      + Class instance objects
+      + Type objects (see module: types)
+      + File objects (see above)
+      + Slice objects
+      + XRange objects
+      + Callable types:
+          o User-defined (written in Python):
+              # User-defined Function objects
+              # User-defined Method objects
+          o Built-in (written in C):
+              # Built-in Function objects
+              # Built-in Method objects
+      + Internal Types:
+          o Code objects (byte-compile executable Python code: bytecode)
+          o Frame objects (execution frames)
+          o Traceback objects (stack trace of an exception)
+
+
+    Statements
+
+    pass            -- Null statement
+    del name[,name]* -- Unbind name(s) from object. Object will be indirectly
+                        (and automatically) deleted only if no longer referenced.
+    print [>> fileobject,] [s1 [, s2 ]* [,]
+                    -- Writes to sys.stdout, or to fileobject if supplied.
+                       Puts spaces between arguments. Puts newline at end
+                       unless statement ends with comma.
+                       Print is not required when running interactively,
+                       simply typing an expression will print its value,
+                       unless the value is None.
+    exec x [in globals [,locals]]
+                    -- Executes x in namespaces provided. Defaults
+                       to current namespaces. x can be a string, file
+                       object or a function object.
+    callable(value,... [id=value], [*args], [**kw])
+                    -- Call function callable with parameters. Parameters can
+                       be passed by name or be omitted if function
+                       defines default values. E.g. if callable is defined as
+                       "def callable(p1=1, p2=2)"
+                       "callable()"       <=>  "callable(1, 2)"
+                       "callable(10)"     <=>  "callable(10, 2)"
+                       "callable(p2=99)"  <=>  "callable(1, 99)"
+                       *args is a tuple of positional arguments.
+                       **kw is a dictionary of keyword arguments.
+
+    Assignment operators
+
+                              Caption
+    Operator                    Result                     Notes
+    a = b    Basic assignment - assign object b to label a  (1)
+    a += b   Roughly equivalent to a = a + b                (2)
+    a -= b   Roughly equivalent to a = a - b                (2)
+    a *= b   Roughly equivalent to a = a * b                (2)
+    a /= b   Roughly equivalent to a = a / b                (2)
+    a %= b   Roughly equivalent to a = a % b                (2)
+    a **= b  Roughly equivalent to a = a ** b               (2)
+    a &= b   Roughly equivalent to a = a & b                (2)
+    a |= b   Roughly equivalent to a = a | b                (2)
+    a ^= b   Roughly equivalent to a = a ^ b                (2)
+    a >>= b  Roughly equivalent to a = a >> b               (2)
+    a <<= b  Roughly equivalent to a = a << b               (2)
+
+    Notes :
+        (1) Can unpack tuples, lists, and strings.
+           first, second = a[0:2]; [f, s] = range(2); c1,c2,c3='abc'
+           Tip: x,y = y,x swaps x and y.
+        (2) Not exactly equivalent - a is evaluated only once. Also, where
+    possible, operation performed in-place - a is modified rather than
+    replaced.
+
+    Control Flow
+
+    if condition: suite
+    [elif condition: suite]*
+    [else: suite]   -- usual if/else_if/else statement
+    while condition: suite
+    [else: suite]
+                    -- usual while statement. "else" suite is executed
+                       after loop exits, unless the loop is exited with
+                       "break"
+    for element in sequence: suite
+    [else: suite]
+                    -- iterates over sequence, assigning each element to element.
+                       Use built-in range function to iterate a number of times.
+                       "else" suite executed at end unless loop exited
+                       with "break"
+    break           -- immediately exits "for" or "while" loop
+    continue        -- immediately does next iteration of "for" or "while" loop
+    return [result] -- Exits from function (or method) and returns result (use a tuple to
+                       return more than one value). If no result given, then returns None.
+    yield result    -- Freezes the execution frame of a generator and returns the result
+                       to the iterator's .next() method.  Upon the next call to next(),
+                       resumes execution at the frozen point with all of the local variables
+                       still intact.
+
+    Exception Statements
+
+    assert expr[, message]
+                    -- expr is evaluated. if false, raises exception AssertionError
+                       with message. Inhibited if __debug__ is 0.
+    try: suite1
+    [except [exception [, value]: suite2]+
+    [else: suite3]
+                    -- statements in suite1 are executed. If an exception occurs, look
+                       in "except" clauses for matching <exception>. If matches or bare
+                       "except" execute suite of that clause. If no exception happens
+                       suite in "else" clause is executed after suite1.
+                       If exception has a value, it is put in value.
+                       exception can also be tuple of exceptions, e.g.
+                       "except (KeyError, NameError), val: print val"
+    try: suite1
+    finally: suite2
+                    -- statements in suite1 are executed. If no
+                       exception, execute suite2 (even if suite1 is
+                       exited with a "return", "break" or "continue"
+                       statement). If exception did occur, executes
+                       suite2 and then immediately reraises exception.
+    raise exception [,value [, traceback]]
+                    -- raises exception with optional value
+                       value. Arg traceback specifies a traceback object to
+                       use when printing the exception's backtrace.
+    raise           -- a raise statement without arguments re-raises
+                       the last exception raised in the current function
+An exception is either a string (object) or a class instance.
+  Can create a new one simply by creating a new string:
+
+              my_exception = 'You did something wrong'
+      try:
+                   if bad:
+              raise my_exception, bad
+      except my_exception, value:
+                    print 'Oops', value
+
+Exception classes must be derived from the predefined class: Exception, e.g.:
+            class text_exception(Exception): pass
+            try:
+                if bad:
+                    raise text_exception()
+                    # This is a shorthand for the form
+                    # "raise <class>, <instance>"
+             except Exception:
+                 print 'Oops'
+                 # This will be printed because
+                 # text_exception is a subclass of Exception
+When an error message is printed for an unhandled exception which is a
+class, the class name is printed, then a colon and a space, and
+finally the instance converted to a string using the built-in function
+str().
+All built-in exception classes derives from StandardError, itself
+derived from Exception.
+
+Name Space Statements
+
+[1.51: On Mac & Windows, the case of module file names must now match the case
+as used
+  in the import statement]
+Packages (>1.5): a package is a name space which maps to a directory including
+                module(s) and the special initialization module '__init__.py'
+                (possibly empty). Packages/dirs can be nested. You address a
+                module's symbol via '[package.[package...]module.symbol's.
+import module1 [as name1] [, module2]*
+                -- imports modules. Members of module must be
+                   referred to by qualifying with [package.]module name:
+                   "import sys; print sys.argv:"
+                   "import package1.subpackage.module; package1.subpackage.module.foo()"
+                   module1 renamed as name1, if supplied.
+from module import name1 [as othername1] [, name2]*
+                -- imports names from module module in current namespace.
+                   "from sys import argv; print argv"
+                   "from package1 import module; module.foo()"
+                   "from package1.module import foo; foo()"
+                   name1 renamed as othername1, if supplied.
+from module import *
+                -- imports all names in module, except those starting with "_";
+                   *to be used sparsely, beware of name clashes* :
+                   "from sys import *; print argv"
+                   "from package.module import *; print x'
+                    NB: "from package import *" only imports the symbols defined
+                    in the package's __init__.py file, not those in the
+                    template modules!
+global name1 [, name2]*
+                -- names are from global scope (usually meaning from module)
+                   rather than local (usually meaning only in function).
+                -- E.g. in fct without "global" statements, assuming
+                   "a" is name that hasn't been used in fct or module
+                   so far:
+                   -Try to read from "a" -> NameError
+                   -Try to write to "a" -> creates "a" local to fcn
+                   -If "a" not defined in fct, but is in module, then
+                       -Try to read from "a", gets value from module
+                       -Try to write to "a", creates "a" local to fct
+                   But note "a[0]=3" starts with search for "a",
+                   will use to global "a" if no local "a".
+
+Function Definition
+
+def func_id ([param_list]): suite
+                -- Creates a function object & binds it to name func_id.
+
+    param_list ::= [id [, id]*]
+    id ::= value | id = value | *id | **id
+    [Args are passed by value.Thus only args representing a mutable object
+    can be modified (are inout parameters). Use a tuple to return more than
+    one value]
+
+Example:
+        def test (p1, p2 = 1+1, *rest, **keywords):
+            -- Parameters with "=" have default value (v is
+               evaluated when function defined).
+               If list has "*id" then id is assigned a tuple of
+               all remaining args passed to function (like C vararg)
+               If list has "**id" then id is assigned a dictionary of
+               all extra arguments passed as keywords.
+
+Class Definition
+
+class <class_id> [(<super_class1> [,<super_class2>]*)]: <suite>
+        -- Creates a class object and assigns it name <class_id>
+           <suite> may contain local "defs" of class methods and
+           assignments to class attributes.
+Example:
+       class my_class (class1, class_list[3]): ...
+                  Creates a class object inheriting from both "class1" and whatever
+                  class object "class_list[3]" evaluates to. Assigns new
+                  class object to name "my_class".
+        - First arg to class methods is always instance object, called 'self'
+          by convention.
+        - Special method __init__() is called when instance is created.
+        - Special method __del__() called when no more reference to object.
+        - Create instance by "calling" class object, possibly with arg
+          (thus instance=apply(aClassObject, args...) creates an instance!)
+        - In current implementation, can't subclass off built-in
+          classes. But can "wrap" them, see UserDict & UserList modules,
+          and see __getattr__() below.
+Example:
+        class c (c_parent):
+           def __init__(self, name): self.name = name
+           def print_name(self): print "I'm", self.name
+           def call_parent(self): c_parent.print_name(self)
+           instance = c('tom')
+           print instance.name
+           'tom'
+           instance.print_name()
+           "I'm tom"
+        Call parent's super class by accessing parent's method
+        directly and passing "self" explicitly (see "call_parent"
+        in example above).
+        Many other special methods available for implementing
+        arithmetic operators, sequence, mapping indexing, etc.
+
+Documentation Strings
+
+Modules, classes and functions may be documented by placing a string literal by
+itself as the first statement in the suite. The documentation can be retrieved
+by getting the '__doc__' attribute from the module, class or function.
+Example:
+        class C:
+            "A description of C"
+            def __init__(self):
+                "A description of the constructor"
+                # etc.
+Then c.__doc__ == "A description of C".
+Then c.__init__.__doc__ == "A description of the constructor".
+
+Others
+
+lambda [param_list]: returnedExpr
+                -- Creates an anonymous function. returnedExpr must be
+                   an expression, not a statement (e.g., not "if xx:...",
+                   "print xxx", etc.) and thus can't contain newlines.
+                   Used mostly for filter(), map(), reduce() functions, and GUI callbacks..
+List comprehensions
+result = [expression for item1 in sequence1  [if condition1]
+                        [for item2 in sequence2 ... for itemN in sequenceN]
+                      ]
+is equivalent to:
+result = []
+for item1 in sequence1:
+    for item2 in sequence2:
+    ...
+        for itemN in sequenceN:
+             if (condition1) and furthur conditions:
+                  result.append(expression)
+
+
+
+Built-In Functions
+
+                              Built-In Functions
+     Function                                 Result
+__import__(name[,   Imports module within the given context (see lib ref for
+globals[, locals[,  more details)
+fromlist]]])
+abs(x)              Return the absolute value of number x.
+apply(f, args[,     Calls func/method f with arguments args and optional
+keywords])          keywords.
+bool(x)             Returns True when the argument x is true and False otherwise.
+buffer(obj)         Creates a buffer reference to an object.
+callable(x)         Returns True if x callable, else False.
+chr(i)              Returns one-character string whose ASCII code isinteger i
+classmethod(f)      Converts a function f, into a method with the class as the
+                    first argument.  Useful for creating alternative constructors.
+cmp(x,y)            Returns negative, 0, positive if x <, ==, > to y
+coerce(x,y)         Returns a tuple of the two numeric arguments converted to a
+                    common type.
+                    Compiles string into a code object.filename is used in
+                    error message, can be any string. It isusually the file
+compile(string,     from which the code was read, or eg. '<string>'if not read
+filename, kind)     from file.kind can be 'eval' if string is a single stmt, or
+                    'single' which prints the output of expression statements
+                    thatevaluate to something else than None, or be 'exec'.
+complex(real[,      Builds a complex object (can also be done using J or j
+image])             suffix,e.g. 1+3J)
+delattr(obj, name)  deletes attribute named name of object obj <=> del obj.name
+                    If no args, returns the list of names in current
+dict([items])       Create a new dictionary from the specified item list.
+dir([object])       localsymbol table. With a module, class or class
+                    instanceobject as arg, returns list of names in its attr.
+                    dict.
+divmod(a,b)         Returns tuple of (a/b, a%b)
+enumerate(seq)      Return a iterator giving:  (0, seq[0]), (1, seq[1]), ...
+eval(s[, globals[,  Eval string s in (optional) globals, locals contexts.s must
+locals]])           have no NUL's or newlines. s can also be acode object.
+                    Example: x = 1; incr_x = eval('x + 1')
+execfile(file[,     Executes a file without creating a new module, unlike
+globals[, locals]]) import.
+file()              Synonym for open().
+filter(function,    Constructs a list from those elements of sequence for which
+sequence)           function returns true. function takes one parameter.
+float(x)            Converts a number or a string to floating point.
+getattr(object,     [<default> arg added in 1.5.2]Gets attribute called name
+name[, default]))   from object,e.g. getattr(x, 'f') <=> x.f). If not found,
+                    raisesAttributeError or returns default if specified.
+globals()           Returns a dictionary containing current global variables.
+hasattr(object,     Returns true if object has attr called name.
+name)
+hash(object)        Returns the hash value of the object (if it has one)
+help(f)             Display documentation on object f.
+hex(x)              Converts a number x to a hexadecimal string.
+id(object)          Returns a unique 'identity' integer for an object.
+input([prompt])     Prints prompt if given. Reads input and evaluates it.
+                    Converts a number or a string to a plain integer. Optional
+int(x[, base])      base paramenter specifies base from which to convert string
+                    values.
+intern(aString)     Enters aString in the table of "interned strings"
+                    andreturns the string. Interned strings are 'immortals'.
+isinstance(obj,     returns true if obj is an instance of class. Ifissubclass
+class)              (A,B) then isinstance(x,A) => isinstance(x,B)
+issubclass(class1,  returns true if class1 is derived from class2
+class2)
+                    Returns the length (the number of items) of an object
+iter(collection)    Returns an iterator over the collection.
+len(obj)            (sequence, dictionary, or instance of class implementing
+                    __len__).
+list(sequence)      Converts sequence into a list. If already a list,returns a
+                    copy of it.
+locals()            Returns a dictionary containing current local variables.
+                    Converts a number or a string to a long integer. Optional
+long(x[, base])     base paramenter specifies base from which to convert string
+                    values.
+                    Applies function to every item of list and returns a listof
+map(function, list, the results. If additional arguments are passed,function
+...)                must take that many arguments and it is givento function on
+                    each call.
+max(seq)            Returns the largest item of the non-empty sequence seq.
+min(seq)            Returns the smallest item of a non-empty sequence seq.
+oct(x)              Converts a number to an octal string.
+open(filename [,    Returns a new file object. First two args are same asthose
+mode='r', [bufsize= for C's "stdio open" function. bufsize is 0for unbuffered,
+implementation      1 for line-buffered, negative forsys-default, all else, of
+dependent]])        (about) given size.
+ord(c)              Returns integer ASCII value of c (a string of len 1). Works
+                    with Unicode char.
+object()            Create a base type.  Used as a superclass for new-style objects.
+open(name           Open a file.
+  [, mode
+  [, buffering]])
+pow(x, y [, z])     Returns x to power y [modulo z]. See also ** operator.
+property()          Created a property with access controlled by functions.
+range(start [,end   Returns list of ints from >= start and < end.With 1 arg,
+[, step]])          list from 0..arg-1With 2 args, list from start..end-1With 3
+                    args, list from start up to end by step
+raw_input([prompt]) Prints prompt if given, then reads string from stdinput (no
+                    trailing \n). See also input().
+reduce(f, list [,   Applies the binary function f to the items oflist so as to
+init])              reduce the list to a single value.If init given, it is
+                    "prepended" to list.
+                    Re-parses and re-initializes an already imported module.
+                    Useful in interactive mode, if you want to reload amodule
+reload(module)      after fixing it. If module was syntacticallycorrect but had
+                    an error in initialization, mustimport it one more time
+                    before calling reload().
+                    Returns a string containing a printable and if possible
+repr(object)        evaluable representation of an object. <=> `object`
+                    (usingbackquotes). Class redefinissable (__repr__). See
+                    also str()
+round(x, n=0)       Returns the floating point value x rounded to n digitsafter
+                    the decimal point.
+setattr(object,     This is the counterpart of getattr().setattr(o, 'foobar',
+name, value)        3) <=> o.foobar = 3Creates attribute if it doesn't exist!
+slice([start,] stop Returns a slice object representing a range, with R/
+[, step])           Oattributes: start, stop, step.
+                    Returns a string containing a nicely
+staticmethod()      Convert a function to method with no self or class
+                    argument.  Useful for methods associated with a class that
+                    do not need access to an object's internal state.
+str(object)         printablerepresentation of an object. Class overridable
+                    (__str__).See also repr().
+super(type)         Create an unbound super object.  Used to call cooperative
+                    superclass methods.
+sum(sequence,       Add the values in the sequence and return the sum.
+    [start]) 
+tuple(sequence)     Creates a tuple with same elements as sequence. If already
+                    a tuple, return itself (not a copy).
+                    Returns a type object [see module types] representing
+                    thetype of obj. Example: import typesif type(x) ==
+type(obj)           types.StringType: print 'It is a string'NB: it is
+                    recommanded to use the following form:if isinstance(x,
+                    types.StringType): etc...
+unichr(code)        code.
+unicode(string[,    Creates a Unicode string from a 8-bit string, using
+encoding[, error    thegiven encoding name and error treatment ('strict',
+]]])                'ignore',or 'replace'}.
+                    Without arguments, returns a dictionary correspondingto the
+                    current local symbol table. With a module,class or class
+vars([object])      instance object as argumentreturns a dictionary
+                    corresponding to the object'ssymbol table. Useful with "%"
+                    formatting operator.
+xrange(start [, end Like range(), but doesn't actually store entire listall at
+[, step]])          once. Good to use in "for" loops when there is abig range
+                    and little memory.
+zip(seq1[, seq2,    Returns a list of tuples where each tuple contains the nth
+...])               element of each of the argument sequences.
+
+
+
+
+Built-In Exceptions
+
+Exception>
+         Root class for all exceptions
+    SystemExit
+         On 'sys.exit()'
+    StopIteration
+         Signal the end from iterator.next()
+    StandardError
+                 Base class for all built-in exceptions; derived from Exception
+    root class.
+        ArithmeticError
+                 Base class for OverflowError, ZeroDivisionError,
+    FloatingPointError
+            FloatingPointError
+                       When a floating point operation fails.
+            OverflowError
+                            On excessively large arithmetic operation
+            ZeroDivisionError
+                  On division or modulo operation with 0 as 2nd arg
+            AssertionError
+                When an assert statement fails.
+        AttributeError
+                    On attribute reference or assignment failure
+        EnvironmentError    [new in 1.5.2]
+                On error outside Python; error arg tuple is (errno, errMsg...)
+            IOError    [changed in 1.5.2]
+               I/O-related operation failure
+            OSError    [new in 1.5.2]
+               used by the os module's os.error exception.
+        EOFError
+                    Immediate end-of-file hit by input() or raw_input()
+        ImportError
+         On failure of `import' to find module or name
+        KeyboardInterrupt
+         On user entry of the interrupt key (often `Control-C')
+        LookupError
+                base class for IndexError, KeyError
+            IndexError
+                 On out-of-range sequence subscript
+            KeyError
+                 On reference to a non-existent mapping (dict) key
+        MemoryError
+         On recoverable memory exhaustion
+        NameError
+         On failure to find a local or global (unqualified) name
+        RuntimeError
+         Obsolete catch-all; define a suitable error instead
+          NotImplementedError   [new in 1.5.2]
+                On method not implemented
+        SyntaxError
+         On parser encountering a syntax error
+       IndentationError
+           On parser encountering an indentation syntax error
+       TabError
+           On parser encountering an indentation syntax error
+        SystemError
+         On non-fatal interpreter error - bug - report it
+        TypeError
+         On passing inappropriate type to built-in op or func
+        ValueError
+         On arg error not covered by TypeError or more precise
+    Warning
+              UserWarning
+              DeprecationWarning
+              PendingDeprecationWarning
+              SyntaxWarning
+              RuntimeWarning
+              FutureWarning
+
+
+
+Standard methods & operators redefinition in classes
+
+Standard methods & operators map to special '__methods__' and thus may be
+ redefined (mostly in in user-defined classes), e.g.:
+    class x:
+         def __init__(self, v): self.value = v
+         def __add__(self, r): return self.value + r
+    a = x(3) # sort of like calling x.__init__(a, 3)
+    a + 4    # is equivalent to a.__add__(4)
+
+Special methods for any class
+
+(s: self, o: other)
+        __init__(s, args) instance initialization (on construction)
+        __del__(s)        called on object demise (refcount becomes 0)
+        __repr__(s)       repr() and `...` conversions
+        __str__(s)        str() and 'print' statement
+        __cmp__(s, o)     Compares s to o and returns <0, 0, or >0.
+                          Implements >, <, == etc...
+        __hash__(s)       Compute a 32 bit hash code; hash() and dictionary ops
+        __nonzero__(s)    Returns False or True for truth value testing
+        __getattr__(s, name)  called when attr lookup doesn't find <name>
+        __setattr__(s, name, val) called when setting an attr
+                                  (inside, don't use "self.name = value"
+                                   use "self.__dict__[name] = val")
+        __delattr__(s, name)  called to delete attr <name>
+        __call__(self, *args) called when an instance is called as function.
+
+Operators
+
+    See list in the operator module. Operator function names are provided with
+    2 variants, with or without
+    ading & trailing '__' (eg. __add__ or add).
+
+    Numeric operations special methods
+    (s: self, o: other)
+
+        s+o       =  __add__(s,o)         s-o        =  __sub__(s,o)
+        s*o       =  __mul__(s,o)         s/o        =  __div__(s,o)
+        s%o       =  __mod__(s,o)         divmod(s,o) = __divmod__(s,o)
+        s**o      =  __pow__(s,o)
+        s&o       =  __and__(s,o)
+        s^o       =  __xor__(s,o)         s|o        =  __or__(s,o)
+        s<<o      =  __lshift__(s,o)      s>>o       =  __rshift__(s,o)
+        nonzero(s) = __nonzero__(s) (used in boolean testing)
+        -s        =  __neg__(s)           +s         =  __pos__(s)
+        abs(s)    =  __abs__(s)           ~s         =  __invert__(s)  (bitwise)
+        s+=o      =  __iadd__(s,o)        s-=o       =  __isub__(s,o)
+        s*=o      =  __imul__(s,o)        s/=o       =  __idiv__(s,o)
+        s%=o      =  __imod__(s,o)
+        s**=o     =  __ipow__(s,o)
+        s&=o      =  __iand__(s,o)
+        s^=o      =  __ixor__(s,o)        s|=o       =  __ior__(s,o)
+        s<<=o     =  __ilshift__(s,o)     s>>=o      =  __irshift__(s,o)
+        Conversions
+        int(s)    =  __int__(s)           long(s)    =  __long__(s)
+        float(s)  =  __float__(s)         complex(s)    =  __complex__(s)
+        oct(s)    =  __oct__(s)           hex(s)     =  __hex__(s)
+        coerce(s,o) = __coerce__(s,o)
+        Right-hand-side equivalents for all binary operators exist;
+        are called when class instance is on r-h-s of operator:
+        a + 3  calls __add__(a, 3)
+        3 + a  calls __radd__(a, 3)
+
+    All seqs and maps, general operations plus:
+    (s: self, i: index or key)
+
+        len(s)    = __len__(s)        length of object, >= 0.  Length 0 == false
+        s[i]      = __getitem__(s,i)  Element at index/key i, origin 0
+
+    Sequences, general methods, plus:
+      s[i]=v           = __setitem__(s,i,v)
+      del s[i]         = __delitem__(s,i)
+      s[i:j]           = __getslice__(s,i,j)
+      s[i:j]=seq       = __setslice__(s,i,j,seq)
+      del s[i:j]       = __delslice__(s,i,j)   == s[i:j] = []
+      seq * n          = __repeat__(seq, n)
+      s1 + s2          = __concat__(s1, s2)
+      i in s           = __contains__(s, i)
+    Mappings, general methods, plus
+      hash(s)          = __hash__(s) - hash value for dictionary references
+      s[k]=v           = __setitem__(s,k,v)
+      del s[k]         = __delitem__(s,k)
+
+Special informative state attributes for some types:
+
+    Modules:
+        __doc__ (string/None, R/O): doc string (<=> __dict__['__doc__'])
+        __name__(string, R/O): module name (also in __dict__['__name__'])
+        __dict__ (dict, R/O): module's name space
+        __file__(string/undefined, R/O): pathname of .pyc, .pyo or .pyd (undef for
+                 modules statically linked to the interpreter)
+
+    Classes:    [in bold: writable since 1.5.2]
+        __doc__ (string/None, R/W): doc string (<=> __dict__['__doc__'])
+        __module__ is the module name in which the class was defined
+        __name__(string, R/W): class name (also in __dict__['__name__'])
+        __bases__ (tuple, R/W): parent classes
+        __dict__ (dict, R/W): attributes (class name space)
+
+    Instances:
+        __class__ (class, R/W): instance's class
+        __dict__ (dict, R/W): attributes
+
+    User-defined functions: [bold: writable since 1.5.2]
+        __doc__ (string/None, R/W): doc string
+        __name__(string, R/O): function name
+        func_doc (R/W): same as __doc__
+        func_name (R/O): same as __name__
+        func_defaults (tuple/None, R/W): default args values if any
+        func_code (code, R/W): code object representing the compiled function body
+        func_globals (dict, R/O): ref to dictionary of func global variables
+        func_dict (dict, R/W):  same as __dict__ contains the namespace supporting
+            arbitrary function attributes
+        func_closure (R/O): None or a tuple of cells that contain bindings
+            for the function's free variables.
+
+
+    User-defined Methods:
+        __doc__ (string/None, R/O): doc string
+        __name__(string, R/O): method name (same as im_func.__name__)
+        im_class (class, R/O): class defining the method (may be a base class)
+        im_self (instance/None, R/O): target instance object (None if unbound)
+        im_func (function, R/O): function object
+
+    Built-in Functions & methods:
+        __doc__ (string/None, R/O): doc string
+        __name__ (string, R/O): function name
+        __self__ : [methods only] target object
+
+    Codes:
+        co_name (string, R/O): function name
+        co_argcount (int, R/0): number of positional args
+        co_nlocals (int, R/O): number of local vars (including args)
+        co_varnames (tuple, R/O): names of local vars (starting with args)
+        co_cellvars (tuple, R/O)) the names of local variables referenced by
+            nested functions
+        co_freevars (tuple, R/O)) names of free variables
+        co_code (string, R/O): sequence of bytecode instructions
+        co_consts (tuple, R/O): litterals used by the bytecode, 1st one is
+                                fct doc (or None)
+        co_names (tuple, R/O): names used by the bytecode
+        co_filename (string, R/O): filename from which the code was compiled
+        co_firstlineno (int, R/O): first line number of the function
+        co_lnotab (string, R/O): string encoding bytecode offsets to line numbers.
+        co_stacksize (int, R/O): required stack size (including local vars)
+        co_flags (int, R/O): flags for the interpreter
+                           bit 2 set if fct uses "*arg" syntax
+                           bit 3 set if fct uses '**keywords' syntax
+    Frames:
+        f_back (frame/None, R/O): previous stack frame (toward the caller)
+        f_code (code, R/O): code object being executed in this frame
+        f_locals (dict, R/O): local vars
+        f_globals (dict, R/O): global vars
+        f_builtins (dict, R/O): built-in (intrinsic) names
+        f_restricted (int, R/O): flag indicating whether fct is executed in
+                                 restricted mode
+        f_lineno (int, R/O): current line number
+        f_lasti (int, R/O): precise instruction (index into bytecode)
+        f_trace (function/None, R/W): debug hook called at start of each source line
+        f_exc_type (Type/None, R/W): Most recent exception type
+        f_exc_value (any, R/W): Most recent exception value
+        f_exc_traceback (traceback/None, R/W): Most recent exception traceback
+    Tracebacks:
+        tb_next (frame/None, R/O): next level in stack trace (toward the frame where
+                                  the exception occurred)
+        tb_frame (frame, R/O): execution frame of the current level
+        tb_lineno (int, R/O): line number where the exception occurred
+        tb_lasti (int, R/O): precise instruction (index into bytecode)
+
+    Slices:
+        start (any/None, R/O): lowerbound
+        stop (any/None, R/O): upperbound
+        step (any/None, R/O): step value
+
+    Complex numbers:
+        real (float, R/O): real part
+        imag (float, R/O): imaginary part
+
+
+Important Modules
+
+                                      sys
+
+                              Some sys variables
+      Variable                                Content
+argv                 The list of command line arguments passed to aPython
+                     script. sys.argv[0] is the script name.
+builtin_module_names A list of strings giving the names of all moduleswritten
+                     in C that are linked into this interpreter.
+check_interval       How often to check for thread switches or signals(measured
+                     in number of virtual machine instructions)
+exc_type, exc_value, Deprecated since release 1.5. Use exc_info() instead.
+exc_traceback
+exitfunc             User can set to a parameterless fcn. It will getcalled
+                     before interpreter exits.
+last_type,           Set only when an exception not handled andinterpreter
+last_value,          prints an error. Used by debuggers.
+last_traceback
+maxint               maximum positive value for integers
+modules              Dictionary of modules that have already been loaded.
+path                 Search path for external modules. Can be modifiedby
+                     program. sys.path[0] == dir of script executing
+platform             The current platform, e.g. "sunos5", "win32"
+ps1, ps2             prompts to use in interactive mode.
+                     File objects used for I/O. One can redirect byassigning a
+stdin, stdout,       new file object to them (or any object:.with a method
+stderr               write(string) for stdout/stderr,.with a method readline()
+                     for stdin)
+version              string containing version info about Python interpreter.
+                     (and also: copyright, dllhandle, exec_prefix, prefix)
+version_info         tuple containing Python version info - (major, minor,
+                     micro, level, serial).
+
+                              Some sys functions
+     Function                                 Result
+exit(n)            Exits with status n. Raises SystemExit exception.(Hence can
+                   be caught and ignored by program)
+getrefcount(object Returns the reference count of the object. Generally one
+)                  higher than you might expect, because of object arg temp
+                   reference.
+setcheckinterval(  Sets the interpreter's thread switching interval (in number
+interval)          of virtual code instructions, default:100).
+settrace(func)     Sets a trace function: called before each line ofcode is
+                   exited.
+setprofile(func)   Sets a profile function for performance profiling.
+                   Info on exception currently being handled; this is atuple
+                   (exc_type, exc_value, exc_traceback).Warning: assigning the
+exc_info()         traceback return value to a loca variable in a
+                   function handling an exception will cause a circular
+                   reference.
+setdefaultencoding Change default Unicode encoding - defaults to 7-bit ASCII.
+(encoding)
+getrecursionlimit  Retrieve maximum recursion depth.
+()
+setrecursionlimit  Set maximum recursion depth. (Defaults to 1000.)
+()
+
+
+
+                                      os
+"synonym" for whatever O/S-specific module is proper for current environment.
+this module uses posix whenever possible.
+(see also M.A. Lemburg's utility http://www.lemburg.com/files/python/
+platform.py)
+
+                               Some os variables
+     Variable                                 Meaning
+name                name of O/S-specific module (e.g. "posix", "mac", "nt")
+path                O/S-specific module for path manipulations.
+                    On Unix, os.path.split() <=> posixpath.split()
+curdir              string used to represent current directory ('.')
+pardir              string used to represent parent directory ('..')
+sep                 string used to separate directories ('/' or '\'). Tip: use
+                    os.path.join() to build portable paths.
+altsep              Alternate sep
+if applicable (None
+otherwise)
+pathsep             character used to separate search path components (as in
+                    $PATH), eg. ';' for windows.
+linesep             line separator as used in binary files, ie '\n' on Unix, '\
+                    r\n' on Dos/Win, '\r'
+
+                               Some os functions
+     Function                                 Result
+makedirs(path[,     Recursive directory creation (create required intermediary
+mode=0777])         dirs); os.error if fails.
+removedirs(path)    Recursive directory delete (delete intermediary empty
+                    dirs); if fails.
+renames(old, new)   Recursive directory or file renaming; os.error if fails.
+
+
+
+                                     posix
+don't import this module directly, import os instead !
+(see also module: shutil for file copy & remove fcts)
+
+                            posix Variables
+Variable                             Meaning
+environ  dictionary of environment variables, e.g.posix.environ['HOME'].
+error    exception raised on POSIX-related error.
+         Corresponding value is tuple of errno code and perror() string.
+
+                             Some posix functions
+   Function                                 Result
+chdir(path)     Changes current directory to path.
+chmod(path,     Changes the mode of path to the numeric mode
+mode)
+close(fd)       Closes file descriptor fd opened with posix.open.
+_exit(n)        Immediate exit, with no cleanups, no SystemExit,etc. Should use
+                this to exit a child process.
+execv(p, args)  "Become" executable p with args args
+getcwd()        Returns a string representing the current working directory
+getpid()        Returns the current process id
+fork()          Like C's fork(). Returns 0 to child, child pid to parent.[Not
+                on Windows]
+kill(pid,       Like C's kill [Not on Windows]
+signal)
+listdir(path)   Lists (base)names of entries in directory path, excluding '.'
+                and '..'
+lseek(fd, pos,  Sets current position in file fd to position pos, expressedas
+how)            an offset relative to beginning of file (how=0), tocurrent
+                position (how=1), or to end of file (how=2)
+mkdir(path[,    Creates a directory named path with numeric mode (default 0777)
+mode])
+open(file,      Like C's open(). Returns file descriptor. Use file object
+flags, mode)    fctsrather than this low level ones.
+pipe()          Creates a pipe. Returns pair of file descriptors (r, w) [Not on
+                Windows].
+popen(command,  Opens a pipe to or from command. Result is a file object to
+mode='r',       read to orwrite from, as indicated by mode being 'r' or 'w'.
+bufSize=0)      Use it to catch acommand output ('r' mode) or to feed it ('w'
+                mode).
+remove(path)    See unlink.
+rename(src, dst Renames/moves the file or directory src to dst. [error iftarget
+)               name already exists]
+rmdir(path)     Removes the empty directory path
+read(fd, n)     Reads n bytes from file descriptor fd and return as string.
+                Returns st_mode, st_ino, st_dev, st_nlink, st_uid,st_gid,
+stat(path)      st_size, st_atime, st_mtime, st_ctime.[st_ino, st_uid, st_gid
+                are dummy on Windows]
+system(command) Executes string command in a subshell. Returns exitstatus of
+                subshell (usually 0 means OK).
+                Returns accumulated CPU times in sec (user, system, children's
+times()         user,children's sys, elapsed real time). [3 last not on
+                Windows]
+unlink(path)    Unlinks ("deletes") the file (not dir!) path. same as: remove
+utime(path, (   Sets the access & modified time of the file to the given tuple
+aTime, mTime))  of values.
+wait()          Waits for child process completion. Returns tuple ofpid,
+                exit_status [Not on Windows]
+waitpid(pid,    Waits for process pid to complete. Returns tuple ofpid,
+options)        exit_status [Not on Windows]
+write(fd, str)  Writes str to file fd. Returns nb of bytes written.
+
+
+
+                                   posixpath
+Do not import this module directly, import os instead and refer to this module
+as os.path. (e.g. os.path.exists(p)) !
+
+                           Some posixpath functions
+ Function                                 Result
+abspath(p) Returns absolute path for path p, taking current working dir in
+           account.
+dirname/
+basename(p directory and name parts of the path p. See also split.
+)
+exists(p)  True if string p is an existing path (file or directory)
+expanduser Returns string that is (a copy of) p with "~" expansion done.
+(p)
+expandvars Returns string that is (a copy of) p with environment vars expanded.
+(p)        [Windows: case significant; must use Unix: $var notation, not %var%]
+getsize(   return the size in bytes of filename. raise os.error.
+filename)
+getmtime(  return last modification time of filename (integer nb of seconds
+filename)  since epoch).
+getatime(  return last access time of filename (integer nb of seconds since
+filename)  epoch).
+isabs(p)   True if string p is an absolute path.
+isdir(p)   True if string p is a directory.
+islink(p)  True if string p is a symbolic link.
+ismount(p) True if string p is a mount point [true for all dirs on Windows].
+join(p[,q  Joins one or more path components intelligently.
+[,...]])
+           Splits p into (head, tail) where tail is lastpathname component and
+split(p)   <head> is everything leadingup to that. <=> (dirname(p), basename
+           (p))
+splitdrive Splits path p in a pair ('drive:', tail) [Windows]
+(p)
+splitext(p Splits into (root, ext) where last comp of root contains no periods
+)          and ext is empty or startswith a period.
+           Calls the function visit with arguments(arg, dirname, names) for
+           each directory recursively inthe directory tree rooted at p
+walk(p,    (including p itself if it's a dir)The argument dirname specifies the
+visit, arg visited directory, the argumentnames lists the files in the
+)          directory. The visit function maymodify names to influence the set
+           of directories visited belowdirname, e.g., to avoid visiting certain
+           parts of the tree.
+
+
+
+                                    shutil
+high-level file operations (copying, deleting).
+
+                             Main shutil functions
+     Function                                 Result
+copy(src, dst)     Copies the contents of file src to file dst, retaining file
+                   permissions.
+copytree(src, dst  Recursively copies an entire directory tree rooted at src
+[, symlinks])      into dst (which should not already exist). If symlinks is
+                   true, links insrc are kept as such in dst.
+rmtree(path[,      Deletes an entire directory tree, ignoring errors if
+ignore_errors[,    ignore_errors true,or calling onerror(func, path,
+onerror]])         sys.exc_info()) if supplied with
+
+(and also: copyfile, copymode, copystat, copy2)
+
+time
+
+                                  Variables
+Variable                               Meaning
+altzone  signed offset of local DST timezone in sec west of the 0th meridian.
+daylight nonzero if a DST timezone is specified
+
+                                   Functions
+  Function                                 Result
+time()        return a float representing UTC time in seconds since the epoch.
+gmtime(secs), return a tuple representing time : (year aaaa, month(1-12),day
+localtime(    (1-31), hour(0-23), minute(0-59), second(0-59), weekday(0-6, 0 is
+secs)         monday), Julian day(1-366), daylight flag(-1,0 or 1))
+asctime(
+timeTuple),
+strftime(
+format,       return a formated string representing time.
+timeTuple)
+mktime(tuple) inverse of localtime(). Return a float.
+strptime(     parse a formated string representing time, return tuple as in
+string[,      gmtime().
+format])
+sleep(secs)   Suspend execution for <secs> seconds. <secs> can be a float.
+
+and also: clock, ctime.
+
+                                    string
+
+As of Python 2.0, much (though not all) of the functionality provided by the
+string module have been superseded by built-in string methods - see Operations
+on strings for details.
+
+                             Some string variables
+              Variable                                Meaning
+digits                               The string '0123456789'
+hexdigits, octdigits                 legal hexadecimal & octal digits
+letters, uppercase, lowercase,       Strings containing the appropriate
+whitespace                           characters
+index_error                          Exception raised by index() if substr not
+                                     found.
+
+                             Some string functions
+     Function                                 Result
+expandtabs(s,      returns a copy of string <s> with tabs expanded.
+tabSize)
+find/rfind(s, sub  Return the lowest/highest index in <s> where the substring
+[, start=0[, end=  <sub> is found such that <sub> is wholly contained ins
+0])                [start:end]. Return -1 if <sub> not found.
+ljust/rjust/center Return a copy of string <s> left/right justified/centerd in
+(s, width)         afield of given width, padded with spaces. <s> is
+                   nevertruncated.
+lower/upper(s)     Return a string that is (a copy of) <s> in lowercase/
+                   uppercase
+split(s[, sep=     Return a list containing the words of the string <s>,using
+whitespace[,       the string <sep> as a separator.
+maxsplit=0]])
+join(words[, sep=' Concatenate a list or tuple of words with
+'])                interveningseparators; inverse of split.
+replace(s, old,    Returns a copy of string <s> with all occurrences of
+new[, maxsplit=0]  substring<old> replaced by <new>. Limits to <maxsplit>
+                   firstsubstitutions if specified.
+strip(s)           Return a string that is (a copy of) <s> without leadingand
+                   trailing whitespace. see also lstrip, rstrip.
+
+
+
+                                   re (sre)
+
+Handles Unicode strings. Implemented in new module sre, re now a mere front-end
+for compatibility.
+Patterns are specified as strings. Tip: Use raw strings (e.g. r'\w*') to
+litteralize backslashes.
+
+
+                           Regular expression syntax
+   Form                                Description
+.          matches any character (including newline if DOTALL flag specified)
+^          matches start of the string (of every line in MULTILINE mode)
+$          matches end of the string (of every line in MULTILINE mode)
+*          0 or more of preceding regular expression (as many as possible)
++          1 or more of preceding regular expression (as many as possible)
+?          0 or 1 occurrence of preceding regular expression
+*?, +?, ?? Same as *, + and ? but matches as few characters as possible
+{m,n}      matches from m to n repetitions of preceding RE
+{m,n}?     idem, attempting to match as few repetitions as possible
+[ ]        defines character set: e.g. '[a-zA-Z]' to match all letters(see also
+           \w \S)
+[^ ]       defines complemented character set: matches if char is NOT in set
+           escapes special chars '*?+&$|()' and introduces special sequences
+\          (see below). Due to Python string rules, write as '\\' orr'\' in the
+           pattern string.
+\\         matches a litteral '\'; due to Python string rules, write as '\\\\
+           'in pattern string, or better using raw string: r'\\'.
+|          specifies alternative: 'foo|bar' matches 'foo' or 'bar'
+(...)      matches any RE inside (), and delimits a group.
+(?:...)    idem but doesn't delimit a group.
+           matches if ... matches next, but doesn't consume any of the string
+(?=...)    e.g. 'Isaac (?=Asimov)' matches 'Isaac' only if followed by
+           'Asimov'.
+(?!...)    matches if ... doesn't match next. Negative of (?=...)
+(?P<name   matches any RE inside (), and delimits a named group. (e.g. r'(?P
+>...)      <id>[a-zA-Z_]\w*)' defines a group named id)
+(?P=name)  matches whatever text was matched by the earlier group named name.
+(?#...)    A comment; ignored.
+(?letter)  letter is one of 'i','L', 'm', 's', 'x'. Set the corresponding flags
+           (re.I, re.L, re.M, re.S, re.X) for the entire RE.
+
+                               Special sequences
+Sequence                              Description
+number   matches content of the group of the same number; groups are numbered
+         starting from 1
+\A       matches only at the start of the string
+\b       empty str at beg or end of word: '\bis\b' matches 'is', but not 'his'
+\B       empty str NOT at beginning or end of word
+\d       any decimal digit (<=> [0-9])
+\D       any non-decimal digit char (<=> [^O-9])
+\s       any whitespace char (<=> [ \t\n\r\f\v])
+\S       any non-whitespace char (<=> [^ \t\n\r\f\v])
+\w       any alphaNumeric char (depends on LOCALE flag)
+\W       any non-alphaNumeric char (depends on LOCALE flag)
+\Z       matches only at the end of the string
+
+                         Variables
+Variable                       Meaning
+error    Exception when pattern string isn't a valid regexp.
+
+                                   Functions
+   Function                                 Result
+               Compile a RE pattern string into a regular expression object.
+               Flags (combinable by |):
+
+               I or IGNORECASE or (?i)
+                   case insensitive matching
+compile(       L or LOCALE or (?L)
+pattern[,          make \w, \W, \b, \B dependent on thecurrent locale
+flags=0])      M or MULTILINE or (?m)
+                   matches every new line and not onlystart/end of the whole
+                   string
+               S or DOTALL or (?s)
+                   '.' matches ALL chars, including newline
+               X or VERBOSE or (?x)
+                   Ignores whitespace outside character sets
+escape(string) return (a copy of) string with all non-alphanumerics
+               backslashed.
+match(pattern, if 0 or more chars at beginning of <string> match the RE pattern
+string[, flags string,return a corresponding MatchObject instance, or None if
+])             no match.
+search(pattern scan thru <string> for a location matching <pattern>, return
+, string[,     acorresponding MatchObject instance, or None if no match.
+flags])
+split(pattern, split <string> by occurrences of <pattern>. If capturing () are
+string[,       used inpattern, then occurrences of patterns or subpatterns are
+maxsplit=0])   also returned.
+findall(       return a list of non-overlapping matches in <pattern>, either a
+pattern,       list ofgroups or a list of tuples if the pattern has more than 1
+string)        group.
+               return string obtained by replacing the (<count> first) lefmost
+sub(pattern,   non-overlapping occurrences of <pattern> (a string or a RE
+repl, string[, object) in <string>by <repl>; <repl> can be a string or a fct
+count=0])      called with a single MatchObj arg, which must return the
+               replacement string.
+subn(pattern,
+repl, string[, same as sub(), but returns a tuple (newString, numberOfSubsMade)
+count=0])
+
+Regular Expression Objects
+
+
+(RE objects are returned by the compile fct)
+
+                          re object attributes
+Attribute                            Descrition
+flags      flags arg used when RE obj was compiled, or 0 if none provided
+groupindex dictionary of {group name: group number} in pattern
+pattern    pattern string from which RE obj was compiled
+
+                               re object methods
+  Method                                  Result
+            If zero or more characters at the beginning of string match this
+            regular expression, return a corresponding MatchObject instance.
+            Return None if the string does not match the pattern; note that
+            this is different from a zero-length match.
+            The optional second parameter pos gives an index in the string
+match(      where the search is to start; it defaults to 0. This is not
+string[,    completely equivalent to slicing the string; the '' pattern
+pos][,      character matches at the real beginning of the string and at
+endpos])    positions just after a newline, but not necessarily at the index
+            where the search is to start.
+            The optional parameter endpos limits how far the string will be
+            searched; it will be as if the string is endpos characters long, so
+            only the characters from pos to endpos will be searched for a
+            match.
+            Scan through string looking for a location where this regular
+search(     expression produces a match, and return a corresponding MatchObject
+string[,    instance. Return None if no position in the string matches the
+pos][,      pattern; note that this is different from finding a zero-length
+endpos])    match at some point in the string.
+            The optional pos and endpos parameters have the same meaning as for
+            the match() method.
+split(
+string[,    Identical to the split() function, using the compiled pattern.
+maxsplit=
+0])
+findall(    Identical to the findall() function, using the compiled pattern.
+string)
+sub(repl,
+string[,    Identical to the sub() function, using the compiled pattern.
+count=0])
+subn(repl,
+string[,    Identical to the subn() function, using the compiled pattern.
+count=0])
+
+Match Objects
+
+
+(Match objects are returned by the match & search functions)
+
+                            Match object attributes
+Attribute                              Description
+pos       value of pos passed to search or match functions; index intostring at
+          which RE engine started search.
+endpos    value of endpos passed to search or match functions; index intostring
+          beyond which RE engine won't go.
+re        RE object whose match or search fct produced this MatchObj instance
+string    string passed to match() or search()
+
+                            Match object functions
+Function                                 Result
+          returns one or more groups of the match. If one arg, result is a
+group([g1 string;if multiple args, result is a tuple with one item per arg. If
+, g2,     gi is 0,return value is entire matching string; if 1 <= gi <= 99,
+...])     returnstring matching group #gi (or None if no such group); gi may
+          also bea group name.
+          returns a tuple of all groups of the match; groups not
+groups()  participatingto the match have a value of None. Returns a string
+          instead of tupleif len(tuple)=1
+start(
+group),   returns indices of start & end of substring matched by group (or
+end(group Noneif group exists but doesn't contribute to the match)
+)
+span(     returns the 2-tuple (start(group), end(group)); can be (None, None)if
+group)    group didn't contibute to the match.
+
+
+
+                                     math
+
+Variables:
+pi
+e
+Functions (see ordinary C man pages for info):
+acos(x)
+asin(x)
+atan(x)
+atan2(x, y)
+ceil(x)
+cos(x)
+cosh(x)
+degrees(x)
+exp(x)
+fabs(x)
+floor(x)
+fmod(x, y)
+frexp(x)        -- Unlike C: (float, int) = frexp(float)
+ldexp(x, y)
+log(x [,base])
+log10(x)
+modf(x)         -- Unlike C: (float, float) = modf(float)
+pow(x, y)
+radians(x)
+sin(x)
+sinh(x)
+sqrt(x)
+tan(x)
+tanh(x)
+
+                                    getopt
+
+Functions:
+getopt(list, optstr)    -- Similar to C. <optstr> is option
+                           letters to look for. Put ':' after letter
+                           if option takes arg. E.g.
+    # invocation was "python test.py -c hi -a arg1 arg2"
+       opts, args =  getopt.getopt(sys.argv[1:], 'ab:c:')
+    # opts would be
+       [('-c', 'hi'), ('-a', '')]
+    # args would be
+       ['arg1', 'arg2']
+
+
+List of modules and packages in base distribution
+
+(built-ins and content of python Lib directory)
+(Python NT distribution, may be slightly different in other distributions)
+
+                           Standard library modules
+   Operation                                 Result
+aifc             Stuff to parse AIFF-C and AIFF files.
+anydbm           Generic interface to all dbm clones. (dbhash, gdbm,
+                 dbm,dumbdbm)
+asynchat         Support for 'chat' style protocols
+asyncore         Asynchronous File I/O (in select style)
+atexit           Register functions to be called at exit of Python interpreter.
+audiodev         Audio support for a few platforms.
+base64           Conversions to/from base64 RFC-MIME transport encoding .
+BaseHTTPServer   Base class forhttp services.
+Bastion          "Bastionification" utility (control access to instance vars)
+bdb              A generic Python debugger base class.
+binhex           Macintosh binhex compression/decompression.
+bisect           List bisection algorithms.
+bz2              Support for bz2 compression/decompression.
+calendar         Calendar printing functions.
+cgi              Wraps the WWW Forms Common Gateway Interface (CGI).
+cgitb            Utility for handling CGI tracebacks.
+CGIHTTPServer    CGI http services.
+cmd              A generic class to build line-oriented command interpreters.
+datetime         Basic date and time types.
+code             Utilities needed to emulate Python's interactive interpreter
+codecs           Lookup existing Unicode encodings and register new ones.
+colorsys         Conversion functions between RGB and other color systems.
+commands         Tools for executing UNIX commands .
+compileall       Force "compilation" of all .py files in a directory.
+ConfigParser     Configuration file parser (much like windows .ini files)
+copy             Generic shallow and deep copying operations.
+copy_reg         Helper to provide extensibility for pickle/cPickle.
+csv              Read and write files with comma separated values.
+dbhash           (g)dbm-compatible interface to bsdhash.hashopen.
+dircache         Sorted list of files in a dir, using a cache.
+[DEL:dircmp:DEL] [DEL:Defines a class to build directory diff tools on.:DEL]
+difflib          Tool for creating delta between sequences.
+dis              Bytecode disassembler.
+distutils        Package installation system.
+doctest          Tool for running and verifying tests inside doc strings.
+dospath          Common operations on DOS pathnames.
+dumbdbm          A dumb and slow but simple dbm clone.
+[DEL:dump:DEL]   [DEL:Print python code that reconstructs a variable.:DEL]
+email            Comprehensive support for internet email.
+exceptions       Class based built-in exception hierarchy.
+filecmp          File comparison.
+fileinput        Helper class to quickly write a loop over all standard input
+                 files.
+[DEL:find:DEL]   [DEL:Find files directory hierarchy matching a pattern.:DEL]
+fnmatch          Filename matching with shell patterns.
+formatter        A test formatter.
+fpformat         General floating point formatting functions.
+ftplib           An FTP client class. Based on RFC 959.
+gc               Perform garbacge collection, obtain GC debug stats, and tune
+                 GC parameters.
+getopt           Standard command line processing. See also ftp://
+                 www.pauahtun.org/pub/getargspy.zip
+getpass          Utilities to get a password and/or the current user name.
+glob             filename globbing.
+gopherlib        Gopher protocol client interface.
+[DEL:grep:DEL]   [DEL:'grep' utilities.:DEL]
+gzip             Read & write gzipped files.
+heapq            Priority queue implemented using lists organized as heaps.
+HMAC             Keyed-Hashing for Message Authentication -- RFC 2104.
+htmlentitydefs   Proposed entity definitions for HTML.
+htmllib          HTML parsing utilities.
+HTMLParser       A parser for HTML and XHTML.
+httplib          HTTP client class.
+ihooks           Hooks into the "import" mechanism.
+imaplib          IMAP4 client.Based on RFC 2060.
+imghdr           Recognizing image files based on their first few bytes.
+imputil          Privides a way of writing customised import hooks.
+inspect          Tool for probing live Python objects.
+keyword          List of Python keywords.
+knee             A Python re-implementation of hierarchical module import.
+linecache        Cache lines from files.
+linuxaudiodev    Lunix /dev/audio support.
+locale           Support for number formatting using the current locale
+                 settings.
+logging          Python logging facility.
+macpath          Pathname (or related) operations for the Macintosh.
+macurl2path      Mac specific module for conversion between pathnames and URLs.
+mailbox          A class to handle a unix-style or mmdf-style mailbox.
+mailcap          Mailcap file handling (RFC 1524).
+mhlib            MH (mailbox) interface.
+mimetools        Various tools used by MIME-reading or MIME-writing programs.
+mimetypes        Guess the MIME type of a file.
+MimeWriter       Generic MIME writer.
+mimify           Mimification and unmimification of mail messages.
+mmap             Interface to memory-mapped files - they behave like mutable
+                 strings./font>
+multifile        Class to make multi-file messages easier to handle.
+mutex            Mutual exclusion -- for use with module sched.
+netrc
+nntplib          An NNTP client class. Based on RFC 977.
+ntpath           Common operations on DOS pathnames.
+nturl2path       Mac specific module for conversion between pathnames and URLs.
+optparse         A comprehensive tool for processing command line options.
+os               Either mac, dos or posix depending system.
+[DEL:packmail:   [DEL:Create a self-unpacking shell archive.:DEL]
+DEL]
+pdb              A Python debugger.
+pickle           Pickling (save and restore) of Python objects (a faster
+                 Cimplementation exists in built-in module: cPickle).
+pipes            Conversion pipeline templates.
+pkgunil          Utilities for working with Python packages.
+popen2           variations on pipe open.
+poplib           A POP3 client class. Based on the J. Myers POP3 draft.
+posixfile        Extended (posix) file operations.
+posixpath        Common operations on POSIX pathnames.
+pprint           Support to pretty-print lists, tuples, & dictionaries
+                 recursively.
+profile          Class for profiling python code.
+pstats           Class for printing reports on profiled python code.
+pydoc            Utility for generating documentation from source files.
+pty              Pseudo terminal utilities.
+pyexpat          Interface to the Expay XML parser.
+py_compile       Routine to "compile" a .py file to a .pyc file.
+pyclbr           Parse a Python file and retrieve classes and methods.
+Queue            A multi-producer, multi-consumer queue.
+quopri           Conversions to/from quoted-printable transport encoding.
+rand             Don't use unless you want compatibility with C's rand().
+random           Random variable generators
+re               Regular Expressions.
+repr             Redo repr() but with limits on most sizes.
+rexec            Restricted execution facilities ("safe" exec, eval, etc).
+rfc822           RFC-822 message manipulation class.
+rlcompleter      Word completion for GNU readline 2.0.
+robotparser      Parse robots.txt files, useful for web spiders.
+sched            A generally useful event scheduler class.
+sets             Module for a set datatype.
+sgmllib          A parser for SGML.
+shelve           Manage shelves of pickled objects.
+shlex            Lexical analyzer class for simple shell-like syntaxes.
+shutil           Utility functions usable in a shell-like program.
+SimpleHTTPServer Simple extension to base http class
+site             Append module search paths for third-party packages to
+                 sys.path.
+smtplib          SMTP Client class (RFC 821)
+sndhdr           Several routines that help recognizing sound.
+SocketServer     Generic socket server classes.
+stat             Constants and functions for interpreting stat/lstat struct.
+statcache        Maintain a cache of file stats.
+statvfs          Constants for interpreting statvfs struct as returned by
+                 os.statvfs()and os.fstatvfs() (if they exist).
+string           A collection of string operations.
+StringIO         File-like objects that read/write a string buffer (a fasterC
+                 implementation exists in built-in module: cStringIO).
+sunau            Stuff to parse Sun and NeXT audio files.
+sunaudio         Interpret sun audio headers.
+symbol           Non-terminal symbols of Python grammar (from "graminit.h").
+tabnanny,/font>  Check Python source for ambiguous indentation.
+tarfile          Facility for reading and writing to the *nix tarfile format.
+telnetlib        TELNET client class. Based on RFC 854.
+tempfile         Temporary file name allocation.
+textwrap         Object for wrapping and filling text.
+threading        Proposed new higher-level threading interfaces
+threading_api    (doc of the threading module)
+toaiff           Convert "arbitrary" sound files to AIFF files .
+token            Tokens (from "token.h").
+tokenize         Compiles a regular expression that recognizes Python tokens.
+traceback        Format and print Python stack traces.
+tty              Terminal utilities.
+turtle           LogoMation-like turtle graphics
+types            Define names for all type symbols in the std interpreter.
+tzparse          Parse a timezone specification.
+unicodedata      Interface to unicode properties.
+urllib           Open an arbitrary URL.
+urlparse         Parse URLs according to latest draft of standard.
+user             Hook to allow user-specified customization code to run.
+UserDict         A wrapper to allow subclassing of built-in dict class.
+UserList         A wrapper to allow subclassing of built-in list class.
+UserString       A wrapper to allow subclassing of built-in string class.
+[DEL:util:DEL]   [DEL:some useful functions that don't fit elsewhere !!:DEL]
+uu               UUencode/UUdecode.
+unittest         Utilities for implementing unit testing.
+wave             Stuff to parse WAVE files.
+weakref          Tools for creating and managing weakly referenced objects.
+webbrowser       Platform independent URL launcher.
+[DEL:whatsound:  [DEL:Several routines that help recognizing sound files.:DEL]
+DEL]
+whichdb          Guess which db package to use to open a db file.
+xdrlib           Implements (a subset of) Sun XDR (eXternal Data
+                 Representation)
+xmllib           A parser for XML, using the derived class as static DTD.
+xml.dom          Classes for processing XML using the Document Object Model.
+xml.sax          Classes for processing XML using the SAX API.
+xmlrpclib        Support for remote procedure calls using XML.
+zipfile          Read & write PK zipped files.
+[DEL:zmod:DEL]   [DEL:Demonstration of abstruse mathematical concepts.:DEL]
+
+
+
+* Built-ins *
+
+            sys                 Interpreter state vars and functions
+            __built-in__        Access to all built-in python identifiers
+            __main__            Scope of the interpreters main program, script or stdin
+            array               Obj efficiently representing arrays of basic values
+            math                Math functions of C standard
+            time                Time-related functions (also the newer datetime module)
+            marshal             Read and write some python values in binary format
+            struct              Convert between python values and C structs
+
+* Standard *
+
+            getopt              Parse cmd line args in sys.argv.  A la UNIX 'getopt'.
+            os                  A more portable interface to OS dependent functionality
+            re                  Functions useful for working with regular expressions
+            string              Useful string and characters functions and exceptions
+            random              Mersenne Twister pseudo-random number generator
+            thread              Low-level primitives for working with process threads
+            threading           idem, new recommanded interface.
+
+* Unix/Posix *
+
+            dbm                 Interface to Unix ndbm database library
+            grp                 Interface to Unix group database
+            posix               OS functionality standardized by C and POSIX standards
+            posixpath           POSIX pathname functions
+            pwd                 Access to the Unix password database
+            select              Access to Unix select multiplex file synchronization
+            socket              Access to BSD socket interface
+
+* Tk User-interface Toolkit *
+
+            tkinter             Main interface to Tk
+
+* Multimedia *
+
+            audioop             Useful operations on sound fragments
+            imageop             Useful operations on images
+            jpeg                Access to jpeg image compressor and decompressor
+            rgbimg              Access SGI imglib image files
+
+* Cryptographic Extensions *
+
+            md5         Interface to RSA's MD5 message digest algorithm
+            sha         Interface to the SHA message digest algorithm
+            HMAC        Keyed-Hashing for Message Authentication -- RFC 2104.
+
+* Stdwin * Standard Window System
+
+            stdwin              Standard Window System interface
+            stdwinevents        Stdwin event, command, and selection constants
+            rect                Rectangle manipulation operations
+
+* SGI IRIX * (4 & 5)
+
+            al          SGI audio facilities
+            AL          al constants
+            fl          Interface to FORMS library
+            FL          fl constants
+            flp Functions for form designer
+            fm          Access to font manager library
+            gl          Access to graphics library
+            GL          Constants for gl
+            DEVICE      More constants for gl
+            imgfile     Imglib image file interface
+
+* Suns *
+
+            sunaudiodev Access to sun audio interface
+
+
+Workspace exploration and idiom hints
+
+        dir(<module>)   list functions, variables in <module>
+        dir()           get object keys, defaults to local name space
+        if __name__ == '__main__': main()            invoke main if running as script
+        map(None, lst1, lst2, ...)                   merge lists
+        b = a[:]                                     create copy of seq structure
+        _                       in interactive mode, is last value printed
+
+
+
+
+
+
+
+Python Mode for Emacs
+
+(Not revised, possibly not up to date)
+Type C-c ? when in python-mode for extensive help.
+INDENTATION
+Primarily for entering new code:
+        TAB      indent line appropriately
+        LFD      insert newline, then indent
+        DEL      reduce indentation, or delete single character
+Primarily for reindenting existing code:
+        C-c :    guess py-indent-offset from file content; change locally
+        C-u C-c :        ditto, but change globally
+        C-c TAB  reindent region to match its context
+        C-c <    shift region left by py-indent-offset
+        C-c >    shift region right by py-indent-offset
+MARKING & MANIPULATING REGIONS OF CODE
+C-c C-b         mark block of lines
+M-C-h           mark smallest enclosing def
+C-u M-C-h       mark smallest enclosing class
+C-c #           comment out region of code
+C-u C-c #       uncomment region of code
+MOVING POINT
+C-c C-p         move to statement preceding point
+C-c C-n         move to statement following point
+C-c C-u         move up to start of current block
+M-C-a           move to start of def
+C-u M-C-a       move to start of class
+M-C-e           move to end of def
+C-u M-C-e       move to end of class
+EXECUTING PYTHON CODE
+C-c C-c sends the entire buffer to the Python interpreter
+C-c |   sends the current region
+C-c !   starts a Python interpreter window; this will be used by
+        subsequent C-c C-c or C-c | commands
+C-c C-w runs PyChecker
+
+VARIABLES
+py-indent-offset        indentation increment
+py-block-comment-prefix comment string used by py-comment-region
+py-python-command       shell command to invoke Python interpreter
+py-scroll-process-buffer        t means always scroll Python process buffer
+py-temp-directory       directory used for temp files (if needed)
+py-beep-if-tab-change   ring the bell if tab-width is changed
+
+
+The Python Debugger
+
+(Not revised, possibly not up to date, see 1.5.2 Library Ref section 9.1; in 1.5.2, you may also use debugger integrated in IDLE)
+
+Accessing
+
+import pdb      (it's a module written in Python)
+        -- defines functions :
+           run(statement[,globals[, locals]])
+                        -- execute statement string under debugger control, with optional
+                           global & local environment.
+           runeval(expression[,globals[, locals]])
+                        -- same as run, but evaluate expression and return value.
+           runcall(function[, argument, ...])
+                        -- run function object with given arg(s)
+           pm()         -- run postmortem on last exception (like debugging a core file)
+           post_mortem(t)
+                        -- run postmortem on traceback object <t>
+
+        -- defines class Pdb :
+           use Pdb to create reusable debugger objects. Object
+           preserves state (i.e. break points) between calls.
+
+        runs until a breakpoint hit, exception, or end of program
+        If exception, variable '__exception__' holds (exception,value).
+
+Commands
+
+h, help
+        brief reminder of commands
+b, break [<arg>]
+        if <arg> numeric, break at line <arg> in current file
+        if <arg> is function object, break on entry to fcn <arg>
+        if no arg, list breakpoints
+cl, clear [<arg>]
+        if <arg> numeric, clear breakpoint at <arg> in current file
+        if no arg, clear all breakpoints after confirmation
+w, where
+        print current call stack
+u, up
+        move up one stack frame (to top-level caller)
+d, down
+        move down one stack frame
+s, step
+        advance one line in the program, stepping into calls
+n, next
+        advance one line, stepping over calls
+r, return
+        continue execution until current function returns
+        (return value is saved in variable "__return__", which
+        can be printed or manipulated from debugger)
+c, continue
+        continue until next breakpoint
+j, jump lineno
+        Set the next line that will be executed
+a, args
+        print args to current function
+rv, retval
+        prints return value from last function that returned
+p, print <arg>
+        prints value of <arg> in current stack frame
+l, list [<first> [, <last>]]
+               List source code for the current file.
+               Without arguments, list 11 lines around the current line
+               or continue the previous listing.
+               With one argument, list 11 lines starting at that line.
+               With two arguments, list the given range;
+               if the second argument is less than the first, it is a count.
+whatis <arg>
+        prints type of <arg>
+!
+        executes rest of line as a Python statement in the current stack frame
+q quit
+        immediately stop execution and leave debugger
+<return>
+        executes last command again
+Any input debugger doesn't recognize as a command is assumed to be a
+Python statement to execute in the current stack frame, the same way
+the exclamation mark ("!") command does.
+
+Example
+
+(1394) python
+Python 1.0.3 (Sep 26 1994)
+Copyright 1991-1994 Stichting Mathematisch Centrum, Amsterdam
+>>> import rm
+>>> rm.run()
+Traceback (innermost last):
+         File "<stdin>", line 1
+         File "./rm.py", line 7
+           x = div(3)
+         File "./rm.py", line 2
+           return a / r
+ZeroDivisionError: integer division or modulo
+>>> import pdb
+>>> pdb.pm()
+> ./rm.py(2)div: return a / r
+(Pdb) list
+         1     def div(a):
+         2  ->     return a / r
+         3
+         4     def run():
+         5         global r
+         6         r = 0
+         7         x = div(3)
+         8         print x
+[EOF]
+(Pdb) print r
+0
+(Pdb) q
+>>> pdb.runcall(rm.run)
+etc.
+
+Quirks
+
+Breakpoints are stored as filename, line number tuples. If a module is reloaded
+after editing, any remembered breakpoints are likely to be wrong.
+
+Always single-steps through top-most stack frame. That is, "c" acts like "n".
+
+

Added: vendor/Python/current/Misc/developers.txt
===================================================================
--- vendor/Python/current/Misc/developers.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Misc/developers.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,141 @@
+Developer Log
+=============
+
+This file is a running log of developers given permissions on SourceForge.
+
+The purpose is to provide some institutional memory of who was given access
+and why.
+
+The first entry starts in April 2005.  In keeping with the style of
+Misc/NEWS, newer entries should be added to the top.  Any markup should
+be in the form of ReST.  Entries should include the initials of the
+project admin who made the change or granted access.  Feel free to revise
+the format to accommodate documentation needs as they arise.
+
+
+
+Permissions History
+-------------------
+
+- 2006 Summer of Code entries: SoC developers are expected to work
+  primarily in nondist/sandbox or on a branch of their own, and will
+  have their work reviewed before changes are accepted into the trunk.
+
+  - Matt Fleming was added on 25 May 2006 by AMK; he'll be working on
+    enhancing the Python debugger.   
+
+  - Jackilyn Hoxworth was added on 25 May 2006 by AMK; she'll be adding logging
+    to the standard library.  
+
+  - Mateusz Rukowicz was added on 30 May 2006 by AMK; he'll be 
+    translating the decimal module into C.
+
+- SVN access granted to the "Need for Speed" Iceland sprint attendees,
+  between May 17 and 21, 2006, by Tim Peters.  All work is to be done
+  in new sandbox projects or on new branches, with merging to the
+  trunk as approved:
+
+  Andrew Dalke
+  Christian Tismer
+  Jack Diederich
+  John Benediktsson
+  Kristján V. Jónsson
+  Martin Blais
+  Richard Emslie
+  Richard Jones
+  Runar Petursson
+  Steve Holden
+  Richard M. Tew
+
+- Steven Bethard was given SVN access on 27 Apr 2006 by DJG, for PEP
+  update access.
+
+- Talin was given SVN access on 27 Apr 2006 by DJG, for PEP update
+  access.
+
+- George Yoshida (SF name "quiver") added to the SourceForge Python
+  project 14 Apr 2006, by Tim Peters, as a tracker admin.  See
+  contemporaneous python-checkins thread with the unlikely Subject:
+
+      r45329 - python/trunk/Doc/whatsnew/whatsnew25.tex
+
+- Ronald Oussoren was given SVN access on 3 Mar 2006 by NCN, for Mac
+  related work.
+
+- Bob Ippolito was given SVN access on 2 Mar 2006 by NCN, for Mac
+  related work.
+
+- Nick Coghlan requested CVS access so he could update his PEP directly.
+  Granted by GvR on 16 Oct 2005.
+
+- Added two new developers for the Summer of Code project. 8 July 2005
+  by RDH.  Andrew Kuchling will be mentoring Gregory K Johnson for a
+  project to enhance mailbox.  Brett Cannon requested access for Flovis
+  Bruynooghe (sirolf) to work on pstats, profile, and hotshot.  Both users
+  are expected to work primarily in nondist/sandbox and have their work
+  reviewed before making updates to active code.
+
+- Georg Brandl was given SF tracker permissions on 28 May 2005
+  by RDH.  Since the beginning of 2005, he has been active in discussions
+  on python-dev and has submitted a dozen patch reviews.  The permissions
+  add the ability to change tracker status and to attach patches.  On
+  3 June 2005, this was expanded by RDH to include checkin permissions.
+
+- Terry Reedy was given SF tracker permissions on 7 Apr 2005 by RDH.
+
+- Nick Coghlan was given SF tracker permissions on 5 Apr 2005 by RDH.
+  For several months, he has been active in reviewing and contributing
+  patches.  The added permissions give him greater flexibility in
+  working with the tracker.
+
+- Eric Price was made a developer on 2 May 2003 by TGP.  This was
+  specifically to work on the new ``decimal`` package, which lived in
+  ``nondist/sandbox/decimal/`` at the time.
+
+- Eric S. Raymond was made a developer on 2 Jul 2000 by TGP, for general
+  library work.  His request is archived here:
+
+      http://mail.python.org/pipermail/python-dev/2000-July/005314.html
+
+
+Permissions Dropped on Request
+------------------------------
+
+- Per note from Andrew Kuchling, the permissions for Gregory K Johnson
+  and the Summer Of Code project are no longer needed.  AMK will make
+  any future checkins directly.  16 Oct 2005 RDH
+
+- Johannes Gijsbers sent a drop request.  27 July 2005 RDH
+
+- Flovis Bruynooghe sent a drop request.  14 July 2005 RDH
+
+- Paul Prescod sent a drop request.  30 Apr 2005 RDH
+
+- Finn Bock sent a drop request.  13 Apr 2005 RDH
+
+- Eric Price sent a drop request.  10 Apr 2005 RDH
+
+- Irmen de Jong requested dropping CVS access while keeping tracker
+  access.  10 Apr 2005 RDH
+
+- Moshe Zadka and Ken Manheimer sent drop requests.  8 Apr 2005 by RDH
+
+- Steve Holden, Gerhard Haring, and David Cole sent email stating that
+  they no longer use their access.   7 Apr 2005 RDH
+
+
+Permissions Dropped after Loss of Contact
+-----------------------------------------
+
+- Several unsuccessful efforts were made to contact Charles G Waldman.
+  Removed on 8 Apr 2005 by RDH.
+
+
+Initials of Project Admins
+--------------------------
+
+GvR:  Guido van Rossum
+NCN:  Neal Norwitz
+RDH:  Raymond Hettinger
+TGP:  Tim Peters
+DJG:  David Goodger

Added: vendor/Python/current/Misc/find_recursionlimit.py
===================================================================
--- vendor/Python/current/Misc/find_recursionlimit.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Misc/find_recursionlimit.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,87 @@
+#! /usr/bin/env python
+"""Find the maximum recursion limit that prevents core dumps
+
+This script finds the maximum safe recursion limit on a particular
+platform.  If you need to change the recursion limit on your system,
+this script will tell you a safe upper bound.  To use the new limit,
+call sys.setrecursionlimit.
+
+This module implements several ways to create infinite recursion in
+Python.  Different implementations end up pushing different numbers of
+C stack frames, depending on how many calls through Python's abstract
+C API occur.
+
+After each round of tests, it prints a message
+Limit of NNNN is fine.
+
+It ends when Python causes a segmentation fault because the limit is
+too high.  On platforms like Mac and Windows, it should exit with a
+MemoryError.
+
+NB: A program that does not use __methods__ can set a higher limit.
+"""
+
+import sys
+
+class RecursiveBlowup1:
+    def __init__(self):
+        self.__init__()
+
+def test_init():
+    return RecursiveBlowup1()
+
+class RecursiveBlowup2:
+    def __repr__(self):
+        return repr(self)
+
+def test_repr():
+    return repr(RecursiveBlowup2())
+
+class RecursiveBlowup4:
+    def __add__(self, x):
+        return x + self
+
+def test_add():
+    return RecursiveBlowup4() + RecursiveBlowup4()
+
+class RecursiveBlowup5:
+    def __getattr__(self, attr):
+        return getattr(self, attr)
+
+def test_getattr():
+    return RecursiveBlowup5().attr
+
+class RecursiveBlowup6:
+    def __getitem__(self, item):
+        return self[item - 2] + self[item - 1]
+
+def test_getitem():
+    return RecursiveBlowup6()[5]
+
+def test_recurse():
+    return test_recurse()
+
+def check_limit(n, test_func_name):
+    sys.setrecursionlimit(n)
+    if test_func_name.startswith("test_"):
+        print test_func_name[5:]
+    else:
+        print test_func_name
+    test_func = globals()[test_func_name]
+    try:
+        test_func()
+    except RuntimeError:
+        pass
+    else:
+        print "Yikes!"
+
+limit = 1000
+while 1:
+    check_limit(limit, "test_recurse")
+    check_limit(limit, "test_add")
+    check_limit(limit, "test_repr")
+    check_limit(limit, "test_init")
+    check_limit(limit, "test_getattr")
+    check_limit(limit, "test_getitem")
+    print "Limit of %d is fine" % limit
+    limit = limit + 100

Added: vendor/Python/current/Misc/gdbinit
===================================================================
--- vendor/Python/current/Misc/gdbinit	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Misc/gdbinit	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,140 @@
+# -*- ksh -*-
+#
+# If you use the GNU debugger gdb to debug the Python C runtime, you
+# might find some of the following commands useful.  Copy this to your
+# ~/.gdbinit file and it'll get loaded into gdb automatically when you
+# start it up.  Then, at the gdb prompt you can do things like:
+#
+#    (gdb) pyo apyobjectptr
+#    <module 'foobar' (built-in)>
+#    refcounts: 1
+#    address    : 84a7a2c
+#    $1 = void
+#    (gdb)
+
+# Prints a representation of the object to stderr, along with the
+# number of reference counts it current has and the hex address the
+# object is allocated at.  The argument must be a PyObject*
+define pyo
+print _PyObject_Dump($arg0)
+end
+
+# Prints a representation of the object to stderr, along with the
+# number of reference counts it current has and the hex address the
+# object is allocated at.  The argument must be a PyGC_Head*
+define pyg
+print _PyGC_Dump($arg0)
+end
+
+# print the local variables of the current frame
+define pylocals
+    set $_i = 0
+    while $_i < f->f_nlocals
+	if f->f_localsplus + $_i != 0
+	    set $_names = co->co_varnames
+	    set $_name = PyString_AsString(PyTuple_GetItem($_names, $_i))
+	    printf "%s:\n", $_name
+	    # side effect of calling _PyObject_Dump is to dump the object's
+	    # info - assigning just prevents gdb from printing the
+	    # NULL return value
+	    set $_val = _PyObject_Dump(f->f_localsplus[$_i])
+	end
+        set $_i = $_i + 1
+    end
+end
+
+# A rewrite of the Python interpreter's line number calculator in GDB's
+# command language
+define lineno
+    set $__continue = 1
+    set $__co = f->f_code
+    set $__lasti = f->f_lasti
+    set $__sz = ((PyStringObject *)$__co->co_lnotab)->ob_size/2
+    set $__p = (unsigned char *)((PyStringObject *)$__co->co_lnotab)->ob_sval
+    set $__li = $__co->co_firstlineno
+    set $__ad = 0
+    while ($__sz-1 >= 0 && $__continue)
+      set $__sz = $__sz - 1
+      set $__ad = $__ad + *$__p
+      set $__p = $__p + 1
+      if ($__ad > $__lasti)
+	set $__continue = 0
+      end
+      set $__li = $__li + *$__p
+      set $__p = $__p + 1
+    end
+    printf "%d", $__li
+end
+
+# print the current frame - verbose
+define pyframev
+    pyframe
+    pylocals
+end
+
+define pyframe
+    set $__fn = (char *)((PyStringObject *)co->co_filename)->ob_sval
+    set $__n = (char *)((PyStringObject *)co->co_name)->ob_sval
+    printf "%s (", $__fn
+    lineno
+    printf "): %s\n", $__n
+### Uncomment these lines when using from within Emacs/XEmacs so it will
+### automatically track/display the current Python source line
+#    printf "%c%c%s:", 032, 032, $__fn
+#    lineno
+#    printf ":1\n"
+end
+
+### Use these at your own risk.  It appears that a bug in gdb causes it
+### to crash in certain circumstances.
+
+#define up
+#    up-silently 1
+#    printframe
+#end
+
+#define down
+#    down-silently 1
+#    printframe
+#end
+
+define printframe
+    if $pc > PyEval_EvalFrameEx && $pc < PyEval_EvalCodeEx
+	pyframe
+    else
+        frame
+    end
+end
+
+# Here's a somewhat fragile way to print the entire Python stack from gdb.
+# It's fragile because the tests for the value of $pc depend on the layout
+# of specific functions in the C source code.
+
+# Explanation of while and if tests: We want to pop up the stack until we
+# land in Py_Main (this is probably an incorrect assumption in an embedded
+# interpreter, but the test can be extended by an interested party).  If
+# Py_Main <= $pc <= Py_GetArgcArv is true, $pc is in Py_Main(), so the while
+# tests succeeds as long as it's not true.  In a similar fashion the if
+# statement tests to see if we are in PyEval_EvalFrame().
+
+# print the entire Python call stack
+define pystack
+    while $pc < Py_Main || $pc > Py_GetArgcArgv
+        if $pc > PyEval_EvalFrame && $pc < PyEval_EvalCodeEx
+	    pyframe
+        end
+        up-silently 1
+    end
+    select-frame 0
+end
+
+# print the entire Python call stack - verbose mode
+define pystackv
+    while $pc < Py_Main || $pc > Py_GetArgcArgv
+        if $pc > PyEval_EvalFrame && $pc < PyEval_EvalCodeEx
+	    pyframev
+        end
+        up-silently 1
+    end
+    select-frame 0
+end

Added: vendor/Python/current/Misc/indent.pro
===================================================================
--- vendor/Python/current/Misc/indent.pro	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Misc/indent.pro	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,15 @@
+-sob
+-nbad
+-bap
+-br
+-nce
+-ncs
+-npcs
+-i8
+-ip8
+-c25
+-T PyObject
+
+
+
+

Added: vendor/Python/current/Misc/pymemcompat.h
===================================================================
--- vendor/Python/current/Misc/pymemcompat.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Misc/pymemcompat.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,85 @@
+/* The idea of this file is that you bundle it with your extension,
+   #include it, program to Python 2.3's memory API and have your
+   extension build with any version of Python from 1.5.2 through to
+   2.3 (and hopefully beyond). */
+
+#ifndef Py_PYMEMCOMPAT_H
+#define Py_PYMEMCOMPAT_H
+
+#include "Python.h"
+
+/* There are three "families" of memory API: the "raw memory", "object
+   memory" and "object" families.  (This is ignoring the matter of the
+   cycle collector, about which more is said below).
+
+   Raw Memory:
+
+       PyMem_Malloc, PyMem_Realloc, PyMem_Free
+
+   Object Memory:
+
+       PyObject_Malloc, PyObject_Realloc, PyObject_Free
+
+   Object:
+
+       PyObject_New, PyObject_NewVar, PyObject_Del
+
+   The raw memory and object memory allocators both mimic the
+   malloc/realloc/free interface from ANSI C, but the object memory
+   allocator can (and, since 2.3, does by default) use a different
+   allocation strategy biased towards lots of "small" allocations.
+
+   The object family is used for allocating Python objects, and the
+   initializers take care of some basic initialization (setting the
+   refcount to 1 and filling out the ob_type field) as well as having
+   a somewhat different interface.
+
+   Do not mix the families!  E.g. do not allocate memory with
+   PyMem_Malloc and free it with PyObject_Free.  You may get away with
+   it quite a lot of the time, but there *are* scenarios where this
+   will break.  You Have Been Warned. 
+
+   Also, in many versions of Python there are an insane amount of
+   memory interfaces to choose from.  Use the ones described above. */
+
+#if PY_VERSION_HEX < 0x01060000
+/* raw memory interface already present */
+
+/* there is no object memory interface in 1.5.2 */
+#define PyObject_Malloc		PyMem_Malloc
+#define PyObject_Realloc	PyMem_Realloc
+#define PyObject_Free		PyMem_Free
+
+/* the object interface is there, but the names have changed */
+#define PyObject_New		PyObject_NEW
+#define PyObject_NewVar		PyObject_NEW_VAR
+#define PyObject_Del		PyMem_Free
+#endif
+
+/* If your object is a container you probably want to support the
+   cycle collector, which was new in Python 2.0.
+
+   Unfortunately, the interface to the collector that was present in
+   Python 2.0 and 2.1 proved to be tricky to use, and so changed in
+   2.2 -- in a way that can't easily be papered over with macros.
+
+   This file contains macros that let you program to the 2.2 GC API.
+   Your module will compile against any Python since version 1.5.2,
+   but the type will only participate in the GC in versions 2.2 and
+   up.  Some work is still necessary on your part to only fill out the
+   tp_traverse and tp_clear fields when they exist and set tp_flags
+   appropriately.
+
+   It is possible to support both the 2.0 and 2.2 GC APIs, but it's
+   not pretty and this comment block is too narrow to contain a
+   desciption of what's required... */
+
+#if PY_VERSION_HEX < 0x020200B1
+#define PyObject_GC_New         PyObject_New
+#define PyObject_GC_NewVar      PyObject_NewVar
+#define PyObject_GC_Del         PyObject_Del
+#define PyObject_GC_Track(op)
+#define PyObject_GC_UnTrack(op)
+#endif
+
+#endif /* !Py_PYMEMCOMPAT_H */

Added: vendor/Python/current/Misc/python-config.in
===================================================================
--- vendor/Python/current/Misc/python-config.in	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Misc/python-config.in	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,53 @@
+#!@EXENAME@
+
+import sys
+import os
+import getopt
+from distutils import sysconfig
+
+valid_opts = ['prefix', 'exec-prefix', 'includes', 'libs', 'cflags', 
+              'ldflags', 'help']
+
+def exit_with_usage(code=1):
+    print >>sys.stderr, "Usage: %s [%s]" % (sys.argv[0], 
+                                            '|'.join('--'+opt for opt in valid_opts))
+    sys.exit(code)
+
+try:
+    opts, args = getopt.getopt(sys.argv[1:], '', valid_opts)
+except getopt.error:
+    exit_with_usage()
+
+if not opts:
+    exit_with_usage()
+
+opt = opts[0][0]
+
+pyver = sysconfig.get_config_var('VERSION')
+getvar = sysconfig.get_config_var
+
+if opt == '--help':
+    exit_with_usage(0)
+
+elif opt == '--prefix':
+    print sysconfig.PREFIX
+
+elif opt == '--exec-prefix':
+    print sysconfig.EXEC_PREFIX
+
+elif opt in ('--includes', '--cflags'):
+    flags = ['-I' + sysconfig.get_python_inc(),
+             '-I' + sysconfig.get_python_inc(plat_specific=True)]
+    if opt == '--cflags':
+        flags.extend(getvar('CFLAGS').split())
+    print ' '.join(flags)
+
+elif opt in ('--libs', '--ldflags'):
+    libs = getvar('LIBS').split() + getvar('SYSLIBS').split()
+    libs.append('-lpython'+pyver)
+    # add the prefix/lib/pythonX.Y/config dir, but only if there is no
+    # shared library in prefix/lib/.
+    if opt == '--ldflags' and not getvar('Py_ENABLE_SHARED'):
+        libs.insert(0, '-L' + getvar('LIBPL'))
+    print ' '.join(libs)
+

Added: vendor/Python/current/Misc/python-mode.el
===================================================================
--- vendor/Python/current/Misc/python-mode.el	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Misc/python-mode.el	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,3768 @@
+;;; python-mode.el --- Major mode for editing Python programs
+
+;; Copyright (C) 1992,1993,1994  Tim Peters
+
+;; Author: 1995-2002 Barry A. Warsaw
+;;         1992-1994 Tim Peters
+;; Maintainer: python-mode at python.org
+;; Created:    Feb 1992
+;; Keywords:   python languages oop
+
+(defconst py-version "$Revision: 34960 $"
+  "`python-mode' version number.")
+
+;; This software is provided as-is, without express or implied
+;; warranty.  Permission to use, copy, modify, distribute or sell this
+;; software, without fee, for any purpose and by any individual or
+;; organization, is hereby granted, provided that the above copyright
+;; notice and this paragraph appear in all copies.
+
+;;; Commentary:
+
+;; This is a major mode for editing Python programs.  It was developed
+;; by Tim Peters after an original idea by Michael A. Guravage.  Tim
+;; subsequently left the net; in 1995, Barry Warsaw inherited the mode
+;; and is the current maintainer.  Tim's now back but disavows all
+;; responsibility for the mode.  Smart Tim :-)
+
+;; pdbtrack support contributed by Ken Manheimer, April 2001.
+
+;; Please use the SourceForge Python project to submit bugs or
+;; patches:
+;;
+;;     http://sourceforge.net/projects/python
+
+;; FOR MORE INFORMATION:
+
+;; There is some information on python-mode.el at
+
+;;     http://www.python.org/emacs/python-mode/
+;;
+;; It does contain links to other packages that you might find useful,
+;; such as pdb interfaces, OO-Browser links, etc.
+
+;; BUG REPORTING:
+
+;; As mentioned above, please use the SourceForge Python project for
+;; submitting bug reports or patches.  The old recommendation, to use
+;; C-c C-b will still work, but those reports have a higher chance of
+;; getting buried in my mailbox.  Please include a complete, but
+;; concise code sample and a recipe for reproducing the bug.  Send
+;; suggestions and other comments to python-mode at python.org.
+
+;; When in a Python mode buffer, do a C-h m for more help.  It's
+;; doubtful that a texinfo manual would be very useful, but if you
+;; want to contribute one, I'll certainly accept it!
+
+;;; Code:
+
+(require 'comint)
+(require 'custom)
+(require 'cl)
+(require 'compile)
+
+
+;; user definable variables
+;; vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
+
+(defgroup python nil
+  "Support for the Python programming language, <http://www.python.org/>"
+  :group 'languages
+  :prefix "py-")
+
+(defcustom py-python-command "python"
+  "*Shell command used to start Python interpreter."
+  :type 'string
+  :group 'python)
+
+(defcustom py-jpython-command "jpython"
+  "*Shell command used to start the JPython interpreter."
+  :type 'string
+  :group 'python
+  :tag "JPython Command")
+
+(defcustom py-default-interpreter 'cpython
+  "*Which Python interpreter is used by default.
+The value for this variable can be either `cpython' or `jpython'.
+
+When the value is `cpython', the variables `py-python-command' and
+`py-python-command-args' are consulted to determine the interpreter
+and arguments to use.
+
+When the value is `jpython', the variables `py-jpython-command' and
+`py-jpython-command-args' are consulted to determine the interpreter
+and arguments to use.
+
+Note that this variable is consulted only the first time that a Python
+mode buffer is visited during an Emacs session.  After that, use
+\\[py-toggle-shells] to change the interpreter shell."
+  :type '(choice (const :tag "Python (a.k.a. CPython)" cpython)
+		 (const :tag "JPython" jpython))
+  :group 'python)
+
+(defcustom py-python-command-args '("-i")
+  "*List of string arguments to be used when starting a Python shell."
+  :type '(repeat string)
+  :group 'python)
+
+(defcustom py-jpython-command-args '("-i")
+  "*List of string arguments to be used when starting a JPython shell."
+  :type '(repeat string)
+  :group 'python
+  :tag "JPython Command Args")
+
+(defcustom py-indent-offset 4
+  "*Amount of offset per level of indentation.
+`\\[py-guess-indent-offset]' can usually guess a good value when
+you're editing someone else's Python code."
+  :type 'integer
+  :group 'python)
+
+(defcustom py-continuation-offset 4
+  "*Additional amount of offset to give for some continuation lines.
+Continuation lines are those that immediately follow a backslash
+terminated line.  Only those continuation lines for a block opening
+statement are given this extra offset."
+  :type 'integer
+  :group 'python)
+
+(defcustom py-smart-indentation t
+  "*Should `python-mode' try to automagically set some indentation variables?
+When this variable is non-nil, two things happen when a buffer is set
+to `python-mode':
+
+    1. `py-indent-offset' is guessed from existing code in the buffer.
+       Only guessed values between 2 and 8 are considered.  If a valid
+       guess can't be made (perhaps because you are visiting a new
+       file), then the value in `py-indent-offset' is used.
+
+    2. `indent-tabs-mode' is turned off if `py-indent-offset' does not
+       equal `tab-width' (`indent-tabs-mode' is never turned on by
+       Python mode).  This means that for newly written code, tabs are
+       only inserted in indentation if one tab is one indentation
+       level, otherwise only spaces are used.
+
+Note that both these settings occur *after* `python-mode-hook' is run,
+so if you want to defeat the automagic configuration, you must also
+set `py-smart-indentation' to nil in your `python-mode-hook'."
+  :type 'boolean
+  :group 'python)
+
+(defcustom py-align-multiline-strings-p t
+  "*Flag describing how multi-line triple quoted strings are aligned.
+When this flag is non-nil, continuation lines are lined up under the
+preceding line's indentation.  When this flag is nil, continuation
+lines are aligned to column zero."
+  :type '(choice (const :tag "Align under preceding line" t)
+		 (const :tag "Align to column zero" nil))
+  :group 'python)
+
+(defcustom py-block-comment-prefix "##"
+  "*String used by \\[comment-region] to comment out a block of code.
+This should follow the convention for non-indenting comment lines so
+that the indentation commands won't get confused (i.e., the string
+should be of the form `#x...' where `x' is not a blank or a tab, and
+`...' is arbitrary).  However, this string should not end in whitespace."
+  :type 'string
+  :group 'python)
+
+(defcustom py-honor-comment-indentation t
+  "*Controls how comment lines influence subsequent indentation.
+
+When nil, all comment lines are skipped for indentation purposes, and
+if possible, a faster algorithm is used (i.e. X/Emacs 19 and beyond).
+
+When t, lines that begin with a single `#' are a hint to subsequent
+line indentation.  If the previous line is such a comment line (as
+opposed to one that starts with `py-block-comment-prefix'), then its
+indentation is used as a hint for this line's indentation.  Lines that
+begin with `py-block-comment-prefix' are ignored for indentation
+purposes.
+
+When not nil or t, comment lines that begin with a single `#' are used
+as indentation hints, unless the comment character is in column zero."
+  :type '(choice
+	  (const :tag "Skip all comment lines (fast)" nil)
+	  (const :tag "Single # `sets' indentation for next line" t)
+	  (const :tag "Single # `sets' indentation except at column zero"
+		 other)
+	  )
+  :group 'python)
+
+(defcustom py-temp-directory
+  (let ((ok '(lambda (x)
+	       (and x
+		    (setq x (expand-file-name x)) ; always true
+		    (file-directory-p x)
+		    (file-writable-p x)
+		    x))))
+    (or (funcall ok (getenv "TMPDIR"))
+	(funcall ok "/usr/tmp")
+	(funcall ok "/tmp")
+	(funcall ok "/var/tmp")
+	(funcall ok  ".")
+	(error
+	 "Couldn't find a usable temp directory -- set `py-temp-directory'")))
+  "*Directory used for temporary files created by a *Python* process.
+By default, the first directory from this list that exists and that you
+can write into: the value (if any) of the environment variable TMPDIR,
+/usr/tmp, /tmp, /var/tmp, or the current directory."
+  :type 'string
+  :group 'python)
+
+(defcustom py-beep-if-tab-change t
+  "*Ring the bell if `tab-width' is changed.
+If a comment of the form
+
+  \t# vi:set tabsize=<number>:
+
+is found before the first code line when the file is entered, and the
+current value of (the general Emacs variable) `tab-width' does not
+equal <number>, `tab-width' is set to <number>, a message saying so is
+displayed in the echo area, and if `py-beep-if-tab-change' is non-nil
+the Emacs bell is also rung as a warning."
+  :type 'boolean
+  :group 'python)
+
+(defcustom py-jump-on-exception t
+  "*Jump to innermost exception frame in *Python Output* buffer.
+When this variable is non-nil and an exception occurs when running
+Python code synchronously in a subprocess, jump immediately to the
+source code of the innermost traceback frame."
+  :type 'boolean
+  :group 'python)
+
+(defcustom py-ask-about-save t
+  "If not nil, ask about which buffers to save before executing some code.
+Otherwise, all modified buffers are saved without asking."
+  :type 'boolean
+  :group 'python)
+
+(defcustom py-backspace-function 'backward-delete-char-untabify
+  "*Function called by `py-electric-backspace' when deleting backwards."
+  :type 'function
+  :group 'python)
+
+(defcustom py-delete-function 'delete-char
+  "*Function called by `py-electric-delete' when deleting forwards."
+  :type 'function
+  :group 'python)
+
+(defcustom py-imenu-show-method-args-p nil 
+  "*Controls echoing of arguments of functions & methods in the Imenu buffer.
+When non-nil, arguments are printed."
+  :type 'boolean
+  :group 'python)
+(make-variable-buffer-local 'py-indent-offset)
+
+(defcustom py-pdbtrack-do-tracking-p t
+  "*Controls whether the pdbtrack feature is enabled or not.
+When non-nil, pdbtrack is enabled in all comint-based buffers,
+e.g. shell buffers and the *Python* buffer.  When using pdb to debug a
+Python program, pdbtrack notices the pdb prompt and displays the
+source file and line that the program is stopped at, much the same way
+as gud-mode does for debugging C programs with gdb."
+  :type 'boolean
+  :group 'python)
+(make-variable-buffer-local 'py-pdbtrack-do-tracking-p)
+
+(defcustom py-pdbtrack-minor-mode-string " PDB"
+  "*String to use in the minor mode list when pdbtrack is enabled."
+  :type 'string
+  :group 'python)
+
+(defcustom py-import-check-point-max
+  20000
+  "Maximum number of characters to search for a Java-ish import statement.
+When `python-mode' tries to calculate the shell to use (either a
+CPython or a JPython shell), it looks at the so-called `shebang' line
+-- i.e. #! line.  If that's not available, it looks at some of the
+file heading imports to see if they look Java-like."
+  :type 'integer
+  :group 'python
+  )
+
+(defcustom py-jpython-packages
+  '("java" "javax" "org" "com")
+  "Imported packages that imply `jpython-mode'."
+  :type '(repeat string)
+  :group 'python)
+  
+;; Not customizable
+(defvar py-master-file nil
+  "If non-nil, execute the named file instead of the buffer's file.
+The intent is to allow you to set this variable in the file's local
+variable section, e.g.:
+
+    # Local Variables:
+    # py-master-file: \"master.py\"
+    # End:
+
+so that typing \\[py-execute-buffer] in that buffer executes the named
+master file instead of the buffer's file.  If the file name has a
+relative path, the value of variable `default-directory' for the
+buffer is prepended to come up with a file name.")
+(make-variable-buffer-local 'py-master-file)
+
+(defcustom py-pychecker-command "pychecker"
+  "*Shell command used to run Pychecker."
+  :type 'string
+  :group 'python
+  :tag "Pychecker Command")
+
+(defcustom py-pychecker-command-args '("--stdlib")
+  "*List of string arguments to be passed to pychecker."
+  :type '(repeat string)
+  :group 'python
+  :tag "Pychecker Command Args")
+
+(defvar py-shell-alist
+  '(("jpython" . 'jpython)
+    ("jython" . 'jpython)
+    ("python" . 'cpython))
+  "*Alist of interpreters and python shells. Used by `py-choose-shell'
+to select the appropriate python interpreter mode for a file.")
+
+
+;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+;; NO USER DEFINABLE VARIABLES BEYOND THIS POINT
+
+(defconst py-emacs-features
+  (let (features)
+   features)
+  "A list of features extant in the Emacs you are using.
+There are many flavors of Emacs out there, with different levels of
+support for features needed by `python-mode'.")
+
+;; Face for None, True, False, self, and Ellipsis
+(defvar py-pseudo-keyword-face 'py-pseudo-keyword-face
+  "Face for pseudo keywords in Python mode, like self, True, False, Ellipsis.")
+(make-face 'py-pseudo-keyword-face)
+
+(defun py-font-lock-mode-hook ()
+  (or (face-differs-from-default-p 'py-pseudo-keyword-face)
+      (copy-face 'font-lock-keyword-face 'py-pseudo-keyword-face)))
+(add-hook 'font-lock-mode-hook 'py-font-lock-mode-hook)
+
+(defvar python-font-lock-keywords
+  (let ((kw1 (mapconcat 'identity
+			'("and"      "assert"   "break"   "class"
+			  "continue" "def"      "del"     "elif"
+			  "else"     "except"   "exec"    "for"
+			  "from"     "global"   "if"      "import"
+			  "in"       "is"       "lambda"  "not"
+			  "or"       "pass"     "print"   "raise"
+			  "return"   "while"    "yield"
+			  )
+			"\\|"))
+	(kw2 (mapconcat 'identity
+			'("else:" "except:" "finally:" "try:")
+			"\\|"))
+	(kw3 (mapconcat 'identity
+			'("ArithmeticError" "AssertionError"
+			  "AttributeError" "DeprecationWarning" "EOFError"
+			  "Ellipsis" "EnvironmentError" "Exception" "False"
+			  "FloatingPointError" "FutureWarning" "IOError"
+			  "ImportError" "IndentationError" "IndexError"
+			  "KeyError" "KeyboardInterrupt" "LookupError"
+			  "MemoryError" "NameError" "None" "NotImplemented"
+			  "NotImplementedError" "OSError" "OverflowError"
+			  "OverflowWarning" "PendingDeprecationWarning"
+			  "ReferenceError" "RuntimeError" "RuntimeWarning"
+			  "StandardError" "StopIteration" "SyntaxError"
+			  "SyntaxWarning" "SystemError" "SystemExit"
+			  "TabError" "True" "TypeError" "UnboundLocalError"
+			  "UnicodeDecodeError" "UnicodeEncodeError"
+			  "UnicodeError" "UnicodeTranslateError"
+			  "UserWarning" "ValueError" "Warning"
+			  "ZeroDivisionError" "__debug__"
+			  "__import__" "__name__" "abs" "apply" "basestring"
+			  "bool" "buffer" "callable" "chr" "classmethod"
+			  "cmp" "coerce" "compile" "complex" "copyright"
+			  "delattr" "dict" "dir" "divmod"
+			  "enumerate" "eval" "execfile" "exit" "file"
+			  "filter" "float" "getattr" "globals" "hasattr"
+			  "hash" "hex" "id" "input" "int" "intern"
+			  "isinstance" "issubclass" "iter" "len" "license"
+			  "list" "locals" "long" "map" "max" "min" "object"
+			  "oct" "open" "ord" "pow" "property" "range"
+			  "raw_input" "reduce" "reload" "repr" "round"
+			  "setattr" "slice" "staticmethod" "str" "sum"
+			  "super" "tuple" "type" "unichr" "unicode" "vars"
+			  "xrange" "zip")
+			"\\|"))
+	)
+    (list
+     ;; keywords
+     (cons (concat "\\b\\(" kw1 "\\)\\b[ \n\t(]") 1)
+     ;; builtins when they don't appear as object attributes
+     (cons (concat "\\(\\b\\|[.]\\)\\(" kw3 "\\)\\b[ \n\t(]") 2)
+     ;; block introducing keywords with immediately following colons.
+     ;; Yes "except" is in both lists.
+     (cons (concat "\\b\\(" kw2 "\\)[ \n\t(]") 1)
+     ;; `as' but only in "import foo as bar"
+     '("[ \t]*\\(\\bfrom\\b.*\\)?\\bimport\\b.*\\b\\(as\\)\\b" . 2)
+     ;; classes
+     '("\\bclass[ \t]+\\([a-zA-Z_]+[a-zA-Z0-9_]*\\)"
+       1 font-lock-type-face)
+     ;; functions
+     '("\\bdef[ \t]+\\([a-zA-Z_]+[a-zA-Z0-9_]*\\)"
+       1 font-lock-function-name-face)
+     ;; pseudo-keywords
+     '("\\b\\(self\\|None\\|True\\|False\\|Ellipsis\\)\\b"
+       1 py-pseudo-keyword-face)
+     ))
+  "Additional expressions to highlight in Python mode.")
+(put 'python-mode 'font-lock-defaults '(python-font-lock-keywords))
+
+;; have to bind py-file-queue before installing the kill-emacs-hook
+(defvar py-file-queue nil
+  "Queue of Python temp files awaiting execution.
+Currently-active file is at the head of the list.")
+
+(defvar py-pdbtrack-is-tracking-p nil)
+(defvar py-pdbtrack-last-grubbed-buffer nil
+  "Record of the last buffer used when the source path was invalid.
+
+This buffer is consulted before the buffer-list history for satisfying
+`py-pdbtrack-grub-for-buffer', since it's the most often the likely
+prospect as debugging continues.")
+(make-variable-buffer-local 'py-pdbtrack-last-grubbed-buffer)
+(defvar py-pychecker-history nil)
+
+
+
+;; Constants
+
+(defconst py-stringlit-re
+  (concat
+   ;; These fail if backslash-quote ends the string (not worth
+   ;; fixing?).  They precede the short versions so that the first two
+   ;; quotes don't look like an empty short string.
+   ;;
+   ;; (maybe raw), long single quoted triple quoted strings (SQTQ),
+   ;; with potential embedded single quotes
+   "[rR]?'''[^']*\\(\\('[^']\\|''[^']\\)[^']*\\)*'''"
+   "\\|"
+   ;; (maybe raw), long double quoted triple quoted strings (DQTQ),
+   ;; with potential embedded double quotes
+   "[rR]?\"\"\"[^\"]*\\(\\(\"[^\"]\\|\"\"[^\"]\\)[^\"]*\\)*\"\"\""
+   "\\|"
+   "[rR]?'\\([^'\n\\]\\|\\\\.\\)*'"	; single-quoted
+   "\\|"				; or
+   "[rR]?\"\\([^\"\n\\]\\|\\\\.\\)*\""	; double-quoted
+   )
+  "Regular expression matching a Python string literal.")
+
+(defconst py-continued-re
+  ;; This is tricky because a trailing backslash does not mean
+  ;; continuation if it's in a comment
+  (concat
+   "\\(" "[^#'\"\n\\]" "\\|" py-stringlit-re "\\)*"
+   "\\\\$")
+  "Regular expression matching Python backslash continuation lines.")
+  
+(defconst py-blank-or-comment-re "[ \t]*\\($\\|#\\)"
+  "Regular expression matching a blank or comment line.")
+
+(defconst py-outdent-re
+  (concat "\\(" (mapconcat 'identity
+			   '("else:"
+			     "except\\(\\s +.*\\)?:"
+			     "finally:"
+			     "elif\\s +.*:")
+			   "\\|")
+	  "\\)")
+  "Regular expression matching statements to be dedented one level.")
+  
+(defconst py-block-closing-keywords-re
+  "\\(return\\|raise\\|break\\|continue\\|pass\\)"
+  "Regular expression matching keywords which typically close a block.")
+
+(defconst py-no-outdent-re
+  (concat
+   "\\("
+   (mapconcat 'identity
+	      (list "try:"
+		    "except\\(\\s +.*\\)?:"
+		    "while\\s +.*:"
+		    "for\\s +.*:"
+		    "if\\s +.*:"
+		    "elif\\s +.*:"
+		    (concat py-block-closing-keywords-re "[ \t\n]")
+		    )
+	      "\\|")
+	  "\\)")
+  "Regular expression matching lines not to dedent after.")
+
+(defconst py-defun-start-re
+  "^\\([ \t]*\\)def[ \t]+\\([a-zA-Z_0-9]+\\)\\|\\(^[a-zA-Z_0-9]+\\)[ \t]*="
+  ;; If you change this, you probably have to change py-current-defun
+  ;; as well.  This is only used by py-current-defun to find the name
+  ;; for add-log.el.
+  "Regular expression matching a function, method, or variable assignment.")
+
+(defconst py-class-start-re "^class[ \t]*\\([a-zA-Z_0-9]+\\)"
+  ;; If you change this, you probably have to change py-current-defun
+  ;; as well.  This is only used by py-current-defun to find the name
+  ;; for add-log.el.
+  "Regular expression for finding a class name.")
+
+(defconst py-traceback-line-re
+  "[ \t]+File \"\\([^\"]+\\)\", line \\([0-9]+\\)"
+  "Regular expression that describes tracebacks.")
+
+;; pdbtrack contants
+(defconst py-pdbtrack-stack-entry-regexp
+;  "^> \\([^(]+\\)(\\([0-9]+\\))\\([?a-zA-Z0-9_]+\\)()"
+  "^> \\(.*\\)(\\([0-9]+\\))\\([?a-zA-Z0-9_]+\\)()"
+  "Regular expression pdbtrack uses to find a stack trace entry.")
+
+(defconst py-pdbtrack-input-prompt "\n[(<]*pdb[>)]+ "
+  "Regular expression pdbtrack uses to recognize a pdb prompt.")
+
+(defconst py-pdbtrack-track-range 10000
+  "Max number of characters from end of buffer to search for stack entry.")
+
+
+
+;; Major mode boilerplate
+
+;; define a mode-specific abbrev table for those who use such things
+(defvar python-mode-abbrev-table nil
+  "Abbrev table in use in `python-mode' buffers.")
+(define-abbrev-table 'python-mode-abbrev-table nil)
+
+(defvar python-mode-hook nil
+  "*Hook called by `python-mode'.")
+
+(defvar jpython-mode-hook nil
+  "*Hook called by `jpython-mode'. `jpython-mode' also calls
+`python-mode-hook'.")
+
+(defvar py-shell-hook nil
+  "*Hook called by `py-shell'.")
+
+;; In previous version of python-mode.el, the hook was incorrectly
+;; called py-mode-hook, and was not defvar'd.  Deprecate its use.
+(and (fboundp 'make-obsolete-variable)
+     (make-obsolete-variable 'py-mode-hook 'python-mode-hook))
+
+(defvar py-mode-map ()
+  "Keymap used in `python-mode' buffers.")
+(if py-mode-map
+    nil
+  (setq py-mode-map (make-sparse-keymap))
+  ;; electric keys
+  (define-key py-mode-map ":" 'py-electric-colon)
+  ;; indentation level modifiers
+  (define-key py-mode-map "\C-c\C-l"  'py-shift-region-left)
+  (define-key py-mode-map "\C-c\C-r"  'py-shift-region-right)
+  (define-key py-mode-map "\C-c<"     'py-shift-region-left)
+  (define-key py-mode-map "\C-c>"     'py-shift-region-right)
+  ;; paragraph and string filling
+  (define-key py-mode-map "\eq"       'py-fill-paragraph)
+  ;; subprocess commands
+  (define-key py-mode-map "\C-c\C-c"  'py-execute-buffer)
+  (define-key py-mode-map "\C-c\C-m"  'py-execute-import-or-reload)
+  (define-key py-mode-map "\C-c\C-s"  'py-execute-string)
+  (define-key py-mode-map "\C-c|"     'py-execute-region)
+  (define-key py-mode-map "\e\C-x"    'py-execute-def-or-class)
+  (define-key py-mode-map "\C-c!"     'py-shell)
+  (define-key py-mode-map "\C-c\C-t"  'py-toggle-shells)
+  ;; Caution!  Enter here at your own risk.  We are trying to support
+  ;; several behaviors and it gets disgusting. :-( This logic ripped
+  ;; largely from CC Mode.
+  ;;
+  ;; In XEmacs 19, Emacs 19, and Emacs 20, we use this to bind
+  ;; backwards deletion behavior to DEL, which both Delete and
+  ;; Backspace get translated to.  There's no way to separate this
+  ;; behavior in a clean way, so deal with it!  Besides, it's been
+  ;; this way since the dawn of time.
+  (if (not (boundp 'delete-key-deletes-forward))
+      (define-key py-mode-map "\177" 'py-electric-backspace)
+    ;; However, XEmacs 20 actually achieved enlightenment.  It is
+    ;; possible to sanely define both backward and forward deletion
+    ;; behavior under X separately (TTYs are forever beyond hope, but
+    ;; who cares?  XEmacs 20 does the right thing with these too).
+    (define-key py-mode-map [delete]    'py-electric-delete)
+    (define-key py-mode-map [backspace] 'py-electric-backspace))
+  ;; Separate M-BS from C-M-h.  The former should remain
+  ;; backward-kill-word.
+  (define-key py-mode-map [(control meta h)] 'py-mark-def-or-class)
+  (define-key py-mode-map "\C-c\C-k"  'py-mark-block)
+  ;; Miscellaneous
+  (define-key py-mode-map "\C-c:"     'py-guess-indent-offset)
+  (define-key py-mode-map "\C-c\t"    'py-indent-region)
+  (define-key py-mode-map "\C-c\C-d"  'py-pdbtrack-toggle-stack-tracking)
+  (define-key py-mode-map "\C-c\C-n"  'py-next-statement)
+  (define-key py-mode-map "\C-c\C-p"  'py-previous-statement)
+  (define-key py-mode-map "\C-c\C-u"  'py-goto-block-up)
+  (define-key py-mode-map "\C-c#"     'py-comment-region)
+  (define-key py-mode-map "\C-c?"     'py-describe-mode)
+  (define-key py-mode-map "\C-c\C-h"  'py-help-at-point)
+  (define-key py-mode-map "\e\C-a"    'py-beginning-of-def-or-class)
+  (define-key py-mode-map "\e\C-e"    'py-end-of-def-or-class)
+  (define-key py-mode-map "\C-c-"     'py-up-exception)
+  (define-key py-mode-map "\C-c="     'py-down-exception)
+  ;; stuff that is `standard' but doesn't interface well with
+  ;; python-mode, which forces us to rebind to special commands
+  (define-key py-mode-map "\C-xnd"    'py-narrow-to-defun)
+  ;; information
+  (define-key py-mode-map "\C-c\C-b" 'py-submit-bug-report)
+  (define-key py-mode-map "\C-c\C-v" 'py-version)
+  (define-key py-mode-map "\C-c\C-w" 'py-pychecker-run)
+  ;; shadow global bindings for newline-and-indent w/ the py- version.
+  ;; BAW - this is extremely bad form, but I'm not going to change it
+  ;; for now.
+  (mapcar #'(lambda (key)
+	      (define-key py-mode-map key 'py-newline-and-indent))
+	  (where-is-internal 'newline-and-indent))
+  ;; Force RET to be py-newline-and-indent even if it didn't get
+  ;; mapped by the above code.  motivation: Emacs' default binding for
+  ;; RET is `newline' and C-j is `newline-and-indent'.  Most Pythoneers
+  ;; expect RET to do a `py-newline-and-indent' and any Emacsers who
+  ;; dislike this are probably knowledgeable enough to do a rebind.
+  ;; However, we do *not* change C-j since many Emacsers have already
+  ;; swapped RET and C-j and they don't want C-j bound to `newline' to 
+  ;; change.
+  (define-key py-mode-map "\C-m" 'py-newline-and-indent)
+  )
+
+(defvar py-mode-output-map nil
+  "Keymap used in *Python Output* buffers.")
+(if py-mode-output-map
+    nil
+  (setq py-mode-output-map (make-sparse-keymap))
+  (define-key py-mode-output-map [button2]  'py-mouseto-exception)
+  (define-key py-mode-output-map "\C-c\C-c" 'py-goto-exception)
+  ;; TBD: Disable all self-inserting keys.  This is bogus, we should
+  ;; really implement this as *Python Output* buffer being read-only
+  (mapcar #' (lambda (key)
+	       (define-key py-mode-output-map key
+		 #'(lambda () (interactive) (beep))))
+	     (where-is-internal 'self-insert-command))
+  )
+
+(defvar py-shell-map nil
+  "Keymap used in *Python* shell buffers.")
+(if py-shell-map
+    nil
+  (setq py-shell-map (copy-keymap comint-mode-map))
+  (define-key py-shell-map [tab]   'tab-to-tab-stop)
+  (define-key py-shell-map "\C-c-" 'py-up-exception)
+  (define-key py-shell-map "\C-c=" 'py-down-exception)
+  )
+
+(defvar py-mode-syntax-table nil
+  "Syntax table used in `python-mode' buffers.")
+(when (not py-mode-syntax-table)
+  (setq py-mode-syntax-table (make-syntax-table))
+  (modify-syntax-entry ?\( "()" py-mode-syntax-table)
+  (modify-syntax-entry ?\) ")(" py-mode-syntax-table)
+  (modify-syntax-entry ?\[ "(]" py-mode-syntax-table)
+  (modify-syntax-entry ?\] ")[" py-mode-syntax-table)
+  (modify-syntax-entry ?\{ "(}" py-mode-syntax-table)
+  (modify-syntax-entry ?\} "){" py-mode-syntax-table)
+  ;; Add operator symbols misassigned in the std table
+  (modify-syntax-entry ?\$ "."  py-mode-syntax-table)
+  (modify-syntax-entry ?\% "."  py-mode-syntax-table)
+  (modify-syntax-entry ?\& "."  py-mode-syntax-table)
+  (modify-syntax-entry ?\* "."  py-mode-syntax-table)
+  (modify-syntax-entry ?\+ "."  py-mode-syntax-table)
+  (modify-syntax-entry ?\- "."  py-mode-syntax-table)
+  (modify-syntax-entry ?\/ "."  py-mode-syntax-table)
+  (modify-syntax-entry ?\< "."  py-mode-syntax-table)
+  (modify-syntax-entry ?\= "."  py-mode-syntax-table)
+  (modify-syntax-entry ?\> "."  py-mode-syntax-table)
+  (modify-syntax-entry ?\| "."  py-mode-syntax-table)
+  ;; For historical reasons, underscore is word class instead of
+  ;; symbol class.  GNU conventions say it should be symbol class, but
+  ;; there's a natural conflict between what major mode authors want
+  ;; and what users expect from `forward-word' and `backward-word'.
+  ;; Guido and I have hashed this out and have decided to keep
+  ;; underscore in word class.  If you're tempted to change it, try
+  ;; binding M-f and M-b to py-forward-into-nomenclature and
+  ;; py-backward-into-nomenclature instead.  This doesn't help in all
+  ;; situations where you'd want the different behavior
+  ;; (e.g. backward-kill-word).
+  (modify-syntax-entry ?\_ "w"  py-mode-syntax-table)
+  ;; Both single quote and double quote are string delimiters
+  (modify-syntax-entry ?\' "\"" py-mode-syntax-table)
+  (modify-syntax-entry ?\" "\"" py-mode-syntax-table)
+  ;; backquote is open and close paren
+  (modify-syntax-entry ?\` "$"  py-mode-syntax-table)
+  ;; comment delimiters
+  (modify-syntax-entry ?\# "<"  py-mode-syntax-table)
+  (modify-syntax-entry ?\n ">"  py-mode-syntax-table)
+  )
+
+;; An auxiliary syntax table which places underscore and dot in the
+;; symbol class for simplicity
+(defvar py-dotted-expression-syntax-table nil
+  "Syntax table used to identify Python dotted expressions.")
+(when (not py-dotted-expression-syntax-table)
+  (setq py-dotted-expression-syntax-table
+	(copy-syntax-table py-mode-syntax-table))
+  (modify-syntax-entry ?_ "_" py-dotted-expression-syntax-table)
+  (modify-syntax-entry ?. "_" py-dotted-expression-syntax-table))
+
+
+
+;; Utilities
+(defmacro py-safe (&rest body)
+  "Safely execute BODY, return nil if an error occurred."
+  (` (condition-case nil
+	 (progn (,@ body))
+       (error nil))))
+
+(defsubst py-keep-region-active ()
+  "Keep the region active in XEmacs."
+  ;; Ignore byte-compiler warnings you might see.  Also note that
+  ;; FSF's Emacs 19 does it differently; its policy doesn't require us
+  ;; to take explicit action.
+  (and (boundp 'zmacs-region-stays)
+       (setq zmacs-region-stays t)))
+
+(defsubst py-point (position)
+  "Returns the value of point at certain commonly referenced POSITIONs.
+POSITION can be one of the following symbols:
+
+  bol  -- beginning of line
+  eol  -- end of line
+  bod  -- beginning of def or class
+  eod  -- end of def or class
+  bob  -- beginning of buffer
+  eob  -- end of buffer
+  boi  -- back to indentation
+  bos  -- beginning of statement
+
+This function does not modify point or mark."
+  (let ((here (point)))
+    (cond
+     ((eq position 'bol) (beginning-of-line))
+     ((eq position 'eol) (end-of-line))
+     ((eq position 'bod) (py-beginning-of-def-or-class))
+     ((eq position 'eod) (py-end-of-def-or-class))
+     ;; Kind of funny, I know, but useful for py-up-exception.
+     ((eq position 'bob) (beginning-of-buffer))
+     ((eq position 'eob) (end-of-buffer))
+     ((eq position 'boi) (back-to-indentation))
+     ((eq position 'bos) (py-goto-initial-line))
+     (t (error "Unknown buffer position requested: %s" position))
+     )
+    (prog1
+	(point)
+      (goto-char here))))
+
+(defsubst py-highlight-line (from to file line)
+  (cond
+   ((fboundp 'make-extent)
+    ;; XEmacs
+    (let ((e (make-extent from to)))
+      (set-extent-property e 'mouse-face 'highlight)
+      (set-extent-property e 'py-exc-info (cons file line))
+      (set-extent-property e 'keymap py-mode-output-map)))
+   (t
+    ;; Emacs -- Please port this!
+    )
+   ))
+
+(defun py-in-literal (&optional lim)
+  "Return non-nil if point is in a Python literal (a comment or string).
+Optional argument LIM indicates the beginning of the containing form,
+i.e. the limit on how far back to scan."
+  ;; This is the version used for non-XEmacs, which has a nicer
+  ;; interface.
+  ;;
+  ;; WARNING: Watch out for infinite recursion.
+  (let* ((lim (or lim (py-point 'bod)))
+	 (state (parse-partial-sexp lim (point))))
+    (cond
+     ((nth 3 state) 'string)
+     ((nth 4 state) 'comment)
+     (t nil))))
+
+;; XEmacs has a built-in function that should make this much quicker.
+;; In this case, lim is ignored
+(defun py-fast-in-literal (&optional lim)
+  "Fast version of `py-in-literal', used only by XEmacs.
+Optional LIM is ignored."
+  ;; don't have to worry about context == 'block-comment
+  (buffer-syntactic-context))
+
+(if (fboundp 'buffer-syntactic-context)
+    (defalias 'py-in-literal 'py-fast-in-literal))
+
+
+
+;; Menu definitions, only relevent if you have the easymenu.el package
+;; (standard in the latest Emacs 19 and XEmacs 19 distributions).
+(defvar py-menu nil
+  "Menu for Python Mode.
+This menu will get created automatically if you have the `easymenu'
+package.  Note that the latest X/Emacs releases contain this package.")
+
+(and (py-safe (require 'easymenu) t)
+     (easy-menu-define
+      py-menu py-mode-map "Python Mode menu"
+      '("Python"
+	["Comment Out Region"   py-comment-region  (mark)]
+	["Uncomment Region"     (py-comment-region (point) (mark) '(4)) (mark)]
+	"-"
+	["Mark current block"   py-mark-block t]
+	["Mark current def"     py-mark-def-or-class t]
+	["Mark current class"   (py-mark-def-or-class t) t]
+	"-"
+	["Shift region left"    py-shift-region-left (mark)]
+	["Shift region right"   py-shift-region-right (mark)]
+	"-"
+	["Import/reload file"   py-execute-import-or-reload t]
+	["Execute buffer"       py-execute-buffer t]
+	["Execute region"       py-execute-region (mark)]
+	["Execute def or class" py-execute-def-or-class (mark)]
+	["Execute string"       py-execute-string t]
+	["Start interpreter..." py-shell t]
+	"-"
+	["Go to start of block" py-goto-block-up t]
+	["Go to start of class" (py-beginning-of-def-or-class t) t]
+	["Move to end of class" (py-end-of-def-or-class t) t]
+	["Move to start of def" py-beginning-of-def-or-class t]
+	["Move to end of def"   py-end-of-def-or-class t]
+	"-"
+	["Describe mode"        py-describe-mode t]
+	)))
+
+
+
+;; Imenu definitions
+(defvar py-imenu-class-regexp
+  (concat				; <<classes>>
+   "\\("				;
+   "^[ \t]*"				; newline and maybe whitespace
+   "\\(class[ \t]+[a-zA-Z0-9_]+\\)"	; class name
+					; possibly multiple superclasses
+   "\\([ \t]*\\((\\([a-zA-Z0-9_,. \t\n]\\)*)\\)?\\)"
+   "[ \t]*:"				; and the final :
+   "\\)"				; >>classes<<
+   )
+  "Regexp for Python classes for use with the Imenu package."
+  )
+
+(defvar py-imenu-method-regexp
+  (concat                               ; <<methods and functions>>
+   "\\("                                ; 
+   "^[ \t]*"                            ; new line and maybe whitespace
+   "\\(def[ \t]+"                       ; function definitions start with def
+   "\\([a-zA-Z0-9_]+\\)"                ;   name is here
+					;   function arguments...
+;;   "[ \t]*(\\([-+/a-zA-Z0-9_=,\* \t\n.()\"'#]*\\))"
+   "[ \t]*(\\([^:#]*\\))"
+   "\\)"                                ; end of def
+   "[ \t]*:"                            ; and then the :
+   "\\)"                                ; >>methods and functions<<
+   )
+  "Regexp for Python methods/functions for use with the Imenu package."
+  )
+
+(defvar py-imenu-method-no-arg-parens '(2 8)
+  "Indices into groups of the Python regexp for use with Imenu.
+
+Using these values will result in smaller Imenu lists, as arguments to
+functions are not listed.
+
+See the variable `py-imenu-show-method-args-p' for more
+information.")
+
+(defvar py-imenu-method-arg-parens '(2 7)
+  "Indices into groups of the Python regexp for use with imenu.
+Using these values will result in large Imenu lists, as arguments to
+functions are listed.
+
+See the variable `py-imenu-show-method-args-p' for more
+information.")
+
+;; Note that in this format, this variable can still be used with the
+;; imenu--generic-function. Otherwise, there is no real reason to have
+;; it.
+(defvar py-imenu-generic-expression
+  (cons
+   (concat 
+    py-imenu-class-regexp
+    "\\|"				; or...
+    py-imenu-method-regexp
+    )
+   py-imenu-method-no-arg-parens)
+  "Generic Python expression which may be used directly with Imenu.
+Used by setting the variable `imenu-generic-expression' to this value.
+Also, see the function \\[py-imenu-create-index] for a better
+alternative for finding the index.")
+
+;; These next two variables are used when searching for the Python
+;; class/definitions. Just saving some time in accessing the
+;; generic-python-expression, really.
+(defvar py-imenu-generic-regexp nil)
+(defvar py-imenu-generic-parens nil)
+
+
+(defun py-imenu-create-index-function ()
+  "Python interface function for the Imenu package.
+Finds all Python classes and functions/methods. Calls function
+\\[py-imenu-create-index-engine].  See that function for the details
+of how this works."
+  (setq py-imenu-generic-regexp (car py-imenu-generic-expression)
+	py-imenu-generic-parens (if py-imenu-show-method-args-p
+				    py-imenu-method-arg-parens
+				  py-imenu-method-no-arg-parens))
+  (goto-char (point-min))
+  ;; Warning: When the buffer has no classes or functions, this will
+  ;; return nil, which seems proper according to the Imenu API, but
+  ;; causes an error in the XEmacs port of Imenu.  Sigh.
+  (py-imenu-create-index-engine nil))
+
+(defun py-imenu-create-index-engine (&optional start-indent)
+  "Function for finding Imenu definitions in Python.
+
+Finds all definitions (classes, methods, or functions) in a Python
+file for the Imenu package.
+
+Returns a possibly nested alist of the form
+
+	(INDEX-NAME . INDEX-POSITION)
+
+The second element of the alist may be an alist, producing a nested
+list as in
+
+	(INDEX-NAME . INDEX-ALIST)
+
+This function should not be called directly, as it calls itself
+recursively and requires some setup.  Rather this is the engine for
+the function \\[py-imenu-create-index-function].
+
+It works recursively by looking for all definitions at the current
+indention level.  When it finds one, it adds it to the alist.  If it
+finds a definition at a greater indentation level, it removes the
+previous definition from the alist. In its place it adds all
+definitions found at the next indentation level.  When it finds a
+definition that is less indented then the current level, it returns
+the alist it has created thus far.
+
+The optional argument START-INDENT indicates the starting indentation
+at which to continue looking for Python classes, methods, or
+functions.  If this is not supplied, the function uses the indentation
+of the first definition found."
+  (let (index-alist
+	sub-method-alist
+	looking-p
+	def-name prev-name
+	cur-indent def-pos
+	(class-paren (first  py-imenu-generic-parens)) 
+	(def-paren   (second py-imenu-generic-parens)))
+    (setq looking-p
+	  (re-search-forward py-imenu-generic-regexp (point-max) t))
+    (while looking-p
+      (save-excursion
+	;; used to set def-name to this value but generic-extract-name
+	;; is new to imenu-1.14. this way it still works with
+	;; imenu-1.11
+	;;(imenu--generic-extract-name py-imenu-generic-parens))
+	(let ((cur-paren (if (match-beginning class-paren)
+			     class-paren def-paren)))
+	  (setq def-name
+		(buffer-substring-no-properties (match-beginning cur-paren)
+						(match-end cur-paren))))
+	(save-match-data
+	  (py-beginning-of-def-or-class 'either))
+	(beginning-of-line)
+	(setq cur-indent (current-indentation)))
+      ;; HACK: want to go to the next correct definition location.  We
+      ;; explicitly list them here but it would be better to have them
+      ;; in a list.
+      (setq def-pos
+	    (or (match-beginning class-paren)
+		(match-beginning def-paren)))
+      ;; if we don't have a starting indent level, take this one
+      (or start-indent
+	  (setq start-indent cur-indent))
+      ;; if we don't have class name yet, take this one
+      (or prev-name
+	  (setq prev-name def-name))
+      ;; what level is the next definition on?  must be same, deeper
+      ;; or shallower indentation
+      (cond
+       ;; Skip code in comments and strings
+       ((py-in-literal))
+       ;; at the same indent level, add it to the list...
+       ((= start-indent cur-indent)
+	(push (cons def-name def-pos) index-alist))
+       ;; deeper indented expression, recurse
+       ((< start-indent cur-indent)
+	;; the point is currently on the expression we're supposed to
+	;; start on, so go back to the last expression. The recursive
+	;; call will find this place again and add it to the correct
+	;; list
+	(re-search-backward py-imenu-generic-regexp (point-min) 'move)
+	(setq sub-method-alist (py-imenu-create-index-engine cur-indent))
+	(if sub-method-alist
+	    ;; we put the last element on the index-alist on the start
+	    ;; of the submethod alist so the user can still get to it.
+	    (let ((save-elmt (pop index-alist)))
+	      (push (cons prev-name
+			  (cons save-elmt sub-method-alist))
+		    index-alist))))
+       ;; found less indented expression, we're done.
+       (t 
+	(setq looking-p nil)
+	(re-search-backward py-imenu-generic-regexp (point-min) t)))
+      ;; end-cond
+      (setq prev-name def-name)
+      (and looking-p
+	   (setq looking-p
+		 (re-search-forward py-imenu-generic-regexp
+				    (point-max) 'move))))
+    (nreverse index-alist)))
+
+
+
+(defun py-choose-shell-by-shebang ()
+  "Choose CPython or JPython mode by looking at #! on the first line.
+Returns the appropriate mode function.
+Used by `py-choose-shell', and similar to but distinct from
+`set-auto-mode', though it uses `auto-mode-interpreter-regexp' (if available)."
+  ;; look for an interpreter specified in the first line
+  ;; similar to set-auto-mode (files.el)
+  (let* ((re (if (boundp 'auto-mode-interpreter-regexp)
+		 auto-mode-interpreter-regexp
+	       ;; stolen from Emacs 21.2
+	       "#![ \t]?\\([^ \t\n]*/bin/env[ \t]\\)?\\([^ \t\n]+\\)"))
+	 (interpreter (save-excursion
+			(goto-char (point-min))
+			(if (looking-at re)
+			    (match-string 2)
+			  "")))
+	 elt)
+    ;; Map interpreter name to a mode.
+    (setq elt (assoc (file-name-nondirectory interpreter)
+		     py-shell-alist))
+    (and elt (caddr elt))))
+
+
+
+(defun py-choose-shell-by-import ()
+  "Choose CPython or JPython mode based imports.
+If a file imports any packages in `py-jpython-packages', within
+`py-import-check-point-max' characters from the start of the file,
+return `jpython', otherwise return nil."
+  (let (mode)
+    (save-excursion
+      (goto-char (point-min))
+      (while (and (not mode)
+		  (search-forward-regexp
+		   "^\\(\\(from\\)\\|\\(import\\)\\) \\([^ \t\n.]+\\)"
+		   py-import-check-point-max t))
+	(setq mode (and (member (match-string 4) py-jpython-packages)
+			'jpython
+			))))
+    mode))
+
+
+(defun py-choose-shell ()
+  "Choose CPython or JPython mode. Returns the appropriate mode function.
+This does the following:
+ - look for an interpreter with `py-choose-shell-by-shebang'
+ - examine imports using `py-choose-shell-by-import'
+ - default to the variable `py-default-interpreter'"
+  (interactive)
+  (or (py-choose-shell-by-shebang)
+      (py-choose-shell-by-import)
+      py-default-interpreter
+;      'cpython ;; don't use to py-default-interpreter, because default
+;               ;; is only way to choose CPython
+      ))
+
+
+;;;###autoload
+(defun python-mode ()
+  "Major mode for editing Python files.
+To submit a problem report, enter `\\[py-submit-bug-report]' from a
+`python-mode' buffer.  Do `\\[py-describe-mode]' for detailed
+documentation.  To see what version of `python-mode' you are running,
+enter `\\[py-version]'.
+
+This mode knows about Python indentation, tokens, comments and
+continuation lines.  Paragraphs are separated by blank lines only.
+
+COMMANDS
+\\{py-mode-map}
+VARIABLES
+
+py-indent-offset\t\tindentation increment
+py-block-comment-prefix\t\tcomment string used by `comment-region'
+py-python-command\t\tshell command to invoke Python interpreter
+py-temp-directory\t\tdirectory used for temp files (if needed)
+py-beep-if-tab-change\t\tring the bell if `tab-width' is changed"
+  (interactive)
+  ;; set up local variables
+  (kill-all-local-variables)
+  (make-local-variable 'font-lock-defaults)
+  (make-local-variable 'paragraph-separate)
+  (make-local-variable 'paragraph-start)
+  (make-local-variable 'require-final-newline)
+  (make-local-variable 'comment-start)
+  (make-local-variable 'comment-end)
+  (make-local-variable 'comment-start-skip)
+  (make-local-variable 'comment-column)
+  (make-local-variable 'comment-indent-function)
+  (make-local-variable 'indent-region-function)
+  (make-local-variable 'indent-line-function)
+  (make-local-variable 'add-log-current-defun-function)
+  ;;
+  (set-syntax-table py-mode-syntax-table)
+  (setq major-mode              'python-mode
+	mode-name               "Python"
+	local-abbrev-table      python-mode-abbrev-table
+	font-lock-defaults      '(python-font-lock-keywords)
+	paragraph-separate      "^[ \t]*$"
+	paragraph-start         "^[ \t]*$"
+	require-final-newline   t
+	comment-start           "# "
+	comment-end             ""
+	comment-start-skip      "# *"
+	comment-column          40
+	comment-indent-function 'py-comment-indent-function
+	indent-region-function  'py-indent-region
+	indent-line-function    'py-indent-line
+	;; tell add-log.el how to find the current function/method/variable
+	add-log-current-defun-function 'py-current-defun
+	)
+  (use-local-map py-mode-map)
+  ;; add the menu
+  (if py-menu
+      (easy-menu-add py-menu))
+  ;; Emacs 19 requires this
+  (if (boundp 'comment-multi-line)
+      (setq comment-multi-line nil))
+  ;; Install Imenu if available
+  (when (py-safe (require 'imenu))
+    (setq imenu-create-index-function #'py-imenu-create-index-function)
+    (setq imenu-generic-expression py-imenu-generic-expression)
+    (if (fboundp 'imenu-add-to-menubar)
+	(imenu-add-to-menubar (format "%s-%s" "IM" mode-name)))
+    )
+  ;; Run the mode hook.  Note that py-mode-hook is deprecated.
+  (if python-mode-hook
+      (run-hooks 'python-mode-hook)
+    (run-hooks 'py-mode-hook))
+  ;; Now do the automagical guessing
+  (if py-smart-indentation
+    (let ((offset py-indent-offset))
+      ;; It's okay if this fails to guess a good value
+      (if (and (py-safe (py-guess-indent-offset))
+	       (<= py-indent-offset 8)
+	       (>= py-indent-offset 2))
+	  (setq offset py-indent-offset))
+      (setq py-indent-offset offset)
+      ;; Only turn indent-tabs-mode off if tab-width !=
+      ;; py-indent-offset.  Never turn it on, because the user must
+      ;; have explicitly turned it off.
+      (if (/= tab-width py-indent-offset)
+	  (setq indent-tabs-mode nil))
+      ))
+  ;; Set the default shell if not already set
+  (when (null py-which-shell)
+    (py-toggle-shells (py-choose-shell))))
+
+
+(defun jpython-mode ()
+  "Major mode for editing JPython/Jython files.
+This is a simple wrapper around `python-mode'.
+It runs `jpython-mode-hook' then calls `python-mode.'
+It is added to `interpreter-mode-alist' and `py-choose-shell'.
+"
+  (interactive)
+  (python-mode)
+  (py-toggle-shells 'jpython)
+  (when jpython-mode-hook
+      (run-hooks 'jpython-mode-hook)))
+
+
+;; It's handy to add recognition of Python files to the
+;; interpreter-mode-alist and to auto-mode-alist.  With the former, we
+;; can specify different `derived-modes' based on the #! line, but
+;; with the latter, we can't.  So we just won't add them if they're
+;; already added.
+(let ((modes '(("jpython" . jpython-mode)
+	       ("jython" . jpython-mode)
+	       ("python" . python-mode))))
+  (while modes
+    (when (not (assoc (car modes) interpreter-mode-alist))
+      (push (car modes) interpreter-mode-alist))
+    (setq modes (cdr modes))))
+
+(when (not (or (rassq 'python-mode auto-mode-alist)
+	       (rassq 'jpython-mode auto-mode-alist)))
+  (push '("\\.py$" . python-mode) auto-mode-alist))
+
+
+
+;; electric characters
+(defun py-outdent-p ()
+  "Returns non-nil if the current line should dedent one level."
+  (save-excursion
+    (and (progn (back-to-indentation)
+		(looking-at py-outdent-re))
+	 ;; short circuit infloop on illegal construct
+	 (not (bobp))
+	 (progn (forward-line -1)
+		(py-goto-initial-line)
+		(back-to-indentation)
+		(while (or (looking-at py-blank-or-comment-re)
+			   (bobp))
+		  (backward-to-indentation 1))
+		(not (looking-at py-no-outdent-re)))
+	 )))
+
+(defun py-electric-colon (arg)
+  "Insert a colon.
+In certain cases the line is dedented appropriately.  If a numeric
+argument ARG is provided, that many colons are inserted
+non-electrically.  Electric behavior is inhibited inside a string or
+comment."
+  (interactive "*P")
+  (self-insert-command (prefix-numeric-value arg))
+  ;; are we in a string or comment?
+  (if (save-excursion
+	(let ((pps (parse-partial-sexp (save-excursion
+					 (py-beginning-of-def-or-class)
+					 (point))
+				       (point))))
+	  (not (or (nth 3 pps) (nth 4 pps)))))
+      (save-excursion
+	(let ((here (point))
+	      (outdent 0)
+	      (indent (py-compute-indentation t)))
+	  (if (and (not arg)
+		   (py-outdent-p)
+		   (= indent (save-excursion
+			       (py-next-statement -1)
+			       (py-compute-indentation t)))
+		   )
+	      (setq outdent py-indent-offset))
+	  ;; Don't indent, only dedent.  This assumes that any lines
+	  ;; that are already dedented relative to
+	  ;; py-compute-indentation were put there on purpose.  It's
+	  ;; highly annoying to have `:' indent for you.  Use TAB, C-c
+	  ;; C-l or C-c C-r to adjust.  TBD: Is there a better way to
+	  ;; determine this???
+	  (if (< (current-indentation) indent) nil
+	    (goto-char here)
+	    (beginning-of-line)
+	    (delete-horizontal-space)
+	    (indent-to (- indent outdent))
+	    )))))
+
+
+;; Python subprocess utilities and filters
+(defun py-execute-file (proc filename)
+  "Send to Python interpreter process PROC \"execfile('FILENAME')\".
+Make that process's buffer visible and force display.  Also make
+comint believe the user typed this string so that
+`kill-output-from-shell' does The Right Thing."
+  (let ((curbuf (current-buffer))
+	(procbuf (process-buffer proc))
+;	(comint-scroll-to-bottom-on-output t)
+	(msg (format "## working on region in file %s...\n" filename))
+	(cmd (format "execfile(r'%s')\n" filename)))
+    (unwind-protect
+	(save-excursion
+	  (set-buffer procbuf)
+	  (goto-char (point-max))
+	  (move-marker (process-mark proc) (point))
+	  (funcall (process-filter proc) proc msg))
+      (set-buffer curbuf))
+    (process-send-string proc cmd)))
+
+(defun py-comint-output-filter-function (string)
+  "Watch output for Python prompt and exec next file waiting in queue.
+This function is appropriate for `comint-output-filter-functions'."
+  ;; TBD: this should probably use split-string
+  (when (and (or (string-equal string ">>> ")
+		 (and (>= (length string) 5)
+		      (string-equal (substring string -5) "\n>>> ")))
+	     py-file-queue)
+    (pop-to-buffer (current-buffer))
+    (py-safe (delete-file (car py-file-queue)))
+    (setq py-file-queue (cdr py-file-queue))
+    (if py-file-queue
+	(let ((pyproc (get-buffer-process (current-buffer))))
+	  (py-execute-file pyproc (car py-file-queue))))
+    ))
+
+(defun py-pdbtrack-overlay-arrow (activation)
+  "Activate or de arrow at beginning-of-line in current buffer."
+  ;; This was derived/simplified from edebug-overlay-arrow
+  (cond (activation
+	 (setq overlay-arrow-position (make-marker))
+	 (setq overlay-arrow-string "=>")
+	 (set-marker overlay-arrow-position (py-point 'bol) (current-buffer))
+	 (setq py-pdbtrack-is-tracking-p t))
+	(overlay-arrow-position
+	 (setq overlay-arrow-position nil)
+	 (setq py-pdbtrack-is-tracking-p nil))
+	))
+
+(defun py-pdbtrack-track-stack-file (text)
+  "Show the file indicated by the pdb stack entry line, in a separate window.
+
+Activity is disabled if the buffer-local variable
+`py-pdbtrack-do-tracking-p' is nil.
+
+We depend on the pdb input prompt matching `py-pdbtrack-input-prompt'
+at the beginning of the line.
+
+If the traceback target file path is invalid, we look for the most
+recently visited python-mode buffer which either has the name of the
+current function \(or class) or which defines the function \(or
+class).  This is to provide for remote scripts, eg, Zope's 'Script
+(Python)' - put a _copy_ of the script in a buffer named for the
+script, and set to python-mode, and pdbtrack will find it.)"
+  ;; Instead of trying to piece things together from partial text
+  ;; (which can be almost useless depending on Emacs version), we
+  ;; monitor to the point where we have the next pdb prompt, and then
+  ;; check all text from comint-last-input-end to process-mark.
+  ;;
+  ;; Also, we're very conservative about clearing the overlay arrow,
+  ;; to minimize residue.  This means, for instance, that executing
+  ;; other pdb commands wipe out the highlight.  You can always do a
+  ;; 'where' (aka 'w') command to reveal the overlay arrow.
+  (let* ((origbuf (current-buffer))
+	 (currproc (get-buffer-process origbuf)))
+
+    (if (not (and currproc py-pdbtrack-do-tracking-p))
+        (py-pdbtrack-overlay-arrow nil)
+
+      (let* ((procmark (process-mark currproc))
+             (block (buffer-substring (max comint-last-input-end
+                                           (- procmark
+                                              py-pdbtrack-track-range))
+                                      procmark))
+             target target_fname target_lineno)
+
+        (if (not (string-match (concat py-pdbtrack-input-prompt "$") block))
+            (py-pdbtrack-overlay-arrow nil)
+
+          (setq target (py-pdbtrack-get-source-buffer block))
+
+          (if (stringp target)
+              (message "pdbtrack: %s" target)
+
+            (setq target_lineno (car target))
+            (setq target_buffer (cadr target))
+            (setq target_fname (buffer-file-name target_buffer))
+            (switch-to-buffer-other-window target_buffer)
+            (goto-line target_lineno)
+            (message "pdbtrack: line %s, file %s" target_lineno target_fname)
+            (py-pdbtrack-overlay-arrow t)
+            (pop-to-buffer origbuf t)
+
+            )))))
+  )
+
+(defun py-pdbtrack-get-source-buffer (block)
+  "Return line number and buffer of code indicated by block's traceback text.
+
+We look first to visit the file indicated in the trace.
+
+Failing that, we look for the most recently visited python-mode buffer
+with the same name or having 
+having the named function.
+
+If we're unable find the source code we return a string describing the
+problem as best as we can determine."
+
+  (if (not (string-match py-pdbtrack-stack-entry-regexp block))
+
+      "Traceback cue not found"
+
+    (let* ((filename (match-string 1 block))
+           (lineno (string-to-int (match-string 2 block)))
+           (funcname (match-string 3 block))
+           funcbuffer)
+
+      (cond ((file-exists-p filename)
+             (list lineno (find-file-noselect filename)))
+
+            ((setq funcbuffer (py-pdbtrack-grub-for-buffer funcname lineno))
+             (if (string-match "/Script (Python)$" filename)
+                 ;; Add in number of lines for leading '##' comments:
+                 (setq lineno
+                       (+ lineno
+                          (save-excursion
+                            (set-buffer funcbuffer)
+                            (count-lines
+                             (point-min)
+                             (max (point-min)
+                                  (string-match "^\\([^#]\\|#[^#]\\|#$\\)"
+                                                (buffer-substring (point-min)
+                                                                  (point-max)))
+                                  ))))))
+             (list lineno funcbuffer))
+
+            ((= (elt filename 0) ?\<)
+             (format "(Non-file source: '%s')" filename))
+
+            (t (format "Not found: %s(), %s" funcname filename)))
+      )
+    )
+  )
+
+(defun py-pdbtrack-grub-for-buffer (funcname lineno)
+  "Find most recent buffer itself named or having function funcname.
+
+We first check the last buffer this function found, if any, then walk
+throught the buffer-list history for python-mode buffers that are
+named for funcname or define a function funcname."
+  (let ((buffers (buffer-list))
+        curbuf
+        got)
+    (while (and buffers (not got))
+      (setq buf (car buffers)
+            buffers (cdr buffers))
+      (if (and (save-excursion (set-buffer buf)
+                               (string= major-mode "python-mode"))
+               (or (string-match funcname (buffer-name buf))
+                   (string-match (concat "^\\s-*\\(def\\|class\\)\\s-+"
+                                         funcname "\\s-*(")
+                                 (save-excursion
+                                   (set-buffer buf)
+                                   (buffer-substring (point-min)
+                                                     (point-max))))))
+          (setq got buf)))
+    (setq py-pdbtrack-last-grubbed-buffer got)))
+
+(defun py-postprocess-output-buffer (buf)
+  "Highlight exceptions found in BUF.
+If an exception occurred return t, otherwise return nil.  BUF must exist."
+  (let (line file bol err-p)
+    (save-excursion
+      (set-buffer buf)
+      (beginning-of-buffer)
+      (while (re-search-forward py-traceback-line-re nil t)
+	(setq file (match-string 1)
+	      line (string-to-int (match-string 2))
+	      bol (py-point 'bol))
+	(py-highlight-line bol (py-point 'eol) file line)))
+    (when (and py-jump-on-exception line)
+      (beep)
+      (py-jump-to-exception file line)
+      (setq err-p t))
+    err-p))
+
+
+
+;;; Subprocess commands
+
+;; only used when (memq 'broken-temp-names py-emacs-features)
+(defvar py-serial-number 0)
+(defvar py-exception-buffer nil)
+(defconst py-output-buffer "*Python Output*")
+(make-variable-buffer-local 'py-output-buffer)
+
+;; for toggling between CPython and JPython
+(defvar py-which-shell nil)
+(defvar py-which-args  py-python-command-args)
+(defvar py-which-bufname "Python")
+(make-variable-buffer-local 'py-which-shell)
+(make-variable-buffer-local 'py-which-args)
+(make-variable-buffer-local 'py-which-bufname)
+
+(defun py-toggle-shells (arg)
+  "Toggles between the CPython and JPython shells.
+
+With positive argument ARG (interactively \\[universal-argument]),
+uses the CPython shell, with negative ARG uses the JPython shell, and
+with a zero argument, toggles the shell.
+
+Programmatically, ARG can also be one of the symbols `cpython' or
+`jpython', equivalent to positive arg and negative arg respectively."
+  (interactive "P")
+  ;; default is to toggle
+  (if (null arg)
+      (setq arg 0))
+  ;; preprocess arg
+  (cond
+   ((equal arg 0)
+    ;; toggle
+    (if (string-equal py-which-bufname "Python")
+	(setq arg -1)
+      (setq arg 1)))
+   ((equal arg 'cpython) (setq arg 1))
+   ((equal arg 'jpython) (setq arg -1)))
+  (let (msg)
+    (cond
+     ((< 0 arg)
+      ;; set to CPython
+      (setq py-which-shell py-python-command
+	    py-which-args py-python-command-args
+	    py-which-bufname "Python"
+	    msg "CPython"
+	    mode-name "Python"))
+     ((> 0 arg)
+      (setq py-which-shell py-jpython-command
+	    py-which-args py-jpython-command-args
+	    py-which-bufname "JPython"
+	    msg "JPython"
+	    mode-name "JPython"))
+     )
+    (message "Using the %s shell" msg)
+    (setq py-output-buffer (format "*%s Output*" py-which-bufname))))
+
+;;;###autoload
+(defun py-shell (&optional argprompt)
+  "Start an interactive Python interpreter in another window.
+This is like Shell mode, except that Python is running in the window
+instead of a shell.  See the `Interactive Shell' and `Shell Mode'
+sections of the Emacs manual for details, especially for the key
+bindings active in the `*Python*' buffer.
+
+With optional \\[universal-argument], the user is prompted for the
+flags to pass to the Python interpreter.  This has no effect when this
+command is used to switch to an existing process, only when a new
+process is started.  If you use this, you will probably want to ensure
+that the current arguments are retained (they will be included in the
+prompt).  This argument is ignored when this function is called
+programmatically, or when running in Emacs 19.34 or older.
+
+Note: You can toggle between using the CPython interpreter and the
+JPython interpreter by hitting \\[py-toggle-shells].  This toggles
+buffer local variables which control whether all your subshell
+interactions happen to the `*JPython*' or `*Python*' buffers (the
+latter is the name used for the CPython buffer).
+
+Warning: Don't use an interactive Python if you change sys.ps1 or
+sys.ps2 from their default values, or if you're running code that
+prints `>>> ' or `... ' at the start of a line.  `python-mode' can't
+distinguish your output from Python's output, and assumes that `>>> '
+at the start of a line is a prompt from Python.  Similarly, the Emacs
+Shell mode code assumes that both `>>> ' and `... ' at the start of a
+line are Python prompts.  Bad things can happen if you fool either
+mode.
+
+Warning:  If you do any editing *in* the process buffer *while* the
+buffer is accepting output from Python, do NOT attempt to `undo' the
+changes.  Some of the output (nowhere near the parts you changed!) may
+be lost if you do.  This appears to be an Emacs bug, an unfortunate
+interaction between undo and process filters; the same problem exists in
+non-Python process buffers using the default (Emacs-supplied) process
+filter."
+  (interactive "P")
+  ;; Set the default shell if not already set
+  (when (null py-which-shell)
+    (py-toggle-shells py-default-interpreter))
+  (let ((args py-which-args))
+    (when (and argprompt
+	       (interactive-p)
+	       (fboundp 'split-string))
+      ;; TBD: Perhaps force "-i" in the final list?
+      (setq args (split-string
+		  (read-string (concat py-which-bufname
+				       " arguments: ")
+			       (concat
+				(mapconcat 'identity py-which-args " ") " ")
+			       ))))
+    (switch-to-buffer-other-window
+     (apply 'make-comint py-which-bufname py-which-shell nil args))
+    (make-local-variable 'comint-prompt-regexp)
+    (setq comint-prompt-regexp "^>>> \\|^[.][.][.] \\|^(pdb) ")
+    (add-hook 'comint-output-filter-functions
+	      'py-comint-output-filter-function)
+    ;; pdbtrack
+    (add-hook 'comint-output-filter-functions 'py-pdbtrack-track-stack-file)
+    (setq py-pdbtrack-do-tracking-p t)
+    (set-syntax-table py-mode-syntax-table)
+    (use-local-map py-shell-map)
+    (run-hooks 'py-shell-hook)
+    ))
+
+(defun py-clear-queue ()
+  "Clear the queue of temporary files waiting to execute."
+  (interactive)
+  (let ((n (length py-file-queue)))
+    (mapcar 'delete-file py-file-queue)
+    (setq py-file-queue nil)
+    (message "%d pending files de-queued." n)))
+
+
+(defun py-execute-region (start end &optional async)
+  "Execute the region in a Python interpreter.
+
+The region is first copied into a temporary file (in the directory
+`py-temp-directory').  If there is no Python interpreter shell
+running, this file is executed synchronously using
+`shell-command-on-region'.  If the program is long running, use
+\\[universal-argument] to run the command asynchronously in its own
+buffer.
+
+When this function is used programmatically, arguments START and END
+specify the region to execute, and optional third argument ASYNC, if
+non-nil, specifies to run the command asynchronously in its own
+buffer.
+
+If the Python interpreter shell is running, the region is execfile()'d
+in that shell.  If you try to execute regions too quickly,
+`python-mode' will queue them up and execute them one at a time when
+it sees a `>>> ' prompt from Python.  Each time this happens, the
+process buffer is popped into a window (if it's not already in some
+window) so you can see it, and a comment of the form
+
+    \t## working on region in file <name>...
+
+is inserted at the end.  See also the command `py-clear-queue'."
+  (interactive "r\nP")
+  ;; Skip ahead to the first non-blank line
+  (let* ((proc (get-process py-which-bufname))
+	 (temp (if (memq 'broken-temp-names py-emacs-features)
+		   (let
+		       ((sn py-serial-number)
+			(pid (and (fboundp 'emacs-pid) (emacs-pid))))
+		     (setq py-serial-number (1+ py-serial-number))
+		     (if pid
+			 (format "python-%d-%d" sn pid)
+		       (format "python-%d" sn)))
+		 (make-temp-name "python-")))
+	 (file (concat (expand-file-name temp py-temp-directory) ".py"))
+	 (cur (current-buffer))
+	 (buf (get-buffer-create file))
+	 shell)
+    ;; Write the contents of the buffer, watching out for indented regions.
+    (save-excursion
+      (goto-char start)
+      (beginning-of-line)
+      (while (and (looking-at "\\s *$")
+		  (< (point) end))
+	(forward-line 1))
+      (setq start (point))
+      (or (< start end)
+	  (error "Region is empty"))
+      (let ((needs-if (/= (py-point 'bol) (py-point 'boi))))
+	(set-buffer buf)
+	(python-mode)
+	(when needs-if
+	  (insert "if 1:\n"))
+	(insert-buffer-substring cur start end)
+	;; Set the shell either to the #! line command, or to the
+	;; py-which-shell buffer local variable.
+	(setq shell (or (py-choose-shell-by-shebang)
+			(py-choose-shell-by-import)
+			py-which-shell))))
+    (cond
+     ;; always run the code in its own asynchronous subprocess
+     (async
+      ;; User explicitly wants this to run in its own async subprocess
+      (save-excursion
+	(set-buffer buf)
+	(write-region (point-min) (point-max) file nil 'nomsg))
+      (let* ((buf (generate-new-buffer-name py-output-buffer))
+	     ;; TBD: a horrible hack, but why create new Custom variables?
+	     (arg (if (string-equal py-which-bufname "Python")
+		      "-u" "")))
+	(start-process py-which-bufname buf shell arg file)
+	(pop-to-buffer buf)
+	(py-postprocess-output-buffer buf)
+	;; TBD: clean up the temporary file!
+	))
+     ;; if the Python interpreter shell is running, queue it up for
+     ;; execution there.
+     (proc
+      ;; use the existing python shell
+      (save-excursion
+	(set-buffer buf)
+	(write-region (point-min) (point-max) file nil 'nomsg))
+      (if (not py-file-queue)
+	  (py-execute-file proc file)
+	(message "File %s queued for execution" file))
+      (setq py-file-queue (append py-file-queue (list file)))
+      (setq py-exception-buffer (cons file (current-buffer))))
+     (t
+      ;; TBD: a horrible hack, but why create new Custom variables?
+      (let ((cmd (concat shell (if (string-equal py-which-bufname "JPython")
+				   " -" ""))))
+	;; otherwise either run it synchronously in a subprocess
+	(save-excursion
+	  (set-buffer buf)
+	  (shell-command-on-region (point-min) (point-max)
+				   cmd py-output-buffer))
+	;; shell-command-on-region kills the output buffer if it never
+	;; existed and there's no output from the command
+	(if (not (get-buffer py-output-buffer))
+	    (message "No output.")
+	  (setq py-exception-buffer (current-buffer))
+	  (let ((err-p (py-postprocess-output-buffer py-output-buffer)))
+	    (pop-to-buffer py-output-buffer)
+	    (if err-p
+		(pop-to-buffer py-exception-buffer)))
+	  ))
+      ))
+    ;; Clean up after ourselves.
+    (kill-buffer buf)))
+
+
+;; Code execution commands
+(defun py-execute-buffer (&optional async)
+  "Send the contents of the buffer to a Python interpreter.
+If the file local variable `py-master-file' is non-nil, execute the
+named file instead of the buffer's file.
+
+If there is a *Python* process buffer it is used.  If a clipping
+restriction is in effect, only the accessible portion of the buffer is
+sent.  A trailing newline will be supplied if needed.
+
+See the `\\[py-execute-region]' docs for an account of some
+subtleties, including the use of the optional ASYNC argument."
+  (interactive "P")
+  (if py-master-file
+      (let* ((filename (expand-file-name py-master-file))
+	     (buffer (or (get-file-buffer filename)
+			 (find-file-noselect filename))))
+	(set-buffer buffer)))
+  (py-execute-region (point-min) (point-max) async))
+
+(defun py-execute-import-or-reload (&optional async)
+  "Import the current buffer's file in a Python interpreter.
+
+If the file has already been imported, then do reload instead to get
+the latest version.
+
+If the file's name does not end in \".py\", then do execfile instead.
+
+If the current buffer is not visiting a file, do `py-execute-buffer'
+instead.
+
+If the file local variable `py-master-file' is non-nil, import or
+reload the named file instead of the buffer's file.  The file may be
+saved based on the value of `py-execute-import-or-reload-save-p'.
+
+See the `\\[py-execute-region]' docs for an account of some
+subtleties, including the use of the optional ASYNC argument.
+
+This may be preferable to `\\[py-execute-buffer]' because:
+
+ - Definitions stay in their module rather than appearing at top
+   level, where they would clutter the global namespace and not affect
+   uses of qualified names (MODULE.NAME).
+
+ - The Python debugger gets line number information about the functions."
+  (interactive "P")
+  ;; Check file local variable py-master-file
+  (if py-master-file
+      (let* ((filename (expand-file-name py-master-file))
+             (buffer (or (get-file-buffer filename)
+                         (find-file-noselect filename))))
+        (set-buffer buffer)))
+  (let ((file (buffer-file-name (current-buffer))))
+    (if file
+        (progn
+	  ;; Maybe save some buffers
+	  (save-some-buffers (not py-ask-about-save) nil)
+          (py-execute-string
+           (if (string-match "\\.py$" file)
+               (let ((f (file-name-sans-extension
+			 (file-name-nondirectory file))))
+                 (format "if globals().has_key('%s'):\n    reload(%s)\nelse:\n    import %s\n"
+                         f f f))
+             (format "execfile(r'%s')\n" file))
+           async))
+      ;; else
+      (py-execute-buffer async))))
+
+
+(defun py-execute-def-or-class (&optional async)
+  "Send the current function or class definition to a Python interpreter.
+
+If there is a *Python* process buffer it is used.
+
+See the `\\[py-execute-region]' docs for an account of some
+subtleties, including the use of the optional ASYNC argument."
+  (interactive "P")
+  (save-excursion
+    (py-mark-def-or-class)
+    ;; mark is before point
+    (py-execute-region (mark) (point) async)))
+
+
+(defun py-execute-string (string &optional async)
+  "Send the argument STRING to a Python interpreter.
+
+If there is a *Python* process buffer it is used.
+
+See the `\\[py-execute-region]' docs for an account of some
+subtleties, including the use of the optional ASYNC argument."
+  (interactive "sExecute Python command: ")
+  (save-excursion
+    (set-buffer (get-buffer-create
+                 (generate-new-buffer-name " *Python Command*")))
+    (insert string)
+    (py-execute-region (point-min) (point-max) async)))
+
+
+
+(defun py-jump-to-exception (file line)
+  "Jump to the Python code in FILE at LINE."
+  (let ((buffer (cond ((string-equal file "<stdin>")
+		       (if (consp py-exception-buffer)
+			   (cdr py-exception-buffer)
+			 py-exception-buffer))
+		      ((and (consp py-exception-buffer)
+			    (string-equal file (car py-exception-buffer)))
+		       (cdr py-exception-buffer))
+		      ((py-safe (find-file-noselect file)))
+		      ;; could not figure out what file the exception
+		      ;; is pointing to, so prompt for it
+		      (t (find-file (read-file-name "Exception file: "
+						    nil
+						    file t))))))
+    (pop-to-buffer buffer)
+    ;; Force Python mode
+    (if (not (eq major-mode 'python-mode))
+	(python-mode))
+    (goto-line line)
+    (message "Jumping to exception in file %s on line %d" file line)))
+
+(defun py-mouseto-exception (event)
+  "Jump to the code which caused the Python exception at EVENT.
+EVENT is usually a mouse click."
+  (interactive "e")
+  (cond
+   ((fboundp 'event-point)
+    ;; XEmacs
+    (let* ((point (event-point event))
+	   (buffer (event-buffer event))
+	   (e (and point buffer (extent-at point buffer 'py-exc-info)))
+	   (info (and e (extent-property e 'py-exc-info))))
+      (message "Event point: %d, info: %s" point info)
+      (and info
+	   (py-jump-to-exception (car info) (cdr info)))
+      ))
+   ;; Emacs -- Please port this!
+   ))
+
+(defun py-goto-exception ()
+  "Go to the line indicated by the traceback."
+  (interactive)
+  (let (file line)
+    (save-excursion
+      (beginning-of-line)
+      (if (looking-at py-traceback-line-re)
+	  (setq file (match-string 1)
+		line (string-to-int (match-string 2)))))
+    (if (not file)
+	(error "Not on a traceback line"))
+    (py-jump-to-exception file line)))
+
+(defun py-find-next-exception (start buffer searchdir errwhere)
+  "Find the next Python exception and jump to the code that caused it.
+START is the buffer position in BUFFER from which to begin searching
+for an exception.  SEARCHDIR is a function, either
+`re-search-backward' or `re-search-forward' indicating the direction
+to search.  ERRWHERE is used in an error message if the limit (top or
+bottom) of the trackback stack is encountered."
+  (let (file line)
+    (save-excursion
+      (set-buffer buffer)
+      (goto-char (py-point start))
+      (if (funcall searchdir py-traceback-line-re nil t)
+	  (setq file (match-string 1)
+		line (string-to-int (match-string 2)))))
+    (if (and file line)
+	(py-jump-to-exception file line)
+      (error "%s of traceback" errwhere))))
+
+(defun py-down-exception (&optional bottom)
+  "Go to the next line down in the traceback.
+With \\[univeral-argument] (programmatically, optional argument
+BOTTOM), jump to the bottom (innermost) exception in the exception
+stack."
+  (interactive "P")
+  (let* ((proc (get-process "Python"))
+	 (buffer (if proc "*Python*" py-output-buffer)))
+    (if bottom
+	(py-find-next-exception 'eob buffer 're-search-backward "Bottom")
+      (py-find-next-exception 'eol buffer 're-search-forward "Bottom"))))
+
+(defun py-up-exception (&optional top)
+  "Go to the previous line up in the traceback.
+With \\[universal-argument] (programmatically, optional argument TOP)
+jump to the top (outermost) exception in the exception stack."
+  (interactive "P")
+  (let* ((proc (get-process "Python"))
+	 (buffer (if proc "*Python*" py-output-buffer)))
+    (if top
+	(py-find-next-exception 'bob buffer 're-search-forward "Top")
+      (py-find-next-exception 'bol buffer 're-search-backward "Top"))))
+
+
+;; Electric deletion
+(defun py-electric-backspace (arg)
+  "Delete preceding character or levels of indentation.
+Deletion is performed by calling the function in `py-backspace-function'
+with a single argument (the number of characters to delete).
+
+If point is at the leftmost column, delete the preceding newline.
+
+Otherwise, if point is at the leftmost non-whitespace character of a
+line that is neither a continuation line nor a non-indenting comment
+line, or if point is at the end of a blank line, this command reduces
+the indentation to match that of the line that opened the current
+block of code.  The line that opened the block is displayed in the
+echo area to help you keep track of where you are.  With
+\\[universal-argument] dedents that many blocks (but not past column
+zero).
+
+Otherwise the preceding character is deleted, converting a tab to
+spaces if needed so that only a single column position is deleted.
+\\[universal-argument] specifies how many characters to delete;
+default is 1.
+
+When used programmatically, argument ARG specifies the number of
+blocks to dedent, or the number of characters to delete, as indicated
+above."
+  (interactive "*p")
+  (if (or (/= (current-indentation) (current-column))
+	  (bolp)
+	  (py-continuation-line-p)
+;	  (not py-honor-comment-indentation)
+;	  (looking-at "#[^ \t\n]")	; non-indenting #
+	  )
+      (funcall py-backspace-function arg)
+    ;; else indent the same as the colon line that opened the block
+    ;; force non-blank so py-goto-block-up doesn't ignore it
+    (insert-char ?* 1)
+    (backward-char)
+    (let ((base-indent 0)		; indentation of base line
+	  (base-text "")		; and text of base line
+	  (base-found-p nil))
+      (save-excursion
+	(while (< 0 arg)
+	  (condition-case nil		; in case no enclosing block
+	      (progn
+		(py-goto-block-up 'no-mark)
+		(setq base-indent (current-indentation)
+		      base-text   (py-suck-up-leading-text)
+		      base-found-p t))
+	    (error nil))
+	  (setq arg (1- arg))))
+      (delete-char 1)			; toss the dummy character
+      (delete-horizontal-space)
+      (indent-to base-indent)
+      (if base-found-p
+	  (message "Closes block: %s" base-text)))))
+
+
+(defun py-electric-delete (arg)
+  "Delete preceding or following character or levels of whitespace.
+
+The behavior of this function depends on the variable
+`delete-key-deletes-forward'.  If this variable is nil (or does not
+exist, as in older Emacsen and non-XEmacs versions), then this
+function behaves identically to \\[c-electric-backspace].
+
+If `delete-key-deletes-forward' is non-nil and is supported in your
+Emacs, then deletion occurs in the forward direction, by calling the
+function in `py-delete-function'.
+
+\\[universal-argument] (programmatically, argument ARG) specifies the
+number of characters to delete (default is 1)."
+  (interactive "*p")
+  (if (or (and (fboundp 'delete-forward-p) ;XEmacs 21
+	       (delete-forward-p))
+	  (and (boundp 'delete-key-deletes-forward) ;XEmacs 20
+	       delete-key-deletes-forward))
+      (funcall py-delete-function arg)
+    (py-electric-backspace arg)))
+
+;; required for pending-del and delsel modes
+(put 'py-electric-colon 'delete-selection t) ;delsel
+(put 'py-electric-colon 'pending-delete   t) ;pending-del
+(put 'py-electric-backspace 'delete-selection 'supersede) ;delsel
+(put 'py-electric-backspace 'pending-delete   'supersede) ;pending-del
+(put 'py-electric-delete    'delete-selection 'supersede) ;delsel
+(put 'py-electric-delete    'pending-delete   'supersede) ;pending-del
+
+
+
+(defun py-indent-line (&optional arg)
+  "Fix the indentation of the current line according to Python rules.
+With \\[universal-argument] (programmatically, the optional argument
+ARG non-nil), ignore dedenting rules for block closing statements
+(e.g. return, raise, break, continue, pass)
+
+This function is normally bound to `indent-line-function' so
+\\[indent-for-tab-command] will call it."
+  (interactive "P")
+  (let* ((ci (current-indentation))
+	 (move-to-indentation-p (<= (current-column) ci))
+	 (need (py-compute-indentation (not arg))))
+    ;; see if we need to dedent
+    (if (py-outdent-p)
+	(setq need (- need py-indent-offset)))
+    (if (/= ci need)
+	(save-excursion
+	  (beginning-of-line)
+	  (delete-horizontal-space)
+	  (indent-to need)))
+    (if move-to-indentation-p (back-to-indentation))))
+
+(defun py-newline-and-indent ()
+  "Strives to act like the Emacs `newline-and-indent'.
+This is just `strives to' because correct indentation can't be computed
+from scratch for Python code.  In general, deletes the whitespace before
+point, inserts a newline, and takes an educated guess as to how you want
+the new line indented."
+  (interactive)
+  (let ((ci (current-indentation)))
+    (if (< ci (current-column))		; if point beyond indentation
+	(newline-and-indent)
+      ;; else try to act like newline-and-indent "normally" acts
+      (beginning-of-line)
+      (insert-char ?\n 1)
+      (move-to-column ci))))
+
+(defun py-compute-indentation (honor-block-close-p)
+  "Compute Python indentation.
+When HONOR-BLOCK-CLOSE-P is non-nil, statements such as `return',
+`raise', `break', `continue', and `pass' force one level of
+dedenting."
+  (save-excursion
+    (beginning-of-line)
+    (let* ((bod (py-point 'bod))
+	   (pps (parse-partial-sexp bod (point)))
+	   (boipps (parse-partial-sexp bod (py-point 'boi)))
+	   placeholder)
+      (cond
+       ;; are we inside a multi-line string or comment?
+       ((or (and (nth 3 pps) (nth 3 boipps))
+	    (and (nth 4 pps) (nth 4 boipps)))
+	(save-excursion
+	  (if (not py-align-multiline-strings-p) 0
+	    ;; skip back over blank & non-indenting comment lines
+	    ;; note: will skip a blank or non-indenting comment line
+	    ;; that happens to be a continuation line too
+	    (re-search-backward "^[ \t]*\\([^ \t\n#]\\|#[ \t\n]\\)" nil 'move)
+	    (back-to-indentation)
+	    (current-column))))
+       ;; are we on a continuation line?
+       ((py-continuation-line-p)
+	(let ((startpos (point))
+	      (open-bracket-pos (py-nesting-level))
+	      endpos searching found state)
+	  (if open-bracket-pos
+	      (progn
+		;; align with first item in list; else a normal
+		;; indent beyond the line with the open bracket
+		(goto-char (1+ open-bracket-pos)) ; just beyond bracket
+		;; is the first list item on the same line?
+		(skip-chars-forward " \t")
+		(if (null (memq (following-char) '(?\n ?# ?\\)))
+					; yes, so line up with it
+		    (current-column)
+		  ;; first list item on another line, or doesn't exist yet
+		  (forward-line 1)
+		  (while (and (< (point) startpos)
+			      (looking-at "[ \t]*[#\n\\\\]")) ; skip noise
+		    (forward-line 1))
+		  (if (and (< (point) startpos)
+			   (/= startpos
+			       (save-excursion
+				 (goto-char (1+ open-bracket-pos))
+				 (forward-comment (point-max))
+				 (point))))
+		      ;; again mimic the first list item
+		      (current-indentation)
+		    ;; else they're about to enter the first item
+		    (goto-char open-bracket-pos)
+		    (setq placeholder (point))
+		    (py-goto-initial-line)
+		    (py-goto-beginning-of-tqs
+		     (save-excursion (nth 3 (parse-partial-sexp
+					     placeholder (point)))))
+		    (+ (current-indentation) py-indent-offset))))
+
+	    ;; else on backslash continuation line
+	    (forward-line -1)
+	    (if (py-continuation-line-p) ; on at least 3rd line in block
+		(current-indentation)	; so just continue the pattern
+	      ;; else started on 2nd line in block, so indent more.
+	      ;; if base line is an assignment with a start on a RHS,
+	      ;; indent to 2 beyond the leftmost "="; else skip first
+	      ;; chunk of non-whitespace characters on base line, + 1 more
+	      ;; column
+	      (end-of-line)
+	      (setq endpos (point)
+		    searching t)
+	      (back-to-indentation)
+	      (setq startpos (point))
+	      ;; look at all "=" from left to right, stopping at first
+	      ;; one not nested in a list or string
+	      (while searching
+		(skip-chars-forward "^=" endpos)
+		(if (= (point) endpos)
+		    (setq searching nil)
+		  (forward-char 1)
+		  (setq state (parse-partial-sexp startpos (point)))
+		  (if (and (zerop (car state)) ; not in a bracket
+			   (null (nth 3 state))) ; & not in a string
+		      (progn
+			(setq searching nil) ; done searching in any case
+			(setq found
+			      (not (or
+				    (eq (following-char) ?=)
+				    (memq (char-after (- (point) 2))
+					  '(?< ?> ?!)))))))))
+	      (if (or (not found)	; not an assignment
+		      (looking-at "[ \t]*\\\\")) ; <=><spaces><backslash>
+		  (progn
+		    (goto-char startpos)
+		    (skip-chars-forward "^ \t\n")))
+	      ;; if this is a continuation for a block opening
+	      ;; statement, add some extra offset.
+	      (+ (current-column) (if (py-statement-opens-block-p)
+				      py-continuation-offset 0)
+		 1)
+	      ))))
+
+       ;; not on a continuation line
+       ((bobp) (current-indentation))
+
+       ;; Dfn: "Indenting comment line".  A line containing only a
+       ;; comment, but which is treated like a statement for
+       ;; indentation calculation purposes.  Such lines are only
+       ;; treated specially by the mode; they are not treated
+       ;; specially by the Python interpreter.
+
+       ;; The rules for indenting comment lines are a line where:
+       ;;   - the first non-whitespace character is `#', and
+       ;;   - the character following the `#' is whitespace, and
+       ;;   - the line is dedented with respect to (i.e. to the left
+       ;;     of) the indentation of the preceding non-blank line.
+
+       ;; The first non-blank line following an indenting comment
+       ;; line is given the same amount of indentation as the
+       ;; indenting comment line.
+
+       ;; All other comment-only lines are ignored for indentation
+       ;; purposes.
+
+       ;; Are we looking at a comment-only line which is *not* an
+       ;; indenting comment line?  If so, we assume that it's been
+       ;; placed at the desired indentation, so leave it alone.
+       ;; Indenting comment lines are aligned as statements down
+       ;; below.
+       ((and (looking-at "[ \t]*#[^ \t\n]")
+	     ;; NOTE: this test will not be performed in older Emacsen
+	     (fboundp 'forward-comment)
+	     (<= (current-indentation)
+		 (save-excursion
+		   (forward-comment (- (point-max)))
+		   (current-indentation))))
+	(current-indentation))
+
+       ;; else indentation based on that of the statement that
+       ;; precedes us; use the first line of that statement to
+       ;; establish the base, in case the user forced a non-std
+       ;; indentation for the continuation lines (if any)
+       (t
+	;; skip back over blank & non-indenting comment lines note:
+	;; will skip a blank or non-indenting comment line that
+	;; happens to be a continuation line too.  use fast Emacs 19
+	;; function if it's there.
+	(if (and (eq py-honor-comment-indentation nil)
+		 (fboundp 'forward-comment))
+	    (forward-comment (- (point-max)))
+	  (let ((prefix-re (concat py-block-comment-prefix "[ \t]*"))
+		done)
+	    (while (not done)
+	      (re-search-backward "^[ \t]*\\([^ \t\n#]\\|#\\)" nil 'move)
+	      (setq done (or (bobp)
+			     (and (eq py-honor-comment-indentation t)
+				  (save-excursion
+				    (back-to-indentation)
+				    (not (looking-at prefix-re))
+				    ))
+			     (and (not (eq py-honor-comment-indentation t))
+				  (save-excursion
+				    (back-to-indentation)
+				    (and (not (looking-at prefix-re))
+					 (or (looking-at "[^#]")
+					     (not (zerop (current-column)))
+					     ))
+				    ))
+			     ))
+	      )))
+	;; if we landed inside a string, go to the beginning of that
+	;; string. this handles triple quoted, multi-line spanning
+	;; strings.
+	(py-goto-beginning-of-tqs (nth 3 (parse-partial-sexp bod (point))))
+	;; now skip backward over continued lines
+	(setq placeholder (point))
+	(py-goto-initial-line)
+	;; we may *now* have landed in a TQS, so find the beginning of
+	;; this string.
+	(py-goto-beginning-of-tqs
+	 (save-excursion (nth 3 (parse-partial-sexp
+				 placeholder (point)))))
+	(+ (current-indentation)
+	   (if (py-statement-opens-block-p)
+	       py-indent-offset
+	     (if (and honor-block-close-p (py-statement-closes-block-p))
+		 (- py-indent-offset)
+	       0)))
+	)))))
+
+(defun py-guess-indent-offset (&optional global)
+  "Guess a good value for, and change, `py-indent-offset'.
+
+By default, make a buffer-local copy of `py-indent-offset' with the
+new value, so that other Python buffers are not affected.  With
+\\[universal-argument] (programmatically, optional argument GLOBAL),
+change the global value of `py-indent-offset'.  This affects all
+Python buffers (that don't have their own buffer-local copy), both
+those currently existing and those created later in the Emacs session.
+
+Some people use a different value for `py-indent-offset' than you use.
+There's no excuse for such foolishness, but sometimes you have to deal
+with their ugly code anyway.  This function examines the file and sets
+`py-indent-offset' to what it thinks it was when they created the
+mess.
+
+Specifically, it searches forward from the statement containing point,
+looking for a line that opens a block of code.  `py-indent-offset' is
+set to the difference in indentation between that line and the Python
+statement following it.  If the search doesn't succeed going forward,
+it's tried again going backward."
+  (interactive "P")			; raw prefix arg
+  (let (new-value
+	(start (point))
+	(restart (point))
+	(found nil)
+	colon-indent)
+    (py-goto-initial-line)
+    (while (not (or found (eobp)))
+      (when (and (re-search-forward ":[ \t]*\\($\\|[#\\]\\)" nil 'move)
+		 (not (py-in-literal restart)))
+	(setq restart (point))
+	(py-goto-initial-line)
+	(if (py-statement-opens-block-p)
+	    (setq found t)
+	  (goto-char restart))))
+    (unless found
+      (goto-char start)
+      (py-goto-initial-line)
+      (while (not (or found (bobp)))
+	(setq found (and
+		     (re-search-backward ":[ \t]*\\($\\|[#\\]\\)" nil 'move)
+		     (or (py-goto-initial-line) t) ; always true -- side effect
+		     (py-statement-opens-block-p)))))
+    (setq colon-indent (current-indentation)
+	  found (and found (zerop (py-next-statement 1)))
+	  new-value (- (current-indentation) colon-indent))
+    (goto-char start)
+    (if (not found)
+	(error "Sorry, couldn't guess a value for py-indent-offset")
+      (funcall (if global 'kill-local-variable 'make-local-variable)
+	       'py-indent-offset)
+      (setq py-indent-offset new-value)
+      (or noninteractive
+	  (message "%s value of py-indent-offset set to %d"
+		   (if global "Global" "Local")
+		   py-indent-offset)))
+    ))
+
+(defun py-comment-indent-function ()
+  "Python version of `comment-indent-function'."
+  ;; This is required when filladapt is turned off.  Without it, when
+  ;; filladapt is not used, comments which start in column zero
+  ;; cascade one character to the right
+  (save-excursion
+    (beginning-of-line)
+    (let ((eol (py-point 'eol)))
+      (and comment-start-skip
+	   (re-search-forward comment-start-skip eol t)
+	   (setq eol (match-beginning 0)))
+      (goto-char eol)
+      (skip-chars-backward " \t")
+      (max comment-column (+ (current-column) (if (bolp) 0 1)))
+      )))
+
+(defun py-narrow-to-defun (&optional class)
+  "Make text outside current defun invisible.
+The defun visible is the one that contains point or follows point.
+Optional CLASS is passed directly to `py-beginning-of-def-or-class'."
+  (interactive "P")
+  (save-excursion
+    (widen)
+    (py-end-of-def-or-class class)
+    (let ((end (point)))
+      (py-beginning-of-def-or-class class)
+      (narrow-to-region (point) end))))
+
+
+(defun py-shift-region (start end count)
+  "Indent lines from START to END by COUNT spaces."
+  (save-excursion
+    (goto-char end)
+    (beginning-of-line)
+    (setq end (point))
+    (goto-char start)
+    (beginning-of-line)
+    (setq start (point))
+    (indent-rigidly start end count)))
+
+(defun py-shift-region-left (start end &optional count)
+  "Shift region of Python code to the left.
+The lines from the line containing the start of the current region up
+to (but not including) the line containing the end of the region are
+shifted to the left, by `py-indent-offset' columns.
+
+If a prefix argument is given, the region is instead shifted by that
+many columns.  With no active region, dedent only the current line.
+You cannot dedent the region if any line is already at column zero."
+  (interactive
+   (let ((p (point))
+	 (m (mark))
+	 (arg current-prefix-arg))
+     (if m
+	 (list (min p m) (max p m) arg)
+       (list p (save-excursion (forward-line 1) (point)) arg))))
+  ;; if any line is at column zero, don't shift the region
+  (save-excursion
+    (goto-char start)
+    (while (< (point) end)
+      (back-to-indentation)
+      (if (and (zerop (current-column))
+	       (not (looking-at "\\s *$")))
+	  (error "Region is at left edge"))
+      (forward-line 1)))
+  (py-shift-region start end (- (prefix-numeric-value
+				 (or count py-indent-offset))))
+  (py-keep-region-active))
+
+(defun py-shift-region-right (start end &optional count)
+  "Shift region of Python code to the right.
+The lines from the line containing the start of the current region up
+to (but not including) the line containing the end of the region are
+shifted to the right, by `py-indent-offset' columns.
+
+If a prefix argument is given, the region is instead shifted by that
+many columns.  With no active region, indent only the current line."
+  (interactive
+   (let ((p (point))
+	 (m (mark))
+	 (arg current-prefix-arg))
+     (if m
+	 (list (min p m) (max p m) arg)
+       (list p (save-excursion (forward-line 1) (point)) arg))))
+  (py-shift-region start end (prefix-numeric-value
+			      (or count py-indent-offset)))
+  (py-keep-region-active))
+
+(defun py-indent-region (start end &optional indent-offset)
+  "Reindent a region of Python code.
+
+The lines from the line containing the start of the current region up
+to (but not including) the line containing the end of the region are
+reindented.  If the first line of the region has a non-whitespace
+character in the first column, the first line is left alone and the
+rest of the region is reindented with respect to it.  Else the entire
+region is reindented with respect to the (closest code or indenting
+comment) statement immediately preceding the region.
+
+This is useful when code blocks are moved or yanked, when enclosing
+control structures are introduced or removed, or to reformat code
+using a new value for the indentation offset.
+
+If a numeric prefix argument is given, it will be used as the value of
+the indentation offset.  Else the value of `py-indent-offset' will be
+used.
+
+Warning: The region must be consistently indented before this function
+is called!  This function does not compute proper indentation from
+scratch (that's impossible in Python), it merely adjusts the existing
+indentation to be correct in context.
+
+Warning: This function really has no idea what to do with
+non-indenting comment lines, and shifts them as if they were indenting
+comment lines.  Fixing this appears to require telepathy.
+
+Special cases: whitespace is deleted from blank lines; continuation
+lines are shifted by the same amount their initial line was shifted,
+in order to preserve their relative indentation with respect to their
+initial line; and comment lines beginning in column 1 are ignored."
+  (interactive "*r\nP")			; region; raw prefix arg
+  (save-excursion
+    (goto-char end)   (beginning-of-line) (setq end (point-marker))
+    (goto-char start) (beginning-of-line)
+    (let ((py-indent-offset (prefix-numeric-value
+			     (or indent-offset py-indent-offset)))
+	  (indents '(-1))		; stack of active indent levels
+	  (target-column 0)		; column to which to indent
+	  (base-shifted-by 0)		; amount last base line was shifted
+	  (indent-base (if (looking-at "[ \t\n]")
+			   (py-compute-indentation t)
+			 0))
+	  ci)
+      (while (< (point) end)
+	(setq ci (current-indentation))
+	;; figure out appropriate target column
+	(cond
+	 ((or (eq (following-char) ?#)	; comment in column 1
+	      (looking-at "[ \t]*$"))	; entirely blank
+	  (setq target-column 0))
+	 ((py-continuation-line-p)	; shift relative to base line
+	  (setq target-column (+ ci base-shifted-by)))
+	 (t				; new base line
+	  (if (> ci (car indents))	; going deeper; push it
+	      (setq indents (cons ci indents))
+	    ;; else we should have seen this indent before
+	    (setq indents (memq ci indents)) ; pop deeper indents
+	    (if (null indents)
+		(error "Bad indentation in region, at line %d"
+		       (save-restriction
+			 (widen)
+			 (1+ (count-lines 1 (point)))))))
+	  (setq target-column (+ indent-base
+				 (* py-indent-offset
+				    (- (length indents) 2))))
+	  (setq base-shifted-by (- target-column ci))))
+	;; shift as needed
+	(if (/= ci target-column)
+	    (progn
+	      (delete-horizontal-space)
+	      (indent-to target-column)))
+	(forward-line 1))))
+  (set-marker end nil))
+
+(defun py-comment-region (beg end &optional arg)
+  "Like `comment-region' but uses double hash (`#') comment starter."
+  (interactive "r\nP")
+  (let ((comment-start py-block-comment-prefix))
+    (comment-region beg end arg)))
+
+
+;; Functions for moving point
+(defun py-previous-statement (count)
+  "Go to the start of the COUNTth preceding Python statement.
+By default, goes to the previous statement.  If there is no such
+statement, goes to the first statement.  Return count of statements
+left to move.  `Statements' do not include blank, comment, or
+continuation lines."
+  (interactive "p")			; numeric prefix arg
+  (if (< count 0) (py-next-statement (- count))
+    (py-goto-initial-line)
+    (let (start)
+      (while (and
+	      (setq start (point))	; always true -- side effect
+	      (> count 0)
+	      (zerop (forward-line -1))
+	      (py-goto-statement-at-or-above))
+	(setq count (1- count)))
+      (if (> count 0) (goto-char start)))
+    count))
+
+(defun py-next-statement (count)
+  "Go to the start of next Python statement.
+If the statement at point is the i'th Python statement, goes to the
+start of statement i+COUNT.  If there is no such statement, goes to the
+last statement.  Returns count of statements left to move.  `Statements'
+do not include blank, comment, or continuation lines."
+  (interactive "p")			; numeric prefix arg
+  (if (< count 0) (py-previous-statement (- count))
+    (beginning-of-line)
+    (let (start)
+      (while (and
+	      (setq start (point))	; always true -- side effect
+	      (> count 0)
+	      (py-goto-statement-below))
+	(setq count (1- count)))
+      (if (> count 0) (goto-char start)))
+    count))
+
+(defun py-goto-block-up (&optional nomark)
+  "Move up to start of current block.
+Go to the statement that starts the smallest enclosing block; roughly
+speaking, this will be the closest preceding statement that ends with a
+colon and is indented less than the statement you started on.  If
+successful, also sets the mark to the starting point.
+
+`\\[py-mark-block]' can be used afterward to mark the whole code
+block, if desired.
+
+If called from a program, the mark will not be set if optional argument
+NOMARK is not nil."
+  (interactive)
+  (let ((start (point))
+	(found nil)
+	initial-indent)
+    (py-goto-initial-line)
+    ;; if on blank or non-indenting comment line, use the preceding stmt
+    (if (looking-at "[ \t]*\\($\\|#[^ \t\n]\\)")
+	(progn
+	  (py-goto-statement-at-or-above)
+	  (setq found (py-statement-opens-block-p))))
+    ;; search back for colon line indented less
+    (setq initial-indent (current-indentation))
+    (if (zerop initial-indent)
+	;; force fast exit
+	(goto-char (point-min)))
+    (while (not (or found (bobp)))
+      (setq found
+	    (and
+	     (re-search-backward ":[ \t]*\\($\\|[#\\]\\)" nil 'move)
+	     (or (py-goto-initial-line) t) ; always true -- side effect
+	     (< (current-indentation) initial-indent)
+	     (py-statement-opens-block-p))))
+    (if found
+	(progn
+	  (or nomark (push-mark start))
+	  (back-to-indentation))
+      (goto-char start)
+      (error "Enclosing block not found"))))
+
+(defun py-beginning-of-def-or-class (&optional class count)
+  "Move point to start of `def' or `class'.
+
+Searches back for the closest preceding `def'.  If you supply a prefix
+arg, looks for a `class' instead.  The docs below assume the `def'
+case; just substitute `class' for `def' for the other case.
+Programmatically, if CLASS is `either', then moves to either `class'
+or `def'.
+
+When second optional argument is given programmatically, move to the
+COUNTth start of `def'.
+
+If point is in a `def' statement already, and after the `d', simply
+moves point to the start of the statement.
+
+Otherwise (i.e. when point is not in a `def' statement, or at or
+before the `d' of a `def' statement), searches for the closest
+preceding `def' statement, and leaves point at its start.  If no such
+statement can be found, leaves point at the start of the buffer.
+
+Returns t iff a `def' statement is found by these rules.
+
+Note that doing this command repeatedly will take you closer to the
+start of the buffer each time.
+
+To mark the current `def', see `\\[py-mark-def-or-class]'."
+  (interactive "P")			; raw prefix arg
+  (setq count (or count 1))
+  (let ((at-or-before-p (<= (current-column) (current-indentation)))
+	(start-of-line (goto-char (py-point 'bol)))
+	(start-of-stmt (goto-char (py-point 'bos)))
+	(start-re (cond ((eq class 'either) "^[ \t]*\\(class\\|def\\)\\>")
+			(class "^[ \t]*class\\>")
+			(t "^[ \t]*def\\>")))
+	)
+    ;; searching backward
+    (if (and (< 0 count)
+	     (or (/= start-of-stmt start-of-line)
+		 (not at-or-before-p)))
+	(end-of-line))
+    ;; search forward
+    (if (and (> 0 count)
+	     (zerop (current-column))
+	     (looking-at start-re))
+	(end-of-line))
+    (if (re-search-backward start-re nil 'move count)
+	(goto-char (match-beginning 0)))))
+
+;; Backwards compatibility
+(defalias 'beginning-of-python-def-or-class 'py-beginning-of-def-or-class)
+
+(defun py-end-of-def-or-class (&optional class count)
+  "Move point beyond end of `def' or `class' body.
+
+By default, looks for an appropriate `def'.  If you supply a prefix
+arg, looks for a `class' instead.  The docs below assume the `def'
+case; just substitute `class' for `def' for the other case.
+Programmatically, if CLASS is `either', then moves to either `class'
+or `def'.
+
+When second optional argument is given programmatically, move to the
+COUNTth end of `def'.
+
+If point is in a `def' statement already, this is the `def' we use.
+
+Else, if the `def' found by `\\[py-beginning-of-def-or-class]'
+contains the statement you started on, that's the `def' we use.
+
+Otherwise, we search forward for the closest following `def', and use that.
+
+If a `def' can be found by these rules, point is moved to the start of
+the line immediately following the `def' block, and the position of the
+start of the `def' is returned.
+
+Else point is moved to the end of the buffer, and nil is returned.
+
+Note that doing this command repeatedly will take you closer to the
+end of the buffer each time.
+
+To mark the current `def', see `\\[py-mark-def-or-class]'."
+  (interactive "P")			; raw prefix arg
+  (if (and count (/= count 1))
+      (py-beginning-of-def-or-class (- 1 count)))
+  (let ((start (progn (py-goto-initial-line) (point)))
+	(which (cond ((eq class 'either) "\\(class\\|def\\)")
+		     (class "class")
+		     (t "def")))
+	(state 'not-found))
+    ;; move point to start of appropriate def/class
+    (if (looking-at (concat "[ \t]*" which "\\>")) ; already on one
+	(setq state 'at-beginning)
+      ;; else see if py-beginning-of-def-or-class hits container
+      (if (and (py-beginning-of-def-or-class class)
+	       (progn (py-goto-beyond-block)
+		      (> (point) start)))
+	  (setq state 'at-end)
+	;; else search forward
+	(goto-char start)
+	(if (re-search-forward (concat "^[ \t]*" which "\\>") nil 'move)
+	    (progn (setq state 'at-beginning)
+		   (beginning-of-line)))))
+    (cond
+     ((eq state 'at-beginning) (py-goto-beyond-block) t)
+     ((eq state 'at-end) t)
+     ((eq state 'not-found) nil)
+     (t (error "Internal error in `py-end-of-def-or-class'")))))
+
+;; Backwards compabitility
+(defalias 'end-of-python-def-or-class 'py-end-of-def-or-class)
+
+
+;; Functions for marking regions
+(defun py-mark-block (&optional extend just-move)
+  "Mark following block of lines.  With prefix arg, mark structure.
+Easier to use than explain.  It sets the region to an `interesting'
+block of succeeding lines.  If point is on a blank line, it goes down to
+the next non-blank line.  That will be the start of the region.  The end
+of the region depends on the kind of line at the start:
+
+ - If a comment, the region will include all succeeding comment lines up
+   to (but not including) the next non-comment line (if any).
+
+ - Else if a prefix arg is given, and the line begins one of these
+   structures:
+
+     if elif else try except finally for while def class
+
+   the region will be set to the body of the structure, including
+   following blocks that `belong' to it, but excluding trailing blank
+   and comment lines.  E.g., if on a `try' statement, the `try' block
+   and all (if any) of the following `except' and `finally' blocks
+   that belong to the `try' structure will be in the region.  Ditto
+   for if/elif/else, for/else and while/else structures, and (a bit
+   degenerate, since they're always one-block structures) def and
+   class blocks.
+
+ - Else if no prefix argument is given, and the line begins a Python
+   block (see list above), and the block is not a `one-liner' (i.e.,
+   the statement ends with a colon, not with code), the region will
+   include all succeeding lines up to (but not including) the next
+   code statement (if any) that's indented no more than the starting
+   line, except that trailing blank and comment lines are excluded.
+   E.g., if the starting line begins a multi-statement `def'
+   structure, the region will be set to the full function definition,
+   but without any trailing `noise' lines.
+
+ - Else the region will include all succeeding lines up to (but not
+   including) the next blank line, or code or indenting-comment line
+   indented strictly less than the starting line.  Trailing indenting
+   comment lines are included in this case, but not trailing blank
+   lines.
+
+A msg identifying the location of the mark is displayed in the echo
+area; or do `\\[exchange-point-and-mark]' to flip down to the end.
+
+If called from a program, optional argument EXTEND plays the role of
+the prefix arg, and if optional argument JUST-MOVE is not nil, just
+moves to the end of the block (& does not set mark or display a msg)."
+  (interactive "P")			; raw prefix arg
+  (py-goto-initial-line)
+  ;; skip over blank lines
+  (while (and
+	  (looking-at "[ \t]*$")	; while blank line
+	  (not (eobp)))			; & somewhere to go
+    (forward-line 1))
+  (if (eobp)
+      (error "Hit end of buffer without finding a non-blank stmt"))
+  (let ((initial-pos (point))
+	(initial-indent (current-indentation))
+	last-pos			; position of last stmt in region
+	(followers
+	 '((if elif else) (elif elif else) (else)
+	   (try except finally) (except except) (finally)
+	   (for else) (while else)
+	   (def) (class) ) )
+	first-symbol next-symbol)
+
+    (cond
+     ;; if comment line, suck up the following comment lines
+     ((looking-at "[ \t]*#")
+      (re-search-forward "^[ \t]*[^ \t#]" nil 'move) ; look for non-comment
+      (re-search-backward "^[ \t]*#")	; and back to last comment in block
+      (setq last-pos (point)))
+
+     ;; else if line is a block line and EXTEND given, suck up
+     ;; the whole structure
+     ((and extend
+	   (setq first-symbol (py-suck-up-first-keyword) )
+	   (assq first-symbol followers))
+      (while (and
+	      (or (py-goto-beyond-block) t) ; side effect
+	      (forward-line -1)		; side effect
+	      (setq last-pos (point))	; side effect
+	      (py-goto-statement-below)
+	      (= (current-indentation) initial-indent)
+	      (setq next-symbol (py-suck-up-first-keyword))
+	      (memq next-symbol (cdr (assq first-symbol followers))))
+	(setq first-symbol next-symbol)))
+
+     ;; else if line *opens* a block, search for next stmt indented <=
+     ((py-statement-opens-block-p)
+      (while (and
+	      (setq last-pos (point))	; always true -- side effect
+	      (py-goto-statement-below)
+	      (> (current-indentation) initial-indent)
+	      )))
+
+     ;; else plain code line; stop at next blank line, or stmt or
+     ;; indenting comment line indented <
+     (t
+      (while (and
+	      (setq last-pos (point))	; always true -- side effect
+	      (or (py-goto-beyond-final-line) t)
+	      (not (looking-at "[ \t]*$")) ; stop at blank line
+	      (or
+	       (>= (current-indentation) initial-indent)
+	       (looking-at "[ \t]*#[^ \t\n]"))) ; ignore non-indenting #
+	nil)))
+
+    ;; skip to end of last stmt
+    (goto-char last-pos)
+    (py-goto-beyond-final-line)
+
+    ;; set mark & display
+    (if just-move
+	()				; just return
+      (push-mark (point) 'no-msg)
+      (forward-line -1)
+      (message "Mark set after: %s" (py-suck-up-leading-text))
+      (goto-char initial-pos))))
+
+(defun py-mark-def-or-class (&optional class)
+  "Set region to body of def (or class, with prefix arg) enclosing point.
+Pushes the current mark, then point, on the mark ring (all language
+modes do this, but although it's handy it's never documented ...).
+
+In most Emacs language modes, this function bears at least a
+hallucinogenic resemblance to `\\[py-end-of-def-or-class]' and
+`\\[py-beginning-of-def-or-class]'.
+
+And in earlier versions of Python mode, all 3 were tightly connected.
+Turned out that was more confusing than useful: the `goto start' and
+`goto end' commands are usually used to search through a file, and
+people expect them to act a lot like `search backward' and `search
+forward' string-search commands.  But because Python `def' and `class'
+can nest to arbitrary levels, finding the smallest def containing
+point cannot be done via a simple backward search: the def containing
+point may not be the closest preceding def, or even the closest
+preceding def that's indented less.  The fancy algorithm required is
+appropriate for the usual uses of this `mark' command, but not for the
+`goto' variations.
+
+So the def marked by this command may not be the one either of the
+`goto' commands find: If point is on a blank or non-indenting comment
+line, moves back to start of the closest preceding code statement or
+indenting comment line.  If this is a `def' statement, that's the def
+we use.  Else searches for the smallest enclosing `def' block and uses
+that.  Else signals an error.
+
+When an enclosing def is found: The mark is left immediately beyond
+the last line of the def block.  Point is left at the start of the
+def, except that: if the def is preceded by a number of comment lines
+followed by (at most) one optional blank line, point is left at the
+start of the comments; else if the def is preceded by a blank line,
+point is left at its start.
+
+The intent is to mark the containing def/class and its associated
+documentation, to make moving and duplicating functions and classes
+pleasant."
+  (interactive "P")			; raw prefix arg
+  (let ((start (point))
+	(which (cond ((eq class 'either) "\\(class\\|def\\)")
+		     (class "class")
+		     (t "def"))))
+    (push-mark start)
+    (if (not (py-go-up-tree-to-keyword which))
+	(progn (goto-char start)
+	       (error "Enclosing %s not found"
+		      (if (eq class 'either)
+			  "def or class"
+			which)))
+      ;; else enclosing def/class found
+      (setq start (point))
+      (py-goto-beyond-block)
+      (push-mark (point))
+      (goto-char start)
+      (if (zerop (forward-line -1))	; if there is a preceding line
+	  (progn
+	    (if (looking-at "[ \t]*$")	; it's blank
+		(setq start (point))	; so reset start point
+	      (goto-char start))	; else try again
+	    (if (zerop (forward-line -1))
+		(if (looking-at "[ \t]*#") ; a comment
+		    ;; look back for non-comment line
+		    ;; tricky: note that the regexp matches a blank
+		    ;; line, cuz \n is in the 2nd character class
+		    (and
+		     (re-search-backward "^[ \t]*[^ \t#]" nil 'move)
+		     (forward-line 1))
+		  ;; no comment, so go back
+		  (goto-char start)))))))
+  (exchange-point-and-mark)
+  (py-keep-region-active))
+
+;; ripped from cc-mode
+(defun py-forward-into-nomenclature (&optional arg)
+  "Move forward to end of a nomenclature section or word.
+With \\[universal-argument] (programmatically, optional argument ARG), 
+do it that many times.
+
+A `nomenclature' is a fancy way of saying AWordWithMixedCaseNotUnderscores."
+  (interactive "p")
+  (let ((case-fold-search nil))
+    (if (> arg 0)
+	(re-search-forward
+	 "\\(\\W\\|[_]\\)*\\([A-Z]*[a-z0-9]*\\)"
+	 (point-max) t arg)
+      (while (and (< arg 0)
+		  (re-search-backward
+		   "\\(\\W\\|[a-z0-9]\\)[A-Z]+\\|\\(\\W\\|[_]\\)\\w+"
+		   (point-min) 0))
+	(forward-char 1)
+	(setq arg (1+ arg)))))
+  (py-keep-region-active))
+
+(defun py-backward-into-nomenclature (&optional arg)
+  "Move backward to beginning of a nomenclature section or word.
+With optional ARG, move that many times.  If ARG is negative, move
+forward.
+
+A `nomenclature' is a fancy way of saying AWordWithMixedCaseNotUnderscores."
+  (interactive "p")
+  (py-forward-into-nomenclature (- arg))
+  (py-keep-region-active))
+
+
+
+;; pdbtrack functions
+(defun py-pdbtrack-toggle-stack-tracking (arg)
+  (interactive "P")
+  (if (not (get-buffer-process (current-buffer)))
+      (error "No process associated with buffer '%s'" (current-buffer)))
+  ;; missing or 0 is toggle, >0 turn on, <0 turn off
+  (if (or (not arg)
+	  (zerop (setq arg (prefix-numeric-value arg))))
+      (setq py-pdbtrack-do-tracking-p (not py-pdbtrack-do-tracking-p))
+    (setq py-pdbtrack-do-tracking-p (> arg 0)))
+  (message "%sabled Python's pdbtrack"
+           (if py-pdbtrack-do-tracking-p "En" "Dis")))
+
+(defun turn-on-pdbtrack ()
+  (interactive)
+  (py-pdbtrack-toggle-stack-tracking 1))
+
+(defun turn-off-pdbtrack ()
+  (interactive)
+  (py-pdbtrack-toggle-stack-tracking 0))
+
+
+
+;; Pychecker
+(defun py-pychecker-run (command)
+  "*Run pychecker (default on the file currently visited)."
+  (interactive
+   (let ((default
+           (format "%s %s %s" py-pychecker-command
+		   (mapconcat 'identity py-pychecker-command-args " ")
+		   (buffer-file-name)))
+	 (last (when py-pychecker-history
+		 (let* ((lastcmd (car py-pychecker-history))
+			(cmd (cdr (reverse (split-string lastcmd))))
+			(newcmd (reverse (cons (buffer-file-name) cmd))))
+		   (mapconcat 'identity newcmd " ")))))
+
+     (list
+      (if (fboundp 'read-shell-command)
+	  (read-shell-command "Run pychecker like this: "
+			      (if last
+				  last
+				default)
+			      'py-pychecker-history)
+	(read-string "Run pychecker like this: "
+		     (if last
+			 last
+		       default)
+		     'py-pychecker-history))
+	)))
+  (save-some-buffers (not py-ask-about-save) nil)
+  (compile-internal command "No more errors"))
+
+
+
+;; pydoc commands. The guts of this function is stolen from XEmacs's
+;; symbol-near-point, but without the useless regexp-quote call on the
+;; results, nor the interactive bit.  Also, we've added the temporary
+;; syntax table setting, which Skip originally had broken out into a
+;; separate function.  Note that Emacs doesn't have the original
+;; function.
+(defun py-symbol-near-point ()
+  "Return the first textual item to the nearest point."
+  ;; alg stolen from etag.el
+  (save-excursion
+    (with-syntax-table py-dotted-expression-syntax-table
+      (if (or (bobp) (not (memq (char-syntax (char-before)) '(?w ?_))))
+	  (while (not (looking-at "\\sw\\|\\s_\\|\\'"))
+	    (forward-char 1)))
+      (while (looking-at "\\sw\\|\\s_")
+	(forward-char 1))
+      (if (re-search-backward "\\sw\\|\\s_" nil t)
+	  (progn (forward-char 1)
+		 (buffer-substring (point)
+				   (progn (forward-sexp -1)
+					  (while (looking-at "\\s'")
+					    (forward-char 1))
+					  (point))))
+	nil))))
+
+(defun py-help-at-point ()
+  "Get help from Python based on the symbol nearest point."
+  (interactive)
+  (let* ((sym (py-symbol-near-point))
+	 (base (substring sym 0 (or (search "." sym :from-end t) 0)))
+	 cmd)
+    (if (not (equal base ""))
+        (setq cmd (concat "import " base "\n")))
+    (setq cmd (concat "import pydoc\n"
+                      cmd
+		      "try: pydoc.help('" sym "')\n"
+		      "except: print 'No help available on:', \"" sym "\""))
+    (message cmd)
+    (py-execute-string cmd)
+    (set-buffer "*Python Output*")
+    ;; BAW: Should we really be leaving the output buffer in help-mode?
+    (help-mode)))
+
+
+
+;; Documentation functions
+
+;; dump the long form of the mode blurb; does the usual doc escapes,
+;; plus lines of the form ^[vc]:name$ to suck variable & command docs
+;; out of the right places, along with the keys they're on & current
+;; values
+(defun py-dump-help-string (str)
+  (with-output-to-temp-buffer "*Help*"
+    (let ((locals (buffer-local-variables))
+	  funckind funcname func funcdoc
+	  (start 0) mstart end
+	  keys )
+      (while (string-match "^%\\([vc]\\):\\(.+\\)\n" str start)
+	(setq mstart (match-beginning 0)  end (match-end 0)
+	      funckind (substring str (match-beginning 1) (match-end 1))
+	      funcname (substring str (match-beginning 2) (match-end 2))
+	      func (intern funcname))
+	(princ (substitute-command-keys (substring str start mstart)))
+	(cond
+	 ((equal funckind "c")		; command
+	  (setq funcdoc (documentation func)
+		keys (concat
+		      "Key(s): "
+		      (mapconcat 'key-description
+				 (where-is-internal func py-mode-map)
+				 ", "))))
+	 ((equal funckind "v")		; variable
+	  (setq funcdoc (documentation-property func 'variable-documentation)
+		keys (if (assq func locals)
+			 (concat
+			  "Local/Global values: "
+			  (prin1-to-string (symbol-value func))
+			  " / "
+			  (prin1-to-string (default-value func)))
+		       (concat
+			"Value: "
+			(prin1-to-string (symbol-value func))))))
+	 (t				; unexpected
+	  (error "Error in py-dump-help-string, tag `%s'" funckind)))
+	(princ (format "\n-> %s:\t%s\t%s\n\n"
+		       (if (equal funckind "c") "Command" "Variable")
+		       funcname keys))
+	(princ funcdoc)
+	(terpri)
+	(setq start end))
+      (princ (substitute-command-keys (substring str start))))
+    (print-help-return-message)))
+
+(defun py-describe-mode ()
+  "Dump long form of Python-mode docs."
+  (interactive)
+  (py-dump-help-string "Major mode for editing Python files.
+Knows about Python indentation, tokens, comments and continuation lines.
+Paragraphs are separated by blank lines only.
+
+Major sections below begin with the string `@'; specific function and
+variable docs begin with `->'.
+
+ at EXECUTING PYTHON CODE
+
+\\[py-execute-import-or-reload]\timports or reloads the file in the Python interpreter
+\\[py-execute-buffer]\tsends the entire buffer to the Python interpreter
+\\[py-execute-region]\tsends the current region
+\\[py-execute-def-or-class]\tsends the current function or class definition
+\\[py-execute-string]\tsends an arbitrary string
+\\[py-shell]\tstarts a Python interpreter window; this will be used by
+\tsubsequent Python execution commands
+%c:py-execute-import-or-reload
+%c:py-execute-buffer
+%c:py-execute-region
+%c:py-execute-def-or-class
+%c:py-execute-string
+%c:py-shell
+
+ at VARIABLES
+
+py-indent-offset\tindentation increment
+py-block-comment-prefix\tcomment string used by comment-region
+
+py-python-command\tshell command to invoke Python interpreter
+py-temp-directory\tdirectory used for temp files (if needed)
+
+py-beep-if-tab-change\tring the bell if tab-width is changed
+%v:py-indent-offset
+%v:py-block-comment-prefix
+%v:py-python-command
+%v:py-temp-directory
+%v:py-beep-if-tab-change
+
+ at KINDS OF LINES
+
+Each physical line in the file is either a `continuation line' (the
+preceding line ends with a backslash that's not part of a comment, or
+the paren/bracket/brace nesting level at the start of the line is
+non-zero, or both) or an `initial line' (everything else).
+
+An initial line is in turn a `blank line' (contains nothing except
+possibly blanks or tabs), a `comment line' (leftmost non-blank
+character is `#'), or a `code line' (everything else).
+
+Comment Lines
+
+Although all comment lines are treated alike by Python, Python mode
+recognizes two kinds that act differently with respect to indentation.
+
+An `indenting comment line' is a comment line with a blank, tab or
+nothing after the initial `#'.  The indentation commands (see below)
+treat these exactly as if they were code lines: a line following an
+indenting comment line will be indented like the comment line.  All
+other comment lines (those with a non-whitespace character immediately
+following the initial `#') are `non-indenting comment lines', and
+their indentation is ignored by the indentation commands.
+
+Indenting comment lines are by far the usual case, and should be used
+whenever possible.  Non-indenting comment lines are useful in cases
+like these:
+
+\ta = b   # a very wordy single-line comment that ends up being
+\t        #... continued onto another line
+
+\tif a == b:
+##\t\tprint 'panic!' # old code we've `commented out'
+\t\treturn a
+
+Since the `#...' and `##' comment lines have a non-whitespace
+character following the initial `#', Python mode ignores them when
+computing the proper indentation for the next line.
+
+Continuation Lines and Statements
+
+The Python-mode commands generally work on statements instead of on
+individual lines, where a `statement' is a comment or blank line, or a
+code line and all of its following continuation lines (if any)
+considered as a single logical unit.  The commands in this mode
+generally (when it makes sense) automatically move to the start of the
+statement containing point, even if point happens to be in the middle
+of some continuation line.
+
+
+ at INDENTATION
+
+Primarily for entering new code:
+\t\\[indent-for-tab-command]\t indent line appropriately
+\t\\[py-newline-and-indent]\t insert newline, then indent
+\t\\[py-electric-backspace]\t reduce indentation, or delete single character
+
+Primarily for reindenting existing code:
+\t\\[py-guess-indent-offset]\t guess py-indent-offset from file content; change locally
+\t\\[universal-argument] \\[py-guess-indent-offset]\t ditto, but change globally
+
+\t\\[py-indent-region]\t reindent region to match its context
+\t\\[py-shift-region-left]\t shift region left by py-indent-offset
+\t\\[py-shift-region-right]\t shift region right by py-indent-offset
+
+Unlike most programming languages, Python uses indentation, and only
+indentation, to specify block structure.  Hence the indentation supplied
+automatically by Python-mode is just an educated guess:  only you know
+the block structure you intend, so only you can supply correct
+indentation.
+
+The \\[indent-for-tab-command] and \\[py-newline-and-indent] keys try to suggest plausible indentation, based on
+the indentation of preceding statements.  E.g., assuming
+py-indent-offset is 4, after you enter
+\tif a > 0: \\[py-newline-and-indent]
+the cursor will be moved to the position of the `_' (_ is not a
+character in the file, it's just used here to indicate the location of
+the cursor):
+\tif a > 0:
+\t    _
+If you then enter `c = d' \\[py-newline-and-indent], the cursor will move
+to
+\tif a > 0:
+\t    c = d
+\t    _
+Python-mode cannot know whether that's what you intended, or whether
+\tif a > 0:
+\t    c = d
+\t_
+was your intent.  In general, Python-mode either reproduces the
+indentation of the (closest code or indenting-comment) preceding
+statement, or adds an extra py-indent-offset blanks if the preceding
+statement has `:' as its last significant (non-whitespace and non-
+comment) character.  If the suggested indentation is too much, use
+\\[py-electric-backspace] to reduce it.
+
+Continuation lines are given extra indentation.  If you don't like the
+suggested indentation, change it to something you do like, and Python-
+mode will strive to indent later lines of the statement in the same way.
+
+If a line is a continuation line by virtue of being in an unclosed
+paren/bracket/brace structure (`list', for short), the suggested
+indentation depends on whether the current line contains the first item
+in the list.  If it does, it's indented py-indent-offset columns beyond
+the indentation of the line containing the open bracket.  If you don't
+like that, change it by hand.  The remaining items in the list will mimic
+whatever indentation you give to the first item.
+
+If a line is a continuation line because the line preceding it ends with
+a backslash, the third and following lines of the statement inherit their
+indentation from the line preceding them.  The indentation of the second
+line in the statement depends on the form of the first (base) line:  if
+the base line is an assignment statement with anything more interesting
+than the backslash following the leftmost assigning `=', the second line
+is indented two columns beyond that `='.  Else it's indented to two
+columns beyond the leftmost solid chunk of non-whitespace characters on
+the base line.
+
+Warning:  indent-region should not normally be used!  It calls \\[indent-for-tab-command]
+repeatedly, and as explained above, \\[indent-for-tab-command] can't guess the block
+structure you intend.
+%c:indent-for-tab-command
+%c:py-newline-and-indent
+%c:py-electric-backspace
+
+
+The next function may be handy when editing code you didn't write:
+%c:py-guess-indent-offset
+
+
+The remaining `indent' functions apply to a region of Python code.  They
+assume the block structure (equals indentation, in Python) of the region
+is correct, and alter the indentation in various ways while preserving
+the block structure:
+%c:py-indent-region
+%c:py-shift-region-left
+%c:py-shift-region-right
+
+ at MARKING & MANIPULATING REGIONS OF CODE
+
+\\[py-mark-block]\t mark block of lines
+\\[py-mark-def-or-class]\t mark smallest enclosing def
+\\[universal-argument] \\[py-mark-def-or-class]\t mark smallest enclosing class
+\\[comment-region]\t comment out region of code
+\\[universal-argument] \\[comment-region]\t uncomment region of code
+%c:py-mark-block
+%c:py-mark-def-or-class
+%c:comment-region
+
+ at MOVING POINT
+
+\\[py-previous-statement]\t move to statement preceding point
+\\[py-next-statement]\t move to statement following point
+\\[py-goto-block-up]\t move up to start of current block
+\\[py-beginning-of-def-or-class]\t move to start of def
+\\[universal-argument] \\[py-beginning-of-def-or-class]\t move to start of class
+\\[py-end-of-def-or-class]\t move to end of def
+\\[universal-argument] \\[py-end-of-def-or-class]\t move to end of class
+
+The first two move to one statement beyond the statement that contains
+point.  A numeric prefix argument tells them to move that many
+statements instead.  Blank lines, comment lines, and continuation lines
+do not count as `statements' for these commands.  So, e.g., you can go
+to the first code statement in a file by entering
+\t\\[beginning-of-buffer]\t to move to the top of the file
+\t\\[py-next-statement]\t to skip over initial comments and blank lines
+Or do `\\[py-previous-statement]' with a huge prefix argument.
+%c:py-previous-statement
+%c:py-next-statement
+%c:py-goto-block-up
+%c:py-beginning-of-def-or-class
+%c:py-end-of-def-or-class
+
+ at LITTLE-KNOWN EMACS COMMANDS PARTICULARLY USEFUL IN PYTHON MODE
+
+`\\[indent-new-comment-line]' is handy for entering a multi-line comment.
+
+`\\[set-selective-display]' with a `small' prefix arg is ideally suited for viewing the
+overall class and def structure of a module.
+
+`\\[back-to-indentation]' moves point to a line's first non-blank character.
+
+`\\[indent-relative]' is handy for creating odd indentation.
+
+ at OTHER EMACS HINTS
+
+If you don't like the default value of a variable, change its value to
+whatever you do like by putting a `setq' line in your .emacs file.
+E.g., to set the indentation increment to 4, put this line in your
+.emacs:
+\t(setq  py-indent-offset  4)
+To see the value of a variable, do `\\[describe-variable]' and enter the variable
+name at the prompt.
+
+When entering a key sequence like `C-c C-n', it is not necessary to
+release the CONTROL key after doing the `C-c' part -- it suffices to
+press the CONTROL key, press and release `c' (while still holding down
+CONTROL), press and release `n' (while still holding down CONTROL), &
+then release CONTROL.
+
+Entering Python mode calls with no arguments the value of the variable
+`python-mode-hook', if that value exists and is not nil; for backward
+compatibility it also tries `py-mode-hook'; see the `Hooks' section of
+the Elisp manual for details.
+
+Obscure:  When python-mode is first loaded, it looks for all bindings
+to newline-and-indent in the global keymap, and shadows them with
+local bindings to py-newline-and-indent."))
+
+(require 'info-look)
+;; The info-look package does not always provide this function (it
+;; appears this is the case with XEmacs 21.1)
+(when (fboundp 'info-lookup-maybe-add-help)
+  (info-lookup-maybe-add-help
+   :mode 'python-mode
+   :regexp "[a-zA-Z0-9_]+"
+   :doc-spec '(("(python-lib)Module Index")
+	       ("(python-lib)Class-Exception-Object Index")
+	       ("(python-lib)Function-Method-Variable Index")
+	       ("(python-lib)Miscellaneous Index")))
+  )
+
+
+;; Helper functions
+(defvar py-parse-state-re
+  (concat
+   "^[ \t]*\\(elif\\|else\\|while\\|def\\|class\\)\\>"
+   "\\|"
+   "^[^ #\t\n]"))
+
+(defun py-parse-state ()
+  "Return the parse state at point (see `parse-partial-sexp' docs)."
+  (save-excursion
+    (let ((here (point))
+	  pps done)
+      (while (not done)
+	;; back up to the first preceding line (if any; else start of
+	;; buffer) that begins with a popular Python keyword, or a
+	;; non- whitespace and non-comment character.  These are good
+	;; places to start parsing to see whether where we started is
+	;; at a non-zero nesting level.  It may be slow for people who
+	;; write huge code blocks or huge lists ... tough beans.
+	(re-search-backward py-parse-state-re nil 'move)
+	(beginning-of-line)
+	;; In XEmacs, we have a much better way to test for whether
+	;; we're in a triple-quoted string or not.  Emacs does not
+	;; have this built-in function, which is its loss because
+	;; without scanning from the beginning of the buffer, there's
+	;; no accurate way to determine this otherwise.
+	(save-excursion (setq pps (parse-partial-sexp (point) here)))
+	;; make sure we don't land inside a triple-quoted string
+	(setq done (or (not (nth 3 pps))
+		       (bobp)))
+	;; Just go ahead and short circuit the test back to the
+	;; beginning of the buffer.  This will be slow, but not
+	;; nearly as slow as looping through many
+	;; re-search-backwards.
+	(if (not done)
+	    (goto-char (point-min))))
+      pps)))
+
+(defun py-nesting-level ()
+  "Return the buffer position of the last unclosed enclosing list.
+If nesting level is zero, return nil."
+  (let ((status (py-parse-state)))
+    (if (zerop (car status))
+	nil				; not in a nest
+      (car (cdr status)))))		; char# of open bracket
+
+(defun py-backslash-continuation-line-p ()
+  "Return t iff preceding line ends with backslash that is not in a comment."
+  (save-excursion
+    (beginning-of-line)
+    (and
+     ;; use a cheap test first to avoid the regexp if possible
+     ;; use 'eq' because char-after may return nil
+     (eq (char-after (- (point) 2)) ?\\ )
+     ;; make sure; since eq test passed, there is a preceding line
+     (forward-line -1)			; always true -- side effect
+     (looking-at py-continued-re))))
+
+(defun py-continuation-line-p ()
+  "Return t iff current line is a continuation line."
+  (save-excursion
+    (beginning-of-line)
+    (or (py-backslash-continuation-line-p)
+	(py-nesting-level))))
+
+(defun py-goto-beginning-of-tqs (delim)
+  "Go to the beginning of the triple quoted string we find ourselves in.
+DELIM is the TQS string delimiter character we're searching backwards
+for."
+  (let ((skip (and delim (make-string 1 delim)))
+	(continue t))
+    (when skip
+      (save-excursion
+	(while continue
+	  (py-safe (search-backward skip))
+	  (setq continue (and (not (bobp))
+			      (= (char-before) ?\\))))
+	(if (and (= (char-before) delim)
+		 (= (char-before (1- (point))) delim))
+	    (setq skip (make-string 3 delim))))
+      ;; we're looking at a triple-quoted string
+      (py-safe (search-backward skip)))))
+
+(defun py-goto-initial-line ()
+  "Go to the initial line of the current statement.
+Usually this is the line we're on, but if we're on the 2nd or
+following lines of a continuation block, we need to go up to the first
+line of the block."
+  ;; Tricky: We want to avoid quadratic-time behavior for long
+  ;; continued blocks, whether of the backslash or open-bracket
+  ;; varieties, or a mix of the two.  The following manages to do that
+  ;; in the usual cases.
+  ;;
+  ;; Also, if we're sitting inside a triple quoted string, this will
+  ;; drop us at the line that begins the string.
+  (let (open-bracket-pos)
+    (while (py-continuation-line-p)
+      (beginning-of-line)
+      (if (py-backslash-continuation-line-p)
+	  (while (py-backslash-continuation-line-p)
+	    (forward-line -1))
+	;; else zip out of nested brackets/braces/parens
+	(while (setq open-bracket-pos (py-nesting-level))
+	  (goto-char open-bracket-pos)))))
+  (beginning-of-line))
+
+(defun py-goto-beyond-final-line ()
+  "Go to the point just beyond the fine line of the current statement.
+Usually this is the start of the next line, but if this is a
+multi-line statement we need to skip over the continuation lines."
+  ;; Tricky: Again we need to be clever to avoid quadratic time
+  ;; behavior.
+  ;;
+  ;; XXX: Not quite the right solution, but deals with multi-line doc
+  ;; strings
+  (if (looking-at (concat "[ \t]*\\(" py-stringlit-re "\\)"))
+      (goto-char (match-end 0)))
+  ;;
+  (forward-line 1)
+  (let (state)
+    (while (and (py-continuation-line-p)
+		(not (eobp)))
+      ;; skip over the backslash flavor
+      (while (and (py-backslash-continuation-line-p)
+		  (not (eobp)))
+	(forward-line 1))
+      ;; if in nest, zip to the end of the nest
+      (setq state (py-parse-state))
+      (if (and (not (zerop (car state)))
+	       (not (eobp)))
+	  (progn
+	    (parse-partial-sexp (point) (point-max) 0 nil state)
+	    (forward-line 1))))))
+
+(defun py-statement-opens-block-p ()
+  "Return t iff the current statement opens a block.
+I.e., iff it ends with a colon that is not in a comment.  Point should 
+be at the start of a statement."
+  (save-excursion
+    (let ((start (point))
+	  (finish (progn (py-goto-beyond-final-line) (1- (point))))
+	  (searching t)
+	  (answer nil)
+	  state)
+      (goto-char start)
+      (while searching
+	;; look for a colon with nothing after it except whitespace, and
+	;; maybe a comment
+	(if (re-search-forward ":\\([ \t]\\|\\\\\n\\)*\\(#.*\\)?$"
+			       finish t)
+	    (if (eq (point) finish)	; note: no `else' clause; just
+					; keep searching if we're not at
+					; the end yet
+		;; sure looks like it opens a block -- but it might
+		;; be in a comment
+		(progn
+		  (setq searching nil)	; search is done either way
+		  (setq state (parse-partial-sexp start
+						  (match-beginning 0)))
+		  (setq answer (not (nth 4 state)))))
+	  ;; search failed: couldn't find another interesting colon
+	  (setq searching nil)))
+      answer)))
+
+(defun py-statement-closes-block-p ()
+  "Return t iff the current statement closes a block.
+I.e., if the line starts with `return', `raise', `break', `continue',
+and `pass'.  This doesn't catch embedded statements."
+  (let ((here (point)))
+    (py-goto-initial-line)
+    (back-to-indentation)
+    (prog1
+	(looking-at (concat py-block-closing-keywords-re "\\>"))
+      (goto-char here))))
+
+(defun py-goto-beyond-block ()
+  "Go to point just beyond the final line of block begun by the current line.
+This is the same as where `py-goto-beyond-final-line' goes unless
+we're on colon line, in which case we go to the end of the block.
+Assumes point is at the beginning of the line."
+  (if (py-statement-opens-block-p)
+      (py-mark-block nil 'just-move)
+    (py-goto-beyond-final-line)))
+
+(defun py-goto-statement-at-or-above ()
+  "Go to the start of the first statement at or preceding point.
+Return t if there is such a statement, otherwise nil.  `Statement'
+does not include blank lines, comments, or continuation lines."
+  (py-goto-initial-line)
+  (if (looking-at py-blank-or-comment-re)
+      ;; skip back over blank & comment lines
+      ;; note:  will skip a blank or comment line that happens to be
+      ;; a continuation line too
+      (if (re-search-backward "^[ \t]*[^ \t#\n]" nil t)
+	  (progn (py-goto-initial-line) t)
+	nil)
+    t))
+
+(defun py-goto-statement-below ()
+  "Go to start of the first statement following the statement containing point.
+Return t if there is such a statement, otherwise nil.  `Statement'
+does not include blank lines, comments, or continuation lines."
+  (beginning-of-line)
+  (let ((start (point)))
+    (py-goto-beyond-final-line)
+    (while (and
+	    (or (looking-at py-blank-or-comment-re)
+		(py-in-literal))
+	    (not (eobp)))
+      (forward-line 1))
+    (if (eobp)
+	(progn (goto-char start) nil)
+      t)))
+
+(defun py-go-up-tree-to-keyword (key)
+  "Go to begining of statement starting with KEY, at or preceding point.
+
+KEY is a regular expression describing a Python keyword.  Skip blank
+lines and non-indenting comments.  If the statement found starts with
+KEY, then stop, otherwise go back to first enclosing block starting
+with KEY.  If successful, leave point at the start of the KEY line and 
+return t.  Otherwise, leav point at an undefined place and return nil."
+  ;; skip blanks and non-indenting #
+  (py-goto-initial-line)
+  (while (and
+	  (looking-at "[ \t]*\\($\\|#[^ \t\n]\\)")
+	  (zerop (forward-line -1)))	; go back
+    nil)
+  (py-goto-initial-line)
+  (let* ((re (concat "[ \t]*" key "\\b"))
+	 (case-fold-search nil)		; let* so looking-at sees this
+	 (found (looking-at re))
+	 (dead nil))
+    (while (not (or found dead))
+      (condition-case nil		; in case no enclosing block
+	  (py-goto-block-up 'no-mark)
+	(error (setq dead t)))
+      (or dead (setq found (looking-at re))))
+    (beginning-of-line)
+    found))
+
+(defun py-suck-up-leading-text ()
+  "Return string in buffer from start of indentation to end of line.
+Prefix with \"...\" if leading whitespace was skipped."
+  (save-excursion
+    (back-to-indentation)
+    (concat
+     (if (bolp) "" "...")
+     (buffer-substring (point) (progn (end-of-line) (point))))))
+
+(defun py-suck-up-first-keyword ()
+  "Return first keyword on the line as a Lisp symbol.
+`Keyword' is defined (essentially) as the regular expression
+([a-z]+).  Returns nil if none was found."
+  (let ((case-fold-search nil))
+    (if (looking-at "[ \t]*\\([a-z]+\\)\\b")
+	(intern (buffer-substring (match-beginning 1) (match-end 1)))
+      nil)))
+
+(defun py-current-defun ()
+  "Python value for `add-log-current-defun-function'.
+This tells add-log.el how to find the current function/method/variable."
+  (save-excursion
+    (if (re-search-backward py-defun-start-re nil t)
+	(or (match-string 3)
+	    (let ((method (match-string 2)))
+	      (if (and (not (zerop (length (match-string 1))))
+		       (re-search-backward py-class-start-re nil t))
+		  (concat (match-string 1) "." method)
+		method)))
+      nil)))
+
+
+(defconst py-help-address "python-mode at python.org"
+  "Address accepting submission of bug reports.")
+
+(defun py-version ()
+  "Echo the current version of `python-mode' in the minibuffer."
+  (interactive)
+  (message "Using `python-mode' version %s" py-version)
+  (py-keep-region-active))
+
+;; only works under Emacs 19
+;(eval-when-compile
+;  (require 'reporter))
+
+(defun py-submit-bug-report (enhancement-p)
+  "Submit via mail a bug report on `python-mode'.
+With \\[universal-argument] (programmatically, argument ENHANCEMENT-P
+non-nil) just submit an enhancement request."
+  (interactive
+   (list (not (y-or-n-p
+	       "Is this a bug report (hit `n' to send other comments)? "))))
+  (let ((reporter-prompt-for-summary-p (if enhancement-p
+					   "(Very) brief summary: "
+					 t)))
+    (require 'reporter)
+    (reporter-submit-bug-report
+     py-help-address			;address
+     (concat "python-mode " py-version)	;pkgname
+     ;; varlist
+     (if enhancement-p nil
+       '(py-python-command
+	 py-indent-offset
+	 py-block-comment-prefix
+	 py-temp-directory
+	 py-beep-if-tab-change))
+     nil				;pre-hooks
+     nil				;post-hooks
+     "Dear Barry,")			;salutation
+    (if enhancement-p nil
+      (set-mark (point))
+      (insert 
+"Please replace this text with a sufficiently large code sample\n\
+and an exact recipe so that I can reproduce your problem.  Failure\n\
+to do so may mean a greater delay in fixing your bug.\n\n")
+      (exchange-point-and-mark)
+      (py-keep-region-active))))
+
+
+(defun py-kill-emacs-hook ()
+  "Delete files in `py-file-queue'.
+These are Python temporary files awaiting execution."
+  (mapcar #'(lambda (filename)
+	      (py-safe (delete-file filename)))
+	  py-file-queue))
+
+;; arrange to kill temp files when Emacs exists
+(add-hook 'kill-emacs-hook 'py-kill-emacs-hook)
+(add-hook 'comint-output-filter-functions 'py-pdbtrack-track-stack-file)
+
+;; Add a designator to the minor mode strings
+(or (assq 'py-pdbtrack-minor-mode-string minor-mode-alist)
+    (push '(py-pdbtrack-is-tracking-p py-pdbtrack-minor-mode-string)
+	  minor-mode-alist))
+
+
+
+;;; paragraph and string filling code from Bernhard Herzog
+;;; see http://mail.python.org/pipermail/python-list/2002-May/103189.html
+
+(defun py-fill-comment (&optional justify)
+  "Fill the comment paragraph around point"
+  (let (;; Non-nil if the current line contains a comment.
+	has-comment
+
+	;; If has-comment, the appropriate fill-prefix for the comment.
+	comment-fill-prefix)
+
+    ;; Figure out what kind of comment we are looking at.
+    (save-excursion
+      (beginning-of-line)
+      (cond
+       ;; A line with nothing but a comment on it?
+       ((looking-at "[ \t]*#[# \t]*")
+	(setq has-comment t
+	      comment-fill-prefix (buffer-substring (match-beginning 0)
+						    (match-end 0))))
+
+       ;; A line with some code, followed by a comment? Remember that the hash
+       ;; which starts the comment shouldn't be part of a string or character.
+       ((progn
+	  (while (not (looking-at "#\\|$"))
+	    (skip-chars-forward "^#\n\"'\\")
+	    (cond
+	     ((eq (char-after (point)) ?\\) (forward-char 2))
+	     ((memq (char-after (point)) '(?\" ?')) (forward-sexp 1))))
+	  (looking-at "#+[\t ]*"))
+	(setq has-comment t)
+	(setq comment-fill-prefix
+	      (concat (make-string (current-column) ? )
+		      (buffer-substring (match-beginning 0) (match-end 0)))))))
+
+    (if (not has-comment)
+	(fill-paragraph justify)
+
+      ;; Narrow to include only the comment, and then fill the region.
+      (save-restriction
+	(narrow-to-region
+
+	 ;; Find the first line we should include in the region to fill.
+	 (save-excursion
+	   (while (and (zerop (forward-line -1))
+		       (looking-at "^[ \t]*#")))
+
+	   ;; We may have gone to far.  Go forward again.
+	   (or (looking-at "^[ \t]*#")
+	       (forward-line 1))
+	   (point))
+
+	 ;; Find the beginning of the first line past the region to fill.
+	 (save-excursion
+	   (while (progn (forward-line 1)
+			 (looking-at "^[ \t]*#")))
+	   (point)))
+
+	;; Lines with only hashes on them can be paragraph boundaries.
+	(let ((paragraph-start (concat paragraph-start "\\|[ \t#]*$"))
+	      (paragraph-separate (concat paragraph-separate "\\|[ \t#]*$"))
+	      (fill-prefix comment-fill-prefix))
+	  ;;(message "paragraph-start %S paragraph-separate %S"
+	  ;;paragraph-start paragraph-separate)
+	  (fill-paragraph justify))))
+    t))
+
+
+(defun py-fill-string (start &optional justify)
+  "Fill the paragraph around (point) in the string starting at start"
+  ;; basic strategy: narrow to the string and call the default
+  ;; implementation
+  (let (;; the start of the string's contents
+	string-start
+	;; the end of the string's contents
+	string-end
+	;; length of the string's delimiter
+	delim-length
+	;; The string delimiter
+	delim
+	)
+
+    (save-excursion
+      (goto-char start)
+      (if (looking-at "\\('''\\|\"\"\"\\|'\\|\"\\)\\\\?\n?")
+	  (setq string-start (match-end 0)
+		delim-length (- (match-end 1) (match-beginning 1))
+		delim (buffer-substring-no-properties (match-beginning 1)
+						      (match-end 1)))
+	(error "The parameter start is not the beginning of a python string"))
+
+      ;; if the string is the first token on a line and doesn't start with
+      ;; a newline, fill as if the string starts at the beginning of the
+      ;; line. this helps with one line docstrings
+      (save-excursion
+	(beginning-of-line)
+	(and (/= (char-before string-start) ?\n)
+	     (looking-at (concat "[ \t]*" delim))
+	     (setq string-start (point))))
+
+      (forward-sexp (if (= delim-length 3) 2 1))
+
+      ;; with both triple quoted strings and single/double quoted strings
+      ;; we're now directly behind the first char of the end delimiter
+      ;; (this doesn't work correctly when the triple quoted string
+      ;; contains the quote mark itself). The end of the string's contents
+      ;; is one less than point
+      (setq string-end (1- (point))))
+
+    ;; Narrow to the string's contents and fill the current paragraph
+    (save-restriction
+      (narrow-to-region string-start string-end)
+      (let ((ends-with-newline (= (char-before (point-max)) ?\n)))
+	(fill-paragraph justify)
+	(if (and (not ends-with-newline)
+		 (= (char-before (point-max)) ?\n))
+	    ;; the default fill-paragraph implementation has inserted a
+	    ;; newline at the end. Remove it again.
+	    (save-excursion
+	      (goto-char (point-max))
+	      (delete-char -1)))))
+
+    ;; return t to indicate that we've done our work
+    t))
+
+(defun py-fill-paragraph (&optional justify)
+  "Like \\[fill-paragraph], but handle Python comments and strings.
+If any of the current line is a comment, fill the comment or the
+paragraph of it that point is in, preserving the comment's indentation
+and initial `#'s.
+If point is inside a string, narrow to that string and fill.
+"
+  (interactive "P")
+  (let* ((bod (py-point 'bod))
+	 (pps (parse-partial-sexp bod (point))))
+    (cond
+     ;; are we inside a comment or on a line with only whitespace before
+     ;; the comment start?
+     ((or (nth 4 pps)
+	  (save-excursion (beginning-of-line) (looking-at "[ \t]*#")))
+      (py-fill-comment justify))
+     ;; are we inside a string?
+     ((nth 3 pps)
+      (py-fill-string (nth 8 pps)))
+     ;; otherwise use the default
+     (t
+      (fill-paragraph justify)))))
+
+
+
+(provide 'python-mode)
+;;; python-mode.el ends here

Added: vendor/Python/current/Misc/python.man
===================================================================
--- vendor/Python/current/Misc/python.man	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Misc/python.man	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,397 @@
+.TH PYTHON "1" "$Date: 2005-03-21 01:16:03 +1100 (Mon, 21 Mar 2005) $"
+
+./" To view this file while editing, run it through groff:
+./"   groff -Tascii -man python.man | less
+
+.SH NAME
+python \- an interpreted, interactive, object-oriented programming language
+.SH SYNOPSIS
+.B python
+[
+.B \-d
+]
+[
+.B \-E
+]
+[
+.B \-h
+]
+[
+.B \-i
+]
+[
+.B \-m 
+.I module-name
+]
+[
+.B \-O
+]
+.br
+       [
+.B -Q
+.I argument
+]
+[
+.B \-S
+]
+[
+.B \-t
+]
+[
+.B \-u
+]
+.br
+       [
+.B \-v
+]
+[
+.B \-V
+]
+[
+.B \-W
+.I argument
+]
+[
+.B \-x
+]
+.br
+       [
+.B \-c
+.I command
+|
+.I script
+|
+\-
+]
+[
+.I arguments
+]
+.SH DESCRIPTION
+Python is an interpreted, interactive, object-oriented programming
+language that combines remarkable power with very clear syntax.
+For an introduction to programming in Python you are referred to the
+Python Tutorial.
+The Python Library Reference documents built-in and standard types,
+constants, functions and modules.
+Finally, the Python Reference Manual describes the syntax and
+semantics of the core language in (perhaps too) much detail.
+(These documents may be located via the
+.B "INTERNET RESOURCES"
+below; they may be installed on your system as well.)
+.PP
+Python's basic power can be extended with your own modules written in
+C or C++.
+On most systems such modules may be dynamically loaded.
+Python is also adaptable as an extension language for existing
+applications.
+See the internal documentation for hints.
+.PP
+Documentation for installed Python modules and packages can be 
+viewed by running the 
+.B pydoc
+program.  
+.SH COMMAND LINE OPTIONS
+.TP
+.BI "\-c " command
+Specify the command to execute (see next section).
+This terminates the option list (following options are passed as
+arguments to the command).
+.TP
+.B \-d
+Turn on parser debugging output (for wizards only, depending on
+compilation options).
+.TP
+.B \-E
+Ignore environment variables like PYTHONPATH and PYTHONHOME that modify
+the behavior of the interpreter.
+.TP
+.B \-h
+Prints the usage for the interpreter executable and exits.
+.TP
+.B \-i
+When a script is passed as first argument or the \fB\-c\fP option is
+used, enter interactive mode after executing the script or the
+command.  It does not read the $PYTHONSTARTUP file.  This can be
+useful to inspect global variables or a stack trace when a script
+raises an exception.
+.TP
+.BI "\-m " module-name
+Searches 
+.I sys.path 
+for the named module and runs the corresponding 
+.I .py 
+file as a script.
+.TP
+.B \-O
+Turn on basic optimizations.  This changes the filename extension for
+compiled (bytecode) files from
+.I .pyc
+to \fI.pyo\fP.  Given twice, causes docstrings to be discarded.
+.TP
+.BI "\-Q " argument
+Division control; see PEP 238.  The argument must be one of "old" (the
+default, int/int and long/long return an int or long), "new" (new
+division semantics, i.e. int/int and long/long returns a float),
+"warn" (old division semantics with a warning for int/int and
+long/long), or "warnall" (old division semantics with a warning for
+all use of the division operator).  For a use of "warnall", see the
+Tools/scripts/fixdiv.py script.
+.TP
+.B \-S
+Disable the import of the module
+.I site
+and the site-dependent manipulations of
+.I sys.path
+that it entails.
+.TP
+.B \-t
+Issue a warning when a source file mixes tabs and spaces for
+indentation in a way that makes it depend on the worth of a tab
+expressed in spaces.  Issue an error when the option is given twice.
+.TP
+.B \-u
+Force stdin, stdout and stderr to be totally unbuffered.  On systems
+where it matters, also put stdin, stdout and stderr in binary mode.
+Note that there is internal buffering in xreadlines(), readlines() and
+file-object iterators ("for line in sys.stdin") which is not
+influenced by this option.  To work around this, you will want to use
+"sys.stdin.readline()" inside a "while 1:" loop.
+.TP
+.B \-v
+Print a message each time a module is initialized, showing the place
+(filename or built-in module) from which it is loaded.  When given
+twice, print a message for each file that is checked for when 
+searching for a module.  Also provides information on module cleanup
+at exit.
+.TP
+.B \-V
+Prints the Python version number of the executable and exits.
+.TP
+.BI "\-W " argument
+Warning control.  Python sometimes prints warning message to
+.IR sys.stderr .
+A typical warning message has the following form:
+.IB file ":" line ": " category ": " message.
+By default, each warning is printed once for each source line where it
+occurs.  This option controls how often warnings are printed.
+Multiple
+.B \-W
+options may be given; when a warning matches more than one
+option, the action for the last matching option is performed.
+Invalid
+.B \-W
+options are ignored (a warning message is printed about invalid
+options when the first warning is issued).  Warnings can also be
+controlled from within a Python program using the
+.I warnings
+module.
+
+The simplest form of
+.I argument
+is one of the following
+.I action
+strings (or a unique abbreviation):
+.B ignore
+to ignore all warnings;
+.B default
+to explicitly request the default behavior (printing each warning once
+per source line);
+.B all
+to print a warning each time it occurs (this may generate many
+messages if a warning is triggered repeatedly for the same source
+line, such as inside a loop);
+.B module
+to print each warning only only the first time it occurs in each
+module;
+.B once
+to print each warning only the first time it occurs in the program; or
+.B error
+to raise an exception instead of printing a warning message.
+
+The full form of
+.I argument
+is
+.IB action : message : category : module : line.
+Here,
+.I action
+is as explained above but only applies to messages that match the
+remaining fields.  Empty fields match all values; trailing empty
+fields may be omitted.  The
+.I message
+field matches the start of the warning message printed; this match is
+case-insensitive.  The
+.I category
+field matches the warning category.  This must be a class name; the
+match test whether the actual warning category of the message is a
+subclass of the specified warning category.  The full class name must
+be given.  The
+.I module
+field matches the (fully-qualified) module name; this match is
+case-sensitive.  The
+.I line
+field matches the line number, where zero matches all line numbers and
+is thus equivalent to an omitted line number.
+.TP
+.B \-x
+Skip the first line of the source.  This is intended for a DOS
+specific hack only.  Warning: the line numbers in error messages will
+be off by one!
+.SH INTERPRETER INTERFACE
+The interpreter interface resembles that of the UNIX shell: when
+called with standard input connected to a tty device, it prompts for
+commands and executes them until an EOF is read; when called with a
+file name argument or with a file as standard input, it reads and
+executes a
+.I script
+from that file;
+when called with
+.B \-c
+.I command,
+it executes the Python statement(s) given as
+.I command.
+Here
+.I command
+may contain multiple statements separated by newlines.
+Leading whitespace is significant in Python statements!
+In non-interactive mode, the entire input is parsed before it is
+executed.
+.PP
+If available, the script name and additional arguments thereafter are
+passed to the script in the Python variable
+.I sys.argv ,
+which is a list of strings (you must first
+.I import sys
+to be able to access it).
+If no script name is given,
+.I sys.argv[0]
+is an empty string; if
+.B \-c
+is used,
+.I sys.argv[0]
+contains the string
+.I '-c'.
+Note that options interpreted by the Python interpreter itself
+are not placed in
+.I sys.argv.
+.PP
+In interactive mode, the primary prompt is `>>>'; the second prompt
+(which appears when a command is not complete) is `...'.
+The prompts can be changed by assignment to
+.I sys.ps1
+or
+.I sys.ps2.
+The interpreter quits when it reads an EOF at a prompt.
+When an unhandled exception occurs, a stack trace is printed and
+control returns to the primary prompt; in non-interactive mode, the
+interpreter exits after printing the stack trace.
+The interrupt signal raises the
+.I Keyboard\%Interrupt
+exception; other UNIX signals are not caught (except that SIGPIPE is
+sometimes ignored, in favor of the
+.I IOError
+exception).  Error messages are written to stderr.
+.SH FILES AND DIRECTORIES
+These are subject to difference depending on local installation
+conventions; ${prefix} and ${exec_prefix} are installation-dependent
+and should be interpreted as for GNU software; they may be the same.
+The default for both is \fI/usr/local\fP.
+.IP \fI${exec_prefix}/bin/python\fP
+Recommended location of the interpreter.
+.PP
+.I ${prefix}/lib/python<version>
+.br
+.I ${exec_prefix}/lib/python<version>
+.RS
+Recommended locations of the directories containing the standard
+modules.
+.RE
+.PP
+.I ${prefix}/include/python<version>
+.br
+.I ${exec_prefix}/include/python<version>
+.RS
+Recommended locations of the directories containing the include files
+needed for developing Python extensions and embedding the
+interpreter.
+.RE
+.IP \fI~/.pythonrc.py\fP
+User-specific initialization file loaded by the \fIuser\fP module;
+not used by default or by most applications.
+.SH ENVIRONMENT VARIABLES
+.IP PYTHONHOME
+Change the location of the standard Python libraries.  By default, the
+libraries are searched in ${prefix}/lib/python<version> and
+${exec_prefix}/lib/python<version>, where ${prefix} and ${exec_prefix}
+are installation-dependent directories, both defaulting to
+\fI/usr/local\fP.  When $PYTHONHOME is set to a single directory, its value
+replaces both ${prefix} and ${exec_prefix}.  To specify different values
+for these, set $PYTHONHOME to ${prefix}:${exec_prefix}.
+.IP PYTHONPATH
+Augments the default search path for module files.
+The format is the same as the shell's $PATH: one or more directory
+pathnames separated by colons.
+Non-existent directories are silently ignored.
+The default search path is installation dependent, but generally
+begins with ${prefix}/lib/python<version> (see PYTHONHOME above).
+The default search path is always appended to $PYTHONPATH.
+If a script argument is given, the directory containing the script is
+inserted in the path in front of $PYTHONPATH.
+The search path can be manipulated from within a Python program as the
+variable
+.I sys.path .
+.IP PYTHONSTARTUP
+If this is the name of a readable file, the Python commands in that
+file are executed before the first prompt is displayed in interactive
+mode.
+The file is executed in the same name space where interactive commands
+are executed so that objects defined or imported in it can be used
+without qualification in the interactive session.
+You can also change the prompts
+.I sys.ps1
+and
+.I sys.ps2
+in this file.
+.IP PYTHONY2K
+Set this to a non-empty string to cause the \fItime\fP module to
+require dates specified as strings to include 4-digit years, otherwise
+2-digit years are converted based on rules described in the \fItime\fP
+module documentation.
+.IP PYTHONOPTIMIZE
+If this is set to a non-empty string it is equivalent to specifying
+the \fB\-O\fP option. If set to an integer, it is equivalent to
+specifying \fB\-O\fP multiple times.
+.IP PYTHONDEBUG
+If this is set to a non-empty string it is equivalent to specifying
+the \fB\-d\fP option. If set to an integer, it is equivalent to
+specifying \fB\-d\fP multiple times.
+.IP PYTHONINSPECT
+If this is set to a non-empty string it is equivalent to specifying
+the \fB\-i\fP option.
+.IP PYTHONUNBUFFERED
+If this is set to a non-empty string it is equivalent to specifying
+the \fB\-u\fP option.
+.IP PYTHONVERBOSE
+If this is set to a non-empty string it is equivalent to specifying
+the \fB\-v\fP option. If set to an integer, it is equivalent to
+specifying \fB\-v\fP multiple times. 
+.SH AUTHOR
+The Python Software Foundation: http://www.python.org/psf
+.SH INTERNET RESOURCES
+Main website:  http://www.python.org/
+.br
+Documentation:  http://docs.python.org/
+.br
+Community website:  http://starship.python.net/
+.br
+Developer resources:  http://www.python.org/dev/
+.br
+FTP:  ftp://ftp.python.org/pub/python/
+.br
+Module repository:  http://www.vex.net/parnassus/
+.br
+Newsgroups:  comp.lang.python, comp.lang.python.announce
+.SH LICENSING
+Python is distributed under an Open Source license.  See the file
+"LICENSE" in the Python source distribution for information on terms &
+conditions for accessing and otherwise using Python and for a
+DISCLAIMER OF ALL WARRANTIES.

Added: vendor/Python/current/Misc/setuid-prog.c
===================================================================
--- vendor/Python/current/Misc/setuid-prog.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Misc/setuid-prog.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,176 @@
+/*
+   Template for a setuid program that calls a script.
+
+   The script should be in an unwritable directory and should itself
+   be unwritable.  In fact all parent directories up to the root
+   should be unwritable.  The script must not be setuid, that's what
+   this program is for.
+
+   This is a template program.  You need to fill in the name of the
+   script that must be executed.  This is done by changing the
+   definition of FULL_PATH below.
+
+   There are also some rules that should be adhered to when writing
+   the script itself.
+
+   The first and most important rule is to never, ever trust that the
+   user of the program will behave properly.  Program defensively.
+   Check your arguments for reasonableness.  If the user is allowed to
+   create files, check the names of the files.  If the program depends
+   on argv[0] for the action it should perform, check it.
+
+   Assuming the script is a Bourne shell script, the first line of the
+   script should be
+	#!/bin/sh -
+   The - is important, don't omit it.  If you're using esh, the first
+   line should be
+	#!/usr/local/bin/esh -f
+   and for ksh, the first line should be
+	#!/usr/local/bin/ksh -p
+   The script should then set the variable IFS to the string
+   consisting of <space>, <tab>, and <newline>.  After this (*not*
+   before!), the PATH variable should be set to a reasonable value and
+   exported.  Do not expect the PATH to have a reasonable value, so do
+   not trust the old value of PATH.  You should then set the umask of
+   the program by calling
+	umask 077 # or 022 if you want the files to be readable
+   If you plan to change directories, you should either unset CDPATH
+   or set it to a good value.  Setting CDPATH to just ``.'' (dot) is a
+   good idea.
+   If, for some reason, you want to use csh, the first line should be
+	#!/bin/csh -fb
+   You should then set the path variable to something reasonable,
+   without trusting the inherited path.  Here too, you should set the
+   umask using the command
+	umask 077 # or 022 if you want the files to be readable
+*/
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <string.h>
+
+/* CONFIGURATION SECTION */
+
+#ifndef FULL_PATH	/* so that this can be specified from the Makefile */
+/* Uncomment the following line:
+#define FULL_PATH	"/full/path/of/script" 
+* Then comment out the #error line. */
+#error "You must define FULL_PATH somewhere"
+#endif
+#ifndef UMASK
+#define UMASK		077
+#endif
+
+/* END OF CONFIGURATION SECTION */
+
+#if defined(__STDC__) && defined(__sgi)
+#define environ _environ
+#endif
+
+/* don't change def_IFS */
+char def_IFS[] = "IFS= \t\n";
+/* you may want to change def_PATH, but you should really change it in */
+/* your script */
+#ifdef __sgi
+char def_PATH[] = "PATH=/usr/bsd:/usr/bin:/bin:/usr/local/bin:/usr/sbin";
+#else
+char def_PATH[] = "PATH=/usr/ucb:/usr/bin:/bin:/usr/local/bin";
+#endif
+/* don't change def_CDPATH */
+char def_CDPATH[] = "CDPATH=.";
+/* don't change def_ENV */
+char def_ENV[] = "ENV=:";
+
+/*
+   This function changes all environment variables that start with LD_
+   into variables that start with XD_.  This is important since we
+   don't want the script that is executed to use any funny shared
+   libraries.
+
+   The other changes to the environment are, strictly speaking, not
+   needed here.  They can safely be done in the script.  They are done
+   here because we don't trust the script writer (just like the script
+   writer shouldn't trust the user of the script).
+   If IFS is set in the environment, set it to space,tab,newline.
+   If CDPATH is set in the environment, set it to ``.''.
+   Set PATH to a reasonable default.
+*/
+void
+clean_environ(void)
+{
+	char **p;
+	extern char **environ;
+
+	for (p = environ; *p; p++) {
+		if (strncmp(*p, "LD_", 3) == 0)
+			**p = 'X';
+		else if (strncmp(*p, "_RLD", 4) == 0)
+			**p = 'X';
+		else if (strncmp(*p, "PYTHON", 6) == 0)
+			**p = 'X';
+		else if (strncmp(*p, "IFS=", 4) == 0)
+			*p = def_IFS;
+		else if (strncmp(*p, "CDPATH=", 7) == 0)
+			*p = def_CDPATH;
+		else if (strncmp(*p, "ENV=", 4) == 0)
+			*p = def_ENV;
+	}
+	putenv(def_PATH);
+}
+
+int
+main(int argc, char **argv)
+{
+	struct stat statb;
+	gid_t egid = getegid();
+	uid_t euid = geteuid();
+
+	/*
+	   Sanity check #1.
+	   This check should be made compile-time, but that's not possible.
+	   If you're sure that you specified a full path name for FULL_PATH,
+	   you can omit this check.
+	*/
+	if (FULL_PATH[0] != '/') {
+		fprintf(stderr, "%s: %s is not a full path name\n", argv[0],
+			FULL_PATH);
+		fprintf(stderr, "You can only use this wrapper if you\n");
+		fprintf(stderr, "compile it with an absolute path.\n");
+		exit(1);
+	}
+
+	/*
+	   Sanity check #2.
+	   Check that the owner of the script is equal to either the
+	   effective uid or the super user.
+	*/
+	if (stat(FULL_PATH, &statb) < 0) {
+		perror("stat");
+		exit(1);
+	}
+	if (statb.st_uid != 0 && statb.st_uid != euid) {
+		fprintf(stderr, "%s: %s has the wrong owner\n", argv[0],
+			FULL_PATH);
+		fprintf(stderr, "The script should be owned by root,\n");
+		fprintf(stderr, "and shouldn't be writeable by anyone.\n");
+		exit(1);
+	}
+
+	if (setregid(egid, egid) < 0)
+		perror("setregid");
+	if (setreuid(euid, euid) < 0)
+		perror("setreuid");
+
+	clean_environ();
+
+	umask(UMASK);
+
+	while (**argv == '-')	/* don't let argv[0] start with '-' */
+		(*argv)++;
+	execv(FULL_PATH, argv);
+	fprintf(stderr, "%s: could not execute the script\n", argv[0]);
+	exit(1);
+}

Added: vendor/Python/current/Misc/valgrind-python.supp
===================================================================
--- vendor/Python/current/Misc/valgrind-python.supp	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Misc/valgrind-python.supp	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,349 @@
+#
+# This is a valgrind suppression file that should be used when using valgrind.
+#
+#  Here's an example of running valgrind:
+#
+#	cd python/dist/src
+#	valgrind --tool=memcheck --suppressions=Misc/valgrind-python.supp \
+#		./python -E -tt ./Lib/test/regrtest.py -u bsddb,network
+#
+# You must edit Objects/obmalloc.c and uncomment Py_USING_MEMORY_DEBUGGER
+# to use the preferred suppressions with Py_ADDRESS_IN_RANGE.
+#
+# If you do not want to recompile Python, you can uncomment
+# suppressions for PyObject_Free and PyObject_Realloc.
+#
+# See Misc/README.valgrind for more information.
+
+# all tool names: Addrcheck,Memcheck,cachegrind,helgrind,massif
+{
+   ADDRESS_IN_RANGE/Invalid read of size 4
+   Memcheck:Addr4
+   fun:Py_ADDRESS_IN_RANGE
+}
+
+{
+   ADDRESS_IN_RANGE/Invalid read of size 4
+   Memcheck:Value4
+   fun:Py_ADDRESS_IN_RANGE
+}
+
+{
+   ADDRESS_IN_RANGE/Invalid read of size 8 (x86_64 aka amd64)
+   Memcheck:Value8
+   fun:Py_ADDRESS_IN_RANGE
+}
+
+{
+   ADDRESS_IN_RANGE/Conditional jump or move depends on uninitialised value
+   Memcheck:Cond
+   fun:Py_ADDRESS_IN_RANGE
+}
+
+#
+# Leaks (including possible leaks)
+#    Hmmm, I wonder if this masks some real leaks.  I think it does.
+#    Will need to fix that.
+#
+
+{
+   Handle PyMalloc confusing valgrind (possibly leaked)
+   Memcheck:Leak
+   fun:realloc
+   fun:_PyObject_GC_Resize
+   fun:COMMENT_THIS_LINE_TO_DISABLE_LEAK_WARNING
+}
+
+{
+   Handle PyMalloc confusing valgrind (possibly leaked)
+   Memcheck:Leak
+   fun:malloc
+   fun:_PyObject_GC_New
+   fun:COMMENT_THIS_LINE_TO_DISABLE_LEAK_WARNING
+}
+
+{
+   Handle PyMalloc confusing valgrind (possibly leaked)
+   Memcheck:Leak
+   fun:malloc
+   fun:_PyObject_GC_NewVar
+   fun:COMMENT_THIS_LINE_TO_DISABLE_LEAK_WARNING
+}
+
+#
+# Non-python specific leaks
+#
+
+{
+   Handle pthread issue (possibly leaked)
+   Memcheck:Leak
+   fun:calloc
+   fun:allocate_dtv
+   fun:_dl_allocate_tls_storage
+   fun:_dl_allocate_tls
+}
+
+{
+   Handle pthread issue (possibly leaked)
+   Memcheck:Leak
+   fun:memalign
+   fun:_dl_allocate_tls_storage
+   fun:_dl_allocate_tls
+}
+
+###{
+###   ADDRESS_IN_RANGE/Invalid read of size 4
+###   Memcheck:Addr4
+###   fun:PyObject_Free
+###}
+###
+###{
+###   ADDRESS_IN_RANGE/Invalid read of size 4
+###   Memcheck:Value4
+###   fun:PyObject_Free
+###}
+###
+###{
+###   ADDRESS_IN_RANGE/Conditional jump or move depends on uninitialised value
+###   Memcheck:Cond
+###   fun:PyObject_Free
+###}
+
+###{
+###   ADDRESS_IN_RANGE/Invalid read of size 4
+###   Memcheck:Addr4
+###   fun:PyObject_Realloc
+###}
+###
+###{
+###   ADDRESS_IN_RANGE/Invalid read of size 4
+###   Memcheck:Value4
+###   fun:PyObject_Realloc
+###}
+###
+###{
+###   ADDRESS_IN_RANGE/Conditional jump or move depends on uninitialised value
+###   Memcheck:Cond
+###   fun:PyObject_Realloc
+###}
+
+###
+### All the suppressions below are for errors that occur within libraries
+### that Python uses.  The problems to not appear to be related to Python's
+### use of the libraries.
+###
+
+{
+   Generic gentoo ld problems
+   Memcheck:Cond
+   obj:/lib/ld-2.3.4.so
+   obj:/lib/ld-2.3.4.so
+   obj:/lib/ld-2.3.4.so
+   obj:/lib/ld-2.3.4.so
+}
+
+{
+   DBM problems, see test_dbm
+   Memcheck:Param
+   write(buf)
+   fun:write
+   obj:/usr/lib/libdb1.so.2
+   obj:/usr/lib/libdb1.so.2
+   obj:/usr/lib/libdb1.so.2
+   obj:/usr/lib/libdb1.so.2
+   fun:dbm_close
+}
+
+{
+   DBM problems, see test_dbm
+   Memcheck:Value8
+   fun:memmove
+   obj:/usr/lib/libdb1.so.2
+   obj:/usr/lib/libdb1.so.2
+   obj:/usr/lib/libdb1.so.2
+   obj:/usr/lib/libdb1.so.2
+   fun:dbm_store
+   fun:dbm_ass_sub
+}
+
+{
+   DBM problems, see test_dbm
+   Memcheck:Cond
+   obj:/usr/lib/libdb1.so.2
+   obj:/usr/lib/libdb1.so.2
+   obj:/usr/lib/libdb1.so.2
+   fun:dbm_store
+   fun:dbm_ass_sub
+}
+
+{
+   DBM problems, see test_dbm
+   Memcheck:Cond
+   fun:memmove
+   obj:/usr/lib/libdb1.so.2
+   obj:/usr/lib/libdb1.so.2
+   obj:/usr/lib/libdb1.so.2
+   obj:/usr/lib/libdb1.so.2
+   fun:dbm_store
+   fun:dbm_ass_sub
+}
+
+{
+   GDBM problems, see test_gdbm
+   Memcheck:Param
+   write(buf)
+   fun:write
+   fun:gdbm_open
+
+}
+
+{
+   ZLIB problems, see test_gzip
+   Memcheck:Cond
+   obj:/lib/libz.so.1.2.3
+   obj:/lib/libz.so.1.2.3
+   fun:deflate
+}
+
+{
+   Avoid problems w/readline doing a putenv and leaking on exit
+   Memcheck:Leak
+   fun:malloc
+   fun:xmalloc
+   fun:sh_set_lines_and_columns
+   fun:_rl_get_screen_size
+   fun:_rl_init_terminal_io
+   obj:/lib/libreadline.so.4.3
+   fun:rl_initialize
+}
+
+###
+### These occur from somewhere within the SSL, when running
+###  test_socket_sll.  They are too general to leave on by default.
+###
+###{
+###   somewhere in SSL stuff
+###   Memcheck:Cond
+###   fun:memset
+###}
+###{
+###   somewhere in SSL stuff
+###   Memcheck:Value4
+###   fun:memset
+###}
+###
+###{
+###   somewhere in SSL stuff
+###   Memcheck:Cond
+###   fun:MD5_Update
+###}
+###
+###{
+###   somewhere in SSL stuff
+###   Memcheck:Value4
+###   fun:MD5_Update
+###}
+
+#
+# All of these problems come from using test_socket_ssl
+#
+{
+   from test_socket_ssl
+   Memcheck:Cond
+   fun:BN_bin2bn
+}
+
+{
+   from test_socket_ssl
+   Memcheck:Cond
+   fun:BN_num_bits_word
+}
+
+{
+   from test_socket_ssl
+   Memcheck:Value4
+   fun:BN_num_bits_word
+}
+
+{
+   from test_socket_ssl
+   Memcheck:Cond
+   fun:BN_mod_exp_mont_word
+}
+
+{
+   from test_socket_ssl
+   Memcheck:Cond
+   fun:BN_mod_exp_mont
+}
+
+{
+   from test_socket_ssl
+   Memcheck:Param
+   write(buf)
+   fun:write
+   obj:/usr/lib/libcrypto.so.0.9.7
+}
+
+{
+   from test_socket_ssl
+   Memcheck:Cond
+   fun:RSA_verify
+}
+
+{
+   from test_socket_ssl
+   Memcheck:Value4
+   fun:RSA_verify
+}
+
+{
+   from test_socket_ssl
+   Memcheck:Value4
+   fun:DES_set_key_unchecked
+}
+
+{
+   from test_socket_ssl
+   Memcheck:Value4
+   fun:DES_encrypt2
+}
+
+{
+   from test_socket_ssl
+   Memcheck:Cond
+   obj:/usr/lib/libssl.so.0.9.7
+}
+
+{
+   from test_socket_ssl
+   Memcheck:Value4
+   obj:/usr/lib/libssl.so.0.9.7
+}
+
+{
+   from test_socket_ssl
+   Memcheck:Cond
+   fun:BUF_MEM_grow_clean
+}
+
+{
+   from test_socket_ssl
+   Memcheck:Cond
+   fun:memcpy
+   fun:ssl3_read_bytes
+}
+
+{
+   from test_socket_ssl
+   Memcheck:Cond
+   fun:SHA1_Update
+}
+
+{
+   from test_socket_ssl
+   Memcheck:Value4
+   fun:SHA1_Update
+}
+
+

Added: vendor/Python/current/Misc/vgrindefs
===================================================================
--- vendor/Python/current/Misc/vgrindefs	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Misc/vgrindefs	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,10 @@
+# vgrind is a pretty-printer that takes source code and outputs
+# eye-pleasing postscript.  The entry below should be added to your
+# local vgrindefs file.  Contributed by Neale Pickett <neale at lanl.gov>.
+
+python|Python|py:\
+        :pb=^\d?(def|class)\d\p(\d|\\|\(|\:):\
+        :cb=#:ce=$:sb=":se=\e":lb=':le=\e':\
+        :kw=assert and break class continue def del elif else except\
+         exec finally for from global if import in is lambda not or\
+         pass print raise return try while yield:

Added: vendor/Python/current/Modules/Setup.config.in
===================================================================
--- vendor/Python/current/Modules/Setup.config.in	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/Setup.config.in	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,13 @@
+# This file is transmogrified into Setup.config by config.status.
+
+# The purpose of this file is to conditionally enable certain modules
+# based on configure-time options.
+
+# Threading
+ at USE_THREAD_MODULE@thread threadmodule.c
+
+# The signal module
+ at USE_SIGNAL_MODULE@signal signalmodule.c
+
+# The rest of the modules previously listed in this file are built
+# by the setup.py script in Python 2.1 and later.

Added: vendor/Python/current/Modules/Setup.dist
===================================================================
--- vendor/Python/current/Modules/Setup.dist	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/Setup.dist	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,487 @@
+# -*- makefile -*-
+# The file Setup is used by the makesetup script to construct the files
+# Makefile and config.c, from Makefile.pre and config.c.in,
+# respectively.  The file Setup itself is initially copied from
+# Setup.dist; once it exists it will not be overwritten, so you can edit
+# Setup to your heart's content.  Note that Makefile.pre is created
+# from Makefile.pre.in by the toplevel configure script.
+
+# (VPATH notes: Setup and Makefile.pre are in the build directory, as
+# are Makefile and config.c; the *.in and *.dist files are in the source
+# directory.)
+
+# Each line in this file describes one or more optional modules.
+# Modules enabled here will not be compiled by the setup.py script,
+# so the file can be used to override setup.py's behavior.
+
+# Lines have the following structure:
+#
+# <module> ... [<sourcefile> ...] [<cpparg> ...] [<library> ...]
+#
+# <sourcefile> is anything ending in .c (.C, .cc, .c++ are C++ files)
+# <cpparg> is anything starting with -I, -D, -U or -C
+# <library> is anything ending in .a or beginning with -l or -L
+# <module> is anything else but should be a valid Python
+# identifier (letters, digits, underscores, beginning with non-digit)
+#
+# (As the makesetup script changes, it may recognize some other
+# arguments as well, e.g. *.so and *.sl as libraries.  See the big
+# case statement in the makesetup script.)
+#
+# Lines can also have the form
+#
+# <name> = <value>
+#
+# which defines a Make variable definition inserted into Makefile.in
+#
+# Finally, if a line contains just the word "*shared*" (without the
+# quotes but with the stars), then the following modules will not be
+# built statically.  The build process works like this:
+#
+# 1. Build all modules that are declared as static in Modules/Setup,
+#    combine them into libpythonxy.a, combine that into python.
+# 2. Build all modules that are listed as shared in Modules/Setup.
+# 3. Invoke setup.py. That builds all modules that
+#    a) are not builtin, and
+#    b) are not listed in Modules/Setup, and
+#    c) can be build on the target
+#
+# Therefore, modules declared to be shared will not be
+# included in the config.c file, nor in the list of objects to be
+# added to the library archive, and their linker options won't be
+# added to the linker options. Rules to create their .o files and
+# their shared libraries will still be added to the Makefile, and
+# their names will be collected in the Make variable SHAREDMODS.  This
+# is used to build modules as shared libraries.  (They can be
+# installed using "make sharedinstall", which is implied by the
+# toplevel "make install" target.)  (For compatibility,
+# *noconfig* has the same effect as *shared*.)
+#
+# In addition, *static* explicitly declares the following modules to
+# be static.  Lines containing "*static*" and "*shared*" may thus
+# alternate throughout this file.
+
+# NOTE: As a standard policy, as many modules as can be supported by a
+# platform should be present.  The distribution comes with all modules
+# enabled that are supported by most platforms and don't require you
+# to ftp sources from elsewhere.
+
+
+# Some special rules to define PYTHONPATH.
+# Edit the definitions below to indicate which options you are using.
+# Don't add any whitespace or comments!
+
+# Directories where library files get installed.
+# DESTLIB is for Python modules; MACHDESTLIB for shared libraries.
+DESTLIB=$(LIBDEST)
+MACHDESTLIB=$(BINLIBDEST)
+
+# NOTE: all the paths are now relative to the prefix that is computed
+# at run time!
+
+# Standard path -- don't edit.
+# No leading colon since this is the first entry.
+# Empty since this is now just the runtime prefix.
+DESTPATH=
+
+# Site specific path components -- should begin with : if non-empty
+SITEPATH=
+
+# Standard path components for test modules
+TESTPATH=
+
+# Path components for machine- or system-dependent modules and shared libraries
+MACHDEPPATH=:plat-$(MACHDEP)
+EXTRAMACHDEPPATH=
+
+# Path component for the Tkinter-related modules
+# The TKPATH variable is always enabled, to save you the effort.
+TKPATH=:lib-tk
+
+COREPYTHONPATH=$(DESTPATH)$(SITEPATH)$(TESTPATH)$(MACHDEPPATH)$(EXTRAMACHDEPPATH)$(TKPATH)
+PYTHONPATH=$(COREPYTHONPATH)
+
+
+# The modules listed here can't be built as shared libraries for
+# various reasons; therefore they are listed here instead of in the
+# normal order.
+
+# This only contains the minimal set of modules required to run the 
+# setup.py script in the root of the Python source tree.
+
+posix posixmodule.c		# posix (UNIX) system calls
+errno errnomodule.c		# posix (UNIX) errno values
+pwd pwdmodule.c			# this is needed to find out the user's home dir
+				# if $HOME is not set
+_sre _sre.c			# Fredrik Lundh's new regular expressions
+_codecs _codecsmodule.c		# access to the builtin codecs and codec registry
+
+# The zipimport module is always imported at startup. Having it as a
+# builtin module avoids some bootstrapping problems and reduces overhead.
+zipimport zipimport.c
+
+# The rest of the modules listed in this file are all commented out by
+# default.  Usually they can be detected and built as dynamically
+# loaded modules by the new setup.py script added in Python 2.1.  If
+# you're on a platform that doesn't support dynamic loading, want to 
+# compile modules statically into the Python binary, or need to 
+# specify some odd set of compiler switches, you can uncomment the 
+# appropriate lines below.
+
+# ======================================================================
+
+# The Python symtable module depends on .h files that setup.py doesn't track
+_symtable symtablemodule.c
+
+# The SGI specific GL module:
+
+GLHACK=-Dclear=__GLclear
+#gl glmodule.c cgensupport.c -I$(srcdir) $(GLHACK) -lgl -lX11
+
+# Pure module.  Cannot be linked dynamically.
+# -DWITH_QUANTIFY, -DWITH_PURIFY, or -DWITH_ALL_PURE
+#WHICH_PURE_PRODUCTS=-DWITH_ALL_PURE
+#PURE_INCLS=-I/usr/local/include
+#PURE_STUBLIBS=-L/usr/local/lib -lpurify_stubs -lquantify_stubs
+#pure puremodule.c $(WHICH_PURE_PRODUCTS) $(PURE_INCLS) $(PURE_STUBLIBS)
+
+# Uncommenting the following line tells makesetup that all following
+# modules are to be built as shared libraries (see above for more
+# detail; also note that *static* reverses this effect):
+
+#*shared*
+
+# GNU readline.  Unlike previous Python incarnations, GNU readline is
+# now incorporated in an optional module, configured in the Setup file
+# instead of by a configure script switch.  You may have to insert a
+# -L option pointing to the directory where libreadline.* lives,
+# and you may have to change -ltermcap to -ltermlib or perhaps remove
+# it, depending on your system -- see the GNU readline instructions.
+# It's okay for this to be a shared library, too.
+
+#readline readline.c -lreadline -ltermcap
+
+
+# Modules that should always be present (non UNIX dependent):
+
+#array arraymodule.c	# array objects
+#cmath cmathmodule.c # -lm # complex math library functions
+#math mathmodule.c # -lm # math library functions, e.g. sin()
+#_struct _struct.c	# binary structure packing/unpacking
+#time timemodule.c # -lm # time operations and variables
+#operator operator.c	# operator.add() and similar goodies
+#_weakref _weakref.c	# basic weak reference support
+#_testcapi _testcapimodule.c    # Python C API test module
+#_random _randommodule.c	# Random number generator
+#collections collectionsmodule.c # Container types
+#itertools itertoolsmodule.c	# Functions creating iterators for efficient looping 
+#strop stropmodule.c		# String manipulations
+
+#unicodedata unicodedata.c    # static Unicode character database
+
+# access to ISO C locale support
+#_locale _localemodule.c  # -lintl
+
+
+# Modules with some UNIX dependencies -- on by default:
+# (If you have a really backward UNIX, select and socket may not be
+# supported...)
+
+#fcntl fcntlmodule.c	# fcntl(2) and ioctl(2)
+#spwd spwdmodule.c		# spwd(3) 
+#grp grpmodule.c		# grp(3)
+#select selectmodule.c	# select(2); not on ancient System V
+
+# Memory-mapped files (also works on Win32).
+#mmap mmapmodule.c
+
+# CSV file helper
+#_csv _csv.c
+
+# Socket module helper for socket(2)
+#_socket socketmodule.c
+
+# Socket module helper for SSL support; you must comment out the other
+# socket line above, and possibly edit the SSL variable:
+#SSL=/usr/local/ssl
+#_ssl _ssl.c \
+#	-DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl \
+#	-L$(SSL)/lib -lssl -lcrypto
+
+# The crypt module is now disabled by default because it breaks builds
+# on many systems (where -lcrypt is needed), e.g. Linux (I believe).
+#
+# First, look at Setup.config; configure may have set this for you.
+
+#crypt cryptmodule.c # -lcrypt	# crypt(3); needs -lcrypt on some systems
+
+
+# Some more UNIX dependent modules -- off by default, since these
+# are not supported by all UNIX systems:
+
+#nis nismodule.c -lnsl	# Sun yellow pages -- not everywhere
+#termios termios.c	# Steen Lumholt's termios module
+#resource resource.c	# Jeremy Hylton's rlimit interface
+
+
+# Multimedia modules -- off by default.
+# These don't work for 64-bit platforms!!!
+# #993173 says audioop works on 64-bit platforms, though.
+# These represent audio samples or images as strings:
+
+#audioop audioop.c	# Operations on audio samples
+#imageop imageop.c	# Operations on images
+#rgbimg rgbimgmodule.c	# Read SGI RGB image files (but coded portably)
+
+
+# Note that the _md5 and _sha modules are normally only built if the
+# system does not have the OpenSSL libs containing an optimized version.
+
+# The _md5 module implements the RSA Data Security, Inc. MD5
+# Message-Digest Algorithm, described in RFC 1321.  The necessary files
+# md5.c and md5.h are included here.
+
+#_md5 md5module.c md5.c
+
+
+# The _sha module implements the SHA checksum algorithm.
+# (NIST's Secure Hash Algorithm.)
+#_sha shamodule.c
+
+
+# SGI IRIX specific modules -- off by default.
+
+# These module work on any SGI machine:
+
+# *** gl must be enabled higher up in this file ***
+#fm fmmodule.c $(GLHACK) -lfm -lgl		# Font Manager
+#sgi sgimodule.c			# sgi.nap() and a few more
+
+# This module requires the header file
+# /usr/people/4Dgifts/iristools/include/izoom.h:
+#imgfile imgfile.c -limage -lgutil -lgl -lm	# Image Processing Utilities
+
+
+# These modules require the Multimedia Development Option (I think):
+
+#al almodule.c -laudio			# Audio Library
+#cd cdmodule.c -lcdaudio -lds -lmediad	# CD Audio Library
+#cl clmodule.c -lcl -lawareaudio	# Compression Library
+#sv svmodule.c yuvconvert.c -lsvideo -lXext -lX11	# Starter Video
+
+
+# The FORMS library, by Mark Overmars, implements user interface
+# components such as dialogs and buttons using SGI's GL and FM
+# libraries.  You must ftp the FORMS library separately from
+# ftp://ftp.cs.ruu.nl/pub/SGI/FORMS.  It was tested with FORMS 2.2a.
+# NOTE: if you want to be able to use FORMS and curses simultaneously
+# (or both link them statically into the same binary), you must
+# compile all of FORMS with the cc option "-Dclear=__GLclear".
+
+# The FORMS variable must point to the FORMS subdirectory of the forms
+# toplevel directory:
+
+#FORMS=/ufs/guido/src/forms/FORMS
+#fl flmodule.c -I$(FORMS) $(GLHACK) $(FORMS)/libforms.a -lfm -lgl
+
+
+# SunOS specific modules -- off by default:
+
+#sunaudiodev sunaudiodev.c
+
+
+# A Linux specific module -- off by default; this may also work on 
+# some *BSDs.
+
+#linuxaudiodev linuxaudiodev.c
+
+
+# George Neville-Neil's timing module:
+
+#timing timingmodule.c
+
+
+# The _tkinter module.
+#
+# The command for _tkinter is long and site specific.  Please
+# uncomment and/or edit those parts as indicated.  If you don't have a
+# specific extension (e.g. Tix or BLT), leave the corresponding line
+# commented out.  (Leave the trailing backslashes in!  If you
+# experience strange errors, you may want to join all uncommented
+# lines and remove the backslashes -- the backslash interpretation is
+# done by the shell's "read" command and it may not be implemented on
+# every system.
+
+# *** Always uncomment this (leave the leading underscore in!):
+# _tkinter _tkinter.c tkappinit.c -DWITH_APPINIT \
+# *** Uncomment and edit to reflect where your Tcl/Tk libraries are:
+#	-L/usr/local/lib \
+# *** Uncomment and edit to reflect where your Tcl/Tk headers are:
+#	-I/usr/local/include \
+# *** Uncomment and edit to reflect where your X11 header files are:
+#	-I/usr/X11R6/include \
+# *** Or uncomment this for Solaris:
+#	-I/usr/openwin/include \
+# *** Uncomment and edit for Tix extension only:
+#	-DWITH_TIX -ltix8.1.8.2 \
+# *** Uncomment and edit for BLT extension only:
+#	-DWITH_BLT -I/usr/local/blt/blt8.0-unoff/include -lBLT8.0 \
+# *** Uncomment and edit for PIL (TkImaging) extension only:
+#     (See http://www.pythonware.com/products/pil/ for more info)
+#	-DWITH_PIL -I../Extensions/Imaging/libImaging  tkImaging.c \
+# *** Uncomment and edit for TOGL extension only:
+#	-DWITH_TOGL togl.c \
+# *** Uncomment and edit to reflect your Tcl/Tk versions:
+#	-ltk8.2 -ltcl8.2 \
+# *** Uncomment and edit to reflect where your X11 libraries are:
+#	-L/usr/X11R6/lib \
+# *** Or uncomment this for Solaris:
+#	-L/usr/openwin/lib \
+# *** Uncomment these for TOGL extension only:
+#	-lGL -lGLU -lXext -lXmu \
+# *** Uncomment for AIX:
+#	-lld \
+# *** Always uncomment this; X11 libraries to link with:
+#	-lX11
+
+# Lance Ellinghaus's syslog module
+#syslog syslogmodule.c		# syslog daemon interface
+
+
+# Curses support, requring the System V version of curses, often
+# provided by the ncurses library.  e.g. on Linux, link with -lncurses
+# instead of -lcurses).
+#
+# First, look at Setup.config; configure may have set this for you.
+
+#_curses _cursesmodule.c -lcurses -ltermcap
+# Wrapper for the panel library that's part of ncurses and SYSV curses.
+#_curses_panel _curses_panel.c -lpanel -lncurses 
+
+
+# Generic (SunOS / SVR4) dynamic loading module.
+# This is not needed for dynamic loading of Python modules --
+# it is a highly experimental and dangerous device for calling
+# *arbitrary* C functions in *arbitrary* shared libraries:
+
+#dl dlmodule.c
+
+
+# Modules that provide persistent dictionary-like semantics.  You will
+# probably want to arrange for at least one of them to be available on
+# your machine, though none are defined by default because of library
+# dependencies.  The Python module anydbm.py provides an
+# implementation independent wrapper for these; dumbdbm.py provides
+# similar functionality (but slower of course) implemented in Python.
+
+# The standard Unix dbm module has been moved to Setup.config so that
+# it will be compiled as a shared library by default.  Compiling it as
+# a built-in module causes conflicts with the pybsddb3 module since it
+# creates a static dependency on an out-of-date version of db.so.
+#
+# First, look at Setup.config; configure may have set this for you.
+
+#dbm dbmmodule.c 	# dbm(3) may require -lndbm or similar
+
+# Anthony Baxter's gdbm module.  GNU dbm(3) will require -lgdbm:
+#
+# First, look at Setup.config; configure may have set this for you.
+
+#gdbm gdbmmodule.c -I/usr/local/include -L/usr/local/lib -lgdbm
+
+
+# Sleepycat Berkeley DB interface.
+#
+# This requires the Sleepycat DB code, see http://www.sleepycat.com/
+# The earliest supported version of that library is 3.0, the latest
+# supported version is 4.0 (4.1 is specifically not supported, as that
+# changes the semantics of transactional databases). A list of available
+# releases can be found at
+#
+# http://www.sleepycat.com/update/index.html
+#
+# Edit the variables DB and DBLIBVERto point to the db top directory
+# and the subdirectory of PORT where you built it.
+#DB=/usr/local/BerkeleyDB.4.0
+#DBLIBVER=4.0
+#DBINC=$(DB)/include
+#DBLIB=$(DB)/lib
+#_bsddb _bsddb.c -I$(DBINC) -L$(DBLIB) -ldb-$(DBLIBVER)
+
+# Historical Berkeley DB 1.85
+#
+# This module is deprecated; the 1.85 version of the Berkeley DB library has
+# bugs that can cause data corruption. If you can, use later versions of the
+# library instead, available from <http://www.sleepycat.com/>.
+
+#DB=/depot/sundry/src/berkeley-db/db.1.85
+#DBPORT=$(DB)/PORT/irix.5.3
+#bsddb185 bsddbmodule.c -I$(DBPORT)/include -I$(DBPORT) $(DBPORT)/libdb.a
+
+
+
+# Helper module for various ascii-encoders
+#binascii binascii.c
+
+# Fred Drake's interface to the Python parser
+#parser parsermodule.c
+
+# cStringIO and cPickle
+#cStringIO cStringIO.c
+#cPickle cPickle.c
+
+
+# Lee Busby's SIGFPE modules.
+# The library to link fpectl with is platform specific.
+# Choose *one* of the options below for fpectl:
+
+# For SGI IRIX (tested on 5.3):
+#fpectl fpectlmodule.c -lfpe
+
+# For Solaris with SunPro compiler (tested on Solaris 2.5 with SunPro C 4.2):
+# (Without the compiler you don't have -lsunmath.)
+#fpectl fpectlmodule.c -R/opt/SUNWspro/lib -lsunmath -lm
+
+# For other systems: see instructions in fpectlmodule.c.
+#fpectl fpectlmodule.c ...
+
+# Test module for fpectl.  No extra libraries needed.
+#fpetest fpetestmodule.c
+
+# Andrew Kuchling's zlib module.
+# This require zlib 1.1.3 (or later).
+# See http://www.gzip.org/zlib/
+#zlib zlibmodule.c -I$(prefix)/include -L$(exec_prefix)/lib -lz
+
+# Interface to the Expat XML parser
+#
+# Expat was written by James Clark and is now maintained by a group of
+# developers on SourceForge; see www.libexpat.org for more
+# information.  The pyexpat module was written by Paul Prescod after a
+# prototype by Jack Jansen.  Source of Expat 1.95.2 is included in
+# Modules/expat/.  Usage of a system shared libexpat.so/expat.dll is
+# not advised.
+#
+# More information on Expat can be found at www.libexpat.org.
+#
+#EXPAT_DIR=/usr/local/src/expat-1.95.2
+#pyexpat pyexpat.c -DHAVE_EXPAT_H -I$(EXPAT_DIR)/lib -L$(EXPAT_DIR) -lexpat
+
+
+# Hye-Shik Chang's CJKCodecs
+
+# multibytecodec is required for all the other CJK codec modules
+#_multibytecodec cjkcodecs/multibytecodec.c
+
+#_codecs_cn cjkcodecs/_codecs_cn.c
+#_codecs_hk cjkcodecs/_codecs_hk.c
+#_codecs_iso2022 cjkcodecs/_codecs_iso2022.c
+#_codecs_jp cjkcodecs/_codecs_jp.c
+#_codecs_kr cjkcodecs/_codecs_kr.c
+#_codecs_tw cjkcodecs/_codecs_tw.c
+
+# Example -- included for reference only:
+# xx xxmodule.c
+
+# Another example -- the 'xxsubtype' module shows C-level subtyping in action
+xxsubtype xxsubtype.c

Added: vendor/Python/current/Modules/_bisectmodule.c
===================================================================
--- vendor/Python/current/Modules/_bisectmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_bisectmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,235 @@
+/* Bisection algorithms. Drop in replacement for bisect.py
+
+Converted to C by Dmitry Vasiliev (dima at hlabs.spb.ru).
+*/
+
+#include "Python.h"
+
+static int
+internal_bisect_right(PyObject *list, PyObject *item, Py_ssize_t lo, Py_ssize_t hi)
+{
+	PyObject *litem;
+	Py_ssize_t mid, res;
+
+	if (hi == -1) {
+		hi = PySequence_Size(list);
+		if (hi < 0)
+			return -1;
+	}
+	while (lo < hi) {
+		mid = (lo + hi) / 2;
+		litem = PySequence_GetItem(list, mid);
+		if (litem == NULL)
+			return -1;
+		res = PyObject_RichCompareBool(item, litem, Py_LT);
+		Py_DECREF(litem);
+		if (res < 0)
+			return -1;
+		if (res)
+			hi = mid;
+		else
+			lo = mid + 1;
+	}
+	return lo;
+}
+
+static PyObject *
+bisect_right(PyObject *self, PyObject *args, PyObject *kw)
+{
+	PyObject *list, *item;
+	int lo = 0;
+	int hi = -1;
+	int index;
+	static char *keywords[] = {"a", "x", "lo", "hi", NULL};
+
+	if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|ii:bisect_right",
+		keywords, &list, &item, &lo, &hi))
+		return NULL;
+	index = internal_bisect_right(list, item, lo, hi);
+	if (index < 0)
+		return NULL;
+	return PyInt_FromLong(index);
+}
+
+PyDoc_STRVAR(bisect_right_doc,
+"bisect_right(a, x[, lo[, hi]]) -> index\n\
+\n\
+Return the index where to insert item x in list a, assuming a is sorted.\n\
+\n\
+The return value i is such that all e in a[:i] have e <= x, and all e in\n\
+a[i:] have e > x.  So if x already appears in the list, i points just\n\
+beyond the rightmost x already there\n\
+\n\
+Optional args lo (default 0) and hi (default len(a)) bound the\n\
+slice of a to be searched.\n");
+
+static PyObject *
+insort_right(PyObject *self, PyObject *args, PyObject *kw)
+{
+	PyObject *list, *item, *result;
+	int lo = 0;
+	int hi = -1;
+	int index;
+	static char *keywords[] = {"a", "x", "lo", "hi", NULL};
+
+	if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|ii:insort_right",
+		keywords, &list, &item, &lo, &hi))
+		return NULL;
+	index = internal_bisect_right(list, item, lo, hi);
+	if (index < 0)
+		return NULL;
+	if (PyList_Check(list)) {
+		if (PyList_Insert(list, index, item) < 0)
+			return NULL;
+	} else {
+		result = PyObject_CallMethod(list, "insert", "iO",
+					     index, item);
+		if (result == NULL)
+			return NULL;
+		Py_DECREF(result);
+	}
+
+	Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(insort_right_doc,
+"insort_right(a, x[, lo[, hi]])\n\
+\n\
+Insert item x in list a, and keep it sorted assuming a is sorted.\n\
+\n\
+If x is already in a, insert it to the right of the rightmost x.\n\
+\n\
+Optional args lo (default 0) and hi (default len(a)) bound the\n\
+slice of a to be searched.\n");
+
+static int
+internal_bisect_left(PyObject *list, PyObject *item, int lo, int hi)
+{
+	PyObject *litem;
+	int mid, res;
+
+	if (hi == -1) {
+		hi = PySequence_Size(list);
+		if (hi < 0)
+			return -1;
+	}
+	while (lo < hi) {
+		mid = (lo + hi) / 2;
+		litem = PySequence_GetItem(list, mid);
+		if (litem == NULL)
+			return -1;
+		res = PyObject_RichCompareBool(litem, item, Py_LT);
+		Py_DECREF(litem);
+		if (res < 0)
+			return -1;
+		if (res)
+			lo = mid + 1;
+		else
+			hi = mid;
+	}
+	return lo;
+}
+
+static PyObject *
+bisect_left(PyObject *self, PyObject *args, PyObject *kw)
+{
+	PyObject *list, *item;
+	int lo = 0;
+	int hi = -1;
+	int index;
+	static char *keywords[] = {"a", "x", "lo", "hi", NULL};
+
+	if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|ii:bisect_left",
+		keywords, &list, &item, &lo, &hi))
+		return NULL;
+	index = internal_bisect_left(list, item, lo, hi);
+	if (index < 0)
+		return NULL;
+	return PyInt_FromLong(index);
+}
+
+PyDoc_STRVAR(bisect_left_doc,
+"bisect_left(a, x[, lo[, hi]]) -> index\n\
+\n\
+Return the index where to insert item x in list a, assuming a is sorted.\n\
+\n\
+The return value i is such that all e in a[:i] have e < x, and all e in\n\
+a[i:] have e >= x.  So if x already appears in the list, i points just\n\
+before the leftmost x already there.\n\
+\n\
+Optional args lo (default 0) and hi (default len(a)) bound the\n\
+slice of a to be searched.\n");
+
+static PyObject *
+insort_left(PyObject *self, PyObject *args, PyObject *kw)
+{
+	PyObject *list, *item, *result;
+	int lo = 0;
+	int hi = -1;
+	int index;
+	static char *keywords[] = {"a", "x", "lo", "hi", NULL};
+
+	if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|ii:insort_left",
+		keywords, &list, &item, &lo, &hi))
+		return NULL;
+	index = internal_bisect_left(list, item, lo, hi);
+	if (index < 0)
+		return NULL;
+	if (PyList_Check(list)) {
+		if (PyList_Insert(list, index, item) < 0)
+			return NULL;
+	} else {
+		result = PyObject_CallMethod(list, "insert", "iO",
+					     index, item);
+		if (result == NULL)
+			return NULL;
+		Py_DECREF(result);
+	}
+
+	Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(insort_left_doc,
+"insort_left(a, x[, lo[, hi]])\n\
+\n\
+Insert item x in list a, and keep it sorted assuming a is sorted.\n\
+\n\
+If x is already in a, insert it to the left of the leftmost x.\n\
+\n\
+Optional args lo (default 0) and hi (default len(a)) bound the\n\
+slice of a to be searched.\n");
+
+PyDoc_STRVAR(bisect_doc, "Alias for bisect_right().\n");
+PyDoc_STRVAR(insort_doc, "Alias for insort_right().\n");
+
+static PyMethodDef bisect_methods[] = {
+	{"bisect_right", (PyCFunction)bisect_right,
+		METH_VARARGS|METH_KEYWORDS, bisect_right_doc},
+	{"bisect", (PyCFunction)bisect_right,
+		METH_VARARGS|METH_KEYWORDS, bisect_doc},
+	{"insort_right", (PyCFunction)insort_right,
+		METH_VARARGS|METH_KEYWORDS, insort_right_doc},
+	{"insort", (PyCFunction)insort_right,
+		METH_VARARGS|METH_KEYWORDS, insort_doc},
+	{"bisect_left", (PyCFunction)bisect_left,
+		METH_VARARGS|METH_KEYWORDS, bisect_left_doc},
+	{"insort_left", (PyCFunction)insort_left,
+		METH_VARARGS|METH_KEYWORDS, insort_left_doc},
+	{NULL, NULL} /* sentinel */
+};
+
+PyDoc_STRVAR(module_doc,
+"Bisection algorithms.\n\
+\n\
+This module provides support for maintaining a list in sorted order without\n\
+having to sort the list after each insertion. For long lists of items with\n\
+expensive comparison operations, this can be an improvement over the more\n\
+common approach.\n");
+
+PyMODINIT_FUNC
+init_bisect(void)
+{
+	PyObject *m;
+
+	m = Py_InitModule3("_bisect", bisect_methods, module_doc);
+}

Added: vendor/Python/current/Modules/_bsddb.c
===================================================================
--- vendor/Python/current/Modules/_bsddb.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_bsddb.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,6047 @@
+/*----------------------------------------------------------------------
+  Copyright (c) 1999-2001, Digital Creations, Fredericksburg, VA, USA
+  and Andrew Kuchling. All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions are
+  met:
+
+    o Redistributions of source code must retain the above copyright
+      notice, this list of conditions, and the disclaimer that follows.
+
+    o Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions, and the following disclaimer in
+      the documentation and/or other materials provided with the
+      distribution.
+
+    o Neither the name of Digital Creations nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS AND CONTRIBUTORS *AS
+  IS* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+  TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+  PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL DIGITAL
+  CREATIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+  DAMAGE.
+------------------------------------------------------------------------*/
+
+
+/*
+ * Handwritten code to wrap version 3.x of the Berkeley DB library,
+ * written to replace a SWIG-generated file.  It has since been updated
+ * to compile with BerkeleyDB versions 3.2 through 4.2.
+ *
+ * This module was started by Andrew Kuchling to remove the dependency
+ * on SWIG in a package by Gregory P. Smith <greg at electricrain.com> who
+ * based his work on a similar package by Robin Dunn <robin at alldunn.com>
+ * which wrapped Berkeley DB 2.7.x.
+ *
+ * Development of this module then returned full circle back to Robin Dunn
+ * who worked on behalf of Digital Creations to complete the wrapping of
+ * the DB 3.x API and to build a solid unit test suite.  Robin has
+ * since gone onto other projects (wxPython).
+ *
+ * Gregory P. Smith <greg at electricrain.com> is once again the maintainer.
+ *
+ * Use the pybsddb-users at lists.sf.net mailing list for all questions.
+ * Things can change faster than the header of this file is updated.  This
+ * file is shared with the PyBSDDB project at SourceForge:
+ *
+ * http://pybsddb.sf.net
+ *
+ * This file should remain backward compatible with Python 2.1, but see PEP
+ * 291 for the most current backward compatibility requirements:
+ *
+ * http://www.python.org/peps/pep-0291.html
+ *
+ * This module contains 6 types:
+ *
+ * DB           (Database)
+ * DBCursor     (Database Cursor)
+ * DBEnv        (database environment)
+ * DBTxn        (An explicit database transaction)
+ * DBLock       (A lock handle)
+ * DBSequence   (Sequence)
+ *
+ */
+
+/* --------------------------------------------------------------------- */
+
+/*
+ * Portions of this module, associated unit tests and build scripts are the
+ * result of a contract with The Written Word (http://thewrittenword.com/)
+ * Many thanks go out to them for causing me to raise the bar on quality and
+ * functionality, resulting in a better bsddb3 package for all of us to use.
+ *
+ * --Robin
+ */
+
+/* --------------------------------------------------------------------- */
+
+#include <stddef.h>   /* for offsetof() */
+#include <Python.h>
+#include <db.h>
+
+/* --------------------------------------------------------------------- */
+/* Various macro definitions */
+
+/* 40 = 4.0, 33 = 3.3; this will break if the second number is > 9 */
+#define DBVER (DB_VERSION_MAJOR * 10 + DB_VERSION_MINOR)
+#if DB_VERSION_MINOR > 9
+#error "eek! DBVER can't handle minor versions > 9"
+#endif
+
+#define PY_BSDDB_VERSION "4.4.5.2"
+static char *rcs_id = "$Id: _bsddb.c 53254 2007-01-05 02:09:06Z gregory.p.smith $";
+
+
+#if (PY_VERSION_HEX < 0x02050000)
+typedef int Py_ssize_t;
+#endif
+
+#ifdef WITH_THREAD
+
+/* These are for when calling Python --> C */
+#define MYDB_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS;
+#define MYDB_END_ALLOW_THREADS Py_END_ALLOW_THREADS;
+
+/* For 2.3, use the PyGILState_ calls */
+#if (PY_VERSION_HEX >= 0x02030000)
+#define MYDB_USE_GILSTATE
+#endif
+
+/* and these are for calling C --> Python */
+#if defined(MYDB_USE_GILSTATE)
+#define MYDB_BEGIN_BLOCK_THREADS \
+		PyGILState_STATE __savestate = PyGILState_Ensure();
+#define MYDB_END_BLOCK_THREADS \
+		PyGILState_Release(__savestate);
+#else /* MYDB_USE_GILSTATE */
+/* Pre GILState API - do it the long old way */
+static PyInterpreterState* _db_interpreterState = NULL;
+#define MYDB_BEGIN_BLOCK_THREADS {                              \
+        PyThreadState* prevState;                               \
+        PyThreadState* newState;                                \
+        PyEval_AcquireLock();                                   \
+        newState  = PyThreadState_New(_db_interpreterState);    \
+        prevState = PyThreadState_Swap(newState);
+
+#define MYDB_END_BLOCK_THREADS                                  \
+        newState = PyThreadState_Swap(prevState);               \
+        PyThreadState_Clear(newState);                          \
+        PyEval_ReleaseLock();                                   \
+        PyThreadState_Delete(newState);                         \
+        }
+#endif /* MYDB_USE_GILSTATE */
+
+#else
+/* Compiled without threads - avoid all this cruft */
+#define MYDB_BEGIN_ALLOW_THREADS
+#define MYDB_END_ALLOW_THREADS
+#define MYDB_BEGIN_BLOCK_THREADS
+#define MYDB_END_BLOCK_THREADS
+
+#endif
+
+/* Should DB_INCOMPLETE be turned into a warning or an exception? */
+#define INCOMPLETE_IS_WARNING 1
+
+/* --------------------------------------------------------------------- */
+/* Exceptions */
+
+static PyObject* DBError;               /* Base class, all others derive from this */
+static PyObject* DBCursorClosedError;   /* raised when trying to use a closed cursor object */
+static PyObject* DBKeyEmptyError;       /* DB_KEYEMPTY: also derives from KeyError */
+static PyObject* DBKeyExistError;       /* DB_KEYEXIST */
+static PyObject* DBLockDeadlockError;   /* DB_LOCK_DEADLOCK */
+static PyObject* DBLockNotGrantedError; /* DB_LOCK_NOTGRANTED */
+static PyObject* DBNotFoundError;       /* DB_NOTFOUND: also derives from KeyError */
+static PyObject* DBOldVersionError;     /* DB_OLD_VERSION */
+static PyObject* DBRunRecoveryError;    /* DB_RUNRECOVERY */
+static PyObject* DBVerifyBadError;      /* DB_VERIFY_BAD */
+static PyObject* DBNoServerError;       /* DB_NOSERVER */
+static PyObject* DBNoServerHomeError;   /* DB_NOSERVER_HOME */
+static PyObject* DBNoServerIDError;     /* DB_NOSERVER_ID */
+#if (DBVER >= 33)
+static PyObject* DBPageNotFoundError;   /* DB_PAGE_NOTFOUND */
+static PyObject* DBSecondaryBadError;   /* DB_SECONDARY_BAD */
+#endif
+
+#if !INCOMPLETE_IS_WARNING
+static PyObject* DBIncompleteError;     /* DB_INCOMPLETE */
+#endif
+
+static PyObject* DBInvalidArgError;     /* EINVAL */
+static PyObject* DBAccessError;         /* EACCES */
+static PyObject* DBNoSpaceError;        /* ENOSPC */
+static PyObject* DBNoMemoryError;       /* DB_BUFFER_SMALL (ENOMEM when < 4.3) */
+static PyObject* DBAgainError;          /* EAGAIN */
+static PyObject* DBBusyError;           /* EBUSY  */
+static PyObject* DBFileExistsError;     /* EEXIST */
+static PyObject* DBNoSuchFileError;     /* ENOENT */
+static PyObject* DBPermissionsError;    /* EPERM  */
+
+#if (DBVER < 43)
+#define	DB_BUFFER_SMALL		ENOMEM
+#endif
+
+
+/* --------------------------------------------------------------------- */
+/* Structure definitions */
+
+#if PYTHON_API_VERSION >= 1010       /* python >= 2.1 support weak references */
+#define HAVE_WEAKREF
+#else
+#undef HAVE_WEAKREF
+#endif
+
+/* if Python >= 2.1 better support warnings */
+#if PYTHON_API_VERSION >= 1010
+#define HAVE_WARNINGS
+#else
+#undef HAVE_WARNINGS
+#endif
+
+#if PYTHON_API_VERSION <= 1007
+    /* 1.5 compatibility */
+#define PyObject_New PyObject_NEW
+#define PyObject_Del PyMem_DEL
+#endif
+
+struct behaviourFlags {
+    /* What is the default behaviour when DB->get or DBCursor->get returns a
+       DB_NOTFOUND || DB_KEYEMPTY error?  Return None or raise an exception? */
+    unsigned int getReturnsNone : 1;
+    /* What is the default behaviour for DBCursor.set* methods when DBCursor->get
+     * returns a DB_NOTFOUND || DB_KEYEMPTY  error?  Return None or raise? */
+    unsigned int cursorSetReturnsNone : 1;
+};
+
+#define DEFAULT_GET_RETURNS_NONE                1
+#define DEFAULT_CURSOR_SET_RETURNS_NONE         1   /* 0 in pybsddb < 4.2, python < 2.4 */
+
+typedef struct {
+    PyObject_HEAD
+    DB_ENV*     db_env;
+    u_int32_t   flags;             /* saved flags from open() */
+    int         closed;
+    struct behaviourFlags moduleFlags;
+#ifdef HAVE_WEAKREF
+    PyObject        *in_weakreflist; /* List of weak references */
+#endif
+} DBEnvObject;
+
+
+typedef struct {
+    PyObject_HEAD
+    DB*             db;
+    DBEnvObject*    myenvobj;  /* PyObject containing the DB_ENV */
+    u_int32_t       flags;     /* saved flags from open() */
+    u_int32_t       setflags;  /* saved flags from set_flags() */
+    int             haveStat;
+    struct behaviourFlags moduleFlags;
+#if (DBVER >= 33)
+    PyObject*       associateCallback;
+    PyObject*       btCompareCallback;
+    int             primaryDBType;
+#endif
+#ifdef HAVE_WEAKREF
+    PyObject        *in_weakreflist; /* List of weak references */
+#endif
+} DBObject;
+
+
+typedef struct {
+    PyObject_HEAD
+    DBC*            dbc;
+    DBObject*       mydb;
+#ifdef HAVE_WEAKREF
+    PyObject        *in_weakreflist; /* List of weak references */
+#endif
+} DBCursorObject;
+
+
+typedef struct {
+    PyObject_HEAD
+    DB_TXN*         txn;
+    PyObject        *env;
+#ifdef HAVE_WEAKREF
+    PyObject        *in_weakreflist; /* List of weak references */
+#endif
+} DBTxnObject;
+
+
+typedef struct {
+    PyObject_HEAD
+    DB_LOCK         lock;
+#ifdef HAVE_WEAKREF
+    PyObject        *in_weakreflist; /* List of weak references */
+#endif
+} DBLockObject;
+
+#if (DBVER >= 43)
+typedef struct {
+    PyObject_HEAD
+    DB_SEQUENCE*     sequence;
+    DBObject*        mydb;
+#ifdef HAVE_WEAKREF
+    PyObject        *in_weakreflist; /* List of weak references */
+#endif
+} DBSequenceObject;
+staticforward PyTypeObject DBSequence_Type;
+#endif
+
+staticforward PyTypeObject DB_Type, DBCursor_Type, DBEnv_Type, DBTxn_Type, DBLock_Type;
+
+#define DBObject_Check(v)           ((v)->ob_type == &DB_Type)
+#define DBCursorObject_Check(v)     ((v)->ob_type == &DBCursor_Type)
+#define DBEnvObject_Check(v)        ((v)->ob_type == &DBEnv_Type)
+#define DBTxnObject_Check(v)        ((v)->ob_type == &DBTxn_Type)
+#define DBLockObject_Check(v)       ((v)->ob_type == &DBLock_Type)
+#if (DBVER >= 43)
+#define DBSequenceObject_Check(v)   ((v)->ob_type == &DBSequence_Type)
+#endif
+
+
+/* --------------------------------------------------------------------- */
+/* Utility macros and functions */
+
+#define RETURN_IF_ERR()          \
+    if (makeDBError(err)) {      \
+        return NULL;             \
+    }
+
+#define RETURN_NONE()  Py_INCREF(Py_None); return Py_None;
+
+#define _CHECK_OBJECT_NOT_CLOSED(nonNull, pyErrObj, name) \
+    if ((nonNull) == NULL) {          \
+        PyObject *errTuple = NULL;    \
+        errTuple = Py_BuildValue("(is)", 0, #name " object has been closed"); \
+        PyErr_SetObject((pyErrObj), errTuple);  \
+	Py_DECREF(errTuple);          \
+        return NULL;                  \
+    }
+
+#define CHECK_DB_NOT_CLOSED(dbobj) \
+        _CHECK_OBJECT_NOT_CLOSED(dbobj->db, DBError, DB)
+
+#define CHECK_ENV_NOT_CLOSED(env) \
+        _CHECK_OBJECT_NOT_CLOSED(env->db_env, DBError, DBEnv)
+
+#define CHECK_CURSOR_NOT_CLOSED(curs) \
+        _CHECK_OBJECT_NOT_CLOSED(curs->dbc, DBCursorClosedError, DBCursor)
+
+#if (DBVER >= 43)
+#define CHECK_SEQUENCE_NOT_CLOSED(curs) \
+        _CHECK_OBJECT_NOT_CLOSED(curs->sequence, DBError, DBSequence)
+#endif
+
+#define CHECK_DBFLAG(mydb, flag)    (((mydb)->flags & (flag)) || \
+                                     (((mydb)->myenvobj != NULL) && ((mydb)->myenvobj->flags & (flag))))
+
+#define CLEAR_DBT(dbt)              (memset(&(dbt), 0, sizeof(dbt)))
+
+#define FREE_DBT(dbt)               if ((dbt.flags & (DB_DBT_MALLOC|DB_DBT_REALLOC)) && \
+                                         dbt.data != NULL) { free(dbt.data); dbt.data = NULL; }
+
+
+static int makeDBError(int err);
+
+
+/* Return the access method type of the DBObject */
+static int _DB_get_type(DBObject* self)
+{
+#if (DBVER >= 33)
+    DBTYPE type;
+    int err;
+    err = self->db->get_type(self->db, &type);
+    if (makeDBError(err)) {
+        return -1;
+    }
+    return type;
+#else
+    return self->db->get_type(self->db);
+#endif
+}
+
+
+/* Create a DBT structure (containing key and data values) from Python
+   strings.  Returns 1 on success, 0 on an error. */
+static int make_dbt(PyObject* obj, DBT* dbt)
+{
+    CLEAR_DBT(*dbt);
+    if (obj == Py_None) {
+        /* no need to do anything, the structure has already been zeroed */
+    }
+    else if (!PyArg_Parse(obj, "s#", &dbt->data, &dbt->size)) {
+        PyErr_SetString(PyExc_TypeError,
+                        "Data values must be of type string or None.");
+        return 0;
+    }
+    return 1;
+}
+
+
+/* Recno and Queue DBs can have integer keys.  This function figures out
+   what's been given, verifies that it's allowed, and then makes the DBT.
+
+   Caller MUST call FREE_DBT(key) when done. */
+static int
+make_key_dbt(DBObject* self, PyObject* keyobj, DBT* key, int* pflags)
+{
+    db_recno_t recno;
+    int type;
+
+    CLEAR_DBT(*key);
+    if (keyobj == Py_None) {
+        type = _DB_get_type(self);
+        if (type == -1)
+            return 0;
+        if (type == DB_RECNO || type == DB_QUEUE) {
+            PyErr_SetString(
+                PyExc_TypeError,
+                "None keys not allowed for Recno and Queue DB's");
+            return 0;
+        }
+        /* no need to do anything, the structure has already been zeroed */
+    }
+
+    else if (PyString_Check(keyobj)) {
+        /* verify access method type */
+        type = _DB_get_type(self);
+        if (type == -1)
+            return 0;
+        if (type == DB_RECNO || type == DB_QUEUE) {
+            PyErr_SetString(
+                PyExc_TypeError,
+                "String keys not allowed for Recno and Queue DB's");
+            return 0;
+        }
+
+        key->data = PyString_AS_STRING(keyobj);
+        key->size = PyString_GET_SIZE(keyobj);
+    }
+
+    else if (PyInt_Check(keyobj)) {
+        /* verify access method type */
+        type = _DB_get_type(self);
+        if (type == -1)
+            return 0;
+        if (type == DB_BTREE && pflags != NULL) {
+            /* if BTREE then an Integer key is allowed with the
+             * DB_SET_RECNO flag */
+            *pflags |= DB_SET_RECNO;
+        }
+        else if (type != DB_RECNO && type != DB_QUEUE) {
+            PyErr_SetString(
+                PyExc_TypeError,
+                "Integer keys only allowed for Recno and Queue DB's");
+            return 0;
+        }
+
+        /* Make a key out of the requested recno, use allocated space so DB
+         * will be able to realloc room for the real key if needed. */
+        recno = PyInt_AS_LONG(keyobj);
+        key->data = malloc(sizeof(db_recno_t));
+        if (key->data == NULL) {
+            PyErr_SetString(PyExc_MemoryError, "Key memory allocation failed");
+            return 0;
+        }
+        key->ulen = key->size = sizeof(db_recno_t);
+        memcpy(key->data, &recno, sizeof(db_recno_t));
+        key->flags = DB_DBT_REALLOC;
+    }
+    else {
+        PyErr_Format(PyExc_TypeError,
+                     "String or Integer object expected for key, %s found",
+                     keyobj->ob_type->tp_name);
+        return 0;
+    }
+
+    return 1;
+}
+
+
+/* Add partial record access to an existing DBT data struct.
+   If dlen and doff are set, then the DB_DBT_PARTIAL flag will be set
+   and the data storage/retrieval will be done using dlen and doff. */
+static int add_partial_dbt(DBT* d, int dlen, int doff) {
+    /* if neither were set we do nothing (-1 is the default value) */
+    if ((dlen == -1) && (doff == -1)) {
+        return 1;
+    }
+
+    if ((dlen < 0) || (doff < 0)) {
+        PyErr_SetString(PyExc_TypeError, "dlen and doff must both be >= 0");
+        return 0;
+    }
+
+    d->flags = d->flags | DB_DBT_PARTIAL;
+    d->dlen = (unsigned int) dlen;
+    d->doff = (unsigned int) doff;
+    return 1;
+}
+
+/* a safe strcpy() without the zeroing behaviour and semantics of strncpy. */
+/* TODO: make this use the native libc strlcpy() when available (BSD)      */
+unsigned int our_strlcpy(char* dest, const char* src, unsigned int n)
+{
+    unsigned int srclen, copylen;
+
+    srclen = strlen(src);
+    if (n <= 0)
+	return srclen;
+    copylen = (srclen > n-1) ? n-1 : srclen;
+    /* populate dest[0] thru dest[copylen-1] */
+    memcpy(dest, src, copylen);
+    /* guarantee null termination */
+    dest[copylen] = 0;
+
+    return srclen;
+}
+
+/* Callback used to save away more information about errors from the DB
+ * library. */
+static char _db_errmsg[1024];
+#if (DBVER <= 42)
+static void _db_errorCallback(const char* prefix, char* msg)
+#else
+static void _db_errorCallback(const DB_ENV *db_env,
+	const char* prefix, const char* msg)
+#endif
+{
+    our_strlcpy(_db_errmsg, msg, sizeof(_db_errmsg));
+}
+
+
+/* make a nice exception object to raise for errors. */
+static int makeDBError(int err)
+{
+    char errTxt[2048];  /* really big, just in case... */
+    PyObject *errObj = NULL;
+    PyObject *errTuple = NULL;
+    int exceptionRaised = 0;
+    unsigned int bytes_left;
+
+    switch (err) {
+        case 0:                     /* successful, no error */      break;
+
+#if (DBVER < 41)
+        case DB_INCOMPLETE:
+#if INCOMPLETE_IS_WARNING
+            bytes_left = our_strlcpy(errTxt, db_strerror(err), sizeof(errTxt));
+            /* Ensure that bytes_left never goes negative */
+            if (_db_errmsg[0] && bytes_left < (sizeof(errTxt) - 4)) {
+                bytes_left = sizeof(errTxt) - bytes_left - 4 - 1;
+		assert(bytes_left >= 0);
+                strcat(errTxt, " -- ");
+                strncat(errTxt, _db_errmsg, bytes_left);
+            }
+            _db_errmsg[0] = 0;
+#ifdef HAVE_WARNINGS
+            exceptionRaised = PyErr_Warn(PyExc_RuntimeWarning, errTxt);
+#else
+            fprintf(stderr, errTxt);
+            fprintf(stderr, "\n");
+#endif
+
+#else  /* do an exception instead */
+        errObj = DBIncompleteError;
+#endif
+        break;
+#endif /* DBVER < 41 */
+
+        case DB_KEYEMPTY:           errObj = DBKeyEmptyError;       break;
+        case DB_KEYEXIST:           errObj = DBKeyExistError;       break;
+        case DB_LOCK_DEADLOCK:      errObj = DBLockDeadlockError;   break;
+        case DB_LOCK_NOTGRANTED:    errObj = DBLockNotGrantedError; break;
+        case DB_NOTFOUND:           errObj = DBNotFoundError;       break;
+        case DB_OLD_VERSION:        errObj = DBOldVersionError;     break;
+        case DB_RUNRECOVERY:        errObj = DBRunRecoveryError;    break;
+        case DB_VERIFY_BAD:         errObj = DBVerifyBadError;      break;
+        case DB_NOSERVER:           errObj = DBNoServerError;       break;
+        case DB_NOSERVER_HOME:      errObj = DBNoServerHomeError;   break;
+        case DB_NOSERVER_ID:        errObj = DBNoServerIDError;     break;
+#if (DBVER >= 33)
+        case DB_PAGE_NOTFOUND:      errObj = DBPageNotFoundError;   break;
+        case DB_SECONDARY_BAD:      errObj = DBSecondaryBadError;   break;
+#endif
+        case DB_BUFFER_SMALL:       errObj = DBNoMemoryError;       break;
+
+#if (DBVER >= 43)
+	/* ENOMEM and DB_BUFFER_SMALL were one and the same until 4.3 */
+	case ENOMEM:  errObj = PyExc_MemoryError;   break;
+#endif
+        case EINVAL:  errObj = DBInvalidArgError;   break;
+        case EACCES:  errObj = DBAccessError;       break;
+        case ENOSPC:  errObj = DBNoSpaceError;      break;
+        case EAGAIN:  errObj = DBAgainError;        break;
+        case EBUSY :  errObj = DBBusyError;         break;
+        case EEXIST:  errObj = DBFileExistsError;   break;
+        case ENOENT:  errObj = DBNoSuchFileError;   break;
+        case EPERM :  errObj = DBPermissionsError;  break;
+
+        default:      errObj = DBError;             break;
+    }
+
+    if (errObj != NULL) {
+        bytes_left = our_strlcpy(errTxt, db_strerror(err), sizeof(errTxt));
+        /* Ensure that bytes_left never goes negative */
+        if (_db_errmsg[0] && bytes_left < (sizeof(errTxt) - 4)) {
+            bytes_left = sizeof(errTxt) - bytes_left - 4 - 1;
+            assert(bytes_left >= 0);
+            strcat(errTxt, " -- ");
+            strncat(errTxt, _db_errmsg, bytes_left);
+        }
+        _db_errmsg[0] = 0;
+
+	errTuple = Py_BuildValue("(is)", err, errTxt);
+        PyErr_SetObject(errObj, errTuple);
+	Py_DECREF(errTuple);
+    }
+
+    return ((errObj != NULL) || exceptionRaised);
+}
+
+
+
+/* set a type exception */
+static void makeTypeError(char* expected, PyObject* found)
+{
+    PyErr_Format(PyExc_TypeError, "Expected %s argument, %s found.",
+                 expected, found->ob_type->tp_name);
+}
+
+
+/* verify that an obj is either None or a DBTxn, and set the txn pointer */
+static int checkTxnObj(PyObject* txnobj, DB_TXN** txn)
+{
+    if (txnobj == Py_None || txnobj == NULL) {
+        *txn = NULL;
+        return 1;
+    }
+    if (DBTxnObject_Check(txnobj)) {
+        *txn = ((DBTxnObject*)txnobj)->txn;
+        return 1;
+    }
+    else
+        makeTypeError("DBTxn", txnobj);
+    return 0;
+}
+
+
+/* Delete a key from a database
+  Returns 0 on success, -1 on an error.  */
+static int _DB_delete(DBObject* self, DB_TXN *txn, DBT *key, int flags)
+{
+    int err;
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db->del(self->db, txn, key, 0);
+    MYDB_END_ALLOW_THREADS;
+    if (makeDBError(err)) {
+        return -1;
+    }
+    self->haveStat = 0;
+    return 0;
+}
+
+
+/* Store a key into a database
+   Returns 0 on success, -1 on an error.  */
+static int _DB_put(DBObject* self, DB_TXN *txn, DBT *key, DBT *data, int flags)
+{
+    int err;
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db->put(self->db, txn, key, data, flags);
+    MYDB_END_ALLOW_THREADS;
+    if (makeDBError(err)) {
+        return -1;
+    }
+    self->haveStat = 0;
+    return 0;
+}
+
+/* Get a key/data pair from a cursor */
+static PyObject* _DBCursor_get(DBCursorObject* self, int extra_flags,
+			       PyObject *args, PyObject *kwargs, char *format)
+{
+    int err;
+    PyObject* retval = NULL;
+    DBT key, data;
+    int dlen = -1;
+    int doff = -1;
+    int flags = 0;
+    static char* kwnames[] = { "flags", "dlen", "doff", NULL };
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, kwnames,
+				     &flags, &dlen, &doff)) 
+      return NULL;
+
+    CHECK_CURSOR_NOT_CLOSED(self);
+
+    flags |= extra_flags;
+    CLEAR_DBT(key);
+    CLEAR_DBT(data);
+    if (CHECK_DBFLAG(self->mydb, DB_THREAD)) {
+        /* Tell BerkeleyDB to malloc the return value (thread safe) */
+        data.flags = DB_DBT_MALLOC;
+        key.flags = DB_DBT_MALLOC;
+    }
+    if (!add_partial_dbt(&data, dlen, doff))
+        return NULL;
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->dbc->c_get(self->dbc, &key, &data, flags);
+    MYDB_END_ALLOW_THREADS;
+
+    if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
+	    && self->mydb->moduleFlags.getReturnsNone) {
+        Py_INCREF(Py_None);
+        retval = Py_None;
+    }
+    else if (makeDBError(err)) {
+        retval = NULL;
+    }
+    else {  /* otherwise, success! */
+
+        /* if Recno or Queue, return the key as an Int */
+        switch (_DB_get_type(self->mydb)) {
+        case -1:
+            retval = NULL;
+            break;
+
+        case DB_RECNO:
+        case DB_QUEUE:
+            retval = Py_BuildValue("is#", *((db_recno_t*)key.data),
+                                   data.data, data.size);
+            break;
+        case DB_HASH:
+        case DB_BTREE:
+        default:
+            retval = Py_BuildValue("s#s#", key.data, key.size,
+                                   data.data, data.size);
+            break;
+        }
+    }
+    if (!err) {
+        FREE_DBT(key);
+        FREE_DBT(data);
+    }
+    return retval;
+}
+
+
+/* add an integer to a dictionary using the given name as a key */
+static void _addIntToDict(PyObject* dict, char *name, int value)
+{
+    PyObject* v = PyInt_FromLong((long) value);
+    if (!v || PyDict_SetItemString(dict, name, v))
+        PyErr_Clear();
+
+    Py_XDECREF(v);
+}
+#if (DBVER >= 43)
+/* add an db_seq_t to a dictionary using the given name as a key */
+static void _addDb_seq_tToDict(PyObject* dict, char *name, db_seq_t value)
+{
+    PyObject* v = PyLong_FromLongLong(value);
+    if (!v || PyDict_SetItemString(dict, name, v))
+        PyErr_Clear();
+
+    Py_XDECREF(v);
+}
+#endif
+
+
+
+/* --------------------------------------------------------------------- */
+/* Allocators and deallocators */
+
+static DBObject*
+newDBObject(DBEnvObject* arg, int flags)
+{
+    DBObject* self;
+    DB_ENV* db_env = NULL;
+    int err;
+
+    self = PyObject_New(DBObject, &DB_Type);
+    if (self == NULL)
+        return NULL;
+
+    self->haveStat = 0;
+    self->flags = 0;
+    self->setflags = 0;
+    self->myenvobj = NULL;
+#if (DBVER >= 33)
+    self->associateCallback = NULL;
+    self->btCompareCallback = NULL;
+    self->primaryDBType = 0;
+#endif
+#ifdef HAVE_WEAKREF
+    self->in_weakreflist = NULL;
+#endif
+
+    /* keep a reference to our python DBEnv object */
+    if (arg) {
+        Py_INCREF(arg);
+        self->myenvobj = arg;
+        db_env = arg->db_env;
+    }
+
+    if (self->myenvobj)
+        self->moduleFlags = self->myenvobj->moduleFlags;
+    else
+        self->moduleFlags.getReturnsNone = DEFAULT_GET_RETURNS_NONE;
+        self->moduleFlags.cursorSetReturnsNone = DEFAULT_CURSOR_SET_RETURNS_NONE;
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = db_create(&self->db, db_env, flags);
+    if (self->db != NULL) {
+        self->db->set_errcall(self->db, _db_errorCallback);
+#if (DBVER >= 33)
+        self->db->app_private = (void*)self;
+#endif
+    }
+    MYDB_END_ALLOW_THREADS;
+    /* TODO add a weakref(self) to the self->myenvobj->open_child_weakrefs
+     * list so that a DBEnv can refuse to close without aborting any open
+     * DBTxns and closing any open DBs first. */
+    if (makeDBError(err)) {
+        if (self->myenvobj) {
+            Py_DECREF(self->myenvobj);
+            self->myenvobj = NULL;
+        }
+        PyObject_Del(self);
+        self = NULL;
+    }
+    return self;
+}
+
+
+static void
+DB_dealloc(DBObject* self)
+{
+    if (self->db != NULL) {
+        /* avoid closing a DB when its DBEnv has been closed out from under
+         * it */
+        if (!self->myenvobj ||
+            (self->myenvobj && self->myenvobj->db_env))
+        {
+            MYDB_BEGIN_ALLOW_THREADS;
+            self->db->close(self->db, 0);
+            MYDB_END_ALLOW_THREADS;
+#ifdef HAVE_WARNINGS
+        } else {
+            PyErr_Warn(PyExc_RuntimeWarning,
+                "DB could not be closed in destructor: DBEnv already closed");
+#endif
+        }
+        self->db = NULL;
+    }
+#ifdef HAVE_WEAKREF
+    if (self->in_weakreflist != NULL) {
+        PyObject_ClearWeakRefs((PyObject *) self);
+    }
+#endif
+    if (self->myenvobj) {
+        Py_DECREF(self->myenvobj);
+        self->myenvobj = NULL;
+    }
+#if (DBVER >= 33)
+    if (self->associateCallback != NULL) {
+        Py_DECREF(self->associateCallback);
+        self->associateCallback = NULL;
+    }
+    if (self->btCompareCallback != NULL) {
+        Py_DECREF(self->btCompareCallback);
+        self->btCompareCallback = NULL;
+    }
+#endif
+    PyObject_Del(self);
+}
+
+
+static DBCursorObject*
+newDBCursorObject(DBC* dbc, DBObject* db)
+{
+    DBCursorObject* self = PyObject_New(DBCursorObject, &DBCursor_Type);
+    if (self == NULL)
+        return NULL;
+
+    self->dbc = dbc;
+    self->mydb = db;
+#ifdef HAVE_WEAKREF
+    self->in_weakreflist = NULL;
+#endif
+    Py_INCREF(self->mydb);
+    return self;
+}
+
+
+static void
+DBCursor_dealloc(DBCursorObject* self)
+{
+    int err;
+
+#ifdef HAVE_WEAKREF
+    if (self->in_weakreflist != NULL) {
+        PyObject_ClearWeakRefs((PyObject *) self);
+    }
+#endif
+
+    if (self->dbc != NULL) {
+        MYDB_BEGIN_ALLOW_THREADS;
+	/* If the underlying database has been closed, we don't
+	   need to do anything. If the environment has been closed
+	   we need to leak, as BerkeleyDB will crash trying to access
+	   the environment. There was an exception when the 
+	   user closed the environment even though there still was
+	   a database open. */
+	if (self->mydb->db && self->mydb->myenvobj &&
+	    !self->mydb->myenvobj->closed)
+            err = self->dbc->c_close(self->dbc);
+        self->dbc = NULL;
+        MYDB_END_ALLOW_THREADS;
+    }
+    Py_XDECREF( self->mydb );
+    PyObject_Del(self);
+}
+
+
+static DBEnvObject*
+newDBEnvObject(int flags)
+{
+    int err;
+    DBEnvObject* self = PyObject_New(DBEnvObject, &DBEnv_Type);
+    if (self == NULL)
+        return NULL;
+
+    self->closed = 1;
+    self->flags = flags;
+    self->moduleFlags.getReturnsNone = DEFAULT_GET_RETURNS_NONE;
+    self->moduleFlags.cursorSetReturnsNone = DEFAULT_CURSOR_SET_RETURNS_NONE;
+#ifdef HAVE_WEAKREF
+    self->in_weakreflist = NULL;
+#endif
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = db_env_create(&self->db_env, flags);
+    MYDB_END_ALLOW_THREADS;
+    if (makeDBError(err)) {
+        PyObject_Del(self);
+        self = NULL;
+    }
+    else {
+        self->db_env->set_errcall(self->db_env, _db_errorCallback);
+    }
+    return self;
+}
+
+
+static void
+DBEnv_dealloc(DBEnvObject* self)
+{
+#ifdef HAVE_WEAKREF
+    if (self->in_weakreflist != NULL) {
+        PyObject_ClearWeakRefs((PyObject *) self);
+    }
+#endif
+
+    if (self->db_env && !self->closed) {
+        MYDB_BEGIN_ALLOW_THREADS;
+        self->db_env->close(self->db_env, 0);
+        MYDB_END_ALLOW_THREADS;
+    }
+    PyObject_Del(self);
+}
+
+
+static DBTxnObject*
+newDBTxnObject(DBEnvObject* myenv, DB_TXN *parent, int flags)
+{
+    int err;
+    DBTxnObject* self = PyObject_New(DBTxnObject, &DBTxn_Type);
+    if (self == NULL)
+        return NULL;
+    Py_INCREF(myenv);
+    self->env = (PyObject*)myenv;
+#ifdef HAVE_WEAKREF
+    self->in_weakreflist = NULL;
+#endif
+
+    MYDB_BEGIN_ALLOW_THREADS;
+#if (DBVER >= 40)
+    err = myenv->db_env->txn_begin(myenv->db_env, parent, &(self->txn), flags);
+#else
+    err = txn_begin(myenv->db_env, parent, &(self->txn), flags);
+#endif
+    MYDB_END_ALLOW_THREADS;
+    if (makeDBError(err)) {
+        Py_DECREF(self->env);
+        PyObject_Del(self);
+        self = NULL;
+    }
+    return self;
+}
+
+
+static void
+DBTxn_dealloc(DBTxnObject* self)
+{
+#ifdef HAVE_WEAKREF
+    if (self->in_weakreflist != NULL) {
+        PyObject_ClearWeakRefs((PyObject *) self);
+    }
+#endif
+
+#ifdef HAVE_WARNINGS
+    if (self->txn) {
+        /* it hasn't been finalized, abort it! */
+        MYDB_BEGIN_ALLOW_THREADS;
+#if (DBVER >= 40)
+        self->txn->abort(self->txn);
+#else
+        txn_abort(self->txn);
+#endif
+        MYDB_END_ALLOW_THREADS;
+        PyErr_Warn(PyExc_RuntimeWarning,
+            "DBTxn aborted in destructor.  No prior commit() or abort().");
+    }
+#endif
+
+    Py_DECREF(self->env);
+    PyObject_Del(self);
+}
+
+
+static DBLockObject*
+newDBLockObject(DBEnvObject* myenv, u_int32_t locker, DBT* obj,
+                db_lockmode_t lock_mode, int flags)
+{
+    int err;
+    DBLockObject* self = PyObject_New(DBLockObject, &DBLock_Type);
+    if (self == NULL)
+        return NULL;
+#ifdef HAVE_WEAKREF
+    self->in_weakreflist = NULL;
+#endif
+
+    MYDB_BEGIN_ALLOW_THREADS;
+#if (DBVER >= 40)
+    err = myenv->db_env->lock_get(myenv->db_env, locker, flags, obj, lock_mode,
+                                  &self->lock);
+#else
+    err = lock_get(myenv->db_env, locker, flags, obj, lock_mode, &self->lock);
+#endif
+    MYDB_END_ALLOW_THREADS;
+    if (makeDBError(err)) {
+        PyObject_Del(self);
+        self = NULL;
+    }
+
+    return self;
+}
+
+
+static void
+DBLock_dealloc(DBLockObject* self)
+{
+#ifdef HAVE_WEAKREF
+    if (self->in_weakreflist != NULL) {
+        PyObject_ClearWeakRefs((PyObject *) self);
+    }
+#endif
+    /* TODO: is this lock held? should we release it? */
+
+    PyObject_Del(self);
+}
+
+
+#if (DBVER >= 43)
+static DBSequenceObject*
+newDBSequenceObject(DBObject* mydb,  int flags)
+{
+    int err;
+    DBSequenceObject* self = PyObject_New(DBSequenceObject, &DBSequence_Type);
+    if (self == NULL)
+        return NULL;
+    Py_INCREF(mydb);
+    self->mydb = mydb;
+#ifdef HAVE_WEAKREF
+    self->in_weakreflist = NULL;
+#endif
+
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = db_sequence_create(&self->sequence, self->mydb->db, flags);
+    MYDB_END_ALLOW_THREADS;
+    if (makeDBError(err)) {
+        Py_DECREF(self->mydb);
+        PyObject_Del(self);
+        self = NULL;
+    }
+
+    return self;
+}
+
+
+static void
+DBSequence_dealloc(DBSequenceObject* self)
+{
+#ifdef HAVE_WEAKREF
+    if (self->in_weakreflist != NULL) {
+        PyObject_ClearWeakRefs((PyObject *) self);
+    }
+#endif
+
+    Py_DECREF(self->mydb);
+    PyObject_Del(self);
+}
+#endif
+
+/* --------------------------------------------------------------------- */
+/* DB methods */
+
+static PyObject*
+DB_append(DBObject* self, PyObject* args)
+{
+    PyObject* txnobj = NULL;
+    PyObject* dataobj;
+    db_recno_t recno;
+    DBT key, data;
+    DB_TXN *txn = NULL;
+
+    if (!PyArg_UnpackTuple(args, "append", 1, 2, &dataobj, &txnobj))
+        return NULL;
+
+    CHECK_DB_NOT_CLOSED(self);
+
+    /* make a dummy key out of a recno */
+    recno = 0;
+    CLEAR_DBT(key);
+    key.data = &recno;
+    key.size = sizeof(recno);
+    key.ulen = key.size;
+    key.flags = DB_DBT_USERMEM;
+
+    if (!make_dbt(dataobj, &data)) return NULL;
+    if (!checkTxnObj(txnobj, &txn)) return NULL;
+
+    if (-1 == _DB_put(self, txn, &key, &data, DB_APPEND))
+        return NULL;
+
+    return PyInt_FromLong(recno);
+}
+
+
+#if (DBVER >= 33)
+
+static int
+_db_associateCallback(DB* db, const DBT* priKey, const DBT* priData,
+                      DBT* secKey)
+{
+    int       retval = DB_DONOTINDEX;
+    DBObject* secondaryDB = (DBObject*)db->app_private;
+    PyObject* callback = secondaryDB->associateCallback;
+    int       type = secondaryDB->primaryDBType;
+    PyObject* args;
+    PyObject* result = NULL;
+
+
+    if (callback != NULL) {
+        MYDB_BEGIN_BLOCK_THREADS;
+
+        if (type == DB_RECNO || type == DB_QUEUE)
+            args = Py_BuildValue("(ls#)", *((db_recno_t*)priKey->data),
+                                 priData->data, priData->size);
+        else
+            args = Py_BuildValue("(s#s#)", priKey->data, priKey->size,
+                                 priData->data, priData->size);
+        if (args != NULL) {
+                result = PyEval_CallObject(callback, args);
+        }
+        if (args == NULL || result == NULL) {
+            PyErr_Print();
+        }
+        else if (result == Py_None) {
+            retval = DB_DONOTINDEX;
+        }
+        else if (PyInt_Check(result)) {
+            retval = PyInt_AsLong(result);
+        }
+        else if (PyString_Check(result)) {
+            char* data;
+            Py_ssize_t size;
+
+            CLEAR_DBT(*secKey);
+#if PYTHON_API_VERSION <= 1007
+            /* 1.5 compatibility */
+            size = PyString_Size(result);
+            data = PyString_AsString(result);
+#else
+            PyString_AsStringAndSize(result, &data, &size);
+#endif
+            secKey->flags = DB_DBT_APPMALLOC;   /* DB will free */
+            secKey->data = malloc(size);        /* TODO, check this */
+	    if (secKey->data) {
+		memcpy(secKey->data, data, size);
+		secKey->size = size;
+		retval = 0;
+	    }
+	    else {
+		PyErr_SetString(PyExc_MemoryError,
+                                "malloc failed in _db_associateCallback");
+		PyErr_Print();
+	    }
+        }
+        else {
+            PyErr_SetString(
+               PyExc_TypeError,
+               "DB associate callback should return DB_DONOTINDEX or string.");
+            PyErr_Print();
+        }
+
+        Py_XDECREF(args);
+        Py_XDECREF(result);
+
+        MYDB_END_BLOCK_THREADS;
+    }
+    return retval;
+}
+
+
+static PyObject*
+DB_associate(DBObject* self, PyObject* args, PyObject* kwargs)
+{
+    int err, flags=0;
+    DBObject* secondaryDB;
+    PyObject* callback;
+#if (DBVER >= 41)
+    PyObject *txnobj = NULL;
+    DB_TXN *txn = NULL;
+    static char* kwnames[] = {"secondaryDB", "callback", "flags", "txn",
+                                    NULL};
+#else
+    static char* kwnames[] = {"secondaryDB", "callback", "flags", NULL};
+#endif
+
+#if (DBVER >= 41)
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|iO:associate", kwnames,
+                                     &secondaryDB, &callback, &flags,
+                                     &txnobj)) {
+#else
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|i:associate", kwnames,
+                                     &secondaryDB, &callback, &flags)) {
+#endif
+        return NULL;
+    }
+
+#if (DBVER >= 41)
+    if (!checkTxnObj(txnobj, &txn)) return NULL;
+#endif
+
+    CHECK_DB_NOT_CLOSED(self);
+    if (!DBObject_Check(secondaryDB)) {
+        makeTypeError("DB", (PyObject*)secondaryDB);
+        return NULL;
+    }
+    CHECK_DB_NOT_CLOSED(secondaryDB);
+    if (callback == Py_None) {
+        callback = NULL;
+    }
+    else if (!PyCallable_Check(callback)) {
+        makeTypeError("Callable", callback);
+        return NULL;
+    }
+
+    /* Save a reference to the callback in the secondary DB. */
+    Py_XDECREF(secondaryDB->associateCallback);
+    Py_XINCREF(callback);
+    secondaryDB->associateCallback = callback;
+    secondaryDB->primaryDBType = _DB_get_type(self);
+
+    /* PyEval_InitThreads is called here due to a quirk in python 1.5
+     * - 2.2.1 (at least) according to Russell Williamson <merel at wt.net>:
+     * The global interepreter lock is not initialized until the first
+     * thread is created using thread.start_new_thread() or fork() is
+     * called.  that would cause the ALLOW_THREADS here to segfault due
+     * to a null pointer reference if no threads or child processes
+     * have been created.  This works around that and is a no-op if
+     * threads have already been initialized.
+     *  (see pybsddb-users mailing list post on 2002-08-07)
+     */
+#ifdef WITH_THREAD
+    PyEval_InitThreads();
+#endif
+    MYDB_BEGIN_ALLOW_THREADS;
+#if (DBVER >= 41)
+    err = self->db->associate(self->db,
+	                      txn,
+                              secondaryDB->db,
+                              _db_associateCallback,
+                              flags);
+#else
+    err = self->db->associate(self->db,
+                              secondaryDB->db,
+                              _db_associateCallback,
+                              flags);
+#endif
+    MYDB_END_ALLOW_THREADS;
+
+    if (err) {
+        Py_XDECREF(secondaryDB->associateCallback);
+        secondaryDB->associateCallback = NULL;
+        secondaryDB->primaryDBType = 0;
+    }
+
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+
+
+#endif
+
+
+static PyObject*
+DB_close(DBObject* self, PyObject* args)
+{
+    int err, flags=0;
+    if (!PyArg_ParseTuple(args,"|i:close", &flags))
+        return NULL;
+    if (self->db != NULL) {
+        if (self->myenvobj)
+            CHECK_ENV_NOT_CLOSED(self->myenvobj);
+        err = self->db->close(self->db, flags);
+        self->db = NULL;
+        RETURN_IF_ERR();
+    }
+    RETURN_NONE();
+}
+
+
+#if (DBVER >= 32)
+static PyObject*
+_DB_consume(DBObject* self, PyObject* args, PyObject* kwargs, int consume_flag)
+{
+    int err, flags=0, type;
+    PyObject* txnobj = NULL;
+    PyObject* retval = NULL;
+    DBT key, data;
+    DB_TXN *txn = NULL;
+    static char* kwnames[] = { "txn", "flags", NULL };
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:consume", kwnames,
+                                     &txnobj, &flags))
+        return NULL;
+
+    CHECK_DB_NOT_CLOSED(self);
+    type = _DB_get_type(self);
+    if (type == -1)
+        return NULL;
+    if (type != DB_QUEUE) {
+        PyErr_SetString(PyExc_TypeError,
+                        "Consume methods only allowed for Queue DB's");
+        return NULL;
+    }
+    if (!checkTxnObj(txnobj, &txn))
+        return NULL;
+
+    CLEAR_DBT(key);
+    CLEAR_DBT(data);
+    if (CHECK_DBFLAG(self, DB_THREAD)) {
+        /* Tell BerkeleyDB to malloc the return value (thread safe) */
+        data.flags = DB_DBT_MALLOC;
+        key.flags = DB_DBT_MALLOC;
+    }
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db->get(self->db, txn, &key, &data, flags|consume_flag);
+    MYDB_END_ALLOW_THREADS;
+
+    if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
+	    && self->moduleFlags.getReturnsNone) {
+        err = 0;
+        Py_INCREF(Py_None);
+        retval = Py_None;
+    }
+    else if (!err) {
+        retval = Py_BuildValue("s#s#", key.data, key.size, data.data,
+                               data.size);
+        FREE_DBT(key);
+        FREE_DBT(data);
+    }
+
+    RETURN_IF_ERR();
+    return retval;
+}
+
+static PyObject*
+DB_consume(DBObject* self, PyObject* args, PyObject* kwargs, int consume_flag)
+{
+    return _DB_consume(self, args, kwargs, DB_CONSUME);
+}
+
+static PyObject*
+DB_consume_wait(DBObject* self, PyObject* args, PyObject* kwargs,
+                int consume_flag)
+{
+    return _DB_consume(self, args, kwargs, DB_CONSUME_WAIT);
+}
+#endif
+
+
+
+static PyObject*
+DB_cursor(DBObject* self, PyObject* args, PyObject* kwargs)
+{
+    int err, flags=0;
+    DBC* dbc;
+    PyObject* txnobj = NULL;
+    DB_TXN *txn = NULL;
+    static char* kwnames[] = { "txn", "flags", NULL };
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:cursor", kwnames,
+                                     &txnobj, &flags))
+        return NULL;
+    CHECK_DB_NOT_CLOSED(self);
+    if (!checkTxnObj(txnobj, &txn))
+        return NULL;
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db->cursor(self->db, txn, &dbc, flags);
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+    return (PyObject*) newDBCursorObject(dbc, self);
+}
+
+
+static PyObject*
+DB_delete(DBObject* self, PyObject* args, PyObject* kwargs)
+{
+    PyObject* txnobj = NULL;
+    int flags = 0;
+    PyObject* keyobj;
+    DBT key;
+    DB_TXN *txn = NULL;
+    static char* kwnames[] = { "key", "txn", "flags", NULL };
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:delete", kwnames,
+                                     &keyobj, &txnobj, &flags))
+        return NULL;
+    CHECK_DB_NOT_CLOSED(self);
+    if (!make_key_dbt(self, keyobj, &key, NULL))
+        return NULL;
+    if (!checkTxnObj(txnobj, &txn)) {
+        FREE_DBT(key);
+        return NULL;
+    }
+
+    if (-1 == _DB_delete(self, txn, &key, 0)) {
+        FREE_DBT(key);
+        return NULL;
+    }
+
+    FREE_DBT(key);
+    RETURN_NONE();
+}
+
+
+static PyObject*
+DB_fd(DBObject* self, PyObject* args)
+{
+    int err, the_fd;
+
+    if (!PyArg_ParseTuple(args,":fd"))
+        return NULL;
+    CHECK_DB_NOT_CLOSED(self);
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db->fd(self->db, &the_fd);
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+    return PyInt_FromLong(the_fd);
+}
+
+
+static PyObject*
+DB_get(DBObject* self, PyObject* args, PyObject* kwargs)
+{
+    int err, flags=0;
+    PyObject* txnobj = NULL;
+    PyObject* keyobj;
+    PyObject* dfltobj = NULL;
+    PyObject* retval = NULL;
+    int dlen = -1;
+    int doff = -1;
+    DBT key, data;
+    DB_TXN *txn = NULL;
+    static char* kwnames[] = {"key", "default", "txn", "flags", "dlen",
+                                    "doff", NULL};
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OOiii:get", kwnames,
+                                     &keyobj, &dfltobj, &txnobj, &flags, &dlen,
+                                     &doff))
+        return NULL;
+
+    CHECK_DB_NOT_CLOSED(self);
+    if (!make_key_dbt(self, keyobj, &key, &flags))
+        return NULL;
+    if (!checkTxnObj(txnobj, &txn)) {
+        FREE_DBT(key);
+        return NULL;
+    }
+
+    CLEAR_DBT(data);
+    if (CHECK_DBFLAG(self, DB_THREAD)) {
+        /* Tell BerkeleyDB to malloc the return value (thread safe) */
+        data.flags = DB_DBT_MALLOC;
+    }
+    if (!add_partial_dbt(&data, dlen, doff)) {
+        FREE_DBT(key);
+        return NULL;
+    }
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db->get(self->db, txn, &key, &data, flags);
+    MYDB_END_ALLOW_THREADS;
+
+    if ((err == DB_NOTFOUND || err == DB_KEYEMPTY) && (dfltobj != NULL)) {
+        err = 0;
+        Py_INCREF(dfltobj);
+        retval = dfltobj;
+    }
+    else if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
+	     && self->moduleFlags.getReturnsNone) {
+        err = 0;
+        Py_INCREF(Py_None);
+        retval = Py_None;
+    }
+    else if (!err) {
+        if (flags & DB_SET_RECNO) /* return both key and data */
+            retval = Py_BuildValue("s#s#", key.data, key.size, data.data,
+                                   data.size);
+        else /* return just the data */
+            retval = PyString_FromStringAndSize((char*)data.data, data.size);
+        FREE_DBT(data);
+    }
+    FREE_DBT(key);
+
+    RETURN_IF_ERR();
+    return retval;
+}
+
+#if (DBVER >= 33)
+static PyObject*
+DB_pget(DBObject* self, PyObject* args, PyObject* kwargs)
+{
+    int err, flags=0;
+    PyObject* txnobj = NULL;
+    PyObject* keyobj;
+    PyObject* dfltobj = NULL;
+    PyObject* retval = NULL;
+    int dlen = -1;
+    int doff = -1;
+    DBT key, pkey, data;
+    DB_TXN *txn = NULL;
+    static char* kwnames[] = {"key", "default", "txn", "flags", "dlen",
+                                    "doff", NULL};
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OOiii:pget", kwnames,
+                                     &keyobj, &dfltobj, &txnobj, &flags, &dlen,
+                                     &doff))
+        return NULL;
+
+    CHECK_DB_NOT_CLOSED(self);
+    if (!make_key_dbt(self, keyobj, &key, &flags))
+        return NULL;
+    if (!checkTxnObj(txnobj, &txn)) {
+        FREE_DBT(key);
+        return NULL;
+    }
+
+    CLEAR_DBT(data);
+    if (CHECK_DBFLAG(self, DB_THREAD)) {
+        /* Tell BerkeleyDB to malloc the return value (thread safe) */
+        data.flags = DB_DBT_MALLOC;
+    }
+    if (!add_partial_dbt(&data, dlen, doff)) {
+        FREE_DBT(key);
+        return NULL;
+    }
+
+    CLEAR_DBT(pkey);
+    pkey.flags = DB_DBT_MALLOC;
+    
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db->pget(self->db, txn, &key, &pkey, &data, flags);
+    MYDB_END_ALLOW_THREADS;
+
+    if ((err == DB_NOTFOUND || err == DB_KEYEMPTY) && (dfltobj != NULL)) {
+        err = 0;
+        Py_INCREF(dfltobj);
+        retval = dfltobj;
+    }
+    else if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
+	     && self->moduleFlags.getReturnsNone) {
+        err = 0;
+        Py_INCREF(Py_None);
+        retval = Py_None;
+    }
+    else if (!err) {
+        PyObject *pkeyObj;
+        PyObject *dataObj;
+        dataObj = PyString_FromStringAndSize(data.data, data.size);
+
+        if (self->primaryDBType == DB_RECNO ||
+            self->primaryDBType == DB_QUEUE)
+            pkeyObj = PyInt_FromLong(*(int *)pkey.data);
+        else
+            pkeyObj = PyString_FromStringAndSize(pkey.data, pkey.size);
+
+        if (flags & DB_SET_RECNO) /* return key , pkey and data */
+        {
+            PyObject *keyObj;
+            int type = _DB_get_type(self);
+            if (type == DB_RECNO || type == DB_QUEUE)
+                keyObj = PyInt_FromLong(*(int *)key.data);
+            else
+                keyObj = PyString_FromStringAndSize(key.data, key.size);
+#if (PY_VERSION_HEX >= 0x02040000)
+            retval = PyTuple_Pack(3, keyObj, pkeyObj, dataObj);
+#else
+            retval = Py_BuildValue("OOO", keyObj, pkeyObj, dataObj);
+#endif
+            Py_DECREF(keyObj);
+        }
+        else /* return just the pkey and data */
+        {
+#if (PY_VERSION_HEX >= 0x02040000)
+            retval = PyTuple_Pack(2, pkeyObj, dataObj);
+#else
+            retval = Py_BuildValue("OO", pkeyObj, dataObj);
+#endif
+        }
+        Py_DECREF(dataObj);
+        Py_DECREF(pkeyObj);
+	FREE_DBT(pkey);
+        FREE_DBT(data);
+    }
+    FREE_DBT(key);
+
+    RETURN_IF_ERR();
+    return retval;
+}
+#endif
+
+
+/* Return size of entry */
+static PyObject*
+DB_get_size(DBObject* self, PyObject* args, PyObject* kwargs)
+{
+    int err, flags=0;
+    PyObject* txnobj = NULL;
+    PyObject* keyobj;
+    PyObject* retval = NULL;
+    DBT key, data;
+    DB_TXN *txn = NULL;
+    static char* kwnames[] = { "key", "txn", NULL };
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:get_size", kwnames,
+                                     &keyobj, &txnobj))
+        return NULL;
+    CHECK_DB_NOT_CLOSED(self);
+    if (!make_key_dbt(self, keyobj, &key, &flags))
+        return NULL;
+    if (!checkTxnObj(txnobj, &txn)) {
+        FREE_DBT(key);
+        return NULL;
+    }
+    CLEAR_DBT(data);
+
+    /* We don't allocate any memory, forcing a DB_BUFFER_SMALL error and
+       thus getting the record size. */
+    data.flags = DB_DBT_USERMEM;
+    data.ulen = 0;
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db->get(self->db, txn, &key, &data, flags);
+    MYDB_END_ALLOW_THREADS;
+    if (err == DB_BUFFER_SMALL) {
+        retval = PyInt_FromLong((long)data.size);
+        err = 0;
+    }
+
+    FREE_DBT(key);
+    FREE_DBT(data);
+    RETURN_IF_ERR();
+    return retval;
+}
+
+
+static PyObject*
+DB_get_both(DBObject* self, PyObject* args, PyObject* kwargs)
+{
+    int err, flags=0;
+    PyObject* txnobj = NULL;
+    PyObject* keyobj;
+    PyObject* dataobj;
+    PyObject* retval = NULL;
+    DBT key, data;
+    DB_TXN *txn = NULL;
+    static char* kwnames[] = { "key", "data", "txn", "flags", NULL };
+
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|Oi:get_both", kwnames,
+                                     &keyobj, &dataobj, &txnobj, &flags))
+        return NULL;
+
+    CHECK_DB_NOT_CLOSED(self);
+    if (!make_key_dbt(self, keyobj, &key, NULL))
+        return NULL;
+    if ( !make_dbt(dataobj, &data) ||
+         !checkTxnObj(txnobj, &txn) )
+    {
+        FREE_DBT(key);
+        return NULL;
+    }
+
+    flags |= DB_GET_BOTH;
+
+    if (CHECK_DBFLAG(self, DB_THREAD)) {
+        /* Tell BerkeleyDB to malloc the return value (thread safe) */
+        data.flags = DB_DBT_MALLOC;
+        /* TODO: Is this flag needed?  We're passing a data object that should
+                 match what's in the DB, so there should be no need to malloc.
+                 We run the risk of freeing something twice!  Check this. */
+    }
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db->get(self->db, txn, &key, &data, flags);
+    MYDB_END_ALLOW_THREADS;
+
+    if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
+	    && self->moduleFlags.getReturnsNone) {
+        err = 0;
+        Py_INCREF(Py_None);
+        retval = Py_None;
+    }
+    else if (!err) {
+        retval = PyString_FromStringAndSize((char*)data.data, data.size);
+        FREE_DBT(data); /* Only if retrieval was successful */
+    }
+
+    FREE_DBT(key);
+    RETURN_IF_ERR();
+    return retval;
+}
+
+
+static PyObject*
+DB_get_byteswapped(DBObject* self, PyObject* args)
+{
+#if (DBVER >= 33)
+    int err = 0;
+#endif
+    int retval = -1;
+
+    if (!PyArg_ParseTuple(args,":get_byteswapped"))
+        return NULL;
+    CHECK_DB_NOT_CLOSED(self);
+
+#if (DBVER >= 33)
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db->get_byteswapped(self->db, &retval);
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+#else
+    MYDB_BEGIN_ALLOW_THREADS;
+    retval = self->db->get_byteswapped(self->db);
+    MYDB_END_ALLOW_THREADS;
+#endif
+    return PyInt_FromLong(retval);
+}
+
+
+static PyObject*
+DB_get_type(DBObject* self, PyObject* args)
+{
+    int type;
+
+    if (!PyArg_ParseTuple(args,":get_type"))
+        return NULL;
+    CHECK_DB_NOT_CLOSED(self);
+
+    type = _DB_get_type(self);
+    if (type == -1)
+        return NULL;
+    return PyInt_FromLong(type);
+}
+
+
+static PyObject*
+DB_join(DBObject* self, PyObject* args)
+{
+    int err, flags=0;
+    int length, x;
+    PyObject* cursorsObj;
+    DBC** cursors;
+    DBC*  dbc;
+
+    if (!PyArg_ParseTuple(args,"O|i:join", &cursorsObj, &flags))
+        return NULL;
+
+    CHECK_DB_NOT_CLOSED(self);
+
+    if (!PySequence_Check(cursorsObj)) {
+        PyErr_SetString(PyExc_TypeError,
+                        "Sequence of DBCursor objects expected");
+        return NULL;
+    }
+
+    length = PyObject_Length(cursorsObj);
+    cursors = malloc((length+1) * sizeof(DBC*));
+    if (!cursors) {
+	PyErr_NoMemory();
+	return NULL;
+    }
+
+    cursors[length] = NULL;
+    for (x=0; x<length; x++) {
+        PyObject* item = PySequence_GetItem(cursorsObj, x);
+        if (item == NULL) {
+            free(cursors);
+            return NULL;
+        }
+        if (!DBCursorObject_Check(item)) {
+            PyErr_SetString(PyExc_TypeError,
+                            "Sequence of DBCursor objects expected");
+            free(cursors);
+            return NULL;
+        }
+        cursors[x] = ((DBCursorObject*)item)->dbc;
+        Py_DECREF(item);
+    }
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db->join(self->db, cursors, &dbc, flags);
+    MYDB_END_ALLOW_THREADS;
+    free(cursors);
+    RETURN_IF_ERR();
+
+    /* FIXME: this is a buggy interface.  The returned cursor
+       contains internal references to the passed in cursors
+       but does not hold python references to them or prevent
+       them from being closed prematurely.  This can cause
+       python to crash when things are done in the wrong order. */
+    return (PyObject*) newDBCursorObject(dbc, self);
+}
+
+
+static PyObject*
+DB_key_range(DBObject* self, PyObject* args, PyObject* kwargs)
+{
+    int err, flags=0;
+    PyObject* txnobj = NULL;
+    PyObject* keyobj;
+    DBT key;
+    DB_TXN *txn = NULL;
+    DB_KEY_RANGE range;
+    static char* kwnames[] = { "key", "txn", "flags", NULL };
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:key_range", kwnames,
+                                     &keyobj, &txnobj, &flags))
+        return NULL;
+    CHECK_DB_NOT_CLOSED(self);
+    if (!make_dbt(keyobj, &key))
+        /* BTree only, don't need to allow for an int key */
+        return NULL;
+    if (!checkTxnObj(txnobj, &txn))
+        return NULL;
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db->key_range(self->db, txn, &key, &range, flags);
+    MYDB_END_ALLOW_THREADS;
+
+    RETURN_IF_ERR();
+    return Py_BuildValue("ddd", range.less, range.equal, range.greater);
+}
+
+
+static PyObject*
+DB_open(DBObject* self, PyObject* args, PyObject* kwargs)
+{
+    int err, type = DB_UNKNOWN, flags=0, mode=0660;
+    char* filename = NULL;
+    char* dbname = NULL;
+#if (DBVER >= 41)
+    PyObject *txnobj = NULL;
+    DB_TXN *txn = NULL;
+    /* with dbname */
+    static char* kwnames[] = {
+        "filename", "dbname", "dbtype", "flags", "mode", "txn", NULL};
+    /* without dbname */
+    static char* kwnames_basic[] = {
+        "filename", "dbtype", "flags", "mode", "txn", NULL};
+#else
+    /* with dbname */
+    static char* kwnames[] = {
+        "filename", "dbname", "dbtype", "flags", "mode", NULL};
+    /* without dbname */
+    static char* kwnames_basic[] = {
+        "filename", "dbtype", "flags", "mode", NULL};
+#endif
+
+#if (DBVER >= 41)
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|ziiiO:open", kwnames,
+				     &filename, &dbname, &type, &flags, &mode,
+                                     &txnobj))
+#else
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|ziii:open", kwnames,
+				     &filename, &dbname, &type, &flags,
+                                     &mode))
+#endif
+    {
+	PyErr_Clear();
+	type = DB_UNKNOWN; flags = 0; mode = 0660;
+	filename = NULL; dbname = NULL;
+#if (DBVER >= 41)
+	if (!PyArg_ParseTupleAndKeywords(args, kwargs,"z|iiiO:open",
+                                         kwnames_basic,
+					 &filename, &type, &flags, &mode,
+                                         &txnobj))
+	    return NULL;
+#else
+	if (!PyArg_ParseTupleAndKeywords(args, kwargs,"z|iii:open",
+                                         kwnames_basic,
+					 &filename, &type, &flags, &mode))
+	    return NULL;
+#endif
+    }
+
+#if (DBVER >= 41)
+    if (!checkTxnObj(txnobj, &txn)) return NULL;
+#endif
+
+    if (NULL == self->db) {
+        PyObject *t = Py_BuildValue("(is)", 0,
+                                "Cannot call open() twice for DB object");
+        PyErr_SetObject(DBError, t);
+        Py_DECREF(t);
+        return NULL;
+    }
+
+#if 0 && (DBVER >= 41)
+    if ((!txn) && (txnobj != Py_None) && self->myenvobj
+        && (self->myenvobj->flags & DB_INIT_TXN))
+    {
+	/* If no 'txn' parameter was supplied (no DbTxn object and None was not
+	 * explicitly passed) but we are in a transaction ready environment:
+	 *   add DB_AUTO_COMMIT to allow for older pybsddb apps using transactions
+	 *   to work on BerkeleyDB 4.1 without needing to modify their
+	 *   DBEnv or DB open calls. 
+	 * TODO make this behaviour of the library configurable.
+	 */
+	flags |= DB_AUTO_COMMIT;
+    }
+#endif
+
+    MYDB_BEGIN_ALLOW_THREADS;
+#if (DBVER >= 41)
+    err = self->db->open(self->db, txn, filename, dbname, type, flags, mode);
+#else
+    err = self->db->open(self->db, filename, dbname, type, flags, mode);
+#endif
+    MYDB_END_ALLOW_THREADS;
+    if (makeDBError(err)) {
+        self->db->close(self->db, 0);
+        self->db = NULL;
+        return NULL;
+    }
+
+    self->flags = flags;
+    RETURN_NONE();
+}
+
+
+static PyObject*
+DB_put(DBObject* self, PyObject* args, PyObject* kwargs)
+{
+    int flags=0;
+    PyObject* txnobj = NULL;
+    int dlen = -1;
+    int doff = -1;
+    PyObject* keyobj, *dataobj, *retval;
+    DBT key, data;
+    DB_TXN *txn = NULL;
+    static char* kwnames[] = { "key", "data", "txn", "flags", "dlen",
+                                     "doff", NULL };
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|Oiii:put", kwnames,
+                         &keyobj, &dataobj, &txnobj, &flags, &dlen, &doff))
+        return NULL;
+
+    CHECK_DB_NOT_CLOSED(self);
+    if (!make_key_dbt(self, keyobj, &key, NULL))
+        return NULL;
+    if ( !make_dbt(dataobj, &data) ||
+         !add_partial_dbt(&data, dlen, doff) ||
+         !checkTxnObj(txnobj, &txn) )
+    {
+        FREE_DBT(key);
+        return NULL;
+    }
+
+    if (-1 == _DB_put(self, txn, &key, &data, flags)) {
+        FREE_DBT(key);
+        return NULL;
+    }
+
+    if (flags & DB_APPEND)
+        retval = PyInt_FromLong(*((db_recno_t*)key.data));
+    else {
+        retval = Py_None;
+        Py_INCREF(retval);
+    }
+    FREE_DBT(key);
+    return retval;
+}
+
+
+
+static PyObject*
+DB_remove(DBObject* self, PyObject* args, PyObject* kwargs)
+{
+    char* filename;
+    char* database = NULL;
+    int err, flags=0;
+    static char* kwnames[] = { "filename", "dbname", "flags", NULL};
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|zi:remove", kwnames,
+                                     &filename, &database, &flags))
+        return NULL;
+    CHECK_DB_NOT_CLOSED(self);
+
+    err = self->db->remove(self->db, filename, database, flags);
+    self->db = NULL;
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+
+
+
+static PyObject*
+DB_rename(DBObject* self, PyObject* args)
+{
+    char* filename;
+    char* database;
+    char* newname;
+    int err, flags=0;
+
+    if (!PyArg_ParseTuple(args, "sss|i:rename", &filename, &database, &newname,
+                          &flags))
+        return NULL;
+    CHECK_DB_NOT_CLOSED(self);
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db->rename(self->db, filename, database, newname, flags);
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+
+
+static PyObject*
+DB_set_bt_minkey(DBObject* self, PyObject* args)
+{
+    int err, minkey;
+
+    if (!PyArg_ParseTuple(args,"i:set_bt_minkey", &minkey ))
+        return NULL;
+    CHECK_DB_NOT_CLOSED(self);
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db->set_bt_minkey(self->db, minkey);
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+
+#if (DBVER >= 33)
+static int 
+_default_cmp(const DBT *leftKey,
+	     const DBT *rightKey)
+{
+  int res;
+  int lsize = leftKey->size, rsize = rightKey->size;
+
+  res = memcmp(leftKey->data, rightKey->data, 
+	       lsize < rsize ? lsize : rsize);
+  
+  if (res == 0) {
+      if (lsize < rsize) {
+	  res = -1;
+      }
+      else if (lsize > rsize) {
+	  res = 1;
+      }
+  }
+  return res;
+}
+
+static int
+_db_compareCallback(DB* db, 
+		    const DBT *leftKey,
+		    const DBT *rightKey)
+{
+    int res = 0;
+    PyObject *args;
+    PyObject *result = NULL;
+    DBObject *self = (DBObject *)db->app_private;
+
+    if (self == NULL || self->btCompareCallback == NULL) {
+	MYDB_BEGIN_BLOCK_THREADS;
+	PyErr_SetString(PyExc_TypeError,
+			(self == 0
+			 ? "DB_bt_compare db is NULL."
+			 : "DB_bt_compare callback is NULL."));
+	/* we're in a callback within the DB code, we can't raise */
+	PyErr_Print();
+	res = _default_cmp(leftKey, rightKey);
+	MYDB_END_BLOCK_THREADS;
+    } else {
+	MYDB_BEGIN_BLOCK_THREADS;
+
+	args = Py_BuildValue("s#s#", leftKey->data, leftKey->size,
+			     rightKey->data, rightKey->size);
+	if (args != NULL) {
+		/* XXX(twouters) I highly doubt this INCREF is correct */
+		Py_INCREF(self);
+		result = PyEval_CallObject(self->btCompareCallback, args);
+	}
+	if (args == NULL || result == NULL) {
+	    /* we're in a callback within the DB code, we can't raise */
+	    PyErr_Print();
+	    res = _default_cmp(leftKey, rightKey);
+	} else if (PyInt_Check(result)) {
+	    res = PyInt_AsLong(result);
+	} else {
+	    PyErr_SetString(PyExc_TypeError,
+			    "DB_bt_compare callback MUST return an int.");
+	    /* we're in a callback within the DB code, we can't raise */
+	    PyErr_Print();
+	    res = _default_cmp(leftKey, rightKey);
+	}
+    
+	Py_XDECREF(args);
+	Py_XDECREF(result);
+
+	MYDB_END_BLOCK_THREADS;
+    }
+    return res;
+}
+
+static PyObject*
+DB_set_bt_compare(DBObject* self, PyObject* args)
+{
+    int err;
+    PyObject *comparator;
+    PyObject *tuple, *result;
+
+    if (!PyArg_ParseTuple(args, "O:set_bt_compare", &comparator))
+	return NULL;
+
+    CHECK_DB_NOT_CLOSED(self);
+
+    if (!PyCallable_Check(comparator)) {
+	makeTypeError("Callable", comparator);
+	return NULL;
+    }
+
+    /* 
+     * Perform a test call of the comparator function with two empty
+     * string objects here.  verify that it returns an int (0).
+     * err if not.
+     */
+    tuple = Py_BuildValue("(ss)", "", "");
+    result = PyEval_CallObject(comparator, tuple);
+    Py_DECREF(tuple);
+    if (result == NULL)
+        return NULL;
+    if (!PyInt_Check(result)) {
+	PyErr_SetString(PyExc_TypeError,
+		        "callback MUST return an int");
+	return NULL;
+    } else if (PyInt_AsLong(result) != 0) {
+	PyErr_SetString(PyExc_TypeError,
+		        "callback failed to return 0 on two empty strings");
+	return NULL;
+    }
+    Py_DECREF(result);
+
+    /* We don't accept multiple set_bt_compare operations, in order to
+     * simplify the code. This would have no real use, as one cannot
+     * change the function once the db is opened anyway */
+    if (self->btCompareCallback != NULL) {
+	PyErr_SetString(PyExc_RuntimeError, "set_bt_compare() cannot be called more than once");
+	return NULL;
+    }
+
+    Py_INCREF(comparator);
+    self->btCompareCallback = comparator;
+
+    /* This is to workaround a problem with un-initialized threads (see
+       comment in DB_associate) */
+#ifdef WITH_THREAD
+    PyEval_InitThreads();
+#endif
+
+    err = self->db->set_bt_compare(self->db, _db_compareCallback);
+
+    if (err) {
+	/* restore the old state in case of error */
+	Py_DECREF(comparator);
+	self->btCompareCallback = NULL;
+    }
+
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+#endif /* DBVER >= 33 */
+
+
+static PyObject*
+DB_set_cachesize(DBObject* self, PyObject* args)
+{
+    int err;
+    int gbytes = 0, bytes = 0, ncache = 0;
+
+    if (!PyArg_ParseTuple(args,"ii|i:set_cachesize",
+                          &gbytes,&bytes,&ncache))
+        return NULL;
+    CHECK_DB_NOT_CLOSED(self);
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db->set_cachesize(self->db, gbytes, bytes, ncache);
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+
+
+static PyObject*
+DB_set_flags(DBObject* self, PyObject* args)
+{
+    int err, flags;
+
+    if (!PyArg_ParseTuple(args,"i:set_flags", &flags))
+        return NULL;
+    CHECK_DB_NOT_CLOSED(self);
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db->set_flags(self->db, flags);
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+
+    self->setflags |= flags;
+    RETURN_NONE();
+}
+
+
+static PyObject*
+DB_set_h_ffactor(DBObject* self, PyObject* args)
+{
+    int err, ffactor;
+
+    if (!PyArg_ParseTuple(args,"i:set_h_ffactor", &ffactor))
+        return NULL;
+    CHECK_DB_NOT_CLOSED(self);
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db->set_h_ffactor(self->db, ffactor);
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+
+
+static PyObject*
+DB_set_h_nelem(DBObject* self, PyObject* args)
+{
+    int err, nelem;
+
+    if (!PyArg_ParseTuple(args,"i:set_h_nelem", &nelem))
+        return NULL;
+    CHECK_DB_NOT_CLOSED(self);
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db->set_h_nelem(self->db, nelem);
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+
+
+static PyObject*
+DB_set_lorder(DBObject* self, PyObject* args)
+{
+    int err, lorder;
+
+    if (!PyArg_ParseTuple(args,"i:set_lorder", &lorder))
+        return NULL;
+    CHECK_DB_NOT_CLOSED(self);
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db->set_lorder(self->db, lorder);
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+
+
+static PyObject*
+DB_set_pagesize(DBObject* self, PyObject* args)
+{
+    int err, pagesize;
+
+    if (!PyArg_ParseTuple(args,"i:set_pagesize", &pagesize))
+        return NULL;
+    CHECK_DB_NOT_CLOSED(self);
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db->set_pagesize(self->db, pagesize);
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+
+
+static PyObject*
+DB_set_re_delim(DBObject* self, PyObject* args)
+{
+    int err;
+    char delim;
+
+    if (!PyArg_ParseTuple(args,"b:set_re_delim", &delim)) {
+        PyErr_Clear();
+        if (!PyArg_ParseTuple(args,"c:set_re_delim", &delim))
+            return NULL;
+    }
+
+    CHECK_DB_NOT_CLOSED(self);
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db->set_re_delim(self->db, delim);
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+
+static PyObject*
+DB_set_re_len(DBObject* self, PyObject* args)
+{
+    int err, len;
+
+    if (!PyArg_ParseTuple(args,"i:set_re_len", &len))
+        return NULL;
+    CHECK_DB_NOT_CLOSED(self);
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db->set_re_len(self->db, len);
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+
+
+static PyObject*
+DB_set_re_pad(DBObject* self, PyObject* args)
+{
+    int err;
+    char pad;
+
+    if (!PyArg_ParseTuple(args,"b:set_re_pad", &pad)) {
+        PyErr_Clear();
+        if (!PyArg_ParseTuple(args,"c:set_re_pad", &pad))
+            return NULL;
+    }
+    CHECK_DB_NOT_CLOSED(self);
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db->set_re_pad(self->db, pad);
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+
+
+static PyObject*
+DB_set_re_source(DBObject* self, PyObject* args)
+{
+    int err;
+    char *re_source;
+
+    if (!PyArg_ParseTuple(args,"s:set_re_source", &re_source))
+        return NULL;
+    CHECK_DB_NOT_CLOSED(self);
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db->set_re_source(self->db, re_source);
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+
+
+#if (DBVER >= 32)
+static PyObject*
+DB_set_q_extentsize(DBObject* self, PyObject* args)
+{
+    int err;
+    int extentsize;
+
+    if (!PyArg_ParseTuple(args,"i:set_q_extentsize", &extentsize))
+        return NULL;
+    CHECK_DB_NOT_CLOSED(self);
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db->set_q_extentsize(self->db, extentsize);
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+#endif
+
+static PyObject*
+DB_stat(DBObject* self, PyObject* args, PyObject* kwargs)
+{
+    int err, flags = 0, type;
+    void* sp;
+    PyObject* d;
+#if (DBVER >= 43)
+    PyObject* txnobj = NULL;
+    DB_TXN *txn = NULL;
+    static char* kwnames[] = { "flags", "txn", NULL };
+#else
+    static char* kwnames[] = { "flags", NULL };
+#endif
+
+#if (DBVER >= 43)
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iO:stat", kwnames,
+                                     &flags, &txnobj))
+        return NULL;
+    if (!checkTxnObj(txnobj, &txn))
+        return NULL;
+#else
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat", kwnames, &flags))
+        return NULL;
+#endif
+    CHECK_DB_NOT_CLOSED(self);
+
+    MYDB_BEGIN_ALLOW_THREADS;
+#if (DBVER >= 43)
+    err = self->db->stat(self->db, txn, &sp, flags);
+#elif (DBVER >= 33)
+    err = self->db->stat(self->db, &sp, flags);
+#else
+    err = self->db->stat(self->db, &sp, NULL, flags);
+#endif
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+
+    self->haveStat = 1;
+
+    /* Turn the stat structure into a dictionary */
+    type = _DB_get_type(self);
+    if ((type == -1) || ((d = PyDict_New()) == NULL)) {
+        free(sp);
+        return NULL;
+    }
+
+#define MAKE_HASH_ENTRY(name)  _addIntToDict(d, #name, ((DB_HASH_STAT*)sp)->hash_##name)
+#define MAKE_BT_ENTRY(name)    _addIntToDict(d, #name, ((DB_BTREE_STAT*)sp)->bt_##name)
+#define MAKE_QUEUE_ENTRY(name) _addIntToDict(d, #name, ((DB_QUEUE_STAT*)sp)->qs_##name)
+
+    switch (type) {
+    case DB_HASH:
+        MAKE_HASH_ENTRY(magic);
+        MAKE_HASH_ENTRY(version);
+        MAKE_HASH_ENTRY(nkeys);
+        MAKE_HASH_ENTRY(ndata);
+        MAKE_HASH_ENTRY(pagesize);
+#if (DBVER < 41)
+        MAKE_HASH_ENTRY(nelem);
+#endif
+        MAKE_HASH_ENTRY(ffactor);
+        MAKE_HASH_ENTRY(buckets);
+        MAKE_HASH_ENTRY(free);
+        MAKE_HASH_ENTRY(bfree);
+        MAKE_HASH_ENTRY(bigpages);
+        MAKE_HASH_ENTRY(big_bfree);
+        MAKE_HASH_ENTRY(overflows);
+        MAKE_HASH_ENTRY(ovfl_free);
+        MAKE_HASH_ENTRY(dup);
+        MAKE_HASH_ENTRY(dup_free);
+        break;
+
+    case DB_BTREE:
+    case DB_RECNO:
+        MAKE_BT_ENTRY(magic);
+        MAKE_BT_ENTRY(version);
+        MAKE_BT_ENTRY(nkeys);
+        MAKE_BT_ENTRY(ndata);
+        MAKE_BT_ENTRY(pagesize);
+        MAKE_BT_ENTRY(minkey);
+        MAKE_BT_ENTRY(re_len);
+        MAKE_BT_ENTRY(re_pad);
+        MAKE_BT_ENTRY(levels);
+        MAKE_BT_ENTRY(int_pg);
+        MAKE_BT_ENTRY(leaf_pg);
+        MAKE_BT_ENTRY(dup_pg);
+        MAKE_BT_ENTRY(over_pg);
+        MAKE_BT_ENTRY(free);
+        MAKE_BT_ENTRY(int_pgfree);
+        MAKE_BT_ENTRY(leaf_pgfree);
+        MAKE_BT_ENTRY(dup_pgfree);
+        MAKE_BT_ENTRY(over_pgfree);
+        break;
+
+    case DB_QUEUE:
+        MAKE_QUEUE_ENTRY(magic);
+        MAKE_QUEUE_ENTRY(version);
+        MAKE_QUEUE_ENTRY(nkeys);
+        MAKE_QUEUE_ENTRY(ndata);
+        MAKE_QUEUE_ENTRY(pagesize);
+        MAKE_QUEUE_ENTRY(pages);
+        MAKE_QUEUE_ENTRY(re_len);
+        MAKE_QUEUE_ENTRY(re_pad);
+        MAKE_QUEUE_ENTRY(pgfree);
+#if (DBVER == 31)
+        MAKE_QUEUE_ENTRY(start);
+#endif
+        MAKE_QUEUE_ENTRY(first_recno);
+        MAKE_QUEUE_ENTRY(cur_recno);
+        break;
+
+    default:
+        PyErr_SetString(PyExc_TypeError, "Unknown DB type, unable to stat");
+        Py_DECREF(d);
+        d = NULL;
+    }
+
+#undef MAKE_HASH_ENTRY
+#undef MAKE_BT_ENTRY
+#undef MAKE_QUEUE_ENTRY
+
+    free(sp);
+    return d;
+}
+
+static PyObject*
+DB_sync(DBObject* self, PyObject* args)
+{
+    int err;
+    int flags = 0;
+
+    if (!PyArg_ParseTuple(args,"|i:sync", &flags ))
+        return NULL;
+    CHECK_DB_NOT_CLOSED(self);
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db->sync(self->db, flags);
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+
+
+#if (DBVER >= 33)
+static PyObject*
+DB_truncate(DBObject* self, PyObject* args, PyObject* kwargs)
+{
+    int err, flags=0;
+    u_int32_t count=0;
+    PyObject* txnobj = NULL;
+    DB_TXN *txn = NULL;
+    static char* kwnames[] = { "txn", "flags", NULL };
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:cursor", kwnames,
+                                     &txnobj, &flags))
+        return NULL;
+    CHECK_DB_NOT_CLOSED(self);
+    if (!checkTxnObj(txnobj, &txn))
+        return NULL;
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db->truncate(self->db, txn, &count, flags);
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+    return PyInt_FromLong(count);
+}
+#endif
+
+
+static PyObject*
+DB_upgrade(DBObject* self, PyObject* args)
+{
+    int err, flags=0;
+    char *filename;
+
+    if (!PyArg_ParseTuple(args,"s|i:upgrade", &filename, &flags))
+        return NULL;
+    CHECK_DB_NOT_CLOSED(self);
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db->upgrade(self->db, filename, flags);
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+
+
+static PyObject*
+DB_verify(DBObject* self, PyObject* args, PyObject* kwargs)
+{
+    int err, flags=0;
+    char* fileName;
+    char* dbName=NULL;
+    char* outFileName=NULL;
+    FILE* outFile=NULL;
+    static char* kwnames[] = { "filename", "dbname", "outfile", "flags",
+                                     NULL };
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|zzi:verify", kwnames,
+                                     &fileName, &dbName, &outFileName, &flags))
+        return NULL;
+
+    CHECK_DB_NOT_CLOSED(self);
+    if (outFileName)
+        outFile = fopen(outFileName, "w");
+	/* XXX(nnorwitz): it should probably be an exception if outFile
+	   can't be opened. */
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db->verify(self->db, fileName, dbName, outFile, flags);
+    MYDB_END_ALLOW_THREADS;
+    if (outFile)
+        fclose(outFile);
+
+    /* DB.verify acts as a DB handle destructor (like close); this was
+     * documented in BerkeleyDB 4.2 but had the undocumented effect
+     * of not being safe in prior versions while still requiring an explicit
+     * DB.close call afterwards.  Lets call close for the user to emulate
+     * the safe 4.2 behaviour. */
+#if (DBVER <= 41)
+    self->db->close(self->db, 0);
+#endif
+    self->db = NULL;
+
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+
+
+static PyObject*
+DB_set_get_returns_none(DBObject* self, PyObject* args)
+{
+    int flags=0;
+    int oldValue=0;
+
+    if (!PyArg_ParseTuple(args,"i:set_get_returns_none", &flags))
+        return NULL;
+    CHECK_DB_NOT_CLOSED(self);
+
+    if (self->moduleFlags.getReturnsNone)
+        ++oldValue;
+    if (self->moduleFlags.cursorSetReturnsNone)
+        ++oldValue;
+    self->moduleFlags.getReturnsNone = (flags >= 1);
+    self->moduleFlags.cursorSetReturnsNone = (flags >= 2);
+    return PyInt_FromLong(oldValue);
+}
+
+#if (DBVER >= 41)
+static PyObject*
+DB_set_encrypt(DBObject* self, PyObject* args, PyObject* kwargs)
+{
+    int err;
+    u_int32_t flags=0;
+    char *passwd = NULL;
+    static char* kwnames[] = { "passwd", "flags", NULL };
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|i:set_encrypt", kwnames,
+		&passwd, &flags)) {
+	return NULL;
+    }
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db->set_encrypt(self->db, passwd, flags);
+    MYDB_END_ALLOW_THREADS;
+
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+#endif /* DBVER >= 41 */
+
+
+/*-------------------------------------------------------------- */
+/* Mapping and Dictionary-like access routines */
+
+Py_ssize_t DB_length(PyObject* _self)
+{
+    int err;
+    Py_ssize_t size = 0;
+    int flags = 0;
+    void* sp;
+    DBObject* self = (DBObject*)_self;
+
+    if (self->db == NULL) {
+        PyObject *t = Py_BuildValue("(is)", 0, "DB object has been closed");
+        PyErr_SetObject(DBError, t);
+        Py_DECREF(t);
+        return -1;
+    }
+
+    if (self->haveStat) {  /* Has the stat function been called recently?  If
+                              so, we can use the cached value. */
+        flags = DB_FAST_STAT;
+    }
+
+    MYDB_BEGIN_ALLOW_THREADS;
+redo_stat_for_length:
+#if (DBVER >= 43)
+    err = self->db->stat(self->db, /*txnid*/ NULL, &sp, flags);
+#elif (DBVER >= 33)
+    err = self->db->stat(self->db, &sp, flags);
+#else
+    err = self->db->stat(self->db, &sp, NULL, flags);
+#endif
+
+    /* All the stat structures have matching fields upto the ndata field,
+       so we can use any of them for the type cast */
+    size = ((DB_BTREE_STAT*)sp)->bt_ndata;
+
+    /* A size of 0 could mean that BerkeleyDB no longer had the stat values cached.
+     * redo a full stat to make sure.
+     *   Fixes SF python bug 1493322, pybsddb bug 1184012
+     */
+    if (size == 0 && (flags & DB_FAST_STAT)) {
+        flags = 0;
+        if (!err)
+            free(sp);
+        goto redo_stat_for_length;
+    }
+
+    MYDB_END_ALLOW_THREADS;
+
+    if (err)
+        return -1;
+
+    self->haveStat = 1;
+
+    free(sp);
+    return size;
+}
+
+
+PyObject* DB_subscript(DBObject* self, PyObject* keyobj)
+{
+    int err;
+    PyObject* retval;
+    DBT key;
+    DBT data;
+
+    CHECK_DB_NOT_CLOSED(self);
+    if (!make_key_dbt(self, keyobj, &key, NULL))
+        return NULL;
+
+    CLEAR_DBT(data);
+    if (CHECK_DBFLAG(self, DB_THREAD)) {
+        /* Tell BerkeleyDB to malloc the return value (thread safe) */
+        data.flags = DB_DBT_MALLOC;
+    }
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db->get(self->db, NULL, &key, &data, 0);
+    MYDB_END_ALLOW_THREADS;
+    if (err == DB_NOTFOUND || err == DB_KEYEMPTY) {
+        PyErr_SetObject(PyExc_KeyError, keyobj);
+        retval = NULL;
+    }
+    else if (makeDBError(err)) {
+        retval = NULL;
+    }
+    else {
+        retval = PyString_FromStringAndSize((char*)data.data, data.size);
+        FREE_DBT(data);
+    }
+
+    FREE_DBT(key);
+    return retval;
+}
+
+
+static int
+DB_ass_sub(DBObject* self, PyObject* keyobj, PyObject* dataobj)
+{
+    DBT key, data;
+    int retval;
+    int flags = 0;
+
+    if (self->db == NULL) {
+        PyObject *t = Py_BuildValue("(is)", 0, "DB object has been closed");
+        PyErr_SetObject(DBError, t);
+        Py_DECREF(t);
+        return -1;
+    }
+
+    if (!make_key_dbt(self, keyobj, &key, NULL))
+        return -1;
+
+    if (dataobj != NULL) {
+        if (!make_dbt(dataobj, &data))
+            retval =  -1;
+        else {
+            if (self->setflags & (DB_DUP|DB_DUPSORT))
+                /* dictionaries shouldn't have duplicate keys */
+                flags = DB_NOOVERWRITE;
+            retval = _DB_put(self, NULL, &key, &data, flags);
+
+            if ((retval == -1) &&  (self->setflags & (DB_DUP|DB_DUPSORT))) {
+                /* try deleting any old record that matches and then PUT it
+                 * again... */
+                _DB_delete(self, NULL, &key, 0);
+                PyErr_Clear();
+                retval = _DB_put(self, NULL, &key, &data, flags);
+            }
+        }
+    }
+    else {
+        /* dataobj == NULL, so delete the key */
+        retval = _DB_delete(self, NULL, &key, 0);
+    }
+    FREE_DBT(key);
+    return retval;
+}
+
+
+static PyObject*
+DB_has_key(DBObject* self, PyObject* args)
+{
+    int err;
+    PyObject* keyobj;
+    DBT key, data;
+    PyObject* txnobj = NULL;
+    DB_TXN *txn = NULL;
+
+    if (!PyArg_ParseTuple(args,"O|O:has_key", &keyobj, &txnobj))
+        return NULL;
+    CHECK_DB_NOT_CLOSED(self);
+    if (!make_key_dbt(self, keyobj, &key, NULL))
+        return NULL;
+    if (!checkTxnObj(txnobj, &txn)) {
+        FREE_DBT(key);
+        return NULL;
+    }
+
+    /* This causes DB_BUFFER_SMALL to be returned when the db has the key because
+       it has a record but can't allocate a buffer for the data.  This saves
+       having to deal with data we won't be using.
+     */
+    CLEAR_DBT(data);
+    data.flags = DB_DBT_USERMEM;
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db->get(self->db, txn, &key, &data, 0);
+    MYDB_END_ALLOW_THREADS;
+    FREE_DBT(key);
+
+    if (err == DB_BUFFER_SMALL || err == 0) {
+        return PyInt_FromLong(1);
+    } else if (err == DB_NOTFOUND || err == DB_KEYEMPTY) {
+        return PyInt_FromLong(0);
+    }
+
+    makeDBError(err);
+    return NULL;
+}
+
+
+#define _KEYS_LIST      1
+#define _VALUES_LIST    2
+#define _ITEMS_LIST     3
+
+static PyObject*
+_DB_make_list(DBObject* self, DB_TXN* txn, int type)
+{
+    int err, dbtype;
+    DBT key;
+    DBT data;
+    DBC *cursor;
+    PyObject* list;
+    PyObject* item = NULL;
+
+    CHECK_DB_NOT_CLOSED(self);
+    CLEAR_DBT(key);
+    CLEAR_DBT(data);
+
+    dbtype = _DB_get_type(self);
+    if (dbtype == -1)
+        return NULL;
+
+    list = PyList_New(0);
+    if (list == NULL)
+        return NULL;
+
+    /* get a cursor */
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db->cursor(self->db, txn, &cursor, 0);
+    MYDB_END_ALLOW_THREADS;
+    if (makeDBError(err)) {
+        Py_DECREF(list);
+        return NULL;
+    }
+
+    if (CHECK_DBFLAG(self, DB_THREAD)) {
+        key.flags = DB_DBT_REALLOC;
+        data.flags = DB_DBT_REALLOC;
+    }
+
+    while (1) { /* use the cursor to traverse the DB, collecting items */
+        MYDB_BEGIN_ALLOW_THREADS;
+        err = cursor->c_get(cursor, &key, &data, DB_NEXT);
+        MYDB_END_ALLOW_THREADS;
+
+        if (err) {
+            /* for any error, break out of the loop */
+            break;
+        }
+
+        switch (type) {
+        case _KEYS_LIST:
+            switch(dbtype) {
+            case DB_BTREE:
+            case DB_HASH:
+            default:
+                item = PyString_FromStringAndSize((char*)key.data, key.size);
+                break;
+            case DB_RECNO:
+            case DB_QUEUE:
+                item = PyInt_FromLong(*((db_recno_t*)key.data));
+                break;
+            }
+            break;
+
+        case _VALUES_LIST:
+            item = PyString_FromStringAndSize((char*)data.data, data.size);
+            break;
+
+        case _ITEMS_LIST:
+            switch(dbtype) {
+            case DB_BTREE:
+            case DB_HASH:
+            default:
+                item = Py_BuildValue("s#s#", key.data, key.size, data.data,
+                                     data.size);
+                break;
+            case DB_RECNO:
+            case DB_QUEUE:
+                item = Py_BuildValue("is#", *((db_recno_t*)key.data),
+                                     data.data, data.size);
+                break;
+            }
+            break;
+        default:
+            PyErr_Format(PyExc_ValueError, "Unknown key type 0x%x", type);
+            item = NULL;
+            break;
+        }
+        if (item == NULL) {
+            Py_DECREF(list);
+            list = NULL;
+            goto done;
+        }
+        PyList_Append(list, item);
+        Py_DECREF(item);
+    }
+
+    /* DB_NOTFOUND || DB_KEYEMPTY is okay, it means we got to the end */
+    if (err != DB_NOTFOUND && err != DB_KEYEMPTY && makeDBError(err)) {
+        Py_DECREF(list);
+        list = NULL;
+    }
+
+ done:
+    FREE_DBT(key);
+    FREE_DBT(data);
+    MYDB_BEGIN_ALLOW_THREADS;
+    cursor->c_close(cursor);
+    MYDB_END_ALLOW_THREADS;
+    return list;
+}
+
+
+static PyObject*
+DB_keys(DBObject* self, PyObject* args)
+{
+    PyObject* txnobj = NULL;
+    DB_TXN *txn = NULL;
+
+    if (!PyArg_UnpackTuple(args, "keys", 0, 1, &txnobj))
+        return NULL;
+    if (!checkTxnObj(txnobj, &txn))
+        return NULL;
+    return _DB_make_list(self, txn, _KEYS_LIST);
+}
+
+
+static PyObject*
+DB_items(DBObject* self, PyObject* args)
+{
+    PyObject* txnobj = NULL;
+    DB_TXN *txn = NULL;
+
+    if (!PyArg_UnpackTuple(args, "items", 0, 1, &txnobj))
+        return NULL;
+    if (!checkTxnObj(txnobj, &txn))
+        return NULL;
+    return _DB_make_list(self, txn, _ITEMS_LIST);
+}
+
+
+static PyObject*
+DB_values(DBObject* self, PyObject* args)
+{
+    PyObject* txnobj = NULL;
+    DB_TXN *txn = NULL;
+
+    if (!PyArg_UnpackTuple(args, "values", 0, 1, &txnobj))
+        return NULL;
+    if (!checkTxnObj(txnobj, &txn))
+        return NULL;
+    return _DB_make_list(self, txn, _VALUES_LIST);
+}
+
+/* --------------------------------------------------------------------- */
+/* DBCursor methods */
+
+
+static PyObject*
+DBC_close(DBCursorObject* self, PyObject* args)
+{
+    int err = 0;
+
+    if (!PyArg_ParseTuple(args, ":close"))
+        return NULL;
+
+    if (self->dbc != NULL) {
+        MYDB_BEGIN_ALLOW_THREADS;
+        err = self->dbc->c_close(self->dbc);
+        self->dbc = NULL;
+        MYDB_END_ALLOW_THREADS;
+    }
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+
+
+static PyObject*
+DBC_count(DBCursorObject* self, PyObject* args)
+{
+    int err = 0;
+    db_recno_t count;
+    int flags = 0;
+
+    if (!PyArg_ParseTuple(args, "|i:count", &flags))
+        return NULL;
+
+    CHECK_CURSOR_NOT_CLOSED(self);
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->dbc->c_count(self->dbc, &count, flags);
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+
+    return PyInt_FromLong(count);
+}
+
+
+static PyObject*
+DBC_current(DBCursorObject* self, PyObject* args, PyObject *kwargs)
+{
+    return _DBCursor_get(self,DB_CURRENT,args,kwargs,"|iii:current");
+}
+
+
+static PyObject*
+DBC_delete(DBCursorObject* self, PyObject* args)
+{
+    int err, flags=0;
+
+    if (!PyArg_ParseTuple(args, "|i:delete", &flags))
+        return NULL;
+
+    CHECK_CURSOR_NOT_CLOSED(self);
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->dbc->c_del(self->dbc, flags);
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+
+    self->mydb->haveStat = 0;
+    RETURN_NONE();
+}
+
+
+static PyObject*
+DBC_dup(DBCursorObject* self, PyObject* args)
+{
+    int err, flags =0;
+    DBC* dbc = NULL;
+
+    if (!PyArg_ParseTuple(args, "|i:dup", &flags))
+        return NULL;
+
+    CHECK_CURSOR_NOT_CLOSED(self);
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->dbc->c_dup(self->dbc, &dbc, flags);
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+
+    return (PyObject*) newDBCursorObject(dbc, self->mydb);
+}
+
+static PyObject*
+DBC_first(DBCursorObject* self, PyObject* args, PyObject* kwargs)
+{
+    return _DBCursor_get(self,DB_FIRST,args,kwargs,"|iii:first");
+}
+
+
+static PyObject*
+DBC_get(DBCursorObject* self, PyObject* args, PyObject *kwargs)
+{
+    int err, flags=0;
+    PyObject* keyobj = NULL;
+    PyObject* dataobj = NULL;
+    PyObject* retval = NULL;
+    int dlen = -1;
+    int doff = -1;
+    DBT key, data;
+    static char* kwnames[] = { "key","data", "flags", "dlen", "doff",
+                                     NULL };
+
+    CLEAR_DBT(key);
+    CLEAR_DBT(data);
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|ii:get", &kwnames[2],
+				     &flags, &dlen, &doff))
+    {
+        PyErr_Clear();
+        if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi|ii:get",
+                                         &kwnames[1], 
+					 &keyobj, &flags, &dlen, &doff))
+        {
+            PyErr_Clear();
+            if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOi|ii:get",
+                                             kwnames, &keyobj, &dataobj,
+                                             &flags, &dlen, &doff))
+            {
+                return NULL;
+	    }
+	}
+    }
+
+    CHECK_CURSOR_NOT_CLOSED(self);
+
+    if (keyobj && !make_key_dbt(self->mydb, keyobj, &key, NULL))
+        return NULL;
+    if ( (dataobj && !make_dbt(dataobj, &data)) ||
+         (!add_partial_dbt(&data, dlen, doff)) )
+    {
+        FREE_DBT(key);
+        return NULL;
+    }
+
+    if (CHECK_DBFLAG(self->mydb, DB_THREAD)) {
+        data.flags = DB_DBT_MALLOC;
+        if (!(key.flags & DB_DBT_REALLOC)) {
+            key.flags |= DB_DBT_MALLOC;
+        }
+    }
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->dbc->c_get(self->dbc, &key, &data, flags);
+    MYDB_END_ALLOW_THREADS;
+
+    if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
+	    && self->mydb->moduleFlags.getReturnsNone) {
+        Py_INCREF(Py_None);
+        retval = Py_None;
+    }
+    else if (makeDBError(err)) {
+        retval = NULL;
+    }
+    else {
+        switch (_DB_get_type(self->mydb)) {
+        case -1:
+            retval = NULL;
+            break;
+        case DB_BTREE:
+        case DB_HASH:
+        default:
+            retval = Py_BuildValue("s#s#", key.data, key.size,
+                                   data.data, data.size);
+            break;
+        case DB_RECNO:
+        case DB_QUEUE:
+            retval = Py_BuildValue("is#", *((db_recno_t*)key.data),
+                                   data.data, data.size);
+            break;
+        }
+        FREE_DBT(data);
+    }
+    FREE_DBT(key);
+    return retval;
+}
+
+#if (DBVER >= 33)
+static PyObject*
+DBC_pget(DBCursorObject* self, PyObject* args, PyObject *kwargs)
+{
+    int err, flags=0;
+    PyObject* keyobj = NULL;
+    PyObject* dataobj = NULL;
+    PyObject* retval = NULL;
+    int dlen = -1;
+    int doff = -1;
+    DBT key, pkey, data;
+    static char* kwnames_keyOnly[] = { "key", "flags", "dlen", "doff", NULL };
+    static char* kwnames[] = { "key", "data", "flags", "dlen", "doff", NULL };
+
+    CLEAR_DBT(key);
+    CLEAR_DBT(data);
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|ii:pget", &kwnames[2],
+				     &flags, &dlen, &doff))
+    {
+        PyErr_Clear();
+        if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi|ii:pget",
+                                         kwnames_keyOnly, 
+					 &keyobj, &flags, &dlen, &doff))
+        {
+            PyErr_Clear();
+            if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOi|ii:pget",
+                                             kwnames, &keyobj, &dataobj,
+                                             &flags, &dlen, &doff))
+            {
+                return NULL;
+	    }
+	}
+    }
+
+    CHECK_CURSOR_NOT_CLOSED(self);
+
+    if (keyobj && !make_key_dbt(self->mydb, keyobj, &key, NULL))
+        return NULL;
+    if ( (dataobj && !make_dbt(dataobj, &data)) ||
+         (!add_partial_dbt(&data, dlen, doff)) ) {
+        FREE_DBT(key);
+        return NULL;
+    }
+
+    if (CHECK_DBFLAG(self->mydb, DB_THREAD)) {
+        data.flags = DB_DBT_MALLOC;
+        if (!(key.flags & DB_DBT_REALLOC)) {
+            key.flags |= DB_DBT_MALLOC;
+        }
+    }
+
+    CLEAR_DBT(pkey);
+    pkey.flags = DB_DBT_MALLOC;
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->dbc->c_pget(self->dbc, &key, &pkey, &data, flags);
+    MYDB_END_ALLOW_THREADS;
+
+    if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
+	    && self->mydb->moduleFlags.getReturnsNone) {
+        Py_INCREF(Py_None);
+        retval = Py_None;
+    }
+    else if (makeDBError(err)) {
+        retval = NULL;
+    }
+    else {
+        PyObject *pkeyObj;
+        PyObject *dataObj;
+        dataObj = PyString_FromStringAndSize(data.data, data.size);
+
+        if (self->mydb->primaryDBType == DB_RECNO ||
+            self->mydb->primaryDBType == DB_QUEUE)
+            pkeyObj = PyInt_FromLong(*(int *)pkey.data);
+        else
+            pkeyObj = PyString_FromStringAndSize(pkey.data, pkey.size);
+
+        if (key.data && key.size) /* return key, pkey and data */
+        {
+            PyObject *keyObj;
+            int type = _DB_get_type(self->mydb);
+            if (type == DB_RECNO || type == DB_QUEUE)
+                keyObj = PyInt_FromLong(*(int *)key.data);
+            else
+                keyObj = PyString_FromStringAndSize(key.data, key.size);
+#if (PY_VERSION_HEX >= 0x02040000)
+            retval = PyTuple_Pack(3, keyObj, pkeyObj, dataObj);
+#else
+            retval = Py_BuildValue("OOO", keyObj, pkeyObj, dataObj);
+#endif
+            Py_DECREF(keyObj);
+            FREE_DBT(key);
+        }
+        else /* return just the pkey and data */
+        {
+#if (PY_VERSION_HEX >= 0x02040000)
+            retval = PyTuple_Pack(2, pkeyObj, dataObj);
+#else
+            retval = Py_BuildValue("OO", pkeyObj, dataObj);
+#endif
+        }
+        Py_DECREF(dataObj);
+        Py_DECREF(pkeyObj);
+        FREE_DBT(pkey);
+        FREE_DBT(data);
+    }
+    /* the only time REALLOC should be set is if we used an integer
+     * key that make_key_dbt malloc'd for us.  always free these. */
+    if (key.flags & DB_DBT_REALLOC) {
+        FREE_DBT(key);
+    }
+    return retval;
+}
+#endif
+
+
+static PyObject*
+DBC_get_recno(DBCursorObject* self, PyObject* args)
+{
+    int err;
+    db_recno_t recno;
+    DBT key;
+    DBT data;
+
+    if (!PyArg_ParseTuple(args, ":get_recno"))
+        return NULL;
+
+    CHECK_CURSOR_NOT_CLOSED(self);
+
+    CLEAR_DBT(key);
+    CLEAR_DBT(data);
+    if (CHECK_DBFLAG(self->mydb, DB_THREAD)) {
+        /* Tell BerkeleyDB to malloc the return value (thread safe) */
+        data.flags = DB_DBT_MALLOC;
+        key.flags = DB_DBT_MALLOC;
+    }
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->dbc->c_get(self->dbc, &key, &data, DB_GET_RECNO);
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+
+    recno = *((db_recno_t*)data.data);
+    FREE_DBT(key);
+    FREE_DBT(data);
+    return PyInt_FromLong(recno);
+}
+
+
+static PyObject*
+DBC_last(DBCursorObject* self, PyObject* args, PyObject *kwargs)
+{
+    return _DBCursor_get(self,DB_LAST,args,kwargs,"|iii:last");
+}
+
+
+static PyObject*
+DBC_next(DBCursorObject* self, PyObject* args, PyObject *kwargs)
+{
+    return _DBCursor_get(self,DB_NEXT,args,kwargs,"|iii:next");
+}
+
+
+static PyObject*
+DBC_prev(DBCursorObject* self, PyObject* args, PyObject *kwargs)
+{
+    return _DBCursor_get(self,DB_PREV,args,kwargs,"|iii:prev");
+}
+
+
+static PyObject*
+DBC_put(DBCursorObject* self, PyObject* args, PyObject* kwargs)
+{
+    int err, flags = 0;
+    PyObject* keyobj, *dataobj;
+    DBT key, data;
+    static char* kwnames[] = { "key", "data", "flags", "dlen", "doff",
+                                     NULL };
+    int dlen = -1;
+    int doff = -1;
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|iii:put", kwnames,
+				     &keyobj, &dataobj, &flags, &dlen, &doff))
+        return NULL;
+
+    CHECK_CURSOR_NOT_CLOSED(self);
+
+    if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
+        return NULL;
+    if (!make_dbt(dataobj, &data) ||
+        !add_partial_dbt(&data, dlen, doff) )
+    {
+        FREE_DBT(key);
+        return NULL;
+    }
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->dbc->c_put(self->dbc, &key, &data, flags);
+    MYDB_END_ALLOW_THREADS;
+    FREE_DBT(key);
+    RETURN_IF_ERR();
+    self->mydb->haveStat = 0;
+    RETURN_NONE();
+}
+
+
+static PyObject*
+DBC_set(DBCursorObject* self, PyObject* args, PyObject *kwargs)
+{
+    int err, flags = 0;
+    DBT key, data;
+    PyObject* retval, *keyobj;
+    static char* kwnames[] = { "key", "flags", "dlen", "doff", NULL };
+    int dlen = -1;
+    int doff = -1;
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|iii:set", kwnames,
+				     &keyobj, &flags, &dlen, &doff))
+        return NULL;
+
+    CHECK_CURSOR_NOT_CLOSED(self);
+
+    if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
+        return NULL;
+
+    CLEAR_DBT(data);
+    if (CHECK_DBFLAG(self->mydb, DB_THREAD)) {
+        /* Tell BerkeleyDB to malloc the return value (thread safe) */
+        data.flags = DB_DBT_MALLOC;
+    }
+    if (!add_partial_dbt(&data, dlen, doff)) {
+        FREE_DBT(key);
+        return NULL;
+    }
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->dbc->c_get(self->dbc, &key, &data, flags|DB_SET);
+    MYDB_END_ALLOW_THREADS;
+    if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
+	    && self->mydb->moduleFlags.cursorSetReturnsNone) {
+        Py_INCREF(Py_None);
+        retval = Py_None;
+    }
+    else if (makeDBError(err)) {
+        retval = NULL;
+    }
+    else {
+        switch (_DB_get_type(self->mydb)) {
+        case -1:
+            retval = NULL;
+            break;
+        case DB_BTREE:
+        case DB_HASH:
+        default:
+            retval = Py_BuildValue("s#s#", key.data, key.size,
+                                   data.data, data.size);
+            break;
+        case DB_RECNO:
+        case DB_QUEUE:
+            retval = Py_BuildValue("is#", *((db_recno_t*)key.data),
+                                   data.data, data.size);
+            break;
+        }
+        FREE_DBT(data);
+        FREE_DBT(key);
+    }
+    /* the only time REALLOC should be set is if we used an integer
+     * key that make_key_dbt malloc'd for us.  always free these. */
+    if (key.flags & DB_DBT_REALLOC) {
+        FREE_DBT(key);
+    }
+
+    return retval;
+}
+
+
+static PyObject*
+DBC_set_range(DBCursorObject* self, PyObject* args, PyObject* kwargs)
+{
+    int err, flags = 0;
+    DBT key, data;
+    PyObject* retval, *keyobj;
+    static char* kwnames[] = { "key", "flags", "dlen", "doff", NULL };
+    int dlen = -1;
+    int doff = -1;
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|iii:set_range", kwnames,
+				     &keyobj, &flags, &dlen, &doff))
+        return NULL;
+
+    CHECK_CURSOR_NOT_CLOSED(self);
+
+    if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
+        return NULL;
+
+    CLEAR_DBT(data);
+    if (!add_partial_dbt(&data, dlen, doff)) {
+        FREE_DBT(key);
+        return NULL;
+    }
+    if (CHECK_DBFLAG(self->mydb, DB_THREAD)) {
+        /* Tell BerkeleyDB to malloc the return value (thread safe) */
+        data.flags |= DB_DBT_MALLOC;
+        /* only BTREE databases will return anything in the key */
+        if (!(key.flags & DB_DBT_REALLOC) && _DB_get_type(self->mydb) == DB_BTREE) {
+            key.flags |= DB_DBT_MALLOC;
+        }
+    }
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->dbc->c_get(self->dbc, &key, &data, flags|DB_SET_RANGE);
+    MYDB_END_ALLOW_THREADS;
+    if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
+	    && self->mydb->moduleFlags.cursorSetReturnsNone) {
+        Py_INCREF(Py_None);
+        retval = Py_None;
+    }
+    else if (makeDBError(err)) {
+        retval = NULL;
+    }
+    else {
+        switch (_DB_get_type(self->mydb)) {
+        case -1:
+            retval = NULL;
+            break;
+        case DB_BTREE:
+        case DB_HASH:
+        default:
+            retval = Py_BuildValue("s#s#", key.data, key.size,
+                                   data.data, data.size);
+            break;
+        case DB_RECNO:
+        case DB_QUEUE:
+            retval = Py_BuildValue("is#", *((db_recno_t*)key.data),
+                                   data.data, data.size);
+            break;
+        }
+        FREE_DBT(key);
+        FREE_DBT(data);
+    }
+    /* the only time REALLOC should be set is if we used an integer
+     * key that make_key_dbt malloc'd for us.  always free these. */
+    if (key.flags & DB_DBT_REALLOC) {
+        FREE_DBT(key);
+    }
+
+    return retval;
+}
+
+static PyObject*
+_DBC_get_set_both(DBCursorObject* self, PyObject* keyobj, PyObject* dataobj,
+                  int flags, unsigned int returnsNone)
+{
+    int err;
+    DBT key, data;
+    PyObject* retval;
+
+    /* the caller did this:  CHECK_CURSOR_NOT_CLOSED(self); */
+    if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
+        return NULL;
+    if (!make_dbt(dataobj, &data)) {
+        FREE_DBT(key);
+        return NULL;
+    }
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->dbc->c_get(self->dbc, &key, &data, flags|DB_GET_BOTH);
+    MYDB_END_ALLOW_THREADS;
+    if ((err == DB_NOTFOUND || err == DB_KEYEMPTY) && returnsNone) {
+        Py_INCREF(Py_None);
+        retval = Py_None;
+    }
+    else if (makeDBError(err)) {
+        retval = NULL;
+    }
+    else {
+        switch (_DB_get_type(self->mydb)) {
+        case -1:
+            retval = NULL;
+            break;
+        case DB_BTREE:
+        case DB_HASH:
+        default:
+            retval = Py_BuildValue("s#s#", key.data, key.size,
+                                   data.data, data.size);
+            break;
+        case DB_RECNO:
+        case DB_QUEUE:
+            retval = Py_BuildValue("is#", *((db_recno_t*)key.data),
+                                   data.data, data.size);
+            break;
+        }
+    }
+
+    FREE_DBT(key);
+    return retval;
+}
+
+static PyObject*
+DBC_get_both(DBCursorObject* self, PyObject* args)
+{
+    int flags=0;
+    PyObject *keyobj, *dataobj;
+
+    if (!PyArg_ParseTuple(args, "OO|i:get_both", &keyobj, &dataobj, &flags))
+        return NULL;
+
+    /* if the cursor is closed, self->mydb may be invalid */
+    CHECK_CURSOR_NOT_CLOSED(self);
+
+    return _DBC_get_set_both(self, keyobj, dataobj, flags,
+                self->mydb->moduleFlags.getReturnsNone);
+}
+
+/* Return size of entry */
+static PyObject*
+DBC_get_current_size(DBCursorObject* self, PyObject* args)
+{
+    int err, flags=DB_CURRENT;
+    PyObject* retval = NULL;
+    DBT key, data;
+
+    if (!PyArg_ParseTuple(args, ":get_current_size"))
+        return NULL;
+    CHECK_CURSOR_NOT_CLOSED(self);
+    CLEAR_DBT(key);
+    CLEAR_DBT(data);
+
+    /* We don't allocate any memory, forcing a DB_BUFFER_SMALL error and thus
+       getting the record size. */
+    data.flags = DB_DBT_USERMEM;
+    data.ulen = 0;
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->dbc->c_get(self->dbc, &key, &data, flags);
+    MYDB_END_ALLOW_THREADS;
+    if (err == DB_BUFFER_SMALL || !err) {
+        /* DB_BUFFER_SMALL means positive size, !err means zero length value */
+        retval = PyInt_FromLong((long)data.size);
+        err = 0;
+    }
+
+    FREE_DBT(key);
+    FREE_DBT(data);
+    RETURN_IF_ERR();
+    return retval;
+}
+
+static PyObject*
+DBC_set_both(DBCursorObject* self, PyObject* args)
+{
+    int flags=0;
+    PyObject *keyobj, *dataobj;
+
+    if (!PyArg_ParseTuple(args, "OO|i:set_both", &keyobj, &dataobj, &flags))
+        return NULL;
+
+    /* if the cursor is closed, self->mydb may be invalid */
+    CHECK_CURSOR_NOT_CLOSED(self);
+
+    return _DBC_get_set_both(self, keyobj, dataobj, flags,
+                self->mydb->moduleFlags.cursorSetReturnsNone);
+}
+
+
+static PyObject*
+DBC_set_recno(DBCursorObject* self, PyObject* args, PyObject *kwargs)
+{
+    int err, irecno, flags=0;
+    db_recno_t recno;
+    DBT key, data;
+    PyObject* retval;
+    int dlen = -1;
+    int doff = -1;
+    static char* kwnames[] = { "recno","flags", "dlen", "doff", NULL };
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|iii:set_recno", kwnames,
+				     &irecno, &flags, &dlen, &doff))
+      return NULL;
+
+    CHECK_CURSOR_NOT_CLOSED(self);
+
+    CLEAR_DBT(key);
+    recno = (db_recno_t) irecno;
+    /* use allocated space so DB will be able to realloc room for the real
+     * key */
+    key.data = malloc(sizeof(db_recno_t));
+    if (key.data == NULL) {
+        PyErr_SetString(PyExc_MemoryError, "Key memory allocation failed");
+        return NULL;
+    }
+    key.size = sizeof(db_recno_t);
+    key.ulen = key.size;
+    memcpy(key.data, &recno, sizeof(db_recno_t));
+    key.flags = DB_DBT_REALLOC;
+
+    CLEAR_DBT(data);
+    if (CHECK_DBFLAG(self->mydb, DB_THREAD)) {
+        /* Tell BerkeleyDB to malloc the return value (thread safe) */
+        data.flags = DB_DBT_MALLOC;
+    }
+    if (!add_partial_dbt(&data, dlen, doff)) {
+        FREE_DBT(key);
+        return NULL;
+    }
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->dbc->c_get(self->dbc, &key, &data, flags|DB_SET_RECNO);
+    MYDB_END_ALLOW_THREADS;
+    if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
+	    && self->mydb->moduleFlags.cursorSetReturnsNone) {
+        Py_INCREF(Py_None);
+        retval = Py_None;
+    }
+    else if (makeDBError(err)) {
+        retval = NULL;
+    }
+    else {  /* Can only be used for BTrees, so no need to return int key */
+        retval = Py_BuildValue("s#s#", key.data, key.size,
+                               data.data, data.size);
+        FREE_DBT(data);
+    }
+    FREE_DBT(key);
+
+    return retval;
+}
+
+
+static PyObject*
+DBC_consume(DBCursorObject* self, PyObject* args, PyObject *kwargs)
+{
+    return _DBCursor_get(self,DB_CONSUME,args,kwargs,"|iii:consume");
+}
+
+
+static PyObject*
+DBC_next_dup(DBCursorObject* self, PyObject* args, PyObject *kwargs)
+{
+    return _DBCursor_get(self,DB_NEXT_DUP,args,kwargs,"|iii:next_dup");
+}
+
+
+static PyObject*
+DBC_next_nodup(DBCursorObject* self, PyObject* args, PyObject *kwargs)
+{
+    return _DBCursor_get(self,DB_NEXT_NODUP,args,kwargs,"|iii:next_nodup");
+}
+
+
+static PyObject*
+DBC_prev_nodup(DBCursorObject* self, PyObject* args, PyObject *kwargs)
+{
+    return _DBCursor_get(self,DB_PREV_NODUP,args,kwargs,"|iii:prev_nodup");
+}
+
+
+static PyObject*
+DBC_join_item(DBCursorObject* self, PyObject* args)
+{
+    int err, flags=0;
+    DBT key, data;
+    PyObject* retval;
+
+    if (!PyArg_ParseTuple(args, "|i:join_item", &flags))
+        return NULL;
+
+    CHECK_CURSOR_NOT_CLOSED(self);
+
+    CLEAR_DBT(key);
+    CLEAR_DBT(data);
+    if (CHECK_DBFLAG(self->mydb, DB_THREAD)) {
+        /* Tell BerkeleyDB to malloc the return value (thread safe) */
+        key.flags = DB_DBT_MALLOC;
+    }
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->dbc->c_get(self->dbc, &key, &data, flags | DB_JOIN_ITEM);
+    MYDB_END_ALLOW_THREADS;
+    if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
+	    && self->mydb->moduleFlags.getReturnsNone) {
+        Py_INCREF(Py_None);
+        retval = Py_None;
+    }
+    else if (makeDBError(err)) {
+        retval = NULL;
+    }
+    else {
+        retval = Py_BuildValue("s#", key.data, key.size);
+        FREE_DBT(key);
+    }
+
+    return retval;
+}
+
+
+
+/* --------------------------------------------------------------------- */
+/* DBEnv methods */
+
+
+static PyObject*
+DBEnv_close(DBEnvObject* self, PyObject* args)
+{
+    int err, flags = 0;
+
+    if (!PyArg_ParseTuple(args, "|i:close", &flags))
+        return NULL;
+    if (!self->closed) {      /* Don't close more than once */
+        MYDB_BEGIN_ALLOW_THREADS;
+        err = self->db_env->close(self->db_env, flags);
+        MYDB_END_ALLOW_THREADS;
+        /* after calling DBEnv->close, regardless of error, this DBEnv
+         * may not be accessed again (BerkeleyDB docs). */
+        self->closed = 1;
+        self->db_env = NULL;
+        RETURN_IF_ERR();
+    }
+    RETURN_NONE();
+}
+
+
+static PyObject*
+DBEnv_open(DBEnvObject* self, PyObject* args)
+{
+    int err, flags=0, mode=0660;
+    char *db_home;
+
+    if (!PyArg_ParseTuple(args, "z|ii:open", &db_home, &flags, &mode))
+        return NULL;
+
+    CHECK_ENV_NOT_CLOSED(self);
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db_env->open(self->db_env, db_home, flags, mode);
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+    self->closed = 0;
+    self->flags = flags;
+    RETURN_NONE();
+}
+
+
+static PyObject*
+DBEnv_remove(DBEnvObject* self, PyObject* args)
+{
+    int err, flags=0;
+    char *db_home;
+
+    if (!PyArg_ParseTuple(args, "s|i:remove", &db_home, &flags))
+        return NULL;
+    CHECK_ENV_NOT_CLOSED(self);
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db_env->remove(self->db_env, db_home, flags);
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+
+#if (DBVER >= 41)
+static PyObject*
+DBEnv_dbremove(DBEnvObject* self, PyObject* args, PyObject* kwargs)
+{
+    int err;
+    u_int32_t flags=0;
+    char *file = NULL;
+    char *database = NULL;
+    PyObject *txnobj = NULL;
+    DB_TXN *txn = NULL;
+    static char* kwnames[] = { "file", "database", "txn", "flags",
+                                     NULL };
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|zOi:dbremove", kwnames,
+		&file, &database, &txnobj, &flags)) {
+	return NULL;
+    }
+    if (!checkTxnObj(txnobj, &txn)) {
+        return NULL;
+    }
+    CHECK_ENV_NOT_CLOSED(self);
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db_env->dbremove(self->db_env, txn, file, database, flags);
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+
+static PyObject*
+DBEnv_dbrename(DBEnvObject* self, PyObject* args, PyObject* kwargs)
+{
+    int err;
+    u_int32_t flags=0;
+    char *file = NULL;
+    char *database = NULL;
+    char *newname = NULL;
+    PyObject *txnobj = NULL;
+    DB_TXN *txn = NULL;
+    static char* kwnames[] = { "file", "database", "newname", "txn",
+                                     "flags", NULL };
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "szs|Oi:dbrename", kwnames,
+		&file, &database, &newname, &txnobj, &flags)) {
+	return NULL;
+    }
+    if (!checkTxnObj(txnobj, &txn)) {
+        return NULL;
+    }
+    CHECK_ENV_NOT_CLOSED(self);
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db_env->dbrename(self->db_env, txn, file, database, newname,
+                                 flags);
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+
+static PyObject*
+DBEnv_set_encrypt(DBEnvObject* self, PyObject* args, PyObject* kwargs)
+{
+    int err;
+    u_int32_t flags=0;
+    char *passwd = NULL;
+    static char* kwnames[] = { "passwd", "flags", NULL };
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|i:set_encrypt", kwnames,
+		&passwd, &flags)) {
+	return NULL;
+    }
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db_env->set_encrypt(self->db_env, passwd, flags);
+    MYDB_END_ALLOW_THREADS;
+
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+#endif /* DBVER >= 41 */
+
+#if (DBVER >= 40)
+static PyObject*
+DBEnv_set_timeout(DBEnvObject* self, PyObject* args, PyObject* kwargs)
+{
+    int err;
+    u_int32_t flags=0;
+    u_int32_t timeout = 0;
+    static char* kwnames[] = { "timeout", "flags", NULL };
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii:set_timeout", kwnames,
+		&timeout, &flags)) {
+	return NULL;
+    }
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db_env->set_timeout(self->db_env, (db_timeout_t)timeout, flags);
+    MYDB_END_ALLOW_THREADS;
+
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+#endif /* DBVER >= 40 */
+
+static PyObject*
+DBEnv_set_shm_key(DBEnvObject* self, PyObject* args)
+{
+    int err;
+    long shm_key = 0;
+
+    if (!PyArg_ParseTuple(args, "l:set_shm_key", &shm_key))
+        return NULL;
+    CHECK_ENV_NOT_CLOSED(self);
+
+    err = self->db_env->set_shm_key(self->db_env, shm_key);
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+
+static PyObject*
+DBEnv_set_cachesize(DBEnvObject* self, PyObject* args)
+{
+    int err, gbytes=0, bytes=0, ncache=0;
+
+    if (!PyArg_ParseTuple(args, "ii|i:set_cachesize",
+                          &gbytes, &bytes, &ncache))
+        return NULL;
+    CHECK_ENV_NOT_CLOSED(self);
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db_env->set_cachesize(self->db_env, gbytes, bytes, ncache);
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+
+
+#if (DBVER >= 32)
+static PyObject*
+DBEnv_set_flags(DBEnvObject* self, PyObject* args)
+{
+    int err, flags=0, onoff=0;
+
+    if (!PyArg_ParseTuple(args, "ii:set_flags",
+                          &flags, &onoff))
+        return NULL;
+    CHECK_ENV_NOT_CLOSED(self);
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db_env->set_flags(self->db_env, flags, onoff);
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+#endif
+
+
+static PyObject*
+DBEnv_set_data_dir(DBEnvObject* self, PyObject* args)
+{
+    int err;
+    char *dir;
+
+    if (!PyArg_ParseTuple(args, "s:set_data_dir", &dir))
+        return NULL;
+    CHECK_ENV_NOT_CLOSED(self);
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db_env->set_data_dir(self->db_env, dir);
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+
+
+static PyObject*
+DBEnv_set_lg_bsize(DBEnvObject* self, PyObject* args)
+{
+    int err, lg_bsize;
+
+    if (!PyArg_ParseTuple(args, "i:set_lg_bsize", &lg_bsize))
+        return NULL;
+    CHECK_ENV_NOT_CLOSED(self);
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db_env->set_lg_bsize(self->db_env, lg_bsize);
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+
+
+static PyObject*
+DBEnv_set_lg_dir(DBEnvObject* self, PyObject* args)
+{
+    int err;
+    char *dir;
+
+    if (!PyArg_ParseTuple(args, "s:set_lg_dir", &dir))
+        return NULL;
+    CHECK_ENV_NOT_CLOSED(self);
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db_env->set_lg_dir(self->db_env, dir);
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+
+static PyObject*
+DBEnv_set_lg_max(DBEnvObject* self, PyObject* args)
+{
+    int err, lg_max;
+
+    if (!PyArg_ParseTuple(args, "i:set_lg_max", &lg_max))
+        return NULL;
+    CHECK_ENV_NOT_CLOSED(self);
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db_env->set_lg_max(self->db_env, lg_max);
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+
+
+#if (DBVER >= 33)
+static PyObject*
+DBEnv_set_lg_regionmax(DBEnvObject* self, PyObject* args)
+{
+    int err, lg_max;
+
+    if (!PyArg_ParseTuple(args, "i:set_lg_regionmax", &lg_max))
+        return NULL;
+    CHECK_ENV_NOT_CLOSED(self);
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db_env->set_lg_regionmax(self->db_env, lg_max);
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+#endif
+
+
+static PyObject*
+DBEnv_set_lk_detect(DBEnvObject* self, PyObject* args)
+{
+    int err, lk_detect;
+
+    if (!PyArg_ParseTuple(args, "i:set_lk_detect", &lk_detect))
+        return NULL;
+    CHECK_ENV_NOT_CLOSED(self);
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db_env->set_lk_detect(self->db_env, lk_detect);
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+
+
+#if (DBVER < 45)
+static PyObject*
+DBEnv_set_lk_max(DBEnvObject* self, PyObject* args)
+{
+    int err, max;
+
+    if (!PyArg_ParseTuple(args, "i:set_lk_max", &max))
+        return NULL;
+    CHECK_ENV_NOT_CLOSED(self);
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db_env->set_lk_max(self->db_env, max);
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+#endif
+
+
+#if (DBVER >= 32)
+
+static PyObject*
+DBEnv_set_lk_max_locks(DBEnvObject* self, PyObject* args)
+{
+    int err, max;
+
+    if (!PyArg_ParseTuple(args, "i:set_lk_max_locks", &max))
+        return NULL;
+    CHECK_ENV_NOT_CLOSED(self);
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db_env->set_lk_max_locks(self->db_env, max);
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+
+
+static PyObject*
+DBEnv_set_lk_max_lockers(DBEnvObject* self, PyObject* args)
+{
+    int err, max;
+
+    if (!PyArg_ParseTuple(args, "i:set_lk_max_lockers", &max))
+        return NULL;
+    CHECK_ENV_NOT_CLOSED(self);
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db_env->set_lk_max_lockers(self->db_env, max);
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+
+
+static PyObject*
+DBEnv_set_lk_max_objects(DBEnvObject* self, PyObject* args)
+{
+    int err, max;
+
+    if (!PyArg_ParseTuple(args, "i:set_lk_max_objects", &max))
+        return NULL;
+    CHECK_ENV_NOT_CLOSED(self);
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db_env->set_lk_max_objects(self->db_env, max);
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+
+#endif
+
+
+static PyObject*
+DBEnv_set_mp_mmapsize(DBEnvObject* self, PyObject* args)
+{
+    int err, mp_mmapsize;
+
+    if (!PyArg_ParseTuple(args, "i:set_mp_mmapsize", &mp_mmapsize))
+        return NULL;
+    CHECK_ENV_NOT_CLOSED(self);
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db_env->set_mp_mmapsize(self->db_env, mp_mmapsize);
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+
+
+static PyObject*
+DBEnv_set_tmp_dir(DBEnvObject* self, PyObject* args)
+{
+    int err;
+    char *dir;
+
+    if (!PyArg_ParseTuple(args, "s:set_tmp_dir", &dir))
+        return NULL;
+    CHECK_ENV_NOT_CLOSED(self);
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db_env->set_tmp_dir(self->db_env, dir);
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+
+
+static PyObject*
+DBEnv_txn_begin(DBEnvObject* self, PyObject* args, PyObject* kwargs)
+{
+    int flags = 0;
+    PyObject* txnobj = NULL;
+    DB_TXN *txn = NULL;
+    static char* kwnames[] = { "parent", "flags", NULL };
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:txn_begin", kwnames,
+                                     &txnobj, &flags))
+        return NULL;
+
+    if (!checkTxnObj(txnobj, &txn))
+        return NULL;
+    CHECK_ENV_NOT_CLOSED(self);
+
+    return (PyObject*)newDBTxnObject(self, txn, flags);
+}
+
+
+static PyObject*
+DBEnv_txn_checkpoint(DBEnvObject* self, PyObject* args)
+{
+    int err, kbyte=0, min=0, flags=0;
+
+    if (!PyArg_ParseTuple(args, "|iii:txn_checkpoint", &kbyte, &min, &flags))
+        return NULL;
+    CHECK_ENV_NOT_CLOSED(self);
+
+    MYDB_BEGIN_ALLOW_THREADS;
+#if (DBVER >= 40)
+    err = self->db_env->txn_checkpoint(self->db_env, kbyte, min, flags);
+#else
+    err = txn_checkpoint(self->db_env, kbyte, min, flags);
+#endif
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+
+
+static PyObject*
+DBEnv_set_tx_max(DBEnvObject* self, PyObject* args)
+{
+    int err, max;
+
+    if (!PyArg_ParseTuple(args, "i:set_tx_max", &max))
+        return NULL;
+    CHECK_ENV_NOT_CLOSED(self);
+
+    err = self->db_env->set_tx_max(self->db_env, max);
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+
+
+static PyObject*
+DBEnv_set_tx_timestamp(DBEnvObject* self, PyObject* args)
+{
+    int err;
+    long stamp;
+    time_t timestamp;
+
+    if (!PyArg_ParseTuple(args, "l:set_tx_timestamp", &stamp))
+        return NULL;
+    CHECK_ENV_NOT_CLOSED(self);
+    timestamp = (time_t)stamp;
+    err = self->db_env->set_tx_timestamp(self->db_env, &timestamp);
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+
+
+static PyObject*
+DBEnv_lock_detect(DBEnvObject* self, PyObject* args)
+{
+    int err, atype, flags=0;
+    int aborted = 0;
+
+    if (!PyArg_ParseTuple(args, "i|i:lock_detect", &atype, &flags))
+        return NULL;
+    CHECK_ENV_NOT_CLOSED(self);
+
+    MYDB_BEGIN_ALLOW_THREADS;
+#if (DBVER >= 40)
+    err = self->db_env->lock_detect(self->db_env, flags, atype, &aborted);
+#else
+    err = lock_detect(self->db_env, flags, atype, &aborted);
+#endif
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+    return PyInt_FromLong(aborted);
+}
+
+
+static PyObject*
+DBEnv_lock_get(DBEnvObject* self, PyObject* args)
+{
+    int flags=0;
+    int locker, lock_mode;
+    DBT obj;
+    PyObject* objobj;
+
+    if (!PyArg_ParseTuple(args, "iOi|i:lock_get", &locker, &objobj, &lock_mode, &flags))
+        return NULL;
+
+
+    if (!make_dbt(objobj, &obj))
+        return NULL;
+
+    return (PyObject*)newDBLockObject(self, locker, &obj, lock_mode, flags);
+}
+
+
+static PyObject*
+DBEnv_lock_id(DBEnvObject* self, PyObject* args)
+{
+    int err;
+    u_int32_t theID;
+
+    if (!PyArg_ParseTuple(args, ":lock_id"))
+        return NULL;
+
+    CHECK_ENV_NOT_CLOSED(self);
+    MYDB_BEGIN_ALLOW_THREADS;
+#if (DBVER >= 40)
+    err = self->db_env->lock_id(self->db_env, &theID);
+#else
+    err = lock_id(self->db_env, &theID);
+#endif
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+
+    return PyInt_FromLong((long)theID);
+}
+
+
+static PyObject*
+DBEnv_lock_put(DBEnvObject* self, PyObject* args)
+{
+    int err;
+    DBLockObject* dblockobj;
+
+    if (!PyArg_ParseTuple(args, "O!:lock_put", &DBLock_Type, &dblockobj))
+        return NULL;
+
+    CHECK_ENV_NOT_CLOSED(self);
+    MYDB_BEGIN_ALLOW_THREADS;
+#if (DBVER >= 40)
+    err = self->db_env->lock_put(self->db_env, &dblockobj->lock);
+#else
+    err = lock_put(self->db_env, &dblockobj->lock);
+#endif
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+
+#if (DBVER >= 44)
+static PyObject*
+DBEnv_lsn_reset(DBEnvObject* self, PyObject* args, PyObject* kwargs)
+{
+    int err;
+    char *file;
+    u_int32_t flags = 0;
+    static char* kwnames[] = { "file", "flags", NULL};
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|i:lsn_reset", kwnames,
+                                     &file, &flags))
+        return NULL;
+    CHECK_ENV_NOT_CLOSED(self);
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db_env->lsn_reset(self->db_env, file, flags);
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+#endif /* DBVER >= 4.4 */
+
+#if (DBVER >= 40)
+static PyObject*
+DBEnv_log_stat(DBEnvObject* self, PyObject* args)
+{
+    int err;
+    DB_LOG_STAT* statp = NULL;
+    PyObject* d = NULL;
+    u_int32_t flags = 0;
+
+    if (!PyArg_ParseTuple(args, "|i:log_stat", &flags))
+        return NULL;
+    CHECK_ENV_NOT_CLOSED(self);
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db_env->log_stat(self->db_env, &statp, flags);
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+
+    /* Turn the stat structure into a dictionary */
+    d = PyDict_New();
+    if (d == NULL) {
+        if (statp)
+            free(statp);
+        return NULL;
+    }
+
+#define MAKE_ENTRY(name)  _addIntToDict(d, #name, statp->st_##name)
+
+    MAKE_ENTRY(magic);
+    MAKE_ENTRY(version);
+    MAKE_ENTRY(mode);
+    MAKE_ENTRY(lg_bsize);
+#if (DBVER >= 44)
+    MAKE_ENTRY(lg_size);
+    MAKE_ENTRY(record);
+#endif
+#if (DBVER <= 40)
+    MAKE_ENTRY(lg_max);
+#endif
+    MAKE_ENTRY(w_mbytes);
+    MAKE_ENTRY(w_bytes);
+    MAKE_ENTRY(wc_mbytes);
+    MAKE_ENTRY(wc_bytes);
+    MAKE_ENTRY(wcount);
+    MAKE_ENTRY(wcount_fill);
+#if (DBVER >= 44)
+    MAKE_ENTRY(rcount);
+#endif
+    MAKE_ENTRY(scount);
+    MAKE_ENTRY(cur_file);
+    MAKE_ENTRY(cur_offset);
+    MAKE_ENTRY(disk_file);
+    MAKE_ENTRY(disk_offset);
+    MAKE_ENTRY(maxcommitperflush);
+    MAKE_ENTRY(mincommitperflush);
+    MAKE_ENTRY(regsize);
+    MAKE_ENTRY(region_wait);
+    MAKE_ENTRY(region_nowait);
+
+#undef MAKE_ENTRY
+    free(statp);
+    return d;
+} /* DBEnv_log_stat */
+#endif /* DBVER >= 4.0 for log_stat method */
+
+
+static PyObject*
+DBEnv_lock_stat(DBEnvObject* self, PyObject* args)
+{
+    int err;
+    DB_LOCK_STAT* sp;
+    PyObject* d = NULL;
+    u_int32_t flags = 0;
+
+    if (!PyArg_ParseTuple(args, "|i:lock_stat", &flags))
+        return NULL;
+    CHECK_ENV_NOT_CLOSED(self);
+
+    MYDB_BEGIN_ALLOW_THREADS;
+#if (DBVER >= 40)
+    err = self->db_env->lock_stat(self->db_env, &sp, flags);
+#else
+#if (DBVER >= 33)
+    err = lock_stat(self->db_env, &sp);
+#else
+    err = lock_stat(self->db_env, &sp, NULL);
+#endif
+#endif
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+
+    /* Turn the stat structure into a dictionary */
+    d = PyDict_New();
+    if (d == NULL) {
+        free(sp);
+        return NULL;
+    }
+
+#define MAKE_ENTRY(name)  _addIntToDict(d, #name, sp->st_##name)
+
+#if (DBVER < 41)
+    MAKE_ENTRY(lastid);
+#endif
+    MAKE_ENTRY(nmodes);
+#if (DBVER >= 32)
+    MAKE_ENTRY(maxlocks);
+    MAKE_ENTRY(maxlockers);
+    MAKE_ENTRY(maxobjects);
+    MAKE_ENTRY(nlocks);
+    MAKE_ENTRY(maxnlocks);
+#endif
+    MAKE_ENTRY(nlockers);
+    MAKE_ENTRY(maxnlockers);
+#if (DBVER >= 32)
+    MAKE_ENTRY(nobjects);
+    MAKE_ENTRY(maxnobjects);
+#endif
+    MAKE_ENTRY(nrequests);
+    MAKE_ENTRY(nreleases);
+#if (DBVER < 44)
+    MAKE_ENTRY(nnowaits);       /* these were renamed in 4.4 */
+    MAKE_ENTRY(nconflicts);
+#else
+    MAKE_ENTRY(lock_nowait);
+    MAKE_ENTRY(lock_wait);
+#endif
+    MAKE_ENTRY(ndeadlocks);
+    MAKE_ENTRY(regsize);
+    MAKE_ENTRY(region_wait);
+    MAKE_ENTRY(region_nowait);
+
+#undef MAKE_ENTRY
+    free(sp);
+    return d;
+}
+
+
+static PyObject*
+DBEnv_log_archive(DBEnvObject* self, PyObject* args)
+{
+    int flags=0;
+    int err;
+    char **log_list = NULL;
+    PyObject* list;
+    PyObject* item = NULL;
+
+    if (!PyArg_ParseTuple(args, "|i:log_archive", &flags))
+        return NULL;
+
+    CHECK_ENV_NOT_CLOSED(self);
+    MYDB_BEGIN_ALLOW_THREADS;
+#if (DBVER >= 40)
+    err = self->db_env->log_archive(self->db_env, &log_list, flags);
+#elif (DBVER == 33)
+    err = log_archive(self->db_env, &log_list, flags);
+#else
+    err = log_archive(self->db_env, &log_list, flags, NULL);
+#endif
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+
+    list = PyList_New(0);
+    if (list == NULL) {
+        if (log_list)
+            free(log_list);
+        return NULL;
+    }
+
+    if (log_list) {
+        char **log_list_start;
+        for (log_list_start = log_list; *log_list != NULL; ++log_list) {
+            item = PyString_FromString (*log_list);
+            if (item == NULL) {
+                Py_DECREF(list);
+                list = NULL;
+                break;
+            }
+            PyList_Append(list, item);
+            Py_DECREF(item);
+        }
+        free(log_list_start);
+    }
+    return list;
+}
+
+
+static PyObject*
+DBEnv_txn_stat(DBEnvObject* self, PyObject* args)
+{
+    int err;
+    DB_TXN_STAT* sp;
+    PyObject* d = NULL;
+    u_int32_t flags=0;
+
+    if (!PyArg_ParseTuple(args, "|i:txn_stat", &flags))
+        return NULL;
+    CHECK_ENV_NOT_CLOSED(self);
+
+    MYDB_BEGIN_ALLOW_THREADS;
+#if (DBVER >= 40)
+    err = self->db_env->txn_stat(self->db_env, &sp, flags);
+#elif (DBVER == 33)
+    err = txn_stat(self->db_env, &sp);
+#else
+    err = txn_stat(self->db_env, &sp, NULL);
+#endif
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+
+    /* Turn the stat structure into a dictionary */
+    d = PyDict_New();
+    if (d == NULL) {
+        free(sp);
+        return NULL;
+    }
+
+#define MAKE_ENTRY(name)  _addIntToDict(d, #name, sp->st_##name)
+
+    MAKE_ENTRY(time_ckp);
+    MAKE_ENTRY(last_txnid);
+    MAKE_ENTRY(maxtxns);
+    MAKE_ENTRY(nactive);
+    MAKE_ENTRY(maxnactive);
+    MAKE_ENTRY(nbegins);
+    MAKE_ENTRY(naborts);
+    MAKE_ENTRY(ncommits);
+    MAKE_ENTRY(regsize);
+    MAKE_ENTRY(region_wait);
+    MAKE_ENTRY(region_nowait);
+
+#undef MAKE_ENTRY
+    free(sp);
+    return d;
+}
+
+
+static PyObject*
+DBEnv_set_get_returns_none(DBEnvObject* self, PyObject* args)
+{
+    int flags=0;
+    int oldValue=0;
+
+    if (!PyArg_ParseTuple(args,"i:set_get_returns_none", &flags))
+        return NULL;
+    CHECK_ENV_NOT_CLOSED(self);
+
+    if (self->moduleFlags.getReturnsNone)
+        ++oldValue;
+    if (self->moduleFlags.cursorSetReturnsNone)
+        ++oldValue;
+    self->moduleFlags.getReturnsNone = (flags >= 1);
+    self->moduleFlags.cursorSetReturnsNone = (flags >= 2);
+    return PyInt_FromLong(oldValue);
+}
+
+
+/* --------------------------------------------------------------------- */
+/* DBTxn methods */
+
+
+static PyObject*
+DBTxn_commit(DBTxnObject* self, PyObject* args)
+{
+    int flags=0, err;
+    DB_TXN *txn;
+
+    if (!PyArg_ParseTuple(args, "|i:commit", &flags))
+        return NULL;
+
+    if (!self->txn) {
+        PyObject *t =  Py_BuildValue("(is)", 0, "DBTxn must not be used "
+                                     "after txn_commit or txn_abort");
+        PyErr_SetObject(DBError, t);
+        Py_DECREF(t);
+        return NULL;
+    }
+    txn = self->txn;
+    self->txn = NULL;   /* this DB_TXN is no longer valid after this call */
+    MYDB_BEGIN_ALLOW_THREADS;
+#if (DBVER >= 40)
+    err = txn->commit(txn, flags);
+#else
+    err = txn_commit(txn, flags);
+#endif
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+
+static PyObject*
+DBTxn_prepare(DBTxnObject* self, PyObject* args)
+{
+#if (DBVER >= 33)
+    int err;
+    char* gid=NULL;
+    int   gid_size=0;
+
+    if (!PyArg_ParseTuple(args, "s#:prepare", &gid, &gid_size))
+        return NULL;
+
+    if (gid_size != DB_XIDDATASIZE) {
+        PyErr_SetString(PyExc_TypeError,
+                        "gid must be DB_XIDDATASIZE bytes long");
+        return NULL;
+    }
+
+    if (!self->txn) {
+        PyObject *t = Py_BuildValue("(is)", 0,"DBTxn must not be used "
+                                    "after txn_commit or txn_abort");
+        PyErr_SetObject(DBError, t);
+        Py_DECREF(t);
+        return NULL;
+    }
+    MYDB_BEGIN_ALLOW_THREADS;
+#if (DBVER >= 40)
+    err = self->txn->prepare(self->txn, (u_int8_t*)gid);
+#else
+    err = txn_prepare(self->txn, (u_int8_t*)gid);
+#endif
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+    RETURN_NONE();
+#else
+    int err;
+
+    if (!PyArg_ParseTuple(args, ":prepare"))
+        return NULL;
+
+    if (!self->txn) {
+        PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
+                                    "after txn_commit or txn_abort");
+        PyErr_SetObject(DBError, t);
+        Py_DECREF(t);
+        return NULL;
+    }
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = txn_prepare(self->txn);
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+    RETURN_NONE();
+#endif
+}
+
+
+static PyObject*
+DBTxn_abort(DBTxnObject* self, PyObject* args)
+{
+    int err;
+    DB_TXN *txn;
+
+    if (!PyArg_ParseTuple(args, ":abort"))
+        return NULL;
+
+    if (!self->txn) {
+        PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
+                                    "after txn_commit or txn_abort");
+        PyErr_SetObject(DBError, t);
+        Py_DECREF(t);
+        return NULL;
+    }
+    txn = self->txn;
+    self->txn = NULL;   /* this DB_TXN is no longer valid after this call */
+    MYDB_BEGIN_ALLOW_THREADS;
+#if (DBVER >= 40)
+    err = txn->abort(txn);
+#else
+    err = txn_abort(txn);
+#endif
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+
+
+static PyObject*
+DBTxn_id(DBTxnObject* self, PyObject* args)
+{
+    int id;
+
+    if (!PyArg_ParseTuple(args, ":id"))
+        return NULL;
+
+    if (!self->txn) {
+        PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
+                                    "after txn_commit or txn_abort");
+        PyErr_SetObject(DBError, t);
+        Py_DECREF(t);
+        return NULL;
+    }
+    MYDB_BEGIN_ALLOW_THREADS;
+#if (DBVER >= 40)
+    id = self->txn->id(self->txn);
+#else
+    id = txn_id(self->txn);
+#endif
+    MYDB_END_ALLOW_THREADS;
+    return PyInt_FromLong(id);
+}
+
+#if (DBVER >= 43)
+/* --------------------------------------------------------------------- */
+/* DBSequence methods */
+
+
+static PyObject*
+DBSequence_close(DBSequenceObject* self, PyObject* args)
+{
+    int err, flags=0;
+    if (!PyArg_ParseTuple(args,"|i:close", &flags))
+        return NULL;
+    CHECK_SEQUENCE_NOT_CLOSED(self)
+
+    MYDB_BEGIN_ALLOW_THREADS
+    err = self->sequence->close(self->sequence, flags);
+    self->sequence = NULL;
+    MYDB_END_ALLOW_THREADS
+
+    RETURN_IF_ERR();
+
+    RETURN_NONE();
+}
+
+static PyObject*
+DBSequence_get(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
+{
+    int err, flags = 0;
+    int delta = 1;
+    db_seq_t value;
+    PyObject *txnobj = NULL;
+    DB_TXN *txn = NULL;
+    static char* kwnames[] = {"delta", "txn", "flags", NULL };
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iOi:get", kwnames, &delta, &txnobj, &flags))
+        return NULL;
+    CHECK_SEQUENCE_NOT_CLOSED(self)
+
+    if (!checkTxnObj(txnobj, &txn))
+        return NULL;
+
+    MYDB_BEGIN_ALLOW_THREADS
+    err = self->sequence->get(self->sequence, txn, delta, &value, flags);
+    MYDB_END_ALLOW_THREADS
+
+    RETURN_IF_ERR();
+    return PyLong_FromLongLong(value);
+
+}
+
+static PyObject*
+DBSequence_get_dbp(DBSequenceObject* self, PyObject* args)
+{
+    if (!PyArg_ParseTuple(args,":get_dbp"))
+        return NULL;
+    CHECK_SEQUENCE_NOT_CLOSED(self)
+    Py_INCREF(self->mydb);
+    return (PyObject* )self->mydb;
+}
+
+static PyObject*
+DBSequence_get_key(DBSequenceObject* self, PyObject* args)
+{
+    int err;
+    DBT key;
+    CHECK_SEQUENCE_NOT_CLOSED(self)
+    MYDB_BEGIN_ALLOW_THREADS
+    err = self->sequence->get_key(self->sequence, &key);
+    MYDB_END_ALLOW_THREADS
+
+    RETURN_IF_ERR();
+
+    return PyString_FromStringAndSize(key.data, key.size);
+}
+
+static PyObject*
+DBSequence_init_value(DBSequenceObject* self, PyObject* args)
+{
+    int err;
+    db_seq_t value;
+    if (!PyArg_ParseTuple(args,"L:init_value", &value))
+        return NULL;
+    CHECK_SEQUENCE_NOT_CLOSED(self)
+
+    MYDB_BEGIN_ALLOW_THREADS
+    err = self->sequence->initial_value(self->sequence, value);
+    MYDB_END_ALLOW_THREADS
+
+    RETURN_IF_ERR();
+
+    RETURN_NONE();
+}
+
+static PyObject*
+DBSequence_open(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
+{
+    int err, flags = 0;
+    PyObject* keyobj;
+    PyObject *txnobj = NULL;
+    DB_TXN *txn = NULL;
+    DBT key;
+
+    static char* kwnames[] = {"key", "txn", "flags", NULL };
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:open", kwnames, &keyobj, &txnobj, &flags))
+        return NULL;
+
+    if (!checkTxnObj(txnobj, &txn))
+        return NULL;
+
+    if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
+        return NULL;
+
+    MYDB_BEGIN_ALLOW_THREADS
+    err = self->sequence->open(self->sequence, txn, &key, flags);
+    MYDB_END_ALLOW_THREADS
+
+    CLEAR_DBT(key);
+    RETURN_IF_ERR();
+
+    RETURN_NONE();
+}
+
+static PyObject*
+DBSequence_remove(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
+{
+    int err, flags = 0;
+    PyObject *txnobj = NULL;
+    DB_TXN *txn = NULL;
+
+    static char* kwnames[] = {"txn", "flags", NULL };
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:remove", kwnames, &txnobj, &flags))
+        return NULL;
+
+    if (!checkTxnObj(txnobj, &txn))
+        return NULL;
+
+    CHECK_SEQUENCE_NOT_CLOSED(self)
+
+    MYDB_BEGIN_ALLOW_THREADS
+    err = self->sequence->remove(self->sequence, txn, flags);
+    MYDB_END_ALLOW_THREADS
+
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+
+static PyObject*
+DBSequence_set_cachesize(DBSequenceObject* self, PyObject* args)
+{
+    int err, size;
+    if (!PyArg_ParseTuple(args,"i:set_cachesize", &size))
+        return NULL;
+    CHECK_SEQUENCE_NOT_CLOSED(self)
+
+    MYDB_BEGIN_ALLOW_THREADS
+    err = self->sequence->set_cachesize(self->sequence, size);
+    MYDB_END_ALLOW_THREADS
+
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+
+static PyObject*
+DBSequence_get_cachesize(DBSequenceObject* self, PyObject* args)
+{
+    int err, size;
+    if (!PyArg_ParseTuple(args,":get_cachesize"))
+        return NULL;
+    CHECK_SEQUENCE_NOT_CLOSED(self)
+
+    MYDB_BEGIN_ALLOW_THREADS
+    err = self->sequence->get_cachesize(self->sequence, &size);
+    MYDB_END_ALLOW_THREADS
+
+    RETURN_IF_ERR();
+    return PyInt_FromLong(size);
+}
+
+static PyObject*
+DBSequence_set_flags(DBSequenceObject* self, PyObject* args)
+{
+    int err, flags = 0;
+    if (!PyArg_ParseTuple(args,"i:set_flags", &flags))
+        return NULL;
+    CHECK_SEQUENCE_NOT_CLOSED(self)
+
+    MYDB_BEGIN_ALLOW_THREADS
+    err = self->sequence->set_flags(self->sequence, flags);
+    MYDB_END_ALLOW_THREADS
+
+    RETURN_IF_ERR();
+    RETURN_NONE();
+
+}
+
+static PyObject*
+DBSequence_get_flags(DBSequenceObject* self, PyObject* args)
+{
+    unsigned int flags;
+    int err;
+    if (!PyArg_ParseTuple(args,":get_flags"))
+        return NULL;
+    CHECK_SEQUENCE_NOT_CLOSED(self)
+
+    MYDB_BEGIN_ALLOW_THREADS
+    err = self->sequence->get_flags(self->sequence, &flags);
+    MYDB_END_ALLOW_THREADS
+
+    RETURN_IF_ERR();
+    return PyInt_FromLong((int)flags);
+}
+
+static PyObject*
+DBSequence_set_range(DBSequenceObject* self, PyObject* args)
+{
+    int err;
+    db_seq_t min, max;
+    if (!PyArg_ParseTuple(args,"(LL):set_range", &min, &max))
+        return NULL;
+    CHECK_SEQUENCE_NOT_CLOSED(self)
+
+    MYDB_BEGIN_ALLOW_THREADS
+    err = self->sequence->set_range(self->sequence, min, max);
+    MYDB_END_ALLOW_THREADS
+
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+
+static PyObject*
+DBSequence_get_range(DBSequenceObject* self, PyObject* args)
+{
+    int err;
+    db_seq_t min, max;
+    if (!PyArg_ParseTuple(args,":get_range"))
+        return NULL;
+    CHECK_SEQUENCE_NOT_CLOSED(self)
+
+    MYDB_BEGIN_ALLOW_THREADS
+    err = self->sequence->get_range(self->sequence, &min, &max);
+    MYDB_END_ALLOW_THREADS
+
+    RETURN_IF_ERR();
+    return Py_BuildValue("(LL)", min, max);
+}
+
+static PyObject*
+DBSequence_stat(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
+{
+    int err, flags = 0;
+    DB_SEQUENCE_STAT* sp = NULL;
+    PyObject* dict_stat;
+    static char* kwnames[] = {"flags", NULL };
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat", kwnames, &flags))
+        return NULL;
+    CHECK_SEQUENCE_NOT_CLOSED(self);
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->sequence->stat(self->sequence, &sp, flags);
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+
+    if ((dict_stat = PyDict_New()) == NULL) {
+        free(sp);
+        return NULL;
+    }
+
+
+#define MAKE_INT_ENTRY(name)  _addIntToDict(dict_stat, #name, sp->st_##name)
+#define MAKE_LONG_LONG_ENTRY(name)  _addDb_seq_tToDict(dict_stat, #name, sp->st_##name)
+
+    MAKE_INT_ENTRY(wait);
+    MAKE_INT_ENTRY(nowait);
+    MAKE_LONG_LONG_ENTRY(current);
+    MAKE_LONG_LONG_ENTRY(value);
+    MAKE_LONG_LONG_ENTRY(last_value);
+    MAKE_LONG_LONG_ENTRY(min);
+    MAKE_LONG_LONG_ENTRY(max);
+    MAKE_INT_ENTRY(cache_size);
+    MAKE_INT_ENTRY(flags);
+
+#undef MAKE_INT_ENTRY
+#undef MAKE_LONG_LONG_ENTRY
+
+    free(sp);
+    return dict_stat;
+}
+#endif
+
+
+/* --------------------------------------------------------------------- */
+/* Method definition tables and type objects */
+
+static PyMethodDef DB_methods[] = {
+    {"append",          (PyCFunction)DB_append,         METH_VARARGS},
+#if (DBVER >= 33)
+    {"associate",       (PyCFunction)DB_associate,      METH_VARARGS|METH_KEYWORDS},
+#endif
+    {"close",           (PyCFunction)DB_close,          METH_VARARGS},
+#if (DBVER >= 32)
+    {"consume",         (PyCFunction)DB_consume,        METH_VARARGS|METH_KEYWORDS},
+    {"consume_wait",    (PyCFunction)DB_consume_wait,   METH_VARARGS|METH_KEYWORDS},
+#endif
+    {"cursor",          (PyCFunction)DB_cursor,         METH_VARARGS|METH_KEYWORDS},
+    {"delete",          (PyCFunction)DB_delete,         METH_VARARGS|METH_KEYWORDS},
+    {"fd",              (PyCFunction)DB_fd,             METH_VARARGS},
+    {"get",             (PyCFunction)DB_get,            METH_VARARGS|METH_KEYWORDS},
+#if (DBVER >= 33)
+    {"pget",            (PyCFunction)DB_pget,           METH_VARARGS|METH_KEYWORDS},
+#endif
+    {"get_both",        (PyCFunction)DB_get_both,       METH_VARARGS|METH_KEYWORDS},
+    {"get_byteswapped", (PyCFunction)DB_get_byteswapped,METH_VARARGS},
+    {"get_size",        (PyCFunction)DB_get_size,       METH_VARARGS|METH_KEYWORDS},
+    {"get_type",        (PyCFunction)DB_get_type,       METH_VARARGS},
+    {"join",            (PyCFunction)DB_join,           METH_VARARGS},
+    {"key_range",       (PyCFunction)DB_key_range,      METH_VARARGS|METH_KEYWORDS},
+    {"has_key",         (PyCFunction)DB_has_key,        METH_VARARGS},
+    {"items",           (PyCFunction)DB_items,          METH_VARARGS},
+    {"keys",            (PyCFunction)DB_keys,           METH_VARARGS},
+    {"open",            (PyCFunction)DB_open,           METH_VARARGS|METH_KEYWORDS},
+    {"put",             (PyCFunction)DB_put,            METH_VARARGS|METH_KEYWORDS},
+    {"remove",          (PyCFunction)DB_remove,         METH_VARARGS|METH_KEYWORDS},
+    {"rename",          (PyCFunction)DB_rename,         METH_VARARGS},
+    {"set_bt_minkey",   (PyCFunction)DB_set_bt_minkey,  METH_VARARGS},
+#if (DBVER >= 33)
+    {"set_bt_compare",  (PyCFunction)DB_set_bt_compare, METH_VARARGS},
+#endif
+    {"set_cachesize",   (PyCFunction)DB_set_cachesize,  METH_VARARGS},
+#if (DBVER >= 41)
+    {"set_encrypt",     (PyCFunction)DB_set_encrypt,    METH_VARARGS|METH_KEYWORDS},
+#endif
+    {"set_flags",       (PyCFunction)DB_set_flags,      METH_VARARGS},
+    {"set_h_ffactor",   (PyCFunction)DB_set_h_ffactor,  METH_VARARGS},
+    {"set_h_nelem",     (PyCFunction)DB_set_h_nelem,    METH_VARARGS},
+    {"set_lorder",      (PyCFunction)DB_set_lorder,     METH_VARARGS},
+    {"set_pagesize",    (PyCFunction)DB_set_pagesize,   METH_VARARGS},
+    {"set_re_delim",    (PyCFunction)DB_set_re_delim,   METH_VARARGS},
+    {"set_re_len",      (PyCFunction)DB_set_re_len,     METH_VARARGS},
+    {"set_re_pad",      (PyCFunction)DB_set_re_pad,     METH_VARARGS},
+    {"set_re_source",   (PyCFunction)DB_set_re_source,  METH_VARARGS},
+#if (DBVER >= 32)
+    {"set_q_extentsize",(PyCFunction)DB_set_q_extentsize,METH_VARARGS},
+#endif
+    {"stat",            (PyCFunction)DB_stat,           METH_VARARGS|METH_KEYWORDS},
+    {"sync",            (PyCFunction)DB_sync,           METH_VARARGS},
+#if (DBVER >= 33)
+    {"truncate",        (PyCFunction)DB_truncate,       METH_VARARGS|METH_KEYWORDS},
+#endif
+    {"type",            (PyCFunction)DB_get_type,       METH_VARARGS},
+    {"upgrade",         (PyCFunction)DB_upgrade,        METH_VARARGS},
+    {"values",          (PyCFunction)DB_values,         METH_VARARGS},
+    {"verify",          (PyCFunction)DB_verify,         METH_VARARGS|METH_KEYWORDS},
+    {"set_get_returns_none",(PyCFunction)DB_set_get_returns_none,      METH_VARARGS},
+    {NULL,      NULL}       /* sentinel */
+};
+
+
+static PyMappingMethods DB_mapping = {
+        DB_length,                   /*mp_length*/
+        (binaryfunc)DB_subscript,    /*mp_subscript*/
+        (objobjargproc)DB_ass_sub,   /*mp_ass_subscript*/
+};
+
+
+static PyMethodDef DBCursor_methods[] = {
+    {"close",           (PyCFunction)DBC_close,         METH_VARARGS},
+    {"count",           (PyCFunction)DBC_count,         METH_VARARGS},
+    {"current",         (PyCFunction)DBC_current,       METH_VARARGS|METH_KEYWORDS},
+    {"delete",          (PyCFunction)DBC_delete,        METH_VARARGS},
+    {"dup",             (PyCFunction)DBC_dup,           METH_VARARGS},
+    {"first",           (PyCFunction)DBC_first,         METH_VARARGS|METH_KEYWORDS},
+    {"get",             (PyCFunction)DBC_get,           METH_VARARGS|METH_KEYWORDS},
+#if (DBVER >= 33)
+    {"pget",            (PyCFunction)DBC_pget,          METH_VARARGS|METH_KEYWORDS},
+#endif
+    {"get_recno",       (PyCFunction)DBC_get_recno,     METH_VARARGS},
+    {"last",            (PyCFunction)DBC_last,          METH_VARARGS|METH_KEYWORDS},
+    {"next",            (PyCFunction)DBC_next,          METH_VARARGS|METH_KEYWORDS},
+    {"prev",            (PyCFunction)DBC_prev,          METH_VARARGS|METH_KEYWORDS},
+    {"put",             (PyCFunction)DBC_put,           METH_VARARGS|METH_KEYWORDS},
+    {"set",             (PyCFunction)DBC_set,           METH_VARARGS|METH_KEYWORDS},
+    {"set_range",       (PyCFunction)DBC_set_range,     METH_VARARGS|METH_KEYWORDS},
+    {"get_both",        (PyCFunction)DBC_get_both,      METH_VARARGS},
+    {"get_current_size",(PyCFunction)DBC_get_current_size, METH_VARARGS},
+    {"set_both",        (PyCFunction)DBC_set_both,      METH_VARARGS},
+    {"set_recno",       (PyCFunction)DBC_set_recno,     METH_VARARGS|METH_KEYWORDS},
+    {"consume",         (PyCFunction)DBC_consume,       METH_VARARGS|METH_KEYWORDS},
+    {"next_dup",        (PyCFunction)DBC_next_dup,      METH_VARARGS|METH_KEYWORDS},
+    {"next_nodup",      (PyCFunction)DBC_next_nodup,    METH_VARARGS|METH_KEYWORDS},
+    {"prev_nodup",      (PyCFunction)DBC_prev_nodup,    METH_VARARGS|METH_KEYWORDS},
+    {"join_item",       (PyCFunction)DBC_join_item,     METH_VARARGS},
+    {NULL,      NULL}       /* sentinel */
+};
+
+
+static PyMethodDef DBEnv_methods[] = {
+    {"close",           (PyCFunction)DBEnv_close,            METH_VARARGS},
+    {"open",            (PyCFunction)DBEnv_open,             METH_VARARGS},
+    {"remove",          (PyCFunction)DBEnv_remove,           METH_VARARGS},
+#if (DBVER >= 41)
+    {"dbremove",        (PyCFunction)DBEnv_dbremove,         METH_VARARGS|METH_KEYWORDS},
+    {"dbrename",        (PyCFunction)DBEnv_dbrename,         METH_VARARGS|METH_KEYWORDS},
+    {"set_encrypt",     (PyCFunction)DBEnv_set_encrypt,      METH_VARARGS|METH_KEYWORDS},
+#endif
+#if (DBVER >= 40)
+    {"set_timeout",     (PyCFunction)DBEnv_set_timeout,      METH_VARARGS|METH_KEYWORDS},
+#endif
+    {"set_shm_key",     (PyCFunction)DBEnv_set_shm_key,      METH_VARARGS},
+    {"set_cachesize",   (PyCFunction)DBEnv_set_cachesize,    METH_VARARGS},
+    {"set_data_dir",    (PyCFunction)DBEnv_set_data_dir,     METH_VARARGS},
+#if (DBVER >= 32)
+    {"set_flags",       (PyCFunction)DBEnv_set_flags,        METH_VARARGS},
+#endif
+    {"set_lg_bsize",    (PyCFunction)DBEnv_set_lg_bsize,     METH_VARARGS},
+    {"set_lg_dir",      (PyCFunction)DBEnv_set_lg_dir,       METH_VARARGS},
+    {"set_lg_max",      (PyCFunction)DBEnv_set_lg_max,       METH_VARARGS},
+#if (DBVER >= 33)
+    {"set_lg_regionmax",(PyCFunction)DBEnv_set_lg_regionmax, METH_VARARGS},
+#endif
+    {"set_lk_detect",   (PyCFunction)DBEnv_set_lk_detect,    METH_VARARGS},
+#if (DBVER < 45)
+    {"set_lk_max",      (PyCFunction)DBEnv_set_lk_max,       METH_VARARGS},
+#endif
+#if (DBVER >= 32)
+    {"set_lk_max_locks", (PyCFunction)DBEnv_set_lk_max_locks, METH_VARARGS},
+    {"set_lk_max_lockers", (PyCFunction)DBEnv_set_lk_max_lockers, METH_VARARGS},
+    {"set_lk_max_objects", (PyCFunction)DBEnv_set_lk_max_objects, METH_VARARGS},
+#endif
+    {"set_mp_mmapsize", (PyCFunction)DBEnv_set_mp_mmapsize,  METH_VARARGS},
+    {"set_tmp_dir",     (PyCFunction)DBEnv_set_tmp_dir,      METH_VARARGS},
+    {"txn_begin",       (PyCFunction)DBEnv_txn_begin,        METH_VARARGS|METH_KEYWORDS},
+    {"txn_checkpoint",  (PyCFunction)DBEnv_txn_checkpoint,   METH_VARARGS},
+    {"txn_stat",        (PyCFunction)DBEnv_txn_stat,         METH_VARARGS},
+    {"set_tx_max",      (PyCFunction)DBEnv_set_tx_max,       METH_VARARGS},
+    {"set_tx_timestamp", (PyCFunction)DBEnv_set_tx_timestamp, METH_VARARGS},
+    {"lock_detect",     (PyCFunction)DBEnv_lock_detect,      METH_VARARGS},
+    {"lock_get",        (PyCFunction)DBEnv_lock_get,         METH_VARARGS},
+    {"lock_id",         (PyCFunction)DBEnv_lock_id,          METH_VARARGS},
+    {"lock_put",        (PyCFunction)DBEnv_lock_put,         METH_VARARGS},
+    {"lock_stat",       (PyCFunction)DBEnv_lock_stat,        METH_VARARGS},
+    {"log_archive",     (PyCFunction)DBEnv_log_archive,      METH_VARARGS},
+#if (DBVER >= 40)
+    {"log_stat",        (PyCFunction)DBEnv_log_stat,         METH_VARARGS},
+#endif
+#if (DBVER >= 44)
+    {"lsn_reset",       (PyCFunction)DBEnv_lsn_reset,        METH_VARARGS|METH_KEYWORDS},
+#endif
+    {"set_get_returns_none",(PyCFunction)DBEnv_set_get_returns_none, METH_VARARGS},
+    {NULL,      NULL}       /* sentinel */
+};
+
+
+static PyMethodDef DBTxn_methods[] = {
+    {"commit",          (PyCFunction)DBTxn_commit,      METH_VARARGS},
+    {"prepare",         (PyCFunction)DBTxn_prepare,     METH_VARARGS},
+    {"abort",           (PyCFunction)DBTxn_abort,       METH_VARARGS},
+    {"id",              (PyCFunction)DBTxn_id,          METH_VARARGS},
+    {NULL,      NULL}       /* sentinel */
+};
+
+
+#if (DBVER >= 43)
+static PyMethodDef DBSequence_methods[] = {
+    {"close",           (PyCFunction)DBSequence_close,          METH_VARARGS},
+    {"get",             (PyCFunction)DBSequence_get,            METH_VARARGS|METH_KEYWORDS},
+    {"get_dbp",         (PyCFunction)DBSequence_get_dbp,        METH_VARARGS},
+    {"get_key",         (PyCFunction)DBSequence_get_key,        METH_VARARGS},
+    {"init_value",      (PyCFunction)DBSequence_init_value,     METH_VARARGS},
+    {"open",            (PyCFunction)DBSequence_open,           METH_VARARGS|METH_KEYWORDS},
+    {"remove",          (PyCFunction)DBSequence_remove,         METH_VARARGS|METH_KEYWORDS},
+    {"set_cachesize",   (PyCFunction)DBSequence_set_cachesize,  METH_VARARGS},
+    {"get_cachesize",   (PyCFunction)DBSequence_get_cachesize,  METH_VARARGS},
+    {"set_flags",       (PyCFunction)DBSequence_set_flags,      METH_VARARGS},
+    {"get_flags",       (PyCFunction)DBSequence_get_flags,      METH_VARARGS},
+    {"set_range",       (PyCFunction)DBSequence_set_range,      METH_VARARGS},
+    {"get_range",       (PyCFunction)DBSequence_get_range,      METH_VARARGS},
+    {"stat",            (PyCFunction)DBSequence_stat,           METH_VARARGS|METH_KEYWORDS},
+    {NULL,      NULL}       /* sentinel */
+};
+#endif
+
+
+static PyObject*
+DB_getattr(DBObject* self, char *name)
+{
+    return Py_FindMethod(DB_methods, (PyObject* )self, name);
+}
+
+
+static PyObject*
+DBEnv_getattr(DBEnvObject* self, char *name)
+{
+    if (!strcmp(name, "db_home")) {
+        CHECK_ENV_NOT_CLOSED(self);
+        if (self->db_env->db_home == NULL) {
+            RETURN_NONE();
+        }
+        return PyString_FromString(self->db_env->db_home);
+    }
+
+    return Py_FindMethod(DBEnv_methods, (PyObject* )self, name);
+}
+
+
+static PyObject*
+DBCursor_getattr(DBCursorObject* self, char *name)
+{
+    return Py_FindMethod(DBCursor_methods, (PyObject* )self, name);
+}
+
+static PyObject*
+DBTxn_getattr(DBTxnObject* self, char *name)
+{
+    return Py_FindMethod(DBTxn_methods, (PyObject* )self, name);
+}
+
+static PyObject*
+DBLock_getattr(DBLockObject* self, char *name)
+{
+    return NULL;
+}
+
+#if (DBVER >= 43)
+static PyObject*
+DBSequence_getattr(DBSequenceObject* self, char *name)
+{
+    return Py_FindMethod(DBSequence_methods, (PyObject* )self, name);
+}
+#endif
+
+statichere PyTypeObject DB_Type = {
+    PyObject_HEAD_INIT(NULL)
+    0,                  /*ob_size*/
+    "DB",               /*tp_name*/
+    sizeof(DBObject),   /*tp_basicsize*/
+    0,                  /*tp_itemsize*/
+    /* methods */
+    (destructor)DB_dealloc, /*tp_dealloc*/
+    0,                  /*tp_print*/
+    (getattrfunc)DB_getattr, /*tp_getattr*/
+    0,                      /*tp_setattr*/
+    0,          /*tp_compare*/
+    0,          /*tp_repr*/
+    0,          /*tp_as_number*/
+    0,          /*tp_as_sequence*/
+    &DB_mapping,/*tp_as_mapping*/
+    0,          /*tp_hash*/
+#ifdef HAVE_WEAKREF
+    0,			/* tp_call */
+    0,			/* tp_str */
+    0,  		/* tp_getattro */
+    0,                  /* tp_setattro */
+    0,			/* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS,      /* tp_flags */
+    0,                  /* tp_doc */
+    0,		        /* tp_traverse */
+    0,			/* tp_clear */
+    0,			/* tp_richcompare */
+    offsetof(DBObject, in_weakreflist),   /* tp_weaklistoffset */
+#endif
+};
+
+
+statichere PyTypeObject DBCursor_Type = {
+    PyObject_HEAD_INIT(NULL)
+    0,                  /*ob_size*/
+    "DBCursor",         /*tp_name*/
+    sizeof(DBCursorObject),  /*tp_basicsize*/
+    0,                  /*tp_itemsize*/
+    /* methods */
+    (destructor)DBCursor_dealloc,/*tp_dealloc*/
+    0,                  /*tp_print*/
+    (getattrfunc)DBCursor_getattr, /*tp_getattr*/
+    0,                  /*tp_setattr*/
+    0,                  /*tp_compare*/
+    0,                  /*tp_repr*/
+    0,                  /*tp_as_number*/
+    0,                  /*tp_as_sequence*/
+    0,                  /*tp_as_mapping*/
+    0,                  /*tp_hash*/
+#ifdef HAVE_WEAKREF
+    0,			/* tp_call */
+    0,			/* tp_str */
+    0,  		/* tp_getattro */
+    0,                  /* tp_setattro */
+    0,			/* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS,      /* tp_flags */
+    0,                  /* tp_doc */
+    0,		        /* tp_traverse */
+    0,			/* tp_clear */
+    0,			/* tp_richcompare */
+    offsetof(DBCursorObject, in_weakreflist),   /* tp_weaklistoffset */
+#endif
+};
+
+
+statichere PyTypeObject DBEnv_Type = {
+    PyObject_HEAD_INIT(NULL)
+    0,          /*ob_size*/
+    "DBEnv",            /*tp_name*/
+    sizeof(DBEnvObject),    /*tp_basicsize*/
+    0,          /*tp_itemsize*/
+    /* methods */
+    (destructor)DBEnv_dealloc, /*tp_dealloc*/
+    0,          /*tp_print*/
+    (getattrfunc)DBEnv_getattr, /*tp_getattr*/
+    0,          /*tp_setattr*/
+    0,          /*tp_compare*/
+    0,          /*tp_repr*/
+    0,          /*tp_as_number*/
+    0,          /*tp_as_sequence*/
+    0,          /*tp_as_mapping*/
+    0,          /*tp_hash*/
+#ifdef HAVE_WEAKREF
+    0,			/* tp_call */
+    0,			/* tp_str */
+    0,  		/* tp_getattro */
+    0,                  /* tp_setattro */
+    0,			/* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS,      /* tp_flags */
+    0,                  /* tp_doc */
+    0,		        /* tp_traverse */
+    0,			/* tp_clear */
+    0,			/* tp_richcompare */
+    offsetof(DBEnvObject, in_weakreflist),   /* tp_weaklistoffset */
+#endif
+};
+
+statichere PyTypeObject DBTxn_Type = {
+    PyObject_HEAD_INIT(NULL)
+    0,          /*ob_size*/
+    "DBTxn",    /*tp_name*/
+    sizeof(DBTxnObject),  /*tp_basicsize*/
+    0,          /*tp_itemsize*/
+    /* methods */
+    (destructor)DBTxn_dealloc, /*tp_dealloc*/
+    0,          /*tp_print*/
+    (getattrfunc)DBTxn_getattr, /*tp_getattr*/
+    0,                      /*tp_setattr*/
+    0,          /*tp_compare*/
+    0,          /*tp_repr*/
+    0,          /*tp_as_number*/
+    0,          /*tp_as_sequence*/
+    0,          /*tp_as_mapping*/
+    0,          /*tp_hash*/
+#ifdef HAVE_WEAKREF
+    0,			/* tp_call */
+    0,			/* tp_str */
+    0,  		/* tp_getattro */
+    0,                  /* tp_setattro */
+    0,			/* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS,      /* tp_flags */
+    0,                  /* tp_doc */
+    0,		        /* tp_traverse */
+    0,			/* tp_clear */
+    0,			/* tp_richcompare */
+    offsetof(DBTxnObject, in_weakreflist),   /* tp_weaklistoffset */
+#endif
+};
+
+
+statichere PyTypeObject DBLock_Type = {
+    PyObject_HEAD_INIT(NULL)
+    0,          /*ob_size*/
+    "DBLock",   /*tp_name*/
+    sizeof(DBLockObject),  /*tp_basicsize*/
+    0,          /*tp_itemsize*/
+    /* methods */
+    (destructor)DBLock_dealloc, /*tp_dealloc*/
+    0,          /*tp_print*/
+    (getattrfunc)DBLock_getattr, /*tp_getattr*/
+    0,                      /*tp_setattr*/
+    0,          /*tp_compare*/
+    0,          /*tp_repr*/
+    0,          /*tp_as_number*/
+    0,          /*tp_as_sequence*/
+    0,          /*tp_as_mapping*/
+    0,          /*tp_hash*/
+#ifdef HAVE_WEAKREF
+    0,			/* tp_call */
+    0,			/* tp_str */
+    0,  		/* tp_getattro */
+    0,                  /* tp_setattro */
+    0,			/* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS,      /* tp_flags */
+    0,                  /* tp_doc */
+    0,		        /* tp_traverse */
+    0,			/* tp_clear */
+    0,			/* tp_richcompare */
+    offsetof(DBLockObject, in_weakreflist),   /* tp_weaklistoffset */
+#endif
+};
+
+#if (DBVER >= 43)
+statichere PyTypeObject DBSequence_Type = {
+    PyObject_HEAD_INIT(NULL)
+    0,          /*ob_size*/
+    "DBSequence",                   /*tp_name*/
+    sizeof(DBSequenceObject),       /*tp_basicsize*/
+    0,          /*tp_itemsize*/
+    /* methods */
+    (destructor)DBSequence_dealloc, /*tp_dealloc*/
+    0,          /*tp_print*/
+    (getattrfunc)DBSequence_getattr,/*tp_getattr*/
+    0,          /*tp_setattr*/
+    0,          /*tp_compare*/
+    0,          /*tp_repr*/
+    0,          /*tp_as_number*/
+    0,          /*tp_as_sequence*/
+    0,          /*tp_as_mapping*/
+    0,          /*tp_hash*/
+#ifdef HAVE_WEAKREF
+    0,			/* tp_call */
+    0,			/* tp_str */
+    0,  		/* tp_getattro */
+    0,          /* tp_setattro */
+    0,			/* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS,      /* tp_flags */
+    0,          /* tp_doc */
+    0,		    /* tp_traverse */
+    0,			/* tp_clear */
+    0,			/* tp_richcompare */
+    offsetof(DBSequenceObject, in_weakreflist),   /* tp_weaklistoffset */
+#endif
+};
+#endif
+
+/* --------------------------------------------------------------------- */
+/* Module-level functions */
+
+static PyObject*
+DB_construct(PyObject* self, PyObject* args, PyObject* kwargs)
+{
+    PyObject* dbenvobj = NULL;
+    int flags = 0;
+    static char* kwnames[] = { "dbEnv", "flags", NULL};
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:DB", kwnames,
+                                     &dbenvobj, &flags))
+        return NULL;
+    if (dbenvobj == Py_None)
+        dbenvobj = NULL;
+    else if (dbenvobj && !DBEnvObject_Check(dbenvobj)) {
+        makeTypeError("DBEnv", dbenvobj);
+        return NULL;
+    }
+
+    return (PyObject* )newDBObject((DBEnvObject*)dbenvobj, flags);
+}
+
+
+static PyObject*
+DBEnv_construct(PyObject* self, PyObject* args)
+{
+    int flags = 0;
+    if (!PyArg_ParseTuple(args, "|i:DbEnv", &flags)) return NULL;
+    return (PyObject* )newDBEnvObject(flags);
+}
+
+#if (DBVER >= 43)
+static PyObject*
+DBSequence_construct(PyObject* self, PyObject* args, PyObject* kwargs)
+{
+    PyObject* dbobj;
+    int flags = 0;
+    static char* kwnames[] = { "db", "flags", NULL};
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|i:DBSequence", kwnames, &dbobj, &flags))
+        return NULL;
+    if (!DBObject_Check(dbobj)) {
+        makeTypeError("DB", dbobj);
+        return NULL;
+    }
+    return (PyObject* )newDBSequenceObject((DBObject*)dbobj, flags);
+}
+#endif
+
+static char bsddb_version_doc[] =
+"Returns a tuple of major, minor, and patch release numbers of the\n\
+underlying DB library.";
+
+static PyObject*
+bsddb_version(PyObject* self, PyObject* args)
+{
+    int major, minor, patch;
+
+        if (!PyArg_ParseTuple(args, ":version"))
+        return NULL;
+        db_version(&major, &minor, &patch);
+        return Py_BuildValue("(iii)", major, minor, patch);
+}
+
+
+/* List of functions defined in the module */
+
+static PyMethodDef bsddb_methods[] = {
+    {"DB",          (PyCFunction)DB_construct,          METH_VARARGS | METH_KEYWORDS },
+    {"DBEnv",       (PyCFunction)DBEnv_construct,       METH_VARARGS},
+#if (DBVER >= 43)    
+    {"DBSequence",  (PyCFunction)DBSequence_construct,  METH_VARARGS | METH_KEYWORDS },
+#endif    
+    {"version",     (PyCFunction)bsddb_version,         METH_VARARGS, bsddb_version_doc},
+    {NULL,      NULL}       /* sentinel */
+};
+
+
+/* --------------------------------------------------------------------- */
+/* Module initialization */
+
+
+/* Convenience routine to export an integer value.
+ * Errors are silently ignored, for better or for worse...
+ */
+#define ADD_INT(dict, NAME)         _addIntToDict(dict, #NAME, NAME)
+
+#define MODULE_NAME_MAX_LEN     11
+static char _bsddbModuleName[MODULE_NAME_MAX_LEN+1] = "_bsddb";
+
+DL_EXPORT(void) init_bsddb(void)
+{
+    PyObject* m;
+    PyObject* d;
+    PyObject* pybsddb_version_s = PyString_FromString( PY_BSDDB_VERSION );
+    PyObject* db_version_s = PyString_FromString( DB_VERSION_STRING );
+    PyObject* cvsid_s = PyString_FromString( rcs_id );
+
+    /* Initialize the type of the new type objects here; doing it here
+       is required for portability to Windows without requiring C++. */
+    DB_Type.ob_type = &PyType_Type;
+    DBCursor_Type.ob_type = &PyType_Type;
+    DBEnv_Type.ob_type = &PyType_Type;
+    DBTxn_Type.ob_type = &PyType_Type;
+    DBLock_Type.ob_type = &PyType_Type;
+#if (DBVER >= 43)    
+    DBSequence_Type.ob_type = &PyType_Type;
+#endif    
+
+
+#if defined(WITH_THREAD) && !defined(MYDB_USE_GILSTATE)
+    /* Save the current interpreter, so callbacks can do the right thing. */
+    _db_interpreterState = PyThreadState_GET()->interp;
+#endif
+
+    /* Create the module and add the functions */
+    m = Py_InitModule(_bsddbModuleName, bsddb_methods);
+    if (m == NULL)
+    	return;
+
+    /* Add some symbolic constants to the module */
+    d = PyModule_GetDict(m);
+    PyDict_SetItemString(d, "__version__", pybsddb_version_s);
+    PyDict_SetItemString(d, "cvsid", cvsid_s);
+    PyDict_SetItemString(d, "DB_VERSION_STRING", db_version_s);
+    Py_DECREF(pybsddb_version_s);
+    pybsddb_version_s = NULL;
+    Py_DECREF(cvsid_s);
+    cvsid_s = NULL;
+    Py_DECREF(db_version_s);
+    db_version_s = NULL;
+
+    ADD_INT(d, DB_VERSION_MAJOR);
+    ADD_INT(d, DB_VERSION_MINOR);
+    ADD_INT(d, DB_VERSION_PATCH);
+
+    ADD_INT(d, DB_MAX_PAGES);
+    ADD_INT(d, DB_MAX_RECORDS);
+
+#if (DBVER >= 42)
+    ADD_INT(d, DB_RPCCLIENT);
+#else
+    ADD_INT(d, DB_CLIENT);
+    /* allow apps to be written using DB_RPCCLIENT on older BerkeleyDB */
+    _addIntToDict(d, "DB_RPCCLIENT", DB_CLIENT);
+#endif
+    ADD_INT(d, DB_XA_CREATE);
+
+    ADD_INT(d, DB_CREATE);
+    ADD_INT(d, DB_NOMMAP);
+    ADD_INT(d, DB_THREAD);
+
+    ADD_INT(d, DB_FORCE);
+    ADD_INT(d, DB_INIT_CDB);
+    ADD_INT(d, DB_INIT_LOCK);
+    ADD_INT(d, DB_INIT_LOG);
+    ADD_INT(d, DB_INIT_MPOOL);
+    ADD_INT(d, DB_INIT_TXN);
+#if (DBVER >= 32)
+    ADD_INT(d, DB_JOINENV);
+#endif
+
+    ADD_INT(d, DB_RECOVER);
+    ADD_INT(d, DB_RECOVER_FATAL);
+    ADD_INT(d, DB_TXN_NOSYNC);
+    ADD_INT(d, DB_USE_ENVIRON);
+    ADD_INT(d, DB_USE_ENVIRON_ROOT);
+
+    ADD_INT(d, DB_LOCKDOWN);
+    ADD_INT(d, DB_PRIVATE);
+    ADD_INT(d, DB_SYSTEM_MEM);
+
+    ADD_INT(d, DB_TXN_SYNC);
+    ADD_INT(d, DB_TXN_NOWAIT);
+
+    ADD_INT(d, DB_EXCL);
+    ADD_INT(d, DB_FCNTL_LOCKING);
+    ADD_INT(d, DB_ODDFILESIZE);
+    ADD_INT(d, DB_RDWRMASTER);
+    ADD_INT(d, DB_RDONLY);
+    ADD_INT(d, DB_TRUNCATE);
+#if (DBVER >= 32)
+    ADD_INT(d, DB_EXTENT);
+    ADD_INT(d, DB_CDB_ALLDB);
+    ADD_INT(d, DB_VERIFY);
+#endif
+    ADD_INT(d, DB_UPGRADE);
+
+    ADD_INT(d, DB_AGGRESSIVE);
+    ADD_INT(d, DB_NOORDERCHK);
+    ADD_INT(d, DB_ORDERCHKONLY);
+    ADD_INT(d, DB_PR_PAGE);
+#if ! (DBVER >= 33)
+    ADD_INT(d, DB_VRFY_FLAGMASK);
+    ADD_INT(d, DB_PR_HEADERS);
+#endif
+    ADD_INT(d, DB_PR_RECOVERYTEST);
+    ADD_INT(d, DB_SALVAGE);
+
+    ADD_INT(d, DB_LOCK_NORUN);
+    ADD_INT(d, DB_LOCK_DEFAULT);
+    ADD_INT(d, DB_LOCK_OLDEST);
+    ADD_INT(d, DB_LOCK_RANDOM);
+    ADD_INT(d, DB_LOCK_YOUNGEST);
+#if (DBVER >= 33)
+    ADD_INT(d, DB_LOCK_MAXLOCKS);
+    ADD_INT(d, DB_LOCK_MINLOCKS);
+    ADD_INT(d, DB_LOCK_MINWRITE);
+#endif
+
+
+#if (DBVER >= 33)
+    /* docs say to use zero instead */
+    _addIntToDict(d, "DB_LOCK_CONFLICT", 0);
+#else
+    ADD_INT(d, DB_LOCK_CONFLICT);
+#endif
+
+    ADD_INT(d, DB_LOCK_DUMP);
+    ADD_INT(d, DB_LOCK_GET);
+    ADD_INT(d, DB_LOCK_INHERIT);
+    ADD_INT(d, DB_LOCK_PUT);
+    ADD_INT(d, DB_LOCK_PUT_ALL);
+    ADD_INT(d, DB_LOCK_PUT_OBJ);
+
+    ADD_INT(d, DB_LOCK_NG);
+    ADD_INT(d, DB_LOCK_READ);
+    ADD_INT(d, DB_LOCK_WRITE);
+    ADD_INT(d, DB_LOCK_NOWAIT);
+#if (DBVER >= 32)
+    ADD_INT(d, DB_LOCK_WAIT);
+#endif
+    ADD_INT(d, DB_LOCK_IWRITE);
+    ADD_INT(d, DB_LOCK_IREAD);
+    ADD_INT(d, DB_LOCK_IWR);
+#if (DBVER >= 33)
+#if (DBVER < 44)
+    ADD_INT(d, DB_LOCK_DIRTY);
+#else
+    ADD_INT(d, DB_LOCK_READ_UNCOMMITTED);  /* renamed in 4.4 */
+#endif
+    ADD_INT(d, DB_LOCK_WWRITE);
+#endif
+
+    ADD_INT(d, DB_LOCK_RECORD);
+    ADD_INT(d, DB_LOCK_UPGRADE);
+#if (DBVER >= 32)
+    ADD_INT(d, DB_LOCK_SWITCH);
+#endif
+#if (DBVER >= 33)
+    ADD_INT(d, DB_LOCK_UPGRADE_WRITE);
+#endif
+
+    ADD_INT(d, DB_LOCK_NOWAIT);
+    ADD_INT(d, DB_LOCK_RECORD);
+    ADD_INT(d, DB_LOCK_UPGRADE);
+
+#if (DBVER >= 33)
+    ADD_INT(d, DB_LSTAT_ABORTED);
+#if (DBVER < 43)
+    ADD_INT(d, DB_LSTAT_ERR);
+#endif
+    ADD_INT(d, DB_LSTAT_FREE);
+    ADD_INT(d, DB_LSTAT_HELD);
+#if (DBVER == 33)
+    ADD_INT(d, DB_LSTAT_NOGRANT);
+#endif
+    ADD_INT(d, DB_LSTAT_PENDING);
+    ADD_INT(d, DB_LSTAT_WAITING);
+#endif
+
+    ADD_INT(d, DB_ARCH_ABS);
+    ADD_INT(d, DB_ARCH_DATA);
+    ADD_INT(d, DB_ARCH_LOG);
+#if (DBVER >= 42)
+    ADD_INT(d, DB_ARCH_REMOVE);
+#endif
+
+    ADD_INT(d, DB_BTREE);
+    ADD_INT(d, DB_HASH);
+    ADD_INT(d, DB_RECNO);
+    ADD_INT(d, DB_QUEUE);
+    ADD_INT(d, DB_UNKNOWN);
+
+    ADD_INT(d, DB_DUP);
+    ADD_INT(d, DB_DUPSORT);
+    ADD_INT(d, DB_RECNUM);
+    ADD_INT(d, DB_RENUMBER);
+    ADD_INT(d, DB_REVSPLITOFF);
+    ADD_INT(d, DB_SNAPSHOT);
+
+    ADD_INT(d, DB_JOIN_NOSORT);
+
+    ADD_INT(d, DB_AFTER);
+    ADD_INT(d, DB_APPEND);
+    ADD_INT(d, DB_BEFORE);
+#if (DBVER < 45)
+    ADD_INT(d, DB_CACHED_COUNTS);
+#endif
+#if (DBVER >= 41)
+    _addIntToDict(d, "DB_CHECKPOINT", 0);
+#else
+    ADD_INT(d, DB_CHECKPOINT);
+    ADD_INT(d, DB_CURLSN);
+#endif
+#if ((DBVER >= 33) && (DBVER <= 41))
+    ADD_INT(d, DB_COMMIT);
+#endif
+    ADD_INT(d, DB_CONSUME);
+#if (DBVER >= 32)
+    ADD_INT(d, DB_CONSUME_WAIT);
+#endif
+    ADD_INT(d, DB_CURRENT);
+#if (DBVER >= 33)
+    ADD_INT(d, DB_FAST_STAT);
+#endif
+    ADD_INT(d, DB_FIRST);
+    ADD_INT(d, DB_FLUSH);
+    ADD_INT(d, DB_GET_BOTH);
+    ADD_INT(d, DB_GET_RECNO);
+    ADD_INT(d, DB_JOIN_ITEM);
+    ADD_INT(d, DB_KEYFIRST);
+    ADD_INT(d, DB_KEYLAST);
+    ADD_INT(d, DB_LAST);
+    ADD_INT(d, DB_NEXT);
+    ADD_INT(d, DB_NEXT_DUP);
+    ADD_INT(d, DB_NEXT_NODUP);
+    ADD_INT(d, DB_NODUPDATA);
+    ADD_INT(d, DB_NOOVERWRITE);
+    ADD_INT(d, DB_NOSYNC);
+    ADD_INT(d, DB_POSITION);
+    ADD_INT(d, DB_PREV);
+    ADD_INT(d, DB_PREV_NODUP);
+#if (DBVER < 45)
+    ADD_INT(d, DB_RECORDCOUNT);
+#endif
+    ADD_INT(d, DB_SET);
+    ADD_INT(d, DB_SET_RANGE);
+    ADD_INT(d, DB_SET_RECNO);
+    ADD_INT(d, DB_WRITECURSOR);
+
+    ADD_INT(d, DB_OPFLAGS_MASK);
+    ADD_INT(d, DB_RMW);
+#if (DBVER >= 33)
+    ADD_INT(d, DB_DIRTY_READ);
+    ADD_INT(d, DB_MULTIPLE);
+    ADD_INT(d, DB_MULTIPLE_KEY);
+#endif
+
+#if (DBVER >= 44)
+    ADD_INT(d, DB_READ_UNCOMMITTED);    /* replaces DB_DIRTY_READ in 4.4 */
+    ADD_INT(d, DB_READ_COMMITTED);
+#endif
+
+#if (DBVER >= 33)
+    ADD_INT(d, DB_DONOTINDEX);
+#endif
+
+#if (DBVER >= 41)
+    _addIntToDict(d, "DB_INCOMPLETE", 0);
+#else
+    ADD_INT(d, DB_INCOMPLETE);
+#endif
+    ADD_INT(d, DB_KEYEMPTY);
+    ADD_INT(d, DB_KEYEXIST);
+    ADD_INT(d, DB_LOCK_DEADLOCK);
+    ADD_INT(d, DB_LOCK_NOTGRANTED);
+    ADD_INT(d, DB_NOSERVER);
+    ADD_INT(d, DB_NOSERVER_HOME);
+    ADD_INT(d, DB_NOSERVER_ID);
+    ADD_INT(d, DB_NOTFOUND);
+    ADD_INT(d, DB_OLD_VERSION);
+    ADD_INT(d, DB_RUNRECOVERY);
+    ADD_INT(d, DB_VERIFY_BAD);
+#if (DBVER >= 33)
+    ADD_INT(d, DB_PAGE_NOTFOUND);
+    ADD_INT(d, DB_SECONDARY_BAD);
+#endif
+#if (DBVER >= 40)
+    ADD_INT(d, DB_STAT_CLEAR);
+    ADD_INT(d, DB_REGION_INIT);
+    ADD_INT(d, DB_NOLOCKING);
+    ADD_INT(d, DB_YIELDCPU);
+    ADD_INT(d, DB_PANIC_ENVIRONMENT);
+    ADD_INT(d, DB_NOPANIC);
+#endif
+
+#if (DBVER >= 42)
+    ADD_INT(d, DB_TIME_NOTGRANTED);
+    ADD_INT(d, DB_TXN_NOT_DURABLE);
+    ADD_INT(d, DB_TXN_WRITE_NOSYNC);
+    ADD_INT(d, DB_LOG_AUTOREMOVE);
+    ADD_INT(d, DB_DIRECT_LOG);
+    ADD_INT(d, DB_DIRECT_DB);
+    ADD_INT(d, DB_INIT_REP);
+    ADD_INT(d, DB_ENCRYPT);
+    ADD_INT(d, DB_CHKSUM);
+#endif
+
+#if (DBVER >= 43)
+    ADD_INT(d, DB_LOG_INMEMORY);
+    ADD_INT(d, DB_BUFFER_SMALL);
+    ADD_INT(d, DB_SEQ_DEC);
+    ADD_INT(d, DB_SEQ_INC);
+    ADD_INT(d, DB_SEQ_WRAP);
+#endif
+
+#if (DBVER >= 41)
+    ADD_INT(d, DB_ENCRYPT_AES);
+    ADD_INT(d, DB_AUTO_COMMIT);
+#else
+    /* allow berkeleydb 4.1 aware apps to run on older versions */
+    _addIntToDict(d, "DB_AUTO_COMMIT", 0);
+#endif
+
+    ADD_INT(d, EINVAL);
+    ADD_INT(d, EACCES);
+    ADD_INT(d, ENOSPC);
+    ADD_INT(d, ENOMEM);
+    ADD_INT(d, EAGAIN);
+    ADD_INT(d, EBUSY);
+    ADD_INT(d, EEXIST);
+    ADD_INT(d, ENOENT);
+    ADD_INT(d, EPERM);
+
+#if (DBVER >= 40)
+    ADD_INT(d, DB_SET_LOCK_TIMEOUT);
+    ADD_INT(d, DB_SET_TXN_TIMEOUT);
+#endif
+
+    /* The exception name must be correct for pickled exception *
+     * objects to unpickle properly.                            */
+#ifdef PYBSDDB_STANDALONE  /* different value needed for standalone pybsddb */
+#define PYBSDDB_EXCEPTION_BASE  "bsddb3.db."
+#else
+#define PYBSDDB_EXCEPTION_BASE  "bsddb.db."
+#endif
+
+    /* All the rest of the exceptions derive only from DBError */
+#define MAKE_EX(name)   name = PyErr_NewException(PYBSDDB_EXCEPTION_BASE #name, DBError, NULL); \
+                        PyDict_SetItemString(d, #name, name)
+
+    /* The base exception class is DBError */
+    DBError = NULL;     /* used in MAKE_EX so that it derives from nothing */
+    MAKE_EX(DBError);
+
+    /* Some magic to make DBNotFoundError and DBKeyEmptyError derive
+     * from both DBError and KeyError, since the API only supports
+     * using one base class. */
+    PyDict_SetItemString(d, "KeyError", PyExc_KeyError);
+    PyRun_String("class DBNotFoundError(DBError, KeyError): pass\n"
+	         "class DBKeyEmptyError(DBError, KeyError): pass",
+                 Py_file_input, d, d);
+    DBNotFoundError = PyDict_GetItemString(d, "DBNotFoundError");
+    DBKeyEmptyError = PyDict_GetItemString(d, "DBKeyEmptyError");
+    PyDict_DelItemString(d, "KeyError");
+
+
+#if !INCOMPLETE_IS_WARNING
+    MAKE_EX(DBIncompleteError);
+#endif
+    MAKE_EX(DBCursorClosedError);
+    MAKE_EX(DBKeyEmptyError);
+    MAKE_EX(DBKeyExistError);
+    MAKE_EX(DBLockDeadlockError);
+    MAKE_EX(DBLockNotGrantedError);
+    MAKE_EX(DBOldVersionError);
+    MAKE_EX(DBRunRecoveryError);
+    MAKE_EX(DBVerifyBadError);
+    MAKE_EX(DBNoServerError);
+    MAKE_EX(DBNoServerHomeError);
+    MAKE_EX(DBNoServerIDError);
+#if (DBVER >= 33)
+    MAKE_EX(DBPageNotFoundError);
+    MAKE_EX(DBSecondaryBadError);
+#endif
+
+    MAKE_EX(DBInvalidArgError);
+    MAKE_EX(DBAccessError);
+    MAKE_EX(DBNoSpaceError);
+    MAKE_EX(DBNoMemoryError);
+    MAKE_EX(DBAgainError);
+    MAKE_EX(DBBusyError);
+    MAKE_EX(DBFileExistsError);
+    MAKE_EX(DBNoSuchFileError);
+    MAKE_EX(DBPermissionsError);
+
+#undef MAKE_EX
+
+    /* Check for errors */
+    if (PyErr_Occurred()) {
+        PyErr_Print();
+        Py_FatalError("can't initialize module _bsddb");
+    }
+}
+
+/* allow this module to be named _pybsddb so that it can be installed
+ * and imported on top of python >= 2.3 that includes its own older
+ * copy of the library named _bsddb without importing the old version. */
+DL_EXPORT(void) init_pybsddb(void)
+{
+    strncpy(_bsddbModuleName, "_pybsddb", MODULE_NAME_MAX_LEN);
+    init_bsddb();
+}

Added: vendor/Python/current/Modules/_codecsmodule.c
===================================================================
--- vendor/Python/current/Modules/_codecsmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_codecsmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,934 @@
+/* ------------------------------------------------------------------------
+
+   _codecs -- Provides access to the codec registry and the builtin
+              codecs.
+
+   This module should never be imported directly. The standard library
+   module "codecs" wraps this builtin module for use within Python.
+
+   The codec registry is accessible via:
+
+     register(search_function) -> None
+
+     lookup(encoding) -> (encoder, decoder, stream_reader, stream_writer)
+
+   The builtin Unicode codecs use the following interface:
+
+     <encoding>_encode(Unicode_object[,errors='strict']) ->
+     	(string object, bytes consumed)
+
+     <encoding>_decode(char_buffer_obj[,errors='strict']) ->
+        (Unicode object, bytes consumed)
+
+   <encoding>_encode() interfaces also accept non-Unicode object as
+   input. The objects are then converted to Unicode using
+   PyUnicode_FromObject() prior to applying the conversion.
+
+   These <encoding>s are available: utf_8, unicode_escape,
+   raw_unicode_escape, unicode_internal, latin_1, ascii (7-bit),
+   mbcs (on win32).
+
+
+Written by Marc-Andre Lemburg (mal at lemburg.com).
+
+Copyright (c) Corporation for National Research Initiatives.
+
+   ------------------------------------------------------------------------ */
+
+#define PY_SSIZE_T_CLEAN
+#include "Python.h"
+
+/* --- Registry ----------------------------------------------------------- */
+
+PyDoc_STRVAR(register__doc__,
+"register(search_function)\n\
+\n\
+Register a codec search function. Search functions are expected to take\n\
+one argument, the encoding name in all lower case letters, and return\n\
+a tuple of functions (encoder, decoder, stream_reader, stream_writer).");
+
+static
+PyObject *codec_register(PyObject *self, PyObject *search_function)
+{
+    if (PyCodec_Register(search_function))
+        return NULL;
+
+    Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(lookup__doc__,
+"lookup(encoding) -> (encoder, decoder, stream_reader, stream_writer)\n\
+\n\
+Looks up a codec tuple in the Python codec registry and returns\n\
+a tuple of functions.");
+
+static
+PyObject *codec_lookup(PyObject *self, PyObject *args)
+{
+    char *encoding;
+
+    if (!PyArg_ParseTuple(args, "s:lookup", &encoding))
+        return NULL;
+
+    return _PyCodec_Lookup(encoding);
+}
+
+PyDoc_STRVAR(encode__doc__,
+"encode(obj, [encoding[,errors]]) -> object\n\
+\n\
+Encodes obj using the codec registered for encoding. encoding defaults\n\
+to the default encoding. errors may be given to set a different error\n\
+handling scheme. Default is 'strict' meaning that encoding errors raise\n\
+a ValueError. Other possible values are 'ignore', 'replace' and\n\
+'xmlcharrefreplace' as well as any other name registered with\n\
+codecs.register_error that can handle ValueErrors.");
+
+static PyObject *
+codec_encode(PyObject *self, PyObject *args)
+{
+    const char *encoding = NULL;
+    const char *errors = NULL;
+    PyObject *v;
+
+    if (!PyArg_ParseTuple(args, "O|ss:encode", &v, &encoding, &errors))
+        return NULL;
+
+#ifdef Py_USING_UNICODE
+    if (encoding == NULL)
+	encoding = PyUnicode_GetDefaultEncoding();
+#else
+    if (encoding == NULL) {
+	PyErr_SetString(PyExc_ValueError, "no encoding specified");
+	return NULL;
+    }
+#endif
+
+    /* Encode via the codec registry */
+    return PyCodec_Encode(v, encoding, errors);
+}
+
+PyDoc_STRVAR(decode__doc__,
+"decode(obj, [encoding[,errors]]) -> object\n\
+\n\
+Decodes obj using the codec registered for encoding. encoding defaults\n\
+to the default encoding. errors may be given to set a different error\n\
+handling scheme. Default is 'strict' meaning that encoding errors raise\n\
+a ValueError. Other possible values are 'ignore' and 'replace'\n\
+as well as any other name registerd with codecs.register_error that is\n\
+able to handle ValueErrors.");
+
+static PyObject *
+codec_decode(PyObject *self, PyObject *args)
+{
+    const char *encoding = NULL;
+    const char *errors = NULL;
+    PyObject *v;
+
+    if (!PyArg_ParseTuple(args, "O|ss:decode", &v, &encoding, &errors))
+        return NULL;
+
+#ifdef Py_USING_UNICODE
+    if (encoding == NULL)
+	encoding = PyUnicode_GetDefaultEncoding();
+#else
+    if (encoding == NULL) {
+	PyErr_SetString(PyExc_ValueError, "no encoding specified");
+	return NULL;
+    }
+#endif
+
+    /* Decode via the codec registry */
+    return PyCodec_Decode(v, encoding, errors);
+}
+
+/* --- Helpers ------------------------------------------------------------ */
+
+static
+PyObject *codec_tuple(PyObject *unicode,
+		      Py_ssize_t len)
+{
+    PyObject *v;
+    if (unicode == NULL)
+        return NULL;
+    v = Py_BuildValue("On", unicode, len);
+    Py_DECREF(unicode);
+    return v;
+}
+
+/* --- String codecs ------------------------------------------------------ */
+static PyObject *
+escape_decode(PyObject *self,
+	      PyObject *args)
+{
+    const char *errors = NULL;
+    const char *data;
+    Py_ssize_t size;
+
+    if (!PyArg_ParseTuple(args, "s#|z:escape_decode",
+			  &data, &size, &errors))
+	return NULL;
+    return codec_tuple(PyString_DecodeEscape(data, size, errors, 0, NULL),
+		       size);
+}
+
+static PyObject *
+escape_encode(PyObject *self,
+	      PyObject *args)
+{
+	PyObject *str;
+	const char *errors = NULL;
+	char *buf;
+	Py_ssize_t len;
+
+	if (!PyArg_ParseTuple(args, "O!|z:escape_encode",
+			      &PyString_Type, &str, &errors))
+		return NULL;
+
+	str = PyString_Repr(str, 0);
+	if (!str)
+		return NULL;
+
+	/* The string will be quoted. Unquote, similar to unicode-escape. */
+	buf = PyString_AS_STRING (str);
+	len = PyString_GET_SIZE (str);
+	memmove(buf, buf+1, len-2);
+	if (_PyString_Resize(&str, len-2) < 0)
+		return NULL;
+	
+	return codec_tuple(str, PyString_Size(str));
+}
+
+#ifdef Py_USING_UNICODE
+/* --- Decoder ------------------------------------------------------------ */
+
+static PyObject *
+unicode_internal_decode(PyObject *self,
+			PyObject *args)
+{
+    PyObject *obj;
+    const char *errors = NULL;
+    const char *data;
+    Py_ssize_t size;
+
+    if (!PyArg_ParseTuple(args, "O|z:unicode_internal_decode",
+			  &obj, &errors))
+	return NULL;
+
+    if (PyUnicode_Check(obj)) {
+	Py_INCREF(obj);
+	return codec_tuple(obj, PyUnicode_GET_SIZE(obj));
+    }
+    else {
+	if (PyObject_AsReadBuffer(obj, (const void **)&data, &size))
+	    return NULL;
+
+	return codec_tuple(_PyUnicode_DecodeUnicodeInternal(data, size, errors),
+			   size);
+    }
+}
+
+static PyObject *
+utf_7_decode(PyObject *self,
+	    PyObject *args)
+{
+    const char *data;
+    Py_ssize_t size;
+    const char *errors = NULL;
+
+    if (!PyArg_ParseTuple(args, "t#|z:utf_7_decode",
+			  &data, &size, &errors))
+	return NULL;
+
+    return codec_tuple(PyUnicode_DecodeUTF7(data, size, errors),
+		       size);
+}
+
+static PyObject *
+utf_8_decode(PyObject *self,
+	    PyObject *args)
+{
+    const char *data;
+    Py_ssize_t size;
+    const char *errors = NULL;
+    int final = 0;
+    Py_ssize_t consumed;
+    PyObject *decoded = NULL;
+
+    if (!PyArg_ParseTuple(args, "t#|zi:utf_8_decode",
+			  &data, &size, &errors, &final))
+	return NULL;
+    if (size < 0) {
+	    PyErr_SetString(PyExc_ValueError, "negative argument");
+	    return 0;
+    }
+    consumed = size;
+	
+    decoded = PyUnicode_DecodeUTF8Stateful(data, size, errors,
+					   final ? NULL : &consumed);
+    if (decoded == NULL)
+	return NULL;
+    return codec_tuple(decoded, consumed);
+}
+
+static PyObject *
+utf_16_decode(PyObject *self,
+	    PyObject *args)
+{
+    const char *data;
+    Py_ssize_t size;
+    const char *errors = NULL;
+    int byteorder = 0;
+    int final = 0;
+    Py_ssize_t consumed;
+    PyObject *decoded;
+
+    if (!PyArg_ParseTuple(args, "t#|zi:utf_16_decode",
+			  &data, &size, &errors, &final))
+	return NULL;
+    if (size < 0) {
+	    PyErr_SetString(PyExc_ValueError, "negative argument");
+	    return 0;
+    }
+    consumed = size; /* This is overwritten unless final is true. */
+    decoded = PyUnicode_DecodeUTF16Stateful(data, size, errors, &byteorder,
+					    final ? NULL : &consumed);
+    if (decoded == NULL)
+	return NULL;
+    return codec_tuple(decoded, consumed);
+}
+
+static PyObject *
+utf_16_le_decode(PyObject *self,
+		 PyObject *args)
+{
+    const char *data;
+    Py_ssize_t size;
+    const char *errors = NULL;
+    int byteorder = -1;
+    int final = 0;
+    Py_ssize_t consumed;
+    PyObject *decoded = NULL;
+
+    if (!PyArg_ParseTuple(args, "t#|zi:utf_16_le_decode",
+			  &data, &size, &errors, &final))
+	return NULL;
+
+    if (size < 0) {
+          PyErr_SetString(PyExc_ValueError, "negative argument");
+          return 0;
+    }
+    consumed = size; /* This is overwritten unless final is true. */
+    decoded = PyUnicode_DecodeUTF16Stateful(data, size, errors,
+	&byteorder, final ? NULL : &consumed);
+    if (decoded == NULL)
+	return NULL;
+    return codec_tuple(decoded, consumed);
+
+}
+
+static PyObject *
+utf_16_be_decode(PyObject *self,
+		 PyObject *args)
+{
+    const char *data;
+    Py_ssize_t size;
+    const char *errors = NULL;
+    int byteorder = 1;
+    int final = 0;
+    Py_ssize_t consumed;
+    PyObject *decoded = NULL;
+
+    if (!PyArg_ParseTuple(args, "t#|zi:utf_16_be_decode",
+			  &data, &size, &errors, &final))
+	return NULL;
+    if (size < 0) {
+          PyErr_SetString(PyExc_ValueError, "negative argument");
+          return 0;
+    }
+    consumed = size; /* This is overwritten unless final is true. */
+    decoded = PyUnicode_DecodeUTF16Stateful(data, size, errors,
+	&byteorder, final ? NULL : &consumed);
+    if (decoded == NULL)
+	return NULL;
+    return codec_tuple(decoded, consumed);
+}
+
+/* This non-standard version also provides access to the byteorder
+   parameter of the builtin UTF-16 codec.
+
+   It returns a tuple (unicode, bytesread, byteorder) with byteorder
+   being the value in effect at the end of data.
+
+*/
+
+static PyObject *
+utf_16_ex_decode(PyObject *self,
+		 PyObject *args)
+{
+    const char *data;
+    Py_ssize_t size;
+    const char *errors = NULL;
+    int byteorder = 0;
+    PyObject *unicode, *tuple;
+    int final = 0;
+    Py_ssize_t consumed;
+
+    if (!PyArg_ParseTuple(args, "t#|zii:utf_16_ex_decode",
+			  &data, &size, &errors, &byteorder, &final))
+	return NULL;
+    if (size < 0) {
+	    PyErr_SetString(PyExc_ValueError, "negative argument");
+	    return 0;
+    }
+    consumed = size; /* This is overwritten unless final is true. */
+    unicode = PyUnicode_DecodeUTF16Stateful(data, size, errors, &byteorder,
+					    final ? NULL : &consumed);
+    if (unicode == NULL)
+	return NULL;
+    tuple = Py_BuildValue("Oni", unicode, consumed, byteorder);
+    Py_DECREF(unicode);
+    return tuple;
+}
+
+static PyObject *
+unicode_escape_decode(PyObject *self,
+		     PyObject *args)
+{
+    const char *data;
+    Py_ssize_t size;
+    const char *errors = NULL;
+
+    if (!PyArg_ParseTuple(args, "t#|z:unicode_escape_decode",
+			  &data, &size, &errors))
+	return NULL;
+
+    return codec_tuple(PyUnicode_DecodeUnicodeEscape(data, size, errors),
+		       size);
+}
+
+static PyObject *
+raw_unicode_escape_decode(PyObject *self,
+			PyObject *args)
+{
+    const char *data;
+    Py_ssize_t size;
+    const char *errors = NULL;
+
+    if (!PyArg_ParseTuple(args, "t#|z:raw_unicode_escape_decode",
+			  &data, &size, &errors))
+	return NULL;
+
+    return codec_tuple(PyUnicode_DecodeRawUnicodeEscape(data, size, errors),
+		       size);
+}
+
+static PyObject *
+latin_1_decode(PyObject *self,
+	       PyObject *args)
+{
+    const char *data;
+    Py_ssize_t size;
+    const char *errors = NULL;
+
+    if (!PyArg_ParseTuple(args, "t#|z:latin_1_decode",
+			  &data, &size, &errors))
+	return NULL;
+
+    return codec_tuple(PyUnicode_DecodeLatin1(data, size, errors),
+		       size);
+}
+
+static PyObject *
+ascii_decode(PyObject *self,
+	     PyObject *args)
+{
+    const char *data;
+    Py_ssize_t size;
+    const char *errors = NULL;
+
+    if (!PyArg_ParseTuple(args, "t#|z:ascii_decode",
+			  &data, &size, &errors))
+	return NULL;
+
+    return codec_tuple(PyUnicode_DecodeASCII(data, size, errors),
+		       size);
+}
+
+static PyObject *
+charmap_decode(PyObject *self,
+	       PyObject *args)
+{
+    const char *data;
+    Py_ssize_t size;
+    const char *errors = NULL;
+    PyObject *mapping = NULL;
+
+    if (!PyArg_ParseTuple(args, "t#|zO:charmap_decode",
+			  &data, &size, &errors, &mapping))
+	return NULL;
+    if (mapping == Py_None)
+	mapping = NULL;
+
+    return codec_tuple(PyUnicode_DecodeCharmap(data, size, mapping, errors),
+		       size);
+}
+
+#if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T)
+
+static PyObject *
+mbcs_decode(PyObject *self,
+	    PyObject *args)
+{
+    const char *data;
+    Py_ssize_t size, consumed;
+    const char *errors = NULL;
+    int final = 0;
+    PyObject *decoded;
+
+    if (!PyArg_ParseTuple(args, "t#|zi:mbcs_decode",
+			  &data, &size, &errors, &final))
+	return NULL;
+
+    decoded = PyUnicode_DecodeMBCSStateful(
+	data, size, errors, final ? NULL : &consumed);
+    if (!decoded)
+	return NULL;
+    return codec_tuple(decoded, final ? size : consumed);
+}
+
+#endif /* MS_WINDOWS */
+
+/* --- Encoder ------------------------------------------------------------ */
+
+static PyObject *
+readbuffer_encode(PyObject *self,
+		  PyObject *args)
+{
+    const char *data;
+    Py_ssize_t size;
+    const char *errors = NULL;
+
+    if (!PyArg_ParseTuple(args, "s#|z:readbuffer_encode",
+			  &data, &size, &errors))
+	return NULL;
+
+    return codec_tuple(PyString_FromStringAndSize(data, size),
+		       size);
+}
+
+static PyObject *
+charbuffer_encode(PyObject *self,
+		  PyObject *args)
+{
+    const char *data;
+    Py_ssize_t size;
+    const char *errors = NULL;
+
+    if (!PyArg_ParseTuple(args, "t#|z:charbuffer_encode",
+			  &data, &size, &errors))
+	return NULL;
+
+    return codec_tuple(PyString_FromStringAndSize(data, size),
+		       size);
+}
+
+static PyObject *
+unicode_internal_encode(PyObject *self,
+			PyObject *args)
+{
+    PyObject *obj;
+    const char *errors = NULL;
+    const char *data;
+    Py_ssize_t size;
+
+    if (!PyArg_ParseTuple(args, "O|z:unicode_internal_encode",
+			  &obj, &errors))
+	return NULL;
+
+    if (PyUnicode_Check(obj)) {
+	data = PyUnicode_AS_DATA(obj);
+	size = PyUnicode_GET_DATA_SIZE(obj);
+	return codec_tuple(PyString_FromStringAndSize(data, size),
+			   size);
+    }
+    else {
+	if (PyObject_AsReadBuffer(obj, (const void **)&data, &size))
+	    return NULL;
+	return codec_tuple(PyString_FromStringAndSize(data, size),
+			   size);
+    }
+}
+
+static PyObject *
+utf_7_encode(PyObject *self,
+	    PyObject *args)
+{
+    PyObject *str, *v;
+    const char *errors = NULL;
+
+    if (!PyArg_ParseTuple(args, "O|z:utf_7_encode",
+			  &str, &errors))
+	return NULL;
+
+    str = PyUnicode_FromObject(str);
+    if (str == NULL)
+	return NULL;
+    v = codec_tuple(PyUnicode_EncodeUTF7(PyUnicode_AS_UNICODE(str),
+					 PyUnicode_GET_SIZE(str),
+					 0,
+					 0,
+					 errors),
+		    PyUnicode_GET_SIZE(str));
+    Py_DECREF(str);
+    return v;
+}
+
+static PyObject *
+utf_8_encode(PyObject *self,
+	    PyObject *args)
+{
+    PyObject *str, *v;
+    const char *errors = NULL;
+
+    if (!PyArg_ParseTuple(args, "O|z:utf_8_encode",
+			  &str, &errors))
+	return NULL;
+
+    str = PyUnicode_FromObject(str);
+    if (str == NULL)
+	return NULL;
+    v = codec_tuple(PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(str),
+					 PyUnicode_GET_SIZE(str),
+					 errors),
+		    PyUnicode_GET_SIZE(str));
+    Py_DECREF(str);
+    return v;
+}
+
+/* This version provides access to the byteorder parameter of the
+   builtin UTF-16 codecs as optional third argument. It defaults to 0
+   which means: use the native byte order and prepend the data with a
+   BOM mark.
+
+*/
+
+static PyObject *
+utf_16_encode(PyObject *self,
+	    PyObject *args)
+{
+    PyObject *str, *v;
+    const char *errors = NULL;
+    int byteorder = 0;
+
+    if (!PyArg_ParseTuple(args, "O|zi:utf_16_encode",
+			  &str, &errors, &byteorder))
+	return NULL;
+
+    str = PyUnicode_FromObject(str);
+    if (str == NULL)
+	return NULL;
+    v = codec_tuple(PyUnicode_EncodeUTF16(PyUnicode_AS_UNICODE(str),
+					  PyUnicode_GET_SIZE(str),
+					  errors,
+					  byteorder),
+		    PyUnicode_GET_SIZE(str));
+    Py_DECREF(str);
+    return v;
+}
+
+static PyObject *
+utf_16_le_encode(PyObject *self,
+		 PyObject *args)
+{
+    PyObject *str, *v;
+    const char *errors = NULL;
+
+    if (!PyArg_ParseTuple(args, "O|z:utf_16_le_encode",
+			  &str, &errors))
+	return NULL;
+
+    str = PyUnicode_FromObject(str);
+    if (str == NULL)
+	return NULL;
+    v = codec_tuple(PyUnicode_EncodeUTF16(PyUnicode_AS_UNICODE(str),
+					     PyUnicode_GET_SIZE(str),
+					     errors,
+					     -1),
+		       PyUnicode_GET_SIZE(str));
+    Py_DECREF(str);
+    return v;
+}
+
+static PyObject *
+utf_16_be_encode(PyObject *self,
+		 PyObject *args)
+{
+    PyObject *str, *v;
+    const char *errors = NULL;
+
+    if (!PyArg_ParseTuple(args, "O|z:utf_16_be_encode",
+			  &str, &errors))
+	return NULL;
+
+    str = PyUnicode_FromObject(str);
+    if (str == NULL)
+	return NULL;
+    v = codec_tuple(PyUnicode_EncodeUTF16(PyUnicode_AS_UNICODE(str),
+					  PyUnicode_GET_SIZE(str),
+					  errors,
+					  +1),
+		    PyUnicode_GET_SIZE(str));
+    Py_DECREF(str);
+    return v;
+}
+
+static PyObject *
+unicode_escape_encode(PyObject *self,
+		     PyObject *args)
+{
+    PyObject *str, *v;
+    const char *errors = NULL;
+
+    if (!PyArg_ParseTuple(args, "O|z:unicode_escape_encode",
+			  &str, &errors))
+	return NULL;
+
+    str = PyUnicode_FromObject(str);
+    if (str == NULL)
+	return NULL;
+    v = codec_tuple(PyUnicode_EncodeUnicodeEscape(PyUnicode_AS_UNICODE(str),
+						  PyUnicode_GET_SIZE(str)),
+		    PyUnicode_GET_SIZE(str));
+    Py_DECREF(str);
+    return v;
+}
+
+static PyObject *
+raw_unicode_escape_encode(PyObject *self,
+			PyObject *args)
+{
+    PyObject *str, *v;
+    const char *errors = NULL;
+
+    if (!PyArg_ParseTuple(args, "O|z:raw_unicode_escape_encode",
+			  &str, &errors))
+	return NULL;
+
+    str = PyUnicode_FromObject(str);
+    if (str == NULL)
+	return NULL;
+    v = codec_tuple(PyUnicode_EncodeRawUnicodeEscape(
+			       PyUnicode_AS_UNICODE(str),
+			       PyUnicode_GET_SIZE(str)),
+		    PyUnicode_GET_SIZE(str));
+    Py_DECREF(str);
+    return v;
+}
+
+static PyObject *
+latin_1_encode(PyObject *self,
+	       PyObject *args)
+{
+    PyObject *str, *v;
+    const char *errors = NULL;
+
+    if (!PyArg_ParseTuple(args, "O|z:latin_1_encode",
+			  &str, &errors))
+	return NULL;
+
+    str = PyUnicode_FromObject(str);
+    if (str == NULL)
+	return NULL;
+    v = codec_tuple(PyUnicode_EncodeLatin1(
+			       PyUnicode_AS_UNICODE(str),
+			       PyUnicode_GET_SIZE(str),
+			       errors),
+		    PyUnicode_GET_SIZE(str));
+    Py_DECREF(str);
+    return v;
+}
+
+static PyObject *
+ascii_encode(PyObject *self,
+	     PyObject *args)
+{
+    PyObject *str, *v;
+    const char *errors = NULL;
+
+    if (!PyArg_ParseTuple(args, "O|z:ascii_encode",
+			  &str, &errors))
+	return NULL;
+
+    str = PyUnicode_FromObject(str);
+    if (str == NULL)
+	return NULL;
+    v = codec_tuple(PyUnicode_EncodeASCII(
+			       PyUnicode_AS_UNICODE(str),
+			       PyUnicode_GET_SIZE(str),
+			       errors),
+		    PyUnicode_GET_SIZE(str));
+    Py_DECREF(str);
+    return v;
+}
+
+static PyObject *
+charmap_encode(PyObject *self,
+	     PyObject *args)
+{
+    PyObject *str, *v;
+    const char *errors = NULL;
+    PyObject *mapping = NULL;
+
+    if (!PyArg_ParseTuple(args, "O|zO:charmap_encode",
+			  &str, &errors, &mapping))
+	return NULL;
+    if (mapping == Py_None)
+	mapping = NULL;
+
+    str = PyUnicode_FromObject(str);
+    if (str == NULL)
+	return NULL;
+    v = codec_tuple(PyUnicode_EncodeCharmap(
+			       PyUnicode_AS_UNICODE(str),
+			       PyUnicode_GET_SIZE(str),
+			       mapping,
+			       errors),
+		    PyUnicode_GET_SIZE(str));
+    Py_DECREF(str);
+    return v;
+}
+
+static PyObject*
+charmap_build(PyObject *self, PyObject *args)
+{
+    PyObject *map;
+    if (!PyArg_ParseTuple(args, "U:charmap_build", &map))
+        return NULL;
+    return PyUnicode_BuildEncodingMap(map);
+}
+
+#if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T)
+
+static PyObject *
+mbcs_encode(PyObject *self,
+	    PyObject *args)
+{
+    PyObject *str, *v;
+    const char *errors = NULL;
+
+    if (!PyArg_ParseTuple(args, "O|z:mbcs_encode",
+			  &str, &errors))
+	return NULL;
+
+    str = PyUnicode_FromObject(str);
+    if (str == NULL)
+	return NULL;
+    v = codec_tuple(PyUnicode_EncodeMBCS(
+			       PyUnicode_AS_UNICODE(str),
+			       PyUnicode_GET_SIZE(str),
+			       errors),
+		    PyUnicode_GET_SIZE(str));
+    Py_DECREF(str);
+    return v;
+}
+
+#endif /* MS_WINDOWS */
+#endif /* Py_USING_UNICODE */
+
+/* --- Error handler registry --------------------------------------------- */
+
+PyDoc_STRVAR(register_error__doc__,
+"register_error(errors, handler)\n\
+\n\
+Register the specified error handler under the name\n\
+errors. handler must be a callable object, that\n\
+will be called with an exception instance containing\n\
+information about the location of the encoding/decoding\n\
+error and must return a (replacement, new position) tuple.");
+
+static PyObject *register_error(PyObject *self, PyObject *args)
+{
+    const char *name;
+    PyObject *handler;
+
+    if (!PyArg_ParseTuple(args, "sO:register_error",
+			  &name, &handler))
+	return NULL;
+    if (PyCodec_RegisterError(name, handler))
+        return NULL;
+    Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(lookup_error__doc__,
+"lookup_error(errors) -> handler\n\
+\n\
+Return the error handler for the specified error handling name\n\
+or raise a LookupError, if no handler exists under this name.");
+
+static PyObject *lookup_error(PyObject *self, PyObject *args)
+{
+    const char *name;
+
+    if (!PyArg_ParseTuple(args, "s:lookup_error",
+			  &name))
+	return NULL;
+    return PyCodec_LookupError(name);
+}
+
+/* --- Module API --------------------------------------------------------- */
+
+static PyMethodDef _codecs_functions[] = {
+    {"register",		codec_register,			METH_O,
+        register__doc__},
+    {"lookup",			codec_lookup, 			METH_VARARGS,
+        lookup__doc__},
+    {"encode",			codec_encode,			METH_VARARGS,
+	encode__doc__},
+    {"decode",			codec_decode,			METH_VARARGS,
+	decode__doc__},
+    {"escape_encode",		escape_encode,			METH_VARARGS},
+    {"escape_decode",		escape_decode,			METH_VARARGS},
+#ifdef Py_USING_UNICODE
+    {"utf_8_encode",		utf_8_encode,			METH_VARARGS},
+    {"utf_8_decode",		utf_8_decode,			METH_VARARGS},
+    {"utf_7_encode",		utf_7_encode,			METH_VARARGS},
+    {"utf_7_decode",		utf_7_decode,			METH_VARARGS},
+    {"utf_16_encode",		utf_16_encode,			METH_VARARGS},
+    {"utf_16_le_encode",	utf_16_le_encode,		METH_VARARGS},
+    {"utf_16_be_encode",	utf_16_be_encode,		METH_VARARGS},
+    {"utf_16_decode",		utf_16_decode,			METH_VARARGS},
+    {"utf_16_le_decode",	utf_16_le_decode,		METH_VARARGS},
+    {"utf_16_be_decode",	utf_16_be_decode,		METH_VARARGS},
+    {"utf_16_ex_decode",	utf_16_ex_decode,		METH_VARARGS},
+    {"unicode_escape_encode",	unicode_escape_encode,		METH_VARARGS},
+    {"unicode_escape_decode",	unicode_escape_decode,		METH_VARARGS},
+    {"unicode_internal_encode",	unicode_internal_encode,	METH_VARARGS},
+    {"unicode_internal_decode",	unicode_internal_decode,	METH_VARARGS},
+    {"raw_unicode_escape_encode", raw_unicode_escape_encode,	METH_VARARGS},
+    {"raw_unicode_escape_decode", raw_unicode_escape_decode,	METH_VARARGS},
+    {"latin_1_encode", 		latin_1_encode,			METH_VARARGS},
+    {"latin_1_decode", 		latin_1_decode,			METH_VARARGS},
+    {"ascii_encode", 		ascii_encode,			METH_VARARGS},
+    {"ascii_decode", 		ascii_decode,			METH_VARARGS},
+    {"charmap_encode", 		charmap_encode,			METH_VARARGS},
+    {"charmap_decode", 		charmap_decode,			METH_VARARGS},
+    {"charmap_build", 		charmap_build,			METH_VARARGS},
+    {"readbuffer_encode",	readbuffer_encode,		METH_VARARGS},
+    {"charbuffer_encode",	charbuffer_encode,		METH_VARARGS},
+#if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T)
+    {"mbcs_encode", 		mbcs_encode,			METH_VARARGS},
+    {"mbcs_decode", 		mbcs_decode,			METH_VARARGS},
+#endif
+#endif /* Py_USING_UNICODE */
+    {"register_error", 		register_error,			METH_VARARGS,
+        register_error__doc__},
+    {"lookup_error", 		lookup_error,			METH_VARARGS,
+        lookup_error__doc__},
+    {NULL, NULL}		/* sentinel */
+};
+
+PyMODINIT_FUNC
+init_codecs(void)
+{
+    Py_InitModule("_codecs", _codecs_functions);
+}

Added: vendor/Python/current/Modules/_csv.c
===================================================================
--- vendor/Python/current/Modules/_csv.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_csv.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1604 @@
+/* csv module */
+
+/*
+
+This module provides the low-level underpinnings of a CSV reading/writing
+module.  Users should not use this module directly, but import the csv.py
+module instead.
+
+**** For people modifying this code, please note that as of this writing
+**** (2003-03-23), it is intended that this code should work with Python
+**** 2.2.
+
+*/
+
+#define MODULE_VERSION "1.0"
+
+#include "Python.h"
+#include "structmember.h"
+
+
+/* begin 2.2 compatibility macros */
+#ifndef PyDoc_STRVAR
+/* Define macros for inline documentation. */
+#define PyDoc_VAR(name) static char name[]
+#define PyDoc_STRVAR(name,str) PyDoc_VAR(name) = PyDoc_STR(str)
+#ifdef WITH_DOC_STRINGS
+#define PyDoc_STR(str) str
+#else
+#define PyDoc_STR(str) ""
+#endif
+#endif /* ifndef PyDoc_STRVAR */
+
+#ifndef PyMODINIT_FUNC
+#	if defined(__cplusplus)
+#		define PyMODINIT_FUNC extern "C" void
+#	else /* __cplusplus */
+#		define PyMODINIT_FUNC void
+#	endif /* __cplusplus */
+#endif
+
+#ifndef Py_CLEAR
+#define Py_CLEAR(op)						\
+	do {							\
+		if (op) {					\
+			PyObject *tmp = (PyObject *)(op);	\
+			(op) = NULL;				\
+			Py_DECREF(tmp);				\
+		}						\
+	} while (0)
+#endif
+#ifndef Py_VISIT
+#define Py_VISIT(op)							\
+        do { 								\
+                if (op) {						\
+                        int vret = visit((PyObject *)(op), arg);	\
+                        if (vret)					\
+                                return vret;				\
+                }							\
+        } while (0)
+#endif
+
+/* end 2.2 compatibility macros */
+
+#define IS_BASESTRING(o) \
+	PyObject_TypeCheck(o, &PyBaseString_Type)
+
+static PyObject *error_obj;	/* CSV exception */
+static PyObject *dialects;      /* Dialect registry */
+static long field_limit = 128 * 1024;	/* max parsed field size */
+
+typedef enum {
+	START_RECORD, START_FIELD, ESCAPED_CHAR, IN_FIELD, 
+	IN_QUOTED_FIELD, ESCAPE_IN_QUOTED_FIELD, QUOTE_IN_QUOTED_FIELD,
+	EAT_CRNL
+} ParserState;
+
+typedef enum {
+	QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC, QUOTE_NONE
+} QuoteStyle;
+
+typedef struct {
+	QuoteStyle style;
+	char *name;
+} StyleDesc;
+
+static StyleDesc quote_styles[] = {
+	{ QUOTE_MINIMAL,    "QUOTE_MINIMAL" },
+	{ QUOTE_ALL,        "QUOTE_ALL" },
+	{ QUOTE_NONNUMERIC, "QUOTE_NONNUMERIC" },
+	{ QUOTE_NONE,       "QUOTE_NONE" },
+	{ 0 }
+};
+
+typedef struct {
+        PyObject_HEAD
+        
+	int doublequote;	/* is " represented by ""? */
+	char delimiter;		/* field separator */
+	char quotechar;		/* quote character */
+	char escapechar;	/* escape character */
+	int skipinitialspace;	/* ignore spaces following delimiter? */
+	PyObject *lineterminator; /* string to write between records */
+	int quoting;		/* style of quoting to write */
+
+	int strict;		/* raise exception on bad CSV */
+} DialectObj;
+
+staticforward PyTypeObject Dialect_Type;
+
+typedef struct {
+        PyObject_HEAD
+
+        PyObject *input_iter;   /* iterate over this for input lines */
+
+        DialectObj *dialect;    /* parsing dialect */
+
+	PyObject *fields;	/* field list for current record */
+	ParserState state;	/* current CSV parse state */
+	char *field;		/* build current field in here */
+	int field_size;		/* size of allocated buffer */
+	int field_len;		/* length of current field */
+	int numeric_field;	/* treat field as numeric */
+	unsigned long line_num;	/* Source-file line number */
+} ReaderObj;
+
+staticforward PyTypeObject Reader_Type;
+
+#define ReaderObject_Check(v)   ((v)->ob_type == &Reader_Type)
+
+typedef struct {
+        PyObject_HEAD
+
+        PyObject *writeline;    /* write output lines to this file */
+
+        DialectObj *dialect;    /* parsing dialect */
+
+	char *rec;		/* buffer for parser.join */
+	int rec_size;		/* size of allocated record */
+	int rec_len;		/* length of record */
+	int num_fields;		/* number of fields in record */
+} WriterObj;        
+
+staticforward PyTypeObject Writer_Type;
+
+/*
+ * DIALECT class
+ */
+
+static PyObject *
+get_dialect_from_registry(PyObject * name_obj)
+{
+        PyObject *dialect_obj;
+
+        dialect_obj = PyDict_GetItem(dialects, name_obj);
+	if (dialect_obj == NULL) {
+		if (!PyErr_Occurred())
+			PyErr_Format(error_obj, "unknown dialect");
+	}
+	else
+		Py_INCREF(dialect_obj);
+        return dialect_obj;
+}
+
+static PyObject *
+get_string(PyObject *str)
+{
+        Py_XINCREF(str);
+        return str;
+}
+
+static PyObject *
+get_nullchar_as_None(char c)
+{
+        if (c == '\0') {
+                Py_INCREF(Py_None);
+                return Py_None;
+        }
+        else
+                return PyString_FromStringAndSize((char*)&c, 1);
+}
+
+static PyObject *
+Dialect_get_lineterminator(DialectObj *self)
+{
+        return get_string(self->lineterminator);
+}
+
+static PyObject *
+Dialect_get_escapechar(DialectObj *self)
+{
+        return get_nullchar_as_None(self->escapechar);
+}
+
+static PyObject *
+Dialect_get_quotechar(DialectObj *self)
+{
+        return get_nullchar_as_None(self->quotechar);
+}
+
+static PyObject *
+Dialect_get_quoting(DialectObj *self)
+{
+        return PyInt_FromLong(self->quoting);
+}
+
+static int
+_set_bool(const char *name, int *target, PyObject *src, int dflt)
+{
+	if (src == NULL)
+		*target = dflt;
+	else
+		*target = PyObject_IsTrue(src);
+	return 0;
+}
+
+static int
+_set_int(const char *name, int *target, PyObject *src, int dflt)
+{
+	if (src == NULL)
+		*target = dflt;
+	else {
+		if (!PyInt_Check(src)) {
+			PyErr_Format(PyExc_TypeError, 
+				     "\"%s\" must be an integer", name);
+			return -1;
+		}
+		*target = PyInt_AsLong(src);
+	}
+	return 0;
+}
+
+static int
+_set_char(const char *name, char *target, PyObject *src, char dflt)
+{
+	if (src == NULL)
+		*target = dflt;
+	else {
+		if (src == Py_None || PyString_Size(src) == 0)
+			*target = '\0';
+		else if (!PyString_Check(src) || PyString_Size(src) != 1) {
+			PyErr_Format(PyExc_TypeError, 
+				     "\"%s\" must be an 1-character string", 
+				     name);
+			return -1;
+		}
+		else {
+			char *s = PyString_AsString(src);
+			if (s == NULL)
+				return -1;
+			*target = s[0];
+		}
+	}
+        return 0;
+}
+
+static int
+_set_str(const char *name, PyObject **target, PyObject *src, const char *dflt)
+{
+	if (src == NULL)
+		*target = PyString_FromString(dflt);
+	else {
+		if (src == Py_None)
+			*target = NULL;
+		else if (!IS_BASESTRING(src)) {
+			PyErr_Format(PyExc_TypeError, 
+				     "\"%s\" must be an string", name);
+			return -1;
+		}
+		else {
+			Py_XDECREF(*target);
+			Py_INCREF(src);
+			*target = src;
+		}
+	}
+        return 0;
+}
+
+static int
+dialect_check_quoting(int quoting)
+{
+        StyleDesc *qs = quote_styles;
+
+	for (qs = quote_styles; qs->name; qs++) {
+		if (qs->style == quoting)
+                        return 0;
+        }
+	PyErr_Format(PyExc_TypeError, "bad \"quoting\" value");
+        return -1;
+}
+
+#define D_OFF(x) offsetof(DialectObj, x)
+
+static struct PyMemberDef Dialect_memberlist[] = {
+	{ "delimiter",          T_CHAR, D_OFF(delimiter), READONLY },
+	{ "skipinitialspace",   T_INT, D_OFF(skipinitialspace), READONLY },
+	{ "doublequote",        T_INT, D_OFF(doublequote), READONLY },
+	{ "strict",             T_INT, D_OFF(strict), READONLY },
+	{ NULL }
+};
+
+static PyGetSetDef Dialect_getsetlist[] = {
+	{ "escapechar",		(getter)Dialect_get_escapechar},
+	{ "lineterminator",	(getter)Dialect_get_lineterminator},
+	{ "quotechar",		(getter)Dialect_get_quotechar},
+	{ "quoting",		(getter)Dialect_get_quoting},
+	{NULL},
+};
+
+static void
+Dialect_dealloc(DialectObj *self)
+{
+        Py_XDECREF(self->lineterminator);
+        self->ob_type->tp_free((PyObject *)self);
+}
+
+static char *dialect_kws[] = {
+	"dialect",
+	"delimiter",
+	"doublequote",
+	"escapechar",
+	"lineterminator",
+	"quotechar",
+	"quoting",
+	"skipinitialspace",
+	"strict",
+	NULL
+};
+
+static PyObject *
+dialect_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
+{
+	DialectObj *self;
+	PyObject *ret = NULL;
+	PyObject *dialect = NULL;
+	PyObject *delimiter = NULL;
+	PyObject *doublequote = NULL;
+	PyObject *escapechar = NULL;
+	PyObject *lineterminator = NULL;
+	PyObject *quotechar = NULL;
+	PyObject *quoting = NULL;
+	PyObject *skipinitialspace = NULL;
+	PyObject *strict = NULL;
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+					 "|OOOOOOOOO", dialect_kws,
+					 &dialect,
+					 &delimiter,
+					 &doublequote,
+					 &escapechar,
+					 &lineterminator,
+					 &quotechar,
+					 &quoting,
+					 &skipinitialspace,
+					 &strict))
+		return NULL;
+
+	if (dialect != NULL) {
+		if (IS_BASESTRING(dialect)) {
+			dialect = get_dialect_from_registry(dialect);
+			if (dialect == NULL)
+				return NULL;
+		}
+		else
+			Py_INCREF(dialect);
+		/* Can we reuse this instance? */
+		if (PyObject_TypeCheck(dialect, &Dialect_Type) &&
+		    delimiter == 0 &&
+		    doublequote == 0 &&
+		    escapechar == 0 &&
+		    lineterminator == 0 &&
+		    quotechar == 0 &&
+		    quoting == 0 &&
+		    skipinitialspace == 0 &&
+		    strict == 0)
+			return dialect;
+	}
+
+	self = (DialectObj *)type->tp_alloc(type, 0);
+	if (self == NULL) {
+		Py_XDECREF(dialect);
+		return NULL;
+	}
+	self->lineterminator = NULL;
+
+	Py_XINCREF(delimiter);
+	Py_XINCREF(doublequote);
+	Py_XINCREF(escapechar);
+	Py_XINCREF(lineterminator);
+	Py_XINCREF(quotechar);
+	Py_XINCREF(quoting);
+	Py_XINCREF(skipinitialspace);
+	Py_XINCREF(strict);
+	if (dialect != NULL) {
+#define DIALECT_GETATTR(v, n) \
+		if (v == NULL) \
+			v = PyObject_GetAttrString(dialect, n)
+		DIALECT_GETATTR(delimiter, "delimiter");
+		DIALECT_GETATTR(doublequote, "doublequote");
+		DIALECT_GETATTR(escapechar, "escapechar");
+		DIALECT_GETATTR(lineterminator, "lineterminator");
+		DIALECT_GETATTR(quotechar, "quotechar");
+		DIALECT_GETATTR(quoting, "quoting");
+		DIALECT_GETATTR(skipinitialspace, "skipinitialspace");
+		DIALECT_GETATTR(strict, "strict");
+		PyErr_Clear();
+	}
+
+	/* check types and convert to C values */
+#define DIASET(meth, name, target, src, dflt) \
+	if (meth(name, target, src, dflt)) \
+		goto err
+	DIASET(_set_char, "delimiter", &self->delimiter, delimiter, ',');
+	DIASET(_set_bool, "doublequote", &self->doublequote, doublequote, 1);
+	DIASET(_set_char, "escapechar", &self->escapechar, escapechar, 0);
+	DIASET(_set_str, "lineterminator", &self->lineterminator, lineterminator, "\r\n");
+	DIASET(_set_char, "quotechar", &self->quotechar, quotechar, '"');
+	DIASET(_set_int, "quoting", &self->quoting, quoting, QUOTE_MINIMAL);
+	DIASET(_set_bool, "skipinitialspace", &self->skipinitialspace, skipinitialspace, 0);
+	DIASET(_set_bool, "strict", &self->strict, strict, 0);
+
+	/* validate options */
+	if (dialect_check_quoting(self->quoting))
+		goto err;
+	if (self->delimiter == 0) {
+                PyErr_SetString(PyExc_TypeError, "delimiter must be set");
+		goto err;
+	}
+	if (quotechar == Py_None && quoting == NULL)
+		self->quoting = QUOTE_NONE;
+	if (self->quoting != QUOTE_NONE && self->quotechar == 0) {
+                PyErr_SetString(PyExc_TypeError, 
+				"quotechar must be set if quoting enabled");
+		goto err;
+	}
+	if (self->lineterminator == 0) {
+		PyErr_SetString(PyExc_TypeError, "lineterminator must be set");
+		goto err;
+	}
+
+	ret = (PyObject *)self;
+	Py_INCREF(self);
+err:
+	Py_XDECREF(self);
+	Py_XDECREF(dialect);
+	Py_XDECREF(delimiter);
+	Py_XDECREF(doublequote);
+	Py_XDECREF(escapechar);
+	Py_XDECREF(lineterminator);
+	Py_XDECREF(quotechar);
+	Py_XDECREF(quoting);
+	Py_XDECREF(skipinitialspace);
+	Py_XDECREF(strict);
+	return ret;
+}
+
+
+PyDoc_STRVAR(Dialect_Type_doc, 
+"CSV dialect\n"
+"\n"
+"The Dialect type records CSV parsing and generation options.\n");
+
+static PyTypeObject Dialect_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0,                                      /* ob_size */
+	"_csv.Dialect",                         /* tp_name */
+	sizeof(DialectObj),                     /* tp_basicsize */
+	0,                                      /* tp_itemsize */
+	/*  methods  */
+	(destructor)Dialect_dealloc,            /* tp_dealloc */
+	(printfunc)0,                           /* tp_print */
+	(getattrfunc)0,                         /* tp_getattr */
+	(setattrfunc)0,                         /* tp_setattr */
+	(cmpfunc)0,                             /* tp_compare */
+	(reprfunc)0,                            /* tp_repr */
+	0,                                      /* tp_as_number */
+	0,                                      /* tp_as_sequence */
+	0,                                      /* tp_as_mapping */
+	(hashfunc)0,                            /* tp_hash */
+	(ternaryfunc)0,                         /* tp_call */
+	(reprfunc)0,                    	/* tp_str */
+	0,                                      /* tp_getattro */
+        0,                                      /* tp_setattro */
+        0,                                      /* tp_as_buffer */
+        Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+	Dialect_Type_doc,                       /* tp_doc */
+        0,                                      /* tp_traverse */
+        0,                                      /* tp_clear */
+        0,                                      /* tp_richcompare */
+        0,                                      /* tp_weaklistoffset */
+        0,                                      /* tp_iter */
+        0,                                      /* tp_iternext */
+	0,					/* tp_methods */
+        Dialect_memberlist,                     /* tp_members */
+        Dialect_getsetlist,                     /* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	0,					/* tp_init */
+	0,					/* tp_alloc */
+	dialect_new,			        /* tp_new */
+	0,                           		/* tp_free */
+};
+
+/*
+ * Return an instance of the dialect type, given a Python instance or kwarg
+ * description of the dialect
+ */
+static PyObject *
+_call_dialect(PyObject *dialect_inst, PyObject *kwargs)
+{
+	PyObject *ctor_args;
+	PyObject *dialect;
+
+	ctor_args = Py_BuildValue(dialect_inst ? "(O)" : "()", dialect_inst);
+	if (ctor_args == NULL)
+		return NULL;
+	dialect = PyObject_Call((PyObject *)&Dialect_Type, ctor_args, kwargs);
+	Py_DECREF(ctor_args);
+	return dialect;
+}
+
+/*
+ * READER
+ */
+static int
+parse_save_field(ReaderObj *self)
+{
+	PyObject *field;
+
+	field = PyString_FromStringAndSize(self->field, self->field_len);
+	if (field == NULL)
+		return -1;
+	self->field_len = 0;
+	if (self->numeric_field) {
+		PyObject *tmp;
+
+		self->numeric_field = 0;
+		tmp = PyNumber_Float(field);
+		if (tmp == NULL) {
+			Py_DECREF(field);
+			return -1;
+		}
+		Py_DECREF(field);
+		field = tmp;
+	}
+	PyList_Append(self->fields, field);
+	Py_DECREF(field);
+	return 0;
+}
+
+static int
+parse_grow_buff(ReaderObj *self)
+{
+	if (self->field_size == 0) {
+		self->field_size = 4096;
+		if (self->field != NULL)
+			PyMem_Free(self->field);
+		self->field = PyMem_Malloc(self->field_size);
+	}
+	else {
+		self->field_size *= 2;
+		self->field = PyMem_Realloc(self->field, self->field_size);
+	}
+	if (self->field == NULL) {
+		PyErr_NoMemory();
+		return 0;
+	}
+	return 1;
+}
+
+static int
+parse_add_char(ReaderObj *self, char c)
+{
+	if (self->field_len >= field_limit) {
+		PyErr_Format(error_obj, "field larger than field limit (%ld)",
+			     field_limit);
+		return -1;
+	}
+	if (self->field_len == self->field_size && !parse_grow_buff(self))
+		return -1;
+	self->field[self->field_len++] = c;
+	return 0;
+}
+
+static int
+parse_process_char(ReaderObj *self, char c)
+{
+        DialectObj *dialect = self->dialect;
+
+	switch (self->state) {
+	case START_RECORD:
+		/* start of record */
+		if (c == '\0')
+			/* empty line - return [] */
+			break;
+		else if (c == '\n' || c == '\r') {
+			self->state = EAT_CRNL;
+			break;
+		}
+		/* normal character - handle as START_FIELD */
+		self->state = START_FIELD;
+		/* fallthru */
+	case START_FIELD:
+		/* expecting field */
+		if (c == '\n' || c == '\r' || c == '\0') {
+			/* save empty field - return [fields] */
+			if (parse_save_field(self) < 0)
+				return -1;
+			self->state = (c == '\0' ? START_RECORD : EAT_CRNL);
+		}
+		else if (c == dialect->quotechar && 
+			 dialect->quoting != QUOTE_NONE) {
+			/* start quoted field */
+			self->state = IN_QUOTED_FIELD;
+		}
+		else if (c == dialect->escapechar) {
+			/* possible escaped character */
+			self->state = ESCAPED_CHAR;
+		}
+		else if (c == ' ' && dialect->skipinitialspace)
+			/* ignore space at start of field */
+			;
+		else if (c == dialect->delimiter) {
+			/* save empty field */
+			if (parse_save_field(self) < 0)
+				return -1;
+		}
+		else {
+			/* begin new unquoted field */
+			if (dialect->quoting == QUOTE_NONNUMERIC)
+				self->numeric_field = 1;
+			if (parse_add_char(self, c) < 0)
+				return -1;
+			self->state = IN_FIELD;
+		}
+		break;
+
+	case ESCAPED_CHAR:
+		if (c == '\0')
+			c = '\n';
+		if (parse_add_char(self, c) < 0)
+			return -1;
+		self->state = IN_FIELD;
+		break;
+
+	case IN_FIELD:
+		/* in unquoted field */
+		if (c == '\n' || c == '\r' || c == '\0') {
+			/* end of line - return [fields] */
+			if (parse_save_field(self) < 0)
+				return -1;
+			self->state = (c == '\0' ? START_RECORD : EAT_CRNL);
+		}
+		else if (c == dialect->escapechar) {
+			/* possible escaped character */
+			self->state = ESCAPED_CHAR;
+		}
+		else if (c == dialect->delimiter) {
+			/* save field - wait for new field */
+			if (parse_save_field(self) < 0)
+				return -1;
+			self->state = START_FIELD;
+		}
+		else {
+			/* normal character - save in field */
+			if (parse_add_char(self, c) < 0)
+				return -1;
+		}
+		break;
+
+	case IN_QUOTED_FIELD:
+		/* in quoted field */
+		if (c == '\0')
+			;
+		else if (c == dialect->escapechar) {
+			/* Possible escape character */
+			self->state = ESCAPE_IN_QUOTED_FIELD;
+		}
+		else if (c == dialect->quotechar &&
+			 dialect->quoting != QUOTE_NONE) {
+			if (dialect->doublequote) {
+				/* doublequote; " represented by "" */
+				self->state = QUOTE_IN_QUOTED_FIELD;
+			}
+			else {
+				/* end of quote part of field */
+				self->state = IN_FIELD;
+			}
+		}
+		else {
+			/* normal character - save in field */
+			if (parse_add_char(self, c) < 0)
+				return -1;
+		}
+		break;
+
+	case ESCAPE_IN_QUOTED_FIELD:
+		if (c == '\0')
+			c = '\n';
+		if (parse_add_char(self, c) < 0)
+			return -1;
+		self->state = IN_QUOTED_FIELD;
+		break;
+
+	case QUOTE_IN_QUOTED_FIELD:
+		/* doublequote - seen a quote in an quoted field */
+		if (dialect->quoting != QUOTE_NONE && 
+                    c == dialect->quotechar) {
+			/* save "" as " */
+			if (parse_add_char(self, c) < 0)
+				return -1;
+			self->state = IN_QUOTED_FIELD;
+		}
+		else if (c == dialect->delimiter) {
+			/* save field - wait for new field */
+			if (parse_save_field(self) < 0)
+				return -1;
+			self->state = START_FIELD;
+		}
+		else if (c == '\n' || c == '\r' || c == '\0') {
+			/* end of line - return [fields] */
+			if (parse_save_field(self) < 0)
+				return -1;
+			self->state = (c == '\0' ? START_RECORD : EAT_CRNL);
+		}
+		else if (!dialect->strict) {
+			if (parse_add_char(self, c) < 0)
+				return -1;
+			self->state = IN_FIELD;
+		}
+		else {
+			/* illegal */
+			PyErr_Format(error_obj, "'%c' expected after '%c'", 
+					dialect->delimiter, 
+                                        dialect->quotechar);
+			return -1;
+		}
+		break;
+
+	case EAT_CRNL:
+		if (c == '\n' || c == '\r')
+			;
+		else if (c == '\0')
+			self->state = START_RECORD;
+		else {
+			PyErr_Format(error_obj, "new-line character seen in unquoted field - do you need to open the file in universal-newline mode?");
+			return -1;
+		}
+		break;
+
+	}
+	return 0;
+}
+
+static int
+parse_reset(ReaderObj *self)
+{
+	Py_XDECREF(self->fields);
+	self->fields = PyList_New(0);
+	if (self->fields == NULL)
+		return -1;
+	self->field_len = 0;
+	self->state = START_RECORD;
+	self->numeric_field = 0;
+	return 0;
+}
+
+static PyObject *
+Reader_iternext(ReaderObj *self)
+{
+        PyObject *lineobj;
+        PyObject *fields = NULL;
+        char *line, c;
+	int linelen;
+
+	if (parse_reset(self) < 0)
+		return NULL;
+        do {
+                lineobj = PyIter_Next(self->input_iter);
+                if (lineobj == NULL) {
+                        /* End of input OR exception */
+                        if (!PyErr_Occurred() && self->field_len != 0)
+                                PyErr_Format(error_obj,
+					     "newline inside string");
+                        return NULL;
+                }
+		++self->line_num;
+
+                line = PyString_AsString(lineobj);
+		linelen = PyString_Size(lineobj);
+
+                if (line == NULL || linelen < 0) {
+                        Py_DECREF(lineobj);
+                        return NULL;
+                }
+                while (linelen--) {
+			c = *line++;
+			if (c == '\0') {
+				Py_DECREF(lineobj);
+				PyErr_Format(error_obj,
+					     "line contains NULL byte");
+				goto err;
+			}
+			if (parse_process_char(self, c) < 0) {
+				Py_DECREF(lineobj);
+				goto err;
+			}
+		}
+                Py_DECREF(lineobj);
+		if (parse_process_char(self, 0) < 0)
+			goto err;
+        } while (self->state != START_RECORD);
+
+        fields = self->fields;
+        self->fields = NULL;
+err:
+        return fields;
+}
+
+static void
+Reader_dealloc(ReaderObj *self)
+{
+	PyObject_GC_UnTrack(self);
+        Py_XDECREF(self->dialect);
+        Py_XDECREF(self->input_iter);
+        Py_XDECREF(self->fields);
+        if (self->field != NULL)
+        	PyMem_Free(self->field);
+	PyObject_GC_Del(self);
+}
+
+static int
+Reader_traverse(ReaderObj *self, visitproc visit, void *arg)
+{
+	Py_VISIT(self->dialect);
+	Py_VISIT(self->input_iter);
+	Py_VISIT(self->fields);
+	return 0;
+}
+
+static int
+Reader_clear(ReaderObj *self)
+{
+	Py_CLEAR(self->dialect);
+	Py_CLEAR(self->input_iter);
+	Py_CLEAR(self->fields);
+	return 0;
+}
+
+PyDoc_STRVAR(Reader_Type_doc,
+"CSV reader\n"
+"\n"
+"Reader objects are responsible for reading and parsing tabular data\n"
+"in CSV format.\n"
+);
+
+static struct PyMethodDef Reader_methods[] = {
+	{ NULL, NULL }
+};
+#define R_OFF(x) offsetof(ReaderObj, x)
+
+static struct PyMemberDef Reader_memberlist[] = {
+	{ "dialect", T_OBJECT, R_OFF(dialect), RO },
+	{ "line_num", T_ULONG, R_OFF(line_num), RO },
+	{ NULL }
+};
+
+
+static PyTypeObject Reader_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0,                                      /*ob_size*/
+	"_csv.reader",                          /*tp_name*/
+	sizeof(ReaderObj),                      /*tp_basicsize*/
+	0,                                      /*tp_itemsize*/
+	/* methods */
+	(destructor)Reader_dealloc,             /*tp_dealloc*/
+	(printfunc)0,                           /*tp_print*/
+	(getattrfunc)0,                         /*tp_getattr*/
+	(setattrfunc)0,                         /*tp_setattr*/
+	(cmpfunc)0,                             /*tp_compare*/
+	(reprfunc)0,                            /*tp_repr*/
+	0,                                      /*tp_as_number*/
+	0,                                      /*tp_as_sequence*/
+	0,                                      /*tp_as_mapping*/
+	(hashfunc)0,                            /*tp_hash*/
+	(ternaryfunc)0,                         /*tp_call*/
+	(reprfunc)0,                    	/*tp_str*/
+	0,                                      /*tp_getattro*/
+        0,                                      /*tp_setattro*/
+        0,                                      /*tp_as_buffer*/
+        Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
+		Py_TPFLAGS_HAVE_GC,		/*tp_flags*/
+	Reader_Type_doc,                        /*tp_doc*/
+        (traverseproc)Reader_traverse,          /*tp_traverse*/
+        (inquiry)Reader_clear,                  /*tp_clear*/
+        0,                                      /*tp_richcompare*/
+        0,                                      /*tp_weaklistoffset*/
+        PyObject_SelfIter,		        /*tp_iter*/
+        (getiterfunc)Reader_iternext,           /*tp_iternext*/
+        Reader_methods,                         /*tp_methods*/
+        Reader_memberlist,                      /*tp_members*/
+        0,                                      /*tp_getset*/
+
+};
+
+static PyObject *
+csv_reader(PyObject *module, PyObject *args, PyObject *keyword_args)
+{
+	PyObject * iterator, * dialect = NULL;
+        ReaderObj * self = PyObject_GC_New(ReaderObj, &Reader_Type);
+
+        if (!self)
+                return NULL;
+
+        self->dialect = NULL;
+        self->fields = NULL;
+        self->input_iter = NULL;
+	self->field = NULL;
+	self->field_size = 0;
+	self->line_num = 0;
+
+	if (parse_reset(self) < 0) {
+                Py_DECREF(self);
+                return NULL;
+	}
+
+	if (!PyArg_UnpackTuple(args, "", 1, 2, &iterator, &dialect)) {
+                Py_DECREF(self);
+                return NULL;
+        }
+        self->input_iter = PyObject_GetIter(iterator);
+        if (self->input_iter == NULL) {
+                PyErr_SetString(PyExc_TypeError, 
+                                "argument 1 must be an iterator");
+                Py_DECREF(self);
+                return NULL;
+        }
+	self->dialect = (DialectObj *)_call_dialect(dialect, keyword_args);
+        if (self->dialect == NULL) {
+                Py_DECREF(self);
+                return NULL;
+        }
+
+	PyObject_GC_Track(self);
+        return (PyObject *)self;
+}
+
+/*
+ * WRITER
+ */
+/* ---------------------------------------------------------------- */
+static void
+join_reset(WriterObj *self)
+{
+	self->rec_len = 0;
+	self->num_fields = 0;
+}
+
+#define MEM_INCR 32768
+
+/* Calculate new record length or append field to record.  Return new
+ * record length.
+ */
+static int
+join_append_data(WriterObj *self, char *field, int quote_empty,
+		 int *quoted, int copy_phase)
+{
+        DialectObj *dialect = self->dialect;
+	int i, rec_len;
+	char *lineterm;
+
+#define ADDCH(c) \
+	do {\
+		if (copy_phase) \
+			self->rec[rec_len] = c;\
+		rec_len++;\
+	} while(0)
+
+	lineterm = PyString_AsString(dialect->lineterminator);
+	if (lineterm == NULL)
+		return -1;
+
+	rec_len = self->rec_len;
+
+	/* If this is not the first field we need a field separator */
+	if (self->num_fields > 0)
+		ADDCH(dialect->delimiter);
+
+	/* Handle preceding quote */
+	if (copy_phase && *quoted)
+		ADDCH(dialect->quotechar);
+
+	/* Copy/count field data */
+	for (i = 0;; i++) {
+		char c = field[i];
+		int want_escape = 0;
+
+		if (c == '\0')
+			break;
+
+		if (c == dialect->delimiter ||
+		    c == dialect->escapechar ||
+		    c == dialect->quotechar ||
+		    strchr(lineterm, c)) {
+			if (dialect->quoting == QUOTE_NONE)
+				want_escape = 1;
+			else {
+				if (c == dialect->quotechar) {
+					if (dialect->doublequote)
+						ADDCH(dialect->quotechar);
+					else
+						want_escape = 1;
+				}
+				if (!want_escape)
+					*quoted = 1;
+			}
+			if (want_escape) {
+				if (!dialect->escapechar) {
+					PyErr_Format(error_obj, 
+						     "need to escape, but no escapechar set");
+					return -1;
+				}
+				ADDCH(dialect->escapechar);
+			}
+		}
+		/* Copy field character into record buffer.
+		 */
+		ADDCH(c);
+	}
+
+	/* If field is empty check if it needs to be quoted.
+	 */
+	if (i == 0 && quote_empty) {
+		if (dialect->quoting == QUOTE_NONE) {
+			PyErr_Format(error_obj,
+                                     "single empty field record must be quoted");
+			return -1;
+		}
+		else
+			*quoted = 1;
+	}
+
+	if (*quoted) {
+		if (copy_phase)
+			ADDCH(dialect->quotechar);
+		else
+			rec_len += 2;
+	}
+	return rec_len;
+#undef ADDCH
+}
+
+static int
+join_check_rec_size(WriterObj *self, int rec_len)
+{
+	if (rec_len > self->rec_size) {
+		if (self->rec_size == 0) {
+			self->rec_size = (rec_len / MEM_INCR + 1) * MEM_INCR;
+			if (self->rec != NULL)
+				PyMem_Free(self->rec);
+			self->rec = PyMem_Malloc(self->rec_size);
+		}
+		else {
+			char *old_rec = self->rec;
+
+			self->rec_size = (rec_len / MEM_INCR + 1) * MEM_INCR;
+			self->rec = PyMem_Realloc(self->rec, self->rec_size);
+			if (self->rec == NULL)
+				PyMem_Free(old_rec);
+		}
+		if (self->rec == NULL) {
+			PyErr_NoMemory();
+			return 0;
+		}
+	}
+	return 1;
+}
+
+static int
+join_append(WriterObj *self, char *field, int *quoted, int quote_empty)
+{
+	int rec_len;
+
+	rec_len = join_append_data(self, field, quote_empty, quoted, 0);
+	if (rec_len < 0)
+		return 0;
+
+	/* grow record buffer if necessary */
+	if (!join_check_rec_size(self, rec_len))
+		return 0;
+
+	self->rec_len = join_append_data(self, field, quote_empty, quoted, 1);
+	self->num_fields++;
+
+	return 1;
+}
+
+static int
+join_append_lineterminator(WriterObj *self)
+{
+	int terminator_len;
+	char *terminator;
+
+	terminator_len = PyString_Size(self->dialect->lineterminator);
+	if (terminator_len == -1)
+		return 0;
+
+	/* grow record buffer if necessary */
+	if (!join_check_rec_size(self, self->rec_len + terminator_len))
+		return 0;
+
+	terminator = PyString_AsString(self->dialect->lineterminator); 
+	if (terminator == NULL)
+		return 0;
+	memmove(self->rec + self->rec_len, terminator, terminator_len);
+	self->rec_len += terminator_len;
+
+	return 1;
+}
+
+PyDoc_STRVAR(csv_writerow_doc,
+"writerow(sequence)\n"
+"\n"
+"Construct and write a CSV record from a sequence of fields.  Non-string\n"
+"elements will be converted to string.");
+
+static PyObject *
+csv_writerow(WriterObj *self, PyObject *seq)
+{
+        DialectObj *dialect = self->dialect;
+	int len, i;
+
+	if (!PySequence_Check(seq))
+		return PyErr_Format(error_obj, "sequence expected");
+
+	len = PySequence_Length(seq);
+	if (len < 0)
+		return NULL;
+
+	/* Join all fields in internal buffer.
+	 */
+	join_reset(self);
+	for (i = 0; i < len; i++) {
+		PyObject *field;
+		int append_ok;
+		int quoted;
+
+		field = PySequence_GetItem(seq, i);
+		if (field == NULL)
+			return NULL;
+
+		switch (dialect->quoting) {
+		case QUOTE_NONNUMERIC:
+			quoted = !PyNumber_Check(field);
+			break;
+		case QUOTE_ALL:
+			quoted = 1;
+			break;
+		default:
+			quoted = 0;
+			break;
+		}
+
+		if (PyString_Check(field)) {
+			append_ok = join_append(self,
+						PyString_AS_STRING(field),
+                                                &quoted, len == 1);
+			Py_DECREF(field);
+		}
+		else if (field == Py_None) {
+			append_ok = join_append(self, "", &quoted, len == 1);
+			Py_DECREF(field);
+		}
+		else {
+			PyObject *str;
+
+			str = PyObject_Str(field);
+			Py_DECREF(field);
+			if (str == NULL)
+				return NULL;
+
+			append_ok = join_append(self, PyString_AS_STRING(str), 
+                                                &quoted, len == 1);
+			Py_DECREF(str);
+		}
+		if (!append_ok)
+			return NULL;
+	}
+
+	/* Add line terminator.
+	 */
+	if (!join_append_lineterminator(self))
+		return 0;
+
+	return PyObject_CallFunction(self->writeline, 
+                                     "(s#)", self->rec, self->rec_len);
+}
+
+PyDoc_STRVAR(csv_writerows_doc,
+"writerows(sequence of sequences)\n"
+"\n"
+"Construct and write a series of sequences to a csv file.  Non-string\n"
+"elements will be converted to string.");
+
+static PyObject *
+csv_writerows(WriterObj *self, PyObject *seqseq)
+{
+        PyObject *row_iter, *row_obj, *result;
+
+        row_iter = PyObject_GetIter(seqseq);
+        if (row_iter == NULL) {
+                PyErr_SetString(PyExc_TypeError,
+                                "writerows() argument must be iterable");
+                return NULL;
+        }
+        while ((row_obj = PyIter_Next(row_iter))) {
+                result = csv_writerow(self, row_obj);
+                Py_DECREF(row_obj);
+                if (!result) {
+                        Py_DECREF(row_iter);
+                        return NULL;
+                }
+                else
+                     Py_DECREF(result);   
+        }
+        Py_DECREF(row_iter);
+        if (PyErr_Occurred())
+                return NULL;
+        Py_INCREF(Py_None);
+        return Py_None;
+}
+
+static struct PyMethodDef Writer_methods[] = {
+        { "writerow", (PyCFunction)csv_writerow, METH_O, csv_writerow_doc},
+        { "writerows", (PyCFunction)csv_writerows, METH_O, csv_writerows_doc},
+	{ NULL, NULL }
+};
+
+#define W_OFF(x) offsetof(WriterObj, x)
+
+static struct PyMemberDef Writer_memberlist[] = {
+	{ "dialect", T_OBJECT, W_OFF(dialect), RO },
+	{ NULL }
+};
+
+static void
+Writer_dealloc(WriterObj *self)
+{
+	PyObject_GC_UnTrack(self);
+        Py_XDECREF(self->dialect);
+        Py_XDECREF(self->writeline);
+	if (self->rec != NULL)
+		PyMem_Free(self->rec);
+	PyObject_GC_Del(self);
+}
+
+static int
+Writer_traverse(WriterObj *self, visitproc visit, void *arg)
+{
+	Py_VISIT(self->dialect);
+	Py_VISIT(self->writeline);
+	return 0;
+}
+
+static int
+Writer_clear(WriterObj *self)
+{
+	Py_CLEAR(self->dialect);
+	Py_CLEAR(self->writeline);
+	return 0;
+}
+
+PyDoc_STRVAR(Writer_Type_doc, 
+"CSV writer\n"
+"\n"
+"Writer objects are responsible for generating tabular data\n"
+"in CSV format from sequence input.\n"
+);
+
+static PyTypeObject Writer_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0,                                      /*ob_size*/
+	"_csv.writer",                          /*tp_name*/
+	sizeof(WriterObj),                      /*tp_basicsize*/
+	0,                                      /*tp_itemsize*/
+	/* methods */
+	(destructor)Writer_dealloc,             /*tp_dealloc*/
+	(printfunc)0,                           /*tp_print*/
+	(getattrfunc)0,                         /*tp_getattr*/
+	(setattrfunc)0,                         /*tp_setattr*/
+	(cmpfunc)0,                             /*tp_compare*/
+	(reprfunc)0,                            /*tp_repr*/
+	0,                                      /*tp_as_number*/
+	0,                                      /*tp_as_sequence*/
+	0,                                      /*tp_as_mapping*/
+	(hashfunc)0,                            /*tp_hash*/
+	(ternaryfunc)0,                         /*tp_call*/
+	(reprfunc)0,                            /*tp_str*/
+	0,                                      /*tp_getattro*/
+        0,                                      /*tp_setattro*/
+        0,                                      /*tp_as_buffer*/
+        Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
+		Py_TPFLAGS_HAVE_GC,		/*tp_flags*/
+	Writer_Type_doc,
+        (traverseproc)Writer_traverse,          /*tp_traverse*/
+        (inquiry)Writer_clear,                  /*tp_clear*/
+        0,                                      /*tp_richcompare*/
+        0,                                      /*tp_weaklistoffset*/
+        (getiterfunc)0,                         /*tp_iter*/
+        (getiterfunc)0,                         /*tp_iternext*/
+        Writer_methods,                         /*tp_methods*/
+        Writer_memberlist,                      /*tp_members*/
+        0,                                      /*tp_getset*/
+};
+
+static PyObject *
+csv_writer(PyObject *module, PyObject *args, PyObject *keyword_args)
+{
+	PyObject * output_file, * dialect = NULL;
+        WriterObj * self = PyObject_GC_New(WriterObj, &Writer_Type);
+
+        if (!self)
+                return NULL;
+
+        self->dialect = NULL;
+        self->writeline = NULL;
+
+	self->rec = NULL;
+	self->rec_size = 0;
+	self->rec_len = 0;
+	self->num_fields = 0;
+
+	if (!PyArg_UnpackTuple(args, "", 1, 2, &output_file, &dialect)) {
+                Py_DECREF(self);
+                return NULL;
+        }
+        self->writeline = PyObject_GetAttrString(output_file, "write");
+        if (self->writeline == NULL || !PyCallable_Check(self->writeline)) {
+                PyErr_SetString(PyExc_TypeError,
+                                "argument 1 must have a \"write\" method");
+                Py_DECREF(self);
+                return NULL;
+        }
+	self->dialect = (DialectObj *)_call_dialect(dialect, keyword_args);
+        if (self->dialect == NULL) {
+                Py_DECREF(self);
+                return NULL;
+        }
+	PyObject_GC_Track(self);
+        return (PyObject *)self;
+}
+
+/*
+ * DIALECT REGISTRY
+ */
+static PyObject *
+csv_list_dialects(PyObject *module, PyObject *args)
+{
+        return PyDict_Keys(dialects);
+}
+
+static PyObject *
+csv_register_dialect(PyObject *module, PyObject *args, PyObject *kwargs)
+{
+	PyObject *name_obj, *dialect_obj = NULL;
+	PyObject *dialect;
+
+	if (!PyArg_UnpackTuple(args, "", 1, 2, &name_obj, &dialect_obj))
+                return NULL;
+        if (!IS_BASESTRING(name_obj)) {
+                PyErr_SetString(PyExc_TypeError, 
+                                "dialect name must be a string or unicode");
+                return NULL;
+        }
+	dialect = _call_dialect(dialect_obj, kwargs);
+	if (dialect == NULL)
+		return NULL;
+	if (PyDict_SetItem(dialects, name_obj, dialect) < 0) {
+		Py_DECREF(dialect);
+                return NULL;
+        }
+	Py_DECREF(dialect);
+        Py_INCREF(Py_None);
+        return Py_None;
+}
+
+static PyObject *
+csv_unregister_dialect(PyObject *module, PyObject *name_obj)
+{
+        if (PyDict_DelItem(dialects, name_obj) < 0)
+                return PyErr_Format(error_obj, "unknown dialect");
+        Py_INCREF(Py_None);
+        return Py_None;
+}
+
+static PyObject *
+csv_get_dialect(PyObject *module, PyObject *name_obj)
+{
+        return get_dialect_from_registry(name_obj);
+}
+
+static PyObject *
+csv_field_size_limit(PyObject *module, PyObject *args)
+{
+	PyObject *new_limit = NULL;
+	long old_limit = field_limit;
+
+	if (!PyArg_UnpackTuple(args, "field_size_limit", 0, 1, &new_limit))
+		return NULL;
+	if (new_limit != NULL) {
+		if (!PyInt_Check(new_limit)) {
+			PyErr_Format(PyExc_TypeError, 
+				     "limit must be an integer");
+			return NULL;
+		}
+		field_limit = PyInt_AsLong(new_limit);
+	}
+	return PyInt_FromLong(old_limit);
+}
+
+/*
+ * MODULE
+ */
+
+PyDoc_STRVAR(csv_module_doc,
+"CSV parsing and writing.\n"
+"\n"
+"This module provides classes that assist in the reading and writing\n"
+"of Comma Separated Value (CSV) files, and implements the interface\n"
+"described by PEP 305.  Although many CSV files are simple to parse,\n"
+"the format is not formally defined by a stable specification and\n"
+"is subtle enough that parsing lines of a CSV file with something\n"
+"like line.split(\",\") is bound to fail.  The module supports three\n"
+"basic APIs: reading, writing, and registration of dialects.\n"
+"\n"
+"\n"
+"DIALECT REGISTRATION:\n"
+"\n"
+"Readers and writers support a dialect argument, which is a convenient\n"
+"handle on a group of settings.  When the dialect argument is a string,\n"
+"it identifies one of the dialects previously registered with the module.\n"
+"If it is a class or instance, the attributes of the argument are used as\n"
+"the settings for the reader or writer:\n"
+"\n"
+"    class excel:\n"
+"        delimiter = ','\n"
+"        quotechar = '\"'\n"
+"        escapechar = None\n"
+"        doublequote = True\n"
+"        skipinitialspace = False\n"
+"        lineterminator = '\\r\\n'\n"
+"        quoting = QUOTE_MINIMAL\n"
+"\n"
+"SETTINGS:\n"
+"\n"
+"    * quotechar - specifies a one-character string to use as the \n"
+"        quoting character.  It defaults to '\"'.\n"
+"    * delimiter - specifies a one-character string to use as the \n"
+"        field separator.  It defaults to ','.\n"
+"    * skipinitialspace - specifies how to interpret whitespace which\n"
+"        immediately follows a delimiter.  It defaults to False, which\n"
+"        means that whitespace immediately following a delimiter is part\n"
+"        of the following field.\n"
+"    * lineterminator -  specifies the character sequence which should \n"
+"        terminate rows.\n"
+"    * quoting - controls when quotes should be generated by the writer.\n"
+"        It can take on any of the following module constants:\n"
+"\n"
+"        csv.QUOTE_MINIMAL means only when required, for example, when a\n"
+"            field contains either the quotechar or the delimiter\n"
+"        csv.QUOTE_ALL means that quotes are always placed around fields.\n"
+"        csv.QUOTE_NONNUMERIC means that quotes are always placed around\n"
+"            fields which do not parse as integers or floating point\n"
+"            numbers.\n"
+"        csv.QUOTE_NONE means that quotes are never placed around fields.\n"
+"    * escapechar - specifies a one-character string used to escape \n"
+"        the delimiter when quoting is set to QUOTE_NONE.\n"
+"    * doublequote - controls the handling of quotes inside fields.  When\n"
+"        True, two consecutive quotes are interpreted as one during read,\n"
+"        and when writing, each quote character embedded in the data is\n"
+"        written as two quotes\n");
+
+PyDoc_STRVAR(csv_reader_doc,
+"    csv_reader = reader(iterable [, dialect='excel']\n"
+"                        [optional keyword args])\n"
+"    for row in csv_reader:\n"
+"        process(row)\n"
+"\n"
+"The \"iterable\" argument can be any object that returns a line\n"
+"of input for each iteration, such as a file object or a list.  The\n"
+"optional \"dialect\" parameter is discussed below.  The function\n"
+"also accepts optional keyword arguments which override settings\n"
+"provided by the dialect.\n"
+"\n"
+"The returned object is an iterator.  Each iteration returns a row\n"
+"of the CSV file (which can span multiple input lines):\n");
+
+PyDoc_STRVAR(csv_writer_doc,
+"    csv_writer = csv.writer(fileobj [, dialect='excel']\n"
+"                            [optional keyword args])\n"
+"    for row in sequence:\n"
+"        csv_writer.writerow(row)\n"
+"\n"
+"    [or]\n"
+"\n"
+"    csv_writer = csv.writer(fileobj [, dialect='excel']\n"
+"                            [optional keyword args])\n"
+"    csv_writer.writerows(rows)\n"
+"\n"
+"The \"fileobj\" argument can be any object that supports the file API.\n");
+
+PyDoc_STRVAR(csv_list_dialects_doc,
+"Return a list of all know dialect names.\n"
+"    names = csv.list_dialects()");
+
+PyDoc_STRVAR(csv_get_dialect_doc,
+"Return the dialect instance associated with name.\n"
+"    dialect = csv.get_dialect(name)");
+
+PyDoc_STRVAR(csv_register_dialect_doc,
+"Create a mapping from a string name to a dialect class.\n"
+"    dialect = csv.register_dialect(name, dialect)");
+
+PyDoc_STRVAR(csv_unregister_dialect_doc,
+"Delete the name/dialect mapping associated with a string name.\n"
+"    csv.unregister_dialect(name)");
+
+PyDoc_STRVAR(csv_field_size_limit_doc,
+"Sets an upper limit on parsed fields.\n"
+"    csv.field_size_limit([limit])\n"
+"\n"
+"Returns old limit. If limit is not given, no new limit is set and\n"
+"the old limit is returned");
+
+static struct PyMethodDef csv_methods[] = {
+	{ "reader", (PyCFunction)csv_reader, 
+		METH_VARARGS | METH_KEYWORDS, csv_reader_doc},
+	{ "writer", (PyCFunction)csv_writer, 
+		METH_VARARGS | METH_KEYWORDS, csv_writer_doc},
+	{ "list_dialects", (PyCFunction)csv_list_dialects, 
+		METH_NOARGS, csv_list_dialects_doc},
+	{ "register_dialect", (PyCFunction)csv_register_dialect, 
+		METH_VARARGS | METH_KEYWORDS, csv_register_dialect_doc},
+	{ "unregister_dialect", (PyCFunction)csv_unregister_dialect, 
+		METH_O, csv_unregister_dialect_doc},
+	{ "get_dialect", (PyCFunction)csv_get_dialect, 
+		METH_O, csv_get_dialect_doc},
+	{ "field_size_limit", (PyCFunction)csv_field_size_limit, 
+		METH_VARARGS, csv_field_size_limit_doc},
+	{ NULL, NULL }
+};
+
+PyMODINIT_FUNC
+init_csv(void)
+{
+	PyObject *module;
+	StyleDesc *style;
+
+	if (PyType_Ready(&Dialect_Type) < 0)
+		return;
+
+	if (PyType_Ready(&Reader_Type) < 0)
+		return;
+
+	if (PyType_Ready(&Writer_Type) < 0)
+		return;
+
+	/* Create the module and add the functions */
+	module = Py_InitModule3("_csv", csv_methods, csv_module_doc);
+	if (module == NULL)
+		return;
+
+	/* Add version to the module. */
+	if (PyModule_AddStringConstant(module, "__version__",
+				       MODULE_VERSION) == -1)
+		return;
+
+        /* Add _dialects dictionary */
+        dialects = PyDict_New();
+        if (dialects == NULL)
+                return;
+        if (PyModule_AddObject(module, "_dialects", dialects))
+                return;
+
+	/* Add quote styles into dictionary */
+	for (style = quote_styles; style->name; style++) {
+		if (PyModule_AddIntConstant(module, style->name,
+					    style->style) == -1)
+			return;
+	}
+
+        /* Add the Dialect type */
+	Py_INCREF(&Dialect_Type);
+        if (PyModule_AddObject(module, "Dialect", (PyObject *)&Dialect_Type))
+                return;
+
+	/* Add the CSV exception object to the module. */
+	error_obj = PyErr_NewException("_csv.Error", NULL, NULL);
+	if (error_obj == NULL)
+		return;
+	PyModule_AddObject(module, "Error", error_obj);
+}

Added: vendor/Python/current/Modules/_ctypes/_ctypes.c
===================================================================
--- vendor/Python/current/Modules/_ctypes/_ctypes.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/_ctypes.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,4859 @@
+/*****************************************************************
+  This file should be kept compatible with Python 2.3, see PEP 291.
+ *****************************************************************/
+
+
+/*
+  ToDo:
+
+  Get rid of the checker (and also the converters) field in CFuncPtrObject and
+  StgDictObject, and replace them by slot functions in StgDictObject.
+
+  think about a buffer-like object (memory? bytes?)
+
+  Should POINTER(c_char) and POINTER(c_wchar) have a .value property?
+  What about c_char and c_wchar arrays then?
+
+  Add from_mmap, from_file, from_string metaclass methods.
+
+  Maybe we can get away with from_file (calls read) and with a from_buffer
+  method?
+
+  And what about the to_mmap, to_file, to_str(?) methods?  They would clobber
+  the namespace, probably. So, functions instead? And we already have memmove...
+*/
+
+/*
+
+Name			methods, members, getsets
+==============================================================================
+
+StructType_Type		__new__(), from_address(), __mul__(), from_param()
+UnionType_Type		__new__(), from_address(), __mul__(), from_param()
+PointerType_Type	__new__(), from_address(), __mul__(), from_param(), set_type()
+ArrayType_Type		__new__(), from_address(), __mul__(), from_param()
+SimpleType_Type		__new__(), from_address(), __mul__(), from_param()
+
+CData_Type
+  Struct_Type		__new__(), __init__()
+  Pointer_Type		__new__(), __init__(), _as_parameter_, contents
+  Array_Type		__new__(), __init__(), _as_parameter_, __get/setitem__(), __len__()
+  Simple_Type		__new__(), __init__(), _as_parameter_
+
+CField_Type
+StgDict_Type
+
+==============================================================================
+
+class methods
+-------------
+
+It has some similarity to the byref() construct compared to pointer()
+from_address(addr)
+	- construct an instance from a given memory block (sharing this memory block)
+
+from_param(obj)
+	- typecheck and convert a Python object into a C function call parameter
+	  the result may be an instance of the type, or an integer or tuple
+	  (typecode, value[, obj])
+
+instance methods/properties
+---------------------------
+
+_as_parameter_
+	- convert self into a C function call parameter
+	  This is either an integer, or a 3-tuple (typecode, value, obj)
+
+functions
+---------
+
+sizeof(cdata)
+	- return the number of bytes the buffer contains
+
+sizeof(ctype)
+	- return the number of bytes the buffer of an instance would contain
+
+byref(cdata)
+
+addressof(cdata)
+
+pointer(cdata)
+
+POINTER(ctype)
+
+bytes(cdata)
+	- return the buffer contents as a sequence of bytes (which is currently a string)
+
+*/
+
+/*
+ * StgDict_Type
+ * StructType_Type
+ * UnionType_Type
+ * PointerType_Type
+ * ArrayType_Type
+ * SimpleType_Type
+ *
+ * CData_Type
+ * Struct_Type
+ * Union_Type
+ * Array_Type
+ * Simple_Type
+ * Pointer_Type
+ * CField_Type
+ *
+ */
+
+#include "Python.h"
+#include "structmember.h"
+
+#include <ffi.h>
+#ifdef MS_WIN32
+#include <windows.h>
+#include <malloc.h>
+#ifndef IS_INTRESOURCE
+#define IS_INTRESOURCE(x) (((size_t)(x) >> 16) == 0)
+#endif
+# ifdef _WIN32_WCE
+/* Unlike desktop Windows, WinCE has both W and A variants of
+   GetProcAddress, but the default W version is not what we want */
+#  undef GetProcAddress
+#  define GetProcAddress GetProcAddressA
+# endif
+#else
+#include "ctypes_dlfcn.h"
+#endif
+#include "ctypes.h"
+
+PyObject *PyExc_ArgError;
+static PyTypeObject Simple_Type;
+
+char *conversion_mode_encoding = NULL;
+char *conversion_mode_errors = NULL;
+
+
+/******************************************************************/
+/*
+  StructType_Type - a meta type/class.  Creating a new class using this one as
+  __metaclass__ will call the contructor StructUnionType_new.  It replaces the
+  tp_dict member with a new instance of StgDict, and initializes the C
+  accessible fields somehow.
+*/
+
+static PyCArgObject *
+StructUnionType_paramfunc(CDataObject *self)
+{
+	PyCArgObject *parg;
+	StgDictObject *stgdict;
+	
+	parg = new_CArgObject();
+	if (parg == NULL)
+		return NULL;
+
+	parg->tag = 'V';
+	stgdict = PyObject_stgdict((PyObject *)self);
+	assert(stgdict); /* Cannot be NULL for structure/union instances */
+	parg->pffi_type = &stgdict->ffi_type_pointer;
+	/* For structure parameters (by value), parg->value doesn't contain the structure
+	   data itself, instead parg->value.p *points* to the structure's data
+	   See also _ctypes.c, function _call_function_pointer().
+	*/
+	parg->value.p = self->b_ptr;
+	parg->size = self->b_size;
+	Py_INCREF(self);
+	parg->obj = (PyObject *)self;
+	return parg;	
+}
+
+static PyObject *
+StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isStruct)
+{
+	PyTypeObject *result;
+	PyObject *fields;
+	StgDictObject *dict;
+
+	/* create the new instance (which is a class,
+	   since we are a metatype!) */
+	result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
+	if (!result)
+		return NULL;
+
+	/* keep this for bw compatibility */
+	if (PyDict_GetItemString(result->tp_dict, "_abstract_"))
+		return (PyObject *)result;
+
+	dict = (StgDictObject *)PyObject_CallObject((PyObject *)&StgDict_Type, NULL);
+	if (!dict) {
+		Py_DECREF(result);
+		return NULL;
+	}
+	/* replace the class dict by our updated stgdict, which holds info
+	   about storage requirements of the instances */
+	if (-1 == PyDict_Update((PyObject *)dict, result->tp_dict)) {
+		Py_DECREF(result);
+		Py_DECREF((PyObject *)dict);
+		return NULL;
+	}
+	Py_DECREF(result->tp_dict);
+	result->tp_dict = (PyObject *)dict;
+
+	dict->paramfunc = StructUnionType_paramfunc;
+
+	fields = PyDict_GetItemString((PyObject *)dict, "_fields_");
+	if (!fields) {
+		StgDictObject *basedict = PyType_stgdict((PyObject *)result->tp_base);
+
+		if (basedict == NULL)
+			return (PyObject *)result;
+		/* copy base dict */
+		if (-1 == StgDict_clone(dict, basedict)) {
+			Py_DECREF(result);
+			return NULL;
+		}
+		dict->flags &= ~DICTFLAG_FINAL; /* clear the 'final' flag in the subclass dict */
+		basedict->flags |= DICTFLAG_FINAL; /* set the 'final' flag in the baseclass dict */
+		return (PyObject *)result;
+	}
+
+	if (-1 == PyObject_SetAttrString((PyObject *)result, "_fields_", fields)) {
+		Py_DECREF(result);
+		return NULL;
+	}
+	return (PyObject *)result;
+}
+
+static PyObject *
+StructType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	return StructUnionType_new(type, args, kwds, 1);
+}
+
+static PyObject *
+UnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	return StructUnionType_new(type, args, kwds, 0);
+}
+
+static char from_address_doc[] =
+"C.from_address(integer) -> C instance\naccess a C instance at the specified address";
+
+static PyObject *
+CDataType_from_address(PyObject *type, PyObject *value)
+{
+	void *buf;
+	if (!PyInt_Check(value) && !PyLong_Check(value)) {
+		PyErr_SetString(PyExc_TypeError,
+				"integer expected");
+		return NULL;
+	}
+	buf = (void *)PyLong_AsVoidPtr(value);
+	if (PyErr_Occurred())
+		return NULL;
+	return CData_AtAddress(type, buf);
+}
+
+static char in_dll_doc[] =
+"C.in_dll(dll, name) -> C instance\naccess a C instance in a dll";
+
+static PyObject *
+CDataType_in_dll(PyObject *type, PyObject *args)
+{
+	PyObject *dll;
+	char *name;
+	PyObject *obj;
+	void *handle;
+	void *address;
+
+	if (!PyArg_ParseTuple(args, "Os:in_dll", &dll, &name))
+		return NULL;
+
+	obj = PyObject_GetAttrString(dll, "_handle");
+	if (!obj)
+		return NULL;
+	if (!PyInt_Check(obj) && !PyLong_Check(obj)) {
+		PyErr_SetString(PyExc_TypeError,
+				"the _handle attribute of the second argument must be an integer");
+		Py_DECREF(obj);
+		return NULL;
+	}
+	handle = (void *)PyLong_AsVoidPtr(obj);
+	Py_DECREF(obj);
+	if (PyErr_Occurred()) {
+		PyErr_SetString(PyExc_ValueError,
+				"could not convert the _handle attribute to a pointer");
+		return NULL;
+	}
+
+#ifdef MS_WIN32
+	address = (void *)GetProcAddress(handle, name);
+	if (!address) {
+		PyErr_Format(PyExc_ValueError,
+			     "symbol '%s' not found",
+			     name);
+		return NULL;
+	}
+#else
+	address = (void *)ctypes_dlsym(handle, name);
+	if (!address) {
+		PyErr_Format(PyExc_ValueError,
+#ifdef __CYGWIN__
+/* dlerror() isn't very helpful on cygwin */
+			     "symbol '%s' not found (%s) ",
+			     name,
+#endif
+			     ctypes_dlerror());
+		return NULL;
+	}
+#endif
+	return CData_AtAddress(type, address);
+}
+
+static char from_param_doc[] =
+"Convert a Python object into a function call parameter.";
+
+static PyObject *
+CDataType_from_param(PyObject *type, PyObject *value)
+{
+	PyObject *as_parameter;
+	if (1 == PyObject_IsInstance(value, type)) {
+		Py_INCREF(value);
+		return value;
+	}
+	if (PyCArg_CheckExact(value)) {
+		PyCArgObject *p = (PyCArgObject *)value;
+		PyObject *ob = p->obj;
+		const char *ob_name;
+		StgDictObject *dict;
+		dict = PyType_stgdict(type);
+
+		/* If we got a PyCArgObject, we must check if the object packed in it
+		   is an instance of the type's dict->proto */
+		if(dict && ob
+		   && PyObject_IsInstance(ob, dict->proto)) {
+			Py_INCREF(value);
+			return value;
+		}
+		ob_name = (ob) ? ob->ob_type->tp_name : "???";
+		PyErr_Format(PyExc_TypeError,
+			     "expected %s instance instead of pointer to %s",
+			     ((PyTypeObject *)type)->tp_name, ob_name);
+		return NULL;
+	}
+
+	as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
+	if (as_parameter) {
+		value = CDataType_from_param(type, as_parameter);
+		Py_DECREF(as_parameter);
+		return value;
+	}
+	PyErr_Format(PyExc_TypeError,
+		     "expected %s instance instead of %s",
+		     ((PyTypeObject *)type)->tp_name,
+		     value->ob_type->tp_name);
+	return NULL;
+}
+
+static PyMethodDef CDataType_methods[] = {
+	{ "from_param", CDataType_from_param, METH_O, from_param_doc },
+	{ "from_address", CDataType_from_address, METH_O, from_address_doc },
+	{ "in_dll", CDataType_in_dll, METH_VARARGS, in_dll_doc },
+	{ NULL, NULL },
+};
+
+static PyObject *
+CDataType_repeat(PyObject *self, Py_ssize_t length)
+{
+	if (length < 0)
+		return PyErr_Format(PyExc_ValueError,
+#if (PY_VERSION_HEX < 0x02050000)
+				    "Array length must be >= 0, not %d",
+#else
+				    "Array length must be >= 0, not %zd",
+#endif
+				    length);
+	return CreateArrayType(self, length);
+}
+
+static PySequenceMethods CDataType_as_sequence = {
+	0,			/* inquiry sq_length; */
+	0,			/* binaryfunc sq_concat; */
+	CDataType_repeat,	/* intargfunc sq_repeat; */
+	0,			/* intargfunc sq_item; */
+	0,			/* intintargfunc sq_slice; */
+	0,			/* intobjargproc sq_ass_item; */
+	0,			/* intintobjargproc sq_ass_slice; */
+	0,			/* objobjproc sq_contains; */
+	
+	0,			/* binaryfunc sq_inplace_concat; */
+	0,			/* intargfunc sq_inplace_repeat; */
+};
+
+static int
+CDataType_clear(PyTypeObject *self)
+{
+	StgDictObject *dict = PyType_stgdict((PyObject *)self);
+	if (dict)
+		Py_CLEAR(dict->proto);
+	return PyType_Type.tp_clear((PyObject *)self);
+}
+
+static int
+CDataType_traverse(PyTypeObject *self, visitproc visit, void *arg)
+{
+	StgDictObject *dict = PyType_stgdict((PyObject *)self);
+	if (dict)
+		Py_VISIT(dict->proto);
+	return PyType_Type.tp_traverse((PyObject *)self, visit, arg);
+}
+
+static int
+StructType_setattro(PyObject *self, PyObject *key, PyObject *value)
+{
+	/* XXX Should we disallow deleting _fields_? */
+	if (-1 == PyObject_GenericSetAttr(self, key, value))
+		return -1;
+	
+	if (value && PyString_Check(key) &&
+	    0 == strcmp(PyString_AS_STRING(key), "_fields_"))
+		return StructUnionType_update_stgdict(self, value, 1);
+	return 0;
+}
+
+
+static int
+UnionType_setattro(PyObject *self, PyObject *key, PyObject *value)
+{
+	/* XXX Should we disallow deleting _fields_? */
+	if (-1 == PyObject_GenericSetAttr(self, key, value))
+		return -1;
+	
+	if (PyString_Check(key) &&
+	    0 == strcmp(PyString_AS_STRING(key), "_fields_"))
+		return StructUnionType_update_stgdict(self, value, 0);
+	return 0;
+}
+
+
+PyTypeObject StructType_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0,					/* ob_size */
+	"_ctypes.StructType",			/* tp_name */
+	0,					/* tp_basicsize */
+	0,					/* tp_itemsize */
+	0,					/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	0,			       		/* tp_repr */
+	0,					/* tp_as_number */
+	&CDataType_as_sequence,			/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	0,					/* tp_getattro */
+	StructType_setattro,			/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+	"metatype for the CData Objects",	/* tp_doc */
+	(traverseproc)CDataType_traverse,	/* tp_traverse */
+	(inquiry)CDataType_clear,		/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	CDataType_methods,			/* tp_methods */
+	0,					/* tp_members */
+	0,					/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	0,					/* tp_init */
+	0,					/* tp_alloc */
+	StructType_new,				/* tp_new */
+	0,					/* tp_free */
+};
+
+static PyTypeObject UnionType_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0,					/* ob_size */
+	"_ctypes.UnionType",			/* tp_name */
+	0,					/* tp_basicsize */
+	0,					/* tp_itemsize */
+	0,					/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	0,			       		/* tp_repr */
+	0,					/* tp_as_number */
+	&CDataType_as_sequence,		/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	0,					/* tp_getattro */
+	UnionType_setattro,			/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+	"metatype for the CData Objects",	/* tp_doc */
+	(traverseproc)CDataType_traverse,	/* tp_traverse */
+	(inquiry)CDataType_clear,		/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	CDataType_methods,			/* tp_methods */
+	0,					/* tp_members */
+	0,					/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	0,					/* tp_init */
+	0,					/* tp_alloc */
+	UnionType_new,				/* tp_new */
+	0,					/* tp_free */
+};
+
+
+/******************************************************************/
+
+/*
+
+The PointerType_Type metaclass must ensure that the subclass of Pointer can be
+created. It must check for a _type_ attribute in the class. Since are no
+runtime created properties, a CField is probably *not* needed ?
+
+class IntPointer(Pointer):
+    _type_ = "i"
+
+The Pointer_Type provides the functionality: a contents method/property, a
+size property/method, and the sequence protocol.
+
+*/
+
+static int
+PointerType_SetProto(StgDictObject *stgdict, PyObject *proto)
+{
+	if (!proto || !PyType_Check(proto)) {
+		PyErr_SetString(PyExc_TypeError,
+				"_type_ must be a type");
+		return -1;
+	}
+	if (!PyType_stgdict(proto)) {
+		PyErr_SetString(PyExc_TypeError,
+				"_type_ must have storage info");
+		return -1;
+	}
+	Py_INCREF(proto);
+	Py_XDECREF(stgdict->proto);
+	stgdict->proto = proto;
+	return 0;
+}
+
+static PyCArgObject *
+PointerType_paramfunc(CDataObject *self)
+{
+	PyCArgObject *parg;
+
+	parg = new_CArgObject();
+	if (parg == NULL)
+		return NULL;
+
+	parg->tag = 'P';
+	parg->pffi_type = &ffi_type_pointer;
+	Py_INCREF(self);
+	parg->obj = (PyObject *)self;
+	parg->value.p = *(void **)self->b_ptr;
+	return parg;
+}
+
+static PyObject *
+PointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	PyTypeObject *result;
+	StgDictObject *stgdict;
+	PyObject *proto;
+	PyObject *typedict;
+
+	typedict = PyTuple_GetItem(args, 2);
+	if (!typedict)
+		return NULL;
+/*
+  stgdict items size, align, length contain info about pointers itself,
+  stgdict->proto has info about the pointed to type!
+*/
+	stgdict = (StgDictObject *)PyObject_CallObject(
+		(PyObject *)&StgDict_Type, NULL);
+	if (!stgdict)
+		return NULL;
+	stgdict->size = sizeof(void *);
+	stgdict->align = getentry("P")->pffi_type->alignment;
+	stgdict->length = 1;
+	stgdict->ffi_type_pointer = ffi_type_pointer;
+	stgdict->paramfunc = PointerType_paramfunc;
+
+	proto = PyDict_GetItemString(typedict, "_type_"); /* Borrowed ref */
+	if (proto && -1 == PointerType_SetProto(stgdict, proto)) {
+		Py_DECREF((PyObject *)stgdict);
+		return NULL;
+	}
+
+	/* create the new instance (which is a class,
+	   since we are a metatype!) */
+	result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
+	if (result == NULL) {
+		Py_DECREF((PyObject *)stgdict);
+		return NULL;
+	}
+
+	/* replace the class dict by our updated spam dict */
+	if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
+		Py_DECREF(result);
+		Py_DECREF((PyObject *)stgdict);
+		return NULL;
+	}
+	Py_DECREF(result->tp_dict);
+	result->tp_dict = (PyObject *)stgdict;
+
+	return (PyObject *)result;
+}
+
+
+static PyObject *
+PointerType_set_type(PyTypeObject *self, PyObject *type)
+{
+	StgDictObject *dict;
+
+	dict = PyType_stgdict((PyObject *)self);
+	assert(dict);
+
+	if (-1 == PointerType_SetProto(dict, type))
+		return NULL;
+
+	if (-1 == PyDict_SetItemString((PyObject *)dict, "_type_", type))
+		return NULL;
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+staticforward PyObject *_byref(PyObject *);
+
+static PyObject *
+PointerType_from_param(PyObject *type, PyObject *value)
+{
+	StgDictObject *typedict;
+
+	if (value == Py_None)
+		return PyInt_FromLong(0); /* NULL pointer */
+
+	typedict = PyType_stgdict(type);
+	assert(typedict); /* Cannot be NULL for pointer types */
+
+	/* If we expect POINTER(<type>), but receive a <type> instance, accept
+	   it by calling byref(<type>).
+	*/
+	switch (PyObject_IsInstance(value, typedict->proto)) {
+	case 1:
+		Py_INCREF(value); /* _byref steals a refcount */
+		return _byref(value);
+	case -1:
+		PyErr_Clear();
+		break;
+	default:
+ 		break;
+	}
+
+ 	if (PointerObject_Check(value) || ArrayObject_Check(value)) {
+ 		/* Array instances are also pointers when
+ 		   the item types are the same.
+ 		*/
+ 		StgDictObject *v = PyObject_stgdict(value);
+		assert(v); /* Cannot be NULL for pointer or array objects */
+ 		if (PyObject_IsSubclass(v->proto, typedict->proto)) {
+  			Py_INCREF(value);
+  			return value;
+  		}
+  	}
+     	return CDataType_from_param(type, value);
+}
+
+static PyMethodDef PointerType_methods[] = {
+	{ "from_address", CDataType_from_address, METH_O, from_address_doc },
+	{ "in_dll", CDataType_in_dll, METH_VARARGS, in_dll_doc},
+	{ "from_param", (PyCFunction)PointerType_from_param, METH_O, from_param_doc},
+	{ "set_type", (PyCFunction)PointerType_set_type, METH_O },
+	{ NULL, NULL },
+};
+
+PyTypeObject PointerType_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0,					/* ob_size */
+	"_ctypes.PointerType",				/* tp_name */
+	0,					/* tp_basicsize */
+	0,					/* tp_itemsize */
+	0,					/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	0,			       		/* tp_repr */
+	0,					/* tp_as_number */
+	&CDataType_as_sequence,		/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	0,					/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+	"metatype for the Pointer Objects",	/* tp_doc */
+	(traverseproc)CDataType_traverse,	/* tp_traverse */
+	(inquiry)CDataType_clear,		/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	PointerType_methods,			/* tp_methods */
+	0,					/* tp_members */
+	0,					/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	0,					/* tp_init */
+	0,					/* tp_alloc */
+	PointerType_new,			/* tp_new */
+	0,					/* tp_free */
+};
+
+
+/******************************************************************/
+/*
+  ArrayType_Type
+*/
+/*
+  ArrayType_new ensures that the new Array subclass created has a _length_
+  attribute, and a _type_ attribute.
+*/
+
+static int
+CharArray_set_raw(CDataObject *self, PyObject *value)
+{
+	char *ptr;
+	Py_ssize_t size;
+	if (PyBuffer_Check(value)) {
+		size = value->ob_type->tp_as_buffer->bf_getreadbuffer(value, 0, (void *)&ptr);
+		if (size < 0)
+			return -1;
+	} else if (-1 == PyString_AsStringAndSize(value, &ptr, &size)) {
+		return -1;
+	}
+	if (size > self->b_size) {
+		PyErr_SetString(PyExc_ValueError,
+				"string too long");
+		return -1;
+	}
+
+	memcpy(self->b_ptr, ptr, size);
+
+	return 0;
+}
+
+static PyObject *
+CharArray_get_raw(CDataObject *self)
+{
+	return PyString_FromStringAndSize(self->b_ptr, self->b_size);
+}
+
+static PyObject *
+CharArray_get_value(CDataObject *self)
+{
+	int i;
+	char *ptr = self->b_ptr;
+	for (i = 0; i < self->b_size; ++i)
+		if (*ptr++ == '\0')
+			break;
+	return PyString_FromStringAndSize(self->b_ptr, i);
+}
+
+static int
+CharArray_set_value(CDataObject *self, PyObject *value)
+{
+	char *ptr;
+	int size;
+
+	if (PyUnicode_Check(value)) {
+		value = PyUnicode_AsEncodedString(value,
+						  conversion_mode_encoding,
+						  conversion_mode_errors);
+		if (!value)
+			return -1;
+	} else if (!PyString_Check(value)) {
+		PyErr_Format(PyExc_TypeError,
+			     "string expected instead of %s instance",
+			     value->ob_type->tp_name);
+		return -1;
+	} else
+		Py_INCREF(value);
+	size = PyString_GET_SIZE(value);
+	if (size > self->b_size) {
+		PyErr_SetString(PyExc_ValueError,
+				"string too long");
+		Py_DECREF(value);
+		return -1;
+	}
+
+	ptr = PyString_AS_STRING(value);
+	memcpy(self->b_ptr, ptr, size);
+	if (size < self->b_size)
+		self->b_ptr[size] = '\0';
+	Py_DECREF(value);
+
+	return 0;
+}
+
+static PyGetSetDef CharArray_getsets[] = {
+	{ "raw", (getter)CharArray_get_raw, (setter)CharArray_set_raw,
+	  "value", NULL },
+	{ "value", (getter)CharArray_get_value, (setter)CharArray_set_value,
+	  "string value"},
+	{ NULL, NULL }
+};
+
+#ifdef CTYPES_UNICODE
+static PyObject *
+WCharArray_get_value(CDataObject *self)
+{
+	unsigned int i;
+	wchar_t *ptr = (wchar_t *)self->b_ptr;
+	for (i = 0; i < self->b_size/sizeof(wchar_t); ++i)
+		if (*ptr++ == (wchar_t)0)
+			break;
+	return PyUnicode_FromWideChar((wchar_t *)self->b_ptr, i);
+}
+
+static int
+WCharArray_set_value(CDataObject *self, PyObject *value)
+{
+	int result = 0;
+
+	if (PyString_Check(value)) {
+		value = PyUnicode_FromEncodedObject(value,
+						    conversion_mode_encoding,
+						    conversion_mode_errors);
+		if (!value)
+			return -1;
+	} else if (!PyUnicode_Check(value)) {
+		PyErr_Format(PyExc_TypeError,
+				"unicode string expected instead of %s instance",
+				value->ob_type->tp_name);
+		return -1;
+	} else
+		Py_INCREF(value);
+	if ((unsigned)PyUnicode_GET_SIZE(value) > self->b_size/sizeof(wchar_t)) {
+		PyErr_SetString(PyExc_ValueError,
+				"string too long");
+		result = -1;
+		goto done;
+	}
+	result = PyUnicode_AsWideChar((PyUnicodeObject *)value,
+				      (wchar_t *)self->b_ptr,
+				      self->b_size/sizeof(wchar_t));
+	if (result >= 0 && (unsigned)result < self->b_size/sizeof(wchar_t))
+		((wchar_t *)self->b_ptr)[result] = (wchar_t)0;
+	if (result > 0)
+		result = 0;
+  done:
+	Py_DECREF(value);
+
+	return result;
+}
+
+static PyGetSetDef WCharArray_getsets[] = {
+	{ "value", (getter)WCharArray_get_value, (setter)WCharArray_set_value,
+	  "string value"},
+	{ NULL, NULL }
+};
+#endif
+
+/*
+  The next three functions copied from Python's typeobject.c.
+
+  They are used to attach methods, members, or getsets to a type *after* it
+  has been created: Arrays of characters have additional getsets to treat them
+  as strings.
+ */
+/*
+static int
+add_methods(PyTypeObject *type, PyMethodDef *meth)
+{
+	PyObject *dict = type->tp_dict;
+	for (; meth->ml_name != NULL; meth++) {
+		PyObject *descr;
+		descr = PyDescr_NewMethod(type, meth);
+		if (descr == NULL)
+			return -1;
+		if (PyDict_SetItemString(dict,meth->ml_name, descr) < 0)
+			return -1;
+		Py_DECREF(descr);
+	}
+	return 0;
+}
+
+static int
+add_members(PyTypeObject *type, PyMemberDef *memb)
+{
+	PyObject *dict = type->tp_dict;
+	for (; memb->name != NULL; memb++) {
+		PyObject *descr;
+		descr = PyDescr_NewMember(type, memb);
+		if (descr == NULL)
+			return -1;
+		if (PyDict_SetItemString(dict, memb->name, descr) < 0)
+			return -1;
+		Py_DECREF(descr);
+	}
+	return 0;
+}
+*/
+
+static int
+add_getset(PyTypeObject *type, PyGetSetDef *gsp)
+{
+	PyObject *dict = type->tp_dict;
+	for (; gsp->name != NULL; gsp++) {
+		PyObject *descr;
+		descr = PyDescr_NewGetSet(type, gsp);
+		if (descr == NULL)
+			return -1;
+		if (PyDict_SetItemString(dict, gsp->name, descr) < 0)
+			return -1;
+		Py_DECREF(descr);
+	}
+	return 0;
+}
+
+static PyCArgObject *
+ArrayType_paramfunc(CDataObject *self)
+{
+	PyCArgObject *p = new_CArgObject();
+	if (p == NULL)
+		return NULL;
+	p->tag = 'P';
+	p->pffi_type = &ffi_type_pointer;
+	p->value.p = (char *)self->b_ptr;
+	Py_INCREF(self);
+	p->obj = (PyObject *)self;
+	return p;
+}
+
+static PyObject *
+ArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	PyTypeObject *result;
+	StgDictObject *stgdict;
+	StgDictObject *itemdict;
+	PyObject *proto;
+	PyObject *typedict;
+	int length;
+
+	int itemsize, itemalign;
+
+	typedict = PyTuple_GetItem(args, 2);
+	if (!typedict)
+		return NULL;
+
+	proto = PyDict_GetItemString(typedict, "_length_"); /* Borrowed ref */
+	if (!proto || !PyInt_Check(proto)) {
+		PyErr_SetString(PyExc_AttributeError,
+				"class must define a '_length_' attribute, "
+				"which must be a positive integer");
+		return NULL;
+	}
+	length = PyInt_AS_LONG(proto);
+
+	proto = PyDict_GetItemString(typedict, "_type_"); /* Borrowed ref */
+	if (!proto) {
+		PyErr_SetString(PyExc_AttributeError,
+				"class must define a '_type_' attribute");
+		return NULL;
+	}
+
+	stgdict = (StgDictObject *)PyObject_CallObject(
+		(PyObject *)&StgDict_Type, NULL);
+	if (!stgdict)
+		return NULL;
+
+	itemdict = PyType_stgdict(proto);
+	if (!itemdict) {
+		PyErr_SetString(PyExc_TypeError,
+				"_type_ must have storage info");
+		Py_DECREF((PyObject *)stgdict);
+		return NULL;
+	}
+
+	itemsize = itemdict->size;
+	if (length * itemsize < 0) {
+		PyErr_SetString(PyExc_OverflowError,
+				"array too large");
+		return NULL;
+	}
+
+	itemalign = itemdict->align;
+
+	stgdict->size = itemsize * length;
+	stgdict->align = itemalign;
+	stgdict->length = length;
+	Py_INCREF(proto);
+	stgdict->proto = proto;
+
+	stgdict->paramfunc = &ArrayType_paramfunc;
+
+	/* Arrays are passed as pointers to function calls. */
+	stgdict->ffi_type_pointer = ffi_type_pointer;
+
+	/* create the new instance (which is a class,
+	   since we are a metatype!) */
+	result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
+	if (result == NULL)
+		return NULL;
+
+	/* replace the class dict by our updated spam dict */
+	if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
+		Py_DECREF(result);
+		Py_DECREF((PyObject *)stgdict);
+		return NULL;
+	}
+	Py_DECREF(result->tp_dict);
+	result->tp_dict = (PyObject *)stgdict;
+
+	/* Special case for character arrays.
+	   A permanent annoyance: char arrays are also strings!
+	*/
+	if (itemdict->getfunc == getentry("c")->getfunc) {
+		if (-1 == add_getset(result, CharArray_getsets))
+			return NULL;
+#ifdef CTYPES_UNICODE
+	} else if (itemdict->getfunc == getentry("u")->getfunc) {
+		if (-1 == add_getset(result, WCharArray_getsets))
+			return NULL;
+#endif
+	}
+
+	return (PyObject *)result;
+}
+
+PyTypeObject ArrayType_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0,					/* ob_size */
+	"_ctypes.ArrayType",			/* tp_name */
+	0,					/* tp_basicsize */
+	0,					/* tp_itemsize */
+	0,					/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	0,			       		/* tp_repr */
+	0,					/* tp_as_number */
+	&CDataType_as_sequence,			/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	0,					/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+	"metatype for the Array Objects",	/* tp_doc */
+	0,					/* tp_traverse */
+	0,					/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	CDataType_methods,			/* tp_methods */
+	0,					/* tp_members */
+	0,					/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	0,					/* tp_init */
+	0,					/* tp_alloc */
+	ArrayType_new,				/* tp_new */
+	0,					/* tp_free */
+};
+
+
+/******************************************************************/
+/*
+  SimpleType_Type
+*/
+/*
+
+SimpleType_new ensures that the new Simple_Type subclass created has a valid
+_type_ attribute.
+
+*/
+
+static char *SIMPLE_TYPE_CHARS = "cbBhHiIlLdfuzZqQPXOv";
+
+static PyObject *
+c_wchar_p_from_param(PyObject *type, PyObject *value)
+{
+	PyObject *as_parameter;
+#if (PYTHON_API_VERSION < 1012)
+# error not supported
+#endif
+	if (value == Py_None) {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+	if (PyUnicode_Check(value) || PyString_Check(value)) {
+		PyCArgObject *parg;
+		struct fielddesc *fd = getentry("Z");
+
+		parg = new_CArgObject();
+		if (parg == NULL)
+			return NULL;
+		parg->pffi_type = &ffi_type_pointer;
+		parg->tag = 'Z';
+		parg->obj = fd->setfunc(&parg->value, value, 0);
+		if (parg->obj == NULL) {
+			Py_DECREF(parg);
+			return NULL;
+		}
+		return (PyObject *)parg;
+	}
+	if (PyObject_IsInstance(value, type)) {
+		Py_INCREF(value);
+		return value;
+	}
+	if (ArrayObject_Check(value) || PointerObject_Check(value)) {
+		/* c_wchar array instance or pointer(c_wchar(...)) */
+		StgDictObject *dt = PyObject_stgdict(value);
+		StgDictObject *dict;
+		assert(dt); /* Cannot be NULL for pointer or array objects */
+		dict = dt && dt->proto ? PyType_stgdict(dt->proto) : NULL;
+		if (dict && (dict->setfunc == getentry("u")->setfunc)) {
+			Py_INCREF(value);
+			return value;
+		}
+	}
+	if (PyCArg_CheckExact(value)) {
+		/* byref(c_char(...)) */
+		PyCArgObject *a = (PyCArgObject *)value;
+		StgDictObject *dict = PyObject_stgdict(a->obj);
+		if (dict && (dict->setfunc == getentry("u")->setfunc)) {
+			Py_INCREF(value);
+			return value;
+		}
+	}
+
+	as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
+	if (as_parameter) {
+		value = c_wchar_p_from_param(type, as_parameter);
+		Py_DECREF(as_parameter);
+		return value;
+	}
+	/* XXX better message */
+	PyErr_SetString(PyExc_TypeError,
+			"wrong type");
+	return NULL;
+}
+
+static PyObject *
+c_char_p_from_param(PyObject *type, PyObject *value)
+{
+	PyObject *as_parameter;
+#if (PYTHON_API_VERSION < 1012)
+# error not supported
+#endif
+	if (value == Py_None) {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+	if (PyString_Check(value) || PyUnicode_Check(value)) {
+		PyCArgObject *parg;
+		struct fielddesc *fd = getentry("z");
+
+		parg = new_CArgObject();
+		if (parg == NULL)
+			return NULL;
+		parg->pffi_type = &ffi_type_pointer;
+		parg->tag = 'z';
+		parg->obj = fd->setfunc(&parg->value, value, 0);
+		if (parg->obj == NULL) {
+			Py_DECREF(parg);
+			return NULL;
+		}
+		return (PyObject *)parg;
+	}
+	if (PyObject_IsInstance(value, type)) {
+		Py_INCREF(value);
+		return value;
+	}
+	if (ArrayObject_Check(value) || PointerObject_Check(value)) {
+		/* c_char array instance or pointer(c_char(...)) */
+		StgDictObject *dt = PyObject_stgdict(value);
+		StgDictObject *dict;
+		assert(dt); /* Cannot be NULL for pointer or array objects */
+		dict = dt && dt->proto ? PyType_stgdict(dt->proto) : NULL;
+		if (dict && (dict->setfunc == getentry("c")->setfunc)) {
+			Py_INCREF(value);
+			return value;
+		}
+	}
+	if (PyCArg_CheckExact(value)) {
+		/* byref(c_char(...)) */
+		PyCArgObject *a = (PyCArgObject *)value;
+		StgDictObject *dict = PyObject_stgdict(a->obj);
+		if (dict && (dict->setfunc == getentry("c")->setfunc)) {
+			Py_INCREF(value);
+			return value;
+		}
+	}
+
+	as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
+	if (as_parameter) {
+		value = c_char_p_from_param(type, as_parameter);
+		Py_DECREF(as_parameter);
+		return value;
+	}
+	/* XXX better message */
+	PyErr_SetString(PyExc_TypeError,
+			"wrong type");
+	return NULL;
+}
+
+static PyObject *
+c_void_p_from_param(PyObject *type, PyObject *value)
+{
+	StgDictObject *stgd;
+	PyObject *as_parameter;
+#if (PYTHON_API_VERSION < 1012)
+# error not supported
+#endif
+
+/* None */
+	if (value == Py_None) {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+	/* Should probably allow buffer interface as well */
+/* int, long */
+	if (PyInt_Check(value) || PyLong_Check(value)) {
+		PyCArgObject *parg;
+		struct fielddesc *fd = getentry("P");
+
+		parg = new_CArgObject();
+		if (parg == NULL)
+			return NULL;
+		parg->pffi_type = &ffi_type_pointer;
+		parg->tag = 'P';
+		parg->obj = fd->setfunc(&parg->value, value, 0);
+		if (parg->obj == NULL) {
+			Py_DECREF(parg);
+			return NULL;
+		}
+		return (PyObject *)parg;
+	}
+/* string */
+	if (PyString_Check(value)) {
+		PyCArgObject *parg;
+		struct fielddesc *fd = getentry("z");
+
+		parg = new_CArgObject();
+		if (parg == NULL)
+			return NULL;
+		parg->pffi_type = &ffi_type_pointer;
+		parg->tag = 'z';
+		parg->obj = fd->setfunc(&parg->value, value, 0);
+		if (parg->obj == NULL) {
+			Py_DECREF(parg);
+			return NULL;
+		}
+		return (PyObject *)parg;
+	}
+/* unicode */
+	if (PyUnicode_Check(value)) {
+		PyCArgObject *parg;
+		struct fielddesc *fd = getentry("Z");
+
+		parg = new_CArgObject();
+		if (parg == NULL)
+			return NULL;
+		parg->pffi_type = &ffi_type_pointer;
+		parg->tag = 'Z';
+		parg->obj = fd->setfunc(&parg->value, value, 0);
+		if (parg->obj == NULL) {
+			Py_DECREF(parg);
+			return NULL;
+		}
+		return (PyObject *)parg;
+	}
+/* c_void_p instance (or subclass) */
+	if (PyObject_IsInstance(value, type)) {
+		/* c_void_p instances */
+		Py_INCREF(value);
+		return value;
+	}
+/* ctypes array or pointer instance */
+	if (ArrayObject_Check(value) || PointerObject_Check(value)) {
+		/* Any array or pointer is accepted */
+		Py_INCREF(value);
+		return value;
+	}
+/* byref(...) */
+	if (PyCArg_CheckExact(value)) {
+		/* byref(c_xxx()) */
+		PyCArgObject *a = (PyCArgObject *)value;
+		if (a->tag == 'P') {
+			Py_INCREF(value);
+			return value;
+		}
+	}
+/* function pointer */
+	if (CFuncPtrObject_Check(value)) {
+		PyCArgObject *parg;
+		CFuncPtrObject *func;
+		func = (CFuncPtrObject *)value;
+		parg = new_CArgObject();
+		if (parg == NULL)
+			return NULL;
+		parg->pffi_type = &ffi_type_pointer;
+		parg->tag = 'P';
+		Py_INCREF(value);
+		parg->value.p = *(void **)func->b_ptr;
+		parg->obj = value;
+		return (PyObject *)parg;
+	}
+/* c_char_p, c_wchar_p */
+	stgd = PyObject_stgdict(value);
+	if (stgd && CDataObject_Check(value) && stgd->proto && PyString_Check(stgd->proto)) {
+		PyCArgObject *parg;
+
+		switch (PyString_AS_STRING(stgd->proto)[0]) {
+		case 'z': /* c_char_p */
+		case 'Z': /* c_wchar_p */
+			parg = new_CArgObject();
+			if (parg == NULL)
+				return NULL;
+			parg->pffi_type = &ffi_type_pointer;
+			parg->tag = 'Z';
+			Py_INCREF(value);
+			parg->obj = value;
+			/* Remember: b_ptr points to where the pointer is stored! */
+			parg->value.p = *(void **)(((CDataObject *)value)->b_ptr);
+			return (PyObject *)parg;
+		}
+	}
+
+	as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
+	if (as_parameter) {
+		value = c_void_p_from_param(type, as_parameter);
+		Py_DECREF(as_parameter);
+		return value;
+	}
+	/* XXX better message */
+	PyErr_SetString(PyExc_TypeError,
+			"wrong type");
+	return NULL;
+}
+#if (PYTHON_API_VERSION >= 1012)
+
+static PyMethodDef c_void_p_method = { "from_param", c_void_p_from_param, METH_O };
+static PyMethodDef c_char_p_method = { "from_param", c_char_p_from_param, METH_O };
+static PyMethodDef c_wchar_p_method = { "from_param", c_wchar_p_from_param, METH_O };
+
+#else
+#error
+static PyMethodDef c_void_p_method = { "from_param", c_void_p_from_param, METH_VARARGS };
+static PyMethodDef c_char_p_method = { "from_param", c_char_p_from_param, METH_VARARGS };
+static PyMethodDef c_wchar_p_method = { "from_param", c_wchar_p_from_param, METH_VARARGS };
+
+#endif
+
+static PyObject *CreateSwappedType(PyTypeObject *type, PyObject *args, PyObject *kwds,
+				   PyObject *proto, struct fielddesc *fmt)
+{
+	PyTypeObject *result;
+	StgDictObject *stgdict;
+	PyObject *name = PyTuple_GET_ITEM(args, 0);
+	PyObject *swapped_args;
+	static PyObject *suffix;
+	Py_ssize_t i;
+
+	swapped_args = PyTuple_New(PyTuple_GET_SIZE(args));
+	if (!swapped_args)
+		return NULL;
+
+	if (suffix == NULL)
+#ifdef WORDS_BIGENDIAN
+		suffix = PyString_FromString("_le");
+#else
+		suffix = PyString_FromString("_be");
+#endif
+
+	Py_INCREF(name);
+	PyString_Concat(&name, suffix);
+	if (name == NULL)
+		return NULL;
+
+	PyTuple_SET_ITEM(swapped_args, 0, name);
+	for (i=1; i<PyTuple_GET_SIZE(args); ++i) {
+		PyObject *v = PyTuple_GET_ITEM(args, i);
+		Py_INCREF(v);
+		PyTuple_SET_ITEM(swapped_args, i, v);
+	}
+
+	/* create the new instance (which is a class,
+	   since we are a metatype!) */
+	result = (PyTypeObject *)PyType_Type.tp_new(type, swapped_args, kwds);
+	Py_DECREF(swapped_args);
+	if (result == NULL)
+		return NULL;
+
+	stgdict = (StgDictObject *)PyObject_CallObject(
+		(PyObject *)&StgDict_Type, NULL);
+	if (!stgdict) /* XXX leaks result! */
+		return NULL;
+
+	stgdict->ffi_type_pointer = *fmt->pffi_type;
+	stgdict->align = fmt->pffi_type->alignment;
+	stgdict->length = 0;
+	stgdict->size = fmt->pffi_type->size;
+	stgdict->setfunc = fmt->setfunc_swapped;
+	stgdict->getfunc = fmt->getfunc_swapped;
+
+	Py_INCREF(proto);
+	stgdict->proto = proto;
+
+	/* replace the class dict by our updated spam dict */
+	if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
+		Py_DECREF(result);
+		Py_DECREF((PyObject *)stgdict);
+		return NULL;
+	}
+	Py_DECREF(result->tp_dict);
+	result->tp_dict = (PyObject *)stgdict;
+
+	return (PyObject *)result;
+}
+
+static PyCArgObject *
+SimpleType_paramfunc(CDataObject *self)
+{
+	StgDictObject *dict;
+	char *fmt;
+	PyCArgObject *parg;
+	struct fielddesc *fd;
+	
+	dict = PyObject_stgdict((PyObject *)self);
+	assert(dict); /* Cannot be NULL for CDataObject instances */
+	fmt = PyString_AsString(dict->proto);
+	assert(fmt);
+
+	fd = getentry(fmt);
+	assert(fd);
+	
+	parg = new_CArgObject();
+	if (parg == NULL)
+		return NULL;
+	
+	parg->tag = fmt[0];
+	parg->pffi_type = fd->pffi_type;
+	Py_INCREF(self);
+	parg->obj = (PyObject *)self;
+	memcpy(&parg->value, self->b_ptr, self->b_size);
+	return parg;	
+}
+
+static PyObject *
+SimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	PyTypeObject *result;
+	StgDictObject *stgdict;
+	PyObject *proto;
+	PyMethodDef *ml;
+	struct fielddesc *fmt;
+
+	/* create the new instance (which is a class,
+	   since we are a metatype!) */
+	result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
+	if (result == NULL)
+		return NULL;
+
+	proto = PyObject_GetAttrString((PyObject *)result, "_type_"); /* new ref */
+	if (!proto
+	    || !PyString_Check(proto)
+	    || 1 != strlen(PyString_AS_STRING(proto))
+	    || !strchr(SIMPLE_TYPE_CHARS, PyString_AS_STRING(proto)[0])) {
+		PyErr_Format(PyExc_AttributeError,
+			     "class must define a '_type_' attribute which must be\n"
+			     "a single character string containing one of '%s'.",
+			     SIMPLE_TYPE_CHARS);
+		Py_XDECREF(proto);
+		Py_DECREF(result);
+		return NULL;
+	}
+	fmt = getentry(PyString_AS_STRING(proto));
+	if (fmt == NULL) {
+		Py_DECREF(result);
+		PyErr_Format(PyExc_ValueError,
+			     "_type_ '%s' not supported",
+			     PyString_AS_STRING(proto));
+		return NULL;
+	}
+
+	stgdict = (StgDictObject *)PyObject_CallObject(
+		(PyObject *)&StgDict_Type, NULL);
+	if (!stgdict)
+		return NULL;
+
+	stgdict->ffi_type_pointer = *fmt->pffi_type;
+	stgdict->align = fmt->pffi_type->alignment;
+	stgdict->length = 0;
+	stgdict->size = fmt->pffi_type->size;
+	stgdict->setfunc = fmt->setfunc;
+	stgdict->getfunc = fmt->getfunc;
+
+	stgdict->paramfunc = SimpleType_paramfunc;
+/*
+	if (result->tp_base != &Simple_Type) {
+		stgdict->setfunc = NULL;
+		stgdict->getfunc = NULL;
+	}
+*/
+
+	/* This consumes the refcount on proto which we have */
+	stgdict->proto = proto;
+
+	/* replace the class dict by our updated spam dict */
+	if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
+		Py_DECREF(result);
+		Py_DECREF((PyObject *)stgdict);
+		return NULL;
+	}
+	Py_DECREF(result->tp_dict);
+	result->tp_dict = (PyObject *)stgdict;
+
+	/* Install from_param class methods in ctypes base classes.
+	   Overrides the SimpleType_from_param generic method.
+	 */
+	if (result->tp_base == &Simple_Type) {
+		switch (PyString_AS_STRING(proto)[0]) {
+		case 'z': /* c_char_p */
+			ml = &c_char_p_method;
+			break;
+		case 'Z': /* c_wchar_p */
+			ml = &c_wchar_p_method;
+			break;
+		case 'P': /* c_void_p */
+			ml = &c_void_p_method;
+			break;
+		default:
+			ml = NULL;
+			break;
+		}
+			
+		if (ml) {
+#if (PYTHON_API_VERSION >= 1012)
+			PyObject *meth;
+			int x;
+			meth = PyDescr_NewClassMethod(result, ml);
+			if (!meth)
+				return NULL;
+#else
+#error
+			PyObject *meth, *func;
+			int x;
+			func = PyCFunction_New(ml, NULL);
+			if (!func)
+				return NULL;
+			meth = PyObject_CallFunctionObjArgs(
+				(PyObject *)&PyClassMethod_Type,
+				func, NULL);
+			Py_DECREF(func);
+			if (!meth) {
+				return NULL;
+			}
+#endif
+			x = PyDict_SetItemString(result->tp_dict,
+						 ml->ml_name,
+						 meth);
+			Py_DECREF(meth);
+			if (x == -1) {
+				Py_DECREF(result);
+				return NULL;
+			}
+		}
+	}
+
+	if (type == &SimpleType_Type && fmt->setfunc_swapped && fmt->getfunc_swapped) {
+		PyObject *swapped = CreateSwappedType(type, args, kwds,
+						      proto, fmt);
+		if (swapped == NULL) {
+			Py_DECREF(result);
+			return NULL;
+		}
+#ifdef WORDS_BIGENDIAN
+		PyObject_SetAttrString((PyObject *)result, "__ctype_le__", swapped);
+		PyObject_SetAttrString((PyObject *)result, "__ctype_be__", (PyObject *)result);
+		PyObject_SetAttrString(swapped, "__ctype_be__", (PyObject *)result);
+		PyObject_SetAttrString(swapped, "__ctype_le__", swapped);
+#else
+		PyObject_SetAttrString((PyObject *)result, "__ctype_be__", swapped);
+		PyObject_SetAttrString((PyObject *)result, "__ctype_le__", (PyObject *)result);
+		PyObject_SetAttrString(swapped, "__ctype_le__", (PyObject *)result);
+		PyObject_SetAttrString(swapped, "__ctype_be__", swapped);
+#endif
+		Py_DECREF(swapped);
+	};
+
+	return (PyObject *)result;
+}
+
+/*
+ * This is a *class method*.
+ * Convert a parameter into something that ConvParam can handle.
+ */
+static PyObject *
+SimpleType_from_param(PyObject *type, PyObject *value)
+{
+	StgDictObject *dict;
+	char *fmt;
+	PyCArgObject *parg;
+	struct fielddesc *fd;
+	PyObject *as_parameter;
+
+	/* If the value is already an instance of the requested type,
+	   we can use it as is */
+	if (1 == PyObject_IsInstance(value, type)) {
+		Py_INCREF(value);
+		return value;
+	}
+
+	dict = PyType_stgdict(type);
+	assert(dict);
+
+	/* I think we can rely on this being a one-character string */
+	fmt = PyString_AsString(dict->proto);
+	assert(fmt);
+	
+	fd = getentry(fmt);
+	assert(fd);
+	
+	parg = new_CArgObject();
+	if (parg == NULL)
+		return NULL;
+
+	parg->tag = fmt[0];
+	parg->pffi_type = fd->pffi_type;
+	parg->obj = fd->setfunc(&parg->value, value, 0);
+	if (parg->obj)
+		return (PyObject *)parg;
+	PyErr_Clear();
+	Py_DECREF(parg);
+
+	as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
+	if (as_parameter) {
+		value = SimpleType_from_param(type, as_parameter);
+		Py_DECREF(as_parameter);
+		return value;
+	}
+	PyErr_SetString(PyExc_TypeError,
+			"wrong type");
+	return NULL;
+}
+
+static PyMethodDef SimpleType_methods[] = {
+	{ "from_param", SimpleType_from_param, METH_O, from_param_doc },
+	{ "from_address", CDataType_from_address, METH_O, from_address_doc },
+	{ "in_dll", CDataType_in_dll, METH_VARARGS, in_dll_doc},
+	{ NULL, NULL },
+};
+
+PyTypeObject SimpleType_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0,					/* ob_size */
+	"_ctypes.SimpleType",				/* tp_name */
+	0,					/* tp_basicsize */
+	0,					/* tp_itemsize */
+	0,					/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	0,			       		/* tp_repr */
+	0,					/* tp_as_number */
+	&CDataType_as_sequence,		/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	0,					/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+	"metatype for the SimpleType Objects",	/* tp_doc */
+	0,					/* tp_traverse */
+	0,					/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	SimpleType_methods,			/* tp_methods */
+	0,					/* tp_members */
+	0,					/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	0,					/* tp_init */
+	0,					/* tp_alloc */
+	SimpleType_new,				/* tp_new */
+	0,					/* tp_free */
+};
+
+/******************************************************************/
+/*
+  CFuncPtrType_Type
+ */
+
+static PyObject *
+converters_from_argtypes(PyObject *ob)
+{
+	PyObject *converters;
+	int i;
+	int nArgs;
+
+	ob = PySequence_Tuple(ob); /* new reference */
+	if (!ob) {
+		PyErr_SetString(PyExc_TypeError,
+				"_argtypes_ must be a sequence of types");
+		return NULL;
+	}
+
+	nArgs = PyTuple_GET_SIZE(ob);
+	converters = PyTuple_New(nArgs);
+	if (!converters)
+		return NULL;
+		
+	/* I have to check if this is correct. Using c_char, which has a size
+	   of 1, will be assumed to be pushed as only one byte!
+	   Aren't these promoted to integers by the C compiler and pushed as 4 bytes?
+	*/
+
+	for (i = 0; i < nArgs; ++i) {
+		PyObject *tp = PyTuple_GET_ITEM(ob, i);
+		PyObject *cnv = PyObject_GetAttrString(tp, "from_param");
+		if (!cnv)
+			goto argtypes_error_1;
+		PyTuple_SET_ITEM(converters, i, cnv);
+	}
+	Py_DECREF(ob);
+	return converters;
+
+  argtypes_error_1:
+	Py_XDECREF(converters);
+	Py_DECREF(ob);
+	PyErr_Format(PyExc_TypeError,
+		     "item %d in _argtypes_ has no from_param method", i+1);
+	return NULL;
+}
+
+static int
+make_funcptrtype_dict(StgDictObject *stgdict)
+{
+	PyObject *ob;
+	PyObject *converters = NULL;
+
+	stgdict->align = getentry("P")->pffi_type->alignment;
+	stgdict->length = 1;
+	stgdict->size = sizeof(void *);
+	stgdict->setfunc = NULL;
+	stgdict->getfunc = NULL;
+	stgdict->ffi_type_pointer = ffi_type_pointer;
+
+	ob = PyDict_GetItemString((PyObject *)stgdict, "_flags_");
+	if (!ob || !PyInt_Check(ob)) {
+		PyErr_SetString(PyExc_TypeError,
+		    "class must define _flags_ which must be an integer");
+		return -1;
+	}
+	stgdict->flags = PyInt_AS_LONG(ob);
+
+	/* _argtypes_ is optional... */
+	ob = PyDict_GetItemString((PyObject *)stgdict, "_argtypes_");
+	if (ob) {
+		converters = converters_from_argtypes(ob);
+		if (!converters)
+			goto error;
+		Py_INCREF(ob);
+		stgdict->argtypes = ob;
+		stgdict->converters = converters;
+	}
+
+	ob = PyDict_GetItemString((PyObject *)stgdict, "_restype_");
+	if (ob) {
+		if (ob != Py_None && !PyType_stgdict(ob) && !PyCallable_Check(ob)) {
+			PyErr_SetString(PyExc_TypeError,
+				"_restype_ must be a type, a callable, or None");
+			return -1;
+		}
+		Py_INCREF(ob);
+		stgdict->restype = ob;
+		stgdict->checker = PyObject_GetAttrString(ob, "_check_retval_");
+		if (stgdict->checker == NULL)
+			PyErr_Clear();
+	}
+/* XXX later, maybe.
+	ob = PyDict_GetItemString((PyObject *)stgdict, "_errcheck_");
+	if (ob) {
+		if (!PyCallable_Check(ob)) {
+			PyErr_SetString(PyExc_TypeError,
+				"_errcheck_ must be callable");
+			return -1;
+		}
+		Py_INCREF(ob);
+		stgdict->errcheck = ob;
+	}
+*/
+	return 0;
+
+  error:
+	Py_XDECREF(converters);
+	return -1;
+
+}
+
+static PyCArgObject *
+CFuncPtrType_paramfunc(CDataObject *self)
+{
+	PyCArgObject *parg;
+	
+	parg = new_CArgObject();
+	if (parg == NULL)
+		return NULL;
+	
+	parg->tag = 'P';
+	parg->pffi_type = &ffi_type_pointer;
+	Py_INCREF(self);
+	parg->obj = (PyObject *)self;
+	parg->value.p = *(void **)self->b_ptr;
+	return parg;	
+}
+
+static PyObject *
+CFuncPtrType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	PyTypeObject *result;
+	StgDictObject *stgdict;
+
+	stgdict = (StgDictObject *)PyObject_CallObject(
+		(PyObject *)&StgDict_Type, NULL);
+	if (!stgdict)
+		return NULL;
+
+	stgdict->paramfunc = CFuncPtrType_paramfunc;
+
+	/* create the new instance (which is a class,
+	   since we are a metatype!) */
+	result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
+	if (result == NULL) {
+		Py_DECREF((PyObject *)stgdict);
+		return NULL;
+	}
+
+	/* replace the class dict by our updated storage dict */
+	if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
+		Py_DECREF(result);
+		Py_DECREF((PyObject *)stgdict);
+		return NULL;
+	}
+	Py_DECREF(result->tp_dict);
+	result->tp_dict = (PyObject *)stgdict;
+
+	if (-1 == make_funcptrtype_dict(stgdict)) {
+		Py_DECREF(result);
+		return NULL;
+	}
+
+	return (PyObject *)result;
+}
+
+PyTypeObject CFuncPtrType_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0,					/* ob_size */
+	"_ctypes.CFuncPtrType",			/* tp_name */
+	0,					/* tp_basicsize */
+	0,					/* tp_itemsize */
+	0,					/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	0,			       		/* tp_repr */
+	0,					/* tp_as_number */
+	&CDataType_as_sequence,			/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	0,					/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+	"metatype for C function pointers",	/* tp_doc */
+	(traverseproc)CDataType_traverse,	/* tp_traverse */
+	(inquiry)CDataType_clear,		/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	CDataType_methods,			/* tp_methods */
+	0,					/* tp_members */
+	0,					/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	0,					/* tp_init */
+	0,					/* tp_alloc */
+	CFuncPtrType_new,			/* tp_new */
+	0,					/* tp_free */
+};
+
+
+/*****************************************************************
+ * Code to keep needed objects alive
+ */
+
+static CDataObject *
+CData_GetContainer(CDataObject *self)
+{
+	while (self->b_base)
+		self = self->b_base;
+	if (self->b_objects == NULL) {
+		if (self->b_length) {
+			self->b_objects = PyDict_New();
+		} else {
+			Py_INCREF(Py_None);
+			self->b_objects = Py_None;
+		}
+	}
+	return self;
+}
+
+static PyObject *
+GetKeepedObjects(CDataObject *target)
+{
+	return CData_GetContainer(target)->b_objects;
+}
+
+static PyObject *
+unique_key(CDataObject *target, Py_ssize_t index)
+{
+	char string[256];
+	char *cp = string;
+	size_t bytes_left;
+
+	assert(sizeof(string) - 1 > sizeof(Py_ssize_t) * 2);
+#if (PY_VERSION_HEX < 0x02050000)
+	cp += sprintf(cp, "%x", index);
+#else
+	cp += sprintf(cp, "%x", Py_SAFE_DOWNCAST(index, Py_ssize_t, int));
+#endif
+	while (target->b_base) {
+		bytes_left = sizeof(string) - (cp - string) - 1;
+		/* Hex format needs 2 characters per byte */
+		if (bytes_left < sizeof(Py_ssize_t) * 2) {
+			PyErr_SetString(PyExc_ValueError,
+					"ctypes object structure too deep");
+			return NULL;
+		}
+#if (PY_VERSION_HEX < 0x02050000)
+		cp += sprintf(cp, ":%x", (int)target->b_index);
+#else
+		cp += sprintf(cp, ":%x", Py_SAFE_DOWNCAST(target->b_index, Py_ssize_t, int));
+#endif
+		target = target->b_base;
+	}
+	return PyString_FromStringAndSize(string, cp-string);
+}
+
+/*
+ * Keep a reference to 'keep' in the 'target', at index 'index'.
+ *
+ * If 'keep' is None, do nothing.
+ *
+ * Otherwise create a dictionary (if it does not yet exist) id the root
+ * objects 'b_objects' item, which will store the 'keep' object under a unique
+ * key.
+ *
+ * The unique_key helper travels the target's b_base pointer down to the root,
+ * building a string containing hex-formatted indexes found during traversal,
+ * separated by colons.
+ *
+ * The index tuple is used as a key into the root object's b_objects dict.
+ *
+ * Note: This function steals a refcount of the third argument, even if it
+ * fails!
+ */
+static int
+KeepRef(CDataObject *target, Py_ssize_t index, PyObject *keep)
+{
+	int result;
+	CDataObject *ob;
+	PyObject *key;
+
+/* Optimization: no need to store None */
+	if (keep == Py_None) {
+		Py_DECREF(Py_None);
+		return 0;
+	}
+	ob = CData_GetContainer(target);
+	if (ob->b_objects == NULL || !PyDict_Check(ob->b_objects)) {
+		Py_XDECREF(ob->b_objects);
+		ob->b_objects = keep; /* refcount consumed */
+		return 0;
+	}
+	key = unique_key(target, index);
+	if (key == NULL) {
+		Py_DECREF(keep);
+		return -1;
+	}
+	result = PyDict_SetItem(ob->b_objects, key, keep);
+	Py_DECREF(key);
+	Py_DECREF(keep);
+	return result;
+}
+
+/******************************************************************/
+/*
+  CData_Type
+ */
+static int
+CData_traverse(CDataObject *self, visitproc visit, void *arg)
+{
+	Py_VISIT(self->b_objects);
+	Py_VISIT((PyObject *)self->b_base);
+	return 0;
+}
+
+static int
+CData_clear(CDataObject *self)
+{
+	StgDictObject *dict = PyObject_stgdict((PyObject *)self);
+	assert(dict); /* Cannot be NULL for CDataObject instances */
+	Py_CLEAR(self->b_objects);
+	if ((self->b_needsfree)
+	    && ((size_t)dict->size > sizeof(self->b_value)))
+		PyMem_Free(self->b_ptr);
+	self->b_ptr = NULL;
+	Py_CLEAR(self->b_base);
+	return 0;
+}
+
+static void
+CData_dealloc(PyObject *self)
+{
+	CData_clear((CDataObject *)self);
+	self->ob_type->tp_free(self);
+}
+
+static PyMemberDef CData_members[] = {
+	{ "_b_base_", T_OBJECT,
+	  offsetof(CDataObject, b_base), READONLY,
+	  "the base object" },
+	{ "_b_needsfree_", T_INT,
+	  offsetof(CDataObject, b_needsfree), READONLY,
+	  "whether the object owns the memory or not" },
+	{ "_objects", T_OBJECT,
+	  offsetof(CDataObject, b_objects), READONLY,
+	  "internal objects tree (NEVER CHANGE THIS OBJECT!)"},
+	{ NULL },
+};
+
+static Py_ssize_t CData_GetBuffer(PyObject *_self, Py_ssize_t seg, void **pptr)
+{
+	CDataObject *self = (CDataObject *)_self;
+	if (seg != 0) {
+		/* Hm. Must this set an exception? */
+		return -1;
+	}
+	*pptr = self->b_ptr;
+	return self->b_size;
+}
+
+static Py_ssize_t CData_GetSegcount(PyObject *_self, Py_ssize_t *lenp)
+{
+	if (lenp)
+		*lenp = 1;
+	return 1;
+}
+
+static PyBufferProcs CData_as_buffer = {
+	CData_GetBuffer,
+	CData_GetBuffer,
+	CData_GetSegcount,
+	NULL,
+};
+
+/*
+ * CData objects are mutable, so they cannot be hashable!
+ */
+static long
+CData_nohash(PyObject *self)
+{
+	PyErr_SetString(PyExc_TypeError, "unhashable type");
+	return -1;
+}
+
+/*
+ * default __ctypes_from_outparam__ method returns self.
+ */
+static PyObject *
+CData_from_outparam(PyObject *self, PyObject *args)
+{
+	Py_INCREF(self);
+	return self;
+}
+
+static PyMethodDef CData_methods[] = {
+	{ "__ctypes_from_outparam__", CData_from_outparam, METH_NOARGS, },
+	{ NULL, NULL },
+};
+
+PyTypeObject CData_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0,
+	"_ctypes._CData",
+	sizeof(CDataObject),			/* tp_basicsize */
+	0,					/* tp_itemsize */
+	CData_dealloc,				/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	0,					/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	CData_nohash,				/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	0,					/* tp_getattro */
+	0,					/* tp_setattro */
+	&CData_as_buffer,			/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+	"XXX to be provided",			/* tp_doc */
+	(traverseproc)CData_traverse,		/* tp_traverse */
+	(inquiry)CData_clear,			/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	CData_methods,				/* tp_methods */
+	CData_members,				/* tp_members */
+	0,					/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	0,					/* tp_init */
+	0,					/* tp_alloc */
+	0,					/* tp_new */
+	0,					/* tp_free */
+};
+
+static int CData_MallocBuffer(CDataObject *obj, StgDictObject *dict)
+{
+	if ((size_t)dict->size <= sizeof(obj->b_value)) {
+		/* No need to call malloc, can use the default buffer */
+		obj->b_ptr = (char *)&obj->b_value;
+		/* The b_needsfree flag does not mean that we actually did
+		   call PyMem_Malloc to allocate the memory block; instead it
+		   means we are the *owner* of the memory and are responsible
+		   for freeing resources associated with the memory.  This is
+		   also the reason that b_needsfree is exposed to Python.
+		 */
+		obj->b_needsfree = 1;
+	} else {
+		/* In python 2.4, and ctypes 0.9.6, the malloc call took about
+		   33% of the creation time for c_int().
+		*/
+		obj->b_ptr = (char *)PyMem_Malloc(dict->size);
+		if (obj->b_ptr == NULL) {
+			PyErr_NoMemory();
+			return -1;
+		}
+		obj->b_needsfree = 1;
+		memset(obj->b_ptr, 0, dict->size);
+	}
+	obj->b_size = dict->size;
+	return 0;
+}
+
+PyObject *
+CData_FromBaseObj(PyObject *type, PyObject *base, Py_ssize_t index, char *adr)
+{
+	CDataObject *cmem;
+	StgDictObject *dict;
+
+	assert(PyType_Check(type));
+	dict = PyType_stgdict(type);
+	if (!dict) {
+		PyErr_SetString(PyExc_TypeError,
+				"abstract class");
+		return NULL;
+	}
+	dict->flags |= DICTFLAG_FINAL;
+	cmem = (CDataObject *)((PyTypeObject *)type)->tp_alloc((PyTypeObject *)type, 0);
+	if (cmem == NULL)
+		return NULL;
+	assert(CDataObject_Check(cmem));
+
+	cmem->b_length = dict->length;
+	cmem->b_size = dict->size;
+	if (base) { /* use base's buffer */
+		assert(CDataObject_Check(base));
+		cmem->b_ptr = adr;
+		cmem->b_needsfree = 0;
+		Py_INCREF(base);
+		cmem->b_base = (CDataObject *)base;
+		cmem->b_index = index;
+	} else { /* copy contents of adr */
+		if (-1 == CData_MallocBuffer(cmem, dict)) {
+			return NULL;
+			Py_DECREF(cmem);
+		}
+		memcpy(cmem->b_ptr, adr, dict->size);
+		cmem->b_index = index;
+	}
+	return (PyObject *)cmem;
+}
+
+/*
+ Box a memory block into a CData instance.
+*/
+PyObject *
+CData_AtAddress(PyObject *type, void *buf)
+{
+	CDataObject *pd;
+	StgDictObject *dict;
+
+	assert(PyType_Check(type));
+	dict = PyType_stgdict(type);
+	if (!dict) {
+		PyErr_SetString(PyExc_TypeError,
+				"abstract class");
+		return NULL;
+	}
+	dict->flags |= DICTFLAG_FINAL;
+
+	pd = (CDataObject *)((PyTypeObject *)type)->tp_alloc((PyTypeObject *)type, 0);
+	if (!pd)
+		return NULL;
+	assert(CDataObject_Check(pd));
+	pd->b_ptr = (char *)buf;
+	pd->b_length = dict->length;
+	pd->b_size = dict->size;
+	return (PyObject *)pd;
+}
+
+/*
+  This function returns TRUE for c_int, c_void_p, and these kind of
+  classes.  FALSE otherwise FALSE also for subclasses of c_int and
+  such.
+*/
+int IsSimpleSubType(PyObject *obj)
+{
+	PyTypeObject *type = (PyTypeObject *)obj;
+
+	if (SimpleTypeObject_Check(type))
+		return type->tp_base != &Simple_Type;
+	return 0;
+}
+
+PyObject *
+CData_get(PyObject *type, GETFUNC getfunc, PyObject *src,
+	  Py_ssize_t index, Py_ssize_t size, char *adr)
+{
+	StgDictObject *dict;
+	if (getfunc)
+		return getfunc(adr, size);
+	assert(type);
+	dict = PyType_stgdict(type);
+	if (dict && dict->getfunc && !IsSimpleSubType(type))
+		return dict->getfunc(adr, size);
+	return CData_FromBaseObj(type, src, index, adr);
+}
+
+/*
+  Helper function for CData_set below.
+*/
+static PyObject *
+_CData_set(CDataObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
+	   Py_ssize_t size, char *ptr)
+{
+	CDataObject *src;
+
+	if (setfunc)
+		return setfunc(ptr, value, size);
+	
+	if (!CDataObject_Check(value)) {
+		StgDictObject *dict = PyType_stgdict(type);
+		if (dict && dict->setfunc)
+			return dict->setfunc(ptr, value, size);
+		/*
+		   If value is a tuple, we try to call the type with the tuple
+		   and use the result!
+		*/
+		assert(PyType_Check(type));
+		if (PyTuple_Check(value)) {
+			PyObject *ob;
+			PyObject *result;
+			ob = PyObject_CallObject(type, value);
+			if (ob == NULL) {
+				Extend_Error_Info(PyExc_RuntimeError, "(%s) ",
+						  ((PyTypeObject *)type)->tp_name);
+				return NULL;
+			}
+			result = _CData_set(dst, type, setfunc, ob,
+					    size, ptr);
+			Py_DECREF(ob);
+			return result;
+		} else if (value == Py_None && PointerTypeObject_Check(type)) {
+			*(void **)ptr = NULL;
+			Py_INCREF(Py_None);
+			return Py_None;
+		} else {
+			PyErr_Format(PyExc_TypeError,
+				     "expected %s instance, got %s",
+				     ((PyTypeObject *)type)->tp_name,
+				     value->ob_type->tp_name);
+			return NULL;
+		}
+	}
+	src = (CDataObject *)value;
+
+	if (PyObject_IsInstance(value, type)) {
+		memcpy(ptr,
+		       src->b_ptr,
+		       size);
+
+		if (PointerTypeObject_Check(type))
+			/* XXX */;
+
+		value = GetKeepedObjects(src);
+		Py_INCREF(value);
+		return value;
+	}
+
+	if (PointerTypeObject_Check(type)
+	    && ArrayObject_Check(value)) {
+		StgDictObject *p1, *p2;
+		PyObject *keep;
+		p1 = PyObject_stgdict(value);
+		assert(p1); /* Cannot be NULL for array instances */
+		p2 = PyType_stgdict(type);
+		assert(p2); /* Cannot be NULL for pointer types */
+
+		if (p1->proto != p2->proto) {
+			PyErr_Format(PyExc_TypeError,
+				     "incompatible types, %s instance instead of %s instance",
+				     value->ob_type->tp_name,
+				     ((PyTypeObject *)type)->tp_name);
+			return NULL;
+		}
+		*(void **)ptr = src->b_ptr;
+
+		keep = GetKeepedObjects(src);
+		/*
+		  We are assigning an array object to a field which represents
+		  a pointer. This has the same effect as converting an array
+		  into a pointer. So, again, we have to keep the whole object
+		  pointed to (which is the array in this case) alive, and not
+		  only it's object list.  So we create a tuple, containing
+		  b_objects list PLUS the array itself, and return that!
+		*/
+		return Py_BuildValue("(OO)", keep, value);
+	}
+	PyErr_Format(PyExc_TypeError,
+		     "incompatible types, %s instance instead of %s instance",
+		     value->ob_type->tp_name,
+		     ((PyTypeObject *)type)->tp_name);
+	return NULL;
+}
+
+/*
+ * Set a slice in object 'dst', which has the type 'type',
+ * to the value 'value'.
+ */
+int
+CData_set(PyObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
+	  Py_ssize_t index, Py_ssize_t size, char *ptr)
+{
+	CDataObject *mem = (CDataObject *)dst;
+	PyObject *result;
+
+	if (!CDataObject_Check(dst)) {
+		PyErr_SetString(PyExc_TypeError,
+				"not a ctype instance");
+		return -1;
+	}
+
+	result = _CData_set(mem, type, setfunc, value,
+			    size, ptr);
+	if (result == NULL)
+		return -1;
+
+	/* KeepRef steals a refcount from it's last argument */
+	/* If KeepRef fails, we are stumped.  The dst memory block has already
+	   been changed */
+	return KeepRef(mem, index, result);
+}
+
+
+/******************************************************************/
+static PyObject *
+GenericCData_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	CDataObject *obj;
+	StgDictObject *dict;
+
+	dict = PyType_stgdict((PyObject *)type);
+	if (!dict) {
+		PyErr_SetString(PyExc_TypeError,
+				"abstract class");
+		return NULL;
+	}
+	dict->flags |= DICTFLAG_FINAL;
+
+	obj = (CDataObject *)type->tp_alloc(type, 0);
+	if (!obj)
+		return NULL;
+
+	obj->b_base = NULL;
+	obj->b_index = 0;
+	obj->b_objects = NULL;
+	obj->b_length = dict->length;
+			
+	if (-1 == CData_MallocBuffer(obj, dict)) {
+		Py_DECREF(obj);
+		return NULL;
+	}
+	return (PyObject *)obj;
+}
+/*****************************************************************/
+/*
+  CFuncPtr_Type
+*/
+
+static int
+CFuncPtr_set_errcheck(CFuncPtrObject *self, PyObject *ob)
+{
+	if (ob && !PyCallable_Check(ob)) {
+		PyErr_SetString(PyExc_TypeError,
+				"the errcheck attribute must be callable");
+		return -1;
+	}
+	Py_XDECREF(self->errcheck);
+	Py_XINCREF(ob);
+	self->errcheck = ob;
+	return 0;
+}
+
+static PyObject *
+CFuncPtr_get_errcheck(CFuncPtrObject *self)
+{
+	if (self->errcheck) {
+		Py_INCREF(self->errcheck);
+		return self->errcheck;
+	}
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static int
+CFuncPtr_set_restype(CFuncPtrObject *self, PyObject *ob)
+{
+	if (ob == NULL) {
+		Py_XDECREF(self->restype);
+		self->restype = NULL;
+		Py_XDECREF(self->checker);
+		self->checker = NULL;
+		return 0;
+	}
+	if (ob != Py_None && !PyType_stgdict(ob) && !PyCallable_Check(ob)) {
+		PyErr_SetString(PyExc_TypeError,
+				"restype must be a type, a callable, or None");
+		return -1;
+	}
+	Py_XDECREF(self->checker);
+	Py_XDECREF(self->restype);
+	Py_INCREF(ob);
+	self->restype = ob;
+	self->checker = PyObject_GetAttrString(ob, "_check_retval_");
+	if (self->checker == NULL)
+		PyErr_Clear();
+	return 0;
+}
+
+static PyObject *
+CFuncPtr_get_restype(CFuncPtrObject *self)
+{
+	StgDictObject *dict;
+	if (self->restype) {
+		Py_INCREF(self->restype);
+		return self->restype;
+	}
+	dict = PyObject_stgdict((PyObject *)self);
+	assert(dict); /* Cannot be NULL for CFuncPtrObject instances */
+	if (dict->restype) {
+		Py_INCREF(dict->restype);
+		return dict->restype;
+	} else {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+}
+
+static int
+CFuncPtr_set_argtypes(CFuncPtrObject *self, PyObject *ob)
+{
+	PyObject *converters;
+
+	if (ob == NULL || ob == Py_None) {
+		Py_XDECREF(self->converters);
+		self->converters = NULL;
+		Py_XDECREF(self->argtypes);
+		self->argtypes = NULL;
+	} else {
+		converters = converters_from_argtypes(ob);
+		if (!converters)
+			return -1;
+		Py_XDECREF(self->converters);
+		self->converters = converters;
+		Py_XDECREF(self->argtypes);
+		Py_INCREF(ob);
+		self->argtypes = ob;
+	}
+	return 0;
+}
+
+static PyObject *
+CFuncPtr_get_argtypes(CFuncPtrObject *self)
+{
+	StgDictObject *dict;
+	if (self->argtypes) {
+		Py_INCREF(self->argtypes);
+		return self->argtypes;
+	}
+	dict = PyObject_stgdict((PyObject *)self);
+	assert(dict); /* Cannot be NULL for CFuncPtrObject instances */
+	if (dict->argtypes) {
+		Py_INCREF(dict->argtypes);
+		return dict->argtypes;
+	} else {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+}
+
+static PyGetSetDef CFuncPtr_getsets[] = {
+	{ "errcheck", (getter)CFuncPtr_get_errcheck, (setter)CFuncPtr_set_errcheck,
+	  "a function to check for errors", NULL },
+	{ "restype", (getter)CFuncPtr_get_restype, (setter)CFuncPtr_set_restype,
+	  "specify the result type", NULL },
+	{ "argtypes", (getter)CFuncPtr_get_argtypes,
+	  (setter)CFuncPtr_set_argtypes,
+	  "specify the argument types", NULL },
+	{ NULL, NULL }
+};
+
+#ifdef MS_WIN32
+static PPROC FindAddress(void *handle, char *name, PyObject *type)
+{
+	PPROC address;
+	char *mangled_name;
+	int i;
+	StgDictObject *dict = PyType_stgdict((PyObject *)type);
+
+	address = (PPROC)GetProcAddress(handle, name);
+	if (address)
+		return address;
+
+	if (((size_t)name & ~0xFFFF) == 0) {
+		return NULL;
+	}
+
+	/* It should not happen that dict is NULL, but better be safe */
+	if (dict==NULL || dict->flags & FUNCFLAG_CDECL)
+		return address;
+
+	/* for stdcall, try mangled names:
+	   funcname -> _funcname@<n>
+	   where n is 0, 4, 8, 12, ..., 128
+	 */
+	mangled_name = alloca(strlen(name) + 1 + 1 + 1 + 3); /* \0 _ @ %d */
+	if (!mangled_name)
+		return NULL;
+	for (i = 0; i < 32; ++i) {
+		sprintf(mangled_name, "_%s@%d", name, i*4);
+		address = (PPROC)GetProcAddress(handle, mangled_name);
+		if (address)
+			return address;
+	}
+	return NULL;
+}
+#endif
+
+/* Return 1 if usable, 0 else and exception set. */
+static int
+_check_outarg_type(PyObject *arg, int index)
+{
+	StgDictObject *dict;
+
+	if (PointerTypeObject_Check(arg))
+		return 1;
+
+	if (ArrayTypeObject_Check(arg))
+		return 1;
+
+	dict = PyType_stgdict(arg);
+	if (dict
+	    /* simple pointer types, c_void_p, c_wchar_p, BSTR, ... */
+	    && PyString_Check(dict->proto)
+/* We only allow c_void_p, c_char_p and c_wchar_p as a simple output parameter type */
+	    && (strchr("PzZ", PyString_AS_STRING(dict->proto)[0]))) {
+		return 1;
+	}
+
+	PyErr_Format(PyExc_TypeError,
+		     "'out' parameter %d must be a pointer type, not %s",
+		     index,
+		     PyType_Check(arg) ?
+		     ((PyTypeObject *)arg)->tp_name :
+		     arg->ob_type->tp_name);
+	return 0;
+}
+
+/* Returns 1 on success, 0 on error */
+static int
+_validate_paramflags(PyTypeObject *type, PyObject *paramflags)
+{
+	int i, len;
+	StgDictObject *dict;
+	PyObject *argtypes;
+
+	dict = PyType_stgdict((PyObject *)type);
+	assert(dict); /* Cannot be NULL. 'type' is a CFuncPtr type. */
+	argtypes = dict->argtypes;
+
+	if (paramflags == NULL || dict->argtypes == NULL)
+		return 1;
+
+	if (!PyTuple_Check(paramflags)) {
+		PyErr_SetString(PyExc_TypeError,
+				"paramflags must be a tuple or None");
+		return 0;
+	}
+
+	len = PyTuple_GET_SIZE(paramflags);
+	if (len != PyTuple_GET_SIZE(dict->argtypes)) {
+		PyErr_SetString(PyExc_ValueError,
+				"paramflags must have the same length as argtypes");
+		return 0;
+	}
+	
+	for (i = 0; i < len; ++i) {
+		PyObject *item = PyTuple_GET_ITEM(paramflags, i);
+		int flag;
+		char *name;
+		PyObject *defval;
+		PyObject *typ;
+		if (!PyArg_ParseTuple(item, "i|zO", &flag, &name, &defval)) {
+			PyErr_SetString(PyExc_TypeError,
+			       "paramflags must be a sequence of (int [,string [,value]]) tuples");
+			return 0;
+		}
+		typ = PyTuple_GET_ITEM(argtypes, i);
+		switch (flag & (PARAMFLAG_FIN | PARAMFLAG_FOUT | PARAMFLAG_FLCID)) {
+		case 0:
+		case PARAMFLAG_FIN:
+		case PARAMFLAG_FIN | PARAMFLAG_FLCID:
+		case PARAMFLAG_FIN | PARAMFLAG_FOUT:
+			break;
+		case PARAMFLAG_FOUT:
+			if (!_check_outarg_type(typ, i+1))
+				return 0;
+			break;
+		default:
+			PyErr_Format(PyExc_TypeError,
+				     "paramflag value %d not supported",
+				     flag);
+			return 0;
+		}
+	}
+	return 1;
+}
+
+static int
+_get_name(PyObject *obj, char **pname)
+{
+#ifdef MS_WIN32
+	if (PyInt_Check(obj) || PyLong_Check(obj)) {
+		/* We have to use MAKEINTRESOURCEA for Windows CE.
+		   Works on Windows as well, of course.
+		*/
+		*pname = MAKEINTRESOURCEA(PyInt_AsUnsignedLongMask(obj) & 0xFFFF);
+		return 1;
+	}
+#endif
+	if (PyString_Check(obj) || PyUnicode_Check(obj)) {
+		*pname = PyString_AsString(obj);
+		return *pname ? 1 : 0;
+	}
+	PyErr_SetString(PyExc_TypeError,
+			"function name must be string or integer");
+	return 0;
+}
+
+
+static PyObject *
+CFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	char *name;
+	int (* address)(void);
+	PyObject *dll;
+	PyObject *obj;
+	CFuncPtrObject *self;
+	void *handle;
+	PyObject *paramflags = NULL;
+
+	if (!PyArg_ParseTuple(args, "(O&O)|O", _get_name, &name, &dll, &paramflags))
+		return NULL;
+	if (paramflags == Py_None)
+		paramflags = NULL;
+
+	obj = PyObject_GetAttrString(dll, "_handle");
+	if (!obj)
+		return NULL;
+	if (!PyInt_Check(obj) && !PyLong_Check(obj)) {
+		PyErr_SetString(PyExc_TypeError,
+				"the _handle attribute of the second argument must be an integer");
+		Py_DECREF(obj);
+		return NULL;
+	}
+	handle = (void *)PyLong_AsVoidPtr(obj);
+	Py_DECREF(obj);
+	if (PyErr_Occurred()) {
+		PyErr_SetString(PyExc_ValueError,
+				"could not convert the _handle attribute to a pointer");
+		return NULL;
+	}
+
+#ifdef MS_WIN32
+	address = FindAddress(handle, name, (PyObject *)type);
+	if (!address) {
+		if (!IS_INTRESOURCE(name))
+			PyErr_Format(PyExc_AttributeError,
+				     "function '%s' not found",
+				     name);
+		else
+			PyErr_Format(PyExc_AttributeError,
+				     "function ordinal %d not found",
+				     (WORD)(size_t)name);
+		return NULL;
+	}
+#else
+	address = (PPROC)ctypes_dlsym(handle, name);
+	if (!address) {
+		PyErr_Format(PyExc_AttributeError,
+#ifdef __CYGWIN__
+/* dlerror() isn't very helpful on cygwin */
+			     "function '%s' not found (%s) ",
+			     name,
+#endif
+			     ctypes_dlerror());
+		return NULL;
+	}
+#endif
+	if (!_validate_paramflags(type, paramflags))
+		return NULL;
+
+	self = (CFuncPtrObject *)GenericCData_new(type, args, kwds);
+	if (!self)
+		return NULL;
+
+	Py_XINCREF(paramflags);
+	self->paramflags = paramflags;
+
+	*(void **)self->b_ptr = address;
+
+	Py_INCREF((PyObject *)dll); /* for KeepRef */
+	if (-1 == KeepRef((CDataObject *)self, 0, dll)) {
+		Py_DECREF((PyObject *)self);
+		return NULL;
+	}
+
+	Py_INCREF(self);
+	self->callable = (PyObject *)self;
+	return (PyObject *)self;
+}
+
+#ifdef MS_WIN32
+static PyObject *
+CFuncPtr_FromVtblIndex(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	CFuncPtrObject *self;
+	int index;
+	char *name = NULL;
+	PyObject *paramflags = NULL;
+	GUID *iid = NULL;
+	int iid_len = 0;
+
+	if (!PyArg_ParseTuple(args, "is|Oz#", &index, &name, &paramflags, &iid, &iid_len))
+		return NULL;
+	if (paramflags == Py_None)
+		paramflags = NULL;
+
+	if (!_validate_paramflags(type, paramflags))
+		return NULL;
+
+	self = (CFuncPtrObject *)GenericCData_new(type, args, kwds);
+	self->index = index + 0x1000;
+	Py_XINCREF(paramflags);
+	self->paramflags = paramflags;
+	if (iid_len == sizeof(GUID))
+		self->iid = iid;
+	return (PyObject *)self;
+}
+#endif
+
+/*
+  CFuncPtr_new accepts different argument lists in addition to the standard
+  _basespec_ keyword arg:
+
+  one argument form
+  "i" - function address
+  "O" - must be a callable, creates a C callable function
+
+  two or more argument forms (the third argument is a paramflags tuple)
+  "(sO)|..." - (function name, dll object (with an integer handle)), paramflags
+  "(iO)|..." - (function ordinal, dll object (with an integer handle)), paramflags
+  "is|..." - vtable index, method name, creates callable calling COM vtbl
+*/
+static PyObject *
+CFuncPtr_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	CFuncPtrObject *self;
+	PyObject *callable;
+	StgDictObject *dict;
+	ffi_info *thunk;
+
+	if (PyTuple_GET_SIZE(args) == 0)
+		return GenericCData_new(type, args, kwds);
+
+	if (1 <= PyTuple_GET_SIZE(args) && PyTuple_Check(PyTuple_GET_ITEM(args, 0)))
+		return CFuncPtr_FromDll(type, args, kwds);
+
+#ifdef MS_WIN32
+	if (2 <= PyTuple_GET_SIZE(args) && PyInt_Check(PyTuple_GET_ITEM(args, 0)))
+		return CFuncPtr_FromVtblIndex(type, args, kwds);
+#endif
+
+	if (1 == PyTuple_GET_SIZE(args)
+	    && (PyInt_Check(PyTuple_GET_ITEM(args, 0))
+		|| PyLong_Check(PyTuple_GET_ITEM(args, 0)))) {
+		CDataObject *ob;
+		void *ptr = PyLong_AsVoidPtr(PyTuple_GET_ITEM(args, 0));
+		if (ptr == NULL)
+			return NULL;
+		ob = (CDataObject *)GenericCData_new(type, args, kwds);
+		if (ob == NULL)
+			return NULL;
+		*(void **)ob->b_ptr = ptr;
+		return (PyObject *)ob;
+	}
+
+	if (!PyArg_ParseTuple(args, "O", &callable))
+		return NULL;
+	if (!PyCallable_Check(callable)) {
+		PyErr_SetString(PyExc_TypeError,
+				"argument must be callable or integer function address");
+		return NULL;
+	}
+
+	/* XXX XXX This would allow to pass additional options.  For COM
+	   method *implementations*, we would probably want different
+	   behaviour than in 'normal' callback functions: return a HRESULT if
+	   an exception occurrs in the callback, and print the traceback not
+	   only on the console, but also to OutputDebugString() or something
+	   like that.
+	*/
+/*
+	if (kwds && PyDict_GetItemString(kwds, "options")) {
+		...
+	}
+*/
+
+	dict = PyType_stgdict((PyObject *)type);
+	/* XXXX Fails if we do: 'CFuncPtr(lambda x: x)' */
+	if (!dict || !dict->argtypes) {
+		PyErr_SetString(PyExc_TypeError,
+		       "cannot construct instance of this class:"
+			" no argtypes");
+		return NULL;
+	}
+
+	/*****************************************************************/
+	/* The thunk keeps unowned references to callable and dict->argtypes
+	   so we have to keep them alive somewhere else: callable is kept in self,
+	   dict->argtypes is in the type's stgdict.
+	*/
+	thunk = AllocFunctionCallback(callable,
+				      dict->argtypes,
+				      dict->restype,
+				      dict->flags & FUNCFLAG_CDECL);
+	if (!thunk)
+		return NULL;
+
+	self = (CFuncPtrObject *)GenericCData_new(type, args, kwds);
+	if (self == NULL)
+		return NULL;
+
+	Py_INCREF(callable);
+	self->callable = callable;
+
+	self->thunk = thunk;
+	*(void **)self->b_ptr = *(void **)thunk;
+
+	/* We store ourself in self->b_objects[0], because the whole instance
+	   must be kept alive if stored in a structure field, for example.
+	   Cycle GC to the rescue! And we have a unittest proving that this works
+	   correctly...
+	*/
+
+	Py_INCREF((PyObject *)self); /* for KeepRef */
+	if (-1 == KeepRef((CDataObject *)self, 0, (PyObject *)self)) {
+		Py_DECREF((PyObject *)self);
+		return NULL;
+	}
+
+	return (PyObject *)self;
+}
+
+
+/*
+  _byref consumes a refcount to its argument
+*/
+static PyObject *
+_byref(PyObject *obj)
+{
+	PyCArgObject *parg;
+	if (!CDataObject_Check(obj)) {
+		PyErr_SetString(PyExc_TypeError,
+				"expected CData instance");
+		return NULL;
+	}
+
+	parg = new_CArgObject();
+	if (parg == NULL) {
+		Py_DECREF(obj);
+		return NULL;
+	}
+
+	parg->tag = 'P';
+	parg->pffi_type = &ffi_type_pointer;
+	parg->obj = obj;
+	parg->value.p = ((CDataObject *)obj)->b_ptr;
+	return (PyObject *)parg;
+}
+
+static PyObject *
+_get_arg(int *pindex, char *name, PyObject *defval, PyObject *inargs, PyObject *kwds)
+{
+	PyObject *v;
+
+	if (*pindex < PyTuple_GET_SIZE(inargs)) {
+		v = PyTuple_GET_ITEM(inargs, *pindex);
+		++*pindex;
+		Py_INCREF(v);
+		return v;
+	}
+	if (kwds && (v = PyDict_GetItemString(kwds, name))) {
+		++*pindex;
+		Py_INCREF(v);
+		return v;
+	}
+	if (defval) {
+		Py_INCREF(defval);
+		return defval;
+	}
+	/* we can't currently emit a better error message */
+	if (name)
+		PyErr_Format(PyExc_TypeError,
+			     "required argument '%s' missing", name);
+	else
+		PyErr_Format(PyExc_TypeError,
+			     "not enough arguments");
+	return NULL;
+}
+
+/*
+ This function implements higher level functionality plus the ability to call
+ functions with keyword arguments by looking at parameter flags.  parameter
+ flags is a tuple of 1, 2 or 3-tuples.  The first entry in each is an integer
+ specifying the direction of the data transfer for this parameter - 'in',
+ 'out' or 'inout' (zero means the same as 'in').  The second entry is the
+ parameter name, and the third is the default value if the parameter is
+ missing in the function call.
+
+ This function builds and returns a new tuple 'callargs' which contains the
+ parameters to use in the call.  Items on this tuple are copied from the
+ 'inargs' tuple for 'in' and 'in, out' parameters, and constructed from the
+ 'argtypes' tuple for 'out' parameters.  It also calculates numretvals which
+ is the number of return values for the function, outmask/inoutmask are
+ bitmasks containing indexes into the callargs tuple specifying which
+ parameters have to be returned.  _build_result builds the return value of the
+ function.
+*/
+static PyObject *
+_build_callargs(CFuncPtrObject *self, PyObject *argtypes,
+		PyObject *inargs, PyObject *kwds,
+		int *poutmask, int *pinoutmask, unsigned int *pnumretvals)
+{
+	PyObject *paramflags = self->paramflags;
+	PyObject *callargs;
+	StgDictObject *dict;
+	int i, len;
+	int inargs_index = 0;
+	/* It's a little bit difficult to determine how many arguments the
+	function call requires/accepts.  For simplicity, we count the consumed
+	args and compare this to the number of supplied args. */
+	int actual_args;
+
+	*poutmask = 0;
+	*pinoutmask = 0;
+	*pnumretvals = 0;
+
+	/* Trivial cases, where we either return inargs itself, or a slice of it. */
+	if (argtypes == NULL || paramflags == NULL || PyTuple_GET_SIZE(argtypes) == 0) {
+#ifdef MS_WIN32
+		if (self->index)
+			return PyTuple_GetSlice(inargs, 1, PyTuple_GET_SIZE(inargs));
+#endif
+		Py_INCREF(inargs);
+		return inargs;
+	}
+
+	len = PyTuple_GET_SIZE(argtypes);
+	callargs = PyTuple_New(len); /* the argument tuple we build */
+	if (callargs == NULL)
+		return NULL;
+
+#ifdef MS_WIN32
+	/* For a COM method, skip the first arg */
+	if (self->index) {
+		inargs_index = 1;
+	}
+#endif
+	for (i = 0; i < len; ++i) {
+		PyObject *item = PyTuple_GET_ITEM(paramflags, i);
+		PyObject *ob;
+		int flag;
+		char *name = NULL;
+		PyObject *defval = NULL;
+
+		/* This way seems to be ~2 us faster than the PyArg_ParseTuple
+		   calls below. */
+		/* We HAVE already checked that the tuple can be parsed with "i|zO", so... */
+		int tsize = PyTuple_GET_SIZE(item);
+		flag = PyInt_AS_LONG(PyTuple_GET_ITEM(item, 0));
+		name = tsize > 1 ? PyString_AS_STRING(PyTuple_GET_ITEM(item, 1)) : NULL;
+		defval = tsize > 2 ? PyTuple_GET_ITEM(item, 2) : NULL;
+
+		switch (flag & (PARAMFLAG_FIN | PARAMFLAG_FOUT | PARAMFLAG_FLCID)) {
+		case PARAMFLAG_FIN | PARAMFLAG_FLCID:
+			/* ['in', 'lcid'] parameter.  Always taken from defval,
+			 if given, else the integer 0. */
+			if (defval == NULL) {
+				defval = PyInt_FromLong(0);
+				if (defval == NULL)
+					goto error;
+			} else
+				Py_INCREF(defval);
+			PyTuple_SET_ITEM(callargs, i, defval);
+			break;
+		case (PARAMFLAG_FIN | PARAMFLAG_FOUT):
+			*pinoutmask |= (1 << i); /* mark as inout arg */
+			(*pnumretvals)++;
+			/* fall through to PARAMFLAG_FIN... */
+		case 0:
+		case PARAMFLAG_FIN:
+			/* 'in' parameter.  Copy it from inargs. */
+			ob =_get_arg(&inargs_index, name, defval, inargs, kwds);
+			if (ob == NULL)
+				goto error;
+			PyTuple_SET_ITEM(callargs, i, ob);
+			break;
+		case PARAMFLAG_FOUT:
+			/* XXX Refactor this code into a separate function. */
+			/* 'out' parameter.
+			   argtypes[i] must be a POINTER to a c type.
+
+			   Cannot by supplied in inargs, but a defval will be used
+			   if available.  XXX Should we support getting it from kwds?
+			*/
+			if (defval) {
+				/* XXX Using mutable objects as defval will
+				   make the function non-threadsafe, unless we
+				   copy the object in each invocation */
+				Py_INCREF(defval);
+				PyTuple_SET_ITEM(callargs, i, defval);
+				*poutmask |= (1 << i); /* mark as out arg */
+				(*pnumretvals)++;
+				break;
+			}
+			ob = PyTuple_GET_ITEM(argtypes, i);
+			dict = PyType_stgdict(ob);
+			if (dict == NULL) {
+				/* Cannot happen: _validate_paramflags()
+				  would not accept such an object */
+				PyErr_Format(PyExc_RuntimeError,
+					     "NULL stgdict unexpected");
+				goto error;
+			}
+			if (PyString_Check(dict->proto)) {
+				PyErr_Format(
+					PyExc_TypeError,
+					"%s 'out' parameter must be passed as default value",
+					((PyTypeObject *)ob)->tp_name);
+				goto error;
+			}
+			if (ArrayTypeObject_Check(ob))
+				ob = PyObject_CallObject(ob, NULL);
+			else
+				/* Create an instance of the pointed-to type */
+				ob = PyObject_CallObject(dict->proto, NULL);
+			/*			   
+			   XXX Is the following correct any longer?
+			   We must not pass a byref() to the array then but
+			   the array instance itself. Then, we cannot retrive
+			   the result from the PyCArgObject.
+			*/
+			if (ob == NULL)
+				goto error;
+			/* The .from_param call that will ocurr later will pass this
+			   as a byref parameter. */
+			PyTuple_SET_ITEM(callargs, i, ob);
+			*poutmask |= (1 << i); /* mark as out arg */
+			(*pnumretvals)++;
+			break;
+		default:
+			PyErr_Format(PyExc_ValueError,
+				     "paramflag %d not yet implemented", flag);
+			goto error;
+			break;
+		}
+	}
+
+	/* We have counted the arguments we have consumed in 'inargs_index'.  This
+	   must be the same as len(inargs) + len(kwds), otherwise we have
+	   either too much or not enough arguments. */
+
+	actual_args = PyTuple_GET_SIZE(inargs) + (kwds ? PyDict_Size(kwds) : 0);
+	if (actual_args != inargs_index) {
+		/* When we have default values or named parameters, this error
+		   message is misleading.  See unittests/test_paramflags.py
+		 */
+		PyErr_Format(PyExc_TypeError,
+			     "call takes exactly %d arguments (%d given)",
+			     inargs_index, actual_args);
+		goto error;
+	}
+
+	/* outmask is a bitmask containing indexes into callargs.  Items at
+	   these indexes contain values to return.
+	 */
+	return callargs;
+  error:
+	Py_DECREF(callargs);
+	return NULL;
+}
+
+/* See also:
+   http://msdn.microsoft.com/library/en-us/com/html/769127a1-1a14-4ed4-9d38-7cf3e571b661.asp
+*/
+/*
+  Build return value of a function.
+
+  Consumes the refcount on result and callargs.
+*/
+static PyObject *
+_build_result(PyObject *result, PyObject *callargs,
+	      int outmask, int inoutmask, unsigned int numretvals)
+{
+	unsigned int i, index;
+	int bit;
+	PyObject *tup = NULL;
+
+	if (callargs == NULL)
+		return result;
+	if (result == NULL || numretvals == 0) {
+		Py_DECREF(callargs);
+		return result;
+	}
+	Py_DECREF(result);
+
+	/* tup will not be allocated if numretvals == 1 */
+	/* allocate tuple to hold the result */
+	if (numretvals > 1) {
+		tup = PyTuple_New(numretvals);
+		if (tup == NULL) {
+			Py_DECREF(callargs);
+			return NULL;
+		}
+	}
+
+	index = 0;
+	for (bit = 1, i = 0; i < 32; ++i, bit <<= 1) {
+		PyObject *v;
+		if (bit & inoutmask) {
+			v = PyTuple_GET_ITEM(callargs, i);
+			Py_INCREF(v);
+			if (numretvals == 1) {
+				Py_DECREF(callargs);
+				return v;
+			}
+			PyTuple_SET_ITEM(tup, index, v);
+			index++;
+		} else if (bit & outmask) {
+			v = PyTuple_GET_ITEM(callargs, i);
+			v = PyObject_CallMethod(v, "__ctypes_from_outparam__", NULL);
+			if (v == NULL || numretvals == 1) {
+				Py_DECREF(callargs);
+				return v;
+			}
+			PyTuple_SET_ITEM(tup, index, v);
+			index++;
+		}
+		if (index == numretvals)
+			break;
+	}
+
+	Py_DECREF(callargs);
+	return tup;
+}
+
+static PyObject *
+CFuncPtr_call(CFuncPtrObject *self, PyObject *inargs, PyObject *kwds)
+{
+	PyObject *restype;
+	PyObject *converters;
+	PyObject *checker;
+	PyObject *argtypes;
+	StgDictObject *dict = PyObject_stgdict((PyObject *)self);
+	PyObject *result;
+	PyObject *callargs;
+	PyObject *errcheck;
+#ifdef MS_WIN32
+	IUnknown *piunk = NULL;
+#endif
+	void *pProc = NULL;
+
+	int inoutmask;
+	int outmask;
+	unsigned int numretvals;
+
+	assert(dict); /* Cannot be NULL for CFuncPtrObject instances */
+	restype = self->restype ? self->restype : dict->restype;
+	converters = self->converters ? self->converters : dict->converters;
+	checker = self->checker ? self->checker : dict->checker;
+	argtypes = self->argtypes ? self->argtypes : dict->argtypes;
+/* later, we probably want to have an errcheck field in stgdict */
+	errcheck = self->errcheck /* ? self->errcheck : dict->errcheck */;
+
+
+	pProc = *(void **)self->b_ptr;
+#ifdef MS_WIN32
+	if (self->index) {
+		/* It's a COM method */
+		CDataObject *this;
+		this = (CDataObject *)PyTuple_GetItem(inargs, 0); /* borrowed ref! */
+		if (!this) {
+			PyErr_SetString(PyExc_ValueError,
+					"native com method call without 'this' parameter");
+			return NULL;
+		}
+		if (!CDataObject_Check(this)) {
+			PyErr_SetString(PyExc_TypeError,
+					"Expected a COM this pointer as first argument");
+			return NULL;
+		}
+		/* there should be more checks? No, in Python */
+		/* First arg is an pointer to an interface instance */
+		if (!this->b_ptr || *(void **)this->b_ptr == NULL) {
+			PyErr_SetString(PyExc_ValueError,
+					"NULL COM pointer access");
+			return NULL;
+		}
+		piunk = *(IUnknown **)this->b_ptr;
+		if (NULL == piunk->lpVtbl) {
+			PyErr_SetString(PyExc_ValueError,
+					"COM method call without VTable");
+			return NULL;
+		}
+		pProc = ((void **)piunk->lpVtbl)[self->index - 0x1000];
+	}
+#endif
+	callargs = _build_callargs(self, argtypes,
+				   inargs, kwds,
+				   &outmask, &inoutmask, &numretvals);
+	if (callargs == NULL)
+		return NULL;
+
+	if (converters) {
+		int required = PyTuple_GET_SIZE(converters);
+		int actual = PyTuple_GET_SIZE(callargs);
+
+		if ((dict->flags & FUNCFLAG_CDECL) == FUNCFLAG_CDECL) {
+			/* For cdecl functions, we allow more actual arguments
+			   than the length of the argtypes tuple.
+			*/
+			if (required > actual) {
+				Py_DECREF(callargs);
+				PyErr_Format(PyExc_TypeError,
+			  "this function takes at least %d argument%s (%d given)",
+					     required,
+					     required == 1 ? "" : "s",
+					     actual);
+				return NULL;
+			}
+		} else if (required != actual) {
+			Py_DECREF(callargs);
+			PyErr_Format(PyExc_TypeError,
+			     "this function takes %d argument%s (%d given)",
+				     required,
+				     required == 1 ? "" : "s",
+				     actual);
+			return NULL;
+		}
+	}
+
+	result = _CallProc(pProc,
+			   callargs,
+#ifdef MS_WIN32
+			   piunk,
+			   self->iid,
+#endif
+			   dict->flags,
+			   converters,
+			   restype,
+			   checker);
+/* The 'errcheck' protocol */
+	if (result != NULL && errcheck) {
+		PyObject *v = PyObject_CallFunctionObjArgs(errcheck,
+							   result,
+							   self,
+							   callargs,
+							   NULL);
+		/* If the errcheck funtion failed, return NULL.
+		   If the errcheck function returned callargs unchanged,
+		   continue normal processing.
+		   If the errcheck function returned something else,
+		   use that as result.
+		*/
+		if (v == NULL || v != callargs) {
+			Py_DECREF(result);
+			Py_DECREF(callargs);
+			return v;
+		}
+		Py_DECREF(v);
+	}
+
+	return _build_result(result, callargs,
+			     outmask, inoutmask, numretvals);
+}
+
+static int
+CFuncPtr_traverse(CFuncPtrObject *self, visitproc visit, void *arg)
+{
+	Py_VISIT(self->callable);
+	Py_VISIT(self->restype);
+	Py_VISIT(self->checker);
+	Py_VISIT(self->errcheck);
+	Py_VISIT(self->argtypes);
+	Py_VISIT(self->converters);
+	Py_VISIT(self->paramflags);
+	return CData_traverse((CDataObject *)self, visit, arg);
+}
+
+static int
+CFuncPtr_clear(CFuncPtrObject *self)
+{
+	Py_CLEAR(self->callable);
+	Py_CLEAR(self->restype);
+	Py_CLEAR(self->checker);
+	Py_CLEAR(self->errcheck);
+	Py_CLEAR(self->argtypes);
+	Py_CLEAR(self->converters);
+	Py_CLEAR(self->paramflags);
+
+	if (self->thunk) {
+		FreeClosure(self->thunk->pcl);
+		PyMem_Free(self->thunk);
+		self->thunk = NULL;
+	}
+
+	return CData_clear((CDataObject *)self);
+}
+
+static void
+CFuncPtr_dealloc(CFuncPtrObject *self)
+{
+	CFuncPtr_clear(self);
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *
+CFuncPtr_repr(CFuncPtrObject *self)
+{
+#ifdef MS_WIN32
+	if (self->index)
+		return PyString_FromFormat("<COM method offset %d: %s at %p>",
+					   self->index - 0x1000,
+					   self->ob_type->tp_name,
+					   self);
+#endif
+	return PyString_FromFormat("<%s object at %p>",
+				   self->ob_type->tp_name,
+				   self);
+}
+
+PyTypeObject CFuncPtr_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0,
+	"_ctypes.CFuncPtr",
+	sizeof(CFuncPtrObject),			/* tp_basicsize */
+	0,					/* tp_itemsize */
+	(destructor)CFuncPtr_dealloc,		/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	(reprfunc)CFuncPtr_repr,		/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	(ternaryfunc)CFuncPtr_call,		/* tp_call */
+	0,					/* tp_str */
+	0,					/* tp_getattro */
+	0,					/* tp_setattro */
+	&CData_as_buffer,			/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+	"Function Pointer",			/* tp_doc */
+	(traverseproc)CFuncPtr_traverse,	/* tp_traverse */
+	(inquiry)CFuncPtr_clear,		/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	0,					/* tp_methods */
+	0,					/* tp_members */
+	CFuncPtr_getsets,			/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	0,					/* tp_init */
+	0,					/* tp_alloc */
+        CFuncPtr_new,				/* tp_new */
+	0,					/* tp_free */
+};
+
+/*****************************************************************/
+/*
+  Struct_Type
+*/
+static int
+IBUG(char *msg)
+{
+	PyErr_Format(PyExc_RuntimeError,
+			"inconsistent state in CDataObject (%s)", msg);
+	return -1;
+}
+
+static int
+Struct_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+	int i;
+	PyObject *fields;
+
+/* Optimization possible: Store the attribute names _fields_[x][0]
+ * in C accessible fields somewhere ?
+ */
+
+/* Check this code again for correctness! */
+
+	if (!PyTuple_Check(args)) {
+		PyErr_SetString(PyExc_TypeError,
+				"args not a tuple?");
+		return -1;
+	}
+	if (PyTuple_GET_SIZE(args)) {
+		fields = PyObject_GetAttrString(self, "_fields_");
+		if (!fields) {
+			PyErr_Clear();
+			fields = PyTuple_New(0);
+			if (!fields)
+				return -1;
+		}
+
+		if (PyTuple_GET_SIZE(args) > PySequence_Length(fields)) {
+			Py_DECREF(fields);
+			PyErr_SetString(PyExc_ValueError,
+					"too many initializers");
+			return -1;
+		}
+
+		for (i = 0; i < PyTuple_GET_SIZE(args); ++i) {
+			PyObject *pair = PySequence_GetItem(fields, i);
+			PyObject *name;
+			PyObject *val;
+			if (!pair) {
+				Py_DECREF(fields);
+				return IBUG("_fields_[i] failed");
+			}
+
+			name = PySequence_GetItem(pair, 0);
+			if (!name) {
+				Py_DECREF(pair);
+				Py_DECREF(fields);
+				return IBUG("_fields_[i][0] failed");
+			}
+
+			val = PyTuple_GET_ITEM(args, i);
+			if (-1 == PyObject_SetAttr(self, name, val)) {
+				Py_DECREF(pair);
+				Py_DECREF(name);
+				Py_DECREF(fields);
+				return -1;
+			}
+
+			Py_DECREF(name);
+			Py_DECREF(pair);
+		}
+		Py_DECREF(fields);
+	}
+
+	if (kwds) {
+		PyObject *key, *value;
+		Py_ssize_t pos = 0;
+		while(PyDict_Next(kwds, &pos, &key, &value)) {
+			if (-1 == PyObject_SetAttr(self, key, value))
+				return -1;
+		}
+	}
+	return 0;
+}
+
+static PyTypeObject Struct_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0,
+	"_ctypes.Structure",
+	sizeof(CDataObject),			/* tp_basicsize */
+	0,					/* tp_itemsize */
+	0,					/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	0,					/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	0,					/* tp_getattro */
+	0,					/* tp_setattro */
+	&CData_as_buffer,			/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+	"Structure base class",			/* tp_doc */
+	(traverseproc)CData_traverse,		/* tp_traverse */
+	(inquiry)CData_clear,			/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	0,					/* tp_methods */
+	0,					/* tp_members */
+	0,					/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	Struct_init,				/* tp_init */
+	0,					/* tp_alloc */
+	GenericCData_new,			/* tp_new */
+	0,					/* tp_free */
+};
+
+static PyTypeObject Union_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0,
+	"_ctypes.Union",
+	sizeof(CDataObject),			/* tp_basicsize */
+	0,					/* tp_itemsize */
+	0,					/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	0,					/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	0,					/* tp_getattro */
+	0,					/* tp_setattro */
+	&CData_as_buffer,			/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+	"Union base class",			/* tp_doc */
+	(traverseproc)CData_traverse,		/* tp_traverse */
+	(inquiry)CData_clear,			/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	0,					/* tp_methods */
+	0,					/* tp_members */
+	0,					/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	Struct_init,				/* tp_init */
+	0,					/* tp_alloc */
+	GenericCData_new,			/* tp_new */
+	0,					/* tp_free */
+};
+
+
+/******************************************************************/
+/*
+  Array_Type
+*/
+static int
+Array_init(CDataObject *self, PyObject *args, PyObject *kw)
+{
+	int i;
+	int n;
+
+	if (!PyTuple_Check(args)) {
+		PyErr_SetString(PyExc_TypeError,
+				"args not a tuple?");
+		return -1;
+	}
+	n = PyTuple_GET_SIZE(args);
+	for (i = 0; i < n; ++i) {
+		PyObject *v;
+		v = PyTuple_GET_ITEM(args, i);
+		if (-1 == PySequence_SetItem((PyObject *)self, i, v))
+			return -1;
+	}
+	return 0;
+}
+
+static PyObject *
+Array_item(PyObject *_self, Py_ssize_t index)
+{
+	CDataObject *self = (CDataObject *)_self;
+	int offset, size;
+	StgDictObject *stgdict;
+
+
+	if (index < 0 || index >= self->b_length) {
+		PyErr_SetString(PyExc_IndexError,
+				"invalid index");
+		return NULL;
+	}
+
+	stgdict = PyObject_stgdict((PyObject *)self);
+	assert(stgdict); /* Cannot be NULL for array instances */
+	/* Would it be clearer if we got the item size from
+	   stgdict->proto's stgdict?
+	*/
+	size = stgdict->size / stgdict->length;
+	offset = index * size;
+
+	return CData_get(stgdict->proto, stgdict->getfunc, (PyObject *)self,
+			 index, size, self->b_ptr + offset);
+}
+
+static PyObject *
+Array_slice(PyObject *_self, Py_ssize_t ilow, Py_ssize_t ihigh)
+{
+	CDataObject *self = (CDataObject *)_self;
+	StgDictObject *stgdict, *itemdict;
+	PyObject *proto;
+	PyListObject *np;
+	Py_ssize_t i, len;
+
+	if (ilow < 0)
+		ilow = 0;
+	else if (ilow > self->b_length)
+		ilow = self->b_length;
+	if (ihigh < ilow)
+		ihigh = ilow;
+	else if (ihigh > self->b_length)
+		ihigh = self->b_length;
+	len = ihigh - ilow;
+
+	stgdict = PyObject_stgdict((PyObject *)self);
+	assert(stgdict); /* Cannot be NULL for array object instances */
+	proto = stgdict->proto;
+	itemdict = PyType_stgdict(proto);
+	assert(itemdict); /* proto is the item type of the array, a ctypes
+			     type, so this cannot be NULL */
+	if (itemdict->getfunc == getentry("c")->getfunc) {
+		char *ptr = (char *)self->b_ptr;
+		return PyString_FromStringAndSize(ptr + ilow, len);
+#ifdef CTYPES_UNICODE
+	} else if (itemdict->getfunc == getentry("u")->getfunc) {
+		wchar_t *ptr = (wchar_t *)self->b_ptr;
+		return PyUnicode_FromWideChar(ptr + ilow, len);
+#endif
+	}
+
+	np = (PyListObject *) PyList_New(len);
+	if (np == NULL)
+		return NULL;
+
+	for (i = 0; i < len; i++) {
+		PyObject *v = Array_item(_self, i+ilow);
+		PyList_SET_ITEM(np, i, v);
+	}
+	return (PyObject *)np;
+}
+
+static int
+Array_ass_item(PyObject *_self, Py_ssize_t index, PyObject *value)
+{
+	CDataObject *self = (CDataObject *)_self;
+	int size, offset;
+	StgDictObject *stgdict;
+	char *ptr;
+
+	if (value == NULL) {
+		PyErr_SetString(PyExc_TypeError,
+				"Array does not support item deletion");
+		return -1;
+	}
+	
+	stgdict = PyObject_stgdict((PyObject *)self);
+	assert(stgdict); /* Cannot be NULL for array object instances */
+	if (index < 0 || index >= stgdict->length) {
+		PyErr_SetString(PyExc_IndexError,
+				"invalid index");
+		return -1;
+	}
+	size = stgdict->size / stgdict->length;
+	offset = index * size;
+	ptr = self->b_ptr + offset;
+
+	return CData_set((PyObject *)self, stgdict->proto, stgdict->setfunc, value,
+			 index, size, ptr);
+}
+
+static int
+Array_ass_slice(PyObject *_self, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *value)
+{
+	CDataObject *self = (CDataObject *)_self;
+	int i, len;
+
+	if (value == NULL) {
+		PyErr_SetString(PyExc_TypeError,
+				"Array does not support item deletion");
+		return -1;
+	}
+
+	if (ilow < 0)
+		ilow = 0;
+	else if (ilow > self->b_length)
+		ilow = self->b_length;
+	if (ihigh < 0)
+		ihigh = 0;
+	if (ihigh < ilow)
+		ihigh = ilow;
+	else if (ihigh > self->b_length)
+		ihigh = self->b_length;
+
+	len = PySequence_Length(value);
+	if (len != ihigh - ilow) {
+		PyErr_SetString(PyExc_ValueError,
+				"Can only assign sequence of same size");
+		return -1;
+	}
+	for (i = 0; i < len; i++) {
+		PyObject *item = PySequence_GetItem(value, i);
+		int result;
+		if (item == NULL)
+			return -1;
+		result = Array_ass_item(_self, i+ilow, item);
+		Py_DECREF(item);
+		if (result == -1)
+			return -1;
+	}
+	return 0;
+}
+
+static Py_ssize_t
+Array_length(PyObject *_self)
+{
+	CDataObject *self = (CDataObject *)_self;
+	return self->b_length;
+}
+
+static PySequenceMethods Array_as_sequence = {
+	Array_length,				/* sq_length; */
+	0,					/* sq_concat; */
+	0,					/* sq_repeat; */
+	Array_item,				/* sq_item; */
+	Array_slice,				/* sq_slice; */
+	Array_ass_item,				/* sq_ass_item; */
+	Array_ass_slice,			/* sq_ass_slice; */
+	0,					/* sq_contains; */
+	
+	0,					/* sq_inplace_concat; */
+	0,					/* sq_inplace_repeat; */
+};
+
+PyTypeObject Array_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0,
+	"_ctypes.Array",
+	sizeof(CDataObject),			/* tp_basicsize */
+	0,					/* tp_itemsize */
+	0,					/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	0,					/* tp_repr */
+	0,					/* tp_as_number */
+	&Array_as_sequence,			/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	0,					/* tp_getattro */
+	0,					/* tp_setattro */
+	&CData_as_buffer,			/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+	"XXX to be provided",			/* tp_doc */
+	(traverseproc)CData_traverse,		/* tp_traverse */
+	(inquiry)CData_clear,			/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	0,					/* tp_methods */
+	0,					/* tp_members */
+	0,					/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	(initproc)Array_init,			/* tp_init */
+	0,					/* tp_alloc */
+        GenericCData_new,			/* tp_new */
+	0,					/* tp_free */
+};
+
+PyObject *
+CreateArrayType(PyObject *itemtype, Py_ssize_t length)
+{
+	static PyObject *cache;
+	PyObject *key;
+	PyObject *result;
+	char name[256];
+
+	if (cache == NULL) {
+		cache = PyDict_New();
+		if (cache == NULL)
+			return NULL;
+	}
+#if (PY_VERSION_HEX < 0x02050000)
+	key = Py_BuildValue("(Oi)", itemtype, length);
+#else
+	key = Py_BuildValue("(On)", itemtype, length);
+#endif
+	if (!key)
+		return NULL;
+	result = PyDict_GetItem(cache, key);
+	if (result) {
+		Py_INCREF(result);
+		Py_DECREF(key);
+		return result;
+	}
+
+	if (!PyType_Check(itemtype)) {
+		PyErr_SetString(PyExc_TypeError,
+				"Expected a type object");
+		return NULL;
+	}
+#ifdef MS_WIN64
+	sprintf(name, "%.200s_Array_%Id",
+		((PyTypeObject *)itemtype)->tp_name, length);
+#else
+	sprintf(name, "%.200s_Array_%ld",
+		((PyTypeObject *)itemtype)->tp_name, (long)length);
+#endif
+
+	result = PyObject_CallFunction((PyObject *)&ArrayType_Type,
+#if (PY_VERSION_HEX < 0x02050000)
+				       "s(O){s:i,s:O}",
+#else
+				       "s(O){s:n,s:O}",
+#endif
+				       name,
+				       &Array_Type,
+				       "_length_",
+				       length,
+				       "_type_",
+				       itemtype
+		);
+	if (!result)
+		return NULL;
+	PyDict_SetItem(cache, key, result);
+	Py_DECREF(key);
+	return result;
+}
+
+
+/******************************************************************/
+/*
+  Simple_Type
+*/
+
+static int
+Simple_set_value(CDataObject *self, PyObject *value)
+{
+	PyObject *result;
+	StgDictObject *dict = PyObject_stgdict((PyObject *)self);
+
+	assert(dict); /* Cannot be NULL for CDataObject instances */
+	assert(dict->setfunc);
+	result = dict->setfunc(self->b_ptr, value, dict->size);
+	if (!result)
+		return -1;
+
+	/* consumes the refcount the setfunc returns */
+	return KeepRef(self, 0, result);
+}
+
+static int
+Simple_init(CDataObject *self, PyObject *args, PyObject *kw)
+{
+	PyObject *value = NULL;
+	if (!PyArg_UnpackTuple(args, "__init__", 0, 1, &value))
+		return -1;
+	if (value)
+		return Simple_set_value(self, value);
+	return 0;
+}
+
+static PyObject *
+Simple_get_value(CDataObject *self)
+{
+	StgDictObject *dict;
+	dict = PyObject_stgdict((PyObject *)self);
+	assert(dict); /* Cannot be NULL for CDataObject instances */
+	assert(dict->getfunc);
+	return dict->getfunc(self->b_ptr, self->b_size);
+}
+
+static PyGetSetDef Simple_getsets[] = {
+	{ "value", (getter)Simple_get_value, (setter)Simple_set_value,
+	  "current value", NULL },
+	{ NULL, NULL }
+};
+
+static PyObject *
+Simple_from_outparm(PyObject *self, PyObject *args)
+{
+	if (IsSimpleSubType((PyObject *)self->ob_type)) {
+		Py_INCREF(self);
+		return self;
+	}
+	/* call stgdict->getfunc */
+	return Simple_get_value((CDataObject *)self);
+}
+
+static PyMethodDef Simple_methods[] = {
+	{ "__ctypes_from_outparam__", Simple_from_outparm, METH_NOARGS, },
+	{ NULL, NULL },
+};
+
+static int Simple_nonzero(CDataObject *self)
+{
+	return memcmp(self->b_ptr, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", self->b_size);
+}
+
+static PyNumberMethods Simple_as_number = {
+	0, /* nb_add */
+	0, /* nb_subtract */
+	0, /* nb_multiply */
+	0, /* nb_divide */
+	0, /* nb_remainder */
+	0, /* nb_divmod */
+	0, /* nb_power */
+	0, /* nb_negative */
+	0, /* nb_positive */
+	0, /* nb_absolute */
+	(inquiry)Simple_nonzero, /* nb_nonzero */
+};
+
+#if (PY_VERSION_HEX < 0x02040000)
+/* Only in Python 2.4 and up */
+static PyObject *
+PyTuple_Pack(int n, ...)
+{
+	int i;
+	PyObject *o;
+	PyObject *result;
+	PyObject **items;
+	va_list vargs;
+
+	va_start(vargs, n);
+	result = PyTuple_New(n);
+	if (result == NULL)
+		return NULL;
+	items = ((PyTupleObject *)result)->ob_item;
+	for (i = 0; i < n; i++) {
+		o = va_arg(vargs, PyObject *);
+		Py_INCREF(o);
+		items[i] = o;
+	}
+	va_end(vargs);
+	return result;
+}
+#endif
+
+/* "%s(%s)" % (self.__class__.__name__, self.value) */
+static PyObject *
+Simple_repr(CDataObject *self)
+{
+	PyObject *val, *name, *args, *result;
+	static PyObject *format;
+
+	if (self->ob_type->tp_base != &Simple_Type) {
+		return PyString_FromFormat("<%s object at %p>",
+					   self->ob_type->tp_name, self);
+	}
+
+	if (format == NULL) {
+		format = PyString_FromString("%s(%r)");
+		if (format == NULL)
+			return NULL;
+	}
+
+	val = Simple_get_value(self);
+	if (val == NULL)
+		return NULL;
+
+	name = PyString_FromString(self->ob_type->tp_name);
+	if (name == NULL) {
+		Py_DECREF(val);
+		return NULL;
+	}
+
+	args = PyTuple_Pack(2, name, val);
+	Py_DECREF(name);
+	Py_DECREF(val);
+	if (args == NULL)
+		return NULL;
+
+	result = PyString_Format(format, args);
+	Py_DECREF(args);
+	return result;
+}
+
+static PyTypeObject Simple_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0,
+	"_ctypes._SimpleCData",
+	sizeof(CDataObject),			/* tp_basicsize */
+	0,					/* tp_itemsize */
+	0,					/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	(reprfunc)&Simple_repr,			/* tp_repr */
+	&Simple_as_number,			/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	0,					/* tp_getattro */
+	0,					/* tp_setattro */
+	&CData_as_buffer,			/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+	"XXX to be provided",			/* tp_doc */
+	(traverseproc)CData_traverse,		/* tp_traverse */
+	(inquiry)CData_clear,			/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	Simple_methods,				/* tp_methods */
+	0,					/* tp_members */
+	Simple_getsets,				/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	(initproc)Simple_init,			/* tp_init */
+	0,					/* tp_alloc */
+        GenericCData_new,			/* tp_new */
+	0,					/* tp_free */
+};
+
+/******************************************************************/
+/*
+  Pointer_Type
+*/
+static PyObject *
+Pointer_item(PyObject *_self, Py_ssize_t index)
+{
+	CDataObject *self = (CDataObject *)_self;
+	int size;
+	Py_ssize_t offset;
+	StgDictObject *stgdict, *itemdict;
+	PyObject *proto;
+
+	if (*(void **)self->b_ptr == NULL) {
+		PyErr_SetString(PyExc_ValueError,
+				"NULL pointer access");
+		return NULL;
+	}
+
+	stgdict = PyObject_stgdict((PyObject *)self);
+	assert(stgdict); /* Cannot be NULL for pointer object instances */
+	
+	proto = stgdict->proto;
+	assert(proto);
+	itemdict = PyType_stgdict(proto);
+	assert(itemdict); /* proto is the item type of the pointer, a ctypes
+			     type, so this cannot be NULL */
+
+	size = itemdict->size;
+	offset = index * itemdict->size;
+
+	return CData_get(proto, stgdict->getfunc, (PyObject *)self,
+			 index, size, (*(char **)self->b_ptr) + offset);
+}
+
+static int
+Pointer_ass_item(PyObject *_self, Py_ssize_t index, PyObject *value)
+{
+	CDataObject *self = (CDataObject *)_self;
+	int size;
+	Py_ssize_t offset;
+	StgDictObject *stgdict, *itemdict;
+	PyObject *proto;
+
+	if (value == NULL) {
+		PyErr_SetString(PyExc_TypeError,
+				"Pointer does not support item deletion");
+		return -1;
+	}
+
+	if (*(void **)self->b_ptr == NULL) {
+		PyErr_SetString(PyExc_ValueError,
+				"NULL pointer access");
+		return -1;
+	}
+	
+	stgdict = PyObject_stgdict((PyObject *)self);
+	assert(stgdict); /* Cannot be NULL fr pointer instances */
+
+	proto = stgdict->proto;
+	assert(proto);
+
+	itemdict = PyType_stgdict(proto);
+	assert(itemdict); /* Cannot be NULL because the itemtype of a pointer
+			     is always a ctypes type */
+
+	size = itemdict->size;
+	offset = index * itemdict->size;
+
+	return CData_set((PyObject *)self, proto, stgdict->setfunc, value,
+			 index, size, (*(char **)self->b_ptr) + offset);
+}
+
+static PyObject *
+Pointer_get_contents(CDataObject *self, void *closure)
+{
+	StgDictObject *stgdict;
+
+	if (*(void **)self->b_ptr == NULL) {
+		PyErr_SetString(PyExc_ValueError,
+				"NULL pointer access");
+		return NULL;
+	}
+
+	stgdict = PyObject_stgdict((PyObject *)self);
+	assert(stgdict); /* Cannot be NULL fr pointer instances */
+	return CData_FromBaseObj(stgdict->proto,
+				 (PyObject *)self, 0,
+				 *(void **)self->b_ptr);
+}
+
+static int
+Pointer_set_contents(CDataObject *self, PyObject *value, void *closure)
+{
+	StgDictObject *stgdict;
+	CDataObject *dst;
+	PyObject *keep;
+
+	if (value == NULL) {
+		PyErr_SetString(PyExc_TypeError,
+				"Pointer does not support item deletion");
+		return -1;
+	}
+	stgdict = PyObject_stgdict((PyObject *)self);
+	assert(stgdict); /* Cannot be NULL fr pointer instances */
+	assert(stgdict->proto);
+	if (!CDataObject_Check(value) 
+	    || 0 == PyObject_IsInstance(value, stgdict->proto)) {
+		/* XXX PyObject_IsInstance could return -1! */
+		PyErr_Format(PyExc_TypeError,
+			     "expected %s instead of %s",
+			     ((PyTypeObject *)(stgdict->proto))->tp_name,
+			     value->ob_type->tp_name);
+		return -1;
+	}
+
+	dst = (CDataObject *)value;
+	*(void **)self->b_ptr = dst->b_ptr;
+
+	/* 
+	   A Pointer instance must keep a the value it points to alive.  So, a
+	   pointer instance has b_length set to 2 instead of 1, and we set
+	   'value' itself as the second item of the b_objects list, additionally.
+	*/
+	Py_INCREF(value);
+	if (-1 == KeepRef(self, 1, value))
+		return -1;
+
+	keep = GetKeepedObjects(dst);
+	Py_INCREF(keep);
+	return KeepRef(self, 0, keep);
+}
+
+static PyGetSetDef Pointer_getsets[] = {
+	{ "contents", (getter)Pointer_get_contents,
+	  (setter)Pointer_set_contents,
+	  "the object this pointer points to (read-write)", NULL },
+	{ NULL, NULL }
+};
+
+static int
+Pointer_init(CDataObject *self, PyObject *args, PyObject *kw)
+{
+	PyObject *value = NULL;
+
+	if (!PyArg_ParseTuple(args, "|O:POINTER", &value))
+		return -1;
+	if (value == NULL)
+		return 0;
+	return Pointer_set_contents(self, value, NULL);
+}
+
+static PyObject *
+Pointer_new(PyTypeObject *type, PyObject *args, PyObject *kw)
+{
+	StgDictObject *dict = PyType_stgdict((PyObject *)type);
+	if (!dict || !dict->proto) {
+		PyErr_SetString(PyExc_TypeError,
+				"Cannot create instance: has no _type_");
+		return NULL;
+	}
+	return GenericCData_new(type, args, kw);
+}
+
+static PyObject *
+Pointer_slice(PyObject *_self, Py_ssize_t ilow, Py_ssize_t ihigh)
+{
+	CDataObject *self = (CDataObject *)_self;
+	PyListObject *np;
+	StgDictObject *stgdict, *itemdict;
+	PyObject *proto;
+	Py_ssize_t i, len;
+
+	if (ilow < 0)
+		ilow = 0;
+	if (ihigh < ilow)
+		ihigh = ilow;
+	len = ihigh - ilow;
+
+	stgdict = PyObject_stgdict((PyObject *)self);
+	assert(stgdict); /* Cannot be NULL fr pointer instances */
+	proto = stgdict->proto;
+	assert(proto);
+	itemdict = PyType_stgdict(proto);
+	assert(itemdict);
+	if (itemdict->getfunc == getentry("c")->getfunc) {
+		char *ptr = *(char **)self->b_ptr;
+		return PyString_FromStringAndSize(ptr + ilow, len);
+#ifdef CTYPES_UNICODE
+	} else if (itemdict->getfunc == getentry("u")->getfunc) {
+		wchar_t *ptr = *(wchar_t **)self->b_ptr;
+		return PyUnicode_FromWideChar(ptr + ilow, len);
+#endif
+	}
+
+	np = (PyListObject *) PyList_New(len);
+	if (np == NULL)
+		return NULL;
+
+	for (i = 0; i < len; i++) {
+		PyObject *v = Pointer_item(_self, i+ilow);
+		PyList_SET_ITEM(np, i, v);
+	}
+	return (PyObject *)np;
+}
+
+static PySequenceMethods Pointer_as_sequence = {
+	0,					/* inquiry sq_length; */
+	0,					/* binaryfunc sq_concat; */
+	0,					/* intargfunc sq_repeat; */
+	Pointer_item,				/* intargfunc sq_item; */
+	Pointer_slice,				/* intintargfunc sq_slice; */
+	Pointer_ass_item,			/* intobjargproc sq_ass_item; */
+	0,					/* intintobjargproc sq_ass_slice; */
+	0,					/* objobjproc sq_contains; */
+	/* Added in release 2.0 */
+	0,					/* binaryfunc sq_inplace_concat; */
+	0,					/* intargfunc sq_inplace_repeat; */
+};
+
+static int
+Pointer_nonzero(CDataObject *self)
+{
+	return *(void **)self->b_ptr != NULL;
+}
+
+static PyNumberMethods Pointer_as_number = {
+	0, /* nb_add */
+	0, /* nb_subtract */
+	0, /* nb_multiply */
+	0, /* nb_divide */
+	0, /* nb_remainder */
+	0, /* nb_divmod */
+	0, /* nb_power */
+	0, /* nb_negative */
+	0, /* nb_positive */
+	0, /* nb_absolute */
+	(inquiry)Pointer_nonzero, /* nb_nonzero */
+};
+
+PyTypeObject Pointer_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0,
+	"_ctypes._Pointer",
+	sizeof(CDataObject),			/* tp_basicsize */
+	0,					/* tp_itemsize */
+	0,					/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	0,					/* tp_repr */
+	&Pointer_as_number,			/* tp_as_number */
+	&Pointer_as_sequence,			/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	0,					/* tp_getattro */
+	0,					/* tp_setattro */
+	&CData_as_buffer,			/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+	"XXX to be provided",			/* tp_doc */
+	(traverseproc)CData_traverse,		/* tp_traverse */
+	(inquiry)CData_clear,			/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	0,					/* tp_methods */
+	0,					/* tp_members */
+	Pointer_getsets,			/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	(initproc)Pointer_init,			/* tp_init */
+	0,					/* tp_alloc */
+	Pointer_new,				/* tp_new */
+	0,					/* tp_free */
+};
+
+
+/******************************************************************/
+/*
+ *  Module initialization.
+ */
+
+static char *module_docs =
+"Create and manipulate C compatible data types in Python.";
+
+#ifdef MS_WIN32
+
+static char comerror_doc[] = "Raised when a COM method call failed.";
+
+static PyObject *
+comerror_str(PyObject *ignored, PyObject *self)
+{
+	PyObject *args = PyObject_GetAttrString(self, "args");
+	PyObject *result;
+	if (args == NULL)
+		return NULL;
+	result = PyObject_Str(args);
+	Py_DECREF(args);
+	return result;
+}
+
+static PyObject *
+comerror_init(PyObject *self, PyObject *args)
+{
+    PyObject *hresult, *text, *details;
+    PyObject *a;
+    int status;
+
+    if (!PyArg_ParseTuple(args, "OOOO:COMError", &self, &hresult, &text, &details))
+	    return NULL;
+
+    a = PySequence_GetSlice(args, 1, PySequence_Size(args));
+    if (!a)
+        return NULL;
+    status = PyObject_SetAttrString(self, "args", a);
+    Py_DECREF(a);
+    if (status < 0)
+        return NULL;
+
+    if (PyObject_SetAttrString(self, "hresult", hresult) < 0)
+	    return NULL;
+
+    if (PyObject_SetAttrString(self, "text", text) < 0)
+	    return NULL;
+
+    if (PyObject_SetAttrString(self, "details", details) < 0)
+	    return NULL;
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyMethodDef comerror_methods[] = {
+	{ "__str__", comerror_str, METH_O },
+	{ "__init__", comerror_init, METH_VARARGS },
+	{ NULL, NULL },
+};
+
+PyObject *COMError;
+
+static int
+create_comerror(void)
+{
+	PyObject *dict = PyDict_New();
+	PyMethodDef *methods = comerror_methods;
+	PyObject *s;
+	int status;
+
+	ComError = PyErr_NewException("_ctypes.COMError",
+				      NULL,
+				      dict);
+	if (ComError == NULL)
+		return -1;
+	while (methods->ml_name) {
+		/* get a wrapper for the built-in function */
+		PyObject *func = PyCFunction_New(methods, NULL);
+		PyObject *meth;
+		if (func == NULL)
+			return -1;
+		meth = PyMethod_New(func, NULL, ComError);
+		Py_DECREF(func);
+		if (meth == NULL)
+			return -1;
+		PyDict_SetItemString(dict, methods->ml_name, meth);
+		Py_DECREF(meth);
+		++methods;
+	}
+	Py_INCREF(ComError);
+	s = PyString_FromString(comerror_doc);
+	if (s == NULL)
+		return -1;
+	status = PyDict_SetItemString(dict, "__doc__", s);
+	Py_DECREF(s);
+	return status;
+}
+
+#endif
+
+static PyObject *
+string_at(const char *ptr, int size)
+{
+	if (size == -1)
+		return PyString_FromString(ptr);
+	return PyString_FromStringAndSize(ptr, size);
+}
+
+static int
+cast_check_pointertype(PyObject *arg)
+{
+	StgDictObject *dict;
+
+	if (PointerTypeObject_Check(arg))
+		return 1;
+	if (CFuncPtrTypeObject_Check(arg))
+		return 1;
+	dict = PyType_stgdict(arg);
+	if (dict) {
+		if (PyString_Check(dict->proto)
+		    && (strchr("sPzUZXO", PyString_AS_STRING(dict->proto)[0]))) {
+			/* simple pointer types, c_void_p, c_wchar_p, BSTR, ... */
+			return 1;
+		}
+	}
+	PyErr_Format(PyExc_TypeError,
+		     "cast() argument 2 must be a pointer type, not %s",
+		     PyType_Check(arg)
+		     ? ((PyTypeObject *)arg)->tp_name
+		     : arg->ob_type->tp_name);
+	return 0;
+}
+
+static PyObject *
+cast(void *ptr, PyObject *src, PyObject *ctype)
+{
+	CDataObject *result;
+	if (0 == cast_check_pointertype(ctype))
+		return NULL;
+	result = (CDataObject *)PyObject_CallFunctionObjArgs(ctype, NULL);
+	if (result == NULL)
+		return NULL;
+
+	/*
+	  The casted objects '_objects' member:
+
+	  It must certainly contain the source objects one.
+	  It must contain the source object itself.
+	 */
+	if (CDataObject_Check(src)) {
+		CDataObject *obj = (CDataObject *)src;
+		/* CData_GetContainer will initialize src.b_objects, we need
+		   this so it can be shared */
+		CData_GetContainer(obj);
+		/* But we need a dictionary! */
+		if (obj->b_objects == Py_None) {
+			Py_DECREF(Py_None);
+			obj->b_objects = PyDict_New();
+			if (obj->b_objects == NULL)
+				goto failed;
+		}
+		Py_XINCREF(obj->b_objects);
+		result->b_objects = obj->b_objects;
+		if (result->b_objects && PyDict_Check(result->b_objects)) {
+			PyObject *index;
+			int rc;
+			index = PyLong_FromVoidPtr((void *)src);
+			if (index == NULL)
+				goto failed;
+			rc = PyDict_SetItem(result->b_objects, index, src);
+			Py_DECREF(index);
+			if (rc == -1)
+				goto failed;
+		}
+	}
+	/* Should we assert that result is a pointer type? */
+	memcpy(result->b_ptr, &ptr, sizeof(void *));
+	return (PyObject *)result;
+
+  failed:
+	Py_DECREF(result);
+	return NULL;
+}
+
+#ifdef CTYPES_UNICODE
+static PyObject *
+wstring_at(const wchar_t *ptr, int size)
+{
+	if (size == -1)
+		size = wcslen(ptr);
+	return PyUnicode_FromWideChar(ptr, size);
+}
+#endif
+
+PyMODINIT_FUNC
+init_ctypes(void)
+{
+	PyObject *m;
+
+/* Note:
+   ob_type is the metatype (the 'type'), defaults to PyType_Type,
+   tp_base is the base type, defaults to 'object' aka PyBaseObject_Type.
+*/
+#ifdef WITH_THREAD
+	PyEval_InitThreads();
+#endif
+	m = Py_InitModule3("_ctypes", module_methods, module_docs);
+	if (!m)
+		return;
+
+	if (PyType_Ready(&PyCArg_Type) < 0)
+		return;
+
+	/* StgDict is derived from PyDict_Type */
+	StgDict_Type.tp_base = &PyDict_Type;
+	if (PyType_Ready(&StgDict_Type) < 0)
+		return;
+
+	/*************************************************
+	 *
+	 * Metaclasses
+	 */
+
+	StructType_Type.tp_base = &PyType_Type;
+	if (PyType_Ready(&StructType_Type) < 0)
+		return;
+
+	UnionType_Type.tp_base = &PyType_Type;
+	if (PyType_Ready(&UnionType_Type) < 0)
+		return;
+
+	PointerType_Type.tp_base = &PyType_Type;
+	if (PyType_Ready(&PointerType_Type) < 0)
+		return;
+
+	ArrayType_Type.tp_base = &PyType_Type;
+	if (PyType_Ready(&ArrayType_Type) < 0)
+		return;
+
+	SimpleType_Type.tp_base = &PyType_Type;
+	if (PyType_Ready(&SimpleType_Type) < 0)
+		return;
+
+	CFuncPtrType_Type.tp_base = &PyType_Type;
+	if (PyType_Ready(&CFuncPtrType_Type) < 0)
+		return;
+
+	/*************************************************
+	 *
+	 * Classes using a custom metaclass
+	 */
+
+	if (PyType_Ready(&CData_Type) < 0)
+		return;
+
+	Struct_Type.ob_type = &StructType_Type;
+	Struct_Type.tp_base = &CData_Type;
+	if (PyType_Ready(&Struct_Type) < 0)
+		return;
+	PyModule_AddObject(m, "Structure", (PyObject *)&Struct_Type);
+
+	Union_Type.ob_type = &UnionType_Type;
+	Union_Type.tp_base = &CData_Type;
+	if (PyType_Ready(&Union_Type) < 0)
+		return;
+	PyModule_AddObject(m, "Union", (PyObject *)&Union_Type);
+
+	Pointer_Type.ob_type = &PointerType_Type;
+	Pointer_Type.tp_base = &CData_Type;
+	if (PyType_Ready(&Pointer_Type) < 0)
+		return;
+	PyModule_AddObject(m, "_Pointer", (PyObject *)&Pointer_Type);
+
+	Array_Type.ob_type = &ArrayType_Type;
+	Array_Type.tp_base = &CData_Type;
+	if (PyType_Ready(&Array_Type) < 0)
+		return;
+	PyModule_AddObject(m, "Array", (PyObject *)&Array_Type);
+
+	Simple_Type.ob_type = &SimpleType_Type;
+	Simple_Type.tp_base = &CData_Type;
+	if (PyType_Ready(&Simple_Type) < 0)
+		return;
+	PyModule_AddObject(m, "_SimpleCData", (PyObject *)&Simple_Type);
+
+	CFuncPtr_Type.ob_type = &CFuncPtrType_Type;
+	CFuncPtr_Type.tp_base = &CData_Type;
+	if (PyType_Ready(&CFuncPtr_Type) < 0)
+		return;
+	PyModule_AddObject(m, "CFuncPtr", (PyObject *)&CFuncPtr_Type);
+
+	/*************************************************
+	 *
+	 * Simple classes
+	 */
+
+	/* CField_Type is derived from PyBaseObject_Type */
+	if (PyType_Ready(&CField_Type) < 0)
+		return;
+
+	/*************************************************
+	 *
+	 * Other stuff
+	 */
+
+#ifdef MS_WIN32
+	if (create_comerror() < 0)
+		return;
+	PyModule_AddObject(m, "COMError", ComError);
+
+	PyModule_AddObject(m, "FUNCFLAG_HRESULT", PyInt_FromLong(FUNCFLAG_HRESULT));
+	PyModule_AddObject(m, "FUNCFLAG_STDCALL", PyInt_FromLong(FUNCFLAG_STDCALL));
+#endif
+	PyModule_AddObject(m, "FUNCFLAG_CDECL", PyInt_FromLong(FUNCFLAG_CDECL));
+	PyModule_AddObject(m, "FUNCFLAG_PYTHONAPI", PyInt_FromLong(FUNCFLAG_PYTHONAPI));
+	PyModule_AddStringConstant(m, "__version__", "1.0.2");
+
+	PyModule_AddObject(m, "_memmove_addr", PyLong_FromVoidPtr(memmove));
+	PyModule_AddObject(m, "_memset_addr", PyLong_FromVoidPtr(memset));
+	PyModule_AddObject(m, "_string_at_addr", PyLong_FromVoidPtr(string_at));
+	PyModule_AddObject(m, "_cast_addr", PyLong_FromVoidPtr(cast));
+#ifdef CTYPES_UNICODE
+	PyModule_AddObject(m, "_wstring_at_addr", PyLong_FromVoidPtr(wstring_at));
+#endif
+
+/* If RTLD_LOCAL is not defined (Windows!), set it to zero. */
+#ifndef RTLD_LOCAL
+#define RTLD_LOCAL 0
+#endif
+
+/* If RTLD_GLOBAL is not defined (cygwin), set it to the same value as
+   RTLD_LOCAL.
+*/
+#ifndef RTLD_GLOBAL
+#define RTLD_GLOBAL RTLD_LOCAL
+#endif
+
+	PyModule_AddObject(m, "RTLD_LOCAL", PyInt_FromLong(RTLD_LOCAL));
+	PyModule_AddObject(m, "RTLD_GLOBAL", PyInt_FromLong(RTLD_GLOBAL));
+	
+	PyExc_ArgError = PyErr_NewException("ctypes.ArgumentError", NULL, NULL);
+	if (PyExc_ArgError) {
+		Py_INCREF(PyExc_ArgError);
+		PyModule_AddObject(m, "ArgumentError", PyExc_ArgError);
+	}
+	/*************************************************
+	 *
+	 * Others...
+	 */
+	init_callbacks_in_module(m);
+}
+
+/*****************************************************************
+ * replacements for broken Python api functions (in Python 2.3).
+ * See #1047269 Buffer overwrite in PyUnicode_AsWideChar
+ */
+
+#ifdef HAVE_WCHAR_H
+
+PyObject *My_PyUnicode_FromWideChar(register const wchar_t *w,
+				    Py_ssize_t size)
+{
+    PyUnicodeObject *unicode;
+
+    if (w == NULL) {
+	PyErr_BadInternalCall();
+	return NULL;
+    }
+
+    unicode = (PyUnicodeObject *)PyUnicode_FromUnicode(NULL, size);
+    if (!unicode)
+        return NULL;
+
+    /* Copy the wchar_t data into the new object */
+#ifdef HAVE_USABLE_WCHAR_T
+    memcpy(unicode->str, w, size * sizeof(wchar_t));
+#else
+    {
+	register Py_UNICODE *u;
+	register int i;
+	u = PyUnicode_AS_UNICODE(unicode);
+	/* In Python, the following line has a one-off error */
+	for (i = size; i > 0; i--)
+	    *u++ = *w++;
+    }
+#endif
+
+    return (PyObject *)unicode;
+}
+
+int My_PyUnicode_AsWideChar(PyUnicodeObject *unicode,
+			    register wchar_t *w,
+			    Py_ssize_t size)
+{
+    if (unicode == NULL) {
+	PyErr_BadInternalCall();
+	return -1;
+    }
+    if (size > PyUnicode_GET_SIZE(unicode))
+	size = PyUnicode_GET_SIZE(unicode);
+#ifdef HAVE_USABLE_WCHAR_T
+    memcpy(w, unicode->str, size * sizeof(wchar_t));
+#else
+    {
+	register Py_UNICODE *u;
+	register int i;
+	u = PyUnicode_AS_UNICODE(unicode);
+	/* In Python, the following line has a one-off error */
+	for (i = size; i > 0; i--)
+	    *w++ = *u++;
+    }
+#endif
+
+    return size;
+}
+
+#endif
+
+/*
+ Local Variables:
+ compile-command: "cd .. && python setup.py -q build -g && python setup.py -q build install --home ~"
+ End:
+*/

Added: vendor/Python/current/Modules/_ctypes/_ctypes_test.c
===================================================================
--- vendor/Python/current/Modules/_ctypes/_ctypes_test.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/_ctypes_test.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,548 @@
+/*****************************************************************
+  This file should be kept compatible with Python 2.3, see PEP 291.
+ *****************************************************************/
+
+
+#include <Python.h>
+
+/*
+  Backwards compatibility:
+  Python2.2 used LONG_LONG instead of PY_LONG_LONG
+*/
+#if defined(HAVE_LONG_LONG) && !defined(PY_LONG_LONG)
+#define PY_LONG_LONG LONG_LONG
+#endif
+
+#ifdef MS_WIN32
+#include <windows.h>
+#endif
+
+#if defined(MS_WIN32) || defined(__CYGWIN__)
+#define EXPORT(x) __declspec(dllexport) x
+#else
+#define EXPORT(x) x
+#endif
+
+/* some functions handy for testing */
+
+EXPORT(char *)my_strtok(char *token, const char *delim)
+{
+	return strtok(token, delim);
+}
+
+EXPORT(char *)my_strchr(const char *s, int c)
+{
+	return strchr(s, c);
+}
+
+
+EXPORT(double) my_sqrt(double a)
+{
+	return sqrt(a);
+}
+
+EXPORT(void) my_qsort(void *base, size_t num, size_t width, int(*compare)(const void*, const void*))
+{
+	qsort(base, num, width, compare);
+}
+
+EXPORT(int *) _testfunc_ai8(int a[8])
+{
+	return a;
+}
+
+EXPORT(void) _testfunc_v(int a, int b, int *presult)
+{
+	*presult = a + b;
+}
+
+EXPORT(int) _testfunc_i_bhilfd(signed char b, short h, int i, long l, float f, double d)
+{
+/*	printf("_testfunc_i_bhilfd got %d %d %d %ld %f %f\n",
+	       b, h, i, l, f, d);
+*/
+	return (int)(b + h + i + l + f + d);
+}
+
+EXPORT(float) _testfunc_f_bhilfd(signed char b, short h, int i, long l, float f, double d)
+{
+/*	printf("_testfunc_f_bhilfd got %d %d %d %ld %f %f\n",
+	       b, h, i, l, f, d);
+*/
+	return (float)(b + h + i + l + f + d);
+}
+
+EXPORT(double) _testfunc_d_bhilfd(signed char b, short h, int i, long l, float f, double d)
+{
+/*	printf("_testfunc_d_bhilfd got %d %d %d %ld %f %f\n",
+	       b, h, i, l, f, d);
+*/
+	return (double)(b + h + i + l + f + d);
+}
+
+EXPORT(char *) _testfunc_p_p(void *s)
+{
+	return (char *)s;
+}
+
+EXPORT(void *) _testfunc_c_p_p(int *argcp, char **argv)
+{
+	return argv[(*argcp)-1];
+}
+
+EXPORT(void *) get_strchr(void)
+{
+	return (void *)strchr;
+}
+
+EXPORT(char *) my_strdup(char *src)
+{
+	char *dst = (char *)malloc(strlen(src)+1);
+	if (!dst)
+		return NULL;
+	strcpy(dst, src);
+	return dst;
+}
+
+EXPORT(void)my_free(void *ptr)
+{
+	free(ptr);
+}
+
+#ifdef HAVE_WCHAR_H
+EXPORT(wchar_t *) my_wcsdup(wchar_t *src)
+{
+	size_t len = wcslen(src);
+	wchar_t *ptr = (wchar_t *)malloc((len + 1) * sizeof(wchar_t));
+	if (ptr == NULL)
+		return NULL;
+	memcpy(ptr, src, (len+1) * sizeof(wchar_t));
+	return ptr;
+}
+
+EXPORT(size_t) my_wcslen(wchar_t *src)
+{
+	return wcslen(src);
+}
+#endif
+
+#ifndef MS_WIN32
+# ifndef __stdcall
+#  define __stdcall /* */
+# endif
+#endif
+
+typedef struct {
+	int (*c)(int, int);
+	int (__stdcall *s)(int, int);
+} FUNCS;
+
+EXPORT(int) _testfunc_callfuncp(FUNCS *fp)
+{
+	fp->c(1, 2);
+	fp->s(3, 4);
+	return 0;
+}
+
+EXPORT(int) _testfunc_deref_pointer(int *pi)
+{
+	return *pi;
+}
+
+#ifdef MS_WIN32
+EXPORT(int) _testfunc_piunk(IUnknown FAR *piunk)
+{
+	piunk->lpVtbl->AddRef(piunk);
+	return piunk->lpVtbl->Release(piunk);
+}
+#endif
+
+EXPORT(int) _testfunc_callback_with_pointer(int (*func)(int *))
+{
+	int table[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+
+	return (*func)(table);
+}
+
+#ifdef HAVE_LONG_LONG
+EXPORT(PY_LONG_LONG) _testfunc_q_bhilfdq(signed char b, short h, int i, long l, float f,
+				     double d, PY_LONG_LONG q)
+{
+	return (PY_LONG_LONG)(b + h + i + l + f + d + q);
+}
+
+EXPORT(PY_LONG_LONG) _testfunc_q_bhilfd(signed char b, short h, int i, long l, float f, double d)
+{
+	return (PY_LONG_LONG)(b + h + i + l + f + d);
+}
+
+EXPORT(int) _testfunc_callback_i_if(int value, int (*func)(int))
+{
+	int sum = 0;
+	while (value != 0) {
+		sum += func(value);
+		value /= 2;
+	}
+	return sum;
+}
+
+EXPORT(PY_LONG_LONG) _testfunc_callback_q_qf(PY_LONG_LONG value,
+					     PY_LONG_LONG (*func)(PY_LONG_LONG))
+{
+	PY_LONG_LONG sum = 0;
+
+	while (value != 0) {
+		sum += func(value);
+		value /= 2;
+	}
+	return sum;
+}
+
+#endif
+
+typedef struct {
+	char *name;
+	char *value;
+} SPAM;
+
+typedef struct {
+	char *name;
+	int num_spams;
+	SPAM *spams;
+} EGG;
+
+SPAM my_spams[2] = {
+	{ "name1", "value1" },
+	{ "name2", "value2" },
+};
+
+EGG my_eggs[1] = {
+	{ "first egg", 1, my_spams }
+};
+
+EXPORT(int) getSPAMANDEGGS(EGG **eggs)
+{
+	*eggs = my_eggs;
+	return 1;
+}
+
+typedef struct tagpoint {
+	int x;
+	int y;
+} point;
+
+EXPORT(int) _testfunc_byval(point in, point *pout)
+{
+	if (pout) {
+		pout->x = in.x;
+		pout->y = in.y;
+	}
+	return in.x + in.y;
+}
+
+EXPORT (int) an_integer = 42;
+
+EXPORT(int) get_an_integer(void)
+{
+	return an_integer;
+}
+
+EXPORT(double)
+integrate(double a, double b, double (*f)(double), long nstep)
+{
+	double x, sum=0.0, dx=(b-a)/(double)nstep;
+	for(x=a+0.5*dx; (b-x)*(x-a)>0.0; x+=dx)
+		sum += f(x);
+	return sum/(double)nstep;
+}
+
+typedef struct {
+	void (*initialize)(void *(*)(int), void(*)(void *));
+} xxx_library;
+
+static void _xxx_init(void *(*Xalloc)(int), void (*Xfree)(void *))
+{
+	void *ptr;
+	
+	printf("_xxx_init got %p %p\n", Xalloc, Xfree);
+	printf("calling\n");
+	ptr = Xalloc(32);
+	Xfree(ptr);
+	printf("calls done, ptr was %p\n", ptr);
+}
+
+xxx_library _xxx_lib = {
+	_xxx_init
+};
+
+EXPORT(xxx_library) *library_get(void)
+{
+	return &_xxx_lib;
+}
+
+#ifdef MS_WIN32
+/* See Don Box (german), pp 79ff. */
+EXPORT(void) GetString(BSTR *pbstr)
+{
+	*pbstr = SysAllocString(L"Goodbye!");
+}
+#endif
+
+/*
+ * Some do-nothing functions, for speed tests
+ */
+PyObject *py_func_si(PyObject *self, PyObject *args)
+{
+	char *name;
+	int i;
+	if (!PyArg_ParseTuple(args, "si", &name, &i))
+		return NULL;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+EXPORT(void) _py_func_si(char *s, int i)
+{
+}
+
+PyObject *py_func(PyObject *self, PyObject *args)
+{
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+EXPORT(void) _py_func(void)
+{
+}
+
+EXPORT(PY_LONG_LONG) last_tf_arg_s;
+EXPORT(unsigned PY_LONG_LONG) last_tf_arg_u;
+
+struct BITS {
+	int A: 1, B:2, C:3, D:4, E: 5, F: 6, G: 7, H: 8, I: 9;
+	short M: 1, N: 2, O: 3, P: 4, Q: 5, R: 6, S: 7;
+};
+
+DL_EXPORT(void) set_bitfields(struct BITS *bits, char name, int value)
+{
+	switch (name) {
+	case 'A': bits->A = value; break;
+	case 'B': bits->B = value; break;
+	case 'C': bits->C = value; break;
+	case 'D': bits->D = value; break;
+	case 'E': bits->E = value; break;
+	case 'F': bits->F = value; break;
+	case 'G': bits->G = value; break;
+	case 'H': bits->H = value; break;
+	case 'I': bits->I = value; break;
+
+	case 'M': bits->M = value; break;
+	case 'N': bits->N = value; break;
+	case 'O': bits->O = value; break;
+	case 'P': bits->P = value; break;
+	case 'Q': bits->Q = value; break;
+	case 'R': bits->R = value; break;
+	case 'S': bits->S = value; break;
+	}
+}
+
+DL_EXPORT(int) unpack_bitfields(struct BITS *bits, char name)
+{
+	switch (name) {
+	case 'A': return bits->A;
+	case 'B': return bits->B;
+	case 'C': return bits->C;
+	case 'D': return bits->D;
+	case 'E': return bits->E;
+	case 'F': return bits->F;
+	case 'G': return bits->G;
+	case 'H': return bits->H;
+	case 'I': return bits->I;
+
+	case 'M': return bits->M;
+	case 'N': return bits->N;
+	case 'O': return bits->O;
+	case 'P': return bits->P;
+	case 'Q': return bits->Q;
+	case 'R': return bits->R;
+	case 'S': return bits->S;
+	}
+	return 0;
+}
+
+PyMethodDef module_methods[] = {
+/*	{"get_last_tf_arg_s", get_last_tf_arg_s, METH_NOARGS},
+	{"get_last_tf_arg_u", get_last_tf_arg_u, METH_NOARGS},
+*/
+	{"func_si", py_func_si, METH_VARARGS},
+	{"func", py_func, METH_NOARGS},
+	{ NULL, NULL, 0, NULL},
+};
+
+#define S last_tf_arg_s = (PY_LONG_LONG)c
+#define U last_tf_arg_u = (unsigned PY_LONG_LONG)c
+
+EXPORT(signed char) tf_b(signed char c) { S; return c/3; }
+EXPORT(unsigned char) tf_B(unsigned char c) { U; return c/3; }
+EXPORT(short) tf_h(short c) { S; return c/3; }
+EXPORT(unsigned short) tf_H(unsigned short c) { U; return c/3; }
+EXPORT(int) tf_i(int c) { S; return c/3; }
+EXPORT(unsigned int) tf_I(unsigned int c) { U; return c/3; }
+EXPORT(long) tf_l(long c) { S; return c/3; }
+EXPORT(unsigned long) tf_L(unsigned long c) { U; return c/3; }
+EXPORT(PY_LONG_LONG) tf_q(PY_LONG_LONG c) { S; return c/3; }
+EXPORT(unsigned PY_LONG_LONG) tf_Q(unsigned PY_LONG_LONG c) { U; return c/3; }
+EXPORT(float) tf_f(float c) { S; return c/3; }
+EXPORT(double) tf_d(double c) { S; return c/3; }
+
+#ifdef MS_WIN32
+EXPORT(signed char) __stdcall s_tf_b(signed char c) { S; return c/3; }
+EXPORT(unsigned char) __stdcall s_tf_B(unsigned char c) { U; return c/3; }
+EXPORT(short) __stdcall s_tf_h(short c) { S; return c/3; }
+EXPORT(unsigned short) __stdcall s_tf_H(unsigned short c) { U; return c/3; }
+EXPORT(int) __stdcall s_tf_i(int c) { S; return c/3; }
+EXPORT(unsigned int) __stdcall s_tf_I(unsigned int c) { U; return c/3; }
+EXPORT(long) __stdcall s_tf_l(long c) { S; return c/3; }
+EXPORT(unsigned long) __stdcall s_tf_L(unsigned long c) { U; return c/3; }
+EXPORT(PY_LONG_LONG) __stdcall s_tf_q(PY_LONG_LONG c) { S; return c/3; }
+EXPORT(unsigned PY_LONG_LONG) __stdcall s_tf_Q(unsigned PY_LONG_LONG c) { U; return c/3; }
+EXPORT(float) __stdcall s_tf_f(float c) { S; return c/3; }
+EXPORT(double) __stdcall s_tf_d(double c) { S; return c/3; }
+#endif
+/*******/
+
+EXPORT(signed char) tf_bb(signed char x, signed char c) { S; return c/3; }
+EXPORT(unsigned char) tf_bB(signed char x, unsigned char c) { U; return c/3; }
+EXPORT(short) tf_bh(signed char x, short c) { S; return c/3; }
+EXPORT(unsigned short) tf_bH(signed char x, unsigned short c) { U; return c/3; }
+EXPORT(int) tf_bi(signed char x, int c) { S; return c/3; }
+EXPORT(unsigned int) tf_bI(signed char x, unsigned int c) { U; return c/3; }
+EXPORT(long) tf_bl(signed char x, long c) { S; return c/3; }
+EXPORT(unsigned long) tf_bL(signed char x, unsigned long c) { U; return c/3; }
+EXPORT(PY_LONG_LONG) tf_bq(signed char x, PY_LONG_LONG c) { S; return c/3; }
+EXPORT(unsigned PY_LONG_LONG) tf_bQ(signed char x, unsigned PY_LONG_LONG c) { U; return c/3; }
+EXPORT(float) tf_bf(signed char x, float c) { S; return c/3; }
+EXPORT(double) tf_bd(signed char x, double c) { S; return c/3; }
+EXPORT(void) tv_i(int c) { S; return; }
+
+#ifdef MS_WIN32
+EXPORT(signed char) __stdcall s_tf_bb(signed char x, signed char c) { S; return c/3; }
+EXPORT(unsigned char) __stdcall s_tf_bB(signed char x, unsigned char c) { U; return c/3; }
+EXPORT(short) __stdcall s_tf_bh(signed char x, short c) { S; return c/3; }
+EXPORT(unsigned short) __stdcall s_tf_bH(signed char x, unsigned short c) { U; return c/3; }
+EXPORT(int) __stdcall s_tf_bi(signed char x, int c) { S; return c/3; }
+EXPORT(unsigned int) __stdcall s_tf_bI(signed char x, unsigned int c) { U; return c/3; }
+EXPORT(long) __stdcall s_tf_bl(signed char x, long c) { S; return c/3; }
+EXPORT(unsigned long) __stdcall s_tf_bL(signed char x, unsigned long c) { U; return c/3; }
+EXPORT(PY_LONG_LONG) __stdcall s_tf_bq(signed char x, PY_LONG_LONG c) { S; return c/3; }
+EXPORT(unsigned PY_LONG_LONG) __stdcall s_tf_bQ(signed char x, unsigned PY_LONG_LONG c) { U; return c/3; }
+EXPORT(float) __stdcall s_tf_bf(signed char x, float c) { S; return c/3; }
+EXPORT(double) __stdcall s_tf_bd(signed char x, double c) { S; return c/3; }
+EXPORT(void) __stdcall s_tv_i(int c) { S; return; }
+#endif
+
+/********/
+ 
+#ifndef MS_WIN32
+
+typedef struct {
+	long x;
+	long y;
+} POINT;
+
+typedef struct {
+	long left;
+	long top;
+	long right;
+	long bottom;
+} RECT;
+
+#endif
+
+EXPORT(int) PointInRect(RECT *prc, POINT pt)
+{
+	if (pt.x < prc->left)
+		return 0;
+	if (pt.x > prc->right)
+		return 0;
+	if (pt.y < prc->top)
+		return 0;
+	if (pt.y > prc->bottom)
+		return 0;
+	return 1;
+}
+
+typedef struct {
+	short x;
+	short y;
+} S2H;
+
+EXPORT(S2H) ret_2h_func(S2H inp)
+{
+	inp.x *= 2;
+	inp.y *= 3;
+	return inp;
+}
+
+typedef struct {
+	int a, b, c, d, e, f, g, h;
+} S8I;
+
+EXPORT(S8I) ret_8i_func(S8I inp)
+{
+	inp.a *= 2;
+	inp.b *= 3;
+	inp.c *= 4;
+	inp.d *= 5;
+	inp.e *= 6;
+	inp.f *= 7;
+	inp.g *= 8;
+	inp.h *= 9;
+	return inp;
+}
+
+EXPORT(int) GetRectangle(int flag, RECT *prect)
+{
+	if (flag == 0)
+		return 0;
+	prect->left = (int)flag;
+	prect->top = (int)flag + 1;
+	prect->right = (int)flag + 2;
+	prect->bottom = (int)flag + 3;
+	return 1;
+}
+
+EXPORT(void) TwoOutArgs(int a, int *pi, int b, int *pj)
+{
+	*pi += a;
+	*pj += b;
+}
+
+#ifdef MS_WIN32
+EXPORT(S2H) __stdcall s_ret_2h_func(S2H inp) { return ret_2h_func(inp); }
+EXPORT(S8I) __stdcall s_ret_8i_func(S8I inp) { return ret_8i_func(inp); }
+#endif
+
+#ifdef MS_WIN32
+/* Should port this */
+#include <stdlib.h>
+#include <search.h>
+
+EXPORT (HRESULT) KeepObject(IUnknown *punk)
+{
+	static IUnknown *pobj;
+	if (punk)
+		punk->lpVtbl->AddRef(punk);
+	if (pobj)
+		pobj->lpVtbl->Release(pobj);
+	pobj = punk;
+	return S_OK;
+}
+
+#endif
+
+DL_EXPORT(void)
+init_ctypes_test(void)
+{
+	Py_InitModule("_ctypes_test", module_methods);
+}

Added: vendor/Python/current/Modules/_ctypes/_ctypes_test.h
===================================================================
--- vendor/Python/current/Modules/_ctypes/_ctypes_test.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/_ctypes_test.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1 @@
+extern int _testfunc_i_bhilfd(char b, short h, int i, long l, float f, double d);

Added: vendor/Python/current/Modules/_ctypes/callbacks.c
===================================================================
--- vendor/Python/current/Modules/_ctypes/callbacks.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/callbacks.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,499 @@
+/*****************************************************************
+  This file should be kept compatible with Python 2.3, see PEP 291.
+ *****************************************************************/
+
+#include "Python.h"
+#include "compile.h" /* required only for 2.3, as it seems */
+#include "frameobject.h"
+
+#include <ffi.h>
+#ifdef MS_WIN32
+#include <windows.h>
+#endif
+#include "ctypes.h"
+
+static void
+PrintError(char *msg, ...)
+{
+	char buf[512];
+	PyObject *f = PySys_GetObject("stderr");
+	va_list marker;
+
+	va_start(marker, msg);
+	vsnprintf(buf, sizeof(buf), msg, marker);
+	va_end(marker);
+	if (f)
+		PyFile_WriteString(buf, f);
+	PyErr_Print();
+}
+
+
+/* after code that pyrex generates */
+void _AddTraceback(char *funcname, char *filename, int lineno)
+{
+	PyObject *py_srcfile = 0;
+	PyObject *py_funcname = 0;
+	PyObject *py_globals = 0;
+	PyObject *empty_tuple = 0;
+	PyObject *empty_string = 0;
+	PyCodeObject *py_code = 0;
+	PyFrameObject *py_frame = 0;
+    
+	py_srcfile = PyString_FromString(filename);
+	if (!py_srcfile) goto bad;
+	py_funcname = PyString_FromString(funcname);
+	if (!py_funcname) goto bad;
+	py_globals = PyDict_New();
+	if (!py_globals) goto bad;
+	empty_tuple = PyTuple_New(0);
+	if (!empty_tuple) goto bad;
+	empty_string = PyString_FromString("");
+	if (!empty_string) goto bad;
+	py_code = PyCode_New(
+		0,            /*int argcount,*/
+		0,            /*int nlocals,*/
+		0,            /*int stacksize,*/
+		0,            /*int flags,*/
+		empty_string, /*PyObject *code,*/
+		empty_tuple,  /*PyObject *consts,*/
+		empty_tuple,  /*PyObject *names,*/
+		empty_tuple,  /*PyObject *varnames,*/
+		empty_tuple,  /*PyObject *freevars,*/
+		empty_tuple,  /*PyObject *cellvars,*/
+		py_srcfile,   /*PyObject *filename,*/
+		py_funcname,  /*PyObject *name,*/
+		lineno,   /*int firstlineno,*/
+		empty_string  /*PyObject *lnotab*/
+		);
+	if (!py_code) goto bad;
+	py_frame = PyFrame_New(
+		PyThreadState_Get(), /*PyThreadState *tstate,*/
+		py_code,             /*PyCodeObject *code,*/
+		py_globals,          /*PyObject *globals,*/
+		0                    /*PyObject *locals*/
+		);
+	if (!py_frame) goto bad;
+	py_frame->f_lineno = lineno;
+	PyTraceBack_Here(py_frame);
+  bad:
+	Py_XDECREF(py_globals);
+	Py_XDECREF(py_srcfile);
+	Py_XDECREF(py_funcname);
+	Py_XDECREF(empty_tuple);
+	Py_XDECREF(empty_string);
+	Py_XDECREF(py_code);
+	Py_XDECREF(py_frame);
+}
+
+#ifdef MS_WIN32
+/*
+ * We must call AddRef() on non-NULL COM pointers we receive as arguments
+ * to callback functions - these functions are COM method implementations.
+ * The Python instances we create have a __del__ method which calls Release().
+ *
+ * The presence of a class attribute named '_needs_com_addref_' triggers this
+ * behaviour.  It would also be possible to call the AddRef() Python method,
+ * after checking for PyObject_IsTrue(), but this would probably be somewhat
+ * slower.
+ */
+static void
+TryAddRef(StgDictObject *dict, CDataObject *obj)
+{
+	IUnknown *punk;
+
+	if (NULL == PyDict_GetItemString((PyObject *)dict, "_needs_com_addref_"))
+		return;
+
+	punk = *(IUnknown **)obj->b_ptr;
+	if (punk)
+		punk->lpVtbl->AddRef(punk);
+	return;
+}
+#endif
+
+/******************************************************************************
+ *
+ * Call the python object with all arguments
+ *
+ */
+static void _CallPythonObject(void *mem,
+			      ffi_type *restype,
+			      SETFUNC setfunc,
+			      PyObject *callable,
+			      PyObject *converters,
+			      void **pArgs)
+{
+	int i;
+	PyObject *result;
+	PyObject *arglist = NULL;
+	int nArgs;
+#ifdef WITH_THREAD
+	PyGILState_STATE state = PyGILState_Ensure();
+#endif
+
+	nArgs = PySequence_Length(converters);
+	/* Hm. What to return in case of error?
+	   For COM, 0xFFFFFFFF seems better than 0.
+	*/
+	if (nArgs < 0) {
+		PrintError("BUG: PySequence_Length");
+		goto Done;
+	}
+
+	arglist = PyTuple_New(nArgs);
+	if (!arglist) {
+		PrintError("PyTuple_New()");
+		goto Done;
+	}
+	for (i = 0; i < nArgs; ++i) {
+		/* Note: new reference! */
+		PyObject *cnv = PySequence_GetItem(converters, i);
+		StgDictObject *dict;
+		if (cnv)
+			dict = PyType_stgdict(cnv);
+		else {
+			PrintError("Getting argument converter %d\n", i);
+			goto Done;
+		}
+
+		if (dict && dict->getfunc && !IsSimpleSubType(cnv)) {
+			PyObject *v = dict->getfunc(*pArgs, dict->size);
+			if (!v) {
+				PrintError("create argument %d:\n", i);
+				Py_DECREF(cnv);
+				goto Done;
+			}
+			PyTuple_SET_ITEM(arglist, i, v);
+			/* XXX XXX XX
+			   We have the problem that c_byte or c_short have dict->size of
+			   1 resp. 4, but these parameters are pushed as sizeof(int) bytes.
+			   BTW, the same problem occurrs when they are pushed as parameters
+			*/
+		} else if (dict) {
+			/* Hm, shouldn't we use CData_AtAddress() or something like that instead? */
+			CDataObject *obj = (CDataObject *)PyObject_CallFunctionObjArgs(cnv, NULL);
+			if (!obj) {
+				PrintError("create argument %d:\n", i);
+				Py_DECREF(cnv);
+				goto Done;
+			}
+			if (!CDataObject_Check(obj)) {
+				Py_DECREF(obj);
+				Py_DECREF(cnv);
+				PrintError("unexpected result of create argument %d:\n", i);
+				goto Done;
+			}
+			memcpy(obj->b_ptr, *pArgs, dict->size);
+			PyTuple_SET_ITEM(arglist, i, (PyObject *)obj);
+#ifdef MS_WIN32
+			TryAddRef(dict, obj);
+#endif
+		} else {
+			PyErr_SetString(PyExc_TypeError,
+					"cannot build parameter");
+			PrintError("Parsing argument %d\n", i);
+			Py_DECREF(cnv);
+			goto Done;
+		}
+		Py_DECREF(cnv);
+		/* XXX error handling! */
+		pArgs++;
+	}
+
+#define CHECK(what, x) \
+if (x == NULL) _AddTraceback(what, __FILE__, __LINE__ - 1), PyErr_Print()
+
+	result = PyObject_CallObject(callable, arglist);
+	CHECK("'calling callback function'", result);
+	if ((restype != &ffi_type_void) && result) {
+		PyObject *keep;
+		assert(setfunc);
+#ifdef WORDS_BIGENDIAN
+		/* See the corresponding code in callproc.c, around line 961 */
+		if (restype->type != FFI_TYPE_FLOAT && restype->size < sizeof(ffi_arg))
+			mem = (char *)mem + sizeof(ffi_arg) - restype->size;
+#endif
+		keep = setfunc(mem, result, 0);
+		CHECK("'converting callback result'", keep);
+		/* keep is an object we have to keep alive so that the result
+		   stays valid.  If there is no such object, the setfunc will
+		   have returned Py_None.
+
+		   If there is such an object, we have no choice than to keep
+		   it alive forever - but a refcount and/or memory leak will
+		   be the result.  EXCEPT when restype is py_object - Python
+		   itself knows how to manage the refcount of these objects.
+		*/
+		if (keep == NULL) /* Could not convert callback result. */
+			PyErr_WriteUnraisable(callable);
+		else if (keep == Py_None) /* Nothing to keep */
+			Py_DECREF(keep);
+		else if (setfunc != getentry("O")->setfunc) {
+			if (-1 == PyErr_Warn(PyExc_RuntimeWarning,
+					     "memory leak in callback function."))
+				PyErr_WriteUnraisable(callable);
+		}
+	}
+	Py_XDECREF(result);
+  Done:
+	Py_XDECREF(arglist);
+#ifdef WITH_THREAD
+	PyGILState_Release(state);
+#endif
+}
+
+static void closure_fcn(ffi_cif *cif,
+			void *resp,
+			void **args,
+			void *userdata)
+{
+	ffi_info *p = userdata;
+
+	_CallPythonObject(resp,
+			  p->restype,
+			  p->setfunc,
+			  p->callable,
+			  p->converters,
+			  args);
+}
+
+ffi_info *AllocFunctionCallback(PyObject *callable,
+				PyObject *converters,
+				PyObject *restype,
+				int is_cdecl)
+{
+	int result;
+	ffi_info *p;
+	int nArgs, i;
+	ffi_abi cc;
+
+	nArgs = PySequence_Size(converters);
+	p = (ffi_info *)PyMem_Malloc(sizeof(ffi_info) + sizeof(ffi_type) * (nArgs + 1));
+	if (p == NULL) {
+		PyErr_NoMemory();
+		return NULL;
+	}
+	p->pcl = MallocClosure();
+	if (p->pcl == NULL) {
+		PyErr_NoMemory();
+		goto error;
+	}
+
+	for (i = 0; i < nArgs; ++i) {
+		PyObject *cnv = PySequence_GetItem(converters, i);
+		if (cnv == NULL)
+			goto error;
+		p->atypes[i] = GetType(cnv);
+		Py_DECREF(cnv);
+	}
+	p->atypes[i] = NULL;
+
+	if (restype == Py_None) {
+		p->setfunc = NULL;
+		p->restype = &ffi_type_void;
+	} else {
+		StgDictObject *dict = PyType_stgdict(restype);
+		if (dict == NULL || dict->setfunc == NULL) {
+		  PyErr_SetString(PyExc_TypeError,
+				  "invalid result type for callback function");
+		  goto error;
+		}
+		p->setfunc = dict->setfunc;
+		p->restype = &dict->ffi_type_pointer;
+	}
+
+	cc = FFI_DEFAULT_ABI;
+#if defined(MS_WIN32) && !defined(_WIN32_WCE)
+	if (is_cdecl == 0)
+		cc = FFI_STDCALL;
+#endif
+	result = ffi_prep_cif(&p->cif, cc, nArgs,
+			      GetType(restype),
+			      &p->atypes[0]);
+	if (result != FFI_OK) {
+		PyErr_Format(PyExc_RuntimeError,
+			     "ffi_prep_cif failed with %d", result);
+		goto error;
+	}
+	result = ffi_prep_closure(p->pcl, &p->cif, closure_fcn, p);
+	if (result != FFI_OK) {
+		PyErr_Format(PyExc_RuntimeError,
+			     "ffi_prep_closure failed with %d", result);
+		goto error;
+	}
+
+	p->converters = converters;
+	p->callable = callable;
+	return p;
+
+  error:
+	if (p) {
+		if (p->pcl)
+			FreeClosure(p->pcl);
+		PyMem_Free(p);
+	}
+	return NULL;
+}
+
+/****************************************************************************
+ *
+ * callback objects: initialization
+ */
+
+void init_callbacks_in_module(PyObject *m)
+{
+	if (PyType_Ready((PyTypeObject *)&PyType_Type) < 0)
+		return;
+}
+
+#ifdef MS_WIN32
+
+static void LoadPython(void)
+{
+	if (!Py_IsInitialized()) {
+#ifdef WITH_THREAD
+		PyEval_InitThreads();
+#endif
+		Py_Initialize();
+	}
+}
+
+/******************************************************************/
+
+long Call_GetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
+{
+	PyObject *mod, *func, *result;
+	long retval;
+	static PyObject *context;
+
+	if (context == NULL)
+		context = PyString_FromString("_ctypes.DllGetClassObject");
+
+	mod = PyImport_ImportModule("ctypes");
+	if (!mod) {
+		PyErr_WriteUnraisable(context ? context : Py_None);
+		/* There has been a warning before about this already */
+		return E_FAIL;
+	}
+
+	func = PyObject_GetAttrString(mod, "DllGetClassObject");
+	Py_DECREF(mod);
+	if (!func) {
+		PyErr_WriteUnraisable(context ? context : Py_None);
+		return E_FAIL;
+	}
+
+	result = PyObject_CallFunction(func,
+				       "iii", rclsid, riid, ppv);
+	Py_DECREF(func);
+	if (!result) {
+		PyErr_WriteUnraisable(context ? context : Py_None);
+		return E_FAIL;
+	}
+
+	retval = PyInt_AsLong(result);
+	if (PyErr_Occurred()) {
+		PyErr_WriteUnraisable(context ? context : Py_None);
+		retval = E_FAIL;
+	}
+	Py_DECREF(result);
+	return retval;
+}
+
+STDAPI DllGetClassObject(REFCLSID rclsid,
+			 REFIID riid,
+			 LPVOID *ppv)
+{
+	long result;
+#ifdef WITH_THREAD
+	PyGILState_STATE state;
+#endif
+
+	LoadPython();
+#ifdef WITH_THREAD
+	state = PyGILState_Ensure();
+#endif
+	result = Call_GetClassObject(rclsid, riid, ppv);
+#ifdef WITH_THREAD
+	PyGILState_Release(state);
+#endif
+	return result;
+}
+
+long Call_CanUnloadNow(void)
+{
+	PyObject *mod, *func, *result;
+	long retval;
+	static PyObject *context;
+
+	if (context == NULL)
+		context = PyString_FromString("_ctypes.DllCanUnloadNow");
+
+	mod = PyImport_ImportModule("ctypes");
+	if (!mod) {
+/*		OutputDebugString("Could not import ctypes"); */
+		/* We assume that this error can only occur when shutting
+		   down, so we silently ignore it */
+		PyErr_Clear();
+		return E_FAIL;
+	}
+	/* Other errors cannot be raised, but are printed to stderr */
+	func = PyObject_GetAttrString(mod, "DllCanUnloadNow");
+	Py_DECREF(mod);
+	if (!func) {
+		PyErr_WriteUnraisable(context ? context : Py_None);
+		return E_FAIL;
+	}
+
+	result = PyObject_CallFunction(func, NULL);
+	Py_DECREF(func);
+	if (!result) {
+		PyErr_WriteUnraisable(context ? context : Py_None);
+		return E_FAIL;
+	}
+
+	retval = PyInt_AsLong(result);
+	if (PyErr_Occurred()) {
+		PyErr_WriteUnraisable(context ? context : Py_None);
+		retval = E_FAIL;
+	}
+	Py_DECREF(result);
+	return retval;
+}
+
+/*
+  DllRegisterServer and DllUnregisterServer still missing
+*/
+
+STDAPI DllCanUnloadNow(void)
+{
+	long result;
+#ifdef WITH_THREAD
+	PyGILState_STATE state = PyGILState_Ensure();
+#endif
+	result = Call_CanUnloadNow();
+#ifdef WITH_THREAD
+	PyGILState_Release(state);
+#endif
+	return result;
+}
+
+#ifndef Py_NO_ENABLE_SHARED
+BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvRes)
+{
+	switch(fdwReason) {
+	case DLL_PROCESS_ATTACH:
+		DisableThreadLibraryCalls(hinstDLL);
+		break;
+	}
+	return TRUE;
+}
+#endif
+
+#endif
+
+/*
+ Local Variables:
+ compile-command: "cd .. && python setup.py -q build_ext"
+ End:
+*/

Added: vendor/Python/current/Modules/_ctypes/callproc.c
===================================================================
--- vendor/Python/current/Modules/_ctypes/callproc.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/callproc.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1581 @@
+/*****************************************************************
+  This file should be kept compatible with Python 2.3, see PEP 291.
+ *****************************************************************/
+
+
+/*
+ * History: First version dated from 3/97, derived from my SCMLIB version
+ * for win16.
+ */
+/*
+ * Related Work:
+ *	- calldll	http://www.nightmare.com/software.html
+ *	- libffi	http://sourceware.cygnus.com/libffi/
+ *	- ffcall 	http://clisp.cons.org/~haible/packages-ffcall.html
+ *   and, of course, Don Beaudry's MESS package, but this is more ctypes
+ *   related.
+ */
+
+
+/*
+  How are functions called, and how are parameters converted to C ?
+
+  1. _ctypes.c::CFuncPtr_call receives an argument tuple 'inargs' and a
+  keyword dictionary 'kwds'.
+
+  2. After several checks, _build_callargs() is called which returns another
+  tuple 'callargs'.  This may be the same tuple as 'inargs', a slice of
+  'inargs', or a completely fresh tuple, depending on several things (is is a
+  COM method, are 'paramflags' available).
+
+  3. _build_callargs also calculates bitarrays containing indexes into
+  the callargs tuple, specifying how to build the return value(s) of
+  the function.
+
+  4. _CallProc is then called with the 'callargs' tuple.  _CallProc first
+  allocates two arrays.  The first is an array of 'struct argument' items, the
+  second array has 'void *' entried.
+
+  5. If 'converters' are present (converters is a sequence of argtypes'
+  from_param methods), for each item in 'callargs' converter is called and the
+  result passed to ConvParam.  If 'converters' are not present, each argument
+  is directly passed to ConvParm.
+
+  6. For each arg, ConvParam stores the contained C data (or a pointer to it,
+  for structures) into the 'struct argument' array.
+
+  7. Finally, a loop fills the 'void *' array so that each item points to the
+  data contained in or pointed to by the 'struct argument' array.
+
+  8. The 'void *' argument array is what _call_function_pointer
+  expects. _call_function_pointer then has very little to do - only some
+  libffi specific stuff, then it calls ffi_call.
+
+  So, there are 4 data structures holding processed arguments:
+  - the inargs tuple (in CFuncPtr_call)
+  - the callargs tuple (in CFuncPtr_call)
+  - the 'struct argguments' array
+  - the 'void *' array
+
+ */
+
+#include "Python.h"
+#include "structmember.h"
+
+#ifdef MS_WIN32
+#include <windows.h>
+#else
+#include "ctypes_dlfcn.h"
+#endif
+
+#ifdef MS_WIN32
+#include <malloc.h>
+#endif
+
+#include <ffi.h>
+#include "ctypes.h"
+
+#if defined(_DEBUG) || defined(__MINGW32__)
+/* Don't use structured exception handling on Windows if this is defined.
+   MingW, AFAIK, doesn't support it.
+*/
+#define DONT_USE_SEH
+#endif
+
+#ifdef MS_WIN32
+PyObject *ComError;
+
+static TCHAR *FormatError(DWORD code)
+{
+	TCHAR *lpMsgBuf;
+	DWORD n;
+	n = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+			  NULL,
+			  code,
+			  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+			  (LPTSTR) &lpMsgBuf,
+			  0,
+			  NULL);
+	if (n) {
+		while (isspace(lpMsgBuf[n-1]))
+			--n;
+		lpMsgBuf[n] = '\0'; /* rstrip() */
+	}
+	return lpMsgBuf;
+}
+
+#ifndef DONT_USE_SEH
+void SetException(DWORD code, EXCEPTION_RECORD *pr)
+{
+	TCHAR *lpMsgBuf;
+	lpMsgBuf = FormatError(code);
+	if(lpMsgBuf) {
+		PyErr_SetFromWindowsErr(code);
+		LocalFree(lpMsgBuf);
+	} else {
+		switch (code) {
+		case EXCEPTION_ACCESS_VIOLATION:
+			/* The thread attempted to read from or write
+			   to a virtual address for which it does not
+			   have the appropriate access. */
+			if (pr->ExceptionInformation[0] == 0)
+				PyErr_Format(PyExc_WindowsError,
+					     "exception: access violation reading %p",
+					     pr->ExceptionInformation[1]);
+			else
+				PyErr_Format(PyExc_WindowsError,
+					     "exception: access violation writing %p",
+					     pr->ExceptionInformation[1]);
+			break;
+		case EXCEPTION_BREAKPOINT:
+			/* A breakpoint was encountered. */
+			PyErr_SetString(PyExc_WindowsError,
+					"exception: breakpoint encountered");
+			break;
+			
+		case EXCEPTION_DATATYPE_MISALIGNMENT:
+			/* The thread attempted to read or write data that is
+			   misaligned on hardware that does not provide
+			   alignment. For example, 16-bit values must be
+			   aligned on 2-byte boundaries, 32-bit values on
+			   4-byte boundaries, and so on. */
+			PyErr_SetString(PyExc_WindowsError,
+					"exception: datatype misalignment");
+			break;
+
+		case EXCEPTION_SINGLE_STEP:
+			/* A trace trap or other single-instruction mechanism
+			   signaled that one instruction has been executed. */
+			PyErr_SetString(PyExc_WindowsError,
+					"exception: single step");
+			break;
+
+		case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: 
+			/* The thread attempted to access an array element
+			   that is out of bounds, and the underlying hardware
+			   supports bounds checking. */
+			PyErr_SetString(PyExc_WindowsError,
+					"exception: array bounds exceeded");
+			break;
+
+		case EXCEPTION_FLT_DENORMAL_OPERAND:
+			/* One of the operands in a floating-point operation
+			   is denormal. A denormal value is one that is too
+			   small to represent as a standard floating-point
+			   value. */
+			PyErr_SetString(PyExc_WindowsError,
+					"exception: floating-point operand denormal");
+			break;
+
+		case EXCEPTION_FLT_DIVIDE_BY_ZERO:
+			/* The thread attempted to divide a floating-point
+			   value by a floating-point divisor of zero. */
+			PyErr_SetString(PyExc_WindowsError,
+					"exception: float divide by zero");
+			break;
+
+		case EXCEPTION_FLT_INEXACT_RESULT:
+			/* The result of a floating-point operation cannot be
+			   represented exactly as a decimal fraction. */
+			PyErr_SetString(PyExc_WindowsError,
+					"exception: float inexact");
+			break;
+
+		case EXCEPTION_FLT_INVALID_OPERATION:
+			/* This exception represents any floating-point
+			   exception not included in this list. */
+			PyErr_SetString(PyExc_WindowsError,
+					"exception: float invalid operation");
+			break;
+
+		case EXCEPTION_FLT_OVERFLOW:
+			/* The exponent of a floating-point operation is
+			   greater than the magnitude allowed by the
+			   corresponding type. */
+			PyErr_SetString(PyExc_WindowsError,
+					"exception: float overflow");
+			break;
+
+		case EXCEPTION_FLT_STACK_CHECK:
+			/* The stack overflowed or underflowed as the result
+			   of a floating-point operation. */
+			PyErr_SetString(PyExc_WindowsError,
+					"exception: stack over/underflow");
+			break;
+
+		case EXCEPTION_STACK_OVERFLOW:
+			/* The stack overflowed or underflowed as the result
+			   of a floating-point operation. */
+			PyErr_SetString(PyExc_WindowsError,
+					"exception: stack overflow");
+			break;
+
+		case EXCEPTION_FLT_UNDERFLOW:
+			/* The exponent of a floating-point operation is less
+			   than the magnitude allowed by the corresponding
+			   type. */
+			PyErr_SetString(PyExc_WindowsError,
+					"exception: float underflow");
+			break;
+
+		case EXCEPTION_INT_DIVIDE_BY_ZERO:
+			/* The thread attempted to divide an integer value by
+			   an integer divisor of zero. */
+			PyErr_SetString(PyExc_WindowsError,
+					"exception: integer divide by zero");
+			break;
+
+		case EXCEPTION_INT_OVERFLOW:
+			/* The result of an integer operation caused a carry
+			   out of the most significant bit of the result. */
+			PyErr_SetString(PyExc_WindowsError,
+					"exception: integer overflow");
+			break;
+
+		case EXCEPTION_PRIV_INSTRUCTION:
+			/* The thread attempted to execute an instruction
+			   whose operation is not allowed in the current
+			   machine mode. */
+			PyErr_SetString(PyExc_WindowsError,
+					"exception: priviledged instruction");
+			break;
+
+		case EXCEPTION_NONCONTINUABLE_EXCEPTION:
+			/* The thread attempted to continue execution after a
+			   noncontinuable exception occurred. */
+			PyErr_SetString(PyExc_WindowsError,
+					"exception: nocontinuable");
+			break;
+		default:
+			printf("error %d\n", code);
+			PyErr_Format(PyExc_WindowsError,
+				     "exception code 0x%08x",
+				     code);
+			break;
+		}
+	}
+}
+
+static DWORD HandleException(EXCEPTION_POINTERS *ptrs,
+			     DWORD *pdw, EXCEPTION_RECORD *record)
+{
+	*pdw = ptrs->ExceptionRecord->ExceptionCode;
+	*record = *ptrs->ExceptionRecord;
+	return EXCEPTION_EXECUTE_HANDLER;
+}
+#endif
+
+static PyObject *
+check_hresult(PyObject *self, PyObject *args)
+{
+	HRESULT hr;
+	if (!PyArg_ParseTuple(args, "i", &hr))
+		return NULL;
+	if (FAILED(hr))
+		return PyErr_SetFromWindowsErr(hr);
+	return PyInt_FromLong(hr);
+}
+
+#endif
+
+/**************************************************************/
+
+PyCArgObject *
+new_CArgObject(void)
+{
+	PyCArgObject *p;
+	p = PyObject_New(PyCArgObject, &PyCArg_Type);
+	if (p == NULL)
+		return NULL;
+	p->pffi_type = NULL;
+	p->tag = '\0';
+	p->obj = NULL;
+	memset(&p->value, 0, sizeof(p->value));
+	return p;
+}
+
+static void
+PyCArg_dealloc(PyCArgObject *self)
+{
+	Py_XDECREF(self->obj);
+	PyObject_Del(self);
+}
+
+static PyObject *
+PyCArg_repr(PyCArgObject *self)
+{
+	char buffer[256];
+	switch(self->tag) {
+	case 'b':
+	case 'B':
+		sprintf(buffer, "<cparam '%c' (%d)>",
+			self->tag, self->value.b);
+		break;
+	case 'h':
+	case 'H':
+		sprintf(buffer, "<cparam '%c' (%d)>",
+			self->tag, self->value.h);
+		break;
+	case 'i':
+	case 'I':
+		sprintf(buffer, "<cparam '%c' (%d)>",
+			self->tag, self->value.i);
+		break;
+	case 'l':
+	case 'L':
+		sprintf(buffer, "<cparam '%c' (%ld)>",
+			self->tag, self->value.l);
+		break;
+		
+#ifdef HAVE_LONG_LONG
+	case 'q':
+	case 'Q':
+		sprintf(buffer,
+#ifdef MS_WIN32
+			"<cparam '%c' (%I64d)>",
+#else
+			"<cparam '%c' (%qd)>",
+#endif
+			self->tag, self->value.q);
+		break;
+#endif
+	case 'd':
+		sprintf(buffer, "<cparam '%c' (%f)>",
+			self->tag, self->value.d);
+		break;
+	case 'f':
+		sprintf(buffer, "<cparam '%c' (%f)>",
+			self->tag, self->value.f);
+		break;
+
+	case 'c':
+		sprintf(buffer, "<cparam '%c' (%c)>",
+			self->tag, self->value.c);
+		break;
+
+/* Hm, are these 'z' and 'Z' codes useful at all?
+   Shouldn't they be replaced by the functionality of c_string
+   and c_wstring ?
+*/
+	case 'z':
+	case 'Z':
+	case 'P':
+		sprintf(buffer, "<cparam '%c' (%08lx)>",
+			self->tag, (long)self->value.p);
+		break;
+
+	default:
+		sprintf(buffer, "<cparam '%c' at %08lx>",
+			self->tag, (long)self);
+		break;
+	}
+	return PyString_FromString(buffer);
+}
+
+static PyMemberDef PyCArgType_members[] = {
+	{ "_obj", T_OBJECT,
+	  offsetof(PyCArgObject, obj), READONLY,
+	  "the wrapped object" },
+	{ NULL },
+};
+
+PyTypeObject PyCArg_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0,
+	"CArgObject",
+	sizeof(PyCArgObject),
+	0,
+	(destructor)PyCArg_dealloc,		/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	(reprfunc)PyCArg_repr,			/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	0,					/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT,			/* tp_flags */
+	0,					/* tp_doc */
+	0,					/* tp_traverse */
+	0,					/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	0,					/* tp_methods */
+	PyCArgType_members,			/* tp_members */
+};
+
+/****************************************************************/
+/*
+ * Convert a PyObject * into a parameter suitable to pass to an
+ * C function call.
+ *
+ * 1. Python integers are converted to C int and passed by value.
+ *
+ * 2. 3-tuples are expected to have a format character in the first
+ *    item, which must be 'i', 'f', 'd', 'q', or 'P'.
+ *    The second item will have to be an integer, float, double, long long
+ *    or integer (denoting an address void *), will be converted to the
+ *    corresponding C data type and passed by value.
+ *
+ * 3. Other Python objects are tested for an '_as_parameter_' attribute.
+ *    The value of this attribute must be an integer which will be passed
+ *    by value, or a 2-tuple or 3-tuple which will be used according
+ *    to point 2 above. The third item (if any), is ignored. It is normally
+ *    used to keep the object alive where this parameter refers to.
+ *    XXX This convention is dangerous - you can construct arbitrary tuples
+ *    in Python and pass them. Would it be safer to use a custom container
+ *    datatype instead of a tuple?
+ *
+ * 4. Other Python objects cannot be passed as parameters - an exception is raised.
+ *
+ * 5. ConvParam will store the converted result in a struct containing format
+ *    and value.
+ */
+
+union result {
+	char c;
+	char b;
+	short h;
+	int i;
+	long l;
+#ifdef HAVE_LONG_LONG
+	PY_LONG_LONG q;
+#endif
+	double d;
+	float f;
+	void *p;
+};
+
+struct argument {
+	ffi_type *ffi_type;
+	PyObject *keep;
+	union result value;
+};
+
+/*
+ * Convert a single Python object into a PyCArgObject and return it.
+ */
+static int ConvParam(PyObject *obj, int index, struct argument *pa)
+{
+	StgDictObject *dict;
+	pa->keep = NULL; /* so we cannot forget it later */
+
+	dict = PyObject_stgdict(obj);
+	if (dict) {
+		PyCArgObject *carg;
+		assert(dict->paramfunc);
+		/* If it has an stgdict, it is a CDataObject */
+		carg = dict->paramfunc((CDataObject *)obj);
+		pa->ffi_type = carg->pffi_type;
+		memcpy(&pa->value, &carg->value, sizeof(pa->value));
+		pa->keep = (PyObject *)carg;
+		return 0;
+	}
+
+	if (PyCArg_CheckExact(obj)) {
+		PyCArgObject *carg = (PyCArgObject *)obj;
+		pa->ffi_type = carg->pffi_type;
+		Py_INCREF(obj);
+		pa->keep = obj;
+		memcpy(&pa->value, &carg->value, sizeof(pa->value));
+		return 0;
+	}
+
+	/* check for None, integer, string or unicode and use directly if successful */
+	if (obj == Py_None) {
+		pa->ffi_type = &ffi_type_pointer;
+		pa->value.p = NULL;
+		return 0;
+	}
+
+	if (PyInt_Check(obj)) {
+		pa->ffi_type = &ffi_type_sint;
+		pa->value.i = PyInt_AS_LONG(obj);
+		return 0;
+	}
+
+	if (PyLong_Check(obj)) {
+		pa->ffi_type = &ffi_type_sint;
+		pa->value.i = (long)PyLong_AsUnsignedLong(obj);
+		if (pa->value.i == -1 && PyErr_Occurred()) {
+			PyErr_Clear();
+			pa->value.i = PyLong_AsLong(obj);
+			if (pa->value.i == -1 && PyErr_Occurred()) {
+				PyErr_SetString(PyExc_OverflowError,
+						"long int too long to convert");
+				return -1;
+			}
+		}
+		return 0;
+	}
+
+	if (PyString_Check(obj)) {
+		pa->ffi_type = &ffi_type_pointer;
+		pa->value.p = PyString_AS_STRING(obj);
+		Py_INCREF(obj);
+		pa->keep = obj;
+		return 0;
+	}
+
+#ifdef CTYPES_UNICODE
+	if (PyUnicode_Check(obj)) {
+#ifdef HAVE_USABLE_WCHAR_T
+		pa->ffi_type = &ffi_type_pointer;
+		pa->value.p = PyUnicode_AS_UNICODE(obj);
+		Py_INCREF(obj);
+		pa->keep = obj;
+		return 0;
+#else
+		int size = PyUnicode_GET_SIZE(obj);
+		size += 1; /* terminating NUL */
+		size *= sizeof(wchar_t);
+		pa->value.p = PyMem_Malloc(size);
+		if (!pa->value.p)
+			return -1;
+		memset(pa->value.p, 0, size);
+		pa->keep = PyCObject_FromVoidPtr(pa->value.p, PyMem_Free);
+		if (!pa->keep) {
+			PyMem_Free(pa->value.p);
+			return -1;
+		}
+		if (-1 == PyUnicode_AsWideChar((PyUnicodeObject *)obj,
+					       pa->value.p, PyUnicode_GET_SIZE(obj)))
+			return -1;
+		return 0;
+#endif
+	}
+#endif
+
+	{
+		PyObject *arg;
+		arg = PyObject_GetAttrString(obj, "_as_parameter_");
+		/* Which types should we exactly allow here?
+		   integers are required for using Python classes
+		   as parameters (they have to expose the '_as_parameter_'
+		   attribute)
+		*/
+		if (arg) {
+			int result;
+			result = ConvParam(arg, index, pa);
+			Py_DECREF(arg);
+			return result;
+		}
+		PyErr_Format(PyExc_TypeError,
+			     "Don't know how to convert parameter %d", index);
+		return -1;
+	}
+}
+
+
+ffi_type *GetType(PyObject *obj)
+{
+	StgDictObject *dict;
+	if (obj == NULL)
+		return &ffi_type_sint;
+	dict = PyType_stgdict(obj);
+	if (dict == NULL)
+		return &ffi_type_sint;
+#if defined(MS_WIN32) && !defined(_WIN32_WCE)
+	/* This little trick works correctly with MSVC.
+	   It returns small structures in registers
+	*/
+	if (dict->ffi_type_pointer.type == FFI_TYPE_STRUCT) {
+		if (dict->ffi_type_pointer.size <= 4)
+			return &ffi_type_sint32;
+		else if (dict->ffi_type_pointer.size <= 8)
+			return &ffi_type_sint64;
+	}
+#endif
+	return &dict->ffi_type_pointer;
+}
+
+
+/*
+ * libffi uses:
+ *
+ * ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi,
+ *	                   unsigned int nargs,
+ *                         ffi_type *rtype,
+ *                         ffi_type **atypes);
+ *
+ * and then
+ *
+ * void ffi_call(ffi_cif *cif, void *fn, void *rvalue, void **avalues);
+ */
+static int _call_function_pointer(int flags,
+				  PPROC pProc,
+				  void **avalues,
+				  ffi_type **atypes,
+				  ffi_type *restype,
+				  void *resmem,
+				  int argcount)
+{
+#ifdef WITH_THREAD
+	PyThreadState *_save = NULL; /* For Py_BLOCK_THREADS and Py_UNBLOCK_THREADS */
+#endif
+	ffi_cif cif;
+	int cc;
+#ifdef MS_WIN32
+	int delta;
+#ifndef DONT_USE_SEH
+	DWORD dwExceptionCode = 0;
+	EXCEPTION_RECORD record;
+#endif
+#endif
+	/* XXX check before here */
+	if (restype == NULL) {
+		PyErr_SetString(PyExc_RuntimeError,
+				"No ffi_type for result");
+		return -1;
+	}
+	
+	cc = FFI_DEFAULT_ABI;
+#if defined(MS_WIN32) && !defined(_WIN32_WCE)
+	if ((flags & FUNCFLAG_CDECL) == 0)
+		cc = FFI_STDCALL;
+#endif
+	if (FFI_OK != ffi_prep_cif(&cif,
+				   cc,
+				   argcount,
+				   restype,
+				   atypes)) {
+		PyErr_SetString(PyExc_RuntimeError,
+				"ffi_prep_cif failed");
+		return -1;
+	}
+
+#ifdef WITH_THREAD
+	if ((flags & FUNCFLAG_PYTHONAPI) == 0)
+		Py_UNBLOCK_THREADS
+#endif
+#ifdef MS_WIN32
+#ifndef DONT_USE_SEH
+	__try {
+#endif
+		delta =
+#endif
+			ffi_call(&cif, (void *)pProc, resmem, avalues);
+#ifdef MS_WIN32
+#ifndef DONT_USE_SEH
+	}
+	__except (HandleException(GetExceptionInformation(),
+				  &dwExceptionCode, &record)) {
+		;
+	}
+#endif
+#endif
+#ifdef WITH_THREAD
+	if ((flags & FUNCFLAG_PYTHONAPI) == 0)
+		Py_BLOCK_THREADS
+#endif
+#ifdef MS_WIN32
+#ifndef DONT_USE_SEH
+	if (dwExceptionCode) {
+		SetException(dwExceptionCode, &record);
+		return -1;
+	}
+#endif
+	if (delta < 0) {
+		if (flags & FUNCFLAG_CDECL)
+			PyErr_Format(PyExc_ValueError,
+				     "Procedure called with not enough "
+				     "arguments (%d bytes missing) "
+				     "or wrong calling convention",
+				     -delta);
+		else
+			PyErr_Format(PyExc_ValueError,
+				     "Procedure probably called with not enough "
+				     "arguments (%d bytes missing)",
+				     -delta);
+		return -1;
+	} else if (delta > 0) {
+		PyErr_Format(PyExc_ValueError,
+			     "Procedure probably called with too many "
+			     "arguments (%d bytes in excess)",
+			     delta);
+		return -1;
+	}
+#endif
+	if ((flags & FUNCFLAG_PYTHONAPI) && PyErr_Occurred())
+		return -1;
+	return 0;
+}
+
+/*
+ * Convert the C value in result into a Python object, depending on restype.
+ *
+ * - If restype is NULL, return a Python integer.
+ * - If restype is None, return None.
+ * - If restype is a simple ctypes type (c_int, c_void_p), call the type's getfunc,
+ *   pass the result to checker and return the result.
+ * - If restype is another ctypes type, return an instance of that.
+ * - Otherwise, call restype and return the result.
+ */
+static PyObject *GetResult(PyObject *restype, void *result, PyObject *checker)
+{
+	StgDictObject *dict;
+	PyObject *retval, *v;
+
+	if (restype == NULL)
+		return PyInt_FromLong(*(int *)result);
+
+	if (restype == Py_None) {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+
+	dict = PyType_stgdict(restype);
+	if (dict == NULL)
+		return PyObject_CallFunction(restype, "i", *(int *)result);
+
+	if (dict->getfunc && !IsSimpleSubType(restype)) {
+		retval = dict->getfunc(result, dict->size);
+		/* If restype is py_object (detected by comparing getfunc with
+		   O_get), we have to call Py_DECREF because O_get has already
+		   called Py_INCREF.
+		*/
+		if (dict->getfunc == getentry("O")->getfunc) {
+			Py_DECREF(retval);
+		}
+	} else
+		retval = CData_FromBaseObj(restype, NULL, 0, result);
+
+	if (!checker || !retval)
+		return retval;
+
+	v = PyObject_CallFunctionObjArgs(checker, retval, NULL);
+	if (v == NULL)
+		_AddTraceback("GetResult", __FILE__, __LINE__-2);
+	Py_DECREF(retval);
+	return v;
+}
+
+/*
+ * Raise a new exception 'exc_class', adding additional text to the original
+ * exception string.
+ */
+void Extend_Error_Info(PyObject *exc_class, char *fmt, ...)
+{
+	va_list vargs;
+	PyObject *tp, *v, *tb, *s, *cls_str, *msg_str;
+
+	va_start(vargs, fmt);
+	s = PyString_FromFormatV(fmt, vargs);
+	va_end(vargs);
+	if (!s)
+		return;
+
+	PyErr_Fetch(&tp, &v, &tb);
+	PyErr_NormalizeException(&tp, &v, &tb);
+	cls_str = PyObject_Str(tp);
+	if (cls_str) {
+		PyString_ConcatAndDel(&s, cls_str);
+		PyString_ConcatAndDel(&s, PyString_FromString(": "));
+		if (s == NULL)
+			goto error;
+	} else
+		PyErr_Clear();
+	msg_str = PyObject_Str(v);
+	if (msg_str)
+		PyString_ConcatAndDel(&s, msg_str);
+	else {
+		PyErr_Clear();
+		PyString_ConcatAndDel(&s, PyString_FromString("???"));
+		if (s == NULL)
+			goto error;
+	}
+	PyErr_SetObject(exc_class, s);
+error:
+	Py_XDECREF(tp);
+	Py_XDECREF(v);
+	Py_XDECREF(tb);
+	Py_XDECREF(s);
+}
+
+
+#ifdef MS_WIN32
+
+static PyObject *
+GetComError(HRESULT errcode, GUID *riid, IUnknown *pIunk)
+{
+	HRESULT hr;
+	ISupportErrorInfo *psei = NULL;
+	IErrorInfo *pei = NULL;
+	BSTR descr=NULL, helpfile=NULL, source=NULL;
+	GUID guid;
+	DWORD helpcontext=0;
+	LPOLESTR progid;
+	PyObject *obj;
+	TCHAR *text;
+
+	/* We absolutely have to release the GIL during COM method calls,
+	   otherwise we may get a deadlock!
+	*/
+#ifdef WITH_THREAD
+	Py_BEGIN_ALLOW_THREADS
+#endif
+
+	hr = pIunk->lpVtbl->QueryInterface(pIunk, &IID_ISupportErrorInfo, (void **)&psei);
+	if (FAILED(hr))
+		goto failed;
+
+	hr = psei->lpVtbl->InterfaceSupportsErrorInfo(psei, riid);
+	psei->lpVtbl->Release(psei);
+	if (FAILED(hr))
+		goto failed;
+
+	hr = GetErrorInfo(0, &pei);
+	if (hr != S_OK)
+		goto failed;
+
+	pei->lpVtbl->GetDescription(pei, &descr);
+	pei->lpVtbl->GetGUID(pei, &guid);
+	pei->lpVtbl->GetHelpContext(pei, &helpcontext);
+	pei->lpVtbl->GetHelpFile(pei, &helpfile);
+	pei->lpVtbl->GetSource(pei, &source);
+
+	pei->lpVtbl->Release(pei);
+
+  failed:
+#ifdef WITH_THREAD
+	Py_END_ALLOW_THREADS
+#endif
+
+	progid = NULL;
+	ProgIDFromCLSID(&guid, &progid);
+
+	text = FormatError(errcode);
+	obj = Py_BuildValue(
+#ifdef _UNICODE
+		"iu(uuuiu)",
+#else
+		"is(uuuiu)",
+#endif
+		errcode,
+		text,
+		descr, source, helpfile, helpcontext,
+		progid);
+	if (obj) {
+		PyErr_SetObject(ComError, obj);
+		Py_DECREF(obj);
+	}
+	LocalFree(text);
+
+	if (descr)
+		SysFreeString(descr);
+	if (helpfile)
+		SysFreeString(helpfile);
+	if (source)
+		SysFreeString(source);
+
+	return NULL;
+}
+#endif
+
+/*
+ * Requirements, must be ensured by the caller:
+ * - argtuple is tuple of arguments
+ * - argtypes is either NULL, or a tuple of the same size as argtuple
+ *
+ * - XXX various requirements for restype, not yet collected
+ */
+PyObject *_CallProc(PPROC pProc,
+		    PyObject *argtuple,
+#ifdef MS_WIN32
+		    IUnknown *pIunk,
+		    GUID *iid,
+#endif
+		    int flags,
+		    PyObject *argtypes, /* misleading name: This is a tuple of
+					   methods, not types: the .from_param
+					   class methods of the types */
+		    PyObject *restype,
+		    PyObject *checker)
+{
+	int i, n, argcount, argtype_count;
+	void *resbuf;
+	struct argument *args, *pa;
+	ffi_type **atypes;
+	ffi_type *rtype;
+	void **avalues;
+	PyObject *retval = NULL;
+
+	n = argcount = PyTuple_GET_SIZE(argtuple);
+#ifdef MS_WIN32
+	/* an optional COM object this pointer */
+	if (pIunk)
+		++argcount;
+#endif
+
+	args = (struct argument *)alloca(sizeof(struct argument) * argcount);
+	if (!args) {
+		PyErr_NoMemory();
+		return NULL;
+	}
+	memset(args, 0, sizeof(struct argument) * argcount);
+	argtype_count = argtypes ? PyTuple_GET_SIZE(argtypes) : 0;
+#ifdef MS_WIN32
+	if (pIunk) {
+		args[0].ffi_type = &ffi_type_pointer;
+		args[0].value.p = pIunk;
+		pa = &args[1];
+	} else
+#endif
+		pa = &args[0];
+
+	/* Convert the arguments */
+	for (i = 0; i < n; ++i, ++pa) {
+		PyObject *converter;
+		PyObject *arg;
+		int err;
+
+		arg = PyTuple_GET_ITEM(argtuple, i);	/* borrowed ref */
+		/* For cdecl functions, we allow more actual arguments
+		   than the length of the argtypes tuple.
+		   This is checked in _ctypes::CFuncPtr_Call
+		*/
+		if (argtypes && argtype_count > i) {
+			PyObject *v;
+			converter = PyTuple_GET_ITEM(argtypes, i);
+			v = PyObject_CallFunctionObjArgs(converter,
+							   arg,
+							   NULL);
+			if (v == NULL) {
+				Extend_Error_Info(PyExc_ArgError, "argument %d: ", i+1);
+				goto cleanup;
+			}
+
+			err = ConvParam(v, i+1, pa);
+			Py_DECREF(v);
+			if (-1 == err) {
+				Extend_Error_Info(PyExc_ArgError, "argument %d: ", i+1);
+				goto cleanup;
+			}
+		} else {
+			err = ConvParam(arg, i+1, pa);
+			if (-1 == err) {
+				Extend_Error_Info(PyExc_ArgError, "argument %d: ", i+1);
+				goto cleanup; /* leaking ? */
+			}
+		}
+	}
+
+	rtype = GetType(restype);
+	resbuf = alloca(max(rtype->size, sizeof(ffi_arg)));
+
+	avalues = (void **)alloca(sizeof(void *) * argcount);
+	atypes = (ffi_type **)alloca(sizeof(ffi_type *) * argcount);
+	if (!resbuf || !avalues || !atypes) {
+		PyErr_NoMemory();
+		goto cleanup;
+	}
+	for (i = 0; i < argcount; ++i) {
+		atypes[i] = args[i].ffi_type;
+		if (atypes[i]->type == FFI_TYPE_STRUCT)
+			avalues[i] = (void *)args[i].value.p;
+		else
+			avalues[i] = (void *)&args[i].value;
+	}
+
+	if (-1 == _call_function_pointer(flags, pProc, avalues, atypes,
+					 rtype, resbuf, argcount))
+		goto cleanup;
+
+#ifdef WORDS_BIGENDIAN
+	/* libffi returns the result in a buffer with sizeof(ffi_arg). This
+	   causes problems on big endian machines, since the result buffer
+	   address cannot simply be used as result pointer, instead we must
+	   adjust the pointer value:
+	 */
+	/*
+	  XXX I should find out and clarify why this is needed at all,
+	  especially why adjusting for ffi_type_float must be avoided on
+	  64-bit platforms.
+	 */
+	if (rtype->type != FFI_TYPE_FLOAT
+	    && rtype->type != FFI_TYPE_STRUCT
+	    && rtype->size < sizeof(ffi_arg))
+		resbuf = (char *)resbuf + sizeof(ffi_arg) - rtype->size;
+#endif
+
+#ifdef MS_WIN32
+	if (iid && pIunk) {
+		if (*(int *)resbuf & 0x80000000)
+			retval = GetComError(*(HRESULT *)resbuf, iid, pIunk);
+		else
+			retval = PyInt_FromLong(*(int *)resbuf);
+	} else if (flags & FUNCFLAG_HRESULT) {
+		if (*(int *)resbuf & 0x80000000)
+			retval = PyErr_SetFromWindowsErr(*(int *)resbuf);
+		else
+			retval = PyInt_FromLong(*(int *)resbuf);
+	} else
+#endif
+		retval = GetResult(restype, resbuf, checker);
+  cleanup:
+	for (i = 0; i < argcount; ++i)
+		Py_XDECREF(args[i].keep);
+	return retval;
+}
+
+#ifdef MS_WIN32
+
+#ifdef _UNICODE
+#  define PYBUILD_TSTR "u"
+#else
+#  define PYBUILD_TSTR "s"
+#  ifndef _T
+#    define _T(text) text
+#  endif
+#endif
+
+static char format_error_doc[] =
+"FormatError([integer]) -> string\n\
+\n\
+Convert a win32 error code into a string. If the error code is not\n\
+given, the return value of a call to GetLastError() is used.\n";
+static PyObject *format_error(PyObject *self, PyObject *args)
+{
+	PyObject *result;
+	TCHAR *lpMsgBuf;
+	DWORD code = 0;
+	if (!PyArg_ParseTuple(args, "|i:FormatError", &code))
+		return NULL;
+	if (code == 0)
+		code = GetLastError();
+	lpMsgBuf = FormatError(code);
+	if (lpMsgBuf) {
+		result = Py_BuildValue(PYBUILD_TSTR, lpMsgBuf);
+		LocalFree(lpMsgBuf);
+	} else {
+		result = Py_BuildValue("s", "<no description>");
+	}
+	return result;
+}
+
+static char load_library_doc[] =
+"LoadLibrary(name) -> handle\n\
+\n\
+Load an executable (usually a DLL), and return a handle to it.\n\
+The handle may be used to locate exported functions in this\n\
+module.\n";
+static PyObject *load_library(PyObject *self, PyObject *args)
+{
+	TCHAR *name;
+	PyObject *nameobj;
+	PyObject *ignored;
+	HMODULE hMod;
+	if (!PyArg_ParseTuple(args, "O|O:LoadLibrary", &nameobj, &ignored))
+		return NULL;
+#ifdef _UNICODE
+	name = alloca((PyString_Size(nameobj) + 1) * sizeof(WCHAR));
+	if (!name) {
+		PyErr_NoMemory();
+		return NULL;
+	}
+
+	{
+		int r;
+		char *aname = PyString_AsString(nameobj);
+		if(!aname)
+			return NULL;
+		r = MultiByteToWideChar(CP_ACP, 0, aname, -1, name, PyString_Size(nameobj) + 1);
+		name[r] = 0;
+	}
+#else
+	name = PyString_AsString(nameobj);
+	if(!name)
+		return NULL;
+#endif
+
+	hMod = LoadLibrary(name);
+	if (!hMod)
+		return PyErr_SetFromWindowsErr(GetLastError());
+	return Py_BuildValue("i", hMod);
+}
+
+static char free_library_doc[] =
+"FreeLibrary(handle) -> void\n\
+\n\
+Free the handle of an executable previously loaded by LoadLibrary.\n";
+static PyObject *free_library(PyObject *self, PyObject *args)
+{
+	HMODULE hMod;
+	if (!PyArg_ParseTuple(args, "i:FreeLibrary", &hMod))
+		return NULL;
+	if (!FreeLibrary(hMod))
+		return PyErr_SetFromWindowsErr(GetLastError());
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* obsolete, should be removed */
+/* Only used by sample code (in samples\Windows\COM.py) */
+static PyObject *
+call_commethod(PyObject *self, PyObject *args)
+{
+	IUnknown *pIunk;
+	int index;
+	PyObject *arguments;
+	PPROC *lpVtbl;
+	PyObject *result;
+	CDataObject *pcom;
+	PyObject *argtypes = NULL;
+
+	if (!PyArg_ParseTuple(args,
+			      "OiO!|O!",
+			      &pcom, &index,
+			      &PyTuple_Type, &arguments,
+			      &PyTuple_Type, &argtypes))
+		return NULL;
+
+	if (argtypes && (PyTuple_GET_SIZE(arguments) != PyTuple_GET_SIZE(argtypes))) {
+		PyErr_Format(PyExc_TypeError,
+			     "Method takes %d arguments (%d given)",
+			     PyTuple_GET_SIZE(argtypes), PyTuple_GET_SIZE(arguments));
+		return NULL;
+	}
+
+	if (!CDataObject_Check(pcom) || (pcom->b_size != sizeof(void *))) {
+		PyErr_Format(PyExc_TypeError,
+			     "COM Pointer expected instead of %s instance",
+			     pcom->ob_type->tp_name);
+		return NULL;
+	}
+
+	if ((*(void **)(pcom->b_ptr)) == NULL) {
+		PyErr_SetString(PyExc_ValueError,
+				"The COM 'this' pointer is NULL");
+		return NULL;
+	}
+
+	pIunk = (IUnknown *)(*(void **)(pcom->b_ptr));
+	lpVtbl = (PPROC *)(pIunk->lpVtbl);
+
+	result =  _CallProc(lpVtbl[index],
+			    arguments,
+#ifdef MS_WIN32
+			    pIunk,
+			    NULL,
+#endif
+			    FUNCFLAG_HRESULT, /* flags */
+			    argtypes, /* self->argtypes */
+			    NULL, /* self->restype */
+			    NULL); /* checker */
+	return result;
+}
+
+static char copy_com_pointer_doc[] =
+"CopyComPointer(src, dst) -> HRESULT value\n";
+
+static PyObject *
+copy_com_pointer(PyObject *self, PyObject *args)
+{
+	PyObject *p1, *p2, *r = NULL;
+	struct argument a, b;
+	IUnknown *src, **pdst;
+	if (!PyArg_ParseTuple(args, "OO:CopyComPointer", &p1, &p2))
+		return NULL;
+	a.keep = b.keep = NULL;
+
+	if (-1 == ConvParam(p1, 0, &a) || -1 == ConvParam(p2, 1, &b))
+		goto done;
+	src = (IUnknown *)a.value.p;
+	pdst = (IUnknown **)b.value.p;
+
+	if (pdst == NULL)
+		r = PyInt_FromLong(E_POINTER);
+	else {
+		if (src)
+			src->lpVtbl->AddRef(src);
+		*pdst = src;
+		r = PyInt_FromLong(S_OK);
+	}
+  done:
+	Py_XDECREF(a.keep);
+	Py_XDECREF(b.keep);
+	return r;
+}
+#else
+
+static PyObject *py_dl_open(PyObject *self, PyObject *args)
+{
+	char *name;
+	void * handle;
+#ifdef RTLD_LOCAL	
+	int mode = RTLD_NOW | RTLD_LOCAL;
+#else
+	/* cygwin doesn't define RTLD_LOCAL */
+	int mode = RTLD_NOW;
+#endif
+	if (!PyArg_ParseTuple(args, "z|i:dlopen", &name, &mode))
+		return NULL;
+	mode |= RTLD_NOW;
+	handle = ctypes_dlopen(name, mode);
+	if (!handle) {
+		PyErr_SetString(PyExc_OSError,
+				       ctypes_dlerror());
+		return NULL;
+	}
+	return PyLong_FromVoidPtr(handle);
+}
+
+static PyObject *py_dl_close(PyObject *self, PyObject *args)
+{
+	void * handle;
+
+	if (!PyArg_ParseTuple(args, "i:dlclose", &handle))
+		return NULL;
+	if (dlclose(handle)) {
+		PyErr_SetString(PyExc_OSError,
+				       ctypes_dlerror());
+		return NULL;
+	}
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *py_dl_sym(PyObject *self, PyObject *args)
+{
+	char *name;
+	void *handle;
+	void *ptr;
+
+	if (!PyArg_ParseTuple(args, "is:dlsym", &handle, &name))
+		return NULL;
+	ptr = ctypes_dlsym(handle, name);
+	if (!ptr) {
+		PyErr_SetString(PyExc_OSError,
+				       ctypes_dlerror());
+		return NULL;
+	}
+	return Py_BuildValue("i", ptr);
+}
+#endif
+
+/*
+ * Only for debugging so far: So that we can call CFunction instances
+ *
+ * XXX Needs to accept more arguments: flags, argtypes, restype
+ */
+static PyObject *
+call_function(PyObject *self, PyObject *args)
+{
+	PPROC func;
+	PyObject *arguments;
+	PyObject *result;
+
+	if (!PyArg_ParseTuple(args,
+			      "iO!",
+			      &func,
+			      &PyTuple_Type, &arguments))
+		return NULL;
+
+	result =  _CallProc(func,
+			    arguments,
+#ifdef MS_WIN32
+			    NULL,
+			    NULL,
+#endif
+			    0, /* flags */
+			    NULL, /* self->argtypes */
+			    NULL, /* self->restype */
+			    NULL); /* checker */
+	return result;
+}
+
+/*
+ * Only for debugging so far: So that we can call CFunction instances
+ *
+ * XXX Needs to accept more arguments: flags, argtypes, restype
+ */
+static PyObject *
+call_cdeclfunction(PyObject *self, PyObject *args)
+{
+	PPROC func;
+	PyObject *arguments;
+	PyObject *result;
+
+	if (!PyArg_ParseTuple(args,
+			      "iO!",
+			      &func,
+			      &PyTuple_Type, &arguments))
+		return NULL;
+
+	result =  _CallProc(func,
+			    arguments,
+#ifdef MS_WIN32
+			    NULL,
+			    NULL,
+#endif
+			    FUNCFLAG_CDECL, /* flags */
+			    NULL, /* self->argtypes */
+			    NULL, /* self->restype */
+			    NULL); /* checker */
+	return result;
+}
+
+/*****************************************************************
+ * functions
+ */
+static char sizeof_doc[] =
+"sizeof(C type) -> integer\n"
+"sizeof(C instance) -> integer\n"
+"Return the size in bytes of a C instance";
+
+static PyObject *
+sizeof_func(PyObject *self, PyObject *obj)
+{
+	StgDictObject *dict;
+
+	dict = PyType_stgdict(obj);
+	if (dict)
+		return PyInt_FromLong(dict->size);
+
+	if (CDataObject_Check(obj))
+		return PyInt_FromLong(((CDataObject *)obj)->b_size);
+	PyErr_SetString(PyExc_TypeError,
+			"this type has no size");
+	return NULL;
+}
+
+static char alignment_doc[] =
+"alignment(C type) -> integer\n"
+"alignment(C instance) -> integer\n"
+"Return the alignment requirements of a C instance";
+
+static PyObject *
+align_func(PyObject *self, PyObject *obj)
+{
+	StgDictObject *dict;
+
+	dict = PyType_stgdict(obj);
+	if (dict)
+		return PyInt_FromLong(dict->align);
+
+	dict = PyObject_stgdict(obj);
+	if (dict)
+		return PyInt_FromLong(dict->align);
+
+	PyErr_SetString(PyExc_TypeError,
+			"no alignment info");
+	return NULL;
+}
+
+static char byref_doc[] =
+"byref(C instance) -> byref-object\n"
+"Return a pointer lookalike to a C instance, only usable\n"
+"as function argument";
+
+/*
+ * We must return something which can be converted to a parameter,
+ * but still has a reference to self.
+ */
+static PyObject *
+byref(PyObject *self, PyObject *obj)
+{
+	PyCArgObject *parg;
+	if (!CDataObject_Check(obj)) {
+		PyErr_Format(PyExc_TypeError,
+			     "byref() argument must be a ctypes instance, not '%s'",
+			     obj->ob_type->tp_name);
+		return NULL;
+	}
+
+	parg = new_CArgObject();
+	if (parg == NULL)
+		return NULL;
+
+	parg->tag = 'P';
+	parg->pffi_type = &ffi_type_pointer;
+	Py_INCREF(obj);
+	parg->obj = obj;
+	parg->value.p = ((CDataObject *)obj)->b_ptr;
+	return (PyObject *)parg;
+}
+
+static char addressof_doc[] =
+"addressof(C instance) -> integer\n"
+"Return the address of the C instance internal buffer";
+
+static PyObject *
+addressof(PyObject *self, PyObject *obj)
+{
+	if (CDataObject_Check(obj))
+		return PyLong_FromVoidPtr(((CDataObject *)obj)->b_ptr);
+	PyErr_SetString(PyExc_TypeError,
+			"invalid type");
+	return NULL;
+}
+
+static int
+converter(PyObject *obj, void **address)
+{
+	*address = PyLong_AsVoidPtr(obj);
+	return *address != NULL;
+}
+
+static PyObject *
+My_PyObj_FromPtr(PyObject *self, PyObject *args)
+{
+	PyObject *ob;
+	if (!PyArg_ParseTuple(args, "O&:PyObj_FromPtr", converter, &ob))
+		return NULL;
+	Py_INCREF(ob);
+	return ob;
+}
+
+static PyObject *
+My_Py_INCREF(PyObject *self, PyObject *arg)
+{
+	Py_INCREF(arg); /* that's what this function is for */
+	Py_INCREF(arg); /* that for returning it */
+	return arg;
+}
+
+static PyObject *
+My_Py_DECREF(PyObject *self, PyObject *arg)
+{
+	Py_DECREF(arg); /* that's what this function is for */
+	Py_INCREF(arg); /* that's for returning it */
+	return arg;
+}
+
+#ifdef CTYPES_UNICODE
+
+static char set_conversion_mode_doc[] =
+"set_conversion_mode(encoding, errors) -> (previous-encoding, previous-errors)\n\
+\n\
+Set the encoding and error handling ctypes uses when converting\n\
+between unicode and strings.  Returns the previous values.\n";
+
+static PyObject *
+set_conversion_mode(PyObject *self, PyObject *args)
+{
+	char *coding, *mode;
+	PyObject *result;
+
+	if (!PyArg_ParseTuple(args, "zs:set_conversion_mode", &coding, &mode))
+		return NULL;
+	result = Py_BuildValue("(zz)", conversion_mode_encoding, conversion_mode_errors);
+	if (coding) {
+		PyMem_Free(conversion_mode_encoding);
+		conversion_mode_encoding = PyMem_Malloc(strlen(coding) + 1);
+		strcpy(conversion_mode_encoding, coding);
+	} else {
+		conversion_mode_encoding = NULL;
+	}
+	PyMem_Free(conversion_mode_errors);
+	conversion_mode_errors = PyMem_Malloc(strlen(mode) + 1);
+	strcpy(conversion_mode_errors, mode);
+	return result;
+}
+#endif
+
+static PyObject *
+resize(PyObject *self, PyObject *args)
+{
+	CDataObject *obj;
+	StgDictObject *dict;
+	Py_ssize_t size;
+
+	if (!PyArg_ParseTuple(args,
+#if (PY_VERSION_HEX < 0x02050000)
+			      "Oi:resize",
+#else
+			      "On:resize",
+#endif
+			      (PyObject *)&obj, &size))
+		return NULL;
+
+	dict = PyObject_stgdict((PyObject *)obj);
+	if (dict == NULL) {
+		PyErr_SetString(PyExc_TypeError,
+				"excepted ctypes instance");
+		return NULL;
+	}
+	if (size < dict->size) {
+		PyErr_Format(PyExc_ValueError,
+#if PY_VERSION_HEX < 0x02050000
+			     "minimum size is %d",
+#else
+			     "minimum size is %zd",
+#endif
+			     dict->size);
+		return NULL;
+	}
+	if (obj->b_needsfree == 0) {
+		PyErr_Format(PyExc_ValueError,
+			     "Memory cannot be resized because this object doesn't own it");
+		return NULL;
+	}
+	if (size <= sizeof(obj->b_value)) {
+		/* internal default buffer is large enough */
+		obj->b_size = size;
+		goto done;
+	}
+	if (obj->b_size <= sizeof(obj->b_value)) {
+		/* We are currently using the objects default buffer, but it
+		   isn't large enough any more. */
+		void *ptr = PyMem_Malloc(size);
+		if (ptr == NULL)
+			return PyErr_NoMemory();
+		memset(ptr, 0, size);
+		memmove(ptr, obj->b_ptr, obj->b_size);
+		obj->b_ptr = ptr;
+		obj->b_size = size;
+	} else {
+		void * ptr = PyMem_Realloc(obj->b_ptr, size);
+		if (ptr == NULL)
+			return PyErr_NoMemory();
+		obj->b_ptr = ptr;
+		obj->b_size = size;
+	}
+  done:
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyMethodDef module_methods[] = {
+	{"resize", resize, METH_VARARGS, "Resize the memory buffer of a ctypes instance"},
+#ifdef CTYPES_UNICODE
+	{"set_conversion_mode", set_conversion_mode, METH_VARARGS, set_conversion_mode_doc},
+#endif
+#ifdef MS_WIN32
+	{"CopyComPointer", copy_com_pointer, METH_VARARGS, copy_com_pointer_doc},
+	{"FormatError", format_error, METH_VARARGS, format_error_doc},
+	{"LoadLibrary", load_library, METH_VARARGS, load_library_doc},
+	{"FreeLibrary", free_library, METH_VARARGS, free_library_doc},
+	{"call_commethod", call_commethod, METH_VARARGS },
+	{"_check_HRESULT", check_hresult, METH_VARARGS},
+#else
+	{"dlopen", py_dl_open, METH_VARARGS,
+	 "dlopen(name, flag={RTLD_GLOBAL|RTLD_LOCAL}) open a shared library"},
+	{"dlclose", py_dl_close, METH_VARARGS, "dlclose a library"},
+	{"dlsym", py_dl_sym, METH_VARARGS, "find symbol in shared library"},
+#endif
+	{"alignment", align_func, METH_O, alignment_doc},
+	{"sizeof", sizeof_func, METH_O, sizeof_doc},
+	{"byref", byref, METH_O, byref_doc},
+	{"addressof", addressof, METH_O, addressof_doc},
+	{"call_function", call_function, METH_VARARGS },
+	{"call_cdeclfunction", call_cdeclfunction, METH_VARARGS },
+	{"PyObj_FromPtr", My_PyObj_FromPtr, METH_VARARGS },
+	{"Py_INCREF", My_Py_INCREF, METH_O },
+	{"Py_DECREF", My_Py_DECREF, METH_O },
+	{NULL,      NULL}        /* Sentinel */
+};
+
+/*
+ Local Variables:
+ compile-command: "cd .. && python setup.py -q build -g && python setup.py -q build install --home ~"
+ End:
+*/

Added: vendor/Python/current/Modules/_ctypes/cfield.c
===================================================================
--- vendor/Python/current/Modules/_ctypes/cfield.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/cfield.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1668 @@
+/*****************************************************************
+  This file should be kept compatible with Python 2.3, see PEP 291.
+ *****************************************************************/
+
+#include "Python.h"
+
+#include <ffi.h>
+#ifdef MS_WIN32
+#include <windows.h>
+#endif
+#include "ctypes.h"
+
+/******************************************************************/
+/*
+  CField_Type
+*/
+static PyObject *
+CField_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	CFieldObject *obj;
+	obj = (CFieldObject *)type->tp_alloc(type, 0);
+	return (PyObject *)obj;
+}
+
+/*
+ * Expects the size, index and offset for the current field in *psize and
+ * *poffset, stores the total size so far in *psize, the offset for the next
+ * field in *poffset, the alignment requirements for the current field in
+ * *palign, and returns a field desriptor for this field.
+ */
+/*
+ * bitfields extension:
+ * bitsize != 0: this is a bit field.
+ * pbitofs points to the current bit offset, this will be updated.
+ * prev_desc points to the type of the previous bitfield, if any.
+ */
+PyObject *
+CField_FromDesc(PyObject *desc, int index,
+		int *pfield_size, int bitsize, int *pbitofs,
+		int *psize, int *poffset, int *palign,
+		int pack, int big_endian)
+{
+	CFieldObject *self;
+	PyObject *proto;
+	int size, align, length;
+	SETFUNC setfunc = NULL;
+	GETFUNC getfunc = NULL;
+	StgDictObject *dict;
+	int fieldtype;
+#define NO_BITFIELD 0
+#define NEW_BITFIELD 1
+#define CONT_BITFIELD 2
+#define EXPAND_BITFIELD 3
+
+	self = (CFieldObject *)PyObject_CallObject((PyObject *)&CField_Type,
+						   NULL);
+	if (self == NULL)
+		return NULL;
+	dict = PyType_stgdict(desc);
+	if (!dict) {
+		PyErr_SetString(PyExc_TypeError,
+				"has no _stginfo_");
+		Py_DECREF(self);
+		return NULL;
+	}
+	if (bitsize /* this is a bitfield request */
+	    && *pfield_size /* we have a bitfield open */
+#if defined(MS_WIN32) && !defined(__MINGW32__)
+	    && dict->size * 8 == *pfield_size /* MSVC */
+#else
+	    && dict->size * 8 <= *pfield_size /* GCC, MINGW */
+#endif
+	    && (*pbitofs + bitsize) <= *pfield_size) {
+		/* continue bit field */
+		fieldtype = CONT_BITFIELD;
+#ifndef MS_WIN32
+	} else if (bitsize /* this is a bitfield request */
+	    && *pfield_size /* we have a bitfield open */
+	    && dict->size * 8 >= *pfield_size
+	    && (*pbitofs + bitsize) <= dict->size * 8) {
+		/* expand bit field */
+		fieldtype = EXPAND_BITFIELD;
+#endif
+	} else if (bitsize) {
+		/* start new bitfield */
+		fieldtype = NEW_BITFIELD;
+		*pbitofs = 0;
+		*pfield_size = dict->size * 8;
+	} else {
+		/* not a bit field */
+		fieldtype = NO_BITFIELD;
+		*pbitofs = 0;
+		*pfield_size = 0;
+	}
+
+	size = dict->size;
+	length = dict->length;
+	proto = desc;
+
+	/*  Field descriptors for 'c_char * n' are be scpecial cased to
+	    return a Python string instead of an Array object instance...
+	*/
+	if (ArrayTypeObject_Check(proto)) {
+		StgDictObject *adict = PyType_stgdict(proto);
+		StgDictObject *idict;
+		if (adict && adict->proto) {
+			idict = PyType_stgdict(adict->proto);
+			if (!idict) {
+				PyErr_SetString(PyExc_TypeError,
+						"has no _stginfo_");
+				Py_DECREF(self);
+				return NULL;
+			}
+			if (idict->getfunc == getentry("c")->getfunc) {
+				struct fielddesc *fd = getentry("s");
+				getfunc = fd->getfunc;
+				setfunc = fd->setfunc;
+			}
+#ifdef CTYPES_UNICODE
+			if (idict->getfunc == getentry("u")->getfunc) {
+				struct fielddesc *fd = getentry("U");
+				getfunc = fd->getfunc;
+				setfunc = fd->setfunc;
+			}
+#endif
+		}
+	}
+
+	self->setfunc = setfunc;
+	self->getfunc = getfunc;
+	self->index = index;
+
+	Py_INCREF(proto);
+	self->proto = proto;
+
+	switch (fieldtype) {
+	case NEW_BITFIELD:
+		if (big_endian)
+			self->size = (bitsize << 16) + *pfield_size - *pbitofs - bitsize;
+		else
+			self->size = (bitsize << 16) + *pbitofs;
+		*pbitofs = bitsize;
+		/* fall through */
+	case NO_BITFIELD:
+		if (pack)
+			align = min(pack, dict->align);
+		else
+			align = dict->align;
+		if (align && *poffset % align) {
+			int delta = align - (*poffset % align);
+			*psize += delta;
+			*poffset += delta;
+		}
+
+		if (bitsize == 0)
+			self->size = size;
+		*psize += size;
+
+		self->offset = *poffset;
+		*poffset += size;
+
+		*palign = align;
+		break;
+
+	case EXPAND_BITFIELD:
+		/* XXX needs more */
+		*psize += dict->size - *pfield_size/8;
+
+		*pfield_size = dict->size * 8;
+
+		if (big_endian)
+			self->size = (bitsize << 16) + *pfield_size - *pbitofs - bitsize;
+		else
+			self->size = (bitsize << 16) + *pbitofs;
+
+		self->offset = *poffset - size; /* poffset is already updated for the NEXT field */
+		*pbitofs += bitsize;
+		break;
+
+	case CONT_BITFIELD:
+		if (big_endian)
+			self->size = (bitsize << 16) + *pfield_size - *pbitofs - bitsize;
+		else
+			self->size = (bitsize << 16) + *pbitofs;
+
+		self->offset = *poffset - size; /* poffset is already updated for the NEXT field */
+		*pbitofs += bitsize;
+		break;
+	}
+
+	return (PyObject *)self;
+}
+
+static int
+CField_set(CFieldObject *self, PyObject *inst, PyObject *value)
+{
+	CDataObject *dst;
+	char *ptr;
+	assert(CDataObject_Check(inst));
+	dst = (CDataObject *)inst;
+	ptr = dst->b_ptr + self->offset;
+	return CData_set(inst, self->proto, self->setfunc, value,
+			 self->index, self->size, ptr);
+}
+
+static PyObject *
+CField_get(CFieldObject *self, PyObject *inst, PyTypeObject *type)
+{
+	CDataObject *src;
+	if (inst == NULL) {
+		Py_INCREF(self);
+		return (PyObject *)self;
+	}
+	assert(CDataObject_Check(inst));
+	src = (CDataObject *)inst;
+	return CData_get(self->proto, self->getfunc, inst,
+			 self->index, self->size, src->b_ptr + self->offset);
+}
+
+static PyObject *
+CField_get_offset(PyObject *self, void *data)
+{
+#if (PY_VERSION_HEX < 0x02050000)
+	return PyInt_FromLong(((CFieldObject *)self)->offset);
+#else
+	return PyInt_FromSsize_t(((CFieldObject *)self)->offset);
+#endif
+}
+
+static PyObject *
+CField_get_size(PyObject *self, void *data)
+{
+#if (PY_VERSION_HEX < 0x02050000)
+	return PyInt_FromLong(((CFieldObject *)self)->size);
+#else
+	return PyInt_FromSsize_t(((CFieldObject *)self)->size);
+#endif
+}
+
+static PyGetSetDef CField_getset[] = {
+	{ "offset", CField_get_offset, NULL, "offset in bytes of this field" },
+	{ "size", CField_get_size, NULL, "size in bytes of this field" },
+	{ NULL, NULL, NULL, NULL },
+};
+
+static int
+CField_traverse(CFieldObject *self, visitproc visit, void *arg)
+{
+	Py_VISIT(self->proto);
+	return 0;
+}
+
+static int
+CField_clear(CFieldObject *self)
+{
+	Py_CLEAR(self->proto);
+	return 0;
+}
+
+static void
+CField_dealloc(PyObject *self)
+{
+	CField_clear((CFieldObject *)self);
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *
+CField_repr(CFieldObject *self)
+{
+	PyObject *result;
+	int bits = self->size >> 16;
+	int size = self->size & 0xFFFF;
+	const char *name;
+
+	name = ((PyTypeObject *)self->proto)->tp_name;
+
+	if (bits)
+		result = PyString_FromFormat(
+#if (PY_VERSION_HEX < 0x02050000)
+			"<Field type=%s, ofs=%d:%d, bits=%d>",
+#else
+			"<Field type=%s, ofs=%zd:%d, bits=%d>",
+#endif
+			name, self->offset, size, bits);
+	else
+		result = PyString_FromFormat(
+#if (PY_VERSION_HEX < 0x02050000)
+			"<Field type=%s, ofs=%d, size=%d>",
+#else
+			"<Field type=%s, ofs=%zd, size=%d>",
+#endif
+			name, self->offset, size);
+	return result;
+}
+
+PyTypeObject CField_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0,					/* ob_size */
+	"_ctypes.CField",				/* tp_name */
+	sizeof(CFieldObject),			/* tp_basicsize */
+	0,					/* tp_itemsize */
+	CField_dealloc,				/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	(reprfunc)CField_repr,			/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	0,					/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+	"Structure/Union member",		/* tp_doc */
+	(traverseproc)CField_traverse,		/* tp_traverse */
+	(inquiry)CField_clear,			/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	0,					/* tp_methods */
+	0,					/* tp_members */
+	CField_getset,				/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	(descrgetfunc)CField_get,		/* tp_descr_get */
+	(descrsetfunc)CField_set,		/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	0,					/* tp_init */
+	0,					/* tp_alloc */
+	CField_new,				/* tp_new */
+	0,					/* tp_free */
+};
+
+
+/******************************************************************/
+/*
+  Accessor functions
+*/
+
+/* Derived from Modules/structmodule.c:
+   Helper routine to get a Python integer and raise the appropriate error
+   if it isn't one */
+
+static int
+get_long(PyObject *v, long *p)
+{
+	long x;
+	if (!PyInt_Check(v) && !PyLong_Check(v)) {
+		PyErr_Format(PyExc_TypeError,
+			     "int expected instead of %s instance",
+			     v->ob_type->tp_name);
+		return -1;
+	}
+	x = PyInt_AsUnsignedLongMask(v);
+	if (x == -1 && PyErr_Occurred())
+		return -1;
+	*p = x;
+	return 0;
+}
+
+/* Same, but handling unsigned long */
+
+static int
+get_ulong(PyObject *v, unsigned long *p)
+{
+	unsigned long x;
+	if (!PyInt_Check(v) && !PyLong_Check(v)) {
+		PyErr_Format(PyExc_TypeError,
+			     "int expected instead of %s instance",
+			     v->ob_type->tp_name);
+		return -1;
+	}
+	x = PyInt_AsUnsignedLongMask(v);
+	if (x == -1 && PyErr_Occurred())
+		return -1;
+	*p = x;
+	return 0;
+}
+
+#ifdef HAVE_LONG_LONG
+
+/* Same, but handling native long long. */
+
+static int
+get_longlong(PyObject *v, PY_LONG_LONG *p)
+{
+	PY_LONG_LONG x;
+	if (!PyInt_Check(v) && !PyLong_Check(v)) {
+		PyErr_Format(PyExc_TypeError,
+			     "int expected instead of %s instance",
+			     v->ob_type->tp_name);
+		return -1;
+	}
+	x = PyInt_AsUnsignedLongLongMask(v);
+	if (x == -1 && PyErr_Occurred())
+		return -1;
+	*p = x;
+	return 0;
+}
+
+/* Same, but handling native unsigned long long. */
+
+static int
+get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p)
+{
+	unsigned PY_LONG_LONG x;
+	if (!PyInt_Check(v) && !PyLong_Check(v)) {
+		PyErr_Format(PyExc_TypeError,
+			     "int expected instead of %s instance",
+			     v->ob_type->tp_name);
+		return -1;
+	}
+	x = PyInt_AsUnsignedLongLongMask(v);
+	if (x == -1 && PyErr_Occurred())
+		return -1;
+	*p = x;
+	return 0;
+}
+
+#endif
+
+/*****************************************************************
+ * Integer fields, with bitfield support
+ */
+
+/* how to decode the size field, for integer get/set functions */
+#define LOW_BIT(x)  ((x) & 0xFFFF)
+#define NUM_BITS(x) ((x) >> 16)
+
+/* This seems nore a compiler issue than a Windows/non-Windows one */
+#ifdef MS_WIN32
+#  define BIT_MASK(size) ((1 << NUM_BITS(size))-1)
+#else
+#  define BIT_MASK(size) ((1LL << NUM_BITS(size))-1)
+#endif
+
+/* This macro CHANGES the first parameter IN PLACE. For proper sign handling,
+   we must first shift left, then right.
+*/
+#define GET_BITFIELD(v, size)						\
+	if (NUM_BITS(size)) {						\
+		v <<= (sizeof(v)*8 - LOW_BIT(size) - NUM_BITS(size));	\
+		v >>= (sizeof(v)*8 - NUM_BITS(size));			\
+	}
+
+/* This macro RETURNS the first parameter with the bit field CHANGED. */
+#define SET(x, v, size)							\
+	(NUM_BITS(size) ?						\
+	 ( ( x & ~(BIT_MASK(size) << LOW_BIT(size)) ) | ( (v & BIT_MASK(size)) << LOW_BIT(size) ) ) \
+	 : v)
+
+/* byte swapping macros */
+#define SWAP_2(v)				\
+	( ( (v >> 8) & 0x00FF) |		\
+	  ( (v << 8) & 0xFF00) )
+
+#define SWAP_4(v)			\
+	( ( (v & 0x000000FF) << 24 ) |  \
+	  ( (v & 0x0000FF00) <<  8 ) |  \
+	  ( (v & 0x00FF0000) >>  8 ) |  \
+	  ( ((v >> 24) & 0xFF)) )
+
+#ifdef _MSC_VER
+#define SWAP_8(v)				\
+	( ( (v & 0x00000000000000FFL) << 56 ) |  \
+	  ( (v & 0x000000000000FF00L) << 40 ) |  \
+	  ( (v & 0x0000000000FF0000L) << 24 ) |  \
+	  ( (v & 0x00000000FF000000L) <<  8 ) |  \
+	  ( (v & 0x000000FF00000000L) >>  8 ) |  \
+	  ( (v & 0x0000FF0000000000L) >> 24 ) |  \
+	  ( (v & 0x00FF000000000000L) >> 40 ) |  \
+	  ( ((v >> 56) & 0xFF)) )
+#else
+#define SWAP_8(v)				\
+	( ( (v & 0x00000000000000FFLL) << 56 ) |  \
+	  ( (v & 0x000000000000FF00LL) << 40 ) |  \
+	  ( (v & 0x0000000000FF0000LL) << 24 ) |  \
+	  ( (v & 0x00000000FF000000LL) <<  8 ) |  \
+	  ( (v & 0x000000FF00000000LL) >>  8 ) |  \
+	  ( (v & 0x0000FF0000000000LL) >> 24 ) |  \
+	  ( (v & 0x00FF000000000000LL) >> 40 ) |  \
+	  ( ((v >> 56) & 0xFF)) )
+#endif
+
+#define SWAP_INT SWAP_4
+
+#if SIZEOF_LONG == 4
+# define SWAP_LONG SWAP_4
+#elif SIZEOF_LONG == 8
+# define SWAP_LONG SWAP_8
+#endif
+/*****************************************************************
+ * The setter methods return an object which must be kept alive, to keep the
+ * data valid which has been stored in the memory block.  The ctypes object
+ * instance inserts this object into its 'b_objects' list.
+ *
+ * For simple Python types like integers or characters, there is nothing that
+ * has to been kept alive, so Py_None is returned in these cases.  But this
+ * makes inspecting the 'b_objects' list, which is accessible from Python for
+ * debugging, less useful.
+ *
+ * So, defining the _CTYPES_DEBUG_KEEP symbol returns the original value
+ * instead of Py_None.
+ */
+
+#ifdef _CTYPES_DEBUG_KEEP
+#define _RET(x) Py_INCREF(x); return x
+#else
+#define _RET(X) Py_INCREF(Py_None); return Py_None
+#endif
+
+/*****************************************************************
+ * integer accessor methods, supporting bit fields
+ */
+
+static PyObject *
+b_set(void *ptr, PyObject *value, unsigned size)
+{
+	long val;
+	if (get_long(value, &val) < 0)
+		return NULL;
+	*(signed char *)ptr = (signed char)SET(*(signed char *)ptr, (signed char)val, size);
+	_RET(value);
+}
+
+
+static PyObject *
+b_get(void *ptr, unsigned size)
+{
+	signed char val = *(signed char *)ptr;
+	GET_BITFIELD(val, size);
+	return PyInt_FromLong(val);
+}
+
+static PyObject *
+B_set(void *ptr, PyObject *value, unsigned size)
+{
+	unsigned long val;
+	if (get_ulong(value, &val) < 0)
+		return NULL;
+	*(unsigned char *)ptr = (unsigned char)SET(*(unsigned char*)ptr,
+						   (unsigned short)val, size);
+	_RET(value);
+}
+
+
+static PyObject *
+B_get(void *ptr, unsigned size)
+{
+	unsigned char val = *(unsigned char *)ptr;
+	GET_BITFIELD(val, size);
+	return PyInt_FromLong(val);
+}
+
+static PyObject *
+h_set(void *ptr, PyObject *value, unsigned size)
+{
+	long val;
+	short x;
+	if (get_long(value, &val) < 0)
+		return NULL;
+	memcpy(&x, ptr, sizeof(x));
+	x = SET(x, (short)val, size);
+	memcpy(ptr, &x, sizeof(x));
+	_RET(value);
+}
+
+
+static PyObject *
+h_set_sw(void *ptr, PyObject *value, unsigned size)
+{
+	long val;
+	short field;
+	if (get_long(value, &val) < 0)
+		return NULL;
+	memcpy(&field, ptr, sizeof(field));
+	field = SWAP_2(field);
+	field = SET(field, (short)val, size);
+	field = SWAP_2(field);
+	memcpy(ptr, &field, sizeof(field));
+	_RET(value);
+}
+
+static PyObject *
+h_get(void *ptr, unsigned size)
+{
+	short val;
+	memcpy(&val, ptr, sizeof(val));
+	GET_BITFIELD(val, size);
+	return PyInt_FromLong((long)val);
+}
+
+static PyObject *
+h_get_sw(void *ptr, unsigned size)
+{
+	short val;
+	memcpy(&val, ptr, sizeof(val));
+	val = SWAP_2(val);
+	GET_BITFIELD(val, size);
+	return PyInt_FromLong(val);
+}
+
+static PyObject *
+H_set(void *ptr, PyObject *value, unsigned size)
+{
+	unsigned long val;
+	unsigned short x;
+	if (get_ulong(value, &val) < 0)
+		return NULL;
+	memcpy(&x, ptr, sizeof(x));
+	x = SET(x, (unsigned short)val, size);
+	memcpy(ptr, &x, sizeof(x));
+	_RET(value);
+}
+
+static PyObject *
+H_set_sw(void *ptr, PyObject *value, unsigned size)
+{
+	unsigned long val;
+	unsigned short field;
+	if (get_ulong(value, &val) < 0)
+		return NULL;
+	memcpy(&field, ptr, sizeof(field));
+	field = SWAP_2(field);
+	field = SET(field, (unsigned short)val, size);
+	field = SWAP_2(field);
+	memcpy(ptr, &field, sizeof(field));
+	_RET(value);
+}
+
+
+static PyObject *
+H_get(void *ptr, unsigned size)
+{
+	unsigned short val;
+	memcpy(&val, ptr, sizeof(val));
+	GET_BITFIELD(val, size);
+	return PyInt_FromLong(val);
+}
+
+static PyObject *
+H_get_sw(void *ptr, unsigned size)
+{
+	unsigned short val;
+	memcpy(&val, ptr, sizeof(val));
+	val = SWAP_2(val);
+	GET_BITFIELD(val, size);
+	return PyInt_FromLong(val);
+}
+
+static PyObject *
+i_set(void *ptr, PyObject *value, unsigned size)
+{
+	long val;
+	int x;
+	if (get_long(value, &val) < 0)
+		return NULL;
+	memcpy(&x, ptr, sizeof(x));
+	x = SET(x, (int)val, size);
+	memcpy(ptr, &x, sizeof(x));
+	_RET(value);
+}
+
+static PyObject *
+i_set_sw(void *ptr, PyObject *value, unsigned size)
+{
+	long val;
+	int field;
+	if (get_long(value, &val) < 0)
+		return NULL;
+	memcpy(&field, ptr, sizeof(field));
+	field = SWAP_INT(field);
+	field = SET(field, (int)val, size);
+	field = SWAP_INT(field);
+	memcpy(ptr, &field, sizeof(field));
+	_RET(value);
+}
+
+
+static PyObject *
+i_get(void *ptr, unsigned size)
+{
+	int val;
+	memcpy(&val, ptr, sizeof(val));
+	GET_BITFIELD(val, size);
+	return PyInt_FromLong(val);
+}
+
+static PyObject *
+i_get_sw(void *ptr, unsigned size)
+{
+	int val;
+	memcpy(&val, ptr, sizeof(val));
+	val = SWAP_INT(val);
+	GET_BITFIELD(val, size);
+	return PyInt_FromLong(val);
+}
+
+#ifdef MS_WIN32
+/* short BOOL - VARIANT_BOOL */
+static PyObject *
+vBOOL_set(void *ptr, PyObject *value, unsigned size)
+{
+	switch (PyObject_IsTrue(value)) {
+	case -1:
+		return NULL;
+	case 0:
+		*(short int *)ptr = VARIANT_FALSE;
+		_RET(value);
+	default:
+		*(short int *)ptr = VARIANT_TRUE;
+		_RET(value);
+	}
+}
+
+static PyObject *
+vBOOL_get(void *ptr, unsigned size)
+{
+	return PyBool_FromLong((long)*(short int *)ptr);
+}
+#endif
+
+static PyObject *
+I_set(void *ptr, PyObject *value, unsigned size)
+{
+	unsigned long val;
+	unsigned int x;
+	if (get_ulong(value, &val) < 0)
+		return  NULL;
+	memcpy(&x, ptr, sizeof(x));
+	x = SET(x, (unsigned int)val, size);
+	memcpy(ptr, &x, sizeof(x));
+	_RET(value);
+}
+
+static PyObject *
+I_set_sw(void *ptr, PyObject *value, unsigned size)
+{
+	unsigned long val;
+	unsigned int field;
+	if (get_ulong(value, &val) < 0)
+		return  NULL;
+	memcpy(&field, ptr, sizeof(field));
+	field = (unsigned int)SET(field, (unsigned int)val, size);
+	field = SWAP_INT(field);
+	memcpy(ptr, &field, sizeof(field));
+	_RET(value);
+}
+
+
+static PyObject *
+I_get(void *ptr, unsigned size)
+{
+	unsigned int val;
+	memcpy(&val, ptr, sizeof(val));
+	GET_BITFIELD(val, size);
+	return PyLong_FromUnsignedLong(val);
+}
+
+static PyObject *
+I_get_sw(void *ptr, unsigned size)
+{
+	unsigned int val;
+	memcpy(&val, ptr, sizeof(val));
+	val = SWAP_INT(val);
+	GET_BITFIELD(val, size);
+	return PyLong_FromUnsignedLong(val);
+}
+
+static PyObject *
+l_set(void *ptr, PyObject *value, unsigned size)
+{
+	long val;
+	long x;
+	if (get_long(value, &val) < 0)
+		return NULL;
+	memcpy(&x, ptr, sizeof(x));
+	x = SET(x, val, size);
+	memcpy(ptr, &x, sizeof(x));
+	_RET(value);
+}
+
+static PyObject *
+l_set_sw(void *ptr, PyObject *value, unsigned size)
+{
+	long val;
+	long field;
+	if (get_long(value, &val) < 0)
+		return NULL;
+	memcpy(&field, ptr, sizeof(field));
+	field = SWAP_LONG(field);
+	field = (long)SET(field, val, size);
+	field = SWAP_LONG(field);
+	memcpy(ptr, &field, sizeof(field));
+	_RET(value);
+}
+
+
+static PyObject *
+l_get(void *ptr, unsigned size)
+{
+	long val;
+	memcpy(&val, ptr, sizeof(val));
+	GET_BITFIELD(val, size);
+	return PyInt_FromLong(val);
+}
+
+static PyObject *
+l_get_sw(void *ptr, unsigned size)
+{
+	long val;
+	memcpy(&val, ptr, sizeof(val));
+	val = SWAP_LONG(val);
+	GET_BITFIELD(val, size);
+	return PyInt_FromLong(val);
+}
+
+static PyObject *
+L_set(void *ptr, PyObject *value, unsigned size)
+{
+	unsigned long val;
+	unsigned long x;
+	if (get_ulong(value, &val) < 0)
+		return  NULL;
+	memcpy(&x, ptr, sizeof(x));
+	x = SET(x, val, size);
+	memcpy(ptr, &x, sizeof(x));
+	_RET(value);
+}
+
+static PyObject *
+L_set_sw(void *ptr, PyObject *value, unsigned size)
+{
+	unsigned long val;
+	unsigned long field;
+	if (get_ulong(value, &val) < 0)
+		return  NULL;
+	memcpy(&field, ptr, sizeof(field));
+	field = SWAP_LONG(field);
+	field = (unsigned long)SET(field, val, size);
+	field = SWAP_LONG(field);
+	memcpy(ptr, &field, sizeof(field));
+	_RET(value);
+}
+
+
+static PyObject *
+L_get(void *ptr, unsigned size)
+{
+	unsigned long val;
+	memcpy(&val, ptr, sizeof(val));
+	GET_BITFIELD(val, size);
+	return PyLong_FromUnsignedLong(val);
+}
+
+static PyObject *
+L_get_sw(void *ptr, unsigned size)
+{
+	unsigned long val;
+	memcpy(&val, ptr, sizeof(val));
+	val = SWAP_LONG(val);
+	GET_BITFIELD(val, size);
+	return PyLong_FromUnsignedLong(val);
+}
+
+#ifdef HAVE_LONG_LONG
+static PyObject *
+q_set(void *ptr, PyObject *value, unsigned size)
+{
+	PY_LONG_LONG val;
+	PY_LONG_LONG x;
+	if (get_longlong(value, &val) < 0)
+		return NULL;
+	memcpy(&x, ptr, sizeof(x));
+	x = SET(x, val, size);
+	memcpy(ptr, &x, sizeof(x));
+	_RET(value);
+}
+
+static PyObject *
+q_set_sw(void *ptr, PyObject *value, unsigned size)
+{
+	PY_LONG_LONG val;
+	PY_LONG_LONG field;
+	if (get_longlong(value, &val) < 0)
+		return NULL;
+	memcpy(&field, ptr, sizeof(field));
+	field = SWAP_8(field);
+	field = (PY_LONG_LONG)SET(field, val, size);
+	field = SWAP_8(field);
+	memcpy(ptr, &field, sizeof(field));
+	_RET(value);
+}
+
+static PyObject *
+q_get(void *ptr, unsigned size)
+{
+	PY_LONG_LONG val;
+	memcpy(&val, ptr, sizeof(val));
+	GET_BITFIELD(val, size);
+	return PyLong_FromLongLong(val);
+}
+
+static PyObject *
+q_get_sw(void *ptr, unsigned size)
+{
+	PY_LONG_LONG val;
+	memcpy(&val, ptr, sizeof(val));
+	val = SWAP_8(val);
+	GET_BITFIELD(val, size);
+	return PyLong_FromLongLong(val);
+}
+
+static PyObject *
+Q_set(void *ptr, PyObject *value, unsigned size)
+{
+	unsigned PY_LONG_LONG val;
+	unsigned PY_LONG_LONG x;
+	if (get_ulonglong(value, &val) < 0)
+		return NULL;
+	memcpy(&x, ptr, sizeof(x));
+	x = SET(x, val, size);
+	memcpy(ptr, &x, sizeof(x));
+	_RET(value);
+}
+
+static PyObject *
+Q_set_sw(void *ptr, PyObject *value, unsigned size)
+{
+	unsigned PY_LONG_LONG val;
+	unsigned PY_LONG_LONG field;
+	if (get_ulonglong(value, &val) < 0)
+		return NULL;
+	memcpy(&field, ptr, sizeof(field));
+	field = SWAP_8(field);
+	field = (unsigned PY_LONG_LONG)SET(field, val, size);
+	field = SWAP_8(field);
+	memcpy(ptr, &field, sizeof(field));
+	_RET(value);
+}
+
+static PyObject *
+Q_get(void *ptr, unsigned size)
+{
+	unsigned PY_LONG_LONG val;
+	memcpy(&val, ptr, sizeof(val));
+	GET_BITFIELD(val, size);
+	return PyLong_FromUnsignedLongLong(val);
+}
+
+static PyObject *
+Q_get_sw(void *ptr, unsigned size)
+{
+	unsigned PY_LONG_LONG val;
+	memcpy(&val, ptr, sizeof(val));
+	val = SWAP_8(val);
+	GET_BITFIELD(val, size);
+	return PyLong_FromUnsignedLongLong(val);
+}
+#endif
+
+/*****************************************************************
+ * non-integer accessor methods, not supporting bit fields
+ */
+
+
+
+static PyObject *
+d_set(void *ptr, PyObject *value, unsigned size)
+{
+	double x;
+
+	x = PyFloat_AsDouble(value);
+	if (x == -1 && PyErr_Occurred()) {
+		PyErr_Format(PyExc_TypeError,
+			     " float expected instead of %s instance",
+			     value->ob_type->tp_name);
+		return NULL;
+	}
+	memcpy(ptr, &x, sizeof(double));
+	_RET(value);
+}
+
+static PyObject *
+d_get(void *ptr, unsigned size)
+{
+	double val;
+	memcpy(&val, ptr, sizeof(val));
+	return PyFloat_FromDouble(val);
+}
+
+static PyObject *
+d_set_sw(void *ptr, PyObject *value, unsigned size)
+{
+	double x;
+
+	x = PyFloat_AsDouble(value);
+	if (x == -1 && PyErr_Occurred()) {
+		PyErr_Format(PyExc_TypeError,
+			     " float expected instead of %s instance",
+			     value->ob_type->tp_name);
+		return NULL;
+	}
+#ifdef WORDS_BIGENDIAN
+	if (_PyFloat_Pack8(x, (unsigned char *)ptr, 1))
+		return NULL;
+#else
+	if (_PyFloat_Pack8(x, (unsigned char *)ptr, 0))
+		return NULL;
+#endif
+	_RET(value);
+}
+
+static PyObject *
+d_get_sw(void *ptr, unsigned size)
+{
+#ifdef WORDS_BIGENDIAN
+	return PyFloat_FromDouble(_PyFloat_Unpack8(ptr, 1));
+#else
+	return PyFloat_FromDouble(_PyFloat_Unpack8(ptr, 0));
+#endif
+}
+
+static PyObject *
+f_set(void *ptr, PyObject *value, unsigned size)
+{
+	float x;
+
+	x = (float)PyFloat_AsDouble(value);
+	if (x == -1 && PyErr_Occurred()) {
+		PyErr_Format(PyExc_TypeError,
+			     " float expected instead of %s instance",
+			     value->ob_type->tp_name);
+		return NULL;
+	}
+	memcpy(ptr, &x, sizeof(x));
+	_RET(value);
+}
+
+static PyObject *
+f_get(void *ptr, unsigned size)
+{
+	float val;
+	memcpy(&val, ptr, sizeof(val));
+	return PyFloat_FromDouble(val);
+}
+
+static PyObject *
+f_set_sw(void *ptr, PyObject *value, unsigned size)
+{
+	float x;
+
+	x = (float)PyFloat_AsDouble(value);
+	if (x == -1 && PyErr_Occurred()) {
+		PyErr_Format(PyExc_TypeError,
+			     " float expected instead of %s instance",
+			     value->ob_type->tp_name);
+		return NULL;
+	}
+#ifdef WORDS_BIGENDIAN
+	if (_PyFloat_Pack4(x, (unsigned char *)ptr, 1))
+		return NULL;
+#else
+	if (_PyFloat_Pack4(x, (unsigned char *)ptr, 0))
+		return NULL;
+#endif
+	_RET(value);
+}
+
+static PyObject *
+f_get_sw(void *ptr, unsigned size)
+{
+#ifdef WORDS_BIGENDIAN
+	return PyFloat_FromDouble(_PyFloat_Unpack4(ptr, 1));
+#else
+	return PyFloat_FromDouble(_PyFloat_Unpack4(ptr, 0));
+#endif
+}
+
+/*
+  py_object refcounts:
+
+  1. If we have a py_object instance, O_get must Py_INCREF the returned
+  object, of course.  If O_get is called from a function result, no py_object
+  instance is created - so callproc.c::GetResult has to call Py_DECREF.
+
+  2. The memory block in py_object owns a refcount.  So, py_object must call
+  Py_DECREF on destruction.  Maybe only when b_needsfree is non-zero.
+*/
+static PyObject *
+O_get(void *ptr, unsigned size)
+{
+	PyObject *ob = *(PyObject **)ptr;
+	if (ob == NULL) {
+		if (!PyErr_Occurred())
+			/* Set an error if not yet set */
+			PyErr_SetString(PyExc_ValueError,
+					"PyObject is NULL");
+		return NULL;
+	}
+	Py_INCREF(ob);
+	return ob;
+}
+
+static PyObject *
+O_set(void *ptr, PyObject *value, unsigned size)
+{
+	/* Hm, does the memory block need it's own refcount or not? */
+	*(PyObject **)ptr = value;
+	Py_INCREF(value);
+	return value;
+}
+
+
+static PyObject *
+c_set(void *ptr, PyObject *value, unsigned size)
+{
+	if (!PyString_Check(value) || (1 != PyString_Size(value))) {
+		PyErr_Format(PyExc_TypeError,
+			     "one character string expected");
+		return NULL;
+	}
+	*(char *)ptr = PyString_AS_STRING(value)[0];
+	_RET(value);
+}
+
+
+static PyObject *
+c_get(void *ptr, unsigned size)
+{
+	return PyString_FromStringAndSize((char *)ptr, 1);
+}
+
+#ifdef CTYPES_UNICODE
+/* u - a single wchar_t character */
+static PyObject *
+u_set(void *ptr, PyObject *value, unsigned size)
+{
+	int len;
+
+	if (PyString_Check(value)) {
+		value = PyUnicode_FromEncodedObject(value,
+						    conversion_mode_encoding,
+						    conversion_mode_errors);
+		if (!value)
+			return NULL;
+	} else if (!PyUnicode_Check(value)) {
+		PyErr_Format(PyExc_TypeError,
+				"unicode string expected instead of %s instance",
+				value->ob_type->tp_name);
+		return NULL;
+	} else
+		Py_INCREF(value);
+
+	len = PyUnicode_GET_SIZE(value);
+	if (len != 1) {
+		Py_DECREF(value);
+		PyErr_SetString(PyExc_TypeError,
+				"one character unicode string expected");
+		return NULL;
+	}
+
+	*(wchar_t *)ptr = PyUnicode_AS_UNICODE(value)[0];
+	Py_DECREF(value);
+
+	_RET(value);
+}
+
+
+static PyObject *
+u_get(void *ptr, unsigned size)
+{
+	return PyUnicode_FromWideChar((wchar_t *)ptr, 1);
+}
+
+/* U - a unicode string */
+static PyObject *
+U_get(void *ptr, unsigned size)
+{
+	PyObject *result;
+	unsigned int len;
+	Py_UNICODE *p;
+
+	size /= sizeof(wchar_t); /* we count character units here, not bytes */
+
+	result = PyUnicode_FromWideChar((wchar_t *)ptr, size);
+	if (!result)
+		return NULL;
+	/* We need 'result' to be able to count the characters with wcslen,
+	   since ptr may not be NUL terminated.  If the length is smaller (if
+	   it was actually NUL terminated, we construct a new one and throw
+	   away the result.
+	*/
+	/* chop off at the first NUL character, if any. */
+	p = PyUnicode_AS_UNICODE(result);
+	for (len = 0; len < size; ++len)
+		if (!p[len])
+			break;
+
+	if (len < size) {
+		PyObject *ob = PyUnicode_FromWideChar((wchar_t *)ptr, len);
+		Py_DECREF(result);
+		return ob;
+	}
+	return result;
+}
+
+static PyObject *
+U_set(void *ptr, PyObject *value, unsigned length)
+{
+	unsigned int size;
+
+	/* It's easier to calculate in characters than in bytes */
+	length /= sizeof(wchar_t);
+
+	if (PyString_Check(value)) {
+		value = PyUnicode_FromEncodedObject(value,
+						    conversion_mode_encoding,
+						    conversion_mode_errors);
+		if (!value)
+			return NULL;
+	} else if (!PyUnicode_Check(value)) {
+		PyErr_Format(PyExc_TypeError,
+				"unicode string expected instead of %s instance",
+				value->ob_type->tp_name);
+		return NULL;
+	} else
+		Py_INCREF(value);
+	size = PyUnicode_GET_SIZE(value);
+	if (size > length) {
+		PyErr_Format(PyExc_ValueError,
+			     "string too long (%d, maximum length %d)",
+			     size, length);
+		Py_DECREF(value);
+		return NULL;
+	} else if (size < length-1)
+		/* copy terminating NUL character if there is space */
+		size += 1;
+	PyUnicode_AsWideChar((PyUnicodeObject *)value, (wchar_t *)ptr, size);
+	return value;
+}
+
+#endif
+
+static PyObject *
+s_get(void *ptr, unsigned size)
+{
+	PyObject *result;
+
+	result = PyString_FromString((char *)ptr);
+	if (!result)
+		return NULL;
+	/* chop off at the first NUL character, if any.
+	 * On error, result will be deallocated and set to NULL.
+	 */
+	size = min(size, strlen(PyString_AS_STRING(result)));
+	if (result->ob_refcnt == 1) {
+		/* shorten the result */
+		_PyString_Resize(&result, size);
+		return result;
+	} else
+		/* cannot shorten the result */
+		return PyString_FromStringAndSize(ptr, size);
+}
+
+static PyObject *
+s_set(void *ptr, PyObject *value, unsigned length)
+{
+	char *data;
+	unsigned size;
+
+	data = PyString_AsString(value);
+	if (!data)
+		return NULL;
+	size = strlen(data);
+	if (size < length) {
+		/* This will copy the leading NUL character
+		 * if there is space for it.
+		 */
+		++size;
+	} else if (size > length) {
+		PyErr_Format(PyExc_ValueError,
+			     "string too long (%d, maximum length %d)",
+			     size, length);
+		return NULL;
+	}
+	/* Also copy the terminating NUL character if there is space */
+	memcpy((char *)ptr, data, size);
+	_RET(value);
+}
+
+static PyObject *
+z_set(void *ptr, PyObject *value, unsigned size)
+{
+	if (value == Py_None) {
+		*(char **)ptr = NULL;
+		Py_INCREF(value);
+		return value;
+	}
+	if (PyString_Check(value)) {
+		*(char **)ptr = PyString_AS_STRING(value);
+		Py_INCREF(value);
+		return value;
+	} else if (PyUnicode_Check(value)) {
+		PyObject *str = PyUnicode_AsEncodedString(value,
+							  conversion_mode_encoding,
+							  conversion_mode_errors);
+		if (str == NULL)
+			return NULL;
+		*(char **)ptr = PyString_AS_STRING(str);
+		return str;
+	} else if (PyInt_Check(value) || PyLong_Check(value)) {
+		*(char **)ptr = (char *)PyInt_AsUnsignedLongMask(value);
+		_RET(value);
+	}
+	PyErr_Format(PyExc_TypeError,
+		     "string or integer address expected instead of %s instance",
+		     value->ob_type->tp_name);
+	return NULL;
+}
+
+static PyObject *
+z_get(void *ptr, unsigned size)
+{
+	/* XXX What about invalid pointers ??? */
+	if (*(void **)ptr) {
+#if defined(MS_WIN32) && !defined(_WIN32_WCE)
+		if (IsBadStringPtrA(*(char **)ptr, -1)) {
+			PyErr_Format(PyExc_ValueError,
+				     "invalid string pointer %p",
+				     ptr);
+			return NULL;
+		}
+#endif
+		return PyString_FromString(*(char **)ptr);
+	} else {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+}
+
+#ifdef CTYPES_UNICODE
+static PyObject *
+Z_set(void *ptr, PyObject *value, unsigned size)
+{
+	if (value == Py_None) {
+		*(wchar_t **)ptr = NULL;
+		Py_INCREF(value);
+		return value;
+	}
+	if (PyString_Check(value)) {
+		value = PyUnicode_FromEncodedObject(value,
+						    conversion_mode_encoding,
+						    conversion_mode_errors);
+		if (!value)
+			return NULL;
+	} else if (PyInt_Check(value) || PyLong_Check(value)) {
+		*(wchar_t **)ptr = (wchar_t *)PyInt_AsUnsignedLongMask(value);
+		Py_INCREF(Py_None);
+		return Py_None;
+	} else if (!PyUnicode_Check(value)) {
+		PyErr_Format(PyExc_TypeError,
+			     "unicode string or integer address expected instead of %s instance",
+			     value->ob_type->tp_name);
+		return NULL;
+	} else
+		Py_INCREF(value);
+#ifdef HAVE_USABLE_WCHAR_T
+	/* HAVE_USABLE_WCHAR_T means that Py_UNICODE and wchar_t is the same
+	   type.  So we can copy directly.  Hm, are unicode objects always NUL
+	   terminated in Python, internally?
+	 */
+	*(wchar_t **)ptr = PyUnicode_AS_UNICODE(value);
+	return value;
+#else
+	{
+		/* We must create a wchar_t* buffer from the unicode object,
+		   and keep it alive */
+		PyObject *keep;
+		wchar_t *buffer;
+
+		int size = PyUnicode_GET_SIZE(value);
+		size += 1; /* terminating NUL */
+		size *= sizeof(wchar_t);
+		buffer = (wchar_t *)PyMem_Malloc(size);
+		if (!buffer)
+			return NULL;
+		memset(buffer, 0, size);
+		keep = PyCObject_FromVoidPtr(buffer, PyMem_Free);
+		if (!keep) {
+			PyMem_Free(buffer);
+			return NULL;
+		}
+		*(wchar_t **)ptr = (wchar_t *)buffer;
+		if (-1 == PyUnicode_AsWideChar((PyUnicodeObject *)value,
+					       buffer, PyUnicode_GET_SIZE(value))) {
+			Py_DECREF(value);
+			Py_DECREF(keep);
+			return NULL;
+		}
+		Py_DECREF(value);
+		return keep;
+	}
+#endif
+}
+
+static PyObject *
+Z_get(void *ptr, unsigned size)
+{
+	wchar_t *p;
+	p = *(wchar_t **)ptr;
+	if (p)
+		return PyUnicode_FromWideChar(p, wcslen(p));
+	else {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+}
+#endif
+
+#ifdef MS_WIN32
+static PyObject *
+BSTR_set(void *ptr, PyObject *value, unsigned size)
+{
+	BSTR bstr;
+
+	/* convert value into a PyUnicodeObject or NULL */
+	if (Py_None == value) {
+		value = NULL;
+	} else if (PyString_Check(value)) {
+		value = PyUnicode_FromEncodedObject(value,
+						    conversion_mode_encoding,
+						    conversion_mode_errors);
+		if (!value)
+			return NULL;
+	} else if (PyUnicode_Check(value)) {
+		Py_INCREF(value); /* for the descref below */
+	} else {
+		PyErr_Format(PyExc_TypeError,
+				"unicode string expected instead of %s instance",
+				value->ob_type->tp_name);
+		return NULL;
+	}
+
+	/* create a BSTR from value */
+	if (value) {
+		bstr = SysAllocStringLen(PyUnicode_AS_UNICODE(value),
+					 PyUnicode_GET_SIZE(value));
+		Py_DECREF(value);
+	} else
+		bstr = NULL;
+
+	/* free the previous contents, if any */
+	if (*(BSTR *)ptr)
+		SysFreeString(*(BSTR *)ptr);
+	
+	/* and store it */
+	*(BSTR *)ptr = bstr;
+
+	/* We don't need to keep any other object */
+	_RET(value);
+}
+
+
+static PyObject *
+BSTR_get(void *ptr, unsigned size)
+{
+	BSTR p;
+	p = *(BSTR *)ptr;
+	if (p)
+		return PyUnicode_FromWideChar(p, SysStringLen(p));
+	else {
+		/* Hm, it seems NULL pointer and zero length string are the
+		   same in BSTR, see Don Box, p 81
+		*/
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+}
+#endif
+
+static PyObject *
+P_set(void *ptr, PyObject *value, unsigned size)
+{
+	void *v;
+	if (value == Py_None) {
+		*(void **)ptr = NULL;
+		_RET(value);
+	}
+
+	if (!PyInt_Check(value) && !PyLong_Check(value)) {
+		PyErr_SetString(PyExc_TypeError,
+				"cannot be converted to pointer");
+		return NULL;
+	}
+
+#if SIZEOF_VOID_P <= SIZEOF_LONG
+	v = (void *)PyInt_AsUnsignedLongMask(value);
+#else
+#ifndef HAVE_LONG_LONG
+#   error "PyLong_AsVoidPtr: sizeof(void*) > sizeof(long), but no long long"
+#elif SIZEOF_LONG_LONG < SIZEOF_VOID_P
+#   error "PyLong_AsVoidPtr: sizeof(PY_LONG_LONG) < sizeof(void*)"
+#endif
+	v = (void *)PyInt_AsUnsignedLongLongMask(value);
+#endif
+
+	if (PyErr_Occurred())
+		return NULL;
+
+	*(void **)ptr = v;
+	_RET(value);
+}
+
+static PyObject *
+P_get(void *ptr, unsigned size)
+{
+	if (*(void **)ptr == NULL) {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+	return PyLong_FromVoidPtr(*(void **)ptr);
+}
+
+static struct fielddesc formattable[] = {
+	{ 's', s_set, s_get, &ffi_type_pointer},
+	{ 'b', b_set, b_get, &ffi_type_schar},
+	{ 'B', B_set, B_get, &ffi_type_uchar},
+	{ 'c', c_set, c_get, &ffi_type_schar},
+	{ 'd', d_set, d_get, &ffi_type_double, d_set_sw, d_get_sw},
+	{ 'f', f_set, f_get, &ffi_type_float, f_set_sw, f_get_sw},
+	{ 'h', h_set, h_get, &ffi_type_sshort, h_set_sw, h_get_sw},
+	{ 'H', H_set, H_get, &ffi_type_ushort, H_set_sw, H_get_sw},
+	{ 'i', i_set, i_get, &ffi_type_sint, i_set_sw, i_get_sw},
+	{ 'I', I_set, I_get, &ffi_type_uint, I_set_sw, I_get_sw},
+/* XXX Hm, sizeof(int) == sizeof(long) doesn't hold on every platform */
+/* As soon as we can get rid of the type codes, this is no longer a problem */
+#if SIZEOF_LONG == 4
+	{ 'l', l_set, l_get, &ffi_type_sint, l_set_sw, l_get_sw},
+	{ 'L', L_set, L_get, &ffi_type_uint, L_set_sw, L_get_sw},
+#elif SIZEOF_LONG == 8
+	{ 'l', l_set, l_get, &ffi_type_slong, l_set_sw, l_get_sw},
+	{ 'L', L_set, L_get, &ffi_type_ulong, L_set_sw, L_get_sw},
+#else
+# error
+#endif
+#ifdef HAVE_LONG_LONG
+	{ 'q', q_set, q_get, &ffi_type_slong, q_set_sw, q_get_sw},
+	{ 'Q', Q_set, Q_get, &ffi_type_ulong, Q_set_sw, Q_get_sw},
+#endif
+	{ 'P', P_set, P_get, &ffi_type_pointer},
+	{ 'z', z_set, z_get, &ffi_type_pointer},
+#ifdef CTYPES_UNICODE
+	{ 'u', u_set, u_get, NULL}, /* ffi_type set later */
+	{ 'U', U_set, U_get, &ffi_type_pointer},
+	{ 'Z', Z_set, Z_get, &ffi_type_pointer},
+#endif
+#ifdef MS_WIN32
+	{ 'X', BSTR_set, BSTR_get, &ffi_type_pointer},
+	{ 'v', vBOOL_set, vBOOL_get, &ffi_type_sshort},
+#endif
+	{ 'O', O_set, O_get, &ffi_type_pointer},
+	{ 0, NULL, NULL, NULL},
+};
+
+/*
+  Ideas: Implement VARIANT in this table, using 'V' code.
+  Use '?' as code for BOOL.
+*/
+
+struct fielddesc *
+getentry(char *fmt)
+{
+	static int initialized = 0;
+	struct fielddesc *table = formattable;
+
+	if (!initialized) {
+		initialized = 1;
+#ifdef CTYPES_UNICODE
+		if (sizeof(wchar_t) == sizeof(short))
+			getentry("u")->pffi_type = &ffi_type_sshort;
+		else if (sizeof(wchar_t) == sizeof(int))
+			getentry("u")->pffi_type = &ffi_type_sint;
+		else if (sizeof(wchar_t) == sizeof(long))
+			getentry("u")->pffi_type = &ffi_type_slong;
+#endif
+	}
+
+	for (; table->code; ++table) {
+		if (table->code == fmt[0])
+			return table;
+	}
+	return NULL;
+}
+
+typedef struct { char c; char x; } s_char;
+typedef struct { char c; short x; } s_short;
+typedef struct { char c; int x; } s_int;
+typedef struct { char c; long x; } s_long;
+typedef struct { char c; float x; } s_float;
+typedef struct { char c; double x; } s_double;
+typedef struct { char c; char *x; } s_char_p;
+typedef struct { char c; void *x; } s_void_p;
+
+/*
+#define CHAR_ALIGN (sizeof(s_char) - sizeof(char))
+#define SHORT_ALIGN (sizeof(s_short) - sizeof(short))
+#define INT_ALIGN (sizeof(s_int) - sizeof(int))
+#define LONG_ALIGN (sizeof(s_long) - sizeof(long))
+*/
+#define FLOAT_ALIGN (sizeof(s_float) - sizeof(float))
+#define DOUBLE_ALIGN (sizeof(s_double) - sizeof(double))
+/* #define CHAR_P_ALIGN (sizeof(s_char_p) - sizeof(char*)) */
+#define VOID_P_ALIGN (sizeof(s_void_p) - sizeof(void*))
+
+/*
+#ifdef HAVE_USABLE_WCHAR_T
+typedef struct { char c; wchar_t x; } s_wchar;
+typedef struct { char c; wchar_t *x; } s_wchar_p;
+
+#define WCHAR_ALIGN (sizeof(s_wchar) - sizeof(wchar_t))
+#define WCHAR_P_ALIGN (sizeof(s_wchar_p) - sizeof(wchar_t*))
+#endif
+*/
+
+#ifdef HAVE_LONG_LONG
+typedef struct { char c; PY_LONG_LONG x; } s_long_long;
+#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(PY_LONG_LONG))
+#endif
+
+/* from ffi.h:
+typedef struct _ffi_type
+{
+	size_t size;
+	unsigned short alignment;
+	unsigned short type;
+	struct _ffi_type **elements;
+} ffi_type;
+*/
+
+/* align and size are bogus for void, but they must not be zero */
+ffi_type ffi_type_void = { 1, 1, FFI_TYPE_VOID };
+
+ffi_type ffi_type_uint8 = { 1, 1, FFI_TYPE_UINT8 };
+ffi_type ffi_type_sint8 = { 1, 1, FFI_TYPE_SINT8 };
+
+ffi_type ffi_type_uint16 = { 2, 2, FFI_TYPE_UINT16 };
+ffi_type ffi_type_sint16 = { 2, 2, FFI_TYPE_SINT16 };
+
+ffi_type ffi_type_uint32 = { 4, 4, FFI_TYPE_UINT32 };
+ffi_type ffi_type_sint32 = { 4, 4, FFI_TYPE_SINT32 };
+
+ffi_type ffi_type_uint64 = { 8, LONG_LONG_ALIGN, FFI_TYPE_UINT64 };
+ffi_type ffi_type_sint64 = { 8, LONG_LONG_ALIGN, FFI_TYPE_SINT64 };
+
+ffi_type ffi_type_float = { sizeof(float), FLOAT_ALIGN, FFI_TYPE_FLOAT };
+ffi_type ffi_type_double = { sizeof(double), DOUBLE_ALIGN, FFI_TYPE_DOUBLE };
+
+/* ffi_type ffi_type_longdouble */
+
+ffi_type ffi_type_pointer = { sizeof(void *), VOID_P_ALIGN, FFI_TYPE_POINTER };
+
+/*---------------- EOF ----------------*/

Added: vendor/Python/current/Modules/_ctypes/ctypes.h
===================================================================
--- vendor/Python/current/Modules/_ctypes/ctypes.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/ctypes.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,407 @@
+/*****************************************************************
+  This file should be kept compatible with Python 2.3, see PEP 291.
+ *****************************************************************/
+
+#if (PY_VERSION_HEX < 0x02050000)
+typedef int Py_ssize_t;
+#endif
+
+#ifndef MS_WIN32
+#define max(a, b) ((a) > (b) ? (a) : (b))
+#define min(a, b) ((a) < (b) ? (a) : (b))
+
+#define PARAMFLAG_FIN 0x1
+#define PARAMFLAG_FOUT 0x2
+#define PARAMFLAG_FLCID 0x4
+#endif
+
+/*
+  Backwards compatibility:
+  Python2.2 used LONG_LONG instead of PY_LONG_LONG
+*/
+#if defined(HAVE_LONG_LONG) && !defined(PY_LONG_LONG)
+#define PY_LONG_LONG LONG_LONG
+#endif
+
+typedef struct tagPyCArgObject PyCArgObject;
+typedef struct tagCDataObject CDataObject;
+typedef PyObject *(* GETFUNC)(void *, unsigned size);
+typedef PyObject *(* SETFUNC)(void *, PyObject *value, unsigned size);
+typedef PyCArgObject *(* PARAMFUNC)(CDataObject *obj);
+
+/* A default buffer in CDataObject, which can be used for small C types.  If
+this buffer is too small, PyMem_Malloc will be called to create a larger one,
+and this one is not used.
+
+Making CDataObject a variable size object would be a better solution, but more
+difficult in the presence of CFuncPtrObject.  Maybe later.
+*/
+union value {
+		char c[16];
+		short s;
+		int i;
+		long l;
+		float f;
+		double d;
+#ifdef HAVE_LONG_LONG
+		PY_LONG_LONG ll;
+#endif
+};
+
+/*
+  Hm. Are there CDataObject's which do not need the b_objects member?  In
+  this case we probably should introduce b_flags to mark it as present...  If
+  b_objects is not present/unused b_length is unneeded as well.
+*/
+
+struct tagCDataObject {
+	PyObject_HEAD
+	char *b_ptr;		/* pointer to memory block */
+	int  b_needsfree;	/* need _we_ free the memory? */
+	CDataObject *b_base;	/* pointer to base object or NULL */
+	Py_ssize_t b_size;	/* size of memory block in bytes */
+	Py_ssize_t b_length;	/* number of references we need */
+	Py_ssize_t b_index;	/* index of this object into base's
+				   b_object list */
+	PyObject *b_objects;	/* dictionary of references we need to keep, or Py_None */
+	union value b_value;
+};
+
+typedef struct {
+	ffi_closure *pcl; /* the C callable */
+	ffi_cif cif;
+	PyObject *converters;
+	PyObject *callable;
+	SETFUNC setfunc;
+	ffi_type *restype;
+	ffi_type *atypes[0];
+} ffi_info;
+
+typedef struct {
+	/* First part identical to tagCDataObject */
+	PyObject_HEAD
+	char *b_ptr;		/* pointer to memory block */
+	int  b_needsfree;	/* need _we_ free the memory? */
+	CDataObject *b_base;	/* pointer to base object or NULL */
+	Py_ssize_t b_size;	/* size of memory block in bytes */
+	Py_ssize_t b_length;	/* number of references we need */
+	Py_ssize_t b_index;	/* index of this object into base's
+				   b_object list */
+	PyObject *b_objects;	/* list of references we need to keep */
+	union value b_value;
+	/* end of tagCDataObject, additional fields follow */
+
+	ffi_info *thunk;
+	PyObject *callable;
+
+	/* These two fields will override the ones in the type's stgdict if
+	   they are set */
+	PyObject *converters;
+	PyObject *argtypes;
+	PyObject *restype;
+	PyObject *checker;
+	PyObject *errcheck;
+#ifdef MS_WIN32
+	int index;
+	GUID *iid;
+#endif
+	PyObject *paramflags;
+} CFuncPtrObject;
+
+extern PyTypeObject StgDict_Type;
+#define StgDict_CheckExact(v)	    ((v)->ob_type == &StgDict_Type)
+#define StgDict_Check(v)	    PyObject_TypeCheck(v, &StgDict_Type)
+
+extern int StructUnionType_update_stgdict(PyObject *fields, PyObject *type, int isStruct);
+extern int PyType_stginfo(PyTypeObject *self, Py_ssize_t *psize, Py_ssize_t *palign, Py_ssize_t *plength);
+extern int PyObject_stginfo(PyObject *self, Py_ssize_t *psize, Py_ssize_t *palign, Py_ssize_t *plength);
+
+
+
+extern PyTypeObject CData_Type;
+#define CDataObject_CheckExact(v)	((v)->ob_type == &CData_Type)
+#define CDataObject_Check(v)		PyObject_TypeCheck(v, &CData_Type)
+
+extern PyTypeObject SimpleType_Type;
+#define SimpleTypeObject_CheckExact(v)	((v)->ob_type == &SimpleType_Type)
+#define SimpleTypeObject_Check(v)	PyObject_TypeCheck(v, &SimpleType_Type)
+
+extern PyTypeObject CField_Type;
+extern struct fielddesc *getentry(char *fmt);
+
+
+extern PyObject *
+CField_FromDesc(PyObject *desc, int index,
+		int *pfield_size, int bitsize, int *pbitofs,
+		int *psize, int *poffset, int *palign,
+		int pack, int is_big_endian);
+
+extern PyObject *CData_AtAddress(PyObject *type, void *buf);
+extern PyObject *CData_FromBytes(PyObject *type, char *data, Py_ssize_t length);
+
+extern PyTypeObject ArrayType_Type;
+extern PyTypeObject Array_Type;
+extern PyTypeObject PointerType_Type;
+extern PyTypeObject Pointer_Type;
+extern PyTypeObject CFuncPtr_Type;
+extern PyTypeObject CFuncPtrType_Type;
+extern PyTypeObject StructType_Type;
+
+#define ArrayTypeObject_Check(v)	PyObject_TypeCheck(v, &ArrayType_Type)
+#define ArrayObject_Check(v)		PyObject_TypeCheck(v, &Array_Type)
+#define PointerObject_Check(v)		PyObject_TypeCheck(v, &Pointer_Type)
+#define PointerTypeObject_Check(v)	PyObject_TypeCheck(v, &PointerType_Type)
+#define CFuncPtrObject_Check(v)		PyObject_TypeCheck(v, &CFuncPtr_Type)
+#define CFuncPtrTypeObject_Check(v)	PyObject_TypeCheck(v, &CFuncPtrType_Type)
+#define StructTypeObject_Check(v)	PyObject_TypeCheck(v, &StructType_Type)
+
+extern PyObject *
+CreateArrayType(PyObject *itemtype, Py_ssize_t length);
+
+extern void init_callbacks_in_module(PyObject *m);
+
+extern PyMethodDef module_methods[];
+
+extern ffi_info *AllocFunctionCallback(PyObject *callable,
+				       PyObject *converters,
+				       PyObject *restype,
+				       int stdcall);
+/* a table entry describing a predefined ctypes type */
+struct fielddesc {
+	char code;
+	SETFUNC setfunc;
+	GETFUNC getfunc;
+	ffi_type *pffi_type; /* always statically allocated */
+	SETFUNC setfunc_swapped;
+	GETFUNC getfunc_swapped;
+};
+
+typedef struct {
+	PyObject_HEAD
+	Py_ssize_t offset;
+	Py_ssize_t size;
+	Py_ssize_t index;		/* Index into CDataObject's
+					   object array */
+	PyObject *proto;		/* a type or NULL */
+	GETFUNC getfunc;		/* getter function if proto is NULL */
+	SETFUNC setfunc;		/* setter function if proto is NULL */
+	int anonymous;
+} CFieldObject;
+
+/* A subclass of PyDictObject, used as the instance dictionary of ctypes
+   metatypes */
+typedef struct {
+	PyDictObject dict;	/* first part identical to PyDictObject */
+/* The size and align fields are unneeded, they are in ffi_type as well.  As
+   an experiment shows, it's trivial to get rid of them, the only thing to
+   remember is that in ArrayType_new the ffi_type fields must be filled in -
+   so far it was unneeded because libffi doesn't support arrays at all
+   (because they are passed as pointers to function calls anyway).  But it's
+   too much risk to change that now, and there are other fields which doen't
+   belong into this structure anyway.  Maybe in ctypes 2.0... (ctypes 2000?)
+*/
+	Py_ssize_t size;	/* number of bytes */
+	Py_ssize_t align;	/* alignment requirements */
+	Py_ssize_t length;	/* number of fields */
+	ffi_type ffi_type_pointer;
+	PyObject *proto;	/* Only for Pointer/ArrayObject */
+	SETFUNC setfunc;	/* Only for simple objects */
+	GETFUNC getfunc;	/* Only for simple objects */
+	PARAMFUNC paramfunc;
+
+	/* Following fields only used by CFuncPtrType_Type instances */
+	PyObject *argtypes;	/* tuple of CDataObjects */
+	PyObject *converters;	/* tuple([t.from_param for t in argtypes]) */
+	PyObject *restype;	/* CDataObject or NULL */
+	PyObject *checker;
+	int flags;		/* calling convention and such */
+} StgDictObject;
+
+/****************************************************************
+ StgDictObject fields
+
+ setfunc and getfunc is only set for simple data types, it is copied from the
+ corresponding fielddesc entry.  These are functions to set and get the value
+ in a memory block.
+ They should probably by used by other types as well.
+
+ proto is only used for Pointer and Array types - it points to the item type
+ object.
+
+ Probably all the magic ctypes methods (like from_param) should have C
+ callable wrappers in the StgDictObject.  For simple data type, for example,
+ the fielddesc table could have entries for C codec from_param functions or
+ other methods as well, if a subtype overrides this method in Python at
+ construction time, or assigns to it later, tp_setattro should update the
+ StgDictObject function to a generic one.
+
+ Currently, CFuncPtr types have 'converters' and 'checker' entries in their
+ type dict.  They are only used to cache attributes from other entries, whihc
+ is wrong.
+
+ One use case is the .value attribute that all simple types have.  But some
+ complex structures, like VARIANT, represent a single value also, and should
+ have this attribute.
+
+ Another use case is a _check_retval_ function, which is called when a ctypes
+ type is used as return type of a function to validate and compute the return
+ value.
+
+ Common ctypes protocol:
+
+  - setfunc: store a python value in a memory block
+  - getfunc: convert data from a memory block into a python value
+
+  - checkfunc: validate and convert a return value from a function call
+  - toparamfunc: convert a python value into a function argument
+
+*****************************************************************/
+
+/* May return NULL, but does not set an exception! */
+extern StgDictObject *PyType_stgdict(PyObject *obj);
+
+/* May return NULL, but does not set an exception! */
+extern StgDictObject *PyObject_stgdict(PyObject *self);
+
+extern int StgDict_clone(StgDictObject *src, StgDictObject *dst);
+
+typedef int(* PPROC)(void);
+
+PyObject *_CallProc(PPROC pProc,
+		    PyObject *arguments,
+#ifdef MS_WIN32
+		    IUnknown *pIUnk,
+		    GUID *iid,
+#endif
+		    int flags,
+		    PyObject *argtypes,
+		    PyObject *restype,
+		    PyObject *checker);
+ 
+
+#define FUNCFLAG_STDCALL 0x0
+#define FUNCFLAG_CDECL   0x1
+#define FUNCFLAG_HRESULT 0x2
+#define FUNCFLAG_PYTHONAPI 0x4
+
+#define DICTFLAG_FINAL 0x1000
+
+struct tagPyCArgObject {
+	PyObject_HEAD
+	ffi_type *pffi_type;
+	char tag;
+	union {
+		char c;
+		char b;
+		short h;
+		int i;
+		long l;
+#ifdef HAVE_LONG_LONG
+		PY_LONG_LONG q;
+#endif
+		double d;
+		float f;
+		void *p;
+	} value;
+	PyObject *obj;
+	int size; /* for the 'V' tag */
+};
+
+extern PyTypeObject PyCArg_Type;
+extern PyCArgObject *new_CArgObject(void);
+#define PyCArg_CheckExact(v)	    ((v)->ob_type == &PyCArg_Type)
+extern PyCArgObject *new_CArgObject(void);
+
+extern PyObject *
+CData_get(PyObject *type, GETFUNC getfunc, PyObject *src,
+	  Py_ssize_t index, Py_ssize_t size, char *ptr);
+
+extern int
+CData_set(PyObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
+	  Py_ssize_t index, Py_ssize_t size, char *ptr);
+
+extern void Extend_Error_Info(PyObject *exc_class, char *fmt, ...);
+
+struct basespec {
+	CDataObject *base;
+	Py_ssize_t index;
+	char *adr;
+};
+
+extern char basespec_string[];
+
+extern ffi_type *GetType(PyObject *obj);
+
+/* exception classes */
+extern PyObject *PyExc_ArgError;
+
+extern char *conversion_mode_encoding;
+extern char *conversion_mode_errors;
+
+/* Python 2.4 macros, which are not available in Python 2.3 */
+
+#ifndef Py_CLEAR
+#define Py_CLEAR(op)				\
+        do {                            	\
+                if (op) {			\
+                        PyObject *tmp = (PyObject *)(op);	\
+                        (op) = NULL;		\
+                        Py_DECREF(tmp);		\
+                }				\
+        } while (0)
+#endif
+
+#ifndef Py_VISIT
+/* Utility macro to help write tp_traverse functions.
+ * To use this macro, the tp_traverse function must name its arguments
+ * "visit" and "arg".  This is intended to keep tp_traverse functions
+ * looking as much alike as possible.
+ */
+#define Py_VISIT(op)					\
+        do { 						\
+                if (op) {				\
+                        int vret = visit((op), arg);	\
+                        if (vret)			\
+                                return vret;		\
+                }					\
+        } while (0)
+#endif
+
+/* Python's PyUnicode_*WideChar functions are broken ... */
+#if defined(Py_USING_UNICODE) && defined(HAVE_WCHAR_H)
+#  define CTYPES_UNICODE
+#endif
+
+
+#ifdef CTYPES_UNICODE
+#  undef PyUnicode_FromWideChar
+#  define PyUnicode_FromWideChar My_PyUnicode_FromWideChar
+
+#  undef PyUnicode_AsWideChar
+#  define PyUnicode_AsWideChar My_PyUnicode_AsWideChar
+
+extern PyObject *My_PyUnicode_FromWideChar(const wchar_t *, Py_ssize_t);
+extern int My_PyUnicode_AsWideChar(PyUnicodeObject *, wchar_t *, Py_ssize_t);
+
+#endif
+
+extern void FreeClosure(void *);
+extern void *MallocClosure(void);
+
+extern void _AddTraceback(char *, char *, int);
+
+extern PyObject *CData_FromBaseObj(PyObject *type, PyObject *base, Py_ssize_t index, char *adr);
+
+/* XXX better name needed! */
+extern int IsSimpleSubType(PyObject *obj);
+
+
+#ifdef MS_WIN32
+extern PyObject *ComError;
+#endif
+
+/*
+ Local Variables:
+ compile-command: "python setup.py -q build install --home ~"
+ End:
+*/

Added: vendor/Python/current/Modules/_ctypes/ctypes_dlfcn.h
===================================================================
--- vendor/Python/current/Modules/_ctypes/ctypes_dlfcn.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/ctypes_dlfcn.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,31 @@
+/*****************************************************************
+  This file should be kept compatible with Python 2.3, see PEP 291.
+ *****************************************************************/
+
+#ifndef _CTYPES_DLFCN_H_
+#define _CTYPES_DLFCN_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#ifndef MS_WIN32
+
+#include <dlfcn.h>
+
+#ifndef CTYPES_DARWIN_DLFCN
+
+#define ctypes_dlsym dlsym
+#define ctypes_dlerror dlerror
+#define ctypes_dlopen dlopen
+#define ctypes_dlclose dlclose
+#define ctypes_dladdr dladdr
+
+#endif /* !CTYPES_DARWIN_DLFCN */
+
+#endif /* !MS_WIN32 */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* _CTYPES_DLFCN_H_ */

Added: vendor/Python/current/Modules/_ctypes/darwin/LICENSE
===================================================================
--- vendor/Python/current/Modules/_ctypes/darwin/LICENSE	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/darwin/LICENSE	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,31 @@
+Copyright (c) 2002 Jorge Acereda  <jacereda at users.sourceforge.net> &
+                   Peter O'Gorman <ogorman at users.sourceforge.net>
+                   
+Portions may be copyright others, see the AUTHORS file included with this
+distribution.
+
+Maintained by Peter O'Gorman <ogorman at users.sourceforge.net>
+
+Bug Reports and other queries should go to <ogorman at users.sourceforge.net>
+
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+

Added: vendor/Python/current/Modules/_ctypes/darwin/README
===================================================================
--- vendor/Python/current/Modules/_ctypes/darwin/README	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/darwin/README	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,95 @@
+dlcompat for Darwin
+=========================
+
+This is dlcompat, a small library that emulates the dlopen()
+interface on top of Darwin's dyld API.
+
+dlcompat allows loading a ".dylib" library (as long as the RTLD_LOCAL 
+flag isn't passed to dlopen()). It can be configured to yield a warning 
+when trying to close it (dynamic libraries cannot currently be unloaded).
+
+It automatically searches for modules in several directories when no 
+absolute path is specified and the module is not found in the current 
+directory.
+
+The paths searched are those specified in the environment variables
+LD_LIBRARY_PATH and DYLD_LIBRARY_PATH plus /lib, /usr/local/lib and 
+/usr/lib or the path specified in the environment variable 
+DYLD_FALLBACK_LIBRARY_PATH.
+
+In the default install the behavior of dlsym is to automatically prepend
+an underscore to passed in symbol names, this allows easier porting of
+applications which were written specifically for ELF based lifeforms.
+
+Installation
+--------------
+Type:
+	./configure
+	make
+	sudo make install
+
+This will compile the source file, generate both a static and shared
+library called libdl and install it into /usr/local/lib. The header
+file dlfcn.h will be installed in /usr/local/include.
+
+If you want to place the files somewhere else, run
+
+  make clean
+  ./configure --prefix=<prefix>
+  make
+  sudo make install
+
+where <prefix> is the hierarchy you want to install into, e.g. /usr
+for /usr/lib and /usr/include (_NOT_ recommended!).
+
+To enable debugging output (useful for me), run
+
+  make clean
+  ./configure --enable-debug
+  make
+  sudo make install
+  
+If you want old dlcompat style behavior of not prepending the underscore
+on calls to dlsym then type:
+
+  make clean
+  ./configure --enable-fink
+  make
+  sudo make install
+
+Usage
+-------
+Software that uses GNU autoconf will likely check for a library called
+libdl, that's why I named it that way. For software that doesn't find
+the library on its own, you must add a '-ldl' to the appropriate
+Makefile (or environment) variable, usually LIBS.
+
+If you installed dlcompat into a directory other than /usr/local/lib,
+you must tell the compiler where to find it. Add '-L<prefix>/lib' to
+LDFLAGS (or CFLAGS) and '-I<prefix>/include' to CPPFLAGS (or CFLAGS).
+
+Notes
+-----
+If you are writing new software and plan to have Mac OX X compatibility you
+should look at the dyld api's in /usr/include/mach-o/dyld.h, rather than
+using dlcompat, using the native api's is the supported method of loading
+dynamically on Mac OS X, if you want an small example, look at dlfcn_simple.c,
+which should help get you started.
+
+Also note that the functions in dlcompat are not thread safe, and while it is not
+POSIX spec compliant, it is about as close to compliance as it is going to get though.
+
+You can always get the latest version from opendarwin cvs:
+
+  cvs -d :pserver:anonymous at anoncvs.opendarwin.org:/cvs/od login
+  cvs -z3 -d :pserver:anonymous at anoncvs.opendarwin.org:/cvs/od \
+               co -d dlcompat proj/dlcompat
+
+
+It is hoped that this library will be useful, and as bug free as possible, if you find
+any bugs please let us know about them so they can be fixed.
+
+Please send bug reports to Peter O'Gorman <ogorman at users.sourceforge.net>
+
+Thanks.
+

Added: vendor/Python/current/Modules/_ctypes/darwin/README.ctypes
===================================================================
--- vendor/Python/current/Modules/_ctypes/darwin/README.ctypes	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/darwin/README.ctypes	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,11 @@
+The files in this directory are taken from
+http://www.opendarwin.org/cgi-bin/cvsweb.cgi/~checkout~/proj/dlcompat/
+
+The LICENSE in this directory applies to these files.
+
+Thomas Heller, Jan 2003
+
+These files have been modified so they fall back to the system
+dlfcn calls if available in libSystem.
+
+Bob Ippolito, Feb 2006

Added: vendor/Python/current/Modules/_ctypes/darwin/dlfcn.h
===================================================================
--- vendor/Python/current/Modules/_ctypes/darwin/dlfcn.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/darwin/dlfcn.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,84 @@
+/*
+Copyright (c) 2002 Jorge Acereda  <jacereda at users.sourceforge.net> &
+                   Peter O'Gorman <ogorman at users.sourceforge.net>
+                   
+Portions may be copyright others, see the AUTHORS file included with this
+distribution.
+
+Maintained by Peter O'Gorman <ogorman at users.sourceforge.net>
+
+Bug Reports and other queries should go to <ogorman at users.sourceforge.net>
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+#ifndef _DLFCN_H_
+#define _DLFCN_H_
+
+#include <AvailabilityMacros.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*
+ * Structure filled in by dladdr().
+ */
+
+typedef struct dl_info {
+        const char      *dli_fname;     /* Pathname of shared object */
+        void            *dli_fbase;     /* Base address of shared object */
+        const char      *dli_sname;     /* Name of nearest symbol */
+        void            *dli_saddr;     /* Address of nearest symbol */
+} Dl_info;
+
+
+#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_2
+#warning CTYPES_DARWIN_DLFCN
+#define CTYPES_DARWIN_DLFCN
+extern void * (*ctypes_dlopen)(const char *path, int mode);
+extern void * (*ctypes_dlsym)(void * handle, const char *symbol);
+extern const char * (*ctypes_dlerror)(void);
+extern int (*ctypes_dlclose)(void * handle);
+extern int (*ctypes_dladdr)(const void *, Dl_info *);
+#else
+extern void * dlopen(const char *path, int mode);
+extern void * dlsym(void * handle, const char *symbol);
+extern const char * dlerror(void);
+extern int dlclose(void * handle);
+extern int dladdr(const void *, Dl_info *);
+#endif
+
+#define RTLD_LAZY	0x1
+#define RTLD_NOW	0x2
+#define RTLD_LOCAL	0x4
+#define RTLD_GLOBAL	0x8
+#define RTLD_NOLOAD	0x10
+#define RTLD_NODELETE	0x80
+
+/* These are from the Mac OS X 10.4 headers */
+#define RTLD_NEXT       ((void *) -1)   /* Search subsequent objects. */
+#define RTLD_DEFAULT    ((void *) -2)   /* Use default search algorithm. */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DLFCN_H_ */

Added: vendor/Python/current/Modules/_ctypes/darwin/dlfcn_simple.c
===================================================================
--- vendor/Python/current/Modules/_ctypes/darwin/dlfcn_simple.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/darwin/dlfcn_simple.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,272 @@
+/*
+Copyright (c) 2002 Peter O'Gorman <ogorman at users.sourceforge.net>
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+
+/* Just to prove that it isn't that hard to add Mac calls to your code :)
+   This works with pretty much everything, including kde3 xemacs and the gimp,
+   I'd guess that it'd work in at least 95% of cases, use this as your starting
+   point, rather than the mess that is dlfcn.c, assuming that your code does not
+   require ref counting or symbol lookups in dependent libraries
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdarg.h>
+#include <limits.h>
+#include <mach-o/dyld.h>
+#include <AvailabilityMacros.h>
+#include "dlfcn.h"
+
+#ifdef CTYPES_DARWIN_DLFCN
+
+#define ERR_STR_LEN 256
+
+#ifndef MAC_OS_X_VERSION_10_3
+#define MAC_OS_X_VERSION_10_3 1030
+#endif
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3
+#define DARWIN_HAS_DLOPEN
+extern void * dlopen(const char *path, int mode) __attribute__((weak_import));
+extern void * dlsym(void * handle, const char *symbol) __attribute__((weak_import));
+extern const char * dlerror(void) __attribute__((weak_import));
+extern int dlclose(void * handle) __attribute__((weak_import));
+extern int dladdr(const void *, Dl_info *) __attribute__((weak_import));
+#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3 */
+
+#ifndef DARWIN_HAS_DLOPEN
+#define dlopen darwin_dlopen
+#define dlsym darwin_dlsym
+#define dlerror darwin_dlerror
+#define dlclose darwin_dlclose
+#define dladdr darwin_dladdr
+#endif
+
+void * (*ctypes_dlopen)(const char *path, int mode);
+void * (*ctypes_dlsym)(void * handle, const char *symbol);
+const char * (*ctypes_dlerror)(void);
+int (*ctypes_dlclose)(void * handle);
+int (*ctypes_dladdr)(const void *, Dl_info *);
+
+#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3
+/* Mac OS X 10.3+ has dlopen, so strip all this dead code to avoid warnings */
+
+static void *dlsymIntern(void *handle, const char *symbol);
+
+static const char *error(int setget, const char *str, ...);
+
+/* Set and get the error string for use by dlerror */
+static const char *error(int setget, const char *str, ...)
+{
+	static char errstr[ERR_STR_LEN];
+	static int err_filled = 0;
+	const char *retval;
+	va_list arg;
+	if (setget == 0)
+	{
+		va_start(arg, str);
+		strncpy(errstr, "dlcompat: ", ERR_STR_LEN);
+		vsnprintf(errstr + 10, ERR_STR_LEN - 10, str, arg);
+		va_end(arg);
+		err_filled = 1;
+		retval = NULL;
+	}
+	else
+	{
+		if (!err_filled)
+			retval = NULL;
+		else
+			retval = errstr;
+		err_filled = 0;
+	}
+	return retval;
+}
+
+/* darwin_dlopen */
+static void *darwin_dlopen(const char *path, int mode)
+{
+	void *module = 0;
+	NSObjectFileImage ofi = 0;
+	NSObjectFileImageReturnCode ofirc;
+
+	/* If we got no path, the app wants the global namespace, use -1 as the marker
+	   in this case */
+	if (!path)
+		return (void *)-1;
+
+	/* Create the object file image, works for things linked with the -bundle arg to ld */
+	ofirc = NSCreateObjectFileImageFromFile(path, &ofi);
+	switch (ofirc)
+	{
+		case NSObjectFileImageSuccess:
+			/* It was okay, so use NSLinkModule to link in the image */
+			module = NSLinkModule(ofi, path,
+								  NSLINKMODULE_OPTION_RETURN_ON_ERROR
+								  | (mode & RTLD_GLOBAL) ? 0 : NSLINKMODULE_OPTION_PRIVATE
+								  | (mode & RTLD_LAZY) ? 0 : NSLINKMODULE_OPTION_BINDNOW);
+			NSDestroyObjectFileImage(ofi);
+			break;
+		case NSObjectFileImageInappropriateFile:
+			/* It may have been a dynamic library rather than a bundle, try to load it */
+			module = (void *)NSAddImage(path, NSADDIMAGE_OPTION_RETURN_ON_ERROR);
+			break;
+		default:
+			/* God knows what we got */
+			error(0, "Can not open \"%s\"", path);
+			return 0;
+	}
+	if (!module)
+		error(0, "Can not open \"%s\"", path);
+	return module;
+
+}
+
+/* dlsymIntern is used by dlsym to find the symbol */
+static void *dlsymIntern(void *handle, const char *symbol)
+{
+	NSSymbol nssym = 0;
+	/* If the handle is -1, if is the app global context */
+	if (handle == (void *)-1)
+	{
+		/* Global context, use NSLookupAndBindSymbol */
+		if (NSIsSymbolNameDefined(symbol))
+		{
+			nssym = NSLookupAndBindSymbol(symbol);
+		}
+
+	}
+	/* Now see if the handle is a struch mach_header* or not, use NSLookupSymbol in image
+	   for libraries, and NSLookupSymbolInModule for bundles */
+	else
+	{
+		/* Check for both possible magic numbers depending on x86/ppc byte order */
+		if ((((struct mach_header *)handle)->magic == MH_MAGIC) ||
+			(((struct mach_header *)handle)->magic == MH_CIGAM))
+		{
+			if (NSIsSymbolNameDefinedInImage((struct mach_header *)handle, symbol))
+			{
+				nssym = NSLookupSymbolInImage((struct mach_header *)handle,
+											  symbol,
+											  NSLOOKUPSYMBOLINIMAGE_OPTION_BIND
+											  | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);
+			}
+
+		}
+		else
+		{
+			nssym = NSLookupSymbolInModule(handle, symbol);
+		}
+	}
+	if (!nssym)
+	{
+		error(0, "Symbol \"%s\" Not found", symbol);
+		return NULL;
+	}
+	return NSAddressOfSymbol(nssym);
+}
+
+static const char *darwin_dlerror(void)
+{
+	return error(1, (char *)NULL);
+}
+
+static int darwin_dlclose(void *handle)
+{
+	if ((((struct mach_header *)handle)->magic == MH_MAGIC) ||
+		(((struct mach_header *)handle)->magic == MH_CIGAM))
+	{
+		error(0, "Can't remove dynamic libraries on darwin");
+		return 0;
+	}
+	if (!NSUnLinkModule(handle, 0))
+	{
+		error(0, "unable to unlink module %s", NSNameOfModule(handle));
+		return 1;
+	}
+	return 0;
+}
+
+
+/* dlsym, prepend the underscore and call dlsymIntern */
+static void *darwin_dlsym(void *handle, const char *symbol)
+{
+	static char undersym[257];	/* Saves calls to malloc(3) */
+	int sym_len = strlen(symbol);
+	void *value = NULL;
+	char *malloc_sym = NULL;
+
+	if (sym_len < 256)
+	{
+		snprintf(undersym, 256, "_%s", symbol);
+		value = dlsymIntern(handle, undersym);
+	}
+	else
+	{
+		malloc_sym = malloc(sym_len + 2);
+		if (malloc_sym)
+		{
+			sprintf(malloc_sym, "_%s", symbol);
+			value = dlsymIntern(handle, malloc_sym);
+			free(malloc_sym);
+		}
+		else
+		{
+			error(0, "Unable to allocate memory");
+		}
+	}
+	return value;
+}
+
+static int darwin_dladdr(const void *handle, Dl_info *info) {
+	return 0;
+}
+#endif /* MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3 */
+
+#if __GNUC__ < 4
+#pragma CALL_ON_LOAD ctypes_dlfcn_init
+#else
+static void __attribute__ ((constructor)) ctypes_dlfcn_init(void);
+static
+#endif
+void ctypes_dlfcn_init(void) {
+	if (dlopen != NULL) {
+		ctypes_dlsym = dlsym;
+		ctypes_dlopen = dlopen;
+		ctypes_dlerror = dlerror;
+		ctypes_dlclose = dlclose;
+		ctypes_dladdr = dladdr;
+	} else {
+#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3
+		ctypes_dlsym = darwin_dlsym;
+		ctypes_dlopen = darwin_dlopen;
+		ctypes_dlerror = darwin_dlerror;
+		ctypes_dlclose = darwin_dlclose;
+		ctypes_dladdr = darwin_dladdr;
+#endif /* MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3 */
+	}
+}
+
+#endif /* CTYPES_DARWIN_DLFCN */

Added: vendor/Python/current/Modules/_ctypes/libffi/LICENSE
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/LICENSE	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/LICENSE	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,20 @@
+libffi - Copyright (c) 1996-2003  Red Hat, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+``Software''), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.

Added: vendor/Python/current/Modules/_ctypes/libffi/README
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/README	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/README	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,500 @@
+This directory contains the libffi package, which is not part of GCC but
+shipped with GCC as convenience.
+
+Status
+======
+
+libffi-2.00 has not been released yet! This is a development snapshot!
+
+libffi-1.20 was released on October 5, 1998. Check the libffi web
+page for updates: <URL:http://sources.redhat.com/libffi/>.
+
+
+What is libffi?
+===============
+
+Compilers for high level languages generate code that follow certain
+conventions. These conventions are necessary, in part, for separate
+compilation to work. One such convention is the "calling
+convention". The "calling convention" is essentially a set of
+assumptions made by the compiler about where function arguments will
+be found on entry to a function. A "calling convention" also specifies
+where the return value for a function is found.
+
+Some programs may not know at the time of compilation what arguments
+are to be passed to a function. For instance, an interpreter may be
+told at run-time about the number and types of arguments used to call
+a given function. Libffi can be used in such programs to provide a
+bridge from the interpreter program to compiled code.
+
+The libffi library provides a portable, high level programming
+interface to various calling conventions. This allows a programmer to
+call any function specified by a call interface description at run
+time.  
+
+Ffi stands for Foreign Function Interface. A foreign function
+interface is the popular name for the interface that allows code
+written in one language to call code written in another language. The
+libffi library really only provides the lowest, machine dependent
+layer of a fully featured foreign function interface. A layer must
+exist above libffi that handles type conversions for values passed
+between the two languages.
+
+
+Supported Platforms and Prerequisites
+=====================================
+
+Libffi has been ported to:
+
+	SunOS 4.1.3 & Solaris 2.x (SPARC-V8, SPARC-V9)
+
+	Irix 5.3 & 6.2 (System V/o32 & n32)
+
+	Intel x86 - Linux (System V ABI)
+
+	Alpha - Linux and OSF/1
+
+	m68k - Linux (System V ABI)
+
+	PowerPC - Linux (System V ABI, Darwin, AIX)
+
+	ARM - Linux (System V ABI)
+
+Libffi has been tested with the egcs 1.0.2 gcc compiler. Chances are
+that other versions will work.  Libffi has also been built and tested
+with the SGI compiler tools.
+
+On PowerPC, the tests failed (see the note below).
+
+You must use GNU make to build libffi. SGI's make will not work.
+Sun's probably won't either.
+	
+If you port libffi to another platform, please let me know! I assume
+that some will be easy (x86 NetBSD), and others will be more difficult
+(HP).
+
+
+Installing libffi
+=================
+
+[Note: before actually performing any of these installation steps,
+ you may wish to read the "Platform Specific Notes" below.]
+
+First you must configure the distribution for your particular
+system. Go to the directory you wish to build libffi in and run the
+"configure" program found in the root directory of the libffi source
+distribution.
+
+You may want to tell configure where to install the libffi library and
+header files. To do that, use the --prefix configure switch.  Libffi
+will install under /usr/local by default. 
+
+If you want to enable extra run-time debugging checks use the the
+--enable-debug configure switch. This is useful when your program dies
+mysteriously while using libffi. 
+
+Another useful configure switch is --enable-purify-safety. Using this
+will add some extra code which will suppress certain warnings when you
+are using Purify with libffi. Only use this switch when using 
+Purify, as it will slow down the library.
+
+Configure has many other options. Use "configure --help" to see them all.
+
+Once configure has finished, type "make". Note that you must be using
+GNU make. SGI's make will not work.  Sun's probably won't either.
+You can ftp GNU make from prep.ai.mit.edu:/pub/gnu.
+
+To ensure that libffi is working as advertised, type "make test".
+
+To install the library and header files, type "make install".
+
+
+Using libffi
+============
+
+	The Basics
+	----------
+
+Libffi assumes that you have a pointer to the function you wish to
+call and that you know the number and types of arguments to pass it,
+as well as the return type of the function.
+
+The first thing you must do is create an ffi_cif object that matches
+the signature of the function you wish to call. The cif in ffi_cif
+stands for Call InterFace. To prepare a call interface object, use the
+following function:
+
+ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi,
+			unsigned int nargs, 
+			ffi_type *rtype, ffi_type **atypes);
+
+	CIF is a pointer to the call interface object you wish
+		to initialize.
+
+	ABI is an enum that specifies the calling convention 
+		to use for the call. FFI_DEFAULT_ABI defaults
+		to the system's native calling convention. Other
+		ABI's may be used with care. They are system
+		specific.
+
+	NARGS is the number of arguments this function accepts.	
+		libffi does not yet support vararg functions.
+
+	RTYPE is a pointer to an ffi_type structure that represents
+		the return type of the function. Ffi_type objects
+		describe the types of values. libffi provides
+		ffi_type objects for many of the native C types:
+		signed int, unsigned int, signed char, unsigned char,
+		etc. There is also a pointer ffi_type object and
+		a void ffi_type. Use &ffi_type_void for functions that 
+		don't return values.
+
+	ATYPES is a vector of ffi_type pointers. ARGS must be NARGS long.
+		If NARGS is 0, this is ignored.
+
+
+ffi_prep_cif will return a status code that you are responsible 
+for checking. It will be one of the following:
+
+	FFI_OK - All is good.
+
+	FFI_BAD_TYPEDEF - One of the ffi_type objects that ffi_prep_cif
+		came across is bad.
+
+
+Before making the call, the VALUES vector should be initialized 
+with pointers to the appropriate argument values.
+
+To call the the function using the initialized ffi_cif, use the
+ffi_call function:
+
+void ffi_call(ffi_cif *cif, void *fn, void *rvalue, void **avalues);
+
+	CIF is a pointer to the ffi_cif initialized specifically
+		for this function.
+
+	FN is a pointer to the function you want to call.
+
+	RVALUE is a pointer to a chunk of memory that is to hold the
+		result of the function call. Currently, it must be
+		at least one word in size (except for the n32 version
+		under Irix 6.x, which must be a pointer to an 8 byte 
+		aligned value (a long long). It must also be at least 
+		word aligned (depending on the return type, and the
+		system's alignment requirements). If RTYPE is 
+		&ffi_type_void, this is ignored. If RVALUE is NULL, 
+		the return value is discarded.
+
+	AVALUES is a vector of void* that point to the memory locations
+		holding the argument values for a call.
+		If NARGS is 0, this is ignored.
+
+
+If you are expecting a return value from FN it will have been stored
+at RVALUE.
+
+
+
+	An Example
+	----------
+
+Here is a trivial example that calls puts() a few times.
+
+    #include <stdio.h>
+    #include <ffi.h>
+    
+    int main()
+    {
+      ffi_cif cif;
+      ffi_type *args[1];
+      void *values[1];
+      char *s;
+      int rc;
+      
+      /* Initialize the argument info vectors */    
+      args[0] = &ffi_type_uint;
+      values[0] = &s;
+      
+      /* Initialize the cif */
+      if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 
+    		       &ffi_type_uint, args) == FFI_OK)
+        {
+          s = "Hello World!";
+          ffi_call(&cif, puts, &rc, values);
+          /* rc now holds the result of the call to puts */
+          
+          /* values holds a pointer to the function's arg, so to 
+	     call puts() again all we need to do is change the 
+             value of s */
+          s = "This is cool!";
+          ffi_call(&cif, puts, &rc, values);
+        }
+      
+      return 0;
+    }
+
+
+
+	Aggregate Types
+	---------------
+
+Although libffi has no special support for unions or bit-fields, it is
+perfectly happy passing structures back and forth. You must first
+describe the structure to libffi by creating a new ffi_type object
+for it. Here is the definition of ffi_type:
+
+    typedef struct _ffi_type
+    {
+      unsigned size;
+      short alignment;
+      short type;
+      struct _ffi_type **elements;
+    } ffi_type;
+    
+All structures must have type set to FFI_TYPE_STRUCT.  You may set
+size and alignment to 0. These will be calculated and reset to the
+appropriate values by ffi_prep_cif().
+
+elements is a NULL terminated array of pointers to ffi_type objects
+that describe the type of the structure elements. These may, in turn,
+be structure elements.
+
+The following example initializes a ffi_type object representing the
+tm struct from Linux's time.h:
+
+				    struct tm {
+					int tm_sec;
+					int tm_min;
+					int tm_hour;
+					int tm_mday;
+					int tm_mon;
+					int tm_year;
+					int tm_wday;
+					int tm_yday;
+					int tm_isdst;
+					/* Those are for future use. */
+					long int __tm_gmtoff__;
+					__const char *__tm_zone__;
+				    };
+
+    {
+      ffi_type tm_type;
+      ffi_type *tm_type_elements[12];
+      int i;
+
+      tm_type.size = tm_type.alignment = 0;
+      tm_type.elements = &tm_type_elements;
+    
+      for (i = 0; i < 9; i++)
+          tm_type_elements[i] = &ffi_type_sint;
+
+      tm_type_elements[9] = &ffi_type_slong;
+      tm_type_elements[10] = &ffi_type_pointer;
+      tm_type_elements[11] = NULL;
+
+      /* tm_type can now be used to represent tm argument types and
+	 return types for ffi_prep_cif() */
+    }
+
+
+
+Platform Specific Notes
+=======================
+
+	Intel x86
+	---------
+
+There are no known problems with the x86 port.
+
+	Sun SPARC - SunOS 4.1.3 & Solaris 2.x
+	-------------------------------------
+
+You must use GNU Make to build libffi on Sun platforms.
+
+	MIPS - Irix 5.3 & 6.x
+	---------------------
+
+Irix 6.2 and better supports three different calling conventions: o32,
+n32 and n64. Currently, libffi only supports both o32 and n32 under
+Irix 6.x, but only o32 under Irix 5.3. Libffi will automatically be
+configured for whichever calling convention it was built for.
+
+By default, the configure script will try to build libffi with the GNU
+development tools. To build libffi with the SGI development tools, set
+the environment variable CC to either "cc -32" or "cc -n32" before
+running configure under Irix 6.x (depending on whether you want an o32
+or n32 library), or just "cc" for Irix 5.3.
+
+With the n32 calling convention, when returning structures smaller
+than 16 bytes, be sure to provide an RVALUE that is 8 byte aligned.
+Here's one way of forcing this:
+
+	double struct_storage[2];
+	my_small_struct *s = (my_small_struct *) struct_storage;  
+	/* Use s for RVALUE */
+
+If you don't do this you are liable to get spurious bus errors. 
+
+"long long" values are not supported yet.
+
+You must use GNU Make to build libffi on SGI platforms.
+
+	ARM - System V ABI
+	------------------
+
+The ARM port was performed on a NetWinder running ARM Linux ELF
+(2.0.31) and gcc 2.8.1.
+
+
+
+	PowerPC System V ABI
+	--------------------
+
+There are two `System V ABI's which libffi implements for PowerPC.
+They differ only in how small structures are returned from functions.
+
+In the FFI_SYSV version, structures that are 8 bytes or smaller are
+returned in registers.  This is what GCC does when it is configured
+for solaris, and is what the System V ABI I have (dated September
+1995) says.
+
+In the FFI_GCC_SYSV version, all structures are returned the same way:
+by passing a pointer as the first argument to the function.  This is
+what GCC does when it is configured for linux or a generic sysv
+target.
+
+EGCS 1.0.1 (and probably other versions of EGCS/GCC) also has a
+inconsistency with the SysV ABI: When a procedure is called with many
+floating-point arguments, some of them get put on the stack.  They are
+all supposed to be stored in double-precision format, even if they are
+only single-precision, but EGCS stores single-precision arguments as
+single-precision anyway.  This causes one test to fail (the `many
+arguments' test).
+
+
+What's With The Crazy Comments?
+===============================
+
+You might notice a number of cryptic comments in the code, delimited
+by /*@ and @*/. These are annotations read by the program LCLint, a
+tool for statically checking C programs. You can read all about it at
+<http://larch-www.lcs.mit.edu:8001/larch/lclint/index.html>.
+
+
+History
+=======
+
+1.20 Oct-5-98
+	Raffaele Sena produces ARM port.
+
+1.19 Oct-5-98
+	Fixed x86 long double and long long return support.
+	m68k bug fixes from Andreas Schwab.
+	Patch for DU assembler compatibility for the Alpha from Richard
+	Henderson.
+
+1.18 Apr-17-98
+	Bug fixes and MIPS configuration changes.
+
+1.17 Feb-24-98
+	Bug fixes and m68k port from Andreas Schwab. PowerPC port from
+	Geoffrey Keating. Various bug x86, Sparc and MIPS bug fixes.
+
+1.16 Feb-11-98
+	Richard Henderson produces Alpha port.
+
+1.15 Dec-4-97
+	Fixed an n32 ABI bug. New libtool, auto* support.
+
+1.14 May-13-97
+	libtool is now used to generate shared and static libraries.
+	Fixed a minor portability problem reported by Russ McManus
+	<mcmanr at eq.gs.com>.
+
+1.13 Dec-2-96
+	Added --enable-purify-safety to keep Purify from complaining
+	about certain low level code.
+	Sparc fix for calling functions with < 6 args.
+	Linux x86 a.out fix.
+
+1.12 Nov-22-96
+	Added missing ffi_type_void, needed for supporting void return 
+	types. Fixed test case for non MIPS machines. Cygnus Support 
+	is now Cygnus Solutions. 
+
+1.11 Oct-30-96
+	Added notes about GNU make.
+
+1.10 Oct-29-96
+	Added configuration fix for non GNU compilers.
+
+1.09 Oct-29-96
+	Added --enable-debug configure switch. Clean-ups based on LCLint 
+	feedback. ffi_mips.h is always installed. Many configuration 
+	fixes. Fixed ffitest.c for sparc builds.
+
+1.08 Oct-15-96
+	Fixed n32 problem. Many clean-ups.
+
+1.07 Oct-14-96
+	Gordon Irlam rewrites v8.S again. Bug fixes.
+
+1.06 Oct-14-96
+	Gordon Irlam improved the sparc port. 
+
+1.05 Oct-14-96
+	Interface changes based on feedback.
+
+1.04 Oct-11-96
+	Sparc port complete (modulo struct passing bug).
+
+1.03 Oct-10-96
+	Passing struct args, and returning struct values works for
+	all architectures/calling conventions. Expanded tests.
+
+1.02 Oct-9-96
+	Added SGI n32 support. Fixed bugs in both o32 and Linux support.
+	Added "make test".
+
+1.01 Oct-8-96
+	Fixed float passing bug in mips version. Restructured some
+	of the code. Builds cleanly with SGI tools.
+
+1.00 Oct-7-96
+	First release. No public announcement.
+
+
+Authors & Credits
+=================
+
+libffi was written by Anthony Green <green at cygnus.com>.
+
+Portions of libffi were derived from Gianni Mariani's free gencall
+library for Silicon Graphics machines.
+
+The closure mechanism was designed and implemented by Kresten Krab
+Thorup.
+
+The Sparc port was derived from code contributed by the fine folks at
+Visible Decisions Inc <http://www.vdi.com>. Further enhancements were
+made by Gordon Irlam at Cygnus Solutions <http://www.cygnus.com>.
+
+The Alpha port was written by Richard Henderson at Cygnus Solutions.
+
+Andreas Schwab ported libffi to m68k Linux and provided a number of
+bug fixes.
+
+Geoffrey Keating ported libffi to the PowerPC.
+
+Raffaele Sena ported libffi to the ARM.
+
+Jesper Skov and Andrew Haley both did more than their fair share of
+stepping through the code and tracking down bugs.
+
+Thanks also to Tom Tromey for bug fixes and configuration help.
+
+Thanks to Jim Blandy, who provided some useful feedback on the libffi
+interface.
+
+If you have a problem, or have found a bug, please send a note to
+green at cygnus.com.

Added: vendor/Python/current/Modules/_ctypes/libffi/config.guess
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/config.guess	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/config.guess	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1453 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+
+timestamp='2004-11-12'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Per Bothner <per at bothner.com>.
+# Please send patches to <config-patches at gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit build system type.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches at gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit 0 ;;
+    --version | -v )
+       echo "$version" ; exit 0 ;;
+    --help | --h* | -h )
+       echo "$usage"; exit 0 ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help" >&2
+       exit 1 ;;
+    * )
+       break ;;
+  esac
+done
+
+if test $# != 0; then
+  echo "$me: too many arguments$help" >&2
+  exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int x;" > $dummy.c ;
+	for c in cc gcc c89 c99 ; do
+	  if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+	     CC_FOR_BUILD="$c"; break ;
+	  fi ;
+	done ;
+	if test x"$CC_FOR_BUILD" = x ; then
+	  CC_FOR_BUILD=no_compiler_found ;
+	fi
+	;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi at noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+	PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    *:NetBSD:*:*)
+	# NetBSD (nbsd) targets should (where applicable) match one or
+	# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+	# switched to ELF, *-*-netbsd* would select the old
+	# object file format.  This provides both forward
+	# compatibility and a consistent mechanism for selecting the
+	# object file format.
+	#
+	# Note: NetBSD doesn't particularly care about the vendor
+	# portion of the name.  We always set it to "unknown".
+	sysctl="sysctl -n hw.machine_arch"
+	UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+	    /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+	case "${UNAME_MACHINE_ARCH}" in
+	    armeb) machine=armeb-unknown ;;
+	    arm*) machine=arm-unknown ;;
+	    sh3el) machine=shl-unknown ;;
+	    sh3eb) machine=sh-unknown ;;
+	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+	esac
+	# The Operating System including object format, if it has switched
+	# to ELF recently, or will in the future.
+	case "${UNAME_MACHINE_ARCH}" in
+	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+		eval $set_cc_for_build
+		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+			| grep __ELF__ >/dev/null
+		then
+		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+		    # Return netbsd for either.  FIX?
+		    os=netbsd
+		else
+		    os=netbsdelf
+		fi
+		;;
+	    *)
+	        os=netbsd
+		;;
+	esac
+	# The OS release
+	# Debian GNU/NetBSD machines have a different userland, and
+	# thus, need a distinct triplet. However, they do not need
+	# kernel version information, so it can be replaced with a
+	# suitable tag, in the style of linux-gnu.
+	case "${UNAME_VERSION}" in
+	    Debian*)
+		release='-gnu'
+		;;
+	    *)
+		release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+		;;
+	esac
+	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+	# contains redundant information, the shorter form:
+	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+	echo "${machine}-${os}${release}"
+	exit 0 ;;
+    amd64:OpenBSD:*:*)
+	echo x86_64-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    amiga:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    cats:OpenBSD:*:*)
+	echo arm-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    hp300:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    luna88k:OpenBSD:*:*)
+    	echo m88k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mac68k:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    macppc:OpenBSD:*:*)
+	echo powerpc-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvme68k:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvme88k:OpenBSD:*:*)
+	echo m88k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvmeppc:OpenBSD:*:*)
+	echo powerpc-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    sgi:OpenBSD:*:*)
+	echo mips64-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    sun3:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    *:OpenBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    *:ekkoBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+	exit 0 ;;
+    macppc:MirBSD:*:*)
+	echo powerppc-unknown-mirbsd${UNAME_RELEASE}
+	exit 0 ;;
+    *:MirBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+	exit 0 ;;
+    alpha:OSF1:*:*)
+	case $UNAME_RELEASE in
+	*4.0)
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+		;;
+	*5.*)
+	        UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+		;;
+	esac
+	# According to Compaq, /usr/sbin/psrinfo has been available on
+	# OSF/1 and Tru64 systems produced since 1995.  I hope that
+	# covers most systems running today.  This code pipes the CPU
+	# types through head -n 1, so we only detect the type of CPU 0.
+	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+	case "$ALPHA_CPU_TYPE" in
+	    "EV4 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV4.5 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "LCA4 (21066/21068)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV5 (21164)")
+		UNAME_MACHINE="alphaev5" ;;
+	    "EV5.6 (21164A)")
+		UNAME_MACHINE="alphaev56" ;;
+	    "EV5.6 (21164PC)")
+		UNAME_MACHINE="alphapca56" ;;
+	    "EV5.7 (21164PC)")
+		UNAME_MACHINE="alphapca57" ;;
+	    "EV6 (21264)")
+		UNAME_MACHINE="alphaev6" ;;
+	    "EV6.7 (21264A)")
+		UNAME_MACHINE="alphaev67" ;;
+	    "EV6.8CB (21264C)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8AL (21264B)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8CX (21264D)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.9A (21264/EV69A)")
+		UNAME_MACHINE="alphaev69" ;;
+	    "EV7 (21364)")
+		UNAME_MACHINE="alphaev7" ;;
+	    "EV7.9 (21364A)")
+		UNAME_MACHINE="alphaev79" ;;
+	esac
+	# A Pn.n version is a patched version.
+	# A Vn.n version is a released version.
+	# A Tn.n version is a released field test version.
+	# A Xn.n version is an unreleased experimental baselevel.
+	# 1.2 uses "1.2" for uname -r.
+	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+	exit 0 ;;
+    Alpha\ *:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# Should we change UNAME_MACHINE based on the output of uname instead
+	# of the specific Alpha model?
+	echo alpha-pc-interix
+	exit 0 ;;
+    21064:Windows_NT:50:3)
+	echo alpha-dec-winnt3.5
+	exit 0 ;;
+    Amiga*:UNIX_System_V:4.0:*)
+	echo m68k-unknown-sysv4
+	exit 0;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-amigaos
+	exit 0 ;;
+    *:[Mm]orph[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-morphos
+	exit 0 ;;
+    *:OS/390:*:*)
+	echo i370-ibm-openedition
+	exit 0 ;;
+    *:z/VM:*:*)
+	echo s390-ibm-zvmoe
+	exit 0 ;;
+    *:OS400:*:*)
+        echo powerpc-ibm-os400
+	exit 0 ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+	echo arm-acorn-riscix${UNAME_RELEASE}
+	exit 0;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+	echo hppa1.1-hitachi-hiuxmpp
+	exit 0;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+	# akee at wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+	if test "`(/bin/universe) 2>/dev/null`" = att ; then
+		echo pyramid-pyramid-sysv3
+	else
+		echo pyramid-pyramid-bsd
+	fi
+	exit 0 ;;
+    NILE*:*:*:dcosx)
+	echo pyramid-pyramid-svr4
+	exit 0 ;;
+    DRS?6000:unix:4.0:6*)
+	echo sparc-icl-nx6
+	exit 0 ;;
+    DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+	case `/usr/bin/uname -p` in
+	    sparc) echo sparc-icl-nx7 && exit 0 ;;
+	esac ;;
+    sun4H:SunOS:5.*:*)
+	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    i86pc:SunOS:5.*:*)
+	echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:6*:*)
+	# According to config.sub, this is the proper way to canonicalize
+	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+	# it's likely to be more like Solaris than SunOS4.
+	echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:*:*)
+	case "`/usr/bin/arch -k`" in
+	    Series*|S4*)
+		UNAME_RELEASE=`uname -v`
+		;;
+	esac
+	# Japanese Language versions have a version number like `4.1.3-JL'.
+	echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+	exit 0 ;;
+    sun3*:SunOS:*:*)
+	echo m68k-sun-sunos${UNAME_RELEASE}
+	exit 0 ;;
+    sun*:*:4.2BSD:*)
+	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+	test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+	case "`/bin/arch`" in
+	    sun3)
+		echo m68k-sun-sunos${UNAME_RELEASE}
+		;;
+	    sun4)
+		echo sparc-sun-sunos${UNAME_RELEASE}
+		;;
+	esac
+	exit 0 ;;
+    aushp:SunOS:*:*)
+	echo sparc-auspex-sunos${UNAME_RELEASE}
+	exit 0 ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit 0 ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit 0 ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+        echo m68k-milan-mint${UNAME_RELEASE}
+        exit 0 ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+        echo m68k-hades-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+        echo m68k-unknown-mint${UNAME_RELEASE}
+        exit 0 ;;
+    m68k:machten:*:*)
+	echo m68k-apple-machten${UNAME_RELEASE}
+	exit 0 ;;
+    powerpc:machten:*:*)
+	echo powerpc-apple-machten${UNAME_RELEASE}
+	exit 0 ;;
+    RISC*:Mach:*:*)
+	echo mips-dec-mach_bsd4.3
+	exit 0 ;;
+    RISC*:ULTRIX:*:*)
+	echo mips-dec-ultrix${UNAME_RELEASE}
+	exit 0 ;;
+    VAX*:ULTRIX*:*:*)
+	echo vax-dec-ultrix${UNAME_RELEASE}
+	exit 0 ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+	echo clipper-intergraph-clix${UNAME_RELEASE}
+	exit 0 ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+	int main (int argc, char *argv[]) {
+#else
+	int main (argc, argv) int argc; char *argv[]; {
+#endif
+	#if defined (host_mips) && defined (MIPSEB)
+	#if defined (SYSTYPE_SYSV)
+	  printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_SVR4)
+	  printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+	  printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+	#endif
+	#endif
+	  exit (-1);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c \
+	  && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+	  && exit 0
+	echo mips-mips-riscos${UNAME_RELEASE}
+	exit 0 ;;
+    Motorola:PowerMAX_OS:*:*)
+	echo powerpc-motorola-powermax
+	exit 0 ;;
+    Motorola:*:4.3:PL8-*)
+	echo powerpc-harris-powermax
+	exit 0 ;;
+    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+	echo powerpc-harris-powermax
+	exit 0 ;;
+    Night_Hawk:Power_UNIX:*:*)
+	echo powerpc-harris-powerunix
+	exit 0 ;;
+    m88k:CX/UX:7*:*)
+	echo m88k-harris-cxux7
+	exit 0 ;;
+    m88k:*:4*:R4*)
+	echo m88k-motorola-sysv4
+	exit 0 ;;
+    m88k:*:3*:R3*)
+	echo m88k-motorola-sysv3
+	exit 0 ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`/usr/bin/uname -p`
+	if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+	then
+	    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+	       [ ${TARGET_BINARY_INTERFACE}x = x ]
+	    then
+		echo m88k-dg-dgux${UNAME_RELEASE}
+	    else
+		echo m88k-dg-dguxbcs${UNAME_RELEASE}
+	    fi
+	else
+	    echo i586-dg-dgux${UNAME_RELEASE}
+	fi
+ 	exit 0 ;;
+    M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
+	echo m88k-dolphin-sysv3
+	exit 0 ;;
+    M88*:*:R3*:*)
+	# Delta 88k system running SVR3
+	echo m88k-motorola-sysv3
+	exit 0 ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+	echo m88k-tektronix-sysv3
+	exit 0 ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+	echo m68k-tektronix-bsd
+	exit 0 ;;
+    *:IRIX*:*:*)
+	echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+	exit 0 ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+	echo romp-ibm-aix      # uname -m gives an 8 hex-code CPU id
+	exit 0 ;;              # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
+	echo i386-ibm-aix
+	exit 0 ;;
+    ia64:AIX:*:*)
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+	exit 0 ;;
+    *:AIX:2:3)
+	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+		eval $set_cc_for_build
+		sed 's/^		//' << EOF >$dummy.c
+		#include <sys/systemcfg.h>
+
+		main()
+			{
+			if (!__power_pc())
+				exit(1);
+			puts("powerpc-ibm-aix3.2.5");
+			exit(0);
+			}
+EOF
+		$CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
+		echo rs6000-ibm-aix3.2.5
+	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+		echo rs6000-ibm-aix3.2.4
+	else
+		echo rs6000-ibm-aix3.2
+	fi
+	exit 0 ;;
+    *:AIX:*:[45])
+	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+		IBM_ARCH=rs6000
+	else
+		IBM_ARCH=powerpc
+	fi
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+	exit 0 ;;
+    *:AIX:*:*)
+	echo rs6000-ibm-aix
+	exit 0 ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+	echo romp-ibm-bsd4.4
+	exit 0 ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+	echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+	exit 0 ;;                           # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+	echo rs6000-bull-bosx
+	exit 0 ;;
+    DPX/2?00:B.O.S.:*:*)
+	echo m68k-bull-sysv3
+	exit 0 ;;
+    9000/[34]??:4.3bsd:1.*:*)
+	echo m68k-hp-bsd
+	exit 0 ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+	echo m68k-hp-bsd4.4
+	exit 0 ;;
+    9000/[34678]??:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	case "${UNAME_MACHINE}" in
+	    9000/31? )            HP_ARCH=m68000 ;;
+	    9000/[34]?? )         HP_ARCH=m68k ;;
+	    9000/[678][0-9][0-9])
+		if [ -x /usr/bin/getconf ]; then
+		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+                    case "${sc_cpu_version}" in
+                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+                      532)                      # CPU_PA_RISC2_0
+                        case "${sc_kernel_bits}" in
+                          32) HP_ARCH="hppa2.0n" ;;
+                          64) HP_ARCH="hppa2.0w" ;;
+			  '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
+                        esac ;;
+                    esac
+		fi
+		if [ "${HP_ARCH}" = "" ]; then
+		    eval $set_cc_for_build
+		    sed 's/^              //' << EOF >$dummy.c
+
+              #define _HPUX_SOURCE
+              #include <stdlib.h>
+              #include <unistd.h>
+
+              int main ()
+              {
+              #if defined(_SC_KERNEL_BITS)
+                  long bits = sysconf(_SC_KERNEL_BITS);
+              #endif
+                  long cpu  = sysconf (_SC_CPU_VERSION);
+
+                  switch (cpu)
+              	{
+              	case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+              	case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+              	case CPU_PA_RISC2_0:
+              #if defined(_SC_KERNEL_BITS)
+              	    switch (bits)
+              		{
+              		case 64: puts ("hppa2.0w"); break;
+              		case 32: puts ("hppa2.0n"); break;
+              		default: puts ("hppa2.0"); break;
+              		} break;
+              #else  /* !defined(_SC_KERNEL_BITS) */
+              	    puts ("hppa2.0"); break;
+              #endif
+              	default: puts ("hppa1.0"); break;
+              	}
+                  exit (0);
+              }
+EOF
+		    (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+		    test -z "$HP_ARCH" && HP_ARCH=hppa
+		fi ;;
+	esac
+	if [ ${HP_ARCH} = "hppa2.0w" ]
+	then
+	    # avoid double evaluation of $set_cc_for_build
+	    test -n "$CC_FOR_BUILD" || eval $set_cc_for_build
+	    if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null
+	    then
+		HP_ARCH="hppa2.0w"
+	    else
+		HP_ARCH="hppa64"
+	    fi
+	fi
+	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+	exit 0 ;;
+    ia64:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	echo ia64-hp-hpux${HPUX_REV}
+	exit 0 ;;
+    3050*:HI-UX:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <unistd.h>
+	int
+	main ()
+	{
+	  long cpu = sysconf (_SC_CPU_VERSION);
+	  /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+	     true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+	     results, however.  */
+	  if (CPU_IS_PA_RISC (cpu))
+	    {
+	      switch (cpu)
+		{
+		  case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+		  default: puts ("hppa-hitachi-hiuxwe2"); break;
+		}
+	    }
+	  else if (CPU_IS_HP_MC68K (cpu))
+	    puts ("m68k-hitachi-hiuxwe2");
+	  else puts ("unknown-hitachi-hiuxwe2");
+	  exit (0);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
+	echo unknown-hitachi-hiuxwe2
+	exit 0 ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+	echo hppa1.1-hp-bsd
+	exit 0 ;;
+    9000/8??:4.3bsd:*:*)
+	echo hppa1.0-hp-bsd
+	exit 0 ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+	echo hppa1.0-hp-mpeix
+	exit 0 ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+	echo hppa1.1-hp-osf
+	exit 0 ;;
+    hp8??:OSF1:*:*)
+	echo hppa1.0-hp-osf
+	exit 0 ;;
+    i*86:OSF1:*:*)
+	if [ -x /usr/sbin/sysversion ] ; then
+	    echo ${UNAME_MACHINE}-unknown-osf1mk
+	else
+	    echo ${UNAME_MACHINE}-unknown-osf1
+	fi
+	exit 0 ;;
+    parisc*:Lites*:*:*)
+	echo hppa1.1-hp-lites
+	exit 0 ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+	echo c1-convex-bsd
+        exit 0 ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+        exit 0 ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+	echo c34-convex-bsd
+        exit 0 ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+	echo c38-convex-bsd
+        exit 0 ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+	echo c4-convex-bsd
+        exit 0 ;;
+    CRAY*Y-MP:*:*:*)
+	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*[A-Z]90:*:*:*)
+	echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+	      -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*TS:*:*:*)
+	echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*T3E:*:*:*)
+	echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*SV1:*:*:*)
+	echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    *:UNICOS/mp:*:*)
+	echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+	FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        exit 0 ;;
+    5000:UNIX_System_V:4.*:*)
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+        echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+	exit 0 ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    sparc*:BSD/OS:*:*)
+	echo sparc-unknown-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    *:BSD/OS:*:*)
+	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    *:FreeBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	exit 0 ;;
+    i*:CYGWIN*:*)
+	echo ${UNAME_MACHINE}-pc-cygwin
+	exit 0 ;;
+    i*:MINGW*:*)
+	echo ${UNAME_MACHINE}-pc-mingw32
+	exit 0 ;;
+    i*:PW*:*)
+	echo ${UNAME_MACHINE}-pc-pw32
+	exit 0 ;;
+    x86:Interix*:[34]*)
+	echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//'
+	exit 0 ;;
+    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+	echo i${UNAME_MACHINE}-pc-mks
+	exit 0 ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+	# UNAME_MACHINE based on the output of uname instead of i386?
+	echo i586-pc-interix
+	exit 0 ;;
+    i*:UWIN*:*)
+	echo ${UNAME_MACHINE}-pc-uwin
+	exit 0 ;;
+    p*:CYGWIN*:*)
+	echo powerpcle-unknown-cygwin
+	exit 0 ;;
+    prep*:SunOS:5.*:*)
+	echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    *:GNU:*:*)
+	# the GNU system
+	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+	exit 0 ;;
+    *:GNU/*:*:*)
+	# other systems with GNU libc and userland
+	echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+	exit 0 ;;
+    i*86:Minix:*:*)
+	echo ${UNAME_MACHINE}-pc-minix
+	exit 0 ;;
+    arm*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    cris:Linux:*:*)
+	echo cris-axis-linux-gnu
+	exit 0 ;;
+    crisv32:Linux:*:*)
+	echo crisv32-axis-linux-gnu
+	exit 0 ;;
+    frv:Linux:*:*)
+    	echo frv-unknown-linux-gnu
+	exit 0 ;;
+    ia64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    m32r*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    m68*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    mips:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef mips
+	#undef mipsel
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=mipsel
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=mips
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+	test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
+	;;
+    mips64:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef mips64
+	#undef mips64el
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=mips64el
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=mips64
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+	test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
+	;;
+    ppc:Linux:*:*)
+	echo powerpc-unknown-linux-gnu
+	exit 0 ;;
+    ppc64:Linux:*:*)
+	echo powerpc64-unknown-linux-gnu
+	exit 0 ;;
+    alpha:Linux:*:*)
+	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+	  EV5)   UNAME_MACHINE=alphaev5 ;;
+	  EV56)  UNAME_MACHINE=alphaev56 ;;
+	  PCA56) UNAME_MACHINE=alphapca56 ;;
+	  PCA57) UNAME_MACHINE=alphapca56 ;;
+	  EV6)   UNAME_MACHINE=alphaev6 ;;
+	  EV67)  UNAME_MACHINE=alphaev67 ;;
+	  EV68*) UNAME_MACHINE=alphaev68 ;;
+        esac
+	objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+	if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+	echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+	exit 0 ;;
+    parisc:Linux:*:* | hppa:Linux:*:*)
+	# Look for CPU level
+	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+	  PA7*) echo hppa1.1-unknown-linux-gnu ;;
+	  PA8*) echo hppa2.0-unknown-linux-gnu ;;
+	  *)    echo hppa-unknown-linux-gnu ;;
+	esac
+	exit 0 ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+	echo hppa64-unknown-linux-gnu
+	exit 0 ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+	echo ${UNAME_MACHINE}-ibm-linux
+	exit 0 ;;
+    sh64*:Linux:*:*)
+    	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    sh*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    x86_64:Linux:*:*)
+	echo x86_64-unknown-linux-gnu
+	exit 0 ;;
+    i*86:Linux:*:*)
+	# The BFD linker knows what the default object file format is, so
+	# first see if it will tell us. cd to the root directory to prevent
+	# problems with other programs or directories called `ld' in the path.
+	# Set LC_ALL=C to ensure ld outputs messages in English.
+	ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
+			 | sed -ne '/supported targets:/!d
+				    s/[ 	][ 	]*/ /g
+				    s/.*supported targets: *//
+				    s/ .*//
+				    p'`
+        case "$ld_supported_targets" in
+	  elf32-i386)
+		TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+		;;
+	  a.out-i386-linux)
+		echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+		exit 0 ;;
+	  coff-i386)
+		echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+		exit 0 ;;
+	  "")
+		# Either a pre-BFD a.out linker (linux-gnuoldld) or
+		# one that does not give us useful --help.
+		echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
+		exit 0 ;;
+	esac
+	# Determine whether the default compiler is a.out or elf
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <features.h>
+	#ifdef __ELF__
+	# ifdef __GLIBC__
+	#  if __GLIBC__ >= 2
+	LIBC=gnu
+	#  else
+	LIBC=gnulibc1
+	#  endif
+	# else
+	LIBC=gnulibc1
+	# endif
+	#else
+	#ifdef __INTEL_COMPILER
+	LIBC=gnu
+	#else
+	LIBC=gnuaout
+	#endif
+	#endif
+	#ifdef __dietlibc__
+	LIBC=dietlibc
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+	test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0
+	test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
+	;;
+    i*86:DYNIX/ptx:4*:*)
+	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+	# earlier versions are messed up and put the nodename in both
+	# sysname and nodename.
+	echo i386-sequent-sysv4
+	exit 0 ;;
+    i*86:UNIX_SV:4.2MP:2.*)
+        # Unixware is an offshoot of SVR4, but it has its own version
+        # number series starting with 2...
+        # I am not positive that other SVR4 systems won't match this,
+	# I just have to hope.  -- rms.
+        # Use sysv4.2uw... so that sysv4* matches it.
+	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+	exit 0 ;;
+    i*86:OS/2:*:*)
+	# If we were able to find `uname', then EMX Unix compatibility
+	# is probably installed.
+	echo ${UNAME_MACHINE}-pc-os2-emx
+	exit 0 ;;
+    i*86:XTS-300:*:STOP)
+	echo ${UNAME_MACHINE}-unknown-stop
+	exit 0 ;;
+    i*86:atheos:*:*)
+	echo ${UNAME_MACHINE}-unknown-atheos
+	exit 0 ;;
+	i*86:syllable:*:*)
+	echo ${UNAME_MACHINE}-pc-syllable
+	exit 0 ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+	echo i386-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    i*86:*DOS:*:*)
+	echo ${UNAME_MACHINE}-pc-msdosdjgpp
+	exit 0 ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+	UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+		echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+	else
+		echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+	fi
+	exit 0 ;;
+    i*86:*:5:[78]*)
+	case `/bin/uname -X | grep "^Machine"` in
+	    *486*)	     UNAME_MACHINE=i486 ;;
+	    *Pentium)	     UNAME_MACHINE=i586 ;;
+	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+	esac
+	echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+	exit 0 ;;
+    i*86:*:3.2:*)
+	if test -f /usr/options/cb.name; then
+		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+		echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+	elif /bin/uname -X 2>/dev/null >/dev/null ; then
+		UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+		(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+		(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+			&& UNAME_MACHINE=i586
+		(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+	else
+		echo ${UNAME_MACHINE}-pc-sysv32
+	fi
+	exit 0 ;;
+    pc:*:*:*)
+	# Left here for compatibility:
+        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+        # the processor, so we play safe by assuming i386.
+	echo i386-pc-msdosdjgpp
+        exit 0 ;;
+    Intel:Mach:3*:*)
+	echo i386-pc-mach3
+	exit 0 ;;
+    paragon:*:*:*)
+	echo i860-intel-osf1
+	exit 0 ;;
+    i860:*:4.*:*) # i860-SVR4
+	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+	  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+	else # Add other i860-SVR4 vendors below as they are discovered.
+	  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+	fi
+	exit 0 ;;
+    mini*:CTIX:SYS*5:*)
+	# "miniframe"
+	echo m68010-convergent-sysv
+	exit 0 ;;
+    mc68k:UNIX:SYSTEM5:3.51m)
+	echo m68k-convergent-sysv
+	exit 0 ;;
+    M680?0:D-NIX:5.3:*)
+	echo m68k-diab-dnix
+	exit 0 ;;
+    M68*:*:R3V[5678]*:*)
+	test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+	OS_REL=''
+	test -r /etc/.relid \
+	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	  && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	  && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && echo i486-ncr-sysv4 && exit 0 ;;
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+	echo m68k-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    mc68030:UNIX_System_V:4.*:*)
+	echo m68k-atari-sysv4
+	exit 0 ;;
+    TSUNAMI:LynxOS:2.*:*)
+	echo sparc-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    rs6000:LynxOS:2.*:*)
+	echo rs6000-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+	echo powerpc-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    SM[BE]S:UNIX_SV:*:*)
+	echo mips-dde-sysv${UNAME_RELEASE}
+	exit 0 ;;
+    RM*:ReliantUNIX-*:*:*)
+	echo mips-sni-sysv4
+	exit 0 ;;
+    RM*:SINIX-*:*:*)
+	echo mips-sni-sysv4
+	exit 0 ;;
+    *:SINIX-*:*:*)
+	if uname -p 2>/dev/null >/dev/null ; then
+		UNAME_MACHINE=`(uname -p) 2>/dev/null`
+		echo ${UNAME_MACHINE}-sni-sysv4
+	else
+		echo ns32k-sni-sysv
+	fi
+	exit 0 ;;
+    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                      # says <Richard.M.Bartel at ccMail.Census.GOV>
+        echo i586-unisys-sysv4
+        exit 0 ;;
+    *:UNIX_System_V:4*:FTX*)
+	# From Gerald Hewes <hewes at openmarket.com>.
+	# How about differentiating between stratus architectures? -djm
+	echo hppa1.1-stratus-sysv4
+	exit 0 ;;
+    *:*:*:FTX*)
+	# From seanf at swdc.stratus.com.
+	echo i860-stratus-sysv4
+	exit 0 ;;
+    *:VOS:*:*)
+	# From Paul.Green at stratus.com.
+	echo hppa1.1-stratus-vos
+	exit 0 ;;
+    mc68*:A/UX:*:*)
+	echo m68k-apple-aux${UNAME_RELEASE}
+	exit 0 ;;
+    news*:NEWS-OS:6*:*)
+	echo mips-sony-newsos6
+	exit 0 ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+	if [ -d /usr/nec ]; then
+	        echo mips-nec-sysv${UNAME_RELEASE}
+	else
+	        echo mips-unknown-sysv${UNAME_RELEASE}
+	fi
+        exit 0 ;;
+    BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
+	echo powerpc-be-beos
+	exit 0 ;;
+    BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
+	echo powerpc-apple-beos
+	exit 0 ;;
+    BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
+	echo i586-pc-beos
+	exit 0 ;;
+    SX-4:SUPER-UX:*:*)
+	echo sx4-nec-superux${UNAME_RELEASE}
+	exit 0 ;;
+    SX-5:SUPER-UX:*:*)
+	echo sx5-nec-superux${UNAME_RELEASE}
+	exit 0 ;;
+    SX-6:SUPER-UX:*:*)
+	echo sx6-nec-superux${UNAME_RELEASE}
+	exit 0 ;;
+    Power*:Rhapsody:*:*)
+	echo powerpc-apple-rhapsody${UNAME_RELEASE}
+	exit 0 ;;
+    *:Rhapsody:*:*)
+	echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+	exit 0 ;;
+    *:Darwin:*:*)
+	UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+	case $UNAME_PROCESSOR in
+	    *86) UNAME_PROCESSOR=i686 ;;
+	    unknown) UNAME_PROCESSOR=powerpc ;;
+	esac
+	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+	exit 0 ;;
+    *:procnto*:*:* | *:QNX:[0123456789]*:*)
+	UNAME_PROCESSOR=`uname -p`
+	if test "$UNAME_PROCESSOR" = "x86"; then
+		UNAME_PROCESSOR=i386
+		UNAME_MACHINE=pc
+	fi
+	echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+	exit 0 ;;
+    *:QNX:*:4*)
+	echo i386-pc-qnx
+	exit 0 ;;
+    NSR-?:NONSTOP_KERNEL:*:*)
+	echo nsr-tandem-nsk${UNAME_RELEASE}
+	exit 0 ;;
+    *:NonStop-UX:*:*)
+	echo mips-compaq-nonstopux
+	exit 0 ;;
+    BS2000:POSIX*:*:*)
+	echo bs2000-siemens-sysv
+	exit 0 ;;
+    DS/*:UNIX_System_V:*:*)
+	echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+	exit 0 ;;
+    *:Plan9:*:*)
+	# "uname -m" is not consistent, so use $cputype instead. 386
+	# is converted to i386 for consistency with other x86
+	# operating systems.
+	if test "$cputype" = "386"; then
+	    UNAME_MACHINE=i386
+	else
+	    UNAME_MACHINE="$cputype"
+	fi
+	echo ${UNAME_MACHINE}-unknown-plan9
+	exit 0 ;;
+    *:TOPS-10:*:*)
+	echo pdp10-unknown-tops10
+	exit 0 ;;
+    *:TENEX:*:*)
+	echo pdp10-unknown-tenex
+	exit 0 ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+	echo pdp10-dec-tops20
+	exit 0 ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+	echo pdp10-xkl-tops20
+	exit 0 ;;
+    *:TOPS-20:*:*)
+	echo pdp10-unknown-tops20
+	exit 0 ;;
+    *:ITS:*:*)
+	echo pdp10-unknown-its
+	exit 0 ;;
+    SEI:*:*:SEIUX)
+        echo mips-sei-seiux${UNAME_RELEASE}
+	exit 0 ;;
+    *:DragonFly:*:*)
+	echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	exit 0 ;;
+    *:*VMS:*:*)
+    	UNAME_MACHINE=`(uname -p) 2>/dev/null`
+	case "${UNAME_MACHINE}" in
+	    A*) echo alpha-dec-vms && exit 0 ;;
+	    I*) echo ia64-dec-vms && exit 0 ;;
+	    V*) echo vax-dec-vms && exit 0 ;;
+	esac ;;
+    *:XENIX:*:SysV)
+	echo i386-pc-xenix
+	exit 0 ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+          "4"
+#else
+	  ""
+#endif
+         ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+	printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+	printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+	echo c1-convex-bsd
+	exit 0 ;;
+    c2*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+	exit 0 ;;
+    c34*)
+	echo c34-convex-bsd
+	exit 0 ;;
+    c38*)
+	echo c38-convex-bsd
+	exit 0 ;;
+    c4*)
+	echo c4-convex-bsd
+	exit 0 ;;
+    esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+    ftp://ftp.gnu.org/pub/gnu/config/
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches at gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo               = `(hostinfo) 2>/dev/null`
+/bin/universe          = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch              = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM  = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:


Property changes on: vendor/Python/current/Modules/_ctypes/libffi/config.guess
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Modules/_ctypes/libffi/config.sub
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/config.sub	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/config.sub	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1569 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+timestamp='2005-04-22'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Please send patches to <config-patches at gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#	CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+       $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches at gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit 0 ;;
+    --version | -v )
+       echo "$version" ; exit 0 ;;
+    --help | --h* | -h )
+       echo "$usage"; exit 0 ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit 0;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \
+  kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+	-sun*os*)
+		# Prevent following clause from handling this invalid input.
+		;;
+	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+	-apple | -axis | -knuth | -cray)
+		os=
+		basic_machine=$1
+		;;
+	-sim | -cisco | -oki | -wec | -winbond)
+		os=
+		basic_machine=$1
+		;;
+	-scout)
+		;;
+	-wrs)
+		os=-vxworks
+		basic_machine=$1
+		;;
+	-chorusos*)
+		os=-chorusos
+		basic_machine=$1
+		;;
+ 	-chorusrdb)
+ 		os=-chorusrdb
+		basic_machine=$1
+ 		;;
+	-hiux*)
+		os=-hiuxwe2
+		;;
+	-sco5)
+		os=-sco3.2v5
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco4)
+		os=-sco3.2v4
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2.[4-9]*)
+		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2v[4-9]*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco*)
+		os=-sco3.2v2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-udk*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-isc)
+		os=-isc2.2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-clix*)
+		basic_machine=clipper-intergraph
+		;;
+	-isc*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-lynx*)
+		os=-lynxos
+		;;
+	-ptx*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+		;;
+	-windowsnt*)
+		os=`echo $os | sed -e 's/windowsnt/winnt/'`
+		;;
+	-psos*)
+		os=-psos
+		;;
+	-mint | -mint[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+	# Recognize the basic CPU types without company name.
+	# Some are omitted here because they have special meanings below.
+	1750a | 580 \
+	| a29k \
+	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+	| am33_2.0 \
+	| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
+	| bfin \
+	| c4x | clipper \
+	| d10v | d30v | dlx | dsp16xx \
+	| fr30 | frv \
+	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+	| i370 | i860 | i960 | ia64 \
+	| ip2k | iq2000 \
+	| m32r | m32rle | m68000 | m68k | m88k | maxq | mcore \
+	| mips | mipsbe | mipseb | mipsel | mipsle \
+	| mips16 \
+	| mips64 | mips64el \
+	| mips64vr | mips64vrel \
+	| mips64orion | mips64orionel \
+	| mips64vr4100 | mips64vr4100el \
+	| mips64vr4300 | mips64vr4300el \
+	| mips64vr5000 | mips64vr5000el \
+	| mipsisa32 | mipsisa32el \
+	| mipsisa32r2 | mipsisa32r2el \
+	| mipsisa64 | mipsisa64el \
+	| mipsisa64r2 | mipsisa64r2el \
+	| mipsisa64sb1 | mipsisa64sb1el \
+	| mipsisa64sr71k | mipsisa64sr71kel \
+	| mipstx39 | mipstx39el \
+	| mn10200 | mn10300 \
+	| msp430 \
+	| ns16k | ns32k \
+	| openrisc | or32 \
+	| pdp10 | pdp11 | pj | pjl \
+	| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+	| pyramid \
+	| sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
+	| sh64 | sh64le \
+	| sparc | sparc64 | sparc64b | sparc86x | sparclet | sparclite \
+	| sparcv8 | sparcv9 | sparcv9b \
+	| strongarm \
+	| tahoe | thumb | tic4x | tic80 | tron \
+	| v850 | v850e \
+	| we32k \
+	| x86 | xscale | xscalee[bl] | xstormy16 | xtensa \
+	| z8k)
+		basic_machine=$basic_machine-unknown
+		;;
+	m6811 | m68hc11 | m6812 | m68hc12)
+		# Motorola 68HC11/12.
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
+	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+		;;
+
+	# We use `pc' rather than `unknown'
+	# because (1) that's what they normally are, and
+	# (2) the word "unknown" tends to confuse beginning users.
+	i*86 | x86_64)
+	  basic_machine=$basic_machine-pc
+	  ;;
+	# Object if more than one company name word.
+	*-*-*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+	# Recognize the basic CPU types with company name.
+	580-* \
+	| a29k-* \
+	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
+	| avr-* \
+	| bfin-* | bs2000-* \
+	| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+	| clipper-* | craynv-* | cydra-* \
+	| d10v-* | d30v-* | dlx-* \
+	| elxsi-* \
+	| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
+	| h8300-* | h8500-* \
+	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+	| i*86-* | i860-* | i960-* | ia64-* \
+	| ip2k-* | iq2000-* \
+	| m32r-* | m32rle-* \
+	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+	| m88110-* | m88k-* | maxq-* | mcore-* \
+	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+	| mips16-* \
+	| mips64-* | mips64el-* \
+	| mips64vr-* | mips64vrel-* \
+	| mips64orion-* | mips64orionel-* \
+	| mips64vr4100-* | mips64vr4100el-* \
+	| mips64vr4300-* | mips64vr4300el-* \
+	| mips64vr5000-* | mips64vr5000el-* \
+	| mipsisa32-* | mipsisa32el-* \
+	| mipsisa32r2-* | mipsisa32r2el-* \
+	| mipsisa64-* | mipsisa64el-* \
+	| mipsisa64r2-* | mipsisa64r2el-* \
+	| mipsisa64sb1-* | mipsisa64sb1el-* \
+	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
+	| mipstx39-* | mipstx39el-* \
+	| mmix-* \
+	| msp430-* \
+	| none-* | np1-* | ns16k-* | ns32k-* \
+	| orion-* \
+	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+	| pyramid-* \
+	| romp-* | rs6000-* \
+	| sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \
+	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+	| sparc-* | sparc64-* | sparc64b-* | sparc86x-* | sparclet-* \
+	| sparclite-* \
+	| sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
+	| tahoe-* | thumb-* \
+	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+	| tron-* \
+	| v850-* | v850e-* | vax-* \
+	| we32k-* \
+	| x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \
+	| xstormy16-* | xtensa-* \
+	| ymp-* \
+	| z8k-*)
+		;;
+	# Recognize the various machine names and aliases which stand
+	# for a CPU type and a company and sometimes even an OS.
+	386bsd)
+		basic_machine=i386-unknown
+		os=-bsd
+		;;
+	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+		basic_machine=m68000-att
+		;;
+	3b*)
+		basic_machine=we32k-att
+		;;
+	a29khif)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+    	abacus)
+		basic_machine=abacus-unknown
+		;;
+	adobe68k)
+		basic_machine=m68010-adobe
+		os=-scout
+		;;
+	alliant | fx80)
+		basic_machine=fx80-alliant
+		;;
+	altos | altos3068)
+		basic_machine=m68k-altos
+		;;
+	am29k)
+		basic_machine=a29k-none
+		os=-bsd
+		;;
+	amd64)
+		basic_machine=x86_64-pc
+		;;
+	amd64-*)
+		basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	amdahl)
+		basic_machine=580-amdahl
+		os=-sysv
+		;;
+	amiga | amiga-*)
+		basic_machine=m68k-unknown
+		;;
+	amigaos | amigados)
+		basic_machine=m68k-unknown
+		os=-amigaos
+		;;
+	amigaunix | amix)
+		basic_machine=m68k-unknown
+		os=-sysv4
+		;;
+	apollo68)
+		basic_machine=m68k-apollo
+		os=-sysv
+		;;
+	apollo68bsd)
+		basic_machine=m68k-apollo
+		os=-bsd
+		;;
+	aux)
+		basic_machine=m68k-apple
+		os=-aux
+		;;
+	balance)
+		basic_machine=ns32k-sequent
+		os=-dynix
+		;;
+	c90)
+		basic_machine=c90-cray
+		os=-unicos
+		;;
+	convex-c1)
+		basic_machine=c1-convex
+		os=-bsd
+		;;
+	convex-c2)
+		basic_machine=c2-convex
+		os=-bsd
+		;;
+	convex-c32)
+		basic_machine=c32-convex
+		os=-bsd
+		;;
+	convex-c34)
+		basic_machine=c34-convex
+		os=-bsd
+		;;
+	convex-c38)
+		basic_machine=c38-convex
+		os=-bsd
+		;;
+	cray | j90)
+		basic_machine=j90-cray
+		os=-unicos
+		;;
+	craynv)
+		basic_machine=craynv-cray
+		os=-unicosmp
+		;;
+	cr16c)
+		basic_machine=cr16c-unknown
+		os=-elf
+		;;
+	crds | unos)
+		basic_machine=m68k-crds
+		;;
+	crisv32 | crisv32-* | etraxfs*)
+		basic_machine=crisv32-axis
+		;;
+	cris | cris-* | etrax*)
+		basic_machine=cris-axis
+		;;
+	crx)
+		basic_machine=crx-unknown
+		os=-elf
+		;;
+	da30 | da30-*)
+		basic_machine=m68k-da30
+		;;
+	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+		basic_machine=mips-dec
+		;;
+	decsystem10* | dec10*)
+		basic_machine=pdp10-dec
+		os=-tops10
+		;;
+	decsystem20* | dec20*)
+		basic_machine=pdp10-dec
+		os=-tops20
+		;;
+	delta | 3300 | motorola-3300 | motorola-delta \
+	      | 3300-motorola | delta-motorola)
+		basic_machine=m68k-motorola
+		;;
+	delta88)
+		basic_machine=m88k-motorola
+		os=-sysv3
+		;;
+	djgpp)
+		basic_machine=i586-pc
+		os=-msdosdjgpp
+		;;
+	dpx20 | dpx20-*)
+		basic_machine=rs6000-bull
+		os=-bosx
+		;;
+	dpx2* | dpx2*-bull)
+		basic_machine=m68k-bull
+		os=-sysv3
+		;;
+	ebmon29k)
+		basic_machine=a29k-amd
+		os=-ebmon
+		;;
+	elxsi)
+		basic_machine=elxsi-elxsi
+		os=-bsd
+		;;
+	encore | umax | mmax)
+		basic_machine=ns32k-encore
+		;;
+	es1800 | OSE68k | ose68k | ose | OSE)
+		basic_machine=m68k-ericsson
+		os=-ose
+		;;
+	fx2800)
+		basic_machine=i860-alliant
+		;;
+	genix)
+		basic_machine=ns32k-ns
+		;;
+	gmicro)
+		basic_machine=tron-gmicro
+		os=-sysv
+		;;
+	go32)
+		basic_machine=i386-pc
+		os=-go32
+		;;
+	h3050r* | hiux*)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	h8300hms)
+		basic_machine=h8300-hitachi
+		os=-hms
+		;;
+	h8300xray)
+		basic_machine=h8300-hitachi
+		os=-xray
+		;;
+	h8500hms)
+		basic_machine=h8500-hitachi
+		os=-hms
+		;;
+	harris)
+		basic_machine=m88k-harris
+		os=-sysv3
+		;;
+	hp300-*)
+		basic_machine=m68k-hp
+		;;
+	hp300bsd)
+		basic_machine=m68k-hp
+		os=-bsd
+		;;
+	hp300hpux)
+		basic_machine=m68k-hp
+		os=-hpux
+		;;
+	hp3k9[0-9][0-9] | hp9[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k2[0-9][0-9] | hp9k31[0-9])
+		basic_machine=m68000-hp
+		;;
+	hp9k3[2-9][0-9])
+		basic_machine=m68k-hp
+		;;
+	hp9k6[0-9][0-9] | hp6[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k7[0-79][0-9] | hp7[0-79][0-9])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k78[0-9] | hp78[0-9])
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][13679] | hp8[0-9][13679])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][0-9] | hp8[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hppa-next)
+		os=-nextstep3
+		;;
+	hppaosf)
+		basic_machine=hppa1.1-hp
+		os=-osf
+		;;
+	hppro)
+		basic_machine=hppa1.1-hp
+		os=-proelf
+		;;
+	i370-ibm* | ibm*)
+		basic_machine=i370-ibm
+		;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+	i*86v32)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv32
+		;;
+	i*86v4*)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv4
+		;;
+	i*86v)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv
+		;;
+	i*86sol2)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-solaris2
+		;;
+	i386mach)
+		basic_machine=i386-mach
+		os=-mach
+		;;
+	i386-vsta | vsta)
+		basic_machine=i386-unknown
+		os=-vsta
+		;;
+	iris | iris4d)
+		basic_machine=mips-sgi
+		case $os in
+		    -irix*)
+			;;
+		    *)
+			os=-irix4
+			;;
+		esac
+		;;
+	isi68 | isi)
+		basic_machine=m68k-isi
+		os=-sysv
+		;;
+	m88k-omron*)
+		basic_machine=m88k-omron
+		;;
+	magnum | m3230)
+		basic_machine=mips-mips
+		os=-sysv
+		;;
+	merlin)
+		basic_machine=ns32k-utek
+		os=-sysv
+		;;
+	mingw32)
+		basic_machine=i386-pc
+		os=-mingw32
+		;;
+	miniframe)
+		basic_machine=m68000-convergent
+		;;
+	*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+	mips3*-*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+		;;
+	mips3*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+		;;
+	monitor)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	morphos)
+		basic_machine=powerpc-unknown
+		os=-morphos
+		;;
+	msdos)
+		basic_machine=i386-pc
+		os=-msdos
+		;;
+	mvs)
+		basic_machine=i370-ibm
+		os=-mvs
+		;;
+	ncr3000)
+		basic_machine=i486-ncr
+		os=-sysv4
+		;;
+	netbsd386)
+		basic_machine=i386-unknown
+		os=-netbsd
+		;;
+	netwinder)
+		basic_machine=armv4l-rebel
+		os=-linux
+		;;
+	news | news700 | news800 | news900)
+		basic_machine=m68k-sony
+		os=-newsos
+		;;
+	news1000)
+		basic_machine=m68030-sony
+		os=-newsos
+		;;
+	news-3600 | risc-news)
+		basic_machine=mips-sony
+		os=-newsos
+		;;
+	necv70)
+		basic_machine=v70-nec
+		os=-sysv
+		;;
+	next | m*-next )
+		basic_machine=m68k-next
+		case $os in
+		    -nextstep* )
+			;;
+		    -ns2*)
+		      os=-nextstep2
+			;;
+		    *)
+		      os=-nextstep3
+			;;
+		esac
+		;;
+	nh3000)
+		basic_machine=m68k-harris
+		os=-cxux
+		;;
+	nh[45]000)
+		basic_machine=m88k-harris
+		os=-cxux
+		;;
+	nindy960)
+		basic_machine=i960-intel
+		os=-nindy
+		;;
+	mon960)
+		basic_machine=i960-intel
+		os=-mon960
+		;;
+	nonstopux)
+		basic_machine=mips-compaq
+		os=-nonstopux
+		;;
+	np1)
+		basic_machine=np1-gould
+		;;
+	nsr-tandem)
+		basic_machine=nsr-tandem
+		;;
+	op50n-* | op60c-*)
+		basic_machine=hppa1.1-oki
+		os=-proelf
+		;;
+	or32 | or32-*)
+		basic_machine=or32-unknown
+		os=-coff
+		;;
+	os400)
+		basic_machine=powerpc-ibm
+		os=-os400
+		;;
+	OSE68000 | ose68000)
+		basic_machine=m68000-ericsson
+		os=-ose
+		;;
+	os68k)
+		basic_machine=m68k-none
+		os=-os68k
+		;;
+	pa-hitachi)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	paragon)
+		basic_machine=i860-intel
+		os=-osf
+		;;
+	pbd)
+		basic_machine=sparc-tti
+		;;
+	pbb)
+		basic_machine=m68k-tti
+		;;
+	pc532 | pc532-*)
+		basic_machine=ns32k-pc532
+		;;
+	pentium | p5 | k5 | k6 | nexgen | viac3)
+		basic_machine=i586-pc
+		;;
+	pentiumpro | p6 | 6x86 | athlon | athlon_*)
+		basic_machine=i686-pc
+		;;
+	pentiumii | pentium2 | pentiumiii | pentium3)
+		basic_machine=i686-pc
+		;;
+	pentium4)
+		basic_machine=i786-pc
+		;;
+	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumpro-* | p6-* | 6x86-* | athlon-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium4-*)
+		basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pn)
+		basic_machine=pn-gould
+		;;
+	power)	basic_machine=power-ibm
+		;;
+	ppc)	basic_machine=powerpc-unknown
+		;;
+	ppc-*)	basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppcle | powerpclittle | ppc-le | powerpc-little)
+		basic_machine=powerpcle-unknown
+		;;
+	ppcle-* | powerpclittle-*)
+		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64)	basic_machine=powerpc64-unknown
+		;;
+	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+		basic_machine=powerpc64le-unknown
+		;;
+	ppc64le-* | powerpc64little-*)
+		basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ps2)
+		basic_machine=i386-ibm
+		;;
+	pw32)
+		basic_machine=i586-unknown
+		os=-pw32
+		;;
+	rom68k)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	rm[46]00)
+		basic_machine=mips-siemens
+		;;
+	rtpc | rtpc-*)
+		basic_machine=romp-ibm
+		;;
+	s390 | s390-*)
+		basic_machine=s390-ibm
+		;;
+	s390x | s390x-*)
+		basic_machine=s390x-ibm
+		;;
+	sa29200)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	sb1)
+		basic_machine=mipsisa64sb1-unknown
+		;;
+	sb1el)
+		basic_machine=mipsisa64sb1el-unknown
+		;;
+	sei)
+		basic_machine=mips-sei
+		os=-seiux
+		;;
+	sequent)
+		basic_machine=i386-sequent
+		;;
+	sh)
+		basic_machine=sh-hitachi
+		os=-hms
+		;;
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparclite-wrs | simso-wrs)
+		basic_machine=sparclite-wrs
+		os=-vxworks
+		;;
+	sps7)
+		basic_machine=m68k-bull
+		os=-sysv2
+		;;
+	spur)
+		basic_machine=spur-unknown
+		;;
+	st2000)
+		basic_machine=m68k-tandem
+		;;
+	stratus)
+		basic_machine=i860-stratus
+		os=-sysv4
+		;;
+	sun2)
+		basic_machine=m68000-sun
+		;;
+	sun2os3)
+		basic_machine=m68000-sun
+		os=-sunos3
+		;;
+	sun2os4)
+		basic_machine=m68000-sun
+		os=-sunos4
+		;;
+	sun3os3)
+		basic_machine=m68k-sun
+		os=-sunos3
+		;;
+	sun3os4)
+		basic_machine=m68k-sun
+		os=-sunos4
+		;;
+	sun4os3)
+		basic_machine=sparc-sun
+		os=-sunos3
+		;;
+	sun4os4)
+		basic_machine=sparc-sun
+		os=-sunos4
+		;;
+	sun4sol2)
+		basic_machine=sparc-sun
+		os=-solaris2
+		;;
+	sun3 | sun3-*)
+		basic_machine=m68k-sun
+		;;
+	sun4)
+		basic_machine=sparc-sun
+		;;
+	sun386 | sun386i | roadrunner)
+		basic_machine=i386-sun
+		;;
+	sv1)
+		basic_machine=sv1-cray
+		os=-unicos
+		;;
+	symmetry)
+		basic_machine=i386-sequent
+		os=-dynix
+		;;
+	t3e)
+		basic_machine=alphaev5-cray
+		os=-unicos
+		;;
+	t90)
+		basic_machine=t90-cray
+		os=-unicos
+		;;
+	tic54x | c54x*)
+		basic_machine=tic54x-unknown
+		os=-coff
+		;;
+	tic55x | c55x*)
+		basic_machine=tic55x-unknown
+		os=-coff
+		;;
+	tic6x | c6x*)
+		basic_machine=tic6x-unknown
+		os=-coff
+		;;
+	tx39)
+		basic_machine=mipstx39-unknown
+		;;
+	tx39el)
+		basic_machine=mipstx39el-unknown
+		;;
+	toad1)
+		basic_machine=pdp10-xkl
+		os=-tops20
+		;;
+	tower | tower-32)
+		basic_machine=m68k-ncr
+		;;
+	tpf)
+		basic_machine=s390x-ibm
+		os=-tpf
+		;;
+	udi29k)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	ultra3)
+		basic_machine=a29k-nyu
+		os=-sym1
+		;;
+	v810 | necv810)
+		basic_machine=v810-nec
+		os=-none
+		;;
+	vaxv)
+		basic_machine=vax-dec
+		os=-sysv
+		;;
+	vms)
+		basic_machine=vax-dec
+		os=-vms
+		;;
+	vpp*|vx|vx-*)
+		basic_machine=f301-fujitsu
+		;;
+	vxworks960)
+		basic_machine=i960-wrs
+		os=-vxworks
+		;;
+	vxworks68)
+		basic_machine=m68k-wrs
+		os=-vxworks
+		;;
+	vxworks29k)
+		basic_machine=a29k-wrs
+		os=-vxworks
+		;;
+	w65*)
+		basic_machine=w65-wdc
+		os=-none
+		;;
+	w89k-*)
+		basic_machine=hppa1.1-winbond
+		os=-proelf
+		;;
+	xbox)
+		basic_machine=i686-pc
+		os=-mingw32
+		;;
+	xps | xps100)
+		basic_machine=xps100-honeywell
+		;;
+	ymp)
+		basic_machine=ymp-cray
+		os=-unicos
+		;;
+	z8k-*-coff)
+		basic_machine=z8k-unknown
+		os=-sim
+		;;
+	none)
+		basic_machine=none-none
+		os=-none
+		;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+	w89k)
+		basic_machine=hppa1.1-winbond
+		;;
+	op50n)
+		basic_machine=hppa1.1-oki
+		;;
+	op60c)
+		basic_machine=hppa1.1-oki
+		;;
+	romp)
+		basic_machine=romp-ibm
+		;;
+	mmix)
+		basic_machine=mmix-knuth
+		;;
+	rs6000)
+		basic_machine=rs6000-ibm
+		;;
+	vax)
+		basic_machine=vax-dec
+		;;
+	pdp10)
+		# there are many clones, so DEC is not a safe bet
+		basic_machine=pdp10-unknown
+		;;
+	pdp11)
+		basic_machine=pdp11-dec
+		;;
+	we32k)
+		basic_machine=we32k-att
+		;;
+	sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele)
+		basic_machine=sh-unknown
+		;;
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparc | sparcv8 | sparcv9 | sparcv9b)
+		basic_machine=sparc-sun
+		;;
+	cydra)
+		basic_machine=cydra-cydrome
+		;;
+	orion)
+		basic_machine=orion-highlevel
+		;;
+	orion105)
+		basic_machine=clipper-highlevel
+		;;
+	mac | mpw | mac-mpw)
+		basic_machine=m68k-apple
+		;;
+	pmac | pmac-mpw)
+		basic_machine=powerpc-apple
+		;;
+	*-unknown)
+		# Make sure to match an already-canonicalized machine name.
+		;;
+	*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+	*-digital*)
+		basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+		;;
+	*-commodore*)
+		basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+		;;
+	*)
+		;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+	# -solaris* is a basic system type, with this one exception.
+	-solaris1 | -solaris1.*)
+		os=`echo $os | sed -e 's|solaris1|sunos4|'`
+		;;
+	-solaris)
+		os=-solaris2
+		;;
+	-svr4*)
+		os=-sysv4
+		;;
+	-unixware*)
+		os=-sysv4.2uw
+		;;
+	-gnu/linux*)
+		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+		;;
+	# First accept the basic system types.
+	# The portable systems comes first.
+	# Each alternative MUST END IN A *, to match a version number.
+	# -sysv* is not here because it comes later, after sysvr4.
+	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+	      | -aos* \
+	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \
+	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+	      | -chorusos* | -chorusrdb* \
+	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+	      | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \
+	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly*)
+	# Remember, each alternative MUST END IN *, to match a version number.
+		;;
+	-qnx*)
+		case $basic_machine in
+		    x86-* | i*86-*)
+			;;
+		    *)
+			os=-nto$os
+			;;
+		esac
+		;;
+	-nto-qnx*)
+		;;
+	-nto*)
+		os=`echo $os | sed -e 's|nto|nto-qnx|'`
+		;;
+	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
+	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+		;;
+	-mac*)
+		os=`echo $os | sed -e 's|mac|macos|'`
+		;;
+	-linux-dietlibc)
+		os=-linux-dietlibc
+		;;
+	-linux*)
+		os=`echo $os | sed -e 's|linux|linux-gnu|'`
+		;;
+	-sunos5*)
+		os=`echo $os | sed -e 's|sunos5|solaris2|'`
+		;;
+	-sunos6*)
+		os=`echo $os | sed -e 's|sunos6|solaris3|'`
+		;;
+	-opened*)
+		os=-openedition
+		;;
+        -os400*)
+		os=-os400
+		;;
+	-wince*)
+		os=-wince
+		;;
+	-osfrose*)
+		os=-osfrose
+		;;
+	-osf*)
+		os=-osf
+		;;
+	-utek*)
+		os=-bsd
+		;;
+	-dynix*)
+		os=-bsd
+		;;
+	-acis*)
+		os=-aos
+		;;
+	-atheos*)
+		os=-atheos
+		;;
+	-syllable*)
+		os=-syllable
+		;;
+	-386bsd)
+		os=-bsd
+		;;
+	-ctix* | -uts*)
+		os=-sysv
+		;;
+	-nova*)
+		os=-rtmk-nova
+		;;
+	-ns2 )
+		os=-nextstep2
+		;;
+	-nsk*)
+		os=-nsk
+		;;
+	# Preserve the version number of sinix5.
+	-sinix5.*)
+		os=`echo $os | sed -e 's|sinix|sysv|'`
+		;;
+	-sinix*)
+		os=-sysv4
+		;;
+        -tpf*)
+		os=-tpf
+		;;
+	-triton*)
+		os=-sysv3
+		;;
+	-oss*)
+		os=-sysv3
+		;;
+	-svr4)
+		os=-sysv4
+		;;
+	-svr3)
+		os=-sysv3
+		;;
+	-sysvr4)
+		os=-sysv4
+		;;
+	# This must come after -sysvr4.
+	-sysv*)
+		;;
+	-ose*)
+		os=-ose
+		;;
+	-es1800*)
+		os=-ose
+		;;
+	-xenix)
+		os=-xenix
+		;;
+	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+		os=-mint
+		;;
+	-aros*)
+		os=-aros
+		;;
+	-kaos*)
+		os=-kaos
+		;;
+	-zvmoe)
+		os=-zvmoe
+		;;
+	-none)
+		;;
+	*)
+		# Get rid of the `-' at the beginning of $os.
+		os=`echo $os | sed 's/[^-]*-//'`
+		echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+		exit 1
+		;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+	*-acorn)
+		os=-riscix1.2
+		;;
+	arm*-rebel)
+		os=-linux
+		;;
+	arm*-semi)
+		os=-aout
+		;;
+    c4x-* | tic4x-*)
+        os=-coff
+        ;;
+	# This must come before the *-dec entry.
+	pdp10-*)
+		os=-tops20
+		;;
+	pdp11-*)
+		os=-none
+		;;
+	*-dec | vax-*)
+		os=-ultrix4.2
+		;;
+	m68*-apollo)
+		os=-domain
+		;;
+	i386-sun)
+		os=-sunos4.0.2
+		;;
+	m68000-sun)
+		os=-sunos3
+		# This also exists in the configure program, but was not the
+		# default.
+		# os=-sunos4
+		;;
+	m68*-cisco)
+		os=-aout
+		;;
+	mips*-cisco)
+		os=-elf
+		;;
+	mips*-*)
+		os=-elf
+		;;
+	or32-*)
+		os=-coff
+		;;
+	*-tti)	# must be before sparc entry or we get the wrong os.
+		os=-sysv3
+		;;
+	sparc-* | *-sun)
+		os=-sunos4.1.1
+		;;
+	*-be)
+		os=-beos
+		;;
+	*-ibm)
+		os=-aix
+		;;
+    	*-knuth)
+		os=-mmixware
+		;;
+	*-wec)
+		os=-proelf
+		;;
+	*-winbond)
+		os=-proelf
+		;;
+	*-oki)
+		os=-proelf
+		;;
+	*-hp)
+		os=-hpux
+		;;
+	*-hitachi)
+		os=-hiux
+		;;
+	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+		os=-sysv
+		;;
+	*-cbm)
+		os=-amigaos
+		;;
+	*-dg)
+		os=-dgux
+		;;
+	*-dolphin)
+		os=-sysv3
+		;;
+	m68k-ccur)
+		os=-rtu
+		;;
+	m88k-omron*)
+		os=-luna
+		;;
+	*-next )
+		os=-nextstep
+		;;
+	*-sequent)
+		os=-ptx
+		;;
+	*-crds)
+		os=-unos
+		;;
+	*-ns)
+		os=-genix
+		;;
+	i370-*)
+		os=-mvs
+		;;
+	*-next)
+		os=-nextstep3
+		;;
+	*-gould)
+		os=-sysv
+		;;
+	*-highlevel)
+		os=-bsd
+		;;
+	*-encore)
+		os=-bsd
+		;;
+	*-sgi)
+		os=-irix
+		;;
+	*-siemens)
+		os=-sysv4
+		;;
+	*-masscomp)
+		os=-rtu
+		;;
+	f30[01]-fujitsu | f700-fujitsu)
+		os=-uxpv
+		;;
+	*-rom68k)
+		os=-coff
+		;;
+	*-*bug)
+		os=-coff
+		;;
+	*-apple)
+		os=-macos
+		;;
+	*-atari*)
+		os=-mint
+		;;
+	*)
+		os=-none
+		;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+	*-unknown)
+		case $os in
+			-riscix*)
+				vendor=acorn
+				;;
+			-sunos*)
+				vendor=sun
+				;;
+			-aix*)
+				vendor=ibm
+				;;
+			-beos*)
+				vendor=be
+				;;
+			-hpux*)
+				vendor=hp
+				;;
+			-mpeix*)
+				vendor=hp
+				;;
+			-hiux*)
+				vendor=hitachi
+				;;
+			-unos*)
+				vendor=crds
+				;;
+			-dgux*)
+				vendor=dg
+				;;
+			-luna*)
+				vendor=omron
+				;;
+			-genix*)
+				vendor=ns
+				;;
+			-mvs* | -opened*)
+				vendor=ibm
+				;;
+			-os400*)
+				vendor=ibm
+				;;
+			-ptx*)
+				vendor=sequent
+				;;
+			-tpf*)
+				vendor=ibm
+				;;
+			-vxsim* | -vxworks* | -windiss*)
+				vendor=wrs
+				;;
+			-aux*)
+				vendor=apple
+				;;
+			-hms*)
+				vendor=hitachi
+				;;
+			-mpw* | -macos*)
+				vendor=apple
+				;;
+			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+				vendor=atari
+				;;
+			-vos*)
+				vendor=stratus
+				;;
+		esac
+		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+		;;
+esac
+
+echo $basic_machine$os
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:


Property changes on: vendor/Python/current/Modules/_ctypes/libffi/config.sub
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Modules/_ctypes/libffi/configure.ac
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/configure.ac	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/configure.ac	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,243 @@
+dnl Process this with autoconf to create configure
+
+AC_PREREQ(2.59)
+
+AC_INIT([libffi], [2.1], [http://gcc.gnu.org/bugs.html])
+AC_CONFIG_HEADERS([fficonfig.h])
+
+AC_CANONICAL_SYSTEM
+target_alias=${target_alias-$host_alias}
+
+m4_rename([_AC_ARG_VAR_PRECIOUS],[real_PRECIOUS])
+m4_define([_AC_ARG_VAR_PRECIOUS],[])
+AC_PROG_CC
+m4_rename([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS])
+
+AC_SUBST(CFLAGS)
+
+AC_CHECK_HEADERS(sys/mman.h)
+AC_CHECK_FUNCS(mmap)
+AC_FUNC_MMAP_BLACKLIST
+
+TARGETDIR="unknown"
+case "$host" in
+x86_64-*-openbsd*) TARGET=X86_64; TARGETDIR=x86;;
+mips*-*-openbsd*) TARGET=MIPS; TARGETDIR=mips;;
+sparc-*-openbsd*) TARGET=SPARC; TARGETDIR=sparc;;
+sparc64-*-openbsd*) TARGET=SPARC; TARGETDIR=sparc;;
+alpha*-*-openbsd*) TARGET=ALPHA; TARGETDIR=alpha;;
+m68k-*-openbsd*) TARGET=M68K; TARGETDIR=m68k;;
+powerpc-*-openbsd*) TARGET=POWERPC; TARGETDIR=powerpc;;
+i*86-*-darwin*) TARGET=X86_DARWIN; TARGETDIR=x86;;
+i*86-*-linux*) TARGET=X86; TARGETDIR=x86;;
+i*86-*-gnu*) TARGET=X86; TARGETDIR=x86;;
+i*86-*-solaris2.1[[0-9]]*) TARGET=X86_64; TARGETDIR=x86;;
+i*86-*-solaris*) TARGET=X86; TARGETDIR=x86;;
+i*86-*-beos*) TARGET=X86; TARGETDIR=x86;;
+i*86-*-freebsd* | i*86-*-kfreebsd*-gnu) TARGET=X86; TARGETDIR=x86;;
+i*86-*-netbsdelf* | i*86-*-knetbsd*-gnu) TARGET=X86; TARGETDIR=x86;;
+i*86-*-openbsd*) TARGET=X86; TARGETDIR=x86;;
+i*86-*-rtems*) TARGET=X86; TARGETDIR=x86;;
+i*86-*-win32*) TARGET=X86_WIN32; TARGETDIR=x86;;
+i*86-*-cygwin*) TARGET=X86_WIN32; TARGETDIR=x86;;
+i*86-*-mingw*) TARGET=X86_WIN32; TARGETDIR=x86;;
+frv-*-*) TARGET=FRV; TARGETDIR=frv;;
+sparc-sun-4*) TARGET=SPARC; TARGETDIR=sparc;;
+sparc*-sun-*) TARGET=SPARC; TARGETDIR=sparc;;
+sparc-*-linux* | sparc-*-netbsdelf* | sparc-*-knetbsd*-gnu) TARGET=SPARC; TARGETDIR=sparc;;
+sparc*-*-rtems*) TARGET=SPARC; TARGETDIR=sparc;;
+sparc64-*-linux* | sparc64-*-freebsd* | sparc64-*-netbsd* | sparc64-*-knetbsd*-gnu) TARGET=SPARC; TARGETDIR=sparc;;
+alpha*-*-linux* | alpha*-*-osf* | alpha*-*-freebsd* | alpha*-*-kfreebsd*-gnu | alpha*-*-netbsd* | alpha*-*-knetbsd*-gnu) TARGET=ALPHA; TARGETDIR=alpha;;
+ia64*-*-*) TARGET=IA64; TARGETDIR=ia64;;
+m32r*-*-linux* ) TARGET=M32R; TARGETDIR=m32r;;
+m68k-*-linux*) TARGET=M68K; TARGETDIR=m68k;;
+mips64*-*);;
+mips-sgi-irix5.* | mips-sgi-irix6.*) TARGET=MIPS_IRIX; TARGETDIR=mips;;
+mips*-*-linux*) TARGET=MIPS_LINUX; TARGETDIR=mips;;
+powerpc*-*-linux* | powerpc-*-sysv*) TARGET=POWERPC; TARGETDIR=powerpc;;
+powerpc-*-beos*) TARGET=POWERPC; TARGETDIR=powerpc;;
+powerpc-*-darwin*) TARGET=POWERPC_DARWIN; TARGETDIR=powerpc;;
+powerpc-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;;
+powerpc-*-freebsd*) TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc;;
+powerpc*-*-rtems*) TARGET=POWERPC; TARGETDIR=powerpc;;
+rs6000-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;;
+arm*-*-linux-*) TARGET=ARM; TARGETDIR=arm;;
+arm*-*-netbsdelf* | arm*-*-knetbsd*-gnu) TARGET=ARM; TARGETDIR=arm;;
+arm*-*-rtems*) TARGET=ARM; TARGETDIR=arm;;
+cris-*-*) TARGET=LIBFFI_CRIS; TARGETDIR=cris;;
+s390-*-linux-*) TARGET=S390; TARGETDIR=s390;;
+s390x-*-linux-*) TARGET=S390; TARGETDIR=s390;;
+x86_64-*-linux* | x86_64-*-freebsd* | x86_64-*-kfreebsd*-gnu) TARGET=X86_64; TARGETDIR=x86;;
+sh-*-linux* | sh[[34]]*-*-linux*) TARGET=SH; TARGETDIR=sh;;
+sh-*-rtems*) TARGET=SH; TARGETDIR=sh;;
+sh64-*-linux* | sh5*-*-linux*) TARGET=SH64; TARGETDIR=sh64;;
+hppa-*-linux* | parisc-*-linux*) TARGET=PA; TARGETDIR=pa;;
+esac
+
+if test $TARGETDIR = unknown; then
+  AC_MSG_ERROR(["libffi has not been ported to $host."])
+fi
+
+dnl  libffi changes TARGET for MIPS to define a such macro in the header
+dnl  while MIPS_IRIX or MIPS_LINUX is separatedly used to decide which
+dnl  files will be compiled.  So, we need to keep the original decision
+dnl  of TARGET to use in fficonfig.py.in.
+MKTARGET=$TARGET
+
+case x$TARGET in
+  xMIPS*) TARGET=MIPS ;;
+  *) ;;
+esac
+
+AC_HEADER_STDC
+AC_CHECK_FUNCS(memcpy)
+AC_FUNC_ALLOCA
+
+AC_CHECK_SIZEOF(double)
+AC_CHECK_SIZEOF(long double)
+
+# Also AC_SUBST this variable for ffi.h.
+HAVE_LONG_DOUBLE=0
+if test $ac_cv_sizeof_double != $ac_cv_sizeof_long_double; then
+  if test $ac_cv_sizeof_long_double != 0; then
+    HAVE_LONG_DOUBLE=1
+    AC_DEFINE(HAVE_LONG_DOUBLE, 1, [Define if you have the long double type and it is bigger than a double])
+  fi
+fi
+AC_SUBST(HAVE_LONG_DOUBLE)
+
+AC_C_BIGENDIAN
+AH_VERBATIM([WORDS_BIGENDIAN],
+[
+/* Define to 1 if your processor stores words with the most significant byte
+   first (like Motorola and SPARC, unlike Intel and VAX). 
+
+   The block below does compile-time checking for endianness on platforms
+   that use GCC and therefore allows compiling fat binaries on OSX by using
+   '-arch ppc -arch i386' as the compile flags. The phrasing was choosen
+   such that the configure-result is used on systems that don't use GCC.
+*/
+#ifdef __BIG_ENDIAN__
+#define WORDS_BIGENDIAN 1
+#else
+#ifndef __LITTLE_ENDIAN__
+#undef WORDS_BIGENDIAN
+#endif
+#endif])
+
+
+if test x$TARGET = xSPARC; then
+    AC_CACHE_CHECK([assembler and linker support unaligned pc related relocs],
+	libffi_cv_as_sparc_ua_pcrel, [
+	save_CFLAGS="$CFLAGS"
+	save_LDFLAGS="$LDFLAGS"
+	CFLAGS="$CFLAGS -fpic"
+	LDFLAGS="$LDFLAGS -shared"
+	AC_TRY_LINK([asm (".text; foo: nop; .data; .align 4; .byte 0; .uaword %r_disp32(foo); .text");],,
+		    [libffi_cv_as_sparc_ua_pcrel=yes],
+		    [libffi_cv_as_sparc_ua_pcrel=no])
+	CFLAGS="$save_CFLAGS"
+	LDFLAGS="$save_LDFLAGS"])
+    if test "x$libffi_cv_as_sparc_ua_pcrel" = xyes; then
+	AC_DEFINE(HAVE_AS_SPARC_UA_PCREL, 1,
+		  [Define if your assembler and linker support unaligned PC relative relocs.])
+    fi
+
+    AC_CACHE_CHECK([assembler .register pseudo-op support],
+       libffi_cv_as_register_pseudo_op, [
+       libffi_cv_as_register_pseudo_op=unknown
+       # Check if we have .register
+       AC_TRY_COMPILE([asm (".register %g2, #scratch");],,
+		       [libffi_cv_as_register_pseudo_op=yes],
+		       [libffi_cv_as_register_pseudo_op=no])
+    ])
+    if test "x$libffi_cv_as_register_pseudo_op" = xyes; then
+       AC_DEFINE(HAVE_AS_REGISTER_PSEUDO_OP, 1,
+	       [Define if your assembler supports .register.])
+    fi
+fi
+
+AC_CACHE_CHECK([whether .eh_frame section should be read-only],
+    libffi_cv_ro_eh_frame, [
+	libffi_cv_ro_eh_frame=no
+	echo 'extern void foo (void); void bar (void) { foo (); foo (); }' > conftest.c
+	if $CC $CFLAGS -S -fpic -fexceptions -o conftest.s conftest.c > /dev/null 2>&1; then
+	    if grep '.section.*eh_frame.*"a"' conftest.s > /dev/null; then
+		libffi_cv_ro_eh_frame=yes
+	    elif grep '.section.*eh_frame.*#alloc' conftest.c \
+		 | grep -v '#write' > /dev/null; then
+		libffi_cv_ro_eh_frame=yes
+	    fi
+	fi
+	rm -f conftest.*
+    ])
+if test "x$libffi_cv_ro_eh_frame" = xyes; then
+    AC_DEFINE(HAVE_RO_EH_FRAME, 1,
+	      [Define if .eh_frame sections should be read-only.])
+    AC_DEFINE(EH_FRAME_FLAGS, "a",
+	      [Define to the flags needed for the .section .eh_frame directive.])
+else
+    AC_DEFINE(EH_FRAME_FLAGS, "aw",
+	      [Define to the flags needed for the .section .eh_frame directive.])
+fi
+
+AC_CACHE_CHECK([for __attribute__((visibility("hidden")))],
+    libffi_cv_hidden_visibility_attribute, [
+	echo 'int __attribute__ ((visibility ("hidden"))) foo (void) { return 1; }' > conftest.c
+	libffi_cv_hidden_visibility_attribute=no
+	if AC_TRY_COMMAND(${CC-cc} -Werror -S conftest.c -o conftest.s 1>&AS_MESSAGE_LOG_FD); then
+	    if grep '\.hidden.*foo' conftest.s >/dev/null; then
+		libffi_cv_hidden_visibility_attribute=yes
+	    fi
+	fi
+	rm -f conftest.*
+    ])
+if test $libffi_cv_hidden_visibility_attribute = yes; then
+    AC_DEFINE(HAVE_HIDDEN_VISIBILITY_ATTRIBUTE, 1,
+	      [Define if __attribute__((visibility("hidden"))) is supported.])
+fi
+
+AH_BOTTOM([
+#ifdef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
+#ifdef LIBFFI_ASM
+#define FFI_HIDDEN(name) .hidden name
+#else
+#define FFI_HIDDEN __attribute__ ((visibility ("hidden")))
+#endif
+#else
+#ifdef LIBFFI_ASM
+#define FFI_HIDDEN(name)
+#else
+#define FFI_HIDDEN
+#endif
+#endif
+])
+
+AC_SUBST(TARGET)
+AC_SUBST(TARGETDIR)
+AC_SUBST(MKTARGET)
+
+AC_SUBST(SHELL)
+
+AC_DEFINE(FFI_NO_RAW_API, 1, [Define this is you do not want support for the raw API.])
+
+AC_CONFIG_COMMANDS(include, [test -d include || mkdir include])
+AC_CONFIG_COMMANDS(src, [
+test -d src || mkdir src
+test -d src/$TARGETDIR || mkdir src/$TARGETDIR
+], [TARGETDIR="$TARGETDIR"])
+
+TARGETINCDIR=$TARGETDIR
+case $host in
+*-*-darwin*)
+   TARGETINCDIR="darwin"
+   ;;
+esac
+
+
+AC_CONFIG_LINKS(include/ffitarget.h:src/$TARGETINCDIR/ffitarget.h)
+AC_CONFIG_LINKS(include/ffi_common.h:include/ffi_common.h)
+
+AC_CONFIG_FILES(include/ffi.h fficonfig.py)
+
+AC_OUTPUT

Added: vendor/Python/current/Modules/_ctypes/libffi/fficonfig.h.in
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/fficonfig.h.in	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/fficonfig.h.in	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,148 @@
+/* fficonfig.h.in.  Generated from configure.ac by autoheader.  */
+
+/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
+   systems. This function is required for `alloca.c' support on those systems.
+   */
+#undef CRAY_STACKSEG_END
+
+/* Define to 1 if using `alloca.c'. */
+#undef C_ALLOCA
+
+/* Define to the flags needed for the .section .eh_frame directive. */
+#undef EH_FRAME_FLAGS
+
+/* Define this is you do not want support for the raw API. */
+#undef FFI_NO_RAW_API
+
+/* Define to 1 if you have `alloca', as a function or macro. */
+#undef HAVE_ALLOCA
+
+/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
+   */
+#undef HAVE_ALLOCA_H
+
+/* Define if your assembler supports .register. */
+#undef HAVE_AS_REGISTER_PSEUDO_OP
+
+/* Define if your assembler and linker support unaligned PC relative relocs.
+   */
+#undef HAVE_AS_SPARC_UA_PCREL
+
+/* Define if __attribute__((visibility("hidden"))) is supported. */
+#undef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define if you have the long double type and it is bigger than a double */
+#undef HAVE_LONG_DOUBLE
+
+/* Define to 1 if you have the `memcpy' function. */
+#undef HAVE_MEMCPY
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `mmap' function. */
+#undef HAVE_MMAP
+
+/* Define if mmap with MAP_ANON(YMOUS) works. */
+#undef HAVE_MMAP_ANON
+
+/* Define if mmap of /dev/zero works. */
+#undef HAVE_MMAP_DEV_ZERO
+
+/* Define if read-only mmap of a plain file works. */
+#undef HAVE_MMAP_FILE
+
+/* Define if .eh_frame sections should be read-only. */
+#undef HAVE_RO_EH_FRAME
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <sys/mman.h> header file. */
+#undef HAVE_SYS_MMAN_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* The size of a `double', as computed by sizeof. */
+#undef SIZEOF_DOUBLE
+
+/* The size of a `long double', as computed by sizeof. */
+#undef SIZEOF_LONG_DOUBLE
+
+/* If using the C implementation of alloca, define if you know the
+   direction of stack growth for your system; otherwise it will be
+   automatically deduced at run-time.
+	STACK_DIRECTION > 0 => grows toward higher addresses
+	STACK_DIRECTION < 0 => grows toward lower addresses
+	STACK_DIRECTION = 0 => direction of growth unknown */
+#undef STACK_DIRECTION
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+
+/* Define to 1 if your processor stores words with the most significant byte
+   first (like Motorola and SPARC, unlike Intel and VAX). 
+
+   The block below does compile-time checking for endianness on platforms
+   that use GCC and therefore allows compiling fat binaries on OSX by using
+   '-arch ppc -arch i386' as the compile flags. The phrasing was choosen
+   such that the configure-result is used on systems that don't use GCC.
+*/
+#ifdef __BIG_ENDIAN__
+#define WORDS_BIGENDIAN 1
+#else
+#ifndef __LITTLE_ENDIAN__
+#undef WORDS_BIGENDIAN
+#endif
+#endif
+
+
+#ifdef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
+#ifdef LIBFFI_ASM
+#define FFI_HIDDEN(name) .hidden name
+#else
+#define FFI_HIDDEN __attribute__ ((visibility ("hidden")))
+#endif
+#else
+#ifdef LIBFFI_ASM
+#define FFI_HIDDEN(name)
+#else
+#define FFI_HIDDEN
+#endif
+#endif
+

Added: vendor/Python/current/Modules/_ctypes/libffi/fficonfig.py.in
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/fficonfig.py.in	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/fficonfig.py.in	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,45 @@
+ffi_sources = """
+src/prep_cif.c
+""".split()
+
+ffi_platforms = {
+    'MIPS_IRIX': ['src/mips/ffi.c', 'src/mips/o32.S', 'src/mips/n32.S'],
+    'MIPS_LINUX': ['src/mips/ffi.c', 'src/mips/o32.S'],
+    'X86': ['src/x86/ffi.c', 'src/x86/sysv.S'],
+    'X86_DARWIN': ['src/x86/ffi_darwin.c', 'src/x86/darwin.S'],
+    'X86_WIN32': ['src/x86/ffi.c', 'src/x86/win32.S'],
+    'SPARC': ['src/sparc/ffi.c', 'src/sparc/v8.S', 'src/sparc/v9.S'],
+    'ALPHA': ['src/alpha/ffi.c', 'src/alpha/osf.S'],
+    'IA64': ['src/ia64/ffi.c', 'src/ia64/unix.S'],
+    'M32R': ['src/m32r/sysv.S', 'src/m32r/ffi.c'],
+    'M68K': ['src/m68k/ffi.c', 'src/m68k/sysv.S'],
+    'POWERPC': ['src/powerpc/ffi.c', 'src/powerpc/sysv.S', 'src/powerpc/ppc_closure.S', 'src/powerpc/linux64.S', 'src/powerpc/linux64_closure.S'],
+    'POWERPC_AIX': ['src/powerpc/ffi_darwin.c', 'src/powerpc/aix.S', 'src/powerpc/aix_closure.S'],
+    'POWERPC_DARWIN': ['src/powerpc/ffi_darwin.c', 'src/powerpc/darwin.S', 'src/powerpc/darwin_closure.S'],
+    'POWERPC_FREEBSD': ['src/powerpc/ffi.c', 'src/powerpc/sysv.S', 'src/powerpc/ppc_closure.S'],
+    'ARM': ['src/arm/sysv.S', 'src/arm/ffi.c'],
+    'LIBFFI_CRIS': ['src/cris/sysv.S', 'src/cris/ffi.c'],
+    'FRV': ['src/frv/eabi.S', 'src/frv/ffi.c'],
+    'S390': ['src/s390/sysv.S', 'src/s390/ffi.c'],
+    'X86_64': ['src/x86/ffi64.c', 'src/x86/unix64.S', 'src/x86/ffi.c', 'src/x86/sysv.S'],
+    'SH': ['src/sh/sysv.S', 'src/sh/ffi.c'],
+    'SH64': ['src/sh64/sysv.S', 'src/sh64/ffi.c'],
+    'PA': ['src/pa/linux.S', 'src/pa/ffi.c'],
+}
+
+# Build all darwin related files on all supported darwin architectures, this
+# makes it easier to build universal binaries.
+if 1:
+    all_darwin = ('X86_DARWIN', 'POWERPC_DARWIN')
+    all_darwin_files = []
+    for pn in all_darwin:
+        all_darwin_files.extend(ffi_platforms[pn])
+    for pn in all_darwin:
+        ffi_platforms[pn] = all_darwin_files
+    del all_darwin, all_darwin_files, pn
+
+ffi_srcdir = '@srcdir@'
+ffi_sources += ffi_platforms['@MKTARGET@']
+ffi_sources = [os.path.join('@srcdir@', f) for f in ffi_sources]
+
+ffi_cflags = '@CFLAGS@'

Added: vendor/Python/current/Modules/_ctypes/libffi/include/ffi.h.in
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/include/ffi.h.in	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/include/ffi.h.in	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,313 @@
+/* -----------------------------------------------------------------*-C-*-
+   libffi @VERSION@ - Copyright (c) 1996-2003  Red Hat, Inc.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+
+   ----------------------------------------------------------------------- */
+
+/* -------------------------------------------------------------------
+   The basic API is described in the README file.
+
+   The raw API is designed to bypass some of the argument packing
+   and unpacking on architectures for which it can be avoided.
+
+   The closure API allows interpreted functions to be packaged up
+   inside a C function pointer, so that they can be called as C functions,
+   with no understanding on the client side that they are interpreted.
+   It can also be used in other cases in which it is necessary to package
+   up a user specified parameter and a function pointer as a single
+   function pointer.
+
+   The closure API must be implemented in order to get its functionality,
+   e.g. for use by gij.  Routines are provided to emulate the raw API
+   if the underlying platform doesn't allow faster implementation.
+
+   More details on the raw and cloure API can be found in:
+
+   http://gcc.gnu.org/ml/java/1999-q3/msg00138.html
+
+   and
+
+   http://gcc.gnu.org/ml/java/1999-q3/msg00174.html
+   -------------------------------------------------------------------- */
+
+#ifndef LIBFFI_H
+#define LIBFFI_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Specify which architecture libffi is configured for. */
+#define @TARGET@
+
+/* ---- System configuration information --------------------------------- */
+
+#include <ffitarget.h>
+
+#ifndef LIBFFI_ASM
+
+#include <stddef.h>
+#include <limits.h>
+
+/* LONG_LONG_MAX is not always defined (not if STRICT_ANSI, for example).
+   But we can find it either under the correct ANSI name, or under GNU
+   C's internal name.  */
+#ifdef LONG_LONG_MAX
+# define FFI_LONG_LONG_MAX LONG_LONG_MAX
+#else
+# ifdef LLONG_MAX
+#  define FFI_LONG_LONG_MAX LLONG_MAX
+# else
+#  ifdef __GNUC__
+#   define FFI_LONG_LONG_MAX __LONG_LONG_MAX__
+#  endif
+# endif
+#endif
+
+#if SCHAR_MAX == 127
+# define ffi_type_uchar                ffi_type_uint8
+# define ffi_type_schar                ffi_type_sint8
+#else
+ #error "char size not supported"
+#endif
+
+#if SHRT_MAX == 32767
+# define ffi_type_ushort       ffi_type_uint16
+# define ffi_type_sshort       ffi_type_sint16
+#elif SHRT_MAX == 2147483647
+# define ffi_type_ushort       ffi_type_uint32
+# define ffi_type_sshort       ffi_type_sint32
+#else
+ #error "short size not supported"
+#endif
+
+#if INT_MAX == 32767
+# define ffi_type_uint         ffi_type_uint16
+# define ffi_type_sint         ffi_type_sint16
+#elif INT_MAX == 2147483647
+# define ffi_type_uint         ffi_type_uint32
+# define ffi_type_sint         ffi_type_sint32
+#elif INT_MAX == 9223372036854775807
+# define ffi_type_uint         ffi_type_uint64
+# define ffi_type_sint         ffi_type_sint64
+#else
+ #error "int size not supported"
+#endif
+
+#define ffi_type_ulong         ffi_type_uint64
+#define ffi_type_slong         ffi_type_sint64
+#if LONG_MAX == 2147483647
+# if FFI_LONG_LONG_MAX != 9223372036854775807
+  #error "no 64-bit data type supported"
+# endif
+#elif LONG_MAX != 9223372036854775807
+ #error "long size not supported"
+#endif
+
+/* The closure code assumes that this works on pointers, i.e. a size_t	*/
+/* can hold a pointer.							*/
+
+typedef struct _ffi_type
+{
+  size_t size;
+  unsigned short alignment;
+  unsigned short type;
+  /*@null@*/ struct _ffi_type **elements;
+} ffi_type;
+
+/* These are defined in types.c */
+extern ffi_type ffi_type_void;
+extern ffi_type ffi_type_uint8;
+extern ffi_type ffi_type_sint8;
+extern ffi_type ffi_type_uint16;
+extern ffi_type ffi_type_sint16;
+extern ffi_type ffi_type_uint32;
+extern ffi_type ffi_type_sint32;
+extern ffi_type ffi_type_uint64;
+extern ffi_type ffi_type_sint64;
+extern ffi_type ffi_type_float;
+extern ffi_type ffi_type_double;
+extern ffi_type ffi_type_longdouble;
+extern ffi_type ffi_type_pointer;
+
+
+typedef enum {
+  FFI_OK = 0,
+  FFI_BAD_TYPEDEF,
+  FFI_BAD_ABI 
+} ffi_status;
+
+typedef unsigned FFI_TYPE;
+
+typedef struct {
+  ffi_abi abi;
+  unsigned nargs;
+  /*@dependent@*/ ffi_type **arg_types;
+  /*@dependent@*/ ffi_type *rtype;
+  unsigned bytes;
+  unsigned flags;
+#ifdef FFI_EXTRA_CIF_FIELDS
+  FFI_EXTRA_CIF_FIELDS;
+#endif
+} ffi_cif;
+
+/* ---- Definitions for the raw API -------------------------------------- */
+
+#ifndef FFI_SIZEOF_ARG
+# if LONG_MAX == 2147483647
+#  define FFI_SIZEOF_ARG        4
+# elif LONG_MAX == 9223372036854775807
+#  define FFI_SIZEOF_ARG        8
+# endif
+#endif
+
+typedef union {
+  ffi_sarg  sint;
+  ffi_arg   uint;
+  float	    flt;
+  char      data[FFI_SIZEOF_ARG];
+  void*     ptr;
+} ffi_raw;
+
+void ffi_raw_call (/*@dependent@*/ ffi_cif *cif, 
+		   void (*fn)(void), 
+		   /*@out@*/ void *rvalue, 
+		   /*@dependent@*/ ffi_raw *avalue);
+
+void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
+void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
+size_t ffi_raw_size (ffi_cif *cif);
+
+/* This is analogous to the raw API, except it uses Java parameter	*/
+/* packing, even on 64-bit machines.  I.e. on 64-bit machines		*/
+/* longs and doubles are followed by an empty 64-bit word.		*/
+
+void ffi_java_raw_call (/*@dependent@*/ ffi_cif *cif, 
+		        void (*fn)(void), 
+		        /*@out@*/ void *rvalue, 
+		        /*@dependent@*/ ffi_raw *avalue);
+
+void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
+void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
+size_t ffi_java_raw_size (ffi_cif *cif);
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#if FFI_CLOSURES
+
+typedef struct {
+  char tramp[FFI_TRAMPOLINE_SIZE];
+  ffi_cif   *cif;
+  void     (*fun)(ffi_cif*,void*,void**,void*);
+  void      *user_data;
+} ffi_closure __attribute__((aligned (8)));
+
+ffi_status
+ffi_prep_closure (ffi_closure*,
+		  ffi_cif *,
+		  void (*fun)(ffi_cif*,void*,void**,void*),
+		  void *user_data);
+
+typedef struct {
+  char tramp[FFI_TRAMPOLINE_SIZE];
+
+  ffi_cif   *cif;
+
+#if !FFI_NATIVE_RAW_API
+
+  /* if this is enabled, then a raw closure has the same layout 
+     as a regular closure.  We use this to install an intermediate 
+     handler to do the transaltion, void** -> ffi_raw*. */
+
+  void     (*translate_args)(ffi_cif*,void*,void**,void*);
+  void      *this_closure;
+
+#endif
+
+  void     (*fun)(ffi_cif*,void*,ffi_raw*,void*);
+  void      *user_data;
+
+} ffi_raw_closure;
+
+ffi_status
+ffi_prep_raw_closure (ffi_raw_closure*,
+		      ffi_cif *cif,
+		      void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
+		      void *user_data);
+
+ffi_status
+ffi_prep_java_raw_closure (ffi_raw_closure*,
+		           ffi_cif *cif,
+		           void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
+		           void *user_data);
+
+#endif /* FFI_CLOSURES */
+
+/* ---- Public interface definition -------------------------------------- */
+
+ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif, 
+			ffi_abi abi,
+			unsigned int nargs, 
+			/*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type *rtype, 
+			/*@dependent@*/ ffi_type **atypes);
+
+void ffi_call(/*@dependent@*/ ffi_cif *cif, 
+	      void (*fn)(void), 
+	      /*@out@*/ void *rvalue, 
+	      /*@dependent@*/ void **avalue);
+
+/* Useful for eliminating compiler warnings */
+#define FFI_FN(f) ((void (*)())f)
+
+/* ---- Definitions shared with assembly code ---------------------------- */
+
+#endif
+
+/* If these change, update src/mips/ffitarget.h. */
+#define FFI_TYPE_VOID       0    
+#define FFI_TYPE_INT        1
+#define FFI_TYPE_FLOAT      2    
+#define FFI_TYPE_DOUBLE     3
+#if @HAVE_LONG_DOUBLE@
+#define FFI_TYPE_LONGDOUBLE 4
+#else
+#define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE
+#endif
+#define FFI_TYPE_UINT8      5   
+#define FFI_TYPE_SINT8      6
+#define FFI_TYPE_UINT16     7 
+#define FFI_TYPE_SINT16     8
+#define FFI_TYPE_UINT32     9
+#define FFI_TYPE_SINT32     10
+#define FFI_TYPE_UINT64     11
+#define FFI_TYPE_SINT64     12
+#define FFI_TYPE_STRUCT     13
+#define FFI_TYPE_POINTER    14
+
+/* This should always refer to the last type code (for sanity checks) */
+#define FFI_TYPE_LAST       FFI_TYPE_POINTER
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+

Added: vendor/Python/current/Modules/_ctypes/libffi/include/ffi_common.h
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/include/ffi_common.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/include/ffi_common.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,95 @@
+/* -----------------------------------------------------------------------
+   ffi_common.h - Copyright (c) 1996  Red Hat, Inc.
+
+   Common internal definitions and macros. Only necessary for building
+   libffi.
+   ----------------------------------------------------------------------- */
+
+#ifndef FFI_COMMON_H
+#define FFI_COMMON_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <fficonfig.h>
+
+/* Do not move this. Some versions of AIX are very picky about where
+   this is positioned. */
+#ifdef __GNUC__
+# define alloca __builtin_alloca
+#else
+# if HAVE_ALLOCA_H
+#  include <alloca.h>
+# else
+#  ifdef _AIX
+ #pragma alloca
+#  else
+#   ifndef alloca /* predefined by HP cc +Olibcalls */
+char *alloca ();
+#   endif
+#  endif
+# endif
+#endif
+
+/* Check for the existence of memcpy. */
+#if STDC_HEADERS
+# include <string.h>
+#else
+# ifndef HAVE_MEMCPY
+#  define memcpy(d, s, n) bcopy ((s), (d), (n))
+# endif
+#endif
+
+#if defined(FFI_DEBUG) 
+#include <stdio.h>
+#endif
+
+#ifdef FFI_DEBUG
+/*@exits@*/ void ffi_assert(/*@temp@*/ char *expr, /*@temp@*/ char *file, int line);
+void ffi_stop_here(void);
+void ffi_type_test(/*@temp@*/ /*@out@*/ ffi_type *a, /*@temp@*/ char *file, int line);
+
+#define FFI_ASSERT(x) ((x) ? (void)0 : ffi_assert(#x, __FILE__,__LINE__))
+#define FFI_ASSERT_AT(x, f, l) ((x) ? 0 : ffi_assert(#x, (f), (l)))
+#define FFI_ASSERT_VALID_TYPE(x) ffi_type_test (x, __FILE__, __LINE__)
+#else
+#define FFI_ASSERT(x) 
+#define FFI_ASSERT_AT(x, f, l)
+#define FFI_ASSERT_VALID_TYPE(x)
+#endif
+
+#define ALIGN(v, a)  (((((size_t) (v))-1) | ((a)-1))+1)
+#define ALIGN_DOWN(v, a) (((size_t) (v)) & -a)
+
+/* Perform machine dependent cif processing */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif);
+
+/* Extended cif, used in callback from assembly routine */
+typedef struct
+{
+  /*@dependent@*/ ffi_cif *cif;
+  /*@dependent@*/ void *rvalue;
+  /*@dependent@*/ void **avalue;
+} extended_cif;
+
+/* Terse sized type definitions.  */
+typedef unsigned int UINT8  __attribute__((__mode__(__QI__)));
+typedef signed int   SINT8  __attribute__((__mode__(__QI__)));
+typedef unsigned int UINT16 __attribute__((__mode__(__HI__)));
+typedef signed int   SINT16 __attribute__((__mode__(__HI__)));
+typedef unsigned int UINT32 __attribute__((__mode__(__SI__)));
+typedef signed int   SINT32 __attribute__((__mode__(__SI__)));
+typedef unsigned int UINT64 __attribute__((__mode__(__DI__)));
+typedef signed int   SINT64 __attribute__((__mode__(__DI__)));
+
+typedef float FLOAT32;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+

Added: vendor/Python/current/Modules/_ctypes/libffi/install-sh
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/install-sh	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/install-sh	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,294 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+#
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.  It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+	-c) instcmd=$cpprog
+	    shift
+	    continue;;
+
+	-d) dir_arg=true
+	    shift
+	    continue;;
+
+	-m) chmodcmd="$chmodprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-o) chowncmd="$chownprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-g) chgrpcmd="$chgrpprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-s) stripcmd=$stripprog
+	    shift
+	    continue;;
+
+	-t=*) transformarg=`echo $1 | sed 's/-t=//'`
+	    shift
+	    continue;;
+
+	-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+	    shift
+	    continue;;
+
+	*)  if [ x"$src" = x ]
+	    then
+		src=$1
+	    else
+		# this colon is to work around a 386BSD /bin/sh bug
+		:
+		dst=$1
+	    fi
+	    shift
+	    continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+	echo "$0: no input file specified" >&2
+	exit 1
+else
+	:
+fi
+
+if [ x"$dir_arg" != x ]; then
+	dst=$src
+	src=""
+
+	if [ -d "$dst" ]; then
+		instcmd=:
+		chmodcmd=""
+	else
+		instcmd=$mkdirprog
+	fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad
+# if $src (and thus $dsttmp) contains '*'.
+
+	if [ -f "$src" ] || [ -d "$src" ]
+	then
+		:
+	else
+		echo "$0: $src does not exist" >&2
+		exit 1
+	fi
+
+	if [ x"$dst" = x ]
+	then
+		echo "$0: no destination specified" >&2
+		exit 1
+	else
+		:
+	fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+	if [ -d "$dst" ]
+	then
+		dst=$dst/`basename "$src"`
+	else
+		:
+	fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+#  this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='
+	'
+IFS="${IFS-$defaultIFS}"
+
+oIFS=$IFS
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS=$oIFS
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+	pathcomp=$pathcomp$1
+	shift
+
+	if [ ! -d "$pathcomp" ] ;
+        then
+		$mkdirprog "$pathcomp"
+	else
+		:
+	fi
+
+	pathcomp=$pathcomp/
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+	$doit $instcmd "$dst" &&
+
+	if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi &&
+	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi &&
+	if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi &&
+	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+	if [ x"$transformarg" = x ]
+	then
+		dstfile=`basename "$dst"`
+	else
+		dstfile=`basename "$dst" $transformbasename |
+			sed $transformarg`$transformbasename
+	fi
+
+# don't allow the sed command to completely eliminate the filename
+
+	if [ x"$dstfile" = x ]
+	then
+		dstfile=`basename "$dst"`
+	else
+		:
+	fi
+
+# Make a couple of temp file names in the proper directory.
+
+	dsttmp=$dstdir/#inst.$$#
+	rmtmp=$dstdir/#rm.$$#
+
+# Trap to clean up temp files at exit.
+
+	trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0
+	trap '(exit $?); exit' 1 2 13 15
+
+# Move or copy the file name to the temp name
+
+	$doit $instcmd "$src" "$dsttmp" &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing.  If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+	if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi &&
+	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi &&
+	if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi &&
+	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi &&
+
+# Now remove or move aside any old file at destination location.  We try this
+# two ways since rm can't unlink itself on some systems and the destination
+# file might be busy for other reasons.  In this case, the final cleanup
+# might fail but the new file should still install successfully.
+
+{
+	if [ -f "$dstdir/$dstfile" ]
+	then
+		$doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null ||
+		$doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null ||
+		{
+		  echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
+		  (exit 1); exit
+		}
+	else
+		:
+	fi
+} &&
+
+# Now rename the file to the real destination.
+
+	$doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
+
+fi &&
+
+# The final little trick to "correctly" pass the exit status to the exit trap.
+
+{
+	(exit 0); exit
+}


Property changes on: vendor/Python/current/Modules/_ctypes/libffi/install-sh
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Modules/_ctypes/libffi/src/alpha/ffi.c
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/alpha/ffi.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/alpha/ffi.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,252 @@
+/* -----------------------------------------------------------------------
+   ffi.c - Copyright (c) 1998, 2001 Red Hat, Inc.
+   
+   Alpha Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+
+extern void ffi_call_osf(void *, unsigned long, unsigned, void *, void (*)());
+extern void ffi_closure_osf(void);
+
+
+ffi_status
+ffi_prep_cif_machdep(ffi_cif *cif)
+{
+  /* Adjust cif->bytes to represent a minimum 6 words for the temporary
+     register argument loading area.  */
+  if (cif->bytes < 6*FFI_SIZEOF_ARG)
+    cif->bytes = 6*FFI_SIZEOF_ARG;
+
+  /* Set the return type flag */
+  switch (cif->rtype->type)
+    {
+    case FFI_TYPE_STRUCT:
+    case FFI_TYPE_FLOAT:
+    case FFI_TYPE_DOUBLE:
+      cif->flags = cif->rtype->type;
+      break;
+
+    default:
+      cif->flags = FFI_TYPE_INT;
+      break;
+    }
+  
+  return FFI_OK;
+}
+
+void
+ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
+{
+  unsigned long *stack, *argp;
+  long i, avn;
+  ffi_type **arg_types;
+  
+  FFI_ASSERT (cif->abi == FFI_OSF);
+
+  /* If the return value is a struct and we don't have a return
+     value address then we need to make one.  */
+  if (rvalue == NULL && cif->flags == FFI_TYPE_STRUCT)
+    rvalue = alloca(cif->rtype->size);
+
+  /* Allocate the space for the arguments, plus 4 words of temp
+     space for ffi_call_osf.  */
+  argp = stack = alloca(cif->bytes + 4*FFI_SIZEOF_ARG);
+
+  if (cif->flags == FFI_TYPE_STRUCT)
+    *(void **) argp++ = rvalue;
+
+  i = 0;
+  avn = cif->nargs;
+  arg_types = cif->arg_types;
+
+  while (i < avn)
+    {
+      switch ((*arg_types)->type)
+	{
+	case FFI_TYPE_SINT8:
+	  *(SINT64 *) argp = *(SINT8 *)(* avalue);
+	  break;
+		  
+	case FFI_TYPE_UINT8:
+	  *(SINT64 *) argp = *(UINT8 *)(* avalue);
+	  break;
+		  
+	case FFI_TYPE_SINT16:
+	  *(SINT64 *) argp = *(SINT16 *)(* avalue);
+	  break;
+		  
+	case FFI_TYPE_UINT16:
+	  *(SINT64 *) argp = *(UINT16 *)(* avalue);
+	  break;
+		  
+	case FFI_TYPE_SINT32:
+	case FFI_TYPE_UINT32:
+	  /* Note that unsigned 32-bit quantities are sign extended.  */
+	  *(SINT64 *) argp = *(SINT32 *)(* avalue);
+	  break;
+		  
+	case FFI_TYPE_SINT64:
+	case FFI_TYPE_UINT64:
+	case FFI_TYPE_POINTER:
+	  *(UINT64 *) argp = *(UINT64 *)(* avalue);
+	  break;
+
+	case FFI_TYPE_FLOAT:
+	  if (argp - stack < 6)
+	    {
+	      /* Note the conversion -- all the fp regs are loaded as
+		 doubles.  The in-register format is the same.  */
+	      *(double *) argp = *(float *)(* avalue);
+	    }
+	  else
+	    *(float *) argp = *(float *)(* avalue);
+	  break;
+
+	case FFI_TYPE_DOUBLE:
+	  *(double *) argp = *(double *)(* avalue);
+	  break;
+
+	case FFI_TYPE_STRUCT:
+	  memcpy(argp, *avalue, (*arg_types)->size);
+	  break;
+
+	default:
+	  FFI_ASSERT(0);
+	}
+
+      argp += ALIGN((*arg_types)->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
+      i++, arg_types++, avalue++;
+    }
+
+  ffi_call_osf(stack, cif->bytes, cif->flags, rvalue, fn);
+}
+
+
+ffi_status
+ffi_prep_closure (ffi_closure* closure,
+		  ffi_cif* cif,
+		  void (*fun)(ffi_cif*, void*, void**, void*),
+		  void *user_data)
+{
+  unsigned int *tramp;
+
+  FFI_ASSERT (cif->abi == FFI_OSF);
+
+  tramp = (unsigned int *) &closure->tramp[0];
+  tramp[0] = 0x47fb0401;	/* mov $27,$1		*/
+  tramp[1] = 0xa77b0010;	/* ldq $27,16($27)	*/
+  tramp[2] = 0x6bfb0000;	/* jmp $31,($27),0	*/
+  tramp[3] = 0x47ff041f;	/* nop			*/
+  *(void **) &tramp[4] = ffi_closure_osf;
+
+  closure->cif = cif;
+  closure->fun = fun;
+  closure->user_data = user_data;
+
+  /* Flush the Icache.
+
+     Tru64 UNIX as doesn't understand the imb mnemonic, so use call_pal
+     instead, since both Compaq as and gas can handle it.
+
+     0x86 is PAL_imb in Tru64 UNIX <alpha/pal.h>.  */
+  asm volatile ("call_pal 0x86" : : : "memory");
+
+  return FFI_OK;
+}
+
+int
+ffi_closure_osf_inner(ffi_closure *closure, void *rvalue, unsigned long *argp)
+{
+  ffi_cif *cif;
+  void **avalue;
+  ffi_type **arg_types;
+  long i, avn, argn;
+
+  cif = closure->cif;
+  avalue = alloca(cif->nargs * sizeof(void *));
+
+  argn = 0;
+
+  /* Copy the caller's structure return address to that the closure
+     returns the data directly to the caller.  */
+  if (cif->flags == FFI_TYPE_STRUCT)
+    {
+      rvalue = (void *) argp[0];
+      argn = 1;
+    }
+
+  i = 0;
+  avn = cif->nargs;
+  arg_types = cif->arg_types;
+  
+  /* Grab the addresses of the arguments from the stack frame.  */
+  while (i < avn)
+    {
+      switch (arg_types[i]->type)
+	{
+	case FFI_TYPE_SINT8:
+	case FFI_TYPE_UINT8:
+	case FFI_TYPE_SINT16:
+	case FFI_TYPE_UINT16:
+	case FFI_TYPE_SINT32:
+	case FFI_TYPE_UINT32:
+	case FFI_TYPE_SINT64:
+	case FFI_TYPE_UINT64:
+	case FFI_TYPE_POINTER:
+	case FFI_TYPE_STRUCT:
+	  avalue[i] = &argp[argn];
+	  break;
+
+	case FFI_TYPE_FLOAT:
+	  if (argn < 6)
+	    {
+	      /* Floats coming from registers need conversion from double
+	         back to float format.  */
+	      *(float *)&argp[argn - 6] = *(double *)&argp[argn - 6];
+	      avalue[i] = &argp[argn - 6];
+	    }
+	  else
+	    avalue[i] = &argp[argn];
+	  break;
+
+	case FFI_TYPE_DOUBLE:
+	  avalue[i] = &argp[argn - (argn < 6 ? 6 : 0)];
+	  break;
+
+	default:
+	  FFI_ASSERT(0);
+	}
+
+      argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
+      i++;
+    }
+
+  /* Invoke the closure.  */
+  (closure->fun) (cif, rvalue, avalue, closure->user_data);
+
+  /* Tell ffi_closure_osf how to perform return type promotions.  */
+  return cif->rtype->type;
+}

Added: vendor/Python/current/Modules/_ctypes/libffi/src/alpha/ffitarget.h
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/alpha/ffitarget.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/alpha/ffitarget.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,48 @@
+/* -----------------------------------------------------------------*-C-*-
+   ffitarget.h - Copyright (c) 1996-2003  Red Hat, Inc.
+   Target configuration macros for Alpha.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+
+   ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+#ifndef LIBFFI_ASM
+typedef unsigned long          ffi_arg;
+typedef signed long            ffi_sarg;
+
+typedef enum ffi_abi {
+  FFI_FIRST_ABI = 0,
+  FFI_OSF,
+  FFI_DEFAULT_ABI = FFI_OSF,
+  FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
+} ffi_abi;
+#endif
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#define FFI_CLOSURES 1
+#define FFI_TRAMPOLINE_SIZE 24
+#define FFI_NATIVE_RAW_API 0
+
+#endif
+

Added: vendor/Python/current/Modules/_ctypes/libffi/src/alpha/osf.S
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/alpha/osf.S	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/alpha/osf.S	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,359 @@
+/* -----------------------------------------------------------------------
+   osf.S - Copyright (c) 1998, 2001 Red Hat
+   
+   Alpha/OSF Foreign Function Interface 
+
+   $Id: osf.S,v 1.2 2006/03/03 20:24:26 theller Exp $
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM	
+#include <fficonfig.h>
+#include <ffi.h>
+
+	.arch ev6
+	.text
+
+/* ffi_call_osf (void *args, unsigned long bytes, unsigned flags,
+		 void *raddr, void (*fnaddr)());
+
+   Bit o trickiness here -- ARGS+BYTES is the base of the stack frame
+   for this function.  This has been allocated by ffi_call.  We also
+   deallocate some of the stack that has been alloca'd.  */
+
+	.align	3
+	.globl	ffi_call_osf
+	.ent	ffi_call_osf
+ffi_call_osf:
+	.frame	$15, 32, $26, 0
+	.mask   0x4008000, -32
+$LFB1:
+	addq	$16,$17,$1
+	mov	$16, $30
+	stq	$26, 0($1)
+	stq	$15, 8($1)
+	stq	$18, 16($1)
+	mov	$1, $15
+$LCFI1:
+	.prologue 0
+
+	stq	$19, 24($1)
+	mov	$20, $27
+
+	# Load up all of the (potential) argument registers.
+	ldq	$16, 0($30)
+	ldt	$f16, 0($30)
+	ldt	$f17, 8($30)
+	ldq	$17, 8($30)
+	ldt	$f18, 16($30)
+	ldq	$18, 16($30)
+	ldt	$f19, 24($30)
+	ldq	$19, 24($30)
+	ldt	$f20, 32($30)
+	ldq	$20, 32($30)
+	ldt	$f21, 40($30)
+	ldq	$21, 40($30)
+
+	# Deallocate the register argument area.
+	lda	$30, 48($30)
+
+	jsr	$26, ($27), 0
+	ldgp	$29, 0($26)
+
+	# If the return value pointer is NULL, assume no return value.
+	ldq	$19, 24($15)
+	ldq	$18, 16($15)
+	ldq	$26, 0($15)
+$LCFI2:
+	beq	$19, $noretval
+
+	# Store the return value out in the proper type.
+	cmpeq	$18, FFI_TYPE_INT, $1
+	bne	$1, $retint
+	cmpeq	$18, FFI_TYPE_FLOAT, $2
+	bne	$2, $retfloat
+	cmpeq	$18, FFI_TYPE_DOUBLE, $3
+	bne	$3, $retdouble
+
+	.align	3
+$noretval:
+	ldq	$15, 8($15)
+	ret
+
+	.align	4
+$retint:
+	stq	$0, 0($19)
+	nop
+	ldq	$15, 8($15)
+	ret
+
+	.align	4
+$retfloat:
+	sts	$f0, 0($19)
+	nop
+	ldq	$15, 8($15)
+	ret
+
+	.align	4
+$retdouble:
+	stt	$f0, 0($19)
+	nop
+	ldq	$15, 8($15)
+	ret
+$LFE1:
+
+	.end	ffi_call_osf
+
+/* ffi_closure_osf(...)
+
+   Receives the closure argument in $1.   */
+
+	.align	3
+	.globl	ffi_closure_osf
+	.ent	ffi_closure_osf
+ffi_closure_osf:
+	.frame	$30, 16*8, $26, 0
+	.mask	0x4000000, -16*8
+$LFB2:
+	ldgp	$29, 0($27)
+	subq	$30, 16*8, $30
+$LCFI5:
+	stq	$26, 0($30)
+$LCFI6:
+	.prologue 1
+
+	# Store all of the potential argument registers in va_list format.
+	stt	$f16, 4*8($30)
+	stt	$f17, 5*8($30)
+	stt	$f18, 6*8($30)
+	stt	$f19, 7*8($30)
+	stt	$f20, 8*8($30)
+	stt	$f21, 9*8($30)
+	stq	$16, 10*8($30)
+	stq	$17, 11*8($30)
+	stq	$18, 12*8($30)
+	stq	$19, 13*8($30)
+	stq	$20, 14*8($30)
+	stq	$21, 15*8($30)
+
+	# Call ffi_closure_osf_inner to do the bulk of the work.
+	mov	$1, $16
+	lda	$17, 2*8($30)
+	lda	$18, 10*8($30)
+	jsr	$26, ffi_closure_osf_inner
+	ldgp	$29, 0($26)
+	ldq	$26, 0($30)
+
+	# Load up the return value in the proper type.
+	lda	$1, $load_table
+	s4addq	$0, $1, $1
+	ldl	$1, 0($1)
+	addq	$1, $29, $1
+	jmp	$31, ($1), $load_32
+
+	.align 4
+$load_none:
+	addq	$30, 16*8, $30
+	ret
+
+	.align 4
+$load_float:
+	lds	$f0, 16($30)
+	nop
+	addq	$30, 16*8, $30
+	ret
+
+	.align 4
+$load_double:
+	ldt	$f0, 16($30)
+	nop
+	addq	$30, 16*8, $30
+	ret
+
+	.align 4
+$load_u8:
+#ifdef __alpha_bwx__
+	ldbu	$0, 16($30)
+	nop
+#else
+	ldq	$0, 16($30)
+	and	$0, 255, $0
+#endif
+	addq	$30, 16*8, $30
+	ret
+
+	.align 4
+$load_s8:
+#ifdef __alpha_bwx__
+	ldbu	$0, 16($30)
+	sextb	$0, $0
+#else
+	ldq	$0, 16($30)
+	sll	$0, 56, $0
+	sra	$0, 56, $0
+#endif
+	addq	$30, 16*8, $30
+	ret
+
+	.align 4
+$load_u16:
+#ifdef __alpha_bwx__
+	ldwu	$0, 16($30)
+	nop
+#else
+	ldq	$0, 16($30)
+	zapnot	$0, 3, $0
+#endif
+	addq	$30, 16*8, $30
+	ret
+
+	.align 4
+$load_s16:
+#ifdef __alpha_bwx__
+	ldwu	$0, 16($30)
+	sextw	$0, $0
+#else
+	ldq	$0, 16($30)
+	sll	$0, 48, $0
+	sra	$0, 48, $0
+#endif
+	addq	$30, 16*8, $30
+	ret
+
+	.align 4
+$load_32:
+	ldl	$0, 16($30)
+	nop
+	addq	$30, 16*8, $30
+	ret
+
+	.align 4
+$load_64:
+	ldq	$0, 16($30)
+	nop
+	addq	$30, 16*8, $30
+	ret
+$LFE2:
+
+	.end	ffi_closure_osf
+
+#ifdef __ELF__
+.section .rodata
+#else
+.rdata
+#endif
+$load_table:
+	.gprel32 $load_none	# FFI_TYPE_VOID
+	.gprel32 $load_32	# FFI_TYPE_INT
+	.gprel32 $load_float	# FFI_TYPE_FLOAT
+	.gprel32 $load_double	# FFI_TYPE_DOUBLE
+	.gprel32 $load_double	# FFI_TYPE_LONGDOUBLE
+	.gprel32 $load_u8	# FFI_TYPE_UINT8
+	.gprel32 $load_s8	# FFI_TYPE_SINT8
+	.gprel32 $load_u16	# FFI_TYPE_UINT16
+	.gprel32 $load_s16	# FFI_TYPE_SINT16
+	.gprel32 $load_32	# FFI_TYPE_UINT32
+	.gprel32 $load_32	# FFI_TYPE_SINT32
+	.gprel32 $load_64	# FFI_TYPE_UINT64
+	.gprel32 $load_64	# FFI_TYPE_SINT64
+	.gprel32 $load_none	# FFI_TYPE_STRUCT
+	.gprel32 $load_64	# FFI_TYPE_POINTER
+
+/* Assert that the table above is in sync with ffi.h.  */
+
+#if	   FFI_TYPE_FLOAT != 2		\
+	|| FFI_TYPE_DOUBLE != 3		\
+	|| FFI_TYPE_UINT8 != 5		\
+	|| FFI_TYPE_SINT8 != 6		\
+	|| FFI_TYPE_UINT16 != 7		\
+	|| FFI_TYPE_SINT16 != 8		\
+	|| FFI_TYPE_UINT32 != 9		\
+	|| FFI_TYPE_SINT32 != 10	\
+	|| FFI_TYPE_UINT64 != 11	\
+	|| FFI_TYPE_SINT64 != 12	\
+	|| FFI_TYPE_STRUCT != 13	\
+	|| FFI_TYPE_POINTER != 14	\
+	|| FFI_TYPE_LAST != 14
+#error "osf.S out of sync with ffi.h"
+#endif
+
+#ifdef __ELF__
+	.section	.eh_frame,EH_FRAME_FLAGS, at progbits
+__FRAME_BEGIN__:
+	.4byte	$LECIE1-$LSCIE1	# Length of Common Information Entry
+$LSCIE1:
+	.4byte	0x0		# CIE Identifier Tag
+	.byte	0x1		# CIE Version
+	.ascii "zR\0"		# CIE Augmentation
+	.byte	0x1		# uleb128 0x1; CIE Code Alignment Factor
+	.byte	0x78		# sleb128 -8; CIE Data Alignment Factor
+	.byte	26		# CIE RA Column
+	.byte	0x1		# uleb128 0x1; Augmentation size
+	.byte	0x1b		# FDE Encoding (pcrel sdata4)
+	.byte	0xc		# DW_CFA_def_cfa
+	.byte	30		# uleb128 column 30
+	.byte	0		# uleb128 offset 0
+	.align 3
+$LECIE1:
+$LSFDE1:
+	.4byte	$LEFDE1-$LASFDE1		# FDE Length
+$LASFDE1:
+	.4byte	$LASFDE1-__FRAME_BEGIN__	# FDE CIE offset
+	.4byte	$LFB1-.		# FDE initial location
+	.4byte	$LFE1-$LFB1	# FDE address range
+	.byte	0x0		# uleb128 0x0; Augmentation size
+
+	.byte	0x4		# DW_CFA_advance_loc4
+	.4byte	$LCFI1-$LFB1
+	.byte	0x9a		# DW_CFA_offset, column 26
+	.byte	4		# uleb128 4*-8
+	.byte	0x8f		# DW_CFA_offset, column 15
+	.byte	0x3		# uleb128 3*-8
+	.byte	0xc		# DW_CFA_def_cfa
+	.byte	15		# uleb128 column 15
+	.byte	32		# uleb128 offset 32
+
+	.byte	0x4		# DW_CFA_advance_loc4
+	.4byte	$LCFI2-$LCFI1
+	.byte	0xda		# DW_CFA_restore, column 26
+	.align 3
+$LEFDE1:
+
+$LSFDE3:
+	.4byte	$LEFDE3-$LASFDE3		# FDE Length
+$LASFDE3:
+	.4byte	$LASFDE3-__FRAME_BEGIN__	# FDE CIE offset
+	.4byte	$LFB2-.		# FDE initial location
+	.4byte	$LFE2-$LFB2	# FDE address range
+	.byte	0x0		# uleb128 0x0; Augmentation size
+
+	.byte	0x4		# DW_CFA_advance_loc4
+	.4byte	$LCFI5-$LFB2
+	.byte	0xe		# DW_CFA_def_cfa_offset
+	.byte	0x80,0x1	# uleb128 128
+
+	.byte	0x4		# DW_CFA_advance_loc4
+	.4byte	$LCFI6-$LCFI5
+	.byte	0x9a		# DW_CFA_offset, column 26
+	.byte	16		# uleb128 offset 16*-8
+	.align 3
+$LEFDE3:
+#endif

Added: vendor/Python/current/Modules/_ctypes/libffi/src/arm/ffi.c
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/arm/ffi.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/arm/ffi.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,185 @@
+/* -----------------------------------------------------------------------
+   ffi.c - Copyright (c) 1998  Red Hat, Inc.
+   
+   ARM Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+
+/* ffi_prep_args is called by the assembly routine once stack space
+   has been allocated for the function's arguments */
+
+/*@-exportheader@*/
+void ffi_prep_args(char *stack, extended_cif *ecif)
+/*@=exportheader@*/
+{
+  register unsigned int i;
+  register void **p_argv;
+  register char *argp;
+  register ffi_type **p_arg;
+
+  argp = stack;
+
+  if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT ) {
+    *(void **) argp = ecif->rvalue;
+    argp += 4;
+  }
+
+  p_argv = ecif->avalue;
+
+  for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
+       (i != 0);
+       i--, p_arg++)
+    {
+      size_t z;
+
+      /* Align if necessary */
+      if (((*p_arg)->alignment - 1) & (unsigned) argp) {
+	argp = (char *) ALIGN(argp, (*p_arg)->alignment);
+      }
+
+	  z = (*p_arg)->size;
+	  if (z < sizeof(int))
+	    {
+	      z = sizeof(int);
+	      switch ((*p_arg)->type)
+		{
+		case FFI_TYPE_SINT8:
+		  *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
+		  break;
+		  
+		case FFI_TYPE_UINT8:
+		  *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
+		  break;
+		  
+		case FFI_TYPE_SINT16:
+		  *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
+		  break;
+		  
+		case FFI_TYPE_UINT16:
+		  *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
+		  break;
+		  
+		case FFI_TYPE_STRUCT:
+		  *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+		  break;
+
+		default:
+		  FFI_ASSERT(0);
+		}
+	    }
+	  else if (z == sizeof(int))
+	    {
+	      *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+	    }
+	  else
+	    {
+	      memcpy(argp, *p_argv, z);
+	    }
+	  p_argv++;
+	  argp += z;
+    }
+  
+  return;
+}
+
+/* Perform machine dependent cif processing */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+{
+  /* Round the stack up to a multiple of 8 bytes.  This isn't needed 
+     everywhere, but it is on some platforms, and it doesn't harm anything
+     when it isn't needed.  */
+  cif->bytes = (cif->bytes + 7) & ~7;
+
+  /* Set the return type flag */
+  switch (cif->rtype->type)
+    {
+    case FFI_TYPE_VOID:
+    case FFI_TYPE_STRUCT:
+    case FFI_TYPE_FLOAT:
+    case FFI_TYPE_DOUBLE:
+      cif->flags = (unsigned) cif->rtype->type;
+      break;
+
+    case FFI_TYPE_SINT64:
+    case FFI_TYPE_UINT64:
+      cif->flags = (unsigned) FFI_TYPE_SINT64;
+      break;
+
+    default:
+      cif->flags = FFI_TYPE_INT;
+      break;
+    }
+
+  return FFI_OK;
+}
+
+/*@-declundef@*/
+/*@-exportheader@*/
+extern void ffi_call_SYSV(void (*)(char *, extended_cif *), 
+			  /*@out@*/ extended_cif *, 
+			  unsigned, unsigned, 
+			  /*@out@*/ unsigned *, 
+			  void (*fn)());
+/*@=declundef@*/
+/*@=exportheader@*/
+
+void ffi_call(/*@dependent@*/ ffi_cif *cif, 
+	      void (*fn)(), 
+	      /*@out@*/ void *rvalue, 
+	      /*@dependent@*/ void **avalue)
+{
+  extended_cif ecif;
+
+  ecif.cif = cif;
+  ecif.avalue = avalue;
+  
+  /* If the return value is a struct and we don't have a return	*/
+  /* value address then we need to make one		        */
+
+  if ((rvalue == NULL) && 
+      (cif->rtype->type == FFI_TYPE_STRUCT))
+    {
+      /*@-sysunrecog@*/
+      ecif.rvalue = alloca(cif->rtype->size);
+      /*@=sysunrecog@*/
+    }
+  else
+    ecif.rvalue = rvalue;
+    
+  
+  switch (cif->abi) 
+    {
+    case FFI_SYSV:
+      /*@-usedef@*/
+      ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, 
+		    cif->flags, ecif.rvalue, fn);
+      /*@=usedef@*/
+      break;
+    default:
+      FFI_ASSERT(0);
+      break;
+    }
+}

Added: vendor/Python/current/Modules/_ctypes/libffi/src/arm/ffitarget.h
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/arm/ffitarget.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/arm/ffitarget.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,47 @@
+/* -----------------------------------------------------------------*-C-*-
+   ffitarget.h - Copyright (c) 1996-2003  Red Hat, Inc.
+   Target configuration macros for ARM.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+
+   ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+#ifndef LIBFFI_ASM
+typedef unsigned long          ffi_arg;
+typedef signed long            ffi_sarg;
+
+typedef enum ffi_abi {
+  FFI_FIRST_ABI = 0,
+  FFI_SYSV,
+  FFI_DEFAULT_ABI = FFI_SYSV,
+  FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
+} ffi_abi;
+#endif
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#define FFI_CLOSURES 0
+#define FFI_NATIVE_RAW_API 0
+
+#endif
+

Added: vendor/Python/current/Modules/_ctypes/libffi/src/arm/sysv.S
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/arm/sysv.S	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/arm/sysv.S	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,209 @@
+/* -----------------------------------------------------------------------
+   sysv.S - Copyright (c) 1998 Red Hat, Inc.
+   
+   ARM Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM	
+#include <fficonfig.h>
+#include <ffi.h>
+#ifdef HAVE_MACHINE_ASM_H
+#include <machine/asm.h>
+#else
+#ifdef __USER_LABEL_PREFIX__
+#define CONCAT1(a, b) CONCAT2(a, b)
+#define CONCAT2(a, b) a ## b
+
+/* Use the right prefix for global labels.  */
+#define CNAME(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
+#else
+#define CNAME(x) x
+#endif
+#define ENTRY(x) .globl CNAME(x); .type CNAME(x),%function; CNAME(x):
+#endif
+
+#ifdef __ELF__
+#define LSYM(x) .x
+#else
+#define LSYM(x) x
+#endif
+
+/* We need a better way of testing for this, but for now, this is all 
+   we can do.  */
+@ This selects the minimum architecture level required.
+#define __ARM_ARCH__ 3
+
+#if defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__)
+# undef __ARM_ARCH__
+# define __ARM_ARCH__ 4
+#endif
+        
+#if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \
+	|| defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \
+	|| defined(__ARM_ARCH_5TEJ__)
+# undef __ARM_ARCH__
+# define __ARM_ARCH__ 5
+#endif
+
+#if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
+        || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \
+        || defined(__ARM_ARCH_6ZK__)
+# undef __ARM_ARCH__
+# define __ARM_ARCH__ 6
+#endif
+
+#if __ARM_ARCH__ >= 5
+# define call_reg(x)	blx	x
+#elif defined (__ARM_ARCH_4T__)
+# define call_reg(x)	mov	lr, pc ; bx	x
+# if defined(__thumb__) || defined(__THUMB_INTERWORK__)
+#  define __INTERWORKING__
+# endif
+#else
+# define call_reg(x)	mov	lr, pc ; mov	pc, x
+#endif
+
+#if defined(__thumb__) && !defined(__THUMB_INTERWORK__)
+.macro	ARM_FUNC_START name
+	.text
+	.align 0
+	.thumb
+	.thumb_func
+	ENTRY(\name)
+	bx	pc
+	nop
+	.arm
+/* A hook to tell gdb that we've switched to ARM mode.  Also used to call
+   directly from other local arm routines.  */
+_L__\name:		
+.endm
+#else
+.macro	ARM_FUNC_START name
+	.text
+	.align 0
+	.arm
+	ENTRY(\name)
+.endm
+#endif
+
+.macro	RETLDM	regs=, cond=, dirn=ia
+#if defined (__INTERWORKING__)
+	.ifc "\regs",""
+	ldr\cond	lr, [sp], #4
+	.else
+	ldm\cond\dirn	sp!, {\regs, lr}
+	.endif
+	bx\cond	lr
+#else
+	.ifc "\regs",""
+	ldr\cond	pc, [sp], #4
+	.else
+	ldm\cond\dirn	sp!, {\regs, pc}
+	.endif
+#endif
+.endm
+
+
+	@ r0:   ffi_prep_args
+	@ r1:   &ecif
+	@ r2:   cif->bytes
+	@ r3:   fig->flags
+	@ sp+0: ecif.rvalue
+	@ sp+4: fn
+
+	@ This assumes we are using gas.
+ARM_FUNC_START ffi_call_SYSV
+	@ Save registers
+        stmfd	sp!, {r0-r3, fp, lr}
+	mov	fp, sp
+
+	@ Make room for all of the new args.
+	sub	sp, fp, r2
+
+	@ Place all of the ffi_prep_args in position
+	mov	ip, r0
+	mov	r0, sp
+	@     r1 already set
+
+	@ Call ffi_prep_args(stack, &ecif)
+	call_reg(ip)
+
+	@ move first 4 parameters in registers
+	ldmia	sp, {r0-r3}
+
+	@ and adjust stack
+	ldr	ip, [fp, #8]
+        cmp	ip, #16
+	movhs	ip, #16
+        add	sp, sp, ip
+
+	@ call (fn) (...)
+	ldr	ip, [fp, #28]
+	call_reg(ip)
+	
+	@ Remove the space we pushed for the args
+	mov	sp, fp
+
+	@ Load r2 with the pointer to storage for the return value
+	ldr	r2, [sp, #24]
+
+	@ Load r3 with the return type code 
+	ldr	r3, [sp, #12]
+
+	@ If the return value pointer is NULL, assume no return value.
+	cmp	r2, #0
+	beq	LSYM(Lepilogue)
+
+@ return INT
+	cmp	r3, #FFI_TYPE_INT
+#ifdef __SOFTFP__
+	cmpne	r3, #FFI_TYPE_FLOAT
+#endif
+	streq	r0, [r2]
+	beq	LSYM(Lepilogue)
+
+	@ return INT64
+	cmp	r3, #FFI_TYPE_SINT64
+#ifdef __SOFTFP__
+	cmpne	r3, #FFI_TYPE_DOUBLE
+#endif
+	stmeqia	r2, {r0, r1}
+
+#ifndef __SOFTFP__
+	beq	LSYM(Lepilogue)
+
+@ return FLOAT
+	cmp	r3, #FFI_TYPE_FLOAT
+	stfeqs	f0, [r2]
+	beq	LSYM(Lepilogue)
+
+@ return DOUBLE or LONGDOUBLE
+	cmp	r3, #FFI_TYPE_DOUBLE
+	stfeqd	f0, [r2]
+#endif
+
+LSYM(Lepilogue):
+	RETLDM	"r0-r3,fp"
+
+.ffi_call_SYSV_end:
+        .size    CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV)
+

Added: vendor/Python/current/Modules/_ctypes/libffi/src/cris/ffi.c
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/cris/ffi.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/cris/ffi.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,381 @@
+/* -----------------------------------------------------------------------
+   ffi.c - Copyright (c) 1998 Cygnus Solutions
+           Copyright (c) 2004 Simon Posnjak
+	   Copyright (c) 2005 Axis Communications AB
+
+   CRIS Foreign Function Interface
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL SIMON POSNJAK BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#define STACK_ARG_SIZE(x) ALIGN(x, FFI_SIZEOF_ARG)
+
+static ffi_status
+initialize_aggregate_packed_struct (ffi_type * arg)
+{
+  ffi_type **ptr;
+
+  FFI_ASSERT (arg != NULL);
+
+  FFI_ASSERT (arg->elements != NULL);
+  FFI_ASSERT (arg->size == 0);
+  FFI_ASSERT (arg->alignment == 0);
+
+  ptr = &(arg->elements[0]);
+
+  while ((*ptr) != NULL)
+    {
+      if (((*ptr)->size == 0)
+	  && (initialize_aggregate_packed_struct ((*ptr)) != FFI_OK))
+	return FFI_BAD_TYPEDEF;
+
+      FFI_ASSERT (ffi_type_test ((*ptr)));
+
+      arg->size += (*ptr)->size;
+
+      arg->alignment = (arg->alignment > (*ptr)->alignment) ?
+	arg->alignment : (*ptr)->alignment;
+
+      ptr++;
+    }
+
+  if (arg->size == 0)
+    return FFI_BAD_TYPEDEF;
+  else
+    return FFI_OK;
+}
+
+int
+ffi_prep_args (char *stack, extended_cif * ecif)
+{
+  unsigned int i;
+  unsigned int struct_count = 0;
+  void **p_argv;
+  char *argp;
+  ffi_type **p_arg;
+
+  argp = stack;
+
+  p_argv = ecif->avalue;
+
+  for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
+       (i != 0); i--, p_arg++)
+    {
+      size_t z;
+
+      switch ((*p_arg)->type)
+	{
+	case FFI_TYPE_STRUCT:
+	  {
+	    z = (*p_arg)->size;
+	    if (z <= 4)
+	      {
+		memcpy (argp, *p_argv, z);
+		z = 4;
+	      }
+	    else if (z <= 8)
+	      {
+		memcpy (argp, *p_argv, z);
+		z = 8;
+	      }
+	    else
+	      {
+		unsigned int uiLocOnStack;
+		z = sizeof (void *);
+		uiLocOnStack = 4 * ecif->cif->nargs + struct_count;
+		struct_count = struct_count + (*p_arg)->size;
+		*(unsigned int *) argp =
+		  (unsigned int) (UINT32 *) (stack + uiLocOnStack);
+		memcpy ((stack + uiLocOnStack), *p_argv, (*p_arg)->size);
+	      }
+	    break;
+	  }
+	default:
+	  z = (*p_arg)->size;
+	  if (z < sizeof (int))
+	    {
+	      switch ((*p_arg)->type)
+		{
+		case FFI_TYPE_SINT8:
+		  *(signed int *) argp = (signed int) *(SINT8 *) (*p_argv);
+		  break;
+
+		case FFI_TYPE_UINT8:
+		  *(unsigned int *) argp =
+		    (unsigned int) *(UINT8 *) (*p_argv);
+		  break;
+
+		case FFI_TYPE_SINT16:
+		  *(signed int *) argp = (signed int) *(SINT16 *) (*p_argv);
+		  break;
+
+		case FFI_TYPE_UINT16:
+		  *(unsigned int *) argp =
+		    (unsigned int) *(UINT16 *) (*p_argv);
+		  break;
+
+		default:
+		  FFI_ASSERT (0);
+		}
+	      z = sizeof (int);
+	    }
+	  else if (z == sizeof (int))
+	    *(unsigned int *) argp = (unsigned int) *(UINT32 *) (*p_argv);
+	  else
+	    memcpy (argp, *p_argv, z);
+	  break;
+	}
+      p_argv++;
+      argp += z;
+    }
+
+  return (struct_count);
+}
+
+ffi_status
+ffi_prep_cif (ffi_cif * cif,
+	      ffi_abi abi, unsigned int nargs,
+	      ffi_type * rtype, ffi_type ** atypes)
+{
+  unsigned bytes = 0;
+  unsigned int i;
+  ffi_type **ptr;
+
+  FFI_ASSERT (cif != NULL);
+  FFI_ASSERT ((abi > FFI_FIRST_ABI) && (abi <= FFI_DEFAULT_ABI));
+
+  cif->abi = abi;
+  cif->arg_types = atypes;
+  cif->nargs = nargs;
+  cif->rtype = rtype;
+
+  cif->flags = 0;
+
+  if ((cif->rtype->size == 0)
+      && (initialize_aggregate_packed_struct (cif->rtype) != FFI_OK))
+    return FFI_BAD_TYPEDEF;
+
+  FFI_ASSERT_VALID_TYPE (cif->rtype);
+
+  for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
+    {
+      if (((*ptr)->size == 0)
+	  && (initialize_aggregate_packed_struct ((*ptr)) != FFI_OK))
+	return FFI_BAD_TYPEDEF;
+
+      FFI_ASSERT_VALID_TYPE (*ptr);
+
+      if (((*ptr)->alignment - 1) & bytes)
+	bytes = ALIGN (bytes, (*ptr)->alignment);
+      if ((*ptr)->type == FFI_TYPE_STRUCT)
+	{
+	  if ((*ptr)->size > 8)
+	    {
+	      bytes += (*ptr)->size;
+	      bytes += sizeof (void *);
+	    }
+	  else
+	    {
+	      if ((*ptr)->size > 4)
+		bytes += 8;
+	      else
+		bytes += 4;
+	    }
+	}
+      else
+	bytes += STACK_ARG_SIZE ((*ptr)->size);
+    }
+
+  cif->bytes = bytes;
+
+  return ffi_prep_cif_machdep (cif);
+}
+
+ffi_status
+ffi_prep_cif_machdep (ffi_cif * cif)
+{
+  switch (cif->rtype->type)
+    {
+    case FFI_TYPE_VOID:
+    case FFI_TYPE_STRUCT:
+    case FFI_TYPE_FLOAT:
+    case FFI_TYPE_DOUBLE:
+    case FFI_TYPE_SINT64:
+    case FFI_TYPE_UINT64:
+      cif->flags = (unsigned) cif->rtype->type;
+      break;
+
+    default:
+      cif->flags = FFI_TYPE_INT;
+      break;
+    }
+
+  return FFI_OK;
+}
+
+extern void ffi_call_SYSV (int (*)(char *, extended_cif *),
+			   extended_cif *,
+			   unsigned, unsigned, unsigned *, void (*fn) ())
+     __attribute__ ((__visibility__ ("hidden")));
+
+void
+ffi_call (ffi_cif * cif, void (*fn) (), void *rvalue, void **avalue)
+{
+  extended_cif ecif;
+
+  ecif.cif = cif;
+  ecif.avalue = avalue;
+
+  if ((rvalue == NULL) && (cif->rtype->type == FFI_TYPE_STRUCT))
+    {
+      ecif.rvalue = alloca (cif->rtype->size);
+    }
+  else
+    ecif.rvalue = rvalue;
+
+  switch (cif->abi)
+    {
+    case FFI_SYSV:
+      ffi_call_SYSV (ffi_prep_args, &ecif, cif->bytes,
+		     cif->flags, ecif.rvalue, fn);
+      break;
+    default:
+      FFI_ASSERT (0);
+      break;
+    }
+}
+
+/* Because the following variables are not exported outside libffi, we
+   mark them hidden.  */
+
+/* Assembly code for the jump stub.  */
+extern const char ffi_cris_trampoline_template[]
+ __attribute__ ((__visibility__ ("hidden")));
+
+/* Offset into ffi_cris_trampoline_template of where to put the
+   ffi_prep_closure_inner function.  */
+extern const int ffi_cris_trampoline_fn_offset
+ __attribute__ ((__visibility__ ("hidden")));
+
+/* Offset into ffi_cris_trampoline_template of where to put the
+   closure data.  */
+extern const int ffi_cris_trampoline_closure_offset
+ __attribute__ ((__visibility__ ("hidden")));
+
+/* This function is sibling-called (jumped to) by the closure
+   trampoline.  We get R10..R13 at PARAMS[0..3] and a copy of [SP] at
+   PARAMS[4] to simplify handling of a straddling parameter.  A copy
+   of R9 is at PARAMS[5] and SP at PARAMS[6].  These parameters are
+   put at the appropriate place in CLOSURE which is then executed and
+   the return value is passed back to the caller.  */
+
+static unsigned long long
+ffi_prep_closure_inner (void **params, ffi_closure* closure)
+{
+  char *register_args = (char *) params;
+  void *struct_ret = params[5];
+  char *stack_args = params[6];
+  char *ptr = register_args;
+  ffi_cif *cif = closure->cif;
+  ffi_type **arg_types = cif->arg_types;
+
+  /* Max room needed is number of arguments as 64-bit values.  */
+  void **avalue = alloca (closure->cif->nargs * sizeof(void *));
+  int i;
+  int doing_regs;
+  long long llret = 0;
+
+  /* Find the address of each argument.  */
+  for (i = 0, doing_regs = 1; i < cif->nargs; i++)
+    {
+      /* Types up to and including 8 bytes go by-value.  */
+      if (arg_types[i]->size <= 4)
+	{
+	  avalue[i] = ptr;
+	  ptr += 4;
+	}
+      else if (arg_types[i]->size <= 8)
+	{
+	  avalue[i] = ptr;
+	  ptr += 8;
+	}
+      else
+	{
+	  FFI_ASSERT (arg_types[i]->type == FFI_TYPE_STRUCT);
+
+	  /* Passed by-reference, so copy the pointer.  */
+	  avalue[i] = *(void **) ptr;
+	  ptr += 4;
+	}
+
+      /* If we've handled more arguments than fit in registers, start
+	 looking at the those passed on the stack.  Step over the
+	 first one if we had a straddling parameter.  */
+      if (doing_regs && ptr >= register_args + 4*4)
+	{
+	  ptr = stack_args + ((ptr > register_args + 4*4) ? 4 : 0);
+	  doing_regs = 0;
+	}
+    }
+
+  /* Invoke the closure.  */
+  (closure->fun) (cif,
+
+		  cif->rtype->type == FFI_TYPE_STRUCT
+		  /* The caller allocated space for the return
+		     structure, and passed a pointer to this space in
+		     R9.  */
+		  ? struct_ret
+
+		  /* We take advantage of being able to ignore that
+		     the high part isn't set if the return value is
+		     not in R10:R11, but in R10 only.  */
+		  : (void *) &llret,
+
+		  avalue, closure->user_data);
+
+  return llret;
+}
+
+/* API function: Prepare the trampoline.  */
+
+ffi_status
+ffi_prep_closure (ffi_closure* closure,
+		  ffi_cif* cif,
+		  void (*fun)(ffi_cif *, void *, void **, void*),
+		  void *user_data)
+{
+  void *innerfn = ffi_prep_closure_inner;
+  FFI_ASSERT (cif->abi == FFI_SYSV);
+  closure->cif  = cif;
+  closure->user_data = user_data;
+  closure->fun  = fun;
+  memcpy (closure->tramp, ffi_cris_trampoline_template,
+	  FFI_CRIS_TRAMPOLINE_CODE_PART_SIZE);
+  memcpy (closure->tramp + ffi_cris_trampoline_fn_offset,
+	  &innerfn, sizeof (void *));
+  memcpy (closure->tramp + ffi_cris_trampoline_closure_offset,
+	  &closure, sizeof (void *));
+
+  return FFI_OK;
+}

Added: vendor/Python/current/Modules/_ctypes/libffi/src/cris/ffitarget.h
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/cris/ffitarget.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/cris/ffitarget.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,50 @@
+/* -----------------------------------------------------------------*-C-*-
+   ffitarget.h - Copyright (c) 1996-2003  Red Hat, Inc.
+   Target configuration macros for CRIS.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+
+   ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+#ifndef LIBFFI_ASM
+typedef unsigned long          ffi_arg;
+typedef signed long            ffi_sarg;
+
+typedef enum ffi_abi {
+  FFI_FIRST_ABI = 0,
+  FFI_SYSV,
+  FFI_DEFAULT_ABI = FFI_SYSV,
+  FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
+} ffi_abi;
+#endif
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#define FFI_CLOSURES 1
+#define FFI_CRIS_TRAMPOLINE_CODE_PART_SIZE 36
+#define FFI_CRIS_TRAMPOLINE_DATA_PART_SIZE (7*4)
+#define FFI_TRAMPOLINE_SIZE \
+ (FFI_CRIS_TRAMPOLINE_CODE_PART_SIZE + FFI_CRIS_TRAMPOLINE_DATA_PART_SIZE)
+#define FFI_NATIVE_RAW_API 0
+
+#endif

Added: vendor/Python/current/Modules/_ctypes/libffi/src/cris/sysv.S
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/cris/sysv.S	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/cris/sysv.S	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,215 @@
+/* -----------------------------------------------------------------------
+   sysv.S - Copyright (c) 2004 Simon Posnjak
+	    Copyright (c) 2005 Axis Communications AB
+
+   CRIS Foreign Function Interface
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL SIMON POSNJAK BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <ffi.h>
+#define CONCAT(x,y) x ## y
+#define XCONCAT(x,y) CONCAT (x, y)
+#define L(x) XCONCAT (__USER_LABEL_PREFIX__, x)
+
+	.text
+
+	;; OK, when we get called we should have this (according to
+	;; AXIS ETRAX 100LX Programmer's Manual chapter 6.3).
+	;;
+	;; R10:	 ffi_prep_args (func. pointer)
+	;; R11:  &ecif
+	;; R12:  cif->bytes
+	;; R13:  fig->flags
+	;; sp+0: ecif.rvalue
+	;; sp+4: fn (function pointer to the function that we need to call)
+
+	.globl  L(ffi_call_SYSV)
+	.type   L(ffi_call_SYSV), at function
+	.hidden	L(ffi_call_SYSV)
+
+L(ffi_call_SYSV):
+	;; Save the regs to the stack.
+	push $srp
+	;; Used for stack pointer saving.
+	push $r6
+	;; Used for function address pointer.
+	push $r7
+	;; Used for stack pointer saving.
+	push $r8
+	;; We save fig->flags to stack we will need them after we
+	;; call The Function.
+	push $r13
+
+	;; Saving current stack pointer.
+	move.d $sp,$r8
+	move.d $sp,$r6
+
+	;; Move address of ffi_prep_args to r13.
+	move.d $r10,$r13
+
+	;; Make room on the stack for the args of fn.
+	sub.d  $r12,$sp
+
+	;; Function void ffi_prep_args(char *stack, extended_cif *ecif) parameters are:
+	;; 	r10 <-- stack pointer
+	;; 	r11 <-- &ecif (already there)
+	move.d $sp,$r10
+
+	;; Call the function.
+	jsr $r13
+
+	;; Save the size of the structures which are passed on stack.
+	move.d $r10,$r7
+
+	;; Move first four args in to r10..r13.
+	move.d [$sp+0],$r10
+	move.d [$sp+4],$r11
+	move.d [$sp+8],$r12
+	move.d [$sp+12],$r13
+
+	;; Adjust the stack and check if any parameters are given on stack.
+	addq 16,$sp
+	sub.d $r7,$r6
+	cmp.d $sp,$r6
+
+	bpl go_on
+	nop
+
+go_on_no_params_on_stack:
+	move.d $r6,$sp
+
+go_on:
+	;; Discover if we need to put rval address in to r9.
+	move.d [$r8+0],$r7
+	cmpq FFI_TYPE_STRUCT,$r7
+	bne call_now
+	nop
+
+	;; Move rval address to $r9.
+	move.d [$r8+20],$r9
+
+call_now:
+	;; Move address of The Function in to r7.
+	move.d [$r8+24],$r7
+
+	;; Call The Function.
+	jsr $r7
+
+	;; Reset stack.
+	move.d $r8,$sp
+
+	;; Load rval type (fig->flags) in to r13.
+	pop $r13
+
+	;; Detect rval type.
+	cmpq FFI_TYPE_VOID,$r13
+	beq epilogue
+
+	cmpq FFI_TYPE_STRUCT,$r13
+	beq epilogue
+
+	cmpq FFI_TYPE_DOUBLE,$r13
+	beq return_double_or_longlong
+
+	cmpq FFI_TYPE_UINT64,$r13
+	beq return_double_or_longlong
+
+	cmpq FFI_TYPE_SINT64,$r13
+	beq return_double_or_longlong
+	nop
+
+	;; Just return the 32 bit value.
+	ba return
+	nop
+
+return_double_or_longlong:
+	;; Load half of the rval to r10 and the other half to r11.
+	move.d [$sp+16],$r13
+	move.d $r10,[$r13]
+	addq 4,$r13
+	move.d $r11,[$r13]
+	ba epilogue
+	nop
+
+return:
+	;; Load the rval to r10.
+	move.d [$sp+16],$r13
+	move.d $r10,[$r13]
+
+epilogue:
+	pop $r8
+	pop $r7
+	pop $r6
+	Jump [$sp+]
+
+	.size   ffi_call_SYSV,.-ffi_call_SYSV
+
+/* Save R10..R13 into an array, somewhat like varargs.  Copy the next
+   argument too, to simplify handling of any straddling parameter.
+   Save R9 and SP after those.  Jump to function handling the rest.
+   Since this is a template, copied and the main function filled in by
+   the user.  */
+
+	.globl	L(ffi_cris_trampoline_template)
+	.type	L(ffi_cris_trampoline_template), at function
+	.hidden	L(ffi_cris_trampoline_template)
+
+L(ffi_cris_trampoline_template):
+0:
+	/* The value we get for "PC" is right after the prefix instruction,
+	   two bytes from the beginning, i.e. 0b+2. */
+	move.d $r10,[$pc+2f-(0b+2)]
+	move.d $pc,$r10
+1:
+	addq 2f-1b+4,$r10
+	move.d $r11,[$r10+]
+	move.d $r12,[$r10+]
+	move.d $r13,[$r10+]
+	move.d [$sp],$r11
+	move.d $r11,[$r10+]
+	move.d $r9,[$r10+]
+	move.d $sp,[$r10+]
+	subq FFI_CRIS_TRAMPOLINE_DATA_PART_SIZE,$r10
+	move.d 0,$r11
+3:
+        jump 0
+2:
+	.size	ffi_cris_trampoline_template,.-0b
+
+/* This macro create a constant usable as "extern const int \name" in
+   C from within libffi, when \name has no prefix decoration.  */
+
+	.macro const name,value
+	.globl	\name
+	.type	\name, at object
+	.hidden	\name
+\name:
+	.dword  \value
+	.size	\name,4
+	.endm
+
+/* Constants for offsets within the trampoline.  We could do this with
+   just symbols, avoiding memory contents and memory accesses, but the
+   C usage code would look a bit stranger.  */
+
+	const L(ffi_cris_trampoline_fn_offset),2b-4-0b
+	const L(ffi_cris_trampoline_closure_offset),3b-4-0b

Added: vendor/Python/current/Modules/_ctypes/libffi/src/darwin/ffitarget.h
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/darwin/ffitarget.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/darwin/ffitarget.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,25 @@
+/*
+ * This file is for MacOSX only. Dispatch to the right architecture include
+ * file based on the current archictecture (instead of relying on a symlink
+ * created by configure). This makes is possible to build a univeral binary
+ * of ctypes in one go.
+ */
+#if defined(__i386__)
+
+#ifndef X86_DARWIN
+#define X86_DARWIN
+#endif
+#undef POWERPC_DARWIN
+
+#include "../src/x86/ffitarget.h"
+
+#elif defined(__ppc__)
+
+#ifndef POWERPC_DARWIN
+#define POWERPC_DARWIN
+#endif
+#undef X86_DARWIN
+
+#include "../src/powerpc/ffitarget.h"
+
+#endif

Added: vendor/Python/current/Modules/_ctypes/libffi/src/frv/eabi.S
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/frv/eabi.S	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/frv/eabi.S	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,130 @@
+/* -----------------------------------------------------------------------
+   eabi.S - Copyright (c) 2004  Anthony Green
+   
+   FR-V Assembly glue.
+
+   $Id: eabi.S,v 1.2 2006/03/03 20:24:46 theller Exp $
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM	
+#include <fficonfig.h>
+#include <ffi.h>
+
+	.globl ffi_prep_args_EABI
+
+	.text
+	.p2align 4
+	.globl ffi_call_EABI
+	.type ffi_call_EABI, @function
+
+	# gr8 :   ffi_prep_args
+	# gr9 :   &ecif
+	# gr10:   cif->bytes
+	# gr11:   fig->flags
+	# gr12:   ecif.rvalue
+	# gr13:   fn
+	
+ffi_call_EABI:	
+	addi	sp, #-80, sp
+	sti	fp, @(sp, #24)
+	addi	sp, #24, fp
+	movsg	lr, gr5
+
+	/* Make room for the new arguments.  */
+	/* subi	sp, fp, gr10 */
+	
+	/* Store return address and incoming args on stack.  */
+	sti	gr5, @(fp, #8)
+	sti	gr8, @(fp, #-4)
+	sti	gr9, @(fp, #-8)
+	sti	gr10, @(fp, #-12)
+	sti	gr11, @(fp, #-16)
+	sti	gr12, @(fp, #-20)
+	sti	gr13, @(fp, #-24)
+
+	sub     sp, gr10, sp
+	
+	/* Call ffi_prep_args.  */
+	ldi	@(fp, #-4), gr4
+	addi	sp, #0, gr8
+	ldi	@(fp, #-8), gr9
+#ifdef __FRV_FDPIC__
+	ldd	@(gr4, gr0), gr14
+	calll	@(gr14, gr0)
+#else
+	calll	@(gr4, gr0)
+#endif	
+
+	/* ffi_prep_args returns the new stack pointer.  */
+	mov	gr8, gr4
+		
+	ldi	@(sp, #0), gr8
+	ldi	@(sp, #4), gr9
+	ldi	@(sp, #8), gr10
+	ldi	@(sp, #12), gr11
+	ldi	@(sp, #16), gr12
+	ldi	@(sp, #20), gr13
+
+	/* Always copy the return value pointer into the hidden
+	   parameter register.  This is only strictly necessary
+	   when we're returning an aggregate type, but it doesn't
+	   hurt to do this all the time, and it saves a branch.  */
+	ldi	@(fp, #-20), gr3
+
+	/* Use the ffi_prep_args return value for the new sp.  */
+	mov	gr4, sp
+	
+	/* Call the target function.  */
+	ldi	@(fp, -24), gr4
+#ifdef __FRV_FDPIC__
+	ldd	@(gr4, gr0), gr14
+	calll	@(gr14, gr0)
+#else
+	calll	@(gr4, gr0)
+#endif	
+
+	/* Store the result. */
+	ldi	@(fp, #-16), gr10  /* fig->flags */
+	ldi	@(fp, #-20), gr4   /* ecif.rvalue */
+
+	/* Is the return value stored in two registers?  */
+	cmpi	gr10, #8, icc0
+	bne	icc0, 0, .L2
+	/*   Yes, save them.  */
+	sti	gr8, @(gr4, #0)
+	sti	gr9, @(gr4, #4)
+	bra	.L3
+.L2:
+	/* Is the return value a structure?  */
+	cmpi	gr10, #-1, icc0
+	beq	icc0, 0, .L3
+	/*   No, save a 4 byte return value.  */
+	sti	gr8, @(gr4, #0)
+.L3:	
+
+	/* Restore the stack, and return.  */
+	ldi	@(fp, 8), gr5
+	ld	@(fp, gr0), fp
+	addi	sp,#80,sp
+	jmpl	@(gr5,gr0)
+	.size ffi_call_EABI, .-ffi_call_EABI
+	

Added: vendor/Python/current/Modules/_ctypes/libffi/src/frv/ffi.c
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/frv/ffi.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/frv/ffi.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,287 @@
+/* -----------------------------------------------------------------------
+   ffi.c - Copyright (c) 2004  Anthony Green
+   
+   FR-V Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+
+/* ffi_prep_args is called by the assembly routine once stack space
+   has been allocated for the function's arguments */
+
+void *ffi_prep_args(char *stack, extended_cif *ecif)
+{
+  register unsigned int i;
+  register void **p_argv;
+  register char *argp;
+  register ffi_type **p_arg;
+  register int count = 0;
+
+  p_argv = ecif->avalue;
+  argp = stack;
+
+  for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
+       (i != 0);
+       i--, p_arg++)
+    {
+      size_t z;
+      
+      z = (*p_arg)->size;
+
+      if ((*p_arg)->type == FFI_TYPE_STRUCT)
+	{
+	  z = sizeof(void*);
+	  *(void **) argp = *p_argv;
+	} 
+      /*      if ((*p_arg)->type == FFI_TYPE_FLOAT)
+	{
+	  if (count > 24)
+	    {
+	      // This is going on the stack.  Turn it into a double.  
+	      *(double *) argp = (double) *(float*)(* p_argv);
+	      z = sizeof(double);
+	    }
+	  else
+	    *(void **) argp = *(void **)(* p_argv);
+	}  */
+      else if (z < sizeof(int))
+	{
+	  z = sizeof(int);
+	  switch ((*p_arg)->type)
+	    {
+	    case FFI_TYPE_SINT8:
+	      *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
+	      break;
+	      
+	    case FFI_TYPE_UINT8:
+	      *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
+	      break;
+	      
+	    case FFI_TYPE_SINT16:
+	      *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
+	      break;
+		  
+	    case FFI_TYPE_UINT16:
+	      *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
+	      break;
+		  
+	    default:
+	      FFI_ASSERT(0);
+	    }
+	}
+      else if (z == sizeof(int))
+	{
+	  *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+	}
+      else
+	{
+	  memcpy(argp, *p_argv, z);
+	}
+      p_argv++;
+      argp += z;
+      count += z;
+    }
+
+  return (stack + ((count > 24) ? 24 : ALIGN_DOWN(count, 8)));
+}
+
+/* Perform machine dependent cif processing */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+{
+  if (cif->rtype->type == FFI_TYPE_STRUCT)
+    cif->flags = -1;
+  else
+    cif->flags = cif->rtype->size;
+
+  cif->bytes = ALIGN (cif->bytes, 8);
+
+  return FFI_OK;
+}
+
+extern void ffi_call_EABI(void *(*)(char *, extended_cif *), 
+			  extended_cif *, 
+			  unsigned, unsigned, 
+			  unsigned *, 
+			  void (*fn)());
+
+void ffi_call(ffi_cif *cif, 
+	      void (*fn)(), 
+	      void *rvalue, 
+	      void **avalue)
+{
+  extended_cif ecif;
+
+  ecif.cif = cif;
+  ecif.avalue = avalue;
+  
+  /* If the return value is a struct and we don't have a return	*/
+  /* value address then we need to make one		        */
+
+  if ((rvalue == NULL) && 
+      (cif->rtype->type == FFI_TYPE_STRUCT))
+    {
+      ecif.rvalue = alloca(cif->rtype->size);
+    }
+  else
+    ecif.rvalue = rvalue;
+    
+  
+  switch (cif->abi) 
+    {
+    case FFI_EABI:
+      ffi_call_EABI(ffi_prep_args, &ecif, cif->bytes, 
+		    cif->flags, ecif.rvalue, fn);
+      break;
+    default:
+      FFI_ASSERT(0);
+      break;
+    }
+}
+
+void ffi_closure_eabi (unsigned arg1, unsigned arg2, unsigned arg3,
+		       unsigned arg4, unsigned arg5, unsigned arg6)
+{
+  /* This function is called by a trampoline.  The trampoline stows a
+     pointer to the ffi_closure object in gr7.  We must save this
+     pointer in a place that will persist while we do our work.  */
+  register ffi_closure *creg __asm__ ("gr7");
+  ffi_closure *closure = creg;
+
+  /* Arguments that don't fit in registers are found on the stack
+     at a fixed offset above the current frame pointer.  */
+  register char *frame_pointer __asm__ ("fp");
+  char *stack_args = frame_pointer + 16;
+
+  /* Lay the register arguments down in a continuous chunk of memory.  */
+  unsigned register_args[6] =
+    { arg1, arg2, arg3, arg4, arg5, arg6 };
+
+  ffi_cif *cif = closure->cif;
+  ffi_type **arg_types = cif->arg_types;
+  void **avalue = alloca (cif->nargs * sizeof(void *));
+  char *ptr = (char *) register_args;
+  int i;
+
+  /* Find the address of each argument.  */
+  for (i = 0; i < cif->nargs; i++)
+    {
+      switch (arg_types[i]->type)
+	{
+	case FFI_TYPE_SINT8:
+	case FFI_TYPE_UINT8:
+	  avalue[i] = ptr + 3;
+	  break;
+	case FFI_TYPE_SINT16:
+	case FFI_TYPE_UINT16:
+	  avalue[i] = ptr + 2;
+	  break;
+	case FFI_TYPE_SINT32:
+	case FFI_TYPE_UINT32:
+	case FFI_TYPE_FLOAT:
+	  avalue[i] = ptr;
+	  break;
+	case FFI_TYPE_STRUCT:
+	  avalue[i] = *(void**)ptr;
+	  break;
+	default:
+	  /* This is an 8-byte value.  */
+	  avalue[i] = ptr;
+	  ptr += 4;
+	  break;
+	}
+      ptr += 4;
+
+      /* If we've handled more arguments than fit in registers,
+	 start looking at the those passed on the stack.  */
+      if (ptr == ((char *)register_args + (6*4)))
+	ptr = stack_args;
+    }
+
+  /* Invoke the closure.  */
+  if (cif->rtype->type == FFI_TYPE_STRUCT)
+    {
+      /* The caller allocates space for the return structure, and
+       passes a pointer to this space in gr3.  Use this value directly
+       as the return value.  */
+      register void *return_struct_ptr __asm__("gr3");
+      (closure->fun) (cif, return_struct_ptr, avalue, closure->user_data);
+    }
+  else
+    {
+      /* Allocate space for the return value and call the function.  */
+      long long rvalue;
+      (closure->fun) (cif, &rvalue, avalue, closure->user_data);
+
+      /* Functions return 4-byte or smaller results in gr8.  8-byte
+	 values also use gr9.  We fill the both, even for small return
+	 values, just to avoid a branch.  */ 
+      asm ("ldi  @(%0, #0), gr8" : : "r" (&rvalue));
+      asm ("ldi  @(%0, #0), gr9" : : "r" (&((int *) &rvalue)[1]));
+    }
+}
+
+ffi_status
+ffi_prep_closure (ffi_closure* closure,
+		  ffi_cif* cif,
+		  void (*fun)(ffi_cif*, void*, void**, void*),
+		  void *user_data)
+{
+  unsigned int *tramp = (unsigned int *) &closure->tramp[0];
+  unsigned long fn = (long) ffi_closure_eabi;
+  unsigned long cls = (long) closure;
+#ifdef __FRV_FDPIC__
+  register void *got __asm__("gr15");
+#endif
+  int i;
+
+  fn = (unsigned long) ffi_closure_eabi;
+
+#ifdef __FRV_FDPIC__
+  tramp[0] = &tramp[2];
+  tramp[1] = got;
+  tramp[2] = 0x8cfc0000 + (fn  & 0xffff); /* setlos lo(fn), gr6    */
+  tramp[3] = 0x8efc0000 + (cls & 0xffff); /* setlos lo(cls), gr7   */
+  tramp[4] = 0x8cf80000 + (fn  >> 16);	  /* sethi hi(fn), gr6     */
+  tramp[5] = 0x8ef80000 + (cls >> 16);    /* sethi hi(cls), gr7    */
+  tramp[6] = 0x9cc86000;                  /* ldi @(gr6, #0), gr14  */
+  tramp[7] = 0x8030e000;                  /* jmpl @(gr14, gr0)     */
+#else
+  tramp[0] = 0x8cfc0000 + (fn  & 0xffff); /* setlos lo(fn), gr6    */
+  tramp[1] = 0x8efc0000 + (cls & 0xffff); /* setlos lo(cls), gr7   */
+  tramp[2] = 0x8cf80000 + (fn  >> 16);	  /* sethi hi(fn), gr6     */
+  tramp[3] = 0x8ef80000 + (cls >> 16);    /* sethi hi(cls), gr7    */
+  tramp[4] = 0x80300006;                  /* jmpl @(gr0, gr6)      */
+#endif
+
+  closure->cif = cif;
+  closure->fun = fun;
+  closure->user_data = user_data;
+
+  /* Cache flushing.  */
+  for (i = 0; i < FFI_TRAMPOLINE_SIZE; i++)
+    __asm__ volatile ("dcf @(%0,%1)\n\tici @(%0,%1)" :: "r" (tramp), "r" (i));
+
+  return FFI_OK;
+}

Added: vendor/Python/current/Modules/_ctypes/libffi/src/frv/ffitarget.h
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/frv/ffitarget.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/frv/ffitarget.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,60 @@
+/* -----------------------------------------------------------------*-C-*-
+   ffitarget.h - Copyright (c) 1996-2004  Red Hat, Inc.
+   Target configuration macros for FR-V
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+
+   ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+/* ---- System specific configurations ----------------------------------- */
+
+#ifndef LIBFFI_ASM
+typedef unsigned long          ffi_arg;
+typedef signed long            ffi_sarg;
+
+typedef enum ffi_abi {
+  FFI_FIRST_ABI = 0,
+
+#ifdef FRV
+  FFI_EABI,
+  FFI_DEFAULT_ABI = FFI_EABI,
+#endif
+
+  FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
+} ffi_abi;
+#endif
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#define FFI_CLOSURES 1
+#define FFI_NATIVE_RAW_API 0
+
+#ifdef __FRV_FDPIC__
+/* Trampolines are 8 4-byte instructions long.  */
+#define FFI_TRAMPOLINE_SIZE (8*4)
+#else
+/* Trampolines are 5 4-byte instructions long.  */
+#define FFI_TRAMPOLINE_SIZE (5*4)
+#endif
+
+#endif

Added: vendor/Python/current/Modules/_ctypes/libffi/src/ia64/ffi.c
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/ia64/ffi.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/ia64/ffi.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,562 @@
+/* -----------------------------------------------------------------------
+   ffi.c - Copyright (c) 1998 Red Hat, Inc.
+	   Copyright (c) 2000 Hewlett Packard Company
+   
+   IA64 Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+#include <stdbool.h>
+#include <float.h>
+
+#include "ia64_flags.h"
+
+/* A 64-bit pointer value.  In LP64 mode, this is effectively a plain
+   pointer.  In ILP32 mode, it's a pointer that's been extended to 
+   64 bits by "addp4".  */
+typedef void *PTR64 __attribute__((mode(DI)));
+
+/* Memory image of fp register contents.  This is the implementation
+   specific format used by ldf.fill/stf.spill.  All we care about is
+   that it wants a 16 byte aligned slot.  */
+typedef struct
+{
+  UINT64 x[2] __attribute__((aligned(16)));
+} fpreg;
+
+
+/* The stack layout given to ffi_call_unix and ffi_closure_unix_inner.  */
+
+struct ia64_args
+{
+  fpreg fp_regs[8];	/* Contents of 8 fp arg registers.  */
+  UINT64 gp_regs[8];	/* Contents of 8 gp arg registers.  */
+  UINT64 other_args[];	/* Arguments passed on stack, variable size.  */
+};
+
+
+/* Adjust ADDR, a pointer to an 8 byte slot, to point to the low LEN bytes.  */
+
+static inline void *
+endian_adjust (void *addr, size_t len)
+{
+#ifdef __BIG_ENDIAN__
+  return addr + (8 - len);
+#else
+  return addr;
+#endif
+}
+
+/* Store VALUE to ADDR in the current cpu implementation's fp spill format.  */
+
+static inline void
+stf_spill(fpreg *addr, __float80 value)
+{
+  asm ("stf.spill %0 = %1%P0" : "=m" (*addr) : "f"(value));
+}
+
+/* Load a value from ADDR, which is in the current cpu implementation's
+   fp spill format.  */
+
+static inline __float80
+ldf_fill(fpreg *addr)
+{
+  __float80 ret;
+  asm ("ldf.fill %0 = %1%P1" : "=f"(ret) : "m"(*addr));
+  return ret;
+}
+
+/* Return the size of the C type associated with with TYPE.  Which will
+   be one of the FFI_IA64_TYPE_HFA_* values.  */
+
+static size_t
+hfa_type_size (int type)
+{
+  switch (type)
+    {
+    case FFI_IA64_TYPE_HFA_FLOAT:
+      return sizeof(float);
+    case FFI_IA64_TYPE_HFA_DOUBLE:
+      return sizeof(double);
+    case FFI_IA64_TYPE_HFA_LDOUBLE:
+      return sizeof(__float80);
+    default:
+      abort ();
+    }
+}
+
+/* Load from ADDR a value indicated by TYPE.  Which will be one of
+   the FFI_IA64_TYPE_HFA_* values.  */
+
+static __float80
+hfa_type_load (int type, void *addr)
+{
+  switch (type)
+    {
+    case FFI_IA64_TYPE_HFA_FLOAT:
+      return *(float *) addr;
+    case FFI_IA64_TYPE_HFA_DOUBLE:
+      return *(double *) addr;
+    case FFI_IA64_TYPE_HFA_LDOUBLE:
+      return *(__float80 *) addr;
+    default:
+      abort ();
+    }
+}
+
+/* Load VALUE into ADDR as indicated by TYPE.  Which will be one of
+   the FFI_IA64_TYPE_HFA_* values.  */
+
+static void
+hfa_type_store (int type, void *addr, __float80 value)
+{
+  switch (type)
+    {
+    case FFI_IA64_TYPE_HFA_FLOAT:
+      *(float *) addr = value;
+      break;
+    case FFI_IA64_TYPE_HFA_DOUBLE:
+      *(double *) addr = value;
+      break;
+    case FFI_IA64_TYPE_HFA_LDOUBLE:
+      *(__float80 *) addr = value;
+      break;
+    default:
+      abort ();
+    }
+}
+
+/* Is TYPE a struct containing floats, doubles, or extended doubles,
+   all of the same fp type?  If so, return the element type.  Return
+   FFI_TYPE_VOID if not.  */
+
+static int
+hfa_element_type (ffi_type *type, int nested)
+{
+  int element = FFI_TYPE_VOID;
+
+  switch (type->type)
+    {
+    case FFI_TYPE_FLOAT:
+      /* We want to return VOID for raw floating-point types, but the
+	 synthetic HFA type if we're nested within an aggregate.  */
+      if (nested)
+	element = FFI_IA64_TYPE_HFA_FLOAT;
+      break;
+
+    case FFI_TYPE_DOUBLE:
+      /* Similarly.  */
+      if (nested)
+	element = FFI_IA64_TYPE_HFA_DOUBLE;
+      break;
+
+    case FFI_TYPE_LONGDOUBLE:
+      /* Similarly, except that that HFA is true for double extended,
+	 but not quad precision.  Both have sizeof == 16, so tell the
+	 difference based on the precision.  */
+      if (LDBL_MANT_DIG == 64 && nested)
+	element = FFI_IA64_TYPE_HFA_LDOUBLE;
+      break;
+
+    case FFI_TYPE_STRUCT:
+      {
+	ffi_type **ptr = &type->elements[0];
+
+	for (ptr = &type->elements[0]; *ptr ; ptr++)
+	  {
+	    int sub_element = hfa_element_type (*ptr, 1);
+	    if (sub_element == FFI_TYPE_VOID)
+	      return FFI_TYPE_VOID;
+
+	    if (element == FFI_TYPE_VOID)
+	      element = sub_element;
+	    else if (element != sub_element)
+	      return FFI_TYPE_VOID;
+	  }
+      }
+      break;
+
+    default:
+      return FFI_TYPE_VOID;
+    }
+
+  return element;
+}
+
+
+/* Perform machine dependent cif processing. */
+
+ffi_status
+ffi_prep_cif_machdep(ffi_cif *cif)
+{
+  int flags;
+
+  /* Adjust cif->bytes to include space for the bits of the ia64_args frame
+     that preceeds the integer register portion.  The estimate that the 
+     generic bits did for the argument space required is good enough for the
+     integer component.  */
+  cif->bytes += offsetof(struct ia64_args, gp_regs[0]);
+  if (cif->bytes < sizeof(struct ia64_args))
+    cif->bytes = sizeof(struct ia64_args);
+
+  /* Set the return type flag. */
+  flags = cif->rtype->type;
+  switch (cif->rtype->type)
+    {
+    case FFI_TYPE_LONGDOUBLE:
+      /* Leave FFI_TYPE_LONGDOUBLE as meaning double extended precision,
+	 and encode quad precision as a two-word integer structure.  */
+      if (LDBL_MANT_DIG != 64)
+	flags = FFI_IA64_TYPE_SMALL_STRUCT | (16 << 8);
+      break;
+
+    case FFI_TYPE_STRUCT:
+      {
+        size_t size = cif->rtype->size;
+  	int hfa_type = hfa_element_type (cif->rtype, 0);
+
+	if (hfa_type != FFI_TYPE_VOID)
+	  {
+	    size_t nelts = size / hfa_type_size (hfa_type);
+	    if (nelts <= 8)
+	      flags = hfa_type | (size << 8);
+	  }
+	else
+	  {
+	    if (size <= 32)
+	      flags = FFI_IA64_TYPE_SMALL_STRUCT | (size << 8);
+	  }
+      }
+      break;
+
+    default:
+      break;
+    }
+  cif->flags = flags;
+
+  return FFI_OK;
+}
+
+extern int ffi_call_unix (struct ia64_args *, PTR64, void (*)(), UINT64);
+
+void
+ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
+{
+  struct ia64_args *stack;
+  long i, avn, gpcount, fpcount;
+  ffi_type **p_arg;
+
+  FFI_ASSERT (cif->abi == FFI_UNIX);
+
+  /* If we have no spot for a return value, make one.  */
+  if (rvalue == NULL && cif->rtype->type != FFI_TYPE_VOID)
+    rvalue = alloca (cif->rtype->size);
+    
+  /* Allocate the stack frame.  */
+  stack = alloca (cif->bytes);
+
+  gpcount = fpcount = 0;
+  avn = cif->nargs;
+  for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++)
+    {
+      switch ((*p_arg)->type)
+	{
+	case FFI_TYPE_SINT8:
+	  stack->gp_regs[gpcount++] = *(SINT8 *)avalue[i];
+	  break;
+	case FFI_TYPE_UINT8:
+	  stack->gp_regs[gpcount++] = *(UINT8 *)avalue[i];
+	  break;
+	case FFI_TYPE_SINT16:
+	  stack->gp_regs[gpcount++] = *(SINT16 *)avalue[i];
+	  break;
+	case FFI_TYPE_UINT16:
+	  stack->gp_regs[gpcount++] = *(UINT16 *)avalue[i];
+	  break;
+	case FFI_TYPE_SINT32:
+	  stack->gp_regs[gpcount++] = *(SINT32 *)avalue[i];
+	  break;
+	case FFI_TYPE_UINT32:
+	  stack->gp_regs[gpcount++] = *(UINT32 *)avalue[i];
+	  break;
+	case FFI_TYPE_SINT64:
+	case FFI_TYPE_UINT64:
+	  stack->gp_regs[gpcount++] = *(UINT64 *)avalue[i];
+	  break;
+
+	case FFI_TYPE_POINTER:
+	  stack->gp_regs[gpcount++] = (UINT64)(PTR64) *(void **)avalue[i];
+	  break;
+
+	case FFI_TYPE_FLOAT:
+	  if (gpcount < 8 && fpcount < 8)
+	    stf_spill (&stack->fp_regs[fpcount++], *(float *)avalue[i]);
+	  stack->gp_regs[gpcount++] = *(UINT32 *)avalue[i];
+	  break;
+
+	case FFI_TYPE_DOUBLE:
+	  if (gpcount < 8 && fpcount < 8)
+	    stf_spill (&stack->fp_regs[fpcount++], *(double *)avalue[i]);
+	  stack->gp_regs[gpcount++] = *(UINT64 *)avalue[i];
+	  break;
+
+	case FFI_TYPE_LONGDOUBLE:
+	  if (gpcount & 1)
+	    gpcount++;
+	  if (LDBL_MANT_DIG == 64 && gpcount < 8 && fpcount < 8)
+	    stf_spill (&stack->fp_regs[fpcount++], *(__float80 *)avalue[i]);
+	  memcpy (&stack->gp_regs[gpcount], avalue[i], 16);
+	  gpcount += 2;
+	  break;
+
+	case FFI_TYPE_STRUCT:
+	  {
+	    size_t size = (*p_arg)->size;
+	    size_t align = (*p_arg)->alignment;
+	    int hfa_type = hfa_element_type (*p_arg, 0);
+
+	    FFI_ASSERT (align <= 16);
+	    if (align == 16 && (gpcount & 1))
+	      gpcount++;
+
+	    if (hfa_type != FFI_TYPE_VOID)
+	      {
+		size_t hfa_size = hfa_type_size (hfa_type);
+		size_t offset = 0;
+		size_t gp_offset = gpcount * 8;
+
+		while (fpcount < 8
+		       && offset < size
+		       && gp_offset < 8 * 8)
+		  {
+		    stf_spill (&stack->fp_regs[fpcount],
+			       hfa_type_load (hfa_type, avalue[i] + offset));
+		    offset += hfa_size;
+		    gp_offset += hfa_size;
+		    fpcount += 1;
+		  }
+	      }
+
+	    memcpy (&stack->gp_regs[gpcount], avalue[i], size);
+	    gpcount += (size + 7) / 8;
+	  }
+	  break;
+
+	default:
+	  abort ();
+	}
+    }
+
+  ffi_call_unix (stack, rvalue, fn, cif->flags);
+}
+
+/* Closures represent a pair consisting of a function pointer, and
+   some user data.  A closure is invoked by reinterpreting the closure
+   as a function pointer, and branching to it.  Thus we can make an
+   interpreted function callable as a C function: We turn the
+   interpreter itself, together with a pointer specifying the
+   interpreted procedure, into a closure.
+
+   For IA64, function pointer are already pairs consisting of a code
+   pointer, and a gp pointer.  The latter is needed to access global
+   variables.  Here we set up such a pair as the first two words of
+   the closure (in the "trampoline" area), but we replace the gp
+   pointer with a pointer to the closure itself.  We also add the real
+   gp pointer to the closure.  This allows the function entry code to
+   both retrieve the user data, and to restire the correct gp pointer.  */
+
+extern void ffi_closure_unix ();
+
+ffi_status
+ffi_prep_closure (ffi_closure* closure,
+		  ffi_cif* cif,
+		  void (*fun)(ffi_cif*,void*,void**,void*),
+		  void *user_data)
+{
+  /* The layout of a function descriptor.  A C function pointer really 
+     points to one of these.  */
+  struct ia64_fd
+  {
+    UINT64 code_pointer;
+    UINT64 gp;
+  };
+
+  struct ffi_ia64_trampoline_struct
+  {
+    UINT64 code_pointer;	/* Pointer to ffi_closure_unix.  */
+    UINT64 fake_gp;		/* Pointer to closure, installed as gp.  */
+    UINT64 real_gp;		/* Real gp value.  */
+  };
+
+  struct ffi_ia64_trampoline_struct *tramp;
+  struct ia64_fd *fd;
+
+  FFI_ASSERT (cif->abi == FFI_UNIX);
+
+  tramp = (struct ffi_ia64_trampoline_struct *)closure->tramp;
+  fd = (struct ia64_fd *)(void *)ffi_closure_unix;
+
+  tramp->code_pointer = fd->code_pointer;
+  tramp->real_gp = fd->gp;
+  tramp->fake_gp = (UINT64)(PTR64)closure;
+  closure->cif = cif;
+  closure->user_data = user_data;
+  closure->fun = fun;
+
+  return FFI_OK;
+}
+
+
+UINT64
+ffi_closure_unix_inner (ffi_closure *closure, struct ia64_args *stack,
+			void *rvalue, void *r8)
+{
+  ffi_cif *cif;
+  void **avalue;
+  ffi_type **p_arg;
+  long i, avn, gpcount, fpcount;
+
+  cif = closure->cif;
+  avn = cif->nargs;
+  avalue = alloca (avn * sizeof (void *));
+
+  /* If the structure return value is passed in memory get that location
+     from r8 so as to pass the value directly back to the caller.  */
+  if (cif->flags == FFI_TYPE_STRUCT)
+    rvalue = r8;
+
+  gpcount = fpcount = 0;
+  for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++)
+    {
+      switch ((*p_arg)->type)
+	{
+	case FFI_TYPE_SINT8:
+	case FFI_TYPE_UINT8:
+	  avalue[i] = endian_adjust(&stack->gp_regs[gpcount++], 1);
+	  break;
+	case FFI_TYPE_SINT16:
+	case FFI_TYPE_UINT16:
+	  avalue[i] = endian_adjust(&stack->gp_regs[gpcount++], 2);
+	  break;
+	case FFI_TYPE_SINT32:
+	case FFI_TYPE_UINT32:
+	  avalue[i] = endian_adjust(&stack->gp_regs[gpcount++], 4);
+	  break;
+	case FFI_TYPE_SINT64:
+	case FFI_TYPE_UINT64:
+	  avalue[i] = &stack->gp_regs[gpcount++];
+	  break;
+	case FFI_TYPE_POINTER:
+	  avalue[i] = endian_adjust(&stack->gp_regs[gpcount++], sizeof(void*));
+	  break;
+
+	case FFI_TYPE_FLOAT:
+	  if (gpcount < 8 && fpcount < 8)
+	    {
+	      void *addr = &stack->fp_regs[fpcount++];
+	      avalue[i] = addr;
+	      *(float *)addr = ldf_fill (addr);
+	    }
+	  else
+	    avalue[i] = endian_adjust(&stack->gp_regs[gpcount], 4);
+	  gpcount++;
+	  break;
+
+	case FFI_TYPE_DOUBLE:
+	  if (gpcount < 8 && fpcount < 8)
+	    {
+	      void *addr = &stack->fp_regs[fpcount++];
+	      avalue[i] = addr;
+	      *(double *)addr = ldf_fill (addr);
+	    }
+	  else
+	    avalue[i] = &stack->gp_regs[gpcount];
+	  gpcount++;
+	  break;
+
+	case FFI_TYPE_LONGDOUBLE:
+	  if (gpcount & 1)
+	    gpcount++;
+	  if (LDBL_MANT_DIG == 64 && gpcount < 8 && fpcount < 8)
+	    {
+	      void *addr = &stack->fp_regs[fpcount++];
+	      avalue[i] = addr;
+	      *(__float80 *)addr = ldf_fill (addr);
+	    }
+	  else
+	    avalue[i] = &stack->gp_regs[gpcount];
+	  gpcount += 2;
+	  break;
+
+	case FFI_TYPE_STRUCT:
+	  {
+	    size_t size = (*p_arg)->size;
+	    size_t align = (*p_arg)->alignment;
+	    int hfa_type = hfa_element_type (*p_arg, 0);
+
+	    FFI_ASSERT (align <= 16);
+	    if (align == 16 && (gpcount & 1))
+	      gpcount++;
+
+	    if (hfa_type != FFI_TYPE_VOID)
+	      {
+		size_t hfa_size = hfa_type_size (hfa_type);
+		size_t offset = 0;
+		size_t gp_offset = gpcount * 8;
+		void *addr = alloca (size);
+
+		avalue[i] = addr;
+
+		while (fpcount < 8
+		       && offset < size
+		       && gp_offset < 8 * 8)
+		  {
+		    hfa_type_store (hfa_type, addr + offset, 
+				    ldf_fill (&stack->fp_regs[fpcount]));
+		    offset += hfa_size;
+		    gp_offset += hfa_size;
+		    fpcount += 1;
+		  }
+
+		if (offset < size)
+		  memcpy (addr + offset, (char *)stack->gp_regs + gp_offset,
+			  size - offset);
+	      }
+	    else
+	      avalue[i] = &stack->gp_regs[gpcount];
+
+	    gpcount += (size + 7) / 8;
+	  }
+	  break;
+
+	default:
+	  abort ();
+	}
+    }
+
+  closure->fun (cif, rvalue, avalue, closure->user_data);
+
+  return cif->flags;
+}

Added: vendor/Python/current/Modules/_ctypes/libffi/src/ia64/ffitarget.h
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/ia64/ffitarget.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/ia64/ffitarget.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,49 @@
+/* -----------------------------------------------------------------*-C-*-
+   ffitarget.h - Copyright (c) 1996-2003  Red Hat, Inc.
+   Target configuration macros for IA-64.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+
+   ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+#ifndef LIBFFI_ASM
+typedef unsigned long long          ffi_arg;
+typedef signed long long            ffi_sarg;
+
+typedef enum ffi_abi {
+  FFI_FIRST_ABI = 0,
+  FFI_UNIX,   	/* Linux and all Unix variants use the same conventions	*/
+  FFI_DEFAULT_ABI = FFI_UNIX,
+  FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
+} ffi_abi;
+#endif
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#define FFI_CLOSURES 1
+#define FFI_TRAMPOLINE_SIZE 24  /* Really the following struct, which 	*/
+				/* can be interpreted as a C function	*/
+				/* descriptor:				*/
+
+#endif
+

Added: vendor/Python/current/Modules/_ctypes/libffi/src/ia64/ia64_flags.h
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/ia64/ia64_flags.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/ia64/ia64_flags.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,39 @@
+/* -----------------------------------------------------------------------
+   ia64_flags.h - Copyright (c) 2000 Hewlett Packard Company
+   
+   IA64/unix Foreign Function Interface 
+
+   Original author: Hans Boehm, HP Labs
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+/* "Type" codes used between assembly and C.  When used as a part of
+   a cfi->flags value, the low byte will be these extra type codes,
+   and bits 8-31 will be the actual size of the type.  */
+
+/* Small structures containing N words in integer registers.  */
+#define FFI_IA64_TYPE_SMALL_STRUCT	(FFI_TYPE_LAST + 1)
+
+/* Homogeneous Floating Point Aggregates (HFAs) which are returned
+   in FP registers.  */
+#define FFI_IA64_TYPE_HFA_FLOAT		(FFI_TYPE_LAST + 2)
+#define FFI_IA64_TYPE_HFA_DOUBLE	(FFI_TYPE_LAST + 3)
+#define FFI_IA64_TYPE_HFA_LDOUBLE	(FFI_TYPE_LAST + 4)

Added: vendor/Python/current/Modules/_ctypes/libffi/src/ia64/unix.S
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/ia64/unix.S	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/ia64/unix.S	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,555 @@
+/* -----------------------------------------------------------------------
+   unix.S - Copyright (c) 1998 Red Hat, Inc.
+            Copyright (c) 2000 Hewlett Packard Company
+   
+   IA64/unix Foreign Function Interface 
+
+   Primary author: Hans Boehm, HP Labs
+
+   Loosely modeled on Cygnus code for other platforms.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM	
+#include <fficonfig.h>
+#include <ffi.h>
+#include "ia64_flags.h"
+
+	.pred.safe_across_calls p1-p5,p16-p63
+.text
+
+/* int ffi_call_unix (struct ia64_args *stack, PTR64 rvalue,
+		      void (*fn)(), int flags);
+ */
+
+        .align 16
+        .global	ffi_call_unix
+        .proc	ffi_call_unix
+ffi_call_unix:
+	.prologue
+	/* Bit o trickiness.  We actually share a stack frame with ffi_call.
+	   Rely on the fact that ffi_call uses a vframe and don't bother
+	   tracking one here at all.  */
+	.fframe	0
+	.save	ar.pfs, r36 // loc0
+	alloc   loc0 = ar.pfs, 4, 3, 8, 0
+	.save	rp, loc1
+	mov 	loc1 = b0
+	.body
+	add	r16 = 16, in0
+	mov	loc2 = gp
+	mov	r8 = in1
+	;;
+
+	/* Load up all of the argument registers.  */
+	ldf.fill f8 = [in0], 32
+	ldf.fill f9 = [r16], 32
+	;;
+	ldf.fill f10 = [in0], 32
+	ldf.fill f11 = [r16], 32
+	;;
+	ldf.fill f12 = [in0], 32
+	ldf.fill f13 = [r16], 32
+	;;
+	ldf.fill f14 = [in0], 32
+	ldf.fill f15 = [r16], 24
+	;;
+	ld8	out0 = [in0], 16
+	ld8	out1 = [r16], 16
+	;;
+	ld8	out2 = [in0], 16
+	ld8	out3 = [r16], 16
+	;;
+	ld8	out4 = [in0], 16
+	ld8	out5 = [r16], 16
+	;;
+	ld8	out6 = [in0]
+	ld8	out7 = [r16]
+	;;
+
+	/* Deallocate the register save area from the stack frame.  */
+	mov	sp = in0
+
+	/* Call the target function.  */
+	ld8	r16 = [in2], 8
+	;;
+	ld8	gp = [in2]
+	mov	b6 = r16
+	br.call.sptk.many b0 = b6
+	;;
+
+	/* Dispatch to handle return value.  */
+	mov	gp = loc2
+	zxt1	r16 = in3
+	;;
+	mov	ar.pfs = loc0
+	addl	r18 = @ltoffx(.Lst_table), gp
+	;;
+	ld8.mov	r18 = [r18], .Lst_table
+	mov	b0 = loc1
+	;;
+	shladd	r18 = r16, 3, r18
+	;;
+	ld8	r17 = [r18]
+	shr	in3 = in3, 8
+	;;
+	add	r17 = r17, r18
+	;;
+	mov	b6 = r17
+	br	b6
+	;;
+
+.Lst_void:
+	br.ret.sptk.many b0
+	;;
+.Lst_uint8:
+	zxt1	r8 = r8
+	;;
+	st8	[in1] = r8
+	br.ret.sptk.many b0
+	;;
+.Lst_sint8:
+	sxt1	r8 = r8
+	;;
+	st8	[in1] = r8
+	br.ret.sptk.many b0
+	;;
+.Lst_uint16:
+	zxt2	r8 = r8
+	;;
+	st8	[in1] = r8
+	br.ret.sptk.many b0
+	;;
+.Lst_sint16:
+	sxt2	r8 = r8
+	;;
+	st8	[in1] = r8
+	br.ret.sptk.many b0
+	;;
+.Lst_uint32:
+	zxt4	r8 = r8
+	;;
+	st8	[in1] = r8
+	br.ret.sptk.many b0
+	;;
+.Lst_sint32:
+	sxt4	r8 = r8
+	;;
+	st8	[in1] = r8
+	br.ret.sptk.many b0
+	;;
+.Lst_int64:
+	st8	[in1] = r8
+	br.ret.sptk.many b0
+	;;
+.Lst_float:
+	stfs	[in1] = f8
+	br.ret.sptk.many b0
+	;;
+.Lst_double:
+	stfd	[in1] = f8
+	br.ret.sptk.many b0
+	;;
+.Lst_ldouble:
+	stfe	[in1] = f8
+	br.ret.sptk.many b0
+	;;
+
+.Lst_small_struct:
+	add	sp = -16, sp
+	cmp.lt	p6, p0 = 8, in3
+	cmp.lt	p7, p0 = 16, in3
+	cmp.lt	p8, p0 = 24, in3
+	;;
+	add	r16 = 8, sp
+	add	r17 = 16, sp
+	add	r18 = 24, sp
+	;;
+	st8	[sp] = r8
+(p6)	st8	[r16] = r9
+	mov	out0 = in1
+(p7)	st8	[r17] = r10
+(p8)	st8	[r18] = r11
+	mov	out1 = sp
+	mov	out2 = in3
+	br.call.sptk.many b0 = memcpy#
+	;;
+	mov	ar.pfs = loc0
+	mov	b0 = loc1
+	mov	gp = loc2
+	br.ret.sptk.many b0
+
+.Lst_hfa_float:
+	add	r16 = 4, in1
+	cmp.lt	p6, p0 = 4, in3
+	;;
+	stfs	[in1] = f8, 8
+(p6)	stfs	[r16] = f9, 8
+	cmp.lt	p7, p0 = 8, in3
+	cmp.lt	p8, p0 = 12, in3
+	;;
+(p7)	stfs	[in1] = f10, 8
+(p8)	stfs	[r16] = f11, 8
+	cmp.lt	p9, p0 = 16, in3
+	cmp.lt	p10, p0 = 20, in3
+	;;
+(p9)	stfs	[in1] = f12, 8
+(p10)	stfs	[r16] = f13, 8
+	cmp.lt	p6, p0 = 24, in3
+	cmp.lt	p7, p0 = 28, in3
+	;;
+(p6)	stfs	[in1] = f14
+(p7)	stfs	[r16] = f15
+	br.ret.sptk.many b0
+	;;
+
+.Lst_hfa_double:
+	add	r16 = 8, in1
+	cmp.lt	p6, p0 = 8, in3
+	;;
+	stfd	[in1] = f8, 16
+(p6)	stfd	[r16] = f9, 16
+	cmp.lt	p7, p0 = 16, in3
+	cmp.lt	p8, p0 = 24, in3
+	;;
+(p7)	stfd	[in1] = f10, 16
+(p8)	stfd	[r16] = f11, 16
+	cmp.lt	p9, p0 = 32, in3
+	cmp.lt	p10, p0 = 40, in3
+	;;
+(p9)	stfd	[in1] = f12, 16
+(p10)	stfd	[r16] = f13, 16
+	cmp.lt	p6, p0 = 48, in3
+	cmp.lt	p7, p0 = 56, in3
+	;;
+(p6)	stfd	[in1] = f14
+(p7)	stfd	[r16] = f15
+	br.ret.sptk.many b0
+	;;
+
+.Lst_hfa_ldouble:
+	add	r16 = 16, in1
+	cmp.lt	p6, p0 = 16, in3
+	;;
+	stfe	[in1] = f8, 32
+(p6)	stfe	[r16] = f9, 32
+	cmp.lt	p7, p0 = 32, in3
+	cmp.lt	p8, p0 = 48, in3
+	;;
+(p7)	stfe	[in1] = f10, 32
+(p8)	stfe	[r16] = f11, 32
+	cmp.lt	p9, p0 = 64, in3
+	cmp.lt	p10, p0 = 80, in3
+	;;
+(p9)	stfe	[in1] = f12, 32
+(p10)	stfe	[r16] = f13, 32
+	cmp.lt	p6, p0 = 96, in3
+	cmp.lt	p7, p0 = 112, in3
+	;;
+(p6)	stfe	[in1] = f14
+(p7)	stfe	[r16] = f15
+	br.ret.sptk.many b0
+	;;
+
+        .endp ffi_call_unix
+
+        .align 16
+        .global ffi_closure_unix
+        .proc ffi_closure_unix
+
+#define FRAME_SIZE	(8*16 + 8*8 + 8*16)
+
+ffi_closure_unix:
+	.prologue
+	.save	ar.pfs, r40 // loc0
+	alloc   loc0 = ar.pfs, 8, 4, 4, 0
+	.fframe	FRAME_SIZE
+	add	r12 = -FRAME_SIZE, r12
+	.save	rp, loc1
+	mov	loc1 = b0
+	.save	ar.unat, loc2
+	mov	loc2 = ar.unat
+	.body
+
+	/* Retrieve closure pointer and real gp.  */
+#ifdef _ILP32
+	addp4	out0 = 0, gp
+	addp4	gp = 16, gp
+#else
+	mov	out0 = gp
+	add	gp = 16, gp
+#endif
+	;;
+	ld8	gp = [gp]
+
+	/* Spill all of the possible argument registers.  */
+	add	r16 = 16 + 8*16, sp
+	add	r17 = 16 + 8*16 + 16, sp
+	;;
+	stf.spill [r16] = f8, 32
+	stf.spill [r17] = f9, 32
+	mov	loc3 = gp
+	;;
+	stf.spill [r16] = f10, 32
+	stf.spill [r17] = f11, 32
+	;;
+	stf.spill [r16] = f12, 32
+	stf.spill [r17] = f13, 32
+	;;
+	stf.spill [r16] = f14, 32
+	stf.spill [r17] = f15, 24
+	;;
+	.mem.offset 0, 0
+	st8.spill [r16] = in0, 16
+	.mem.offset 8, 0
+	st8.spill [r17] = in1, 16
+	add	out1 = 16 + 8*16, sp
+	;;
+	.mem.offset 0, 0
+	st8.spill [r16] = in2, 16
+	.mem.offset 8, 0
+	st8.spill [r17] = in3, 16
+	add	out2 = 16, sp
+	;;
+	.mem.offset 0, 0
+	st8.spill [r16] = in4, 16
+	.mem.offset 8, 0
+	st8.spill [r17] = in5, 16
+	mov	out3 = r8
+	;;
+	.mem.offset 0, 0
+	st8.spill [r16] = in6
+	.mem.offset 8, 0
+	st8.spill [r17] = in7
+
+	/* Invoke ffi_closure_unix_inner for the hard work.  */
+	br.call.sptk.many b0 = ffi_closure_unix_inner
+	;;
+
+	/* Dispatch to handle return value.  */
+	mov	gp = loc3
+	zxt1	r16 = r8
+	;;
+	addl	r18 = @ltoffx(.Lld_table), gp
+	mov	ar.pfs = loc0
+	;;
+	ld8.mov	r18 = [r18], .Lld_table
+	mov	b0 = loc1
+	;;
+	shladd	r18 = r16, 3, r18
+	mov	ar.unat = loc2
+	;;
+	ld8	r17 = [r18]
+	shr	r8 = r8, 8
+	;;
+	add	r17 = r17, r18
+	add	r16 = 16, sp
+	;;
+	mov	b6 = r17
+	br	b6
+	;;
+	.label_state 1
+
+.Lld_void:
+	.restore sp
+	add	sp = FRAME_SIZE, sp
+	br.ret.sptk.many b0
+	;;
+.Lld_int:
+	.body
+	.copy_state 1
+	ld8	r8 = [r16]
+	.restore sp
+	add	sp = FRAME_SIZE, sp
+	br.ret.sptk.many b0
+	;;
+.Lld_float:
+	.body
+	.copy_state 1
+	ldfs	f8 = [r16]
+	.restore sp
+	add	sp = FRAME_SIZE, sp
+	br.ret.sptk.many b0
+	;;
+.Lld_double:
+	.body
+	.copy_state 1
+	ldfd	f8 = [r16]
+	.restore sp
+	add	sp = FRAME_SIZE, sp
+	br.ret.sptk.many b0
+	;;
+.Lld_ldouble:
+	.body
+	.copy_state 1
+	ldfe	f8 = [r16]
+	.restore sp
+	add	sp = FRAME_SIZE, sp
+	br.ret.sptk.many b0
+	;;
+
+.Lld_small_struct:
+	.body
+	.copy_state 1
+	add	r17 = 8, r16
+	cmp.lt	p6, p0 = 8, r8
+	cmp.lt	p7, p0 = 16, r8
+	cmp.lt	p8, p0 = 24, r8
+	;;
+	ld8	r8 = [r16], 16
+(p6)	ld8	r9 = [r17], 16
+	;;
+(p7)	ld8	r10 = [r16]
+(p8)	ld8	r11 = [r17]
+	.restore sp
+	add	sp = FRAME_SIZE, sp
+	br.ret.sptk.many b0
+	;;
+
+.Lld_hfa_float:
+	.body
+	.copy_state 1
+	add	r17 = 4, r16
+	cmp.lt	p6, p0 = 4, r8
+	;;
+	ldfs	f8 = [r16], 8
+(p6)	ldfs	f9 = [r17], 8
+	cmp.lt	p7, p0 = 8, r8
+	cmp.lt	p8, p0 = 12, r8
+	;;
+(p7)	ldfs	f10 = [r16], 8
+(p8)	ldfs	f11 = [r17], 8
+	cmp.lt	p9, p0 = 16, r8
+	cmp.lt	p10, p0 = 20, r8
+	;;
+(p9)	ldfs	f12 = [r16], 8
+(p10)	ldfs	f13 = [r17], 8
+	cmp.lt	p6, p0 = 24, r8
+	cmp.lt	p7, p0 = 28, r8
+	;;
+(p6)	ldfs	f14 = [r16]
+(p7)	ldfs	f15 = [r17]
+	.restore sp
+	add	sp = FRAME_SIZE, sp
+	br.ret.sptk.many b0
+	;;
+
+.Lld_hfa_double:
+	.body
+	.copy_state 1
+	add	r17 = 8, r16
+	cmp.lt	p6, p0 = 8, r8
+	;;
+	ldfd	f8 = [r16], 16
+(p6)	ldfd	f9 = [r17], 16
+	cmp.lt	p7, p0 = 16, r8
+	cmp.lt	p8, p0 = 24, r8
+	;;
+(p7)	ldfd	f10 = [r16], 16
+(p8)	ldfd	f11 = [r17], 16
+	cmp.lt	p9, p0 = 32, r8
+	cmp.lt	p10, p0 = 40, r8
+	;;
+(p9)	ldfd	f12 = [r16], 16
+(p10)	ldfd	f13 = [r17], 16
+	cmp.lt	p6, p0 = 48, r8
+	cmp.lt	p7, p0 = 56, r8
+	;;
+(p6)	ldfd	f14 = [r16]
+(p7)	ldfd	f15 = [r17]
+	.restore sp
+	add	sp = FRAME_SIZE, sp
+	br.ret.sptk.many b0
+	;;
+
+.Lld_hfa_ldouble:
+	.body
+	.copy_state 1
+	add	r17 = 16, r16
+	cmp.lt	p6, p0 = 16, r8
+	;;
+	ldfe	f8 = [r16], 32
+(p6)	ldfe	f9 = [r17], 32
+	cmp.lt	p7, p0 = 32, r8
+	cmp.lt	p8, p0 = 48, r8
+	;;
+(p7)	ldfe	f10 = [r16], 32
+(p8)	ldfe	f11 = [r17], 32
+	cmp.lt	p9, p0 = 64, r8
+	cmp.lt	p10, p0 = 80, r8
+	;;
+(p9)	ldfe	f12 = [r16], 32
+(p10)	ldfe	f13 = [r17], 32
+	cmp.lt	p6, p0 = 96, r8
+	cmp.lt	p7, p0 = 112, r8
+	;;
+(p6)	ldfe	f14 = [r16]
+(p7)	ldfe	f15 = [r17]
+	.restore sp
+	add	sp = FRAME_SIZE, sp
+	br.ret.sptk.many b0
+	;;
+
+	.endp	ffi_closure_unix
+
+	.section .rodata
+	.align	8
+.Lst_table:
+	data8	@pcrel(.Lst_void)		// FFI_TYPE_VOID
+	data8	@pcrel(.Lst_sint32)		// FFI_TYPE_INT
+	data8	@pcrel(.Lst_float)		// FFI_TYPE_FLOAT
+	data8	@pcrel(.Lst_double)		// FFI_TYPE_DOUBLE
+	data8	@pcrel(.Lst_ldouble)		// FFI_TYPE_LONGDOUBLE
+	data8	@pcrel(.Lst_uint8)		// FFI_TYPE_UINT8
+	data8	@pcrel(.Lst_sint8)		// FFI_TYPE_SINT8
+	data8	@pcrel(.Lst_uint16)		// FFI_TYPE_UINT16
+	data8	@pcrel(.Lst_sint16)		// FFI_TYPE_SINT16
+	data8	@pcrel(.Lst_uint32)		// FFI_TYPE_UINT32
+	data8	@pcrel(.Lst_sint32)		// FFI_TYPE_SINT32
+	data8	@pcrel(.Lst_int64)		// FFI_TYPE_UINT64
+	data8	@pcrel(.Lst_int64)		// FFI_TYPE_SINT64
+	data8	@pcrel(.Lst_void)		// FFI_TYPE_STRUCT
+	data8	@pcrel(.Lst_int64)		// FFI_TYPE_POINTER
+	data8 	@pcrel(.Lst_small_struct)	// FFI_IA64_TYPE_SMALL_STRUCT
+	data8	@pcrel(.Lst_hfa_float)		// FFI_IA64_TYPE_HFA_FLOAT
+	data8	@pcrel(.Lst_hfa_double)		// FFI_IA64_TYPE_HFA_DOUBLE
+	data8	@pcrel(.Lst_hfa_ldouble)	// FFI_IA64_TYPE_HFA_LDOUBLE
+
+.Lld_table:
+	data8	@pcrel(.Lld_void)		// FFI_TYPE_VOID
+	data8	@pcrel(.Lld_int)		// FFI_TYPE_INT
+	data8	@pcrel(.Lld_float)		// FFI_TYPE_FLOAT
+	data8	@pcrel(.Lld_double)		// FFI_TYPE_DOUBLE
+	data8	@pcrel(.Lld_ldouble)		// FFI_TYPE_LONGDOUBLE
+	data8	@pcrel(.Lld_int)		// FFI_TYPE_UINT8
+	data8	@pcrel(.Lld_int)		// FFI_TYPE_SINT8
+	data8	@pcrel(.Lld_int)		// FFI_TYPE_UINT16
+	data8	@pcrel(.Lld_int)		// FFI_TYPE_SINT16
+	data8	@pcrel(.Lld_int)		// FFI_TYPE_UINT32
+	data8	@pcrel(.Lld_int)		// FFI_TYPE_SINT32
+	data8	@pcrel(.Lld_int)		// FFI_TYPE_UINT64
+	data8	@pcrel(.Lld_int)		// FFI_TYPE_SINT64
+	data8	@pcrel(.Lld_void)		// FFI_TYPE_STRUCT
+	data8	@pcrel(.Lld_int)		// FFI_TYPE_POINTER
+	data8 	@pcrel(.Lld_small_struct)	// FFI_IA64_TYPE_SMALL_STRUCT
+	data8	@pcrel(.Lld_hfa_float)		// FFI_IA64_TYPE_HFA_FLOAT
+	data8	@pcrel(.Lld_hfa_double)		// FFI_IA64_TYPE_HFA_DOUBLE
+	data8	@pcrel(.Lld_hfa_ldouble)	// FFI_IA64_TYPE_HFA_LDOUBLE

Added: vendor/Python/current/Modules/_ctypes/libffi/src/m32r/ffi.c
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/m32r/ffi.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/m32r/ffi.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,247 @@
+/* -----------------------------------------------------------------------
+   ffi.c - Copyright (c) 2004  Renesas Technology
+   
+   M32R Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL RENESAS TECHNOLOGY BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+
+/* ffi_prep_args is called by the assembly routine once stack
+   space has been allocated for the function's arguments.  */
+
+/*@-exportheader@*/
+void ffi_prep_args(char *stack, extended_cif *ecif)
+/*@=exportheader@*/
+{
+  unsigned int i;
+  int tmp;
+  unsigned int avn;
+  void **p_argv;
+  char *argp;
+  ffi_type **p_arg;
+
+  tmp = 0;
+  argp = stack;
+
+  if (ecif->cif->rtype->type == FFI_TYPE_STRUCT && ecif->cif->rtype->size > 8)
+    {
+      *(void **) argp = ecif->rvalue;
+      argp += 4;
+    }
+
+  avn = ecif->cif->nargs;
+  p_argv = ecif->avalue;
+
+  for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
+       (i != 0) && (avn != 0);
+       i--, p_arg++)
+    {
+      size_t z;
+
+      /* Align if necessary.  */
+      if (((*p_arg)->alignment - 1) & (unsigned) argp)
+	argp = (char *) ALIGN (argp, (*p_arg)->alignment);
+
+      if (avn != 0) 
+	{
+	  avn--;
+	  z = (*p_arg)->size;
+	  if (z < sizeof (int))
+	    {
+	      z = sizeof (int);
+
+	      switch ((*p_arg)->type)
+		{
+		case FFI_TYPE_SINT8:
+		  *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
+		  break;
+		  
+		case FFI_TYPE_UINT8:
+		  *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
+		  break;
+		  
+		case FFI_TYPE_SINT16:
+		  *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
+		  break;
+		  
+		case FFI_TYPE_UINT16:
+		  *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
+		  break;
+		  
+		case FFI_TYPE_STRUCT:
+	  	  z = (*p_arg)->size;
+	  	  if ((*p_arg)->alignment != 1)
+		    memcpy (argp, *p_argv, z);
+		  else
+		    memcpy (argp + 4 - z, *p_argv, z);
+	  	  z = sizeof (int);
+		  break;
+
+		default:
+		  FFI_ASSERT(0);
+		}
+	    }
+	  else if (z == sizeof (int))
+	    {
+	       *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+	    }
+	  else
+	    {
+	      if ((*p_arg)->type == FFI_TYPE_STRUCT)
+	        {
+		  if (z > 8)
+		    {
+		      *(unsigned int *) argp = (unsigned int)(void *)(* p_argv);
+		      z = sizeof(void *);
+		    }
+		  else
+		    {
+	              memcpy(argp, *p_argv, z);
+		      z = 8;
+		    }
+	        }
+	      else
+	        {
+		  /* Double or long long 64bit.  */
+	          memcpy (argp, *p_argv, z);
+	        }
+	    }
+	  p_argv++;
+	  argp += z;
+	}
+    }
+  
+  return;
+}
+
+/* Perform machine dependent cif processing.  */
+ffi_status
+ffi_prep_cif_machdep(ffi_cif *cif)
+{
+  /* Set the return type flag.  */
+  switch (cif->rtype->type)
+    {
+    case FFI_TYPE_VOID:
+      cif->flags = (unsigned) cif->rtype->type;
+      break;
+
+    case FFI_TYPE_STRUCT:
+      if (cif->rtype->size <= 4)
+	cif->flags = FFI_TYPE_INT;
+
+      else if (cif->rtype->size <= 8)
+	cif->flags = FFI_TYPE_DOUBLE;
+
+      else
+	cif->flags = (unsigned) cif->rtype->type;
+      break;
+
+    case FFI_TYPE_SINT64:
+    case FFI_TYPE_UINT64:
+    case FFI_TYPE_DOUBLE:
+      cif->flags = FFI_TYPE_DOUBLE;
+      break;
+
+    case FFI_TYPE_FLOAT:
+    default:
+      cif->flags = FFI_TYPE_INT;
+      break;
+    }
+
+  return FFI_OK;
+}
+
+/*@-declundef@*/
+/*@-exportheader@*/
+extern void ffi_call_SYSV(void (*)(char *, extended_cif *), 
+			  /*@out@*/ extended_cif *, 
+			  unsigned, unsigned, 
+			  /*@out@*/ unsigned *, 
+			  void (*fn)());
+/*@=declundef@*/
+/*@=exportheader@*/
+
+void ffi_call(/*@dependent@*/ ffi_cif *cif, 
+	      void (*fn)(), 
+	      /*@out@*/ void *rvalue, 
+	      /*@dependent@*/ void **avalue)
+{
+  extended_cif ecif;
+
+  ecif.cif = cif;
+  ecif.avalue = avalue;
+  
+  /* If the return value is a struct and we don't have
+     a return value address then we need to make one.  */
+  if ((rvalue == NULL) && 
+      (cif->rtype->type == FFI_TYPE_STRUCT))
+    {
+      /*@-sysunrecog@*/
+      ecif.rvalue = alloca (cif->rtype->size);
+      /*@=sysunrecog@*/
+    }
+  else
+    ecif.rvalue = rvalue;    
+  
+  switch (cif->abi) 
+    {
+    case FFI_SYSV:
+      /*@-usedef@*/
+      ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, 
+		    cif->flags, ecif.rvalue, fn);
+      if (cif->rtype->type == FFI_TYPE_STRUCT)
+	{
+	  int size = cif->rtype->size;
+	  int align = cif->rtype->alignment;
+
+	  if (size < 4)
+	    {
+	      if (align == 1)
+	        *(unsigned long *)(ecif.rvalue) <<= (4 - size) * 8;
+	    }
+	  else if (4 < size && size < 8)
+	    {
+	      if (align == 1)
+		{
+		  memcpy (ecif.rvalue, ecif.rvalue + 8-size, size);
+		}
+	      else if (align == 2)
+		{
+		  if (size & 1)
+		    size += 1;
+
+		  if (size != 8)
+		    memcpy (ecif.rvalue, ecif.rvalue + 8-size, size);
+		}
+	    }
+	}
+      /*@=usedef@*/
+      break;
+
+    default:
+      FFI_ASSERT(0);
+      break;
+    }
+}

Added: vendor/Python/current/Modules/_ctypes/libffi/src/m32r/ffitarget.h
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/m32r/ffitarget.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/m32r/ffitarget.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,48 @@
+/* -----------------------------------------------------------------*-C-*-
+   ffitarget.h - Copyright (c) 2004  Renesas Technology.
+   Target configuration macros for M32R.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL RENESAS TECHNOLOGY BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+
+   ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+/* ---- Generic type definitions ----------------------------------------- */
+
+#ifndef LIBFFI_ASM
+typedef unsigned long          ffi_arg;
+typedef signed long            ffi_sarg;
+
+typedef enum ffi_abi
+  {
+    FFI_FIRST_ABI = 0,
+    FFI_SYSV,
+    FFI_DEFAULT_ABI = FFI_SYSV,
+    FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
+  } ffi_abi;
+#endif
+
+#define FFI_CLOSURES 		0
+#define FFI_TRAMPOLINE_SIZE	24
+#define FFI_NATIVE_RAW_API 	0
+
+#endif

Added: vendor/Python/current/Modules/_ctypes/libffi/src/m32r/sysv.S
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/m32r/sysv.S	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/m32r/sysv.S	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,121 @@
+/* -----------------------------------------------------------------------
+   sysv.S - Copyright (c) 2004 Renesas Technology
+   
+   M32R Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL RENESAS TECHNOLOGY BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+#ifdef HAVE_MACHINE_ASM_H
+#include <machine/asm.h>
+#else
+/* XXX these lose for some platforms, I'm sure.  */
+#define CNAME(x) x
+#define ENTRY(x) .globl CNAME(x)! .type CNAME(x),%function! CNAME(x):
+#endif
+
+.text
+
+	/* R0:   ffi_prep_args */
+	/* R1:   &ecif */
+	/* R2:   cif->bytes */
+	/* R3:   fig->flags */
+	/* sp+0: ecif.rvalue */
+	/* sp+4: fn */
+
+	/* This assumes we are using gas.  */
+ENTRY(ffi_call_SYSV)
+	/* Save registers.  */
+	push	fp
+	push	lr
+	push	r3
+	push	r2
+	push	r1
+	push	r0
+	mv	fp, sp
+
+	/* Make room for all of the new args.  */
+	sub	sp, r2
+
+	/* Place all of the ffi_prep_args in position.  */
+	mv	lr, r0	
+	mv	r0, sp
+	/* R1 already set.  */
+
+	/* And call.  */
+	jl	lr
+
+	/* Move first 4 parameters in registers...  */
+	ld	r0, @(0,sp)
+	ld	r1, @(4,sp)
+	ld	r2, @(8,sp)
+        ld	r3, @(12,sp)
+
+	/* ...and adjust the stack.  */
+	ld	lr, @(8,fp)
+        cmpi	lr, #16
+	bc	adjust_stack
+	ldi	lr, #16
+adjust_stack:
+        add	sp, lr
+
+	/* Call the function.  */
+	ld	lr, @(28,fp)
+	jl	lr	
+
+	/* Remove the space we pushed for the args.  */
+	mv	sp, fp	
+
+	/* Load R2 with the pointer to storage for the return value.  */
+	ld	r2, @(24,sp)
+
+	/* Load R3 with the return type code.  */
+	ld	r3, @(12,sp)
+
+	/* If the return value pointer is NULL, assume no return value.  */
+	beqz	r2, epilogue
+
+	/* Return INT.  */
+	ldi	r4, #FFI_TYPE_INT
+	bne	r3, r4, return_double
+	st	r0, @r2	
+	bra	epilogue
+
+return_double:
+	/* Return DOUBLE or LONGDOUBLE.  */
+	ldi	r4, #FFI_TYPE_DOUBLE
+	bne	r3, r4, epilogue
+	st	r0, @r2	
+	st	r1, @(4,r2)
+
+epilogue:
+	pop	r0
+	pop	r1
+	pop	r2
+	pop	r3
+	pop	lr
+	pop	fp
+        jmp lr
+
+.ffi_call_SYSV_end:
+        .size    CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV)

Added: vendor/Python/current/Modules/_ctypes/libffi/src/m68k/ffi.c
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/m68k/ffi.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/m68k/ffi.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,176 @@
+/* -----------------------------------------------------------------------
+   ffi.c
+   
+   m68k Foreign Function Interface 
+   ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+
+/* ffi_prep_args is called by the assembly routine once stack space has
+   been allocated for the function's arguments.  */
+
+static void *
+ffi_prep_args (void *stack, extended_cif *ecif)
+{
+  unsigned int i;
+  void **p_argv;
+  char *argp;
+  ffi_type **p_arg;
+  void *struct_value_ptr;
+
+  argp = stack;
+
+  if (ecif->cif->rtype->type == FFI_TYPE_STRUCT
+      && ecif->cif->rtype->size > 8)
+    struct_value_ptr = ecif->rvalue;
+  else
+    struct_value_ptr = NULL;
+
+  p_argv = ecif->avalue;
+
+  for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
+       i != 0;
+       i--, p_arg++)
+    {
+      size_t z;
+
+      /* Align if necessary.  */
+      if (((*p_arg)->alignment - 1) & (unsigned) argp)
+	argp = (char *) ALIGN (argp, (*p_arg)->alignment);
+
+	  z = (*p_arg)->size;
+	  if (z < sizeof (int))
+	    {
+	      switch ((*p_arg)->type)
+		{
+		case FFI_TYPE_SINT8:
+		  *(signed int *) argp = (signed int) *(SINT8 *) *p_argv;
+		  break;
+
+		case FFI_TYPE_UINT8:
+		  *(unsigned int *) argp = (unsigned int) *(UINT8 *) *p_argv;
+		  break;
+
+		case FFI_TYPE_SINT16:
+		  *(signed int *) argp = (signed int) *(SINT16 *) *p_argv;
+		  break;
+
+		case FFI_TYPE_UINT16:
+		  *(unsigned int *) argp = (unsigned int) *(UINT16 *) *p_argv;
+		  break;
+
+		case FFI_TYPE_STRUCT:
+		  memcpy (argp + sizeof (int) - z, *p_argv, z);
+		  break;
+
+		default:
+		  FFI_ASSERT (0);
+		}
+	      z = sizeof (int);
+	    }
+	  else
+	    memcpy (argp, *p_argv, z);
+	  p_argv++;
+	  argp += z;
+    }
+
+  return struct_value_ptr;
+}
+
+#define CIF_FLAGS_INT		1
+#define CIF_FLAGS_DINT		2
+#define CIF_FLAGS_FLOAT		4
+#define CIF_FLAGS_DOUBLE	8
+#define CIF_FLAGS_LDOUBLE	16
+#define CIF_FLAGS_POINTER	32
+#define CIF_FLAGS_STRUCT	64
+
+/* Perform machine dependent cif processing */
+ffi_status
+ffi_prep_cif_machdep (ffi_cif *cif)
+{
+  /* Set the return type flag */
+  switch (cif->rtype->type)
+    {
+    case FFI_TYPE_VOID:
+      cif->flags = 0;
+      break;
+
+    case FFI_TYPE_STRUCT:
+      if (cif->rtype->size > 4 && cif->rtype->size <= 8)
+	cif->flags = CIF_FLAGS_DINT;
+      else if (cif->rtype->size <= 4)
+	cif->flags = CIF_FLAGS_STRUCT;
+      else
+	cif->flags = 0;
+      break;
+
+    case FFI_TYPE_FLOAT:
+      cif->flags = CIF_FLAGS_FLOAT;
+      break;
+
+    case FFI_TYPE_DOUBLE:
+      cif->flags = CIF_FLAGS_DOUBLE;
+      break;
+
+    case FFI_TYPE_LONGDOUBLE:
+      cif->flags = CIF_FLAGS_LDOUBLE;
+      break;
+
+    case FFI_TYPE_POINTER:
+      cif->flags = CIF_FLAGS_POINTER;
+      break;
+
+    case FFI_TYPE_SINT64:
+    case FFI_TYPE_UINT64:
+      cif->flags = CIF_FLAGS_DINT;
+      break;
+
+    default:
+      cif->flags = CIF_FLAGS_INT;
+      break;
+    }
+
+  return FFI_OK;
+}
+
+extern void ffi_call_SYSV (void *(*) (void *, extended_cif *), 
+			   extended_cif *, 
+			   unsigned, unsigned, unsigned,
+			   void *, void (*fn) ());
+
+void
+ffi_call (ffi_cif *cif, void (*fn) (), void *rvalue, void **avalue)
+{
+  extended_cif ecif;
+
+  ecif.cif = cif;
+  ecif.avalue = avalue;
+  
+  /* If the return value is a struct and we don't have a return value
+     address then we need to make one.  */
+
+  if (rvalue == NULL
+      && cif->rtype->type == FFI_TYPE_STRUCT
+      && cif->rtype->size > 8)
+    ecif.rvalue = alloca (cif->rtype->size);
+  else
+    ecif.rvalue = rvalue;
+    
+  
+  switch (cif->abi) 
+    {
+    case FFI_SYSV:
+      ffi_call_SYSV (ffi_prep_args, &ecif, cif->bytes, 
+		     cif->flags, cif->rtype->size * 8,
+		     ecif.rvalue, fn);
+      break;
+
+    default:
+      FFI_ASSERT (0);
+      break;
+    }
+}

Added: vendor/Python/current/Modules/_ctypes/libffi/src/m68k/ffitarget.h
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/m68k/ffitarget.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/m68k/ffitarget.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,47 @@
+/* -----------------------------------------------------------------*-C-*-
+   ffitarget.h - Copyright (c) 1996-2003  Red Hat, Inc.
+   Target configuration macros for Motorola 68K.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+
+   ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+#ifndef LIBFFI_ASM
+typedef unsigned long          ffi_arg;
+typedef signed long            ffi_sarg;
+
+typedef enum ffi_abi {
+  FFI_FIRST_ABI = 0,
+  FFI_SYSV,
+  FFI_DEFAULT_ABI = FFI_SYSV,
+  FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
+} ffi_abi;
+#endif
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#define FFI_CLOSURES 0
+#define FFI_NATIVE_RAW_API 0
+
+#endif
+

Added: vendor/Python/current/Modules/_ctypes/libffi/src/m68k/sysv.S
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/m68k/sysv.S	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/m68k/sysv.S	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,97 @@
+/* -----------------------------------------------------------------------
+   sysv.S
+   
+   m68k Foreign Function Interface 
+   ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM	
+#include <fficonfig.h>
+#include <ffi.h>
+
+	.text
+
+	.globl	ffi_call_SYSV
+	.type	ffi_call_SYSV, at function
+
+ffi_call_SYSV:
+	link	%fp,#0
+	move.l	%d2,-(%sp)
+
+	| Make room for all of the new args.
+	sub.l	16(%fp),%sp
+
+	| Call ffi_prep_args
+	move.l	12(%fp),-(%sp)
+	pea	4(%sp)
+	move.l	8(%fp),%a0
+	jsr	(%a0)
+	addq.l	#8,%sp	
+
+	| Pass pointer to struct value, if any
+	move.l	%a0,%a1
+
+	| Call the function
+	move.l	32(%fp),%a0
+	jsr	(%a0)
+
+	| Remove the space we pushed for the args
+	add.l	16(%fp),%sp
+
+	| Load the pointer to storage for the return value
+	move.l	28(%fp),%a1
+
+	| Load the return type code 
+	move.l	20(%fp),%d2
+
+	| If the return value pointer is NULL, assume no return value.
+	tst.l	%a1
+	jbeq	noretval
+
+	btst	#0,%d2
+	jbeq	retlongint
+	move.l	%d0,(%a1)
+	jbra	epilogue
+
+retlongint:
+	btst	#1,%d2
+	jbeq	retfloat
+	move.l	%d0,(%a1)
+	move.l	%d1,4(%a1)
+	jbra	epilogue
+
+retfloat:
+	btst	#2,%d2
+	jbeq	retdouble
+	fmove.s	%fp0,(%a1)
+	jbra	epilogue
+
+retdouble:
+	btst	#3,%d2
+	jbeq	retlongdouble
+	fmove.d	%fp0,(%a1)
+	jbra	epilogue
+
+retlongdouble:
+	btst	#4,%d2
+	jbeq	retpointer
+	fmove.x	%fp0,(%a1)
+	jbra	epilogue
+
+retpointer:
+	btst	#5,%d2
+	jbeq	retstruct
+	move.l	%a0,(%a1)
+	jbra	epilogue
+
+retstruct:
+	btst	#6,%d2
+	jbeq	noretval
+	move.l	24(%fp),%d2
+	bfins	%d0,(%a1){#0,%d2}
+
+noretval:
+epilogue:
+	move.l	(%sp)+,%d2
+	unlk	%a6
+	rts
+	.size	ffi_call_SYSV,.-ffi_call_SYSV

Added: vendor/Python/current/Modules/_ctypes/libffi/src/mips/ffi.c
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/mips/ffi.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/mips/ffi.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,648 @@
+/* -----------------------------------------------------------------------
+   ffi.c - Copyright (c) 1996 Red Hat, Inc.
+   
+   MIPS Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+#include <sys/cachectl.h>
+
+#if _MIPS_SIM == _ABIN32
+#define FIX_ARGP \
+FFI_ASSERT(argp <= &stack[bytes]); \
+if (argp == &stack[bytes]) \
+{ \
+  argp = stack; \
+  ffi_stop_here(); \
+}
+#else
+#define FIX_ARGP 
+#endif
+
+
+/* ffi_prep_args is called by the assembly routine once stack space
+   has been allocated for the function's arguments */
+
+static void ffi_prep_args(char *stack, 
+			  extended_cif *ecif,
+			  int bytes,
+			  int flags)
+{
+  int i;
+  void **p_argv;
+  char *argp;
+  ffi_type **p_arg;
+
+#if _MIPS_SIM == _ABIN32
+  /* If more than 8 double words are used, the remainder go
+     on the stack. We reorder stuff on the stack here to 
+     support this easily. */
+  if (bytes > 8 * sizeof(ffi_arg))
+    argp = &stack[bytes - (8 * sizeof(ffi_arg))];
+  else
+    argp = stack;
+#else
+  argp = stack;
+#endif
+
+  memset(stack, 0, bytes);
+
+#if _MIPS_SIM == _ABIN32
+  if ( ecif->cif->rstruct_flag != 0 )
+#else
+  if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT )
+#endif  
+    {
+      *(ffi_arg *) argp = (ffi_arg) ecif->rvalue;
+      argp += sizeof(ffi_arg);
+      FIX_ARGP;
+    }
+
+  p_argv = ecif->avalue;
+
+  for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; i; i--, p_arg++)
+    {
+      size_t z;
+      unsigned int a;
+
+      /* Align if necessary.  */
+      a = (*p_arg)->alignment;
+      if (a < sizeof(ffi_arg))
+        a = sizeof(ffi_arg);
+      
+      if ((a - 1) & (unsigned int) argp)
+	{
+	  argp = (char *) ALIGN(argp, a);
+	  FIX_ARGP;
+	}
+
+      z = (*p_arg)->size;
+      if (z <= sizeof(ffi_arg))
+	{
+	  z = sizeof(ffi_arg);
+
+	  switch ((*p_arg)->type)
+	    {
+	      case FFI_TYPE_SINT8:
+		*(ffi_arg *)argp = *(SINT8 *)(* p_argv);
+		break;
+
+	      case FFI_TYPE_UINT8:
+		*(ffi_arg *)argp = *(UINT8 *)(* p_argv);
+		break;
+		  
+	      case FFI_TYPE_SINT16:
+		*(ffi_arg *)argp = *(SINT16 *)(* p_argv);
+		break;
+		  
+	      case FFI_TYPE_UINT16:
+		*(ffi_arg *)argp = *(UINT16 *)(* p_argv);
+		break;
+		  
+	      case FFI_TYPE_SINT32:
+		*(ffi_arg *)argp = *(SINT32 *)(* p_argv);
+		break;
+		  
+	      case FFI_TYPE_UINT32:
+	      case FFI_TYPE_POINTER:
+		*(ffi_arg *)argp = *(UINT32 *)(* p_argv);
+		break;
+
+	      /* This can only happen with 64bit slots.  */
+	      case FFI_TYPE_FLOAT:
+		*(float *) argp = *(float *)(* p_argv);
+		break;
+
+	      /* Handle small structures.  */
+	      case FFI_TYPE_STRUCT:
+	      default:
+		memcpy(argp, *p_argv, (*p_arg)->size);
+		break;
+	    }
+	}
+      else
+	{
+#if _MIPS_SIM == _ABIO32
+	  memcpy(argp, *p_argv, z);
+#else
+	  {
+	    unsigned end = (unsigned) argp+z;
+	    unsigned cap = (unsigned) stack+bytes;
+
+	    /* Check if the data will fit within the register space.
+	       Handle it if it doesn't.  */
+
+	    if (end <= cap)
+	      memcpy(argp, *p_argv, z);
+	    else
+	      {
+		unsigned portion = end - cap;
+
+		memcpy(argp, *p_argv, portion);
+		argp = stack;
+		memcpy(argp,
+		       (void*)((unsigned)(*p_argv)+portion), z - portion);
+	      }
+	  }
+#endif
+      }
+      p_argv++;
+      argp += z;
+      FIX_ARGP;
+    }
+}
+
+#if _MIPS_SIM == _ABIN32
+
+/* The n32 spec says that if "a chunk consists solely of a double 
+   float field (but not a double, which is part of a union), it
+   is passed in a floating point register. Any other chunk is
+   passed in an integer register". This code traverses structure
+   definitions and generates the appropriate flags. */
+
+unsigned calc_n32_struct_flags(ffi_type *arg, unsigned *shift)
+{
+  unsigned flags = 0;
+  unsigned index = 0;
+
+  ffi_type *e;
+
+  while (e = arg->elements[index])
+    {
+      if (e->type == FFI_TYPE_DOUBLE)
+	{
+	  flags += (FFI_TYPE_DOUBLE << *shift);
+	  *shift += FFI_FLAG_BITS;
+	}
+      else if (e->type == FFI_TYPE_STRUCT)
+	  flags += calc_n32_struct_flags(e, shift);
+      else
+	*shift += FFI_FLAG_BITS;
+
+      index++;
+    }
+
+  return flags;
+}
+
+unsigned calc_n32_return_struct_flags(ffi_type *arg)
+{
+  unsigned flags = 0;
+  unsigned index = 0;
+  unsigned small = FFI_TYPE_SMALLSTRUCT;
+  ffi_type *e;
+
+  /* Returning structures under n32 is a tricky thing.
+     A struct with only one or two floating point fields 
+     is returned in $f0 (and $f2 if necessary). Any other
+     struct results at most 128 bits are returned in $2
+     (the first 64 bits) and $3 (remainder, if necessary).
+     Larger structs are handled normally. */
+  
+  if (arg->size > 16)
+    return 0;
+
+  if (arg->size > 8)
+    small = FFI_TYPE_SMALLSTRUCT2;
+
+  e = arg->elements[0];
+  if (e->type == FFI_TYPE_DOUBLE)
+    flags = FFI_TYPE_DOUBLE << FFI_FLAG_BITS;
+  else if (e->type == FFI_TYPE_FLOAT)
+    flags = FFI_TYPE_FLOAT << FFI_FLAG_BITS;
+
+  if (flags && (e = arg->elements[1]))
+    {
+      if (e->type == FFI_TYPE_DOUBLE)
+	flags += FFI_TYPE_DOUBLE;
+      else if (e->type == FFI_TYPE_FLOAT)
+	flags += FFI_TYPE_FLOAT;
+      else 
+	return small;
+
+      if (flags && (arg->elements[2]))
+	{
+	  /* There are three arguments and the first two are 
+	     floats! This must be passed the old way. */
+	  return small;
+	}
+    }
+  else
+    if (!flags)
+      return small;
+
+  return flags;
+}
+
+#endif
+
+/* Perform machine dependent cif processing */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+{
+  cif->flags = 0;
+
+#if _MIPS_SIM == _ABIO32
+  /* Set the flags necessary for O32 processing.  FFI_O32_SOFT_FLOAT
+   * does not have special handling for floating point args.
+   */
+
+  if (cif->rtype->type != FFI_TYPE_STRUCT && cif->abi == FFI_O32)
+    {
+      if (cif->nargs > 0)
+	{
+	  switch ((cif->arg_types)[0]->type)
+	    {
+	    case FFI_TYPE_FLOAT:
+	    case FFI_TYPE_DOUBLE:
+	      cif->flags += (cif->arg_types)[0]->type;
+	      break;
+	      
+	    default:
+	      break;
+	    }
+
+	  if (cif->nargs > 1)
+	    {
+	      /* Only handle the second argument if the first
+		 is a float or double. */
+	      if (cif->flags)
+		{
+		  switch ((cif->arg_types)[1]->type)
+		    {
+		    case FFI_TYPE_FLOAT:
+		    case FFI_TYPE_DOUBLE:
+		      cif->flags += (cif->arg_types)[1]->type << FFI_FLAG_BITS;
+		      break;
+		      
+		    default:
+		      break;
+		    }
+		}
+	    }
+	}
+    }
+      
+  /* Set the return type flag */
+
+  if (cif->abi == FFI_O32_SOFT_FLOAT)
+    {
+      switch (cif->rtype->type)
+        {
+        case FFI_TYPE_VOID:
+        case FFI_TYPE_STRUCT:
+          cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 2);
+          break;
+
+        case FFI_TYPE_SINT64:
+        case FFI_TYPE_UINT64:
+        case FFI_TYPE_DOUBLE:
+          cif->flags += FFI_TYPE_UINT64 << (FFI_FLAG_BITS * 2);
+          break;
+      
+        case FFI_TYPE_FLOAT:
+        default:
+          cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 2);
+          break;
+        }
+    }
+  else
+    {
+      /* FFI_O32 */      
+      switch (cif->rtype->type)
+        {
+        case FFI_TYPE_VOID:
+        case FFI_TYPE_STRUCT:
+        case FFI_TYPE_FLOAT:
+        case FFI_TYPE_DOUBLE:
+          cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 2);
+          break;
+
+        case FFI_TYPE_SINT64:
+        case FFI_TYPE_UINT64:
+          cif->flags += FFI_TYPE_UINT64 << (FFI_FLAG_BITS * 2);
+          break;
+      
+        default:
+          cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 2);
+          break;
+        }
+    }
+#endif
+
+#if _MIPS_SIM == _ABIN32
+  /* Set the flags necessary for N32 processing */
+  {
+    unsigned shift = 0;
+    unsigned count = (cif->nargs < 8) ? cif->nargs : 8;
+    unsigned index = 0;
+
+    unsigned struct_flags = 0;
+
+    if (cif->rtype->type == FFI_TYPE_STRUCT)
+      {
+	struct_flags = calc_n32_return_struct_flags(cif->rtype);
+
+	if (struct_flags == 0)
+	  {
+	    /* This means that the structure is being passed as
+	       a hidden argument */
+
+	    shift = FFI_FLAG_BITS;
+	    count = (cif->nargs < 7) ? cif->nargs : 7;
+
+	    cif->rstruct_flag = !0;
+	  }
+	else
+	    cif->rstruct_flag = 0;
+      }
+    else
+      cif->rstruct_flag = 0;
+
+    while (count-- > 0)
+      {
+	switch ((cif->arg_types)[index]->type)
+	  {
+	  case FFI_TYPE_FLOAT:
+	  case FFI_TYPE_DOUBLE:
+	    cif->flags += ((cif->arg_types)[index]->type << shift);
+	    shift += FFI_FLAG_BITS;
+	    break;
+
+	  case FFI_TYPE_STRUCT:
+	    cif->flags += calc_n32_struct_flags((cif->arg_types)[index],
+						&shift);
+	    break;
+
+	  default:
+	    shift += FFI_FLAG_BITS;
+	  }
+
+	index++;
+      }
+
+  /* Set the return type flag */
+    switch (cif->rtype->type)
+      {
+      case FFI_TYPE_STRUCT:
+	{
+	  if (struct_flags == 0)
+	    {
+	      /* The structure is returned through a hidden
+		 first argument. Do nothing, 'cause FFI_TYPE_VOID 
+		 is 0 */
+	    }
+	  else
+	    {
+	      /* The structure is returned via some tricky
+		 mechanism */
+	      cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8);
+	      cif->flags += struct_flags << (4 + (FFI_FLAG_BITS * 8));
+	    }
+	  break;
+	}
+      
+      case FFI_TYPE_VOID:
+	/* Do nothing, 'cause FFI_TYPE_VOID is 0 */
+	break;
+	
+      case FFI_TYPE_FLOAT:
+      case FFI_TYPE_DOUBLE:
+	cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 8);
+	break;
+	
+      default:
+	cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8);
+	break;
+      }
+  }
+#endif
+  
+  return FFI_OK;
+}
+
+/* Low level routine for calling O32 functions */
+extern int ffi_call_O32(void (*)(char *, extended_cif *, int, int), 
+			extended_cif *, unsigned, 
+			unsigned, unsigned *, void (*)());
+
+/* Low level routine for calling N32 functions */
+extern int ffi_call_N32(void (*)(char *, extended_cif *, int, int), 
+			extended_cif *, unsigned, 
+			unsigned, unsigned *, void (*)());
+
+void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
+{
+  extended_cif ecif;
+
+  ecif.cif = cif;
+  ecif.avalue = avalue;
+  
+  /* If the return value is a struct and we don't have a return	*/
+  /* value address then we need to make one		        */
+  
+  if ((rvalue == NULL) && 
+      (cif->rtype->type == FFI_TYPE_STRUCT))
+    ecif.rvalue = alloca(cif->rtype->size);
+  else
+    ecif.rvalue = rvalue;
+    
+  switch (cif->abi) 
+    {
+#if _MIPS_SIM == _ABIO32
+    case FFI_O32:
+    case FFI_O32_SOFT_FLOAT:
+      ffi_call_O32(ffi_prep_args, &ecif, cif->bytes, 
+		   cif->flags, ecif.rvalue, fn);
+      break;
+#endif
+
+#if _MIPS_SIM == _ABIN32
+    case FFI_N32:
+      ffi_call_N32(ffi_prep_args, &ecif, cif->bytes, 
+		   cif->flags, ecif.rvalue, fn);
+      break;
+#endif
+
+    default:
+      FFI_ASSERT(0);
+      break;
+    }
+}
+
+#if FFI_CLOSURES  /* N32 not implemented yet, FFI_CLOSURES not defined */
+#if defined(FFI_MIPS_O32)
+extern void ffi_closure_O32(void);
+#endif /* FFI_MIPS_O32 */
+
+ffi_status
+ffi_prep_closure (ffi_closure *closure,
+		  ffi_cif *cif,
+		  void (*fun)(ffi_cif*,void*,void**,void*),
+		  void *user_data)
+{
+  unsigned int *tramp = (unsigned int *) &closure->tramp[0];
+  unsigned int fn;
+  unsigned int ctx = (unsigned int) closure;
+
+#if defined(FFI_MIPS_O32)
+  FFI_ASSERT(cif->abi == FFI_O32 || cif->abi == FFI_O32_SOFT_FLOAT);
+  fn = (unsigned int) ffi_closure_O32;
+#else /* FFI_MIPS_N32 */
+  FFI_ASSERT(cif->abi == FFI_N32);
+  FFI_ASSERT(!"not implemented");
+#endif /* FFI_MIPS_O32 */
+
+  tramp[0] = 0x3c190000 | (fn >> 16);     /* lui  $25,high(fn) */
+  tramp[1] = 0x37390000 | (fn & 0xffff);  /* ori  $25,low(fn)  */
+  tramp[2] = 0x3c080000 | (ctx >> 16);    /* lui  $8,high(ctx) */
+  tramp[3] = 0x03200008;                  /* jr   $25          */
+  tramp[4] = 0x35080000 | (ctx & 0xffff); /* ori  $8,low(ctx)  */
+
+  closure->cif = cif;
+  closure->fun = fun;
+  closure->user_data = user_data;
+
+  /* XXX this is available on Linux, but anything else? */
+  cacheflush (tramp, FFI_TRAMPOLINE_SIZE, ICACHE);
+
+  return FFI_OK;
+}
+
+/*
+ * Decodes the arguments to a function, which will be stored on the
+ * stack. AR is the pointer to the beginning of the integer arguments
+ * (and, depending upon the arguments, some floating-point arguments
+ * as well). FPR is a pointer to the area where floating point
+ * registers have been saved, if any.
+ *
+ * RVALUE is the location where the function return value will be
+ * stored. CLOSURE is the prepared closure to invoke.
+ *
+ * This function should only be called from assembly, which is in
+ * turn called from a trampoline.
+ *
+ * Returns the function return type.
+ *
+ * Based on the similar routine for sparc.
+ */
+int
+ffi_closure_mips_inner_O32 (ffi_closure *closure,
+			    void *rvalue, ffi_arg *ar,
+			    double *fpr)
+{
+  ffi_cif *cif;
+  void **avaluep;
+  ffi_arg *avalue;
+  ffi_type **arg_types;
+  int i, avn, argn, seen_int;
+
+  cif = closure->cif;
+  avalue = alloca (cif->nargs * sizeof (ffi_arg));
+  avaluep = alloca (cif->nargs * sizeof (ffi_arg));
+
+  seen_int = (cif->abi == FFI_O32_SOFT_FLOAT);
+  argn = 0;
+
+  if ((cif->flags >> (FFI_FLAG_BITS * 2)) == FFI_TYPE_STRUCT)
+    {
+      rvalue = (void *) ar[0];
+      argn = 1;
+    }
+
+  i = 0;
+  avn = cif->nargs;
+  arg_types = cif->arg_types;
+
+  while (i < avn)
+    {
+      if (i < 2 && !seen_int &&
+	  (arg_types[i]->type == FFI_TYPE_FLOAT ||
+	   arg_types[i]->type == FFI_TYPE_DOUBLE))
+	{
+#ifdef __MIPSEB__
+	  if (arg_types[i]->type == FFI_TYPE_FLOAT)
+	    avaluep[i] = ((char *) &fpr[i]) + sizeof (float);
+	  else
+#endif
+	    avaluep[i] = (char *) &fpr[i];
+	}
+      else
+	{
+	  if (arg_types[i]->alignment == 8 && (argn & 0x1))
+	    argn++;
+	  switch (arg_types[i]->type)
+	    {
+	      case FFI_TYPE_SINT8:
+		avaluep[i] = &avalue[i];
+		*(SINT8 *) &avalue[i] = (SINT8) ar[argn];
+		break;
+
+	      case FFI_TYPE_UINT8:
+		avaluep[i] = &avalue[i];
+		*(UINT8 *) &avalue[i] = (UINT8) ar[argn];
+		break;
+		  
+	      case FFI_TYPE_SINT16:
+		avaluep[i] = &avalue[i];
+		*(SINT16 *) &avalue[i] = (SINT16) ar[argn];
+		break;
+		  
+	      case FFI_TYPE_UINT16:
+		avaluep[i] = &avalue[i];
+		*(UINT16 *) &avalue[i] = (UINT16) ar[argn];
+		break;
+
+	      default:
+		avaluep[i] = (char *) &ar[argn];
+		break;
+	    }
+	  seen_int = 1;
+	}
+      argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
+      i++;
+    }
+
+  /* Invoke the closure. */
+  (closure->fun) (cif, rvalue, avaluep, closure->user_data);
+
+  if (cif->abi == FFI_O32_SOFT_FLOAT)
+    {
+      switch (cif->rtype->type)
+        {
+        case FFI_TYPE_FLOAT:
+          return FFI_TYPE_INT;
+        case FFI_TYPE_DOUBLE:
+          return FFI_TYPE_UINT64;
+        default:
+          return cif->rtype->type;
+        }
+    }
+  else
+    {
+      return cif->rtype->type;
+    }
+}
+
+#endif /* FFI_CLOSURES */

Added: vendor/Python/current/Modules/_ctypes/libffi/src/mips/ffitarget.h
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/mips/ffitarget.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/mips/ffitarget.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,167 @@
+/* -----------------------------------------------------------------*-C-*-
+   ffitarget.h - Copyright (c) 1996-2003  Red Hat, Inc.
+   Target configuration macros for MIPS.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+
+   ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+#if !defined(_MIPS_SIM)
+-- something is very wrong --
+#else
+#  if (_MIPS_SIM==_ABIN32 && defined(_ABIN32)) || (_MIPS_SIM==_ABI64 && defined(_ABI64))
+#    define FFI_MIPS_N32
+#  else
+#    if (_MIPS_SIM==_ABIO32 && defined(_ABIO32))
+#      define FFI_MIPS_O32
+#    else
+-- this is an unsupported platform --
+#    endif
+#  endif
+#endif
+
+#ifdef FFI_MIPS_O32
+/* O32 stack frames have 32bit integer args */
+#define FFI_SIZEOF_ARG         4
+#else
+/* N32 and N64 frames have 64bit integer args */
+#define FFI_SIZEOF_ARG         8
+#endif
+
+#define FFI_FLAG_BITS 2
+
+/* SGI's strange assembler requires that we multiply by 4 rather 
+   than shift left by FFI_FLAG_BITS */
+
+#define FFI_ARGS_D   FFI_TYPE_DOUBLE
+#define FFI_ARGS_F   FFI_TYPE_FLOAT
+#define FFI_ARGS_DD  FFI_TYPE_DOUBLE * 4 + FFI_TYPE_DOUBLE
+#define FFI_ARGS_FF  FFI_TYPE_FLOAT * 4 +  FFI_TYPE_FLOAT
+#define FFI_ARGS_FD  FFI_TYPE_DOUBLE * 4 + FFI_TYPE_FLOAT
+#define FFI_ARGS_DF  FFI_TYPE_FLOAT * 4 + FFI_TYPE_DOUBLE
+
+/* Needed for N32 structure returns */
+#define FFI_TYPE_SMALLSTRUCT  FFI_TYPE_UINT8
+#define FFI_TYPE_SMALLSTRUCT2 FFI_TYPE_SINT8
+
+#if 0
+/* The SGI assembler can't handle this.. */
+#define FFI_TYPE_STRUCT_DD (( FFI_ARGS_DD ) << 4) + FFI_TYPE_STRUCT
+/* (and so on) */
+#else
+/* ...so we calculate these by hand! */
+#define FFI_TYPE_STRUCT_D      61
+#define FFI_TYPE_STRUCT_F      45
+#define FFI_TYPE_STRUCT_DD     253
+#define FFI_TYPE_STRUCT_FF     173
+#define FFI_TYPE_STRUCT_FD     237
+#define FFI_TYPE_STRUCT_DF     189
+#define FFI_TYPE_STRUCT_SMALL  93
+#define FFI_TYPE_STRUCT_SMALL2 109
+#endif
+
+#ifdef LIBFFI_ASM
+#define v0 $2
+#define v1 $3
+#define a0 $4
+#define a1 $5
+#define a2 $6
+#define a3 $7
+#define a4 $8		
+#define a5 $9		
+#define a6 $10		
+#define a7 $11		
+#define t0 $8
+#define t1 $9
+#define t2 $10
+#define t3 $11
+#define t4 $12		
+#define t5 $13
+#define t6 $14	
+#define t7 $15
+#define t8 $24
+#define t9 $25
+#define ra $31		
+
+#ifdef FFI_MIPS_O32
+#define REG_L	lw
+#define REG_S	sw
+#define SUBU	subu
+#define ADDU	addu
+#define SRL	srl
+#define LI	li
+#else /* !FFI_MIPS_O32 */
+#define REG_L	ld
+#define REG_S	sd
+#define SUBU	dsubu
+#define ADDU	daddu
+#define SRL	dsrl
+#define LI 	dli
+#endif /* !FFI_MIPS_O32 */
+#else /* !LIBFFI_ASM */
+#ifdef FFI_MIPS_O32
+/* O32 stack frames have 32bit integer args */
+typedef unsigned int     ffi_arg __attribute__((__mode__(__SI__)));
+typedef signed   int     ffi_sarg __attribute__((__mode__(__SI__)));
+#else
+/* N32 and N64 frames have 64bit integer args */
+typedef unsigned int     ffi_arg __attribute__((__mode__(__DI__)));
+typedef signed   int     ffi_sarg __attribute__((__mode__(__DI__)));
+#endif
+
+typedef enum ffi_abi {
+  FFI_FIRST_ABI = 0,
+  FFI_O32,
+  FFI_N32,
+  FFI_N64,
+  FFI_O32_SOFT_FLOAT,
+
+#ifdef FFI_MIPS_O32
+#ifdef __mips_soft_float
+  FFI_DEFAULT_ABI = FFI_O32_SOFT_FLOAT,
+#else
+  FFI_DEFAULT_ABI = FFI_O32,
+#endif
+#else
+  FFI_DEFAULT_ABI = FFI_N32,
+#endif
+
+  FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
+} ffi_abi;
+
+#define FFI_EXTRA_CIF_FIELDS unsigned rstruct_flag
+#endif /* !LIBFFI_ASM */
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#if defined(FFI_MIPS_O32)
+#define FFI_CLOSURES 1
+#define FFI_TRAMPOLINE_SIZE 20
+#else
+/* N32/N64 not implemented yet. */
+#define FFI_CLOSURES 0
+#endif /* FFI_MIPS_O32 */
+#define FFI_NATIVE_RAW_API 0
+
+#endif
+

Added: vendor/Python/current/Modules/_ctypes/libffi/src/mips/n32.S
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/mips/n32.S	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/mips/n32.S	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,320 @@
+/* -----------------------------------------------------------------------
+   n32.S - Copyright (c) 1996, 1998, 2005  Red Hat, Inc.
+   
+   MIPS Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM	
+#include <fficonfig.h>
+#include <ffi.h>
+
+/* Only build this code if we are compiling for n32 */	
+
+#if defined(FFI_MIPS_N32)
+
+#define callback a0
+#define bytes	 a2
+#define flags	 a3
+#define raddr    a4
+#define fn       a5
+
+#define SIZEOF_FRAME	( 8 * FFI_SIZEOF_ARG )
+
+	.abicalls
+	.text
+	.align	2
+	.globl	ffi_call_N32
+	.ent	ffi_call_N32
+ffi_call_N32:	
+
+	# Prologue
+	SUBU	$sp, SIZEOF_FRAME			# Frame size
+	REG_S	$fp, SIZEOF_FRAME - 2*FFI_SIZEOF_ARG($sp)	# Save frame pointer
+	REG_S	ra, SIZEOF_FRAME - 1*FFI_SIZEOF_ARG($sp)	# Save return address
+	move	$fp, $sp
+
+	move	t9, callback	# callback function pointer
+	REG_S	bytes, 2*FFI_SIZEOF_ARG($fp) # bytes
+	REG_S	flags, 3*FFI_SIZEOF_ARG($fp) # flags
+	REG_S	raddr, 4*FFI_SIZEOF_ARG($fp) # raddr
+	REG_S	fn,    5*FFI_SIZEOF_ARG($fp) # fn
+
+	# Allocate at least 4 words in the argstack
+	move	v0, bytes
+	bge	bytes, 4 * FFI_SIZEOF_ARG, bigger	
+	LI	v0, 4 * FFI_SIZEOF_ARG
+	b	sixteen
+
+	bigger:	
+	ADDU	t4, v0, 2 * FFI_SIZEOF_ARG -1	# make sure it is aligned 
+	and	v0, t4, -2 * FFI_SIZEOF_ARG		# to a proper boundry.
+
+sixteen:
+	SUBU	$sp, $sp, v0	# move the stack pointer to reflect the
+				# arg space
+
+	ADDU	a0, $sp, 0      # 4 * FFI_SIZEOF_ARG
+	ADDU	a3, $fp, 3 * FFI_SIZEOF_ARG
+
+	# Call ffi_prep_args
+	jal	t9
+	
+	#	ADDU	$sp, $sp, 4 * FFI_SIZEOF_ARG	# adjust $sp to new args
+
+	# Copy the stack pointer to t9
+	move	t9, $sp
+	
+	# Fix the stack if there are more than 8 64bit slots worth
+	# of arguments.
+
+	# Load the number of bytes
+	REG_L	t6, 2*FFI_SIZEOF_ARG($fp)
+
+	# Is it bigger than 8 * FFI_SIZEOF_ARG?
+	dadd	t7, $0, 8 * FFI_SIZEOF_ARG
+	dsub	t8, t6, t7
+	bltz	t8, loadregs
+
+	add	t9, t9, t8
+	
+loadregs:	
+
+	REG_L	t4, 3*FFI_SIZEOF_ARG($fp)  # load the flags word
+	add	t6, t4, 0			      # and copy it into t6
+
+	and	t4, ((1<<FFI_FLAG_BITS)-1)
+	bnez	t4, arg1_floatp
+	REG_L	a0, 0*FFI_SIZEOF_ARG(t9)
+	b	arg1_next
+arg1_floatp:	
+	bne	t4, FFI_TYPE_FLOAT, arg1_doublep
+	l.s	$f12, 0*FFI_SIZEOF_ARG(t9)
+	b	arg1_next
+arg1_doublep:	
+	l.d	$f12, 0*FFI_SIZEOF_ARG(t9)
+arg1_next:	
+	
+	add	t4, t6, 0
+	SRL	t4, 1*FFI_FLAG_BITS
+	and	t4, ((1<<FFI_FLAG_BITS)-1)
+	bnez	t4, arg2_floatp
+	REG_L	a1, 1*FFI_SIZEOF_ARG(t9)
+	b	arg2_next
+arg2_floatp:
+	bne	t4, FFI_TYPE_FLOAT, arg2_doublep
+	l.s	$f13, 1*FFI_SIZEOF_ARG(t9)	
+	b	arg2_next
+arg2_doublep:	
+	l.d	$f13, 1*FFI_SIZEOF_ARG(t9)	
+arg2_next:	
+	
+	add	t4, t6, 0
+	SRL	t4, 2*FFI_FLAG_BITS
+	and	t4, ((1<<FFI_FLAG_BITS)-1)
+	bnez	t4, arg3_floatp
+	REG_L	a2, 2*FFI_SIZEOF_ARG(t9)
+	b	arg3_next
+arg3_floatp:
+	bne	t4, FFI_TYPE_FLOAT, arg3_doublep
+	l.s	$f14, 2*FFI_SIZEOF_ARG(t9)	
+	b	arg3_next
+arg3_doublep:	
+	l.d	$f14, 2*FFI_SIZEOF_ARG(t9)	
+arg3_next:	
+	
+	add	t4, t6, 0
+	SRL	t4, 3*FFI_FLAG_BITS
+	and	t4, ((1<<FFI_FLAG_BITS)-1)
+	bnez	t4, arg4_floatp
+	REG_L	a3, 3*FFI_SIZEOF_ARG(t9)
+	b	arg4_next
+arg4_floatp:
+	bne	t4, FFI_TYPE_FLOAT, arg4_doublep
+	l.s	$f15, 3*FFI_SIZEOF_ARG(t9)	
+	b	arg4_next
+arg4_doublep:	
+	l.d	$f15, 3*FFI_SIZEOF_ARG(t9)	
+arg4_next:	
+	
+	add	t4, t6, 0
+	SRL	t4, 4*FFI_FLAG_BITS
+	and	t4, ((1<<FFI_FLAG_BITS)-1)
+	bnez	t4, arg5_floatp
+	REG_L	a4, 4*FFI_SIZEOF_ARG(t9)
+	b	arg5_next
+arg5_floatp:
+	bne	t4, FFI_TYPE_FLOAT, arg5_doublep
+	l.s	$f16, 4*FFI_SIZEOF_ARG(t9)	
+	b	arg5_next
+arg5_doublep:	
+	l.d	$f16, 4*FFI_SIZEOF_ARG(t9)	
+arg5_next:	
+	
+	add	t4, t6, 0
+	SRL	t4, 5*FFI_FLAG_BITS
+	and	t4, ((1<<FFI_FLAG_BITS)-1)
+	bnez	t4, arg6_floatp
+	REG_L	a5, 5*FFI_SIZEOF_ARG(t9)
+	b	arg6_next
+arg6_floatp:
+	bne	t4, FFI_TYPE_FLOAT, arg6_doublep
+	l.s	$f17, 5*FFI_SIZEOF_ARG(t9)	
+	b	arg6_next
+arg6_doublep:	
+	l.d	$f17, 5*FFI_SIZEOF_ARG(t9)	
+arg6_next:	
+	
+	add	t4, t6, 0
+	SRL	t4, 6*FFI_FLAG_BITS
+	and	t4, ((1<<FFI_FLAG_BITS)-1)
+	bnez	t4, arg7_floatp
+	REG_L	a6, 6*FFI_SIZEOF_ARG(t9)
+	b	arg7_next
+arg7_floatp:
+	bne	t4, FFI_TYPE_FLOAT, arg7_doublep
+	l.s	$f18, 6*FFI_SIZEOF_ARG(t9)	
+	b	arg7_next
+arg7_doublep:	
+	l.d	$f18, 6*FFI_SIZEOF_ARG(t9)	
+arg7_next:	
+	
+	add	t4, t6, 0
+	SRL	t4, 7*FFI_FLAG_BITS
+	and	t4, ((1<<FFI_FLAG_BITS)-1)
+	bnez	t4, arg8_floatp
+	REG_L	a7, 7*FFI_SIZEOF_ARG(t9)
+	b	arg8_next
+arg8_floatp:
+	bne	t4, FFI_TYPE_FLOAT, arg8_doublep
+ 	l.s	$f19, 7*FFI_SIZEOF_ARG(t9)	
+	b	arg8_next
+arg8_doublep:	
+ 	l.d	$f19, 7*FFI_SIZEOF_ARG(t9)	
+arg8_next:	
+
+callit:		
+	# Load the function pointer
+	REG_L	t9, 5*FFI_SIZEOF_ARG($fp)
+
+	# If the return value pointer is NULL, assume no return value.
+	REG_L	t5, 4*FFI_SIZEOF_ARG($fp)
+	beqz	t5, noretval
+
+	# Shift the return type flag over
+	SRL	t6, 8*FFI_FLAG_BITS
+	
+	bne     t6, FFI_TYPE_INT, retfloat
+	jal	t9
+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)
+	REG_S	v0, 0(t4)
+	b	epilogue
+
+retfloat:
+	bne     t6, FFI_TYPE_FLOAT, retdouble
+	jal	t9
+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)
+	s.s	$f0, 0(t4)
+	b	epilogue
+
+retdouble:	
+	bne	t6, FFI_TYPE_DOUBLE, retstruct_d
+	jal	t9
+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)
+	s.d	$f0, 0(t4)
+	b	epilogue
+
+retstruct_d:	
+	bne	t6, FFI_TYPE_STRUCT_D, retstruct_f
+	jal	t9
+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)
+	s.d	$f0, 0(t4)
+	b	epilogue
+	
+retstruct_f:	
+	bne	t6, FFI_TYPE_STRUCT_F, retstruct_d_d
+	jal	t9
+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)
+	s.s	$f0, 0(t4)
+	b	epilogue
+	
+retstruct_d_d:	
+	bne	t6, FFI_TYPE_STRUCT_DD, retstruct_f_f
+	jal	t9
+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)
+	s.d	$f0, 0(t4)
+	s.d	$f2, 8(t4)
+	b	epilogue
+	
+retstruct_f_f:	
+	bne	t6, FFI_TYPE_STRUCT_FF, retstruct_d_f
+	jal	t9
+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)
+	s.s	$f0, 0(t4)
+	s.s	$f2, 4(t4)
+	b	epilogue
+	
+retstruct_d_f:	
+	bne	t6, FFI_TYPE_STRUCT_DF, retstruct_f_d
+	jal	t9
+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)
+	s.d	$f0, 0(t4)
+	s.s	$f2, 8(t4)
+	b	epilogue
+	
+retstruct_f_d:	
+	bne	t6, FFI_TYPE_STRUCT_FD, retstruct_small
+	jal	t9
+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)
+	s.s	$f0, 0(t4)
+	s.d	$f2, 8(t4)
+	b	epilogue
+	
+retstruct_small:	
+	bne	t6, FFI_TYPE_STRUCT_SMALL, retstruct_small2
+	jal	t9
+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)
+	REG_S	v0, 0(t4)
+	b	epilogue
+	
+retstruct_small2:	
+	bne	t6, FFI_TYPE_STRUCT_SMALL2, retstruct
+	jal	t9
+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)
+	REG_S	v0, 0(t4)
+	REG_S	v1, 8(t4)
+	b	epilogue
+	
+retstruct:	
+noretval:	
+	jal	t9
+	
+	# Epilogue
+epilogue:	
+	move	$sp, $fp	
+	REG_L	$fp, SIZEOF_FRAME - 2*FFI_SIZEOF_ARG($sp) # Restore frame pointer
+	REG_L	ra, SIZEOF_FRAME - 1*FFI_SIZEOF_ARG($sp)  # Restore return address
+	ADDU	$sp, SIZEOF_FRAME		      # Fix stack pointer
+	j	ra
+
+	.end	ffi_call_N32
+	
+#endif

Added: vendor/Python/current/Modules/_ctypes/libffi/src/mips/o32.S
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/mips/o32.S	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/mips/o32.S	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,377 @@
+/* -----------------------------------------------------------------------
+   o32.S - Copyright (c) 1996, 1998, 2005  Red Hat, Inc.
+   
+   MIPS Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM	
+#include <fficonfig.h>
+#include <ffi.h>
+
+/* Only build this code if we are compiling for o32 */	
+
+#if defined(FFI_MIPS_O32)
+	
+#define callback a0
+#define bytes	 a2
+#define flags	 a3
+		
+#define SIZEOF_FRAME	(4 * FFI_SIZEOF_ARG + 2 * FFI_SIZEOF_ARG)
+#define A3_OFF		(SIZEOF_FRAME + 3 * FFI_SIZEOF_ARG)
+#define FP_OFF		(SIZEOF_FRAME - 2 * FFI_SIZEOF_ARG)
+#define RA_OFF		(SIZEOF_FRAME - 1 * FFI_SIZEOF_ARG)
+
+	.abicalls
+	.text
+	.align	2
+	.globl	ffi_call_O32
+	.ent	ffi_call_O32
+ffi_call_O32:	
+$LFB0:
+	# Prologue
+	SUBU	$sp, SIZEOF_FRAME	# Frame size
+$LCFI0:
+	REG_S	$fp, FP_OFF($sp)	# Save frame pointer
+$LCFI1:
+	REG_S	ra, RA_OFF($sp)		# Save return address
+$LCFI2:
+	move	$fp, $sp
+
+$LCFI3:
+	move	t9, callback		# callback function pointer
+	REG_S	flags, A3_OFF($fp)	# flags
+
+	# Allocate at least 4 words in the argstack
+	LI	v0, 4 * FFI_SIZEOF_ARG
+	blt	bytes, v0, sixteen
+
+	ADDU	v0, bytes, 7	# make sure it is aligned 
+	and	v0, -8		# to an 8 byte boundry
+
+sixteen:
+	SUBU	$sp, v0		# move the stack pointer to reflect the
+				# arg space
+
+	ADDU	a0, $sp, 4 * FFI_SIZEOF_ARG
+
+	jalr	t9
+	
+	REG_L	t0, A3_OFF($fp)		# load the flags word
+	SRL	t2, t0, 4		# shift our arg info
+	and     t0, ((1<<4)-1)          # mask out the return type
+		
+	ADDU	$sp, 4 * FFI_SIZEOF_ARG		# adjust $sp to new args
+
+	bnez	t0, pass_d			# make it quick for int
+	REG_L	a0, 0*FFI_SIZEOF_ARG($sp)	# just go ahead and load the
+	REG_L	a1, 1*FFI_SIZEOF_ARG($sp)	# four regs.
+	REG_L	a2, 2*FFI_SIZEOF_ARG($sp)
+	REG_L	a3, 3*FFI_SIZEOF_ARG($sp)
+	b	call_it
+
+pass_d:
+	bne	t0, FFI_ARGS_D, pass_f
+	l.d	$f12, 0*FFI_SIZEOF_ARG($sp)	# load $fp regs from args
+	REG_L	a2,   2*FFI_SIZEOF_ARG($sp)	# passing a double
+	REG_L	a3,   3*FFI_SIZEOF_ARG($sp)
+	b	call_it
+
+pass_f:	
+	bne	t0, FFI_ARGS_F, pass_d_d
+	l.s	$f12, 0*FFI_SIZEOF_ARG($sp)	# load $fp regs from args
+	REG_L	a1,   1*FFI_SIZEOF_ARG($sp)	# passing a float
+	REG_L	a2,   2*FFI_SIZEOF_ARG($sp)
+	REG_L	a3,   3*FFI_SIZEOF_ARG($sp)
+	b	call_it		
+
+pass_d_d:		
+	bne	t0, FFI_ARGS_DD, pass_f_f
+	l.d	$f12, 0*FFI_SIZEOF_ARG($sp)	# load $fp regs from args
+	l.d	$f14, 2*FFI_SIZEOF_ARG($sp)	# passing two doubles
+	b	call_it
+
+pass_f_f:	
+	bne	t0, FFI_ARGS_FF, pass_d_f
+	l.s	$f12, 0*FFI_SIZEOF_ARG($sp)	# load $fp regs from args
+	l.s	$f14, 1*FFI_SIZEOF_ARG($sp)	# passing two floats
+	REG_L	a2,   2*FFI_SIZEOF_ARG($sp)
+	REG_L	a3,   3*FFI_SIZEOF_ARG($sp)
+	b	call_it
+
+pass_d_f:		
+	bne	t0, FFI_ARGS_DF, pass_f_d
+	l.d	$f12, 0*FFI_SIZEOF_ARG($sp)	# load $fp regs from args
+	l.s	$f14, 2*FFI_SIZEOF_ARG($sp)	# passing double and float
+	REG_L	a3,   3*FFI_SIZEOF_ARG($sp)
+	b	call_it
+
+pass_f_d:		
+ # assume that the only other combination must be float then double
+ #	bne	t0, FFI_ARGS_F_D, call_it
+	l.s	$f12, 0*FFI_SIZEOF_ARG($sp)	# load $fp regs from args
+	l.d	$f14, 2*FFI_SIZEOF_ARG($sp)	# passing double and float
+
+call_it:	
+	# Load the function pointer
+	REG_L	t9, SIZEOF_FRAME + 5*FFI_SIZEOF_ARG($fp)
+
+	# If the return value pointer is NULL, assume no return value.
+	REG_L	t1, SIZEOF_FRAME + 4*FFI_SIZEOF_ARG($fp)
+	beqz	t1, noretval
+
+	bne     t2, FFI_TYPE_INT, retlonglong
+	jalr	t9
+	REG_L	t0, SIZEOF_FRAME + 4*FFI_SIZEOF_ARG($fp)
+	REG_S	v0, 0(t0)
+	b	epilogue
+
+retlonglong:
+	# Really any 64-bit int, signed or not.
+	bne	t2, FFI_TYPE_UINT64, retfloat
+	jalr	t9
+	REG_L	t0, SIZEOF_FRAME + 4*FFI_SIZEOF_ARG($fp)
+	REG_S	v1, 4(t0)
+	REG_S	v0, 0(t0)
+	b	epilogue
+
+retfloat:
+	bne     t2, FFI_TYPE_FLOAT, retdouble
+	jalr	t9
+	REG_L	t0, SIZEOF_FRAME + 4*FFI_SIZEOF_ARG($fp)
+	s.s	$f0, 0(t0)
+	b	epilogue
+
+retdouble:	
+	bne	t2, FFI_TYPE_DOUBLE, noretval
+	jalr	t9
+	REG_L	t0, SIZEOF_FRAME + 4*FFI_SIZEOF_ARG($fp)
+	s.d	$f0, 0(t0)
+	b	epilogue
+	
+noretval:	
+	jalr	t9
+	
+	# Epilogue
+epilogue:	
+	move	$sp, $fp	
+	REG_L	$fp, FP_OFF($sp)	# Restore frame pointer
+	REG_L	ra, RA_OFF($sp)		# Restore return address
+	ADDU	$sp, SIZEOF_FRAME	# Fix stack pointer
+	j	ra
+
+$LFE0:
+	.end	ffi_call_O32
+
+
+/* ffi_closure_O32. Expects address of the passed-in ffi_closure
+	in t0. Stores any arguments passed in registers onto the
+	stack, then calls ffi_closure_mips_inner_O32, which
+	then decodes them.
+	
+	Stack layout:
+
+	14 - Start of parameters, original sp
+	13 - ra save
+	12 - fp save
+	11 - $16 (s0) save
+	10 - cprestore
+	 9 - return value high (v1)
+	 8 - return value low (v0)
+	 7 - f14 (le high, be low)
+	 6 - f14 (le low, be high)
+	 5 - f12 (le high, be low)
+	 4 - f12 (le low, be high)
+	 3 - Called function a3 save
+	 2 - Called function a2 save
+	 1 - Called function a1 save
+	 0 - Called function a0 save our sp, fp point here
+	 */
+	
+#define SIZEOF_FRAME2	(14 * FFI_SIZEOF_ARG)
+#define A3_OFF2		(SIZEOF_FRAME2 + 3 * FFI_SIZEOF_ARG)
+#define A2_OFF2		(SIZEOF_FRAME2 + 2 * FFI_SIZEOF_ARG)
+#define A1_OFF2		(SIZEOF_FRAME2 + 1 * FFI_SIZEOF_ARG)
+#define A0_OFF2		(SIZEOF_FRAME2 + 0 * FFI_SIZEOF_ARG)
+#define RA_OFF2		(SIZEOF_FRAME2 - 1 * FFI_SIZEOF_ARG)
+#define FP_OFF2		(SIZEOF_FRAME2 - 2 * FFI_SIZEOF_ARG)
+#define S0_OFF2		(SIZEOF_FRAME2 - 3 * FFI_SIZEOF_ARG)
+#define GP_OFF2		(SIZEOF_FRAME2 - 4 * FFI_SIZEOF_ARG)
+#define V1_OFF2		(SIZEOF_FRAME2 - 5 * FFI_SIZEOF_ARG)
+#define V0_OFF2		(SIZEOF_FRAME2 - 6 * FFI_SIZEOF_ARG)
+#define FA_1_1_OFF2	(SIZEOF_FRAME2 - 7 * FFI_SIZEOF_ARG)
+#define FA_1_0_OFF2	(SIZEOF_FRAME2 - 8 * FFI_SIZEOF_ARG)
+#define FA_0_1_OFF2	(SIZEOF_FRAME2 - 9 * FFI_SIZEOF_ARG)
+#define FA_0_0_OFF2	(SIZEOF_FRAME2 - 10 * FFI_SIZEOF_ARG)
+
+	.text
+	.align	2
+	.globl	ffi_closure_O32
+	.ent	ffi_closure_O32
+ffi_closure_O32:
+$LFB1:
+	# Prologue
+	.frame	$fp, SIZEOF_FRAME2, ra
+	.set	noreorder
+	.cpload	t9
+	.set	reorder
+	SUBU	$sp, SIZEOF_FRAME2
+	.cprestore GP_OFF2
+$LCFI4:
+	REG_S	$16, S0_OFF2($sp)	 # Save s0
+	REG_S	$fp, FP_OFF2($sp)	 # Save frame pointer
+	REG_S	ra, RA_OFF2($sp)	 # Save return address
+$LCFI6:
+	move	$fp, $sp
+
+$LCFI7:
+	# Store all possible argument registers. If there are more than
+	# four arguments, then they are stored above where we put a3.
+	REG_S	a0, A0_OFF2($fp)
+	REG_S	a1, A1_OFF2($fp)
+	REG_S	a2, A2_OFF2($fp)
+	REG_S	a3, A3_OFF2($fp)
+
+	# Load ABI enum to s0
+	REG_L	$16, 20($8)	# cif pointer follows tramp.
+	REG_L	$16, 0($16)	# abi is first member.
+
+	li	$13, 1		# FFI_O32
+	bne	$16, $13, 1f	# Skip fp save if FFI_O32_SOFT_FLOAT
+	
+	# Store all possible float/double registers.
+	s.d	$f12, FA_0_0_OFF2($fp)
+	s.d	$f14, FA_1_0_OFF2($fp)
+1:	
+	# Call ffi_closure_mips_inner_O32 to do the work.
+	la	t9, ffi_closure_mips_inner_O32
+	move	a0, $8	 # Pointer to the ffi_closure
+	addu	a1, $fp, V0_OFF2
+	addu	a2, $fp, A0_OFF2
+	addu	a3, $fp, FA_0_0_OFF2
+	jalr	t9
+
+	# Load the return value into the appropriate register.
+	move	$8, $2
+	li	$9, FFI_TYPE_VOID
+	beq	$8, $9, closure_done
+
+	li	$13, 1		# FFI_O32
+	bne	$16, $13, 1f	# Skip fp restore if FFI_O32_SOFT_FLOAT
+
+	li	$9, FFI_TYPE_FLOAT
+	l.s	$f0, V0_OFF2($fp)
+	beq	$8, $9, closure_done
+
+	li	$9, FFI_TYPE_DOUBLE
+	l.d	$f0, V0_OFF2($fp)
+	beq	$8, $9, closure_done
+1:	
+	REG_L	$3, V1_OFF2($fp)
+	REG_L	$2, V0_OFF2($fp)
+
+closure_done:
+	# Epilogue
+	move	$sp, $fp
+	REG_L	$16, S0_OFF2($sp)	 # Restore s0
+	REG_L	$fp, FP_OFF2($sp)	 # Restore frame pointer
+	REG_L	ra,  RA_OFF2($sp)	 # Restore return address
+	ADDU	$sp, SIZEOF_FRAME2
+	j	ra
+$LFE1:
+	.end	ffi_closure_O32
+
+/* DWARF-2 unwind info. */
+
+	.section	.eh_frame,"a", at progbits
+$Lframe0:
+	.4byte	$LECIE0-$LSCIE0	 # Length of Common Information Entry
+$LSCIE0:
+	.4byte	0x0	 # CIE Identifier Tag
+	.byte	0x1	 # CIE Version
+	.ascii "zR\0"	 # CIE Augmentation
+	.uleb128 0x1	 # CIE Code Alignment Factor
+	.sleb128 4	 # CIE Data Alignment Factor
+	.byte	0x1f	 # CIE RA Column
+	.uleb128 0x1	 # Augmentation size
+	.byte	0x00	 # FDE Encoding (absptr)
+	.byte	0xc	 # DW_CFA_def_cfa
+	.uleb128 0x1d
+	.uleb128 0x0
+	.align	2
+$LECIE0:
+$LSFDE0:
+	.4byte	$LEFDE0-$LASFDE0	 # FDE Length
+$LASFDE0:
+	.4byte	$LASFDE0-$Lframe0	 # FDE CIE offset
+	.4byte	$LFB0	 # FDE initial location
+	.4byte	$LFE0-$LFB0	 # FDE address range
+	.uleb128 0x0	 # Augmentation size
+	.byte	0x4	 # DW_CFA_advance_loc4
+	.4byte	$LCFI0-$LFB0
+	.byte	0xe	 # DW_CFA_def_cfa_offset
+	.uleb128 0x18
+	.byte	0x4	 # DW_CFA_advance_loc4
+	.4byte	$LCFI2-$LCFI0
+	.byte	0x11	 # DW_CFA_offset_extended_sf
+	.uleb128 0x1e	 # $fp
+	.sleb128 -2	 # SIZEOF_FRAME2 - 2*FFI_SIZEOF_ARG($sp)
+	.byte	0x11	 # DW_CFA_offset_extended_sf
+	.uleb128 0x1f	 # $ra
+	.sleb128 -1	 # SIZEOF_FRAME2 - 1*FFI_SIZEOF_ARG($sp)
+	.byte	0x4	 # DW_CFA_advance_loc4
+	.4byte	$LCFI3-$LCFI2
+	.byte	0xc	 # DW_CFA_def_cfa
+	.uleb128 0x1e
+	.uleb128 0x18
+	.align	2
+$LEFDE0:
+$LSFDE1:
+	.4byte	$LEFDE1-$LASFDE1	 # FDE Length
+$LASFDE1:
+	.4byte	$LASFDE1-$Lframe0	 # FDE CIE offset
+	.4byte	$LFB1	 # FDE initial location
+	.4byte	$LFE1-$LFB1	 # FDE address range
+	.uleb128 0x0	 # Augmentation size
+	.byte	0x4	 # DW_CFA_advance_loc4
+	.4byte	$LCFI4-$LFB1
+	.byte	0xe	 # DW_CFA_def_cfa_offset
+	.uleb128 0x38
+	.byte	0x4	 # DW_CFA_advance_loc4
+	.4byte	$LCFI6-$LCFI4
+	.byte	0x11	 # DW_CFA_offset_extended_sf
+	.uleb128 0x10	 # $16
+	.sleb128 -3	 # SIZEOF_FRAME2 - 3*FFI_SIZEOF_ARG($sp)
+	.byte	0x11	 # DW_CFA_offset_extended_sf
+	.uleb128 0x1e	 # $fp
+	.sleb128 -2	 # SIZEOF_FRAME2 - 2*FFI_SIZEOF_ARG($sp)
+	.byte	0x11	 # DW_CFA_offset_extended_sf
+	.uleb128 0x1f	 # $ra
+	.sleb128 -1	 # SIZEOF_FRAME2 - 1*FFI_SIZEOF_ARG($sp)
+	.byte	0x4	 # DW_CFA_advance_loc4
+	.4byte	$LCFI7-$LCFI6
+	.byte	0xc	 # DW_CFA_def_cfa
+	.uleb128 0x1e
+	.uleb128 0x38
+	.align	2
+$LEFDE1:
+
+#endif

Added: vendor/Python/current/Modules/_ctypes/libffi/src/pa/ffi.c
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/pa/ffi.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/pa/ffi.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,625 @@
+/* -----------------------------------------------------------------------
+   ffi.c - (c) 2003-2004 Randolph Chung <tausq at debian.org>
+
+   HPPA Foreign Function Interface
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#define ROUND_UP(v, a)  (((size_t)(v) + (a) - 1) & ~((a) - 1))
+#define ROUND_DOWN(v, a)  (((size_t)(v) - (a) + 1) & ~((a) - 1))
+#define MIN_STACK_SIZE  64
+#define FIRST_ARG_SLOT  9
+#define DEBUG_LEVEL   0
+
+#define fldw(addr, fpreg) asm volatile ("fldw 0(%0), %%" #fpreg "L" : : "r"(addr) : #fpreg)
+#define fstw(fpreg, addr) asm volatile ("fstw %%" #fpreg "L, 0(%0)" : : "r"(addr))
+#define fldd(addr, fpreg) asm volatile ("fldd 0(%0), %%" #fpreg : : "r"(addr) : #fpreg)
+#define fstd(fpreg, addr) asm volatile ("fstd %%" #fpreg "L, 0(%0)" : : "r"(addr))
+
+#define debug(lvl, x...) do { if (lvl <= DEBUG_LEVEL) { printf(x); } } while (0)
+
+static inline int ffi_struct_type(ffi_type *t)
+{
+  size_t sz = t->size;
+
+  /* Small structure results are passed in registers,
+     larger ones are passed by pointer.  */
+
+  if (sz <= 1)
+    return FFI_TYPE_UINT8;
+  else if (sz == 2)
+    return FFI_TYPE_UINT16;
+  else if (sz == 3)
+    return FFI_TYPE_SMALL_STRUCT3;
+  else if (sz == 4)
+    return FFI_TYPE_UINT32;
+  else if (sz == 5)
+    return FFI_TYPE_SMALL_STRUCT5;
+  else if (sz == 6)
+    return FFI_TYPE_SMALL_STRUCT6;
+  else if (sz == 7)
+    return FFI_TYPE_SMALL_STRUCT7;
+  else if (sz <= 8)
+    return FFI_TYPE_UINT64;
+  else
+    return FFI_TYPE_STRUCT; /* else, we pass it by pointer.  */
+}
+
+/* PA has a downward growing stack, which looks like this:
+  
+   Offset
+        [ Variable args ]
+   SP = (4*(n+9))       arg word N
+   ...
+   SP-52                arg word 4
+        [ Fixed args ]
+   SP-48                arg word 3
+   SP-44                arg word 2
+   SP-40                arg word 1
+   SP-36                arg word 0
+        [ Frame marker ]
+   ...
+   SP-20                RP
+   SP-4                 previous SP
+  
+   First 4 non-FP 32-bit args are passed in gr26, gr25, gr24 and gr23
+   First 2 non-FP 64-bit args are passed in register pairs, starting
+     on an even numbered register (i.e. r26/r25 and r24+r23)
+   First 4 FP 32-bit arguments are passed in fr4L, fr5L, fr6L and fr7L
+   First 2 FP 64-bit arguments are passed in fr5 and fr7
+   The rest are passed on the stack starting at SP-52, but 64-bit
+     arguments need to be aligned to an 8-byte boundary
+  
+   This means we can have holes either in the register allocation,
+   or in the stack.  */
+
+/* ffi_prep_args is called by the assembly routine once stack space
+   has been allocated for the function's arguments
+  
+   The following code will put everything into the stack frame
+   (which was allocated by the asm routine), and on return
+   the asm routine will load the arguments that should be
+   passed by register into the appropriate registers
+  
+   NOTE: We load floating point args in this function... that means we
+   assume gcc will not mess with fp regs in here.  */
+
+/*@-exportheader@*/
+void ffi_prep_args_LINUX(UINT32 *stack, extended_cif *ecif, unsigned bytes)
+/*@=exportheader@*/
+{
+  register unsigned int i;
+  register ffi_type **p_arg;
+  register void **p_argv;
+  unsigned int slot = FIRST_ARG_SLOT - 1;
+  char *dest_cpy;
+
+  debug(1, "%s: stack = %p, ecif = %p, bytes = %u\n", __FUNCTION__, stack, ecif, bytes);
+
+  p_arg = ecif->cif->arg_types;
+  p_argv = ecif->avalue;
+
+  for (i = 0; i < ecif->cif->nargs; i++)
+    {
+      int type = (*p_arg)->type;
+
+      switch (type)
+	{
+	case FFI_TYPE_SINT8:
+	  slot++;
+	  *(SINT32 *)(stack - slot) = *(SINT8 *)(*p_argv);
+	  break;
+
+	case FFI_TYPE_UINT8:
+	  slot++;
+	  *(UINT32 *)(stack - slot) = *(UINT8 *)(*p_argv);
+	  break;
+
+	case FFI_TYPE_SINT16:
+	  slot++;
+	  *(SINT32 *)(stack - slot) = *(SINT16 *)(*p_argv);
+	  break;
+
+	case FFI_TYPE_UINT16:
+	  slot++;
+	  *(UINT32 *)(stack - slot) = *(UINT16 *)(*p_argv);
+	  break;
+
+	case FFI_TYPE_UINT32:
+	case FFI_TYPE_SINT32:
+	case FFI_TYPE_POINTER:
+	  slot++;
+	  debug(3, "Storing UINT32 %u in slot %u\n", *(UINT32 *)(*p_argv), slot);
+	  *(UINT32 *)(stack - slot) = *(UINT32 *)(*p_argv);
+	  break;
+
+	case FFI_TYPE_UINT64:
+	case FFI_TYPE_SINT64:
+	  slot += 2;
+	  if (slot & 1)
+	    slot++;
+
+	  *(UINT32 *)(stack - slot) = (*(UINT64 *)(*p_argv)) >> 32;
+	  *(UINT32 *)(stack - slot + 1) = (*(UINT64 *)(*p_argv)) & 0xffffffffUL;
+	  break;
+
+	case FFI_TYPE_FLOAT:
+	  /* First 4 args go in fr4L - fr7L */
+	  slot++;
+	  switch (slot - FIRST_ARG_SLOT)
+	    {
+	    case 0: fldw(*p_argv, fr4); break;
+	    case 1: fldw(*p_argv, fr5); break;
+	    case 2: fldw(*p_argv, fr6); break;
+	    case 3: fldw(*p_argv, fr7); break;
+	    default:
+	      /* Other ones are just passed on the stack.  */
+	      debug(3, "Storing UINT32(float) in slot %u\n", slot);
+	      *(UINT32 *)(stack - slot) = *(UINT32 *)(*p_argv);
+	      break;
+	    }
+	    break;
+
+	case FFI_TYPE_DOUBLE:
+	  slot += 2;
+	  if (slot & 1)
+	    slot++;
+	  switch (slot - FIRST_ARG_SLOT + 1)
+	    {
+	      /* First 2 args go in fr5, fr7 */
+	      case 2: fldd(*p_argv, fr5); break;
+	      case 4: fldd(*p_argv, fr7); break;
+	      default:
+	        debug(3, "Storing UINT64(double) at slot %u\n", slot);
+	        *(UINT64 *)(stack - slot) = *(UINT64 *)(*p_argv);
+	        break;
+	    }
+	  break;
+
+	case FFI_TYPE_STRUCT:
+
+	  /* Structs smaller or equal than 4 bytes are passed in one
+	     register. Structs smaller or equal 8 bytes are passed in two
+	     registers. Larger structures are passed by pointer.  */
+
+	  if((*p_arg)->size <= 4) 
+	    {
+	      slot++;
+	      dest_cpy = (char *)(stack - slot);
+	      dest_cpy += 4 - (*p_arg)->size;
+	      memcpy((char *)dest_cpy, (char *)*p_argv, (*p_arg)->size);
+	    }
+	  else if ((*p_arg)->size <= 8) 
+	    {
+	      slot += 2;
+	      if (slot & 1)
+	        slot++;
+	      dest_cpy = (char *)(stack - slot);
+	      dest_cpy += 8 - (*p_arg)->size;
+	      memcpy((char *)dest_cpy, (char *)*p_argv, (*p_arg)->size);
+	    } 
+	  else 
+	    {
+	      slot++;
+	      *(UINT32 *)(stack - slot) = (UINT32)(*p_argv);
+	    }
+	  break;
+
+	default:
+	  FFI_ASSERT(0);
+	}
+
+      p_arg++;
+      p_argv++;
+    }
+
+  /* Make sure we didn't mess up and scribble on the stack.  */
+  {
+    int n;
+
+    debug(5, "Stack setup:\n");
+    for (n = 0; n < (bytes + 3) / 4; n++)
+      {
+	if ((n%4) == 0) { debug(5, "\n%08x: ", (unsigned int)(stack - n)); }
+	debug(5, "%08x ", *(stack - n));
+      }
+    debug(5, "\n");
+  }
+
+  FFI_ASSERT(slot * 4 <= bytes);
+
+  return;
+}
+
+static void ffi_size_stack_LINUX(ffi_cif *cif)
+{
+  ffi_type **ptr;
+  int i;
+  int z = 0; /* # stack slots */
+
+  for (ptr = cif->arg_types, i = 0; i < cif->nargs; ptr++, i++)
+    {
+      int type = (*ptr)->type;
+
+      switch (type)
+	{
+	case FFI_TYPE_DOUBLE:
+	case FFI_TYPE_UINT64:
+	case FFI_TYPE_SINT64:
+	  z += 2 + (z & 1); /* must start on even regs, so we may waste one */
+	  break;
+
+	case FFI_TYPE_STRUCT:
+	  z += 1; /* pass by ptr, callee will copy */
+	  break;
+
+	default: /* <= 32-bit values */
+	  z++;
+	}
+    }
+
+  /* We can fit up to 6 args in the default 64-byte stack frame,
+     if we need more, we need more stack.  */
+  if (z <= 6)
+    cif->bytes = MIN_STACK_SIZE; /* min stack size */
+  else
+    cif->bytes = 64 + ROUND_UP((z - 6) * sizeof(UINT32), MIN_STACK_SIZE);
+
+  debug(3, "Calculated stack size is %u bytes\n", cif->bytes);
+}
+
+/* Perform machine dependent cif processing.  */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+{
+  /* Set the return type flag */
+  switch (cif->rtype->type)
+    {
+    case FFI_TYPE_VOID:
+    case FFI_TYPE_FLOAT:
+    case FFI_TYPE_DOUBLE:
+      cif->flags = (unsigned) cif->rtype->type;
+      break;
+
+    case FFI_TYPE_STRUCT:
+      /* For the return type we have to check the size of the structures.
+	 If the size is smaller or equal 4 bytes, the result is given back
+	 in one register. If the size is smaller or equal 8 bytes than we
+	 return the result in two registers. But if the size is bigger than
+	 8 bytes, we work with pointers.  */
+      cif->flags = ffi_struct_type(cif->rtype);
+      break;
+
+    case FFI_TYPE_UINT64:
+    case FFI_TYPE_SINT64:
+      cif->flags = FFI_TYPE_UINT64;
+      break;
+
+    default:
+      cif->flags = FFI_TYPE_INT;
+      break;
+    }
+
+  /* Lucky us, because of the unique PA ABI we get to do our
+     own stack sizing.  */
+  switch (cif->abi)
+    {
+    case FFI_LINUX:
+      ffi_size_stack_LINUX(cif);
+      break;
+
+    default:
+      FFI_ASSERT(0);
+      break;
+    }
+
+  return FFI_OK;
+}
+
+/*@-declundef@*/
+/*@-exportheader@*/
+extern void ffi_call_LINUX(void (*)(UINT32 *, extended_cif *, unsigned),
+			   /*@out@*/ extended_cif *,
+			   unsigned, unsigned,
+			   /*@out@*/ unsigned *,
+			   void (*fn)());
+/*@=declundef@*/
+/*@=exportheader@*/
+
+void ffi_call(/*@dependent@*/ ffi_cif *cif,
+	      void (*fn)(),
+	      /*@out@*/ void *rvalue,
+	      /*@dependent@*/ void **avalue)
+{
+  extended_cif ecif;
+
+  ecif.cif = cif;
+  ecif.avalue = avalue;
+
+  /* If the return value is a struct and we don't have a return
+     value address then we need to make one.  */
+
+  if ((rvalue == NULL) &&
+      (cif->rtype->type == FFI_TYPE_STRUCT))
+    {
+      /*@-sysunrecog@*/
+      ecif.rvalue = alloca(cif->rtype->size);
+      /*@=sysunrecog@*/
+    }
+  else
+    ecif.rvalue = rvalue;
+
+
+  switch (cif->abi)
+    {
+    case FFI_LINUX:
+      /*@-usedef@*/
+      debug(2, "Calling ffi_call_LINUX: ecif=%p, bytes=%u, flags=%u, rvalue=%p, fn=%p\n", &ecif, cif->bytes, cif->flags, ecif.rvalue, (void *)fn);
+      ffi_call_LINUX(ffi_prep_args_LINUX, &ecif, cif->bytes,
+		     cif->flags, ecif.rvalue, fn);
+      /*@=usedef@*/
+      break;
+
+    default:
+      FFI_ASSERT(0);
+      break;
+    }
+}
+
+#if FFI_CLOSURES
+/* This is more-or-less an inverse of ffi_call -- we have arguments on
+   the stack, and we need to fill them into a cif structure and invoke
+   the user function. This really ought to be in asm to make sure
+   the compiler doesn't do things we don't expect.  */
+UINT32 ffi_closure_inner_LINUX(ffi_closure *closure, UINT32 *stack)
+{
+  ffi_cif *cif;
+  void **avalue;
+  void *rvalue;
+  UINT32 ret[2]; /* function can return up to 64-bits in registers */
+  ffi_type **p_arg;
+  char *tmp;
+  int i, avn, slot = FIRST_ARG_SLOT - 1;
+  register UINT32 r28 asm("r28");
+
+  cif = closure->cif;
+
+  /* If returning via structure, callee will write to our pointer.  */
+  if (cif->flags == FFI_TYPE_STRUCT)
+    rvalue = (void *)r28;
+  else
+    rvalue = &ret[0];
+
+  avalue = (void **)alloca(cif->nargs * FFI_SIZEOF_ARG);
+  avn = cif->nargs;
+  p_arg = cif->arg_types;
+
+  for (i = 0; i < avn; i++)
+    {
+      int type = (*p_arg)->type;
+
+      switch (type)
+	{
+	case FFI_TYPE_SINT8:
+	case FFI_TYPE_UINT8:
+	case FFI_TYPE_SINT16:
+	case FFI_TYPE_UINT16:
+	case FFI_TYPE_SINT32:
+	case FFI_TYPE_UINT32:
+	case FFI_TYPE_POINTER:
+	  slot++;
+	  avalue[i] = (char *)(stack - slot) + sizeof(UINT32) - (*p_arg)->size;
+	  break;
+
+	case FFI_TYPE_SINT64:
+	case FFI_TYPE_UINT64:
+	  slot += 2;
+	  if (slot & 1)
+	    slot++;
+	  avalue[i] = (void *)(stack - slot);
+	  break;
+
+	case FFI_TYPE_FLOAT:
+	  slot++;
+	  switch (slot - FIRST_ARG_SLOT)
+	    {
+	    case 0: fstw(fr4, (void *)(stack - slot)); break;
+	    case 1: fstw(fr5, (void *)(stack - slot)); break;
+	    case 2: fstw(fr6, (void *)(stack - slot)); break;
+	    case 3: fstw(fr7, (void *)(stack - slot)); break;
+	    }
+	  avalue[i] = (void *)(stack - slot);
+	  break;
+
+	case FFI_TYPE_DOUBLE:
+	  slot += 2;
+	  if (slot & 1)
+	    slot++;
+	  switch (slot - FIRST_ARG_SLOT + 1)
+	    {
+	    case 2: fstd(fr5, (void *)(stack - slot)); break;
+	    case 4: fstd(fr7, (void *)(stack - slot)); break;
+	    }
+	  avalue[i] = (void *)(stack - slot);
+	  break;
+
+	case FFI_TYPE_STRUCT:
+	  /* Structs smaller or equal than 4 bytes are passed in one
+	     register. Structs smaller or equal 8 bytes are passed in two
+	     registers. Larger structures are passed by pointer.  */
+	  if((*p_arg)->size <= 4) {
+	    slot++;
+	    avalue[i] = (void *)(stack - slot) + sizeof(UINT32) -
+	      (*p_arg)->size;
+	  } else if ((*p_arg)->size <= 8) {
+	    slot += 2;
+	    if (slot & 1)
+	      slot++;
+	    avalue[i] = (void *)(stack - slot) + sizeof(UINT64) -
+	      (*p_arg)->size;
+	  } else {
+	    slot++;
+	    avalue[i] = (void *) *(stack - slot);
+	  }
+	  break;
+
+	default:
+	  FFI_ASSERT(0);
+	}
+
+      p_arg++;
+    }
+
+  /* Invoke the closure.  */
+  (closure->fun) (cif, rvalue, avalue, closure->user_data);
+
+  debug(3, "after calling function, ret[0] = %08x, ret[1] = %08x\n", ret[0], ret[1]);
+
+  /* Store the result */
+  switch (cif->flags)
+    {
+    case FFI_TYPE_UINT8:
+      *(stack - FIRST_ARG_SLOT) = (UINT8)(ret[0] >> 24);
+      break;
+    case FFI_TYPE_SINT8:
+      *(stack - FIRST_ARG_SLOT) = (SINT8)(ret[0] >> 24);
+      break;
+    case FFI_TYPE_UINT16:
+      *(stack - FIRST_ARG_SLOT) = (UINT16)(ret[0] >> 16);
+      break;
+    case FFI_TYPE_SINT16:
+      *(stack - FIRST_ARG_SLOT) = (SINT16)(ret[0] >> 16);
+      break;
+    case FFI_TYPE_INT:
+    case FFI_TYPE_SINT32:
+    case FFI_TYPE_UINT32:
+      *(stack - FIRST_ARG_SLOT) = ret[0];
+      break;
+    case FFI_TYPE_SINT64:
+    case FFI_TYPE_UINT64:
+      *(stack - FIRST_ARG_SLOT) = ret[0];
+      *(stack - FIRST_ARG_SLOT - 1) = ret[1];
+      break;
+
+    case FFI_TYPE_DOUBLE:
+      fldd(rvalue, fr4);
+      break;
+
+    case FFI_TYPE_FLOAT:
+      fldw(rvalue, fr4);
+      break;
+
+    case FFI_TYPE_STRUCT:
+      /* Don't need a return value, done by caller.  */
+      break;
+
+    case FFI_TYPE_SMALL_STRUCT3:
+      tmp = (void*)(stack -  FIRST_ARG_SLOT);
+      tmp += 4 - cif->rtype->size;
+      memcpy((void*)tmp, &ret[0], cif->rtype->size);
+      break;
+
+    case FFI_TYPE_SMALL_STRUCT5:
+    case FFI_TYPE_SMALL_STRUCT6:
+    case FFI_TYPE_SMALL_STRUCT7:
+      {
+	unsigned int ret2[2];
+	int off;
+
+	/* Right justify ret[0] and ret[1] */
+	switch (cif->flags)
+	  {
+	    case FFI_TYPE_SMALL_STRUCT5: off = 3; break;
+	    case FFI_TYPE_SMALL_STRUCT6: off = 2; break;
+	    case FFI_TYPE_SMALL_STRUCT7: off = 1; break;
+	    default: off = 0; break;
+	  }
+
+	memset (ret2, 0, sizeof (ret2));
+	memcpy ((char *)ret2 + off, ret, 8 - off);
+
+	*(stack - FIRST_ARG_SLOT) = ret2[0];
+	*(stack - FIRST_ARG_SLOT - 1) = ret2[1];
+      }
+      break;
+
+    case FFI_TYPE_POINTER:
+    case FFI_TYPE_VOID:
+      break;
+
+    default:
+      debug(0, "assert with cif->flags: %d\n",cif->flags);
+      FFI_ASSERT(0);
+      break;
+    }
+  return FFI_OK;
+}
+
+/* Fill in a closure to refer to the specified fun and user_data.
+   cif specifies the argument and result types for fun.
+   The cif must already be prep'ed.  */
+
+void ffi_closure_LINUX(void);
+
+ffi_status
+ffi_prep_closure (ffi_closure* closure,
+		  ffi_cif* cif,
+		  void (*fun)(ffi_cif*,void*,void**,void*),
+		  void *user_data)
+{
+  UINT32 *tramp = (UINT32 *)(closure->tramp);
+
+  FFI_ASSERT (cif->abi == FFI_LINUX);
+
+  /* Make a small trampoline that will branch to our
+     handler function. Use PC-relative addressing.  */
+
+  tramp[0] = 0xeaa00000; /* b,l  .+8, %r21      ; %r21 <- pc+8 */
+  tramp[1] = 0xd6a01c1e; /* depi 0,31,2, %r21   ; mask priv bits */
+  tramp[2] = 0x4aa10028; /* ldw  20(%r21), %r1  ; load plabel */
+  tramp[3] = 0x36b53ff1; /* ldo  -8(%r21), %r21 ; get closure addr */
+  tramp[4] = 0x0c201096; /* ldw  0(%r1), %r22   ; address of handler */
+  tramp[5] = 0xeac0c000; /* bv	 %r0(%r22)      ; branch to handler */
+  tramp[6] = 0x0c281093; /* ldw  4(%r1), %r19   ; GP of handler */
+  tramp[7] = ((UINT32)(ffi_closure_LINUX) & ~2);
+
+  /* Flush d/icache -- have to flush up 2 two lines because of
+     alignment.  */
+  asm volatile (
+		"fdc 0(%0)\n"
+		"fdc %1(%0)\n"
+		"fic 0(%%sr4, %0)\n"
+		"fic %1(%%sr4, %0)\n"
+		"sync\n"
+		: : "r"((unsigned long)tramp & ~31), "r"(32 /* stride */));
+
+  closure->cif  = cif;
+  closure->user_data = user_data;
+  closure->fun  = fun;
+
+  return FFI_OK;
+}
+#endif

Added: vendor/Python/current/Modules/_ctypes/libffi/src/pa/ffitarget.h
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/pa/ffitarget.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/pa/ffitarget.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,59 @@
+/* -----------------------------------------------------------------*-C-*-
+   ffitarget.h - Copyright (c) 1996-2003  Red Hat, Inc.
+   Target configuration macros for hppa.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+
+   ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+/* ---- System specific configurations ----------------------------------- */
+
+#ifndef LIBFFI_ASM
+typedef unsigned long          ffi_arg;
+typedef signed long            ffi_sarg;
+
+typedef enum ffi_abi {
+  FFI_FIRST_ABI = 0,
+
+#ifdef PA
+  FFI_LINUX,
+  FFI_DEFAULT_ABI = FFI_LINUX,
+#endif
+
+  FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
+} ffi_abi;
+#endif
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#define FFI_CLOSURES 1
+#define FFI_NATIVE_RAW_API 0
+
+#define FFI_TRAMPOLINE_SIZE 32
+
+#define FFI_TYPE_SMALL_STRUCT3 -1
+#define FFI_TYPE_SMALL_STRUCT5 -2
+#define FFI_TYPE_SMALL_STRUCT6 -3
+#define FFI_TYPE_SMALL_STRUCT7 -4
+#endif
+

Added: vendor/Python/current/Modules/_ctypes/libffi/src/pa/linux.S
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/pa/linux.S	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/pa/linux.S	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,307 @@
+/* -----------------------------------------------------------------------
+   linux.S - (c) 2003-2004 Randolph Chung <tausq at debian.org>
+
+   HPPA Foreign Function Interface
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+
+	.text
+	.level 1.1
+	.align 4
+
+	/* void ffi_call_LINUX(void (*)(char *, extended_cif *),
+			       extended_cif *ecif,
+			       unsigned bytes,
+			       unsigned flags,
+			       unsigned *rvalue,
+			       void (*fn)());
+	 */
+
+	.export ffi_call_LINUX,code
+	.import ffi_prep_args_LINUX,code
+
+	.type ffi_call_LINUX, @function
+.LFB1:
+ffi_call_LINUX:
+	.proc
+	.callinfo FRAME=64,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=4
+	.entry
+	stw %rp, -20(%sp)
+	copy %r3, %r1
+.LCFI11:
+
+	copy %sp, %r3
+.LCFI12:
+
+	/* Setup the stack for calling prep_args...
+	   We want the stack to look like this:
+
+	   [ Previous stack                            ] <- %r3
+
+	   [ 64-bytes register save area               ] <- %r4
+
+	   [ Stack space for actual call, passed as    ] <- %arg0
+	   [     arg0 to ffi_prep_args_LINUX           ]
+
+	   [ Stack for calling prep_args               ] <- %sp
+	 */
+
+	stwm %r1, 64(%sp)
+	stw %r4, 12(%r3)
+.LCFI13:
+	copy %sp, %r4
+
+	addl %arg2, %r4, %arg0                  /* arg stack */
+	stw %arg3, -48(%r3)                     /* save flags; we need it later */
+
+	/* Call prep_args:
+	   %arg0(stack) -- set up above
+	   %arg1(ecif) -- same as incoming param
+	   %arg2(bytes) -- same as incoming param */
+	bl ffi_prep_args_LINUX,%r2
+	ldo 64(%arg0), %sp
+	ldo -64(%sp), %sp
+
+	/* now %sp should point where %arg0 was pointing.  */
+
+	/* Load the arguments that should be passed in registers
+	   The fp args were loaded by the prep_args function.  */
+	ldw -36(%sp), %arg0
+	ldw -40(%sp), %arg1
+	ldw -44(%sp), %arg2
+	ldw -48(%sp), %arg3
+
+	/* in case the function is going to return a structure
+	   we need to give it a place to put the result.  */
+	ldw -52(%r3), %ret0                     /* %ret0 <- rvalue */
+	ldw -56(%r3), %r22                      /* %r22 <- function to call */
+	bl $$dyncall, %r31                      /* Call the user function */
+	copy %r31, %rp
+
+	/* Prepare to store the result; we need to recover flags and rvalue.  */
+	ldw -48(%r3), %r21                      /* r21 <- flags */
+	ldw -52(%r3), %r20                      /* r20 <- rvalue */
+
+	/* Store the result according to the return type.  */
+
+checksmst3:
+	comib,<>,n FFI_TYPE_SMALL_STRUCT3, %r21, checksmst567
+	/* 3-byte structs are returned in ret0 as ??xxyyzz.  Shift
+	   left 8 bits to write to the result structure.  */
+	zdep %ret0, 23, 24, %r22
+	b done
+	stw %r22, 0(%r20)
+
+checksmst567:
+	/* 5-7 byte values are returned right justified:
+	      ret0     ret1
+	   5: ??????aa bbccddee
+	   6: ????aabb ccddeeff
+	   7: ??aabbcc ddeeffgg
+
+	   To store this in the result, write the first 4 bytes into a temp
+	   register using shrpw (t1 = aabbccdd), followed by a rotation of
+	   ret1:
+
+	      ret0     ret1	   ret1
+	   5: ??????aa bbccddee -> eebbccdd (rotate 8)
+	   6: ????aabb ccddeeff -> eeffccdd (rotate 16)
+	   7: ??aabbcc ddeeffgg -> eeffggdd (rotate 24)
+
+	   then we write (t1, ret1) into the result.  */
+
+	addi,<> -FFI_TYPE_SMALL_STRUCT5,%r21,%r0
+	ldi 8, %r22
+	addi,<> -FFI_TYPE_SMALL_STRUCT6,%r21,%r0
+	ldi 16, %r22
+	addi,<> -FFI_TYPE_SMALL_STRUCT7,%r21,%r0
+	ldi 24, %r22
+
+	/* This relies on all the FFI_TYPE_*_STRUCT* defines being <0 */
+	cmpib,<=,n 0, %r21, checkint8
+	mtsar %r22
+
+	shrpw %ret0, %ret1, %sar, %ret0  /* ret0 = aabbccdd */
+	shrpw %ret1, %ret1, %sar, %ret1  /* rotate ret1 */
+	
+	stw %ret0, 0(%r20)
+	b done
+	stw %ret1, 4(%r20)
+
+checkint8:
+	comib,<>,n FFI_TYPE_UINT8, %r21, checkint16
+	b done
+	stb %ret0, 0(%r20)
+
+checkint16:
+	comib,<>,n FFI_TYPE_UINT16, %r21, checkint32
+	b done
+	sth %ret0, 0(%r20)
+
+checkint32:
+	comib,<>,n FFI_TYPE_UINT32, %r21, checkint
+	b done
+	stw %ret0, 0(%r20)
+
+checkint:
+	comib,<>,n FFI_TYPE_INT, %r21, checkll
+	b done
+	stw %ret0, 0(%r20)
+
+checkll:
+	comib,<>,n FFI_TYPE_UINT64, %r21, checkdbl
+	stw %ret0, 0(%r20)
+	b done
+	stw %ret1, 4(%r20)
+
+checkdbl:
+	comib,<>,n FFI_TYPE_DOUBLE, %r21, checkfloat
+	b done
+	fstd %fr4,0(%r20)
+
+checkfloat:
+	comib,<>,n FFI_TYPE_FLOAT, %r21, done
+	fstw %fr4L,0(%r20)
+
+	/* structure returns are either handled by one of the
+	   INT/UINT64 cases above, or, if passed by pointer,
+	   is handled by the callee.  */
+
+done:
+	/* all done, return */
+	copy %r4, %sp                           /* pop arg stack */
+	ldw 12(%r3), %r4
+	ldwm -64(%sp), %r3                      /* .. and pop stack */
+	ldw -20(%sp), %rp
+	bv %r0(%rp)
+	nop
+	.exit
+	.procend
+.LFE1:
+
+	/* void ffi_closure_LINUX(void);
+	   Called with closure argument in %r21 */
+	.export ffi_closure_LINUX,code
+	.import ffi_closure_inner_LINUX,code
+
+	.type ffi_closure_LINUX, @function
+.LFB2:
+ffi_closure_LINUX:
+	.proc
+	.callinfo FRAME=64,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=3
+	.entry
+
+	stw %rp, -20(%sp)
+.LCFI20:
+	copy %r3, %r1
+.LCFI21:
+	copy %sp, %r3
+.LCFI22:
+	stwm %r1, 64(%sp)
+
+	/* Put arguments onto the stack and call ffi_closure_inner.  */
+	stw %arg0, -36(%r3)
+	stw %arg1, -40(%r3)
+	stw %arg2, -44(%r3)
+	stw %arg3, -48(%r3)
+
+	copy %r21, %arg0
+	bl ffi_closure_inner_LINUX, %r2
+	copy %r3, %arg1
+
+	ldwm -64(%sp), %r3
+	ldw -20(%sp), %rp
+	ldw -36(%sp), %ret0
+	bv %r0(%r2)
+	ldw -40(%sp), %ret1
+
+	.exit
+	.procend
+.LFE2:
+
+	.section        ".eh_frame",EH_FRAME_FLAGS, at progbits
+.Lframe1:
+	.word   .LECIE1-.LSCIE1 ;# Length of Common Information Entry
+.LSCIE1:
+	.word   0x0     ;# CIE Identifier Tag
+	.byte   0x1     ;# CIE Version
+	.ascii "\0"     ;# CIE Augmentation
+	.uleb128 0x1    ;# CIE Code Alignment Factor
+	.sleb128 4      ;# CIE Data Alignment Factor
+	.byte   0x2     ;# CIE RA Column
+	.byte   0xc     ;# DW_CFA_def_cfa
+	.uleb128 0x1e
+	.uleb128 0x0
+	.align 4
+.LECIE1:
+.LSFDE1:
+	.word   .LEFDE1-.LASFDE1        ;# FDE Length
+.LASFDE1:
+	.word   .LASFDE1-.Lframe1       ;# FDE CIE offset
+	.word   .LFB1   ;# FDE initial location
+	.word   .LFE1-.LFB1     ;# FDE address range
+
+	.byte   0x4     ;# DW_CFA_advance_loc4
+	.word   .LCFI11-.LFB1
+	.byte	0x83	;# DW_CFA_offset, column 0x3
+	.uleb128 0x0
+	.byte   0x11    ;# DW_CFA_offset_extended_sf; save r2 at [r30-20]
+	.uleb128 0x2
+	.sleb128 -5
+
+	.byte   0x4     ;# DW_CFA_advance_loc4
+	.word   .LCFI12-.LCFI11
+	.byte   0xd     ;# DW_CFA_def_cfa_register = r3
+	.uleb128 0x3
+
+	.byte   0x4     ;# DW_CFA_advance_loc4
+	.word   .LCFI13-.LCFI12
+	.byte	0x84	;# DW_CFA_offset, column 0x4
+	.uleb128 0x3
+
+	.align 4
+.LEFDE1:
+
+.LSFDE2:
+	.word   .LEFDE2-.LASFDE2        ;# FDE Length
+.LASFDE2:
+	.word   .LASFDE2-.Lframe1       ;# FDE CIE offset
+	.word   .LFB2   ;# FDE initial location
+	.word   .LFE2-.LFB2     ;# FDE address range
+	.byte   0x4     ;# DW_CFA_advance_loc4
+	.word   .LCFI21-.LFB2
+	.byte   0x83    ;# DW_CFA_offset, column 0x3
+	.uleb128 0x0
+	.byte   0x11    ;# DW_CFA_offset_extended_sf
+	.uleb128 0x2
+	.sleb128 -5
+
+	.byte   0x4     ;# DW_CFA_advance_loc4
+	.word   .LCFI12-.LCFI11
+	.byte   0xd     ;# DW_CFA_def_cfa_register = r3
+	.uleb128 0x3
+
+	.align 4
+.LEFDE2:

Added: vendor/Python/current/Modules/_ctypes/libffi/src/powerpc/aix.S
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/powerpc/aix.S	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/powerpc/aix.S	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,225 @@
+/* -----------------------------------------------------------------------
+   aix.S - Copyright (c) 2002 Free Software Foundation, Inc.
+   based on darwin.S by John Hornkvist
+
+   PowerPC Assembly glue.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+	.set r0,0
+	.set r1,1
+	.set r2,2
+	.set r3,3
+	.set r4,4
+	.set r5,5
+	.set r6,6
+	.set r7,7
+	.set r8,8
+	.set r9,9
+	.set r10,10
+	.set r11,11
+	.set r12,12
+	.set r13,13
+	.set r14,14
+	.set r15,15
+	.set r16,16
+	.set r17,17
+	.set r18,18
+	.set r19,19
+	.set r20,20
+	.set r21,21
+	.set r22,22
+	.set r23,23
+	.set r24,24
+	.set r25,25
+	.set r26,26
+	.set r27,27
+	.set r28,28
+	.set r29,29
+	.set r30,30
+	.set r31,31
+	.set f0,0
+	.set f1,1
+	.set f2,2
+	.set f3,3
+	.set f4,4
+	.set f5,5
+	.set f6,6
+	.set f7,7
+	.set f8,8
+	.set f9,9
+	.set f10,10
+	.set f11,11
+	.set f12,12
+	.set f13,13
+	.set f14,14
+	.set f15,15
+	.set f16,16
+	.set f17,17
+	.set f18,18
+	.set f19,19
+	.set f20,20
+	.set f21,21
+
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+#define JUMPTARGET(name) name
+#define L(x) x
+	.file "aix.S"
+	.toc
+	.csect .text[PR]
+	.align 2
+.globl ffi_prep_args
+
+.csect .text[PR]
+	.align 2
+	.globl ffi_call_AIX
+	.globl .ffi_call_AIX
+.csect ffi_call_AIX[DS]
+ffi_call_AIX:
+	.long .ffi_call_AIX, TOC[tc0], 0
+	.csect .text[PR]
+.ffi_call_AIX:
+	mr      r12,r8 // We only need r12 until the call, so it doesn't have to be saved...
+	/* Save the old stack pointer as AP.  */
+	mr	r8,r1
+
+	/* Allocate the stack space we need.  */
+	stwux	r1,r1,r4
+
+	/* Save registers we use.  */
+	mflr	r9
+
+	stw	r28,-16(r8)
+	stw	r29,-12(r8)
+	stw	r30, -8(r8)
+	stw	r31, -4(r8)
+
+	stw	r9,  8(r8)
+	stw	r2, 20(r1)
+
+	/* Save arguments over call...  */
+	mr	r31,r5	/* flags, */
+	mr	r30,r6	/* rvalue, */
+	mr	r29,r7	/* function address, */
+	mr	r28,r8	/* our AP. */
+
+	/* Call ffi_prep_args.  */
+	mr	r4,r1
+	li	r9,0
+
+	lwz	r2,4(r12)
+	lwz	r12,0(r12)
+	mtctr	r12 // r12 holds address of _ffi_prep_args
+	bctrl
+	lwz     r2,20(r1)
+
+	/* Now do the call.  */
+	lwz	r12,0(r29)
+	/* Set up cr1 with bits 4-7 of the flags.  */
+	mtcrf	0x40,r31
+	stw	r2,20(r1)
+	mtctr	r12
+	lwz	r2,4(r29)
+	/* Load all those argument registers.  */
+	// We have set up a nice stack frame, just load it into registers.
+	lwz     r3, 20+(1*4)(r1)
+	lwz     r4, 20+(2*4)(r1)
+	lwz     r5, 20+(3*4)(r1)
+	lwz     r6, 20+(4*4)(r1)
+	nop
+	lwz     r7, 20+(5*4)(r1)
+	lwz     r8, 20+(6*4)(r1)
+	lwz     r9, 20+(7*4)(r1)
+	lwz     r10,20+(8*4)(r1)
+
+L1:
+	/* Load all the FP registers.  */
+	bf	6,L2 // 2f + 0x18
+	lfd	f1,-16-(13*8)(r28)
+	lfd	f2,-16-(12*8)(r28)
+	lfd	f3,-16-(11*8)(r28)
+	lfd	f4,-16-(10*8)(r28)
+	nop
+	lfd	f5,-16-(9*8)(r28)
+	lfd	f6,-16-(8*8)(r28)
+	lfd	f7,-16-(7*8)(r28)
+	lfd	f8,-16-(6*8)(r28)
+	nop
+	lfd     f9,-16-(5*8)(r28)
+	lfd     f10,-16-(4*8)(r28)
+	lfd     f11,-16-(3*8)(r28)
+	lfd     f12,-16-(2*8)(r28)
+	nop
+	lfd     f13,-16-(1*8)(r28)
+
+L2:
+	/* Make the call.  */
+	bctrl
+	lwz r2,20(r1)
+
+	/* Now, deal with the return value.  */
+	mtcrf	0x01,r31
+
+	bt	30,L(done_return_value)
+	bt	29,L(fp_return_value)
+	stw	r3,0(r30)
+	bf	28,L(done_return_value)
+	stw	r4,4(r30)
+
+	/* Fall through...  */
+
+L(done_return_value):
+	/* Restore the registers we used and return.  */
+	lwz	r9,   8(r28)
+	lwz	r31,  -4(r28)
+	mtlr	r9
+	lwz	r30, -8(r28)
+	lwz	r29,-12(r28)
+	lwz	r28,-16(r28)
+	lwz	r1,0(r1)
+	blr
+
+L(fp_return_value):
+	bf	28,L(float_return_value)
+	stfd	f1,0(r30)
+	b	L(done_return_value)
+L(float_return_value):
+	stfs	f1,0(r30)
+	b	L(done_return_value)
+	.long 0
+	.byte 0,0,0,1,128,4,0,0
+//END(ffi_call_AIX)
+
+.csect .text[PR]
+	.align 2
+	.globl ffi_call_DARWIN
+	.globl .ffi_call_DARWIN
+.csect ffi_call_DARWIN[DS]
+ffi_call_DARWIN:
+	.long .ffi_call_DARWIN, TOC[tc0], 0
+	.csect .text[PR]
+.ffi_call_DARWIN:
+	blr
+	.long 0
+	.byte 0,0,0,0,0,0,0,0
+//END(ffi_call_DARWIN)

Added: vendor/Python/current/Modules/_ctypes/libffi/src/powerpc/aix_closure.S
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/powerpc/aix_closure.S	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/powerpc/aix_closure.S	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,247 @@
+/* -----------------------------------------------------------------------
+   aix_closure.S - Copyright (c) 2002 2003 Free Software Foundation, Inc.
+   based on darwin_closure.S
+
+   PowerPC Assembly glue.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+	.set r0,0
+	.set r1,1
+	.set r2,2
+	.set r3,3
+	.set r4,4
+	.set r5,5
+	.set r6,6
+	.set r7,7
+	.set r8,8
+	.set r9,9
+	.set r10,10
+	.set r11,11
+	.set r12,12
+	.set r13,13
+	.set r14,14
+	.set r15,15
+	.set r16,16
+	.set r17,17
+	.set r18,18
+	.set r19,19
+	.set r20,20
+	.set r21,21
+	.set r22,22
+	.set r23,23
+	.set r24,24
+	.set r25,25
+	.set r26,26
+	.set r27,27
+	.set r28,28
+	.set r29,29
+	.set r30,30
+	.set r31,31
+	.set f0,0
+	.set f1,1
+	.set f2,2
+	.set f3,3
+	.set f4,4
+	.set f5,5
+	.set f6,6
+	.set f7,7
+	.set f8,8
+	.set f9,9
+	.set f10,10
+	.set f11,11
+	.set f12,12
+	.set f13,13
+	.set f14,14
+	.set f15,15
+	.set f16,16
+	.set f17,17
+	.set f18,18
+	.set f19,19
+	.set f20,20
+	.set f21,21
+
+#define LIBFFI_ASM
+#define JUMPTARGET(name) name
+#define L(x) x
+	.file "aix_closure.S"
+	.toc
+LC..60:
+	.tc L..60[TC],L..60
+	.csect .text[PR]
+	.align 2
+
+.csect .text[PR]
+	.align 2
+	.globl ffi_closure_ASM
+	.globl .ffi_closure_ASM
+.csect ffi_closure_ASM[DS]
+
+ffi_closure_ASM:
+	.long .ffi_closure_ASM, TOC[tc0], 0
+	.csect .text[PR]
+.ffi_closure_ASM:
+
+	mflr r0			/* extract return address */
+	stw r0, 8(r1)		/* save the return address */
+
+	/* 24 Bytes (Linkage Area) */
+	/* 32 Bytes (params) */
+	/* 104 Bytes (13*8 from FPR) */
+	/* 8 Bytes (result) */
+	/* 168 Bytes */
+
+	stwu r1,-176(r1)	/* skip over caller save area
+				keep stack aligned to 16  */
+
+/* we want to build up an area for the parameters passed */
+/* in registers (both floating point and integer) */
+
+	/* we store gpr 3 to gpr 10 (aligned to 4)
+	in the parents outgoing area  */
+	stw   r3, 200(r1)
+	stw   r4, 204(r1)
+	stw   r5, 208(r1)
+	stw   r6, 212(r1)
+	stw   r7, 216(r1)
+	stw   r8, 220(r1)
+	stw   r9, 224(r1)
+	stw   r10, 228(r1)
+
+	/* next save fpr 1 to fpr 13 (aligned to 8) */
+	stfd  f1, 56(r1)
+	stfd  f2, 64(r1)
+	stfd  f3, 72(r1)
+	stfd  f4, 80(r1)
+	stfd  f5, 88(r1)
+	stfd  f6, 96(r1)
+	stfd  f7, 104(r1)
+	stfd  f8, 112(r1)
+	stfd  f9, 120(r1)
+	stfd  f10, 128(r1)
+	stfd  f11, 136(r1)
+	stfd  f12, 144(r1)
+	stfd  f13, 152(r1)
+
+	/* set up registers for the routine that actually does the work */
+	/* get the context pointer from the trampoline */
+	mr r3,r11
+
+	/* now load up the pointer to the result storage */
+	addi r4,r1,160
+
+	/* now load up the pointer to the saved gpr registers */
+	addi r5,r1,200
+
+	/* now load up the pointer to the saved fpr registers */
+	addi r6,r1,56
+
+	/* make the call */
+	bl .ffi_closure_helper_DARWIN
+	nop
+
+	/* now r3 contains the return type */
+	/* so use it to look up in a table */
+	/* so we know how to deal with each type */
+
+	/* look up the proper starting point in table  */
+	/* by using return type as offset */
+	addi r5,r1,160		/* get pointer to results area */
+	lwz r4,LC..60(2)	/* get address of jump table */
+	slwi r3,r3,2		/* now multiply return type by 4 */
+	lwzx r3,r4,r3		/* get the contents of that table value */
+	add r3,r3,r4		/* add contents of table to table address */
+	mtctr r3
+	bctr			/* jump to it */
+
+L..60:
+	.long L..44-L..60    /* FFI_TYPE_VOID */
+	.long L..50-L..60    /* FFI_TYPE_INT */
+	.long L..47-L..60    /* FFI_TYPE_FLOAT */
+	.long L..46-L..60    /* FFI_TYPE_DOUBLE */
+	.long L..46-L..60    /* FFI_TYPE_LONGDOUBLE */
+	.long L..56-L..60    /* FFI_TYPE_UINT8 */
+	.long L..55-L..60    /* FFI_TYPE_SINT8 */
+	.long L..58-L..60    /* FFI_TYPE_UINT16 */
+	.long L..57-L..60    /* FFI_TYPE_SINT16 */
+	.long L..50-L..60    /* FFI_TYPE_UINT32 */
+	.long L..50-L..60    /* FFI_TYPE_SINT32 */
+	.long L..48-L..60    /* FFI_TYPE_UINT64 */
+	.long L..48-L..60    /* FFI_TYPE_SINT64 */
+	.long L..44-L..60    /* FFI_TYPE_STRUCT */
+	.long L..50-L..60    /* FFI_TYPE_POINTER */
+
+
+/* case double */
+L..46:
+	lfd f1,0(r5)
+	b L..44
+
+/* case float */
+L..47:
+	lfs f1,0(r5)
+	b L..44
+
+/* case long long */
+L..48:
+	lwz r3,0(r5)
+	lwz r4,4(r5)
+	b L..44
+
+/* case default / int32 / pointer */
+L..50:
+	lwz r3,0(r5)
+	b L..44
+
+/* case signed int8	 */
+L..55:
+	addi r5,r5,3
+	lbz r3,0(r5)
+	slwi r3,r3,24
+	srawi r3,r3,24
+	b L..44
+
+/* case unsigned int8	 */
+L..56:
+	addi r5,r5,3
+	lbz r3,0(r5)
+	b L..44
+
+/* case signed int16 */
+L..57:
+	addi r5,r5,2
+	lhz r3,0(r5)
+	extsh r3,r3
+	b L..44
+
+/* case unsigned int16 */
+L..58:
+	addi r5,r5,2
+	lhz r3,0(r5)
+
+/* case void / done	 */
+L..44:
+	addi r1,r1,176		/* restore stack pointer */
+	lwz r0,8(r1)		/* get return address */
+	mtlr r0			/* reset link register */
+	blr
+
+/* END(ffi_closure_ASM) */

Added: vendor/Python/current/Modules/_ctypes/libffi/src/powerpc/asm.h
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/powerpc/asm.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/powerpc/asm.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,125 @@
+/* -----------------------------------------------------------------------
+   asm.h - Copyright (c) 1998 Geoffrey Keating
+
+   PowerPC Assembly glue.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#define ASM_GLOBAL_DIRECTIVE .globl
+
+
+#define C_SYMBOL_NAME(name) name
+/* Macro for a label.  */
+#ifdef	__STDC__
+#define C_LABEL(name)		name##:
+#else
+#define C_LABEL(name)		name/**/:
+#endif
+
+/* This seems to always be the case on PPC.  */
+#define ALIGNARG(log2) log2
+/* For ELF we need the `.type' directive to make shared libs work right.  */
+#define ASM_TYPE_DIRECTIVE(name,typearg) .type name,typearg;
+#define ASM_SIZE_DIRECTIVE(name) .size name,.-name
+
+/* If compiled for profiling, call `_mcount' at the start of each function.  */
+#ifdef	PROF
+/* The mcount code relies on a the return address being on the stack
+   to locate our caller and so it can restore it; so store one just
+   for its benefit.  */
+#ifdef PIC
+#define CALL_MCOUNT							      \
+  .pushsection;								      \
+  .section ".data";							      \
+  .align ALIGNARG(2);							      \
+0:.long 0;								      \
+  .previous;								      \
+  mflr  %r0;								      \
+  stw   %r0,4(%r1);							      \
+  bl    _GLOBAL_OFFSET_TABLE_ at local-4;					      \
+  mflr  %r11;								      \
+  lwz   %r0,0b at got(%r11);						      \
+  bl    JUMPTARGET(_mcount);
+#else  /* PIC */
+#define CALL_MCOUNT							      \
+  .section ".data";							      \
+  .align ALIGNARG(2);							      \
+0:.long 0;								      \
+  .previous;								      \
+  mflr  %r0;								      \
+  lis   %r11,0b at ha;							      \
+  stw   %r0,4(%r1);							      \
+  addi  %r0,%r11,0b at l;							      \
+  bl    JUMPTARGET(_mcount);
+#endif /* PIC */
+#else  /* PROF */
+#define CALL_MCOUNT		/* Do nothing.  */
+#endif /* PROF */
+
+#define	ENTRY(name)							      \
+  ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name);				      \
+  ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name), at function)			      \
+  .align ALIGNARG(2);							      \
+  C_LABEL(name)								      \
+  CALL_MCOUNT
+
+#define EALIGN_W_0  /* No words to insert.  */
+#define EALIGN_W_1  nop
+#define EALIGN_W_2  nop;nop
+#define EALIGN_W_3  nop;nop;nop
+#define EALIGN_W_4  EALIGN_W_3;nop
+#define EALIGN_W_5  EALIGN_W_4;nop
+#define EALIGN_W_6  EALIGN_W_5;nop
+#define EALIGN_W_7  EALIGN_W_6;nop
+
+/* EALIGN is like ENTRY, but does alignment to 'words'*4 bytes
+   past a 2^align boundary.  */
+#ifdef PROF
+#define EALIGN(name, alignt, words)					      \
+  ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name);				      \
+  ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name), at function)			      \
+  .align ALIGNARG(2);							      \
+  C_LABEL(name)								      \
+  CALL_MCOUNT								      \
+  b 0f;									      \
+  .align ALIGNARG(alignt);						      \
+  EALIGN_W_##words;							      \
+  0:
+#else /* PROF */
+#define EALIGN(name, alignt, words)					      \
+  ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name);				      \
+  ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name), at function)			      \
+  .align ALIGNARG(alignt);						      \
+  EALIGN_W_##words;							      \
+  C_LABEL(name)
+#endif
+
+#define END(name)							      \
+  ASM_SIZE_DIRECTIVE(name)
+
+#ifdef PIC
+#define JUMPTARGET(name) name##@plt
+#else
+#define JUMPTARGET(name) name
+#endif
+
+/* Local labels stripped out by the linker.  */
+#define L(x) .L##x

Added: vendor/Python/current/Modules/_ctypes/libffi/src/powerpc/darwin.S
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/powerpc/darwin.S	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/powerpc/darwin.S	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,247 @@
+#ifdef __ppc__
+/* -----------------------------------------------------------------------
+   darwin.S - Copyright (c) 2000 John Hornkvist
+	      Copyright (c) 2004 Free Software Foundation, Inc.
+
+   PowerPC Assembly glue.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#if defined(__ppc64__)
+#define MODE_CHOICE(x, y) y
+#else
+#define MODE_CHOICE(x, y) x
+#endif
+
+#define g_long  MODE_CHOICE(long, quad)         /* usage is ".g_long" */
+
+#define LOG2_GPR_BYTES  MODE_CHOICE(2,3)        /* log2(GPR_BYTES) */
+
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+#define JUMPTARGET(name) name
+#define L(x) x
+.text
+	.align 2
+.globl _ffi_prep_args
+
+.text
+	.align 2
+.globl _ffi_call_DARWIN
+.text
+	.align 2
+_ffi_call_DARWIN:
+LFB0:
+	mr   	r12,r8	/* We only need r12 until the call,
+			   so it doesn't have to be saved.  */
+LFB1:
+	/* Save the old stack pointer as AP.  */
+	mr	r8,r1
+LCFI0:
+	/* Allocate the stack space we need.  */
+	stwux	r1,r1,r4
+
+	/* Save registers we use.  */
+	mflr	r9
+
+	stw	r28,-16(r8)	
+	stw	r29,-12(r8)
+	stw	r30,-8(r8)
+	stw	r31,-4(r8)
+
+	stw	r9,8(r8)
+	stw	r2,20(r1)
+LCFI1:
+
+	/* Save arguments over call.  */
+	mr	r31,r5	/* flags,  */
+	mr	r30,r6	/* rvalue,  */
+	mr	r29,r7	/* function address,  */
+	mr	r28,r8	/* our AP.  */
+LCFI2:
+	/* Call ffi_prep_args.  */
+	mr	r4,r1
+	li	r9,0
+
+	mtctr	r12 /* r12 holds address of _ffi_prep_args.  */
+	bctrl
+	lwz     r2,20(r1)
+
+	/* Now do the call.
+	   Set up cr1 with bits 4-7 of the flags.  */
+	mtcrf	0x40,r31
+	/* Get the address to call into CTR.  */
+	mtctr	r29
+	/* Load all those argument registers.
+	   We have set up a nice stack frame, just load it into registers.  */
+	lwz     r3,20+(1*4)(r1)
+	lwz     r4,20+(2*4)(r1)
+	lwz     r5,20+(3*4)(r1)
+	lwz     r6,20+(4*4)(r1)
+	nop
+	lwz     r7,20+(5*4)(r1)
+	lwz     r8,20+(6*4)(r1)
+	lwz     r9,20+(7*4)(r1)
+	lwz     r10,20+(8*4)(r1)
+
+L1:
+	/* Load all the FP registers.  */
+	bf	6,L2	/* No floats to load.  */
+	lfd	f1,-16-(13*8)(r28)
+	lfd	f2,-16-(12*8)(r28)
+	lfd	f3,-16-(11*8)(r28)
+	lfd	f4,-16-(10*8)(r28)
+	nop
+	lfd	f5,-16-(9*8)(r28)
+	lfd	f6,-16-(8*8)(r28)
+	lfd	f7,-16-(7*8)(r28)
+	lfd	f8,-16-(6*8)(r28)
+	nop
+	lfd     f9,-16-(5*8)(r28)
+	lfd     f10,-16-(4*8)(r28)
+	lfd     f11,-16-(3*8)(r28)
+	lfd     f12,-16-(2*8)(r28)
+	nop
+	lfd     f13,-16-(1*8)(r28)
+
+L2:
+	mr	r12,r29	/* Put the target address in r12 as specified.  */
+	mtctr  	r12
+	nop
+	nop
+	/* Make the call.  */
+	bctrl
+
+	/* Now, deal with the return value.  */
+	mtcrf	0x01,r31
+
+	bt	30,L(done_return_value)
+	bt	29,L(fp_return_value)
+	stw	r3,0(r30)
+	bf	28,L(done_return_value)
+	stw	r4,4(r30)
+
+	/* Fall through.  */
+
+L(done_return_value):
+	/* Restore the registers we used and return.  */
+	lwz	r9,8(r28)
+	lwz	r31,-4(r28)
+	mtlr	r9
+	lwz	r30,-8(r28)
+	lwz	r29,-12(r28)
+	lwz	r28,-16(r28)
+	lwz	r1,0(r1)
+	blr
+
+L(fp_return_value):
+	/* Do we have long double to store?  */
+	bf	31,L(fd_return_value)
+	stfd	f1,0(r30)
+	stfd	f2,8(r30)
+	b	L(done_return_value)
+
+L(fd_return_value):
+	/* Do we have double to store?  */
+	bf	28,L(float_return_value)
+	stfd	f1,0(r30)
+	b	L(done_return_value)
+
+L(float_return_value):
+	/* We only have a float to store.  */
+	stfs	f1,0(r30)
+	b	L(done_return_value)
+
+LFE1:
+/* END(_ffi_call_DARWIN)  */
+
+/* Provide a null definition of _ffi_call_AIX.  */
+.text
+	.align 2
+.globl _ffi_call_AIX
+.text
+	.align 2
+_ffi_call_AIX:
+	blr
+/* END(_ffi_call_AIX)  */
+
+.data
+.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms
+EH_frame1:
+	.set	L$set$0,LECIE1-LSCIE1
+	.long	L$set$0	; Length of Common Information Entry
+LSCIE1:
+	.long	0x0	; CIE Identifier Tag
+	.byte	0x1	; CIE Version
+	.ascii	"zR\0"	; CIE Augmentation
+	.byte	0x1	; uleb128 0x1; CIE Code Alignment Factor
+	.byte	0x7c	; sleb128 -4; CIE Data Alignment Factor
+	.byte	0x41	; CIE RA Column
+	.byte	0x1	; uleb128 0x1; Augmentation size
+	.byte	0x90	; FDE Encoding (indirect pcrel)
+	.byte	0xc	; DW_CFA_def_cfa
+	.byte	0x1	; uleb128 0x1
+	.byte	0x0	; uleb128 0x0
+	.align	LOG2_GPR_BYTES
+LECIE1:
+.globl _ffi_call_DARWIN.eh
+_ffi_call_DARWIN.eh:
+LSFDE1:
+	.set	L$set$1,LEFDE1-LASFDE1
+	.long	L$set$1	; FDE Length
+LASFDE1:
+	.long	LASFDE1-EH_frame1 ; FDE CIE offset
+	.g_long	LLFB0$non_lazy_ptr-.	; FDE initial location
+	.set	L$set$3,LFE1-LFB0
+	.g_long	L$set$3	; FDE address range
+	.byte   0x0     ; uleb128 0x0; Augmentation size
+	.byte	0x4	; DW_CFA_advance_loc4
+	.set	L$set$4,LCFI0-LFB1
+	.long	L$set$4
+	.byte	0xd	; DW_CFA_def_cfa_register
+	.byte	0x08	; uleb128 0x08
+	.byte	0x4	; DW_CFA_advance_loc4
+	.set	L$set$5,LCFI1-LCFI0
+	.long	L$set$5
+	.byte   0x11    ; DW_CFA_offset_extended_sf
+	.byte	0x41	; uleb128 0x41
+	.byte   0x7e    ; sleb128 -2
+	.byte	0x9f	; DW_CFA_offset, column 0x1f
+	.byte	0x1	; uleb128 0x1
+	.byte	0x9e	; DW_CFA_offset, column 0x1e
+	.byte	0x2	; uleb128 0x2
+	.byte	0x9d	; DW_CFA_offset, column 0x1d
+	.byte	0x3	; uleb128 0x3
+	.byte	0x9c	; DW_CFA_offset, column 0x1c
+	.byte	0x4	; uleb128 0x4
+	.byte	0x4	; DW_CFA_advance_loc4
+	.set	L$set$6,LCFI2-LCFI1
+	.long	L$set$6
+	.byte	0xd	; DW_CFA_def_cfa_register
+	.byte	0x1c	; uleb128 0x1c
+	.align LOG2_GPR_BYTES
+LEFDE1:
+.data
+	.align LOG2_GPR_BYTES
+LLFB0$non_lazy_ptr:
+	.g_long LFB0
+#endif

Added: vendor/Python/current/Modules/_ctypes/libffi/src/powerpc/darwin_closure.S
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/powerpc/darwin_closure.S	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/powerpc/darwin_closure.S	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,319 @@
+#ifdef __ppc__
+/* -----------------------------------------------------------------------
+   darwin_closure.S - Copyright (c) 2002, 2003, 2004, Free Software Foundation,
+   Inc. based on ppc_closure.S
+
+   PowerPC Assembly glue.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#define L(x) x
+
+#if defined(__ppc64__)
+#define MODE_CHOICE(x, y) y
+#else
+#define MODE_CHOICE(x, y) x
+#endif
+
+#define lgu     MODE_CHOICE(lwzu, ldu)
+
+#define g_long  MODE_CHOICE(long, quad)         /* usage is ".g_long" */
+
+#define LOG2_GPR_BYTES  MODE_CHOICE(2,3)        /* log2(GPR_BYTES) */
+
+	.file	"darwin_closure.S"
+.text
+	.align LOG2_GPR_BYTES
+.globl _ffi_closure_ASM
+
+.text
+	.align LOG2_GPR_BYTES
+_ffi_closure_ASM:
+LFB1:
+	mflr	r0		/* extract return address  */
+	stw	r0,8(r1)	/* save the return address  */
+LCFI0:
+	/* 24 Bytes (Linkage Area)
+	   32 Bytes (outgoing parameter area, always reserved)
+	   104 Bytes (13*8 from FPR)
+	   16 Bytes (result)
+	   176 Bytes  */
+
+	stwu	r1,-176(r1)	/* skip over caller save area
+				keep stack aligned to 16.  */
+LCFI1:
+	/* We want to build up an area for the parameters passed
+	   in registers. (both floating point and integer)  */
+
+	/* We store gpr 3 to gpr 10 (aligned to 4)
+	   in the parents outgoing area.  */
+	stw   r3,200(r1)
+	stw   r4,204(r1)
+	stw   r5,208(r1)
+	stw   r6,212(r1)
+	stw   r7,216(r1)
+	stw   r8,220(r1)
+	stw   r9,224(r1)
+	stw   r10,228(r1)
+
+	/* We save fpr 1 to fpr 13. (aligned to 8)  */
+	stfd  f1,56(r1)
+	stfd  f2,64(r1)
+	stfd  f3,72(r1)
+	stfd  f4,80(r1)
+	stfd  f5,88(r1)
+	stfd  f6,96(r1)
+	stfd  f7,104(r1)
+	stfd  f8,112(r1)
+	stfd  f9,120(r1)
+	stfd  f10,128(r1)
+	stfd  f11,136(r1)
+	stfd  f12,144(r1)
+	stfd  f13,152(r1)
+
+	/* Set up registers for the routine that actually does the work
+	   get the context pointer from the trampoline.  */
+	mr r3,r11
+
+	/* Now load up the pointer to the result storage.  */
+	addi r4,r1,160
+
+	/* Now load up the pointer to the saved gpr registers.  */
+	addi r5,r1,200
+
+	/* Now load up the pointer to the saved fpr registers.  */
+	addi r6,r1,56
+
+	/* Make the call.  */
+	bl	Lffi_closure_helper_DARWIN$stub
+
+	/* Now r3 contains the return type
+	   so use it to look up in a table
+	   so we know how to deal with each type.  */
+
+	/* Look up the proper starting point in table
+	   by using return type as offset.  */
+	addi  r5,r1,160		  /* Get pointer to results area.  */
+	bl    Lget_ret_type0_addr /* Get pointer to Lret_type0 into LR.  */
+	mflr  r4		  /* Move to r4.  */
+	slwi  r3,r3,4		  /* Now multiply return type by 16.  */
+	add   r3,r3,r4		  /* Add contents of table to table address.  */
+	mtctr r3
+	bctr			  /* Jump to it.  */
+LFE1:
+/* Each of the ret_typeX code fragments has to be exactly 16 bytes long
+   (4 instructions). For cache effectiveness we align to a 16 byte boundary
+   first.  */
+
+	.align 4
+
+	nop
+	nop
+	nop
+Lget_ret_type0_addr:
+	blrl
+
+/* case FFI_TYPE_VOID  */
+Lret_type0:
+	b	Lfinish
+	nop
+	nop
+	nop
+
+/* case FFI_TYPE_INT  */
+Lret_type1:
+	lwz	r3,0(r5)
+	b	Lfinish
+	nop
+	nop
+
+/* case FFI_TYPE_FLOAT  */
+Lret_type2:
+	lfs	f1,0(r5)
+	b	Lfinish
+	nop
+	nop
+
+/* case FFI_TYPE_DOUBLE  */
+Lret_type3:
+	lfd	f1,0(r5)
+	b	Lfinish
+	nop
+	nop
+
+/* case FFI_TYPE_LONGDOUBLE  */
+Lret_type4:
+	lfd	f1,0(r5)
+	lfd	f2,8(r5)
+	b	Lfinish
+	nop
+
+/* case FFI_TYPE_UINT8  */
+Lret_type5:
+	lbz	r3,3(r5)
+	b	Lfinish
+	nop
+	nop
+
+/* case FFI_TYPE_SINT8  */
+Lret_type6:
+	lbz	r3,3(r5)
+	extsb	r3,r3
+	b	Lfinish
+	nop
+
+/* case FFI_TYPE_UINT16  */
+Lret_type7:
+	lhz	r3,2(r5)
+	b	Lfinish
+	nop
+	nop
+
+/* case FFI_TYPE_SINT16  */
+Lret_type8:
+	lha	r3,2(r5)
+	b	Lfinish
+	nop
+	nop
+
+/* case FFI_TYPE_UINT32  */
+Lret_type9:
+	lwz	r3,0(r5)
+	b	Lfinish
+	nop
+	nop
+
+/* case FFI_TYPE_SINT32  */
+Lret_type10:
+	lwz	r3,0(r5)
+	b	Lfinish
+	nop
+	nop
+
+/* case FFI_TYPE_UINT64  */
+Lret_type11:
+	lwz	r3,0(r5)
+	lwz	r4,4(r5)
+	b	Lfinish
+	nop
+
+/* case FFI_TYPE_SINT64  */
+Lret_type12:
+	lwz	r3,0(r5)
+	lwz	r4,4(r5)
+	b	Lfinish
+	nop
+
+/* case FFI_TYPE_STRUCT  */
+Lret_type13:
+	b	Lfinish
+	nop
+	nop
+	nop
+
+/* case FFI_TYPE_POINTER  */
+Lret_type14:
+	lwz	r3,0(r5)
+	b	Lfinish
+	nop
+	nop
+
+/* case done  */
+Lfinish:
+	addi	r1,r1,176	/* Restore stack pointer.  */
+	lwz	r0,8(r1)	/* Get return address.  */
+	mtlr	r0		/* Reset link register.  */
+	blr
+
+/* END(ffi_closure_ASM)  */
+
+.data
+.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms
+EH_frame1:
+	.set	L$set$0,LECIE1-LSCIE1
+	.long	L$set$0	; Length of Common Information Entry
+LSCIE1:
+	.long	0x0	; CIE Identifier Tag
+	.byte	0x1	; CIE Version
+	.ascii	"zR\0"	; CIE Augmentation
+	.byte	0x1	; uleb128 0x1; CIE Code Alignment Factor
+	.byte	0x7c	; sleb128 -4; CIE Data Alignment Factor
+	.byte	0x41	; CIE RA Column
+	.byte	0x1	; uleb128 0x1; Augmentation size
+	.byte	0x90	; FDE Encoding (indirect pcrel)
+	.byte	0xc	; DW_CFA_def_cfa
+	.byte	0x1	; uleb128 0x1
+	.byte	0x0	; uleb128 0x0
+	.align	LOG2_GPR_BYTES
+LECIE1:
+.globl _ffi_closure_ASM.eh
+_ffi_closure_ASM.eh:
+LSFDE1:
+	.set	L$set$1,LEFDE1-LASFDE1
+	.long	L$set$1	; FDE Length
+
+LASFDE1:
+	.long	LASFDE1-EH_frame1	; FDE CIE offset
+	.g_long	LLFB1$non_lazy_ptr-.	; FDE initial location
+	.set	L$set$3,LFE1-LFB1
+	.g_long	L$set$3	; FDE address range
+	.byte   0x0     ; uleb128 0x0; Augmentation size
+	.byte	0x4	; DW_CFA_advance_loc4
+	.set	L$set$3,LCFI1-LCFI0
+	.long	L$set$3
+	.byte	0xe	; DW_CFA_def_cfa_offset
+	.byte	176,1	; uleb128 176
+	.byte	0x4	; DW_CFA_advance_loc4
+	.set	L$set$4,LCFI0-LFB1
+	.long	L$set$4
+	.byte   0x11    ; DW_CFA_offset_extended_sf
+	.byte	0x41	; uleb128 0x41
+	.byte   0x7e    ; sleb128 -2
+	.align	LOG2_GPR_BYTES
+LEFDE1:
+.data
+	.align	LOG2_GPR_BYTES
+LDFCM0:
+.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
+	.align	LOG2_GPR_BYTES
+Lffi_closure_helper_DARWIN$stub:
+#if 1
+	.indirect_symbol _ffi_closure_helper_DARWIN
+	mflr	r0
+	bcl	20,31,LO$ffi_closure_helper_DARWIN
+LO$ffi_closure_helper_DARWIN:
+	mflr	r11
+	addis	r11,r11,ha16(L_ffi_closure_helper_DARWIN$lazy_ptr - LO$ffi_closure_helper_DARWIN)
+	mtlr	r0
+	lgu	r12,lo16(L_ffi_closure_helper_DARWIN$lazy_ptr - LO$ffi_closure_helper_DARWIN)(r11)
+	mtctr	r12
+	bctr
+.lazy_symbol_pointer
+L_ffi_closure_helper_DARWIN$lazy_ptr:
+	.indirect_symbol _ffi_closure_helper_DARWIN
+	.g_long dyld_stub_binding_helper
+#endif
+.data
+	.align LOG2_GPR_BYTES
+LLFB1$non_lazy_ptr:
+	.g_long LFB1
+#endif

Added: vendor/Python/current/Modules/_ctypes/libffi/src/powerpc/ffi.c
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/powerpc/ffi.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/powerpc/ffi.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1249 @@
+/* -----------------------------------------------------------------------
+   ffi.c - Copyright (c) 1998 Geoffrey Keating
+
+   PowerPC Foreign Function Interface
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+
+
+extern void ffi_closure_SYSV (void);
+extern void FFI_HIDDEN ffi_closure_LINUX64 (void);
+
+enum {
+  /* The assembly depends on these exact flags.  */
+  FLAG_RETURNS_SMST	= 1 << (31-31), /* Used for FFI_SYSV small structs.  */
+  FLAG_RETURNS_NOTHING  = 1 << (31-30), /* These go in cr7 */
+  FLAG_RETURNS_FP       = 1 << (31-29),
+  FLAG_RETURNS_64BITS   = 1 << (31-28),
+  FLAG_RETURNS_128BITS  = 1 << (31-27),
+
+  FLAG_ARG_NEEDS_COPY   = 1 << (31- 7),
+  FLAG_FP_ARGUMENTS     = 1 << (31- 6), /* cr1.eq; specified by ABI */
+  FLAG_4_GPR_ARGUMENTS  = 1 << (31- 5),
+  FLAG_RETVAL_REFERENCE = 1 << (31- 4)
+};
+
+/* About the SYSV ABI.  */
+enum {
+  NUM_GPR_ARG_REGISTERS = 8,
+  NUM_FPR_ARG_REGISTERS = 8
+};
+enum { ASM_NEEDS_REGISTERS = 4 };
+
+/* ffi_prep_args_SYSV is called by the assembly routine once stack space
+   has been allocated for the function's arguments.
+
+   The stack layout we want looks like this:
+
+   |   Return address from ffi_call_SYSV 4bytes	|	higher addresses
+   |--------------------------------------------|
+   |   Previous backchain pointer	4	|       stack pointer here
+   |--------------------------------------------|<+ <<<	on entry to
+   |   Saved r28-r31			4*4	| |	ffi_call_SYSV
+   |--------------------------------------------| |
+   |   GPR registers r3-r10		8*4	| |	ffi_call_SYSV
+   |--------------------------------------------| |
+   |   FPR registers f1-f8 (optional)	8*8	| |
+   |--------------------------------------------| |	stack	|
+   |   Space for copied structures		| |	grows	|
+   |--------------------------------------------| |	down    V
+   |   Parameters that didn't fit in registers  | |
+   |--------------------------------------------| |	lower addresses
+   |   Space for callee's LR		4	| |
+   |--------------------------------------------| |	stack pointer here
+   |   Current backchain pointer	4	|-/	during
+   |--------------------------------------------|   <<<	ffi_call_SYSV
+
+*/
+
+/*@-exportheader@*/
+void
+ffi_prep_args_SYSV (extended_cif *ecif, unsigned *const stack)
+/*@=exportheader@*/
+{
+  const unsigned bytes = ecif->cif->bytes;
+  const unsigned flags = ecif->cif->flags;
+
+  typedef union {
+    char *c;
+    unsigned *u;
+    long long *ll;
+    float *f;
+    double *d;
+  } valp;
+
+  /* 'stacktop' points at the previous backchain pointer.  */
+  valp stacktop;
+
+  /* 'gpr_base' points at the space for gpr3, and grows upwards as
+     we use GPR registers.  */
+  valp gpr_base;
+  int intarg_count;
+
+  /* 'fpr_base' points at the space for fpr1, and grows upwards as
+     we use FPR registers.  */
+  valp fpr_base;
+  int fparg_count;
+
+  /* 'copy_space' grows down as we put structures in it.  It should
+     stay 16-byte aligned.  */
+  valp copy_space;
+
+  /* 'next_arg' grows up as we put parameters in it.  */
+  valp next_arg;
+
+  int i;
+  ffi_type **ptr;
+  double double_tmp;
+  union {
+    void **v;
+    char **c;
+    signed char **sc;
+    unsigned char **uc;
+    signed short **ss;
+    unsigned short **us;
+    unsigned int **ui;
+    long long **ll;
+    float **f;
+    double **d;
+  } p_argv;
+  size_t struct_copy_size;
+  unsigned gprvalue;
+
+  stacktop.c = (char *) stack + bytes;
+  gpr_base.u = stacktop.u - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS;
+  intarg_count = 0;
+  fpr_base.d = gpr_base.d - NUM_FPR_ARG_REGISTERS;
+  fparg_count = 0;
+  copy_space.c = ((flags & FLAG_FP_ARGUMENTS) ? fpr_base.c : gpr_base.c);
+  next_arg.u = stack + 2;
+
+  /* Check that everything starts aligned properly.  */
+  FFI_ASSERT (((unsigned) (char *) stack & 0xF) == 0);
+  FFI_ASSERT (((unsigned) copy_space.c & 0xF) == 0);
+  FFI_ASSERT (((unsigned) stacktop.c & 0xF) == 0);
+  FFI_ASSERT ((bytes & 0xF) == 0);
+  FFI_ASSERT (copy_space.c >= next_arg.c);
+
+  /* Deal with return values that are actually pass-by-reference.  */
+  if (flags & FLAG_RETVAL_REFERENCE)
+    {
+      *gpr_base.u++ = (unsigned long) (char *) ecif->rvalue;
+      intarg_count++;
+    }
+
+  /* Now for the arguments.  */
+  p_argv.v = ecif->avalue;
+  for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
+       i > 0;
+       i--, ptr++, p_argv.v++)
+    {
+      switch ((*ptr)->type)
+	{
+	case FFI_TYPE_FLOAT:
+	  double_tmp = **p_argv.f;
+	  if (fparg_count >= NUM_FPR_ARG_REGISTERS)
+	    {
+	      *next_arg.f = (float) double_tmp;
+	      next_arg.u += 1;
+	    }
+	  else
+	    *fpr_base.d++ = double_tmp;
+	  fparg_count++;
+	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
+	  break;
+
+	case FFI_TYPE_DOUBLE:
+	  double_tmp = **p_argv.d;
+
+	  if (fparg_count >= NUM_FPR_ARG_REGISTERS)
+	    {
+	      if (intarg_count >= NUM_GPR_ARG_REGISTERS
+		  && intarg_count % 2 != 0)
+		{
+		  intarg_count++;
+		  next_arg.u++;
+		}
+	      *next_arg.d = double_tmp;
+	      next_arg.u += 2;
+	    }
+	  else
+	    *fpr_base.d++ = double_tmp;
+	  fparg_count++;
+	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
+	  break;
+
+	case FFI_TYPE_UINT64:
+	case FFI_TYPE_SINT64:
+	  if (intarg_count == NUM_GPR_ARG_REGISTERS-1)
+	    intarg_count++;
+	  if (intarg_count >= NUM_GPR_ARG_REGISTERS)
+	    {
+	      if (intarg_count % 2 != 0)
+		{
+		  intarg_count++;
+		  next_arg.u++;
+		}
+	      *next_arg.ll = **p_argv.ll;
+	      next_arg.u += 2;
+	    }
+	  else
+	    {
+	      /* whoops: abi states only certain register pairs
+	       * can be used for passing long long int
+	       * specifically (r3,r4), (r5,r6), (r7,r8),
+	       * (r9,r10) and if next arg is long long but
+	       * not correct starting register of pair then skip
+	       * until the proper starting register
+	       */
+	      if (intarg_count % 2 != 0)
+		{
+		  intarg_count ++;
+		  gpr_base.u++;
+		}
+	      *gpr_base.ll++ = **p_argv.ll;
+	    }
+	  intarg_count += 2;
+	  break;
+
+	case FFI_TYPE_STRUCT:
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+	case FFI_TYPE_LONGDOUBLE:
+#endif
+	  struct_copy_size = ((*ptr)->size + 15) & ~0xF;
+	  copy_space.c -= struct_copy_size;
+	  memcpy (copy_space.c, *p_argv.c, (*ptr)->size);
+
+	  gprvalue = (unsigned long) copy_space.c;
+
+	  FFI_ASSERT (copy_space.c > next_arg.c);
+	  FFI_ASSERT (flags & FLAG_ARG_NEEDS_COPY);
+	  goto putgpr;
+
+	case FFI_TYPE_UINT8:
+	  gprvalue = **p_argv.uc;
+	  goto putgpr;
+	case FFI_TYPE_SINT8:
+	  gprvalue = **p_argv.sc;
+	  goto putgpr;
+	case FFI_TYPE_UINT16:
+	  gprvalue = **p_argv.us;
+	  goto putgpr;
+	case FFI_TYPE_SINT16:
+	  gprvalue = **p_argv.ss;
+	  goto putgpr;
+
+	case FFI_TYPE_INT:
+	case FFI_TYPE_UINT32:
+	case FFI_TYPE_SINT32:
+	case FFI_TYPE_POINTER:
+	  gprvalue = **p_argv.ui;
+
+	putgpr:
+	  if (intarg_count >= NUM_GPR_ARG_REGISTERS)
+	    *next_arg.u++ = gprvalue;
+	  else
+	    *gpr_base.u++ = gprvalue;
+	  intarg_count++;
+	  break;
+	}
+    }
+
+  /* Check that we didn't overrun the stack...  */
+  FFI_ASSERT (copy_space.c >= next_arg.c);
+  FFI_ASSERT (gpr_base.u <= stacktop.u - ASM_NEEDS_REGISTERS);
+  FFI_ASSERT (fpr_base.u
+	      <= stacktop.u - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS);
+  FFI_ASSERT (flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4);
+}
+
+/* About the LINUX64 ABI.  */
+enum {
+  NUM_GPR_ARG_REGISTERS64 = 8,
+  NUM_FPR_ARG_REGISTERS64 = 13
+};
+enum { ASM_NEEDS_REGISTERS64 = 4 };
+
+/* ffi_prep_args64 is called by the assembly routine once stack space
+   has been allocated for the function's arguments.
+
+   The stack layout we want looks like this:
+
+   |   Ret addr from ffi_call_LINUX64	8bytes	|	higher addresses
+   |--------------------------------------------|
+   |   CR save area			8bytes	|
+   |--------------------------------------------|
+   |   Previous backchain pointer	8	|	stack pointer here
+   |--------------------------------------------|<+ <<<	on entry to
+   |   Saved r28-r31			4*8	| |	ffi_call_LINUX64
+   |--------------------------------------------| |
+   |   GPR registers r3-r10		8*8	| |
+   |--------------------------------------------| |
+   |   FPR registers f1-f13 (optional)	13*8	| |
+   |--------------------------------------------| |
+   |   Parameter save area		        | |
+   |--------------------------------------------| |
+   |   TOC save area			8	| |
+   |--------------------------------------------| |	stack	|
+   |   Linker doubleword		8	| |	grows	|
+   |--------------------------------------------| |	down	V
+   |   Compiler doubleword		8	| |
+   |--------------------------------------------| |	lower addresses
+   |   Space for callee's LR		8	| |
+   |--------------------------------------------| |
+   |   CR save area			8	| |
+   |--------------------------------------------| |	stack pointer here
+   |   Current backchain pointer	8	|-/	during
+   |--------------------------------------------|   <<<	ffi_call_LINUX64
+
+*/
+
+/*@-exportheader@*/
+void FFI_HIDDEN
+ffi_prep_args64 (extended_cif *ecif, unsigned long *const stack)
+/*@=exportheader@*/
+{
+  const unsigned long bytes = ecif->cif->bytes;
+  const unsigned long flags = ecif->cif->flags;
+
+  typedef union {
+    char *c;
+    unsigned long *ul;
+    float *f;
+    double *d;
+  } valp;
+
+  /* 'stacktop' points at the previous backchain pointer.  */
+  valp stacktop;
+
+  /* 'next_arg' points at the space for gpr3, and grows upwards as
+     we use GPR registers, then continues at rest.  */
+  valp gpr_base;
+  valp gpr_end;
+  valp rest;
+  valp next_arg;
+
+  /* 'fpr_base' points at the space for fpr3, and grows upwards as
+     we use FPR registers.  */
+  valp fpr_base;
+  int fparg_count;
+
+  int i, words;
+  ffi_type **ptr;
+  double double_tmp;
+  union {
+    void **v;
+    char **c;
+    signed char **sc;
+    unsigned char **uc;
+    signed short **ss;
+    unsigned short **us;
+    signed int **si;
+    unsigned int **ui;
+    unsigned long **ul;
+    float **f;
+    double **d;
+  } p_argv;
+  unsigned long gprvalue;
+
+  stacktop.c = (char *) stack + bytes;
+  gpr_base.ul = stacktop.ul - ASM_NEEDS_REGISTERS64 - NUM_GPR_ARG_REGISTERS64;
+  gpr_end.ul = gpr_base.ul + NUM_GPR_ARG_REGISTERS64;
+  rest.ul = stack + 6 + NUM_GPR_ARG_REGISTERS64;
+  fpr_base.d = gpr_base.d - NUM_FPR_ARG_REGISTERS64;
+  fparg_count = 0;
+  next_arg.ul = gpr_base.ul;
+
+  /* Check that everything starts aligned properly.  */
+  FFI_ASSERT (((unsigned long) (char *) stack & 0xF) == 0);
+  FFI_ASSERT (((unsigned long) stacktop.c & 0xF) == 0);
+  FFI_ASSERT ((bytes & 0xF) == 0);
+
+  /* Deal with return values that are actually pass-by-reference.  */
+  if (flags & FLAG_RETVAL_REFERENCE)
+    *next_arg.ul++ = (unsigned long) (char *) ecif->rvalue;
+
+  /* Now for the arguments.  */
+  p_argv.v = ecif->avalue;
+  for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
+       i > 0;
+       i--, ptr++, p_argv.v++)
+    {
+      switch ((*ptr)->type)
+	{
+	case FFI_TYPE_FLOAT:
+	  double_tmp = **p_argv.f;
+	  *next_arg.f = (float) double_tmp;
+	  if (++next_arg.ul == gpr_end.ul)
+	    next_arg.ul = rest.ul;
+	  if (fparg_count < NUM_FPR_ARG_REGISTERS64)
+	    *fpr_base.d++ = double_tmp;
+	  fparg_count++;
+	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
+	  break;
+
+	case FFI_TYPE_DOUBLE:
+	  double_tmp = **p_argv.d;
+	  *next_arg.d = double_tmp;
+	  if (++next_arg.ul == gpr_end.ul)
+	    next_arg.ul = rest.ul;
+	  if (fparg_count < NUM_FPR_ARG_REGISTERS64)
+	    *fpr_base.d++ = double_tmp;
+	  fparg_count++;
+	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
+	  break;
+
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+	case FFI_TYPE_LONGDOUBLE:
+	  double_tmp = (*p_argv.d)[0];
+	  *next_arg.d = double_tmp;
+	  if (++next_arg.ul == gpr_end.ul)
+	    next_arg.ul = rest.ul;
+	  if (fparg_count < NUM_FPR_ARG_REGISTERS64)
+	    *fpr_base.d++ = double_tmp;
+	  fparg_count++;
+	  double_tmp = (*p_argv.d)[1];
+	  *next_arg.d = double_tmp;
+	  if (++next_arg.ul == gpr_end.ul)
+	    next_arg.ul = rest.ul;
+	  if (fparg_count < NUM_FPR_ARG_REGISTERS64)
+	    *fpr_base.d++ = double_tmp;
+	  fparg_count++;
+	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
+	  break;
+#endif
+
+	case FFI_TYPE_STRUCT:
+	  words = ((*ptr)->size + 7) / 8;
+	  if (next_arg.ul >= gpr_base.ul && next_arg.ul + words > gpr_end.ul)
+	    {
+	      size_t first = gpr_end.c - next_arg.c;
+	      memcpy (next_arg.c, *p_argv.c, first);
+	      memcpy (rest.c, *p_argv.c + first, (*ptr)->size - first);
+	      next_arg.c = rest.c + words * 8 - first;
+	    }
+	  else
+	    {
+	      char *where = next_arg.c;
+
+	      /* Structures with size less than eight bytes are passed
+		 left-padded.  */
+	      if ((*ptr)->size < 8)
+		where += 8 - (*ptr)->size;
+
+	      memcpy (where, *p_argv.c, (*ptr)->size);
+	      next_arg.ul += words;
+	      if (next_arg.ul == gpr_end.ul)
+		next_arg.ul = rest.ul;
+	    }
+	  break;
+
+	case FFI_TYPE_UINT8:
+	  gprvalue = **p_argv.uc;
+	  goto putgpr;
+	case FFI_TYPE_SINT8:
+	  gprvalue = **p_argv.sc;
+	  goto putgpr;
+	case FFI_TYPE_UINT16:
+	  gprvalue = **p_argv.us;
+	  goto putgpr;
+	case FFI_TYPE_SINT16:
+	  gprvalue = **p_argv.ss;
+	  goto putgpr;
+	case FFI_TYPE_UINT32:
+	  gprvalue = **p_argv.ui;
+	  goto putgpr;
+	case FFI_TYPE_INT:
+	case FFI_TYPE_SINT32:
+	  gprvalue = **p_argv.si;
+	  goto putgpr;
+
+	case FFI_TYPE_UINT64:
+	case FFI_TYPE_SINT64:
+	case FFI_TYPE_POINTER:
+	  gprvalue = **p_argv.ul;
+	putgpr:
+	  *next_arg.ul++ = gprvalue;
+	  if (next_arg.ul == gpr_end.ul)
+	    next_arg.ul = rest.ul;
+	  break;
+	}
+    }
+
+  FFI_ASSERT (flags & FLAG_4_GPR_ARGUMENTS
+	      || (next_arg.ul >= gpr_base.ul
+		  && next_arg.ul <= gpr_base.ul + 4));
+}
+
+
+
+/* Perform machine dependent cif processing */
+ffi_status
+ffi_prep_cif_machdep (ffi_cif *cif)
+{
+  /* All this is for the SYSV and LINUX64 ABI.  */
+  int i;
+  ffi_type **ptr;
+  unsigned bytes;
+  int fparg_count = 0, intarg_count = 0;
+  unsigned flags = 0;
+  unsigned struct_copy_size = 0;
+  unsigned type = cif->rtype->type;
+  unsigned size = cif->rtype->size;
+
+  if (cif->abi != FFI_LINUX64)
+    {
+      /* All the machine-independent calculation of cif->bytes will be wrong.
+	 Redo the calculation for SYSV.  */
+
+      /* Space for the frame pointer, callee's LR, and the asm's temp regs.  */
+      bytes = (2 + ASM_NEEDS_REGISTERS) * sizeof (int);
+
+      /* Space for the GPR registers.  */
+      bytes += NUM_GPR_ARG_REGISTERS * sizeof (int);
+    }
+  else
+    {
+      /* 64-bit ABI.  */
+
+      /* Space for backchain, CR, LR, cc/ld doubleword, TOC and the asm's temp
+	 regs.  */
+      bytes = (6 + ASM_NEEDS_REGISTERS64) * sizeof (long);
+
+      /* Space for the mandatory parm save area and general registers.  */
+      bytes += 2 * NUM_GPR_ARG_REGISTERS64 * sizeof (long);
+
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+      if (type == FFI_TYPE_LONGDOUBLE)
+	type = FFI_TYPE_DOUBLE;
+#endif
+    }
+
+  /* Return value handling.  The rules for SYSV are as follows:
+     - 32-bit (or less) integer values are returned in gpr3;
+     - Structures of size <= 4 bytes also returned in gpr3;
+     - 64-bit integer values and structures between 5 and 8 bytes are returned
+     in gpr3 and gpr4;
+     - Single/double FP values are returned in fpr1;
+     - Larger structures and long double (if not equivalent to double) values
+     are allocated space and a pointer is passed as the first argument.
+     For LINUX64:
+     - integer values in gpr3;
+     - Structures/Unions by reference;
+     - Single/double FP values in fpr1, long double in fpr1,fpr2.  */
+  switch (type)
+    {
+    case FFI_TYPE_DOUBLE:
+      flags |= FLAG_RETURNS_64BITS;
+      /* Fall through.  */
+    case FFI_TYPE_FLOAT:
+      flags |= FLAG_RETURNS_FP;
+      break;
+
+    case FFI_TYPE_UINT64:
+    case FFI_TYPE_SINT64:
+      flags |= FLAG_RETURNS_64BITS;
+      break;
+
+    case FFI_TYPE_STRUCT:
+      if (cif->abi == FFI_SYSV)
+	{
+	  /* The final SYSV ABI says that structures smaller or equal 8 bytes
+	     are returned in r3/r4. The FFI_GCC_SYSV ABI instead returns them
+	     in memory.  */
+
+	  /* Treat structs with size <= 8 bytes.  */
+	  if (size <= 8)
+	    {
+	      flags |= FLAG_RETURNS_SMST;
+	      /* These structs are returned in r3. We pack the type and the
+		 precalculated shift value (needed in the sysv.S) into flags.
+		 The same applies for the structs returned in r3/r4.  */
+	      if (size <= 4)
+		{
+		  flags |= 1 << (31 - FFI_SYSV_TYPE_SMALL_STRUCT - 1);
+		  flags |= 8 * (4 - size) << 4;
+		  break;
+		}
+	      /* These structs are returned in r3 and r4. See above.   */
+	      if  (size <= 8)
+		{
+		  flags |= 1 << (31 - FFI_SYSV_TYPE_SMALL_STRUCT - 2);
+		  flags |= 8 * (8 - size) << 4;
+		  break;
+		}
+	    }
+	}
+      /* else fall through.  */
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+    case FFI_TYPE_LONGDOUBLE:
+      if (type == FFI_TYPE_LONGDOUBLE && cif->abi == FFI_LINUX64)
+	{
+	  flags |= FLAG_RETURNS_128BITS;
+	  flags |= FLAG_RETURNS_FP;
+	  break;
+	}
+#endif
+      intarg_count++;
+      flags |= FLAG_RETVAL_REFERENCE;
+      /* Fall through.  */
+    case FFI_TYPE_VOID:
+      flags |= FLAG_RETURNS_NOTHING;
+      break;
+
+    default:
+      /* Returns 32-bit integer, or similar.  Nothing to do here.  */
+      break;
+    }
+
+  if (cif->abi != FFI_LINUX64)
+    /* The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the
+       first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest
+       goes on the stack.  Structures and long doubles (if not equivalent
+       to double) are passed as a pointer to a copy of the structure.
+       Stuff on the stack needs to keep proper alignment.  */
+    for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
+      {
+	switch ((*ptr)->type)
+	  {
+	  case FFI_TYPE_FLOAT:
+	    fparg_count++;
+	    /* floating singles are not 8-aligned on stack */
+	    break;
+
+	  case FFI_TYPE_DOUBLE:
+	    fparg_count++;
+	    /* If this FP arg is going on the stack, it must be
+	       8-byte-aligned.  */
+	    if (fparg_count > NUM_FPR_ARG_REGISTERS
+		&& intarg_count >= NUM_GPR_ARG_REGISTERS
+		&& intarg_count % 2 != 0)
+	      intarg_count++;
+	    break;
+
+	  case FFI_TYPE_UINT64:
+	  case FFI_TYPE_SINT64:
+	    /* 'long long' arguments are passed as two words, but
+	       either both words must fit in registers or both go
+	       on the stack.  If they go on the stack, they must
+	       be 8-byte-aligned.
+
+	       Also, only certain register pairs can be used for
+	       passing long long int -- specifically (r3,r4), (r5,r6),
+	       (r7,r8), (r9,r10).
+	    */
+	    if (intarg_count == NUM_GPR_ARG_REGISTERS-1
+		|| intarg_count % 2 != 0)
+	      intarg_count++;
+	    intarg_count += 2;
+	    break;
+
+	  case FFI_TYPE_STRUCT:
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+	  case FFI_TYPE_LONGDOUBLE:
+#endif
+	    /* We must allocate space for a copy of these to enforce
+	       pass-by-value.  Pad the space up to a multiple of 16
+	       bytes (the maximum alignment required for anything under
+	       the SYSV ABI).  */
+	    struct_copy_size += ((*ptr)->size + 15) & ~0xF;
+	    /* Fall through (allocate space for the pointer).  */
+
+	  default:
+	    /* Everything else is passed as a 4-byte word in a GPR, either
+	       the object itself or a pointer to it.  */
+	    intarg_count++;
+	    break;
+	  }
+      }
+  else
+    for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
+      {
+	switch ((*ptr)->type)
+	  {
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+	  case FFI_TYPE_LONGDOUBLE:
+	    fparg_count += 2;
+	    intarg_count += 2;
+	    break;
+#endif
+	  case FFI_TYPE_FLOAT:
+	  case FFI_TYPE_DOUBLE:
+	    fparg_count++;
+	    intarg_count++;
+	    break;
+
+	  case FFI_TYPE_STRUCT:
+	    intarg_count += ((*ptr)->size + 7) / 8;
+	    break;
+
+	  default:
+	    /* Everything else is passed as a 8-byte word in a GPR, either
+	       the object itself or a pointer to it.  */
+	    intarg_count++;
+	    break;
+	  }
+      }
+
+  if (fparg_count != 0)
+    flags |= FLAG_FP_ARGUMENTS;
+  if (intarg_count > 4)
+    flags |= FLAG_4_GPR_ARGUMENTS;
+  if (struct_copy_size != 0)
+    flags |= FLAG_ARG_NEEDS_COPY;
+
+  if (cif->abi != FFI_LINUX64)
+    {
+      /* Space for the FPR registers, if needed.  */
+      if (fparg_count != 0)
+	bytes += NUM_FPR_ARG_REGISTERS * sizeof (double);
+
+      /* Stack space.  */
+      if (intarg_count > NUM_GPR_ARG_REGISTERS)
+	bytes += (intarg_count - NUM_GPR_ARG_REGISTERS) * sizeof (int);
+      if (fparg_count > NUM_FPR_ARG_REGISTERS)
+	bytes += (fparg_count - NUM_FPR_ARG_REGISTERS) * sizeof (double);
+    }
+  else
+    {
+      /* Space for the FPR registers, if needed.  */
+      if (fparg_count != 0)
+	bytes += NUM_FPR_ARG_REGISTERS64 * sizeof (double);
+
+      /* Stack space.  */
+      if (intarg_count > NUM_GPR_ARG_REGISTERS64)
+	bytes += (intarg_count - NUM_GPR_ARG_REGISTERS64) * sizeof (long);
+    }
+
+  /* The stack space allocated needs to be a multiple of 16 bytes.  */
+  bytes = (bytes + 15) & ~0xF;
+
+  /* Add in the space for the copied structures.  */
+  bytes += struct_copy_size;
+
+  cif->flags = flags;
+  cif->bytes = bytes;
+
+  return FFI_OK;
+}
+
+/*@-declundef@*/
+/*@-exportheader@*/
+extern void ffi_call_SYSV(/*@out@*/ extended_cif *,
+			  unsigned, unsigned,
+			  /*@out@*/ unsigned *,
+			  void (*fn)());
+extern void FFI_HIDDEN ffi_call_LINUX64(/*@out@*/ extended_cif *,
+					unsigned long, unsigned long,
+					/*@out@*/ unsigned long *,
+					void (*fn)());
+/*@=declundef@*/
+/*@=exportheader@*/
+
+void
+ffi_call(/*@dependent@*/ ffi_cif *cif,
+	 void (*fn)(),
+	 /*@out@*/ void *rvalue,
+	 /*@dependent@*/ void **avalue)
+{
+  extended_cif ecif;
+
+  ecif.cif = cif;
+  ecif.avalue = avalue;
+
+  /* If the return value is a struct and we don't have a return	*/
+  /* value address then we need to make one		        */
+
+  if ((rvalue == NULL) && (cif->rtype->type == FFI_TYPE_STRUCT))
+    {
+      /*@-sysunrecog@*/
+      ecif.rvalue = alloca(cif->rtype->size);
+      /*@=sysunrecog@*/
+    }
+  else
+    ecif.rvalue = rvalue;
+
+
+  switch (cif->abi)
+    {
+#ifndef POWERPC64
+    case FFI_SYSV:
+    case FFI_GCC_SYSV:
+      /*@-usedef@*/
+      ffi_call_SYSV (&ecif, -cif->bytes, cif->flags, ecif.rvalue, fn);
+      /*@=usedef@*/
+      break;
+#else
+    case FFI_LINUX64:
+      /*@-usedef@*/
+      ffi_call_LINUX64 (&ecif, -(long) cif->bytes, cif->flags, ecif.rvalue, fn);
+      /*@=usedef@*/
+      break;
+#endif
+    default:
+      FFI_ASSERT (0);
+      break;
+    }
+}
+
+
+#ifndef POWERPC64
+#define MIN_CACHE_LINE_SIZE 8
+
+static void
+flush_icache (char *addr1, int size)
+{
+  int i;
+  char * addr;
+  for (i = 0; i < size; i += MIN_CACHE_LINE_SIZE)
+    {
+      addr = addr1 + i;
+      __asm__ volatile ("icbi 0,%0;" "dcbf 0,%0;"
+			: : "r" (addr) : "memory");
+    }
+  addr = addr1 + size - 1;
+  __asm__ volatile ("icbi 0,%0;" "dcbf 0,%0;" "sync;" "isync;"
+		    : : "r"(addr) : "memory");
+}
+#endif
+
+ffi_status
+ffi_prep_closure (ffi_closure *closure,
+		  ffi_cif *cif,
+		  void (*fun) (ffi_cif *, void *, void **, void *),
+		  void *user_data)
+{
+#ifdef POWERPC64
+  void **tramp = (void **) &closure->tramp[0];
+
+  FFI_ASSERT (cif->abi == FFI_LINUX64);
+  /* Copy function address and TOC from ffi_closure_LINUX64.  */
+  memcpy (tramp, (char *) ffi_closure_LINUX64, 16);
+  tramp[2] = (void *) closure;
+#else
+  unsigned int *tramp;
+
+  FFI_ASSERT (cif->abi == FFI_GCC_SYSV || cif->abi == FFI_SYSV);
+
+  tramp = (unsigned int *) &closure->tramp[0];
+  tramp[0] = 0x7c0802a6;  /*   mflr    r0 */
+  tramp[1] = 0x4800000d;  /*   bl      10 <trampoline_initial+0x10> */
+  tramp[4] = 0x7d6802a6;  /*   mflr    r11 */
+  tramp[5] = 0x7c0803a6;  /*   mtlr    r0 */
+  tramp[6] = 0x800b0000;  /*   lwz     r0,0(r11) */
+  tramp[7] = 0x816b0004;  /*   lwz     r11,4(r11) */
+  tramp[8] = 0x7c0903a6;  /*   mtctr   r0 */
+  tramp[9] = 0x4e800420;  /*   bctr */
+  *(void **) &tramp[2] = (void *) ffi_closure_SYSV; /* function */
+  *(void **) &tramp[3] = (void *) closure;          /* context */
+
+  /* Flush the icache.  */
+  flush_icache (&closure->tramp[0],FFI_TRAMPOLINE_SIZE);
+#endif
+
+  closure->cif = cif;
+  closure->fun = fun;
+  closure->user_data = user_data;
+
+  return FFI_OK;
+}
+
+typedef union
+{
+  float f;
+  double d;
+} ffi_dblfl;
+
+int ffi_closure_helper_SYSV (ffi_closure *, void *, unsigned long *,
+			     ffi_dblfl *, unsigned long *);
+
+/* Basically the trampoline invokes ffi_closure_SYSV, and on
+ * entry, r11 holds the address of the closure.
+ * After storing the registers that could possibly contain
+ * parameters to be passed into the stack frame and setting
+ * up space for a return value, ffi_closure_SYSV invokes the
+ * following helper function to do most of the work
+ */
+
+int
+ffi_closure_helper_SYSV (ffi_closure *closure, void *rvalue,
+			 unsigned long *pgr, ffi_dblfl *pfr,
+			 unsigned long *pst)
+{
+  /* rvalue is the pointer to space for return value in closure assembly */
+  /* pgr is the pointer to where r3-r10 are stored in ffi_closure_SYSV */
+  /* pfr is the pointer to where f1-f8 are stored in ffi_closure_SYSV  */
+  /* pst is the pointer to outgoing parameter stack in original caller */
+
+  void **          avalue;
+  ffi_type **      arg_types;
+  long             i, avn;
+  long             nf;   /* number of floating registers already used */
+  long             ng;   /* number of general registers already used */
+  ffi_cif *        cif;
+  double           temp;
+  unsigned         size;
+
+  cif = closure->cif;
+  avalue = alloca (cif->nargs * sizeof (void *));
+  size = cif->rtype->size;
+
+  nf = 0;
+  ng = 0;
+
+  /* Copy the caller's structure return value address so that the closure
+     returns the data directly to the caller.
+     For FFI_SYSV the result is passed in r3/r4 if the struct size is less
+     or equal 8 bytes.  */
+
+  if (cif->rtype->type == FFI_TYPE_STRUCT)
+    {
+      if (!((cif->abi == FFI_SYSV) && (size <= 8)))
+	{
+	  rvalue = (void *) *pgr;
+	  ng++;
+	  pgr++;
+	}
+    }
+
+  i = 0;
+  avn = cif->nargs;
+  arg_types = cif->arg_types;
+
+  /* Grab the addresses of the arguments from the stack frame.  */
+  while (i < avn)
+    {
+      switch (arg_types[i]->type)
+	{
+	case FFI_TYPE_SINT8:
+	case FFI_TYPE_UINT8:
+	  /* there are 8 gpr registers used to pass values */
+	  if (ng < 8)
+	    {
+	      avalue[i] = (char *) pgr + 3;
+	      ng++;
+	      pgr++;
+	    }
+	  else
+	    {
+	      avalue[i] = (char *) pst + 3;
+	      pst++;
+	    }
+	  break;
+
+	case FFI_TYPE_SINT16:
+	case FFI_TYPE_UINT16:
+	  /* there are 8 gpr registers used to pass values */
+	  if (ng < 8)
+	    {
+	      avalue[i] = (char *) pgr + 2;
+	      ng++;
+	      pgr++;
+	    }
+	  else
+	    {
+	      avalue[i] = (char *) pst + 2;
+	      pst++;
+	    }
+	  break;
+
+	case FFI_TYPE_SINT32:
+	case FFI_TYPE_UINT32:
+	case FFI_TYPE_POINTER:
+	  /* there are 8 gpr registers used to pass values */
+	  if (ng < 8)
+	    {
+	      avalue[i] = pgr;
+	      ng++;
+	      pgr++;
+	    }
+	  else
+	    {
+	      avalue[i] = pst;
+	      pst++;
+	    }
+	  break;
+
+	case FFI_TYPE_STRUCT:
+	  /* Structs are passed by reference. The address will appear in a
+	     gpr if it is one of the first 8 arguments.  */
+	  if (ng < 8)
+	    {
+	      avalue[i] = (void *) *pgr;
+	      ng++;
+	      pgr++;
+	    }
+	  else
+	    {
+	      avalue[i] = (void *) *pst;
+	      pst++;
+	    }
+	  break;
+
+	case FFI_TYPE_SINT64:
+	case FFI_TYPE_UINT64:
+	  /* passing long long ints are complex, they must
+	   * be passed in suitable register pairs such as
+	   * (r3,r4) or (r5,r6) or (r6,r7), or (r7,r8) or (r9,r10)
+	   * and if the entire pair aren't available then the outgoing
+	   * parameter stack is used for both but an alignment of 8
+	   * must will be kept.  So we must either look in pgr
+	   * or pst to find the correct address for this type
+	   * of parameter.
+	   */
+	  if (ng < 7)
+	    {
+	      if (ng & 0x01)
+		{
+		  /* skip r4, r6, r8 as starting points */
+		  ng++;
+		  pgr++;
+		}
+	      avalue[i] = pgr;
+	      ng += 2;
+	      pgr += 2;
+	    }
+	  else
+	    {
+	      if (((long) pst) & 4)
+		pst++;
+	      avalue[i] = pst;
+	      pst += 2;
+	    }
+	  break;
+
+	case FFI_TYPE_FLOAT:
+	  /* unfortunately float values are stored as doubles
+	   * in the ffi_closure_SYSV code (since we don't check
+	   * the type in that routine).
+	   */
+
+	  /* there are 8 64bit floating point registers */
+
+	  if (nf < 8)
+	    {
+	      temp = pfr->d;
+	      pfr->f = (float) temp;
+	      avalue[i] = pfr;
+	      nf++;
+	      pfr++;
+	    }
+	  else
+	    {
+	      /* FIXME? here we are really changing the values
+	       * stored in the original calling routines outgoing
+	       * parameter stack.  This is probably a really
+	       * naughty thing to do but...
+	       */
+	      avalue[i] = pst;
+	      nf++;
+	      pst += 1;
+	    }
+	  break;
+
+	case FFI_TYPE_DOUBLE:
+	  /* On the outgoing stack all values are aligned to 8 */
+	  /* there are 8 64bit floating point registers */
+
+	  if (nf < 8)
+	    {
+	      avalue[i] = pfr;
+	      nf++;
+	      pfr++;
+	    }
+	  else
+	    {
+	      if (((long) pst) & 4)
+		pst++;
+	      avalue[i] = pst;
+	      nf++;
+	      pst += 2;
+	    }
+	  break;
+
+	default:
+	  FFI_ASSERT (0);
+	}
+
+      i++;
+    }
+
+
+  (closure->fun) (cif, rvalue, avalue, closure->user_data);
+
+  /* Tell ffi_closure_SYSV how to perform return type promotions.
+     Because the FFI_SYSV ABI returns the structures <= 8 bytes in r3/r4
+     we have to tell ffi_closure_SYSV how to treat them.  */
+  if (cif->abi == FFI_SYSV && cif->rtype->type == FFI_TYPE_STRUCT
+      && size <= 8)
+    return FFI_SYSV_TYPE_SMALL_STRUCT + size;
+  return cif->rtype->type;
+
+}
+
+int FFI_HIDDEN ffi_closure_helper_LINUX64 (ffi_closure *, void *,
+					   unsigned long *, ffi_dblfl *);
+
+int FFI_HIDDEN
+ffi_closure_helper_LINUX64 (ffi_closure *closure, void *rvalue,
+			    unsigned long *pst, ffi_dblfl *pfr)
+{
+  /* rvalue is the pointer to space for return value in closure assembly */
+  /* pst is the pointer to parameter save area
+     (r3-r10 are stored into its first 8 slots by ffi_closure_LINUX64) */
+  /* pfr is the pointer to where f1-f13 are stored in ffi_closure_LINUX64 */
+
+  void **avalue;
+  ffi_type **arg_types;
+  long i, avn;
+  ffi_cif *cif;
+  ffi_dblfl *end_pfr = pfr + NUM_FPR_ARG_REGISTERS64;
+
+  cif = closure->cif;
+  avalue = alloca (cif->nargs * sizeof (void *));
+
+  /* Copy the caller's structure return value address so that the closure
+     returns the data directly to the caller.  */
+  if (cif->rtype->type == FFI_TYPE_STRUCT)
+    {
+      rvalue = (void *) *pst;
+      pst++;
+    }
+
+  i = 0;
+  avn = cif->nargs;
+  arg_types = cif->arg_types;
+
+  /* Grab the addresses of the arguments from the stack frame.  */
+  while (i < avn)
+    {
+      switch (arg_types[i]->type)
+	{
+	case FFI_TYPE_SINT8:
+	case FFI_TYPE_UINT8:
+	  avalue[i] = (char *) pst + 7;
+	  pst++;
+	  break;
+
+	case FFI_TYPE_SINT16:
+	case FFI_TYPE_UINT16:
+	  avalue[i] = (char *) pst + 6;
+	  pst++;
+	  break;
+
+	case FFI_TYPE_SINT32:
+	case FFI_TYPE_UINT32:
+	  avalue[i] = (char *) pst + 4;
+	  pst++;
+	  break;
+
+	case FFI_TYPE_SINT64:
+	case FFI_TYPE_UINT64:
+	case FFI_TYPE_POINTER:
+	  avalue[i] = pst;
+	  pst++;
+	  break;
+
+	case FFI_TYPE_STRUCT:
+	  /* Structures with size less than eight bytes are passed
+	     left-padded.  */
+	  if (arg_types[i]->size < 8)
+	    avalue[i] = (char *) pst + 8 - arg_types[i]->size;
+	  else
+	    avalue[i] = pst;
+	  pst += (arg_types[i]->size + 7) / 8;
+	  break;
+
+	case FFI_TYPE_FLOAT:
+	  /* unfortunately float values are stored as doubles
+	   * in the ffi_closure_LINUX64 code (since we don't check
+	   * the type in that routine).
+	   */
+
+	  /* there are 13 64bit floating point registers */
+
+	  if (pfr < end_pfr)
+	    {
+	      double temp = pfr->d;
+	      pfr->f = (float) temp;
+	      avalue[i] = pfr;
+	      pfr++;
+	    }
+	  else
+	    avalue[i] = pst;
+	  pst++;
+	  break;
+
+	case FFI_TYPE_DOUBLE:
+	  /* On the outgoing stack all values are aligned to 8 */
+	  /* there are 13 64bit floating point registers */
+
+	  if (pfr < end_pfr)
+	    {
+	      avalue[i] = pfr;
+	      pfr++;
+	    }
+	  else
+	    avalue[i] = pst;
+	  pst++;
+	  break;
+
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+	case FFI_TYPE_LONGDOUBLE:
+	  if (pfr + 1 < end_pfr)
+	    {
+	      avalue[i] = pfr;
+	      pfr += 2;
+	    }
+	  else
+	    {
+	      if (pfr < end_pfr)
+		{
+		  /* Passed partly in f13 and partly on the stack.
+		     Move it all to the stack.  */
+		  *pst = *(unsigned long *) pfr;
+		  pfr++;
+		}
+	      avalue[i] = pst;
+	    }
+	  pst += 2;
+	  break;
+#endif
+
+	default:
+	  FFI_ASSERT (0);
+	}
+
+      i++;
+    }
+
+
+  (closure->fun) (cif, rvalue, avalue, closure->user_data);
+
+  /* Tell ffi_closure_LINUX64 how to perform return type promotions.  */
+  return cif->rtype->type;
+}

Added: vendor/Python/current/Modules/_ctypes/libffi/src/powerpc/ffi_darwin.c
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/powerpc/ffi_darwin.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/powerpc/ffi_darwin.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,771 @@
+#if !(defined(__APPLE__) && !defined(__ppc__))
+/* -----------------------------------------------------------------------
+   ffi.c - Copyright (c) 1998 Geoffrey Keating
+
+   PowerPC Foreign Function Interface
+
+   Darwin ABI support (c) 2001 John Hornkvist
+   AIX ABI support (c) 2002 Free Software Foundation, Inc.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+
+extern void ffi_closure_ASM(void);
+
+enum {
+  /* The assembly depends on these exact flags.  */
+  FLAG_RETURNS_NOTHING  = 1 << (31-30), /* These go in cr7  */
+  FLAG_RETURNS_FP       = 1 << (31-29),
+  FLAG_RETURNS_64BITS   = 1 << (31-28),
+  FLAG_RETURNS_128BITS  = 1 << (31-31),
+
+  FLAG_ARG_NEEDS_COPY   = 1 << (31- 7),
+  FLAG_FP_ARGUMENTS     = 1 << (31- 6), /* cr1.eq; specified by ABI  */
+  FLAG_4_GPR_ARGUMENTS  = 1 << (31- 5),
+  FLAG_RETVAL_REFERENCE = 1 << (31- 4)
+};
+
+/* About the DARWIN ABI.  */
+enum {
+  NUM_GPR_ARG_REGISTERS = 8,
+  NUM_FPR_ARG_REGISTERS = 13
+};
+enum { ASM_NEEDS_REGISTERS = 4 };
+
+/* ffi_prep_args is called by the assembly routine once stack space
+   has been allocated for the function's arguments.
+
+   The stack layout we want looks like this:
+
+   |   Return address from ffi_call_DARWIN      |	higher addresses
+   |--------------------------------------------|
+   |   Previous backchain pointer	4	|	stack pointer here
+   |--------------------------------------------|<+ <<<	on entry to
+   |   Saved r28-r31			4*4	| |	ffi_call_DARWIN
+   |--------------------------------------------| |
+   |   Parameters             (at least 8*4=32) | |
+   |--------------------------------------------| |
+   |   Space for GPR2                   4       | |
+   |--------------------------------------------| |	stack	|
+   |   Reserved                       2*4       | |	grows	|
+   |--------------------------------------------| |	down	V
+   |   Space for callee's LR		4	| |
+   |--------------------------------------------| |	lower addresses
+   |   Saved CR                         4       | |
+   |--------------------------------------------| |     stack pointer here
+   |   Current backchain pointer	4	|-/	during
+   |--------------------------------------------|   <<<	ffi_call_DARWIN
+
+   */
+
+/*@-exportheader@*/
+void ffi_prep_args(extended_cif *ecif, unsigned *const stack)
+/*@=exportheader@*/
+{
+  const unsigned bytes = ecif->cif->bytes;
+  const unsigned flags = ecif->cif->flags;
+
+  /* 'stacktop' points at the previous backchain pointer.  */
+  unsigned *const stacktop = stack + (bytes / sizeof(unsigned));
+
+  /* 'fpr_base' points at the space for fpr1, and grows upwards as
+     we use FPR registers.  */
+  double *fpr_base = (double*) (stacktop - ASM_NEEDS_REGISTERS) - NUM_FPR_ARG_REGISTERS;
+  int fparg_count = 0;
+
+
+  /* 'next_arg' grows up as we put parameters in it.  */
+  unsigned *next_arg = stack + 6; /* 6 reserved positions.  */
+
+  int i = ecif->cif->nargs;
+  double double_tmp;
+  void **p_argv = ecif->avalue;
+  unsigned gprvalue;
+  ffi_type** ptr = ecif->cif->arg_types;
+  char *dest_cpy;
+  unsigned size_al = 0;
+
+  /* Check that everything starts aligned properly.  */
+  FFI_ASSERT(((unsigned)(char *)stack & 0xF) == 0);
+  FFI_ASSERT(((unsigned)(char *)stacktop & 0xF) == 0);
+  FFI_ASSERT((bytes & 0xF) == 0);
+
+  /* Deal with return values that are actually pass-by-reference.
+     Rule:
+     Return values are referenced by r3, so r4 is the first parameter.  */
+
+  if (flags & FLAG_RETVAL_REFERENCE)
+    *next_arg++ = (unsigned)(char *)ecif->rvalue;
+
+  /* Now for the arguments.  */
+  for (;
+       i > 0;
+       i--, ptr++, p_argv++)
+    {
+      switch ((*ptr)->type)
+	{
+	/* If a floating-point parameter appears before all of the general-
+	   purpose registers are filled, the corresponding GPRs that match
+	   the size of the floating-point parameter are skipped.  */
+	case FFI_TYPE_FLOAT:
+	  double_tmp = *(float *)*p_argv;
+	  if (fparg_count >= NUM_FPR_ARG_REGISTERS)
+	    *(double *)next_arg = double_tmp;
+	  else
+	    *fpr_base++ = double_tmp;
+	  next_arg++;
+	  fparg_count++;
+	  FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
+	  break;
+
+	case FFI_TYPE_DOUBLE:
+	  double_tmp = *(double *)*p_argv;
+	  if (fparg_count >= NUM_FPR_ARG_REGISTERS)
+	    *(double *)next_arg = double_tmp;
+	  else
+	    *fpr_base++ = double_tmp;
+	  next_arg += 2;
+	  fparg_count++;
+	  FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
+	  break;
+
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+
+	case FFI_TYPE_LONGDOUBLE:
+	  double_tmp = ((double *)*p_argv)[0];
+	  if (fparg_count >= NUM_FPR_ARG_REGISTERS)
+	    *(double *)next_arg = double_tmp;
+	  else
+	    *fpr_base++ = double_tmp;
+	  next_arg += 2;
+	  fparg_count++;
+	  double_tmp = ((double *)*p_argv)[1];
+	  if (fparg_count >= NUM_FPR_ARG_REGISTERS)
+	    *(double *)next_arg = double_tmp;
+	  else
+	    *fpr_base++ = double_tmp;
+	  next_arg += 2;
+	  fparg_count++;
+	  FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
+	  break;
+#endif
+	case FFI_TYPE_UINT64:
+	case FFI_TYPE_SINT64:
+	  *(long long *)next_arg = *(long long *)*p_argv;
+	  next_arg+=2;
+	  break;
+	case FFI_TYPE_UINT8:
+	  gprvalue = *(unsigned char *)*p_argv;
+	  goto putgpr;
+	case FFI_TYPE_SINT8:
+	  gprvalue = *(signed char *)*p_argv;
+	  goto putgpr;
+	case FFI_TYPE_UINT16:
+	  gprvalue = *(unsigned short *)*p_argv;
+	  goto putgpr;
+	case FFI_TYPE_SINT16:
+	  gprvalue = *(signed short *)*p_argv;
+	  goto putgpr;
+
+	case FFI_TYPE_STRUCT:
+	  dest_cpy = (char *) next_arg;
+
+	  /* Structures that match the basic modes (QI 1 byte, HI 2 bytes,
+	     SI 4 bytes) are aligned as if they were those modes.
+	     Structures with 3 byte in size are padded upwards.  */
+	  size_al = (*ptr)->size;
+	  /* If the first member of the struct is a double, then align
+	     the struct to double-word.
+	     Type 3 is defined in include/ffi.h. #define FFI_TYPE_DOUBLE 3.  */
+	  if ((*ptr)->elements[0]->type == 3)
+	    size_al = ALIGN((*ptr)->size, 8);
+	  if (size_al < 3 && ecif->cif->abi == FFI_DARWIN)
+	    dest_cpy += 4 - size_al;
+
+	  memcpy((char *)dest_cpy, (char *)*p_argv, size_al);
+	  next_arg += (size_al + 3) / 4;
+	  break;
+
+	case FFI_TYPE_INT:
+	case FFI_TYPE_UINT32:
+	case FFI_TYPE_SINT32:
+	case FFI_TYPE_POINTER:
+	  gprvalue = *(unsigned *)*p_argv;
+	putgpr:
+	  *next_arg++ = gprvalue;
+	  break;
+	default:
+	  break;
+	}
+    }
+
+  /* Check that we didn't overrun the stack...  */
+  //FFI_ASSERT(gpr_base <= stacktop - ASM_NEEDS_REGISTERS);
+  //FFI_ASSERT((unsigned *)fpr_base
+  //	     <= stacktop - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS);
+  //FFI_ASSERT(flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4);
+}
+
+/* Perform machine dependent cif processing.  */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+{
+  /* All this is for the DARWIN ABI.  */
+  int i;
+  ffi_type **ptr;
+  unsigned bytes;
+  int fparg_count = 0, intarg_count = 0;
+  unsigned flags = 0;
+  unsigned size_al = 0;
+
+  /* All the machine-independent calculation of cif->bytes will be wrong.
+     Redo the calculation for DARWIN.  */
+
+  /* Space for the frame pointer, callee's LR, CR, etc, and for
+     the asm's temp regs.  */
+
+  bytes = (6 + ASM_NEEDS_REGISTERS) * sizeof(long);
+
+  /* Return value handling.  The rules are as follows:
+     - 32-bit (or less) integer values are returned in gpr3;
+     - Structures of size <= 4 bytes also returned in gpr3;
+     - 64-bit integer values and structures between 5 and 8 bytes are returned
+       in gpr3 and gpr4;
+     - Single/double FP values are returned in fpr1;
+     - Long double FP (if not equivalent to double) values are returned in
+       fpr1 and fpr2;
+     - Larger structures values are allocated space and a pointer is passed
+       as the first argument.  */
+  switch (cif->rtype->type)
+    {
+
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+    case FFI_TYPE_LONGDOUBLE:
+      flags |= FLAG_RETURNS_128BITS;
+      flags |= FLAG_RETURNS_FP;
+      break;
+#endif
+
+    case FFI_TYPE_DOUBLE:
+      flags |= FLAG_RETURNS_64BITS;
+      /* Fall through.  */
+    case FFI_TYPE_FLOAT:
+      flags |= FLAG_RETURNS_FP;
+      break;
+
+    case FFI_TYPE_UINT64:
+    case FFI_TYPE_SINT64:
+      flags |= FLAG_RETURNS_64BITS;
+      break;
+
+    case FFI_TYPE_STRUCT:
+      flags |= FLAG_RETVAL_REFERENCE;
+      flags |= FLAG_RETURNS_NOTHING;
+      intarg_count++;
+      break;
+    case FFI_TYPE_VOID:
+      flags |= FLAG_RETURNS_NOTHING;
+      break;
+
+    default:
+      /* Returns 32-bit integer, or similar.  Nothing to do here.  */
+      break;
+    }
+
+  /* The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the
+     first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest
+     goes on the stack.  Structures are passed as a pointer to a copy of
+     the structure. Stuff on the stack needs to keep proper alignment.  */
+  for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
+    {
+      switch ((*ptr)->type)
+	{
+	case FFI_TYPE_FLOAT:
+	case FFI_TYPE_DOUBLE:
+	  fparg_count++;
+	  /* If this FP arg is going on the stack, it must be
+	     8-byte-aligned.  */
+	  if (fparg_count > NUM_FPR_ARG_REGISTERS
+	      && intarg_count%2 != 0)
+	    intarg_count++;
+	  break;
+
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+
+	case FFI_TYPE_LONGDOUBLE:
+	  fparg_count += 2;
+	  /* If this FP arg is going on the stack, it must be
+	     8-byte-aligned.  */
+	  if (fparg_count > NUM_FPR_ARG_REGISTERS
+	      && intarg_count%2 != 0)
+	    intarg_count++;
+	  intarg_count +=2;
+	  break;
+#endif
+
+	case FFI_TYPE_UINT64:
+	case FFI_TYPE_SINT64:
+	  /* 'long long' arguments are passed as two words, but
+	     either both words must fit in registers or both go
+	     on the stack.  If they go on the stack, they must
+	     be 8-byte-aligned.  */
+	  if (intarg_count == NUM_GPR_ARG_REGISTERS-1
+	      || (intarg_count >= NUM_GPR_ARG_REGISTERS && intarg_count%2 != 0))
+	    intarg_count++;
+	  intarg_count += 2;
+	  break;
+
+	case FFI_TYPE_STRUCT:
+	  size_al = (*ptr)->size;
+	  /* If the first member of the struct is a double, then align
+	     the struct to double-word.
+	     Type 3 is defined in include/ffi.h. #define FFI_TYPE_DOUBLE 3.  */
+	  if ((*ptr)->elements[0]->type == 3)
+	    size_al = ALIGN((*ptr)->size, 8);
+	  intarg_count += (size_al + 3) / 4;
+	  break;
+
+	default:
+	  /* Everything else is passed as a 4-byte word in a GPR, either
+	     the object itself or a pointer to it.  */
+	  intarg_count++;
+	  break;
+	}
+    }
+
+  if (fparg_count != 0)
+    flags |= FLAG_FP_ARGUMENTS;
+
+  /* Space for the FPR registers, if needed.  */
+  if (fparg_count != 0)
+    bytes += NUM_FPR_ARG_REGISTERS * sizeof(double);
+
+  /* Stack space.  */
+  if ((intarg_count + 2 * fparg_count) > NUM_GPR_ARG_REGISTERS)
+    bytes += (intarg_count + 2 * fparg_count) * sizeof(long);
+  else
+    bytes += NUM_GPR_ARG_REGISTERS * sizeof(long);
+
+  /* The stack space allocated needs to be a multiple of 16 bytes.  */
+  bytes = (bytes + 15) & ~0xF;
+
+  cif->flags = flags;
+  cif->bytes = bytes;
+
+  return FFI_OK;
+}
+
+/*@-declundef@*/
+/*@-exportheader@*/
+extern void ffi_call_AIX(/*@out@*/ extended_cif *,
+			 unsigned, unsigned,
+			 /*@out@*/ unsigned *,
+			 void (*fn)(void),
+			 void (*fn2)(extended_cif *, unsigned *const));
+extern void ffi_call_DARWIN(/*@out@*/ extended_cif *,
+			    unsigned, unsigned,
+			    /*@out@*/ unsigned *,
+			    void (*fn)(void),
+			    void (*fn2)(extended_cif *, unsigned *const));
+/*@=declundef@*/
+/*@=exportheader@*/
+
+void ffi_call(/*@dependent@*/ ffi_cif *cif,
+	      void (*fn)(void),
+	      /*@out@*/ void *rvalue,
+	      /*@dependent@*/ void **avalue)
+{
+  extended_cif ecif;
+
+  ecif.cif = cif;
+  ecif.avalue = avalue;
+
+  /* If the return value is a struct and we don't have a return
+     value address then we need to make one.  */
+
+  if ((rvalue == NULL) &&
+      (cif->rtype->type == FFI_TYPE_STRUCT))
+    {
+      /*@-sysunrecog@*/
+      ecif.rvalue = alloca(cif->rtype->size);
+      /*@=sysunrecog@*/
+    }
+  else
+    ecif.rvalue = rvalue;
+
+  switch (cif->abi)
+    {
+    case FFI_AIX:
+      /*@-usedef@*/
+      ffi_call_AIX(&ecif, -cif->bytes,
+		   cif->flags, ecif.rvalue, fn, ffi_prep_args);
+      /*@=usedef@*/
+      break;
+    case FFI_DARWIN:
+      /*@-usedef@*/
+      ffi_call_DARWIN(&ecif, -cif->bytes,
+		      cif->flags, ecif.rvalue, fn, ffi_prep_args);
+      /*@=usedef@*/
+      break;
+    default:
+      FFI_ASSERT(0);
+      break;
+    }
+}
+
+static void flush_icache(char *);
+static void flush_range(char *, int);
+
+/* The layout of a function descriptor.  A C function pointer really
+   points to one of these.  */
+
+typedef struct aix_fd_struct {
+  void *code_pointer;
+  void *toc;
+} aix_fd;
+
+/* here I'd like to add the stack frame layout we use in darwin_closure.S
+   and aix_clsoure.S
+
+   SP previous -> +---------------------------------------+ <--- child frame
+		  | back chain to caller 4                |
+		  +---------------------------------------+ 4
+		  | saved CR 4                            |
+		  +---------------------------------------+ 8
+		  | saved LR 4                            |
+		  +---------------------------------------+ 12
+		  | reserved for compilers 4              |
+		  +---------------------------------------+ 16
+		  | reserved for binders 4                |
+		  +---------------------------------------+ 20
+		  | saved TOC pointer 4                   |
+		  +---------------------------------------+ 24
+		  | always reserved 8*4=32 (previous GPRs)|
+		  | according to the linkage convention   |
+		  | from AIX                              |
+		  +---------------------------------------+ 56
+		  | our FPR area 13*8=104                 |
+		  | f1                                    |
+		  | .                                     |
+		  | f13                                   |
+		  +---------------------------------------+ 160
+		  | result area 8                         |
+		  +---------------------------------------+ 168
+		  | alignement to the next multiple of 16 |
+SP current -->    +---------------------------------------+ 176 <- parent frame
+		  | back chain to caller 4                |
+		  +---------------------------------------+ 180
+		  | saved CR 4                            |
+		  +---------------------------------------+ 184
+		  | saved LR 4                            |
+		  +---------------------------------------+ 188
+		  | reserved for compilers 4              |
+		  +---------------------------------------+ 192
+		  | reserved for binders 4                |
+		  +---------------------------------------+ 196
+		  | saved TOC pointer 4                   |
+		  +---------------------------------------+ 200
+		  | always reserved 8*4=32  we store our  |
+		  | GPRs here                             |
+		  | r3                                    |
+		  | .                                     |
+		  | r10                                   |
+		  +---------------------------------------+ 232
+		  | overflow part                         |
+		  +---------------------------------------+ xxx
+		  | ????                                  |
+		  +---------------------------------------+ xxx
+
+*/
+ffi_status
+ffi_prep_closure (ffi_closure* closure,
+		  ffi_cif* cif,
+		  void (*fun)(ffi_cif*, void*, void**, void*),
+		  void *user_data)
+{
+  unsigned int *tramp;
+  struct ffi_aix_trampoline_struct *tramp_aix;
+  aix_fd *fd;
+
+  switch (cif->abi)
+    {
+    case FFI_DARWIN:
+
+      FFI_ASSERT (cif->abi == FFI_DARWIN);
+
+      tramp = (unsigned int *) &closure->tramp[0];
+      tramp[0] = 0x7c0802a6;  /*   mflr    r0  */
+      tramp[1] = 0x429f000d;  /*   bcl-    20,4*cr7+so,0x10  */
+      tramp[4] = 0x7d6802a6;  /*   mflr    r11  */
+      tramp[5] = 0x818b0000;  /*   lwz     r12,0(r11) function address  */
+      tramp[6] = 0x7c0803a6;  /*   mtlr    r0   */
+      tramp[7] = 0x7d8903a6;  /*   mtctr   r12  */
+      tramp[8] = 0x816b0004;  /*   lwz     r11,4(r11) static chain  */
+      tramp[9] = 0x4e800420;  /*   bctr  */
+      tramp[2] = (unsigned long) ffi_closure_ASM; /* function  */
+      tramp[3] = (unsigned long) closure; /* context  */
+
+      closure->cif = cif;
+      closure->fun = fun;
+      closure->user_data = user_data;
+
+      /* Flush the icache. Only necessary on Darwin.  */
+      flush_range(&closure->tramp[0],FFI_TRAMPOLINE_SIZE);
+
+      break;
+
+    case FFI_AIX:
+
+      tramp_aix = (struct ffi_aix_trampoline_struct *) (closure->tramp);
+      fd = (aix_fd *)(void *)ffi_closure_ASM;
+
+      FFI_ASSERT (cif->abi == FFI_AIX);
+
+      tramp_aix->code_pointer = fd->code_pointer;
+      tramp_aix->toc = fd->toc;
+      tramp_aix->static_chain = closure;
+      closure->cif = cif;
+      closure->fun = fun;
+      closure->user_data = user_data;
+
+    default:
+
+      FFI_ASSERT(0);
+      break;
+    }
+  return FFI_OK;
+}
+
+static void
+flush_icache(char *addr)
+{
+#ifndef _AIX
+  __asm__ volatile (
+		"dcbf 0,%0\n"
+		"\tsync\n"
+		"\ticbi 0,%0\n"
+		"\tsync\n"
+		"\tisync"
+		: : "r"(addr) : "memory");
+#endif
+}
+
+static void
+flush_range(char * addr1, int size)
+{
+#define MIN_LINE_SIZE 32
+  int i;
+  for (i = 0; i < size; i += MIN_LINE_SIZE)
+    flush_icache(addr1+i);
+  flush_icache(addr1+size-1);
+}
+
+typedef union
+{
+  float f;
+  double d;
+} ffi_dblfl;
+
+int ffi_closure_helper_DARWIN (ffi_closure*, void*,
+			       unsigned long*, ffi_dblfl*);
+
+/* Basically the trampoline invokes ffi_closure_ASM, and on
+   entry, r11 holds the address of the closure.
+   After storing the registers that could possibly contain
+   parameters to be passed into the stack frame and setting
+   up space for a return value, ffi_closure_ASM invokes the
+   following helper function to do most of the work.  */
+
+int ffi_closure_helper_DARWIN (ffi_closure* closure, void * rvalue,
+			       unsigned long * pgr, ffi_dblfl * pfr)
+{
+  /* rvalue is the pointer to space for return value in closure assembly
+     pgr is the pointer to where r3-r10 are stored in ffi_closure_ASM
+     pfr is the pointer to where f1-f13 are stored in ffi_closure_ASM.  */
+
+  typedef double ldbits[2];
+
+  union ldu
+  {
+    ldbits lb;
+    long double ld;
+  };
+
+  void **          avalue;
+  ffi_type **      arg_types;
+  long             i, avn;
+  long             nf;   /* number of floating registers already used.  */
+  long             ng;   /* number of general registers already used.  */
+  ffi_cif *        cif;
+  double           temp;
+  unsigned         size_al;
+  union ldu        temp_ld;
+
+  cif = closure->cif;
+  avalue = alloca(cif->nargs * sizeof(void *));
+
+  nf = 0;
+  ng = 0;
+
+  /* Copy the caller's structure return value address so that the closure
+     returns the data directly to the caller.  */
+  if (cif->rtype->type == FFI_TYPE_STRUCT)
+    {
+      rvalue = (void *) *pgr;
+      pgr++;
+      ng++;
+    }
+
+  i = 0;
+  avn = cif->nargs;
+  arg_types = cif->arg_types;
+
+  /* Grab the addresses of the arguments from the stack frame.  */
+  while (i < avn)
+    {
+      switch (arg_types[i]->type)
+	{
+	case FFI_TYPE_SINT8:
+	case FFI_TYPE_UINT8:
+	  avalue[i] = (char *) pgr + 3;
+	  ng++;
+	  pgr++;
+	  break;
+
+	case FFI_TYPE_SINT16:
+	case FFI_TYPE_UINT16:
+	  avalue[i] = (char *) pgr + 2;
+	  ng++;
+	  pgr++;
+	  break;
+
+	case FFI_TYPE_SINT32:
+	case FFI_TYPE_UINT32:
+	case FFI_TYPE_POINTER:
+	  avalue[i] = pgr;
+	  ng++;
+	  pgr++;
+	  break;
+
+	case FFI_TYPE_STRUCT:
+	  /* Structures that match the basic modes (QI 1 byte, HI 2 bytes,
+	     SI 4 bytes) are aligned as if they were those modes.  */
+	  size_al = arg_types[i]->size;
+	  /* If the first member of the struct is a double, then align
+	     the struct to double-word.
+	     Type 3 is defined in include/ffi.h. #define FFI_TYPE_DOUBLE 3.  */
+	  if (arg_types[i]->elements[0]->type == 3)
+	    size_al = ALIGN(arg_types[i]->size, 8);
+	  if (size_al < 3 && cif->abi == FFI_DARWIN)
+	    avalue[i] = (void*) pgr + 4 - size_al;
+	  else
+	    avalue[i] = (void*) pgr;
+	  ng += (size_al + 3) / 4;
+	  pgr += (size_al + 3) / 4;
+	  break;
+
+	case FFI_TYPE_SINT64:
+	case FFI_TYPE_UINT64:
+	  /* Long long ints are passed in two gpr's.  */
+	  avalue[i] = pgr;
+	  ng += 2;
+	  pgr += 2;
+	  break;
+
+	case FFI_TYPE_FLOAT:
+	  /* A float value consumes a GPR.
+	     There are 13 64bit floating point registers.  */
+	  if (nf < NUM_FPR_ARG_REGISTERS)
+	    {
+	      temp = pfr->d;
+	      pfr->f = (float)temp;
+	      avalue[i] = pfr;
+	      pfr++;
+	    }
+	  else
+	    {
+	      avalue[i] = pgr;
+	    }
+	  nf++;
+	  ng++;
+	  pgr++;
+	  break;
+
+	case FFI_TYPE_DOUBLE:
+	  /* A double value consumes two GPRs.
+	     There are 13 64bit floating point registers.  */
+	  if (nf < NUM_FPR_ARG_REGISTERS)
+	    {
+	      avalue[i] = pfr;
+	      pfr++;
+	    }
+	  else
+	    {
+	      avalue[i] = pgr;
+	    }
+	  nf++;
+	  ng += 2;
+	  pgr += 2;
+	  break;
+
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+
+	case FFI_TYPE_LONGDOUBLE:
+	  /* A long double value consumes four GPRs and two FPRs.
+	     There are 13 64bit floating point registers.  */
+	  if (nf < NUM_FPR_ARG_REGISTERS - 1)
+	    {
+	      avalue[i] = pfr;
+	      pfr += 2;
+	    }
+	  /* Here we have the situation where one part of the long double
+	     is stored in fpr13 and the other part is already on the stack.
+	     We use a union to pass the long double to avalue[i].  */
+	  else if (nf == NUM_FPR_ARG_REGISTERS - 1)
+	    {
+	      memcpy (&temp_ld.lb[0], pfr, sizeof(ldbits));
+	      memcpy (&temp_ld.lb[1], pgr + 2, sizeof(ldbits));
+	      avalue[i] = &temp_ld.ld;
+	    }
+	  else
+	    {
+	      avalue[i] = pgr;
+	    }
+	  nf += 2;
+	  ng += 4;
+	  pgr += 4;
+	  break;
+#endif
+	default:
+	  FFI_ASSERT(0);
+	}
+      i++;
+    }
+
+  (closure->fun) (cif, rvalue, avalue, closure->user_data);
+
+  /* Tell ffi_closure_ASM to perform return type promotions.  */
+  return cif->rtype->type;
+}
+#endif

Added: vendor/Python/current/Modules/_ctypes/libffi/src/powerpc/ffitarget.h
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/powerpc/ffitarget.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/powerpc/ffitarget.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,100 @@
+/* -----------------------------------------------------------------*-C-*-
+   ffitarget.h - Copyright (c) 1996-2003  Red Hat, Inc.
+   Target configuration macros for PowerPC.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+
+   ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+/* ---- System specific configurations ----------------------------------- */
+
+#if defined (POWERPC) && defined (__powerpc64__)
+#define POWERPC64
+#endif
+
+#ifndef LIBFFI_ASM
+typedef unsigned long          ffi_arg;
+typedef signed long            ffi_sarg;
+
+typedef enum ffi_abi {
+  FFI_FIRST_ABI = 0,
+
+#ifdef POWERPC
+  FFI_SYSV,
+  FFI_GCC_SYSV,
+  FFI_LINUX64,
+# ifdef POWERPC64
+  FFI_DEFAULT_ABI = FFI_LINUX64,
+# else
+  FFI_DEFAULT_ABI = FFI_GCC_SYSV,
+# endif
+#endif
+
+#ifdef POWERPC_AIX
+  FFI_AIX,
+  FFI_DARWIN,
+  FFI_DEFAULT_ABI = FFI_AIX,
+#endif
+
+#ifdef POWERPC_DARWIN
+  FFI_AIX,
+  FFI_DARWIN,
+  FFI_DEFAULT_ABI = FFI_DARWIN,
+#endif
+
+#ifdef POWERPC_FREEBSD
+  FFI_SYSV,
+  FFI_GCC_SYSV,
+  FFI_LINUX64,
+  FFI_DEFAULT_ABI = FFI_SYSV,
+#endif
+
+  FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
+} ffi_abi;
+#endif
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#define FFI_CLOSURES 1
+#define FFI_NATIVE_RAW_API 0
+
+/* Needed for FFI_SYSV small structure returns.  */
+#define FFI_SYSV_TYPE_SMALL_STRUCT  (FFI_TYPE_LAST)
+
+#if defined(POWERPC64) || defined(POWERPC_AIX)
+#define FFI_TRAMPOLINE_SIZE 24
+#else /* POWERPC || POWERPC_AIX */
+#define FFI_TRAMPOLINE_SIZE 40
+#endif
+
+#ifndef LIBFFI_ASM
+#if defined(POWERPC_DARWIN) || defined(POWERPC_AIX)
+struct ffi_aix_trampoline_struct {
+    void * code_pointer;	/* Pointer to ffi_closure_ASM */
+    void * toc;			/* TOC */
+    void * static_chain;	/* Pointer to closure */
+};
+#endif
+#endif
+
+#endif

Added: vendor/Python/current/Modules/_ctypes/libffi/src/powerpc/linux64.S
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/powerpc/linux64.S	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/powerpc/linux64.S	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,180 @@
+/* -----------------------------------------------------------------------
+   sysv.h - Copyright (c) 2003 Jakub Jelinek <jakub at redhat.com>
+
+   PowerPC64 Assembly glue.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+
+#ifdef __powerpc64__
+	.hidden	ffi_call_LINUX64, .ffi_call_LINUX64
+	.globl	ffi_call_LINUX64, .ffi_call_LINUX64
+	.section	".opd","aw"
+	.align	3
+ffi_call_LINUX64:
+	.quad	.ffi_call_LINUX64,.TOC. at tocbase,0
+	.size	ffi_call_LINUX64,24
+	.type	.ffi_call_LINUX64, at function
+	.text
+.ffi_call_LINUX64:
+.LFB1:
+	mflr	%r0
+	std	%r28, -32(%r1)
+	std	%r29, -24(%r1)
+	std	%r30, -16(%r1)
+	std	%r31, -8(%r1)
+	std	%r0, 16(%r1)
+
+	mr	%r28, %r1	/* our AP.  */
+	stdux	%r1, %r1, %r4
+.LCFI0:
+	mr	%r31, %r5	/* flags, */
+	mr	%r30, %r6	/* rvalue, */
+	mr	%r29, %r7	/* function address.  */
+	std	%r2, 40(%r1)
+
+	/* Call ffi_prep_args64.  */
+	mr	%r4, %r1
+	bl	.ffi_prep_args64
+
+	ld	%r0, 0(%r29)
+	ld	%r2, 8(%r29)
+	ld	%r11, 16(%r29)
+
+	/* Now do the call.  */
+	/* Set up cr1 with bits 4-7 of the flags.  */
+	mtcrf	0x40, %r31
+
+	/* Get the address to call into CTR.  */
+	mtctr	%r0
+	/* Load all those argument registers.  */
+	ld	%r3, -32-(8*8)(%r28)
+	ld	%r4, -32-(7*8)(%r28)
+	ld	%r5, -32-(6*8)(%r28)
+	ld	%r6, -32-(5*8)(%r28)
+	bf-	5, 1f
+	ld	%r7, -32-(4*8)(%r28)
+	ld	%r8, -32-(3*8)(%r28)
+	ld	%r9, -32-(2*8)(%r28)
+	ld	%r10, -32-(1*8)(%r28)
+1:
+
+	/* Load all the FP registers.  */
+	bf-	6, 2f
+	lfd	%f1, -32-(21*8)(%r28)
+	lfd	%f2, -32-(20*8)(%r28)
+	lfd	%f3, -32-(19*8)(%r28)
+	lfd	%f4, -32-(18*8)(%r28)
+	lfd	%f5, -32-(17*8)(%r28)
+	lfd	%f6, -32-(16*8)(%r28)
+	lfd	%f7, -32-(15*8)(%r28)
+	lfd	%f8, -32-(14*8)(%r28)
+	lfd	%f9, -32-(13*8)(%r28)
+	lfd	%f10, -32-(12*8)(%r28)
+	lfd	%f11, -32-(11*8)(%r28)
+	lfd	%f12, -32-(10*8)(%r28)
+	lfd	%f13, -32-(9*8)(%r28)
+2:
+
+	/* Make the call.  */
+	bctrl
+
+	/* Now, deal with the return value.  */
+	mtcrf	0x01, %r31
+	bt-	30, .Ldone_return_value
+	bt-	29, .Lfp_return_value
+	std	%r3, 0(%r30)
+	/* Fall through...  */
+
+.Ldone_return_value:
+	/* Restore the registers we used and return.  */
+	ld	%r2, 40(%r1)
+	mr	%r1, %r28
+	ld	%r0, 16(%r28)
+	ld	%r28, -32(%r1)
+	mtlr	%r0
+	ld	%r29, -24(%r1)
+	ld	%r30, -16(%r1)
+	ld	%r31, -8(%r1)
+	blr
+
+.Lfp_return_value:
+	bt	27, .Lfd_return_value
+	bf	28, .Lfloat_return_value
+	stfd	%f1, 0(%r30)
+	b	.Ldone_return_value
+.Lfd_return_value:
+	stfd	%f1, 0(%r30)
+	stfd	%f2, 8(%r30)
+	b	.Ldone_return_value
+.Lfloat_return_value:
+	stfs	%f1, 0(%r30)
+	b	.Ldone_return_value
+.LFE1:
+	.long	0
+	.byte	0,12,0,1,128,4,0,0
+	.size	.ffi_call_LINUX64,.-.ffi_call_LINUX64
+
+	.section	.eh_frame,EH_FRAME_FLAGS, at progbits
+.Lframe1:
+	.4byte	.LECIE1-.LSCIE1	 # Length of Common Information Entry
+.LSCIE1:
+	.4byte	0x0	 # CIE Identifier Tag
+	.byte	0x1	 # CIE Version
+	.ascii "zR\0"	 # CIE Augmentation
+	.uleb128 0x1	 # CIE Code Alignment Factor
+	.sleb128 -8	 # CIE Data Alignment Factor
+	.byte	0x41	 # CIE RA Column
+	.uleb128 0x1	 # Augmentation size
+	.byte	0x14	 # FDE Encoding (pcrel udata8)
+	.byte	0xc	 # DW_CFA_def_cfa
+	.uleb128 0x1
+	.uleb128 0x0
+	.align 3
+.LECIE1:
+.LSFDE1:
+	.4byte	.LEFDE1-.LASFDE1	 # FDE Length
+.LASFDE1:
+	.4byte	.LASFDE1-.Lframe1	 # FDE CIE offset
+	.8byte	.LFB1-.	 # FDE initial location
+	.8byte	.LFE1-.LFB1	 # FDE address range
+	.uleb128 0x0	 # Augmentation size
+	.byte	0x2	 # DW_CFA_advance_loc1
+	.byte	.LCFI0-.LFB1
+	.byte	0xd	 # DW_CFA_def_cfa_register
+	.uleb128 0x1c
+	.byte	0x11	 # DW_CFA_offset_extended_sf
+	.uleb128 0x41
+	.sleb128 -2
+	.byte	0x9f	 # DW_CFA_offset, column 0x1f
+	.uleb128 0x1
+	.byte	0x9e	 # DW_CFA_offset, column 0x1e
+	.uleb128 0x2
+	.byte	0x9d	 # DW_CFA_offset, column 0x1d
+	.uleb128 0x3
+	.byte	0x9c	 # DW_CFA_offset, column 0x1c
+	.uleb128 0x4
+	.align 3
+.LEFDE1:
+#endif

Added: vendor/Python/current/Modules/_ctypes/libffi/src/powerpc/linux64_closure.S
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/powerpc/linux64_closure.S	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/powerpc/linux64_closure.S	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,206 @@
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+
+	.file	"linux64_closure.S"
+
+#ifdef __powerpc64__
+	FFI_HIDDEN (ffi_closure_LINUX64)
+	FFI_HIDDEN (.ffi_closure_LINUX64)
+	.globl  ffi_closure_LINUX64, .ffi_closure_LINUX64
+	.section        ".opd","aw"
+	.align  3
+ffi_closure_LINUX64:
+	.quad   .ffi_closure_LINUX64,.TOC. at tocbase,0
+	.size   ffi_closure_LINUX64,24
+	.type   .ffi_closure_LINUX64, at function
+	.text
+.ffi_closure_LINUX64:
+.LFB1:
+	# save general regs into parm save area
+	std	%r3, 48(%r1)
+	std	%r4, 56(%r1)
+	std	%r5, 64(%r1)
+	std	%r6, 72(%r1)
+	mflr	%r0
+
+	std	%r7, 80(%r1)
+	std	%r8, 88(%r1)
+	std	%r9, 96(%r1)
+	std	%r10, 104(%r1)
+	std	%r0, 16(%r1)
+
+	# mandatory 48 bytes special reg save area + 64 bytes parm save area
+	# + 16 bytes retval area + 13*8 bytes fpr save area + round to 16
+	stdu	%r1, -240(%r1)
+.LCFI0:
+
+	# next save fpr 1 to fpr 13
+	stfd  %f1, 128+(0*8)(%r1)
+	stfd  %f2, 128+(1*8)(%r1)
+	stfd  %f3, 128+(2*8)(%r1)
+	stfd  %f4, 128+(3*8)(%r1)
+	stfd  %f5, 128+(4*8)(%r1)
+	stfd  %f6, 128+(5*8)(%r1)
+	stfd  %f7, 128+(6*8)(%r1)
+	stfd  %f8, 128+(7*8)(%r1)
+	stfd  %f9, 128+(8*8)(%r1)
+	stfd  %f10, 128+(9*8)(%r1)
+	stfd  %f11, 128+(10*8)(%r1)
+	stfd  %f12, 128+(11*8)(%r1)
+	stfd  %f13, 128+(12*8)(%r1)
+
+	# set up registers for the routine that actually does the work
+	# get the context pointer from the trampoline
+	mr %r3, %r11
+
+	# now load up the pointer to the result storage
+	addi %r4, %r1, 112
+
+	# now load up the pointer to the parameter save area
+	# in the previous frame
+	addi %r5, %r1, 240 + 48
+
+	# now load up the pointer to the saved fpr registers */
+	addi %r6, %r1, 128
+
+	# make the call
+	bl .ffi_closure_helper_LINUX64
+.Lret:
+
+	# now r3 contains the return type
+	# so use it to look up in a table
+	# so we know how to deal with each type
+
+	# look up the proper starting point in table
+	# by using return type as offset
+	mflr %r4		# move address of .Lret to r4
+	sldi %r3, %r3, 4	# now multiply return type by 16
+	addi %r4, %r4, .Lret_type0 - .Lret
+	ld %r0, 240+16(%r1)
+	add %r3, %r3, %r4	# add contents of table to table address
+	mtctr %r3
+	bctr			# jump to it
+
+# Each of the ret_typeX code fragments has to be exactly 16 bytes long
+# (4 instructions). For cache effectiveness we align to a 16 byte boundary
+# first.
+	.align 4
+
+.Lret_type0:
+# case FFI_TYPE_VOID
+	mtlr %r0
+	addi %r1, %r1, 240
+	blr
+	nop
+# case FFI_TYPE_INT
+	lwa %r3, 112+4(%r1)
+	mtlr %r0
+	addi %r1, %r1, 240
+	blr
+# case FFI_TYPE_FLOAT
+	lfs %f1, 112+0(%r1)
+	mtlr %r0
+	addi %r1, %r1, 240
+	blr
+# case FFI_TYPE_DOUBLE
+	lfd %f1, 112+0(%r1)
+	mtlr %r0
+	addi %r1, %r1, 240
+	blr
+# case FFI_TYPE_LONGDOUBLE
+	lfd %f1, 112+0(%r1)
+	mtlr %r0
+	lfd %f2, 112+8(%r1)
+	b .Lfinish
+# case FFI_TYPE_UINT8
+	lbz %r3, 112+7(%r1)
+	mtlr %r0
+	addi %r1, %r1, 240
+	blr
+# case FFI_TYPE_SINT8
+	lbz %r3, 112+7(%r1)
+	extsb %r3,%r3
+	mtlr %r0
+	b .Lfinish
+# case FFI_TYPE_UINT16
+	lhz %r3, 112+6(%r1)
+	mtlr %r0
+.Lfinish:
+	addi %r1, %r1, 240
+	blr
+# case FFI_TYPE_SINT16
+	lha %r3, 112+6(%r1)
+	mtlr %r0
+	addi %r1, %r1, 240
+	blr
+# case FFI_TYPE_UINT32
+	lwz %r3, 112+4(%r1)
+	mtlr %r0
+	addi %r1, %r1, 240
+	blr
+# case FFI_TYPE_SINT32
+	lwa %r3, 112+4(%r1)
+	mtlr %r0
+	addi %r1, %r1, 240
+	blr
+# case FFI_TYPE_UINT64
+	ld %r3, 112+0(%r1)
+	mtlr %r0
+	addi %r1, %r1, 240
+	blr
+# case FFI_TYPE_SINT64
+	ld %r3, 112+0(%r1)
+	mtlr %r0
+	addi %r1, %r1, 240
+	blr
+# case FFI_TYPE_STRUCT
+	mtlr %r0
+	addi %r1, %r1, 240
+	blr
+	nop
+# case FFI_TYPE_POINTER
+	ld %r3, 112+0(%r1)
+	mtlr %r0
+	addi %r1, %r1, 240
+	blr
+# esac
+.LFE1:
+	.long	0
+	.byte	0,12,0,1,128,0,0,0
+	.size	.ffi_closure_LINUX64,.-.ffi_closure_LINUX64
+
+	.section	.eh_frame,EH_FRAME_FLAGS, at progbits
+.Lframe1:
+	.4byte	.LECIE1-.LSCIE1	 # Length of Common Information Entry
+.LSCIE1:
+	.4byte	0x0	 # CIE Identifier Tag
+	.byte	0x1	 # CIE Version
+	.ascii "zR\0"	 # CIE Augmentation
+	.uleb128 0x1	 # CIE Code Alignment Factor
+	.sleb128 -8	 # CIE Data Alignment Factor
+	.byte	0x41	 # CIE RA Column
+	.uleb128 0x1	 # Augmentation size
+	.byte	0x14	 # FDE Encoding (pcrel udata8)
+	.byte	0xc	 # DW_CFA_def_cfa
+	.uleb128 0x1
+	.uleb128 0x0
+	.align 3
+.LECIE1:
+.LSFDE1:
+	.4byte	.LEFDE1-.LASFDE1	 # FDE Length
+.LASFDE1:
+	.4byte	.LASFDE1-.Lframe1	 # FDE CIE offset
+	.8byte	.LFB1-.	 # FDE initial location
+	.8byte	.LFE1-.LFB1	 # FDE address range
+	.uleb128 0x0	 # Augmentation size
+	.byte	0x2	 # DW_CFA_advance_loc1
+	.byte	.LCFI0-.LFB1
+	.byte	0xe	 # DW_CFA_def_cfa_offset
+	.uleb128 240
+	.byte	0x11	 # DW_CFA_offset_extended_sf
+	.uleb128 0x41
+	.sleb128 -2
+	.align 3
+.LEFDE1:
+#endif

Added: vendor/Python/current/Modules/_ctypes/libffi/src/powerpc/ppc_closure.S
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/powerpc/ppc_closure.S	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/powerpc/ppc_closure.S	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,323 @@
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+#include <powerpc/asm.h>
+
+	.file   "ppc_closure.S"
+
+#ifndef __powerpc64__
+
+ENTRY(ffi_closure_SYSV)
+.LFB1:
+	stwu %r1,-144(%r1)
+.LCFI0:
+	mflr %r0
+.LCFI1:
+	stw %r0,148(%r1)
+
+# we want to build up an areas for the parameters passed
+# in registers (both floating point and integer)
+
+	# so first save gpr 3 to gpr 10 (aligned to 4)
+	stw   %r3, 16(%r1)
+	stw   %r4, 20(%r1)
+	stw   %r5, 24(%r1)
+	stw   %r6, 28(%r1)
+	stw   %r7, 32(%r1)
+	stw   %r8, 36(%r1)
+	stw   %r9, 40(%r1)
+	stw   %r10,44(%r1)
+
+	# next save fpr 1 to fpr 8 (aligned to 8)
+	stfd  %f1, 48(%r1)
+	stfd  %f2, 56(%r1)
+	stfd  %f3, 64(%r1)
+	stfd  %f4, 72(%r1)
+	stfd  %f5, 80(%r1)
+	stfd  %f6, 88(%r1)
+	stfd  %f7, 96(%r1)
+	stfd  %f8, 104(%r1)
+
+	# set up registers for the routine that actually does the work
+	# get the context pointer from the trampoline
+	mr %r3,%r11
+
+	# now load up the pointer to the result storage
+	addi %r4,%r1,112
+
+	# now load up the pointer to the saved gpr registers
+	addi %r5,%r1,16
+
+	# now load up the pointer to the saved fpr registers */
+	addi %r6,%r1,48
+
+	# now load up the pointer to the outgoing parameter
+	# stack in the previous frame
+	# i.e. the previous frame pointer + 8
+	addi %r7,%r1,152
+
+	# make the call
+	bl ffi_closure_helper_SYSV at local
+
+	# now r3 contains the return type
+	# so use it to look up in a table
+	# so we know how to deal with each type
+
+	# look up the proper starting point in table
+	# by using return type as offset
+	addi %r6,%r1,112   # get pointer to results area
+	bl .Lget_ret_type0_addr # get pointer to .Lret_type0 into LR
+	mflr %r4           # move to r4
+	slwi %r3,%r3,4     # now multiply return type by 16
+	add %r3,%r3,%r4    # add contents of table to table address
+	mtctr %r3
+	bctr               # jump to it
+.LFE1:
+
+# Each of the ret_typeX code fragments has to be exactly 16 bytes long
+# (4 instructions). For cache effectiveness we align to a 16 byte boundary
+# first.
+	.align 4
+
+	nop
+	nop
+	nop
+.Lget_ret_type0_addr:
+	blrl
+
+# case FFI_TYPE_VOID
+.Lret_type0:
+	b .Lfinish
+	nop
+	nop
+	nop
+
+# case FFI_TYPE_INT
+.Lret_type1:
+	lwz %r3,0(%r6)
+	b .Lfinish
+	nop
+	nop
+
+# case FFI_TYPE_FLOAT
+.Lret_type2:
+	lfs %f1,0(%r6)
+	b .Lfinish
+	nop
+	nop
+
+# case FFI_TYPE_DOUBLE
+.Lret_type3:
+	lfd %f1,0(%r6)
+	b .Lfinish
+	nop
+	nop
+
+# case FFI_TYPE_LONGDOUBLE
+.Lret_type4:
+	lfd %f1,0(%r6)
+	b .Lfinish
+	nop
+	nop
+
+# case FFI_TYPE_UINT8
+.Lret_type5:
+	lbz %r3,3(%r6)
+	b .Lfinish
+	nop
+	nop
+
+# case FFI_TYPE_SINT8
+.Lret_type6:
+	lbz %r3,3(%r6)
+	extsb %r3,%r3
+	b .Lfinish
+	nop
+
+# case FFI_TYPE_UINT16
+.Lret_type7:
+	lhz %r3,2(%r6)
+	b .Lfinish
+	nop
+	nop
+
+# case FFI_TYPE_SINT16
+.Lret_type8:
+	lha %r3,2(%r6)
+	b .Lfinish
+	nop
+	nop
+
+# case FFI_TYPE_UINT32
+.Lret_type9:
+	lwz %r3,0(%r6)
+	b .Lfinish
+	nop
+	nop
+
+# case FFI_TYPE_SINT32
+.Lret_type10:
+	lwz %r3,0(%r6)
+	b .Lfinish
+	nop
+	nop
+
+# case FFI_TYPE_UINT64
+.Lret_type11:
+	lwz %r3,0(%r6)
+	lwz %r4,4(%r6)
+	b .Lfinish
+	nop
+
+# case FFI_TYPE_SINT64
+.Lret_type12:
+	lwz %r3,0(%r6)
+	lwz %r4,4(%r6)
+	b .Lfinish
+	nop
+
+# case FFI_TYPE_STRUCT
+.Lret_type13:
+	b .Lfinish
+	nop
+	nop
+	nop
+
+# case FFI_TYPE_POINTER
+.Lret_type14:
+	lwz %r3,0(%r6)
+	b .Lfinish
+	nop
+	nop
+
+# The return types below are only used when the ABI type is FFI_SYSV.
+# case FFI_SYSV_TYPE_SMALL_STRUCT + 1. One byte struct.
+.Lret_type15:
+# fall through.
+	lbz %r3,0(%r6)
+	b .Lfinish
+	nop
+	nop
+
+# case FFI_SYSV_TYPE_SMALL_STRUCT + 2. Two byte struct.
+.Lret_type16:
+# fall through.
+	lhz %r3,0(%r6)
+	b .Lfinish
+	nop
+	nop
+
+# case FFI_SYSV_TYPE_SMALL_STRUCT + 3. Three byte struct.
+.Lret_type17:
+# fall through.
+	lwz %r3,0(%r6)
+	srwi %r3,%r3,8
+	b .Lfinish
+	nop
+
+# case FFI_SYSV_TYPE_SMALL_STRUCT + 4. Four byte struct.
+.Lret_type18:
+# this one handles the structs from above too.
+	lwz %r3,0(%r6)
+	b .Lfinish
+	nop
+	nop
+
+# case FFI_SYSV_TYPE_SMALL_STRUCT + 5. Five byte struct.
+.Lret_type19:
+# fall through.
+	lwz %r3,0(%r6)
+	lwz %r4,4(%r6)
+	li %r5,24
+	b .Lstruct567
+
+# case FFI_SYSV_TYPE_SMALL_STRUCT + 6. Six byte struct.
+.Lret_type20:
+# fall through.
+	lwz %r3,0(%r6)
+	lwz %r4,4(%r6)
+	li %r5,16
+	b .Lstruct567
+
+# case FFI_SYSV_TYPE_SMALL_STRUCT + 7. Seven byte struct.
+.Lret_type21:
+# fall through.
+	lwz %r3,0(%r6)
+	lwz %r4,4(%r6)
+	li %r5,8
+	b .Lstruct567
+
+# case FFI_SYSV_TYPE_SMALL_STRUCT + 8. Eight byte struct.
+.Lret_type22:
+# this one handles the above unhandled structs.
+	lwz %r3,0(%r6)
+	lwz %r4,4(%r6)
+	b .Lfinish
+	nop
+
+# case done
+.Lfinish:
+
+	lwz %r0,148(%r1)
+	mtlr %r0
+	addi %r1,%r1,144
+	blr
+
+.Lstruct567:
+	subfic %r0,%r5,32
+	srw %r4,%r4,%r5
+	slw %r0,%r3,%r0
+	srw %r3,%r3,%r5
+	or %r4,%r0,%r4
+	b .Lfinish
+END(ffi_closure_SYSV)
+
+	.section	".eh_frame",EH_FRAME_FLAGS, at progbits
+.Lframe1:
+	.4byte	.LECIE1-.LSCIE1	 # Length of Common Information Entry
+.LSCIE1:
+	.4byte	0x0	 # CIE Identifier Tag
+	.byte	0x1	 # CIE Version
+#if defined _RELOCATABLE || defined __PIC__
+	.ascii "zR\0"	 # CIE Augmentation
+#else
+	.ascii "\0"	 # CIE Augmentation
+#endif
+	.uleb128 0x1	 # CIE Code Alignment Factor
+	.sleb128 -4	 # CIE Data Alignment Factor
+	.byte	0x41	 # CIE RA Column
+#if defined _RELOCATABLE || defined __PIC__
+	.uleb128 0x1	 # Augmentation size
+	.byte	0x1b	 # FDE Encoding (pcrel sdata4)
+#endif
+	.byte	0xc	 # DW_CFA_def_cfa
+	.uleb128 0x1
+	.uleb128 0x0
+	.align 2
+.LECIE1:
+.LSFDE1:
+	.4byte	.LEFDE1-.LASFDE1	 # FDE Length
+.LASFDE1:
+	.4byte	.LASFDE1-.Lframe1	 # FDE CIE offset
+#if defined _RELOCATABLE || defined __PIC__
+	.4byte	.LFB1-.	 # FDE initial location
+#else
+	.4byte	.LFB1	 # FDE initial location
+#endif
+	.4byte	.LFE1-.LFB1	 # FDE address range
+#if defined _RELOCATABLE || defined __PIC__
+	.uleb128 0x0	 # Augmentation size
+#endif
+	.byte	0x4	 # DW_CFA_advance_loc4
+	.4byte	.LCFI0-.LFB1
+	.byte	0xe	 # DW_CFA_def_cfa_offset
+	.uleb128 144
+	.byte	0x4	 # DW_CFA_advance_loc4
+	.4byte	.LCFI1-.LCFI0
+	.byte	0x11	 # DW_CFA_offset_extended_sf
+	.uleb128 0x41
+	.sleb128 -1
+	.align 2
+.LEFDE1:
+
+#endif

Added: vendor/Python/current/Modules/_ctypes/libffi/src/powerpc/sysv.S
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/powerpc/sysv.S	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/powerpc/sysv.S	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,217 @@
+/* -----------------------------------------------------------------------
+   sysv.h - Copyright (c) 1998 Geoffrey Keating
+
+   PowerPC Assembly glue.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+#include <powerpc/asm.h>
+
+#ifndef __powerpc64__
+	.globl ffi_prep_args_SYSV
+ENTRY(ffi_call_SYSV)
+.LFB1:
+	/* Save the old stack pointer as AP.  */
+	mr	%r8,%r1
+
+.LCFI0:
+	/* Allocate the stack space we need.  */
+	stwux	%r1,%r1,%r4
+	/* Save registers we use.  */
+	mflr	%r9
+	stw	%r28,-16(%r8)
+.LCFI1:
+	stw	%r29,-12(%r8)
+.LCFI2:
+	stw	%r30, -8(%r8)
+.LCFI3:
+	stw	%r31, -4(%r8)
+.LCFI4:
+	stw	%r9,   4(%r8)
+.LCFI5:
+
+	/* Save arguments over call...  */
+	mr	%r31,%r5	/* flags, */
+	mr	%r30,%r6	/* rvalue, */
+	mr	%r29,%r7	/* function address, */
+	mr	%r28,%r8	/* our AP. */
+.LCFI6:
+
+	/* Call ffi_prep_args_SYSV.  */
+	mr	%r4,%r1
+	bl	ffi_prep_args_SYSV at local
+
+	/* Now do the call.  */
+	/* Set up cr1 with bits 4-7 of the flags.  */
+	mtcrf	0x40,%r31
+	/* Get the address to call into CTR.  */
+	mtctr	%r29
+	/* Load all those argument registers.  */
+	lwz	%r3,-16-(8*4)(%r28)
+	lwz	%r4,-16-(7*4)(%r28)
+	lwz	%r5,-16-(6*4)(%r28)
+	lwz	%r6,-16-(5*4)(%r28)
+	bf-	5,1f
+	nop
+	lwz	%r7,-16-(4*4)(%r28)
+	lwz	%r8,-16-(3*4)(%r28)
+	lwz	%r9,-16-(2*4)(%r28)
+	lwz	%r10,-16-(1*4)(%r28)
+	nop
+1:
+
+	/* Load all the FP registers.  */
+	bf-	6,2f
+	lfd	%f1,-16-(8*4)-(8*8)(%r28)
+	lfd	%f2,-16-(8*4)-(7*8)(%r28)
+	lfd	%f3,-16-(8*4)-(6*8)(%r28)
+	lfd	%f4,-16-(8*4)-(5*8)(%r28)
+	nop
+	lfd	%f5,-16-(8*4)-(4*8)(%r28)
+	lfd	%f6,-16-(8*4)-(3*8)(%r28)
+	lfd	%f7,-16-(8*4)-(2*8)(%r28)
+	lfd	%f8,-16-(8*4)-(1*8)(%r28)
+2:
+
+	/* Make the call.  */
+	bctrl
+
+	/* Now, deal with the return value.  */
+	mtcrf	0x01,%r31
+	bt-	31,L(small_struct_return_value)
+	bt-	30,L(done_return_value)
+	bt-	29,L(fp_return_value)
+	stw	%r3,0(%r30)
+	bf+	28,L(done_return_value)
+	stw	%r4,4(%r30)
+	/* Fall through...  */
+
+L(done_return_value):
+	/* Restore the registers we used and return.  */
+	lwz	%r9,   4(%r28)
+	lwz	%r31, -4(%r28)
+	mtlr	%r9
+	lwz	%r30, -8(%r28)
+	lwz	%r29,-12(%r28)
+	lwz	%r28,-16(%r28)
+	lwz	%r1,0(%r1)
+	blr
+
+L(fp_return_value):
+	bf	28,L(float_return_value)
+	stfd	%f1,0(%r30)
+	b	L(done_return_value)
+L(float_return_value):
+	stfs	%f1,0(%r30)
+	b	L(done_return_value)
+
+L(small_struct_return_value):
+	mtcrf	0x10,%r31	/* cr3  */
+	bt-	15,L(smst_one_register)
+	mtcrf	0x08,%r31	/* cr4  */
+	bt-	16,L(smst_two_register)
+	b       L(done_return_value)
+
+L(smst_one_register):
+	rlwinm  %r5,%r31,5+23,32-5,31 /* Extract the value to shift.  */
+	slw	%r3,%r3,%r5
+	stw	%r3,0(%r30)
+	b	L(done_return_value)
+L(smst_two_register):
+	rlwinm  %r5,%r31,5+23,32-5,31 /* Extract the value to shift.  */
+	cmpwi	%r5,0
+	subfic	%r9,%r5,32
+	slw	%r29,%r3,%r5
+	srw	%r9,%r4,%r9
+	beq-	L(smst_8byte)
+	or	%r3,%r9,%r29
+	slw	%r4,%r4,%r5
+L(smst_8byte):
+	stw	%r3,0(%r30)
+	stw	%r4,4(%r30)
+	b	L(done_return_value)
+
+.LFE1:
+END(ffi_call_SYSV)
+
+      .section	".eh_frame",EH_FRAME_FLAGS, at progbits
+.Lframe1:
+      .4byte    .LECIE1-.LSCIE1  /*  Length of Common Information Entry */
+.LSCIE1:
+      .4byte    0x0      /*  CIE Identifier Tag */
+      .byte     0x1      /*  CIE Version */
+#if defined _RELOCATABLE || defined __PIC__
+      .ascii	"zR\0"   /*  CIE Augmentation */
+#else
+      .ascii	"\0"	 /*  CIE Augmentation */
+#endif
+      .uleb128  0x1      /*  CIE Code Alignment Factor */
+      .sleb128  -4	 /*  CIE Data Alignment Factor */
+      .byte     0x41     /*  CIE RA Column */
+#if defined _RELOCATABLE || defined __PIC__
+      .uleb128  0x1      /*  Augmentation size */
+      .byte	0x1b	 /*  FDE Encoding (pcrel sdata4) */
+#endif
+      .byte     0xc      /*  DW_CFA_def_cfa */
+      .uleb128  0x1
+      .uleb128  0x0
+      .align 2
+.LECIE1:
+.LSFDE1:
+      .4byte    .LEFDE1-.LASFDE1         /*  FDE Length */
+.LASFDE1:
+      .4byte    .LASFDE1-.Lframe1         /*  FDE CIE offset */
+#if defined _RELOCATABLE || defined __PIC__
+      .4byte    .LFB1-.  /*  FDE initial location */
+#else
+      .4byte    .LFB1    /*  FDE initial location */
+#endif
+      .4byte    .LFE1-.LFB1      /*  FDE address range */
+#if defined _RELOCATABLE || defined __PIC__
+      .uleb128  0x0	 /*  Augmentation size */
+#endif
+      .byte     0x4      /*  DW_CFA_advance_loc4 */
+      .4byte    .LCFI0-.LFB1
+      .byte     0xd      /*  DW_CFA_def_cfa_register */
+      .uleb128  0x08
+      .byte     0x4      /*  DW_CFA_advance_loc4 */
+      .4byte    .LCFI5-.LCFI0
+      .byte     0x11     /*  DW_CFA_offset_extended_sf */
+      .uleb128  0x41
+      .sleb128  -1
+      .byte     0x9f     /*  DW_CFA_offset, column 0x1f */
+      .uleb128  0x1
+      .byte     0x9e     /*  DW_CFA_offset, column 0x1e */
+      .uleb128  0x2
+      .byte     0x9d     /*  DW_CFA_offset, column 0x1d */
+      .uleb128  0x3
+      .byte     0x9c     /*  DW_CFA_offset, column 0x1c */
+      .uleb128  0x4
+      .byte     0x4      /*  DW_CFA_advance_loc4 */
+      .4byte    .LCFI6-.LCFI5
+      .byte     0xd      /*  DW_CFA_def_cfa_register */
+      .uleb128  0x1c
+      .align 2
+.LEFDE1:
+#endif

Added: vendor/Python/current/Modules/_ctypes/libffi/src/prep_cif.c
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/prep_cif.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/prep_cif.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,210 @@
+/* -----------------------------------------------------------------------
+   prep_cif.c - Copyright (c) 1996, 1998  Red Hat, Inc.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+#include <stdlib.h>
+
+
+/* Round up to FFI_SIZEOF_ARG. */
+
+#define STACK_ARG_SIZE(x) ALIGN(x, FFI_SIZEOF_ARG)
+
+/* Perform machine independent initialization of aggregate type
+   specifications. */
+
+static ffi_status initialize_aggregate(/*@out@*/ ffi_type *arg)
+{
+  ffi_type **ptr; 
+
+  FFI_ASSERT(arg != NULL);
+
+  /*@-usedef@*/
+
+  FFI_ASSERT(arg->elements != NULL);
+  FFI_ASSERT(arg->size == 0);
+  FFI_ASSERT(arg->alignment == 0);
+
+  ptr = &(arg->elements[0]);
+
+  while ((*ptr) != NULL)
+    {
+      if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK))
+	return FFI_BAD_TYPEDEF;
+      
+      /* Perform a sanity check on the argument type */
+      FFI_ASSERT_VALID_TYPE(*ptr);
+
+#ifdef POWERPC_DARWIN
+      {
+	      int curalign;
+
+	      curalign = (*ptr)->alignment;
+	      if (ptr != &(arg->elements[0])) {
+		      if (curalign > 4 && curalign != 16) {
+			      curalign = 4;
+		      }
+	      }
+      arg->size = ALIGN(arg->size, curalign);
+      arg->size += (*ptr)->size;
+
+      arg->alignment = (arg->alignment > curalign) ? 
+	      arg->alignment : curalign;
+      }
+#else
+      arg->size = ALIGN(arg->size, (*ptr)->alignment);
+      arg->size += (*ptr)->size;
+
+      arg->alignment = (arg->alignment > (*ptr)->alignment) ? 
+	arg->alignment : (*ptr)->alignment;
+#endif
+
+      ptr++;
+    }
+
+  /* Structure size includes tail padding.  This is important for
+     structures that fit in one register on ABIs like the PowerPC64
+     Linux ABI that right justify small structs in a register.
+     It's also needed for nested structure layout, for example
+     struct A { long a; char b; }; struct B { struct A x; char y; };
+     should find y at an offset of 2*sizeof(long) and result in a
+     total size of 3*sizeof(long).  */
+  arg->size = ALIGN (arg->size, arg->alignment);
+
+  if (arg->size == 0)
+    return FFI_BAD_TYPEDEF;
+  else
+    return FFI_OK;
+
+  /*@=usedef@*/
+}
+
+#ifndef __CRIS__
+/* The CRIS ABI specifies structure elements to have byte
+   alignment only, so it completely overrides this functions,
+   which assumes "natural" alignment and padding.  */
+
+/* Perform machine independent ffi_cif preparation, then call
+   machine dependent routine. */
+
+#ifdef X86_DARWIN
+static inline int struct_on_stack(int size)
+{
+	if (size > 8) return 1;
+	/* This is not what the ABI says, but is what is really implemented */
+	switch (size) {
+	case 1: case 2: case 4: case 8: return 0;
+	}
+	return 1;
+}
+#endif
+
+
+ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif, 
+			ffi_abi abi, unsigned int nargs, 
+			/*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type *rtype, 
+			/*@dependent@*/ ffi_type **atypes)
+{
+  unsigned bytes = 0;
+  unsigned int i;
+  ffi_type **ptr;
+
+  FFI_ASSERT(cif != NULL);
+  FFI_ASSERT((abi > FFI_FIRST_ABI) && (abi <= FFI_DEFAULT_ABI));
+
+  cif->abi = abi;
+  cif->arg_types = atypes;
+  cif->nargs = nargs;
+  cif->rtype = rtype;
+
+  cif->flags = 0;
+
+  /* Initialize the return type if necessary */
+  /*@-usedef@*/
+  if ((cif->rtype->size == 0) && (initialize_aggregate(cif->rtype) != FFI_OK))
+    return FFI_BAD_TYPEDEF;
+  /*@=usedef@*/
+
+  /* Perform a sanity check on the return type */
+  FFI_ASSERT_VALID_TYPE(cif->rtype);
+
+  /* x86-64 and s390 stack space allocation is handled in prep_machdep.  */
+#if !defined M68K && !defined __x86_64__ && !defined S390 && !defined PA
+  /* Make space for the return structure pointer */
+  if (cif->rtype->type == FFI_TYPE_STRUCT
+#ifdef SPARC
+      && (cif->abi != FFI_V9 || cif->rtype->size > 32)
+#endif
+#ifdef X86_DARWIN
+
+      && (struct_on_stack(cif->rtype->size))
+#endif
+      )
+    bytes = STACK_ARG_SIZE(sizeof(void*));
+#endif
+
+  for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
+    {
+
+      /* Initialize any uninitialized aggregate type definitions */
+      if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK))
+	return FFI_BAD_TYPEDEF;
+
+      /* Perform a sanity check on the argument type, do this 
+	 check after the initialization.  */
+      FFI_ASSERT_VALID_TYPE(*ptr);
+
+#if defined(X86_DARWIN)
+      {
+	      int align = (*ptr)->alignment;
+	      if (align > 4) align = 4;
+	      if ((align - 1) & bytes)
+		 bytes = ALIGN(bytes, align);
+	      bytes += STACK_ARG_SIZE((*ptr)->size);
+      }
+
+#elif !defined __x86_64__ && !defined S390 && !defined PA
+#ifdef SPARC
+      if (((*ptr)->type == FFI_TYPE_STRUCT
+	   && ((*ptr)->size > 16 || cif->abi != FFI_V9))
+	  || ((*ptr)->type == FFI_TYPE_LONGDOUBLE
+	      && cif->abi != FFI_V9))
+	bytes += sizeof(void*);
+      else
+#endif
+	{
+	  /* Add any padding if necessary */
+	  if (((*ptr)->alignment - 1) & bytes)
+	    bytes = ALIGN(bytes, (*ptr)->alignment);
+	  
+	  bytes += STACK_ARG_SIZE((*ptr)->size);
+	}
+#endif
+    }
+
+  cif->bytes = bytes;
+
+  /* Perform machine dependent cif processing */
+  return ffi_prep_cif_machdep(cif);
+}
+#endif /* not __CRIS__ */

Added: vendor/Python/current/Modules/_ctypes/libffi/src/s390/ffi.c
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/s390/ffi.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/s390/ffi.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,751 @@
+/* -----------------------------------------------------------------------
+   ffi.c - Copyright (c) 2000 Software AG
+ 
+   S390 Foreign Function Interface
+ 
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+ 
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+ 
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+/*====================================================================*/
+/*                          Includes                                  */
+/*                          --------                                  */
+/*====================================================================*/
+ 
+#include <ffi.h>
+#include <ffi_common.h>
+ 
+#include <stdlib.h>
+#include <stdio.h>
+ 
+/*====================== End of Includes =============================*/
+ 
+/*====================================================================*/
+/*                           Defines                                  */
+/*                           -------                                  */
+/*====================================================================*/
+
+/* Maximum number of GPRs available for argument passing.  */ 
+#define MAX_GPRARGS 5
+
+/* Maximum number of FPRs available for argument passing.  */ 
+#ifdef __s390x__
+#define MAX_FPRARGS 4
+#else
+#define MAX_FPRARGS 2
+#endif
+
+/* Round to multiple of 16.  */
+#define ROUND_SIZE(size) (((size) + 15) & ~15)
+
+/* If these values change, sysv.S must be adapted!  */
+#define FFI390_RET_VOID		0
+#define FFI390_RET_STRUCT	1
+#define FFI390_RET_FLOAT	2
+#define FFI390_RET_DOUBLE	3
+#define FFI390_RET_INT32	4
+#define FFI390_RET_INT64	5
+
+/*===================== End of Defines ===============================*/
+ 
+/*====================================================================*/
+/*                          Prototypes                                */
+/*                          ----------                                */
+/*====================================================================*/
+ 
+static void ffi_prep_args (unsigned char *, extended_cif *);
+void
+#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
+__attribute__ ((visibility ("hidden")))
+#endif
+ffi_closure_helper_SYSV (ffi_closure *, unsigned long *, 
+			 unsigned long long *, unsigned long *);
+
+/*====================== End of Prototypes ===========================*/
+ 
+/*====================================================================*/
+/*                          Externals                                 */
+/*                          ---------                                 */
+/*====================================================================*/
+ 
+extern void ffi_call_SYSV(unsigned,
+			  extended_cif *,
+			  void (*)(unsigned char *, extended_cif *),
+			  unsigned,
+			  void *,
+			  void (*fn)());
+
+extern void ffi_closure_SYSV(void);
+ 
+/*====================== End of Externals ============================*/
+ 
+/*====================================================================*/
+/*                                                                    */
+/* Name     - ffi_check_struct_type.                                  */
+/*                                                                    */
+/* Function - Determine if a structure can be passed within a         */
+/*            general purpose or floating point register.             */
+/*                                                                    */
+/*====================================================================*/
+ 
+static int
+ffi_check_struct_type (ffi_type *arg)
+{
+  size_t size = arg->size;
+
+  /* If the struct has just one element, look at that element
+     to find out whether to consider the struct as floating point.  */
+  while (arg->type == FFI_TYPE_STRUCT 
+         && arg->elements[0] && !arg->elements[1])
+    arg = arg->elements[0];
+
+  /* Structs of size 1, 2, 4, and 8 are passed in registers,
+     just like the corresponding int/float types.  */
+  switch (size)
+    {
+      case 1:
+        return FFI_TYPE_UINT8;
+
+      case 2:
+        return FFI_TYPE_UINT16;
+
+      case 4:
+	if (arg->type == FFI_TYPE_FLOAT)
+          return FFI_TYPE_FLOAT;
+	else
+	  return FFI_TYPE_UINT32;
+
+      case 8:
+	if (arg->type == FFI_TYPE_DOUBLE)
+          return FFI_TYPE_DOUBLE;
+	else
+	  return FFI_TYPE_UINT64;
+
+      default:
+	break;
+    }
+
+  /* Other structs are passed via a pointer to the data.  */
+  return FFI_TYPE_POINTER;
+}
+ 
+/*======================== End of Routine ============================*/
+ 
+/*====================================================================*/
+/*                                                                    */
+/* Name     - ffi_prep_args.                                          */
+/*                                                                    */
+/* Function - Prepare parameters for call to function.                */
+/*                                                                    */
+/* ffi_prep_args is called by the assembly routine once stack space   */
+/* has been allocated for the function's arguments.                   */
+/*                                                                    */
+/*====================================================================*/
+ 
+static void
+ffi_prep_args (unsigned char *stack, extended_cif *ecif)
+{
+  /* The stack space will be filled with those areas:
+
+	FPR argument register save area     (highest addresses)
+	GPR argument register save area
+	temporary struct copies
+	overflow argument area              (lowest addresses)
+
+     We set up the following pointers:
+
+        p_fpr: bottom of the FPR area (growing upwards)
+	p_gpr: bottom of the GPR area (growing upwards)
+	p_ov: bottom of the overflow area (growing upwards)
+	p_struct: top of the struct copy area (growing downwards)
+
+     All areas are kept aligned to twice the word size.  */
+
+  int gpr_off = ecif->cif->bytes;
+  int fpr_off = gpr_off + ROUND_SIZE (MAX_GPRARGS * sizeof (long));
+
+  unsigned long long *p_fpr = (unsigned long long *)(stack + fpr_off);
+  unsigned long *p_gpr = (unsigned long *)(stack + gpr_off);
+  unsigned char *p_struct = (unsigned char *)p_gpr;
+  unsigned long *p_ov = (unsigned long *)stack;
+
+  int n_fpr = 0;
+  int n_gpr = 0;
+  int n_ov = 0;
+
+  ffi_type **ptr;
+  void **p_argv = ecif->avalue;
+  int i;
+ 
+  /* If we returning a structure then we set the first parameter register
+     to the address of where we are returning this structure.  */
+
+  if (ecif->cif->flags == FFI390_RET_STRUCT)
+    p_gpr[n_gpr++] = (unsigned long) ecif->rvalue;
+
+  /* Now for the arguments.  */
+ 
+  for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
+       i > 0;
+       i--, ptr++, p_argv++)
+    {
+      void *arg = *p_argv;
+      int type = (*ptr)->type;
+
+      /* Check how a structure type is passed.  */
+      if (type == FFI_TYPE_STRUCT)
+	{
+	  type = ffi_check_struct_type (*ptr);
+
+	  /* If we pass the struct via pointer, copy the data.  */
+	  if (type == FFI_TYPE_POINTER)
+	    {
+	      p_struct -= ROUND_SIZE ((*ptr)->size);
+	      memcpy (p_struct, (char *)arg, (*ptr)->size);
+	      arg = &p_struct;
+	    }
+	}
+
+      /* Now handle all primitive int/pointer/float data types.  */
+      switch (type) 
+	{
+	  case FFI_TYPE_DOUBLE:
+	    if (n_fpr < MAX_FPRARGS)
+	      p_fpr[n_fpr++] = *(unsigned long long *) arg;
+	    else
+#ifdef __s390x__
+	      p_ov[n_ov++] = *(unsigned long *) arg;
+#else
+	      p_ov[n_ov++] = ((unsigned long *) arg)[0],
+	      p_ov[n_ov++] = ((unsigned long *) arg)[1];
+#endif
+	    break;
+	
+	  case FFI_TYPE_FLOAT:
+	    if (n_fpr < MAX_FPRARGS)
+	      p_fpr[n_fpr++] = (long long) *(unsigned int *) arg << 32;
+	    else
+	      p_ov[n_ov++] = *(unsigned int *) arg;
+	    break;
+
+	  case FFI_TYPE_POINTER:
+	    if (n_gpr < MAX_GPRARGS)
+	      p_gpr[n_gpr++] = (unsigned long)*(unsigned char **) arg;
+	    else
+	      p_ov[n_ov++] = (unsigned long)*(unsigned char **) arg;
+	    break;
+ 
+	  case FFI_TYPE_UINT64:
+	  case FFI_TYPE_SINT64:
+#ifdef __s390x__
+	    if (n_gpr < MAX_GPRARGS)
+	      p_gpr[n_gpr++] = *(unsigned long *) arg;
+	    else
+	      p_ov[n_ov++] = *(unsigned long *) arg;
+#else
+	    if (n_gpr == MAX_GPRARGS-1)
+	      n_gpr = MAX_GPRARGS;
+	    if (n_gpr < MAX_GPRARGS)
+	      p_gpr[n_gpr++] = ((unsigned long *) arg)[0],
+	      p_gpr[n_gpr++] = ((unsigned long *) arg)[1];
+	    else
+	      p_ov[n_ov++] = ((unsigned long *) arg)[0],
+	      p_ov[n_ov++] = ((unsigned long *) arg)[1];
+#endif
+	    break;
+ 
+	  case FFI_TYPE_UINT32:
+	    if (n_gpr < MAX_GPRARGS)
+	      p_gpr[n_gpr++] = *(unsigned int *) arg;
+	    else
+	      p_ov[n_ov++] = *(unsigned int *) arg;
+	    break;
+ 
+	  case FFI_TYPE_INT:
+	  case FFI_TYPE_SINT32:
+	    if (n_gpr < MAX_GPRARGS)
+	      p_gpr[n_gpr++] = *(signed int *) arg;
+	    else
+	      p_ov[n_ov++] = *(signed int *) arg;
+	    break;
+ 
+	  case FFI_TYPE_UINT16:
+	    if (n_gpr < MAX_GPRARGS)
+	      p_gpr[n_gpr++] = *(unsigned short *) arg;
+	    else
+	      p_ov[n_ov++] = *(unsigned short *) arg;
+	    break;
+ 
+	  case FFI_TYPE_SINT16:
+	    if (n_gpr < MAX_GPRARGS)
+	      p_gpr[n_gpr++] = *(signed short *) arg;
+	    else
+	      p_ov[n_ov++] = *(signed short *) arg;
+	    break;
+
+	  case FFI_TYPE_UINT8:
+	    if (n_gpr < MAX_GPRARGS)
+	      p_gpr[n_gpr++] = *(unsigned char *) arg;
+	    else
+	      p_ov[n_ov++] = *(unsigned char *) arg;
+	    break;
+ 
+	  case FFI_TYPE_SINT8:
+	    if (n_gpr < MAX_GPRARGS)
+	      p_gpr[n_gpr++] = *(signed char *) arg;
+	    else
+	      p_ov[n_ov++] = *(signed char *) arg;
+	    break;
+ 
+	  default:
+	    FFI_ASSERT (0);
+	    break;
+        }
+    }
+}
+
+/*======================== End of Routine ============================*/
+ 
+/*====================================================================*/
+/*                                                                    */
+/* Name     - ffi_prep_cif_machdep.                                   */
+/*                                                                    */
+/* Function - Perform machine dependent CIF processing.               */
+/*                                                                    */
+/*====================================================================*/
+ 
+ffi_status
+ffi_prep_cif_machdep(ffi_cif *cif)
+{
+  size_t struct_size = 0;
+  int n_gpr = 0;
+  int n_fpr = 0;
+  int n_ov = 0;
+
+  ffi_type **ptr;
+  int i;
+
+  /* Determine return value handling.  */ 
+
+  switch (cif->rtype->type)
+    {
+      /* Void is easy.  */
+      case FFI_TYPE_VOID:
+	cif->flags = FFI390_RET_VOID;
+	break;
+
+      /* Structures are returned via a hidden pointer.  */
+      case FFI_TYPE_STRUCT:
+	cif->flags = FFI390_RET_STRUCT;
+	n_gpr++;  /* We need one GPR to pass the pointer.  */
+	break; 
+
+      /* Floating point values are returned in fpr 0.  */
+      case FFI_TYPE_FLOAT:
+	cif->flags = FFI390_RET_FLOAT;
+	break;
+
+      case FFI_TYPE_DOUBLE:
+	cif->flags = FFI390_RET_DOUBLE;
+	break;
+
+      /* Integer values are returned in gpr 2 (and gpr 3
+	 for 64-bit values on 31-bit machines).  */
+      case FFI_TYPE_UINT64:
+      case FFI_TYPE_SINT64:
+	cif->flags = FFI390_RET_INT64;
+	break;
+
+      case FFI_TYPE_POINTER:
+      case FFI_TYPE_INT:
+      case FFI_TYPE_UINT32:
+      case FFI_TYPE_SINT32:
+      case FFI_TYPE_UINT16:
+      case FFI_TYPE_SINT16:
+      case FFI_TYPE_UINT8:
+      case FFI_TYPE_SINT8:
+	/* These are to be extended to word size.  */
+#ifdef __s390x__
+	cif->flags = FFI390_RET_INT64;
+#else
+	cif->flags = FFI390_RET_INT32;
+#endif
+	break;
+ 
+      default:
+        FFI_ASSERT (0);
+        break;
+    }
+
+  /* Now for the arguments.  */
+ 
+  for (ptr = cif->arg_types, i = cif->nargs;
+       i > 0;
+       i--, ptr++)
+    {
+      int type = (*ptr)->type;
+
+      /* Check how a structure type is passed.  */
+      if (type == FFI_TYPE_STRUCT)
+	{
+	  type = ffi_check_struct_type (*ptr);
+
+	  /* If we pass the struct via pointer, we must reserve space
+	     to copy its data for proper call-by-value semantics.  */
+	  if (type == FFI_TYPE_POINTER)
+	    struct_size += ROUND_SIZE ((*ptr)->size);
+	}
+
+      /* Now handle all primitive int/float data types.  */
+      switch (type) 
+	{
+	  /* The first MAX_FPRARGS floating point arguments
+	     go in FPRs, the rest overflow to the stack.  */
+
+	  case FFI_TYPE_DOUBLE:
+	    if (n_fpr < MAX_FPRARGS)
+	      n_fpr++;
+	    else
+	      n_ov += sizeof (double) / sizeof (long);
+	    break;
+	
+	  case FFI_TYPE_FLOAT:
+	    if (n_fpr < MAX_FPRARGS)
+	      n_fpr++;
+	    else
+	      n_ov++;
+	    break;
+
+	  /* On 31-bit machines, 64-bit integers are passed in GPR pairs,
+	     if one is still available, or else on the stack.  If only one
+	     register is free, skip the register (it won't be used for any 
+	     subsequent argument either).  */
+	      
+#ifndef __s390x__
+	  case FFI_TYPE_UINT64:
+	  case FFI_TYPE_SINT64:
+	    if (n_gpr == MAX_GPRARGS-1)
+	      n_gpr = MAX_GPRARGS;
+	    if (n_gpr < MAX_GPRARGS)
+	      n_gpr += 2;
+	    else
+	      n_ov += 2;
+	    break;
+#endif
+
+	  /* Everything else is passed in GPRs (until MAX_GPRARGS
+	     have been used) or overflows to the stack.  */
+
+	  default: 
+	    if (n_gpr < MAX_GPRARGS)
+	      n_gpr++;
+	    else
+	      n_ov++;
+	    break;
+        }
+    }
+
+  /* Total stack space as required for overflow arguments
+     and temporary structure copies.  */
+
+  cif->bytes = ROUND_SIZE (n_ov * sizeof (long)) + struct_size;
+ 
+  return FFI_OK;
+}
+ 
+/*======================== End of Routine ============================*/
+ 
+/*====================================================================*/
+/*                                                                    */
+/* Name     - ffi_call.                                               */
+/*                                                                    */
+/* Function - Call the FFI routine.                                   */
+/*                                                                    */
+/*====================================================================*/
+ 
+void
+ffi_call(ffi_cif *cif,
+	 void (*fn)(),
+	 void *rvalue,
+	 void **avalue)
+{
+  int ret_type = cif->flags;
+  extended_cif ecif;
+ 
+  ecif.cif    = cif;
+  ecif.avalue = avalue;
+  ecif.rvalue = rvalue;
+
+  /* If we don't have a return value, we need to fake one.  */
+  if (rvalue == NULL)
+    {
+      if (ret_type == FFI390_RET_STRUCT)
+	ecif.rvalue = alloca (cif->rtype->size);
+      else
+	ret_type = FFI390_RET_VOID;
+    } 
+
+  switch (cif->abi)
+    {
+      case FFI_SYSV:
+        ffi_call_SYSV (cif->bytes, &ecif, ffi_prep_args,
+		       ret_type, ecif.rvalue, fn);
+        break;
+ 
+      default:
+        FFI_ASSERT (0);
+        break;
+    }
+}
+ 
+/*======================== End of Routine ============================*/
+
+/*====================================================================*/
+/*                                                                    */
+/* Name     - ffi_closure_helper_SYSV.                                */
+/*                                                                    */
+/* Function - Call a FFI closure target function.                     */
+/*                                                                    */
+/*====================================================================*/
+ 
+void
+ffi_closure_helper_SYSV (ffi_closure *closure,
+			 unsigned long *p_gpr,
+			 unsigned long long *p_fpr,
+			 unsigned long *p_ov)
+{
+  unsigned long long ret_buffer;
+
+  void *rvalue = &ret_buffer;
+  void **avalue;
+  void **p_arg;
+
+  int n_gpr = 0;
+  int n_fpr = 0;
+  int n_ov = 0;
+
+  ffi_type **ptr;
+  int i;
+
+  /* Allocate buffer for argument list pointers.  */
+
+  p_arg = avalue = alloca (closure->cif->nargs * sizeof (void *));
+
+  /* If we returning a structure, pass the structure address 
+     directly to the target function.  Otherwise, have the target 
+     function store the return value to the GPR save area.  */
+
+  if (closure->cif->flags == FFI390_RET_STRUCT)
+    rvalue = (void *) p_gpr[n_gpr++];
+
+  /* Now for the arguments.  */
+
+  for (ptr = closure->cif->arg_types, i = closure->cif->nargs;
+       i > 0;
+       i--, p_arg++, ptr++)
+    {
+      int deref_struct_pointer = 0;
+      int type = (*ptr)->type;
+
+      /* Check how a structure type is passed.  */
+      if (type == FFI_TYPE_STRUCT)
+	{
+	  type = ffi_check_struct_type (*ptr);
+
+	  /* If we pass the struct via pointer, remember to 
+	     retrieve the pointer later.  */
+	  if (type == FFI_TYPE_POINTER)
+	    deref_struct_pointer = 1;
+	}
+
+      /* Pointers are passed like UINTs of the same size.  */
+      if (type == FFI_TYPE_POINTER)
+#ifdef __s390x__
+	type = FFI_TYPE_UINT64;
+#else
+	type = FFI_TYPE_UINT32;
+#endif
+
+      /* Now handle all primitive int/float data types.  */
+      switch (type) 
+	{
+	  case FFI_TYPE_DOUBLE:
+	    if (n_fpr < MAX_FPRARGS)
+	      *p_arg = &p_fpr[n_fpr++];
+	    else
+	      *p_arg = &p_ov[n_ov], 
+	      n_ov += sizeof (double) / sizeof (long);
+	    break;
+	
+	  case FFI_TYPE_FLOAT:
+	    if (n_fpr < MAX_FPRARGS)
+	      *p_arg = &p_fpr[n_fpr++];
+	    else
+	      *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 4;
+	    break;
+ 
+	  case FFI_TYPE_UINT64:
+	  case FFI_TYPE_SINT64:
+#ifdef __s390x__
+	    if (n_gpr < MAX_GPRARGS)
+	      *p_arg = &p_gpr[n_gpr++];
+	    else
+	      *p_arg = &p_ov[n_ov++];
+#else
+	    if (n_gpr == MAX_GPRARGS-1)
+	      n_gpr = MAX_GPRARGS;
+	    if (n_gpr < MAX_GPRARGS)
+	      *p_arg = &p_gpr[n_gpr], n_gpr += 2;
+	    else
+	      *p_arg = &p_ov[n_ov], n_ov += 2;
+#endif
+	    break;
+ 
+	  case FFI_TYPE_INT:
+	  case FFI_TYPE_UINT32:
+	  case FFI_TYPE_SINT32:
+	    if (n_gpr < MAX_GPRARGS)
+	      *p_arg = (char *)&p_gpr[n_gpr++] + sizeof (long) - 4;
+	    else
+	      *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 4;
+	    break;
+ 
+	  case FFI_TYPE_UINT16:
+	  case FFI_TYPE_SINT16:
+	    if (n_gpr < MAX_GPRARGS)
+	      *p_arg = (char *)&p_gpr[n_gpr++] + sizeof (long) - 2;
+	    else
+	      *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 2;
+	    break;
+
+	  case FFI_TYPE_UINT8:
+	  case FFI_TYPE_SINT8:
+	    if (n_gpr < MAX_GPRARGS)
+	      *p_arg = (char *)&p_gpr[n_gpr++] + sizeof (long) - 1;
+	    else
+	      *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 1;
+	    break;
+ 
+	  default:
+	    FFI_ASSERT (0);
+	    break;
+        }
+
+      /* If this is a struct passed via pointer, we need to
+	 actually retrieve that pointer.  */
+      if (deref_struct_pointer)
+	*p_arg = *(void **)*p_arg;
+    }
+
+
+  /* Call the target function.  */
+  (closure->fun) (closure->cif, rvalue, avalue, closure->user_data);
+
+  /* Convert the return value.  */
+  switch (closure->cif->rtype->type)
+    {
+      /* Void is easy, and so is struct.  */
+      case FFI_TYPE_VOID:
+      case FFI_TYPE_STRUCT:
+	break;
+
+      /* Floating point values are returned in fpr 0.  */
+      case FFI_TYPE_FLOAT:
+	p_fpr[0] = (long long) *(unsigned int *) rvalue << 32;
+	break;
+
+      case FFI_TYPE_DOUBLE:
+	p_fpr[0] = *(unsigned long long *) rvalue;
+	break;
+
+      /* Integer values are returned in gpr 2 (and gpr 3
+	 for 64-bit values on 31-bit machines).  */
+      case FFI_TYPE_UINT64:
+      case FFI_TYPE_SINT64:
+#ifdef __s390x__
+	p_gpr[0] = *(unsigned long *) rvalue;
+#else
+	p_gpr[0] = ((unsigned long *) rvalue)[0],
+	p_gpr[1] = ((unsigned long *) rvalue)[1];
+#endif
+	break;
+
+      case FFI_TYPE_POINTER:
+      case FFI_TYPE_UINT32:
+      case FFI_TYPE_UINT16:
+      case FFI_TYPE_UINT8:
+	p_gpr[0] = *(unsigned long *) rvalue;
+	break;
+
+      case FFI_TYPE_INT:
+      case FFI_TYPE_SINT32:
+      case FFI_TYPE_SINT16:
+      case FFI_TYPE_SINT8:
+	p_gpr[0] = *(signed long *) rvalue;
+	break;
+
+      default:
+        FFI_ASSERT (0);
+        break;
+    }
+}
+ 
+/*======================== End of Routine ============================*/
+
+/*====================================================================*/
+/*                                                                    */
+/* Name     - ffi_prep_closure.                                       */
+/*                                                                    */
+/* Function - Prepare a FFI closure.                                  */
+/*                                                                    */
+/*====================================================================*/
+ 
+ffi_status
+ffi_prep_closure (ffi_closure *closure,
+                  ffi_cif *cif,
+                  void (*fun) (ffi_cif *, void *, void **, void *),
+                  void *user_data)
+{
+  FFI_ASSERT (cif->abi == FFI_SYSV);
+
+#ifndef __s390x__
+  *(short *)&closure->tramp [0] = 0x0d10;   /* basr %r1,0 */
+  *(short *)&closure->tramp [2] = 0x9801;   /* lm %r0,%r1,6(%r1) */
+  *(short *)&closure->tramp [4] = 0x1006;
+  *(short *)&closure->tramp [6] = 0x07f1;   /* br %r1 */
+  *(long  *)&closure->tramp [8] = (long)closure;
+  *(long  *)&closure->tramp[12] = (long)&ffi_closure_SYSV;
+#else
+  *(short *)&closure->tramp [0] = 0x0d10;   /* basr %r1,0 */
+  *(short *)&closure->tramp [2] = 0xeb01;   /* lmg %r0,%r1,14(%r1) */
+  *(short *)&closure->tramp [4] = 0x100e;
+  *(short *)&closure->tramp [6] = 0x0004;
+  *(short *)&closure->tramp [8] = 0x07f1;   /* br %r1 */
+  *(long  *)&closure->tramp[16] = (long)closure;
+  *(long  *)&closure->tramp[24] = (long)&ffi_closure_SYSV;
+#endif 
+ 
+  closure->cif = cif;
+  closure->user_data = user_data;
+  closure->fun = fun;
+ 
+  return FFI_OK;
+}
+
+/*======================== End of Routine ============================*/
+ 

Added: vendor/Python/current/Modules/_ctypes/libffi/src/s390/ffitarget.h
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/s390/ffitarget.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/s390/ffitarget.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,59 @@
+/* -----------------------------------------------------------------*-C-*-
+   ffitarget.h - Copyright (c) 1996-2003  Red Hat, Inc.
+   Target configuration macros for S390.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+
+   ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+#if defined (__s390x__)
+#define S390X
+#endif
+
+/* ---- System specific configurations ----------------------------------- */
+
+#ifndef LIBFFI_ASM
+typedef unsigned long          ffi_arg;
+typedef signed long            ffi_sarg;
+
+typedef enum ffi_abi {
+  FFI_FIRST_ABI = 0,
+  FFI_SYSV,
+  FFI_DEFAULT_ABI = FFI_SYSV,
+  FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
+} ffi_abi;
+#endif
+
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#define FFI_CLOSURES 1
+#ifdef S390X
+#define FFI_TRAMPOLINE_SIZE 32
+#else
+#define FFI_TRAMPOLINE_SIZE 16
+#endif
+#define FFI_NATIVE_RAW_API 0
+
+#endif
+

Added: vendor/Python/current/Modules/_ctypes/libffi/src/s390/sysv.S
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/s390/sysv.S	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/s390/sysv.S	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,429 @@
+/* -----------------------------------------------------------------------
+   sysv.S - Copyright (c) 2000 Software AG
+ 
+   S390 Foreign Function Interface
+ 
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+ 
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+ 
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+
+#ifndef __s390x__
+ 
+.text
+
+	# r2:	cif->bytes
+	# r3:	&ecif
+	# r4:	ffi_prep_args
+	# r5:	ret_type
+	# r6:	ecif.rvalue
+	# ov:	fn 
+ 
+	# This assumes we are using gas.
+	.globl	ffi_call_SYSV
+	.type	ffi_call_SYSV,%function
+ffi_call_SYSV:
+.LFB1:
+	stm	%r6,%r15,24(%r15)		# Save registers
+.LCFI0:
+	basr	%r13,0				# Set up base register
+.Lbase:
+	lr	%r11,%r15			# Set up frame pointer
+.LCFI1:
+	sr	%r15,%r2
+	ahi	%r15,-96-48			# Allocate stack
+	lr	%r8,%r6				# Save ecif.rvalue
+	sr	%r9,%r9
+	ic	%r9,.Ltable-.Lbase(%r13,%r5)	# Load epilog address
+	l	%r7,96(%r11)			# Load function address
+	st	%r11,0(%r15)			# Set up back chain
+	ahi	%r11,-48			# Register save area
+.LCFI2:
+
+	la	%r2,96(%r15)			# Save area
+						# r3 already holds &ecif
+	basr	%r14,%r4			# Call ffi_prep_args
+
+	lm	%r2,%r6,0(%r11)			# Load arguments
+	ld	%f0,32(%r11)
+	ld	%f2,40(%r11)
+	la	%r14,0(%r13,%r9)		# Set return address
+	br	%r7				# ... and call function
+
+.LretNone:					# Return void
+	l	%r4,48+56(%r11)
+	lm	%r6,%r15,48+24(%r11)
+	br	%r4
+
+.LretFloat:
+	l	%r4,48+56(%r11)
+	ste	%f0,0(%r8)			# Return float
+	lm	%r6,%r15,48+24(%r11)
+	br	%r4
+ 
+.LretDouble:
+	l	%r4,48+56(%r11)
+	std	%f0,0(%r8)			# Return double
+	lm	%r6,%r15,48+24(%r11)
+	br	%r4
+
+.LretInt32:
+	l	%r4,48+56(%r11)
+	st	%r2,0(%r8)			# Return int
+	lm	%r6,%r15,48+24(%r11)
+	br	%r4
+ 
+.LretInt64:
+	l	%r4,48+56(%r11)
+	stm	%r2,%r3,0(%r8)			# Return long long
+	lm	%r6,%r15,48+24(%r11)
+	br	%r4
+ 
+.Ltable:
+	.byte	.LretNone-.Lbase		# FFI390_RET_VOID
+	.byte	.LretNone-.Lbase		# FFI390_RET_STRUCT
+	.byte	.LretFloat-.Lbase		# FFI390_RET_FLOAT
+	.byte	.LretDouble-.Lbase		# FFI390_RET_DOUBLE
+	.byte	.LretInt32-.Lbase		# FFI390_RET_INT32
+	.byte	.LretInt64-.Lbase		# FFI390_RET_INT64
+
+.LFE1: 
+.ffi_call_SYSV_end:
+	.size	 ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
+
+
+	.globl	ffi_closure_SYSV
+	.type	ffi_closure_SYSV,%function
+ffi_closure_SYSV:
+.LFB2:
+	stm	%r12,%r15,48(%r15)		# Save registers
+.LCFI10:
+	basr	%r13,0				# Set up base register
+.Lcbase:
+	stm	%r2,%r6,8(%r15)			# Save arguments
+	std	%f0,64(%r15)
+	std	%f2,72(%r15)
+	lr	%r1,%r15			# Set up stack frame
+	ahi	%r15,-96
+.LCFI11:
+	l	%r12,.Lchelper-.Lcbase(%r13)	# Get helper function
+	lr	%r2,%r0				# Closure
+	la	%r3,8(%r1)			# GPRs
+	la	%r4,64(%r1)			# FPRs
+	la	%r5,96(%r1)			# Overflow
+	st	%r1,0(%r15)			# Set up back chain
+
+	bas	%r14,0(%r12,%r13)		# Call helper
+
+	l	%r4,96+56(%r15)
+	ld	%f0,96+64(%r15)			# Load return registers
+	lm	%r2,%r3,96+8(%r15)
+	lm	%r12,%r15,96+48(%r15)
+	br	%r4
+
+	.align 4
+.Lchelper:
+	.long	ffi_closure_helper_SYSV-.Lcbase
+
+.LFE2: 
+
+.ffi_closure_SYSV_end:
+	.size	 ffi_closure_SYSV,.ffi_closure_SYSV_end-ffi_closure_SYSV
+
+
+	.section	.eh_frame,EH_FRAME_FLAGS, at progbits
+.Lframe1:
+	.4byte	.LECIE1-.LSCIE1	# Length of Common Information Entry
+.LSCIE1:
+	.4byte	0x0	# CIE Identifier Tag
+	.byte	0x1	# CIE Version
+	.ascii "zR\0"	# CIE Augmentation
+	.uleb128 0x1	# CIE Code Alignment Factor
+	.sleb128 -4	# CIE Data Alignment Factor
+	.byte	0xe	# CIE RA Column
+	.uleb128 0x1	# Augmentation size
+	.byte	0x1b	# FDE Encoding (pcrel sdata4)
+	.byte	0xc	# DW_CFA_def_cfa
+	.uleb128 0xf
+	.uleb128 0x60
+	.align	4
+.LECIE1:
+.LSFDE1:
+	.4byte	.LEFDE1-.LASFDE1	# FDE Length
+.LASFDE1:
+	.4byte	.LASFDE1-.Lframe1	# FDE CIE offset
+	.4byte	.LFB1-.	# FDE initial location
+	.4byte	.LFE1-.LFB1	# FDE address range
+	.uleb128 0x0	# Augmentation size
+	.byte	0x4	# DW_CFA_advance_loc4
+	.4byte	.LCFI0-.LFB1
+	.byte	0x8f	# DW_CFA_offset, column 0xf
+	.uleb128 0x9
+	.byte	0x8e	# DW_CFA_offset, column 0xe
+	.uleb128 0xa
+	.byte	0x8d	# DW_CFA_offset, column 0xd
+	.uleb128 0xb
+	.byte	0x8c	# DW_CFA_offset, column 0xc
+	.uleb128 0xc
+	.byte	0x8b	# DW_CFA_offset, column 0xb
+	.uleb128 0xd
+	.byte	0x8a	# DW_CFA_offset, column 0xa
+	.uleb128 0xe
+	.byte	0x89	# DW_CFA_offset, column 0x9
+	.uleb128 0xf
+	.byte	0x88	# DW_CFA_offset, column 0x8
+	.uleb128 0x10
+	.byte	0x87	# DW_CFA_offset, column 0x7
+	.uleb128 0x11
+	.byte	0x86	# DW_CFA_offset, column 0x6
+	.uleb128 0x12
+	.byte	0x4	# DW_CFA_advance_loc4
+	.4byte	.LCFI1-.LCFI0
+	.byte	0xd	# DW_CFA_def_cfa_register
+	.uleb128 0xb
+	.byte	0x4	# DW_CFA_advance_loc4
+	.4byte	.LCFI2-.LCFI1
+	.byte	0xe	# DW_CFA_def_cfa_offset
+	.uleb128 0x90
+	.align	4
+.LEFDE1:
+.LSFDE2:
+	.4byte	.LEFDE2-.LASFDE2	# FDE Length
+.LASFDE2:
+	.4byte	.LASFDE2-.Lframe1	# FDE CIE offset
+	.4byte	.LFB2-.	# FDE initial location
+	.4byte	.LFE2-.LFB2	# FDE address range
+	.uleb128 0x0	# Augmentation size
+	.byte	0x4	# DW_CFA_advance_loc4
+	.4byte	.LCFI10-.LFB2
+	.byte	0x8f	# DW_CFA_offset, column 0xf
+	.uleb128 0x9
+	.byte	0x8e	# DW_CFA_offset, column 0xe
+	.uleb128 0xa
+	.byte	0x8d	# DW_CFA_offset, column 0xd
+	.uleb128 0xb
+	.byte	0x8c	# DW_CFA_offset, column 0xc
+	.uleb128 0xc
+	.byte	0x4	# DW_CFA_advance_loc4
+	.4byte	.LCFI11-.LCFI10
+	.byte	0xe	# DW_CFA_def_cfa_offset
+	.uleb128 0xc0
+	.align	4
+.LEFDE2:
+
+#else
+ 
+.text
+ 
+	# r2:	cif->bytes
+	# r3:	&ecif
+	# r4:	ffi_prep_args
+	# r5:	ret_type
+	# r6:	ecif.rvalue
+	# ov:	fn 
+ 
+	# This assumes we are using gas.
+	.globl	ffi_call_SYSV
+	.type	ffi_call_SYSV,%function
+ffi_call_SYSV:
+.LFB1:
+	stmg	%r6,%r15,48(%r15)		# Save registers
+.LCFI0:
+	larl	%r13,.Lbase			# Set up base register
+	lgr	%r11,%r15			# Set up frame pointer
+.LCFI1:
+	sgr	%r15,%r2
+	aghi	%r15,-160-80			# Allocate stack
+	lgr	%r8,%r6				# Save ecif.rvalue
+	llgc	%r9,.Ltable-.Lbase(%r13,%r5)	# Load epilog address
+	lg	%r7,160(%r11)			# Load function address
+	stg	%r11,0(%r15)			# Set up back chain
+	aghi	%r11,-80			# Register save area
+.LCFI2:
+
+	la	%r2,160(%r15)			# Save area
+						# r3 already holds &ecif
+	basr	%r14,%r4			# Call ffi_prep_args
+
+	lmg	%r2,%r6,0(%r11)			# Load arguments
+	ld	%f0,48(%r11)
+	ld	%f2,56(%r11)
+	ld	%f4,64(%r11)
+	ld	%f6,72(%r11)
+	la	%r14,0(%r13,%r9)		# Set return address
+	br	%r7				# ... and call function
+
+.Lbase:
+.LretNone:					# Return void
+	lg	%r4,80+112(%r11)
+	lmg	%r6,%r15,80+48(%r11)
+	br	%r4
+
+.LretFloat:
+	lg	%r4,80+112(%r11)
+	ste	%f0,0(%r8)			# Return float
+	lmg	%r6,%r15,80+48(%r11)
+	br	%r4
+ 
+.LretDouble:
+	lg	%r4,80+112(%r11)
+	std	%f0,0(%r8)			# Return double
+	lmg	%r6,%r15,80+48(%r11)
+	br	%r4
+
+.LretInt32:
+	lg	%r4,80+112(%r11)
+	st	%r2,0(%r8)			# Return int
+	lmg	%r6,%r15,80+48(%r11)
+	br	%r4
+ 
+.LretInt64:
+	lg	%r4,80+112(%r11)
+	stg	%r2,0(%r8)			# Return long
+	lmg	%r6,%r15,80+48(%r11)
+	br	%r4
+ 
+.Ltable:
+	.byte	.LretNone-.Lbase		# FFI390_RET_VOID
+	.byte	.LretNone-.Lbase		# FFI390_RET_STRUCT
+	.byte	.LretFloat-.Lbase		# FFI390_RET_FLOAT
+	.byte	.LretDouble-.Lbase		# FFI390_RET_DOUBLE
+	.byte	.LretInt32-.Lbase		# FFI390_RET_INT32
+	.byte	.LretInt64-.Lbase		# FFI390_RET_INT64
+
+.LFE1: 
+.ffi_call_SYSV_end:
+	.size	 ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
+
+
+	.globl	ffi_closure_SYSV
+	.type	ffi_closure_SYSV,%function
+ffi_closure_SYSV:
+.LFB2:
+	stmg	%r14,%r15,112(%r15)		# Save registers
+.LCFI10:
+	stmg	%r2,%r6,16(%r15)		# Save arguments
+	std	%f0,128(%r15)
+	std	%f2,136(%r15)
+	std	%f4,144(%r15)
+	std	%f6,152(%r15)
+	lgr	%r1,%r15			# Set up stack frame
+	aghi	%r15,-160
+.LCFI11:
+	lgr	%r2,%r0				# Closure
+	la	%r3,16(%r1)			# GPRs
+	la	%r4,128(%r1)			# FPRs
+	la	%r5,160(%r1)			# Overflow
+	stg	%r1,0(%r15)			# Set up back chain
+
+	brasl	%r14,ffi_closure_helper_SYSV	# Call helper
+
+	lg	%r14,160+112(%r15)
+	ld	%f0,160+128(%r15)		# Load return registers
+	lg	%r2,160+16(%r15)
+	la	%r15,160(%r15)
+	br	%r14
+.LFE2: 
+
+.ffi_closure_SYSV_end:
+	.size	 ffi_closure_SYSV,.ffi_closure_SYSV_end-ffi_closure_SYSV
+
+
+
+	.section	.eh_frame,EH_FRAME_FLAGS, at progbits
+.Lframe1:
+	.4byte	.LECIE1-.LSCIE1	# Length of Common Information Entry
+.LSCIE1:
+	.4byte	0x0	# CIE Identifier Tag
+	.byte	0x1	# CIE Version
+	.ascii "zR\0"	# CIE Augmentation
+	.uleb128 0x1	# CIE Code Alignment Factor
+	.sleb128 -8	# CIE Data Alignment Factor
+	.byte	0xe	# CIE RA Column
+	.uleb128 0x1	# Augmentation size
+	.byte	0x1b	# FDE Encoding (pcrel sdata4)
+	.byte	0xc	# DW_CFA_def_cfa
+	.uleb128 0xf
+	.uleb128 0xa0
+	.align	8
+.LECIE1:
+.LSFDE1:
+	.4byte	.LEFDE1-.LASFDE1	# FDE Length
+.LASFDE1:
+	.4byte	.LASFDE1-.Lframe1	# FDE CIE offset
+	.4byte	.LFB1-.	# FDE initial location
+	.4byte	.LFE1-.LFB1	# FDE address range
+	.uleb128 0x0	# Augmentation size
+	.byte	0x4	# DW_CFA_advance_loc4
+	.4byte	.LCFI0-.LFB1
+	.byte	0x8f	# DW_CFA_offset, column 0xf
+	.uleb128 0x5
+	.byte	0x8e	# DW_CFA_offset, column 0xe
+	.uleb128 0x6
+	.byte	0x8d	# DW_CFA_offset, column 0xd
+	.uleb128 0x7
+	.byte	0x8c	# DW_CFA_offset, column 0xc
+	.uleb128 0x8
+	.byte	0x8b	# DW_CFA_offset, column 0xb
+	.uleb128 0x9
+	.byte	0x8a	# DW_CFA_offset, column 0xa
+	.uleb128 0xa
+	.byte	0x89	# DW_CFA_offset, column 0x9
+	.uleb128 0xb
+	.byte	0x88	# DW_CFA_offset, column 0x8
+	.uleb128 0xc
+	.byte	0x87	# DW_CFA_offset, column 0x7
+	.uleb128 0xd
+	.byte	0x86	# DW_CFA_offset, column 0x6
+	.uleb128 0xe
+	.byte	0x4	# DW_CFA_advance_loc4
+	.4byte	.LCFI1-.LCFI0
+	.byte	0xd	# DW_CFA_def_cfa_register
+	.uleb128 0xb
+	.byte	0x4	# DW_CFA_advance_loc4
+	.4byte	.LCFI2-.LCFI1
+	.byte	0xe	# DW_CFA_def_cfa_offset
+	.uleb128 0xf0
+	.align	8
+.LEFDE1:
+.LSFDE2:
+	.4byte	.LEFDE2-.LASFDE2	# FDE Length
+.LASFDE2:
+	.4byte	.LASFDE2-.Lframe1	# FDE CIE offset
+	.4byte	.LFB2-.	# FDE initial location
+	.4byte	.LFE2-.LFB2	# FDE address range
+	.uleb128 0x0	# Augmentation size
+	.byte	0x4	# DW_CFA_advance_loc4
+	.4byte	.LCFI10-.LFB2
+	.byte	0x8f	# DW_CFA_offset, column 0xf
+	.uleb128 0x5
+	.byte	0x8e	# DW_CFA_offset, column 0xe
+	.uleb128 0x6
+	.byte	0x4	# DW_CFA_advance_loc4
+	.4byte	.LCFI11-.LCFI10
+	.byte	0xe	# DW_CFA_def_cfa_offset
+	.uleb128 0x140
+	.align	8
+.LEFDE2:
+
+#endif
+

Added: vendor/Python/current/Modules/_ctypes/libffi/src/sh/ffi.c
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/sh/ffi.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/sh/ffi.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,728 @@
+/* -----------------------------------------------------------------------
+   ffi.c - Copyright (c) 2002, 2003, 2004, 2005 Kaz Kojima
+   
+   SuperH Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+
+#define NGREGARG 4
+#if defined(__SH4__)
+#define NFREGARG 8
+#endif
+
+#if defined(__HITACHI__)
+#define STRUCT_VALUE_ADDRESS_WITH_ARG 1
+#else
+#define STRUCT_VALUE_ADDRESS_WITH_ARG 0
+#endif
+
+/* If the structure has essentialy an unique element, return its type.  */
+static int
+simple_type (ffi_type *arg)
+{
+  if (arg->type != FFI_TYPE_STRUCT)
+    return arg->type;
+  else if (arg->elements[1])
+    return FFI_TYPE_STRUCT;
+
+  return simple_type (arg->elements[0]);
+}
+
+static int
+return_type (ffi_type *arg)
+{
+  unsigned short type;
+
+  if (arg->type != FFI_TYPE_STRUCT)
+    return arg->type;
+
+  type = simple_type (arg->elements[0]);
+  if (! arg->elements[1])
+    {
+      switch (type)
+	{
+	case FFI_TYPE_SINT8:
+	case FFI_TYPE_UINT8:
+	case FFI_TYPE_SINT16:
+	case FFI_TYPE_UINT16:
+	case FFI_TYPE_SINT32:
+	case FFI_TYPE_UINT32:
+	  return FFI_TYPE_INT;
+
+	default:
+	  return type;
+	}
+    }
+
+  /* gcc uses r0/r1 pair for some kind of structures.  */
+  if (arg->size <= 2 * sizeof (int))
+    {
+      int i = 0;
+      ffi_type *e;
+
+      while ((e = arg->elements[i++]))
+	{
+	  type = simple_type (e);
+	  switch (type)
+	    {
+	    case FFI_TYPE_SINT32:
+	    case FFI_TYPE_UINT32:
+	    case FFI_TYPE_INT:
+	    case FFI_TYPE_FLOAT:
+	      return FFI_TYPE_UINT64;
+
+	    default:
+	      break;
+	    }
+	}
+    }
+
+  return FFI_TYPE_STRUCT;
+}
+
+/* ffi_prep_args is called by the assembly routine once stack space
+   has been allocated for the function's arguments */
+
+/*@-exportheader@*/
+void ffi_prep_args(char *stack, extended_cif *ecif)
+/*@=exportheader@*/
+{
+  register unsigned int i;
+  register int tmp;
+  register unsigned int avn;
+  register void **p_argv;
+  register char *argp;
+  register ffi_type **p_arg;
+  int greg, ireg;
+#if defined(__SH4__)
+  int freg = 0;
+#endif
+
+  tmp = 0;
+  argp = stack;
+
+  if (return_type (ecif->cif->rtype) == FFI_TYPE_STRUCT)
+    {
+      *(void **) argp = ecif->rvalue;
+      argp += 4;
+      ireg = STRUCT_VALUE_ADDRESS_WITH_ARG ? 1 : 0;
+    }
+  else
+    ireg = 0;
+
+  /* Set arguments for registers.  */
+  greg = ireg;
+  avn = ecif->cif->nargs;
+  p_argv = ecif->avalue;
+
+  for (i = 0, p_arg = ecif->cif->arg_types; i < avn; i++, p_arg++, p_argv++)
+    {
+      size_t z;
+
+      z = (*p_arg)->size;
+      if (z < sizeof(int))
+	{
+	  if (greg++ >= NGREGARG)
+	    continue;
+
+	  z = sizeof(int);
+	  switch ((*p_arg)->type)
+	    {
+	    case FFI_TYPE_SINT8:
+	      *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
+	      break;
+  
+	    case FFI_TYPE_UINT8:
+	      *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
+	      break;
+  
+	    case FFI_TYPE_SINT16:
+	      *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
+	      break;
+  
+	    case FFI_TYPE_UINT16:
+	      *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
+	      break;
+  
+	    case FFI_TYPE_STRUCT:
+	      *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+	      break;
+
+	    default:
+	      FFI_ASSERT(0);
+	    }
+	  argp += z;
+	}
+      else if (z == sizeof(int))
+	{
+#if defined(__SH4__)
+	  if ((*p_arg)->type == FFI_TYPE_FLOAT)
+	    {
+	      if (freg++ >= NFREGARG)
+		continue;
+	    }
+	  else
+#endif
+	    {
+	      if (greg++ >= NGREGARG)
+		continue;
+	    }
+	  *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+	  argp += z;
+	}
+#if defined(__SH4__)
+      else if ((*p_arg)->type == FFI_TYPE_DOUBLE)
+	{
+	  if (freg + 1 >= NFREGARG)
+	    continue;
+	  freg = (freg + 1) & ~1;
+	  freg += 2;
+	  memcpy (argp, *p_argv, z);
+	  argp += z;
+	}
+#endif
+      else
+	{
+	  int n = (z + sizeof (int) - 1) / sizeof (int);
+#if defined(__SH4__)
+	  if (greg + n - 1 >= NGREGARG)
+	    continue;
+#else
+	  if (greg >= NGREGARG)
+	    continue;
+#endif
+	  greg += n;
+	  memcpy (argp, *p_argv, z);
+	  argp += n * sizeof (int);
+	}
+    }
+
+  /* Set arguments on stack.  */
+  greg = ireg;
+#if defined(__SH4__)
+  freg = 0;
+#endif
+  p_argv = ecif->avalue;
+
+  for (i = 0, p_arg = ecif->cif->arg_types; i < avn; i++, p_arg++, p_argv++)
+    {
+      size_t z;
+
+      z = (*p_arg)->size;
+      if (z < sizeof(int))
+	{
+	  if (greg++ < NGREGARG)
+	    continue;
+
+	  z = sizeof(int);
+	  switch ((*p_arg)->type)
+	    {
+	    case FFI_TYPE_SINT8:
+	      *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
+	      break;
+  
+	    case FFI_TYPE_UINT8:
+	      *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
+	      break;
+  
+	    case FFI_TYPE_SINT16:
+	      *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
+	      break;
+  
+	    case FFI_TYPE_UINT16:
+	      *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
+	      break;
+  
+	    case FFI_TYPE_STRUCT:
+	      *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+	      break;
+
+	    default:
+	      FFI_ASSERT(0);
+	    }
+	  argp += z;
+	}
+      else if (z == sizeof(int))
+	{
+#if defined(__SH4__)
+	  if ((*p_arg)->type == FFI_TYPE_FLOAT)
+	    {
+	      if (freg++ < NFREGARG)
+		continue;
+	    }
+	  else
+#endif
+	    {
+	      if (greg++ < NGREGARG)
+		continue;
+	    }
+	  *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+	  argp += z;
+	}
+#if defined(__SH4__)
+      else if ((*p_arg)->type == FFI_TYPE_DOUBLE)
+	{
+	  if (freg + 1 < NFREGARG)
+	    {
+	      freg = (freg + 1) & ~1;
+	      freg += 2;
+	      continue;
+	    }
+	  memcpy (argp, *p_argv, z);
+	  argp += z;
+	}
+#endif
+      else
+	{
+	  int n = (z + sizeof (int) - 1) / sizeof (int);
+	  if (greg + n - 1 < NGREGARG)
+	    {
+	      greg += n;
+	      continue;
+	    }
+#if (! defined(__SH4__))
+	  else if (greg < NGREGARG)
+	    {
+	      greg = NGREGARG;
+	      continue;
+	    }
+#endif
+	  memcpy (argp, *p_argv, z);
+	  argp += n * sizeof (int);
+	}
+    }
+
+  return;
+}
+
+/* Perform machine dependent cif processing */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+{
+  int i, j;
+  int size, type;
+  int n, m;
+  int greg;
+#if defined(__SH4__)
+  int freg = 0;
+#endif
+
+  cif->flags = 0;
+
+  greg = ((return_type (cif->rtype) == FFI_TYPE_STRUCT) &&
+	  STRUCT_VALUE_ADDRESS_WITH_ARG) ? 1 : 0;
+
+#if defined(__SH4__)
+  for (i = j = 0; i < cif->nargs && j < 12; i++)
+    {
+      type = (cif->arg_types)[i]->type;
+      switch (type)
+	{
+	case FFI_TYPE_FLOAT:
+	  if (freg >= NFREGARG)
+	    continue;
+	  freg++;
+	  cif->flags += ((cif->arg_types)[i]->type) << (2 * j);
+	  j++;
+	  break;
+
+	case FFI_TYPE_DOUBLE:
+	  if ((freg + 1) >= NFREGARG)
+	    continue;
+	  freg = (freg + 1) & ~1;
+	  freg += 2;
+	  cif->flags += ((cif->arg_types)[i]->type) << (2 * j);
+	  j++;
+	  break;
+	      
+	default:
+	  size = (cif->arg_types)[i]->size;
+	  n = (size + sizeof (int) - 1) / sizeof (int);
+	  if (greg + n - 1 >= NGREGARG)
+		continue;
+	  greg += n;
+	  for (m = 0; m < n; m++)
+	    cif->flags += FFI_TYPE_INT << (2 * j++);
+	  break;
+	}
+    }
+#else
+  for (i = j = 0; i < cif->nargs && j < 4; i++)
+    {
+      size = (cif->arg_types)[i]->size;
+      n = (size + sizeof (int) - 1) / sizeof (int);
+      if (greg >= NGREGARG)
+	continue;
+      else if (greg + n - 1 >= NGREGARG)
+	n = NGREGARG - greg;
+      greg += n;
+      for (m = 0; m < n; m++)
+        cif->flags += FFI_TYPE_INT << (2 * j++);
+    }
+#endif
+
+  /* Set the return type flag */
+  switch (cif->rtype->type)
+    {
+    case FFI_TYPE_STRUCT:
+      cif->flags += (unsigned) (return_type (cif->rtype)) << 24;
+      break;
+
+    case FFI_TYPE_VOID:
+    case FFI_TYPE_FLOAT:
+    case FFI_TYPE_DOUBLE:
+    case FFI_TYPE_SINT64:
+    case FFI_TYPE_UINT64:
+      cif->flags += (unsigned) cif->rtype->type << 24;
+      break;
+
+    default:
+      cif->flags += FFI_TYPE_INT << 24;
+      break;
+    }
+
+  return FFI_OK;
+}
+
+/*@-declundef@*/
+/*@-exportheader@*/
+extern void ffi_call_SYSV(void (*)(char *, extended_cif *), 
+			  /*@out@*/ extended_cif *, 
+			  unsigned, unsigned, 
+			  /*@out@*/ unsigned *, 
+			  void (*fn)());
+/*@=declundef@*/
+/*@=exportheader@*/
+
+void ffi_call(/*@dependent@*/ ffi_cif *cif, 
+	      void (*fn)(), 
+	      /*@out@*/ void *rvalue, 
+	      /*@dependent@*/ void **avalue)
+{
+  extended_cif ecif;
+  UINT64 trvalue;
+
+  ecif.cif = cif;
+  ecif.avalue = avalue;
+  
+  /* If the return value is a struct and we don't have a return	*/
+  /* value address then we need to make one		        */
+
+  if (cif->rtype->type == FFI_TYPE_STRUCT
+      && return_type (cif->rtype) != FFI_TYPE_STRUCT)
+    ecif.rvalue = &trvalue;
+  else if ((rvalue == NULL) && 
+      (cif->rtype->type == FFI_TYPE_STRUCT))
+    {
+      /*@-sysunrecog@*/
+      ecif.rvalue = alloca(cif->rtype->size);
+      /*@=sysunrecog@*/
+    }
+  else
+    ecif.rvalue = rvalue;
+
+  switch (cif->abi) 
+    {
+    case FFI_SYSV:
+      /*@-usedef@*/
+      ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, 
+		    cif->flags, ecif.rvalue, fn);
+      /*@=usedef@*/
+      break;
+    default:
+      FFI_ASSERT(0);
+      break;
+    }
+
+  if (rvalue
+      && cif->rtype->type == FFI_TYPE_STRUCT
+      && return_type (cif->rtype) != FFI_TYPE_STRUCT)
+    memcpy (rvalue, &trvalue, cif->rtype->size);
+}
+
+extern void ffi_closure_SYSV (void);
+#if defined(__SH4__)
+extern void __ic_invalidate (void *line);
+#endif
+
+ffi_status
+ffi_prep_closure (ffi_closure* closure,
+		  ffi_cif* cif,
+		  void (*fun)(ffi_cif*, void*, void**, void*),
+		  void *user_data)
+{
+  unsigned int *tramp;
+  unsigned short insn;
+
+  FFI_ASSERT (cif->abi == FFI_GCC_SYSV);
+
+  tramp = (unsigned int *) &closure->tramp[0];
+  /* Set T bit if the function returns a struct pointed with R2.  */
+  insn = (return_type (cif->rtype) == FFI_TYPE_STRUCT
+	  ? 0x0018 /* sett */
+	  : 0x0008 /* clrt */);
+
+#ifdef __LITTLE_ENDIAN__
+  tramp[0] = 0xd301d102;
+  tramp[1] = 0x0000412b | (insn << 16);
+#else
+  tramp[0] = 0xd102d301;
+  tramp[1] = 0x412b0000 | insn;
+#endif
+  *(void **) &tramp[2] = (void *)closure;          /* ctx */
+  *(void **) &tramp[3] = (void *)ffi_closure_SYSV; /* funaddr */
+
+  closure->cif = cif;
+  closure->fun = fun;
+  closure->user_data = user_data;
+
+#if defined(__SH4__)
+  /* Flush the icache.  */
+  __ic_invalidate(&closure->tramp[0]);
+#endif
+
+  return FFI_OK;
+}
+
+/* Basically the trampoline invokes ffi_closure_SYSV, and on 
+ * entry, r3 holds the address of the closure.
+ * After storing the registers that could possibly contain
+ * parameters to be passed into the stack frame and setting
+ * up space for a return value, ffi_closure_SYSV invokes the 
+ * following helper function to do most of the work.
+ */
+
+#ifdef __LITTLE_ENDIAN__
+#define OFS_INT8	0
+#define OFS_INT16	0
+#else
+#define OFS_INT8	3
+#define OFS_INT16	2
+#endif
+
+int
+ffi_closure_helper_SYSV (ffi_closure *closure, void *rvalue, 
+			 unsigned long *pgr, unsigned long *pfr, 
+			 unsigned long *pst)
+{
+  void **avalue;
+  ffi_type **p_arg;
+  int i, avn;
+  int ireg, greg = 0;
+#if defined(__SH4__)
+  int freg = 0;
+#endif
+  ffi_cif *cif; 
+  double temp; 
+
+  cif = closure->cif;
+  avalue = alloca(cif->nargs * sizeof(void *));
+
+  /* Copy the caller's structure return value address so that the closure
+     returns the data directly to the caller.  */
+  if (cif->rtype->type == FFI_TYPE_STRUCT && STRUCT_VALUE_ADDRESS_WITH_ARG)
+    {
+      rvalue = *pgr++;
+      ireg = 1;
+    }
+  else
+    ireg = 0;
+
+  cif = closure->cif;
+  greg = ireg;
+  avn = cif->nargs;
+
+  /* Grab the addresses of the arguments from the stack frame.  */
+  for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++)
+    {
+      size_t z;
+
+      z = (*p_arg)->size;
+      if (z < sizeof(int))
+	{
+	  if (greg++ >= NGREGARG)
+	    continue;
+
+	  z = sizeof(int);
+	  switch ((*p_arg)->type)
+	    {
+	    case FFI_TYPE_SINT8:
+	    case FFI_TYPE_UINT8:
+	      avalue[i] = (((char *)pgr) + OFS_INT8);
+	      break;
+  
+	    case FFI_TYPE_SINT16:
+	    case FFI_TYPE_UINT16:
+	      avalue[i] = (((char *)pgr) + OFS_INT16);
+	      break;
+  
+	    case FFI_TYPE_STRUCT:
+	      avalue[i] = pgr;
+	      break;
+
+	    default:
+	      FFI_ASSERT(0);
+	    }
+	  pgr++;
+	}
+      else if (z == sizeof(int))
+	{
+#if defined(__SH4__)
+	  if ((*p_arg)->type == FFI_TYPE_FLOAT)
+	    {
+	      if (freg++ >= NFREGARG)
+		continue;
+	      avalue[i] = pfr;
+	      pfr++;
+	    }
+	  else
+#endif
+	    {
+	      if (greg++ >= NGREGARG)
+		continue;
+	      avalue[i] = pgr;
+	      pgr++;
+	    }
+	}
+#if defined(__SH4__)
+      else if ((*p_arg)->type == FFI_TYPE_DOUBLE)
+	{
+	  if (freg + 1 >= NFREGARG)
+	    continue;
+	  freg = (freg + 1) & ~1;
+	  freg += 2;
+	  avalue[i] = pfr;
+	  pfr += 2;
+	}
+#endif
+      else
+	{
+	  int n = (z + sizeof (int) - 1) / sizeof (int);
+#if defined(__SH4__)
+	  if (greg + n - 1 >= NGREGARG)
+	    continue;
+#else
+	  if (greg >= NGREGARG)
+	    continue;
+#endif
+	  greg += n;
+	  avalue[i] = pgr;
+	  pgr += n;
+	}
+    }
+
+  greg = ireg;
+#if defined(__SH4__)
+  freg = 0;
+#endif
+
+  for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++)
+    {
+      size_t z;
+
+      z = (*p_arg)->size;
+      if (z < sizeof(int))
+	{
+	  if (greg++ < NGREGARG)
+	    continue;
+
+	  z = sizeof(int);
+	  switch ((*p_arg)->type)
+	    {
+	    case FFI_TYPE_SINT8:
+	    case FFI_TYPE_UINT8:
+	      avalue[i] = (((char *)pst) + OFS_INT8);
+	      break;
+  
+	    case FFI_TYPE_SINT16:
+	    case FFI_TYPE_UINT16:
+	      avalue[i] = (((char *)pst) + OFS_INT16);
+	      break;
+  
+	    case FFI_TYPE_STRUCT:
+	      avalue[i] = pst;
+	      break;
+
+	    default:
+	      FFI_ASSERT(0);
+	    }
+	  pst++;
+	}
+      else if (z == sizeof(int))
+	{
+#if defined(__SH4__)
+	  if ((*p_arg)->type == FFI_TYPE_FLOAT)
+	    {
+	      if (freg++ < NFREGARG)
+		continue;
+	    }
+	  else
+#endif
+	    {
+	      if (greg++ < NGREGARG)
+		continue;
+	    }
+	  avalue[i] = pst;
+	  pst++;
+	}
+#if defined(__SH4__)
+      else if ((*p_arg)->type == FFI_TYPE_DOUBLE)
+	{
+	  if (freg + 1 < NFREGARG)
+	    {
+	      freg = (freg + 1) & ~1;
+	      freg += 2;
+	      continue;
+	    }
+	  avalue[i] = pst;
+	  pst += 2;
+	}
+#endif
+      else
+	{
+	  int n = (z + sizeof (int) - 1) / sizeof (int);
+	  if (greg + n - 1 < NGREGARG)
+	    {
+	      greg += n;
+	      continue;
+	    }
+#if (! defined(__SH4__))
+	  else if (greg < NGREGARG)
+	    {
+	      greg += n;
+	      pst += greg - NGREGARG;
+	      continue;
+	    }
+#endif
+	  avalue[i] = pst;
+	  pst += n;
+	}
+    }
+
+  (closure->fun) (cif, rvalue, avalue, closure->user_data);
+
+  /* Tell ffi_closure_SYSV how to perform return type promotions.  */
+  return return_type (cif->rtype);
+}

Added: vendor/Python/current/Modules/_ctypes/libffi/src/sh/ffitarget.h
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/sh/ffitarget.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/sh/ffitarget.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,48 @@
+/* -----------------------------------------------------------------*-C-*-
+   ffitarget.h - Copyright (c) 1996-2003  Red Hat, Inc.
+   Target configuration macros for SuperH.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+
+   ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+/* ---- Generic type definitions ----------------------------------------- */
+
+#ifndef LIBFFI_ASM
+typedef unsigned long          ffi_arg;
+typedef signed long            ffi_sarg;
+
+typedef enum ffi_abi {
+  FFI_FIRST_ABI = 0,
+  FFI_SYSV,
+  FFI_DEFAULT_ABI = FFI_SYSV,
+  FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
+} ffi_abi;
+#endif
+
+#define FFI_CLOSURES 1
+#define FFI_TRAMPOLINE_SIZE 16
+#define FFI_NATIVE_RAW_API 0
+
+#endif
+

Added: vendor/Python/current/Modules/_ctypes/libffi/src/sh/sysv.S
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/sh/sysv.S	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/sh/sysv.S	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,845 @@
+/* -----------------------------------------------------------------------
+   sysv.S - Copyright (c) 2002, 2003, 2004 Kaz Kojima
+   
+   SuperH Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM	
+#include <fficonfig.h>
+#include <ffi.h>
+#ifdef HAVE_MACHINE_ASM_H
+#include <machine/asm.h>
+#else
+/* XXX these lose for some platforms, I'm sure. */
+#define CNAME(x) x
+#define ENTRY(x) .globl CNAME(x); .type CNAME(x),%function; CNAME(x):
+#endif
+
+#if defined(__HITACHI__)
+#define STRUCT_VALUE_ADDRESS_WITH_ARG 1
+#else
+#define STRUCT_VALUE_ADDRESS_WITH_ARG 0
+#endif
+
+.text
+
+	# r4:	ffi_prep_args
+	# r5:	&ecif
+	# r6:	bytes
+	# r7:	flags
+	# sp+0: rvalue
+	# sp+4: fn
+
+	# This assumes we are using gas.
+ENTRY(ffi_call_SYSV)
+	# Save registers
+.LFB1:
+	mov.l	r8, at -r15
+.LCFI0:
+	mov.l	r9, at -r15
+.LCFI1:
+	mov.l	r10, at -r15
+.LCFI2:
+	mov.l	r12, at -r15
+.LCFI3:
+	mov.l	r14, at -r15
+.LCFI4:
+	sts.l	pr, at -r15
+.LCFI5:
+	mov	r15,r14
+.LCFI6:
+#if defined(__SH4__)
+	mov	r6,r8
+	mov	r7,r9
+
+	sub	r6,r15
+	add	#-16,r15
+	mov	#~7,r0
+	and	r0,r15
+
+	mov	r4,r0
+	jsr	@r0
+	 mov	r15,r4
+
+	mov	r9,r1
+	shlr8	r9
+	shlr8	r9
+	shlr8	r9
+
+	mov	#FFI_TYPE_STRUCT,r2
+	cmp/eq	r2,r9
+	bf	1f
+#if STRUCT_VALUE_ADDRESS_WITH_ARG
+ 	mov.l	@r15+,r4
+	bra	2f
+	 mov	#5,r2
+#else
+ 	mov.l	@r15+,r10
+#endif
+1:
+	mov	#4,r2
+2:
+	mov	#4,r3
+
+L_pass:
+	cmp/pl	r8
+	bf	L_call_it
+
+	mov	r1,r0
+	and	#3,r0
+
+L_pass_d:
+	cmp/eq	#FFI_TYPE_DOUBLE,r0
+	bf	L_pass_f
+
+	mov	r3,r0
+	and	#1,r0
+	tst	r0,r0
+	bt	1f
+	add	#1,r3
+1:
+	mov	#12,r0
+	cmp/hs	r0,r3
+	bt/s	3f
+	 shlr2	r1
+	bsr	L_pop_d
+	 nop
+3:
+	add	#2,r3
+	bra	L_pass
+	 add	#-8,r8
+
+L_pop_d:
+	mov	r3,r0
+	add	r0,r0
+	add	r3,r0
+	add	#-12,r0
+	braf	r0
+	 nop
+#ifdef __LITTLE_ENDIAN__
+	fmov.s	@r15+,fr5
+	rts
+	 fmov.s	@r15+,fr4
+	fmov.s	@r15+,fr7
+	rts
+	 fmov.s	@r15+,fr6
+	fmov.s	@r15+,fr9
+	rts
+	 fmov.s	@r15+,fr8
+	fmov.s	@r15+,fr11
+	rts
+	 fmov.s	@r15+,fr10
+#else
+	fmov.s	@r15+,fr4
+	rts
+	 fmov.s	@r15+,fr5
+	fmov.s	@r15+,fr6
+	rts
+	 fmov.s	@r15+,fr7
+	fmov.s	@r15+,fr8
+	rts
+	 fmov.s	@r15+,fr9
+	fmov.s	@r15+,fr10
+	rts
+	 fmov.s	@r15+,fr11
+#endif
+
+L_pass_f:
+	cmp/eq	#FFI_TYPE_FLOAT,r0
+	bf	L_pass_i
+
+	mov	#12,r0
+	cmp/hs	r0,r3
+	bt/s	2f
+	 shlr2	r1
+	bsr	L_pop_f
+	 nop
+2:
+	add	#1,r3
+	bra	L_pass
+	 add	#-4,r8
+
+L_pop_f:
+	mov	r3,r0
+	shll2	r0
+	add	#-16,r0
+	braf	r0
+	 nop
+#ifdef __LITTLE_ENDIAN__
+	rts
+	 fmov.s	@r15+,fr5
+	rts
+	 fmov.s	@r15+,fr4
+	rts
+	 fmov.s	@r15+,fr7
+	rts
+	 fmov.s	@r15+,fr6
+	rts
+	 fmov.s	@r15+,fr9
+	rts
+	 fmov.s	@r15+,fr8
+	rts
+	 fmov.s	@r15+,fr11
+	rts
+	 fmov.s	@r15+,fr10
+#else
+	rts
+	 fmov.s	@r15+,fr4
+	rts
+	 fmov.s	@r15+,fr5
+	rts
+	 fmov.s	@r15+,fr6
+	rts
+	 fmov.s	@r15+,fr7
+	rts
+	 fmov.s	@r15+,fr8
+	rts
+	 fmov.s	@r15+,fr9
+	rts
+	 fmov.s	@r15+,fr10
+	rts
+	 fmov.s	@r15+,fr11
+#endif
+
+L_pass_i:
+	cmp/eq	#FFI_TYPE_INT,r0
+	bf	L_call_it
+
+	mov	#8,r0
+	cmp/hs	r0,r2
+	bt/s	2f
+	 shlr2	r1
+	bsr	L_pop_i
+	 nop
+2:
+	add	#1,r2
+	bra	L_pass
+	 add	#-4,r8
+
+L_pop_i:
+	mov	r2,r0
+	shll2	r0
+	add	#-16,r0
+	braf	r0
+	 nop
+	rts
+	 mov.l	@r15+,r4
+	rts
+	 mov.l	@r15+,r5
+	rts
+	 mov.l	@r15+,r6
+	rts
+	 mov.l	@r15+,r7
+
+L_call_it:
+	# call function
+#if (! STRUCT_VALUE_ADDRESS_WITH_ARG)
+	mov	r10, r2
+#endif
+	mov.l  @(28,r14),r1
+	jsr    @r1
+	 nop
+
+L_ret_d:
+	mov	#FFI_TYPE_DOUBLE,r2
+	cmp/eq	r2,r9
+	bf	L_ret_ll
+
+	mov.l	@(24,r14),r1
+#ifdef __LITTLE_ENDIAN__
+	fmov.s	fr1, at r1
+	add	#4,r1
+	bra	L_epilogue
+	 fmov.s	fr0, at r1
+#else
+	fmov.s	fr0, at r1
+	add	#4,r1
+	bra	L_epilogue
+	 fmov.s	fr1, at r1
+#endif
+
+L_ret_ll:
+	mov	#FFI_TYPE_SINT64,r2
+	cmp/eq	r2,r9
+	bt/s	1f
+	 mov	#FFI_TYPE_UINT64,r2
+	cmp/eq	r2,r9
+	bf	L_ret_f
+
+1:
+	mov.l	@(24,r14),r2
+	mov.l	r0, at r2
+	bra	L_epilogue
+	 mov.l	r1,@(4,r2)
+
+L_ret_f:
+	mov	#FFI_TYPE_FLOAT,r2
+	cmp/eq	r2,r9
+	bf	L_ret_i
+
+	mov.l	@(24,r14),r1
+	bra	L_epilogue
+	 fmov.s	fr0, at r1
+
+L_ret_i:
+	mov	#FFI_TYPE_INT,r2
+	cmp/eq	r2,r9
+	bf	L_epilogue
+
+	mov.l	@(24,r14),r1
+	bra	L_epilogue
+	 mov.l	r0, at r1
+
+L_epilogue:
+	# Remove the space we pushed for the args
+	mov   r14,r15
+
+	lds.l  @r15+,pr
+	mov.l  @r15+,r14
+	mov.l  @r15+,r12
+	mov.l  @r15+,r10
+	mov.l  @r15+,r9
+	rts
+	 mov.l  @r15+,r8
+#else
+	mov	r6,r8
+	mov	r7,r9
+
+	sub	r6,r15
+	add	#-16,r15
+	mov	#~7,r0
+	and	r0,r15
+
+	mov	r4,r0
+	jsr	@r0
+	 mov	r15,r4
+
+	mov	r9,r3
+	shlr8	r9
+	shlr8	r9
+	shlr8	r9
+
+	mov	#FFI_TYPE_STRUCT,r2
+	cmp/eq	r2,r9
+	bf	1f
+#if STRUCT_VALUE_ADDRESS_WITH_ARG
+	mov.l	@r15+,r4
+	bra	2f
+	 mov	#5,r2
+#else
+	mov.l	@r15+,r10
+#endif
+1:
+	mov	#4,r2
+2:
+
+L_pass:
+	cmp/pl	r8
+	bf	L_call_it
+
+	mov	r3,r0
+	and	#3,r0
+
+L_pass_d:
+	cmp/eq	#FFI_TYPE_DOUBLE,r0
+	bf	L_pass_i
+
+	mov	r15,r0
+	and	#7,r0
+	tst	r0,r0
+	bt	1f
+	add	#4,r15
+1:
+	mov	#8,r0
+	cmp/hs	r0,r2
+	bt/s	2f
+	 shlr2	r3
+	bsr	L_pop_d
+	 nop
+2:
+	add	#2,r2
+	bra	L_pass
+	 add	#-8,r8
+
+L_pop_d:
+	mov	r2,r0
+	add	r0,r0
+	add	r2,r0
+	add	#-12,r0
+	add	r0,r0
+	braf	r0
+	 nop
+	mov.l	@r15+,r4
+	rts
+	 mov.l	@r15+,r5
+	mov.l	@r15+,r5
+	rts
+	 mov.l	@r15+,r6
+	mov.l	@r15+,r6
+	rts
+	 mov.l	@r15+,r7
+	rts
+	 mov.l	@r15+,r7
+
+L_pass_i:
+	cmp/eq	#FFI_TYPE_INT,r0
+	bf	L_call_it
+
+	mov	#8,r0
+	cmp/hs	r0,r2
+	bt/s	2f
+	 shlr2	r3
+	bsr	L_pop_i
+	 nop
+2:
+	add	#1,r2
+	bra	L_pass
+	 add	#-4,r8
+
+L_pop_i:
+	mov	r2,r0
+	shll2	r0
+	add	#-16,r0
+	braf	r0
+	 nop
+	rts
+	 mov.l	@r15+,r4
+	rts
+	 mov.l	@r15+,r5
+	rts
+	 mov.l	@r15+,r6
+	rts
+	 mov.l	@r15+,r7
+
+L_call_it:
+	# call function
+#if (! STRUCT_VALUE_ADDRESS_WITH_ARG)
+	mov	r10, r2
+#endif
+	mov.l  @(28,r14),r1
+	jsr    @r1
+	 nop
+
+L_ret_d:
+	mov	#FFI_TYPE_DOUBLE,r2
+	cmp/eq	r2,r9
+	bf	L_ret_ll
+
+	mov.l	@(24,r14),r2
+	mov.l	r0, at r2
+	bra	L_epilogue
+	 mov.l	r1,@(4,r2)
+
+L_ret_ll:
+	mov	#FFI_TYPE_SINT64,r2
+	cmp/eq	r2,r9
+	bt/s	1f
+	 mov	#FFI_TYPE_UINT64,r2
+	cmp/eq	r2,r9
+	bf	L_ret_i
+
+1:
+	mov.l	@(24,r14),r2
+	mov.l	r0, at r2
+	bra	L_epilogue
+	 mov.l	r1,@(4,r2)
+
+L_ret_i:
+	mov	#FFI_TYPE_FLOAT,r2
+	cmp/eq	r2,r9
+	bt	1f
+	mov	#FFI_TYPE_INT,r2
+	cmp/eq	r2,r9
+	bf	L_epilogue
+1:
+	mov.l	@(24,r14),r1
+	bra	L_epilogue
+	 mov.l	r0, at r1
+
+L_epilogue:
+	# Remove the space we pushed for the args
+	mov   r14,r15
+
+	lds.l  @r15+,pr
+	mov.l  @r15+,r14
+	mov.l  @r15+,r12
+	mov.l  @r15+,r10
+	mov.l  @r15+,r9
+	rts
+	 mov.l  @r15+,r8
+#endif
+.LFE1:
+.ffi_call_SYSV_end:
+        .size    CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV)
+
+.globl	ffi_closure_helper_SYSV
+
+ENTRY(ffi_closure_SYSV)
+.LFB2:
+	mov.l	r7, at -r15
+.LCFI7:
+	mov.l	r6, at -r15
+.LCFI8:
+	mov.l	r5, at -r15
+.LCFI9:
+	mov.l	r4, at -r15
+.LCFIA:
+	mov.l	r14, at -r15
+.LCFIB:
+	sts.l	pr, at -r15
+
+	/* Stack layout:	
+	   xx bytes (on stack parameters)
+	   16 bytes (register parameters)
+	    4 bytes (saved frame pointer)
+	    4 bytes (saved return address)
+	   32 bytes (floating register parameters, SH-4 only)
+	    8 bytes (result)
+	    4 bytes (pad)
+	    4 bytes (5th arg)
+	   <- new stack pointer
+	*/
+.LCFIC:
+#if defined(__SH4__)
+	add	#-48,r15
+#else
+	add	#-16,r15
+#endif
+.LCFID:
+	mov	r15,r14
+.LCFIE:
+
+#if defined(__SH4__)
+	mov	r14,r1
+	add	#48,r1
+#ifdef __LITTLE_ENDIAN__
+	fmov.s	fr10, at -r1
+	fmov.s	fr11, at -r1
+	fmov.s	fr8, at -r1
+	fmov.s	fr9, at -r1
+	fmov.s	fr6, at -r1
+	fmov.s	fr7, at -r1
+	fmov.s	fr4, at -r1
+	fmov.s	fr5, at -r1
+#else
+	fmov.s	fr11, at -r1
+	fmov.s	fr10, at -r1
+	fmov.s	fr9, at -r1
+	fmov.s	fr8, at -r1
+	fmov.s	fr7, at -r1
+	fmov.s	fr6, at -r1
+	fmov.s	fr5, at -r1
+	fmov.s	fr4, at -r1
+#endif
+	mov	r1,r7
+	mov	r14,r6
+	add	#56,r6
+#else
+	mov	r14,r6
+	add	#24,r6
+#endif
+
+	bt/s	10f
+	 mov	r2, r5
+	mov	r14,r1
+	add	#8,r1
+	mov	r1,r5
+10:
+
+	mov	r14,r1
+#if defined(__SH4__)
+	add	#72,r1
+#else
+	add	#40,r1
+#endif
+	mov.l	r1, at r14
+
+#ifdef PIC
+	mov.l	L_got,r1
+	mova	L_got,r0
+	add	r0,r1
+	mov.l	L_helper,r0
+	add	r1,r0
+#else
+	mov.l	L_helper,r0
+#endif
+	jsr	@r0
+	 mov	r3,r4
+
+	shll	r0
+	mov	r0,r1
+	mova	L_table,r0
+	add	r1,r0
+	mov.w	@r0,r0
+	mov	r14,r2
+	braf	r0
+	 add	#8,r2
+0:
+	.align 2
+#ifdef PIC
+L_got:
+	.long	_GLOBAL_OFFSET_TABLE_
+L_helper:
+	.long	ffi_closure_helper_SYSV at GOTOFF
+#else
+L_helper:
+	.long	ffi_closure_helper_SYSV
+#endif
+L_table:
+	.short L_case_v - 0b	/* FFI_TYPE_VOID */
+	.short L_case_i - 0b	/* FFI_TYPE_INT */
+#if defined(__SH4__)
+	.short L_case_f - 0b	/* FFI_TYPE_FLOAT */
+	.short L_case_d - 0b	/* FFI_TYPE_DOUBLE */
+	.short L_case_d - 0b	/* FFI_TYPE_LONGDOUBLE */
+#else
+	.short L_case_i - 0b	/* FFI_TYPE_FLOAT */
+	.short L_case_ll - 0b	/* FFI_TYPE_DOUBLE */
+	.short L_case_ll - 0b	/* FFI_TYPE_LONGDOUBLE */
+#endif
+	.short L_case_uq - 0b	/* FFI_TYPE_UINT8 */
+	.short L_case_q - 0b	/* FFI_TYPE_SINT8 */
+	.short L_case_uh - 0b	/* FFI_TYPE_UINT16 */
+	.short L_case_h - 0b	/* FFI_TYPE_SINT16 */
+	.short L_case_i - 0b	/* FFI_TYPE_UINT32 */
+	.short L_case_i - 0b	/* FFI_TYPE_SINT32 */
+	.short L_case_ll - 0b	/* FFI_TYPE_UINT64 */
+	.short L_case_ll - 0b	/* FFI_TYPE_SINT64 */
+	.short L_case_v - 0b	/* FFI_TYPE_STRUCT */
+	.short L_case_i - 0b	/* FFI_TYPE_POINTER */
+
+#if defined(__SH4__)
+L_case_d:
+#ifdef __LITTLE_ENDIAN__
+	fmov.s	@r2+,fr1
+	bra	L_case_v
+	 fmov.s	@r2,fr0
+#else
+	fmov.s	@r2+,fr0
+	bra	L_case_v
+	 fmov.s	@r2,fr1
+#endif
+
+L_case_f:
+	bra	L_case_v
+	 fmov.s	@r2,fr0
+#endif
+	
+L_case_ll:
+	mov.l	@r2+,r0
+	bra	L_case_v
+	 mov.l	@r2,r1
+	
+L_case_i:
+	bra	L_case_v
+	 mov.l	@r2,r0
+	
+L_case_q:
+#ifdef __LITTLE_ENDIAN__
+#else
+	add	#3,r2
+#endif
+	bra	L_case_v
+	 mov.b	@r2,r0
+
+L_case_uq:
+#ifdef __LITTLE_ENDIAN__
+#else
+	add	#3,r2
+#endif
+	mov.b	@r2,r0
+	bra	L_case_v
+	 extu.b r0,r0
+
+L_case_h:
+#ifdef __LITTLE_ENDIAN__
+#else
+	add	#2,r2
+#endif
+	bra	L_case_v
+	 mov.w	@r2,r0
+
+L_case_uh:
+#ifdef __LITTLE_ENDIAN__
+#else
+	add	#2,r2
+#endif
+	mov.w	@r2,r0
+	extu.w	r0,r0
+	/* fall through */
+
+L_case_v:
+#if defined(__SH4__)
+	add	#48,r15
+#else
+	add	#16,r15
+#endif
+	lds.l	@r15+,pr
+	mov.l	@r15+,r14
+	rts
+	 add	#16,r15
+.LFE2:
+.ffi_closure_SYSV_end:
+        .size    CNAME(ffi_closure_SYSV),.ffi_closure_SYSV_end-CNAME(ffi_closure_SYSV)
+
+	.section	".eh_frame","aw", at progbits
+__FRAME_BEGIN__:
+	.4byte	.LECIE1-.LSCIE1	/* Length of Common Information Entry */
+.LSCIE1:
+	.4byte	0x0	/* CIE Identifier Tag */
+	.byte	0x1	/* CIE Version */
+#ifdef PIC
+	.ascii "zR\0"	/* CIE Augmentation */
+#else
+	.byte	0x0	/* CIE Augmentation */
+#endif
+	.byte	0x1	/* uleb128 0x1; CIE Code Alignment Factor */
+	.byte	0x7c	/* sleb128 -4; CIE Data Alignment Factor */
+	.byte	0x11	/* CIE RA Column */
+#ifdef PIC
+	.uleb128 0x1	/* Augmentation size */
+	.byte	0x10	/* FDE Encoding (pcrel) */
+#endif
+	.byte	0xc	/* DW_CFA_def_cfa */
+	.byte	0xf	/* uleb128 0xf */
+	.byte	0x0	/* uleb128 0x0 */
+	.align	2
+.LECIE1:
+.LSFDE1:
+	.4byte	.LEFDE1-.LASFDE1	/* FDE Length */
+.LASFDE1:
+	.4byte	.LASFDE1-__FRAME_BEGIN__	/* FDE CIE offset */
+#ifdef PIC
+	.4byte	.LFB1-.	/* FDE initial location */
+#else
+	.4byte	.LFB1	/* FDE initial location */
+#endif
+	.4byte	.LFE1-.LFB1	 /* FDE address range */
+#ifdef PIC
+	.uleb128 0x0	/* Augmentation size */
+#endif
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	.LCFI0-.LFB1
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+	.byte	0x4	/* uleb128 0x4 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	.LCFI1-.LCFI0
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+	.byte	0x8	/* uleb128 0x4 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	.LCFI2-.LCFI1
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+	.byte	0xc	/* uleb128 0x4 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	.LCFI3-.LCFI2
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+	.byte	0x10	/* uleb128 0x4 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	.LCFI4-.LCFI3
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+	.byte	0x14	/* uleb128 0x4 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	.LCFI5-.LCFI4
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+	.byte	0x18	/* uleb128 0x4 */
+	.byte	0x91	/* DW_CFA_offset, column 0x11 */
+	.byte	0x6	/* uleb128 0x6 */
+	.byte	0x8e	/* DW_CFA_offset, column 0xe */
+	.byte	0x5	/* uleb128 0x5 */
+	.byte	0x8c	/* DW_CFA_offset, column 0xc */
+	.byte	0x4	/* uleb128 0x4 */
+	.byte	0x8a	/* DW_CFA_offset, column 0xa */
+	.byte	0x3	/* uleb128 0x3 */
+	.byte	0x89	/* DW_CFA_offset, column 0x9 */
+	.byte	0x2	/* uleb128 0x2 */
+	.byte	0x88	/* DW_CFA_offset, column 0x8 */
+	.byte	0x1	/* uleb128 0x1 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	.LCFI6-.LCFI5
+	.byte	0xd	/* DW_CFA_def_cfa_register */
+	.byte	0xe	/* uleb128 0xe */
+	.align	2
+.LEFDE1:
+
+.LSFDE3:
+	.4byte	.LEFDE3-.LASFDE3	/* FDE Length */
+.LASFDE3:
+	.4byte	.LASFDE3-__FRAME_BEGIN__	/* FDE CIE offset */
+#ifdef PIC
+	.4byte	.LFB2-.	/* FDE initial location */
+#else
+	.4byte	.LFB2	/* FDE initial location */
+#endif
+	.4byte	.LFE2-.LFB2	 /* FDE address range */
+#ifdef PIC
+	.uleb128 0x0	/* Augmentation size */
+#endif
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	.LCFI7-.LFB2
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+	.byte	0x4	/* uleb128 0x4 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	.LCFI8-.LCFI7
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+	.byte	0x8	/* uleb128 0x4 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	.LCFI9-.LCFI8
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+	.byte	0xc	/* uleb128 0x4 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	.LCFIA-.LCFI9
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+	.byte	0x10	/* uleb128 0x4 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	.LCFIB-.LCFIA
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+	.byte	0x14	/* uleb128 0x4 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	.LCFIC-.LCFIB
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+	.byte	0x18	/* uleb128 0x4 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	.LCFID-.LCFIC
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+#if defined(__SH4__)
+	.byte	24+48	/* uleb128 24+48 */
+#else
+	.byte	24+16	/* uleb128 24+16 */
+#endif
+	.byte	0x91	/* DW_CFA_offset, column 0x11 */
+	.byte	0x6	/* uleb128 0x6 */
+	.byte	0x8e	/* DW_CFA_offset, column 0xe */
+	.byte	0x5	/* uleb128 0x5 */
+	.byte	0x8b	/* DW_CFA_offset, column 0xb */
+	.byte	0x4	/* uleb128 0x4 */
+	.byte	0x8a	/* DW_CFA_offset, column 0xa */
+	.byte	0x3	/* uleb128 0x3 */
+	.byte	0x89	/* DW_CFA_offset, column 0x9 */
+	.byte	0x2	/* uleb128 0x2 */
+	.byte	0x88	/* DW_CFA_offset, column 0x8 */
+	.byte	0x1	/* uleb128 0x1 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	.LCFIE-.LCFID
+	.byte	0xd	/* DW_CFA_def_cfa_register */
+	.byte	0xe	/* uleb128 0xe */
+	.align	2
+.LEFDE3:

Added: vendor/Python/current/Modules/_ctypes/libffi/src/sh64/ffi.c
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/sh64/ffi.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/sh64/ffi.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,451 @@
+/* -----------------------------------------------------------------------
+   ffi.c - Copyright (c) 2003, 2004 Kaz Kojima
+   
+   SuperH SHmedia Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+
+#define NGREGARG 8
+#define NFREGARG 12
+
+static int
+return_type (ffi_type *arg)
+{
+
+  if (arg->type != FFI_TYPE_STRUCT)
+    return arg->type;
+
+  /* gcc uses r2 if the result can be packed in on register.  */
+  if (arg->size <= sizeof (UINT8))
+    return FFI_TYPE_UINT8;
+  else if (arg->size <= sizeof (UINT16))
+    return FFI_TYPE_UINT16;
+  else if (arg->size <= sizeof (UINT32))
+    return FFI_TYPE_UINT32;
+  else if (arg->size <= sizeof (UINT64))
+    return FFI_TYPE_UINT64;
+
+  return FFI_TYPE_STRUCT;
+}
+
+/* ffi_prep_args is called by the assembly routine once stack space
+   has been allocated for the function's arguments */
+
+/*@-exportheader@*/
+void ffi_prep_args(char *stack, extended_cif *ecif)
+/*@=exportheader@*/
+{
+  register unsigned int i;
+  register unsigned int avn;
+  register void **p_argv;
+  register char *argp;
+  register ffi_type **p_arg;
+
+  argp = stack;
+
+  if (return_type (ecif->cif->rtype) == FFI_TYPE_STRUCT)
+    {
+      *(void **) argp = ecif->rvalue;
+      argp += sizeof (UINT64);
+    }
+
+  avn = ecif->cif->nargs;
+  p_argv = ecif->avalue;
+
+  for (i = 0, p_arg = ecif->cif->arg_types; i < avn; i++, p_arg++, p_argv++)
+    {
+      size_t z;
+      int align;
+
+      z = (*p_arg)->size;
+      align = (*p_arg)->alignment;
+      if (z < sizeof (UINT32))
+	{
+	  switch ((*p_arg)->type)
+	    {
+	    case FFI_TYPE_SINT8:
+	      *(SINT64 *) argp = (SINT64) *(SINT8 *)(*p_argv);
+	      break;
+  
+	    case FFI_TYPE_UINT8:
+	      *(UINT64 *) argp = (UINT64) *(UINT8 *)(*p_argv);
+	      break;
+  
+	    case FFI_TYPE_SINT16:
+	      *(SINT64 *) argp = (SINT64) *(SINT16 *)(*p_argv);
+	      break;
+  
+	    case FFI_TYPE_UINT16:
+	      *(UINT64 *) argp = (UINT64) *(UINT16 *)(*p_argv);
+	      break;
+  
+	    case FFI_TYPE_STRUCT:
+	      memcpy (argp, *p_argv, z);
+	      break;
+
+	    default:
+	      FFI_ASSERT(0);
+	    }
+	  argp += sizeof (UINT64);
+	}
+      else if (z == sizeof (UINT32) && align == sizeof (UINT32))
+	{
+	  switch ((*p_arg)->type)
+	    {
+	    case FFI_TYPE_INT:
+	    case FFI_TYPE_SINT32:
+	      *(SINT64 *) argp = (SINT64) *(SINT32 *) (*p_argv);
+	      break;
+
+	    case FFI_TYPE_FLOAT:
+	    case FFI_TYPE_POINTER:
+	    case FFI_TYPE_UINT32:
+	    case FFI_TYPE_STRUCT:
+	      *(UINT64 *) argp = (UINT64) *(UINT32 *) (*p_argv);
+	      break;
+
+	    default:
+	      FFI_ASSERT(0);
+	      break;
+	    }
+	  argp += sizeof (UINT64);
+	}
+      else if (z == sizeof (UINT64)
+	       && align == sizeof (UINT64)
+	       && ((int) *p_argv & (sizeof (UINT64) - 1)) == 0)
+	{
+	  *(UINT64 *) argp = *(UINT64 *) (*p_argv);
+	  argp += sizeof (UINT64);
+	}
+      else
+	{
+	  int n = (z + sizeof (UINT64) - 1) / sizeof (UINT64);
+
+	  memcpy (argp, *p_argv, z);
+	  argp += n * sizeof (UINT64);
+	}
+    }
+
+  return;
+}
+
+/* Perform machine dependent cif processing */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+{
+  int i, j;
+  int size, type;
+  int n, m;
+  int greg;
+  int freg;
+
+  greg = (return_type (cif->rtype) == FFI_TYPE_STRUCT ? 1 : 0);
+  freg = 0;
+  cif->flags2 = 0;
+
+  for (i = j = 0; i < cif->nargs; i++)
+    {
+      type = (cif->arg_types)[i]->type;
+      switch (type)
+	{
+	case FFI_TYPE_FLOAT:
+	  greg++;
+	  cif->bytes += sizeof (UINT64) - sizeof (float);
+	  if (freg >= NFREGARG - 1)
+	    continue;
+	  freg++;
+	  cif->flags2 += ((cif->arg_types)[i]->type) << (2 * j++);
+	  break;
+
+	case FFI_TYPE_DOUBLE:
+	  if (greg++ >= NGREGARG && (freg + 1) >= NFREGARG)
+	    continue;
+	  if ((freg + 1) < NFREGARG)
+	    {
+	      freg = (freg + 1) & ~1;
+	      freg += 2;
+	      cif->flags2 += ((cif->arg_types)[i]->type) << (2 * j++);
+	    }
+	  else
+	    cif->flags2 += FFI_TYPE_INT << (2 * j++);
+	  break;
+	      
+	default:
+	  size = (cif->arg_types)[i]->size;
+	  if (size < sizeof (UINT64))
+	    cif->bytes += sizeof (UINT64) - size;
+	  n = (size + sizeof (UINT64) - 1) / sizeof (UINT64);
+	  if (greg >= NGREGARG)
+	    continue;
+	  else if (greg + n - 1 >= NGREGARG)
+	    greg = NGREGARG;
+	  else
+	    greg += n;
+	  for (m = 0; m < n; m++)
+	    cif->flags2 += FFI_TYPE_INT << (2 * j++);
+	  break;
+	}
+    }
+
+  /* Set the return type flag */
+  switch (cif->rtype->type)
+    {
+    case FFI_TYPE_STRUCT:
+      cif->flags = return_type (cif->rtype);
+      break;
+
+    case FFI_TYPE_VOID:
+    case FFI_TYPE_FLOAT:
+    case FFI_TYPE_DOUBLE:
+    case FFI_TYPE_SINT64:
+    case FFI_TYPE_UINT64:
+      cif->flags = cif->rtype->type;
+      break;
+
+    default:
+      cif->flags = FFI_TYPE_INT;
+      break;
+    }
+
+  return FFI_OK;
+}
+
+/*@-declundef@*/
+/*@-exportheader@*/
+extern void ffi_call_SYSV(void (*)(char *, extended_cif *), 
+			  /*@out@*/ extended_cif *, 
+			  unsigned, unsigned, long long,
+			  /*@out@*/ unsigned *, 
+			  void (*fn)());
+/*@=declundef@*/
+/*@=exportheader@*/
+
+void ffi_call(/*@dependent@*/ ffi_cif *cif, 
+	      void (*fn)(), 
+	      /*@out@*/ void *rvalue, 
+	      /*@dependent@*/ void **avalue)
+{
+  extended_cif ecif;
+  UINT64 trvalue;
+
+  ecif.cif = cif;
+  ecif.avalue = avalue;
+  
+  /* If the return value is a struct and we don't have a return	*/
+  /* value address then we need to make one		        */
+
+  if (cif->rtype->type == FFI_TYPE_STRUCT
+      && return_type (cif->rtype) != FFI_TYPE_STRUCT)
+    ecif.rvalue = &trvalue;
+  else if ((rvalue == NULL) && 
+      (cif->rtype->type == FFI_TYPE_STRUCT))
+    {
+      /*@-sysunrecog@*/
+      ecif.rvalue = alloca(cif->rtype->size);
+      /*@=sysunrecog@*/
+    }
+  else
+    ecif.rvalue = rvalue;
+
+  switch (cif->abi) 
+    {
+    case FFI_SYSV:
+      /*@-usedef@*/
+      ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, 
+		    cif->flags, cif->flags2, ecif.rvalue, fn);
+      /*@=usedef@*/
+      break;
+    default:
+      FFI_ASSERT(0);
+      break;
+    }
+
+  if (rvalue
+      && cif->rtype->type == FFI_TYPE_STRUCT
+      && return_type (cif->rtype) != FFI_TYPE_STRUCT)
+    memcpy (rvalue, &trvalue, cif->rtype->size);
+}
+
+extern void ffi_closure_SYSV (void);
+extern void __ic_invalidate (void *line);
+
+ffi_status
+ffi_prep_closure (ffi_closure *closure,
+		  ffi_cif *cif,
+		  void (*fun)(ffi_cif*, void*, void**, void*),
+		  void *user_data)
+{
+  unsigned int *tramp;
+
+  FFI_ASSERT (cif->abi == FFI_GCC_SYSV);
+
+  tramp = (unsigned int *) &closure->tramp[0];
+  /* Since ffi_closure is an aligned object, the ffi trampoline is
+     called as an SHcompact code.  Sigh.
+     SHcompact part:
+     mova @(1,pc),r0; add #1,r0; jmp @r0; nop;
+     SHmedia part:
+     movi fnaddr >> 16,r1; shori fnaddr,r1; ptabs/l r1,tr0
+     movi cxt >> 16,r1; shori cxt,r1; blink tr0,r63  */
+#ifdef __LITTLE_ENDIAN__
+  tramp[0] = 0x7001c701;
+  tramp[1] = 0x0009402b;
+#else
+  tramp[0] = 0xc7017001;
+  tramp[1] = 0x402b0009;
+#endif
+  tramp[2] = 0xcc000010 | (((UINT32) ffi_closure_SYSV) >> 16) << 10;
+  tramp[3] = 0xc8000010 | (((UINT32) ffi_closure_SYSV) & 0xffff) << 10;
+  tramp[4] = 0x6bf10600;
+  tramp[5] = 0xcc000010 | (((UINT32) closure) >> 16) << 10;
+  tramp[6] = 0xc8000010 | (((UINT32) closure) & 0xffff) << 10;
+  tramp[7] = 0x4401fff0;
+
+  closure->cif = cif;
+  closure->fun = fun;
+  closure->user_data = user_data;
+
+  /* Flush the icache.  */
+  asm volatile ("ocbwb %0,0; synco; icbi %0,0; synci" : : "r" (tramp));
+
+  return FFI_OK;
+}
+
+/* Basically the trampoline invokes ffi_closure_SYSV, and on 
+ * entry, r3 holds the address of the closure.
+ * After storing the registers that could possibly contain
+ * parameters to be passed into the stack frame and setting
+ * up space for a return value, ffi_closure_SYSV invokes the 
+ * following helper function to do most of the work.
+ */
+
+int
+ffi_closure_helper_SYSV (ffi_closure *closure, UINT64 *rvalue, 
+			 UINT64 *pgr, UINT64 *pfr, UINT64 *pst)
+{
+  void **avalue;
+  ffi_type **p_arg;
+  int i, avn;
+  int greg, freg;
+  ffi_cif *cif;
+
+  cif = closure->cif;
+  avalue = alloca (cif->nargs * sizeof (void *));
+
+  /* Copy the caller's structure return value address so that the closure
+     returns the data directly to the caller.  */
+  if (return_type (cif->rtype) == FFI_TYPE_STRUCT)
+    {
+      rvalue = *pgr;
+      greg = 1;
+    }
+  else
+    greg = 0;
+
+  freg = 0;
+  cif = closure->cif;
+  avn = cif->nargs;
+
+  /* Grab the addresses of the arguments from the stack frame.  */
+  for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++)
+    {
+      size_t z;
+      void *p;
+
+      z = (*p_arg)->size;
+      if (z < sizeof (UINT32))
+	{
+	  p = pgr + greg++;
+
+	  switch ((*p_arg)->type)
+	    {
+	    case FFI_TYPE_SINT8:
+	    case FFI_TYPE_UINT8:
+	    case FFI_TYPE_SINT16:
+	    case FFI_TYPE_UINT16:
+	    case FFI_TYPE_STRUCT:
+#ifdef __LITTLE_ENDIAN__
+	      avalue[i] = p;
+#else
+	      avalue[i] = ((char *) p) + sizeof (UINT32) - z;
+#endif
+	      break;
+
+	    default:
+	      FFI_ASSERT(0);
+	    }
+	}
+      else if (z == sizeof (UINT32))
+	{
+	  if ((*p_arg)->type == FFI_TYPE_FLOAT)
+	    {
+	      if (freg < NFREGARG - 1)
+#ifdef __LITTLE_ENDIAN__
+		avalue[i] = (UINT32 *) pfr + (1 ^ freg++);
+#else
+		avalue[i] = (UINT32 *) pfr + freg++;
+#endif
+	      else
+#ifdef __LITTLE_ENDIAN__
+		avalue[i] = pgr + greg;
+#else
+		avalue[i] = (UINT32 *) (pgr + greg) + 1;
+#endif
+	    }
+	  else
+#ifdef __LITTLE_ENDIAN__
+	    avalue[i] = pgr + greg;
+#else
+	    avalue[i] = (UINT32 *) (pgr + greg) + 1;
+#endif
+	  greg++;
+	}
+      else if ((*p_arg)->type == FFI_TYPE_DOUBLE)
+	{
+	  if (freg + 1 >= NFREGARG)
+	    avalue[i] = pgr + greg;
+	  else
+	    {
+	      freg = (freg + 1) & ~1;
+	      avalue[i] = pfr + (freg >> 1);
+	      freg += 2;
+	    }
+	  greg++;
+	}
+      else
+	{
+	  int n = (z + sizeof (UINT64) - 1) / sizeof (UINT64);
+
+	  avalue[i] = pgr + greg;
+	  greg += n;
+	}
+    }
+
+  (closure->fun) (cif, rvalue, avalue, closure->user_data);
+
+  /* Tell ffi_closure_SYSV how to perform return type promotions.  */
+  return return_type (cif->rtype);
+}
+

Added: vendor/Python/current/Modules/_ctypes/libffi/src/sh64/ffitarget.h
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/sh64/ffitarget.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/sh64/ffitarget.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,52 @@
+/* -----------------------------------------------------------------*-C-*-
+   ffitarget.h - Copyright (c) 1996-2003  Red Hat, Inc.
+   Target configuration macros for SuperH - SHmedia.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+
+   ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+/* ---- Generic type definitions ----------------------------------------- */
+
+#ifndef LIBFFI_ASM
+typedef unsigned long          ffi_arg;
+typedef signed long            ffi_sarg;
+
+typedef enum ffi_abi {
+  FFI_FIRST_ABI = 0,
+  FFI_SYSV,
+  FFI_DEFAULT_ABI = FFI_SYSV,
+  FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
+} ffi_abi;
+
+#define FFI_EXTRA_CIF_FIELDS long long flags2
+#endif
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#define FFI_CLOSURES 1
+#define FFI_TRAMPOLINE_SIZE 32
+#define FFI_NATIVE_RAW_API 0
+
+#endif
+

Added: vendor/Python/current/Modules/_ctypes/libffi/src/sh64/sysv.S
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/sh64/sysv.S	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/sh64/sysv.S	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,525 @@
+/* -----------------------------------------------------------------------
+   sysv.S - Copyright (c) 2003, 2004 Kaz Kojima
+   
+   SuperH SHmedia Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM	
+#include <fficonfig.h>
+#include <ffi.h>
+#ifdef HAVE_MACHINE_ASM_H
+#include <machine/asm.h>
+#else
+/* XXX these lose for some platforms, I'm sure. */
+#define CNAME(x) x
+#define ENTRY(x) .globl CNAME(x); .type CNAME(x),%function; CNAME(x):
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define OFS_FLT	0
+#else
+#define OFS_FLT	4
+#endif
+
+	.section	.text..SHmedia32,"ax"
+
+	# r2:	ffi_prep_args
+	# r3:	&ecif
+	# r4:	bytes
+	# r5:	flags
+	# r6:	flags2
+	# r7:	rvalue
+	# r8:	fn
+
+	# This assumes we are using gas.
+	.align	5
+ENTRY(ffi_call_SYSV)
+	# Save registers
+.LFB1:
+	addi.l	r15, -48, r15
+.LCFI0:
+	st.q	r15, 40, r32
+	st.q	r15, 32, r31
+	st.q	r15, 24, r30
+	st.q	r15, 16, r29
+	st.q	r15, 8, r28
+	st.l	r15, 4, r18
+	st.l	r15, 0, r14
+.LCFI1:
+	add.l	r15, r63, r14
+.LCFI2:
+#	add	r4, r63, r28
+	add	r5, r63, r29
+	add	r6, r63, r30
+	add	r7, r63, r31
+	add	r8, r63, r32
+
+	addi	r4, (64 + 7), r4
+	andi	r4, ~7, r4
+	sub.l	r15, r4, r15
+
+	ptabs/l	r2, tr0
+	add	r15, r63, r2
+	blink	tr0, r18
+
+	addi	r15, 64, r22
+	movi	0, r0
+	movi	0, r1
+
+	pt/l	1f, tr1
+	bnei/l	r29, FFI_TYPE_STRUCT, tr1
+	ld.l	r15, 0, r19
+	addi	r15, 8, r15
+	addi	r0, 1, r0
+1:
+
+.L_pass:
+	andi	r30, 3, r20
+	shlri	r30, 2, r30
+
+	pt/l	.L_call_it, tr0
+	pt/l	.L_pass_i, tr1
+	pt/l	.L_pass_f, tr2
+
+	beqi/l	r20, FFI_TYPE_VOID, tr0
+	beqi/l	r20, FFI_TYPE_INT, tr1
+	beqi/l	r20, FFI_TYPE_FLOAT, tr2
+
+.L_pass_d:
+	addi	r0, 1, r0
+	addi	r1, 1, r1
+	andi	r1, ~1, r1
+
+	pt/l	3f, tr0
+	movi	12, r20
+	bge/l	r1, r20, tr0
+
+	pt/l	.L_pop_d, tr1
+	pt/l	2f, tr0
+	blink	tr1, r63
+2:
+	addi.l	r15, 8, r15
+3:
+	pt/l	.L_pass, tr0
+	addi	r1, 2, r1
+	blink	tr0, r63
+
+.L_pop_d:
+	pt/l	.L_pop_d_tbl, tr1
+	gettr	tr1, r20
+	shlli	r1, 2, r21
+	add	r20, r21, r20
+	ptabs/l	r20, tr1
+	blink	tr1, r63
+
+.L_pop_d_tbl:
+	fld.d	r15, 0, dr0
+	blink	tr0, r63
+	fld.d	r15, 0, dr2
+	blink	tr0, r63
+	fld.d	r15, 0, dr4
+	blink	tr0, r63
+	fld.d	r15, 0, dr6
+	blink	tr0, r63
+	fld.d	r15, 0, dr8
+	blink	tr0, r63
+	fld.d	r15, 0, dr10
+	blink	tr0, r63
+
+.L_pass_f:
+	addi	r0, 1, r0
+	pt/l	3f, tr0
+	movi	12, r20
+	bge/l	r1, r20, tr0
+
+	pt/l	.L_pop_f, tr1
+	pt/l	2f, tr0
+	blink	tr1, r63
+2:
+	addi.l	r15, 8, r15
+3:
+	pt/l	.L_pass, tr0
+	addi	r1, 1, r1
+	blink	tr0, r63
+
+.L_pop_f:
+	pt/l	.L_pop_f_tbl, tr1
+	gettr	tr1, r20
+	shlli	r1, 3, r21
+	add	r20, r21, r20
+	ptabs/l	r20, tr1
+	blink	tr1, r63
+
+.L_pop_f_tbl:
+	fld.s	r15, OFS_FLT, fr0
+	blink	tr0, r63
+	fld.s	r15, OFS_FLT, fr1
+	blink	tr0, r63
+	fld.s	r15, OFS_FLT, fr2
+	blink	tr0, r63
+	fld.s	r15, OFS_FLT, fr3
+	blink	tr0, r63
+	fld.s	r15, OFS_FLT, fr4
+	blink	tr0, r63
+	fld.s	r15, OFS_FLT, fr5
+	blink	tr0, r63
+	fld.s	r15, OFS_FLT, fr6
+	blink	tr0, r63
+	fld.s	r15, OFS_FLT, fr7
+	blink	tr0, r63
+	fld.s	r15, OFS_FLT, fr8
+	blink	tr0, r63
+	fld.s	r15, OFS_FLT, fr9
+	blink	tr0, r63
+	fld.s	r15, OFS_FLT, fr10
+	blink	tr0, r63
+	fld.s	r15, OFS_FLT, fr11
+	blink	tr0, r63
+
+.L_pass_i:
+	pt/l	3f, tr0
+	movi	8, r20
+	bge/l	r0, r20, tr0
+
+	pt/l	.L_pop_i, tr1
+	pt/l	2f, tr0
+	blink	tr1, r63
+2:
+	addi.l	r15, 8, r15
+3:
+	pt/l	.L_pass, tr0
+	addi	r0, 1, r0
+	blink	tr0, r63
+
+.L_pop_i:
+	pt/l	.L_pop_i_tbl, tr1
+	gettr	tr1, r20
+	shlli	r0, 3, r21
+	add	r20, r21, r20
+	ptabs/l	r20, tr1
+	blink	tr1, r63
+
+.L_pop_i_tbl:
+	ld.q	r15, 0, r2
+	blink	tr0, r63
+	ld.q	r15, 0, r3
+	blink	tr0, r63
+	ld.q	r15, 0, r4
+	blink	tr0, r63
+	ld.q	r15, 0, r5
+	blink	tr0, r63
+	ld.q	r15, 0, r6
+	blink	tr0, r63
+	ld.q	r15, 0, r7
+	blink	tr0, r63
+	ld.q	r15, 0, r8
+	blink	tr0, r63
+	ld.q	r15, 0, r9
+	blink	tr0, r63
+
+.L_call_it:
+	# call function
+	pt/l	1f, tr1
+	bnei/l	r29, FFI_TYPE_STRUCT, tr1
+	add	r19, r63, r2
+1:
+	add	r22, r63, r15
+	ptabs/l	r32, tr0
+	blink	tr0, r18
+
+	pt/l	.L_ret_i, tr0
+	pt/l	.L_ret_ll, tr1
+	pt/l	.L_ret_d, tr2
+	pt/l	.L_ret_f, tr3
+	pt/l	.L_epilogue, tr4
+
+	beqi/l	r29, FFI_TYPE_INT, tr0
+	beqi/l	r29, FFI_TYPE_UINT32, tr0
+	beqi/l	r29, FFI_TYPE_SINT64, tr1
+	beqi/l	r29, FFI_TYPE_UINT64, tr1
+	beqi/l	r29, FFI_TYPE_DOUBLE, tr2
+	beqi/l	r29, FFI_TYPE_FLOAT, tr3
+
+	pt/l	.L_ret_q, tr0
+	pt/l	.L_ret_h, tr1
+
+	beqi/l	r29, FFI_TYPE_UINT8, tr0
+	beqi/l	r29, FFI_TYPE_UINT16, tr1
+	blink	tr4, r63
+
+.L_ret_d:
+	fst.d	r31, 0, dr0
+	blink	tr4, r63
+
+.L_ret_ll:
+	st.q	r31, 0, r2
+	blink	tr4, r63
+
+.L_ret_f:
+	fst.s	r31, OFS_FLT, fr0
+	blink	tr4, r63
+
+.L_ret_q:
+	st.b	r31, 0, r2
+	blink	tr4, r63
+
+.L_ret_h:
+	st.w	r31, 0, r2
+	blink	tr4, r63
+
+.L_ret_i:
+	st.l	r31, 0, r2
+	# Fall
+
+.L_epilogue:
+	# Remove the space we pushed for the args
+	add	r14, r63, r15
+
+	ld.l	r15, 0, r14
+	ld.l	r15, 4, r18
+	ld.q	r15, 8, r28
+	ld.q	r15, 16, r29
+	ld.q	r15, 24, r30
+	ld.q	r15, 32, r31
+	ld.q	r15, 40, r32
+	addi.l	r15, 48, r15
+	ptabs	r18, tr0
+	blink	tr0, r63
+
+.LFE1:
+.ffi_call_SYSV_end:
+	.size	 CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV)
+
+	.align	5
+ENTRY(ffi_closure_SYSV)
+.LFB2:
+	addi.l	r15, -136, r15
+.LCFI3:
+	st.l	r15, 12, r18
+	st.l	r15, 8, r14
+	st.l	r15, 4, r12
+.LCFI4:
+	add	r15, r63, r14
+.LCFI5:
+	/* Stack layout:	
+	   ...
+	   64 bytes (register parameters)
+	   48 bytes (floating register parameters)
+	    8 bytes (result)
+	    4 bytes (r18)
+	    4 bytes (r14)
+	    4 bytes (r12)
+	    4 bytes (for align)
+	   <- new stack pointer
+	*/
+	fst.d	r14, 24, dr0
+	fst.d	r14, 32, dr2
+	fst.d	r14, 40, dr4
+	fst.d	r14, 48, dr6
+	fst.d	r14, 56, dr8
+	fst.d	r14, 64, dr10
+	st.q	r14, 72, r2
+	st.q	r14, 80, r3
+	st.q	r14, 88, r4
+	st.q	r14, 96, r5
+	st.q	r14, 104, r6
+	st.q	r14, 112, r7
+	st.q	r14, 120, r8
+	st.q	r14, 128, r9
+
+	add	r1, r63, r2
+	addi	r14, 16, r3
+	addi	r14, 72, r4
+	addi	r14, 24, r5
+	addi	r14, 136, r6
+#ifdef PIC
+	movi	(((datalabel _GLOBAL_OFFSET_TABLE_-(.LPCS0-.)) >> 16) & 65535), r12
+        shori	((datalabel _GLOBAL_OFFSET_TABLE_-(.LPCS0-.)) & 65535), r12
+.LPCS0:	ptrel/u r12, tr0
+	movi	((ffi_closure_helper_SYSV at GOTPLT) & 65535), r1
+	gettr	tr0, r12
+	ldx.l	r1, r12, r1
+	ptabs	r1, tr0
+#else
+	pt/l	ffi_closure_helper_SYSV, tr0
+#endif
+	blink	tr0, r18
+
+	shlli	r2, 1, r1
+        movi    (((datalabel .L_table) >> 16) & 65535), r2
+        shori   ((datalabel .L_table) & 65535), r2
+        ldx.w   r2, r1, r1
+        add     r1, r2, r1
+	pt/l	.L_case_v, tr1
+        ptabs   r1, tr0
+        blink   tr0, r63
+
+        .align 2
+.L_table:
+	.word	.L_case_v - datalabel .L_table	/* FFI_TYPE_VOID */
+	.word	.L_case_i - datalabel .L_table	/* FFI_TYPE_INT */
+	.word	.L_case_f - datalabel .L_table	/* FFI_TYPE_FLOAT */
+	.word	.L_case_d - datalabel .L_table	/* FFI_TYPE_DOUBLE */
+	.word	.L_case_d - datalabel .L_table	/* FFI_TYPE_LONGDOUBLE */
+	.word	.L_case_uq - datalabel .L_table	/* FFI_TYPE_UINT8 */
+	.word	.L_case_q - datalabel .L_table	/* FFI_TYPE_SINT8 */
+	.word	.L_case_uh - datalabel .L_table	/* FFI_TYPE_UINT16 */
+	.word	.L_case_h - datalabel .L_table	/* FFI_TYPE_SINT16 */
+	.word	.L_case_i - datalabel .L_table	/* FFI_TYPE_UINT32 */
+	.word	.L_case_i - datalabel .L_table	/* FFI_TYPE_SINT32 */
+	.word	.L_case_ll - datalabel .L_table	/* FFI_TYPE_UINT64 */
+	.word	.L_case_ll - datalabel .L_table	/* FFI_TYPE_SINT64 */
+	.word	.L_case_v - datalabel .L_table	/* FFI_TYPE_STRUCT */
+	.word	.L_case_i - datalabel .L_table	/* FFI_TYPE_POINTER */
+
+        .align 2
+.L_case_d:
+	fld.d	r14, 16, dr0
+	blink	tr1, r63
+.L_case_f:
+	fld.s	r14, 16, fr0
+	blink	tr1, r63
+.L_case_ll:
+	ld.q	r14, 16, r2
+	blink	tr1, r63
+.L_case_i:
+	ld.l	r14, 16, r2
+	blink	tr1, r63
+.L_case_q:
+	ld.b	r14, 16, r2
+	blink	tr1, r63
+.L_case_uq:
+	ld.ub	r14, 16, r2
+	blink	tr1, r63
+.L_case_h:
+	ld.w	r14, 16, r2
+	blink	tr1, r63
+.L_case_uh:
+	ld.uw	r14, 16, r2
+	blink	tr1, r63
+.L_case_v:
+	add.l	r14, r63, r15
+	ld.l	r15, 4, r12
+	ld.l	r15, 8, r14
+	ld.l	r15, 12, r18
+	addi.l	r15, 136, r15
+	ptabs	r18, tr0
+	blink	tr0, r63
+
+.LFE2:
+.ffi_closure_SYSV_end:
+	.size	 CNAME(ffi_closure_SYSV),.ffi_closure_SYSV_end-CNAME(ffi_closure_SYSV)
+
+	.section	".eh_frame","aw", at progbits
+__FRAME_BEGIN__:
+	.4byte	.LECIE1-.LSCIE1	/* Length of Common Information Entry */
+.LSCIE1:
+	.4byte	0x0	/* CIE Identifier Tag */
+	.byte	0x1	/* CIE Version */
+#ifdef PIC
+	.ascii "zR\0"	/* CIE Augmentation */
+#else
+	.byte	0x0	/* CIE Augmentation */
+#endif
+	.uleb128 0x1	/* CIE Code Alignment Factor */
+	.sleb128 -4	/* CIE Data Alignment Factor */
+	.byte	0x12	/* CIE RA Column */
+#ifdef PIC
+	.uleb128 0x1	/* Augmentation size */
+	.byte	0x10	/* FDE Encoding (pcrel) */
+#endif
+	.byte	0xc	/* DW_CFA_def_cfa */
+	.uleb128 0xf
+	.uleb128 0x0
+	.align	2
+.LECIE1:
+.LSFDE1:
+	.4byte	datalabel .LEFDE1-datalabel .LASFDE1	/* FDE Length */
+.LASFDE1:
+	.4byte	datalabel .LASFDE1-datalabel __FRAME_BEGIN__
+#ifdef PIC
+	.4byte	.LFB1-.	/* FDE initial location */
+#else
+	.4byte	.LFB1	/* FDE initial location */
+#endif
+	.4byte	datalabel .LFE1-datalabel .LFB1	/* FDE address range */
+#ifdef PIC
+	.uleb128 0x0	/* Augmentation size */
+#endif
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	datalabel .LCFI0-datalabel .LFB1
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+	.uleb128 0x30
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	datalabel .LCFI1-datalabel .LCFI0
+	.byte   0x8e	/* DW_CFA_offset, column 0xe */
+	.uleb128 0xc
+	.byte   0x92	/* DW_CFA_offset, column 0x12 */
+	.uleb128 0xb
+	.byte   0x9c	/* DW_CFA_offset, column 0x1c */
+	.uleb128 0xa
+	.byte   0x9d	/* DW_CFA_offset, column 0x1d */
+	.uleb128 0x8
+	.byte   0x9e	/* DW_CFA_offset, column 0x1e */
+	.uleb128 0x6
+	.byte   0x9f	/* DW_CFA_offset, column 0x1f */
+	.uleb128 0x4
+	.byte   0xa0	/* DW_CFA_offset, column 0x20 */
+	.uleb128 0x2
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	datalabel .LCFI2-datalabel .LCFI1
+	.byte	0xd	/* DW_CFA_def_cfa_register */
+	.uleb128 0xe
+	.align	2
+.LEFDE1:
+
+.LSFDE3:
+	.4byte	datalabel .LEFDE3-datalabel .LASFDE3	/* FDE Length */
+.LASFDE3:
+	.4byte	datalabel .LASFDE3-datalabel __FRAME_BEGIN__
+#ifdef PIC
+	.4byte	.LFB2-.	/* FDE initial location */
+#else
+	.4byte	.LFB2	/* FDE initial location */
+#endif
+	.4byte	datalabel .LFE2-datalabel .LFB2	/* FDE address range */
+#ifdef PIC
+	.uleb128 0x0	/* Augmentation size */
+#endif
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	datalabel .LCFI3-datalabel .LFB2
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+	.uleb128 0x88
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	datalabel .LCFI4-datalabel .LCFI3
+	.byte   0x8c	/* DW_CFA_offset, column 0xc */
+	.uleb128 0x21
+	.byte   0x8e	/* DW_CFA_offset, column 0xe */
+	.uleb128 0x20
+	.byte   0x92	/* DW_CFA_offset, column 0x12 */
+	.uleb128 0x1f
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	datalabel .LCFI5-datalabel .LCFI4
+	.byte	0xd	/* DW_CFA_def_cfa_register */
+	.uleb128 0xe
+	.align	2
+.LEFDE3:

Added: vendor/Python/current/Modules/_ctypes/libffi/src/sparc/ffi.c
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/sparc/ffi.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/sparc/ffi.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,608 @@
+/* -----------------------------------------------------------------------
+   ffi.c - Copyright (c) 1996, 2003, 2004 Red Hat, Inc.
+   
+   SPARC Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+
+
+/* ffi_prep_args is called by the assembly routine once stack space
+   has been allocated for the function's arguments */
+
+void ffi_prep_args_v8(char *stack, extended_cif *ecif)
+{
+  int i;
+  void **p_argv;
+  char *argp;
+  ffi_type **p_arg;
+
+  /* Skip 16 words for the window save area */
+  argp = stack + 16*sizeof(int);
+
+  /* This should only really be done when we are returning a structure,
+     however, it's faster just to do it all the time...
+
+  if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT ) */
+  *(int *) argp = (long)ecif->rvalue;
+
+  /* And 1 word for the  structure return value. */
+  argp += sizeof(int);
+
+#ifdef USING_PURIFY
+  /* Purify will probably complain in our assembly routine, unless we
+     zero out this memory. */
+
+  ((int*)argp)[0] = 0;
+  ((int*)argp)[1] = 0;
+  ((int*)argp)[2] = 0;
+  ((int*)argp)[3] = 0;
+  ((int*)argp)[4] = 0;
+  ((int*)argp)[5] = 0;
+#endif
+
+  p_argv = ecif->avalue;
+
+  for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; i; i--, p_arg++)
+    {
+      size_t z;
+
+	  if ((*p_arg)->type == FFI_TYPE_STRUCT
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+	      || (*p_arg)->type == FFI_TYPE_LONGDOUBLE
+#endif
+	      )
+	    {
+	      *(unsigned int *) argp = (unsigned long)(* p_argv);
+	      z = sizeof(int);
+	    }
+	  else
+	    {
+	      z = (*p_arg)->size;
+	      if (z < sizeof(int))
+		{
+		  z = sizeof(int);
+		  switch ((*p_arg)->type)
+		    {
+		    case FFI_TYPE_SINT8:
+		      *(signed int *) argp = *(SINT8 *)(* p_argv);
+		      break;
+		      
+		    case FFI_TYPE_UINT8:
+		      *(unsigned int *) argp = *(UINT8 *)(* p_argv);
+		      break;
+		      
+		    case FFI_TYPE_SINT16:
+		      *(signed int *) argp = *(SINT16 *)(* p_argv);
+		      break;
+		      
+		    case FFI_TYPE_UINT16:
+		      *(unsigned int *) argp = *(UINT16 *)(* p_argv);
+		      break;
+
+		    default:
+		      FFI_ASSERT(0);
+		    }
+		}
+	      else
+		{
+		  memcpy(argp, *p_argv, z);
+		}
+	    }
+	  p_argv++;
+	  argp += z;
+    }
+  
+  return;
+}
+
+int ffi_prep_args_v9(char *stack, extended_cif *ecif)
+{
+  int i, ret = 0;
+  int tmp;
+  void **p_argv;
+  char *argp;
+  ffi_type **p_arg;
+
+  tmp = 0;
+
+  /* Skip 16 words for the window save area */
+  argp = stack + 16*sizeof(long long);
+
+#ifdef USING_PURIFY
+  /* Purify will probably complain in our assembly routine, unless we
+     zero out this memory. */
+
+  ((long long*)argp)[0] = 0;
+  ((long long*)argp)[1] = 0;
+  ((long long*)argp)[2] = 0;
+  ((long long*)argp)[3] = 0;
+  ((long long*)argp)[4] = 0;
+  ((long long*)argp)[5] = 0;
+#endif
+
+  p_argv = ecif->avalue;
+
+  if (ecif->cif->rtype->type == FFI_TYPE_STRUCT &&
+      ecif->cif->rtype->size > 32)
+    {
+      *(unsigned long long *) argp = (unsigned long)ecif->rvalue;
+      argp += sizeof(long long);
+      tmp = 1;
+    }
+
+  for (i = 0, p_arg = ecif->cif->arg_types; i < ecif->cif->nargs;
+       i++, p_arg++)
+    {
+      size_t z;
+
+      z = (*p_arg)->size;
+      switch ((*p_arg)->type)
+	{
+	case FFI_TYPE_STRUCT:
+	  if (z > 16)
+	    {
+	      /* For structures larger than 16 bytes we pass reference.  */
+	      *(unsigned long long *) argp = (unsigned long)* p_argv;
+	      argp += sizeof(long long);
+	      tmp++;
+	      p_argv++;
+	      continue;
+	    }
+	  /* FALLTHROUGH */
+	case FFI_TYPE_FLOAT:
+	case FFI_TYPE_DOUBLE:
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+	case FFI_TYPE_LONGDOUBLE:
+#endif
+	  ret = 1; /* We should promote into FP regs as well as integer.  */
+	  break;
+	}
+      if (z < sizeof(long long))
+	{
+	  switch ((*p_arg)->type)
+	    {
+	    case FFI_TYPE_SINT8:
+	      *(signed long long *) argp = *(SINT8 *)(* p_argv);
+	      break;
+
+	    case FFI_TYPE_UINT8:
+	      *(unsigned long long *) argp = *(UINT8 *)(* p_argv);
+	      break;
+
+	    case FFI_TYPE_SINT16:
+	      *(signed long long *) argp = *(SINT16 *)(* p_argv);
+	      break;
+
+	    case FFI_TYPE_UINT16:
+	      *(unsigned long long *) argp = *(UINT16 *)(* p_argv);
+	      break;
+
+	    case FFI_TYPE_SINT32:
+	      *(signed long long *) argp = *(SINT32 *)(* p_argv);
+	      break;
+
+	    case FFI_TYPE_UINT32:
+	      *(unsigned long long *) argp = *(UINT32 *)(* p_argv);
+	      break;
+
+	    case FFI_TYPE_FLOAT:
+	      *(float *) (argp + 4) = *(FLOAT32 *)(* p_argv); /* Right justify */
+	      break;
+
+	    case FFI_TYPE_STRUCT:
+	      memcpy(argp, *p_argv, z);
+	      break;
+
+	    default:
+	      FFI_ASSERT(0);
+	    }
+	  z = sizeof(long long);
+	  tmp++;
+	}
+      else if (z == sizeof(long long))
+	{
+	  memcpy(argp, *p_argv, z);
+	  z = sizeof(long long);
+	  tmp++;
+	}
+      else
+	{
+	  if ((tmp & 1) && (*p_arg)->alignment > 8)
+	    {
+	      tmp++;
+	      argp += sizeof(long long);
+	    }
+	  memcpy(argp, *p_argv, z);
+	  z = 2 * sizeof(long long);
+	  tmp += 2;
+	}
+      p_argv++;
+      argp += z;
+    }
+
+  return ret;
+}
+
+/* Perform machine dependent cif processing */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+{
+  int wordsize;
+
+  if (cif->abi != FFI_V9)
+    {
+      wordsize = 4;
+
+      /* If we are returning a struct, this will already have been added.
+	 Otherwise we need to add it because it's always got to be there! */
+
+      if (cif->rtype->type != FFI_TYPE_STRUCT)
+	cif->bytes += wordsize;
+
+      /* sparc call frames require that space is allocated for 6 args,
+	 even if they aren't used. Make that space if necessary. */
+  
+      if (cif->bytes < 4*6+4)
+	cif->bytes = 4*6+4;
+    }
+  else
+    {
+      wordsize = 8;
+
+      /* sparc call frames require that space is allocated for 6 args,
+	 even if they aren't used. Make that space if necessary. */
+  
+      if (cif->bytes < 8*6)
+	cif->bytes = 8*6;
+    }
+
+  /* Adjust cif->bytes. to include 16 words for the window save area,
+     and maybe the struct/union return pointer area, */
+
+  cif->bytes += 16 * wordsize;
+
+  /* The stack must be 2 word aligned, so round bytes up
+     appropriately. */
+
+  cif->bytes = ALIGN(cif->bytes, 2 * wordsize);
+
+  /* Set the return type flag */
+  switch (cif->rtype->type)
+    {
+    case FFI_TYPE_VOID:
+    case FFI_TYPE_FLOAT:
+    case FFI_TYPE_DOUBLE:
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+    case FFI_TYPE_LONGDOUBLE:
+#endif
+      cif->flags = cif->rtype->type;
+      break;
+
+    case FFI_TYPE_STRUCT:
+      if (cif->abi == FFI_V9 && cif->rtype->size > 32)
+	cif->flags = FFI_TYPE_VOID;
+      else
+	cif->flags = FFI_TYPE_STRUCT;
+      break;
+
+    case FFI_TYPE_SINT64:
+    case FFI_TYPE_UINT64:
+      if (cif->abi != FFI_V9)
+	{
+	  cif->flags = FFI_TYPE_SINT64;
+	  break;
+	}
+      /* FALLTHROUGH */
+    default:
+      cif->flags = FFI_TYPE_INT;
+      break;
+    }
+  return FFI_OK;
+}
+
+int ffi_v9_layout_struct(ffi_type *arg, int off, char *ret, char *intg, char *flt)
+{
+  ffi_type **ptr = &arg->elements[0];
+
+  while (*ptr != NULL)
+    {
+      if (off & ((*ptr)->alignment - 1))
+	off = ALIGN(off, (*ptr)->alignment);
+
+      switch ((*ptr)->type)
+	{
+	case FFI_TYPE_STRUCT:
+	  off = ffi_v9_layout_struct(*ptr, off, ret, intg, flt);
+	  off = ALIGN(off, FFI_SIZEOF_ARG);
+	  break;
+	case FFI_TYPE_FLOAT:
+	case FFI_TYPE_DOUBLE:
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+	case FFI_TYPE_LONGDOUBLE:
+#endif
+	  memmove(ret + off, flt + off, (*ptr)->size);
+	  off += (*ptr)->size;
+	  break;
+	default:
+	  memmove(ret + off, intg + off, (*ptr)->size);
+	  off += (*ptr)->size;
+	  break;
+	}
+      ptr++;
+    }
+  return off;
+}
+
+
+#ifdef SPARC64
+extern int ffi_call_v9(void *, extended_cif *, unsigned, 
+		       unsigned, unsigned *, void (*fn)());
+#else
+extern int ffi_call_v8(void *, extended_cif *, unsigned, 
+		       unsigned, unsigned *, void (*fn)());
+#endif
+
+void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
+{
+  extended_cif ecif;
+  void *rval = rvalue;
+
+  ecif.cif = cif;
+  ecif.avalue = avalue;
+
+  /* If the return value is a struct and we don't have a return	*/
+  /* value address then we need to make one		        */
+
+  ecif.rvalue = rvalue;
+  if (cif->rtype->type == FFI_TYPE_STRUCT)
+    {
+      if (cif->rtype->size <= 32)
+	rval = alloca(64);
+      else
+	{
+	  rval = NULL;
+	  if (rvalue == NULL)
+	    ecif.rvalue = alloca(cif->rtype->size);
+	}
+    }
+
+  switch (cif->abi) 
+    {
+    case FFI_V8:
+#ifdef SPARC64
+      /* We don't yet support calling 32bit code from 64bit */
+      FFI_ASSERT(0);
+#else
+      ffi_call_v8(ffi_prep_args_v8, &ecif, cif->bytes, 
+		  cif->flags, rvalue, fn);
+#endif
+      break;
+    case FFI_V9:
+#ifdef SPARC64
+      ffi_call_v9(ffi_prep_args_v9, &ecif, cif->bytes,
+		  cif->flags, rval, fn);
+      if (rvalue && rval && cif->rtype->type == FFI_TYPE_STRUCT)
+	ffi_v9_layout_struct(cif->rtype, 0, (char *)rvalue, (char *)rval, ((char *)rval)+32);
+#else
+      /* And vice versa */
+      FFI_ASSERT(0);
+#endif
+      break;
+    default:
+      FFI_ASSERT(0);
+      break;
+    }
+
+}
+
+
+#ifdef SPARC64
+extern void ffi_closure_v9(void);
+#else
+extern void ffi_closure_v8(void);
+#endif
+
+ffi_status
+ffi_prep_closure (ffi_closure* closure,
+		  ffi_cif* cif,
+		  void (*fun)(ffi_cif*, void*, void**, void*),
+		  void *user_data)
+{
+  unsigned int *tramp = (unsigned int *) &closure->tramp[0];
+  unsigned long fn;
+#ifdef SPARC64
+  /* Trampoline address is equal to the closure address.  We take advantage
+     of that to reduce the trampoline size by 8 bytes. */
+  FFI_ASSERT (cif->abi == FFI_V9);
+  fn = (unsigned long) ffi_closure_v9;
+  tramp[0] = 0x83414000;	/* rd	%pc, %g1	*/
+  tramp[1] = 0xca586010;	/* ldx	[%g1+16], %g5	*/
+  tramp[2] = 0x81c14000;	/* jmp	%g5		*/
+  tramp[3] = 0x01000000;	/* nop			*/
+  *((unsigned long *) &tramp[4]) = fn;
+#else
+  unsigned long ctx = (unsigned long) closure;
+  FFI_ASSERT (cif->abi == FFI_V8);
+  fn = (unsigned long) ffi_closure_v8;
+  tramp[0] = 0x03000000 | fn >> 10;	/* sethi %hi(fn), %g1	*/
+  tramp[1] = 0x05000000 | ctx >> 10;	/* sethi %hi(ctx), %g2	*/
+  tramp[2] = 0x81c06000 | (fn & 0x3ff);	/* jmp   %g1+%lo(fn)	*/
+  tramp[3] = 0x8410a000 | (ctx & 0x3ff);/* or    %g2, %lo(ctx)	*/
+#endif
+
+  closure->cif = cif;
+  closure->fun = fun;
+  closure->user_data = user_data;
+
+  /* Flush the Icache.  FIXME: alignment isn't certain, assume 8 bytes */
+#ifdef SPARC64
+  asm volatile ("flush	%0" : : "r" (closure) : "memory");
+  asm volatile ("flush	%0" : : "r" (((char *) closure) + 8) : "memory");
+#else
+  asm volatile ("iflush	%0" : : "r" (closure) : "memory");
+  asm volatile ("iflush	%0" : : "r" (((char *) closure) + 8) : "memory");
+#endif
+
+  return FFI_OK;
+}
+
+int
+ffi_closure_sparc_inner_v8(ffi_closure *closure,
+  void *rvalue, unsigned long *gpr, unsigned long *scratch)
+{
+  ffi_cif *cif;
+  ffi_type **arg_types;
+  void **avalue;
+  int i, argn;
+
+  cif = closure->cif;
+  arg_types = cif->arg_types;
+  avalue = alloca(cif->nargs * sizeof(void *));
+
+  /* Copy the caller's structure return address so that the closure
+     returns the data directly to the caller.  */
+  if (cif->flags == FFI_TYPE_STRUCT
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE  
+      || cif->flags == FFI_TYPE_LONGDOUBLE
+#endif
+     )
+    rvalue = (void *) gpr[0];
+
+  /* Always skip the structure return address.  */
+  argn = 1;
+
+  /* Grab the addresses of the arguments from the stack frame.  */
+  for (i = 0; i < cif->nargs; i++)
+    {
+      if (arg_types[i]->type == FFI_TYPE_STRUCT
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+	  || arg_types[i]->type == FFI_TYPE_LONGDOUBLE
+#endif
+         )
+	{
+	  /* Straight copy of invisible reference.  */
+	  avalue[i] = (void *)gpr[argn++];
+	}
+      else if ((arg_types[i]->type == FFI_TYPE_DOUBLE
+	       || arg_types[i]->type == FFI_TYPE_SINT64
+	       || arg_types[i]->type == FFI_TYPE_UINT64)
+	       /* gpr is 8-byte aligned.  */
+	       && (argn % 2) != 0)
+	{
+	  /* Align on a 8-byte boundary.  */
+	  scratch[0] = gpr[argn];
+	  scratch[1] = gpr[argn+1];
+	  avalue[i] = scratch;
+	  scratch -= 2;
+	  argn += 2;
+	}
+      else
+	{
+	  /* Always right-justify.  */
+	  argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
+	  avalue[i] = ((char *) &gpr[argn]) - arg_types[i]->size;
+	}
+    }
+
+  /* Invoke the closure.  */
+  (closure->fun) (cif, rvalue, avalue, closure->user_data);
+
+  /* Tell ffi_closure_sparc how to perform return type promotions.  */
+  return cif->rtype->type;
+}
+
+int
+ffi_closure_sparc_inner_v9(ffi_closure *closure,
+  void *rvalue, unsigned long *gpr, double *fpr)
+{
+  ffi_cif *cif;
+  ffi_type **arg_types;
+  void **avalue;
+  int i, argn, fp_slot_max;
+
+  cif = closure->cif;
+  arg_types = cif->arg_types;
+  avalue = alloca(cif->nargs * sizeof(void *));
+
+  /* Copy the caller's structure return address so that the closure
+     returns the data directly to the caller.  */
+  if (cif->flags == FFI_TYPE_VOID
+      && cif->rtype->type == FFI_TYPE_STRUCT)
+    {
+      rvalue = (void *) gpr[0];
+      /* Skip the structure return address.  */
+      argn = 1;
+    }
+  else
+    argn = 0;
+
+  fp_slot_max = 16 - argn;
+
+  /* Grab the addresses of the arguments from the stack frame.  */
+  for (i = 0; i < cif->nargs; i++)
+    {
+      if (arg_types[i]->type == FFI_TYPE_STRUCT)
+	{
+	  if (arg_types[i]->size > 16)
+	    {
+	      /* Straight copy of invisible reference.  */
+	      avalue[i] = (void *)gpr[argn++];
+	    }
+	  else
+	    {
+	      /* Left-justify.  */
+	      ffi_v9_layout_struct(arg_types[i],
+				   0,
+				   (char *) &gpr[argn],
+				   (char *) &gpr[argn],
+				   (char *) &fpr[argn]);
+	      avalue[i] = &gpr[argn];
+	      argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
+	    }
+	}
+      else
+	{
+	  /* Right-justify.  */
+	  argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
+
+	  if (i < fp_slot_max
+	      && (arg_types[i]->type == FFI_TYPE_FLOAT
+		  || arg_types[i]->type == FFI_TYPE_DOUBLE
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+		  || arg_types[i]->type == FFI_TYPE_LONGDOUBLE
+#endif
+		  ))
+	    avalue[i] = ((char *) &fpr[argn]) - arg_types[i]->size;
+	  else
+	    avalue[i] = ((char *) &gpr[argn]) - arg_types[i]->size;
+	}
+    }
+
+  /* Invoke the closure.  */
+  (closure->fun) (cif, rvalue, avalue, closure->user_data);
+
+  /* Tell ffi_closure_sparc how to perform return type promotions.  */
+  return cif->rtype->type;
+}

Added: vendor/Python/current/Modules/_ctypes/libffi/src/sparc/ffitarget.h
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/sparc/ffitarget.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/sparc/ffitarget.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,65 @@
+/* -----------------------------------------------------------------*-C-*-
+   ffitarget.h - Copyright (c) 1996-2003  Red Hat, Inc.
+   Target configuration macros for SPARC.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+
+   ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+/* ---- System specific configurations ----------------------------------- */
+
+#if defined(__arch64__) || defined(__sparcv9)
+#define SPARC64
+#endif
+
+#ifndef LIBFFI_ASM
+typedef unsigned long          ffi_arg;
+typedef signed long            ffi_sarg;
+
+typedef enum ffi_abi {
+  FFI_FIRST_ABI = 0,
+  FFI_V8,
+  FFI_V8PLUS,
+  FFI_V9,
+#ifdef SPARC64
+  FFI_DEFAULT_ABI = FFI_V9,
+#else
+  FFI_DEFAULT_ABI = FFI_V8,
+#endif
+  FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
+} ffi_abi;
+#endif
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#define FFI_CLOSURES 1
+#define FFI_NATIVE_RAW_API 0
+
+#ifdef SPARC64
+#define FFI_TRAMPOLINE_SIZE 24
+#else
+#define FFI_TRAMPOLINE_SIZE 16
+#endif
+
+#endif
+

Added: vendor/Python/current/Modules/_ctypes/libffi/src/sparc/v8.S
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/sparc/v8.S	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/sparc/v8.S	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,267 @@
+/* -----------------------------------------------------------------------
+   v8.S - Copyright (c) 1996, 1997, 2003, 2004 Red Hat, Inc.
+   
+   SPARC Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM	
+#include <fficonfig.h>
+#include <ffi.h>
+
+#define STACKFRAME 96		/* Minimum stack framesize for SPARC */
+#define ARGS (64+4)		/* Offset of register area in frame */
+
+.text
+        .align 8
+.globl ffi_call_v8
+.globl _ffi_call_v8
+
+ffi_call_v8:
+_ffi_call_v8:
+.LLFB1:
+	save	%sp, -STACKFRAME, %sp
+.LLCFI0:
+	
+	sub	%sp, %i2, %sp	! alloca() space in stack for frame to set up
+	add	%sp, STACKFRAME, %l0	! %l0 has start of 
+					! frame to set up
+
+	mov	%l0, %o0	! call routine to set up frame
+	call	%i0
+	mov	%i1, %o1	! (delay)
+
+	ld	[%l0+ARGS], %o0	! call foreign function
+	ld	[%l0+ARGS+4], %o1
+	ld	[%l0+ARGS+8], %o2
+	ld	[%l0+ARGS+12], %o3
+	ld	[%l0+ARGS+16], %o4
+	ld	[%l0+ARGS+20], %o5
+	call	%i5
+	mov	%l0, %sp	! (delay) switch to frame
+	nop			! STRUCT returning functions skip 12 instead of 8 bytes
+
+	! If the return value pointer is NULL, assume no return value.
+	tst	%i4
+	bz	done
+	nop
+
+	cmp	%i3, FFI_TYPE_INT
+	be,a	done
+	st	%o0, [%i4]	! (delay)
+
+	cmp	%i3, FFI_TYPE_FLOAT
+	be,a	done
+	st	%f0, [%i4+0]	! (delay)
+
+	cmp	%i3, FFI_TYPE_SINT64
+	be	longlong
+
+	cmp	%i3, FFI_TYPE_DOUBLE
+	bne	done
+	nop
+	st	%f0, [%i4+0]
+	st	%f1, [%i4+4]
+	
+done:
+	ret
+	restore
+
+longlong:
+	st	%o0, [%i4+0]
+	st	%o1, [%i4+4]
+	ret
+	restore
+.LLFE1:
+
+.ffi_call_v8_end:
+	.size	ffi_call_v8,.ffi_call_v8_end-ffi_call_v8
+
+
+#undef STACKFRAME
+#define	STACKFRAME	104	/* 16*4 register window +
+				   1*4 struct return +	
+				   6*4 args backing store +
+				   3*4 locals */
+
+/* ffi_closure_v8(...)
+
+   Receives the closure argument in %g2.   */
+
+	.text
+	.align 8
+	.globl ffi_closure_v8
+
+ffi_closure_v8:
+#ifdef HAVE_AS_REGISTER_PSEUDO_OP
+		.register	%g2, #scratch
+#endif
+.LLFB2:
+	! Reserve frame space for all arguments in case
+	! we need to align them on a 8-byte boundary.
+	ld	[%g2+FFI_TRAMPOLINE_SIZE], %g1
+	ld	[%g1+4], %g1
+	sll	%g1, 3, %g1
+	add	%g1, STACKFRAME, %g1
+	! %g1 == STACKFRAME + 8*nargs
+	neg	%g1
+	save	%sp, %g1, %sp
+.LLCFI1:
+
+	! Store all of the potential argument registers in va_list format.
+	st	%i0, [%fp+68+0]
+	st	%i1, [%fp+68+4]
+	st	%i2, [%fp+68+8]
+	st	%i3, [%fp+68+12]
+	st	%i4, [%fp+68+16]
+	st	%i5, [%fp+68+20]
+
+	! Call ffi_closure_sparc_inner to do the bulk of the work.
+	mov	%g2, %o0
+	add	%fp, -8, %o1
+	add	%fp,  64, %o2
+	call	ffi_closure_sparc_inner_v8
+	 add	%fp, -16, %o3
+
+	! Load up the return value in the proper type.
+	! See ffi_prep_cif_machdep for the list of cases.
+	cmp	%o0, FFI_TYPE_VOID
+	be	done1
+
+	cmp	%o0, FFI_TYPE_INT
+	be	integer
+
+	cmp	%o0, FFI_TYPE_FLOAT
+	be,a	done1
+	 ld	[%fp-8], %f0
+
+	cmp	%o0, FFI_TYPE_DOUBLE
+	be,a	done1
+	 ldd	[%fp-8], %f0
+
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+	cmp	%o0, FFI_TYPE_LONGDOUBLE
+	be	done2
+#endif
+
+	cmp	%o0, FFI_TYPE_STRUCT
+	be	done2
+
+	! FFI_TYPE_SINT64
+	! FFI_TYPE_UINT64
+	ld	[%fp-4], %i1
+
+integer:
+	ld	[%fp-8], %i0
+
+done1:
+	jmp	%i7+8
+	 restore
+done2:
+	! Skip 'unimp'.
+	jmp	%i7+12
+	 restore
+.LLFE2:
+
+.ffi_closure_v8_end:
+	.size	ffi_closure_v8,.ffi_closure_v8_end-ffi_closure_v8
+
+#ifdef SPARC64
+#define WS 8
+#define nword	xword
+#define uanword	uaxword
+#else
+#define WS 4
+#define nword	long
+#define uanword	uaword
+#endif
+
+#ifdef HAVE_RO_EH_FRAME
+	.section	".eh_frame",#alloc
+#else
+	.section	".eh_frame",#alloc,#write
+#endif
+.LLframe1:
+	.uaword	.LLECIE1-.LLSCIE1	! Length of Common Information Entry
+.LLSCIE1:
+	.uaword	0x0	! CIE Identifier Tag
+	.byte	0x1	! CIE Version
+	.ascii "zR\0"	! CIE Augmentation
+	.byte	0x1	! uleb128 0x1; CIE Code Alignment Factor
+	.byte	0x80-WS	! sleb128 -WS; CIE Data Alignment Factor
+	.byte	0xf	! CIE RA Column
+	.byte	0x1	! uleb128 0x1; Augmentation size
+#ifdef HAVE_AS_SPARC_UA_PCREL
+	.byte	0x1b	! FDE Encoding (pcrel sdata4)
+#else
+	.byte	0x50	! FDE Encoding (aligned absolute)
+#endif
+	.byte	0xc	! DW_CFA_def_cfa
+	.byte	0xe	! uleb128 0xe
+	.byte	0x0	! uleb128 0x0
+	.align	WS
+.LLECIE1:
+.LLSFDE1:
+	.uaword	.LLEFDE1-.LLASFDE1	! FDE Length
+.LLASFDE1:
+	.uaword	.LLASFDE1-.LLframe1	! FDE CIE offset
+#ifdef HAVE_AS_SPARC_UA_PCREL
+	.uaword	%r_disp32(.LLFB1)
+	.uaword	.LLFE1-.LLFB1	! FDE address range
+#else
+	.align	WS
+	.nword	.LLFB1
+	.uanword .LLFE1-.LLFB1	! FDE address range
+#endif
+	.byte	0x0	! uleb128 0x0; Augmentation size
+	.byte	0x4	! DW_CFA_advance_loc4
+	.uaword	.LLCFI0-.LLFB1
+	.byte	0xd	! DW_CFA_def_cfa_register
+	.byte	0x1e	! uleb128 0x1e
+	.byte	0x2d	! DW_CFA_GNU_window_save
+	.byte	0x9	! DW_CFA_register
+	.byte	0xf	! uleb128 0xf
+	.byte	0x1f	! uleb128 0x1f
+	.align	WS
+.LLEFDE1:
+.LLSFDE2:
+	.uaword	.LLEFDE2-.LLASFDE2	! FDE Length
+.LLASFDE2:
+	.uaword	.LLASFDE2-.LLframe1	! FDE CIE offset
+#ifdef HAVE_AS_SPARC_UA_PCREL
+	.uaword	%r_disp32(.LLFB2)
+	.uaword	.LLFE2-.LLFB2	! FDE address range
+#else
+	.align	WS
+	.nword	.LLFB2
+	.uanword .LLFE2-.LLFB2	! FDE address range
+#endif
+	.byte	0x0	! uleb128 0x0; Augmentation size
+	.byte	0x4	! DW_CFA_advance_loc4
+	.uaword	.LLCFI1-.LLFB2
+	.byte	0xd	! DW_CFA_def_cfa_register
+	.byte	0x1e	! uleb128 0x1e
+	.byte	0x2d	! DW_CFA_GNU_window_save
+	.byte	0x9	! DW_CFA_register
+	.byte	0xf	! uleb128 0xf
+	.byte	0x1f	! uleb128 0x1f
+	.align	WS
+.LLEFDE2:

Added: vendor/Python/current/Modules/_ctypes/libffi/src/sparc/v9.S
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/sparc/v9.S	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/sparc/v9.S	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,302 @@
+/* -----------------------------------------------------------------------
+   v9.S - Copyright (c) 2000, 2003, 2004 Red Hat, Inc.
+   
+   SPARC 64-bit Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM	
+#include <fficonfig.h>
+#include <ffi.h>
+
+#ifdef SPARC64
+/* Only compile this in for 64bit builds, because otherwise the object file
+   will have inproper architecture due to used instructions.  */
+
+#define STACKFRAME 128		/* Minimum stack framesize for SPARC */
+#define STACK_BIAS 2047
+#define ARGS (128)		/* Offset of register area in frame */
+
+.text
+        .align 8
+.globl ffi_call_v9
+.globl _ffi_call_v9
+
+ffi_call_v9:
+_ffi_call_v9:
+.LLFB1:
+	save	%sp, -STACKFRAME, %sp
+.LLCFI0:
+	
+	sub	%sp, %i2, %sp	! alloca() space in stack for frame to set up
+	add	%sp, STACKFRAME+STACK_BIAS, %l0	! %l0 has start of 
+						! frame to set up
+
+	mov	%l0, %o0	! call routine to set up frame
+	call	%i0
+	 mov	%i1, %o1	! (delay)
+	brz,pt	%o0, 1f
+	 ldx	[%l0+ARGS], %o0	! call foreign function
+
+	ldd	[%l0+ARGS], %f0
+	ldd	[%l0+ARGS+8], %f2
+	ldd	[%l0+ARGS+16], %f4
+	ldd	[%l0+ARGS+24], %f6
+	ldd	[%l0+ARGS+32], %f8
+	ldd	[%l0+ARGS+40], %f10
+	ldd	[%l0+ARGS+48], %f12
+	ldd	[%l0+ARGS+56], %f14
+	ldd	[%l0+ARGS+64], %f16
+	ldd	[%l0+ARGS+72], %f18
+	ldd	[%l0+ARGS+80], %f20
+	ldd	[%l0+ARGS+88], %f22
+	ldd	[%l0+ARGS+96], %f24
+	ldd	[%l0+ARGS+104], %f26
+	ldd	[%l0+ARGS+112], %f28
+	ldd	[%l0+ARGS+120], %f30
+
+1:	ldx	[%l0+ARGS+8], %o1
+	ldx	[%l0+ARGS+16], %o2
+	ldx	[%l0+ARGS+24], %o3
+	ldx	[%l0+ARGS+32], %o4
+	ldx	[%l0+ARGS+40], %o5
+	call	%i5
+	 sub	%l0, STACK_BIAS, %sp	! (delay) switch to frame
+
+	! If the return value pointer is NULL, assume no return value.
+	brz,pn	%i4, done
+	 nop
+
+	cmp	%i3, FFI_TYPE_INT
+	be,a,pt	%icc, done
+	 stx	%o0, [%i4+0]	! (delay)
+
+	cmp	%i3, FFI_TYPE_FLOAT
+	be,a,pn	%icc, done
+	 st	%f0, [%i4+0]	! (delay)
+
+	cmp	%i3, FFI_TYPE_DOUBLE
+	be,a,pn	%icc, done
+	 std	%f0, [%i4+0]	! (delay)
+
+	cmp	%i3, FFI_TYPE_STRUCT
+	be,pn	%icc, dostruct
+
+	cmp	%i3, FFI_TYPE_LONGDOUBLE
+	bne,pt	%icc, done
+	 nop
+	std	%f0, [%i4+0]
+	std	%f2, [%i4+8]
+
+done:	ret
+	 restore
+
+dostruct:
+	/* This will not work correctly for unions. */
+	stx	%o0, [%i4+0]
+	stx	%o1, [%i4+8]
+	stx	%o2, [%i4+16]
+	stx	%o3, [%i4+24]
+	std	%f0, [%i4+32]
+	std	%f2, [%i4+40]
+	std	%f4, [%i4+48]
+	std	%f6, [%i4+56]
+	ret
+	 restore
+.LLFE1:
+
+.ffi_call_v9_end:
+	.size	ffi_call_v9,.ffi_call_v9_end-ffi_call_v9
+
+
+#undef STACKFRAME
+#define	STACKFRAME	 336	/* 16*8 register window +
+				   6*8 args backing store +
+				   20*8 locals */
+#define	FP		%fp+STACK_BIAS
+
+/* ffi_closure_v9(...)
+
+   Receives the closure argument in %g1.   */
+
+	.text
+	.align 8
+	.globl ffi_closure_v9
+
+ffi_closure_v9:
+.LLFB2:
+	save	%sp, -STACKFRAME, %sp
+.LLCFI1:
+
+	! Store all of the potential argument registers in va_list format.
+	stx	%i0, [FP+128+0]
+	stx	%i1, [FP+128+8]
+	stx	%i2, [FP+128+16]
+	stx	%i3, [FP+128+24]
+	stx	%i4, [FP+128+32]
+	stx	%i5, [FP+128+40]
+
+	! Store possible floating point argument registers too.
+	std	%f0,  [FP-128]
+	std	%f2,  [FP-120]
+	std	%f4,  [FP-112]
+	std	%f6,  [FP-104]
+	std	%f8,  [FP-96]
+	std	%f10, [FP-88]
+	std     %f12, [FP-80]
+	std     %f14, [FP-72]
+	std     %f16, [FP-64]
+	std     %f18, [FP-56]
+	std     %f20, [FP-48]
+	std     %f22, [FP-40]
+	std     %f24, [FP-32]
+	std     %f26, [FP-24]
+	std     %f28, [FP-16]
+	std     %f30, [FP-8]
+
+	! Call ffi_closure_sparc_inner to do the bulk of the work.
+	mov	%g1, %o0
+	add	%fp, STACK_BIAS-160, %o1
+	add	%fp, STACK_BIAS+128, %o2
+	call	ffi_closure_sparc_inner_v9
+	 add	%fp, STACK_BIAS-128, %o3
+
+	! Load up the return value in the proper type.
+	! See ffi_prep_cif_machdep for the list of cases.
+	cmp	%o0, FFI_TYPE_VOID
+	be,pn	%icc, done1
+
+	cmp	%o0, FFI_TYPE_INT
+	be,pn	%icc, integer
+
+	cmp	%o0, FFI_TYPE_FLOAT
+	be,a,pn	%icc, done1
+	 ld	[FP-160], %f0
+
+	cmp	%o0, FFI_TYPE_DOUBLE
+	be,a,pn	%icc, done1
+	 ldd	[FP-160], %f0
+
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+	cmp	%o0, FFI_TYPE_LONGDOUBLE
+	be,a,pn	%icc, longdouble1
+	 ldd	[FP-160], %f0
+#endif
+
+	! FFI_TYPE_STRUCT
+	ldx	[FP-152], %i1
+	ldx	[FP-144], %i2
+	ldx	[FP-136], %i3
+	ldd	[FP-160], %f0
+	ldd	[FP-152], %f2
+	ldd	[FP-144], %f4
+	ldd	[FP-136], %f6
+
+integer:
+	ldx	[FP-160], %i0
+
+done1:
+	ret
+	 restore
+
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+longdouble1:
+	ldd	[FP-152], %f2
+	ret
+	 restore
+#endif
+.LLFE2:
+
+.ffi_closure_v9_end:
+	.size	ffi_closure_v9,.ffi_closure_v9_end-ffi_closure_v9
+
+#ifdef HAVE_RO_EH_FRAME
+	.section	".eh_frame",#alloc
+#else
+	.section	".eh_frame",#alloc,#write
+#endif
+.LLframe1:
+	.uaword	.LLECIE1-.LLSCIE1	! Length of Common Information Entry
+.LLSCIE1:
+	.uaword	0x0	! CIE Identifier Tag
+	.byte	0x1	! CIE Version
+	.ascii "zR\0"	! CIE Augmentation
+	.byte	0x1	! uleb128 0x1; CIE Code Alignment Factor
+	.byte	0x78	! sleb128 -8; CIE Data Alignment Factor
+	.byte	0xf	! CIE RA Column
+	.byte	0x1	! uleb128 0x1; Augmentation size
+#ifdef HAVE_AS_SPARC_UA_PCREL
+	.byte	0x1b	! FDE Encoding (pcrel sdata4)
+#else
+	.byte	0x50	! FDE Encoding (aligned absolute)
+#endif
+	.byte	0xc	! DW_CFA_def_cfa
+	.byte	0xe	! uleb128 0xe
+	.byte	0xff,0xf	! uleb128 0x7ff
+	.align 8
+.LLECIE1:
+.LLSFDE1:
+	.uaword	.LLEFDE1-.LLASFDE1	! FDE Length
+.LLASFDE1:
+	.uaword	.LLASFDE1-.LLframe1	! FDE CIE offset
+#ifdef HAVE_AS_SPARC_UA_PCREL
+	.uaword	%r_disp32(.LLFB1)
+	.uaword	.LLFE1-.LLFB1		! FDE address range
+#else
+	.align 8
+	.xword	.LLFB1
+	.uaxword	.LLFE1-.LLFB1	! FDE address range
+#endif
+	.byte	0x0	! uleb128 0x0; Augmentation size
+	.byte	0x4	! DW_CFA_advance_loc4
+	.uaword	.LLCFI0-.LLFB1
+	.byte	0xd	! DW_CFA_def_cfa_register
+	.byte	0x1e	! uleb128 0x1e
+	.byte	0x2d	! DW_CFA_GNU_window_save
+	.byte	0x9	! DW_CFA_register
+	.byte	0xf	! uleb128 0xf
+	.byte	0x1f	! uleb128 0x1f
+	.align 8
+.LLEFDE1:
+.LLSFDE2:
+	.uaword	.LLEFDE2-.LLASFDE2	! FDE Length
+.LLASFDE2:
+	.uaword	.LLASFDE2-.LLframe1	! FDE CIE offset
+#ifdef HAVE_AS_SPARC_UA_PCREL
+	.uaword	%r_disp32(.LLFB2)
+	.uaword	.LLFE2-.LLFB2		! FDE address range
+#else
+	.align 8
+	.xword	.LLFB2
+	.uaxword	.LLFE2-.LLFB2	! FDE address range
+#endif
+	.byte	0x0	! uleb128 0x0; Augmentation size
+	.byte	0x4	! DW_CFA_advance_loc4
+	.uaword	.LLCFI1-.LLFB2
+	.byte	0xd	! DW_CFA_def_cfa_register
+	.byte	0x1e	! uleb128 0x1e
+	.byte	0x2d	! DW_CFA_GNU_window_save
+	.byte	0x9	! DW_CFA_register
+	.byte	0xf	! uleb128 0xf
+	.byte	0x1f	! uleb128 0x1f
+	.align 8
+.LLEFDE2:
+#endif

Added: vendor/Python/current/Modules/_ctypes/libffi/src/x86/darwin.S
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/x86/darwin.S	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/x86/darwin.S	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,243 @@
+#ifdef __i386__
+/* -----------------------------------------------------------------------
+   darwin.S - Copyright (c) 1996, 1998, 2001, 2002, 2003  Red Hat, Inc.
+   
+   X86 Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+  
+/*
+ * This file is based on sysv.S and then hacked up by Ronald who hasn't done
+ * assembly programming in 8 years.
+ */
+
+#ifndef __x86_64__
+
+#define LIBFFI_ASM	
+#include <fficonfig.h>
+#include <ffi.h>
+
+#ifdef PyObjC_STRICT_DEBUGGING
+  /* XXX: Debugging of stack alignment, to be removed */
+#define ASSERT_STACK_ALIGNED movdqa -16(%esp), %xmm0
+#else
+#define ASSERT_STACK_ALIGNED 
+#endif
+
+.text
+
+.globl _ffi_prep_args
+
+.align 4
+.globl _ffi_call_SYSV
+
+_ffi_call_SYSV:
+.LFB1:
+        pushl %ebp
+.LCFI0:
+        movl  %esp,%ebp
+	subl  $8,%esp
+	ASSERT_STACK_ALIGNED
+.LCFI1:
+	/* Make room for all of the new args.  */
+	movl  16(%ebp),%ecx
+	subl  %ecx,%esp
+
+	ASSERT_STACK_ALIGNED
+
+	movl  %esp,%eax
+
+	/* Place all of the ffi_prep_args in position  */
+	subl  $8,%esp
+	pushl 12(%ebp)
+	pushl %eax
+	call  *8(%ebp)
+
+	ASSERT_STACK_ALIGNED
+
+	/* Return stack to previous state and call the function  */
+	addl  $16,%esp
+
+	ASSERT_STACK_ALIGNED
+
+	call  *28(%ebp)
+	
+	/* XXX: return returns return with 'ret $4', that upsets the stack! */
+	movl  16(%ebp),%ecx
+	addl  %ecx,%esp
+
+
+	/* Load %ecx with the return type code  */
+	movl  20(%ebp),%ecx	
+
+
+	/* If the return value pointer is NULL, assume no return value.  */
+	cmpl  $0,24(%ebp)
+	jne   retint
+
+	/* Even if there is no space for the return value, we are 
+	   obliged to handle floating-point values.  */
+	cmpl  $FFI_TYPE_FLOAT,%ecx
+	jne   noretval
+	fstp  %st(0)
+
+        jmp   epilogue
+
+retint:
+	cmpl  $FFI_TYPE_INT,%ecx
+	jne   retfloat
+	/* Load %ecx with the pointer to storage for the return value  */
+	movl  24(%ebp),%ecx	
+	movl  %eax,0(%ecx)
+	jmp   epilogue
+
+retfloat:
+	cmpl  $FFI_TYPE_FLOAT,%ecx
+	jne   retdouble
+	/* Load %ecx with the pointer to storage for the return value  */
+	movl  24(%ebp),%ecx	
+	fstps (%ecx)
+	jmp   epilogue
+
+retdouble:
+	cmpl  $FFI_TYPE_DOUBLE,%ecx
+	jne   retlongdouble
+	/* Load %ecx with the pointer to storage for the return value  */
+	movl  24(%ebp),%ecx	
+	fstpl (%ecx)
+	jmp   epilogue
+
+retlongdouble:
+	cmpl  $FFI_TYPE_LONGDOUBLE,%ecx
+	jne   retint64
+	/* Load %ecx with the pointer to storage for the return value  */
+	movl  24(%ebp),%ecx	
+	fstpt (%ecx)
+	jmp   epilogue
+	
+retint64:	
+	cmpl  $FFI_TYPE_SINT64,%ecx
+        jne   retstruct1b
+	/* Load %ecx with the pointer to storage for the return value  */
+	movl  24(%ebp),%ecx	
+	movl  %eax,0(%ecx)
+	movl  %edx,4(%ecx)
+	jmp   epilogue
+
+retstruct1b:
+   cmpl $FFI_TYPE_SINT8,%ecx
+   jne  retstruct2b
+   movl 24(%ebp),%ecx
+   movb  %al,0(%ecx)
+   jmp  epilogue
+
+retstruct2b:
+   cmpl $FFI_TYPE_SINT16,%ecx
+   jne  retstruct
+   movl 24(%ebp),%ecx
+   movw %ax,0(%ecx)
+   jmp  epilogue
+	
+retstruct:
+   cmpl $FFI_TYPE_STRUCT,%ecx
+   jne  noretval
+	/* Nothing to do!  */
+
+	subl $4,%esp
+
+	ASSERT_STACK_ALIGNED
+
+	addl $8,%esp
+	movl %ebp, %esp
+	popl %ebp
+	ret
+
+noretval:
+epilogue:
+	ASSERT_STACK_ALIGNED
+	addl $8, %esp
+
+
+        movl %ebp,%esp
+        popl %ebp
+        ret
+.LFE1:
+.ffi_call_SYSV_end:
+#if 0
+        .size    ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
+#endif
+
+#if 0
+	.section	.eh_frame,EH_FRAME_FLAGS, at progbits
+.Lframe1:
+	.long	.LECIE1-.LSCIE1	/* Length of Common Information Entry */
+.LSCIE1:
+	.long	0x0	/* CIE Identifier Tag */
+	.byte	0x1	/* CIE Version */
+#ifdef __PIC__
+	.ascii "zR\0"	/* CIE Augmentation */
+#else
+	.ascii "\0"	/* CIE Augmentation */
+#endif
+	.byte	0x1	/* .uleb128 0x1; CIE Code Alignment Factor */
+	.byte	0x7c	/* .sleb128 -4; CIE Data Alignment Factor */
+	.byte	0x8	/* CIE RA Column */
+#ifdef __PIC__
+	.byte	0x1	/* .uleb128 0x1; Augmentation size */
+	.byte	0x1b	/* FDE Encoding (pcrel sdata4) */
+#endif
+	.byte	0xc	/* DW_CFA_def_cfa */
+	.byte	0x4	/* .uleb128 0x4 */
+	.byte	0x4	/* .uleb128 0x4 */
+	.byte	0x88	/* DW_CFA_offset, column 0x8 */
+	.byte	0x1	/* .uleb128 0x1 */
+	.align 4
+.LECIE1:
+.LSFDE1:
+	.long	.LEFDE1-.LASFDE1	/* FDE Length */
+.LASFDE1:
+	.long	.LASFDE1-.Lframe1	/* FDE CIE offset */
+#ifdef __PIC__
+	.long	.LFB1-.	/* FDE initial location */
+#else
+	.long	.LFB1	/* FDE initial location */
+#endif
+	.long	.LFE1-.LFB1	/* FDE address range */
+#ifdef __PIC__
+	.byte	0x0	/* .uleb128 0x0; Augmentation size */
+#endif
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.long	.LCFI0-.LFB1
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+	.byte	0x8	/* .uleb128 0x8 */
+	.byte	0x85	/* DW_CFA_offset, column 0x5 */
+	.byte	0x2	/* .uleb128 0x2 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.long	.LCFI1-.LCFI0
+	.byte	0xd	/* DW_CFA_def_cfa_register */
+	.byte	0x5	/* .uleb128 0x5 */
+	.align 4
+.LEFDE1:
+#endif
+
+#endif /* ifndef __x86_64__ */
+
+#endif /* defined __i386__ */

Added: vendor/Python/current/Modules/_ctypes/libffi/src/x86/ffi.c
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/x86/ffi.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/x86/ffi.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,469 @@
+/* -----------------------------------------------------------------------
+   ffi.c - Copyright (c) 1996, 1998, 1999, 2001  Red Hat, Inc.
+           Copyright (c) 2002  Ranjit Mathew
+           Copyright (c) 2002  Bo Thorsen
+           Copyright (c) 2002  Roger Sayle
+   
+   x86 Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#ifndef __x86_64__
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+
+/* ffi_prep_args is called by the assembly routine once stack space
+   has been allocated for the function's arguments */
+
+/*@-exportheader@*/
+void ffi_prep_args(char *stack, extended_cif *ecif)
+/*@=exportheader@*/
+{
+  register unsigned int i;
+  register void **p_argv;
+  register char *argp;
+  register ffi_type **p_arg;
+
+  argp = stack;
+
+  if (ecif->cif->flags == FFI_TYPE_STRUCT)
+    {
+      *(void **) argp = ecif->rvalue;
+      argp += 4;
+    }
+
+  p_argv = ecif->avalue;
+
+  for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
+       i != 0;
+       i--, p_arg++)
+    {
+      size_t z;
+
+      /* Align if necessary */
+      if ((sizeof(int) - 1) & (unsigned) argp)
+	argp = (char *) ALIGN(argp, sizeof(int));
+
+      z = (*p_arg)->size;
+      if (z < sizeof(int))
+	{
+	  z = sizeof(int);
+	  switch ((*p_arg)->type)
+	    {
+	    case FFI_TYPE_SINT8:
+	      *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
+	      break;
+
+	    case FFI_TYPE_UINT8:
+	      *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
+	      break;
+
+	    case FFI_TYPE_SINT16:
+	      *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
+	      break;
+
+	    case FFI_TYPE_UINT16:
+	      *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
+	      break;
+
+	    case FFI_TYPE_SINT32:
+	      *(signed int *) argp = (signed int)*(SINT32 *)(* p_argv);
+	      break;
+
+	    case FFI_TYPE_UINT32:
+	      *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+	      break;
+
+	    case FFI_TYPE_STRUCT:
+	      *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+	      break;
+
+	    default:
+	      FFI_ASSERT(0);
+	    }
+	}
+      else
+	{
+	  memcpy(argp, *p_argv, z);
+	}
+      p_argv++;
+      argp += z;
+    }
+  
+  return;
+}
+
+/* Perform machine dependent cif processing */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+{
+  /* Set the return type flag */
+  switch (cif->rtype->type)
+    {
+    case FFI_TYPE_VOID:
+#if !defined(X86_WIN32) && !defined(__OpenBSD__) && !defined(__FreeBSD__)
+    case FFI_TYPE_STRUCT:
+#endif
+    case FFI_TYPE_SINT64:
+    case FFI_TYPE_FLOAT:
+    case FFI_TYPE_DOUBLE:
+    case FFI_TYPE_LONGDOUBLE:
+      cif->flags = (unsigned) cif->rtype->type;
+      break;
+
+    case FFI_TYPE_UINT64:
+      cif->flags = FFI_TYPE_SINT64;
+      break;
+
+#if defined(X86_WIN32) || defined(__OpenBSD__) || defined(__FreeBSD__)
+    case FFI_TYPE_STRUCT:
+      if (cif->rtype->size == 1)
+        {
+          cif->flags = FFI_TYPE_SINT8; /* same as char size */
+        }
+      else if (cif->rtype->size == 2)
+        {
+          cif->flags = FFI_TYPE_SINT16; /* same as short size */
+        }
+      else if (cif->rtype->size == 4)
+        {
+          cif->flags = FFI_TYPE_INT; /* same as int type */
+        }
+      else if (cif->rtype->size == 8)
+        {
+          cif->flags = FFI_TYPE_SINT64; /* same as int64 type */
+        }
+      else
+        {
+          cif->flags = FFI_TYPE_STRUCT;
+        }
+      break;
+#endif
+
+    default:
+      cif->flags = FFI_TYPE_INT;
+      break;
+    }
+
+  return FFI_OK;
+}
+
+/*@-declundef@*/
+/*@-exportheader@*/
+extern void ffi_call_SYSV(void (*)(char *, extended_cif *), 
+			  /*@out@*/ extended_cif *, 
+			  unsigned, unsigned, 
+			  /*@out@*/ unsigned *, 
+			  void (*fn)());
+/*@=declundef@*/
+/*@=exportheader@*/
+
+#ifdef X86_WIN32
+/*@-declundef@*/
+/*@-exportheader@*/
+extern void ffi_call_STDCALL(void (*)(char *, extended_cif *),
+			  /*@out@*/ extended_cif *,
+			  unsigned, unsigned,
+			  /*@out@*/ unsigned *,
+			  void (*fn)());
+/*@=declundef@*/
+/*@=exportheader@*/
+#endif /* X86_WIN32 */
+
+void ffi_call(/*@dependent@*/ ffi_cif *cif, 
+	      void (*fn)(), 
+	      /*@out@*/ void *rvalue, 
+	      /*@dependent@*/ void **avalue)
+{
+  extended_cif ecif;
+
+  ecif.cif = cif;
+  ecif.avalue = avalue;
+  
+  /* If the return value is a struct and we don't have a return	*/
+  /* value address then we need to make one		        */
+
+  if ((rvalue == NULL) && 
+      (cif->flags == FFI_TYPE_STRUCT))
+    {
+      /*@-sysunrecog@*/
+      ecif.rvalue = alloca(cif->rtype->size);
+      /*@=sysunrecog@*/
+    }
+  else
+    ecif.rvalue = rvalue;
+    
+  
+  switch (cif->abi) 
+    {
+    case FFI_SYSV:
+      /*@-usedef@*/
+      ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, 
+		    cif->flags, ecif.rvalue, fn);
+      /*@=usedef@*/
+      break;
+#ifdef X86_WIN32
+    case FFI_STDCALL:
+      /*@-usedef@*/
+      ffi_call_STDCALL(ffi_prep_args, &ecif, cif->bytes,
+		    cif->flags, ecif.rvalue, fn);
+      /*@=usedef@*/
+      break;
+#endif /* X86_WIN32 */
+    default:
+      FFI_ASSERT(0);
+      break;
+    }
+}
+
+
+/** private members **/
+
+static void ffi_prep_incoming_args_SYSV (char *stack, void **ret,
+					 void** args, ffi_cif* cif);
+void FFI_HIDDEN ffi_closure_SYSV (ffi_closure *)
+     __attribute__ ((regparm(1)));
+unsigned int FFI_HIDDEN ffi_closure_SYSV_inner (ffi_closure *, void **, void *)
+     __attribute__ ((regparm(1)));
+void FFI_HIDDEN ffi_closure_raw_SYSV (ffi_raw_closure *)
+     __attribute__ ((regparm(1)));
+
+/* This function is jumped to by the trampoline */
+
+unsigned int FFI_HIDDEN
+ffi_closure_SYSV_inner (closure, respp, args)
+     ffi_closure *closure;
+     void **respp;
+     void *args;
+{
+  // our various things...
+  ffi_cif       *cif;
+  void         **arg_area;
+
+  cif         = closure->cif;
+  arg_area    = (void**) alloca (cif->nargs * sizeof (void*));  
+
+  /* this call will initialize ARG_AREA, such that each
+   * element in that array points to the corresponding 
+   * value on the stack; and if the function returns
+   * a structure, it will re-set RESP to point to the
+   * structure return address.  */
+
+  ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif);
+
+  (closure->fun) (cif, *respp, arg_area, closure->user_data);
+
+  return cif->flags;
+}
+
+/*@-exportheader@*/
+static void 
+ffi_prep_incoming_args_SYSV(char *stack, void **rvalue,
+			    void **avalue, ffi_cif *cif)
+/*@=exportheader@*/
+{
+  register unsigned int i;
+  register void **p_argv;
+  register char *argp;
+  register ffi_type **p_arg;
+
+  argp = stack;
+
+  if ( cif->flags == FFI_TYPE_STRUCT ) {
+    *rvalue = *(void **) argp;
+    argp += 4;
+  }
+
+  p_argv = avalue;
+
+  for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++)
+    {
+      size_t z;
+
+      /* Align if necessary */
+      if ((sizeof(int) - 1) & (unsigned) argp) {
+	argp = (char *) ALIGN(argp, sizeof(int));
+      }
+
+      z = (*p_arg)->size;
+
+      /* because we're little endian, this is what it turns into.   */
+
+      *p_argv = (void*) argp;
+
+      p_argv++;
+      argp += z;
+    }
+  
+  return;
+}
+
+/* How to make a trampoline.  Derived from gcc/config/i386/i386.c. */
+
+#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \
+({ unsigned char *__tramp = (unsigned char*)(TRAMP); \
+   unsigned int  __fun = (unsigned int)(FUN); \
+   unsigned int  __ctx = (unsigned int)(CTX); \
+   unsigned int  __dis = __fun - ((unsigned int) __tramp + FFI_TRAMPOLINE_SIZE); \
+   *(unsigned char*) &__tramp[0] = 0xb8; \
+   *(unsigned int*)  &__tramp[1] = __ctx; /* movl __ctx, %eax */ \
+   *(unsigned char *)  &__tramp[5] = 0xe9; \
+   *(unsigned int*)  &__tramp[6] = __dis; /* jmp __fun  */ \
+ })
+
+
+/* the cif must already be prep'ed */
+
+ffi_status
+ffi_prep_closure (ffi_closure* closure,
+		  ffi_cif* cif,
+		  void (*fun)(ffi_cif*,void*,void**,void*),
+		  void *user_data)
+{
+  FFI_ASSERT (cif->abi == FFI_SYSV);
+
+  FFI_INIT_TRAMPOLINE (&closure->tramp[0], \
+		       &ffi_closure_SYSV,  \
+		       (void*)closure);
+    
+  closure->cif  = cif;
+  closure->user_data = user_data;
+  closure->fun  = fun;
+
+  return FFI_OK;
+}
+
+/* ------- Native raw API support -------------------------------- */
+
+#if !FFI_NO_RAW_API
+
+ffi_status
+ffi_prep_raw_closure (ffi_raw_closure* closure,
+		      ffi_cif* cif,
+		      void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
+		      void *user_data)
+{
+  int i;
+
+  FFI_ASSERT (cif->abi == FFI_SYSV);
+
+  // we currently don't support certain kinds of arguments for raw
+  // closures.  This should be implemented by a separate assembly language
+  // routine, since it would require argument processing, something we
+  // don't do now for performance.
+
+  for (i = cif->nargs-1; i >= 0; i--)
+    {
+      FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_STRUCT);
+      FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_LONGDOUBLE);
+    }
+  
+
+  FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_raw_SYSV,
+		       (void*)closure);
+    
+  closure->cif  = cif;
+  closure->user_data = user_data;
+  closure->fun  = fun;
+
+  return FFI_OK;
+}
+
+static void 
+ffi_prep_args_raw(char *stack, extended_cif *ecif)
+{
+  memcpy (stack, ecif->avalue, ecif->cif->bytes);
+}
+
+/* we borrow this routine from libffi (it must be changed, though, to
+ * actually call the function passed in the first argument.  as of
+ * libffi-1.20, this is not the case.)
+ */
+
+extern void 
+ffi_call_SYSV(void (*)(char *, extended_cif *), 
+	      /*@out@*/ extended_cif *, 
+	      unsigned, unsigned, 
+	      /*@out@*/ unsigned *, 
+	      void (*fn)());
+
+#ifdef X86_WIN32
+extern void
+ffi_call_STDCALL(void (*)(char *, extended_cif *),
+	      /*@out@*/ extended_cif *,
+	      unsigned, unsigned,
+	      /*@out@*/ unsigned *,
+	      void (*fn)());
+#endif /* X86_WIN32 */
+
+void
+ffi_raw_call(/*@dependent@*/ ffi_cif *cif, 
+	     void (*fn)(), 
+	     /*@out@*/ void *rvalue, 
+	     /*@dependent@*/ ffi_raw *fake_avalue)
+{
+  extended_cif ecif;
+  void **avalue = (void **)fake_avalue;
+
+  ecif.cif = cif;
+  ecif.avalue = avalue;
+  
+  /* If the return value is a struct and we don't have a return	*/
+  /* value address then we need to make one		        */
+
+  if ((rvalue == NULL) && 
+      (cif->rtype->type == FFI_TYPE_STRUCT))
+    {
+      /*@-sysunrecog@*/
+      ecif.rvalue = alloca(cif->rtype->size);
+      /*@=sysunrecog@*/
+    }
+  else
+    ecif.rvalue = rvalue;
+    
+  
+  switch (cif->abi) 
+    {
+    case FFI_SYSV:
+      /*@-usedef@*/
+      ffi_call_SYSV(ffi_prep_args_raw, &ecif, cif->bytes, 
+		    cif->flags, ecif.rvalue, fn);
+      /*@=usedef@*/
+      break;
+#ifdef X86_WIN32
+    case FFI_STDCALL:
+      /*@-usedef@*/
+      ffi_call_STDCALL(ffi_prep_args_raw, &ecif, cif->bytes,
+		    cif->flags, ecif.rvalue, fn);
+      /*@=usedef@*/
+      break;
+#endif /* X86_WIN32 */
+    default:
+      FFI_ASSERT(0);
+      break;
+    }
+}
+
+#endif
+
+#endif /* __x86_64__  */

Added: vendor/Python/current/Modules/_ctypes/libffi/src/x86/ffi64.c
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/x86/ffi64.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/x86/ffi64.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,569 @@
+/* -----------------------------------------------------------------------
+   ffi.c - Copyright (c) 2002  Bo Thorsen <bo at suse.de>
+   
+   x86-64 Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+#include <stdarg.h>
+
+#ifdef __x86_64__
+
+#define MAX_GPR_REGS 6
+#define MAX_SSE_REGS 8
+
+struct register_args
+{
+  /* Registers for argument passing.  */
+  UINT64 gpr[MAX_GPR_REGS];
+  __int128_t sse[MAX_SSE_REGS];
+};
+
+extern void ffi_call_unix64 (void *args, unsigned long bytes, unsigned flags,
+			     void *raddr, void (*fnaddr)(), unsigned ssecount);
+
+/* All reference to register classes here is identical to the code in
+   gcc/config/i386/i386.c. Do *not* change one without the other.  */
+
+/* Register class used for passing given 64bit part of the argument.
+   These represent classes as documented by the PS ABI, with the exception
+   of SSESF, SSEDF classes, that are basically SSE class, just gcc will
+   use SF or DFmode move instead of DImode to avoid reformating penalties.
+
+   Similary we play games with INTEGERSI_CLASS to use cheaper SImode moves
+   whenever possible (upper half does contain padding).  */
+enum x86_64_reg_class
+  {
+    X86_64_NO_CLASS,
+    X86_64_INTEGER_CLASS,
+    X86_64_INTEGERSI_CLASS,
+    X86_64_SSE_CLASS,
+    X86_64_SSESF_CLASS,
+    X86_64_SSEDF_CLASS,
+    X86_64_SSEUP_CLASS,
+    X86_64_X87_CLASS,
+    X86_64_X87UP_CLASS,
+    X86_64_COMPLEX_X87_CLASS,
+    X86_64_MEMORY_CLASS
+  };
+
+#define MAX_CLASSES 4
+
+#define SSE_CLASS_P(X)	((X) >= X86_64_SSE_CLASS && X <= X86_64_SSEUP_CLASS)
+
+/* x86-64 register passing implementation.  See x86-64 ABI for details.  Goal
+   of this code is to classify each 8bytes of incoming argument by the register
+   class and assign registers accordingly.  */
+
+/* Return the union class of CLASS1 and CLASS2.
+   See the x86-64 PS ABI for details.  */
+
+static enum x86_64_reg_class
+merge_classes (enum x86_64_reg_class class1, enum x86_64_reg_class class2)
+{
+  /* Rule #1: If both classes are equal, this is the resulting class.  */
+  if (class1 == class2)
+    return class1;
+
+  /* Rule #2: If one of the classes is NO_CLASS, the resulting class is
+     the other class.  */
+  if (class1 == X86_64_NO_CLASS)
+    return class2;
+  if (class2 == X86_64_NO_CLASS)
+    return class1;
+
+  /* Rule #3: If one of the classes is MEMORY, the result is MEMORY.  */
+  if (class1 == X86_64_MEMORY_CLASS || class2 == X86_64_MEMORY_CLASS)
+    return X86_64_MEMORY_CLASS;
+
+  /* Rule #4: If one of the classes is INTEGER, the result is INTEGER.  */
+  if ((class1 == X86_64_INTEGERSI_CLASS && class2 == X86_64_SSESF_CLASS)
+      || (class2 == X86_64_INTEGERSI_CLASS && class1 == X86_64_SSESF_CLASS))
+    return X86_64_INTEGERSI_CLASS;
+  if (class1 == X86_64_INTEGER_CLASS || class1 == X86_64_INTEGERSI_CLASS
+      || class2 == X86_64_INTEGER_CLASS || class2 == X86_64_INTEGERSI_CLASS)
+    return X86_64_INTEGER_CLASS;
+
+  /* Rule #5: If one of the classes is X87, X87UP, or COMPLEX_X87 class,
+     MEMORY is used.  */
+  if (class1 == X86_64_X87_CLASS
+      || class1 == X86_64_X87UP_CLASS
+      || class1 == X86_64_COMPLEX_X87_CLASS
+      || class2 == X86_64_X87_CLASS
+      || class2 == X86_64_X87UP_CLASS
+      || class2 == X86_64_COMPLEX_X87_CLASS)
+    return X86_64_MEMORY_CLASS;
+
+  /* Rule #6: Otherwise class SSE is used.  */
+  return X86_64_SSE_CLASS;
+}
+
+/* Classify the argument of type TYPE and mode MODE.
+   CLASSES will be filled by the register class used to pass each word
+   of the operand.  The number of words is returned.  In case the parameter
+   should be passed in memory, 0 is returned. As a special case for zero
+   sized containers, classes[0] will be NO_CLASS and 1 is returned.
+
+   See the x86-64 PS ABI for details.
+*/
+static int
+classify_argument (ffi_type *type, enum x86_64_reg_class classes[],
+		   size_t byte_offset)
+{
+  switch (type->type)
+    {
+    case FFI_TYPE_UINT8:
+    case FFI_TYPE_SINT8:
+    case FFI_TYPE_UINT16:
+    case FFI_TYPE_SINT16:
+    case FFI_TYPE_UINT32:
+    case FFI_TYPE_SINT32:
+    case FFI_TYPE_UINT64:
+    case FFI_TYPE_SINT64:
+    case FFI_TYPE_POINTER:
+      if (byte_offset + type->size <= 4)
+	classes[0] = X86_64_INTEGERSI_CLASS;
+      else
+	classes[0] = X86_64_INTEGER_CLASS;
+      return 1;
+    case FFI_TYPE_FLOAT:
+      if (byte_offset == 0)
+	classes[0] = X86_64_SSESF_CLASS;
+      else
+	classes[0] = X86_64_SSE_CLASS;
+      return 1;
+    case FFI_TYPE_DOUBLE:
+      classes[0] = X86_64_SSEDF_CLASS;
+      return 1;
+    case FFI_TYPE_LONGDOUBLE:
+      classes[0] = X86_64_X87_CLASS;
+      classes[1] = X86_64_X87UP_CLASS;
+      return 2;
+    case FFI_TYPE_STRUCT:
+      {
+	const int UNITS_PER_WORD = 8;
+	int words = (type->size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
+	ffi_type **ptr; 
+	int i;
+	enum x86_64_reg_class subclasses[MAX_CLASSES];
+
+	/* If the struct is larger than 16 bytes, pass it on the stack.  */
+	if (type->size > 16)
+	  return 0;
+
+	for (i = 0; i < words; i++)
+	  classes[i] = X86_64_NO_CLASS;
+
+	/* Merge the fields of structure.  */
+	for (ptr = type->elements; *ptr != NULL; ptr++)
+	  {
+	    int num;
+
+	    byte_offset = ALIGN (byte_offset, (*ptr)->alignment);
+
+	    num = classify_argument (*ptr, subclasses, byte_offset % 8);
+	    if (num == 0)
+	      return 0;
+	    for (i = 0; i < num; i++)
+	      {
+		int pos = byte_offset / 8;
+		classes[i + pos] =
+		  merge_classes (subclasses[i], classes[i + pos]);
+	      }
+
+	    byte_offset += (*ptr)->size;
+	  }
+
+	/* Final merger cleanup.  */
+	for (i = 0; i < words; i++)
+	  {
+	    /* If one class is MEMORY, everything should be passed in
+	       memory.  */
+	    if (classes[i] == X86_64_MEMORY_CLASS)
+	      return 0;
+
+	    /* The X86_64_SSEUP_CLASS should be always preceded by
+	       X86_64_SSE_CLASS.  */
+	    if (classes[i] == X86_64_SSEUP_CLASS
+		&& (i == 0 || classes[i - 1] != X86_64_SSE_CLASS))
+	      classes[i] = X86_64_SSE_CLASS;
+
+	    /*  X86_64_X87UP_CLASS should be preceded by X86_64_X87_CLASS.  */
+	    if (classes[i] == X86_64_X87UP_CLASS
+		&& (i == 0 || classes[i - 1] != X86_64_X87_CLASS))
+	      classes[i] = X86_64_SSE_CLASS;
+	  }
+	return words;
+      }
+
+    default:
+      FFI_ASSERT(0);
+    }
+  return 0; /* Never reached.  */
+}
+
+/* Examine the argument and return set number of register required in each
+   class.  Return zero iff parameter should be passed in memory, otherwise
+   the number of registers.  */
+
+static int
+examine_argument (ffi_type *type, enum x86_64_reg_class classes[MAX_CLASSES],
+		  _Bool in_return, int *pngpr, int *pnsse)
+{
+  int i, n, ngpr, nsse;
+
+  n = classify_argument (type, classes, 0);
+  if (n == 0)
+    return 0;
+
+  ngpr = nsse = 0;
+  for (i = 0; i < n; ++i)
+    switch (classes[i])
+      {
+      case X86_64_INTEGER_CLASS:
+      case X86_64_INTEGERSI_CLASS:
+	ngpr++;
+	break;
+      case X86_64_SSE_CLASS:
+      case X86_64_SSESF_CLASS:
+      case X86_64_SSEDF_CLASS:
+	nsse++;
+	break;
+      case X86_64_NO_CLASS:
+      case X86_64_SSEUP_CLASS:
+	break;
+      case X86_64_X87_CLASS:
+      case X86_64_X87UP_CLASS:
+      case X86_64_COMPLEX_X87_CLASS:
+	return in_return != 0;
+      default:
+	abort ();
+      }
+
+  *pngpr = ngpr;
+  *pnsse = nsse;
+
+  return n;
+}
+
+/* Perform machine dependent cif processing.  */
+
+ffi_status
+ffi_prep_cif_machdep (ffi_cif *cif)
+{
+  int gprcount, ssecount, i, avn, n, ngpr, nsse, flags;
+  enum x86_64_reg_class classes[MAX_CLASSES];
+  size_t bytes;
+
+  gprcount = ssecount = 0;
+
+  flags = cif->rtype->type;
+  if (flags != FFI_TYPE_VOID)
+    {
+      n = examine_argument (cif->rtype, classes, 1, &ngpr, &nsse);
+      if (n == 0)
+	{
+	  /* The return value is passed in memory.  A pointer to that
+	     memory is the first argument.  Allocate a register for it.  */
+	  gprcount++;
+	  /* We don't have to do anything in asm for the return.  */
+	  flags = FFI_TYPE_VOID;
+	}
+      else if (flags == FFI_TYPE_STRUCT)
+	{
+	  /* Mark which registers the result appears in.  */
+	  _Bool sse0 = SSE_CLASS_P (classes[0]);
+	  _Bool sse1 = n == 2 && SSE_CLASS_P (classes[1]);
+	  if (sse0 && !sse1)
+	    flags |= 1 << 8;
+	  else if (!sse0 && sse1)
+	    flags |= 1 << 9;
+	  else if (sse0 && sse1)
+	    flags |= 1 << 10;
+	  /* Mark the true size of the structure.  */
+	  flags |= cif->rtype->size << 12;
+	}
+    }
+
+  /* Go over all arguments and determine the way they should be passed.
+     If it's in a register and there is space for it, let that be so. If
+     not, add it's size to the stack byte count.  */
+  for (bytes = 0, i = 0, avn = cif->nargs; i < avn; i++)
+    {
+      if (examine_argument (cif->arg_types[i], classes, 0, &ngpr, &nsse) == 0
+	  || gprcount + ngpr > MAX_GPR_REGS
+	  || ssecount + nsse > MAX_SSE_REGS)
+	{
+	  long align = cif->arg_types[i]->alignment;
+
+	  if (align < 8)
+	    align = 8;
+
+	  bytes = ALIGN(bytes, align);
+	  bytes += cif->arg_types[i]->size;
+	}
+      else
+	{
+	  gprcount += ngpr;
+	  ssecount += nsse;
+	}
+    }
+  if (ssecount)
+    flags |= 1 << 11;
+  cif->flags = flags;
+  cif->bytes = bytes;
+
+  return FFI_OK;
+}
+
+void
+ffi_call (ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
+{
+  enum x86_64_reg_class classes[MAX_CLASSES];
+  char *stack, *argp;
+  ffi_type **arg_types;
+  int gprcount, ssecount, ngpr, nsse, i, avn;
+  _Bool ret_in_memory;
+  struct register_args *reg_args;
+
+  /* Can't call 32-bit mode from 64-bit mode.  */
+  FFI_ASSERT (cif->abi == FFI_UNIX64);
+
+  /* If the return value is a struct and we don't have a return value
+     address then we need to make one.  Note the setting of flags to
+     VOID above in ffi_prep_cif_machdep.  */
+  ret_in_memory = (cif->rtype->type == FFI_TYPE_STRUCT
+		   && (cif->flags & 0xff) == FFI_TYPE_VOID);
+  if (rvalue == NULL && ret_in_memory)
+    rvalue = alloca (cif->rtype->size);
+
+  /* Allocate the space for the arguments, plus 4 words of temp space.  */
+  stack = alloca (sizeof (struct register_args) + cif->bytes + 4*8);
+  reg_args = (struct register_args *) stack;
+  argp = stack + sizeof (struct register_args);
+
+  gprcount = ssecount = 0;
+
+  /* If the return value is passed in memory, add the pointer as the
+     first integer argument.  */
+  if (ret_in_memory)
+    reg_args->gpr[gprcount++] = (long) rvalue;
+
+  avn = cif->nargs;
+  arg_types = cif->arg_types;
+
+  for (i = 0; i < avn; ++i)
+    {
+      size_t size = arg_types[i]->size;
+      int n;
+
+      n = examine_argument (arg_types[i], classes, 0, &ngpr, &nsse);
+      if (n == 0
+	  || gprcount + ngpr > MAX_GPR_REGS
+	  || ssecount + nsse > MAX_SSE_REGS)
+	{
+	  long align = arg_types[i]->alignment;
+
+	  /* Stack arguments are *always* at least 8 byte aligned.  */
+	  if (align < 8)
+	    align = 8;
+
+	  /* Pass this argument in memory.  */
+	  argp = (void *) ALIGN (argp, align);
+	  memcpy (argp, avalue[i], size);
+	  argp += size;
+	}
+      else
+	{
+	  /* The argument is passed entirely in registers.  */
+	  char *a = (char *) avalue[i];
+	  int j;
+
+	  for (j = 0; j < n; j++, a += 8, size -= 8)
+	    {
+	      switch (classes[j])
+		{
+		case X86_64_INTEGER_CLASS:
+		case X86_64_INTEGERSI_CLASS:
+		  reg_args->gpr[gprcount] = 0;
+		  memcpy (&reg_args->gpr[gprcount], a, size < 8 ? size : 8);
+		  gprcount++;
+		  break;
+		case X86_64_SSE_CLASS:
+		case X86_64_SSEDF_CLASS:
+		  reg_args->sse[ssecount++] = *(UINT64 *) a;
+		  break;
+		case X86_64_SSESF_CLASS:
+		  reg_args->sse[ssecount++] = *(UINT32 *) a;
+		  break;
+		default:
+		  abort();
+		}
+	    }
+	}
+    }
+
+  ffi_call_unix64 (stack, cif->bytes + sizeof (struct register_args),
+		   cif->flags, rvalue, fn, ssecount);
+}
+
+
+extern void ffi_closure_unix64(void);
+
+ffi_status
+ffi_prep_closure (ffi_closure* closure,
+		  ffi_cif* cif,
+		  void (*fun)(ffi_cif*, void*, void**, void*),
+		  void *user_data)
+{
+  volatile unsigned short *tramp;
+
+  tramp = (volatile unsigned short *) &closure->tramp[0];
+
+  tramp[0] = 0xbb49;		/* mov <code>, %r11	*/
+  *(void * volatile *) &tramp[1] = ffi_closure_unix64;
+  tramp[5] = 0xba49;		/* mov <data>, %r10	*/
+  *(void * volatile *) &tramp[6] = closure;
+
+  /* Set the carry bit iff the function uses any sse registers.
+     This is clc or stc, together with the first byte of the jmp.  */
+  tramp[10] = cif->flags & (1 << 11) ? 0x49f9 : 0x49f8;
+
+  tramp[11] = 0xe3ff;			/* jmp *%r11    */
+
+  closure->cif = cif;
+  closure->fun = fun;
+  closure->user_data = user_data;
+
+  return FFI_OK;
+}
+
+int
+ffi_closure_unix64_inner(ffi_closure *closure, void *rvalue,
+			 struct register_args *reg_args, char *argp)
+{
+  ffi_cif *cif;
+  void **avalue;
+  ffi_type **arg_types;
+  long i, avn;
+  int gprcount, ssecount, ngpr, nsse;
+  int ret;
+
+  cif = closure->cif;
+  avalue = alloca(cif->nargs * sizeof(void *));
+  gprcount = ssecount = 0;
+
+  ret = cif->rtype->type;
+  if (ret != FFI_TYPE_VOID)
+    {
+      enum x86_64_reg_class classes[MAX_CLASSES];
+      int n = examine_argument (cif->rtype, classes, 1, &ngpr, &nsse);
+      if (n == 0)
+	{
+	  /* The return value goes in memory.  Arrange for the closure
+	     return value to go directly back to the original caller.  */
+	  rvalue = (void *) reg_args->gpr[gprcount++];
+	  /* We don't have to do anything in asm for the return.  */
+	  ret = FFI_TYPE_VOID;
+	}
+      else if (ret == FFI_TYPE_STRUCT && n == 2)
+	{
+	  /* Mark which register the second word of the structure goes in.  */
+	  _Bool sse0 = SSE_CLASS_P (classes[0]);
+	  _Bool sse1 = SSE_CLASS_P (classes[1]);
+	  if (!sse0 && sse1)
+	    ret |= 1 << 8;
+	  else if (sse0 && !sse1)
+	    ret |= 1 << 9;
+	}
+    }
+
+  avn = cif->nargs;
+  arg_types = cif->arg_types;
+  
+  for (i = 0; i < avn; ++i)
+    {
+      enum x86_64_reg_class classes[MAX_CLASSES];
+      int n;
+
+      n = examine_argument (arg_types[i], classes, 0, &ngpr, &nsse);
+      if (n == 0
+	  || gprcount + ngpr > MAX_GPR_REGS
+	  || ssecount + nsse > MAX_SSE_REGS)
+	{
+	  long align = arg_types[i]->alignment;
+
+	  /* Stack arguments are *always* at least 8 byte aligned.  */
+	  if (align < 8)
+	    align = 8;
+
+	  /* Pass this argument in memory.  */
+	  argp = (void *) ALIGN (argp, align);
+	  avalue[i] = argp;
+	  argp += arg_types[i]->size;
+	}
+      /* If the argument is in a single register, or two consecutive
+	 registers, then we can use that address directly.  */
+      else if (n == 1
+	       || (n == 2
+		   && SSE_CLASS_P (classes[0]) == SSE_CLASS_P (classes[1])))
+	{
+	  /* The argument is in a single register.  */
+	  if (SSE_CLASS_P (classes[0]))
+	    {
+	      avalue[i] = &reg_args->sse[ssecount];
+	      ssecount += n;
+	    }
+	  else
+	    {
+	      avalue[i] = &reg_args->gpr[gprcount];
+	      gprcount += n;
+	    }
+	}
+      /* Otherwise, allocate space to make them consecutive.  */
+      else
+	{
+	  char *a = alloca (16);
+	  int j;
+
+	  avalue[i] = a;
+	  for (j = 0; j < n; j++, a += 8)
+	    {
+	      if (SSE_CLASS_P (classes[j]))
+		memcpy (a, &reg_args->sse[ssecount++], 8);
+	      else
+		memcpy (a, &reg_args->gpr[gprcount++], 8);
+	    }
+	}
+    }
+
+  /* Invoke the closure.  */
+  closure->fun (cif, rvalue, avalue, closure->user_data);
+
+  /* Tell assembly how to perform return type promotions.  */
+  return ret;
+}
+
+#endif /* __x86_64__ */

Added: vendor/Python/current/Modules/_ctypes/libffi/src/x86/ffi_darwin.c
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/x86/ffi_darwin.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/x86/ffi_darwin.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,594 @@
+# ifdef __i386__
+/* -----------------------------------------------------------------------
+   ffi.c - Copyright (c) 1996, 1998, 1999, 2001  Red Hat, Inc.
+           Copyright (c) 2002  Ranjit Mathew
+           Copyright (c) 2002  Bo Thorsen
+           Copyright (c) 2002  Roger Sayle
+   
+   x86 Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#ifndef __x86_64__
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+
+/* ffi_prep_args is called by the assembly routine once stack space
+   has been allocated for the function's arguments */
+
+/*@-exportheader@*/
+void ffi_prep_args(char *stack, extended_cif *ecif);
+
+static inline int retval_on_stack(ffi_type* tp)
+{
+	if (tp->type == FFI_TYPE_STRUCT) {
+		int sz = tp->size;
+		if (sz > 8) {
+			return 1;
+		}
+		switch (sz) {
+		case 1: case 2: case 4: case 8: return 0;
+		default: return 1;
+		}
+	}
+	return 0;
+}
+
+
+void ffi_prep_args(char *stack, extended_cif *ecif)
+/*@=exportheader@*/
+{
+  register unsigned int i;
+  register void **p_argv;
+  register char *argp;
+  register ffi_type **p_arg;
+
+  argp = stack;
+
+  if (retval_on_stack(ecif->cif->rtype)) {
+      *(void **) argp = ecif->rvalue;
+      argp += 4;
+  }
+
+
+  p_argv = ecif->avalue;
+
+  for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
+       i != 0;
+       i--, p_arg++)
+    {
+      size_t z;
+
+      /* Align if necessary */
+      if ((sizeof(int) - 1) & (unsigned) argp)
+	      argp = (char *) ALIGN(argp, sizeof(int));
+
+      z = (*p_arg)->size;
+      if (z < sizeof(int))
+	{
+	  z = sizeof(int);
+	  switch ((*p_arg)->type)
+	    {
+	    case FFI_TYPE_SINT8:
+	      *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
+	      break;
+
+	    case FFI_TYPE_UINT8:
+	      *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
+	      break;
+
+	    case FFI_TYPE_SINT16:
+	      *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
+	      break;
+
+	    case FFI_TYPE_UINT16:
+	      *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
+	      break;
+
+	    case FFI_TYPE_SINT32:
+	      *(signed int *) argp = (signed int)*(SINT32 *)(* p_argv);
+	      break;
+
+	    case FFI_TYPE_UINT32:
+	      *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+	      break;
+
+	    case FFI_TYPE_STRUCT:
+	      *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+	      break;
+
+	    default:
+	      FFI_ASSERT(0);
+	    }
+	}
+      else
+	{
+	  memcpy(argp, *p_argv, z);
+	}
+      p_argv++;
+      argp += z;
+    }
+  
+  return;
+}
+
+/* Perform machine dependent cif processing */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+{
+  /* Set the return type flag */
+  switch (cif->rtype->type)
+    {
+    case FFI_TYPE_VOID:
+#if !defined(X86_WIN32)  && !defined(X86_DARWIN)
+    case FFI_TYPE_STRUCT:
+#endif
+    case FFI_TYPE_SINT64:
+    case FFI_TYPE_FLOAT:
+    case FFI_TYPE_DOUBLE:
+    case FFI_TYPE_LONGDOUBLE:
+      cif->flags = (unsigned) cif->rtype->type;
+      break;
+
+    case FFI_TYPE_UINT64:
+      cif->flags = FFI_TYPE_SINT64;
+      break;
+
+#if defined(X86_WIN32) || defined(X86_DARWIN)
+
+    case FFI_TYPE_STRUCT:
+      if (cif->rtype->size == 1)
+        {
+          cif->flags = FFI_TYPE_SINT8; /* same as char size */
+        }
+      else if (cif->rtype->size == 2)
+        {
+          cif->flags = FFI_TYPE_SINT16; /* same as short size */
+        }
+      else if (cif->rtype->size == 4)
+        {
+          cif->flags = FFI_TYPE_INT; /* same as int type */
+        }
+      else if (cif->rtype->size == 8)
+        {
+          cif->flags = FFI_TYPE_SINT64; /* same as int64 type */
+        }
+      else
+        {
+          cif->flags = FFI_TYPE_STRUCT;
+        }
+      break;
+#endif
+
+    default:
+      cif->flags = FFI_TYPE_INT;
+      break;
+    }
+
+  /* Darwin: The stack needs to be aligned to a multiple of 16 bytes */
+#if 1
+  cif->bytes = (cif->bytes + 15) & ~0xF;
+#endif
+
+
+  return FFI_OK;
+}
+
+/*@-declundef@*/
+/*@-exportheader@*/
+extern void ffi_call_SYSV(void (*)(char *, extended_cif *), 
+			  /*@out@*/ extended_cif *, 
+			  unsigned, unsigned, 
+			  /*@out@*/ unsigned *, 
+			  void (*fn)(void));
+/*@=declundef@*/
+/*@=exportheader@*/
+
+#ifdef X86_WIN32
+/*@-declundef@*/
+/*@-exportheader@*/
+extern void ffi_call_STDCALL(void (*)(char *, extended_cif *),
+			  /*@out@*/ extended_cif *,
+			  unsigned, unsigned,
+			  /*@out@*/ unsigned *,
+			  void (*fn)(void));
+/*@=declundef@*/
+/*@=exportheader@*/
+#endif /* X86_WIN32 */
+
+void ffi_call(/*@dependent@*/ ffi_cif *cif, 
+	      void (*fn)(), 
+	      /*@out@*/ void *rvalue, 
+	      /*@dependent@*/ void **avalue)
+{
+  extended_cif ecif;
+
+  ecif.cif = cif;
+  ecif.avalue = avalue;
+  
+  /* If the return value is a struct and we don't have a return	*/
+  /* value address then we need to make one		        */
+
+  if ((rvalue == NULL) && retval_on_stack(cif->rtype))
+    {
+      /*@-sysunrecog@*/
+      ecif.rvalue = alloca(cif->rtype->size);
+      /*@=sysunrecog@*/
+    }
+  else
+    ecif.rvalue = rvalue;
+
+  switch (cif->abi) 
+    {
+    case FFI_SYSV:
+      /*@-usedef@*/
+      /* To avoid changing the assembly code make sure the size of the argument 
+       * block is a multiple of 16. Then add 8 to compensate for local variables
+       * in ffi_call_SYSV.
+       */
+      ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, 
+		    cif->flags, ecif.rvalue, fn);
+      /*@=usedef@*/
+      break;
+#ifdef X86_WIN32
+    case FFI_STDCALL:
+      /*@-usedef@*/
+      ffi_call_STDCALL(ffi_prep_args, &ecif, cif->bytes,
+		    cif->flags, ecif.rvalue, fn);
+      /*@=usedef@*/
+      break;
+#endif /* X86_WIN32 */
+    default:
+      FFI_ASSERT(0);
+      break;
+    }
+}
+
+
+/** private members **/
+
+static void ffi_closure_SYSV (ffi_closure *)
+     __attribute__ ((regparm(1)));
+#if !FFI_NO_RAW_API
+static void ffi_closure_raw_SYSV (ffi_raw_closure *)
+     __attribute__ ((regparm(1)));
+#endif
+
+/*@-exportheader@*/
+static inline void 
+ffi_prep_incoming_args_SYSV(char *stack, void **rvalue,
+			    void **avalue, ffi_cif *cif)
+/*@=exportheader@*/
+{
+  register unsigned int i;
+  register void **p_argv;
+  register char *argp;
+  register ffi_type **p_arg;
+
+  argp = stack;
+
+  if (retval_on_stack(cif->rtype)) {
+    *rvalue = *(void **) argp;
+    argp += 4;
+  }
+
+  p_argv = avalue;
+
+  for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++)
+    {
+      size_t z;
+
+      /* Align if necessary */
+      if ((sizeof(int) - 1) & (unsigned) argp) {
+	argp = (char *) ALIGN(argp, sizeof(int));
+      }
+
+      z = (*p_arg)->size;
+
+      /* because we're little endian, this is what it turns into.   */
+
+      *p_argv = (void*) argp;
+
+      p_argv++;
+      argp += z;
+    }
+  
+  return;
+}
+
+/* This function is jumped to by the trampoline */
+
+static void
+ffi_closure_SYSV (closure)
+     ffi_closure *closure;
+{
+  // this is our return value storage
+  long double  res;
+
+  // our various things...
+  ffi_cif       *cif;
+  void         **arg_area;
+  void          *resp = (void*)&res;
+  void *args = __builtin_dwarf_cfa ();
+
+
+  cif         = closure->cif;
+  arg_area    = (void**) alloca (cif->nargs * sizeof (void*));  
+
+  /* this call will initialize ARG_AREA, such that each
+   * element in that array points to the corresponding 
+   * value on the stack; and if the function returns
+   * a structure, it will re-set RESP to point to the
+   * structure return address.  */
+
+  ffi_prep_incoming_args_SYSV(args, (void**)&resp, arg_area, cif);
+  
+  (closure->fun) (cif, resp, arg_area, closure->user_data);
+
+  /* now, do a generic return based on the value of rtype */
+  if (cif->flags == FFI_TYPE_INT)
+    {
+      asm ("movl (%0),%%eax" : : "r" (resp) : "eax");
+    }
+  else if (cif->flags == FFI_TYPE_FLOAT)
+    {
+      asm ("flds (%0)" : : "r" (resp) : "st" );
+    }
+  else if (cif->flags == FFI_TYPE_DOUBLE)
+    {
+      asm ("fldl (%0)" : : "r" (resp) : "st", "st(1)" );
+    }
+  else if (cif->flags == FFI_TYPE_LONGDOUBLE)
+    {
+      asm ("fldt (%0)" : : "r" (resp) : "st", "st(1)" );
+    }
+  else if (cif->flags == FFI_TYPE_SINT64)
+    {
+      asm ("movl 0(%0),%%eax;"
+	   "movl 4(%0),%%edx" 
+	   : : "r"(resp)
+	   : "eax", "edx");
+    }
+#if defined(X86_WIN32) || defined(X86_DARWIN)
+  else if (cif->flags == FFI_TYPE_SINT8) /* 1-byte struct  */
+    {
+      asm ("movsbl (%0),%%eax" : : "r" (resp) : "eax");
+    }
+  else if (cif->flags == FFI_TYPE_SINT16) /* 2-bytes struct */
+    {
+      asm ("movswl (%0),%%eax" : : "r" (resp) : "eax");
+    }
+#endif
+
+  else if (cif->flags == FFI_TYPE_STRUCT)
+    {
+      asm ("lea -8(%ebp),%esp;"
+	   "pop %esi;"
+	   "pop %edi;"
+	   "pop %ebp;"
+	   "ret $4"); 
+    }
+}
+
+
+/* How to make a trampoline.  Derived from gcc/config/i386/i386.c. */
+
+#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \
+({ unsigned char *__tramp = (unsigned char*)(TRAMP); \
+   unsigned int  __fun = (unsigned int)(FUN); \
+   unsigned int  __ctx = (unsigned int)(CTX); \
+   unsigned int  __dis = __fun - ((unsigned int) __tramp + FFI_TRAMPOLINE_SIZE); \
+   *(unsigned char*) &__tramp[0] = 0xb8; \
+   *(unsigned int*)  &__tramp[1] = __ctx; /* movl __ctx, %eax */ \
+   *(unsigned char *)  &__tramp[5] = 0xe9; \
+   *(unsigned int*)  &__tramp[6] = __dis; /* jmp __fun  */ \
+ })
+
+
+/* the cif must already be prep'ed */
+
+ffi_status
+ffi_prep_closure (ffi_closure* closure,
+		  ffi_cif* cif,
+		  void (*fun)(ffi_cif*,void*,void**,void*),
+		  void *user_data)
+{
+  FFI_ASSERT (cif->abi == FFI_SYSV);
+
+  FFI_INIT_TRAMPOLINE (&closure->tramp[0], \
+		       &ffi_closure_SYSV,  \
+		       (void*)closure);
+    
+  closure->cif  = cif;
+  closure->user_data = user_data;
+  closure->fun  = fun;
+
+  return FFI_OK;
+}
+
+/* ------- Native raw API support -------------------------------- */
+
+#if !FFI_NO_RAW_API
+
+static void
+ffi_closure_raw_SYSV (closure)
+     ffi_raw_closure *closure;
+{
+  // this is our return value storage
+  long double    res;
+
+  // our various things...
+  ffi_raw         *raw_args;
+  ffi_cif         *cif;
+  unsigned short   rtype;
+  void            *resp = (void*)&res;
+
+  /* get the cif */
+  cif = closure->cif;
+
+  /* the SYSV/X86 abi matches the RAW API exactly, well.. almost */
+  raw_args = (ffi_raw*) __builtin_dwarf_cfa ();
+
+  (closure->fun) (cif, resp, raw_args, closure->user_data);
+
+  rtype = cif->flags;
+
+  /* now, do a generic return based on the value of rtype */
+  if (rtype == FFI_TYPE_INT)
+    {
+      asm ("movl (%0),%%eax" : : "r" (resp) : "eax");
+    }
+  else if (rtype == FFI_TYPE_FLOAT)
+    {
+      asm ("flds (%0)" : : "r" (resp) : "st" );
+    }
+  else if (rtype == FFI_TYPE_DOUBLE)
+    {
+      asm ("fldl (%0)" : : "r" (resp) : "st", "st(1)" );
+    }
+  else if (rtype == FFI_TYPE_LONGDOUBLE)
+    {
+      asm ("fldt (%0)" : : "r" (resp) : "st", "st(1)" );
+    }
+  else if (rtype == FFI_TYPE_SINT64)
+    {
+      asm ("movl 0(%0),%%eax; movl 4(%0),%%edx" 
+	   : : "r"(resp)
+	   : "eax", "edx");
+    }
+}
+
+ 
+
+
+ffi_status
+ffi_prep_raw_closure (ffi_raw_closure* closure,
+		      ffi_cif* cif,
+		      void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
+		      void *user_data)
+{
+  int i;
+
+  FFI_ASSERT (cif->abi == FFI_SYSV);
+
+  // we currently don't support certain kinds of arguments for raw
+  // closures.  This should be implemented by a separate assembly language
+  // routine, since it would require argument processing, something we
+  // don't do now for performance.
+
+  for (i = cif->nargs-1; i >= 0; i--)
+    {
+      FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_STRUCT);
+      FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_LONGDOUBLE);
+    }
+  
+
+  FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_raw_SYSV,
+		       (void*)closure);
+    
+  closure->cif  = cif;
+  closure->user_data = user_data;
+  closure->fun  = fun;
+
+  return FFI_OK;
+}
+
+static void 
+ffi_prep_args_raw(char *stack, extended_cif *ecif)
+{
+  memcpy (stack, ecif->avalue, ecif->cif->bytes);
+}
+
+/* we borrow this routine from libffi (it must be changed, though, to
+ * actually call the function passed in the first argument.  as of
+ * libffi-1.20, this is not the case.)
+ */
+
+extern void 
+ffi_call_SYSV(void (*)(char *, extended_cif *), 
+	      /*@out@*/ extended_cif *, 
+	      unsigned, unsigned, 
+	      /*@out@*/ unsigned *, 
+	      void (*fn)());
+
+#ifdef X86_WIN32
+extern void
+ffi_call_STDCALL(void (*)(char *, extended_cif *),
+	      /*@out@*/ extended_cif *,
+	      unsigned, unsigned,
+	      /*@out@*/ unsigned *,
+	      void (*fn)());
+#endif /* X86_WIN32 */
+
+void
+ffi_raw_call(/*@dependent@*/ ffi_cif *cif, 
+	     void (*fn)(), 
+	     /*@out@*/ void *rvalue, 
+	     /*@dependent@*/ ffi_raw *fake_avalue)
+{
+  extended_cif ecif;
+  void **avalue = (void **)fake_avalue;
+
+  ecif.cif = cif;
+  ecif.avalue = avalue;
+  
+  /* If the return value is a struct and we don't have a return	*/
+  /* value address then we need to make one		        */
+
+  if ((rvalue == NULL) && retval_on_stack(cif->rtype)) 
+    {
+      /*@-sysunrecog@*/
+      ecif.rvalue = alloca(cif->rtype->size);
+      /*@=sysunrecog@*/
+    }
+  else
+    ecif.rvalue = rvalue;
+    
+  
+  switch (cif->abi) 
+    {
+    case FFI_SYSV:
+      /*@-usedef@*/
+      ffi_call_SYSV(ffi_prep_args_raw, &ecif, cif->bytes, 
+		    cif->flags, ecif.rvalue, fn);
+      /*@=usedef@*/
+      break;
+#ifdef X86_WIN32
+    case FFI_STDCALL:
+      /*@-usedef@*/
+      ffi_call_STDCALL(ffi_prep_args_raw, &ecif, cif->bytes,
+		    cif->flags, ecif.rvalue, fn);
+      /*@=usedef@*/
+      break;
+#endif /* X86_WIN32 */
+    default:
+      FFI_ASSERT(0);
+      break;
+    }
+}
+
+#endif
+
+#endif /* __x86_64__  */
+
+#endif /* __i386__ */

Added: vendor/Python/current/Modules/_ctypes/libffi/src/x86/ffitarget.h
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/x86/ffitarget.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/x86/ffitarget.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,81 @@
+/* -----------------------------------------------------------------*-C-*-
+   ffitarget.h - Copyright (c) 1996-2003  Red Hat, Inc.
+   Target configuration macros for x86 and x86-64.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+
+   ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+/* ---- System specific configurations ----------------------------------- */
+
+#if defined (X86_64) && defined (__i386__)
+#undef X86_64
+#define X86
+#endif
+
+/* ---- Generic type definitions ----------------------------------------- */
+
+#ifndef LIBFFI_ASM
+typedef unsigned long          ffi_arg;
+typedef signed long            ffi_sarg;
+
+typedef enum ffi_abi {
+  FFI_FIRST_ABI = 0,
+
+  /* ---- Intel x86 Win32 ---------- */
+#ifdef X86_WIN32
+  FFI_SYSV,
+  FFI_STDCALL,
+  /* TODO: Add fastcall support for the sake of completeness */
+  FFI_DEFAULT_ABI = FFI_SYSV,
+#endif
+
+  /* ---- Intel x86 and AMD x86-64 - */
+#if !defined(X86_WIN32) && (defined(__i386__) || defined(__x86_64__)) 
+  FFI_SYSV,
+  FFI_UNIX64,   /* Unix variants all use the same ABI for x86-64  */
+#ifdef __i386__
+  FFI_DEFAULT_ABI = FFI_SYSV,
+#else
+  FFI_DEFAULT_ABI = FFI_UNIX64,
+#endif
+#endif
+
+  FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
+} ffi_abi;
+#endif
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#define FFI_CLOSURES 1
+
+#ifdef X86_64
+#define FFI_TRAMPOLINE_SIZE 24
+#define FFI_NATIVE_RAW_API 0
+#else
+#define FFI_TRAMPOLINE_SIZE 10
+#define FFI_NATIVE_RAW_API 1	/* x86 has native raw api support */
+#endif
+
+#endif
+

Added: vendor/Python/current/Modules/_ctypes/libffi/src/x86/sysv.S
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/x86/sysv.S	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/x86/sysv.S	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,382 @@
+/* -----------------------------------------------------------------------
+   sysv.S - Copyright (c) 1996, 1998, 2001, 2002, 2003, 2005  Red Hat, Inc.
+   
+   X86 Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#ifndef __x86_64__
+
+#define LIBFFI_ASM	
+#include <fficonfig.h>
+#include <ffi.h>
+
+.text
+
+.globl ffi_prep_args
+
+	.align 4
+.globl ffi_call_SYSV
+        .type    ffi_call_SYSV, at function
+
+ffi_call_SYSV:
+.LFB1:
+        pushl %ebp
+.LCFI0:
+        movl  %esp,%ebp
+.LCFI1:
+	/* Make room for all of the new args.  */
+	movl  16(%ebp),%ecx
+	subl  %ecx,%esp
+
+	movl  %esp,%eax
+
+	/* Place all of the ffi_prep_args in position  */
+	pushl 12(%ebp)
+	pushl %eax
+	call  *8(%ebp)
+
+	/* Return stack to previous state and call the function  */
+	addl  $8,%esp	
+
+	call  *28(%ebp)
+
+	/* Remove the space we pushed for the args  */
+	movl  16(%ebp),%ecx
+	addl  %ecx,%esp
+
+	/* Load %ecx with the return type code  */
+	movl  20(%ebp),%ecx	
+
+	/* If the return value pointer is NULL, assume no return value.  */
+	cmpl  $0,24(%ebp)
+	jne   retint
+
+	/* Even if there is no space for the return value, we are 
+	   obliged to handle floating-point values.  */
+	cmpl  $FFI_TYPE_FLOAT,%ecx
+	jne   noretval
+	fstp  %st(0)
+
+        jmp   epilogue
+
+retint:
+	cmpl  $FFI_TYPE_INT,%ecx
+	jne   retfloat
+	/* Load %ecx with the pointer to storage for the return value  */
+	movl  24(%ebp),%ecx	
+	movl  %eax,0(%ecx)
+	jmp   epilogue
+
+retfloat:
+	cmpl  $FFI_TYPE_FLOAT,%ecx
+	jne   retdouble
+	/* Load %ecx with the pointer to storage for the return value  */
+	movl  24(%ebp),%ecx	
+	fstps (%ecx)
+	jmp   epilogue
+
+retdouble:
+	cmpl  $FFI_TYPE_DOUBLE,%ecx
+	jne   retlongdouble
+	/* Load %ecx with the pointer to storage for the return value  */
+	movl  24(%ebp),%ecx	
+	fstpl (%ecx)
+	jmp   epilogue
+
+retlongdouble:
+	cmpl  $FFI_TYPE_LONGDOUBLE,%ecx
+	jne   retint64
+	/* Load %ecx with the pointer to storage for the return value  */
+	movl  24(%ebp),%ecx	
+	fstpt (%ecx)
+	jmp   epilogue
+	
+retint64:	
+	cmpl  $FFI_TYPE_SINT64,%ecx
+        jne   retstruct
+	/* Load %ecx with the pointer to storage for the return value  */
+	movl  24(%ebp),%ecx	
+	movl  %eax,0(%ecx)
+	movl  %edx,4(%ecx)
+	
+retstruct:
+	/* Nothing to do!  */
+
+noretval:
+epilogue:
+        movl %ebp,%esp
+        popl %ebp
+        ret
+.LFE1:
+.ffi_call_SYSV_end:
+        .size    ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
+
+	.align	4
+FFI_HIDDEN (ffi_closure_SYSV)
+.globl ffi_closure_SYSV
+	.type	ffi_closure_SYSV, @function
+
+ffi_closure_SYSV:
+.LFB2:
+	pushl	%ebp
+.LCFI2:
+	movl	%esp, %ebp
+.LCFI3:
+	subl	$40, %esp
+	leal	-24(%ebp), %edx
+	movl	%edx, -12(%ebp)	/* resp */
+	leal	8(%ebp), %edx
+	movl	%edx, 4(%esp)	/* args = __builtin_dwarf_cfa () */
+	leal	-12(%ebp), %edx
+	movl	%edx, (%esp)	/* &resp */
+#if defined HAVE_HIDDEN_VISIBILITY_ATTRIBUTE || !defined __PIC__
+	call	ffi_closure_SYSV_inner
+#else
+	movl	%ebx, 8(%esp)
+.LCFI7:
+	call	1f
+1:	popl	%ebx
+	addl	$_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx
+	call	ffi_closure_SYSV_inner at PLT
+	movl	8(%esp), %ebx
+#endif
+	movl	-12(%ebp), %ecx
+	cmpl	$FFI_TYPE_INT, %eax
+	je	.Lcls_retint
+	cmpl	$FFI_TYPE_FLOAT, %eax
+	je	.Lcls_retfloat
+	cmpl	$FFI_TYPE_DOUBLE, %eax
+	je	.Lcls_retdouble
+	cmpl	$FFI_TYPE_LONGDOUBLE, %eax
+	je	.Lcls_retldouble
+	cmpl	$FFI_TYPE_SINT64, %eax
+	je	.Lcls_retllong
+.Lcls_epilogue:
+	movl	%ebp, %esp
+	popl	%ebp
+	ret
+.Lcls_retint:
+	movl	(%ecx), %eax
+	jmp	.Lcls_epilogue
+.Lcls_retfloat:
+	flds	(%ecx)
+	jmp	.Lcls_epilogue
+.Lcls_retdouble:
+	fldl	(%ecx)
+	jmp	.Lcls_epilogue
+.Lcls_retldouble:
+	fldt	(%ecx)
+	jmp	.Lcls_epilogue
+.Lcls_retllong:
+	movl	(%ecx), %eax
+	movl	4(%ecx), %edx
+	jmp	.Lcls_epilogue
+.LFE2:
+	.size	ffi_closure_SYSV, .-ffi_closure_SYSV
+
+#if !FFI_NO_RAW_API
+
+#define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) & ~3)
+#define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4)
+#define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4)
+#define CIF_FLAGS_OFFSET 20
+
+	.align	4
+FFI_HIDDEN (ffi_closure_raw_SYSV)
+.globl ffi_closure_raw_SYSV
+	.type	ffi_closure_raw_SYSV, @function
+
+ffi_closure_raw_SYSV:
+.LFB3:
+	pushl	%ebp
+.LCFI4:
+	movl	%esp, %ebp
+.LCFI5:
+	pushl	%esi
+.LCFI6:
+	subl	$36, %esp
+	movl	RAW_CLOSURE_CIF_OFFSET(%eax), %esi	 /* closure->cif */
+	movl	RAW_CLOSURE_USER_DATA_OFFSET(%eax), %edx /* closure->user_data */
+	movl	%edx, 12(%esp)	/* user_data */
+	leal	8(%ebp), %edx	/* __builtin_dwarf_cfa () */
+	movl	%edx, 8(%esp)	/* raw_args */
+	leal	-24(%ebp), %edx
+	movl	%edx, 4(%esp)	/* &res */
+	movl	%esi, (%esp)	/* cif */
+	call	*RAW_CLOSURE_FUN_OFFSET(%eax)		 /* closure->fun */
+	movl	CIF_FLAGS_OFFSET(%esi), %eax		 /* rtype */
+	cmpl	$FFI_TYPE_INT, %eax
+	je	.Lrcls_retint
+	cmpl	$FFI_TYPE_FLOAT, %eax
+	je	.Lrcls_retfloat
+	cmpl	$FFI_TYPE_DOUBLE, %eax
+	je	.Lrcls_retdouble
+	cmpl	$FFI_TYPE_LONGDOUBLE, %eax
+	je	.Lrcls_retldouble
+	cmpl	$FFI_TYPE_SINT64, %eax
+	je	.Lrcls_retllong
+.Lrcls_epilogue:
+	addl	$36, %esp
+	popl	%esi
+	popl	%ebp
+	ret
+.Lrcls_retint:
+	movl	-24(%ebp), %eax
+	jmp	.Lrcls_epilogue
+.Lrcls_retfloat:
+	flds	-24(%ebp)
+	jmp	.Lrcls_epilogue
+.Lrcls_retdouble:
+	fldl	-24(%ebp)
+	jmp	.Lrcls_epilogue
+.Lrcls_retldouble:
+	fldt	-24(%ebp)
+	jmp	.Lrcls_epilogue
+.Lrcls_retllong:
+	movl	-24(%ebp), %eax
+	movl	-20(%ebp), %edx
+	jmp	.Lrcls_epilogue
+.LFE3:
+	.size	ffi_closure_raw_SYSV, .-ffi_closure_raw_SYSV
+#endif
+
+	.section	.eh_frame,EH_FRAME_FLAGS, at progbits
+.Lframe1:
+	.long	.LECIE1-.LSCIE1	/* Length of Common Information Entry */
+.LSCIE1:
+	.long	0x0	/* CIE Identifier Tag */
+	.byte	0x1	/* CIE Version */
+#ifdef __PIC__
+	.ascii "zR\0"	/* CIE Augmentation */
+#else
+	.ascii "\0"	/* CIE Augmentation */
+#endif
+	.byte	0x1	/* .uleb128 0x1; CIE Code Alignment Factor */
+	.byte	0x7c	/* .sleb128 -4; CIE Data Alignment Factor */
+	.byte	0x8	/* CIE RA Column */
+#ifdef __PIC__
+	.byte	0x1	/* .uleb128 0x1; Augmentation size */
+	.byte	0x1b	/* FDE Encoding (pcrel sdata4) */
+#endif
+	.byte	0xc	/* DW_CFA_def_cfa */
+	.byte	0x4	/* .uleb128 0x4 */
+	.byte	0x4	/* .uleb128 0x4 */
+	.byte	0x88	/* DW_CFA_offset, column 0x8 */
+	.byte	0x1	/* .uleb128 0x1 */
+	.align 4
+.LECIE1:
+.LSFDE1:
+	.long	.LEFDE1-.LASFDE1	/* FDE Length */
+.LASFDE1:
+	.long	.LASFDE1-.Lframe1	/* FDE CIE offset */
+#ifdef __PIC__
+	.long	.LFB1-.	/* FDE initial location */
+#else
+	.long	.LFB1	/* FDE initial location */
+#endif
+	.long	.LFE1-.LFB1	/* FDE address range */
+#ifdef __PIC__
+	.byte	0x0	/* .uleb128 0x0; Augmentation size */
+#endif
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.long	.LCFI0-.LFB1
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+	.byte	0x8	/* .uleb128 0x8 */
+	.byte	0x85	/* DW_CFA_offset, column 0x5 */
+	.byte	0x2	/* .uleb128 0x2 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.long	.LCFI1-.LCFI0
+	.byte	0xd	/* DW_CFA_def_cfa_register */
+	.byte	0x5	/* .uleb128 0x5 */
+	.align 4
+.LEFDE1:
+.LSFDE2:
+	.long	.LEFDE2-.LASFDE2	/* FDE Length */
+.LASFDE2:
+	.long	.LASFDE2-.Lframe1	/* FDE CIE offset */
+#ifdef __PIC__
+	.long	.LFB2-.	/* FDE initial location */
+#else
+	.long	.LFB2
+#endif
+	.long	.LFE2-.LFB2	/* FDE address range */
+#ifdef __PIC__
+	.byte	0x0	/* .uleb128 0x0; Augmentation size */
+#endif
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.long	.LCFI2-.LFB2
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+	.byte	0x8	/* .uleb128 0x8 */
+	.byte	0x85	/* DW_CFA_offset, column 0x5 */
+	.byte	0x2	/* .uleb128 0x2 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.long	.LCFI3-.LCFI2
+	.byte	0xd	/* DW_CFA_def_cfa_register */
+	.byte	0x5	/* .uleb128 0x5 */
+#if !defined HAVE_HIDDEN_VISIBILITY_ATTRIBUTE && defined __PIC__
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.long	.LCFI7-.LCFI3
+	.byte	0x83	/* DW_CFA_offset, column 0x3 */
+	.byte	0xa	/* .uleb128 0xa */
+#endif
+	.align 4
+.LEFDE2:
+
+#if !FFI_NO_RAW_API
+
+.LSFDE3:
+	.long	.LEFDE3-.LASFDE3	/* FDE Length */
+.LASFDE3:
+	.long	.LASFDE3-.Lframe1	/* FDE CIE offset */
+#ifdef __PIC__
+	.long	.LFB3-.	/* FDE initial location */
+#else
+	.long	.LFB3
+#endif
+	.long	.LFE3-.LFB3	/* FDE address range */
+#ifdef __PIC__
+	.byte	0x0	/* .uleb128 0x0; Augmentation size */
+#endif
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.long	.LCFI4-.LFB3
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+	.byte	0x8	/* .uleb128 0x8 */
+	.byte	0x85	/* DW_CFA_offset, column 0x5 */
+	.byte	0x2	/* .uleb128 0x2 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.long	.LCFI5-.LCFI4
+	.byte	0xd	/* DW_CFA_def_cfa_register */
+	.byte	0x5	/* .uleb128 0x5 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.long	.LCFI6-.LCFI5
+	.byte	0x86	/* DW_CFA_offset, column 0x6 */
+	.byte	0x3	/* .uleb128 0x3 */
+	.align 4
+.LEFDE3:
+
+#endif
+
+#endif /* ifndef __x86_64__ */
+
+#ifdef __ELF__
+.section .note.GNU-stack,"",%progbits
+#endif

Added: vendor/Python/current/Modules/_ctypes/libffi/src/x86/unix64.S
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/x86/unix64.S	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/x86/unix64.S	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,412 @@
+/* -----------------------------------------------------------------------
+   unix64.S - Copyright (c) 2002  Bo Thorsen <bo at suse.de>
+
+   x86-64 Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#ifdef __x86_64__
+#define LIBFFI_ASM	
+#include <fficonfig.h>
+#include <ffi.h>
+
+.text
+
+/* ffi_call_unix64 (void *args, unsigned long bytes, unsigned flags,
+	            void *raddr, void (*fnaddr)());
+
+   Bit o trickiness here -- ARGS+BYTES is the base of the stack frame
+   for this function.  This has been allocated by ffi_call.  We also
+   deallocate some of the stack that has been alloca'd.  */
+
+	.align	2
+	.globl	ffi_call_unix64
+	.type	ffi_call_unix64, at function
+
+ffi_call_unix64:
+.LUW0:
+	movq	(%rsp), %r10		/* Load return address.  */
+	leaq	(%rdi, %rsi), %rax	/* Find local stack base.  */
+	movq	%rdx, (%rax)		/* Save flags.  */
+	movq	%rcx, 8(%rax)		/* Save raddr.  */
+	movq	%rbp, 16(%rax)		/* Save old frame pointer.  */
+	movq	%r10, 24(%rax)		/* Relocate return address.  */
+	movq	%rax, %rbp		/* Finalize local stack frame.  */
+.LUW1:
+	movq	%rdi, %r10		/* Save a copy of the register area. */
+	movq	%r8, %r11		/* Save a copy of the target fn.  */
+	movl	%r9d, %eax		/* Set number of SSE registers.  */
+
+	/* Load up all argument registers.  */
+	movq	(%r10), %rdi
+	movq	8(%r10), %rsi
+	movq	16(%r10), %rdx
+	movq	24(%r10), %rcx
+	movq	32(%r10), %r8
+	movq	40(%r10), %r9
+	testl	%eax, %eax
+	jnz	.Lload_sse
+.Lret_from_load_sse:
+
+	/* Deallocate the reg arg area.  */
+	leaq	176(%r10), %rsp
+
+	/* Call the user function.  */
+	call	*%r11
+
+	/* Deallocate stack arg area; local stack frame in redzone.  */
+	leaq	24(%rbp), %rsp
+
+	movq	0(%rbp), %rcx		/* Reload flags.  */
+	movq	8(%rbp), %rdi		/* Reload raddr.  */
+	movq	16(%rbp), %rbp		/* Reload old frame pointer.  */
+.LUW2:
+
+	/* The first byte of the flags contains the FFI_TYPE.  */
+	movzbl	%cl, %r10d
+	leaq	.Lstore_table(%rip), %r11
+	movslq	(%r11, %r10, 4), %r10
+	addq	%r11, %r10
+	jmp	*%r10
+
+	.section .rodata
+.Lstore_table:
+	.long	.Lst_void-.Lstore_table		/* FFI_TYPE_VOID */
+	.long	.Lst_sint32-.Lstore_table	/* FFI_TYPE_INT */
+	.long	.Lst_float-.Lstore_table	/* FFI_TYPE_FLOAT */
+	.long	.Lst_double-.Lstore_table	/* FFI_TYPE_DOUBLE */
+	.long	.Lst_ldouble-.Lstore_table	/* FFI_TYPE_LONGDOUBLE */
+	.long	.Lst_uint8-.Lstore_table	/* FFI_TYPE_UINT8 */
+	.long	.Lst_sint8-.Lstore_table	/* FFI_TYPE_SINT8 */
+	.long	.Lst_uint16-.Lstore_table	/* FFI_TYPE_UINT16 */
+	.long	.Lst_sint16-.Lstore_table	/* FFI_TYPE_SINT16 */
+	.long	.Lst_uint32-.Lstore_table	/* FFI_TYPE_UINT32 */
+	.long	.Lst_sint32-.Lstore_table	/* FFI_TYPE_SINT32 */
+	.long	.Lst_int64-.Lstore_table	/* FFI_TYPE_UINT64 */
+	.long	.Lst_int64-.Lstore_table	/* FFI_TYPE_SINT64 */
+	.long	.Lst_struct-.Lstore_table	/* FFI_TYPE_STRUCT */
+	.long	.Lst_int64-.Lstore_table	/* FFI_TYPE_POINTER */
+
+	.text
+	.align 2
+.Lst_void:
+	ret
+	.align 2
+
+.Lst_uint8:
+	movzbq	%al, %rax
+	movq	%rax, (%rdi)
+	ret
+	.align 2
+.Lst_sint8:
+	movsbq	%al, %rax
+	movq	%rax, (%rdi)
+	ret
+	.align 2
+.Lst_uint16:
+	movzwq	%ax, %rax
+	movq	%rax, (%rdi)
+	.align 2
+.Lst_sint16:
+	movswq	%ax, %rax
+	movq	%rax, (%rdi)
+	ret
+	.align 2
+.Lst_uint32:
+	movl	%eax, %eax
+	movq	%rax, (%rdi)
+	.align 2
+.Lst_sint32:
+	cltq
+	movq	%rax, (%rdi)
+	ret
+	.align 2
+.Lst_int64:
+	movq	%rax, (%rdi)
+	ret
+
+	.align 2
+.Lst_float:
+	movss	%xmm0, (%rdi)
+	ret
+	.align 2
+.Lst_double:
+	movsd	%xmm0, (%rdi)
+	ret
+.Lst_ldouble:
+	fstpt	(%rdi)
+	ret
+
+	.align 2
+.Lst_struct:
+	leaq	-20(%rsp), %rsi		/* Scratch area in redzone.  */
+
+	/* We have to locate the values now, and since we don't want to
+	   write too much data into the user's return value, we spill the
+	   value to a 16 byte scratch area first.  Bits 8, 9, and 10
+	   control where the values are located.  Only one of the three
+	   bits will be set; see ffi_prep_cif_machdep for the pattern.  */
+	movd	%xmm0, %r10
+	movd	%xmm1, %r11
+	testl	$0x100, %ecx
+	cmovnz	%rax, %rdx
+	cmovnz	%r10, %rax
+	testl	$0x200, %ecx
+	cmovnz	%r10, %rdx
+	testl	$0x400, %ecx
+	cmovnz	%r10, %rax
+	cmovnz	%r11, %rdx
+	movq	%rax, (%rsi)
+	movq	%rdx, 8(%rsi)
+
+	/* Bits 12-31 contain the true size of the structure.  Copy from
+	   the scratch area to the true destination.  */
+	shrl	$12, %ecx
+	rep movsb
+	ret
+
+	/* Many times we can avoid loading any SSE registers at all.
+	   It's not worth an indirect jump to load the exact set of
+	   SSE registers needed; zero or all is a good compromise.  */
+	.align 2
+.LUW3:
+.Lload_sse:
+	movdqa	48(%r10), %xmm0
+	movdqa	64(%r10), %xmm1
+	movdqa	80(%r10), %xmm2
+	movdqa	96(%r10), %xmm3
+	movdqa	112(%r10), %xmm4
+	movdqa	128(%r10), %xmm5
+	movdqa	144(%r10), %xmm6
+	movdqa	160(%r10), %xmm7
+	jmp	.Lret_from_load_sse
+
+.LUW4:
+	.size    ffi_call_unix64,.-ffi_call_unix64
+
+	.align	2
+	.globl ffi_closure_unix64
+	.type	ffi_closure_unix64, at function
+
+ffi_closure_unix64:
+.LUW5:
+	/* The carry flag is set by the trampoline iff SSE registers
+	   are used.  Don't clobber it before the branch instruction.  */
+	leaq    -200(%rsp), %rsp
+.LUW6:
+	movq	%rdi, (%rsp)
+	movq    %rsi, 8(%rsp)
+	movq    %rdx, 16(%rsp)
+	movq    %rcx, 24(%rsp)
+	movq    %r8, 32(%rsp)
+	movq    %r9, 40(%rsp)
+	jc      .Lsave_sse
+.Lret_from_save_sse:
+
+	movq	%r10, %rdi
+	leaq	176(%rsp), %rsi
+	movq	%rsp, %rdx
+	leaq	208(%rsp), %rcx
+	call	ffi_closure_unix64_inner at PLT
+
+	/* Deallocate stack frame early; return value is now in redzone.  */
+	addq	$200, %rsp
+.LUW7:
+
+	/* The first byte of the return value contains the FFI_TYPE.  */
+	movzbl	%al, %r10d
+	leaq	.Lload_table(%rip), %r11
+	movslq	(%r11, %r10, 4), %r10
+	addq	%r11, %r10
+	jmp	*%r10
+
+	.section .rodata
+.Lload_table:
+	.long	.Lld_void-.Lload_table		/* FFI_TYPE_VOID */
+	.long	.Lld_int32-.Lload_table		/* FFI_TYPE_INT */
+	.long	.Lld_float-.Lload_table		/* FFI_TYPE_FLOAT */
+	.long	.Lld_double-.Lload_table	/* FFI_TYPE_DOUBLE */
+	.long	.Lld_ldouble-.Lload_table	/* FFI_TYPE_LONGDOUBLE */
+	.long	.Lld_int8-.Lload_table		/* FFI_TYPE_UINT8 */
+	.long	.Lld_int8-.Lload_table		/* FFI_TYPE_SINT8 */
+	.long	.Lld_int16-.Lload_table		/* FFI_TYPE_UINT16 */
+	.long	.Lld_int16-.Lload_table		/* FFI_TYPE_SINT16 */
+	.long	.Lld_int32-.Lload_table		/* FFI_TYPE_UINT32 */
+	.long	.Lld_int32-.Lload_table		/* FFI_TYPE_SINT32 */
+	.long	.Lld_int64-.Lload_table		/* FFI_TYPE_UINT64 */
+	.long	.Lld_int64-.Lload_table		/* FFI_TYPE_SINT64 */
+	.long	.Lld_struct-.Lload_table	/* FFI_TYPE_STRUCT */
+	.long	.Lld_int64-.Lload_table		/* FFI_TYPE_POINTER */
+
+	.text
+	.align 2
+.Lld_void:
+	ret
+
+	.align 2
+.Lld_int8:
+	movzbl	-24(%rsp), %eax
+	ret
+	.align 2
+.Lld_int16:
+	movzwl	-24(%rsp), %eax
+	ret
+	.align 2
+.Lld_int32:
+	movl	-24(%rsp), %eax
+	ret
+	.align 2
+.Lld_int64:
+	movq	-24(%rsp), %rax
+	ret
+
+	.align 2
+.Lld_float:
+	movss	-24(%rsp), %xmm0
+	ret
+	.align 2
+.Lld_double:
+	movsd	-24(%rsp), %xmm0
+	ret
+	.align 2
+.Lld_ldouble:
+	fldt	-24(%rsp)
+	ret
+
+	.align 2
+.Lld_struct:
+	/* There are four possibilities here, %rax/%rdx, %xmm0/%rax,
+	   %rax/%xmm0, %xmm0/%xmm1.  We collapse two by always loading
+	   both rdx and xmm1 with the second word.  For the remaining,
+	   bit 8 set means xmm0 gets the second word, and bit 9 means
+	   that rax gets the second word.  */
+	movq	-24(%rsp), %rcx
+	movq	-16(%rsp), %rdx
+	movq	-16(%rsp), %xmm1
+	testl	$0x100, %eax
+	cmovnz	%rdx, %rcx
+	movd	%rcx, %xmm0
+	testl	$0x200, %eax
+	movq	-24(%rsp), %rax
+	cmovnz	%rdx, %rax
+	ret
+
+	/* See the comment above .Lload_sse; the same logic applies here.  */
+	.align 2
+.LUW8:
+.Lsave_sse:
+	movdqa	%xmm0, 48(%rsp)
+	movdqa	%xmm1, 64(%rsp)
+	movdqa	%xmm2, 80(%rsp)
+	movdqa	%xmm3, 96(%rsp)
+	movdqa	%xmm4, 112(%rsp)
+	movdqa	%xmm5, 128(%rsp)
+	movdqa	%xmm6, 144(%rsp)
+	movdqa	%xmm7, 160(%rsp)
+	jmp	.Lret_from_save_sse
+
+.LUW9:
+	.size	ffi_closure_unix64,.-ffi_closure_unix64
+
+	.section	.eh_frame,"a", at progbits
+.Lframe1:
+	.long	.LECIE1-.LSCIE1		/* CIE Length */
+.LSCIE1:
+	.long	0			/* CIE Identifier Tag */
+	.byte	1			/* CIE Version */
+	.ascii "zR\0"			/* CIE Augmentation */
+	.uleb128 1			/* CIE Code Alignment Factor */
+	.sleb128 -8			/* CIE Data Alignment Factor */
+	.byte	0x10			/* CIE RA Column */
+	.uleb128 1			/* Augmentation size */
+	.byte	0x1b			/* FDE Encoding (pcrel sdata4) */
+	.byte	0xc			/* DW_CFA_def_cfa, %rsp offset 8 */
+	.uleb128 7
+	.uleb128 8
+	.byte	0x80+16			/* DW_CFA_offset, %rip offset 1*-8 */
+	.uleb128 1
+	.align 8
+.LECIE1:
+.LSFDE1:
+	.long	.LEFDE1-.LASFDE1	/* FDE Length */
+.LASFDE1:
+	.long	.LASFDE1-.Lframe1	/* FDE CIE offset */
+	.long	.LUW0-.			/* FDE initial location */
+	.long	.LUW4-.LUW0		/* FDE address range */
+	.uleb128 0x0			/* Augmentation size */
+
+	.byte	0x4			/* DW_CFA_advance_loc4 */
+	.long	.LUW1-.LUW0
+
+	/* New stack frame based off rbp.  This is a itty bit of unwind
+	   trickery in that the CFA *has* changed.  There is no easy way
+	   to describe it correctly on entry to the function.  Fortunately,
+	   it doesn't matter too much since at all points we can correctly
+	   unwind back to ffi_call.  Note that the location to which we
+	   moved the return address is (the new) CFA-8, so from the
+	   perspective of the unwind info, it hasn't moved.  */
+	.byte	0xc			/* DW_CFA_def_cfa, %rbp offset 32 */
+	.uleb128 6
+	.uleb128 32
+	.byte	0x80+6			/* DW_CFA_offset, %rbp offset 2*-8 */
+	.uleb128 2
+	.byte	0xa			/* DW_CFA_remember_state */
+
+	.byte	0x4			/* DW_CFA_advance_loc4 */
+	.long	.LUW2-.LUW1
+	.byte	0xc			/* DW_CFA_def_cfa, %rsp offset 8 */
+	.uleb128 7
+	.uleb128 8
+	.byte	0xc0+6			/* DW_CFA_restore, %rbp */
+
+	.byte	0x4			/* DW_CFA_advance_loc4 */
+	.long	.LUW3-.LUW2
+	.byte	0xb			/* DW_CFA_restore_state */
+
+	.align 8
+.LEFDE1:
+.LSFDE3:
+	.long	.LEFDE3-.LASFDE3	/* FDE Length */
+.LASFDE3:
+	.long	.LASFDE3-.Lframe1	/* FDE CIE offset */
+	.long	.LUW5-.			/* FDE initial location */
+	.long	.LUW9-.LUW5		/* FDE address range */
+	.uleb128 0x0			/* Augmentation size */
+
+	.byte	0x4			/* DW_CFA_advance_loc4 */
+	.long	.LUW6-.LUW5
+	.byte	0xe			/* DW_CFA_def_cfa_offset */
+	.uleb128 208
+	.byte	0xa			/* DW_CFA_remember_state */
+
+	.byte	0x4			/* DW_CFA_advance_loc4 */
+	.long	.LUW7-.LUW6
+	.byte	0xe			/* DW_CFA_def_cfa_offset */
+	.uleb128 8
+
+	.byte	0x4			/* DW_CFA_advance_loc4 */
+	.long	.LUW8-.LUW7
+	.byte	0xb			/* DW_CFA_restore_state */
+
+	.align 8
+.LEFDE3:
+
+#endif /* __x86_64__ */

Added: vendor/Python/current/Modules/_ctypes/libffi/src/x86/win32.S
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi/src/x86/win32.S	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi/src/x86/win32.S	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,373 @@
+/* -----------------------------------------------------------------------
+   win32.S - Copyright (c) 1996, 1998, 2001, 2002  Red Hat, Inc.
+	     Copyright (c) 2001  John Beniton
+	     Copyright (c) 2002  Ranjit Mathew
+			
+ 
+   X86 Foreign Function Interface
+ 
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+ 
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+ 
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+ 
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+ 
+.text
+ 
+.globl ffi_prep_args
+ 
+        # This assumes we are using gas.
+        .balign 16
+.globl _ffi_call_SYSV
+ 
+_ffi_call_SYSV:
+        pushl %ebp
+        movl  %esp,%ebp
+ 
+        # Make room for all of the new args.
+        movl  16(%ebp),%ecx                                                     
+        subl  %ecx,%esp
+ 
+        movl  %esp,%eax
+ 
+        # Place all of the ffi_prep_args in position
+        pushl 12(%ebp)
+        pushl %eax
+        call  *8(%ebp)
+ 
+        # Return stack to previous state and call the function
+        addl  $8,%esp
+ 
+        # FIXME: Align the stack to a 128-bit boundary to avoid
+        # potential performance hits.
+
+	call  *28(%ebp)
+ 
+        # Remove the space we pushed for the args
+        movl  16(%ebp),%ecx
+        addl  %ecx,%esp
+ 
+        # Load %ecx with the return type code
+        movl  20(%ebp),%ecx
+ 
+        # If the return value pointer is NULL, assume no return value.
+        cmpl  $0,24(%ebp)
+        jne   retint
+ 
+        # Even if there is no space for the return value, we are
+        # obliged to handle floating-point values.
+        cmpl  $FFI_TYPE_FLOAT,%ecx
+        jne   noretval
+        fstp  %st(0)
+ 
+        jmp   epilogue
+ 
+retint:
+        cmpl  $FFI_TYPE_INT,%ecx
+        jne   retfloat
+        # Load %ecx with the pointer to storage for the return value
+        movl  24(%ebp),%ecx
+        movl  %eax,0(%ecx)
+        jmp   epilogue
+ 
+retfloat:
+        cmpl  $FFI_TYPE_FLOAT,%ecx
+        jne   retdouble   
+         # Load %ecx with the pointer to storage for the return value
+        movl  24(%ebp),%ecx
+        fstps (%ecx)
+        jmp   epilogue
+ 
+retdouble:
+        cmpl  $FFI_TYPE_DOUBLE,%ecx
+        jne   retlongdouble
+        # Load %ecx with the pointer to storage for the return value
+        movl  24(%ebp),%ecx
+        fstpl (%ecx)
+        jmp   epilogue
+ 
+retlongdouble:
+        cmpl  $FFI_TYPE_LONGDOUBLE,%ecx
+        jne   retint64
+        # Load %ecx with the pointer to storage for the return value
+        movl  24(%ebp),%ecx
+        fstpt (%ecx)
+        jmp   epilogue
+ 
+retint64:
+        cmpl  $FFI_TYPE_SINT64,%ecx
+        jne   retstruct1b
+        # Load %ecx with the pointer to storage for the return value
+        movl  24(%ebp),%ecx
+        movl  %eax,0(%ecx)
+        movl  %edx,4(%ecx)
+ 
+retstruct1b:
+        cmpl  $FFI_TYPE_SINT8,%ecx
+        jne   retstruct2b
+        # Load %ecx with the pointer to storage for the return value
+        movl  24(%ebp),%ecx
+        movb  %al,0(%ecx)
+        jmp   epilogue
+ 
+retstruct2b:
+        cmpl  $FFI_TYPE_SINT16,%ecx
+        jne   retstruct
+        # Load %ecx with the pointer to storage for the return value
+        movl  24(%ebp),%ecx
+        movw  %ax,0(%ecx)
+        jmp   epilogue
+ 
+retstruct:
+        # Nothing to do!
+ 
+noretval:
+epilogue:
+        movl %ebp,%esp
+        popl %ebp
+        ret
+ 
+.ffi_call_SYSV_end:
+
+        # This assumes we are using gas.
+        .balign 16
+.globl _ffi_call_STDCALL
+
+_ffi_call_STDCALL:
+        pushl %ebp
+        movl  %esp,%ebp
+
+        # Make room for all of the new args.
+        movl  16(%ebp),%ecx 
+        subl  %ecx,%esp
+
+        movl  %esp,%eax
+
+        # Place all of the ffi_prep_args in position
+        pushl 12(%ebp)
+        pushl %eax
+        call  *8(%ebp)
+
+        # Return stack to previous state and call the function
+        addl  $8,%esp
+
+        # FIXME: Align the stack to a 128-bit boundary to avoid
+        # potential performance hits.
+
+        call  *28(%ebp)
+
+        # stdcall functions pop arguments off the stack themselves
+
+        # Load %ecx with the return type code
+        movl  20(%ebp),%ecx
+
+        # If the return value pointer is NULL, assume no return value.
+        cmpl  $0,24(%ebp)
+        jne   sc_retint
+
+        # Even if there is no space for the return value, we are
+        # obliged to handle floating-point values.
+        cmpl  $FFI_TYPE_FLOAT,%ecx
+        jne   sc_noretval
+        fstp  %st(0)
+
+        jmp   sc_epilogue
+
+sc_retint:
+        cmpl  $FFI_TYPE_INT,%ecx
+        jne   sc_retfloat
+        # Load %ecx with the pointer to storage for the return value
+        movl  24(%ebp),%ecx
+        movl  %eax,0(%ecx)
+        jmp   sc_epilogue
+
+sc_retfloat:
+        cmpl  $FFI_TYPE_FLOAT,%ecx
+        jne   sc_retdouble
+         # Load %ecx with the pointer to storage for the return value
+        movl  24(%ebp),%ecx
+        fstps (%ecx)
+        jmp   sc_epilogue
+
+sc_retdouble:
+        cmpl  $FFI_TYPE_DOUBLE,%ecx
+        jne   sc_retlongdouble
+        # Load %ecx with the pointer to storage for the return value
+        movl  24(%ebp),%ecx
+        fstpl (%ecx)
+        jmp   sc_epilogue
+
+sc_retlongdouble:
+        cmpl  $FFI_TYPE_LONGDOUBLE,%ecx
+        jne   sc_retint64
+        # Load %ecx with the pointer to storage for the return value
+        movl  24(%ebp),%ecx
+        fstpt (%ecx)
+        jmp   sc_epilogue
+
+sc_retint64:
+        cmpl  $FFI_TYPE_SINT64,%ecx
+        jne   sc_retstruct1b
+        # Load %ecx with the pointer to storage for the return value
+        movl  24(%ebp),%ecx
+        movl  %eax,0(%ecx)
+        movl  %edx,4(%ecx)
+
+sc_retstruct1b:
+        cmpl  $FFI_TYPE_SINT8,%ecx
+        jne   sc_retstruct2b
+        # Load %ecx with the pointer to storage for the return value
+        movl  24(%ebp),%ecx
+        movb  %al,0(%ecx)
+        jmp   sc_epilogue
+
+sc_retstruct2b:
+        cmpl  $FFI_TYPE_SINT16,%ecx
+        jne   sc_retstruct
+        # Load %ecx with the pointer to storage for the return value
+        movl  24(%ebp),%ecx
+        movw  %ax,0(%ecx)
+        jmp   sc_epilogue
+
+sc_retstruct:
+        # Nothing to do!
+
+sc_noretval:
+sc_epilogue:
+        movl %ebp,%esp
+        popl %ebp
+        ret
+
+.ffi_call_STDCALL_end:
+
+	.globl _ffi_closure_SYSV
+_ffi_closure_SYSV:
+	pushl	%ebp
+	movl	%esp, %ebp
+	subl	$40, %esp
+	leal	-24(%ebp), %edx
+	movl	%edx, -12(%ebp)	/* resp */
+	leal	8(%ebp), %edx
+	movl	%edx, 4(%esp)	/* args = __builtin_dwarf_cfa () */
+	leal	-12(%ebp), %edx
+	movl	%edx, (%esp)	/* &resp */
+	call	_ffi_closure_SYSV_inner
+	movl	-12(%ebp), %ecx
+	cmpl	$FFI_TYPE_INT, %eax
+	je	.Lcls_retint
+	cmpl	$FFI_TYPE_FLOAT, %eax
+	je	.Lcls_retfloat
+	cmpl	$FFI_TYPE_DOUBLE, %eax
+	je	.Lcls_retdouble
+	cmpl	$FFI_TYPE_LONGDOUBLE, %eax
+	je	.Lcls_retldouble
+	cmpl	$FFI_TYPE_SINT64, %eax
+	je	.Lcls_retllong
+	cmpl	$FFI_TYPE_SINT8, %eax	/* 1-byte struct */
+	je	.Lcls_retstruct1
+	cmpl	$FFI_TYPE_SINT16, %eax	/* 2-bytes struct */
+	je	.Lcls_retstruct2
+.Lcls_epilogue:
+	movl	%ebp, %esp
+	popl	%ebp
+	ret
+.Lcls_retint:
+	movl	(%ecx), %eax
+	jmp	.Lcls_epilogue
+.Lcls_retfloat:
+	flds	(%ecx)
+	jmp	.Lcls_epilogue
+.Lcls_retdouble:
+	fldl	(%ecx)
+	jmp	.Lcls_epilogue
+.Lcls_retldouble:
+	fldt	(%ecx)
+	jmp	.Lcls_epilogue
+.Lcls_retllong:
+	movl	(%ecx), %eax
+	movl	4(%ecx), %edx
+	jmp	.Lcls_epilogue
+.Lcls_retstruct1:
+	movsbl	(%ecx), %eax
+	jmp	.Lcls_epilogue
+.Lcls_retstruct2:
+	movswl	(%ecx), %eax
+	jmp	.Lcls_epilogue
+.ffi_closure_SYSV_end:
+
+#if !FFI_NO_RAW_API
+
+#define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) & ~3)
+#define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4)
+#define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4)
+#define CIF_FLAGS_OFFSET 20
+
+	.balign	16
+	.globl _ffi_closure_raw_SYSV
+_ffi_closure_raw_SYSV:
+	pushl	%ebp
+	movl	%esp, %ebp
+	pushl	%esi
+	subl	$36, %esp
+	movl	RAW_CLOSURE_CIF_OFFSET(%eax), %esi	 /* closure->cif */
+	movl	RAW_CLOSURE_USER_DATA_OFFSET(%eax), %edx /* closure->user_data */
+	movl	%edx, 12(%esp)	/* user_data */
+	leal	8(%ebp), %edx	/* __builtin_dwarf_cfa () */
+	movl	%edx, 8(%esp)	/* raw_args */
+	leal	-24(%ebp), %edx
+	movl	%edx, 4(%esp)	/* &res */
+	movl	%esi, (%esp)	/* cif */
+	call	*RAW_CLOSURE_FUN_OFFSET(%eax)		 /* closure->fun */
+	movl	CIF_FLAGS_OFFSET(%esi), %eax		 /* rtype */
+	cmpl	$FFI_TYPE_INT, %eax
+	je	.Lrcls_retint
+	cmpl	$FFI_TYPE_FLOAT, %eax
+	je	.Lrcls_retfloat
+	cmpl	$FFI_TYPE_DOUBLE, %eax
+	je	.Lrcls_retdouble
+	cmpl	$FFI_TYPE_LONGDOUBLE, %eax
+	je	.Lrcls_retldouble
+	cmpl	$FFI_TYPE_SINT64, %eax
+	je	.Lrcls_retllong
+.Lrcls_epilogue:
+	addl	$36, %esp
+	popl	%esi
+	popl	%ebp
+	ret
+.Lrcls_retint:
+	movl	-24(%ebp), %eax
+	jmp	.Lrcls_epilogue
+.Lrcls_retfloat:
+	flds	-24(%ebp)
+	jmp	.Lrcls_epilogue
+.Lrcls_retdouble:
+	fldl	-24(%ebp)
+	jmp	.Lrcls_epilogue
+.Lrcls_retldouble:
+	fldt	-24(%ebp)
+	jmp	.Lrcls_epilogue
+.Lrcls_retllong:
+	movl	-24(%ebp), %eax
+	movl	-20(%ebp), %edx
+	jmp	.Lrcls_epilogue
+.ffi_closure_raw_SYSV_end:
+
+#endif

Added: vendor/Python/current/Modules/_ctypes/libffi_arm_wince/debug.c
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi_arm_wince/debug.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi_arm_wince/debug.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,59 @@
+/* -----------------------------------------------------------------------
+   debug.c - Copyright (c) 1996 Red Hat, Inc.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+/* General debugging routines */
+
+void ffi_stop_here(void)
+{
+  /* This function is only useful for debugging purposes.
+     Place a breakpoint on ffi_stop_here to be notified of 
+     significant events. */
+}
+
+/* This function should only be called via the FFI_ASSERT() macro */
+
+void ffi_assert(char *expr, char *file, int line)
+{
+  fprintf(stderr, "ASSERTION FAILURE: %s at %s:%d\n", expr, file, line);
+  ffi_stop_here();
+  abort();
+}
+
+/* Perform a sanity check on an ffi_type structure */
+
+void ffi_type_test(ffi_type *a, char *file, int line)
+{
+  FFI_ASSERT_AT(a != NULL, file, line);
+
+  /*@-usedef@*/
+  FFI_ASSERT_AT(a->type <= FFI_TYPE_LAST, file, line);
+  FFI_ASSERT_AT(a->type == FFI_TYPE_VOID || a->size > 0, file, line);
+  FFI_ASSERT_AT(a->type == FFI_TYPE_VOID || a->alignment > 0, file, line);
+  FFI_ASSERT_AT(a->type != FFI_TYPE_STRUCT || a->elements != NULL, file, line);
+  /*@=usedef@*/
+}

Added: vendor/Python/current/Modules/_ctypes/libffi_arm_wince/ffi.c
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi_arm_wince/ffi.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi_arm_wince/ffi.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,310 @@
+/* -----------------------------------------------------------------------
+   ffi.c - Copyright (c) 1998  Red Hat, Inc.
+   
+   ARM Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+
+#ifdef _WIN32_WCE
+#pragma warning (disable : 4142)    /* benign redefinition of type */
+#include <windows.h>
+#endif
+
+/* ffi_prep_args is called by the assembly routine once stack space
+   has been allocated for the function's arguments */
+
+/*@-exportheader@*/
+void ffi_prep_args(char *stack, extended_cif *ecif)
+/*@=exportheader@*/
+{
+  register unsigned int i;
+  register void **p_argv;
+  register char *argp;
+  register ffi_type **p_arg;
+
+  argp = stack;
+
+  if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT ) {
+    *(void **) argp = ecif->rvalue;
+    argp += 4;
+  }
+
+  p_argv = ecif->avalue;
+
+  for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
+       (i != 0);
+       i--, p_arg++)
+    {
+      size_t z;
+      size_t argalign = (*p_arg)->alignment;
+
+#ifdef _WIN32_WCE
+      if (argalign > 4)
+        argalign = 4;
+#endif
+      /* Align if necessary */
+      if ((argalign - 1) & (unsigned) argp) {
+	argp = (char *) ALIGN(argp, argalign);
+      }
+
+	  z = (*p_arg)->size;
+	  if (z < sizeof(int))
+	    {
+	      z = sizeof(int);
+	      switch ((*p_arg)->type)
+		{
+		case FFI_TYPE_SINT8:
+		  *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
+		  break;
+		  
+		case FFI_TYPE_UINT8:
+		  *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
+		  break;
+		  
+		case FFI_TYPE_SINT16:
+		  *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
+		  break;
+		  
+		case FFI_TYPE_UINT16:
+		  *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
+		  break;
+		  
+		case FFI_TYPE_STRUCT:
+                  /* *p_argv may not be aligned for a UINT32 */
+                  memcpy(argp, *p_argv, z);
+		  break;
+
+		default:
+		  FFI_ASSERT(0);
+		}
+	    }
+	  else if (z == sizeof(int))
+	    {
+	      *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+	    }
+	  else
+	    {
+	      memcpy(argp, *p_argv, z);
+	    }
+	  p_argv++;
+	  argp += z;
+    }
+  
+  return;
+}
+
+/* Perform machine dependent cif processing */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+{
+  /* Set the return type flag */
+  switch (cif->rtype->type)
+    {
+    case FFI_TYPE_VOID:
+    case FFI_TYPE_STRUCT:
+    case FFI_TYPE_FLOAT:
+    case FFI_TYPE_DOUBLE:
+    case FFI_TYPE_SINT64:
+      cif->flags = (unsigned) cif->rtype->type;
+      break;
+
+    case FFI_TYPE_UINT64:
+      cif->flags = FFI_TYPE_SINT64;
+      break;
+
+    default:
+      cif->flags = FFI_TYPE_INT;
+      break;
+    }
+
+  return FFI_OK;
+}
+
+/*@-declundef@*/
+/*@-exportheader@*/
+extern void ffi_call_SYSV(void (*)(char *, extended_cif *), 
+			  /*@out@*/ extended_cif *, 
+			  unsigned, unsigned, 
+			  /*@out@*/ unsigned *, 
+			  void (*fn)());
+/*@=declundef@*/
+/*@=exportheader@*/
+
+/* Return type changed from void for ctypes */
+int ffi_call(/*@dependent@*/ ffi_cif *cif, 
+	      void (*fn)(), 
+	      /*@out@*/ void *rvalue, 
+	      /*@dependent@*/ void **avalue)
+{
+  extended_cif ecif;
+
+  ecif.cif = cif;
+  ecif.avalue = avalue;
+  
+  /* If the return value is a struct and we don't have a return	*/
+  /* value address then we need to make one		        */
+
+  if ((rvalue == NULL) && 
+      (cif->rtype->type == FFI_TYPE_STRUCT))
+    {
+      /*@-sysunrecog@*/
+      ecif.rvalue = alloca(cif->rtype->size);
+      /*@=sysunrecog@*/
+    }
+  else
+    ecif.rvalue = rvalue;
+    
+  
+  switch (cif->abi) 
+    {
+    case FFI_SYSV:
+      /*@-usedef@*/
+      ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, 
+		    cif->flags, ecif.rvalue, fn);
+      /*@=usedef@*/
+      break;
+    default:
+      FFI_ASSERT(0);
+      break;
+    }
+  /* I think calculating the real stack pointer delta is not useful
+     because stdcall is not supported */
+  return 0;
+}
+
+/** private members **/
+
+static void ffi_prep_incoming_args_SYSV (char *stack, void **ret,
+					 void** args, ffi_cif* cif);
+
+/* This function is called by ffi_closure_SYSV in sysv.asm */
+
+unsigned int
+ffi_closure_SYSV_inner (ffi_closure *closure, char *in_args, void *rvalue)
+{
+  ffi_cif *cif = closure->cif;
+  void **out_args;
+
+  out_args = (void **) alloca(cif->nargs * sizeof (void *));  
+
+  /* this call will initialize out_args, such that each
+   * element in that array points to the corresponding 
+   * value on the stack; and if the function returns
+   * a structure, it will re-set rvalue to point to the
+   * structure return address.  */
+
+  ffi_prep_incoming_args_SYSV(in_args, &rvalue, out_args, cif);
+  
+  (closure->fun)(cif, rvalue, out_args, closure->user_data);
+
+  /* Tell ffi_closure_SYSV what the returntype is */
+  return cif->flags;
+}
+
+/*@-exportheader@*/
+static void 
+ffi_prep_incoming_args_SYSV(char *stack, void **rvalue,
+			    void **avalue, ffi_cif *cif)
+/*@=exportheader@*/
+{
+  unsigned int i;
+  void **p_argv;
+  char *argp;
+  ffi_type **p_arg;
+
+  argp = stack;
+
+  if ( cif->rtype->type == FFI_TYPE_STRUCT ) {
+    *rvalue = *(void **) argp;
+    argp += 4;
+  }
+
+  p_argv = avalue;
+
+  for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++)
+    {
+      size_t z;
+      size_t argalign = (*p_arg)->alignment;
+
+#ifdef _WIN32_WCE
+      if (argalign > 4)
+        argalign = 4;
+#endif
+      /* Align if necessary */
+      if ((argalign - 1) & (unsigned) argp) {
+	argp = (char *) ALIGN(argp, argalign);
+      }
+
+      z = (*p_arg)->size;
+      if (z < sizeof(int))
+        z = sizeof(int);
+
+      *p_argv = (void*) argp;
+
+      p_argv++;
+      argp += z;
+    }
+}
+
+/*
+    add   ip, pc, #-8     ; ip = address of this trampoline == address of ffi_closure
+    ldr   pc, [pc, #-4]   ; jump to __fun
+    DCD __fun
+*/
+#define FFI_INIT_TRAMPOLINE(TRAMP,FUN) \
+{ \
+    unsigned int *__tramp = (unsigned int *)(TRAMP); \
+    __tramp[0] = 0xe24fc008;            /* add   ip, pc, #-8    */ \
+    __tramp[1] = 0xe51ff004;            /* ldr   pc, [pc, #-4]  */ \
+    __tramp[2] = (unsigned int)(FUN); \
+  }
+
+/* the cif must already be prep'ed */
+
+/* defined in sysv.asm */
+void ffi_closure_SYSV(void);
+
+ffi_status
+ffi_prep_closure (ffi_closure* closure,
+		  ffi_cif* cif,
+		  void (*fun)(ffi_cif*,void*,void**,void*),
+		  void *user_data)
+{
+  FFI_ASSERT (cif->abi == FFI_SYSV);
+  
+  FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_SYSV);
+
+  closure->cif  = cif;
+  closure->user_data = user_data;
+  closure->fun  = fun;
+
+#ifdef _WIN32_WCE
+  /* This is important to allow calling the trampoline safely */
+  FlushInstructionCache(GetCurrentProcess(), 0, 0);
+#endif
+
+  return FFI_OK;
+}
+

Added: vendor/Python/current/Modules/_ctypes/libffi_arm_wince/ffi.h
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi_arm_wince/ffi.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi_arm_wince/ffi.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,317 @@
+/* -----------------------------------------------------------------*-C-*-
+   libffi 2.00-beta-wince - Copyright (c) 1996-2003  Red Hat, Inc.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+
+   ----------------------------------------------------------------------- */
+
+/* -------------------------------------------------------------------
+   The basic API is described in the README file.
+
+   The raw API is designed to bypass some of the argument packing
+   and unpacking on architectures for which it can be avoided.
+
+   The closure API allows interpreted functions to be packaged up
+   inside a C function pointer, so that they can be called as C functions,
+   with no understanding on the client side that they are interpreted.
+   It can also be used in other cases in which it is necessary to package
+   up a user specified parameter and a function pointer as a single
+   function pointer.
+
+   The closure API must be implemented in order to get its functionality,
+   e.g. for use by gij.  Routines are provided to emulate the raw API
+   if the underlying platform doesn't allow faster implementation.
+
+   More details on the raw and cloure API can be found in:
+
+   http://gcc.gnu.org/ml/java/1999-q3/msg00138.html
+
+   and
+
+   http://gcc.gnu.org/ml/java/1999-q3/msg00174.html
+   -------------------------------------------------------------------- */
+
+#ifndef LIBFFI_H
+#define LIBFFI_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Specify which architecture libffi is configured for. */
+/*#define @TARGET@*/
+
+/* ---- System configuration information --------------------------------- */
+
+#include <ffitarget.h>
+
+#ifndef LIBFFI_ASM
+
+#include <stddef.h>
+#include <limits.h>
+
+/* LONG_LONG_MAX is not always defined (not if STRICT_ANSI, for example).
+   But we can find it either under the correct ANSI name, or under GNU
+   C's internal name.  */
+#ifdef LONG_LONG_MAX
+# define FFI_LONG_LONG_MAX LONG_LONG_MAX
+#else
+# ifdef LLONG_MAX
+#  define FFI_LONG_LONG_MAX LLONG_MAX
+# else
+#  ifdef __GNUC__
+#   define FFI_LONG_LONG_MAX __LONG_LONG_MAX__
+#  endif
+#  ifdef _MSC_VER
+#   define FFI_LONG_LONG_MAX _I64_MAX
+#  endif
+# endif
+#endif
+
+#if SCHAR_MAX == 127
+# define ffi_type_uchar                ffi_type_uint8
+# define ffi_type_schar                ffi_type_sint8
+#else
+ #error "char size not supported"
+#endif
+
+#if SHRT_MAX == 32767
+# define ffi_type_ushort       ffi_type_uint16
+# define ffi_type_sshort       ffi_type_sint16
+#elif SHRT_MAX == 2147483647
+# define ffi_type_ushort       ffi_type_uint32
+# define ffi_type_sshort       ffi_type_sint32
+#else
+ #error "short size not supported"
+#endif
+
+#if INT_MAX == 32767
+# define ffi_type_uint         ffi_type_uint16
+# define ffi_type_sint         ffi_type_sint16
+#elif INT_MAX == 2147483647
+# define ffi_type_uint         ffi_type_uint32
+# define ffi_type_sint         ffi_type_sint32
+#elif INT_MAX == 9223372036854775807
+# define ffi_type_uint         ffi_type_uint64
+# define ffi_type_sint         ffi_type_sint64
+#else
+ #error "int size not supported"
+#endif
+
+#define ffi_type_ulong         ffi_type_uint64
+#define ffi_type_slong         ffi_type_sint64
+#if LONG_MAX == 2147483647
+# if FFI_LONG_LONG_MAX != 9223372036854775807
+  #error "no 64-bit data type supported"
+# endif
+#elif LONG_MAX != 9223372036854775807
+ #error "long size not supported"
+#endif
+
+/* The closure code assumes that this works on pointers, i.e. a size_t	*/
+/* can hold a pointer.							*/
+
+typedef struct _ffi_type
+{
+  size_t size;
+  unsigned short alignment;
+  unsigned short type;
+  /*@null@*/ struct _ffi_type **elements;
+} ffi_type;
+
+/* These are defined in types.c */
+extern ffi_type ffi_type_void;
+extern ffi_type ffi_type_uint8;
+extern ffi_type ffi_type_sint8;
+extern ffi_type ffi_type_uint16;
+extern ffi_type ffi_type_sint16;
+extern ffi_type ffi_type_uint32;
+extern ffi_type ffi_type_sint32;
+extern ffi_type ffi_type_uint64;
+extern ffi_type ffi_type_sint64;
+extern ffi_type ffi_type_float;
+extern ffi_type ffi_type_double;
+extern ffi_type ffi_type_longdouble;
+extern ffi_type ffi_type_pointer;
+
+
+typedef enum {
+  FFI_OK = 0,
+  FFI_BAD_TYPEDEF,
+  FFI_BAD_ABI 
+} ffi_status;
+
+typedef unsigned FFI_TYPE;
+
+typedef struct {
+  ffi_abi abi;
+  unsigned nargs;
+  /*@dependent@*/ ffi_type **arg_types;
+  /*@dependent@*/ ffi_type *rtype;
+  unsigned bytes;
+  unsigned flags;
+#ifdef FFI_EXTRA_CIF_FIELDS
+  FFI_EXTRA_CIF_FIELDS;
+#endif
+} ffi_cif;
+
+/* ---- Definitions for the raw API -------------------------------------- */
+
+#ifndef FFI_SIZEOF_ARG
+# if LONG_MAX == 2147483647
+#  define FFI_SIZEOF_ARG        4
+# elif LONG_MAX == 9223372036854775807
+#  define FFI_SIZEOF_ARG        8
+# endif
+#endif
+
+typedef union {
+  ffi_sarg  sint;
+  ffi_arg   uint;
+  float	    flt;
+  char      data[FFI_SIZEOF_ARG];
+  void*     ptr;
+} ffi_raw;
+
+void ffi_raw_call (/*@dependent@*/ ffi_cif *cif, 
+		   void (*fn)(), 
+		   /*@out@*/ void *rvalue, 
+		   /*@dependent@*/ ffi_raw *avalue);
+
+void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
+void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
+size_t ffi_raw_size (ffi_cif *cif);
+
+/* This is analogous to the raw API, except it uses Java parameter	*/
+/* packing, even on 64-bit machines.  I.e. on 64-bit machines		*/
+/* longs and doubles are followed by an empty 64-bit word.		*/
+
+void ffi_java_raw_call (/*@dependent@*/ ffi_cif *cif, 
+		        void (*fn)(), 
+		        /*@out@*/ void *rvalue, 
+		        /*@dependent@*/ ffi_raw *avalue);
+
+void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
+void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
+size_t ffi_java_raw_size (ffi_cif *cif);
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#if FFI_CLOSURES
+
+typedef struct {
+  char tramp[FFI_TRAMPOLINE_SIZE];
+  ffi_cif   *cif;
+  void     (*fun)(ffi_cif*,void*,void**,void*);
+  void      *user_data;
+} ffi_closure;
+
+ffi_status
+ffi_prep_closure (ffi_closure*,
+		  ffi_cif *,
+		  void (*fun)(ffi_cif*,void*,void**,void*),
+		  void *user_data);
+
+typedef struct {
+  char tramp[FFI_TRAMPOLINE_SIZE];
+
+  ffi_cif   *cif;
+
+#if !FFI_NATIVE_RAW_API
+
+  /* if this is enabled, then a raw closure has the same layout 
+     as a regular closure.  We use this to install an intermediate 
+     handler to do the transaltion, void** -> ffi_raw*. */
+
+  void     (*translate_args)(ffi_cif*,void*,void**,void*);
+  void      *this_closure;
+
+#endif
+
+  void     (*fun)(ffi_cif*,void*,ffi_raw*,void*);
+  void      *user_data;
+
+} ffi_raw_closure;
+
+ffi_status
+ffi_prep_raw_closure (ffi_raw_closure*,
+		      ffi_cif *cif,
+		      void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
+		      void *user_data);
+
+ffi_status
+ffi_prep_java_raw_closure (ffi_raw_closure*,
+		           ffi_cif *cif,
+		           void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
+		           void *user_data);
+
+#endif /* FFI_CLOSURES */
+
+/* ---- Public interface definition -------------------------------------- */
+
+ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif, 
+			ffi_abi abi,
+			unsigned int nargs, 
+			/*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type *rtype, 
+			/*@dependent@*/ ffi_type **atypes);
+
+/* Return type changed from void for ctypes */
+int ffi_call(/*@dependent@*/ ffi_cif *cif, 
+	      void (*fn)(), 
+	      /*@out@*/ void *rvalue, 
+	      /*@dependent@*/ void **avalue);
+
+/* Useful for eliminating compiler warnings */
+#define FFI_FN(f) ((void (*)())f)
+
+/* ---- Definitions shared with assembly code ---------------------------- */
+
+#endif
+
+/* If these change, update src/mips/ffitarget.h. */
+#define FFI_TYPE_VOID       0    
+#define FFI_TYPE_INT        1
+#define FFI_TYPE_FLOAT      2    
+#define FFI_TYPE_DOUBLE     3
+#if 0 /*@HAVE_LONG_DOUBLE@*/
+#define FFI_TYPE_LONGDOUBLE 4
+#else
+#define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE
+#endif
+#define FFI_TYPE_UINT8      5   
+#define FFI_TYPE_SINT8      6
+#define FFI_TYPE_UINT16     7 
+#define FFI_TYPE_SINT16     8
+#define FFI_TYPE_UINT32     9
+#define FFI_TYPE_SINT32     10
+#define FFI_TYPE_UINT64     11
+#define FFI_TYPE_SINT64     12
+#define FFI_TYPE_STRUCT     13
+#define FFI_TYPE_POINTER    14
+
+/* This should always refer to the last type code (for sanity checks) */
+#define FFI_TYPE_LAST       FFI_TYPE_POINTER
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+

Added: vendor/Python/current/Modules/_ctypes/libffi_arm_wince/ffi_common.h
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi_arm_wince/ffi_common.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi_arm_wince/ffi_common.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,111 @@
+/* -----------------------------------------------------------------------
+   ffi_common.h - Copyright (c) 1996  Red Hat, Inc.
+
+   Common internal definitions and macros. Only necessary for building
+   libffi.
+   ----------------------------------------------------------------------- */
+
+#ifndef FFI_COMMON_H
+#define FFI_COMMON_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <fficonfig.h>
+
+/* Do not move this. Some versions of AIX are very picky about where
+   this is positioned. */
+#ifdef __GNUC__
+# define alloca __builtin_alloca
+#else
+# if HAVE_ALLOCA_H
+#  include <alloca.h>
+# else
+#  ifdef _AIX
+ #pragma alloca
+#  else
+#   ifndef alloca /* predefined by HP cc +Olibcalls */
+char *alloca ();
+#   endif
+#  endif
+# endif
+#endif
+
+/* Check for the existence of memcpy. */
+#if STDC_HEADERS
+# include <string.h>
+#else
+# ifndef HAVE_MEMCPY
+#  define memcpy(d, s, n) bcopy ((s), (d), (n))
+# endif
+#endif
+
+#if defined(FFI_DEBUG) 
+#include <stdio.h>
+#endif
+
+#ifdef FFI_DEBUG
+/*@exits@*/ void ffi_assert(/*@temp@*/ char *expr, /*@temp@*/ char *file, int line);
+void ffi_stop_here(void);
+void ffi_type_test(/*@temp@*/ /*@out@*/ ffi_type *a, /*@temp@*/ char *file, int line);
+
+#define FFI_ASSERT(x) ((x) ? (void)0 : ffi_assert(#x, __FILE__,__LINE__))
+#define FFI_ASSERT_AT(x, f, l) ((x) ? 0 : ffi_assert(#x, (f), (l)))
+#define FFI_ASSERT_VALID_TYPE(x) ffi_type_test (x, __FILE__, __LINE__)
+#else
+#define FFI_ASSERT(x) 
+#define FFI_ASSERT_AT(x, f, l)
+#define FFI_ASSERT_VALID_TYPE(x)
+#endif
+
+#define ALIGN(v, a)  (((((size_t) (v))-1) | ((a)-1))+1)
+
+/* Perform machine dependent cif processing */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif);
+
+/* Extended cif, used in callback from assembly routine */
+typedef struct
+{
+  /*@dependent@*/ ffi_cif *cif;
+  /*@dependent@*/ void *rvalue;
+  /*@dependent@*/ void **avalue;
+} extended_cif;
+
+/* Terse sized type definitions.  */
+#if defined(__GNUC__)
+
+typedef unsigned int UINT8  __attribute__((__mode__(__QI__)));
+typedef signed int   SINT8  __attribute__((__mode__(__QI__)));
+typedef unsigned int UINT16 __attribute__((__mode__(__HI__)));
+typedef signed int   SINT16 __attribute__((__mode__(__HI__)));
+typedef unsigned int UINT32 __attribute__((__mode__(__SI__)));
+typedef signed int   SINT32 __attribute__((__mode__(__SI__)));
+typedef unsigned int UINT64 __attribute__((__mode__(__DI__)));
+typedef signed int   SINT64 __attribute__((__mode__(__DI__)));
+
+#elif defined(_MSC_VER)
+
+typedef unsigned __int8  UINT8;
+typedef signed __int8    SINT8;
+typedef unsigned __int16 UINT16;
+typedef signed __int16   SINT16;
+typedef unsigned __int32 UINT32;
+typedef signed __int32   SINT32;
+typedef unsigned __int64 UINT64;
+typedef signed __int64   SINT64;
+
+#else
+#error "Need typedefs here"
+#endif
+
+typedef float FLOAT32;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+

Added: vendor/Python/current/Modules/_ctypes/libffi_arm_wince/fficonfig.h
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi_arm_wince/fficonfig.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi_arm_wince/fficonfig.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,152 @@
+/* fficonfig.h created manually for Windows CE on ARM */
+/* fficonfig.h.in.  Generated from configure.ac by autoheader.  */
+
+/* 1234 = LIL_ENDIAN, 4321 = BIGENDIAN */
+#define BYTEORDER 1234
+
+/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
+   systems. This function is required for `alloca.c' support on those systems.
+   */
+/* #undef CRAY_STACKSEG_END */
+
+/* Define to 1 if using `alloca.c'. */
+/* #undef C_ALLOCA */
+
+/* Define to the flags needed for the .section .eh_frame directive. */
+/* #undef EH_FRAME_FLAGS */
+
+/* Define this if you want extra debugging. */
+#ifdef DEBUG  /* Defined by the project settings for Debug builds */
+#define FFI_DEBUG
+#else
+#undef FFI_DEBUG
+#endif
+
+/* Define this is you do not want support for the raw API. */
+/* #undef FFI_NO_RAW_API */
+
+/* Define this is you do not want support for aggregate types. */
+/* #undef FFI_NO_STRUCTS */
+
+/* Define to 1 if you have `alloca', as a function or macro. */
+#define HAVE_ALLOCA 1
+
+/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
+   */
+/* #undef HAVE_ALLOCA_H */
+
+/* Define if your assembler supports .register. */
+/* #undef HAVE_AS_REGISTER_PSEUDO_OP */
+
+/* Define if your assembler and linker support unaligned PC relative relocs.
+   */
+/* #undef HAVE_AS_SPARC_UA_PCREL */
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+/* #undef HAVE_INTTYPES_H */
+
+/* Define if you have the long double type and it is bigger than a double */
+/* This differs from the MSVC build, but even there it should not be defined */
+/* #undef HAVE_LONG_DOUBLE */
+
+/* Define to 1 if you have the `memcpy' function. */
+#define HAVE_MEMCPY 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+/* WinCE has this but I don't think we need to use it */
+/* #undef HAVE_MEMORY_H */
+
+/* Define to 1 if you have the `mmap' function. */
+/* #undef HAVE_MMAP */
+
+/* Define if mmap with MAP_ANON(YMOUS) works. */
+/* #undef HAVE_MMAP_ANON */
+
+/* Define if mmap of /dev/zero works. */
+/* #undef HAVE_MMAP_DEV_ZERO */
+
+/* Define if read-only mmap of a plain file works. */
+/* #undef HAVE_MMAP_FILE */
+
+/* Define if .eh_frame sections should be read-only. */
+/* #undef HAVE_RO_EH_FRAME */
+
+/* Define to 1 if you have the <stdint.h> header file. */
+/* #undef HAVE_STDINT_H */
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+/* #undef HAVE_STRINGS_H */
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the <sys/mman.h> header file. */
+/* #undef HAVE_SYS_MMAN_H */
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+/* #undef HAVE_SYS_STAT_H */
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+/* #undef HAVE_SYS_TYPES_H */
+
+/* Define to 1 if you have the <unistd.h> header file. */
+/* #undef HAVE_UNISTD_H */
+
+/* Define if the host machine stores words of multi-word integers in
+   big-endian order. */
+/* #undef HOST_WORDS_BIG_ENDIAN */
+
+/* Define to 1 if your C compiler doesn't accept -c and -o together. */
+/* #undef NO_MINUS_C_MINUS_O */
+
+/* Name of package */
+/* #undef PACKAGE */
+
+/* Define to the address where bug reports for this package should be sent. */
+/* #undef PACKAGE_BUGREPORT */
+
+/* Define to the full name of this package. */
+/* #undef PACKAGE_NAME */
+
+/* Define to the full name and version of this package. */
+/* #undef PACKAGE_STRING */
+
+/* Define to the one symbol short name of this package. */
+/* #undef PACKAGE_TARNAME */
+
+/* Define to the version of this package. */
+/* #undef PACKAGE_VERSION */
+
+/* The number of bytes in type double */
+#define SIZEOF_DOUBLE 8
+
+/* The number of bytes in type long double */
+#define SIZEOF_LONG_DOUBLE 8
+
+/* If using the C implementation of alloca, define if you know the
+   direction of stack growth for your system; otherwise it will be
+   automatically deduced at run-time.
+	STACK_DIRECTION > 0 => grows toward higher addresses
+	STACK_DIRECTION < 0 => grows toward lower addresses
+	STACK_DIRECTION = 0 => direction of growth unknown */
+/* #undef STACK_DIRECTION */
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define this if you are using Purify and want to suppress spurious messages.
+   */
+/* #undef USING_PURIFY */
+
+/* Version number of package */
+/* #undef VERSION */
+
+/* whether byteorder is bigendian */
+/* #undef WORDS_BIGENDIAN */
+
+#define alloca _alloca
+
+#define abort() exit(999)

Added: vendor/Python/current/Modules/_ctypes/libffi_arm_wince/ffitarget.h
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi_arm_wince/ffitarget.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi_arm_wince/ffitarget.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,49 @@
+/* -----------------------------------------------------------------*-C-*-
+   ffitarget.h - Copyright (c) 1996-2003  Red Hat, Inc.
+   Target configuration macros for ARM.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+
+   ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+#ifndef LIBFFI_ASM
+typedef unsigned long          ffi_arg;
+typedef signed long            ffi_sarg;
+
+typedef enum ffi_abi {
+  FFI_FIRST_ABI = 0,
+  FFI_SYSV,
+  FFI_DEFAULT_ABI = FFI_SYSV,
+  FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
+} ffi_abi;
+#endif
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#define FFI_CLOSURES 1
+#define FFI_TRAMPOLINE_SIZE 12
+
+#define FFI_NATIVE_RAW_API 0
+
+#endif
+

Added: vendor/Python/current/Modules/_ctypes/libffi_arm_wince/prep_cif.c
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi_arm_wince/prep_cif.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi_arm_wince/prep_cif.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,175 @@
+/* -----------------------------------------------------------------------
+   prep_cif.c - Copyright (c) 1996, 1998  Red Hat, Inc.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+#include <stdlib.h>
+
+
+/* Round up to FFI_SIZEOF_ARG. */
+
+#define STACK_ARG_SIZE(x) ALIGN(x, FFI_SIZEOF_ARG)
+
+/* Perform machine independent initialization of aggregate type
+   specifications. */
+
+static ffi_status initialize_aggregate(/*@out@*/ ffi_type *arg)
+{
+  ffi_type **ptr; 
+
+  FFI_ASSERT(arg != NULL);
+
+  /*@-usedef@*/
+
+  FFI_ASSERT(arg->elements != NULL);
+  FFI_ASSERT(arg->size == 0);
+  FFI_ASSERT(arg->alignment == 0);
+
+  ptr = &(arg->elements[0]);
+
+  while ((*ptr) != NULL)
+    {
+      if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK))
+	return FFI_BAD_TYPEDEF;
+      
+      /* Perform a sanity check on the argument type */
+      FFI_ASSERT_VALID_TYPE(*ptr);
+
+      arg->size = ALIGN(arg->size, (*ptr)->alignment);
+      arg->size += (*ptr)->size;
+
+      arg->alignment = (arg->alignment > (*ptr)->alignment) ? 
+	arg->alignment : (*ptr)->alignment;
+
+      ptr++;
+    }
+
+  /* Structure size includes tail padding.  This is important for
+     structures that fit in one register on ABIs like the PowerPC64
+     Linux ABI that right justify small structs in a register.
+     It's also needed for nested structure layout, for example
+     struct A { long a; char b; }; struct B { struct A x; char y; };
+     should find y at an offset of 2*sizeof(long) and result in a
+     total size of 3*sizeof(long).  */
+  arg->size = ALIGN (arg->size, arg->alignment);
+
+  if (arg->size == 0)
+    return FFI_BAD_TYPEDEF;
+  else
+    return FFI_OK;
+
+  /*@=usedef@*/
+}
+
+/* Perform machine independent ffi_cif preparation, then call
+   machine dependent routine. */
+
+ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif, 
+			ffi_abi abi, unsigned int nargs, 
+			/*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type *rtype, 
+			/*@dependent@*/ ffi_type **atypes)
+{
+  unsigned bytes = 0;
+  unsigned int i;
+  ffi_type **ptr;
+
+  FFI_ASSERT(cif != NULL);
+  FFI_ASSERT((abi > FFI_FIRST_ABI) && (abi <= FFI_DEFAULT_ABI));
+
+  cif->abi = abi;
+  cif->arg_types = atypes;
+  cif->nargs = nargs;
+  cif->rtype = rtype;
+
+  cif->flags = 0;
+
+  /* Initialize the return type if necessary */
+  /*@-usedef@*/
+  if ((cif->rtype->size == 0) && (initialize_aggregate(cif->rtype) != FFI_OK))
+    return FFI_BAD_TYPEDEF;
+  /*@=usedef@*/
+
+  /* Perform a sanity check on the return type */
+  FFI_ASSERT_VALID_TYPE(cif->rtype);
+
+  /* x86-64 and s390 stack space allocation is handled in prep_machdep.  */
+#if !defined M68K && !defined __x86_64__ && !defined S390
+  /* Make space for the return structure pointer */
+  if (cif->rtype->type == FFI_TYPE_STRUCT
+      /* MSVC returns small structures in registers.  But we have a different
+      workaround: pretend int32 or int64 return type, and converting to
+      structure afterwards. */
+#ifdef SPARC
+      && (cif->abi != FFI_V9 || cif->rtype->size > 32)
+#endif
+      )
+    bytes = STACK_ARG_SIZE(sizeof(void*));
+#endif
+
+  for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
+    {
+
+      /* Initialize any uninitialized aggregate type definitions */
+      if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK))
+	return FFI_BAD_TYPEDEF;
+
+      /* Perform a sanity check on the argument type, do this 
+	 check after the initialization.  */
+      FFI_ASSERT_VALID_TYPE(*ptr);
+
+#if !defined __x86_64__ && !defined S390
+#ifdef SPARC
+      if (((*ptr)->type == FFI_TYPE_STRUCT
+	   && ((*ptr)->size > 16 || cif->abi != FFI_V9))
+	  || ((*ptr)->type == FFI_TYPE_LONGDOUBLE
+	      && cif->abi != FFI_V9))
+	bytes += sizeof(void*);
+      else
+#endif
+	{
+#ifndef _MSC_VER
+		/* Don't know if this is a libffi bug or not.  At least on
+		   Windows with MSVC, function call parameters are *not*
+		   aligned in the same way as structure fields are, they are
+		   only aligned in integer boundaries.
+
+		   This doesn't do any harm for cdecl functions and closures,
+		   since the caller cleans up the stack, but it is wrong for
+		   stdcall functions where the callee cleans.
+		*/
+
+	  /* Add any padding if necessary */
+	  if (((*ptr)->alignment - 1) & bytes)
+	    bytes = ALIGN(bytes, (*ptr)->alignment);
+	  
+#endif
+	  bytes += STACK_ARG_SIZE((*ptr)->size);
+	}
+#endif
+    }
+
+  cif->bytes = bytes;
+
+  /* Perform machine dependent cif processing */
+  return ffi_prep_cif_machdep(cif);
+}

Added: vendor/Python/current/Modules/_ctypes/libffi_arm_wince/sysv.asm
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi_arm_wince/sysv.asm	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi_arm_wince/sysv.asm	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,228 @@
+; -----------------------------------------------------------------------
+;  sysv.S - Copyright (c) 1998 Red Hat, Inc.
+;  
+;  ARM Foreign Function Interface 
+;
+;  Permission is hereby granted, free of charge, to any person obtaining
+;  a copy of this software and associated documentation files (the
+;  ``Software''), to deal in the Software without restriction, including
+;  without limitation the rights to use, copy, modify, merge, publish,
+;  distribute, sublicense, and/or sell copies of the Software, and to
+;  permit persons to whom the Software is furnished to do so, subject to
+;  the following conditions:
+;
+;  The above copyright notice and this permission notice shall be included
+;  in all copies or substantial portions of the Software.
+;
+;  THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+;  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+;  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+;  IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+;  OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+;  ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+;  OTHER DEALINGS IN THE SOFTWARE.
+;  ----------------------------------------------------------------------- */
+
+;#define LIBFFI_ASM     
+;#include <fficonfig.h>
+;#include <ffi.h>
+;#ifdef HAVE_MACHINE_ASM_H
+;#include <machine/asm.h>
+;#else
+;#ifdef __USER_LABEL_PREFIX__
+;#define CONCAT1(a, b) CONCAT2(a, b)
+;#define CONCAT2(a, b) a ## b
+
+;/* Use the right prefix for global labels.  */
+;#define CNAME(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
+;#else
+;#define CNAME(x) x
+;#endif
+;#define ENTRY(x) .globl CNAME(x); .type CNAME(x),%function; CNAME(x):
+;#endif
+
+
+FFI_TYPE_VOID       EQU 0
+FFI_TYPE_INT        EQU 1
+FFI_TYPE_FLOAT      EQU 2
+FFI_TYPE_DOUBLE     EQU 3
+;FFI_TYPE_LONGDOUBLE EQU 4
+FFI_TYPE_UINT8      EQU 5
+FFI_TYPE_SINT8      EQU 6
+FFI_TYPE_UINT16     EQU 7
+FFI_TYPE_SINT16     EQU 8
+FFI_TYPE_UINT32     EQU 9
+FFI_TYPE_SINT32     EQU 10
+FFI_TYPE_UINT64     EQU 11
+FFI_TYPE_SINT64     EQU 12
+FFI_TYPE_STRUCT     EQU 13
+FFI_TYPE_POINTER    EQU 14
+
+; WinCE always uses software floating point (I think)
+__SOFTFP__ EQU {TRUE}
+
+
+    AREA |.text|, CODE, ARM     ; .text
+
+
+    ; a1:   ffi_prep_args
+    ; a2:   &ecif
+    ; a3:   cif->bytes
+    ; a4:   fig->flags
+    ; sp+0: ecif.rvalue
+    ; sp+4: fn
+
+    ; This assumes we are using gas.
+;ENTRY(ffi_call_SYSV)
+
+    EXPORT |ffi_call_SYSV|
+
+|ffi_call_SYSV| PROC
+
+    ; Save registers
+    stmfd sp!, {a1-a4, fp, lr}
+    mov   fp, sp
+
+    ; Make room for all of the new args.
+    sub   sp, fp, a3
+
+    ; Place all of the ffi_prep_args in position
+    mov   ip, a1
+    mov   a1, sp
+    ;     a2 already set
+
+    ; And call
+    mov   lr, pc
+    mov   pc, ip
+
+    ; move first 4 parameters in registers
+    ldr   a1, [sp, #0]
+    ldr   a2, [sp, #4]
+    ldr   a3, [sp, #8]
+    ldr   a4, [sp, #12]
+
+    ; and adjust stack
+    ldr   ip, [fp, #8]
+    cmp   ip, #16
+    movge ip, #16
+    add   sp, sp, ip
+
+    ; call function
+    mov   lr, pc
+    ldr   pc, [fp, #28]
+
+    ; Remove the space we pushed for the args
+    mov   sp, fp
+
+    ; Load a3 with the pointer to storage for the return value
+    ldr   a3, [sp, #24]
+
+    ; Load a4 with the return type code 
+    ldr   a4, [sp, #12]
+
+    ; If the return value pointer is NULL, assume no return value.
+    cmp   a3, #0
+    beq   call_epilogue
+
+; return INT
+    cmp   a4, #FFI_TYPE_INT
+    streq a1, [a3]
+    beq   call_epilogue
+
+; return FLOAT
+    cmp     a4, #FFI_TYPE_FLOAT
+    [ __SOFTFP__                    ;ifdef __SOFTFP__
+    streq   a1, [a3]
+    |                               ;else
+    stfeqs  f0, [a3]
+    ]                               ;endif
+    beq     call_epilogue
+
+; return DOUBLE or LONGDOUBLE
+    cmp     a4, #FFI_TYPE_DOUBLE
+    [ __SOFTFP__                    ;ifdef __SOFTFP__
+    stmeqia a3, {a1, a2}
+    |                               ;else
+    stfeqd  f0, [a3]
+    ]                               ;endif
+    beq     call_epilogue
+
+; return SINT64 or UINT64
+    cmp     a4, #FFI_TYPE_SINT64
+    stmeqia a3, {a1, a2}
+
+call_epilogue
+    ldmfd   sp!, {a1-a4, fp, pc}
+
+;.ffi_call_SYSV_end:
+    ;.size    CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV)
+    ENDP
+
+
+RESERVE_RETURN EQU 16
+
+    ; This function is called by the trampoline
+    ; It is NOT callable from C
+    ; ip = pointer to struct ffi_closure
+
+    IMPORT |ffi_closure_SYSV_inner|
+
+    EXPORT |ffi_closure_SYSV|
+|ffi_closure_SYSV| PROC
+
+    ; Store the argument registers on the stack
+    stmfd   sp!, {a1-a4}
+    ; Push the return address onto the stack
+    stmfd   sp!, {lr}
+
+    mov     a1, ip            ; first arg = address of ffi_closure
+    add     a2, sp, #4        ; second arg = sp+4 (points to saved a1)
+
+    ; Allocate space for a non-struct return value
+    sub     sp, sp, #RESERVE_RETURN
+    mov     a3, sp            ; third arg = return value address
+
+    ; static unsigned int
+    ; ffi_closure_SYSV_inner (ffi_closure *closure, char *in_args, void *rvalue)
+    bl      ffi_closure_SYSV_inner
+    ; a1 now contains the return type code 
+
+    ; At this point the return value is on the stack
+    ; Transfer it to the correct registers if necessary
+
+; return INT
+    cmp     a1, #FFI_TYPE_INT
+    ldreq   a1, [sp]
+    beq     closure_epilogue
+
+; return FLOAT
+    cmp     a1, #FFI_TYPE_FLOAT
+    [ __SOFTFP__                    ;ifdef __SOFTFP__
+    ldreq   a1, [sp]
+    |                               ;else
+    stfeqs  f0, [sp]
+    ]                               ;endif
+    beq     closure_epilogue
+
+; return DOUBLE or LONGDOUBLE
+    cmp     a1, #FFI_TYPE_DOUBLE
+    [ __SOFTFP__                    ;ifdef __SOFTFP__
+    ldmeqia sp, {a1, a2}
+    |                               ;else
+    stfeqd  f0, [sp]
+    ]                               ;endif
+    beq     closure_epilogue
+
+; return SINT64 or UINT64
+    cmp     a1, #FFI_TYPE_SINT64
+    ldmeqia sp, {a1, a2}
+
+closure_epilogue
+    add     sp, sp, #RESERVE_RETURN   ; remove return value buffer
+    ldmfd   sp!, {ip}         ; ip = pop return address
+    add     sp, sp, #16       ; remove saved argument registers {a1-a4} from the stack
+    mov     pc, ip            ; return
+
+    ENDP    ; ffi_closure_SYSV
+
+    END

Added: vendor/Python/current/Modules/_ctypes/libffi_msvc/LICENSE
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi_msvc/LICENSE	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi_msvc/LICENSE	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,20 @@
+libffi - Copyright (c) 1996-2003  Red Hat, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+``Software''), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.

Added: vendor/Python/current/Modules/_ctypes/libffi_msvc/README
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi_msvc/README	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi_msvc/README	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,500 @@
+This directory contains the libffi package, which is not part of GCC but
+shipped with GCC as convenience.
+
+Status
+======
+
+libffi-2.00 has not been released yet! This is a development snapshot!
+
+libffi-1.20 was released on October 5, 1998. Check the libffi web
+page for updates: <URL:http://sources.redhat.com/libffi/>.
+
+
+What is libffi?
+===============
+
+Compilers for high level languages generate code that follow certain
+conventions. These conventions are necessary, in part, for separate
+compilation to work. One such convention is the "calling
+convention". The "calling convention" is essentially a set of
+assumptions made by the compiler about where function arguments will
+be found on entry to a function. A "calling convention" also specifies
+where the return value for a function is found.
+
+Some programs may not know at the time of compilation what arguments
+are to be passed to a function. For instance, an interpreter may be
+told at run-time about the number and types of arguments used to call
+a given function. Libffi can be used in such programs to provide a
+bridge from the interpreter program to compiled code.
+
+The libffi library provides a portable, high level programming
+interface to various calling conventions. This allows a programmer to
+call any function specified by a call interface description at run
+time.  
+
+Ffi stands for Foreign Function Interface. A foreign function
+interface is the popular name for the interface that allows code
+written in one language to call code written in another language. The
+libffi library really only provides the lowest, machine dependent
+layer of a fully featured foreign function interface. A layer must
+exist above libffi that handles type conversions for values passed
+between the two languages.
+
+
+Supported Platforms and Prerequisites
+=====================================
+
+Libffi has been ported to:
+
+	SunOS 4.1.3 & Solaris 2.x (SPARC-V8, SPARC-V9)
+
+	Irix 5.3 & 6.2 (System V/o32 & n32)
+
+	Intel x86 - Linux (System V ABI)
+
+	Alpha - Linux and OSF/1
+
+	m68k - Linux (System V ABI)
+
+	PowerPC - Linux (System V ABI, Darwin, AIX)
+
+	ARM - Linux (System V ABI)
+
+Libffi has been tested with the egcs 1.0.2 gcc compiler. Chances are
+that other versions will work.  Libffi has also been built and tested
+with the SGI compiler tools.
+
+On PowerPC, the tests failed (see the note below).
+
+You must use GNU make to build libffi. SGI's make will not work.
+Sun's probably won't either.
+	
+If you port libffi to another platform, please let me know! I assume
+that some will be easy (x86 NetBSD), and others will be more difficult
+(HP).
+
+
+Installing libffi
+=================
+
+[Note: before actually performing any of these installation steps,
+ you may wish to read the "Platform Specific Notes" below.]
+
+First you must configure the distribution for your particular
+system. Go to the directory you wish to build libffi in and run the
+"configure" program found in the root directory of the libffi source
+distribution.
+
+You may want to tell configure where to install the libffi library and
+header files. To do that, use the --prefix configure switch.  Libffi
+will install under /usr/local by default. 
+
+If you want to enable extra run-time debugging checks use the the
+--enable-debug configure switch. This is useful when your program dies
+mysteriously while using libffi. 
+
+Another useful configure switch is --enable-purify-safety. Using this
+will add some extra code which will suppress certain warnings when you
+are using Purify with libffi. Only use this switch when using 
+Purify, as it will slow down the library.
+
+Configure has many other options. Use "configure --help" to see them all.
+
+Once configure has finished, type "make". Note that you must be using
+GNU make. SGI's make will not work.  Sun's probably won't either.
+You can ftp GNU make from prep.ai.mit.edu:/pub/gnu.
+
+To ensure that libffi is working as advertised, type "make test".
+
+To install the library and header files, type "make install".
+
+
+Using libffi
+============
+
+	The Basics
+	----------
+
+Libffi assumes that you have a pointer to the function you wish to
+call and that you know the number and types of arguments to pass it,
+as well as the return type of the function.
+
+The first thing you must do is create an ffi_cif object that matches
+the signature of the function you wish to call. The cif in ffi_cif
+stands for Call InterFace. To prepare a call interface object, use the
+following function:
+
+ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi,
+			unsigned int nargs, 
+			ffi_type *rtype, ffi_type **atypes);
+
+	CIF is a pointer to the call interface object you wish
+		to initialize.
+
+	ABI is an enum that specifies the calling convention 
+		to use for the call. FFI_DEFAULT_ABI defaults
+		to the system's native calling convention. Other
+		ABI's may be used with care. They are system
+		specific.
+
+	NARGS is the number of arguments this function accepts.	
+		libffi does not yet support vararg functions.
+
+	RTYPE is a pointer to an ffi_type structure that represents
+		the return type of the function. Ffi_type objects
+		describe the types of values. libffi provides
+		ffi_type objects for many of the native C types:
+		signed int, unsigned int, signed char, unsigned char,
+		etc. There is also a pointer ffi_type object and
+		a void ffi_type. Use &ffi_type_void for functions that 
+		don't return values.
+
+	ATYPES is a vector of ffi_type pointers. ARGS must be NARGS long.
+		If NARGS is 0, this is ignored.
+
+
+ffi_prep_cif will return a status code that you are responsible 
+for checking. It will be one of the following:
+
+	FFI_OK - All is good.
+
+	FFI_BAD_TYPEDEF - One of the ffi_type objects that ffi_prep_cif
+		came across is bad.
+
+
+Before making the call, the VALUES vector should be initialized 
+with pointers to the appropriate argument values.
+
+To call the the function using the initialized ffi_cif, use the
+ffi_call function:
+
+void ffi_call(ffi_cif *cif, void *fn, void *rvalue, void **avalues);
+
+	CIF is a pointer to the ffi_cif initialized specifically
+		for this function.
+
+	FN is a pointer to the function you want to call.
+
+	RVALUE is a pointer to a chunk of memory that is to hold the
+		result of the function call. Currently, it must be
+		at least one word in size (except for the n32 version
+		under Irix 6.x, which must be a pointer to an 8 byte 
+		aligned value (a long long). It must also be at least 
+		word aligned (depending on the return type, and the
+		system's alignment requirements). If RTYPE is 
+		&ffi_type_void, this is ignored. If RVALUE is NULL, 
+		the return value is discarded.
+
+	AVALUES is a vector of void* that point to the memory locations
+		holding the argument values for a call.
+		If NARGS is 0, this is ignored.
+
+
+If you are expecting a return value from FN it will have been stored
+at RVALUE.
+
+
+
+	An Example
+	----------
+
+Here is a trivial example that calls puts() a few times.
+
+    #include <stdio.h>
+    #include <ffi.h>
+    
+    int main()
+    {
+      ffi_cif cif;
+      ffi_type *args[1];
+      void *values[1];
+      char *s;
+      int rc;
+      
+      /* Initialize the argument info vectors */    
+      args[0] = &ffi_type_uint;
+      values[0] = &s;
+      
+      /* Initialize the cif */
+      if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 
+    		       &ffi_type_uint, args) == FFI_OK)
+        {
+          s = "Hello World!";
+          ffi_call(&cif, puts, &rc, values);
+          /* rc now holds the result of the call to puts */
+          
+          /* values holds a pointer to the function's arg, so to 
+	     call puts() again all we need to do is change the 
+             value of s */
+          s = "This is cool!";
+          ffi_call(&cif, puts, &rc, values);
+        }
+      
+      return 0;
+    }
+
+
+
+	Aggregate Types
+	---------------
+
+Although libffi has no special support for unions or bit-fields, it is
+perfectly happy passing structures back and forth. You must first
+describe the structure to libffi by creating a new ffi_type object
+for it. Here is the definition of ffi_type:
+
+    typedef struct _ffi_type
+    {
+      unsigned size;
+      short alignment;
+      short type;
+      struct _ffi_type **elements;
+    } ffi_type;
+    
+All structures must have type set to FFI_TYPE_STRUCT.  You may set
+size and alignment to 0. These will be calculated and reset to the
+appropriate values by ffi_prep_cif().
+
+elements is a NULL terminated array of pointers to ffi_type objects
+that describe the type of the structure elements. These may, in turn,
+be structure elements.
+
+The following example initializes a ffi_type object representing the
+tm struct from Linux's time.h:
+
+				    struct tm {
+					int tm_sec;
+					int tm_min;
+					int tm_hour;
+					int tm_mday;
+					int tm_mon;
+					int tm_year;
+					int tm_wday;
+					int tm_yday;
+					int tm_isdst;
+					/* Those are for future use. */
+					long int __tm_gmtoff__;
+					__const char *__tm_zone__;
+				    };
+
+    {
+      ffi_type tm_type;
+      ffi_type *tm_type_elements[12];
+      int i;
+
+      tm_type.size = tm_type.alignment = 0;
+      tm_type.elements = &tm_type_elements;
+    
+      for (i = 0; i < 9; i++)
+          tm_type_elements[i] = &ffi_type_sint;
+
+      tm_type_elements[9] = &ffi_type_slong;
+      tm_type_elements[10] = &ffi_type_pointer;
+      tm_type_elements[11] = NULL;
+
+      /* tm_type can now be used to represent tm argument types and
+	 return types for ffi_prep_cif() */
+    }
+
+
+
+Platform Specific Notes
+=======================
+
+	Intel x86
+	---------
+
+There are no known problems with the x86 port.
+
+	Sun SPARC - SunOS 4.1.3 & Solaris 2.x
+	-------------------------------------
+
+You must use GNU Make to build libffi on Sun platforms.
+
+	MIPS - Irix 5.3 & 6.x
+	---------------------
+
+Irix 6.2 and better supports three different calling conventions: o32,
+n32 and n64. Currently, libffi only supports both o32 and n32 under
+Irix 6.x, but only o32 under Irix 5.3. Libffi will automatically be
+configured for whichever calling convention it was built for.
+
+By default, the configure script will try to build libffi with the GNU
+development tools. To build libffi with the SGI development tools, set
+the environment variable CC to either "cc -32" or "cc -n32" before
+running configure under Irix 6.x (depending on whether you want an o32
+or n32 library), or just "cc" for Irix 5.3.
+
+With the n32 calling convention, when returning structures smaller
+than 16 bytes, be sure to provide an RVALUE that is 8 byte aligned.
+Here's one way of forcing this:
+
+	double struct_storage[2];
+	my_small_struct *s = (my_small_struct *) struct_storage;  
+	/* Use s for RVALUE */
+
+If you don't do this you are liable to get spurious bus errors. 
+
+"long long" values are not supported yet.
+
+You must use GNU Make to build libffi on SGI platforms.
+
+	ARM - System V ABI
+	------------------
+
+The ARM port was performed on a NetWinder running ARM Linux ELF
+(2.0.31) and gcc 2.8.1.
+
+
+
+	PowerPC System V ABI
+	--------------------
+
+There are two `System V ABI's which libffi implements for PowerPC.
+They differ only in how small structures are returned from functions.
+
+In the FFI_SYSV version, structures that are 8 bytes or smaller are
+returned in registers.  This is what GCC does when it is configured
+for solaris, and is what the System V ABI I have (dated September
+1995) says.
+
+In the FFI_GCC_SYSV version, all structures are returned the same way:
+by passing a pointer as the first argument to the function.  This is
+what GCC does when it is configured for linux or a generic sysv
+target.
+
+EGCS 1.0.1 (and probably other versions of EGCS/GCC) also has a
+inconsistency with the SysV ABI: When a procedure is called with many
+floating-point arguments, some of them get put on the stack.  They are
+all supposed to be stored in double-precision format, even if they are
+only single-precision, but EGCS stores single-precision arguments as
+single-precision anyway.  This causes one test to fail (the `many
+arguments' test).
+
+
+What's With The Crazy Comments?
+===============================
+
+You might notice a number of cryptic comments in the code, delimited
+by /*@ and @*/. These are annotations read by the program LCLint, a
+tool for statically checking C programs. You can read all about it at
+<http://larch-www.lcs.mit.edu:8001/larch/lclint/index.html>.
+
+
+History
+=======
+
+1.20 Oct-5-98
+	Raffaele Sena produces ARM port.
+
+1.19 Oct-5-98
+	Fixed x86 long double and long long return support.
+	m68k bug fixes from Andreas Schwab.
+	Patch for DU assembler compatibility for the Alpha from Richard
+	Henderson.
+
+1.18 Apr-17-98
+	Bug fixes and MIPS configuration changes.
+
+1.17 Feb-24-98
+	Bug fixes and m68k port from Andreas Schwab. PowerPC port from
+	Geoffrey Keating. Various bug x86, Sparc and MIPS bug fixes.
+
+1.16 Feb-11-98
+	Richard Henderson produces Alpha port.
+
+1.15 Dec-4-97
+	Fixed an n32 ABI bug. New libtool, auto* support.
+
+1.14 May-13-97
+	libtool is now used to generate shared and static libraries.
+	Fixed a minor portability problem reported by Russ McManus
+	<mcmanr at eq.gs.com>.
+
+1.13 Dec-2-96
+	Added --enable-purify-safety to keep Purify from complaining
+	about certain low level code.
+	Sparc fix for calling functions with < 6 args.
+	Linux x86 a.out fix.
+
+1.12 Nov-22-96
+	Added missing ffi_type_void, needed for supporting void return 
+	types. Fixed test case for non MIPS machines. Cygnus Support 
+	is now Cygnus Solutions. 
+
+1.11 Oct-30-96
+	Added notes about GNU make.
+
+1.10 Oct-29-96
+	Added configuration fix for non GNU compilers.
+
+1.09 Oct-29-96
+	Added --enable-debug configure switch. Clean-ups based on LCLint 
+	feedback. ffi_mips.h is always installed. Many configuration 
+	fixes. Fixed ffitest.c for sparc builds.
+
+1.08 Oct-15-96
+	Fixed n32 problem. Many clean-ups.
+
+1.07 Oct-14-96
+	Gordon Irlam rewrites v8.S again. Bug fixes.
+
+1.06 Oct-14-96
+	Gordon Irlam improved the sparc port. 
+
+1.05 Oct-14-96
+	Interface changes based on feedback.
+
+1.04 Oct-11-96
+	Sparc port complete (modulo struct passing bug).
+
+1.03 Oct-10-96
+	Passing struct args, and returning struct values works for
+	all architectures/calling conventions. Expanded tests.
+
+1.02 Oct-9-96
+	Added SGI n32 support. Fixed bugs in both o32 and Linux support.
+	Added "make test".
+
+1.01 Oct-8-96
+	Fixed float passing bug in mips version. Restructured some
+	of the code. Builds cleanly with SGI tools.
+
+1.00 Oct-7-96
+	First release. No public announcement.
+
+
+Authors & Credits
+=================
+
+libffi was written by Anthony Green <green at cygnus.com>.
+
+Portions of libffi were derived from Gianni Mariani's free gencall
+library for Silicon Graphics machines.
+
+The closure mechanism was designed and implemented by Kresten Krab
+Thorup.
+
+The Sparc port was derived from code contributed by the fine folks at
+Visible Decisions Inc <http://www.vdi.com>. Further enhancements were
+made by Gordon Irlam at Cygnus Solutions <http://www.cygnus.com>.
+
+The Alpha port was written by Richard Henderson at Cygnus Solutions.
+
+Andreas Schwab ported libffi to m68k Linux and provided a number of
+bug fixes.
+
+Geoffrey Keating ported libffi to the PowerPC.
+
+Raffaele Sena ported libffi to the ARM.
+
+Jesper Skov and Andrew Haley both did more than their fair share of
+stepping through the code and tracking down bugs.
+
+Thanks also to Tom Tromey for bug fixes and configuration help.
+
+Thanks to Jim Blandy, who provided some useful feedback on the libffi
+interface.
+
+If you have a problem, or have found a bug, please send a note to
+green at cygnus.com.

Added: vendor/Python/current/Modules/_ctypes/libffi_msvc/README.ctypes
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi_msvc/README.ctypes	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi_msvc/README.ctypes	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,7 @@
+The purpose is to hack the libffi sources so that they can be compiled
+with MSVC, and to extend them so that they have the features I need
+for ctypes.
+
+I retrieved the libffi sources from the gcc cvs repository on
+2004-01-27.  Then I did 'configure' in a 'build' subdirectory on a x86
+linux system, and copied the files I found useful.

Added: vendor/Python/current/Modules/_ctypes/libffi_msvc/ffi.c
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi_msvc/ffi.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi_msvc/ffi.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,394 @@
+/* -----------------------------------------------------------------------
+   ffi.c - Copyright (c) 1996, 1998, 1999, 2001  Red Hat, Inc.
+           Copyright (c) 2002  Ranjit Mathew
+           Copyright (c) 2002  Bo Thorsen
+           Copyright (c) 2002  Roger Sayle
+   
+   x86 Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+
+/* ffi_prep_args is called by the assembly routine once stack space
+   has been allocated for the function's arguments */
+
+/*@-exportheader@*/
+void ffi_prep_args(char *stack, extended_cif *ecif)
+/*@=exportheader@*/
+{
+  register unsigned int i;
+  register void **p_argv;
+  register char *argp;
+  register ffi_type **p_arg;
+
+  argp = stack;
+
+  if (ecif->cif->rtype->type == FFI_TYPE_STRUCT)
+    {
+      *(void **) argp = ecif->rvalue;
+      argp += 4;
+    }
+
+  p_argv = ecif->avalue;
+
+  for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
+       i != 0;
+       i--, p_arg++)
+    {
+      size_t z;
+
+      /* Align if necessary */
+      if ((sizeof(int) - 1) & (unsigned) argp)
+	argp = (char *) ALIGN(argp, sizeof(int));
+
+      z = (*p_arg)->size;
+      if (z < sizeof(int))
+	{
+	  z = sizeof(int);
+	  switch ((*p_arg)->type)
+	    {
+	    case FFI_TYPE_SINT8:
+	      *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
+	      break;
+
+	    case FFI_TYPE_UINT8:
+	      *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
+	      break;
+
+	    case FFI_TYPE_SINT16:
+	      *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
+	      break;
+
+	    case FFI_TYPE_UINT16:
+	      *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
+	      break;
+
+	    case FFI_TYPE_SINT32:
+	      *(signed int *) argp = (signed int)*(SINT32 *)(* p_argv);
+	      break;
+
+	    case FFI_TYPE_UINT32:
+	      *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+	      break;
+
+	    case FFI_TYPE_STRUCT:
+	      *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+	      break;
+
+	    default:
+	      FFI_ASSERT(0);
+	    }
+	}
+      else
+	{
+	  memcpy(argp, *p_argv, z);
+	}
+      p_argv++;
+      argp += z;
+    }
+  
+  return;
+}
+
+/* Perform machine dependent cif processing */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+{
+  /* Set the return type flag */
+  switch (cif->rtype->type)
+    {
+    case FFI_TYPE_VOID:
+    case FFI_TYPE_STRUCT:
+    case FFI_TYPE_SINT64:
+    case FFI_TYPE_FLOAT:
+    case FFI_TYPE_DOUBLE:
+    case FFI_TYPE_LONGDOUBLE:
+      cif->flags = (unsigned) cif->rtype->type;
+      break;
+
+    case FFI_TYPE_UINT64:
+      cif->flags = FFI_TYPE_SINT64;
+      break;
+
+    default:
+      cif->flags = FFI_TYPE_INT;
+      break;
+    }
+
+  return FFI_OK;
+}
+
+/*@-declundef@*/
+/*@-exportheader@*/
+extern int
+ffi_call_SYSV(void (*)(char *, extended_cif *), 
+	      /*@out@*/ extended_cif *, 
+	      unsigned, unsigned, 
+	      /*@out@*/ unsigned *, 
+	      void (*fn)());
+/*@=declundef@*/
+/*@=exportheader@*/
+
+/*@-declundef@*/
+/*@-exportheader@*/
+extern int
+ffi_call_STDCALL(void (*)(char *, extended_cif *),
+		 /*@out@*/ extended_cif *,
+		 unsigned, unsigned,
+		 /*@out@*/ unsigned *,
+		 void (*fn)());
+/*@=declundef@*/
+/*@=exportheader@*/
+
+int
+ffi_call(/*@dependent@*/ ffi_cif *cif, 
+	 void (*fn)(), 
+	 /*@out@*/ void *rvalue, 
+	 /*@dependent@*/ void **avalue)
+{
+  extended_cif ecif;
+
+  ecif.cif = cif;
+  ecif.avalue = avalue;
+  
+  /* If the return value is a struct and we don't have a return	*/
+  /* value address then we need to make one		        */
+
+  if ((rvalue == NULL) && 
+      (cif->rtype->type == FFI_TYPE_STRUCT))
+    {
+      /*@-sysunrecog@*/
+      ecif.rvalue = alloca(cif->rtype->size);
+      /*@=sysunrecog@*/
+    }
+  else
+    ecif.rvalue = rvalue;
+    
+  
+  switch (cif->abi) 
+    {
+    case FFI_SYSV:
+      /*@-usedef@*/
+      return ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, 
+			   cif->flags, ecif.rvalue, fn);
+      /*@=usedef@*/
+      break;
+
+    case FFI_STDCALL:
+      /*@-usedef@*/
+      return ffi_call_STDCALL(ffi_prep_args, &ecif, cif->bytes,
+			      cif->flags, ecif.rvalue, fn);
+      /*@=usedef@*/
+      break;
+
+    default:
+      FFI_ASSERT(0);
+      break;
+    }
+  return -1; /* theller: Hrm. */
+}
+
+
+/** private members **/
+
+static void ffi_prep_incoming_args_SYSV (char *stack, void **ret,
+					 void** args, ffi_cif* cif);
+/* This function is jumped to by the trampoline */
+
+static void __fastcall
+ffi_closure_SYSV (ffi_closure *closure, int *argp)
+{
+  // this is our return value storage
+  long double    res;
+
+  // our various things...
+  ffi_cif       *cif;
+  void         **arg_area;
+  unsigned short rtype;
+  void          *resp = (void*)&res;
+  void *args = &argp[1];
+
+  cif         = closure->cif;
+  arg_area    = (void**) alloca (cif->nargs * sizeof (void*));  
+
+  /* this call will initialize ARG_AREA, such that each
+   * element in that array points to the corresponding 
+   * value on the stack; and if the function returns
+   * a structure, it will re-set RESP to point to the
+   * structure return address.  */
+
+  ffi_prep_incoming_args_SYSV(args, (void**)&resp, arg_area, cif);
+  
+  (closure->fun) (cif, resp, arg_area, closure->user_data);
+
+  rtype = cif->flags;
+
+#ifdef _MSC_VER
+  /* now, do a generic return based on the value of rtype */
+  if (rtype == FFI_TYPE_INT)
+    {
+	    _asm mov eax, resp ;
+	    _asm mov eax, [eax] ;
+    }
+  else if (rtype == FFI_TYPE_FLOAT)
+    {
+	    _asm mov eax, resp ;
+	    _asm fld DWORD PTR [eax] ;
+//      asm ("flds (%0)" : : "r" (resp) : "st" );
+    }
+  else if (rtype == FFI_TYPE_DOUBLE)
+    {
+	    _asm mov eax, resp ;
+	    _asm fld QWORD PTR [eax] ;
+//      asm ("fldl (%0)" : : "r" (resp) : "st", "st(1)" );
+    }
+  else if (rtype == FFI_TYPE_LONGDOUBLE)
+    {
+//      asm ("fldt (%0)" : : "r" (resp) : "st", "st(1)" );
+    }
+  else if (rtype == FFI_TYPE_SINT64)
+    {
+	    _asm mov edx, resp ;
+	    _asm mov eax, [edx] ;
+	    _asm mov edx, [edx + 4] ;
+//      asm ("movl 0(%0),%%eax;"
+//	   "movl 4(%0),%%edx" 
+//	   : : "r"(resp)
+//	   : "eax", "edx");
+    }
+#else
+  /* now, do a generic return based on the value of rtype */
+  if (rtype == FFI_TYPE_INT)
+    {
+      asm ("movl (%0),%%eax" : : "r" (resp) : "eax");
+    }
+  else if (rtype == FFI_TYPE_FLOAT)
+    {
+      asm ("flds (%0)" : : "r" (resp) : "st" );
+    }
+  else if (rtype == FFI_TYPE_DOUBLE)
+    {
+      asm ("fldl (%0)" : : "r" (resp) : "st", "st(1)" );
+    }
+  else if (rtype == FFI_TYPE_LONGDOUBLE)
+    {
+      asm ("fldt (%0)" : : "r" (resp) : "st", "st(1)" );
+    }
+  else if (rtype == FFI_TYPE_SINT64)
+    {
+      asm ("movl 0(%0),%%eax;"
+	   "movl 4(%0),%%edx" 
+	   : : "r"(resp)
+	   : "eax", "edx");
+    }
+#endif
+}
+
+/*@-exportheader@*/
+static void 
+ffi_prep_incoming_args_SYSV(char *stack, void **rvalue,
+			    void **avalue, ffi_cif *cif)
+/*@=exportheader@*/
+{
+  register unsigned int i;
+  register void **p_argv;
+  register char *argp;
+  register ffi_type **p_arg;
+
+  argp = stack;
+
+  if ( cif->rtype->type == FFI_TYPE_STRUCT ) {
+    *rvalue = *(void **) argp;
+    argp += 4;
+  }
+
+  p_argv = avalue;
+
+  for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++)
+    {
+      size_t z;
+
+      /* Align if necessary */
+      if ((sizeof(int) - 1) & (unsigned) argp) {
+	argp = (char *) ALIGN(argp, sizeof(int));
+      }
+
+      z = (*p_arg)->size;
+
+      /* because we're little endian, this is what it turns into.   */
+
+      *p_argv = (void*) argp;
+
+      p_argv++;
+      argp += z;
+    }
+  
+  return;
+}
+
+/* How to make a trampoline.  Derived from gcc/config/i386/i386.c. */
+
+#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX,BYTES) \
+{ unsigned char *__tramp = (unsigned char*)(TRAMP); \
+   unsigned int  __fun = (unsigned int)(FUN); \
+   unsigned int  __ctx = (unsigned int)(CTX); \
+   unsigned int  __dis = __fun - ((unsigned int) __tramp + 8 + 4); \
+   *(unsigned char*)  &__tramp[0] = 0xb9; \
+   *(unsigned int*)   &__tramp[1] = __ctx; /* mov ecx, __ctx */ \
+   *(unsigned char*)  &__tramp[5] = 0x8b; \
+   *(unsigned char*)  &__tramp[6] = 0xd4; /* mov edx, esp */ \
+   *(unsigned char*)  &__tramp[7] = 0xe8; \
+   *(unsigned int*)   &__tramp[8] = __dis; /* call __fun  */ \
+   *(unsigned char*)  &__tramp[12] = 0xC2; /* ret BYTES */ \
+   *(unsigned short*) &__tramp[13] = BYTES; \
+ }
+
+/* the cif must already be prep'ed */
+
+ffi_status
+ffi_prep_closure (ffi_closure* closure,
+		  ffi_cif* cif,
+		  void (*fun)(ffi_cif*,void*,void**,void*),
+		  void *user_data)
+{
+  short bytes;
+  FFI_ASSERT (cif->abi == FFI_SYSV);
+  
+  if (cif->abi == FFI_SYSV)
+    bytes = 0;
+  else if (cif->abi == FFI_STDCALL)
+    bytes = cif->bytes;
+  else
+    return FFI_BAD_ABI;
+
+  FFI_INIT_TRAMPOLINE (&closure->tramp[0],
+		       &ffi_closure_SYSV,
+		       (void*)closure,
+		       bytes);
+  closure->cif  = cif;
+  closure->user_data = user_data;
+  closure->fun  = fun;
+
+  return FFI_OK;
+}

Added: vendor/Python/current/Modules/_ctypes/libffi_msvc/ffi.h
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi_msvc/ffi.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi_msvc/ffi.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,317 @@
+/* -----------------------------------------------------------------*-C-*-
+   libffi 2.00-beta - Copyright (c) 1996-2003  Red Hat, Inc.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+
+   ----------------------------------------------------------------------- */
+
+/* -------------------------------------------------------------------
+   The basic API is described in the README file.
+
+   The raw API is designed to bypass some of the argument packing
+   and unpacking on architectures for which it can be avoided.
+
+   The closure API allows interpreted functions to be packaged up
+   inside a C function pointer, so that they can be called as C functions,
+   with no understanding on the client side that they are interpreted.
+   It can also be used in other cases in which it is necessary to package
+   up a user specified parameter and a function pointer as a single
+   function pointer.
+
+   The closure API must be implemented in order to get its functionality,
+   e.g. for use by gij.  Routines are provided to emulate the raw API
+   if the underlying platform doesn't allow faster implementation.
+
+   More details on the raw and cloure API can be found in:
+
+   http://gcc.gnu.org/ml/java/1999-q3/msg00138.html
+
+   and
+
+   http://gcc.gnu.org/ml/java/1999-q3/msg00174.html
+   -------------------------------------------------------------------- */
+
+#ifndef LIBFFI_H
+#define LIBFFI_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Specify which architecture libffi is configured for. */
+//XXX #define X86
+
+/* ---- System configuration information --------------------------------- */
+
+#include <ffitarget.h>
+
+#ifndef LIBFFI_ASM
+
+#include <stddef.h>
+#include <limits.h>
+
+/* LONG_LONG_MAX is not always defined (not if STRICT_ANSI, for example).
+   But we can find it either under the correct ANSI name, or under GNU
+   C's internal name.  */
+#ifdef LONG_LONG_MAX
+# define FFI_LONG_LONG_MAX LONG_LONG_MAX
+#else
+# ifdef LLONG_MAX
+#  define FFI_LONG_LONG_MAX LLONG_MAX
+# else
+#  ifdef __GNUC__
+#   define FFI_LONG_LONG_MAX __LONG_LONG_MAX__
+#  endif
+#  ifdef _MSC_VER
+#   define FFI_LONG_LONG_MAX _I64_MAX
+#  endif
+# endif
+#endif
+
+#if SCHAR_MAX == 127
+# define ffi_type_uchar                ffi_type_uint8
+# define ffi_type_schar                ffi_type_sint8
+#else
+ #error "char size not supported"
+#endif
+
+#if SHRT_MAX == 32767
+# define ffi_type_ushort       ffi_type_uint16
+# define ffi_type_sshort       ffi_type_sint16
+#elif SHRT_MAX == 2147483647
+# define ffi_type_ushort       ffi_type_uint32
+# define ffi_type_sshort       ffi_type_sint32
+#else
+ #error "short size not supported"
+#endif
+
+#if INT_MAX == 32767
+# define ffi_type_uint         ffi_type_uint16
+# define ffi_type_sint         ffi_type_sint16
+#elif INT_MAX == 2147483647
+# define ffi_type_uint         ffi_type_uint32
+# define ffi_type_sint         ffi_type_sint32
+#elif INT_MAX == 9223372036854775807
+# define ffi_type_uint         ffi_type_uint64
+# define ffi_type_sint         ffi_type_sint64
+#else
+ #error "int size not supported"
+#endif
+
+#define ffi_type_ulong         ffi_type_uint64
+#define ffi_type_slong         ffi_type_sint64
+#if LONG_MAX == 2147483647
+# if FFI_LONG_LONG_MAX != 9223372036854775807
+  #error "no 64-bit data type supported"
+# endif
+#elif LONG_MAX != 9223372036854775807
+ #error "long size not supported"
+#endif
+
+/* The closure code assumes that this works on pointers, i.e. a size_t	*/
+/* can hold a pointer.							*/
+
+typedef struct _ffi_type
+{
+  size_t size;
+  unsigned short alignment;
+  unsigned short type;
+  /*@null@*/ struct _ffi_type **elements;
+} ffi_type;
+
+/* These are defined in types.c */
+extern ffi_type ffi_type_void;
+extern ffi_type ffi_type_uint8;
+extern ffi_type ffi_type_sint8;
+extern ffi_type ffi_type_uint16;
+extern ffi_type ffi_type_sint16;
+extern ffi_type ffi_type_uint32;
+extern ffi_type ffi_type_sint32;
+extern ffi_type ffi_type_uint64;
+extern ffi_type ffi_type_sint64;
+extern ffi_type ffi_type_float;
+extern ffi_type ffi_type_double;
+extern ffi_type ffi_type_longdouble;
+extern ffi_type ffi_type_pointer;
+
+
+typedef enum {
+  FFI_OK = 0,
+  FFI_BAD_TYPEDEF,
+  FFI_BAD_ABI 
+} ffi_status;
+
+typedef unsigned FFI_TYPE;
+
+typedef struct {
+  ffi_abi abi;
+  unsigned nargs;
+  /*@dependent@*/ ffi_type **arg_types;
+  /*@dependent@*/ ffi_type *rtype;
+  unsigned bytes;
+  unsigned flags;
+#ifdef FFI_EXTRA_CIF_FIELDS
+  FFI_EXTRA_CIF_FIELDS;
+#endif
+} ffi_cif;
+
+/* ---- Definitions for the raw API -------------------------------------- */
+
+#ifndef FFI_SIZEOF_ARG
+# if LONG_MAX == 2147483647
+#  define FFI_SIZEOF_ARG        4
+# elif LONG_MAX == 9223372036854775807
+#  define FFI_SIZEOF_ARG        8
+# endif
+#endif
+
+typedef union {
+  ffi_sarg  sint;
+  ffi_arg   uint;
+  float	    flt;
+  char      data[FFI_SIZEOF_ARG];
+  void*     ptr;
+} ffi_raw;
+
+void ffi_raw_call (/*@dependent@*/ ffi_cif *cif, 
+		   void (*fn)(), 
+		   /*@out@*/ void *rvalue, 
+		   /*@dependent@*/ ffi_raw *avalue);
+
+void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
+void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
+size_t ffi_raw_size (ffi_cif *cif);
+
+/* This is analogous to the raw API, except it uses Java parameter	*/
+/* packing, even on 64-bit machines.  I.e. on 64-bit machines		*/
+/* longs and doubles are followed by an empty 64-bit word.		*/
+
+void ffi_java_raw_call (/*@dependent@*/ ffi_cif *cif, 
+		        void (*fn)(), 
+		        /*@out@*/ void *rvalue, 
+		        /*@dependent@*/ ffi_raw *avalue);
+
+void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
+void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
+size_t ffi_java_raw_size (ffi_cif *cif);
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#if FFI_CLOSURES
+
+typedef struct {
+  char tramp[FFI_TRAMPOLINE_SIZE];
+  ffi_cif   *cif;
+  void     (*fun)(ffi_cif*,void*,void**,void*);
+  void      *user_data;
+} ffi_closure;
+
+ffi_status
+ffi_prep_closure (ffi_closure*,
+		  ffi_cif *,
+		  void (*fun)(ffi_cif*,void*,void**,void*),
+		  void *user_data);
+
+typedef struct {
+  char tramp[FFI_TRAMPOLINE_SIZE];
+
+  ffi_cif   *cif;
+
+#if !FFI_NATIVE_RAW_API
+
+  /* if this is enabled, then a raw closure has the same layout 
+     as a regular closure.  We use this to install an intermediate 
+     handler to do the transaltion, void** -> ffi_raw*. */
+
+  void     (*translate_args)(ffi_cif*,void*,void**,void*);
+  void      *this_closure;
+
+#endif
+
+  void     (*fun)(ffi_cif*,void*,ffi_raw*,void*);
+  void      *user_data;
+
+} ffi_raw_closure;
+
+ffi_status
+ffi_prep_raw_closure (ffi_raw_closure*,
+		      ffi_cif *cif,
+		      void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
+		      void *user_data);
+
+ffi_status
+ffi_prep_java_raw_closure (ffi_raw_closure*,
+		           ffi_cif *cif,
+		           void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
+		           void *user_data);
+
+#endif /* FFI_CLOSURES */
+
+/* ---- Public interface definition -------------------------------------- */
+
+ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif, 
+			ffi_abi abi,
+			unsigned int nargs, 
+			/*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type *rtype, 
+			/*@dependent@*/ ffi_type **atypes);
+
+int
+ffi_call(/*@dependent@*/ ffi_cif *cif, 
+	 void (*fn)(), 
+	 /*@out@*/ void *rvalue, 
+	 /*@dependent@*/ void **avalue);
+
+/* Useful for eliminating compiler warnings */
+#define FFI_FN(f) ((void (*)())f)
+
+/* ---- Definitions shared with assembly code ---------------------------- */
+
+#endif
+
+/* If these change, update src/mips/ffitarget.h. */
+#define FFI_TYPE_VOID       0    
+#define FFI_TYPE_INT        1
+#define FFI_TYPE_FLOAT      2    
+#define FFI_TYPE_DOUBLE     3
+#if 1
+#define FFI_TYPE_LONGDOUBLE 4
+#else
+#define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE
+#endif
+#define FFI_TYPE_UINT8      5   
+#define FFI_TYPE_SINT8      6
+#define FFI_TYPE_UINT16     7 
+#define FFI_TYPE_SINT16     8
+#define FFI_TYPE_UINT32     9
+#define FFI_TYPE_SINT32     10
+#define FFI_TYPE_UINT64     11
+#define FFI_TYPE_SINT64     12
+#define FFI_TYPE_STRUCT     13
+#define FFI_TYPE_POINTER    14
+
+/* This should always refer to the last type code (for sanity checks) */
+#define FFI_TYPE_LAST       FFI_TYPE_POINTER
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+

Added: vendor/Python/current/Modules/_ctypes/libffi_msvc/ffi_common.h
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi_msvc/ffi_common.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi_msvc/ffi_common.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,77 @@
+/* -----------------------------------------------------------------------
+   ffi_common.h - Copyright (c) 1996  Red Hat, Inc.
+
+   Common internal definitions and macros. Only necessary for building
+   libffi.
+   ----------------------------------------------------------------------- */
+
+#ifndef FFI_COMMON_H
+#define FFI_COMMON_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <fficonfig.h>
+#include <malloc.h>
+
+/* Check for the existence of memcpy. */
+#if STDC_HEADERS
+# include <string.h>
+#else
+# ifndef HAVE_MEMCPY
+#  define memcpy(d, s, n) bcopy ((s), (d), (n))
+# endif
+#endif
+
+#if defined(FFI_DEBUG) 
+#include <stdio.h>
+#endif
+
+#ifdef FFI_DEBUG
+/*@exits@*/ void ffi_assert(/*@temp@*/ char *expr, /*@temp@*/ char *file, int line);
+void ffi_stop_here(void);
+void ffi_type_test(/*@temp@*/ /*@out@*/ ffi_type *a, /*@temp@*/ char *file, int line);
+
+#define FFI_ASSERT(x) ((x) ? (void)0 : ffi_assert(#x, __FILE__,__LINE__))
+#define FFI_ASSERT_AT(x, f, l) ((x) ? 0 : ffi_assert(#x, (f), (l)))
+#define FFI_ASSERT_VALID_TYPE(x) ffi_type_test (x, __FILE__, __LINE__)
+#else
+#define FFI_ASSERT(x) 
+#define FFI_ASSERT_AT(x, f, l)
+#define FFI_ASSERT_VALID_TYPE(x)
+#endif
+
+#define ALIGN(v, a)  (((((size_t) (v))-1) | ((a)-1))+1)
+
+/* Perform machine dependent cif processing */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif);
+
+/* Extended cif, used in callback from assembly routine */
+typedef struct
+{
+  /*@dependent@*/ ffi_cif *cif;
+  /*@dependent@*/ void *rvalue;
+  /*@dependent@*/ void **avalue;
+} extended_cif;
+
+/* Terse sized type definitions.  */
+typedef unsigned int UINT8  __attribute__((__mode__(__QI__)));
+typedef signed int   SINT8  __attribute__((__mode__(__QI__)));
+typedef unsigned int UINT16 __attribute__((__mode__(__HI__)));
+typedef signed int   SINT16 __attribute__((__mode__(__HI__)));
+typedef unsigned int UINT32 __attribute__((__mode__(__SI__)));
+typedef signed int   SINT32 __attribute__((__mode__(__SI__)));
+typedef unsigned int UINT64 __attribute__((__mode__(__DI__)));
+typedef signed int   SINT64 __attribute__((__mode__(__DI__)));
+
+typedef float FLOAT32;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+

Added: vendor/Python/current/Modules/_ctypes/libffi_msvc/fficonfig.h
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi_msvc/fficonfig.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi_msvc/fficonfig.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,96 @@
+/* fficonfig.h.  Originally created by configure, now hand_maintained for MSVC. */
+
+/* fficonfig.h.  Generated automatically by configure.  */
+/* fficonfig.h.in.  Generated automatically from configure.in by autoheader.  */
+
+/* Define this for MSVC, but not for mingw32! */
+#ifdef _MSC_VER
+#define __attribute__(x) /* */
+#endif
+#define alloca _alloca
+
+/*----------------------------------------------------------------*/
+
+/* Define if using alloca.c.  */
+/* #undef C_ALLOCA */
+
+/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
+   This function is required for alloca.c support on those systems.  */
+/* #undef CRAY_STACKSEG_END */
+
+/* Define if you have alloca, as a function or macro.  */
+#define HAVE_ALLOCA 1
+
+/* Define if you have <alloca.h> and it should be used (not on Ultrix).  */
+/* #define HAVE_ALLOCA_H 1 */
+
+/* If using the C implementation of alloca, define if you know the
+   direction of stack growth for your system; otherwise it will be
+   automatically deduced at run-time.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown
+ */
+/* #undef STACK_DIRECTION */
+
+/* Define if you have the ANSI C header files.  */
+#define STDC_HEADERS 1
+
+/* Define if you have the memcpy function.  */
+#define HAVE_MEMCPY 1
+
+/* Define if read-only mmap of a plain file works. */
+//#define HAVE_MMAP_FILE 1
+
+/* Define if mmap of /dev/zero works. */
+//#define HAVE_MMAP_DEV_ZERO 1
+
+/* Define if mmap with MAP_ANON(YMOUS) works. */
+//#define HAVE_MMAP_ANON 1
+
+/* The number of bytes in type double */
+#define SIZEOF_DOUBLE 8
+
+/* The number of bytes in type long double */
+#define SIZEOF_LONG_DOUBLE 12
+
+/* Define if you have the long double type and it is bigger than a double */
+#define HAVE_LONG_DOUBLE 1
+
+/* whether byteorder is bigendian */
+/* #undef WORDS_BIGENDIAN */
+
+/* Define if the host machine stores words of multi-word integers in
+   big-endian order. */
+/* #undef HOST_WORDS_BIG_ENDIAN */
+
+/* 1234 = LIL_ENDIAN, 4321 = BIGENDIAN */
+#define BYTEORDER 1234
+
+/* Define if your assembler and linker support unaligned PC relative relocs. */
+/* #undef HAVE_AS_SPARC_UA_PCREL */
+
+/* Define if your assembler supports .register. */
+/* #undef HAVE_AS_REGISTER_PSEUDO_OP */
+
+/* Define if .eh_frame sections should be read-only. */
+/* #undef HAVE_RO_EH_FRAME */
+
+/* Define to the flags needed for the .section .eh_frame directive. */
+/* #define EH_FRAME_FLAGS "aw" */
+
+/* Define to the flags needed for the .section .eh_frame directive. */
+/* #define EH_FRAME_FLAGS "aw" */
+
+/* Define this if you want extra debugging. */
+/* #undef FFI_DEBUG */
+
+/* Define this is you do not want support for aggregate types. */
+/* #undef FFI_NO_STRUCTS */
+
+/* Define this is you do not want support for the raw API. */
+/* #undef FFI_NO_RAW_API */
+
+/* Define this if you are using Purify and want to suppress spurious messages. */
+/* #undef USING_PURIFY */
+

Added: vendor/Python/current/Modules/_ctypes/libffi_msvc/ffitarget.h
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi_msvc/ffitarget.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi_msvc/ffitarget.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,79 @@
+/* -----------------------------------------------------------------*-C-*-
+   ffitarget.h - Copyright (c) 1996-2003  Red Hat, Inc.
+   Target configuration macros for x86 and x86-64.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+
+   ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+/* ---- System specific configurations ----------------------------------- */
+
+#if defined (X86_64) && defined (__i386__)
+#undef X86_64
+#define X86
+#endif
+
+/* ---- Generic type definitions ----------------------------------------- */
+
+#ifndef LIBFFI_ASM
+typedef unsigned long          ffi_arg;
+typedef signed long            ffi_sarg;
+
+typedef enum ffi_abi {
+  FFI_FIRST_ABI = 0,
+
+  /* ---- Intel x86 Win32 ---------- */
+  FFI_SYSV,
+  FFI_STDCALL,
+  /* TODO: Add fastcall support for the sake of completeness */
+  FFI_DEFAULT_ABI = FFI_SYSV,
+
+  /* ---- Intel x86 and AMD x86-64 - */
+/* #if !defined(X86_WIN32) && (defined(__i386__) || defined(__x86_64__)) */
+/*   FFI_SYSV, */
+/*   FFI_UNIX64,*/   /* Unix variants all use the same ABI for x86-64  */
+/* #ifdef __i386__ */
+/*   FFI_DEFAULT_ABI = FFI_SYSV, */
+/* #else */
+/*   FFI_DEFAULT_ABI = FFI_UNIX64, */
+/* #endif */
+/* #endif */
+
+  FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
+} ffi_abi;
+#endif
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#define FFI_CLOSURES 1
+
+#ifdef X86_64
+#define FFI_TRAMPOLINE_SIZE 24
+#define FFI_NATIVE_RAW_API 0
+#else
+#define FFI_TRAMPOLINE_SIZE 15
+#define FFI_NATIVE_RAW_API 1	/* x86 has native raw api support */
+#endif
+
+#endif
+

Added: vendor/Python/current/Modules/_ctypes/libffi_msvc/prep_cif.c
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi_msvc/prep_cif.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi_msvc/prep_cif.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,175 @@
+/* -----------------------------------------------------------------------
+   prep_cif.c - Copyright (c) 1996, 1998  Red Hat, Inc.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+#include <stdlib.h>
+
+
+/* Round up to FFI_SIZEOF_ARG. */
+
+#define STACK_ARG_SIZE(x) ALIGN(x, FFI_SIZEOF_ARG)
+
+/* Perform machine independent initialization of aggregate type
+   specifications. */
+
+static ffi_status initialize_aggregate(/*@out@*/ ffi_type *arg)
+{
+  ffi_type **ptr; 
+
+  FFI_ASSERT(arg != NULL);
+
+  /*@-usedef@*/
+
+  FFI_ASSERT(arg->elements != NULL);
+  FFI_ASSERT(arg->size == 0);
+  FFI_ASSERT(arg->alignment == 0);
+
+  ptr = &(arg->elements[0]);
+
+  while ((*ptr) != NULL)
+    {
+      if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK))
+	return FFI_BAD_TYPEDEF;
+      
+      /* Perform a sanity check on the argument type */
+      FFI_ASSERT_VALID_TYPE(*ptr);
+
+      arg->size = ALIGN(arg->size, (*ptr)->alignment);
+      arg->size += (*ptr)->size;
+
+      arg->alignment = (arg->alignment > (*ptr)->alignment) ? 
+	arg->alignment : (*ptr)->alignment;
+
+      ptr++;
+    }
+
+  /* Structure size includes tail padding.  This is important for
+     structures that fit in one register on ABIs like the PowerPC64
+     Linux ABI that right justify small structs in a register.
+     It's also needed for nested structure layout, for example
+     struct A { long a; char b; }; struct B { struct A x; char y; };
+     should find y at an offset of 2*sizeof(long) and result in a
+     total size of 3*sizeof(long).  */
+  arg->size = ALIGN (arg->size, arg->alignment);
+
+  if (arg->size == 0)
+    return FFI_BAD_TYPEDEF;
+  else
+    return FFI_OK;
+
+  /*@=usedef@*/
+}
+
+/* Perform machine independent ffi_cif preparation, then call
+   machine dependent routine. */
+
+ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif, 
+			ffi_abi abi, unsigned int nargs, 
+			/*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type *rtype, 
+			/*@dependent@*/ ffi_type **atypes)
+{
+  unsigned bytes = 0;
+  unsigned int i;
+  ffi_type **ptr;
+
+  FFI_ASSERT(cif != NULL);
+  FFI_ASSERT((abi > FFI_FIRST_ABI) && (abi <= FFI_DEFAULT_ABI));
+
+  cif->abi = abi;
+  cif->arg_types = atypes;
+  cif->nargs = nargs;
+  cif->rtype = rtype;
+
+  cif->flags = 0;
+
+  /* Initialize the return type if necessary */
+  /*@-usedef@*/
+  if ((cif->rtype->size == 0) && (initialize_aggregate(cif->rtype) != FFI_OK))
+    return FFI_BAD_TYPEDEF;
+  /*@=usedef@*/
+
+  /* Perform a sanity check on the return type */
+  FFI_ASSERT_VALID_TYPE(cif->rtype);
+
+  /* x86-64 and s390 stack space allocation is handled in prep_machdep.  */
+#if !defined M68K && !defined __x86_64__ && !defined S390
+  /* Make space for the return structure pointer */
+  if (cif->rtype->type == FFI_TYPE_STRUCT
+      /* MSVC returns small structures in registers.  But we have a different
+      workaround: pretend int32 or int64 return type, and converting to
+      structure afterwards. */
+#ifdef SPARC
+      && (cif->abi != FFI_V9 || cif->rtype->size > 32)
+#endif
+      )
+    bytes = STACK_ARG_SIZE(sizeof(void*));
+#endif
+
+  for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
+    {
+
+      /* Initialize any uninitialized aggregate type definitions */
+      if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK))
+	return FFI_BAD_TYPEDEF;
+
+      /* Perform a sanity check on the argument type, do this 
+	 check after the initialization.  */
+      FFI_ASSERT_VALID_TYPE(*ptr);
+
+#if !defined __x86_64__ && !defined S390
+#ifdef SPARC
+      if (((*ptr)->type == FFI_TYPE_STRUCT
+	   && ((*ptr)->size > 16 || cif->abi != FFI_V9))
+	  || ((*ptr)->type == FFI_TYPE_LONGDOUBLE
+	      && cif->abi != FFI_V9))
+	bytes += sizeof(void*);
+      else
+#endif
+	{
+#if !defined(_MSC_VER) && !defined(__MINGW32__)
+		/* Don't know if this is a libffi bug or not.  At least on
+		   Windows with MSVC, function call parameters are *not*
+		   aligned in the same way as structure fields are, they are
+		   only aligned in integer boundaries.
+
+		   This doesn't do any harm for cdecl functions and closures,
+		   since the caller cleans up the stack, but it is wrong for
+		   stdcall functions where the callee cleans.
+		*/
+
+	  /* Add any padding if necessary */
+	  if (((*ptr)->alignment - 1) & bytes)
+	    bytes = ALIGN(bytes, (*ptr)->alignment);
+	  
+#endif
+	  bytes += STACK_ARG_SIZE((*ptr)->size);
+	}
+#endif
+    }
+
+  cif->bytes = bytes;
+
+  /* Perform machine dependent cif processing */
+  return ffi_prep_cif_machdep(cif);
+}

Added: vendor/Python/current/Modules/_ctypes/libffi_msvc/types.c
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi_msvc/types.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi_msvc/types.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,104 @@
+/* -----------------------------------------------------------------------
+   types.c - Copyright (c) 1996, 1998  Red Hat, Inc.
+   
+   Predefined ffi_types needed by libffi.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+/* Type definitions */
+
+#define FFI_INTEGRAL_TYPEDEF(n, s, a, t) ffi_type ffi_type_##n = { s, a, t, NULL }
+#define FFI_AGGREGATE_TYPEDEF(n, e) ffi_type ffi_type_##n = { 0, 0, FFI_TYPE_STRUCT, e }
+
+/* Size and alignment are fake here. They must not be 0. */
+FFI_INTEGRAL_TYPEDEF(void, 1, 1, FFI_TYPE_VOID);
+
+FFI_INTEGRAL_TYPEDEF(uint8, 1, 1, FFI_TYPE_UINT8);
+FFI_INTEGRAL_TYPEDEF(sint8, 1, 1, FFI_TYPE_SINT8);
+FFI_INTEGRAL_TYPEDEF(uint16, 2, 2, FFI_TYPE_UINT16);
+FFI_INTEGRAL_TYPEDEF(sint16, 2, 2, FFI_TYPE_SINT16);
+FFI_INTEGRAL_TYPEDEF(uint32, 4, 4, FFI_TYPE_UINT32);
+FFI_INTEGRAL_TYPEDEF(sint32, 4, 4, FFI_TYPE_SINT32);
+FFI_INTEGRAL_TYPEDEF(float, 4, 4, FFI_TYPE_FLOAT);
+
+#if defined ALPHA || defined SPARC64 || defined X86_64 || defined S390X \
+    || defined IA64
+
+FFI_INTEGRAL_TYPEDEF(pointer, 8, 8, FFI_TYPE_POINTER);
+
+#else
+
+FFI_INTEGRAL_TYPEDEF(pointer, 4, 4, FFI_TYPE_POINTER);
+
+#endif
+
+#if defined X86 || defined X86_WIN32 || defined ARM || defined M68K
+
+FFI_INTEGRAL_TYPEDEF(uint64, 8, 4, FFI_TYPE_UINT64);
+FFI_INTEGRAL_TYPEDEF(sint64, 8, 4, FFI_TYPE_SINT64);
+
+#elif defined SH
+
+FFI_INTEGRAL_TYPEDEF(uint64, 8, 4, FFI_TYPE_UINT64);
+FFI_INTEGRAL_TYPEDEF(sint64, 8, 4, FFI_TYPE_SINT64);
+
+#else
+
+FFI_INTEGRAL_TYPEDEF(uint64, 8, 8, FFI_TYPE_UINT64);
+FFI_INTEGRAL_TYPEDEF(sint64, 8, 8, FFI_TYPE_SINT64);
+
+#endif
+
+
+#if defined X86 || defined X86_WIN32 || defined M68K
+
+FFI_INTEGRAL_TYPEDEF(double, 8, 4, FFI_TYPE_DOUBLE);
+FFI_INTEGRAL_TYPEDEF(longdouble, 12, 4, FFI_TYPE_LONGDOUBLE);
+
+#elif defined ARM || defined SH || defined POWERPC_AIX || defined POWERPC_DARWIN
+
+FFI_INTEGRAL_TYPEDEF(double, 8, 4, FFI_TYPE_DOUBLE);
+FFI_INTEGRAL_TYPEDEF(longdouble, 8, 4, FFI_TYPE_LONGDOUBLE);
+
+#elif defined SPARC
+
+FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE);
+#ifdef SPARC64
+FFI_INTEGRAL_TYPEDEF(longdouble, 16, 16, FFI_TYPE_LONGDOUBLE);
+#else
+FFI_INTEGRAL_TYPEDEF(longdouble, 16, 8, FFI_TYPE_LONGDOUBLE);
+#endif
+
+#elif defined X86_64
+
+FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE);
+FFI_INTEGRAL_TYPEDEF(longdouble, 16, 16, FFI_TYPE_LONGDOUBLE);
+
+#else
+
+FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE);
+FFI_INTEGRAL_TYPEDEF(longdouble, 8, 8, FFI_TYPE_LONGDOUBLE);
+
+#endif
+

Added: vendor/Python/current/Modules/_ctypes/libffi_msvc/win32.S
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi_msvc/win32.S	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi_msvc/win32.S	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,243 @@
+/* -----------------------------------------------------------------------
+   win32.S - Copyright (c) 1996, 1998, 2001, 2002  Red Hat, Inc.
+	     Copyright (c) 2001  John Beniton
+	     Copyright (c) 2002  Ranjit Mathew
+			
+ 
+   X86 Foreign Function Interface
+ 
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+ 
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+ 
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+ 
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+ 
+.text
+ 
+.globl ffi_prep_args
+ 
+        # This assumes we are using gas.
+        .balign 16
+.globl _ffi_call_SYSV
+ 
+_ffi_call_SYSV:
+        pushl %ebp
+        movl  %esp,%ebp
+
+	#THe: save previous %esi, and store the current stack pointer in %esi
+	pushl %esi
+	movl %esp,%esi
+
+        # Make room for all of the new args.
+        movl  16(%ebp),%ecx                                                     
+        subl  %ecx,%esp
+ 
+        movl  %esp,%eax
+ 
+        # Place all of the ffi_prep_args in position
+        pushl 12(%ebp)
+        pushl %eax
+        call  *8(%ebp)
+ 
+        # Return stack to previous state and call the function
+        addl  $8,%esp
+ 
+        # FIXME: Align the stack to a 128-bit boundary to avoid
+        # potential performance hits.
+
+	call  *28(%ebp)
+ 
+        # Remove the space we pushed for the args
+        movl  16(%ebp),%ecx
+        addl  %ecx,%esp
+
+	sub %esp,%esi # calculate stack pointer difference
+
+        # Load %ecx with the return type code
+        movl  20(%ebp),%ecx
+ 
+        # If the return value pointer is NULL, assume no return value.
+        cmpl  $0,24(%ebp)
+        jne   retint
+ 
+        # Even if there is no space for the return value, we are
+        # obliged to handle floating-point values.
+        cmpl  $FFI_TYPE_FLOAT,%ecx
+        jne   noretval
+        fstp  %st(0)
+ 
+        jmp   epilogue
+ 
+retint:
+        cmpl  $FFI_TYPE_INT,%ecx
+        jne   retfloat
+        # Load %ecx with the pointer to storage for the return value
+        movl  24(%ebp),%ecx
+        movl  %eax,0(%ecx)
+        jmp   epilogue
+ 
+retfloat:
+        cmpl  $FFI_TYPE_FLOAT,%ecx
+        jne   retdouble   
+         # Load %ecx with the pointer to storage for the return value
+        movl  24(%ebp),%ecx
+        fstps (%ecx)
+        jmp   epilogue
+ 
+retdouble:
+        cmpl  $FFI_TYPE_DOUBLE,%ecx
+        jne   retlongdouble
+        # Load %ecx with the pointer to storage for the return value
+        movl  24(%ebp),%ecx
+        fstpl (%ecx)
+        jmp   epilogue
+ 
+retlongdouble:
+        cmpl  $FFI_TYPE_LONGDOUBLE,%ecx
+        jne   retint64
+        # Load %ecx with the pointer to storage for the return value
+        movl  24(%ebp),%ecx
+        fstpt (%ecx)
+        jmp   epilogue
+ 
+retint64:
+        cmpl  $FFI_TYPE_SINT64,%ecx
+        jne   retstruct
+        # Load %ecx with the pointer to storage for the return value
+        movl  24(%ebp),%ecx
+        movl  %eax,0(%ecx)
+        movl  %edx,4(%ecx)
+ 
+retstruct:
+        # Nothing to do!
+ 
+noretval:
+epilogue:
+	movl %esi,%eax # return the stack pointer detlta in %eax
+	popl %esi # restore previous %esi
+        movl %ebp,%esp
+        popl %ebp
+        ret
+ 
+.ffi_call_SYSV_end:
+
+        # This assumes we are using gas.
+        .balign 16
+.globl _ffi_call_STDCALL
+
+_ffi_call_STDCALL:
+        pushl %ebp
+        movl  %esp,%ebp
+
+	#THe: save previous %esi, and store the current stack pointer in %esi
+	pushl %esi
+	movl %esp,%esi
+	
+        # Make room for all of the new args.
+        movl  16(%ebp),%ecx 
+        subl  %ecx,%esp
+
+        movl  %esp,%eax
+
+        # Place all of the ffi_prep_args in position
+        pushl 12(%ebp)
+        pushl %eax
+        call  *8(%ebp)
+
+        # Return stack to previous state and call the function
+        addl  $8,%esp
+
+        # FIXME: Align the stack to a 128-bit boundary to avoid
+        # potential performance hits.
+
+        call  *28(%ebp)
+
+	sub %esp,%esi # difference in stack
+
+        # stdcall functions pop arguments off the stack themselves
+
+        # Load %ecx with the return type code
+        movl  20(%ebp),%ecx
+
+        # If the return value pointer is NULL, assume no return value.
+        cmpl  $0,24(%ebp)
+        jne   sc_retint
+
+        # Even if there is no space for the return value, we are
+        # obliged to handle floating-point values.
+        cmpl  $FFI_TYPE_FLOAT,%ecx
+        jne   sc_noretval
+        fstp  %st(0)
+
+        jmp   sc_epilogue
+
+sc_retint:
+        cmpl  $FFI_TYPE_INT,%ecx
+        jne   sc_retfloat
+        # Load %ecx with the pointer to storage for the return value
+        movl  24(%ebp),%ecx
+        movl  %eax,0(%ecx)
+        jmp   sc_epilogue
+
+sc_retfloat:
+        cmpl  $FFI_TYPE_FLOAT,%ecx
+        jne   sc_retdouble
+         # Load %ecx with the pointer to storage for the return value
+        movl  24(%ebp),%ecx
+        fstps (%ecx)
+        jmp   sc_epilogue
+
+sc_retdouble:
+        cmpl  $FFI_TYPE_DOUBLE,%ecx
+        jne   sc_retlongdouble
+        # Load %ecx with the pointer to storage for the return value
+        movl  24(%ebp),%ecx
+        fstpl (%ecx)
+        jmp   sc_epilogue
+
+sc_retlongdouble:
+        cmpl  $FFI_TYPE_LONGDOUBLE,%ecx
+        jne   sc_retint64
+        # Load %ecx with the pointer to storage for the return value
+        movl  24(%ebp),%ecx
+        fstpt (%ecx)
+        jmp   sc_epilogue
+
+sc_retint64:
+        cmpl  $FFI_TYPE_SINT64,%ecx
+        jne   sc_retstruct
+        # Load %ecx with the pointer to storage for the return value
+        movl  24(%ebp),%ecx
+        movl  %eax,0(%ecx)
+        movl  %edx,4(%ecx)
+
+sc_retstruct:
+        # Nothing to do!
+
+sc_noretval:
+sc_epilogue:
+        movl %esi,%eax # return the stack difference
+	popl %esi # restore previous %esi value
+        movl %ebp,%esp
+        popl %ebp
+        ret
+
+.ffi_call_STDCALL_end:

Added: vendor/Python/current/Modules/_ctypes/libffi_msvc/win32.c
===================================================================
--- vendor/Python/current/Modules/_ctypes/libffi_msvc/win32.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/libffi_msvc/win32.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,267 @@
+/* -----------------------------------------------------------------------
+   win32.S - Copyright (c) 1996, 1998, 2001, 2002  Red Hat, Inc.
+	     Copyright (c) 2001  John Beniton
+	     Copyright (c) 2002  Ranjit Mathew
+			
+ 
+   X86 Foreign Function Interface
+ 
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+ 
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+ 
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+/* theller: almost verbatim translation from gas syntax to MSVC inline
+   assembler code. */
+
+/* theller: ffi_call_SYSV and ffi_call_STDCALL now return an integer - the
+   difference of the stack pointer before and after the function call.  If
+   everything is ok, zero is returned.  If stdcall functions are passed the
+   wrong number of arguments, the difference will be nonzero. */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+__declspec(naked) int
+ffi_call_SYSV(void (* prepfunc)(char *, extended_cif *), /* 8 */
+		 extended_cif *ecif, /* 12 */
+		 unsigned bytes, /* 16 */
+		 unsigned flags, /* 20 */
+		 unsigned *rvalue, /* 24 */
+		 void (*fn)()) /* 28 */
+{
+	_asm {
+		push ebp
+		mov ebp, esp
+
+		push esi // NEW: this register must be preserved across function calls
+// XXX SAVE ESP NOW!
+		mov esi, esp		// save stack pointer before the call
+
+// Make room for all of the new args.
+		mov ecx, [ebp+16]
+		sub esp, ecx		// sub esp, bytes
+		
+		mov eax, esp
+
+// Place all of the ffi_prep_args in position
+		push [ebp + 12] // ecif
+		push eax
+		call [ebp + 8] // prepfunc
+
+// Return stack to previous state and call the function
+		add esp, 8
+// FIXME: Align the stack to a 128-bit boundary to avoid
+// potential performance hits.
+		call [ebp + 28]
+// Remove the space we pushed for the args
+		mov ecx, [ebp + 16]
+		add esp, ecx
+
+// XXX ASSERT THAT ESP IS THE SAME NOW THAN BEFORE!
+		sub esi, esp
+
+// Load %ecx with the return type code
+		mov ecx, [ebp + 20]
+
+// If the return value pointer is NULL, assume no return value.
+/*
+  Intel asm is weird. We have to explicitely specify 'DWORD PTR' in the nexr instruction,
+  otherwise only one BYTE will be compared (instead of a DWORD)!
+ */
+		cmp DWORD PTR [ebp + 24], 0
+		jne sc_retint
+
+// Even if there is no space for the return value, we are
+// obliged to handle floating-point values.
+		cmp ecx, FFI_TYPE_FLOAT
+		jne sc_noretval
+//        fstp  %st(0)
+		fstp st(0)
+
+		jmp sc_epilogue
+
+sc_retint:
+		cmp ecx, FFI_TYPE_INT
+		jne sc_retfloat
+//        # Load %ecx with the pointer to storage for the return value
+		mov ecx, [ebp + 24]
+		mov [ecx + 0], eax
+		jmp sc_epilogue
+
+sc_retfloat:
+		cmp ecx, FFI_TYPE_FLOAT
+		jne sc_retdouble
+// Load %ecx with the pointer to storage for the return value
+		mov ecx, [ebp+24]
+//        fstps (%ecx)
+		fstp DWORD PTR [ecx]
+		jmp sc_epilogue
+
+sc_retdouble:
+		cmp ecx, FFI_TYPE_DOUBLE
+		jne sc_retlongdouble
+//        movl  24(%ebp),%ecx
+		mov ecx, [ebp+24]
+		fstp QWORD PTR [ecx]
+		jmp sc_epilogue
+
+		jmp sc_retlongdouble // avoid warning about unused label
+sc_retlongdouble:
+		cmp ecx, FFI_TYPE_LONGDOUBLE
+		jne sc_retint64
+// Load %ecx with the pointer to storage for the return value
+		mov ecx, [ebp+24]
+//        fstpt (%ecx)
+		fstp QWORD PTR [ecx] /* XXX ??? */
+		jmp sc_epilogue
+
+sc_retint64:
+		cmp ecx, FFI_TYPE_SINT64
+		jne sc_retstruct
+// Load %ecx with the pointer to storage for the return value
+		mov ecx, [ebp+24]
+		mov [ecx+0], eax
+		mov [ecx+4], edx
+
+sc_retstruct:
+// Nothing to do!
+
+sc_noretval:
+sc_epilogue:
+		mov eax, esi
+		pop esi // NEW restore: must be preserved across function calls
+		mov esp, ebp
+		pop ebp
+		ret
+	}
+}
+
+__declspec(naked) int
+ffi_call_STDCALL(void (* prepfunc)(char *, extended_cif *), /* 8 */
+		 extended_cif *ecif, /* 12 */
+		 unsigned bytes, /* 16 */
+		 unsigned flags, /* 20 */
+		 unsigned *rvalue, /* 24 */
+		 void (*fn)()) /* 28 */
+{
+	_asm {
+		push ebp
+		mov ebp, esp
+
+		push esi // NEW: this register must be preserved across function calls
+
+// XXX SAVE ESP NOW!
+		mov esi, esp
+
+// Make room for all of the new args.
+		mov ecx, [ebp+16]
+		sub esp, ecx
+		
+		mov eax, esp
+
+// Place all of the ffi_prep_args in position
+		push [ebp + 12] // ecif
+		push eax
+		call [ebp + 8] // prepfunc
+
+// Return stack to previous state and call the function
+		add esp, 8
+// FIXME: Align the stack to a 128-bit boundary to avoid
+// potential performance hits.
+		call [ebp + 28]
+// stdcall functions pop arguments off the stack themselves
+
+// XXX IS ESP NOW THE SAME AS BEFORE?
+		sub esi, esp
+
+// Load %ecx with the return type code
+		mov ecx, [ebp + 20]
+
+// If the return value pointer is NULL, assume no return value.
+/*
+  Intel asm is weird. We have to explicitely specify 'DWORD PTR' in the nexr instruction,
+  otherwise only one BYTE will be compared (instead of a DWORD)!
+ */
+		cmp DWORD PTR [ebp + 24], 0
+		jne sc_retint
+
+// Even if there is no space for the return value, we are
+// obliged to handle floating-point values.
+		cmp ecx, FFI_TYPE_FLOAT
+		jne sc_noretval
+//        fstp  %st(0)
+		fstp st(0)
+
+		jmp sc_epilogue
+
+sc_retint:
+		cmp ecx, FFI_TYPE_INT
+		jne sc_retfloat
+//        # Load %ecx with the pointer to storage for the return value
+		mov ecx, [ebp + 24]
+		mov [ecx + 0], eax
+		jmp sc_epilogue
+
+sc_retfloat:
+		cmp ecx, FFI_TYPE_FLOAT
+		jne sc_retdouble
+// Load %ecx with the pointer to storage for the return value
+		mov ecx, [ebp+24]
+//        fstps (%ecx)
+		fstp DWORD PTR [ecx]
+		jmp sc_epilogue
+
+sc_retdouble:
+		cmp ecx, FFI_TYPE_DOUBLE
+		jne sc_retlongdouble
+//        movl  24(%ebp),%ecx
+		mov ecx, [ebp+24]
+		fstp QWORD PTR [ecx]
+		jmp sc_epilogue
+
+		jmp sc_retlongdouble // avoid warning about unused label
+sc_retlongdouble:
+		cmp ecx, FFI_TYPE_LONGDOUBLE
+		jne sc_retint64
+// Load %ecx with the pointer to storage for the return value
+		mov ecx, [ebp+24]
+//        fstpt (%ecx)
+		fstp QWORD PTR [ecx] /* XXX ??? */
+		jmp sc_epilogue
+
+sc_retint64:
+		cmp ecx, FFI_TYPE_SINT64
+		jne sc_retstruct
+// Load %ecx with the pointer to storage for the return value
+		mov ecx, [ebp+24]
+		mov [ecx+0], eax
+		mov [ecx+4], edx
+
+sc_retstruct:
+// Nothing to do!
+
+sc_noretval:
+sc_epilogue:
+		mov eax, esi
+		pop esi // NEW restore: must be preserved across function calls
+		mov esp, ebp
+		pop ebp
+		ret
+	}
+}

Added: vendor/Python/current/Modules/_ctypes/malloc_closure.c
===================================================================
--- vendor/Python/current/Modules/_ctypes/malloc_closure.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/malloc_closure.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,110 @@
+/*****************************************************************
+  This file should be kept compatible with Python 2.3, see PEP 291.
+ *****************************************************************/
+
+#include <Python.h>
+#include <ffi.h>
+#ifdef MS_WIN32
+#include <windows.h>
+#else
+#include <sys/mman.h>
+#include <unistd.h>
+# if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
+#  define MAP_ANONYMOUS MAP_ANON
+# endif
+#endif
+#include "ctypes.h"
+
+/* BLOCKSIZE can be adjusted.  Larger blocksize will take a larger memory
+   overhead, but allocate less blocks from the system.  It may be that some
+   systems have a limit of how many mmap'd blocks can be open.
+*/
+
+#define BLOCKSIZE _pagesize
+
+/* #define MALLOC_CLOSURE_DEBUG */ /* enable for some debugging output */
+
+/******************************************************************/
+
+typedef union _tagITEM {
+	ffi_closure closure;
+	union _tagITEM *next;
+} ITEM;
+
+static ITEM *free_list;
+int _pagesize;
+
+static void more_core(void)
+{
+	ITEM *item;
+	int count, i;
+
+/* determine the pagesize */
+#ifdef MS_WIN32
+	if (!_pagesize) {
+		SYSTEM_INFO systeminfo;
+		GetSystemInfo(&systeminfo);
+		_pagesize = systeminfo.dwPageSize;
+	}
+#else
+	if (!_pagesize) {
+		_pagesize = getpagesize();
+	}
+#endif
+
+	/* calculate the number of nodes to allocate */
+	count = BLOCKSIZE / sizeof(ITEM);
+
+	/* allocate a memory block */
+#ifdef MS_WIN32
+	item = (ITEM *)VirtualAlloc(NULL,
+					       count * sizeof(ITEM),
+					       MEM_COMMIT,
+					       PAGE_EXECUTE_READWRITE);
+	if (item == NULL)
+		return;
+#else
+	item = (ITEM *)mmap(NULL,
+			    count * sizeof(ITEM),
+			    PROT_READ | PROT_WRITE | PROT_EXEC,
+			    MAP_PRIVATE | MAP_ANONYMOUS,
+			    -1,
+			    0);
+	if (item == (void *)MAP_FAILED)
+		return;
+#endif
+
+#ifdef MALLOC_CLOSURE_DEBUG
+	printf("block at %p allocated (%d bytes), %d ITEMs\n",
+	       item, count * sizeof(ITEM), count);
+#endif
+	/* put them into the free list */
+	for (i = 0; i < count; ++i) {
+		item->next = free_list;
+		free_list = item;
+		++item;
+	}
+}
+
+/******************************************************************/
+
+/* put the item back into the free list */
+void FreeClosure(void *p)
+{
+	ITEM *item = (ITEM *)p;
+	item->next = free_list;
+	free_list = item;
+}
+
+/* return one item from the free list, allocating more if needed */
+void *MallocClosure(void)
+{
+	ITEM *item;
+	if (!free_list)
+		more_core();
+	if (!free_list)
+		return NULL;
+	item = free_list;
+	free_list = item->next;
+	return item;
+}

Added: vendor/Python/current/Modules/_ctypes/stgdict.c
===================================================================
--- vendor/Python/current/Modules/_ctypes/stgdict.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ctypes/stgdict.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,494 @@
+/*****************************************************************
+  This file should be kept compatible with Python 2.3, see PEP 291.
+ *****************************************************************/
+
+#include "Python.h"
+#include <ffi.h>
+#ifdef MS_WIN32
+#include <windows.h>
+#endif
+#include "ctypes.h"
+
+/******************************************************************/
+/*
+  StdDict - a dictionary subclass, containing additional C accessible fields
+
+  XXX blabla more
+*/
+
+/* Seems we need this, otherwise we get problems when calling
+ * PyDict_SetItem() (ma_lookup is NULL)
+ */
+static int
+StgDict_init(StgDictObject *self, PyObject *args, PyObject *kwds)
+{
+	if (PyDict_Type.tp_init((PyObject *)self, args, kwds) < 0)
+		return -1;
+	return 0;
+}
+
+static int
+StgDict_clear(StgDictObject *self)
+{
+	Py_CLEAR(self->proto);
+	Py_CLEAR(self->argtypes);
+	Py_CLEAR(self->converters);
+	Py_CLEAR(self->restype);
+	Py_CLEAR(self->checker);
+	return 0;
+}
+
+static void
+StgDict_dealloc(StgDictObject *self)
+{
+	StgDict_clear(self);
+	PyMem_Free(self->ffi_type_pointer.elements);
+	PyDict_Type.tp_dealloc((PyObject *)self);
+}
+
+int
+StgDict_clone(StgDictObject *dst, StgDictObject *src)
+{
+	char *d, *s;
+	int size;
+
+	StgDict_clear(dst);
+	PyMem_Free(dst->ffi_type_pointer.elements);
+	dst->ffi_type_pointer.elements = NULL;
+
+	d = (char *)dst;
+	s = (char *)src;
+	memcpy(d + sizeof(PyDictObject),
+	       s + sizeof(PyDictObject),
+	       sizeof(StgDictObject) - sizeof(PyDictObject));
+
+	Py_XINCREF(dst->proto);
+	Py_XINCREF(dst->argtypes);
+	Py_XINCREF(dst->converters);
+	Py_XINCREF(dst->restype);
+	Py_XINCREF(dst->checker);
+
+	if (src->ffi_type_pointer.elements == NULL)
+		return 0;
+	size = sizeof(ffi_type *) * (src->length + 1);
+	dst->ffi_type_pointer.elements = PyMem_Malloc(size);
+	if (dst->ffi_type_pointer.elements == NULL)
+		return -1;
+	memcpy(dst->ffi_type_pointer.elements,
+	       src->ffi_type_pointer.elements,
+	       size);
+	return 0;
+}
+
+PyTypeObject StgDict_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0,
+	"StgDict",
+	sizeof(StgDictObject),
+	0,
+	(destructor)StgDict_dealloc,		/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	0,					/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	0,					/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0,					/* tp_doc */
+	0,					/* tp_traverse */
+	0,					/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	0,					/* tp_methods */
+	0,					/* tp_members */
+	0,					/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	(initproc)StgDict_init,			/* tp_init */
+	0,					/* tp_alloc */
+	0,					/* tp_new */
+	0,					/* tp_free */
+};
+
+/* May return NULL, but does not set an exception! */
+StgDictObject *
+PyType_stgdict(PyObject *obj)
+{
+	PyTypeObject *type;
+
+	if (!PyType_Check(obj))
+		return NULL;
+	type = (PyTypeObject *)obj;
+	if (!PyType_HasFeature(type, Py_TPFLAGS_HAVE_CLASS))
+		return NULL;
+	if (!type->tp_dict || !StgDict_CheckExact(type->tp_dict))
+		return NULL;
+	return (StgDictObject *)type->tp_dict;
+}
+
+/* May return NULL, but does not set an exception! */
+/*
+  This function should be as fast as possible, so we don't call PyType_stgdict
+  above but inline the code, and avoid the PyType_Check().
+*/
+StgDictObject *
+PyObject_stgdict(PyObject *self)
+{
+	PyTypeObject *type = self->ob_type;
+	if (!PyType_HasFeature(type, Py_TPFLAGS_HAVE_CLASS))
+		return NULL;
+	if (!type->tp_dict || !StgDict_CheckExact(type->tp_dict))
+		return NULL;
+	return (StgDictObject *)type->tp_dict;
+}
+
+/* descr is the descriptor for a field marked as anonymous.  Get all the
+ _fields_ descriptors from descr->proto, create new descriptors with offset
+ and index adjusted, and stuff them into type.
+ */
+static int
+MakeFields(PyObject *type, CFieldObject *descr,
+	   Py_ssize_t index, Py_ssize_t offset)
+{
+	Py_ssize_t i;
+	PyObject *fields;
+	PyObject *fieldlist;
+
+	fields = PyObject_GetAttrString(descr->proto, "_fields_");
+	if (fields == NULL)
+		return -1;
+	fieldlist = PySequence_Fast(fields, "_fields_ must be a sequence");
+	Py_DECREF(fields);
+	if (fieldlist == NULL)
+		return -1;
+
+	for (i = 0; i < PySequence_Fast_GET_SIZE(fieldlist); ++i) {
+		PyObject *pair = PySequence_Fast_GET_ITEM(fieldlist, i); /* borrowed */
+		PyObject *fname, *ftype, *bits;
+		CFieldObject *fdescr;
+		CFieldObject *new_descr;
+		/* Convert to PyArg_UnpackTuple... */
+		if (!PyArg_ParseTuple(pair, "OO|O", &fname, &ftype, &bits)) {
+			Py_DECREF(fieldlist);
+			return -1;
+		}
+		fdescr = (CFieldObject *)PyObject_GetAttr(descr->proto, fname);
+		if (fdescr == NULL) {
+			Py_DECREF(fieldlist);
+			return -1;
+		}
+		if (fdescr->ob_type != &CField_Type) {
+			PyErr_SetString(PyExc_TypeError, "unexpected type");
+			Py_DECREF(fdescr);
+			Py_DECREF(fieldlist);
+			return -1;
+		}
+		if (fdescr->anonymous) {
+			int rc = MakeFields(type, fdescr,
+					    index + fdescr->index,
+					    offset + fdescr->offset);
+			Py_DECREF(fdescr);
+			if (rc == -1) {
+				Py_DECREF(fieldlist);
+				return -1;
+			}
+			continue;
+		}
+ 		new_descr = (CFieldObject *)PyObject_CallObject((PyObject *)&CField_Type, NULL);
+		if (new_descr == NULL) {
+			Py_DECREF(fdescr);
+			Py_DECREF(fieldlist);
+			return -1;
+		}
+		assert(new_descr->ob_type == &CField_Type);
+ 		new_descr->size = fdescr->size;
+ 		new_descr->offset = fdescr->offset + offset;
+ 		new_descr->index = fdescr->index + index;
+ 		new_descr->proto = fdescr->proto;
+ 		Py_XINCREF(new_descr->proto);
+ 		new_descr->getfunc = fdescr->getfunc;
+ 		new_descr->setfunc = fdescr->setfunc;
+
+  		Py_DECREF(fdescr);
+		
+		if (-1 == PyObject_SetAttr(type, fname, (PyObject *)new_descr)) {
+			Py_DECREF(fieldlist);
+			Py_DECREF(new_descr);
+			return -1;
+		}
+		Py_DECREF(new_descr);
+	}
+	Py_DECREF(fieldlist);
+	return 0;
+}
+
+/* Iterate over the names in the type's _anonymous_ attribute, if present,
+ */
+static int
+MakeAnonFields(PyObject *type)
+{
+	PyObject *anon;
+	PyObject *anon_names;
+	Py_ssize_t i;
+
+	anon = PyObject_GetAttrString(type, "_anonymous_");
+	if (anon == NULL) {
+		PyErr_Clear();
+		return 0;
+	}
+	anon_names = PySequence_Fast(anon, "_anonymous_ must be a sequence");
+	Py_DECREF(anon);
+	if (anon_names == NULL)
+		return -1;
+
+	for (i = 0; i < PySequence_Fast_GET_SIZE(anon_names); ++i) {
+		PyObject *fname = PySequence_Fast_GET_ITEM(anon_names, i); /* borrowed */
+		CFieldObject *descr = (CFieldObject *)PyObject_GetAttr(type, fname);
+		if (descr == NULL) {
+			Py_DECREF(anon_names);
+			return -1;
+		}
+		assert(descr->ob_type == &CField_Type);
+		descr->anonymous = 1;
+
+		/* descr is in the field descriptor. */
+		if (-1 == MakeFields(type, (CFieldObject *)descr,
+				     ((CFieldObject *)descr)->index,
+				     ((CFieldObject *)descr)->offset)) {
+			Py_DECREF(descr);
+			Py_DECREF(anon_names);
+			return -1;
+		}
+		Py_DECREF(descr);
+	}
+
+	Py_DECREF(anon_names);
+	return 0;
+}
+
+/*
+  Retrive the (optional) _pack_ attribute from a type, the _fields_ attribute,
+  and create an StgDictObject.  Used for Structure and Union subclasses.
+*/
+int
+StructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct)
+{
+	StgDictObject *stgdict, *basedict;
+	int len, offset, size, align, i;
+	int union_size, total_align;
+	int field_size = 0;
+	int bitofs;
+	PyObject *isPacked;
+	int pack = 0;
+	int ffi_ofs;
+	int big_endian;
+
+	/* HACK Alert: I cannot be bothered to fix ctypes.com, so there has to
+	   be a way to use the old, broken sematics: _fields_ are not extended
+	   but replaced in subclasses.
+	   
+	   XXX Remove this in ctypes 1.0!
+	*/
+	int use_broken_old_ctypes_semantics;
+
+	if (fields == NULL)
+		return 0;
+
+#ifdef WORDS_BIGENDIAN
+	big_endian = PyObject_HasAttrString(type, "_swappedbytes_") ? 0 : 1;
+#else
+	big_endian = PyObject_HasAttrString(type, "_swappedbytes_") ? 1 : 0;
+#endif
+
+	use_broken_old_ctypes_semantics = \
+		PyObject_HasAttrString(type, "_use_broken_old_ctypes_structure_semantics_");
+
+	isPacked = PyObject_GetAttrString(type, "_pack_");
+	if (isPacked) {
+		pack = PyInt_AsLong(isPacked);
+		if (pack < 0 || PyErr_Occurred()) {
+			Py_XDECREF(isPacked);
+			PyErr_SetString(PyExc_ValueError,
+					"_pack_ must be a non-negative integer");
+			return -1;
+		}
+		Py_DECREF(isPacked);
+	} else
+		PyErr_Clear();
+
+	len = PySequence_Length(fields);
+	if (len == -1) {
+		PyErr_SetString(PyExc_TypeError,
+				"'_fields_' must be a sequence of pairs");
+		return -1;
+	}
+
+	stgdict = PyType_stgdict(type);
+	if (!stgdict)
+		return -1;
+	/* If this structure/union is already marked final we cannot assign
+	   _fields_ anymore. */
+
+	if (stgdict->flags & DICTFLAG_FINAL) {/* is final ? */
+		PyErr_SetString(PyExc_AttributeError,
+				"_fields_ is final");
+		return -1;
+	}
+
+	if (stgdict->ffi_type_pointer.elements)
+		PyMem_Free(stgdict->ffi_type_pointer.elements);
+
+	basedict = PyType_stgdict((PyObject *)((PyTypeObject *)type)->tp_base);
+	if (basedict && !use_broken_old_ctypes_semantics) {
+		size = offset = basedict->size;
+		align = basedict->align;
+		union_size = 0;
+		total_align = align ? align : 1;
+		stgdict->ffi_type_pointer.type = FFI_TYPE_STRUCT;
+		stgdict->ffi_type_pointer.elements = PyMem_Malloc(sizeof(ffi_type *) * (basedict->length + len + 1));
+		memset(stgdict->ffi_type_pointer.elements, 0,
+		       sizeof(ffi_type *) * (basedict->length + len + 1));
+		memcpy(stgdict->ffi_type_pointer.elements,
+		       basedict->ffi_type_pointer.elements,
+		       sizeof(ffi_type *) * (basedict->length));
+		ffi_ofs = basedict->length;
+	} else {
+		offset = 0;
+		size = 0;
+		align = 0;
+		union_size = 0;
+		total_align = 1;
+		stgdict->ffi_type_pointer.type = FFI_TYPE_STRUCT;
+		stgdict->ffi_type_pointer.elements = PyMem_Malloc(sizeof(ffi_type *) * (len + 1));
+		memset(stgdict->ffi_type_pointer.elements, 0,
+		       sizeof(ffi_type *) * (len + 1));
+		ffi_ofs = 0;
+	}
+
+#define realdict ((PyObject *)&stgdict->dict)
+	for (i = 0; i < len; ++i) {
+		PyObject *name = NULL, *desc = NULL;
+		PyObject *pair = PySequence_GetItem(fields, i);
+		PyObject *prop;
+		StgDictObject *dict;
+		int bitsize = 0;
+
+		if (!pair || !PyArg_ParseTuple(pair, "OO|i", &name, &desc, &bitsize)) {
+			PyErr_SetString(PyExc_AttributeError,
+					"'_fields_' must be a sequence of pairs");
+			Py_XDECREF(pair);
+			return -1;
+		}
+		dict = PyType_stgdict(desc);
+		if (dict == NULL) {
+			Py_DECREF(pair);
+			PyErr_Format(PyExc_TypeError,
+				     "second item in _fields_ tuple (index %d) must be a C type",
+				     i);
+			return -1;
+		}
+		stgdict->ffi_type_pointer.elements[ffi_ofs + i] = &dict->ffi_type_pointer;
+		dict->flags |= DICTFLAG_FINAL; /* mark field type final */
+		if (PyTuple_Size(pair) == 3) { /* bits specified */
+			switch(dict->ffi_type_pointer.type) {
+			case FFI_TYPE_UINT8:
+			case FFI_TYPE_UINT16:
+			case FFI_TYPE_UINT32:
+			case FFI_TYPE_SINT64:
+			case FFI_TYPE_UINT64:
+				break;
+
+			case FFI_TYPE_SINT8:
+			case FFI_TYPE_SINT16:
+			case FFI_TYPE_SINT32:
+				if (dict->getfunc != getentry("c")->getfunc
+#ifdef CTYPES_UNICODE
+				    && dict->getfunc != getentry("u")->getfunc
+#endif
+					)
+					break;
+				/* else fall through */
+			default:
+				PyErr_Format(PyExc_TypeError,
+					     "bit fields not allowed for type %s",
+					     ((PyTypeObject *)desc)->tp_name);
+				Py_DECREF(pair);
+				return -1;
+			}
+			if (bitsize <= 0 || bitsize > dict->size * 8) {
+				PyErr_SetString(PyExc_ValueError,
+						"number of bits invalid for bit field");
+				Py_DECREF(pair);
+				return -1;
+			}
+		} else
+			bitsize = 0;
+		if (isStruct) {
+			prop = CField_FromDesc(desc, i,
+					       &field_size, bitsize, &bitofs,
+					       &size, &offset, &align,
+					       pack, big_endian);
+		} else /* union */ {
+			size = 0;
+			offset = 0;
+			align = 0;
+			prop = CField_FromDesc(desc, i,
+					       &field_size, bitsize, &bitofs,
+					       &size, &offset, &align,
+					       pack, big_endian);
+			union_size = max(size, union_size);
+		}
+		total_align = max(align, total_align);
+
+		if (!prop) {
+			Py_DECREF(pair);
+			Py_DECREF((PyObject *)stgdict);
+			return -1;
+		}
+		if (-1 == PyDict_SetItem(realdict, name, prop)) {
+			Py_DECREF(prop);
+			Py_DECREF(pair);
+			Py_DECREF((PyObject *)stgdict);
+			return -1;
+		}
+		Py_DECREF(pair);
+		Py_DECREF(prop);
+	}
+#undef realdict
+	if (!isStruct)
+		size = union_size;
+
+	/* Adjust the size according to the alignment requirements */
+	size = ((size + total_align - 1) / total_align) * total_align;
+
+	stgdict->ffi_type_pointer.alignment = total_align;
+	stgdict->ffi_type_pointer.size = size;
+
+	stgdict->size = size;
+	stgdict->align = total_align;
+	stgdict->length = len;	/* ADD ffi_ofs? */
+
+	/* We did check that this flag was NOT set above, it must not
+	   have been set until now. */
+	if (stgdict->flags & DICTFLAG_FINAL) {
+		PyErr_SetString(PyExc_AttributeError,
+				"Structure or union cannot contain itself");
+		return -1;
+	}
+	stgdict->flags |= DICTFLAG_FINAL;
+
+	return MakeAnonFields(type);
+}

Added: vendor/Python/current/Modules/_curses_panel.c
===================================================================
--- vendor/Python/current/Modules/_curses_panel.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_curses_panel.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,480 @@
+/*
+ *   Interface to the ncurses panel library
+ *
+ * Original version by Thomas Gellekum
+ */
+
+/* Release Number */
+
+static char *PyCursesVersion = "2.1";
+
+/* Includes */
+
+#include "Python.h"
+
+#include "py_curses.h"
+
+#include <panel.h>
+
+static PyObject *PyCursesError;
+
+
+/* Utility Functions */
+
+/*
+ * Check the return code from a curses function and return None 
+ * or raise an exception as appropriate.
+ */
+
+static PyObject *
+PyCursesCheckERR(int code, char *fname)
+{
+    if (code != ERR) {
+	Py_INCREF(Py_None);
+	return Py_None;
+    } else {
+	if (fname == NULL) {
+	    PyErr_SetString(PyCursesError, catchall_ERR);
+	} else {
+	    PyErr_Format(PyCursesError, "%s() returned ERR", fname);
+	}
+	return NULL;
+    }
+}
+
+/*****************************************************************************
+ The Panel Object
+******************************************************************************/
+
+/* Definition of the panel object and panel type */
+
+typedef struct {
+    PyObject_HEAD
+    PANEL *pan;
+    PyCursesWindowObject *wo;	/* for reference counts */
+} PyCursesPanelObject;
+
+PyTypeObject PyCursesPanel_Type;
+
+#define PyCursesPanel_Check(v)	 ((v)->ob_type == &PyCursesPanel_Type)
+
+/* Some helper functions. The problem is that there's always a window
+   associated with a panel. To ensure that Python's GC doesn't pull
+   this window from under our feet we need to keep track of references
+   to the corresponding window object within Python. We can't use
+   dupwin(oldwin) to keep a copy of the curses WINDOW because the
+   contents of oldwin is copied only once; code like
+
+   win = newwin(...)
+   pan = win.panel()
+   win.addstr(some_string)
+   pan.window().addstr(other_string)
+
+   will fail. */
+
+/* We keep a linked list of PyCursesPanelObjects, lop. A list should
+   suffice, I don't expect more than a handful or at most a few
+   dozens of panel objects within a typical program. */
+typedef struct _list_of_panels {
+    PyCursesPanelObject *po;
+    struct _list_of_panels *next;
+} list_of_panels;
+
+/* list anchor */
+static list_of_panels *lop;
+
+/* Insert a new panel object into lop */
+static int
+insert_lop(PyCursesPanelObject *po)
+{
+    list_of_panels *new;
+    
+    if ((new = (list_of_panels *)malloc(sizeof(list_of_panels))) == NULL) {
+	PyErr_NoMemory();
+	return -1;
+    }
+    new->po = po;
+    new->next = lop;
+    lop = new;
+    return 0;
+}
+
+/* Remove the panel object from lop */
+static void
+remove_lop(PyCursesPanelObject *po)
+{
+    list_of_panels *temp, *n;
+
+    temp = lop;
+    if (temp->po == po) {
+	lop = temp->next;
+	free(temp);
+	return;
+    }
+    while (temp->next == NULL || temp->next->po != po) {
+	if (temp->next == NULL) {
+	    PyErr_SetString(PyExc_RuntimeError,
+			    "remove_lop: can't find Panel Object");
+	    return;
+	}
+	temp = temp->next;
+    }
+    n = temp->next->next;
+    free(temp->next);
+    temp->next = n;
+    return;
+}
+
+/* Return the panel object that corresponds to pan */
+static PyCursesPanelObject *
+find_po(PANEL *pan)
+{
+    list_of_panels *temp;
+    for (temp = lop; temp->po->pan != pan; temp = temp->next)
+	if (temp->next == NULL) return NULL;	/* not found!? */
+    return temp->po;
+}
+
+/* Function Prototype Macros - They are ugly but very, very useful. ;-)
+
+   X - function name
+   TYPE - parameter Type
+   ERGSTR - format string for construction of the return value
+   PARSESTR - format string for argument parsing */
+
+#define Panel_NoArgNoReturnFunction(X) \
+static PyObject *PyCursesPanel_##X(PyCursesPanelObject *self) \
+{ return PyCursesCheckERR(X(self->pan), # X); }
+
+#define Panel_NoArgTrueFalseFunction(X) \
+static PyObject *PyCursesPanel_##X(PyCursesPanelObject *self) \
+{ \
+  if (X (self->pan) == FALSE) { Py_INCREF(Py_False); return Py_False; } \
+  else { Py_INCREF(Py_True); return Py_True; } }
+
+#define Panel_TwoArgNoReturnFunction(X, TYPE, PARSESTR) \
+static PyObject *PyCursesPanel_##X(PyCursesPanelObject *self, PyObject *args) \
+{ \
+  TYPE arg1, arg2; \
+  if (!PyArg_ParseTuple(args, PARSESTR, &arg1, &arg2)) return NULL; \
+  return PyCursesCheckERR(X(self->pan, arg1, arg2), # X); }
+
+/* ------------- PANEL routines --------------- */
+
+Panel_NoArgNoReturnFunction(bottom_panel)
+Panel_NoArgNoReturnFunction(hide_panel)
+Panel_NoArgNoReturnFunction(show_panel)
+Panel_NoArgNoReturnFunction(top_panel)
+Panel_NoArgTrueFalseFunction(panel_hidden)
+Panel_TwoArgNoReturnFunction(move_panel, int, "ii;y,x")
+
+/* Allocation and deallocation of Panel Objects */
+
+static PyObject *
+PyCursesPanel_New(PANEL *pan, PyCursesWindowObject *wo)
+{
+    PyCursesPanelObject *po;
+
+    po = PyObject_NEW(PyCursesPanelObject, &PyCursesPanel_Type);
+    if (po == NULL) return NULL;
+    po->pan = pan;
+    po->wo = wo;
+    Py_INCREF(wo);
+    if (insert_lop(po) < 0) {
+	PyObject_DEL(po);
+	return NULL;
+    }
+    return (PyObject *)po;
+}
+
+static void
+PyCursesPanel_Dealloc(PyCursesPanelObject *po)
+{
+    (void)del_panel(po->pan);
+    Py_DECREF(po->wo);
+    remove_lop(po);
+    PyObject_DEL(po);
+}
+
+/* panel_above(NULL) returns the bottom panel in the stack. To get
+   this behaviour we use curses.panel.bottom_panel(). */
+static PyObject *
+PyCursesPanel_above(PyCursesPanelObject *self)
+{
+    PANEL *pan;
+    PyCursesPanelObject *po;
+    
+    pan = panel_above(self->pan);
+
+    if (pan == NULL) {		/* valid output, it means the calling panel
+				   is on top of the stack */
+	Py_INCREF(Py_None);
+	return Py_None;
+    }
+    po = find_po(pan);
+    if (po == NULL) {
+	PyErr_SetString(PyExc_RuntimeError,
+			"panel_above: can't find Panel Object");
+	return NULL;
+    }
+    Py_INCREF(po);
+    return (PyObject *)po;
+}
+
+/* panel_below(NULL) returns the top panel in the stack. To get
+   this behaviour we use curses.panel.top_panel(). */
+static PyObject *
+PyCursesPanel_below(PyCursesPanelObject *self)
+{
+    PANEL *pan;
+    PyCursesPanelObject *po;
+    
+    pan = panel_below(self->pan);
+    
+    if (pan == NULL) {		/* valid output, it means the calling panel
+				   is on the bottom of the stack */
+	Py_INCREF(Py_None);
+	return Py_None;
+    }
+    po = find_po(pan);
+    if (po == NULL) {
+	PyErr_SetString(PyExc_RuntimeError,
+			"panel_below: can't find Panel Object");
+	return NULL;
+    }
+    Py_INCREF(po);
+    return (PyObject *)po;
+}
+
+static PyObject *
+PyCursesPanel_window(PyCursesPanelObject *self)
+{
+    Py_INCREF(self->wo);
+    return (PyObject *)self->wo;
+}
+
+static PyObject *
+PyCursesPanel_replace_panel(PyCursesPanelObject *self, PyObject *args)
+{
+    PyCursesPanelObject *po;
+    PyCursesWindowObject *temp;
+    int rtn;
+    
+    if (PyTuple_Size(args) != 1) {
+	PyErr_SetString(PyExc_TypeError, "replace requires one argument");
+	return NULL;
+    }
+    if (!PyArg_ParseTuple(args, "O!;window object",
+			  &PyCursesWindow_Type, &temp))
+	return NULL;
+
+    po = find_po(self->pan);
+    if (po == NULL) {
+	PyErr_SetString(PyExc_RuntimeError,
+			"replace_panel: can't find Panel Object");
+	return NULL;
+    }
+
+    rtn = replace_panel(self->pan, temp->win);
+    if (rtn == ERR) {
+	PyErr_SetString(PyCursesError, "replace_panel() returned ERR");
+	return NULL;
+    }
+    Py_DECREF(po->wo);
+    po->wo = temp;
+    Py_INCREF(po->wo);
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject *
+PyCursesPanel_set_panel_userptr(PyCursesPanelObject *self, PyObject *obj)
+{
+    Py_INCREF(obj);
+    return PyCursesCheckERR(set_panel_userptr(self->pan, (void*)obj),
+                            "set_panel_userptr");
+}
+
+static PyObject *
+PyCursesPanel_userptr(PyCursesPanelObject *self)
+{
+    PyObject *obj;
+    PyCursesInitialised; 
+    obj = (PyObject *) panel_userptr(self->pan);
+    if (obj == NULL) {
+	PyErr_SetString(PyCursesError, "no userptr set");
+	return NULL;
+    }
+
+    Py_INCREF(obj);
+    return obj;
+}
+
+
+/* Module interface */
+
+static PyMethodDef PyCursesPanel_Methods[] = {
+    {"above",           (PyCFunction)PyCursesPanel_above, METH_NOARGS},
+    {"below",           (PyCFunction)PyCursesPanel_below, METH_NOARGS},
+    {"bottom",          (PyCFunction)PyCursesPanel_bottom_panel, METH_NOARGS},
+    {"hidden",          (PyCFunction)PyCursesPanel_panel_hidden, METH_NOARGS},
+    {"hide",            (PyCFunction)PyCursesPanel_hide_panel, METH_NOARGS},
+    {"move",            (PyCFunction)PyCursesPanel_move_panel, METH_VARARGS},
+    {"replace",         (PyCFunction)PyCursesPanel_replace_panel, METH_VARARGS},
+    {"set_userptr",     (PyCFunction)PyCursesPanel_set_panel_userptr, METH_O},
+    {"show",            (PyCFunction)PyCursesPanel_show_panel, METH_NOARGS},
+    {"top",             (PyCFunction)PyCursesPanel_top_panel, METH_NOARGS},
+    {"userptr",         (PyCFunction)PyCursesPanel_userptr, METH_NOARGS},
+    {"window",          (PyCFunction)PyCursesPanel_window, METH_NOARGS},
+    {NULL,		NULL}   /* sentinel */
+};
+
+static PyObject *
+PyCursesPanel_GetAttr(PyCursesPanelObject *self, char *name)
+{
+    return Py_FindMethod(PyCursesPanel_Methods, (PyObject *)self, name);
+}
+
+/* -------------------------------------------------------*/
+
+PyTypeObject PyCursesPanel_Type = {
+    PyObject_HEAD_INIT(NULL)
+    0,			/*ob_size*/
+    "_curses_panel.curses panel",	/*tp_name*/
+    sizeof(PyCursesPanelObject),	/*tp_basicsize*/
+    0,			/*tp_itemsize*/
+    /* methods */
+    (destructor)PyCursesPanel_Dealloc, /*tp_dealloc*/
+    0,			/*tp_print*/
+    (getattrfunc)PyCursesPanel_GetAttr, /*tp_getattr*/
+    (setattrfunc)0, /*tp_setattr*/
+    0,			/*tp_compare*/
+    0,			/*tp_repr*/
+    0,			/*tp_as_number*/
+    0,			/*tp_as_sequence*/
+    0,			/*tp_as_mapping*/
+    0,			/*tp_hash*/
+};
+
+/* Wrapper for panel_above(NULL). This function returns the bottom
+   panel of the stack, so it's renamed to bottom_panel().
+   panel.above() *requires* a panel object in the first place which
+   may be undesirable. */
+static PyObject *
+PyCurses_bottom_panel(PyObject *self)
+{
+    PANEL *pan;
+    PyCursesPanelObject *po;
+
+    PyCursesInitialised;
+
+    pan = panel_above(NULL);
+
+    if (pan == NULL) {		/* valid output, it means
+				   there's no panel at all */  
+	Py_INCREF(Py_None);
+	return Py_None;
+    }
+    po = find_po(pan);
+    if (po == NULL) {
+	PyErr_SetString(PyExc_RuntimeError,
+			"panel_above: can't find Panel Object");
+	return NULL;
+    }
+    Py_INCREF(po);
+    return (PyObject *)po;
+}
+
+static PyObject *
+PyCurses_new_panel(PyObject *self, PyObject *args)
+{
+    PyCursesWindowObject *win;
+    PANEL *pan;
+
+    if (!PyArg_ParseTuple(args, "O!", &PyCursesWindow_Type, &win))
+        return NULL;
+    pan = new_panel(win->win);
+    if (pan == NULL) {
+	PyErr_SetString(PyCursesError, catchall_NULL);
+	return NULL;
+    }
+    return (PyObject *)PyCursesPanel_New(pan, win);
+}
+
+
+/* Wrapper for panel_below(NULL). This function returns the top panel
+   of the stack, so it's renamed to top_panel(). panel.below()
+   *requires* a panel object in the first place which may be
+   undesirable. */
+static PyObject *
+PyCurses_top_panel(PyObject *self)
+{
+    PANEL *pan;
+    PyCursesPanelObject *po;
+    
+    PyCursesInitialised;
+
+    pan = panel_below(NULL);
+
+    if (pan == NULL) {		/* valid output, it means
+				   there's no panel at all */
+	Py_INCREF(Py_None);
+	return Py_None;
+    }
+    po = find_po(pan);
+    if (po == NULL) {
+	PyErr_SetString(PyExc_RuntimeError,
+			"panel_below: can't find Panel Object");
+	return NULL;
+    }
+    Py_INCREF(po);
+    return (PyObject *)po;
+}
+
+static PyObject *PyCurses_update_panels(PyObject *self)
+{ 
+    PyCursesInitialised;
+    update_panels();
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+
+/* List of functions defined in the module */
+
+static PyMethodDef PyCurses_methods[] = {
+    {"bottom_panel",        (PyCFunction)PyCurses_bottom_panel,  METH_NOARGS},
+    {"new_panel",           (PyCFunction)PyCurses_new_panel,     METH_VARARGS},
+    {"top_panel",           (PyCFunction)PyCurses_top_panel,     METH_NOARGS},
+    {"update_panels",       (PyCFunction)PyCurses_update_panels, METH_NOARGS},
+    {NULL,		NULL}		/* sentinel */
+};
+
+/* Initialization function for the module */
+
+PyMODINIT_FUNC
+init_curses_panel(void)
+{
+    PyObject *m, *d, *v;
+
+    /* Initialize object type */
+    PyCursesPanel_Type.ob_type = &PyType_Type;
+
+    import_curses();
+
+    /* Create the module and add the functions */
+    m = Py_InitModule("_curses_panel", PyCurses_methods);
+    if (m == NULL)
+    	return;
+    d = PyModule_GetDict(m);
+
+    /* For exception _curses_panel.error */
+    PyCursesError = PyErr_NewException("_curses_panel.error", NULL, NULL);
+    PyDict_SetItemString(d, "error", PyCursesError);
+
+    /* Make the version available */
+    v = PyString_FromString(PyCursesVersion);
+    PyDict_SetItemString(d, "version", v);
+    PyDict_SetItemString(d, "__version__", v);
+    Py_DECREF(v);
+}

Added: vendor/Python/current/Modules/_cursesmodule.c
===================================================================
--- vendor/Python/current/Modules/_cursesmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_cursesmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2760 @@
+/*
+ *   This is a curses module for Python.
+ *
+ *   Based on prior work by Lance Ellinghaus and Oliver Andrich
+ *   Version 1.2 of this module: Copyright 1994 by Lance Ellinghouse,
+ *    Cathedral City, California Republic, United States of America.
+ *
+ *   Version 1.5b1, heavily extended for ncurses by Oliver Andrich:
+ *   Copyright 1996,1997 by Oliver Andrich, Koblenz, Germany.
+ *
+ *   Tidied for Python 1.6, and currently maintained by <amk at amk.ca>.
+ *
+ *   Permission is hereby granted, free of charge, to any person obtaining
+ *   a copy of this source file to use, copy, modify, merge, or publish it
+ *   subject to the following conditions:
+ *
+ *   The above copyright notice and this permission notice shall be included
+ *   in all copies or in any new file that contains a substantial portion of
+ *   this file.
+ *
+ *   THE  AUTHOR  MAKES  NO  REPRESENTATIONS ABOUT  THE  SUITABILITY  OF
+ *   THE  SOFTWARE FOR  ANY  PURPOSE.  IT IS  PROVIDED  "AS IS"  WITHOUT
+ *   EXPRESS OR  IMPLIED WARRANTY.  THE AUTHOR DISCLAIMS  ALL WARRANTIES
+ *   WITH  REGARD TO  THIS  SOFTWARE, INCLUDING  ALL IMPLIED  WARRANTIES
+ *   OF   MERCHANTABILITY,  FITNESS   FOR  A   PARTICULAR  PURPOSE   AND
+ *   NON-INFRINGEMENT  OF THIRD  PARTY  RIGHTS. IN  NO  EVENT SHALL  THE
+ *   AUTHOR  BE LIABLE  TO  YOU  OR ANY  OTHER  PARTY  FOR ANY  SPECIAL,
+ *   INDIRECT,  OR  CONSEQUENTIAL  DAMAGES  OR  ANY  DAMAGES  WHATSOEVER
+ *   WHETHER IN AN  ACTION OF CONTRACT, NEGLIGENCE,  STRICT LIABILITY OR
+ *   ANY OTHER  ACTION ARISING OUT OF  OR IN CONNECTION WITH  THE USE OR
+ *   PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* CVS: $Id: _cursesmodule.c 54181 2007-03-06 20:46:26Z walter.doerwald $ */
+
+/*
+
+A number of SysV or ncurses functions don't have wrappers yet; if you need
+a given function, add it and send a patch.  Here's a list of currently
+unsupported functions:
+
+	addchnstr addchstr chgat color_set define_key
+	del_curterm delscreen dupwin inchnstr inchstr innstr keyok
+	mcprint mvaddchnstr mvaddchstr mvchgat mvcur mvinchnstr
+	mvinchstr mvinnstr mmvwaddchnstr mvwaddchstr mvwchgat
+	mvwinchnstr mvwinchstr mvwinnstr newterm
+	restartterm ripoffline scr_dump
+	scr_init scr_restore scr_set scrl set_curterm set_term setterm
+	tgetent tgetflag tgetnum tgetstr tgoto timeout tputs
+	vidattr vidputs waddchnstr waddchstr wchgat
+	wcolor_set winchnstr winchstr winnstr wmouse_trafo wscrl
+
+Low-priority: 
+	slk_attr slk_attr_off slk_attr_on slk_attr_set slk_attroff
+	slk_attron slk_attrset slk_clear slk_color slk_init slk_label
+	slk_noutrefresh slk_refresh slk_restore slk_set slk_touch
+
+Menu extension (ncurses and probably SYSV):
+	current_item free_item free_menu item_count item_description
+	item_index item_init item_name item_opts item_opts_off
+	item_opts_on item_term item_userptr item_value item_visible
+	menu_back menu_driver menu_fore menu_format menu_grey
+	menu_init menu_items menu_mark menu_opts menu_opts_off
+	menu_opts_on menu_pad menu_pattern menu_request_by_name
+	menu_request_name menu_spacing menu_sub menu_term menu_userptr
+	menu_win new_item new_menu pos_menu_cursor post_menu
+	scale_menu set_current_item set_item_init set_item_opts
+	set_item_term set_item_userptr set_item_value set_menu_back
+	set_menu_fore set_menu_format set_menu_grey set_menu_init
+	set_menu_items set_menu_mark set_menu_opts set_menu_pad
+	set_menu_pattern set_menu_spacing set_menu_sub set_menu_term
+	set_menu_userptr set_menu_win set_top_row top_row unpost_menu
+
+Form extension (ncurses and probably SYSV):
+	current_field data_ahead data_behind dup_field
+	dynamic_fieldinfo field_arg field_back field_buffer
+	field_count field_fore field_index field_info field_init
+	field_just field_opts field_opts_off field_opts_on field_pad
+	field_status field_term field_type field_userptr form_driver
+	form_fields form_init form_opts form_opts_off form_opts_on
+	form_page form_request_by_name form_request_name form_sub
+	form_term form_userptr form_win free_field free_form
+	link_field link_fieldtype move_field new_field new_form
+	new_page pos_form_cursor post_form scale_form
+	set_current_field set_field_back set_field_buffer
+	set_field_fore set_field_init set_field_just set_field_opts
+	set_field_pad set_field_status set_field_term set_field_type
+	set_field_userptr set_fieldtype_arg set_fieldtype_choice
+	set_form_fields set_form_init set_form_opts set_form_page
+	set_form_sub set_form_term set_form_userptr set_form_win
+	set_max_field set_new_page unpost_form
+
+
+ */
+
+/* Release Number */
+
+char *PyCursesVersion = "2.2";
+
+/* Includes */
+
+#include "Python.h"
+
+#ifdef __osf__
+#define STRICT_SYSV_CURSES      /* Don't use ncurses extensions */
+#endif
+
+#ifdef __hpux
+#define STRICT_SYSV_CURSES
+#endif
+
+#define CURSES_MODULE
+#include "py_curses.h"
+
+/*  These prototypes are in <term.h>, but including this header 
+    #defines many common symbols (such as "lines") which breaks the 
+    curses module in other ways.  So the code will just specify 
+    explicit prototypes here. */
+extern int setupterm(char *,int,int *);
+#ifdef __sgi
+#include <term.h>
+#endif
+
+#if !defined(HAVE_NCURSES_H) && (defined(sgi) || defined(__sun) || defined(SCO5))
+#define STRICT_SYSV_CURSES       /* Don't use ncurses extensions */
+typedef chtype attr_t;           /* No attr_t type is available */
+#endif
+
+#if defined(_AIX)
+#define STRICT_SYSV_CURSES
+#endif
+
+/* Definition of exception curses.error */
+
+static PyObject *PyCursesError;
+
+/* Tells whether setupterm() has been called to initialise terminfo.  */
+static int initialised_setupterm = FALSE;
+
+/* Tells whether initscr() has been called to initialise curses.  */
+static int initialised = FALSE;
+
+/* Tells whether start_color() has been called to initialise color usage. */
+static int initialisedcolors = FALSE;
+
+/* Utility Macros */
+#define PyCursesSetupTermCalled \
+  if (initialised_setupterm != TRUE) { \
+                  PyErr_SetString(PyCursesError, \
+                                  "must call (at least) setupterm() first"); \
+                  return 0; }
+
+#define PyCursesInitialised \
+  if (initialised != TRUE) { \
+                  PyErr_SetString(PyCursesError, \
+                                  "must call initscr() first"); \
+                  return 0; }
+
+#define PyCursesInitialisedColor \
+  if (initialisedcolors != TRUE) { \
+                  PyErr_SetString(PyCursesError, \
+                                  "must call start_color() first"); \
+                  return 0; }
+
+#ifndef MIN
+#define MIN(x,y) ((x) < (y) ? (x) : (y))
+#endif
+
+/* Utility Functions */
+
+/*
+ * Check the return code from a curses function and return None 
+ * or raise an exception as appropriate.  These are exported using the
+ * CObject API. 
+ */
+
+static PyObject *
+PyCursesCheckERR(int code, char *fname)
+{
+  if (code != ERR) {
+    Py_INCREF(Py_None);
+    return Py_None;
+  } else {
+    if (fname == NULL) {
+      PyErr_SetString(PyCursesError, catchall_ERR);
+    } else {
+      PyErr_Format(PyCursesError, "%s() returned ERR", fname);
+    }
+    return NULL;
+  }
+}
+
+static int 
+PyCurses_ConvertToChtype(PyObject *obj, chtype *ch)
+{
+  if (PyInt_Check(obj)) {
+    *ch = (chtype) PyInt_AsLong(obj);
+  } else if(PyString_Check(obj) 
+	    && (PyString_Size(obj) == 1)) {
+    *ch = (chtype) *PyString_AsString(obj);
+  } else {
+    return 0;
+  }
+  return 1;
+}
+
+/* Function versions of the 3 functions for tested whether curses has been
+   initialised or not. */
+   
+static int func_PyCursesSetupTermCalled(void)
+{
+    PyCursesSetupTermCalled;
+    return 1;
+}
+
+static int func_PyCursesInitialised(void)
+{
+    PyCursesInitialised;
+    return 1;
+}
+
+static int func_PyCursesInitialisedColor(void)
+{
+    PyCursesInitialisedColor;
+    return 1;
+}
+
+/*****************************************************************************
+ The Window Object
+******************************************************************************/
+
+/* Definition of the window type */
+
+PyTypeObject PyCursesWindow_Type;
+
+/* Function prototype macros for Window object
+
+   X - function name
+   TYPE - parameter Type
+   ERGSTR - format string for construction of the return value
+   PARSESTR - format string for argument parsing
+   */
+
+#define Window_NoArgNoReturnFunction(X) \
+static PyObject *PyCursesWindow_ ## X (PyCursesWindowObject *self, PyObject *args) \
+{ return PyCursesCheckERR(X(self->win), # X); }
+
+#define Window_NoArgTrueFalseFunction(X) \
+static PyObject * PyCursesWindow_ ## X (PyCursesWindowObject *self) \
+{ \
+  if (X (self->win) == FALSE) { Py_INCREF(Py_False); return Py_False; } \
+  else { Py_INCREF(Py_True); return Py_True; } }
+
+#define Window_NoArgNoReturnVoidFunction(X) \
+static PyObject * PyCursesWindow_ ## X (PyCursesWindowObject *self) \
+{ \
+  X(self->win); Py_INCREF(Py_None); return Py_None; }
+
+#define Window_NoArg2TupleReturnFunction(X, TYPE, ERGSTR) \
+static PyObject * PyCursesWindow_ ## X (PyCursesWindowObject *self) \
+{ \
+  TYPE arg1, arg2; \
+  X(self->win,arg1,arg2); return Py_BuildValue(ERGSTR, arg1, arg2); } 
+
+#define Window_OneArgNoReturnVoidFunction(X, TYPE, PARSESTR) \
+static PyObject * PyCursesWindow_ ## X (PyCursesWindowObject *self, PyObject *args) \
+{ \
+  TYPE arg1; \
+  if (!PyArg_ParseTuple(args, PARSESTR, &arg1)) return NULL; \
+  X(self->win,arg1); Py_INCREF(Py_None); return Py_None; }
+
+#define Window_OneArgNoReturnFunction(X, TYPE, PARSESTR) \
+static PyObject * PyCursesWindow_ ## X (PyCursesWindowObject *self, PyObject *args) \
+{ \
+  TYPE arg1; \
+  if (!PyArg_ParseTuple(args,PARSESTR, &arg1)) return NULL; \
+  return PyCursesCheckERR(X(self->win, arg1), # X); }
+
+#define Window_TwoArgNoReturnFunction(X, TYPE, PARSESTR) \
+static PyObject * PyCursesWindow_ ## X (PyCursesWindowObject *self, PyObject *args) \
+{ \
+  TYPE arg1, arg2; \
+  if (!PyArg_ParseTuple(args,PARSESTR, &arg1, &arg2)) return NULL; \
+  return PyCursesCheckERR(X(self->win, arg1, arg2), # X); }
+
+/* ------------- WINDOW routines --------------- */
+
+Window_NoArgNoReturnFunction(untouchwin)
+Window_NoArgNoReturnFunction(touchwin)
+Window_NoArgNoReturnFunction(redrawwin)
+Window_NoArgNoReturnFunction(winsertln)
+Window_NoArgNoReturnFunction(werase)
+Window_NoArgNoReturnFunction(wdeleteln)
+
+Window_NoArgTrueFalseFunction(is_wintouched)
+
+Window_NoArgNoReturnVoidFunction(wsyncup)
+Window_NoArgNoReturnVoidFunction(wsyncdown)
+Window_NoArgNoReturnVoidFunction(wstandend)
+Window_NoArgNoReturnVoidFunction(wstandout)
+Window_NoArgNoReturnVoidFunction(wcursyncup)
+Window_NoArgNoReturnVoidFunction(wclrtoeol)
+Window_NoArgNoReturnVoidFunction(wclrtobot)
+Window_NoArgNoReturnVoidFunction(wclear)
+
+Window_OneArgNoReturnVoidFunction(idcok, int, "i;True(1) or False(0)")
+Window_OneArgNoReturnVoidFunction(immedok, int, "i;True(1) or False(0)")
+Window_OneArgNoReturnVoidFunction(wtimeout, int, "i;delay")
+
+Window_NoArg2TupleReturnFunction(getyx, int, "ii")
+Window_NoArg2TupleReturnFunction(getbegyx, int, "ii")
+Window_NoArg2TupleReturnFunction(getmaxyx, int, "ii")
+Window_NoArg2TupleReturnFunction(getparyx, int, "ii")
+
+Window_OneArgNoReturnFunction(wattron, attr_t, "l;attr")
+Window_OneArgNoReturnFunction(wattroff, attr_t, "l;attr")
+Window_OneArgNoReturnFunction(wattrset, attr_t, "l;attr")
+Window_OneArgNoReturnFunction(clearok, int, "i;True(1) or False(0)")
+Window_OneArgNoReturnFunction(idlok, int, "i;True(1) or False(0)")
+#if defined(__NetBSD__)
+Window_OneArgNoReturnVoidFunction(keypad, int, "i;True(1) or False(0)")
+#else
+Window_OneArgNoReturnFunction(keypad, int, "i;True(1) or False(0)")
+#endif
+Window_OneArgNoReturnFunction(leaveok, int, "i;True(1) or False(0)")
+#if defined(__NetBSD__)
+Window_OneArgNoReturnVoidFunction(nodelay, int, "i;True(1) or False(0)")
+#else
+Window_OneArgNoReturnFunction(nodelay, int, "i;True(1) or False(0)")
+#endif
+Window_OneArgNoReturnFunction(notimeout, int, "i;True(1) or False(0)")
+Window_OneArgNoReturnFunction(scrollok, int, "i;True(1) or False(0)")
+Window_OneArgNoReturnFunction(winsdelln, int, "i;nlines")
+Window_OneArgNoReturnFunction(syncok, int, "i;True(1) or False(0)")
+
+Window_TwoArgNoReturnFunction(mvwin, int, "ii;y,x")
+Window_TwoArgNoReturnFunction(mvderwin, int, "ii;y,x")
+Window_TwoArgNoReturnFunction(wmove, int, "ii;y,x")
+#ifndef STRICT_SYSV_CURSES
+Window_TwoArgNoReturnFunction(wresize, int, "ii;lines,columns")
+#endif
+
+/* Allocation and deallocation of Window Objects */
+
+static PyObject *
+PyCursesWindow_New(WINDOW *win)
+{
+	PyCursesWindowObject *wo;
+
+	wo = PyObject_NEW(PyCursesWindowObject, &PyCursesWindow_Type);
+	if (wo == NULL) return NULL;
+	wo->win = win;
+	return (PyObject *)wo;
+}
+
+static void
+PyCursesWindow_Dealloc(PyCursesWindowObject *wo)
+{
+  if (wo->win != stdscr) delwin(wo->win);
+  PyObject_DEL(wo);
+}
+
+/* Addch, Addstr, Addnstr */
+
+static PyObject *
+PyCursesWindow_AddCh(PyCursesWindowObject *self, PyObject *args)
+{
+  int rtn, x, y, use_xy = FALSE;
+  PyObject *temp;
+  chtype ch = 0;
+  attr_t attr = A_NORMAL;
+  
+  switch (PyTuple_Size(args)) {
+  case 1:
+    if (!PyArg_ParseTuple(args, "O;ch or int", &temp))
+	  return NULL;
+    break;
+  case 2:
+    if (!PyArg_ParseTuple(args, "Ol;ch or int,attr", &temp, &attr))
+      return NULL;
+    break;
+  case 3:
+    if (!PyArg_ParseTuple(args,"iiO;y,x,ch or int", &y, &x, &temp))
+      return NULL;
+    use_xy = TRUE;
+    break;
+  case 4:
+    if (!PyArg_ParseTuple(args,"iiOl;y,x,ch or int, attr", 
+		     &y, &x, &temp, &attr))
+      return NULL;
+    use_xy = TRUE;
+    break;
+  default:
+    PyErr_SetString(PyExc_TypeError, "addch requires 1 to 4 arguments");
+    return NULL;
+  }
+
+  if (!PyCurses_ConvertToChtype(temp, &ch)) {
+    PyErr_SetString(PyExc_TypeError, "argument 1 or 3 must be a ch or an int");
+    return NULL;
+  }
+  
+  if (use_xy == TRUE)
+    rtn = mvwaddch(self->win,y,x, ch | attr);
+  else {
+    rtn = waddch(self->win, ch | attr);
+  }
+  return PyCursesCheckERR(rtn, "addch");
+}
+
+static PyObject *
+PyCursesWindow_AddStr(PyCursesWindowObject *self, PyObject *args)
+{
+  int rtn;
+  int x, y;
+  char *str;
+  attr_t attr = A_NORMAL , attr_old = A_NORMAL;
+  int use_xy = FALSE, use_attr = FALSE;
+
+  switch (PyTuple_Size(args)) {
+  case 1:
+    if (!PyArg_ParseTuple(args,"s;str", &str))
+      return NULL;
+    break;
+  case 2:
+    if (!PyArg_ParseTuple(args,"sl;str,attr", &str, &attr))
+      return NULL;
+    use_attr = TRUE;
+    break;
+  case 3:
+    if (!PyArg_ParseTuple(args,"iis;int,int,str", &y, &x, &str))
+      return NULL;
+    use_xy = TRUE;
+    break;
+  case 4:
+    if (!PyArg_ParseTuple(args,"iisl;int,int,str,attr", &y, &x, &str, &attr))
+      return NULL;
+    use_xy = use_attr = TRUE;
+    break;
+  default:
+    PyErr_SetString(PyExc_TypeError, "addstr requires 1 to 4 arguments");
+    return NULL;
+  }
+
+  if (use_attr == TRUE) {
+    attr_old = getattrs(self->win);
+    wattrset(self->win,attr);
+  }
+  if (use_xy == TRUE)
+    rtn = mvwaddstr(self->win,y,x,str);
+  else
+    rtn = waddstr(self->win,str);
+  if (use_attr == TRUE)
+    wattrset(self->win,attr_old);
+  return PyCursesCheckERR(rtn, "addstr");
+}
+
+static PyObject *
+PyCursesWindow_AddNStr(PyCursesWindowObject *self, PyObject *args)
+{
+  int rtn, x, y, n;
+  char *str;
+  attr_t attr = A_NORMAL , attr_old = A_NORMAL;
+  int use_xy = FALSE, use_attr = FALSE;
+
+  switch (PyTuple_Size(args)) {
+  case 2:
+    if (!PyArg_ParseTuple(args,"si;str,n", &str, &n))
+      return NULL;
+    break;
+  case 3:
+    if (!PyArg_ParseTuple(args,"sil;str,n,attr", &str, &n, &attr))
+      return NULL;
+    use_attr = TRUE;
+    break;
+  case 4:
+    if (!PyArg_ParseTuple(args,"iisi;y,x,str,n", &y, &x, &str, &n))
+      return NULL;
+    use_xy = TRUE;
+    break;
+  case 5:
+    if (!PyArg_ParseTuple(args,"iisil;y,x,str,n,attr", &y, &x, &str, &n, &attr))
+      return NULL;
+    use_xy = use_attr = TRUE;
+    break;
+  default:
+    PyErr_SetString(PyExc_TypeError, "addnstr requires 2 to 5 arguments");
+    return NULL;
+  }
+
+  if (use_attr == TRUE) {
+    attr_old = getattrs(self->win);
+    wattrset(self->win,attr);
+  }
+  if (use_xy == TRUE)
+    rtn = mvwaddnstr(self->win,y,x,str,n);
+  else
+    rtn = waddnstr(self->win,str,n);
+  if (use_attr == TRUE)
+    wattrset(self->win,attr_old);
+  return PyCursesCheckERR(rtn, "addnstr");
+}
+
+static PyObject *
+PyCursesWindow_Bkgd(PyCursesWindowObject *self, PyObject *args)
+{
+  PyObject *temp;
+  chtype bkgd;
+  attr_t attr = A_NORMAL;
+
+  switch (PyTuple_Size(args)) {
+    case 1:
+      if (!PyArg_ParseTuple(args, "O;ch or int", &temp))
+        return NULL;
+      break;
+    case 2:
+      if (!PyArg_ParseTuple(args,"Ol;ch or int,attr", &temp, &attr))
+        return NULL;
+      break;
+    default:
+      PyErr_SetString(PyExc_TypeError, "bkgd requires 1 or 2 arguments");
+      return NULL;
+  }
+
+  if (!PyCurses_ConvertToChtype(temp, &bkgd)) {
+    PyErr_SetString(PyExc_TypeError, "argument 1 or 3 must be a ch or an int");
+    return NULL;
+  }
+
+  return PyCursesCheckERR(wbkgd(self->win, bkgd | attr), "bkgd");
+}
+
+static PyObject *
+PyCursesWindow_BkgdSet(PyCursesWindowObject *self, PyObject *args)
+{
+  PyObject *temp;
+  chtype bkgd;
+  attr_t attr = A_NORMAL;
+
+  switch (PyTuple_Size(args)) {
+    case 1:
+      if (!PyArg_ParseTuple(args, "O;ch or int", &temp))
+        return NULL;
+      break;
+    case 2:
+      if (!PyArg_ParseTuple(args,"Ol;ch or int,attr", &temp, &attr))
+        return NULL;
+      break;
+    default:
+      PyErr_SetString(PyExc_TypeError, "bkgdset requires 1 or 2 arguments");
+      return NULL;
+  }
+
+  if (!PyCurses_ConvertToChtype(temp, &bkgd)) {
+    PyErr_SetString(PyExc_TypeError, "argument 1 must be a ch or an int");
+    return NULL;
+  }
+
+  wbkgdset(self->win, bkgd | attr);
+  return PyCursesCheckERR(0, "bkgdset");
+}
+
+static PyObject *
+PyCursesWindow_Border(PyCursesWindowObject *self, PyObject *args)
+{
+  PyObject *temp[8];
+  chtype ch[8];
+  int i;
+
+  /* Clear the array of parameters */
+  for(i=0; i<8; i++) {
+       temp[i] = NULL;
+       ch[i] = 0;
+  }    
+  
+  if (!PyArg_ParseTuple(args,"|OOOOOOOO;ls,rs,ts,bs,tl,tr,bl,br",
+                        &temp[0], &temp[1], &temp[2], &temp[3],
+                        &temp[4], &temp[5], &temp[6], &temp[7]))
+    return NULL;
+
+  for(i=0; i<8; i++) {
+      if (temp[i] != NULL && !PyCurses_ConvertToChtype(temp[i], &ch[i])) {
+          PyErr_Format(PyExc_TypeError,
+                       "argument %i must be a ch or an int", i+1);
+          return NULL;
+      }
+  }
+  
+  wborder(self->win,
+          ch[0], ch[1], ch[2], ch[3],
+          ch[4], ch[5], ch[6], ch[7]);
+  Py_INCREF(Py_None);
+  return Py_None;
+}
+
+static PyObject *
+PyCursesWindow_Box(PyCursesWindowObject *self, PyObject *args)
+{
+  chtype ch1=0,ch2=0;
+  switch(PyTuple_Size(args)){
+  case 0: break;
+  default:
+    if (!PyArg_ParseTuple(args,"ll;vertint,horint", &ch1, &ch2))
+      return NULL;
+  }
+  box(self->win,ch1,ch2);
+  Py_INCREF(Py_None);
+  return Py_None;
+}
+
+#if defined(HAVE_NCURSES_H) || defined(MVWDELCH_IS_EXPRESSION)
+#define py_mvwdelch mvwdelch
+#else
+int py_mvwdelch(WINDOW *w, int y, int x)
+{
+  mvwdelch(w,y,x);
+  /* On HP/UX, mvwdelch already returns. On other systems,
+     we may well run into this return statement. */
+  return 0;
+}
+#endif
+
+
+static PyObject *
+PyCursesWindow_DelCh(PyCursesWindowObject *self, PyObject *args)
+{
+  int rtn;
+  int x, y;
+
+  switch (PyTuple_Size(args)) {
+  case 0:
+    rtn = wdelch(self->win);
+    break;
+  case 2:
+    if (!PyArg_ParseTuple(args,"ii;y,x", &y, &x))
+      return NULL;
+    rtn = py_mvwdelch(self->win,y,x);
+    break;
+  default:
+    PyErr_SetString(PyExc_TypeError, "delch requires 0 or 2 arguments");
+    return NULL;
+  }
+  return PyCursesCheckERR(rtn, "[mv]wdelch");
+}
+
+static PyObject *
+PyCursesWindow_DerWin(PyCursesWindowObject *self, PyObject *args)
+{
+  WINDOW *win;
+  int nlines, ncols, begin_y, begin_x;
+
+  nlines = 0;
+  ncols  = 0;
+  switch (PyTuple_Size(args)) {
+  case 2:
+    if (!PyArg_ParseTuple(args,"ii;begin_y,begin_x",&begin_y,&begin_x))
+      return NULL;
+    break;
+  case 4:
+    if (!PyArg_ParseTuple(args, "iiii;nlines,ncols,begin_y,begin_x",
+		   &nlines,&ncols,&begin_y,&begin_x))
+      return NULL;
+    break;
+  default:
+    PyErr_SetString(PyExc_TypeError, "derwin requires 2 or 4 arguments");
+    return NULL;
+  }
+
+  win = derwin(self->win,nlines,ncols,begin_y,begin_x);
+
+  if (win == NULL) {
+    PyErr_SetString(PyCursesError, catchall_NULL);
+    return NULL;
+  }
+
+  return (PyObject *)PyCursesWindow_New(win);
+}
+
+static PyObject *
+PyCursesWindow_EchoChar(PyCursesWindowObject *self, PyObject *args)
+{
+  PyObject *temp;
+  chtype ch;
+  attr_t attr = A_NORMAL;
+
+  switch (PyTuple_Size(args)) {
+  case 1:
+    if (!PyArg_ParseTuple(args,"O;ch or int", &temp))
+      return NULL;
+    break;
+  case 2:
+    if (!PyArg_ParseTuple(args,"Ol;ch or int,attr", &temp, &attr))
+      return NULL;
+    break;
+  default:
+    PyErr_SetString(PyExc_TypeError, "echochar requires 1 or 2 arguments");
+
+
+    return NULL;
+  }
+
+  if (!PyCurses_ConvertToChtype(temp, &ch)) {
+    PyErr_SetString(PyExc_TypeError, "argument 1 must be a ch or an int");
+    return NULL;
+  }
+  
+#ifdef WINDOW_HAS_FLAGS
+  if (self->win->_flags & _ISPAD)
+    return PyCursesCheckERR(pechochar(self->win, ch | attr), 
+			    "echochar");
+  else
+#endif
+    return PyCursesCheckERR(wechochar(self->win, ch | attr), 
+			    "echochar");
+}
+
+#ifdef NCURSES_MOUSE_VERSION
+static PyObject *
+PyCursesWindow_Enclose(PyCursesWindowObject *self, PyObject *args)
+{
+	int x, y;
+	if (!PyArg_ParseTuple(args,"ii;y,x", &y, &x))
+		return NULL;
+
+	return PyInt_FromLong( wenclose(self->win,y,x) );
+}
+#endif
+
+static PyObject *
+PyCursesWindow_GetBkgd(PyCursesWindowObject *self)
+{
+  return PyInt_FromLong((long) getbkgd(self->win));
+}
+
+static PyObject *
+PyCursesWindow_GetCh(PyCursesWindowObject *self, PyObject *args)
+{
+  int x, y;
+  int rtn;
+
+  switch (PyTuple_Size(args)) {
+  case 0:
+    Py_BEGIN_ALLOW_THREADS
+    rtn = wgetch(self->win);
+    Py_END_ALLOW_THREADS
+    break;
+  case 2:
+    if (!PyArg_ParseTuple(args,"ii;y,x",&y,&x))
+      return NULL;
+    Py_BEGIN_ALLOW_THREADS
+    rtn = mvwgetch(self->win,y,x);
+    Py_END_ALLOW_THREADS
+    break;
+  default:
+    PyErr_SetString(PyExc_TypeError, "getch requires 0 or 2 arguments");
+    return NULL;
+  }
+  return PyInt_FromLong((long)rtn);
+}
+
+static PyObject *
+PyCursesWindow_GetKey(PyCursesWindowObject *self, PyObject *args)
+{
+  int x, y;
+  int rtn;
+
+  switch (PyTuple_Size(args)) {
+  case 0:
+    Py_BEGIN_ALLOW_THREADS
+    rtn = wgetch(self->win);
+    Py_END_ALLOW_THREADS
+    break;
+  case 2:
+    if (!PyArg_ParseTuple(args,"ii;y,x",&y,&x))
+      return NULL;
+    Py_BEGIN_ALLOW_THREADS
+    rtn = mvwgetch(self->win,y,x);
+    Py_END_ALLOW_THREADS
+    break;
+  default:
+    PyErr_SetString(PyExc_TypeError, "getkey requires 0 or 2 arguments");
+    return NULL;
+  }
+  if (rtn == ERR) {
+    /* getch() returns ERR in nodelay mode */
+    PyErr_SetString(PyCursesError, "no input");
+    return NULL;
+  } else if (rtn<=255)
+    return Py_BuildValue("c", rtn);
+  else
+#if defined(__NetBSD__)
+    return PyString_FromString(unctrl(rtn));
+#else
+    return PyString_FromString((char *)keyname(rtn));
+#endif
+}
+
+static PyObject *
+PyCursesWindow_GetStr(PyCursesWindowObject *self, PyObject *args)
+{
+  int x, y, n;
+  char rtn[1024]; /* This should be big enough.. I hope */
+  int rtn2;
+
+  switch (PyTuple_Size(args)) {
+  case 0:
+    Py_BEGIN_ALLOW_THREADS
+    rtn2 = wgetnstr(self->win,rtn, 1023);
+    Py_END_ALLOW_THREADS
+    break;
+  case 1:
+    if (!PyArg_ParseTuple(args,"i;n", &n))
+      return NULL;
+    Py_BEGIN_ALLOW_THREADS
+    rtn2 = wgetnstr(self->win,rtn,MIN(n, 1023));
+    Py_END_ALLOW_THREADS
+    break;
+  case 2:
+    if (!PyArg_ParseTuple(args,"ii;y,x",&y,&x))
+      return NULL;
+    Py_BEGIN_ALLOW_THREADS
+#ifdef STRICT_SYSV_CURSES
+    rtn2 = wmove(self->win,y,x)==ERR ? ERR : wgetnstr(self->win, rtn, 1023);
+#else
+    rtn2 = mvwgetnstr(self->win,y,x,rtn, 1023);
+#endif
+    Py_END_ALLOW_THREADS
+    break;
+  case 3:
+    if (!PyArg_ParseTuple(args,"iii;y,x,n", &y, &x, &n))
+      return NULL;
+#ifdef STRICT_SYSV_CURSES
+    Py_BEGIN_ALLOW_THREADS
+    rtn2 = wmove(self->win,y,x)==ERR ? ERR :
+      wgetnstr(self->win, rtn, MIN(n, 1023));
+    Py_END_ALLOW_THREADS
+#else
+    Py_BEGIN_ALLOW_THREADS
+    rtn2 = mvwgetnstr(self->win, y, x, rtn, MIN(n, 1023));
+    Py_END_ALLOW_THREADS
+#endif
+    break;
+  default:
+    PyErr_SetString(PyExc_TypeError, "getstr requires 0 to 3 arguments");
+    return NULL;
+  }
+  if (rtn2 == ERR)
+    rtn[0] = 0;
+  return PyString_FromString(rtn);
+}
+
+static PyObject *
+PyCursesWindow_Hline(PyCursesWindowObject *self, PyObject *args)
+{
+  PyObject *temp;
+  chtype ch;
+  int n, x, y, code = OK;
+  attr_t attr = A_NORMAL;
+
+  switch (PyTuple_Size(args)) {
+  case 2:
+    if (!PyArg_ParseTuple(args, "Oi;ch or int,n", &temp, &n))
+      return NULL;
+    break;
+  case 3:
+    if (!PyArg_ParseTuple(args, "Oil;ch or int,n,attr", &temp, &n, &attr))
+      return NULL;
+    break;
+  case 4:
+    if (!PyArg_ParseTuple(args, "iiOi;y,x,ch or int,n", &y, &x, &temp, &n))
+      return NULL;
+    code = wmove(self->win, y, x);
+    break;
+  case 5:
+    if (!PyArg_ParseTuple(args, "iiOil; y,x,ch or int,n,attr", 
+		     &y, &x, &temp, &n, &attr))
+      return NULL;
+    code = wmove(self->win, y, x);
+    break;
+  default:
+    PyErr_SetString(PyExc_TypeError, "hline requires 2 to 5 arguments");
+    return NULL;
+  }
+
+  if (code != ERR) {
+    if (!PyCurses_ConvertToChtype(temp, &ch)) {
+      PyErr_SetString(PyExc_TypeError, 
+		      "argument 1 or 3 must be a ch or an int");
+      return NULL;
+    }
+    return PyCursesCheckERR(whline(self->win, ch | attr, n), "hline");
+  } else 
+    return PyCursesCheckERR(code, "wmove");
+}
+
+static PyObject *
+PyCursesWindow_InsCh(PyCursesWindowObject *self, PyObject *args)
+{
+  int rtn, x, y, use_xy = FALSE;
+  PyObject *temp;
+  chtype ch = 0;
+  attr_t attr = A_NORMAL;
+  
+  switch (PyTuple_Size(args)) {
+  case 1:
+    if (!PyArg_ParseTuple(args, "O;ch or int", &temp))
+      return NULL;
+    break;
+  case 2:
+    if (!PyArg_ParseTuple(args, "Ol;ch or int,attr", &temp, &attr))
+      return NULL;
+    break;
+  case 3:
+    if (!PyArg_ParseTuple(args,"iiO;y,x,ch or int", &y, &x, &temp))
+      return NULL;
+    use_xy = TRUE;
+    break;
+  case 4:
+    if (!PyArg_ParseTuple(args,"iiOl;y,x,ch or int, attr", &y, &x, &temp, &attr))
+      return NULL;
+    use_xy = TRUE;
+    break;
+  default:
+    PyErr_SetString(PyExc_TypeError, "insch requires 1 or 4 arguments");
+    return NULL;
+  }
+
+  if (!PyCurses_ConvertToChtype(temp, &ch)) {
+    PyErr_SetString(PyExc_TypeError, 
+		    "argument 1 or 3 must be a ch or an int");
+    return NULL;
+  }
+  
+  if (use_xy == TRUE)
+    rtn = mvwinsch(self->win,y,x, ch | attr);
+  else {
+    rtn = winsch(self->win, ch | attr);
+  }
+  return PyCursesCheckERR(rtn, "insch");
+}
+
+static PyObject *
+PyCursesWindow_InCh(PyCursesWindowObject *self, PyObject *args)
+{
+  int x, y, rtn;
+
+  switch (PyTuple_Size(args)) {
+  case 0:
+    rtn = winch(self->win);
+    break;
+  case 2:
+    if (!PyArg_ParseTuple(args,"ii;y,x",&y,&x))
+      return NULL;
+    rtn = mvwinch(self->win,y,x);
+    break;
+  default:
+    PyErr_SetString(PyExc_TypeError, "inch requires 0 or 2 arguments");
+    return NULL;
+  }
+  return PyInt_FromLong((long) rtn);
+}
+
+static PyObject *
+PyCursesWindow_InStr(PyCursesWindowObject *self, PyObject *args)
+{
+  int x, y, n;
+  char rtn[1024]; /* This should be big enough.. I hope */
+  int rtn2;
+
+  switch (PyTuple_Size(args)) {
+  case 0:
+    rtn2 = winnstr(self->win,rtn, 1023);
+    break;
+  case 1:
+    if (!PyArg_ParseTuple(args,"i;n", &n))
+      return NULL;
+    rtn2 = winnstr(self->win,rtn,MIN(n,1023));
+    break;
+  case 2:
+    if (!PyArg_ParseTuple(args,"ii;y,x",&y,&x))
+      return NULL;
+    rtn2 = mvwinnstr(self->win,y,x,rtn,1023);
+    break;
+  case 3:
+    if (!PyArg_ParseTuple(args, "iii;y,x,n", &y, &x, &n))
+      return NULL;
+    rtn2 = mvwinnstr(self->win, y, x, rtn, MIN(n,1023));
+    break;
+  default:
+    PyErr_SetString(PyExc_TypeError, "instr requires 0 or 3 arguments");
+    return NULL;
+  }
+  if (rtn2 == ERR)
+    rtn[0] = 0;
+  return PyString_FromString(rtn);
+}
+
+static PyObject *
+PyCursesWindow_InsStr(PyCursesWindowObject *self, PyObject *args)
+{
+  int rtn;
+  int x, y;
+  char *str;
+  attr_t attr = A_NORMAL , attr_old = A_NORMAL;
+  int use_xy = FALSE, use_attr = FALSE;
+
+  switch (PyTuple_Size(args)) {
+  case 1:
+    if (!PyArg_ParseTuple(args,"s;str", &str))
+      return NULL;
+    break;
+  case 2:
+    if (!PyArg_ParseTuple(args,"sl;str,attr", &str, &attr))
+      return NULL;
+    use_attr = TRUE;
+    break;
+  case 3:
+    if (!PyArg_ParseTuple(args,"iis;y,x,str", &y, &x, &str))
+      return NULL;
+    use_xy = TRUE;
+    break;
+  case 4:
+    if (!PyArg_ParseTuple(args,"iisl;y,x,str,attr", &y, &x, &str, &attr))
+      return NULL;
+    use_xy = use_attr = TRUE;
+    break;
+  default:
+    PyErr_SetString(PyExc_TypeError, "insstr requires 1 to 4 arguments");
+    return NULL;
+  }
+
+  if (use_attr == TRUE) {
+    attr_old = getattrs(self->win);
+    wattrset(self->win,attr);
+  }
+  if (use_xy == TRUE)
+    rtn = mvwinsstr(self->win,y,x,str);
+  else
+    rtn = winsstr(self->win,str);
+  if (use_attr == TRUE)
+    wattrset(self->win,attr_old);
+  return PyCursesCheckERR(rtn, "insstr");
+}
+
+static PyObject *
+PyCursesWindow_InsNStr(PyCursesWindowObject *self, PyObject *args)
+{
+  int rtn, x, y, n;
+  char *str;
+  attr_t attr = A_NORMAL , attr_old = A_NORMAL;
+  int use_xy = FALSE, use_attr = FALSE;
+
+  switch (PyTuple_Size(args)) {
+  case 2:
+    if (!PyArg_ParseTuple(args,"si;str,n", &str, &n))
+      return NULL;
+    break;
+  case 3:
+    if (!PyArg_ParseTuple(args,"sil;str,n,attr", &str, &n, &attr))
+      return NULL;
+    use_attr = TRUE;
+    break;
+  case 4:
+    if (!PyArg_ParseTuple(args,"iisi;y,x,str,n", &y, &x, &str, &n))
+      return NULL;
+    use_xy = TRUE;
+    break;
+  case 5:
+    if (!PyArg_ParseTuple(args,"iisil;y,x,str,n,attr", &y, &x, &str, &n, &attr))
+      return NULL;
+    use_xy = use_attr = TRUE;
+    break;
+  default:
+    PyErr_SetString(PyExc_TypeError, "insnstr requires 2 to 5 arguments");
+    return NULL;
+  }
+
+  if (use_attr == TRUE) {
+    attr_old = getattrs(self->win);
+    wattrset(self->win,attr);
+  }
+  if (use_xy == TRUE)
+    rtn = mvwinsnstr(self->win,y,x,str,n);
+  else
+    rtn = winsnstr(self->win,str,n);
+  if (use_attr == TRUE)
+    wattrset(self->win,attr_old);
+  return PyCursesCheckERR(rtn, "insnstr");
+}
+
+static PyObject *
+PyCursesWindow_Is_LineTouched(PyCursesWindowObject *self, PyObject *args)
+{
+  int line, erg;
+  if (!PyArg_ParseTuple(args,"i;line", &line))
+    return NULL;
+  erg = is_linetouched(self->win, line);
+  if (erg == ERR) {
+    PyErr_SetString(PyExc_TypeError, 
+		    "is_linetouched: line number outside of boundaries");
+    return NULL;
+  } else 
+    if (erg == FALSE) {
+      Py_INCREF(Py_False);
+      return Py_False;
+    } else {
+      Py_INCREF(Py_True);
+      return Py_True;
+    }
+}
+
+static PyObject *
+PyCursesWindow_NoOutRefresh(PyCursesWindowObject *self, PyObject *args)
+{
+  int pminrow,pmincol,sminrow,smincol,smaxrow,smaxcol;
+  int rtn;
+
+#ifndef WINDOW_HAS_FLAGS
+  if (0) {
+#else
+  if (self->win->_flags & _ISPAD) {
+#endif
+    switch(PyTuple_Size(args)) {
+    case 6:
+      if (!PyArg_ParseTuple(args, 
+		       "iiiiii;" \
+		       "pminrow,pmincol,sminrow,smincol,smaxrow,smaxcol", 
+		       &pminrow, &pmincol, &sminrow, 
+		       &smincol, &smaxrow, &smaxcol))
+	return NULL;
+      Py_BEGIN_ALLOW_THREADS
+      rtn = pnoutrefresh(self->win,
+			 pminrow, pmincol, sminrow, 
+			 smincol, smaxrow, smaxcol);
+      Py_END_ALLOW_THREADS
+      return PyCursesCheckERR(rtn, "pnoutrefresh");
+    default:
+      PyErr_SetString(PyCursesError, 
+		      "noutrefresh() called for a pad " 
+		      "requires 6 arguments");
+      return NULL;
+    }
+  } else {
+    if (!PyArg_ParseTuple(args, ":noutrefresh"))
+      return NULL;    
+
+    Py_BEGIN_ALLOW_THREADS
+    rtn = wnoutrefresh(self->win);
+    Py_END_ALLOW_THREADS
+    return PyCursesCheckERR(rtn, "wnoutrefresh");
+  }
+}
+
+static PyObject *
+PyCursesWindow_Overlay(PyCursesWindowObject *self, PyObject *args)
+{
+    PyCursesWindowObject *temp;
+    int use_copywin = FALSE;
+    int sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol;
+    int rtn;
+    
+    switch (PyTuple_Size(args)) {
+    case 1:
+	if (!PyArg_ParseTuple(args, "O!;window object",
+			      &PyCursesWindow_Type, &temp))
+	    return NULL;
+	break;
+    case 7:
+	if (!PyArg_ParseTuple(args, "O!iiiiii;window object, int, int, int, int, int, int",
+			      &PyCursesWindow_Type, &temp, &sminrow, &smincol,
+			      &dminrow, &dmincol, &dmaxrow, &dmaxcol))
+	    return NULL;
+	use_copywin = TRUE;
+	break;
+    default:
+	PyErr_SetString(PyExc_TypeError,
+			"overlay requires one or seven arguments");
+	return NULL;
+    }
+
+    if (use_copywin == TRUE) {
+	    rtn = copywin(self->win, temp->win, sminrow, smincol,
+			  dminrow, dmincol, dmaxrow, dmaxcol, TRUE);
+	    return PyCursesCheckERR(rtn, "copywin");
+    }
+    else {
+	    rtn = overlay(self->win, temp->win);
+	    return PyCursesCheckERR(rtn, "overlay");
+    }
+}
+
+static PyObject *
+PyCursesWindow_Overwrite(PyCursesWindowObject *self, PyObject *args)
+{
+    PyCursesWindowObject *temp;
+    int use_copywin = FALSE;
+    int sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol;
+    int rtn;
+    
+    switch (PyTuple_Size(args)) {
+    case 1:
+	if (!PyArg_ParseTuple(args, "O!;window object",
+			      &PyCursesWindow_Type, &temp))
+	    return NULL;
+	break;
+    case 7:
+	if (!PyArg_ParseTuple(args, "O!iiiiii;window object, int, int, int, int, int, int",
+			      &PyCursesWindow_Type, &temp, &sminrow, &smincol,
+			      &dminrow, &dmincol, &dmaxrow, &dmaxcol))
+	    return NULL;
+	use_copywin = TRUE;
+	break;
+    default:
+	PyErr_SetString(PyExc_TypeError,
+			"overwrite requires one or seven arguments");
+	return NULL;
+    }
+
+    if (use_copywin == TRUE) {
+	rtn = copywin(self->win, temp->win, sminrow, smincol,
+		      dminrow, dmincol, dmaxrow, dmaxcol, FALSE);
+        return PyCursesCheckERR(rtn, "copywin");
+    }
+    else {
+	    rtn = overwrite(self->win, temp->win);
+	    return PyCursesCheckERR(rtn, "overwrite");
+    }
+}
+
+static PyObject *
+PyCursesWindow_PutWin(PyCursesWindowObject *self, PyObject *args)
+{
+  PyObject *temp;
+  
+  if (!PyArg_ParseTuple(args, "O;fileobj", &temp))
+    return NULL;
+  if (!PyFile_Check(temp)) {
+    PyErr_SetString(PyExc_TypeError, "argument must be a file object");
+    return NULL;
+  }
+  return PyCursesCheckERR(putwin(self->win, PyFile_AsFile(temp)), 
+			  "putwin");
+}
+
+static PyObject *
+PyCursesWindow_RedrawLine(PyCursesWindowObject *self, PyObject *args)
+{
+  int beg, num;
+  if (!PyArg_ParseTuple(args,"ii;beg,num", &beg, &num))
+    return NULL;
+  return PyCursesCheckERR(wredrawln(self->win,beg,num), "redrawln");
+}
+
+static PyObject *
+PyCursesWindow_Refresh(PyCursesWindowObject *self, PyObject *args)
+{
+  int pminrow,pmincol,sminrow,smincol,smaxrow,smaxcol;
+  int rtn;
+  
+#ifndef WINDOW_HAS_FLAGS
+  if (0) {
+#else
+  if (self->win->_flags & _ISPAD) {
+#endif
+    switch(PyTuple_Size(args)) {
+    case 6:
+      if (!PyArg_ParseTuple(args, 
+		       "iiiiii;" \
+		       "pminrow,pmincol,sminrow,smincol,smaxrow,smaxcol", 
+		       &pminrow, &pmincol, &sminrow, 
+		       &smincol, &smaxrow, &smaxcol))
+	return NULL;
+
+      Py_BEGIN_ALLOW_THREADS
+      rtn = prefresh(self->win,
+		     pminrow, pmincol, sminrow, 
+		     smincol, smaxrow, smaxcol);
+      Py_END_ALLOW_THREADS
+      return PyCursesCheckERR(rtn, "prefresh");
+    default:
+      PyErr_SetString(PyCursesError, 
+		      "refresh() for a pad requires 6 arguments");
+      return NULL;
+    }
+  } else {
+    if (!PyArg_ParseTuple(args, ":refresh"))
+      return NULL;    
+    Py_BEGIN_ALLOW_THREADS
+    rtn = wrefresh(self->win);
+    Py_END_ALLOW_THREADS
+    return PyCursesCheckERR(rtn, "prefresh");    
+  }
+}
+
+static PyObject *
+PyCursesWindow_SetScrollRegion(PyCursesWindowObject *self, PyObject *args)
+{
+  int x, y;
+  if (!PyArg_ParseTuple(args,"ii;top, bottom",&y,&x))
+    return NULL;
+  return PyCursesCheckERR(wsetscrreg(self->win,y,x), "wsetscrreg");
+}
+
+static PyObject *
+PyCursesWindow_SubWin(PyCursesWindowObject *self, PyObject *args)
+{
+  WINDOW *win;
+  int nlines, ncols, begin_y, begin_x;
+
+  nlines = 0;
+  ncols  = 0;
+  switch (PyTuple_Size(args)) {
+  case 2:
+    if (!PyArg_ParseTuple(args,"ii;begin_y,begin_x",&begin_y,&begin_x))
+      return NULL;
+    break;
+  case 4:
+    if (!PyArg_ParseTuple(args, "iiii;nlines,ncols,begin_y,begin_x",
+		   &nlines,&ncols,&begin_y,&begin_x))
+      return NULL;
+    break;
+  default:
+    PyErr_SetString(PyExc_TypeError, "subwin requires 2 or 4 arguments");
+    return NULL;
+  }
+
+  /* printf("Subwin: %i %i %i %i   \n", nlines, ncols, begin_y, begin_x); */
+#ifdef WINDOW_HAS_FLAGS
+  if (self->win->_flags & _ISPAD)
+    win = subpad(self->win, nlines, ncols, begin_y, begin_x);
+  else
+#endif
+    win = subwin(self->win, nlines, ncols, begin_y, begin_x);
+
+  if (win == NULL) {
+    PyErr_SetString(PyCursesError, catchall_NULL);
+    return NULL;
+  }
+  
+  return (PyObject *)PyCursesWindow_New(win);
+}
+
+static PyObject *
+PyCursesWindow_Scroll(PyCursesWindowObject *self, PyObject *args)
+{
+  int nlines;
+  switch(PyTuple_Size(args)) {
+  case 0:
+    return PyCursesCheckERR(scroll(self->win), "scroll");
+  case 1:
+    if (!PyArg_ParseTuple(args, "i;nlines", &nlines))
+      return NULL;
+    return PyCursesCheckERR(wscrl(self->win, nlines), "scroll");
+  default:
+    PyErr_SetString(PyExc_TypeError, "scroll requires 0 or 1 arguments");
+    return NULL;
+  }
+}
+
+static PyObject *
+PyCursesWindow_TouchLine(PyCursesWindowObject *self, PyObject *args)
+{
+  int st, cnt, val;
+  switch (PyTuple_Size(args)) {
+  case 2:
+    if (!PyArg_ParseTuple(args,"ii;start,count",&st,&cnt))
+      return NULL;
+    return PyCursesCheckERR(touchline(self->win,st,cnt), "touchline");
+  case 3:
+    if (!PyArg_ParseTuple(args, "iii;start,count,val", &st, &cnt, &val))
+      return NULL;
+    return PyCursesCheckERR(wtouchln(self->win, st, cnt, val), "touchline");
+  default:
+    PyErr_SetString(PyExc_TypeError, "touchline requires 2 or 3 arguments");
+    return NULL;
+  }
+}
+
+static PyObject *
+PyCursesWindow_Vline(PyCursesWindowObject *self, PyObject *args)
+{
+  PyObject *temp;
+  chtype ch;
+  int n, x, y, code = OK;
+  attr_t attr = A_NORMAL;
+
+  switch (PyTuple_Size(args)) {
+  case 2:
+    if (!PyArg_ParseTuple(args, "Oi;ch or int,n", &temp, &n))
+      return NULL;
+    break;
+  case 3:
+    if (!PyArg_ParseTuple(args, "Oil;ch or int,n,attr", &temp, &n, &attr))
+      return NULL;
+    break;
+  case 4:
+    if (!PyArg_ParseTuple(args, "iiOi;y,x,ch or int,n", &y, &x, &temp, &n))
+      return NULL;
+    code = wmove(self->win, y, x);
+    break;
+  case 5:
+    if (!PyArg_ParseTuple(args, "iiOil; y,x,ch or int,n,attr", 
+		     &y, &x, &temp, &n, &attr))
+      return NULL;
+    code = wmove(self->win, y, x);
+    break;
+  default:
+    PyErr_SetString(PyExc_TypeError, "vline requires 2 to 5 arguments");
+    return NULL;
+  }
+
+  if (code != ERR) {
+    if (!PyCurses_ConvertToChtype(temp, &ch)) {
+      PyErr_SetString(PyExc_TypeError, 
+		      "argument 1 or 3 must be a ch or an int");
+      return NULL;
+    }
+    return PyCursesCheckERR(wvline(self->win, ch | attr, n), "vline");
+  } else
+    return PyCursesCheckERR(code, "wmove");
+}
+
+static PyMethodDef PyCursesWindow_Methods[] = {
+	{"addch",           (PyCFunction)PyCursesWindow_AddCh, METH_VARARGS},
+	{"addnstr",         (PyCFunction)PyCursesWindow_AddNStr, METH_VARARGS},
+	{"addstr",          (PyCFunction)PyCursesWindow_AddStr, METH_VARARGS},
+	{"attroff",         (PyCFunction)PyCursesWindow_wattroff, METH_VARARGS},
+	{"attron",          (PyCFunction)PyCursesWindow_wattron, METH_VARARGS},
+	{"attrset",         (PyCFunction)PyCursesWindow_wattrset, METH_VARARGS},
+	{"bkgd",            (PyCFunction)PyCursesWindow_Bkgd, METH_VARARGS},
+	{"bkgdset",         (PyCFunction)PyCursesWindow_BkgdSet, METH_VARARGS},
+	{"border",          (PyCFunction)PyCursesWindow_Border, METH_VARARGS},
+	{"box",             (PyCFunction)PyCursesWindow_Box, METH_VARARGS},
+	{"clear",           (PyCFunction)PyCursesWindow_wclear, METH_NOARGS},
+	{"clearok",         (PyCFunction)PyCursesWindow_clearok, METH_VARARGS},
+	{"clrtobot",        (PyCFunction)PyCursesWindow_wclrtobot, METH_NOARGS},
+	{"clrtoeol",        (PyCFunction)PyCursesWindow_wclrtoeol, METH_NOARGS},
+	{"cursyncup",       (PyCFunction)PyCursesWindow_wcursyncup, METH_NOARGS},
+	{"delch",           (PyCFunction)PyCursesWindow_DelCh, METH_VARARGS},
+	{"deleteln",        (PyCFunction)PyCursesWindow_wdeleteln, METH_NOARGS},
+	{"derwin",          (PyCFunction)PyCursesWindow_DerWin, METH_VARARGS},
+	{"echochar",        (PyCFunction)PyCursesWindow_EchoChar, METH_VARARGS},
+#ifdef NCURSES_MOUSE_VERSION
+	{"enclose",         (PyCFunction)PyCursesWindow_Enclose, METH_VARARGS},
+#endif
+	{"erase",           (PyCFunction)PyCursesWindow_werase, METH_NOARGS},
+	{"getbegyx",        (PyCFunction)PyCursesWindow_getbegyx, METH_NOARGS},
+	{"getbkgd",         (PyCFunction)PyCursesWindow_GetBkgd, METH_NOARGS},
+	{"getch",           (PyCFunction)PyCursesWindow_GetCh, METH_VARARGS},
+	{"getkey",          (PyCFunction)PyCursesWindow_GetKey, METH_VARARGS},
+	{"getmaxyx",        (PyCFunction)PyCursesWindow_getmaxyx, METH_NOARGS},
+	{"getparyx",        (PyCFunction)PyCursesWindow_getparyx, METH_NOARGS},
+	{"getstr",          (PyCFunction)PyCursesWindow_GetStr, METH_VARARGS},
+	{"getyx",           (PyCFunction)PyCursesWindow_getyx, METH_NOARGS},
+	{"hline",           (PyCFunction)PyCursesWindow_Hline, METH_VARARGS},
+	{"idcok",           (PyCFunction)PyCursesWindow_idcok, METH_VARARGS},
+	{"idlok",           (PyCFunction)PyCursesWindow_idlok, METH_VARARGS},
+	{"immedok",         (PyCFunction)PyCursesWindow_immedok, METH_VARARGS},
+	{"inch",            (PyCFunction)PyCursesWindow_InCh, METH_VARARGS},
+	{"insch",           (PyCFunction)PyCursesWindow_InsCh, METH_VARARGS},
+	{"insdelln",        (PyCFunction)PyCursesWindow_winsdelln, METH_VARARGS},
+	{"insertln",        (PyCFunction)PyCursesWindow_winsertln, METH_NOARGS},
+	{"insnstr",         (PyCFunction)PyCursesWindow_InsNStr, METH_VARARGS},
+	{"insstr",          (PyCFunction)PyCursesWindow_InsStr, METH_VARARGS},
+	{"instr",           (PyCFunction)PyCursesWindow_InStr, METH_VARARGS},
+	{"is_linetouched",  (PyCFunction)PyCursesWindow_Is_LineTouched, METH_VARARGS},
+	{"is_wintouched",   (PyCFunction)PyCursesWindow_is_wintouched, METH_NOARGS},
+	{"keypad",          (PyCFunction)PyCursesWindow_keypad, METH_VARARGS},
+	{"leaveok",         (PyCFunction)PyCursesWindow_leaveok, METH_VARARGS},
+	{"move",            (PyCFunction)PyCursesWindow_wmove, METH_VARARGS},
+	{"mvderwin",        (PyCFunction)PyCursesWindow_mvderwin, METH_VARARGS},
+	{"mvwin",           (PyCFunction)PyCursesWindow_mvwin, METH_VARARGS},
+	{"nodelay",         (PyCFunction)PyCursesWindow_nodelay, METH_VARARGS},
+	{"notimeout",       (PyCFunction)PyCursesWindow_notimeout, METH_VARARGS},
+	{"noutrefresh",     (PyCFunction)PyCursesWindow_NoOutRefresh, METH_VARARGS},
+        /* Backward compatibility alias -- remove in Python 2.3 */
+	{"nooutrefresh",    (PyCFunction)PyCursesWindow_NoOutRefresh, METH_VARARGS},
+	{"overlay",         (PyCFunction)PyCursesWindow_Overlay, METH_VARARGS},
+	{"overwrite",       (PyCFunction)PyCursesWindow_Overwrite,
+         METH_VARARGS},
+	{"putwin",          (PyCFunction)PyCursesWindow_PutWin, METH_VARARGS},
+	{"redrawln",        (PyCFunction)PyCursesWindow_RedrawLine},
+	{"redrawwin",       (PyCFunction)PyCursesWindow_redrawwin, METH_NOARGS},
+	{"refresh",         (PyCFunction)PyCursesWindow_Refresh, METH_VARARGS},
+#ifndef STRICT_SYSV_CURSES
+	{"resize",          (PyCFunction)PyCursesWindow_wresize, METH_VARARGS},
+#endif
+	{"scroll",          (PyCFunction)PyCursesWindow_Scroll, METH_VARARGS},
+	{"scrollok",        (PyCFunction)PyCursesWindow_scrollok, METH_VARARGS},
+	{"setscrreg",       (PyCFunction)PyCursesWindow_SetScrollRegion, METH_VARARGS},
+	{"standend",        (PyCFunction)PyCursesWindow_wstandend, METH_NOARGS},
+	{"standout",        (PyCFunction)PyCursesWindow_wstandout, METH_NOARGS},
+	{"subpad",          (PyCFunction)PyCursesWindow_SubWin, METH_VARARGS},
+	{"subwin",          (PyCFunction)PyCursesWindow_SubWin, METH_VARARGS},
+	{"syncdown",        (PyCFunction)PyCursesWindow_wsyncdown, METH_NOARGS},
+	{"syncok",          (PyCFunction)PyCursesWindow_syncok, METH_VARARGS},
+	{"syncup",          (PyCFunction)PyCursesWindow_wsyncup, METH_NOARGS},
+	{"timeout",         (PyCFunction)PyCursesWindow_wtimeout, METH_VARARGS},
+	{"touchline",       (PyCFunction)PyCursesWindow_TouchLine, METH_VARARGS},
+	{"touchwin",        (PyCFunction)PyCursesWindow_touchwin, METH_NOARGS},
+	{"untouchwin",      (PyCFunction)PyCursesWindow_untouchwin, METH_NOARGS},
+	{"vline",           (PyCFunction)PyCursesWindow_Vline, METH_VARARGS},
+	{NULL,		    NULL}   /* sentinel */
+};
+
+static PyObject *
+PyCursesWindow_GetAttr(PyCursesWindowObject *self, char *name)
+{
+  return Py_FindMethod(PyCursesWindow_Methods, (PyObject *)self, name);
+}
+
+/* -------------------------------------------------------*/
+
+PyTypeObject PyCursesWindow_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0,			/*ob_size*/
+	"_curses.curses window",	/*tp_name*/
+	sizeof(PyCursesWindowObject),	/*tp_basicsize*/
+	0,			/*tp_itemsize*/
+	/* methods */
+	(destructor)PyCursesWindow_Dealloc, /*tp_dealloc*/
+	0,			/*tp_print*/
+	(getattrfunc)PyCursesWindow_GetAttr, /*tp_getattr*/
+	(setattrfunc)0, /*tp_setattr*/
+	0,			/*tp_compare*/
+	0,			/*tp_repr*/
+	0,			/*tp_as_number*/
+	0,			/*tp_as_sequence*/
+	0,			/*tp_as_mapping*/
+	0,			/*tp_hash*/
+};
+
+/*********************************************************************
+ Global Functions
+**********************************************************************/
+
+NoArgNoReturnFunction(beep)
+NoArgNoReturnFunction(def_prog_mode)
+NoArgNoReturnFunction(def_shell_mode)
+NoArgNoReturnFunction(doupdate)
+NoArgNoReturnFunction(endwin)
+NoArgNoReturnFunction(flash)
+NoArgNoReturnFunction(nocbreak)
+NoArgNoReturnFunction(noecho)
+NoArgNoReturnFunction(nonl)
+NoArgNoReturnFunction(noraw)
+NoArgNoReturnFunction(reset_prog_mode)
+NoArgNoReturnFunction(reset_shell_mode)
+NoArgNoReturnFunction(resetty)
+NoArgNoReturnFunction(savetty)
+
+NoArgOrFlagNoReturnFunction(cbreak)
+NoArgOrFlagNoReturnFunction(echo)
+NoArgOrFlagNoReturnFunction(nl)
+NoArgOrFlagNoReturnFunction(raw)
+
+NoArgReturnIntFunction(baudrate)
+NoArgReturnIntFunction(termattrs)
+
+NoArgReturnStringFunction(termname)
+NoArgReturnStringFunction(longname)
+
+NoArgTrueFalseFunction(can_change_color)
+NoArgTrueFalseFunction(has_colors)
+NoArgTrueFalseFunction(has_ic)
+NoArgTrueFalseFunction(has_il)
+NoArgTrueFalseFunction(isendwin)
+NoArgNoReturnVoidFunction(filter)
+NoArgNoReturnVoidFunction(flushinp)
+NoArgNoReturnVoidFunction(noqiflush)
+
+static PyObject *
+PyCurses_Color_Content(PyObject *self, PyObject *args)
+{
+  short color,r,g,b;
+
+  PyCursesInitialised
+  PyCursesInitialisedColor
+
+  if (!PyArg_ParseTuple(args, "h:color_content", &color)) return NULL;
+
+  if (color_content(color, &r, &g, &b) != ERR)
+    return Py_BuildValue("(iii)", r, g, b);
+  else {
+    PyErr_SetString(PyCursesError, 
+		    "Argument 1 was out of range. Check value of COLORS.");
+    return NULL;
+  }
+}
+
+static PyObject *
+PyCurses_color_pair(PyObject *self, PyObject *args)
+{
+  int n;
+
+  PyCursesInitialised
+  PyCursesInitialisedColor
+
+  if (!PyArg_ParseTuple(args, "i:color_pair", &n)) return NULL;
+  return PyInt_FromLong((long) (n << 8));
+}
+
+static PyObject *
+PyCurses_Curs_Set(PyObject *self, PyObject *args)
+{
+  int vis,erg;
+
+  PyCursesInitialised
+
+  if (!PyArg_ParseTuple(args, "i:curs_set", &vis)) return NULL;
+
+  erg = curs_set(vis);
+  if (erg == ERR) return PyCursesCheckERR(erg, "curs_set");
+
+  return PyInt_FromLong((long) erg);
+}
+
+static PyObject *
+PyCurses_Delay_Output(PyObject *self, PyObject *args)
+{
+  int ms;
+
+  PyCursesInitialised
+
+  if (!PyArg_ParseTuple(args, "i:delay_output", &ms)) return NULL;
+
+  return PyCursesCheckERR(delay_output(ms), "delay_output");
+}
+
+static PyObject *
+PyCurses_EraseChar(PyObject *self)
+{
+  char ch;
+
+  PyCursesInitialised
+
+  ch = erasechar();
+
+  return PyString_FromStringAndSize(&ch, 1);
+}
+
+static PyObject *
+PyCurses_getsyx(PyObject *self)
+{
+  int x,y;
+
+  PyCursesInitialised
+
+  getsyx(y, x);
+
+  return Py_BuildValue("(ii)", y, x);
+}
+
+#ifdef NCURSES_MOUSE_VERSION
+static PyObject *
+PyCurses_GetMouse(PyObject *self)
+{
+	int rtn;
+	MEVENT event;
+
+	PyCursesInitialised
+
+	rtn = getmouse( &event );
+	if (rtn == ERR) {
+		PyErr_SetString(PyCursesError, "getmouse() returned ERR");
+		return NULL;
+	}
+	return Py_BuildValue("(hiiil)", 
+			     (short)event.id, 
+			     event.x, event.y, event.z,
+			     (long) event.bstate);
+}
+
+static PyObject *
+PyCurses_UngetMouse(PyObject *self, PyObject *args)
+{
+	MEVENT event;
+
+	PyCursesInitialised
+	if (!PyArg_ParseTuple(args, "hiiil",
+			     &event.id, 
+			     &event.x, &event.y, &event.z,
+			     (int *) &event.bstate))
+	  return NULL;
+
+	return PyCursesCheckERR(ungetmouse(&event), "ungetmouse");
+}
+#endif
+
+static PyObject *
+PyCurses_GetWin(PyCursesWindowObject *self, PyObject *temp)
+{
+  WINDOW *win;
+
+  PyCursesInitialised
+
+  if (!PyFile_Check(temp)) {
+    PyErr_SetString(PyExc_TypeError, "argument must be a file object");
+    return NULL;
+  }
+
+  win = getwin(PyFile_AsFile(temp));
+
+  if (win == NULL) {
+    PyErr_SetString(PyCursesError, catchall_NULL);
+    return NULL;
+  }
+
+  return PyCursesWindow_New(win);
+}
+
+static PyObject *
+PyCurses_HalfDelay(PyObject *self, PyObject *args)
+{
+  unsigned char tenths;
+
+  PyCursesInitialised
+
+  if (!PyArg_ParseTuple(args, "b:halfdelay", &tenths)) return NULL;
+
+  return PyCursesCheckERR(halfdelay(tenths), "halfdelay");
+}
+
+#ifndef STRICT_SYSV_CURSES
+ /* No has_key! */
+static PyObject * PyCurses_has_key(PyObject *self, PyObject *args)
+{
+  int ch;
+
+  PyCursesInitialised
+
+  if (!PyArg_ParseTuple(args,"i",&ch)) return NULL;
+
+  if (has_key(ch) == FALSE) {
+    Py_INCREF(Py_False);
+    return Py_False;
+  }
+  Py_INCREF(Py_True);
+  return Py_True; 
+}
+#endif /* STRICT_SYSV_CURSES */
+
+static PyObject *
+PyCurses_Init_Color(PyObject *self, PyObject *args)
+{
+  short color, r, g, b;
+
+  PyCursesInitialised
+  PyCursesInitialisedColor
+
+  switch(PyTuple_Size(args)) {
+  case 4:
+    if (!PyArg_ParseTuple(args, "hhhh;color,r,g,b", &color, &r, &g, &b)) return NULL;
+    break;
+  default:
+    PyErr_SetString(PyExc_TypeError, "init_color requires 4 arguments");
+    return NULL;
+  }
+
+  return PyCursesCheckERR(init_color(color, r, g, b), "init_color");
+}
+
+static PyObject *
+PyCurses_Init_Pair(PyObject *self, PyObject *args)
+{
+  short pair, f, b;
+
+  PyCursesInitialised
+  PyCursesInitialisedColor
+
+  if (PyTuple_Size(args) != 3) {
+    PyErr_SetString(PyExc_TypeError, "init_pair requires 3 arguments");
+    return NULL;
+  }
+
+  if (!PyArg_ParseTuple(args, "hhh;pair, f, b", &pair, &f, &b)) return NULL;
+
+  return PyCursesCheckERR(init_pair(pair, f, b), "init_pair");
+}
+
+static PyObject *ModDict;
+
+static PyObject * 
+PyCurses_InitScr(PyObject *self)
+{
+  WINDOW *win;
+
+  if (initialised == TRUE) {
+    wrefresh(stdscr);
+    return (PyObject *)PyCursesWindow_New(stdscr);
+  }
+
+  win = initscr();
+
+  if (win == NULL) {
+    PyErr_SetString(PyCursesError, catchall_NULL);
+    return NULL;
+  }
+
+  initialised = initialised_setupterm = TRUE;
+
+/* This was moved from initcurses() because it core dumped on SGI,
+   where they're not defined until you've called initscr() */
+#define SetDictInt(string,ch) \
+    do {							\
+	PyObject *o = PyInt_FromLong((long) (ch));		\
+	if (o && PyDict_SetItemString(ModDict, string, o) == 0)	{ \
+	    Py_DECREF(o);					\
+	}							\
+    } while (0)
+
+	/* Here are some graphic symbols you can use */
+        SetDictInt("ACS_ULCORNER",      (ACS_ULCORNER));
+	SetDictInt("ACS_LLCORNER",      (ACS_LLCORNER));
+	SetDictInt("ACS_URCORNER",      (ACS_URCORNER));
+	SetDictInt("ACS_LRCORNER",      (ACS_LRCORNER));
+	SetDictInt("ACS_LTEE",          (ACS_LTEE));
+	SetDictInt("ACS_RTEE",          (ACS_RTEE));
+	SetDictInt("ACS_BTEE",          (ACS_BTEE));
+	SetDictInt("ACS_TTEE",          (ACS_TTEE));
+	SetDictInt("ACS_HLINE",         (ACS_HLINE));
+	SetDictInt("ACS_VLINE",         (ACS_VLINE));
+	SetDictInt("ACS_PLUS",          (ACS_PLUS));
+#if !defined(__hpux) || defined(HAVE_NCURSES_H)
+        /* On HP/UX 11, these are of type cchar_t, which is not an
+           integral type. If this is a problem on more platforms, a
+           configure test should be added to determine whether ACS_S1
+           is of integral type. */
+	SetDictInt("ACS_S1",            (ACS_S1));
+	SetDictInt("ACS_S9",            (ACS_S9));
+	SetDictInt("ACS_DIAMOND",       (ACS_DIAMOND));
+	SetDictInt("ACS_CKBOARD",       (ACS_CKBOARD));
+	SetDictInt("ACS_DEGREE",        (ACS_DEGREE));
+	SetDictInt("ACS_PLMINUS",       (ACS_PLMINUS));
+	SetDictInt("ACS_BULLET",        (ACS_BULLET));
+	SetDictInt("ACS_LARROW",        (ACS_LARROW));
+	SetDictInt("ACS_RARROW",        (ACS_RARROW));
+	SetDictInt("ACS_DARROW",        (ACS_DARROW));
+	SetDictInt("ACS_UARROW",        (ACS_UARROW));
+	SetDictInt("ACS_BOARD",         (ACS_BOARD));
+	SetDictInt("ACS_LANTERN",       (ACS_LANTERN));
+	SetDictInt("ACS_BLOCK",         (ACS_BLOCK));
+#endif
+	SetDictInt("ACS_BSSB",          (ACS_ULCORNER));
+	SetDictInt("ACS_SSBB",          (ACS_LLCORNER));
+	SetDictInt("ACS_BBSS",          (ACS_URCORNER));
+	SetDictInt("ACS_SBBS",          (ACS_LRCORNER));
+	SetDictInt("ACS_SBSS",          (ACS_RTEE));
+	SetDictInt("ACS_SSSB",          (ACS_LTEE));
+	SetDictInt("ACS_SSBS",          (ACS_BTEE));
+	SetDictInt("ACS_BSSS",          (ACS_TTEE));
+	SetDictInt("ACS_BSBS",          (ACS_HLINE));
+	SetDictInt("ACS_SBSB",          (ACS_VLINE));
+	SetDictInt("ACS_SSSS",          (ACS_PLUS));
+
+	/* The following are never available with strict SYSV curses */
+#ifdef ACS_S3
+	SetDictInt("ACS_S3",            (ACS_S3));
+#endif
+#ifdef ACS_S7
+	SetDictInt("ACS_S7",            (ACS_S7));
+#endif
+#ifdef ACS_LEQUAL
+	SetDictInt("ACS_LEQUAL",        (ACS_LEQUAL));
+#endif
+#ifdef ACS_GEQUAL
+	SetDictInt("ACS_GEQUAL",        (ACS_GEQUAL));
+#endif
+#ifdef ACS_PI
+	SetDictInt("ACS_PI",            (ACS_PI));
+#endif
+#ifdef ACS_NEQUAL
+	SetDictInt("ACS_NEQUAL",        (ACS_NEQUAL));
+#endif
+#ifdef ACS_STERLING
+	SetDictInt("ACS_STERLING",      (ACS_STERLING));
+#endif
+
+  SetDictInt("LINES", LINES);
+  SetDictInt("COLS", COLS);
+
+  return (PyObject *)PyCursesWindow_New(win);
+}
+
+static PyObject *
+PyCurses_setupterm(PyObject* self, PyObject *args, PyObject* keywds)
+{
+	int fd = -1;
+	int err;
+	char* termstr = NULL;
+
+	static char *kwlist[] = {"term", "fd", NULL};
+
+	if (!PyArg_ParseTupleAndKeywords(
+		args, keywds, "|zi:setupterm", kwlist, &termstr, &fd)) {
+		return NULL;
+	}
+	
+	if (fd == -1) {
+		PyObject* sys_stdout;
+
+		sys_stdout = PySys_GetObject("stdout");
+
+		if (sys_stdout == NULL) {
+			PyErr_SetString(
+				PyCursesError,
+				"lost sys.stdout");
+			return NULL;
+		}
+
+		fd = PyObject_AsFileDescriptor(sys_stdout);
+
+		if (fd == -1) {
+			return NULL;
+		}
+	}
+
+	if (setupterm(termstr,fd,&err) == ERR) {
+		char* s = "setupterm: unknown error";
+		
+		if (err == 0) {
+			s = "setupterm: could not find terminal";
+		} else if (err == -1) {
+			s = "setupterm: could not find terminfo database";
+		}
+
+		PyErr_SetString(PyCursesError,s);
+		return NULL;
+	}
+
+	initialised_setupterm = TRUE;
+
+	Py_INCREF(Py_None);
+	return Py_None;	
+}
+
+static PyObject *
+PyCurses_IntrFlush(PyObject *self, PyObject *args)
+{
+  int ch;
+
+  PyCursesInitialised
+
+  switch(PyTuple_Size(args)) {
+  case 1:
+    if (!PyArg_ParseTuple(args,"i;True(1), False(0)",&ch)) return NULL;
+    break;
+  default:
+    PyErr_SetString(PyExc_TypeError, "intrflush requires 1 argument");
+    return NULL;
+  }
+
+  return PyCursesCheckERR(intrflush(NULL,ch), "intrflush");
+}
+
+#ifdef HAVE_CURSES_IS_TERM_RESIZED
+static PyObject *
+PyCurses_Is_Term_Resized(PyObject *self, PyObject *args)
+{
+  int lines;
+  int columns;
+  int result;
+
+  PyCursesInitialised
+
+  if (!PyArg_ParseTuple(args,"ii:is_term_resized", &lines, &columns))
+    return NULL;
+  result = is_term_resized(lines, columns);
+  if (result == TRUE) {
+    Py_INCREF(Py_True);
+    return Py_True;
+  } else {
+    Py_INCREF(Py_False);
+    return Py_False;
+  }
+}
+#endif /* HAVE_CURSES_IS_TERM_RESIZED */
+
+#if !defined(__NetBSD__)
+static PyObject *
+PyCurses_KeyName(PyObject *self, PyObject *args)
+{
+  const char *knp;
+  int ch;
+
+  PyCursesInitialised
+
+  if (!PyArg_ParseTuple(args,"i",&ch)) return NULL;
+
+  if (ch < 0) {
+    PyErr_SetString(PyExc_ValueError, "invalid key number");
+    return NULL;
+  }
+  knp = keyname(ch);
+
+  return PyString_FromString((knp == NULL) ? "" : (char *)knp);
+}
+#endif
+
+static PyObject *  
+PyCurses_KillChar(PyObject *self)  
+{  
+  char ch;  
+
+  ch = killchar();  
+
+  return PyString_FromStringAndSize(&ch, 1);  
+}  
+
+static PyObject *
+PyCurses_Meta(PyObject *self, PyObject *args)
+{
+  int ch;
+
+  PyCursesInitialised
+
+  switch(PyTuple_Size(args)) {
+  case 1:
+    if (!PyArg_ParseTuple(args,"i;True(1), False(0)",&ch)) return NULL;
+    break;
+  default:
+    PyErr_SetString(PyExc_TypeError, "meta requires 1 argument");
+    return NULL;
+  }
+
+  return PyCursesCheckERR(meta(stdscr, ch), "meta");
+}
+
+#ifdef NCURSES_MOUSE_VERSION
+static PyObject *
+PyCurses_MouseInterval(PyObject *self, PyObject *args)
+{
+	int interval;
+	PyCursesInitialised 
+
+	if (!PyArg_ParseTuple(args,"i;interval",&interval)) 
+		return NULL;
+	return PyCursesCheckERR(mouseinterval(interval), "mouseinterval");
+}
+
+static PyObject *
+PyCurses_MouseMask(PyObject *self, PyObject *args)
+{
+	int newmask;
+	mmask_t oldmask, availmask;
+
+	PyCursesInitialised 
+	if (!PyArg_ParseTuple(args,"i;mousemask",&newmask)) 
+		return NULL;
+	availmask = mousemask(newmask, &oldmask);
+	return Py_BuildValue("(ll)", (long)availmask, (long)oldmask);
+}
+#endif
+
+static PyObject *
+PyCurses_Napms(PyObject *self, PyObject *args)
+{
+    int ms;
+
+    PyCursesInitialised
+    if (!PyArg_ParseTuple(args, "i;ms", &ms)) return NULL;
+
+    return Py_BuildValue("i", napms(ms));
+}
+
+
+static PyObject *
+PyCurses_NewPad(PyObject *self, PyObject *args)
+{
+  WINDOW *win;
+  int nlines, ncols;
+
+  PyCursesInitialised 
+
+  if (!PyArg_ParseTuple(args,"ii;nlines,ncols",&nlines,&ncols)) return NULL;
+
+  win = newpad(nlines, ncols);
+  
+  if (win == NULL) {
+    PyErr_SetString(PyCursesError, catchall_NULL);
+    return NULL;
+  }
+
+  return (PyObject *)PyCursesWindow_New(win);
+}
+
+static PyObject *
+PyCurses_NewWindow(PyObject *self, PyObject *args)
+{
+  WINDOW *win;
+  int nlines, ncols, begin_y=0, begin_x=0;
+
+  PyCursesInitialised
+
+  switch (PyTuple_Size(args)) {
+  case 2:
+    if (!PyArg_ParseTuple(args,"ii;nlines,ncols",&nlines,&ncols))
+      return NULL;
+    break;
+  case 4:
+    if (!PyArg_ParseTuple(args, "iiii;nlines,ncols,begin_y,begin_x",
+		   &nlines,&ncols,&begin_y,&begin_x))
+      return NULL;
+    break;
+  default:
+    PyErr_SetString(PyExc_TypeError, "newwin requires 2 or 4 arguments");
+    return NULL;
+  }
+
+  win = newwin(nlines,ncols,begin_y,begin_x);
+  if (win == NULL) {
+    PyErr_SetString(PyCursesError, catchall_NULL);
+    return NULL;
+  }
+
+  return (PyObject *)PyCursesWindow_New(win);
+}
+
+static PyObject *
+PyCurses_Pair_Content(PyObject *self, PyObject *args)
+{
+  short pair,f,b;
+
+  PyCursesInitialised
+  PyCursesInitialisedColor
+
+  switch(PyTuple_Size(args)) {
+  case 1:
+    if (!PyArg_ParseTuple(args, "h;pair", &pair)) return NULL;
+    break;
+  default:
+    PyErr_SetString(PyExc_TypeError, "pair_content requires 1 argument");
+    return NULL;
+  }
+
+  if (pair_content(pair, &f, &b)==ERR) {
+    PyErr_SetString(PyCursesError,
+		    "Argument 1 was out of range. (1..COLOR_PAIRS-1)");
+    return NULL;
+  }
+
+  return Py_BuildValue("(ii)", f, b);
+}
+
+static PyObject *
+PyCurses_pair_number(PyObject *self, PyObject *args)
+{
+  int n;
+
+  PyCursesInitialised
+  PyCursesInitialisedColor
+
+  switch(PyTuple_Size(args)) {
+  case 1:
+    if (!PyArg_ParseTuple(args, "i;pairvalue", &n)) return NULL;
+    break;
+  default:
+    PyErr_SetString(PyExc_TypeError,
+                    "pair_number requires 1 argument");
+    return NULL;
+  }
+
+  return PyInt_FromLong((long) ((n & A_COLOR) >> 8));
+}
+
+static PyObject *
+PyCurses_Putp(PyObject *self, PyObject *args)
+{
+  char *str;
+
+  if (!PyArg_ParseTuple(args,"s;str", &str)) return NULL;
+  return PyCursesCheckERR(putp(str), "putp");
+}
+
+static PyObject *
+PyCurses_QiFlush(PyObject *self, PyObject *args)
+{
+  int flag = 0;
+
+  PyCursesInitialised
+
+  switch(PyTuple_Size(args)) {
+  case 0:
+    qiflush();
+    Py_INCREF(Py_None);
+    return Py_None;
+  case 1:
+    if (!PyArg_ParseTuple(args, "i;True(1) or False(0)", &flag)) return NULL;
+    if (flag) qiflush();
+    else noqiflush();
+    Py_INCREF(Py_None);
+    return Py_None;
+  default:
+    PyErr_SetString(PyExc_TypeError, "qiflush requires 0 or 1 arguments");
+    return NULL;
+  }
+}
+
+/* Internal helper used for updating curses.LINES, curses.COLS, _curses.LINES
+ * and _curses.COLS */
+static int
+update_lines_cols(void)
+{
+  PyObject *o;
+  PyObject *m = PyImport_ImportModule("curses");
+
+  if (!m)
+    return 0;
+
+  o = PyInt_FromLong(LINES);
+  if (!o) {
+    Py_DECREF(m);
+    return 0;
+  }
+  if (PyObject_SetAttrString(m, "LINES", o)) {
+    Py_DECREF(m);
+    Py_DECREF(o);
+    return 0;
+  }
+  if (PyDict_SetItemString(ModDict, "LINES", o)) {
+    Py_DECREF(m);
+    Py_DECREF(o);
+    return 0;
+  }
+  Py_DECREF(o);
+  o = PyInt_FromLong(COLS);
+  if (!o) {
+    Py_DECREF(m);
+    return 0;
+  }
+  if (PyObject_SetAttrString(m, "COLS", o)) {
+    Py_DECREF(m);
+    Py_DECREF(o);
+    return 0;
+  }
+  if (PyDict_SetItemString(ModDict, "COLS", o)) {
+    Py_DECREF(m);
+    Py_DECREF(o);
+    return 0;
+  }
+  Py_DECREF(o);
+  Py_DECREF(m);
+  return 1;
+}
+
+#ifdef HAVE_CURSES_RESIZETERM
+static PyObject *
+PyCurses_ResizeTerm(PyObject *self, PyObject *args)
+{
+  int lines;
+  int columns;
+  PyObject *result;
+
+  PyCursesInitialised
+
+  if (!PyArg_ParseTuple(args,"ii:resizeterm", &lines, &columns))
+    return NULL;
+
+  result = PyCursesCheckERR(resizeterm(lines, columns), "resizeterm");
+  if (!result)
+    return NULL;
+  if (!update_lines_cols())
+    return NULL;
+  return result;
+}
+
+#endif
+
+#ifdef HAVE_CURSES_RESIZE_TERM
+static PyObject *
+PyCurses_Resize_Term(PyObject *self, PyObject *args)
+{
+  int lines;
+  int columns;
+
+  PyObject *result;
+
+  PyCursesInitialised
+
+  if (!PyArg_ParseTuple(args,"ii:resize_term", &lines, &columns))
+    return NULL;
+
+  result = PyCursesCheckERR(resize_term(lines, columns), "resize_term");
+  if (!result)
+    return NULL;
+  if (!update_lines_cols())
+    return NULL;
+  return result;
+}
+#endif /* HAVE_CURSES_RESIZE_TERM */
+
+static PyObject *
+PyCurses_setsyx(PyObject *self, PyObject *args)
+{
+  int y,x;
+
+  PyCursesInitialised
+
+  if (PyTuple_Size(args)!=2) {
+    PyErr_SetString(PyExc_TypeError, "setsyx requires 2 arguments");
+    return NULL;
+  }
+
+  if (!PyArg_ParseTuple(args, "ii;y, x", &y, &x)) return NULL;
+
+  setsyx(y,x);
+
+  Py_INCREF(Py_None);
+  return Py_None;
+}
+
+static PyObject *
+PyCurses_Start_Color(PyObject *self)
+{
+  int code;
+  PyObject *c, *cp;
+
+  PyCursesInitialised
+
+  code = start_color();
+  if (code != ERR) {
+    initialisedcolors = TRUE;
+    c = PyInt_FromLong((long) COLORS);
+    PyDict_SetItemString(ModDict, "COLORS", c);
+    Py_DECREF(c);
+    cp = PyInt_FromLong((long) COLOR_PAIRS);
+    PyDict_SetItemString(ModDict, "COLOR_PAIRS", cp);
+    Py_DECREF(cp);
+    Py_INCREF(Py_None);
+    return Py_None;
+  } else {
+    PyErr_SetString(PyCursesError, "start_color() returned ERR");
+    return NULL;
+  }
+}
+
+static PyObject *
+PyCurses_tigetflag(PyObject *self, PyObject *args)
+{
+	char *capname;
+
+	PyCursesSetupTermCalled;
+		
+	if (!PyArg_ParseTuple(args, "z", &capname))
+		return NULL;
+
+	return PyInt_FromLong( (long) tigetflag( capname ) );
+}
+
+static PyObject *
+PyCurses_tigetnum(PyObject *self, PyObject *args)
+{
+	char *capname;
+
+	PyCursesSetupTermCalled;
+		
+	if (!PyArg_ParseTuple(args, "z", &capname))
+		return NULL;
+
+	return PyInt_FromLong( (long) tigetnum( capname ) );
+}
+
+static PyObject *
+PyCurses_tigetstr(PyObject *self, PyObject *args)
+{
+	char *capname;
+
+	PyCursesSetupTermCalled;
+		
+	if (!PyArg_ParseTuple(args, "z", &capname))
+		return NULL;
+
+	capname = tigetstr( capname );
+	if (capname == 0 || capname == (char*) -1) {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+	return PyString_FromString( capname );
+}
+
+static PyObject *
+PyCurses_tparm(PyObject *self, PyObject *args)
+{
+	char* fmt;
+	char* result = NULL;
+	int i1=0,i2=0,i3=0,i4=0,i5=0,i6=0,i7=0,i8=0,i9=0;
+
+	PyCursesSetupTermCalled;
+
+	if (!PyArg_ParseTuple(args, "s|iiiiiiiii:tparm", 
+			      &fmt, &i1, &i2, &i3, &i4, 
+			      &i5, &i6, &i7, &i8, &i9)) {
+		return NULL;
+	}
+
+	result = tparm(fmt,i1,i2,i3,i4,i5,i6,i7,i8,i9);
+	if (!result) {
+		PyErr_SetString(PyCursesError, "tparm() returned NULL");
+  		return NULL;
+	}
+
+	return PyString_FromString(result);
+}
+
+static PyObject *
+PyCurses_TypeAhead(PyObject *self, PyObject *args)
+{
+  int fd;
+
+  PyCursesInitialised
+
+  if (!PyArg_ParseTuple(args,"i;fd",&fd)) return NULL;
+
+  return PyCursesCheckERR(typeahead( fd ), "typeahead");
+}
+
+static PyObject *
+PyCurses_UnCtrl(PyObject *self, PyObject *args)
+{
+  PyObject *temp;
+  chtype ch;
+
+  PyCursesInitialised
+
+  if (!PyArg_ParseTuple(args,"O;ch or int",&temp)) return NULL;
+
+  if (PyInt_Check(temp))
+    ch = (chtype) PyInt_AsLong(temp);
+  else if (PyString_Check(temp))
+    ch = (chtype) *PyString_AsString(temp);
+  else {
+    PyErr_SetString(PyExc_TypeError, "argument must be a ch or an int");
+    return NULL;
+  }
+
+  return PyString_FromString(unctrl(ch));
+}
+
+static PyObject *
+PyCurses_UngetCh(PyObject *self, PyObject *args)
+{
+  PyObject *temp;
+  int ch;
+
+  PyCursesInitialised
+
+  if (!PyArg_ParseTuple(args,"O;ch or int",&temp)) return NULL;
+
+  if (PyInt_Check(temp))
+    ch = (int) PyInt_AsLong(temp);
+  else if (PyString_Check(temp))
+    ch = (int) *PyString_AsString(temp);
+  else {
+    PyErr_SetString(PyExc_TypeError, "argument must be a ch or an int");
+    return NULL;
+  }
+
+  return PyCursesCheckERR(ungetch(ch), "ungetch");
+}
+
+static PyObject *
+PyCurses_Use_Env(PyObject *self, PyObject *args)
+{
+  int flag;
+
+  PyCursesInitialised
+
+  switch(PyTuple_Size(args)) {
+  case 1:
+    if (!PyArg_ParseTuple(args,"i;True(1), False(0)",&flag))
+      return NULL;
+    break;
+  default:
+    PyErr_SetString(PyExc_TypeError, "use_env requires 1 argument");
+    return NULL;
+  }
+  use_env(flag);
+  Py_INCREF(Py_None);
+  return Py_None;
+}
+
+#ifndef STRICT_SYSV_CURSES
+static PyObject *
+PyCurses_Use_Default_Colors(PyObject *self)
+{
+  int code;
+
+  PyCursesInitialised
+  PyCursesInitialisedColor
+
+  code = use_default_colors();
+  if (code != ERR) {
+    Py_INCREF(Py_None);
+    return Py_None;
+  } else {
+    PyErr_SetString(PyCursesError, "use_default_colors() returned ERR");
+    return NULL;
+  }
+}
+#endif /* STRICT_SYSV_CURSES */
+
+/* List of functions defined in the module */
+
+static PyMethodDef PyCurses_methods[] = {
+  {"baudrate",            (PyCFunction)PyCurses_baudrate, METH_NOARGS},
+  {"beep",                (PyCFunction)PyCurses_beep, METH_NOARGS},
+  {"can_change_color",    (PyCFunction)PyCurses_can_change_color, METH_NOARGS},
+  {"cbreak",              (PyCFunction)PyCurses_cbreak, METH_VARARGS},
+  {"color_content",       (PyCFunction)PyCurses_Color_Content, METH_VARARGS},
+  {"color_pair",          (PyCFunction)PyCurses_color_pair, METH_VARARGS},
+  {"curs_set",            (PyCFunction)PyCurses_Curs_Set, METH_VARARGS},
+  {"def_prog_mode",       (PyCFunction)PyCurses_def_prog_mode, METH_NOARGS},
+  {"def_shell_mode",      (PyCFunction)PyCurses_def_shell_mode, METH_NOARGS},
+  {"delay_output",        (PyCFunction)PyCurses_Delay_Output, METH_VARARGS},
+  {"doupdate",            (PyCFunction)PyCurses_doupdate, METH_NOARGS},
+  {"echo",                (PyCFunction)PyCurses_echo, METH_VARARGS},
+  {"endwin",              (PyCFunction)PyCurses_endwin, METH_NOARGS},
+  {"erasechar",           (PyCFunction)PyCurses_EraseChar, METH_NOARGS},
+  {"filter",              (PyCFunction)PyCurses_filter, METH_NOARGS},
+  {"flash",               (PyCFunction)PyCurses_flash, METH_NOARGS},
+  {"flushinp",            (PyCFunction)PyCurses_flushinp, METH_NOARGS},
+#ifdef NCURSES_MOUSE_VERSION
+  {"getmouse",            (PyCFunction)PyCurses_GetMouse, METH_NOARGS},
+  {"ungetmouse",          (PyCFunction)PyCurses_UngetMouse, METH_VARARGS},
+#endif
+  {"getsyx",              (PyCFunction)PyCurses_getsyx, METH_NOARGS},
+  {"getwin",              (PyCFunction)PyCurses_GetWin, METH_O},
+  {"has_colors",          (PyCFunction)PyCurses_has_colors, METH_NOARGS},
+  {"has_ic",              (PyCFunction)PyCurses_has_ic, METH_NOARGS},
+  {"has_il",              (PyCFunction)PyCurses_has_il, METH_NOARGS},
+#ifndef STRICT_SYSV_CURSES
+  {"has_key",             (PyCFunction)PyCurses_has_key, METH_VARARGS},
+#endif
+  {"halfdelay",           (PyCFunction)PyCurses_HalfDelay, METH_VARARGS},
+  {"init_color",          (PyCFunction)PyCurses_Init_Color, METH_VARARGS},
+  {"init_pair",           (PyCFunction)PyCurses_Init_Pair, METH_VARARGS},
+  {"initscr",             (PyCFunction)PyCurses_InitScr, METH_NOARGS},
+  {"intrflush",           (PyCFunction)PyCurses_IntrFlush, METH_VARARGS},
+  {"isendwin",            (PyCFunction)PyCurses_isendwin, METH_NOARGS},
+#ifdef HAVE_CURSES_IS_TERM_RESIZED
+  {"is_term_resized",     (PyCFunction)PyCurses_Is_Term_Resized, METH_VARARGS},
+#endif
+#if !defined(__NetBSD__)
+  {"keyname",             (PyCFunction)PyCurses_KeyName, METH_VARARGS},
+#endif
+  {"killchar",            (PyCFunction)PyCurses_KillChar, METH_NOARGS}, 
+  {"longname",            (PyCFunction)PyCurses_longname, METH_NOARGS}, 
+  {"meta",                (PyCFunction)PyCurses_Meta, METH_VARARGS},
+#ifdef NCURSES_MOUSE_VERSION
+  {"mouseinterval",       (PyCFunction)PyCurses_MouseInterval, METH_VARARGS},
+  {"mousemask",           (PyCFunction)PyCurses_MouseMask, METH_VARARGS},
+#endif
+  {"napms",               (PyCFunction)PyCurses_Napms, METH_VARARGS},
+  {"newpad",              (PyCFunction)PyCurses_NewPad, METH_VARARGS},
+  {"newwin",              (PyCFunction)PyCurses_NewWindow, METH_VARARGS},
+  {"nl",                  (PyCFunction)PyCurses_nl, METH_VARARGS},
+  {"nocbreak",            (PyCFunction)PyCurses_nocbreak, METH_NOARGS},
+  {"noecho",              (PyCFunction)PyCurses_noecho, METH_NOARGS},
+  {"nonl",                (PyCFunction)PyCurses_nonl, METH_NOARGS},
+  {"noqiflush",           (PyCFunction)PyCurses_noqiflush, METH_NOARGS},
+  {"noraw",               (PyCFunction)PyCurses_noraw, METH_NOARGS},
+  {"pair_content",        (PyCFunction)PyCurses_Pair_Content, METH_VARARGS},
+  {"pair_number",         (PyCFunction)PyCurses_pair_number, METH_VARARGS},
+  {"putp",                (PyCFunction)PyCurses_Putp, METH_VARARGS},
+  {"qiflush",             (PyCFunction)PyCurses_QiFlush, METH_VARARGS},
+  {"raw",                 (PyCFunction)PyCurses_raw, METH_VARARGS},
+  {"reset_prog_mode",     (PyCFunction)PyCurses_reset_prog_mode, METH_NOARGS},
+  {"reset_shell_mode",    (PyCFunction)PyCurses_reset_shell_mode, METH_NOARGS},
+  {"resetty",             (PyCFunction)PyCurses_resetty, METH_NOARGS},
+#ifdef HAVE_CURSES_RESIZETERM
+  {"resizeterm",          (PyCFunction)PyCurses_ResizeTerm, METH_VARARGS},
+#endif
+#ifdef HAVE_CURSES_RESIZE_TERM
+  {"resize_term",         (PyCFunction)PyCurses_Resize_Term, METH_VARARGS},
+#endif
+  {"savetty",             (PyCFunction)PyCurses_savetty, METH_NOARGS},
+  {"setsyx",              (PyCFunction)PyCurses_setsyx, METH_VARARGS},
+  {"setupterm",           (PyCFunction)PyCurses_setupterm,
+   METH_VARARGS|METH_KEYWORDS},
+  {"start_color",         (PyCFunction)PyCurses_Start_Color, METH_NOARGS},
+  {"termattrs",           (PyCFunction)PyCurses_termattrs, METH_NOARGS},
+  {"termname",            (PyCFunction)PyCurses_termname, METH_NOARGS},
+  {"tigetflag",		  (PyCFunction)PyCurses_tigetflag, METH_VARARGS},
+  {"tigetnum",		  (PyCFunction)PyCurses_tigetnum, METH_VARARGS},
+  {"tigetstr",		  (PyCFunction)PyCurses_tigetstr, METH_VARARGS},
+  {"tparm",               (PyCFunction)PyCurses_tparm, METH_VARARGS},
+  {"typeahead",           (PyCFunction)PyCurses_TypeAhead, METH_VARARGS},
+  {"unctrl",              (PyCFunction)PyCurses_UnCtrl, METH_VARARGS},
+  {"ungetch",             (PyCFunction)PyCurses_UngetCh, METH_VARARGS},
+  {"use_env",             (PyCFunction)PyCurses_Use_Env, METH_VARARGS},
+#ifndef STRICT_SYSV_CURSES
+  {"use_default_colors",  (PyCFunction)PyCurses_Use_Default_Colors, METH_NOARGS},
+#endif
+  {NULL,		  NULL}		/* sentinel */
+};
+
+/* Initialization function for the module */
+
+PyMODINIT_FUNC
+init_curses(void)
+{
+	PyObject *m, *d, *v, *c_api_object;
+	static void *PyCurses_API[PyCurses_API_pointers];
+
+	/* Initialize object type */
+	PyCursesWindow_Type.ob_type = &PyType_Type;
+
+	/* Initialize the C API pointer array */
+	PyCurses_API[0] = (void *)&PyCursesWindow_Type;
+	PyCurses_API[1] = (void *)func_PyCursesSetupTermCalled;
+	PyCurses_API[2] = (void *)func_PyCursesInitialised;
+	PyCurses_API[3] = (void *)func_PyCursesInitialisedColor;
+
+	/* Create the module and add the functions */
+	m = Py_InitModule("_curses", PyCurses_methods);
+	if (m == NULL)
+    		return;
+
+	/* Add some symbolic constants to the module */
+	d = PyModule_GetDict(m);
+	if (d == NULL)
+		return;
+	ModDict = d; /* For PyCurses_InitScr to use later */
+
+	/* Add a CObject for the C API */
+	c_api_object = PyCObject_FromVoidPtr((void *)PyCurses_API, NULL);
+	PyDict_SetItemString(d, "_C_API", c_api_object);
+	Py_DECREF(c_api_object);
+
+	/* For exception curses.error */
+	PyCursesError = PyErr_NewException("_curses.error", NULL, NULL);
+	PyDict_SetItemString(d, "error", PyCursesError);
+
+	/* Make the version available */
+	v = PyString_FromString(PyCursesVersion);
+	PyDict_SetItemString(d, "version", v);
+	PyDict_SetItemString(d, "__version__", v);
+	Py_DECREF(v);
+
+        SetDictInt("ERR", ERR);
+        SetDictInt("OK", OK);
+
+	/* Here are some attributes you can add to chars to print */
+	
+	SetDictInt("A_ATTRIBUTES",      A_ATTRIBUTES);
+	SetDictInt("A_NORMAL",		A_NORMAL);
+	SetDictInt("A_STANDOUT",	A_STANDOUT);
+	SetDictInt("A_UNDERLINE",	A_UNDERLINE);
+	SetDictInt("A_REVERSE",		A_REVERSE);
+	SetDictInt("A_BLINK",		A_BLINK);
+	SetDictInt("A_DIM",		A_DIM);
+	SetDictInt("A_BOLD",		A_BOLD);
+	SetDictInt("A_ALTCHARSET",	A_ALTCHARSET);
+#if !defined(__NetBSD__)
+	SetDictInt("A_INVIS",           A_INVIS);
+#endif
+	SetDictInt("A_PROTECT",         A_PROTECT);
+	SetDictInt("A_CHARTEXT",        A_CHARTEXT);
+	SetDictInt("A_COLOR",           A_COLOR);
+
+	/* The following are never available with strict SYSV curses */
+#ifdef A_HORIZONTAL
+	SetDictInt("A_HORIZONTAL",      A_HORIZONTAL);
+#endif
+#ifdef A_LEFT
+	SetDictInt("A_LEFT",            A_LEFT);
+#endif
+#ifdef A_LOW
+	SetDictInt("A_LOW",             A_LOW);
+#endif
+#ifdef A_RIGHT
+	SetDictInt("A_RIGHT",           A_RIGHT);
+#endif
+#ifdef A_TOP
+	SetDictInt("A_TOP",             A_TOP);
+#endif
+#ifdef A_VERTICAL
+	SetDictInt("A_VERTICAL",        A_VERTICAL);
+#endif
+
+	SetDictInt("COLOR_BLACK",       COLOR_BLACK);
+	SetDictInt("COLOR_RED",         COLOR_RED);
+	SetDictInt("COLOR_GREEN",       COLOR_GREEN);
+	SetDictInt("COLOR_YELLOW",      COLOR_YELLOW);
+	SetDictInt("COLOR_BLUE",        COLOR_BLUE);
+	SetDictInt("COLOR_MAGENTA",     COLOR_MAGENTA);
+	SetDictInt("COLOR_CYAN",        COLOR_CYAN);
+	SetDictInt("COLOR_WHITE",       COLOR_WHITE);
+
+#ifdef NCURSES_MOUSE_VERSION
+	/* Mouse-related constants */
+	SetDictInt("BUTTON1_PRESSED",          BUTTON1_PRESSED);
+	SetDictInt("BUTTON1_RELEASED",         BUTTON1_RELEASED);
+	SetDictInt("BUTTON1_CLICKED",          BUTTON1_CLICKED);
+	SetDictInt("BUTTON1_DOUBLE_CLICKED",   BUTTON1_DOUBLE_CLICKED);
+	SetDictInt("BUTTON1_TRIPLE_CLICKED",   BUTTON1_TRIPLE_CLICKED);
+
+	SetDictInt("BUTTON2_PRESSED",          BUTTON2_PRESSED);
+	SetDictInt("BUTTON2_RELEASED",         BUTTON2_RELEASED);
+	SetDictInt("BUTTON2_CLICKED",          BUTTON2_CLICKED);
+	SetDictInt("BUTTON2_DOUBLE_CLICKED",   BUTTON2_DOUBLE_CLICKED);
+	SetDictInt("BUTTON2_TRIPLE_CLICKED",   BUTTON2_TRIPLE_CLICKED);
+
+	SetDictInt("BUTTON3_PRESSED",          BUTTON3_PRESSED);
+	SetDictInt("BUTTON3_RELEASED",         BUTTON3_RELEASED);
+	SetDictInt("BUTTON3_CLICKED",          BUTTON3_CLICKED);
+	SetDictInt("BUTTON3_DOUBLE_CLICKED",   BUTTON3_DOUBLE_CLICKED);
+	SetDictInt("BUTTON3_TRIPLE_CLICKED",   BUTTON3_TRIPLE_CLICKED);
+
+	SetDictInt("BUTTON4_PRESSED",          BUTTON4_PRESSED);
+	SetDictInt("BUTTON4_RELEASED",         BUTTON4_RELEASED);
+	SetDictInt("BUTTON4_CLICKED",          BUTTON4_CLICKED);
+	SetDictInt("BUTTON4_DOUBLE_CLICKED",   BUTTON4_DOUBLE_CLICKED);
+	SetDictInt("BUTTON4_TRIPLE_CLICKED",   BUTTON4_TRIPLE_CLICKED);
+
+	SetDictInt("BUTTON_SHIFT",             BUTTON_SHIFT);
+	SetDictInt("BUTTON_CTRL",              BUTTON_CTRL);
+	SetDictInt("BUTTON_ALT",               BUTTON_ALT);
+
+	SetDictInt("ALL_MOUSE_EVENTS",         ALL_MOUSE_EVENTS);
+	SetDictInt("REPORT_MOUSE_POSITION",    REPORT_MOUSE_POSITION);
+#endif
+	/* Now set everything up for KEY_ variables */
+	{
+	  int key;
+	  char *key_n;
+	  char *key_n2;
+#if !defined(__NetBSD__)
+	  for (key=KEY_MIN;key < KEY_MAX; key++) {
+	    key_n = (char *)keyname(key);
+	    if (key_n == NULL || strcmp(key_n,"UNKNOWN KEY")==0)
+	      continue;
+	    if (strncmp(key_n,"KEY_F(",6)==0) {
+	      char *p1, *p2;
+	      key_n2 = malloc(strlen(key_n)+1);
+	      if (!key_n2) {
+		PyErr_NoMemory();
+		break;
+              }
+	      p1 = key_n;
+	      p2 = key_n2;
+	      while (*p1) {
+		if (*p1 != '(' && *p1 != ')') {
+		  *p2 = *p1;
+		  p2++;
+		}
+		p1++;
+	      }
+	      *p2 = (char)0;
+	    } else
+	      key_n2 = key_n;
+	    SetDictInt(key_n2,key);
+	    if (key_n2 != key_n)
+	      free(key_n2);
+	  }
+#endif
+	  SetDictInt("KEY_MIN", KEY_MIN);
+	  SetDictInt("KEY_MAX", KEY_MAX);
+	}
+}

Added: vendor/Python/current/Modules/_elementtree.c
===================================================================
--- vendor/Python/current/Modules/_elementtree.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_elementtree.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2815 @@
+/*
+ * ElementTree
+ * $Id: _elementtree.c 2657 2006-03-12 20:50:32Z fredrik $
+ *
+ * elementtree accelerator
+ *
+ * History:
+ * 1999-06-20 fl  created (as part of sgmlop)
+ * 2001-05-29 fl  effdom edition
+ * 2001-06-05 fl  backported to unix; fixed bogus free in clear
+ * 2001-07-10 fl  added findall helper
+ * 2003-02-27 fl  elementtree edition (alpha)
+ * 2004-06-03 fl  updates for elementtree 1.2
+ * 2005-01-05 fl  added universal name cache, Element/SubElement factories
+ * 2005-01-06 fl  moved python helpers into C module; removed 1.5.2 support
+ * 2005-01-07 fl  added 2.1 support; work around broken __copy__ in 2.3
+ * 2005-01-08 fl  added makeelement method; fixed path support
+ * 2005-01-10 fl  optimized memory usage
+ * 2005-01-11 fl  first public release (cElementTree 0.8)
+ * 2005-01-12 fl  split element object into base and extras
+ * 2005-01-13 fl  use tagged pointers for tail/text (cElementTree 0.9)
+ * 2005-01-17 fl  added treebuilder close method
+ * 2005-01-17 fl  fixed crash in getchildren
+ * 2005-01-18 fl  removed observer api, added iterparse (cElementTree 0.9.3)
+ * 2005-01-23 fl  revised iterparse api; added namespace event support (0.9.8)
+ * 2005-01-26 fl  added VERSION module property (cElementTree 1.0)
+ * 2005-01-28 fl  added remove method (1.0.1)
+ * 2005-03-01 fl  added iselement function; fixed makeelement aliasing (1.0.2)
+ * 2005-03-13 fl  export Comment and ProcessingInstruction/PI helpers
+ * 2005-03-26 fl  added Comment and PI support to XMLParser
+ * 2005-03-27 fl  event optimizations; complain about bogus events
+ * 2005-08-08 fl  fixed read error handling in parse
+ * 2005-08-11 fl  added runtime test for copy workaround (1.0.3)
+ * 2005-12-13 fl  added expat_capi support (for xml.etree) (1.0.4)
+ * 2005-12-16 fl  added support for non-standard encodings
+ * 2006-03-08 fl  fixed a couple of potential null-refs and leaks
+ * 2006-03-12 fl  merge in 2.5 ssize_t changes
+ *
+ * Copyright (c) 1999-2006 by Secret Labs AB.  All rights reserved.
+ * Copyright (c) 1999-2006 by Fredrik Lundh.
+ *
+ * info at pythonware.com
+ * http://www.pythonware.com
+ */
+
+/* Licensed to PSF under a Contributor Agreement. */
+/* See http://www.python.org/2.4/license for licensing details. */
+
+#include "Python.h"
+
+#define VERSION "1.0.6"
+
+/* -------------------------------------------------------------------- */
+/* configuration */
+
+/* Leave defined to include the expat-based XMLParser type */
+#define USE_EXPAT
+
+/* Define to to all expat calls via pyexpat's embedded expat library */
+/* #define USE_PYEXPAT_CAPI */
+
+/* An element can hold this many children without extra memory
+   allocations. */
+#define STATIC_CHILDREN 4
+
+/* For best performance, chose a value so that 80-90% of all nodes
+   have no more than the given number of children.  Set this to zero
+   to minimize the size of the element structure itself (this only
+   helps if you have lots of leaf nodes with attributes). */
+
+/* Also note that pymalloc always allocates blocks in multiples of
+   eight bytes.  For the current version of cElementTree, this means
+   that the number of children should be an even number, at least on
+   32-bit platforms. */
+
+/* -------------------------------------------------------------------- */
+
+#if 0
+static int memory = 0;
+#define ALLOC(size, comment)\
+do { memory += size; printf("%8d - %s\n", memory, comment); } while (0)
+#define RELEASE(size, comment)\
+do { memory -= size; printf("%8d - %s\n", memory, comment); } while (0)
+#else
+#define ALLOC(size, comment)
+#define RELEASE(size, comment)
+#endif
+
+/* compiler tweaks */
+#if defined(_MSC_VER)
+#define LOCAL(type) static __inline type __fastcall
+#else
+#define LOCAL(type) static type
+#endif
+
+/* compatibility macros */
+#if (PY_VERSION_HEX < 0x02050000)
+typedef int Py_ssize_t;
+#define lenfunc inquiry
+#endif
+
+#if (PY_VERSION_HEX < 0x02040000)
+#define PyDict_CheckExact PyDict_Check
+#if (PY_VERSION_HEX < 0x02020000)
+#define PyList_CheckExact PyList_Check
+#define PyString_CheckExact PyString_Check
+#if (PY_VERSION_HEX >= 0x01060000)
+#define Py_USING_UNICODE /* always enabled for 2.0 and 2.1 */
+#endif
+#endif
+#endif
+
+#if !defined(Py_RETURN_NONE)
+#define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
+#endif
+
+/* macros used to store 'join' flags in string object pointers.  note
+   that all use of text and tail as object pointers must be wrapped in
+   JOIN_OBJ.  see comments in the ElementObject definition for more
+   info. */
+#define JOIN_GET(p) ((Py_uintptr_t) (p) & 1)
+#define JOIN_SET(p, flag) ((void*) ((Py_uintptr_t) (JOIN_OBJ(p)) | (flag)))
+#define JOIN_OBJ(p) ((PyObject*) ((Py_uintptr_t) (p) & ~1))
+
+/* glue functions (see the init function for details) */
+static PyObject* elementtree_copyelement_obj;
+static PyObject* elementtree_deepcopy_obj;
+static PyObject* elementtree_getiterator_obj;
+static PyObject* elementpath_obj;
+
+/* helpers */
+
+LOCAL(PyObject*)
+deepcopy(PyObject* object, PyObject* memo)
+{
+    /* do a deep copy of the given object */
+
+    PyObject* args;
+    PyObject* result;
+
+    if (!elementtree_deepcopy_obj) {
+        PyErr_SetString(
+            PyExc_RuntimeError,
+            "deepcopy helper not found"
+            );
+        return NULL;
+    }
+
+    args = PyTuple_New(2);
+    if (!args)
+        return NULL;
+
+    Py_INCREF(object); PyTuple_SET_ITEM(args, 0, (PyObject*) object);
+    Py_INCREF(memo);   PyTuple_SET_ITEM(args, 1, (PyObject*) memo);
+
+    result = PyObject_CallObject(elementtree_deepcopy_obj, args);
+
+    Py_DECREF(args);
+
+    return result;
+}
+
+LOCAL(PyObject*)
+list_join(PyObject* list)
+{
+    /* join list elements (destroying the list in the process) */
+
+    PyObject* joiner;
+    PyObject* function;
+    PyObject* args;
+    PyObject* result;
+
+    switch (PyList_GET_SIZE(list)) {
+    case 0:
+        Py_DECREF(list);
+        return PyString_FromString("");
+    case 1:
+        result = PyList_GET_ITEM(list, 0);
+        Py_INCREF(result);
+        Py_DECREF(list);
+        return result;
+    }
+
+    /* two or more elements: slice out a suitable separator from the
+       first member, and use that to join the entire list */
+
+    joiner = PySequence_GetSlice(PyList_GET_ITEM(list, 0), 0, 0);
+    if (!joiner)
+        return NULL;
+
+    function = PyObject_GetAttrString(joiner, "join");
+    if (!function) {
+        Py_DECREF(joiner);
+        return NULL;
+    }
+
+    args = PyTuple_New(1);
+    if (!args)
+        return NULL;
+
+    PyTuple_SET_ITEM(args, 0, list);
+
+    result = PyObject_CallObject(function, args);
+
+    Py_DECREF(args); /* also removes list */
+    Py_DECREF(function);
+    Py_DECREF(joiner);
+
+    return result;
+}
+
+#if (PY_VERSION_HEX < 0x02020000)
+LOCAL(int)
+PyDict_Update(PyObject* dict, PyObject* other)
+{
+    /* PyDict_Update emulation for 2.1 and earlier */
+
+    PyObject* res;
+    
+    res = PyObject_CallMethod(dict, "update", "O", other);
+    if (!res)
+        return -1;
+
+    Py_DECREF(res);
+    return 0;
+}
+#endif
+
+/* -------------------------------------------------------------------- */
+/* the element type */
+
+typedef struct {
+
+    /* attributes (a dictionary object), or None if no attributes */
+    PyObject* attrib;
+
+    /* child elements */
+    int length; /* actual number of items */
+    int allocated; /* allocated items */
+
+    /* this either points to _children or to a malloced buffer */
+    PyObject* *children;
+
+    PyObject* _children[STATIC_CHILDREN];
+    
+} ElementObjectExtra;
+
+typedef struct {
+    PyObject_HEAD
+
+    /* element tag (a string). */
+    PyObject* tag;
+
+    /* text before first child.  note that this is a tagged pointer;
+       use JOIN_OBJ to get the object pointer.  the join flag is used
+       to distinguish lists created by the tree builder from lists
+       assigned to the attribute by application code; the former
+       should be joined before being returned to the user, the latter
+       should be left intact. */
+    PyObject* text;
+
+    /* text after this element, in parent.  note that this is a tagged
+       pointer; use JOIN_OBJ to get the object pointer. */
+    PyObject* tail;
+
+    ElementObjectExtra* extra;
+
+} ElementObject;
+
+staticforward PyTypeObject Element_Type;
+
+#define Element_CheckExact(op) ((op)->ob_type == &Element_Type)
+
+/* -------------------------------------------------------------------- */
+/* element constructor and destructor */
+
+LOCAL(int)
+element_new_extra(ElementObject* self, PyObject* attrib)
+{
+    self->extra = PyObject_Malloc(sizeof(ElementObjectExtra));
+    if (!self->extra)
+        return -1;
+
+    if (!attrib)
+        attrib = Py_None;
+
+    Py_INCREF(attrib);
+    self->extra->attrib = attrib;
+
+    self->extra->length = 0;
+    self->extra->allocated = STATIC_CHILDREN;
+    self->extra->children = self->extra->_children;
+
+    return 0;
+}
+
+LOCAL(void)
+element_dealloc_extra(ElementObject* self)
+{
+    int i;
+
+    Py_DECREF(self->extra->attrib);
+
+    for (i = 0; i < self->extra->length; i++)
+        Py_DECREF(self->extra->children[i]);
+
+    if (self->extra->children != self->extra->_children)
+        PyObject_Free(self->extra->children);
+
+    PyObject_Free(self->extra);
+}
+
+LOCAL(PyObject*)
+element_new(PyObject* tag, PyObject* attrib)
+{
+    ElementObject* self;
+
+    self = PyObject_New(ElementObject, &Element_Type);
+    if (self == NULL)
+        return NULL;
+
+    /* use None for empty dictionaries */
+    if (PyDict_CheckExact(attrib) && !PyDict_Size(attrib))
+        attrib = Py_None;
+
+    self->extra = NULL;
+
+    if (attrib != Py_None) {
+
+        if (element_new_extra(self, attrib) < 0) {
+            PyObject_Del(self);
+            return NULL;
+	}
+
+        self->extra->length = 0;
+        self->extra->allocated = STATIC_CHILDREN;
+        self->extra->children = self->extra->_children;
+
+    }
+
+    Py_INCREF(tag);
+    self->tag = tag;
+
+    Py_INCREF(Py_None);
+    self->text = Py_None;
+
+    Py_INCREF(Py_None);
+    self->tail = Py_None;
+
+    ALLOC(sizeof(ElementObject), "create element");
+
+    return (PyObject*) self;
+}
+
+LOCAL(int)
+element_resize(ElementObject* self, int extra)
+{
+    int size;
+    PyObject* *children;
+
+    /* make sure self->children can hold the given number of extra
+       elements.  set an exception and return -1 if allocation failed */
+
+    if (!self->extra)
+        element_new_extra(self, NULL);
+
+    size = self->extra->length + extra;
+
+    if (size > self->extra->allocated) {
+        /* use Python 2.4's list growth strategy */
+        size = (size >> 3) + (size < 9 ? 3 : 6) + size;
+        if (self->extra->children != self->extra->_children) {
+            children = PyObject_Realloc(self->extra->children,
+                                        size * sizeof(PyObject*));
+            if (!children)
+                goto nomemory;
+        } else {
+            children = PyObject_Malloc(size * sizeof(PyObject*));
+            if (!children)
+                goto nomemory;
+            /* copy existing children from static area to malloc buffer */
+            memcpy(children, self->extra->children,
+                   self->extra->length * sizeof(PyObject*));
+        }
+        self->extra->children = children;
+        self->extra->allocated = size;
+    }
+
+    return 0;
+
+  nomemory:
+    PyErr_NoMemory();
+    return -1;
+}
+
+LOCAL(int)
+element_add_subelement(ElementObject* self, PyObject* element)
+{
+    /* add a child element to a parent */
+
+    if (element_resize(self, 1) < 0)
+        return -1;
+
+    Py_INCREF(element);
+    self->extra->children[self->extra->length] = element;
+
+    self->extra->length++;
+
+    return 0;
+}
+
+LOCAL(PyObject*)
+element_get_attrib(ElementObject* self)
+{
+    /* return borrowed reference to attrib dictionary */
+    /* note: this function assumes that the extra section exists */
+
+    PyObject* res = self->extra->attrib;
+
+    if (res == Py_None) {
+        /* create missing dictionary */
+        res = PyDict_New();
+        if (!res)
+            return NULL;
+        self->extra->attrib = res;
+    }
+
+    return res;
+}
+
+LOCAL(PyObject*)
+element_get_text(ElementObject* self)
+{
+    /* return borrowed reference to text attribute */
+
+    PyObject* res = self->text;
+
+    if (JOIN_GET(res)) {
+        res = JOIN_OBJ(res);
+        if (PyList_CheckExact(res)) {
+            res = list_join(res);
+            if (!res)
+                return NULL;
+            self->text = res;
+        }
+    }
+
+    return res;
+}
+
+LOCAL(PyObject*)
+element_get_tail(ElementObject* self)
+{
+    /* return borrowed reference to text attribute */
+
+    PyObject* res = self->tail;
+
+    if (JOIN_GET(res)) {
+        res = JOIN_OBJ(res);
+        if (PyList_CheckExact(res)) {
+            res = list_join(res);
+            if (!res)
+                return NULL;
+            self->tail = res;
+        }
+    }
+
+    return res;
+}
+
+static PyObject*
+element(PyObject* self, PyObject* args, PyObject* kw)
+{
+    PyObject* elem;
+
+    PyObject* tag;
+    PyObject* attrib = NULL;
+    if (!PyArg_ParseTuple(args, "O|O!:Element", &tag,
+                          &PyDict_Type, &attrib))
+        return NULL;
+
+    if (attrib || kw) {
+        attrib = (attrib) ? PyDict_Copy(attrib) : PyDict_New();
+        if (!attrib)
+            return NULL;
+        if (kw)
+            PyDict_Update(attrib, kw);
+    } else {
+        Py_INCREF(Py_None);
+        attrib = Py_None;
+    }
+
+    elem = element_new(tag, attrib);
+
+    Py_DECREF(attrib);
+
+    return elem;
+}
+
+static PyObject*
+subelement(PyObject* self, PyObject* args, PyObject* kw)
+{
+    PyObject* elem;
+
+    ElementObject* parent;
+    PyObject* tag;
+    PyObject* attrib = NULL;
+    if (!PyArg_ParseTuple(args, "O!O|O!:SubElement",
+                          &Element_Type, &parent, &tag,
+                          &PyDict_Type, &attrib))
+        return NULL;
+
+    if (attrib || kw) {
+        attrib = (attrib) ? PyDict_Copy(attrib) : PyDict_New();
+        if (!attrib)
+            return NULL;
+        if (kw)
+            PyDict_Update(attrib, kw);
+    } else {
+        Py_INCREF(Py_None);
+        attrib = Py_None;
+    }
+
+    elem = element_new(tag, attrib);
+
+    Py_DECREF(attrib);
+
+    if (element_add_subelement(parent, elem) < 0) {
+        Py_DECREF(elem);
+        return NULL;
+    }
+
+    return elem;
+}
+
+static void
+element_dealloc(ElementObject* self)
+{
+    if (self->extra)
+        element_dealloc_extra(self);
+
+    /* discard attributes */
+    Py_DECREF(self->tag);
+    Py_DECREF(JOIN_OBJ(self->text));
+    Py_DECREF(JOIN_OBJ(self->tail));
+
+    RELEASE(sizeof(ElementObject), "destroy element");
+
+    PyObject_Del(self);
+}
+
+/* -------------------------------------------------------------------- */
+/* methods (in alphabetical order) */
+
+static PyObject*
+element_append(ElementObject* self, PyObject* args)
+{
+    PyObject* element;
+    if (!PyArg_ParseTuple(args, "O!:append", &Element_Type, &element))
+        return NULL;
+
+    if (element_add_subelement(self, element) < 0)
+        return NULL;
+
+    Py_RETURN_NONE;
+}
+
+static PyObject*
+element_clear(ElementObject* self, PyObject* args)
+{
+    if (!PyArg_ParseTuple(args, ":clear"))
+        return NULL;
+
+    if (self->extra) {
+        element_dealloc_extra(self);
+        self->extra = NULL;
+    }
+
+    Py_INCREF(Py_None);
+    Py_DECREF(JOIN_OBJ(self->text));
+    self->text = Py_None;
+
+    Py_INCREF(Py_None);
+    Py_DECREF(JOIN_OBJ(self->tail));
+    self->tail = Py_None;
+
+    Py_RETURN_NONE;
+}
+
+static PyObject*
+element_copy(ElementObject* self, PyObject* args)
+{
+    int i;
+    ElementObject* element;
+
+    if (!PyArg_ParseTuple(args, ":__copy__"))
+        return NULL;
+
+    element = (ElementObject*) element_new(
+        self->tag, (self->extra) ? self->extra->attrib : Py_None
+        );
+    if (!element)
+        return NULL;
+
+    Py_DECREF(JOIN_OBJ(element->text));
+    element->text = self->text;
+    Py_INCREF(JOIN_OBJ(element->text));
+
+    Py_DECREF(JOIN_OBJ(element->tail));
+    element->tail = self->tail;
+    Py_INCREF(JOIN_OBJ(element->tail));
+
+    if (self->extra) {
+        
+        if (element_resize(element, self->extra->length) < 0) {
+            Py_DECREF(element);
+            return NULL;
+        }
+
+        for (i = 0; i < self->extra->length; i++) {
+            Py_INCREF(self->extra->children[i]);
+            element->extra->children[i] = self->extra->children[i];
+        }
+
+        element->extra->length = self->extra->length;
+        
+    }
+
+    return (PyObject*) element;
+}
+
+static PyObject*
+element_deepcopy(ElementObject* self, PyObject* args)
+{
+    int i;
+    ElementObject* element;
+    PyObject* tag;
+    PyObject* attrib;
+    PyObject* text;
+    PyObject* tail;
+    PyObject* id;
+
+    PyObject* memo;
+    if (!PyArg_ParseTuple(args, "O:__deepcopy__", &memo))
+        return NULL;
+
+    tag = deepcopy(self->tag, memo);
+    if (!tag)
+        return NULL;
+
+    if (self->extra) {
+        attrib = deepcopy(self->extra->attrib, memo);
+        if (!attrib) {
+            Py_DECREF(tag);
+            return NULL;
+        }
+    } else {
+        Py_INCREF(Py_None);
+        attrib = Py_None;
+    }
+
+    element = (ElementObject*) element_new(tag, attrib);
+
+    Py_DECREF(tag);
+    Py_DECREF(attrib);
+
+    if (!element)
+        return NULL;
+    
+    text = deepcopy(JOIN_OBJ(self->text), memo);
+    if (!text)
+        goto error;
+    Py_DECREF(element->text);
+    element->text = JOIN_SET(text, JOIN_GET(self->text));
+
+    tail = deepcopy(JOIN_OBJ(self->tail), memo);
+    if (!tail)
+        goto error;
+    Py_DECREF(element->tail);
+    element->tail = JOIN_SET(tail, JOIN_GET(self->tail));
+
+    if (self->extra) {
+        
+        if (element_resize(element, self->extra->length) < 0)
+            goto error;
+
+        for (i = 0; i < self->extra->length; i++) {
+            PyObject* child = deepcopy(self->extra->children[i], memo);
+            if (!child) {
+                element->extra->length = i;
+                goto error;
+            }
+            element->extra->children[i] = child;
+        }
+
+        element->extra->length = self->extra->length;
+        
+    }
+
+    /* add object to memo dictionary (so deepcopy won't visit it again) */
+    id = PyInt_FromLong((Py_uintptr_t) self);
+
+    i = PyDict_SetItem(memo, id, (PyObject*) element);
+
+    Py_DECREF(id);
+
+    if (i < 0)
+        goto error;
+
+    return (PyObject*) element;
+
+  error:
+    Py_DECREF(element);
+    return NULL;
+}
+
+LOCAL(int)
+checkpath(PyObject* tag)
+{
+    Py_ssize_t i;
+    int check = 1;
+
+    /* check if a tag contains an xpath character */
+
+#define PATHCHAR(ch) (ch == '/' || ch == '*' || ch == '[' || ch == '@')
+
+#if defined(Py_USING_UNICODE)
+    if (PyUnicode_Check(tag)) {
+        Py_UNICODE *p = PyUnicode_AS_UNICODE(tag);
+        for (i = 0; i < PyUnicode_GET_SIZE(tag); i++) {
+            if (p[i] == '{')
+                check = 0;
+            else if (p[i] == '}')
+                check = 1;
+            else if (check && PATHCHAR(p[i]))
+                return 1;
+        }
+        return 0;
+    }
+#endif
+    if (PyString_Check(tag)) {
+        char *p = PyString_AS_STRING(tag);
+        for (i = 0; i < PyString_GET_SIZE(tag); i++) {
+            if (p[i] == '{')
+                check = 0;
+            else if (p[i] == '}')
+                check = 1;
+            else if (check && PATHCHAR(p[i]))
+                return 1;
+        }
+        return 0;
+    }
+
+    return 1; /* unknown type; might be path expression */
+}
+
+static PyObject*
+element_find(ElementObject* self, PyObject* args)
+{
+    int i;
+
+    PyObject* tag;
+    if (!PyArg_ParseTuple(args, "O:find", &tag))
+        return NULL;
+
+    if (checkpath(tag))
+        return PyObject_CallMethod(
+            elementpath_obj, "find", "OO", self, tag
+            );
+
+    if (!self->extra)
+        Py_RETURN_NONE;
+        
+    for (i = 0; i < self->extra->length; i++) {
+        PyObject* item = self->extra->children[i];
+        if (Element_CheckExact(item) &&
+            PyObject_Compare(((ElementObject*)item)->tag, tag) == 0) {
+            Py_INCREF(item);
+            return item;
+        }
+    }
+
+    Py_RETURN_NONE;
+}
+
+static PyObject*
+element_findtext(ElementObject* self, PyObject* args)
+{
+    int i;
+
+    PyObject* tag;
+    PyObject* default_value = Py_None;
+    if (!PyArg_ParseTuple(args, "O|O:findtext", &tag, &default_value))
+        return NULL;
+
+    if (checkpath(tag))
+        return PyObject_CallMethod(
+            elementpath_obj, "findtext", "OOO", self, tag, default_value
+            );
+
+    if (!self->extra) {
+        Py_INCREF(default_value);
+        return default_value;
+    }
+
+    for (i = 0; i < self->extra->length; i++) {
+        ElementObject* item = (ElementObject*) self->extra->children[i];
+        if (Element_CheckExact(item) && !PyObject_Compare(item->tag, tag)) {
+            PyObject* text = element_get_text(item);
+            if (text == Py_None)
+                return PyString_FromString("");
+            Py_XINCREF(text);
+            return text;
+        }
+    }
+
+    Py_INCREF(default_value);
+    return default_value;
+}
+
+static PyObject*
+element_findall(ElementObject* self, PyObject* args)
+{
+    int i;
+    PyObject* out;
+
+    PyObject* tag;
+    if (!PyArg_ParseTuple(args, "O:findall", &tag))
+        return NULL;
+
+    if (checkpath(tag))
+        return PyObject_CallMethod(
+            elementpath_obj, "findall", "OO", self, tag
+            );
+
+    out = PyList_New(0);
+    if (!out)
+        return NULL;
+
+    if (!self->extra)
+        return out;
+
+    for (i = 0; i < self->extra->length; i++) {
+        PyObject* item = self->extra->children[i];
+        if (Element_CheckExact(item) &&
+            PyObject_Compare(((ElementObject*)item)->tag, tag) == 0) {
+            if (PyList_Append(out, item) < 0) {
+                Py_DECREF(out);
+                return NULL;
+            }
+        }
+    }
+
+    return out;
+}
+
+static PyObject*
+element_get(ElementObject* self, PyObject* args)
+{
+    PyObject* value;
+
+    PyObject* key;
+    PyObject* default_value = Py_None;
+    if (!PyArg_ParseTuple(args, "O|O:get", &key, &default_value))
+        return NULL;
+
+    if (!self->extra || self->extra->attrib == Py_None)
+        value = default_value;
+    else {
+        value = PyDict_GetItem(self->extra->attrib, key);
+        if (!value)
+            value = default_value;
+    }
+
+    Py_INCREF(value);
+    return value;
+}
+
+static PyObject*
+element_getchildren(ElementObject* self, PyObject* args)
+{
+    int i;
+    PyObject* list;
+
+    if (!PyArg_ParseTuple(args, ":getchildren"))
+        return NULL;
+
+    if (!self->extra)
+        return PyList_New(0);
+
+    list = PyList_New(self->extra->length);
+    if (!list)
+        return NULL;
+
+    for (i = 0; i < self->extra->length; i++) {
+        PyObject* item = self->extra->children[i];
+        Py_INCREF(item);
+        PyList_SET_ITEM(list, i, item);
+    }
+
+    return list;
+}
+
+static PyObject*
+element_getiterator(ElementObject* self, PyObject* args)
+{
+    PyObject* result;
+    
+    PyObject* tag = Py_None;
+    if (!PyArg_ParseTuple(args, "|O:getiterator", &tag))
+        return NULL;
+
+    if (!elementtree_getiterator_obj) {
+        PyErr_SetString(
+            PyExc_RuntimeError,
+            "getiterator helper not found"
+            );
+        return NULL;
+    }
+
+    args = PyTuple_New(2);
+    if (!args)
+        return NULL;
+
+    Py_INCREF(self); PyTuple_SET_ITEM(args, 0, (PyObject*) self);
+    Py_INCREF(tag);  PyTuple_SET_ITEM(args, 1, (PyObject*) tag);
+
+    result = PyObject_CallObject(elementtree_getiterator_obj, args);
+
+    Py_DECREF(args);
+
+    return result;
+}
+
+static PyObject*
+element_getitem(PyObject* self_, Py_ssize_t index)
+{
+    ElementObject* self = (ElementObject*) self_;
+
+    if (!self->extra || index < 0 || index >= self->extra->length) {
+        PyErr_SetString(
+            PyExc_IndexError,
+            "child index out of range"
+            );
+        return NULL;
+    }
+
+    Py_INCREF(self->extra->children[index]);
+    return self->extra->children[index];
+}
+
+static PyObject*
+element_getslice(PyObject* self_, Py_ssize_t start, Py_ssize_t end)
+{
+    ElementObject* self = (ElementObject*) self_;
+    Py_ssize_t i;
+    PyObject* list;
+
+    if (!self->extra)
+        return PyList_New(0);
+
+    /* standard clamping */
+    if (start < 0)
+        start = 0;
+    if (end < 0)
+        end = 0;
+    if (end > self->extra->length)
+        end = self->extra->length;
+    if (start > end)
+        start = end;
+
+    list = PyList_New(end - start);
+    if (!list)
+        return NULL;
+
+    for (i = start; i < end; i++) {
+        PyObject* item = self->extra->children[i];
+        Py_INCREF(item);
+        PyList_SET_ITEM(list, i - start, item);
+    }
+
+    return list;
+}
+
+static PyObject*
+element_insert(ElementObject* self, PyObject* args)
+{
+    int i;
+
+    int index;
+    PyObject* element;
+    if (!PyArg_ParseTuple(args, "iO!:insert", &index,
+                          &Element_Type, &element))
+        return NULL;
+
+    if (!self->extra)
+        element_new_extra(self, NULL);
+
+    if (index < 0)
+        index = 0;
+    if (index > self->extra->length)
+        index = self->extra->length;
+
+    if (element_resize(self, 1) < 0)
+        return NULL;
+
+    for (i = self->extra->length; i > index; i--)
+        self->extra->children[i] = self->extra->children[i-1];
+
+    Py_INCREF(element);
+    self->extra->children[index] = element;
+
+    self->extra->length++;
+
+    Py_RETURN_NONE;
+}
+
+static PyObject*
+element_items(ElementObject* self, PyObject* args)
+{
+    if (!PyArg_ParseTuple(args, ":items"))
+        return NULL;
+
+    if (!self->extra || self->extra->attrib == Py_None)
+        return PyList_New(0);
+
+    return PyDict_Items(self->extra->attrib);
+}
+
+static PyObject*
+element_keys(ElementObject* self, PyObject* args)
+{
+    if (!PyArg_ParseTuple(args, ":keys"))
+        return NULL;
+
+    if (!self->extra || self->extra->attrib == Py_None)
+        return PyList_New(0);
+
+    return PyDict_Keys(self->extra->attrib);
+}
+
+static Py_ssize_t
+element_length(ElementObject* self)
+{
+    if (!self->extra)
+        return 0;
+
+    return self->extra->length;
+}
+
+static PyObject*
+element_makeelement(PyObject* self, PyObject* args, PyObject* kw)
+{
+    PyObject* elem;
+
+    PyObject* tag;
+    PyObject* attrib;
+    if (!PyArg_ParseTuple(args, "OO:makeelement", &tag, &attrib))
+        return NULL;
+
+    attrib = PyDict_Copy(attrib);
+    if (!attrib)
+        return NULL;
+
+    elem = element_new(tag, attrib);
+
+    Py_DECREF(attrib);
+
+    return elem;
+}
+
+static PyObject*
+element_reduce(ElementObject* self, PyObject* args)
+{
+    if (!PyArg_ParseTuple(args, ":__reduce__"))
+        return NULL;
+
+    /* Hack alert: This method is used to work around a __copy__
+       problem on certain 2.3 and 2.4 versions.  To save time and
+       simplify the code, we create the copy in here, and use a dummy
+       copyelement helper to trick the copy module into doing the
+       right thing. */
+
+    if (!elementtree_copyelement_obj) {
+        PyErr_SetString(
+            PyExc_RuntimeError,
+            "copyelement helper not found"
+            );
+        return NULL;
+    }
+
+    return Py_BuildValue(
+        "O(N)", elementtree_copyelement_obj, element_copy(self, args)
+        );
+}
+
+static PyObject*
+element_remove(ElementObject* self, PyObject* args)
+{
+    int i;
+
+    PyObject* element;
+    if (!PyArg_ParseTuple(args, "O!:remove", &Element_Type, &element))
+        return NULL;
+
+    if (!self->extra) {
+        /* element has no children, so raise exception */
+        PyErr_SetString(
+            PyExc_ValueError,
+            "list.remove(x): x not in list"
+            );
+        return NULL;
+    }
+
+    for (i = 0; i < self->extra->length; i++) {
+        if (self->extra->children[i] == element)
+            break;
+        if (PyObject_Compare(self->extra->children[i], element) == 0)
+            break;
+    }
+
+    if (i == self->extra->length) {
+        /* element is not in children, so raise exception */
+        PyErr_SetString(
+            PyExc_ValueError,
+            "list.remove(x): x not in list"
+            );
+        return NULL;
+    }
+
+    Py_DECREF(self->extra->children[i]);
+
+    self->extra->length--;
+
+    for (; i < self->extra->length; i++)
+        self->extra->children[i] = self->extra->children[i+1];
+
+    Py_RETURN_NONE;
+}
+
+static PyObject*
+element_repr(ElementObject* self)
+{
+    PyObject* repr;
+    char buffer[100];
+    
+    repr = PyString_FromString("<Element ");
+
+    PyString_ConcatAndDel(&repr, PyObject_Repr(self->tag));
+
+    sprintf(buffer, " at %p>", self);
+    PyString_ConcatAndDel(&repr, PyString_FromString(buffer));
+
+    return repr;
+}
+
+static PyObject*
+element_set(ElementObject* self, PyObject* args)
+{
+    PyObject* attrib;
+
+    PyObject* key;
+    PyObject* value;
+    if (!PyArg_ParseTuple(args, "OO:set", &key, &value))
+        return NULL;
+
+    if (!self->extra)
+        element_new_extra(self, NULL);
+
+    attrib = element_get_attrib(self);
+    if (!attrib)
+        return NULL;
+
+    if (PyDict_SetItem(attrib, key, value) < 0)
+        return NULL;
+
+    Py_RETURN_NONE;
+}
+
+static int
+element_setslice(PyObject* self_, Py_ssize_t start, Py_ssize_t end, PyObject* item)
+{
+    ElementObject* self = (ElementObject*) self_;
+    Py_ssize_t i, new, old;
+    PyObject* recycle = NULL;
+
+    if (!self->extra)
+        element_new_extra(self, NULL);
+
+    /* standard clamping */
+    if (start < 0)
+        start = 0;
+    if (end < 0)
+        end = 0;
+    if (end > self->extra->length)
+        end = self->extra->length;
+    if (start > end)
+        start = end;
+
+    old = end - start;
+
+    if (item == NULL)
+        new = 0;
+    else if (PyList_CheckExact(item)) {
+        new = PyList_GET_SIZE(item);
+    } else {
+        /* FIXME: support arbitrary sequences? */
+        PyErr_Format(
+            PyExc_TypeError,
+            "expected list, not \"%.200s\"", item->ob_type->tp_name
+            );
+        return -1;
+    }
+
+    if (old > 0) {
+        /* to avoid recursive calls to this method (via decref), move
+           old items to the recycle bin here, and get rid of them when
+           we're done modifying the element */
+        recycle = PyList_New(old);
+        for (i = 0; i < old; i++)
+            PyList_SET_ITEM(recycle, i, self->extra->children[i + start]);
+    }
+
+    if (new < old) {
+        /* delete slice */
+        for (i = end; i < self->extra->length; i++)
+            self->extra->children[i + new - old] = self->extra->children[i];
+    } else if (new > old) {
+        /* insert slice */
+        if (element_resize(self, new - old) < 0)
+            return -1;
+        for (i = self->extra->length-1; i >= end; i--)
+            self->extra->children[i + new - old] = self->extra->children[i];
+    }
+
+    /* replace the slice */
+    for (i = 0; i < new; i++) {
+        PyObject* element = PyList_GET_ITEM(item, i);
+        Py_INCREF(element);
+        self->extra->children[i + start] = element;
+    }
+
+    self->extra->length += new - old;
+
+    /* discard the recycle bin, and everything in it */
+    Py_XDECREF(recycle);
+
+    return 0;
+}
+
+static int
+element_setitem(PyObject* self_, Py_ssize_t index, PyObject* item)
+{
+    ElementObject* self = (ElementObject*) self_;
+    int i;
+    PyObject* old;
+
+    if (!self->extra || index < 0 || index >= self->extra->length) {
+        PyErr_SetString(
+            PyExc_IndexError,
+            "child assignment index out of range");
+        return -1;
+    }
+
+    old = self->extra->children[index];
+
+    if (item) {
+        Py_INCREF(item);
+        self->extra->children[index] = item;
+    } else {
+        self->extra->length--;
+        for (i = index; i < self->extra->length; i++)
+            self->extra->children[i] = self->extra->children[i+1];
+    }
+
+    Py_DECREF(old);
+
+    return 0;
+}
+
+static PyMethodDef element_methods[] = {
+
+    {"clear", (PyCFunction) element_clear, METH_VARARGS},
+
+    {"get", (PyCFunction) element_get, METH_VARARGS},
+    {"set", (PyCFunction) element_set, METH_VARARGS},
+
+    {"find", (PyCFunction) element_find, METH_VARARGS},
+    {"findtext", (PyCFunction) element_findtext, METH_VARARGS},
+    {"findall", (PyCFunction) element_findall, METH_VARARGS},
+
+    {"append", (PyCFunction) element_append, METH_VARARGS},
+    {"insert", (PyCFunction) element_insert, METH_VARARGS},
+    {"remove", (PyCFunction) element_remove, METH_VARARGS},
+
+    {"getiterator", (PyCFunction) element_getiterator, METH_VARARGS},
+    {"getchildren", (PyCFunction) element_getchildren, METH_VARARGS},
+
+    {"items", (PyCFunction) element_items, METH_VARARGS},
+    {"keys", (PyCFunction) element_keys, METH_VARARGS},
+
+    {"makeelement", (PyCFunction) element_makeelement, METH_VARARGS},
+
+    {"__copy__", (PyCFunction) element_copy, METH_VARARGS},
+    {"__deepcopy__", (PyCFunction) element_deepcopy, METH_VARARGS},
+
+    /* Some 2.3 and 2.4 versions do not handle the __copy__ method on
+       C objects correctly, so we have to fake it using a __reduce__-
+       based hack (see the element_reduce implementation above for
+       details). */
+
+    /* The behaviour has been changed in 2.3.5 and 2.4.1, so we're
+       using a runtime test to figure out if we need to fake things
+       or now (see the init code below).  The following entry is
+       enabled only if the hack is needed. */
+
+    {"!__reduce__", (PyCFunction) element_reduce, METH_VARARGS},
+
+    {NULL, NULL}
+};
+
+static PyObject*  
+element_getattr(ElementObject* self, char* name)
+{
+    PyObject* res;
+
+    res = Py_FindMethod(element_methods, (PyObject*) self, name);
+    if (res)
+	return res;
+
+    PyErr_Clear();
+
+    if (strcmp(name, "tag") == 0)
+	res = self->tag;
+    else if (strcmp(name, "text") == 0)
+        res = element_get_text(self);
+    else if (strcmp(name, "tail") == 0) {
+        res = element_get_tail(self);
+    } else if (strcmp(name, "attrib") == 0) {
+        if (!self->extra)
+            element_new_extra(self, NULL);
+	res = element_get_attrib(self);
+    } else {
+        PyErr_SetString(PyExc_AttributeError, name);
+        return NULL;
+    }
+
+    if (!res)
+        return NULL;
+
+    Py_INCREF(res);
+    return res;
+}
+
+static int
+element_setattr(ElementObject* self, const char* name, PyObject* value)
+{
+    if (value == NULL) {
+        PyErr_SetString(
+            PyExc_AttributeError,
+            "can't delete element attributes"
+            );
+        return -1;
+    }
+
+    if (strcmp(name, "tag") == 0) {
+        Py_DECREF(self->tag);
+        self->tag = value;
+        Py_INCREF(self->tag);
+    } else if (strcmp(name, "text") == 0) {
+        Py_DECREF(JOIN_OBJ(self->text));
+        self->text = value;
+        Py_INCREF(self->text);
+    } else if (strcmp(name, "tail") == 0) {
+        Py_DECREF(JOIN_OBJ(self->tail));
+        self->tail = value;
+        Py_INCREF(self->tail);
+    } else if (strcmp(name, "attrib") == 0) {
+        if (!self->extra)
+            element_new_extra(self, NULL);
+        Py_DECREF(self->extra->attrib);
+        self->extra->attrib = value;
+        Py_INCREF(self->extra->attrib);
+    } else {
+        PyErr_SetString(PyExc_AttributeError, name);
+        return -1;
+    }
+
+    return 0;
+}
+
+static PySequenceMethods element_as_sequence = {
+    (lenfunc) element_length,
+    0, /* sq_concat */
+    0, /* sq_repeat */
+    element_getitem,
+    element_getslice,
+    element_setitem,
+    element_setslice,
+};
+
+statichere PyTypeObject Element_Type = {
+    PyObject_HEAD_INIT(NULL)
+    0, "Element", sizeof(ElementObject), 0,
+    /* methods */
+    (destructor)element_dealloc, /* tp_dealloc */
+    0, /* tp_print */
+    (getattrfunc)element_getattr, /* tp_getattr */
+    (setattrfunc)element_setattr, /* tp_setattr */
+    0, /* tp_compare */
+    (reprfunc)element_repr, /* tp_repr */
+    0, /* tp_as_number */
+    &element_as_sequence, /* tp_as_sequence */
+};
+
+/* ==================================================================== */
+/* the tree builder type */
+
+typedef struct {
+    PyObject_HEAD
+
+    PyObject* root; /* root node (first created node) */
+
+    ElementObject* this; /* current node */
+    ElementObject* last; /* most recently created node */
+
+    PyObject* data; /* data collector (string or list), or NULL */
+
+    PyObject* stack; /* element stack */
+    Py_ssize_t index; /* current stack size (0=empty) */
+
+    /* element tracing */
+    PyObject* events; /* list of events, or NULL if not collecting */
+    PyObject* start_event_obj; /* event objects (NULL to ignore) */
+    PyObject* end_event_obj;
+    PyObject* start_ns_event_obj;
+    PyObject* end_ns_event_obj;
+
+} TreeBuilderObject;
+
+staticforward PyTypeObject TreeBuilder_Type;
+
+#define TreeBuilder_CheckExact(op) ((op)->ob_type == &TreeBuilder_Type)
+
+/* -------------------------------------------------------------------- */
+/* constructor and destructor */
+
+LOCAL(PyObject*)
+treebuilder_new(void)
+{
+    TreeBuilderObject* self;
+
+    self = PyObject_New(TreeBuilderObject, &TreeBuilder_Type);
+    if (self == NULL)
+        return NULL;
+
+    self->root = NULL;
+
+    Py_INCREF(Py_None);
+    self->this = (ElementObject*) Py_None;
+
+    Py_INCREF(Py_None);
+    self->last = (ElementObject*) Py_None;
+
+    self->data = NULL;
+
+    self->stack = PyList_New(20);
+    self->index = 0;
+
+    self->events = NULL;
+    self->start_event_obj = self->end_event_obj = NULL;
+    self->start_ns_event_obj = self->end_ns_event_obj = NULL;
+
+    ALLOC(sizeof(TreeBuilderObject), "create treebuilder");
+
+    return (PyObject*) self;
+}
+
+static PyObject*
+treebuilder(PyObject* self_, PyObject* args)
+{
+    if (!PyArg_ParseTuple(args, ":TreeBuilder"))
+        return NULL;
+
+    return treebuilder_new();
+}
+
+static void
+treebuilder_dealloc(TreeBuilderObject* self)
+{
+    Py_XDECREF(self->end_ns_event_obj);
+    Py_XDECREF(self->start_ns_event_obj);
+    Py_XDECREF(self->end_event_obj);
+    Py_XDECREF(self->start_event_obj);
+    Py_XDECREF(self->events);
+    Py_DECREF(self->stack);
+    Py_XDECREF(self->data);
+    Py_DECREF(self->last);
+    Py_DECREF(self->this);
+    Py_XDECREF(self->root);
+
+    RELEASE(sizeof(TreeBuilderObject), "destroy treebuilder");
+
+    PyObject_Del(self);
+}
+
+/* -------------------------------------------------------------------- */
+/* handlers */
+
+LOCAL(PyObject*)
+treebuilder_handle_xml(TreeBuilderObject* self, PyObject* encoding,
+                       PyObject* standalone)
+{
+    Py_RETURN_NONE;
+}
+
+LOCAL(PyObject*)
+treebuilder_handle_start(TreeBuilderObject* self, PyObject* tag,
+                         PyObject* attrib)
+{
+    PyObject* node;
+    PyObject* this;
+
+    if (self->data) {
+        if (self->this == self->last) {
+            Py_DECREF(JOIN_OBJ(self->last->text));
+            self->last->text = JOIN_SET(
+                self->data, PyList_CheckExact(self->data)
+                );
+        } else {
+            Py_DECREF(JOIN_OBJ(self->last->tail));
+            self->last->tail = JOIN_SET(
+                self->data, PyList_CheckExact(self->data)
+                );
+        }
+        self->data = NULL;
+    }
+
+    node = element_new(tag, attrib);
+    if (!node)
+        return NULL;
+
+    this = (PyObject*) self->this;
+
+    if (this != Py_None) {
+        if (element_add_subelement((ElementObject*) this, node) < 0)
+            goto error;
+    } else {
+        if (self->root) {
+            PyErr_SetString(
+                PyExc_SyntaxError,
+                "multiple elements on top level"
+                );
+            goto error;
+        }
+        Py_INCREF(node);
+        self->root = node;
+    }
+
+    if (self->index < PyList_GET_SIZE(self->stack)) {
+        if (PyList_SetItem(self->stack, self->index, this) < 0)
+            goto error;
+        Py_INCREF(this);
+    } else {
+        if (PyList_Append(self->stack, this) < 0)
+            goto error;
+    }
+    self->index++;
+
+    Py_DECREF(this);
+    Py_INCREF(node);
+    self->this = (ElementObject*) node;
+
+    Py_DECREF(self->last);
+    Py_INCREF(node);
+    self->last = (ElementObject*) node;
+
+    if (self->start_event_obj) {
+        PyObject* res;
+        PyObject* action = self->start_event_obj;
+        res = PyTuple_New(2);
+        if (res) {
+            Py_INCREF(action); PyTuple_SET_ITEM(res, 0, (PyObject*) action);
+            Py_INCREF(node);   PyTuple_SET_ITEM(res, 1, (PyObject*) node);
+            PyList_Append(self->events, res);
+            Py_DECREF(res);
+        } else
+            PyErr_Clear(); /* FIXME: propagate error */
+    }
+
+    return node;
+
+  error:
+    Py_DECREF(node);
+    return NULL;
+}
+
+LOCAL(PyObject*)
+treebuilder_handle_data(TreeBuilderObject* self, PyObject* data)
+{
+    if (!self->data) {
+        if (self->last == (ElementObject*) Py_None) {
+            /* ignore calls to data before the first call to start */
+            Py_RETURN_NONE;
+        }
+        /* store the first item as is */
+        Py_INCREF(data); self->data = data;
+    } else {
+        /* more than one item; use a list to collect items */
+        if (PyString_CheckExact(self->data) && self->data->ob_refcnt == 1 &&
+            PyString_CheckExact(data) && PyString_GET_SIZE(data) == 1) {
+            /* expat often generates single character data sections; handle
+               the most common case by resizing the existing string... */
+            Py_ssize_t size = PyString_GET_SIZE(self->data);
+            if (_PyString_Resize(&self->data, size + 1) < 0)
+                return NULL;
+            PyString_AS_STRING(self->data)[size] = PyString_AS_STRING(data)[0];
+        } else if (PyList_CheckExact(self->data)) {
+            if (PyList_Append(self->data, data) < 0)
+                return NULL;
+        } else {
+            PyObject* list = PyList_New(2);
+            if (!list)
+                return NULL;
+            PyList_SET_ITEM(list, 0, self->data);
+            Py_INCREF(data); PyList_SET_ITEM(list, 1, data);
+            self->data = list;
+        }
+    }
+
+    Py_RETURN_NONE;
+}
+
+LOCAL(PyObject*)
+treebuilder_handle_end(TreeBuilderObject* self, PyObject* tag)
+{
+    PyObject* item;
+
+    if (self->data) {
+        if (self->this == self->last) {
+            Py_DECREF(JOIN_OBJ(self->last->text));
+            self->last->text = JOIN_SET(
+                self->data, PyList_CheckExact(self->data)
+                );
+        } else {
+            Py_DECREF(JOIN_OBJ(self->last->tail));
+            self->last->tail = JOIN_SET(
+                self->data, PyList_CheckExact(self->data)
+                );
+        }
+        self->data = NULL;
+    }
+
+    if (self->index == 0) {
+        PyErr_SetString(
+            PyExc_IndexError,
+            "pop from empty stack"
+            );
+        return NULL;
+    }
+
+    self->index--;
+
+    item = PyList_GET_ITEM(self->stack, self->index);
+    Py_INCREF(item);
+
+    Py_DECREF(self->last);
+
+    self->last = (ElementObject*) self->this;
+    self->this = (ElementObject*) item;
+
+    if (self->end_event_obj) {
+        PyObject* res;
+        PyObject* action = self->end_event_obj;
+        PyObject* node = (PyObject*) self->last;
+        res = PyTuple_New(2);
+        if (res) {
+            Py_INCREF(action); PyTuple_SET_ITEM(res, 0, (PyObject*) action);
+            Py_INCREF(node);   PyTuple_SET_ITEM(res, 1, (PyObject*) node);
+            PyList_Append(self->events, res);
+            Py_DECREF(res);
+        } else
+            PyErr_Clear(); /* FIXME: propagate error */
+    }
+
+    Py_INCREF(self->last);
+    return (PyObject*) self->last;
+}
+
+LOCAL(void)
+treebuilder_handle_namespace(TreeBuilderObject* self, int start,
+                             const char* prefix, const char *uri)
+{
+    PyObject* res;
+    PyObject* action;
+    PyObject* parcel;
+
+    if (!self->events)
+        return;
+
+    if (start) {
+        if (!self->start_ns_event_obj)
+            return;
+        action = self->start_ns_event_obj;
+        /* FIXME: prefix and uri use utf-8 encoding! */
+        parcel = Py_BuildValue("ss", (prefix) ? prefix : "", uri);
+        if (!parcel)
+            return;
+        Py_INCREF(action);
+    } else {
+        if (!self->end_ns_event_obj)
+            return;
+        action = self->end_ns_event_obj;
+        Py_INCREF(action);
+        parcel = Py_None;
+        Py_INCREF(parcel);
+    }
+
+    res = PyTuple_New(2);
+
+    if (res) {
+        PyTuple_SET_ITEM(res, 0, action);
+        PyTuple_SET_ITEM(res, 1, parcel);
+        PyList_Append(self->events, res);
+        Py_DECREF(res);
+    } else
+        PyErr_Clear(); /* FIXME: propagate error */
+}
+
+/* -------------------------------------------------------------------- */
+/* methods (in alphabetical order) */
+
+static PyObject*
+treebuilder_data(TreeBuilderObject* self, PyObject* args)
+{
+    PyObject* data;
+    if (!PyArg_ParseTuple(args, "O:data", &data))
+        return NULL;
+
+    return treebuilder_handle_data(self, data);
+}
+
+static PyObject*
+treebuilder_end(TreeBuilderObject* self, PyObject* args)
+{
+    PyObject* tag;
+    if (!PyArg_ParseTuple(args, "O:end", &tag))
+        return NULL;
+
+    return treebuilder_handle_end(self, tag);
+}
+
+LOCAL(PyObject*)
+treebuilder_done(TreeBuilderObject* self)
+{
+    PyObject* res;
+
+    /* FIXME: check stack size? */
+
+    if (self->root)
+        res = self->root;
+    else
+        res = Py_None;
+
+    Py_INCREF(res);
+    return res;
+}
+
+static PyObject*
+treebuilder_close(TreeBuilderObject* self, PyObject* args)
+{
+    if (!PyArg_ParseTuple(args, ":close"))
+        return NULL;
+
+    return treebuilder_done(self);
+}
+
+static PyObject*
+treebuilder_start(TreeBuilderObject* self, PyObject* args)
+{
+    PyObject* tag;
+    PyObject* attrib = Py_None;
+    if (!PyArg_ParseTuple(args, "O|O:start", &tag, &attrib))
+        return NULL;
+
+    return treebuilder_handle_start(self, tag, attrib);
+}
+
+static PyObject*
+treebuilder_xml(TreeBuilderObject* self, PyObject* args)
+{
+    PyObject* encoding;
+    PyObject* standalone;
+    if (!PyArg_ParseTuple(args, "OO:xml", &encoding, &standalone))
+        return NULL;
+
+    return treebuilder_handle_xml(self, encoding, standalone);
+}
+
+static PyMethodDef treebuilder_methods[] = {
+    {"data", (PyCFunction) treebuilder_data, METH_VARARGS},
+    {"start", (PyCFunction) treebuilder_start, METH_VARARGS},
+    {"end", (PyCFunction) treebuilder_end, METH_VARARGS},
+    {"xml", (PyCFunction) treebuilder_xml, METH_VARARGS},
+    {"close", (PyCFunction) treebuilder_close, METH_VARARGS},
+    {NULL, NULL}
+};
+
+static PyObject*  
+treebuilder_getattr(TreeBuilderObject* self, char* name)
+{
+    return Py_FindMethod(treebuilder_methods, (PyObject*) self, name);
+}
+
+statichere PyTypeObject TreeBuilder_Type = {
+    PyObject_HEAD_INIT(NULL)
+    0, "TreeBuilder", sizeof(TreeBuilderObject), 0,
+    /* methods */
+    (destructor)treebuilder_dealloc, /* tp_dealloc */
+    0, /* tp_print */
+    (getattrfunc)treebuilder_getattr, /* tp_getattr */
+};
+
+/* ==================================================================== */
+/* the expat interface */
+
+#if defined(USE_EXPAT)
+
+#include "expat.h"
+
+#if defined(USE_PYEXPAT_CAPI)
+#include "pyexpat.h"
+static struct PyExpat_CAPI* expat_capi;
+#define EXPAT(func) (expat_capi->func)
+#else
+#define EXPAT(func) (XML_##func)
+#endif
+
+typedef struct {
+    PyObject_HEAD
+
+    XML_Parser parser;
+
+    PyObject* target;
+    PyObject* entity;
+
+    PyObject* names;
+
+    PyObject* handle_xml;
+    PyObject* handle_start;
+    PyObject* handle_data;
+    PyObject* handle_end;
+
+    PyObject* handle_comment;
+    PyObject* handle_pi;
+
+} XMLParserObject;
+
+staticforward PyTypeObject XMLParser_Type;
+
+/* helpers */
+
+#if defined(Py_USING_UNICODE)
+LOCAL(int)
+checkstring(const char* string, int size)
+{
+    int i;
+
+    /* check if an 8-bit string contains UTF-8 characters */
+    for (i = 0; i < size; i++)
+        if (string[i] & 0x80)
+            return 1;
+
+    return 0;
+}
+#endif
+
+LOCAL(PyObject*)
+makestring(const char* string, int size)
+{
+    /* convert a UTF-8 string to either a 7-bit ascii string or a
+       Unicode string */
+
+#if defined(Py_USING_UNICODE)
+    if (checkstring(string, size))
+        return PyUnicode_DecodeUTF8(string, size, "strict");
+#endif
+
+    return PyString_FromStringAndSize(string, size);
+}
+
+LOCAL(PyObject*)
+makeuniversal(XMLParserObject* self, const char* string)
+{
+    /* convert a UTF-8 tag/attribute name from the expat parser
+       to a universal name string */
+
+    int size = strlen(string);
+    PyObject* key;
+    PyObject* value;
+
+    /* look the 'raw' name up in the names dictionary */
+    key = PyString_FromStringAndSize(string, size);
+    if (!key)
+        return NULL;
+
+    value = PyDict_GetItem(self->names, key);
+
+    if (value) {
+        Py_INCREF(value);
+    } else {
+        /* new name.  convert to universal name, and decode as
+           necessary */
+
+        PyObject* tag;
+        char* p;
+        int i;
+
+        /* look for namespace separator */
+        for (i = 0; i < size; i++)
+            if (string[i] == '}')
+                break;
+        if (i != size) {
+            /* convert to universal name */
+            tag = PyString_FromStringAndSize(NULL, size+1);
+            p = PyString_AS_STRING(tag);
+            p[0] = '{';
+            memcpy(p+1, string, size);
+            size++;
+        } else {
+            /* plain name; use key as tag */
+            Py_INCREF(key);
+            tag = key;
+        }
+        
+        /* decode universal name */
+#if defined(Py_USING_UNICODE)
+        /* inline makestring, to avoid duplicating the source string if
+           it's not an utf-8 string */
+        p = PyString_AS_STRING(tag);
+        if (checkstring(p, size)) {
+            value = PyUnicode_DecodeUTF8(p, size, "strict");
+            Py_DECREF(tag);
+            if (!value) {
+                Py_DECREF(key);
+                return NULL;
+            }
+        } else
+#endif
+            value = tag; /* use tag as is */
+
+        /* add to names dictionary */
+        if (PyDict_SetItem(self->names, key, value) < 0) {
+            Py_DECREF(key);
+            Py_DECREF(value);
+            return NULL;
+        }
+    }
+
+    Py_DECREF(key);
+    return value;
+}
+
+/* -------------------------------------------------------------------- */
+/* handlers */
+
+static void
+expat_default_handler(XMLParserObject* self, const XML_Char* data_in,
+                      int data_len)
+{
+    PyObject* key;
+    PyObject* value;
+    PyObject* res;
+
+    if (data_len < 2 || data_in[0] != '&')
+        return;
+
+    key = makestring(data_in + 1, data_len - 2);
+    if (!key)
+        return;
+
+    value = PyDict_GetItem(self->entity, key);
+
+    if (value) {
+        if (TreeBuilder_CheckExact(self->target))
+            res = treebuilder_handle_data(
+                (TreeBuilderObject*) self->target, value
+                );
+        else if (self->handle_data)
+            res = PyObject_CallFunction(self->handle_data, "O", value);
+        else
+            res = NULL;
+        Py_XDECREF(res);
+    } else {
+        PyErr_Format(
+            PyExc_SyntaxError, "undefined entity &%s;: line %ld, column %ld",
+            PyString_AS_STRING(key),
+            EXPAT(GetErrorLineNumber)(self->parser),
+            EXPAT(GetErrorColumnNumber)(self->parser)
+            );
+    }
+
+    Py_DECREF(key);
+}
+
+static void
+expat_start_handler(XMLParserObject* self, const XML_Char* tag_in,
+                    const XML_Char **attrib_in)
+{
+    PyObject* res;
+    PyObject* tag;
+    PyObject* attrib;
+    int ok;
+
+    /* tag name */
+    tag = makeuniversal(self, tag_in);
+    if (!tag)
+        return; /* parser will look for errors */
+
+    /* attributes */
+    if (attrib_in[0]) {
+        attrib = PyDict_New();
+        if (!attrib)
+            return;
+        while (attrib_in[0] && attrib_in[1]) {
+            PyObject* key = makeuniversal(self, attrib_in[0]);
+            PyObject* value = makestring(attrib_in[1], strlen(attrib_in[1]));
+            if (!key || !value) {
+                Py_XDECREF(value);
+                Py_XDECREF(key);
+                Py_DECREF(attrib);
+                return;
+            }
+            ok = PyDict_SetItem(attrib, key, value);
+            Py_DECREF(value);
+            Py_DECREF(key);
+            if (ok < 0) {
+                Py_DECREF(attrib);
+                return;
+            }
+            attrib_in += 2;
+        }
+    } else {
+        Py_INCREF(Py_None);
+        attrib = Py_None;
+    }
+
+    if (TreeBuilder_CheckExact(self->target))
+        /* shortcut */
+        res = treebuilder_handle_start((TreeBuilderObject*) self->target,
+                                       tag, attrib);
+    else if (self->handle_start)
+        res = PyObject_CallFunction(self->handle_start, "OO", tag, attrib);
+    else
+        res = NULL;
+
+    Py_DECREF(tag);
+    Py_DECREF(attrib);
+
+    Py_XDECREF(res);
+}
+
+static void
+expat_data_handler(XMLParserObject* self, const XML_Char* data_in,
+                   int data_len)
+{
+    PyObject* data;
+    PyObject* res;
+
+    data = makestring(data_in, data_len);
+    if (!data)
+        return; /* parser will look for errors */
+
+    if (TreeBuilder_CheckExact(self->target))
+        /* shortcut */
+        res = treebuilder_handle_data((TreeBuilderObject*) self->target, data);
+    else if (self->handle_data)
+        res = PyObject_CallFunction(self->handle_data, "O", data);
+    else
+        res = NULL;
+
+    Py_DECREF(data);
+
+    Py_XDECREF(res);
+}
+
+static void
+expat_end_handler(XMLParserObject* self, const XML_Char* tag_in)
+{
+    PyObject* tag;
+    PyObject* res = NULL;
+
+    if (TreeBuilder_CheckExact(self->target))
+        /* shortcut */
+        /* the standard tree builder doesn't look at the end tag */
+        res = treebuilder_handle_end(
+            (TreeBuilderObject*) self->target, Py_None
+            );
+    else if (self->handle_end) {
+        tag = makeuniversal(self, tag_in);
+        if (tag) {
+            res = PyObject_CallFunction(self->handle_end, "O", tag);
+            Py_DECREF(tag);
+        }
+    }
+
+    Py_XDECREF(res);
+}
+
+static void
+expat_start_ns_handler(XMLParserObject* self, const XML_Char* prefix,
+                       const XML_Char *uri)
+{
+    treebuilder_handle_namespace(
+        (TreeBuilderObject*) self->target, 1, prefix, uri
+        );
+}
+
+static void
+expat_end_ns_handler(XMLParserObject* self, const XML_Char* prefix_in)
+{
+    treebuilder_handle_namespace(
+        (TreeBuilderObject*) self->target, 0, NULL, NULL
+        );
+}
+
+static void
+expat_comment_handler(XMLParserObject* self, const XML_Char* comment_in)
+{
+    PyObject* comment;
+    PyObject* res;
+
+    if (self->handle_comment) {
+        comment = makestring(comment_in, strlen(comment_in));
+        if (comment) {
+            res = PyObject_CallFunction(self->handle_comment, "O", comment);
+            Py_XDECREF(res);
+            Py_DECREF(comment);
+        }
+    }
+}
+
+static void
+expat_pi_handler(XMLParserObject* self, const XML_Char* target_in,
+                 const XML_Char* data_in)
+{
+    PyObject* target;
+    PyObject* data;
+    PyObject* res;
+
+    if (self->handle_pi) {
+        target = makestring(target_in, strlen(target_in));
+        data = makestring(data_in, strlen(data_in));
+        if (target && data) {
+            res = PyObject_CallFunction(self->handle_pi, "OO", target, data);
+            Py_XDECREF(res);
+            Py_DECREF(data);
+            Py_DECREF(target);
+        } else {
+            Py_XDECREF(data);
+            Py_XDECREF(target);
+        }
+    }
+}
+
+#if defined(Py_USING_UNICODE)
+static int
+expat_unknown_encoding_handler(XMLParserObject *self, const XML_Char *name,
+                               XML_Encoding *info)
+{
+    PyObject* u;
+    Py_UNICODE* p;
+    unsigned char s[256];
+    int i;
+
+    memset(info, 0, sizeof(XML_Encoding));
+
+    for (i = 0; i < 256; i++)
+        s[i] = i;
+    
+    u = PyUnicode_Decode((char*) s, 256, name, "replace");
+    if (!u)
+        return XML_STATUS_ERROR;
+
+    if (PyUnicode_GET_SIZE(u) != 256) {
+        Py_DECREF(u);
+        return XML_STATUS_ERROR;
+    }
+
+    p = PyUnicode_AS_UNICODE(u);
+
+    for (i = 0; i < 256; i++) {
+	if (p[i] != Py_UNICODE_REPLACEMENT_CHARACTER)
+	    info->map[i] = p[i];
+        else
+	    info->map[i] = -1;
+    }
+
+    Py_DECREF(u);
+
+    return XML_STATUS_OK;
+}
+#endif
+
+/* -------------------------------------------------------------------- */
+/* constructor and destructor */
+
+static PyObject*
+xmlparser(PyObject* self_, PyObject* args, PyObject* kw)
+{
+    XMLParserObject* self;
+    /* FIXME: does this need to be static? */
+    static XML_Memory_Handling_Suite memory_handler;
+
+    PyObject* target = NULL;
+    char* encoding = NULL;
+    static char* kwlist[] = { "target", "encoding", NULL };
+    if (!PyArg_ParseTupleAndKeywords(args, kw, "|Oz:XMLParser", kwlist,
+                                     &target, &encoding))
+        return NULL;
+
+#if defined(USE_PYEXPAT_CAPI)
+    if (!expat_capi) {
+        PyErr_SetString(
+            PyExc_RuntimeError, "cannot load dispatch table from pyexpat"
+            );
+        return NULL;
+    }
+#endif
+
+    self = PyObject_New(XMLParserObject, &XMLParser_Type);
+    if (self == NULL)
+        return NULL;
+
+    self->entity = PyDict_New();
+    if (!self->entity) {
+        PyObject_Del(self);
+        return NULL;
+    }
+     
+    self->names = PyDict_New();
+    if (!self->names) {
+        PyObject_Del(self->entity);
+        PyObject_Del(self);
+        return NULL;
+    }
+
+    memory_handler.malloc_fcn = PyObject_Malloc;
+    memory_handler.realloc_fcn = PyObject_Realloc;
+    memory_handler.free_fcn = PyObject_Free;
+
+    self->parser = EXPAT(ParserCreate_MM)(encoding, &memory_handler, "}");
+    if (!self->parser) {
+        PyObject_Del(self->names);
+        PyObject_Del(self->entity);
+        PyObject_Del(self);
+        PyErr_NoMemory();
+        return NULL;
+    }
+
+    /* setup target handlers */
+    if (!target) {
+        target = treebuilder_new();
+        if (!target) {
+            EXPAT(ParserFree)(self->parser);
+            PyObject_Del(self->names);
+            PyObject_Del(self->entity);
+            PyObject_Del(self);
+            return NULL;
+        }
+    } else
+        Py_INCREF(target);
+    self->target = target;
+
+    self->handle_xml = PyObject_GetAttrString(target, "xml");
+    self->handle_start = PyObject_GetAttrString(target, "start");
+    self->handle_data = PyObject_GetAttrString(target, "data");
+    self->handle_end = PyObject_GetAttrString(target, "end");
+    self->handle_comment = PyObject_GetAttrString(target, "comment");
+    self->handle_pi = PyObject_GetAttrString(target, "pi");
+
+    PyErr_Clear();
+
+    /* configure parser */
+    EXPAT(SetUserData)(self->parser, self);
+    EXPAT(SetElementHandler)(
+        self->parser,
+        (XML_StartElementHandler) expat_start_handler,
+        (XML_EndElementHandler) expat_end_handler
+        );
+    EXPAT(SetDefaultHandlerExpand)(
+        self->parser,
+        (XML_DefaultHandler) expat_default_handler
+        );
+    EXPAT(SetCharacterDataHandler)(
+        self->parser,
+        (XML_CharacterDataHandler) expat_data_handler
+        );
+    if (self->handle_comment)
+        EXPAT(SetCommentHandler)(
+            self->parser,
+            (XML_CommentHandler) expat_comment_handler
+            );
+    if (self->handle_pi)
+        EXPAT(SetProcessingInstructionHandler)(
+            self->parser,
+            (XML_ProcessingInstructionHandler) expat_pi_handler
+            );
+#if defined(Py_USING_UNICODE)
+    EXPAT(SetUnknownEncodingHandler)(
+        self->parser,
+        (XML_UnknownEncodingHandler) expat_unknown_encoding_handler, NULL
+        );
+#endif
+
+    ALLOC(sizeof(XMLParserObject), "create expatparser");
+
+    return (PyObject*) self;
+}
+
+static void
+xmlparser_dealloc(XMLParserObject* self)
+{
+    EXPAT(ParserFree)(self->parser);
+
+    Py_XDECREF(self->handle_pi);
+    Py_XDECREF(self->handle_comment);
+    Py_XDECREF(self->handle_end);
+    Py_XDECREF(self->handle_data);
+    Py_XDECREF(self->handle_start);
+    Py_XDECREF(self->handle_xml);
+
+    Py_DECREF(self->target);
+    Py_DECREF(self->entity);
+    Py_DECREF(self->names);
+
+    RELEASE(sizeof(XMLParserObject), "destroy expatparser");
+
+    PyObject_Del(self);
+}
+
+/* -------------------------------------------------------------------- */
+/* methods (in alphabetical order) */
+
+LOCAL(PyObject*)
+expat_parse(XMLParserObject* self, char* data, int data_len, int final)
+{
+    int ok;
+
+    ok = EXPAT(Parse)(self->parser, data, data_len, final);
+
+    if (PyErr_Occurred())
+        return NULL;
+
+    if (!ok) {
+        PyErr_Format(
+            PyExc_SyntaxError, "%s: line %ld, column %ld",
+            EXPAT(ErrorString)(EXPAT(GetErrorCode)(self->parser)),
+            EXPAT(GetErrorLineNumber)(self->parser),
+            EXPAT(GetErrorColumnNumber)(self->parser)
+            );
+        return NULL;
+    }
+
+    Py_RETURN_NONE;
+}
+
+static PyObject*
+xmlparser_close(XMLParserObject* self, PyObject* args)
+{
+    /* end feeding data to parser */
+
+    PyObject* res;
+    if (!PyArg_ParseTuple(args, ":close"))
+        return NULL;
+
+    res = expat_parse(self, "", 0, 1);
+
+    if (res && TreeBuilder_CheckExact(self->target)) {
+        Py_DECREF(res);
+        return treebuilder_done((TreeBuilderObject*) self->target);
+    }
+
+    return res;
+}
+
+static PyObject*
+xmlparser_feed(XMLParserObject* self, PyObject* args)
+{
+    /* feed data to parser */
+
+    char* data;
+    int data_len;
+    if (!PyArg_ParseTuple(args, "s#:feed", &data, &data_len))
+        return NULL;
+
+    return expat_parse(self, data, data_len, 0);
+}
+
+static PyObject*
+xmlparser_parse(XMLParserObject* self, PyObject* args)
+{
+    /* (internal) parse until end of input stream */
+
+    PyObject* reader;
+    PyObject* buffer;
+    PyObject* res;
+
+    PyObject* fileobj;
+    if (!PyArg_ParseTuple(args, "O:_parse", &fileobj))
+        return NULL;
+
+    reader = PyObject_GetAttrString(fileobj, "read");
+    if (!reader)
+        return NULL;
+    
+    /* read from open file object */
+    for (;;) {
+
+        buffer = PyObject_CallFunction(reader, "i", 64*1024);
+
+        if (!buffer) {
+            /* read failed (e.g. due to KeyboardInterrupt) */
+            Py_DECREF(reader);
+            return NULL;
+        }
+
+        if (!PyString_CheckExact(buffer) || PyString_GET_SIZE(buffer) == 0) {
+            Py_DECREF(buffer);
+            break;
+        }
+
+        res = expat_parse(
+            self, PyString_AS_STRING(buffer), PyString_GET_SIZE(buffer), 0
+            );
+
+        Py_DECREF(buffer);
+
+        if (!res) {
+            Py_DECREF(reader);
+            return NULL;
+        }
+        Py_DECREF(res);
+
+    }
+
+    Py_DECREF(reader);
+
+    res = expat_parse(self, "", 0, 1);
+
+    if (res && TreeBuilder_CheckExact(self->target)) {
+        Py_DECREF(res);
+        return treebuilder_done((TreeBuilderObject*) self->target);
+    }
+
+    return res;
+}
+
+static PyObject*
+xmlparser_setevents(XMLParserObject* self, PyObject* args)
+{
+    /* activate element event reporting */
+
+    Py_ssize_t i;
+    TreeBuilderObject* target;
+
+    PyObject* events; /* event collector */
+    PyObject* event_set = Py_None;
+    if (!PyArg_ParseTuple(args, "O!|O:_setevents",  &PyList_Type, &events,
+                          &event_set))
+        return NULL;
+
+    if (!TreeBuilder_CheckExact(self->target)) {
+        PyErr_SetString(
+            PyExc_TypeError,
+            "event handling only supported for cElementTree.Treebuilder "
+            "targets"
+            );
+        return NULL;
+    }
+
+    target = (TreeBuilderObject*) self->target;
+
+    Py_INCREF(events);
+    Py_XDECREF(target->events);
+    target->events = events;
+
+    /* clear out existing events */
+    Py_XDECREF(target->start_event_obj); target->start_event_obj = NULL;
+    Py_XDECREF(target->end_event_obj); target->end_event_obj = NULL;
+    Py_XDECREF(target->start_ns_event_obj); target->start_ns_event_obj = NULL;
+    Py_XDECREF(target->end_ns_event_obj); target->end_ns_event_obj = NULL;
+
+    if (event_set == Py_None) {
+        /* default is "end" only */
+        target->end_event_obj = PyString_FromString("end");
+        Py_RETURN_NONE;
+    }
+
+    if (!PyTuple_Check(event_set)) /* FIXME: handle arbitrary sequences */
+        goto error;
+
+    for (i = 0; i < PyTuple_GET_SIZE(event_set); i++) {
+        PyObject* item = PyTuple_GET_ITEM(event_set, i);
+        char* event;
+        if (!PyString_Check(item))
+            goto error;
+        event = PyString_AS_STRING(item);
+        if (strcmp(event, "start") == 0) {
+            Py_INCREF(item);
+            target->start_event_obj = item;
+        } else if (strcmp(event, "end") == 0) {
+            Py_INCREF(item);
+            Py_XDECREF(target->end_event_obj);
+            target->end_event_obj = item;
+        } else if (strcmp(event, "start-ns") == 0) {
+            Py_INCREF(item);
+            Py_XDECREF(target->start_ns_event_obj);
+            target->start_ns_event_obj = item;
+            EXPAT(SetNamespaceDeclHandler)(
+                self->parser,
+                (XML_StartNamespaceDeclHandler) expat_start_ns_handler,
+                (XML_EndNamespaceDeclHandler) expat_end_ns_handler
+                );
+        } else if (strcmp(event, "end-ns") == 0) {
+            Py_INCREF(item);
+            Py_XDECREF(target->end_ns_event_obj);
+            target->end_ns_event_obj = item;
+            EXPAT(SetNamespaceDeclHandler)(
+                self->parser,
+                (XML_StartNamespaceDeclHandler) expat_start_ns_handler,
+                (XML_EndNamespaceDeclHandler) expat_end_ns_handler
+                );
+        } else {
+            PyErr_Format(
+                PyExc_ValueError,
+                "unknown event '%s'", event
+                );
+            return NULL;
+        }
+    }
+
+    Py_RETURN_NONE;
+
+  error:
+    PyErr_SetString(
+        PyExc_TypeError,
+        "invalid event tuple"
+        );
+    return NULL;
+}
+
+static PyMethodDef xmlparser_methods[] = {
+    {"feed", (PyCFunction) xmlparser_feed, METH_VARARGS},
+    {"close", (PyCFunction) xmlparser_close, METH_VARARGS},
+    {"_parse", (PyCFunction) xmlparser_parse, METH_VARARGS},
+    {"_setevents", (PyCFunction) xmlparser_setevents, METH_VARARGS},
+    {NULL, NULL}
+};
+
+static PyObject*  
+xmlparser_getattr(XMLParserObject* self, char* name)
+{
+    PyObject* res;
+
+    res = Py_FindMethod(xmlparser_methods, (PyObject*) self, name);
+    if (res)
+	return res;
+
+    PyErr_Clear();
+
+    if (strcmp(name, "entity") == 0)
+	res = self->entity;
+    else if (strcmp(name, "target") == 0)
+	res = self->target;
+    else if (strcmp(name, "version") == 0) {
+        char buffer[100];
+        sprintf(buffer, "Expat %d.%d.%d", XML_MAJOR_VERSION,
+                XML_MINOR_VERSION, XML_MICRO_VERSION);
+        return PyString_FromString(buffer);
+    } else {
+        PyErr_SetString(PyExc_AttributeError, name);
+        return NULL;
+    }
+
+    Py_INCREF(res);
+    return res;
+}
+
+statichere PyTypeObject XMLParser_Type = {
+    PyObject_HEAD_INIT(NULL)
+    0, "XMLParser", sizeof(XMLParserObject), 0,
+    /* methods */
+    (destructor)xmlparser_dealloc, /* tp_dealloc */
+    0, /* tp_print */
+    (getattrfunc)xmlparser_getattr, /* tp_getattr */
+};
+
+#endif
+
+/* ==================================================================== */
+/* python module interface */
+
+static PyMethodDef _functions[] = {
+    {"Element", (PyCFunction) element, METH_VARARGS|METH_KEYWORDS},
+    {"SubElement", (PyCFunction) subelement, METH_VARARGS|METH_KEYWORDS},
+    {"TreeBuilder", (PyCFunction) treebuilder, METH_VARARGS},
+#if defined(USE_EXPAT)
+    {"XMLParser", (PyCFunction) xmlparser, METH_VARARGS|METH_KEYWORDS},
+    {"XMLTreeBuilder", (PyCFunction) xmlparser, METH_VARARGS|METH_KEYWORDS},
+#endif
+    {NULL, NULL}
+};
+
+DL_EXPORT(void)
+init_elementtree(void)
+{
+    PyObject* m;
+    PyObject* g;
+    char* bootstrap;
+#if defined(USE_PYEXPAT_CAPI)
+    struct PyExpat_CAPI* capi;
+#endif
+
+    /* Patch object type */
+    Element_Type.ob_type = TreeBuilder_Type.ob_type = &PyType_Type;
+#if defined(USE_EXPAT)
+    XMLParser_Type.ob_type = &PyType_Type;
+#endif
+
+    m = Py_InitModule("_elementtree", _functions);
+    if (!m)
+        return;
+
+    /* python glue code */
+
+    g = PyDict_New();
+    if (!g)
+        return;
+
+    PyDict_SetItemString(g, "__builtins__", PyEval_GetBuiltins());
+
+    bootstrap = (
+
+#if (PY_VERSION_HEX >= 0x02020000 && PY_VERSION_HEX < 0x02030000)
+        "from __future__ import generators\n" /* enable yield under 2.2 */
+#endif
+
+        "from copy import copy, deepcopy\n"
+
+        "try:\n"
+        "  from xml.etree import ElementTree\n"
+        "except ImportError:\n"
+        "  import ElementTree\n"
+        "ET = ElementTree\n"
+        "del ElementTree\n"
+
+        "import _elementtree as cElementTree\n"
+
+        "try:\n" /* check if copy works as is */
+        "  copy(cElementTree.Element('x'))\n"
+        "except:\n"
+        "  def copyelement(elem):\n"
+        "    return elem\n"
+
+        "def Comment(text=None):\n" /* public */
+        "  element = cElementTree.Element(ET.Comment)\n"
+        "  element.text = text\n"
+        "  return element\n"
+        "cElementTree.Comment = Comment\n"
+
+        "class ElementTree(ET.ElementTree):\n" /* public */
+        "  def parse(self, source, parser=None):\n"
+        "    if not hasattr(source, 'read'):\n"
+        "      source = open(source, 'rb')\n"
+        "    if parser is not None:\n"
+        "      while 1:\n"
+        "        data = source.read(65536)\n"
+        "        if not data:\n"
+        "          break\n"
+        "        parser.feed(data)\n"
+        "      self._root = parser.close()\n"
+        "    else:\n" 
+        "      parser = cElementTree.XMLParser()\n"
+        "      self._root = parser._parse(source)\n"
+        "    return self._root\n"
+        "cElementTree.ElementTree = ElementTree\n"
+
+        "def getiterator(node, tag=None):\n" /* helper */
+        "  if tag == '*':\n"
+        "    tag = None\n"
+#if (PY_VERSION_HEX < 0x02020000)
+        "  nodes = []\n" /* 2.1 doesn't have yield */
+        "  if tag is None or node.tag == tag:\n"
+        "    nodes.append(node)\n"
+        "  for node in node:\n"
+        "    nodes.extend(getiterator(node, tag))\n"
+        "  return nodes\n"
+#else
+        "  if tag is None or node.tag == tag:\n"
+        "    yield node\n"
+        "  for node in node:\n"
+        "    for node in getiterator(node, tag):\n"
+        "      yield node\n"
+#endif
+
+        "def parse(source, parser=None):\n" /* public */
+        "  tree = ElementTree()\n"
+        "  tree.parse(source, parser)\n"
+        "  return tree\n"
+        "cElementTree.parse = parse\n"
+
+#if (PY_VERSION_HEX < 0x02020000)
+        "if hasattr(ET, 'iterparse'):\n"
+        "    cElementTree.iterparse = ET.iterparse\n" /* delegate on 2.1 */
+#else
+        "class iterparse(object):\n"
+        " root = None\n"
+        " def __init__(self, file, events=None):\n"
+        "  if not hasattr(file, 'read'):\n"
+        "    file = open(file, 'rb')\n"
+        "  self._file = file\n"
+        "  self._events = events\n"
+        " def __iter__(self):\n" 
+        "  events = []\n"
+        "  b = cElementTree.TreeBuilder()\n"
+        "  p = cElementTree.XMLParser(b)\n"
+        "  p._setevents(events, self._events)\n"
+        "  while 1:\n"
+        "    data = self._file.read(16384)\n"
+        "    if not data:\n"
+        "      break\n"
+        "    p.feed(data)\n"
+        "    for event in events:\n"
+        "      yield event\n"
+        "    del events[:]\n"
+        "  root = p.close()\n"
+        "  for event in events:\n"
+        "    yield event\n"
+        "  self.root = root\n"
+        "cElementTree.iterparse = iterparse\n"
+#endif
+
+        "def PI(target, text=None):\n" /* public */
+        "  element = cElementTree.Element(ET.ProcessingInstruction)\n"
+        "  element.text = target\n"
+        "  if text:\n"
+        "    element.text = element.text + ' ' + text\n"
+        "  return element\n"
+
+        "  elem = cElementTree.Element(ET.PI)\n"
+        "  elem.text = text\n"
+        "  return elem\n"
+        "cElementTree.PI = cElementTree.ProcessingInstruction = PI\n"
+
+        "def XML(text):\n" /* public */
+        "  parser = cElementTree.XMLParser()\n"
+        "  parser.feed(text)\n"
+        "  return parser.close()\n"
+        "cElementTree.XML = cElementTree.fromstring = XML\n"
+
+        "def XMLID(text):\n" /* public */
+        "  tree = XML(text)\n"
+        "  ids = {}\n"
+        "  for elem in tree.getiterator():\n"
+        "    id = elem.get('id')\n"
+        "    if id:\n"
+        "      ids[id] = elem\n"
+        "  return tree, ids\n"
+        "cElementTree.XMLID = XMLID\n"
+
+        "cElementTree.dump = ET.dump\n"
+        "cElementTree.ElementPath = ElementPath = ET.ElementPath\n"
+        "cElementTree.iselement = ET.iselement\n"
+        "cElementTree.QName = ET.QName\n"
+        "cElementTree.tostring = ET.tostring\n"
+        "cElementTree.VERSION = '" VERSION "'\n"
+        "cElementTree.__version__ = '" VERSION "'\n"
+        "cElementTree.XMLParserError = SyntaxError\n"
+
+       );
+
+    PyRun_String(bootstrap, Py_file_input, g, NULL);
+
+    elementpath_obj = PyDict_GetItemString(g, "ElementPath");
+
+    elementtree_copyelement_obj = PyDict_GetItemString(g, "copyelement");
+    if (elementtree_copyelement_obj) {
+        /* reduce hack needed; enable reduce method */
+        PyMethodDef* mp;
+        for (mp = element_methods; mp->ml_name; mp++)
+            if (mp->ml_meth == (PyCFunction) element_reduce) {
+                mp->ml_name = "__reduce__";
+                break;
+            }
+    } else
+        PyErr_Clear();
+    elementtree_deepcopy_obj = PyDict_GetItemString(g, "deepcopy");
+    elementtree_getiterator_obj = PyDict_GetItemString(g, "getiterator");
+
+#if defined(USE_PYEXPAT_CAPI)
+    /* link against pyexpat, if possible */
+    capi = PyCObject_Import("pyexpat", "expat_CAPI");
+    if (capi &&
+        strcmp(capi->magic, PyExpat_CAPI_MAGIC) == 0 &&
+        capi->size <= sizeof(*expat_capi) &&
+        capi->MAJOR_VERSION == XML_MAJOR_VERSION &&
+        capi->MINOR_VERSION == XML_MINOR_VERSION &&
+        capi->MICRO_VERSION == XML_MICRO_VERSION)
+        expat_capi = capi;
+    else
+        expat_capi = NULL;
+#endif
+
+}

Added: vendor/Python/current/Modules/_functoolsmodule.c
===================================================================
--- vendor/Python/current/Modules/_functoolsmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_functoolsmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,277 @@
+
+#include "Python.h"
+#include "structmember.h"
+
+/* _functools module written and maintained 
+   by Hye-Shik Chang <perky at FreeBSD.org>
+   with adaptations by Raymond Hettinger <python at rcn.com>
+   Copyright (c) 2004, 2005, 2006 Python Software Foundation.
+   All rights reserved.
+*/
+
+/* partial object **********************************************************/
+
+typedef struct {
+	PyObject_HEAD
+	PyObject *fn;
+	PyObject *args;
+	PyObject *kw;
+	PyObject *dict;
+	PyObject *weakreflist; /* List of weak references */
+} partialobject;
+
+static PyTypeObject partial_type;
+
+static PyObject *
+partial_new(PyTypeObject *type, PyObject *args, PyObject *kw)
+{
+	PyObject *func;
+	partialobject *pto;
+
+	if (PyTuple_GET_SIZE(args) < 1) {
+		PyErr_SetString(PyExc_TypeError,
+				"type 'partial' takes at least one argument");
+		return NULL;
+	}
+
+	func = PyTuple_GET_ITEM(args, 0);
+	if (!PyCallable_Check(func)) {
+		PyErr_SetString(PyExc_TypeError,
+				"the first argument must be callable");
+		return NULL;
+	}
+
+	/* create partialobject structure */
+	pto = (partialobject *)type->tp_alloc(type, 0);
+	if (pto == NULL)
+		return NULL;
+
+	pto->fn = func;
+	Py_INCREF(func);
+	pto->args = PyTuple_GetSlice(args, 1, PY_SSIZE_T_MAX);
+	if (pto->args == NULL) {
+		pto->kw = NULL;
+		Py_DECREF(pto);
+		return NULL;
+	}
+	if (kw != NULL) {
+		pto->kw = PyDict_Copy(kw);
+		if (pto->kw == NULL) {
+			Py_DECREF(pto);
+			return NULL;
+		}
+	} else {
+		pto->kw = Py_None;
+		Py_INCREF(Py_None);
+	}
+
+	pto->weakreflist = NULL;
+	pto->dict = NULL;
+
+	return (PyObject *)pto;
+}
+
+static void
+partial_dealloc(partialobject *pto)
+{
+	PyObject_GC_UnTrack(pto);
+	if (pto->weakreflist != NULL)
+		PyObject_ClearWeakRefs((PyObject *) pto);
+	Py_XDECREF(pto->fn);
+	Py_XDECREF(pto->args);
+	Py_XDECREF(pto->kw);
+	Py_XDECREF(pto->dict);
+	pto->ob_type->tp_free(pto);
+}
+
+static PyObject *
+partial_call(partialobject *pto, PyObject *args, PyObject *kw)
+{
+	PyObject *ret;
+	PyObject *argappl = NULL, *kwappl = NULL;
+
+	assert (PyCallable_Check(pto->fn));
+	assert (PyTuple_Check(pto->args));
+	assert (pto->kw == Py_None  ||  PyDict_Check(pto->kw));
+
+	if (PyTuple_GET_SIZE(pto->args) == 0) {
+		argappl = args;
+		Py_INCREF(args);
+	} else if (PyTuple_GET_SIZE(args) == 0) {
+		argappl = pto->args;
+		Py_INCREF(pto->args);
+	} else {
+		argappl = PySequence_Concat(pto->args, args);
+		if (argappl == NULL)
+			return NULL;
+	}
+
+	if (pto->kw == Py_None) {
+		kwappl = kw;
+		Py_XINCREF(kw);
+	} else {
+		kwappl = PyDict_Copy(pto->kw);
+		if (kwappl == NULL) {
+			Py_DECREF(argappl);
+			return NULL;
+		}
+		if (kw != NULL) {
+			if (PyDict_Merge(kwappl, kw, 1) != 0) {
+				Py_DECREF(argappl);
+				Py_DECREF(kwappl);
+				return NULL;
+			}
+		}
+	}
+
+	ret = PyObject_Call(pto->fn, argappl, kwappl);
+	Py_DECREF(argappl);
+	Py_XDECREF(kwappl);
+	return ret;
+}
+
+static int
+partial_traverse(partialobject *pto, visitproc visit, void *arg)
+{
+	Py_VISIT(pto->fn);
+	Py_VISIT(pto->args);
+	Py_VISIT(pto->kw);
+	Py_VISIT(pto->dict);
+	return 0;
+}
+
+PyDoc_STRVAR(partial_doc,
+"partial(func, *args, **keywords) - new function with partial application\n\
+	of the given arguments and keywords.\n");
+
+#define OFF(x) offsetof(partialobject, x)
+static PyMemberDef partial_memberlist[] = {
+	{"func",	T_OBJECT,	OFF(fn),	READONLY,
+	 "function object to use in future partial calls"},
+	{"args",	T_OBJECT,	OFF(args),	READONLY,
+	 "tuple of arguments to future partial calls"},
+	{"keywords",	T_OBJECT,	OFF(kw),	READONLY,
+	 "dictionary of keyword arguments to future partial calls"},
+	{NULL}  /* Sentinel */
+};
+
+static PyObject *
+partial_get_dict(partialobject *pto)
+{
+	if (pto->dict == NULL) {
+		pto->dict = PyDict_New();
+		if (pto->dict == NULL)
+			return NULL;
+	}
+	Py_INCREF(pto->dict);
+	return pto->dict;
+}
+
+static int
+partial_set_dict(partialobject *pto, PyObject *value)
+{
+	PyObject *tmp;
+
+	/* It is illegal to del p.__dict__ */
+	if (value == NULL) {
+		PyErr_SetString(PyExc_TypeError,
+				"a partial object's dictionary may not be deleted");
+		return -1;
+	}
+	/* Can only set __dict__ to a dictionary */
+	if (!PyDict_Check(value)) {
+		PyErr_SetString(PyExc_TypeError,
+				"setting partial object's dictionary to a non-dict");
+		return -1;
+	}
+	tmp = pto->dict;
+	Py_INCREF(value);
+	pto->dict = value;
+	Py_XDECREF(tmp);
+	return 0;
+}
+
+static PyGetSetDef partial_getsetlist[] = {
+	{"__dict__", (getter)partial_get_dict, (setter)partial_set_dict},
+	{NULL} /* Sentinel */
+};
+
+static PyTypeObject partial_type = {
+	PyObject_HEAD_INIT(NULL)
+	0,				/* ob_size */
+	"functools.partial",		/* tp_name */
+	sizeof(partialobject),		/* tp_basicsize */
+	0,				/* tp_itemsize */
+	/* methods */
+	(destructor)partial_dealloc,	/* tp_dealloc */
+	0,				/* tp_print */
+	0,				/* tp_getattr */
+	0,				/* tp_setattr */
+	0,				/* tp_compare */
+	0,				/* tp_repr */
+	0,				/* tp_as_number */
+	0,				/* tp_as_sequence */
+	0,				/* tp_as_mapping */
+	0,				/* tp_hash */
+	(ternaryfunc)partial_call,	/* tp_call */
+	0,				/* tp_str */
+	PyObject_GenericGetAttr,	/* tp_getattro */
+	PyObject_GenericSetAttr,	/* tp_setattro */
+	0,				/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+		Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_WEAKREFS,	/* tp_flags */
+	partial_doc,			/* tp_doc */
+	(traverseproc)partial_traverse,	/* tp_traverse */
+	0,				/* tp_clear */
+	0,				/* tp_richcompare */
+	offsetof(partialobject, weakreflist),	/* tp_weaklistoffset */
+	0,				/* tp_iter */
+	0,				/* tp_iternext */
+	0,				/* tp_methods */
+	partial_memberlist,		/* tp_members */
+	partial_getsetlist,		/* tp_getset */
+	0,				/* tp_base */
+	0,				/* tp_dict */
+	0,				/* tp_descr_get */
+	0,				/* tp_descr_set */
+	offsetof(partialobject, dict),	/* tp_dictoffset */
+	0,				/* tp_init */
+	0,				/* tp_alloc */
+	partial_new,			/* tp_new */
+	PyObject_GC_Del,		/* tp_free */
+};
+
+
+/* module level code ********************************************************/
+
+PyDoc_STRVAR(module_doc,
+"Tools that operate on functions.");
+
+static PyMethodDef module_methods[] = {
+ 	{NULL,		NULL}		/* sentinel */
+};
+
+PyMODINIT_FUNC
+init_functools(void)
+{
+	int i;
+	PyObject *m;
+	char *name;
+	PyTypeObject *typelist[] = {
+		&partial_type,
+		NULL
+	};
+
+	m = Py_InitModule3("_functools", module_methods, module_doc);
+	if (m == NULL)
+		return;
+
+	for (i=0 ; typelist[i] != NULL ; i++) {
+		if (PyType_Ready(typelist[i]) < 0)
+			return;
+		name = strchr(typelist[i]->tp_name, '.');
+		assert (name != NULL);
+		Py_INCREF(typelist[i]);
+		PyModule_AddObject(m, name+1, (PyObject *)typelist[i]);
+	}
+}

Added: vendor/Python/current/Modules/_hashopenssl.c
===================================================================
--- vendor/Python/current/Modules/_hashopenssl.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_hashopenssl.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,487 @@
+/* Module that wraps all OpenSSL hash algorithms */
+
+/*
+ * Copyright (C) 2005   Gregory P. Smith (greg at electricrain.com)
+ * Licensed to PSF under a Contributor Agreement.
+ *
+ * Derived from a skeleton of shamodule.c containing work performed by:
+ *
+ * Andrew Kuchling (amk at amk.ca)
+ * Greg Stein (gstein at lyra.org)
+ *
+ */
+
+#define PY_SSIZE_T_CLEAN
+
+#include "Python.h"
+#include "structmember.h"
+
+/* EVP is the preferred interface to hashing in OpenSSL */
+#include <openssl/evp.h>
+
+
+#ifndef HASH_OBJ_CONSTRUCTOR
+#define HASH_OBJ_CONSTRUCTOR 0
+#endif
+
+typedef struct {
+    PyObject_HEAD
+    PyObject            *name;  /* name of this hash algorithm */
+    EVP_MD_CTX          ctx;    /* OpenSSL message digest context */
+} EVPobject;
+
+
+static PyTypeObject EVPtype;
+
+
+#define DEFINE_CONSTS_FOR_NEW(Name)  \
+    static PyObject *CONST_ ## Name ## _name_obj; \
+    static EVP_MD_CTX CONST_new_ ## Name ## _ctx; \
+    static EVP_MD_CTX *CONST_new_ ## Name ## _ctx_p = NULL;
+
+DEFINE_CONSTS_FOR_NEW(md5)
+DEFINE_CONSTS_FOR_NEW(sha1)
+DEFINE_CONSTS_FOR_NEW(sha224)
+DEFINE_CONSTS_FOR_NEW(sha256)
+DEFINE_CONSTS_FOR_NEW(sha384)
+DEFINE_CONSTS_FOR_NEW(sha512)
+
+
+static EVPobject *
+newEVPobject(PyObject *name)
+{
+    EVPobject *retval = (EVPobject *)PyObject_New(EVPobject, &EVPtype);
+
+    /* save the name for .name to return */
+    if (retval != NULL) {
+        Py_INCREF(name);
+        retval->name = name;
+    }
+
+    return retval;
+}
+
+/* Internal methods for a hash object */
+
+static void
+EVP_dealloc(PyObject *ptr)
+{
+    EVP_MD_CTX_cleanup(&((EVPobject *)ptr)->ctx);
+    Py_XDECREF(((EVPobject *)ptr)->name);
+    PyObject_Del(ptr);
+}
+
+
+/* External methods for a hash object */
+
+PyDoc_STRVAR(EVP_copy__doc__, "Return a copy of the hash object.");
+
+static PyObject *
+EVP_copy(EVPobject *self, PyObject *unused)
+{
+    EVPobject *newobj;
+
+    if ( (newobj = newEVPobject(self->name))==NULL)
+        return NULL;
+
+    EVP_MD_CTX_copy(&newobj->ctx, &self->ctx);
+    return (PyObject *)newobj;
+}
+
+PyDoc_STRVAR(EVP_digest__doc__,
+"Return the digest value as a string of binary data.");
+
+static PyObject *
+EVP_digest(EVPobject *self, PyObject *unused)
+{
+    unsigned char digest[EVP_MAX_MD_SIZE];
+    EVP_MD_CTX temp_ctx;
+    PyObject *retval;
+    unsigned int digest_size;
+
+    EVP_MD_CTX_copy(&temp_ctx, &self->ctx);
+    digest_size = EVP_MD_CTX_size(&temp_ctx);
+    EVP_DigestFinal(&temp_ctx, digest, NULL);
+
+    retval = PyString_FromStringAndSize((const char *)digest, digest_size);
+    EVP_MD_CTX_cleanup(&temp_ctx);
+    return retval;
+}
+
+PyDoc_STRVAR(EVP_hexdigest__doc__,
+"Return the digest value as a string of hexadecimal digits.");
+
+static PyObject *
+EVP_hexdigest(EVPobject *self, PyObject *unused)
+{
+    unsigned char digest[EVP_MAX_MD_SIZE];
+    EVP_MD_CTX temp_ctx;
+    PyObject *retval;
+    char *hex_digest;
+    unsigned int i, j, digest_size;
+
+    /* Get the raw (binary) digest value */
+    EVP_MD_CTX_copy(&temp_ctx, &self->ctx);
+    digest_size = EVP_MD_CTX_size(&temp_ctx);
+    EVP_DigestFinal(&temp_ctx, digest, NULL);
+
+    EVP_MD_CTX_cleanup(&temp_ctx);
+
+    /* Create a new string */
+    /* NOTE: not thread safe! modifying an already created string object */
+    /* (not a problem because we hold the GIL by default) */
+    retval = PyString_FromStringAndSize(NULL, digest_size * 2);
+    if (!retval)
+	    return NULL;
+    hex_digest = PyString_AsString(retval);
+    if (!hex_digest) {
+	    Py_DECREF(retval);
+	    return NULL;
+    }
+
+    /* Make hex version of the digest */
+    for(i=j=0; i<digest_size; i++) {
+        char c;
+        c = (digest[i] >> 4) & 0xf;
+	c = (c>9) ? c+'a'-10 : c + '0';
+        hex_digest[j++] = c;
+        c = (digest[i] & 0xf);
+	c = (c>9) ? c+'a'-10 : c + '0';
+        hex_digest[j++] = c;
+    }
+    return retval;
+}
+
+PyDoc_STRVAR(EVP_update__doc__,
+"Update this hash object's state with the provided string.");
+
+static PyObject *
+EVP_update(EVPobject *self, PyObject *args)
+{
+    unsigned char *cp;
+    Py_ssize_t len;
+
+    if (!PyArg_ParseTuple(args, "s#:update", &cp, &len))
+        return NULL;
+
+    EVP_DigestUpdate(&self->ctx, cp, Py_SAFE_DOWNCAST(len, Py_ssize_t,
+                                                      unsigned int));
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyMethodDef EVP_methods[] = {
+    {"update",	  (PyCFunction)EVP_update,    METH_VARARGS, EVP_update__doc__},
+    {"digest",	  (PyCFunction)EVP_digest,    METH_NOARGS,  EVP_digest__doc__},
+    {"hexdigest", (PyCFunction)EVP_hexdigest, METH_NOARGS,  EVP_hexdigest__doc__},
+    {"copy",	  (PyCFunction)EVP_copy,      METH_NOARGS,  EVP_copy__doc__},
+    {NULL,	  NULL}		/* sentinel */
+};
+
+static PyObject *
+EVP_get_block_size(EVPobject *self, void *closure)
+{
+    return PyInt_FromLong(EVP_MD_CTX_block_size(&((EVPobject *)self)->ctx));
+}
+
+static PyObject *
+EVP_get_digest_size(EVPobject *self, void *closure)
+{
+    return PyInt_FromLong(EVP_MD_CTX_size(&((EVPobject *)self)->ctx));
+}
+
+static PyMemberDef EVP_members[] = {
+    {"name", T_OBJECT, offsetof(EVPobject, name), READONLY, PyDoc_STR("algorithm name.")},
+    {NULL}  /* Sentinel */
+};
+
+static PyGetSetDef EVP_getseters[] = {
+    {"digest_size",
+     (getter)EVP_get_digest_size, NULL,
+     NULL,
+     NULL},
+    {"block_size",
+     (getter)EVP_get_block_size, NULL,
+     NULL,
+     NULL},
+    /* the old md5 and sha modules support 'digest_size' as in PEP 247.
+     * the old sha module also supported 'digestsize'.  ugh. */
+    {"digestsize",
+     (getter)EVP_get_digest_size, NULL,
+     NULL,
+     NULL},
+    {NULL}  /* Sentinel */
+};
+
+
+static PyObject *
+EVP_repr(PyObject *self)
+{
+    char buf[100];
+    PyOS_snprintf(buf, sizeof(buf), "<%s HASH object @ %p>",
+            PyString_AsString(((EVPobject *)self)->name), self);
+    return PyString_FromString(buf);
+}
+
+#if HASH_OBJ_CONSTRUCTOR
+static int
+EVP_tp_init(EVPobject *self, PyObject *args, PyObject *kwds)
+{
+    static char *kwlist[] = {"name", "string", NULL};
+    PyObject *name_obj = NULL;
+    char *nameStr;
+    unsigned char *cp = NULL;
+    Py_ssize_t len = 0;
+    const EVP_MD *digest;
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|s#:HASH", kwlist,
+                                     &name_obj, &cp, &len)) {
+        return -1;
+    }
+
+    if (!PyArg_Parse(name_obj, "s", &nameStr)) {
+        PyErr_SetString(PyExc_TypeError, "name must be a string");
+        return -1;
+    }
+
+    digest = EVP_get_digestbyname(nameStr);
+    if (!digest) {
+        PyErr_SetString(PyExc_ValueError, "unknown hash function");
+        return -1;
+    }
+    EVP_DigestInit(&self->ctx, digest);
+
+    self->name = name_obj;
+    Py_INCREF(self->name);
+
+    if (cp && len)
+        EVP_DigestUpdate(&self->ctx, cp, Py_SAFE_DOWNCAST(len, Py_ssize_t,
+                                                          unsigned int));
+
+    return 0;
+}
+#endif
+
+
+PyDoc_STRVAR(hashtype_doc,
+"A hash represents the object used to calculate a checksum of a\n\
+string of information.\n\
+\n\
+Methods:\n\
+\n\
+update() -- updates the current digest with an additional string\n\
+digest() -- return the current digest value\n\
+hexdigest() -- return the current digest as a string of hexadecimal digits\n\
+copy() -- return a copy of the current hash object\n\
+\n\
+Attributes:\n\
+\n\
+name -- the hash algorithm being used by this object\n\
+digest_size -- number of bytes in this hashes output\n");
+
+static PyTypeObject EVPtype = {
+    PyObject_HEAD_INIT(NULL)
+    0,			/*ob_size*/
+    "_hashlib.HASH",    /*tp_name*/
+    sizeof(EVPobject),	/*tp_basicsize*/
+    0,			/*tp_itemsize*/
+    /* methods */
+    EVP_dealloc,	/*tp_dealloc*/
+    0,			/*tp_print*/
+    0,                  /*tp_getattr*/
+    0,                  /*tp_setattr*/
+    0,                  /*tp_compare*/
+    EVP_repr,           /*tp_repr*/
+    0,                  /*tp_as_number*/
+    0,                  /*tp_as_sequence*/
+    0,                  /*tp_as_mapping*/
+    0,                  /*tp_hash*/
+    0,                  /*tp_call*/
+    0,                  /*tp_str*/
+    0,                  /*tp_getattro*/
+    0,                  /*tp_setattro*/
+    0,                  /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+    hashtype_doc,       /*tp_doc*/
+    0,                  /*tp_traverse*/
+    0,			/*tp_clear*/
+    0,			/*tp_richcompare*/
+    0,			/*tp_weaklistoffset*/
+    0,			/*tp_iter*/
+    0,			/*tp_iternext*/
+    EVP_methods,	/* tp_methods */
+    EVP_members,	/* tp_members */
+    EVP_getseters,      /* tp_getset */
+#if 1
+    0,                  /* tp_base */
+    0,                  /* tp_dict */
+    0,                  /* tp_descr_get */
+    0,                  /* tp_descr_set */
+    0,                  /* tp_dictoffset */
+#endif
+#if HASH_OBJ_CONSTRUCTOR
+    (initproc)EVP_tp_init, /* tp_init */
+#endif
+};
+
+static PyObject *
+EVPnew(PyObject *name_obj,
+       const EVP_MD *digest, const EVP_MD_CTX *initial_ctx,
+       const unsigned char *cp, unsigned int len)
+{
+    EVPobject *self;
+
+    if (!digest && !initial_ctx) {
+        PyErr_SetString(PyExc_ValueError, "unsupported hash type");
+        return NULL;
+    }
+
+    if ((self = newEVPobject(name_obj)) == NULL)
+        return NULL;
+
+    if (initial_ctx) {
+        EVP_MD_CTX_copy(&self->ctx, initial_ctx);
+    } else {
+        EVP_DigestInit(&self->ctx, digest);
+    }
+
+    if (cp && len)
+        EVP_DigestUpdate(&self->ctx, cp, len);
+
+    return (PyObject *)self;
+}
+
+
+/* The module-level function: new() */
+
+PyDoc_STRVAR(EVP_new__doc__,
+"Return a new hash object using the named algorithm.\n\
+An optional string argument may be provided and will be\n\
+automatically hashed.\n\
+\n\
+The MD5 and SHA1 algorithms are always supported.\n");
+
+static PyObject *
+EVP_new(PyObject *self, PyObject *args, PyObject *kwdict)
+{
+    static char *kwlist[] = {"name", "string", NULL};
+    PyObject *name_obj = NULL;
+    char *name;
+    const EVP_MD *digest;
+    unsigned char *cp = NULL;
+    Py_ssize_t len = 0;
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwdict, "O|s#:new", kwlist,
+                                     &name_obj, &cp, &len)) {
+        return NULL;
+    }
+
+    if (!PyArg_Parse(name_obj, "s", &name)) {
+        PyErr_SetString(PyExc_TypeError, "name must be a string");
+        return NULL;
+    }
+
+    digest = EVP_get_digestbyname(name);
+
+    return EVPnew(name_obj, digest, NULL, cp, Py_SAFE_DOWNCAST(len, Py_ssize_t,
+                                                               unsigned int));
+}
+
+/*
+ *  This macro generates constructor function definitions for specific
+ *  hash algorithms.  These constructors are much faster than calling
+ *  the generic one passing it a python string and are noticably
+ *  faster than calling a python new() wrapper.  Thats important for
+ *  code that wants to make hashes of a bunch of small strings.
+ */
+#define GEN_CONSTRUCTOR(NAME)  \
+    static PyObject * \
+    EVP_new_ ## NAME (PyObject *self, PyObject *args) \
+    { \
+        unsigned char *cp = NULL; \
+        Py_ssize_t len = 0; \
+     \
+        if (!PyArg_ParseTuple(args, "|s#:" #NAME , &cp, &len)) { \
+            return NULL; \
+        } \
+     \
+        return EVPnew( \
+                CONST_ ## NAME ## _name_obj, \
+                NULL, \
+                CONST_new_ ## NAME ## _ctx_p, \
+                cp, Py_SAFE_DOWNCAST(len, Py_ssize_t, unsigned int)); \
+    }
+
+/* a PyMethodDef structure for the constructor */
+#define CONSTRUCTOR_METH_DEF(NAME)  \
+    {"openssl_" #NAME, (PyCFunction)EVP_new_ ## NAME, METH_VARARGS, \
+        PyDoc_STR("Returns a " #NAME \
+                  " hash object; optionally initialized with a string") \
+    }
+
+/* used in the init function to setup a constructor */
+#define INIT_CONSTRUCTOR_CONSTANTS(NAME)  do { \
+    CONST_ ## NAME ## _name_obj = PyString_FromString(#NAME); \
+    if (EVP_get_digestbyname(#NAME)) { \
+        CONST_new_ ## NAME ## _ctx_p = &CONST_new_ ## NAME ## _ctx; \
+        EVP_DigestInit(CONST_new_ ## NAME ## _ctx_p, EVP_get_digestbyname(#NAME)); \
+    } \
+} while (0);
+
+GEN_CONSTRUCTOR(md5)
+GEN_CONSTRUCTOR(sha1)
+GEN_CONSTRUCTOR(sha224)
+GEN_CONSTRUCTOR(sha256)
+GEN_CONSTRUCTOR(sha384)
+GEN_CONSTRUCTOR(sha512)
+
+/* List of functions exported by this module */
+
+static struct PyMethodDef EVP_functions[] = {
+    {"new", (PyCFunction)EVP_new, METH_VARARGS|METH_KEYWORDS, EVP_new__doc__},
+    CONSTRUCTOR_METH_DEF(md5),
+    CONSTRUCTOR_METH_DEF(sha1),
+    CONSTRUCTOR_METH_DEF(sha224),
+    CONSTRUCTOR_METH_DEF(sha256),
+    CONSTRUCTOR_METH_DEF(sha384),
+    CONSTRUCTOR_METH_DEF(sha512),
+    {NULL,	NULL}		 /* Sentinel */
+};
+
+
+/* Initialize this module. */
+
+PyMODINIT_FUNC
+init_hashlib(void)
+{
+    PyObject *m;
+
+    OpenSSL_add_all_digests();
+
+    /* TODO build EVP_functions openssl_* entries dynamically based
+     * on what hashes are supported rather than listing many
+     * but having some be unsupported.  Only init appropriate
+     * constants. */
+
+    EVPtype.ob_type = &PyType_Type;
+    if (PyType_Ready(&EVPtype) < 0)
+        return;
+
+    m = Py_InitModule("_hashlib", EVP_functions);
+    if (m == NULL)
+        return;
+
+#if HASH_OBJ_CONSTRUCTOR
+    Py_INCREF(&EVPtype);
+    PyModule_AddObject(m, "HASH", (PyObject *)&EVPtype);
+#endif
+
+    /* these constants are used by the convenience constructors */
+    INIT_CONSTRUCTOR_CONSTANTS(md5);
+    INIT_CONSTRUCTOR_CONSTANTS(sha1);
+    INIT_CONSTRUCTOR_CONSTANTS(sha224);
+    INIT_CONSTRUCTOR_CONSTANTS(sha256);
+    INIT_CONSTRUCTOR_CONSTANTS(sha384);
+    INIT_CONSTRUCTOR_CONSTANTS(sha512);
+}

Added: vendor/Python/current/Modules/_heapqmodule.c
===================================================================
--- vendor/Python/current/Modules/_heapqmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_heapqmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,619 @@
+/* Drop in replacement for heapq.py 
+
+C implementation derived directly from heapq.py in Py2.3
+which was written by Kevin O'Connor, augmented by Tim Peters,
+annotated by François Pinard, and converted to C by Raymond Hettinger.
+
+*/
+
+#include "Python.h"
+
+static int
+_siftdown(PyListObject *heap, Py_ssize_t startpos, Py_ssize_t pos)
+{
+	PyObject *newitem, *parent;
+	int cmp;
+	Py_ssize_t parentpos;
+
+	assert(PyList_Check(heap));
+	if (pos >= PyList_GET_SIZE(heap)) {
+		PyErr_SetString(PyExc_IndexError, "index out of range");
+		return -1;
+	}
+
+	newitem = PyList_GET_ITEM(heap, pos);
+	Py_INCREF(newitem);
+	/* Follow the path to the root, moving parents down until finding
+	   a place newitem fits. */
+	while (pos > startpos){
+		parentpos = (pos - 1) >> 1;
+		parent = PyList_GET_ITEM(heap, parentpos);
+		cmp = PyObject_RichCompareBool(parent, newitem, Py_LE);
+		if (cmp == -1) {
+			Py_DECREF(newitem);
+			return -1;
+		}
+		if (cmp == 1)
+			break;
+		Py_INCREF(parent);
+		Py_DECREF(PyList_GET_ITEM(heap, pos));
+		PyList_SET_ITEM(heap, pos, parent);
+		pos = parentpos;
+	}
+	Py_DECREF(PyList_GET_ITEM(heap, pos));
+	PyList_SET_ITEM(heap, pos, newitem);
+	return 0;
+}
+
+static int
+_siftup(PyListObject *heap, Py_ssize_t pos)
+{
+	Py_ssize_t startpos, endpos, childpos, rightpos;
+	int cmp;
+	PyObject *newitem, *tmp;
+
+	assert(PyList_Check(heap));
+	endpos = PyList_GET_SIZE(heap);
+	startpos = pos;
+	if (pos >= endpos) {
+		PyErr_SetString(PyExc_IndexError, "index out of range");
+		return -1;
+	}
+	newitem = PyList_GET_ITEM(heap, pos);
+	Py_INCREF(newitem);
+
+	/* Bubble up the smaller child until hitting a leaf. */
+	childpos = 2*pos + 1;    /* leftmost child position  */
+	while (childpos < endpos) {
+		/* Set childpos to index of smaller child.   */
+		rightpos = childpos + 1;
+		if (rightpos < endpos) {
+			cmp = PyObject_RichCompareBool(
+				PyList_GET_ITEM(heap, rightpos),
+				PyList_GET_ITEM(heap, childpos),
+				Py_LE);
+			if (cmp == -1) {
+				Py_DECREF(newitem);
+				return -1;
+			}
+			if (cmp == 1)
+				childpos = rightpos;
+		}
+		/* Move the smaller child up. */
+		tmp = PyList_GET_ITEM(heap, childpos);
+		Py_INCREF(tmp);
+		Py_DECREF(PyList_GET_ITEM(heap, pos));
+		PyList_SET_ITEM(heap, pos, tmp);
+		pos = childpos;
+		childpos = 2*pos + 1;
+	}
+
+	/* The leaf at pos is empty now.  Put newitem there, and and bubble
+	   it up to its final resting place (by sifting its parents down). */
+	Py_DECREF(PyList_GET_ITEM(heap, pos));
+	PyList_SET_ITEM(heap, pos, newitem);
+	return _siftdown(heap, startpos, pos);
+}
+
+static PyObject *
+heappush(PyObject *self, PyObject *args)
+{
+	PyObject *heap, *item;
+
+	if (!PyArg_UnpackTuple(args, "heappush", 2, 2, &heap, &item))
+		return NULL;
+
+	if (!PyList_Check(heap)) {
+		PyErr_SetString(PyExc_TypeError, "heap argument must be a list");
+		return NULL;
+	}
+
+	if (PyList_Append(heap, item) == -1)
+		return NULL;
+
+	if (_siftdown((PyListObject *)heap, 0, PyList_GET_SIZE(heap)-1) == -1)
+		return NULL;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(heappush_doc,
+"Push item onto heap, maintaining the heap invariant.");
+
+static PyObject *
+heappop(PyObject *self, PyObject *heap)
+{
+	PyObject *lastelt, *returnitem;
+	Py_ssize_t n;
+
+	if (!PyList_Check(heap)) {
+		PyErr_SetString(PyExc_TypeError, "heap argument must be a list");
+		return NULL;
+	}
+
+	/* # raises appropriate IndexError if heap is empty */
+	n = PyList_GET_SIZE(heap);
+	if (n == 0) {
+		PyErr_SetString(PyExc_IndexError, "index out of range");
+		return NULL;
+	}
+
+	lastelt = PyList_GET_ITEM(heap, n-1) ;
+	Py_INCREF(lastelt);
+	PyList_SetSlice(heap, n-1, n, NULL);
+	n--;
+
+	if (!n) 
+		return lastelt;
+	returnitem = PyList_GET_ITEM(heap, 0);
+	PyList_SET_ITEM(heap, 0, lastelt);
+	if (_siftup((PyListObject *)heap, 0) == -1) {
+		Py_DECREF(returnitem);
+		return NULL;
+	}
+	return returnitem;
+}
+
+PyDoc_STRVAR(heappop_doc,
+"Pop the smallest item off the heap, maintaining the heap invariant.");
+
+static PyObject *
+heapreplace(PyObject *self, PyObject *args)
+{
+	PyObject *heap, *item, *returnitem;
+
+	if (!PyArg_UnpackTuple(args, "heapreplace", 2, 2, &heap, &item))
+		return NULL;
+
+	if (!PyList_Check(heap)) {
+		PyErr_SetString(PyExc_TypeError, "heap argument must be a list");
+		return NULL;
+	}
+
+	if (PyList_GET_SIZE(heap) < 1) {
+		PyErr_SetString(PyExc_IndexError, "index out of range");
+		return NULL;
+	}
+
+	returnitem = PyList_GET_ITEM(heap, 0);
+	Py_INCREF(item);
+	PyList_SET_ITEM(heap, 0, item);
+	if (_siftup((PyListObject *)heap, 0) == -1) {
+		Py_DECREF(returnitem);
+		return NULL;
+	}
+	return returnitem;
+}
+
+PyDoc_STRVAR(heapreplace_doc,
+"Pop and return the current smallest value, and add the new item.\n\
+\n\
+This is more efficient than heappop() followed by heappush(), and can be\n\
+more appropriate when using a fixed-size heap.  Note that the value\n\
+returned may be larger than item!  That constrains reasonable uses of\n\
+this routine unless written as part of a conditional replacement:\n\n\
+        if item > heap[0]:\n\
+            item = heapreplace(heap, item)\n");
+
+static PyObject *
+heapify(PyObject *self, PyObject *heap)
+{
+	Py_ssize_t i, n;
+
+	if (!PyList_Check(heap)) {
+		PyErr_SetString(PyExc_TypeError, "heap argument must be a list");
+		return NULL;
+	}
+
+	n = PyList_GET_SIZE(heap);
+	/* Transform bottom-up.  The largest index there's any point to
+	   looking at is the largest with a child index in-range, so must
+	   have 2*i + 1 < n, or i < (n-1)/2.  If n is even = 2*j, this is
+	   (2*j-1)/2 = j-1/2 so j-1 is the largest, which is n//2 - 1.  If
+	   n is odd = 2*j+1, this is (2*j+1-1)/2 = j so j-1 is the largest,
+	   and that's again n//2-1.
+	*/
+	for (i=n/2-1 ; i>=0 ; i--)
+		if(_siftup((PyListObject *)heap, i) == -1)
+			return NULL;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(heapify_doc,
+"Transform list into a heap, in-place, in O(len(heap)) time.");
+
+static PyObject *
+nlargest(PyObject *self, PyObject *args)
+{
+	PyObject *heap=NULL, *elem, *iterable, *sol, *it, *oldelem;
+	Py_ssize_t i, n;
+
+	if (!PyArg_ParseTuple(args, "nO:nlargest", &n, &iterable))
+		return NULL;
+
+	it = PyObject_GetIter(iterable);
+	if (it == NULL)
+		return NULL;
+
+	heap = PyList_New(0);
+	if (heap == NULL)
+		goto fail;
+
+	for (i=0 ; i<n ; i++ ){
+		elem = PyIter_Next(it);
+		if (elem == NULL) {
+			if (PyErr_Occurred())
+				goto fail;
+			else
+				goto sortit;
+		}
+		if (PyList_Append(heap, elem) == -1) {
+			Py_DECREF(elem);
+			goto fail;
+		}
+		Py_DECREF(elem);
+	}
+	if (PyList_GET_SIZE(heap) == 0)
+		goto sortit;
+
+	for (i=n/2-1 ; i>=0 ; i--)
+		if(_siftup((PyListObject *)heap, i) == -1)
+			goto fail;
+
+	sol = PyList_GET_ITEM(heap, 0);
+	while (1) {
+		elem = PyIter_Next(it);
+		if (elem == NULL) {
+			if (PyErr_Occurred())
+				goto fail;
+			else
+				goto sortit;
+		}
+		if (PyObject_RichCompareBool(elem, sol, Py_LE)) {
+			Py_DECREF(elem);
+			continue;
+		}
+		oldelem = PyList_GET_ITEM(heap, 0);
+		PyList_SET_ITEM(heap, 0, elem);
+		Py_DECREF(oldelem);
+		if (_siftup((PyListObject *)heap, 0) == -1)
+			goto fail;
+		sol = PyList_GET_ITEM(heap, 0);
+	}
+sortit:
+	if (PyList_Sort(heap) == -1)
+		goto fail;
+	if (PyList_Reverse(heap) == -1)
+		goto fail;
+	Py_DECREF(it);
+	return heap;
+
+fail:
+	Py_DECREF(it);
+	Py_XDECREF(heap);
+	return NULL;
+}
+
+PyDoc_STRVAR(nlargest_doc,
+"Find the n largest elements in a dataset.\n\
+\n\
+Equivalent to:  sorted(iterable, reverse=True)[:n]\n");
+
+static int
+_siftdownmax(PyListObject *heap, Py_ssize_t startpos, Py_ssize_t pos)
+{
+	PyObject *newitem, *parent;
+	int cmp;
+	Py_ssize_t parentpos;
+
+	assert(PyList_Check(heap));
+	if (pos >= PyList_GET_SIZE(heap)) {
+		PyErr_SetString(PyExc_IndexError, "index out of range");
+		return -1;
+	}
+
+	newitem = PyList_GET_ITEM(heap, pos);
+	Py_INCREF(newitem);
+	/* Follow the path to the root, moving parents down until finding
+	   a place newitem fits. */
+	while (pos > startpos){
+		parentpos = (pos - 1) >> 1;
+		parent = PyList_GET_ITEM(heap, parentpos);
+		cmp = PyObject_RichCompareBool(newitem, parent, Py_LE);
+		if (cmp == -1) {
+			Py_DECREF(newitem);
+			return -1;
+		}
+		if (cmp == 1)
+			break;
+		Py_INCREF(parent);
+		Py_DECREF(PyList_GET_ITEM(heap, pos));
+		PyList_SET_ITEM(heap, pos, parent);
+		pos = parentpos;
+	}
+	Py_DECREF(PyList_GET_ITEM(heap, pos));
+	PyList_SET_ITEM(heap, pos, newitem);
+	return 0;
+}
+
+static int
+_siftupmax(PyListObject *heap, Py_ssize_t pos)
+{
+	Py_ssize_t startpos, endpos, childpos, rightpos;
+	int cmp;
+	PyObject *newitem, *tmp;
+
+	assert(PyList_Check(heap));
+	endpos = PyList_GET_SIZE(heap);
+	startpos = pos;
+	if (pos >= endpos) {
+		PyErr_SetString(PyExc_IndexError, "index out of range");
+		return -1;
+	}
+	newitem = PyList_GET_ITEM(heap, pos);
+	Py_INCREF(newitem);
+
+	/* Bubble up the smaller child until hitting a leaf. */
+	childpos = 2*pos + 1;    /* leftmost child position  */
+	while (childpos < endpos) {
+		/* Set childpos to index of smaller child.   */
+		rightpos = childpos + 1;
+		if (rightpos < endpos) {
+			cmp = PyObject_RichCompareBool(
+				PyList_GET_ITEM(heap, childpos),
+				PyList_GET_ITEM(heap, rightpos),
+				Py_LE);
+			if (cmp == -1) {
+				Py_DECREF(newitem);
+				return -1;
+			}
+			if (cmp == 1)
+				childpos = rightpos;
+		}
+		/* Move the smaller child up. */
+		tmp = PyList_GET_ITEM(heap, childpos);
+		Py_INCREF(tmp);
+		Py_DECREF(PyList_GET_ITEM(heap, pos));
+		PyList_SET_ITEM(heap, pos, tmp);
+		pos = childpos;
+		childpos = 2*pos + 1;
+	}
+
+	/* The leaf at pos is empty now.  Put newitem there, and and bubble
+	   it up to its final resting place (by sifting its parents down). */
+	Py_DECREF(PyList_GET_ITEM(heap, pos));
+	PyList_SET_ITEM(heap, pos, newitem);
+	return _siftdownmax(heap, startpos, pos);
+}
+
+static PyObject *
+nsmallest(PyObject *self, PyObject *args)
+{
+	PyObject *heap=NULL, *elem, *iterable, *los, *it, *oldelem;
+	Py_ssize_t i, n;
+
+	if (!PyArg_ParseTuple(args, "nO:nsmallest", &n, &iterable))
+		return NULL;
+
+	it = PyObject_GetIter(iterable);
+	if (it == NULL)
+		return NULL;
+
+	heap = PyList_New(0);
+	if (heap == NULL)
+		goto fail;
+
+	for (i=0 ; i<n ; i++ ){
+		elem = PyIter_Next(it);
+		if (elem == NULL) {
+			if (PyErr_Occurred())
+				goto fail;
+			else
+				goto sortit;
+		}
+		if (PyList_Append(heap, elem) == -1) {
+			Py_DECREF(elem);
+			goto fail;
+		}
+		Py_DECREF(elem);
+	}
+	n = PyList_GET_SIZE(heap);
+	if (n == 0)
+		goto sortit;
+
+	for (i=n/2-1 ; i>=0 ; i--)
+		if(_siftupmax((PyListObject *)heap, i) == -1)
+			goto fail;
+
+	los = PyList_GET_ITEM(heap, 0);
+	while (1) {
+		elem = PyIter_Next(it);
+		if (elem == NULL) {
+			if (PyErr_Occurred())
+				goto fail;
+			else
+				goto sortit;
+		}
+		if (PyObject_RichCompareBool(los, elem, Py_LE)) {
+			Py_DECREF(elem);
+			continue;
+		}
+
+		oldelem = PyList_GET_ITEM(heap, 0);
+		PyList_SET_ITEM(heap, 0, elem);
+		Py_DECREF(oldelem);
+		if (_siftupmax((PyListObject *)heap, 0) == -1)
+			goto fail;
+		los = PyList_GET_ITEM(heap, 0);
+	}
+
+sortit:
+	if (PyList_Sort(heap) == -1)
+		goto fail;
+	Py_DECREF(it);
+	return heap;
+
+fail:
+	Py_DECREF(it);
+	Py_XDECREF(heap);
+	return NULL;
+}
+
+PyDoc_STRVAR(nsmallest_doc,
+"Find the n smallest elements in a dataset.\n\
+\n\
+Equivalent to:  sorted(iterable)[:n]\n");
+
+static PyMethodDef heapq_methods[] = {
+	{"heappush",	(PyCFunction)heappush,		
+		METH_VARARGS,	heappush_doc},
+	{"heappop",	(PyCFunction)heappop,
+		METH_O,		heappop_doc},
+	{"heapreplace",	(PyCFunction)heapreplace,
+		METH_VARARGS,	heapreplace_doc},
+	{"heapify",	(PyCFunction)heapify,
+		METH_O,		heapify_doc},
+	{"nlargest",	(PyCFunction)nlargest,
+		METH_VARARGS,	nlargest_doc},
+	{"nsmallest",	(PyCFunction)nsmallest,
+		METH_VARARGS,	nsmallest_doc},
+	{NULL,		NULL}		/* sentinel */
+};
+
+PyDoc_STRVAR(module_doc,
+"Heap queue algorithm (a.k.a. priority queue).\n\
+\n\
+Heaps are arrays for which a[k] <= a[2*k+1] and a[k] <= a[2*k+2] for\n\
+all k, counting elements from 0.  For the sake of comparison,\n\
+non-existing elements are considered to be infinite.  The interesting\n\
+property of a heap is that a[0] is always its smallest element.\n\
+\n\
+Usage:\n\
+\n\
+heap = []            # creates an empty heap\n\
+heappush(heap, item) # pushes a new item on the heap\n\
+item = heappop(heap) # pops the smallest item from the heap\n\
+item = heap[0]       # smallest item on the heap without popping it\n\
+heapify(x)           # transforms list into a heap, in-place, in linear time\n\
+item = heapreplace(heap, item) # pops and returns smallest item, and adds\n\
+                               # new item; the heap size is unchanged\n\
+\n\
+Our API differs from textbook heap algorithms as follows:\n\
+\n\
+- We use 0-based indexing.  This makes the relationship between the\n\
+  index for a node and the indexes for its children slightly less\n\
+  obvious, but is more suitable since Python uses 0-based indexing.\n\
+\n\
+- Our heappop() method returns the smallest item, not the largest.\n\
+\n\
+These two make it possible to view the heap as a regular Python list\n\
+without surprises: heap[0] is the smallest item, and heap.sort()\n\
+maintains the heap invariant!\n");
+
+
+PyDoc_STRVAR(__about__,
+"Heap queues\n\
+\n\
+[explanation by François Pinard]\n\
+\n\
+Heaps are arrays for which a[k] <= a[2*k+1] and a[k] <= a[2*k+2] for\n\
+all k, counting elements from 0.  For the sake of comparison,\n\
+non-existing elements are considered to be infinite.  The interesting\n\
+property of a heap is that a[0] is always its smallest element.\n"
+"\n\
+The strange invariant above is meant to be an efficient memory\n\
+representation for a tournament.  The numbers below are `k', not a[k]:\n\
+\n\
+                                   0\n\
+\n\
+                  1                                 2\n\
+\n\
+          3               4                5               6\n\
+\n\
+      7       8       9       10      11      12      13      14\n\
+\n\
+    15 16   17 18   19 20   21 22   23 24   25 26   27 28   29 30\n\
+\n\
+\n\
+In the tree above, each cell `k' is topping `2*k+1' and `2*k+2'.  In\n\
+an usual binary tournament we see in sports, each cell is the winner\n\
+over the two cells it tops, and we can trace the winner down the tree\n\
+to see all opponents s/he had.  However, in many computer applications\n\
+of such tournaments, we do not need to trace the history of a winner.\n\
+To be more memory efficient, when a winner is promoted, we try to\n\
+replace it by something else at a lower level, and the rule becomes\n\
+that a cell and the two cells it tops contain three different items,\n\
+but the top cell \"wins\" over the two topped cells.\n"
+"\n\
+If this heap invariant is protected at all time, index 0 is clearly\n\
+the overall winner.  The simplest algorithmic way to remove it and\n\
+find the \"next\" winner is to move some loser (let's say cell 30 in the\n\
+diagram above) into the 0 position, and then percolate this new 0 down\n\
+the tree, exchanging values, until the invariant is re-established.\n\
+This is clearly logarithmic on the total number of items in the tree.\n\
+By iterating over all items, you get an O(n ln n) sort.\n"
+"\n\
+A nice feature of this sort is that you can efficiently insert new\n\
+items while the sort is going on, provided that the inserted items are\n\
+not \"better\" than the last 0'th element you extracted.  This is\n\
+especially useful in simulation contexts, where the tree holds all\n\
+incoming events, and the \"win\" condition means the smallest scheduled\n\
+time.  When an event schedule other events for execution, they are\n\
+scheduled into the future, so they can easily go into the heap.  So, a\n\
+heap is a good structure for implementing schedulers (this is what I\n\
+used for my MIDI sequencer :-).\n"
+"\n\
+Various structures for implementing schedulers have been extensively\n\
+studied, and heaps are good for this, as they are reasonably speedy,\n\
+the speed is almost constant, and the worst case is not much different\n\
+than the average case.  However, there are other representations which\n\
+are more efficient overall, yet the worst cases might be terrible.\n"
+"\n\
+Heaps are also very useful in big disk sorts.  You most probably all\n\
+know that a big sort implies producing \"runs\" (which are pre-sorted\n\
+sequences, which size is usually related to the amount of CPU memory),\n\
+followed by a merging passes for these runs, which merging is often\n\
+very cleverly organised[1].  It is very important that the initial\n\
+sort produces the longest runs possible.  Tournaments are a good way\n\
+to that.  If, using all the memory available to hold a tournament, you\n\
+replace and percolate items that happen to fit the current run, you'll\n\
+produce runs which are twice the size of the memory for random input,\n\
+and much better for input fuzzily ordered.\n"
+"\n\
+Moreover, if you output the 0'th item on disk and get an input which\n\
+may not fit in the current tournament (because the value \"wins\" over\n\
+the last output value), it cannot fit in the heap, so the size of the\n\
+heap decreases.  The freed memory could be cleverly reused immediately\n\
+for progressively building a second heap, which grows at exactly the\n\
+same rate the first heap is melting.  When the first heap completely\n\
+vanishes, you switch heaps and start a new run.  Clever and quite\n\
+effective!\n\
+\n\
+In a word, heaps are useful memory structures to know.  I use them in\n\
+a few applications, and I think it is good to keep a `heap' module\n\
+around. :-)\n"
+"\n\
+--------------------\n\
+[1] The disk balancing algorithms which are current, nowadays, are\n\
+more annoying than clever, and this is a consequence of the seeking\n\
+capabilities of the disks.  On devices which cannot seek, like big\n\
+tape drives, the story was quite different, and one had to be very\n\
+clever to ensure (far in advance) that each tape movement will be the\n\
+most effective possible (that is, will best participate at\n\
+\"progressing\" the merge).  Some tapes were even able to read\n\
+backwards, and this was also used to avoid the rewinding time.\n\
+Believe me, real good tape sorts were quite spectacular to watch!\n\
+From all times, sorting has always been a Great Art! :-)\n");
+
+PyMODINIT_FUNC
+init_heapq(void)
+{
+	PyObject *m;
+
+	m = Py_InitModule3("_heapq", heapq_methods, module_doc);
+	if (m == NULL)
+    		return;
+	PyModule_AddObject(m, "__about__", PyString_FromString(__about__));
+}
+

Added: vendor/Python/current/Modules/_hotshot.c
===================================================================
--- vendor/Python/current/Modules/_hotshot.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_hotshot.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1647 @@
+/*
+ * This is the High Performance Python Profiler portion of HotShot.
+ */
+
+#include "Python.h"
+#include "code.h"
+#include "eval.h"
+#include "frameobject.h"
+#include "structmember.h"
+
+/*
+ * Which timer to use should be made more configurable, but that should not
+ * be difficult.  This will do for now.
+ */
+#ifdef MS_WINDOWS
+#include <windows.h>
+
+#ifdef HAVE_DIRECT_H
+#include <direct.h>    /* for getcwd() */
+#endif
+
+typedef __int64 hs_time;
+#define GETTIMEOFDAY(P_HS_TIME) \
+	{ LARGE_INTEGER _temp; \
+	  QueryPerformanceCounter(&_temp); \
+	  *(P_HS_TIME) = _temp.QuadPart; }
+	  
+
+#else
+#ifndef HAVE_GETTIMEOFDAY
+#error "This module requires gettimeofday() on non-Windows platforms!"
+#endif
+#if (defined(PYOS_OS2) && defined(PYCC_GCC)) || defined(__QNX__)
+#include <sys/time.h>
+#else
+#include <sys/resource.h>
+#include <sys/times.h>
+#endif
+typedef struct timeval hs_time;
+#endif
+
+#if !defined(__cplusplus) && !defined(inline)
+#ifdef __GNUC__
+#define inline __inline
+#endif
+#endif
+
+#ifndef inline
+#define inline
+#endif
+
+#define BUFFERSIZE 10240
+
+#if defined(PYOS_OS2) && defined(PYCC_GCC)
+#define PATH_MAX 260
+#endif
+
+#if defined(__sgi) && _COMPILER_VERSION>700 && !defined(PATH_MAX)
+/* fix PATH_MAX not being defined with MIPSPro 7.x
+   if mode is ANSI C (default) */
+#define PATH_MAX 1024
+#endif
+
+#ifndef PATH_MAX
+#   ifdef MAX_PATH
+#       define PATH_MAX MAX_PATH
+#   elif defined (_POSIX_PATH_MAX)
+#       define PATH_MAX _POSIX_PATH_MAX
+#   else
+#       error "Need a defn. for PATH_MAX in _hotshot.c"
+#   endif
+#endif
+
+typedef struct {
+    PyObject_HEAD
+    PyObject *filemap;
+    PyObject *logfilename;
+    Py_ssize_t index;
+    unsigned char buffer[BUFFERSIZE];
+    FILE *logfp;
+    int lineevents;
+    int linetimings;
+    int frametimings;
+    /* size_t filled; */
+    int active;
+    int next_fileno;
+    hs_time prev_timeofday;
+} ProfilerObject;
+
+typedef struct {
+    PyObject_HEAD
+    PyObject *info;
+    FILE *logfp;
+    int linetimings;
+    int frametimings;
+} LogReaderObject;
+
+static PyObject * ProfilerError = NULL;
+
+
+#ifndef MS_WINDOWS
+#ifdef GETTIMEOFDAY_NO_TZ
+#define GETTIMEOFDAY(ptv) gettimeofday((ptv))
+#else
+#define GETTIMEOFDAY(ptv) gettimeofday((ptv), (struct timezone *)NULL)
+#endif
+#endif
+
+
+/* The log reader... */
+
+PyDoc_STRVAR(logreader_close__doc__,
+"close()\n"
+"Close the log file, preventing additional records from being read.");
+
+static PyObject *
+logreader_close(LogReaderObject *self, PyObject *args)
+{
+    if (self->logfp != NULL) {
+        fclose(self->logfp);
+        self->logfp = NULL;
+    }
+    Py_INCREF(Py_None);
+
+    return Py_None;
+}
+
+PyDoc_STRVAR(logreader_fileno__doc__,
+"fileno() -> file descriptor\n"
+"Returns the file descriptor for the log file, if open.\n"
+"Raises ValueError if the log file is closed.");
+
+static PyObject *
+logreader_fileno(LogReaderObject *self)
+{
+    if (self->logfp == NULL) {
+        PyErr_SetString(PyExc_ValueError,
+                        "logreader's file object already closed");
+        return NULL;
+    }
+    return PyInt_FromLong(fileno(self->logfp));
+}
+
+
+/* Log File Format
+ * ---------------
+ *
+ * The log file consists of a sequence of variable-length records.
+ * Each record is identified with a record type identifier in two
+ * bits of the first byte.  The two bits are the "least significant"
+ * bits of the byte.
+ *
+ * Low bits:    Opcode:        Meaning:
+ *       0x00         ENTER     enter a frame
+ *       0x01          EXIT     exit a frame
+ *       0x02        LINENO     execution moved onto a different line
+ *       0x03         OTHER     more bits are needed to deecode
+ *
+ * If the type is OTHER, the record is not packed so tightly, and the
+ * remaining bits are used to disambiguate the record type.  These
+ * records are not used as frequently so compaction is not an issue.
+ * Each of the first three record types has a highly tailored
+ * structure that allows it to be packed tightly.
+ *
+ * The OTHER records have the following identifiers:
+ *
+ * First byte:  Opcode:        Meaning:
+ *       0x13      ADD_INFO     define a key/value pair
+ *       0x23   DEFINE_FILE     define an int->filename mapping
+ *       0x33    LINE_TIMES     indicates if LINENO events have tdeltas
+ *       0x43   DEFINE_FUNC     define a (fileno,lineno)->funcname mapping
+ *       0x53   FRAME_TIMES     indicates if ENTER/EXIT events have tdeltas
+ *
+ * Packed Integers
+ *
+ * "Packed integers" are non-negative integer values encoded as a
+ * sequence of bytes.  Each byte is encoded such that the most
+ * significant bit is set if the next byte is also part of the
+ * integer.  Each byte provides bits to the least-significant end of
+ * the result; the accumulated value must be shifted up to place the
+ * new bits into the result.
+ *
+ * "Modified packed integers" are packed integers where only a portion
+ * of the first byte is used.  In the rest of the specification, these
+ * are referred to as "MPI(n,name)", where "n" is the number of bits
+ * discarded from the least-signicant positions of the byte, and
+ * "name" is a name being given to those "discarded" bits, since they
+ * are a field themselves.
+ *
+ * ENTER records:
+ *
+ *      MPI(2,type)  fileno          -- type is 0x00
+ *      PI           lineno
+ *      PI           tdelta          -- iff frame times are enabled
+ *
+ * EXIT records
+ *
+ *      MPI(2,type)  tdelta          -- type is 0x01; tdelta will be 0
+ *                                      if frame times are disabled
+ *
+ * LINENO records
+ *
+ *      MPI(2,type)  lineno          -- type is 0x02
+ *      PI           tdelta          -- iff LINENO includes it
+ *
+ * ADD_INFO records
+ *
+ *      BYTE         type            -- always 0x13
+ *      PI           len1            -- length of first string
+ *      BYTE         string1[len1]   -- len1 bytes of string data
+ *      PI           len2            -- length of second string
+ *      BYTE         string2[len2]   -- len2 bytes of string data
+ *
+ * DEFINE_FILE records
+ *
+ *      BYTE         type            -- always 0x23
+ *      PI           fileno
+ *      PI           len             -- length of filename
+ *      BYTE         filename[len]   -- len bytes of string data
+ *
+ * DEFINE_FUNC records
+ *
+ *      BYTE         type            -- always 0x43
+ *      PI           fileno
+ *      PI           lineno
+ *      PI           len             -- length of funcname
+ *      BYTE         funcname[len]   -- len bytes of string data
+ *
+ * LINE_TIMES records
+ *
+ * This record can be used only before the start of ENTER/EXIT/LINENO
+ * records.  If have_tdelta is true, LINENO records will include the
+ * tdelta field, otherwise it will be omitted.  If this record is not
+ * given, LINENO records will not contain the tdelta field.
+ *
+ *      BYTE         type            -- always 0x33
+ *      BYTE         have_tdelta     -- 0 if LINENO does *not* have
+ *                                      timing information
+ * FRAME_TIMES records
+ *
+ * This record can be used only before the start of ENTER/EXIT/LINENO
+ * records.  If have_tdelta is true, ENTER and EXIT records will
+ * include the tdelta field, otherwise it will be omitted.  If this
+ * record is not given, ENTER and EXIT records will contain the tdelta
+ * field.
+ *
+ *      BYTE         type            -- always 0x53
+ *      BYTE         have_tdelta     -- 0 if ENTER/EXIT do *not* have
+ *                                      timing information
+ */
+
+#define WHAT_ENTER        0x00
+#define WHAT_EXIT         0x01
+#define WHAT_LINENO       0x02
+#define WHAT_OTHER        0x03  /* only used in decoding */
+#define WHAT_ADD_INFO     0x13
+#define WHAT_DEFINE_FILE  0x23
+#define WHAT_LINE_TIMES   0x33
+#define WHAT_DEFINE_FUNC  0x43
+#define WHAT_FRAME_TIMES  0x53
+
+#define ERR_NONE          0
+#define ERR_EOF          -1
+#define ERR_EXCEPTION    -2
+#define ERR_BAD_RECTYPE  -3
+
+#define PISIZE            (sizeof(int) + 1)
+#define MPISIZE           (PISIZE + 1)
+
+/* Maximum size of "normal" events -- nothing that contains string data */
+#define MAXEVENTSIZE      (MPISIZE + PISIZE*2)
+
+
+/* Unpack a packed integer; if "discard" is non-zero, unpack a modified
+ * packed integer with "discard" discarded bits.
+ */
+static int
+unpack_packed_int(LogReaderObject *self, int *pvalue, int discard)
+{
+    int c;
+    int accum = 0;
+    int bits = 0;
+    int cont;
+
+    do {
+        /* read byte */
+	if ((c = fgetc(self->logfp)) == EOF)
+            return ERR_EOF;
+        accum |= ((c & 0x7F) >> discard) << bits;
+        bits += (7 - discard);
+        cont = c & 0x80;
+        discard = 0;
+    } while (cont);
+
+    *pvalue = accum;
+
+    return 0;
+}
+
+/* Unpack a string, which is encoded as a packed integer giving the
+ * length of the string, followed by the string data.
+ */
+static int
+unpack_string(LogReaderObject *self, PyObject **pvalue)
+{
+    int i;
+    int len;
+    int err;
+    int ch;
+    char *buf;
+    
+    if ((err = unpack_packed_int(self, &len, 0)))
+        return err;
+
+    buf = (char *)malloc(len);
+    if (!buf) {
+	PyErr_NoMemory();
+	return ERR_EXCEPTION;
+    }
+
+    for (i=0; i < len; i++) {
+        ch = fgetc(self->logfp);
+	buf[i] = ch;
+        if (ch == EOF) {
+            free(buf);
+            return ERR_EOF;
+        }
+    }
+    *pvalue = PyString_FromStringAndSize(buf, len);
+    free(buf);
+    if (*pvalue == NULL) {
+        return ERR_EXCEPTION;
+    }
+    return 0;
+}
+
+
+static int
+unpack_add_info(LogReaderObject *self)
+{
+    PyObject *key;
+    PyObject *value = NULL;
+    int err;
+
+    err = unpack_string(self, &key);
+    if (!err) {
+        err = unpack_string(self, &value);
+        if (err)
+            Py_DECREF(key);
+        else {
+            PyObject *list = PyDict_GetItem(self->info, key);
+            if (list == NULL) {
+                list = PyList_New(0);
+                if (list == NULL) {
+                    err = ERR_EXCEPTION;
+                    goto finally;
+                }
+                if (PyDict_SetItem(self->info, key, list)) {
+                    Py_DECREF(list);
+                    err = ERR_EXCEPTION;
+                    goto finally;
+                }
+                Py_DECREF(list);
+            }
+            if (PyList_Append(list, value))
+                err = ERR_EXCEPTION;
+        }
+    }
+ finally:
+    Py_XDECREF(key);
+    Py_XDECREF(value);
+    return err;
+}
+
+
+static void
+eof_error(LogReaderObject *self)
+{
+    fclose(self->logfp);
+    self->logfp = NULL;
+    PyErr_SetString(PyExc_EOFError,
+                    "end of file with incomplete profile record");
+}
+
+static PyObject *
+logreader_tp_iternext(LogReaderObject *self)
+{
+    int c;
+    int what;
+    int err = ERR_NONE;
+    int lineno = -1;
+    int fileno = -1;
+    int tdelta = -1;
+    PyObject *s1 = NULL, *s2 = NULL;
+    PyObject *result = NULL;
+#if 0
+    unsigned char b0, b1;
+#endif
+
+    if (self->logfp == NULL) {
+        PyErr_SetString(ProfilerError,
+                        "cannot iterate over closed LogReader object");
+        return NULL;
+    }
+
+restart:
+    /* decode the record type */
+    if ((c = fgetc(self->logfp)) == EOF) {
+        fclose(self->logfp);
+        self->logfp = NULL;
+        return NULL;
+    }
+    what = c & WHAT_OTHER;
+    if (what == WHAT_OTHER)
+        what = c; /* need all the bits for type */
+    else
+        ungetc(c, self->logfp); /* type byte includes packed int */
+
+    switch (what) {
+    case WHAT_ENTER:
+        err = unpack_packed_int(self, &fileno, 2);
+        if (!err) {
+            err = unpack_packed_int(self, &lineno, 0);
+            if (self->frametimings && !err)
+                err = unpack_packed_int(self, &tdelta, 0);
+        }
+        break;
+    case WHAT_EXIT:
+        err = unpack_packed_int(self, &tdelta, 2);
+        break;
+    case WHAT_LINENO:
+        err = unpack_packed_int(self, &lineno, 2);
+        if (self->linetimings && !err)
+            err = unpack_packed_int(self, &tdelta, 0);
+        break;
+    case WHAT_ADD_INFO:
+        err = unpack_add_info(self);
+        break;
+    case WHAT_DEFINE_FILE:
+        err = unpack_packed_int(self, &fileno, 0);
+        if (!err) {
+            err = unpack_string(self, &s1);
+            if (!err) {
+                Py_INCREF(Py_None);
+                s2 = Py_None;
+            }
+        }
+        break;
+    case WHAT_DEFINE_FUNC:
+        err = unpack_packed_int(self, &fileno, 0);
+        if (!err) {
+            err = unpack_packed_int(self, &lineno, 0);
+            if (!err)
+                err = unpack_string(self, &s1);
+        }
+        break;
+    case WHAT_LINE_TIMES:
+        if ((c = fgetc(self->logfp)) == EOF)
+            err = ERR_EOF;
+        else {
+            self->linetimings = c ? 1 : 0;
+	    goto restart;
+	}
+        break;
+    case WHAT_FRAME_TIMES:
+        if ((c = fgetc(self->logfp)) == EOF)
+            err = ERR_EOF;
+        else {
+            self->frametimings = c ? 1 : 0;
+	    goto restart;
+	}
+        break;
+    default:
+        err = ERR_BAD_RECTYPE;
+    }
+    if (err == ERR_BAD_RECTYPE) {
+        PyErr_SetString(PyExc_ValueError,
+                        "unknown record type in log file");
+    }
+    else if (err == ERR_EOF) {
+        eof_error(self);
+    }
+    else if (!err) {
+        result = PyTuple_New(4);
+        if (result == NULL)
+            return NULL;
+        PyTuple_SET_ITEM(result, 0, PyInt_FromLong(what));
+        PyTuple_SET_ITEM(result, 2, PyInt_FromLong(fileno));
+        if (s1 == NULL)
+            PyTuple_SET_ITEM(result, 1, PyInt_FromLong(tdelta));
+        else
+            PyTuple_SET_ITEM(result, 1, s1);
+        if (s2 == NULL)
+            PyTuple_SET_ITEM(result, 3, PyInt_FromLong(lineno));
+        else
+            PyTuple_SET_ITEM(result, 3, s2);
+    }
+    /* The only other case is err == ERR_EXCEPTION, in which case the
+     * exception is already set.
+     */
+#if 0
+    b0 = self->buffer[self->index];
+    b1 = self->buffer[self->index + 1];
+    if (b0 & 1) {
+        /* This is a line-number event. */
+        what = PyTrace_LINE;
+        lineno = ((b0 & ~1) << 7) + b1;
+        self->index += 2;
+    }
+    else {
+        what = (b0 & 0x0E) >> 1;
+        tdelta = ((b0 & 0xF0) << 4) + b1;
+        if (what == PyTrace_CALL) {
+            /* we know there's a 2-byte file ID & 2-byte line number */
+            fileno = ((self->buffer[self->index + 2] << 8)
+                      + self->buffer[self->index + 3]);
+            lineno = ((self->buffer[self->index + 4] << 8)
+                      + self->buffer[self->index + 5]);
+            self->index += 6;
+        }
+        else
+            self->index += 2;
+    }
+#endif
+    return result;
+}
+
+static void
+logreader_dealloc(LogReaderObject *self)
+{
+    if (self->logfp != NULL) {
+        fclose(self->logfp);
+        self->logfp = NULL;
+    }
+    Py_XDECREF(self->info);
+    PyObject_Del(self);
+}
+
+static PyObject *
+logreader_sq_item(LogReaderObject *self, Py_ssize_t index)
+{
+    PyObject *result = logreader_tp_iternext(self);
+    if (result == NULL && !PyErr_Occurred()) {
+        PyErr_SetString(PyExc_IndexError, "no more events in log");
+        return NULL;
+    }
+    return result;
+}
+
+static void
+do_stop(ProfilerObject *self);
+
+static int
+flush_data(ProfilerObject *self)
+{
+    /* Need to dump data to the log file... */
+    size_t written = fwrite(self->buffer, 1, self->index, self->logfp);
+    if (written == (size_t)self->index)
+        self->index = 0;
+    else {
+        memmove(self->buffer, &self->buffer[written],
+                self->index - written);
+        self->index -= written;
+        if (written == 0) {
+            char *s = PyString_AsString(self->logfilename);
+            PyErr_SetFromErrnoWithFilename(PyExc_IOError, s);
+            do_stop(self);
+            return -1;
+        }
+    }
+    if (written > 0) {
+        if (fflush(self->logfp)) {
+            char *s = PyString_AsString(self->logfilename);
+            PyErr_SetFromErrnoWithFilename(PyExc_IOError, s);
+            do_stop(self);
+            return -1;
+        }
+    }
+    return 0;
+}
+
+static inline int
+pack_packed_int(ProfilerObject *self, int value)
+{
+    unsigned char partial;
+
+    do {
+        partial = value & 0x7F;
+        value >>= 7;
+        if (value)
+            partial |= 0x80;
+        self->buffer[self->index] = partial;
+        self->index++;
+    } while (value);
+    return 0;
+}
+
+/* Encode a modified packed integer, with a subfield of modsize bits
+ * containing the value "subfield".  The value of subfield is not
+ * checked to ensure it actually fits in modsize bits.
+ */
+static inline int
+pack_modified_packed_int(ProfilerObject *self, int value,
+                         int modsize, int subfield)
+{
+    const int maxvalues[] = {-1, 1, 3, 7, 15, 31, 63, 127};
+
+    int bits = 7 - modsize;
+    int partial = value & maxvalues[bits];
+    unsigned char b = subfield | (partial << modsize);
+
+    if (partial != value) {
+        b |= 0x80;
+        self->buffer[self->index] = b;
+        self->index++;
+        return pack_packed_int(self, value >> bits);
+    }
+    self->buffer[self->index] = b;
+    self->index++;
+    return 0;
+}
+
+static int
+pack_string(ProfilerObject *self, const char *s, Py_ssize_t len)
+{
+    if (len + PISIZE + self->index >= BUFFERSIZE) {
+        if (flush_data(self) < 0)
+            return -1;
+    }
+    assert(len < INT_MAX);
+    if (pack_packed_int(self, (int)len) < 0)
+        return -1;
+    memcpy(self->buffer + self->index, s, len);
+    self->index += len;
+    return 0;
+}
+
+static int
+pack_add_info(ProfilerObject *self, const char *s1, const char *s2)
+{
+    Py_ssize_t len1 = strlen(s1);
+    Py_ssize_t len2 = strlen(s2);
+
+    if (len1 + len2 + PISIZE*2 + 1 + self->index >= BUFFERSIZE) {
+        if (flush_data(self) < 0)
+            return -1;
+    }
+    self->buffer[self->index] = WHAT_ADD_INFO;
+    self->index++;
+    if (pack_string(self, s1, len1) < 0)
+        return -1;
+    return pack_string(self, s2, len2);
+}
+
+static int
+pack_define_file(ProfilerObject *self, int fileno, const char *filename)
+{
+    Py_ssize_t len = strlen(filename);
+
+    if (len + PISIZE*2 + 1 + self->index >= BUFFERSIZE) {
+        if (flush_data(self) < 0)
+            return -1;
+    }
+    self->buffer[self->index] = WHAT_DEFINE_FILE;
+    self->index++;
+    if (pack_packed_int(self, fileno) < 0)
+        return -1;
+    return pack_string(self, filename, len);
+}
+
+static int
+pack_define_func(ProfilerObject *self, int fileno, int lineno,
+                 const char *funcname)
+{
+    Py_ssize_t len = strlen(funcname);
+
+    if (len + PISIZE*3 + 1 + self->index >= BUFFERSIZE) {
+        if (flush_data(self) < 0)
+            return -1;
+    }
+    self->buffer[self->index] = WHAT_DEFINE_FUNC;
+    self->index++;
+    if (pack_packed_int(self, fileno) < 0)
+        return -1;
+    if (pack_packed_int(self, lineno) < 0)
+        return -1;
+    return pack_string(self, funcname, len);
+}
+
+static int
+pack_line_times(ProfilerObject *self)
+{
+    if (2 + self->index >= BUFFERSIZE) {
+        if (flush_data(self) < 0)
+            return -1;
+    }
+    self->buffer[self->index] = WHAT_LINE_TIMES;
+    self->buffer[self->index + 1] = self->linetimings ? 1 : 0;
+    self->index += 2;
+    return 0;
+}
+
+static int
+pack_frame_times(ProfilerObject *self)
+{
+    if (2 + self->index >= BUFFERSIZE) {
+        if (flush_data(self) < 0)
+            return -1;
+    }
+    self->buffer[self->index] = WHAT_FRAME_TIMES;
+    self->buffer[self->index + 1] = self->frametimings ? 1 : 0;
+    self->index += 2;
+    return 0;
+}
+
+static inline int
+pack_enter(ProfilerObject *self, int fileno, int tdelta, int lineno)
+{
+    if (MPISIZE + PISIZE*2 + self->index >= BUFFERSIZE) {
+        if (flush_data(self) < 0)
+            return -1;
+    }
+    pack_modified_packed_int(self, fileno, 2, WHAT_ENTER);
+    pack_packed_int(self, lineno);
+    if (self->frametimings)
+        return pack_packed_int(self, tdelta);
+    else
+        return 0;
+}
+
+static inline int
+pack_exit(ProfilerObject *self, int tdelta)
+{
+    if (MPISIZE + self->index >= BUFFERSIZE) {
+        if (flush_data(self) < 0)
+            return -1;
+    }
+    if (self->frametimings)
+        return pack_modified_packed_int(self, tdelta, 2, WHAT_EXIT);
+    self->buffer[self->index] = WHAT_EXIT;
+    self->index++;
+    return 0;
+}
+
+static inline int
+pack_lineno(ProfilerObject *self, int lineno)
+{
+    if (MPISIZE + self->index >= BUFFERSIZE) {
+        if (flush_data(self) < 0)
+            return -1;
+    }
+    return pack_modified_packed_int(self, lineno, 2, WHAT_LINENO);
+}
+
+static inline int
+pack_lineno_tdelta(ProfilerObject *self, int lineno, int tdelta)
+{
+    if (MPISIZE + PISIZE + self->index >= BUFFERSIZE) {
+        if (flush_data(self) < 0)
+            return 0;
+    }
+    if (pack_modified_packed_int(self, lineno, 2, WHAT_LINENO) < 0)
+        return -1;
+    return pack_packed_int(self, tdelta);
+}
+
+static inline int
+get_fileno(ProfilerObject *self, PyCodeObject *fcode)
+{
+    /* This is only used for ENTER events. */
+
+    PyObject *obj;
+    PyObject *dict;
+    int fileno;
+
+    obj = PyDict_GetItem(self->filemap, fcode->co_filename);
+    if (obj == NULL) {
+        /* first sighting of this file */
+        dict = PyDict_New();
+        if (dict == NULL) {
+            return -1;
+        }
+        fileno = self->next_fileno;
+        obj = Py_BuildValue("iN", fileno, dict);
+        if (obj == NULL) {
+            return -1;
+        }
+        if (PyDict_SetItem(self->filemap, fcode->co_filename, obj)) {
+            Py_DECREF(obj);
+            return -1;
+        }
+        self->next_fileno++;
+        Py_DECREF(obj);
+        if (pack_define_file(self, fileno,
+                             PyString_AS_STRING(fcode->co_filename)) < 0)
+            return -1;
+    }
+    else {
+        /* already know this ID */
+        fileno = PyInt_AS_LONG(PyTuple_GET_ITEM(obj, 0));
+        dict = PyTuple_GET_ITEM(obj, 1);
+    }
+    /* make sure we save a function name for this (fileno, lineno) */
+    obj = PyInt_FromLong(fcode->co_firstlineno);
+    if (obj == NULL) {
+        /* We just won't have it saved; too bad. */
+        PyErr_Clear();
+    }
+    else {
+        PyObject *name = PyDict_GetItem(dict, obj);
+        if (name == NULL) {
+            if (pack_define_func(self, fileno, fcode->co_firstlineno,
+                                 PyString_AS_STRING(fcode->co_name)) < 0) {
+                Py_DECREF(obj);
+                return -1;
+            }
+            if (PyDict_SetItem(dict, obj, fcode->co_name)) {
+                Py_DECREF(obj);
+                return -1;
+            }
+        }
+        Py_DECREF(obj);
+    }
+    return fileno;
+}
+
+static inline int
+get_tdelta(ProfilerObject *self)
+{
+    int tdelta;
+#ifdef MS_WINDOWS
+    hs_time tv;
+    hs_time diff;
+
+    GETTIMEOFDAY(&tv);
+    diff = tv - self->prev_timeofday;
+    tdelta = (int)diff;
+#else
+    struct timeval tv;
+
+    GETTIMEOFDAY(&tv);
+
+    tdelta = tv.tv_usec - self->prev_timeofday.tv_usec;
+    if (tv.tv_sec != self->prev_timeofday.tv_sec)
+        tdelta += (tv.tv_sec - self->prev_timeofday.tv_sec) * 1000000;
+#endif
+    /* time can go backwards on some multiprocessor systems or by NTP */
+    if (tdelta < 0)
+        return 0;
+
+    self->prev_timeofday = tv;
+    return tdelta;
+}
+
+
+/* The workhorse:  the profiler callback function. */
+
+static int
+tracer_callback(ProfilerObject *self, PyFrameObject *frame, int what,
+                PyObject *arg)
+{
+    int fileno;
+
+    switch (what) {
+    case PyTrace_CALL:
+        fileno = get_fileno(self, frame->f_code);
+        if (fileno < 0)
+            return -1;
+        return pack_enter(self, fileno,
+                          self->frametimings ? get_tdelta(self) : -1,
+                          frame->f_code->co_firstlineno);
+
+    case PyTrace_RETURN:
+        return pack_exit(self, get_tdelta(self));
+
+    case PyTrace_LINE:  /* we only get these events if we asked for them */
+        if (self->linetimings)
+            return pack_lineno_tdelta(self, frame->f_lineno,
+				      get_tdelta(self));
+        else
+            return pack_lineno(self, frame->f_lineno);
+
+    default:
+        /* ignore PyTrace_EXCEPTION */
+        break;
+    }
+    return 0;
+}
+
+
+/* A couple of useful helper functions. */
+
+#ifdef MS_WINDOWS
+static LARGE_INTEGER frequency = {0, 0};
+#endif
+
+static unsigned long timeofday_diff = 0;
+static unsigned long rusage_diff = 0;
+
+static void
+calibrate(void)
+{
+    hs_time tv1, tv2;
+
+#ifdef MS_WINDOWS
+    hs_time diff;
+    QueryPerformanceFrequency(&frequency);
+#endif
+
+    GETTIMEOFDAY(&tv1);
+    while (1) {
+        GETTIMEOFDAY(&tv2);
+#ifdef MS_WINDOWS
+        diff = tv2 - tv1;
+        if (diff != 0) {
+            timeofday_diff = (unsigned long)diff;
+            break;
+        }
+#else
+        if (tv1.tv_sec != tv2.tv_sec || tv1.tv_usec != tv2.tv_usec) {
+            if (tv1.tv_sec == tv2.tv_sec)
+                timeofday_diff = tv2.tv_usec - tv1.tv_usec;
+            else
+                timeofday_diff = (1000000 - tv1.tv_usec) + tv2.tv_usec;
+            break;
+        }
+#endif
+    }
+#if defined(MS_WINDOWS) || defined(PYOS_OS2) || \
+    defined(__VMS) || defined (__QNX__)
+    rusage_diff = -1;
+#else
+    {
+        struct rusage ru1, ru2;
+
+        getrusage(RUSAGE_SELF, &ru1);
+        while (1) {
+            getrusage(RUSAGE_SELF, &ru2);
+            if (ru1.ru_utime.tv_sec != ru2.ru_utime.tv_sec) {
+                rusage_diff = ((1000000 - ru1.ru_utime.tv_usec)
+                               + ru2.ru_utime.tv_usec);
+                break;
+            }
+            else if (ru1.ru_utime.tv_usec != ru2.ru_utime.tv_usec) {
+                rusage_diff = ru2.ru_utime.tv_usec - ru1.ru_utime.tv_usec;
+                break;
+            }
+            else if (ru1.ru_stime.tv_sec != ru2.ru_stime.tv_sec) {
+                rusage_diff = ((1000000 - ru1.ru_stime.tv_usec)
+                               + ru2.ru_stime.tv_usec);
+                break;
+            }
+            else if (ru1.ru_stime.tv_usec != ru2.ru_stime.tv_usec) {
+                rusage_diff = ru2.ru_stime.tv_usec - ru1.ru_stime.tv_usec;
+                break;
+            }
+        }
+    }
+#endif
+}
+
+static void
+do_start(ProfilerObject *self)
+{
+    self->active = 1;
+    GETTIMEOFDAY(&self->prev_timeofday);
+    if (self->lineevents)
+        PyEval_SetTrace((Py_tracefunc) tracer_callback, (PyObject *)self);
+    else
+        PyEval_SetProfile((Py_tracefunc) tracer_callback, (PyObject *)self);
+}
+
+static void
+do_stop(ProfilerObject *self)
+{
+    if (self->active) {
+        self->active = 0;
+        if (self->lineevents)
+            PyEval_SetTrace(NULL, NULL);
+        else
+            PyEval_SetProfile(NULL, NULL);
+    }
+    if (self->index > 0) {
+        /* Best effort to dump out any remaining data. */
+        flush_data(self);
+    }
+}
+
+static int
+is_available(ProfilerObject *self)
+{
+    if (self->active) {
+        PyErr_SetString(ProfilerError, "profiler already active");
+        return 0;
+    }
+    if (self->logfp == NULL) {
+        PyErr_SetString(ProfilerError, "profiler already closed");
+        return 0;
+    }
+    return 1;
+}
+
+
+/* Profiler object interface methods. */
+
+PyDoc_STRVAR(addinfo__doc__,
+"addinfo(key, value)\n"
+"Insert an ADD_INFO record into the log.");
+
+static PyObject *
+profiler_addinfo(ProfilerObject *self, PyObject *args)
+{
+    PyObject *result = NULL;
+    char *key, *value;
+
+    if (PyArg_ParseTuple(args, "ss:addinfo", &key, &value)) {
+        if (self->logfp == NULL)
+            PyErr_SetString(ProfilerError, "profiler already closed");
+        else {
+            if (pack_add_info(self, key, value) == 0) {
+                result = Py_None;
+                Py_INCREF(result);
+            }
+        }
+    }
+    return result;
+}
+
+PyDoc_STRVAR(close__doc__,
+"close()\n"
+"Shut down this profiler and close the log files, even if its active.");
+
+static PyObject *
+profiler_close(ProfilerObject *self)
+{
+    do_stop(self);
+    if (self->logfp != NULL) {
+        fclose(self->logfp);
+        self->logfp = NULL;
+    }
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+#define fileno__doc__ logreader_fileno__doc__
+
+static PyObject *
+profiler_fileno(ProfilerObject *self)
+{
+    if (self->logfp == NULL) {
+        PyErr_SetString(PyExc_ValueError,
+                        "profiler's file object already closed");
+        return NULL;
+    }
+    return PyInt_FromLong(fileno(self->logfp));
+}
+
+PyDoc_STRVAR(runcall__doc__,
+"runcall(callable[, args[, kw]]) -> callable()\n"
+"Profile a specific function call, returning the result of that call.");
+
+static PyObject *
+profiler_runcall(ProfilerObject *self, PyObject *args)
+{
+    PyObject *result = NULL;
+    PyObject *callargs = NULL;
+    PyObject *callkw = NULL;
+    PyObject *callable;
+
+    if (PyArg_UnpackTuple(args, "runcall", 1, 3,
+                         &callable, &callargs, &callkw)) {
+        if (is_available(self)) {
+            do_start(self);
+            result = PyEval_CallObjectWithKeywords(callable, callargs, callkw);
+            do_stop(self);
+        }
+    }
+    return result;
+}
+
+PyDoc_STRVAR(runcode__doc__,
+"runcode(code, globals[, locals])\n"
+"Execute a code object while collecting profile data.  If locals is\n"
+"omitted, globals is used for the locals as well.");
+
+static PyObject *
+profiler_runcode(ProfilerObject *self, PyObject *args)
+{
+    PyObject *result = NULL;
+    PyCodeObject *code;
+    PyObject *globals;
+    PyObject *locals = NULL;
+
+    if (PyArg_ParseTuple(args, "O!O!|O:runcode",
+                         &PyCode_Type, &code,
+                         &PyDict_Type, &globals,
+                         &locals)) {
+        if (is_available(self)) {
+            if (locals == NULL || locals == Py_None)
+                locals = globals;
+            else if (!PyDict_Check(locals)) {
+                PyErr_SetString(PyExc_TypeError,
+                                "locals must be a dictionary or None");
+                return NULL;
+            }
+            do_start(self);
+            result = PyEval_EvalCode(code, globals, locals);
+            do_stop(self);
+#if 0
+            if (!PyErr_Occurred()) {
+                result = Py_None;
+                Py_INCREF(result);
+            }
+#endif
+        }
+    }
+    return result;
+}
+
+PyDoc_STRVAR(start__doc__,
+"start()\n"
+"Install this profiler for the current thread.");
+
+static PyObject *
+profiler_start(ProfilerObject *self, PyObject *args)
+{
+    PyObject *result = NULL;
+
+    if (is_available(self)) {
+        do_start(self);
+        result = Py_None;
+        Py_INCREF(result);
+    }
+    return result;
+}
+
+PyDoc_STRVAR(stop__doc__,
+"stop()\n"
+"Remove this profiler from the current thread.");
+
+static PyObject *
+profiler_stop(ProfilerObject *self, PyObject *args)
+{
+    PyObject *result = NULL;
+
+    if (!self->active)
+        PyErr_SetString(ProfilerError, "profiler not active");
+    else {
+        do_stop(self);
+        result = Py_None;
+        Py_INCREF(result);
+    }
+    return result;
+}
+
+
+/* Python API support. */
+
+static void
+profiler_dealloc(ProfilerObject *self)
+{
+    do_stop(self);
+    if (self->logfp != NULL)
+        fclose(self->logfp);
+    Py_XDECREF(self->filemap);
+    Py_XDECREF(self->logfilename);
+    PyObject_Del((PyObject *)self);
+}
+
+static PyMethodDef profiler_methods[] = {
+    {"addinfo", (PyCFunction)profiler_addinfo, METH_VARARGS, addinfo__doc__},
+    {"close",   (PyCFunction)profiler_close,   METH_NOARGS,  close__doc__},
+    {"fileno",  (PyCFunction)profiler_fileno,  METH_NOARGS,  fileno__doc__},
+    {"runcall", (PyCFunction)profiler_runcall, METH_VARARGS, runcall__doc__},
+    {"runcode", (PyCFunction)profiler_runcode, METH_VARARGS, runcode__doc__},
+    {"start",   (PyCFunction)profiler_start,   METH_NOARGS,  start__doc__},
+    {"stop",    (PyCFunction)profiler_stop,    METH_NOARGS,  stop__doc__},
+    {NULL, NULL}
+};
+
+static PyMemberDef profiler_members[] = {
+    {"frametimings", T_LONG, offsetof(ProfilerObject, linetimings), READONLY},
+    {"lineevents",   T_LONG, offsetof(ProfilerObject, lineevents), READONLY},
+    {"linetimings",  T_LONG, offsetof(ProfilerObject, linetimings), READONLY},
+    {NULL}
+};
+
+static PyObject *
+profiler_get_closed(ProfilerObject *self, void *closure)
+{
+    PyObject *result = (self->logfp == NULL) ? Py_True : Py_False;
+    Py_INCREF(result);
+    return result;
+}
+
+static PyGetSetDef profiler_getsets[] = {
+    {"closed", (getter)profiler_get_closed, NULL,
+     PyDoc_STR("True if the profiler's output file has already been closed.")},
+    {NULL}
+};
+
+
+PyDoc_STRVAR(profiler_object__doc__,
+"High-performance profiler object.\n"
+"\n"
+"Methods:\n"
+"\n"
+"close():      Stop the profiler and close the log files.\n"
+"fileno():     Returns the file descriptor of the log file.\n"
+"runcall():    Run a single function call with profiling enabled.\n"
+"runcode():    Execute a code object with profiling enabled.\n"
+"start():      Install the profiler and return.\n"
+"stop():       Remove the profiler.\n"
+"\n"
+"Attributes (read-only):\n"
+"\n"
+"closed:       True if the profiler has already been closed.\n"
+"frametimings: True if ENTER/EXIT events collect timing information.\n"
+"lineevents:   True if line events are reported to the profiler.\n"
+"linetimings:  True if line events collect timing information.");
+
+static PyTypeObject ProfilerType = {
+    PyObject_HEAD_INIT(NULL)
+    0,					/* ob_size		*/
+    "_hotshot.ProfilerType",		/* tp_name		*/
+    (int) sizeof(ProfilerObject),	/* tp_basicsize		*/
+    0,					/* tp_itemsize		*/
+    (destructor)profiler_dealloc,	/* tp_dealloc		*/
+    0,					/* tp_print		*/
+    0,					/* tp_getattr		*/
+    0,					/* tp_setattr		*/
+    0,					/* tp_compare		*/
+    0,					/* tp_repr		*/
+    0,					/* tp_as_number		*/
+    0,					/* tp_as_sequence	*/
+    0,					/* tp_as_mapping	*/
+    0,					/* tp_hash		*/
+    0,					/* tp_call		*/
+    0,					/* tp_str		*/
+    PyObject_GenericGetAttr,		/* tp_getattro		*/
+    0,					/* tp_setattro		*/
+    0,					/* tp_as_buffer		*/
+    Py_TPFLAGS_DEFAULT,			/* tp_flags		*/
+    profiler_object__doc__,		/* tp_doc		*/
+    0,					/* tp_traverse		*/
+    0,					/* tp_clear		*/
+    0,					/* tp_richcompare	*/
+    0,					/* tp_weaklistoffset	*/
+    0,					/* tp_iter		*/
+    0,					/* tp_iternext		*/
+    profiler_methods,			/* tp_methods		*/
+    profiler_members,			/* tp_members		*/
+    profiler_getsets,			/* tp_getset		*/
+    0,					/* tp_base		*/
+    0,					/* tp_dict		*/
+    0,					/* tp_descr_get		*/
+    0,					/* tp_descr_set		*/
+};
+
+
+static PyMethodDef logreader_methods[] = {
+    {"close",   (PyCFunction)logreader_close,  METH_NOARGS,
+     logreader_close__doc__},
+    {"fileno",  (PyCFunction)logreader_fileno, METH_NOARGS,
+     logreader_fileno__doc__},
+    {NULL, NULL}
+};
+
+static PyMemberDef logreader_members[] = {
+    {"info", T_OBJECT, offsetof(LogReaderObject, info), RO,
+     PyDoc_STR("Dictionary mapping informational keys to lists of values.")},
+    {NULL}
+};
+
+
+PyDoc_STRVAR(logreader__doc__,
+"logreader(filename) --> log-iterator\n\
+Create a log-reader for the timing information file.");
+
+static PySequenceMethods logreader_as_sequence = {
+    0,					/* sq_length */
+    0,					/* sq_concat */
+    0,					/* sq_repeat */
+    (ssizeargfunc)logreader_sq_item,	/* sq_item */
+    0,					/* sq_slice */
+    0,					/* sq_ass_item */
+    0,					/* sq_ass_slice */
+    0,					/* sq_contains */
+    0,					/* sq_inplace_concat */
+    0,					/* sq_inplace_repeat */
+};
+
+static PyObject *
+logreader_get_closed(LogReaderObject *self, void *closure)
+{
+    PyObject *result = (self->logfp == NULL) ? Py_True : Py_False;
+    Py_INCREF(result);
+    return result;
+}
+
+static PyGetSetDef logreader_getsets[] = {
+    {"closed", (getter)logreader_get_closed, NULL,
+     PyDoc_STR("True if the logreader's input file has already been closed.")},
+    {NULL}
+};
+
+static PyTypeObject LogReaderType = {
+    PyObject_HEAD_INIT(NULL)
+    0,					/* ob_size		*/
+    "_hotshot.LogReaderType",		/* tp_name		*/
+    (int) sizeof(LogReaderObject),	/* tp_basicsize		*/
+    0,					/* tp_itemsize		*/
+    (destructor)logreader_dealloc,	/* tp_dealloc		*/
+    0,					/* tp_print		*/
+    0,					/* tp_getattr		*/
+    0,					/* tp_setattr		*/
+    0,					/* tp_compare		*/
+    0,					/* tp_repr		*/
+    0,					/* tp_as_number		*/
+    &logreader_as_sequence,		/* tp_as_sequence	*/
+    0,					/* tp_as_mapping	*/
+    0,					/* tp_hash		*/
+    0,					/* tp_call		*/
+    0,					/* tp_str		*/
+    PyObject_GenericGetAttr,		/* tp_getattro		*/
+    0,					/* tp_setattro		*/
+    0,					/* tp_as_buffer		*/
+    Py_TPFLAGS_DEFAULT,			/* tp_flags		*/
+    logreader__doc__,			/* tp_doc		*/
+    0,					/* tp_traverse		*/
+    0,					/* tp_clear		*/
+    0,					/* tp_richcompare	*/
+    0,					/* tp_weaklistoffset	*/
+    PyObject_SelfIter,			/* tp_iter		*/
+    (iternextfunc)logreader_tp_iternext,/* tp_iternext		*/
+    logreader_methods,			/* tp_methods		*/
+    logreader_members,			/* tp_members		*/
+    logreader_getsets,			/* tp_getset		*/
+    0,					/* tp_base		*/
+    0,					/* tp_dict		*/
+    0,					/* tp_descr_get		*/
+    0,					/* tp_descr_set		*/
+};
+
+static PyObject *
+hotshot_logreader(PyObject *unused, PyObject *args)
+{
+    LogReaderObject *self = NULL;
+    char *filename;
+    int c;
+    int err = 0;
+
+    if (PyArg_ParseTuple(args, "s:logreader", &filename)) {
+        self = PyObject_New(LogReaderObject, &LogReaderType);
+        if (self != NULL) {
+            self->frametimings = 1;
+            self->linetimings = 0;
+            self->info = NULL;
+            self->logfp = fopen(filename, "rb");
+            if (self->logfp == NULL) {
+                PyErr_SetFromErrnoWithFilename(PyExc_IOError, filename);
+                Py_DECREF(self);
+                self = NULL;
+                goto finally;
+            }
+            self->info = PyDict_New();
+            if (self->info == NULL) {
+                Py_DECREF(self);
+                goto finally;
+            }
+            /* read initial info */
+            for (;;) {
+                if ((c = fgetc(self->logfp)) == EOF) {
+                    eof_error(self);
+                    break;
+                }
+                if (c != WHAT_ADD_INFO) {
+                    ungetc(c, self->logfp);
+                    break;
+                }
+                err = unpack_add_info(self);
+                if (err) {
+                    if (err == ERR_EOF)
+                        eof_error(self);
+                    else
+                        PyErr_SetString(PyExc_RuntimeError,
+                                        "unexpected error");
+                    break;
+                }
+            }
+        }
+    }
+ finally:
+    return (PyObject *) self;
+}
+
+
+/* Return a Python string that represents the version number without the
+ * extra cruft added by revision control, even if the right options were
+ * given to the "cvs export" command to make it not include the extra
+ * cruft.
+ */
+static char *
+get_version_string(void)
+{
+    static char *rcsid = "$Revision: 51218 $";
+    char *rev = rcsid;
+    char *buffer;
+    int i = 0;
+
+    while (*rev && !isdigit(Py_CHARMASK(*rev)))
+        ++rev;
+    while (rev[i] != ' ' && rev[i] != '\0')
+        ++i;
+    buffer = (char *)malloc(i + 1);
+    if (buffer != NULL) {
+        memmove(buffer, rev, i);
+        buffer[i] = '\0';
+    }
+    return buffer;
+}
+
+/* Write out a RFC 822-style header with various useful bits of
+ * information to make the output easier to manage.
+ */
+static int
+write_header(ProfilerObject *self)
+{
+    char *buffer;
+    char cwdbuffer[PATH_MAX];
+    PyObject *temp;
+    Py_ssize_t i, len;
+
+    buffer = get_version_string();
+    if (buffer == NULL) {
+        PyErr_NoMemory();
+        return -1;
+    }
+    pack_add_info(self, "hotshot-version", buffer);
+    pack_add_info(self, "requested-frame-timings",
+                  (self->frametimings ? "yes" : "no"));
+    pack_add_info(self, "requested-line-events",
+                  (self->lineevents ? "yes" : "no"));
+    pack_add_info(self, "requested-line-timings",
+                  (self->linetimings ? "yes" : "no"));
+    pack_add_info(self, "platform", Py_GetPlatform());
+    pack_add_info(self, "executable", Py_GetProgramFullPath());
+    free(buffer);
+    buffer = (char *) Py_GetVersion();
+    if (buffer == NULL)
+        PyErr_Clear();
+    else
+        pack_add_info(self, "executable-version", buffer);
+
+#ifdef MS_WINDOWS
+    PyOS_snprintf(cwdbuffer, sizeof(cwdbuffer), "%I64d", frequency.QuadPart);
+    pack_add_info(self, "reported-performance-frequency", cwdbuffer);
+#else
+    PyOS_snprintf(cwdbuffer, sizeof(cwdbuffer), "%lu", rusage_diff);
+    pack_add_info(self, "observed-interval-getrusage", cwdbuffer);
+    PyOS_snprintf(cwdbuffer, sizeof(cwdbuffer), "%lu", timeofday_diff);
+    pack_add_info(self, "observed-interval-gettimeofday", cwdbuffer);
+#endif
+
+    pack_add_info(self, "current-directory",
+                  getcwd(cwdbuffer, sizeof cwdbuffer));
+
+    temp = PySys_GetObject("path");
+    if (temp == NULL || !PyList_Check(temp)) {
+	PyErr_SetString(PyExc_RuntimeError, "sys.path must be a list");
+    	return -1;
+    }
+    len = PyList_GET_SIZE(temp);
+    for (i = 0; i < len; ++i) {
+        PyObject *item = PyList_GET_ITEM(temp, i);
+        buffer = PyString_AsString(item);
+        if (buffer == NULL) {
+            pack_add_info(self, "sys-path-entry", "<non-string-path-entry>");
+            PyErr_Clear();
+        }
+        else {
+            pack_add_info(self, "sys-path-entry", buffer);
+        }
+    }
+    pack_frame_times(self);
+    pack_line_times(self);
+
+    return 0;
+}
+
+PyDoc_STRVAR(profiler__doc__,
+"profiler(logfilename[, lineevents[, linetimes]]) -> profiler\n\
+Create a new profiler object.");
+
+static PyObject *
+hotshot_profiler(PyObject *unused, PyObject *args)
+{
+    char *logfilename;
+    ProfilerObject *self = NULL;
+    int lineevents = 0;
+    int linetimings = 1;
+
+    if (PyArg_ParseTuple(args, "s|ii:profiler", &logfilename,
+                         &lineevents, &linetimings)) {
+        self = PyObject_New(ProfilerObject, &ProfilerType);
+        if (self == NULL)
+            return NULL;
+        self->frametimings = 1;
+        self->lineevents = lineevents ? 1 : 0;
+        self->linetimings = (lineevents && linetimings) ? 1 : 0;
+        self->index = 0;
+        self->active = 0;
+        self->next_fileno = 0;
+        self->logfp = NULL;
+        self->logfilename = PyTuple_GET_ITEM(args, 0);
+        Py_INCREF(self->logfilename);
+        self->filemap = PyDict_New();
+        if (self->filemap == NULL) {
+            Py_DECREF(self);
+            return NULL;
+        }
+        self->logfp = fopen(logfilename, "wb");
+        if (self->logfp == NULL) {
+            Py_DECREF(self);
+            PyErr_SetFromErrnoWithFilename(PyExc_IOError, logfilename);
+            return NULL;
+        }
+        if (timeofday_diff == 0) {
+            /* Run this several times since sometimes the first
+             * doesn't give the lowest values, and we're really trying
+             * to determine the lowest.
+             */
+            calibrate();
+            calibrate();
+            calibrate();
+        }
+        if (write_header(self)) {
+            /* some error occurred, exception has been set */
+            Py_DECREF(self);
+            self = NULL;
+        }
+    }
+    return (PyObject *) self;
+}
+
+PyDoc_STRVAR(coverage__doc__,
+"coverage(logfilename) -> profiler\n\
+Returns a profiler that doesn't collect any timing information, which is\n\
+useful in building a coverage analysis tool.");
+
+static PyObject *
+hotshot_coverage(PyObject *unused, PyObject *args)
+{
+    char *logfilename;
+    PyObject *result = NULL;
+
+    if (PyArg_ParseTuple(args, "s:coverage", &logfilename)) {
+        result = hotshot_profiler(unused, args);
+        if (result != NULL) {
+            ProfilerObject *self = (ProfilerObject *) result;
+            self->frametimings = 0;
+            self->linetimings = 0;
+            self->lineevents = 1;
+        }
+    }
+    return result;
+}
+
+PyDoc_VAR(resolution__doc__) = 
+#ifdef MS_WINDOWS
+PyDoc_STR(
+"resolution() -> (performance-counter-ticks, update-frequency)\n"
+"Return the resolution of the timer provided by the QueryPerformanceCounter()\n"
+"function.  The first value is the smallest observed change, and the second\n"
+"is the result of QueryPerformanceFrequency()."
+)
+#else
+PyDoc_STR(
+"resolution() -> (gettimeofday-usecs, getrusage-usecs)\n"
+"Return the resolution of the timers provided by the gettimeofday() and\n"
+"getrusage() system calls, or -1 if the call is not supported."
+)
+#endif
+;
+
+static PyObject *
+hotshot_resolution(PyObject *self, PyObject *unused)
+{
+    if (timeofday_diff == 0) {
+        calibrate();
+        calibrate();
+        calibrate();
+    }
+#ifdef MS_WINDOWS
+    return Py_BuildValue("ii", timeofday_diff, frequency.LowPart);
+#else
+    return Py_BuildValue("ii", timeofday_diff, rusage_diff);
+#endif
+}
+
+
+static PyMethodDef functions[] = {
+    {"coverage",   hotshot_coverage,   METH_VARARGS, coverage__doc__},
+    {"profiler",   hotshot_profiler,   METH_VARARGS, profiler__doc__},
+    {"logreader",  hotshot_logreader,  METH_VARARGS, logreader__doc__},
+    {"resolution", hotshot_resolution, METH_NOARGS,  resolution__doc__},
+    {NULL, NULL}
+};
+
+
+void
+init_hotshot(void)
+{
+    PyObject *module;
+
+    LogReaderType.ob_type = &PyType_Type;
+    ProfilerType.ob_type = &PyType_Type;
+    module = Py_InitModule("_hotshot", functions);
+    if (module != NULL) {
+        char *s = get_version_string();
+
+        PyModule_AddStringConstant(module, "__version__", s);
+        free(s);
+        Py_INCREF(&LogReaderType);
+        PyModule_AddObject(module, "LogReaderType",
+                           (PyObject *)&LogReaderType);
+        Py_INCREF(&ProfilerType);
+        PyModule_AddObject(module, "ProfilerType",
+                           (PyObject *)&ProfilerType);
+
+        if (ProfilerError == NULL)
+            ProfilerError = PyErr_NewException("hotshot.ProfilerError",
+                                               NULL, NULL);
+        if (ProfilerError != NULL) {
+            Py_INCREF(ProfilerError);
+            PyModule_AddObject(module, "ProfilerError", ProfilerError);
+        }
+        PyModule_AddIntConstant(module, "WHAT_ENTER", WHAT_ENTER);
+        PyModule_AddIntConstant(module, "WHAT_EXIT", WHAT_EXIT);
+        PyModule_AddIntConstant(module, "WHAT_LINENO", WHAT_LINENO);
+        PyModule_AddIntConstant(module, "WHAT_OTHER", WHAT_OTHER);
+        PyModule_AddIntConstant(module, "WHAT_ADD_INFO", WHAT_ADD_INFO);
+        PyModule_AddIntConstant(module, "WHAT_DEFINE_FILE", WHAT_DEFINE_FILE);
+        PyModule_AddIntConstant(module, "WHAT_DEFINE_FUNC", WHAT_DEFINE_FUNC);
+        PyModule_AddIntConstant(module, "WHAT_LINE_TIMES", WHAT_LINE_TIMES);
+    }
+}

Added: vendor/Python/current/Modules/_localemodule.c
===================================================================
--- vendor/Python/current/Modules/_localemodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_localemodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,780 @@
+/***********************************************************
+Copyright (C) 1997, 2002, 2003 Martin von Loewis
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies.
+
+This software comes with no warranty. Use at your own risk.
+
+******************************************************************/
+
+#include "Python.h"
+
+#include <stdio.h>
+#include <locale.h>
+#include <string.h>
+#include <ctype.h>
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#ifdef HAVE_LANGINFO_H
+#include <langinfo.h>
+#endif
+
+#ifdef HAVE_LIBINTL_H
+#include <libintl.h>
+#endif
+
+#ifdef HAVE_WCHAR_H
+#include <wchar.h>
+#endif
+
+#if defined(__APPLE__)
+#include <CoreFoundation/CoreFoundation.h>
+#endif
+
+#if defined(MS_WINDOWS)
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#endif
+
+#ifdef RISCOS
+char *strdup(const char *);
+#endif
+
+PyDoc_STRVAR(locale__doc__, "Support for POSIX locales.");
+
+static PyObject *Error;
+
+/* support functions for formatting floating point numbers */
+
+PyDoc_STRVAR(setlocale__doc__,
+"(integer,string=None) -> string. Activates/queries locale processing.");
+
+/* the grouping is terminated by either 0 or CHAR_MAX */
+static PyObject*
+copy_grouping(char* s)
+{
+    int i;
+    PyObject *result, *val = NULL;
+
+    if (s[0] == '\0')
+        /* empty string: no grouping at all */
+        return PyList_New(0);
+
+    for (i = 0; s[i] != '\0' && s[i] != CHAR_MAX; i++)
+        ; /* nothing */
+
+    result = PyList_New(i+1);
+    if (!result)
+        return NULL;
+
+    i = -1;
+    do {
+        i++;
+        val = PyInt_FromLong(s[i]);
+        if (!val)
+            break;
+        if (PyList_SetItem(result, i, val)) {
+            Py_DECREF(val);
+            val = NULL;
+            break;
+        }
+    } while (s[i] != '\0' && s[i] != CHAR_MAX);
+
+    if (!val) {
+        Py_DECREF(result);
+        return NULL;
+    }
+
+    return result;
+}
+
+static void
+fixup_ulcase(void)
+{
+    PyObject *mods, *strop, *string, *ulo;
+    unsigned char ul[256];
+    int n, c;
+
+    /* find the string and strop modules */
+    mods = PyImport_GetModuleDict();
+    if (!mods)
+        return;
+    string = PyDict_GetItemString(mods, "string");
+    if (string)
+        string = PyModule_GetDict(string);
+    strop=PyDict_GetItemString(mods, "strop");
+    if (strop)
+        strop = PyModule_GetDict(strop);
+    if (!string && !strop)
+        return;
+
+    /* create uppercase map string */
+    n = 0;
+    for (c = 0; c < 256; c++) {
+        if (isupper(c))
+            ul[n++] = c;
+    }
+    ulo = PyString_FromStringAndSize((const char *)ul, n);
+    if (!ulo)
+        return;
+    if (string)
+        PyDict_SetItemString(string, "uppercase", ulo);
+    if (strop)
+        PyDict_SetItemString(strop, "uppercase", ulo);
+    Py_DECREF(ulo);
+
+    /* create lowercase string */
+    n = 0;
+    for (c = 0; c < 256; c++) {
+        if (islower(c))
+            ul[n++] = c;
+    }
+    ulo = PyString_FromStringAndSize((const char *)ul, n);
+    if (!ulo)
+        return;
+    if (string)
+        PyDict_SetItemString(string, "lowercase", ulo);
+    if (strop)
+        PyDict_SetItemString(strop, "lowercase", ulo);
+    Py_DECREF(ulo);
+
+    /* create letters string */
+    n = 0;
+    for (c = 0; c < 256; c++) {
+        if (isalpha(c))
+            ul[n++] = c;
+    }
+    ulo = PyString_FromStringAndSize((const char *)ul, n);
+    if (!ulo)
+        return;
+    if (string)
+        PyDict_SetItemString(string, "letters", ulo);
+    Py_DECREF(ulo);
+}
+
+static PyObject*
+PyLocale_setlocale(PyObject* self, PyObject* args)
+{
+    int category;
+    char *locale = NULL, *result;
+    PyObject *result_object;
+
+    if (!PyArg_ParseTuple(args, "i|z:setlocale", &category, &locale))
+        return NULL;
+
+    if (locale) {
+        /* set locale */
+        result = setlocale(category, locale);
+        if (!result) {
+            /* operation failed, no setting was changed */
+            PyErr_SetString(Error, "unsupported locale setting");
+            return NULL;
+        }
+        result_object = PyString_FromString(result);
+        if (!result_object)
+            return NULL;
+        /* record changes to LC_CTYPE */
+        if (category == LC_CTYPE || category == LC_ALL)
+            fixup_ulcase();
+        /* things that got wrong up to here are ignored */
+        PyErr_Clear();
+    } else {
+        /* get locale */
+        result = setlocale(category, NULL);
+        if (!result) {
+            PyErr_SetString(Error, "locale query failed");
+            return NULL;
+        }
+        result_object = PyString_FromString(result);
+    }
+    return result_object;
+}
+
+PyDoc_STRVAR(localeconv__doc__,
+"() -> dict. Returns numeric and monetary locale-specific parameters.");
+
+static PyObject*
+PyLocale_localeconv(PyObject* self)
+{
+    PyObject* result;
+    struct lconv *l;
+    PyObject *x;
+
+    result = PyDict_New();
+    if (!result)
+        return NULL;
+
+    /* if LC_NUMERIC is different in the C library, use saved value */
+    l = localeconv();
+
+    /* hopefully, the localeconv result survives the C library calls
+       involved herein */
+
+#define RESULT_STRING(s)\
+    x = PyString_FromString(l->s);\
+    if (!x) goto failed;\
+    PyDict_SetItemString(result, #s, x);\
+    Py_XDECREF(x)
+
+#define RESULT_INT(i)\
+    x = PyInt_FromLong(l->i);\
+    if (!x) goto failed;\
+    PyDict_SetItemString(result, #i, x);\
+    Py_XDECREF(x)
+
+    /* Numeric information */
+    RESULT_STRING(decimal_point);
+    RESULT_STRING(thousands_sep);
+    x = copy_grouping(l->grouping);
+    if (!x)
+        goto failed;
+    PyDict_SetItemString(result, "grouping", x);
+    Py_XDECREF(x);
+
+    /* Monetary information */
+    RESULT_STRING(int_curr_symbol);
+    RESULT_STRING(currency_symbol);
+    RESULT_STRING(mon_decimal_point);
+    RESULT_STRING(mon_thousands_sep);
+    x = copy_grouping(l->mon_grouping);
+    if (!x)
+        goto failed;
+    PyDict_SetItemString(result, "mon_grouping", x);
+    Py_XDECREF(x);
+    RESULT_STRING(positive_sign);
+    RESULT_STRING(negative_sign);
+    RESULT_INT(int_frac_digits);
+    RESULT_INT(frac_digits);
+    RESULT_INT(p_cs_precedes);
+    RESULT_INT(p_sep_by_space);
+    RESULT_INT(n_cs_precedes);
+    RESULT_INT(n_sep_by_space);
+    RESULT_INT(p_sign_posn);
+    RESULT_INT(n_sign_posn);
+    return result;
+
+  failed:
+    Py_XDECREF(result);
+    Py_XDECREF(x);
+    return NULL;
+}
+
+PyDoc_STRVAR(strcoll__doc__,
+"string,string -> int. Compares two strings according to the locale.");
+
+static PyObject*
+PyLocale_strcoll(PyObject* self, PyObject* args)
+{
+#if !defined(HAVE_WCSCOLL) || !defined(Py_USING_UNICODE)
+    char *s1,*s2;
+    
+    if (!PyArg_ParseTuple(args, "ss:strcoll", &s1, &s2))
+        return NULL;
+    return PyInt_FromLong(strcoll(s1, s2));
+#else
+    PyObject *os1, *os2, *result = NULL;
+    wchar_t *ws1 = NULL, *ws2 = NULL;
+    int rel1 = 0, rel2 = 0, len1, len2;
+    
+    if (!PyArg_UnpackTuple(args, "strcoll", 2, 2, &os1, &os2))
+        return NULL;
+    /* If both arguments are byte strings, use strcoll.  */
+    if (PyString_Check(os1) && PyString_Check(os2))
+        return PyInt_FromLong(strcoll(PyString_AS_STRING(os1),
+                                      PyString_AS_STRING(os2)));
+    /* If neither argument is unicode, it's an error.  */
+    if (!PyUnicode_Check(os1) && !PyUnicode_Check(os2)) {
+        PyErr_SetString(PyExc_ValueError, "strcoll arguments must be strings");
+    }
+    /* Convert the non-unicode argument to unicode. */
+    if (!PyUnicode_Check(os1)) {
+        os1 = PyUnicode_FromObject(os1);
+        if (!os1)
+            return NULL;
+        rel1 = 1;
+    }
+    if (!PyUnicode_Check(os2)) {
+        os2 = PyUnicode_FromObject(os2);
+        if (!os2) {
+            Py_DECREF(os1);
+            return NULL;
+        } 
+        rel2 = 1;
+    }
+    /* Convert the unicode strings to wchar[]. */
+    len1 = PyUnicode_GET_SIZE(os1) + 1;
+    ws1 = PyMem_MALLOC(len1 * sizeof(wchar_t));
+    if (!ws1) {
+        PyErr_NoMemory();
+        goto done;
+    }
+    if (PyUnicode_AsWideChar((PyUnicodeObject*)os1, ws1, len1) == -1)
+        goto done;
+    ws1[len1 - 1] = 0;
+    len2 = PyUnicode_GET_SIZE(os2) + 1;
+    ws2 = PyMem_MALLOC(len2 * sizeof(wchar_t));
+    if (!ws2) {
+        PyErr_NoMemory();
+        goto done;
+    }
+    if (PyUnicode_AsWideChar((PyUnicodeObject*)os2, ws2, len2) == -1)
+        goto done;
+    ws2[len2 - 1] = 0;
+    /* Collate the strings. */
+    result = PyInt_FromLong(wcscoll(ws1, ws2));
+  done:
+    /* Deallocate everything. */
+    if (ws1) PyMem_FREE(ws1);
+    if (ws2) PyMem_FREE(ws2);
+    if (rel1) {
+        Py_DECREF(os1);
+    }
+    if (rel2) {
+        Py_DECREF(os2);
+    }
+    return result;
+#endif
+}
+
+
+PyDoc_STRVAR(strxfrm__doc__,
+"string -> string. Returns a string that behaves for cmp locale-aware.");
+
+static PyObject*
+PyLocale_strxfrm(PyObject* self, PyObject* args)
+{
+    char *s, *buf;
+    size_t n1, n2;
+    PyObject *result;
+
+    if (!PyArg_ParseTuple(args, "s:strxfrm", &s))
+        return NULL;
+
+    /* assume no change in size, first */
+    n1 = strlen(s) + 1;
+    buf = PyMem_Malloc(n1);
+    if (!buf)
+        return PyErr_NoMemory();
+    n2 = strxfrm(buf, s, n1) + 1;
+    if (n2 > n1) {
+        /* more space needed */
+        buf = PyMem_Realloc(buf, n2);
+        if (!buf)
+            return PyErr_NoMemory();
+        strxfrm(buf, s, n2);
+    }
+    result = PyString_FromString(buf);
+    PyMem_Free(buf);
+    return result;
+}
+
+#if defined(MS_WINDOWS)
+static PyObject*
+PyLocale_getdefaultlocale(PyObject* self)
+{
+    char encoding[100];
+    char locale[100];
+
+    PyOS_snprintf(encoding, sizeof(encoding), "cp%d", GetACP());
+
+    if (GetLocaleInfo(LOCALE_USER_DEFAULT,
+                      LOCALE_SISO639LANGNAME,
+                      locale, sizeof(locale))) {
+        Py_ssize_t i = strlen(locale);
+        locale[i++] = '_';
+        if (GetLocaleInfo(LOCALE_USER_DEFAULT,
+                          LOCALE_SISO3166CTRYNAME,
+                          locale+i, (int)(sizeof(locale)-i)))
+            return Py_BuildValue("ss", locale, encoding);
+    }
+
+    /* If we end up here, this windows version didn't know about
+       ISO639/ISO3166 names (it's probably Windows 95).  Return the
+       Windows language identifier instead (a hexadecimal number) */
+
+    locale[0] = '0';
+    locale[1] = 'x';
+    if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTLANGUAGE,
+                      locale+2, sizeof(locale)-2)) {
+        return Py_BuildValue("ss", locale, encoding);
+    }
+
+    /* cannot determine the language code (very unlikely) */
+    Py_INCREF(Py_None);
+    return Py_BuildValue("Os", Py_None, encoding);
+}
+#endif
+
+#if defined(__APPLE__)
+/*
+** Find out what the current script is.
+** Donated by Fredrik Lundh.
+*/
+static char *mac_getscript(void)
+{
+    CFStringEncoding enc = CFStringGetSystemEncoding();
+    static CFStringRef name = NULL;
+    /* Return the code name for the encodings for which we have codecs. */
+    switch(enc) {
+    case kCFStringEncodingMacRoman: return "mac-roman";
+    case kCFStringEncodingMacGreek: return "mac-greek";
+    case kCFStringEncodingMacCyrillic: return "mac-cyrillic";
+    case kCFStringEncodingMacTurkish: return "mac-turkish";
+    case kCFStringEncodingMacIcelandic: return "mac-icelandic";
+    /* XXX which one is mac-latin2? */
+    }
+    if (!name) {
+        /* This leaks an object. */
+        name = CFStringConvertEncodingToIANACharSetName(enc);
+    }
+    return (char *)CFStringGetCStringPtr(name, 0); 
+}
+
+static PyObject*
+PyLocale_getdefaultlocale(PyObject* self)
+{
+    return Py_BuildValue("Os", Py_None, mac_getscript());
+}
+#endif
+
+#ifdef HAVE_LANGINFO_H
+#define LANGINFO(X) {#X, X}
+struct langinfo_constant{
+	char* name;
+	int value;
+} langinfo_constants[] = 
+{
+    /* These constants should exist on any langinfo implementation */
+    LANGINFO(DAY_1),
+    LANGINFO(DAY_2),
+    LANGINFO(DAY_3),
+    LANGINFO(DAY_4),
+    LANGINFO(DAY_5),
+    LANGINFO(DAY_6),
+    LANGINFO(DAY_7),
+
+    LANGINFO(ABDAY_1),
+    LANGINFO(ABDAY_2),
+    LANGINFO(ABDAY_3),
+    LANGINFO(ABDAY_4),
+    LANGINFO(ABDAY_5),
+    LANGINFO(ABDAY_6),
+    LANGINFO(ABDAY_7),
+
+    LANGINFO(MON_1),
+    LANGINFO(MON_2),
+    LANGINFO(MON_3),
+    LANGINFO(MON_4),
+    LANGINFO(MON_5),
+    LANGINFO(MON_6),
+    LANGINFO(MON_7),
+    LANGINFO(MON_8),
+    LANGINFO(MON_9),
+    LANGINFO(MON_10),
+    LANGINFO(MON_11),
+    LANGINFO(MON_12),
+
+    LANGINFO(ABMON_1),
+    LANGINFO(ABMON_2),
+    LANGINFO(ABMON_3),
+    LANGINFO(ABMON_4),
+    LANGINFO(ABMON_5),
+    LANGINFO(ABMON_6),
+    LANGINFO(ABMON_7),
+    LANGINFO(ABMON_8),
+    LANGINFO(ABMON_9),
+    LANGINFO(ABMON_10),
+    LANGINFO(ABMON_11),
+    LANGINFO(ABMON_12),
+
+#ifdef RADIXCHAR
+    /* The following are not available with glibc 2.0 */
+    LANGINFO(RADIXCHAR),
+    LANGINFO(THOUSEP),
+    /* YESSTR and NOSTR are deprecated in glibc, since they are
+       a special case of message translation, which should be rather
+       done using gettext. So we don't expose it to Python in the
+       first place.
+    LANGINFO(YESSTR),
+    LANGINFO(NOSTR),
+    */
+    LANGINFO(CRNCYSTR),
+#endif
+
+    LANGINFO(D_T_FMT),
+    LANGINFO(D_FMT),
+    LANGINFO(T_FMT),
+    LANGINFO(AM_STR),
+    LANGINFO(PM_STR),
+
+    /* The following constants are available only with XPG4, but...
+       AIX 3.2. only has CODESET.
+       OpenBSD doesn't have CODESET but has T_FMT_AMPM, and doesn't have
+       a few of the others.
+       Solution: ifdef-test them all. */
+#ifdef CODESET
+    LANGINFO(CODESET),
+#endif
+#ifdef T_FMT_AMPM
+    LANGINFO(T_FMT_AMPM),
+#endif
+#ifdef ERA
+    LANGINFO(ERA),
+#endif
+#ifdef ERA_D_FMT
+    LANGINFO(ERA_D_FMT),
+#endif
+#ifdef ERA_D_T_FMT
+    LANGINFO(ERA_D_T_FMT),
+#endif
+#ifdef ERA_T_FMT
+    LANGINFO(ERA_T_FMT),
+#endif
+#ifdef ALT_DIGITS
+    LANGINFO(ALT_DIGITS),
+#endif
+#ifdef YESEXPR
+    LANGINFO(YESEXPR),
+#endif
+#ifdef NOEXPR
+    LANGINFO(NOEXPR),
+#endif
+#ifdef _DATE_FMT
+    /* This is not available in all glibc versions that have CODESET. */
+    LANGINFO(_DATE_FMT),
+#endif
+    {0, 0}
+};
+
+PyDoc_STRVAR(nl_langinfo__doc__,
+"nl_langinfo(key) -> string\n"
+"Return the value for the locale information associated with key.");
+
+static PyObject*
+PyLocale_nl_langinfo(PyObject* self, PyObject* args)
+{
+    int item, i;
+    if (!PyArg_ParseTuple(args, "i:nl_langinfo", &item))
+        return NULL;
+    /* Check whether this is a supported constant. GNU libc sometimes
+       returns numeric values in the char* return value, which would
+       crash PyString_FromString.  */
+    for (i = 0; langinfo_constants[i].name; i++)
+        if (langinfo_constants[i].value == item) {
+            /* Check NULL as a workaround for GNU libc's returning NULL
+               instead of an empty string for nl_langinfo(ERA).  */
+            const char *result = nl_langinfo(item);
+            return PyString_FromString(result != NULL ? result : "");
+        }
+    PyErr_SetString(PyExc_ValueError, "unsupported langinfo constant");
+    return NULL;
+}
+#endif /* HAVE_LANGINFO_H */
+
+#ifdef HAVE_LIBINTL_H
+
+PyDoc_STRVAR(gettext__doc__,
+"gettext(msg) -> string\n"
+"Return translation of msg.");
+
+static PyObject*
+PyIntl_gettext(PyObject* self, PyObject *args)
+{
+	char *in;
+	if (!PyArg_ParseTuple(args, "z", &in))
+		return 0;
+	return PyString_FromString(gettext(in));
+}
+
+PyDoc_STRVAR(dgettext__doc__,
+"dgettext(domain, msg) -> string\n"
+"Return translation of msg in domain.");
+
+static PyObject*
+PyIntl_dgettext(PyObject* self, PyObject *args)
+{
+	char *domain, *in;
+	if (!PyArg_ParseTuple(args, "zz", &domain, &in))
+		return 0;
+	return PyString_FromString(dgettext(domain, in));
+}
+
+PyDoc_STRVAR(dcgettext__doc__,
+"dcgettext(domain, msg, category) -> string\n"
+"Return translation of msg in domain and category.");
+
+static PyObject*
+PyIntl_dcgettext(PyObject *self, PyObject *args)
+{
+	char *domain, *msgid;
+	int category;
+	if (!PyArg_ParseTuple(args, "zzi", &domain, &msgid, &category))
+		return 0;
+	return PyString_FromString(dcgettext(domain,msgid,category));
+}
+
+PyDoc_STRVAR(textdomain__doc__,
+"textdomain(domain) -> string\n"
+"Set the C library's textdmain to domain, returning the new domain.");
+
+static PyObject*
+PyIntl_textdomain(PyObject* self, PyObject* args)
+{
+	char *domain;
+	if (!PyArg_ParseTuple(args, "z", &domain))
+		return 0;
+	domain = textdomain(domain);
+	if (!domain) {
+		PyErr_SetFromErrno(PyExc_OSError);
+		return NULL;
+	}
+	return PyString_FromString(domain);
+}
+
+PyDoc_STRVAR(bindtextdomain__doc__,
+"bindtextdomain(domain, dir) -> string\n"
+"Bind the C library's domain to dir.");
+
+static PyObject*
+PyIntl_bindtextdomain(PyObject* self,PyObject*args)
+{
+	char *domain,*dirname;
+	if (!PyArg_ParseTuple(args, "zz", &domain, &dirname))
+		return 0;
+	dirname = bindtextdomain(domain, dirname);
+	if (!dirname) {
+		PyErr_SetFromErrno(PyExc_OSError);
+		return NULL;
+	}
+	return PyString_FromString(dirname);
+}
+
+#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
+PyDoc_STRVAR(bind_textdomain_codeset__doc__,
+"bind_textdomain_codeset(domain, codeset) -> string\n"
+"Bind the C library's domain to codeset.");
+
+static PyObject*
+PyIntl_bind_textdomain_codeset(PyObject* self,PyObject*args)
+{
+	char *domain,*codeset;
+	if (!PyArg_ParseTuple(args, "sz", &domain, &codeset))
+		return NULL;
+	codeset = bind_textdomain_codeset(domain, codeset);
+	if (codeset)
+		return PyString_FromString(codeset);
+	Py_RETURN_NONE;
+}
+#endif
+
+#endif
+
+static struct PyMethodDef PyLocale_Methods[] = {
+  {"setlocale", (PyCFunction) PyLocale_setlocale, 
+   METH_VARARGS, setlocale__doc__},
+  {"localeconv", (PyCFunction) PyLocale_localeconv, 
+   METH_NOARGS, localeconv__doc__},
+  {"strcoll", (PyCFunction) PyLocale_strcoll, 
+   METH_VARARGS, strcoll__doc__},
+  {"strxfrm", (PyCFunction) PyLocale_strxfrm, 
+   METH_VARARGS, strxfrm__doc__},
+#if defined(MS_WINDOWS) || defined(__APPLE__)
+  {"_getdefaultlocale", (PyCFunction) PyLocale_getdefaultlocale, METH_NOARGS},
+#endif
+#ifdef HAVE_LANGINFO_H
+  {"nl_langinfo", (PyCFunction) PyLocale_nl_langinfo,
+   METH_VARARGS, nl_langinfo__doc__},
+#endif
+#ifdef HAVE_LIBINTL_H
+  {"gettext",(PyCFunction)PyIntl_gettext,METH_VARARGS,
+    gettext__doc__},
+  {"dgettext",(PyCFunction)PyIntl_dgettext,METH_VARARGS,
+   dgettext__doc__},
+  {"dcgettext",(PyCFunction)PyIntl_dcgettext,METH_VARARGS,
+    dcgettext__doc__},
+  {"textdomain",(PyCFunction)PyIntl_textdomain,METH_VARARGS,
+   textdomain__doc__},
+  {"bindtextdomain",(PyCFunction)PyIntl_bindtextdomain,METH_VARARGS,
+   bindtextdomain__doc__},
+#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
+  {"bind_textdomain_codeset",(PyCFunction)PyIntl_bind_textdomain_codeset,
+   METH_VARARGS, bind_textdomain_codeset__doc__},
+#endif
+#endif  
+  {NULL, NULL}
+};
+
+PyMODINIT_FUNC
+init_locale(void)
+{
+    PyObject *m, *d, *x;
+#ifdef HAVE_LANGINFO_H
+    int i;
+#endif
+
+    m = Py_InitModule("_locale", PyLocale_Methods);
+    if (m == NULL)
+    	return;
+
+    d = PyModule_GetDict(m);
+
+    x = PyInt_FromLong(LC_CTYPE);
+    PyDict_SetItemString(d, "LC_CTYPE", x);
+    Py_XDECREF(x);
+
+    x = PyInt_FromLong(LC_TIME);
+    PyDict_SetItemString(d, "LC_TIME", x);
+    Py_XDECREF(x);
+
+    x = PyInt_FromLong(LC_COLLATE);
+    PyDict_SetItemString(d, "LC_COLLATE", x);
+    Py_XDECREF(x);
+
+    x = PyInt_FromLong(LC_MONETARY);
+    PyDict_SetItemString(d, "LC_MONETARY", x);
+    Py_XDECREF(x);
+
+#ifdef LC_MESSAGES
+    x = PyInt_FromLong(LC_MESSAGES);
+    PyDict_SetItemString(d, "LC_MESSAGES", x);
+    Py_XDECREF(x);
+#endif /* LC_MESSAGES */
+
+    x = PyInt_FromLong(LC_NUMERIC);
+    PyDict_SetItemString(d, "LC_NUMERIC", x);
+    Py_XDECREF(x);
+
+    x = PyInt_FromLong(LC_ALL);
+    PyDict_SetItemString(d, "LC_ALL", x);
+    Py_XDECREF(x);
+
+    x = PyInt_FromLong(CHAR_MAX);
+    PyDict_SetItemString(d, "CHAR_MAX", x);
+    Py_XDECREF(x);
+
+    Error = PyErr_NewException("locale.Error", NULL, NULL);
+    PyDict_SetItemString(d, "Error", Error);
+
+    x = PyString_FromString(locale__doc__);
+    PyDict_SetItemString(d, "__doc__", x);
+    Py_XDECREF(x);
+
+#ifdef HAVE_LANGINFO_H
+    for (i = 0; langinfo_constants[i].name; i++) {
+	    PyModule_AddIntConstant(m, langinfo_constants[i].name,
+				    langinfo_constants[i].value);
+    }
+#endif
+}
+
+/* 
+Local variables:
+c-basic-offset: 4
+indent-tabs-mode: nil
+End:
+*/

Added: vendor/Python/current/Modules/_lsprof.c
===================================================================
--- vendor/Python/current/Modules/_lsprof.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_lsprof.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,875 @@
+#include "Python.h"
+#include "compile.h"
+#include "frameobject.h"
+#include "structseq.h"
+#include "rotatingtree.h"
+
+#if !defined(HAVE_LONG_LONG)
+#error "This module requires long longs!"
+#endif
+
+/*** Selection of a high-precision timer ***/
+
+#ifdef MS_WINDOWS
+
+#include <windows.h>
+
+static PY_LONG_LONG
+hpTimer(void)
+{
+	LARGE_INTEGER li;
+	QueryPerformanceCounter(&li);
+	return li.QuadPart;
+}
+
+static double
+hpTimerUnit(void)
+{
+	LARGE_INTEGER li;
+	if (QueryPerformanceFrequency(&li))
+		return 1.0 / li.QuadPart;
+	else
+		return 0.000001;  /* unlikely */
+}
+
+#else  /* !MS_WINDOWS */
+
+#ifndef HAVE_GETTIMEOFDAY
+#error "This module requires gettimeofday() on non-Windows platforms!"
+#endif
+
+#if (defined(PYOS_OS2) && defined(PYCC_GCC))
+#include <sys/time.h>
+#else
+#include <sys/resource.h>
+#include <sys/times.h>
+#endif
+
+static PY_LONG_LONG
+hpTimer(void)
+{
+	struct timeval tv;
+	PY_LONG_LONG ret;
+#ifdef GETTIMEOFDAY_NO_TZ
+	gettimeofday(&tv);
+#else
+	gettimeofday(&tv, (struct timezone *)NULL);
+#endif
+	ret = tv.tv_sec;
+	ret = ret * 1000000 + tv.tv_usec;
+	return ret;
+}
+
+static double
+hpTimerUnit(void)
+{
+	return 0.000001;
+}
+
+#endif  /* MS_WINDOWS */
+
+/************************************************************/
+/* Written by Brett Rosen and Ted Czotter */
+
+struct _ProfilerEntry;
+
+/* represents a function called from another function */
+typedef struct _ProfilerSubEntry {
+	rotating_node_t header;
+	PY_LONG_LONG tt;
+	PY_LONG_LONG it;
+	long callcount;
+	long recursivecallcount;
+	long recursionLevel;
+} ProfilerSubEntry;
+
+/* represents a function or user defined block */
+typedef struct _ProfilerEntry {
+	rotating_node_t header;
+	PyObject *userObj; /* PyCodeObject, or a descriptive str for builtins */
+	PY_LONG_LONG tt; /* total time in this entry */
+	PY_LONG_LONG it; /* inline time in this entry (not in subcalls) */
+	long callcount; /* how many times this was called */
+	long recursivecallcount; /* how many times called recursively */
+	long recursionLevel;
+	rotating_node_t *calls;
+} ProfilerEntry;
+
+typedef struct _ProfilerContext {
+	PY_LONG_LONG t0;
+	PY_LONG_LONG subt;
+	struct _ProfilerContext *previous;
+	ProfilerEntry *ctxEntry;
+} ProfilerContext;
+
+typedef struct {
+	PyObject_HEAD
+	rotating_node_t *profilerEntries;
+	ProfilerContext *currentProfilerContext;
+	ProfilerContext *freelistProfilerContext;
+	int flags;
+	PyObject *externalTimer;
+	double externalTimerUnit;
+} ProfilerObject;
+
+#define POF_ENABLED     0x001
+#define POF_SUBCALLS    0x002
+#define POF_BUILTINS    0x004
+#define POF_NOMEMORY    0x100
+
+staticforward PyTypeObject PyProfiler_Type;
+
+#define PyProfiler_Check(op) PyObject_TypeCheck(op, &PyProfiler_Type)
+#define PyProfiler_CheckExact(op) ((op)->ob_type == &PyProfiler_Type)
+
+/*** External Timers ***/
+
+#define DOUBLE_TIMER_PRECISION   4294967296.0
+static PyObject *empty_tuple;
+
+static PY_LONG_LONG CallExternalTimer(ProfilerObject *pObj)
+{
+	PY_LONG_LONG result;
+	PyObject *o = PyObject_Call(pObj->externalTimer, empty_tuple, NULL);
+	if (o == NULL) {
+		PyErr_WriteUnraisable(pObj->externalTimer);
+		return 0;
+	}
+	if (pObj->externalTimerUnit > 0.0) {
+		/* interpret the result as an integer that will be scaled
+		   in profiler_getstats() */
+		result = PyLong_AsLongLong(o);
+	}
+	else {
+		/* interpret the result as a double measured in seconds.
+		   As the profiler works with PY_LONG_LONG internally
+		   we convert it to a large integer */
+		double val = PyFloat_AsDouble(o);
+		/* error handling delayed to the code below */
+		result = (PY_LONG_LONG) (val * DOUBLE_TIMER_PRECISION);
+	}
+	Py_DECREF(o);
+	if (PyErr_Occurred()) {
+		PyErr_WriteUnraisable((PyObject *) pObj);
+		return 0;
+	}
+	return result;
+}
+
+#define CALL_TIMER(pObj)	((pObj)->externalTimer ?		\
+					CallExternalTimer(pObj) :	\
+					hpTimer())
+
+/*** ProfilerObject ***/
+
+static PyObject *
+normalizeUserObj(PyObject *obj)
+{
+	PyCFunctionObject *fn;
+	if (!PyCFunction_Check(obj)) {
+		Py_INCREF(obj);
+		return obj;
+	}
+	/* Replace built-in function objects with a descriptive string
+	   because of built-in methods -- keeping a reference to
+	   __self__ is probably not a good idea. */
+	fn = (PyCFunctionObject *)obj;
+
+	if (fn->m_self == NULL) {
+		/* built-in function: look up the module name */
+		PyObject *mod = fn->m_module;
+		char *modname;
+		if (mod && PyString_Check(mod)) {
+			modname = PyString_AS_STRING(mod);
+		}
+		else if (mod && PyModule_Check(mod)) {
+			modname = PyModule_GetName(mod);
+			if (modname == NULL) {
+				PyErr_Clear();
+				modname = "__builtin__";
+			}
+		}
+		else {
+			modname = "__builtin__";
+		}
+		if (strcmp(modname, "__builtin__") != 0)
+			return PyString_FromFormat("<%s.%s>",
+						   modname,
+						   fn->m_ml->ml_name);
+		else
+			return PyString_FromFormat("<%s>",
+						   fn->m_ml->ml_name);
+	}
+	else {
+		/* built-in method: try to return
+			repr(getattr(type(__self__), __name__))
+		*/
+		PyObject *self = fn->m_self;
+		PyObject *name = PyString_FromString(fn->m_ml->ml_name);
+		if (name != NULL) {
+			PyObject *mo = _PyType_Lookup(self->ob_type, name);
+			Py_XINCREF(mo);
+			Py_DECREF(name);
+			if (mo != NULL) {
+				PyObject *res = PyObject_Repr(mo);
+				Py_DECREF(mo);
+				if (res != NULL)
+					return res;
+			}
+		}
+		PyErr_Clear();
+		return PyString_FromFormat("<built-in method %s>",
+					   fn->m_ml->ml_name);
+	}
+}
+
+static ProfilerEntry*
+newProfilerEntry(ProfilerObject *pObj, void *key, PyObject *userObj)
+{
+	ProfilerEntry *self;
+	self = (ProfilerEntry*) malloc(sizeof(ProfilerEntry));
+	if (self == NULL) {
+		pObj->flags |= POF_NOMEMORY;
+		return NULL;
+	}
+	userObj = normalizeUserObj(userObj);
+	if (userObj == NULL) {
+		PyErr_Clear();
+		free(self);
+		pObj->flags |= POF_NOMEMORY;
+		return NULL;
+	}
+	self->header.key = key;
+	self->userObj = userObj;
+	self->tt = 0;
+	self->it = 0;
+	self->callcount = 0;
+	self->recursivecallcount = 0;
+	self->recursionLevel = 0;
+	self->calls = EMPTY_ROTATING_TREE;
+	RotatingTree_Add(&pObj->profilerEntries, &self->header);
+	return self;
+}
+
+static ProfilerEntry*
+getEntry(ProfilerObject *pObj, void *key)
+{
+	return (ProfilerEntry*) RotatingTree_Get(&pObj->profilerEntries, key);
+}
+
+static ProfilerSubEntry * 
+getSubEntry(ProfilerObject *pObj, ProfilerEntry *caller, ProfilerEntry* entry)
+{
+	return (ProfilerSubEntry*) RotatingTree_Get(&caller->calls,
+						    (void *)entry);
+}
+
+static ProfilerSubEntry *
+newSubEntry(ProfilerObject *pObj,  ProfilerEntry *caller, ProfilerEntry* entry)
+{
+	ProfilerSubEntry *self;
+	self = (ProfilerSubEntry*) malloc(sizeof(ProfilerSubEntry));
+	if (self == NULL) {
+		pObj->flags |= POF_NOMEMORY;
+		return NULL;
+	}
+	self->header.key = (void *)entry;
+	self->tt = 0;
+	self->it = 0;
+	self->callcount = 0;
+	self->recursivecallcount = 0;
+	self->recursionLevel = 0;
+	RotatingTree_Add(&caller->calls, &self->header);
+	return self;
+}
+
+static int freeSubEntry(rotating_node_t *header, void *arg)
+{
+	ProfilerSubEntry *subentry = (ProfilerSubEntry*) header;
+	free(subentry);
+	return 0;
+}
+
+static int freeEntry(rotating_node_t *header, void *arg)
+{
+	ProfilerEntry *entry = (ProfilerEntry*) header;
+	RotatingTree_Enum(entry->calls, freeSubEntry, NULL);
+	Py_DECREF(entry->userObj);
+	free(entry);
+	return 0;
+}
+
+static void clearEntries(ProfilerObject *pObj)
+{
+	RotatingTree_Enum(pObj->profilerEntries, freeEntry, NULL);
+	pObj->profilerEntries = EMPTY_ROTATING_TREE;
+	/* release the memory hold by the free list of ProfilerContexts */
+	while (pObj->freelistProfilerContext) {
+		ProfilerContext *c = pObj->freelistProfilerContext;
+		pObj->freelistProfilerContext = c->previous;
+		free(c);
+	}
+}
+
+static void
+initContext(ProfilerObject *pObj, ProfilerContext *self, ProfilerEntry *entry)
+{
+	self->ctxEntry = entry;
+	self->subt = 0;
+	self->previous = pObj->currentProfilerContext;
+	pObj->currentProfilerContext = self;
+	++entry->recursionLevel;
+	if ((pObj->flags & POF_SUBCALLS) && self->previous) {
+		/* find or create an entry for me in my caller's entry */
+		ProfilerEntry *caller = self->previous->ctxEntry;
+		ProfilerSubEntry *subentry = getSubEntry(pObj, caller, entry);
+		if (subentry == NULL)
+			subentry = newSubEntry(pObj, caller, entry);
+		if (subentry)
+			++subentry->recursionLevel;
+	}
+	self->t0 = CALL_TIMER(pObj);
+}
+
+static void
+Stop(ProfilerObject *pObj, ProfilerContext *self, ProfilerEntry *entry)
+{
+	PY_LONG_LONG tt = CALL_TIMER(pObj) - self->t0;
+	PY_LONG_LONG it = tt - self->subt;
+	if (self->previous)
+		self->previous->subt += tt;
+	pObj->currentProfilerContext = self->previous;
+	if (--entry->recursionLevel == 0)
+		entry->tt += tt;
+	else
+		++entry->recursivecallcount;
+	entry->it += it;
+	entry->callcount++;
+	if ((pObj->flags & POF_SUBCALLS) && self->previous) {
+		/* find or create an entry for me in my caller's entry */
+		ProfilerEntry *caller = self->previous->ctxEntry;
+		ProfilerSubEntry *subentry = getSubEntry(pObj, caller, entry);
+		if (subentry) {
+			if (--subentry->recursionLevel == 0)
+				subentry->tt += tt;
+			else
+				++subentry->recursivecallcount;
+			subentry->it += it;
+			++subentry->callcount;
+		}
+	}
+}
+
+static void
+ptrace_enter_call(PyObject *self, void *key, PyObject *userObj)
+{
+	/* entering a call to the function identified by 'key'
+	   (which can be a PyCodeObject or a PyMethodDef pointer) */
+	ProfilerObject *pObj = (ProfilerObject*)self;
+	ProfilerEntry *profEntry;
+	ProfilerContext *pContext;
+
+	profEntry = getEntry(pObj, key);
+	if (profEntry == NULL) {
+		profEntry = newProfilerEntry(pObj, key, userObj);
+		if (profEntry == NULL)
+			return;
+	}
+	/* grab a ProfilerContext out of the free list */
+	pContext = pObj->freelistProfilerContext;
+	if (pContext) {
+		pObj->freelistProfilerContext = pContext->previous;
+	}
+	else {
+		/* free list exhausted, allocate a new one */
+		pContext = (ProfilerContext*)
+			malloc(sizeof(ProfilerContext));
+		if (pContext == NULL) {
+			pObj->flags |= POF_NOMEMORY;
+			return;
+		}
+	}
+	initContext(pObj, pContext, profEntry);
+}
+
+static void
+ptrace_leave_call(PyObject *self, void *key)
+{
+	/* leaving a call to the function identified by 'key' */
+	ProfilerObject *pObj = (ProfilerObject*)self;
+	ProfilerEntry *profEntry;
+	ProfilerContext *pContext;
+
+	pContext = pObj->currentProfilerContext;
+	if (pContext == NULL)
+		return;
+	profEntry = getEntry(pObj, key);
+	if (profEntry) {
+		Stop(pObj, pContext, profEntry);
+	}
+	else {
+		pObj->currentProfilerContext = pContext->previous;
+	}
+	/* put pContext into the free list */
+	pContext->previous = pObj->freelistProfilerContext;
+	pObj->freelistProfilerContext = pContext;
+}
+
+static int
+profiler_callback(PyObject *self, PyFrameObject *frame, int what,
+		  PyObject *arg)
+{
+	switch (what) {
+
+	/* the 'frame' of a called function is about to start its execution */
+	case PyTrace_CALL:
+		ptrace_enter_call(self, (void *)frame->f_code,
+				        (PyObject *)frame->f_code);
+		break;
+
+	/* the 'frame' of a called function is about to finish
+	   (either normally or with an exception) */
+	case PyTrace_RETURN:
+		ptrace_leave_call(self, (void *)frame->f_code);
+		break;
+
+	/* case PyTrace_EXCEPTION:
+		If the exception results in the function exiting, a
+		PyTrace_RETURN event will be generated, so we don't need to
+		handle it. */
+
+#ifdef PyTrace_C_CALL	/* not defined in Python <= 2.3 */
+	/* the Python function 'frame' is issuing a call to the built-in
+	   function 'arg' */
+	case PyTrace_C_CALL:
+		if ((((ProfilerObject *)self)->flags & POF_BUILTINS)
+		    && PyCFunction_Check(arg)) {
+			ptrace_enter_call(self,
+					  ((PyCFunctionObject *)arg)->m_ml,
+					  arg);
+		}
+		break;
+
+	/* the call to the built-in function 'arg' is returning into its
+	   caller 'frame' */
+	case PyTrace_C_RETURN:		/* ...normally */
+	case PyTrace_C_EXCEPTION:	/* ...with an exception set */
+		if ((((ProfilerObject *)self)->flags & POF_BUILTINS)
+		    && PyCFunction_Check(arg)) {
+			ptrace_leave_call(self,
+					  ((PyCFunctionObject *)arg)->m_ml);
+		}
+		break;
+#endif
+
+	default:
+		break;
+	}
+	return 0;
+}
+
+static int
+pending_exception(ProfilerObject *pObj)
+{
+	if (pObj->flags & POF_NOMEMORY) {
+		pObj->flags -= POF_NOMEMORY;
+		PyErr_SetString(PyExc_MemoryError,
+				"memory was exhausted while profiling");
+		return -1;
+	}
+	return 0;
+}
+
+/************************************************************/
+
+static PyStructSequence_Field profiler_entry_fields[] = {
+	{"code",         "code object or built-in function name"},
+	{"callcount",    "how many times this was called"},
+	{"reccallcount", "how many times called recursively"},
+	{"totaltime",    "total time in this entry"},
+	{"inlinetime",   "inline time in this entry (not in subcalls)"},
+	{"calls",        "details of the calls"},
+	{0}
+};
+
+static PyStructSequence_Field profiler_subentry_fields[] = {
+	{"code",         "called code object or built-in function name"},
+	{"callcount",    "how many times this is called"},
+	{"reccallcount", "how many times this is called recursively"},
+	{"totaltime",    "total time spent in this call"},
+	{"inlinetime",   "inline time (not in further subcalls)"},
+	{0}
+};
+
+static PyStructSequence_Desc profiler_entry_desc = {
+	"_lsprof.profiler_entry", /* name */
+	NULL, /* doc */
+	profiler_entry_fields,
+	6
+};
+
+static PyStructSequence_Desc profiler_subentry_desc = {
+	"_lsprof.profiler_subentry", /* name */
+	NULL, /* doc */
+	profiler_subentry_fields,
+	5
+};
+
+static int initialized;
+static PyTypeObject StatsEntryType;
+static PyTypeObject StatsSubEntryType;
+
+
+typedef struct {
+	PyObject *list;
+	PyObject *sublist;
+	double factor;
+} statscollector_t;
+
+static int statsForSubEntry(rotating_node_t *node, void *arg)
+{
+	ProfilerSubEntry *sentry = (ProfilerSubEntry*) node;
+	statscollector_t *collect = (statscollector_t*) arg;
+	ProfilerEntry *entry = (ProfilerEntry*) sentry->header.key;
+	int err;
+	PyObject *sinfo;
+	sinfo = PyObject_CallFunction((PyObject*) &StatsSubEntryType,
+				      "((Olldd))",
+				      entry->userObj,
+				      sentry->callcount,
+				      sentry->recursivecallcount,
+				      collect->factor * sentry->tt,
+				      collect->factor * sentry->it);
+	if (sinfo == NULL)
+		return -1;
+	err = PyList_Append(collect->sublist, sinfo);
+	Py_DECREF(sinfo);
+	return err;
+}
+
+static int statsForEntry(rotating_node_t *node, void *arg)
+{
+	ProfilerEntry *entry = (ProfilerEntry*) node;
+	statscollector_t *collect = (statscollector_t*) arg;
+	PyObject *info;
+	int err;
+	if (entry->callcount == 0)
+		return 0;   /* skip */
+
+	if (entry->calls != EMPTY_ROTATING_TREE) {
+		collect->sublist = PyList_New(0);
+		if (collect->sublist == NULL)
+			return -1;
+		if (RotatingTree_Enum(entry->calls,
+				      statsForSubEntry, collect) != 0) {
+			Py_DECREF(collect->sublist);
+			return -1;
+		}
+	}
+	else {
+		Py_INCREF(Py_None);
+		collect->sublist = Py_None;
+	}
+
+	info = PyObject_CallFunction((PyObject*) &StatsEntryType,
+				     "((OllddO))",
+				     entry->userObj,
+				     entry->callcount,
+				     entry->recursivecallcount,
+				     collect->factor * entry->tt,
+				     collect->factor * entry->it,
+				     collect->sublist);
+	Py_DECREF(collect->sublist);
+	if (info == NULL)
+		return -1;
+	err = PyList_Append(collect->list, info);
+	Py_DECREF(info);
+	return err;
+}
+
+PyDoc_STRVAR(getstats_doc, "\
+getstats() -> list of profiler_entry objects\n\
+\n\
+Return all information collected by the profiler.\n\
+Each profiler_entry is a tuple-like object with the\n\
+following attributes:\n\
+\n\
+    code          code object\n\
+    callcount     how many times this was called\n\
+    reccallcount  how many times called recursively\n\
+    totaltime     total time in this entry\n\
+    inlinetime    inline time in this entry (not in subcalls)\n\
+    calls         details of the calls\n\
+\n\
+The calls attribute is either None or a list of\n\
+profiler_subentry objects:\n\
+\n\
+    code          called code object\n\
+    callcount     how many times this is called\n\
+    reccallcount  how many times this is called recursively\n\
+    totaltime     total time spent in this call\n\
+    inlinetime    inline time (not in further subcalls)\n\
+");
+
+static PyObject*
+profiler_getstats(ProfilerObject *pObj, PyObject* noarg)
+{
+	statscollector_t collect;
+	if (pending_exception(pObj))
+		return NULL;
+	if (!pObj->externalTimer)
+		collect.factor = hpTimerUnit();
+	else if (pObj->externalTimerUnit > 0.0)
+		collect.factor = pObj->externalTimerUnit;
+	else
+		collect.factor = 1.0 / DOUBLE_TIMER_PRECISION;
+	collect.list = PyList_New(0);
+	if (collect.list == NULL)
+		return NULL;
+	if (RotatingTree_Enum(pObj->profilerEntries, statsForEntry, &collect)
+	    != 0) {
+		Py_DECREF(collect.list);
+		return NULL;
+	}
+	return collect.list;
+}
+
+static int
+setSubcalls(ProfilerObject *pObj, int nvalue)
+{
+	if (nvalue == 0)
+		pObj->flags &= ~POF_SUBCALLS;
+	else if (nvalue > 0)
+		pObj->flags |=  POF_SUBCALLS;
+	return 0;
+}
+
+static int
+setBuiltins(ProfilerObject *pObj, int nvalue)
+{
+	if (nvalue == 0)
+		pObj->flags &= ~POF_BUILTINS;
+	else if (nvalue > 0) {
+#ifndef PyTrace_C_CALL
+		PyErr_SetString(PyExc_ValueError,
+				"builtins=True requires Python >= 2.4");
+		return -1;
+#else
+		pObj->flags |=  POF_BUILTINS;
+#endif
+	}
+	return 0;
+}
+
+PyDoc_STRVAR(enable_doc, "\
+enable(subcalls=True, builtins=True)\n\
+\n\
+Start collecting profiling information.\n\
+If 'subcalls' is True, also records for each function\n\
+statistics separated according to its current caller.\n\
+If 'builtins' is True, records the time spent in\n\
+built-in functions separately from their caller.\n\
+");
+
+static PyObject*
+profiler_enable(ProfilerObject *self, PyObject *args, PyObject *kwds)
+{
+	int subcalls = -1;
+        int builtins = -1;
+	static char *kwlist[] = {"subcalls", "builtins", 0};
+	if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ii:enable",
+					 kwlist, &subcalls, &builtins))
+		return NULL;
+	if (setSubcalls(self, subcalls) < 0 || setBuiltins(self, builtins) < 0)
+		return NULL;
+	PyEval_SetProfile(profiler_callback, (PyObject*)self);
+	self->flags |= POF_ENABLED;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static void
+flush_unmatched(ProfilerObject *pObj)
+{
+	while (pObj->currentProfilerContext) {
+		ProfilerContext *pContext = pObj->currentProfilerContext;
+		ProfilerEntry *profEntry= pContext->ctxEntry;
+		if (profEntry)
+			Stop(pObj, pContext, profEntry);
+		else
+			pObj->currentProfilerContext = pContext->previous;
+		if (pContext)
+			free(pContext);
+	}
+
+}
+
+PyDoc_STRVAR(disable_doc, "\
+disable()\n\
+\n\
+Stop collecting profiling information.\n\
+");
+
+static PyObject*
+profiler_disable(ProfilerObject *self, PyObject* noarg)
+{
+	self->flags &= ~POF_ENABLED;
+	PyEval_SetProfile(NULL, NULL);
+	flush_unmatched(self);
+	if (pending_exception(self))
+		return NULL;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(clear_doc, "\
+clear()\n\
+\n\
+Clear all profiling information collected so far.\n\
+");
+
+static PyObject*
+profiler_clear(ProfilerObject *pObj, PyObject* noarg)
+{
+	clearEntries(pObj);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static void
+profiler_dealloc(ProfilerObject *op)
+{
+	if (op->flags & POF_ENABLED)
+		PyEval_SetProfile(NULL, NULL);
+	flush_unmatched(op);
+	clearEntries(op);
+	Py_XDECREF(op->externalTimer);
+	op->ob_type->tp_free(op);
+}
+
+static int
+profiler_init(ProfilerObject *pObj, PyObject *args, PyObject *kw)
+{
+	PyObject *o;
+	PyObject *timer = NULL;
+	double timeunit = 0.0;
+	int subcalls = 1;
+#ifdef PyTrace_C_CALL
+	int builtins = 1;
+#else
+	int builtins = 0;
+#endif
+	static char *kwlist[] = {"timer", "timeunit",
+				       "subcalls", "builtins", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(args, kw, "|Odii:Profiler", kwlist,
+					 &timer, &timeunit,
+					 &subcalls, &builtins))
+		return -1;
+
+	if (setSubcalls(pObj, subcalls) < 0 || setBuiltins(pObj, builtins) < 0)
+		return -1;
+	o = pObj->externalTimer;
+	pObj->externalTimer = timer;
+	Py_XINCREF(timer);
+	Py_XDECREF(o);
+	pObj->externalTimerUnit = timeunit;
+	return 0;
+}
+
+static PyMethodDef profiler_methods[] = {
+	{"getstats",    (PyCFunction)profiler_getstats,
+			METH_NOARGS,			getstats_doc},
+	{"enable",	(PyCFunction)profiler_enable,
+			METH_VARARGS | METH_KEYWORDS,	enable_doc},
+	{"disable",	(PyCFunction)profiler_disable,
+			METH_NOARGS,			disable_doc},
+	{"clear",	(PyCFunction)profiler_clear,
+			METH_NOARGS,			clear_doc},
+	{NULL, NULL}
+};
+
+PyDoc_STRVAR(profiler_doc, "\
+Profiler(custom_timer=None, time_unit=None, subcalls=True, builtins=True)\n\
+\n\
+    Builds a profiler object using the specified timer function.\n\
+    The default timer is a fast built-in one based on real time.\n\
+    For custom timer functions returning integers, time_unit can\n\
+    be a float specifying a scale (i.e. how long each integer unit\n\
+    is, in seconds).\n\
+");
+
+statichere PyTypeObject PyProfiler_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0,                                      /* ob_size */
+	"_lsprof.Profiler",                     /* tp_name */
+	sizeof(ProfilerObject),                 /* tp_basicsize */
+	0,                                      /* tp_itemsize */
+	(destructor)profiler_dealloc,           /* tp_dealloc */
+	0,                                      /* tp_print */
+	0,                                      /* tp_getattr */
+	0,                                      /* tp_setattr */
+	0,                                      /* tp_compare */
+	0,                                      /* tp_repr */
+	0,                                      /* tp_as_number */
+	0,                                      /* tp_as_sequence */
+	0,                                      /* tp_as_mapping */
+	0,                                      /* tp_hash */
+	0,                                      /* tp_call */
+	0,                                      /* tp_str */
+	0,                                      /* tp_getattro */
+	0,                                      /* tp_setattro */
+	0,                                      /* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+	profiler_doc,                           /* tp_doc */
+	0,                                      /* tp_traverse */
+	0,                                      /* tp_clear */
+	0,                                      /* tp_richcompare */
+	0,                                      /* tp_weaklistoffset */
+	0,                                      /* tp_iter */
+	0,                                      /* tp_iternext */
+	profiler_methods,                       /* tp_methods */
+	0,                                      /* tp_members */
+	0,                                      /* tp_getset */
+	0,                                      /* tp_base */
+	0,                                      /* tp_dict */
+	0,                                      /* tp_descr_get */
+	0,                                      /* tp_descr_set */
+	0,                                      /* tp_dictoffset */
+	(initproc)profiler_init,                /* tp_init */
+	PyType_GenericAlloc,                    /* tp_alloc */
+	PyType_GenericNew,                      /* tp_new */
+	PyObject_Del,                           /* tp_free */
+};
+
+static PyMethodDef moduleMethods[] = {
+	{NULL, NULL}
+};
+
+PyMODINIT_FUNC
+init_lsprof(void)
+{
+	PyObject *module, *d;
+	module = Py_InitModule3("_lsprof", moduleMethods, "Fast profiler");
+	if (module == NULL)
+		return;
+	d = PyModule_GetDict(module);
+	if (PyType_Ready(&PyProfiler_Type) < 0)
+		return;
+	PyDict_SetItemString(d, "Profiler", (PyObject *)&PyProfiler_Type);
+
+	if (!initialized) {
+		PyStructSequence_InitType(&StatsEntryType, 
+					  &profiler_entry_desc);
+		PyStructSequence_InitType(&StatsSubEntryType, 
+					  &profiler_subentry_desc);
+	}
+	Py_INCREF((PyObject*) &StatsEntryType);
+	Py_INCREF((PyObject*) &StatsSubEntryType);
+	PyModule_AddObject(module, "profiler_entry",
+			   (PyObject*) &StatsEntryType);
+	PyModule_AddObject(module, "profiler_subentry",
+			   (PyObject*) &StatsSubEntryType);
+	empty_tuple = PyTuple_New(0);
+	initialized = 1;
+}

Added: vendor/Python/current/Modules/_randommodule.c
===================================================================
--- vendor/Python/current/Modules/_randommodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_randommodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,580 @@
+/* Random objects */
+
+/* ------------------------------------------------------------------
+   The code in this module was based on a download from:
+	  http://www.math.keio.ac.jp/~matumoto/MT2002/emt19937ar.html
+
+   It was modified in 2002 by Raymond Hettinger as follows:
+
+	* the principal computational lines untouched except for tabbing.
+
+	* renamed genrand_res53() to random_random() and wrapped
+	  in python calling/return code.
+
+	* genrand_int32() and the helper functions, init_genrand()
+	  and init_by_array(), were declared static, wrapped in
+	  Python calling/return code.  also, their global data
+	  references were replaced with structure references.
+
+	* unused functions from the original were deleted.
+	  new, original C python code was added to implement the
+	  Random() interface.
+
+   The following are the verbatim comments from the original code:
+
+   A C-program for MT19937, with initialization improved 2002/1/26.
+   Coded by Takuji Nishimura and Makoto Matsumoto.
+
+   Before using, initialize the state by using init_genrand(seed)
+   or init_by_array(init_key, key_length).
+
+   Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
+   All rights reserved.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+
+     1. Redistributions of source code must retain the above copyright
+	notice, this list of conditions and the following disclaimer.
+
+     2. Redistributions in binary form must reproduce the above copyright
+	notice, this list of conditions and the following disclaimer in the
+	documentation and/or other materials provided with the distribution.
+
+     3. The names of its contributors may not be used to endorse or promote
+	products derived from this software without specific prior written
+	permission.
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+   Any feedback is very welcome.
+   http://www.math.keio.ac.jp/matumoto/emt.html
+   email: matumoto at math.keio.ac.jp
+*/
+
+/* ---------------------------------------------------------------*/
+
+#include "Python.h"
+#include <time.h>		/* for seeding to current time */
+
+/* Period parameters -- These are all magic.  Don't change. */
+#define N 624
+#define M 397
+#define MATRIX_A 0x9908b0dfUL	/* constant vector a */
+#define UPPER_MASK 0x80000000UL /* most significant w-r bits */
+#define LOWER_MASK 0x7fffffffUL /* least significant r bits */
+
+typedef struct {
+	PyObject_HEAD
+	unsigned long state[N];
+	int index;
+} RandomObject;
+
+static PyTypeObject Random_Type;
+
+#define RandomObject_Check(v)	   ((v)->ob_type == &Random_Type)
+
+
+/* Random methods */
+
+
+/* generates a random number on [0,0xffffffff]-interval */
+static unsigned long
+genrand_int32(RandomObject *self)
+{
+	unsigned long y;
+	static unsigned long mag01[2]={0x0UL, MATRIX_A};
+	/* mag01[x] = x * MATRIX_A  for x=0,1 */
+	unsigned long *mt;
+
+	mt = self->state;
+	if (self->index >= N) { /* generate N words at one time */
+		int kk;
+
+		for (kk=0;kk<N-M;kk++) {
+			y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
+			mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1UL];
+		}
+		for (;kk<N-1;kk++) {
+			y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
+			mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1UL];
+		}
+		y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
+		mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL];
+
+		self->index = 0;
+	}
+
+    y = mt[self->index++];
+    y ^= (y >> 11);
+    y ^= (y << 7) & 0x9d2c5680UL;
+    y ^= (y << 15) & 0xefc60000UL;
+    y ^= (y >> 18);
+    return y;
+}
+
+/* random_random is the function named genrand_res53 in the original code;
+ * generates a random number on [0,1) with 53-bit resolution; note that
+ * 9007199254740992 == 2**53; I assume they're spelling "/2**53" as
+ * multiply-by-reciprocal in the (likely vain) hope that the compiler will
+ * optimize the division away at compile-time.  67108864 is 2**26.  In
+ * effect, a contains 27 random bits shifted left 26, and b fills in the
+ * lower 26 bits of the 53-bit numerator.
+ * The orginal code credited Isaku Wada for this algorithm, 2002/01/09.
+ */
+static PyObject *
+random_random(RandomObject *self)
+{
+	unsigned long a=genrand_int32(self)>>5, b=genrand_int32(self)>>6;
+    	return PyFloat_FromDouble((a*67108864.0+b)*(1.0/9007199254740992.0));
+}
+
+/* initializes mt[N] with a seed */
+static void
+init_genrand(RandomObject *self, unsigned long s)
+{
+	int mti;
+	unsigned long *mt;
+
+	mt = self->state;
+	mt[0]= s & 0xffffffffUL;
+	for (mti=1; mti<N; mti++) {
+		mt[mti] =
+		(1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti);
+		/* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
+		/* In the previous versions, MSBs of the seed affect   */
+		/* only MSBs of the array mt[]. 		       */
+		/* 2002/01/09 modified by Makoto Matsumoto	       */
+		mt[mti] &= 0xffffffffUL;
+		/* for >32 bit machines */
+	}
+	self->index = mti;
+	return;
+}
+
+/* initialize by an array with array-length */
+/* init_key is the array for initializing keys */
+/* key_length is its length */
+static PyObject *
+init_by_array(RandomObject *self, unsigned long init_key[], unsigned long key_length)
+{
+	unsigned int i, j, k;	/* was signed in the original code. RDH 12/16/2002 */
+	unsigned long *mt;
+
+	mt = self->state;
+	init_genrand(self, 19650218UL);
+	i=1; j=0;
+	k = (N>key_length ? N : key_length);
+	for (; k; k--) {
+		mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525UL))
+			 + init_key[j] + j; /* non linear */
+		mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
+		i++; j++;
+		if (i>=N) { mt[0] = mt[N-1]; i=1; }
+		if (j>=key_length) j=0;
+	}
+	for (k=N-1; k; k--) {
+		mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941UL))
+			 - i; /* non linear */
+		mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
+		i++;
+		if (i>=N) { mt[0] = mt[N-1]; i=1; }
+	}
+
+    mt[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+/*
+ * The rest is Python-specific code, neither part of, nor derived from, the
+ * Twister download.
+ */
+
+static PyObject *
+random_seed(RandomObject *self, PyObject *args)
+{
+	PyObject *result = NULL;	/* guilty until proved innocent */
+	PyObject *masklower = NULL;
+	PyObject *thirtytwo = NULL;
+	PyObject *n = NULL;
+	unsigned long *key = NULL;
+	unsigned long keymax;		/* # of allocated slots in key */
+	unsigned long keyused;		/* # of used slots in key */
+	int err;
+
+	PyObject *arg = NULL;
+
+	if (!PyArg_UnpackTuple(args, "seed", 0, 1, &arg))
+		return NULL;
+
+	if (arg == NULL || arg == Py_None) {
+		time_t now;
+
+		time(&now);
+		init_genrand(self, (unsigned long)now);
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+	/* If the arg is an int or long, use its absolute value; else use
+	 * the absolute value of its hash code.
+	 */
+	if (PyInt_Check(arg) || PyLong_Check(arg))
+		n = PyNumber_Absolute(arg);
+	else {
+		long hash = PyObject_Hash(arg);
+		if (hash == -1)
+			goto Done;
+		n = PyLong_FromUnsignedLong((unsigned long)hash);
+	}
+	if (n == NULL)
+		goto Done;
+
+	/* Now split n into 32-bit chunks, from the right.  Each piece is
+	 * stored into key, which has a capacity of keymax chunks, of which
+	 * keyused are filled.  Alas, the repeated shifting makes this a
+	 * quadratic-time algorithm; we'd really like to use
+	 * _PyLong_AsByteArray here, but then we'd have to break into the
+	 * long representation to figure out how big an array was needed
+	 * in advance.
+	 */
+	keymax = 8; 	/* arbitrary; grows later if needed */
+	keyused = 0;
+	key = (unsigned long *)PyMem_Malloc(keymax * sizeof(*key));
+	if (key == NULL)
+		goto Done;
+
+	masklower = PyLong_FromUnsignedLong(0xffffffffU);
+	if (masklower == NULL)
+		goto Done;
+	thirtytwo = PyInt_FromLong(32L);
+	if (thirtytwo == NULL)
+		goto Done;
+	while ((err=PyObject_IsTrue(n))) {
+		PyObject *newn;
+		PyObject *pychunk;
+		unsigned long chunk;
+
+		if (err == -1)
+			goto Done;
+		pychunk = PyNumber_And(n, masklower);
+		if (pychunk == NULL)
+			goto Done;
+		chunk = PyLong_AsUnsignedLong(pychunk);
+		Py_DECREF(pychunk);
+		if (chunk == (unsigned long)-1 && PyErr_Occurred())
+			goto Done;
+		newn = PyNumber_Rshift(n, thirtytwo);
+		if (newn == NULL)
+			goto Done;
+		Py_DECREF(n);
+		n = newn;
+		if (keyused >= keymax) {
+			unsigned long bigger = keymax << 1;
+			if ((bigger >> 1) != keymax) {
+				PyErr_NoMemory();
+				goto Done;
+			}
+			key = (unsigned long *)PyMem_Realloc(key,
+						bigger * sizeof(*key));
+			if (key == NULL)
+				goto Done;
+			keymax = bigger;
+		}
+		assert(keyused < keymax);
+		key[keyused++] = chunk;
+	}
+
+	if (keyused == 0)
+		key[keyused++] = 0UL;
+	result = init_by_array(self, key, keyused);
+Done:
+	Py_XDECREF(masklower);
+	Py_XDECREF(thirtytwo);
+	Py_XDECREF(n);
+	PyMem_Free(key);
+	return result;
+}
+
+static PyObject *
+random_getstate(RandomObject *self)
+{
+	PyObject *state;
+	PyObject *element;
+	int i;
+
+	state = PyTuple_New(N+1);
+	if (state == NULL)
+		return NULL;
+	for (i=0; i<N ; i++) {
+		element = PyInt_FromLong((long)(self->state[i]));
+		if (element == NULL)
+			goto Fail;
+		PyTuple_SET_ITEM(state, i, element);
+	}
+	element = PyInt_FromLong((long)(self->index));
+	if (element == NULL)
+		goto Fail;
+	PyTuple_SET_ITEM(state, i, element);
+	return state;
+
+Fail:
+	Py_DECREF(state);
+	return NULL;
+}
+
+static PyObject *
+random_setstate(RandomObject *self, PyObject *state)
+{
+	int i;
+	long element;
+
+	if (!PyTuple_Check(state)) {
+		PyErr_SetString(PyExc_TypeError,
+			"state vector must be a tuple");
+		return NULL;
+	}
+	if (PyTuple_Size(state) != N+1) {
+		PyErr_SetString(PyExc_ValueError,
+			"state vector is the wrong size");
+		return NULL;
+	}
+
+	for (i=0; i<N ; i++) {
+		element = PyInt_AsLong(PyTuple_GET_ITEM(state, i));
+		if (element == -1 && PyErr_Occurred())
+			return NULL;
+		self->state[i] = (unsigned long)element;
+	}
+
+	element = PyInt_AsLong(PyTuple_GET_ITEM(state, i));
+	if (element == -1 && PyErr_Occurred())
+		return NULL;
+	self->index = (int)element;
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/*
+Jumpahead should be a fast way advance the generator n-steps ahead, but
+lacking a formula for that, the next best is to use n and the existing
+state to create a new state far away from the original.
+
+The generator uses constant spaced additive feedback, so shuffling the
+state elements ought to produce a state which would not be encountered
+(in the near term) by calls to random().  Shuffling is normally
+implemented by swapping the ith element with another element ranging
+from 0 to i inclusive.  That allows the element to have the possibility
+of not being moved.  Since the goal is to produce a new, different
+state, the swap element is ranged from 0 to i-1 inclusive.  This assures
+that each element gets moved at least once.
+
+To make sure that consecutive calls to jumpahead(n) produce different
+states (even in the rare case of involutory shuffles), i+1 is added to
+each element at position i.  Successive calls are then guaranteed to
+have changing (growing) values as well as shuffled positions.
+
+Finally, the self->index value is set to N so that the generator itself
+kicks in on the next call to random().	This assures that all results
+have been through the generator and do not just reflect alterations to
+the underlying state.
+*/
+
+static PyObject *
+random_jumpahead(RandomObject *self, PyObject *n)
+{
+	long i, j;
+	PyObject *iobj;
+	PyObject *remobj;
+	unsigned long *mt, tmp;
+
+	if (!PyInt_Check(n) && !PyLong_Check(n)) {
+		PyErr_Format(PyExc_TypeError, "jumpahead requires an "
+			     "integer, not '%s'",
+			     n->ob_type->tp_name);
+		return NULL;
+	}
+
+	mt = self->state;
+	for (i = N-1; i > 1; i--) {
+		iobj = PyInt_FromLong(i);
+		if (iobj == NULL)
+			return NULL;
+		remobj = PyNumber_Remainder(n, iobj);
+		Py_DECREF(iobj);
+		if (remobj == NULL)
+			return NULL;
+		j = PyInt_AsLong(remobj);
+		Py_DECREF(remobj);
+		if (j == -1L && PyErr_Occurred())
+			return NULL;
+		tmp = mt[i];
+		mt[i] = mt[j];
+		mt[j] = tmp;
+	}
+
+	for (i = 0; i < N; i++)
+		mt[i] += i+1;
+
+	self->index = N;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+random_getrandbits(RandomObject *self, PyObject *args)
+{
+	int k, i, bytes;
+	unsigned long r;
+	unsigned char *bytearray;
+	PyObject *result;
+
+	if (!PyArg_ParseTuple(args, "i:getrandbits", &k))
+		return NULL;
+
+	if (k <= 0) {
+		PyErr_SetString(PyExc_ValueError,
+				"number of bits must be greater than zero");
+		return NULL;
+	}
+
+	bytes = ((k - 1) / 32 + 1) * 4;
+	bytearray = (unsigned char *)PyMem_Malloc(bytes);
+	if (bytearray == NULL) {
+		PyErr_NoMemory();
+		return NULL;
+	}
+
+	/* Fill-out whole words, byte-by-byte to avoid endianness issues */
+	for (i=0 ; i<bytes ; i+=4, k-=32) {
+		r = genrand_int32(self);
+		if (k < 32)
+			r >>= (32 - k);
+		bytearray[i+0] = (unsigned char)r;
+		bytearray[i+1] = (unsigned char)(r >> 8);
+		bytearray[i+2] = (unsigned char)(r >> 16);
+		bytearray[i+3] = (unsigned char)(r >> 24);
+	}
+
+	/* little endian order to match bytearray assignment order */
+	result = _PyLong_FromByteArray(bytearray, bytes, 1, 0);
+	PyMem_Free(bytearray);
+	return result;
+}
+
+static PyObject *
+random_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	RandomObject *self;
+	PyObject *tmp;
+
+	if (type == &Random_Type && !_PyArg_NoKeywords("Random()", kwds))
+		return NULL;
+
+	self = (RandomObject *)type->tp_alloc(type, 0);
+	if (self == NULL)
+		return NULL;
+	tmp = random_seed(self, args);
+	if (tmp == NULL) {
+		Py_DECREF(self);
+		return NULL;
+	}
+	Py_DECREF(tmp);
+	return (PyObject *)self;
+}
+
+static PyMethodDef random_methods[] = {
+	{"random",	(PyCFunction)random_random,  METH_NOARGS,
+		PyDoc_STR("random() -> x in the interval [0, 1).")},
+	{"seed",	(PyCFunction)random_seed,  METH_VARARGS,
+		PyDoc_STR("seed([n]) -> None.  Defaults to current time.")},
+	{"getstate",	(PyCFunction)random_getstate,  METH_NOARGS,
+		PyDoc_STR("getstate() -> tuple containing the current state.")},
+	{"setstate",	  (PyCFunction)random_setstate,  METH_O,
+		PyDoc_STR("setstate(state) -> None.  Restores generator state.")},
+	{"jumpahead",	(PyCFunction)random_jumpahead,	METH_O,
+		PyDoc_STR("jumpahead(int) -> None.  Create new state from "
+			  "existing state and integer.")},
+	{"getrandbits",	(PyCFunction)random_getrandbits,  METH_VARARGS,
+		PyDoc_STR("getrandbits(k) -> x.  Generates a long int with "
+			  "k random bits.")},
+	{NULL,		NULL}		/* sentinel */
+};
+
+PyDoc_STRVAR(random_doc,
+"Random() -> create a random number generator with its own internal state.");
+
+static PyTypeObject Random_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0,				/*ob_size*/
+	"_random.Random",		/*tp_name*/
+	sizeof(RandomObject),		/*tp_basicsize*/
+	0,				/*tp_itemsize*/
+	/* methods */
+	0,				/*tp_dealloc*/
+	0,				/*tp_print*/
+	0,				/*tp_getattr*/
+	0,				/*tp_setattr*/
+	0,				/*tp_compare*/
+	0,				/*tp_repr*/
+	0,				/*tp_as_number*/
+	0,				/*tp_as_sequence*/
+	0,				/*tp_as_mapping*/
+	0,				/*tp_hash*/
+	0,				/*tp_call*/
+	0,				/*tp_str*/
+	PyObject_GenericGetAttr,	/*tp_getattro*/
+	0,				/*tp_setattro*/
+	0,				/*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,	/*tp_flags*/
+	random_doc,			/*tp_doc*/
+	0,				/*tp_traverse*/
+	0,				/*tp_clear*/
+	0,				/*tp_richcompare*/
+	0,				/*tp_weaklistoffset*/
+	0,				/*tp_iter*/
+	0,				/*tp_iternext*/
+	random_methods, 		/*tp_methods*/
+	0,				/*tp_members*/
+	0,				/*tp_getset*/
+	0,				/*tp_base*/
+	0,				/*tp_dict*/
+	0,				/*tp_descr_get*/
+	0,				/*tp_descr_set*/
+	0,				/*tp_dictoffset*/
+	0,				/*tp_init*/
+	0,				/*tp_alloc*/
+	random_new,			/*tp_new*/
+	_PyObject_Del,			/*tp_free*/
+	0,				/*tp_is_gc*/
+};
+
+PyDoc_STRVAR(module_doc,
+"Module implements the Mersenne Twister random number generator.");
+
+PyMODINIT_FUNC
+init_random(void)
+{
+	PyObject *m;
+
+	if (PyType_Ready(&Random_Type) < 0)
+		return;
+	m = Py_InitModule3("_random", NULL, module_doc);
+	if (m == NULL)
+		return;
+	Py_INCREF(&Random_Type);
+	PyModule_AddObject(m, "Random", (PyObject *)&Random_Type);
+}

Added: vendor/Python/current/Modules/_sqlite/cache.c
===================================================================
--- vendor/Python/current/Modules/_sqlite/cache.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_sqlite/cache.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,375 @@
+/* cache .c - a LRU cache
+ *
+ * Copyright (C) 2004-2006 Gerhard Häring <gh at ghaering.de>
+ *
+ * This file is part of pysqlite.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#include "cache.h"
+#include <limits.h>
+
+/* only used internally */
+Node* new_node(PyObject* key, PyObject* data)
+{
+    Node* node;
+
+    node = (Node*) (NodeType.tp_alloc(&NodeType, 0));
+    if (!node) {
+        return NULL;
+    }
+
+    Py_INCREF(key);
+    node->key = key;
+
+    Py_INCREF(data);
+    node->data = data;
+
+    node->prev = NULL;
+    node->next = NULL;
+
+    return node;
+}
+
+void node_dealloc(Node* self)
+{
+    Py_DECREF(self->key);
+    Py_DECREF(self->data);
+
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+int cache_init(Cache* self, PyObject* args, PyObject* kwargs)
+{
+    PyObject* factory;
+    int size = 10;
+
+    self->factory = NULL;
+
+    if (!PyArg_ParseTuple(args, "O|i", &factory, &size)) {
+        return -1;
+    }
+
+    /* minimum cache size is 5 entries */
+    if (size < 5) {
+        size = 5;
+    }
+    self->size = size;
+    self->first = NULL;
+    self->last = NULL;
+
+    self->mapping = PyDict_New();
+    if (!self->mapping) {
+        return -1;
+    }
+
+    Py_INCREF(factory);
+    self->factory = factory;
+
+    self->decref_factory = 1;
+
+    return 0;
+}
+
+void cache_dealloc(Cache* self)
+{
+    Node* node;
+    Node* delete_node;
+
+    if (!self->factory) {
+        /* constructor failed, just get out of here */
+        return;
+    }
+
+    /* iterate over all nodes and deallocate them */
+    node = self->first;
+    while (node) {
+        delete_node = node;
+        node = node->next;
+        Py_DECREF(delete_node);
+    }
+
+    if (self->decref_factory) {
+        Py_DECREF(self->factory);
+    }
+    Py_DECREF(self->mapping);
+
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+PyObject* cache_get(Cache* self, PyObject* args)
+{
+    PyObject* key = args;
+    Node* node;
+    Node* ptr;
+    PyObject* data;
+
+    node = (Node*)PyDict_GetItem(self->mapping, key);
+    if (node) {
+        /* an entry for this key already exists in the cache */
+
+        /* increase usage counter of the node found */
+        if (node->count < LONG_MAX) {
+            node->count++;
+        }
+
+        /* if necessary, reorder entries in the cache by swapping positions */
+        if (node->prev && node->count > node->prev->count) {
+            ptr = node->prev;
+
+            while (ptr->prev && node->count > ptr->prev->count) {
+                ptr = ptr->prev;
+            }
+
+            if (node->next) {
+                node->next->prev = node->prev;
+            } else {
+                self->last = node->prev;
+            }
+            if (node->prev) {
+                node->prev->next = node->next;
+            }
+            if (ptr->prev) {
+                ptr->prev->next = node;
+            } else {
+                self->first = node;
+            }
+
+            node->next = ptr;
+            node->prev = ptr->prev;
+            if (!node->prev) {
+                self->first = node;
+            }
+            ptr->prev = node;
+        }
+    } else {
+        /* There is no entry for this key in the cache, yet. We'll insert a new
+         * entry in the cache, and make space if necessary by throwing the
+         * least used item out of the cache. */
+
+        if (PyDict_Size(self->mapping) == self->size) {
+            if (self->last) {
+                node = self->last;
+
+                if (PyDict_DelItem(self->mapping, self->last->key) != 0) {
+                    return NULL;
+                }
+
+                if (node->prev) {
+                    node->prev->next = NULL;
+                }
+                self->last = node->prev;
+                node->prev = NULL;
+
+                Py_DECREF(node);
+            }
+        }
+
+        data = PyObject_CallFunction(self->factory, "O", key);
+
+        if (!data) {
+            return NULL;
+        }
+
+        node = new_node(key, data);
+        if (!node) {
+            return NULL;
+        }
+        node->prev = self->last;
+
+        Py_DECREF(data);
+
+        if (PyDict_SetItem(self->mapping, key, (PyObject*)node) != 0) {
+            Py_DECREF(node);
+            return NULL;
+        }
+
+        if (self->last) {
+            self->last->next = node;
+        } else {
+            self->first = node;
+        }
+        self->last = node;
+    }
+
+    Py_INCREF(node->data);
+    return node->data;
+}
+
+PyObject* cache_display(Cache* self, PyObject* args)
+{
+    Node* ptr;
+    PyObject* prevkey;
+    PyObject* nextkey;
+    PyObject* fmt_args;
+    PyObject* template;
+    PyObject* display_str;
+
+    ptr = self->first;
+
+    while (ptr) {
+        if (ptr->prev) {
+            prevkey = ptr->prev->key;
+        } else {
+            prevkey = Py_None;
+        }
+        Py_INCREF(prevkey);
+
+        if (ptr->next) {
+            nextkey = ptr->next->key;
+        } else {
+            nextkey = Py_None;
+        }
+        Py_INCREF(nextkey);
+
+        fmt_args = Py_BuildValue("OOO", prevkey, ptr->key, nextkey);
+        if (!fmt_args) {
+            return NULL;
+        }
+        template = PyString_FromString("%s <- %s ->%s\n");
+        if (!template) {
+            return NULL;
+        }
+        display_str = PyString_Format(template, fmt_args);
+        Py_DECREF(template);
+        Py_DECREF(fmt_args);
+        if (!display_str) {
+            return NULL;
+        }
+        PyObject_Print(display_str, stdout, Py_PRINT_RAW);
+        Py_DECREF(display_str);
+
+        Py_DECREF(prevkey);
+        Py_DECREF(nextkey);
+
+        ptr = ptr->next;
+    }
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyMethodDef cache_methods[] = {
+    {"get", (PyCFunction)cache_get, METH_O,
+        PyDoc_STR("Gets an entry from the cache or calls the factory function to produce one.")},
+    {"display", (PyCFunction)cache_display, METH_NOARGS,
+        PyDoc_STR("For debugging only.")},
+    {NULL, NULL}
+};
+
+PyTypeObject NodeType = {
+        PyObject_HEAD_INIT(NULL)
+        0,                                              /* ob_size */
+        MODULE_NAME "Node",                             /* tp_name */
+        sizeof(Node),                                   /* tp_basicsize */
+        0,                                              /* tp_itemsize */
+        (destructor)node_dealloc,                       /* tp_dealloc */
+        0,                                              /* tp_print */
+        0,                                              /* tp_getattr */
+        0,                                              /* tp_setattr */
+        0,                                              /* tp_compare */
+        0,                                              /* tp_repr */
+        0,                                              /* tp_as_number */
+        0,                                              /* tp_as_sequence */
+        0,                                              /* tp_as_mapping */
+        0,                                              /* tp_hash */
+        0,                                              /* tp_call */
+        0,                                              /* tp_str */
+        0,                                              /* tp_getattro */
+        0,                                              /* tp_setattro */
+        0,                                              /* tp_as_buffer */
+        Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,         /* tp_flags */
+        0,                                              /* tp_doc */
+        0,                                              /* tp_traverse */
+        0,                                              /* tp_clear */
+        0,                                              /* tp_richcompare */
+        0,                                              /* tp_weaklistoffset */
+        0,                                              /* tp_iter */
+        0,                                              /* tp_iternext */
+        0,                                              /* tp_methods */
+        0,                                              /* tp_members */
+        0,                                              /* tp_getset */
+        0,                                              /* tp_base */
+        0,                                              /* tp_dict */
+        0,                                              /* tp_descr_get */
+        0,                                              /* tp_descr_set */
+        0,                                              /* tp_dictoffset */
+        (initproc)0,                                    /* tp_init */
+        0,                                              /* tp_alloc */
+        0,                                              /* tp_new */
+        0                                               /* tp_free */
+};
+
+PyTypeObject CacheType = {
+        PyObject_HEAD_INIT(NULL)
+        0,                                              /* ob_size */
+        MODULE_NAME ".Cache",                           /* tp_name */
+        sizeof(Cache),                                  /* tp_basicsize */
+        0,                                              /* tp_itemsize */
+        (destructor)cache_dealloc,                      /* tp_dealloc */
+        0,                                              /* tp_print */
+        0,                                              /* tp_getattr */
+        0,                                              /* tp_setattr */
+        0,                                              /* tp_compare */
+        0,                                              /* tp_repr */
+        0,                                              /* tp_as_number */
+        0,                                              /* tp_as_sequence */
+        0,                                              /* tp_as_mapping */
+        0,                                              /* tp_hash */
+        0,                                              /* tp_call */
+        0,                                              /* tp_str */
+        0,                                              /* tp_getattro */
+        0,                                              /* tp_setattro */
+        0,                                              /* tp_as_buffer */
+        Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,         /* tp_flags */
+        0,                                              /* tp_doc */
+        0,                                              /* tp_traverse */
+        0,                                              /* tp_clear */
+        0,                                              /* tp_richcompare */
+        0,                                              /* tp_weaklistoffset */
+        0,                                              /* tp_iter */
+        0,                                              /* tp_iternext */
+        cache_methods,                                  /* tp_methods */
+        0,                                              /* tp_members */
+        0,                                              /* tp_getset */
+        0,                                              /* tp_base */
+        0,                                              /* tp_dict */
+        0,                                              /* tp_descr_get */
+        0,                                              /* tp_descr_set */
+        0,                                              /* tp_dictoffset */
+        (initproc)cache_init,                           /* tp_init */
+        0,                                              /* tp_alloc */
+        0,                                              /* tp_new */
+        0                                               /* tp_free */
+};
+
+extern int cache_setup_types(void)
+{
+    int rc;
+
+    NodeType.tp_new = PyType_GenericNew;
+    CacheType.tp_new = PyType_GenericNew;
+
+    rc = PyType_Ready(&NodeType);
+    if (rc < 0) {
+        return rc;
+    }
+
+    rc = PyType_Ready(&CacheType);
+    return rc;
+}

Added: vendor/Python/current/Modules/_sqlite/cache.h
===================================================================
--- vendor/Python/current/Modules/_sqlite/cache.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_sqlite/cache.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,73 @@
+/* cache.h - definitions for the LRU cache
+ *
+ * Copyright (C) 2004-2006 Gerhard Häring <gh at ghaering.de>
+ *
+ * This file is part of pysqlite.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#ifndef PYSQLITE_CACHE_H
+#define PYSQLITE_CACHE_H
+#include "Python.h"
+
+/* The LRU cache is implemented as a combination of a doubly-linked with a
+ * dictionary. The list items are of type 'Node' and the dictionary has the
+ * nodes as values. */
+
+typedef struct _Node
+{
+    PyObject_HEAD
+    PyObject* key;
+    PyObject* data;
+    long count;
+    struct _Node* prev;
+    struct _Node* next;
+} Node;
+
+typedef struct
+{
+    PyObject_HEAD
+    int size;
+
+    /* a dictionary mapping keys to Node entries */
+    PyObject* mapping;
+
+    /* the factory callable */
+    PyObject* factory;
+
+    Node* first;
+    Node* last;
+
+    /* if set, decrement the factory function when the Cache is deallocated.
+     * this is almost always desirable, but not in the pysqlite context */
+    int decref_factory;
+} Cache;
+
+extern PyTypeObject NodeType;
+extern PyTypeObject CacheType;
+
+int node_init(Node* self, PyObject* args, PyObject* kwargs);
+void node_dealloc(Node* self);
+
+int cache_init(Cache* self, PyObject* args, PyObject* kwargs);
+void cache_dealloc(Cache* self);
+PyObject* cache_get(Cache* self, PyObject* args);
+
+int cache_setup_types(void);
+
+#endif

Added: vendor/Python/current/Modules/_sqlite/connection.c
===================================================================
--- vendor/Python/current/Modules/_sqlite/connection.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_sqlite/connection.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1255 @@
+/* connection.c - the connection type
+ *
+ * Copyright (C) 2004-2006 Gerhard Häring <gh at ghaering.de>
+ *
+ * This file is part of pysqlite.
+ * 
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#include "cache.h"
+#include "module.h"
+#include "connection.h"
+#include "statement.h"
+#include "cursor.h"
+#include "prepare_protocol.h"
+#include "util.h"
+#include "sqlitecompat.h"
+
+#include "pythread.h"
+
+static int connection_set_isolation_level(Connection* self, PyObject* isolation_level);
+
+
+void _sqlite3_result_error(sqlite3_context* ctx, const char* errmsg, int len)
+{
+    /* in older SQLite versions, calling sqlite3_result_error in callbacks
+     * triggers a bug in SQLite that leads either to irritating results or
+     * segfaults, depending on the SQLite version */
+#if SQLITE_VERSION_NUMBER >= 3003003
+    sqlite3_result_error(ctx, errmsg, len);
+#else
+    PyErr_SetString(OperationalError, errmsg);
+#endif
+}
+
+int connection_init(Connection* self, PyObject* args, PyObject* kwargs)
+{
+    static char *kwlist[] = {"database", "timeout", "detect_types", "isolation_level", "check_same_thread", "factory", "cached_statements", NULL, NULL};
+
+    char* database;
+    int detect_types = 0;
+    PyObject* isolation_level = NULL;
+    PyObject* factory = NULL;
+    int check_same_thread = 1;
+    int cached_statements = 100;
+    double timeout = 5.0;
+    int rc;
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|diOiOi", kwlist,
+                                     &database, &timeout, &detect_types, &isolation_level, &check_same_thread, &factory, &cached_statements))
+    {
+        return -1; 
+    }
+
+    self->begin_statement = NULL;
+
+    self->statement_cache = NULL;
+    self->statements = NULL;
+
+    Py_INCREF(Py_None);
+    self->row_factory = Py_None;
+
+    Py_INCREF(&PyUnicode_Type);
+    self->text_factory = (PyObject*)&PyUnicode_Type;
+
+    Py_BEGIN_ALLOW_THREADS
+    rc = sqlite3_open(database, &self->db);
+    Py_END_ALLOW_THREADS
+
+    if (rc != SQLITE_OK) {
+        _seterror(self->db);
+        return -1;
+    }
+
+    if (!isolation_level) {
+        isolation_level = PyString_FromString("");
+        if (!isolation_level) {
+            return -1;
+        }
+    } else {
+        Py_INCREF(isolation_level);
+    }
+    self->isolation_level = NULL;
+    connection_set_isolation_level(self, isolation_level);
+    Py_DECREF(isolation_level);
+
+    self->statement_cache = (Cache*)PyObject_CallFunction((PyObject*)&CacheType, "Oi", self, cached_statements);
+    if (PyErr_Occurred()) {
+        return -1;
+    }
+
+    self->statements = PyList_New(0);
+    if (!self->statements) {
+        return -1;
+    }
+    self->created_statements = 0;
+
+    /* By default, the Cache class INCREFs the factory in its initializer, and
+     * decrefs it in its deallocator method. Since this would create a circular
+     * reference here, we're breaking it by decrementing self, and telling the
+     * cache class to not decref the factory (self) in its deallocator.
+     */
+    self->statement_cache->decref_factory = 0;
+    Py_DECREF(self);
+
+    self->inTransaction = 0;
+    self->detect_types = detect_types;
+    self->timeout = timeout;
+    (void)sqlite3_busy_timeout(self->db, (int)(timeout*1000));
+
+    self->thread_ident = PyThread_get_thread_ident();
+    self->check_same_thread = check_same_thread;
+
+    self->function_pinboard = PyDict_New();
+    if (!self->function_pinboard) {
+        return -1;
+    }
+
+    self->collations = PyDict_New();
+    if (!self->collations) {
+        return -1;
+    }
+
+    self->Warning = Warning;
+    self->Error = Error;
+    self->InterfaceError = InterfaceError;
+    self->DatabaseError = DatabaseError;
+    self->DataError = DataError;
+    self->OperationalError = OperationalError;
+    self->IntegrityError = IntegrityError;
+    self->InternalError = InternalError;
+    self->ProgrammingError = ProgrammingError;
+    self->NotSupportedError = NotSupportedError;
+
+    return 0;
+}
+
+/* Empty the entire statement cache of this connection */
+void flush_statement_cache(Connection* self)
+{
+    Node* node;
+    Statement* statement;
+
+    node = self->statement_cache->first;
+
+    while (node) {
+        statement = (Statement*)(node->data);
+        (void)statement_finalize(statement);
+        node = node->next;
+    }
+
+    Py_DECREF(self->statement_cache);
+    self->statement_cache = (Cache*)PyObject_CallFunction((PyObject*)&CacheType, "O", self);
+    Py_DECREF(self);
+    self->statement_cache->decref_factory = 0;
+}
+
+void reset_all_statements(Connection* self)
+{
+    int i;
+    PyObject* weakref;
+    PyObject* statement;
+
+    for (i = 0; i < PyList_Size(self->statements); i++) {
+        weakref = PyList_GetItem(self->statements, i);
+        statement = PyWeakref_GetObject(weakref);
+        if (statement != Py_None) {
+            (void)statement_reset((Statement*)statement);
+        }
+    }
+}
+
+void connection_dealloc(Connection* self)
+{
+    Py_XDECREF(self->statement_cache);
+
+    /* Clean up if user has not called .close() explicitly. */
+    if (self->db) {
+        Py_BEGIN_ALLOW_THREADS
+        sqlite3_close(self->db);
+        Py_END_ALLOW_THREADS
+    }
+
+    if (self->begin_statement) {
+        PyMem_Free(self->begin_statement);
+    }
+    Py_XDECREF(self->isolation_level);
+    Py_XDECREF(self->function_pinboard);
+    Py_XDECREF(self->row_factory);
+    Py_XDECREF(self->text_factory);
+    Py_XDECREF(self->collations);
+    Py_XDECREF(self->statements);
+
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+PyObject* connection_cursor(Connection* self, PyObject* args, PyObject* kwargs)
+{
+    static char *kwlist[] = {"factory", NULL, NULL};
+    PyObject* factory = NULL;
+    PyObject* cursor;
+
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", kwlist,
+                                     &factory)) {
+        return NULL;
+    }
+
+    if (!check_thread(self) || !check_connection(self)) {
+        return NULL;
+    }
+
+    if (factory == NULL) {
+        factory = (PyObject*)&CursorType;
+    }
+
+    cursor = PyObject_CallFunction(factory, "O", self);
+
+    if (cursor && self->row_factory != Py_None) {
+        Py_XDECREF(((Cursor*)cursor)->row_factory);
+        Py_INCREF(self->row_factory);
+        ((Cursor*)cursor)->row_factory = self->row_factory;
+    }
+
+    return cursor;
+}
+
+PyObject* connection_close(Connection* self, PyObject* args)
+{
+    int rc;
+
+    if (!check_thread(self)) {
+        return NULL;
+    }
+
+    flush_statement_cache(self);
+
+    if (self->db) {
+        Py_BEGIN_ALLOW_THREADS
+        rc = sqlite3_close(self->db);
+        Py_END_ALLOW_THREADS
+
+        if (rc != SQLITE_OK) {
+            _seterror(self->db);
+            return NULL;
+        } else {
+            self->db = NULL;
+        }
+    }
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+/*
+ * Checks if a connection object is usable (i. e. not closed).
+ *
+ * 0 => error; 1 => ok
+ */
+int check_connection(Connection* con)
+{
+    if (!con->db) {
+        PyErr_SetString(ProgrammingError, "Cannot operate on a closed database.");
+        return 0;
+    } else {
+        return 1;
+    }
+}
+
+PyObject* _connection_begin(Connection* self)
+{
+    int rc;
+    const char* tail;
+    sqlite3_stmt* statement;
+
+    Py_BEGIN_ALLOW_THREADS
+    rc = sqlite3_prepare(self->db, self->begin_statement, -1, &statement, &tail);
+    Py_END_ALLOW_THREADS
+
+    if (rc != SQLITE_OK) {
+        _seterror(self->db);
+        goto error;
+    }
+
+    rc = _sqlite_step_with_busyhandler(statement, self);
+    if (rc == SQLITE_DONE) {
+        self->inTransaction = 1;
+    } else {
+        _seterror(self->db);
+    }
+
+    Py_BEGIN_ALLOW_THREADS
+    rc = sqlite3_finalize(statement);
+    Py_END_ALLOW_THREADS
+
+    if (rc != SQLITE_OK && !PyErr_Occurred()) {
+        _seterror(self->db);
+    }
+
+error:
+    if (PyErr_Occurred()) {
+        return NULL;
+    } else {
+        Py_INCREF(Py_None);
+        return Py_None;
+    }
+}
+
+PyObject* connection_commit(Connection* self, PyObject* args)
+{
+    int rc;
+    const char* tail;
+    sqlite3_stmt* statement;
+
+    if (!check_thread(self) || !check_connection(self)) {
+        return NULL;
+    }
+
+    if (self->inTransaction) {
+        Py_BEGIN_ALLOW_THREADS
+        rc = sqlite3_prepare(self->db, "COMMIT", -1, &statement, &tail);
+        Py_END_ALLOW_THREADS
+        if (rc != SQLITE_OK) {
+            _seterror(self->db);
+            goto error;
+        }
+
+        rc = _sqlite_step_with_busyhandler(statement, self);
+        if (rc == SQLITE_DONE) {
+            self->inTransaction = 0;
+        } else {
+            _seterror(self->db);
+        }
+
+        Py_BEGIN_ALLOW_THREADS
+        rc = sqlite3_finalize(statement);
+        Py_END_ALLOW_THREADS
+        if (rc != SQLITE_OK && !PyErr_Occurred()) {
+            _seterror(self->db);
+        }
+
+    }
+
+error:
+    if (PyErr_Occurred()) {
+        return NULL;
+    } else {
+        Py_INCREF(Py_None);
+        return Py_None;
+    }
+}
+
+PyObject* connection_rollback(Connection* self, PyObject* args)
+{
+    int rc;
+    const char* tail;
+    sqlite3_stmt* statement;
+
+    if (!check_thread(self) || !check_connection(self)) {
+        return NULL;
+    }
+
+    if (self->inTransaction) {
+        reset_all_statements(self);
+
+        Py_BEGIN_ALLOW_THREADS
+        rc = sqlite3_prepare(self->db, "ROLLBACK", -1, &statement, &tail);
+        Py_END_ALLOW_THREADS
+        if (rc != SQLITE_OK) {
+            _seterror(self->db);
+            goto error;
+        }
+
+        rc = _sqlite_step_with_busyhandler(statement, self);
+        if (rc == SQLITE_DONE) {
+            self->inTransaction = 0;
+        } else {
+            _seterror(self->db);
+        }
+
+        Py_BEGIN_ALLOW_THREADS
+        rc = sqlite3_finalize(statement);
+        Py_END_ALLOW_THREADS
+        if (rc != SQLITE_OK && !PyErr_Occurred()) {
+            _seterror(self->db);
+        }
+
+    }
+
+error:
+    if (PyErr_Occurred()) {
+        return NULL;
+    } else {
+        Py_INCREF(Py_None);
+        return Py_None;
+    }
+}
+
+void _set_result(sqlite3_context* context, PyObject* py_val)
+{
+    long longval;
+    const char* buffer;
+    Py_ssize_t buflen;
+    PyObject* stringval;
+
+    if ((!py_val) || PyErr_Occurred()) {
+        sqlite3_result_null(context);
+    } else if (py_val == Py_None) {
+        sqlite3_result_null(context);
+    } else if (PyInt_Check(py_val)) {
+        longval = PyInt_AsLong(py_val);
+        sqlite3_result_int64(context, (PY_LONG_LONG)longval);
+    } else if (PyFloat_Check(py_val)) {
+        sqlite3_result_double(context, PyFloat_AsDouble(py_val));
+    } else if (PyBuffer_Check(py_val)) {
+        if (PyObject_AsCharBuffer(py_val, &buffer, &buflen) != 0) {
+            PyErr_SetString(PyExc_ValueError, "could not convert BLOB to buffer");
+        } else {
+            sqlite3_result_blob(context, buffer, buflen, SQLITE_TRANSIENT);
+        }
+    } else if (PyString_Check(py_val)) {
+        sqlite3_result_text(context, PyString_AsString(py_val), -1, SQLITE_TRANSIENT);
+    } else if (PyUnicode_Check(py_val)) {
+        stringval = PyUnicode_AsUTF8String(py_val);
+        if (stringval) {
+            sqlite3_result_text(context, PyString_AsString(stringval), -1, SQLITE_TRANSIENT);
+            Py_DECREF(stringval);
+        }
+    } else {
+        /* TODO: raise error */
+    }
+}
+
+PyObject* _build_py_params(sqlite3_context *context, int argc, sqlite3_value** argv)
+{
+    PyObject* args;
+    int i;
+    sqlite3_value* cur_value;
+    PyObject* cur_py_value;
+    const char* val_str;
+    PY_LONG_LONG val_int;
+    Py_ssize_t buflen;
+    void* raw_buffer;
+
+    args = PyTuple_New(argc);
+    if (!args) {
+        return NULL;
+    }
+
+    for (i = 0; i < argc; i++) {
+        cur_value = argv[i];
+        switch (sqlite3_value_type(argv[i])) {
+            case SQLITE_INTEGER:
+                val_int = sqlite3_value_int64(cur_value);
+                cur_py_value = PyInt_FromLong((long)val_int);
+                break;
+            case SQLITE_FLOAT:
+                cur_py_value = PyFloat_FromDouble(sqlite3_value_double(cur_value));
+                break;
+            case SQLITE_TEXT:
+                val_str = (const char*)sqlite3_value_text(cur_value);
+                cur_py_value = PyUnicode_DecodeUTF8(val_str, strlen(val_str), NULL);
+                /* TODO: have a way to show errors here */
+                if (!cur_py_value) {
+                    PyErr_Clear();
+                    Py_INCREF(Py_None);
+                    cur_py_value = Py_None;
+                }
+                break;
+            case SQLITE_BLOB:
+                buflen = sqlite3_value_bytes(cur_value);
+                cur_py_value = PyBuffer_New(buflen);
+                if (!cur_py_value) {
+                    break;
+                }
+                if (PyObject_AsWriteBuffer(cur_py_value, &raw_buffer, &buflen)) {
+                    Py_DECREF(cur_py_value);
+                    cur_py_value = NULL;
+                    break;
+                }
+                memcpy(raw_buffer, sqlite3_value_blob(cur_value), buflen);
+                break;
+            case SQLITE_NULL:
+            default:
+                Py_INCREF(Py_None);
+                cur_py_value = Py_None;
+        }
+
+        if (!cur_py_value) {
+            Py_DECREF(args);
+            return NULL;
+        }
+
+        PyTuple_SetItem(args, i, cur_py_value);
+
+    }
+
+    return args;
+}
+
+void _func_callback(sqlite3_context* context, int argc, sqlite3_value** argv)
+{
+    PyObject* args;
+    PyObject* py_func;
+    PyObject* py_retval = NULL;
+
+    PyGILState_STATE threadstate;
+
+    threadstate = PyGILState_Ensure();
+
+    py_func = (PyObject*)sqlite3_user_data(context);
+
+    args = _build_py_params(context, argc, argv);
+    if (args) {
+        py_retval = PyObject_CallObject(py_func, args);
+        Py_DECREF(args);
+    }
+
+    if (py_retval) {
+        _set_result(context, py_retval);
+        Py_DECREF(py_retval);
+    } else {
+        if (_enable_callback_tracebacks) {
+            PyErr_Print();
+        } else {
+            PyErr_Clear();
+        }
+        _sqlite3_result_error(context, "user-defined function raised exception", -1);
+    }
+
+    PyGILState_Release(threadstate);
+}
+
+static void _step_callback(sqlite3_context *context, int argc, sqlite3_value** params)
+{
+    PyObject* args;
+    PyObject* function_result = NULL;
+    PyObject* aggregate_class;
+    PyObject** aggregate_instance;
+    PyObject* stepmethod = NULL;
+
+    PyGILState_STATE threadstate;
+
+    threadstate = PyGILState_Ensure();
+
+    aggregate_class = (PyObject*)sqlite3_user_data(context);
+
+    aggregate_instance = (PyObject**)sqlite3_aggregate_context(context, sizeof(PyObject*));
+
+    if (*aggregate_instance == 0) {
+        *aggregate_instance = PyObject_CallFunction(aggregate_class, "");
+
+        if (PyErr_Occurred()) {
+            *aggregate_instance = 0;
+            if (_enable_callback_tracebacks) {
+                PyErr_Print();
+            } else {
+                PyErr_Clear();
+            }
+            _sqlite3_result_error(context, "user-defined aggregate's '__init__' method raised error", -1);
+            goto error;
+        }
+    }
+
+    stepmethod = PyObject_GetAttrString(*aggregate_instance, "step");
+    if (!stepmethod) {
+        goto error;
+    }
+
+    args = _build_py_params(context, argc, params);
+    if (!args) {
+        goto error;
+    }
+
+    function_result = PyObject_CallObject(stepmethod, args);
+    Py_DECREF(args);
+
+    if (!function_result) {
+        if (_enable_callback_tracebacks) {
+            PyErr_Print();
+        } else {
+            PyErr_Clear();
+        }
+        _sqlite3_result_error(context, "user-defined aggregate's 'step' method raised error", -1);
+    }
+
+error:
+    Py_XDECREF(stepmethod);
+    Py_XDECREF(function_result);
+
+    PyGILState_Release(threadstate);
+}
+
+void _final_callback(sqlite3_context* context)
+{
+    PyObject* function_result = NULL;
+    PyObject** aggregate_instance;
+    PyObject* aggregate_class;
+
+    PyGILState_STATE threadstate;
+
+    threadstate = PyGILState_Ensure();
+
+    aggregate_class = (PyObject*)sqlite3_user_data(context);
+
+    aggregate_instance = (PyObject**)sqlite3_aggregate_context(context, sizeof(PyObject*));
+    if (!*aggregate_instance) {
+        /* this branch is executed if there was an exception in the aggregate's
+         * __init__ */
+
+        goto error;
+    }
+
+    function_result = PyObject_CallMethod(*aggregate_instance, "finalize", "");
+    if (!function_result) {
+        if (_enable_callback_tracebacks) {
+            PyErr_Print();
+        } else {
+            PyErr_Clear();
+        }
+        _sqlite3_result_error(context, "user-defined aggregate's 'finalize' method raised error", -1);
+    } else {
+        _set_result(context, function_result);
+    }
+
+error:
+    Py_XDECREF(*aggregate_instance);
+    Py_XDECREF(function_result);
+
+    PyGILState_Release(threadstate);
+}
+
+void _drop_unused_statement_references(Connection* self)
+{
+    PyObject* new_list;
+    PyObject* weakref;
+    int i;
+
+    /* we only need to do this once in a while */
+    if (self->created_statements++ < 200) {
+        return;
+    }
+
+    self->created_statements = 0;
+
+    new_list = PyList_New(0);
+    if (!new_list) {
+        return;
+    }
+
+    for (i = 0; i < PyList_Size(self->statements); i++) {
+        weakref = PyList_GetItem(self->statements, i);
+        if (PyWeakref_GetObject(weakref) != Py_None) {
+            if (PyList_Append(new_list, weakref) != 0) {
+                Py_DECREF(new_list);
+                return;
+            }
+        }
+    }
+
+    Py_DECREF(self->statements);
+    self->statements = new_list;
+}
+
+PyObject* connection_create_function(Connection* self, PyObject* args, PyObject* kwargs)
+{
+    static char *kwlist[] = {"name", "narg", "func", NULL, NULL};
+
+    PyObject* func;
+    char* name;
+    int narg;
+    int rc;
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "siO", kwlist,
+                                     &name, &narg, &func))
+    {
+        return NULL;
+    }
+
+    rc = sqlite3_create_function(self->db, name, narg, SQLITE_UTF8, (void*)func, _func_callback, NULL, NULL);
+
+    if (rc != SQLITE_OK) {
+        /* Workaround for SQLite bug: no error code or string is available here */
+        PyErr_SetString(OperationalError, "Error creating function");
+        return NULL;
+    } else {
+        PyDict_SetItem(self->function_pinboard, func, Py_None);
+
+        Py_INCREF(Py_None);
+        return Py_None;
+    }
+}
+
+PyObject* connection_create_aggregate(Connection* self, PyObject* args, PyObject* kwargs)
+{
+    PyObject* aggregate_class;
+
+    int n_arg;
+    char* name;
+    static char *kwlist[] = { "name", "n_arg", "aggregate_class", NULL };
+    int rc;
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "siO:create_aggregate",
+                                      kwlist, &name, &n_arg, &aggregate_class)) {
+        return NULL;
+    }
+
+    rc = sqlite3_create_function(self->db, name, n_arg, SQLITE_UTF8, (void*)aggregate_class, 0, &_step_callback, &_final_callback);
+    if (rc != SQLITE_OK) {
+        /* Workaround for SQLite bug: no error code or string is available here */
+        PyErr_SetString(OperationalError, "Error creating aggregate");
+        return NULL;
+    } else {
+        PyDict_SetItem(self->function_pinboard, aggregate_class, Py_None);
+
+        Py_INCREF(Py_None);
+        return Py_None;
+    }
+}
+
+int _authorizer_callback(void* user_arg, int action, const char* arg1, const char* arg2 , const char* dbname, const char* access_attempt_source)
+{
+    PyObject *ret;
+    int rc;
+    PyGILState_STATE gilstate;
+
+    gilstate = PyGILState_Ensure();
+    ret = PyObject_CallFunction((PyObject*)user_arg, "issss", action, arg1, arg2, dbname, access_attempt_source);
+
+    if (!ret) {
+        if (_enable_callback_tracebacks) {
+            PyErr_Print();
+        } else {
+            PyErr_Clear();
+        }
+
+        rc = SQLITE_DENY;
+    } else {
+        if (PyInt_Check(ret)) {
+            rc = (int)PyInt_AsLong(ret);
+        } else {
+            rc = SQLITE_DENY;
+        }
+        Py_DECREF(ret);
+    }
+
+    PyGILState_Release(gilstate);
+    return rc;
+}
+
+PyObject* connection_set_authorizer(Connection* self, PyObject* args, PyObject* kwargs)
+{
+    PyObject* authorizer_cb;
+
+    static char *kwlist[] = { "authorizer_callback", NULL };
+    int rc;
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:set_authorizer",
+                                      kwlist, &authorizer_cb)) {
+        return NULL;
+    }
+
+    rc = sqlite3_set_authorizer(self->db, _authorizer_callback, (void*)authorizer_cb);
+
+    if (rc != SQLITE_OK) {
+        PyErr_SetString(OperationalError, "Error setting authorizer callback");
+        return NULL;
+    } else {
+        PyDict_SetItem(self->function_pinboard, authorizer_cb, Py_None);
+
+        Py_INCREF(Py_None);
+        return Py_None;
+    }
+}
+
+int check_thread(Connection* self)
+{
+    if (self->check_same_thread) {
+        if (PyThread_get_thread_ident() != self->thread_ident) {
+            PyErr_Format(ProgrammingError,
+                        "SQLite objects created in a thread can only be used in that same thread."
+                        "The object was created in thread id %ld and this is thread id %ld",
+                        self->thread_ident, PyThread_get_thread_ident());
+            return 0;
+        }
+
+    }
+
+    return 1;
+}
+
+static PyObject* connection_get_isolation_level(Connection* self, void* unused)
+{
+    Py_INCREF(self->isolation_level);
+    return self->isolation_level;
+}
+
+static PyObject* connection_get_total_changes(Connection* self, void* unused)
+{
+    if (!check_connection(self)) {
+        return NULL;
+    } else {
+        return Py_BuildValue("i", sqlite3_total_changes(self->db));
+    }
+}
+
+static int connection_set_isolation_level(Connection* self, PyObject* isolation_level)
+{
+    PyObject* res;
+    PyObject* begin_statement;
+
+    Py_XDECREF(self->isolation_level);
+
+    if (self->begin_statement) {
+        PyMem_Free(self->begin_statement);
+        self->begin_statement = NULL;
+    }
+
+    if (isolation_level == Py_None) {
+        Py_INCREF(Py_None);
+        self->isolation_level = Py_None;
+
+        res = connection_commit(self, NULL);
+        if (!res) {
+            return -1;
+        }
+        Py_DECREF(res);
+
+        self->inTransaction = 0;
+    } else {
+        Py_INCREF(isolation_level);
+        self->isolation_level = isolation_level;
+
+        begin_statement = PyString_FromString("BEGIN ");
+        if (!begin_statement) {
+            return -1;
+        }
+        PyString_Concat(&begin_statement, isolation_level);
+        if (!begin_statement) {
+            return -1;
+        }
+
+        self->begin_statement = PyMem_Malloc(PyString_Size(begin_statement) + 2);
+        if (!self->begin_statement) {
+            return -1;
+        }
+
+        strcpy(self->begin_statement, PyString_AsString(begin_statement));
+        Py_DECREF(begin_statement);
+    }
+
+    return 0;
+}
+
+PyObject* connection_call(Connection* self, PyObject* args, PyObject* kwargs)
+{
+    PyObject* sql;
+    Statement* statement;
+    PyObject* weakref;
+    int rc;
+
+    if (!PyArg_ParseTuple(args, "O", &sql)) {
+        return NULL;
+    }
+
+    _drop_unused_statement_references(self);
+
+    statement = PyObject_New(Statement, &StatementType);
+    if (!statement) {
+        return NULL;
+    }
+
+    rc = statement_create(statement, self, sql);
+
+    if (rc != SQLITE_OK) {
+        if (rc == PYSQLITE_TOO_MUCH_SQL) {
+            PyErr_SetString(Warning, "You can only execute one statement at a time.");
+        } else if (rc == PYSQLITE_SQL_WRONG_TYPE) {
+            PyErr_SetString(Warning, "SQL is of wrong type. Must be string or unicode.");
+        } else {
+            _seterror(self->db);
+        }
+
+        Py_DECREF(statement);
+        statement = 0;
+    } else {
+        weakref = PyWeakref_NewRef((PyObject*)statement, NULL);
+        if (!weakref) {
+            Py_DECREF(statement);
+            statement = 0;
+            goto error;
+        }
+
+        if (PyList_Append(self->statements, weakref) != 0) {
+            Py_DECREF(weakref);
+            statement = 0;
+            goto error;
+        }
+
+        Py_DECREF(weakref);
+    }
+
+error:
+    return (PyObject*)statement;
+}
+
+PyObject* connection_execute(Connection* self, PyObject* args, PyObject* kwargs)
+{
+    PyObject* cursor = 0;
+    PyObject* result = 0;
+    PyObject* method = 0;
+
+    cursor = PyObject_CallMethod((PyObject*)self, "cursor", "");
+    if (!cursor) {
+        goto error;
+    }
+
+    method = PyObject_GetAttrString(cursor, "execute");
+    if (!method) {
+        Py_DECREF(cursor);
+        cursor = 0;
+        goto error;
+    }
+
+    result = PyObject_CallObject(method, args);
+    if (!result) {
+        Py_DECREF(cursor);
+        cursor = 0;
+    }
+
+error:
+    Py_XDECREF(result);
+    Py_XDECREF(method);
+
+    return cursor;
+}
+
+PyObject* connection_executemany(Connection* self, PyObject* args, PyObject* kwargs)
+{
+    PyObject* cursor = 0;
+    PyObject* result = 0;
+    PyObject* method = 0;
+
+    cursor = PyObject_CallMethod((PyObject*)self, "cursor", "");
+    if (!cursor) {
+        goto error;
+    }
+
+    method = PyObject_GetAttrString(cursor, "executemany");
+    if (!method) {
+        Py_DECREF(cursor);
+        cursor = 0;
+        goto error;
+    }
+
+    result = PyObject_CallObject(method, args);
+    if (!result) {
+        Py_DECREF(cursor);
+        cursor = 0;
+    }
+
+error:
+    Py_XDECREF(result);
+    Py_XDECREF(method);
+
+    return cursor;
+}
+
+PyObject* connection_executescript(Connection* self, PyObject* args, PyObject* kwargs)
+{
+    PyObject* cursor = 0;
+    PyObject* result = 0;
+    PyObject* method = 0;
+
+    cursor = PyObject_CallMethod((PyObject*)self, "cursor", "");
+    if (!cursor) {
+        goto error;
+    }
+
+    method = PyObject_GetAttrString(cursor, "executescript");
+    if (!method) {
+        Py_DECREF(cursor);
+        cursor = 0;
+        goto error;
+    }
+
+    result = PyObject_CallObject(method, args);
+    if (!result) {
+        Py_DECREF(cursor);
+        cursor = 0;
+    }
+
+error:
+    Py_XDECREF(result);
+    Py_XDECREF(method);
+
+    return cursor;
+}
+
+/* ------------------------- COLLATION CODE ------------------------ */
+
+static int
+collation_callback(
+        void* context,
+        int text1_length, const void* text1_data,
+        int text2_length, const void* text2_data)
+{
+    PyObject* callback = (PyObject*)context;
+    PyObject* string1 = 0;
+    PyObject* string2 = 0;
+    PyGILState_STATE gilstate;
+
+    PyObject* retval = NULL;
+    int result = 0;
+
+    gilstate = PyGILState_Ensure();
+
+    if (PyErr_Occurred()) {
+        goto finally;
+    }
+
+    string1 = PyString_FromStringAndSize((const char*)text1_data, text1_length);
+    string2 = PyString_FromStringAndSize((const char*)text2_data, text2_length);
+
+    if (!string1 || !string2) {
+        goto finally; /* failed to allocate strings */
+    }
+
+    retval = PyObject_CallFunctionObjArgs(callback, string1, string2, NULL);
+
+    if (!retval) {
+        /* execution failed */
+        goto finally;
+    }
+
+    result = PyInt_AsLong(retval);
+    if (PyErr_Occurred()) {
+        result = 0;
+    }
+
+finally:
+    Py_XDECREF(string1);
+    Py_XDECREF(string2);
+    Py_XDECREF(retval);
+
+    PyGILState_Release(gilstate);
+
+    return result;
+}
+
+static PyObject *
+connection_interrupt(Connection* self, PyObject* args)
+{
+    PyObject* retval = NULL;
+
+    if (!check_connection(self)) {
+        goto finally;
+    }
+
+    sqlite3_interrupt(self->db);
+
+    Py_INCREF(Py_None);
+    retval = Py_None;
+
+finally:
+    return retval;
+}
+
+static PyObject *
+connection_create_collation(Connection* self, PyObject* args)
+{
+    PyObject* callable;
+    PyObject* uppercase_name = 0;
+    PyObject* name;
+    PyObject* retval;
+    char* chk;
+    int rc;
+
+    if (!check_thread(self) || !check_connection(self)) {
+        goto finally;
+    }
+
+    if (!PyArg_ParseTuple(args, "O!O:create_collation(name, callback)", &PyString_Type, &name, &callable)) {
+        goto finally;
+    }
+
+    uppercase_name = PyObject_CallMethod(name, "upper", "");
+    if (!uppercase_name) {
+        goto finally;
+    }
+
+    chk = PyString_AsString(uppercase_name);
+    while (*chk) {
+        if ((*chk >= '0' && *chk <= '9')
+         || (*chk >= 'A' && *chk <= 'Z')
+         || (*chk == '_'))
+        {
+            chk++;
+        } else {
+            PyErr_SetString(ProgrammingError, "invalid character in collation name");
+            goto finally;
+        }
+    }
+
+    if (callable != Py_None && !PyCallable_Check(callable)) {
+        PyErr_SetString(PyExc_TypeError, "parameter must be callable");
+        goto finally;
+    }
+
+    if (callable != Py_None) {
+        PyDict_SetItem(self->collations, uppercase_name, callable);
+    } else {
+        PyDict_DelItem(self->collations, uppercase_name);
+    }
+
+    rc = sqlite3_create_collation(self->db,
+                                  PyString_AsString(uppercase_name),
+                                  SQLITE_UTF8,
+                                  (callable != Py_None) ? callable : NULL,
+                                  (callable != Py_None) ? collation_callback : NULL);
+    if (rc != SQLITE_OK) {
+        PyDict_DelItem(self->collations, uppercase_name);
+        _seterror(self->db);
+        goto finally;
+    }
+
+finally:
+    Py_XDECREF(uppercase_name);
+
+    if (PyErr_Occurred()) {
+        retval = NULL;
+    } else {
+        Py_INCREF(Py_None);
+        retval = Py_None;
+    }
+
+    return retval;
+}
+
+static char connection_doc[] =
+PyDoc_STR("SQLite database connection object.");
+
+static PyGetSetDef connection_getset[] = {
+    {"isolation_level",  (getter)connection_get_isolation_level, (setter)connection_set_isolation_level},
+    {"total_changes",  (getter)connection_get_total_changes, (setter)0},
+    {NULL}
+};
+
+static PyMethodDef connection_methods[] = {
+    {"cursor", (PyCFunction)connection_cursor, METH_VARARGS|METH_KEYWORDS,
+        PyDoc_STR("Return a cursor for the connection.")},
+    {"close", (PyCFunction)connection_close, METH_NOARGS,
+        PyDoc_STR("Closes the connection.")},
+    {"commit", (PyCFunction)connection_commit, METH_NOARGS,
+        PyDoc_STR("Commit the current transaction.")},
+    {"rollback", (PyCFunction)connection_rollback, METH_NOARGS,
+        PyDoc_STR("Roll back the current transaction.")},
+    {"create_function", (PyCFunction)connection_create_function, METH_VARARGS|METH_KEYWORDS,
+        PyDoc_STR("Creates a new function. Non-standard.")},
+    {"create_aggregate", (PyCFunction)connection_create_aggregate, METH_VARARGS|METH_KEYWORDS,
+        PyDoc_STR("Creates a new aggregate. Non-standard.")},
+    {"set_authorizer", (PyCFunction)connection_set_authorizer, METH_VARARGS|METH_KEYWORDS,
+        PyDoc_STR("Sets authorizer callback. Non-standard.")},
+    {"execute", (PyCFunction)connection_execute, METH_VARARGS,
+        PyDoc_STR("Executes a SQL statement. Non-standard.")},
+    {"executemany", (PyCFunction)connection_executemany, METH_VARARGS,
+        PyDoc_STR("Repeatedly executes a SQL statement. Non-standard.")},
+    {"executescript", (PyCFunction)connection_executescript, METH_VARARGS,
+        PyDoc_STR("Executes a multiple SQL statements at once. Non-standard.")},
+    {"create_collation", (PyCFunction)connection_create_collation, METH_VARARGS,
+        PyDoc_STR("Creates a collation function. Non-standard.")},
+    {"interrupt", (PyCFunction)connection_interrupt, METH_NOARGS,
+        PyDoc_STR("Abort any pending database operation. Non-standard.")},
+    {NULL, NULL}
+};
+
+static struct PyMemberDef connection_members[] =
+{
+    {"Warning", T_OBJECT, offsetof(Connection, Warning), RO},
+    {"Error", T_OBJECT, offsetof(Connection, Error), RO},
+    {"InterfaceError", T_OBJECT, offsetof(Connection, InterfaceError), RO},
+    {"DatabaseError", T_OBJECT, offsetof(Connection, DatabaseError), RO},
+    {"DataError", T_OBJECT, offsetof(Connection, DataError), RO},
+    {"OperationalError", T_OBJECT, offsetof(Connection, OperationalError), RO},
+    {"IntegrityError", T_OBJECT, offsetof(Connection, IntegrityError), RO},
+    {"InternalError", T_OBJECT, offsetof(Connection, InternalError), RO},
+    {"ProgrammingError", T_OBJECT, offsetof(Connection, ProgrammingError), RO},
+    {"NotSupportedError", T_OBJECT, offsetof(Connection, NotSupportedError), RO},
+    {"row_factory", T_OBJECT, offsetof(Connection, row_factory)},
+    {"text_factory", T_OBJECT, offsetof(Connection, text_factory)},
+    {NULL}
+};
+
+PyTypeObject ConnectionType = {
+        PyObject_HEAD_INIT(NULL)
+        0,                                              /* ob_size */
+        MODULE_NAME ".Connection",                      /* tp_name */
+        sizeof(Connection),                             /* tp_basicsize */
+        0,                                              /* tp_itemsize */
+        (destructor)connection_dealloc,                 /* tp_dealloc */
+        0,                                              /* tp_print */
+        0,                                              /* tp_getattr */
+        0,                                              /* tp_setattr */
+        0,                                              /* tp_compare */
+        0,                                              /* tp_repr */
+        0,                                              /* tp_as_number */
+        0,                                              /* tp_as_sequence */
+        0,                                              /* tp_as_mapping */
+        0,                                              /* tp_hash */
+        (ternaryfunc)connection_call,                   /* tp_call */
+        0,                                              /* tp_str */
+        0,                                              /* tp_getattro */
+        0,                                              /* tp_setattro */
+        0,                                              /* tp_as_buffer */
+        Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,         /* tp_flags */
+        connection_doc,                                 /* tp_doc */
+        0,                                              /* tp_traverse */
+        0,                                              /* tp_clear */
+        0,                                              /* tp_richcompare */
+        0,                                              /* tp_weaklistoffset */
+        0,                                              /* tp_iter */
+        0,                                              /* tp_iternext */
+        connection_methods,                             /* tp_methods */
+        connection_members,                             /* tp_members */
+        connection_getset,                              /* tp_getset */
+        0,                                              /* tp_base */
+        0,                                              /* tp_dict */
+        0,                                              /* tp_descr_get */
+        0,                                              /* tp_descr_set */
+        0,                                              /* tp_dictoffset */
+        (initproc)connection_init,                      /* tp_init */
+        0,                                              /* tp_alloc */
+        0,                                              /* tp_new */
+        0                                               /* tp_free */
+};
+
+extern int connection_setup_types(void)
+{
+    ConnectionType.tp_new = PyType_GenericNew;
+    return PyType_Ready(&ConnectionType);
+}

Added: vendor/Python/current/Modules/_sqlite/connection.h
===================================================================
--- vendor/Python/current/Modules/_sqlite/connection.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_sqlite/connection.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,129 @@
+/* connection.h - definitions for the connection type
+ *
+ * Copyright (C) 2004-2006 Gerhard Häring <gh at ghaering.de>
+ *
+ * This file is part of pysqlite.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#ifndef PYSQLITE_CONNECTION_H
+#define PYSQLITE_CONNECTION_H
+#include "Python.h"
+#include "pythread.h"
+#include "structmember.h"
+
+#include "cache.h"
+#include "module.h"
+
+#include "sqlite3.h"
+
+typedef struct
+{
+    PyObject_HEAD
+    sqlite3* db;
+
+    /* 1 if we are currently within a transaction, i. e. if a BEGIN has been
+     * issued */
+    int inTransaction;
+
+    /* the type detection mode. Only 0, PARSE_DECLTYPES, PARSE_COLNAMES or a
+     * bitwise combination thereof makes sense */
+    int detect_types;
+
+    /* the timeout value in seconds for database locks */
+    double timeout;
+
+    /* for internal use in the timeout handler: when did the timeout handler
+     * first get called with count=0? */
+    double timeout_started;
+
+    /* None for autocommit, otherwise a PyString with the isolation level */
+    PyObject* isolation_level;
+
+    /* NULL for autocommit, otherwise a string with the BEGIN statment; will be
+     * freed in connection destructor */
+    char* begin_statement;
+
+    /* 1 if a check should be performed for each API call if the connection is
+     * used from the same thread it was created in */
+    int check_same_thread;
+
+    /* thread identification of the thread the connection was created in */
+    long thread_ident;
+
+    Cache* statement_cache;
+
+    /* A list of weak references to statements used within this connection */
+    PyObject* statements;
+
+    /* a counter for how many statements were created in the connection. May be
+     * reset to 0 at certain intervals */
+    int created_statements;
+
+    PyObject* row_factory;
+
+    /* Determines how bytestrings from SQLite are converted to Python objects:
+     * - PyUnicode_Type:        Python Unicode objects are constructed from UTF-8 bytestrings
+     * - OptimizedUnicode:      Like before, but for ASCII data, only PyStrings are created.
+     * - PyString_Type:         PyStrings are created as-is.
+     * - Any custom callable:   Any object returned from the callable called with the bytestring
+     *                          as single parameter.
+     */
+    PyObject* text_factory;
+
+    /* remember references to functions/classes used in
+     * create_function/create/aggregate, use these as dictionary keys, so we
+     * can keep the total system refcount constant by clearing that dictionary
+     * in connection_dealloc */
+    PyObject* function_pinboard;
+
+    /* a dictionary of registered collation name => collation callable mappings */
+    PyObject* collations;
+
+    /* Exception objects */
+    PyObject* Warning;
+    PyObject* Error;
+    PyObject* InterfaceError;
+    PyObject* DatabaseError;
+    PyObject* DataError;
+    PyObject* OperationalError;
+    PyObject* IntegrityError;
+    PyObject* InternalError;
+    PyObject* ProgrammingError;
+    PyObject* NotSupportedError;
+} Connection;
+
+extern PyTypeObject ConnectionType;
+
+PyObject* connection_alloc(PyTypeObject* type, int aware);
+void connection_dealloc(Connection* self);
+PyObject* connection_cursor(Connection* self, PyObject* args, PyObject* kwargs);
+PyObject* connection_close(Connection* self, PyObject* args);
+PyObject* _connection_begin(Connection* self);
+PyObject* connection_begin(Connection* self, PyObject* args);
+PyObject* connection_commit(Connection* self, PyObject* args);
+PyObject* connection_rollback(Connection* self, PyObject* args);
+PyObject* connection_new(PyTypeObject* type, PyObject* args, PyObject* kw);
+int connection_init(Connection* self, PyObject* args, PyObject* kwargs);
+
+int check_thread(Connection* self);
+int check_connection(Connection* con);
+
+int connection_setup_types(void);
+
+#endif

Added: vendor/Python/current/Modules/_sqlite/cursor.c
===================================================================
--- vendor/Python/current/Modules/_sqlite/cursor.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_sqlite/cursor.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1057 @@
+/* cursor.c - the cursor type
+ *
+ * Copyright (C) 2004-2006 Gerhard Häring <gh at ghaering.de>
+ *
+ * This file is part of pysqlite.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#include "cursor.h"
+#include "module.h"
+#include "util.h"
+#include "sqlitecompat.h"
+
+/* used to decide wether to call PyInt_FromLong or PyLong_FromLongLong */
+#ifndef INT32_MIN
+#define INT32_MIN (-2147483647 - 1)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX 2147483647
+#endif
+
+PyObject* cursor_iternext(Cursor *self);
+
+static StatementKind detect_statement_type(char* statement)
+{
+    char buf[20];
+    char* src;
+    char* dst;
+
+    src = statement;
+    /* skip over whitepace */
+    while (*src == '\r' || *src == '\n' || *src == ' ' || *src == '\t') {
+        src++;
+    }
+
+    if (*src == 0)
+        return STATEMENT_INVALID;
+
+    dst = buf;
+    *dst = 0;
+    while (isalpha(*src) && dst - buf < sizeof(buf) - 2) {
+        *dst++ = tolower(*src++);
+    }
+
+    *dst = 0;
+
+    if (!strcmp(buf, "select")) {
+        return STATEMENT_SELECT;
+    } else if (!strcmp(buf, "insert")) {
+        return STATEMENT_INSERT;
+    } else if (!strcmp(buf, "update")) {
+        return STATEMENT_UPDATE;
+    } else if (!strcmp(buf, "delete")) {
+        return STATEMENT_DELETE;
+    } else if (!strcmp(buf, "replace")) {
+        return STATEMENT_REPLACE;
+    } else {
+        return STATEMENT_OTHER;
+    }
+}
+
+int cursor_init(Cursor* self, PyObject* args, PyObject* kwargs)
+{
+    Connection* connection;
+
+    if (!PyArg_ParseTuple(args, "O!", &ConnectionType, &connection))
+    {
+        return -1; 
+    }
+
+    Py_INCREF(connection);
+    self->connection = connection;
+    self->statement = NULL;
+    self->next_row = NULL;
+
+    self->row_cast_map = PyList_New(0);
+    if (!self->row_cast_map) {
+        return -1;
+    }
+
+    Py_INCREF(Py_None);
+    self->description = Py_None;
+
+    Py_INCREF(Py_None);
+    self->lastrowid= Py_None;
+
+    self->arraysize = 1;
+
+    self->rowcount = PyInt_FromLong(-1L);
+    if (!self->rowcount) {
+        return -1;
+    }
+
+    Py_INCREF(Py_None);
+    self->row_factory = Py_None;
+
+    if (!check_thread(self->connection)) {
+        return -1;
+    }
+
+    return 0;
+}
+
+void cursor_dealloc(Cursor* self)
+{
+    int rc;
+
+    /* Reset the statement if the user has not closed the cursor */
+    if (self->statement) {
+        rc = statement_reset(self->statement);
+        Py_DECREF(self->statement);
+    }
+
+    Py_XDECREF(self->connection);
+    Py_XDECREF(self->row_cast_map);
+    Py_XDECREF(self->description);
+    Py_XDECREF(self->lastrowid);
+    Py_XDECREF(self->rowcount);
+    Py_XDECREF(self->row_factory);
+    Py_XDECREF(self->next_row);
+
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+PyObject* _get_converter(PyObject* key)
+{
+    PyObject* upcase_key;
+    PyObject* retval;
+
+    upcase_key = PyObject_CallMethod(key, "upper", "");
+    if (!upcase_key) {
+        return NULL;
+    }
+
+    retval = PyDict_GetItem(converters, upcase_key);
+    Py_DECREF(upcase_key);
+
+    return retval;
+}
+
+int build_row_cast_map(Cursor* self)
+{
+    int i;
+    const char* type_start = (const char*)-1;
+    const char* pos;
+
+    const char* colname;
+    const char* decltype;
+    PyObject* py_decltype;
+    PyObject* converter;
+    PyObject* key;
+
+    if (!self->connection->detect_types) {
+        return 0;
+    }
+
+    Py_XDECREF(self->row_cast_map);
+    self->row_cast_map = PyList_New(0);
+
+    for (i = 0; i < sqlite3_column_count(self->statement->st); i++) {
+        converter = NULL;
+
+        if (self->connection->detect_types | PARSE_COLNAMES) {
+            colname = sqlite3_column_name(self->statement->st, i);
+            if (colname) {
+                for (pos = colname; *pos != 0; pos++) {
+                    if (*pos == '[') {
+                        type_start = pos + 1;
+                    } else if (*pos == ']' && type_start != (const char*)-1) {
+                        key = PyString_FromStringAndSize(type_start, pos - type_start);
+                        if (!key) {
+                            /* creating a string failed, but it is too complicated
+                             * to propagate the error here, we just assume there is
+                             * no converter and proceed */
+                            break;
+                        }
+
+                        converter = _get_converter(key);
+                        Py_DECREF(key);
+                        break;
+                    }
+                }
+            }
+        }
+
+        if (!converter && self->connection->detect_types | PARSE_DECLTYPES) {
+            decltype = sqlite3_column_decltype(self->statement->st, i);
+            if (decltype) {
+                for (pos = decltype;;pos++) {
+                    if (*pos == ' ' || *pos == 0) {
+                        py_decltype = PyString_FromStringAndSize(decltype, pos - decltype);
+                        if (!py_decltype) {
+                            return -1;
+                        }
+                        break;
+                    }
+                }
+
+                converter = _get_converter(py_decltype);
+                Py_DECREF(py_decltype);
+            }
+        }
+
+        if (!converter) {
+            converter = Py_None;
+        }
+
+        if (PyList_Append(self->row_cast_map, converter) != 0) {
+            if (converter != Py_None) {
+                Py_DECREF(converter);
+            }
+            Py_XDECREF(self->row_cast_map);
+            self->row_cast_map = NULL;
+
+            return -1;
+        }
+    }
+
+    return 0;
+}
+
+PyObject* _build_column_name(const char* colname)
+{
+    const char* pos;
+
+    if (!colname) {
+        Py_INCREF(Py_None);
+        return Py_None;
+    }
+
+    for (pos = colname;; pos++) {
+        if (*pos == 0 || *pos == '[') {
+            if ((*pos == '[') && (pos > colname) && (*(pos-1) == ' ')) {
+                pos--;
+            }
+            return PyString_FromStringAndSize(colname, pos - colname);
+        }
+    }
+}
+
+PyObject* unicode_from_string(const char* val_str, int optimize)
+{
+    const char* check;
+    int is_ascii = 0;
+
+    if (optimize) {
+        is_ascii = 1;
+
+        check = val_str;
+        while (*check) {
+            if (*check & 0x80) {
+                is_ascii = 0;
+                break;
+            }
+
+            check++;
+        }
+    }
+
+    if (is_ascii) {
+        return PyString_FromString(val_str);
+    } else {
+        return PyUnicode_DecodeUTF8(val_str, strlen(val_str), NULL);
+    }
+}
+
+/*
+ * Returns a row from the currently active SQLite statement
+ *
+ * Precondidition:
+ * - sqlite3_step() has been called before and it returned SQLITE_ROW.
+ */
+PyObject* _fetch_one_row(Cursor* self)
+{
+    int i, numcols;
+    PyObject* row;
+    PyObject* item = NULL;
+    int coltype;
+    PY_LONG_LONG intval;
+    PyObject* converter;
+    PyObject* converted;
+    Py_ssize_t nbytes;
+    PyObject* buffer;
+    void* raw_buffer;
+    const char* val_str;
+    char buf[200];
+    const char* colname;
+
+    Py_BEGIN_ALLOW_THREADS
+    numcols = sqlite3_data_count(self->statement->st);
+    Py_END_ALLOW_THREADS
+
+    row = PyTuple_New(numcols);
+    if (!row) {
+        return NULL;
+    }
+
+    for (i = 0; i < numcols; i++) {
+        if (self->connection->detect_types) {
+            converter = PyList_GetItem(self->row_cast_map, i);
+            if (!converter) {
+                converter = Py_None;
+            }
+        } else {
+            converter = Py_None;
+        }
+
+        if (converter != Py_None) {
+            nbytes = sqlite3_column_bytes(self->statement->st, i);
+            val_str = (const char*)sqlite3_column_blob(self->statement->st, i);
+            if (!val_str) {
+                Py_INCREF(Py_None);
+                converted = Py_None;
+            } else {
+                item = PyString_FromStringAndSize(val_str, nbytes);
+                if (!item) {
+                    return NULL;
+                }
+                converted = PyObject_CallFunction(converter, "O", item);
+                Py_DECREF(item);
+                if (!converted) {
+                    break;
+                }
+            }
+        } else {
+            Py_BEGIN_ALLOW_THREADS
+            coltype = sqlite3_column_type(self->statement->st, i);
+            Py_END_ALLOW_THREADS
+            if (coltype == SQLITE_NULL) {
+                Py_INCREF(Py_None);
+                converted = Py_None;
+            } else if (coltype == SQLITE_INTEGER) {
+                intval = sqlite3_column_int64(self->statement->st, i);
+                if (intval < INT32_MIN || intval > INT32_MAX) {
+                    converted = PyLong_FromLongLong(intval);
+                } else {
+                    converted = PyInt_FromLong((long)intval);
+                }
+            } else if (coltype == SQLITE_FLOAT) {
+                converted = PyFloat_FromDouble(sqlite3_column_double(self->statement->st, i));
+            } else if (coltype == SQLITE_TEXT) {
+                val_str = (const char*)sqlite3_column_text(self->statement->st, i);
+                if ((self->connection->text_factory == (PyObject*)&PyUnicode_Type)
+                    || (self->connection->text_factory == OptimizedUnicode)) {
+
+                    converted = unicode_from_string(val_str,
+                        self->connection->text_factory == OptimizedUnicode ? 1 : 0);
+
+                    if (!converted) {
+                        colname = sqlite3_column_name(self->statement->st, i);
+                        if (!colname) {
+                            colname = "<unknown column name>";
+                        }
+                        PyOS_snprintf(buf, sizeof(buf) - 1, "Could not decode to UTF-8 column '%s' with text '%s'",
+                                     colname , val_str);
+                        PyErr_SetString(OperationalError, buf);
+                    }
+                } else if (self->connection->text_factory == (PyObject*)&PyString_Type) {
+                    converted = PyString_FromString(val_str);
+                } else {
+                    converted = PyObject_CallFunction(self->connection->text_factory, "s", val_str);
+                }
+            } else {
+                /* coltype == SQLITE_BLOB */
+                nbytes = sqlite3_column_bytes(self->statement->st, i);
+                buffer = PyBuffer_New(nbytes);
+                if (!buffer) {
+                    break;
+                }
+                if (PyObject_AsWriteBuffer(buffer, &raw_buffer, &nbytes)) {
+                    break;
+                }
+                memcpy(raw_buffer, sqlite3_column_blob(self->statement->st, i), nbytes);
+                converted = buffer;
+            }
+        }
+
+        if (converted) {
+            PyTuple_SetItem(row, i, converted);
+        } else {
+            Py_INCREF(Py_None);
+            PyTuple_SetItem(row, i, Py_None);
+        }
+    }
+
+    if (PyErr_Occurred()) {
+        Py_DECREF(row);
+        row = NULL;
+    }
+
+    return row;
+}
+
+PyObject* _query_execute(Cursor* self, int multiple, PyObject* args)
+{
+    PyObject* operation;
+    PyObject* operation_bytestr = NULL;
+    char* operation_cstr;
+    PyObject* parameters_list = NULL;
+    PyObject* parameters_iter = NULL;
+    PyObject* parameters = NULL;
+    int i;
+    int rc;
+    PyObject* func_args;
+    PyObject* result;
+    int numcols;
+    PY_LONG_LONG lastrowid;
+    int statement_type;
+    PyObject* descriptor;
+    PyObject* second_argument = NULL;
+    long rowcount = 0;
+
+    if (!check_thread(self->connection) || !check_connection(self->connection)) {
+        return NULL;
+    }
+
+    Py_XDECREF(self->next_row);
+    self->next_row = NULL;
+
+    if (multiple) {
+        /* executemany() */
+        if (!PyArg_ParseTuple(args, "OO", &operation, &second_argument)) {
+            return NULL; 
+        }
+
+        if (!PyString_Check(operation) && !PyUnicode_Check(operation)) {
+            PyErr_SetString(PyExc_ValueError, "operation parameter must be str or unicode");
+            return NULL;
+        }
+
+        if (PyIter_Check(second_argument)) {
+            /* iterator */
+            Py_INCREF(second_argument);
+            parameters_iter = second_argument;
+        } else {
+            /* sequence */
+            parameters_iter = PyObject_GetIter(second_argument);
+            if (!parameters_iter) {
+                return NULL;
+            }
+        }
+    } else {
+        /* execute() */
+        if (!PyArg_ParseTuple(args, "O|O", &operation, &second_argument)) {
+            return NULL; 
+        }
+
+        if (!PyString_Check(operation) && !PyUnicode_Check(operation)) {
+            PyErr_SetString(PyExc_ValueError, "operation parameter must be str or unicode");
+            return NULL;
+        }
+
+        parameters_list = PyList_New(0);
+        if (!parameters_list) {
+            return NULL;
+        }
+
+        if (second_argument == NULL) {
+            second_argument = PyTuple_New(0);
+            if (!second_argument) {
+                goto error;
+            }
+        } else {
+            Py_INCREF(second_argument);
+        }
+        if (PyList_Append(parameters_list, second_argument) != 0) {
+            Py_DECREF(second_argument);
+            goto error;
+        }
+        Py_DECREF(second_argument);
+
+        parameters_iter = PyObject_GetIter(parameters_list);
+        if (!parameters_iter) {
+            goto error;
+        }
+    }
+
+    if (self->statement != NULL) {
+        /* There is an active statement */
+        rc = statement_reset(self->statement);
+    }
+
+    if (PyString_Check(operation)) {
+        operation_cstr = PyString_AsString(operation);
+    } else {
+        operation_bytestr = PyUnicode_AsUTF8String(operation);
+        if (!operation_bytestr) {
+            goto error;
+        }
+
+        operation_cstr = PyString_AsString(operation_bytestr);
+    }
+
+    /* reset description and rowcount */
+    Py_DECREF(self->description);
+    Py_INCREF(Py_None);
+    self->description = Py_None;
+
+    Py_DECREF(self->rowcount);
+    self->rowcount = PyInt_FromLong(-1L);
+    if (!self->rowcount) {
+        goto error;
+    }
+
+    statement_type = detect_statement_type(operation_cstr);
+    if (self->connection->begin_statement) {
+        switch (statement_type) {
+            case STATEMENT_UPDATE:
+            case STATEMENT_DELETE:
+            case STATEMENT_INSERT:
+            case STATEMENT_REPLACE:
+                if (!self->connection->inTransaction) {
+                    result = _connection_begin(self->connection);
+                    if (!result) {
+                        goto error;
+                    }
+                    Py_DECREF(result);
+                }
+                break;
+            case STATEMENT_OTHER:
+                /* it's a DDL statement or something similar
+                   - we better COMMIT first so it works for all cases */
+                if (self->connection->inTransaction) {
+                    result = connection_commit(self->connection, NULL);
+                    if (!result) {
+                        goto error;
+                    }
+                    Py_DECREF(result);
+                }
+                break;
+            case STATEMENT_SELECT:
+                if (multiple) {
+                    PyErr_SetString(ProgrammingError,
+                                "You cannot execute SELECT statements in executemany().");
+                    goto error;
+                }
+                break;
+        }
+    }
+
+    func_args = PyTuple_New(1);
+    if (!func_args) {
+        goto error;
+    }
+    Py_INCREF(operation);
+    if (PyTuple_SetItem(func_args, 0, operation) != 0) {
+        goto error;
+    }
+
+    if (self->statement) {
+        (void)statement_reset(self->statement);
+        Py_DECREF(self->statement);
+    }
+
+    self->statement = (Statement*)cache_get(self->connection->statement_cache, func_args);
+    Py_DECREF(func_args);
+
+    if (!self->statement) {
+        goto error;
+    }
+
+    if (self->statement->in_use) {
+        Py_DECREF(self->statement);
+        self->statement = PyObject_New(Statement, &StatementType);
+        if (!self->statement) {
+            goto error;
+        }
+        rc = statement_create(self->statement, self->connection, operation);
+        if (rc != SQLITE_OK) {
+            self->statement = 0;
+            goto error;
+        }
+    }
+
+    statement_reset(self->statement);
+    statement_mark_dirty(self->statement);
+
+    while (1) {
+        parameters = PyIter_Next(parameters_iter);
+        if (!parameters) {
+            break;
+        }
+
+        statement_mark_dirty(self->statement);
+
+        statement_bind_parameters(self->statement, parameters);
+        if (PyErr_Occurred()) {
+            goto error;
+        }
+
+        if (build_row_cast_map(self) != 0) {
+            PyErr_SetString(OperationalError, "Error while building row_cast_map");
+            goto error;
+        }
+
+        rc = _sqlite_step_with_busyhandler(self->statement->st, self->connection);
+        if (rc != SQLITE_DONE && rc != SQLITE_ROW) {
+            rc = statement_reset(self->statement);
+            if (rc == SQLITE_SCHEMA) {
+                rc = statement_recompile(self->statement, parameters);
+                if (rc == SQLITE_OK) {
+                    rc = _sqlite_step_with_busyhandler(self->statement->st, self->connection);
+                } else {
+                    _seterror(self->connection->db);
+                    goto error;
+                }
+            } else {
+                if (PyErr_Occurred()) {
+                    /* there was an error that occurred in a user-defined callback */
+                    if (_enable_callback_tracebacks) {
+                        PyErr_Print();
+                    } else {
+                        PyErr_Clear();
+                    }
+                }
+                _seterror(self->connection->db);
+                goto error;
+            }
+        }
+
+        if (rc == SQLITE_ROW || (rc == SQLITE_DONE && statement_type == STATEMENT_SELECT)) {
+            Py_BEGIN_ALLOW_THREADS
+            numcols = sqlite3_column_count(self->statement->st);
+            Py_END_ALLOW_THREADS
+
+            if (self->description == Py_None) {
+                Py_DECREF(self->description);
+                self->description = PyTuple_New(numcols);
+                if (!self->description) {
+                    goto error;
+                }
+                for (i = 0; i < numcols; i++) {
+                    descriptor = PyTuple_New(7);
+                    if (!descriptor) {
+                        goto error;
+                    }
+                    PyTuple_SetItem(descriptor, 0, _build_column_name(sqlite3_column_name(self->statement->st, i)));
+                    Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 1, Py_None);
+                    Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 2, Py_None);
+                    Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 3, Py_None);
+                    Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 4, Py_None);
+                    Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 5, Py_None);
+                    Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 6, Py_None);
+                    PyTuple_SetItem(self->description, i, descriptor);
+                }
+            }
+        }
+
+        if (rc == SQLITE_ROW) {
+            if (multiple) {
+                PyErr_SetString(ProgrammingError, "executemany() can only execute DML statements.");
+                goto error;
+            }
+
+            self->next_row = _fetch_one_row(self);
+        } else if (rc == SQLITE_DONE && !multiple) {
+            statement_reset(self->statement);
+            Py_DECREF(self->statement);
+            self->statement = 0;
+        }
+
+        switch (statement_type) {
+            case STATEMENT_UPDATE:
+            case STATEMENT_DELETE:
+            case STATEMENT_INSERT:
+            case STATEMENT_REPLACE:
+                Py_BEGIN_ALLOW_THREADS
+                rowcount += (long)sqlite3_changes(self->connection->db);
+                Py_END_ALLOW_THREADS
+                Py_DECREF(self->rowcount);
+                self->rowcount = PyInt_FromLong(rowcount);
+        }
+
+        Py_DECREF(self->lastrowid);
+        if (statement_type == STATEMENT_INSERT) {
+            Py_BEGIN_ALLOW_THREADS
+            lastrowid = sqlite3_last_insert_rowid(self->connection->db);
+            Py_END_ALLOW_THREADS
+            self->lastrowid = PyInt_FromLong((long)lastrowid);
+        } else {
+            Py_INCREF(Py_None);
+            self->lastrowid = Py_None;
+        }
+
+        if (multiple) {
+            rc = statement_reset(self->statement);
+        }
+        Py_XDECREF(parameters);
+    }
+
+error:
+    Py_XDECREF(operation_bytestr);
+    Py_XDECREF(parameters);
+    Py_XDECREF(parameters_iter);
+    Py_XDECREF(parameters_list);
+
+    if (PyErr_Occurred()) {
+        return NULL;
+    } else {
+        Py_INCREF(self);
+        return (PyObject*)self;
+    }
+}
+
+PyObject* cursor_execute(Cursor* self, PyObject* args)
+{
+    return _query_execute(self, 0, args);
+}
+
+PyObject* cursor_executemany(Cursor* self, PyObject* args)
+{
+    return _query_execute(self, 1, args);
+}
+
+PyObject* cursor_executescript(Cursor* self, PyObject* args)
+{
+    PyObject* script_obj;
+    PyObject* script_str = NULL;
+    const char* script_cstr;
+    sqlite3_stmt* statement;
+    int rc;
+    PyObject* result;
+    int statement_completed = 0;
+
+    if (!PyArg_ParseTuple(args, "O", &script_obj)) {
+        return NULL; 
+    }
+
+    if (!check_thread(self->connection) || !check_connection(self->connection)) {
+        return NULL;
+    }
+
+    if (PyString_Check(script_obj)) {
+        script_cstr = PyString_AsString(script_obj);
+    } else if (PyUnicode_Check(script_obj)) {
+        script_str = PyUnicode_AsUTF8String(script_obj);
+        if (!script_str) {
+            return NULL;
+        }
+
+        script_cstr = PyString_AsString(script_str);
+    } else {
+        PyErr_SetString(PyExc_ValueError, "script argument must be unicode or string.");
+        return NULL;
+    }
+
+    /* commit first */
+    result = connection_commit(self->connection, NULL);
+    if (!result) {
+        goto error;
+    }
+    Py_DECREF(result);
+
+    while (1) {
+        if (!sqlite3_complete(script_cstr)) {
+            break;
+        }
+        statement_completed = 1;
+
+        rc = sqlite3_prepare(self->connection->db,
+                             script_cstr,
+                             -1,
+                             &statement,
+                             &script_cstr);
+        if (rc != SQLITE_OK) {
+            _seterror(self->connection->db);
+            goto error;
+        }
+
+        /* execute statement, and ignore results of SELECT statements */
+        rc = SQLITE_ROW;
+        while (rc == SQLITE_ROW) {
+            rc = _sqlite_step_with_busyhandler(statement, self->connection);
+        }
+
+        if (rc != SQLITE_DONE) {
+            (void)sqlite3_finalize(statement);
+            _seterror(self->connection->db);
+            goto error;
+        }
+
+        rc = sqlite3_finalize(statement);
+        if (rc != SQLITE_OK) {
+            _seterror(self->connection->db);
+            goto error;
+        }
+    }
+
+error:
+    Py_XDECREF(script_str);
+
+    if (!statement_completed) {
+        PyErr_SetString(ProgrammingError, "you did not provide a complete SQL statement");
+    }
+
+    if (PyErr_Occurred()) {
+        return NULL;
+    } else {
+        Py_INCREF(self);
+        return (PyObject*)self;
+    }
+}
+
+PyObject* cursor_getiter(Cursor *self)
+{
+    Py_INCREF(self);
+    return (PyObject*)self;
+}
+
+PyObject* cursor_iternext(Cursor *self)
+{
+    PyObject* next_row_tuple;
+    PyObject* next_row;
+    int rc;
+
+    if (!check_thread(self->connection) || !check_connection(self->connection)) {
+        return NULL;
+    }
+
+    if (!self->next_row) {
+         if (self->statement) {
+            (void)statement_reset(self->statement);
+            Py_DECREF(self->statement);
+            self->statement = NULL;
+        }
+        return NULL;
+    }
+
+    next_row_tuple = self->next_row;
+    self->next_row = NULL;
+
+    if (self->row_factory != Py_None) {
+        next_row = PyObject_CallFunction(self->row_factory, "OO", self, next_row_tuple);
+        Py_DECREF(next_row_tuple);
+    } else {
+        next_row = next_row_tuple;
+    }
+
+    rc = _sqlite_step_with_busyhandler(self->statement->st, self->connection);
+    if (rc != SQLITE_DONE && rc != SQLITE_ROW) {
+        Py_DECREF(next_row);
+        _seterror(self->connection->db);
+        return NULL;
+    }
+
+    if (rc == SQLITE_ROW) {
+        self->next_row = _fetch_one_row(self);
+    }
+
+    return next_row;
+}
+
+PyObject* cursor_fetchone(Cursor* self, PyObject* args)
+{
+    PyObject* row;
+
+    row = cursor_iternext(self);
+    if (!row && !PyErr_Occurred()) {
+        Py_INCREF(Py_None);
+        return Py_None;
+    }
+
+    return row;
+}
+
+PyObject* cursor_fetchmany(Cursor* self, PyObject* args)
+{
+    PyObject* row;
+    PyObject* list;
+    int maxrows = self->arraysize;
+    int counter = 0;
+
+    if (!PyArg_ParseTuple(args, "|i", &maxrows)) {
+        return NULL; 
+    }
+
+    list = PyList_New(0);
+    if (!list) {
+        return NULL;
+    }
+
+    /* just make sure we enter the loop */
+    row = Py_None;
+
+    while (row) {
+        row = cursor_iternext(self);
+        if (row) {
+            PyList_Append(list, row);
+            Py_DECREF(row);
+        } else {
+            break;
+        }
+
+        if (++counter == maxrows) {
+            break;
+        }
+    }
+
+    if (PyErr_Occurred()) {
+        Py_DECREF(list);
+        return NULL;
+    } else {
+        return list;
+    }
+}
+
+PyObject* cursor_fetchall(Cursor* self, PyObject* args)
+{
+    PyObject* row;
+    PyObject* list;
+
+    list = PyList_New(0);
+    if (!list) {
+        return NULL;
+    }
+
+    /* just make sure we enter the loop */
+    row = (PyObject*)Py_None;
+
+    while (row) {
+        row = cursor_iternext(self);
+        if (row) {
+            PyList_Append(list, row);
+            Py_DECREF(row);
+        }
+    }
+
+    if (PyErr_Occurred()) {
+        Py_DECREF(list);
+        return NULL;
+    } else {
+        return list;
+    }
+}
+
+PyObject* pysqlite_noop(Connection* self, PyObject* args)
+{
+    /* don't care, return None */
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+PyObject* cursor_close(Cursor* self, PyObject* args)
+{
+    if (!check_thread(self->connection) || !check_connection(self->connection)) {
+        return NULL;
+    }
+
+    if (self->statement) {
+        (void)statement_reset(self->statement);
+        Py_DECREF(self->statement);
+        self->statement = 0;
+    }
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyMethodDef cursor_methods[] = {
+    {"execute", (PyCFunction)cursor_execute, METH_VARARGS,
+        PyDoc_STR("Executes a SQL statement.")},
+    {"executemany", (PyCFunction)cursor_executemany, METH_VARARGS,
+        PyDoc_STR("Repeatedly executes a SQL statement.")},
+    {"executescript", (PyCFunction)cursor_executescript, METH_VARARGS,
+        PyDoc_STR("Executes a multiple SQL statements at once. Non-standard.")},
+    {"fetchone", (PyCFunction)cursor_fetchone, METH_NOARGS,
+        PyDoc_STR("Fetches several rows from the resultset.")},
+    {"fetchmany", (PyCFunction)cursor_fetchmany, METH_VARARGS,
+        PyDoc_STR("Fetches all rows from the resultset.")},
+    {"fetchall", (PyCFunction)cursor_fetchall, METH_NOARGS,
+        PyDoc_STR("Fetches one row from the resultset.")},
+    {"close", (PyCFunction)cursor_close, METH_NOARGS,
+        PyDoc_STR("Closes the cursor.")},
+    {"setinputsizes", (PyCFunction)pysqlite_noop, METH_VARARGS,
+        PyDoc_STR("Required by DB-API. Does nothing in pysqlite.")},
+    {"setoutputsize", (PyCFunction)pysqlite_noop, METH_VARARGS,
+        PyDoc_STR("Required by DB-API. Does nothing in pysqlite.")},
+    {NULL, NULL}
+};
+
+static struct PyMemberDef cursor_members[] =
+{
+    {"connection", T_OBJECT, offsetof(Cursor, connection), RO},
+    {"description", T_OBJECT, offsetof(Cursor, description), RO},
+    {"arraysize", T_INT, offsetof(Cursor, arraysize), 0},
+    {"lastrowid", T_OBJECT, offsetof(Cursor, lastrowid), RO},
+    {"rowcount", T_OBJECT, offsetof(Cursor, rowcount), RO},
+    {"row_factory", T_OBJECT, offsetof(Cursor, row_factory), 0},
+    {NULL}
+};
+
+static char cursor_doc[] =
+PyDoc_STR("SQLite database cursor class.");
+
+PyTypeObject CursorType = {
+        PyObject_HEAD_INIT(NULL)
+        0,                                              /* ob_size */
+        MODULE_NAME ".Cursor",                          /* tp_name */
+        sizeof(Cursor),                                 /* tp_basicsize */
+        0,                                              /* tp_itemsize */
+        (destructor)cursor_dealloc,                     /* tp_dealloc */
+        0,                                              /* tp_print */
+        0,                                              /* tp_getattr */
+        0,                                              /* tp_setattr */
+        0,                                              /* tp_compare */
+        0,                                              /* tp_repr */
+        0,                                              /* tp_as_number */
+        0,                                              /* tp_as_sequence */
+        0,                                              /* tp_as_mapping */
+        0,                                              /* tp_hash */
+        0,                                              /* tp_call */
+        0,                                              /* tp_str */
+        0,                                              /* tp_getattro */
+        0,                                              /* tp_setattro */
+        0,                                              /* tp_as_buffer */
+        Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_ITER|Py_TPFLAGS_BASETYPE, /* tp_flags */
+        cursor_doc,                                     /* tp_doc */
+        0,                                              /* tp_traverse */
+        0,                                              /* tp_clear */
+        0,                                              /* tp_richcompare */
+        0,                                              /* tp_weaklistoffset */
+        (getiterfunc)cursor_getiter,                    /* tp_iter */
+        (iternextfunc)cursor_iternext,                  /* tp_iternext */
+        cursor_methods,                                 /* tp_methods */
+        cursor_members,                                 /* tp_members */
+        0,                                              /* tp_getset */
+        0,                                              /* tp_base */
+        0,                                              /* tp_dict */
+        0,                                              /* tp_descr_get */
+        0,                                              /* tp_descr_set */
+        0,                                              /* tp_dictoffset */
+        (initproc)cursor_init,                          /* tp_init */
+        0,                                              /* tp_alloc */
+        0,                                              /* tp_new */
+        0                                               /* tp_free */
+};
+
+extern int cursor_setup_types(void)
+{
+    CursorType.tp_new = PyType_GenericNew;
+    return PyType_Ready(&CursorType);
+}

Added: vendor/Python/current/Modules/_sqlite/cursor.h
===================================================================
--- vendor/Python/current/Modules/_sqlite/cursor.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_sqlite/cursor.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,71 @@
+/* cursor.h - definitions for the cursor type
+ *
+ * Copyright (C) 2004-2006 Gerhard Häring <gh at ghaering.de>
+ *
+ * This file is part of pysqlite.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#ifndef PYSQLITE_CURSOR_H
+#define PYSQLITE_CURSOR_H
+#include "Python.h"
+
+#include "statement.h"
+#include "connection.h"
+#include "module.h"
+
+typedef struct
+{
+    PyObject_HEAD
+    Connection* connection;
+    PyObject* description;
+    PyObject* row_cast_map;
+    int arraysize;
+    PyObject* lastrowid;
+    PyObject* rowcount;
+    PyObject* row_factory;
+    Statement* statement;
+
+    /* the next row to be returned, NULL if no next row available */
+    PyObject* next_row;
+} Cursor;
+
+typedef enum {
+    STATEMENT_INVALID, STATEMENT_INSERT, STATEMENT_DELETE,
+    STATEMENT_UPDATE, STATEMENT_REPLACE, STATEMENT_SELECT,
+    STATEMENT_OTHER
+} StatementKind;
+
+extern PyTypeObject CursorType;
+
+int cursor_init(Cursor* self, PyObject* args, PyObject* kwargs);
+void cursor_dealloc(Cursor* self);
+PyObject* cursor_execute(Cursor* self, PyObject* args);
+PyObject* cursor_executemany(Cursor* self, PyObject* args);
+PyObject* cursor_getiter(Cursor *self);
+PyObject* cursor_iternext(Cursor *self);
+PyObject* cursor_fetchone(Cursor* self, PyObject* args);
+PyObject* cursor_fetchmany(Cursor* self, PyObject* args);
+PyObject* cursor_fetchall(Cursor* self, PyObject* args);
+PyObject* pysqlite_noop(Connection* self, PyObject* args);
+PyObject* cursor_close(Cursor* self, PyObject* args);
+
+int cursor_setup_types(void);
+
+#define UNKNOWN (-1)
+#endif

Added: vendor/Python/current/Modules/_sqlite/microprotocols.c
===================================================================
--- vendor/Python/current/Modules/_sqlite/microprotocols.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_sqlite/microprotocols.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,142 @@
+/* microprotocols.c - minimalist and non-validating protocols implementation
+ *
+ * Copyright (C) 2003-2004 Federico Di Gregorio <fog at debian.org>
+ *
+ * This file is part of psycopg and was adapted for pysqlite. Federico Di
+ * Gregorio gave the permission to use it within pysqlite under the following
+ * license:
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#include <Python.h>
+#include <structmember.h>
+
+#include "cursor.h"
+#include "microprotocols.h"
+#include "prepare_protocol.h"
+
+
+/** the adapters registry **/
+
+PyObject *psyco_adapters;
+
+/* microprotocols_init - initialize the adapters dictionary */
+
+int
+microprotocols_init(PyObject *dict)
+{
+    /* create adapters dictionary and put it in module namespace */
+    if ((psyco_adapters = PyDict_New()) == NULL) {
+        return -1;
+    }
+
+    return PyDict_SetItemString(dict, "adapters", psyco_adapters);
+}
+
+
+/* microprotocols_add - add a reverse type-caster to the dictionary */
+
+int
+microprotocols_add(PyTypeObject *type, PyObject *proto, PyObject *cast)
+{
+    PyObject* key;
+    int rc;
+
+    if (proto == NULL) proto = (PyObject*)&SQLitePrepareProtocolType;
+
+    key = Py_BuildValue("(OO)", (PyObject*)type, proto);
+    if (!key) {
+        return -1;
+    }
+
+    rc = PyDict_SetItem(psyco_adapters, key, cast);
+    Py_DECREF(key);
+
+    return rc;
+}
+
+/* microprotocols_adapt - adapt an object to the built-in protocol */
+
+PyObject *
+microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt)
+{
+    PyObject *adapter, *key;
+
+    /* we don't check for exact type conformance as specified in PEP 246
+       because the SQLitePrepareProtocolType type is abstract and there is no
+       way to get a quotable object to be its instance */
+
+    /* look for an adapter in the registry */
+    key = Py_BuildValue("(OO)", (PyObject*)obj->ob_type, proto);
+    if (!key) {
+        return NULL;
+    }
+    adapter = PyDict_GetItem(psyco_adapters, key);
+    Py_DECREF(key);
+    if (adapter) {
+        PyObject *adapted = PyObject_CallFunctionObjArgs(adapter, obj, NULL);
+        return adapted;
+    }
+
+    /* try to have the protocol adapt this object*/
+    if (PyObject_HasAttrString(proto, "__adapt__")) {
+        PyObject *adapted = PyObject_CallMethod(proto, "__adapt__", "O", obj);
+        if (adapted) {
+            if (adapted != Py_None) {
+                return adapted;
+            } else {
+                Py_DECREF(adapted);
+            }
+        }
+
+        if (PyErr_Occurred() && !PyErr_ExceptionMatches(PyExc_TypeError))
+            return NULL;
+    }
+
+    /* and finally try to have the object adapt itself */
+    if (PyObject_HasAttrString(obj, "__conform__")) {
+        PyObject *adapted = PyObject_CallMethod(obj, "__conform__","O", proto);
+        if (adapted) {
+            if (adapted != Py_None) {
+                return adapted;
+            } else {
+                Py_DECREF(adapted);
+            }
+        }
+
+        if (PyErr_Occurred() && !PyErr_ExceptionMatches(PyExc_TypeError)) {
+            return NULL;
+        }
+    }
+
+    /* else set the right exception and return NULL */
+    PyErr_SetString(ProgrammingError, "can't adapt");
+    return NULL;
+}
+
+/** module-level functions **/
+
+PyObject *
+psyco_microprotocols_adapt(Cursor *self, PyObject *args)
+{
+    PyObject *obj, *alt = NULL;
+    PyObject *proto = (PyObject*)&SQLitePrepareProtocolType;
+
+    if (!PyArg_ParseTuple(args, "O|OO", &obj, &proto, &alt)) return NULL;
+    return microprotocols_adapt(obj, proto, alt);
+}

Added: vendor/Python/current/Modules/_sqlite/microprotocols.h
===================================================================
--- vendor/Python/current/Modules/_sqlite/microprotocols.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_sqlite/microprotocols.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,59 @@
+/* microprotocols.c - definitions for minimalist and non-validating protocols
+ *
+ * Copyright (C) 2003-2004 Federico Di Gregorio <fog at debian.org>
+ *
+ * This file is part of psycopg and was adapted for pysqlite. Federico Di
+ * Gregorio gave the permission to use it within pysqlite under the following
+ * license:
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#ifndef PSYCOPG_MICROPROTOCOLS_H
+#define PSYCOPG_MICROPROTOCOLS_H 1
+
+#include <Python.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** adapters registry **/
+
+extern PyObject *psyco_adapters;
+
+/** the names of the three mandatory methods **/
+
+#define MICROPROTOCOLS_GETQUOTED_NAME "getquoted"
+#define MICROPROTOCOLS_GETSTRING_NAME "getstring"
+#define MICROPROTOCOLS_GETBINARY_NAME "getbinary"
+
+/** exported functions **/
+
+/* used by module.c to init the microprotocols system */
+extern int microprotocols_init(PyObject *dict);
+extern int microprotocols_add(
+    PyTypeObject *type, PyObject *proto, PyObject *cast);
+extern PyObject *microprotocols_adapt(
+    PyObject *obj, PyObject *proto, PyObject *alt);
+
+extern PyObject *
+    psyco_microprotocols_adapt(Cursor* self, PyObject *args);   
+#define psyco_microprotocols_adapt_doc \
+    "adapt(obj, protocol, alternate) -> adapt obj to given protocol. Non-standard."
+
+#endif /* !defined(PSYCOPG_MICROPROTOCOLS_H) */

Added: vendor/Python/current/Modules/_sqlite/module.c
===================================================================
--- vendor/Python/current/Modules/_sqlite/module.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_sqlite/module.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,409 @@
+    /* module.c - the module itself
+     *
+     * Copyright (C) 2004-2006 Gerhard Häring <gh at ghaering.de>
+     *
+     * This file is part of pysqlite.
+     *
+     * This software is provided 'as-is', without any express or implied
+     * warranty.  In no event will the authors be held liable for any damages
+     * arising from the use of this software.
+     *
+     * Permission is granted to anyone to use this software for any purpose,
+     * including commercial applications, and to alter it and redistribute it
+     * freely, subject to the following restrictions:
+     *
+     * 1. The origin of this software must not be misrepresented; you must not
+     *    claim that you wrote the original software. If you use this software
+     *    in a product, an acknowledgment in the product documentation would be
+     *    appreciated but is not required.
+     * 2. Altered source versions must be plainly marked as such, and must not be
+     *    misrepresented as being the original software.
+     * 3. This notice may not be removed or altered from any source distribution.
+     */
+
+#include "connection.h"
+#include "statement.h"
+#include "cursor.h"
+#include "cache.h"
+#include "prepare_protocol.h"
+#include "microprotocols.h"
+#include "row.h"
+
+#if SQLITE_VERSION_NUMBER >= 3003003
+#define HAVE_SHARED_CACHE
+#endif
+
+/* static objects at module-level */
+
+PyObject* Error, *Warning, *InterfaceError, *DatabaseError, *InternalError,
+    *OperationalError, *ProgrammingError, *IntegrityError, *DataError,
+    *NotSupportedError, *OptimizedUnicode;
+
+PyObject* converters;
+int _enable_callback_tracebacks;
+
+static PyObject* module_connect(PyObject* self, PyObject* args, PyObject*
+        kwargs)
+{
+    /* Python seems to have no way of extracting a single keyword-arg at
+     * C-level, so this code is redundant with the one in connection_init in
+     * connection.c and must always be copied from there ... */
+
+    static char *kwlist[] = {"database", "timeout", "detect_types", "isolation_level", "check_same_thread", "factory", "cached_statements", NULL, NULL};
+    char* database;
+    int detect_types = 0;
+    PyObject* isolation_level;
+    PyObject* factory = NULL;
+    int check_same_thread = 1;
+    int cached_statements;
+    double timeout = 5.0;
+
+    PyObject* result;
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|diOiOi", kwlist,
+                                     &database, &timeout, &detect_types, &isolation_level, &check_same_thread, &factory, &cached_statements))
+    {
+        return NULL; 
+    }
+
+    if (factory == NULL) {
+        factory = (PyObject*)&ConnectionType;
+    }
+
+    result = PyObject_Call(factory, args, kwargs);
+
+    return result;
+}
+
+static PyObject* module_complete(PyObject* self, PyObject* args, PyObject*
+        kwargs)
+{
+    static char *kwlist[] = {"statement", NULL, NULL};
+    char* statement;
+
+    PyObject* result;
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s", kwlist, &statement))
+    {
+        return NULL; 
+    }
+
+    if (sqlite3_complete(statement)) {
+        result = Py_True;
+    } else {
+        result = Py_False;
+    }
+
+    Py_INCREF(result);
+
+    return result;
+}
+
+#ifdef HAVE_SHARED_CACHE
+static PyObject* module_enable_shared_cache(PyObject* self, PyObject* args, PyObject*
+        kwargs)
+{
+    static char *kwlist[] = {"do_enable", NULL, NULL};
+    int do_enable;
+    int rc;
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i", kwlist, &do_enable))
+    {
+        return NULL; 
+    }
+
+    rc = sqlite3_enable_shared_cache(do_enable);
+
+    if (rc != SQLITE_OK) {
+        PyErr_SetString(OperationalError, "Changing the shared_cache flag failed");
+        return NULL;
+    } else {
+        Py_INCREF(Py_None);
+        return Py_None;
+    }
+}
+#endif /* HAVE_SHARED_CACHE */
+
+static PyObject* module_register_adapter(PyObject* self, PyObject* args, PyObject* kwargs)
+{
+    PyTypeObject* type;
+    PyObject* caster;
+
+    if (!PyArg_ParseTuple(args, "OO", &type, &caster)) {
+        return NULL;
+    }
+
+    microprotocols_add(type, (PyObject*)&SQLitePrepareProtocolType, caster);
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject* module_register_converter(PyObject* self, PyObject* args, PyObject* kwargs)
+{
+    char* orig_name;
+    char* name = NULL;
+    char* c;
+    PyObject* callable;
+    PyObject* retval = NULL;
+
+    if (!PyArg_ParseTuple(args, "sO", &orig_name, &callable)) {
+        return NULL;
+    }
+
+    /* convert the name to lowercase */
+    name = PyMem_Malloc(strlen(orig_name) + 2);
+    if (!name) {
+        goto error;
+    }
+    strcpy(name, orig_name);
+    for (c = name; *c != (char)0; c++) {
+        *c = (*c) & 0xDF;
+    }
+
+    if (PyDict_SetItemString(converters, name, callable) != 0) {
+        goto error;
+    }
+
+    Py_INCREF(Py_None);
+    retval = Py_None;
+error:
+    if (name) {
+        PyMem_Free(name);
+    }
+    return retval;
+}
+
+static PyObject* enable_callback_tracebacks(PyObject* self, PyObject* args, PyObject* kwargs)
+{
+    if (!PyArg_ParseTuple(args, "i", &_enable_callback_tracebacks)) {
+        return NULL;
+    }
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+void converters_init(PyObject* dict)
+{
+    converters = PyDict_New();
+    if (!converters) {
+        return;
+    }
+
+    PyDict_SetItemString(dict, "converters", converters);
+}
+
+static PyMethodDef module_methods[] = {
+    {"connect",  (PyCFunction)module_connect,  METH_VARARGS|METH_KEYWORDS, PyDoc_STR("Creates a connection.")},
+    {"complete_statement",  (PyCFunction)module_complete,  METH_VARARGS|METH_KEYWORDS, PyDoc_STR("Checks if a string contains a complete SQL statement. Non-standard.")},
+#ifdef HAVE_SHARED_CACHE
+    {"enable_shared_cache",  (PyCFunction)module_enable_shared_cache,  METH_VARARGS|METH_KEYWORDS, PyDoc_STR("Enable or disable shared cache mode for the calling thread. Experimental/Non-standard.")},
+#endif
+    {"register_adapter", (PyCFunction)module_register_adapter, METH_VARARGS, PyDoc_STR("Registers an adapter with pysqlite's adapter registry. Non-standard.")},
+    {"register_converter", (PyCFunction)module_register_converter, METH_VARARGS, PyDoc_STR("Registers a converter with pysqlite. Non-standard.")},
+    {"adapt",  (PyCFunction)psyco_microprotocols_adapt, METH_VARARGS, psyco_microprotocols_adapt_doc},
+    {"enable_callback_tracebacks",  (PyCFunction)enable_callback_tracebacks, METH_VARARGS, PyDoc_STR("Enable or disable callback functions throwing errors to stderr.")},
+    {NULL, NULL}
+};
+
+struct _IntConstantPair {
+    char* constant_name;
+    int constant_value;
+};
+
+typedef struct _IntConstantPair IntConstantPair;
+
+static IntConstantPair _int_constants[] = {
+    {"PARSE_DECLTYPES", PARSE_DECLTYPES},
+    {"PARSE_COLNAMES", PARSE_COLNAMES},
+
+    {"SQLITE_OK", SQLITE_OK},
+    {"SQLITE_DENY", SQLITE_DENY},
+    {"SQLITE_IGNORE", SQLITE_IGNORE},
+    {"SQLITE_CREATE_INDEX", SQLITE_CREATE_INDEX},
+    {"SQLITE_CREATE_TABLE", SQLITE_CREATE_TABLE},
+    {"SQLITE_CREATE_TEMP_INDEX", SQLITE_CREATE_TEMP_INDEX},
+    {"SQLITE_CREATE_TEMP_TABLE", SQLITE_CREATE_TEMP_TABLE},
+    {"SQLITE_CREATE_TEMP_TRIGGER", SQLITE_CREATE_TEMP_TRIGGER},
+    {"SQLITE_CREATE_TEMP_VIEW", SQLITE_CREATE_TEMP_VIEW},
+    {"SQLITE_CREATE_TRIGGER", SQLITE_CREATE_TRIGGER},
+    {"SQLITE_CREATE_VIEW", SQLITE_CREATE_VIEW},
+    {"SQLITE_DELETE", SQLITE_DELETE},
+    {"SQLITE_DROP_INDEX", SQLITE_DROP_INDEX},
+    {"SQLITE_DROP_TABLE", SQLITE_DROP_TABLE},
+    {"SQLITE_DROP_TEMP_INDEX", SQLITE_DROP_TEMP_INDEX},
+    {"SQLITE_DROP_TEMP_TABLE", SQLITE_DROP_TEMP_TABLE},
+    {"SQLITE_DROP_TEMP_TRIGGER", SQLITE_DROP_TEMP_TRIGGER},
+    {"SQLITE_DROP_TEMP_VIEW", SQLITE_DROP_TEMP_VIEW},
+    {"SQLITE_DROP_TRIGGER", SQLITE_DROP_TRIGGER},
+    {"SQLITE_DROP_VIEW", SQLITE_DROP_VIEW},
+    {"SQLITE_INSERT", SQLITE_INSERT},
+    {"SQLITE_PRAGMA", SQLITE_PRAGMA},
+    {"SQLITE_READ", SQLITE_READ},
+    {"SQLITE_SELECT", SQLITE_SELECT},
+    {"SQLITE_TRANSACTION", SQLITE_TRANSACTION},
+    {"SQLITE_UPDATE", SQLITE_UPDATE},
+    {"SQLITE_ATTACH", SQLITE_ATTACH},
+    {"SQLITE_DETACH", SQLITE_DETACH},
+#if SQLITE_VERSION_NUMBER >= 3002001
+    {"SQLITE_ALTER_TABLE", SQLITE_ALTER_TABLE},
+    {"SQLITE_REINDEX", SQLITE_REINDEX},
+#endif
+#if SQLITE_VERSION_NUMBER >= 3003000
+    {"SQLITE_ANALYZE", SQLITE_ANALYZE},
+#endif
+    {(char*)NULL, 0}
+};
+
+PyMODINIT_FUNC init_sqlite3(void)
+{
+    PyObject *module, *dict;
+    PyObject *tmp_obj;
+    int i;
+
+    module = Py_InitModule("_sqlite3", module_methods);
+
+    if (!module ||
+        (row_setup_types() < 0) ||
+        (cursor_setup_types() < 0) ||
+        (connection_setup_types() < 0) ||
+        (cache_setup_types() < 0) ||
+        (statement_setup_types() < 0) ||
+        (prepare_protocol_setup_types() < 0)
+       ) {
+        return;
+    }
+
+    Py_INCREF(&ConnectionType);
+    PyModule_AddObject(module, "Connection", (PyObject*) &ConnectionType);
+    Py_INCREF(&CursorType);
+    PyModule_AddObject(module, "Cursor", (PyObject*) &CursorType);
+    Py_INCREF(&CacheType);
+    PyModule_AddObject(module, "Statement", (PyObject*)&StatementType);
+    Py_INCREF(&StatementType);
+    PyModule_AddObject(module, "Cache", (PyObject*) &CacheType);
+    Py_INCREF(&SQLitePrepareProtocolType);
+    PyModule_AddObject(module, "PrepareProtocol", (PyObject*) &SQLitePrepareProtocolType);
+    Py_INCREF(&RowType);
+    PyModule_AddObject(module, "Row", (PyObject*) &RowType);
+
+    if (!(dict = PyModule_GetDict(module))) {
+        goto error;
+    }
+
+    /*** Create DB-API Exception hierarchy */
+
+    if (!(Error = PyErr_NewException(MODULE_NAME ".Error", PyExc_StandardError, NULL))) {
+        goto error;
+    }
+    PyDict_SetItemString(dict, "Error", Error);
+
+    if (!(Warning = PyErr_NewException(MODULE_NAME ".Warning", PyExc_StandardError, NULL))) {
+        goto error;
+    }
+    PyDict_SetItemString(dict, "Warning", Warning);
+
+    /* Error subclasses */
+
+    if (!(InterfaceError = PyErr_NewException(MODULE_NAME ".InterfaceError", Error, NULL))) {
+        goto error;
+    }
+    PyDict_SetItemString(dict, "InterfaceError", InterfaceError);
+
+    if (!(DatabaseError = PyErr_NewException(MODULE_NAME ".DatabaseError", Error, NULL))) {
+        goto error;
+    }
+    PyDict_SetItemString(dict, "DatabaseError", DatabaseError);
+
+    /* DatabaseError subclasses */
+
+    if (!(InternalError = PyErr_NewException(MODULE_NAME ".InternalError", DatabaseError, NULL))) {
+        goto error;
+    }
+    PyDict_SetItemString(dict, "InternalError", InternalError);
+
+    if (!(OperationalError = PyErr_NewException(MODULE_NAME ".OperationalError", DatabaseError, NULL))) {
+        goto error;
+    }
+    PyDict_SetItemString(dict, "OperationalError", OperationalError);
+
+    if (!(ProgrammingError = PyErr_NewException(MODULE_NAME ".ProgrammingError", DatabaseError, NULL))) {
+        goto error;
+    }
+    PyDict_SetItemString(dict, "ProgrammingError", ProgrammingError);
+
+    if (!(IntegrityError = PyErr_NewException(MODULE_NAME ".IntegrityError", DatabaseError,NULL))) {
+        goto error;
+    }
+    PyDict_SetItemString(dict, "IntegrityError", IntegrityError);
+
+    if (!(DataError = PyErr_NewException(MODULE_NAME ".DataError", DatabaseError, NULL))) {
+        goto error;
+    }
+    PyDict_SetItemString(dict, "DataError", DataError);
+
+    if (!(NotSupportedError = PyErr_NewException(MODULE_NAME ".NotSupportedError", DatabaseError, NULL))) {
+        goto error;
+    }
+    PyDict_SetItemString(dict, "NotSupportedError", NotSupportedError);
+
+    /* We just need "something" unique for OptimizedUnicode. It does not really
+     * need to be a string subclass. Just anything that can act as a special
+     * marker for us. So I pulled PyCell_Type out of my magic hat.
+     */
+    Py_INCREF((PyObject*)&PyCell_Type);
+    OptimizedUnicode = (PyObject*)&PyCell_Type;
+    PyDict_SetItemString(dict, "OptimizedUnicode", OptimizedUnicode);
+
+    /* Set integer constants */
+    for (i = 0; _int_constants[i].constant_name != 0; i++) {
+        tmp_obj = PyInt_FromLong(_int_constants[i].constant_value);
+        if (!tmp_obj) {
+            goto error;
+        }
+        PyDict_SetItemString(dict, _int_constants[i].constant_name, tmp_obj);
+        Py_DECREF(tmp_obj);
+    }
+
+    if (!(tmp_obj = PyString_FromString(PYSQLITE_VERSION))) {
+        goto error;
+    }
+    PyDict_SetItemString(dict, "version", tmp_obj);
+    Py_DECREF(tmp_obj);
+
+    if (!(tmp_obj = PyString_FromString(sqlite3_libversion()))) {
+        goto error;
+    }
+    PyDict_SetItemString(dict, "sqlite_version", tmp_obj);
+    Py_DECREF(tmp_obj);
+
+    /* initialize microprotocols layer */
+    microprotocols_init(dict);
+
+    /* initialize the default converters */
+    converters_init(dict);
+
+    _enable_callback_tracebacks = 0;
+
+    /* Original comment form _bsddb.c in the Python core. This is also still
+     * needed nowadays for Python 2.3/2.4.
+     * 
+     * PyEval_InitThreads is called here due to a quirk in python 1.5
+     * - 2.2.1 (at least) according to Russell Williamson <merel at wt.net>:
+     * The global interepreter lock is not initialized until the first
+     * thread is created using thread.start_new_thread() or fork() is
+     * called.  that would cause the ALLOW_THREADS here to segfault due
+     * to a null pointer reference if no threads or child processes
+     * have been created.  This works around that and is a no-op if
+     * threads have already been initialized.
+     *  (see pybsddb-users mailing list post on 2002-08-07)
+     */
+    PyEval_InitThreads();
+
+error:
+    if (PyErr_Occurred())
+    {
+        PyErr_SetString(PyExc_ImportError, MODULE_NAME ": init failed");
+    }
+}

Added: vendor/Python/current/Modules/_sqlite/module.h
===================================================================
--- vendor/Python/current/Modules/_sqlite/module.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_sqlite/module.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,57 @@
+/* module.h - definitions for the module
+ *
+ * Copyright (C) 2004-2006 Gerhard Häring <gh at ghaering.de>
+ *
+ * This file is part of pysqlite.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#ifndef PYSQLITE_MODULE_H
+#define PYSQLITE_MODULE_H
+#include "Python.h"
+
+#define PYSQLITE_VERSION "2.3.2"
+
+extern PyObject* Error;
+extern PyObject* Warning;
+extern PyObject* InterfaceError;
+extern PyObject* DatabaseError;
+extern PyObject* InternalError;
+extern PyObject* OperationalError;
+extern PyObject* ProgrammingError;
+extern PyObject* IntegrityError;
+extern PyObject* DataError;
+extern PyObject* NotSupportedError;
+
+extern PyObject* OptimizedUnicode;
+
+/* the functions time.time() and time.sleep() */
+extern PyObject* time_time;
+extern PyObject* time_sleep;
+
+/* A dictionary, mapping colum types (INTEGER, VARCHAR, etc.) to converter
+ * functions, that convert the SQL value to the appropriate Python value.
+ * The key is uppercase.
+ */
+extern PyObject* converters;
+
+extern int _enable_callback_tracebacks;
+
+#define PARSE_DECLTYPES 1
+#define PARSE_COLNAMES 2
+#endif

Added: vendor/Python/current/Modules/_sqlite/prepare_protocol.c
===================================================================
--- vendor/Python/current/Modules/_sqlite/prepare_protocol.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_sqlite/prepare_protocol.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,84 @@
+/* prepare_protocol.c - the protocol for preparing values for SQLite
+ *
+ * Copyright (C) 2005-2006 Gerhard Häring <gh at ghaering.de>
+ *
+ * This file is part of pysqlite.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#include "prepare_protocol.h"
+
+int prepare_protocol_init(SQLitePrepareProtocol* self, PyObject* args, PyObject* kwargs)
+{
+    return 0;
+}
+
+void prepare_protocol_dealloc(SQLitePrepareProtocol* self)
+{
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+PyTypeObject SQLitePrepareProtocolType= {
+        PyObject_HEAD_INIT(NULL)
+        0,                                              /* ob_size */
+        MODULE_NAME ".PrepareProtocol",                 /* tp_name */
+        sizeof(SQLitePrepareProtocol),                  /* tp_basicsize */
+        0,                                              /* tp_itemsize */
+        (destructor)prepare_protocol_dealloc,           /* tp_dealloc */
+        0,                                              /* tp_print */
+        0,                                              /* tp_getattr */
+        0,                                              /* tp_setattr */
+        0,                                              /* tp_compare */
+        0,                                              /* tp_repr */
+        0,                                              /* tp_as_number */
+        0,                                              /* tp_as_sequence */
+        0,                                              /* tp_as_mapping */
+        0,                                              /* tp_hash */
+        0,                                              /* tp_call */
+        0,                                              /* tp_str */
+        0,                                              /* tp_getattro */
+        0,                                              /* tp_setattro */
+        0,                                              /* tp_as_buffer */
+        Py_TPFLAGS_DEFAULT,                             /* tp_flags */
+        0,                                              /* tp_doc */
+        0,                                              /* tp_traverse */
+        0,                                              /* tp_clear */
+        0,                                              /* tp_richcompare */
+        0,                                              /* tp_weaklistoffset */
+        0,                                              /* tp_iter */
+        0,                                              /* tp_iternext */
+        0,                                              /* tp_methods */
+        0,                                              /* tp_members */
+        0,                                              /* tp_getset */
+        0,                                              /* tp_base */
+        0,                                              /* tp_dict */
+        0,                                              /* tp_descr_get */
+        0,                                              /* tp_descr_set */
+        0,                                              /* tp_dictoffset */
+        (initproc)prepare_protocol_init,                /* tp_init */
+        0,                                              /* tp_alloc */
+        0,                                              /* tp_new */
+        0                                               /* tp_free */
+};
+
+extern int prepare_protocol_setup_types(void)
+{
+    SQLitePrepareProtocolType.tp_new = PyType_GenericNew;
+    SQLitePrepareProtocolType.ob_type= &PyType_Type;
+    return PyType_Ready(&SQLitePrepareProtocolType);
+}

Added: vendor/Python/current/Modules/_sqlite/prepare_protocol.h
===================================================================
--- vendor/Python/current/Modules/_sqlite/prepare_protocol.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_sqlite/prepare_protocol.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,41 @@
+/* prepare_protocol.h - the protocol for preparing values for SQLite
+ *
+ * Copyright (C) 2005 Gerhard Häring <gh at ghaering.de>
+ *
+ * This file is part of pysqlite.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#ifndef PYSQLITE_PREPARE_PROTOCOL_H
+#define PYSQLITE_PREPARE_PROTOCOL_H
+#include "Python.h"
+
+typedef struct
+{
+    PyObject_HEAD
+} SQLitePrepareProtocol;
+
+extern PyTypeObject SQLitePrepareProtocolType;
+
+int prepare_protocol_init(SQLitePrepareProtocol* self, PyObject* args, PyObject* kwargs);
+void prepare_protocol_dealloc(SQLitePrepareProtocol* self);
+
+int prepare_protocol_setup_types(void);
+
+#define UNKNOWN (-1)
+#endif

Added: vendor/Python/current/Modules/_sqlite/row.c
===================================================================
--- vendor/Python/current/Modules/_sqlite/row.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_sqlite/row.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,202 @@
+/* row.c - an enhanced tuple for database rows
+ *
+ * Copyright (C) 2005-2006 Gerhard Häring <gh at ghaering.de>
+ *
+ * This file is part of pysqlite.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#include "row.h"
+#include "cursor.h"
+#include "sqlitecompat.h"
+
+void row_dealloc(Row* self)
+{
+    Py_XDECREF(self->data);
+    Py_XDECREF(self->description);
+
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+int row_init(Row* self, PyObject* args, PyObject* kwargs)
+{
+    PyObject* data;
+    Cursor* cursor;
+
+    self->data = 0;
+    self->description = 0;
+
+    if (!PyArg_ParseTuple(args, "OO", &cursor, &data)) {
+        return -1;
+    }
+
+    if (!PyObject_IsInstance((PyObject*)cursor, (PyObject*)&CursorType)) {
+        PyErr_SetString(PyExc_TypeError, "instance of cursor required for first argument");
+        return -1;
+    }
+
+    if (!PyTuple_Check(data)) {
+        PyErr_SetString(PyExc_TypeError, "tuple required for second argument");
+        return -1;
+    }
+
+    Py_INCREF(data);
+    self->data = data;
+
+    Py_INCREF(cursor->description);
+    self->description = cursor->description;
+
+    return 0;
+}
+
+PyObject* row_subscript(Row* self, PyObject* idx)
+{
+    long _idx;
+    char* key;
+    int nitems, i;
+    char* compare_key;
+
+    char* p1;
+    char* p2;
+
+    PyObject* item;
+
+    if (PyInt_Check(idx)) {
+        _idx = PyInt_AsLong(idx);
+        item = PyTuple_GetItem(self->data, _idx);
+        Py_XINCREF(item);
+        return item;
+    } else if (PyLong_Check(idx)) {
+        _idx = PyLong_AsLong(idx);
+        item = PyTuple_GetItem(self->data, _idx);
+        Py_XINCREF(item);
+        return item;
+    } else if (PyString_Check(idx)) {
+        key = PyString_AsString(idx);
+
+        nitems = PyTuple_Size(self->description);
+
+        for (i = 0; i < nitems; i++) {
+            compare_key = PyString_AsString(PyTuple_GET_ITEM(PyTuple_GET_ITEM(self->description, i), 0));
+            if (!compare_key) {
+                return NULL;
+            }
+
+            p1 = key;
+            p2 = compare_key;
+
+            while (1) {
+                if ((*p1 == (char)0) || (*p2 == (char)0)) {
+                    break;
+                }
+
+                if ((*p1 | 0x20) != (*p2 | 0x20)) {
+                    break;
+                }
+
+                p1++;
+                p2++;
+            }
+
+            if ((*p1 == (char)0) && (*p2 == (char)0)) {
+                /* found item */
+                item = PyTuple_GetItem(self->data, i);
+                Py_INCREF(item);
+                return item;
+            }
+
+        }
+
+        PyErr_SetString(PyExc_IndexError, "No item with that key");
+        return NULL;
+    } else if (PySlice_Check(idx)) {
+        PyErr_SetString(PyExc_ValueError, "slices not implemented, yet");
+        return NULL;
+    } else {
+        PyErr_SetString(PyExc_IndexError, "Index must be int or string");
+        return NULL;
+    }
+}
+
+Py_ssize_t row_length(Row* self, PyObject* args, PyObject* kwargs)
+{
+    return PyTuple_GET_SIZE(self->data);
+}
+
+static int row_print(Row* self, FILE *fp, int flags)
+{
+    return (&PyTuple_Type)->tp_print(self->data, fp, flags);
+}
+
+
+PyMappingMethods row_as_mapping = {
+    /* mp_length        */ (lenfunc)row_length,
+    /* mp_subscript     */ (binaryfunc)row_subscript,
+    /* mp_ass_subscript */ (objobjargproc)0,
+};
+
+
+PyTypeObject RowType = {
+        PyObject_HEAD_INIT(NULL)
+        0,                                              /* ob_size */
+        MODULE_NAME ".Row",                             /* tp_name */
+        sizeof(Row),                                    /* tp_basicsize */
+        0,                                              /* tp_itemsize */
+        (destructor)row_dealloc,                        /* tp_dealloc */
+        (printfunc)row_print,                           /* tp_print */
+        0,                                              /* tp_getattr */
+        0,                                              /* tp_setattr */
+        0,                                              /* tp_compare */
+        0,                                              /* tp_repr */
+        0,                                              /* tp_as_number */
+        0,                                              /* tp_as_sequence */
+        0,                                              /* tp_as_mapping */
+        0,                                              /* tp_hash */
+        0,                                              /* tp_call */
+        0,                                              /* tp_str */
+        0,                                              /* tp_getattro */
+        0,                                              /* tp_setattro */
+        0,                                              /* tp_as_buffer */
+        Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,         /* tp_flags */
+        0,                                              /* tp_doc */
+        0,                                              /* tp_traverse */
+        0,                                              /* tp_clear */
+        0,                                              /* tp_richcompare */
+        0,                                              /* tp_weaklistoffset */
+        0,                                              /* tp_iter */
+        0,                                              /* tp_iternext */
+        0,                                              /* tp_methods */
+        0,                                              /* tp_members */
+        0,                                              /* tp_getset */
+        0,                                              /* tp_base */
+        0,                                              /* tp_dict */
+        0,                                              /* tp_descr_get */
+        0,                                              /* tp_descr_set */
+        0,                                              /* tp_dictoffset */
+        (initproc)row_init,                             /* tp_init */
+        0,                                              /* tp_alloc */
+        0,                                              /* tp_new */
+        0                                               /* tp_free */
+};
+
+extern int row_setup_types(void)
+{
+    RowType.tp_new = PyType_GenericNew;
+    RowType.tp_as_mapping = &row_as_mapping;
+    return PyType_Ready(&RowType);
+}

Added: vendor/Python/current/Modules/_sqlite/row.h
===================================================================
--- vendor/Python/current/Modules/_sqlite/row.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_sqlite/row.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,39 @@
+/* row.h - an enhanced tuple for database rows
+ *
+ * Copyright (C) 2005 Gerhard Häring <gh at ghaering.de>
+ *
+ * This file is part of pysqlite.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#ifndef PYSQLITE_ROW_H
+#define PYSQLITE_ROW_H
+#include "Python.h"
+
+typedef struct _Row
+{
+    PyObject_HEAD
+    PyObject* data;
+    PyObject* description;
+} Row;
+
+extern PyTypeObject RowType;
+
+int row_setup_types(void);
+
+#endif

Added: vendor/Python/current/Modules/_sqlite/sqlitecompat.h
===================================================================
--- vendor/Python/current/Modules/_sqlite/sqlitecompat.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_sqlite/sqlitecompat.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,34 @@
+/* sqlitecompat.h - compatibility macros
+ *
+ * Copyright (C) 2006 Gerhard Häring <gh at ghaering.de>
+ *
+ * This file is part of pysqlite.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#ifndef PYSQLITE_COMPAT_H
+#define PYSQLITE_COMPAT_H
+
+/* define Py_ssize_t for pre-2.5 versions of Python */
+
+#if PY_VERSION_HEX < 0x02050000
+typedef int Py_ssize_t;
+typedef int (*lenfunc)(PyObject*);
+#endif
+
+#endif

Added: vendor/Python/current/Modules/_sqlite/statement.c
===================================================================
--- vendor/Python/current/Modules/_sqlite/statement.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_sqlite/statement.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,432 @@
+/* statement.c - the statement type
+ *
+ * Copyright (C) 2005-2006 Gerhard Häring <gh at ghaering.de>
+ *
+ * This file is part of pysqlite.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#include "statement.h"
+#include "cursor.h"
+#include "connection.h"
+#include "microprotocols.h"
+#include "prepare_protocol.h"
+#include "sqlitecompat.h"
+
+/* prototypes */
+int check_remaining_sql(const char* tail);
+
+typedef enum {
+    LINECOMMENT_1,
+    IN_LINECOMMENT,
+    COMMENTSTART_1,
+    IN_COMMENT,
+    COMMENTEND_1,
+    NORMAL
+} parse_remaining_sql_state;
+
+int statement_create(Statement* self, Connection* connection, PyObject* sql)
+{
+    const char* tail;
+    int rc;
+    PyObject* sql_str;
+    char* sql_cstr;
+
+    self->st = NULL;
+    self->in_use = 0;
+
+    if (PyString_Check(sql)) {
+        sql_str = sql;
+        Py_INCREF(sql_str);
+    } else if (PyUnicode_Check(sql)) {
+        sql_str = PyUnicode_AsUTF8String(sql);
+        if (!sql_str) {
+            rc = PYSQLITE_SQL_WRONG_TYPE;
+            return rc;
+        }
+    } else {
+        rc = PYSQLITE_SQL_WRONG_TYPE;
+        return rc;
+    }
+
+    self->in_weakreflist = NULL;
+    self->sql = sql_str;
+
+    sql_cstr = PyString_AsString(sql_str);
+
+    rc = sqlite3_prepare(connection->db,
+                         sql_cstr,
+                         -1,
+                         &self->st,
+                         &tail);
+
+    self->db = connection->db;
+
+    if (rc == SQLITE_OK && check_remaining_sql(tail)) {
+        (void)sqlite3_finalize(self->st);
+        self->st = NULL;
+        rc = PYSQLITE_TOO_MUCH_SQL;
+    }
+
+    return rc;
+}
+
+int statement_bind_parameter(Statement* self, int pos, PyObject* parameter)
+{
+    int rc = SQLITE_OK;
+    long longval;
+#ifdef HAVE_LONG_LONG
+    PY_LONG_LONG longlongval;
+#endif
+    const char* buffer;
+    char* string;
+    Py_ssize_t buflen;
+    PyObject* stringval;
+
+    if (parameter == Py_None) {
+        rc = sqlite3_bind_null(self->st, pos);
+    } else if (PyInt_Check(parameter)) {
+        longval = PyInt_AsLong(parameter);
+        rc = sqlite3_bind_int64(self->st, pos, (sqlite_int64)longval);
+#ifdef HAVE_LONG_LONG
+    } else if (PyLong_Check(parameter)) {
+        longlongval = PyLong_AsLongLong(parameter);
+        /* in the overflow error case, longlongval is -1, and an exception is set */
+        rc = sqlite3_bind_int64(self->st, pos, (sqlite_int64)longlongval);
+#endif
+    } else if (PyFloat_Check(parameter)) {
+        rc = sqlite3_bind_double(self->st, pos, PyFloat_AsDouble(parameter));
+    } else if (PyBuffer_Check(parameter)) {
+        if (PyObject_AsCharBuffer(parameter, &buffer, &buflen) == 0) {
+            rc = sqlite3_bind_blob(self->st, pos, buffer, buflen, SQLITE_TRANSIENT);
+        } else {
+            PyErr_SetString(PyExc_ValueError, "could not convert BLOB to buffer");
+            rc = -1;
+        }
+    } else if PyString_Check(parameter) {
+        string = PyString_AsString(parameter);
+        rc = sqlite3_bind_text(self->st, pos, string, -1, SQLITE_TRANSIENT);
+    } else if PyUnicode_Check(parameter) {
+        stringval = PyUnicode_AsUTF8String(parameter);
+        string = PyString_AsString(stringval);
+        rc = sqlite3_bind_text(self->st, pos, string, -1, SQLITE_TRANSIENT);
+        Py_DECREF(stringval);
+    } else {
+        rc = -1;
+    }
+
+    return rc;
+}
+
+void statement_bind_parameters(Statement* self, PyObject* parameters)
+{
+    PyObject* current_param;
+    PyObject* adapted;
+    const char* binding_name;
+    int i;
+    int rc;
+    int num_params_needed;
+    int num_params;
+
+    Py_BEGIN_ALLOW_THREADS
+    num_params_needed = sqlite3_bind_parameter_count(self->st);
+    Py_END_ALLOW_THREADS
+
+    if (PyDict_Check(parameters)) {
+        /* parameters passed as dictionary */
+        for (i = 1; i <= num_params_needed; i++) {
+            Py_BEGIN_ALLOW_THREADS
+            binding_name = sqlite3_bind_parameter_name(self->st, i);
+            Py_END_ALLOW_THREADS
+            if (!binding_name) {
+                PyErr_Format(ProgrammingError, "Binding %d has no name, but you supplied a dictionary (which has only names).", i);
+                return;
+            }
+
+            binding_name++; /* skip first char (the colon) */
+            current_param = PyDict_GetItemString(parameters, binding_name);
+            if (!current_param) {
+                PyErr_Format(ProgrammingError, "You did not supply a value for binding %d.", i);
+                return;
+            }
+
+            Py_INCREF(current_param);
+            adapted = microprotocols_adapt(current_param, (PyObject*)&SQLitePrepareProtocolType, NULL);
+            if (adapted) {
+                Py_DECREF(current_param);
+            } else {
+                PyErr_Clear();
+                adapted = current_param;
+            }
+
+            rc = statement_bind_parameter(self, i, adapted);
+            Py_DECREF(adapted);
+
+            if (rc != SQLITE_OK) {
+                PyErr_Format(InterfaceError, "Error binding parameter :%s - probably unsupported type.", binding_name);
+                return;
+           }
+        }
+    } else {
+        /* parameters passed as sequence */
+        num_params = PySequence_Length(parameters);
+        if (num_params != num_params_needed) {
+            PyErr_Format(ProgrammingError, "Incorrect number of bindings supplied. The current statement uses %d, and there are %d supplied.",
+                         num_params_needed, num_params);
+            return;
+        }
+        for (i = 0; i < num_params; i++) {
+            current_param = PySequence_GetItem(parameters, i);
+            if (!current_param) {
+                return;
+            }
+            adapted = microprotocols_adapt(current_param, (PyObject*)&SQLitePrepareProtocolType, NULL);
+
+            if (adapted) {
+                Py_DECREF(current_param);
+            } else {
+                PyErr_Clear();
+                adapted = current_param;
+            }
+
+            rc = statement_bind_parameter(self, i + 1, adapted);
+            Py_DECREF(adapted);
+
+            if (rc != SQLITE_OK) {
+                PyErr_Format(InterfaceError, "Error binding parameter %d - probably unsupported type.", i);
+                return;
+            }
+        }
+    }
+}
+
+int statement_recompile(Statement* self, PyObject* params)
+{
+    const char* tail;
+    int rc;
+    char* sql_cstr;
+    sqlite3_stmt* new_st;
+
+    sql_cstr = PyString_AsString(self->sql);
+
+    rc = sqlite3_prepare(self->db,
+                         sql_cstr,
+                         -1,
+                         &new_st,
+                         &tail);
+
+    if (rc == SQLITE_OK) {
+        /* The efficient sqlite3_transfer_bindings is only available in SQLite
+         * version 3.2.2 or later. For older SQLite releases, that might not
+         * even define SQLITE_VERSION_NUMBER, we do it the manual way.
+         */
+        #ifdef SQLITE_VERSION_NUMBER
+        #if SQLITE_VERSION_NUMBER >= 3002002
+        (void)sqlite3_transfer_bindings(self->st, new_st);
+        #endif
+        #else
+        statement_bind_parameters(self, params);
+        #endif
+
+        (void)sqlite3_finalize(self->st);
+        self->st = new_st;
+    }
+
+    return rc;
+}
+
+int statement_finalize(Statement* self)
+{
+    int rc;
+
+    rc = SQLITE_OK;
+    if (self->st) {
+        Py_BEGIN_ALLOW_THREADS
+        rc = sqlite3_finalize(self->st);
+        Py_END_ALLOW_THREADS
+        self->st = NULL;
+    }
+
+    self->in_use = 0;
+
+    return rc;
+}
+
+int statement_reset(Statement* self)
+{
+    int rc;
+
+    rc = SQLITE_OK;
+
+    if (self->in_use && self->st) {
+        Py_BEGIN_ALLOW_THREADS
+        rc = sqlite3_reset(self->st);
+        Py_END_ALLOW_THREADS
+
+        if (rc == SQLITE_OK) {
+            self->in_use = 0;
+        }
+    }
+
+    return rc;
+}
+
+void statement_mark_dirty(Statement* self)
+{
+    self->in_use = 1;
+}
+
+void statement_dealloc(Statement* self)
+{
+    int rc;
+
+    if (self->st) {
+        Py_BEGIN_ALLOW_THREADS
+        rc = sqlite3_finalize(self->st);
+        Py_END_ALLOW_THREADS
+    }
+
+    self->st = NULL;
+
+    Py_XDECREF(self->sql);
+
+    if (self->in_weakreflist != NULL) {
+        PyObject_ClearWeakRefs((PyObject*)self);
+    }
+
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+/*
+ * Checks if there is anything left in an SQL string after SQLite compiled it.
+ * This is used to check if somebody tried to execute more than one SQL command
+ * with one execute()/executemany() command, which the DB-API and we don't
+ * allow.
+ *
+ * Returns 1 if there is more left than should be. 0 if ok.
+ */
+int check_remaining_sql(const char* tail)
+{
+    const char* pos = tail;
+
+    parse_remaining_sql_state state = NORMAL;
+
+    for (;;) {
+        switch (*pos) {
+            case 0:
+                return 0;
+            case '-':
+                if (state == NORMAL) {
+                    state  = LINECOMMENT_1;
+                } else if (state == LINECOMMENT_1) {
+                    state = IN_LINECOMMENT;
+                }
+                break;
+            case ' ':
+            case '\t':
+                break;
+            case '\n':
+            case 13:
+                if (state == IN_LINECOMMENT) {
+                    state = NORMAL;
+                }
+                break;
+            case '/':
+                if (state == NORMAL) {
+                    state = COMMENTSTART_1;
+                } else if (state == COMMENTEND_1) {
+                    state = NORMAL;
+                } else if (state == COMMENTSTART_1) {
+                    return 1;
+                }
+                break;
+            case '*':
+                if (state == NORMAL) {
+                    return 1;
+                } else if (state == LINECOMMENT_1) {
+                    return 1;
+                } else if (state == COMMENTSTART_1) {
+                    state = IN_COMMENT;
+                } else if (state == IN_COMMENT) {
+                    state = COMMENTEND_1;
+                }
+                break;
+            default:
+                if (state == COMMENTEND_1) {
+                    state = IN_COMMENT;
+                } else if (state == IN_LINECOMMENT) {
+                } else if (state == IN_COMMENT) {
+                } else {
+                    return 1;
+                }
+        }
+
+        pos++;
+    }
+
+    return 0;
+}
+
+PyTypeObject StatementType = {
+        PyObject_HEAD_INIT(NULL)
+        0,                                              /* ob_size */
+        MODULE_NAME ".Statement",                       /* tp_name */
+        sizeof(Statement),                              /* tp_basicsize */
+        0,                                              /* tp_itemsize */
+        (destructor)statement_dealloc,                  /* tp_dealloc */
+        0,                                              /* tp_print */
+        0,                                              /* tp_getattr */
+        0,                                              /* tp_setattr */
+        0,                                              /* tp_compare */
+        0,                                              /* tp_repr */
+        0,                                              /* tp_as_number */
+        0,                                              /* tp_as_sequence */
+        0,                                              /* tp_as_mapping */
+        0,                                              /* tp_hash */
+        0,                                              /* tp_call */
+        0,                                              /* tp_str */
+        0,                                              /* tp_getattro */
+        0,                                              /* tp_setattro */
+        0,                                              /* tp_as_buffer */
+        Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS,  /* tp_flags */
+        0,                                              /* tp_doc */
+        0,                                              /* tp_traverse */
+        0,                                              /* tp_clear */
+        0,                                              /* tp_richcompare */
+        offsetof(Statement, in_weakreflist),            /* tp_weaklistoffset */
+        0,                                              /* tp_iter */
+        0,                                              /* tp_iternext */
+        0,                                              /* tp_methods */
+        0,                                              /* tp_members */
+        0,                                              /* tp_getset */
+        0,                                              /* tp_base */
+        0,                                              /* tp_dict */
+        0,                                              /* tp_descr_get */
+        0,                                              /* tp_descr_set */
+        0,                                              /* tp_dictoffset */
+        (initproc)0,                                    /* tp_init */
+        0,                                              /* tp_alloc */
+        0,                                              /* tp_new */
+        0                                               /* tp_free */
+};
+
+extern int statement_setup_types(void)
+{
+    StatementType.tp_new = PyType_GenericNew;
+    return PyType_Ready(&StatementType);
+}

Added: vendor/Python/current/Modules/_sqlite/statement.h
===================================================================
--- vendor/Python/current/Modules/_sqlite/statement.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_sqlite/statement.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,59 @@
+/* statement.h - definitions for the statement type
+ *
+ * Copyright (C) 2005 Gerhard Häring <gh at ghaering.de>
+ *
+ * This file is part of pysqlite.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#ifndef PYSQLITE_STATEMENT_H
+#define PYSQLITE_STATEMENT_H
+#include "Python.h"
+
+#include "connection.h"
+#include "sqlite3.h"
+
+#define PYSQLITE_TOO_MUCH_SQL (-100)
+#define PYSQLITE_SQL_WRONG_TYPE (-101)
+
+typedef struct
+{
+    PyObject_HEAD
+    sqlite3* db;
+    sqlite3_stmt* st;
+    PyObject* sql;
+    int in_use;
+    PyObject* in_weakreflist; /* List of weak references */
+} Statement;
+
+extern PyTypeObject StatementType;
+
+int statement_create(Statement* self, Connection* connection, PyObject* sql);
+void statement_dealloc(Statement* self);
+
+int statement_bind_parameter(Statement* self, int pos, PyObject* parameter);
+void statement_bind_parameters(Statement* self, PyObject* parameters);
+
+int statement_recompile(Statement* self, PyObject* parameters);
+int statement_finalize(Statement* self);
+int statement_reset(Statement* self);
+void statement_mark_dirty(Statement* self);
+
+int statement_setup_types(void);
+
+#endif

Added: vendor/Python/current/Modules/_sqlite/util.c
===================================================================
--- vendor/Python/current/Modules/_sqlite/util.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_sqlite/util.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,96 @@
+/* util.c - various utility functions
+ *
+ * Copyright (C) 2005-2006 Gerhard Häring <gh at ghaering.de>
+ *
+ * This file is part of pysqlite.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#include "module.h"
+#include "connection.h"
+
+int _sqlite_step_with_busyhandler(sqlite3_stmt* statement, Connection* connection
+)
+{
+    int rc;
+
+    Py_BEGIN_ALLOW_THREADS
+    rc = sqlite3_step(statement);
+    Py_END_ALLOW_THREADS
+
+    return rc;
+}
+
+/**
+ * Checks the SQLite error code and sets the appropriate DB-API exception.
+ * Returns the error code (0 means no error occurred).
+ */
+int _seterror(sqlite3* db)
+{
+    int errorcode;
+
+    errorcode = sqlite3_errcode(db);
+
+    switch (errorcode)
+    {
+        case SQLITE_OK:
+            PyErr_Clear();
+            break;
+        case SQLITE_INTERNAL:
+        case SQLITE_NOTFOUND:
+            PyErr_SetString(InternalError, sqlite3_errmsg(db));
+            break;
+        case SQLITE_NOMEM:
+            (void)PyErr_NoMemory();
+            break;
+        case SQLITE_ERROR:
+        case SQLITE_PERM:
+        case SQLITE_ABORT:
+        case SQLITE_BUSY:
+        case SQLITE_LOCKED:
+        case SQLITE_READONLY:
+        case SQLITE_INTERRUPT:
+        case SQLITE_IOERR:
+        case SQLITE_FULL:
+        case SQLITE_CANTOPEN:
+        case SQLITE_PROTOCOL:
+        case SQLITE_EMPTY:
+        case SQLITE_SCHEMA:
+            PyErr_SetString(OperationalError, sqlite3_errmsg(db));
+            break;
+        case SQLITE_CORRUPT:
+            PyErr_SetString(DatabaseError, sqlite3_errmsg(db));
+            break;
+        case SQLITE_TOOBIG:
+            PyErr_SetString(DataError, sqlite3_errmsg(db));
+            break;
+        case SQLITE_CONSTRAINT:
+        case SQLITE_MISMATCH:
+            PyErr_SetString(IntegrityError, sqlite3_errmsg(db));
+            break;
+        case SQLITE_MISUSE:
+            PyErr_SetString(ProgrammingError, sqlite3_errmsg(db));
+            break;
+        default:
+            PyErr_SetString(DatabaseError, sqlite3_errmsg(db));
+            break;
+    }
+
+    return errorcode;
+}
+

Added: vendor/Python/current/Modules/_sqlite/util.h
===================================================================
--- vendor/Python/current/Modules/_sqlite/util.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_sqlite/util.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,38 @@
+/* util.h - various utility functions
+ *
+ * Copyright (C) 2005-2006 Gerhard Häring <gh at ghaering.de>
+ *
+ * This file is part of pysqlite.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#ifndef PYSQLITE_UTIL_H
+#define PYSQLITE_UTIL_H
+#include "Python.h"
+#include "pythread.h"
+#include "sqlite3.h"
+#include "connection.h"
+
+int _sqlite_step_with_busyhandler(sqlite3_stmt* statement, Connection* connection);
+
+/**
+ * Checks the SQLite error code and sets the appropriate DB-API exception.
+ * Returns the error code (0 means no error occurred).
+ */
+int _seterror(sqlite3* db);
+#endif

Added: vendor/Python/current/Modules/_sre.c
===================================================================
--- vendor/Python/current/Modules/_sre.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_sre.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,3429 @@
+/*
+ * Secret Labs' Regular Expression Engine
+ *
+ * regular expression matching engine
+ *
+ * partial history:
+ * 1999-10-24 fl  created (based on existing template matcher code)
+ * 2000-03-06 fl  first alpha, sort of
+ * 2000-08-01 fl  fixes for 1.6b1
+ * 2000-08-07 fl  use PyOS_CheckStack() if available
+ * 2000-09-20 fl  added expand method
+ * 2001-03-20 fl  lots of fixes for 2.1b2
+ * 2001-04-15 fl  export copyright as Python attribute, not global
+ * 2001-04-28 fl  added __copy__ methods (work in progress)
+ * 2001-05-14 fl  fixes for 1.5.2 compatibility
+ * 2001-07-01 fl  added BIGCHARSET support (from Martin von Loewis)
+ * 2001-10-18 fl  fixed group reset issue (from Matthew Mueller)
+ * 2001-10-20 fl  added split primitive; reenable unicode for 1.6/2.0/2.1
+ * 2001-10-21 fl  added sub/subn primitive
+ * 2001-10-24 fl  added finditer primitive (for 2.2 only)
+ * 2001-12-07 fl  fixed memory leak in sub/subn (Guido van Rossum)
+ * 2002-11-09 fl  fixed empty sub/subn return type
+ * 2003-04-18 mvl fully support 4-byte codes
+ * 2003-10-17 gn  implemented non recursive scheme
+ *
+ * Copyright (c) 1997-2001 by Secret Labs AB.  All rights reserved.
+ *
+ * This version of the SRE library can be redistributed under CNRI's
+ * Python 1.6 license.  For any other use, please contact Secret Labs
+ * AB (info at pythonware.com).
+ *
+ * Portions of this engine have been developed in cooperation with
+ * CNRI.  Hewlett-Packard provided funding for 1.6 integration and
+ * other compatibility work.
+ */
+
+#ifndef SRE_RECURSIVE
+
+static char copyright[] =
+    " SRE 2.2.2 Copyright (c) 1997-2002 by Secret Labs AB ";
+
+#define PY_SSIZE_T_CLEAN
+
+#include "Python.h"
+#include "structmember.h" /* offsetof */
+
+#include "sre.h"
+
+#include <ctype.h>
+
+/* name of this module, minus the leading underscore */
+#if !defined(SRE_MODULE)
+#define SRE_MODULE "sre"
+#endif
+
+#define SRE_PY_MODULE "re"
+
+/* defining this one enables tracing */
+#undef VERBOSE
+
+#if PY_VERSION_HEX >= 0x01060000
+#if PY_VERSION_HEX  < 0x02020000 || defined(Py_USING_UNICODE)
+/* defining this enables unicode support (default under 1.6a1 and later) */
+#define HAVE_UNICODE
+#endif
+#endif
+
+/* -------------------------------------------------------------------- */
+/* optional features */
+
+/* enables fast searching */
+#define USE_FAST_SEARCH
+
+/* enables aggressive inlining (always on for Visual C) */
+#undef USE_INLINE
+
+/* enables copy/deepcopy handling (work in progress) */
+#undef USE_BUILTIN_COPY
+
+#if PY_VERSION_HEX < 0x01060000
+#define PyObject_DEL(op) PyMem_DEL((op))
+#endif
+
+/* -------------------------------------------------------------------- */
+
+#if defined(_MSC_VER)
+#pragma optimize("agtw", on) /* doesn't seem to make much difference... */
+#pragma warning(disable: 4710) /* who cares if functions are not inlined ;-) */
+/* fastest possible local call under MSVC */
+#define LOCAL(type) static __inline type __fastcall
+#elif defined(USE_INLINE)
+#define LOCAL(type) static inline type
+#else
+#define LOCAL(type) static type
+#endif
+
+/* error codes */
+#define SRE_ERROR_ILLEGAL -1 /* illegal opcode */
+#define SRE_ERROR_STATE -2 /* illegal state */
+#define SRE_ERROR_RECURSION_LIMIT -3 /* runaway recursion */
+#define SRE_ERROR_MEMORY -9 /* out of memory */
+
+#if defined(VERBOSE)
+#define TRACE(v) printf v
+#else
+#define TRACE(v)
+#endif
+
+/* -------------------------------------------------------------------- */
+/* search engine state */
+
+/* default character predicates (run sre_chars.py to regenerate tables) */
+
+#define SRE_DIGIT_MASK 1
+#define SRE_SPACE_MASK 2
+#define SRE_LINEBREAK_MASK 4
+#define SRE_ALNUM_MASK 8
+#define SRE_WORD_MASK 16
+
+/* FIXME: this assumes ASCII.  create tables in init_sre() instead */
+
+static char sre_char_info[128] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 6, 2,
+2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 25, 25, 25, 25, 25, 25,
+25, 25, 0, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0,
+0, 0, 16, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 0, 0 };
+
+static char sre_char_lower[128] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
+27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
+44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
+61, 62, 63, 64, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107,
+108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121,
+122, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105,
+106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
+120, 121, 122, 123, 124, 125, 126, 127 };
+
+#define SRE_IS_DIGIT(ch)\
+    ((ch) < 128 ? (sre_char_info[(ch)] & SRE_DIGIT_MASK) : 0)
+#define SRE_IS_SPACE(ch)\
+    ((ch) < 128 ? (sre_char_info[(ch)] & SRE_SPACE_MASK) : 0)
+#define SRE_IS_LINEBREAK(ch)\
+    ((ch) < 128 ? (sre_char_info[(ch)] & SRE_LINEBREAK_MASK) : 0)
+#define SRE_IS_ALNUM(ch)\
+    ((ch) < 128 ? (sre_char_info[(ch)] & SRE_ALNUM_MASK) : 0)
+#define SRE_IS_WORD(ch)\
+    ((ch) < 128 ? (sre_char_info[(ch)] & SRE_WORD_MASK) : 0)
+
+static unsigned int sre_lower(unsigned int ch)
+{
+    return ((ch) < 128 ? (unsigned int)sre_char_lower[ch] : ch);
+}
+
+/* locale-specific character predicates */
+/* !(c & ~N) == (c < N+1) for any unsigned c, this avoids
+ * warnings when c's type supports only numbers < N+1 */
+#define SRE_LOC_IS_DIGIT(ch) (!((ch) & ~255) ? isdigit((ch)) : 0)
+#define SRE_LOC_IS_SPACE(ch) (!((ch) & ~255) ? isspace((ch)) : 0)
+#define SRE_LOC_IS_LINEBREAK(ch) ((ch) == '\n')
+#define SRE_LOC_IS_ALNUM(ch) (!((ch) & ~255) ? isalnum((ch)) : 0)
+#define SRE_LOC_IS_WORD(ch) (SRE_LOC_IS_ALNUM((ch)) || (ch) == '_')
+
+static unsigned int sre_lower_locale(unsigned int ch)
+{
+    return ((ch) < 256 ? (unsigned int)tolower((ch)) : ch);
+}
+
+/* unicode-specific character predicates */
+
+#if defined(HAVE_UNICODE)
+
+#define SRE_UNI_IS_DIGIT(ch) Py_UNICODE_ISDIGIT((Py_UNICODE)(ch))
+#define SRE_UNI_IS_SPACE(ch) Py_UNICODE_ISSPACE((Py_UNICODE)(ch))
+#define SRE_UNI_IS_LINEBREAK(ch) Py_UNICODE_ISLINEBREAK((Py_UNICODE)(ch))
+#define SRE_UNI_IS_ALNUM(ch) Py_UNICODE_ISALNUM((Py_UNICODE)(ch))
+#define SRE_UNI_IS_WORD(ch) (SRE_UNI_IS_ALNUM((ch)) || (ch) == '_')
+
+static unsigned int sre_lower_unicode(unsigned int ch)
+{
+    return (unsigned int) Py_UNICODE_TOLOWER((Py_UNICODE)(ch));
+}
+
+#endif
+
+LOCAL(int)
+sre_category(SRE_CODE category, unsigned int ch)
+{
+    switch (category) {
+
+    case SRE_CATEGORY_DIGIT:
+        return SRE_IS_DIGIT(ch);
+    case SRE_CATEGORY_NOT_DIGIT:
+        return !SRE_IS_DIGIT(ch);
+    case SRE_CATEGORY_SPACE:
+        return SRE_IS_SPACE(ch);
+    case SRE_CATEGORY_NOT_SPACE:
+        return !SRE_IS_SPACE(ch);
+    case SRE_CATEGORY_WORD:
+        return SRE_IS_WORD(ch);
+    case SRE_CATEGORY_NOT_WORD:
+        return !SRE_IS_WORD(ch);
+    case SRE_CATEGORY_LINEBREAK:
+        return SRE_IS_LINEBREAK(ch);
+    case SRE_CATEGORY_NOT_LINEBREAK:
+        return !SRE_IS_LINEBREAK(ch);
+
+    case SRE_CATEGORY_LOC_WORD:
+        return SRE_LOC_IS_WORD(ch);
+    case SRE_CATEGORY_LOC_NOT_WORD:
+        return !SRE_LOC_IS_WORD(ch);
+
+#if defined(HAVE_UNICODE)
+    case SRE_CATEGORY_UNI_DIGIT:
+        return SRE_UNI_IS_DIGIT(ch);
+    case SRE_CATEGORY_UNI_NOT_DIGIT:
+        return !SRE_UNI_IS_DIGIT(ch);
+    case SRE_CATEGORY_UNI_SPACE:
+        return SRE_UNI_IS_SPACE(ch);
+    case SRE_CATEGORY_UNI_NOT_SPACE:
+        return !SRE_UNI_IS_SPACE(ch);
+    case SRE_CATEGORY_UNI_WORD:
+        return SRE_UNI_IS_WORD(ch);
+    case SRE_CATEGORY_UNI_NOT_WORD:
+        return !SRE_UNI_IS_WORD(ch);
+    case SRE_CATEGORY_UNI_LINEBREAK:
+        return SRE_UNI_IS_LINEBREAK(ch);
+    case SRE_CATEGORY_UNI_NOT_LINEBREAK:
+        return !SRE_UNI_IS_LINEBREAK(ch);
+#else
+    case SRE_CATEGORY_UNI_DIGIT:
+        return SRE_IS_DIGIT(ch);
+    case SRE_CATEGORY_UNI_NOT_DIGIT:
+        return !SRE_IS_DIGIT(ch);
+    case SRE_CATEGORY_UNI_SPACE:
+        return SRE_IS_SPACE(ch);
+    case SRE_CATEGORY_UNI_NOT_SPACE:
+        return !SRE_IS_SPACE(ch);
+    case SRE_CATEGORY_UNI_WORD:
+        return SRE_LOC_IS_WORD(ch);
+    case SRE_CATEGORY_UNI_NOT_WORD:
+        return !SRE_LOC_IS_WORD(ch);
+    case SRE_CATEGORY_UNI_LINEBREAK:
+        return SRE_IS_LINEBREAK(ch);
+    case SRE_CATEGORY_UNI_NOT_LINEBREAK:
+        return !SRE_IS_LINEBREAK(ch);
+#endif
+    }
+    return 0;
+}
+
+/* helpers */
+
+static void
+data_stack_dealloc(SRE_STATE* state)
+{
+    if (state->data_stack) {
+        PyMem_FREE(state->data_stack);
+        state->data_stack = NULL;
+    }
+    state->data_stack_size = state->data_stack_base = 0;
+}
+
+static int
+data_stack_grow(SRE_STATE* state, Py_ssize_t size)
+{
+    Py_ssize_t minsize, cursize;
+    minsize = state->data_stack_base+size;
+    cursize = state->data_stack_size;
+    if (cursize < minsize) {
+        void* stack;
+        cursize = minsize+minsize/4+1024;
+        TRACE(("allocate/grow stack %d\n", cursize));
+        stack = PyMem_REALLOC(state->data_stack, cursize);
+        if (!stack) {
+            data_stack_dealloc(state);
+            return SRE_ERROR_MEMORY;
+        }
+        state->data_stack = (char *)stack;
+        state->data_stack_size = cursize;
+    }
+    return 0;
+}
+
+/* generate 8-bit version */
+
+#define SRE_CHAR unsigned char
+#define SRE_AT sre_at
+#define SRE_COUNT sre_count
+#define SRE_CHARSET sre_charset
+#define SRE_INFO sre_info
+#define SRE_MATCH sre_match
+#define SRE_MATCH_CONTEXT sre_match_context
+#define SRE_SEARCH sre_search
+#define SRE_LITERAL_TEMPLATE sre_literal_template
+
+#if defined(HAVE_UNICODE)
+
+#define SRE_RECURSIVE
+#include "_sre.c"
+#undef SRE_RECURSIVE
+
+#undef SRE_LITERAL_TEMPLATE
+#undef SRE_SEARCH
+#undef SRE_MATCH
+#undef SRE_MATCH_CONTEXT
+#undef SRE_INFO
+#undef SRE_CHARSET
+#undef SRE_COUNT
+#undef SRE_AT
+#undef SRE_CHAR
+
+/* generate 16-bit unicode version */
+
+#define SRE_CHAR Py_UNICODE
+#define SRE_AT sre_uat
+#define SRE_COUNT sre_ucount
+#define SRE_CHARSET sre_ucharset
+#define SRE_INFO sre_uinfo
+#define SRE_MATCH sre_umatch
+#define SRE_MATCH_CONTEXT sre_umatch_context
+#define SRE_SEARCH sre_usearch
+#define SRE_LITERAL_TEMPLATE sre_uliteral_template
+#endif
+
+#endif /* SRE_RECURSIVE */
+
+/* -------------------------------------------------------------------- */
+/* String matching engine */
+
+/* the following section is compiled twice, with different character
+   settings */
+
+LOCAL(int)
+SRE_AT(SRE_STATE* state, SRE_CHAR* ptr, SRE_CODE at)
+{
+    /* check if pointer is at given position */
+
+    Py_ssize_t thisp, thatp;
+
+    switch (at) {
+
+    case SRE_AT_BEGINNING:
+    case SRE_AT_BEGINNING_STRING:
+        return ((void*) ptr == state->beginning);
+
+    case SRE_AT_BEGINNING_LINE:
+        return ((void*) ptr == state->beginning ||
+                SRE_IS_LINEBREAK((int) ptr[-1]));
+
+    case SRE_AT_END:
+        return (((void*) (ptr+1) == state->end &&
+                 SRE_IS_LINEBREAK((int) ptr[0])) ||
+                ((void*) ptr == state->end));
+
+    case SRE_AT_END_LINE:
+        return ((void*) ptr == state->end ||
+                SRE_IS_LINEBREAK((int) ptr[0]));
+
+    case SRE_AT_END_STRING:
+        return ((void*) ptr == state->end);
+
+    case SRE_AT_BOUNDARY:
+        if (state->beginning == state->end)
+            return 0;
+        thatp = ((void*) ptr > state->beginning) ?
+            SRE_IS_WORD((int) ptr[-1]) : 0;
+        thisp = ((void*) ptr < state->end) ?
+            SRE_IS_WORD((int) ptr[0]) : 0;
+        return thisp != thatp;
+
+    case SRE_AT_NON_BOUNDARY:
+        if (state->beginning == state->end)
+            return 0;
+        thatp = ((void*) ptr > state->beginning) ?
+            SRE_IS_WORD((int) ptr[-1]) : 0;
+        thisp = ((void*) ptr < state->end) ?
+            SRE_IS_WORD((int) ptr[0]) : 0;
+        return thisp == thatp;
+
+    case SRE_AT_LOC_BOUNDARY:
+        if (state->beginning == state->end)
+            return 0;
+        thatp = ((void*) ptr > state->beginning) ?
+            SRE_LOC_IS_WORD((int) ptr[-1]) : 0;
+        thisp = ((void*) ptr < state->end) ?
+            SRE_LOC_IS_WORD((int) ptr[0]) : 0;
+        return thisp != thatp;
+
+    case SRE_AT_LOC_NON_BOUNDARY:
+        if (state->beginning == state->end)
+            return 0;
+        thatp = ((void*) ptr > state->beginning) ?
+            SRE_LOC_IS_WORD((int) ptr[-1]) : 0;
+        thisp = ((void*) ptr < state->end) ?
+            SRE_LOC_IS_WORD((int) ptr[0]) : 0;
+        return thisp == thatp;
+
+#if defined(HAVE_UNICODE)
+    case SRE_AT_UNI_BOUNDARY:
+        if (state->beginning == state->end)
+            return 0;
+        thatp = ((void*) ptr > state->beginning) ?
+            SRE_UNI_IS_WORD((int) ptr[-1]) : 0;
+        thisp = ((void*) ptr < state->end) ?
+            SRE_UNI_IS_WORD((int) ptr[0]) : 0;
+        return thisp != thatp;
+
+    case SRE_AT_UNI_NON_BOUNDARY:
+        if (state->beginning == state->end)
+            return 0;
+        thatp = ((void*) ptr > state->beginning) ?
+            SRE_UNI_IS_WORD((int) ptr[-1]) : 0;
+        thisp = ((void*) ptr < state->end) ?
+            SRE_UNI_IS_WORD((int) ptr[0]) : 0;
+        return thisp == thatp;
+#endif
+
+    }
+
+    return 0;
+}
+
+LOCAL(int)
+SRE_CHARSET(SRE_CODE* set, SRE_CODE ch)
+{
+    /* check if character is a member of the given set */
+
+    int ok = 1;
+
+    for (;;) {
+        switch (*set++) {
+
+        case SRE_OP_FAILURE:
+            return !ok;
+
+        case SRE_OP_LITERAL:
+            /* <LITERAL> <code> */
+            if (ch == set[0])
+                return ok;
+            set++;
+            break;
+
+        case SRE_OP_CATEGORY:
+            /* <CATEGORY> <code> */
+            if (sre_category(set[0], (int) ch))
+                return ok;
+            set += 1;
+            break;
+
+        case SRE_OP_CHARSET:
+            if (sizeof(SRE_CODE) == 2) {
+                /* <CHARSET> <bitmap> (16 bits per code word) */
+                if (ch < 256 && (set[ch >> 4] & (1 << (ch & 15))))
+                    return ok;
+                set += 16;
+            }
+            else {
+                /* <CHARSET> <bitmap> (32 bits per code word) */
+                if (ch < 256 && (set[ch >> 5] & (1 << (ch & 31))))
+                    return ok;
+                set += 8;
+            }
+            break;
+
+        case SRE_OP_RANGE:
+            /* <RANGE> <lower> <upper> */
+            if (set[0] <= ch && ch <= set[1])
+                return ok;
+            set += 2;
+            break;
+
+        case SRE_OP_NEGATE:
+            ok = !ok;
+            break;
+
+        case SRE_OP_BIGCHARSET:
+            /* <BIGCHARSET> <blockcount> <256 blockindices> <blocks> */
+        {
+            Py_ssize_t count, block;
+            count = *(set++);
+
+            if (sizeof(SRE_CODE) == 2) {
+                block = ((unsigned char*)set)[ch >> 8];
+                set += 128;
+                if (set[block*16 + ((ch & 255)>>4)] & (1 << (ch & 15)))
+                    return ok;
+                set += count*16;
+            }
+            else {
+                /* !(c & ~N) == (c < N+1) for any unsigned c, this avoids
+                 * warnings when c's type supports only numbers < N+1 */
+                if (!(ch & ~65535))
+                    block = ((unsigned char*)set)[ch >> 8];
+                else
+                    block = -1;
+                set += 64;
+                if (block >=0 &&
+                    (set[block*8 + ((ch & 255)>>5)] & (1 << (ch & 31))))
+                    return ok;
+                set += count*8;
+            }
+            break;
+        }
+
+        default:
+            /* internal error -- there's not much we can do about it
+               here, so let's just pretend it didn't match... */
+            return 0;
+        }
+    }
+}
+
+LOCAL(Py_ssize_t) SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern);
+
+LOCAL(Py_ssize_t)
+SRE_COUNT(SRE_STATE* state, SRE_CODE* pattern, Py_ssize_t maxcount)
+{
+    SRE_CODE chr;
+    SRE_CHAR* ptr = (SRE_CHAR *)state->ptr;
+    SRE_CHAR* end = (SRE_CHAR *)state->end;
+    Py_ssize_t i;
+
+    /* adjust end */
+    if (maxcount < end - ptr && maxcount != 65535)
+        end = ptr + maxcount;
+
+    switch (pattern[0]) {
+
+    case SRE_OP_IN:
+        /* repeated set */
+        TRACE(("|%p|%p|COUNT IN\n", pattern, ptr));
+        while (ptr < end && SRE_CHARSET(pattern + 2, *ptr))
+            ptr++;
+        break;
+
+    case SRE_OP_ANY:
+        /* repeated dot wildcard. */
+        TRACE(("|%p|%p|COUNT ANY\n", pattern, ptr));
+        while (ptr < end && !SRE_IS_LINEBREAK(*ptr))
+            ptr++;
+        break;
+
+    case SRE_OP_ANY_ALL:
+        /* repeated dot wildcard.  skip to the end of the target
+           string, and backtrack from there */
+        TRACE(("|%p|%p|COUNT ANY_ALL\n", pattern, ptr));
+        ptr = end;
+        break;
+
+    case SRE_OP_LITERAL:
+        /* repeated literal */
+        chr = pattern[1];
+        TRACE(("|%p|%p|COUNT LITERAL %d\n", pattern, ptr, chr));
+        while (ptr < end && (SRE_CODE) *ptr == chr)
+            ptr++;
+        break;
+
+    case SRE_OP_LITERAL_IGNORE:
+        /* repeated literal */
+        chr = pattern[1];
+        TRACE(("|%p|%p|COUNT LITERAL_IGNORE %d\n", pattern, ptr, chr));
+        while (ptr < end && (SRE_CODE) state->lower(*ptr) == chr)
+            ptr++;
+        break;
+
+    case SRE_OP_NOT_LITERAL:
+        /* repeated non-literal */
+        chr = pattern[1];
+        TRACE(("|%p|%p|COUNT NOT_LITERAL %d\n", pattern, ptr, chr));
+        while (ptr < end && (SRE_CODE) *ptr != chr)
+            ptr++;
+        break;
+
+    case SRE_OP_NOT_LITERAL_IGNORE:
+        /* repeated non-literal */
+        chr = pattern[1];
+        TRACE(("|%p|%p|COUNT NOT_LITERAL_IGNORE %d\n", pattern, ptr, chr));
+        while (ptr < end && (SRE_CODE) state->lower(*ptr) != chr)
+            ptr++;
+        break;
+
+    default:
+        /* repeated single character pattern */
+        TRACE(("|%p|%p|COUNT SUBPATTERN\n", pattern, ptr));
+        while ((SRE_CHAR*) state->ptr < end) {
+            i = SRE_MATCH(state, pattern);
+            if (i < 0)
+                return i;
+            if (!i)
+                break;
+        }
+        TRACE(("|%p|%p|COUNT %d\n", pattern, ptr,
+               (SRE_CHAR*) state->ptr - ptr));
+        return (SRE_CHAR*) state->ptr - ptr;
+    }
+
+    TRACE(("|%p|%p|COUNT %d\n", pattern, ptr, ptr - (SRE_CHAR*) state->ptr));
+    return ptr - (SRE_CHAR*) state->ptr;
+}
+
+#if 0 /* not used in this release */
+LOCAL(int)
+SRE_INFO(SRE_STATE* state, SRE_CODE* pattern)
+{
+    /* check if an SRE_OP_INFO block matches at the current position.
+       returns the number of SRE_CODE objects to skip if successful, 0
+       if no match */
+
+    SRE_CHAR* end = state->end;
+    SRE_CHAR* ptr = state->ptr;
+    Py_ssize_t i;
+
+    /* check minimal length */
+    if (pattern[3] && (end - ptr) < pattern[3])
+        return 0;
+
+    /* check known prefix */
+    if (pattern[2] & SRE_INFO_PREFIX && pattern[5] > 1) {
+        /* <length> <skip> <prefix data> <overlap data> */
+        for (i = 0; i < pattern[5]; i++)
+            if ((SRE_CODE) ptr[i] != pattern[7 + i])
+                return 0;
+        return pattern[0] + 2 * pattern[6];
+    }
+    return pattern[0];
+}
+#endif
+
+/* The macros below should be used to protect recursive SRE_MATCH()
+ * calls that *failed* and do *not* return immediately (IOW, those
+ * that will backtrack). Explaining:
+ *
+ * - Recursive SRE_MATCH() returned true: that's usually a success
+ *   (besides atypical cases like ASSERT_NOT), therefore there's no
+ *   reason to restore lastmark;
+ *
+ * - Recursive SRE_MATCH() returned false but the current SRE_MATCH()
+ *   is returning to the caller: If the current SRE_MATCH() is the
+ *   top function of the recursion, returning false will be a matching
+ *   failure, and it doesn't matter where lastmark is pointing to.
+ *   If it's *not* the top function, it will be a recursive SRE_MATCH()
+ *   failure by itself, and the calling SRE_MATCH() will have to deal
+ *   with the failure by the same rules explained here (it will restore
+ *   lastmark by itself if necessary);
+ *
+ * - Recursive SRE_MATCH() returned false, and will continue the
+ *   outside 'for' loop: must be protected when breaking, since the next
+ *   OP could potentially depend on lastmark;
+ *
+ * - Recursive SRE_MATCH() returned false, and will be called again
+ *   inside a local for/while loop: must be protected between each
+ *   loop iteration, since the recursive SRE_MATCH() could do anything,
+ *   and could potentially depend on lastmark.
+ *
+ * For more information, check the discussion at SF patch #712900.
+ */
+#define LASTMARK_SAVE()     \
+    do { \
+        ctx->lastmark = state->lastmark; \
+        ctx->lastindex = state->lastindex; \
+    } while (0)
+#define LASTMARK_RESTORE()  \
+    do { \
+        state->lastmark = ctx->lastmark; \
+        state->lastindex = ctx->lastindex; \
+    } while (0)
+
+#define RETURN_ERROR(i) do { return i; } while(0)
+#define RETURN_FAILURE do { ret = 0; goto exit; } while(0)
+#define RETURN_SUCCESS do { ret = 1; goto exit; } while(0)
+
+#define RETURN_ON_ERROR(i) \
+    do { if (i < 0) RETURN_ERROR(i); } while (0)
+#define RETURN_ON_SUCCESS(i) \
+    do { RETURN_ON_ERROR(i); if (i > 0) RETURN_SUCCESS; } while (0)
+#define RETURN_ON_FAILURE(i) \
+    do { RETURN_ON_ERROR(i); if (i == 0) RETURN_FAILURE; } while (0)
+
+#define SFY(x) #x
+
+#define DATA_STACK_ALLOC(state, type, ptr) \
+do { \
+    alloc_pos = state->data_stack_base; \
+    TRACE(("allocating %s in %d (%d)\n", \
+           SFY(type), alloc_pos, sizeof(type))); \
+    if (state->data_stack_size < alloc_pos+sizeof(type)) { \
+        int j = data_stack_grow(state, sizeof(type)); \
+        if (j < 0) return j; \
+        if (ctx_pos != -1) \
+            DATA_STACK_LOOKUP_AT(state, SRE_MATCH_CONTEXT, ctx, ctx_pos); \
+    } \
+    ptr = (type*)(state->data_stack+alloc_pos); \
+    state->data_stack_base += sizeof(type); \
+} while (0)
+
+#define DATA_STACK_LOOKUP_AT(state, type, ptr, pos) \
+do { \
+    TRACE(("looking up %s at %d\n", SFY(type), pos)); \
+    ptr = (type*)(state->data_stack+pos); \
+} while (0)
+
+#define DATA_STACK_PUSH(state, data, size) \
+do { \
+    TRACE(("copy data in %p to %d (%d)\n", \
+           data, state->data_stack_base, size)); \
+    if (state->data_stack_size < state->data_stack_base+size) { \
+        int j = data_stack_grow(state, size); \
+        if (j < 0) return j; \
+        if (ctx_pos != -1) \
+            DATA_STACK_LOOKUP_AT(state, SRE_MATCH_CONTEXT, ctx, ctx_pos); \
+    } \
+    memcpy(state->data_stack+state->data_stack_base, data, size); \
+    state->data_stack_base += size; \
+} while (0)
+
+#define DATA_STACK_POP(state, data, size, discard) \
+do { \
+    TRACE(("copy data to %p from %d (%d)\n", \
+           data, state->data_stack_base-size, size)); \
+    memcpy(data, state->data_stack+state->data_stack_base-size, size); \
+    if (discard) \
+        state->data_stack_base -= size; \
+} while (0)
+
+#define DATA_STACK_POP_DISCARD(state, size) \
+do { \
+    TRACE(("discard data from %d (%d)\n", \
+           state->data_stack_base-size, size)); \
+    state->data_stack_base -= size; \
+} while(0)
+
+#define DATA_PUSH(x) \
+    DATA_STACK_PUSH(state, (x), sizeof(*(x)))
+#define DATA_POP(x) \
+    DATA_STACK_POP(state, (x), sizeof(*(x)), 1)
+#define DATA_POP_DISCARD(x) \
+    DATA_STACK_POP_DISCARD(state, sizeof(*(x)))
+#define DATA_ALLOC(t,p) \
+    DATA_STACK_ALLOC(state, t, p)
+#define DATA_LOOKUP_AT(t,p,pos) \
+    DATA_STACK_LOOKUP_AT(state,t,p,pos)
+
+#define MARK_PUSH(lastmark) \
+    do if (lastmark > 0) { \
+        i = lastmark; /* ctx->lastmark may change if reallocated */ \
+        DATA_STACK_PUSH(state, state->mark, (i+1)*sizeof(void*)); \
+    } while (0)
+#define MARK_POP(lastmark) \
+    do if (lastmark > 0) { \
+        DATA_STACK_POP(state, state->mark, (lastmark+1)*sizeof(void*), 1); \
+    } while (0)
+#define MARK_POP_KEEP(lastmark) \
+    do if (lastmark > 0) { \
+        DATA_STACK_POP(state, state->mark, (lastmark+1)*sizeof(void*), 0); \
+    } while (0)
+#define MARK_POP_DISCARD(lastmark) \
+    do if (lastmark > 0) { \
+        DATA_STACK_POP_DISCARD(state, (lastmark+1)*sizeof(void*)); \
+    } while (0)
+
+#define JUMP_NONE            0
+#define JUMP_MAX_UNTIL_1     1
+#define JUMP_MAX_UNTIL_2     2
+#define JUMP_MAX_UNTIL_3     3
+#define JUMP_MIN_UNTIL_1     4
+#define JUMP_MIN_UNTIL_2     5
+#define JUMP_MIN_UNTIL_3     6
+#define JUMP_REPEAT          7
+#define JUMP_REPEAT_ONE_1    8
+#define JUMP_REPEAT_ONE_2    9
+#define JUMP_MIN_REPEAT_ONE  10
+#define JUMP_BRANCH          11
+#define JUMP_ASSERT          12
+#define JUMP_ASSERT_NOT      13
+
+#define DO_JUMP(jumpvalue, jumplabel, nextpattern) \
+    DATA_ALLOC(SRE_MATCH_CONTEXT, nextctx); \
+    nextctx->last_ctx_pos = ctx_pos; \
+    nextctx->jump = jumpvalue; \
+    nextctx->pattern = nextpattern; \
+    ctx_pos = alloc_pos; \
+    ctx = nextctx; \
+    goto entrance; \
+    jumplabel: \
+    while (0) /* gcc doesn't like labels at end of scopes */ \
+
+typedef struct {
+    Py_ssize_t last_ctx_pos;
+    Py_ssize_t jump;
+    SRE_CHAR* ptr;
+    SRE_CODE* pattern;
+    Py_ssize_t count;
+    Py_ssize_t lastmark;
+    Py_ssize_t lastindex;
+    union {
+        SRE_CODE chr;
+        SRE_REPEAT* rep;
+    } u;
+} SRE_MATCH_CONTEXT;
+
+/* check if string matches the given pattern.  returns <0 for
+   error, 0 for failure, and 1 for success */
+LOCAL(Py_ssize_t)
+SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern)
+{
+    SRE_CHAR* end = (SRE_CHAR *)state->end;
+    Py_ssize_t alloc_pos, ctx_pos = -1;
+    Py_ssize_t i, ret = 0;
+    Py_ssize_t jump;
+
+    SRE_MATCH_CONTEXT* ctx;
+    SRE_MATCH_CONTEXT* nextctx;
+
+    TRACE(("|%p|%p|ENTER\n", pattern, state->ptr));
+
+    DATA_ALLOC(SRE_MATCH_CONTEXT, ctx);
+    ctx->last_ctx_pos = -1;
+    ctx->jump = JUMP_NONE;
+    ctx->pattern = pattern;
+    ctx_pos = alloc_pos;
+
+entrance:
+
+    ctx->ptr = (SRE_CHAR *)state->ptr;
+
+    if (ctx->pattern[0] == SRE_OP_INFO) {
+        /* optimization info block */
+        /* <INFO> <1=skip> <2=flags> <3=min> ... */
+        if (ctx->pattern[3] && (end - ctx->ptr) < ctx->pattern[3]) {
+            TRACE(("reject (got %d chars, need %d)\n",
+                   (end - ctx->ptr), ctx->pattern[3]));
+            RETURN_FAILURE;
+        }
+        ctx->pattern += ctx->pattern[1] + 1;
+    }
+
+    for (;;) {
+
+        switch (*ctx->pattern++) {
+
+        case SRE_OP_MARK:
+            /* set mark */
+            /* <MARK> <gid> */
+            TRACE(("|%p|%p|MARK %d\n", ctx->pattern,
+                   ctx->ptr, ctx->pattern[0]));
+            i = ctx->pattern[0];
+            if (i & 1)
+                state->lastindex = i/2 + 1;
+            if (i > state->lastmark) {
+                /* state->lastmark is the highest valid index in the
+                   state->mark array.  If it is increased by more than 1,
+                   the intervening marks must be set to NULL to signal
+                   that these marks have not been encountered. */
+                Py_ssize_t j = state->lastmark + 1;
+                while (j < i)
+                    state->mark[j++] = NULL;
+                state->lastmark = i;
+            }
+            state->mark[i] = ctx->ptr;
+            ctx->pattern++;
+            break;
+
+        case SRE_OP_LITERAL:
+            /* match literal string */
+            /* <LITERAL> <code> */
+            TRACE(("|%p|%p|LITERAL %d\n", ctx->pattern,
+                   ctx->ptr, *ctx->pattern));
+            if (ctx->ptr >= end || (SRE_CODE) ctx->ptr[0] != ctx->pattern[0])
+                RETURN_FAILURE;
+            ctx->pattern++;
+            ctx->ptr++;
+            break;
+
+        case SRE_OP_NOT_LITERAL:
+            /* match anything that is not literal character */
+            /* <NOT_LITERAL> <code> */
+            TRACE(("|%p|%p|NOT_LITERAL %d\n", ctx->pattern,
+                   ctx->ptr, *ctx->pattern));
+            if (ctx->ptr >= end || (SRE_CODE) ctx->ptr[0] == ctx->pattern[0])
+                RETURN_FAILURE;
+            ctx->pattern++;
+            ctx->ptr++;
+            break;
+
+        case SRE_OP_SUCCESS:
+            /* end of pattern */
+            TRACE(("|%p|%p|SUCCESS\n", ctx->pattern, ctx->ptr));
+            state->ptr = ctx->ptr;
+            RETURN_SUCCESS;
+
+        case SRE_OP_AT:
+            /* match at given position */
+            /* <AT> <code> */
+            TRACE(("|%p|%p|AT %d\n", ctx->pattern, ctx->ptr, *ctx->pattern));
+            if (!SRE_AT(state, ctx->ptr, *ctx->pattern))
+                RETURN_FAILURE;
+            ctx->pattern++;
+            break;
+
+        case SRE_OP_CATEGORY:
+            /* match at given category */
+            /* <CATEGORY> <code> */
+            TRACE(("|%p|%p|CATEGORY %d\n", ctx->pattern,
+                   ctx->ptr, *ctx->pattern));
+            if (ctx->ptr >= end || !sre_category(ctx->pattern[0], ctx->ptr[0]))
+                RETURN_FAILURE;
+            ctx->pattern++;
+            ctx->ptr++;
+            break;
+
+        case SRE_OP_ANY:
+            /* match anything (except a newline) */
+            /* <ANY> */
+            TRACE(("|%p|%p|ANY\n", ctx->pattern, ctx->ptr));
+            if (ctx->ptr >= end || SRE_IS_LINEBREAK(ctx->ptr[0]))
+                RETURN_FAILURE;
+            ctx->ptr++;
+            break;
+
+        case SRE_OP_ANY_ALL:
+            /* match anything */
+            /* <ANY_ALL> */
+            TRACE(("|%p|%p|ANY_ALL\n", ctx->pattern, ctx->ptr));
+            if (ctx->ptr >= end)
+                RETURN_FAILURE;
+            ctx->ptr++;
+            break;
+
+        case SRE_OP_IN:
+            /* match set member (or non_member) */
+            /* <IN> <skip> <set> */
+            TRACE(("|%p|%p|IN\n", ctx->pattern, ctx->ptr));
+            if (ctx->ptr >= end || !SRE_CHARSET(ctx->pattern + 1, *ctx->ptr))
+                RETURN_FAILURE;
+            ctx->pattern += ctx->pattern[0];
+            ctx->ptr++;
+            break;
+
+        case SRE_OP_LITERAL_IGNORE:
+            TRACE(("|%p|%p|LITERAL_IGNORE %d\n",
+                   ctx->pattern, ctx->ptr, ctx->pattern[0]));
+            if (ctx->ptr >= end ||
+                state->lower(*ctx->ptr) != state->lower(*ctx->pattern))
+                RETURN_FAILURE;
+            ctx->pattern++;
+            ctx->ptr++;
+            break;
+
+        case SRE_OP_NOT_LITERAL_IGNORE:
+            TRACE(("|%p|%p|NOT_LITERAL_IGNORE %d\n",
+                   ctx->pattern, ctx->ptr, *ctx->pattern));
+            if (ctx->ptr >= end ||
+                state->lower(*ctx->ptr) == state->lower(*ctx->pattern))
+                RETURN_FAILURE;
+            ctx->pattern++;
+            ctx->ptr++;
+            break;
+
+        case SRE_OP_IN_IGNORE:
+            TRACE(("|%p|%p|IN_IGNORE\n", ctx->pattern, ctx->ptr));
+            if (ctx->ptr >= end
+                || !SRE_CHARSET(ctx->pattern+1,
+                                (SRE_CODE)state->lower(*ctx->ptr)))
+                RETURN_FAILURE;
+            ctx->pattern += ctx->pattern[0];
+            ctx->ptr++;
+            break;
+
+        case SRE_OP_JUMP:
+        case SRE_OP_INFO:
+            /* jump forward */
+            /* <JUMP> <offset> */
+            TRACE(("|%p|%p|JUMP %d\n", ctx->pattern,
+                   ctx->ptr, ctx->pattern[0]));
+            ctx->pattern += ctx->pattern[0];
+            break;
+
+        case SRE_OP_BRANCH:
+            /* alternation */
+            /* <BRANCH> <0=skip> code <JUMP> ... <NULL> */
+            TRACE(("|%p|%p|BRANCH\n", ctx->pattern, ctx->ptr));
+            LASTMARK_SAVE();
+            ctx->u.rep = state->repeat;
+            if (ctx->u.rep)
+                MARK_PUSH(ctx->lastmark);
+            for (; ctx->pattern[0]; ctx->pattern += ctx->pattern[0]) {
+                if (ctx->pattern[1] == SRE_OP_LITERAL &&
+                    (ctx->ptr >= end ||
+                     (SRE_CODE) *ctx->ptr != ctx->pattern[2]))
+                    continue;
+                if (ctx->pattern[1] == SRE_OP_IN &&
+                    (ctx->ptr >= end ||
+                     !SRE_CHARSET(ctx->pattern + 3, (SRE_CODE) *ctx->ptr)))
+                    continue;
+                state->ptr = ctx->ptr;
+                DO_JUMP(JUMP_BRANCH, jump_branch, ctx->pattern+1);
+                if (ret) {
+                    if (ctx->u.rep)
+                        MARK_POP_DISCARD(ctx->lastmark);
+                    RETURN_ON_ERROR(ret);
+                    RETURN_SUCCESS;
+                }
+                if (ctx->u.rep)
+                    MARK_POP_KEEP(ctx->lastmark);
+                LASTMARK_RESTORE();
+            }
+            if (ctx->u.rep)
+                MARK_POP_DISCARD(ctx->lastmark);
+            RETURN_FAILURE;
+
+        case SRE_OP_REPEAT_ONE:
+            /* match repeated sequence (maximizing regexp) */
+
+            /* this operator only works if the repeated item is
+               exactly one character wide, and we're not already
+               collecting backtracking points.  for other cases,
+               use the MAX_REPEAT operator */
+
+            /* <REPEAT_ONE> <skip> <1=min> <2=max> item <SUCCESS> tail */
+
+            TRACE(("|%p|%p|REPEAT_ONE %d %d\n", ctx->pattern, ctx->ptr,
+                   ctx->pattern[1], ctx->pattern[2]));
+
+            if (ctx->ptr + ctx->pattern[1] > end)
+                RETURN_FAILURE; /* cannot match */
+
+            state->ptr = ctx->ptr;
+
+            ret = SRE_COUNT(state, ctx->pattern+3, ctx->pattern[2]);
+            RETURN_ON_ERROR(ret);
+            DATA_LOOKUP_AT(SRE_MATCH_CONTEXT, ctx, ctx_pos);
+            ctx->count = ret;
+            ctx->ptr += ctx->count;
+
+            /* when we arrive here, count contains the number of
+               matches, and ctx->ptr points to the tail of the target
+               string.  check if the rest of the pattern matches,
+               and backtrack if not. */
+
+            if (ctx->count < (Py_ssize_t) ctx->pattern[1])
+                RETURN_FAILURE;
+
+            if (ctx->pattern[ctx->pattern[0]] == SRE_OP_SUCCESS) {
+                /* tail is empty.  we're finished */
+                state->ptr = ctx->ptr;
+                RETURN_SUCCESS;
+            }
+
+            LASTMARK_SAVE();
+
+            if (ctx->pattern[ctx->pattern[0]] == SRE_OP_LITERAL) {
+                /* tail starts with a literal. skip positions where
+                   the rest of the pattern cannot possibly match */
+                ctx->u.chr = ctx->pattern[ctx->pattern[0]+1];
+                for (;;) {
+                    while (ctx->count >= (Py_ssize_t) ctx->pattern[1] &&
+                           (ctx->ptr >= end || *ctx->ptr != ctx->u.chr)) {
+                        ctx->ptr--;
+                        ctx->count--;
+                    }
+                    if (ctx->count < (Py_ssize_t) ctx->pattern[1])
+                        break;
+                    state->ptr = ctx->ptr;
+                    DO_JUMP(JUMP_REPEAT_ONE_1, jump_repeat_one_1,
+                            ctx->pattern+ctx->pattern[0]);
+                    if (ret) {
+                        RETURN_ON_ERROR(ret);
+                        RETURN_SUCCESS;
+                    }
+
+                    LASTMARK_RESTORE();
+
+                    ctx->ptr--;
+                    ctx->count--;
+                }
+
+            } else {
+                /* general case */
+                while (ctx->count >= (Py_ssize_t) ctx->pattern[1]) {
+                    state->ptr = ctx->ptr;
+                    DO_JUMP(JUMP_REPEAT_ONE_2, jump_repeat_one_2,
+                            ctx->pattern+ctx->pattern[0]);
+                    if (ret) {
+                        RETURN_ON_ERROR(ret);
+                        RETURN_SUCCESS;
+                    }
+                    ctx->ptr--;
+                    ctx->count--;
+                    LASTMARK_RESTORE();
+                }
+            }
+            RETURN_FAILURE;
+
+        case SRE_OP_MIN_REPEAT_ONE:
+            /* match repeated sequence (minimizing regexp) */
+
+            /* this operator only works if the repeated item is
+               exactly one character wide, and we're not already
+               collecting backtracking points.  for other cases,
+               use the MIN_REPEAT operator */
+
+            /* <MIN_REPEAT_ONE> <skip> <1=min> <2=max> item <SUCCESS> tail */
+
+            TRACE(("|%p|%p|MIN_REPEAT_ONE %d %d\n", ctx->pattern, ctx->ptr,
+                   ctx->pattern[1], ctx->pattern[2]));
+
+            if (ctx->ptr + ctx->pattern[1] > end)
+                RETURN_FAILURE; /* cannot match */
+
+            state->ptr = ctx->ptr;
+
+            if (ctx->pattern[1] == 0)
+                ctx->count = 0;
+            else {
+                /* count using pattern min as the maximum */
+                ret = SRE_COUNT(state, ctx->pattern+3, ctx->pattern[1]);
+                RETURN_ON_ERROR(ret);
+                DATA_LOOKUP_AT(SRE_MATCH_CONTEXT, ctx, ctx_pos);
+                if (ret < (Py_ssize_t) ctx->pattern[1])
+                    /* didn't match minimum number of times */
+                    RETURN_FAILURE;
+                /* advance past minimum matches of repeat */
+                ctx->count = ret;
+                ctx->ptr += ctx->count;
+            }
+
+            if (ctx->pattern[ctx->pattern[0]] == SRE_OP_SUCCESS) {
+                /* tail is empty.  we're finished */
+                state->ptr = ctx->ptr;
+                RETURN_SUCCESS;
+
+            } else {
+                /* general case */
+                LASTMARK_SAVE();
+                while ((Py_ssize_t)ctx->pattern[2] == 65535
+                       || ctx->count <= (Py_ssize_t)ctx->pattern[2]) {
+                    state->ptr = ctx->ptr;
+                    DO_JUMP(JUMP_MIN_REPEAT_ONE,jump_min_repeat_one,
+                            ctx->pattern+ctx->pattern[0]);
+                    if (ret) {
+                        RETURN_ON_ERROR(ret);
+                        RETURN_SUCCESS;
+                    }
+                    state->ptr = ctx->ptr;
+                    ret = SRE_COUNT(state, ctx->pattern+3, 1);
+                    RETURN_ON_ERROR(ret);
+                    DATA_LOOKUP_AT(SRE_MATCH_CONTEXT, ctx, ctx_pos);
+                    if (ret == 0)
+                        break;
+                    assert(ret == 1);
+                    ctx->ptr++;
+                    ctx->count++;
+                    LASTMARK_RESTORE();
+                }
+            }
+            RETURN_FAILURE;
+
+        case SRE_OP_REPEAT:
+            /* create repeat context.  all the hard work is done
+               by the UNTIL operator (MAX_UNTIL, MIN_UNTIL) */
+            /* <REPEAT> <skip> <1=min> <2=max> item <UNTIL> tail */
+            TRACE(("|%p|%p|REPEAT %d %d\n", ctx->pattern, ctx->ptr,
+                   ctx->pattern[1], ctx->pattern[2]));
+
+            /* install new repeat context */
+            ctx->u.rep = (SRE_REPEAT*) PyObject_MALLOC(sizeof(*ctx->u.rep));
+            if (!ctx->u.rep) {
+                PyErr_NoMemory();
+                RETURN_FAILURE;
+            }
+            ctx->u.rep->count = -1;
+            ctx->u.rep->pattern = ctx->pattern;
+            ctx->u.rep->prev = state->repeat;
+            ctx->u.rep->last_ptr = NULL;
+            state->repeat = ctx->u.rep;
+
+            state->ptr = ctx->ptr;
+            DO_JUMP(JUMP_REPEAT, jump_repeat, ctx->pattern+ctx->pattern[0]);
+            state->repeat = ctx->u.rep->prev;
+            PyObject_FREE(ctx->u.rep);
+
+            if (ret) {
+                RETURN_ON_ERROR(ret);
+                RETURN_SUCCESS;
+            }
+            RETURN_FAILURE;
+
+        case SRE_OP_MAX_UNTIL:
+            /* maximizing repeat */
+            /* <REPEAT> <skip> <1=min> <2=max> item <MAX_UNTIL> tail */
+
+            /* FIXME: we probably need to deal with zero-width
+               matches in here... */
+
+            ctx->u.rep = state->repeat;
+            if (!ctx->u.rep)
+                RETURN_ERROR(SRE_ERROR_STATE);
+
+            state->ptr = ctx->ptr;
+
+            ctx->count = ctx->u.rep->count+1;
+
+            TRACE(("|%p|%p|MAX_UNTIL %d\n", ctx->pattern,
+                   ctx->ptr, ctx->count));
+
+            if (ctx->count < ctx->u.rep->pattern[1]) {
+                /* not enough matches */
+                ctx->u.rep->count = ctx->count;
+                DO_JUMP(JUMP_MAX_UNTIL_1, jump_max_until_1,
+                        ctx->u.rep->pattern+3);
+                if (ret) {
+                    RETURN_ON_ERROR(ret);
+                    RETURN_SUCCESS;
+                }
+                ctx->u.rep->count = ctx->count-1;
+                state->ptr = ctx->ptr;
+                RETURN_FAILURE;
+            }
+
+            if ((ctx->count < ctx->u.rep->pattern[2] ||
+                ctx->u.rep->pattern[2] == 65535) &&
+                state->ptr != ctx->u.rep->last_ptr) {
+                /* we may have enough matches, but if we can
+                   match another item, do so */
+                ctx->u.rep->count = ctx->count;
+                LASTMARK_SAVE();
+                MARK_PUSH(ctx->lastmark);
+                /* zero-width match protection */
+                DATA_PUSH(&ctx->u.rep->last_ptr);
+                ctx->u.rep->last_ptr = state->ptr;
+                DO_JUMP(JUMP_MAX_UNTIL_2, jump_max_until_2,
+                        ctx->u.rep->pattern+3);
+                DATA_POP(&ctx->u.rep->last_ptr);
+                if (ret) {
+                    MARK_POP_DISCARD(ctx->lastmark);
+                    RETURN_ON_ERROR(ret);
+                    RETURN_SUCCESS;
+                }
+                MARK_POP(ctx->lastmark);
+                LASTMARK_RESTORE();
+                ctx->u.rep->count = ctx->count-1;
+                state->ptr = ctx->ptr;
+            }
+
+            /* cannot match more repeated items here.  make sure the
+               tail matches */
+            state->repeat = ctx->u.rep->prev;
+            DO_JUMP(JUMP_MAX_UNTIL_3, jump_max_until_3, ctx->pattern);
+            RETURN_ON_SUCCESS(ret);
+            state->repeat = ctx->u.rep;
+            state->ptr = ctx->ptr;
+            RETURN_FAILURE;
+
+        case SRE_OP_MIN_UNTIL:
+            /* minimizing repeat */
+            /* <REPEAT> <skip> <1=min> <2=max> item <MIN_UNTIL> tail */
+
+            ctx->u.rep = state->repeat;
+            if (!ctx->u.rep)
+                RETURN_ERROR(SRE_ERROR_STATE);
+
+            state->ptr = ctx->ptr;
+
+            ctx->count = ctx->u.rep->count+1;
+
+            TRACE(("|%p|%p|MIN_UNTIL %d %p\n", ctx->pattern,
+                   ctx->ptr, ctx->count, ctx->u.rep->pattern));
+
+            if (ctx->count < ctx->u.rep->pattern[1]) {
+                /* not enough matches */
+                ctx->u.rep->count = ctx->count;
+                DO_JUMP(JUMP_MIN_UNTIL_1, jump_min_until_1,
+                        ctx->u.rep->pattern+3);
+                if (ret) {
+                    RETURN_ON_ERROR(ret);
+                    RETURN_SUCCESS;
+                }
+                ctx->u.rep->count = ctx->count-1;
+                state->ptr = ctx->ptr;
+                RETURN_FAILURE;
+            }
+
+            LASTMARK_SAVE();
+
+            /* see if the tail matches */
+            state->repeat = ctx->u.rep->prev;
+            DO_JUMP(JUMP_MIN_UNTIL_2, jump_min_until_2, ctx->pattern);
+            if (ret) {
+                RETURN_ON_ERROR(ret);
+                RETURN_SUCCESS;
+            }
+
+            state->repeat = ctx->u.rep;
+            state->ptr = ctx->ptr;
+
+            LASTMARK_RESTORE();
+
+            if (ctx->count >= ctx->u.rep->pattern[2]
+                && ctx->u.rep->pattern[2] != 65535)
+                RETURN_FAILURE;
+
+            ctx->u.rep->count = ctx->count;
+            DO_JUMP(JUMP_MIN_UNTIL_3,jump_min_until_3,
+                    ctx->u.rep->pattern+3);
+            if (ret) {
+                RETURN_ON_ERROR(ret);
+                RETURN_SUCCESS;
+            }
+            ctx->u.rep->count = ctx->count-1;
+            state->ptr = ctx->ptr;
+            RETURN_FAILURE;
+
+        case SRE_OP_GROUPREF:
+            /* match backreference */
+            TRACE(("|%p|%p|GROUPREF %d\n", ctx->pattern,
+                   ctx->ptr, ctx->pattern[0]));
+            i = ctx->pattern[0];
+            {
+                Py_ssize_t groupref = i+i;
+                if (groupref >= state->lastmark) {
+                    RETURN_FAILURE;
+                } else {
+                    SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref];
+                    SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1];
+                    if (!p || !e || e < p)
+                        RETURN_FAILURE;
+                    while (p < e) {
+                        if (ctx->ptr >= end || *ctx->ptr != *p)
+                            RETURN_FAILURE;
+                        p++; ctx->ptr++;
+                    }
+                }
+            }
+            ctx->pattern++;
+            break;
+
+        case SRE_OP_GROUPREF_IGNORE:
+            /* match backreference */
+            TRACE(("|%p|%p|GROUPREF_IGNORE %d\n", ctx->pattern,
+                   ctx->ptr, ctx->pattern[0]));
+            i = ctx->pattern[0];
+            {
+                Py_ssize_t groupref = i+i;
+                if (groupref >= state->lastmark) {
+                    RETURN_FAILURE;
+                } else {
+                    SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref];
+                    SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1];
+                    if (!p || !e || e < p)
+                        RETURN_FAILURE;
+                    while (p < e) {
+                        if (ctx->ptr >= end ||
+                            state->lower(*ctx->ptr) != state->lower(*p))
+                            RETURN_FAILURE;
+                        p++; ctx->ptr++;
+                    }
+                }
+            }
+            ctx->pattern++;
+            break;
+
+        case SRE_OP_GROUPREF_EXISTS:
+            TRACE(("|%p|%p|GROUPREF_EXISTS %d\n", ctx->pattern,
+                   ctx->ptr, ctx->pattern[0]));
+            /* <GROUPREF_EXISTS> <group> <skip> codeyes <JUMP> codeno ... */
+            i = ctx->pattern[0];
+            {
+                Py_ssize_t groupref = i+i;
+                if (groupref >= state->lastmark) {
+                    ctx->pattern += ctx->pattern[1];
+                    break;
+                } else {
+                    SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref];
+                    SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1];
+                    if (!p || !e || e < p) {
+                        ctx->pattern += ctx->pattern[1];
+                        break;
+                    }
+                }
+            }
+            ctx->pattern += 2;
+            break;
+
+        case SRE_OP_ASSERT:
+            /* assert subpattern */
+            /* <ASSERT> <skip> <back> <pattern> */
+            TRACE(("|%p|%p|ASSERT %d\n", ctx->pattern,
+                   ctx->ptr, ctx->pattern[1]));
+            state->ptr = ctx->ptr - ctx->pattern[1];
+            if (state->ptr < state->beginning)
+                RETURN_FAILURE;
+            DO_JUMP(JUMP_ASSERT, jump_assert, ctx->pattern+2);
+            RETURN_ON_FAILURE(ret);
+            ctx->pattern += ctx->pattern[0];
+            break;
+
+        case SRE_OP_ASSERT_NOT:
+            /* assert not subpattern */
+            /* <ASSERT_NOT> <skip> <back> <pattern> */
+            TRACE(("|%p|%p|ASSERT_NOT %d\n", ctx->pattern,
+                   ctx->ptr, ctx->pattern[1]));
+            state->ptr = ctx->ptr - ctx->pattern[1];
+            if (state->ptr >= state->beginning) {
+                DO_JUMP(JUMP_ASSERT_NOT, jump_assert_not, ctx->pattern+2);
+                if (ret) {
+                    RETURN_ON_ERROR(ret);
+                    RETURN_FAILURE;
+                }
+            }
+            ctx->pattern += ctx->pattern[0];
+            break;
+
+        case SRE_OP_FAILURE:
+            /* immediate failure */
+            TRACE(("|%p|%p|FAILURE\n", ctx->pattern, ctx->ptr));
+            RETURN_FAILURE;
+
+        default:
+            TRACE(("|%p|%p|UNKNOWN %d\n", ctx->pattern, ctx->ptr,
+                   ctx->pattern[-1]));
+            RETURN_ERROR(SRE_ERROR_ILLEGAL);
+        }
+    }
+
+exit:
+    ctx_pos = ctx->last_ctx_pos;
+    jump = ctx->jump;
+    DATA_POP_DISCARD(ctx);
+    if (ctx_pos == -1)
+        return ret;
+    DATA_LOOKUP_AT(SRE_MATCH_CONTEXT, ctx, ctx_pos);
+
+    switch (jump) {
+        case JUMP_MAX_UNTIL_2:
+            TRACE(("|%p|%p|JUMP_MAX_UNTIL_2\n", ctx->pattern, ctx->ptr));
+            goto jump_max_until_2;
+        case JUMP_MAX_UNTIL_3:
+            TRACE(("|%p|%p|JUMP_MAX_UNTIL_3\n", ctx->pattern, ctx->ptr));
+            goto jump_max_until_3;
+        case JUMP_MIN_UNTIL_2:
+            TRACE(("|%p|%p|JUMP_MIN_UNTIL_2\n", ctx->pattern, ctx->ptr));
+            goto jump_min_until_2;
+        case JUMP_MIN_UNTIL_3:
+            TRACE(("|%p|%p|JUMP_MIN_UNTIL_3\n", ctx->pattern, ctx->ptr));
+            goto jump_min_until_3;
+        case JUMP_BRANCH:
+            TRACE(("|%p|%p|JUMP_BRANCH\n", ctx->pattern, ctx->ptr));
+            goto jump_branch;
+        case JUMP_MAX_UNTIL_1:
+            TRACE(("|%p|%p|JUMP_MAX_UNTIL_1\n", ctx->pattern, ctx->ptr));
+            goto jump_max_until_1;
+        case JUMP_MIN_UNTIL_1:
+            TRACE(("|%p|%p|JUMP_MIN_UNTIL_1\n", ctx->pattern, ctx->ptr));
+            goto jump_min_until_1;
+        case JUMP_REPEAT:
+            TRACE(("|%p|%p|JUMP_REPEAT\n", ctx->pattern, ctx->ptr));
+            goto jump_repeat;
+        case JUMP_REPEAT_ONE_1:
+            TRACE(("|%p|%p|JUMP_REPEAT_ONE_1\n", ctx->pattern, ctx->ptr));
+            goto jump_repeat_one_1;
+        case JUMP_REPEAT_ONE_2:
+            TRACE(("|%p|%p|JUMP_REPEAT_ONE_2\n", ctx->pattern, ctx->ptr));
+            goto jump_repeat_one_2;
+        case JUMP_MIN_REPEAT_ONE:
+            TRACE(("|%p|%p|JUMP_MIN_REPEAT_ONE\n", ctx->pattern, ctx->ptr));
+            goto jump_min_repeat_one;
+        case JUMP_ASSERT:
+            TRACE(("|%p|%p|JUMP_ASSERT\n", ctx->pattern, ctx->ptr));
+            goto jump_assert;
+        case JUMP_ASSERT_NOT:
+            TRACE(("|%p|%p|JUMP_ASSERT_NOT\n", ctx->pattern, ctx->ptr));
+            goto jump_assert_not;
+        case JUMP_NONE:
+            TRACE(("|%p|%p|RETURN %d\n", ctx->pattern, ctx->ptr, ret));
+            break;
+    }
+
+    return ret; /* should never get here */
+}
+
+LOCAL(Py_ssize_t)
+SRE_SEARCH(SRE_STATE* state, SRE_CODE* pattern)
+{
+    SRE_CHAR* ptr = (SRE_CHAR *)state->start;
+    SRE_CHAR* end = (SRE_CHAR *)state->end;
+    Py_ssize_t status = 0;
+    Py_ssize_t prefix_len = 0;
+    Py_ssize_t prefix_skip = 0;
+    SRE_CODE* prefix = NULL;
+    SRE_CODE* charset = NULL;
+    SRE_CODE* overlap = NULL;
+    int flags = 0;
+
+    if (pattern[0] == SRE_OP_INFO) {
+        /* optimization info block */
+        /* <INFO> <1=skip> <2=flags> <3=min> <4=max> <5=prefix info>  */
+
+        flags = pattern[2];
+
+        if (pattern[3] > 1) {
+            /* adjust end point (but make sure we leave at least one
+               character in there, so literal search will work) */
+            end -= pattern[3]-1;
+            if (end <= ptr)
+                end = ptr+1;
+        }
+
+        if (flags & SRE_INFO_PREFIX) {
+            /* pattern starts with a known prefix */
+            /* <length> <skip> <prefix data> <overlap data> */
+            prefix_len = pattern[5];
+            prefix_skip = pattern[6];
+            prefix = pattern + 7;
+            overlap = prefix + prefix_len - 1;
+        } else if (flags & SRE_INFO_CHARSET)
+            /* pattern starts with a character from a known set */
+            /* <charset> */
+            charset = pattern + 5;
+
+        pattern += 1 + pattern[1];
+    }
+
+    TRACE(("prefix = %p %d %d\n", prefix, prefix_len, prefix_skip));
+    TRACE(("charset = %p\n", charset));
+
+#if defined(USE_FAST_SEARCH)
+    if (prefix_len > 1) {
+        /* pattern starts with a known prefix.  use the overlap
+           table to skip forward as fast as we possibly can */
+        Py_ssize_t i = 0;
+        end = (SRE_CHAR *)state->end;
+        while (ptr < end) {
+            for (;;) {
+                if ((SRE_CODE) ptr[0] != prefix[i]) {
+                    if (!i)
+                        break;
+                    else
+                        i = overlap[i];
+                } else {
+                    if (++i == prefix_len) {
+                        /* found a potential match */
+                        TRACE(("|%p|%p|SEARCH SCAN\n", pattern, ptr));
+                        state->start = ptr + 1 - prefix_len;
+                        state->ptr = ptr + 1 - prefix_len + prefix_skip;
+                        if (flags & SRE_INFO_LITERAL)
+                            return 1; /* we got all of it */
+                        status = SRE_MATCH(state, pattern + 2*prefix_skip);
+                        if (status != 0)
+                            return status;
+                        /* close but no cigar -- try again */
+                        i = overlap[i];
+                    }
+                    break;
+                }
+            }
+            ptr++;
+        }
+        return 0;
+    }
+#endif
+
+    if (pattern[0] == SRE_OP_LITERAL) {
+        /* pattern starts with a literal character.  this is used
+           for short prefixes, and if fast search is disabled */
+        SRE_CODE chr = pattern[1];
+        end = (SRE_CHAR *)state->end;
+        for (;;) {
+            while (ptr < end && (SRE_CODE) ptr[0] != chr)
+                ptr++;
+            if (ptr >= end)
+                return 0;
+            TRACE(("|%p|%p|SEARCH LITERAL\n", pattern, ptr));
+            state->start = ptr;
+            state->ptr = ++ptr;
+            if (flags & SRE_INFO_LITERAL)
+                return 1; /* we got all of it */
+            status = SRE_MATCH(state, pattern + 2);
+            if (status != 0)
+                break;
+        }
+    } else if (charset) {
+        /* pattern starts with a character from a known set */
+        end = (SRE_CHAR *)state->end;
+        for (;;) {
+            while (ptr < end && !SRE_CHARSET(charset, ptr[0]))
+                ptr++;
+            if (ptr >= end)
+                return 0;
+            TRACE(("|%p|%p|SEARCH CHARSET\n", pattern, ptr));
+            state->start = ptr;
+            state->ptr = ptr;
+            status = SRE_MATCH(state, pattern);
+            if (status != 0)
+                break;
+            ptr++;
+        }
+    } else
+        /* general case */
+        while (ptr <= end) {
+            TRACE(("|%p|%p|SEARCH\n", pattern, ptr));
+            state->start = state->ptr = ptr++;
+            status = SRE_MATCH(state, pattern);
+            if (status != 0)
+                break;
+        }
+
+    return status;
+}
+
+LOCAL(int)
+SRE_LITERAL_TEMPLATE(SRE_CHAR* ptr, Py_ssize_t len)
+{
+    /* check if given string is a literal template (i.e. no escapes) */
+    while (len-- > 0)
+        if (*ptr++ == '\\')
+            return 0;
+    return 1;
+}
+
+#if !defined(SRE_RECURSIVE)
+
+/* -------------------------------------------------------------------- */
+/* factories and destructors */
+
+/* see sre.h for object declarations */
+static PyObject*pattern_new_match(PatternObject*, SRE_STATE*, int);
+static PyObject*pattern_scanner(PatternObject*, PyObject*);
+
+static PyObject *
+sre_codesize(PyObject* self, PyObject *unused)
+{
+    return Py_BuildValue("l", sizeof(SRE_CODE));
+}
+
+static PyObject *
+sre_getlower(PyObject* self, PyObject* args)
+{
+    int character, flags;
+    if (!PyArg_ParseTuple(args, "ii", &character, &flags))
+        return NULL;
+    if (flags & SRE_FLAG_LOCALE)
+        return Py_BuildValue("i", sre_lower_locale(character));
+    if (flags & SRE_FLAG_UNICODE)
+#if defined(HAVE_UNICODE)
+        return Py_BuildValue("i", sre_lower_unicode(character));
+#else
+        return Py_BuildValue("i", sre_lower_locale(character));
+#endif
+    return Py_BuildValue("i", sre_lower(character));
+}
+
+LOCAL(void)
+state_reset(SRE_STATE* state)
+{
+    /* FIXME: dynamic! */
+    /*memset(state->mark, 0, sizeof(*state->mark) * SRE_MARK_SIZE);*/
+
+    state->lastmark = -1;
+    state->lastindex = -1;
+
+    state->repeat = NULL;
+
+    data_stack_dealloc(state);
+}
+
+static void*
+getstring(PyObject* string, Py_ssize_t* p_length, int* p_charsize)
+{
+    /* given a python object, return a data pointer, a length (in
+       characters), and a character size.  return NULL if the object
+       is not a string (or not compatible) */
+
+    PyBufferProcs *buffer;
+    Py_ssize_t size, bytes;
+    int charsize;
+    void* ptr;
+
+#if defined(HAVE_UNICODE)
+    if (PyUnicode_Check(string)) {
+        /* unicode strings doesn't always support the buffer interface */
+        ptr = (void*) PyUnicode_AS_DATA(string);
+        bytes = PyUnicode_GET_DATA_SIZE(string);
+        size = PyUnicode_GET_SIZE(string);
+        charsize = sizeof(Py_UNICODE);
+
+    } else {
+#endif
+
+    /* get pointer to string buffer */
+    buffer = string->ob_type->tp_as_buffer;
+    if (!buffer || !buffer->bf_getreadbuffer || !buffer->bf_getsegcount ||
+        buffer->bf_getsegcount(string, NULL) != 1) {
+        PyErr_SetString(PyExc_TypeError, "expected string or buffer");
+        return NULL;
+    }
+
+    /* determine buffer size */
+    bytes = buffer->bf_getreadbuffer(string, 0, &ptr);
+    if (bytes < 0) {
+        PyErr_SetString(PyExc_TypeError, "buffer has negative size");
+        return NULL;
+    }
+
+    /* determine character size */
+#if PY_VERSION_HEX >= 0x01060000
+    size = PyObject_Size(string);
+#else
+    size = PyObject_Length(string);
+#endif
+
+    if (PyString_Check(string) || bytes == size)
+        charsize = 1;
+#if defined(HAVE_UNICODE)
+    else if (bytes == (Py_ssize_t) (size * sizeof(Py_UNICODE)))
+        charsize = sizeof(Py_UNICODE);
+#endif
+    else {
+        PyErr_SetString(PyExc_TypeError, "buffer size mismatch");
+        return NULL;
+    }
+
+#if defined(HAVE_UNICODE)
+    }
+#endif
+
+    *p_length = size;
+    *p_charsize = charsize;
+
+    return ptr;
+}
+
+LOCAL(PyObject*)
+state_init(SRE_STATE* state, PatternObject* pattern, PyObject* string,
+           Py_ssize_t start, Py_ssize_t end)
+{
+    /* prepare state object */
+
+    Py_ssize_t length;
+    int charsize;
+    void* ptr;
+
+    memset(state, 0, sizeof(SRE_STATE));
+
+    state->lastmark = -1;
+    state->lastindex = -1;
+
+    ptr = getstring(string, &length, &charsize);
+    if (!ptr)
+        return NULL;
+
+    /* adjust boundaries */
+    if (start < 0)
+        start = 0;
+    else if (start > length)
+        start = length;
+
+    if (end < 0)
+        end = 0;
+    else if (end > length)
+        end = length;
+
+    state->charsize = charsize;
+
+    state->beginning = ptr;
+
+    state->start = (void*) ((char*) ptr + start * state->charsize);
+    state->end = (void*) ((char*) ptr + end * state->charsize);
+
+    Py_INCREF(string);
+    state->string = string;
+    state->pos = start;
+    state->endpos = end;
+
+    if (pattern->flags & SRE_FLAG_LOCALE)
+        state->lower = sre_lower_locale;
+    else if (pattern->flags & SRE_FLAG_UNICODE)
+#if defined(HAVE_UNICODE)
+        state->lower = sre_lower_unicode;
+#else
+        state->lower = sre_lower_locale;
+#endif
+    else
+        state->lower = sre_lower;
+
+    return string;
+}
+
+LOCAL(void)
+state_fini(SRE_STATE* state)
+{
+    Py_XDECREF(state->string);
+    data_stack_dealloc(state);
+}
+
+/* calculate offset from start of string */
+#define STATE_OFFSET(state, member)\
+    (((char*)(member) - (char*)(state)->beginning) / (state)->charsize)
+
+LOCAL(PyObject*)
+state_getslice(SRE_STATE* state, Py_ssize_t index, PyObject* string, int empty)
+{
+    Py_ssize_t i, j;
+
+    index = (index - 1) * 2;
+
+    if (string == Py_None || index >= state->lastmark || !state->mark[index] || !state->mark[index+1]) {
+        if (empty)
+            /* want empty string */
+            i = j = 0;
+        else {
+            Py_INCREF(Py_None);
+            return Py_None;
+        }
+    } else {
+        i = STATE_OFFSET(state, state->mark[index]);
+        j = STATE_OFFSET(state, state->mark[index+1]);
+    }
+
+    return PySequence_GetSlice(string, i, j);
+}
+
+static void
+pattern_error(int status)
+{
+    switch (status) {
+    case SRE_ERROR_RECURSION_LIMIT:
+        PyErr_SetString(
+            PyExc_RuntimeError,
+            "maximum recursion limit exceeded"
+            );
+        break;
+    case SRE_ERROR_MEMORY:
+        PyErr_NoMemory();
+        break;
+    default:
+        /* other error codes indicate compiler/engine bugs */
+        PyErr_SetString(
+            PyExc_RuntimeError,
+            "internal error in regular expression engine"
+            );
+    }
+}
+
+static void
+pattern_dealloc(PatternObject* self)
+{
+    if (self->weakreflist != NULL)
+        PyObject_ClearWeakRefs((PyObject *) self);
+    Py_XDECREF(self->pattern);
+    Py_XDECREF(self->groupindex);
+    Py_XDECREF(self->indexgroup);
+    PyObject_DEL(self);
+}
+
+static PyObject*
+pattern_match(PatternObject* self, PyObject* args, PyObject* kw)
+{
+    SRE_STATE state;
+    int status;
+
+    PyObject* string;
+    Py_ssize_t start = 0;
+    Py_ssize_t end = PY_SSIZE_T_MAX;
+    static char* kwlist[] = { "pattern", "pos", "endpos", NULL };
+    if (!PyArg_ParseTupleAndKeywords(args, kw, "O|nn:match", kwlist,
+                                     &string, &start, &end))
+        return NULL;
+
+    string = state_init(&state, self, string, start, end);
+    if (!string)
+        return NULL;
+
+    state.ptr = state.start;
+
+    TRACE(("|%p|%p|MATCH\n", PatternObject_GetCode(self), state.ptr));
+
+    if (state.charsize == 1) {
+        status = sre_match(&state, PatternObject_GetCode(self));
+    } else {
+#if defined(HAVE_UNICODE)
+        status = sre_umatch(&state, PatternObject_GetCode(self));
+#endif
+    }
+
+    TRACE(("|%p|%p|END\n", PatternObject_GetCode(self), state.ptr));
+    if (PyErr_Occurred())
+        return NULL;
+
+    state_fini(&state);
+
+    return pattern_new_match(self, &state, status);
+}
+
+static PyObject*
+pattern_search(PatternObject* self, PyObject* args, PyObject* kw)
+{
+    SRE_STATE state;
+    int status;
+
+    PyObject* string;
+    Py_ssize_t start = 0;
+    Py_ssize_t end = PY_SSIZE_T_MAX;
+    static char* kwlist[] = { "pattern", "pos", "endpos", NULL };
+    if (!PyArg_ParseTupleAndKeywords(args, kw, "O|nn:search", kwlist,
+                                     &string, &start, &end))
+        return NULL;
+
+    string = state_init(&state, self, string, start, end);
+    if (!string)
+        return NULL;
+
+    TRACE(("|%p|%p|SEARCH\n", PatternObject_GetCode(self), state.ptr));
+
+    if (state.charsize == 1) {
+        status = sre_search(&state, PatternObject_GetCode(self));
+    } else {
+#if defined(HAVE_UNICODE)
+        status = sre_usearch(&state, PatternObject_GetCode(self));
+#endif
+    }
+
+    TRACE(("|%p|%p|END\n", PatternObject_GetCode(self), state.ptr));
+
+    state_fini(&state);
+
+    if (PyErr_Occurred())
+        return NULL;
+
+    return pattern_new_match(self, &state, status);
+}
+
+static PyObject*
+call(char* module, char* function, PyObject* args)
+{
+    PyObject* name;
+    PyObject* mod;
+    PyObject* func;
+    PyObject* result;
+
+    if (!args)
+        return NULL;
+    name = PyString_FromString(module);
+    if (!name)
+        return NULL;
+    mod = PyImport_Import(name);
+    Py_DECREF(name);
+    if (!mod)
+        return NULL;
+    func = PyObject_GetAttrString(mod, function);
+    Py_DECREF(mod);
+    if (!func)
+        return NULL;
+    result = PyObject_CallObject(func, args);
+    Py_DECREF(func);
+    Py_DECREF(args);
+    return result;
+}
+
+#ifdef USE_BUILTIN_COPY
+static int
+deepcopy(PyObject** object, PyObject* memo)
+{
+    PyObject* copy;
+
+    copy = call(
+        "copy", "deepcopy",
+        PyTuple_Pack(2, *object, memo)
+        );
+    if (!copy)
+        return 0;
+
+    Py_DECREF(*object);
+    *object = copy;
+
+    return 1; /* success */
+}
+#endif
+
+static PyObject*
+join_list(PyObject* list, PyObject* pattern)
+{
+    /* join list elements */
+
+    PyObject* joiner;
+#if PY_VERSION_HEX >= 0x01060000
+    PyObject* function;
+    PyObject* args;
+#endif
+    PyObject* result;
+
+    switch (PyList_GET_SIZE(list)) {
+    case 0:
+        Py_DECREF(list);
+        return PySequence_GetSlice(pattern, 0, 0);
+    case 1:
+        result = PyList_GET_ITEM(list, 0);
+        Py_INCREF(result);
+        Py_DECREF(list);
+        return result;
+    }
+
+    /* two or more elements: slice out a suitable separator from the
+       first member, and use that to join the entire list */
+
+    joiner = PySequence_GetSlice(pattern, 0, 0);
+    if (!joiner)
+        return NULL;
+
+#if PY_VERSION_HEX >= 0x01060000
+    function = PyObject_GetAttrString(joiner, "join");
+    if (!function) {
+        Py_DECREF(joiner);
+        return NULL;
+    }
+    args = PyTuple_New(1);
+    if (!args) {
+        Py_DECREF(function);
+        Py_DECREF(joiner);
+        return NULL;
+    }
+    PyTuple_SET_ITEM(args, 0, list);
+    result = PyObject_CallObject(function, args);
+    Py_DECREF(args); /* also removes list */
+    Py_DECREF(function);
+#else
+    result = call(
+        "string", "join",
+        PyTuple_Pack(2, list, joiner)
+        );
+#endif
+    Py_DECREF(joiner);
+
+    return result;
+}
+
+static PyObject*
+pattern_findall(PatternObject* self, PyObject* args, PyObject* kw)
+{
+    SRE_STATE state;
+    PyObject* list;
+    int status;
+    Py_ssize_t i, b, e;
+
+    PyObject* string;
+    Py_ssize_t start = 0;
+    Py_ssize_t end = PY_SSIZE_T_MAX;
+    static char* kwlist[] = { "source", "pos", "endpos", NULL };
+    if (!PyArg_ParseTupleAndKeywords(args, kw, "O|nn:findall", kwlist,
+                                     &string, &start, &end))
+        return NULL;
+
+    string = state_init(&state, self, string, start, end);
+    if (!string)
+        return NULL;
+
+    list = PyList_New(0);
+    if (!list) {
+        state_fini(&state);
+        return NULL;
+    }
+
+    while (state.start <= state.end) {
+
+        PyObject* item;
+
+        state_reset(&state);
+
+        state.ptr = state.start;
+
+        if (state.charsize == 1) {
+            status = sre_search(&state, PatternObject_GetCode(self));
+        } else {
+#if defined(HAVE_UNICODE)
+            status = sre_usearch(&state, PatternObject_GetCode(self));
+#endif
+        }
+
+	if (PyErr_Occurred())
+	    goto error;
+
+        if (status <= 0) {
+            if (status == 0)
+                break;
+            pattern_error(status);
+            goto error;
+        }
+
+        /* don't bother to build a match object */
+        switch (self->groups) {
+        case 0:
+            b = STATE_OFFSET(&state, state.start);
+            e = STATE_OFFSET(&state, state.ptr);
+            item = PySequence_GetSlice(string, b, e);
+            if (!item)
+                goto error;
+            break;
+        case 1:
+            item = state_getslice(&state, 1, string, 1);
+            if (!item)
+                goto error;
+            break;
+        default:
+            item = PyTuple_New(self->groups);
+            if (!item)
+                goto error;
+            for (i = 0; i < self->groups; i++) {
+                PyObject* o = state_getslice(&state, i+1, string, 1);
+                if (!o) {
+                    Py_DECREF(item);
+                    goto error;
+                }
+                PyTuple_SET_ITEM(item, i, o);
+            }
+            break;
+        }
+
+        status = PyList_Append(list, item);
+        Py_DECREF(item);
+        if (status < 0)
+            goto error;
+
+        if (state.ptr == state.start)
+            state.start = (void*) ((char*) state.ptr + state.charsize);
+        else
+            state.start = state.ptr;
+
+    }
+
+    state_fini(&state);
+    return list;
+
+error:
+    Py_DECREF(list);
+    state_fini(&state);
+    return NULL;
+
+}
+
+#if PY_VERSION_HEX >= 0x02020000
+static PyObject*
+pattern_finditer(PatternObject* pattern, PyObject* args)
+{
+    PyObject* scanner;
+    PyObject* search;
+    PyObject* iterator;
+
+    scanner = pattern_scanner(pattern, args);
+    if (!scanner)
+        return NULL;
+
+    search = PyObject_GetAttrString(scanner, "search");
+    Py_DECREF(scanner);
+    if (!search)
+        return NULL;
+
+    iterator = PyCallIter_New(search, Py_None);
+    Py_DECREF(search);
+
+    return iterator;
+}
+#endif
+
+static PyObject*
+pattern_split(PatternObject* self, PyObject* args, PyObject* kw)
+{
+    SRE_STATE state;
+    PyObject* list;
+    PyObject* item;
+    int status;
+    Py_ssize_t n;
+    Py_ssize_t i;
+    void* last;
+
+    PyObject* string;
+    Py_ssize_t maxsplit = 0;
+    static char* kwlist[] = { "source", "maxsplit", NULL };
+    if (!PyArg_ParseTupleAndKeywords(args, kw, "O|n:split", kwlist,
+                                     &string, &maxsplit))
+        return NULL;
+
+    string = state_init(&state, self, string, 0, PY_SSIZE_T_MAX);
+    if (!string)
+        return NULL;
+
+    list = PyList_New(0);
+    if (!list) {
+        state_fini(&state);
+        return NULL;
+    }
+
+    n = 0;
+    last = state.start;
+
+    while (!maxsplit || n < maxsplit) {
+
+        state_reset(&state);
+
+        state.ptr = state.start;
+
+        if (state.charsize == 1) {
+            status = sre_search(&state, PatternObject_GetCode(self));
+        } else {
+#if defined(HAVE_UNICODE)
+            status = sre_usearch(&state, PatternObject_GetCode(self));
+#endif
+        }
+
+	if (PyErr_Occurred())
+	    goto error;
+
+        if (status <= 0) {
+            if (status == 0)
+                break;
+            pattern_error(status);
+            goto error;
+        }
+
+        if (state.start == state.ptr) {
+            if (last == state.end)
+                break;
+            /* skip one character */
+            state.start = (void*) ((char*) state.ptr + state.charsize);
+            continue;
+        }
+
+        /* get segment before this match */
+        item = PySequence_GetSlice(
+            string, STATE_OFFSET(&state, last),
+            STATE_OFFSET(&state, state.start)
+            );
+        if (!item)
+            goto error;
+        status = PyList_Append(list, item);
+        Py_DECREF(item);
+        if (status < 0)
+            goto error;
+
+        /* add groups (if any) */
+        for (i = 0; i < self->groups; i++) {
+            item = state_getslice(&state, i+1, string, 0);
+            if (!item)
+                goto error;
+            status = PyList_Append(list, item);
+            Py_DECREF(item);
+            if (status < 0)
+                goto error;
+        }
+
+        n = n + 1;
+
+        last = state.start = state.ptr;
+
+    }
+
+    /* get segment following last match (even if empty) */
+    item = PySequence_GetSlice(
+        string, STATE_OFFSET(&state, last), state.endpos
+        );
+    if (!item)
+        goto error;
+    status = PyList_Append(list, item);
+    Py_DECREF(item);
+    if (status < 0)
+        goto error;
+
+    state_fini(&state);
+    return list;
+
+error:
+    Py_DECREF(list);
+    state_fini(&state);
+    return NULL;
+
+}
+
+static PyObject*
+pattern_subx(PatternObject* self, PyObject* ptemplate, PyObject* string,
+             Py_ssize_t count, Py_ssize_t subn)
+{
+    SRE_STATE state;
+    PyObject* list;
+    PyObject* item;
+    PyObject* filter;
+    PyObject* args;
+    PyObject* match;
+    void* ptr;
+    int status;
+    Py_ssize_t n;
+    Py_ssize_t i, b, e;
+    int bint;
+    int filter_is_callable;
+
+    if (PyCallable_Check(ptemplate)) {
+        /* sub/subn takes either a function or a template */
+        filter = ptemplate;
+        Py_INCREF(filter);
+        filter_is_callable = 1;
+    } else {
+        /* if not callable, check if it's a literal string */
+        int literal;
+        ptr = getstring(ptemplate, &n, &bint);
+        b = bint;
+        if (ptr) {
+            if (b == 1) {
+		    literal = sre_literal_template((unsigned char *)ptr, n);
+            } else {
+#if defined(HAVE_UNICODE)
+		    literal = sre_uliteral_template((Py_UNICODE *)ptr, n);
+#endif
+            }
+        } else {
+            PyErr_Clear();
+            literal = 0;
+        }
+        if (literal) {
+            filter = ptemplate;
+            Py_INCREF(filter);
+            filter_is_callable = 0;
+        } else {
+            /* not a literal; hand it over to the template compiler */
+            filter = call(
+                SRE_PY_MODULE, "_subx",
+                PyTuple_Pack(2, self, ptemplate)
+                );
+            if (!filter)
+                return NULL;
+            filter_is_callable = PyCallable_Check(filter);
+        }
+    }
+
+    string = state_init(&state, self, string, 0, PY_SSIZE_T_MAX);
+    if (!string) {
+        Py_DECREF(filter);
+        return NULL;
+    }
+
+    list = PyList_New(0);
+    if (!list) {
+        Py_DECREF(filter);
+        state_fini(&state);
+        return NULL;
+    }
+
+    n = i = 0;
+
+    while (!count || n < count) {
+
+        state_reset(&state);
+
+        state.ptr = state.start;
+
+        if (state.charsize == 1) {
+            status = sre_search(&state, PatternObject_GetCode(self));
+        } else {
+#if defined(HAVE_UNICODE)
+            status = sre_usearch(&state, PatternObject_GetCode(self));
+#endif
+        }
+
+	if (PyErr_Occurred())
+	    goto error;
+
+        if (status <= 0) {
+            if (status == 0)
+                break;
+            pattern_error(status);
+            goto error;
+        }
+
+        b = STATE_OFFSET(&state, state.start);
+        e = STATE_OFFSET(&state, state.ptr);
+
+        if (i < b) {
+            /* get segment before this match */
+            item = PySequence_GetSlice(string, i, b);
+            if (!item)
+                goto error;
+            status = PyList_Append(list, item);
+            Py_DECREF(item);
+            if (status < 0)
+                goto error;
+
+        } else if (i == b && i == e && n > 0)
+            /* ignore empty match on latest position */
+            goto next;
+
+        if (filter_is_callable) {
+            /* pass match object through filter */
+            match = pattern_new_match(self, &state, 1);
+            if (!match)
+                goto error;
+            args = PyTuple_Pack(1, match);
+            if (!args) {
+                Py_DECREF(match);
+                goto error;
+            }
+            item = PyObject_CallObject(filter, args);
+            Py_DECREF(args);
+            Py_DECREF(match);
+            if (!item)
+                goto error;
+        } else {
+            /* filter is literal string */
+            item = filter;
+            Py_INCREF(item);
+        }
+
+        /* add to list */
+        if (item != Py_None) {
+            status = PyList_Append(list, item);
+            Py_DECREF(item);
+            if (status < 0)
+                goto error;
+        }
+
+        i = e;
+        n = n + 1;
+
+next:
+        /* move on */
+        if (state.ptr == state.start)
+            state.start = (void*) ((char*) state.ptr + state.charsize);
+        else
+            state.start = state.ptr;
+
+    }
+
+    /* get segment following last match */
+    if (i < state.endpos) {
+        item = PySequence_GetSlice(string, i, state.endpos);
+        if (!item)
+            goto error;
+        status = PyList_Append(list, item);
+        Py_DECREF(item);
+        if (status < 0)
+            goto error;
+    }
+
+    state_fini(&state);
+
+    Py_DECREF(filter);
+
+    /* convert list to single string (also removes list) */
+    item = join_list(list, self->pattern);
+
+    if (!item)
+        return NULL;
+
+    if (subn)
+        return Py_BuildValue("Ni", item, n);
+
+    return item;
+
+error:
+    Py_DECREF(list);
+    state_fini(&state);
+    Py_DECREF(filter);
+    return NULL;
+
+}
+
+static PyObject*
+pattern_sub(PatternObject* self, PyObject* args, PyObject* kw)
+{
+    PyObject* ptemplate;
+    PyObject* string;
+    Py_ssize_t count = 0;
+    static char* kwlist[] = { "repl", "string", "count", NULL };
+    if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|n:sub", kwlist,
+                                     &ptemplate, &string, &count))
+        return NULL;
+
+    return pattern_subx(self, ptemplate, string, count, 0);
+}
+
+static PyObject*
+pattern_subn(PatternObject* self, PyObject* args, PyObject* kw)
+{
+    PyObject* ptemplate;
+    PyObject* string;
+    Py_ssize_t count = 0;
+    static char* kwlist[] = { "repl", "string", "count", NULL };
+    if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|n:subn", kwlist,
+                                     &ptemplate, &string, &count))
+        return NULL;
+
+    return pattern_subx(self, ptemplate, string, count, 1);
+}
+
+static PyObject*
+pattern_copy(PatternObject* self, PyObject *unused)
+{
+#ifdef USE_BUILTIN_COPY
+    PatternObject* copy;
+    int offset;
+
+    copy = PyObject_NEW_VAR(PatternObject, &Pattern_Type, self->codesize);
+    if (!copy)
+        return NULL;
+
+    offset = offsetof(PatternObject, groups);
+
+    Py_XINCREF(self->groupindex);
+    Py_XINCREF(self->indexgroup);
+    Py_XINCREF(self->pattern);
+
+    memcpy((char*) copy + offset, (char*) self + offset,
+           sizeof(PatternObject) + self->codesize * sizeof(SRE_CODE) - offset);
+    copy->weakreflist = NULL;
+
+    return (PyObject*) copy;
+#else
+    PyErr_SetString(PyExc_TypeError, "cannot copy this pattern object");
+    return NULL;
+#endif
+}
+
+static PyObject*
+pattern_deepcopy(PatternObject* self, PyObject* memo)
+{
+#ifdef USE_BUILTIN_COPY
+    PatternObject* copy;
+
+    copy = (PatternObject*) pattern_copy(self);
+    if (!copy)
+        return NULL;
+
+    if (!deepcopy(&copy->groupindex, memo) ||
+        !deepcopy(&copy->indexgroup, memo) ||
+        !deepcopy(&copy->pattern, memo)) {
+        Py_DECREF(copy);
+        return NULL;
+    }
+
+#else
+    PyErr_SetString(PyExc_TypeError, "cannot deepcopy this pattern object");
+    return NULL;
+#endif
+}
+
+PyDoc_STRVAR(pattern_match_doc,
+"match(string[, pos[, endpos]]) --> match object or None.\n\
+    Matches zero or more characters at the beginning of the string");
+
+PyDoc_STRVAR(pattern_search_doc,
+"search(string[, pos[, endpos]]) --> match object or None.\n\
+    Scan through string looking for a match, and return a corresponding\n\
+    MatchObject instance. Return None if no position in the string matches.");
+
+PyDoc_STRVAR(pattern_split_doc,
+"split(string[, maxsplit = 0])  --> list.\n\
+    Split string by the occurrences of pattern.");
+
+PyDoc_STRVAR(pattern_findall_doc,
+"findall(string[, pos[, endpos]]) --> list.\n\
+   Return a list of all non-overlapping matches of pattern in string.");
+
+PyDoc_STRVAR(pattern_finditer_doc,
+"finditer(string[, pos[, endpos]]) --> iterator.\n\
+    Return an iterator over all non-overlapping matches for the \n\
+    RE pattern in string. For each match, the iterator returns a\n\
+    match object.");
+
+PyDoc_STRVAR(pattern_sub_doc,
+"sub(repl, string[, count = 0]) --> newstring\n\
+    Return the string obtained by replacing the leftmost non-overlapping\n\
+    occurrences of pattern in string by the replacement repl.");
+
+PyDoc_STRVAR(pattern_subn_doc,
+"subn(repl, string[, count = 0]) --> (newstring, number of subs)\n\
+    Return the tuple (new_string, number_of_subs_made) found by replacing\n\
+    the leftmost non-overlapping occurrences of pattern with the\n\
+    replacement repl.");
+
+PyDoc_STRVAR(pattern_doc, "Compiled regular expression objects");
+
+static PyMethodDef pattern_methods[] = {
+    {"match", (PyCFunction) pattern_match, METH_VARARGS|METH_KEYWORDS,
+	pattern_match_doc},
+    {"search", (PyCFunction) pattern_search, METH_VARARGS|METH_KEYWORDS,
+	pattern_search_doc},
+    {"sub", (PyCFunction) pattern_sub, METH_VARARGS|METH_KEYWORDS,
+	pattern_sub_doc},
+    {"subn", (PyCFunction) pattern_subn, METH_VARARGS|METH_KEYWORDS,
+	pattern_subn_doc},
+    {"split", (PyCFunction) pattern_split, METH_VARARGS|METH_KEYWORDS,
+	pattern_split_doc},
+    {"findall", (PyCFunction) pattern_findall, METH_VARARGS|METH_KEYWORDS,
+	pattern_findall_doc},
+#if PY_VERSION_HEX >= 0x02020000
+    {"finditer", (PyCFunction) pattern_finditer, METH_VARARGS,
+	pattern_finditer_doc},
+#endif
+    {"scanner", (PyCFunction) pattern_scanner, METH_VARARGS},
+    {"__copy__", (PyCFunction) pattern_copy, METH_NOARGS},
+    {"__deepcopy__", (PyCFunction) pattern_deepcopy, METH_O},
+    {NULL, NULL}
+};
+
+static PyObject*
+pattern_getattr(PatternObject* self, char* name)
+{
+    PyObject* res;
+
+    res = Py_FindMethod(pattern_methods, (PyObject*) self, name);
+
+    if (res)
+        return res;
+
+    PyErr_Clear();
+
+    /* attributes */
+    if (!strcmp(name, "pattern")) {
+        Py_INCREF(self->pattern);
+        return self->pattern;
+    }
+
+    if (!strcmp(name, "flags"))
+        return Py_BuildValue("i", self->flags);
+
+    if (!strcmp(name, "groups"))
+        return Py_BuildValue("i", self->groups);
+
+    if (!strcmp(name, "groupindex") && self->groupindex) {
+        Py_INCREF(self->groupindex);
+        return self->groupindex;
+    }
+
+    PyErr_SetString(PyExc_AttributeError, name);
+    return NULL;
+}
+
+statichere PyTypeObject Pattern_Type = {
+    PyObject_HEAD_INIT(NULL)
+    0, "_" SRE_MODULE ".SRE_Pattern",
+    sizeof(PatternObject), sizeof(SRE_CODE),
+    (destructor)pattern_dealloc, /*tp_dealloc*/
+    0, /*tp_print*/
+    (getattrfunc)pattern_getattr, /*tp_getattr*/
+    0,					/* tp_setattr */
+    0,					/* tp_compare */
+    0,					/* tp_repr */
+    0,					/* tp_as_number */
+    0,					/* tp_as_sequence */
+    0,					/* tp_as_mapping */
+    0,					/* tp_hash */
+    0,					/* tp_call */
+    0,					/* tp_str */
+    0,					/* tp_getattro */
+    0,					/* tp_setattro */
+    0,					/* tp_as_buffer */
+    Py_TPFLAGS_HAVE_WEAKREFS,		/* tp_flags */
+    pattern_doc,			/* tp_doc */
+    0,					/* tp_traverse */
+    0,					/* tp_clear */
+    0,					/* tp_richcompare */
+    offsetof(PatternObject, weakreflist),	/* tp_weaklistoffset */
+};
+
+static PyObject *
+_compile(PyObject* self_, PyObject* args)
+{
+    /* "compile" pattern descriptor to pattern object */
+
+    PatternObject* self;
+    Py_ssize_t i, n;
+
+    PyObject* pattern;
+    int flags = 0;
+    PyObject* code;
+    Py_ssize_t groups = 0;
+    PyObject* groupindex = NULL;
+    PyObject* indexgroup = NULL;
+    if (!PyArg_ParseTuple(args, "OiO!|nOO", &pattern, &flags,
+                          &PyList_Type, &code, &groups,
+                          &groupindex, &indexgroup))
+        return NULL;
+
+    n = PyList_GET_SIZE(code);
+
+    self = PyObject_NEW_VAR(PatternObject, &Pattern_Type, n);
+    if (!self)
+        return NULL;
+
+    self->codesize = n;
+
+    for (i = 0; i < n; i++) {
+        PyObject *o = PyList_GET_ITEM(code, i);
+        unsigned long value = PyInt_Check(o) ? (unsigned long)PyInt_AsLong(o)
+                                              : PyLong_AsUnsignedLong(o);
+        self->code[i] = (SRE_CODE) value;
+        if ((unsigned long) self->code[i] != value) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "regular expression code size limit exceeded");
+            break;
+        }
+    }
+
+    if (PyErr_Occurred()) {
+        PyObject_DEL(self);
+        return NULL;
+    }
+
+    Py_INCREF(pattern);
+    self->pattern = pattern;
+
+    self->flags = flags;
+
+    self->groups = groups;
+
+    Py_XINCREF(groupindex);
+    self->groupindex = groupindex;
+
+    Py_XINCREF(indexgroup);
+    self->indexgroup = indexgroup;
+
+    self->weakreflist = NULL;
+
+    return (PyObject*) self;
+}
+
+/* -------------------------------------------------------------------- */
+/* match methods */
+
+static void
+match_dealloc(MatchObject* self)
+{
+    Py_XDECREF(self->regs);
+    Py_XDECREF(self->string);
+    Py_DECREF(self->pattern);
+    PyObject_DEL(self);
+}
+
+static PyObject*
+match_getslice_by_index(MatchObject* self, Py_ssize_t index, PyObject* def)
+{
+    if (index < 0 || index >= self->groups) {
+        /* raise IndexError if we were given a bad group number */
+        PyErr_SetString(
+            PyExc_IndexError,
+            "no such group"
+            );
+        return NULL;
+    }
+
+    index *= 2;
+
+    if (self->string == Py_None || self->mark[index] < 0) {
+        /* return default value if the string or group is undefined */
+        Py_INCREF(def);
+        return def;
+    }
+
+    return PySequence_GetSlice(
+        self->string, self->mark[index], self->mark[index+1]
+        );
+}
+
+static Py_ssize_t
+match_getindex(MatchObject* self, PyObject* index)
+{
+    Py_ssize_t i;
+
+    if (PyInt_Check(index))
+        return PyInt_AsSsize_t(index);
+
+    i = -1;
+
+    if (self->pattern->groupindex) {
+        index = PyObject_GetItem(self->pattern->groupindex, index);
+        if (index) {
+            if (PyInt_Check(index) || PyLong_Check(index))
+                i = PyInt_AsSsize_t(index);
+            Py_DECREF(index);
+        } else
+            PyErr_Clear();
+    }
+
+    return i;
+}
+
+static PyObject*
+match_getslice(MatchObject* self, PyObject* index, PyObject* def)
+{
+    return match_getslice_by_index(self, match_getindex(self, index), def);
+}
+
+static PyObject*
+match_expand(MatchObject* self, PyObject* ptemplate)
+{
+    /* delegate to Python code */
+    return call(
+        SRE_PY_MODULE, "_expand",
+        PyTuple_Pack(3, self->pattern, self, ptemplate)
+        );
+}
+
+static PyObject*
+match_group(MatchObject* self, PyObject* args)
+{
+    PyObject* result;
+    Py_ssize_t i, size;
+
+    size = PyTuple_GET_SIZE(args);
+
+    switch (size) {
+    case 0:
+        result = match_getslice(self, Py_False, Py_None);
+        break;
+    case 1:
+        result = match_getslice(self, PyTuple_GET_ITEM(args, 0), Py_None);
+        break;
+    default:
+        /* fetch multiple items */
+        result = PyTuple_New(size);
+        if (!result)
+            return NULL;
+        for (i = 0; i < size; i++) {
+            PyObject* item = match_getslice(
+                self, PyTuple_GET_ITEM(args, i), Py_None
+                );
+            if (!item) {
+                Py_DECREF(result);
+                return NULL;
+            }
+            PyTuple_SET_ITEM(result, i, item);
+        }
+        break;
+    }
+    return result;
+}
+
+static PyObject*
+match_groups(MatchObject* self, PyObject* args, PyObject* kw)
+{
+    PyObject* result;
+    Py_ssize_t index;
+
+    PyObject* def = Py_None;
+    static char* kwlist[] = { "default", NULL };
+    if (!PyArg_ParseTupleAndKeywords(args, kw, "|O:groups", kwlist, &def))
+        return NULL;
+
+    result = PyTuple_New(self->groups-1);
+    if (!result)
+        return NULL;
+
+    for (index = 1; index < self->groups; index++) {
+        PyObject* item;
+        item = match_getslice_by_index(self, index, def);
+        if (!item) {
+            Py_DECREF(result);
+            return NULL;
+        }
+        PyTuple_SET_ITEM(result, index-1, item);
+    }
+
+    return result;
+}
+
+static PyObject*
+match_groupdict(MatchObject* self, PyObject* args, PyObject* kw)
+{
+    PyObject* result;
+    PyObject* keys;
+    Py_ssize_t index;
+
+    PyObject* def = Py_None;
+    static char* kwlist[] = { "default", NULL };
+    if (!PyArg_ParseTupleAndKeywords(args, kw, "|O:groupdict", kwlist, &def))
+        return NULL;
+
+    result = PyDict_New();
+    if (!result || !self->pattern->groupindex)
+        return result;
+
+    keys = PyMapping_Keys(self->pattern->groupindex);
+    if (!keys)
+        goto failed;
+
+    for (index = 0; index < PyList_GET_SIZE(keys); index++) {
+        int status;
+        PyObject* key;
+        PyObject* value;
+        key = PyList_GET_ITEM(keys, index);
+        if (!key)
+            goto failed;
+        value = match_getslice(self, key, def);
+        if (!value) {
+            Py_DECREF(key);
+            goto failed;
+        }
+        status = PyDict_SetItem(result, key, value);
+        Py_DECREF(value);
+        if (status < 0)
+            goto failed;
+    }
+
+    Py_DECREF(keys);
+
+    return result;
+
+failed:
+    Py_XDECREF(keys);
+    Py_DECREF(result);
+    return NULL;
+}
+
+static PyObject*
+match_start(MatchObject* self, PyObject* args)
+{
+    Py_ssize_t index;
+
+    PyObject* index_ = Py_False; /* zero */
+    if (!PyArg_UnpackTuple(args, "start", 0, 1, &index_))
+        return NULL;
+
+    index = match_getindex(self, index_);
+
+    if (index < 0 || index >= self->groups) {
+        PyErr_SetString(
+            PyExc_IndexError,
+            "no such group"
+            );
+        return NULL;
+    }
+
+    /* mark is -1 if group is undefined */
+    return Py_BuildValue("i", self->mark[index*2]);
+}
+
+static PyObject*
+match_end(MatchObject* self, PyObject* args)
+{
+    Py_ssize_t index;
+
+    PyObject* index_ = Py_False; /* zero */
+    if (!PyArg_UnpackTuple(args, "end", 0, 1, &index_))
+        return NULL;
+
+    index = match_getindex(self, index_);
+
+    if (index < 0 || index >= self->groups) {
+        PyErr_SetString(
+            PyExc_IndexError,
+            "no such group"
+            );
+        return NULL;
+    }
+
+    /* mark is -1 if group is undefined */
+    return Py_BuildValue("i", self->mark[index*2+1]);
+}
+
+LOCAL(PyObject*)
+_pair(Py_ssize_t i1, Py_ssize_t i2)
+{
+    PyObject* pair;
+    PyObject* item;
+
+    pair = PyTuple_New(2);
+    if (!pair)
+        return NULL;
+
+    item = PyInt_FromSsize_t(i1);
+    if (!item)
+        goto error;
+    PyTuple_SET_ITEM(pair, 0, item);
+
+    item = PyInt_FromSsize_t(i2);
+    if (!item)
+        goto error;
+    PyTuple_SET_ITEM(pair, 1, item);
+
+    return pair;
+
+  error:
+    Py_DECREF(pair);
+    return NULL;
+}
+
+static PyObject*
+match_span(MatchObject* self, PyObject* args)
+{
+    Py_ssize_t index;
+
+    PyObject* index_ = Py_False; /* zero */
+    if (!PyArg_UnpackTuple(args, "span", 0, 1, &index_))
+        return NULL;
+
+    index = match_getindex(self, index_);
+
+    if (index < 0 || index >= self->groups) {
+        PyErr_SetString(
+            PyExc_IndexError,
+            "no such group"
+            );
+        return NULL;
+    }
+
+    /* marks are -1 if group is undefined */
+    return _pair(self->mark[index*2], self->mark[index*2+1]);
+}
+
+static PyObject*
+match_regs(MatchObject* self)
+{
+    PyObject* regs;
+    PyObject* item;
+    Py_ssize_t index;
+
+    regs = PyTuple_New(self->groups);
+    if (!regs)
+        return NULL;
+
+    for (index = 0; index < self->groups; index++) {
+        item = _pair(self->mark[index*2], self->mark[index*2+1]);
+        if (!item) {
+            Py_DECREF(regs);
+            return NULL;
+        }
+        PyTuple_SET_ITEM(regs, index, item);
+    }
+
+    Py_INCREF(regs);
+    self->regs = regs;
+
+    return regs;
+}
+
+static PyObject*
+match_copy(MatchObject* self, PyObject *unused)
+{
+#ifdef USE_BUILTIN_COPY
+    MatchObject* copy;
+    Py_ssize_t slots, offset;
+
+    slots = 2 * (self->pattern->groups+1);
+
+    copy = PyObject_NEW_VAR(MatchObject, &Match_Type, slots);
+    if (!copy)
+        return NULL;
+
+    /* this value a constant, but any compiler should be able to
+       figure that out all by itself */
+    offset = offsetof(MatchObject, string);
+
+    Py_XINCREF(self->pattern);
+    Py_XINCREF(self->string);
+    Py_XINCREF(self->regs);
+
+    memcpy((char*) copy + offset, (char*) self + offset,
+           sizeof(MatchObject) + slots * sizeof(Py_ssize_t) - offset);
+
+    return (PyObject*) copy;
+#else
+    PyErr_SetString(PyExc_TypeError, "cannot copy this match object");
+    return NULL;
+#endif
+}
+
+static PyObject*
+match_deepcopy(MatchObject* self, PyObject* memo)
+{
+#ifdef USE_BUILTIN_COPY
+    MatchObject* copy;
+
+    copy = (MatchObject*) match_copy(self);
+    if (!copy)
+        return NULL;
+
+    if (!deepcopy((PyObject**) &copy->pattern, memo) ||
+        !deepcopy(&copy->string, memo) ||
+        !deepcopy(&copy->regs, memo)) {
+        Py_DECREF(copy);
+        return NULL;
+    }
+
+#else
+    PyErr_SetString(PyExc_TypeError, "cannot deepcopy this match object");
+    return NULL;
+#endif
+}
+
+static PyMethodDef match_methods[] = {
+    {"group", (PyCFunction) match_group, METH_VARARGS},
+    {"start", (PyCFunction) match_start, METH_VARARGS},
+    {"end", (PyCFunction) match_end, METH_VARARGS},
+    {"span", (PyCFunction) match_span, METH_VARARGS},
+    {"groups", (PyCFunction) match_groups, METH_VARARGS|METH_KEYWORDS},
+    {"groupdict", (PyCFunction) match_groupdict, METH_VARARGS|METH_KEYWORDS},
+    {"expand", (PyCFunction) match_expand, METH_O},
+    {"__copy__", (PyCFunction) match_copy, METH_NOARGS},
+    {"__deepcopy__", (PyCFunction) match_deepcopy, METH_O},
+    {NULL, NULL}
+};
+
+static PyObject*
+match_getattr(MatchObject* self, char* name)
+{
+    PyObject* res;
+
+    res = Py_FindMethod(match_methods, (PyObject*) self, name);
+    if (res)
+        return res;
+
+    PyErr_Clear();
+
+    if (!strcmp(name, "lastindex")) {
+        if (self->lastindex >= 0)
+            return Py_BuildValue("i", self->lastindex);
+        Py_INCREF(Py_None);
+        return Py_None;
+    }
+
+    if (!strcmp(name, "lastgroup")) {
+        if (self->pattern->indexgroup && self->lastindex >= 0) {
+            PyObject* result = PySequence_GetItem(
+                self->pattern->indexgroup, self->lastindex
+                );
+            if (result)
+                return result;
+            PyErr_Clear();
+        }
+        Py_INCREF(Py_None);
+        return Py_None;
+    }
+
+    if (!strcmp(name, "string")) {
+        if (self->string) {
+            Py_INCREF(self->string);
+            return self->string;
+        } else {
+            Py_INCREF(Py_None);
+            return Py_None;
+        }
+    }
+
+    if (!strcmp(name, "regs")) {
+        if (self->regs) {
+            Py_INCREF(self->regs);
+            return self->regs;
+        } else
+            return match_regs(self);
+    }
+
+    if (!strcmp(name, "re")) {
+        Py_INCREF(self->pattern);
+        return (PyObject*) self->pattern;
+    }
+
+    if (!strcmp(name, "pos"))
+        return Py_BuildValue("i", self->pos);
+
+    if (!strcmp(name, "endpos"))
+        return Py_BuildValue("i", self->endpos);
+
+    PyErr_SetString(PyExc_AttributeError, name);
+    return NULL;
+}
+
+/* FIXME: implement setattr("string", None) as a special case (to
+   detach the associated string, if any */
+
+statichere PyTypeObject Match_Type = {
+    PyObject_HEAD_INIT(NULL)
+    0, "_" SRE_MODULE ".SRE_Match",
+    sizeof(MatchObject), sizeof(Py_ssize_t),
+    (destructor)match_dealloc, /*tp_dealloc*/
+    0, /*tp_print*/
+    (getattrfunc)match_getattr /*tp_getattr*/
+};
+
+static PyObject*
+pattern_new_match(PatternObject* pattern, SRE_STATE* state, int status)
+{
+    /* create match object (from state object) */
+
+    MatchObject* match;
+    Py_ssize_t i, j;
+    char* base;
+    int n;
+
+    if (status > 0) {
+
+        /* create match object (with room for extra group marks) */
+        match = PyObject_NEW_VAR(MatchObject, &Match_Type,
+                                 2*(pattern->groups+1));
+        if (!match)
+            return NULL;
+
+        Py_INCREF(pattern);
+        match->pattern = pattern;
+
+        Py_INCREF(state->string);
+        match->string = state->string;
+
+        match->regs = NULL;
+        match->groups = pattern->groups+1;
+
+        /* fill in group slices */
+
+        base = (char*) state->beginning;
+        n = state->charsize;
+
+        match->mark[0] = ((char*) state->start - base) / n;
+        match->mark[1] = ((char*) state->ptr - base) / n;
+
+        for (i = j = 0; i < pattern->groups; i++, j+=2)
+            if (j+1 <= state->lastmark && state->mark[j] && state->mark[j+1]) {
+                match->mark[j+2] = ((char*) state->mark[j] - base) / n;
+                match->mark[j+3] = ((char*) state->mark[j+1] - base) / n;
+            } else
+                match->mark[j+2] = match->mark[j+3] = -1; /* undefined */
+
+        match->pos = state->pos;
+        match->endpos = state->endpos;
+
+        match->lastindex = state->lastindex;
+
+        return (PyObject*) match;
+
+    } else if (status == 0) {
+
+        /* no match */
+        Py_INCREF(Py_None);
+        return Py_None;
+
+    }
+
+    /* internal error */
+    pattern_error(status);
+    return NULL;
+}
+
+
+/* -------------------------------------------------------------------- */
+/* scanner methods (experimental) */
+
+static void
+scanner_dealloc(ScannerObject* self)
+{
+    state_fini(&self->state);
+    Py_DECREF(self->pattern);
+    PyObject_DEL(self);
+}
+
+static PyObject*
+scanner_match(ScannerObject* self, PyObject *unused)
+{
+    SRE_STATE* state = &self->state;
+    PyObject* match;
+    int status;
+
+    state_reset(state);
+
+    state->ptr = state->start;
+
+    if (state->charsize == 1) {
+        status = sre_match(state, PatternObject_GetCode(self->pattern));
+    } else {
+#if defined(HAVE_UNICODE)
+        status = sre_umatch(state, PatternObject_GetCode(self->pattern));
+#endif
+    }
+    if (PyErr_Occurred())
+        return NULL;
+
+    match = pattern_new_match((PatternObject*) self->pattern,
+                               state, status);
+
+    if (status == 0 || state->ptr == state->start)
+        state->start = (void*) ((char*) state->ptr + state->charsize);
+    else
+        state->start = state->ptr;
+
+    return match;
+}
+
+
+static PyObject*
+scanner_search(ScannerObject* self, PyObject *unused)
+{
+    SRE_STATE* state = &self->state;
+    PyObject* match;
+    int status;
+
+    state_reset(state);
+
+    state->ptr = state->start;
+
+    if (state->charsize == 1) {
+        status = sre_search(state, PatternObject_GetCode(self->pattern));
+    } else {
+#if defined(HAVE_UNICODE)
+        status = sre_usearch(state, PatternObject_GetCode(self->pattern));
+#endif
+    }
+    if (PyErr_Occurred())
+        return NULL;
+
+    match = pattern_new_match((PatternObject*) self->pattern,
+                               state, status);
+
+    if (status == 0 || state->ptr == state->start)
+        state->start = (void*) ((char*) state->ptr + state->charsize);
+    else
+        state->start = state->ptr;
+
+    return match;
+}
+
+static PyMethodDef scanner_methods[] = {
+    {"match", (PyCFunction) scanner_match, METH_NOARGS},
+    {"search", (PyCFunction) scanner_search, METH_NOARGS},
+    {NULL, NULL}
+};
+
+static PyObject*
+scanner_getattr(ScannerObject* self, char* name)
+{
+    PyObject* res;
+
+    res = Py_FindMethod(scanner_methods, (PyObject*) self, name);
+    if (res)
+        return res;
+
+    PyErr_Clear();
+
+    /* attributes */
+    if (!strcmp(name, "pattern")) {
+        Py_INCREF(self->pattern);
+        return self->pattern;
+    }
+
+    PyErr_SetString(PyExc_AttributeError, name);
+    return NULL;
+}
+
+statichere PyTypeObject Scanner_Type = {
+    PyObject_HEAD_INIT(NULL)
+    0, "_" SRE_MODULE ".SRE_Scanner",
+    sizeof(ScannerObject), 0,
+    (destructor)scanner_dealloc, /*tp_dealloc*/
+    0, /*tp_print*/
+    (getattrfunc)scanner_getattr, /*tp_getattr*/
+};
+
+static PyObject*
+pattern_scanner(PatternObject* pattern, PyObject* args)
+{
+    /* create search state object */
+
+    ScannerObject* self;
+
+    PyObject* string;
+    Py_ssize_t start = 0;
+    Py_ssize_t end = PY_SSIZE_T_MAX;
+    if (!PyArg_ParseTuple(args, "O|nn:scanner", &string, &start, &end))
+        return NULL;
+
+    /* create scanner object */
+    self = PyObject_NEW(ScannerObject, &Scanner_Type);
+    if (!self)
+        return NULL;
+
+    string = state_init(&self->state, pattern, string, start, end);
+    if (!string) {
+        PyObject_DEL(self);
+        return NULL;
+    }
+
+    Py_INCREF(pattern);
+    self->pattern = (PyObject*) pattern;
+
+    return (PyObject*) self;
+}
+
+static PyMethodDef _functions[] = {
+    {"compile", _compile, METH_VARARGS},
+    {"getcodesize", sre_codesize, METH_NOARGS},
+    {"getlower", sre_getlower, METH_VARARGS},
+    {NULL, NULL}
+};
+
+#if PY_VERSION_HEX < 0x02030000
+DL_EXPORT(void) init_sre(void)
+#else
+PyMODINIT_FUNC init_sre(void)
+#endif
+{
+    PyObject* m;
+    PyObject* d;
+    PyObject* x;
+
+    /* Patch object types */
+    Pattern_Type.ob_type = Match_Type.ob_type =
+        Scanner_Type.ob_type = &PyType_Type;
+
+    m = Py_InitModule("_" SRE_MODULE, _functions);
+    if (m == NULL)
+    	return;
+    d = PyModule_GetDict(m);
+
+    x = PyInt_FromLong(SRE_MAGIC);
+    if (x) {
+        PyDict_SetItemString(d, "MAGIC", x);
+        Py_DECREF(x);
+    }
+
+    x = PyInt_FromLong(sizeof(SRE_CODE));
+    if (x) {
+        PyDict_SetItemString(d, "CODESIZE", x);
+        Py_DECREF(x);
+    }
+
+    x = PyString_FromString(copyright);
+    if (x) {
+        PyDict_SetItemString(d, "copyright", x);
+        Py_DECREF(x);
+    }
+}
+
+#endif /* !defined(SRE_RECURSIVE) */
+
+/* vim:ts=4:sw=4:et
+*/

Added: vendor/Python/current/Modules/_ssl.c
===================================================================
--- vendor/Python/current/Modules/_ssl.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_ssl.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,726 @@
+/* SSL socket module 
+
+   SSL support based on patches by Brian E Gallew and Laszlo Kovacs.
+
+   This module is imported by socket.py. It should *not* be used
+   directly.
+
+*/
+
+#include "Python.h"
+enum py_ssl_error {
+	/* these mirror ssl.h */
+	PY_SSL_ERROR_NONE,                 
+	PY_SSL_ERROR_SSL,                   
+	PY_SSL_ERROR_WANT_READ,             
+	PY_SSL_ERROR_WANT_WRITE,            
+	PY_SSL_ERROR_WANT_X509_LOOKUP,      
+	PY_SSL_ERROR_SYSCALL,     /* look at error stack/return value/errno */
+	PY_SSL_ERROR_ZERO_RETURN,           
+	PY_SSL_ERROR_WANT_CONNECT,
+	/* start of non ssl.h errorcodes */ 
+	PY_SSL_ERROR_EOF,         /* special case of SSL_ERROR_SYSCALL */
+	PY_SSL_ERROR_INVALID_ERROR_CODE
+};
+
+/* Include symbols from _socket module */
+#include "socketmodule.h"
+
+#if defined(HAVE_POLL_H) 
+#include <poll.h>
+#elif defined(HAVE_SYS_POLL_H)
+#include <sys/poll.h>
+#endif
+
+/* Include OpenSSL header files */
+#include "openssl/rsa.h"
+#include "openssl/crypto.h"
+#include "openssl/x509.h"
+#include "openssl/pem.h"
+#include "openssl/ssl.h"
+#include "openssl/err.h"
+#include "openssl/rand.h"
+
+/* SSL error object */
+static PyObject *PySSLErrorObject;
+
+/* SSL socket object */
+
+#define X509_NAME_MAXLEN 256
+
+/* RAND_* APIs got added to OpenSSL in 0.9.5 */
+#if OPENSSL_VERSION_NUMBER >= 0x0090500fL
+# define HAVE_OPENSSL_RAND 1
+#else
+# undef HAVE_OPENSSL_RAND
+#endif
+
+typedef struct {
+	PyObject_HEAD
+	PySocketSockObject *Socket;	/* Socket on which we're layered */
+	SSL_CTX* 	ctx;
+	SSL*     	ssl;
+	X509*    	server_cert;
+	char    	server[X509_NAME_MAXLEN];
+	char		issuer[X509_NAME_MAXLEN];
+
+} PySSLObject;
+
+static PyTypeObject PySSL_Type;
+static PyObject *PySSL_SSLwrite(PySSLObject *self, PyObject *args);
+static PyObject *PySSL_SSLread(PySSLObject *self, PyObject *args);
+static int check_socket_and_wait_for_timeout(PySocketSockObject *s, 
+					     int writing);
+
+#define PySSLObject_Check(v)	((v)->ob_type == &PySSL_Type)
+
+typedef enum {
+	SOCKET_IS_NONBLOCKING,
+	SOCKET_IS_BLOCKING,
+	SOCKET_HAS_TIMED_OUT,
+	SOCKET_HAS_BEEN_CLOSED,
+	SOCKET_TOO_LARGE_FOR_SELECT,
+	SOCKET_OPERATION_OK
+} timeout_state;
+
+/* XXX It might be helpful to augment the error message generated
+   below with the name of the SSL function that generated the error.
+   I expect it's obvious most of the time.
+*/
+
+static PyObject *
+PySSL_SetError(PySSLObject *obj, int ret)
+{
+	PyObject *v, *n, *s;
+	char *errstr;
+	int err;
+	enum py_ssl_error p;
+
+	assert(ret <= 0);
+    
+	err = SSL_get_error(obj->ssl, ret);
+
+	switch (err) {
+	case SSL_ERROR_ZERO_RETURN:
+		errstr = "TLS/SSL connection has been closed";
+		p = PY_SSL_ERROR_ZERO_RETURN;
+		break;
+	case SSL_ERROR_WANT_READ:
+		errstr = "The operation did not complete (read)";
+		p = PY_SSL_ERROR_WANT_READ;
+		break;
+	case SSL_ERROR_WANT_WRITE:
+		p = PY_SSL_ERROR_WANT_WRITE;
+		errstr = "The operation did not complete (write)";
+		break;
+	case SSL_ERROR_WANT_X509_LOOKUP:
+		p = PY_SSL_ERROR_WANT_X509_LOOKUP;
+		errstr = "The operation did not complete (X509 lookup)";
+		break;
+	case SSL_ERROR_WANT_CONNECT:
+		p = PY_SSL_ERROR_WANT_CONNECT;
+		errstr = "The operation did not complete (connect)";
+		break;
+	case SSL_ERROR_SYSCALL:
+	{
+		unsigned long e = ERR_get_error();
+		if (e == 0) {
+			if (ret == 0 || !obj->Socket) {
+				p = PY_SSL_ERROR_EOF;
+				errstr = "EOF occurred in violation of protocol";
+			} else if (ret == -1) {
+				/* the underlying BIO reported an I/O error */
+				return obj->Socket->errorhandler();
+			} else {  /* possible? */
+				p = PY_SSL_ERROR_SYSCALL;
+				errstr = "Some I/O error occurred";
+			}
+		} else {
+			p = PY_SSL_ERROR_SYSCALL;
+			/* XXX Protected by global interpreter lock */
+			errstr = ERR_error_string(e, NULL);
+		}
+		break;
+	}   
+	case SSL_ERROR_SSL:
+	{
+		unsigned long e = ERR_get_error();
+		p = PY_SSL_ERROR_SSL;
+		if (e != 0) 
+			/* XXX Protected by global interpreter lock */
+			errstr = ERR_error_string(e, NULL);
+		else { /* possible? */
+			errstr = "A failure in the SSL library occurred";
+		}
+		break;
+	}
+	default:
+		p = PY_SSL_ERROR_INVALID_ERROR_CODE;
+		errstr = "Invalid error code";
+	}
+	n = PyInt_FromLong((long) p);
+	if (n == NULL)
+		return NULL;
+	v = PyTuple_New(2);
+	if (v == NULL) {
+		Py_DECREF(n);
+		return NULL;
+	}
+
+	s = PyString_FromString(errstr);
+	if (s == NULL) {
+		Py_DECREF(v);
+		Py_DECREF(n);
+	}
+	PyTuple_SET_ITEM(v, 0, n);
+	PyTuple_SET_ITEM(v, 1, s);
+	PyErr_SetObject(PySSLErrorObject, v);
+	Py_DECREF(v);
+	return NULL;
+}
+
+static PySSLObject *
+newPySSLObject(PySocketSockObject *Sock, char *key_file, char *cert_file)
+{
+	PySSLObject *self;
+	char *errstr = NULL;
+	int ret;
+	int err;
+	int sockstate;
+
+	self = PyObject_New(PySSLObject, &PySSL_Type); /* Create new object */
+	if (self == NULL)
+		return NULL;
+	memset(self->server, '\0', sizeof(char) * X509_NAME_MAXLEN);
+	memset(self->issuer, '\0', sizeof(char) * X509_NAME_MAXLEN);
+	self->server_cert = NULL;
+	self->ssl = NULL;
+	self->ctx = NULL;
+	self->Socket = NULL;
+
+	if ((key_file && !cert_file) || (!key_file && cert_file)) {
+		errstr = "Both the key & certificate files must be specified";
+		goto fail;
+	}
+
+	Py_BEGIN_ALLOW_THREADS
+	self->ctx = SSL_CTX_new(SSLv23_method()); /* Set up context */
+	Py_END_ALLOW_THREADS
+	if (self->ctx == NULL) {
+		errstr = "SSL_CTX_new error";
+		goto fail;
+	}
+
+	if (key_file) {
+		Py_BEGIN_ALLOW_THREADS
+		ret = SSL_CTX_use_PrivateKey_file(self->ctx, key_file,
+						SSL_FILETYPE_PEM);
+		Py_END_ALLOW_THREADS
+		if (ret < 1) {
+			errstr = "SSL_CTX_use_PrivateKey_file error";
+			goto fail;
+		}
+
+		Py_BEGIN_ALLOW_THREADS
+		ret = SSL_CTX_use_certificate_chain_file(self->ctx,
+						       cert_file);
+		Py_END_ALLOW_THREADS
+		SSL_CTX_set_options(self->ctx, SSL_OP_ALL); /* ssl compatibility */
+		if (ret < 1) {
+			errstr = "SSL_CTX_use_certificate_chain_file error";
+			goto fail;
+		}
+	}
+
+	Py_BEGIN_ALLOW_THREADS
+	SSL_CTX_set_verify(self->ctx,
+			   SSL_VERIFY_NONE, NULL); /* set verify lvl */
+	self->ssl = SSL_new(self->ctx); /* New ssl struct */
+	Py_END_ALLOW_THREADS
+	SSL_set_fd(self->ssl, Sock->sock_fd);	/* Set the socket for SSL */
+
+	/* If the socket is in non-blocking mode or timeout mode, set the BIO
+	 * to non-blocking mode (blocking is the default)
+	 */
+	if (Sock->sock_timeout >= 0.0) {
+		/* Set both the read and write BIO's to non-blocking mode */
+		BIO_set_nbio(SSL_get_rbio(self->ssl), 1);
+		BIO_set_nbio(SSL_get_wbio(self->ssl), 1);
+	}
+
+	Py_BEGIN_ALLOW_THREADS
+	SSL_set_connect_state(self->ssl);
+	Py_END_ALLOW_THREADS
+
+	/* Actually negotiate SSL connection */
+	/* XXX If SSL_connect() returns 0, it's also a failure. */
+	sockstate = 0;
+	do {
+		Py_BEGIN_ALLOW_THREADS
+		ret = SSL_connect(self->ssl);
+		err = SSL_get_error(self->ssl, ret);
+		Py_END_ALLOW_THREADS
+		if(PyErr_CheckSignals()) {
+                        goto fail;
+		}
+		if (err == SSL_ERROR_WANT_READ) {
+			sockstate = check_socket_and_wait_for_timeout(Sock, 0);
+		} else if (err == SSL_ERROR_WANT_WRITE) {
+			sockstate = check_socket_and_wait_for_timeout(Sock, 1);
+		} else {
+			sockstate = SOCKET_OPERATION_OK;
+		}
+	        if (sockstate == SOCKET_HAS_TIMED_OUT) {
+			PyErr_SetString(PySSLErrorObject, "The connect operation timed out");
+			goto fail;
+		} else if (sockstate == SOCKET_HAS_BEEN_CLOSED) {
+			PyErr_SetString(PySSLErrorObject, "Underlying socket has been closed.");
+			goto fail;
+		} else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) {
+			PyErr_SetString(PySSLErrorObject, "Underlying socket too large for select().");
+			goto fail;
+		} else if (sockstate == SOCKET_IS_NONBLOCKING) {
+			break;
+		}
+	} while (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE);
+	if (ret <= 0) {
+		PySSL_SetError(self, ret);
+		goto fail;
+	}
+	self->ssl->debug = 1;
+
+	Py_BEGIN_ALLOW_THREADS
+	if ((self->server_cert = SSL_get_peer_certificate(self->ssl))) {
+		X509_NAME_oneline(X509_get_subject_name(self->server_cert),
+				  self->server, X509_NAME_MAXLEN);
+		X509_NAME_oneline(X509_get_issuer_name(self->server_cert),
+				  self->issuer, X509_NAME_MAXLEN);
+	}
+	Py_END_ALLOW_THREADS
+	self->Socket = Sock;
+	Py_INCREF(self->Socket);
+	return self;
+ fail:
+	if (errstr)
+		PyErr_SetString(PySSLErrorObject, errstr);
+	Py_DECREF(self);
+	return NULL;
+}
+
+static PyObject *
+PySocket_ssl(PyObject *self, PyObject *args)
+{
+	PySSLObject *rv;
+	PySocketSockObject *Sock;
+	char *key_file = NULL;
+	char *cert_file = NULL;
+
+	if (!PyArg_ParseTuple(args, "O!|zz:ssl",
+			      PySocketModule.Sock_Type,
+			      (PyObject*)&Sock,
+			      &key_file, &cert_file))
+		return NULL;
+
+	rv = newPySSLObject(Sock, key_file, cert_file);
+	if (rv == NULL)
+		return NULL;
+	return (PyObject *)rv;
+}
+
+PyDoc_STRVAR(ssl_doc,
+"ssl(socket, [keyfile, certfile]) -> sslobject");
+
+/* SSL object methods */
+
+static PyObject *
+PySSL_server(PySSLObject *self)
+{
+	return PyString_FromString(self->server);
+}
+
+static PyObject *
+PySSL_issuer(PySSLObject *self)
+{
+	return PyString_FromString(self->issuer);
+}
+
+
+static void PySSL_dealloc(PySSLObject *self)
+{
+	if (self->server_cert)	/* Possible not to have one? */
+		X509_free (self->server_cert);
+	if (self->ssl)
+	    SSL_free(self->ssl);
+	if (self->ctx)
+	    SSL_CTX_free(self->ctx);
+	Py_XDECREF(self->Socket);
+	PyObject_Del(self);
+}
+
+/* If the socket has a timeout, do a select()/poll() on the socket.
+   The argument writing indicates the direction.
+   Returns one of the possibilities in the timeout_state enum (above).
+ */
+
+static int
+check_socket_and_wait_for_timeout(PySocketSockObject *s, int writing)
+{
+	fd_set fds;
+	struct timeval tv;
+	int rc;
+
+	/* Nothing to do unless we're in timeout mode (not non-blocking) */
+	if (s->sock_timeout < 0.0)
+		return SOCKET_IS_BLOCKING;
+	else if (s->sock_timeout == 0.0)
+		return SOCKET_IS_NONBLOCKING;
+
+	/* Guard against closed socket */
+	if (s->sock_fd < 0)
+		return SOCKET_HAS_BEEN_CLOSED;
+
+	/* Prefer poll, if available, since you can poll() any fd
+	 * which can't be done with select(). */
+#ifdef HAVE_POLL
+	{
+		struct pollfd pollfd;
+		int timeout;
+
+		pollfd.fd = s->sock_fd;
+		pollfd.events = writing ? POLLOUT : POLLIN;
+
+		/* s->sock_timeout is in seconds, timeout in ms */
+		timeout = (int)(s->sock_timeout * 1000 + 0.5);
+		Py_BEGIN_ALLOW_THREADS
+		rc = poll(&pollfd, 1, timeout);
+		Py_END_ALLOW_THREADS
+
+		goto normal_return;
+	}
+#endif
+
+	/* Guard against socket too large for select*/
+#ifndef Py_SOCKET_FD_CAN_BE_GE_FD_SETSIZE
+	if (s->sock_fd >= FD_SETSIZE)
+		return SOCKET_TOO_LARGE_FOR_SELECT;
+#endif
+
+	/* Construct the arguments to select */
+	tv.tv_sec = (int)s->sock_timeout;
+	tv.tv_usec = (int)((s->sock_timeout - tv.tv_sec) * 1e6);
+	FD_ZERO(&fds);
+	FD_SET(s->sock_fd, &fds);
+
+	/* See if the socket is ready */
+	Py_BEGIN_ALLOW_THREADS
+	if (writing)
+		rc = select(s->sock_fd+1, NULL, &fds, NULL, &tv);
+	else
+		rc = select(s->sock_fd+1, &fds, NULL, NULL, &tv);
+	Py_END_ALLOW_THREADS
+
+normal_return:
+	/* Return SOCKET_TIMED_OUT on timeout, SOCKET_OPERATION_OK otherwise
+	   (when we are able to write or when there's something to read) */
+	return rc == 0 ? SOCKET_HAS_TIMED_OUT : SOCKET_OPERATION_OK;
+}
+
+static PyObject *PySSL_SSLwrite(PySSLObject *self, PyObject *args)
+{
+	char *data;
+	int len;
+	int count;
+	int sockstate;
+	int err;
+
+	if (!PyArg_ParseTuple(args, "s#:write", &data, &count))
+		return NULL;
+
+	sockstate = check_socket_and_wait_for_timeout(self->Socket, 1);
+	if (sockstate == SOCKET_HAS_TIMED_OUT) {
+		PyErr_SetString(PySSLErrorObject, "The write operation timed out");
+		return NULL;
+	} else if (sockstate == SOCKET_HAS_BEEN_CLOSED) {
+		PyErr_SetString(PySSLErrorObject, "Underlying socket has been closed.");
+		return NULL;
+	} else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) {
+		PyErr_SetString(PySSLErrorObject, "Underlying socket too large for select().");
+		return NULL;
+	}
+	do {
+		err = 0;
+		Py_BEGIN_ALLOW_THREADS
+		len = SSL_write(self->ssl, data, count);
+		err = SSL_get_error(self->ssl, len);
+		Py_END_ALLOW_THREADS
+		if(PyErr_CheckSignals()) {
+			return NULL;
+		}
+		if (err == SSL_ERROR_WANT_READ) {
+			sockstate = check_socket_and_wait_for_timeout(self->Socket, 0);
+		} else if (err == SSL_ERROR_WANT_WRITE) {
+			sockstate = check_socket_and_wait_for_timeout(self->Socket, 1);
+		} else {
+			sockstate = SOCKET_OPERATION_OK;
+		}
+	        if (sockstate == SOCKET_HAS_TIMED_OUT) {
+			PyErr_SetString(PySSLErrorObject, "The write operation timed out");
+			return NULL;
+		} else if (sockstate == SOCKET_HAS_BEEN_CLOSED) {
+			PyErr_SetString(PySSLErrorObject, "Underlying socket has been closed.");
+			return NULL;
+		} else if (sockstate == SOCKET_IS_NONBLOCKING) {
+			break;
+		}
+	} while (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE);
+	if (len > 0)
+		return PyInt_FromLong(len);
+	else
+		return PySSL_SetError(self, len);
+}
+
+PyDoc_STRVAR(PySSL_SSLwrite_doc,
+"write(s) -> len\n\
+\n\
+Writes the string s into the SSL object.  Returns the number\n\
+of bytes written.");
+
+static PyObject *PySSL_SSLread(PySSLObject *self, PyObject *args)
+{
+	PyObject *buf;
+	int count = 0;
+	int len = 1024;
+	int sockstate;
+	int err;
+
+	if (!PyArg_ParseTuple(args, "|i:read", &len))
+		return NULL;
+
+	if (!(buf = PyString_FromStringAndSize((char *) 0, len)))
+		return NULL;
+	
+	/* first check if there are bytes ready to be read */
+	Py_BEGIN_ALLOW_THREADS
+	count = SSL_pending(self->ssl);
+	Py_END_ALLOW_THREADS
+
+	if (!count) {
+		sockstate = check_socket_and_wait_for_timeout(self->Socket, 0);
+		if (sockstate == SOCKET_HAS_TIMED_OUT) {
+			PyErr_SetString(PySSLErrorObject, "The read operation timed out");
+			Py_DECREF(buf);
+			return NULL;
+		} else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) {
+			PyErr_SetString(PySSLErrorObject, "Underlying socket too large for select().");
+			return NULL;
+		}
+	}
+	do {
+		err = 0;
+		Py_BEGIN_ALLOW_THREADS
+		count = SSL_read(self->ssl, PyString_AsString(buf), len);
+		err = SSL_get_error(self->ssl, count);
+		Py_END_ALLOW_THREADS
+		if(PyErr_CheckSignals()) {
+			Py_DECREF(buf);
+			return NULL;
+		}
+		if (err == SSL_ERROR_WANT_READ) {
+			sockstate = check_socket_and_wait_for_timeout(self->Socket, 0);
+		} else if (err == SSL_ERROR_WANT_WRITE) {
+			sockstate = check_socket_and_wait_for_timeout(self->Socket, 1);
+		} else {
+			sockstate = SOCKET_OPERATION_OK;
+		}
+	        if (sockstate == SOCKET_HAS_TIMED_OUT) {
+			PyErr_SetString(PySSLErrorObject, "The read operation timed out");
+			Py_DECREF(buf);
+			return NULL;
+		} else if (sockstate == SOCKET_IS_NONBLOCKING) {
+			break;
+		}
+	} while (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE);
+ 	if (count <= 0) {
+		Py_DECREF(buf);
+		return PySSL_SetError(self, count);
+	}
+	if (count != len)
+		_PyString_Resize(&buf, count);
+	return buf;
+}
+
+PyDoc_STRVAR(PySSL_SSLread_doc,
+"read([len]) -> string\n\
+\n\
+Read up to len bytes from the SSL socket.");
+
+static PyMethodDef PySSLMethods[] = {
+	{"write", (PyCFunction)PySSL_SSLwrite, METH_VARARGS,
+	          PySSL_SSLwrite_doc},
+	{"read", (PyCFunction)PySSL_SSLread, METH_VARARGS,
+	          PySSL_SSLread_doc},
+	{"server", (PyCFunction)PySSL_server, METH_NOARGS},
+	{"issuer", (PyCFunction)PySSL_issuer, METH_NOARGS},
+	{NULL, NULL}
+};
+
+static PyObject *PySSL_getattr(PySSLObject *self, char *name)
+{
+	return Py_FindMethod(PySSLMethods, (PyObject *)self, name);
+}
+
+static PyTypeObject PySSL_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0,				/*ob_size*/
+	"socket.SSL",			/*tp_name*/
+	sizeof(PySSLObject),		/*tp_basicsize*/
+	0,				/*tp_itemsize*/
+	/* methods */
+	(destructor)PySSL_dealloc,	/*tp_dealloc*/
+	0,				/*tp_print*/
+	(getattrfunc)PySSL_getattr,	/*tp_getattr*/
+	0,				/*tp_setattr*/
+	0,				/*tp_compare*/
+	0,				/*tp_repr*/
+	0,				/*tp_as_number*/
+	0,				/*tp_as_sequence*/
+	0,				/*tp_as_mapping*/
+	0,				/*tp_hash*/
+};
+
+#ifdef HAVE_OPENSSL_RAND
+
+/* helper routines for seeding the SSL PRNG */
+static PyObject *
+PySSL_RAND_add(PyObject *self, PyObject *args)
+{
+    char *buf;
+    int len;
+    double entropy;
+
+    if (!PyArg_ParseTuple(args, "s#d:RAND_add", &buf, &len, &entropy))
+	return NULL;
+    RAND_add(buf, len, entropy);
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+PyDoc_STRVAR(PySSL_RAND_add_doc,
+"RAND_add(string, entropy)\n\
+\n\
+Mix string into the OpenSSL PRNG state.  entropy (a float) is a lower\n\
+bound on the entropy contained in string.");
+
+static PyObject *
+PySSL_RAND_status(PyObject *self)
+{
+    return PyInt_FromLong(RAND_status());
+}
+
+PyDoc_STRVAR(PySSL_RAND_status_doc,
+"RAND_status() -> 0 or 1\n\
+\n\
+Returns 1 if the OpenSSL PRNG has been seeded with enough data and 0 if not.\n\
+It is necessary to seed the PRNG with RAND_add() on some platforms before\n\
+using the ssl() function.");
+
+static PyObject *
+PySSL_RAND_egd(PyObject *self, PyObject *arg)
+{
+    int bytes;
+
+    if (!PyString_Check(arg))
+	return PyErr_Format(PyExc_TypeError,
+			    "RAND_egd() expected string, found %s",
+			    arg->ob_type->tp_name);
+    bytes = RAND_egd(PyString_AS_STRING(arg));
+    if (bytes == -1) {
+	PyErr_SetString(PySSLErrorObject,
+			"EGD connection failed or EGD did not return "
+			"enough data to seed the PRNG");
+	return NULL;
+    }
+    return PyInt_FromLong(bytes);
+}
+
+PyDoc_STRVAR(PySSL_RAND_egd_doc,
+"RAND_egd(path) -> bytes\n\
+\n\
+Queries the entropy gather daemon (EGD) on socket path.  Returns number\n\
+of bytes read.  Raises socket.sslerror if connection to EGD fails or\n\
+if it does provide enough data to seed PRNG.");
+
+#endif
+
+/* List of functions exported by this module. */
+
+static PyMethodDef PySSL_methods[] = {
+	{"ssl",			PySocket_ssl,
+	 METH_VARARGS, ssl_doc},
+#ifdef HAVE_OPENSSL_RAND
+	{"RAND_add",            PySSL_RAND_add, METH_VARARGS, 
+	 PySSL_RAND_add_doc},
+	{"RAND_egd",            PySSL_RAND_egd, METH_O,
+	 PySSL_RAND_egd_doc},
+	{"RAND_status",         (PyCFunction)PySSL_RAND_status, METH_NOARGS,
+	 PySSL_RAND_status_doc},
+#endif
+	{NULL,			NULL}		 /* Sentinel */
+};
+
+
+PyDoc_STRVAR(module_doc,
+"Implementation module for SSL socket operations.  See the socket module\n\
+for documentation.");
+
+PyMODINIT_FUNC
+init_ssl(void)
+{
+	PyObject *m, *d;
+
+	PySSL_Type.ob_type = &PyType_Type;
+
+	m = Py_InitModule3("_ssl", PySSL_methods, module_doc);
+	if (m == NULL)
+		return;
+	d = PyModule_GetDict(m);
+
+	/* Load _socket module and its C API */
+	if (PySocketModule_ImportModuleAndAPI())
+ 	    	return;
+
+	/* Init OpenSSL */
+	SSL_load_error_strings();
+	SSLeay_add_ssl_algorithms();
+
+	/* Add symbols to module dict */
+	PySSLErrorObject = PyErr_NewException("socket.sslerror",
+                                               PySocketModule.error,
+                                               NULL);
+	if (PySSLErrorObject == NULL)
+		return;
+	PyDict_SetItemString(d, "sslerror", PySSLErrorObject);
+	if (PyDict_SetItemString(d, "SSLType",
+				 (PyObject *)&PySSL_Type) != 0)
+		return;
+	PyModule_AddIntConstant(m, "SSL_ERROR_ZERO_RETURN",
+				PY_SSL_ERROR_ZERO_RETURN);
+	PyModule_AddIntConstant(m, "SSL_ERROR_WANT_READ",
+				PY_SSL_ERROR_WANT_READ);
+	PyModule_AddIntConstant(m, "SSL_ERROR_WANT_WRITE",
+				PY_SSL_ERROR_WANT_WRITE);
+	PyModule_AddIntConstant(m, "SSL_ERROR_WANT_X509_LOOKUP",
+				PY_SSL_ERROR_WANT_X509_LOOKUP);
+	PyModule_AddIntConstant(m, "SSL_ERROR_SYSCALL",
+				PY_SSL_ERROR_SYSCALL);
+	PyModule_AddIntConstant(m, "SSL_ERROR_SSL",
+				PY_SSL_ERROR_SSL);
+	PyModule_AddIntConstant(m, "SSL_ERROR_WANT_CONNECT",
+				PY_SSL_ERROR_WANT_CONNECT);
+	/* non ssl.h errorcodes */
+	PyModule_AddIntConstant(m, "SSL_ERROR_EOF",
+				PY_SSL_ERROR_EOF);
+	PyModule_AddIntConstant(m, "SSL_ERROR_INVALID_ERROR_CODE",
+				PY_SSL_ERROR_INVALID_ERROR_CODE);
+
+}

Added: vendor/Python/current/Modules/_struct.c
===================================================================
--- vendor/Python/current/Modules/_struct.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_struct.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1896 @@
+/* struct module -- pack values into and (out of) strings */
+
+/* New version supporting byte order, alignment and size options,
+   character strings, and unsigned numbers */
+
+#define PY_SSIZE_T_CLEAN
+
+#include "Python.h"
+#include "structseq.h"
+#include "structmember.h"
+#include <ctype.h>
+
+static PyTypeObject PyStructType;
+
+/* compatibility macros */
+#if (PY_VERSION_HEX < 0x02050000)
+typedef int Py_ssize_t;
+#endif
+
+/* If PY_STRUCT_OVERFLOW_MASKING is defined, the struct module will wrap all input
+   numbers for explicit endians such that they fit in the given type, much
+   like explicit casting in C. A warning will be raised if the number did
+   not originally fit within the range of the requested type. If it is
+   not defined, then all range errors and overflow will be struct.error
+   exceptions. */
+
+#define PY_STRUCT_OVERFLOW_MASKING 1
+
+#ifdef PY_STRUCT_OVERFLOW_MASKING
+static PyObject *pylong_ulong_mask = NULL;
+static PyObject *pyint_zero = NULL;
+#endif
+
+/* If PY_STRUCT_FLOAT_COERCE is defined, the struct module will allow float
+   arguments for integer formats with a warning for backwards
+   compatibility. */
+
+#define PY_STRUCT_FLOAT_COERCE 1
+
+#ifdef PY_STRUCT_FLOAT_COERCE
+#define FLOAT_COERCE "integer argument expected, got float"
+#endif
+
+
+/* The translation function for each format character is table driven */
+typedef struct _formatdef {
+	char format;
+	Py_ssize_t size;
+	Py_ssize_t alignment;
+	PyObject* (*unpack)(const char *,
+			    const struct _formatdef *);
+	int (*pack)(char *, PyObject *,
+		    const struct _formatdef *);
+} formatdef;
+
+typedef struct _formatcode {
+	const struct _formatdef *fmtdef;
+	Py_ssize_t offset;
+	Py_ssize_t size;
+} formatcode;
+
+/* Struct object interface */
+
+typedef struct {
+	PyObject_HEAD
+	Py_ssize_t s_size;
+	Py_ssize_t s_len;
+	formatcode *s_codes;
+	PyObject *s_format;
+	PyObject *weakreflist; /* List of weak references */
+} PyStructObject;
+
+
+#define PyStruct_Check(op) PyObject_TypeCheck(op, &PyStructType)
+#define PyStruct_CheckExact(op) ((op)->ob_type == &PyStructType)
+
+
+/* Exception */
+
+static PyObject *StructError;
+
+
+/* Define various structs to figure out the alignments of types */
+
+
+typedef struct { char c; short x; } st_short;
+typedef struct { char c; int x; } st_int;
+typedef struct { char c; long x; } st_long;
+typedef struct { char c; float x; } st_float;
+typedef struct { char c; double x; } st_double;
+typedef struct { char c; void *x; } st_void_p;
+
+#define SHORT_ALIGN (sizeof(st_short) - sizeof(short))
+#define INT_ALIGN (sizeof(st_int) - sizeof(int))
+#define LONG_ALIGN (sizeof(st_long) - sizeof(long))
+#define FLOAT_ALIGN (sizeof(st_float) - sizeof(float))
+#define DOUBLE_ALIGN (sizeof(st_double) - sizeof(double))
+#define VOID_P_ALIGN (sizeof(st_void_p) - sizeof(void *))
+
+/* We can't support q and Q in native mode unless the compiler does;
+   in std mode, they're 8 bytes on all platforms. */
+#ifdef HAVE_LONG_LONG
+typedef struct { char c; PY_LONG_LONG x; } s_long_long;
+#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(PY_LONG_LONG))
+#endif
+
+#define STRINGIFY(x)    #x
+
+#ifdef __powerc
+#pragma options align=reset
+#endif
+
+/* Helper to get a PyLongObject by hook or by crook.  Caller should decref. */
+
+static PyObject *
+get_pylong(PyObject *v)
+{
+	PyNumberMethods *m;
+
+	assert(v != NULL);
+	if (PyInt_Check(v))
+		return PyLong_FromLong(PyInt_AS_LONG(v));
+	if (PyLong_Check(v)) {
+		Py_INCREF(v);
+		return v;
+	}
+	m = v->ob_type->tp_as_number;
+	if (m != NULL && m->nb_long != NULL) {
+		v = m->nb_long(v);
+		if (v == NULL)
+			return NULL;
+		if (PyLong_Check(v))
+			return v;
+		Py_DECREF(v);
+	}
+	PyErr_SetString(StructError,
+			"cannot convert argument to long");
+	return NULL;
+}
+
+/* Helper routine to get a Python integer and raise the appropriate error
+   if it isn't one */
+
+static int
+get_long(PyObject *v, long *p)
+{
+	long x = PyInt_AsLong(v);
+	if (x == -1 && PyErr_Occurred()) {
+#ifdef PY_STRUCT_FLOAT_COERCE
+		if (PyFloat_Check(v)) {
+			PyObject *o;
+			int res;
+			PyErr_Clear();
+			if (PyErr_WarnEx(PyExc_DeprecationWarning, FLOAT_COERCE, 2) < 0)
+				return -1;
+			o = PyNumber_Int(v);
+			if (o == NULL)
+				return -1;
+			res = get_long(o, p);
+			Py_DECREF(o);
+			return res;
+		}
+#endif
+		if (PyErr_ExceptionMatches(PyExc_TypeError))
+			PyErr_SetString(StructError,
+					"required argument is not an integer");
+		return -1;
+	}
+	*p = x;
+	return 0;
+}
+
+
+/* Same, but handling unsigned long */
+
+static int
+get_ulong(PyObject *v, unsigned long *p)
+{
+	if (PyLong_Check(v)) {
+		unsigned long x = PyLong_AsUnsignedLong(v);
+		if (x == (unsigned long)(-1) && PyErr_Occurred())
+			return -1;
+		*p = x;
+		return 0;
+	}
+	if (get_long(v, (long *)p) < 0)
+		return -1;
+	if (((long)*p) < 0) {
+		PyErr_SetString(StructError,
+				"unsigned argument is < 0");
+		return -1;
+	}
+	return 0;
+}
+
+#ifdef HAVE_LONG_LONG
+
+/* Same, but handling native long long. */
+
+static int
+get_longlong(PyObject *v, PY_LONG_LONG *p)
+{
+	PY_LONG_LONG x;
+
+	v = get_pylong(v);
+	if (v == NULL)
+		return -1;
+	assert(PyLong_Check(v));
+	x = PyLong_AsLongLong(v);
+	Py_DECREF(v);
+	if (x == (PY_LONG_LONG)-1 && PyErr_Occurred())
+		return -1;
+	*p = x;
+	return 0;
+}
+
+/* Same, but handling native unsigned long long. */
+
+static int
+get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p)
+{
+	unsigned PY_LONG_LONG x;
+
+	v = get_pylong(v);
+	if (v == NULL)
+		return -1;
+	assert(PyLong_Check(v));
+	x = PyLong_AsUnsignedLongLong(v);
+	Py_DECREF(v);
+	if (x == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())
+		return -1;
+	*p = x;
+	return 0;
+}
+
+#endif
+
+#ifdef PY_STRUCT_OVERFLOW_MASKING
+
+/* Helper routine to get a Python integer and raise the appropriate error
+   if it isn't one */
+
+#define INT_OVERFLOW "struct integer overflow masking is deprecated"
+
+static int
+get_wrapped_long(PyObject *v, long *p)
+{
+	if (get_long(v, p) < 0) {
+		if (PyLong_Check(v) &&
+		    PyErr_ExceptionMatches(PyExc_OverflowError)) {
+			PyObject *wrapped;
+			long x;
+			PyErr_Clear();
+#ifdef PY_STRUCT_FLOAT_COERCE
+			if (PyFloat_Check(v)) {
+				PyObject *o;
+				int res;
+				PyErr_Clear();
+				if (PyErr_WarnEx(PyExc_DeprecationWarning, FLOAT_COERCE, 2) < 0)
+					return -1;
+				o = PyNumber_Int(v);
+				if (o == NULL)
+					return -1;
+				res = get_wrapped_long(o, p);
+				Py_DECREF(o);
+				return res;
+			}
+#endif
+			if (PyErr_WarnEx(PyExc_DeprecationWarning, INT_OVERFLOW, 2) < 0)
+				return -1;
+			wrapped = PyNumber_And(v, pylong_ulong_mask);
+			if (wrapped == NULL)
+				return -1;
+			x = (long)PyLong_AsUnsignedLong(wrapped);
+			Py_DECREF(wrapped);
+			if (x == -1 && PyErr_Occurred())
+				return -1;
+			*p = x;
+		} else {
+			return -1;
+		}
+	}
+	return 0;
+}
+
+static int
+get_wrapped_ulong(PyObject *v, unsigned long *p)
+{
+	long x = (long)PyLong_AsUnsignedLong(v);
+	if (x == -1 && PyErr_Occurred()) {
+		PyObject *wrapped;
+		PyErr_Clear();
+#ifdef PY_STRUCT_FLOAT_COERCE
+		if (PyFloat_Check(v)) {
+			PyObject *o;
+			int res;
+			PyErr_Clear();
+			if (PyErr_WarnEx(PyExc_DeprecationWarning, FLOAT_COERCE, 2) < 0)
+				return -1;
+			o = PyNumber_Int(v);
+			if (o == NULL)
+				return -1;
+			res = get_wrapped_ulong(o, p);
+			Py_DECREF(o);
+			return res;
+		}
+#endif
+		wrapped = PyNumber_And(v, pylong_ulong_mask);
+		if (wrapped == NULL)
+			return -1;
+		if (PyErr_WarnEx(PyExc_DeprecationWarning, INT_OVERFLOW, 2) < 0) {
+			Py_DECREF(wrapped);
+			return -1;
+		}
+		x = (long)PyLong_AsUnsignedLong(wrapped);
+		Py_DECREF(wrapped);
+		if (x == -1 && PyErr_Occurred())
+			return -1;
+	}
+	*p = (unsigned long)x;
+	return 0;
+}
+
+#define RANGE_ERROR(x, f, flag, mask) \
+	do { \
+		if (_range_error(f, flag) < 0) \
+			return -1; \
+		else \
+			(x) &= (mask); \
+	} while (0)
+
+#else
+
+#define get_wrapped_long get_long
+#define get_wrapped_ulong get_ulong
+#define RANGE_ERROR(x, f, flag, mask) return _range_error(f, flag)
+
+#endif
+
+/* Floating point helpers */
+
+static PyObject *
+unpack_float(const char *p,  /* start of 4-byte string */
+             int le)	     /* true for little-endian, false for big-endian */
+{
+	double x;
+
+	x = _PyFloat_Unpack4((unsigned char *)p, le);
+	if (x == -1.0 && PyErr_Occurred())
+		return NULL;
+	return PyFloat_FromDouble(x);
+}
+
+static PyObject *
+unpack_double(const char *p,  /* start of 8-byte string */
+              int le)         /* true for little-endian, false for big-endian */
+{
+	double x;
+
+	x = _PyFloat_Unpack8((unsigned char *)p, le);
+	if (x == -1.0 && PyErr_Occurred())
+		return NULL;
+	return PyFloat_FromDouble(x);
+}
+
+/* Helper to format the range error exceptions */
+static int
+_range_error(const formatdef *f, int is_unsigned)
+{
+	/* ulargest is the largest unsigned value with f->size bytes.
+	 * Note that the simpler:
+	 *     ((size_t)1 << (f->size * 8)) - 1
+	 * doesn't work when f->size == sizeof(size_t) because C doesn't
+	 * define what happens when a left shift count is >= the number of
+	 * bits in the integer being shifted; e.g., on some boxes it doesn't
+	 * shift at all when they're equal.
+	 */
+	const size_t ulargest = (size_t)-1 >> ((SIZEOF_SIZE_T - f->size)*8);
+	assert(f->size >= 1 && f->size <= SIZEOF_SIZE_T);
+	if (is_unsigned)
+		PyErr_Format(StructError,
+			"'%c' format requires 0 <= number <= %zu",
+			f->format,
+			ulargest);
+	else {
+		const Py_ssize_t largest = (Py_ssize_t)(ulargest >> 1);
+		PyErr_Format(StructError,
+			"'%c' format requires %zd <= number <= %zd",
+			f->format,
+			~ largest,
+			largest);
+	}
+#ifdef PY_STRUCT_OVERFLOW_MASKING
+	{
+		PyObject *ptype, *pvalue, *ptraceback;
+		PyObject *msg;
+		int rval;
+		PyErr_Fetch(&ptype, &pvalue, &ptraceback);
+		assert(pvalue != NULL);
+		msg = PyObject_Str(pvalue);
+		Py_XDECREF(ptype);
+		Py_XDECREF(pvalue);
+		Py_XDECREF(ptraceback);
+		if (msg == NULL)
+			return -1;
+		rval = PyErr_WarnEx(PyExc_DeprecationWarning,
+				    PyString_AS_STRING(msg), 2);
+		Py_DECREF(msg);
+		if (rval == 0)
+			return 0;
+	}
+#endif
+	return -1;
+}
+
+
+
+/* A large number of small routines follow, with names of the form
+
+   [bln][up]_TYPE
+
+   [bln] distiguishes among big-endian, little-endian and native.
+   [pu] distiguishes between pack (to struct) and unpack (from struct).
+   TYPE is one of char, byte, ubyte, etc.
+*/
+
+/* Native mode routines. ****************************************************/
+/* NOTE:
+   In all n[up]_<type> routines handling types larger than 1 byte, there is
+   *no* guarantee that the p pointer is properly aligned for each type,
+   therefore memcpy is called.  An intermediate variable is used to
+   compensate for big-endian architectures.
+   Normally both the intermediate variable and the memcpy call will be
+   skipped by C optimisation in little-endian architectures (gcc >= 2.91
+   does this). */
+
+static PyObject *
+nu_char(const char *p, const formatdef *f)
+{
+	return PyString_FromStringAndSize(p, 1);
+}
+
+static PyObject *
+nu_byte(const char *p, const formatdef *f)
+{
+	return PyInt_FromLong((long) *(signed char *)p);
+}
+
+static PyObject *
+nu_ubyte(const char *p, const formatdef *f)
+{
+	return PyInt_FromLong((long) *(unsigned char *)p);
+}
+
+static PyObject *
+nu_short(const char *p, const formatdef *f)
+{
+	short x;
+	memcpy((char *)&x, p, sizeof x);
+	return PyInt_FromLong((long)x);
+}
+
+static PyObject *
+nu_ushort(const char *p, const formatdef *f)
+{
+	unsigned short x;
+	memcpy((char *)&x, p, sizeof x);
+	return PyInt_FromLong((long)x);
+}
+
+static PyObject *
+nu_int(const char *p, const formatdef *f)
+{
+	int x;
+	memcpy((char *)&x, p, sizeof x);
+	return PyInt_FromLong((long)x);
+}
+
+static PyObject *
+nu_uint(const char *p, const formatdef *f)
+{
+	unsigned int x;
+	memcpy((char *)&x, p, sizeof x);
+#if (SIZEOF_LONG > SIZEOF_INT)
+	return PyInt_FromLong((long)x);
+#else
+	if (x <= ((unsigned int)LONG_MAX))
+		return PyInt_FromLong((long)x);
+	return PyLong_FromUnsignedLong((unsigned long)x);
+#endif
+}
+
+static PyObject *
+nu_long(const char *p, const formatdef *f)
+{
+	long x;
+	memcpy((char *)&x, p, sizeof x);
+	return PyInt_FromLong(x);
+}
+
+static PyObject *
+nu_ulong(const char *p, const formatdef *f)
+{
+	unsigned long x;
+	memcpy((char *)&x, p, sizeof x);
+	if (x <= LONG_MAX)
+		return PyInt_FromLong((long)x);
+	return PyLong_FromUnsignedLong(x);
+}
+
+/* Native mode doesn't support q or Q unless the platform C supports
+   long long (or, on Windows, __int64). */
+
+#ifdef HAVE_LONG_LONG
+
+static PyObject *
+nu_longlong(const char *p, const formatdef *f)
+{
+	PY_LONG_LONG x;
+	memcpy((char *)&x, p, sizeof x);
+	if (x >= LONG_MIN && x <= LONG_MAX)
+		return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
+	return PyLong_FromLongLong(x);
+}
+
+static PyObject *
+nu_ulonglong(const char *p, const formatdef *f)
+{
+	unsigned PY_LONG_LONG x;
+	memcpy((char *)&x, p, sizeof x);
+	if (x <= LONG_MAX)
+		return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
+	return PyLong_FromUnsignedLongLong(x);
+}
+
+#endif
+
+static PyObject *
+nu_float(const char *p, const formatdef *f)
+{
+	float x;
+	memcpy((char *)&x, p, sizeof x);
+	return PyFloat_FromDouble((double)x);
+}
+
+static PyObject *
+nu_double(const char *p, const formatdef *f)
+{
+	double x;
+	memcpy((char *)&x, p, sizeof x);
+	return PyFloat_FromDouble(x);
+}
+
+static PyObject *
+nu_void_p(const char *p, const formatdef *f)
+{
+	void *x;
+	memcpy((char *)&x, p, sizeof x);
+	return PyLong_FromVoidPtr(x);
+}
+
+static int
+np_byte(char *p, PyObject *v, const formatdef *f)
+{
+	long x;
+	if (get_long(v, &x) < 0)
+		return -1;
+	if (x < -128 || x > 127){
+		PyErr_SetString(StructError,
+				"byte format requires -128 <= number <= 127");
+		return -1;
+	}
+	*p = (char)x;
+	return 0;
+}
+
+static int
+np_ubyte(char *p, PyObject *v, const formatdef *f)
+{
+	long x;
+	if (get_long(v, &x) < 0)
+		return -1;
+	if (x < 0 || x > 255){
+		PyErr_SetString(StructError,
+				"ubyte format requires 0 <= number <= 255");
+		return -1;
+	}
+	*p = (char)x;
+	return 0;
+}
+
+static int
+np_char(char *p, PyObject *v, const formatdef *f)
+{
+	if (!PyString_Check(v) || PyString_Size(v) != 1) {
+		PyErr_SetString(StructError,
+				"char format require string of length 1");
+		return -1;
+	}
+	*p = *PyString_AsString(v);
+	return 0;
+}
+
+static int
+np_short(char *p, PyObject *v, const formatdef *f)
+{
+	long x;
+	short y;
+	if (get_long(v, &x) < 0)
+		return -1;
+	if (x < SHRT_MIN || x > SHRT_MAX){
+		PyErr_SetString(StructError,
+				"short format requires " STRINGIFY(SHRT_MIN)
+				" <= number <= " STRINGIFY(SHRT_MAX));
+		return -1;
+	}
+	y = (short)x;
+	memcpy(p, (char *)&y, sizeof y);
+	return 0;
+}
+
+static int
+np_ushort(char *p, PyObject *v, const formatdef *f)
+{
+	long x;
+	unsigned short y;
+	if (get_long(v, &x) < 0)
+		return -1;
+	if (x < 0 || x > USHRT_MAX){
+		PyErr_SetString(StructError,
+				"short format requires 0 <= number <= " STRINGIFY(USHRT_MAX));
+		return -1;
+	}
+	y = (unsigned short)x;
+	memcpy(p, (char *)&y, sizeof y);
+	return 0;
+}
+
+static int
+np_int(char *p, PyObject *v, const formatdef *f)
+{
+	long x;
+	int y;
+	if (get_long(v, &x) < 0)
+		return -1;
+#if (SIZEOF_LONG > SIZEOF_INT)
+	if ((x < ((long)INT_MIN)) || (x > ((long)INT_MAX)))
+		return _range_error(f, 0);
+#endif
+	y = (int)x;
+	memcpy(p, (char *)&y, sizeof y);
+	return 0;
+}
+
+static int
+np_uint(char *p, PyObject *v, const formatdef *f)
+{
+	unsigned long x;
+	unsigned int y;
+	if (get_ulong(v, &x) < 0)
+		return _range_error(f, 1);
+	y = (unsigned int)x;
+#if (SIZEOF_LONG > SIZEOF_INT)
+	if (x > ((unsigned long)UINT_MAX))
+		return _range_error(f, 1);
+#endif
+	memcpy(p, (char *)&y, sizeof y);
+	return 0;
+}
+
+static int
+np_long(char *p, PyObject *v, const formatdef *f)
+{
+	long x;
+	if (get_long(v, &x) < 0)
+		return -1;
+	memcpy(p, (char *)&x, sizeof x);
+	return 0;
+}
+
+static int
+np_ulong(char *p, PyObject *v, const formatdef *f)
+{
+	unsigned long x;
+	if (get_ulong(v, &x) < 0)
+		return _range_error(f, 1);
+	memcpy(p, (char *)&x, sizeof x);
+	return 0;
+}
+
+#ifdef HAVE_LONG_LONG
+
+static int
+np_longlong(char *p, PyObject *v, const formatdef *f)
+{
+	PY_LONG_LONG x;
+	if (get_longlong(v, &x) < 0)
+		return -1;
+	memcpy(p, (char *)&x, sizeof x);
+	return 0;
+}
+
+static int
+np_ulonglong(char *p, PyObject *v, const formatdef *f)
+{
+	unsigned PY_LONG_LONG x;
+	if (get_ulonglong(v, &x) < 0)
+		return -1;
+	memcpy(p, (char *)&x, sizeof x);
+	return 0;
+}
+#endif
+
+static int
+np_float(char *p, PyObject *v, const formatdef *f)
+{
+	float x = (float)PyFloat_AsDouble(v);
+	if (x == -1 && PyErr_Occurred()) {
+		PyErr_SetString(StructError,
+				"required argument is not a float");
+		return -1;
+	}
+	memcpy(p, (char *)&x, sizeof x);
+	return 0;
+}
+
+static int
+np_double(char *p, PyObject *v, const formatdef *f)
+{
+	double x = PyFloat_AsDouble(v);
+	if (x == -1 && PyErr_Occurred()) {
+		PyErr_SetString(StructError,
+				"required argument is not a float");
+		return -1;
+	}
+	memcpy(p, (char *)&x, sizeof(double));
+	return 0;
+}
+
+static int
+np_void_p(char *p, PyObject *v, const formatdef *f)
+{
+	void *x;
+
+	v = get_pylong(v);
+	if (v == NULL)
+		return -1;
+	assert(PyLong_Check(v));
+	x = PyLong_AsVoidPtr(v);
+	Py_DECREF(v);
+	if (x == NULL && PyErr_Occurred())
+		return -1;
+	memcpy(p, (char *)&x, sizeof x);
+	return 0;
+}
+
+static formatdef native_table[] = {
+	{'x',	sizeof(char),	0,		NULL},
+	{'b',	sizeof(char),	0,		nu_byte,	np_byte},
+	{'B',	sizeof(char),	0,		nu_ubyte,	np_ubyte},
+	{'c',	sizeof(char),	0,		nu_char,	np_char},
+	{'s',	sizeof(char),	0,		NULL},
+	{'p',	sizeof(char),	0,		NULL},
+	{'h',	sizeof(short),	SHORT_ALIGN,	nu_short,	np_short},
+	{'H',	sizeof(short),	SHORT_ALIGN,	nu_ushort,	np_ushort},
+	{'i',	sizeof(int),	INT_ALIGN,	nu_int,		np_int},
+	{'I',	sizeof(int),	INT_ALIGN,	nu_uint,	np_uint},
+	{'l',	sizeof(long),	LONG_ALIGN,	nu_long,	np_long},
+	{'L',	sizeof(long),	LONG_ALIGN,	nu_ulong,	np_ulong},
+#ifdef HAVE_LONG_LONG
+	{'q',	sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_longlong, np_longlong},
+	{'Q',	sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong},
+#endif
+	{'f',	sizeof(float),	FLOAT_ALIGN,	nu_float,	np_float},
+	{'d',	sizeof(double),	DOUBLE_ALIGN,	nu_double,	np_double},
+	{'P',	sizeof(void *),	VOID_P_ALIGN,	nu_void_p,	np_void_p},
+	{0}
+};
+
+/* Big-endian routines. *****************************************************/
+
+static PyObject *
+bu_int(const char *p, const formatdef *f)
+{
+	long x = 0;
+	Py_ssize_t i = f->size;
+	const unsigned char *bytes = (const unsigned char *)p;
+	do {
+		x = (x<<8) | *bytes++;
+	} while (--i > 0);
+	/* Extend the sign bit. */
+	if (SIZEOF_LONG > f->size)
+		x |= -(x & (1L << ((8 * f->size) - 1)));
+	return PyInt_FromLong(x);
+}
+
+static PyObject *
+bu_uint(const char *p, const formatdef *f)
+{
+	unsigned long x = 0;
+	Py_ssize_t i = f->size;
+	const unsigned char *bytes = (const unsigned char *)p;
+	do {
+		x = (x<<8) | *bytes++;
+	} while (--i > 0);
+	if (x <= LONG_MAX)
+		return PyInt_FromLong((long)x);
+	return PyLong_FromUnsignedLong(x);
+}
+
+static PyObject *
+bu_longlong(const char *p, const formatdef *f)
+{
+#ifdef HAVE_LONG_LONG
+	PY_LONG_LONG x = 0;
+	Py_ssize_t i = f->size;
+	const unsigned char *bytes = (const unsigned char *)p;
+	do {
+		x = (x<<8) | *bytes++;
+	} while (--i > 0);
+	/* Extend the sign bit. */
+	if (SIZEOF_LONG_LONG > f->size)
+		x |= -(x & ( (PY_LONG_LONG)1 << ((8 * f->size) - 1)));
+	if (x >= LONG_MIN && x <= LONG_MAX)
+		return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
+	return PyLong_FromLongLong(x);
+#else
+	return _PyLong_FromByteArray((const unsigned char *)p,
+				      8,
+				      0, /* little-endian */
+				      1  /* signed */);
+#endif
+}
+
+static PyObject *
+bu_ulonglong(const char *p, const formatdef *f)
+{
+#ifdef HAVE_LONG_LONG
+	unsigned PY_LONG_LONG x = 0;
+	Py_ssize_t i = f->size;
+	const unsigned char *bytes = (const unsigned char *)p;
+	do {
+		x = (x<<8) | *bytes++;
+	} while (--i > 0);
+	if (x <= LONG_MAX)
+		return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
+	return PyLong_FromUnsignedLongLong(x);
+#else
+	return _PyLong_FromByteArray((const unsigned char *)p,
+				      8,
+				      0, /* little-endian */
+				      0  /* signed */);
+#endif
+}
+
+static PyObject *
+bu_float(const char *p, const formatdef *f)
+{
+	return unpack_float(p, 0);
+}
+
+static PyObject *
+bu_double(const char *p, const formatdef *f)
+{
+	return unpack_double(p, 0);
+}
+
+static int
+bp_int(char *p, PyObject *v, const formatdef *f)
+{
+	long x;
+	Py_ssize_t i;
+	if (get_wrapped_long(v, &x) < 0)
+		return -1;
+	i = f->size;
+	if (i != SIZEOF_LONG) {
+		if ((i == 2) && (x < -32768 || x > 32767))
+			RANGE_ERROR(x, f, 0, 0xffffL);
+#if (SIZEOF_LONG != 4)
+		else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
+			RANGE_ERROR(x, f, 0, 0xffffffffL);
+#endif
+#ifdef PY_STRUCT_OVERFLOW_MASKING
+		else if ((i == 1) && (x < -128 || x > 127))
+			RANGE_ERROR(x, f, 0, 0xffL);
+#endif
+	}
+	do {
+		p[--i] = (char)x;
+		x >>= 8;
+	} while (i > 0);
+	return 0;
+}
+
+static int
+bp_uint(char *p, PyObject *v, const formatdef *f)
+{
+	unsigned long x;
+	Py_ssize_t i;
+	if (get_wrapped_ulong(v, &x) < 0)
+		return -1;
+	i = f->size;
+	if (i != SIZEOF_LONG) {
+		unsigned long maxint = 1;
+		maxint <<= (unsigned long)(i * 8);
+		if (x >= maxint)
+			RANGE_ERROR(x, f, 1, maxint - 1);
+	}
+	do {
+		p[--i] = (char)x;
+		x >>= 8;
+	} while (i > 0);
+	return 0;
+}
+
+static int
+bp_longlong(char *p, PyObject *v, const formatdef *f)
+{
+	int res;
+	v = get_pylong(v);
+	if (v == NULL)
+		return -1;
+	res = _PyLong_AsByteArray((PyLongObject *)v,
+			   	  (unsigned char *)p,
+				  8,
+				  0, /* little_endian */
+				  1  /* signed */);
+	Py_DECREF(v);
+	return res;
+}
+
+static int
+bp_ulonglong(char *p, PyObject *v, const formatdef *f)
+{
+	int res;
+	v = get_pylong(v);
+	if (v == NULL)
+		return -1;
+	res = _PyLong_AsByteArray((PyLongObject *)v,
+			   	  (unsigned char *)p,
+				  8,
+				  0, /* little_endian */
+				  0  /* signed */);
+	Py_DECREF(v);
+	return res;
+}
+
+static int
+bp_float(char *p, PyObject *v, const formatdef *f)
+{
+	double x = PyFloat_AsDouble(v);
+	if (x == -1 && PyErr_Occurred()) {
+		PyErr_SetString(StructError,
+				"required argument is not a float");
+		return -1;
+	}
+	return _PyFloat_Pack4(x, (unsigned char *)p, 0);
+}
+
+static int
+bp_double(char *p, PyObject *v, const formatdef *f)
+{
+	double x = PyFloat_AsDouble(v);
+	if (x == -1 && PyErr_Occurred()) {
+		PyErr_SetString(StructError,
+				"required argument is not a float");
+		return -1;
+	}
+	return _PyFloat_Pack8(x, (unsigned char *)p, 0);
+}
+
+static formatdef bigendian_table[] = {
+	{'x',	1,		0,		NULL},
+#ifdef PY_STRUCT_OVERFLOW_MASKING
+	/* Native packers do range checking without overflow masking. */
+	{'b',	1,		0,		nu_byte,	bp_int},
+	{'B',	1,		0,		nu_ubyte,	bp_uint},
+#else
+	{'b',	1,		0,		nu_byte,	np_byte},
+	{'B',	1,		0,		nu_ubyte,	np_ubyte},
+#endif
+	{'c',	1,		0,		nu_char,	np_char},
+	{'s',	1,		0,		NULL},
+	{'p',	1,		0,		NULL},
+	{'h',	2,		0,		bu_int,		bp_int},
+	{'H',	2,		0,		bu_uint,	bp_uint},
+	{'i',	4,		0,		bu_int,		bp_int},
+	{'I',	4,		0,		bu_uint,	bp_uint},
+	{'l',	4,		0,		bu_int,		bp_int},
+	{'L',	4,		0,		bu_uint,	bp_uint},
+	{'q',	8,		0,		bu_longlong,	bp_longlong},
+	{'Q',	8,		0,		bu_ulonglong,	bp_ulonglong},
+	{'f',	4,		0,		bu_float,	bp_float},
+	{'d',	8,		0,		bu_double,	bp_double},
+	{0}
+};
+
+/* Little-endian routines. *****************************************************/
+
+static PyObject *
+lu_int(const char *p, const formatdef *f)
+{
+	long x = 0;
+	Py_ssize_t i = f->size;
+	const unsigned char *bytes = (const unsigned char *)p;
+	do {
+		x = (x<<8) | bytes[--i];
+	} while (i > 0);
+	/* Extend the sign bit. */
+	if (SIZEOF_LONG > f->size)
+		x |= -(x & (1L << ((8 * f->size) - 1)));
+	return PyInt_FromLong(x);
+}
+
+static PyObject *
+lu_uint(const char *p, const formatdef *f)
+{
+	unsigned long x = 0;
+	Py_ssize_t i = f->size;
+	const unsigned char *bytes = (const unsigned char *)p;
+	do {
+		x = (x<<8) | bytes[--i];
+	} while (i > 0);
+	if (x <= LONG_MAX)
+		return PyInt_FromLong((long)x);
+	return PyLong_FromUnsignedLong((long)x);
+}
+
+static PyObject *
+lu_longlong(const char *p, const formatdef *f)
+{
+#ifdef HAVE_LONG_LONG
+	PY_LONG_LONG x = 0;
+	Py_ssize_t i = f->size;
+	const unsigned char *bytes = (const unsigned char *)p;
+	do {
+		x = (x<<8) | bytes[--i];
+	} while (i > 0);
+	/* Extend the sign bit. */
+	if (SIZEOF_LONG_LONG > f->size)
+		x |= -(x & ( (PY_LONG_LONG)1 << ((8 * f->size) - 1)));
+	if (x >= LONG_MIN && x <= LONG_MAX)
+		return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
+	return PyLong_FromLongLong(x);
+#else
+	return _PyLong_FromByteArray((const unsigned char *)p,
+				      8,
+				      1, /* little-endian */
+				      1  /* signed */);
+#endif
+}
+
+static PyObject *
+lu_ulonglong(const char *p, const formatdef *f)
+{
+#ifdef HAVE_LONG_LONG
+	unsigned PY_LONG_LONG x = 0;
+	Py_ssize_t i = f->size;
+	const unsigned char *bytes = (const unsigned char *)p;
+	do {
+		x = (x<<8) | bytes[--i];
+	} while (i > 0);
+	if (x <= LONG_MAX)
+		return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
+	return PyLong_FromUnsignedLongLong(x);
+#else
+	return _PyLong_FromByteArray((const unsigned char *)p,
+				      8,
+				      1, /* little-endian */
+				      0  /* signed */);
+#endif
+}
+
+static PyObject *
+lu_float(const char *p, const formatdef *f)
+{
+	return unpack_float(p, 1);
+}
+
+static PyObject *
+lu_double(const char *p, const formatdef *f)
+{
+	return unpack_double(p, 1);
+}
+
+static int
+lp_int(char *p, PyObject *v, const formatdef *f)
+{
+	long x;
+	Py_ssize_t i;
+	if (get_wrapped_long(v, &x) < 0)
+		return -1;
+	i = f->size;
+	if (i != SIZEOF_LONG) {
+		if ((i == 2) && (x < -32768 || x > 32767))
+			RANGE_ERROR(x, f, 0, 0xffffL);
+#if (SIZEOF_LONG != 4)
+		else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
+			RANGE_ERROR(x, f, 0, 0xffffffffL);
+#endif
+#ifdef PY_STRUCT_OVERFLOW_MASKING
+		else if ((i == 1) && (x < -128 || x > 127))
+			RANGE_ERROR(x, f, 0, 0xffL);
+#endif
+	}
+	do {
+		*p++ = (char)x;
+		x >>= 8;
+	} while (--i > 0);
+	return 0;
+}
+
+static int
+lp_uint(char *p, PyObject *v, const formatdef *f)
+{
+	unsigned long x;
+	Py_ssize_t i;
+	if (get_wrapped_ulong(v, &x) < 0)
+		return -1;
+	i = f->size;
+	if (i != SIZEOF_LONG) {
+		unsigned long maxint = 1;
+		maxint <<= (unsigned long)(i * 8);
+		if (x >= maxint)
+			RANGE_ERROR(x, f, 1, maxint - 1);
+	}
+	do {
+		*p++ = (char)x;
+		x >>= 8;
+	} while (--i > 0);
+	return 0;
+}
+
+static int
+lp_longlong(char *p, PyObject *v, const formatdef *f)
+{
+	int res;
+	v = get_pylong(v);
+	if (v == NULL)
+		return -1;
+	res = _PyLong_AsByteArray((PyLongObject*)v,
+			   	  (unsigned char *)p,
+				  8,
+				  1, /* little_endian */
+				  1  /* signed */);
+	Py_DECREF(v);
+	return res;
+}
+
+static int
+lp_ulonglong(char *p, PyObject *v, const formatdef *f)
+{
+	int res;
+	v = get_pylong(v);
+	if (v == NULL)
+		return -1;
+	res = _PyLong_AsByteArray((PyLongObject*)v,
+			   	  (unsigned char *)p,
+				  8,
+				  1, /* little_endian */
+				  0  /* signed */);
+	Py_DECREF(v);
+	return res;
+}
+
+static int
+lp_float(char *p, PyObject *v, const formatdef *f)
+{
+	double x = PyFloat_AsDouble(v);
+	if (x == -1 && PyErr_Occurred()) {
+		PyErr_SetString(StructError,
+				"required argument is not a float");
+		return -1;
+	}
+	return _PyFloat_Pack4(x, (unsigned char *)p, 1);
+}
+
+static int
+lp_double(char *p, PyObject *v, const formatdef *f)
+{
+	double x = PyFloat_AsDouble(v);
+	if (x == -1 && PyErr_Occurred()) {
+		PyErr_SetString(StructError,
+				"required argument is not a float");
+		return -1;
+	}
+	return _PyFloat_Pack8(x, (unsigned char *)p, 1);
+}
+
+static formatdef lilendian_table[] = {
+	{'x',	1,		0,		NULL},
+#ifdef PY_STRUCT_OVERFLOW_MASKING
+	/* Native packers do range checking without overflow masking. */
+	{'b',	1,		0,		nu_byte,	lp_int},
+	{'B',	1,		0,		nu_ubyte,	lp_uint},
+#else
+	{'b',	1,		0,		nu_byte,	np_byte},
+	{'B',	1,		0,		nu_ubyte,	np_ubyte},
+#endif
+	{'c',	1,		0,		nu_char,	np_char},
+	{'s',	1,		0,		NULL},
+	{'p',	1,		0,		NULL},
+	{'h',	2,		0,		lu_int,		lp_int},
+	{'H',	2,		0,		lu_uint,	lp_uint},
+	{'i',	4,		0,		lu_int,		lp_int},
+	{'I',	4,		0,		lu_uint,	lp_uint},
+	{'l',	4,		0,		lu_int,		lp_int},
+	{'L',	4,		0,		lu_uint,	lp_uint},
+	{'q',	8,		0,		lu_longlong,	lp_longlong},
+	{'Q',	8,		0,		lu_ulonglong,	lp_ulonglong},
+	{'f',	4,		0,		lu_float,	lp_float},
+	{'d',	8,		0,		lu_double,	lp_double},
+	{0}
+};
+
+
+static const formatdef *
+whichtable(char **pfmt)
+{
+	const char *fmt = (*pfmt)++; /* May be backed out of later */
+	switch (*fmt) {
+	case '<':
+		return lilendian_table;
+	case '>':
+	case '!': /* Network byte order is big-endian */
+		return bigendian_table;
+	case '=': { /* Host byte order -- different from native in aligment! */
+		int n = 1;
+		char *p = (char *) &n;
+		if (*p == 1)
+			return lilendian_table;
+		else
+			return bigendian_table;
+	}
+	default:
+		--*pfmt; /* Back out of pointer increment */
+		/* Fall through */
+	case '@':
+		return native_table;
+	}
+}
+
+
+/* Get the table entry for a format code */
+
+static const formatdef *
+getentry(int c, const formatdef *f)
+{
+	for (; f->format != '\0'; f++) {
+		if (f->format == c) {
+			return f;
+		}
+	}
+	PyErr_SetString(StructError, "bad char in struct format");
+	return NULL;
+}
+
+
+/* Align a size according to a format code */
+
+static int
+align(Py_ssize_t size, char c, const formatdef *e)
+{
+	if (e->format == c) {
+		if (e->alignment) {
+			size = ((size + e->alignment - 1)
+				/ e->alignment)
+				* e->alignment;
+		}
+	}
+	return size;
+}
+
+
+/* calculate the size of a format string */
+
+static int
+prepare_s(PyStructObject *self)
+{
+	const formatdef *f;
+	const formatdef *e;
+	formatcode *codes;
+
+	const char *s;
+	const char *fmt;
+	char c;
+	Py_ssize_t size, len, num, itemsize, x;
+
+	fmt = PyString_AS_STRING(self->s_format);
+
+	f = whichtable((char **)&fmt);
+
+	s = fmt;
+	size = 0;
+	len = 0;
+	while ((c = *s++) != '\0') {
+		if (isspace(Py_CHARMASK(c)))
+			continue;
+		if ('0' <= c && c <= '9') {
+			num = c - '0';
+			while ('0' <= (c = *s++) && c <= '9') {
+				x = num*10 + (c - '0');
+				if (x/10 != num) {
+					PyErr_SetString(
+						StructError,
+						"overflow in item count");
+					return -1;
+				}
+				num = x;
+			}
+			if (c == '\0')
+				break;
+		}
+		else
+			num = 1;
+
+		e = getentry(c, f);
+		if (e == NULL)
+			return -1;
+
+		switch (c) {
+			case 's': /* fall through */
+			case 'p': len++; break;
+			case 'x': break;
+			default: len += num; break;
+		}
+
+		itemsize = e->size;
+		size = align(size, c, e);
+		x = num * itemsize;
+		size += x;
+		if (x/itemsize != num || size < 0) {
+			PyErr_SetString(StructError,
+					"total struct size too long");
+			return -1;
+		}
+	}
+
+	self->s_size = size;
+	self->s_len = len;
+	codes = PyMem_MALLOC((len + 1) * sizeof(formatcode));
+	if (codes == NULL) {
+		PyErr_NoMemory();
+		return -1;
+	}
+	self->s_codes = codes;
+
+	s = fmt;
+	size = 0;
+	while ((c = *s++) != '\0') {
+		if (isspace(Py_CHARMASK(c)))
+			continue;
+		if ('0' <= c && c <= '9') {
+			num = c - '0';
+			while ('0' <= (c = *s++) && c <= '9')
+				num = num*10 + (c - '0');
+			if (c == '\0')
+				break;
+		}
+		else
+			num = 1;
+
+		e = getentry(c, f);
+
+		size = align(size, c, e);
+		if (c == 's' || c == 'p') {
+			codes->offset = size;
+			codes->size = num;
+			codes->fmtdef = e;
+			codes++;
+			size += num;
+		} else if (c == 'x') {
+			size += num;
+		} else {
+			while (--num >= 0) {
+				codes->offset = size;
+				codes->size = e->size;
+				codes->fmtdef = e;
+				codes++;
+				size += e->size;
+			}
+		}
+	}
+	codes->fmtdef = NULL;
+	codes->offset = size;
+	codes->size = 0;
+
+	return 0;
+}
+
+static PyObject *
+s_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	PyObject *self;
+
+	assert(type != NULL && type->tp_alloc != NULL);
+
+	self = type->tp_alloc(type, 0);
+	if (self != NULL) {
+		PyStructObject *s = (PyStructObject*)self;
+		Py_INCREF(Py_None);
+		s->s_format = Py_None;
+		s->s_codes = NULL;
+		s->s_size = -1;
+		s->s_len = -1;
+	}
+	return self;
+}
+
+static int
+s_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+	PyStructObject *soself = (PyStructObject *)self;
+	PyObject *o_format = NULL;
+	int ret = 0;
+	static char *kwlist[] = {"format", 0};
+
+	assert(PyStruct_Check(self));
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwds, "S:Struct", kwlist,
+					 &o_format))
+		return -1;
+
+	Py_INCREF(o_format);
+	Py_XDECREF(soself->s_format);
+	soself->s_format = o_format;
+
+	ret = prepare_s(soself);
+	return ret;
+}
+
+static void
+s_dealloc(PyStructObject *s)
+{
+	if (s->weakreflist != NULL)
+		PyObject_ClearWeakRefs((PyObject *)s);
+	if (s->s_codes != NULL) {
+		PyMem_FREE(s->s_codes);
+	}
+	Py_XDECREF(s->s_format);
+	s->ob_type->tp_free((PyObject *)s);
+}
+
+static PyObject *
+s_unpack_internal(PyStructObject *soself, char *startfrom) {
+	formatcode *code;
+	Py_ssize_t i = 0;
+	PyObject *result = PyTuple_New(soself->s_len);
+	if (result == NULL)
+		return NULL;
+
+	for (code = soself->s_codes; code->fmtdef != NULL; code++) {
+		PyObject *v;
+		const formatdef *e = code->fmtdef;
+		const char *res = startfrom + code->offset;
+		if (e->format == 's') {
+			v = PyString_FromStringAndSize(res, code->size);
+		} else if (e->format == 'p') {
+			Py_ssize_t n = *(unsigned char*)res;
+			if (n >= code->size)
+				n = code->size - 1;
+			v = PyString_FromStringAndSize(res + 1, n);
+		} else {
+			v = e->unpack(res, e);
+		}
+		if (v == NULL)
+			goto fail;
+		PyTuple_SET_ITEM(result, i++, v);
+	}
+
+	return result;
+fail:
+	Py_DECREF(result);
+	return NULL;
+}
+
+
+PyDoc_STRVAR(s_unpack__doc__,
+"S.unpack(str) -> (v1, v2, ...)\n\
+\n\
+Return tuple containing values unpacked according to this Struct's format.\n\
+Requires len(str) == self.size. See struct.__doc__ for more on format\n\
+strings.");
+
+static PyObject *
+s_unpack(PyObject *self, PyObject *inputstr)
+{
+	char *start;
+	Py_ssize_t len;
+	PyObject *args=NULL, *result;
+	PyStructObject *soself = (PyStructObject *)self;
+	assert(PyStruct_Check(self));
+	assert(soself->s_codes != NULL);
+	if (inputstr == NULL)
+		goto fail;
+	if (PyString_Check(inputstr) &&
+		PyString_GET_SIZE(inputstr) == soself->s_size) {
+			return s_unpack_internal(soself, PyString_AS_STRING(inputstr));
+	}
+	args = PyTuple_Pack(1, inputstr);
+	if (args == NULL)
+		return NULL;
+	if (!PyArg_ParseTuple(args, "s#:unpack", &start, &len))
+		goto fail;
+	if (soself->s_size != len)
+		goto fail;
+	result = s_unpack_internal(soself, start);
+	Py_DECREF(args);
+	return result;
+
+fail:
+	Py_XDECREF(args);
+	PyErr_Format(StructError,
+		"unpack requires a string argument of length %zd",
+		soself->s_size);
+	return NULL;
+}
+
+PyDoc_STRVAR(s_unpack_from__doc__,
+"S.unpack_from(buffer[, offset]) -> (v1, v2, ...)\n\
+\n\
+Return tuple containing values unpacked according to this Struct's format.\n\
+Unlike unpack, unpack_from can unpack values from any object supporting\n\
+the buffer API, not just str. Requires len(buffer[offset:]) >= self.size.\n\
+See struct.__doc__ for more on format strings.");
+
+static PyObject *
+s_unpack_from(PyObject *self, PyObject *args, PyObject *kwds)
+{
+	static char *kwlist[] = {"buffer", "offset", 0};
+#if (PY_VERSION_HEX < 0x02050000)
+	static char *fmt = "z#|i:unpack_from";
+#else
+	static char *fmt = "z#|n:unpack_from";
+#endif
+	Py_ssize_t buffer_len = 0, offset = 0;
+	char *buffer = NULL;
+	PyStructObject *soself = (PyStructObject *)self;
+	assert(PyStruct_Check(self));
+	assert(soself->s_codes != NULL);
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
+					 &buffer, &buffer_len, &offset))
+		return NULL;
+
+	if (buffer == NULL) {
+		PyErr_Format(StructError,
+			"unpack_from requires a buffer argument");
+		return NULL;
+	}
+
+	if (offset < 0)
+		offset += buffer_len;
+
+	if (offset < 0 || (buffer_len - offset) < soself->s_size) {
+		PyErr_Format(StructError,
+			"unpack_from requires a buffer of at least %zd bytes",
+			soself->s_size);
+		return NULL;
+	}
+	return s_unpack_internal(soself, buffer + offset);
+}
+
+
+/*
+ * Guts of the pack function.
+ *
+ * Takes a struct object, a tuple of arguments, and offset in that tuple of
+ * argument for where to start processing the arguments for packing, and a
+ * character buffer for writing the packed string.  The caller must insure
+ * that the buffer may contain the required length for packing the arguments.
+ * 0 is returned on success, 1 is returned if there is an error.
+ *
+ */
+static int
+s_pack_internal(PyStructObject *soself, PyObject *args, int offset, char* buf)
+{
+	formatcode *code;
+	/* XXX(nnorwitz): why does i need to be a local?  can we use
+	   the offset parameter or do we need the wider width? */
+	Py_ssize_t i;
+
+	memset(buf, '\0', soself->s_size);
+	i = offset;
+	for (code = soself->s_codes; code->fmtdef != NULL; code++) {
+		Py_ssize_t n;
+		PyObject *v = PyTuple_GET_ITEM(args, i++);
+		const formatdef *e = code->fmtdef;
+		char *res = buf + code->offset;
+		if (e->format == 's') {
+			if (!PyString_Check(v)) {
+				PyErr_SetString(StructError,
+						"argument for 's' must be a string");
+				return -1;
+			}
+			n = PyString_GET_SIZE(v);
+			if (n > code->size)
+				n = code->size;
+			if (n > 0)
+				memcpy(res, PyString_AS_STRING(v), n);
+		} else if (e->format == 'p') {
+			if (!PyString_Check(v)) {
+				PyErr_SetString(StructError,
+						"argument for 'p' must be a string");
+				return -1;
+			}
+			n = PyString_GET_SIZE(v);
+			if (n > (code->size - 1))
+				n = code->size - 1;
+			if (n > 0)
+				memcpy(res + 1, PyString_AS_STRING(v), n);
+			if (n > 255)
+				n = 255;
+			*res = Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char);
+		} else {
+			if (e->pack(res, v, e) < 0) {
+				if (PyLong_Check(v) && PyErr_ExceptionMatches(PyExc_OverflowError))
+					PyErr_SetString(StructError,
+							"long too large to convert to int");
+				return -1;
+			}
+		}
+	}
+
+	/* Success */
+	return 0;
+}
+
+
+PyDoc_STRVAR(s_pack__doc__,
+"S.pack(v1, v2, ...) -> string\n\
+\n\
+Return a string containing values v1, v2, ... packed according to this\n\
+Struct's format. See struct.__doc__ for more on format strings.");
+
+static PyObject *
+s_pack(PyObject *self, PyObject *args)
+{
+	PyStructObject *soself;
+	PyObject *result;
+
+	/* Validate arguments. */
+	soself = (PyStructObject *)self;
+	assert(PyStruct_Check(self));
+	assert(soself->s_codes != NULL);
+	if (PyTuple_GET_SIZE(args) != soself->s_len)
+	{
+		PyErr_Format(StructError,
+			"pack requires exactly %zd arguments", soself->s_len);
+		return NULL;
+	}
+
+	/* Allocate a new string */
+	result = PyString_FromStringAndSize((char *)NULL, soself->s_size);
+	if (result == NULL)
+		return NULL;
+
+	/* Call the guts */
+	if ( s_pack_internal(soself, args, 0, PyString_AS_STRING(result)) != 0 ) {
+		Py_DECREF(result);
+		return NULL;
+	}
+
+	return result;
+}
+
+PyDoc_STRVAR(s_pack_into__doc__,
+"S.pack_into(buffer, offset, v1, v2, ...)\n\
+\n\
+Pack the values v1, v2, ... according to this Struct's format, write \n\
+the packed bytes into the writable buffer buf starting at offset.  Note\n\
+that the offset is not an optional argument.  See struct.__doc__ for \n\
+more on format strings.");
+
+static PyObject *
+s_pack_into(PyObject *self, PyObject *args)
+{
+	PyStructObject *soself;
+	char *buffer;
+	Py_ssize_t buffer_len, offset;
+
+	/* Validate arguments.  +1 is for the first arg as buffer. */
+	soself = (PyStructObject *)self;
+	assert(PyStruct_Check(self));
+	assert(soself->s_codes != NULL);
+	if (PyTuple_GET_SIZE(args) != (soself->s_len + 2))
+	{
+		PyErr_Format(StructError,
+			     "pack_into requires exactly %zd arguments",
+			     (soself->s_len + 2));
+		return NULL;
+	}
+
+	/* Extract a writable memory buffer from the first argument */
+	if ( PyObject_AsWriteBuffer(PyTuple_GET_ITEM(args, 0),
+								(void**)&buffer, &buffer_len) == -1 ) {
+		return NULL;
+	}
+	assert( buffer_len >= 0 );
+
+	/* Extract the offset from the first argument */
+	offset = PyInt_AsSsize_t(PyTuple_GET_ITEM(args, 1));
+
+	/* Support negative offsets. */
+	if (offset < 0)
+		offset += buffer_len;
+
+	/* Check boundaries */
+	if (offset < 0 || (buffer_len - offset) < soself->s_size) {
+		PyErr_Format(StructError,
+			     "pack_into requires a buffer of at least %zd bytes",
+			     soself->s_size);
+		return NULL;
+	}
+
+	/* Call the guts */
+	if ( s_pack_internal(soself, args, 2, buffer + offset) != 0 ) {
+		return NULL;
+	}
+
+	Py_RETURN_NONE;
+}
+
+static PyObject *
+s_get_format(PyStructObject *self, void *unused)
+{
+	Py_INCREF(self->s_format);
+	return self->s_format;
+}
+
+static PyObject *
+s_get_size(PyStructObject *self, void *unused)
+{
+    return PyInt_FromSsize_t(self->s_size);
+}
+
+/* List of functions */
+
+static struct PyMethodDef s_methods[] = {
+	{"pack",	s_pack,		METH_VARARGS, s_pack__doc__},
+	{"pack_into",	s_pack_into,	METH_VARARGS, s_pack_into__doc__},
+	{"unpack",	s_unpack,       METH_O, s_unpack__doc__},
+	{"unpack_from",	(PyCFunction)s_unpack_from, METH_KEYWORDS,
+			s_unpack_from__doc__},
+	{NULL,	 NULL}		/* sentinel */
+};
+
+PyDoc_STRVAR(s__doc__, "Compiled struct object");
+
+#define OFF(x) offsetof(PyStructObject, x)
+
+static PyGetSetDef s_getsetlist[] = {
+	{"format", (getter)s_get_format, (setter)NULL, "struct format string", NULL},
+	{"size", (getter)s_get_size, (setter)NULL, "struct size in bytes", NULL},
+	{NULL} /* sentinel */
+};
+
+static
+PyTypeObject PyStructType = {
+	PyObject_HEAD_INIT(NULL)
+	0,
+	"Struct",
+	sizeof(PyStructObject),
+	0,
+	(destructor)s_dealloc,	/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	0,					/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	PyObject_GenericGetAttr,	/* tp_getattro */
+	PyObject_GenericSetAttr,	/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_WEAKREFS,/* tp_flags */
+	s__doc__,			/* tp_doc */
+	0,					/* tp_traverse */
+	0,					/* tp_clear */
+	0,					/* tp_richcompare */
+	offsetof(PyStructObject, weakreflist),	/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	s_methods,			/* tp_methods */
+	NULL,				/* tp_members */
+	s_getsetlist,		/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	s_init,				/* tp_init */
+	PyType_GenericAlloc,/* tp_alloc */
+	s_new,				/* tp_new */
+	PyObject_Del,		/* tp_free */
+};
+
+/* Module initialization */
+
+PyMODINIT_FUNC
+init_struct(void)
+{
+	PyObject *m = Py_InitModule("_struct", NULL);
+	if (m == NULL)
+		return;
+
+	PyStructType.ob_type = &PyType_Type;
+	if (PyType_Ready(&PyStructType) < 0)
+		return;
+
+#ifdef PY_STRUCT_OVERFLOW_MASKING
+	if (pyint_zero == NULL) {
+		pyint_zero = PyInt_FromLong(0);
+		if (pyint_zero == NULL)
+			return;
+	}
+	if (pylong_ulong_mask == NULL) {
+#if (SIZEOF_LONG == 4)
+		pylong_ulong_mask = PyLong_FromString("FFFFFFFF", NULL, 16);
+#else
+		pylong_ulong_mask = PyLong_FromString("FFFFFFFFFFFFFFFF", NULL, 16);
+#endif
+		if (pylong_ulong_mask == NULL)
+			return;
+	}
+
+#else
+	/* This speed trick can't be used until overflow masking goes away, because
+	   native endian always raises exceptions instead of overflow masking. */
+
+	/* Check endian and swap in faster functions */
+	{
+		int one = 1;
+		formatdef *native = native_table;
+		formatdef *other, *ptr;
+		if ((int)*(unsigned char*)&one)
+			other = lilendian_table;
+		else
+			other = bigendian_table;
+		/* Scan through the native table, find a matching
+		   entry in the endian table and swap in the
+		   native implementations whenever possible
+		   (64-bit platforms may not have "standard" sizes) */
+		while (native->format != '\0' && other->format != '\0') {
+			ptr = other;
+			while (ptr->format != '\0') {
+				if (ptr->format == native->format) {
+					/* Match faster when formats are
+					   listed in the same order */
+					if (ptr == other)
+						other++;
+					/* Only use the trick if the
+					   size matches */
+					if (ptr->size != native->size)
+						break;
+					/* Skip float and double, could be
+					   "unknown" float format */
+					if (ptr->format == 'd' || ptr->format == 'f')
+						break;
+					ptr->pack = native->pack;
+					ptr->unpack = native->unpack;
+					break;
+				}
+				ptr++;
+			}
+			native++;
+		}
+	}
+#endif
+
+	/* Add some symbolic constants to the module */
+	if (StructError == NULL) {
+		StructError = PyErr_NewException("struct.error", NULL, NULL);
+		if (StructError == NULL)
+			return;
+	}
+
+	Py_INCREF(StructError);
+	PyModule_AddObject(m, "error", StructError);
+
+	Py_INCREF((PyObject*)&PyStructType);
+	PyModule_AddObject(m, "Struct", (PyObject*)&PyStructType);
+
+	PyModule_AddIntConstant(m, "_PY_STRUCT_RANGE_CHECKING", 1);
+#ifdef PY_STRUCT_OVERFLOW_MASKING
+	PyModule_AddIntConstant(m, "_PY_STRUCT_OVERFLOW_MASKING", 1);
+#endif
+#ifdef PY_STRUCT_FLOAT_COERCE
+	PyModule_AddIntConstant(m, "_PY_STRUCT_FLOAT_COERCE", 1);
+#endif
+
+}

Added: vendor/Python/current/Modules/_testcapimodule.c
===================================================================
--- vendor/Python/current/Modules/_testcapimodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_testcapimodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,898 @@
+/*
+ * C Extension module to test Python interpreter C APIs.
+ *
+ * The 'test_*' functions exported by this module are run as part of the
+ * standard Python regression test, via Lib/test/test_capi.py.
+ */
+
+#include "Python.h"
+#include <float.h>
+#include "structmember.h"
+
+#ifdef WITH_THREAD
+#include "pythread.h"
+#endif /* WITH_THREAD */
+static PyObject *TestError;	/* set to exception object in init */
+
+/* Raise TestError with test_name + ": " + msg, and return NULL. */
+
+static PyObject *
+raiseTestError(const char* test_name, const char* msg)
+{
+	char buf[2048];
+
+	if (strlen(test_name) + strlen(msg) > sizeof(buf) - 50)
+		PyErr_SetString(TestError, "internal error msg too large");
+	else {
+		PyOS_snprintf(buf, sizeof(buf), "%s: %s", test_name, msg);
+		PyErr_SetString(TestError, buf);
+	}
+	return NULL;
+}
+
+/* Test #defines from pyconfig.h (particularly the SIZEOF_* defines).
+
+   The ones derived from autoconf on the UNIX-like OSes can be relied
+   upon (in the absence of sloppy cross-compiling), but the Windows
+   platforms have these hardcoded.  Better safe than sorry.
+*/
+static PyObject*
+sizeof_error(const char* fatname, const char* typname,
+        int expected, int got)
+{
+	char buf[1024];
+	PyOS_snprintf(buf, sizeof(buf),
+		"%.200s #define == %d but sizeof(%.200s) == %d",
+		fatname, expected, typname, got);
+	PyErr_SetString(TestError, buf);
+	return (PyObject*)NULL;
+}
+
+static PyObject*
+test_config(PyObject *self)
+{
+#define CHECK_SIZEOF(FATNAME, TYPE) \
+	    if (FATNAME != sizeof(TYPE)) \
+    	    	return sizeof_error(#FATNAME, #TYPE, FATNAME, sizeof(TYPE))
+
+	CHECK_SIZEOF(SIZEOF_SHORT, short);
+	CHECK_SIZEOF(SIZEOF_INT, int);
+	CHECK_SIZEOF(SIZEOF_LONG, long);
+	CHECK_SIZEOF(SIZEOF_VOID_P, void*);
+	CHECK_SIZEOF(SIZEOF_TIME_T, time_t);
+#ifdef HAVE_LONG_LONG
+	CHECK_SIZEOF(SIZEOF_LONG_LONG, PY_LONG_LONG);
+#endif
+
+#undef CHECK_SIZEOF
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject*
+test_list_api(PyObject *self)
+{
+	PyObject* list;
+	int i;
+
+	/* SF bug 132008:  PyList_Reverse segfaults */
+#define NLIST 30
+	list = PyList_New(NLIST);
+	if (list == (PyObject*)NULL)
+		return (PyObject*)NULL;
+	/* list = range(NLIST) */
+	for (i = 0; i < NLIST; ++i) {
+		PyObject* anint = PyInt_FromLong(i);
+		if (anint == (PyObject*)NULL) {
+			Py_DECREF(list);
+			return (PyObject*)NULL;
+		}
+		PyList_SET_ITEM(list, i, anint);
+	}
+	/* list.reverse(), via PyList_Reverse() */
+	i = PyList_Reverse(list);   /* should not blow up! */
+	if (i != 0) {
+		Py_DECREF(list);
+		return (PyObject*)NULL;
+	}
+	/* Check that list == range(29, -1, -1) now */
+	for (i = 0; i < NLIST; ++i) {
+		PyObject* anint = PyList_GET_ITEM(list, i);
+		if (PyInt_AS_LONG(anint) != NLIST-1-i) {
+			PyErr_SetString(TestError,
+			                "test_list_api: reverse screwed up");
+			Py_DECREF(list);
+			return (PyObject*)NULL;
+		}
+	}
+	Py_DECREF(list);
+#undef NLIST
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static int
+test_dict_inner(int count)
+{
+	Py_ssize_t pos = 0, iterations = 0;
+	int i;
+	PyObject *dict = PyDict_New();
+	PyObject *v, *k;
+
+	if (dict == NULL)
+		return -1;
+
+	for (i = 0; i < count; i++) {
+		v = PyInt_FromLong(i);
+		PyDict_SetItem(dict, v, v);
+		Py_DECREF(v);
+	}
+
+	while (PyDict_Next(dict, &pos, &k, &v)) {
+		PyObject *o;
+		iterations++;
+
+		i = PyInt_AS_LONG(v) + 1;
+		o = PyInt_FromLong(i);
+		if (o == NULL)
+			return -1;
+		if (PyDict_SetItem(dict, k, o) < 0) {
+			Py_DECREF(o);
+			return -1;
+		}
+		Py_DECREF(o);
+	}
+
+	Py_DECREF(dict);
+
+	if (iterations != count) {
+		PyErr_SetString(
+			TestError,
+			"test_dict_iteration: dict iteration went wrong ");
+		return -1;
+	} else {
+		return 0;
+	}
+}
+
+static PyObject*
+test_dict_iteration(PyObject* self)
+{
+	int i;
+
+	for (i = 0; i < 200; i++) {
+		if (test_dict_inner(i) < 0) {
+			return NULL;
+		}
+	}
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+
+/* Tests of PyLong_{As, From}{Unsigned,}Long(), and (#ifdef HAVE_LONG_LONG)
+   PyLong_{As, From}{Unsigned,}LongLong().
+
+   Note that the meat of the test is contained in testcapi_long.h.
+   This is revolting, but delicate code duplication is worse:  "almost
+   exactly the same" code is needed to test PY_LONG_LONG, but the ubiquitous
+   dependence on type names makes it impossible to use a parameterized
+   function.  A giant macro would be even worse than this.  A C++ template
+   would be perfect.
+
+   The "report an error" functions are deliberately not part of the #include
+   file:  if the test fails, you can set a breakpoint in the appropriate
+   error function directly, and crawl back from there in the debugger.
+*/
+
+#define UNBIND(X)  Py_DECREF(X); (X) = NULL
+
+static PyObject *
+raise_test_long_error(const char* msg)
+{
+	return raiseTestError("test_long_api", msg);
+}
+
+#define TESTNAME	test_long_api_inner
+#define TYPENAME	long
+#define F_S_TO_PY	PyLong_FromLong
+#define F_PY_TO_S	PyLong_AsLong
+#define F_U_TO_PY	PyLong_FromUnsignedLong
+#define F_PY_TO_U	PyLong_AsUnsignedLong
+
+#include "testcapi_long.h"
+
+static PyObject *
+test_long_api(PyObject* self)
+{
+	return TESTNAME(raise_test_long_error);
+}
+
+#undef TESTNAME
+#undef TYPENAME
+#undef F_S_TO_PY
+#undef F_PY_TO_S
+#undef F_U_TO_PY
+#undef F_PY_TO_U
+
+#ifdef HAVE_LONG_LONG
+
+static PyObject *
+raise_test_longlong_error(const char* msg)
+{
+	return raiseTestError("test_longlong_api", msg);
+}
+
+#define TESTNAME	test_longlong_api_inner
+#define TYPENAME	PY_LONG_LONG
+#define F_S_TO_PY	PyLong_FromLongLong
+#define F_PY_TO_S	PyLong_AsLongLong
+#define F_U_TO_PY	PyLong_FromUnsignedLongLong
+#define F_PY_TO_U	PyLong_AsUnsignedLongLong
+
+#include "testcapi_long.h"
+
+static PyObject *
+test_longlong_api(PyObject* self, PyObject *args)
+{
+	return TESTNAME(raise_test_longlong_error);
+}
+
+#undef TESTNAME
+#undef TYPENAME
+#undef F_S_TO_PY
+#undef F_PY_TO_S
+#undef F_U_TO_PY
+#undef F_PY_TO_U
+
+/* Test the L code for PyArg_ParseTuple.  This should deliver a PY_LONG_LONG
+   for both long and int arguments.  The test may leak a little memory if
+   it fails.
+*/
+static PyObject *
+test_L_code(PyObject *self)
+{
+	PyObject *tuple, *num;
+	PY_LONG_LONG value;
+
+        tuple = PyTuple_New(1);
+        if (tuple == NULL)
+        	return NULL;
+
+        num = PyLong_FromLong(42);
+        if (num == NULL)
+        	return NULL;
+
+        PyTuple_SET_ITEM(tuple, 0, num);
+
+        value = -1;
+        if (PyArg_ParseTuple(tuple, "L:test_L_code", &value) < 0)
+        	return NULL;
+        if (value != 42)
+        	return raiseTestError("test_L_code",
+			"L code returned wrong value for long 42");
+
+	Py_DECREF(num);
+        num = PyInt_FromLong(42);
+        if (num == NULL)
+        	return NULL;
+
+        PyTuple_SET_ITEM(tuple, 0, num);
+
+	value = -1;
+        if (PyArg_ParseTuple(tuple, "L:test_L_code", &value) < 0)
+        	return NULL;
+        if (value != 42)
+        	return raiseTestError("test_L_code",
+			"L code returned wrong value for int 42");
+
+	Py_DECREF(tuple);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+#endif	/* ifdef HAVE_LONG_LONG */
+
+/* Test tuple argument processing */
+static PyObject *
+getargs_tuple(PyObject *self, PyObject *args)
+{
+	int a, b, c;
+	if (!PyArg_ParseTuple(args, "i(ii)", &a, &b, &c))
+		return NULL;
+	return Py_BuildValue("iii", a, b, c);
+}
+
+/* Functions to call PyArg_ParseTuple with integer format codes,
+   and return the result.
+*/
+static PyObject *
+getargs_b(PyObject *self, PyObject *args)
+{
+	unsigned char value;
+	if (!PyArg_ParseTuple(args, "b", &value))
+		return NULL;
+	return PyLong_FromUnsignedLong((unsigned long)value);
+}
+
+static PyObject *
+getargs_B(PyObject *self, PyObject *args)
+{
+	unsigned char value;
+	if (!PyArg_ParseTuple(args, "B", &value))
+		return NULL;
+	return PyLong_FromUnsignedLong((unsigned long)value);
+}
+
+static PyObject *
+getargs_H(PyObject *self, PyObject *args)
+{
+	unsigned short value;
+	if (!PyArg_ParseTuple(args, "H", &value))
+		return NULL;
+	return PyLong_FromUnsignedLong((unsigned long)value);
+}
+
+static PyObject *
+getargs_I(PyObject *self, PyObject *args)
+{
+	unsigned int value;
+	if (!PyArg_ParseTuple(args, "I", &value))
+		return NULL;
+	return PyLong_FromUnsignedLong((unsigned long)value);
+}
+
+static PyObject *
+getargs_k(PyObject *self, PyObject *args)
+{
+	unsigned long value;
+	if (!PyArg_ParseTuple(args, "k", &value))
+		return NULL;
+	return PyLong_FromUnsignedLong(value);
+}
+
+static PyObject *
+getargs_i(PyObject *self, PyObject *args)
+{
+	int value;
+	if (!PyArg_ParseTuple(args, "i", &value))
+		return NULL;
+	return PyLong_FromLong((long)value);
+}
+
+static PyObject *
+getargs_l(PyObject *self, PyObject *args)
+{
+	long value;
+	if (!PyArg_ParseTuple(args, "l", &value))
+		return NULL;
+	return PyLong_FromLong(value);
+}
+
+static PyObject *
+getargs_n(PyObject *self, PyObject *args)
+{
+	Py_ssize_t value;
+	if (!PyArg_ParseTuple(args, "n", &value))
+	return NULL;
+	return PyInt_FromSsize_t(value);
+}
+
+#ifdef HAVE_LONG_LONG
+static PyObject *
+getargs_L(PyObject *self, PyObject *args)
+{
+	PY_LONG_LONG value;
+	if (!PyArg_ParseTuple(args, "L", &value))
+		return NULL;
+	return PyLong_FromLongLong(value);
+}
+
+static PyObject *
+getargs_K(PyObject *self, PyObject *args)
+{
+	unsigned PY_LONG_LONG value;
+	if (!PyArg_ParseTuple(args, "K", &value))
+		return NULL;
+	return PyLong_FromUnsignedLongLong(value);
+}
+#endif
+
+/* This function not only tests the 'k' getargs code, but also the
+   PyInt_AsUnsignedLongMask() and PyInt_AsUnsignedLongMask() functions. */
+static PyObject *
+test_k_code(PyObject *self)
+{
+	PyObject *tuple, *num;
+	unsigned long value;
+
+        tuple = PyTuple_New(1);
+        if (tuple == NULL)
+        	return NULL;
+
+	/* a number larger than ULONG_MAX even on 64-bit platforms */
+        num = PyLong_FromString("FFFFFFFFFFFFFFFFFFFFFFFF", NULL, 16);
+        if (num == NULL)
+        	return NULL;
+
+	value = PyInt_AsUnsignedLongMask(num);
+	if (value != ULONG_MAX)
+        	return raiseTestError("test_k_code",
+	    "PyInt_AsUnsignedLongMask() returned wrong value for long 0xFFF...FFF");
+
+        PyTuple_SET_ITEM(tuple, 0, num);
+
+        value = 0;
+        if (PyArg_ParseTuple(tuple, "k:test_k_code", &value) < 0)
+        	return NULL;
+        if (value != ULONG_MAX)
+        	return raiseTestError("test_k_code",
+			"k code returned wrong value for long 0xFFF...FFF");
+
+	Py_DECREF(num);
+        num = PyLong_FromString("-FFFFFFFF000000000000000042", NULL, 16);
+        if (num == NULL)
+        	return NULL;
+
+	value = PyInt_AsUnsignedLongMask(num);
+	if (value != (unsigned long)-0x42)
+        	return raiseTestError("test_k_code",
+	    "PyInt_AsUnsignedLongMask() returned wrong value for long 0xFFF...FFF");
+
+        PyTuple_SET_ITEM(tuple, 0, num);
+
+	value = 0;
+        if (PyArg_ParseTuple(tuple, "k:test_k_code", &value) < 0)
+        	return NULL;
+        if (value != (unsigned long)-0x42)
+        	return raiseTestError("test_k_code",
+			"k code returned wrong value for long -0xFFF..000042");
+
+	Py_DECREF(tuple);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+#ifdef Py_USING_UNICODE
+
+/* Test the u and u# codes for PyArg_ParseTuple. May leak memory in case
+   of an error.
+*/
+static PyObject *
+test_u_code(PyObject *self)
+{
+	PyObject *tuple, *obj;
+	Py_UNICODE *value;
+	int len;
+
+        tuple = PyTuple_New(1);
+        if (tuple == NULL)
+        	return NULL;
+
+        obj = PyUnicode_Decode("test", strlen("test"),
+			       "ascii", NULL);
+        if (obj == NULL)
+        	return NULL;
+
+        PyTuple_SET_ITEM(tuple, 0, obj);
+
+        value = 0;
+        if (PyArg_ParseTuple(tuple, "u:test_u_code", &value) < 0)
+        	return NULL;
+        if (value != PyUnicode_AS_UNICODE(obj))
+        	return raiseTestError("test_u_code",
+			"u code returned wrong value for u'test'");
+        value = 0;
+        if (PyArg_ParseTuple(tuple, "u#:test_u_code", &value, &len) < 0)
+        	return NULL;
+        if (value != PyUnicode_AS_UNICODE(obj) ||
+	    len != PyUnicode_GET_SIZE(obj))
+        	return raiseTestError("test_u_code",
+			"u# code returned wrong values for u'test'");
+
+	Py_DECREF(tuple);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+codec_incrementalencoder(PyObject *self, PyObject *args)
+{
+	const char *encoding, *errors = NULL;
+	if (!PyArg_ParseTuple(args, "s|s:test_incrementalencoder",
+			      &encoding, &errors))
+		return NULL;
+	return PyCodec_IncrementalEncoder(encoding, errors);
+}
+
+static PyObject *
+codec_incrementaldecoder(PyObject *self, PyObject *args)
+{
+	const char *encoding, *errors = NULL;
+	if (!PyArg_ParseTuple(args, "s|s:test_incrementaldecoder",
+			      &encoding, &errors))
+		return NULL;
+	return PyCodec_IncrementalDecoder(encoding, errors);
+}
+
+#endif
+
+/* Simple test of _PyLong_NumBits and _PyLong_Sign. */
+static PyObject *
+test_long_numbits(PyObject *self)
+{
+	struct triple {
+		long input;
+		size_t nbits;
+		int sign;
+	} testcases[] = {{0, 0, 0},
+			 {1L, 1, 1},
+			 {-1L, 1, -1},
+			 {2L, 2, 1},
+			 {-2L, 2, -1},
+			 {3L, 2, 1},
+			 {-3L, 2, -1},
+			 {4L, 3, 1},
+			 {-4L, 3, -1},
+			 {0x7fffL, 15, 1},	/* one Python long digit */
+			 {-0x7fffL, 15, -1},
+			 {0xffffL, 16, 1},
+			 {-0xffffL, 16, -1},
+			 {0xfffffffL, 28, 1},
+			 {-0xfffffffL, 28, -1}};
+	int i;
+
+	for (i = 0; i < sizeof(testcases) / sizeof(struct triple); ++i) {
+		PyObject *plong = PyLong_FromLong(testcases[i].input);
+		size_t nbits = _PyLong_NumBits(plong);
+		int sign = _PyLong_Sign(plong);
+
+		Py_DECREF(plong);
+		if (nbits != testcases[i].nbits)
+			return raiseTestError("test_long_numbits",
+					"wrong result for _PyLong_NumBits");
+		if (sign != testcases[i].sign)
+			return raiseTestError("test_long_numbits",
+					"wrong result for _PyLong_Sign");
+	}
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* Example passing NULLs to PyObject_Str(NULL) and PyObject_Unicode(NULL). */
+
+static PyObject *
+test_null_strings(PyObject *self)
+{
+	PyObject *o1 = PyObject_Str(NULL), *o2 = PyObject_Unicode(NULL);
+	PyObject *tuple = PyTuple_Pack(2, o1, o2);
+	Py_XDECREF(o1);
+	Py_XDECREF(o2);
+	return tuple;
+}
+
+static PyObject *
+raise_exception(PyObject *self, PyObject *args)
+{
+	PyObject *exc;
+	PyObject *exc_args, *v;
+	int num_args, i;
+
+	if (!PyArg_ParseTuple(args, "Oi:raise_exception",
+			      &exc, &num_args))
+		return NULL;
+
+	exc_args = PyTuple_New(num_args);
+	if (exc_args == NULL)
+		return NULL;
+	for (i = 0; i < num_args; ++i) {
+		v = PyInt_FromLong(i);
+		if (v == NULL) {
+			Py_DECREF(exc_args);
+			return NULL;
+		}
+		PyTuple_SET_ITEM(exc_args, i, v);
+	}
+	PyErr_SetObject(exc, exc_args);
+	Py_DECREF(exc_args);
+	return NULL;
+}
+
+#ifdef WITH_THREAD
+
+/* test_thread_state spawns a thread of its own, and that thread releases
+ * `thread_done` when it's finished.  The driver code has to know when the
+ * thread finishes, because the thread uses a PyObject (the callable) that
+ * may go away when the driver finishes.  The former lack of this explicit
+ * synchronization caused rare segfaults, so rare that they were seen only
+ * on a Mac buildbot (although they were possible on any box).
+ */
+static PyThread_type_lock thread_done = NULL;
+
+static void
+_make_call(void *callable)
+{
+	PyObject *rc;
+	PyGILState_STATE s = PyGILState_Ensure();
+	rc = PyObject_CallFunction((PyObject *)callable, "");
+	Py_XDECREF(rc);
+	PyGILState_Release(s);
+}
+
+/* Same thing, but releases `thread_done` when it returns.  This variant
+ * should be called only from threads spawned by test_thread_state().
+ */
+static void
+_make_call_from_thread(void *callable)
+{
+	_make_call(callable);
+	PyThread_release_lock(thread_done);
+}
+
+static PyObject *
+test_thread_state(PyObject *self, PyObject *args)
+{
+	PyObject *fn;
+
+	if (!PyArg_ParseTuple(args, "O:test_thread_state", &fn))
+		return NULL;
+
+	/* Ensure Python is set up for threading */
+	PyEval_InitThreads();
+	thread_done = PyThread_allocate_lock();
+	if (thread_done == NULL)
+		return PyErr_NoMemory();
+	PyThread_acquire_lock(thread_done, 1);
+
+	/* Start a new thread with our callback. */
+	PyThread_start_new_thread(_make_call_from_thread, fn);
+	/* Make the callback with the thread lock held by this thread */
+	_make_call(fn);
+	/* Do it all again, but this time with the thread-lock released */
+	Py_BEGIN_ALLOW_THREADS
+	_make_call(fn);
+	PyThread_acquire_lock(thread_done, 1);  /* wait for thread to finish */
+	Py_END_ALLOW_THREADS
+
+	/* And once more with and without a thread
+	   XXX - should use a lock and work out exactly what we are trying
+	   to test <wink>
+	*/
+	Py_BEGIN_ALLOW_THREADS
+	PyThread_start_new_thread(_make_call_from_thread, fn);
+	_make_call(fn);
+	PyThread_acquire_lock(thread_done, 1);  /* wait for thread to finish */
+	Py_END_ALLOW_THREADS
+
+	/* Release lock we acquired above.  This is required on HP-UX. */
+	PyThread_release_lock(thread_done);
+
+	PyThread_free_lock(thread_done);
+	Py_RETURN_NONE;
+}
+#endif
+
+/* Some tests of PyString_FromFormat().  This needs more tests. */
+static PyObject *
+test_string_from_format(PyObject *self, PyObject *args)
+{
+	PyObject *result;
+	char *msg;
+
+#define CHECK_1_FORMAT(FORMAT, TYPE) 			\
+	result = PyString_FromFormat(FORMAT, (TYPE)1);	\
+	if (result == NULL)				\
+		return NULL;				\
+	if (strcmp(PyString_AsString(result), "1")) {	\
+		msg = FORMAT " failed at 1";		\
+		goto Fail;				\
+	}						\
+	Py_DECREF(result)
+
+	CHECK_1_FORMAT("%d", int);
+	CHECK_1_FORMAT("%ld", long);
+	/* The z width modifier was added in Python 2.5. */
+	CHECK_1_FORMAT("%zd", Py_ssize_t);
+
+	/* The u type code was added in Python 2.5. */
+	CHECK_1_FORMAT("%u", unsigned int);
+	CHECK_1_FORMAT("%lu", unsigned long);
+	CHECK_1_FORMAT("%zu", size_t);
+
+	Py_RETURN_NONE;
+
+ Fail:
+ 	Py_XDECREF(result);
+	return raiseTestError("test_string_from_format", msg);
+
+#undef CHECK_1_FORMAT
+}
+
+/* This is here to provide a docstring for test_descr. */
+static PyObject *
+test_with_docstring(PyObject *self)
+{
+	Py_RETURN_NONE;
+}
+
+static PyMethodDef TestMethods[] = {
+	{"raise_exception",	raise_exception,		 METH_VARARGS},
+	{"test_config",		(PyCFunction)test_config,	 METH_NOARGS},
+	{"test_list_api",	(PyCFunction)test_list_api,	 METH_NOARGS},
+	{"test_dict_iteration",	(PyCFunction)test_dict_iteration,METH_NOARGS},
+	{"test_long_api",	(PyCFunction)test_long_api,	 METH_NOARGS},
+	{"test_long_numbits",	(PyCFunction)test_long_numbits,	 METH_NOARGS},
+	{"test_k_code",		(PyCFunction)test_k_code,	 METH_NOARGS},
+	{"test_null_strings",	(PyCFunction)test_null_strings,	 METH_NOARGS},
+	{"test_string_from_format", (PyCFunction)test_string_from_format, METH_NOARGS},
+	{"test_with_docstring", (PyCFunction)test_with_docstring, METH_NOARGS,
+	 PyDoc_STR("This is a pretty normal docstring.")},
+
+	{"getargs_tuple",	getargs_tuple,			 METH_VARARGS},
+	{"getargs_b",		getargs_b,			 METH_VARARGS},
+	{"getargs_B",		getargs_B,			 METH_VARARGS},
+	{"getargs_H",		getargs_H,			 METH_VARARGS},
+	{"getargs_I",		getargs_I,			 METH_VARARGS},
+	{"getargs_k",		getargs_k,			 METH_VARARGS},
+	{"getargs_i",		getargs_i,			 METH_VARARGS},
+	{"getargs_l",		getargs_l,			 METH_VARARGS},
+	{"getargs_n",		getargs_n, 			 METH_VARARGS},
+#ifdef HAVE_LONG_LONG
+	{"getargs_L",		getargs_L,			 METH_VARARGS},
+	{"getargs_K",		getargs_K,			 METH_VARARGS},
+	{"test_longlong_api",	test_longlong_api,		 METH_NOARGS},
+	{"test_L_code",		(PyCFunction)test_L_code,	 METH_NOARGS},
+	{"codec_incrementalencoder",
+	 (PyCFunction)codec_incrementalencoder,	 METH_VARARGS},
+	{"codec_incrementaldecoder",
+	 (PyCFunction)codec_incrementaldecoder,	 METH_VARARGS},
+#endif
+#ifdef Py_USING_UNICODE
+	{"test_u_code",		(PyCFunction)test_u_code,	 METH_NOARGS},
+#endif
+#ifdef WITH_THREAD
+	{"_test_thread_state",  test_thread_state, 		 METH_VARARGS},
+#endif
+	{NULL, NULL} /* sentinel */
+};
+
+#define AddSym(d, n, f, v) {PyObject *o = f(v); PyDict_SetItemString(d, n, o); Py_DECREF(o);}
+
+typedef struct {
+	char byte_member;
+	unsigned char ubyte_member;
+	short short_member;
+	unsigned short ushort_member;
+	int int_member;
+	unsigned int uint_member;
+	long long_member;
+	unsigned long ulong_member;
+	float float_member;
+	double double_member;
+} all_structmembers;
+
+typedef struct {
+    PyObject_HEAD
+	all_structmembers structmembers;
+} test_structmembers;
+
+static struct PyMemberDef test_members[] = {
+	{"T_BYTE", T_BYTE, offsetof(test_structmembers, structmembers.byte_member), 0, NULL},
+	{"T_UBYTE", T_UBYTE, offsetof(test_structmembers, structmembers.ubyte_member), 0, NULL},
+	{"T_SHORT", T_SHORT, offsetof(test_structmembers, structmembers.short_member), 0, NULL},
+	{"T_USHORT", T_USHORT, offsetof(test_structmembers, structmembers.ushort_member), 0, NULL},
+	{"T_INT", T_INT, offsetof(test_structmembers, structmembers.int_member), 0, NULL},
+	{"T_UINT", T_UINT, offsetof(test_structmembers, structmembers.uint_member), 0, NULL},
+	{"T_LONG", T_LONG, offsetof(test_structmembers, structmembers.long_member), 0, NULL},
+	{"T_ULONG", T_ULONG, offsetof(test_structmembers, structmembers.ulong_member), 0, NULL},
+	{"T_FLOAT", T_FLOAT, offsetof(test_structmembers, structmembers.float_member), 0, NULL},
+	{"T_DOUBLE", T_DOUBLE, offsetof(test_structmembers, structmembers.double_member), 0, NULL},
+	{NULL}
+};
+
+
+static PyObject *test_structmembers_new(PyTypeObject *type, PyObject *args, PyObject *kwargs){
+	static char *keywords[]={"T_BYTE", "T_UBYTE", "T_SHORT", "T_USHORT", "T_INT", "T_UINT",
+		"T_LONG", "T_ULONG", "T_FLOAT", "T_DOUBLE", NULL};
+	test_structmembers *ob=PyObject_New(test_structmembers, type);
+	if (ob==NULL)
+		return NULL;
+	memset(&ob->structmembers, 0, sizeof(all_structmembers));
+	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|bBhHiIlkfd", keywords,
+		&ob->structmembers.byte_member, &ob->structmembers.ubyte_member,
+		&ob->structmembers.short_member, &ob->structmembers.ushort_member,
+		&ob->structmembers.int_member, &ob->structmembers.uint_member, 
+		&ob->structmembers.long_member, &ob->structmembers.ulong_member,
+		&ob->structmembers.float_member, &ob->structmembers.double_member)){
+		Py_DECREF(ob);
+		return NULL;
+		}
+	return (PyObject *)ob;
+}
+
+static void test_structmembers_free(PyObject *ob){
+	PyObject_FREE(ob);
+}
+
+static PyTypeObject test_structmembersType = {
+    PyObject_HEAD_INIT(NULL)
+    0,
+	"test_structmembersType",
+	sizeof(test_structmembers),	/* tp_basicsize */
+	0,				/* tp_itemsize */
+	test_structmembers_free,	/* destructor tp_dealloc */
+	0,				/* tp_print */
+	0,				/* tp_getattr */
+	0,				/* tp_setattr */
+	0,				/* tp_compare */
+	0,				/* tp_repr */
+	0,				/* tp_as_number */
+	0,				/* tp_as_sequence */
+	0,				/* tp_as_mapping */
+	0,				/* tp_hash */
+	0,				/* tp_call */
+	0,				/* tp_str */
+	PyObject_GenericGetAttr,
+	PyObject_GenericSetAttr,
+	0,				/* tp_as_buffer */
+	0,				/* tp_flags */
+	"Type containing all structmember types",
+	0,				/* traverseproc tp_traverse */
+	0,				/* tp_clear */
+	0,				/* tp_richcompare */
+	0,				/* tp_weaklistoffset */
+	0,				/* tp_iter */
+	0,				/* tp_iternext */
+	0,				/* tp_methods */
+	test_members,	/* tp_members */
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	test_structmembers_new,			/* tp_new */
+};
+
+
+PyMODINIT_FUNC
+init_testcapi(void)
+{
+	PyObject *m;
+
+	m = Py_InitModule("_testcapi", TestMethods);
+	if (m == NULL)
+		return;
+
+	test_structmembersType.ob_type=&PyType_Type;
+	Py_INCREF(&test_structmembersType);
+	PyModule_AddObject(m, "test_structmembersType", (PyObject *)&test_structmembersType);
+
+	PyModule_AddObject(m, "CHAR_MAX", PyInt_FromLong(CHAR_MAX));
+	PyModule_AddObject(m, "CHAR_MIN", PyInt_FromLong(CHAR_MIN));
+	PyModule_AddObject(m, "UCHAR_MAX", PyInt_FromLong(UCHAR_MAX));
+	PyModule_AddObject(m, "SHRT_MAX", PyInt_FromLong(SHRT_MAX));
+	PyModule_AddObject(m, "SHRT_MIN", PyInt_FromLong(SHRT_MIN));
+	PyModule_AddObject(m, "USHRT_MAX", PyInt_FromLong(USHRT_MAX));
+	PyModule_AddObject(m, "INT_MAX",  PyLong_FromLong(INT_MAX));
+	PyModule_AddObject(m, "INT_MIN",  PyLong_FromLong(INT_MIN));
+	PyModule_AddObject(m, "UINT_MAX",  PyLong_FromUnsignedLong(UINT_MAX));
+	PyModule_AddObject(m, "LONG_MAX", PyInt_FromLong(LONG_MAX));
+	PyModule_AddObject(m, "LONG_MIN", PyInt_FromLong(LONG_MIN));
+	PyModule_AddObject(m, "ULONG_MAX", PyLong_FromUnsignedLong(ULONG_MAX));
+	PyModule_AddObject(m, "FLT_MAX", PyFloat_FromDouble(FLT_MAX));
+	PyModule_AddObject(m, "FLT_MIN", PyFloat_FromDouble(FLT_MIN));
+	PyModule_AddObject(m, "DBL_MAX", PyFloat_FromDouble(DBL_MAX));
+	PyModule_AddObject(m, "DBL_MIN", PyFloat_FromDouble(DBL_MIN));
+	PyModule_AddObject(m, "PY_SSIZE_T_MAX", PyInt_FromSsize_t(PY_SSIZE_T_MAX));
+	PyModule_AddObject(m, "PY_SSIZE_T_MIN", PyInt_FromSsize_t(PY_SSIZE_T_MIN));
+
+	TestError = PyErr_NewException("_testcapi.error", NULL, NULL);
+	Py_INCREF(TestError);
+	PyModule_AddObject(m, "error", TestError);
+}

Added: vendor/Python/current/Modules/_tkinter.c
===================================================================
--- vendor/Python/current/Modules/_tkinter.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_tkinter.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,3165 @@
+/***********************************************************
+Copyright (C) 1994 Steen Lumholt.
+
+                        All Rights Reserved
+
+******************************************************************/
+
+/* _tkinter.c -- Interface to libtk.a and libtcl.a. */
+
+/* TCL/TK VERSION INFO:
+
+	Only Tcl/Tk 8.2 and later are supported.  Older versions are not
+	supported.  (Use Python 2.2 if you cannot upgrade your Tcl/Tk
+	libraries.)
+*/
+
+/* XXX Further speed-up ideas, involving Tcl 8.0 features:
+
+   - Register a new Tcl type, "Python callable", which can be called more
+   efficiently and passed to Tcl_EvalObj() directly (if this is possible).
+
+*/
+
+
+#include "Python.h"
+#include <ctype.h>
+
+#ifdef WITH_THREAD
+#include "pythread.h"
+#endif
+
+#ifdef MS_WINDOWS
+#include <windows.h>
+#endif
+
+/* Allow using this code in Python 2.[12] */
+#ifndef PyDoc_STRVAR
+#define PyDoc_STRVAR(name,str) static char name[] = str
+#endif
+
+#ifndef PyMODINIT_FUNC
+#define PyMODINIT_FUNC void
+#endif
+
+#ifndef PyBool_Check
+#define PyBool_Check(o)       0
+#define PyBool_FromLong       PyInt_FromLong
+#endif
+
+/* Starting with Tcl 8.4, many APIs offer const-correctness.  Unfortunately,
+   making _tkinter correct for this API means to break earlier
+   versions. USE_COMPAT_CONST allows to make _tkinter work with both 8.4 and
+   earlier versions. Once Tcl releases before 8.4 don't need to be supported
+   anymore, this should go. */
+#define USE_COMPAT_CONST
+
+/* If Tcl is compiled for threads, we must also define TCL_THREAD. We define
+   it always; if Tcl is not threaded, the thread functions in
+   Tcl are empty.  */
+#define TCL_THREADS
+
+#ifdef TK_FRAMEWORK
+#include <Tcl/tcl.h>
+#include <Tk/tk.h>
+#else
+#include <tcl.h>
+#include <tk.h>
+#endif
+
+/* For Tcl 8.2 and 8.3, CONST* is not defined (except on Cygwin). */
+#ifndef CONST84_RETURN
+#define CONST84_RETURN
+#undef CONST
+#define CONST
+#endif
+
+#define TKMAJORMINOR (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION)
+
+#if TKMAJORMINOR < 8002
+#error "Tk older than 8.2 not supported"
+#endif
+
+/* Unicode conversion assumes that Tcl_UniChar is two bytes.
+   We cannot test this directly, so we test UTF-8 size instead,
+   expecting that TCL_UTF_MAX is changed if Tcl ever supports
+   either UTF-16 or UCS-4.  
+   Redhat 8 sets TCL_UTF_MAX to 6, and uses wchar_t for 
+   Tcl_Unichar. This is also ok as long as Python uses UCS-4,
+   as well.
+*/
+#if TCL_UTF_MAX != 3 && !(defined(Py_UNICODE_WIDE) && TCL_UTF_MAX==6)
+#error "unsupported Tcl configuration"
+#endif
+
+#if !(defined(MS_WINDOWS) || defined(__CYGWIN__))
+#define HAVE_CREATEFILEHANDLER
+#endif
+
+#ifdef HAVE_CREATEFILEHANDLER
+
+/* This bit is to ensure that TCL_UNIX_FD is defined and doesn't interfere
+   with the proper calculation of FHANDLETYPE == TCL_UNIX_FD below. */
+#ifndef TCL_UNIX_FD
+#  ifdef TCL_WIN_SOCKET
+#    define TCL_UNIX_FD (! TCL_WIN_SOCKET)
+#  else
+#    define TCL_UNIX_FD 1
+#  endif
+#endif
+
+/* Tcl_CreateFileHandler() changed several times; these macros deal with the
+   messiness.  In Tcl 8.0 and later, it is not available on Windows (and on
+   Unix, only because Jack added it back); when available on Windows, it only
+   applies to sockets. */
+
+#ifdef MS_WINDOWS
+#define FHANDLETYPE TCL_WIN_SOCKET
+#else
+#define FHANDLETYPE TCL_UNIX_FD
+#endif
+
+/* If Tcl can wait for a Unix file descriptor, define the EventHook() routine
+   which uses this to handle Tcl events while the user is typing commands. */
+
+#if FHANDLETYPE == TCL_UNIX_FD
+#define WAIT_FOR_STDIN
+#endif
+
+#endif /* HAVE_CREATEFILEHANDLER */
+
+#ifdef MS_WINDOWS
+#include <conio.h>
+#define WAIT_FOR_STDIN
+#endif
+
+#ifdef WITH_THREAD
+
+/* The threading situation is complicated.  Tcl is not thread-safe, except
+   when configured with --enable-threads.
+   So we need to use a lock around all uses of Tcl.  Previously, the Python
+   interpreter lock was used for this.  However, this causes problems when
+   other Python threads need to run while Tcl is blocked waiting for events.
+
+   To solve this problem, a separate lock for Tcl is introduced.  Holding it
+   is incompatible with holding Python's interpreter lock.  The following four
+   macros manipulate both locks together.
+
+   ENTER_TCL and LEAVE_TCL are brackets, just like Py_BEGIN_ALLOW_THREADS and
+   Py_END_ALLOW_THREADS.  They should be used whenever a call into Tcl is made
+   that could call an event handler, or otherwise affect the state of a Tcl
+   interpreter.  These assume that the surrounding code has the Python
+   interpreter lock; inside the brackets, the Python interpreter lock has been
+   released and the lock for Tcl has been acquired.
+
+   Sometimes, it is necessary to have both the Python lock and the Tcl lock.
+   (For example, when transferring data from the Tcl interpreter result to a
+   Python string object.)  This can be done by using different macros to close
+   the ENTER_TCL block: ENTER_OVERLAP reacquires the Python lock (and restores
+   the thread state) but doesn't release the Tcl lock; LEAVE_OVERLAP_TCL
+   releases the Tcl lock.
+
+   By contrast, ENTER_PYTHON and LEAVE_PYTHON are used in Tcl event
+   handlers when the handler needs to use Python.  Such event handlers are
+   entered while the lock for Tcl is held; the event handler presumably needs
+   to use Python.  ENTER_PYTHON releases the lock for Tcl and acquires
+   the Python interpreter lock, restoring the appropriate thread state, and
+   LEAVE_PYTHON releases the Python interpreter lock and re-acquires the lock
+   for Tcl.  It is okay for ENTER_TCL/LEAVE_TCL pairs to be contained inside
+   the code between ENTER_PYTHON and LEAVE_PYTHON.
+
+   These locks expand to several statements and brackets; they should not be
+   used in branches of if statements and the like.
+
+   If Tcl is threaded, this approach won't work anymore. The Tcl interpreter is
+   only valid in the thread that created it, and all Tk activity must happen in this
+   thread, also. That means that the mainloop must be invoked in the thread that
+   created the interpreter. Invoking commands from other threads is possible;
+   _tkinter will queue an event for the interpreter thread, which will then
+   execute the command and pass back the result. If the main thread is not in the
+   mainloop, and invoking commands causes an exception; if the main loop is running
+   but not processing events, the command invocation will block.
+
+   In addition, for a threaded Tcl, a single global tcl_tstate won't be sufficient
+   anymore, since multiple Tcl interpreters may simultaneously dispatch in different
+   threads. So we use the Tcl TLS API.
+
+*/
+
+static PyThread_type_lock tcl_lock = 0;
+
+#ifdef TCL_THREADS
+static Tcl_ThreadDataKey state_key;
+typedef PyThreadState *ThreadSpecificData;
+#define tcl_tstate (*(PyThreadState**)Tcl_GetThreadData(&state_key, sizeof(PyThreadState*)))
+#else
+static PyThreadState *tcl_tstate = NULL;
+#endif
+
+#define ENTER_TCL \
+	{ PyThreadState *tstate = PyThreadState_Get(); Py_BEGIN_ALLOW_THREADS \
+	    if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate;
+
+#define LEAVE_TCL \
+    tcl_tstate = NULL; if(tcl_lock)PyThread_release_lock(tcl_lock); Py_END_ALLOW_THREADS}
+
+#define ENTER_OVERLAP \
+	Py_END_ALLOW_THREADS
+
+#define LEAVE_OVERLAP_TCL \
+	tcl_tstate = NULL; if(tcl_lock)PyThread_release_lock(tcl_lock); }
+
+#define ENTER_PYTHON \
+	{ PyThreadState *tstate = tcl_tstate; tcl_tstate = NULL; \
+	    if(tcl_lock)PyThread_release_lock(tcl_lock); PyEval_RestoreThread((tstate)); }
+
+#define LEAVE_PYTHON \
+	{ PyThreadState *tstate = PyEval_SaveThread(); \
+	    if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate; }
+
+#define CHECK_TCL_APPARTMENT \
+	if (((TkappObject *)self)->threaded && \
+	    ((TkappObject *)self)->thread_id != Tcl_GetCurrentThread()) { \
+		PyErr_SetString(PyExc_RuntimeError, "Calling Tcl from different appartment"); \
+		return 0; \
+	}
+
+#else
+
+#define ENTER_TCL
+#define LEAVE_TCL
+#define ENTER_OVERLAP
+#define LEAVE_OVERLAP_TCL
+#define ENTER_PYTHON
+#define LEAVE_PYTHON
+#define CHECK_TCL_APPARTMENT
+
+#endif
+
+#ifndef FREECAST
+#define FREECAST (char *)
+#endif
+
+/**** Tkapp Object Declaration ****/
+
+static PyTypeObject Tkapp_Type;
+
+typedef struct {
+	PyObject_HEAD
+	Tcl_Interp *interp;
+	int wantobjects;
+	int threaded; /* True if tcl_platform[threaded] */
+	Tcl_ThreadId thread_id;
+	int dispatching;
+	/* We cannot include tclInt.h, as this is internal.
+	   So we cache interesting types here. */
+	Tcl_ObjType *BooleanType;
+	Tcl_ObjType *ByteArrayType;
+	Tcl_ObjType *DoubleType;
+	Tcl_ObjType *IntType;
+	Tcl_ObjType *ListType;
+	Tcl_ObjType *ProcBodyType;
+	Tcl_ObjType *StringType;
+} TkappObject;
+
+#define Tkapp_Check(v) ((v)->ob_type == &Tkapp_Type)
+#define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
+#define Tkapp_Result(v) Tcl_GetStringResult(Tkapp_Interp(v))
+
+#define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \
+(void *) v, ((PyObject *) v)->ob_refcnt))
+
+
+
+/**** Error Handling ****/
+
+static PyObject *Tkinter_TclError;
+static int quitMainLoop = 0;
+static int errorInCmd = 0;
+static PyObject *excInCmd;
+static PyObject *valInCmd;
+static PyObject *trbInCmd;
+
+
+
+static PyObject *
+Tkinter_Error(PyObject *v)
+{
+	PyErr_SetString(Tkinter_TclError, Tkapp_Result(v));
+	return NULL;
+}
+
+
+
+/**** Utils ****/
+
+static int Tkinter_busywaitinterval = 20;
+
+#ifdef WITH_THREAD
+#ifndef MS_WINDOWS
+
+/* Millisecond sleep() for Unix platforms. */
+
+static void
+Sleep(int milli)
+{
+	/* XXX Too bad if you don't have select(). */
+	struct timeval t;
+	t.tv_sec = milli/1000;
+	t.tv_usec = (milli%1000) * 1000;
+	select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
+}
+#endif /* MS_WINDOWS */
+
+/* Wait up to 1s for the mainloop to come up. */
+
+static int
+WaitForMainloop(TkappObject* self)
+{
+	int i;
+	for (i = 0; i < 10; i++) {
+		if (self->dispatching)
+			return 1;
+		Py_BEGIN_ALLOW_THREADS
+		Sleep(100);
+		Py_END_ALLOW_THREADS
+	}
+	if (self->dispatching)
+		return 1;
+	PyErr_SetString(PyExc_RuntimeError, "main thread is not in main loop");
+	return 0;
+}
+#endif /* WITH_THREAD */
+
+
+static char *
+AsString(PyObject *value, PyObject *tmp)
+{
+	if (PyString_Check(value))
+		return PyString_AsString(value);
+#ifdef Py_USING_UNICODE
+	else if (PyUnicode_Check(value)) {
+		PyObject *v = PyUnicode_AsUTF8String(value);
+		if (v == NULL)
+			return NULL;
+		if (PyList_Append(tmp, v) != 0) {
+			Py_DECREF(v);
+			return NULL;
+		}
+		Py_DECREF(v);
+		return PyString_AsString(v);
+	}
+#endif
+	else {
+		PyObject *v = PyObject_Str(value);
+		if (v == NULL)
+			return NULL;
+		if (PyList_Append(tmp, v) != 0) {
+			Py_DECREF(v);
+			return NULL;
+		}
+		Py_DECREF(v);
+		return PyString_AsString(v);
+	}
+}
+
+
+
+#define ARGSZ 64
+
+static char *
+Merge(PyObject *args)
+{
+	PyObject *tmp = NULL;
+	char *argvStore[ARGSZ];
+	char **argv = NULL;
+	int fvStore[ARGSZ];
+	int *fv = NULL;
+	int argc = 0, fvc = 0, i;
+	char *res = NULL;
+
+	if (!(tmp = PyList_New(0)))
+	    return NULL;
+
+	argv = argvStore;
+	fv = fvStore;
+
+	if (args == NULL)
+		argc = 0;
+
+	else if (!PyTuple_Check(args)) {
+		argc = 1;
+		fv[0] = 0;
+		if (!(argv[0] = AsString(args, tmp)))
+			goto finally;
+	}
+	else {
+		argc = PyTuple_Size(args);
+
+		if (argc > ARGSZ) {
+			argv = (char **)ckalloc(argc * sizeof(char *));
+			fv = (int *)ckalloc(argc * sizeof(int));
+			if (argv == NULL || fv == NULL) {
+				PyErr_NoMemory();
+				goto finally;
+			}
+		}
+
+		for (i = 0; i < argc; i++) {
+			PyObject *v = PyTuple_GetItem(args, i);
+			if (PyTuple_Check(v)) {
+				fv[i] = 1;
+				if (!(argv[i] = Merge(v)))
+					goto finally;
+				fvc++;
+			}
+			else if (v == Py_None) {
+				argc = i;
+				break;
+			}
+			else {
+				fv[i] = 0;
+				if (!(argv[i] = AsString(v, tmp)))
+					goto finally;
+				fvc++;
+			}
+		}
+	}
+	res = Tcl_Merge(argc, argv);
+	if (res == NULL)
+		PyErr_SetString(Tkinter_TclError, "merge failed");
+
+  finally:
+	for (i = 0; i < fvc; i++)
+		if (fv[i]) {
+			ckfree(argv[i]);
+		}
+	if (argv != argvStore)
+		ckfree(FREECAST argv);
+	if (fv != fvStore)
+		ckfree(FREECAST fv);
+
+	Py_DECREF(tmp);
+	return res;
+}
+
+
+
+static PyObject *
+Split(char *list)
+{
+	int argc;
+	char **argv;
+	PyObject *v;
+
+	if (list == NULL) {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+
+	if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
+		/* Not a list.
+		 * Could be a quoted string containing funnies, e.g. {"}.
+		 * Return the string itself.
+		 */
+		return PyString_FromString(list);
+	}
+
+	if (argc == 0)
+		v = PyString_FromString("");
+	else if (argc == 1)
+		v = PyString_FromString(argv[0]);
+	else if ((v = PyTuple_New(argc)) != NULL) {
+		int i;
+		PyObject *w;
+
+		for (i = 0; i < argc; i++) {
+			if ((w = Split(argv[i])) == NULL) {
+				Py_DECREF(v);
+				v = NULL;
+				break;
+			}
+			PyTuple_SetItem(v, i, w);
+		}
+	}
+	Tcl_Free(FREECAST argv);
+	return v;
+}
+
+/* In some cases, Tcl will still return strings that are supposed to be
+   lists. SplitObj walks through a nested tuple, finding string objects that
+   need to be split. */
+
+PyObject *
+SplitObj(PyObject *arg)
+{
+	if (PyTuple_Check(arg)) {
+		int i, size;
+		PyObject *elem, *newelem, *result;
+
+		size = PyTuple_Size(arg);
+		result = NULL;
+		/* Recursively invoke SplitObj for all tuple items.
+		   If this does not return a new object, no action is
+		   needed. */
+		for(i = 0; i < size; i++) {
+			elem = PyTuple_GetItem(arg, i);
+			newelem = SplitObj(elem);
+			if (!newelem) {
+				Py_XDECREF(result);
+				return NULL;
+			}
+			if (!result) {
+				int k;
+				if (newelem == elem) {
+					Py_DECREF(newelem);
+					continue;
+				}
+				result = PyTuple_New(size);
+				if (!result)
+					return NULL;
+				for(k = 0; k < i; k++) {
+					elem = PyTuple_GetItem(arg, k);
+					Py_INCREF(elem);
+					PyTuple_SetItem(result, k, elem);
+				}
+			}
+			PyTuple_SetItem(result, i, newelem);
+		}
+		if (result)
+			return result;
+		/* Fall through, returning arg. */
+	}
+	else if (PyString_Check(arg)) {
+		int argc;
+		char **argv;
+		char *list = PyString_AsString(arg);
+
+		if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
+			Py_INCREF(arg);
+			return arg;
+		}
+		Tcl_Free(FREECAST argv);
+		if (argc > 1)
+			return Split(PyString_AsString(arg));
+		/* Fall through, returning arg. */
+	}
+	Py_INCREF(arg);
+	return arg;
+}
+
+
+/**** Tkapp Object ****/
+
+#ifndef WITH_APPINIT
+int
+Tcl_AppInit(Tcl_Interp *interp)
+{
+	Tk_Window main;
+	const char * _tkinter_skip_tk_init;
+
+	if (Tcl_Init(interp) == TCL_ERROR) {
+		PySys_WriteStderr("Tcl_Init error: %s\n", Tcl_GetStringResult(interp));
+		return TCL_ERROR;
+	}
+	_tkinter_skip_tk_init =	Tcl_GetVar(interp, "_tkinter_skip_tk_init", TCL_GLOBAL_ONLY);
+	if (_tkinter_skip_tk_init == NULL || strcmp(_tkinter_skip_tk_init, "1")	!= 0) {
+		main = Tk_MainWindow(interp);
+		if (Tk_Init(interp) == TCL_ERROR) {
+			PySys_WriteStderr("Tk_Init error: %s\n", Tcl_GetStringResult(interp));
+			return TCL_ERROR;
+		}
+	}
+	return TCL_OK;
+}
+#endif /* !WITH_APPINIT */
+
+
+
+
+/* Initialize the Tk application; see the `main' function in
+ * `tkMain.c'.
+ */
+
+static void EnableEventHook(void); /* Forward */
+static void DisableEventHook(void); /* Forward */
+
+static TkappObject *
+Tkapp_New(char *screenName, char *baseName, char *className,
+	  int interactive, int wantobjects, int	wantTk, int sync, char *use)
+{
+	TkappObject *v;
+	char *argv0;
+
+	v = PyObject_New(TkappObject, &Tkapp_Type);
+	if (v == NULL)
+		return NULL;
+
+	v->interp = Tcl_CreateInterp();
+	v->wantobjects = wantobjects;
+	v->threaded = Tcl_GetVar2Ex(v->interp, "tcl_platform", "threaded",
+				    TCL_GLOBAL_ONLY) != NULL;
+	v->thread_id = Tcl_GetCurrentThread();
+	v->dispatching = 0;
+
+#ifndef TCL_THREADS
+	if (v->threaded) {
+	    PyErr_SetString(PyExc_RuntimeError, "Tcl is threaded but _tkinter is not");
+	    Py_DECREF(v);
+	    return 0;
+	}
+#endif
+#ifdef WITH_THREAD
+	if (v->threaded && tcl_lock) {
+	    /* If Tcl is threaded, we don't need the lock. */
+	    PyThread_free_lock(tcl_lock);
+	    tcl_lock = NULL;
+	}
+#endif
+
+	v->BooleanType = Tcl_GetObjType("boolean");
+	v->ByteArrayType = Tcl_GetObjType("bytearray");
+	v->DoubleType = Tcl_GetObjType("double");
+	v->IntType = Tcl_GetObjType("int");
+	v->ListType = Tcl_GetObjType("list");
+	v->ProcBodyType = Tcl_GetObjType("procbody");
+	v->StringType = Tcl_GetObjType("string");
+
+	/* Delete the 'exit' command, which can screw things up */
+	Tcl_DeleteCommand(v->interp, "exit");
+
+	if (screenName != NULL)
+		Tcl_SetVar2(v->interp, "env", "DISPLAY",
+			    screenName, TCL_GLOBAL_ONLY);
+
+	if (interactive)
+		Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
+	else
+		Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
+
+	/* This is used to get the application class for Tk 4.1 and up */
+	argv0 = (char*)ckalloc(strlen(className) + 1);
+	if (!argv0) {
+		PyErr_NoMemory();
+		Py_DECREF(v);
+		return NULL;
+	}
+
+	strcpy(argv0, className);
+	if (isupper(Py_CHARMASK(argv0[0])))
+		argv0[0] = tolower(Py_CHARMASK(argv0[0]));
+	Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
+	ckfree(argv0);
+
+	if (! wantTk) {
+	    Tcl_SetVar(v->interp, "_tkinter_skip_tk_init", "1",	TCL_GLOBAL_ONLY);
+	}
+
+	/* some initial arguments need to be in argv */
+	if (sync || use) {
+		char *args;
+		int len = 0;
+
+		if (sync)
+			len += sizeof "-sync";
+		if (use)
+			len += strlen(use) + sizeof "-use ";
+
+		args = (char*)ckalloc(len);
+		if (!args) {
+			PyErr_NoMemory();
+			Py_DECREF(v);
+			return NULL;
+		}
+
+		args[0] = '\0';
+		if (sync)
+			strcat(args, "-sync");
+		if (use) {
+			if (sync)
+				strcat(args, " ");
+			strcat(args, "-use ");
+			strcat(args, use);
+		}
+
+		Tcl_SetVar(v->interp, "argv", args, TCL_GLOBAL_ONLY);
+		ckfree(args);
+	}
+
+	if (Tcl_AppInit(v->interp) != TCL_OK) {
+		PyObject *result = Tkinter_Error((PyObject *)v);
+		Py_DECREF((PyObject *)v);
+		return (TkappObject *)result;
+	}
+
+	EnableEventHook();
+
+	return v;
+}
+
+
+static void
+Tkapp_ThreadSend(TkappObject *self, Tcl_Event *ev,
+		 Tcl_Condition *cond, Tcl_Mutex *mutex)
+{
+	Py_BEGIN_ALLOW_THREADS;
+	Tcl_MutexLock(mutex);
+	Tcl_ThreadQueueEvent(self->thread_id, ev, TCL_QUEUE_TAIL);
+	Tcl_ThreadAlert(self->thread_id);
+	Tcl_ConditionWait(cond, mutex, NULL);
+	Tcl_MutexUnlock(mutex);
+	Py_END_ALLOW_THREADS
+}
+
+
+/** Tcl Eval **/
+
+typedef struct {
+	PyObject_HEAD
+	Tcl_Obj *value;
+	PyObject *string; /* This cannot cause cycles. */
+} PyTclObject;
+
+staticforward PyTypeObject PyTclObject_Type;
+#define PyTclObject_Check(v)	((v)->ob_type == &PyTclObject_Type)
+
+static PyObject *
+newPyTclObject(Tcl_Obj *arg)
+{
+	PyTclObject *self;
+	self = PyObject_New(PyTclObject, &PyTclObject_Type);
+	if (self == NULL)
+		return NULL;
+	Tcl_IncrRefCount(arg);
+	self->value = arg;
+	self->string = NULL;
+	return (PyObject*)self;
+}
+
+static void
+PyTclObject_dealloc(PyTclObject *self)
+{
+	Tcl_DecrRefCount(self->value);
+	Py_XDECREF(self->string);
+	PyObject_Del(self);
+}
+
+static PyObject *
+PyTclObject_str(PyTclObject *self)
+{
+	if (self->string && PyString_Check(self->string)) {
+		Py_INCREF(self->string);
+		return self->string;
+	}
+	/* XXX Could cache value if it is an ASCII string. */
+	return PyString_FromString(Tcl_GetString(self->value));
+}
+
+static char*
+PyTclObject_TclString(PyObject *self)
+{
+	return Tcl_GetString(((PyTclObject*)self)->value);
+}
+
+/* Like _str, but create Unicode if necessary. */
+PyDoc_STRVAR(PyTclObject_string__doc__, 
+"the string representation of this object, either as string or Unicode");
+
+static PyObject *
+PyTclObject_string(PyTclObject *self, void *ignored)
+{
+	char *s;
+	int i, len;
+	if (!self->string) {
+		s = Tcl_GetStringFromObj(self->value, &len);
+		for (i = 0; i < len; i++)
+			if (s[i] & 0x80)
+				break;
+#ifdef Py_USING_UNICODE
+		if (i == len)
+			/* It is an ASCII string. */
+			self->string = PyString_FromStringAndSize(s, len);
+		else {
+			self->string = PyUnicode_DecodeUTF8(s, len, "strict");
+			if (!self->string) {
+				PyErr_Clear();
+				self->string = PyString_FromStringAndSize(s, len);
+			}
+		}
+#else
+		self->string = PyString_FromStringAndSize(s, len);
+#endif
+		if (!self->string)
+			return NULL;
+	}
+	Py_INCREF(self->string);
+	return self->string;
+}
+
+#ifdef Py_USING_UNICODE
+PyDoc_STRVAR(PyTclObject_unicode__doc__, "convert argument to unicode");
+
+static PyObject *
+PyTclObject_unicode(PyTclObject *self, void *ignored)
+{
+	char *s;
+	int len;
+	if (self->string && PyUnicode_Check(self->string)) {
+		Py_INCREF(self->string);
+		return self->string;
+	}
+	/* XXX Could chache result if it is non-ASCII. */
+	s = Tcl_GetStringFromObj(self->value, &len);
+	return PyUnicode_DecodeUTF8(s, len, "strict");
+}
+#endif
+
+static PyObject *
+PyTclObject_repr(PyTclObject *self)
+{
+	char buf[50];
+	PyOS_snprintf(buf, 50, "<%s object at %p>",
+		      self->value->typePtr->name, self->value);
+	return PyString_FromString(buf);
+}
+
+static int
+PyTclObject_cmp(PyTclObject *self, PyTclObject *other)
+{
+	int res;
+	res = strcmp(Tcl_GetString(self->value),
+		     Tcl_GetString(other->value));
+	if (res < 0) return -1;
+	if (res > 0) return 1;
+	return 0;
+}
+
+PyDoc_STRVAR(get_typename__doc__, "name of the Tcl type");
+
+static PyObject*
+get_typename(PyTclObject* obj, void* ignored)
+{
+	return PyString_FromString(obj->value->typePtr->name);
+}
+
+
+static PyGetSetDef PyTclObject_getsetlist[] = {
+	{"typename", (getter)get_typename, NULL, get_typename__doc__},
+	{"string", (getter)PyTclObject_string, NULL, 
+	 PyTclObject_string__doc__},
+	{0},
+};
+
+static PyMethodDef PyTclObject_methods[] = {
+#ifdef Py_USING_UNICODE
+	{"__unicode__",	(PyCFunction)PyTclObject_unicode, METH_NOARGS,
+	PyTclObject_unicode__doc__},
+#endif
+	{0}
+};
+
+statichere PyTypeObject PyTclObject_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0,			/*ob_size*/
+	"_tkinter.Tcl_Obj",		/*tp_name*/
+	sizeof(PyTclObject),	/*tp_basicsize*/
+	0,			/*tp_itemsize*/
+	/* methods */
+	(destructor)PyTclObject_dealloc, /*tp_dealloc*/
+	0,			/*tp_print*/
+	0,			/*tp_getattr*/
+	0,			/*tp_setattr*/
+	(cmpfunc)PyTclObject_cmp,	/*tp_compare*/
+	(reprfunc)PyTclObject_repr,	/*tp_repr*/
+	0,			/*tp_as_number*/
+	0,			/*tp_as_sequence*/
+	0,			/*tp_as_mapping*/
+	0,			/*tp_hash*/
+        0,                      /*tp_call*/
+        (reprfunc)PyTclObject_str,        /*tp_str*/
+        PyObject_GenericGetAttr,/*tp_getattro*/
+        0,                      /*tp_setattro*/
+        0,                      /*tp_as_buffer*/
+        Py_TPFLAGS_DEFAULT,     /*tp_flags*/
+        0,                      /*tp_doc*/
+        0,                      /*tp_traverse*/
+        0,                      /*tp_clear*/
+        0,                      /*tp_richcompare*/
+        0,                      /*tp_weaklistoffset*/
+        0,                      /*tp_iter*/
+        0,                      /*tp_iternext*/
+        PyTclObject_methods,    /*tp_methods*/
+        0,			/*tp_members*/
+        PyTclObject_getsetlist, /*tp_getset*/
+        0,                      /*tp_base*/
+        0,                      /*tp_dict*/
+        0,                      /*tp_descr_get*/
+        0,                      /*tp_descr_set*/
+        0,                      /*tp_dictoffset*/
+        0,                      /*tp_init*/
+        0,                      /*tp_alloc*/
+        0,                      /*tp_new*/
+        0,                      /*tp_free*/
+        0,                      /*tp_is_gc*/
+};
+
+static Tcl_Obj*
+AsObj(PyObject *value)
+{
+	Tcl_Obj *result;
+
+	if (PyString_Check(value))
+		return Tcl_NewStringObj(PyString_AS_STRING(value),
+					PyString_GET_SIZE(value));
+	else if (PyBool_Check(value))
+		return Tcl_NewBooleanObj(PyObject_IsTrue(value));
+	else if (PyInt_Check(value))
+		return Tcl_NewLongObj(PyInt_AS_LONG(value));
+	else if (PyFloat_Check(value))
+		return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value));
+	else if (PyTuple_Check(value)) {
+		Tcl_Obj **argv = (Tcl_Obj**)
+			ckalloc(PyTuple_Size(value)*sizeof(Tcl_Obj*));
+		int i;
+		if(!argv)
+		  return 0;
+		for(i=0;i<PyTuple_Size(value);i++)
+		  argv[i] = AsObj(PyTuple_GetItem(value,i));
+		result = Tcl_NewListObj(PyTuple_Size(value), argv);
+		ckfree(FREECAST argv);
+		return result;
+	}
+#ifdef Py_USING_UNICODE
+	else if (PyUnicode_Check(value)) {
+		Py_UNICODE *inbuf = PyUnicode_AS_UNICODE(value);
+		Py_ssize_t size = PyUnicode_GET_SIZE(value);
+		/* This #ifdef assumes that Tcl uses UCS-2.
+		   See TCL_UTF_MAX test above. */
+#if defined(Py_UNICODE_WIDE) && TCL_UTF_MAX == 3
+		Tcl_UniChar *outbuf;
+		Py_ssize_t i;
+		assert(size < size * sizeof(Tcl_UniChar));
+		outbuf = (Tcl_UniChar*)ckalloc(size * sizeof(Tcl_UniChar));
+		if (!outbuf) {
+			PyErr_NoMemory();
+			return NULL;
+		}
+		for (i = 0; i < size; i++) {
+			if (inbuf[i] >= 0x10000) {
+				/* Tcl doesn't do UTF-16, yet. */
+				PyErr_SetString(PyExc_ValueError,
+						"unsupported character");
+				ckfree(FREECAST outbuf);
+				return NULL;
+			}
+			outbuf[i] = inbuf[i];
+		}
+		result = Tcl_NewUnicodeObj(outbuf, size);
+		ckfree(FREECAST outbuf);
+		return result;
+#else
+		return Tcl_NewUnicodeObj(inbuf, size);
+#endif
+
+	}
+#endif
+	else if(PyTclObject_Check(value)) {
+		Tcl_Obj *v = ((PyTclObject*)value)->value;
+		Tcl_IncrRefCount(v);
+		return v;
+	} 
+	else {
+		PyObject *v = PyObject_Str(value);
+		if (!v)
+			return 0;
+		result = AsObj(v);
+		Py_DECREF(v);
+		return result;
+	}
+}
+
+static PyObject*
+FromObj(PyObject* tkapp, Tcl_Obj *value)
+{
+	PyObject *result = NULL;
+	TkappObject *app = (TkappObject*)tkapp;
+
+	if (value->typePtr == NULL) {
+		/* If the result contains any bytes with the top bit set,
+		   it's UTF-8 and we should decode it to Unicode */
+#ifdef Py_USING_UNICODE
+		int i;
+		char *s = value->bytes;
+		int len = value->length;
+		for (i = 0; i < len; i++) {
+			if (value->bytes[i] & 0x80)
+				break;
+		}
+
+		if (i == value->length)
+			result = PyString_FromStringAndSize(s, len);
+		else {
+			/* Convert UTF-8 to Unicode string */
+			result = PyUnicode_DecodeUTF8(s, len, "strict");
+			if (result == NULL) {
+				PyErr_Clear();
+				result = PyString_FromStringAndSize(s, len);
+			}
+		}
+#else
+		result = PyString_FromStringAndSize(value->bytes, value->length);
+#endif
+		return result;
+	}
+
+	if (value->typePtr == app->BooleanType) {
+		result = value->internalRep.longValue ? Py_True : Py_False;
+		Py_INCREF(result);
+		return result;
+	}
+
+	if (value->typePtr == app->ByteArrayType) {
+		int size;
+		char *data = (char*)Tcl_GetByteArrayFromObj(value, &size);
+		return PyString_FromStringAndSize(data, size);
+	}
+
+	if (value->typePtr == app->DoubleType) {
+		return PyFloat_FromDouble(value->internalRep.doubleValue);
+	}
+
+	if (value->typePtr == app->IntType) {
+		return PyInt_FromLong(value->internalRep.longValue);
+	}
+
+	if (value->typePtr == app->ListType) {
+		int size;
+		int i, status;
+		PyObject *elem;
+		Tcl_Obj *tcl_elem;
+
+		status = Tcl_ListObjLength(Tkapp_Interp(tkapp), value, &size);
+		if (status == TCL_ERROR)
+			return Tkinter_Error(tkapp);
+		result = PyTuple_New(size);
+		if (!result)
+			return NULL;
+		for (i = 0; i < size; i++) {
+			status = Tcl_ListObjIndex(Tkapp_Interp(tkapp),
+						  value, i, &tcl_elem);
+			if (status == TCL_ERROR) {
+				Py_DECREF(result);
+				return Tkinter_Error(tkapp);
+			}
+			elem = FromObj(tkapp, tcl_elem);
+			if (!elem) {
+				Py_DECREF(result);
+				return NULL;
+			}
+			PyTuple_SetItem(result, i, elem);
+		}
+		return result;
+	}
+
+	if (value->typePtr == app->ProcBodyType) {
+	  /* fall through: return tcl object. */
+	}
+
+	if (value->typePtr == app->StringType) {
+#ifdef Py_USING_UNICODE
+#if defined(Py_UNICODE_WIDE) && TCL_UTF_MAX==3
+		PyObject *result;
+		int size;
+		Tcl_UniChar *input;
+		Py_UNICODE *output;
+
+		size = Tcl_GetCharLength(value);
+		result = PyUnicode_FromUnicode(NULL, size);
+		if (!result)
+			return NULL;
+		input = Tcl_GetUnicode(value);
+		output = PyUnicode_AS_UNICODE(result);
+		while (size--)
+			*output++ = *input++;
+		return result;
+#else
+		return PyUnicode_FromUnicode(Tcl_GetUnicode(value),
+					     Tcl_GetCharLength(value));
+#endif
+#else
+		int size;
+		char *c;
+		c = Tcl_GetStringFromObj(value, &size);
+		return PyString_FromStringAndSize(c, size);
+#endif
+	}
+
+	return newPyTclObject(value);
+}
+
+/* This mutex synchronizes inter-thread command calls. */
+
+TCL_DECLARE_MUTEX(call_mutex)
+
+typedef struct Tkapp_CallEvent {
+	Tcl_Event ev;	     /* Must be first */
+	TkappObject *self;
+	PyObject *args;
+	int flags;
+	PyObject **res;
+	PyObject **exc_type, **exc_value, **exc_tb;
+	Tcl_Condition done;
+} Tkapp_CallEvent;
+
+void
+Tkapp_CallDeallocArgs(Tcl_Obj** objv, Tcl_Obj** objStore, int objc)
+{
+	int i;
+	for (i = 0; i < objc; i++)
+		Tcl_DecrRefCount(objv[i]);
+	if (objv != objStore)
+		ckfree(FREECAST objv);
+}
+
+/* Convert Python objects to Tcl objects. This must happen in the
+   interpreter thread, which may or may not be the calling thread. */
+
+static Tcl_Obj**
+Tkapp_CallArgs(PyObject *args, Tcl_Obj** objStore, int *pobjc)
+{
+	Tcl_Obj **objv = objStore;
+	int objc = 0, i;
+	if (args == NULL)
+		/* do nothing */;
+
+	else if (!PyTuple_Check(args)) {
+		objv[0] = AsObj(args);
+		if (objv[0] == 0)
+			goto finally;
+		objc = 1;
+		Tcl_IncrRefCount(objv[0]);
+	}
+	else {
+		objc = PyTuple_Size(args);
+
+		if (objc > ARGSZ) {
+			objv = (Tcl_Obj **)ckalloc(objc * sizeof(char *));
+			if (objv == NULL) {
+				PyErr_NoMemory();
+				objc = 0;
+				goto finally;
+			}
+		}
+
+		for (i = 0; i < objc; i++) {
+			PyObject *v = PyTuple_GetItem(args, i);
+			if (v == Py_None) {
+				objc = i;
+				break;
+			}
+			objv[i] = AsObj(v);
+			if (!objv[i]) {
+				/* Reset objc, so it attempts to clear
+				   objects only up to i. */
+				objc = i;
+				goto finally;
+			}
+			Tcl_IncrRefCount(objv[i]);
+		}
+	}
+	*pobjc = objc;
+	return objv;
+finally:
+	Tkapp_CallDeallocArgs(objv, objStore, objc);
+	return NULL;
+}
+
+/* Convert the results of a command call into a Python objects. */
+
+static PyObject*
+Tkapp_CallResult(TkappObject *self)
+{
+	PyObject *res = NULL;
+	if(self->wantobjects) {
+		Tcl_Obj *value = Tcl_GetObjResult(self->interp);
+		/* Not sure whether the IncrRef is necessary, but something
+		   may overwrite the interpreter result while we are
+		   converting it. */
+		Tcl_IncrRefCount(value);
+		res = FromObj((PyObject*)self, value);
+		Tcl_DecrRefCount(value);
+	} else {
+		const char *s = Tcl_GetStringResult(self->interp);
+		const char *p = s;
+
+		/* If the result contains any bytes with the top bit set,
+		   it's UTF-8 and we should decode it to Unicode */
+#ifdef Py_USING_UNICODE
+		while (*p != '\0') {
+			if (*p & 0x80)
+				break;
+			p++;
+		}
+
+		if (*p == '\0')
+			res = PyString_FromStringAndSize(s, (int)(p-s));
+		else {
+			/* Convert UTF-8 to Unicode string */
+			p = strchr(p, '\0');
+			res = PyUnicode_DecodeUTF8(s, (int)(p-s), "strict");
+			if (res == NULL) {
+				PyErr_Clear();
+				res = PyString_FromStringAndSize(s, (int)(p-s));
+			}
+		}
+#else
+		p = strchr(p, '\0');
+		res = PyString_FromStringAndSize(s, (int)(p-s));
+#endif
+	}
+	return res;
+}
+
+/* Tkapp_CallProc is the event procedure that is executed in the context of
+   the Tcl interpreter thread. Initially, it holds the Tcl lock, and doesn't
+   hold the Python lock. */
+
+static int
+Tkapp_CallProc(Tkapp_CallEvent *e, int flags)
+{
+	Tcl_Obj *objStore[ARGSZ];
+	Tcl_Obj **objv;
+	int objc;
+	int i;
+	ENTER_PYTHON
+	objv = Tkapp_CallArgs(e->args, objStore, &objc);
+	if (!objv) {
+		PyErr_Fetch(e->exc_type, e->exc_value, e->exc_tb);
+		*(e->res) = NULL;
+	}
+	LEAVE_PYTHON
+	if (!objv)
+		goto done;
+	i = Tcl_EvalObjv(e->self->interp, objc, objv, e->flags);
+	ENTER_PYTHON
+	if (i == TCL_ERROR) {
+		*(e->res) = NULL;
+		*(e->exc_type) = NULL;
+		*(e->exc_tb) = NULL;
+		*(e->exc_value) = PyObject_CallFunction(
+			Tkinter_TclError, "s",
+			Tcl_GetStringResult(e->self->interp));
+	}
+	else {
+		*(e->res) = Tkapp_CallResult(e->self);
+	}
+	LEAVE_PYTHON
+  done:
+	/* Wake up calling thread. */
+	Tcl_MutexLock(&call_mutex);
+	Tcl_ConditionNotify(&e->done);
+	Tcl_MutexUnlock(&call_mutex);
+	return 1;
+}
+
+/* This is the main entry point for calling a Tcl command.
+   It supports three cases, with regard to threading:
+   1. Tcl is not threaded: Must have the Tcl lock, then can invoke command in
+      the context of the calling thread.
+   2. Tcl is threaded, caller of the command is in the interpreter thread:
+      Execute the command in the calling thread. Since the Tcl lock will
+      not be used, we can merge that with case 1.
+   3. Tcl is threaded, caller is in a different thread: Must queue an event to
+      the interpreter thread. Allocation of Tcl objects needs to occur in the
+      interpreter thread, so we ship the PyObject* args to the target thread,
+      and perform processing there. */
+
+static PyObject *
+Tkapp_Call(PyObject *selfptr, PyObject *args)
+{
+	Tcl_Obj *objStore[ARGSZ];
+	Tcl_Obj **objv = NULL;
+	int objc, i;
+	PyObject *res = NULL;
+	TkappObject *self = (TkappObject*)selfptr;
+	/* Could add TCL_EVAL_GLOBAL if wrapped by GlobalCall... */
+	int flags = TCL_EVAL_DIRECT;
+
+#ifdef WITH_THREAD
+	if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
+		/* We cannot call the command directly. Instead, we must
+		   marshal the parameters to the interpreter thread. */
+		Tkapp_CallEvent *ev;
+		PyObject *exc_type, *exc_value, *exc_tb;
+		if (!WaitForMainloop(self))
+			return NULL;
+		ev = (Tkapp_CallEvent*)ckalloc(sizeof(Tkapp_CallEvent));
+		ev->ev.proc = (Tcl_EventProc*)Tkapp_CallProc;
+		ev->self = self;
+		ev->args = args;
+		ev->res = &res;
+		ev->exc_type = &exc_type;
+		ev->exc_value = &exc_value;
+		ev->exc_tb = &exc_tb;
+		ev->done = (Tcl_Condition)0;
+
+		Tkapp_ThreadSend(self, (Tcl_Event*)ev, &ev->done, &call_mutex);
+
+		if (res == NULL) {
+			if (exc_type)
+				PyErr_Restore(exc_type, exc_value, exc_tb);
+			else
+				PyErr_SetObject(Tkinter_TclError, exc_value);
+		}
+	}
+	else 
+#endif
+	{
+
+		objv = Tkapp_CallArgs(args, objStore, &objc);
+		if (!objv)
+			return NULL;
+
+		ENTER_TCL
+
+		i = Tcl_EvalObjv(self->interp, objc, objv, flags);
+
+		ENTER_OVERLAP
+
+		if (i == TCL_ERROR)
+			Tkinter_Error(selfptr);
+		else
+			res = Tkapp_CallResult(self);
+
+		LEAVE_OVERLAP_TCL
+
+		Tkapp_CallDeallocArgs(objv, objStore, objc);
+	}
+	return res;
+}
+
+
+static PyObject *
+Tkapp_GlobalCall(PyObject *self, PyObject *args)
+{
+	/* Could do the same here as for Tkapp_Call(), but this is not used
+	   much, so I can't be bothered.  Unfortunately Tcl doesn't export a
+	   way for the user to do what all its Global* variants do (save and
+	   reset the scope pointer, call the local version, restore the saved
+	   scope pointer). */
+
+	char *cmd;
+	PyObject *res = NULL;
+
+	CHECK_TCL_APPARTMENT;
+
+	cmd  = Merge(args);
+	if (cmd) {
+		int err;
+		ENTER_TCL
+		err = Tcl_GlobalEval(Tkapp_Interp(self), cmd);
+		ENTER_OVERLAP
+		if (err == TCL_ERROR)
+			res = Tkinter_Error(self);
+		else
+			res = PyString_FromString(Tkapp_Result(self));
+		LEAVE_OVERLAP_TCL
+		ckfree(cmd);
+	}
+
+	return res;
+}
+
+static PyObject *
+Tkapp_Eval(PyObject *self, PyObject *args)
+{
+	char *script;
+	PyObject *res = NULL;
+	int err;
+
+	if (!PyArg_ParseTuple(args, "s:eval", &script))
+		return NULL;
+
+	CHECK_TCL_APPARTMENT;
+
+	ENTER_TCL
+	err = Tcl_Eval(Tkapp_Interp(self), script);
+	ENTER_OVERLAP
+	if (err == TCL_ERROR)
+		res = Tkinter_Error(self);
+	else
+		res = PyString_FromString(Tkapp_Result(self));
+	LEAVE_OVERLAP_TCL
+	return res;
+}
+
+static PyObject *
+Tkapp_GlobalEval(PyObject *self, PyObject *args)
+{
+	char *script;
+	PyObject *res = NULL;
+	int err;
+
+	if (!PyArg_ParseTuple(args, "s:globaleval", &script))
+		return NULL;
+
+	CHECK_TCL_APPARTMENT;
+
+	ENTER_TCL
+	err = Tcl_GlobalEval(Tkapp_Interp(self), script);
+	ENTER_OVERLAP
+	if (err == TCL_ERROR)
+		res = Tkinter_Error(self);
+	else
+		res = PyString_FromString(Tkapp_Result(self));
+	LEAVE_OVERLAP_TCL
+	return res;
+}
+
+static PyObject *
+Tkapp_EvalFile(PyObject *self, PyObject *args)
+{
+	char *fileName;
+	PyObject *res = NULL;
+	int err;
+
+	if (!PyArg_ParseTuple(args, "s:evalfile", &fileName))
+		return NULL;
+
+	CHECK_TCL_APPARTMENT;
+
+	ENTER_TCL
+	err = Tcl_EvalFile(Tkapp_Interp(self), fileName);
+	ENTER_OVERLAP
+	if (err == TCL_ERROR)
+		res = Tkinter_Error(self);
+
+	else
+		res = PyString_FromString(Tkapp_Result(self));
+	LEAVE_OVERLAP_TCL
+	return res;
+}
+
+static PyObject *
+Tkapp_Record(PyObject *self, PyObject *args)
+{
+	char *script;
+	PyObject *res = NULL;
+	int err;
+
+	if (!PyArg_ParseTuple(args, "s", &script))
+		return NULL;
+
+	CHECK_TCL_APPARTMENT;
+
+	ENTER_TCL
+	err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL);
+	ENTER_OVERLAP
+	if (err == TCL_ERROR)
+		res = Tkinter_Error(self);
+	else
+		res = PyString_FromString(Tkapp_Result(self));
+	LEAVE_OVERLAP_TCL
+	return res;
+}
+
+static PyObject *
+Tkapp_AddErrorInfo(PyObject *self, PyObject *args)
+{
+	char *msg;
+
+	if (!PyArg_ParseTuple(args, "s:adderrorinfo", &msg))
+		return NULL;
+	CHECK_TCL_APPARTMENT;
+
+	ENTER_TCL
+	Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
+	LEAVE_TCL
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+
+
+/** Tcl Variable **/
+
+TCL_DECLARE_MUTEX(var_mutex)
+
+typedef PyObject* (*EventFunc)(PyObject*, PyObject *args, int flags);
+typedef struct VarEvent {
+	Tcl_Event ev; /* must be first */
+	PyObject *self;
+	PyObject *args;
+	int flags;
+	EventFunc func;
+	PyObject **res;
+	PyObject **exc_type;
+	PyObject **exc_val;
+	Tcl_Condition cond;
+} VarEvent;
+
+static int
+varname_converter(PyObject *in, void *_out)
+{
+	char **out = (char**)_out;
+	if (PyString_Check(in)) {
+		*out = PyString_AsString(in);
+		return 1;
+	}
+	if (PyTclObject_Check(in)) {
+		*out = PyTclObject_TclString(in);
+		return 1;
+	}
+	/* XXX: Should give diagnostics. */
+	return 0;
+}	
+
+void
+var_perform(VarEvent *ev)
+{
+	*(ev->res) = ev->func(ev->self, ev->args, ev->flags);
+	if (!*(ev->res)) {
+		PyObject *exc, *val, *tb;
+		PyErr_Fetch(&exc, &val, &tb);
+		PyErr_NormalizeException(&exc, &val, &tb);
+		*(ev->exc_type) = exc;
+		*(ev->exc_val) = val;
+		Py_DECREF(tb);
+	}
+		
+}
+
+static int
+var_proc(VarEvent* ev, int flags)
+{
+	ENTER_PYTHON
+        var_perform(ev);
+	Tcl_MutexLock(&var_mutex);
+	Tcl_ConditionNotify(&ev->cond);
+	Tcl_MutexUnlock(&var_mutex);
+	LEAVE_PYTHON
+	return 1;
+}
+
+static PyObject*
+var_invoke(EventFunc func, PyObject *selfptr, PyObject *args, int flags)
+{
+	TkappObject *self = (TkappObject*)selfptr;
+#ifdef WITH_THREAD
+	if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
+		TkappObject *self = (TkappObject*)selfptr;
+		VarEvent *ev;
+		PyObject *res, *exc_type, *exc_val;
+		
+		/* The current thread is not the interpreter thread.  Marshal
+		   the call to the interpreter thread, then wait for
+		   completion. */
+		if (!WaitForMainloop(self))
+			return NULL;
+
+		ev = (VarEvent*)ckalloc(sizeof(VarEvent));
+
+		ev->self = selfptr;
+		ev->args = args;
+		ev->flags = flags;
+		ev->func = func;
+		ev->res = &res;
+		ev->exc_type = &exc_type;
+		ev->exc_val = &exc_val;
+		ev->cond = NULL;
+		ev->ev.proc = (Tcl_EventProc*)var_proc;
+		Tkapp_ThreadSend(self, (Tcl_Event*)ev, &ev->cond, &var_mutex);
+		if (!res) {
+			PyErr_SetObject(exc_type, exc_val);
+			Py_DECREF(exc_type);
+			Py_DECREF(exc_val);
+			return NULL;
+		}
+		return res;
+	}
+#endif
+        /* Tcl is not threaded, or this is the interpreter thread. */
+	return func(selfptr, args, flags);
+}
+
+static PyObject *
+SetVar(PyObject *self, PyObject *args, int flags)
+{
+	char *name1, *name2;
+	PyObject *newValue;
+	PyObject *res = NULL;
+	Tcl_Obj *newval, *ok;
+
+	if (PyArg_ParseTuple(args, "O&O:setvar", 
+			     varname_converter, &name1, &newValue)) {
+		/* XXX Acquire tcl lock??? */
+		newval = AsObj(newValue);
+		if (newval == NULL)
+			return NULL;
+		ENTER_TCL
+		ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, NULL, 
+				   newval, flags);
+		ENTER_OVERLAP
+		if (!ok)
+			Tkinter_Error(self);
+		else {
+			res = Py_None;
+			Py_INCREF(res);
+		}
+		LEAVE_OVERLAP_TCL
+	}
+	else {
+		PyErr_Clear();
+		if (PyArg_ParseTuple(args, "ssO:setvar",
+				     &name1, &name2, &newValue)) {
+			/* XXX must hold tcl lock already??? */
+			newval = AsObj(newValue);
+			ENTER_TCL
+			ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, name2, newval, flags);
+			ENTER_OVERLAP
+			if (!ok)
+				Tkinter_Error(self);
+			else {
+				res = Py_None;
+				Py_INCREF(res);
+			}
+			LEAVE_OVERLAP_TCL
+		}
+		else {
+			return NULL;
+		}
+	}
+	return res;
+}
+
+static PyObject *
+Tkapp_SetVar(PyObject *self, PyObject *args)
+{
+	return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG);
+}
+
+static PyObject *
+Tkapp_GlobalSetVar(PyObject *self, PyObject *args)
+{
+	return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
+}
+
+
+
+static PyObject *
+GetVar(PyObject *self, PyObject *args, int flags)
+{
+	char *name1, *name2=NULL;
+	PyObject *res = NULL;
+	Tcl_Obj *tres;
+
+	if (!PyArg_ParseTuple(args, "O&|s:getvar", 
+			      varname_converter, &name1, &name2))
+		return NULL;
+
+	ENTER_TCL
+	tres = Tcl_GetVar2Ex(Tkapp_Interp(self), name1, name2, flags);
+	ENTER_OVERLAP
+	if (tres == NULL) {
+		PyErr_SetString(Tkinter_TclError, Tcl_GetStringResult(Tkapp_Interp(self)));
+	} else {
+		if (((TkappObject*)self)->wantobjects) {
+			res = FromObj(self, tres);
+		}
+		else {
+			res = PyString_FromString(Tcl_GetString(tres));
+		}
+	}
+	LEAVE_OVERLAP_TCL
+	return res;
+}
+
+static PyObject *
+Tkapp_GetVar(PyObject *self, PyObject *args)
+{
+	return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG);
+}
+
+static PyObject *
+Tkapp_GlobalGetVar(PyObject *self, PyObject *args)
+{
+	return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
+}
+
+
+
+static PyObject *
+UnsetVar(PyObject *self, PyObject *args, int flags)
+{
+	char *name1, *name2=NULL;
+	int code;
+	PyObject *res = NULL;
+
+	if (!PyArg_ParseTuple(args, "s|s:unsetvar", &name1, &name2))
+		return NULL;
+
+	ENTER_TCL
+	code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
+	ENTER_OVERLAP
+	if (code == TCL_ERROR)
+		res = Tkinter_Error(self);
+	else {
+		Py_INCREF(Py_None);
+		res = Py_None;
+	}
+	LEAVE_OVERLAP_TCL
+	return res;
+}
+
+static PyObject *
+Tkapp_UnsetVar(PyObject *self, PyObject *args)
+{
+	return var_invoke(UnsetVar, self, args, TCL_LEAVE_ERR_MSG);
+}
+
+static PyObject *
+Tkapp_GlobalUnsetVar(PyObject *self, PyObject *args)
+{
+	return var_invoke(UnsetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
+}
+
+
+
+/** Tcl to Python **/
+
+static PyObject *
+Tkapp_GetInt(PyObject *self, PyObject *args)
+{
+	char *s;
+	int v;
+
+	if (PyTuple_Size(args) == 1) {
+		PyObject* o = PyTuple_GetItem(args, 0);
+		if (PyInt_Check(o)) {
+			Py_INCREF(o);
+			return o;
+		}
+	}
+	if (!PyArg_ParseTuple(args, "s:getint", &s))
+		return NULL;
+	if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
+		return Tkinter_Error(self);
+	return Py_BuildValue("i", v);
+}
+
+static PyObject *
+Tkapp_GetDouble(PyObject *self, PyObject *args)
+{
+	char *s;
+	double v;
+
+	if (PyTuple_Size(args) == 1) {
+		PyObject *o = PyTuple_GetItem(args, 0);
+		if (PyFloat_Check(o)) {
+			Py_INCREF(o);
+			return o;
+		}
+	}
+	if (!PyArg_ParseTuple(args, "s:getdouble", &s))
+		return NULL;
+	if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
+		return Tkinter_Error(self);
+	return Py_BuildValue("d", v);
+}
+
+static PyObject *
+Tkapp_GetBoolean(PyObject *self, PyObject *args)
+{
+	char *s;
+	int v;
+
+	if (PyTuple_Size(args) == 1) {
+		PyObject *o = PyTuple_GetItem(args, 0);
+		if (PyInt_Check(o)) {
+			Py_INCREF(o);
+			return o;
+		}
+	}
+	if (!PyArg_ParseTuple(args, "s:getboolean", &s))
+		return NULL;
+	if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
+		return Tkinter_Error(self);
+	return PyBool_FromLong(v);
+}
+
+static PyObject *
+Tkapp_ExprString(PyObject *self, PyObject *args)
+{
+	char *s;
+	PyObject *res = NULL;
+	int retval;
+
+	if (!PyArg_ParseTuple(args, "s:exprstring", &s))
+		return NULL;
+	
+	CHECK_TCL_APPARTMENT;
+
+	ENTER_TCL
+	retval = Tcl_ExprString(Tkapp_Interp(self), s);
+	ENTER_OVERLAP
+	if (retval == TCL_ERROR)
+		res = Tkinter_Error(self);
+	else
+		res = Py_BuildValue("s", Tkapp_Result(self));
+	LEAVE_OVERLAP_TCL
+	return res;
+}
+
+static PyObject *
+Tkapp_ExprLong(PyObject *self, PyObject *args)
+{
+	char *s;
+	PyObject *res = NULL;
+	int retval;
+	long v;
+
+	if (!PyArg_ParseTuple(args, "s:exprlong", &s))
+		return NULL;
+
+	CHECK_TCL_APPARTMENT;
+
+	ENTER_TCL
+	retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v);
+	ENTER_OVERLAP
+	if (retval == TCL_ERROR)
+		res = Tkinter_Error(self);
+	else
+		res = Py_BuildValue("l", v);
+	LEAVE_OVERLAP_TCL
+	return res;
+}
+
+static PyObject *
+Tkapp_ExprDouble(PyObject *self, PyObject *args)
+{
+	char *s;
+	PyObject *res = NULL;
+	double v;
+	int retval;
+
+	if (!PyArg_ParseTuple(args, "s:exprdouble", &s))
+		return NULL;
+	CHECK_TCL_APPARTMENT;
+	PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
+	ENTER_TCL
+	retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
+	ENTER_OVERLAP
+	PyFPE_END_PROTECT(retval)
+	if (retval == TCL_ERROR)
+		res = Tkinter_Error(self);
+	else
+		res = Py_BuildValue("d", v);
+	LEAVE_OVERLAP_TCL
+	return res;
+}
+
+static PyObject *
+Tkapp_ExprBoolean(PyObject *self, PyObject *args)
+{
+	char *s;
+	PyObject *res = NULL;
+	int retval;
+	int v;
+
+	if (!PyArg_ParseTuple(args, "s:exprboolean", &s))
+		return NULL;
+	CHECK_TCL_APPARTMENT;
+	ENTER_TCL
+	retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v);
+	ENTER_OVERLAP
+	if (retval == TCL_ERROR)
+		res = Tkinter_Error(self);
+	else
+		res = Py_BuildValue("i", v);
+	LEAVE_OVERLAP_TCL
+	return res;
+}
+
+
+
+static PyObject *
+Tkapp_SplitList(PyObject *self, PyObject *args)
+{
+	char *list;
+	int argc;
+	char **argv;
+	PyObject *v;
+	int i;
+
+	if (PyTuple_Size(args) == 1) {
+		v = PyTuple_GetItem(args, 0);
+		if (PyTuple_Check(v)) {
+			Py_INCREF(v);
+			return v;
+		}
+	}
+	if (!PyArg_ParseTuple(args, "et:splitlist", "utf-8", &list))
+		return NULL;
+
+	if (Tcl_SplitList(Tkapp_Interp(self), list, 
+			  &argc, &argv) == TCL_ERROR)  {
+		PyMem_Free(list);
+		return Tkinter_Error(self);
+	}
+
+	if (!(v = PyTuple_New(argc)))
+		goto finally;
+
+	for (i = 0; i < argc; i++) {
+		PyObject *s = PyString_FromString(argv[i]);
+		if (!s || PyTuple_SetItem(v, i, s)) {
+			Py_DECREF(v);
+			v = NULL;
+			goto finally;
+		}
+	}
+
+  finally:
+	ckfree(FREECAST argv);
+	PyMem_Free(list);
+	return v;
+}
+
+static PyObject *
+Tkapp_Split(PyObject *self, PyObject *args)
+{
+	PyObject *v;
+	char *list;
+
+	if (PyTuple_Size(args) == 1) {
+		PyObject* o = PyTuple_GetItem(args, 0);
+		if (PyTuple_Check(o)) {
+			o = SplitObj(o);
+			return o;
+		}
+	}
+	if (!PyArg_ParseTuple(args, "et:split", "utf-8", &list))
+		return NULL;
+	v = Split(list);
+	PyMem_Free(list);
+	return v;
+}
+
+static PyObject *
+Tkapp_Merge(PyObject *self, PyObject *args)
+{
+	char *s = Merge(args);
+	PyObject *res = NULL;
+
+	if (s) {
+		res = PyString_FromString(s);
+		ckfree(s);
+	}
+
+	return res;
+}
+
+
+
+/** Tcl Command **/
+
+/* Client data struct */
+typedef struct {
+	PyObject *self;
+	PyObject *func;
+} PythonCmd_ClientData;
+
+static int
+PythonCmd_Error(Tcl_Interp *interp)
+{
+	errorInCmd = 1;
+	PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
+	LEAVE_PYTHON
+	return TCL_ERROR;
+}
+
+/* This is the Tcl command that acts as a wrapper for Python
+ * function or method.
+ */
+static int
+PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
+{
+	PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
+	PyObject *self, *func, *arg, *res, *tmp;
+	int i, rv;
+	char *s;
+
+	ENTER_PYTHON
+
+	/* TBD: no error checking here since we know, via the
+	 * Tkapp_CreateCommand() that the client data is a two-tuple
+	 */
+	self = data->self;
+	func = data->func;
+
+	/* Create argument list (argv1, ..., argvN) */
+	if (!(arg = PyTuple_New(argc - 1)))
+		return PythonCmd_Error(interp);
+
+	for (i = 0; i < (argc - 1); i++) {
+		PyObject *s = PyString_FromString(argv[i + 1]);
+		if (!s || PyTuple_SetItem(arg, i, s)) {
+			Py_DECREF(arg);
+			return PythonCmd_Error(interp);
+		}
+	}
+	res = PyEval_CallObject(func, arg);
+	Py_DECREF(arg);
+
+	if (res == NULL)
+		return PythonCmd_Error(interp);
+
+	if (!(tmp = PyList_New(0))) {
+		Py_DECREF(res);
+		return PythonCmd_Error(interp);
+	}
+
+	s = AsString(res, tmp);
+	if (s == NULL) {
+		rv = PythonCmd_Error(interp);
+	}
+	else {
+		Tcl_SetResult(Tkapp_Interp(self), s, TCL_VOLATILE);
+		rv = TCL_OK;
+	}
+
+	Py_DECREF(res);
+	Py_DECREF(tmp);
+
+	LEAVE_PYTHON
+
+	return rv;
+}
+
+static void
+PythonCmdDelete(ClientData clientData)
+{
+	PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
+
+	ENTER_PYTHON
+	Py_XDECREF(data->self);
+	Py_XDECREF(data->func);
+	PyMem_DEL(data);
+	LEAVE_PYTHON
+}
+
+
+
+
+TCL_DECLARE_MUTEX(command_mutex)
+
+typedef struct CommandEvent{
+	Tcl_Event ev;
+	Tcl_Interp* interp;
+	char *name;
+	int create;
+	int *status;
+	ClientData *data;
+	Tcl_Condition done;
+} CommandEvent;
+
+static int
+Tkapp_CommandProc(CommandEvent *ev, int flags)
+{
+	if (ev->create)
+		*ev->status = Tcl_CreateCommand(
+			ev->interp, ev->name, PythonCmd,
+			ev->data, PythonCmdDelete) == NULL;
+	else
+		*ev->status = Tcl_DeleteCommand(ev->interp, ev->name);
+	Tcl_MutexLock(&command_mutex);
+	Tcl_ConditionNotify(&ev->done);
+	Tcl_MutexUnlock(&command_mutex);
+	return 1;
+}
+
+static PyObject *
+Tkapp_CreateCommand(PyObject *selfptr, PyObject *args)
+{
+	TkappObject *self = (TkappObject*)selfptr;
+	PythonCmd_ClientData *data;
+	char *cmdName;
+	PyObject *func;
+	int err;
+
+	if (!PyArg_ParseTuple(args, "sO:createcommand", &cmdName, &func))
+		return NULL;
+	if (!PyCallable_Check(func)) {
+		PyErr_SetString(PyExc_TypeError, "command not callable");
+		return NULL;
+	}
+
+#ifdef WITH_THREAD
+	if (self->threaded && self->thread_id != Tcl_GetCurrentThread() &&
+	    !WaitForMainloop(self))
+		return NULL;
+#endif
+
+	data = PyMem_NEW(PythonCmd_ClientData, 1);
+	if (!data)
+		return PyErr_NoMemory();
+	Py_INCREF(self);
+	Py_INCREF(func);
+	data->self = selfptr;
+	data->func = func;
+	
+	if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
+		CommandEvent *ev = (CommandEvent*)ckalloc(sizeof(CommandEvent));
+		ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
+		ev->interp = self->interp;
+		ev->create = 1;
+		ev->name = cmdName;
+		ev->data = (ClientData)data;
+		ev->status = &err;
+		ev->done = NULL;
+		Tkapp_ThreadSend(self, (Tcl_Event*)ev, &ev->done, &command_mutex);
+	}
+	else {
+		ENTER_TCL
+		err = Tcl_CreateCommand(
+			Tkapp_Interp(self), cmdName, PythonCmd,
+			(ClientData)data, PythonCmdDelete) == NULL;
+		LEAVE_TCL
+	}
+	if (err) {
+		PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
+		PyMem_DEL(data);
+		return NULL;
+	}
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+
+
+static PyObject *
+Tkapp_DeleteCommand(PyObject *selfptr, PyObject *args)
+{
+	TkappObject *self = (TkappObject*)selfptr;
+	char *cmdName;
+	int err;
+
+	if (!PyArg_ParseTuple(args, "s:deletecommand", &cmdName))
+		return NULL;
+	if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
+		CommandEvent *ev;
+		ev = (CommandEvent*)ckalloc(sizeof(CommandEvent));
+		ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
+		ev->interp = self->interp;
+		ev->create = 0;
+		ev->name = cmdName;
+		ev->status = &err;
+		ev->done = NULL;
+		Tkapp_ThreadSend(self, (Tcl_Event*)ev, &ev->done, 
+				 &command_mutex);
+	}
+	else {
+		ENTER_TCL
+		err = Tcl_DeleteCommand(self->interp, cmdName);
+		LEAVE_TCL
+	}
+	if (err == -1) {
+		PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
+		return NULL;
+	}
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+
+
+#ifdef HAVE_CREATEFILEHANDLER
+/** File Handler **/
+
+typedef struct _fhcdata {
+	PyObject *func;
+	PyObject *file;
+	int id;
+	struct _fhcdata *next;
+} FileHandler_ClientData;
+
+static FileHandler_ClientData *HeadFHCD;
+
+static FileHandler_ClientData *
+NewFHCD(PyObject *func, PyObject *file, int id)
+{
+	FileHandler_ClientData *p;
+	p = PyMem_NEW(FileHandler_ClientData, 1);
+	if (p != NULL) {
+		Py_XINCREF(func);
+		Py_XINCREF(file);
+		p->func = func;
+		p->file = file;
+		p->id = id;
+		p->next = HeadFHCD;
+		HeadFHCD = p;
+	}
+	return p;
+}
+
+static void
+DeleteFHCD(int id)
+{
+	FileHandler_ClientData *p, **pp;
+
+	pp = &HeadFHCD;
+	while ((p = *pp) != NULL) {
+		if (p->id == id) {
+			*pp = p->next;
+			Py_XDECREF(p->func);
+			Py_XDECREF(p->file);
+			PyMem_DEL(p);
+		}
+		else
+			pp = &p->next;
+	}
+}
+
+static void
+FileHandler(ClientData clientData, int mask)
+{
+	FileHandler_ClientData *data = (FileHandler_ClientData *)clientData;
+	PyObject *func, *file, *arg, *res;
+
+	ENTER_PYTHON
+	func = data->func;
+	file = data->file;
+
+	arg = Py_BuildValue("(Oi)", file, (long) mask);
+	res = PyEval_CallObject(func, arg);
+	Py_DECREF(arg);
+
+	if (res == NULL) {
+		errorInCmd = 1;
+		PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
+	}
+	Py_XDECREF(res);
+	LEAVE_PYTHON
+}
+
+static PyObject *
+Tkapp_CreateFileHandler(PyObject *self, PyObject *args)
+     /* args is (file, mask, func) */
+{
+	FileHandler_ClientData *data;
+	PyObject *file, *func;
+	int mask, tfile;
+
+	if (!PyArg_ParseTuple(args, "OiO:createfilehandler",
+			      &file, &mask, &func))
+		return NULL;
+
+#ifdef WITH_THREAD
+	if (!self && !tcl_lock) {
+		/* We don't have the Tcl lock since Tcl is threaded. */
+		PyErr_SetString(PyExc_RuntimeError,
+				"_tkinter.createfilehandler not supported "
+				"for threaded Tcl");
+		return NULL;
+	}
+#endif
+
+	if (self) {
+		CHECK_TCL_APPARTMENT;
+	}
+
+	tfile = PyObject_AsFileDescriptor(file);
+	if (tfile < 0)
+		return NULL;
+	if (!PyCallable_Check(func)) {
+		PyErr_SetString(PyExc_TypeError, "bad argument list");
+		return NULL;
+	}
+
+	data = NewFHCD(func, file, tfile);
+	if (data == NULL)
+		return NULL;
+
+	/* Ought to check for null Tcl_File object... */
+	ENTER_TCL
+	Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
+	LEAVE_TCL
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+Tkapp_DeleteFileHandler(PyObject *self, PyObject *args)
+{
+	PyObject *file;
+	int tfile;
+
+	if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file))
+		return NULL;
+
+#ifdef WITH_THREAD
+	if (!self && !tcl_lock) {
+		/* We don't have the Tcl lock since Tcl is threaded. */
+		PyErr_SetString(PyExc_RuntimeError,
+				"_tkinter.deletefilehandler not supported "
+				"for threaded Tcl");
+		return NULL;
+	}
+#endif
+
+	if (self) {
+		CHECK_TCL_APPARTMENT;
+	}
+
+	tfile = PyObject_AsFileDescriptor(file);
+	if (tfile < 0)
+		return NULL;
+
+	DeleteFHCD(tfile);
+
+	/* Ought to check for null Tcl_File object... */
+	ENTER_TCL
+	Tcl_DeleteFileHandler(tfile);
+	LEAVE_TCL
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+#endif /* HAVE_CREATEFILEHANDLER */
+
+
+/**** Tktt Object (timer token) ****/
+
+static PyTypeObject Tktt_Type;
+
+typedef struct {
+	PyObject_HEAD
+	Tcl_TimerToken token;
+	PyObject *func;
+} TkttObject;
+
+static PyObject *
+Tktt_DeleteTimerHandler(PyObject *self, PyObject *args)
+{
+	TkttObject *v = (TkttObject *)self;
+	PyObject *func = v->func;
+
+	if (!PyArg_ParseTuple(args, ":deletetimerhandler"))
+		return NULL;
+	if (v->token != NULL) {
+		Tcl_DeleteTimerHandler(v->token);
+		v->token = NULL;
+	}
+	if (func != NULL) {
+		v->func = NULL;
+		Py_DECREF(func);
+		Py_DECREF(v); /* See Tktt_New() */
+	}
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyMethodDef Tktt_methods[] =
+{
+	{"deletetimerhandler", Tktt_DeleteTimerHandler, METH_VARARGS},
+	{NULL, NULL}
+};
+
+static TkttObject *
+Tktt_New(PyObject *func)
+{
+	TkttObject *v;
+  
+	v = PyObject_New(TkttObject, &Tktt_Type);
+	if (v == NULL)
+		return NULL;
+
+	Py_INCREF(func);
+	v->token = NULL;
+	v->func = func;
+
+	/* Extra reference, deleted when called or when handler is deleted */
+	Py_INCREF(v);
+	return v;
+}
+
+static void
+Tktt_Dealloc(PyObject *self)
+{
+	TkttObject *v = (TkttObject *)self;
+	PyObject *func = v->func;
+
+	Py_XDECREF(func);
+
+	PyObject_Del(self);
+}
+
+static PyObject *
+Tktt_Repr(PyObject *self)
+{
+	TkttObject *v = (TkttObject *)self;
+	char buf[100];
+
+	PyOS_snprintf(buf, sizeof(buf), "<tktimertoken at %p%s>", v,
+	                v->func == NULL ? ", handler deleted" : "");
+	return PyString_FromString(buf);
+}
+
+static PyObject *
+Tktt_GetAttr(PyObject *self, char *name)
+{
+	return Py_FindMethod(Tktt_methods, self, name);
+}
+
+static PyTypeObject Tktt_Type =
+{
+	PyObject_HEAD_INIT(NULL)
+	0,				     /*ob_size */
+	"tktimertoken",			     /*tp_name */
+	sizeof(TkttObject),		     /*tp_basicsize */
+	0,				     /*tp_itemsize */
+	Tktt_Dealloc,			     /*tp_dealloc */
+	0,				     /*tp_print */
+	Tktt_GetAttr,			     /*tp_getattr */
+	0,				     /*tp_setattr */
+	0,				     /*tp_compare */
+	Tktt_Repr,			     /*tp_repr */
+	0,				     /*tp_as_number */
+	0,				     /*tp_as_sequence */
+	0,				     /*tp_as_mapping */
+	0,				     /*tp_hash */
+};
+
+
+
+/** Timer Handler **/
+
+static void
+TimerHandler(ClientData clientData)
+{
+	TkttObject *v = (TkttObject *)clientData;
+	PyObject *func = v->func;
+	PyObject *res;
+
+	if (func == NULL)
+		return;
+
+	v->func = NULL;
+
+	ENTER_PYTHON
+
+	res  = PyEval_CallObject(func, NULL);
+	Py_DECREF(func);
+	Py_DECREF(v); /* See Tktt_New() */
+
+	if (res == NULL) {
+		errorInCmd = 1;
+		PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
+	}
+	else
+		Py_DECREF(res);
+
+	LEAVE_PYTHON
+}
+
+static PyObject *
+Tkapp_CreateTimerHandler(PyObject *self, PyObject *args)
+{
+	int milliseconds;
+	PyObject *func;
+	TkttObject *v;
+
+	if (!PyArg_ParseTuple(args, "iO:createtimerhandler",
+			      &milliseconds, &func))
+		return NULL;
+	if (!PyCallable_Check(func)) {
+		PyErr_SetString(PyExc_TypeError, "bad argument list");
+		return NULL;
+	}
+
+#ifdef WITH_THREAD
+	if (!self && !tcl_lock) {
+		/* We don't have the Tcl lock since Tcl is threaded. */
+		PyErr_SetString(PyExc_RuntimeError,
+				"_tkinter.createtimerhandler not supported "
+				"for threaded Tcl");
+		return NULL;
+	}
+#endif
+
+	if (self) {
+		CHECK_TCL_APPARTMENT;
+	}
+
+	v = Tktt_New(func);
+	if (v) {
+		v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
+						  (ClientData)v);
+	}
+
+	return (PyObject *) v;
+}
+
+
+/** Event Loop **/
+
+static PyObject *
+Tkapp_MainLoop(PyObject *selfptr, PyObject *args)
+{
+	int threshold = 0;
+	TkappObject *self = (TkappObject*)selfptr;
+#ifdef WITH_THREAD
+	PyThreadState *tstate = PyThreadState_Get();
+#endif
+
+	if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold))
+		return NULL;
+
+#ifdef WITH_THREAD
+	if (!self && !tcl_lock) {
+		/* We don't have the Tcl lock since Tcl is threaded. */
+		PyErr_SetString(PyExc_RuntimeError,
+				"_tkinter.mainloop not supported "
+				"for threaded Tcl");
+		return NULL;
+	}
+#endif
+
+	if (self) {
+		CHECK_TCL_APPARTMENT;
+		self->dispatching = 1;
+	}
+
+	quitMainLoop = 0;
+	while (Tk_GetNumMainWindows() > threshold &&
+	       !quitMainLoop &&
+	       !errorInCmd)
+	{
+		int result;
+
+#ifdef WITH_THREAD
+		if (self && self->threaded) {
+			/* Allow other Python threads to run. */
+			ENTER_TCL
+			result = Tcl_DoOneEvent(0);
+			LEAVE_TCL
+		}
+		else {
+			Py_BEGIN_ALLOW_THREADS
+			if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
+			tcl_tstate = tstate;
+			result = Tcl_DoOneEvent(TCL_DONT_WAIT);
+			tcl_tstate = NULL;
+			if(tcl_lock)PyThread_release_lock(tcl_lock);
+			if (result == 0)
+				Sleep(Tkinter_busywaitinterval);
+			Py_END_ALLOW_THREADS
+		}
+#else
+		result = Tcl_DoOneEvent(0);
+#endif
+
+		if (PyErr_CheckSignals() != 0) {
+			if (self)
+				self->dispatching = 0;
+			return NULL;
+		}
+		if (result < 0)
+			break;
+	}
+	if (self)
+		self->dispatching = 0;
+	quitMainLoop = 0;
+
+	if (errorInCmd) {
+		errorInCmd = 0;
+		PyErr_Restore(excInCmd, valInCmd, trbInCmd);
+		excInCmd = valInCmd = trbInCmd = NULL;
+		return NULL;
+	}
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+Tkapp_DoOneEvent(PyObject *self, PyObject *args)
+{
+	int flags = 0;
+	int rv;
+
+	if (!PyArg_ParseTuple(args, "|i:dooneevent", &flags))
+		return NULL;
+
+	ENTER_TCL
+	rv = Tcl_DoOneEvent(flags);
+	LEAVE_TCL
+	return Py_BuildValue("i", rv);
+}
+
+static PyObject *
+Tkapp_Quit(PyObject *self, PyObject *args)
+{
+
+	if (!PyArg_ParseTuple(args, ":quit"))
+		return NULL;
+
+	quitMainLoop = 1;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+Tkapp_InterpAddr(PyObject *self, PyObject *args)
+{
+
+	if (!PyArg_ParseTuple(args, ":interpaddr"))
+		return NULL;
+
+	return PyInt_FromLong((long)Tkapp_Interp(self));
+}
+
+static PyObject	*
+Tkapp_TkInit(PyObject *self, PyObject *args)
+{
+	static int has_failed;
+	Tcl_Interp *interp = Tkapp_Interp(self);
+	Tk_Window main_window;
+	const char * _tk_exists = NULL;
+	int err;
+	main_window = Tk_MainWindow(interp);
+
+	/* In all current versions of Tk (including 8.4.13), Tk_Init
+	   deadlocks on the second call when the first call failed.
+	   To avoid the deadlock, we just refuse the second call through
+	   a static variable. */
+	if (has_failed) {
+		PyErr_SetString(Tkinter_TclError, 
+				"Calling Tk_Init again after a previous call failed might deadlock");
+		return NULL;
+	}
+	   
+	/* We want to guard against calling Tk_Init() multiple times */
+	CHECK_TCL_APPARTMENT;
+	ENTER_TCL
+	err = Tcl_Eval(Tkapp_Interp(self), "info exists	tk_version");
+	ENTER_OVERLAP
+	if (err == TCL_ERROR) {
+		/* This sets an exception, but we cannot return right
+		   away because we need to exit the overlap first. */
+		Tkinter_Error(self);
+	} else {
+		_tk_exists = Tkapp_Result(self);
+	}
+	LEAVE_OVERLAP_TCL
+	if (err == TCL_ERROR) {
+		return NULL;
+	}
+	if (_tk_exists == NULL || strcmp(_tk_exists, "1") != 0)	{
+		if (Tk_Init(interp)	== TCL_ERROR) {
+		        PyErr_SetString(Tkinter_TclError, Tcl_GetStringResult(Tkapp_Interp(self)));
+			has_failed = 1;
+			return NULL;
+		}
+	}
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+Tkapp_WantObjects(PyObject *self, PyObject *args)
+{
+
+	int wantobjects = -1;
+	if (!PyArg_ParseTuple(args, "|i:wantobjects", &wantobjects))
+		return NULL;
+	if (wantobjects == -1)
+		return PyBool_FromLong(((TkappObject*)self)->wantobjects);
+	((TkappObject*)self)->wantobjects = wantobjects;
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+Tkapp_WillDispatch(PyObject *self, PyObject *args)
+{
+
+	((TkappObject*)self)->dispatching = 1;
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+
+/**** Tkapp Method List ****/
+
+static PyMethodDef Tkapp_methods[] =
+{
+	{"willdispatch",       Tkapp_WillDispatch, METH_NOARGS},
+	{"wantobjects",	       Tkapp_WantObjects, METH_VARARGS},
+	{"call", 	       Tkapp_Call, METH_OLDARGS},
+	{"globalcall", 	       Tkapp_GlobalCall, METH_OLDARGS},
+	{"eval", 	       Tkapp_Eval, METH_VARARGS},
+	{"globaleval", 	       Tkapp_GlobalEval, METH_VARARGS},
+	{"evalfile", 	       Tkapp_EvalFile, METH_VARARGS},
+	{"record", 	       Tkapp_Record, METH_VARARGS},
+	{"adderrorinfo",       Tkapp_AddErrorInfo, METH_VARARGS},
+	{"setvar", 	       Tkapp_SetVar, METH_VARARGS},
+	{"globalsetvar",       Tkapp_GlobalSetVar, METH_VARARGS},
+	{"getvar", 	       Tkapp_GetVar, METH_VARARGS},
+	{"globalgetvar",       Tkapp_GlobalGetVar, METH_VARARGS},
+	{"unsetvar", 	       Tkapp_UnsetVar, METH_VARARGS},
+	{"globalunsetvar",     Tkapp_GlobalUnsetVar, METH_VARARGS},
+	{"getint", 	       Tkapp_GetInt, METH_VARARGS},
+	{"getdouble", 	       Tkapp_GetDouble, METH_VARARGS},
+	{"getboolean", 	       Tkapp_GetBoolean, METH_VARARGS},
+	{"exprstring", 	       Tkapp_ExprString, METH_VARARGS},
+	{"exprlong", 	       Tkapp_ExprLong, METH_VARARGS},
+	{"exprdouble", 	       Tkapp_ExprDouble, METH_VARARGS},
+	{"exprboolean",        Tkapp_ExprBoolean, METH_VARARGS},
+	{"splitlist", 	       Tkapp_SplitList, METH_VARARGS},
+	{"split", 	       Tkapp_Split, METH_VARARGS},
+	{"merge", 	       Tkapp_Merge, METH_OLDARGS},
+	{"createcommand",      Tkapp_CreateCommand, METH_VARARGS},
+	{"deletecommand",      Tkapp_DeleteCommand, METH_VARARGS},
+#ifdef HAVE_CREATEFILEHANDLER
+	{"createfilehandler",  Tkapp_CreateFileHandler, METH_VARARGS},
+	{"deletefilehandler",  Tkapp_DeleteFileHandler, METH_VARARGS},
+#endif
+	{"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS},
+	{"mainloop", 	       Tkapp_MainLoop, METH_VARARGS},
+	{"dooneevent", 	       Tkapp_DoOneEvent, METH_VARARGS},
+	{"quit", 	       Tkapp_Quit, METH_VARARGS},
+	{"interpaddr",         Tkapp_InterpAddr, METH_VARARGS},
+	{"loadtk",	       Tkapp_TkInit, METH_NOARGS},
+	{NULL, 		       NULL}
+};
+
+
+
+/**** Tkapp Type Methods ****/
+
+static void
+Tkapp_Dealloc(PyObject *self)
+{
+	/*CHECK_TCL_APPARTMENT;*/
+	ENTER_TCL
+	Tcl_DeleteInterp(Tkapp_Interp(self));
+	LEAVE_TCL
+	PyObject_Del(self);
+	DisableEventHook();
+}
+
+static PyObject *
+Tkapp_GetAttr(PyObject *self, char *name)
+{
+	return Py_FindMethod(Tkapp_methods, self, name);
+}
+
+static PyTypeObject Tkapp_Type =
+{
+	PyObject_HEAD_INIT(NULL)
+	0,				     /*ob_size */
+	"tkapp",			     /*tp_name */
+	sizeof(TkappObject),		     /*tp_basicsize */
+	0,				     /*tp_itemsize */
+	Tkapp_Dealloc,			     /*tp_dealloc */
+	0,				     /*tp_print */
+	Tkapp_GetAttr,			     /*tp_getattr */
+	0,				     /*tp_setattr */
+	0,				     /*tp_compare */
+	0,				     /*tp_repr */
+	0,				     /*tp_as_number */
+	0,				     /*tp_as_sequence */
+	0,				     /*tp_as_mapping */
+	0,				     /*tp_hash */
+};
+
+
+
+/**** Tkinter Module ****/
+
+typedef struct {
+	PyObject* tuple;
+	int size; /* current size */
+	int maxsize; /* allocated size */
+} FlattenContext;
+
+static int
+_bump(FlattenContext* context, int size)
+{
+	/* expand tuple to hold (at least) size new items.
+	   return true if successful, false if an exception was raised */
+
+	int maxsize = context->maxsize * 2;
+
+	if (maxsize < context->size + size)
+		maxsize = context->size + size;
+
+	context->maxsize = maxsize;
+
+	return _PyTuple_Resize(&context->tuple, maxsize) >= 0;
+}
+
+static int
+_flatten1(FlattenContext* context, PyObject* item, int depth)
+{
+	/* add tuple or list to argument tuple (recursively) */
+
+	int i, size;
+
+	if (depth > 1000) {
+		PyErr_SetString(PyExc_ValueError,
+				"nesting too deep in _flatten");
+		return 0;
+	} else if (PyList_Check(item)) {
+		size = PyList_GET_SIZE(item);
+		/* preallocate (assume no nesting) */
+		if (context->size + size > context->maxsize &&
+		    !_bump(context, size))
+			return 0;
+		/* copy items to output tuple */
+		for (i = 0; i < size; i++) {
+			PyObject *o = PyList_GET_ITEM(item, i);
+			if (PyList_Check(o) || PyTuple_Check(o)) {
+				if (!_flatten1(context, o, depth + 1))
+					return 0;
+			} else if (o != Py_None) {
+				if (context->size + 1 > context->maxsize &&
+				    !_bump(context, 1))
+					return 0;
+				Py_INCREF(o);
+				PyTuple_SET_ITEM(context->tuple,
+						 context->size++, o);
+			}
+		}
+	} else if (PyTuple_Check(item)) {
+		/* same, for tuples */
+		size = PyTuple_GET_SIZE(item);
+		if (context->size + size > context->maxsize &&
+		    !_bump(context, size))
+			return 0;
+		for (i = 0; i < size; i++) {
+			PyObject *o = PyTuple_GET_ITEM(item, i);
+			if (PyList_Check(o) || PyTuple_Check(o)) {
+				if (!_flatten1(context, o, depth + 1))
+					return 0;
+			} else if (o != Py_None) {
+				if (context->size + 1 > context->maxsize &&
+				    !_bump(context, 1))
+					return 0;
+				Py_INCREF(o);
+				PyTuple_SET_ITEM(context->tuple,
+						 context->size++, o);
+			}
+		}
+	} else {
+		PyErr_SetString(PyExc_TypeError, "argument must be sequence");
+		return 0;
+	}
+	return 1;
+}
+
+static PyObject *
+Tkinter_Flatten(PyObject* self, PyObject* args)
+{
+	FlattenContext context;
+	PyObject* item;
+
+	if (!PyArg_ParseTuple(args, "O:_flatten", &item))
+		return NULL;
+
+	context.maxsize = PySequence_Size(item);
+	if (context.maxsize <= 0)
+		return PyTuple_New(0);
+	
+	context.tuple = PyTuple_New(context.maxsize);
+	if (!context.tuple)
+		return NULL;
+	
+	context.size = 0;
+
+	if (!_flatten1(&context, item,0))
+		return NULL;
+
+	if (_PyTuple_Resize(&context.tuple, context.size))
+		return NULL;
+
+	return context.tuple;
+}
+
+static PyObject *
+Tkinter_Create(PyObject *self, PyObject *args)
+{
+	char *screenName = NULL;
+	char *baseName = NULL;
+	char *className = NULL;
+	int interactive = 0;
+	int wantobjects = 0;
+	int wantTk = 1;	/* If false, then Tk_Init() doesn't get	called */
+	int sync = 0; /* pass -sync to wish */
+	char *use = NULL; /* pass -use to wish */
+
+	baseName = strrchr(Py_GetProgramName(), '/');
+	if (baseName != NULL)
+		baseName++;
+	else
+		baseName = Py_GetProgramName();
+	className = "Tk";
+  
+	if (!PyArg_ParseTuple(args, "|zssiiiiz:create",
+			      &screenName, &baseName, &className,
+			      &interactive, &wantobjects, &wantTk,
+			      &sync, &use))
+		return NULL;
+
+	return (PyObject *) Tkapp_New(screenName, baseName, className, 
+				      interactive, wantobjects,	wantTk,
+				      sync, use);
+}
+
+static PyObject *
+Tkinter_setbusywaitinterval(PyObject *self, PyObject *args)
+{
+	int new_val;
+	if (!PyArg_ParseTuple(args, "i:setbusywaitinterval", &new_val))
+		return NULL;
+	if (new_val < 0) {
+		PyErr_SetString(PyExc_ValueError,
+				"busywaitinterval must be >= 0");
+		return NULL;
+	}
+	Tkinter_busywaitinterval = new_val;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static char setbusywaitinterval_doc[] =
+"setbusywaitinterval(n) -> None\n\
+\n\
+Set the busy-wait interval in milliseconds between successive\n\
+calls to Tcl_DoOneEvent in a threaded Python interpreter.\n\
+It should be set to a divisor of the maximum time between\n\
+frames in an animation.";
+
+static PyObject *
+Tkinter_getbusywaitinterval(PyObject *self, PyObject *args)
+{
+        return PyInt_FromLong(Tkinter_busywaitinterval);
+}
+
+static char getbusywaitinterval_doc[] =
+"getbusywaitinterval() -> int\n\
+\n\
+Return the current busy-wait interval between successive\n\
+calls to Tcl_DoOneEvent in a threaded Python interpreter.";
+
+static PyMethodDef moduleMethods[] =
+{
+	{"_flatten",           Tkinter_Flatten, METH_VARARGS},
+	{"create",             Tkinter_Create, METH_VARARGS},
+#ifdef HAVE_CREATEFILEHANDLER
+	{"createfilehandler",  Tkapp_CreateFileHandler, METH_VARARGS},
+	{"deletefilehandler",  Tkapp_DeleteFileHandler, METH_VARARGS},
+#endif
+	{"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS},
+	{"mainloop",           Tkapp_MainLoop, METH_VARARGS},
+	{"dooneevent",         Tkapp_DoOneEvent, METH_VARARGS},
+	{"quit",               Tkapp_Quit, METH_VARARGS},
+	{"setbusywaitinterval",Tkinter_setbusywaitinterval, METH_VARARGS,
+	                       setbusywaitinterval_doc},
+	{"getbusywaitinterval",(PyCFunction)Tkinter_getbusywaitinterval,
+	                       METH_NOARGS, getbusywaitinterval_doc},
+	{NULL,                 NULL}
+};
+
+#ifdef WAIT_FOR_STDIN
+
+static int stdin_ready = 0;
+
+#ifndef MS_WINDOWS
+static void
+MyFileProc(void *clientData, int mask)
+{
+	stdin_ready = 1;
+}
+#endif
+
+#ifdef WITH_THREAD
+static PyThreadState *event_tstate = NULL;
+#endif
+
+static int
+EventHook(void)
+{
+#ifndef MS_WINDOWS
+	int tfile;
+#endif
+#ifdef WITH_THREAD
+	PyEval_RestoreThread(event_tstate);
+#endif
+	stdin_ready = 0;
+	errorInCmd = 0;
+#ifndef MS_WINDOWS
+	tfile = fileno(stdin);
+	Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
+#endif
+	while (!errorInCmd && !stdin_ready) {
+		int result;
+#ifdef MS_WINDOWS
+		if (_kbhit()) {
+			stdin_ready = 1;
+			break;
+		}
+#endif
+#if defined(WITH_THREAD) || defined(MS_WINDOWS)
+		Py_BEGIN_ALLOW_THREADS
+		if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
+		tcl_tstate = event_tstate;
+
+		result = Tcl_DoOneEvent(TCL_DONT_WAIT);
+
+		tcl_tstate = NULL;
+		if(tcl_lock)PyThread_release_lock(tcl_lock);
+		if (result == 0)
+			Sleep(Tkinter_busywaitinterval);
+		Py_END_ALLOW_THREADS
+#else
+		result = Tcl_DoOneEvent(0);
+#endif
+
+		if (result < 0)
+			break;
+	}
+#ifndef MS_WINDOWS
+	Tcl_DeleteFileHandler(tfile);
+#endif
+	if (errorInCmd) {
+		errorInCmd = 0;
+		PyErr_Restore(excInCmd, valInCmd, trbInCmd);
+		excInCmd = valInCmd = trbInCmd = NULL;
+		PyErr_Print();
+	}
+#ifdef WITH_THREAD
+	PyEval_SaveThread();
+#endif
+	return 0;
+}
+
+#endif
+
+static void
+EnableEventHook(void)
+{
+#ifdef WAIT_FOR_STDIN
+	if (PyOS_InputHook == NULL) {
+#ifdef WITH_THREAD
+		event_tstate = PyThreadState_Get();
+#endif
+		PyOS_InputHook = EventHook;
+	}
+#endif
+}
+
+static void
+DisableEventHook(void)
+{
+#ifdef WAIT_FOR_STDIN
+	if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) {
+		PyOS_InputHook = NULL;
+	}
+#endif
+}
+
+
+/* all errors will be checked in one fell swoop in init_tkinter() */
+static void
+ins_long(PyObject *d, char *name, long val)
+{
+	PyObject *v = PyInt_FromLong(val);
+	if (v) {
+		PyDict_SetItemString(d, name, v);
+		Py_DECREF(v);
+	}
+}
+static void
+ins_string(PyObject *d, char *name, char *val)
+{
+	PyObject *v = PyString_FromString(val);
+	if (v) {
+		PyDict_SetItemString(d, name, v);
+		Py_DECREF(v);
+	}
+}
+
+
+PyMODINIT_FUNC
+init_tkinter(void)
+{
+	PyObject *m, *d;
+
+	Tkapp_Type.ob_type = &PyType_Type;
+
+#ifdef WITH_THREAD
+	tcl_lock = PyThread_allocate_lock();
+#endif
+
+	m = Py_InitModule("_tkinter", moduleMethods);
+	if (m == NULL)
+		return;
+
+	d = PyModule_GetDict(m);
+	Tkinter_TclError = PyErr_NewException("_tkinter.TclError", NULL, NULL);
+	PyDict_SetItemString(d, "TclError", Tkinter_TclError);
+
+	ins_long(d, "READABLE", TCL_READABLE);
+	ins_long(d, "WRITABLE", TCL_WRITABLE);
+	ins_long(d, "EXCEPTION", TCL_EXCEPTION);
+	ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
+	ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
+	ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
+	ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
+	ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
+	ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
+	ins_string(d, "TK_VERSION", TK_VERSION);
+	ins_string(d, "TCL_VERSION", TCL_VERSION);
+
+	PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
+
+	Tktt_Type.ob_type = &PyType_Type;
+	PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
+
+	PyTclObject_Type.ob_type = &PyType_Type;
+	PyDict_SetItemString(d, "Tcl_Obj", (PyObject *)&PyTclObject_Type);
+
+#ifdef TK_AQUA
+	/* Tk_MacOSXSetupTkNotifier must be called before Tcl's subsystems
+	 * start waking up.  Note that Tcl_FindExecutable will do this, this
+	 * code must be above it! The original warning from
+	 * tkMacOSXAppInit.c is copied below.
+	 *
+	 * NB - You have to swap in the Tk Notifier BEFORE you start up the
+	 * Tcl interpreter for now.  It probably should work to do this
+	 * in the other order, but for now it doesn't seem to.
+	 *
+	 */
+	Tk_MacOSXSetupTkNotifier();
+#endif
+
+
+	/* This helps the dynamic loader; in Unicode aware Tcl versions
+	   it also helps Tcl find its encodings. */
+	Tcl_FindExecutable(Py_GetProgramName());
+
+	if (PyErr_Occurred())
+		return;
+
+#if 0
+	/* This was not a good idea; through <Destroy> bindings,
+	   Tcl_Finalize() may invoke Python code but at that point the
+	   interpreter and thread state have already been destroyed! */
+	Py_AtExit(Tcl_Finalize);
+#endif
+
+}

Added: vendor/Python/current/Modules/_typesmodule.c
===================================================================
--- vendor/Python/current/Modules/_typesmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_typesmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,94 @@
+/* This extension module exposes some types that are only available at the
+ * C level.  It should not be used directly, but instead through the Python
+ * level types modules, which imports this.
+ */
+
+#include "Python.h"
+#include "structmember.h"
+
+typedef struct
+{
+    PyObject_HEAD
+    int member;
+} Helper;
+
+static PyMemberDef helper_members[] = {
+    { "member", T_INT,  offsetof(Helper, member), READONLY,
+      PyDoc_STR("A member descriptor")
+    },
+    { NULL }
+};
+
+static PyObject *
+helper_getter(Helper *self, void *unused) 
+{
+    Py_RETURN_NONE;
+}
+
+static PyGetSetDef helper_getset[] = {
+    { "getter", (getter)helper_getter, NULL,
+      PyDoc_STR("A getset descriptor"),
+    },
+    { NULL }
+};
+
+static PyTypeObject HelperType = {
+    PyObject_HEAD_INIT(NULL)
+    0,						/* ob_size */
+    "_types.Helper",				/* tp_name */
+    sizeof(Helper),                             /* tp_basicsize */
+    0,						/* tp_itemsize */
+    0,						/* tp_dealloc */
+    0,						/* tp_print */
+    0,						/* tp_getattr */
+    0,						/* tp_setattr */
+    0,						/* tp_compare */
+    0,                                          /* tp_repr */
+    0,                                          /* tp_as_number */
+    0,						/* tp_as_sequence */
+    0,						/* tp_as_mapping */
+    0,                                          /* tp_hash */
+    0,              				/* tp_call */
+    0,          				/* tp_str */
+    0,                                          /* tp_getattro */
+    0,						/* tp_setattro */
+    0,						/* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT,                         /* tp_flags */
+    0,      					/* tp_doc */
+    0,						/* tp_traverse */
+    0,						/* tp_clear */
+    0,                                          /* tp_richcompare */
+    0,						/* tp_weaklistoffset */
+    0,						/* tp_iter */
+    0,						/* tp_iternext */
+    0,      					/* tp_methods */
+    helper_members,                             /* tp_members */
+    helper_getset,                              /* tp_getset */
+    0,						/* tp_base */
+    0,						/* tp_dict */
+    0,						/* tp_descr_get */
+    0,						/* tp_descr_set */
+    0,						/* tp_dictoffset */
+    0,						/* tp_init */
+    0,						/* tp_alloc */
+    0,                                          /* tp_new */
+    0,						/* tp_free */
+};
+
+PyMODINIT_FUNC
+init_types(void)
+{
+    PyObject *m;
+
+    m = Py_InitModule3("_types", NULL, "A types module helper");
+    if (!m)
+        return;
+
+    if (PyType_Ready(&HelperType) < 0)
+        return;
+
+    Py_INCREF(&HelperType);
+    PyModule_AddObject(m, "Helper", (PyObject *)&HelperType);
+}
+
+    

Added: vendor/Python/current/Modules/_weakref.c
===================================================================
--- vendor/Python/current/Modules/_weakref.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/_weakref.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,112 @@
+#include "Python.h"
+
+
+#define GET_WEAKREFS_LISTPTR(o) \
+        ((PyWeakReference **) PyObject_GET_WEAKREFS_LISTPTR(o))
+
+
+PyDoc_STRVAR(weakref_getweakrefcount__doc__,
+"getweakrefcount(object) -- return the number of weak references\n"
+"to 'object'.");
+
+static PyObject *
+weakref_getweakrefcount(PyObject *self, PyObject *object)
+{
+    PyObject *result = NULL;
+
+    if (PyType_SUPPORTS_WEAKREFS(object->ob_type)) {
+        PyWeakReference **list = GET_WEAKREFS_LISTPTR(object);
+
+        result = PyInt_FromSsize_t(_PyWeakref_GetWeakrefCount(*list));
+    }
+    else
+        result = PyInt_FromLong(0);
+
+    return result;
+}
+
+
+PyDoc_STRVAR(weakref_getweakrefs__doc__,
+"getweakrefs(object) -- return a list of all weak reference objects\n"
+"that point to 'object'.");
+
+static PyObject *
+weakref_getweakrefs(PyObject *self, PyObject *object)
+{
+    PyObject *result = NULL;
+
+    if (PyType_SUPPORTS_WEAKREFS(object->ob_type)) {
+        PyWeakReference **list = GET_WEAKREFS_LISTPTR(object);
+        Py_ssize_t count = _PyWeakref_GetWeakrefCount(*list);
+
+        result = PyList_New(count);
+        if (result != NULL) {
+            PyWeakReference *current = *list;
+            Py_ssize_t i;
+            for (i = 0; i < count; ++i) {
+                PyList_SET_ITEM(result, i, (PyObject *) current);
+                Py_INCREF(current);
+                current = current->wr_next;
+            }
+        }
+    }
+    else {
+        result = PyList_New(0);
+    }
+    return result;
+}
+
+
+PyDoc_STRVAR(weakref_proxy__doc__,
+"proxy(object[, callback]) -- create a proxy object that weakly\n"
+"references 'object'.  'callback', if given, is called with a\n"
+"reference to the proxy when 'object' is about to be finalized.");
+
+static PyObject *
+weakref_proxy(PyObject *self, PyObject *args)
+{
+    PyObject *object;
+    PyObject *callback = NULL;
+    PyObject *result = NULL;
+
+    if (PyArg_UnpackTuple(args, "proxy", 1, 2, &object, &callback)) {
+        result = PyWeakref_NewProxy(object, callback);
+    }
+    return result;
+}
+
+
+static PyMethodDef
+weakref_functions[] =  {
+    {"getweakrefcount", weakref_getweakrefcount,        METH_O,
+     weakref_getweakrefcount__doc__},
+    {"getweakrefs",     weakref_getweakrefs,            METH_O,
+     weakref_getweakrefs__doc__},
+    {"proxy",           weakref_proxy,                  METH_VARARGS,
+     weakref_proxy__doc__},
+    {NULL, NULL, 0, NULL}
+};
+
+
+PyMODINIT_FUNC
+init_weakref(void)
+{
+    PyObject *m;
+
+    m = Py_InitModule3("_weakref", weakref_functions,
+                       "Weak-reference support module.");
+    if (m != NULL) {
+        Py_INCREF(&_PyWeakref_RefType);
+        PyModule_AddObject(m, "ref",
+                           (PyObject *) &_PyWeakref_RefType);
+        Py_INCREF(&_PyWeakref_RefType);
+        PyModule_AddObject(m, "ReferenceType",
+                           (PyObject *) &_PyWeakref_RefType);
+        Py_INCREF(&_PyWeakref_ProxyType);
+        PyModule_AddObject(m, "ProxyType",
+                           (PyObject *) &_PyWeakref_ProxyType);
+        Py_INCREF(&_PyWeakref_CallableProxyType);
+        PyModule_AddObject(m, "CallableProxyType",
+                           (PyObject *) &_PyWeakref_CallableProxyType);
+    }
+}

Added: vendor/Python/current/Modules/addrinfo.h
===================================================================
--- vendor/Python/current/Modules/addrinfo.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/addrinfo.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef HAVE_GETADDRINFO
+
+/*
+ * Error return codes from getaddrinfo()
+ */
+#ifdef EAI_ADDRFAMILY
+/* If this is defined, there is a conflicting implementation
+   in the C library, which can't be used for some reason.
+   Make sure it won't interfere with this emulation. */
+
+#undef EAI_ADDRFAMILY
+#undef EAI_AGAIN
+#undef EAI_BADFLAGS
+#undef EAI_FAIL
+#undef EAI_FAMILY
+#undef EAI_MEMORY
+#undef EAI_NODATA
+#undef EAI_NONAME
+#undef EAI_SERVICE
+#undef EAI_SOCKTYPE
+#undef EAI_SYSTEM
+#undef EAI_BADHINTS
+#undef EAI_PROTOCOL
+#undef EAI_MAX
+#undef getaddrinfo
+#define getaddrinfo fake_getaddrinfo
+#endif /* EAI_ADDRFAMILY */
+
+#define	EAI_ADDRFAMILY	 1	/* address family for hostname not supported */
+#define	EAI_AGAIN	 2	/* temporary failure in name resolution */
+#define	EAI_BADFLAGS	 3	/* invalid value for ai_flags */
+#define	EAI_FAIL	 4	/* non-recoverable failure in name resolution */
+#define	EAI_FAMILY	 5	/* ai_family not supported */
+#define	EAI_MEMORY	 6	/* memory allocation failure */
+#define	EAI_NODATA	 7	/* no address associated with hostname */
+#define	EAI_NONAME	 8	/* hostname nor servname provided, or not known */
+#define	EAI_SERVICE	 9	/* servname not supported for ai_socktype */
+#define	EAI_SOCKTYPE	10	/* ai_socktype not supported */
+#define	EAI_SYSTEM	11	/* system error returned in errno */
+#define EAI_BADHINTS	12
+#define EAI_PROTOCOL	13
+#define EAI_MAX		14
+
+/*
+ * Flag values for getaddrinfo()
+ */
+#ifdef AI_PASSIVE
+#undef AI_PASSIVE
+#undef AI_CANONNAME
+#undef AI_NUMERICHOST
+#undef AI_MASK
+#undef AI_ALL
+#undef AI_V4MAPPED_CFG
+#undef AI_ADDRCONFIG
+#undef AI_V4MAPPED
+#undef AI_DEFAULT
+#endif /* AI_PASSIVE */
+
+#define	AI_PASSIVE	0x00000001 /* get address to use bind() */
+#define	AI_CANONNAME	0x00000002 /* fill ai_canonname */
+#define	AI_NUMERICHOST	0x00000004 /* prevent name resolution */
+/* valid flags for addrinfo */
+#define	AI_MASK		(AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST)
+
+#define	AI_ALL		0x00000100 /* IPv6 and IPv4-mapped (with AI_V4MAPPED) */
+#define	AI_V4MAPPED_CFG	0x00000200 /* accept IPv4-mapped if kernel supports */
+#define	AI_ADDRCONFIG	0x00000400 /* only if any address is assigned */
+#define	AI_V4MAPPED	0x00000800 /* accept IPv4-mapped IPv6 address */
+/* special recommended flags for getipnodebyname */
+#define	AI_DEFAULT	(AI_V4MAPPED_CFG | AI_ADDRCONFIG)
+
+#endif /* !HAVE_GETADDRINFO */
+
+#ifndef HAVE_GETNAMEINFO
+
+/*
+ * Constants for getnameinfo()
+ */
+#ifndef NI_MAXHOST
+#define	NI_MAXHOST	1025
+#define	NI_MAXSERV	32
+#endif /* !NI_MAXHOST */
+
+/*
+ * Flag values for getnameinfo()
+ */
+#ifndef NI_NOFQDN
+#define	NI_NOFQDN	0x00000001
+#define	NI_NUMERICHOST	0x00000002
+#define	NI_NAMEREQD	0x00000004
+#define	NI_NUMERICSERV	0x00000008
+#define	NI_DGRAM	0x00000010
+#endif /* !NI_NOFQDN */
+
+#endif /* !HAVE_GETNAMEINFO */
+
+#ifndef HAVE_ADDRINFO
+struct addrinfo {
+	int	ai_flags;	/* AI_PASSIVE, AI_CANONNAME */
+	int	ai_family;	/* PF_xxx */
+	int	ai_socktype;	/* SOCK_xxx */
+	int	ai_protocol;	/* 0 or IPPROTO_xxx for IPv4 and IPv6 */
+	size_t	ai_addrlen;	/* length of ai_addr */
+	char	*ai_canonname;	/* canonical name for hostname */
+	struct sockaddr *ai_addr;	/* binary address */
+	struct addrinfo *ai_next;	/* next structure in linked list */
+};
+#endif /* !HAVE_ADDRINFO */
+
+#ifndef HAVE_SOCKADDR_STORAGE
+/*
+ * RFC 2553: protocol-independent placeholder for socket addresses
+ */
+#define _SS_MAXSIZE	128
+#ifdef HAVE_LONG_LONG
+#define _SS_ALIGNSIZE	(sizeof(PY_LONG_LONG))
+#else
+#define _SS_ALIGNSIZE	(sizeof(double))
+#endif /* HAVE_LONG_LONG */
+#define _SS_PAD1SIZE	(_SS_ALIGNSIZE - sizeof(u_char) * 2)
+#define _SS_PAD2SIZE	(_SS_MAXSIZE - sizeof(u_char) * 2 - \
+				_SS_PAD1SIZE - _SS_ALIGNSIZE)
+
+struct sockaddr_storage {
+#ifdef HAVE_SOCKADDR_SA_LEN
+	unsigned char ss_len;		/* address length */
+	unsigned char ss_family;	/* address family */
+#else
+	unsigned short ss_family;	/* address family */
+#endif /* HAVE_SOCKADDR_SA_LEN */
+	char	__ss_pad1[_SS_PAD1SIZE];
+#ifdef HAVE_LONG_LONG
+	PY_LONG_LONG __ss_align;	/* force desired structure storage alignment */
+#else
+	double __ss_align;	/* force desired structure storage alignment */
+#endif /* HAVE_LONG_LONG */
+	char	__ss_pad2[_SS_PAD2SIZE];
+};
+#endif /* !HAVE_SOCKADDR_STORAGE */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern void freehostent Py_PROTO((struct hostent *));
+#ifdef __cplusplus
+}
+#endif

Added: vendor/Python/current/Modules/almodule.c
===================================================================
--- vendor/Python/current/Modules/almodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/almodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,3226 @@
+
+#define OLD_INTERFACE		/* define for pre-Irix 6 interface */
+
+#include "Python.h"
+#include "stringobject.h"
+#include <audio.h>
+#include <stdarg.h>
+
+#ifndef AL_NO_ELEM
+#ifndef OLD_INTERFACE
+#define OLD_INTERFACE
+#endif /* OLD_INTERFACE */
+#endif /* AL_NO_ELEM */
+
+static PyObject *ErrorObject;
+
+/* ----------------------------------------------------- */
+
+/* Declarations for objects of type port */
+
+typedef struct {
+	PyObject_HEAD
+	/* XXXX Add your own stuff here */
+	ALport port;
+} alpobject;
+
+static PyTypeObject Alptype;
+
+
+
+/* ---------------------------------------------------------------- */
+
+/* Declarations for objects of type config */
+
+typedef struct {
+	PyObject_HEAD
+	/* XXXX Add your own stuff here */
+	ALconfig config;
+} alcobject;
+
+static PyTypeObject Alctype;
+
+
+static void
+ErrorHandler(long code, const char *fmt, ...)
+{
+	va_list args;
+	char buf[128];
+
+	va_start(args, fmt);
+	vsprintf(buf, fmt, args);
+	va_end(args);
+	PyErr_SetString(ErrorObject, buf);
+}
+
+#ifdef AL_NO_ELEM		/* IRIX 6 */
+
+static PyObject *
+param2python(int resource, int param, ALvalue value, ALparamInfo *pinfo)
+{
+	ALparamInfo info;
+
+	if (pinfo == NULL) {
+		pinfo = &info;
+		if (alGetParamInfo(resource, param, &info) < 0)
+			return NULL;
+	}
+	switch (pinfo->elementType) {
+	case AL_PTR_ELEM:
+		/* XXXX don't know how to handle this */
+	case AL_NO_ELEM:
+		Py_INCREF(Py_None);
+		return Py_None;
+	case AL_INT32_ELEM:
+	case AL_RESOURCE_ELEM:
+	case AL_ENUM_ELEM:
+		return PyInt_FromLong((long) value.i);
+	case AL_INT64_ELEM:
+		return PyLong_FromLongLong(value.ll);
+	case AL_FIXED_ELEM:
+		return PyFloat_FromDouble(alFixedToDouble(value.ll));
+	case AL_CHAR_ELEM:
+		if (value.ptr == NULL) {
+			Py_INCREF(Py_None);
+			return Py_None;
+		}
+		return PyString_FromString((char *) value.ptr);
+	default:
+		PyErr_SetString(ErrorObject, "unknown element type");
+		return NULL;
+	}
+}
+
+static int
+python2elem(PyObject *item, void *ptr, int elementType)
+{
+	switch (elementType) {
+	case AL_INT32_ELEM:
+	case AL_RESOURCE_ELEM:
+	case AL_ENUM_ELEM:
+		if (!PyInt_Check(item)) {
+			PyErr_BadArgument();
+			return -1;
+		}
+		*((int *) ptr) = PyInt_AsLong(item);
+		break;
+	case AL_INT64_ELEM:
+		if (PyInt_Check(item))
+			*((long long *) ptr) = PyInt_AsLong(item);
+		else if (PyLong_Check(item))
+			*((long long *) ptr) = PyLong_AsLongLong(item);
+		else {
+			PyErr_BadArgument();
+			return -1;
+		}
+		break;
+	case AL_FIXED_ELEM:
+		if (PyInt_Check(item))
+			*((long long *) ptr) = alDoubleToFixed((double) PyInt_AsLong(item));
+		else if (PyFloat_Check(item))
+			*((long long *) ptr) = alDoubleToFixed(PyFloat_AsDouble(item));
+		else {
+			PyErr_BadArgument();
+			return -1;
+		}
+		break;
+	default:
+		PyErr_SetString(ErrorObject, "unknown element type");
+		return -1;
+	}
+	return 0;
+}
+
+static int
+python2param(int resource, ALpv *param, PyObject *value, ALparamInfo *pinfo)
+{
+	ALparamInfo info;
+	int i, stepsize;
+	PyObject *item;
+
+	if (pinfo == NULL) {
+		pinfo = &info;
+		if (alGetParamInfo(resource, param->param, &info) < 0)
+			return -1;
+	}
+	switch (pinfo->valueType) {
+	case AL_STRING_VAL:
+		if (pinfo->elementType != AL_CHAR_ELEM) {
+			PyErr_SetString(ErrorObject, "unknown element type");
+			return -1;
+		}
+		if (!PyString_Check(value)) {
+			PyErr_BadArgument();
+			return -1;
+		}
+		param->value.ptr = PyString_AS_STRING(value);
+		param->sizeIn = PyString_GET_SIZE(value)+1; /*account for NUL*/
+		break;
+	case AL_SET_VAL:
+	case AL_VECTOR_VAL:
+		if (!PyList_Check(value) && !PyTuple_Check(value)) {
+			PyErr_BadArgument();
+			return -1;
+		}
+		switch (pinfo->elementType) {
+		case AL_INT32_ELEM:
+		case AL_RESOURCE_ELEM:
+		case AL_ENUM_ELEM:
+			param->sizeIn = PySequence_Size(value);
+			param->value.ptr = PyMem_NEW(int, param->sizeIn);
+			stepsize = sizeof(int);
+			break;
+		case AL_INT64_ELEM:
+		case AL_FIXED_ELEM:
+			param->sizeIn = PySequence_Size(value);
+			param->value.ptr = PyMem_NEW(long long, param->sizeIn);
+			stepsize = sizeof(long long);
+			break;
+		}
+		for (i = 0; i < param->sizeIn; i++) {
+			item = PySequence_GetItem(value, i);
+			if (python2elem(item, (void *) ((char *) param->value.ptr + i*stepsize), pinfo->elementType) < 0) {
+				PyMem_DEL(param->value.ptr);
+				return -1;
+			}
+		}
+		break;
+	case AL_SCALAR_VAL:
+		switch (pinfo->elementType) {
+		case AL_INT32_ELEM:
+		case AL_RESOURCE_ELEM:
+		case AL_ENUM_ELEM:
+			return python2elem(value, (void *) &param->value.i,
+					   pinfo->elementType);
+		case AL_INT64_ELEM:
+		case AL_FIXED_ELEM:
+			return python2elem(value, (void *) &param->value.ll,
+					   pinfo->elementType);
+		default:
+			PyErr_SetString(ErrorObject, "unknown element type");
+			return -1;
+		}
+	}
+	return 0;
+}
+
+static int
+python2params(int resource1, int resource2, PyObject *list, ALpv **pvsp, ALparamInfo **pinfop)
+{
+	PyObject *item;
+	ALpv *pvs;
+	ALparamInfo *pinfo;
+	int npvs, i;
+
+	npvs = PyList_Size(list);
+	pvs = PyMem_NEW(ALpv, npvs);
+	pinfo = PyMem_NEW(ALparamInfo, npvs);
+	for (i = 0; i < npvs; i++) {
+		item = PyList_GetItem(list, i);
+		if (!PyArg_ParseTuple(item, "iO", &pvs[i].param, &item))
+			goto error;
+		if (alGetParamInfo(resource1, pvs[i].param, &pinfo[i]) < 0 &&
+		    alGetParamInfo(resource2, pvs[i].param, &pinfo[i]) < 0)
+			goto error;
+		if (python2param(resource1, &pvs[i], item, &pinfo[i]) < 0)
+			goto error;
+	}
+
+	*pvsp = pvs;
+	*pinfop = pinfo;
+	return npvs;
+
+  error:
+	/* XXXX we should clean up everything */
+	if (pvs)
+		PyMem_DEL(pvs);
+	if (pinfo)
+		PyMem_DEL(pinfo);
+	return -1;
+}
+
+/* -------------------------------------------------------- */
+
+
+static PyObject *
+SetConfig(alcobject *self, PyObject *args, int (*func)(ALconfig, int))
+{
+	int par;
+
+	if (!PyArg_ParseTuple(args, "i:SetConfig", &par))
+		return NULL;
+
+	if ((*func)(self->config, par) == -1)
+		return NULL;
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+GetConfig(alcobject *self, PyObject *args, int (*func)(ALconfig))
+{	
+	int par;
+
+	if (!PyArg_ParseTuple(args, ":GetConfig"))
+		return NULL;
+	
+	if ((par = (*func)(self->config)) == -1)
+		return NULL;
+
+	return PyInt_FromLong((long) par);
+}
+
+PyDoc_STRVAR(alc_SetWidth__doc__,
+"alSetWidth: set the wordsize for integer audio data.");
+
+static PyObject *
+alc_SetWidth(alcobject *self, PyObject *args)
+{
+	return SetConfig(self, args, alSetWidth);
+}
+
+
+PyDoc_STRVAR(alc_GetWidth__doc__,
+"alGetWidth: get the wordsize for integer audio data.");
+
+static PyObject *
+alc_GetWidth(alcobject *self, PyObject *args)
+{
+	return GetConfig(self, args, alGetWidth);
+}
+
+
+PyDoc_STRVAR(alc_SetSampFmt__doc__,
+"alSetSampFmt: set the sample format setting in an audio ALconfig "
+"structure.");
+
+static PyObject *
+alc_SetSampFmt(alcobject *self, PyObject *args)
+{
+	return SetConfig(self, args, alSetSampFmt);
+}
+
+
+PyDoc_STRVAR(alc_GetSampFmt__doc__,
+"alGetSampFmt: get the sample format setting in an audio ALconfig "
+"structure.");
+
+static PyObject *
+alc_GetSampFmt(alcobject *self, PyObject *args)
+{
+	return GetConfig(self, args, alGetSampFmt);
+}
+
+
+PyDoc_STRVAR(alc_SetChannels__doc__,
+"alSetChannels: set the channel settings in an audio ALconfig.");
+
+static PyObject *
+alc_SetChannels(alcobject *self, PyObject *args)
+{
+	return SetConfig(self, args, alSetChannels);
+}
+
+
+PyDoc_STRVAR(alc_GetChannels__doc__,
+"alGetChannels: get the channel settings in an audio ALconfig.");
+
+static PyObject *
+alc_GetChannels(alcobject *self, PyObject *args)
+{
+	return GetConfig(self, args, alGetChannels);
+}
+
+
+PyDoc_STRVAR(alc_SetFloatMax__doc__,
+"alSetFloatMax: set the maximum value of floating point sample data.");
+
+static PyObject *
+alc_SetFloatMax(alcobject *self, PyObject *args)
+{
+	double maximum_value;
+
+	if (!PyArg_ParseTuple(args, "d:SetFloatMax", &maximum_value))
+		return NULL;
+	if (alSetFloatMax(self->config, maximum_value) < 0)
+		return NULL;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+
+PyDoc_STRVAR(alc_GetFloatMax__doc__,
+"alGetFloatMax: get the maximum value of floating point sample data.");
+
+static PyObject *
+alc_GetFloatMax(alcobject *self, PyObject *args)
+{
+	double maximum_value;
+
+	if (!PyArg_ParseTuple(args, ":GetFloatMax"))
+		return NULL;
+	if ((maximum_value = alGetFloatMax(self->config)) == 0)
+		return NULL;
+	return PyFloat_FromDouble(maximum_value);
+}
+
+
+PyDoc_STRVAR(alc_SetDevice__doc__,
+"alSetDevice: set the device setting in an audio ALconfig structure.");
+
+static PyObject *
+alc_SetDevice(alcobject *self, PyObject *args)
+{
+	return SetConfig(self, args, alSetDevice);
+}
+
+
+PyDoc_STRVAR(alc_GetDevice__doc__,
+"alGetDevice: get the device setting in an audio ALconfig structure.");
+
+static PyObject *
+alc_GetDevice(alcobject *self, PyObject *args)
+{
+	return GetConfig(self, args, alGetDevice);
+}
+
+
+PyDoc_STRVAR(alc_SetQueueSize__doc__,
+"alSetQueueSize: set audio port buffer size.");
+
+static PyObject *
+alc_SetQueueSize(alcobject *self, PyObject *args)
+{
+	return SetConfig(self, args, alSetQueueSize);
+}
+
+
+PyDoc_STRVAR(alc_GetQueueSize__doc__,
+"alGetQueueSize: get audio port buffer size.");
+
+static PyObject *
+alc_GetQueueSize(alcobject *self, PyObject *args)
+{
+	return GetConfig(self, args, alGetQueueSize);
+}
+
+#endif /* AL_NO_ELEM */
+
+static PyObject *
+setconfig(alcobject *self, PyObject *args, int (*func)(ALconfig, long))
+{
+	long par;
+
+	if (!PyArg_ParseTuple(args, "l:SetConfig", &par))
+		return NULL;
+
+	if ((*func)(self->config, par) == -1)
+		return NULL;
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+getconfig(alcobject *self, PyObject *args, long (*func)(ALconfig))
+{	
+	long par;
+
+	if (!PyArg_ParseTuple(args, ":GetConfig"))
+		return NULL;
+	
+	if ((par = (*func)(self->config)) == -1)
+		return NULL;
+
+	return PyInt_FromLong((long) par);
+}
+
+static PyObject *
+alc_setqueuesize (alcobject *self, PyObject *args)
+{
+	return setconfig(self, args, ALsetqueuesize);
+}
+
+static PyObject *
+alc_getqueuesize (alcobject *self, PyObject *args)
+{
+	return getconfig(self, args, ALgetqueuesize);
+}
+
+static PyObject *
+alc_setwidth (alcobject *self, PyObject *args)
+{
+	return setconfig(self, args, ALsetwidth);
+}
+
+static PyObject *
+alc_getwidth (alcobject *self, PyObject *args)
+{
+	return getconfig(self, args, ALgetwidth);	
+}
+
+static PyObject *
+alc_getchannels (alcobject *self, PyObject *args)
+{
+	return getconfig(self, args, ALgetchannels);	
+}
+
+static PyObject *
+alc_setchannels (alcobject *self, PyObject *args)
+{
+	return setconfig(self, args, ALsetchannels);
+}
+
+#ifdef AL_405
+
+static PyObject *
+alc_getsampfmt (alcobject *self, PyObject *args)
+{
+	return getconfig(self, args, ALgetsampfmt);	
+}
+
+static PyObject *
+alc_setsampfmt (alcobject *self, PyObject *args)
+{
+	return setconfig(self, args, ALsetsampfmt);
+}
+
+static PyObject *
+alc_getfloatmax(alcobject *self, PyObject *args)
+{
+	double arg;
+
+	if (!PyArg_ParseTuple(args, ":GetFloatMax"))
+		return 0;
+	if ((arg = ALgetfloatmax(self->config)) == 0)
+		return NULL;
+	return PyFloat_FromDouble(arg);
+}
+
+static PyObject *
+alc_setfloatmax(alcobject *self, PyObject *args)
+{
+	double arg;
+
+	if (!PyArg_ParseTuple(args, "d:SetFloatMax", &arg))
+		return 0;
+	if (ALsetfloatmax(self->config, arg) == -1)
+		return NULL;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+#endif /* AL_405 */
+	
+static struct PyMethodDef alc_methods[] = {
+#ifdef AL_NO_ELEM		/* IRIX 6 */
+	{"SetWidth",	(PyCFunction)alc_SetWidth,	METH_VARARGS,	alc_SetWidth__doc__},
+	{"GetWidth",	(PyCFunction)alc_GetWidth,	METH_VARARGS,	alc_GetWidth__doc__},
+	{"SetSampFmt",	(PyCFunction)alc_SetSampFmt,	METH_VARARGS,	alc_SetSampFmt__doc__},
+	{"GetSampFmt",	(PyCFunction)alc_GetSampFmt,	METH_VARARGS,	alc_GetSampFmt__doc__},
+	{"SetChannels",	(PyCFunction)alc_SetChannels,	METH_VARARGS,	alc_SetChannels__doc__},
+	{"GetChannels",	(PyCFunction)alc_GetChannels,	METH_VARARGS,	alc_GetChannels__doc__},
+	{"SetFloatMax",	(PyCFunction)alc_SetFloatMax,	METH_VARARGS,	alc_SetFloatMax__doc__},
+	{"GetFloatMax",	(PyCFunction)alc_GetFloatMax,	METH_VARARGS,	alc_GetFloatMax__doc__},
+	{"SetDevice",	(PyCFunction)alc_SetDevice,	METH_VARARGS,	alc_SetDevice__doc__},
+	{"GetDevice",	(PyCFunction)alc_GetDevice,	METH_VARARGS,	alc_GetDevice__doc__},
+	{"SetQueueSize",	(PyCFunction)alc_SetQueueSize,	METH_VARARGS,	alc_SetQueueSize__doc__},
+	{"GetQueueSize",	(PyCFunction)alc_GetQueueSize,	METH_VARARGS,	alc_GetQueueSize__doc__},
+#endif /* AL_NO_ELEM */
+	{"getqueuesize",	(PyCFunction)alc_getqueuesize,	METH_VARARGS},
+	{"setqueuesize",	(PyCFunction)alc_setqueuesize,	METH_VARARGS},
+	{"getwidth",		(PyCFunction)alc_getwidth,	METH_VARARGS},
+	{"setwidth",		(PyCFunction)alc_setwidth,	METH_VARARGS},
+	{"getchannels",		(PyCFunction)alc_getchannels,	METH_VARARGS},
+	{"setchannels",		(PyCFunction)alc_setchannels,	METH_VARARGS},
+#ifdef AL_405
+	{"getsampfmt",		(PyCFunction)alc_getsampfmt,	METH_VARARGS},
+	{"setsampfmt",		(PyCFunction)alc_setsampfmt,	METH_VARARGS},
+	{"getfloatmax",		(PyCFunction)alc_getfloatmax,	METH_VARARGS},
+	{"setfloatmax",		(PyCFunction)alc_setfloatmax,	METH_VARARGS},
+#endif /* AL_405 */
+
+	{NULL,		NULL}		/* sentinel */
+};
+
+/* ---------- */
+
+
+static PyObject *
+newalcobject(ALconfig config)
+{
+	alcobject *self;
+	
+	self = PyObject_New(alcobject, &Alctype);
+	if (self == NULL)
+		return NULL;
+	/* XXXX Add your own initializers here */
+	self->config = config;
+	return (PyObject *) self;
+}
+
+
+static void
+alc_dealloc(alcobject *self)
+{
+	/* XXXX Add your own cleanup code here */
+#ifdef AL_NO_ELEM		/* IRIX 6 */
+	(void) alFreeConfig(self->config);	/* ignore errors */
+#else
+	(void) ALfreeconfig(self->config);	/* ignore errors */
+#endif
+	PyObject_Del(self);
+}
+
+static PyObject *
+alc_getattr(alcobject *self, char *name)
+{
+	/* XXXX Add your own getattr code here */
+	return Py_FindMethod(alc_methods, (PyObject *)self, name);
+}
+
+PyDoc_STRVAR(Alctype__doc__, "");
+
+static PyTypeObject Alctype = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,				/*ob_size*/
+	"al.config",			/*tp_name*/
+	sizeof(alcobject),		/*tp_basicsize*/
+	0,				/*tp_itemsize*/
+	/* methods */
+	(destructor)alc_dealloc,	/*tp_dealloc*/
+	(printfunc)0,		/*tp_print*/
+	(getattrfunc)alc_getattr,	/*tp_getattr*/
+	(setattrfunc)0,	/*tp_setattr*/
+	(cmpfunc)0,		/*tp_compare*/
+	(reprfunc)0,		/*tp_repr*/
+	0,			/*tp_as_number*/
+	0,		/*tp_as_sequence*/
+	0,		/*tp_as_mapping*/
+	(hashfunc)0,		/*tp_hash*/
+	(ternaryfunc)0,		/*tp_call*/
+	(reprfunc)0,		/*tp_str*/
+
+	/* Space for future expansion */
+	0L,0L,0L,0L,
+	Alctype__doc__ /* Documentation string */
+};
+
+/* End of code for config objects */
+/* ---------------------------------------------------------------- */
+
+#ifdef AL_NO_ELEM		/* IRIX 6 */
+
+PyDoc_STRVAR(alp_SetConfig__doc__,
+"alSetConfig: set the ALconfig of an audio ALport.");
+
+static PyObject *
+alp_SetConfig(alpobject *self, PyObject *args)
+{
+	alcobject *config;
+	if (!PyArg_ParseTuple(args, "O!:SetConfig", &Alctype, &config))
+		return NULL;
+	if (alSetConfig(self->port, config->config) < 0)
+		return NULL;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+
+PyDoc_STRVAR(alp_GetConfig__doc__,
+"alGetConfig: get the ALconfig of an audio ALport.");
+
+static PyObject *
+alp_GetConfig(alpobject *self, PyObject *args)
+{
+	ALconfig config;
+	if (!PyArg_ParseTuple(args, ":GetConfig"))
+		return NULL;
+	if ((config = alGetConfig(self->port)) == NULL)
+		return NULL;
+	return newalcobject(config);
+}
+
+
+PyDoc_STRVAR(alp_GetResource__doc__,
+"alGetResource: get the resource associated with an audio port.");
+
+static PyObject *
+alp_GetResource(alpobject *self, PyObject *args)
+{
+	int resource;
+
+	if (!PyArg_ParseTuple(args, ":GetResource"))
+		return NULL;
+	if ((resource = alGetResource(self->port)) == 0)
+		return NULL;
+	return PyInt_FromLong((long) resource);
+}
+
+
+PyDoc_STRVAR(alp_GetFD__doc__,
+"alGetFD: get the file descriptor for an audio port.");
+
+static PyObject *
+alp_GetFD(alpobject *self, PyObject *args)
+{
+	int fd;
+
+	if (!PyArg_ParseTuple(args, ":GetFD"))
+		return NULL;
+
+	if ((fd = alGetFD(self->port)) < 0)
+		return NULL;
+
+	return PyInt_FromLong((long) fd);
+}
+
+
+PyDoc_STRVAR(alp_GetFilled__doc__,
+"alGetFilled: return the number of filled sample frames in "
+"an audio port.");
+
+static PyObject *
+alp_GetFilled(alpobject *self, PyObject *args)
+{
+	int filled;
+
+	if (!PyArg_ParseTuple(args, ":GetFilled"))
+		return NULL;
+	if ((filled = alGetFilled(self->port)) < 0)
+		return NULL;
+	return PyInt_FromLong((long) filled);
+}
+
+
+PyDoc_STRVAR(alp_GetFillable__doc__,
+"alGetFillable: report the number of unfilled sample frames "
+"in an audio port.");
+
+static PyObject *
+alp_GetFillable(alpobject *self, PyObject *args)
+{
+	int fillable;
+
+	if (!PyArg_ParseTuple(args, ":GetFillable"))
+		return NULL;
+	if ((fillable = alGetFillable(self->port)) < 0)
+		return NULL;
+	return PyInt_FromLong((long) fillable);
+}
+
+
+PyDoc_STRVAR(alp_ReadFrames__doc__,
+"alReadFrames: read sample frames from an audio port.");
+
+static PyObject *
+alp_ReadFrames(alpobject *self, PyObject *args)
+{
+	int framecount;
+	PyObject *v;
+	int size;
+	int ch;
+	ALconfig c;
+
+	if (!PyArg_ParseTuple(args, "i:ReadFrames", &framecount))
+		return NULL;
+	if (framecount < 0) {
+		PyErr_SetString(ErrorObject, "negative framecount");
+		return NULL;
+	}
+	c = alGetConfig(self->port);
+	switch (alGetSampFmt(c)) {
+	case AL_SAMPFMT_TWOSCOMP:
+		switch (alGetWidth(c)) {
+		case AL_SAMPLE_8:
+			size = 1;
+			break;
+		case AL_SAMPLE_16:
+			size = 2;
+			break;
+		case AL_SAMPLE_24:
+			size = 4;
+			break;
+		default:
+			PyErr_SetString(ErrorObject, "can't determine width");
+			alFreeConfig(c);
+			return NULL;
+		}
+		break;
+	case AL_SAMPFMT_FLOAT:
+		size = 4;
+		break;
+	case AL_SAMPFMT_DOUBLE:
+		size = 8;
+		break;
+	default:
+		PyErr_SetString(ErrorObject, "can't determine format");
+		alFreeConfig(c);
+		return NULL;
+	}
+	ch = alGetChannels(c);
+	alFreeConfig(c);
+	if (ch < 0) {
+		PyErr_SetString(ErrorObject, "can't determine # of channels");
+		return NULL;
+	}
+	size *= ch;
+	v = PyString_FromStringAndSize((char *) NULL, size * framecount);
+	if (v == NULL)
+		return NULL;
+
+	Py_BEGIN_ALLOW_THREADS
+	alReadFrames(self->port, (void *) PyString_AS_STRING(v), framecount);
+	Py_END_ALLOW_THREADS
+
+	return v;
+}
+
+
+PyDoc_STRVAR(alp_DiscardFrames__doc__,
+"alDiscardFrames: discard audio from an audio port.");
+
+static PyObject *
+alp_DiscardFrames(alpobject *self, PyObject *args)
+{
+	int framecount;
+
+	if (!PyArg_ParseTuple(args, "i:DiscardFrames", &framecount))
+		return NULL;
+
+	Py_BEGIN_ALLOW_THREADS
+	framecount = alDiscardFrames(self->port, framecount);
+	Py_END_ALLOW_THREADS
+
+	if (framecount < 0)
+		return NULL;
+
+	return PyInt_FromLong((long) framecount);
+}
+
+
+PyDoc_STRVAR(alp_ZeroFrames__doc__,
+"alZeroFrames: write zero-valued sample frames to an audio port.");
+
+static PyObject *
+alp_ZeroFrames(alpobject *self, PyObject *args)
+{
+	int framecount;
+
+	if (!PyArg_ParseTuple(args, "i:ZeroFrames", &framecount))
+		return NULL;
+
+	if (framecount < 0) {
+		PyErr_SetString(ErrorObject, "negative framecount");
+		return NULL;
+	}
+
+	Py_BEGIN_ALLOW_THREADS
+	alZeroFrames(self->port, framecount);
+	Py_END_ALLOW_THREADS
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+
+PyDoc_STRVAR(alp_SetFillPoint__doc__,
+"alSetFillPoint: set low- or high-water mark for an audio port.");
+
+static PyObject *
+alp_SetFillPoint(alpobject *self, PyObject *args)
+{
+	int fillpoint;
+
+	if (!PyArg_ParseTuple(args, "i:SetFillPoint", &fillpoint))
+		return NULL;
+
+	if (alSetFillPoint(self->port, fillpoint) < 0)
+		return NULL;
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+
+PyDoc_STRVAR(alp_GetFillPoint__doc__,
+"alGetFillPoint: get low- or high-water mark for an audio port.");
+
+static PyObject *
+alp_GetFillPoint(alpobject *self, PyObject *args)
+{
+	int fillpoint;
+
+	if (!PyArg_ParseTuple(args, ":GetFillPoint"))
+		return NULL;
+
+	if ((fillpoint = alGetFillPoint(self->port)) < 0)
+		return NULL;
+
+	return PyInt_FromLong((long) fillpoint);
+}
+
+
+PyDoc_STRVAR(alp_GetFrameNumber__doc__,
+"alGetFrameNumber: get the absolute sample frame number "
+"associated with a port.");
+
+static PyObject *
+alp_GetFrameNumber(alpobject *self, PyObject *args)
+{
+	stamp_t fnum;
+
+	if (!PyArg_ParseTuple(args, ":GetFrameNumber"))
+		return NULL;
+
+	if (alGetFrameNumber(self->port, &fnum) < 0)
+		return NULL;
+
+	return PyLong_FromLongLong((long long) fnum);
+}
+
+
+PyDoc_STRVAR(alp_GetFrameTime__doc__,
+"alGetFrameTime: get the time at which a sample frame came "
+"in or will go out.");
+
+static PyObject *
+alp_GetFrameTime(alpobject *self, PyObject *args)
+{
+	stamp_t fnum, time;
+	PyObject *ret, *v0, *v1;
+
+	if (!PyArg_ParseTuple(args, ":GetFrameTime"))
+		return NULL;
+	if (alGetFrameTime(self->port, &fnum, &time) < 0)
+		return NULL;
+	v0 = PyLong_FromLongLong((long long) fnum);
+	v1 = PyLong_FromLongLong((long long) time);
+	if (PyErr_Occurred()) {
+		Py_XDECREF(v0);
+		Py_XDECREF(v1);
+		return NULL;
+	}
+	ret = PyTuple_Pack(2, v0, v1);
+	Py_DECREF(v0);
+	Py_DECREF(v1);
+	return ret;
+}
+
+
+PyDoc_STRVAR(alp_WriteFrames__doc__,
+"alWriteFrames: write sample frames to an audio port.");
+
+static PyObject *
+alp_WriteFrames(alpobject *self, PyObject *args)
+{
+	char *samples;
+	int length;
+	int size, ch;
+	ALconfig c;
+
+	if (!PyArg_ParseTuple(args, "s#:WriteFrames", &samples, &length))
+		return NULL;
+	c = alGetConfig(self->port);
+	switch (alGetSampFmt(c)) {
+	case AL_SAMPFMT_TWOSCOMP:
+		switch (alGetWidth(c)) {
+		case AL_SAMPLE_8:
+			size = 1;
+			break;
+		case AL_SAMPLE_16:
+			size = 2;
+			break;
+		case AL_SAMPLE_24:
+			size = 4;
+			break;
+		default:
+			PyErr_SetString(ErrorObject, "can't determine width");
+			alFreeConfig(c);
+			return NULL;
+		}
+		break;
+	case AL_SAMPFMT_FLOAT:
+		size = 4;
+		break;
+	case AL_SAMPFMT_DOUBLE:
+		size = 8;
+		break;
+	default:
+		PyErr_SetString(ErrorObject, "can't determine format");
+		alFreeConfig(c);
+		return NULL;
+	}
+	ch = alGetChannels(c);
+	alFreeConfig(c);
+	if (ch < 0) {
+		PyErr_SetString(ErrorObject, "can't determine # of channels");
+		return NULL;
+	}
+	size *= ch;
+	if (length % size != 0) {
+		PyErr_SetString(ErrorObject,
+				"buffer length not whole number of frames");
+		return NULL;
+	}
+
+	Py_BEGIN_ALLOW_THREADS
+	alWriteFrames(self->port, (void *) samples, length / size);
+	Py_END_ALLOW_THREADS
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+
+PyDoc_STRVAR(alp_ClosePort__doc__, "alClosePort: close an audio port.");
+
+static PyObject *
+alp_ClosePort(alpobject *self, PyObject *args)
+{
+	if (!PyArg_ParseTuple(args, ":ClosePort"))
+		return NULL;
+	if (alClosePort(self->port) < 0)
+		return NULL;
+	self->port = NULL;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+#endif /* AL_NO_ELEM */
+
+#ifdef OLD_INTERFACE
+static PyObject *
+alp_closeport(alpobject *self, PyObject *args)
+{
+	if (!PyArg_ParseTuple(args, ":ClosePort"))
+		return NULL;
+	if (ALcloseport(self->port) < 0)
+		return NULL;
+	self->port = NULL;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+alp_getfd(alpobject *self, PyObject *args)
+{
+	int fd;
+
+	if (!PyArg_ParseTuple(args, ":GetFD"))
+		return NULL;
+	if ((fd = ALgetfd(self-> port)) == -1)
+		return NULL;
+	return PyInt_FromLong(fd);
+}
+
+static PyObject *
+alp_getfilled(alpobject *self, PyObject *args)
+{
+	long count;
+
+	if (!PyArg_ParseTuple(args, ":GetFilled"))
+		return NULL;
+	if ((count = ALgetfilled(self-> port)) == -1)
+		return NULL;
+	return PyInt_FromLong(count);
+}
+
+static PyObject *
+alp_getfillable(alpobject *self, PyObject *args)
+{
+	long count;
+
+	if (!PyArg_ParseTuple(args, ":GetFillable"))
+		return NULL;
+	if ((count = ALgetfillable(self-> port)) == -1)
+		return NULL;
+	return PyInt_FromLong (count);
+}
+
+static PyObject *
+alp_readsamps(alpobject *self, PyObject *args)
+{
+	long count;
+	PyObject *v;
+	ALconfig c;
+	int width;
+	int ret;
+
+	if (!PyArg_ParseTuple(args, "l:readsamps", &count))
+		return NULL;
+
+	if (count <= 0) {
+		PyErr_SetString(ErrorObject, "al.readsamps : arg <= 0");
+		return NULL;
+	}
+
+	c = ALgetconfig(self->port);
+#ifdef AL_405
+	width = ALgetsampfmt(c);
+	if (width == AL_SAMPFMT_FLOAT)
+		width = sizeof(float);
+	else if (width == AL_SAMPFMT_DOUBLE)
+		width = sizeof(double);
+	else
+		width = ALgetwidth(c);
+#else
+	width = ALgetwidth(c);
+#endif /* AL_405 */
+	ALfreeconfig(c);
+	v = PyString_FromStringAndSize((char *)NULL, width * count);
+	if (v == NULL)
+		return NULL;
+
+	Py_BEGIN_ALLOW_THREADS
+	ret = ALreadsamps(self->port, (void *) PyString_AsString(v), count);
+	Py_END_ALLOW_THREADS
+	if (ret == -1) {
+		Py_DECREF(v);
+		return NULL;
+	}
+
+	return (v);
+}
+
+static PyObject *
+alp_writesamps(alpobject *self, PyObject *args)
+{
+	char *buf;
+	int size, width;
+	ALconfig c;
+	int ret;
+
+	if (!PyArg_ParseTuple(args, "s#:writesamps", &buf, &size))
+		return NULL;
+
+	c = ALgetconfig(self->port);
+#ifdef AL_405
+	width = ALgetsampfmt(c);
+	if (width == AL_SAMPFMT_FLOAT)
+		width = sizeof(float);
+	else if (width == AL_SAMPFMT_DOUBLE)
+		width = sizeof(double);
+	else
+		width = ALgetwidth(c);
+#else
+	width = ALgetwidth(c);
+#endif /* AL_405 */
+	ALfreeconfig(c);
+	Py_BEGIN_ALLOW_THREADS
+	ret = ALwritesamps (self->port, (void *) buf, (long) size / width);
+	Py_END_ALLOW_THREADS
+	if (ret == -1)
+		return NULL;
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+alp_getfillpoint(alpobject *self, PyObject *args)
+{
+	long count;
+
+	if (!PyArg_ParseTuple(args, ":GetFillPoint"))
+		return NULL;
+	if ((count = ALgetfillpoint(self->port)) == -1)
+		return NULL;
+	return PyInt_FromLong(count);
+}
+
+static PyObject *
+alp_setfillpoint(alpobject *self, PyObject *args)
+{
+	long count;
+
+	if (!PyArg_ParseTuple(args, "l:SetFillPoint", &count))
+		return NULL;
+	if (ALsetfillpoint(self->port, count) == -1)
+		return NULL;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+alp_setconfig(alpobject *self, PyObject *args)
+{
+	alcobject *config;
+
+	if (!PyArg_ParseTuple(args, "O!:SetConfig", &Alctype, &config))
+		return NULL;
+	if (ALsetconfig(self->port, config->config) == -1)
+		return NULL;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+alp_getconfig(alpobject *self, PyObject *args)
+{
+	ALconfig config;
+
+	if (!PyArg_ParseTuple(args, ":GetConfig"))
+		return NULL;
+	config = ALgetconfig(self->port);
+	if (config == NULL)
+		return NULL;
+	return newalcobject(config);
+}
+
+#ifdef AL_405
+static PyObject *
+alp_getstatus(alpobject *self, PyObject *args)
+{
+	PyObject *list, *v;
+	long *PVbuffer;
+	long length;
+	int i;
+	
+	if (!PyArg_ParseTuple(args, "O!", &PyList_Type, &list))
+		return NULL;
+	length = PyList_Size(list);
+	PVbuffer = PyMem_NEW(long, length);
+	if (PVbuffer == NULL)
+		return PyErr_NoMemory();
+	for (i = 0; i < length; i++) {
+		v = PyList_GetItem(list, i);
+		if (!PyInt_Check(v)) {
+			PyMem_DEL(PVbuffer);
+			PyErr_BadArgument();
+			return NULL;
+		}
+		PVbuffer[i] = PyInt_AsLong(v);
+	}
+
+	if (ALgetstatus(self->port, PVbuffer, length) == -1)
+		return NULL;
+
+	for (i = 0; i < length; i++)
+		PyList_SetItem(list, i, PyInt_FromLong(PVbuffer[i]));
+
+	PyMem_DEL(PVbuffer);
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+#endif /* AL_405 */
+
+#endif /* OLD_INTERFACE */
+
+static struct PyMethodDef alp_methods[] = {
+#ifdef AL_NO_ELEM		/* IRIX 6 */
+	{"SetConfig",	(PyCFunction)alp_SetConfig,	METH_VARARGS,	alp_SetConfig__doc__},
+	{"GetConfig",	(PyCFunction)alp_GetConfig,	METH_VARARGS,	alp_GetConfig__doc__},
+	{"GetResource",	(PyCFunction)alp_GetResource,	METH_VARARGS,	alp_GetResource__doc__},
+	{"GetFD",	(PyCFunction)alp_GetFD,	METH_VARARGS,	alp_GetFD__doc__},
+	{"GetFilled",	(PyCFunction)alp_GetFilled,	METH_VARARGS,	alp_GetFilled__doc__},
+	{"GetFillable",	(PyCFunction)alp_GetFillable,	METH_VARARGS,	alp_GetFillable__doc__},
+	{"ReadFrames",	(PyCFunction)alp_ReadFrames,	METH_VARARGS,	alp_ReadFrames__doc__},
+	{"DiscardFrames",	(PyCFunction)alp_DiscardFrames,	METH_VARARGS,	alp_DiscardFrames__doc__},
+	{"ZeroFrames",	(PyCFunction)alp_ZeroFrames,	METH_VARARGS,	alp_ZeroFrames__doc__},
+	{"SetFillPoint",	(PyCFunction)alp_SetFillPoint,	METH_VARARGS,	alp_SetFillPoint__doc__},
+	{"GetFillPoint",	(PyCFunction)alp_GetFillPoint,	METH_VARARGS,	alp_GetFillPoint__doc__},
+	{"GetFrameNumber",	(PyCFunction)alp_GetFrameNumber,	METH_VARARGS,	alp_GetFrameNumber__doc__},
+	{"GetFrameTime",	(PyCFunction)alp_GetFrameTime,	METH_VARARGS,	alp_GetFrameTime__doc__},
+	{"WriteFrames",	(PyCFunction)alp_WriteFrames,	METH_VARARGS,	alp_WriteFrames__doc__},
+	{"ClosePort",	(PyCFunction)alp_ClosePort,	METH_VARARGS,	alp_ClosePort__doc__},
+#endif /* AL_NO_ELEM */
+#ifdef OLD_INTERFACE
+	{"closeport",		(PyCFunction)alp_closeport,	METH_VARARGS},
+	{"getfd",		(PyCFunction)alp_getfd,	METH_VARARGS},
+        {"fileno",		(PyCFunction)alp_getfd,	METH_VARARGS},
+	{"getfilled",		(PyCFunction)alp_getfilled,	METH_VARARGS},
+	{"getfillable",		(PyCFunction)alp_getfillable,	METH_VARARGS},
+	{"readsamps",		(PyCFunction)alp_readsamps,	METH_VARARGS},
+	{"writesamps",		(PyCFunction)alp_writesamps,	METH_VARARGS},
+	{"setfillpoint",	(PyCFunction)alp_setfillpoint,	METH_VARARGS},
+	{"getfillpoint",	(PyCFunction)alp_getfillpoint,	METH_VARARGS},
+	{"setconfig",		(PyCFunction)alp_setconfig,	METH_VARARGS},
+	{"getconfig",		(PyCFunction)alp_getconfig,	METH_VARARGS},
+#ifdef AL_405
+	{"getstatus",		(PyCFunction)alp_getstatus,	METH_VARARGS},
+#endif /* AL_405 */	    
+#endif /* OLD_INTERFACE */
+ 
+	{NULL,		NULL}		/* sentinel */
+};
+
+/* ---------- */
+
+
+static PyObject *
+newalpobject(ALport port)
+{
+	alpobject *self;
+	
+	self = PyObject_New(alpobject, &Alptype);
+	if (self == NULL)
+		return NULL;
+	/* XXXX Add your own initializers here */
+	self->port = port;
+	return (PyObject *) self;
+}
+
+
+static void
+alp_dealloc(alpobject *self)
+{
+	/* XXXX Add your own cleanup code here */
+	if (self->port) {
+#ifdef AL_NO_ELEM		/* IRIX 6 */
+		alClosePort(self->port);
+#else
+		ALcloseport(self->port);
+#endif
+	}
+	PyObject_Del(self);
+}
+
+static PyObject *
+alp_getattr(alpobject *self, char *name)
+{
+	/* XXXX Add your own getattr code here */
+	if (self->port == NULL) {
+		PyErr_SetString(ErrorObject, "port already closed");
+		return NULL;
+	}
+	return Py_FindMethod(alp_methods, (PyObject *)self, name);
+}
+
+PyDoc_STRVAR(Alptype__doc__, "");
+
+static PyTypeObject Alptype = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,				/*ob_size*/
+	"al.port",			/*tp_name*/
+	sizeof(alpobject),		/*tp_basicsize*/
+	0,				/*tp_itemsize*/
+	/* methods */
+	(destructor)alp_dealloc,	/*tp_dealloc*/
+	(printfunc)0,		/*tp_print*/
+	(getattrfunc)alp_getattr,	/*tp_getattr*/
+	(setattrfunc)0,	/*tp_setattr*/
+	(cmpfunc)0,		/*tp_compare*/
+	(reprfunc)0,		/*tp_repr*/
+	0,			/*tp_as_number*/
+	0,		/*tp_as_sequence*/
+	0,		/*tp_as_mapping*/
+	(hashfunc)0,		/*tp_hash*/
+	(ternaryfunc)0,		/*tp_call*/
+	(reprfunc)0,		/*tp_str*/
+
+	/* Space for future expansion */
+	0L,0L,0L,0L,
+	Alptype__doc__ /* Documentation string */
+};
+
+/* End of code for port objects */
+/* -------------------------------------------------------- */
+
+
+#ifdef AL_NO_ELEM		/* IRIX 6 */
+
+PyDoc_STRVAR(al_NewConfig__doc__,
+"alNewConfig: create and initialize an audio ALconfig structure.");
+
+static PyObject *
+al_NewConfig(PyObject *self, PyObject *args)
+{
+	ALconfig config;
+
+	if (!PyArg_ParseTuple(args, ":NewConfig"))
+		return NULL;
+	if ((config = alNewConfig()) == NULL)
+		return NULL;
+	return newalcobject(config);
+}
+
+PyDoc_STRVAR(al_OpenPort__doc__,
+"alOpenPort: open an audio port.");
+
+static PyObject *
+al_OpenPort(PyObject *self, PyObject *args)
+{
+	ALport port;
+	char *name, *dir;
+	alcobject *config = NULL;
+
+	if (!PyArg_ParseTuple(args, "ss|O!:OpenPort", &name, &dir, &Alctype, &config))
+		return NULL;
+	if ((port = alOpenPort(name, dir, config ? config->config : NULL)) == NULL)
+		return NULL;
+	return newalpobject(port);
+}
+
+PyDoc_STRVAR(al_Connect__doc__,
+"alConnect: connect two audio I/O resources.");
+
+static PyObject *
+al_Connect(PyObject *self, PyObject *args)
+{
+	int source, dest, nprops = 0, id, i;
+	ALpv *props = NULL;
+	ALparamInfo *propinfo = NULL;
+	PyObject *propobj = NULL;
+
+	if (!PyArg_ParseTuple(args, "ii|O!:Connect", &source, &dest, &PyList_Type, &propobj))
+		return NULL;
+	if (propobj != NULL) {
+		nprops = python2params(source, dest, propobj, &props, &propinfo);
+		if (nprops < 0)
+			return NULL;
+	}
+
+	id = alConnect(source, dest, props, nprops);
+
+	if (props) {
+		for (i = 0; i < nprops; i++) {
+			switch (propinfo[i].valueType) {
+			case AL_SET_VAL:
+			case AL_VECTOR_VAL:
+				PyMem_DEL(props[i].value.ptr);
+				break;
+			}
+		}
+		PyMem_DEL(props);
+		PyMem_DEL(propinfo);
+	}
+
+	if (id < 0)
+		return NULL;
+	return PyInt_FromLong((long) id);
+}
+
+PyDoc_STRVAR(al_Disconnect__doc__,
+"alDisconnect: delete a connection between two audio I/O resources.");
+
+static PyObject *
+al_Disconnect(PyObject *self, PyObject *args)
+{
+	int res;
+
+	if (!PyArg_ParseTuple(args, "i:Disconnect", &res))
+		return NULL;
+	if (alDisconnect(res) < 0)
+		return NULL;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(al_GetParams__doc__,
+"alGetParams: get the values of audio resource parameters.");
+
+static PyObject *
+al_GetParams(PyObject *self, PyObject *args)
+{
+	int resource;
+	PyObject *pvslist, *item = NULL, *v = NULL;
+	ALpv *pvs;
+	int i, j, npvs;
+	ALparamInfo *pinfo;
+
+	if (!PyArg_ParseTuple(args, "iO!:GetParams", &resource, &PyList_Type, &pvslist))
+		return NULL;
+	npvs = PyList_Size(pvslist);
+	pvs = PyMem_NEW(ALpv, npvs);
+	pinfo = PyMem_NEW(ALparamInfo, npvs);
+	for (i = 0; i < npvs; i++) {
+		item = PyList_GetItem(pvslist, i);
+		if (!PyInt_Check(item)) {
+			item = NULL;
+			PyErr_SetString(ErrorObject, "list of integers expected");
+			goto error;
+		}
+		pvs[i].param = (int) PyInt_AsLong(item);
+		item = NULL;	/* not needed anymore */
+		if (alGetParamInfo(resource, pvs[i].param, &pinfo[i]) < 0)
+			goto error;
+		switch (pinfo[i].valueType) {
+		case AL_NO_VAL:
+			break;
+		case AL_MATRIX_VAL:
+			pinfo[i].maxElems *= pinfo[i].maxElems2;
+			/* fall through */
+		case AL_STRING_VAL:
+		case AL_SET_VAL:
+		case AL_VECTOR_VAL:
+			switch (pinfo[i].elementType) {
+			case AL_INT32_ELEM:
+			case AL_RESOURCE_ELEM:
+			case AL_ENUM_ELEM:
+				pvs[i].value.ptr = PyMem_NEW(int, pinfo[i].maxElems);
+				pvs[i].sizeIn = pinfo[i].maxElems;
+				break;
+			case AL_INT64_ELEM:
+			case AL_FIXED_ELEM:
+				pvs[i].value.ptr = PyMem_NEW(long long, pinfo[i].maxElems);
+				pvs[i].sizeIn = pinfo[i].maxElems;
+				break;
+			case AL_CHAR_ELEM:
+				pvs[i].value.ptr = PyMem_NEW(char, 32);
+				pvs[i].sizeIn = 32;
+				break;
+			case AL_NO_ELEM:
+			case AL_PTR_ELEM:
+			default:
+				PyErr_SetString(ErrorObject, "internal error");
+				goto error;
+			}
+			break;
+		case AL_SCALAR_VAL:
+			break;
+		default:
+			PyErr_SetString(ErrorObject, "internal error");
+			goto error;
+		}
+		if (pinfo[i].valueType == AL_MATRIX_VAL) {
+			pinfo[i].maxElems /= pinfo[i].maxElems2;
+			pvs[i].sizeIn /= pinfo[i].maxElems2;
+			pvs[i].size2In = pinfo[i].maxElems2;
+		}
+	}
+	if (alGetParams(resource, pvs, npvs) < 0)
+		goto error;
+	if (!(v = PyList_New(npvs)))
+		goto error;
+	for (i = 0; i < npvs; i++) {
+		if (pvs[i].sizeOut < 0) {
+			char buf[32];
+			PyOS_snprintf(buf, sizeof(buf),
+				      "problem with param %d", i);
+			PyErr_SetString(ErrorObject, buf);
+			goto error;
+		}
+		switch (pinfo[i].valueType) {
+		case AL_NO_VAL:
+			item = Py_None;
+			Py_INCREF(item);
+			break;
+		case AL_STRING_VAL:
+			item = PyString_FromString(pvs[i].value.ptr);
+			PyMem_DEL(pvs[i].value.ptr);
+			break;
+		case AL_MATRIX_VAL:
+			/* XXXX this is not right */
+			pvs[i].sizeOut *= pvs[i].size2Out;
+			/* fall through */
+		case AL_SET_VAL:
+		case AL_VECTOR_VAL:
+			item = PyList_New(pvs[i].sizeOut);
+			for (j = 0; j < pvs[i].sizeOut; j++) {
+				switch (pinfo[i].elementType) {
+				case AL_INT32_ELEM:
+				case AL_RESOURCE_ELEM:
+				case AL_ENUM_ELEM:
+					PyList_SetItem(item, j, PyInt_FromLong((long) ((int *) pvs[i].value.ptr)[j]));
+					break;
+				case AL_INT64_ELEM:
+					PyList_SetItem(item, j, PyLong_FromLongLong(((long long *) pvs[i].value.ptr)[j]));
+					break;
+				case AL_FIXED_ELEM:
+					PyList_SetItem(item, j, PyFloat_FromDouble(alFixedToDouble(((long long *) pvs[i].value.ptr)[j])));
+					break;
+				default:
+					PyErr_SetString(ErrorObject, "internal error");
+					goto error;
+				}
+			}
+			PyMem_DEL(pvs[i].value.ptr);
+			break;
+		case AL_SCALAR_VAL:
+			item = param2python(resource, pvs[i].param, pvs[i].value, &pinfo[i]);
+			break;
+		}
+		if (PyErr_Occurred() ||
+		    PyList_SetItem(v, i, Py_BuildValue("(iO)", pvs[i].param,
+						       item)) < 0 ||
+		    PyErr_Occurred())
+			goto error;
+		Py_DECREF(item);
+	}
+	PyMem_DEL(pvs);
+	PyMem_DEL(pinfo);
+	return v;
+
+  error:
+	Py_XDECREF(v);
+	Py_XDECREF(item);
+	if (pvs)
+		PyMem_DEL(pvs);
+	if (pinfo)
+		PyMem_DEL(pinfo);
+	return NULL;
+}
+
+PyDoc_STRVAR(al_SetParams__doc__,
+"alSetParams: set the values of audio resource parameters.");
+
+static PyObject *
+al_SetParams(PyObject *self, PyObject *args)
+{
+	int resource;
+	PyObject *pvslist;
+	ALpv *pvs;
+	ALparamInfo *pinfo;
+	int npvs, i;
+
+	if (!PyArg_ParseTuple(args, "iO!:SetParams", &resource, &PyList_Type, &pvslist))
+		return NULL;
+	npvs = python2params(resource, -1, pvslist, &pvs, &pinfo);
+	if (npvs < 0)
+		return NULL;
+
+	if (alSetParams(resource, pvs, npvs) < 0)
+		goto error;
+
+	/* cleanup */
+	for (i = 0; i < npvs; i++) {
+		switch (pinfo[i].valueType) {
+		case AL_SET_VAL:
+		case AL_VECTOR_VAL:
+			PyMem_DEL(pvs[i].value.ptr);
+			break;
+		}
+	}
+	PyMem_DEL(pvs);
+	PyMem_DEL(pinfo);
+
+	Py_INCREF(Py_None);
+	return Py_None;
+
+  error:
+	/* XXXX we should clean up everything */
+	if (pvs)
+		PyMem_DEL(pvs);
+	if (pinfo)
+		PyMem_DEL(pinfo);
+	return NULL;
+}
+
+PyDoc_STRVAR(al_QueryValues__doc__,
+"alQueryValues: get the set of possible values for a parameter.");
+
+static PyObject *
+al_QueryValues(PyObject *self, PyObject *args)
+{
+	int resource, param;
+	ALvalue *return_set = NULL;
+	int setsize = 32, qualsize = 0, nvals, i;
+	ALpv *quals = NULL;
+	ALparamInfo pinfo;
+	ALparamInfo *qualinfo = NULL;
+	PyObject *qualobj = NULL;
+	PyObject *res = NULL, *item;
+
+	if (!PyArg_ParseTuple(args, "ii|O!:QueryValues", &resource, &param,
+			      &PyList_Type, &qualobj))
+		return NULL;
+	if (qualobj != NULL) {
+		qualsize = python2params(resource, param, qualobj, &quals, &qualinfo);
+		if (qualsize < 0)
+			return NULL;
+	}
+	setsize = 32;
+	return_set = PyMem_NEW(ALvalue, setsize);
+	if (return_set == NULL) {
+		PyErr_NoMemory();
+		goto cleanup;
+	}
+
+  retry:
+	nvals = alQueryValues(resource, param, return_set, setsize, quals, qualsize);
+	if (nvals < 0)
+		goto cleanup;
+	if (nvals > setsize) {
+		setsize = nvals;
+		PyMem_RESIZE(return_set, ALvalue, setsize);
+		if (return_set == NULL) {
+			PyErr_NoMemory();
+			goto cleanup;
+		}
+		goto retry;
+	}
+
+	if (alGetParamInfo(resource, param, &pinfo) < 0)
+		goto cleanup;
+
+	res = PyList_New(nvals);
+	if (res == NULL)
+		goto cleanup;
+	for (i = 0; i < nvals; i++) {
+		item = param2python(resource, param, return_set[i], &pinfo);
+		if (item == NULL ||
+		    PyList_SetItem(res, i, item) < 0) {
+			Py_DECREF(res);
+			res = NULL;
+			goto cleanup;
+		}
+	}
+
+  cleanup:
+	if (return_set)
+		PyMem_DEL(return_set);
+	if (quals) {
+		for (i = 0; i < qualsize; i++) {
+			switch (qualinfo[i].valueType) {
+			case AL_SET_VAL:
+			case AL_VECTOR_VAL:
+				PyMem_DEL(quals[i].value.ptr);
+				break;
+			}
+		}
+		PyMem_DEL(quals);
+		PyMem_DEL(qualinfo);
+	}
+
+	return res;
+}
+
+PyDoc_STRVAR(al_GetParamInfo__doc__,
+"alGetParamInfo: get information about a parameter on "
+"a particular audio resource.");
+
+static PyObject *
+al_GetParamInfo(PyObject *self, PyObject *args)
+{
+	int res, param;
+	ALparamInfo pinfo;
+	PyObject *v, *item;
+
+	if (!PyArg_ParseTuple(args, "ii:GetParamInfo", &res, &param))
+		return NULL;
+	if (alGetParamInfo(res, param, &pinfo) < 0)
+		return NULL;
+	v = PyDict_New();
+	if (!v) return NULL;
+
+	item = PyInt_FromLong((long) pinfo.resource);
+	PyDict_SetItemString(v, "resource", item);
+	Py_DECREF(item);
+
+	item = PyInt_FromLong((long) pinfo.param);
+	PyDict_SetItemString(v, "param", item);
+	Py_DECREF(item);
+
+	item = PyInt_FromLong((long) pinfo.valueType);
+	PyDict_SetItemString(v, "valueType", item);
+	Py_DECREF(item);
+
+	if (pinfo.valueType != AL_NO_VAL && pinfo.valueType != AL_SCALAR_VAL) {
+		/* multiple values */
+		item = PyInt_FromLong((long) pinfo.maxElems);
+		PyDict_SetItemString(v, "maxElems", item);
+		Py_DECREF(item);
+
+		if (pinfo.valueType == AL_MATRIX_VAL) {
+			/* 2 dimensional */
+			item = PyInt_FromLong((long) pinfo.maxElems2);
+			PyDict_SetItemString(v, "maxElems2", item);
+			Py_DECREF(item);
+		}
+	}
+
+	item = PyInt_FromLong((long) pinfo.elementType);
+	PyDict_SetItemString(v, "elementType", item);
+	Py_DECREF(item);
+
+	item = PyString_FromString(pinfo.name);
+	PyDict_SetItemString(v, "name", item);
+	Py_DECREF(item);
+
+	item = param2python(res, param, pinfo.initial, &pinfo);
+	PyDict_SetItemString(v, "initial", item);
+	Py_DECREF(item);
+
+	if (pinfo.elementType != AL_ENUM_ELEM &&
+	    pinfo.elementType != AL_RESOURCE_ELEM &&
+	    pinfo.elementType != AL_CHAR_ELEM) {
+		/* range param */
+		item = param2python(res, param, pinfo.min, &pinfo);
+		PyDict_SetItemString(v, "min", item);
+		Py_DECREF(item);
+
+		item = param2python(res, param, pinfo.max, &pinfo);
+		PyDict_SetItemString(v, "max", item);
+		Py_DECREF(item);
+
+		item = param2python(res, param, pinfo.minDelta, &pinfo);
+		PyDict_SetItemString(v, "minDelta", item);
+		Py_DECREF(item);
+
+		item = param2python(res, param, pinfo.maxDelta, &pinfo);
+		PyDict_SetItemString(v, "maxDelta", item);
+		Py_DECREF(item);
+
+		item = PyInt_FromLong((long) pinfo.specialVals);
+		PyDict_SetItemString(v, "specialVals", item);
+		Py_DECREF(item);
+	}
+
+	return v;
+}
+
+PyDoc_STRVAR(al_GetResourceByName__doc__,
+"alGetResourceByName: find an audio resource by name.");
+
+static PyObject *
+al_GetResourceByName(PyObject *self, PyObject *args)
+{
+	int res, start_res, type;
+	char *name;
+
+	if (!PyArg_ParseTuple(args, "isi:GetResourceByName", &start_res, &name, &type))
+		return NULL;
+	if ((res = alGetResourceByName(start_res, name, type)) == 0)
+		return NULL;
+	return PyInt_FromLong((long) res);
+}
+
+PyDoc_STRVAR(al_IsSubtype__doc__,
+"alIsSubtype: indicate if one resource type is a subtype of another.");
+
+static PyObject *
+al_IsSubtype(PyObject *self, PyObject *args)
+{
+	int type, subtype;
+
+	if (!PyArg_ParseTuple(args, "ii:IsSubtype", &type, &subtype))
+		return NULL;
+	return PyInt_FromLong((long) alIsSubtype(type, subtype));
+}
+
+PyDoc_STRVAR(al_SetErrorHandler__doc__, "");
+
+static PyObject *
+al_SetErrorHandler(PyObject *self, PyObject *args)
+{
+
+	if (!PyArg_ParseTuple(args, ":SetErrorHandler"))
+		return NULL;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+#endif /* AL_NO_ELEM */
+
+#ifdef OLD_INTERFACE
+
+static PyObject *
+al_openport(PyObject *self, PyObject *args)
+{
+	char *name, *dir;
+	ALport port;
+	alcobject *config = NULL;
+
+	if (!PyArg_ParseTuple(args, "ss|O!:OpenPort", &name, &dir, &Alctype, &config))
+		return NULL;
+	if ((port = ALopenport(name, dir, config ? config->config : NULL)) == NULL)
+		return NULL;
+	return newalpobject(port);
+}
+
+static PyObject *
+al_newconfig(PyObject *self, PyObject *args)
+{
+	ALconfig config;
+
+	if (!PyArg_ParseTuple(args, ":NewConfig"))
+		return NULL;
+	if ((config = ALnewconfig ()) == NULL)
+		return NULL;
+	return newalcobject(config);
+}
+
+static PyObject *
+al_queryparams(PyObject *self, PyObject *args)
+{
+	long device;
+	long length;
+	long *PVbuffer;
+	long PVdummy[2];
+	PyObject *v = NULL;
+	int i;
+
+	if (!PyArg_ParseTuple(args, "l:queryparams", &device))
+		return NULL;
+	if ((length = ALqueryparams(device, PVdummy, 2L)) == -1)
+		return NULL;
+	if ((PVbuffer = PyMem_NEW(long, length)) == NULL)
+		return PyErr_NoMemory();
+	if (ALqueryparams(device, PVbuffer, length) >= 0 &&
+	    (v = PyList_New((int)length)) != NULL) {
+		for (i = 0; i < length; i++)
+			PyList_SetItem(v, i, PyInt_FromLong(PVbuffer[i]));
+	}
+	PyMem_DEL(PVbuffer);
+	return v;
+}
+
+static PyObject *
+doParams(PyObject *args, int (*func)(long, long *, long), int modified)
+{
+	long device;
+	PyObject *list, *v;
+	long *PVbuffer;
+	long length;
+	int i;
+	
+	if (!PyArg_ParseTuple(args, "lO!", &device, &PyList_Type, &list))
+		return NULL;
+	length = PyList_Size(list);
+	PVbuffer = PyMem_NEW(long, length);
+	if (PVbuffer == NULL)
+		return PyErr_NoMemory();
+	for (i = 0; i < length; i++) {
+		v = PyList_GetItem(list, i);
+		if (!PyInt_Check(v)) {
+			PyMem_DEL(PVbuffer);
+			PyErr_BadArgument();
+			return NULL;
+		}
+		PVbuffer[i] = PyInt_AsLong(v);
+	}
+
+	if ((*func)(device, PVbuffer, length) == -1) {
+		PyMem_DEL(PVbuffer);
+		return NULL;
+	}
+
+	if (modified) {
+		for (i = 0; i < length; i++)
+			PyList_SetItem(list, i, PyInt_FromLong(PVbuffer[i]));
+	}
+
+	PyMem_DEL(PVbuffer);
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+al_getparams(PyObject *self, PyObject *args)
+{
+	return doParams(args, ALgetparams, 1);
+}
+
+static PyObject *
+al_setparams(PyObject *self, PyObject *args)
+{
+	return doParams(args, ALsetparams, 0);
+}
+
+static PyObject *
+al_getname(PyObject *self, PyObject *args)
+{
+	long device, descriptor;
+	char *name;
+
+	if (!PyArg_ParseTuple(args, "ll:getname", &device, &descriptor))
+		return NULL;
+	if ((name = ALgetname(device, descriptor)) == NULL)
+		return NULL;
+	return PyString_FromString(name);
+}
+
+static PyObject *
+al_getdefault(PyObject *self, PyObject *args)
+{
+	long device, descriptor, value;
+
+	if (!PyArg_ParseTuple(args, "ll:getdefault", &device, &descriptor))
+		return NULL;
+	if ((value = ALgetdefault(device, descriptor)) == -1)
+		return NULL;
+	return PyLong_FromLong(value);
+}
+
+static PyObject *
+al_getminmax(PyObject *self, PyObject *args)
+{
+	long device, descriptor, min, max;
+
+	if (!PyArg_ParseTuple(args, "ll:getminmax", &device, &descriptor))
+		return NULL;
+	min = -1;
+	max = -1;
+	if (ALgetminmax(device, descriptor, &min, &max) == -1)
+		return NULL;
+	return Py_BuildValue("ll", min, max);
+}
+
+#endif /* OLD_INTERFACE */
+
+/* List of methods defined in the module */
+
+static struct PyMethodDef al_methods[] = {
+#ifdef AL_NO_ELEM		/* IRIX 6 */
+	{"NewConfig",	(PyCFunction)al_NewConfig,	METH_VARARGS,	al_NewConfig__doc__},
+	{"OpenPort",	(PyCFunction)al_OpenPort,	METH_VARARGS,	al_OpenPort__doc__},
+	{"Connect",	(PyCFunction)al_Connect,	METH_VARARGS,	al_Connect__doc__},
+	{"Disconnect",	(PyCFunction)al_Disconnect,	METH_VARARGS,	al_Disconnect__doc__},
+	{"GetParams",	(PyCFunction)al_GetParams,	METH_VARARGS,	al_GetParams__doc__},
+	{"SetParams",	(PyCFunction)al_SetParams,	METH_VARARGS,	al_SetParams__doc__},
+	{"QueryValues",	(PyCFunction)al_QueryValues,	METH_VARARGS,	al_QueryValues__doc__},
+	{"GetParamInfo",	(PyCFunction)al_GetParamInfo,	METH_VARARGS,	al_GetParamInfo__doc__},
+	{"GetResourceByName",	(PyCFunction)al_GetResourceByName,	METH_VARARGS,	al_GetResourceByName__doc__},
+	{"IsSubtype",	(PyCFunction)al_IsSubtype,	METH_VARARGS,	al_IsSubtype__doc__},
+#if 0
+	/* this one not supported */
+	{"SetErrorHandler",	(PyCFunction)al_SetErrorHandler,	METH_VARARGS,	al_SetErrorHandler__doc__},
+#endif
+#endif /* AL_NO_ELEM */
+#ifdef OLD_INTERFACE
+	{"openport",		(PyCFunction)al_openport,	METH_VARARGS},
+	{"newconfig",		(PyCFunction)al_newconfig,	METH_VARARGS},
+	{"queryparams",		(PyCFunction)al_queryparams,	METH_VARARGS},
+	{"getparams",		(PyCFunction)al_getparams,	METH_VARARGS},
+	{"setparams",		(PyCFunction)al_setparams,	METH_VARARGS},
+	{"getname",		(PyCFunction)al_getname,	METH_VARARGS},
+	{"getdefault",		(PyCFunction)al_getdefault,	METH_VARARGS},
+	{"getminmax",		(PyCFunction)al_getminmax,	METH_VARARGS},
+#endif /* OLD_INTERFACE */
+
+	{NULL,	 (PyCFunction)NULL, 0, NULL}		/* sentinel */
+};
+
+
+/* Initialization function for the module (*must* be called inital) */
+
+PyDoc_STRVAR(al_module_documentation, "");
+
+void
+inital(void)
+{
+	PyObject *m, *d, *x;
+
+	/* Create the module and add the functions */
+	m = Py_InitModule4("al", al_methods,
+		al_module_documentation,
+		(PyObject*)NULL,PYTHON_API_VERSION);
+	if (m == NULL)
+		return;
+
+	/* Add some symbolic constants to the module */
+	d = PyModule_GetDict(m);
+	ErrorObject = PyErr_NewException("al.error", NULL, NULL);
+	PyDict_SetItemString(d, "error", ErrorObject);
+
+	/* XXXX Add constants here */
+#ifdef AL_4CHANNEL
+	x =  PyInt_FromLong((long) AL_4CHANNEL);
+	if (x == NULL || PyDict_SetItemString(d, "FOURCHANNEL", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_ADAT_IF_TYPE
+	x =  PyInt_FromLong((long) AL_ADAT_IF_TYPE);
+	if (x == NULL || PyDict_SetItemString(d, "ADAT_IF_TYPE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_ADAT_MCLK_TYPE
+	x =  PyInt_FromLong((long) AL_ADAT_MCLK_TYPE);
+	if (x == NULL || PyDict_SetItemString(d, "ADAT_MCLK_TYPE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_AES_IF_TYPE
+	x =  PyInt_FromLong((long) AL_AES_IF_TYPE);
+	if (x == NULL || PyDict_SetItemString(d, "AES_IF_TYPE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_AES_MCLK_TYPE
+	x =  PyInt_FromLong((long) AL_AES_MCLK_TYPE);
+	if (x == NULL || PyDict_SetItemString(d, "AES_MCLK_TYPE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_ANALOG_IF_TYPE
+	x =  PyInt_FromLong((long) AL_ANALOG_IF_TYPE);
+	if (x == NULL || PyDict_SetItemString(d, "ANALOG_IF_TYPE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_ASSOCIATE
+	x =  PyInt_FromLong((long) AL_ASSOCIATE);
+	if (x == NULL || PyDict_SetItemString(d, "ASSOCIATE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_BAD_BUFFER_NULL
+	x =  PyInt_FromLong((long) AL_BAD_BUFFER_NULL);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_BUFFER_NULL", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_BAD_BUFFERLENGTH
+	x =  PyInt_FromLong((long) AL_BAD_BUFFERLENGTH);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_BUFFERLENGTH", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_BAD_BUFFERLENGTH_NEG
+	x =  PyInt_FromLong((long) AL_BAD_BUFFERLENGTH_NEG);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_BUFFERLENGTH_NEG", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_BAD_BUFFERLENGTH_ODD
+	x =  PyInt_FromLong((long) AL_BAD_BUFFERLENGTH_ODD);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_BUFFERLENGTH_ODD", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_BAD_CHANNELS
+	x =  PyInt_FromLong((long) AL_BAD_CHANNELS);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_CHANNELS", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_BAD_CONFIG
+	x =  PyInt_FromLong((long) AL_BAD_CONFIG);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_CONFIG", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_BAD_COUNT_NEG
+	x =  PyInt_FromLong((long) AL_BAD_COUNT_NEG);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_COUNT_NEG", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_BAD_DEVICE
+	x =  PyInt_FromLong((long) AL_BAD_DEVICE);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_DEVICE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_BAD_DEVICE_ACCESS
+	x =  PyInt_FromLong((long) AL_BAD_DEVICE_ACCESS);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_DEVICE_ACCESS", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_BAD_DIRECTION
+	x =  PyInt_FromLong((long) AL_BAD_DIRECTION);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_DIRECTION", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_BAD_FILLPOINT
+	x =  PyInt_FromLong((long) AL_BAD_FILLPOINT);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_FILLPOINT", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_BAD_FLOATMAX
+	x =  PyInt_FromLong((long) AL_BAD_FLOATMAX);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_FLOATMAX", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_BAD_ILLEGAL_STATE
+	x =  PyInt_FromLong((long) AL_BAD_ILLEGAL_STATE);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_ILLEGAL_STATE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_BAD_NO_PORTS
+	x =  PyInt_FromLong((long) AL_BAD_NO_PORTS);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_NO_PORTS", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_BAD_NOT_FOUND
+	x =  PyInt_FromLong((long) AL_BAD_NOT_FOUND);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_NOT_FOUND", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_BAD_NOT_IMPLEMENTED
+	x =  PyInt_FromLong((long) AL_BAD_NOT_IMPLEMENTED);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_NOT_IMPLEMENTED", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_BAD_OUT_OF_MEM
+	x =  PyInt_FromLong((long) AL_BAD_OUT_OF_MEM);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_OUT_OF_MEM", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_BAD_PARAM
+	x =  PyInt_FromLong((long) AL_BAD_PARAM);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_PARAM", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_BAD_PERMISSIONS
+	x =  PyInt_FromLong((long) AL_BAD_PERMISSIONS);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_PERMISSIONS", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_BAD_PORT
+	x =  PyInt_FromLong((long) AL_BAD_PORT);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_PORT", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_BAD_PORTSTYLE
+	x =  PyInt_FromLong((long) AL_BAD_PORTSTYLE);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_PORTSTYLE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_BAD_PVBUFFER
+	x =  PyInt_FromLong((long) AL_BAD_PVBUFFER);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_PVBUFFER", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_BAD_QSIZE
+	x =  PyInt_FromLong((long) AL_BAD_QSIZE);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_QSIZE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_BAD_RATE
+	x =  PyInt_FromLong((long) AL_BAD_RATE);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_RATE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_BAD_RESOURCE
+	x =  PyInt_FromLong((long) AL_BAD_RESOURCE);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_RESOURCE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_BAD_SAMPFMT
+	x =  PyInt_FromLong((long) AL_BAD_SAMPFMT);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_SAMPFMT", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_BAD_TRANSFER_SIZE
+	x =  PyInt_FromLong((long) AL_BAD_TRANSFER_SIZE);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_TRANSFER_SIZE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_BAD_WIDTH
+	x =  PyInt_FromLong((long) AL_BAD_WIDTH);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_WIDTH", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_CHANNEL_MODE
+	x =  PyInt_FromLong((long) AL_CHANNEL_MODE);
+	if (x == NULL || PyDict_SetItemString(d, "CHANNEL_MODE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_CHANNELS
+	x =  PyInt_FromLong((long) AL_CHANNELS);
+	if (x == NULL || PyDict_SetItemString(d, "CHANNELS", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_CHAR_ELEM
+	x =  PyInt_FromLong((long) AL_CHAR_ELEM);
+	if (x == NULL || PyDict_SetItemString(d, "CHAR_ELEM", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_CLOCK_GEN
+	x =  PyInt_FromLong((long) AL_CLOCK_GEN);
+	if (x == NULL || PyDict_SetItemString(d, "CLOCK_GEN", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_CLOCKGEN_TYPE
+	x =  PyInt_FromLong((long) AL_CLOCKGEN_TYPE);
+	if (x == NULL || PyDict_SetItemString(d, "CLOCKGEN_TYPE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_CONNECT
+	x =  PyInt_FromLong((long) AL_CONNECT);
+	if (x == NULL || PyDict_SetItemString(d, "CONNECT", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_CONNECTION_TYPE
+	x =  PyInt_FromLong((long) AL_CONNECTION_TYPE);
+	if (x == NULL || PyDict_SetItemString(d, "CONNECTION_TYPE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_CONNECTIONS
+	x =  PyInt_FromLong((long) AL_CONNECTIONS);
+	if (x == NULL || PyDict_SetItemString(d, "CONNECTIONS", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_CRYSTAL_MCLK_TYPE
+	x =  PyInt_FromLong((long) AL_CRYSTAL_MCLK_TYPE);
+	if (x == NULL || PyDict_SetItemString(d, "CRYSTAL_MCLK_TYPE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_DEFAULT_DEVICE
+	x =  PyInt_FromLong((long) AL_DEFAULT_DEVICE);
+	if (x == NULL || PyDict_SetItemString(d, "DEFAULT_DEVICE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_DEFAULT_INPUT
+	x =  PyInt_FromLong((long) AL_DEFAULT_INPUT);
+	if (x == NULL || PyDict_SetItemString(d, "DEFAULT_INPUT", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_DEFAULT_OUTPUT
+	x =  PyInt_FromLong((long) AL_DEFAULT_OUTPUT);
+	if (x == NULL || PyDict_SetItemString(d, "DEFAULT_OUTPUT", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_DEST
+	x =  PyInt_FromLong((long) AL_DEST);
+	if (x == NULL || PyDict_SetItemString(d, "DEST", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_DEVICE_TYPE
+	x =  PyInt_FromLong((long) AL_DEVICE_TYPE);
+	if (x == NULL || PyDict_SetItemString(d, "DEVICE_TYPE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_DEVICES
+	x =  PyInt_FromLong((long) AL_DEVICES);
+	if (x == NULL || PyDict_SetItemString(d, "DEVICES", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_DIGITAL_IF_TYPE
+	x =  PyInt_FromLong((long) AL_DIGITAL_IF_TYPE);
+	if (x == NULL || PyDict_SetItemString(d, "DIGITAL_IF_TYPE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_DIGITAL_INPUT_RATE
+	x =  PyInt_FromLong((long) AL_DIGITAL_INPUT_RATE);
+	if (x == NULL || PyDict_SetItemString(d, "DIGITAL_INPUT_RATE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_DISCONNECT
+	x =  PyInt_FromLong((long) AL_DISCONNECT);
+	if (x == NULL || PyDict_SetItemString(d, "DISCONNECT", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_ENUM_ELEM
+	x =  PyInt_FromLong((long) AL_ENUM_ELEM);
+	if (x == NULL || PyDict_SetItemString(d, "ENUM_ELEM", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_ENUM_VALUE
+	x =  PyInt_FromLong((long) AL_ENUM_VALUE);
+	if (x == NULL || PyDict_SetItemString(d, "ENUM_VALUE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_ERROR_INPUT_OVERFLOW
+	x =  PyInt_FromLong((long) AL_ERROR_INPUT_OVERFLOW);
+	if (x == NULL || PyDict_SetItemString(d, "ERROR_INPUT_OVERFLOW", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_ERROR_LENGTH
+	x =  PyInt_FromLong((long) AL_ERROR_LENGTH);
+	if (x == NULL || PyDict_SetItemString(d, "ERROR_LENGTH", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_ERROR_LOCATION_LSP
+	x =  PyInt_FromLong((long) AL_ERROR_LOCATION_LSP);
+	if (x == NULL || PyDict_SetItemString(d, "ERROR_LOCATION_LSP", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_ERROR_LOCATION_MSP
+	x =  PyInt_FromLong((long) AL_ERROR_LOCATION_MSP);
+	if (x == NULL || PyDict_SetItemString(d, "ERROR_LOCATION_MSP", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_ERROR_NUMBER
+	x =  PyInt_FromLong((long) AL_ERROR_NUMBER);
+	if (x == NULL || PyDict_SetItemString(d, "ERROR_NUMBER", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_ERROR_OUTPUT_UNDERFLOW
+	x =  PyInt_FromLong((long) AL_ERROR_OUTPUT_UNDERFLOW);
+	if (x == NULL || PyDict_SetItemString(d, "ERROR_OUTPUT_UNDERFLOW", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_ERROR_TYPE
+	x =  PyInt_FromLong((long) AL_ERROR_TYPE);
+	if (x == NULL || PyDict_SetItemString(d, "ERROR_TYPE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_FIXED_ELEM
+	x =  PyInt_FromLong((long) AL_FIXED_ELEM);
+	if (x == NULL || PyDict_SetItemString(d, "FIXED_ELEM", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_FIXED_MCLK_TYPE
+	x =  PyInt_FromLong((long) AL_FIXED_MCLK_TYPE);
+	if (x == NULL || PyDict_SetItemString(d, "FIXED_MCLK_TYPE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_GAIN
+	x =  PyInt_FromLong((long) AL_GAIN);
+	if (x == NULL || PyDict_SetItemString(d, "GAIN", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_GAIN_REF
+	x =  PyInt_FromLong((long) AL_GAIN_REF);
+	if (x == NULL || PyDict_SetItemString(d, "GAIN_REF", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_HRB_TYPE
+	x =  PyInt_FromLong((long) AL_HRB_TYPE);
+	if (x == NULL || PyDict_SetItemString(d, "HRB_TYPE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_INPUT_COUNT
+	x =  PyInt_FromLong((long) AL_INPUT_COUNT);
+	if (x == NULL || PyDict_SetItemString(d, "INPUT_COUNT", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_INPUT_DEVICE_TYPE
+	x =  PyInt_FromLong((long) AL_INPUT_DEVICE_TYPE);
+	if (x == NULL || PyDict_SetItemString(d, "INPUT_DEVICE_TYPE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_INPUT_DIGITAL
+	x =  PyInt_FromLong((long) AL_INPUT_DIGITAL);
+	if (x == NULL || PyDict_SetItemString(d, "INPUT_DIGITAL", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_INPUT_HRB_TYPE
+	x =  PyInt_FromLong((long) AL_INPUT_HRB_TYPE);
+	if (x == NULL || PyDict_SetItemString(d, "INPUT_HRB_TYPE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_INPUT_LINE
+	x =  PyInt_FromLong((long) AL_INPUT_LINE);
+	if (x == NULL || PyDict_SetItemString(d, "INPUT_LINE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_INPUT_MIC
+	x =  PyInt_FromLong((long) AL_INPUT_MIC);
+	if (x == NULL || PyDict_SetItemString(d, "INPUT_MIC", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_INPUT_PORT_TYPE
+	x =  PyInt_FromLong((long) AL_INPUT_PORT_TYPE);
+	if (x == NULL || PyDict_SetItemString(d, "INPUT_PORT_TYPE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_INPUT_RATE
+	x =  PyInt_FromLong((long) AL_INPUT_RATE);
+	if (x == NULL || PyDict_SetItemString(d, "INPUT_RATE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_INPUT_SOURCE
+	x =  PyInt_FromLong((long) AL_INPUT_SOURCE);
+	if (x == NULL || PyDict_SetItemString(d, "INPUT_SOURCE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_INT32_ELEM
+	x =  PyInt_FromLong((long) AL_INT32_ELEM);
+	if (x == NULL || PyDict_SetItemString(d, "INT32_ELEM", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_INT64_ELEM
+	x =  PyInt_FromLong((long) AL_INT64_ELEM);
+	if (x == NULL || PyDict_SetItemString(d, "INT64_ELEM", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_INTERFACE
+	x =  PyInt_FromLong((long) AL_INTERFACE);
+	if (x == NULL || PyDict_SetItemString(d, "INTERFACE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_INTERFACE_TYPE
+	x =  PyInt_FromLong((long) AL_INTERFACE_TYPE);
+	if (x == NULL || PyDict_SetItemString(d, "INTERFACE_TYPE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_INVALID_PARAM
+	x =  PyInt_FromLong((long) AL_INVALID_PARAM);
+	if (x == NULL || PyDict_SetItemString(d, "INVALID_PARAM", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_INVALID_VALUE
+	x =  PyInt_FromLong((long) AL_INVALID_VALUE);
+	if (x == NULL || PyDict_SetItemString(d, "INVALID_VALUE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_JITTER
+	x =  PyInt_FromLong((long) AL_JITTER);
+	if (x == NULL || PyDict_SetItemString(d, "JITTER", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_LABEL
+	x =  PyInt_FromLong((long) AL_LABEL);
+	if (x == NULL || PyDict_SetItemString(d, "LABEL", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_LEFT_INPUT_ATTEN
+	x =  PyInt_FromLong((long) AL_LEFT_INPUT_ATTEN);
+	if (x == NULL || PyDict_SetItemString(d, "LEFT_INPUT_ATTEN", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_LEFT_MONITOR_ATTEN
+	x =  PyInt_FromLong((long) AL_LEFT_MONITOR_ATTEN);
+	if (x == NULL || PyDict_SetItemString(d, "LEFT_MONITOR_ATTEN", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_LEFT_SPEAKER_GAIN
+	x =  PyInt_FromLong((long) AL_LEFT_SPEAKER_GAIN);
+	if (x == NULL || PyDict_SetItemString(d, "LEFT_SPEAKER_GAIN", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_LEFT1_INPUT_ATTEN
+	x =  PyInt_FromLong((long) AL_LEFT1_INPUT_ATTEN);
+	if (x == NULL || PyDict_SetItemString(d, "LEFT1_INPUT_ATTEN", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_LEFT2_INPUT_ATTEN
+	x =  PyInt_FromLong((long) AL_LEFT2_INPUT_ATTEN);
+	if (x == NULL || PyDict_SetItemString(d, "LEFT2_INPUT_ATTEN", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_LINE_IF_TYPE
+	x =  PyInt_FromLong((long) AL_LINE_IF_TYPE);
+	if (x == NULL || PyDict_SetItemString(d, "LINE_IF_TYPE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_LOCKED
+	x =  PyInt_FromLong((long) AL_LOCKED);
+	if (x == NULL || PyDict_SetItemString(d, "LOCKED", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_MASTER_CLOCK
+	x =  PyInt_FromLong((long) AL_MASTER_CLOCK);
+	if (x == NULL || PyDict_SetItemString(d, "MASTER_CLOCK", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_MATRIX_VAL
+	x =  PyInt_FromLong((long) AL_MATRIX_VAL);
+	if (x == NULL || PyDict_SetItemString(d, "MATRIX_VAL", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_MAX_ERROR
+	x =  PyInt_FromLong((long) AL_MAX_ERROR);
+	if (x == NULL || PyDict_SetItemString(d, "MAX_ERROR", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_MAX_EVENT_PARAM
+	x =  PyInt_FromLong((long) AL_MAX_EVENT_PARAM);
+	if (x == NULL || PyDict_SetItemString(d, "MAX_EVENT_PARAM", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_MAX_PBUFSIZE
+	x =  PyInt_FromLong((long) AL_MAX_PBUFSIZE);
+	if (x == NULL || PyDict_SetItemString(d, "MAX_PBUFSIZE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_MAX_PORTS
+	x =  PyInt_FromLong((long) AL_MAX_PORTS);
+	if (x == NULL || PyDict_SetItemString(d, "MAX_PORTS", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_MAX_RESOURCE_ID
+	x =  PyInt_FromLong((long) AL_MAX_RESOURCE_ID);
+	if (x == NULL || PyDict_SetItemString(d, "MAX_RESOURCE_ID", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_MAX_SETSIZE
+	x =  PyInt_FromLong((long) AL_MAX_SETSIZE);
+	if (x == NULL || PyDict_SetItemString(d, "MAX_SETSIZE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_MAX_STRLEN
+	x =  PyInt_FromLong((long) AL_MAX_STRLEN);
+	if (x == NULL || PyDict_SetItemString(d, "MAX_STRLEN", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_MCLK_TYPE
+	x =  PyInt_FromLong((long) AL_MCLK_TYPE);
+	if (x == NULL || PyDict_SetItemString(d, "MCLK_TYPE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_MIC_IF_TYPE
+	x =  PyInt_FromLong((long) AL_MIC_IF_TYPE);
+	if (x == NULL || PyDict_SetItemString(d, "MIC_IF_TYPE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_MONITOR_CTL
+	x =  PyInt_FromLong((long) AL_MONITOR_CTL);
+	if (x == NULL || PyDict_SetItemString(d, "MONITOR_CTL", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_MONITOR_OFF
+	x =  PyInt_FromLong((long) AL_MONITOR_OFF);
+	if (x == NULL || PyDict_SetItemString(d, "MONITOR_OFF", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_MONITOR_ON
+	x =  PyInt_FromLong((long) AL_MONITOR_ON);
+	if (x == NULL || PyDict_SetItemString(d, "MONITOR_ON", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_MONO
+	x =  PyInt_FromLong((long) AL_MONO);
+	if (x == NULL || PyDict_SetItemString(d, "MONO", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_MUTE
+	x =  PyInt_FromLong((long) AL_MUTE);
+	if (x == NULL || PyDict_SetItemString(d, "MUTE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_NAME
+	x =  PyInt_FromLong((long) AL_NAME);
+	if (x == NULL || PyDict_SetItemString(d, "NAME", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_NEG_INFINITY
+	x =  PyInt_FromLong((long) AL_NEG_INFINITY);
+	if (x == NULL || PyDict_SetItemString(d, "NEG_INFINITY", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_NEG_INFINITY_BIT
+	x =  PyInt_FromLong((long) AL_NEG_INFINITY_BIT);
+	if (x == NULL || PyDict_SetItemString(d, "NEG_INFINITY_BIT", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_NO_CHANGE
+	x =  PyInt_FromLong((long) AL_NO_CHANGE);
+	if (x == NULL || PyDict_SetItemString(d, "NO_CHANGE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_NO_CHANGE_BIT
+	x =  PyInt_FromLong((long) AL_NO_CHANGE_BIT);
+	if (x == NULL || PyDict_SetItemString(d, "NO_CHANGE_BIT", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_NO_ELEM
+	x =  PyInt_FromLong((long) AL_NO_ELEM);
+	if (x == NULL || PyDict_SetItemString(d, "NO_ELEM", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_NO_ERRORS
+	x =  PyInt_FromLong((long) AL_NO_ERRORS);
+	if (x == NULL || PyDict_SetItemString(d, "NO_ERRORS", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_NO_OP
+	x =  PyInt_FromLong((long) AL_NO_OP);
+	if (x == NULL || PyDict_SetItemString(d, "NO_OP", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_NO_VAL
+	x =  PyInt_FromLong((long) AL_NO_VAL);
+	if (x == NULL || PyDict_SetItemString(d, "NO_VAL", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_NULL_INTERFACE
+	x =  PyInt_FromLong((long) AL_NULL_INTERFACE);
+	if (x == NULL || PyDict_SetItemString(d, "NULL_INTERFACE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_NULL_RESOURCE
+	x =  PyInt_FromLong((long) AL_NULL_RESOURCE);
+	if (x == NULL || PyDict_SetItemString(d, "NULL_RESOURCE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_OPTICAL_IF_TYPE
+	x =  PyInt_FromLong((long) AL_OPTICAL_IF_TYPE);
+	if (x == NULL || PyDict_SetItemString(d, "OPTICAL_IF_TYPE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_OUTPUT_COUNT
+	x =  PyInt_FromLong((long) AL_OUTPUT_COUNT);
+	if (x == NULL || PyDict_SetItemString(d, "OUTPUT_COUNT", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_OUTPUT_DEVICE_TYPE
+	x =  PyInt_FromLong((long) AL_OUTPUT_DEVICE_TYPE);
+	if (x == NULL || PyDict_SetItemString(d, "OUTPUT_DEVICE_TYPE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_OUTPUT_HRB_TYPE
+	x =  PyInt_FromLong((long) AL_OUTPUT_HRB_TYPE);
+	if (x == NULL || PyDict_SetItemString(d, "OUTPUT_HRB_TYPE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_OUTPUT_PORT_TYPE
+	x =  PyInt_FromLong((long) AL_OUTPUT_PORT_TYPE);
+	if (x == NULL || PyDict_SetItemString(d, "OUTPUT_PORT_TYPE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_OUTPUT_RATE
+	x =  PyInt_FromLong((long) AL_OUTPUT_RATE);
+	if (x == NULL || PyDict_SetItemString(d, "OUTPUT_RATE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_PARAM_BIT
+	x =  PyInt_FromLong((long) AL_PARAM_BIT);
+	if (x == NULL || PyDict_SetItemString(d, "PARAM_BIT", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_PARAMS
+	x =  PyInt_FromLong((long) AL_PARAMS);
+	if (x == NULL || PyDict_SetItemString(d, "PARAMS", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_PORT_COUNT
+	x =  PyInt_FromLong((long) AL_PORT_COUNT);
+	if (x == NULL || PyDict_SetItemString(d, "PORT_COUNT", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_PORT_TYPE
+	x =  PyInt_FromLong((long) AL_PORT_TYPE);
+	if (x == NULL || PyDict_SetItemString(d, "PORT_TYPE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_PORTS
+	x =  PyInt_FromLong((long) AL_PORTS);
+	if (x == NULL || PyDict_SetItemString(d, "PORTS", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_PORTSTYLE_DIRECT
+	x =  PyInt_FromLong((long) AL_PORTSTYLE_DIRECT);
+	if (x == NULL || PyDict_SetItemString(d, "PORTSTYLE_DIRECT", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_PORTSTYLE_SERIAL
+	x =  PyInt_FromLong((long) AL_PORTSTYLE_SERIAL);
+	if (x == NULL || PyDict_SetItemString(d, "PORTSTYLE_SERIAL", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_PRINT_ERRORS
+	x =  PyInt_FromLong((long) AL_PRINT_ERRORS);
+	if (x == NULL || PyDict_SetItemString(d, "PRINT_ERRORS", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_PTR_ELEM
+	x =  PyInt_FromLong((long) AL_PTR_ELEM);
+	if (x == NULL || PyDict_SetItemString(d, "PTR_ELEM", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_RANGE_VALUE
+	x =  PyInt_FromLong((long) AL_RANGE_VALUE);
+	if (x == NULL || PyDict_SetItemString(d, "RANGE_VALUE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_RATE
+	x =  PyInt_FromLong((long) AL_RATE);
+	if (x == NULL || PyDict_SetItemString(d, "RATE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_RATE_11025
+	x =  PyInt_FromLong((long) AL_RATE_11025);
+	if (x == NULL || PyDict_SetItemString(d, "RATE_11025", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_RATE_16000
+	x =  PyInt_FromLong((long) AL_RATE_16000);
+	if (x == NULL || PyDict_SetItemString(d, "RATE_16000", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_RATE_22050
+	x =  PyInt_FromLong((long) AL_RATE_22050);
+	if (x == NULL || PyDict_SetItemString(d, "RATE_22050", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_RATE_32000
+	x =  PyInt_FromLong((long) AL_RATE_32000);
+	if (x == NULL || PyDict_SetItemString(d, "RATE_32000", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_RATE_44100
+	x =  PyInt_FromLong((long) AL_RATE_44100);
+	if (x == NULL || PyDict_SetItemString(d, "RATE_44100", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_RATE_48000
+	x =  PyInt_FromLong((long) AL_RATE_48000);
+	if (x == NULL || PyDict_SetItemString(d, "RATE_48000", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_RATE_8000
+	x =  PyInt_FromLong((long) AL_RATE_8000);
+	if (x == NULL || PyDict_SetItemString(d, "RATE_8000", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_RATE_AES_1
+	x =  PyInt_FromLong((long) AL_RATE_AES_1);
+	if (x == NULL || PyDict_SetItemString(d, "RATE_AES_1", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_RATE_AES_1s
+	x =  PyInt_FromLong((long) AL_RATE_AES_1s);
+	if (x == NULL || PyDict_SetItemString(d, "RATE_AES_1s", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_RATE_AES_2
+	x =  PyInt_FromLong((long) AL_RATE_AES_2);
+	if (x == NULL || PyDict_SetItemString(d, "RATE_AES_2", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_RATE_AES_3
+	x =  PyInt_FromLong((long) AL_RATE_AES_3);
+	if (x == NULL || PyDict_SetItemString(d, "RATE_AES_3", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_RATE_AES_4
+	x =  PyInt_FromLong((long) AL_RATE_AES_4);
+	if (x == NULL || PyDict_SetItemString(d, "RATE_AES_4", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_RATE_AES_6
+	x =  PyInt_FromLong((long) AL_RATE_AES_6);
+	if (x == NULL || PyDict_SetItemString(d, "RATE_AES_6", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_RATE_FRACTION_D
+	x =  PyInt_FromLong((long) AL_RATE_FRACTION_D);
+	if (x == NULL || PyDict_SetItemString(d, "RATE_FRACTION_D", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_RATE_FRACTION_N
+	x =  PyInt_FromLong((long) AL_RATE_FRACTION_N);
+	if (x == NULL || PyDict_SetItemString(d, "RATE_FRACTION_N", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_RATE_INPUTRATE
+	x =  PyInt_FromLong((long) AL_RATE_INPUTRATE);
+	if (x == NULL || PyDict_SetItemString(d, "RATE_INPUTRATE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_RATE_NO_DIGITAL_INPUT
+	x =  PyInt_FromLong((long) AL_RATE_NO_DIGITAL_INPUT);
+	if (x == NULL || PyDict_SetItemString(d, "RATE_NO_DIGITAL_INPUT", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_RATE_UNACQUIRED
+	x =  PyInt_FromLong((long) AL_RATE_UNACQUIRED);
+	if (x == NULL || PyDict_SetItemString(d, "RATE_UNACQUIRED", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_RATE_UNDEFINED
+	x =  PyInt_FromLong((long) AL_RATE_UNDEFINED);
+	if (x == NULL || PyDict_SetItemString(d, "RATE_UNDEFINED", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_REF_0DBV
+	x =  PyInt_FromLong((long) AL_REF_0DBV);
+	if (x == NULL || PyDict_SetItemString(d, "REF_0DBV", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_REF_NONE
+	x =  PyInt_FromLong((long) AL_REF_NONE);
+	if (x == NULL || PyDict_SetItemString(d, "REF_NONE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_RESERVED1_TYPE
+	x =  PyInt_FromLong((long) AL_RESERVED1_TYPE);
+	if (x == NULL || PyDict_SetItemString(d, "RESERVED1_TYPE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_RESERVED2_TYPE
+	x =  PyInt_FromLong((long) AL_RESERVED2_TYPE);
+	if (x == NULL || PyDict_SetItemString(d, "RESERVED2_TYPE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_RESERVED3_TYPE
+	x =  PyInt_FromLong((long) AL_RESERVED3_TYPE);
+	if (x == NULL || PyDict_SetItemString(d, "RESERVED3_TYPE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_RESERVED4_TYPE
+	x =  PyInt_FromLong((long) AL_RESERVED4_TYPE);
+	if (x == NULL || PyDict_SetItemString(d, "RESERVED4_TYPE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_RESOURCE
+	x =  PyInt_FromLong((long) AL_RESOURCE);
+	if (x == NULL || PyDict_SetItemString(d, "RESOURCE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_RESOURCE_ELEM
+	x =  PyInt_FromLong((long) AL_RESOURCE_ELEM);
+	if (x == NULL || PyDict_SetItemString(d, "RESOURCE_ELEM", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_RESOURCE_TYPE
+	x =  PyInt_FromLong((long) AL_RESOURCE_TYPE);
+	if (x == NULL || PyDict_SetItemString(d, "RESOURCE_TYPE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_RIGHT_INPUT_ATTEN
+	x =  PyInt_FromLong((long) AL_RIGHT_INPUT_ATTEN);
+	if (x == NULL || PyDict_SetItemString(d, "RIGHT_INPUT_ATTEN", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_RIGHT_MONITOR_ATTEN
+	x =  PyInt_FromLong((long) AL_RIGHT_MONITOR_ATTEN);
+	if (x == NULL || PyDict_SetItemString(d, "RIGHT_MONITOR_ATTEN", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_RIGHT_SPEAKER_GAIN
+	x =  PyInt_FromLong((long) AL_RIGHT_SPEAKER_GAIN);
+	if (x == NULL || PyDict_SetItemString(d, "RIGHT_SPEAKER_GAIN", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_RIGHT1_INPUT_ATTEN
+	x =  PyInt_FromLong((long) AL_RIGHT1_INPUT_ATTEN);
+	if (x == NULL || PyDict_SetItemString(d, "RIGHT1_INPUT_ATTEN", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_RIGHT2_INPUT_ATTEN
+	x =  PyInt_FromLong((long) AL_RIGHT2_INPUT_ATTEN);
+	if (x == NULL || PyDict_SetItemString(d, "RIGHT2_INPUT_ATTEN", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_SAMPFMT_DOUBLE
+	x =  PyInt_FromLong((long) AL_SAMPFMT_DOUBLE);
+	if (x == NULL || PyDict_SetItemString(d, "SAMPFMT_DOUBLE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_SAMPFMT_FLOAT
+	x =  PyInt_FromLong((long) AL_SAMPFMT_FLOAT);
+	if (x == NULL || PyDict_SetItemString(d, "SAMPFMT_FLOAT", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_SAMPFMT_TWOSCOMP
+	x =  PyInt_FromLong((long) AL_SAMPFMT_TWOSCOMP);
+	if (x == NULL || PyDict_SetItemString(d, "SAMPFMT_TWOSCOMP", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_SAMPLE_16
+	x =  PyInt_FromLong((long) AL_SAMPLE_16);
+	if (x == NULL || PyDict_SetItemString(d, "SAMPLE_16", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_SAMPLE_24
+	x =  PyInt_FromLong((long) AL_SAMPLE_24);
+	if (x == NULL || PyDict_SetItemString(d, "SAMPLE_24", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_SAMPLE_8
+	x =  PyInt_FromLong((long) AL_SAMPLE_8);
+	if (x == NULL || PyDict_SetItemString(d, "SAMPLE_8", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_SCALAR_VAL
+	x =  PyInt_FromLong((long) AL_SCALAR_VAL);
+	if (x == NULL || PyDict_SetItemString(d, "SCALAR_VAL", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_SET_VAL
+	x =  PyInt_FromLong((long) AL_SET_VAL);
+	if (x == NULL || PyDict_SetItemString(d, "SET_VAL", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_SHORT_NAME
+	x =  PyInt_FromLong((long) AL_SHORT_NAME);
+	if (x == NULL || PyDict_SetItemString(d, "SHORT_NAME", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_SMPTE272M_IF_TYPE
+	x =  PyInt_FromLong((long) AL_SMPTE272M_IF_TYPE);
+	if (x == NULL || PyDict_SetItemString(d, "SMPTE272M_IF_TYPE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_SOURCE
+	x =  PyInt_FromLong((long) AL_SOURCE);
+	if (x == NULL || PyDict_SetItemString(d, "SOURCE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_SPEAKER_IF_TYPE
+	x =  PyInt_FromLong((long) AL_SPEAKER_IF_TYPE);
+	if (x == NULL || PyDict_SetItemString(d, "SPEAKER_IF_TYPE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_SPEAKER_MUTE_CTL
+	x =  PyInt_FromLong((long) AL_SPEAKER_MUTE_CTL);
+	if (x == NULL || PyDict_SetItemString(d, "SPEAKER_MUTE_CTL", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_SPEAKER_MUTE_OFF
+	x =  PyInt_FromLong((long) AL_SPEAKER_MUTE_OFF);
+	if (x == NULL || PyDict_SetItemString(d, "SPEAKER_MUTE_OFF", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_SPEAKER_MUTE_ON
+	x =  PyInt_FromLong((long) AL_SPEAKER_MUTE_ON);
+	if (x == NULL || PyDict_SetItemString(d, "SPEAKER_MUTE_ON", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_SPEAKER_PLUS_LINE_IF_TYPE
+	x =  PyInt_FromLong((long) AL_SPEAKER_PLUS_LINE_IF_TYPE);
+	if (x == NULL || PyDict_SetItemString(d, "SPEAKER_PLUS_LINE_IF_TYPE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_STEREO
+	x =  PyInt_FromLong((long) AL_STEREO);
+	if (x == NULL || PyDict_SetItemString(d, "STEREO", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_STRING_VAL
+	x =  PyInt_FromLong((long) AL_STRING_VAL);
+	if (x == NULL || PyDict_SetItemString(d, "STRING_VAL", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_SUBSYSTEM
+	x =  PyInt_FromLong((long) AL_SUBSYSTEM);
+	if (x == NULL || PyDict_SetItemString(d, "SUBSYSTEM", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_SUBSYSTEM_TYPE
+	x =  PyInt_FromLong((long) AL_SUBSYSTEM_TYPE);
+	if (x == NULL || PyDict_SetItemString(d, "SUBSYSTEM_TYPE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_SYNC_INPUT_TO_AES
+	x =  PyInt_FromLong((long) AL_SYNC_INPUT_TO_AES);
+	if (x == NULL || PyDict_SetItemString(d, "SYNC_INPUT_TO_AES", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_SYNC_OUTPUT_TO_AES
+	x =  PyInt_FromLong((long) AL_SYNC_OUTPUT_TO_AES);
+	if (x == NULL || PyDict_SetItemString(d, "SYNC_OUTPUT_TO_AES", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_SYSTEM
+	x =  PyInt_FromLong((long) AL_SYSTEM);
+	if (x == NULL || PyDict_SetItemString(d, "SYSTEM", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_SYSTEM_TYPE
+	x =  PyInt_FromLong((long) AL_SYSTEM_TYPE);
+	if (x == NULL || PyDict_SetItemString(d, "SYSTEM_TYPE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_TEST_IF_TYPE
+	x =  PyInt_FromLong((long) AL_TEST_IF_TYPE);
+	if (x == NULL || PyDict_SetItemString(d, "TEST_IF_TYPE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_TYPE
+	x =  PyInt_FromLong((long) AL_TYPE);
+	if (x == NULL || PyDict_SetItemString(d, "TYPE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_TYPE_BIT
+	x =  PyInt_FromLong((long) AL_TYPE_BIT);
+	if (x == NULL || PyDict_SetItemString(d, "TYPE_BIT", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_UNUSED_COUNT
+	x =  PyInt_FromLong((long) AL_UNUSED_COUNT);
+	if (x == NULL || PyDict_SetItemString(d, "UNUSED_COUNT", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_UNUSED_PORTS
+	x =  PyInt_FromLong((long) AL_UNUSED_PORTS);
+	if (x == NULL || PyDict_SetItemString(d, "UNUSED_PORTS", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_VARIABLE_MCLK_TYPE
+	x =  PyInt_FromLong((long) AL_VARIABLE_MCLK_TYPE);
+	if (x == NULL || PyDict_SetItemString(d, "VARIABLE_MCLK_TYPE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_VECTOR_VAL
+	x =  PyInt_FromLong((long) AL_VECTOR_VAL);
+	if (x == NULL || PyDict_SetItemString(d, "VECTOR_VAL", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_VIDEO_MCLK_TYPE
+	x =  PyInt_FromLong((long) AL_VIDEO_MCLK_TYPE);
+	if (x == NULL || PyDict_SetItemString(d, "VIDEO_MCLK_TYPE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+#ifdef AL_WORDSIZE
+	x =  PyInt_FromLong((long) AL_WORDSIZE);
+	if (x == NULL || PyDict_SetItemString(d, "WORDSIZE", x) < 0)
+		goto error;
+	Py_DECREF(x);
+#endif
+
+#ifdef AL_NO_ELEM		/* IRIX 6 */
+	(void) alSetErrorHandler(ErrorHandler);
+#endif /* AL_NO_ELEM */
+#ifdef OLD_INTERFACE
+	(void) ALseterrorhandler(ErrorHandler);
+#endif /* OLD_INTERFACE */
+	
+  error:
+	return;
+}

Added: vendor/Python/current/Modules/ar_beos
===================================================================
--- vendor/Python/current/Modules/ar_beos	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/ar_beos	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,73 @@
+#!/bin/sh
+#
+#  Truly fake ar, using a directory to store object files.
+#
+#     Donn Cave, donn at oz.net
+
+usage='Usage: ar-fake cr libpython.dir obj.o ...
+       ar-fake d libpython.dir obj.o ...
+       ar-fake so libpython.dir libpython.so'
+
+case $# in
+0|1|2)
+        echo "$usage" >&2
+        exit 1
+        ;;
+esac
+
+command=$1
+library=$2
+shift 2
+
+case $command in
+cr)
+        if test -d $library
+        then :
+        else
+                mkdir $library
+        fi
+        if cp -p $* $library
+        then
+                #  To force directory modify date, create or delete a file.
+                if test -e $library/.tch
+                then rm $library/.tch
+                else echo tch > $library/.tch
+                fi
+                exit 0
+        fi
+        ;;
+d)
+        if test -d $library
+        then
+                cd $library
+                rm -f $*
+        fi
+        ;;
+so)
+        case $BE_HOST_CPU in
+        ppc)
+                #  In case your libpython.a refers to any exotic libraries,
+                #  mwld needs to know that here.  The following hack makes
+                #  a couple of assumptions about Modules/Makefile.  If it
+                #  doesn't work, you may as well add the necessary libraries
+                #  here explicitly instead.
+                extralibs=$(
+                        (cd Modules; make -f Makefile -n link) |
+                        sed -n 's/.*\.so \(.*\) -o python.*/\1/p'
+                )
+                mwld -xms -export pragma -nodup -o $1 $library/* $extralibs
+                ;;
+        x86)
+                ld -shared -soname $(basename $1) -o $1 $library/*
+                ;;
+        esac
+        status=$?
+        cd $(dirname $1)
+        ln -sf $PWD lib
+        exit $status
+        ;;
+*)
+        echo "$usage" >&2
+        exit 1
+        ;;
+esac


Property changes on: vendor/Python/current/Modules/ar_beos
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Modules/arraymodule.c
===================================================================
--- vendor/Python/current/Modules/arraymodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/arraymodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2141 @@
+/* Array object implementation */
+
+/* An array is a uniform list -- all items have the same type.
+   The item type is restricted to simple C types like int or float */
+
+#define PY_SSIZE_T_CLEAN
+#include "Python.h"
+#include "structmember.h"
+
+#ifdef STDC_HEADERS
+#include <stddef.h>
+#else /* !STDC_HEADERS */
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>		/* For size_t */
+#endif /* HAVE_SYS_TYPES_H */
+#endif /* !STDC_HEADERS */
+
+struct arrayobject; /* Forward */
+
+/* All possible arraydescr values are defined in the vector "descriptors"
+ * below.  That's defined later because the appropriate get and set
+ * functions aren't visible yet.
+ */
+struct arraydescr {
+	int typecode;
+	int itemsize;
+	PyObject * (*getitem)(struct arrayobject *, Py_ssize_t);
+	int (*setitem)(struct arrayobject *, Py_ssize_t, PyObject *);
+};
+
+typedef struct arrayobject {
+	PyObject_VAR_HEAD
+	char *ob_item;
+	Py_ssize_t allocated;
+	struct arraydescr *ob_descr;
+	PyObject *weakreflist; /* List of weak references */
+} arrayobject;
+
+static PyTypeObject Arraytype;
+
+#define array_Check(op) PyObject_TypeCheck(op, &Arraytype)
+#define array_CheckExact(op) ((op)->ob_type == &Arraytype)
+
+static int
+array_resize(arrayobject *self, Py_ssize_t newsize)
+{
+	char *items;
+	size_t _new_size;
+
+	/* Bypass realloc() when a previous overallocation is large enough
+	   to accommodate the newsize.  If the newsize is 16 smaller than the
+	   current size, then proceed with the realloc() to shrink the list.
+	*/
+
+	if (self->allocated >= newsize &&
+	    self->ob_size < newsize + 16 &&
+	    self->ob_item != NULL) {
+		self->ob_size = newsize;
+		return 0;
+	}
+
+	/* This over-allocates proportional to the array size, making room
+	 * for additional growth.  The over-allocation is mild, but is
+	 * enough to give linear-time amortized behavior over a long
+	 * sequence of appends() in the presence of a poorly-performing
+	 * system realloc().
+	 * The growth pattern is:  0, 4, 8, 16, 25, 34, 46, 56, 67, 79, ...
+	 * Note, the pattern starts out the same as for lists but then
+	 * grows at a smaller rate so that larger arrays only overallocate
+	 * by about 1/16th -- this is done because arrays are presumed to be more
+	 * memory critical.
+	 */
+
+	_new_size = (newsize >> 4) + (self->ob_size < 8 ? 3 : 7) + newsize;
+	items = self->ob_item;
+	/* XXX The following multiplication and division does not optimize away 
+	   like it does for lists since the size is not known at compile time */
+	if (_new_size <= ((~(size_t)0) / self->ob_descr->itemsize))
+		PyMem_RESIZE(items, char, (_new_size * self->ob_descr->itemsize));
+	else
+		items = NULL;
+	if (items == NULL) {
+		PyErr_NoMemory();
+		return -1;
+	}
+	self->ob_item = items;
+	self->ob_size = newsize;
+	self->allocated = _new_size;
+	return 0;
+}
+
+/****************************************************************************
+Get and Set functions for each type.
+A Get function takes an arrayobject* and an integer index, returning the
+array value at that index wrapped in an appropriate PyObject*.
+A Set function takes an arrayobject, integer index, and PyObject*; sets
+the array value at that index to the raw C data extracted from the PyObject*,
+and returns 0 if successful, else nonzero on failure (PyObject* not of an
+appropriate type or value).
+Note that the basic Get and Set functions do NOT check that the index is
+in bounds; that's the responsibility of the caller.
+****************************************************************************/
+
+static PyObject *
+c_getitem(arrayobject *ap, Py_ssize_t i)
+{
+	return PyString_FromStringAndSize(&((char *)ap->ob_item)[i], 1);
+}
+
+static int
+c_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
+{
+	char x;
+	if (!PyArg_Parse(v, "c;array item must be char", &x))
+		return -1;
+	if (i >= 0)
+		((char *)ap->ob_item)[i] = x;
+	return 0;
+}
+
+static PyObject *
+b_getitem(arrayobject *ap, Py_ssize_t i)
+{
+	long x = ((char *)ap->ob_item)[i];
+	if (x >= 128)
+		x -= 256;
+	return PyInt_FromLong(x);
+}
+
+static int
+b_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
+{
+	short x;
+	/* PyArg_Parse's 'b' formatter is for an unsigned char, therefore
+	   must use the next size up that is signed ('h') and manually do
+	   the overflow checking */
+	if (!PyArg_Parse(v, "h;array item must be integer", &x))
+		return -1;
+	else if (x < -128) {
+		PyErr_SetString(PyExc_OverflowError,
+			"signed char is less than minimum");
+		return -1;
+	}
+	else if (x > 127) {
+		PyErr_SetString(PyExc_OverflowError,
+			"signed char is greater than maximum");
+		return -1;
+	}
+	if (i >= 0)
+		((char *)ap->ob_item)[i] = (char)x;
+	return 0;
+}
+
+static PyObject *
+BB_getitem(arrayobject *ap, Py_ssize_t i)
+{
+	long x = ((unsigned char *)ap->ob_item)[i];
+	return PyInt_FromLong(x);
+}
+
+static int
+BB_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
+{
+	unsigned char x;
+	/* 'B' == unsigned char, maps to PyArg_Parse's 'b' formatter */
+	if (!PyArg_Parse(v, "b;array item must be integer", &x))
+		return -1;
+	if (i >= 0)
+		((char *)ap->ob_item)[i] = x;
+	return 0;
+}
+
+#ifdef Py_USING_UNICODE
+static PyObject *
+u_getitem(arrayobject *ap, Py_ssize_t i)
+{
+	return PyUnicode_FromUnicode(&((Py_UNICODE *) ap->ob_item)[i], 1);
+}
+
+static int
+u_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
+{
+	Py_UNICODE *p;
+	Py_ssize_t len;
+
+	if (!PyArg_Parse(v, "u#;array item must be unicode character", &p, &len))
+		return -1;
+	if (len != 1) {
+		PyErr_SetString(PyExc_TypeError,
+				"array item must be unicode character");
+		return -1;
+	}
+	if (i >= 0)
+		((Py_UNICODE *)ap->ob_item)[i] = p[0];
+	return 0;
+}
+#endif
+
+static PyObject *
+h_getitem(arrayobject *ap, Py_ssize_t i)
+{
+	return PyInt_FromLong((long) ((short *)ap->ob_item)[i]);
+}
+
+static int
+h_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
+{
+	short x;
+	/* 'h' == signed short, maps to PyArg_Parse's 'h' formatter */
+	if (!PyArg_Parse(v, "h;array item must be integer", &x))
+		return -1;
+	if (i >= 0)
+		     ((short *)ap->ob_item)[i] = x;
+	return 0;
+}
+
+static PyObject *
+HH_getitem(arrayobject *ap, Py_ssize_t i)
+{
+	return PyInt_FromLong((long) ((unsigned short *)ap->ob_item)[i]);
+}
+
+static int
+HH_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
+{
+	int x;
+	/* PyArg_Parse's 'h' formatter is for a signed short, therefore
+	   must use the next size up and manually do the overflow checking */
+	if (!PyArg_Parse(v, "i;array item must be integer", &x))
+		return -1;
+	else if (x < 0) {
+		PyErr_SetString(PyExc_OverflowError,
+			"unsigned short is less than minimum");
+		return -1;
+	}
+	else if (x > USHRT_MAX) {
+		PyErr_SetString(PyExc_OverflowError,
+			"unsigned short is greater than maximum");
+		return -1;
+	}
+	if (i >= 0)
+		((short *)ap->ob_item)[i] = (short)x;
+	return 0;
+}
+
+static PyObject *
+i_getitem(arrayobject *ap, Py_ssize_t i)
+{
+	return PyInt_FromLong((long) ((int *)ap->ob_item)[i]);
+}
+
+static int
+i_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
+{
+	int x;
+	/* 'i' == signed int, maps to PyArg_Parse's 'i' formatter */
+	if (!PyArg_Parse(v, "i;array item must be integer", &x))
+		return -1;
+	if (i >= 0)
+		     ((int *)ap->ob_item)[i] = x;
+	return 0;
+}
+
+static PyObject *
+II_getitem(arrayobject *ap, Py_ssize_t i)
+{
+	return PyLong_FromUnsignedLong(
+		(unsigned long) ((unsigned int *)ap->ob_item)[i]);
+}
+
+static int
+II_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
+{
+	unsigned long x;
+	if (PyLong_Check(v)) {
+		x = PyLong_AsUnsignedLong(v);
+		if (x == (unsigned long) -1 && PyErr_Occurred())
+			return -1;
+	}
+	else {
+		long y;
+		if (!PyArg_Parse(v, "l;array item must be integer", &y))
+			return -1;
+		if (y < 0) {
+			PyErr_SetString(PyExc_OverflowError,
+				"unsigned int is less than minimum");
+			return -1;
+		}
+		x = (unsigned long)y;
+
+	}
+	if (x > UINT_MAX) {
+		PyErr_SetString(PyExc_OverflowError,
+			"unsigned int is greater than maximum");
+		return -1;
+	}
+
+	if (i >= 0)
+		((unsigned int *)ap->ob_item)[i] = (unsigned int)x;
+	return 0;
+}
+
+static PyObject *
+l_getitem(arrayobject *ap, Py_ssize_t i)
+{
+	return PyInt_FromLong(((long *)ap->ob_item)[i]);
+}
+
+static int
+l_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
+{
+	long x;
+	if (!PyArg_Parse(v, "l;array item must be integer", &x))
+		return -1;
+	if (i >= 0)
+		     ((long *)ap->ob_item)[i] = x;
+	return 0;
+}
+
+static PyObject *
+LL_getitem(arrayobject *ap, Py_ssize_t i)
+{
+	return PyLong_FromUnsignedLong(((unsigned long *)ap->ob_item)[i]);
+}
+
+static int
+LL_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
+{
+	unsigned long x;
+	if (PyLong_Check(v)) {
+		x = PyLong_AsUnsignedLong(v);
+		if (x == (unsigned long) -1 && PyErr_Occurred())
+			return -1;
+	}
+	else {
+		long y;
+		if (!PyArg_Parse(v, "l;array item must be integer", &y))
+			return -1;
+		if (y < 0) {
+			PyErr_SetString(PyExc_OverflowError,
+				"unsigned long is less than minimum");
+			return -1;
+		}
+		x = (unsigned long)y;
+
+	}
+	if (x > ULONG_MAX) {
+		PyErr_SetString(PyExc_OverflowError,
+			"unsigned long is greater than maximum");
+		return -1;
+	}
+
+	if (i >= 0)
+		((unsigned long *)ap->ob_item)[i] = x;
+	return 0;
+}
+
+static PyObject *
+f_getitem(arrayobject *ap, Py_ssize_t i)
+{
+	return PyFloat_FromDouble((double) ((float *)ap->ob_item)[i]);
+}
+
+static int
+f_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
+{
+	float x;
+	if (!PyArg_Parse(v, "f;array item must be float", &x))
+		return -1;
+	if (i >= 0)
+		     ((float *)ap->ob_item)[i] = x;
+	return 0;
+}
+
+static PyObject *
+d_getitem(arrayobject *ap, Py_ssize_t i)
+{
+	return PyFloat_FromDouble(((double *)ap->ob_item)[i]);
+}
+
+static int
+d_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
+{
+	double x;
+	if (!PyArg_Parse(v, "d;array item must be float", &x))
+		return -1;
+	if (i >= 0)
+		     ((double *)ap->ob_item)[i] = x;
+	return 0;
+}
+
+/* Description of types */
+static struct arraydescr descriptors[] = {
+	{'c', sizeof(char), c_getitem, c_setitem},
+	{'b', sizeof(char), b_getitem, b_setitem},
+	{'B', sizeof(char), BB_getitem, BB_setitem},
+#ifdef Py_USING_UNICODE
+	{'u', sizeof(Py_UNICODE), u_getitem, u_setitem},
+#endif
+	{'h', sizeof(short), h_getitem, h_setitem},
+	{'H', sizeof(short), HH_getitem, HH_setitem},
+	{'i', sizeof(int), i_getitem, i_setitem},
+	{'I', sizeof(int), II_getitem, II_setitem},
+	{'l', sizeof(long), l_getitem, l_setitem},
+	{'L', sizeof(long), LL_getitem, LL_setitem},
+	{'f', sizeof(float), f_getitem, f_setitem},
+	{'d', sizeof(double), d_getitem, d_setitem},
+	{'\0', 0, 0, 0} /* Sentinel */
+};
+
+/****************************************************************************
+Implementations of array object methods.
+****************************************************************************/
+
+static PyObject *
+newarrayobject(PyTypeObject *type, Py_ssize_t size, struct arraydescr *descr)
+{
+	arrayobject *op;
+	size_t nbytes;
+
+	if (size < 0) {
+		PyErr_BadInternalCall();
+		return NULL;
+	}
+
+	nbytes = size * descr->itemsize;
+	/* Check for overflow */
+	if (nbytes / descr->itemsize != (size_t)size) {
+		return PyErr_NoMemory();
+	}
+	op = (arrayobject *) type->tp_alloc(type, 0);
+	if (op == NULL) {
+		return NULL;
+	}
+	op->ob_size = size;
+	if (size <= 0) {
+		op->ob_item = NULL;
+	}
+	else {
+		op->ob_item = PyMem_NEW(char, nbytes);
+		if (op->ob_item == NULL) {
+			PyObject_Del(op);
+			return PyErr_NoMemory();
+		}
+	}
+	op->ob_descr = descr;
+	op->allocated = size;
+	op->weakreflist = NULL;
+	return (PyObject *) op;
+}
+
+static PyObject *
+getarrayitem(PyObject *op, Py_ssize_t i)
+{
+	register arrayobject *ap;
+	assert(array_Check(op));
+	ap = (arrayobject *)op;
+	assert(i>=0 && i<ap->ob_size);
+	return (*ap->ob_descr->getitem)(ap, i);
+}
+
+static int
+ins1(arrayobject *self, Py_ssize_t where, PyObject *v)
+{
+	char *items;
+	Py_ssize_t n = self->ob_size;
+	if (v == NULL) {
+		PyErr_BadInternalCall();
+		return -1;
+	}
+	if ((*self->ob_descr->setitem)(self, -1, v) < 0)
+		return -1;
+
+	if (array_resize(self, n+1) == -1)
+		return -1;
+	items = self->ob_item;
+	if (where < 0) {
+		where += n;
+		if (where < 0)
+			where = 0;
+	}
+	if (where > n)
+		where = n;
+	/* appends don't need to call memmove() */
+	if (where != n)
+		memmove(items + (where+1)*self->ob_descr->itemsize,
+			items + where*self->ob_descr->itemsize,
+			(n-where)*self->ob_descr->itemsize);
+	return (*self->ob_descr->setitem)(self, where, v);
+}
+
+/* Methods */
+
+static void
+array_dealloc(arrayobject *op)
+{
+	if (op->weakreflist != NULL)
+		PyObject_ClearWeakRefs((PyObject *) op);
+	if (op->ob_item != NULL)
+		PyMem_DEL(op->ob_item);
+	op->ob_type->tp_free((PyObject *)op);
+}
+
+static PyObject *
+array_richcompare(PyObject *v, PyObject *w, int op)
+{
+	arrayobject *va, *wa;
+	PyObject *vi = NULL;
+	PyObject *wi = NULL;
+	Py_ssize_t i, k;
+	PyObject *res;
+
+	if (!array_Check(v) || !array_Check(w)) {
+		Py_INCREF(Py_NotImplemented);
+		return Py_NotImplemented;
+	}
+
+	va = (arrayobject *)v;
+	wa = (arrayobject *)w;
+
+	if (va->ob_size != wa->ob_size && (op == Py_EQ || op == Py_NE)) {
+		/* Shortcut: if the lengths differ, the arrays differ */
+		if (op == Py_EQ)
+			res = Py_False;
+		else
+			res = Py_True;
+		Py_INCREF(res);
+		return res;
+	}
+
+	/* Search for the first index where items are different */
+	k = 1;
+	for (i = 0; i < va->ob_size && i < wa->ob_size; i++) {
+		vi = getarrayitem(v, i);
+		wi = getarrayitem(w, i);
+		if (vi == NULL || wi == NULL) {
+			Py_XDECREF(vi);
+			Py_XDECREF(wi);
+			return NULL;
+		}
+		k = PyObject_RichCompareBool(vi, wi, Py_EQ);
+		if (k == 0)
+			break; /* Keeping vi and wi alive! */
+		Py_DECREF(vi);
+		Py_DECREF(wi);
+		if (k < 0)
+			return NULL;
+	}
+
+	if (k) {
+		/* No more items to compare -- compare sizes */
+		Py_ssize_t vs = va->ob_size;
+		Py_ssize_t ws = wa->ob_size;
+		int cmp;
+		switch (op) {
+		case Py_LT: cmp = vs <  ws; break;
+		case Py_LE: cmp = vs <= ws; break;
+		case Py_EQ: cmp = vs == ws; break;
+		case Py_NE: cmp = vs != ws; break;
+		case Py_GT: cmp = vs >  ws; break;
+		case Py_GE: cmp = vs >= ws; break;
+		default: return NULL; /* cannot happen */
+		}
+		if (cmp)
+			res = Py_True;
+		else
+			res = Py_False;
+		Py_INCREF(res);
+		return res;
+	}
+
+	/* We have an item that differs.  First, shortcuts for EQ/NE */
+	if (op == Py_EQ) {
+		Py_INCREF(Py_False);
+		res = Py_False;
+	}
+	else if (op == Py_NE) {
+		Py_INCREF(Py_True);
+		res = Py_True;
+	}
+	else {
+		/* Compare the final item again using the proper operator */
+		res = PyObject_RichCompare(vi, wi, op);
+	}
+	Py_DECREF(vi);
+	Py_DECREF(wi);
+	return res;
+}
+
+static Py_ssize_t
+array_length(arrayobject *a)
+{
+	return a->ob_size;
+}
+
+static PyObject *
+array_item(arrayobject *a, Py_ssize_t i)
+{
+	if (i < 0 || i >= a->ob_size) {
+		PyErr_SetString(PyExc_IndexError, "array index out of range");
+		return NULL;
+	}
+	return getarrayitem((PyObject *)a, i);
+}
+
+static PyObject *
+array_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t ihigh)
+{
+	arrayobject *np;
+	if (ilow < 0)
+		ilow = 0;
+	else if (ilow > a->ob_size)
+		ilow = a->ob_size;
+	if (ihigh < 0)
+		ihigh = 0;
+	if (ihigh < ilow)
+		ihigh = ilow;
+	else if (ihigh > a->ob_size)
+		ihigh = a->ob_size;
+	np = (arrayobject *) newarrayobject(&Arraytype, ihigh - ilow, a->ob_descr);
+	if (np == NULL)
+		return NULL;
+	memcpy(np->ob_item, a->ob_item + ilow * a->ob_descr->itemsize,
+	       (ihigh-ilow) * a->ob_descr->itemsize);
+	return (PyObject *)np;
+}
+
+static PyObject *
+array_copy(arrayobject *a, PyObject *unused)
+{
+	return array_slice(a, 0, a->ob_size);
+}
+
+PyDoc_STRVAR(copy_doc,
+"copy(array)\n\
+\n\
+ Return a copy of the array.");
+
+static PyObject *
+array_concat(arrayobject *a, PyObject *bb)
+{
+	Py_ssize_t size;
+	arrayobject *np;
+	if (!array_Check(bb)) {
+		PyErr_Format(PyExc_TypeError,
+		     "can only append array (not \"%.200s\") to array",
+			     bb->ob_type->tp_name);
+		return NULL;
+	}
+#define b ((arrayobject *)bb)
+	if (a->ob_descr != b->ob_descr) {
+		PyErr_BadArgument();
+		return NULL;
+	}
+	size = a->ob_size + b->ob_size;
+	np = (arrayobject *) newarrayobject(&Arraytype, size, a->ob_descr);
+	if (np == NULL) {
+		return NULL;
+	}
+	memcpy(np->ob_item, a->ob_item, a->ob_size*a->ob_descr->itemsize);
+	memcpy(np->ob_item + a->ob_size*a->ob_descr->itemsize,
+	       b->ob_item, b->ob_size*b->ob_descr->itemsize);
+	return (PyObject *)np;
+#undef b
+}
+
+static PyObject *
+array_repeat(arrayobject *a, Py_ssize_t n)
+{
+	Py_ssize_t i;
+	Py_ssize_t size;
+	arrayobject *np;
+	char *p;
+	Py_ssize_t nbytes;
+	if (n < 0)
+		n = 0;
+	size = a->ob_size * n;
+	np = (arrayobject *) newarrayobject(&Arraytype, size, a->ob_descr);
+	if (np == NULL)
+		return NULL;
+	p = np->ob_item;
+	nbytes = a->ob_size * a->ob_descr->itemsize;
+	for (i = 0; i < n; i++) {
+		memcpy(p, a->ob_item, nbytes);
+		p += nbytes;
+	}
+	return (PyObject *) np;
+}
+
+static int
+array_ass_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v)
+{
+	char *item;
+	Py_ssize_t n; /* Size of replacement array */
+	Py_ssize_t d; /* Change in size */
+#define b ((arrayobject *)v)
+	if (v == NULL)
+		n = 0;
+	else if (array_Check(v)) {
+		n = b->ob_size;
+		if (a == b) {
+			/* Special case "a[i:j] = a" -- copy b first */
+			int ret;
+			v = array_slice(b, 0, n);
+			if (!v)
+				return -1;
+			ret = array_ass_slice(a, ilow, ihigh, v);
+			Py_DECREF(v);
+			return ret;
+		}
+		if (b->ob_descr != a->ob_descr) {
+			PyErr_BadArgument();
+			return -1;
+		}
+	}
+	else {
+		PyErr_Format(PyExc_TypeError,
+	     "can only assign array (not \"%.200s\") to array slice",
+			     v->ob_type->tp_name);
+		return -1;
+	}
+	if (ilow < 0)
+		ilow = 0;
+	else if (ilow > a->ob_size)
+		ilow = a->ob_size;
+	if (ihigh < 0)
+		ihigh = 0;
+	if (ihigh < ilow)
+		ihigh = ilow;
+	else if (ihigh > a->ob_size)
+		ihigh = a->ob_size;
+	item = a->ob_item;
+	d = n - (ihigh-ilow);
+	if (d < 0) { /* Delete -d items */
+		memmove(item + (ihigh+d)*a->ob_descr->itemsize,
+			item + ihigh*a->ob_descr->itemsize,
+			(a->ob_size-ihigh)*a->ob_descr->itemsize);
+		a->ob_size += d;
+		PyMem_RESIZE(item, char, a->ob_size*a->ob_descr->itemsize);
+						/* Can't fail */
+		a->ob_item = item;
+		a->allocated = a->ob_size;
+	}
+	else if (d > 0) { /* Insert d items */
+		PyMem_RESIZE(item, char,
+			     (a->ob_size + d)*a->ob_descr->itemsize);
+		if (item == NULL) {
+			PyErr_NoMemory();
+			return -1;
+		}
+		memmove(item + (ihigh+d)*a->ob_descr->itemsize,
+			item + ihigh*a->ob_descr->itemsize,
+			(a->ob_size-ihigh)*a->ob_descr->itemsize);
+		a->ob_item = item;
+		a->ob_size += d;
+		a->allocated = a->ob_size;
+	}
+	if (n > 0)
+		memcpy(item + ilow*a->ob_descr->itemsize, b->ob_item,
+		       n*b->ob_descr->itemsize);
+	return 0;
+#undef b
+}
+
+static int
+array_ass_item(arrayobject *a, Py_ssize_t i, PyObject *v)
+{
+	if (i < 0 || i >= a->ob_size) {
+		PyErr_SetString(PyExc_IndexError,
+			         "array assignment index out of range");
+		return -1;
+	}
+	if (v == NULL)
+		return array_ass_slice(a, i, i+1, v);
+	return (*a->ob_descr->setitem)(a, i, v);
+}
+
+static int
+setarrayitem(PyObject *a, Py_ssize_t i, PyObject *v)
+{
+	assert(array_Check(a));
+	return array_ass_item((arrayobject *)a, i, v);
+}
+
+static int
+array_iter_extend(arrayobject *self, PyObject *bb)
+{
+	PyObject *it, *v;
+
+	it = PyObject_GetIter(bb);
+	if (it == NULL)
+		return -1;
+
+	while ((v = PyIter_Next(it)) != NULL) {
+		if (ins1(self, (int) self->ob_size, v) != 0) {
+			Py_DECREF(v);
+			Py_DECREF(it);
+			return -1;
+		}
+		Py_DECREF(v);
+	}
+	Py_DECREF(it);
+	if (PyErr_Occurred())
+		return -1;
+	return 0;
+}
+
+static int
+array_do_extend(arrayobject *self, PyObject *bb)
+{
+	Py_ssize_t size;
+
+	if (!array_Check(bb))
+		return array_iter_extend(self, bb);
+#define b ((arrayobject *)bb)
+	if (self->ob_descr != b->ob_descr) {
+		PyErr_SetString(PyExc_TypeError,
+			     "can only extend with array of same kind");
+		return -1;
+	}
+	size = self->ob_size + b->ob_size;
+        PyMem_RESIZE(self->ob_item, char, size*self->ob_descr->itemsize);
+        if (self->ob_item == NULL) {
+                PyObject_Del(self);
+                PyErr_NoMemory();
+		return -1;
+        }
+	memcpy(self->ob_item + self->ob_size*self->ob_descr->itemsize,
+               b->ob_item, b->ob_size*b->ob_descr->itemsize);
+	self->ob_size = size;
+	self->allocated = size;
+
+	return 0;
+#undef b
+}
+
+static PyObject *
+array_inplace_concat(arrayobject *self, PyObject *bb)
+{
+	if (!array_Check(bb)) {
+		PyErr_Format(PyExc_TypeError,
+			"can only extend array with array (not \"%.200s\")",
+			bb->ob_type->tp_name);
+		return NULL;
+	}
+	if (array_do_extend(self, bb) == -1)
+		return NULL;
+	Py_INCREF(self);
+	return (PyObject *)self;
+}
+
+static PyObject *
+array_inplace_repeat(arrayobject *self, Py_ssize_t n)
+{
+	char *items, *p;
+	Py_ssize_t size, i;
+
+	if (self->ob_size > 0) {
+		if (n < 0)
+			n = 0;
+		items = self->ob_item;
+		size = self->ob_size * self->ob_descr->itemsize;
+		if (n == 0) {
+			PyMem_FREE(items);
+			self->ob_item = NULL;
+			self->ob_size = 0;
+			self->allocated = 0;
+		}
+		else {
+			PyMem_Resize(items, char, n * size);
+			if (items == NULL)
+				return PyErr_NoMemory();
+			p = items;
+			for (i = 1; i < n; i++) {
+				p += size;
+				memcpy(p, items, size);
+			}
+			self->ob_item = items;
+			self->ob_size *= n;
+			self->allocated = self->ob_size;
+		}
+	}
+	Py_INCREF(self);
+	return (PyObject *)self;
+}
+
+
+static PyObject *
+ins(arrayobject *self, Py_ssize_t where, PyObject *v)
+{
+	if (ins1(self, where, v) != 0)
+		return NULL;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+array_count(arrayobject *self, PyObject *v)
+{
+	Py_ssize_t count = 0;
+	Py_ssize_t i;
+
+	for (i = 0; i < self->ob_size; i++) {
+		PyObject *selfi = getarrayitem((PyObject *)self, i);
+		int cmp = PyObject_RichCompareBool(selfi, v, Py_EQ);
+		Py_DECREF(selfi);
+		if (cmp > 0)
+			count++;
+		else if (cmp < 0)
+			return NULL;
+	}
+	return PyInt_FromSsize_t(count);
+}
+
+PyDoc_STRVAR(count_doc,
+"count(x)\n\
+\n\
+Return number of occurences of x in the array.");
+
+static PyObject *
+array_index(arrayobject *self, PyObject *v)
+{
+	Py_ssize_t i;
+
+	for (i = 0; i < self->ob_size; i++) {
+		PyObject *selfi = getarrayitem((PyObject *)self, i);
+		int cmp = PyObject_RichCompareBool(selfi, v, Py_EQ);
+		Py_DECREF(selfi);
+		if (cmp > 0) {
+			return PyInt_FromLong((long)i);
+		}
+		else if (cmp < 0)
+			return NULL;
+	}
+	PyErr_SetString(PyExc_ValueError, "array.index(x): x not in list");
+	return NULL;
+}
+
+PyDoc_STRVAR(index_doc,
+"index(x)\n\
+\n\
+Return index of first occurence of x in the array.");
+
+static int
+array_contains(arrayobject *self, PyObject *v)
+{
+	Py_ssize_t i;
+	int cmp;
+
+	for (i = 0, cmp = 0 ; cmp == 0 && i < self->ob_size; i++) {
+		PyObject *selfi = getarrayitem((PyObject *)self, i);
+		cmp = PyObject_RichCompareBool(selfi, v, Py_EQ);
+		Py_DECREF(selfi);
+	}
+	return cmp;
+}
+
+static PyObject *
+array_remove(arrayobject *self, PyObject *v)
+{
+	int i;
+
+	for (i = 0; i < self->ob_size; i++) {
+		PyObject *selfi = getarrayitem((PyObject *)self,i);
+		int cmp = PyObject_RichCompareBool(selfi, v, Py_EQ);
+		Py_DECREF(selfi);
+		if (cmp > 0) {
+			if (array_ass_slice(self, i, i+1,
+					   (PyObject *)NULL) != 0)
+				return NULL;
+			Py_INCREF(Py_None);
+			return Py_None;
+		}
+		else if (cmp < 0)
+			return NULL;
+	}
+	PyErr_SetString(PyExc_ValueError, "array.remove(x): x not in list");
+	return NULL;
+}
+
+PyDoc_STRVAR(remove_doc,
+"remove(x)\n\
+\n\
+Remove the first occurence of x in the array.");
+
+static PyObject *
+array_pop(arrayobject *self, PyObject *args)
+{
+	Py_ssize_t i = -1;
+	PyObject *v;
+	if (!PyArg_ParseTuple(args, "|n:pop", &i))
+		return NULL;
+	if (self->ob_size == 0) {
+		/* Special-case most common failure cause */
+		PyErr_SetString(PyExc_IndexError, "pop from empty array");
+		return NULL;
+	}
+	if (i < 0)
+		i += self->ob_size;
+	if (i < 0 || i >= self->ob_size) {
+		PyErr_SetString(PyExc_IndexError, "pop index out of range");
+		return NULL;
+	}
+	v = getarrayitem((PyObject *)self,i);
+	if (array_ass_slice(self, i, i+1, (PyObject *)NULL) != 0) {
+		Py_DECREF(v);
+		return NULL;
+	}
+	return v;
+}
+
+PyDoc_STRVAR(pop_doc,
+"pop([i])\n\
+\n\
+Return the i-th element and delete it from the array. i defaults to -1.");
+
+static PyObject *
+array_extend(arrayobject *self, PyObject *bb)
+{
+	if (array_do_extend(self, bb) == -1)
+		return NULL;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(extend_doc,
+"extend(array or iterable)\n\
+\n\
+ Append items to the end of the array.");
+
+static PyObject *
+array_insert(arrayobject *self, PyObject *args)
+{
+	Py_ssize_t i;
+	PyObject *v;
+        if (!PyArg_ParseTuple(args, "nO:insert", &i, &v))
+		return NULL;
+	return ins(self, i, v);
+}
+
+PyDoc_STRVAR(insert_doc,
+"insert(i,x)\n\
+\n\
+Insert a new item x into the array before position i.");
+
+
+static PyObject *
+array_buffer_info(arrayobject *self, PyObject *unused)
+{
+	PyObject* retval = NULL;
+	retval = PyTuple_New(2);
+	if (!retval)
+		return NULL;
+
+	PyTuple_SET_ITEM(retval, 0, PyLong_FromVoidPtr(self->ob_item));
+	PyTuple_SET_ITEM(retval, 1, PyInt_FromLong((long)(self->ob_size)));
+
+	return retval;
+}
+
+PyDoc_STRVAR(buffer_info_doc,
+"buffer_info() -> (address, length)\n\
+\n\
+Return a tuple (address, length) giving the current memory address and\n\
+the length in items of the buffer used to hold array's contents\n\
+The length should be multiplied by the itemsize attribute to calculate\n\
+the buffer length in bytes.");
+
+
+static PyObject *
+array_append(arrayobject *self, PyObject *v)
+{
+	return ins(self, (int) self->ob_size, v);
+}
+
+PyDoc_STRVAR(append_doc,
+"append(x)\n\
+\n\
+Append new value x to the end of the array.");
+
+
+static PyObject *
+array_byteswap(arrayobject *self, PyObject *unused)
+{
+	char *p;
+	Py_ssize_t i;
+
+	switch (self->ob_descr->itemsize) {
+	case 1:
+		break;
+	case 2:
+		for (p = self->ob_item, i = self->ob_size; --i >= 0; p += 2) {
+			char p0 = p[0];
+			p[0] = p[1];
+			p[1] = p0;
+		}
+		break;
+	case 4:
+		for (p = self->ob_item, i = self->ob_size; --i >= 0; p += 4) {
+			char p0 = p[0];
+			char p1 = p[1];
+			p[0] = p[3];
+			p[1] = p[2];
+			p[2] = p1;
+			p[3] = p0;
+		}
+		break;
+	case 8:
+		for (p = self->ob_item, i = self->ob_size; --i >= 0; p += 8) {
+			char p0 = p[0];
+			char p1 = p[1];
+			char p2 = p[2];
+			char p3 = p[3];
+			p[0] = p[7];
+			p[1] = p[6];
+			p[2] = p[5];
+			p[3] = p[4];
+			p[4] = p3;
+			p[5] = p2;
+			p[6] = p1;
+			p[7] = p0;
+		}
+		break;
+	default:
+		PyErr_SetString(PyExc_RuntimeError,
+			   "don't know how to byteswap this array type");
+		return NULL;
+	}
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(byteswap_doc,
+"byteswap()\n\
+\n\
+Byteswap all items of the array.  If the items in the array are not 1, 2,\n\
+4, or 8 bytes in size, RuntimeError is raised.");
+
+static PyObject *
+array_reduce(arrayobject *array)
+{
+	PyObject *dict, *result;
+
+	dict = PyObject_GetAttrString((PyObject *)array, "__dict__");
+	if (dict == NULL) {
+		PyErr_Clear();
+		dict = Py_None;
+		Py_INCREF(dict);
+	}
+	if (array->ob_size > 0) {
+		result = Py_BuildValue("O(cs#)O", 
+			array->ob_type, 
+			array->ob_descr->typecode,
+			array->ob_item,
+			array->ob_size * array->ob_descr->itemsize,
+			dict);
+	} else {
+		result = Py_BuildValue("O(c)O", 
+			array->ob_type, 
+			array->ob_descr->typecode,
+			dict);
+	}
+	Py_DECREF(dict);
+	return result;
+}
+
+PyDoc_STRVAR(array_doc, "Return state information for pickling.");
+
+static PyObject *
+array_reverse(arrayobject *self, PyObject *unused)
+{
+	register Py_ssize_t itemsize = self->ob_descr->itemsize;
+	register char *p, *q;
+	/* little buffer to hold items while swapping */
+	char tmp[256];	/* 8 is probably enough -- but why skimp */
+	assert((size_t)itemsize <= sizeof(tmp));
+
+	if (self->ob_size > 1) {
+		for (p = self->ob_item,
+		     q = self->ob_item + (self->ob_size - 1)*itemsize;
+		     p < q;
+		     p += itemsize, q -= itemsize) {
+			/* memory areas guaranteed disjoint, so memcpy
+			 * is safe (& memmove may be slower).
+			 */
+			memcpy(tmp, p, itemsize);
+			memcpy(p, q, itemsize);
+			memcpy(q, tmp, itemsize);
+		}
+	}
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(reverse_doc,
+"reverse()\n\
+\n\
+Reverse the order of the items in the array.");
+
+static PyObject *
+array_fromfile(arrayobject *self, PyObject *args)
+{
+	PyObject *f;
+	Py_ssize_t n;
+	FILE *fp;
+        if (!PyArg_ParseTuple(args, "On:fromfile", &f, &n))
+		return NULL;
+	fp = PyFile_AsFile(f);
+	if (fp == NULL) {
+		PyErr_SetString(PyExc_TypeError, "arg1 must be open file");
+		return NULL;
+	}
+	if (n > 0) {
+		char *item = self->ob_item;
+		Py_ssize_t itemsize = self->ob_descr->itemsize;
+		size_t nread;
+		Py_ssize_t newlength;
+		size_t newbytes;
+		/* Be careful here about overflow */
+		if ((newlength = self->ob_size + n) <= 0 ||
+		    (newbytes = newlength * itemsize) / itemsize !=
+		    (size_t)newlength)
+			goto nomem;
+		PyMem_RESIZE(item, char, newbytes);
+		if (item == NULL) {
+		  nomem:
+			PyErr_NoMemory();
+			return NULL;
+		}
+		self->ob_item = item;
+		self->ob_size += n;
+		self->allocated = self->ob_size;
+		nread = fread(item + (self->ob_size - n) * itemsize,
+			      itemsize, n, fp);
+		if (nread < (size_t)n) {
+		  self->ob_size -= (n - nread);
+			PyMem_RESIZE(item, char, self->ob_size*itemsize);
+			self->ob_item = item;
+			self->allocated = self->ob_size;
+			PyErr_SetString(PyExc_EOFError,
+				         "not enough items in file");
+			return NULL;
+		}
+	}
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(fromfile_doc,
+"fromfile(f, n)\n\
+\n\
+Read n objects from the file object f and append them to the end of the\n\
+array.  Also called as read.");
+
+
+static PyObject *
+array_tofile(arrayobject *self, PyObject *f)
+{
+	FILE *fp;
+
+	fp = PyFile_AsFile(f);
+	if (fp == NULL) {
+		PyErr_SetString(PyExc_TypeError, "arg must be open file");
+		return NULL;
+	}
+	if (self->ob_size > 0) {
+		if (fwrite(self->ob_item, self->ob_descr->itemsize,
+			   self->ob_size, fp) != (size_t)self->ob_size) {
+			PyErr_SetFromErrno(PyExc_IOError);
+			clearerr(fp);
+			return NULL;
+		}
+	}
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(tofile_doc,
+"tofile(f)\n\
+\n\
+Write all items (as machine values) to the file object f.  Also called as\n\
+write.");
+
+
+static PyObject *
+array_fromlist(arrayobject *self, PyObject *list)
+{
+	Py_ssize_t n;
+	Py_ssize_t itemsize = self->ob_descr->itemsize;
+
+	if (!PyList_Check(list)) {
+		PyErr_SetString(PyExc_TypeError, "arg must be list");
+		return NULL;
+	}
+	n = PyList_Size(list);
+	if (n > 0) {
+		char *item = self->ob_item;
+		Py_ssize_t i;
+		PyMem_RESIZE(item, char, (self->ob_size + n) * itemsize);
+		if (item == NULL) {
+			PyErr_NoMemory();
+			return NULL;
+		}
+		self->ob_item = item;
+		self->ob_size += n;
+		self->allocated = self->ob_size;
+		for (i = 0; i < n; i++) {
+			PyObject *v = PyList_GetItem(list, i);
+			if ((*self->ob_descr->setitem)(self,
+					self->ob_size - n + i, v) != 0) {
+				self->ob_size -= n;
+				PyMem_RESIZE(item, char,
+					          self->ob_size * itemsize);
+				self->ob_item = item;
+				self->allocated = self->ob_size;
+				return NULL;
+			}
+		}
+	}
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(fromlist_doc,
+"fromlist(list)\n\
+\n\
+Append items to array from list.");
+
+
+static PyObject *
+array_tolist(arrayobject *self, PyObject *unused)
+{
+	PyObject *list = PyList_New(self->ob_size);
+	Py_ssize_t i;
+
+	if (list == NULL)
+		return NULL;
+	for (i = 0; i < self->ob_size; i++) {
+		PyObject *v = getarrayitem((PyObject *)self, i);
+		if (v == NULL) {
+			Py_DECREF(list);
+			return NULL;
+		}
+		PyList_SetItem(list, i, v);
+	}
+	return list;
+}
+
+PyDoc_STRVAR(tolist_doc,
+"tolist() -> list\n\
+\n\
+Convert array to an ordinary list with the same items.");
+
+
+static PyObject *
+array_fromstring(arrayobject *self, PyObject *args)
+{
+	char *str;
+	Py_ssize_t n;
+	int itemsize = self->ob_descr->itemsize;
+        if (!PyArg_ParseTuple(args, "s#:fromstring", &str, &n))
+		return NULL;
+	if (n % itemsize != 0) {
+		PyErr_SetString(PyExc_ValueError,
+			   "string length not a multiple of item size");
+		return NULL;
+	}
+	n = n / itemsize;
+	if (n > 0) {
+		char *item = self->ob_item;
+		PyMem_RESIZE(item, char, (self->ob_size + n) * itemsize);
+		if (item == NULL) {
+			PyErr_NoMemory();
+			return NULL;
+		}
+		self->ob_item = item;
+		self->ob_size += n;
+		self->allocated = self->ob_size;
+		memcpy(item + (self->ob_size - n) * itemsize,
+		       str, itemsize*n);
+	}
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(fromstring_doc,
+"fromstring(string)\n\
+\n\
+Appends items from the string, interpreting it as an array of machine\n\
+values,as if it had been read from a file using the fromfile() method).");
+
+
+static PyObject *
+array_tostring(arrayobject *self, PyObject *unused)
+{
+	return PyString_FromStringAndSize(self->ob_item,
+				    self->ob_size * self->ob_descr->itemsize);
+}
+
+PyDoc_STRVAR(tostring_doc,
+"tostring() -> string\n\
+\n\
+Convert the array to an array of machine values and return the string\n\
+representation.");
+
+
+
+#ifdef Py_USING_UNICODE
+static PyObject *
+array_fromunicode(arrayobject *self, PyObject *args)
+{
+	Py_UNICODE *ustr;
+	Py_ssize_t n;
+
+        if (!PyArg_ParseTuple(args, "u#:fromunicode", &ustr, &n))
+		return NULL;
+	if (self->ob_descr->typecode != 'u') {
+		PyErr_SetString(PyExc_ValueError,
+			"fromunicode() may only be called on "
+			"type 'u' arrays");
+		return NULL;
+	}
+	if (n > 0) {
+		Py_UNICODE *item = (Py_UNICODE *) self->ob_item;
+		PyMem_RESIZE(item, Py_UNICODE, self->ob_size + n);
+		if (item == NULL) {
+			PyErr_NoMemory();
+			return NULL;
+		}
+		self->ob_item = (char *) item;
+		self->ob_size += n;
+		self->allocated = self->ob_size;
+		memcpy(item + self->ob_size - n,
+		       ustr, n * sizeof(Py_UNICODE));
+	}
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(fromunicode_doc,
+"fromunicode(ustr)\n\
+\n\
+Extends this array with data from the unicode string ustr.\n\
+The array must be a type 'u' array; otherwise a ValueError\n\
+is raised.  Use array.fromstring(ustr.decode(...)) to\n\
+append Unicode data to an array of some other type.");
+
+
+static PyObject *
+array_tounicode(arrayobject *self, PyObject *unused)
+{
+	if (self->ob_descr->typecode != 'u') {
+		PyErr_SetString(PyExc_ValueError,
+			"tounicode() may only be called on type 'u' arrays");
+		return NULL;
+	}
+	return PyUnicode_FromUnicode((Py_UNICODE *) self->ob_item, self->ob_size);
+}
+
+PyDoc_STRVAR(tounicode_doc,
+"tounicode() -> unicode\n\
+\n\
+Convert the array to a unicode string.  The array must be\n\
+a type 'u' array; otherwise a ValueError is raised.  Use\n\
+array.tostring().decode() to obtain a unicode string from\n\
+an array of some other type.");
+
+#endif /* Py_USING_UNICODE */
+
+
+static PyObject *
+array_get_typecode(arrayobject *a, void *closure)
+{
+	char tc = a->ob_descr->typecode;
+	return PyString_FromStringAndSize(&tc, 1);
+}
+
+static PyObject *
+array_get_itemsize(arrayobject *a, void *closure)
+{
+	return PyInt_FromLong((long)a->ob_descr->itemsize);
+}
+
+static PyGetSetDef array_getsets [] = {
+	{"typecode", (getter) array_get_typecode, NULL,
+	 "the typecode character used to create the array"},
+	{"itemsize", (getter) array_get_itemsize, NULL,
+	 "the size, in bytes, of one array item"},
+	{NULL}
+};
+
+PyMethodDef array_methods[] = {
+	{"append",	(PyCFunction)array_append,	METH_O,
+	 append_doc},
+	{"buffer_info", (PyCFunction)array_buffer_info, METH_NOARGS,
+	 buffer_info_doc},
+	{"byteswap",	(PyCFunction)array_byteswap,	METH_NOARGS,
+	 byteswap_doc},
+	{"__copy__",	(PyCFunction)array_copy,	METH_NOARGS,
+	 copy_doc},
+	{"count",	(PyCFunction)array_count,	METH_O,
+	 count_doc},
+	{"__deepcopy__",(PyCFunction)array_copy,	METH_O,
+	 copy_doc},
+	{"extend",      (PyCFunction)array_extend,	METH_O,
+	 extend_doc},
+	{"fromfile",	(PyCFunction)array_fromfile,	METH_VARARGS,
+	 fromfile_doc},
+	{"fromlist",	(PyCFunction)array_fromlist,	METH_O,
+	 fromlist_doc},
+	{"fromstring",	(PyCFunction)array_fromstring,	METH_VARARGS,
+	 fromstring_doc},
+#ifdef Py_USING_UNICODE
+	{"fromunicode",	(PyCFunction)array_fromunicode,	METH_VARARGS,
+	 fromunicode_doc},
+#endif
+	{"index",	(PyCFunction)array_index,	METH_O,
+	 index_doc},
+	{"insert",	(PyCFunction)array_insert,	METH_VARARGS,
+	 insert_doc},
+	{"pop",		(PyCFunction)array_pop,		METH_VARARGS,
+	 pop_doc},
+	{"read",	(PyCFunction)array_fromfile,	METH_VARARGS,
+	 fromfile_doc},
+	{"__reduce__",	(PyCFunction)array_reduce,	METH_NOARGS,
+	 array_doc},
+	{"remove",	(PyCFunction)array_remove,	METH_O,
+	 remove_doc},
+	{"reverse",	(PyCFunction)array_reverse,	METH_NOARGS,
+	 reverse_doc},
+/*	{"sort",	(PyCFunction)array_sort,	METH_VARARGS,
+	sort_doc},*/
+	{"tofile",	(PyCFunction)array_tofile,	METH_O,
+	 tofile_doc},
+	{"tolist",	(PyCFunction)array_tolist,	METH_NOARGS,
+	 tolist_doc},
+	{"tostring",	(PyCFunction)array_tostring,	METH_NOARGS,
+	 tostring_doc},
+#ifdef Py_USING_UNICODE
+	{"tounicode",   (PyCFunction)array_tounicode,	METH_NOARGS,
+	 tounicode_doc},
+#endif
+	{"write",	(PyCFunction)array_tofile,	METH_O,
+	 tofile_doc},
+	{NULL,		NULL}		/* sentinel */
+};
+
+static PyObject *
+array_repr(arrayobject *a)
+{
+	char buf[256], typecode;
+	PyObject *s, *t, *v = NULL;
+	Py_ssize_t len;
+
+	len = a->ob_size;
+	typecode = a->ob_descr->typecode;
+	if (len == 0) {
+		PyOS_snprintf(buf, sizeof(buf), "array('%c')", typecode);
+		return PyString_FromString(buf);
+	}
+		
+	if (typecode == 'c')
+		v = array_tostring(a, NULL);
+#ifdef Py_USING_UNICODE
+	else if (typecode == 'u')
+		v = array_tounicode(a, NULL);
+#endif
+	else
+		v = array_tolist(a, NULL);
+	t = PyObject_Repr(v);
+	Py_XDECREF(v);
+
+	PyOS_snprintf(buf, sizeof(buf), "array('%c', ", typecode);
+	s = PyString_FromString(buf);
+	PyString_ConcatAndDel(&s, t);
+	PyString_ConcatAndDel(&s, PyString_FromString(")"));
+	return s;
+}
+
+static PyObject*
+array_subscr(arrayobject* self, PyObject* item)
+{
+	if (PyIndex_Check(item)) {
+		Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+		if (i==-1 && PyErr_Occurred()) {
+			return NULL;
+		}
+		if (i < 0)
+			i += self->ob_size;
+		return array_item(self, i);
+	}
+	else if (PySlice_Check(item)) {
+		Py_ssize_t start, stop, step, slicelength, cur, i;
+		PyObject* result;
+		arrayobject* ar;
+		int itemsize = self->ob_descr->itemsize;
+
+		if (PySlice_GetIndicesEx((PySliceObject*)item, self->ob_size,
+				 &start, &stop, &step, &slicelength) < 0) {
+			return NULL;
+		}
+
+		if (slicelength <= 0) {
+			return newarrayobject(&Arraytype, 0, self->ob_descr);
+		}
+		else {
+			result = newarrayobject(&Arraytype, slicelength, self->ob_descr);
+			if (!result) return NULL;
+
+			ar = (arrayobject*)result;
+
+			for (cur = start, i = 0; i < slicelength; 
+			     cur += step, i++) {
+				memcpy(ar->ob_item + i*itemsize,
+				       self->ob_item + cur*itemsize,
+				       itemsize);
+			}
+			
+			return result;
+		}		
+	}
+	else {
+		PyErr_SetString(PyExc_TypeError, 
+				"list indices must be integers");
+		return NULL;
+	}
+}
+
+static int
+array_ass_subscr(arrayobject* self, PyObject* item, PyObject* value)
+{
+	if (PyIndex_Check(item)) {
+		Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+		if (i==-1 && PyErr_Occurred()) 
+			return -1;
+		if (i < 0)
+			i += self->ob_size;
+		return array_ass_item(self, i, value);
+	}
+	else if (PySlice_Check(item)) {
+		Py_ssize_t start, stop, step, slicelength;
+		int itemsize = self->ob_descr->itemsize;
+
+		if (PySlice_GetIndicesEx((PySliceObject*)item, self->ob_size,
+				 &start, &stop, &step, &slicelength) < 0) {
+			return -1;
+		}
+
+		/* treat A[slice(a,b)] = v _exactly_ like A[a:b] = v */
+		if (step == 1 && ((PySliceObject*)item)->step == Py_None)
+			return array_ass_slice(self, start, stop, value);
+
+		if (value == NULL) {
+			/* delete slice */
+			Py_ssize_t cur, i, extra;
+			
+			if (slicelength <= 0)
+				return 0;
+
+			if (step < 0) {
+				stop = start + 1;
+				start = stop + step*(slicelength - 1) - 1;
+				step = -step;
+			}
+
+			for (cur = start, i = 0; i < slicelength - 1;
+			     cur += step, i++) {
+				memmove(self->ob_item + (cur - i)*itemsize,
+					self->ob_item + (cur + 1)*itemsize,
+					(step - 1) * itemsize);
+			}
+			extra = self->ob_size - (cur + 1);
+			if (extra > 0) {
+				memmove(self->ob_item + (cur - i)*itemsize,
+					self->ob_item + (cur + 1)*itemsize,
+					extra*itemsize);
+			}
+
+			self->ob_size -= slicelength;
+			self->ob_item = (char *)PyMem_REALLOC(self->ob_item,
+							      itemsize*self->ob_size);
+			self->allocated = self->ob_size;
+
+			return 0;
+		}
+		else {
+			/* assign slice */
+			Py_ssize_t cur, i;
+			arrayobject* av;
+
+			if (!array_Check(value)) {
+				PyErr_Format(PyExc_TypeError,
+			     "must assign array (not \"%.200s\") to slice",
+					     value->ob_type->tp_name);
+				return -1;
+			}
+
+			av = (arrayobject*)value;
+
+			if (av->ob_size != slicelength) {
+				PyErr_Format(PyExc_ValueError,
+            "attempt to assign array of size %ld to extended slice of size %ld",
+					     /*XXX*/(long)av->ob_size, /*XXX*/(long)slicelength);
+				return -1;
+			}
+
+			if (!slicelength)
+				return 0;
+
+			/* protect against a[::-1] = a */
+			if (self == av) { 
+				value = array_slice(av, 0, av->ob_size);
+				av = (arrayobject*)value;
+				if (!av)
+					return -1;
+			} 
+			else {
+				Py_INCREF(value);
+			}
+
+			for (cur = start, i = 0; i < slicelength; 
+			     cur += step, i++) {
+				memcpy(self->ob_item + cur*itemsize,
+				       av->ob_item + i*itemsize,
+				       itemsize);
+			}
+
+			Py_DECREF(value);
+			
+			return 0;
+		}
+	} 
+	else {
+		PyErr_SetString(PyExc_TypeError, 
+				"list indices must be integers");
+		return -1;
+	}
+}
+
+static PyMappingMethods array_as_mapping = {
+	(lenfunc)array_length,
+	(binaryfunc)array_subscr,
+	(objobjargproc)array_ass_subscr
+};
+
+static const void *emptybuf = "";
+
+static Py_ssize_t
+array_buffer_getreadbuf(arrayobject *self, Py_ssize_t index, const void **ptr)
+{
+	if ( index != 0 ) {
+		PyErr_SetString(PyExc_SystemError,
+				"Accessing non-existent array segment");
+		return -1;
+	}
+	*ptr = (void *)self->ob_item;
+	if (*ptr == NULL)
+		*ptr = emptybuf;
+	return self->ob_size*self->ob_descr->itemsize;
+}
+
+static Py_ssize_t
+array_buffer_getwritebuf(arrayobject *self, Py_ssize_t index, const void **ptr)
+{
+	if ( index != 0 ) {
+		PyErr_SetString(PyExc_SystemError,
+				"Accessing non-existent array segment");
+		return -1;
+	}
+	*ptr = (void *)self->ob_item;
+	if (*ptr == NULL)
+		*ptr = emptybuf;
+	return self->ob_size*self->ob_descr->itemsize;
+}
+
+static Py_ssize_t
+array_buffer_getsegcount(arrayobject *self, Py_ssize_t *lenp)
+{
+	if ( lenp )
+		*lenp = self->ob_size*self->ob_descr->itemsize;
+	return 1;
+}
+
+static PySequenceMethods array_as_sequence = {
+	(lenfunc)array_length,		        /*sq_length*/
+	(binaryfunc)array_concat,               /*sq_concat*/
+	(ssizeargfunc)array_repeat,		/*sq_repeat*/
+	(ssizeargfunc)array_item,		        /*sq_item*/
+	(ssizessizeargfunc)array_slice,		/*sq_slice*/
+	(ssizeobjargproc)array_ass_item,		/*sq_ass_item*/
+	(ssizessizeobjargproc)array_ass_slice,	/*sq_ass_slice*/
+	(objobjproc)array_contains,		/*sq_contains*/
+	(binaryfunc)array_inplace_concat,	/*sq_inplace_concat*/
+	(ssizeargfunc)array_inplace_repeat	/*sq_inplace_repeat*/
+};
+
+static PyBufferProcs array_as_buffer = {
+	(readbufferproc)array_buffer_getreadbuf,
+	(writebufferproc)array_buffer_getwritebuf,
+	(segcountproc)array_buffer_getsegcount,
+	NULL,
+};
+
+static PyObject *
+array_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	char c;
+	PyObject *initial = NULL, *it = NULL;
+	struct arraydescr *descr;
+	
+	if (type == &Arraytype && !_PyArg_NoKeywords("array.array()", kwds))
+		return NULL;
+
+	if (!PyArg_ParseTuple(args, "c|O:array", &c, &initial))
+		return NULL;
+
+	if (!(initial == NULL || PyList_Check(initial)
+	      || PyString_Check(initial) || PyTuple_Check(initial)
+	      || (c == 'u' && PyUnicode_Check(initial)))) {
+		it = PyObject_GetIter(initial);
+		if (it == NULL)
+			return NULL;
+		/* We set initial to NULL so that the subsequent code
+		   will create an empty array of the appropriate type
+		   and afterwards we can use array_iter_extend to populate
+		   the array.
+		*/
+		initial = NULL;
+	}
+	for (descr = descriptors; descr->typecode != '\0'; descr++) {
+		if (descr->typecode == c) {
+			PyObject *a;
+			Py_ssize_t len;
+
+			if (initial == NULL || !(PyList_Check(initial) 
+				|| PyTuple_Check(initial)))
+				len = 0;
+			else
+				len = PySequence_Size(initial);
+
+			a = newarrayobject(type, len, descr);
+			if (a == NULL)
+				return NULL;
+
+			if (len > 0) {
+				Py_ssize_t i;
+				for (i = 0; i < len; i++) {
+					PyObject *v =
+					        PySequence_GetItem(initial, i);
+					if (v == NULL) {
+						Py_DECREF(a);
+						return NULL;
+					}
+					if (setarrayitem(a, i, v) != 0) {
+						Py_DECREF(v);
+						Py_DECREF(a);
+						return NULL;
+					}
+					Py_DECREF(v);
+				}
+			} else if (initial != NULL && PyString_Check(initial)) {
+				PyObject *t_initial, *v;
+				t_initial = PyTuple_Pack(1, initial);
+				if (t_initial == NULL) {
+					Py_DECREF(a);
+					return NULL;
+				}
+				v = array_fromstring((arrayobject *)a,
+							 t_initial);
+				Py_DECREF(t_initial);
+				if (v == NULL) {
+					Py_DECREF(a);
+					return NULL;
+				}
+				Py_DECREF(v);
+#ifdef Py_USING_UNICODE
+			} else if (initial != NULL && PyUnicode_Check(initial))  {
+				Py_ssize_t n = PyUnicode_GET_DATA_SIZE(initial);
+				if (n > 0) {
+					arrayobject *self = (arrayobject *)a;
+					char *item = self->ob_item;
+					item = (char *)PyMem_Realloc(item, n);
+					if (item == NULL) {
+						PyErr_NoMemory();
+						Py_DECREF(a);
+						return NULL;
+					}
+					self->ob_item = item;
+					self->ob_size = n / sizeof(Py_UNICODE);
+					memcpy(item, PyUnicode_AS_DATA(initial), n);
+					self->allocated = self->ob_size;
+				}
+#endif
+			}
+			if (it != NULL) {
+				if (array_iter_extend((arrayobject *)a, it) == -1) {
+					Py_DECREF(it);
+					Py_DECREF(a);
+					return NULL;
+				}
+				Py_DECREF(it);
+			}
+			return a;
+		}
+	}
+	PyErr_SetString(PyExc_ValueError,
+		"bad typecode (must be c, b, B, u, h, H, i, I, l, L, f or d)");
+	return NULL;
+}
+
+
+PyDoc_STRVAR(module_doc,
+"This module defines an object type which can efficiently represent\n\
+an array of basic values: characters, integers, floating point\n\
+numbers.  Arrays are sequence types and behave very much like lists,\n\
+except that the type of objects stored in them is constrained.  The\n\
+type is specified at object creation time by using a type code, which\n\
+is a single character.  The following type codes are defined:\n\
+\n\
+    Type code   C Type             Minimum size in bytes \n\
+    'c'         character          1 \n\
+    'b'         signed integer     1 \n\
+    'B'         unsigned integer   1 \n\
+    'u'         Unicode character  2 \n\
+    'h'         signed integer     2 \n\
+    'H'         unsigned integer   2 \n\
+    'i'         signed integer     2 \n\
+    'I'         unsigned integer   2 \n\
+    'l'         signed integer     4 \n\
+    'L'         unsigned integer   4 \n\
+    'f'         floating point     4 \n\
+    'd'         floating point     8 \n\
+\n\
+The constructor is:\n\
+\n\
+array(typecode [, initializer]) -- create a new array\n\
+");
+
+PyDoc_STRVAR(arraytype_doc,
+"array(typecode [, initializer]) -> array\n\
+\n\
+Return a new array whose items are restricted by typecode, and\n\
+initialized from the optional initializer value, which must be a list,\n\
+string. or iterable over elements of the appropriate type.\n\
+\n\
+Arrays represent basic values and behave very much like lists, except\n\
+the type of objects stored in them is constrained.\n\
+\n\
+Methods:\n\
+\n\
+append() -- append a new item to the end of the array\n\
+buffer_info() -- return information giving the current memory info\n\
+byteswap() -- byteswap all the items of the array\n\
+count() -- return number of occurences of an object\n\
+extend() -- extend array by appending multiple elements from an iterable\n\
+fromfile() -- read items from a file object\n\
+fromlist() -- append items from the list\n\
+fromstring() -- append items from the string\n\
+index() -- return index of first occurence of an object\n\
+insert() -- insert a new item into the array at a provided position\n\
+pop() -- remove and return item (default last)\n\
+read() -- DEPRECATED, use fromfile()\n\
+remove() -- remove first occurence of an object\n\
+reverse() -- reverse the order of the items in the array\n\
+tofile() -- write all items to a file object\n\
+tolist() -- return the array converted to an ordinary list\n\
+tostring() -- return the array converted to a string\n\
+write() -- DEPRECATED, use tofile()\n\
+\n\
+Attributes:\n\
+\n\
+typecode -- the typecode character used to create the array\n\
+itemsize -- the length in bytes of one array item\n\
+");
+
+static PyObject *array_iter(arrayobject *ao);
+
+static PyTypeObject Arraytype = {
+	PyObject_HEAD_INIT(NULL)
+	0,
+	"array.array",
+	sizeof(arrayobject),
+	0,
+	(destructor)array_dealloc,		/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	(reprfunc)array_repr,			/* tp_repr */
+	0,					/* tp_as_number*/
+	&array_as_sequence,			/* tp_as_sequence*/
+	&array_as_mapping,			/* tp_as_mapping*/
+	0, 					/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	0,					/* tp_setattro */
+	&array_as_buffer,			/* tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_WEAKREFS,  /* tp_flags */
+	arraytype_doc,				/* tp_doc */
+ 	0,					/* tp_traverse */
+	0,					/* tp_clear */
+	array_richcompare,			/* tp_richcompare */
+	offsetof(arrayobject, weakreflist),	/* tp_weaklistoffset */
+	(getiterfunc)array_iter,		/* tp_iter */
+	0,					/* tp_iternext */
+	array_methods,				/* tp_methods */
+	0,					/* tp_members */
+	array_getsets,				/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	0,					/* tp_init */
+	PyType_GenericAlloc,			/* tp_alloc */
+	array_new,				/* tp_new */
+	PyObject_Del,				/* tp_free */
+};
+
+
+/*********************** Array Iterator **************************/
+
+typedef struct {
+	PyObject_HEAD
+	Py_ssize_t			index;
+	arrayobject		*ao;
+	PyObject		* (*getitem)(struct arrayobject *, Py_ssize_t);
+} arrayiterobject;
+
+static PyTypeObject PyArrayIter_Type;
+
+#define PyArrayIter_Check(op) PyObject_TypeCheck(op, &PyArrayIter_Type)
+
+static PyObject *
+array_iter(arrayobject *ao)
+{
+	arrayiterobject *it;
+
+	if (!array_Check(ao)) {
+		PyErr_BadInternalCall();
+		return NULL;
+	}
+
+	it = PyObject_GC_New(arrayiterobject, &PyArrayIter_Type);
+	if (it == NULL)
+		return NULL;
+
+	Py_INCREF(ao);
+	it->ao = ao;
+	it->index = 0;
+	it->getitem = ao->ob_descr->getitem;
+	PyObject_GC_Track(it);
+	return (PyObject *)it;
+}
+
+static PyObject *
+arrayiter_next(arrayiterobject *it)
+{
+	assert(PyArrayIter_Check(it));
+	if (it->index < it->ao->ob_size)
+		return (*it->getitem)(it->ao, it->index++);
+	return NULL;
+}
+
+static void
+arrayiter_dealloc(arrayiterobject *it)
+{
+	PyObject_GC_UnTrack(it);
+	Py_XDECREF(it->ao);
+	PyObject_GC_Del(it);
+}
+
+static int
+arrayiter_traverse(arrayiterobject *it, visitproc visit, void *arg)
+{
+	Py_VISIT(it->ao);
+	return 0;
+}
+
+static PyTypeObject PyArrayIter_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0,                                      /* ob_size */
+	"arrayiterator",                        /* tp_name */
+	sizeof(arrayiterobject),                /* tp_basicsize */
+	0,                                      /* tp_itemsize */
+	/* methods */
+	(destructor)arrayiter_dealloc,		/* tp_dealloc */
+	0,                                      /* tp_print */
+	0,                                      /* tp_getattr */
+	0,                                      /* tp_setattr */
+	0,                                      /* tp_compare */
+	0,                                      /* tp_repr */
+	0,                                      /* tp_as_number */
+	0,                                      /* tp_as_sequence */
+	0,                                      /* tp_as_mapping */
+	0,                                      /* tp_hash */
+	0,                                      /* tp_call */
+	0,                                      /* tp_str */
+	PyObject_GenericGetAttr,                /* tp_getattro */
+	0,                                      /* tp_setattro */
+	0,                                      /* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+	0,                                      /* tp_doc */
+	(traverseproc)arrayiter_traverse,	/* tp_traverse */
+	0,					/* tp_clear */
+	0,                                      /* tp_richcompare */
+	0,                                      /* tp_weaklistoffset */
+	PyObject_SelfIter,			/* tp_iter */
+	(iternextfunc)arrayiter_next,		/* tp_iternext */
+	0,					/* tp_methods */
+};
+
+
+/*********************** Install Module **************************/
+
+/* No functions in array module. */
+static PyMethodDef a_methods[] = {
+    {NULL, NULL, 0, NULL}        /* Sentinel */
+};
+
+
+PyMODINIT_FUNC
+initarray(void)
+{
+	PyObject *m;
+
+	Arraytype.ob_type = &PyType_Type;
+	PyArrayIter_Type.ob_type = &PyType_Type;
+	m = Py_InitModule3("array", a_methods, module_doc);
+	if (m == NULL)
+		return;
+
+        Py_INCREF((PyObject *)&Arraytype);
+	PyModule_AddObject(m, "ArrayType", (PyObject *)&Arraytype);
+        Py_INCREF((PyObject *)&Arraytype);
+	PyModule_AddObject(m, "array", (PyObject *)&Arraytype);
+	/* No need to check the error here, the caller will do that */
+}

Added: vendor/Python/current/Modules/audioop.c
===================================================================
--- vendor/Python/current/Modules/audioop.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/audioop.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1612 @@
+
+/* audioopmodule - Module to detect peak values in arrays */
+
+#include "Python.h"
+
+#if SIZEOF_INT == 4
+typedef int Py_Int32;
+typedef unsigned int Py_UInt32;
+#else
+#if SIZEOF_LONG == 4
+typedef long Py_Int32;
+typedef unsigned long Py_UInt32;
+#else
+#error "No 4-byte integral type"
+#endif
+#endif
+
+typedef short PyInt16;
+
+#if defined(__CHAR_UNSIGNED__)
+#if defined(signed)
+/* This module currently does not work on systems where only unsigned
+   characters are available.  Take it out of Setup.  Sorry. */
+#endif
+#endif
+
+/* Code shamelessly stolen from sox, 12.17.7, g711.c
+** (c) Craig Reese, Joe Campbell and Jeff Poskanzer 1989 */
+
+/* From g711.c:
+ *
+ * December 30, 1994:
+ * Functions linear2alaw, linear2ulaw have been updated to correctly
+ * convert unquantized 16 bit values.
+ * Tables for direct u- to A-law and A- to u-law conversions have been
+ * corrected.
+ * Borge Lindberg, Center for PersonKommunikation, Aalborg University.
+ * bli at cpk.auc.dk
+ *
+ */
+#define BIAS 0x84   /* define the add-in bias for 16 bit samples */
+#define CLIP 32635
+#define SIGN_BIT        (0x80)          /* Sign bit for a A-law byte. */
+#define QUANT_MASK      (0xf)           /* Quantization field mask. */
+#define SEG_SHIFT       (4)             /* Left shift for segment number. */
+#define SEG_MASK        (0x70)          /* Segment field mask. */
+
+static PyInt16 seg_aend[8] = {0x1F, 0x3F, 0x7F, 0xFF,
+                              0x1FF, 0x3FF, 0x7FF, 0xFFF};
+static PyInt16 seg_uend[8] = {0x3F, 0x7F, 0xFF, 0x1FF,
+                              0x3FF, 0x7FF, 0xFFF, 0x1FFF};
+
+static PyInt16
+search(PyInt16 val, PyInt16 *table, int size)
+{
+        int i;
+
+        for (i = 0; i < size; i++) {
+                if (val <= *table++)
+                        return (i);
+        }
+        return (size);
+}
+#define st_ulaw2linear16(uc) (_st_ulaw2linear16[uc])
+#define st_alaw2linear16(uc) (_st_alaw2linear16[uc])
+
+static PyInt16 _st_ulaw2linear16[256] = {
+    -32124,  -31100,  -30076,  -29052,  -28028,  -27004,  -25980,
+    -24956,  -23932,  -22908,  -21884,  -20860,  -19836,  -18812,
+    -17788,  -16764,  -15996,  -15484,  -14972,  -14460,  -13948,
+    -13436,  -12924,  -12412,  -11900,  -11388,  -10876,  -10364,
+     -9852,   -9340,   -8828,   -8316,   -7932,   -7676,   -7420,
+     -7164,   -6908,   -6652,   -6396,   -6140,   -5884,   -5628,
+     -5372,   -5116,   -4860,   -4604,   -4348,   -4092,   -3900,
+     -3772,   -3644,   -3516,   -3388,   -3260,   -3132,   -3004,
+     -2876,   -2748,   -2620,   -2492,   -2364,   -2236,   -2108,
+     -1980,   -1884,   -1820,   -1756,   -1692,   -1628,   -1564,
+     -1500,   -1436,   -1372,   -1308,   -1244,   -1180,   -1116,
+     -1052,    -988,    -924,    -876,    -844,    -812,    -780,
+      -748,    -716,    -684,    -652,    -620,    -588,    -556,
+      -524,    -492,    -460,    -428,    -396,    -372,    -356,
+      -340,    -324,    -308,    -292,    -276,    -260,    -244,
+      -228,    -212,    -196,    -180,    -164,    -148,    -132,
+      -120,    -112,    -104,     -96,     -88,     -80,     -72,
+       -64,     -56,     -48,     -40,     -32,     -24,     -16,
+        -8,       0,   32124,   31100,   30076,   29052,   28028,
+     27004,   25980,   24956,   23932,   22908,   21884,   20860,
+     19836,   18812,   17788,   16764,   15996,   15484,   14972,
+     14460,   13948,   13436,   12924,   12412,   11900,   11388,
+     10876,   10364,    9852,    9340,    8828,    8316,    7932,
+      7676,    7420,    7164,    6908,    6652,    6396,    6140,
+      5884,    5628,    5372,    5116,    4860,    4604,    4348,
+      4092,    3900,    3772,    3644,    3516,    3388,    3260,
+      3132,    3004,    2876,    2748,    2620,    2492,    2364,
+      2236,    2108,    1980,    1884,    1820,    1756,    1692,
+      1628,    1564,    1500,    1436,    1372,    1308,    1244,
+      1180,    1116,    1052,     988,     924,     876,     844,
+       812,     780,     748,     716,     684,     652,     620,
+       588,     556,     524,     492,     460,     428,     396,
+       372,     356,     340,     324,     308,     292,     276,
+       260,     244,     228,     212,     196,     180,     164,
+       148,     132,     120,     112,     104,      96,      88,
+        80,      72,      64,      56,      48,      40,      32,
+        24,      16,       8,       0
+};
+
+/*
+ * linear2ulaw() accepts a 14-bit signed integer and encodes it as u-law data
+ * stored in a unsigned char.  This function should only be called with
+ * the data shifted such that it only contains information in the lower
+ * 14-bits.
+ *
+ * In order to simplify the encoding process, the original linear magnitude
+ * is biased by adding 33 which shifts the encoding range from (0 - 8158) to
+ * (33 - 8191). The result can be seen in the following encoding table:
+ *
+ *      Biased Linear Input Code        Compressed Code
+ *      ------------------------        ---------------
+ *      00000001wxyza                   000wxyz
+ *      0000001wxyzab                   001wxyz
+ *      000001wxyzabc                   010wxyz
+ *      00001wxyzabcd                   011wxyz
+ *      0001wxyzabcde                   100wxyz
+ *      001wxyzabcdef                   101wxyz
+ *      01wxyzabcdefg                   110wxyz
+ *      1wxyzabcdefgh                   111wxyz
+ *
+ * Each biased linear code has a leading 1 which identifies the segment
+ * number. The value of the segment number is equal to 7 minus the number
+ * of leading 0's. The quantization interval is directly available as the
+ * four bits wxyz.  * The trailing bits (a - h) are ignored.
+ *
+ * Ordinarily the complement of the resulting code word is used for
+ * transmission, and so the code word is complemented before it is returned.
+ *
+ * For further information see John C. Bellamy's Digital Telephony, 1982,
+ * John Wiley & Sons, pps 98-111 and 472-476.
+ */
+static unsigned char
+st_14linear2ulaw(PyInt16 pcm_val)	/* 2's complement (14-bit range) */
+{
+        PyInt16         mask;
+        PyInt16         seg;
+        unsigned char   uval;
+
+        /* The original sox code does this in the calling function, not here */
+        pcm_val = pcm_val >> 2;
+
+        /* u-law inverts all bits */
+        /* Get the sign and the magnitude of the value. */
+        if (pcm_val < 0) {
+                pcm_val = -pcm_val;
+                mask = 0x7F;
+        } else {
+                mask = 0xFF;
+        }
+        if ( pcm_val > CLIP ) pcm_val = CLIP;           /* clip the magnitude */
+        pcm_val += (BIAS >> 2);
+
+        /* Convert the scaled magnitude to segment number. */
+        seg = search(pcm_val, seg_uend, 8);
+
+        /*
+         * Combine the sign, segment, quantization bits;
+         * and complement the code word.
+         */
+        if (seg >= 8)           /* out of range, return maximum value. */
+                return (unsigned char) (0x7F ^ mask);
+        else {
+                uval = (unsigned char) (seg << 4) | ((pcm_val >> (seg + 1)) & 0xF);
+                return (uval ^ mask);
+        }
+
+}
+
+static PyInt16 _st_alaw2linear16[256] = {
+     -5504,   -5248,   -6016,   -5760,   -4480,   -4224,   -4992,
+     -4736,   -7552,   -7296,   -8064,   -7808,   -6528,   -6272,
+     -7040,   -6784,   -2752,   -2624,   -3008,   -2880,   -2240,
+     -2112,   -2496,   -2368,   -3776,   -3648,   -4032,   -3904,
+     -3264,   -3136,   -3520,   -3392,  -22016,  -20992,  -24064,
+    -23040,  -17920,  -16896,  -19968,  -18944,  -30208,  -29184,
+    -32256,  -31232,  -26112,  -25088,  -28160,  -27136,  -11008,
+    -10496,  -12032,  -11520,   -8960,   -8448,   -9984,   -9472,
+    -15104,  -14592,  -16128,  -15616,  -13056,  -12544,  -14080,
+    -13568,    -344,    -328,    -376,    -360,    -280,    -264,
+      -312,    -296,    -472,    -456,    -504,    -488,    -408,
+      -392,    -440,    -424,     -88,     -72,    -120,    -104,
+       -24,      -8,     -56,     -40,    -216,    -200,    -248,
+      -232,    -152,    -136,    -184,    -168,   -1376,   -1312,
+     -1504,   -1440,   -1120,   -1056,   -1248,   -1184,   -1888,
+     -1824,   -2016,   -1952,   -1632,   -1568,   -1760,   -1696,
+      -688,    -656,    -752,    -720,    -560,    -528,    -624,
+      -592,    -944,    -912,   -1008,    -976,    -816,    -784,
+      -880,    -848,    5504,    5248,    6016,    5760,    4480,
+      4224,    4992,    4736,    7552,    7296,    8064,    7808,
+      6528,    6272,    7040,    6784,    2752,    2624,    3008,
+      2880,    2240,    2112,    2496,    2368,    3776,    3648,
+      4032,    3904,    3264,    3136,    3520,    3392,   22016,
+     20992,   24064,   23040,   17920,   16896,   19968,   18944,
+     30208,   29184,   32256,   31232,   26112,   25088,   28160,
+     27136,   11008,   10496,   12032,   11520,    8960,    8448,
+      9984,    9472,   15104,   14592,   16128,   15616,   13056,
+     12544,   14080,   13568,     344,     328,     376,     360,
+       280,     264,     312,     296,     472,     456,     504,
+       488,     408,     392,     440,     424,      88,      72,
+       120,     104,      24,       8,      56,      40,     216,
+       200,     248,     232,     152,     136,     184,     168,
+      1376,    1312,    1504,    1440,    1120,    1056,    1248,
+      1184,    1888,    1824,    2016,    1952,    1632,    1568,
+      1760,    1696,     688,     656,     752,     720,     560,
+       528,     624,     592,     944,     912,    1008,     976,
+       816,     784,     880,     848
+};
+
+/*
+ * linear2alaw() accepts an 13-bit signed integer and encodes it as A-law data
+ * stored in a unsigned char.  This function should only be called with
+ * the data shifted such that it only contains information in the lower
+ * 13-bits.
+ *
+ *              Linear Input Code       Compressed Code
+ *      ------------------------        ---------------
+ *      0000000wxyza                    000wxyz
+ *      0000001wxyza                    001wxyz
+ *      000001wxyzab                    010wxyz
+ *      00001wxyzabc                    011wxyz
+ *      0001wxyzabcd                    100wxyz
+ *      001wxyzabcde                    101wxyz
+ *      01wxyzabcdef                    110wxyz
+ *      1wxyzabcdefg                    111wxyz
+ *
+ * For further information see John C. Bellamy's Digital Telephony, 1982,
+ * John Wiley & Sons, pps 98-111 and 472-476.
+ */
+static unsigned char
+st_linear2alaw(PyInt16 pcm_val)	/* 2's complement (13-bit range) */
+{
+        PyInt16         mask;
+        short           seg;
+        unsigned char   aval;
+
+        /* The original sox code does this in the calling function, not here */
+        pcm_val = pcm_val >> 3;
+
+        /* A-law using even bit inversion */
+        if (pcm_val >= 0) {
+                mask = 0xD5;            /* sign (7th) bit = 1 */
+        } else {
+                mask = 0x55;            /* sign bit = 0 */
+                pcm_val = -pcm_val - 1;
+        }
+
+        /* Convert the scaled magnitude to segment number. */
+        seg = search(pcm_val, seg_aend, 8);
+
+        /* Combine the sign, segment, and quantization bits. */
+
+        if (seg >= 8)           /* out of range, return maximum value. */
+                return (unsigned char) (0x7F ^ mask);
+        else {
+                aval = (unsigned char) seg << SEG_SHIFT;
+                if (seg < 2)
+                        aval |= (pcm_val >> 1) & QUANT_MASK;
+                else
+                        aval |= (pcm_val >> seg) & QUANT_MASK;
+                return (aval ^ mask);
+        }
+}
+/* End of code taken from sox */
+
+/* Intel ADPCM step variation table */
+static int indexTable[16] = {
+        -1, -1, -1, -1, 2, 4, 6, 8,
+        -1, -1, -1, -1, 2, 4, 6, 8,
+};
+
+static int stepsizeTable[89] = {
+        7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
+        19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
+        50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
+        130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
+        337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
+        876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
+        2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
+        5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
+        15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
+};
+    
+#define CHARP(cp, i) ((signed char *)(cp+i))
+#define SHORTP(cp, i) ((short *)(cp+i))
+#define LONGP(cp, i) ((Py_Int32 *)(cp+i))
+
+
+
+static PyObject *AudioopError;
+
+static PyObject *
+audioop_getsample(PyObject *self, PyObject *args)
+{
+        signed char *cp;
+        int len, size, val = 0;
+        int i;
+
+        if ( !PyArg_ParseTuple(args, "s#ii:getsample", &cp, &len, &size, &i) )
+                return 0;
+        if ( size != 1 && size != 2 && size != 4 ) {
+                PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
+                return 0;
+        }
+        if ( i < 0 || i >= len/size ) {
+                PyErr_SetString(AudioopError, "Index out of range");
+                return 0;
+        }
+        if ( size == 1 )      val = (int)*CHARP(cp, i);
+        else if ( size == 2 ) val = (int)*SHORTP(cp, i*2);
+        else if ( size == 4 ) val = (int)*LONGP(cp, i*4);
+        return PyInt_FromLong(val);
+}
+
+static PyObject *
+audioop_max(PyObject *self, PyObject *args)
+{
+        signed char *cp;
+        int len, size, val = 0;
+        int i;
+        int max = 0;
+
+        if ( !PyArg_ParseTuple(args, "s#i:max", &cp, &len, &size) )
+                return 0;
+        if ( size != 1 && size != 2 && size != 4 ) {
+                PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
+                return 0;
+        }
+        for ( i=0; i<len; i+= size) {
+                if ( size == 1 )      val = (int)*CHARP(cp, i);
+                else if ( size == 2 ) val = (int)*SHORTP(cp, i);
+                else if ( size == 4 ) val = (int)*LONGP(cp, i);
+                if ( val < 0 ) val = (-val);
+                if ( val > max ) max = val;
+        }
+        return PyInt_FromLong(max);
+}
+
+static PyObject *
+audioop_minmax(PyObject *self, PyObject *args)
+{
+        signed char *cp;
+        int len, size, val = 0;
+        int i;
+        int min = 0x7fffffff, max = -0x7fffffff;
+
+        if (!PyArg_ParseTuple(args, "s#i:minmax", &cp, &len, &size))
+                return NULL;
+        if (size != 1 && size != 2 && size != 4) {
+                PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
+                return NULL;
+        }
+        for (i = 0; i < len; i += size) {
+                if (size == 1) val = (int) *CHARP(cp, i);
+                else if (size == 2) val = (int) *SHORTP(cp, i);
+                else if (size == 4) val = (int) *LONGP(cp, i);
+                if (val > max) max = val;
+                if (val < min) min = val;
+        }
+        return Py_BuildValue("(ii)", min, max);
+}
+
+static PyObject *
+audioop_avg(PyObject *self, PyObject *args)
+{
+        signed char *cp;
+        int len, size, val = 0;
+        int i;
+        double avg = 0.0;
+
+        if ( !PyArg_ParseTuple(args, "s#i:avg", &cp, &len, &size) )
+                return 0;
+        if ( size != 1 && size != 2 && size != 4 ) {
+                PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
+                return 0;
+        }
+        for ( i=0; i<len; i+= size) {
+                if ( size == 1 )      val = (int)*CHARP(cp, i);
+                else if ( size == 2 ) val = (int)*SHORTP(cp, i);
+                else if ( size == 4 ) val = (int)*LONGP(cp, i);
+                avg += val;
+        }
+        if ( len == 0 )
+                val = 0;
+        else
+                val = (int)(avg / (double)(len/size));
+        return PyInt_FromLong(val);
+}
+
+static PyObject *
+audioop_rms(PyObject *self, PyObject *args)
+{
+        signed char *cp;
+        int len, size, val = 0;
+        int i;
+        double sum_squares = 0.0;
+
+        if ( !PyArg_ParseTuple(args, "s#i:rms", &cp, &len, &size) )
+                return 0;
+        if ( size != 1 && size != 2 && size != 4 ) {
+                PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
+                return 0;
+        }
+        for ( i=0; i<len; i+= size) {
+                if ( size == 1 )      val = (int)*CHARP(cp, i);
+                else if ( size == 2 ) val = (int)*SHORTP(cp, i);
+                else if ( size == 4 ) val = (int)*LONGP(cp, i);
+                sum_squares += (double)val*(double)val;
+        }
+        if ( len == 0 )
+                val = 0;
+        else
+                val = (int)sqrt(sum_squares / (double)(len/size));
+        return PyInt_FromLong(val);
+}
+
+static double _sum2(short *a, short *b, int len)
+{
+        int i;
+        double sum = 0.0;
+
+        for( i=0; i<len; i++) {
+                sum = sum + (double)a[i]*(double)b[i];
+        }
+        return sum;
+}
+
+/*
+** Findfit tries to locate a sample within another sample. Its main use
+** is in echo-cancellation (to find the feedback of the output signal in
+** the input signal).
+** The method used is as follows:
+**
+** let R be the reference signal (length n) and A the input signal (length N)
+** with N > n, and let all sums be over i from 0 to n-1.
+**
+** Now, for each j in {0..N-n} we compute a factor fj so that -fj*R matches A
+** as good as possible, i.e. sum( (A[j+i]+fj*R[i])^2 ) is minimal. This
+** equation gives fj = sum( A[j+i]R[i] ) / sum(R[i]^2).
+**
+** Next, we compute the relative distance between the original signal and
+** the modified signal and minimize that over j:
+** vj = sum( (A[j+i]-fj*R[i])^2 ) / sum( A[j+i]^2 )  =>
+** vj = ( sum(A[j+i]^2)*sum(R[i]^2) - sum(A[j+i]R[i])^2 ) / sum( A[j+i]^2 )
+**
+** In the code variables correspond as follows:
+** cp1          A
+** cp2          R
+** len1         N
+** len2         n
+** aj_m1        A[j-1]
+** aj_lm1       A[j+n-1]
+** sum_ri_2     sum(R[i]^2)
+** sum_aij_2    sum(A[i+j]^2)
+** sum_aij_ri   sum(A[i+j]R[i])
+**
+** sum_ri is calculated once, sum_aij_2 is updated each step and sum_aij_ri
+** is completely recalculated each step.
+*/
+static PyObject *
+audioop_findfit(PyObject *self, PyObject *args)
+{
+        short *cp1, *cp2;
+        int len1, len2;
+        int j, best_j;
+        double aj_m1, aj_lm1;
+        double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor;
+
+        if ( !PyArg_ParseTuple(args, "s#s#:findfit",
+	                       &cp1, &len1, &cp2, &len2) )
+                return 0;
+        if ( len1 & 1 || len2 & 1 ) {
+                PyErr_SetString(AudioopError, "Strings should be even-sized");
+                return 0;
+        }
+        len1 >>= 1;
+        len2 >>= 1;
+    
+        if ( len1 < len2 ) {
+                PyErr_SetString(AudioopError, "First sample should be longer");
+                return 0;
+        }
+        sum_ri_2 = _sum2(cp2, cp2, len2);
+        sum_aij_2 = _sum2(cp1, cp1, len2);
+        sum_aij_ri = _sum2(cp1, cp2, len2);
+
+        result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2;
+
+        best_result = result;
+        best_j = 0;
+        j = 0;
+
+        for ( j=1; j<=len1-len2; j++) {
+                aj_m1 = (double)cp1[j-1];
+                aj_lm1 = (double)cp1[j+len2-1];
+
+                sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1;
+                sum_aij_ri = _sum2(cp1+j, cp2, len2);
+
+                result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri)
+                        / sum_aij_2;
+
+                if ( result < best_result ) {
+                        best_result = result;
+                        best_j = j;
+                }
+        
+        }
+
+        factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2;
+    
+        return Py_BuildValue("(if)", best_j, factor);
+}
+
+/*
+** findfactor finds a factor f so that the energy in A-fB is minimal.
+** See the comment for findfit for details.
+*/
+static PyObject *
+audioop_findfactor(PyObject *self, PyObject *args)
+{
+        short *cp1, *cp2;
+        int len1, len2;
+        double sum_ri_2, sum_aij_ri, result;
+
+        if ( !PyArg_ParseTuple(args, "s#s#:findfactor",
+	                       &cp1, &len1, &cp2, &len2) )
+                return 0;
+        if ( len1 & 1 || len2 & 1 ) {
+                PyErr_SetString(AudioopError, "Strings should be even-sized");
+                return 0;
+        }
+        if ( len1 != len2 ) {
+                PyErr_SetString(AudioopError, "Samples should be same size");
+                return 0;
+        }
+        len2 >>= 1;
+        sum_ri_2 = _sum2(cp2, cp2, len2);
+        sum_aij_ri = _sum2(cp1, cp2, len2);
+
+        result = sum_aij_ri / sum_ri_2;
+
+        return PyFloat_FromDouble(result);
+}
+
+/*
+** findmax returns the index of the n-sized segment of the input sample
+** that contains the most energy.
+*/
+static PyObject *
+audioop_findmax(PyObject *self, PyObject *args)
+{
+        short *cp1;
+        int len1, len2;
+        int j, best_j;
+        double aj_m1, aj_lm1;
+        double result, best_result;
+
+        if ( !PyArg_ParseTuple(args, "s#i:findmax", &cp1, &len1, &len2) )
+                return 0;
+        if ( len1 & 1 ) {
+                PyErr_SetString(AudioopError, "Strings should be even-sized");
+                return 0;
+        }
+        len1 >>= 1;
+    
+        if ( len1 < len2 ) {
+                PyErr_SetString(AudioopError, "Input sample should be longer");
+                return 0;
+        }
+
+        result = _sum2(cp1, cp1, len2);
+
+        best_result = result;
+        best_j = 0;
+        j = 0;
+
+        for ( j=1; j<=len1-len2; j++) {
+                aj_m1 = (double)cp1[j-1];
+                aj_lm1 = (double)cp1[j+len2-1];
+
+                result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1;
+
+                if ( result > best_result ) {
+                        best_result = result;
+                        best_j = j;
+                }
+        
+        }
+
+        return PyInt_FromLong(best_j);
+}
+
+static PyObject *
+audioop_avgpp(PyObject *self, PyObject *args)
+{
+        signed char *cp;
+        int len, size, val = 0, prevval = 0, prevextremevalid = 0,
+                prevextreme = 0;
+        int i;
+        double avg = 0.0;
+        int diff, prevdiff, extremediff, nextreme = 0;
+
+        if ( !PyArg_ParseTuple(args, "s#i:avgpp", &cp, &len, &size) )
+                return 0;
+        if ( size != 1 && size != 2 && size != 4 ) {
+                PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
+                return 0;
+        }
+        /* Compute first delta value ahead. Also automatically makes us
+        ** skip the first extreme value
+        */
+        if ( size == 1 )      prevval = (int)*CHARP(cp, 0);
+        else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
+        else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
+        if ( size == 1 )      val = (int)*CHARP(cp, size);
+        else if ( size == 2 ) val = (int)*SHORTP(cp, size);
+        else if ( size == 4 ) val = (int)*LONGP(cp, size);
+        prevdiff = val - prevval;
+    
+        for ( i=size; i<len; i+= size) {
+                if ( size == 1 )      val = (int)*CHARP(cp, i);
+                else if ( size == 2 ) val = (int)*SHORTP(cp, i);
+                else if ( size == 4 ) val = (int)*LONGP(cp, i);
+                diff = val - prevval;
+                if ( diff*prevdiff < 0 ) {
+                        /* Derivative changed sign. Compute difference to last
+                        ** extreme value and remember.
+                        */
+                        if ( prevextremevalid ) {
+                                extremediff = prevval - prevextreme;
+                                if ( extremediff < 0 )
+                                        extremediff = -extremediff;
+                                avg += extremediff;
+                                nextreme++;
+                        }
+                        prevextremevalid = 1;
+                        prevextreme = prevval;
+                }
+                prevval = val;
+                if ( diff != 0 )
+                        prevdiff = diff;        
+        }
+        if ( nextreme == 0 )
+                val = 0;
+        else
+                val = (int)(avg / (double)nextreme);
+        return PyInt_FromLong(val);
+}
+
+static PyObject *
+audioop_maxpp(PyObject *self, PyObject *args)
+{
+        signed char *cp;
+        int len, size, val = 0, prevval = 0, prevextremevalid = 0,
+                prevextreme = 0;
+        int i;
+        int max = 0;
+        int diff, prevdiff, extremediff;
+
+        if ( !PyArg_ParseTuple(args, "s#i:maxpp", &cp, &len, &size) )
+                return 0;
+        if ( size != 1 && size != 2 && size != 4 ) {
+                PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
+                return 0;
+        }
+        /* Compute first delta value ahead. Also automatically makes us
+        ** skip the first extreme value
+        */
+        if ( size == 1 )      prevval = (int)*CHARP(cp, 0);
+        else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
+        else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
+        if ( size == 1 )      val = (int)*CHARP(cp, size);
+        else if ( size == 2 ) val = (int)*SHORTP(cp, size);
+        else if ( size == 4 ) val = (int)*LONGP(cp, size);
+        prevdiff = val - prevval;
+
+        for ( i=size; i<len; i+= size) {
+                if ( size == 1 )      val = (int)*CHARP(cp, i);
+                else if ( size == 2 ) val = (int)*SHORTP(cp, i);
+                else if ( size == 4 ) val = (int)*LONGP(cp, i);
+                diff = val - prevval;
+                if ( diff*prevdiff < 0 ) {
+                        /* Derivative changed sign. Compute difference to
+                        ** last extreme value and remember.
+                        */
+                        if ( prevextremevalid ) {
+                                extremediff = prevval - prevextreme;
+                                if ( extremediff < 0 )
+                                        extremediff = -extremediff;
+                                if ( extremediff > max )
+                                        max = extremediff;
+                        }
+                        prevextremevalid = 1;
+                        prevextreme = prevval;
+                }
+                prevval = val;
+                if ( diff != 0 )
+                        prevdiff = diff;
+        }
+        return PyInt_FromLong(max);
+}
+
+static PyObject *
+audioop_cross(PyObject *self, PyObject *args)
+{
+        signed char *cp;
+        int len, size, val = 0;
+        int i;
+        int prevval, ncross;
+
+        if ( !PyArg_ParseTuple(args, "s#i:cross", &cp, &len, &size) )
+                return 0;
+        if ( size != 1 && size != 2 && size != 4 ) {
+                PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
+                return 0;
+        }
+        ncross = -1;
+        prevval = 17; /* Anything <> 0,1 */
+        for ( i=0; i<len; i+= size) {
+                if ( size == 1 )      val = ((int)*CHARP(cp, i)) >> 7;
+                else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) >> 15;
+                else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 31;
+                val = val & 1;
+                if ( val != prevval ) ncross++;
+                prevval = val;
+        }
+        return PyInt_FromLong(ncross);
+}
+
+static PyObject *
+audioop_mul(PyObject *self, PyObject *args)
+{
+        signed char *cp, *ncp;
+        int len, size, val = 0;
+        double factor, fval, maxval;
+        PyObject *rv;
+        int i;
+
+        if ( !PyArg_ParseTuple(args, "s#id:mul", &cp, &len, &size, &factor ) )
+                return 0;
+    
+        if ( size == 1 ) maxval = (double) 0x7f;
+        else if ( size == 2 ) maxval = (double) 0x7fff;
+        else if ( size == 4 ) maxval = (double) 0x7fffffff;
+        else {
+                PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
+                return 0;
+        }
+    
+        rv = PyString_FromStringAndSize(NULL, len);
+        if ( rv == 0 )
+                return 0;
+        ncp = (signed char *)PyString_AsString(rv);
+    
+    
+        for ( i=0; i < len; i += size ) {
+                if ( size == 1 )      val = (int)*CHARP(cp, i);
+                else if ( size == 2 ) val = (int)*SHORTP(cp, i);
+                else if ( size == 4 ) val = (int)*LONGP(cp, i);
+                fval = (double)val*factor;
+                if ( fval > maxval ) fval = maxval;
+                else if ( fval < -maxval ) fval = -maxval;
+                val = (int)fval;
+                if ( size == 1 )      *CHARP(ncp, i) = (signed char)val;
+                else if ( size == 2 ) *SHORTP(ncp, i) = (short)val;
+                else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)val;
+        }
+        return rv;
+}
+
+static PyObject *
+audioop_tomono(PyObject *self, PyObject *args)
+{
+        signed char *cp, *ncp;
+        int len, size, val1 = 0, val2 = 0;
+        double fac1, fac2, fval, maxval;
+        PyObject *rv;
+        int i;
+
+        if ( !PyArg_ParseTuple(args, "s#idd:tomono",
+	                       &cp, &len, &size, &fac1, &fac2 ) )
+                return 0;
+    
+        if ( size == 1 ) maxval = (double) 0x7f;
+        else if ( size == 2 ) maxval = (double) 0x7fff;
+        else if ( size == 4 ) maxval = (double) 0x7fffffff;
+        else {
+                PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
+                return 0;
+        }
+    
+        rv = PyString_FromStringAndSize(NULL, len/2);
+        if ( rv == 0 )
+                return 0;
+        ncp = (signed char *)PyString_AsString(rv);
+    
+    
+        for ( i=0; i < len; i += size*2 ) {
+                if ( size == 1 )      val1 = (int)*CHARP(cp, i);
+                else if ( size == 2 ) val1 = (int)*SHORTP(cp, i);
+                else if ( size == 4 ) val1 = (int)*LONGP(cp, i);
+                if ( size == 1 )      val2 = (int)*CHARP(cp, i+1);
+                else if ( size == 2 ) val2 = (int)*SHORTP(cp, i+2);
+                else if ( size == 4 ) val2 = (int)*LONGP(cp, i+4);
+                fval = (double)val1*fac1 + (double)val2*fac2;
+                if ( fval > maxval ) fval = maxval;
+                else if ( fval < -maxval ) fval = -maxval;
+                val1 = (int)fval;
+                if ( size == 1 )      *CHARP(ncp, i/2) = (signed char)val1;
+                else if ( size == 2 ) *SHORTP(ncp, i/2) = (short)val1;
+                else if ( size == 4 ) *LONGP(ncp, i/2)= (Py_Int32)val1;
+        }
+        return rv;
+}
+
+static PyObject *
+audioop_tostereo(PyObject *self, PyObject *args)
+{
+        signed char *cp, *ncp;
+        int len, size, val1, val2, val = 0;
+        double fac1, fac2, fval, maxval;
+        PyObject *rv;
+        int i;
+
+        if ( !PyArg_ParseTuple(args, "s#idd:tostereo",
+	                       &cp, &len, &size, &fac1, &fac2 ) )
+                return 0;
+    
+        if ( size == 1 ) maxval = (double) 0x7f;
+        else if ( size == 2 ) maxval = (double) 0x7fff;
+        else if ( size == 4 ) maxval = (double) 0x7fffffff;
+        else {
+                PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
+                return 0;
+        }
+    
+        rv = PyString_FromStringAndSize(NULL, len*2);
+        if ( rv == 0 )
+                return 0;
+        ncp = (signed char *)PyString_AsString(rv);
+    
+    
+        for ( i=0; i < len; i += size ) {
+                if ( size == 1 )      val = (int)*CHARP(cp, i);
+                else if ( size == 2 ) val = (int)*SHORTP(cp, i);
+                else if ( size == 4 ) val = (int)*LONGP(cp, i);
+
+                fval = (double)val*fac1;
+                if ( fval > maxval ) fval = maxval;
+                else if ( fval < -maxval ) fval = -maxval;
+                val1 = (int)fval;
+
+                fval = (double)val*fac2;
+                if ( fval > maxval ) fval = maxval;
+                else if ( fval < -maxval ) fval = -maxval;
+                val2 = (int)fval;
+
+                if ( size == 1 )      *CHARP(ncp, i*2) = (signed char)val1;
+                else if ( size == 2 ) *SHORTP(ncp, i*2) = (short)val1;
+                else if ( size == 4 ) *LONGP(ncp, i*2) = (Py_Int32)val1;
+
+                if ( size == 1 )      *CHARP(ncp, i*2+1) = (signed char)val2;
+                else if ( size == 2 ) *SHORTP(ncp, i*2+2) = (short)val2;
+                else if ( size == 4 ) *LONGP(ncp, i*2+4) = (Py_Int32)val2;
+        }
+        return rv;
+}
+
+static PyObject *
+audioop_add(PyObject *self, PyObject *args)
+{
+        signed char *cp1, *cp2, *ncp;
+        int len1, len2, size, val1 = 0, val2 = 0, maxval, newval;
+        PyObject *rv;
+        int i;
+
+        if ( !PyArg_ParseTuple(args, "s#s#i:add",
+                          &cp1, &len1, &cp2, &len2, &size ) )
+                return 0;
+
+        if ( len1 != len2 ) {
+                PyErr_SetString(AudioopError, "Lengths should be the same");
+                return 0;
+        }
+    
+        if ( size == 1 ) maxval = 0x7f;
+        else if ( size == 2 ) maxval = 0x7fff;
+        else if ( size == 4 ) maxval = 0x7fffffff;
+        else {
+                PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
+                return 0;
+        }
+
+        rv = PyString_FromStringAndSize(NULL, len1);
+        if ( rv == 0 )
+                return 0;
+        ncp = (signed char *)PyString_AsString(rv);
+
+        for ( i=0; i < len1; i += size ) {
+                if ( size == 1 )      val1 = (int)*CHARP(cp1, i);
+                else if ( size == 2 ) val1 = (int)*SHORTP(cp1, i);
+                else if ( size == 4 ) val1 = (int)*LONGP(cp1, i);
+        
+                if ( size == 1 )      val2 = (int)*CHARP(cp2, i);
+                else if ( size == 2 ) val2 = (int)*SHORTP(cp2, i);
+                else if ( size == 4 ) val2 = (int)*LONGP(cp2, i);
+
+                newval = val1 + val2;
+                /* truncate in case of overflow */
+                if (newval > maxval) newval = maxval;
+                else if (newval < -maxval) newval = -maxval;
+                else if (size == 4 && (newval^val1) < 0 && (newval^val2) < 0)
+                        newval = val1 > 0 ? maxval : - maxval;
+
+                if ( size == 1 )      *CHARP(ncp, i) = (signed char)newval;
+                else if ( size == 2 ) *SHORTP(ncp, i) = (short)newval;
+                else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)newval;
+        }
+        return rv;
+}
+
+static PyObject *
+audioop_bias(PyObject *self, PyObject *args)
+{
+        signed char *cp, *ncp;
+        int len, size, val = 0;
+        PyObject *rv;
+        int i;
+        int bias;
+
+        if ( !PyArg_ParseTuple(args, "s#ii:bias",
+                          &cp, &len, &size , &bias) )
+                return 0;
+
+        if ( size != 1 && size != 2 && size != 4) {
+                PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
+                return 0;
+        }
+    
+        rv = PyString_FromStringAndSize(NULL, len);
+        if ( rv == 0 )
+                return 0;
+        ncp = (signed char *)PyString_AsString(rv);
+    
+    
+        for ( i=0; i < len; i += size ) {
+                if ( size == 1 )      val = (int)*CHARP(cp, i);
+                else if ( size == 2 ) val = (int)*SHORTP(cp, i);
+                else if ( size == 4 ) val = (int)*LONGP(cp, i);
+        
+                if ( size == 1 )      *CHARP(ncp, i) = (signed char)(val+bias);
+                else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val+bias);
+                else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val+bias);
+        }
+        return rv;
+}
+
+static PyObject *
+audioop_reverse(PyObject *self, PyObject *args)
+{
+        signed char *cp;
+        unsigned char *ncp;
+        int len, size, val = 0;
+        PyObject *rv;
+        int i, j;
+
+        if ( !PyArg_ParseTuple(args, "s#i:reverse",
+                          &cp, &len, &size) )
+                return 0;
+
+        if ( size != 1 && size != 2 && size != 4 ) {
+                PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
+                return 0;
+        }
+    
+        rv = PyString_FromStringAndSize(NULL, len);
+        if ( rv == 0 )
+                return 0;
+        ncp = (unsigned char *)PyString_AsString(rv);
+    
+        for ( i=0; i < len; i += size ) {
+                if ( size == 1 )      val = ((int)*CHARP(cp, i)) << 8;
+                else if ( size == 2 ) val = (int)*SHORTP(cp, i);
+                else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
+
+                j = len - i - size;
+        
+                if ( size == 1 )      *CHARP(ncp, j) = (signed char)(val >> 8);
+                else if ( size == 2 ) *SHORTP(ncp, j) = (short)(val);
+                else if ( size == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
+        }
+        return rv;
+}
+
+static PyObject *
+audioop_lin2lin(PyObject *self, PyObject *args)
+{
+        signed char *cp;
+        unsigned char *ncp;
+        int len, size, size2, val = 0;
+        PyObject *rv;
+        int i, j;
+
+        if ( !PyArg_ParseTuple(args, "s#ii:lin2lin",
+                          &cp, &len, &size, &size2) )
+                return 0;
+
+        if ( (size != 1 && size != 2 && size != 4) ||
+             (size2 != 1 && size2 != 2 && size2 != 4)) {
+                PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
+                return 0;
+        }
+    
+        rv = PyString_FromStringAndSize(NULL, (len/size)*size2);
+        if ( rv == 0 )
+                return 0;
+        ncp = (unsigned char *)PyString_AsString(rv);
+    
+        for ( i=0, j=0; i < len; i += size, j += size2 ) {
+                if ( size == 1 )      val = ((int)*CHARP(cp, i)) << 8;
+                else if ( size == 2 ) val = (int)*SHORTP(cp, i);
+                else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
+
+                if ( size2 == 1 )  *CHARP(ncp, j) = (signed char)(val >> 8);
+                else if ( size2 == 2 ) *SHORTP(ncp, j) = (short)(val);
+                else if ( size2 == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
+        }
+        return rv;
+}
+
+static int
+gcd(int a, int b)
+{
+        while (b > 0) {
+                int tmp = a % b;
+                a = b;
+                b = tmp;
+        }
+        return a;
+}
+
+static PyObject *
+audioop_ratecv(PyObject *self, PyObject *args)
+{
+        char *cp, *ncp;
+        int len, size, nchannels, inrate, outrate, weightA, weightB;
+        int chan, d, *prev_i, *cur_i, cur_o;
+        PyObject *state, *samps, *str, *rv = NULL;
+        int bytes_per_frame;
+
+        weightA = 1;
+        weightB = 0;
+        if (!PyArg_ParseTuple(args, "s#iiiiO|ii:ratecv", &cp, &len, &size,
+	                      &nchannels, &inrate, &outrate, &state,
+			      &weightA, &weightB))
+                return NULL;
+        if (size != 1 && size != 2 && size != 4) {
+                PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
+                return NULL;
+        }
+        if (nchannels < 1) {
+                PyErr_SetString(AudioopError, "# of channels should be >= 1");
+                return NULL;
+        }
+        bytes_per_frame = size * nchannels;
+        if (bytes_per_frame / nchannels != size) {
+                /* This overflow test is rigorously correct because
+                   both multiplicands are >= 1.  Use the argument names
+                   from the docs for the error msg. */
+                PyErr_SetString(PyExc_OverflowError,
+                                "width * nchannels too big for a C int");
+                return NULL;
+        }
+        if (weightA < 1 || weightB < 0) {
+                PyErr_SetString(AudioopError,
+                        "weightA should be >= 1, weightB should be >= 0");
+                return NULL;
+        }
+        if (len % bytes_per_frame != 0) {
+                PyErr_SetString(AudioopError, "not a whole number of frames");
+                return NULL;
+        }
+        if (inrate <= 0 || outrate <= 0) {
+                PyErr_SetString(AudioopError, "sampling rate not > 0");
+                return NULL;
+        }
+        /* divide inrate and outrate by their greatest common divisor */
+        d = gcd(inrate, outrate);
+        inrate /= d;
+        outrate /= d;
+
+        prev_i = (int *) malloc(nchannels * sizeof(int));
+        cur_i = (int *) malloc(nchannels * sizeof(int));
+        if (prev_i == NULL || cur_i == NULL) {
+                (void) PyErr_NoMemory();
+                goto exit;
+        }
+
+        len /= bytes_per_frame; /* # of frames */
+
+        if (state == Py_None) {
+                d = -outrate;
+                for (chan = 0; chan < nchannels; chan++)
+                        prev_i[chan] = cur_i[chan] = 0;
+        }
+        else {
+                if (!PyArg_ParseTuple(state,
+                                "iO!;audioop.ratecv: illegal state argument",
+                                &d, &PyTuple_Type, &samps))
+                        goto exit;
+                if (PyTuple_Size(samps) != nchannels) {
+                        PyErr_SetString(AudioopError,
+                                        "illegal state argument");
+                        goto exit;
+                }
+                for (chan = 0; chan < nchannels; chan++) {
+                        if (!PyArg_ParseTuple(PyTuple_GetItem(samps, chan),
+                                              "ii:ratecv", &prev_i[chan], 
+					                   &cur_i[chan]))
+                                goto exit;
+                }
+        }
+
+        /* str <- Space for the output buffer. */
+        {
+                /* There are len input frames, so we need (mathematically)
+                   ceiling(len*outrate/inrate) output frames, and each frame
+                   requires bytes_per_frame bytes.  Computing this
+                   without spurious overflow is the challenge; we can
+                   settle for a reasonable upper bound, though. */
+                int ceiling;   /* the number of output frames */
+                int nbytes;    /* the number of output bytes needed */
+                int q = len / inrate;
+                /* Now len = q * inrate + r exactly (with r = len % inrate),
+                   and this is less than q * inrate + inrate = (q+1)*inrate.
+                   So a reasonable upper bound on len*outrate/inrate is
+                   ((q+1)*inrate)*outrate/inrate =
+                   (q+1)*outrate.
+                */
+                ceiling = (q+1) * outrate;
+                nbytes = ceiling * bytes_per_frame;
+                /* See whether anything overflowed; if not, get the space. */
+                if (q+1 < 0 ||
+                    ceiling / outrate != q+1 ||
+                    nbytes / bytes_per_frame != ceiling)
+                        str = NULL;
+                else
+                        str = PyString_FromStringAndSize(NULL, nbytes);
+
+                if (str == NULL) {
+                        PyErr_SetString(PyExc_MemoryError,
+                                "not enough memory for output buffer");
+                        goto exit;
+                }
+        }
+        ncp = PyString_AsString(str);
+
+        for (;;) {
+                while (d < 0) {
+                        if (len == 0) {
+                                samps = PyTuple_New(nchannels);
+                                if (samps == NULL)
+                                        goto exit;
+                                for (chan = 0; chan < nchannels; chan++)
+                                        PyTuple_SetItem(samps, chan,
+                                                Py_BuildValue("(ii)",
+                                                              prev_i[chan],
+                                                              cur_i[chan]));
+                                if (PyErr_Occurred())
+                                        goto exit;
+                                /* We have checked before that the length
+                                 * of the string fits into int. */
+                                len = (int)(ncp - PyString_AsString(str));
+                                if (len == 0) {
+                                        /*don't want to resize to zero length*/
+                                        rv = PyString_FromStringAndSize("", 0);
+                                        Py_DECREF(str);
+                                        str = rv;
+                                } else if (_PyString_Resize(&str, len) < 0)
+                                        goto exit;
+                                rv = Py_BuildValue("(O(iO))", str, d, samps);
+                                Py_DECREF(samps);
+                                Py_DECREF(str);
+                                goto exit; /* return rv */
+                        }
+                        for (chan = 0; chan < nchannels; chan++) {
+                                prev_i[chan] = cur_i[chan];
+                                if (size == 1)
+                                    cur_i[chan] = ((int)*CHARP(cp, 0)) << 8;
+                                else if (size == 2)
+                                    cur_i[chan] = (int)*SHORTP(cp, 0);
+                                else if (size == 4)
+                                    cur_i[chan] = ((int)*LONGP(cp, 0)) >> 16;
+                                cp += size;
+                                /* implements a simple digital filter */
+                                cur_i[chan] =
+                                        (weightA * cur_i[chan] +
+                                         weightB * prev_i[chan]) /
+                                        (weightA + weightB);
+                        }
+                        len--;
+                        d += outrate;
+                }
+                while (d >= 0) {
+                        for (chan = 0; chan < nchannels; chan++) {
+                                cur_o = (prev_i[chan] * d +
+                                         cur_i[chan] * (outrate - d)) /
+                                        outrate;
+                                if (size == 1)
+                                    *CHARP(ncp, 0) = (signed char)(cur_o >> 8);
+                                else if (size == 2)
+                                    *SHORTP(ncp, 0) = (short)(cur_o);
+                                else if (size == 4)
+                                    *LONGP(ncp, 0) = (Py_Int32)(cur_o<<16);
+                                ncp += size;
+                        }
+                        d -= inrate;
+                }
+        }
+  exit:
+        if (prev_i != NULL)
+                free(prev_i);
+        if (cur_i != NULL)
+                free(cur_i);
+        return rv;
+}
+
+static PyObject *
+audioop_lin2ulaw(PyObject *self, PyObject *args)
+{
+        signed char *cp;
+        unsigned char *ncp;
+        int len, size, val = 0;
+        PyObject *rv;
+        int i;
+
+        if ( !PyArg_ParseTuple(args, "s#i:lin2ulaw",
+                               &cp, &len, &size) )
+                return 0 ;
+
+        if ( size != 1 && size != 2 && size != 4) {
+                PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
+                return 0;
+        }
+    
+        rv = PyString_FromStringAndSize(NULL, len/size);
+        if ( rv == 0 )
+                return 0;
+        ncp = (unsigned char *)PyString_AsString(rv);
+    
+        for ( i=0; i < len; i += size ) {
+                if ( size == 1 )      val = ((int)*CHARP(cp, i)) << 8;
+                else if ( size == 2 ) val = (int)*SHORTP(cp, i);
+                else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
+
+                *ncp++ = st_14linear2ulaw(val);
+        }
+        return rv;
+}
+
+static PyObject *
+audioop_ulaw2lin(PyObject *self, PyObject *args)
+{
+        unsigned char *cp;
+        unsigned char cval;
+        signed char *ncp;
+        int len, size, val;
+        PyObject *rv;
+        int i;
+
+        if ( !PyArg_ParseTuple(args, "s#i:ulaw2lin",
+                               &cp, &len, &size) )
+                return 0;
+
+        if ( size != 1 && size != 2 && size != 4) {
+                PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
+                return 0;
+        }
+    
+        rv = PyString_FromStringAndSize(NULL, len*size);
+        if ( rv == 0 )
+                return 0;
+        ncp = (signed char *)PyString_AsString(rv);
+    
+        for ( i=0; i < len*size; i += size ) {
+                cval = *cp++;
+                val = st_ulaw2linear16(cval);
+        
+                if ( size == 1 )      *CHARP(ncp, i) = (signed char)(val >> 8);
+                else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
+                else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
+        }
+        return rv;
+}
+
+static PyObject *
+audioop_lin2alaw(PyObject *self, PyObject *args)
+{
+        signed char *cp;
+        unsigned char *ncp;
+        int len, size, val = 0;
+        PyObject *rv;
+        int i;
+
+        if ( !PyArg_ParseTuple(args, "s#i:lin2alaw",
+                               &cp, &len, &size) )
+                return 0;
+
+        if ( size != 1 && size != 2 && size != 4) {
+                PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
+                return 0;
+        }
+    
+        rv = PyString_FromStringAndSize(NULL, len/size);
+        if ( rv == 0 )
+                return 0;
+        ncp = (unsigned char *)PyString_AsString(rv);
+    
+        for ( i=0; i < len; i += size ) {
+                if ( size == 1 )      val = ((int)*CHARP(cp, i)) << 8;
+                else if ( size == 2 ) val = (int)*SHORTP(cp, i);
+                else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
+
+                *ncp++ = st_linear2alaw(val);
+        }
+        return rv;
+}
+
+static PyObject *
+audioop_alaw2lin(PyObject *self, PyObject *args)
+{
+        unsigned char *cp;
+        unsigned char cval;
+        signed char *ncp;
+        int len, size, val;
+        PyObject *rv;
+        int i;
+
+        if ( !PyArg_ParseTuple(args, "s#i:alaw2lin",
+                               &cp, &len, &size) )
+                return 0;
+
+        if ( size != 1 && size != 2 && size != 4) {
+                PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
+                return 0;
+        }
+    
+        rv = PyString_FromStringAndSize(NULL, len*size);
+        if ( rv == 0 )
+                return 0;
+        ncp = (signed char *)PyString_AsString(rv);
+    
+        for ( i=0; i < len*size; i += size ) {
+                cval = *cp++;
+                val = st_alaw2linear16(cval);
+        
+                if ( size == 1 )      *CHARP(ncp, i) = (signed char)(val >> 8);
+                else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
+                else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
+        }
+        return rv;
+}
+
+static PyObject *
+audioop_lin2adpcm(PyObject *self, PyObject *args)
+{
+        signed char *cp;
+        signed char *ncp;
+        int len, size, val = 0, step, valpred, delta,
+                index, sign, vpdiff, diff;
+        PyObject *rv, *state, *str;
+        int i, outputbuffer = 0, bufferstep;
+
+        if ( !PyArg_ParseTuple(args, "s#iO:lin2adpcm",
+                               &cp, &len, &size, &state) )
+                return 0;
+    
+
+        if ( size != 1 && size != 2 && size != 4) {
+                PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
+                return 0;
+        }
+    
+        str = PyString_FromStringAndSize(NULL, len/(size*2));
+        if ( str == 0 )
+                return 0;
+        ncp = (signed char *)PyString_AsString(str);
+
+        /* Decode state, should have (value, step) */
+        if ( state == Py_None ) {
+                /* First time, it seems. Set defaults */
+                valpred = 0;
+                step = 7;
+                index = 0;
+        } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) )
+                return 0;
+
+        step = stepsizeTable[index];
+        bufferstep = 1;
+
+        for ( i=0; i < len; i += size ) {
+                if ( size == 1 )      val = ((int)*CHARP(cp, i)) << 8;
+                else if ( size == 2 ) val = (int)*SHORTP(cp, i);
+                else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
+
+                /* Step 1 - compute difference with previous value */
+                diff = val - valpred;
+                sign = (diff < 0) ? 8 : 0;
+                if ( sign ) diff = (-diff);
+
+                /* Step 2 - Divide and clamp */
+                /* Note:
+                ** This code *approximately* computes:
+                **    delta = diff*4/step;
+                **    vpdiff = (delta+0.5)*step/4;
+                ** but in shift step bits are dropped. The net result of this
+                ** is that even if you have fast mul/div hardware you cannot
+                ** put it to good use since the fixup would be too expensive.
+                */
+                delta = 0;
+                vpdiff = (step >> 3);
+        
+                if ( diff >= step ) {
+                        delta = 4;
+                        diff -= step;
+                        vpdiff += step;
+                }
+                step >>= 1;
+                if ( diff >= step  ) {
+                        delta |= 2;
+                        diff -= step;
+                        vpdiff += step;
+                }
+                step >>= 1;
+                if ( diff >= step ) {
+                        delta |= 1;
+                        vpdiff += step;
+                }
+
+                /* Step 3 - Update previous value */
+                if ( sign )
+                        valpred -= vpdiff;
+                else
+                        valpred += vpdiff;
+
+                /* Step 4 - Clamp previous value to 16 bits */
+                if ( valpred > 32767 )
+                        valpred = 32767;
+                else if ( valpred < -32768 )
+                        valpred = -32768;
+
+                /* Step 5 - Assemble value, update index and step values */
+                delta |= sign;
+        
+                index += indexTable[delta];
+                if ( index < 0 ) index = 0;
+                if ( index > 88 ) index = 88;
+                step = stepsizeTable[index];
+
+                /* Step 6 - Output value */
+                if ( bufferstep ) {
+                        outputbuffer = (delta << 4) & 0xf0;
+                } else {
+                        *ncp++ = (delta & 0x0f) | outputbuffer;
+                }
+                bufferstep = !bufferstep;
+        }
+        rv = Py_BuildValue("(O(ii))", str, valpred, index);
+        Py_DECREF(str);
+        return rv;
+}
+
+static PyObject *
+audioop_adpcm2lin(PyObject *self, PyObject *args)
+{
+        signed char *cp;
+        signed char *ncp;
+        int len, size, valpred, step, delta, index, sign, vpdiff;
+        PyObject *rv, *str, *state;
+        int i, inputbuffer = 0, bufferstep;
+
+        if ( !PyArg_ParseTuple(args, "s#iO:adpcm2lin",
+                               &cp, &len, &size, &state) )
+                return 0;
+
+        if ( size != 1 && size != 2 && size != 4) {
+                PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
+                return 0;
+        }
+    
+        /* Decode state, should have (value, step) */
+        if ( state == Py_None ) {
+                /* First time, it seems. Set defaults */
+                valpred = 0;
+                step = 7;
+                index = 0;
+        } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) )
+                return 0;
+    
+        str = PyString_FromStringAndSize(NULL, len*size*2);
+        if ( str == 0 )
+                return 0;
+        ncp = (signed char *)PyString_AsString(str);
+
+        step = stepsizeTable[index];
+        bufferstep = 0;
+    
+        for ( i=0; i < len*size*2; i += size ) {
+                /* Step 1 - get the delta value and compute next index */
+                if ( bufferstep ) {
+                        delta = inputbuffer & 0xf;
+                } else {
+                        inputbuffer = *cp++;
+                        delta = (inputbuffer >> 4) & 0xf;
+                }
+
+                bufferstep = !bufferstep;
+
+                /* Step 2 - Find new index value (for later) */
+                index += indexTable[delta];
+                if ( index < 0 ) index = 0;
+                if ( index > 88 ) index = 88;
+
+                /* Step 3 - Separate sign and magnitude */
+                sign = delta & 8;
+                delta = delta & 7;
+
+                /* Step 4 - Compute difference and new predicted value */
+                /*
+                ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
+                ** in adpcm_coder.
+                */
+                vpdiff = step >> 3;
+                if ( delta & 4 ) vpdiff += step;
+                if ( delta & 2 ) vpdiff += step>>1;
+                if ( delta & 1 ) vpdiff += step>>2;
+
+                if ( sign )
+                        valpred -= vpdiff;
+                else
+                        valpred += vpdiff;
+
+                /* Step 5 - clamp output value */
+                if ( valpred > 32767 )
+                        valpred = 32767;
+                else if ( valpred < -32768 )
+                        valpred = -32768;
+
+                /* Step 6 - Update step value */
+                step = stepsizeTable[index];
+
+                /* Step 6 - Output value */
+                if ( size == 1 ) *CHARP(ncp, i) = (signed char)(valpred >> 8);
+                else if ( size == 2 ) *SHORTP(ncp, i) = (short)(valpred);
+                else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(valpred<<16);
+        }
+
+        rv = Py_BuildValue("(O(ii))", str, valpred, index);
+        Py_DECREF(str);
+        return rv;
+}
+
+static PyMethodDef audioop_methods[] = {
+        { "max", audioop_max, METH_VARARGS },
+        { "minmax", audioop_minmax, METH_VARARGS },
+        { "avg", audioop_avg, METH_VARARGS },
+        { "maxpp", audioop_maxpp, METH_VARARGS },
+        { "avgpp", audioop_avgpp, METH_VARARGS },
+        { "rms", audioop_rms, METH_VARARGS },
+        { "findfit", audioop_findfit, METH_VARARGS },
+        { "findmax", audioop_findmax, METH_VARARGS },
+        { "findfactor", audioop_findfactor, METH_VARARGS },
+        { "cross", audioop_cross, METH_VARARGS },
+        { "mul", audioop_mul, METH_VARARGS },
+        { "add", audioop_add, METH_VARARGS },
+        { "bias", audioop_bias, METH_VARARGS },
+        { "ulaw2lin", audioop_ulaw2lin, METH_VARARGS },
+        { "lin2ulaw", audioop_lin2ulaw, METH_VARARGS },
+        { "alaw2lin", audioop_alaw2lin, METH_VARARGS },
+        { "lin2alaw", audioop_lin2alaw, METH_VARARGS },
+        { "lin2lin", audioop_lin2lin, METH_VARARGS },
+        { "adpcm2lin", audioop_adpcm2lin, METH_VARARGS },
+        { "lin2adpcm", audioop_lin2adpcm, METH_VARARGS },
+        { "tomono", audioop_tomono, METH_VARARGS },
+        { "tostereo", audioop_tostereo, METH_VARARGS },
+        { "getsample", audioop_getsample, METH_VARARGS },
+        { "reverse", audioop_reverse, METH_VARARGS },
+        { "ratecv", audioop_ratecv, METH_VARARGS },
+        { 0,          0 }
+};
+
+PyMODINIT_FUNC
+initaudioop(void)
+{
+        PyObject *m, *d;
+        m = Py_InitModule("audioop", audioop_methods);
+        if (m == NULL)
+                return;
+        d = PyModule_GetDict(m);
+        if (d == NULL)
+                return;
+        AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
+        if (AudioopError != NULL)
+             PyDict_SetItemString(d,"error",AudioopError);
+}

Added: vendor/Python/current/Modules/binascii.c
===================================================================
--- vendor/Python/current/Modules/binascii.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/binascii.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1350 @@
+/*
+** Routines to represent binary data in ASCII and vice-versa
+**
+** This module currently supports the following encodings:
+** uuencode:
+**     	each line encodes 45 bytes (except possibly the last)
+**	First char encodes (binary) length, rest data
+**	each char encodes 6 bits, as follows:
+**	binary: 01234567 abcdefgh ijklmnop
+**	ascii:  012345 67abcd efghij klmnop
+**	ASCII encoding method is "excess-space": 000000 is encoded as ' ', etc.
+**	short binary data is zero-extended (so the bits are always in the
+**	right place), this does *not* reflect in the length.
+** base64:
+**      Line breaks are insignificant, but lines are at most 76 chars
+**      each char encodes 6 bits, in similar order as uucode/hqx. Encoding
+**      is done via a table.
+**      Short binary data is filled (in ASCII) with '='.
+** hqx:
+**	File starts with introductory text, real data starts and ends
+**	with colons.
+**	Data consists of three similar parts: info, datafork, resourcefork.
+**	Each part is protected (at the end) with a 16-bit crc
+**	The binary data is run-length encoded, and then ascii-fied:
+**	binary: 01234567 abcdefgh ijklmnop
+**	ascii:  012345 67abcd efghij klmnop
+**	ASCII encoding is table-driven, see the code.
+**	Short binary data results in the runt ascii-byte being output with
+**	the bits in the right place.
+**
+** While I was reading dozens of programs that encode or decode the formats
+** here (documentation? hihi:-) I have formulated Jansen's Observation:
+**
+**	Programs that encode binary data in ASCII are written in
+**	such a style that they are as unreadable as possible. Devices used
+**	include unnecessary global variables, burying important tables
+**	in unrelated sourcefiles, putting functions in include files,
+**	using seemingly-descriptive variable names for different purposes,
+**	calls to empty subroutines and a host of others.
+**
+** I have attempted to break with this tradition, but I guess that that
+** does make the performance sub-optimal. Oh well, too bad...
+**
+** Jack Jansen, CWI, July 1995.
+**
+** Added support for quoted-printable encoding, based on rfc 1521 et al
+** quoted-printable encoding specifies that non printable characters (anything
+** below 32 and above 126) be encoded as =XX where XX is the hexadecimal value
+** of the character.  It also specifies some other behavior to enable 8bit data
+** in a mail message with little difficulty (maximum line sizes, protecting
+** some cases of whitespace, etc).
+**
+** Brandon Long, September 2001.
+*/
+
+#define PY_SSIZE_T_CLEAN
+
+#include "Python.h"
+
+static PyObject *Error;
+static PyObject *Incomplete;
+
+/*
+** hqx lookup table, ascii->binary.
+*/
+
+#define RUNCHAR 0x90
+
+#define DONE 0x7F
+#define SKIP 0x7E
+#define FAIL 0x7D
+
+static unsigned char table_a2b_hqx[256] = {
+/*       ^@    ^A    ^B    ^C    ^D    ^E    ^F    ^G   */
+/* 0*/	FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+/*       \b    \t    \n    ^K    ^L    \r    ^N    ^O   */
+/* 1*/	FAIL, FAIL, SKIP, FAIL, FAIL, SKIP, FAIL, FAIL,
+/*       ^P    ^Q    ^R    ^S    ^T    ^U    ^V    ^W   */
+/* 2*/	FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+/*       ^X    ^Y    ^Z    ^[    ^\    ^]    ^^    ^_   */
+/* 3*/	FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+/*              !     "     #     $     %     &     '   */
+/* 4*/	FAIL, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
+/*        (     )     *     +     ,     -     .     /   */
+/* 5*/	0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, FAIL, FAIL,
+/*        0     1     2     3     4     5     6     7   */
+/* 6*/	0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, FAIL,
+/*        8     9     :     ;     <     =     >     ?   */
+/* 7*/	0x14, 0x15, DONE, FAIL, FAIL, FAIL, FAIL, FAIL,
+/*        @     A     B     C     D     E     F     G   */
+/* 8*/	0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D,
+/*        H     I     J     K     L     M     N     O   */
+/* 9*/	0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, FAIL,
+/*        P     Q     R     S     T     U     V     W   */
+/*10*/	0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, FAIL,
+/*        X     Y     Z     [     \     ]     ^     _   */
+/*11*/	0x2C, 0x2D, 0x2E, 0x2F, FAIL, FAIL, FAIL, FAIL,
+/*        `     a     b     c     d     e     f     g   */
+/*12*/	0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, FAIL,
+/*        h     i     j     k     l     m     n     o   */
+/*13*/	0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, FAIL, FAIL,
+/*        p     q     r     s     t     u     v     w   */
+/*14*/	0x3D, 0x3E, 0x3F, FAIL, FAIL, FAIL, FAIL, FAIL,
+/*        x     y     z     {     |     }     ~    ^?   */
+/*15*/	FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+/*16*/	FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+	FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+	FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+	FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+	FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+	FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+	FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+	FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+	FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+	FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+	FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+	FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+	FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+	FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+	FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+	FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+};
+
+static unsigned char table_b2a_hqx[] =
+"!\"#$%&'()*+,-012345689 at ABCDEFGHIJKLMNPQRSTUVXYZ[`abcdefhijklmpqr";
+
+static char table_a2b_base64[] = {
+	-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
+	-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
+	-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63,
+	52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1, 0,-1,-1, /* Note PAD->0 */
+	-1, 0, 1, 2,  3, 4, 5, 6,  7, 8, 9,10, 11,12,13,14,
+	15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1,
+	-1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
+	41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1
+};
+
+#define BASE64_PAD '='
+
+/* Max binary chunk size; limited only by available memory */
+#define BASE64_MAXBIN (INT_MAX/2 - sizeof(PyStringObject) - 3)
+
+static unsigned char table_b2a_base64[] =
+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+
+
+static unsigned short crctab_hqx[256] = {
+	0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
+	0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
+	0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
+	0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
+	0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
+	0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
+	0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
+	0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
+	0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
+	0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
+	0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
+	0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
+	0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
+	0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
+	0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
+	0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
+	0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
+	0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
+	0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
+	0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
+	0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
+	0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
+	0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
+	0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
+	0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
+	0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
+	0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
+	0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
+	0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
+	0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
+	0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
+	0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0,
+};
+
+PyDoc_STRVAR(doc_a2b_uu, "(ascii) -> bin. Decode a line of uuencoded data");
+
+static PyObject *
+binascii_a2b_uu(PyObject *self, PyObject *args)
+{
+	unsigned char *ascii_data, *bin_data;
+	int leftbits = 0;
+	unsigned char this_ch;
+	unsigned int leftchar = 0;
+	PyObject *rv;
+	Py_ssize_t ascii_len, bin_len;
+
+	if ( !PyArg_ParseTuple(args, "t#:a2b_uu", &ascii_data, &ascii_len) )
+		return NULL;
+
+	/* First byte: binary data length (in bytes) */
+	bin_len = (*ascii_data++ - ' ') & 077;
+	ascii_len--;
+
+	/* Allocate the buffer */
+	if ( (rv=PyString_FromStringAndSize(NULL, bin_len)) == NULL )
+		return NULL;
+	bin_data = (unsigned char *)PyString_AsString(rv);
+
+	for( ; bin_len > 0 ; ascii_len--, ascii_data++ ) {
+		/* XXX is it really best to add NULs if there's no more data */
+		this_ch = (ascii_len > 0) ? *ascii_data : 0;
+		if ( this_ch == '\n' || this_ch == '\r' || ascii_len <= 0) {
+			/*
+			** Whitespace. Assume some spaces got eaten at
+			** end-of-line. (We check this later)
+			*/
+			this_ch = 0;
+	        } else {
+			/* Check the character for legality
+			** The 64 in stead of the expected 63 is because
+			** there are a few uuencodes out there that use
+			** '`' as zero instead of space.
+			*/
+			if ( this_ch < ' ' || this_ch > (' ' + 64)) {
+				PyErr_SetString(Error, "Illegal char");
+				Py_DECREF(rv);
+				return NULL;
+			}
+			this_ch = (this_ch - ' ') & 077;
+		}
+		/*
+		** Shift it in on the low end, and see if there's
+		** a byte ready for output.
+		*/
+		leftchar = (leftchar << 6) | (this_ch);
+		leftbits += 6;
+		if ( leftbits >= 8 ) {
+			leftbits -= 8;
+			*bin_data++ = (leftchar >> leftbits) & 0xff;
+			leftchar &= ((1 << leftbits) - 1);
+			bin_len--;
+		}
+	}
+	/*
+	** Finally, check that if there's anything left on the line
+	** that it's whitespace only.
+	*/
+	while( ascii_len-- > 0 ) {
+		this_ch = *ascii_data++;
+		/* Extra '`' may be written as padding in some cases */
+		if ( this_ch != ' ' && this_ch != ' '+64 &&
+		     this_ch != '\n' && this_ch != '\r' ) {
+			PyErr_SetString(Error, "Trailing garbage");
+			Py_DECREF(rv);
+			return NULL;
+		}
+	}
+	return rv;
+}
+
+PyDoc_STRVAR(doc_b2a_uu, "(bin) -> ascii. Uuencode line of data");
+
+static PyObject *
+binascii_b2a_uu(PyObject *self, PyObject *args)
+{
+	unsigned char *ascii_data, *bin_data;
+	int leftbits = 0;
+	unsigned char this_ch;
+	unsigned int leftchar = 0;
+	PyObject *rv;
+	Py_ssize_t bin_len;
+
+	if ( !PyArg_ParseTuple(args, "s#:b2a_uu", &bin_data, &bin_len) )
+		return NULL;
+	if ( bin_len > 45 ) {
+		/* The 45 is a limit that appears in all uuencode's */
+		PyErr_SetString(Error, "At most 45 bytes at once");
+		return NULL;
+	}
+
+	/* We're lazy and allocate to much (fixed up later) */
+	if ( (rv=PyString_FromStringAndSize(NULL, bin_len*2+2)) == NULL )
+		return NULL;
+	ascii_data = (unsigned char *)PyString_AsString(rv);
+
+	/* Store the length */
+	*ascii_data++ = ' ' + (bin_len & 077);
+
+	for( ; bin_len > 0 || leftbits != 0 ; bin_len--, bin_data++ ) {
+		/* Shift the data (or padding) into our buffer */
+		if ( bin_len > 0 )	/* Data */
+			leftchar = (leftchar << 8) | *bin_data;
+		else			/* Padding */
+			leftchar <<= 8;
+		leftbits += 8;
+
+		/* See if there are 6-bit groups ready */
+		while ( leftbits >= 6 ) {
+			this_ch = (leftchar >> (leftbits-6)) & 0x3f;
+			leftbits -= 6;
+			*ascii_data++ = this_ch + ' ';
+		}
+	}
+	*ascii_data++ = '\n';	/* Append a courtesy newline */
+
+	_PyString_Resize(&rv, (ascii_data -
+			       (unsigned char *)PyString_AsString(rv)));
+	return rv;
+}
+
+
+static int
+binascii_find_valid(unsigned char *s, Py_ssize_t slen, int num)
+{
+	/* Finds & returns the (num+1)th
+	** valid character for base64, or -1 if none.
+	*/
+
+	int ret = -1;
+	unsigned char c, b64val;
+
+	while ((slen > 0) && (ret == -1)) {
+		c = *s;
+		b64val = table_a2b_base64[c & 0x7f];
+		if ( ((c <= 0x7f) && (b64val != (unsigned char)-1)) ) {
+			if (num == 0)
+				ret = *s;
+			num--;
+		}
+
+		s++;
+		slen--;
+	}
+	return ret;
+}
+
+PyDoc_STRVAR(doc_a2b_base64, "(ascii) -> bin. Decode a line of base64 data");
+
+static PyObject *
+binascii_a2b_base64(PyObject *self, PyObject *args)
+{
+	unsigned char *ascii_data, *bin_data;
+	int leftbits = 0;
+	unsigned char this_ch;
+	unsigned int leftchar = 0;
+	PyObject *rv;
+	Py_ssize_t ascii_len, bin_len;
+	int quad_pos = 0;
+
+	if ( !PyArg_ParseTuple(args, "t#:a2b_base64", &ascii_data, &ascii_len) )
+		return NULL;
+
+	bin_len = ((ascii_len+3)/4)*3; /* Upper bound, corrected later */
+
+	/* Allocate the buffer */
+	if ( (rv=PyString_FromStringAndSize(NULL, bin_len)) == NULL )
+		return NULL;
+	bin_data = (unsigned char *)PyString_AsString(rv);
+	bin_len = 0;
+
+	for( ; ascii_len > 0; ascii_len--, ascii_data++) {
+		this_ch = *ascii_data;
+
+		if (this_ch > 0x7f ||
+		    this_ch == '\r' || this_ch == '\n' || this_ch == ' ')
+			continue;
+
+		/* Check for pad sequences and ignore
+		** the invalid ones.
+		*/
+		if (this_ch == BASE64_PAD) {
+			if ( (quad_pos < 2) ||
+			     ((quad_pos == 2) &&
+			      (binascii_find_valid(ascii_data, ascii_len, 1)
+			       != BASE64_PAD)) )
+			{
+				continue;
+			}
+			else {
+				/* A pad sequence means no more input.
+				** We've already interpreted the data
+				** from the quad at this point.
+				*/
+				leftbits = 0;
+				break;
+			}
+		}
+
+		this_ch = table_a2b_base64[*ascii_data];
+		if ( this_ch == (unsigned char) -1 )
+			continue;
+
+		/*
+		** Shift it in on the low end, and see if there's
+		** a byte ready for output.
+		*/
+		quad_pos = (quad_pos + 1) & 0x03;
+		leftchar = (leftchar << 6) | (this_ch);
+		leftbits += 6;
+
+		if ( leftbits >= 8 ) {
+			leftbits -= 8;
+			*bin_data++ = (leftchar >> leftbits) & 0xff;
+			bin_len++;
+			leftchar &= ((1 << leftbits) - 1);
+		}
+ 	}
+
+	if (leftbits != 0) {
+		PyErr_SetString(Error, "Incorrect padding");
+		Py_DECREF(rv);
+		return NULL;
+	}
+
+	/* And set string size correctly. If the result string is empty
+	** (because the input was all invalid) return the shared empty
+	** string instead; _PyString_Resize() won't do this for us.
+	*/
+	if (bin_len > 0)
+		_PyString_Resize(&rv, bin_len);
+	else {
+		Py_DECREF(rv);
+		rv = PyString_FromString("");
+	}
+	return rv;
+}
+
+PyDoc_STRVAR(doc_b2a_base64, "(bin) -> ascii. Base64-code line of data");
+
+static PyObject *
+binascii_b2a_base64(PyObject *self, PyObject *args)
+{
+	unsigned char *ascii_data, *bin_data;
+	int leftbits = 0;
+	unsigned char this_ch;
+	unsigned int leftchar = 0;
+	PyObject *rv;
+	Py_ssize_t bin_len;
+
+	if ( !PyArg_ParseTuple(args, "s#:b2a_base64", &bin_data, &bin_len) )
+		return NULL;
+	if ( bin_len > BASE64_MAXBIN ) {
+		PyErr_SetString(Error, "Too much data for base64 line");
+		return NULL;
+	}
+
+	/* We're lazy and allocate too much (fixed up later).
+	   "+3" leaves room for up to two pad characters and a trailing
+	   newline.  Note that 'b' gets encoded as 'Yg==\n' (1 in, 5 out). */
+	if ( (rv=PyString_FromStringAndSize(NULL, bin_len*2 + 3)) == NULL )
+		return NULL;
+	ascii_data = (unsigned char *)PyString_AsString(rv);
+
+	for( ; bin_len > 0 ; bin_len--, bin_data++ ) {
+		/* Shift the data into our buffer */
+		leftchar = (leftchar << 8) | *bin_data;
+		leftbits += 8;
+
+		/* See if there are 6-bit groups ready */
+		while ( leftbits >= 6 ) {
+			this_ch = (leftchar >> (leftbits-6)) & 0x3f;
+			leftbits -= 6;
+			*ascii_data++ = table_b2a_base64[this_ch];
+		}
+	}
+	if ( leftbits == 2 ) {
+		*ascii_data++ = table_b2a_base64[(leftchar&3) << 4];
+		*ascii_data++ = BASE64_PAD;
+		*ascii_data++ = BASE64_PAD;
+	} else if ( leftbits == 4 ) {
+		*ascii_data++ = table_b2a_base64[(leftchar&0xf) << 2];
+		*ascii_data++ = BASE64_PAD;
+	}
+	*ascii_data++ = '\n';	/* Append a courtesy newline */
+
+	_PyString_Resize(&rv, (ascii_data -
+			       (unsigned char *)PyString_AsString(rv)));
+	return rv;
+}
+
+PyDoc_STRVAR(doc_a2b_hqx, "ascii -> bin, done. Decode .hqx coding");
+
+static PyObject *
+binascii_a2b_hqx(PyObject *self, PyObject *args)
+{
+	unsigned char *ascii_data, *bin_data;
+	int leftbits = 0;
+	unsigned char this_ch;
+	unsigned int leftchar = 0;
+	PyObject *rv;
+	Py_ssize_t len;
+	int done = 0;
+
+	if ( !PyArg_ParseTuple(args, "t#:a2b_hqx", &ascii_data, &len) )
+		return NULL;
+
+	/* Allocate a string that is too big (fixed later) 
+	   Add two to the initial length to prevent interning which
+	   would preclude subsequent resizing.  */
+	if ( (rv=PyString_FromStringAndSize(NULL, len+2)) == NULL )
+		return NULL;
+	bin_data = (unsigned char *)PyString_AsString(rv);
+
+	for( ; len > 0 ; len--, ascii_data++ ) {
+		/* Get the byte and look it up */
+		this_ch = table_a2b_hqx[*ascii_data];
+		if ( this_ch == SKIP )
+			continue;
+		if ( this_ch == FAIL ) {
+			PyErr_SetString(Error, "Illegal char");
+			Py_DECREF(rv);
+			return NULL;
+		}
+		if ( this_ch == DONE ) {
+			/* The terminating colon */
+			done = 1;
+			break;
+		}
+
+		/* Shift it into the buffer and see if any bytes are ready */
+		leftchar = (leftchar << 6) | (this_ch);
+		leftbits += 6;
+		if ( leftbits >= 8 ) {
+			leftbits -= 8;
+			*bin_data++ = (leftchar >> leftbits) & 0xff;
+			leftchar &= ((1 << leftbits) - 1);
+		}
+	}
+
+	if ( leftbits && !done ) {
+		PyErr_SetString(Incomplete,
+				"String has incomplete number of bytes");
+		Py_DECREF(rv);
+		return NULL;
+	}
+	_PyString_Resize(
+		&rv, (bin_data - (unsigned char *)PyString_AsString(rv)));
+	if (rv) {
+		PyObject *rrv = Py_BuildValue("Oi", rv, done);
+		Py_DECREF(rv);
+		return rrv;
+	}
+
+	return NULL;
+}
+
+PyDoc_STRVAR(doc_rlecode_hqx, "Binhex RLE-code binary data");
+
+static PyObject *
+binascii_rlecode_hqx(PyObject *self, PyObject *args)
+{
+	unsigned char *in_data, *out_data;
+	PyObject *rv;
+	unsigned char ch;
+	Py_ssize_t in, inend, len;
+
+	if ( !PyArg_ParseTuple(args, "s#:rlecode_hqx", &in_data, &len) )
+		return NULL;
+
+	/* Worst case: output is twice as big as input (fixed later) */
+	if ( (rv=PyString_FromStringAndSize(NULL, len*2+2)) == NULL )
+		return NULL;
+	out_data = (unsigned char *)PyString_AsString(rv);
+
+	for( in=0; in<len; in++) {
+		ch = in_data[in];
+		if ( ch == RUNCHAR ) {
+			/* RUNCHAR. Escape it. */
+			*out_data++ = RUNCHAR;
+			*out_data++ = 0;
+		} else {
+			/* Check how many following are the same */
+			for(inend=in+1;
+			    inend<len && in_data[inend] == ch &&
+				    inend < in+255;
+			    inend++) ;
+			if ( inend - in > 3 ) {
+				/* More than 3 in a row. Output RLE. */
+				*out_data++ = ch;
+				*out_data++ = RUNCHAR;
+				*out_data++ = inend-in;
+				in = inend-1;
+			} else {
+				/* Less than 3. Output the byte itself */
+				*out_data++ = ch;
+			}
+		}
+	}
+	_PyString_Resize(&rv, (out_data -
+			       (unsigned char *)PyString_AsString(rv)));
+	return rv;
+}
+
+PyDoc_STRVAR(doc_b2a_hqx, "Encode .hqx data");
+
+static PyObject *
+binascii_b2a_hqx(PyObject *self, PyObject *args)
+{
+	unsigned char *ascii_data, *bin_data;
+	int leftbits = 0;
+	unsigned char this_ch;
+	unsigned int leftchar = 0;
+	PyObject *rv;
+	Py_ssize_t len;
+
+	if ( !PyArg_ParseTuple(args, "s#:b2a_hqx", &bin_data, &len) )
+		return NULL;
+
+	/* Allocate a buffer that is at least large enough */
+	if ( (rv=PyString_FromStringAndSize(NULL, len*2+2)) == NULL )
+		return NULL;
+	ascii_data = (unsigned char *)PyString_AsString(rv);
+
+	for( ; len > 0 ; len--, bin_data++ ) {
+		/* Shift into our buffer, and output any 6bits ready */
+		leftchar = (leftchar << 8) | *bin_data;
+		leftbits += 8;
+		while ( leftbits >= 6 ) {
+			this_ch = (leftchar >> (leftbits-6)) & 0x3f;
+			leftbits -= 6;
+			*ascii_data++ = table_b2a_hqx[this_ch];
+		}
+	}
+	/* Output a possible runt byte */
+	if ( leftbits ) {
+		leftchar <<= (6-leftbits);
+		*ascii_data++ = table_b2a_hqx[leftchar & 0x3f];
+	}
+	_PyString_Resize(&rv, (ascii_data -
+			       (unsigned char *)PyString_AsString(rv)));
+	return rv;
+}
+
+PyDoc_STRVAR(doc_rledecode_hqx, "Decode hexbin RLE-coded string");
+
+static PyObject *
+binascii_rledecode_hqx(PyObject *self, PyObject *args)
+{
+	unsigned char *in_data, *out_data;
+	unsigned char in_byte, in_repeat;
+	PyObject *rv;
+	Py_ssize_t in_len, out_len, out_len_left;
+
+	if ( !PyArg_ParseTuple(args, "s#:rledecode_hqx", &in_data, &in_len) )
+		return NULL;
+
+	/* Empty string is a special case */
+	if ( in_len == 0 )
+		return PyString_FromString("");
+
+	/* Allocate a buffer of reasonable size. Resized when needed */
+	out_len = in_len*2;
+	if ( (rv=PyString_FromStringAndSize(NULL, out_len)) == NULL )
+		return NULL;
+	out_len_left = out_len;
+	out_data = (unsigned char *)PyString_AsString(rv);
+
+	/*
+	** We need two macros here to get/put bytes and handle
+	** end-of-buffer for input and output strings.
+	*/
+#define INBYTE(b) \
+	do { \
+	         if ( --in_len < 0 ) { \
+			   PyErr_SetString(Incomplete, ""); \
+			   Py_DECREF(rv); \
+			   return NULL; \
+		 } \
+		 b = *in_data++; \
+	} while(0)
+
+#define OUTBYTE(b) \
+	do { \
+		 if ( --out_len_left < 0 ) { \
+			  _PyString_Resize(&rv, 2*out_len); \
+			  if ( rv == NULL ) return NULL; \
+			  out_data = (unsigned char *)PyString_AsString(rv) \
+								 + out_len; \
+			  out_len_left = out_len-1; \
+			  out_len = out_len * 2; \
+		 } \
+		 *out_data++ = b; \
+	} while(0)
+
+		/*
+		** Handle first byte separately (since we have to get angry
+		** in case of an orphaned RLE code).
+		*/
+		INBYTE(in_byte);
+
+	if (in_byte == RUNCHAR) {
+		INBYTE(in_repeat);
+		if (in_repeat != 0) {
+			/* Note Error, not Incomplete (which is at the end
+			** of the string only). This is a programmer error.
+			*/
+			PyErr_SetString(Error, "Orphaned RLE code at start");
+			Py_DECREF(rv);
+			return NULL;
+		}
+		OUTBYTE(RUNCHAR);
+	} else {
+		OUTBYTE(in_byte);
+	}
+
+	while( in_len > 0 ) {
+		INBYTE(in_byte);
+
+		if (in_byte == RUNCHAR) {
+			INBYTE(in_repeat);
+			if ( in_repeat == 0 ) {
+				/* Just an escaped RUNCHAR value */
+				OUTBYTE(RUNCHAR);
+			} else {
+				/* Pick up value and output a sequence of it */
+				in_byte = out_data[-1];
+				while ( --in_repeat > 0 )
+					OUTBYTE(in_byte);
+			}
+		} else {
+			/* Normal byte */
+			OUTBYTE(in_byte);
+		}
+	}
+	_PyString_Resize(&rv, (out_data -
+			       (unsigned char *)PyString_AsString(rv)));
+	return rv;
+}
+
+PyDoc_STRVAR(doc_crc_hqx,
+"(data, oldcrc) -> newcrc. Compute hqx CRC incrementally");
+
+static PyObject *
+binascii_crc_hqx(PyObject *self, PyObject *args)
+{
+	unsigned char *bin_data;
+	unsigned int crc;
+	Py_ssize_t len;
+
+	if ( !PyArg_ParseTuple(args, "s#i:crc_hqx", &bin_data, &len, &crc) )
+		return NULL;
+
+	while(len--) {
+		crc=((crc<<8)&0xff00)^crctab_hqx[((crc>>8)&0xff)^*bin_data++];
+	}
+
+	return Py_BuildValue("i", crc);
+}
+
+PyDoc_STRVAR(doc_crc32,
+"(data, oldcrc = 0) -> newcrc. Compute CRC-32 incrementally");
+
+/*  Crc - 32 BIT ANSI X3.66 CRC checksum files
+    Also known as: ISO 3307
+**********************************************************************|
+*                                                                    *|
+* Demonstration program to compute the 32-bit CRC used as the frame  *|
+* check sequence in ADCCP (ANSI X3.66, also known as FIPS PUB 71     *|
+* and FED-STD-1003, the U.S. versions of CCITT's X.25 link-level     *|
+* protocol).  The 32-bit FCS was added via the Federal Register,     *|
+* 1 June 1982, p.23798.  I presume but don't know for certain that   *|
+* this polynomial is or will be included in CCITT V.41, which        *|
+* defines the 16-bit CRC (often called CRC-CCITT) polynomial.  FIPS  *|
+* PUB 78 says that the 32-bit FCS reduces otherwise undetected       *|
+* errors by a factor of 10^-5 over 16-bit FCS.                       *|
+*                                                                    *|
+**********************************************************************|
+
+ Copyright (C) 1986 Gary S. Brown.  You may use this program, or
+ code or tables extracted from it, as desired without restriction.
+
+ First, the polynomial itself and its table of feedback terms.  The
+ polynomial is
+ X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0
+ Note that we take it "backwards" and put the highest-order term in
+ the lowest-order bit.  The X^32 term is "implied"; the LSB is the
+ X^31 term, etc.  The X^0 term (usually shown as "+1") results in
+ the MSB being 1.
+
+ Note that the usual hardware shift register implementation, which
+ is what we're using (we're merely optimizing it by doing eight-bit
+ chunks at a time) shifts bits into the lowest-order term.  In our
+ implementation, that means shifting towards the right.  Why do we
+ do it this way?  Because the calculated CRC must be transmitted in
+ order from highest-order term to lowest-order term.  UARTs transmit
+ characters in order from LSB to MSB.  By storing the CRC this way,
+ we hand it to the UART in the order low-byte to high-byte; the UART
+ sends each low-bit to hight-bit; and the result is transmission bit
+ by bit from highest- to lowest-order term without requiring any bit
+ shuffling on our part.  Reception works similarly.
+
+ The feedback terms table consists of 256, 32-bit entries.  Notes:
+
+  1. The table can be generated at runtime if desired; code to do so
+     is shown later.  It might not be obvious, but the feedback
+     terms simply represent the results of eight shift/xor opera-
+     tions for all combinations of data and CRC register values.
+
+  2. The CRC accumulation logic is the same for all CRC polynomials,
+     be they sixteen or thirty-two bits wide.  You simply choose the
+     appropriate table.  Alternatively, because the table can be
+     generated at runtime, you can start by generating the table for
+     the polynomial in question and use exactly the same "updcrc",
+     if your application needn't simultaneously handle two CRC
+     polynomials.  (Note, however, that XMODEM is strange.)
+
+  3. For 16-bit CRCs, the table entries need be only 16 bits wide;
+     of course, 32-bit entries work OK if the high 16 bits are zero.
+
+  4. The values must be right-shifted by eight bits by the "updcrc"
+     logic; the shift must be unsigned (bring in zeroes).  On some
+     hardware you could probably optimize the shift in assembler by
+     using byte-swap instructions.
+********************************************************************/
+
+static unsigned long crc_32_tab[256] = {
+0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
+0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,
+0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,
+0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,
+0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,
+0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,
+0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,
+0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,
+0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,
+0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,
+0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,
+0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,
+0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,
+0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,
+0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,
+0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,
+0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,
+0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,
+0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,
+0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,
+0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,
+0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,
+0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,
+0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,
+0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,
+0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,
+0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,
+0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,
+0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,
+0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,
+0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,
+0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,
+0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,
+0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,
+0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,
+0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,
+0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,
+0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,
+0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,
+0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,
+0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,
+0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,
+0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,
+0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,
+0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,
+0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,
+0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,
+0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,
+0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,
+0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,
+0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
+0x2d02ef8dUL
+};
+
+static PyObject *
+binascii_crc32(PyObject *self, PyObject *args)
+{ /* By Jim Ahlstrom; All rights transferred to CNRI */
+	unsigned char *bin_data;
+	unsigned long crc = 0UL;	/* initial value of CRC */
+	Py_ssize_t len;
+	long result;
+
+	if ( !PyArg_ParseTuple(args, "s#|l:crc32", &bin_data, &len, &crc) )
+		return NULL;
+
+	crc = ~ crc;
+#if SIZEOF_LONG > 4
+	/* only want the trailing 32 bits */
+	crc &= 0xFFFFFFFFUL;
+#endif
+	while (len--)
+		crc = crc_32_tab[(crc ^ *bin_data++) & 0xffUL] ^ (crc >> 8);
+		/* Note:  (crc >> 8) MUST zero fill on left */
+
+	result = (long)(crc ^ 0xFFFFFFFFUL);
+#if SIZEOF_LONG > 4
+	/* Extend the sign bit.  This is one way to ensure the result is the
+	 * same across platforms.  The other way would be to return an
+	 * unbounded unsigned long, but the evidence suggests that lots of
+	 * code outside this treats the result as if it were a signed 4-byte
+	 * integer.
+	 */
+	result |= -(result & (1L << 31));
+#endif
+	return PyInt_FromLong(result);
+}
+
+
+static PyObject *
+binascii_hexlify(PyObject *self, PyObject *args)
+{
+	char* argbuf;
+	Py_ssize_t arglen;
+	PyObject *retval;
+	char* retbuf;
+	Py_ssize_t i, j;
+
+	if (!PyArg_ParseTuple(args, "s#:b2a_hex", &argbuf, &arglen))
+		return NULL;
+
+	retval = PyString_FromStringAndSize(NULL, arglen*2);
+	if (!retval)
+		return NULL;
+	retbuf = PyString_AsString(retval);
+	if (!retbuf)
+		goto finally;
+
+	/* make hex version of string, taken from shamodule.c */
+	for (i=j=0; i < arglen; i++) {
+		char c;
+		c = (argbuf[i] >> 4) & 0xf;
+		c = (c>9) ? c+'a'-10 : c + '0';
+		retbuf[j++] = c;
+		c = argbuf[i] & 0xf;
+		c = (c>9) ? c+'a'-10 : c + '0';
+		retbuf[j++] = c;
+	}
+	return retval;
+
+  finally:
+	Py_DECREF(retval);
+	return NULL;
+}
+
+PyDoc_STRVAR(doc_hexlify,
+"b2a_hex(data) -> s; Hexadecimal representation of binary data.\n\
+\n\
+This function is also available as \"hexlify()\".");
+
+
+static int
+to_int(int c)
+{
+	if (isdigit(c))
+		return c - '0';
+	else {
+		if (isupper(c))
+			c = tolower(c);
+		if (c >= 'a' && c <= 'f')
+			return c - 'a' + 10;
+	}
+	return -1;
+}
+
+
+static PyObject *
+binascii_unhexlify(PyObject *self, PyObject *args)
+{
+	char* argbuf;
+	Py_ssize_t arglen;
+	PyObject *retval;
+	char* retbuf;
+	Py_ssize_t i, j;
+
+	if (!PyArg_ParseTuple(args, "s#:a2b_hex", &argbuf, &arglen))
+		return NULL;
+
+	/* XXX What should we do about strings with an odd length?  Should
+	 * we add an implicit leading zero, or a trailing zero?  For now,
+	 * raise an exception.
+	 */
+	if (arglen % 2) {
+		PyErr_SetString(PyExc_TypeError, "Odd-length string");
+		return NULL;
+	}
+
+	retval = PyString_FromStringAndSize(NULL, (arglen/2));
+	if (!retval)
+		return NULL;
+	retbuf = PyString_AsString(retval);
+	if (!retbuf)
+		goto finally;
+
+	for (i=j=0; i < arglen; i += 2) {
+		int top = to_int(Py_CHARMASK(argbuf[i]));
+		int bot = to_int(Py_CHARMASK(argbuf[i+1]));
+		if (top == -1 || bot == -1) {
+			PyErr_SetString(PyExc_TypeError,
+					"Non-hexadecimal digit found");
+			goto finally;
+		}
+		retbuf[j++] = (top << 4) + bot;
+	}
+	return retval;
+
+  finally:
+	Py_DECREF(retval);
+	return NULL;
+}
+
+PyDoc_STRVAR(doc_unhexlify,
+"a2b_hex(hexstr) -> s; Binary data of hexadecimal representation.\n\
+\n\
+hexstr must contain an even number of hex digits (upper or lower case).\n\
+This function is also available as \"unhexlify()\"");
+
+static int table_hex[128] = {
+  -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
+  -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
+  -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
+   0, 1, 2, 3,  4, 5, 6, 7,  8, 9,-1,-1, -1,-1,-1,-1,
+  -1,10,11,12, 13,14,15,-1, -1,-1,-1,-1, -1,-1,-1,-1,
+  -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
+  -1,10,11,12, 13,14,15,-1, -1,-1,-1,-1, -1,-1,-1,-1,
+  -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1
+};
+
+#define hexval(c) table_hex[(unsigned int)(c)]
+
+#define MAXLINESIZE 76
+
+PyDoc_STRVAR(doc_a2b_qp, "Decode a string of qp-encoded data");
+
+static PyObject*
+binascii_a2b_qp(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+	Py_ssize_t in, out;
+	char ch;
+	unsigned char *data, *odata;
+	Py_ssize_t datalen = 0;
+	PyObject *rv;
+	static char *kwlist[] = {"data", "header", NULL};
+	int header = 0;
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#|i", kwlist, &data,
+	      &datalen, &header))
+		return NULL;
+
+	/* We allocate the output same size as input, this is overkill.
+	 * The previous implementation used calloc() so we'll zero out the
+	 * memory here too, since PyMem_Malloc() does not guarantee that.
+	 */
+	odata = (unsigned char *) PyMem_Malloc(datalen);
+	if (odata == NULL) {
+		PyErr_NoMemory();
+		return NULL;
+	}
+	memset(odata, 0, datalen);
+
+	in = out = 0;
+	while (in < datalen) {
+		if (data[in] == '=') {
+			in++;
+			if (in >= datalen) break;
+			/* Soft line breaks */
+			if ((data[in] == '\n') || (data[in] == '\r')) {
+				if (data[in] != '\n') {
+					while (in < datalen && data[in] != '\n') in++;
+				}
+				if (in < datalen) in++;
+			}
+			else if (data[in] == '=') {
+				/* broken case from broken python qp */
+				odata[out++] = '=';
+				in++;
+			}
+			else if (((data[in] >= 'A' && data[in] <= 'F') ||
+			          (data[in] >= 'a' && data[in] <= 'f') ||
+				  (data[in] >= '0' && data[in] <= '9')) &&
+			         ((data[in+1] >= 'A' && data[in+1] <= 'F') ||
+				  (data[in+1] >= 'a' && data[in+1] <= 'f') ||
+				  (data[in+1] >= '0' && data[in+1] <= '9'))) {
+				/* hexval */
+				ch = hexval(data[in]) << 4;
+				in++;
+				ch |= hexval(data[in]);
+				in++;
+				odata[out++] = ch;
+			}
+			else {
+			  odata[out++] = '=';
+			}
+		}
+		else if (header && data[in] == '_') {
+			odata[out++] = ' ';
+			in++;
+		}
+		else {
+			odata[out] = data[in];
+			in++;
+			out++;
+		}
+	}
+	if ((rv = PyString_FromStringAndSize((char *)odata, out)) == NULL) {
+		PyMem_Free(odata);
+		return NULL;
+	}
+	PyMem_Free(odata);
+	return rv;
+}
+
+static int
+to_hex (unsigned char ch, unsigned char *s)
+{
+	unsigned int uvalue = ch;
+
+	s[1] = "0123456789ABCDEF"[uvalue % 16];
+	uvalue = (uvalue / 16);
+	s[0] = "0123456789ABCDEF"[uvalue % 16];
+	return 0;
+}
+
+PyDoc_STRVAR(doc_b2a_qp,
+"b2a_qp(data, quotetabs=0, istext=1, header=0) -> s; \n\
+ Encode a string using quoted-printable encoding. \n\
+\n\
+On encoding, when istext is set, newlines are not encoded, and white \n\
+space at end of lines is.  When istext is not set, \\r and \\n (CR/LF) are \n\
+both encoded.  When quotetabs is set, space and tabs are encoded.");
+
+/* XXX: This is ridiculously complicated to be backward compatible
+ * (mostly) with the quopri module.  It doesn't re-create the quopri
+ * module bug where text ending in CRLF has the CR encoded */
+static PyObject*
+binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs)
+{
+	Py_ssize_t in, out;
+	unsigned char *data, *odata;
+	Py_ssize_t datalen = 0, odatalen = 0;
+	PyObject *rv;
+	unsigned int linelen = 0;
+	static char *kwlist[] = {"data", "quotetabs", "istext",
+                                       "header", NULL};
+	int istext = 1;
+	int quotetabs = 0;
+	int header = 0;
+	unsigned char ch;
+	int crlf = 0;
+	unsigned char *p;
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#|iii", kwlist, &data,
+	      &datalen, &quotetabs, &istext, &header))
+		return NULL;
+
+	/* See if this string is using CRLF line ends */
+	/* XXX: this function has the side effect of converting all of
+	 * the end of lines to be the same depending on this detection
+	 * here */
+	p = (unsigned char *) strchr((char *)data, '\n');
+	if ((p != NULL) && (p > data) && (*(p-1) == '\r'))
+		crlf = 1;
+
+	/* First, scan to see how many characters need to be encoded */
+	in = 0;
+	while (in < datalen) {
+		if ((data[in] > 126) ||
+		    (data[in] == '=') ||
+		    (header && data[in] == '_') ||
+		    ((data[in] == '.') && (linelen == 1)) ||
+		    (!istext && ((data[in] == '\r') || (data[in] == '\n'))) ||
+		    ((data[in] == '\t' || data[in] == ' ') && (in + 1 == datalen)) ||
+		    ((data[in] < 33) &&
+		     (data[in] != '\r') && (data[in] != '\n') &&
+		     (quotetabs && ((data[in] != '\t') || (data[in] != ' ')))))
+		{
+			if ((linelen + 3) >= MAXLINESIZE) {
+				linelen = 0;
+				if (crlf)
+					odatalen += 3;
+				else
+					odatalen += 2;
+			}
+			linelen += 3;
+			odatalen += 3;
+			in++;
+		}
+		else {
+		  	if (istext &&
+			    ((data[in] == '\n') ||
+			     ((in+1 < datalen) && (data[in] == '\r') &&
+			     (data[in+1] == '\n'))))
+			{
+			  	linelen = 0;
+				/* Protect against whitespace on end of line */
+				if (in && ((data[in-1] == ' ') || (data[in-1] == '\t')))
+					odatalen += 2;
+				if (crlf)
+					odatalen += 2;
+				else
+					odatalen += 1;
+				if (data[in] == '\r')
+					in += 2;
+				else
+					in++;
+			}
+			else {
+				if ((in + 1 != datalen) &&
+				    (data[in+1] != '\n') &&
+				    (linelen + 1) >= MAXLINESIZE) {
+					linelen = 0;
+					if (crlf)
+						odatalen += 3;
+					else
+						odatalen += 2;
+				}
+				linelen++;
+				odatalen++;
+				in++;
+			}
+		}
+	}
+
+	/* We allocate the output same size as input, this is overkill.
+	 * The previous implementation used calloc() so we'll zero out the
+	 * memory here too, since PyMem_Malloc() does not guarantee that.
+	 */
+	odata = (unsigned char *) PyMem_Malloc(odatalen);
+	if (odata == NULL) {
+		PyErr_NoMemory();
+		return NULL;
+	}
+	memset(odata, 0, odatalen);
+
+	in = out = linelen = 0;
+	while (in < datalen) {
+		if ((data[in] > 126) ||
+		    (data[in] == '=') ||
+		    (header && data[in] == '_') ||
+		    ((data[in] == '.') && (linelen == 1)) ||
+		    (!istext && ((data[in] == '\r') || (data[in] == '\n'))) ||
+		    ((data[in] == '\t' || data[in] == ' ') && (in + 1 == datalen)) ||
+		    ((data[in] < 33) &&
+		     (data[in] != '\r') && (data[in] != '\n') &&
+		     (quotetabs && ((data[in] != '\t') || (data[in] != ' ')))))
+		{
+			if ((linelen + 3 )>= MAXLINESIZE) {
+				odata[out++] = '=';
+				if (crlf) odata[out++] = '\r';
+				odata[out++] = '\n';
+				linelen = 0;
+			}
+			odata[out++] = '=';
+			to_hex(data[in], &odata[out]);
+			out += 2;
+			in++;
+			linelen += 3;
+		}
+		else {
+		  	if (istext &&
+			    ((data[in] == '\n') ||
+			     ((in+1 < datalen) && (data[in] == '\r') &&
+			     (data[in+1] == '\n'))))
+			{
+			  	linelen = 0;
+				/* Protect against whitespace on end of line */
+				if (out && ((odata[out-1] == ' ') || (odata[out-1] == '\t'))) {
+					ch = odata[out-1];
+					odata[out-1] = '=';
+					to_hex(ch, &odata[out]);
+					out += 2;
+				}
+
+				if (crlf) odata[out++] = '\r';
+				odata[out++] = '\n';
+				if (data[in] == '\r')
+					in += 2;
+				else
+					in++;
+			}
+			else {
+				if ((in + 1 != datalen) &&
+				    (data[in+1] != '\n') &&
+				    (linelen + 1) >= MAXLINESIZE) {
+					odata[out++] = '=';
+					if (crlf) odata[out++] = '\r';
+					odata[out++] = '\n';
+					linelen = 0;
+				}
+				linelen++;
+				if (header && data[in] == ' ') {
+					odata[out++] = '_';
+					in++;
+				}
+				else {
+					odata[out++] = data[in++];
+				}
+			}
+		}
+	}
+	if ((rv = PyString_FromStringAndSize((char *)odata, out)) == NULL) {
+		PyMem_Free(odata);
+		return NULL;
+	}
+	PyMem_Free(odata);
+	return rv;
+}
+
+/* List of functions defined in the module */
+
+static struct PyMethodDef binascii_module_methods[] = {
+	{"a2b_uu",     binascii_a2b_uu,     METH_VARARGS, doc_a2b_uu},
+	{"b2a_uu",     binascii_b2a_uu,     METH_VARARGS, doc_b2a_uu},
+	{"a2b_base64", binascii_a2b_base64, METH_VARARGS, doc_a2b_base64},
+	{"b2a_base64", binascii_b2a_base64, METH_VARARGS, doc_b2a_base64},
+	{"a2b_hqx",    binascii_a2b_hqx,    METH_VARARGS, doc_a2b_hqx},
+	{"b2a_hqx",    binascii_b2a_hqx,    METH_VARARGS, doc_b2a_hqx},
+	{"b2a_hex",    binascii_hexlify,    METH_VARARGS, doc_hexlify},
+	{"a2b_hex",    binascii_unhexlify,  METH_VARARGS, doc_unhexlify},
+	{"hexlify",    binascii_hexlify,    METH_VARARGS, doc_hexlify},
+	{"unhexlify",  binascii_unhexlify,  METH_VARARGS, doc_unhexlify},
+	{"rlecode_hqx",   binascii_rlecode_hqx, METH_VARARGS, doc_rlecode_hqx},
+	{"rledecode_hqx", binascii_rledecode_hqx, METH_VARARGS,
+	 doc_rledecode_hqx},
+	{"crc_hqx",    binascii_crc_hqx,    METH_VARARGS, doc_crc_hqx},
+	{"crc32",      binascii_crc32,      METH_VARARGS, doc_crc32},
+	{"a2b_qp", (PyCFunction)binascii_a2b_qp, METH_VARARGS | METH_KEYWORDS,
+	  doc_a2b_qp},
+	{"b2a_qp", (PyCFunction)binascii_b2a_qp, METH_VARARGS | METH_KEYWORDS,
+          doc_b2a_qp},
+	{NULL, NULL}			     /* sentinel */
+};
+
+
+/* Initialization function for the module (*must* be called initbinascii) */
+PyDoc_STRVAR(doc_binascii, "Conversion between binary data and ASCII");
+
+PyMODINIT_FUNC
+initbinascii(void)
+{
+	PyObject *m, *d, *x;
+
+	/* Create the module and add the functions */
+	m = Py_InitModule("binascii", binascii_module_methods);
+	if (m == NULL)
+		return;
+
+	d = PyModule_GetDict(m);
+	x = PyString_FromString(doc_binascii);
+	PyDict_SetItemString(d, "__doc__", x);
+	Py_XDECREF(x);
+
+	Error = PyErr_NewException("binascii.Error", NULL, NULL);
+	PyDict_SetItemString(d, "Error", Error);
+	Incomplete = PyErr_NewException("binascii.Incomplete", NULL, NULL);
+	PyDict_SetItemString(d, "Incomplete", Incomplete);
+}

Added: vendor/Python/current/Modules/bsddbmodule.c
===================================================================
--- vendor/Python/current/Modules/bsddbmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/bsddbmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,858 @@
+/* Berkeley DB interface.
+   Author: Michael McLay
+   Hacked: Guido van Rossum
+   Btree and Recno additions plus sequence methods: David Ely
+   Hacked by Gustavo Niemeyer <niemeyer at conectiva.com> fixing recno
+   support.
+
+   XXX To do:
+   - provide a way to access the various hash functions
+   - support more open flags
+
+   The windows port of the Berkeley DB code is hard to find on the web:
+   www.nightmare.com/software.html
+*/
+
+#include "Python.h"
+#ifdef WITH_THREAD
+#include "pythread.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#ifdef HAVE_DB_185_H
+#include <db_185.h>
+#else
+#include <db.h>
+#endif
+/* Please don't include internal header files of the Berkeley db package
+   (it messes up the info required in the Setup file) */
+
+typedef struct {
+	PyObject_HEAD
+	DB *di_bsddb;
+	int di_size;	/* -1 means recompute */
+	int di_type;
+#ifdef WITH_THREAD
+	PyThread_type_lock di_lock;
+#endif
+} bsddbobject;
+
+static PyTypeObject Bsddbtype;
+
+#define is_bsddbobject(v) ((v)->ob_type == &Bsddbtype)
+#define check_bsddbobject_open(v, r) if ((v)->di_bsddb == NULL) \
+               { PyErr_SetString(BsddbError, \
+				 "BSDDB object has already been closed"); \
+                 return r; }
+
+static PyObject *BsddbError;
+
+static PyObject *
+newdbhashobject(char *file, int flags, int mode,
+		int bsize, int ffactor, int nelem, int cachesize,
+		int hash, int lorder)
+{
+	bsddbobject *dp;
+	HASHINFO info;
+
+	if ((dp = PyObject_New(bsddbobject, &Bsddbtype)) == NULL)
+		return NULL;
+
+	info.bsize = bsize;
+	info.ffactor = ffactor;
+	info.nelem = nelem;
+	info.cachesize = cachesize;
+	info.hash = NULL; /* XXX should derive from hash argument */
+	info.lorder = lorder;
+
+#ifdef O_BINARY
+	flags |= O_BINARY;
+#endif
+	Py_BEGIN_ALLOW_THREADS
+	dp->di_bsddb = dbopen(file, flags, mode, DB_HASH, &info);
+	Py_END_ALLOW_THREADS
+	if (dp->di_bsddb == NULL) {
+		PyErr_SetFromErrno(BsddbError);
+#ifdef WITH_THREAD
+		dp->di_lock = NULL;
+#endif
+		Py_DECREF(dp);
+		return NULL;
+	}
+
+	dp->di_size = -1;
+	dp->di_type = DB_HASH;
+
+#ifdef WITH_THREAD
+	dp->di_lock = PyThread_allocate_lock();
+	if (dp->di_lock == NULL) {
+		PyErr_SetString(BsddbError, "can't allocate lock");
+		Py_DECREF(dp);
+		return NULL;
+	}
+#endif
+
+	return (PyObject *)dp;
+}
+
+static PyObject *
+newdbbtobject(char *file, int flags, int mode,
+	      int btflags, int cachesize, int maxkeypage,
+	      int minkeypage, int psize, int lorder)
+{
+	bsddbobject *dp;
+	BTREEINFO info;
+
+	if ((dp = PyObject_New(bsddbobject, &Bsddbtype)) == NULL)
+		return NULL;
+
+	info.flags = btflags;
+	info.cachesize = cachesize;
+	info.maxkeypage = maxkeypage;
+	info.minkeypage = minkeypage;
+	info.psize = psize;
+	info.lorder = lorder;
+	info.compare = 0; /* Use default comparison functions, for now..*/
+	info.prefix = 0;
+
+#ifdef O_BINARY
+	flags |= O_BINARY;
+#endif
+	Py_BEGIN_ALLOW_THREADS
+	dp->di_bsddb = dbopen(file, flags, mode, DB_BTREE, &info);
+	Py_END_ALLOW_THREADS
+	if (dp->di_bsddb == NULL) {
+		PyErr_SetFromErrno(BsddbError);
+#ifdef WITH_THREAD
+		dp->di_lock = NULL;
+#endif
+		Py_DECREF(dp);
+		return NULL;
+	}
+
+	dp->di_size = -1;
+	dp->di_type = DB_BTREE;
+
+#ifdef WITH_THREAD
+	dp->di_lock = PyThread_allocate_lock();
+	if (dp->di_lock == NULL) {
+		PyErr_SetString(BsddbError, "can't allocate lock");
+		Py_DECREF(dp);
+		return NULL;
+	}
+#endif
+
+	return (PyObject *)dp;
+}
+
+static PyObject *
+newdbrnobject(char *file, int flags, int mode,
+	      int rnflags, int cachesize, int psize, int lorder,
+	      size_t reclen, u_char bval, char *bfname)
+{
+	bsddbobject *dp;
+	RECNOINFO info;
+	int fd;
+
+	if ((dp = PyObject_New(bsddbobject, &Bsddbtype)) == NULL)
+		return NULL;
+
+	info.flags = rnflags;
+	info.cachesize = cachesize;
+	info.psize = psize;
+	info.lorder = lorder;
+	info.reclen = reclen;
+	info.bval = bval;
+	info.bfname = bfname;
+
+#ifdef O_BINARY
+	flags |= O_BINARY;
+#endif
+	/* This is a hack to avoid a dbopen() bug that happens when
+	 * it fails. */
+	fd = open(file, flags);
+	if (fd == -1) {
+		dp->di_bsddb = NULL;
+	}
+	else {
+		close(fd);
+		Py_BEGIN_ALLOW_THREADS
+		dp->di_bsddb = dbopen(file, flags, mode, DB_RECNO, &info);
+		Py_END_ALLOW_THREADS
+	}
+	if (dp->di_bsddb == NULL) {
+		PyErr_SetFromErrno(BsddbError);
+#ifdef WITH_THREAD
+		dp->di_lock = NULL;
+#endif
+		Py_DECREF(dp);
+		return NULL;
+	}
+
+	dp->di_size = -1;
+	dp->di_type = DB_RECNO;
+
+#ifdef WITH_THREAD
+	dp->di_lock = PyThread_allocate_lock();
+	if (dp->di_lock == NULL) {
+		PyErr_SetString(BsddbError, "can't allocate lock");
+		Py_DECREF(dp);
+		return NULL;
+	}
+#endif
+
+	return (PyObject *)dp;
+}
+
+static void
+bsddb_dealloc(bsddbobject *dp)
+{
+#ifdef WITH_THREAD
+	if (dp->di_lock) {
+		PyThread_acquire_lock(dp->di_lock, 0);
+		PyThread_release_lock(dp->di_lock);
+		PyThread_free_lock(dp->di_lock);
+		dp->di_lock = NULL;
+	}
+#endif
+	if (dp->di_bsddb != NULL) {
+		int status;
+		Py_BEGIN_ALLOW_THREADS
+		status = (dp->di_bsddb->close)(dp->di_bsddb);
+		Py_END_ALLOW_THREADS
+		if (status != 0)
+			fprintf(stderr,
+				"Python bsddb: close errno %d in dealloc\n",
+				errno);
+	}
+	PyObject_Del(dp);
+}
+
+#ifdef WITH_THREAD
+#define BSDDB_BGN_SAVE(_dp) \
+	Py_BEGIN_ALLOW_THREADS PyThread_acquire_lock(_dp->di_lock,1);
+#define BSDDB_END_SAVE(_dp) \
+	PyThread_release_lock(_dp->di_lock); Py_END_ALLOW_THREADS
+#else
+#define BSDDB_BGN_SAVE(_dp) Py_BEGIN_ALLOW_THREADS 
+#define BSDDB_END_SAVE(_dp) Py_END_ALLOW_THREADS
+#endif
+
+static Py_ssize_t
+bsddb_length(bsddbobject *dp)
+{
+	check_bsddbobject_open(dp, -1);
+	if (dp->di_size < 0) {
+		DBT krec, drec;
+		int status;
+		int size = 0;
+		BSDDB_BGN_SAVE(dp)
+		for (status = (dp->di_bsddb->seq)(dp->di_bsddb,
+						  &krec, &drec,R_FIRST);
+		     status == 0;
+		     status = (dp->di_bsddb->seq)(dp->di_bsddb,
+						  &krec, &drec, R_NEXT))
+			size++;
+		BSDDB_END_SAVE(dp)
+		if (status < 0) {
+			PyErr_SetFromErrno(BsddbError);
+			return -1;
+		}
+		dp->di_size = size;
+	}
+	return dp->di_size;
+}
+
+static PyObject *
+bsddb_subscript(bsddbobject *dp, PyObject *key)
+{
+	int status;
+	DBT krec, drec;
+	char *data,buf[4096];
+	int size;
+	PyObject *result;
+	recno_t recno;
+	
+	if (dp->di_type == DB_RECNO) {
+		if (!PyArg_Parse(key, "i", &recno)) {
+			PyErr_SetString(PyExc_TypeError,
+					"key type must be integer");
+			return NULL;
+		}
+		krec.data = &recno;
+		krec.size = sizeof(recno);
+	}
+	else {
+		if (!PyArg_Parse(key, "s#", &data, &size)) {
+			PyErr_SetString(PyExc_TypeError,
+					"key type must be string");
+			return NULL;
+		}
+		krec.data = data;
+		krec.size = size;
+	}
+        check_bsddbobject_open(dp, NULL);
+
+	BSDDB_BGN_SAVE(dp)
+	status = (dp->di_bsddb->get)(dp->di_bsddb, &krec, &drec, 0);
+	if (status == 0) {
+		if (drec.size > sizeof(buf)) data = malloc(drec.size);
+		else data = buf;
+		if (data!=NULL) memcpy(data,drec.data,drec.size);
+	}
+	BSDDB_END_SAVE(dp)
+	if (data==NULL) return PyErr_NoMemory();
+	if (status != 0) {
+		if (status < 0)
+			PyErr_SetFromErrno(BsddbError);
+		else
+			PyErr_SetObject(PyExc_KeyError, key);
+		return NULL;
+	}
+
+	result = PyString_FromStringAndSize(data, (int)drec.size);
+	if (data != buf) free(data);
+	return result;
+}
+
+static int
+bsddb_ass_sub(bsddbobject *dp, PyObject *key, PyObject *value)
+{
+	int status;
+	DBT krec, drec;
+	char *data;
+	int size;
+	recno_t recno;
+
+	if (dp->di_type == DB_RECNO) {
+		if (!PyArg_Parse(key, "i", &recno)) {
+			PyErr_SetString(PyExc_TypeError,
+					"bsddb key type must be integer");
+			return -1;
+		}
+		krec.data = &recno;
+		krec.size = sizeof(recno);
+	}
+	else {
+		if (!PyArg_Parse(key, "s#", &data, &size)) {
+			PyErr_SetString(PyExc_TypeError,
+					"bsddb key type must be string");
+			return -1;
+		}
+		krec.data = data;
+		krec.size = size;
+	}
+	check_bsddbobject_open(dp, -1);
+	dp->di_size = -1;
+	if (value == NULL) {
+		BSDDB_BGN_SAVE(dp)
+		status = (dp->di_bsddb->del)(dp->di_bsddb, &krec, 0);
+		BSDDB_END_SAVE(dp)
+	}
+	else {
+		if (!PyArg_Parse(value, "s#", &data, &size)) {
+			PyErr_SetString(PyExc_TypeError,
+					"bsddb value type must be string");
+			return -1;
+		}
+		drec.data = data;
+		drec.size = size;
+		BSDDB_BGN_SAVE(dp)
+		status = (dp->di_bsddb->put)(dp->di_bsddb, &krec, &drec, 0);
+		BSDDB_END_SAVE(dp)
+	}
+	if (status != 0) {
+		if (status < 0)
+			PyErr_SetFromErrno(BsddbError);
+		else
+			PyErr_SetObject(PyExc_KeyError, key);
+		return -1;
+	}
+	return 0;
+}
+
+static PyMappingMethods bsddb_as_mapping = {
+	(lenfunc)bsddb_length,		/*mp_length*/
+	(binaryfunc)bsddb_subscript,	/*mp_subscript*/
+	(objobjargproc)bsddb_ass_sub,	/*mp_ass_subscript*/
+};
+
+static PyObject *
+bsddb_close(bsddbobject *dp)
+{
+	if (dp->di_bsddb != NULL) {
+		int status;
+		BSDDB_BGN_SAVE(dp)
+		status = (dp->di_bsddb->close)(dp->di_bsddb);
+		BSDDB_END_SAVE(dp)
+		if (status != 0) {
+			dp->di_bsddb = NULL;
+			PyErr_SetFromErrno(BsddbError);
+			return NULL;
+		}
+	}
+	dp->di_bsddb = NULL;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+bsddb_keys(bsddbobject *dp)
+{
+	PyObject *list, *item=NULL;
+	DBT krec, drec;
+	char *data=NULL,buf[4096];
+	int status;
+	int err;
+
+	check_bsddbobject_open(dp, NULL);
+	list = PyList_New(0);
+	if (list == NULL)
+		return NULL;
+	BSDDB_BGN_SAVE(dp)
+	status = (dp->di_bsddb->seq)(dp->di_bsddb, &krec, &drec, R_FIRST);
+	if (status == 0) {
+		if (krec.size > sizeof(buf)) data = malloc(krec.size);
+		else data = buf;
+		if (data != NULL) memcpy(data,krec.data,krec.size);
+	}
+	BSDDB_END_SAVE(dp)
+	if (status == 0 && data==NULL) return PyErr_NoMemory();
+	while (status == 0) {
+		if (dp->di_type == DB_RECNO)
+			item = PyInt_FromLong(*((int*)data));
+		else
+			item = PyString_FromStringAndSize(data,
+							  (int)krec.size);
+		if (data != buf) free(data);
+		if (item == NULL) {
+			Py_DECREF(list);
+			return NULL;
+		}
+		err = PyList_Append(list, item);
+		Py_DECREF(item);
+		if (err != 0) {
+			Py_DECREF(list);
+			return NULL;
+		}
+		BSDDB_BGN_SAVE(dp)
+		status = (dp->di_bsddb->seq)
+			(dp->di_bsddb, &krec, &drec, R_NEXT);
+		if (status == 0) {
+			if (krec.size > sizeof(buf))
+				data = malloc(krec.size);
+			else data = buf;
+			if (data != NULL)
+				memcpy(data,krec.data,krec.size);
+		}
+		BSDDB_END_SAVE(dp)
+		if (data == NULL) return PyErr_NoMemory();
+	}
+	if (status < 0) {
+		PyErr_SetFromErrno(BsddbError);
+		Py_DECREF(list);
+		return NULL;
+	}
+	if (dp->di_size < 0)
+		dp->di_size = PyList_Size(list); /* We just did the work */
+	return list;
+}
+
+static PyObject *
+bsddb_has_key(bsddbobject *dp, PyObject *args)
+{
+	DBT krec, drec;
+	int status;
+	char *data;
+	int size;
+	recno_t recno;
+
+	if (dp->di_type == DB_RECNO) {
+		if (!PyArg_ParseTuple(args, "i;key type must be integer",
+				      &recno)) {
+			return NULL;
+		}
+		krec.data = &recno;
+		krec.size = sizeof(recno);
+	}
+	else {
+		if (!PyArg_ParseTuple(args, "s#;key type must be string",
+				      &data, &size)) {
+			return NULL;
+		}
+		krec.data = data;
+		krec.size = size;
+	}
+	check_bsddbobject_open(dp, NULL);
+
+	BSDDB_BGN_SAVE(dp)
+	status = (dp->di_bsddb->get)(dp->di_bsddb, &krec, &drec, 0);
+	BSDDB_END_SAVE(dp)
+	if (status < 0) {
+		PyErr_SetFromErrno(BsddbError);
+		return NULL;
+	}
+
+	return PyInt_FromLong(status == 0);
+}
+
+static PyObject *
+bsddb_set_location(bsddbobject *dp, PyObject *key)
+{
+	int status;
+	DBT krec, drec;
+	char *data,buf[4096];
+	int size;
+	PyObject *result;
+	recno_t recno;
+
+	if (dp->di_type == DB_RECNO) {
+		if (!PyArg_ParseTuple(key, "i;key type must be integer",
+				      &recno)) {
+			return NULL;
+		}
+		krec.data = &recno;
+		krec.size = sizeof(recno);
+	}
+	else {
+		if (!PyArg_ParseTuple(key, "s#;key type must be string",
+				      &data, &size)) {
+			return NULL;
+		}
+		krec.data = data;
+		krec.size = size;
+	}
+	check_bsddbobject_open(dp, NULL);
+
+	BSDDB_BGN_SAVE(dp)
+	status = (dp->di_bsddb->seq)(dp->di_bsddb, &krec, &drec, R_CURSOR);
+	if (status == 0) {
+		if (drec.size > sizeof(buf)) data = malloc(drec.size);
+		else data = buf;
+		if (data!=NULL) memcpy(data,drec.data,drec.size);
+	}
+	BSDDB_END_SAVE(dp)
+	if (data==NULL) return PyErr_NoMemory();
+	if (status != 0) {
+		if (status < 0)
+			PyErr_SetFromErrno(BsddbError);
+		else
+			PyErr_SetObject(PyExc_KeyError, key);
+		return NULL;
+	}
+
+	if (dp->di_type == DB_RECNO)
+		result = Py_BuildValue("is#", *((int*)krec.data),
+				       data, drec.size);
+	else
+		result = Py_BuildValue("s#s#", krec.data, krec.size,
+				       data, drec.size);
+	if (data != buf) free(data);
+	return result;
+}
+
+static PyObject *
+bsddb_seq(bsddbobject *dp, int sequence_request)
+{
+	int status;
+	DBT krec, drec;
+	char *kdata=NULL,kbuf[4096];
+	char *ddata=NULL,dbuf[4096];
+	PyObject *result;
+
+	check_bsddbobject_open(dp, NULL);
+	krec.data = 0;
+	krec.size = 0;
+
+	BSDDB_BGN_SAVE(dp)
+	status = (dp->di_bsddb->seq)(dp->di_bsddb, &krec,
+				     &drec, sequence_request);
+	if (status == 0) {
+		if (krec.size > sizeof(kbuf)) kdata = malloc(krec.size);
+		else kdata = kbuf;
+		if (kdata != NULL) memcpy(kdata,krec.data,krec.size);
+		if (drec.size > sizeof(dbuf)) ddata = malloc(drec.size);
+		else ddata = dbuf;
+		if (ddata != NULL) memcpy(ddata,drec.data,drec.size);
+	}
+	BSDDB_END_SAVE(dp)
+	if (status == 0) {
+		if ((kdata == NULL) || (ddata == NULL)) 
+			return PyErr_NoMemory();
+	}
+	else { 
+		/* (status != 0) */  
+		if (status < 0)
+			PyErr_SetFromErrno(BsddbError);
+		else
+			PyErr_SetString(PyExc_KeyError, "no key/data pairs");
+		return NULL;
+	}
+
+	if (dp->di_type == DB_RECNO)
+		result = Py_BuildValue("is#", *((int*)kdata),
+				       ddata, drec.size);
+	else
+		result = Py_BuildValue("s#s#", kdata, krec.size,
+				       ddata, drec.size);
+	if (kdata != kbuf) free(kdata);
+	if (ddata != dbuf) free(ddata);
+	return result;
+}
+
+static PyObject *
+bsddb_next(bsddbobject *dp)
+{
+	return bsddb_seq(dp, R_NEXT);
+}
+static PyObject *
+bsddb_previous(bsddbobject *dp)
+{
+	return bsddb_seq(dp, R_PREV);
+}
+static PyObject *
+bsddb_first(bsddbobject *dp)
+{
+	return bsddb_seq(dp, R_FIRST);
+}
+static PyObject *
+bsddb_last(bsddbobject *dp)
+{
+	return bsddb_seq(dp, R_LAST);
+}
+static PyObject *
+bsddb_sync(bsddbobject *dp)
+{
+	int status;
+
+	check_bsddbobject_open(dp, NULL);
+	BSDDB_BGN_SAVE(dp)
+	status = (dp->di_bsddb->sync)(dp->di_bsddb, 0);
+	BSDDB_END_SAVE(dp)
+	if (status != 0) {
+		PyErr_SetFromErrno(BsddbError);
+		return NULL;
+	}
+	return PyInt_FromLong(status = 0);
+}
+static PyMethodDef bsddb_methods[] = {
+	{"close",		(PyCFunction)bsddb_close, METH_NOARGS},
+	{"keys",		(PyCFunction)bsddb_keys, METH_NOARGS},
+	{"has_key",		(PyCFunction)bsddb_has_key, METH_VARARGS},
+	{"set_location",	(PyCFunction)bsddb_set_location, METH_VARARGS},
+	{"next",		(PyCFunction)bsddb_next, METH_NOARGS},
+	{"previous",	(PyCFunction)bsddb_previous, METH_NOARGS},
+	{"first",		(PyCFunction)bsddb_first, METH_NOARGS},
+	{"last",		(PyCFunction)bsddb_last, METH_NOARGS},
+	{"sync",		(PyCFunction)bsddb_sync, METH_NOARGS},
+	{NULL,	       	NULL}		/* sentinel */
+};
+
+static PyObject *
+bsddb_getattr(PyObject *dp, char *name)
+{
+	return Py_FindMethod(bsddb_methods, dp, name);
+}
+
+static PyTypeObject Bsddbtype = {
+	PyObject_HEAD_INIT(NULL)
+	0,
+	"bsddb.bsddb",
+	sizeof(bsddbobject),
+	0,
+	(destructor)bsddb_dealloc, /*tp_dealloc*/
+	0,			/*tp_print*/
+	(getattrfunc)bsddb_getattr, /*tp_getattr*/
+	0,			/*tp_setattr*/
+	0,			/*tp_compare*/
+	0,			/*tp_repr*/
+	0,			/*tp_as_number*/
+	0,			/*tp_as_sequence*/
+	&bsddb_as_mapping,	/*tp_as_mapping*/
+};
+
+static PyObject *
+bsdhashopen(PyObject *self, PyObject *args)
+{
+	char *file;
+	char *flag = NULL;
+	int flags = O_RDONLY;
+	int mode = 0666;
+	int bsize = 0;
+	int ffactor = 0;
+	int nelem = 0;
+	int cachesize = 0;
+	int hash = 0; /* XXX currently ignored */
+	int lorder = 0;
+
+	if (!PyArg_ParseTuple(args, "z|siiiiiii:hashopen",
+			      &file, &flag, &mode,
+			      &bsize, &ffactor, &nelem, &cachesize,
+			      &hash, &lorder))
+		return NULL;
+	if (flag != NULL) {
+		/* XXX need to pass O_EXCL, O_EXLOCK, O_NONBLOCK, O_SHLOCK */
+		if (flag[0] == 'r')
+			flags = O_RDONLY;
+		else if (flag[0] == 'w')
+			flags = O_RDWR;
+		else if (flag[0] == 'c')
+			flags = O_RDWR|O_CREAT;
+		else if (flag[0] == 'n')
+			flags = O_RDWR|O_CREAT|O_TRUNC;
+		else {
+			PyErr_SetString(BsddbError,
+				"Flag should begin with 'r', 'w', 'c' or 'n'");
+			return NULL;
+		}
+		if (flag[1] == 'l') {
+#if defined(O_EXLOCK) && defined(O_SHLOCK)
+			if (flag[0] == 'r')
+				flags |= O_SHLOCK;
+			else
+				flags |= O_EXLOCK;
+#else
+			PyErr_SetString(BsddbError,
+				     "locking not supported on this platform");
+			return NULL;
+#endif
+		}
+	}
+	return newdbhashobject(file, flags, mode,
+			       bsize, ffactor, nelem, cachesize, hash, lorder);
+}
+
+static PyObject *
+bsdbtopen(PyObject *self, PyObject *args)
+{
+	char *file;
+	char *flag = NULL;
+	int flags = O_RDONLY;
+	int mode = 0666;
+	int cachesize = 0;
+	int maxkeypage = 0;
+	int minkeypage = 0;
+	int btflags = 0;
+	unsigned int psize = 0;
+	int lorder = 0;
+
+	if (!PyArg_ParseTuple(args, "z|siiiiiii:btopen",
+			      &file, &flag, &mode,
+			      &btflags, &cachesize, &maxkeypage, &minkeypage,
+			      &psize, &lorder))
+		return NULL;
+	if (flag != NULL) {
+		/* XXX need to pass O_EXCL, O_EXLOCK, O_NONBLOCK, O_SHLOCK */
+		if (flag[0] == 'r')
+			flags = O_RDONLY;
+		else if (flag[0] == 'w')
+			flags = O_RDWR;
+		else if (flag[0] == 'c')
+			flags = O_RDWR|O_CREAT;
+		else if (flag[0] == 'n')
+			flags = O_RDWR|O_CREAT|O_TRUNC;
+		else {
+			PyErr_SetString(BsddbError,
+			       "Flag should begin with 'r', 'w', 'c' or 'n'");
+			return NULL;
+		}
+		if (flag[1] == 'l') {
+#if defined(O_EXLOCK) && defined(O_SHLOCK)
+			if (flag[0] == 'r')
+				flags |= O_SHLOCK;
+			else
+				flags |= O_EXLOCK;
+#else
+			PyErr_SetString(BsddbError,
+				    "locking not supported on this platform");
+			return NULL;
+#endif
+		}
+	}
+	return newdbbtobject(file, flags, mode,
+			     btflags, cachesize, maxkeypage, minkeypage,
+			     psize, lorder);
+}
+
+static PyObject *
+bsdrnopen(PyObject *self, PyObject *args)
+{
+	char *file;
+	char *flag = NULL;
+	int flags = O_RDONLY;
+	int mode = 0666;
+	int cachesize = 0;
+	int rnflags = 0;
+	unsigned int psize = 0;
+	int lorder = 0;
+	size_t reclen = 0;
+	char  *bval = "";
+	char *bfname = NULL;
+
+	if (!PyArg_ParseTuple(args, "z|siiiiiiss:rnopen",
+			      &file, &flag, &mode,
+			      &rnflags, &cachesize, &psize, &lorder,
+			      &reclen, &bval, &bfname))
+		return NULL;
+
+	if (flag != NULL) {
+		/* XXX need to pass O_EXCL, O_EXLOCK, O_NONBLOCK, O_SHLOCK */
+		if (flag[0] == 'r')
+			flags = O_RDONLY;
+		else if (flag[0] == 'w')
+			flags = O_RDWR;
+		else if (flag[0] == 'c')
+			flags = O_RDWR|O_CREAT;
+		else if (flag[0] == 'n')
+			flags = O_RDWR|O_CREAT|O_TRUNC;
+		else {
+			PyErr_SetString(BsddbError,
+			       "Flag should begin with 'r', 'w', 'c' or 'n'");
+			return NULL;
+		}
+		if (flag[1] == 'l') {
+#if defined(O_EXLOCK) && defined(O_SHLOCK)
+			if (flag[0] == 'r')
+				flags |= O_SHLOCK;
+			else
+				flags |= O_EXLOCK;
+#else
+			PyErr_SetString(BsddbError,
+				    "locking not supported on this platform");
+			return NULL;
+#endif
+		}
+		else if (flag[1] != '\0') {
+			PyErr_SetString(BsddbError,
+				       "Flag char 2 should be 'l' or absent");
+			return NULL;
+		}
+	}
+	return newdbrnobject(file, flags, mode, rnflags, cachesize,
+			     psize, lorder, reclen, bval[0], bfname);
+}
+
+static PyMethodDef bsddbmodule_methods[] = {
+	{"hashopen",	(PyCFunction)bsdhashopen, METH_VARARGS},
+	{"btopen",	(PyCFunction)bsdbtopen, METH_VARARGS},
+	{"rnopen",	(PyCFunction)bsdrnopen, METH_VARARGS},
+	/* strictly for use by dbhhash!!! */
+	{"open",	(PyCFunction)bsdhashopen, METH_VARARGS},
+	{0,		0},
+};
+
+PyMODINIT_FUNC
+initbsddb185(void) {
+	PyObject *m, *d;
+
+	Bsddbtype.ob_type = &PyType_Type;
+	m = Py_InitModule("bsddb185", bsddbmodule_methods);
+	if (m == NULL)
+		return;
+	d = PyModule_GetDict(m);
+	BsddbError = PyErr_NewException("bsddb.error", NULL, NULL);
+	if (BsddbError != NULL)
+		PyDict_SetItemString(d, "error", BsddbError);
+}

Added: vendor/Python/current/Modules/bz2module.c
===================================================================
--- vendor/Python/current/Modules/bz2module.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/bz2module.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2230 @@
+/*
+
+python-bz2 - python bz2 library interface
+
+Copyright (c) 2002  Gustavo Niemeyer <niemeyer at conectiva.com>
+Copyright (c) 2002  Python Software Foundation; All Rights Reserved
+
+*/
+
+#include "Python.h"
+#include <stdio.h>
+#include <bzlib.h>
+#include "structmember.h"
+
+#ifdef WITH_THREAD
+#include "pythread.h"
+#endif
+
+static char __author__[] =
+"The bz2 python module was written by:\n\
+\n\
+    Gustavo Niemeyer <niemeyer at conectiva.com>\n\
+";
+
+/* Our very own off_t-like type, 64-bit if possible */
+/* copied from Objects/fileobject.c */
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+typedef off_t Py_off_t;
+#elif SIZEOF_OFF_T >= 8
+typedef off_t Py_off_t;
+#elif SIZEOF_FPOS_T >= 8
+typedef fpos_t Py_off_t;
+#else
+#error "Large file support, but neither off_t nor fpos_t is large enough."
+#endif
+
+#define BUF(v) PyString_AS_STRING((PyStringObject *)v)
+
+#define MODE_CLOSED   0
+#define MODE_READ     1
+#define MODE_READ_EOF 2
+#define MODE_WRITE    3
+
+#define BZ2FileObject_Check(v)	((v)->ob_type == &BZ2File_Type)
+
+
+#ifdef BZ_CONFIG_ERROR
+
+#if SIZEOF_LONG >= 8
+#define BZS_TOTAL_OUT(bzs) \
+	(((long)bzs->total_out_hi32 << 32) + bzs->total_out_lo32)
+#elif SIZEOF_LONG_LONG >= 8
+#define BZS_TOTAL_OUT(bzs) \
+	(((PY_LONG_LONG)bzs->total_out_hi32 << 32) + bzs->total_out_lo32)
+#else
+#define BZS_TOTAL_OUT(bzs) \
+	bzs->total_out_lo32
+#endif
+
+#else /* ! BZ_CONFIG_ERROR */
+
+#define BZ2_bzRead bzRead
+#define BZ2_bzReadOpen bzReadOpen
+#define BZ2_bzReadClose bzReadClose
+#define BZ2_bzWrite bzWrite
+#define BZ2_bzWriteOpen bzWriteOpen
+#define BZ2_bzWriteClose bzWriteClose
+#define BZ2_bzCompress bzCompress
+#define BZ2_bzCompressInit bzCompressInit
+#define BZ2_bzCompressEnd bzCompressEnd
+#define BZ2_bzDecompress bzDecompress
+#define BZ2_bzDecompressInit bzDecompressInit
+#define BZ2_bzDecompressEnd bzDecompressEnd
+
+#define BZS_TOTAL_OUT(bzs) bzs->total_out
+
+#endif /* ! BZ_CONFIG_ERROR */
+
+
+#ifdef WITH_THREAD
+#define ACQUIRE_LOCK(obj) PyThread_acquire_lock(obj->lock, 1)
+#define RELEASE_LOCK(obj) PyThread_release_lock(obj->lock)
+#else
+#define ACQUIRE_LOCK(obj)
+#define RELEASE_LOCK(obj)
+#endif
+
+/* Bits in f_newlinetypes */
+#define NEWLINE_UNKNOWN	0	/* No newline seen, yet */
+#define NEWLINE_CR 1		/* \r newline seen */
+#define NEWLINE_LF 2		/* \n newline seen */
+#define NEWLINE_CRLF 4		/* \r\n newline seen */
+
+/* ===================================================================== */
+/* Structure definitions. */
+
+typedef struct {
+	PyObject_HEAD
+	PyObject *file;
+
+	char* f_buf;		/* Allocated readahead buffer */
+	char* f_bufend;		/* Points after last occupied position */
+	char* f_bufptr;		/* Current buffer position */
+
+	int f_softspace;	/* Flag used by 'print' command */
+
+	int f_univ_newline;	/* Handle any newline convention */
+	int f_newlinetypes;	/* Types of newlines seen */
+	int f_skipnextlf;	/* Skip next \n */
+
+	BZFILE *fp;
+	int mode;
+	Py_off_t pos;
+	Py_off_t size;
+#ifdef WITH_THREAD
+	PyThread_type_lock lock;
+#endif
+} BZ2FileObject;
+
+typedef struct {
+	PyObject_HEAD
+	bz_stream bzs;
+	int running;
+#ifdef WITH_THREAD
+	PyThread_type_lock lock;
+#endif
+} BZ2CompObject;
+
+typedef struct {
+	PyObject_HEAD
+	bz_stream bzs;
+	int running;
+	PyObject *unused_data;
+#ifdef WITH_THREAD
+	PyThread_type_lock lock;
+#endif
+} BZ2DecompObject;
+
+/* ===================================================================== */
+/* Utility functions. */
+
+static int
+Util_CatchBZ2Error(int bzerror)
+{
+	int ret = 0;
+	switch(bzerror) {
+		case BZ_OK:
+		case BZ_STREAM_END:
+			break;
+
+#ifdef BZ_CONFIG_ERROR
+		case BZ_CONFIG_ERROR:
+			PyErr_SetString(PyExc_SystemError,
+					"the bz2 library was not compiled "
+					"correctly");
+			ret = 1;
+			break;
+#endif
+
+		case BZ_PARAM_ERROR:
+			PyErr_SetString(PyExc_ValueError,
+					"the bz2 library has received wrong "
+					"parameters");
+			ret = 1;
+			break;
+
+		case BZ_MEM_ERROR:
+			PyErr_NoMemory();
+			ret = 1;
+			break;
+
+		case BZ_DATA_ERROR:
+		case BZ_DATA_ERROR_MAGIC:
+			PyErr_SetString(PyExc_IOError, "invalid data stream");
+			ret = 1;
+			break;
+
+		case BZ_IO_ERROR:
+			PyErr_SetString(PyExc_IOError, "unknown IO error");
+			ret = 1;
+			break;
+
+		case BZ_UNEXPECTED_EOF:
+			PyErr_SetString(PyExc_EOFError,
+					"compressed file ended before the "
+					"logical end-of-stream was detected");
+			ret = 1;
+			break;
+
+		case BZ_SEQUENCE_ERROR:
+			PyErr_SetString(PyExc_RuntimeError,
+					"wrong sequence of bz2 library "
+					"commands used");
+			ret = 1;
+			break;
+	}
+	return ret;
+}
+
+#if BUFSIZ < 8192
+#define SMALLCHUNK 8192
+#else
+#define SMALLCHUNK BUFSIZ
+#endif
+
+#if SIZEOF_INT < 4
+#define BIGCHUNK  (512 * 32)
+#else
+#define BIGCHUNK  (512 * 1024)
+#endif
+
+/* This is a hacked version of Python's fileobject.c:new_buffersize(). */
+static size_t
+Util_NewBufferSize(size_t currentsize)
+{
+	if (currentsize > SMALLCHUNK) {
+		/* Keep doubling until we reach BIGCHUNK;
+		   then keep adding BIGCHUNK. */
+		if (currentsize <= BIGCHUNK)
+			return currentsize + currentsize;
+		else
+			return currentsize + BIGCHUNK;
+	}
+	return currentsize + SMALLCHUNK;
+}
+
+/* This is a hacked version of Python's fileobject.c:get_line(). */
+static PyObject *
+Util_GetLine(BZ2FileObject *f, int n)
+{
+	char c;
+	char *buf, *end;
+	size_t total_v_size;	/* total # of slots in buffer */
+	size_t used_v_size;	/* # used slots in buffer */
+	size_t increment;       /* amount to increment the buffer */
+	PyObject *v;
+	int bzerror;
+	int newlinetypes = f->f_newlinetypes;
+	int skipnextlf = f->f_skipnextlf;
+	int univ_newline = f->f_univ_newline;
+
+	total_v_size = n > 0 ? n : 100;
+	v = PyString_FromStringAndSize((char *)NULL, total_v_size);
+	if (v == NULL)
+		return NULL;
+
+	buf = BUF(v);
+	end = buf + total_v_size;
+
+	for (;;) {
+		Py_BEGIN_ALLOW_THREADS
+		if (univ_newline) {
+			while (1) {
+				BZ2_bzRead(&bzerror, f->fp, &c, 1);
+				f->pos++;
+				if (bzerror != BZ_OK || buf == end)
+					break;
+				if (skipnextlf) {
+					skipnextlf = 0;
+					if (c == '\n') {
+						/* Seeing a \n here with
+						 * skipnextlf true means we
+						 * saw a \r before.
+						 */
+						newlinetypes |= NEWLINE_CRLF;
+						BZ2_bzRead(&bzerror, f->fp,
+							   &c, 1);
+						if (bzerror != BZ_OK)
+							break;
+					} else {
+						newlinetypes |= NEWLINE_CR;
+					}
+				}
+				if (c == '\r') {
+					skipnextlf = 1;
+					c = '\n';
+				} else if ( c == '\n')
+					newlinetypes |= NEWLINE_LF;
+				*buf++ = c;
+				if (c == '\n') break;
+			}
+			if (bzerror == BZ_STREAM_END && skipnextlf)
+				newlinetypes |= NEWLINE_CR;
+		} else /* If not universal newlines use the normal loop */
+			do {
+				BZ2_bzRead(&bzerror, f->fp, &c, 1);
+				f->pos++;
+				*buf++ = c;
+			} while (bzerror == BZ_OK && c != '\n' && buf != end);
+		Py_END_ALLOW_THREADS
+		f->f_newlinetypes = newlinetypes;
+		f->f_skipnextlf = skipnextlf;
+		if (bzerror == BZ_STREAM_END) {
+			f->size = f->pos;
+			f->mode = MODE_READ_EOF;
+			break;
+		} else if (bzerror != BZ_OK) {
+			Util_CatchBZ2Error(bzerror);
+			Py_DECREF(v);
+			return NULL;
+		}
+		if (c == '\n')
+			break;
+		/* Must be because buf == end */
+		if (n > 0)
+			break;
+		used_v_size = total_v_size;
+		increment = total_v_size >> 2; /* mild exponential growth */
+		total_v_size += increment;
+		if (total_v_size > INT_MAX) {
+			PyErr_SetString(PyExc_OverflowError,
+			    "line is longer than a Python string can hold");
+			Py_DECREF(v);
+			return NULL;
+		}
+		if (_PyString_Resize(&v, total_v_size) < 0)
+			return NULL;
+		buf = BUF(v) + used_v_size;
+		end = BUF(v) + total_v_size;
+	}
+
+	used_v_size = buf - BUF(v);
+	if (used_v_size != total_v_size)
+		_PyString_Resize(&v, used_v_size);
+	return v;
+}
+
+/* This is a hacked version of Python's
+ * fileobject.c:Py_UniversalNewlineFread(). */
+size_t
+Util_UnivNewlineRead(int *bzerror, BZFILE *stream,
+		     char* buf, size_t n, BZ2FileObject *f)
+{
+	char *dst = buf;
+	int newlinetypes, skipnextlf;
+
+	assert(buf != NULL);
+	assert(stream != NULL);
+
+	if (!f->f_univ_newline)
+		return BZ2_bzRead(bzerror, stream, buf, n);
+
+	newlinetypes = f->f_newlinetypes;
+	skipnextlf = f->f_skipnextlf;
+
+	/* Invariant:  n is the number of bytes remaining to be filled
+	 * in the buffer.
+	 */
+	while (n) {
+		size_t nread;
+		int shortread;
+		char *src = dst;
+
+		nread = BZ2_bzRead(bzerror, stream, dst, n);
+		assert(nread <= n);
+		n -= nread; /* assuming 1 byte out for each in; will adjust */
+		shortread = n != 0;	/* true iff EOF or error */
+		while (nread--) {
+			char c = *src++;
+			if (c == '\r') {
+				/* Save as LF and set flag to skip next LF. */
+				*dst++ = '\n';
+				skipnextlf = 1;
+			}
+			else if (skipnextlf && c == '\n') {
+				/* Skip LF, and remember we saw CR LF. */
+				skipnextlf = 0;
+				newlinetypes |= NEWLINE_CRLF;
+				++n;
+			}
+			else {
+				/* Normal char to be stored in buffer.  Also
+				 * update the newlinetypes flag if either this
+				 * is an LF or the previous char was a CR.
+				 */
+				if (c == '\n')
+					newlinetypes |= NEWLINE_LF;
+				else if (skipnextlf)
+					newlinetypes |= NEWLINE_CR;
+				*dst++ = c;
+				skipnextlf = 0;
+			}
+		}
+		if (shortread) {
+			/* If this is EOF, update type flags. */
+			if (skipnextlf && *bzerror == BZ_STREAM_END)
+				newlinetypes |= NEWLINE_CR;
+			break;
+		}
+	}
+	f->f_newlinetypes = newlinetypes;
+	f->f_skipnextlf = skipnextlf;
+	return dst - buf;
+}
+
+/* This is a hacked version of Python's fileobject.c:drop_readahead(). */
+static void
+Util_DropReadAhead(BZ2FileObject *f)
+{
+	if (f->f_buf != NULL) {
+		PyMem_Free(f->f_buf);
+		f->f_buf = NULL;
+	}
+}
+
+/* This is a hacked version of Python's fileobject.c:readahead(). */
+static int
+Util_ReadAhead(BZ2FileObject *f, int bufsize)
+{
+	int chunksize;
+	int bzerror;
+
+	if (f->f_buf != NULL) {
+		if((f->f_bufend - f->f_bufptr) >= 1)
+			return 0;
+		else
+			Util_DropReadAhead(f);
+	}
+	if (f->mode == MODE_READ_EOF) {
+		f->f_bufptr = f->f_buf;
+		f->f_bufend = f->f_buf;
+		return 0;
+	}
+	if ((f->f_buf = PyMem_Malloc(bufsize)) == NULL) {
+		return -1;
+	}
+	Py_BEGIN_ALLOW_THREADS
+	chunksize = Util_UnivNewlineRead(&bzerror, f->fp, f->f_buf,
+					 bufsize, f);
+	Py_END_ALLOW_THREADS
+	f->pos += chunksize;
+	if (bzerror == BZ_STREAM_END) {
+		f->size = f->pos;
+		f->mode = MODE_READ_EOF;
+	} else if (bzerror != BZ_OK) {
+		Util_CatchBZ2Error(bzerror);
+		Util_DropReadAhead(f);
+		return -1;
+	}
+	f->f_bufptr = f->f_buf;
+	f->f_bufend = f->f_buf + chunksize;
+	return 0;
+}
+
+/* This is a hacked version of Python's
+ * fileobject.c:readahead_get_line_skip(). */
+static PyStringObject *
+Util_ReadAheadGetLineSkip(BZ2FileObject *f, int skip, int bufsize)
+{
+	PyStringObject* s;
+	char *bufptr;
+	char *buf;
+	int len;
+
+	if (f->f_buf == NULL)
+		if (Util_ReadAhead(f, bufsize) < 0)
+			return NULL;
+
+	len = f->f_bufend - f->f_bufptr;
+	if (len == 0)
+		return (PyStringObject *)
+			PyString_FromStringAndSize(NULL, skip);
+	bufptr = memchr(f->f_bufptr, '\n', len);
+	if (bufptr != NULL) {
+		bufptr++;			/* Count the '\n' */
+		len = bufptr - f->f_bufptr;
+		s = (PyStringObject *)
+			PyString_FromStringAndSize(NULL, skip+len);
+		if (s == NULL)
+			return NULL;
+		memcpy(PyString_AS_STRING(s)+skip, f->f_bufptr, len);
+		f->f_bufptr = bufptr;
+		if (bufptr == f->f_bufend)
+			Util_DropReadAhead(f);
+	} else {
+		bufptr = f->f_bufptr;
+		buf = f->f_buf;
+		f->f_buf = NULL; 	/* Force new readahead buffer */
+                s = Util_ReadAheadGetLineSkip(f, skip+len,
+					      bufsize + (bufsize>>2));
+		if (s == NULL) {
+		        PyMem_Free(buf);
+			return NULL;
+		}
+		memcpy(PyString_AS_STRING(s)+skip, bufptr, len);
+		PyMem_Free(buf);
+	}
+	return s;
+}
+
+/* ===================================================================== */
+/* Methods of BZ2File. */
+
+PyDoc_STRVAR(BZ2File_read__doc__,
+"read([size]) -> string\n\
+\n\
+Read at most size uncompressed bytes, returned as a string. If the size\n\
+argument is negative or omitted, read until EOF is reached.\n\
+");
+
+/* This is a hacked version of Python's fileobject.c:file_read(). */
+static PyObject *
+BZ2File_read(BZ2FileObject *self, PyObject *args)
+{
+	long bytesrequested = -1;
+	size_t bytesread, buffersize, chunksize;
+	int bzerror;
+	PyObject *ret = NULL;
+
+	if (!PyArg_ParseTuple(args, "|l:read", &bytesrequested))
+		return NULL;
+
+	ACQUIRE_LOCK(self);
+	switch (self->mode) {
+		case MODE_READ:
+			break;
+		case MODE_READ_EOF:
+			ret = PyString_FromString("");
+			goto cleanup;
+		case MODE_CLOSED:
+			PyErr_SetString(PyExc_ValueError,
+					"I/O operation on closed file");
+			goto cleanup;
+		default:
+			PyErr_SetString(PyExc_IOError,
+					"file is not ready for reading");
+			goto cleanup;
+	}
+
+	if (bytesrequested < 0)
+		buffersize = Util_NewBufferSize((size_t)0);
+	else
+		buffersize = bytesrequested;
+	if (buffersize > INT_MAX) {
+		PyErr_SetString(PyExc_OverflowError,
+				"requested number of bytes is "
+				"more than a Python string can hold");
+		goto cleanup;
+	}
+	ret = PyString_FromStringAndSize((char *)NULL, buffersize);
+	if (ret == NULL)
+		goto cleanup;
+	bytesread = 0;
+
+	for (;;) {
+		Py_BEGIN_ALLOW_THREADS
+		chunksize = Util_UnivNewlineRead(&bzerror, self->fp,
+						 BUF(ret)+bytesread,
+						 buffersize-bytesread,
+						 self);
+		self->pos += chunksize;
+		Py_END_ALLOW_THREADS
+		bytesread += chunksize;
+		if (bzerror == BZ_STREAM_END) {
+			self->size = self->pos;
+			self->mode = MODE_READ_EOF;
+			break;
+		} else if (bzerror != BZ_OK) {
+			Util_CatchBZ2Error(bzerror);
+			Py_DECREF(ret);
+			ret = NULL;
+			goto cleanup;
+		}
+		if (bytesrequested < 0) {
+			buffersize = Util_NewBufferSize(buffersize);
+			if (_PyString_Resize(&ret, buffersize) < 0)
+				goto cleanup;
+		} else {
+			break;
+		}
+	}
+	if (bytesread != buffersize)
+		_PyString_Resize(&ret, bytesread);
+
+cleanup:
+	RELEASE_LOCK(self);
+	return ret;
+}
+
+PyDoc_STRVAR(BZ2File_readline__doc__,
+"readline([size]) -> string\n\
+\n\
+Return the next line from the file, as a string, retaining newline.\n\
+A non-negative size argument will limit the maximum number of bytes to\n\
+return (an incomplete line may be returned then). Return an empty\n\
+string at EOF.\n\
+");
+
+static PyObject *
+BZ2File_readline(BZ2FileObject *self, PyObject *args)
+{
+	PyObject *ret = NULL;
+	int sizehint = -1;
+
+	if (!PyArg_ParseTuple(args, "|i:readline", &sizehint))
+		return NULL;
+
+	ACQUIRE_LOCK(self);
+	switch (self->mode) {
+		case MODE_READ:
+			break;
+		case MODE_READ_EOF:
+			ret = PyString_FromString("");
+			goto cleanup;
+		case MODE_CLOSED:
+			PyErr_SetString(PyExc_ValueError,
+					"I/O operation on closed file");
+			goto cleanup;
+		default:
+			PyErr_SetString(PyExc_IOError,
+					"file is not ready for reading");
+			goto cleanup;
+	}
+
+	if (sizehint == 0)
+		ret = PyString_FromString("");
+	else
+		ret = Util_GetLine(self, (sizehint < 0) ? 0 : sizehint);
+
+cleanup:
+	RELEASE_LOCK(self);
+	return ret;
+}
+
+PyDoc_STRVAR(BZ2File_readlines__doc__,
+"readlines([size]) -> list\n\
+\n\
+Call readline() repeatedly and return a list of lines read.\n\
+The optional size argument, if given, is an approximate bound on the\n\
+total number of bytes in the lines returned.\n\
+");
+
+/* This is a hacked version of Python's fileobject.c:file_readlines(). */
+static PyObject *
+BZ2File_readlines(BZ2FileObject *self, PyObject *args)
+{
+	long sizehint = 0;
+	PyObject *list = NULL;
+	PyObject *line;
+	char small_buffer[SMALLCHUNK];
+	char *buffer = small_buffer;
+	size_t buffersize = SMALLCHUNK;
+	PyObject *big_buffer = NULL;
+	size_t nfilled = 0;
+	size_t nread;
+	size_t totalread = 0;
+	char *p, *q, *end;
+	int err;
+	int shortread = 0;
+	int bzerror;
+
+	if (!PyArg_ParseTuple(args, "|l:readlines", &sizehint))
+		return NULL;
+
+	ACQUIRE_LOCK(self);
+	switch (self->mode) {
+		case MODE_READ:
+			break;
+		case MODE_READ_EOF:
+			list = PyList_New(0);
+			goto cleanup;
+		case MODE_CLOSED:
+			PyErr_SetString(PyExc_ValueError,
+					"I/O operation on closed file");
+			goto cleanup;
+		default:
+			PyErr_SetString(PyExc_IOError,
+					"file is not ready for reading");
+			goto cleanup;
+	}
+
+	if ((list = PyList_New(0)) == NULL)
+		goto cleanup;
+
+	for (;;) {
+		Py_BEGIN_ALLOW_THREADS
+		nread = Util_UnivNewlineRead(&bzerror, self->fp,
+					     buffer+nfilled,
+					     buffersize-nfilled, self);
+		self->pos += nread;
+		Py_END_ALLOW_THREADS
+		if (bzerror == BZ_STREAM_END) {
+			self->size = self->pos;
+			self->mode = MODE_READ_EOF;
+			if (nread == 0) {
+				sizehint = 0;
+				break;
+			}
+			shortread = 1;
+		} else if (bzerror != BZ_OK) {
+			Util_CatchBZ2Error(bzerror);
+		  error:
+			Py_DECREF(list);
+			list = NULL;
+			goto cleanup;
+		}
+		totalread += nread;
+		p = memchr(buffer+nfilled, '\n', nread);
+		if (!shortread && p == NULL) {
+			/* Need a larger buffer to fit this line */
+			nfilled += nread;
+			buffersize *= 2;
+			if (buffersize > INT_MAX) {
+				PyErr_SetString(PyExc_OverflowError,
+				"line is longer than a Python string can hold");
+				goto error;
+			}
+			if (big_buffer == NULL) {
+				/* Create the big buffer */
+				big_buffer = PyString_FromStringAndSize(
+					NULL, buffersize);
+				if (big_buffer == NULL)
+					goto error;
+				buffer = PyString_AS_STRING(big_buffer);
+				memcpy(buffer, small_buffer, nfilled);
+			}
+			else {
+				/* Grow the big buffer */
+				_PyString_Resize(&big_buffer, buffersize);
+				buffer = PyString_AS_STRING(big_buffer);
+			}
+			continue;			
+		}
+		end = buffer+nfilled+nread;
+		q = buffer;
+		while (p != NULL) {
+			/* Process complete lines */
+			p++;
+			line = PyString_FromStringAndSize(q, p-q);
+			if (line == NULL)
+				goto error;
+			err = PyList_Append(list, line);
+			Py_DECREF(line);
+			if (err != 0)
+				goto error;
+			q = p;
+			p = memchr(q, '\n', end-q);
+		}
+		/* Move the remaining incomplete line to the start */
+		nfilled = end-q;
+		memmove(buffer, q, nfilled);
+		if (sizehint > 0)
+			if (totalread >= (size_t)sizehint)
+				break;
+		if (shortread) {
+			sizehint = 0;
+			break;
+		}
+	}
+	if (nfilled != 0) {
+		/* Partial last line */
+		line = PyString_FromStringAndSize(buffer, nfilled);
+		if (line == NULL)
+			goto error;
+		if (sizehint > 0) {
+			/* Need to complete the last line */
+			PyObject *rest = Util_GetLine(self, 0);
+			if (rest == NULL) {
+				Py_DECREF(line);
+				goto error;
+			}
+			PyString_Concat(&line, rest);
+			Py_DECREF(rest);
+			if (line == NULL)
+				goto error;
+		}
+		err = PyList_Append(list, line);
+		Py_DECREF(line);
+		if (err != 0)
+			goto error;
+	}
+
+  cleanup:
+	RELEASE_LOCK(self);
+	if (big_buffer) {
+		Py_DECREF(big_buffer);
+	}
+	return list;
+}
+
+PyDoc_STRVAR(BZ2File_xreadlines__doc__,
+"xreadlines() -> self\n\
+\n\
+For backward compatibility. BZ2File objects now include the performance\n\
+optimizations previously implemented in the xreadlines module.\n\
+");
+
+PyDoc_STRVAR(BZ2File_write__doc__,
+"write(data) -> None\n\
+\n\
+Write the 'data' string to file. Note that due to buffering, close() may\n\
+be needed before the file on disk reflects the data written.\n\
+");
+
+/* This is a hacked version of Python's fileobject.c:file_write(). */
+static PyObject *
+BZ2File_write(BZ2FileObject *self, PyObject *args)
+{
+	PyObject *ret = NULL;
+	char *buf;
+	int len;
+	int bzerror;
+
+	if (!PyArg_ParseTuple(args, "s#:write", &buf, &len))
+		return NULL;
+
+	ACQUIRE_LOCK(self);
+	switch (self->mode) {
+		case MODE_WRITE:
+			break;
+
+		case MODE_CLOSED:
+			PyErr_SetString(PyExc_ValueError,
+					"I/O operation on closed file");
+			goto cleanup;
+
+		default:
+			PyErr_SetString(PyExc_IOError,
+					"file is not ready for writing");
+			goto cleanup;
+	}
+
+	self->f_softspace = 0;
+
+	Py_BEGIN_ALLOW_THREADS
+	BZ2_bzWrite (&bzerror, self->fp, buf, len);
+	self->pos += len;
+	Py_END_ALLOW_THREADS
+
+	if (bzerror != BZ_OK) {
+		Util_CatchBZ2Error(bzerror);
+		goto cleanup;
+	}
+
+	Py_INCREF(Py_None);
+	ret = Py_None;
+
+cleanup:
+	RELEASE_LOCK(self);
+	return ret;
+}
+
+PyDoc_STRVAR(BZ2File_writelines__doc__,
+"writelines(sequence_of_strings) -> None\n\
+\n\
+Write the sequence of strings to the file. Note that newlines are not\n\
+added. The sequence can be any iterable object producing strings. This is\n\
+equivalent to calling write() for each string.\n\
+");
+
+/* This is a hacked version of Python's fileobject.c:file_writelines(). */
+static PyObject *
+BZ2File_writelines(BZ2FileObject *self, PyObject *seq)
+{
+#define CHUNKSIZE 1000
+	PyObject *list = NULL;
+	PyObject *iter = NULL;
+	PyObject *ret = NULL;
+	PyObject *line;
+	int i, j, index, len, islist;
+	int bzerror;
+
+	ACQUIRE_LOCK(self);
+	switch (self->mode) {
+		case MODE_WRITE:
+			break;
+
+		case MODE_CLOSED:
+			PyErr_SetString(PyExc_ValueError,
+					"I/O operation on closed file");
+			goto error;
+
+		default:
+			PyErr_SetString(PyExc_IOError,
+					"file is not ready for writing");
+			goto error;
+	}
+
+	islist = PyList_Check(seq);
+	if  (!islist) {
+		iter = PyObject_GetIter(seq);
+		if (iter == NULL) {
+			PyErr_SetString(PyExc_TypeError,
+				"writelines() requires an iterable argument");
+			goto error;
+		}
+		list = PyList_New(CHUNKSIZE);
+		if (list == NULL)
+			goto error;
+	}
+
+	/* Strategy: slurp CHUNKSIZE lines into a private list,
+	   checking that they are all strings, then write that list
+	   without holding the interpreter lock, then come back for more. */
+	for (index = 0; ; index += CHUNKSIZE) {
+		if (islist) {
+			Py_XDECREF(list);
+			list = PyList_GetSlice(seq, index, index+CHUNKSIZE);
+			if (list == NULL)
+				goto error;
+			j = PyList_GET_SIZE(list);
+		}
+		else {
+			for (j = 0; j < CHUNKSIZE; j++) {
+				line = PyIter_Next(iter);
+				if (line == NULL) {
+					if (PyErr_Occurred())
+						goto error;
+					break;
+				}
+				PyList_SetItem(list, j, line);
+			}
+		}
+		if (j == 0)
+			break;
+
+		/* Check that all entries are indeed strings. If not,
+		   apply the same rules as for file.write() and
+		   convert the rets to strings. This is slow, but
+		   seems to be the only way since all conversion APIs
+		   could potentially execute Python code. */
+		for (i = 0; i < j; i++) {
+			PyObject *v = PyList_GET_ITEM(list, i);
+			if (!PyString_Check(v)) {
+			    	const char *buffer;
+			    	Py_ssize_t len;
+				if (PyObject_AsCharBuffer(v, &buffer, &len)) {
+					PyErr_SetString(PyExc_TypeError,
+							"writelines() "
+							"argument must be "
+							"a sequence of "
+							"strings");
+					goto error;
+				}
+				line = PyString_FromStringAndSize(buffer,
+								  len);
+				if (line == NULL)
+					goto error;
+				Py_DECREF(v);
+				PyList_SET_ITEM(list, i, line);
+			}
+		}
+
+		self->f_softspace = 0;
+
+		/* Since we are releasing the global lock, the
+		   following code may *not* execute Python code. */
+		Py_BEGIN_ALLOW_THREADS
+		for (i = 0; i < j; i++) {
+		    	line = PyList_GET_ITEM(list, i);
+			len = PyString_GET_SIZE(line);
+			BZ2_bzWrite (&bzerror, self->fp,
+				     PyString_AS_STRING(line), len);
+			if (bzerror != BZ_OK) {
+				Py_BLOCK_THREADS
+				Util_CatchBZ2Error(bzerror);
+				goto error;
+			}
+		}
+		Py_END_ALLOW_THREADS
+
+		if (j < CHUNKSIZE)
+			break;
+	}
+
+	Py_INCREF(Py_None);
+	ret = Py_None;
+
+  error:
+	RELEASE_LOCK(self);
+	Py_XDECREF(list);
+  	Py_XDECREF(iter);
+	return ret;
+#undef CHUNKSIZE
+}
+
+PyDoc_STRVAR(BZ2File_seek__doc__,
+"seek(offset [, whence]) -> None\n\
+\n\
+Move to new file position. Argument offset is a byte count. Optional\n\
+argument whence defaults to 0 (offset from start of file, offset\n\
+should be >= 0); other values are 1 (move relative to current position,\n\
+positive or negative), and 2 (move relative to end of file, usually\n\
+negative, although many platforms allow seeking beyond the end of a file).\n\
+\n\
+Note that seeking of bz2 files is emulated, and depending on the parameters\n\
+the operation may be extremely slow.\n\
+");
+
+static PyObject *
+BZ2File_seek(BZ2FileObject *self, PyObject *args)
+{
+	int where = 0;
+	PyObject *offobj;
+	Py_off_t offset;
+	char small_buffer[SMALLCHUNK];
+	char *buffer = small_buffer;
+	size_t buffersize = SMALLCHUNK;
+	Py_off_t bytesread = 0;
+	size_t readsize;
+	int chunksize;
+	int bzerror;
+	PyObject *ret = NULL;
+
+	if (!PyArg_ParseTuple(args, "O|i:seek", &offobj, &where))
+		return NULL;
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+	offset = PyInt_AsLong(offobj);
+#else
+	offset = PyLong_Check(offobj) ?
+		PyLong_AsLongLong(offobj) : PyInt_AsLong(offobj);
+#endif
+	if (PyErr_Occurred())
+		return NULL;
+
+	ACQUIRE_LOCK(self);
+	Util_DropReadAhead(self);
+	switch (self->mode) {
+		case MODE_READ:
+		case MODE_READ_EOF:
+			break;
+
+		case MODE_CLOSED:
+			PyErr_SetString(PyExc_ValueError,
+					"I/O operation on closed file");
+			goto cleanup;
+
+		default:
+			PyErr_SetString(PyExc_IOError,
+					"seek works only while reading");
+			goto cleanup;
+	}
+
+	if (where == 2) {
+		if (self->size == -1) {
+			assert(self->mode != MODE_READ_EOF);
+			for (;;) {
+				Py_BEGIN_ALLOW_THREADS
+				chunksize = Util_UnivNewlineRead(
+						&bzerror, self->fp,
+						buffer, buffersize,
+						self);
+				self->pos += chunksize;
+				Py_END_ALLOW_THREADS
+
+				bytesread += chunksize;
+				if (bzerror == BZ_STREAM_END) {
+					break;
+				} else if (bzerror != BZ_OK) {
+					Util_CatchBZ2Error(bzerror);
+					goto cleanup;
+				}
+			}
+			self->mode = MODE_READ_EOF;
+			self->size = self->pos;
+			bytesread = 0;
+		}
+		offset = self->size + offset;
+	} else if (where == 1) {
+		offset = self->pos + offset;
+	}
+
+	/* Before getting here, offset must be the absolute position the file 
+	 * pointer should be set to. */
+
+	if (offset >= self->pos) {
+		/* we can move forward */
+		offset -= self->pos;
+	} else {
+		/* we cannot move back, so rewind the stream */
+		BZ2_bzReadClose(&bzerror, self->fp);
+		if (bzerror != BZ_OK) {
+			Util_CatchBZ2Error(bzerror);
+			goto cleanup;
+		}
+		ret = PyObject_CallMethod(self->file, "seek", "(i)", 0);
+		if (!ret)
+			goto cleanup;
+		Py_DECREF(ret);
+		ret = NULL;
+		self->pos = 0;
+		self->fp = BZ2_bzReadOpen(&bzerror, PyFile_AsFile(self->file),
+					  0, 0, NULL, 0);
+		if (bzerror != BZ_OK) {
+			Util_CatchBZ2Error(bzerror);
+			goto cleanup;
+		}
+		self->mode = MODE_READ;
+	}
+
+	if (offset <= 0 || self->mode == MODE_READ_EOF)
+		goto exit;
+
+	/* Before getting here, offset must be set to the number of bytes
+	 * to walk forward. */
+	for (;;) {
+		if (offset-bytesread > buffersize)
+			readsize = buffersize;
+		else
+			/* offset might be wider that readsize, but the result
+			 * of the subtraction is bound by buffersize (see the
+			 * condition above). buffersize is 8192. */
+			readsize = (size_t)(offset-bytesread);
+		Py_BEGIN_ALLOW_THREADS
+		chunksize = Util_UnivNewlineRead(&bzerror, self->fp,
+						 buffer, readsize, self);
+		self->pos += chunksize;
+		Py_END_ALLOW_THREADS
+		bytesread += chunksize;
+		if (bzerror == BZ_STREAM_END) {
+			self->size = self->pos;
+			self->mode = MODE_READ_EOF;
+			break;
+		} else if (bzerror != BZ_OK) {
+			Util_CatchBZ2Error(bzerror);
+			goto cleanup;
+		}
+		if (bytesread == offset)
+			break;
+	}
+
+exit:
+	Py_INCREF(Py_None);
+	ret = Py_None;
+
+cleanup:
+	RELEASE_LOCK(self);
+	return ret;
+}
+
+PyDoc_STRVAR(BZ2File_tell__doc__,
+"tell() -> int\n\
+\n\
+Return the current file position, an integer (may be a long integer).\n\
+");
+
+static PyObject *
+BZ2File_tell(BZ2FileObject *self, PyObject *args)
+{
+	PyObject *ret = NULL;
+
+	if (self->mode == MODE_CLOSED) {
+		PyErr_SetString(PyExc_ValueError,
+				"I/O operation on closed file");
+		goto cleanup;
+	}
+
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+	ret = PyInt_FromLong(self->pos);
+#else
+	ret = PyLong_FromLongLong(self->pos);
+#endif
+
+cleanup:
+	return ret;
+}
+
+PyDoc_STRVAR(BZ2File_close__doc__,
+"close() -> None or (perhaps) an integer\n\
+\n\
+Close the file. Sets data attribute .closed to true. A closed file\n\
+cannot be used for further I/O operations. close() may be called more\n\
+than once without error.\n\
+");
+
+static PyObject *
+BZ2File_close(BZ2FileObject *self)
+{
+	PyObject *ret = NULL;
+	int bzerror = BZ_OK;
+
+	ACQUIRE_LOCK(self);
+	switch (self->mode) {
+		case MODE_READ:
+		case MODE_READ_EOF:
+			BZ2_bzReadClose(&bzerror, self->fp);
+			break;
+		case MODE_WRITE:
+			BZ2_bzWriteClose(&bzerror, self->fp,
+					 0, NULL, NULL);
+			break;
+	}
+	self->mode = MODE_CLOSED;
+	ret = PyObject_CallMethod(self->file, "close", NULL);
+	if (bzerror != BZ_OK) {
+		Util_CatchBZ2Error(bzerror);
+		Py_XDECREF(ret);
+		ret = NULL;
+	}
+
+	RELEASE_LOCK(self);
+	return ret;
+}
+
+static PyObject *BZ2File_getiter(BZ2FileObject *self);
+
+static PyMethodDef BZ2File_methods[] = {
+	{"read", (PyCFunction)BZ2File_read, METH_VARARGS, BZ2File_read__doc__},
+	{"readline", (PyCFunction)BZ2File_readline, METH_VARARGS, BZ2File_readline__doc__},
+	{"readlines", (PyCFunction)BZ2File_readlines, METH_VARARGS, BZ2File_readlines__doc__},
+	{"xreadlines", (PyCFunction)BZ2File_getiter, METH_VARARGS, BZ2File_xreadlines__doc__},
+	{"write", (PyCFunction)BZ2File_write, METH_VARARGS, BZ2File_write__doc__},
+	{"writelines", (PyCFunction)BZ2File_writelines, METH_O, BZ2File_writelines__doc__},
+	{"seek", (PyCFunction)BZ2File_seek, METH_VARARGS, BZ2File_seek__doc__},
+	{"tell", (PyCFunction)BZ2File_tell, METH_NOARGS, BZ2File_tell__doc__},
+	{"close", (PyCFunction)BZ2File_close, METH_NOARGS, BZ2File_close__doc__},
+	{NULL,		NULL}		/* sentinel */
+};
+
+
+/* ===================================================================== */
+/* Getters and setters of BZ2File. */
+
+/* This is a hacked version of Python's fileobject.c:get_newlines(). */
+static PyObject *
+BZ2File_get_newlines(BZ2FileObject *self, void *closure)
+{
+	switch (self->f_newlinetypes) {
+	case NEWLINE_UNKNOWN:
+		Py_INCREF(Py_None);
+		return Py_None;
+	case NEWLINE_CR:
+		return PyString_FromString("\r");
+	case NEWLINE_LF:
+		return PyString_FromString("\n");
+	case NEWLINE_CR|NEWLINE_LF:
+		return Py_BuildValue("(ss)", "\r", "\n");
+	case NEWLINE_CRLF:
+		return PyString_FromString("\r\n");
+	case NEWLINE_CR|NEWLINE_CRLF:
+		return Py_BuildValue("(ss)", "\r", "\r\n");
+	case NEWLINE_LF|NEWLINE_CRLF:
+		return Py_BuildValue("(ss)", "\n", "\r\n");
+	case NEWLINE_CR|NEWLINE_LF|NEWLINE_CRLF:
+		return Py_BuildValue("(sss)", "\r", "\n", "\r\n");
+	default:
+		PyErr_Format(PyExc_SystemError, 
+			     "Unknown newlines value 0x%x\n", 
+			     self->f_newlinetypes);
+		return NULL;
+	}
+}
+
+static PyObject *
+BZ2File_get_closed(BZ2FileObject *self, void *closure)
+{
+	return PyInt_FromLong(self->mode == MODE_CLOSED);
+}
+
+static PyObject *
+BZ2File_get_mode(BZ2FileObject *self, void *closure)
+{
+	return PyObject_GetAttrString(self->file, "mode");
+}
+
+static PyObject *
+BZ2File_get_name(BZ2FileObject *self, void *closure)
+{
+	return PyObject_GetAttrString(self->file, "name");
+}
+
+static PyGetSetDef BZ2File_getset[] = {
+	{"closed", (getter)BZ2File_get_closed, NULL,
+			"True if the file is closed"},
+	{"newlines", (getter)BZ2File_get_newlines, NULL, 
+			"end-of-line convention used in this file"},
+	{"mode", (getter)BZ2File_get_mode, NULL,
+			"file mode ('r', 'w', or 'U')"},
+	{"name", (getter)BZ2File_get_name, NULL,
+			"file name"},
+	{NULL}	/* Sentinel */
+};
+
+
+/* ===================================================================== */
+/* Members of BZ2File_Type. */
+
+#undef OFF
+#define OFF(x) offsetof(BZ2FileObject, x)
+
+static PyMemberDef BZ2File_members[] = {
+	{"softspace",	T_INT,		OFF(f_softspace), 0,
+	 "flag indicating that a space needs to be printed; used by print"},
+	{NULL}	/* Sentinel */
+};
+
+/* ===================================================================== */
+/* Slot definitions for BZ2File_Type. */
+
+static int
+BZ2File_init(BZ2FileObject *self, PyObject *args, PyObject *kwargs)
+{
+	static char *kwlist[] = {"filename", "mode", "buffering",
+                                       "compresslevel", 0};
+	PyObject *name;
+	char *mode = "r";
+	int buffering = -1;
+	int compresslevel = 9;
+	int bzerror;
+	int mode_char = 0;
+
+	self->size = -1;
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|sii:BZ2File",
+					 kwlist, &name, &mode, &buffering,
+					 &compresslevel))
+		return -1;
+
+	if (compresslevel < 1 || compresslevel > 9) {
+		PyErr_SetString(PyExc_ValueError,
+				"compresslevel must be between 1 and 9");
+		return -1;
+	}
+
+	for (;;) {
+		int error = 0;
+		switch (*mode) {
+			case 'r':
+			case 'w':
+				if (mode_char)
+					error = 1;
+				mode_char = *mode;
+				break;
+
+			case 'b':
+				break;
+
+			case 'U':
+#ifdef __VMS
+				self->f_univ_newline = 0;
+#else
+				self->f_univ_newline = 1;
+#endif
+				break;
+
+			default:
+				error = 1;
+				break;
+		}
+		if (error) {
+			PyErr_Format(PyExc_ValueError,
+				     "invalid mode char %c", *mode);
+			return -1;
+		}
+		mode++;
+		if (*mode == '\0')
+			break;
+	}
+
+	if (mode_char == 0) {
+		mode_char = 'r';
+	}
+
+	mode = (mode_char == 'r') ? "rb" : "wb";
+
+	self->file = PyObject_CallFunction((PyObject*)&PyFile_Type, "(Osi)",
+					   name, mode, buffering);
+	if (self->file == NULL)
+		return -1;
+
+	/* From now on, we have stuff to dealloc, so jump to error label
+	 * instead of returning */
+
+#ifdef WITH_THREAD
+	self->lock = PyThread_allocate_lock();
+	if (!self->lock) {
+		PyErr_SetString(PyExc_MemoryError, "unable to allocate lock");
+		goto error;
+	}
+#endif
+
+	if (mode_char == 'r')
+		self->fp = BZ2_bzReadOpen(&bzerror,
+					  PyFile_AsFile(self->file),
+					  0, 0, NULL, 0);
+	else
+		self->fp = BZ2_bzWriteOpen(&bzerror,
+					   PyFile_AsFile(self->file),
+					   compresslevel, 0, 0);
+
+	if (bzerror != BZ_OK) {
+		Util_CatchBZ2Error(bzerror);
+		goto error;
+	}
+
+	self->mode = (mode_char == 'r') ? MODE_READ : MODE_WRITE;
+
+	return 0;
+
+error:
+	Py_CLEAR(self->file);
+#ifdef WITH_THREAD
+	if (self->lock) {
+		PyThread_free_lock(self->lock);
+		self->lock = NULL;
+	}
+#endif
+	return -1;
+}
+
+static void
+BZ2File_dealloc(BZ2FileObject *self)
+{
+	int bzerror;
+#ifdef WITH_THREAD
+	if (self->lock)
+		PyThread_free_lock(self->lock);
+#endif
+	switch (self->mode) {
+		case MODE_READ:
+		case MODE_READ_EOF:
+			BZ2_bzReadClose(&bzerror, self->fp);
+			break;
+		case MODE_WRITE:
+			BZ2_bzWriteClose(&bzerror, self->fp,
+					 0, NULL, NULL);
+			break;
+	}
+	Util_DropReadAhead(self);
+	Py_XDECREF(self->file);
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+/* This is a hacked version of Python's fileobject.c:file_getiter(). */
+static PyObject *
+BZ2File_getiter(BZ2FileObject *self)
+{
+	if (self->mode == MODE_CLOSED) {
+		PyErr_SetString(PyExc_ValueError,
+				"I/O operation on closed file");
+		return NULL;
+	}
+	Py_INCREF((PyObject*)self);
+	return (PyObject *)self;
+}
+
+/* This is a hacked version of Python's fileobject.c:file_iternext(). */
+#define READAHEAD_BUFSIZE 8192
+static PyObject *
+BZ2File_iternext(BZ2FileObject *self)
+{
+	PyStringObject* ret;
+	ACQUIRE_LOCK(self);
+	if (self->mode == MODE_CLOSED) {
+		PyErr_SetString(PyExc_ValueError,
+				"I/O operation on closed file");
+		return NULL;
+	}
+	ret = Util_ReadAheadGetLineSkip(self, 0, READAHEAD_BUFSIZE);
+	RELEASE_LOCK(self);
+	if (ret == NULL || PyString_GET_SIZE(ret) == 0) {
+		Py_XDECREF(ret);
+		return NULL;
+	}
+	return (PyObject *)ret;
+}
+
+/* ===================================================================== */
+/* BZ2File_Type definition. */
+
+PyDoc_VAR(BZ2File__doc__) =
+PyDoc_STR(
+"BZ2File(name [, mode='r', buffering=0, compresslevel=9]) -> file object\n\
+\n\
+Open a bz2 file. The mode can be 'r' or 'w', for reading (default) or\n\
+writing. When opened for writing, the file will be created if it doesn't\n\
+exist, and truncated otherwise. If the buffering argument is given, 0 means\n\
+unbuffered, and larger numbers specify the buffer size. If compresslevel\n\
+is given, must be a number between 1 and 9.\n\
+")
+PyDoc_STR(
+"\n\
+Add a 'U' to mode to open the file for input with universal newline\n\
+support. Any line ending in the input file will be seen as a '\\n' in\n\
+Python. Also, a file so opened gains the attribute 'newlines'; the value\n\
+for this attribute is one of None (no newline read yet), '\\r', '\\n',\n\
+'\\r\\n' or a tuple containing all the newline types seen. Universal\n\
+newlines are available only when reading.\n\
+")
+;
+
+static PyTypeObject BZ2File_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0,			/*ob_size*/
+	"bz2.BZ2File",		/*tp_name*/
+	sizeof(BZ2FileObject),	/*tp_basicsize*/
+	0,			/*tp_itemsize*/
+	(destructor)BZ2File_dealloc, /*tp_dealloc*/
+	0,			/*tp_print*/
+	0,			/*tp_getattr*/
+	0,			/*tp_setattr*/
+	0,			/*tp_compare*/
+	0,			/*tp_repr*/
+	0,			/*tp_as_number*/
+	0,			/*tp_as_sequence*/
+	0,			/*tp_as_mapping*/
+	0,			/*tp_hash*/
+        0,                      /*tp_call*/
+        0,                      /*tp_str*/
+        PyObject_GenericGetAttr,/*tp_getattro*/
+        PyObject_GenericSetAttr,/*tp_setattro*/
+        0,                      /*tp_as_buffer*/
+        Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/
+        BZ2File__doc__,         /*tp_doc*/
+        0,                      /*tp_traverse*/
+        0,                      /*tp_clear*/
+        0,                      /*tp_richcompare*/
+        0,                      /*tp_weaklistoffset*/
+        (getiterfunc)BZ2File_getiter, /*tp_iter*/
+        (iternextfunc)BZ2File_iternext, /*tp_iternext*/
+        BZ2File_methods,        /*tp_methods*/
+        BZ2File_members,        /*tp_members*/
+        BZ2File_getset,         /*tp_getset*/
+        0,                      /*tp_base*/
+        0,                      /*tp_dict*/
+        0,                      /*tp_descr_get*/
+        0,                      /*tp_descr_set*/
+        0,                      /*tp_dictoffset*/
+        (initproc)BZ2File_init, /*tp_init*/
+        PyType_GenericAlloc,    /*tp_alloc*/
+        PyType_GenericNew,      /*tp_new*/
+      	_PyObject_Del,          /*tp_free*/
+        0,                      /*tp_is_gc*/
+};
+
+
+/* ===================================================================== */
+/* Methods of BZ2Comp. */
+
+PyDoc_STRVAR(BZ2Comp_compress__doc__,
+"compress(data) -> string\n\
+\n\
+Provide more data to the compressor object. It will return chunks of\n\
+compressed data whenever possible. When you've finished providing data\n\
+to compress, call the flush() method to finish the compression process,\n\
+and return what is left in the internal buffers.\n\
+");
+
+static PyObject *
+BZ2Comp_compress(BZ2CompObject *self, PyObject *args)
+{
+	char *data;
+	int datasize;
+	int bufsize = SMALLCHUNK;
+	PY_LONG_LONG totalout;
+	PyObject *ret = NULL;
+	bz_stream *bzs = &self->bzs;
+	int bzerror;
+
+	if (!PyArg_ParseTuple(args, "s#:compress", &data, &datasize))
+		return NULL;
+
+	if (datasize == 0)
+		return PyString_FromString("");
+
+	ACQUIRE_LOCK(self);
+	if (!self->running) {
+		PyErr_SetString(PyExc_ValueError,
+				"this object was already flushed");
+		goto error;
+	}
+
+	ret = PyString_FromStringAndSize(NULL, bufsize);
+	if (!ret)
+		goto error;
+
+	bzs->next_in = data;
+	bzs->avail_in = datasize;
+	bzs->next_out = BUF(ret);
+	bzs->avail_out = bufsize;
+
+	totalout = BZS_TOTAL_OUT(bzs);
+
+	for (;;) {
+		Py_BEGIN_ALLOW_THREADS
+		bzerror = BZ2_bzCompress(bzs, BZ_RUN);
+		Py_END_ALLOW_THREADS
+		if (bzerror != BZ_RUN_OK) {
+			Util_CatchBZ2Error(bzerror);
+			goto error;
+		}
+		if (bzs->avail_in == 0)
+			break; /* no more input data */
+		if (bzs->avail_out == 0) {
+			bufsize = Util_NewBufferSize(bufsize);
+			if (_PyString_Resize(&ret, bufsize) < 0) {
+				BZ2_bzCompressEnd(bzs);
+				goto error;
+			}
+			bzs->next_out = BUF(ret) + (BZS_TOTAL_OUT(bzs)
+						    - totalout);
+			bzs->avail_out = bufsize - (bzs->next_out - BUF(ret));
+		}
+	}
+
+	_PyString_Resize(&ret, (Py_ssize_t)(BZS_TOTAL_OUT(bzs) - totalout));
+
+	RELEASE_LOCK(self);
+	return ret;
+
+error:
+	RELEASE_LOCK(self);
+	Py_XDECREF(ret);
+	return NULL;
+}
+
+PyDoc_STRVAR(BZ2Comp_flush__doc__,
+"flush() -> string\n\
+\n\
+Finish the compression process and return what is left in internal buffers.\n\
+You must not use the compressor object after calling this method.\n\
+");
+
+static PyObject *
+BZ2Comp_flush(BZ2CompObject *self)
+{
+	int bufsize = SMALLCHUNK;
+	PyObject *ret = NULL;
+	bz_stream *bzs = &self->bzs;
+	PY_LONG_LONG totalout;
+	int bzerror;
+
+	ACQUIRE_LOCK(self);
+	if (!self->running) {
+		PyErr_SetString(PyExc_ValueError, "object was already "
+						  "flushed");
+		goto error;
+	}
+	self->running = 0;
+
+	ret = PyString_FromStringAndSize(NULL, bufsize);
+	if (!ret)
+		goto error;
+
+	bzs->next_out = BUF(ret);
+	bzs->avail_out = bufsize;
+
+	totalout = BZS_TOTAL_OUT(bzs);
+
+	for (;;) {
+		Py_BEGIN_ALLOW_THREADS
+		bzerror = BZ2_bzCompress(bzs, BZ_FINISH);
+		Py_END_ALLOW_THREADS
+		if (bzerror == BZ_STREAM_END) {
+			break;
+		} else if (bzerror != BZ_FINISH_OK) {
+			Util_CatchBZ2Error(bzerror);
+			goto error;
+		}
+		if (bzs->avail_out == 0) {
+			bufsize = Util_NewBufferSize(bufsize);
+			if (_PyString_Resize(&ret, bufsize) < 0)
+				goto error;
+			bzs->next_out = BUF(ret);
+			bzs->next_out = BUF(ret) + (BZS_TOTAL_OUT(bzs)
+						    - totalout);
+			bzs->avail_out = bufsize - (bzs->next_out - BUF(ret));
+		}
+	}
+
+	if (bzs->avail_out != 0)
+		_PyString_Resize(&ret, (Py_ssize_t)(BZS_TOTAL_OUT(bzs) - totalout));
+
+	RELEASE_LOCK(self);
+	return ret;
+
+error:
+	RELEASE_LOCK(self);
+	Py_XDECREF(ret);
+	return NULL;
+}
+
+static PyMethodDef BZ2Comp_methods[] = {
+	{"compress", (PyCFunction)BZ2Comp_compress, METH_VARARGS,
+	 BZ2Comp_compress__doc__},
+	{"flush", (PyCFunction)BZ2Comp_flush, METH_NOARGS,
+	 BZ2Comp_flush__doc__},
+	{NULL,		NULL}		/* sentinel */
+};
+
+
+/* ===================================================================== */
+/* Slot definitions for BZ2Comp_Type. */
+
+static int
+BZ2Comp_init(BZ2CompObject *self, PyObject *args, PyObject *kwargs)
+{
+	int compresslevel = 9;
+	int bzerror;
+	static char *kwlist[] = {"compresslevel", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:BZ2Compressor",
+					 kwlist, &compresslevel))
+		return -1;
+
+	if (compresslevel < 1 || compresslevel > 9) {
+		PyErr_SetString(PyExc_ValueError,
+				"compresslevel must be between 1 and 9");
+		goto error;
+	}
+
+#ifdef WITH_THREAD
+	self->lock = PyThread_allocate_lock();
+	if (!self->lock) {
+		PyErr_SetString(PyExc_MemoryError, "unable to allocate lock");
+		goto error;
+	}
+#endif
+
+	memset(&self->bzs, 0, sizeof(bz_stream));
+	bzerror = BZ2_bzCompressInit(&self->bzs, compresslevel, 0, 0);
+	if (bzerror != BZ_OK) {
+		Util_CatchBZ2Error(bzerror);
+		goto error;
+	}
+
+	self->running = 1;
+
+	return 0;
+error:
+#ifdef WITH_THREAD
+	if (self->lock) {
+		PyThread_free_lock(self->lock);
+		self->lock = NULL;
+	}
+#endif
+	return -1;
+}
+
+static void
+BZ2Comp_dealloc(BZ2CompObject *self)
+{
+#ifdef WITH_THREAD
+	if (self->lock)
+		PyThread_free_lock(self->lock);
+#endif
+	BZ2_bzCompressEnd(&self->bzs);
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+
+/* ===================================================================== */
+/* BZ2Comp_Type definition. */
+
+PyDoc_STRVAR(BZ2Comp__doc__,
+"BZ2Compressor([compresslevel=9]) -> compressor object\n\
+\n\
+Create a new compressor object. This object may be used to compress\n\
+data sequentially. If you want to compress data in one shot, use the\n\
+compress() function instead. The compresslevel parameter, if given,\n\
+must be a number between 1 and 9.\n\
+");
+
+static PyTypeObject BZ2Comp_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0,			/*ob_size*/
+	"bz2.BZ2Compressor",	/*tp_name*/
+	sizeof(BZ2CompObject),	/*tp_basicsize*/
+	0,			/*tp_itemsize*/
+	(destructor)BZ2Comp_dealloc, /*tp_dealloc*/
+	0,			/*tp_print*/
+	0,			/*tp_getattr*/
+	0,			/*tp_setattr*/
+	0,			/*tp_compare*/
+	0,			/*tp_repr*/
+	0,			/*tp_as_number*/
+	0,			/*tp_as_sequence*/
+	0,			/*tp_as_mapping*/
+	0,			/*tp_hash*/
+        0,                      /*tp_call*/
+        0,                      /*tp_str*/
+        PyObject_GenericGetAttr,/*tp_getattro*/
+        PyObject_GenericSetAttr,/*tp_setattro*/
+        0,                      /*tp_as_buffer*/
+        Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/
+        BZ2Comp__doc__,         /*tp_doc*/
+        0,                      /*tp_traverse*/
+        0,                      /*tp_clear*/
+        0,                      /*tp_richcompare*/
+        0,                      /*tp_weaklistoffset*/
+        0,                      /*tp_iter*/
+        0,                      /*tp_iternext*/
+        BZ2Comp_methods,        /*tp_methods*/
+        0,                      /*tp_members*/
+        0,                      /*tp_getset*/
+        0,                      /*tp_base*/
+        0,                      /*tp_dict*/
+        0,                      /*tp_descr_get*/
+        0,                      /*tp_descr_set*/
+        0,                      /*tp_dictoffset*/
+        (initproc)BZ2Comp_init, /*tp_init*/
+        PyType_GenericAlloc,    /*tp_alloc*/
+        PyType_GenericNew,      /*tp_new*/
+      	_PyObject_Del,          /*tp_free*/
+        0,                      /*tp_is_gc*/
+};
+
+
+/* ===================================================================== */
+/* Members of BZ2Decomp. */
+
+#undef OFF
+#define OFF(x) offsetof(BZ2DecompObject, x)
+
+static PyMemberDef BZ2Decomp_members[] = {
+	{"unused_data", T_OBJECT, OFF(unused_data), RO},
+	{NULL}	/* Sentinel */
+};
+
+
+/* ===================================================================== */
+/* Methods of BZ2Decomp. */
+
+PyDoc_STRVAR(BZ2Decomp_decompress__doc__,
+"decompress(data) -> string\n\
+\n\
+Provide more data to the decompressor object. It will return chunks\n\
+of decompressed data whenever possible. If you try to decompress data\n\
+after the end of stream is found, EOFError will be raised. If any data\n\
+was found after the end of stream, it'll be ignored and saved in\n\
+unused_data attribute.\n\
+");
+
+static PyObject *
+BZ2Decomp_decompress(BZ2DecompObject *self, PyObject *args)
+{
+	char *data;
+	int datasize;
+	int bufsize = SMALLCHUNK;
+	PY_LONG_LONG totalout;
+	PyObject *ret = NULL;
+	bz_stream *bzs = &self->bzs;
+	int bzerror;
+
+	if (!PyArg_ParseTuple(args, "s#:decompress", &data, &datasize))
+		return NULL;
+
+	ACQUIRE_LOCK(self);
+	if (!self->running) {
+		PyErr_SetString(PyExc_EOFError, "end of stream was "
+						"already found");
+		goto error;
+	}
+
+	ret = PyString_FromStringAndSize(NULL, bufsize);
+	if (!ret)
+		goto error;
+
+	bzs->next_in = data;
+	bzs->avail_in = datasize;
+	bzs->next_out = BUF(ret);
+	bzs->avail_out = bufsize;
+
+	totalout = BZS_TOTAL_OUT(bzs);
+
+	for (;;) {
+		Py_BEGIN_ALLOW_THREADS
+		bzerror = BZ2_bzDecompress(bzs);
+		Py_END_ALLOW_THREADS
+		if (bzerror == BZ_STREAM_END) {
+			if (bzs->avail_in != 0) {
+				Py_DECREF(self->unused_data);
+				self->unused_data =
+				    PyString_FromStringAndSize(bzs->next_in,
+							       bzs->avail_in);
+			}
+			self->running = 0;
+			break;
+		}
+		if (bzerror != BZ_OK) {
+			Util_CatchBZ2Error(bzerror);
+			goto error;
+		}
+		if (bzs->avail_in == 0)
+			break; /* no more input data */
+		if (bzs->avail_out == 0) {
+			bufsize = Util_NewBufferSize(bufsize);
+			if (_PyString_Resize(&ret, bufsize) < 0) {
+				BZ2_bzDecompressEnd(bzs);
+				goto error;
+			}
+			bzs->next_out = BUF(ret);
+			bzs->next_out = BUF(ret) + (BZS_TOTAL_OUT(bzs)
+						    - totalout);
+			bzs->avail_out = bufsize - (bzs->next_out - BUF(ret));
+		}
+	}
+
+	if (bzs->avail_out != 0)
+		_PyString_Resize(&ret, (Py_ssize_t)(BZS_TOTAL_OUT(bzs) - totalout));
+
+	RELEASE_LOCK(self);
+	return ret;
+
+error:
+	RELEASE_LOCK(self);
+	Py_XDECREF(ret);
+	return NULL;
+}
+
+static PyMethodDef BZ2Decomp_methods[] = {
+	{"decompress", (PyCFunction)BZ2Decomp_decompress, METH_VARARGS, BZ2Decomp_decompress__doc__},
+	{NULL,		NULL}		/* sentinel */
+};
+
+
+/* ===================================================================== */
+/* Slot definitions for BZ2Decomp_Type. */
+
+static int
+BZ2Decomp_init(BZ2DecompObject *self, PyObject *args, PyObject *kwargs)
+{
+	int bzerror;
+
+	if (!PyArg_ParseTuple(args, ":BZ2Decompressor"))
+		return -1;
+
+#ifdef WITH_THREAD
+	self->lock = PyThread_allocate_lock();
+	if (!self->lock) {
+		PyErr_SetString(PyExc_MemoryError, "unable to allocate lock");
+		goto error;
+	}
+#endif
+
+	self->unused_data = PyString_FromString("");
+	if (!self->unused_data)
+		goto error;
+
+	memset(&self->bzs, 0, sizeof(bz_stream));
+	bzerror = BZ2_bzDecompressInit(&self->bzs, 0, 0);
+	if (bzerror != BZ_OK) {
+		Util_CatchBZ2Error(bzerror);
+		goto error;
+	}
+
+	self->running = 1;
+
+	return 0;
+
+error:
+#ifdef WITH_THREAD
+	if (self->lock) {
+		PyThread_free_lock(self->lock);
+		self->lock = NULL;
+	}
+#endif
+	Py_CLEAR(self->unused_data);
+	return -1;
+}
+
+static void
+BZ2Decomp_dealloc(BZ2DecompObject *self)
+{
+#ifdef WITH_THREAD
+	if (self->lock)
+		PyThread_free_lock(self->lock);
+#endif
+	Py_XDECREF(self->unused_data);
+	BZ2_bzDecompressEnd(&self->bzs);
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+
+/* ===================================================================== */
+/* BZ2Decomp_Type definition. */
+
+PyDoc_STRVAR(BZ2Decomp__doc__,
+"BZ2Decompressor() -> decompressor object\n\
+\n\
+Create a new decompressor object. This object may be used to decompress\n\
+data sequentially. If you want to decompress data in one shot, use the\n\
+decompress() function instead.\n\
+");
+
+static PyTypeObject BZ2Decomp_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0,			/*ob_size*/
+	"bz2.BZ2Decompressor",	/*tp_name*/
+	sizeof(BZ2DecompObject), /*tp_basicsize*/
+	0,			/*tp_itemsize*/
+	(destructor)BZ2Decomp_dealloc, /*tp_dealloc*/
+	0,			/*tp_print*/
+	0,			/*tp_getattr*/
+	0,			/*tp_setattr*/
+	0,			/*tp_compare*/
+	0,			/*tp_repr*/
+	0,			/*tp_as_number*/
+	0,			/*tp_as_sequence*/
+	0,			/*tp_as_mapping*/
+	0,			/*tp_hash*/
+        0,                      /*tp_call*/
+        0,                      /*tp_str*/
+        PyObject_GenericGetAttr,/*tp_getattro*/
+        PyObject_GenericSetAttr,/*tp_setattro*/
+        0,                      /*tp_as_buffer*/
+        Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/
+        BZ2Decomp__doc__,       /*tp_doc*/
+        0,                      /*tp_traverse*/
+        0,                      /*tp_clear*/
+        0,                      /*tp_richcompare*/
+        0,                      /*tp_weaklistoffset*/
+        0,                      /*tp_iter*/
+        0,                      /*tp_iternext*/
+        BZ2Decomp_methods,      /*tp_methods*/
+        BZ2Decomp_members,      /*tp_members*/
+        0,                      /*tp_getset*/
+        0,                      /*tp_base*/
+        0,                      /*tp_dict*/
+        0,                      /*tp_descr_get*/
+        0,                      /*tp_descr_set*/
+        0,                      /*tp_dictoffset*/
+        (initproc)BZ2Decomp_init, /*tp_init*/
+        PyType_GenericAlloc,    /*tp_alloc*/
+        PyType_GenericNew,      /*tp_new*/
+      	_PyObject_Del,          /*tp_free*/
+        0,                      /*tp_is_gc*/
+};
+
+
+/* ===================================================================== */
+/* Module functions. */
+
+PyDoc_STRVAR(bz2_compress__doc__,
+"compress(data [, compresslevel=9]) -> string\n\
+\n\
+Compress data in one shot. If you want to compress data sequentially,\n\
+use an instance of BZ2Compressor instead. The compresslevel parameter, if\n\
+given, must be a number between 1 and 9.\n\
+");
+
+static PyObject *
+bz2_compress(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+	int compresslevel=9;
+	char *data;
+	int datasize;
+	int bufsize;
+	PyObject *ret = NULL;
+	bz_stream _bzs;
+	bz_stream *bzs = &_bzs;
+	int bzerror;
+	static char *kwlist[] = {"data", "compresslevel", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#|i",
+					 kwlist, &data, &datasize,
+					 &compresslevel))
+		return NULL;
+
+	if (compresslevel < 1 || compresslevel > 9) {
+		PyErr_SetString(PyExc_ValueError,
+				"compresslevel must be between 1 and 9");
+		return NULL;
+	}
+
+	/* Conforming to bz2 manual, this is large enough to fit compressed
+	 * data in one shot. We will check it later anyway. */
+	bufsize = datasize + (datasize/100+1) + 600;
+
+	ret = PyString_FromStringAndSize(NULL, bufsize);
+	if (!ret)
+		return NULL;
+
+	memset(bzs, 0, sizeof(bz_stream));
+
+	bzs->next_in = data;
+	bzs->avail_in = datasize;
+	bzs->next_out = BUF(ret);
+	bzs->avail_out = bufsize;
+
+	bzerror = BZ2_bzCompressInit(bzs, compresslevel, 0, 0);
+	if (bzerror != BZ_OK) {
+		Util_CatchBZ2Error(bzerror);
+		Py_DECREF(ret);
+		return NULL;
+	}
+
+	for (;;) {
+		Py_BEGIN_ALLOW_THREADS
+		bzerror = BZ2_bzCompress(bzs, BZ_FINISH);
+		Py_END_ALLOW_THREADS
+		if (bzerror == BZ_STREAM_END) {
+			break;
+		} else if (bzerror != BZ_FINISH_OK) {
+			BZ2_bzCompressEnd(bzs);
+			Util_CatchBZ2Error(bzerror);
+			Py_DECREF(ret);
+			return NULL;
+		}
+		if (bzs->avail_out == 0) {
+			bufsize = Util_NewBufferSize(bufsize);
+			if (_PyString_Resize(&ret, bufsize) < 0) {
+				BZ2_bzCompressEnd(bzs);
+				Py_DECREF(ret);
+				return NULL;
+			}
+			bzs->next_out = BUF(ret) + BZS_TOTAL_OUT(bzs);
+			bzs->avail_out = bufsize - (bzs->next_out - BUF(ret));
+		}
+	}
+
+	if (bzs->avail_out != 0)
+		_PyString_Resize(&ret, (Py_ssize_t)BZS_TOTAL_OUT(bzs));
+	BZ2_bzCompressEnd(bzs);
+
+	return ret;
+}
+
+PyDoc_STRVAR(bz2_decompress__doc__,
+"decompress(data) -> decompressed data\n\
+\n\
+Decompress data in one shot. If you want to decompress data sequentially,\n\
+use an instance of BZ2Decompressor instead.\n\
+");
+
+static PyObject *
+bz2_decompress(PyObject *self, PyObject *args)
+{
+	char *data;
+	int datasize;
+	int bufsize = SMALLCHUNK;
+	PyObject *ret;
+	bz_stream _bzs;
+	bz_stream *bzs = &_bzs;
+	int bzerror;
+
+	if (!PyArg_ParseTuple(args, "s#:decompress", &data, &datasize))
+		return NULL;
+
+	if (datasize == 0)
+		return PyString_FromString("");
+
+	ret = PyString_FromStringAndSize(NULL, bufsize);
+	if (!ret)
+		return NULL;
+
+	memset(bzs, 0, sizeof(bz_stream));
+
+	bzs->next_in = data;
+	bzs->avail_in = datasize;
+	bzs->next_out = BUF(ret);
+	bzs->avail_out = bufsize;
+
+	bzerror = BZ2_bzDecompressInit(bzs, 0, 0);
+	if (bzerror != BZ_OK) {
+		Util_CatchBZ2Error(bzerror);
+		Py_DECREF(ret);
+		return NULL;
+	}
+
+	for (;;) {
+		Py_BEGIN_ALLOW_THREADS
+		bzerror = BZ2_bzDecompress(bzs);
+		Py_END_ALLOW_THREADS
+		if (bzerror == BZ_STREAM_END) {
+			break;
+		} else if (bzerror != BZ_OK) {
+			BZ2_bzDecompressEnd(bzs);
+			Util_CatchBZ2Error(bzerror);
+			Py_DECREF(ret);
+			return NULL;
+		}
+		if (bzs->avail_in == 0) {
+			BZ2_bzDecompressEnd(bzs);
+			PyErr_SetString(PyExc_ValueError,
+					"couldn't find end of stream");
+			Py_DECREF(ret);
+			return NULL;
+		}
+		if (bzs->avail_out == 0) {
+			bufsize = Util_NewBufferSize(bufsize);
+			if (_PyString_Resize(&ret, bufsize) < 0) {
+				BZ2_bzDecompressEnd(bzs);
+				Py_DECREF(ret);
+				return NULL;
+			}
+			bzs->next_out = BUF(ret) + BZS_TOTAL_OUT(bzs);
+			bzs->avail_out = bufsize - (bzs->next_out - BUF(ret));
+		}
+	}
+
+	if (bzs->avail_out != 0)
+		_PyString_Resize(&ret, (Py_ssize_t)BZS_TOTAL_OUT(bzs));
+	BZ2_bzDecompressEnd(bzs);
+
+	return ret;
+}
+
+static PyMethodDef bz2_methods[] = {
+	{"compress", (PyCFunction) bz2_compress, METH_VARARGS|METH_KEYWORDS,
+		bz2_compress__doc__},
+	{"decompress", (PyCFunction) bz2_decompress, METH_VARARGS,
+		bz2_decompress__doc__},
+	{NULL,		NULL}		/* sentinel */
+};
+
+/* ===================================================================== */
+/* Initialization function. */
+
+PyDoc_STRVAR(bz2__doc__,
+"The python bz2 module provides a comprehensive interface for\n\
+the bz2 compression library. It implements a complete file\n\
+interface, one shot (de)compression functions, and types for\n\
+sequential (de)compression.\n\
+");
+
+PyMODINIT_FUNC
+initbz2(void)
+{
+	PyObject *m;
+
+	BZ2File_Type.ob_type = &PyType_Type;
+	BZ2Comp_Type.ob_type = &PyType_Type;
+	BZ2Decomp_Type.ob_type = &PyType_Type;
+
+	m = Py_InitModule3("bz2", bz2_methods, bz2__doc__);
+	if (m == NULL)
+		return;
+
+	PyModule_AddObject(m, "__author__", PyString_FromString(__author__));
+
+	Py_INCREF(&BZ2File_Type);
+	PyModule_AddObject(m, "BZ2File", (PyObject *)&BZ2File_Type);
+
+	Py_INCREF(&BZ2Comp_Type);
+	PyModule_AddObject(m, "BZ2Compressor", (PyObject *)&BZ2Comp_Type);
+
+	Py_INCREF(&BZ2Decomp_Type);
+	PyModule_AddObject(m, "BZ2Decompressor", (PyObject *)&BZ2Decomp_Type);
+}

Added: vendor/Python/current/Modules/cPickle.c
===================================================================
--- vendor/Python/current/Modules/cPickle.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/cPickle.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,5757 @@
+#include "Python.h"
+#include "cStringIO.h"
+#include "structmember.h"
+
+PyDoc_STRVAR(cPickle_module_documentation,
+"C implementation and optimization of the Python pickle module.");
+
+#ifndef Py_eval_input
+#include <graminit.h>
+#define Py_eval_input eval_input
+#endif /* Py_eval_input */
+
+#define DEL_LIST_SLICE(list, from, to) (PyList_SetSlice(list, from, to, NULL))
+
+#define WRITE_BUF_SIZE 256
+
+/* Bump this when new opcodes are added to the pickle protocol. */
+#define HIGHEST_PROTOCOL 2
+
+/*
+ * Pickle opcodes.  These must be kept in synch with pickle.py.  Extensive
+ * docs are in pickletools.py.
+ */
+#define MARK        '('
+#define STOP        '.'
+#define POP         '0'
+#define POP_MARK    '1'
+#define DUP         '2'
+#define FLOAT       'F'
+#define BINFLOAT    'G'
+#define INT         'I'
+#define BININT      'J'
+#define BININT1     'K'
+#define LONG        'L'
+#define BININT2     'M'
+#define NONE        'N'
+#define PERSID      'P'
+#define BINPERSID   'Q'
+#define REDUCE      'R'
+#define STRING      'S'
+#define BINSTRING   'T'
+#define SHORT_BINSTRING 'U'
+#define UNICODE     'V'
+#define BINUNICODE  'X'
+#define APPEND      'a'
+#define BUILD       'b'
+#define GLOBAL      'c'
+#define DICT        'd'
+#define EMPTY_DICT  '}'
+#define APPENDS     'e'
+#define GET         'g'
+#define BINGET      'h'
+#define INST        'i'
+#define LONG_BINGET 'j'
+#define LIST        'l'
+#define EMPTY_LIST  ']'
+#define OBJ         'o'
+#define PUT         'p'
+#define BINPUT      'q'
+#define LONG_BINPUT 'r'
+#define SETITEM     's'
+#define TUPLE       't'
+#define EMPTY_TUPLE ')'
+#define SETITEMS    'u'
+
+/* Protocol 2. */
+#define PROTO	 '\x80' /* identify pickle protocol */
+#define NEWOBJ   '\x81' /* build object by applying cls.__new__ to argtuple */
+#define EXT1     '\x82' /* push object from extension registry; 1-byte index */
+#define EXT2     '\x83' /* ditto, but 2-byte index */
+#define EXT4     '\x84' /* ditto, but 4-byte index */
+#define TUPLE1   '\x85' /* build 1-tuple from stack top */
+#define TUPLE2   '\x86' /* build 2-tuple from two topmost stack items */
+#define TUPLE3   '\x87' /* build 3-tuple from three topmost stack items */
+#define NEWTRUE  '\x88' /* push True */
+#define NEWFALSE '\x89' /* push False */
+#define LONG1    '\x8a' /* push long from < 256 bytes */
+#define LONG4    '\x8b' /* push really big long */
+
+/* There aren't opcodes -- they're ways to pickle bools before protocol 2,
+ * so that unpicklers written before bools were introduced unpickle them
+ * as ints, but unpicklers after can recognize that bools were intended.
+ * Note that protocol 2 added direct ways to pickle bools.
+ */
+#undef TRUE
+#define TRUE        "I01\n"
+#undef FALSE
+#define FALSE       "I00\n"
+
+/* Keep in synch with pickle.Pickler._BATCHSIZE.  This is how many elements
+ * batch_list/dict() pumps out before doing APPENDS/SETITEMS.  Nothing will
+ * break if this gets out of synch with pickle.py, but it's unclear that
+ * would help anything either.
+ */
+#define BATCHSIZE 1000
+
+static char MARKv = MARK;
+
+static PyObject *PickleError;
+static PyObject *PicklingError;
+static PyObject *UnpickleableError;
+static PyObject *UnpicklingError;
+static PyObject *BadPickleGet;
+
+/* As the name says, an empty tuple. */
+static PyObject *empty_tuple;
+
+/* copy_reg.dispatch_table, {type_object: pickling_function} */
+static PyObject *dispatch_table;
+
+/* For EXT[124] opcodes. */
+/* copy_reg._extension_registry, {(module_name, function_name): code} */
+static PyObject *extension_registry;
+/* copy_reg._inverted_registry, {code: (module_name, function_name)} */
+static PyObject *inverted_registry;
+/* copy_reg._extension_cache, {code: object} */
+static PyObject *extension_cache;
+
+/* For looking up name pairs in copy_reg._extension_registry. */
+static PyObject *two_tuple;
+
+static PyObject *__class___str, *__getinitargs___str, *__dict___str,
+  *__getstate___str, *__setstate___str, *__name___str, *__reduce___str,
+  *__reduce_ex___str,
+  *write_str, *append_str,
+  *read_str, *readline_str, *__main___str, 
+  *copy_reg_str, *dispatch_table_str;
+
+/*************************************************************************
+ Internal Data type for pickle data.                                     */
+
+typedef struct {
+	PyObject_HEAD
+	int length;	/* number of initial slots in data currently used */
+	int size;	/* number of slots in data allocated */
+	PyObject **data;
+} Pdata;
+
+static void
+Pdata_dealloc(Pdata *self)
+{
+	int i;
+	PyObject **p;
+
+	for (i = self->length, p = self->data; --i >= 0; p++) {
+		Py_DECREF(*p);
+	}
+	if (self->data)
+		free(self->data);
+	PyObject_Del(self);
+}
+
+static PyTypeObject PdataType = {
+	PyObject_HEAD_INIT(NULL) 0, "cPickle.Pdata", sizeof(Pdata), 0,
+	(destructor)Pdata_dealloc,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0L,0L,0L,0L, ""
+};
+
+#define Pdata_Check(O) ((O)->ob_type == &PdataType)
+
+static PyObject *
+Pdata_New(void)
+{
+	Pdata *self;
+
+	if (!(self = PyObject_New(Pdata, &PdataType)))
+		return NULL;
+	self->size = 8;
+	self->length = 0;
+	self->data = malloc(self->size * sizeof(PyObject*));
+	if (self->data)
+		return (PyObject*)self;
+	Py_DECREF(self);
+	return PyErr_NoMemory();
+}
+
+static int
+stackUnderflow(void)
+{
+	PyErr_SetString(UnpicklingError, "unpickling stack underflow");
+	return -1;
+}
+
+/* Retain only the initial clearto items.  If clearto >= the current
+ * number of items, this is a (non-erroneous) NOP.
+ */
+static int
+Pdata_clear(Pdata *self, int clearto)
+{
+	int i;
+	PyObject **p;
+
+	if (clearto < 0) return stackUnderflow();
+	if (clearto >= self->length) return 0;
+
+	for (i = self->length, p = self->data + clearto;
+	     --i >= clearto;
+	     p++) {
+		Py_CLEAR(*p);
+	}
+	self->length = clearto;
+
+	return 0;
+}
+
+static int
+Pdata_grow(Pdata *self)
+{
+	int bigger;
+	size_t nbytes;
+	PyObject **tmp;
+
+	bigger = self->size << 1;
+	if (bigger <= 0)	/* was 0, or new value overflows */
+		goto nomemory;
+	if ((int)(size_t)bigger != bigger)
+		goto nomemory;
+	nbytes = (size_t)bigger * sizeof(PyObject *);
+	if (nbytes / sizeof(PyObject *) != (size_t)bigger)
+		goto nomemory;
+	tmp = realloc(self->data, nbytes);
+	if (tmp == NULL)
+		goto nomemory;
+	self->data = tmp;
+	self->size = bigger;
+	return 0;
+
+  nomemory:
+	PyErr_NoMemory();
+	return -1;
+}
+
+/* D is a Pdata*.  Pop the topmost element and store it into V, which
+ * must be an lvalue holding PyObject*.  On stack underflow, UnpicklingError
+ * is raised and V is set to NULL.  D and V may be evaluated several times.
+ */
+#define PDATA_POP(D, V) {					\
+	if ((D)->length)					\
+		(V) = (D)->data[--((D)->length)];		\
+	else {							\
+		PyErr_SetString(UnpicklingError, "bad pickle data");	\
+		(V) = NULL;					\
+	}							\
+}
+
+/* PDATA_PUSH and PDATA_APPEND both push rvalue PyObject* O on to Pdata*
+ * D.  If the Pdata stack can't be grown to hold the new value, both
+ * raise MemoryError and execute "return ER".  The difference is in ownership
+ * of O after:  _PUSH transfers ownership of O from the caller to the stack
+ * (no incref of O is done, and in case of error O is decrefed), while
+ * _APPEND pushes a new reference.
+ */
+
+/* Push O on stack D, giving ownership of O to the stack. */
+#define PDATA_PUSH(D, O, ER) {					\
+	if (((Pdata*)(D))->length == ((Pdata*)(D))->size &&	\
+	    Pdata_grow((Pdata*)(D)) < 0) {			\
+		Py_DECREF(O);					\
+		return ER;					\
+	}							\
+	((Pdata*)(D))->data[((Pdata*)(D))->length++] = (O);	\
+}
+
+/* Push O on stack D, pushing a new reference. */
+#define PDATA_APPEND(D, O, ER) {				\
+	if (((Pdata*)(D))->length == ((Pdata*)(D))->size &&	\
+	    Pdata_grow((Pdata*)(D)) < 0)			\
+		return ER;					\
+	Py_INCREF(O);						\
+	((Pdata*)(D))->data[((Pdata*)(D))->length++] = (O);	\
+}
+
+
+static PyObject *
+Pdata_popTuple(Pdata *self, int start)
+{
+	PyObject *r;
+	int i, j, l;
+
+	l = self->length-start;
+	r = PyTuple_New(l);
+	if (r == NULL)
+		return NULL;
+	for (i = start, j = 0 ; j < l; i++, j++)
+		PyTuple_SET_ITEM(r, j, self->data[i]);
+
+	self->length = start;
+	return r;
+}
+
+static PyObject *
+Pdata_popList(Pdata *self, int start)
+{
+	PyObject *r;
+	int i, j, l;
+
+	l=self->length-start;
+	if (!( r=PyList_New(l)))  return NULL;
+	for (i=start, j=0 ; j < l; i++, j++)
+		PyList_SET_ITEM(r, j, self->data[i]);
+
+	self->length=start;
+	return r;
+}
+
+/*************************************************************************/
+
+#define ARG_TUP(self, o) {                          \
+  if (self->arg || (self->arg=PyTuple_New(1))) {    \
+      Py_XDECREF(PyTuple_GET_ITEM(self->arg,0));    \
+      PyTuple_SET_ITEM(self->arg,0,o);              \
+  }                                                 \
+  else {                                            \
+      Py_DECREF(o);                                 \
+  }                                                 \
+}
+
+#define FREE_ARG_TUP(self) {                        \
+    if (self->arg->ob_refcnt > 1) {                 \
+      Py_DECREF(self->arg);                         \
+      self->arg=NULL;                               \
+    }                                               \
+  }
+
+typedef struct Picklerobject {
+	PyObject_HEAD
+	FILE *fp;
+	PyObject *write;
+	PyObject *file;
+	PyObject *memo;
+	PyObject *arg;
+	PyObject *pers_func;
+	PyObject *inst_pers_func;
+
+	/* pickle protocol number, >= 0 */
+	int proto;
+
+	/* bool, true if proto > 0 */
+	int bin;
+
+	int fast; /* Fast mode doesn't save in memo, don't use if circ ref */
+        int nesting;
+	int (*write_func)(struct Picklerobject *, const char *, Py_ssize_t);
+	char *write_buf;
+	int buf_size;
+	PyObject *dispatch_table;
+	int fast_container; /* count nested container dumps */
+	PyObject *fast_memo;
+} Picklerobject;
+
+#ifndef PY_CPICKLE_FAST_LIMIT
+#define PY_CPICKLE_FAST_LIMIT 50
+#endif
+
+static PyTypeObject Picklertype;
+
+typedef struct Unpicklerobject {
+	PyObject_HEAD
+	FILE *fp;
+	PyObject *file;
+	PyObject *readline;
+	PyObject *read;
+	PyObject *memo;
+	PyObject *arg;
+	Pdata *stack;
+	PyObject *mark;
+	PyObject *pers_func;
+	PyObject *last_string;
+	int *marks;
+	int num_marks;
+	int marks_size;
+	Py_ssize_t (*read_func)(struct Unpicklerobject *, char **, Py_ssize_t);
+	Py_ssize_t (*readline_func)(struct Unpicklerobject *, char **);
+	int buf_size;
+	char *buf;
+	PyObject *find_class;
+} Unpicklerobject;
+
+static PyTypeObject Unpicklertype;
+
+/* Forward decls that need the above structs */
+static int save(Picklerobject *, PyObject *, int);
+static int put2(Picklerobject *, PyObject *);
+
+static
+PyObject *
+cPickle_ErrFormat(PyObject *ErrType, char *stringformat, char *format, ...)
+{
+	va_list va;
+	PyObject *args=0, *retval=0;
+	va_start(va, format);
+
+	if (format) args = Py_VaBuildValue(format, va);
+	va_end(va);
+	if (format && ! args) return NULL;
+	if (stringformat && !(retval=PyString_FromString(stringformat)))
+		return NULL;
+
+	if (retval) {
+		if (args) {
+			PyObject *v;
+			v=PyString_Format(retval, args);
+			Py_DECREF(retval);
+			Py_DECREF(args);
+			if (! v) return NULL;
+			retval=v;
+		}
+	}
+	else
+		if (args) retval=args;
+		else {
+			PyErr_SetObject(ErrType,Py_None);
+			return NULL;
+		}
+	PyErr_SetObject(ErrType,retval);
+	Py_DECREF(retval);
+	return NULL;
+}
+
+static int
+write_file(Picklerobject *self, const char *s, Py_ssize_t  n)
+{
+	size_t nbyteswritten;
+
+	if (s == NULL) {
+		return 0;
+	}
+
+	if (n > INT_MAX) {
+		/* String too large */
+		return -1;
+	}
+
+	Py_BEGIN_ALLOW_THREADS
+	nbyteswritten = fwrite(s, sizeof(char), n, self->fp);
+	Py_END_ALLOW_THREADS
+	if (nbyteswritten != (size_t)n) {
+		PyErr_SetFromErrno(PyExc_IOError);
+		return -1;
+	}
+
+	return (int)n;
+}
+
+static int
+write_cStringIO(Picklerobject *self, const char *s, Py_ssize_t  n)
+{
+	if (s == NULL) {
+		return 0;
+	}
+
+	if (PycStringIO->cwrite((PyObject *)self->file, s, n) != n) {
+		return -1;
+	}
+
+	return (int)n;
+}
+
+static int
+write_none(Picklerobject *self, const char *s, Py_ssize_t  n)
+{
+	if (s == NULL) return 0;
+	if (n > INT_MAX) return -1;
+	return (int)n;
+}
+
+static int
+write_other(Picklerobject *self, const char *s, Py_ssize_t  _n)
+{
+	PyObject *py_str = 0, *junk = 0;
+	int n;
+
+	if (_n > INT_MAX)
+		return -1;
+	n = (int)_n;
+	if (s == NULL) {
+		if (!( self->buf_size ))  return 0;
+		py_str = PyString_FromStringAndSize(self->write_buf,
+						    self->buf_size);
+		if (!py_str)
+			return -1;
+	}
+	else {
+		if (self->buf_size && (n + self->buf_size) > WRITE_BUF_SIZE) {
+			if (write_other(self, NULL, 0) < 0)
+				return -1;
+		}
+
+		if (n > WRITE_BUF_SIZE) {
+			if (!( py_str =
+			       PyString_FromStringAndSize(s, n)))
+				return -1;
+		}
+		else {
+			memcpy(self->write_buf + self->buf_size, s, n);
+			self->buf_size += n;
+			return n;
+		}
+	}
+
+	if (self->write) {
+		/* object with write method */
+		ARG_TUP(self, py_str);
+		if (self->arg) {
+			junk = PyObject_Call(self->write, self->arg, NULL);
+			FREE_ARG_TUP(self);
+		}
+		if (junk) Py_DECREF(junk);
+		else return -1;
+	}
+	else
+	    PDATA_PUSH(self->file, py_str, -1);
+
+	self->buf_size = 0;
+	return n;
+}
+
+
+static Py_ssize_t
+read_file(Unpicklerobject *self, char **s, Py_ssize_t n)
+{
+	size_t nbytesread;
+
+	if (self->buf_size == 0) {
+		int size;
+
+		size = ((n < 32) ? 32 : n);
+		if (!( self->buf = (char *)malloc(size))) {
+			PyErr_NoMemory();
+			return -1;
+		}
+
+		self->buf_size = size;
+	}
+	else if (n > self->buf_size) {
+		self->buf = (char *)realloc(self->buf, n);
+		if (!self->buf)  {
+			PyErr_NoMemory();
+			return -1;
+		}
+		self->buf_size = n;
+	}
+
+	Py_BEGIN_ALLOW_THREADS
+	nbytesread = fread(self->buf, sizeof(char), n, self->fp);
+	Py_END_ALLOW_THREADS
+	if (nbytesread != (size_t)n) {
+		if (feof(self->fp)) {
+			PyErr_SetNone(PyExc_EOFError);
+			return -1;
+		}
+
+		PyErr_SetFromErrno(PyExc_IOError);
+		return -1;
+	}
+
+	*s = self->buf;
+
+	return n;
+}
+
+
+static Py_ssize_t
+readline_file(Unpicklerobject *self, char **s)
+{
+	int i;
+
+	if (self->buf_size == 0) {
+		if (!( self->buf = (char *)malloc(40))) {
+			PyErr_NoMemory();
+			return -1;
+		}
+		self->buf_size = 40;
+	}
+
+	i = 0;
+	while (1) {
+		int bigger;
+		for (; i < (self->buf_size - 1); i++) {
+			if (feof(self->fp) ||
+			    (self->buf[i] = getc(self->fp)) == '\n') {
+				self->buf[i + 1] = '\0';
+				*s = self->buf;
+				return i + 1;
+			}
+		}
+		bigger = self->buf_size << 1;
+		if (bigger <= 0) {	/* overflow */
+			PyErr_NoMemory();
+			return -1;
+		}
+		self->buf = (char *)realloc(self->buf, bigger);
+		if (!self->buf)  {
+			PyErr_NoMemory();
+			return -1;
+		}
+		self->buf_size = bigger;
+	}
+}
+
+
+static Py_ssize_t
+read_cStringIO(Unpicklerobject *self, char **s, Py_ssize_t  n)
+{
+	char *ptr;
+
+	if (PycStringIO->cread((PyObject *)self->file, &ptr, n) != n) {
+		PyErr_SetNone(PyExc_EOFError);
+		return -1;
+	}
+
+	*s = ptr;
+
+	return n;
+}
+
+
+static Py_ssize_t
+readline_cStringIO(Unpicklerobject *self, char **s)
+{
+	Py_ssize_t n;
+	char *ptr;
+
+	if ((n = PycStringIO->creadline((PyObject *)self->file, &ptr)) < 0) {
+		return -1;
+	}
+
+	*s = ptr;
+
+	return n;
+}
+
+
+static Py_ssize_t
+read_other(Unpicklerobject *self, char **s, Py_ssize_t  n)
+{
+	PyObject *bytes, *str=0;
+
+	if (!( bytes = PyInt_FromSsize_t(n)))  return -1;
+
+	ARG_TUP(self, bytes);
+	if (self->arg) {
+		str = PyObject_Call(self->read, self->arg, NULL);
+		FREE_ARG_TUP(self);
+	}
+	if (! str) return -1;
+
+	Py_XDECREF(self->last_string);
+	self->last_string = str;
+
+	if (! (*s = PyString_AsString(str))) return -1;
+	return n;
+}
+
+
+static Py_ssize_t
+readline_other(Unpicklerobject *self, char **s)
+{
+	PyObject *str;
+	Py_ssize_t str_size;
+
+	if (!( str = PyObject_CallObject(self->readline, empty_tuple)))  {
+		return -1;
+	}
+
+	if ((str_size = PyString_Size(str)) < 0)
+		return -1;
+
+	Py_XDECREF(self->last_string);
+	self->last_string = str;
+
+	if (! (*s = PyString_AsString(str)))
+		return -1;
+
+	return str_size;
+}
+
+/* Copy the first n bytes from s into newly malloc'ed memory, plus a
+ * trailing 0 byte.  Return a pointer to that, or NULL if out of memory.
+ * The caller is responsible for free()'ing the return value.
+ */
+static char *
+pystrndup(const char *s, int n)
+{
+	char *r = (char *)malloc(n+1);
+	if (r == NULL)
+		return (char*)PyErr_NoMemory();
+	memcpy(r, s, n);
+	r[n] = 0;
+	return r;
+}
+
+
+static int
+get(Picklerobject *self, PyObject *id)
+{
+	PyObject *value, *mv;
+	long c_value;
+	char s[30];
+	size_t len;
+
+	if (!( mv = PyDict_GetItem(self->memo, id)))  {
+		PyErr_SetObject(PyExc_KeyError, id);
+		return -1;
+	}
+
+	if (!( value = PyTuple_GetItem(mv, 0)))
+		return -1;
+
+	if (!( PyInt_Check(value)))  {
+		PyErr_SetString(PicklingError, "no int where int expected in memo");
+		return -1;
+	}
+	c_value = PyInt_AS_LONG((PyIntObject*)value);
+
+	if (!self->bin) {
+		s[0] = GET;
+		PyOS_snprintf(s + 1, sizeof(s) - 1, "%ld\n", c_value);
+		len = strlen(s);
+	}
+	else if (Pdata_Check(self->file)) {
+		if (write_other(self, NULL, 0) < 0) return -1;
+		PDATA_APPEND(self->file, mv, -1);
+		return 0;
+	}
+	else {
+		if (c_value < 256) {
+			s[0] = BINGET;
+			s[1] = (int)(c_value & 0xff);
+			len = 2;
+		}
+		else {
+			s[0] = LONG_BINGET;
+			s[1] = (int)(c_value & 0xff);
+			s[2] = (int)((c_value >> 8)  & 0xff);
+			s[3] = (int)((c_value >> 16) & 0xff);
+			s[4] = (int)((c_value >> 24) & 0xff);
+			len = 5;
+		}
+	}
+
+	if (self->write_func(self, s, len) < 0)
+		return -1;
+
+	return 0;
+}
+
+
+static int
+put(Picklerobject *self, PyObject *ob)
+{
+	if (ob->ob_refcnt < 2 || self->fast)
+		return 0;
+
+	return put2(self, ob);
+}
+
+
+static int
+put2(Picklerobject *self, PyObject *ob)
+{
+	char c_str[30];
+	int p;
+	size_t len;
+	int res = -1;
+	PyObject *py_ob_id = 0, *memo_len = 0, *t = 0;
+
+	if (self->fast)
+		return 0;
+
+	if ((p = PyDict_Size(self->memo)) < 0)
+		goto finally;
+
+	/* Make sure memo keys are positive! */
+	/* XXX Why?
+	 * XXX And does "positive" really mean non-negative?
+	 * XXX pickle.py starts with PUT index 0, not 1.  This makes for
+	 * XXX gratuitous differences between the pickling modules.
+	 */
+	p++;
+
+	if (!( py_ob_id = PyLong_FromVoidPtr(ob)))
+		goto finally;
+
+	if (!( memo_len = PyInt_FromLong(p)))
+		goto finally;
+
+	if (!( t = PyTuple_New(2)))
+		goto finally;
+
+	PyTuple_SET_ITEM(t, 0, memo_len);
+	Py_INCREF(memo_len);
+	PyTuple_SET_ITEM(t, 1, ob);
+	Py_INCREF(ob);
+
+	if (PyDict_SetItem(self->memo, py_ob_id, t) < 0)
+		goto finally;
+
+	if (!self->bin) {
+		c_str[0] = PUT;
+		PyOS_snprintf(c_str + 1, sizeof(c_str) - 1, "%d\n", p);
+		len = strlen(c_str);
+	}
+	else if (Pdata_Check(self->file)) {
+		if (write_other(self, NULL, 0) < 0) return -1;
+		PDATA_APPEND(self->file, memo_len, -1);
+		res=0;          /* Job well done ;) */
+		goto finally;
+	}
+	else {
+		if (p >= 256) {
+			c_str[0] = LONG_BINPUT;
+			c_str[1] = (int)(p & 0xff);
+			c_str[2] = (int)((p >> 8)  & 0xff);
+			c_str[3] = (int)((p >> 16) & 0xff);
+			c_str[4] = (int)((p >> 24) & 0xff);
+			len = 5;
+		}
+		else {
+			c_str[0] = BINPUT;
+			c_str[1] = p;
+			len = 2;
+		}
+	}
+
+	if (self->write_func(self, c_str, len) < 0)
+		goto finally;
+
+	res = 0;
+
+  finally:
+	Py_XDECREF(py_ob_id);
+	Py_XDECREF(memo_len);
+	Py_XDECREF(t);
+
+	return res;
+}
+
+static PyObject *
+whichmodule(PyObject *global, PyObject *global_name)
+{
+	Py_ssize_t i, j;
+	PyObject *module = 0, *modules_dict = 0,
+		*global_name_attr = 0, *name = 0;
+
+	module = PyObject_GetAttrString(global, "__module__");
+	if (module) 
+		return module;
+	if (PyErr_ExceptionMatches(PyExc_AttributeError))
+		PyErr_Clear();
+	else
+		return NULL;
+
+	if (!( modules_dict = PySys_GetObject("modules")))
+		return NULL;
+
+	i = 0;
+	while ((j = PyDict_Next(modules_dict, &i, &name, &module))) {
+
+		if (PyObject_Compare(name, __main___str)==0) continue;
+
+		global_name_attr = PyObject_GetAttr(module, global_name);
+		if (!global_name_attr)  {
+			if (PyErr_ExceptionMatches(PyExc_AttributeError))
+				PyErr_Clear();
+			else
+				return NULL;
+			continue;
+		}
+
+		if (global_name_attr != global) {
+			Py_DECREF(global_name_attr);
+			continue;
+		}
+
+		Py_DECREF(global_name_attr);
+
+		break;
+	}
+
+	/* The following implements the rule in pickle.py added in 1.5
+	   that used __main__ if no module is found.  I don't actually
+	   like this rule. jlf
+	*/
+	if (!j) {
+		j=1;
+		name=__main___str;
+	}
+
+	Py_INCREF(name);
+	return name;
+}
+
+
+static int
+fast_save_enter(Picklerobject *self, PyObject *obj)
+{
+	/* if fast_container < 0, we're doing an error exit. */
+	if (++self->fast_container >= PY_CPICKLE_FAST_LIMIT) {
+		PyObject *key = NULL;
+		if (self->fast_memo == NULL) {
+			self->fast_memo = PyDict_New();
+			if (self->fast_memo == NULL) {
+				self->fast_container = -1;
+				return 0;
+			}
+		}
+		key = PyLong_FromVoidPtr(obj);
+		if (key == NULL)
+			return 0;
+		if (PyDict_GetItem(self->fast_memo, key)) {
+			Py_DECREF(key);
+			PyErr_Format(PyExc_ValueError,
+				     "fast mode: can't pickle cyclic objects "
+				     "including object type %s at %p",
+				     obj->ob_type->tp_name, obj);
+			self->fast_container = -1;
+			return 0;
+		}
+		if (PyDict_SetItem(self->fast_memo, key, Py_None) < 0) {
+			Py_DECREF(key);
+			self->fast_container = -1;
+			return 0;
+		}
+		Py_DECREF(key);
+	}
+	return 1;
+}
+
+int
+fast_save_leave(Picklerobject *self, PyObject *obj)
+{
+	if (self->fast_container-- >= PY_CPICKLE_FAST_LIMIT) {
+		PyObject *key = PyLong_FromVoidPtr(obj);
+		if (key == NULL)
+			return 0;
+		if (PyDict_DelItem(self->fast_memo, key) < 0) {
+			Py_DECREF(key);
+			return 0;
+		}
+		Py_DECREF(key);
+	}
+	return 1;
+}
+
+static int
+save_none(Picklerobject *self, PyObject *args)
+{
+	static char none = NONE;
+	if (self->write_func(self, &none, 1) < 0)
+		return -1;
+
+	return 0;
+}
+
+static int
+save_bool(Picklerobject *self, PyObject *args)
+{
+	static const char *buf[2] = {FALSE, TRUE};
+	static char len[2] = {sizeof(FALSE)-1, sizeof(TRUE)-1};
+	long l = PyInt_AS_LONG((PyIntObject *)args);
+
+	if (self->proto >= 2) {
+		char opcode = l ? NEWTRUE : NEWFALSE;
+		if (self->write_func(self, &opcode, 1) < 0)
+			return -1;
+	}
+	else if (self->write_func(self, buf[l], len[l]) < 0)
+		return -1;
+	return 0;
+}
+
+static int
+save_int(Picklerobject *self, PyObject *args)
+{
+	char c_str[32];
+	long l = PyInt_AS_LONG((PyIntObject *)args);
+	int len = 0;
+
+	if (!self->bin
+#if SIZEOF_LONG > 4
+	    || l >  0x7fffffffL
+	    || l < -0x80000000L
+#endif
+		) {
+		/* Text-mode pickle, or long too big to fit in the 4-byte
+		 * signed BININT format:  store as a string.
+		 */
+		c_str[0] = INT;
+		PyOS_snprintf(c_str + 1, sizeof(c_str) - 1, "%ld\n", l);
+		if (self->write_func(self, c_str, strlen(c_str)) < 0)
+			return -1;
+	}
+	else {
+		/* Binary pickle and l fits in a signed 4-byte int. */
+		c_str[1] = (int)( l        & 0xff);
+		c_str[2] = (int)((l >> 8)  & 0xff);
+		c_str[3] = (int)((l >> 16) & 0xff);
+		c_str[4] = (int)((l >> 24) & 0xff);
+
+		if ((c_str[4] == 0) && (c_str[3] == 0)) {
+			if (c_str[2] == 0) {
+				c_str[0] = BININT1;
+				len = 2;
+			}
+			else {
+				c_str[0] = BININT2;
+				len = 3;
+			}
+		}
+		else {
+			c_str[0] = BININT;
+			len = 5;
+		}
+
+		if (self->write_func(self, c_str, len) < 0)
+			return -1;
+	}
+
+	return 0;
+}
+
+
+static int
+save_long(Picklerobject *self, PyObject *args)
+{
+	Py_ssize_t size;
+	int res = -1;
+	PyObject *repr = NULL;
+
+	static char l = LONG;
+
+	if (self->proto >= 2) {
+		/* Linear-time pickling. */
+		size_t nbits;
+		size_t nbytes;
+		unsigned char *pdata;
+		char c_str[5];
+		int i;
+		int sign = _PyLong_Sign(args);
+
+		if (sign == 0) {
+			/* It's 0 -- an empty bytestring. */
+			c_str[0] = LONG1;
+			c_str[1] = 0;
+			i = self->write_func(self, c_str, 2);
+			if (i < 0) goto finally;
+			res = 0;
+			goto finally;
+		}
+		nbits = _PyLong_NumBits(args);
+		if (nbits == (size_t)-1 && PyErr_Occurred())
+			goto finally;
+		/* How many bytes do we need?  There are nbits >> 3 full
+		 * bytes of data, and nbits & 7 leftover bits.  If there
+		 * are any leftover bits, then we clearly need another
+		 * byte.  Wnat's not so obvious is that we *probably*
+		 * need another byte even if there aren't any leftovers:
+		 * the most-significant bit of the most-significant byte
+		 * acts like a sign bit, and it's usually got a sense
+		 * opposite of the one we need.  The exception is longs
+		 * of the form -(2**(8*j-1)) for j > 0.  Such a long is
+		 * its own 256's-complement, so has the right sign bit
+		 * even without the extra byte.  That's a pain to check
+		 * for in advance, though, so we always grab an extra
+		 * byte at the start, and cut it back later if possible.
+		 */
+		nbytes = (nbits >> 3) + 1;
+		if (nbytes > INT_MAX) {
+			PyErr_SetString(PyExc_OverflowError, "long too large "
+				"to pickle");
+			goto finally;
+		}
+		repr = PyString_FromStringAndSize(NULL, (int)nbytes);
+		if (repr == NULL) goto finally;
+		pdata = (unsigned char *)PyString_AS_STRING(repr);
+		i = _PyLong_AsByteArray((PyLongObject *)args,
+	 			pdata, nbytes,
+				1 /* little endian */, 1 /* signed */);
+		if (i < 0) goto finally;
+		/* If the long is negative, this may be a byte more than
+		 * needed.  This is so iff the MSB is all redundant sign
+		 * bits.
+		 */
+		if (sign < 0 && nbytes > 1 && pdata[nbytes - 1] == 0xff &&
+		    (pdata[nbytes - 2] & 0x80) != 0)
+			--nbytes;
+
+		if (nbytes < 256) {
+			c_str[0] = LONG1;
+			c_str[1] = (char)nbytes;
+			size = 2;
+		}
+		else {
+			c_str[0] = LONG4;
+			size = (int)nbytes;
+			for (i = 1; i < 5; i++) {
+				c_str[i] = (char)(size & 0xff);
+				size >>= 8;
+			}
+			size = 5;
+		}
+		i = self->write_func(self, c_str, size);
+		if (i < 0) goto finally;
+		i = self->write_func(self, (char *)pdata, (int)nbytes);
+		if (i < 0) goto finally;
+		res = 0;
+		goto finally;
+	}
+
+	/* proto < 2:  write the repr and newline.  This is quadratic-time
+	 * (in the number of digits), in both directions.
+	 */
+	if (!( repr = PyObject_Repr(args)))
+		goto finally;
+
+	if ((size = PyString_Size(repr)) < 0)
+		goto finally;
+
+	if (self->write_func(self, &l, 1) < 0)
+		goto finally;
+
+	if (self->write_func(self,
+			     PyString_AS_STRING((PyStringObject *)repr),
+			     			size) < 0)
+		goto finally;
+
+	if (self->write_func(self, "\n", 1) < 0)
+		goto finally;
+
+	res = 0;
+
+  finally:
+	Py_XDECREF(repr);
+	return res;
+}
+
+
+static int
+save_float(Picklerobject *self, PyObject *args)
+{
+	double x = PyFloat_AS_DOUBLE((PyFloatObject *)args);
+
+	if (self->bin) {
+		char str[9];
+		str[0] = BINFLOAT;
+		if (_PyFloat_Pack8(x, (unsigned char *)&str[1], 0) < 0)
+			return -1;
+		if (self->write_func(self, str, 9) < 0)
+			return -1;
+	}
+	else {
+		char c_str[250];
+		c_str[0] = FLOAT;
+		PyOS_ascii_formatd(c_str + 1, sizeof(c_str) - 2, "%.17g", x);
+		/* Extend the formatted string with a newline character */
+		strcat(c_str, "\n");
+
+		if (self->write_func(self, c_str, strlen(c_str)) < 0)
+			return -1;
+	}
+
+	return 0;
+}
+
+
+static int
+save_string(Picklerobject *self, PyObject *args, int doput)
+{
+	int size, len;
+	PyObject *repr=0;
+
+	if ((size = PyString_Size(args)) < 0)
+		return -1;
+
+	if (!self->bin) {
+		char *repr_str;
+
+		static char string = STRING;
+
+		if (!( repr = PyObject_Repr(args)))
+			return -1;
+
+		if ((len = PyString_Size(repr)) < 0)
+			goto err;
+		repr_str = PyString_AS_STRING((PyStringObject *)repr);
+
+		if (self->write_func(self, &string, 1) < 0)
+			goto err;
+
+		if (self->write_func(self, repr_str, len) < 0)
+			goto err;
+
+		if (self->write_func(self, "\n", 1) < 0)
+			goto err;
+
+		Py_XDECREF(repr);
+	}
+	else {
+		int i;
+		char c_str[5];
+
+		if ((size = PyString_Size(args)) < 0)
+			return -1;
+
+		if (size < 256) {
+			c_str[0] = SHORT_BINSTRING;
+			c_str[1] = size;
+			len = 2;
+		}
+		else if (size <= INT_MAX) {
+			c_str[0] = BINSTRING;
+			for (i = 1; i < 5; i++)
+				c_str[i] = (int)(size >> ((i - 1) * 8));
+			len = 5;
+		}
+		else
+			return -1;    /* string too large */
+
+		if (self->write_func(self, c_str, len) < 0)
+			return -1;
+
+		if (size > 128 && Pdata_Check(self->file)) {
+			if (write_other(self, NULL, 0) < 0) return -1;
+			PDATA_APPEND(self->file, args, -1);
+		}
+		else {
+			if (self->write_func(self,
+					     PyString_AS_STRING(
+					     	(PyStringObject *)args),
+					     size) < 0)
+				return -1;
+		}
+	}
+
+	if (doput)
+		if (put(self, args) < 0)
+			return -1;
+
+	return 0;
+
+  err:
+	Py_XDECREF(repr);
+	return -1;
+}
+
+
+#ifdef Py_USING_UNICODE
+/* A copy of PyUnicode_EncodeRawUnicodeEscape() that also translates
+   backslash and newline characters to \uXXXX escapes. */
+static PyObject *
+modified_EncodeRawUnicodeEscape(const Py_UNICODE *s, int size)
+{
+	PyObject *repr;
+	char *p;
+	char *q;
+
+	static const char *hexdigit = "0123456789ABCDEF";
+
+	repr = PyString_FromStringAndSize(NULL, 6 * size);
+	if (repr == NULL)
+		return NULL;
+	if (size == 0)
+		return repr;
+
+	p = q = PyString_AS_STRING(repr);
+	while (size-- > 0) {
+		Py_UNICODE ch = *s++;
+		/* Map 16-bit characters to '\uxxxx' */
+		if (ch >= 256 || ch == '\\' || ch == '\n') {
+			*p++ = '\\';
+			*p++ = 'u';
+			*p++ = hexdigit[(ch >> 12) & 0xf];
+			*p++ = hexdigit[(ch >> 8) & 0xf];
+			*p++ = hexdigit[(ch >> 4) & 0xf];
+			*p++ = hexdigit[ch & 15];
+		}
+		/* Copy everything else as-is */
+		else
+			*p++ = (char) ch;
+	}
+	*p = '\0';
+	_PyString_Resize(&repr, p - q);
+	return repr;
+}
+
+
+static int
+save_unicode(Picklerobject *self, PyObject *args, int doput)
+{
+	Py_ssize_t size, len;
+	PyObject *repr=0;
+
+	if (!PyUnicode_Check(args))
+		return -1;
+
+	if (!self->bin) {
+		char *repr_str;
+		static char string = UNICODE;
+
+		repr = modified_EncodeRawUnicodeEscape(
+			PyUnicode_AS_UNICODE(args), PyUnicode_GET_SIZE(args));
+		if (!repr)
+			return -1;
+
+		if ((len = PyString_Size(repr)) < 0)
+			goto err;
+		repr_str = PyString_AS_STRING((PyStringObject *)repr);
+
+		if (self->write_func(self, &string, 1) < 0)
+			goto err;
+
+		if (self->write_func(self, repr_str, len) < 0)
+			goto err;
+
+		if (self->write_func(self, "\n", 1) < 0)
+			goto err;
+
+		Py_XDECREF(repr);
+	}
+	else {
+		int i;
+		char c_str[5];
+
+		if (!( repr = PyUnicode_AsUTF8String(args)))
+			return -1;
+
+		if ((size = PyString_Size(repr)) < 0)
+			goto err;
+		if (size > INT_MAX)
+			return -1;   /* string too large */
+
+		c_str[0] = BINUNICODE;
+		for (i = 1; i < 5; i++)
+			c_str[i] = (int)(size >> ((i - 1) * 8));
+		len = 5;
+
+		if (self->write_func(self, c_str, len) < 0)
+			goto err;
+
+		if (size > 128 && Pdata_Check(self->file)) {
+			if (write_other(self, NULL, 0) < 0)
+				goto err;
+			PDATA_APPEND(self->file, repr, -1);
+		}
+		else {
+			if (self->write_func(self, PyString_AS_STRING(repr),
+					     size) < 0)
+				goto err;
+		}
+
+		Py_DECREF(repr);
+	}
+
+	if (doput)
+		if (put(self, args) < 0)
+			return -1;
+
+	return 0;
+
+  err:
+	Py_XDECREF(repr);
+	return -1;
+}
+#endif
+
+/* A helper for save_tuple.  Push the len elements in tuple t on the stack. */
+static int
+store_tuple_elements(Picklerobject *self, PyObject *t, int len)
+{
+	int i;
+	int res = -1;	/* guilty until proved innocent */
+
+	assert(PyTuple_Size(t) == len);
+
+	for (i = 0; i < len; i++) {
+		PyObject *element = PyTuple_GET_ITEM(t, i);
+
+		if (element == NULL)
+			goto finally;
+		if (save(self, element, 0) < 0)
+			goto finally;
+	}
+	res = 0;
+
+  finally:
+	return res;
+}
+
+/* Tuples are ubiquitous in the pickle protocols, so many techniques are
+ * used across protocols to minimize the space needed to pickle them.
+ * Tuples are also the only builtin immutable type that can be recursive
+ * (a tuple can be reached from itself), and that requires some subtle
+ * magic so that it works in all cases.  IOW, this is a long routine.
+ */
+static int
+save_tuple(Picklerobject *self, PyObject *args)
+{
+	PyObject *py_tuple_id = NULL;
+	int len, i;
+	int res = -1;
+
+	static char tuple = TUPLE;
+	static char pop = POP;
+	static char pop_mark = POP_MARK;
+	static char len2opcode[] = {EMPTY_TUPLE, TUPLE1, TUPLE2, TUPLE3};
+
+	if ((len = PyTuple_Size(args)) < 0)
+		goto finally;
+
+	if (len == 0) {
+		char c_str[2];
+
+		if (self->proto) {
+			c_str[0] = EMPTY_TUPLE;
+			len = 1;
+		}
+		else {
+			c_str[0] = MARK;
+			c_str[1] = TUPLE;
+			len = 2;
+		}
+		if (self->write_func(self, c_str, len) >= 0)
+			res = 0;
+		/* Don't memoize an empty tuple. */
+		goto finally;
+	}
+
+	/* A non-empty tuple. */
+
+	/* id(tuple) isn't in the memo now.  If it shows up there after
+	 * saving the tuple elements, the tuple must be recursive, in
+	 * which case we'll pop everything we put on the stack, and fetch
+	 * its value from the memo.
+	 */
+	py_tuple_id = PyLong_FromVoidPtr(args);
+	if (py_tuple_id == NULL)
+		goto finally;
+
+	if (len <= 3 && self->proto >= 2) {
+		/* Use TUPLE{1,2,3} opcodes. */
+		if (store_tuple_elements(self, args, len) < 0)
+			goto finally;
+		if (PyDict_GetItem(self->memo, py_tuple_id)) {
+			/* pop the len elements */
+			for (i = 0; i < len; ++i)
+				if (self->write_func(self, &pop, 1) < 0)
+					goto finally;
+			/* fetch from memo */
+			if (get(self, py_tuple_id) < 0)
+				goto finally;
+			res = 0;
+			goto finally;
+		}
+		/* Not recursive. */
+		if (self->write_func(self, len2opcode + len, 1) < 0)
+			goto finally;
+		goto memoize;
+	}
+
+	/* proto < 2 and len > 0, or proto >= 2 and len > 3.
+	 * Generate MARK elt1 elt2 ... TUPLE
+	 */
+	if (self->write_func(self, &MARKv, 1) < 0)
+		goto finally;
+
+	if (store_tuple_elements(self, args, len) < 0)
+		goto finally;
+
+	if (PyDict_GetItem(self->memo, py_tuple_id)) {
+		/* pop the stack stuff we pushed */
+		if (self->bin) {
+			if (self->write_func(self, &pop_mark, 1) < 0)
+				goto finally;
+		}
+		else {
+			/* Note that we pop one more than len, to remove
+			 * the MARK too.
+			 */
+			for (i = 0; i <= len; i++)
+				if (self->write_func(self, &pop, 1) < 0)
+					goto finally;
+		}
+		/* fetch from memo */
+		if (get(self, py_tuple_id) >= 0)
+			res = 0;
+		goto finally;
+	}
+
+	/* Not recursive. */
+	if (self->write_func(self, &tuple, 1) < 0)
+		goto finally;
+
+  memoize:
+	if (put(self, args) >= 0)
+		res = 0;
+
+  finally:
+	Py_XDECREF(py_tuple_id);
+	return res;
+}
+
+/* iter is an iterator giving items, and we batch up chunks of
+ *     MARK item item ... item APPENDS
+ * opcode sequences.  Calling code should have arranged to first create an
+ * empty list, or list-like object, for the APPENDS to operate on.
+ * Returns 0 on success, <0 on error.
+ */
+static int
+batch_list(Picklerobject *self, PyObject *iter)
+{
+	PyObject *obj;
+	PyObject *slice[BATCHSIZE];
+	int i, n;
+
+	static char append = APPEND;
+	static char appends = APPENDS;
+
+	assert(iter != NULL);
+
+	if (self->proto == 0) {
+		/* APPENDS isn't available; do one at a time. */
+		for (;;) {
+			obj = PyIter_Next(iter);
+			if (obj == NULL) {
+				if (PyErr_Occurred())
+					return -1;
+				break;
+			}
+			i = save(self, obj, 0);
+			Py_DECREF(obj);
+			if (i < 0)
+				return -1;
+			if (self->write_func(self, &append, 1) < 0)
+				return -1;
+		}
+		return 0;
+	}
+
+	/* proto > 0:  write in batches of BATCHSIZE. */
+	do {
+		/* Get next group of (no more than) BATCHSIZE elements. */
+		for (n = 0; n < BATCHSIZE; ++n) {
+			obj = PyIter_Next(iter);
+			if (obj == NULL) {
+				if (PyErr_Occurred())
+					goto BatchFailed;
+				break;
+			}
+			slice[n] = obj;
+		}
+
+		if (n > 1) {
+			/* Pump out MARK, slice[0:n], APPENDS. */
+			if (self->write_func(self, &MARKv, 1) < 0)
+				goto BatchFailed;
+			for (i = 0; i < n; ++i) {
+				if (save(self, slice[i], 0) < 0)
+					goto BatchFailed;
+			}
+			if (self->write_func(self, &appends, 1) < 0)
+				goto BatchFailed;
+		}
+		else if (n == 1) {
+			if (save(self, slice[0], 0) < 0)
+				goto BatchFailed;
+			if (self->write_func(self, &append, 1) < 0)
+				goto BatchFailed;
+		}
+
+		for (i = 0; i < n; ++i) {
+			Py_DECREF(slice[i]);
+		}
+	} while (n == BATCHSIZE);
+	return 0;
+
+BatchFailed:
+	while (--n >= 0) {
+		Py_DECREF(slice[n]);
+	}
+	return -1;
+}
+
+static int
+save_list(Picklerobject *self, PyObject *args)
+{
+	int res = -1;
+	char s[3];
+	int len;
+	PyObject *iter;
+
+	if (self->fast && !fast_save_enter(self, args))
+		goto finally;
+
+	/* Create an empty list. */
+	if (self->bin) {
+		s[0] = EMPTY_LIST;
+		len = 1;
+	}
+	else {
+		s[0] = MARK;
+		s[1] = LIST;
+		len = 2;
+	}
+
+	if (self->write_func(self, s, len) < 0)
+		goto finally;
+
+	/* Get list length, and bow out early if empty. */
+	if ((len = PyList_Size(args)) < 0)
+		goto finally;
+
+	/* Memoize. */
+	if (len == 0) {
+		if (put(self, args) >= 0)
+			res = 0;
+		goto finally;
+	}
+	if (put2(self, args) < 0)
+		goto finally;
+
+	/* Materialize the list elements. */
+	iter = PyObject_GetIter(args);
+	if (iter == NULL)
+		goto finally;
+	res = batch_list(self, iter);
+	Py_DECREF(iter);
+
+  finally:
+	if (self->fast && !fast_save_leave(self, args))
+		res = -1;
+
+	return res;
+}
+
+
+/* iter is an iterator giving (key, value) pairs, and we batch up chunks of
+ *     MARK key value ... key value SETITEMS
+ * opcode sequences.  Calling code should have arranged to first create an
+ * empty dict, or dict-like object, for the SETITEMS to operate on.
+ * Returns 0 on success, <0 on error.
+ *
+ * This is very much like batch_list().  The difference between saving
+ * elements directly, and picking apart two-tuples, is so long-winded at
+ * the C level, though, that attempts to combine these routines were too
+ * ugly to bear.
+ */
+static int
+batch_dict(Picklerobject *self, PyObject *iter)
+{
+	PyObject *p;
+	PyObject *slice[BATCHSIZE];
+	int i, n;
+
+	static char setitem = SETITEM;
+	static char setitems = SETITEMS;
+
+	assert(iter != NULL);
+
+	if (self->proto == 0) {
+		/* SETITEMS isn't available; do one at a time. */
+		for (;;) {
+			p = PyIter_Next(iter);
+			if (p == NULL) {
+				if (PyErr_Occurred())
+					return -1;
+				break;
+			}
+			if (!PyTuple_Check(p) || PyTuple_Size(p) != 2) {
+				PyErr_SetString(PyExc_TypeError, "dict items "
+					"iterator must return 2-tuples");
+				return -1;
+			}
+			i = save(self, PyTuple_GET_ITEM(p, 0), 0);
+			if (i >= 0)
+				i = save(self, PyTuple_GET_ITEM(p, 1), 0);
+			Py_DECREF(p);
+			if (i < 0)
+				return -1;
+			if (self->write_func(self, &setitem, 1) < 0)
+				return -1;
+		}
+		return 0;
+	}
+
+	/* proto > 0:  write in batches of BATCHSIZE. */
+	do {
+		/* Get next group of (no more than) BATCHSIZE elements. */
+		for (n = 0; n < BATCHSIZE; ++n) {
+			p = PyIter_Next(iter);
+			if (p == NULL) {
+				if (PyErr_Occurred())
+					goto BatchFailed;
+				break;
+			}
+			if (!PyTuple_Check(p) || PyTuple_Size(p) != 2) {
+				PyErr_SetString(PyExc_TypeError, "dict items "
+					"iterator must return 2-tuples");
+				goto BatchFailed;
+			}
+			slice[n] = p;
+		}
+
+		if (n > 1) {
+			/* Pump out MARK, slice[0:n], SETITEMS. */
+			if (self->write_func(self, &MARKv, 1) < 0)
+				goto BatchFailed;
+			for (i = 0; i < n; ++i) {
+				p = slice[i];
+				if (save(self, PyTuple_GET_ITEM(p, 0), 0) < 0)
+					goto BatchFailed;
+				if (save(self, PyTuple_GET_ITEM(p, 1), 0) < 0)
+					goto BatchFailed;
+			}
+			if (self->write_func(self, &setitems, 1) < 0)
+				goto BatchFailed;
+		}
+		else if (n == 1) {
+			p = slice[0];
+			if (save(self, PyTuple_GET_ITEM(p, 0), 0) < 0)
+				goto BatchFailed;
+			if (save(self, PyTuple_GET_ITEM(p, 1), 0) < 0)
+				goto BatchFailed;
+			if (self->write_func(self, &setitem, 1) < 0)
+				goto BatchFailed;
+		}
+
+		for (i = 0; i < n; ++i) {
+			Py_DECREF(slice[i]);
+		}
+	} while (n == BATCHSIZE);
+	return 0;
+
+BatchFailed:
+	while (--n >= 0) {
+		Py_DECREF(slice[n]);
+	}
+	return -1;
+}
+
+static int
+save_dict(Picklerobject *self, PyObject *args)
+{
+	int res = -1;
+	char s[3];
+	int len;
+	PyObject *iter;
+
+	if (self->fast && !fast_save_enter(self, args))
+		goto finally;
+
+	/* Create an empty dict. */
+	if (self->bin) {
+		s[0] = EMPTY_DICT;
+		len = 1;
+	}
+	else {
+		s[0] = MARK;
+		s[1] = DICT;
+		len = 2;
+	}
+
+	if (self->write_func(self, s, len) < 0)
+		goto finally;
+
+	/* Get dict size, and bow out early if empty. */
+	if ((len = PyDict_Size(args)) < 0)
+		goto finally;
+
+	if (len == 0) {
+		if (put(self, args) >= 0)
+			res = 0;
+		goto finally;
+	}
+	if (put2(self, args) < 0)
+		goto finally;
+
+	/* Materialize the dict items. */
+	iter = PyObject_CallMethod(args, "iteritems", "()");
+	if (iter == NULL)
+		goto finally;
+	res = batch_dict(self, iter);
+	Py_DECREF(iter);
+
+  finally:
+	if (self->fast && !fast_save_leave(self, args))
+		res = -1;
+
+	return res;
+}
+
+
+static int
+save_inst(Picklerobject *self, PyObject *args)
+{
+	PyObject *class = 0, *module = 0, *name = 0, *state = 0,
+		*getinitargs_func = 0, *getstate_func = 0, *class_args = 0;
+	char *module_str, *name_str;
+	int module_size, name_size, res = -1;
+
+	static char inst = INST, obj = OBJ, build = BUILD;
+
+	if (self->fast && !fast_save_enter(self, args))
+		goto finally;
+
+	if (self->write_func(self, &MARKv, 1) < 0)
+		goto finally;
+
+	if (!( class = PyObject_GetAttr(args, __class___str)))
+		goto finally;
+
+	if (self->bin) {
+		if (save(self, class, 0) < 0)
+			goto finally;
+	}
+
+	if ((getinitargs_func = PyObject_GetAttr(args, __getinitargs___str))) {
+		PyObject *element = 0;
+		int i, len;
+
+		if (!( class_args =
+		       PyObject_Call(getinitargs_func, empty_tuple, NULL)))
+			goto finally;
+
+		if ((len = PyObject_Size(class_args)) < 0)
+			goto finally;
+
+		for (i = 0; i < len; i++) {
+			if (!( element = PySequence_GetItem(class_args, i)))
+				goto finally;
+
+			if (save(self, element, 0) < 0) {
+				Py_DECREF(element);
+				goto finally;
+			}
+
+			Py_DECREF(element);
+		}
+	}
+	else {
+		if (PyErr_ExceptionMatches(PyExc_AttributeError))
+			PyErr_Clear();
+		else
+			goto finally;
+	}
+
+	if (!self->bin) {
+		if (!( name = ((PyClassObject *)class)->cl_name ))  {
+			PyErr_SetString(PicklingError, "class has no name");
+			goto finally;
+		}
+
+		if (!( module = whichmodule(class, name)))
+			goto finally;
+
+
+		if ((module_size = PyString_Size(module)) < 0 ||
+		    (name_size = PyString_Size(name)) < 0)
+			goto finally;
+
+		module_str = PyString_AS_STRING((PyStringObject *)module);
+		name_str   = PyString_AS_STRING((PyStringObject *)name);
+
+		if (self->write_func(self, &inst, 1) < 0)
+			goto finally;
+
+		if (self->write_func(self, module_str, module_size) < 0)
+			goto finally;
+
+		if (self->write_func(self, "\n", 1) < 0)
+			goto finally;
+
+		if (self->write_func(self, name_str, name_size) < 0)
+			goto finally;
+
+		if (self->write_func(self, "\n", 1) < 0)
+			goto finally;
+	}
+	else if (self->write_func(self, &obj, 1) < 0) {
+		goto finally;
+	}
+
+	if ((getstate_func = PyObject_GetAttr(args, __getstate___str))) {
+		state = PyObject_Call(getstate_func, empty_tuple, NULL);
+		if (!state)
+			goto finally;
+	}
+	else {
+		if (PyErr_ExceptionMatches(PyExc_AttributeError))
+			PyErr_Clear();
+		else
+			goto finally;
+
+		if (!( state = PyObject_GetAttr(args, __dict___str)))  {
+			if (PyErr_ExceptionMatches(PyExc_AttributeError))
+				PyErr_Clear();
+			else
+				goto finally;
+			res = 0;
+			goto finally;
+		}
+	}
+
+	if (!PyDict_Check(state)) {
+		if (put2(self, args) < 0)
+			goto finally;
+	}
+	else {
+		if (put(self, args) < 0)
+			goto finally;
+	}
+
+	if (save(self, state, 0) < 0)
+		goto finally;
+
+	if (self->write_func(self, &build, 1) < 0)
+		goto finally;
+
+	res = 0;
+
+  finally:
+	if (self->fast && !fast_save_leave(self, args))
+		res = -1;
+
+	Py_XDECREF(module);
+	Py_XDECREF(class);
+	Py_XDECREF(state);
+	Py_XDECREF(getinitargs_func);
+	Py_XDECREF(getstate_func);
+	Py_XDECREF(class_args);
+
+	return res;
+}
+
+
+static int
+save_global(Picklerobject *self, PyObject *args, PyObject *name)
+{
+	PyObject *global_name = 0, *module = 0, *mod = 0, *klass = 0;
+	char *name_str, *module_str;
+	int module_size, name_size, res = -1;
+
+	static char global = GLOBAL;
+
+	if (name) {
+		global_name = name;
+		Py_INCREF(global_name);
+	}
+	else {
+		if (!( global_name = PyObject_GetAttr(args, __name___str)))
+			goto finally;
+	}
+
+	if (!( module = whichmodule(args, global_name)))
+		goto finally;
+
+	if ((module_size = PyString_Size(module)) < 0 ||
+	    (name_size = PyString_Size(global_name)) < 0)
+		goto finally;
+
+	module_str = PyString_AS_STRING((PyStringObject *)module);
+	name_str   = PyString_AS_STRING((PyStringObject *)global_name);
+
+	/* XXX This can be doing a relative import.  Clearly it shouldn't,
+	   but I don't know how to stop it. :-( */
+	mod = PyImport_ImportModule(module_str);
+	if (mod == NULL) {
+		cPickle_ErrFormat(PicklingError,
+				  "Can't pickle %s: import of module %s "
+				  "failed",
+				  "OS", args, module);
+		goto finally;
+	}
+	klass = PyObject_GetAttrString(mod, name_str);
+	if (klass == NULL) {
+		cPickle_ErrFormat(PicklingError,
+				  "Can't pickle %s: attribute lookup %s.%s "
+				  "failed",
+				  "OSS", args, module, global_name);
+		goto finally;
+	}
+	if (klass != args) {
+		Py_DECREF(klass);
+		cPickle_ErrFormat(PicklingError,
+				  "Can't pickle %s: it's not the same object "
+				  	"as %s.%s",
+				  "OSS", args, module, global_name);
+		goto finally;
+	}
+	Py_DECREF(klass);
+
+	if (self->proto >= 2) {
+		/* See whether this is in the extension registry, and if
+		 * so generate an EXT opcode.
+		 */
+		PyObject *py_code;	/* extension code as Python object */
+		long code;		/* extension code as C value */
+		char c_str[5];
+		int n;
+
+		PyTuple_SET_ITEM(two_tuple, 0, module);
+		PyTuple_SET_ITEM(two_tuple, 1, global_name);
+		py_code = PyDict_GetItem(extension_registry, two_tuple);
+		if (py_code == NULL)
+			goto gen_global;	/* not registered */
+
+		/* Verify py_code has the right type and value. */
+		if (!PyInt_Check(py_code)) {
+			cPickle_ErrFormat(PicklingError, "Can't pickle %s: "
+				"extension code %s isn't an integer",
+				"OO", args, py_code);
+			goto finally;
+		}
+		code = PyInt_AS_LONG(py_code);
+		if (code <= 0 ||  code > 0x7fffffffL) {
+			cPickle_ErrFormat(PicklingError, "Can't pickle %s: "
+				"extension code %ld is out of range",
+				"Ol", args, code);
+			goto finally;
+		}
+
+		/* Generate an EXT opcode. */
+		if (code <= 0xff) {
+			c_str[0] = EXT1;
+			c_str[1] = (char)code;
+			n = 2;
+		}
+		else if (code <= 0xffff) {
+			c_str[0] = EXT2;
+			c_str[1] = (char)(code & 0xff);
+			c_str[2] = (char)((code >> 8) & 0xff);
+			n = 3;
+		}
+		else {
+			c_str[0] = EXT4;
+			c_str[1] = (char)(code & 0xff);
+			c_str[2] = (char)((code >> 8) & 0xff);
+			c_str[3] = (char)((code >> 16) & 0xff);
+			c_str[4] = (char)((code >> 24) & 0xff);
+			n = 5;
+		}
+
+		if (self->write_func(self, c_str, n) >= 0)
+			res = 0;
+		goto finally;	/* and don't memoize */
+	}
+
+  gen_global:
+	if (self->write_func(self, &global, 1) < 0)
+		goto finally;
+
+	if (self->write_func(self, module_str, module_size) < 0)
+		goto finally;
+
+	if (self->write_func(self, "\n", 1) < 0)
+		goto finally;
+
+	if (self->write_func(self, name_str, name_size) < 0)
+		goto finally;
+
+	if (self->write_func(self, "\n", 1) < 0)
+		goto finally;
+
+	if (put(self, args) < 0)
+		goto finally;
+
+	res = 0;
+
+  finally:
+	Py_XDECREF(module);
+	Py_XDECREF(global_name);
+	Py_XDECREF(mod);
+
+	return res;
+}
+
+static int
+save_pers(Picklerobject *self, PyObject *args, PyObject *f)
+{
+	PyObject *pid = 0;
+	int size, res = -1;
+
+	static char persid = PERSID, binpersid = BINPERSID;
+
+	Py_INCREF(args);
+	ARG_TUP(self, args);
+	if (self->arg) {
+		pid = PyObject_Call(f, self->arg, NULL);
+		FREE_ARG_TUP(self);
+	}
+	if (! pid) return -1;
+
+	if (pid != Py_None) {
+		if (!self->bin) {
+			if (!PyString_Check(pid)) {
+				PyErr_SetString(PicklingError,
+						"persistent id must be string");
+				goto finally;
+			}
+
+			if (self->write_func(self, &persid, 1) < 0)
+				goto finally;
+
+			if ((size = PyString_Size(pid)) < 0)
+				goto finally;
+
+			if (self->write_func(self,
+					     PyString_AS_STRING(
+					     	(PyStringObject *)pid),
+					     size) < 0)
+				goto finally;
+
+			if (self->write_func(self, "\n", 1) < 0)
+				goto finally;
+
+			res = 1;
+			goto finally;
+		}
+		else if (save(self, pid, 1) >= 0) {
+			if (self->write_func(self, &binpersid, 1) < 0)
+				res = -1;
+			else
+				res = 1;
+		}
+
+		goto finally;
+	}
+
+	res = 0;
+
+  finally:
+	Py_XDECREF(pid);
+
+	return res;
+}
+
+/* We're saving ob, and args is the 2-thru-5 tuple returned by the
+ * appropriate __reduce__ method for ob.
+ */
+static int
+save_reduce(Picklerobject *self, PyObject *args, PyObject *ob)
+{
+	PyObject *callable;
+	PyObject *argtup;
+        PyObject *state = NULL;
+        PyObject *listitems = NULL;
+        PyObject *dictitems = NULL;
+
+	int use_newobj = self->proto >= 2;
+
+	static char reduce = REDUCE;
+	static char build = BUILD;
+	static char newobj = NEWOBJ;
+
+	if (! PyArg_UnpackTuple(args, "save_reduce", 2, 5,
+				&callable,
+				&argtup,
+				&state,
+				&listitems,
+				&dictitems))
+		return -1;
+
+	if (!PyTuple_Check(argtup)) {
+		PyErr_SetString(PicklingError,
+				"args from reduce() should be a tuple");
+		return -1;
+	}
+
+	if (state == Py_None)
+		state = NULL;
+	if (listitems == Py_None)
+		listitems = NULL;
+	if (dictitems == Py_None)
+		dictitems = NULL;
+
+        /* Protocol 2 special case: if callable's name is __newobj__, use
+         * NEWOBJ.  This consumes a lot of code.
+         */
+        if (use_newobj) {
+        	PyObject *temp = PyObject_GetAttr(callable, __name___str);
+
+		if (temp == NULL) {
+			if (PyErr_ExceptionMatches(PyExc_AttributeError))
+				PyErr_Clear();
+			else
+				return -1;
+			use_newobj = 0;
+		}
+		else {
+			use_newobj = PyString_Check(temp) &&
+				     strcmp(PyString_AS_STRING(temp),
+				     	    "__newobj__") == 0;
+			Py_DECREF(temp);
+		}
+	}
+	if (use_newobj) {
+		PyObject *cls;
+		PyObject *newargtup;
+		int n, i;
+
+		/* Sanity checks. */
+		n = PyTuple_Size(argtup);
+		if (n < 1) {
+			PyErr_SetString(PicklingError, "__newobj__ arglist "
+				"is empty");
+			return -1;
+		}
+
+		cls = PyTuple_GET_ITEM(argtup, 0);
+		if (! PyObject_HasAttrString(cls, "__new__")) {
+			PyErr_SetString(PicklingError, "args[0] from "
+				"__newobj__ args has no __new__");
+			return -1;
+		}
+
+		/* XXX How could ob be NULL? */
+		if (ob != NULL) {
+			PyObject *ob_dot_class;
+
+			ob_dot_class = PyObject_GetAttr(ob, __class___str);
+			if (ob_dot_class == NULL) {
+				if (PyErr_ExceptionMatches(
+					    PyExc_AttributeError))
+					PyErr_Clear();
+				else
+					return -1;
+			}
+			i = ob_dot_class != cls; /* true iff a problem */
+			Py_XDECREF(ob_dot_class);
+			if (i) {
+				PyErr_SetString(PicklingError, "args[0] from "
+					"__newobj__ args has the wrong class");
+				return -1;
+			}
+		}
+
+		/* Save the class and its __new__ arguments. */
+		if (save(self, cls, 0) < 0)
+			return -1;
+
+		newargtup = PyTuple_New(n-1);  /* argtup[1:] */
+		if (newargtup == NULL)
+			return -1;
+		for (i = 1; i < n; ++i) {
+			PyObject *temp = PyTuple_GET_ITEM(argtup, i);
+			Py_INCREF(temp);
+			PyTuple_SET_ITEM(newargtup, i-1, temp);
+		}
+		i = save(self, newargtup, 0) < 0;
+		Py_DECREF(newargtup);
+		if (i < 0)
+			return -1;
+
+		/* Add NEWOBJ opcode. */
+		if (self->write_func(self, &newobj, 1) < 0)
+			return -1;
+	}
+	else {
+		/* Not using NEWOBJ. */
+		if (save(self, callable, 0) < 0 ||
+		    save(self, argtup, 0) < 0 ||
+		    self->write_func(self, &reduce, 1) < 0)
+			return -1;
+	}
+
+	/* Memoize. */
+	/* XXX How can ob be NULL? */
+	if (ob != NULL) {
+		if (state && !PyDict_Check(state)) {
+			if (put2(self, ob) < 0)
+				return -1;
+		}
+		else if (put(self, ob) < 0)
+				return -1;
+	}
+
+
+        if (listitems && batch_list(self, listitems) < 0)
+        	return -1;
+
+        if (dictitems && batch_dict(self, dictitems) < 0)
+        	return -1;
+
+	if (state) {
+		if (save(self, state, 0) < 0 ||
+		    self->write_func(self, &build, 1) < 0)
+			return -1;
+	}
+
+	return 0;
+}
+
+static int
+save(Picklerobject *self, PyObject *args, int pers_save)
+{
+	PyTypeObject *type;
+	PyObject *py_ob_id = 0, *__reduce__ = 0, *t = 0;
+	PyObject *arg_tup;
+	int res = -1;
+	int tmp, size;
+
+        if (self->nesting++ > Py_GetRecursionLimit()){
+		PyErr_SetString(PyExc_RuntimeError,
+				"maximum recursion depth exceeded");
+		goto finally;
+	}
+
+	if (!pers_save && self->pers_func) {
+		if ((tmp = save_pers(self, args, self->pers_func)) != 0) {
+			res = tmp;
+			goto finally;
+		}
+	}
+
+	if (args == Py_None) {
+		res = save_none(self, args);
+		goto finally;
+	}
+
+	type = args->ob_type;
+
+	switch (type->tp_name[0]) {
+	case 'b':
+		if (args == Py_False || args == Py_True) {
+			res = save_bool(self, args);
+			goto finally;
+		}
+		break;
+        case 'i':
+		if (type == &PyInt_Type) {
+			res = save_int(self, args);
+			goto finally;
+		}
+		break;
+
+        case 'l':
+		if (type == &PyLong_Type) {
+			res = save_long(self, args);
+			goto finally;
+		}
+		break;
+
+        case 'f':
+		if (type == &PyFloat_Type) {
+			res = save_float(self, args);
+			goto finally;
+		}
+		break;
+
+        case 't':
+		if (type == &PyTuple_Type && PyTuple_Size(args) == 0) {
+			res = save_tuple(self, args);
+			goto finally;
+		}
+		break;
+
+        case 's':
+		if ((type == &PyString_Type) && (PyString_GET_SIZE(args) < 2)) {
+			res = save_string(self, args, 0);
+			goto finally;
+		}
+
+#ifdef Py_USING_UNICODE
+        case 'u':
+		if ((type == &PyUnicode_Type) && (PyString_GET_SIZE(args) < 2)) {
+			res = save_unicode(self, args, 0);
+			goto finally;
+		}
+#endif
+	}
+
+	if (args->ob_refcnt > 1) {
+		if (!( py_ob_id = PyLong_FromVoidPtr(args)))
+			goto finally;
+
+		if (PyDict_GetItem(self->memo, py_ob_id)) {
+			if (get(self, py_ob_id) < 0)
+				goto finally;
+
+			res = 0;
+			goto finally;
+		}
+	}
+
+	switch (type->tp_name[0]) {
+        case 's':
+		if (type == &PyString_Type) {
+			res = save_string(self, args, 1);
+			goto finally;
+		}
+		break;
+
+#ifdef Py_USING_UNICODE
+        case 'u':
+		if (type == &PyUnicode_Type) {
+			res = save_unicode(self, args, 1);
+			goto finally;
+		}
+		break;
+#endif
+
+        case 't':
+		if (type == &PyTuple_Type) {
+			res = save_tuple(self, args);
+			goto finally;
+		}
+		if (type == &PyType_Type) {
+			res = save_global(self, args, NULL);
+			goto finally;
+		}
+		break;
+
+        case 'l':
+		if (type == &PyList_Type) {
+			res = save_list(self, args);
+			goto finally;
+		}
+		break;
+
+        case 'd':
+		if (type == &PyDict_Type) {
+			res = save_dict(self, args);
+			goto finally;
+		}
+		break;
+
+        case 'i':
+		if (type == &PyInstance_Type) {
+			res = save_inst(self, args);
+			goto finally;
+		}
+		break;
+
+        case 'c':
+		if (type == &PyClass_Type) {
+			res = save_global(self, args, NULL);
+			goto finally;
+		}
+		break;
+
+        case 'f':
+		if (type == &PyFunction_Type) {
+			res = save_global(self, args, NULL);
+			if (res && PyErr_ExceptionMatches(PickleError)) {
+				/* fall back to reduce */
+				PyErr_Clear();
+				break;
+			}
+			goto finally;
+		}
+		break;
+
+        case 'b':
+		if (type == &PyCFunction_Type) {
+			res = save_global(self, args, NULL);
+			goto finally;
+		}
+	}
+
+	if (!pers_save && self->inst_pers_func) {
+		if ((tmp = save_pers(self, args, self->inst_pers_func)) != 0) {
+			res = tmp;
+			goto finally;
+		}
+	}
+
+	if (PyType_IsSubtype(type, &PyType_Type)) {
+		res = save_global(self, args, NULL);
+		goto finally;
+	}
+
+	/* Get a reduction callable, and call it.  This may come from
+	 * copy_reg.dispatch_table, the object's __reduce_ex__ method,
+	 * or the object's __reduce__ method.
+	 */
+	__reduce__ = PyDict_GetItem(dispatch_table, (PyObject *)type);
+	if (__reduce__ != NULL) {
+		Py_INCREF(__reduce__);
+		Py_INCREF(args);
+		ARG_TUP(self, args);
+		if (self->arg) {
+			t = PyObject_Call(__reduce__, self->arg, NULL);
+			FREE_ARG_TUP(self);
+		}
+	}
+	else {
+		/* Check for a __reduce_ex__ method. */
+		__reduce__ = PyObject_GetAttr(args, __reduce_ex___str);
+		if (__reduce__ != NULL) {
+			t = PyInt_FromLong(self->proto);
+			if (t != NULL) {
+				ARG_TUP(self, t);
+				t = NULL;
+				if (self->arg) {
+					t = PyObject_Call(__reduce__,
+							  self->arg, NULL);
+					FREE_ARG_TUP(self);
+				}
+			}
+		}
+		else {
+			if (PyErr_ExceptionMatches(PyExc_AttributeError))
+				PyErr_Clear();
+			else
+				goto finally;
+			/* Check for a __reduce__ method. */
+			__reduce__ = PyObject_GetAttr(args, __reduce___str);
+			if (__reduce__ != NULL) {
+				t = PyObject_Call(__reduce__,
+						  empty_tuple, NULL);
+			}
+			else {
+				PyErr_SetObject(UnpickleableError, args);
+				goto finally;
+			}
+		}
+	}
+
+	if (t == NULL)
+		goto finally;
+
+	if (PyString_Check(t)) {
+		res = save_global(self, args, t);
+		goto finally;
+	}
+
+	if (! PyTuple_Check(t)) {
+		cPickle_ErrFormat(PicklingError, "Value returned by "
+				"%s must be string or tuple",
+				"O", __reduce__);
+		goto finally;
+	}
+
+	size = PyTuple_Size(t);
+	if (size < 2 || size > 5) {
+		cPickle_ErrFormat(PicklingError, "tuple returned by "
+			"%s must contain 2 through 5 elements",
+			"O", __reduce__);
+		goto finally;
+	}
+
+	arg_tup = PyTuple_GET_ITEM(t, 1);
+	if (!(PyTuple_Check(arg_tup) || arg_tup == Py_None))  {
+		cPickle_ErrFormat(PicklingError, "Second element of "
+			"tuple returned by %s must be a tuple",
+			"O", __reduce__);
+		goto finally;
+	}
+
+	res = save_reduce(self, t, args);
+
+  finally:
+	self->nesting--;
+	Py_XDECREF(py_ob_id);
+	Py_XDECREF(__reduce__);
+	Py_XDECREF(t);
+
+	return res;
+}
+
+
+static int
+dump(Picklerobject *self, PyObject *args)
+{
+	static char stop = STOP;
+
+	if (self->proto >= 2) {
+		char bytes[2];
+
+		bytes[0] = PROTO;
+		assert(self->proto >= 0 && self->proto < 256);
+		bytes[1] = (char)self->proto;
+		if (self->write_func(self, bytes, 2) < 0)
+			return -1;
+	}
+
+	if (save(self, args, 0) < 0)
+		return -1;
+
+	if (self->write_func(self, &stop, 1) < 0)
+		return -1;
+
+	if (self->write_func(self, NULL, 0) < 0)
+		return -1;
+
+	return 0;
+}
+
+static PyObject *
+Pickle_clear_memo(Picklerobject *self, PyObject *args)
+{
+	if (self->memo)
+		PyDict_Clear(self->memo);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+Pickle_getvalue(Picklerobject *self, PyObject *args)
+{
+	int l, i, rsize, ssize, clear=1, lm;
+	long ik;
+	PyObject *k, *r;
+	char *s, *p, *have_get;
+	Pdata *data;
+
+	/* Can be called by Python code or C code */
+	if (args && !PyArg_ParseTuple(args, "|i:getvalue", &clear))
+		return NULL;
+
+	/* Check to make sure we are based on a list */
+	if (! Pdata_Check(self->file)) {
+		PyErr_SetString(PicklingError,
+				"Attempt to getvalue() a non-list-based pickler");
+		return NULL;
+	}
+
+	/* flush write buffer */
+	if (write_other(self, NULL, 0) < 0) return NULL;
+
+	data=(Pdata*)self->file;
+	l=data->length;
+
+	/* set up an array to hold get/put status */
+	lm = PyDict_Size(self->memo);
+	if (lm < 0) return NULL;
+	lm++;
+	have_get = malloc(lm);
+	if (have_get == NULL) return PyErr_NoMemory();
+	memset(have_get, 0, lm);
+
+	/* Scan for gets. */
+	for (rsize = 0, i = l; --i >= 0; ) {
+		k = data->data[i];
+
+		if (PyString_Check(k))
+			rsize += PyString_GET_SIZE(k);
+
+		else if (PyInt_Check(k)) { /* put */
+			ik = PyInt_AS_LONG((PyIntObject*)k);
+			if (ik >= lm || ik == 0) {
+				PyErr_SetString(PicklingError,
+						"Invalid get data");
+				goto err;
+			}
+			if (have_get[ik]) /* with matching get */
+				rsize += ik < 256 ? 2 : 5;
+		}
+
+		else if (! (PyTuple_Check(k) &&
+			    PyTuple_GET_SIZE(k) == 2 &&
+			    PyInt_Check((k = PyTuple_GET_ITEM(k, 0))))
+			) {
+			PyErr_SetString(PicklingError,
+					"Unexpected data in internal list");
+			goto err;
+		}
+
+		else { /* put */
+			ik = PyInt_AS_LONG((PyIntObject *)k);
+			if (ik >= lm || ik == 0) {
+				PyErr_SetString(PicklingError,
+						"Invalid get data");
+				return NULL;
+			}
+			have_get[ik] = 1;
+			rsize += ik < 256 ? 2 : 5;
+		}
+	}
+
+	/* Now generate the result */
+	r = PyString_FromStringAndSize(NULL, rsize);
+	if (r == NULL) goto err;
+	s = PyString_AS_STRING((PyStringObject *)r);
+
+	for (i = 0; i < l; i++) {
+		k = data->data[i];
+
+		if (PyString_Check(k)) {
+			ssize = PyString_GET_SIZE(k);
+			if (ssize) {
+				p=PyString_AS_STRING((PyStringObject *)k);
+				while (--ssize >= 0)
+					*s++ = *p++;
+			}
+		}
+
+		else if (PyTuple_Check(k)) { /* get */
+			ik = PyInt_AS_LONG((PyIntObject *)
+					    PyTuple_GET_ITEM(k, 0));
+			if (ik < 256) {
+				*s++ = BINGET;
+				*s++ = (int)(ik & 0xff);
+			}
+			else {
+				*s++ = LONG_BINGET;
+				*s++ = (int)(ik & 0xff);
+				*s++ = (int)((ik >> 8)  & 0xff);
+				*s++ = (int)((ik >> 16) & 0xff);
+				*s++ = (int)((ik >> 24) & 0xff);
+			}
+		}
+
+		else { /* put */
+			ik = PyInt_AS_LONG((PyIntObject*)k);
+
+			if (have_get[ik]) { /* with matching get */
+				if (ik < 256) {
+					*s++ = BINPUT;
+					*s++ = (int)(ik & 0xff);
+				}
+				else {
+					*s++ = LONG_BINPUT;
+					*s++ = (int)(ik & 0xff);
+					*s++ = (int)((ik >> 8)  & 0xff);
+					*s++ = (int)((ik >> 16) & 0xff);
+					*s++ = (int)((ik >> 24) & 0xff);
+				}
+			}
+		}
+	}
+
+	if (clear) {
+		PyDict_Clear(self->memo);
+		Pdata_clear(data, 0);
+	}
+
+	free(have_get);
+	return r;
+  err:
+	free(have_get);
+	return NULL;
+}
+
+static PyObject *
+Pickler_dump(Picklerobject *self, PyObject *args)
+{
+	PyObject *ob;
+	int get=0;
+
+	if (!( PyArg_ParseTuple(args, "O|i:dump", &ob, &get)))
+		return NULL;
+
+	if (dump(self, ob) < 0)
+		return NULL;
+
+	if (get) return Pickle_getvalue(self, NULL);
+
+	/* XXX Why does dump() return self? */
+	Py_INCREF(self);
+	return (PyObject*)self;
+}
+
+
+static struct PyMethodDef Pickler_methods[] =
+{
+  {"dump",          (PyCFunction)Pickler_dump,  METH_VARARGS,
+   PyDoc_STR("dump(object) -- "
+   "Write an object in pickle format to the object's pickle stream")},
+  {"clear_memo",  (PyCFunction)Pickle_clear_memo,  METH_NOARGS,
+   PyDoc_STR("clear_memo() -- Clear the picklers memo")},
+  {"getvalue",  (PyCFunction)Pickle_getvalue,  METH_VARARGS,
+   PyDoc_STR("getvalue() -- Finish picking a list-based pickle")},
+  {NULL,                NULL}           /* sentinel */
+};
+
+
+static Picklerobject *
+newPicklerobject(PyObject *file, int proto)
+{
+	Picklerobject *self;
+
+	if (proto < 0)
+		proto = HIGHEST_PROTOCOL;
+	if (proto > HIGHEST_PROTOCOL) {
+		PyErr_Format(PyExc_ValueError, "pickle protocol %d asked for; "
+			     "the highest available protocol is %d",
+			     proto, HIGHEST_PROTOCOL);
+		return NULL;
+	}
+
+	self = PyObject_GC_New(Picklerobject, &Picklertype);
+	if (self == NULL)
+		return NULL;
+	self->proto = proto;
+	self->bin = proto > 0;
+	self->fp = NULL;
+	self->write = NULL;
+	self->memo = NULL;
+	self->arg = NULL;
+	self->pers_func = NULL;
+	self->inst_pers_func = NULL;
+	self->write_buf = NULL;
+	self->fast = 0;
+        self->nesting = 0;
+	self->fast_container = 0;
+	self->fast_memo = NULL;
+	self->buf_size = 0;
+	self->dispatch_table = NULL;
+
+	self->file = NULL;
+	if (file)
+		Py_INCREF(file);
+	else {
+		file = Pdata_New();
+		if (file == NULL)
+			goto err;
+	}
+	self->file = file;
+
+	if (!( self->memo = PyDict_New()))
+		goto err;
+
+	if (PyFile_Check(file)) {
+		self->fp = PyFile_AsFile(file);
+		if (self->fp == NULL) {
+			PyErr_SetString(PyExc_ValueError,
+					"I/O operation on closed file");
+			goto err;
+		}
+		self->write_func = write_file;
+	}
+	else if (PycStringIO_OutputCheck(file)) {
+		self->write_func = write_cStringIO;
+	}
+	else if (file == Py_None) {
+		self->write_func = write_none;
+	}
+	else {
+		self->write_func = write_other;
+
+		if (! Pdata_Check(file)) {
+			self->write = PyObject_GetAttr(file, write_str);
+			if (!self->write)  {
+				PyErr_Clear();
+				PyErr_SetString(PyExc_TypeError,
+						"argument must have 'write' "
+						"attribute");
+				goto err;
+			}
+		}
+
+		self->write_buf = (char *)PyMem_Malloc(WRITE_BUF_SIZE);
+		if (self->write_buf == NULL) {
+			PyErr_NoMemory();
+			goto err;
+		}
+	}
+
+	if (PyEval_GetRestricted()) {
+		/* Restricted execution, get private tables */
+		PyObject *m = PyImport_Import(copy_reg_str);
+
+		if (m == NULL)
+			goto err;
+		self->dispatch_table = PyObject_GetAttr(m, dispatch_table_str);
+		Py_DECREF(m);
+		if (self->dispatch_table == NULL)
+			goto err;
+	}
+	else {
+		self->dispatch_table = dispatch_table;
+		Py_INCREF(dispatch_table);
+	}
+	PyObject_GC_Track(self);
+
+	return self;
+
+  err:
+	Py_DECREF(self);
+	return NULL;
+}
+
+
+static PyObject *
+get_Pickler(PyObject *self, PyObject *args, PyObject *kwds)
+{
+	static char *kwlist[] = {"file", "protocol", NULL};
+	PyObject *file = NULL;
+	int proto = 0;
+
+	/* XXX
+	 * The documented signature is Pickler(file, protocol=0), but this
+	 * accepts Pickler() and Pickler(integer) too.  The meaning then
+	 * is clear as mud, undocumented, and not supported by pickle.py.
+	 * I'm told Zope uses this, but I haven't traced into this code
+	 * far enough to figure out what it means.
+	 */
+	if (!PyArg_ParseTuple(args, "|i:Pickler", &proto)) {
+		PyErr_Clear();
+		proto = 0;
+		if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|i:Pickler",
+			    kwlist, &file, &proto))
+			return NULL;
+	}
+	return (PyObject *)newPicklerobject(file, proto);
+}
+
+
+static void
+Pickler_dealloc(Picklerobject *self)
+{
+	PyObject_GC_UnTrack(self);
+	Py_XDECREF(self->write);
+	Py_XDECREF(self->memo);
+	Py_XDECREF(self->fast_memo);
+	Py_XDECREF(self->arg);
+	Py_XDECREF(self->file);
+	Py_XDECREF(self->pers_func);
+	Py_XDECREF(self->inst_pers_func);
+	Py_XDECREF(self->dispatch_table);
+	PyMem_Free(self->write_buf);
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+static int
+Pickler_traverse(Picklerobject *self, visitproc visit, void *arg)
+{
+	Py_VISIT(self->write);
+	Py_VISIT(self->memo);
+	Py_VISIT(self->fast_memo);
+	Py_VISIT(self->arg);
+	Py_VISIT(self->file);
+	Py_VISIT(self->pers_func);
+	Py_VISIT(self->inst_pers_func);
+	Py_VISIT(self->dispatch_table);
+	return 0;
+}
+
+static int
+Pickler_clear(Picklerobject *self)
+{
+	Py_CLEAR(self->write);
+	Py_CLEAR(self->memo);
+	Py_CLEAR(self->fast_memo);
+	Py_CLEAR(self->arg);
+	Py_CLEAR(self->file);
+	Py_CLEAR(self->pers_func);
+	Py_CLEAR(self->inst_pers_func);
+	Py_CLEAR(self->dispatch_table);
+	return 0;
+}
+
+static PyObject *
+Pickler_get_pers_func(Picklerobject *p)
+{
+	if (p->pers_func == NULL)
+		PyErr_SetString(PyExc_AttributeError, "persistent_id");
+	else
+		Py_INCREF(p->pers_func);
+	return p->pers_func;
+}
+
+static int
+Pickler_set_pers_func(Picklerobject *p, PyObject *v)
+{
+	if (v == NULL) {
+		PyErr_SetString(PyExc_TypeError,
+				"attribute deletion is not supported");
+		return -1;
+	}
+	Py_XDECREF(p->pers_func);
+	Py_INCREF(v);
+	p->pers_func = v;
+	return 0;
+}
+
+static int
+Pickler_set_inst_pers_func(Picklerobject *p, PyObject *v)
+{
+	if (v == NULL) {
+		PyErr_SetString(PyExc_TypeError,
+				"attribute deletion is not supported");
+		return -1;
+	}
+	Py_XDECREF(p->inst_pers_func);
+	Py_INCREF(v);
+	p->inst_pers_func = v;
+	return 0;
+}
+
+static PyObject *
+Pickler_get_memo(Picklerobject *p)
+{
+	if (p->memo == NULL)
+		PyErr_SetString(PyExc_AttributeError, "memo");
+	else
+		Py_INCREF(p->memo);
+	return p->memo;
+}
+
+static int
+Pickler_set_memo(Picklerobject *p, PyObject *v)
+{
+	if (v == NULL) {
+		PyErr_SetString(PyExc_TypeError,
+				"attribute deletion is not supported");
+		return -1;
+	}
+	if (!PyDict_Check(v)) {
+		PyErr_SetString(PyExc_TypeError, "memo must be a dictionary");
+		return -1;
+	}
+	Py_XDECREF(p->memo);
+	Py_INCREF(v);
+	p->memo = v;
+	return 0;
+}
+
+static PyObject *
+Pickler_get_error(Picklerobject *p)
+{
+	/* why is this an attribute on the Pickler? */
+	Py_INCREF(PicklingError);
+	return PicklingError;
+}
+
+static PyMemberDef Pickler_members[] = {
+    {"binary", T_INT, offsetof(Picklerobject, bin)},
+    {"fast", T_INT, offsetof(Picklerobject, fast)},
+    {NULL}
+};
+
+static PyGetSetDef Pickler_getsets[] = {
+    {"persistent_id", (getter)Pickler_get_pers_func,
+                     (setter)Pickler_set_pers_func},
+    {"inst_persistent_id", NULL, (setter)Pickler_set_inst_pers_func},
+    {"memo", (getter)Pickler_get_memo, (setter)Pickler_set_memo},
+    {"PicklingError", (getter)Pickler_get_error, NULL},
+    {NULL}
+};
+
+PyDoc_STRVAR(Picklertype__doc__,
+"Objects that know how to pickle objects\n");
+
+static PyTypeObject Picklertype = {
+    PyObject_HEAD_INIT(NULL)
+    0,                            /*ob_size*/
+    "cPickle.Pickler",            /*tp_name*/
+    sizeof(Picklerobject),              /*tp_basicsize*/
+    0,
+    (destructor)Pickler_dealloc,	/* tp_dealloc */
+    0,					/* tp_print */
+    0,			 		/* tp_getattr */
+    0,			 		/* tp_setattr */
+    0,					/* tp_compare */
+    0,		 			/* tp_repr */
+    0,					/* tp_as_number */
+    0,					/* tp_as_sequence */
+    0,					/* tp_as_mapping */
+    0,					/* tp_hash */
+    0,					/* tp_call */
+    0,					/* tp_str */
+    PyObject_GenericGetAttr,		/* tp_getattro */
+    PyObject_GenericSetAttr,		/* tp_setattro */
+    0,					/* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
+    Picklertype__doc__,			/* tp_doc */
+    (traverseproc)Pickler_traverse,	/* tp_traverse */
+    (inquiry)Pickler_clear,		/* tp_clear */
+    0,					/* tp_richcompare */
+    0,					/* tp_weaklistoffset */
+    0,					/* tp_iter */
+    0,					/* tp_iternext */
+    Pickler_methods,			/* tp_methods */
+    Pickler_members,			/* tp_members */
+    Pickler_getsets,			/* tp_getset */
+};
+
+static PyObject *
+find_class(PyObject *py_module_name, PyObject *py_global_name, PyObject *fc)
+{
+	PyObject *global = 0, *module;
+
+	if (fc) {
+		if (fc==Py_None) {
+			PyErr_SetString(UnpicklingError, "Global and instance "
+					"pickles are not supported.");
+			return NULL;
+		}
+		return PyObject_CallFunctionObjArgs(fc, py_module_name,
+					            py_global_name, NULL);
+	}
+
+	module = PySys_GetObject("modules");
+	if (module == NULL)
+		return NULL;
+
+	module = PyDict_GetItem(module, py_module_name);
+	if (module == NULL) {
+		module = PyImport_Import(py_module_name);
+		if (!module)
+			return NULL;
+		global = PyObject_GetAttr(module, py_global_name);
+		Py_DECREF(module);
+	}
+	else
+		global = PyObject_GetAttr(module, py_global_name);
+	return global;
+}
+
+static int
+marker(Unpicklerobject *self)
+{
+	if (self->num_marks < 1) {
+		PyErr_SetString(UnpicklingError, "could not find MARK");
+		return -1;
+	}
+
+	return self->marks[--self->num_marks];
+}
+
+
+static int
+load_none(Unpicklerobject *self)
+{
+	PDATA_APPEND(self->stack, Py_None, -1);
+	return 0;
+}
+
+static int
+bad_readline(void)
+{
+	PyErr_SetString(UnpicklingError, "pickle data was truncated");
+	return -1;
+}
+
+static int
+load_int(Unpicklerobject *self)
+{
+	PyObject *py_int = 0;
+	char *endptr, *s;
+	int len, res = -1;
+	long l;
+
+	if ((len = self->readline_func(self, &s)) < 0) return -1;
+	if (len < 2) return bad_readline();
+	if (!( s=pystrndup(s,len)))  return -1;
+
+	errno = 0;
+	l = strtol(s, &endptr, 0);
+
+	if (errno || (*endptr != '\n') || (endptr[1] != '\0')) {
+		/* Hm, maybe we've got something long.  Let's try reading
+		   it as a Python long object. */
+		errno = 0;
+		py_int = PyLong_FromString(s, NULL, 0);
+		if (py_int == NULL) {
+			PyErr_SetString(PyExc_ValueError,
+					"could not convert string to int");
+			goto finally;
+		}
+	}
+	else {
+		if (len == 3 && (l == 0 || l == 1)) {
+			if (!( py_int = PyBool_FromLong(l)))  goto finally;
+		}
+		else {
+			if (!( py_int = PyInt_FromLong(l)))  goto finally;
+		}
+	}
+
+	free(s);
+	PDATA_PUSH(self->stack, py_int, -1);
+	return 0;
+
+  finally:
+	free(s);
+
+	return res;
+}
+
+static int
+load_bool(Unpicklerobject *self, PyObject *boolean)
+{
+	assert(boolean == Py_True || boolean == Py_False);
+	PDATA_APPEND(self->stack, boolean, -1);
+	return 0;
+}
+
+/* s contains x bytes of a little-endian integer.  Return its value as a
+ * C int.  Obscure:  when x is 1 or 2, this is an unsigned little-endian
+ * int, but when x is 4 it's a signed one.  This is an historical source
+ * of x-platform bugs.
+ */
+static long
+calc_binint(char *s, int x)
+{
+	unsigned char c;
+	int i;
+	long l;
+
+	for (i = 0, l = 0L; i < x; i++) {
+		c = (unsigned char)s[i];
+		l |= (long)c << (i * 8);
+	}
+#if SIZEOF_LONG > 4
+	/* Unlike BININT1 and BININT2, BININT (more accurately BININT4)
+	 * is signed, so on a box with longs bigger than 4 bytes we need
+	 * to extend a BININT's sign bit to the full width.
+	 */
+	if (x == 4 && l & (1L << 31))
+		l |= (~0L) << 32;
+#endif
+	return l;
+}
+
+
+static int
+load_binintx(Unpicklerobject *self, char *s, int  x)
+{
+	PyObject *py_int = 0;
+	long l;
+
+	l = calc_binint(s, x);
+
+	if (!( py_int = PyInt_FromLong(l)))
+		return -1;
+
+	PDATA_PUSH(self->stack, py_int, -1);
+	return 0;
+}
+
+
+static int
+load_binint(Unpicklerobject *self)
+{
+	char *s;
+
+	if (self->read_func(self, &s, 4) < 0)
+		return -1;
+
+	return load_binintx(self, s, 4);
+}
+
+
+static int
+load_binint1(Unpicklerobject *self)
+{
+	char *s;
+
+	if (self->read_func(self, &s, 1) < 0)
+		return -1;
+
+	return load_binintx(self, s, 1);
+}
+
+
+static int
+load_binint2(Unpicklerobject *self)
+{
+	char *s;
+
+	if (self->read_func(self, &s, 2) < 0)
+		return -1;
+
+	return load_binintx(self, s, 2);
+}
+
+static int
+load_long(Unpicklerobject *self)
+{
+	PyObject *l = 0;
+	char *end, *s;
+	int len, res = -1;
+
+	if ((len = self->readline_func(self, &s)) < 0) return -1;
+	if (len < 2) return bad_readline();
+	if (!( s=pystrndup(s,len)))  return -1;
+
+	if (!( l = PyLong_FromString(s, &end, 0)))
+		goto finally;
+
+	free(s);
+	PDATA_PUSH(self->stack, l, -1);
+	return 0;
+
+  finally:
+	free(s);
+
+	return res;
+}
+
+/* 'size' bytes contain the # of bytes of little-endian 256's-complement
+ * data following.
+ */
+static int
+load_counted_long(Unpicklerobject *self, int size)
+{
+	Py_ssize_t i;
+	char *nbytes;
+	unsigned char *pdata;
+	PyObject *along;
+
+	assert(size == 1 || size == 4);
+	i = self->read_func(self, &nbytes, size);
+	if (i < 0) return -1;
+
+	size = calc_binint(nbytes, size);
+	if (size < 0) {
+		/* Corrupt or hostile pickle -- we never write one like
+		 * this.
+		 */
+		PyErr_SetString(UnpicklingError, "LONG pickle has negative "
+				"byte count");
+		return -1;
+	}
+
+	if (size == 0)
+		along = PyLong_FromLong(0L);
+	else {
+		/* Read the raw little-endian bytes & convert. */
+		i = self->read_func(self, (char **)&pdata, size);
+		if (i < 0) return -1;
+		along = _PyLong_FromByteArray(pdata, (size_t)size,
+				1 /* little endian */, 1 /* signed */);
+	}
+	if (along == NULL)
+		return -1;
+	PDATA_PUSH(self->stack, along, -1);
+	return 0;
+}
+
+static int
+load_float(Unpicklerobject *self)
+{
+	PyObject *py_float = 0;
+	char *endptr, *s;
+	int len, res = -1;
+	double d;
+
+	if ((len = self->readline_func(self, &s)) < 0) return -1;
+	if (len < 2) return bad_readline();
+	if (!( s=pystrndup(s,len)))  return -1;
+
+	errno = 0;
+	d = PyOS_ascii_strtod(s, &endptr);
+
+	if (errno || (endptr[0] != '\n') || (endptr[1] != '\0')) {
+		PyErr_SetString(PyExc_ValueError,
+				"could not convert string to float");
+		goto finally;
+	}
+
+	if (!( py_float = PyFloat_FromDouble(d)))
+		goto finally;
+
+	free(s);
+	PDATA_PUSH(self->stack, py_float, -1);
+	return 0;
+
+  finally:
+	free(s);
+
+	return res;
+}
+
+static int
+load_binfloat(Unpicklerobject *self)
+{
+	PyObject *py_float;
+	double x;
+	char *p;
+
+	if (self->read_func(self, &p, 8) < 0)
+		return -1;
+
+	x = _PyFloat_Unpack8((unsigned char *)p, 0);
+	if (x == -1.0 && PyErr_Occurred())
+		return -1;
+
+	py_float = PyFloat_FromDouble(x);
+	if (py_float == NULL)
+		return -1;
+
+	PDATA_PUSH(self->stack, py_float, -1);
+	return 0;
+}
+
+static int
+load_string(Unpicklerobject *self)
+{
+	PyObject *str = 0;
+	int len, res = -1;
+	char *s, *p;
+
+	if ((len = self->readline_func(self, &s)) < 0) return -1;
+	if (len < 2) return bad_readline();
+	if (!( s=pystrndup(s,len)))  return -1;
+
+
+	/* Strip outermost quotes */
+	while (s[len-1] <= ' ')
+		len--;
+	if(s[0]=='"' && s[len-1]=='"'){
+		s[len-1] = '\0';
+		p = s + 1 ;
+		len -= 2;
+	} else if(s[0]=='\'' && s[len-1]=='\''){
+		s[len-1] = '\0';
+		p = s + 1 ;
+		len -= 2;
+	} else
+		goto insecure;
+	/********************************************/
+
+	str = PyString_DecodeEscape(p, len, NULL, 0, NULL);
+	free(s);
+	if (str) {
+		PDATA_PUSH(self->stack, str, -1);
+		res = 0;
+	}
+	return res;
+
+  insecure:
+	free(s);
+	PyErr_SetString(PyExc_ValueError,"insecure string pickle");
+	return -1;
+}
+
+
+static int
+load_binstring(Unpicklerobject *self)
+{
+	PyObject *py_string = 0;
+	long l;
+	char *s;
+
+	if (self->read_func(self, &s, 4) < 0) return -1;
+
+	l = calc_binint(s, 4);
+
+	if (self->read_func(self, &s, l) < 0)
+		return -1;
+
+	if (!( py_string = PyString_FromStringAndSize(s, l)))
+		return -1;
+
+	PDATA_PUSH(self->stack, py_string, -1);
+	return 0;
+}
+
+
+static int
+load_short_binstring(Unpicklerobject *self)
+{
+	PyObject *py_string = 0;
+	unsigned char l;
+	char *s;
+
+	if (self->read_func(self, &s, 1) < 0)
+		return -1;
+
+	l = (unsigned char)s[0];
+
+	if (self->read_func(self, &s, l) < 0) return -1;
+
+	if (!( py_string = PyString_FromStringAndSize(s, l)))  return -1;
+
+	PDATA_PUSH(self->stack, py_string, -1);
+	return 0;
+}
+
+
+#ifdef Py_USING_UNICODE
+static int
+load_unicode(Unpicklerobject *self)
+{
+	PyObject *str = 0;
+	int len, res = -1;
+	char *s;
+
+	if ((len = self->readline_func(self, &s)) < 0) return -1;
+	if (len < 1) return bad_readline();
+
+	if (!( str = PyUnicode_DecodeRawUnicodeEscape(s, len - 1, NULL)))
+		goto finally;
+
+	PDATA_PUSH(self->stack, str, -1);
+	return 0;
+
+  finally:
+	return res;
+}
+#endif
+
+
+#ifdef Py_USING_UNICODE
+static int
+load_binunicode(Unpicklerobject *self)
+{
+	PyObject *unicode;
+	long l;
+	char *s;
+
+	if (self->read_func(self, &s, 4) < 0) return -1;
+
+	l = calc_binint(s, 4);
+
+	if (self->read_func(self, &s, l) < 0)
+		return -1;
+
+	if (!( unicode = PyUnicode_DecodeUTF8(s, l, NULL)))
+		return -1;
+
+	PDATA_PUSH(self->stack, unicode, -1);
+	return 0;
+}
+#endif
+
+
+static int
+load_tuple(Unpicklerobject *self)
+{
+	PyObject *tup;
+	int i;
+
+	if ((i = marker(self)) < 0) return -1;
+	if (!( tup=Pdata_popTuple(self->stack, i)))  return -1;
+	PDATA_PUSH(self->stack, tup, -1);
+	return 0;
+}
+
+static int
+load_counted_tuple(Unpicklerobject *self, int len)
+{
+	PyObject *tup = PyTuple_New(len);
+
+	if (tup == NULL)
+		return -1;
+
+	while (--len >= 0) {
+		PyObject *element;
+
+		PDATA_POP(self->stack, element);
+		if (element == NULL)
+			return -1;
+		PyTuple_SET_ITEM(tup, len, element);
+	}
+	PDATA_PUSH(self->stack, tup, -1);
+	return 0;
+}
+
+static int
+load_empty_list(Unpicklerobject *self)
+{
+	PyObject *list;
+
+	if (!( list=PyList_New(0)))  return -1;
+	PDATA_PUSH(self->stack, list, -1);
+	return 0;
+}
+
+static int
+load_empty_dict(Unpicklerobject *self)
+{
+	PyObject *dict;
+
+	if (!( dict=PyDict_New()))  return -1;
+	PDATA_PUSH(self->stack, dict, -1);
+	return 0;
+}
+
+
+static int
+load_list(Unpicklerobject *self)
+{
+	PyObject *list = 0;
+	int i;
+
+	if ((i = marker(self)) < 0) return -1;
+	if (!( list=Pdata_popList(self->stack, i)))  return -1;
+	PDATA_PUSH(self->stack, list, -1);
+	return 0;
+}
+
+static int
+load_dict(Unpicklerobject *self)
+{
+	PyObject *dict, *key, *value;
+	int i, j, k;
+
+	if ((i = marker(self)) < 0) return -1;
+	j=self->stack->length;
+
+	if (!( dict = PyDict_New()))  return -1;
+
+	for (k = i+1; k < j; k += 2) {
+		key  =self->stack->data[k-1];
+		value=self->stack->data[k  ];
+		if (PyDict_SetItem(dict, key, value) < 0) {
+			Py_DECREF(dict);
+			return -1;
+		}
+	}
+	Pdata_clear(self->stack, i);
+	PDATA_PUSH(self->stack, dict, -1);
+	return 0;
+}
+
+static PyObject *
+Instance_New(PyObject *cls, PyObject *args)
+{
+	PyObject *r = 0;
+
+	if (PyClass_Check(cls)) {
+		int l;
+
+		if ((l=PyObject_Size(args)) < 0) goto err;
+		if (!( l ))  {
+			PyObject *__getinitargs__;
+
+			__getinitargs__ = PyObject_GetAttr(cls,
+						   __getinitargs___str);
+			if (!__getinitargs__)  {
+				/* We have a class with no __getinitargs__,
+				   so bypass usual construction  */
+				PyObject *inst;
+
+				PyErr_Clear();
+				if (!( inst=PyInstance_NewRaw(cls, NULL)))
+					goto err;
+				return inst;
+			}
+			Py_DECREF(__getinitargs__);
+		}
+
+		if ((r=PyInstance_New(cls, args, NULL))) return r;
+		else goto err;
+	}
+
+	if ((r=PyObject_CallObject(cls, args))) return r;
+
+  err:
+	{
+		PyObject *tp, *v, *tb, *tmp_value;
+
+		PyErr_Fetch(&tp, &v, &tb);
+		tmp_value = v;
+		/* NULL occurs when there was a KeyboardInterrupt */
+		if (tmp_value == NULL)
+			tmp_value = Py_None;
+		if ((r = PyTuple_Pack(3, tmp_value, cls, args))) {
+			Py_XDECREF(v);
+			v=r;
+		}
+		PyErr_Restore(tp,v,tb);
+	}
+	return NULL;
+}
+
+
+static int
+load_obj(Unpicklerobject *self)
+{
+	PyObject *class, *tup, *obj=0;
+	int i;
+
+	if ((i = marker(self)) < 0) return -1;
+	if (!( tup=Pdata_popTuple(self->stack, i+1)))  return -1;
+	PDATA_POP(self->stack, class);
+	if (class) {
+		obj = Instance_New(class, tup);
+		Py_DECREF(class);
+	}
+	Py_DECREF(tup);
+
+	if (! obj) return -1;
+	PDATA_PUSH(self->stack, obj, -1);
+	return 0;
+}
+
+
+static int
+load_inst(Unpicklerobject *self)
+{
+	PyObject *tup, *class=0, *obj=0, *module_name, *class_name;
+	int i, len;
+	char *s;
+
+	if ((i = marker(self)) < 0) return -1;
+
+	if ((len = self->readline_func(self, &s)) < 0) return -1;
+	if (len < 2) return bad_readline();
+	module_name = PyString_FromStringAndSize(s, len - 1);
+	if (!module_name)  return -1;
+
+	if ((len = self->readline_func(self, &s)) >= 0) {
+		if (len < 2) return bad_readline();
+		if ((class_name = PyString_FromStringAndSize(s, len - 1))) {
+			class = find_class(module_name, class_name,
+					   self->find_class);
+			Py_DECREF(class_name);
+		}
+	}
+	Py_DECREF(module_name);
+
+	if (! class) return -1;
+
+	if ((tup=Pdata_popTuple(self->stack, i))) {
+		obj = Instance_New(class, tup);
+		Py_DECREF(tup);
+	}
+	Py_DECREF(class);
+
+	if (! obj) return -1;
+
+	PDATA_PUSH(self->stack, obj, -1);
+	return 0;
+}
+
+static int
+load_newobj(Unpicklerobject *self)
+{
+	PyObject *args = NULL;
+	PyObject *clsraw = NULL;
+	PyTypeObject *cls;	/* clsraw cast to its true type */
+	PyObject *obj;
+
+	/* Stack is ... cls argtuple, and we want to call
+	 * cls.__new__(cls, *argtuple).
+	 */
+	PDATA_POP(self->stack, args);
+	if (args == NULL) goto Fail;
+	if (! PyTuple_Check(args)) {
+		PyErr_SetString(UnpicklingError, "NEWOBJ expected an arg "
+						 "tuple.");
+		goto Fail;
+	}
+
+	PDATA_POP(self->stack, clsraw);
+	cls = (PyTypeObject *)clsraw;
+	if (cls == NULL) goto Fail;
+	if (! PyType_Check(cls)) {
+		PyErr_SetString(UnpicklingError, "NEWOBJ class argument "
+					 	 "isn't a type object");
+		goto Fail;
+	}
+	if (cls->tp_new == NULL) {
+		PyErr_SetString(UnpicklingError, "NEWOBJ class argument "
+						 "has NULL tp_new");
+		goto Fail;
+	}
+
+	/* Call __new__. */
+	obj = cls->tp_new(cls, args, NULL);
+	if (obj == NULL) goto Fail;
+
+ 	Py_DECREF(args);
+ 	Py_DECREF(clsraw);
+	PDATA_PUSH(self->stack, obj, -1);
+ 	return 0;
+
+ Fail:
+ 	Py_XDECREF(args);
+ 	Py_XDECREF(clsraw);
+ 	return -1;
+}
+
+static int
+load_global(Unpicklerobject *self)
+{
+	PyObject *class = 0, *module_name = 0, *class_name = 0;
+	int len;
+	char *s;
+
+	if ((len = self->readline_func(self, &s)) < 0) return -1;
+	if (len < 2) return bad_readline();
+	module_name = PyString_FromStringAndSize(s, len - 1);
+	if (!module_name)  return -1;
+
+	if ((len = self->readline_func(self, &s)) >= 0) {
+		if (len < 2) {
+			Py_DECREF(module_name);
+			return bad_readline();
+		}
+		if ((class_name = PyString_FromStringAndSize(s, len - 1))) {
+			class = find_class(module_name, class_name,
+					   self->find_class);
+			Py_DECREF(class_name);
+		}
+	}
+	Py_DECREF(module_name);
+
+	if (! class) return -1;
+	PDATA_PUSH(self->stack, class, -1);
+	return 0;
+}
+
+
+static int
+load_persid(Unpicklerobject *self)
+{
+	PyObject *pid = 0;
+	int len;
+	char *s;
+
+	if (self->pers_func) {
+		if ((len = self->readline_func(self, &s)) < 0) return -1;
+		if (len < 2) return bad_readline();
+
+		pid = PyString_FromStringAndSize(s, len - 1);
+		if (!pid)  return -1;
+
+		if (PyList_Check(self->pers_func)) {
+			if (PyList_Append(self->pers_func, pid) < 0) {
+				Py_DECREF(pid);
+				return -1;
+			}
+		}
+		else {
+			ARG_TUP(self, pid);
+			if (self->arg) {
+				pid = PyObject_Call(self->pers_func, self->arg,
+						    NULL);
+				FREE_ARG_TUP(self);
+			}
+		}
+
+		if (! pid) return -1;
+
+		PDATA_PUSH(self->stack, pid, -1);
+		return 0;
+	}
+	else {
+		PyErr_SetString(UnpicklingError,
+				"A load persistent id instruction was encountered,\n"
+				"but no persistent_load function was specified.");
+		return -1;
+	}
+}
+
+static int
+load_binpersid(Unpicklerobject *self)
+{
+	PyObject *pid = 0;
+
+	if (self->pers_func) {
+		PDATA_POP(self->stack, pid);
+		if (! pid) return -1;
+
+		if (PyList_Check(self->pers_func)) {
+			if (PyList_Append(self->pers_func, pid) < 0) {
+				Py_DECREF(pid);
+				return -1;
+			}
+		}
+		else {
+			ARG_TUP(self, pid);
+			if (self->arg) {
+				pid = PyObject_Call(self->pers_func, self->arg,
+						    NULL);
+				FREE_ARG_TUP(self);
+			}
+			if (! pid) return -1;
+		}
+
+		PDATA_PUSH(self->stack, pid, -1);
+		return 0;
+	}
+	else {
+		PyErr_SetString(UnpicklingError,
+				"A load persistent id instruction was encountered,\n"
+				"but no persistent_load function was specified.");
+		return -1;
+	}
+}
+
+
+static int
+load_pop(Unpicklerobject *self)
+{
+	int len;
+
+	if (!( (len=self->stack->length) > 0 ))  return stackUnderflow();
+
+	/* Note that we split the (pickle.py) stack into two stacks,
+	   an object stack and a mark stack. We have to be clever and
+	   pop the right one. We do this by looking at the top of the
+	   mark stack.
+	*/
+
+	if ((self->num_marks > 0) &&
+	    (self->marks[self->num_marks - 1] == len))
+		self->num_marks--;
+	else {
+		len--;
+		Py_DECREF(self->stack->data[len]);
+		self->stack->length=len;
+	}
+
+	return 0;
+}
+
+
+static int
+load_pop_mark(Unpicklerobject *self)
+{
+	int i;
+
+	if ((i = marker(self)) < 0)
+		return -1;
+
+	Pdata_clear(self->stack, i);
+
+	return 0;
+}
+
+
+static int
+load_dup(Unpicklerobject *self)
+{
+	PyObject *last;
+	int len;
+
+	if ((len = self->stack->length) <= 0) return stackUnderflow();
+	last=self->stack->data[len-1];
+	Py_INCREF(last);
+	PDATA_PUSH(self->stack, last, -1);
+	return 0;
+}
+
+
+static int
+load_get(Unpicklerobject *self)
+{
+	PyObject *py_str = 0, *value = 0;
+	int len;
+	char *s;
+	int rc;
+
+	if ((len = self->readline_func(self, &s)) < 0) return -1;
+	if (len < 2) return bad_readline();
+
+	if (!( py_str = PyString_FromStringAndSize(s, len - 1)))  return -1;
+
+	value = PyDict_GetItem(self->memo, py_str);
+	if (! value) {
+		PyErr_SetObject(BadPickleGet, py_str);
+		rc = -1;
+	}
+	else {
+		PDATA_APPEND(self->stack, value, -1);
+		rc = 0;
+	}
+
+	Py_DECREF(py_str);
+	return rc;
+}
+
+
+static int
+load_binget(Unpicklerobject *self)
+{
+	PyObject *py_key = 0, *value = 0;
+	unsigned char key;
+	char *s;
+	int rc;
+
+	if (self->read_func(self, &s, 1) < 0) return -1;
+
+	key = (unsigned char)s[0];
+	if (!( py_key = PyInt_FromLong((long)key)))  return -1;
+
+	value = PyDict_GetItem(self->memo, py_key);
+	if (! value) {
+		PyErr_SetObject(BadPickleGet, py_key);
+		rc = -1;
+	}
+	else {
+		PDATA_APPEND(self->stack, value, -1);
+		rc = 0;
+	}
+
+	Py_DECREF(py_key);
+	return rc;
+}
+
+
+static int
+load_long_binget(Unpicklerobject *self)
+{
+	PyObject *py_key = 0, *value = 0;
+	unsigned char c;
+	char *s;
+	long key;
+	int rc;
+
+	if (self->read_func(self, &s, 4) < 0) return -1;
+
+	c = (unsigned char)s[0];
+	key = (long)c;
+	c = (unsigned char)s[1];
+	key |= (long)c << 8;
+	c = (unsigned char)s[2];
+	key |= (long)c << 16;
+	c = (unsigned char)s[3];
+	key |= (long)c << 24;
+
+	if (!( py_key = PyInt_FromLong((long)key)))  return -1;
+
+	value = PyDict_GetItem(self->memo, py_key);
+	if (! value) {
+		PyErr_SetObject(BadPickleGet, py_key);
+		rc = -1;
+	}
+	else {
+		PDATA_APPEND(self->stack, value, -1);
+		rc = 0;
+	}
+
+	Py_DECREF(py_key);
+	return rc;
+}
+
+/* Push an object from the extension registry (EXT[124]).  nbytes is
+ * the number of bytes following the opcode, holding the index (code) value.
+ */
+static int
+load_extension(Unpicklerobject *self, int nbytes)
+{
+	char *codebytes;	/* the nbytes bytes after the opcode */
+	long code;		/* calc_binint returns long */
+	PyObject *py_code;	/* code as a Python int */
+	PyObject *obj;		/* the object to push */
+	PyObject *pair;		/* (module_name, class_name) */
+	PyObject *module_name, *class_name;
+
+	assert(nbytes == 1 || nbytes == 2 || nbytes == 4);
+	if (self->read_func(self, &codebytes, nbytes) < 0) return -1;
+	code = calc_binint(codebytes,  nbytes);
+	if (code <= 0) {		/* note that 0 is forbidden */
+		/* Corrupt or hostile pickle. */
+		PyErr_SetString(UnpicklingError, "EXT specifies code <= 0");
+		return -1;
+	}
+
+	/* Look for the code in the cache. */
+	py_code = PyInt_FromLong(code);
+	if (py_code == NULL) return -1;
+	obj = PyDict_GetItem(extension_cache, py_code);
+	if (obj != NULL) {
+		/* Bingo. */
+		Py_DECREF(py_code);
+		PDATA_APPEND(self->stack, obj, -1);
+		return 0;
+	}
+
+	/* Look up the (module_name, class_name) pair. */
+	pair = PyDict_GetItem(inverted_registry, py_code);
+	if (pair == NULL) {
+		Py_DECREF(py_code);
+		PyErr_Format(PyExc_ValueError, "unregistered extension "
+			     "code %ld", code);
+		return -1;
+	}
+	/* Since the extension registry is manipulable via Python code,
+	 * confirm that pair is really a 2-tuple of strings.
+	 */
+	if (!PyTuple_Check(pair) || PyTuple_Size(pair) != 2 ||
+	    !PyString_Check(module_name = PyTuple_GET_ITEM(pair, 0)) ||
+	    !PyString_Check(class_name = PyTuple_GET_ITEM(pair, 1))) {
+		Py_DECREF(py_code);
+		PyErr_Format(PyExc_ValueError, "_inverted_registry[%ld] "
+			     "isn't a 2-tuple of strings", code);
+		return -1;
+	}
+	/* Load the object. */
+	obj = find_class(module_name, class_name, self->find_class);
+	if (obj == NULL) {
+		Py_DECREF(py_code);
+		return -1;
+	}
+	/* Cache code -> obj. */
+	code = PyDict_SetItem(extension_cache, py_code, obj);
+	Py_DECREF(py_code);
+	if (code < 0) {
+		Py_DECREF(obj);
+		return -1;
+	}
+	PDATA_PUSH(self->stack, obj, -1);
+	return 0;
+}
+
+static int
+load_put(Unpicklerobject *self)
+{
+	PyObject *py_str = 0, *value = 0;
+	int len, l;
+	char *s;
+
+	if ((l = self->readline_func(self, &s)) < 0) return -1;
+	if (l < 2) return bad_readline();
+	if (!( len=self->stack->length ))  return stackUnderflow();
+	if (!( py_str = PyString_FromStringAndSize(s, l - 1)))  return -1;
+	value=self->stack->data[len-1];
+	l=PyDict_SetItem(self->memo, py_str, value);
+	Py_DECREF(py_str);
+	return l;
+}
+
+
+static int
+load_binput(Unpicklerobject *self)
+{
+	PyObject *py_key = 0, *value = 0;
+	unsigned char key;
+	char *s;
+	int len;
+
+	if (self->read_func(self, &s, 1) < 0) return -1;
+	if (!( (len=self->stack->length) > 0 ))  return stackUnderflow();
+
+	key = (unsigned char)s[0];
+
+	if (!( py_key = PyInt_FromLong((long)key)))  return -1;
+	value=self->stack->data[len-1];
+	len=PyDict_SetItem(self->memo, py_key, value);
+	Py_DECREF(py_key);
+	return len;
+}
+
+
+static int
+load_long_binput(Unpicklerobject *self)
+{
+	PyObject *py_key = 0, *value = 0;
+	long key;
+	unsigned char c;
+	char *s;
+	int len;
+
+	if (self->read_func(self, &s, 4) < 0) return -1;
+	if (!( len=self->stack->length ))  return stackUnderflow();
+
+	c = (unsigned char)s[0];
+	key = (long)c;
+	c = (unsigned char)s[1];
+	key |= (long)c << 8;
+	c = (unsigned char)s[2];
+	key |= (long)c << 16;
+	c = (unsigned char)s[3];
+	key |= (long)c << 24;
+
+	if (!( py_key = PyInt_FromLong(key)))  return -1;
+	value=self->stack->data[len-1];
+	len=PyDict_SetItem(self->memo, py_key, value);
+	Py_DECREF(py_key);
+	return len;
+}
+
+
+static int
+do_append(Unpicklerobject *self, int  x)
+{
+	PyObject *value = 0, *list = 0, *append_method = 0;
+	int len, i;
+
+	len=self->stack->length;
+	if (!( len >= x && x > 0 ))  return stackUnderflow();
+	/* nothing to do */
+	if (len==x) return 0;
+
+	list=self->stack->data[x-1];
+
+	if (PyList_Check(list)) {
+		PyObject *slice;
+		int list_len;
+
+		slice=Pdata_popList(self->stack, x);
+		if (! slice) return -1;
+		list_len = PyList_GET_SIZE(list);
+		i=PyList_SetSlice(list, list_len, list_len, slice);
+		Py_DECREF(slice);
+		return i;
+	}
+	else {
+
+		if (!( append_method = PyObject_GetAttr(list, append_str)))
+			return -1;
+
+		for (i = x; i < len; i++) {
+			PyObject *junk;
+
+			value=self->stack->data[i];
+			junk=0;
+			ARG_TUP(self, value);
+			if (self->arg) {
+				junk = PyObject_Call(append_method, self->arg,
+						     NULL);
+				FREE_ARG_TUP(self);
+			}
+			if (! junk) {
+				Pdata_clear(self->stack, i+1);
+				self->stack->length=x;
+				Py_DECREF(append_method);
+				return -1;
+			}
+			Py_DECREF(junk);
+		}
+		self->stack->length=x;
+		Py_DECREF(append_method);
+	}
+
+	return 0;
+}
+
+
+static int
+load_append(Unpicklerobject *self)
+{
+	return do_append(self, self->stack->length - 1);
+}
+
+
+static int
+load_appends(Unpicklerobject *self)
+{
+	return do_append(self, marker(self));
+}
+
+
+static int
+do_setitems(Unpicklerobject *self, int  x)
+{
+	PyObject *value = 0, *key = 0, *dict = 0;
+	int len, i, r=0;
+
+	if (!( (len=self->stack->length) >= x
+	       && x > 0 ))  return stackUnderflow();
+
+	dict=self->stack->data[x-1];
+
+	for (i = x+1; i < len; i += 2) {
+		key  =self->stack->data[i-1];
+		value=self->stack->data[i  ];
+		if (PyObject_SetItem(dict, key, value) < 0) {
+			r=-1;
+			break;
+		}
+	}
+
+	Pdata_clear(self->stack, x);
+
+	return r;
+}
+
+
+static int
+load_setitem(Unpicklerobject *self)
+{
+	return do_setitems(self, self->stack->length - 2);
+}
+
+static int
+load_setitems(Unpicklerobject *self)
+{
+	return do_setitems(self, marker(self));
+}
+
+
+static int
+load_build(Unpicklerobject *self)
+{
+	PyObject *state, *inst, *slotstate;
+	PyObject *__setstate__;
+	PyObject *d_key, *d_value;
+	Py_ssize_t i;
+	int res = -1;
+
+	/* Stack is ... instance, state.  We want to leave instance at
+	 * the stack top, possibly mutated via instance.__setstate__(state).
+	 */
+	if (self->stack->length < 2)
+		return stackUnderflow();
+	PDATA_POP(self->stack, state);
+	if (state == NULL)
+		return -1;
+	inst = self->stack->data[self->stack->length - 1];
+
+	__setstate__ = PyObject_GetAttr(inst, __setstate___str);
+	if (__setstate__ != NULL) {
+		PyObject *junk = NULL;
+
+		/* The explicit __setstate__ is responsible for everything. */
+		ARG_TUP(self, state);
+		if (self->arg) {
+			junk = PyObject_Call(__setstate__, self->arg, NULL);
+			FREE_ARG_TUP(self);
+		}
+		Py_DECREF(__setstate__);
+		if (junk == NULL)
+			return -1;
+		Py_DECREF(junk);
+		return 0;
+	}
+	if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+		return -1;
+	PyErr_Clear();
+
+	/* A default __setstate__.  First see whether state embeds a
+	 * slot state dict too (a proto 2 addition).
+	 */
+	if (PyTuple_Check(state) && PyTuple_Size(state) == 2) {
+		PyObject *temp = state;
+		state = PyTuple_GET_ITEM(temp, 0);
+		slotstate = PyTuple_GET_ITEM(temp, 1);
+		Py_INCREF(state);
+		Py_INCREF(slotstate);
+		Py_DECREF(temp);
+	}
+	else
+		slotstate = NULL;
+
+	/* Set inst.__dict__ from the state dict (if any). */
+	if (state != Py_None) {
+		PyObject *dict;
+		if (! PyDict_Check(state)) {
+			PyErr_SetString(UnpicklingError, "state is not a "
+					"dictionary");
+			goto finally;
+		}
+		dict = PyObject_GetAttr(inst, __dict___str);
+		if (dict == NULL)
+			goto finally;
+
+		i = 0;
+		while (PyDict_Next(state, &i, &d_key, &d_value)) {
+			if (PyObject_SetItem(dict, d_key, d_value) < 0)
+				goto finally;
+		}
+		Py_DECREF(dict);
+	}
+
+	/* Also set instance attributes from the slotstate dict (if any). */
+	if (slotstate != NULL) {
+		if (! PyDict_Check(slotstate)) {
+			PyErr_SetString(UnpicklingError, "slot state is not "
+					"a dictionary");
+			goto finally;
+		}
+		i = 0;
+		while (PyDict_Next(slotstate, &i, &d_key, &d_value)) {
+			if (PyObject_SetAttr(inst, d_key, d_value) < 0)
+				goto finally;
+		}
+	}
+	res = 0;
+
+  finally:
+	Py_DECREF(state);
+	Py_XDECREF(slotstate);
+	return res;
+}
+
+
+static int
+load_mark(Unpicklerobject *self)
+{
+	int s;
+
+	/* Note that we split the (pickle.py) stack into two stacks, an
+	   object stack and a mark stack. Here we push a mark onto the
+	   mark stack.
+	*/
+
+	if ((self->num_marks + 1) >= self->marks_size) {
+		s=self->marks_size+20;
+		if (s <= self->num_marks) s=self->num_marks + 1;
+		if (self->marks == NULL)
+			self->marks=(int *)malloc(s * sizeof(int));
+		else
+			self->marks=(int *)realloc(self->marks,
+						   s * sizeof(int));
+		if (! self->marks) {
+			PyErr_NoMemory();
+			return -1;
+		}
+		self->marks_size = s;
+	}
+
+	self->marks[self->num_marks++] = self->stack->length;
+
+	return 0;
+}
+
+static int
+load_reduce(Unpicklerobject *self)
+{
+	PyObject *callable = 0, *arg_tup = 0, *ob = 0;
+
+	PDATA_POP(self->stack, arg_tup);
+	if (! arg_tup) return -1;
+	PDATA_POP(self->stack, callable);
+	if (callable) {
+		ob = Instance_New(callable, arg_tup);
+		Py_DECREF(callable);
+	}
+	Py_DECREF(arg_tup);
+
+	if (! ob) return -1;
+
+	PDATA_PUSH(self->stack, ob, -1);
+	return 0;
+}
+
+/* Just raises an error if we don't know the protocol specified.  PROTO
+ * is the first opcode for protocols >= 2.
+ */
+static int
+load_proto(Unpicklerobject *self)
+{
+	int i;
+	char *protobyte;
+
+	i = self->read_func(self, &protobyte, 1);
+	if (i < 0)
+		return -1;
+
+	i = calc_binint(protobyte, 1);
+	/* No point checking for < 0, since calc_binint returns an unsigned
+	 * int when chewing on 1 byte.
+	 */
+	assert(i >= 0);
+	if (i <= HIGHEST_PROTOCOL)
+		return 0;
+
+	PyErr_Format(PyExc_ValueError, "unsupported pickle protocol: %d", i);
+	return -1;
+}
+
+static PyObject *
+load(Unpicklerobject *self)
+{
+	PyObject *err = 0, *val = 0;
+	char *s;
+
+	self->num_marks = 0;
+	if (self->stack->length) Pdata_clear(self->stack, 0);
+
+	while (1) {
+		if (self->read_func(self, &s, 1) < 0)
+			break;
+
+		switch (s[0]) {
+		case NONE:
+			if (load_none(self) < 0)
+				break;
+			continue;
+
+		case BININT:
+			if (load_binint(self) < 0)
+				break;
+			continue;
+
+		case BININT1:
+			if (load_binint1(self) < 0)
+				break;
+			continue;
+
+		case BININT2:
+			if (load_binint2(self) < 0)
+				break;
+			continue;
+
+		case INT:
+			if (load_int(self) < 0)
+				break;
+			continue;
+
+		case LONG:
+			if (load_long(self) < 0)
+				break;
+			continue;
+
+		case LONG1:
+			if (load_counted_long(self, 1) < 0)
+				break;
+			continue;
+
+		case LONG4:
+			if (load_counted_long(self, 4) < 0)
+				break;
+			continue;
+
+		case FLOAT:
+			if (load_float(self) < 0)
+				break;
+			continue;
+
+		case BINFLOAT:
+			if (load_binfloat(self) < 0)
+				break;
+			continue;
+
+		case BINSTRING:
+			if (load_binstring(self) < 0)
+				break;
+			continue;
+
+		case SHORT_BINSTRING:
+			if (load_short_binstring(self) < 0)
+				break;
+			continue;
+
+		case STRING:
+			if (load_string(self) < 0)
+				break;
+			continue;
+
+#ifdef Py_USING_UNICODE
+		case UNICODE:
+			if (load_unicode(self) < 0)
+				break;
+			continue;
+
+		case BINUNICODE:
+			if (load_binunicode(self) < 0)
+				break;
+			continue;
+#endif
+
+		case EMPTY_TUPLE:
+			if (load_counted_tuple(self, 0) < 0)
+				break;
+			continue;
+
+		case TUPLE1:
+			if (load_counted_tuple(self, 1) < 0)
+				break;
+			continue;
+
+		case TUPLE2:
+			if (load_counted_tuple(self, 2) < 0)
+				break;
+			continue;
+
+		case TUPLE3:
+			if (load_counted_tuple(self, 3) < 0)
+				break;
+			continue;
+
+		case TUPLE:
+			if (load_tuple(self) < 0)
+				break;
+			continue;
+
+		case EMPTY_LIST:
+			if (load_empty_list(self) < 0)
+				break;
+			continue;
+
+		case LIST:
+			if (load_list(self) < 0)
+				break;
+			continue;
+
+		case EMPTY_DICT:
+			if (load_empty_dict(self) < 0)
+				break;
+			continue;
+
+		case DICT:
+			if (load_dict(self) < 0)
+				break;
+			continue;
+
+		case OBJ:
+			if (load_obj(self) < 0)
+				break;
+			continue;
+
+		case INST:
+			if (load_inst(self) < 0)
+				break;
+			continue;
+
+		case NEWOBJ:
+			if (load_newobj(self) < 0)
+				break;
+			continue;
+
+		case GLOBAL:
+			if (load_global(self) < 0)
+				break;
+			continue;
+
+		case APPEND:
+			if (load_append(self) < 0)
+				break;
+			continue;
+
+		case APPENDS:
+			if (load_appends(self) < 0)
+				break;
+			continue;
+
+		case BUILD:
+			if (load_build(self) < 0)
+				break;
+			continue;
+
+		case DUP:
+			if (load_dup(self) < 0)
+				break;
+			continue;
+
+		case BINGET:
+			if (load_binget(self) < 0)
+				break;
+			continue;
+
+		case LONG_BINGET:
+			if (load_long_binget(self) < 0)
+				break;
+			continue;
+
+		case GET:
+			if (load_get(self) < 0)
+				break;
+			continue;
+
+		case EXT1:
+			if (load_extension(self, 1) < 0)
+				break;
+			continue;
+
+		case EXT2:
+			if (load_extension(self, 2) < 0)
+				break;
+			continue;
+
+		case EXT4:
+			if (load_extension(self, 4) < 0)
+				break;
+			continue;
+		case MARK:
+			if (load_mark(self) < 0)
+				break;
+			continue;
+
+		case BINPUT:
+			if (load_binput(self) < 0)
+				break;
+			continue;
+
+		case LONG_BINPUT:
+			if (load_long_binput(self) < 0)
+				break;
+			continue;
+
+		case PUT:
+			if (load_put(self) < 0)
+				break;
+			continue;
+
+		case POP:
+			if (load_pop(self) < 0)
+				break;
+			continue;
+
+		case POP_MARK:
+			if (load_pop_mark(self) < 0)
+				break;
+			continue;
+
+		case SETITEM:
+			if (load_setitem(self) < 0)
+				break;
+			continue;
+
+		case SETITEMS:
+			if (load_setitems(self) < 0)
+				break;
+			continue;
+
+		case STOP:
+			break;
+
+		case PERSID:
+			if (load_persid(self) < 0)
+				break;
+			continue;
+
+		case BINPERSID:
+			if (load_binpersid(self) < 0)
+				break;
+			continue;
+
+		case REDUCE:
+			if (load_reduce(self) < 0)
+				break;
+			continue;
+
+		case PROTO:
+			if (load_proto(self) < 0)
+				break;
+			continue;
+
+		case NEWTRUE:
+			if (load_bool(self, Py_True) < 0)
+				break;
+			continue;
+
+		case NEWFALSE:
+			if (load_bool(self, Py_False) < 0)
+				break;
+			continue;
+
+		case '\0':
+			/* end of file */
+			PyErr_SetNone(PyExc_EOFError);
+			break;
+
+		default:
+			cPickle_ErrFormat(UnpicklingError,
+					  "invalid load key, '%s'.",
+					  "c", s[0]);
+			return NULL;
+		}
+
+		break;
+	}
+
+	if ((err = PyErr_Occurred())) {
+		if (err == PyExc_EOFError) {
+			PyErr_SetNone(PyExc_EOFError);
+		}
+		return NULL;
+	}
+
+	PDATA_POP(self->stack, val);
+	return val;
+}
+
+
+/* No-load functions to support noload, which is used to
+   find persistent references. */
+
+static int
+noload_obj(Unpicklerobject *self)
+{
+	int i;
+
+	if ((i = marker(self)) < 0) return -1;
+	return Pdata_clear(self->stack, i+1);
+}
+
+
+static int
+noload_inst(Unpicklerobject *self)
+{
+	int i;
+	char *s;
+
+	if ((i = marker(self)) < 0) return -1;
+	Pdata_clear(self->stack, i);
+	if (self->readline_func(self, &s) < 0) return -1;
+	if (self->readline_func(self, &s) < 0) return -1;
+	PDATA_APPEND(self->stack, Py_None, -1);
+	return 0;
+}
+
+static int
+noload_newobj(Unpicklerobject *self)
+{
+	PyObject *obj;
+
+	PDATA_POP(self->stack, obj);	/* pop argtuple */
+	if (obj == NULL) return -1;
+	Py_DECREF(obj);
+
+	PDATA_POP(self->stack, obj);	/* pop cls */
+	if (obj == NULL) return -1;
+	Py_DECREF(obj);
+
+	PDATA_APPEND(self->stack, Py_None, -1);
+ 	return 0;
+}
+
+static int
+noload_global(Unpicklerobject *self)
+{
+	char *s;
+
+	if (self->readline_func(self, &s) < 0) return -1;
+	if (self->readline_func(self, &s) < 0) return -1;
+	PDATA_APPEND(self->stack, Py_None,-1);
+	return 0;
+}
+
+static int
+noload_reduce(Unpicklerobject *self)
+{
+
+	if (self->stack->length < 2) return stackUnderflow();
+	Pdata_clear(self->stack, self->stack->length-2);
+	PDATA_APPEND(self->stack, Py_None,-1);
+	return 0;
+}
+
+static int
+noload_build(Unpicklerobject *self) {
+
+  if (self->stack->length < 1) return stackUnderflow();
+  Pdata_clear(self->stack, self->stack->length-1);
+  return 0;
+}
+
+static int
+noload_extension(Unpicklerobject *self, int nbytes)
+{
+	char *codebytes;
+
+	assert(nbytes == 1 || nbytes == 2 || nbytes == 4);
+	if (self->read_func(self, &codebytes, nbytes) < 0) return -1;
+	PDATA_APPEND(self->stack, Py_None, -1);
+	return 0;
+}
+
+
+static PyObject *
+noload(Unpicklerobject *self)
+{
+	PyObject *err = 0, *val = 0;
+	char *s;
+
+	self->num_marks = 0;
+	Pdata_clear(self->stack, 0);
+
+	while (1) {
+		if (self->read_func(self, &s, 1) < 0)
+			break;
+
+		switch (s[0]) {
+		case NONE:
+			if (load_none(self) < 0)
+				break;
+			continue;
+
+		case BININT:
+			if (load_binint(self) < 0)
+				break;
+			continue;
+
+		case BININT1:
+			if (load_binint1(self) < 0)
+				break;
+			continue;
+
+		case BININT2:
+			if (load_binint2(self) < 0)
+				break;
+			continue;
+
+		case INT:
+			if (load_int(self) < 0)
+				break;
+			continue;
+
+		case LONG:
+			if (load_long(self) < 0)
+				break;
+			continue;
+
+		case LONG1:
+			if (load_counted_long(self, 1) < 0)
+				break;
+			continue;
+
+		case LONG4:
+			if (load_counted_long(self, 4) < 0)
+				break;
+			continue;
+
+		case FLOAT:
+			if (load_float(self) < 0)
+				break;
+			continue;
+
+		case BINFLOAT:
+			if (load_binfloat(self) < 0)
+				break;
+			continue;
+
+		case BINSTRING:
+			if (load_binstring(self) < 0)
+				break;
+			continue;
+
+		case SHORT_BINSTRING:
+			if (load_short_binstring(self) < 0)
+				break;
+			continue;
+
+		case STRING:
+			if (load_string(self) < 0)
+				break;
+			continue;
+
+#ifdef Py_USING_UNICODE
+		case UNICODE:
+			if (load_unicode(self) < 0)
+				break;
+			continue;
+
+		case BINUNICODE:
+			if (load_binunicode(self) < 0)
+				break;
+			continue;
+#endif
+
+		case EMPTY_TUPLE:
+			if (load_counted_tuple(self, 0) < 0)
+				break;
+			continue;
+
+		case TUPLE1:
+			if (load_counted_tuple(self, 1) < 0)
+				break;
+			continue;
+
+		case TUPLE2:
+			if (load_counted_tuple(self, 2) < 0)
+				break;
+			continue;
+
+		case TUPLE3:
+			if (load_counted_tuple(self, 3) < 0)
+				break;
+			continue;
+
+		case TUPLE:
+			if (load_tuple(self) < 0)
+				break;
+			continue;
+
+		case EMPTY_LIST:
+			if (load_empty_list(self) < 0)
+				break;
+			continue;
+
+		case LIST:
+			if (load_list(self) < 0)
+				break;
+			continue;
+
+		case EMPTY_DICT:
+			if (load_empty_dict(self) < 0)
+				break;
+			continue;
+
+		case DICT:
+			if (load_dict(self) < 0)
+				break;
+			continue;
+
+		case OBJ:
+			if (noload_obj(self) < 0)
+				break;
+			continue;
+
+		case INST:
+			if (noload_inst(self) < 0)
+				break;
+			continue;
+
+		case NEWOBJ:
+			if (noload_newobj(self) < 0)
+				break;
+			continue;
+
+		case GLOBAL:
+			if (noload_global(self) < 0)
+				break;
+			continue;
+
+		case APPEND:
+			if (load_append(self) < 0)
+				break;
+			continue;
+
+		case APPENDS:
+			if (load_appends(self) < 0)
+				break;
+			continue;
+
+		case BUILD:
+			if (noload_build(self) < 0)
+				break;
+			continue;
+
+		case DUP:
+			if (load_dup(self) < 0)
+				break;
+			continue;
+
+		case BINGET:
+			if (load_binget(self) < 0)
+				break;
+			continue;
+
+		case LONG_BINGET:
+			if (load_long_binget(self) < 0)
+				break;
+			continue;
+
+		case GET:
+			if (load_get(self) < 0)
+				break;
+			continue;
+
+		case EXT1:
+			if (noload_extension(self, 1) < 0)
+				break;
+			continue;
+
+		case EXT2:
+			if (noload_extension(self, 2) < 0)
+				break;
+			continue;
+
+		case EXT4:
+			if (noload_extension(self, 4) < 0)
+				break;
+			continue;
+
+		case MARK:
+			if (load_mark(self) < 0)
+				break;
+			continue;
+
+		case BINPUT:
+			if (load_binput(self) < 0)
+				break;
+			continue;
+
+		case LONG_BINPUT:
+			if (load_long_binput(self) < 0)
+				break;
+			continue;
+
+		case PUT:
+			if (load_put(self) < 0)
+				break;
+			continue;
+
+		case POP:
+			if (load_pop(self) < 0)
+				break;
+			continue;
+
+		case POP_MARK:
+			if (load_pop_mark(self) < 0)
+				break;
+			continue;
+
+		case SETITEM:
+			if (load_setitem(self) < 0)
+				break;
+			continue;
+
+		case SETITEMS:
+			if (load_setitems(self) < 0)
+				break;
+			continue;
+
+		case STOP:
+			break;
+
+		case PERSID:
+			if (load_persid(self) < 0)
+				break;
+			continue;
+
+		case BINPERSID:
+			if (load_binpersid(self) < 0)
+				break;
+			continue;
+
+		case REDUCE:
+			if (noload_reduce(self) < 0)
+				break;
+			continue;
+
+		case PROTO:
+			if (load_proto(self) < 0)
+				break;
+			continue;
+
+		case NEWTRUE:
+			if (load_bool(self, Py_True) < 0)
+				break;
+			continue;
+
+		case NEWFALSE:
+			if (load_bool(self, Py_False) < 0)
+				break;
+			continue;
+		default:
+			cPickle_ErrFormat(UnpicklingError,
+					  "invalid load key, '%s'.",
+					  "c", s[0]);
+			return NULL;
+		}
+
+		break;
+	}
+
+	if ((err = PyErr_Occurred())) {
+		if (err == PyExc_EOFError) {
+			PyErr_SetNone(PyExc_EOFError);
+		}
+		return NULL;
+	}
+
+	PDATA_POP(self->stack, val);
+	return val;
+}
+
+
+static PyObject *
+Unpickler_load(Unpicklerobject *self, PyObject *unused)
+{
+	return load(self);
+}
+
+static PyObject *
+Unpickler_noload(Unpicklerobject *self, PyObject *unused)
+{
+	return noload(self);
+}
+
+
+static struct PyMethodDef Unpickler_methods[] = {
+  {"load",         (PyCFunction)Unpickler_load,   METH_NOARGS,
+   PyDoc_STR("load() -- Load a pickle")
+  },
+  {"noload",         (PyCFunction)Unpickler_noload,   METH_NOARGS,
+   PyDoc_STR(
+   "noload() -- not load a pickle, but go through most of the motions\n"
+   "\n"
+   "This function can be used to read past a pickle without instantiating\n"
+   "any objects or importing any modules.  It can also be used to find all\n"
+   "persistent references without instantiating any objects or importing\n"
+   "any modules.\n")
+  },
+  {NULL,              NULL}           /* sentinel */
+};
+
+
+static Unpicklerobject *
+newUnpicklerobject(PyObject *f)
+{
+	Unpicklerobject *self;
+
+	if (!( self = PyObject_GC_New(Unpicklerobject, &Unpicklertype)))
+		return NULL;
+
+	self->file = NULL;
+	self->arg = NULL;
+	self->stack = (Pdata*)Pdata_New();
+	self->pers_func = NULL;
+	self->last_string = NULL;
+	self->marks = NULL;
+	self->num_marks = 0;
+	self->marks_size = 0;
+	self->buf_size = 0;
+	self->read = NULL;
+	self->readline = NULL;
+	self->find_class = NULL;
+
+	if (!( self->memo = PyDict_New()))
+		goto err;
+
+	if (!self->stack)
+		goto err;
+
+	Py_INCREF(f);
+	self->file = f;
+
+	/* Set read, readline based on type of f */
+	if (PyFile_Check(f)) {
+		self->fp = PyFile_AsFile(f);
+		if (self->fp == NULL) {
+			PyErr_SetString(PyExc_ValueError,
+					"I/O operation on closed file");
+			goto err;
+		}
+		self->read_func = read_file;
+		self->readline_func = readline_file;
+	}
+	else if (PycStringIO_InputCheck(f)) {
+		self->fp = NULL;
+		self->read_func = read_cStringIO;
+		self->readline_func = readline_cStringIO;
+	}
+	else {
+
+		self->fp = NULL;
+		self->read_func = read_other;
+		self->readline_func = readline_other;
+
+		if (!( (self->readline = PyObject_GetAttr(f, readline_str)) &&
+		       (self->read = PyObject_GetAttr(f, read_str))))  {
+			PyErr_Clear();
+			PyErr_SetString( PyExc_TypeError,
+					 "argument must have 'read' and "
+					 "'readline' attributes" );
+			goto err;
+		}
+	}
+	PyObject_GC_Track(self);
+
+	return self;
+
+  err:
+	Py_DECREF((PyObject *)self);
+	return NULL;
+}
+
+
+static PyObject *
+get_Unpickler(PyObject *self, PyObject *file)
+{
+	return (PyObject *)newUnpicklerobject(file);
+}
+
+
+static void
+Unpickler_dealloc(Unpicklerobject *self)
+{
+	PyObject_GC_UnTrack((PyObject *)self);
+	Py_XDECREF(self->readline);
+	Py_XDECREF(self->read);
+	Py_XDECREF(self->file);
+	Py_XDECREF(self->memo);
+	Py_XDECREF(self->stack);
+	Py_XDECREF(self->pers_func);
+	Py_XDECREF(self->arg);
+	Py_XDECREF(self->last_string);
+	Py_XDECREF(self->find_class);
+
+	if (self->marks) {
+		free(self->marks);
+	}
+
+	if (self->buf_size) {
+		free(self->buf);
+	}
+
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+static int
+Unpickler_traverse(Unpicklerobject *self, visitproc visit, void *arg)
+{
+	Py_VISIT(self->readline);
+	Py_VISIT(self->read);
+	Py_VISIT(self->file);
+	Py_VISIT(self->memo);
+	Py_VISIT(self->stack);
+	Py_VISIT(self->pers_func);
+	Py_VISIT(self->arg);
+	Py_VISIT(self->last_string);
+	Py_VISIT(self->find_class);
+	return 0;
+}
+
+static int
+Unpickler_clear(Unpicklerobject *self)
+{
+	Py_CLEAR(self->readline);
+	Py_CLEAR(self->read);
+	Py_CLEAR(self->file);
+	Py_CLEAR(self->memo);
+	Py_CLEAR(self->stack);
+	Py_CLEAR(self->pers_func);
+	Py_CLEAR(self->arg);
+	Py_CLEAR(self->last_string);
+	Py_CLEAR(self->find_class);
+	return 0;
+}
+
+static PyObject *
+Unpickler_getattr(Unpicklerobject *self, char *name)
+{
+	if (!strcmp(name, "persistent_load")) {
+		if (!self->pers_func) {
+			PyErr_SetString(PyExc_AttributeError, name);
+			return NULL;
+		}
+
+		Py_INCREF(self->pers_func);
+		return self->pers_func;
+	}
+
+	if (!strcmp(name, "find_global")) {
+		if (!self->find_class) {
+			PyErr_SetString(PyExc_AttributeError, name);
+			return NULL;
+		}
+
+		Py_INCREF(self->find_class);
+		return self->find_class;
+	}
+
+	if (!strcmp(name, "memo")) {
+		if (!self->memo) {
+			PyErr_SetString(PyExc_AttributeError, name);
+			return NULL;
+		}
+
+		Py_INCREF(self->memo);
+		return self->memo;
+	}
+
+	if (!strcmp(name, "UnpicklingError")) {
+		Py_INCREF(UnpicklingError);
+		return UnpicklingError;
+	}
+
+	return Py_FindMethod(Unpickler_methods, (PyObject *)self, name);
+}
+
+
+static int
+Unpickler_setattr(Unpicklerobject *self, char *name, PyObject *value)
+{
+
+	if (!strcmp(name, "persistent_load")) {
+		Py_XDECREF(self->pers_func);
+		self->pers_func = value;
+		Py_XINCREF(value);
+		return 0;
+	}
+
+	if (!strcmp(name, "find_global")) {
+		Py_XDECREF(self->find_class);
+		self->find_class = value;
+		Py_XINCREF(value);
+		return 0;
+	}
+
+	if (! value) {
+		PyErr_SetString(PyExc_TypeError,
+				"attribute deletion is not supported");
+		return -1;
+	}
+
+	if (strcmp(name, "memo") == 0) {
+		if (!PyDict_Check(value)) {
+			PyErr_SetString(PyExc_TypeError,
+					"memo must be a dictionary");
+			return -1;
+		}
+		Py_XDECREF(self->memo);
+		self->memo = value;
+		Py_INCREF(value);
+		return 0;
+	}
+
+	PyErr_SetString(PyExc_AttributeError, name);
+	return -1;
+}
+
+/* ---------------------------------------------------------------------------
+ * Module-level functions.
+ */
+
+/* dump(obj, file, protocol=0). */
+static PyObject *
+cpm_dump(PyObject *self, PyObject *args, PyObject *kwds)
+{
+	static char *kwlist[] = {"obj", "file", "protocol", NULL};
+	PyObject *ob, *file, *res = NULL;
+	Picklerobject *pickler = 0;
+	int proto = 0;
+
+	if (!( PyArg_ParseTupleAndKeywords(args, kwds, "OO|i", kwlist,
+		   &ob, &file, &proto)))
+		goto finally;
+
+	if (!( pickler = newPicklerobject(file, proto)))
+		goto finally;
+
+	if (dump(pickler, ob) < 0)
+		goto finally;
+
+	Py_INCREF(Py_None);
+	res = Py_None;
+
+  finally:
+	Py_XDECREF(pickler);
+
+	return res;
+}
+
+
+/* dumps(obj, protocol=0). */
+static PyObject *
+cpm_dumps(PyObject *self, PyObject *args, PyObject *kwds)
+{
+	static char *kwlist[] = {"obj", "protocol", NULL};
+	PyObject *ob, *file = 0, *res = NULL;
+	Picklerobject *pickler = 0;
+	int proto = 0;
+
+	if (!( PyArg_ParseTupleAndKeywords(args, kwds, "O|i:dumps", kwlist,
+		   &ob, &proto)))
+		goto finally;
+
+	if (!( file = PycStringIO->NewOutput(128)))
+		goto finally;
+
+	if (!( pickler = newPicklerobject(file, proto)))
+		goto finally;
+
+	if (dump(pickler, ob) < 0)
+		goto finally;
+
+	res = PycStringIO->cgetvalue(file);
+
+  finally:
+	Py_XDECREF(pickler);
+	Py_XDECREF(file);
+
+	return res;
+}
+
+
+/* load(fileobj). */
+static PyObject *
+cpm_load(PyObject *self, PyObject *ob)
+{
+	Unpicklerobject *unpickler = 0;
+	PyObject *res = NULL;
+
+	if (!( unpickler = newUnpicklerobject(ob)))
+		goto finally;
+
+	res = load(unpickler);
+
+  finally:
+	Py_XDECREF(unpickler);
+
+	return res;
+}
+
+
+/* loads(string) */
+static PyObject *
+cpm_loads(PyObject *self, PyObject *args)
+{
+	PyObject *ob, *file = 0, *res = NULL;
+	Unpicklerobject *unpickler = 0;
+
+	if (!( PyArg_ParseTuple(args, "S:loads", &ob)))
+		goto finally;
+
+	if (!( file = PycStringIO->NewInput(ob)))
+		goto finally;
+
+	if (!( unpickler = newUnpicklerobject(file)))
+		goto finally;
+
+	res = load(unpickler);
+
+  finally:
+	Py_XDECREF(file);
+	Py_XDECREF(unpickler);
+
+	return res;
+}
+
+
+PyDoc_STRVAR(Unpicklertype__doc__,
+"Objects that know how to unpickle");
+
+static PyTypeObject Unpicklertype = {
+    PyObject_HEAD_INIT(NULL)
+    0,                          	 /*ob_size*/
+    "cPickle.Unpickler", 	         /*tp_name*/
+    sizeof(Unpicklerobject),             /*tp_basicsize*/
+    0,
+    (destructor)Unpickler_dealloc,	/* tp_dealloc */
+    0,					/* tp_print */
+    (getattrfunc)Unpickler_getattr,	/* tp_getattr */
+    (setattrfunc)Unpickler_setattr,	/* tp_setattr */
+    0,					/* tp_compare */
+    0,		 			/* tp_repr */
+    0,					/* tp_as_number */
+    0,					/* tp_as_sequence */
+    0,					/* tp_as_mapping */
+    0,					/* tp_hash */
+    0,					/* tp_call */
+    0,					/* tp_str */
+    0,					/* tp_getattro */
+    0,					/* tp_setattro */
+    0,					/* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
+    Unpicklertype__doc__,		/* tp_doc */
+    (traverseproc)Unpickler_traverse,	/* tp_traverse */
+    (inquiry)Unpickler_clear,		/* tp_clear */
+};
+
+static struct PyMethodDef cPickle_methods[] = {
+  {"dump",         (PyCFunction)cpm_dump,         METH_VARARGS | METH_KEYWORDS,
+   PyDoc_STR("dump(obj, file, protocol=0) -- "
+   "Write an object in pickle format to the given file.\n"
+   "\n"
+   "See the Pickler docstring for the meaning of optional argument proto.")
+  },
+
+  {"dumps",        (PyCFunction)cpm_dumps,        METH_VARARGS | METH_KEYWORDS,
+   PyDoc_STR("dumps(obj, protocol=0) -- "
+   "Return a string containing an object in pickle format.\n"
+   "\n"
+   "See the Pickler docstring for the meaning of optional argument proto.")
+  },
+
+  {"load",         (PyCFunction)cpm_load,         METH_O,
+   PyDoc_STR("load(file) -- Load a pickle from the given file")},
+
+  {"loads",        (PyCFunction)cpm_loads,        METH_VARARGS,
+   PyDoc_STR("loads(string) -- Load a pickle from the given string")},
+
+  {"Pickler",      (PyCFunction)get_Pickler,      METH_VARARGS | METH_KEYWORDS,
+   PyDoc_STR("Pickler(file, protocol=0) -- Create a pickler.\n"
+   "\n"
+   "This takes a file-like object for writing a pickle data stream.\n"
+   "The optional proto argument tells the pickler to use the given\n"
+   "protocol; supported protocols are 0, 1, 2.  The default\n"
+   "protocol is 0, to be backwards compatible.  (Protocol 0 is the\n"
+   "only protocol that can be written to a file opened in text\n"
+   "mode and read back successfully.  When using a protocol higher\n"
+   "than 0, make sure the file is opened in binary mode, both when\n"
+   "pickling and unpickling.)\n"
+   "\n"
+   "Protocol 1 is more efficient than protocol 0; protocol 2 is\n"
+   "more efficient than protocol 1.\n"
+   "\n"
+   "Specifying a negative protocol version selects the highest\n"
+   "protocol version supported.  The higher the protocol used, the\n"
+   "more recent the version of Python needed to read the pickle\n"
+   "produced.\n"
+   "\n"
+   "The file parameter must have a write() method that accepts a single\n"
+   "string argument.  It can thus be an open file object, a StringIO\n"
+   "object, or any other custom object that meets this interface.\n")
+  },
+
+  {"Unpickler",    (PyCFunction)get_Unpickler,    METH_O,
+   PyDoc_STR("Unpickler(file) -- Create an unpickler.")},
+
+  { NULL, NULL }
+};
+
+static int
+init_stuff(PyObject *module_dict)
+{
+	PyObject *copy_reg, *t, *r;
+
+#define INIT_STR(S) if (!( S ## _str=PyString_InternFromString(#S)))  return -1;
+
+	if (PyType_Ready(&Unpicklertype) < 0)
+		return -1;
+	if (PyType_Ready(&Picklertype) < 0)
+		return -1;
+
+	INIT_STR(__class__);
+	INIT_STR(__getinitargs__);
+	INIT_STR(__dict__);
+	INIT_STR(__getstate__);
+	INIT_STR(__setstate__);
+	INIT_STR(__name__);
+	INIT_STR(__main__);
+	INIT_STR(__reduce__);
+	INIT_STR(__reduce_ex__);
+	INIT_STR(write);
+	INIT_STR(append);
+	INIT_STR(read);
+	INIT_STR(readline);
+	INIT_STR(copy_reg);
+	INIT_STR(dispatch_table);
+
+	if (!( copy_reg = PyImport_ImportModule("copy_reg")))
+		return -1;
+
+	/* This is special because we want to use a different
+	   one in restricted mode. */
+	dispatch_table = PyObject_GetAttr(copy_reg, dispatch_table_str);
+	if (!dispatch_table) return -1;
+
+	extension_registry = PyObject_GetAttrString(copy_reg,
+				"_extension_registry");
+	if (!extension_registry) return -1;
+
+	inverted_registry = PyObject_GetAttrString(copy_reg,
+				"_inverted_registry");
+	if (!inverted_registry) return -1;
+
+	extension_cache = PyObject_GetAttrString(copy_reg,
+				"_extension_cache");
+	if (!extension_cache) return -1;
+
+	Py_DECREF(copy_reg);
+
+	if (!(empty_tuple = PyTuple_New(0)))
+		return -1;
+
+	two_tuple = PyTuple_New(2);
+	if (two_tuple == NULL)
+		return -1;
+	/* We use this temp container with no regard to refcounts, or to
+	 * keeping containees alive.  Exempt from GC, because we don't
+	 * want anything looking at two_tuple() by magic.
+	 */
+	PyObject_GC_UnTrack(two_tuple);
+
+	/* Ugh */
+	if (!( t=PyImport_ImportModule("__builtin__")))  return -1;
+	if (PyDict_SetItemString(module_dict, "__builtins__", t) < 0)
+		return -1;
+
+	if (!( t=PyDict_New()))  return -1;
+	if (!( r=PyRun_String(
+		       "def __str__(self):\n"
+		       "  return self.args and ('%s' % self.args[0]) or '(what)'\n",
+		       Py_file_input,
+		       module_dict, t)  ))  return -1;
+	Py_DECREF(r);
+
+	PickleError = PyErr_NewException("cPickle.PickleError", NULL, t);
+	if (!PickleError)
+		return -1;
+
+	Py_DECREF(t);
+
+	PicklingError = PyErr_NewException("cPickle.PicklingError",
+					   PickleError, NULL);
+	if (!PicklingError)
+		return -1;
+
+	if (!( t=PyDict_New()))  return -1;
+	if (!( r=PyRun_String(
+		       "def __str__(self):\n"
+		       "  a=self.args\n"
+		       "  a=a and type(a[0]) or '(what)'\n"
+		       "  return 'Cannot pickle %s objects' % a\n"
+		       , Py_file_input,
+		       module_dict, t)  ))  return -1;
+	Py_DECREF(r);
+
+	if (!( UnpickleableError = PyErr_NewException(
+		       "cPickle.UnpickleableError", PicklingError, t)))
+		return -1;
+
+	Py_DECREF(t);
+
+	if (!( UnpicklingError = PyErr_NewException("cPickle.UnpicklingError",
+						    PickleError, NULL)))
+		return -1;
+
+        if (!( BadPickleGet = PyErr_NewException("cPickle.BadPickleGet",
+						 UnpicklingError, NULL)))
+                return -1;
+
+	if (PyDict_SetItemString(module_dict, "PickleError",
+				 PickleError) < 0)
+		return -1;
+
+	if (PyDict_SetItemString(module_dict, "PicklingError",
+				 PicklingError) < 0)
+		return -1;
+
+	if (PyDict_SetItemString(module_dict, "UnpicklingError",
+				 UnpicklingError) < 0)
+		return -1;
+
+	if (PyDict_SetItemString(module_dict, "UnpickleableError",
+				 UnpickleableError) < 0)
+		return -1;
+
+	if (PyDict_SetItemString(module_dict, "BadPickleGet",
+				 BadPickleGet) < 0)
+		return -1;
+
+	PycString_IMPORT;
+
+	return 0;
+}
+
+#ifndef PyMODINIT_FUNC	/* declarations for DLL import/export */
+#define PyMODINIT_FUNC void
+#endif
+PyMODINIT_FUNC
+initcPickle(void)
+{
+	PyObject *m, *d, *di, *v, *k;
+	Py_ssize_t i;
+	char *rev = "1.71";	/* XXX when does this change? */
+	PyObject *format_version;
+	PyObject *compatible_formats;
+
+	Picklertype.ob_type = &PyType_Type;
+	Unpicklertype.ob_type = &PyType_Type;
+	PdataType.ob_type = &PyType_Type;
+
+	/* Initialize some pieces. We need to do this before module creation,
+	 * so we're forced to use a temporary dictionary. :(
+	 */
+	di = PyDict_New();
+	if (!di) return;
+	if (init_stuff(di) < 0) return;
+
+	/* Create the module and add the functions */
+	m = Py_InitModule4("cPickle", cPickle_methods,
+			   cPickle_module_documentation,
+			   (PyObject*)NULL,PYTHON_API_VERSION);
+	if (m == NULL)
+		return;
+
+	/* Add some symbolic constants to the module */
+	d = PyModule_GetDict(m);
+	v = PyString_FromString(rev);
+	PyDict_SetItemString(d, "__version__", v);
+	Py_XDECREF(v);
+
+	/* Copy data from di. Waaa. */
+	for (i=0; PyDict_Next(di, &i, &k, &v); ) {
+		if (PyObject_SetItem(d, k, v) < 0) {
+			Py_DECREF(di);
+			return;
+		}
+	}
+	Py_DECREF(di);
+
+	i = PyModule_AddIntConstant(m, "HIGHEST_PROTOCOL", HIGHEST_PROTOCOL);
+	if (i < 0)
+		return;
+
+	/* These are purely informational; no code uses them. */
+	/* File format version we write. */
+	format_version = PyString_FromString("2.0");
+	/* Format versions we can read. */
+	compatible_formats = Py_BuildValue("[sssss]",
+		"1.0",	/* Original protocol 0 */
+		"1.1",	/* Protocol 0 + INST */
+		"1.2",	/* Original protocol 1 */
+		"1.3",	/* Protocol 1 + BINFLOAT */
+		"2.0");	/* Original protocol 2 */
+	PyDict_SetItemString(d, "format_version", format_version);
+	PyDict_SetItemString(d, "compatible_formats", compatible_formats);
+	Py_XDECREF(format_version);
+	Py_XDECREF(compatible_formats);
+}

Added: vendor/Python/current/Modules/cStringIO.c
===================================================================
--- vendor/Python/current/Modules/cStringIO.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/cStringIO.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,745 @@
+
+#include "Python.h"
+#include "import.h"
+#include "cStringIO.h"
+#include "structmember.h"
+
+PyDoc_STRVAR(cStringIO_module_documentation,
+"A simple fast partial StringIO replacement.\n"
+"\n"
+"This module provides a simple useful replacement for\n"
+"the StringIO module that is written in C.  It does not provide the\n"
+"full generality of StringIO, but it provides enough for most\n"
+"applications and is especially useful in conjunction with the\n"
+"pickle module.\n"
+"\n"
+"Usage:\n"
+"\n"
+"  from cStringIO import StringIO\n"
+"\n"
+"  an_output_stream=StringIO()\n"
+"  an_output_stream.write(some_stuff)\n"
+"  ...\n"
+"  value=an_output_stream.getvalue()\n"
+"\n"
+"  an_input_stream=StringIO(a_string)\n"
+"  spam=an_input_stream.readline()\n"
+"  spam=an_input_stream.read(5)\n"
+"  an_input_stream.seek(0)           # OK, start over\n"
+"  spam=an_input_stream.read()       # and read it all\n"
+"  \n"
+"If someone else wants to provide a more complete implementation,\n"
+"go for it. :-)  \n"
+"\n"
+"cStringIO.c,v 1.29 1999/06/15 14:10:27 jim Exp\n");
+
+/* Declaration for file-like objects that manage data as strings 
+
+   The IOobject type should be though of as a common base type for
+   Iobjects, which provide input (read-only) StringIO objects and
+   Oobjects, which provide read-write objects.  Most of the methods
+   depend only on common data.
+*/
+
+typedef struct {
+  PyObject_HEAD
+  char *buf;
+  Py_ssize_t pos, string_size;
+} IOobject;
+
+#define IOOOBJECT(O) ((IOobject*)(O))
+
+/* Declarations for objects of type StringO */
+
+typedef struct { /* Subtype of IOobject */
+  PyObject_HEAD
+  char *buf;
+  Py_ssize_t pos, string_size;
+
+  Py_ssize_t buf_size;
+  int softspace;
+} Oobject;
+
+/* Declarations for objects of type StringI */
+
+typedef struct { /* Subtype of IOobject */
+  PyObject_HEAD
+  char *buf;
+  Py_ssize_t pos, string_size;
+  /* We store a reference to the object here in order to keep
+     the buffer alive during the lifetime of the Iobject. */
+  PyObject *pbuf;
+} Iobject;
+
+/* IOobject (common) methods */
+
+PyDoc_STRVAR(IO_flush__doc__, "flush(): does nothing.");
+
+static int
+IO__opencheck(IOobject *self) {
+        if (!self->buf) {
+                PyErr_SetString(PyExc_ValueError,
+                                "I/O operation on closed file");
+                return 0;
+        }
+        return 1;
+}
+
+static PyObject *
+IO_get_closed(IOobject *self, void *closure)
+{
+	PyObject *result = Py_False;
+
+	if (self->buf == NULL)
+		result = Py_True;
+	Py_INCREF(result);
+	return result;
+}
+
+static PyGetSetDef file_getsetlist[] = {
+	{"closed", (getter)IO_get_closed, NULL, "True if the file is closed"},
+	{0},
+};
+
+static PyObject *
+IO_flush(IOobject *self, PyObject *unused) {
+
+        if (!IO__opencheck(self)) return NULL;
+
+        Py_INCREF(Py_None);
+        return Py_None;
+}
+
+PyDoc_STRVAR(IO_getval__doc__,
+"getvalue([use_pos]) -- Get the string value."
+"\n"
+"If use_pos is specified and is a true value, then the string returned\n"
+"will include only the text up to the current file position.\n");
+
+static PyObject *
+IO_cgetval(PyObject *self) {
+        if (!IO__opencheck(IOOOBJECT(self))) return NULL;
+        return PyString_FromStringAndSize(((IOobject*)self)->buf,
+                                          ((IOobject*)self)->pos);
+}
+
+static PyObject *
+IO_getval(IOobject *self, PyObject *args) {
+        PyObject *use_pos=Py_None;
+        Py_ssize_t s;
+
+        if (!IO__opencheck(self)) return NULL;
+        if (!PyArg_UnpackTuple(args,"getval", 0, 1,&use_pos)) return NULL;
+
+        if (PyObject_IsTrue(use_pos)) {
+                  s=self->pos;
+                  if (s > self->string_size) s=self->string_size;
+        }
+        else
+                  s=self->string_size;
+        return PyString_FromStringAndSize(self->buf, s);
+}
+
+PyDoc_STRVAR(IO_isatty__doc__, "isatty(): always returns 0");
+
+static PyObject *
+IO_isatty(IOobject *self, PyObject *unused) {
+        if (!IO__opencheck(self)) return NULL;
+        Py_INCREF(Py_False);
+        return Py_False;
+}
+
+PyDoc_STRVAR(IO_read__doc__,
+"read([s]) -- Read s characters, or the rest of the string");
+
+static int
+IO_cread(PyObject *self, char **output, Py_ssize_t  n) {
+        Py_ssize_t l;
+
+        if (!IO__opencheck(IOOOBJECT(self))) return -1;
+        l = ((IOobject*)self)->string_size - ((IOobject*)self)->pos;  
+        if (n < 0 || n > l) {
+                n = l;
+                if (n < 0) n=0;
+        }
+
+        *output=((IOobject*)self)->buf + ((IOobject*)self)->pos;
+        ((IOobject*)self)->pos += n;
+        return n;
+}
+
+static PyObject *
+IO_read(IOobject *self, PyObject *args) {
+        Py_ssize_t n = -1;
+        char *output = NULL;
+
+        if (!PyArg_ParseTuple(args, "|n:read", &n)) return NULL;
+
+        if ( (n=IO_cread((PyObject*)self,&output,n)) < 0) return NULL;
+
+        return PyString_FromStringAndSize(output, n);
+}
+
+PyDoc_STRVAR(IO_readline__doc__, "readline() -- Read one line");
+
+static int
+IO_creadline(PyObject *self, char **output) {
+        char *n, *s;
+        Py_ssize_t l;
+
+        if (!IO__opencheck(IOOOBJECT(self))) return -1;
+
+        for (n = ((IOobject*)self)->buf + ((IOobject*)self)->pos,
+               s = ((IOobject*)self)->buf + ((IOobject*)self)->string_size; 
+             n < s && *n != '\n'; n++);
+        if (n < s) n++;
+
+        *output=((IOobject*)self)->buf + ((IOobject*)self)->pos;
+        l = n - ((IOobject*)self)->buf - ((IOobject*)self)->pos;
+	assert(((IOobject*)self)->pos + l < INT_MAX);
+        ((IOobject*)self)->pos += (int)l;
+        return (int)l;
+}
+
+static PyObject *
+IO_readline(IOobject *self, PyObject *args) {
+        int n, m=-1;
+        char *output;
+
+        if (args)
+                if (!PyArg_ParseTuple(args, "|i:readline", &m)) return NULL;
+
+        if( (n=IO_creadline((PyObject*)self,&output)) < 0) return NULL;
+        if (m >= 0 && m < n) {
+                m = n - m;
+                n -= m;
+                self->pos -= m;
+        }
+        return PyString_FromStringAndSize(output, n);
+}
+
+PyDoc_STRVAR(IO_readlines__doc__, "readlines() -- Read all lines");
+
+static PyObject *
+IO_readlines(IOobject *self, PyObject *args) {
+	int n;
+	char *output;
+	PyObject *result, *line;
+        int hint = 0, length = 0;
+	
+        if (!PyArg_ParseTuple(args, "|i:readlines", &hint)) return NULL;
+
+	result = PyList_New(0);
+	if (!result)
+		return NULL;
+
+	while (1){
+		if ( (n = IO_creadline((PyObject*)self,&output)) < 0)
+                        goto err;
+		if (n == 0)
+			break;
+		line = PyString_FromStringAndSize (output, n);
+		if (!line) 
+                        goto err;
+		if (PyList_Append (result, line) == -1) {
+			Py_DECREF (line);
+			goto err;
+		}
+		Py_DECREF (line);
+                length += n;
+                if (hint > 0 && length >= hint)
+			break;
+	}
+	return result;
+ err:
+        Py_DECREF(result);
+        return NULL;
+}
+
+PyDoc_STRVAR(IO_reset__doc__,
+"reset() -- Reset the file position to the beginning");
+
+static PyObject *
+IO_reset(IOobject *self, PyObject *unused) {
+
+        if (!IO__opencheck(self)) return NULL;
+
+        self->pos = 0;
+
+        Py_INCREF(Py_None);
+        return Py_None;
+}
+
+PyDoc_STRVAR(IO_tell__doc__, "tell() -- get the current position.");
+
+static PyObject *
+IO_tell(IOobject *self, PyObject *unused) {
+
+        if (!IO__opencheck(self)) return NULL;
+
+        return PyInt_FromSsize_t(self->pos);
+}
+
+PyDoc_STRVAR(IO_truncate__doc__,
+"truncate(): truncate the file at the current position.");
+
+static PyObject *
+IO_truncate(IOobject *self, PyObject *args) {
+        Py_ssize_t pos = -1;
+	
+        if (!IO__opencheck(self)) return NULL;
+        if (!PyArg_ParseTuple(args, "|n:truncate", &pos)) return NULL;
+        if (pos < 0) pos = self->pos;
+
+        if (self->string_size > pos) self->string_size = pos;
+        self->pos = self->string_size;
+
+        Py_INCREF(Py_None);
+        return Py_None;
+}
+
+static PyObject *
+IO_iternext(Iobject *self)
+{
+	PyObject *next;
+	next = IO_readline((IOobject *)self, NULL);
+	if (!next)
+		return NULL;
+	if (!PyString_GET_SIZE(next)) {
+		Py_DECREF(next);
+		PyErr_SetNone(PyExc_StopIteration);
+		return NULL;
+	}
+	return next;
+}
+
+
+
+
+/* Read-write object methods */
+
+PyDoc_STRVAR(O_seek__doc__,
+"seek(position)       -- set the current position\n"
+"seek(position, mode) -- mode 0: absolute; 1: relative; 2: relative to EOF");
+
+static PyObject *
+O_seek(Oobject *self, PyObject *args) {
+	Py_ssize_t position;
+	int mode = 0;
+
+        if (!IO__opencheck(IOOOBJECT(self))) return NULL;
+        if (!PyArg_ParseTuple(args, "n|i:seek", &position, &mode)) 
+                return NULL;
+
+        if (mode == 2) {
+                position += self->string_size;
+        }
+        else if (mode == 1) {
+                position += self->pos;
+        }
+
+        if (position > self->buf_size) {
+                  self->buf_size*=2;
+                  if (self->buf_size <= position) self->buf_size=position+1;
+		  self->buf = (char*) realloc(self->buf,self->buf_size);
+                  if (!self->buf) {
+                      self->buf_size=self->pos=0;
+                      return PyErr_NoMemory();
+                    }
+          }
+        else if (position < 0) position=0;
+
+        self->pos=position;
+
+        while (--position >= self->string_size) self->buf[position]=0;
+
+        Py_INCREF(Py_None);
+        return Py_None;
+}
+
+PyDoc_STRVAR(O_write__doc__,
+"write(s) -- Write a string to the file"
+"\n\nNote (hack:) writing None resets the buffer");
+
+
+static int
+O_cwrite(PyObject *self, const char *c, Py_ssize_t  l) {
+        Py_ssize_t newl;
+        Oobject *oself;
+
+        if (!IO__opencheck(IOOOBJECT(self))) return -1;
+        oself = (Oobject *)self;
+
+        newl = oself->pos+l;
+        if (newl >= oself->buf_size) {
+            oself->buf_size *= 2;
+            if (oself->buf_size <= newl) {
+		    assert(newl + 1 < INT_MAX);
+                    oself->buf_size = (int)(newl+1);
+	    }
+            oself->buf = (char*)realloc(oself->buf, oself->buf_size);
+	    if (!oself->buf) {
+                    PyErr_SetString(PyExc_MemoryError,"out of memory");
+                    oself->buf_size = oself->pos = 0;
+                    return -1;
+              }
+          }
+
+        memcpy(oself->buf+oself->pos,c,l);
+
+	assert(oself->pos + l < INT_MAX);
+        oself->pos += (int)l;
+
+        if (oself->string_size < oself->pos) {
+            oself->string_size = oself->pos;
+        }
+
+        return (int)l;
+}
+
+static PyObject *
+O_write(Oobject *self, PyObject *args) {
+        char *c;
+        int l;
+
+        if (!PyArg_ParseTuple(args, "t#:write", &c, &l)) return NULL;
+
+        if (O_cwrite((PyObject*)self,c,l) < 0) return NULL;
+
+        Py_INCREF(Py_None);
+        return Py_None;
+}
+
+PyDoc_STRVAR(O_close__doc__, "close(): explicitly release resources held.");
+
+static PyObject *
+O_close(Oobject *self, PyObject *unused) {
+        if (self->buf != NULL) free(self->buf);
+        self->buf = NULL;
+
+        self->pos = self->string_size = self->buf_size = 0;
+
+        Py_INCREF(Py_None);
+        return Py_None;
+}
+
+PyDoc_STRVAR(O_writelines__doc__,
+"writelines(sequence_of_strings) -> None.  Write the strings to the file.\n"
+"\n"
+"Note that newlines are not added.  The sequence can be any iterable object\n"
+"producing strings. This is equivalent to calling write() for each string.");
+static PyObject *
+O_writelines(Oobject *self, PyObject *args) {
+	PyObject *it, *s;
+	
+	it = PyObject_GetIter(args);
+	if (it == NULL)
+		return NULL;
+	while ((s = PyIter_Next(it)) != NULL) {
+		Py_ssize_t n;
+		char *c;
+		if (PyString_AsStringAndSize(s, &c, &n) == -1) {
+			Py_DECREF(it);
+			Py_DECREF(s);
+			return NULL;
+		}
+		if (O_cwrite((PyObject *)self, c, n) == -1) {
+			Py_DECREF(it);
+			Py_DECREF(s);
+			return NULL;
+               }
+               Py_DECREF(s);
+       }
+
+       Py_DECREF(it);
+
+       /* See if PyIter_Next failed */
+       if (PyErr_Occurred())
+               return NULL;
+
+       Py_RETURN_NONE;
+}
+static struct PyMethodDef O_methods[] = {
+  /* Common methods: */
+  {"flush",     (PyCFunction)IO_flush,    METH_NOARGS,  IO_flush__doc__},
+  {"getvalue",  (PyCFunction)IO_getval,   METH_VARARGS, IO_getval__doc__},
+  {"isatty",    (PyCFunction)IO_isatty,   METH_NOARGS,  IO_isatty__doc__},
+  {"read",	(PyCFunction)IO_read,     METH_VARARGS, IO_read__doc__},
+  {"readline",	(PyCFunction)IO_readline, METH_VARARGS, IO_readline__doc__},
+  {"readlines",	(PyCFunction)IO_readlines,METH_VARARGS, IO_readlines__doc__},
+  {"reset",	(PyCFunction)IO_reset,	  METH_NOARGS,  IO_reset__doc__},
+  {"tell",      (PyCFunction)IO_tell,     METH_NOARGS,  IO_tell__doc__},
+  {"truncate",  (PyCFunction)IO_truncate, METH_VARARGS, IO_truncate__doc__},
+
+  /* Read-write StringIO specific  methods: */
+  {"close",      (PyCFunction)O_close,      METH_NOARGS,  O_close__doc__},
+  {"seek",       (PyCFunction)O_seek,       METH_VARARGS, O_seek__doc__},
+  {"write",	 (PyCFunction)O_write,      METH_VARARGS, O_write__doc__},
+  {"writelines", (PyCFunction)O_writelines, METH_O,	  O_writelines__doc__},
+  {NULL,	 NULL}		/* sentinel */
+};
+
+static PyMemberDef O_memberlist[] = {
+	{"softspace",	T_INT,	offsetof(Oobject, softspace),	0,
+	 "flag indicating that a space needs to be printed; used by print"},
+	 /* getattr(f, "closed") is implemented without this table */
+	{NULL} /* Sentinel */
+};
+
+static void
+O_dealloc(Oobject *self) {
+        if (self->buf != NULL)
+                free(self->buf);
+        PyObject_Del(self);
+}
+
+PyDoc_STRVAR(Otype__doc__, "Simple type for output to strings.");
+
+static PyTypeObject Otype = {
+  PyObject_HEAD_INIT(NULL)
+  0,	       			/*ob_size*/
+  "cStringIO.StringO",   	/*tp_name*/
+  sizeof(Oobject),       	/*tp_basicsize*/
+  0,	       			/*tp_itemsize*/
+  /* methods */
+  (destructor)O_dealloc,	/*tp_dealloc*/
+  0,				/*tp_print*/
+  0,		 		/*tp_getattr */
+  0,		 		/*tp_setattr */
+  0,				/*tp_compare*/
+  0,				/*tp_repr*/
+  0,				/*tp_as_number*/
+  0,				/*tp_as_sequence*/
+  0,				/*tp_as_mapping*/
+  0,				/*tp_hash*/
+  0	,			/*tp_call*/
+  0,				/*tp_str*/
+  0,				/*tp_getattro */
+  0,				/*tp_setattro */
+  0,				/*tp_as_buffer */
+  Py_TPFLAGS_DEFAULT,		/*tp_flags*/
+  Otype__doc__, 		/*tp_doc */
+  0,				/*tp_traverse */
+  0,				/*tp_clear */
+  0,				/*tp_richcompare */
+  0,				/*tp_weaklistoffset */
+  PyObject_SelfIter,		/*tp_iter */
+  (iternextfunc)IO_iternext,	/*tp_iternext */
+  O_methods,			/*tp_methods */
+  O_memberlist,			/*tp_members */
+  file_getsetlist,		/*tp_getset */
+};
+
+static PyObject *
+newOobject(int  size) {
+        Oobject *self;
+
+        self = PyObject_New(Oobject, &Otype);
+        if (self == NULL)
+                return NULL;
+        self->pos=0;
+        self->string_size = 0;
+        self->softspace = 0;
+
+        self->buf = (char *)malloc(size);
+	if (!self->buf) {
+                  PyErr_SetString(PyExc_MemoryError,"out of memory");
+                  self->buf_size = 0;
+                  Py_DECREF(self);
+                  return NULL;
+          }
+
+        self->buf_size=size;
+        return (PyObject*)self;
+}
+
+/* End of code for StringO objects */
+/* -------------------------------------------------------- */
+
+static PyObject *
+I_close(Iobject *self, PyObject *unused) {
+        Py_XDECREF(self->pbuf);
+        self->pbuf = NULL;
+        self->buf = NULL;
+
+        self->pos = self->string_size = 0;
+
+        Py_INCREF(Py_None);
+        return Py_None;
+}
+
+static PyObject *
+I_seek(Iobject *self, PyObject *args) {
+        Py_ssize_t position;
+	int mode = 0;
+
+        if (!IO__opencheck(IOOOBJECT(self))) return NULL;
+        if (!PyArg_ParseTuple(args, "n|i:seek", &position, &mode)) 
+                return NULL;
+
+        if (mode == 2) position += self->string_size;
+        else if (mode == 1) position += self->pos;
+
+        if (position < 0) position=0;
+
+        self->pos=position;
+
+        Py_INCREF(Py_None);
+        return Py_None;
+}
+
+static struct PyMethodDef I_methods[] = {
+  /* Common methods: */
+  {"flush",     (PyCFunction)IO_flush,    METH_NOARGS,  IO_flush__doc__},
+  {"getvalue",  (PyCFunction)IO_getval,   METH_VARARGS, IO_getval__doc__},
+  {"isatty",    (PyCFunction)IO_isatty,   METH_NOARGS,  IO_isatty__doc__},
+  {"read",	(PyCFunction)IO_read,     METH_VARARGS, IO_read__doc__},
+  {"readline",	(PyCFunction)IO_readline, METH_VARARGS, IO_readline__doc__},
+  {"readlines",	(PyCFunction)IO_readlines,METH_VARARGS, IO_readlines__doc__},
+  {"reset",	(PyCFunction)IO_reset,	  METH_NOARGS,  IO_reset__doc__},
+  {"tell",      (PyCFunction)IO_tell,     METH_NOARGS,  IO_tell__doc__},
+  {"truncate",  (PyCFunction)IO_truncate, METH_VARARGS, IO_truncate__doc__},
+
+  /* Read-only StringIO specific  methods: */
+  {"close",     (PyCFunction)I_close,    METH_NOARGS,  O_close__doc__},
+  {"seek",      (PyCFunction)I_seek,     METH_VARARGS, O_seek__doc__},  
+  {NULL,	NULL}
+};
+
+static void
+I_dealloc(Iobject *self) {
+  Py_XDECREF(self->pbuf);
+  PyObject_Del(self);
+}
+
+
+PyDoc_STRVAR(Itype__doc__,
+"Simple type for treating strings as input file streams");
+
+static PyTypeObject Itype = {
+  PyObject_HEAD_INIT(NULL)
+  0,					/*ob_size*/
+  "cStringIO.StringI",			/*tp_name*/
+  sizeof(Iobject),			/*tp_basicsize*/
+  0,					/*tp_itemsize*/
+  /* methods */
+  (destructor)I_dealloc,		/*tp_dealloc*/
+  0,					/*tp_print*/
+  0,		 			/* tp_getattr */
+  0,					/*tp_setattr*/
+  0,					/*tp_compare*/
+  0,					/*tp_repr*/
+  0,					/*tp_as_number*/
+  0,					/*tp_as_sequence*/
+  0,					/*tp_as_mapping*/
+  0,					/*tp_hash*/
+  0,					/*tp_call*/
+  0,					/*tp_str*/
+  0,					/* tp_getattro */
+  0,					/* tp_setattro */
+  0,					/* tp_as_buffer */
+  Py_TPFLAGS_DEFAULT,			/* tp_flags */
+  Itype__doc__,				/* tp_doc */
+  0,					/* tp_traverse */
+  0,					/* tp_clear */
+  0,					/* tp_richcompare */
+  0,					/* tp_weaklistoffset */
+  PyObject_SelfIter,			/* tp_iter */
+  (iternextfunc)IO_iternext,		/* tp_iternext */
+  I_methods,				/* tp_methods */
+  0,					/* tp_members */
+  file_getsetlist,			/* tp_getset */
+};
+
+static PyObject *
+newIobject(PyObject *s) {
+  Iobject *self;
+  char *buf;
+  Py_ssize_t size;
+
+  if (PyObject_AsCharBuffer(s, (const char **)&buf, &size) != 0)
+      return NULL;
+
+  self = PyObject_New(Iobject, &Itype);
+  if (!self) return NULL;
+  Py_INCREF(s);
+  self->buf=buf;
+  self->string_size=size;
+  self->pbuf=s;
+  self->pos=0;
+  
+  return (PyObject*)self;
+}
+
+/* End of code for StringI objects */
+/* -------------------------------------------------------- */
+
+
+PyDoc_STRVAR(IO_StringIO__doc__,
+"StringIO([s]) -- Return a StringIO-like stream for reading or writing");
+
+static PyObject *
+IO_StringIO(PyObject *self, PyObject *args) {
+  PyObject *s=0;
+
+  if (!PyArg_UnpackTuple(args, "StringIO", 0, 1, &s)) return NULL;
+
+  if (s) return newIobject(s);
+  return newOobject(128);
+}
+
+/* List of methods defined in the module */
+
+static struct PyMethodDef IO_methods[] = {
+  {"StringIO",	(PyCFunction)IO_StringIO,	
+   METH_VARARGS,	IO_StringIO__doc__},
+  {NULL,		NULL}		/* sentinel */
+};
+
+
+/* Initialization function for the module (*must* be called initcStringIO) */
+
+static struct PycStringIO_CAPI CAPI = {
+  IO_cread,
+  IO_creadline,
+  O_cwrite,
+  IO_cgetval,
+  newOobject,
+  newIobject,
+  &Itype,
+  &Otype,
+};
+
+#ifndef PyMODINIT_FUNC	/* declarations for DLL import/export */
+#define PyMODINIT_FUNC void
+#endif
+PyMODINIT_FUNC
+initcStringIO(void) {
+  PyObject *m, *d, *v;
+
+
+  /* Create the module and add the functions */
+  m = Py_InitModule4("cStringIO", IO_methods,
+		     cStringIO_module_documentation,
+		     (PyObject*)NULL,PYTHON_API_VERSION);
+  if (m == NULL) return;
+
+  /* Add some symbolic constants to the module */
+  d = PyModule_GetDict(m);
+  
+  /* Export C API */
+  Itype.ob_type=&PyType_Type;
+  Otype.ob_type=&PyType_Type;
+  if (PyType_Ready(&Otype) < 0) return;
+  if (PyType_Ready(&Itype) < 0) return;
+  PyDict_SetItemString(d,"cStringIO_CAPI",
+		       v = PyCObject_FromVoidPtr(&CAPI,NULL));
+  Py_XDECREF(v);
+
+  /* Export Types */
+  PyDict_SetItemString(d,"InputType",  (PyObject*)&Itype);
+  PyDict_SetItemString(d,"OutputType", (PyObject*)&Otype);
+
+  /* Maybe make certain warnings go away */
+  if (0) PycString_IMPORT;
+}

Added: vendor/Python/current/Modules/cdmodule.c
===================================================================
--- vendor/Python/current/Modules/cdmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/cdmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,796 @@
+/* CD module -- interface to Mark Callow's and Roger Chickering's */
+ /* CD Audio Library (CD). */
+
+#include <sys/types.h>
+#include <cdaudio.h>
+#include "Python.h"
+
+#define NCALLBACKS	8
+
+typedef struct {
+	PyObject_HEAD
+	CDPLAYER *ob_cdplayer;
+} cdplayerobject;
+
+static PyObject *CdError;		/* exception cd.error */
+
+static PyObject *
+CD_allowremoval(cdplayerobject *self, PyObject *args)
+{
+	if (!PyArg_ParseTuple(args, ":allowremoval"))
+		return NULL;
+
+	CDallowremoval(self->ob_cdplayer);
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+CD_preventremoval(cdplayerobject *self, PyObject *args)
+{
+	if (!PyArg_ParseTuple(args, ":preventremoval"))
+		return NULL;
+
+	CDpreventremoval(self->ob_cdplayer);
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+CD_bestreadsize(cdplayerobject *self, PyObject *args)
+{
+	if (!PyArg_ParseTuple(args, ":bestreadsize"))
+		return NULL;
+
+	return PyInt_FromLong((long) CDbestreadsize(self->ob_cdplayer));
+}
+
+static PyObject *
+CD_close(cdplayerobject *self, PyObject *args)
+{
+	if (!PyArg_ParseTuple(args, ":close"))
+		return NULL;
+
+	if (!CDclose(self->ob_cdplayer)) {
+		PyErr_SetFromErrno(CdError); /* XXX - ??? */
+		return NULL;
+	}
+	self->ob_cdplayer = NULL;
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+CD_eject(cdplayerobject *self, PyObject *args)
+{
+	CDSTATUS status;
+
+	if (!PyArg_ParseTuple(args, ":eject"))
+		return NULL;
+
+	if (!CDeject(self->ob_cdplayer)) {
+		if (CDgetstatus(self->ob_cdplayer, &status) &&
+		    status.state == CD_NODISC)
+			PyErr_SetString(CdError, "no disc in player");
+		else
+			PyErr_SetString(CdError, "eject failed");
+		return NULL;
+	}
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+	
+static PyObject *
+CD_getstatus(cdplayerobject *self, PyObject *args)
+{
+	CDSTATUS status;
+
+	if (!PyArg_ParseTuple(args, ":getstatus"))
+		return NULL;
+
+	if (!CDgetstatus(self->ob_cdplayer, &status)) {
+		PyErr_SetFromErrno(CdError); /* XXX - ??? */
+		return NULL;
+	}
+
+	return Py_BuildValue("(ii(iii)(iii)(iii)iiii)", status.state,
+		       status.track, status.min, status.sec, status.frame,
+		       status.abs_min, status.abs_sec, status.abs_frame,
+		       status.total_min, status.total_sec, status.total_frame,
+		       status.first, status.last, status.scsi_audio,
+		       status.cur_block);
+}
+	
+static PyObject *
+CD_gettrackinfo(cdplayerobject *self, PyObject *args)
+{
+	int track;
+	CDTRACKINFO info;
+	CDSTATUS status;
+
+	if (!PyArg_ParseTuple(args, "i:gettrackinfo", &track))
+		return NULL;
+
+	if (!CDgettrackinfo(self->ob_cdplayer, track, &info)) {
+		if (CDgetstatus(self->ob_cdplayer, &status) &&
+		    status.state == CD_NODISC)
+			PyErr_SetString(CdError, "no disc in player");
+		else
+			PyErr_SetString(CdError, "gettrackinfo failed");
+		return NULL;
+	}
+
+	return Py_BuildValue("((iii)(iii))",
+		       info.start_min, info.start_sec, info.start_frame,
+		       info.total_min, info.total_sec, info.total_frame);
+}
+	
+static PyObject *
+CD_msftoblock(cdplayerobject *self, PyObject *args)
+{
+	int min, sec, frame;
+
+	if (!PyArg_ParseTuple(args, "iii:msftoblock", &min, &sec, &frame))
+		return NULL;
+
+	return PyInt_FromLong((long) CDmsftoblock(self->ob_cdplayer,
+						min, sec, frame));
+}
+	
+static PyObject *
+CD_play(cdplayerobject *self, PyObject *args)
+{
+	int start, play;
+	CDSTATUS status;
+
+	if (!PyArg_ParseTuple(args, "ii:play", &start, &play))
+		return NULL;
+
+	if (!CDplay(self->ob_cdplayer, start, play)) {
+		if (CDgetstatus(self->ob_cdplayer, &status) &&
+		    status.state == CD_NODISC)
+			PyErr_SetString(CdError, "no disc in player");
+		else
+			PyErr_SetString(CdError, "play failed");
+		return NULL;
+	}
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+	
+static PyObject *
+CD_playabs(cdplayerobject *self, PyObject *args)
+{
+	int min, sec, frame, play;
+	CDSTATUS status;
+
+	if (!PyArg_ParseTuple(args, "iiii:playabs", &min, &sec, &frame, &play))
+		return NULL;
+
+	if (!CDplayabs(self->ob_cdplayer, min, sec, frame, play)) {
+		if (CDgetstatus(self->ob_cdplayer, &status) &&
+		    status.state == CD_NODISC)
+			PyErr_SetString(CdError, "no disc in player");
+		else
+			PyErr_SetString(CdError, "playabs failed");
+		return NULL;
+	}
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+	
+static PyObject *
+CD_playtrack(cdplayerobject *self, PyObject *args)
+{
+	int start, play;
+	CDSTATUS status;
+
+	if (!PyArg_ParseTuple(args, "ii:playtrack", &start, &play))
+		return NULL;
+
+	if (!CDplaytrack(self->ob_cdplayer, start, play)) {
+		if (CDgetstatus(self->ob_cdplayer, &status) &&
+		    status.state == CD_NODISC)
+			PyErr_SetString(CdError, "no disc in player");
+		else
+			PyErr_SetString(CdError, "playtrack failed");
+		return NULL;
+	}
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+	
+static PyObject *
+CD_playtrackabs(cdplayerobject *self, PyObject *args)
+{
+	int track, min, sec, frame, play;
+	CDSTATUS status;
+
+	if (!PyArg_ParseTuple(args, "iiiii:playtrackabs", &track, &min, &sec,
+			      &frame, &play))
+		return NULL;
+
+	if (!CDplaytrackabs(self->ob_cdplayer, track, min, sec, frame, play)) {
+		if (CDgetstatus(self->ob_cdplayer, &status) &&
+		    status.state == CD_NODISC)
+			PyErr_SetString(CdError, "no disc in player");
+		else
+			PyErr_SetString(CdError, "playtrackabs failed");
+		return NULL;
+	}
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+	
+static PyObject *
+CD_readda(cdplayerobject *self, PyObject *args)
+{
+	int numframes, n;
+	PyObject *result;
+
+	if (!PyArg_ParseTuple(args, "i:readda", &numframes))
+		return NULL;
+
+	result = PyString_FromStringAndSize(NULL, numframes * sizeof(CDFRAME));
+	if (result == NULL)
+		return NULL;
+
+	n = CDreadda(self->ob_cdplayer,
+		       (CDFRAME *) PyString_AsString(result), numframes);
+	if (n == -1) {
+		Py_DECREF(result);
+		PyErr_SetFromErrno(CdError);
+		return NULL;
+	}
+	if (n < numframes)
+		_PyString_Resize(&result, n * sizeof(CDFRAME));
+
+	return result;
+}
+
+static PyObject *
+CD_seek(cdplayerobject *self, PyObject *args)
+{
+	int min, sec, frame;
+	long PyTryBlock;
+
+	if (!PyArg_ParseTuple(args, "iii:seek", &min, &sec, &frame))
+		return NULL;
+
+	PyTryBlock = CDseek(self->ob_cdplayer, min, sec, frame);
+	if (PyTryBlock == -1) {
+		PyErr_SetFromErrno(CdError);
+		return NULL;
+	}
+
+	return PyInt_FromLong(PyTryBlock);
+}
+	
+static PyObject *
+CD_seektrack(cdplayerobject *self, PyObject *args)
+{
+	int track;
+	long PyTryBlock;
+
+	if (!PyArg_ParseTuple(args, "i:seektrack", &track))
+		return NULL;
+
+	PyTryBlock = CDseektrack(self->ob_cdplayer, track);
+	if (PyTryBlock == -1) {
+		PyErr_SetFromErrno(CdError);
+		return NULL;
+	}
+
+	return PyInt_FromLong(PyTryBlock);
+}
+	
+static PyObject *
+CD_seekblock(cdplayerobject *self, PyObject *args)
+{
+	unsigned long PyTryBlock;
+
+	if (!PyArg_ParseTuple(args, "l:seekblock", &PyTryBlock))
+		return NULL;
+
+	PyTryBlock = CDseekblock(self->ob_cdplayer, PyTryBlock);
+	if (PyTryBlock == (unsigned long) -1) {
+		PyErr_SetFromErrno(CdError);
+		return NULL;
+	}
+
+	return PyInt_FromLong(PyTryBlock);
+}
+	
+static PyObject *
+CD_stop(cdplayerobject *self, PyObject *args)
+{
+	CDSTATUS status;
+
+	if (!PyArg_ParseTuple(args, ":stop"))
+		return NULL;
+
+	if (!CDstop(self->ob_cdplayer)) {
+		if (CDgetstatus(self->ob_cdplayer, &status) &&
+		    status.state == CD_NODISC)
+			PyErr_SetString(CdError, "no disc in player");
+		else
+			PyErr_SetString(CdError, "stop failed");
+		return NULL;
+	}
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+	
+static PyObject *
+CD_togglepause(cdplayerobject *self, PyObject *args)
+{
+	CDSTATUS status;
+
+	if (!PyArg_ParseTuple(args, ":togglepause"))
+		return NULL;
+
+	if (!CDtogglepause(self->ob_cdplayer)) {
+		if (CDgetstatus(self->ob_cdplayer, &status) &&
+		    status.state == CD_NODISC)
+			PyErr_SetString(CdError, "no disc in player");
+		else
+			PyErr_SetString(CdError, "togglepause failed");
+		return NULL;
+	}
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+	
+static PyMethodDef cdplayer_methods[] = {
+	{"allowremoval",	(PyCFunction)CD_allowremoval,	METH_VARARGS},
+	{"bestreadsize",	(PyCFunction)CD_bestreadsize,	METH_VARARGS},
+	{"close",		(PyCFunction)CD_close,		METH_VARARGS},
+	{"eject",		(PyCFunction)CD_eject,		METH_VARARGS},
+	{"getstatus",		(PyCFunction)CD_getstatus,		METH_VARARGS},
+	{"gettrackinfo",	(PyCFunction)CD_gettrackinfo,	METH_VARARGS},
+	{"msftoblock",		(PyCFunction)CD_msftoblock,		METH_VARARGS},
+	{"play",		(PyCFunction)CD_play,		METH_VARARGS},
+	{"playabs",		(PyCFunction)CD_playabs,		METH_VARARGS},
+	{"playtrack",		(PyCFunction)CD_playtrack,		METH_VARARGS},
+	{"playtrackabs",	(PyCFunction)CD_playtrackabs,	METH_VARARGS},
+	{"preventremoval",	(PyCFunction)CD_preventremoval,	METH_VARARGS},
+	{"readda",		(PyCFunction)CD_readda,		METH_VARARGS},
+	{"seek",		(PyCFunction)CD_seek,		METH_VARARGS},
+	{"seekblock",		(PyCFunction)CD_seekblock,		METH_VARARGS},
+	{"seektrack",		(PyCFunction)CD_seektrack,		METH_VARARGS},
+	{"stop",		(PyCFunction)CD_stop,		METH_VARARGS},
+	{"togglepause",		(PyCFunction)CD_togglepause,   	METH_VARARGS},
+	{NULL,			NULL} 		/* sentinel */
+};
+
+static void
+cdplayer_dealloc(cdplayerobject *self)
+{
+	if (self->ob_cdplayer != NULL)
+		CDclose(self->ob_cdplayer);
+	PyObject_Del(self);
+}
+
+static PyObject *
+cdplayer_getattr(cdplayerobject *self, char *name)
+{
+	if (self->ob_cdplayer == NULL) {
+		PyErr_SetString(PyExc_RuntimeError, "no player active");
+		return NULL;
+	}
+	return Py_FindMethod(cdplayer_methods, (PyObject *)self, name);
+}
+
+PyTypeObject CdPlayertype = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,			/*ob_size*/
+	"cd.cdplayer",	/*tp_name*/
+	sizeof(cdplayerobject),	/*tp_size*/
+	0,			/*tp_itemsize*/
+	/* methods */
+	(destructor)cdplayer_dealloc, /*tp_dealloc*/
+	0,			/*tp_print*/
+	(getattrfunc)cdplayer_getattr, /*tp_getattr*/
+	0,			/*tp_setattr*/
+	0,			/*tp_compare*/
+	0,			/*tp_repr*/
+};
+
+static PyObject *
+newcdplayerobject(CDPLAYER *cdp)
+{
+	cdplayerobject *p;
+
+	p = PyObject_New(cdplayerobject, &CdPlayertype);
+	if (p == NULL)
+		return NULL;
+	p->ob_cdplayer = cdp;
+	return (PyObject *) p;
+}
+
+static PyObject *
+CD_open(PyObject *self, PyObject *args)
+{
+	char *dev, *direction;
+	CDPLAYER *cdp;
+
+	/*
+	 * Variable number of args.
+	 * First defaults to "None", second defaults to "r".
+	 */
+	dev = NULL;
+	direction = "r";
+	if (!PyArg_ParseTuple(args, "|zs:open", &dev, &direction))
+		return NULL;
+
+	cdp = CDopen(dev, direction);
+	if (cdp == NULL) {
+		PyErr_SetFromErrno(CdError);
+		return NULL;
+	}
+
+	return newcdplayerobject(cdp);
+}
+
+typedef struct {
+	PyObject_HEAD
+	CDPARSER *ob_cdparser;
+	struct {
+		PyObject *ob_cdcallback;
+		PyObject *ob_cdcallbackarg;
+	} ob_cdcallbacks[NCALLBACKS];
+} cdparserobject;
+
+static void
+CD_callback(void *arg, CDDATATYPES type, void *data)
+{
+	PyObject *result, *args, *v = NULL;
+	char *p;
+	int i;
+	cdparserobject *self;
+
+	self = (cdparserobject *) arg;
+	args = PyTuple_New(3);
+	if (args == NULL)
+		return;
+	Py_INCREF(self->ob_cdcallbacks[type].ob_cdcallbackarg);
+	PyTuple_SetItem(args, 0, self->ob_cdcallbacks[type].ob_cdcallbackarg);
+	PyTuple_SetItem(args, 1, PyInt_FromLong((long) type));
+	switch (type) {
+	case cd_audio:
+		v = PyString_FromStringAndSize(data, CDDA_DATASIZE);
+		break;
+	case cd_pnum:
+	case cd_index:
+		v = PyInt_FromLong(((CDPROGNUM *) data)->value);
+		break;
+	case cd_ptime:
+	case cd_atime:
+#define ptr ((struct cdtimecode *) data)
+		v = Py_BuildValue("(iii)",
+			    ptr->mhi * 10 + ptr->mlo,
+			    ptr->shi * 10 + ptr->slo,
+			    ptr->fhi * 10 + ptr->flo);
+#undef ptr
+		break;
+	case cd_catalog:
+		v = PyString_FromStringAndSize(NULL, 13);
+		p = PyString_AsString(v);
+		for (i = 0; i < 13; i++)
+			*p++ = ((char *) data)[i] + '0';
+		break;
+	case cd_ident:
+#define ptr ((struct cdident *) data)
+		v = PyString_FromStringAndSize(NULL, 12);
+		p = PyString_AsString(v);
+		CDsbtoa(p, ptr->country, 2);
+		p += 2;
+		CDsbtoa(p, ptr->owner, 3);
+		p += 3;
+		*p++ = ptr->year[0] + '0';
+		*p++ = ptr->year[1] + '0';
+		*p++ = ptr->serial[0] + '0';
+		*p++ = ptr->serial[1] + '0';
+		*p++ = ptr->serial[2] + '0';
+		*p++ = ptr->serial[3] + '0';
+		*p++ = ptr->serial[4] + '0';
+#undef ptr
+		break;
+	case cd_control:
+		v = PyInt_FromLong((long) *((unchar *) data));
+		break;
+	}
+	PyTuple_SetItem(args, 2, v);
+	if (PyErr_Occurred()) {
+		Py_DECREF(args);
+		return;
+	}
+	
+	result = PyEval_CallObject(self->ob_cdcallbacks[type].ob_cdcallback,
+				   args);
+	Py_DECREF(args);
+	Py_XDECREF(result);
+}
+
+static PyObject *
+CD_deleteparser(cdparserobject *self, PyObject *args)
+{
+	int i;
+
+	if (!PyArg_ParseTuple(args, ":deleteparser"))
+		return NULL;
+
+	CDdeleteparser(self->ob_cdparser);
+	self->ob_cdparser = NULL;
+
+	/* no sense in keeping the callbacks, so remove them */
+	for (i = 0; i < NCALLBACKS; i++) {
+		Py_XDECREF(self->ob_cdcallbacks[i].ob_cdcallback);
+		self->ob_cdcallbacks[i].ob_cdcallback = NULL;
+		Py_XDECREF(self->ob_cdcallbacks[i].ob_cdcallbackarg);
+		self->ob_cdcallbacks[i].ob_cdcallbackarg = NULL;
+	}
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+CD_parseframe(cdparserobject *self, PyObject *args)
+{
+	char *cdfp;
+	int length;
+	CDFRAME *p;
+
+	if (!PyArg_ParseTuple(args, "s#:parseframe", &cdfp, &length))
+		return NULL;
+
+	if (length % sizeof(CDFRAME) != 0) {
+		PyErr_SetString(PyExc_TypeError, "bad length");
+		return NULL;
+	}
+
+	p = (CDFRAME *) cdfp;
+	while (length > 0) {
+		CDparseframe(self->ob_cdparser, p);
+		length -= sizeof(CDFRAME);
+		p++;
+		if (PyErr_Occurred())
+			return NULL;
+	}
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+CD_removecallback(cdparserobject *self, PyObject *args)
+{
+	int type;
+
+	if (!PyArg_ParseTuple(args, "i:removecallback", &type))
+		return NULL;
+
+	if (type < 0 || type >= NCALLBACKS) {
+		PyErr_SetString(PyExc_TypeError, "bad type");
+		return NULL;
+	}
+
+	CDremovecallback(self->ob_cdparser, (CDDATATYPES) type);
+
+	Py_XDECREF(self->ob_cdcallbacks[type].ob_cdcallback);
+	self->ob_cdcallbacks[type].ob_cdcallback = NULL;
+
+	Py_XDECREF(self->ob_cdcallbacks[type].ob_cdcallbackarg);
+	self->ob_cdcallbacks[type].ob_cdcallbackarg = NULL;
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+CD_resetparser(cdparserobject *self, PyObject *args)
+{
+	if (!PyArg_ParseTuple(args, ":resetparser"))
+		return NULL;
+
+	CDresetparser(self->ob_cdparser);
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+CD_addcallback(cdparserobject *self, PyObject *args)
+{
+	int type;
+	PyObject *func, *funcarg;
+
+	/* XXX - more work here */
+	if (!PyArg_ParseTuple(args, "iOO:addcallback", &type, &func, &funcarg))
+		return NULL;
+
+	if (type < 0 || type >= NCALLBACKS) {
+		PyErr_SetString(PyExc_TypeError, "argument out of range");
+		return NULL;
+	}
+
+#ifdef CDsetcallback
+	CDaddcallback(self->ob_cdparser, (CDDATATYPES) type, CD_callback,
+		      (void *) self);
+#else
+	CDsetcallback(self->ob_cdparser, (CDDATATYPES) type, CD_callback,
+		      (void *) self);
+#endif
+	Py_XDECREF(self->ob_cdcallbacks[type].ob_cdcallback);
+	Py_INCREF(func);
+	self->ob_cdcallbacks[type].ob_cdcallback = func;
+	Py_XDECREF(self->ob_cdcallbacks[type].ob_cdcallbackarg);
+	Py_INCREF(funcarg);
+	self->ob_cdcallbacks[type].ob_cdcallbackarg = funcarg;
+
+/*
+	if (type == cd_audio) {
+		sigfpe_[_UNDERFL].repls = _ZERO;
+		handle_sigfpes(_ON, _EN_UNDERFL, NULL,
+		                        _ABORT_ON_ERROR, NULL);
+	}
+*/
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyMethodDef cdparser_methods[] = {
+	{"addcallback",		(PyCFunction)CD_addcallback,   	METH_VARARGS},
+	{"deleteparser",	(PyCFunction)CD_deleteparser,	METH_VARARGS},
+	{"parseframe",		(PyCFunction)CD_parseframe,	METH_VARARGS},
+	{"removecallback",	(PyCFunction)CD_removecallback,	METH_VARARGS},
+	{"resetparser",		(PyCFunction)CD_resetparser,	METH_VARARGS},
+		                                /* backward compatibility */
+	{"setcallback",		(PyCFunction)CD_addcallback,   	METH_VARARGS},
+	{NULL,			NULL} 		/* sentinel */
+};
+
+static void
+cdparser_dealloc(cdparserobject *self)
+{
+	int i;
+
+	for (i = 0; i < NCALLBACKS; i++) {
+		Py_XDECREF(self->ob_cdcallbacks[i].ob_cdcallback);
+		self->ob_cdcallbacks[i].ob_cdcallback = NULL;
+		Py_XDECREF(self->ob_cdcallbacks[i].ob_cdcallbackarg);
+		self->ob_cdcallbacks[i].ob_cdcallbackarg = NULL;
+	}
+	CDdeleteparser(self->ob_cdparser);
+	PyObject_Del(self);
+}
+
+static PyObject *
+cdparser_getattr(cdparserobject *self, char *name)
+{
+	if (self->ob_cdparser == NULL) {
+		PyErr_SetString(PyExc_RuntimeError, "no parser active");
+		return NULL;
+	}
+
+	return Py_FindMethod(cdparser_methods, (PyObject *)self, name);
+}
+
+PyTypeObject CdParsertype = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,			/*ob_size*/
+	"cd.cdparser",		/*tp_name*/
+	sizeof(cdparserobject),	/*tp_size*/
+	0,			/*tp_itemsize*/
+	/* methods */
+	(destructor)cdparser_dealloc, /*tp_dealloc*/
+	0,			/*tp_print*/
+	(getattrfunc)cdparser_getattr, /*tp_getattr*/
+	0,			/*tp_setattr*/
+	0,			/*tp_compare*/
+	0,			/*tp_repr*/
+};
+
+static PyObject *
+newcdparserobject(CDPARSER *cdp)
+{
+	cdparserobject *p;
+	int i;
+
+	p = PyObject_New(cdparserobject, &CdParsertype);
+	if (p == NULL)
+		return NULL;
+	p->ob_cdparser = cdp;
+	for (i = 0; i < NCALLBACKS; i++) {
+		p->ob_cdcallbacks[i].ob_cdcallback = NULL;
+		p->ob_cdcallbacks[i].ob_cdcallbackarg = NULL;
+	}
+	return (PyObject *) p;
+}
+
+static PyObject *
+CD_createparser(PyObject *self, PyObject *args)
+{
+	CDPARSER *cdp;
+
+	if (!PyArg_ParseTuple(args, ":createparser"))
+		return NULL;
+	cdp = CDcreateparser();
+	if (cdp == NULL) {
+		PyErr_SetString(CdError, "createparser failed");
+		return NULL;
+	}
+
+	return newcdparserobject(cdp);
+}
+
+static PyObject *
+CD_msftoframe(PyObject *self, PyObject *args)
+{
+	int min, sec, frame;
+
+	if (!PyArg_ParseTuple(args, "iii:msftoframe", &min, &sec, &frame))
+		return NULL;
+
+	return PyInt_FromLong((long) CDmsftoframe(min, sec, frame));
+}
+	
+static PyMethodDef CD_methods[] = {
+	{"open",		(PyCFunction)CD_open,		METH_VARARGS},
+	{"createparser",	(PyCFunction)CD_createparser,	METH_VARARGS},
+	{"msftoframe",		(PyCFunction)CD_msftoframe,	METH_VARARGS},
+	{NULL,		NULL}	/* Sentinel */
+};
+
+void
+initcd(void)
+{
+	PyObject *m, *d;
+
+	m = Py_InitModule("cd", CD_methods);
+	if (m == NULL)
+		return;
+	d = PyModule_GetDict(m);
+
+	CdError = PyErr_NewException("cd.error", NULL, NULL);
+	PyDict_SetItemString(d, "error", CdError);
+
+	/* Identifiers for the different types of callbacks from the parser */
+	PyDict_SetItemString(d, "audio", PyInt_FromLong((long) cd_audio));
+	PyDict_SetItemString(d, "pnum", PyInt_FromLong((long) cd_pnum));
+	PyDict_SetItemString(d, "index", PyInt_FromLong((long) cd_index));
+	PyDict_SetItemString(d, "ptime", PyInt_FromLong((long) cd_ptime));
+	PyDict_SetItemString(d, "atime", PyInt_FromLong((long) cd_atime));
+	PyDict_SetItemString(d, "catalog", PyInt_FromLong((long) cd_catalog));
+	PyDict_SetItemString(d, "ident", PyInt_FromLong((long) cd_ident));
+	PyDict_SetItemString(d, "control", PyInt_FromLong((long) cd_control));
+
+	/* Block size information for digital audio data */
+	PyDict_SetItemString(d, "DATASIZE",
+			   PyInt_FromLong((long) CDDA_DATASIZE));
+	PyDict_SetItemString(d, "BLOCKSIZE",
+			   PyInt_FromLong((long) CDDA_BLOCKSIZE));
+
+	/* Possible states for the cd player */
+	PyDict_SetItemString(d, "ERROR", PyInt_FromLong((long) CD_ERROR));
+	PyDict_SetItemString(d, "NODISC", PyInt_FromLong((long) CD_NODISC));
+	PyDict_SetItemString(d, "READY", PyInt_FromLong((long) CD_READY));
+	PyDict_SetItemString(d, "PLAYING", PyInt_FromLong((long) CD_PLAYING));
+	PyDict_SetItemString(d, "PAUSED", PyInt_FromLong((long) CD_PAUSED));
+	PyDict_SetItemString(d, "STILL", PyInt_FromLong((long) CD_STILL));
+#ifdef CD_CDROM			/* only newer versions of the library */
+	PyDict_SetItemString(d, "CDROM", PyInt_FromLong((long) CD_CDROM));
+#endif
+}

Added: vendor/Python/current/Modules/cgen.py
===================================================================
--- vendor/Python/current/Modules/cgen.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/cgen.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,520 @@
+########################################################################
+# Copyright (c) 2000, BeOpen.com.
+# Copyright (c) 1995-2000, Corporation for National Research Initiatives.
+# Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
+# All rights reserved.
+#
+# See the file "Misc/COPYRIGHT" for information on usage and
+# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+########################################################################
+
+# Python script to parse cstubs file for gl and generate C stubs.
+# usage: python cgen.py <cstubs >glmodule.c
+#
+# NOTE: You  must first make a python binary without the "GL" option
+#       before you can run this, when building Python for the first time.
+#       See comments in the Makefile.
+#
+# XXX BUG return arrays generate wrong code
+# XXX need to change error returns into gotos to free mallocked arrays
+
+
+import string
+import sys
+
+
+# Function to print to stderr
+#
+def err(*args):
+    savestdout = sys.stdout
+    try:
+        sys.stdout = sys.stderr
+        for i in args:
+            print i,
+        print
+    finally:
+        sys.stdout = savestdout
+
+
+# The set of digits that form a number
+#
+digits = '0123456789'
+
+
+# Function to extract a string of digits from the front of the string.
+# Returns the leading string of digits and the remaining string.
+# If no number is found, returns '' and the original string.
+#
+def getnum(s):
+    n = ''
+    while s and s[0] in digits:
+        n = n + s[0]
+        s = s[1:]
+    return n, s
+
+
+# Function to check if a string is a number
+#
+def isnum(s):
+    if not s: return False
+    for c in s:
+        if not c in digits: return False
+    return True
+
+
+# Allowed function return types
+#
+return_types = ['void', 'short', 'long']
+
+
+# Allowed function argument types
+#
+arg_types = ['char', 'string', 'short', 'u_short', 'float', 'long', 'double']
+
+
+# Need to classify arguments as follows
+#       simple input variable
+#       simple output variable
+#       input array
+#       output array
+#       input giving size of some array
+#
+# Array dimensions can be specified as follows
+#       constant
+#       argN
+#       constant * argN
+#       retval
+#       constant * retval
+#
+# The dimensions given as constants * something are really
+# arrays of points where points are 2- 3- or 4-tuples
+#
+# We have to consider three lists:
+#       python input arguments
+#       C stub arguments (in & out)
+#       python output arguments (really return values)
+#
+# There is a mapping from python input arguments to the input arguments
+# of the C stub, and a further mapping from C stub arguments to the
+# python return values
+
+
+# Exception raised by checkarg() and generate()
+#
+arg_error = 'bad arg'
+
+
+# Function to check one argument.
+# Arguments: the type and the arg "name" (really mode plus subscript).
+# Raises arg_error if something's wrong.
+# Return type, mode, factor, rest of subscript; factor and rest may be empty.
+#
+def checkarg(type, arg):
+    #
+    # Turn "char *x" into "string x".
+    #
+    if type == 'char' and arg[0] == '*':
+        type = 'string'
+        arg = arg[1:]
+    #
+    # Check that the type is supported.
+    #
+    if type not in arg_types:
+        raise arg_error, ('bad type', type)
+    if type[:2] == 'u_':
+        type = 'unsigned ' + type[2:]
+    #
+    # Split it in the mode (first character) and the rest.
+    #
+    mode, rest = arg[:1], arg[1:]
+    #
+    # The mode must be 's' for send (= input) or 'r' for return argument.
+    #
+    if mode not in ('r', 's'):
+        raise arg_error, ('bad arg mode', mode)
+    #
+    # Is it a simple argument: if so, we are done.
+    #
+    if not rest:
+        return type, mode, '', ''
+    #
+    # Not a simple argument; must be an array.
+    # The 'rest' must be a subscript enclosed in [ and ].
+    # The subscript must be one of the following forms,
+    # otherwise we don't handle it (where N is a number):
+    #       N
+    #       argN
+    #       retval
+    #       N*argN
+    #       N*retval
+    #
+    if rest[:1] <> '[' or rest[-1:] <> ']':
+        raise arg_error, ('subscript expected', rest)
+    sub = rest[1:-1]
+    #
+    # Is there a leading number?
+    #
+    num, sub = getnum(sub)
+    if num:
+        # There is a leading number
+        if not sub:
+            # The subscript is just a number
+            return type, mode, num, ''
+        if sub[:1] == '*':
+            # There is a factor prefix
+            sub = sub[1:]
+        else:
+            raise arg_error, ('\'*\' expected', sub)
+    if sub == 'retval':
+        # size is retval -- must be a reply argument
+        if mode <> 'r':
+            raise arg_error, ('non-r mode with [retval]', mode)
+    elif not isnum(sub) and (sub[:3] <> 'arg' or not isnum(sub[3:])):
+        raise arg_error, ('bad subscript', sub)
+    #
+    return type, mode, num, sub
+
+
+# List of functions for which we have generated stubs
+#
+functions = []
+
+
+# Generate the stub for the given function, using the database of argument
+# information build by successive calls to checkarg()
+#
+def generate(type, func, database):
+    #
+    # Check that we can handle this case:
+    # no variable size reply arrays yet
+    #
+    n_in_args = 0
+    n_out_args = 0
+    #
+    for a_type, a_mode, a_factor, a_sub in database:
+        if a_mode == 's':
+            n_in_args = n_in_args + 1
+        elif a_mode == 'r':
+            n_out_args = n_out_args + 1
+        else:
+            # Can't happen
+            raise arg_error, ('bad a_mode', a_mode)
+        if (a_mode == 'r' and a_sub) or a_sub == 'retval':
+            err('Function', func, 'too complicated:',
+                a_type, a_mode, a_factor, a_sub)
+            print '/* XXX Too complicated to generate code for */'
+            return
+    #
+    functions.append(func)
+    #
+    # Stub header
+    #
+    print
+    print 'static PyObject *'
+    print 'gl_' + func + '(self, args)'
+    print '\tPyObject *self;'
+    print '\tPyObject *args;'
+    print '{'
+    #
+    # Declare return value if any
+    #
+    if type <> 'void':
+        print '\t' + type, 'retval;'
+    #
+    # Declare arguments
+    #
+    for i in range(len(database)):
+        a_type, a_mode, a_factor, a_sub = database[i]
+        print '\t' + a_type,
+        brac = ket = ''
+        if a_sub and not isnum(a_sub):
+            if a_factor:
+                brac = '('
+                ket = ')'
+            print brac + '*',
+        print 'arg' + repr(i+1) + ket,
+        if a_sub and isnum(a_sub):
+            print '[', a_sub, ']',
+        if a_factor:
+            print '[', a_factor, ']',
+        print ';'
+    #
+    # Find input arguments derived from array sizes
+    #
+    for i in range(len(database)):
+        a_type, a_mode, a_factor, a_sub = database[i]
+        if a_mode == 's' and a_sub[:3] == 'arg' and isnum(a_sub[3:]):
+            # Sending a variable-length array
+            n = eval(a_sub[3:])
+            if 1 <= n <= len(database):
+                b_type, b_mode, b_factor, b_sub = database[n-1]
+                if b_mode == 's':
+                    database[n-1] = b_type, 'i', a_factor, repr(i)
+                    n_in_args = n_in_args - 1
+    #
+    # Assign argument positions in the Python argument list
+    #
+    in_pos = []
+    i_in = 0
+    for i in range(len(database)):
+        a_type, a_mode, a_factor, a_sub = database[i]
+        if a_mode == 's':
+            in_pos.append(i_in)
+            i_in = i_in + 1
+        else:
+            in_pos.append(-1)
+    #
+    # Get input arguments
+    #
+    for i in range(len(database)):
+        a_type, a_mode, a_factor, a_sub = database[i]
+        if a_type[:9] == 'unsigned ':
+            xtype = a_type[9:]
+        else:
+            xtype = a_type
+        if a_mode == 'i':
+            #
+            # Implicit argument;
+            # a_factor is divisor if present,
+            # a_sub indicates which arg (`database index`)
+            #
+            j = eval(a_sub)
+            print '\tif',
+            print '(!geti' + xtype + 'arraysize(args,',
+            print repr(n_in_args) + ',',
+            print repr(in_pos[j]) + ',',
+            if xtype <> a_type:
+                print '('+xtype+' *)',
+            print '&arg' + repr(i+1) + '))'
+            print '\t\treturn NULL;'
+            if a_factor:
+                print '\targ' + repr(i+1),
+                print '= arg' + repr(i+1),
+                print '/', a_factor + ';'
+        elif a_mode == 's':
+            if a_sub and not isnum(a_sub):
+                # Allocate memory for varsize array
+                print '\tif ((arg' + repr(i+1), '=',
+                if a_factor:
+                    print '('+a_type+'(*)['+a_factor+'])',
+                print 'PyMem_NEW(' + a_type, ',',
+                if a_factor:
+                    print a_factor, '*',
+                print a_sub, ')) == NULL)'
+                print '\t\treturn PyErr_NoMemory();'
+            print '\tif',
+            if a_factor or a_sub: # Get a fixed-size array array
+                print '(!geti' + xtype + 'array(args,',
+                print repr(n_in_args) + ',',
+                print repr(in_pos[i]) + ',',
+                if a_factor: print a_factor,
+                if a_factor and a_sub: print '*',
+                if a_sub: print a_sub,
+                print ',',
+                if (a_sub and a_factor) or xtype <> a_type:
+                    print '('+xtype+' *)',
+                print 'arg' + repr(i+1) + '))'
+            else: # Get a simple variable
+                print '(!geti' + xtype + 'arg(args,',
+                print repr(n_in_args) + ',',
+                print repr(in_pos[i]) + ',',
+                if xtype <> a_type:
+                    print '('+xtype+' *)',
+                print '&arg' + repr(i+1) + '))'
+            print '\t\treturn NULL;'
+    #
+    # Begin of function call
+    #
+    if type <> 'void':
+        print '\tretval =', func + '(',
+    else:
+        print '\t' + func + '(',
+    #
+    # Argument list
+    #
+    for i in range(len(database)):
+        if i > 0: print ',',
+        a_type, a_mode, a_factor, a_sub = database[i]
+        if a_mode == 'r' and not a_factor:
+            print '&',
+        print 'arg' + repr(i+1),
+    #
+    # End of function call
+    #
+    print ');'
+    #
+    # Free varsize arrays
+    #
+    for i in range(len(database)):
+        a_type, a_mode, a_factor, a_sub = database[i]
+        if a_mode == 's' and a_sub and not isnum(a_sub):
+            print '\tPyMem_DEL(arg' + repr(i+1) + ');'
+    #
+    # Return
+    #
+    if n_out_args:
+        #
+        # Multiple return values -- construct a tuple
+        #
+        if type <> 'void':
+            n_out_args = n_out_args + 1
+        if n_out_args == 1:
+            for i in range(len(database)):
+                a_type, a_mode, a_factor, a_sub = database[i]
+                if a_mode == 'r':
+                    break
+            else:
+                raise arg_error, 'expected r arg not found'
+            print '\treturn',
+            print mkobject(a_type, 'arg' + repr(i+1)) + ';'
+        else:
+            print '\t{ PyObject *v = PyTuple_New(',
+            print n_out_args, ');'
+            print '\t  if (v == NULL) return NULL;'
+            i_out = 0
+            if type <> 'void':
+                print '\t  PyTuple_SetItem(v,',
+                print repr(i_out) + ',',
+                print mkobject(type, 'retval') + ');'
+                i_out = i_out + 1
+            for i in range(len(database)):
+                a_type, a_mode, a_factor, a_sub = database[i]
+                if a_mode == 'r':
+                    print '\t  PyTuple_SetItem(v,',
+                    print repr(i_out) + ',',
+                    s = mkobject(a_type, 'arg' + repr(i+1))
+                    print s + ');'
+                    i_out = i_out + 1
+            print '\t  return v;'
+            print '\t}'
+    else:
+        #
+        # Simple function return
+        # Return None or return value
+        #
+        if type == 'void':
+            print '\tPy_INCREF(Py_None);'
+            print '\treturn Py_None;'
+        else:
+            print '\treturn', mkobject(type, 'retval') + ';'
+    #
+    # Stub body closing brace
+    #
+    print '}'
+
+
+# Subroutine to return a function call to mknew<type>object(<arg>)
+#
+def mkobject(type, arg):
+    if type[:9] == 'unsigned ':
+        type = type[9:]
+        return 'mknew' + type + 'object((' + type + ') ' + arg + ')'
+    return 'mknew' + type + 'object(' + arg + ')'
+
+
+defined_archs = []
+
+# usage: cgen [ -Dmach ... ] [ file ]
+for arg in sys.argv[1:]:
+    if arg[:2] == '-D':
+        defined_archs.append(arg[2:])
+    else:
+        # Open optional file argument
+        sys.stdin = open(arg, 'r')
+
+
+# Input line number
+lno = 0
+
+
+# Input is divided in two parts, separated by a line containing '%%'.
+#       <part1>         -- literally copied to stdout
+#       <part2>         -- stub definitions
+
+# Variable indicating the current input part.
+#
+part = 1
+
+# Main loop over the input
+#
+while 1:
+    try:
+        line = raw_input()
+    except EOFError:
+        break
+    #
+    lno = lno+1
+    words = string.split(line)
+    #
+    if part == 1:
+        #
+        # In part 1, copy everything literally
+        # except look for a line of just '%%'
+        #
+        if words == ['%%']:
+            part = part + 1
+        else:
+            #
+            # Look for names of manually written
+            # stubs: a single percent followed by the name
+            # of the function in Python.
+            # The stub name is derived by prefixing 'gl_'.
+            #
+            if words and words[0][0] == '%':
+                func = words[0][1:]
+                if (not func) and words[1:]:
+                    func = words[1]
+                if func:
+                    functions.append(func)
+            else:
+                print line
+        continue
+    if not words:
+        continue                # skip empty line
+    elif words[0] == 'if':
+        # if XXX rest
+        # if !XXX rest
+        if words[1][0] == '!':
+            if words[1][1:] in defined_archs:
+                continue
+        elif words[1] not in defined_archs:
+            continue
+        words = words[2:]
+    if words[0] == '#include':
+        print line
+    elif words[0][:1] == '#':
+        pass                    # ignore comment
+    elif words[0] not in return_types:
+        err('Line', lno, ': bad return type :', words[0])
+    elif len(words) < 2:
+        err('Line', lno, ': no funcname :', line)
+    else:
+        if len(words) % 2 <> 0:
+            err('Line', lno, ': odd argument list :', words[2:])
+        else:
+            database = []
+            try:
+                for i in range(2, len(words), 2):
+                    x = checkarg(words[i], words[i+1])
+                    database.append(x)
+                print
+                print '/*',
+                for w in words: print w,
+                print '*/'
+                generate(words[0], words[1], database)
+            except arg_error, msg:
+                err('Line', lno, ':', msg)
+
+
+print
+print 'static struct PyMethodDef gl_methods[] = {'
+for func in functions:
+    print '\t{"' + func + '", gl_' + func + '},'
+print '\t{NULL, NULL} /* Sentinel */'
+print '};'
+print
+print 'void'
+print 'initgl()'
+print '{'
+print '\t(void) Py_InitModule("gl", gl_methods);'
+print '}'

Added: vendor/Python/current/Modules/cgensupport.c
===================================================================
--- vendor/Python/current/Modules/cgensupport.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/cgensupport.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,310 @@
+
+/* Functions used by cgen output */
+
+#include "Python.h"
+#include "cgensupport.h"
+
+
+/* Functions to extract arguments.
+   These needs to know the total number of arguments supplied,
+   since the argument list is a tuple only of there is more than
+   one argument. */
+
+int
+PyArg_GetObject(register PyObject *args, int nargs, int i, PyObject **p_arg)
+{
+	if (nargs != 1) {
+		if (args == NULL || !PyTuple_Check(args) ||
+				nargs != PyTuple_Size(args) ||
+				i < 0 || i >= nargs) {
+			return PyErr_BadArgument();
+		}
+		else {
+			args = PyTuple_GetItem(args, i);
+		}
+	}
+	if (args == NULL) {
+		return PyErr_BadArgument();
+	}
+	*p_arg = args;
+	return 1;
+}
+
+int
+PyArg_GetLong(register PyObject *args, int nargs, int i, long *p_arg)
+{
+	if (nargs != 1) {
+		if (args == NULL || !PyTuple_Check(args) ||
+				nargs != PyTuple_Size(args) ||
+				i < 0 || i >= nargs) {
+			return PyErr_BadArgument();
+		}
+		args = PyTuple_GetItem(args, i);
+	}
+	if (args == NULL || !PyInt_Check(args)) {
+		return PyErr_BadArgument();
+	}
+	*p_arg = PyInt_AsLong(args);
+	return 1;
+}
+
+int
+PyArg_GetShort(register PyObject *args, int nargs, int i, short *p_arg)
+{
+	long x;
+	if (!PyArg_GetLong(args, nargs, i, &x))
+		return 0;
+	*p_arg = (short) x;
+	return 1;
+}
+
+static int
+extractdouble(register PyObject *v, double *p_arg)
+{
+	if (v == NULL) {
+		/* Fall through to error return at end of function */
+	}
+	else if (PyFloat_Check(v)) {
+		*p_arg = PyFloat_AS_DOUBLE((PyFloatObject *)v);
+		return 1;
+	}
+	else if (PyInt_Check(v)) {
+		*p_arg = PyInt_AS_LONG((PyIntObject *)v);
+		return 1;
+	}
+	else if (PyLong_Check(v)) {
+		*p_arg = PyLong_AsDouble(v);
+		return 1;
+	}
+	return PyErr_BadArgument();
+}
+
+static int
+extractfloat(register PyObject *v, float *p_arg)
+{
+	if (v == NULL) {
+		/* Fall through to error return at end of function */
+	}
+	else if (PyFloat_Check(v)) {
+		*p_arg = (float) PyFloat_AS_DOUBLE((PyFloatObject *)v);
+		return 1;
+	}
+	else if (PyInt_Check(v)) {
+		*p_arg = (float) PyInt_AS_LONG((PyIntObject *)v);
+		return 1;
+	}
+	else if (PyLong_Check(v)) {
+		*p_arg = (float) PyLong_AsDouble(v);
+		return 1;
+	}
+	return PyErr_BadArgument();
+}
+
+int
+PyArg_GetFloat(register PyObject *args, int nargs, int i, float *p_arg)
+{
+	PyObject *v;
+	float x;
+	if (!PyArg_GetObject(args, nargs, i, &v))
+		return 0;
+	if (!extractfloat(v, &x))
+		return 0;
+	*p_arg = x;
+	return 1;
+}
+
+int
+PyArg_GetString(PyObject *args, int nargs, int i, string *p_arg)
+{
+	PyObject *v;
+	if (!PyArg_GetObject(args, nargs, i, &v))
+		return 0;
+	if (!PyString_Check(v)) {
+		return PyErr_BadArgument();
+	}
+	*p_arg = PyString_AsString(v);
+	return 1;
+}
+
+int
+PyArg_GetChar(PyObject *args, int nargs, int i, char *p_arg)
+{
+	string x;
+	if (!PyArg_GetString(args, nargs, i, &x))
+		return 0;
+	if (x[0] == '\0' || x[1] != '\0') {
+		/* Not exactly one char */
+		return PyErr_BadArgument();
+	}
+	*p_arg = x[0];
+	return 1;
+}
+
+int
+PyArg_GetLongArraySize(PyObject *args, int nargs, int i, long *p_arg)
+{
+	PyObject *v;
+	if (!PyArg_GetObject(args, nargs, i, &v))
+		return 0;
+	if (PyTuple_Check(v)) {
+		*p_arg = PyTuple_Size(v);
+		return 1;
+	}
+	if (PyList_Check(v)) {
+		*p_arg = PyList_Size(v);
+		return 1;
+	}
+	return PyErr_BadArgument();
+}
+
+int
+PyArg_GetShortArraySize(PyObject *args, int nargs, int i, short *p_arg)
+{
+	long x;
+	if (!PyArg_GetLongArraySize(args, nargs, i, &x))
+		return 0;
+	*p_arg = (short) x;
+	return 1;
+}
+
+/* XXX The following four are too similar.  Should share more code. */
+
+int
+PyArg_GetLongArray(PyObject *args, int nargs, int i, int n, long *p_arg)
+{
+	PyObject *v, *w;
+	if (!PyArg_GetObject(args, nargs, i, &v))
+		return 0;
+	if (PyTuple_Check(v)) {
+		if (PyTuple_Size(v) != n) {
+			return PyErr_BadArgument();
+		}
+		for (i = 0; i < n; i++) {
+			w = PyTuple_GetItem(v, i);
+			if (!PyInt_Check(w)) {
+				return PyErr_BadArgument();
+			}
+			p_arg[i] = PyInt_AsLong(w);
+		}
+		return 1;
+	}
+	else if (PyList_Check(v)) {
+		if (PyList_Size(v) != n) {
+			return PyErr_BadArgument();
+		}
+		for (i = 0; i < n; i++) {
+			w = PyList_GetItem(v, i);
+			if (!PyInt_Check(w)) {
+				return PyErr_BadArgument();
+			}
+			p_arg[i] = PyInt_AsLong(w);
+		}
+		return 1;
+	}
+	else {
+		return PyErr_BadArgument();
+	}
+}
+
+int
+PyArg_GetShortArray(PyObject *args, int nargs, int i, int n, short *p_arg)
+{
+	PyObject *v, *w;
+	if (!PyArg_GetObject(args, nargs, i, &v))
+		return 0;
+	if (PyTuple_Check(v)) {
+		if (PyTuple_Size(v) != n) {
+			return PyErr_BadArgument();
+		}
+		for (i = 0; i < n; i++) {
+			w = PyTuple_GetItem(v, i);
+			if (!PyInt_Check(w)) {
+				return PyErr_BadArgument();
+			}
+			p_arg[i] = (short) PyInt_AsLong(w);
+		}
+		return 1;
+	}
+	else if (PyList_Check(v)) {
+		if (PyList_Size(v) != n) {
+			return PyErr_BadArgument();
+		}
+		for (i = 0; i < n; i++) {
+			w = PyList_GetItem(v, i);
+			if (!PyInt_Check(w)) {
+				return PyErr_BadArgument();
+			}
+			p_arg[i] = (short) PyInt_AsLong(w);
+		}
+		return 1;
+	}
+	else {
+		return PyErr_BadArgument();
+	}
+}
+
+int
+PyArg_GetDoubleArray(PyObject *args, int nargs, int i, int n, double *p_arg)
+{
+	PyObject *v, *w;
+	if (!PyArg_GetObject(args, nargs, i, &v))
+		return 0;
+	if (PyTuple_Check(v)) {
+		if (PyTuple_Size(v) != n) {
+			return PyErr_BadArgument();
+		}
+		for (i = 0; i < n; i++) {
+			w = PyTuple_GetItem(v, i);
+			if (!extractdouble(w, &p_arg[i]))
+				return 0;
+		}
+		return 1;
+	}
+	else if (PyList_Check(v)) {
+		if (PyList_Size(v) != n) {
+			return PyErr_BadArgument();
+		}
+		for (i = 0; i < n; i++) {
+			w = PyList_GetItem(v, i);
+			if (!extractdouble(w, &p_arg[i]))
+				return 0;
+		}
+		return 1;
+	}
+	else {
+		return PyErr_BadArgument();
+	}
+}
+
+int
+PyArg_GetFloatArray(PyObject *args, int nargs, int i, int n, float *p_arg)
+{
+	PyObject *v, *w;
+	if (!PyArg_GetObject(args, nargs, i, &v))
+		return 0;
+	if (PyTuple_Check(v)) {
+		if (PyTuple_Size(v) != n) {
+			return PyErr_BadArgument();
+		}
+		for (i = 0; i < n; i++) {
+			w = PyTuple_GetItem(v, i);
+			if (!extractfloat(w, &p_arg[i]))
+				return 0;
+		}
+		return 1;
+	}
+	else if (PyList_Check(v)) {
+		if (PyList_Size(v) != n) {
+			return PyErr_BadArgument();
+		}
+		for (i = 0; i < n; i++) {
+			w = PyList_GetItem(v, i);
+			if (!extractfloat(w, &p_arg[i]))
+				return 0;
+		}
+		return 1;
+	}
+	else {
+		return PyErr_BadArgument();
+	}
+}

Added: vendor/Python/current/Modules/cgensupport.h
===================================================================
--- vendor/Python/current/Modules/cgensupport.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/cgensupport.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,64 @@
+#ifndef Py_CGENSUPPORT_H
+#define Py_CGENSUPPORT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Definitions used by cgen output */
+
+/* XXX This file is obsolete.  It is *only* used by glmodule.c. */
+
+typedef char *string;
+
+#define mknewlongobject(x) PyInt_FromLong(x)
+#define mknewshortobject(x) PyInt_FromLong((long)x)
+#define mknewfloatobject(x) PyFloat_FromDouble(x)
+#define mknewcharobject(ch) Py_BuildValue("c", ch)
+
+#define getichararg PyArg_GetChar
+#define getidoublearray PyArg_GetDoubleArray
+#define getifloatarg PyArg_GetFloat
+#define getifloatarray PyArg_GetFloatArray
+#define getilongarg PyArg_GetLong
+#define getilongarray PyArg_GetLongArray
+#define getilongarraysize PyArg_GetLongArraySize
+#define getiobjectarg PyArg_GetObject
+#define getishortarg PyArg_GetShort
+#define getishortarray PyArg_GetShortArray
+#define getishortarraysize PyArg_GetShortArraySize
+#define getistringarg PyArg_GetString
+
+extern int PyArg_GetObject(PyObject *args, int nargs,
+			   int i, PyObject **p_a);
+extern int PyArg_GetLong(PyObject *args, int nargs,
+			 int i, long *p_a);
+extern int PyArg_GetShort(PyObject *args, int nargs,
+			  int i, short *p_a);
+extern int PyArg_GetFloat(PyObject *args, int nargs,
+			  int i, float *p_a);
+extern int PyArg_GetString(PyObject *args, int nargs,
+			   int i, string *p_a);
+extern int PyArg_GetChar(PyObject *args, int nargs,
+			 int i, char *p_a);
+extern int PyArg_GetLongArray(PyObject *args, int nargs,
+			    int i, int n, long *p_a);
+extern int PyArg_GetShortArray(PyObject *args, int nargs,
+			    int i, int n, short *p_a);
+extern int PyArg_GetDoubleArray(PyObject *args, int nargs,
+				int i, int n, double *p_a);
+extern int PyArg_GetFloatArray(PyObject *args, int nargs,
+			       int i, int n, float *p_a);
+extern int PyArg_GetLongArraySize(PyObject *args, int nargs,
+				  int i, long *p_a);
+extern int PyArg_GetShortArraySize(PyObject *args, int nargs,
+				int i, short *p_a);
+extern int PyArg_GetDoubleArraySize(PyObject *args, int nargs,
+				    int i, double *p_a);
+extern int PyArg_GetFloatArraySize(PyObject *args, int nargs,
+				   int i, float *p_a);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_CGENSUPPORT_H */

Added: vendor/Python/current/Modules/cjkcodecs/README
===================================================================
--- vendor/Python/current/Modules/cjkcodecs/README	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/cjkcodecs/README	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,79 @@
+To generate or modify mapping headers
+-------------------------------------
+Mapping headers are imported from CJKCodecs as pre-generated form.
+If you need to tweak or add something on it, please look at tools/
+subdirectory of CJKCodecs' distribution.
+
+
+
+Notes on implmentation characteristics of each codecs
+-----------------------------------------------------
+
+1) Big5 codec
+
+  The big5 codec maps the following characters as cp950 does rather
+  than conforming Unicode.org's that maps to 0xFFFD.
+
+    BIG5        Unicode     Description
+
+    0xA15A      0x2574      SPACING UNDERSCORE
+    0xA1C3      0xFFE3      SPACING HEAVY OVERSCORE
+    0xA1C5      0x02CD      SPACING HEAVY UNDERSCORE
+    0xA1FE      0xFF0F      LT DIAG UP RIGHT TO LOW LEFT
+    0xA240      0xFF3C      LT DIAG UP LEFT TO LOW RIGHT
+    0xA2CC      0x5341      HANGZHOU NUMERAL TEN
+    0xA2CE      0x5345      HANGZHOU NUMERAL THIRTY
+
+  Because unicode 0x5341, 0x5345, 0xFF0F, 0xFF3C is mapped to another
+  big5 codes already, a roundtrip compatibility is not guaranteed for
+  them.
+
+
+2) cp932 codec
+
+  To conform to Windows's real mapping, cp932 codec maps the following
+  codepoints in addition of the official cp932 mapping.
+
+    CP932     Unicode     Description
+
+    0x80      0x80        UNDEFINED
+    0xA0      0xF8F0      UNDEFINED
+    0xFD      0xF8F1      UNDEFINED
+    0xFE      0xF8F2      UNDEFINED
+    0xFF      0xF8F3      UNDEFINED
+
+
+3) euc-jisx0213 codec
+
+  The euc-jisx0213 codec maps JIS X 0213 Plane 1 code 0x2140 into
+  unicode U+FF3C instead of U+005C as on unicode.org's mapping.
+  Because euc-jisx0213 has REVERSE SOLIDUS on 0x5c already and A140
+  is shown as a full width character, mapping to U+FF3C can make
+  more sense.
+
+  The euc-jisx0213 codec is enabled to decode JIS X 0212 codes on
+  codeset 2. Because JIS X 0212 and JIS X 0213 Plane 2 don't have
+  overlapped by each other, it doesn't bother standard conformations
+  (and JIS X 0213 Plane 2 is intended to use so.) On encoding
+  sessions, the codec will try to encode kanji characters in this
+  order:
+
+    JIS X 0213 Plane 1 -> JIS X 0213 Plane 2 -> JIS X 0212
+
+
+4) euc-jp codec
+
+  The euc-jp codec is a compatibility instance on these points:
+   - U+FF3C FULLWIDTH REVERSE SOLIDUS is mapped to EUC-JP A1C0 (vice versa)
+   - U+00A5 YEN SIGN is mapped to EUC-JP 0x5c. (one way)
+   - U+203E OVERLINE is mapped to EUC-JP 0x7e. (one way)
+
+
+5) shift-jis codec
+
+  The shift-jis codec is mapping 0x20-0x7e area to U+20-U+7E directly
+  instead of using JIS X 0201 for compatibility. The differences are:
+   - U+005C REVERSE SOLIDUS is mapped to SHIFT-JIS 0x5c.
+   - U+007E TILDE is mapped to SHIFT-JIS 0x7e.
+   - U+FF3C FULL-WIDTH REVERSE SOLIDUS is mapped to SHIFT-JIS 815f.
+

Added: vendor/Python/current/Modules/cjkcodecs/_codecs_cn.c
===================================================================
--- vendor/Python/current/Modules/cjkcodecs/_codecs_cn.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/cjkcodecs/_codecs_cn.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,443 @@
+/*
+ * _codecs_cn.c: Codecs collection for Mainland Chinese encodings
+ *
+ * Written by Hye-Shik Chang <perky at FreeBSD.org>
+ */
+
+#include "cjkcodecs.h"
+#include "mappings_cn.h"
+
+/**
+ * hz is predefined as 100 on AIX. So we undefine it to avoid
+ * conflict against hz codec's.
+ */
+#ifdef _AIX
+#undef hz
+#endif
+
+/* GBK and GB2312 map differently in few codepoints that are listed below:
+ *
+ *		gb2312				gbk
+ * A1A4		U+30FB KATAKANA MIDDLE DOT	U+00B7 MIDDLE DOT
+ * A1AA		U+2015 HORIZONTAL BAR		U+2014 EM DASH
+ * A844		undefined			U+2015 HORIZONTAL BAR
+ */
+
+#define GBK_DECODE(dc1, dc2, assi) \
+	if ((dc1) == 0xa1 && (dc2) == 0xaa) (assi) = 0x2014; \
+	else if ((dc1) == 0xa8 && (dc2) == 0x44) (assi) = 0x2015; \
+	else if ((dc1) == 0xa1 && (dc2) == 0xa4) (assi) = 0x00b7; \
+	else TRYMAP_DEC(gb2312, assi, dc1 ^ 0x80, dc2 ^ 0x80); \
+	else TRYMAP_DEC(gbkext, assi, dc1, dc2);
+
+#define GBK_ENCODE(code, assi) \
+	if ((code) == 0x2014) (assi) = 0xa1aa; \
+	else if ((code) == 0x2015) (assi) = 0xa844; \
+	else if ((code) == 0x00b7) (assi) = 0xa1a4; \
+	else if ((code) != 0x30fb && TRYMAP_ENC_COND(gbcommon, assi, code));
+
+/*
+ * GB2312 codec
+ */
+
+ENCODER(gb2312)
+{
+	while (inleft > 0) {
+		Py_UNICODE c = IN1;
+		DBCHAR code;
+
+		if (c < 0x80) {
+			WRITE1((unsigned char)c)
+			NEXT(1, 1)
+			continue;
+		}
+		UCS4INVALID(c)
+
+		REQUIRE_OUTBUF(2)
+		TRYMAP_ENC(gbcommon, code, c);
+		else return 1;
+
+		if (code & 0x8000) /* MSB set: GBK */
+			return 1;
+
+		OUT1((code >> 8) | 0x80)
+		OUT2((code & 0xFF) | 0x80)
+		NEXT(1, 2)
+	}
+
+	return 0;
+}
+
+DECODER(gb2312)
+{
+	while (inleft > 0) {
+		unsigned char c = **inbuf;
+
+		REQUIRE_OUTBUF(1)
+
+		if (c < 0x80) {
+			OUT1(c)
+			NEXT(1, 1)
+			continue;
+		}
+
+		REQUIRE_INBUF(2)
+		TRYMAP_DEC(gb2312, **outbuf, c ^ 0x80, IN2 ^ 0x80) {
+			NEXT(2, 1)
+		}
+		else return 2;
+	}
+
+	return 0;
+}
+
+
+/*
+ * GBK codec
+ */
+
+ENCODER(gbk)
+{
+	while (inleft > 0) {
+		Py_UNICODE c = IN1;
+		DBCHAR code;
+
+		if (c < 0x80) {
+			WRITE1((unsigned char)c)
+			NEXT(1, 1)
+			continue;
+		}
+		UCS4INVALID(c)
+
+		REQUIRE_OUTBUF(2)
+
+		GBK_ENCODE(c, code)
+		else return 1;
+
+		OUT1((code >> 8) | 0x80)
+		if (code & 0x8000)
+			OUT2((code & 0xFF)) /* MSB set: GBK */
+		else
+			OUT2((code & 0xFF) | 0x80) /* MSB unset: GB2312 */
+		NEXT(1, 2)
+	}
+
+	return 0;
+}
+
+DECODER(gbk)
+{
+	while (inleft > 0) {
+		unsigned char c = IN1;
+
+		REQUIRE_OUTBUF(1)
+
+		if (c < 0x80) {
+			OUT1(c)
+			NEXT(1, 1)
+			continue;
+		}
+
+		REQUIRE_INBUF(2)
+
+		GBK_DECODE(c, IN2, **outbuf)
+		else return 2;
+
+		NEXT(2, 1)
+	}
+
+	return 0;
+}
+
+
+/*
+ * GB18030 codec
+ */
+
+ENCODER(gb18030)
+{
+	while (inleft > 0) {
+		ucs4_t c = IN1;
+		DBCHAR code;
+
+		if (c < 0x80) {
+			WRITE1(c)
+			NEXT(1, 1)
+			continue;
+		}
+
+		DECODE_SURROGATE(c)
+		if (c > 0x10FFFF)
+#if Py_UNICODE_SIZE == 2
+			return 2; /* surrogates pair */
+#else
+			return 1;
+#endif
+		else if (c >= 0x10000) {
+			ucs4_t tc = c - 0x10000;
+
+			REQUIRE_OUTBUF(4)
+
+			OUT4((unsigned char)(tc % 10) + 0x30)
+			tc /= 10;
+			OUT3((unsigned char)(tc % 126) + 0x81)
+			tc /= 126;
+			OUT2((unsigned char)(tc % 10) + 0x30)
+			tc /= 10;
+			OUT1((unsigned char)(tc + 0x90))
+
+#if Py_UNICODE_SIZE == 2
+			NEXT(2, 4) /* surrogates pair */
+#else
+			NEXT(1, 4)
+#endif
+			continue;
+		}
+
+		REQUIRE_OUTBUF(2)
+
+		GBK_ENCODE(c, code)
+		else {
+			const struct _gb18030_to_unibmp_ranges *utrrange;
+
+			REQUIRE_OUTBUF(4)
+
+			for (utrrange = gb18030_to_unibmp_ranges;
+			     utrrange->first != 0;
+			     utrrange++)
+				if (utrrange->first <= c &&
+				    c <= utrrange->last) {
+					Py_UNICODE tc;
+
+					tc = c - utrrange->first +
+					     utrrange->base;
+
+					OUT4((unsigned char)(tc % 10) + 0x30)
+					tc /= 10;
+					OUT3((unsigned char)(tc % 126) + 0x81)
+					tc /= 126;
+					OUT2((unsigned char)(tc % 10) + 0x30)
+					tc /= 10;
+					OUT1((unsigned char)tc + 0x81)
+
+					NEXT(1, 4)
+					break;
+				}
+
+			if (utrrange->first == 0)
+				return 1;
+			continue;
+		}
+
+		OUT1((code >> 8) | 0x80)
+		if (code & 0x8000)
+			OUT2((code & 0xFF)) /* MSB set: GBK or GB18030ext */
+		else
+			OUT2((code & 0xFF) | 0x80) /* MSB unset: GB2312 */
+
+		NEXT(1, 2)
+	}
+
+	return 0;
+}
+
+DECODER(gb18030)
+{
+	while (inleft > 0) {
+		unsigned char c = IN1, c2;
+
+		REQUIRE_OUTBUF(1)
+
+		if (c < 0x80) {
+			OUT1(c)
+			NEXT(1, 1)
+			continue;
+		}
+
+		REQUIRE_INBUF(2)
+
+		c2 = IN2;
+		if (c2 >= 0x30 && c2 <= 0x39) { /* 4 bytes seq */
+			const struct _gb18030_to_unibmp_ranges *utr;
+			unsigned char c3, c4;
+			ucs4_t lseq;
+
+			REQUIRE_INBUF(4)
+			c3 = IN3;
+			c4 = IN4;
+			if (c < 0x81 || c3 < 0x81 || c4 < 0x30 || c4 > 0x39)
+				return 4;
+			c -= 0x81;  c2 -= 0x30;
+			c3 -= 0x81; c4 -= 0x30;
+
+			if (c < 4) { /* U+0080 - U+FFFF */
+				lseq = ((ucs4_t)c * 10 + c2) * 1260 +
+					(ucs4_t)c3 * 10 + c4;
+				if (lseq < 39420) {
+					for (utr = gb18030_to_unibmp_ranges;
+					     lseq >= (utr + 1)->base;
+					     utr++) ;
+					OUT1(utr->first - utr->base + lseq)
+					NEXT(4, 1)
+					continue;
+				}
+			}
+			else if (c >= 15) { /* U+10000 - U+10FFFF */
+				lseq = 0x10000 + (((ucs4_t)c-15) * 10 + c2)
+					* 1260 + (ucs4_t)c3 * 10 + c4;
+				if (lseq <= 0x10FFFF) {
+					WRITEUCS4(lseq);
+					NEXT_IN(4)
+					continue;
+				}
+			}
+			return 4;
+		}
+
+		GBK_DECODE(c, c2, **outbuf)
+		else TRYMAP_DEC(gb18030ext, **outbuf, c, c2);
+		else return 2;
+
+		NEXT(2, 1)
+	}
+
+	return 0;
+}
+
+
+/*
+ * HZ codec
+ */
+
+ENCODER_INIT(hz)
+{
+	state->i = 0;
+	return 0;
+}
+
+ENCODER_RESET(hz)
+{
+	if (state->i != 0) {
+		WRITE2('~', '}')
+		state->i = 0;
+		NEXT_OUT(2)
+	}
+	return 0;
+}
+
+ENCODER(hz)
+{
+	while (inleft > 0) {
+		Py_UNICODE c = IN1;
+		DBCHAR code;
+
+		if (c < 0x80) {
+			if (state->i == 0) {
+				WRITE1((unsigned char)c)
+				NEXT(1, 1)
+			}
+			else {
+				WRITE3('~', '}', (unsigned char)c)
+				NEXT(1, 3)
+				state->i = 0;
+			}
+			continue;
+		}
+
+		UCS4INVALID(c)
+
+		TRYMAP_ENC(gbcommon, code, c);
+		else return 1;
+
+		if (code & 0x8000) /* MSB set: GBK */
+			return 1;
+
+		if (state->i == 0) {
+			WRITE4('~', '{', code >> 8, code & 0xff)
+			NEXT(1, 4)
+			state->i = 1;
+		}
+		else {
+			WRITE2(code >> 8, code & 0xff)
+			NEXT(1, 2)
+		}
+	}
+
+	return 0;
+}
+
+DECODER_INIT(hz)
+{
+	state->i = 0;
+	return 0;
+}
+
+DECODER_RESET(hz)
+{
+	state->i = 0;
+	return 0;
+}
+
+DECODER(hz)
+{
+	while (inleft > 0) {
+		unsigned char c = IN1;
+
+		if (c == '~') {
+			unsigned char c2 = IN2;
+
+			REQUIRE_INBUF(2)
+			if (c2 == '~') {
+				WRITE1('~')
+				NEXT(2, 1)
+				continue;
+			}
+			else if (c2 == '{' && state->i == 0)
+				state->i = 1; /* set GB */
+			else if (c2 == '}' && state->i == 1)
+				state->i = 0; /* set ASCII */
+			else if (c2 == '\n')
+				; /* line-continuation */
+			else
+				return 2;
+			NEXT(2, 0);
+			continue;
+		}
+
+		if (c & 0x80)
+			return 1;
+
+		if (state->i == 0) { /* ASCII mode */
+			WRITE1(c)
+			NEXT(1, 1)
+		}
+		else { /* GB mode */
+			REQUIRE_INBUF(2)
+			REQUIRE_OUTBUF(1)
+			TRYMAP_DEC(gb2312, **outbuf, c, IN2) {
+				NEXT(2, 1)
+			}
+			else
+				return 2;
+		}
+	}
+
+	return 0;
+}
+
+
+BEGIN_MAPPINGS_LIST
+  MAPPING_DECONLY(gb2312)
+  MAPPING_DECONLY(gbkext)
+  MAPPING_ENCONLY(gbcommon)
+  MAPPING_ENCDEC(gb18030ext)
+END_MAPPINGS_LIST
+
+BEGIN_CODECS_LIST
+  CODEC_STATELESS(gb2312)
+  CODEC_STATELESS(gbk)
+  CODEC_STATELESS(gb18030)
+  CODEC_STATEFUL(hz)
+END_CODECS_LIST
+
+I_AM_A_MODULE_FOR(cn)

Added: vendor/Python/current/Modules/cjkcodecs/_codecs_hk.c
===================================================================
--- vendor/Python/current/Modules/cjkcodecs/_codecs_hk.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/cjkcodecs/_codecs_hk.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,143 @@
+/*
+ * _codecs_hk.c: Codecs collection for encodings from Hong Kong
+ *
+ * Written by Hye-Shik Chang <perky at FreeBSD.org>
+ */
+
+#define USING_IMPORTED_MAPS
+
+#include "cjkcodecs.h"
+#include "mappings_hk.h"
+
+/*
+ * BIG5HKSCS codec
+ */
+
+static const encode_map *big5_encmap = NULL;
+static const decode_map *big5_decmap = NULL;
+
+CODEC_INIT(big5hkscs)
+{
+	static int initialized = 0;
+
+	if (!initialized && IMPORT_MAP(tw, big5, &big5_encmap, &big5_decmap))
+		return -1;
+	initialized = 1;
+	return 0;
+}
+
+ENCODER(big5hkscs)
+{
+	while (inleft > 0) {
+		ucs4_t c = **inbuf;
+		DBCHAR code;
+		Py_ssize_t insize;
+
+		if (c < 0x80) {
+			REQUIRE_OUTBUF(1)
+			**outbuf = (unsigned char)c;
+			NEXT(1, 1)
+			continue;
+		}
+
+		DECODE_SURROGATE(c)
+		insize = GET_INSIZE(c);
+
+		REQUIRE_OUTBUF(2)
+
+		if (c < 0x10000) {
+			TRYMAP_ENC(big5hkscs_bmp, code, c);
+			else TRYMAP_ENC(big5, code, c);
+			else return 1;
+		}
+		else if (c < 0x20000)
+			return insize;
+		else if (c < 0x30000) {
+			TRYMAP_ENC(big5hkscs_nonbmp, code, c & 0xffff);
+			else return insize;
+		}
+		else
+			return insize;
+
+		OUT1(code >> 8)
+		OUT2(code & 0xFF)
+		NEXT(insize, 2)
+	}
+
+	return 0;
+}
+
+#define BH2S(c1, c2) (((c1) - 0x88) * (0xfe - 0x40 + 1) + ((c2) - 0x40))
+
+DECODER(big5hkscs)
+{
+	while (inleft > 0) {
+		unsigned char c = IN1;
+		ucs4_t decoded;
+
+		REQUIRE_OUTBUF(1)
+
+		if (c < 0x80) {
+			OUT1(c)
+			NEXT(1, 1)
+			continue;
+		}
+
+		REQUIRE_INBUF(2)
+
+		if (0xc6 <= c && c <= 0xc8 && (c >= 0xc7 || IN2 >= 0xa1))
+			goto hkscsdec;
+
+		TRYMAP_DEC(big5, **outbuf, c, IN2) {
+			NEXT(2, 1)
+		}
+		else
+hkscsdec:	TRYMAP_DEC(big5hkscs, decoded, c, IN2) {
+			int s = BH2S(c, IN2);
+			const unsigned char *hintbase;
+
+			assert(0x88 <= c && c <= 0xfe);
+			assert(0x40 <= IN2 && IN2 <= 0xfe);
+
+			if (BH2S(0x88, 0x40) <= s && s <= BH2S(0xa0, 0xfe)) {
+				hintbase = big5hkscs_phint_0;
+				s -= BH2S(0x88, 0x40);
+			}
+			else if (BH2S(0xc6,0xa1) <= s && s <= BH2S(0xc8,0xfe)){
+				hintbase = big5hkscs_phint_11939;
+				s -= BH2S(0xc6, 0xa1);
+			}
+			else if (BH2S(0xf9,0xd6) <= s && s <= BH2S(0xfe,0xfe)){
+				hintbase = big5hkscs_phint_21733;
+				s -= BH2S(0xf9, 0xd6);
+			}
+			else
+				return MBERR_INTERNAL;
+
+			if (hintbase[s >> 3] & (1 << (s & 7))) {
+				WRITEUCS4(decoded | 0x20000)
+				NEXT_IN(2)
+			}
+			else {
+				OUT1(decoded)
+				NEXT(2, 1)
+			}
+		}
+		else return 2;
+	}
+
+	return 0;
+}
+
+
+BEGIN_MAPPINGS_LIST
+  MAPPING_DECONLY(big5hkscs)
+  MAPPING_ENCONLY(big5hkscs_bmp)
+  MAPPING_ENCONLY(big5hkscs_nonbmp)
+END_MAPPINGS_LIST
+
+BEGIN_CODECS_LIST
+  CODEC_STATELESS_WINIT(big5hkscs)
+END_CODECS_LIST
+
+I_AM_A_MODULE_FOR(hk)

Added: vendor/Python/current/Modules/cjkcodecs/_codecs_iso2022.c
===================================================================
--- vendor/Python/current/Modules/cjkcodecs/_codecs_iso2022.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/cjkcodecs/_codecs_iso2022.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1131 @@
+/*
+ * _codecs_iso2022.c: Codecs collection for ISO-2022 encodings.
+ *
+ * Written by Hye-Shik Chang <perky at FreeBSD.org>
+ */
+
+#define USING_IMPORTED_MAPS
+#define USING_BINARY_PAIR_SEARCH
+#define EXTERN_JISX0213_PAIR
+#define EMULATE_JISX0213_2000_ENCODE_INVALID MAP_UNMAPPABLE
+#define EMULATE_JISX0213_2000_DECODE_INVALID MAP_UNMAPPABLE
+
+#include "cjkcodecs.h"
+#include "alg_jisx0201.h"
+#include "emu_jisx0213_2000.h"
+#include "mappings_jisx0213_pair.h"
+
+/* STATE
+
+   state->c[0-3]
+
+	00000000
+	||^^^^^|
+	|+-----+----  G0-3 Character Set
+	+-----------  Is G0-3 double byte?
+
+   state->c[4]
+
+	00000000
+	      ||
+	      |+----  Locked-Shift?
+	      +-----  ESC Throughout
+*/
+
+#define ESC			0x1B
+#define SO			0x0E
+#define SI			0x0F
+#define LF			0x0A
+
+#define MAX_ESCSEQLEN		16
+
+#define CHARSET_ISO8859_1	'A'
+#define CHARSET_ASCII		'B'
+#define CHARSET_ISO8859_7	'F'
+#define CHARSET_JISX0201_K	'I'
+#define CHARSET_JISX0201_R	'J'
+
+#define CHARSET_GB2312		('A'|CHARSET_DBCS)
+#define CHARSET_JISX0208	('B'|CHARSET_DBCS)
+#define CHARSET_KSX1001		('C'|CHARSET_DBCS)
+#define CHARSET_JISX0212	('D'|CHARSET_DBCS)
+#define CHARSET_GB2312_8565	('E'|CHARSET_DBCS)
+#define CHARSET_CNS11643_1	('G'|CHARSET_DBCS)
+#define CHARSET_CNS11643_2	('H'|CHARSET_DBCS)
+#define CHARSET_JISX0213_2000_1	('O'|CHARSET_DBCS)
+#define CHARSET_JISX0213_2	('P'|CHARSET_DBCS)
+#define CHARSET_JISX0213_2004_1	('Q'|CHARSET_DBCS)
+#define CHARSET_JISX0208_O	('@'|CHARSET_DBCS)
+
+#define CHARSET_DBCS		0x80
+#define ESCMARK(mark)		((mark) & 0x7f)
+
+#define IS_ESCEND(c)	(((c) >= 'A' && (c) <= 'Z') || (c) == '@')
+#define IS_ISO2022ESC(c2) \
+		((c2) == '(' || (c2) == ')' || (c2) == '$' || \
+		 (c2) == '.' || (c2) == '&')
+	/* this is not a complete list of ISO-2022 escape sequence headers.
+	 * but, it's enough to implement CJK instances of iso-2022. */
+
+#define MAP_UNMAPPABLE		0xFFFF
+#define MAP_MULTIPLE_AVAIL	0xFFFE /* for JIS X 0213 */
+
+#define F_SHIFTED		0x01
+#define F_ESCTHROUGHOUT		0x02
+
+#define STATE_SETG(dn, v)	((state)->c[dn]) = (v);
+#define STATE_GETG(dn)		((state)->c[dn])
+
+#define STATE_G0		STATE_GETG(0)
+#define STATE_G1		STATE_GETG(1)
+#define STATE_G2		STATE_GETG(2)
+#define STATE_G3		STATE_GETG(3)
+#define STATE_SETG0(v)		STATE_SETG(0, v)
+#define STATE_SETG1(v)		STATE_SETG(1, v)
+#define STATE_SETG2(v)		STATE_SETG(2, v)
+#define STATE_SETG3(v)		STATE_SETG(3, v)
+
+#define STATE_SETFLAG(f)	((state)->c[4]) |= (f);
+#define STATE_GETFLAG(f)	((state)->c[4] & (f))
+#define STATE_CLEARFLAG(f)	((state)->c[4]) &= ~(f);
+#define STATE_CLEARFLAGS()	((state)->c[4]) = 0;
+
+#define ISO2022_CONFIG		((const struct iso2022_config *)config)
+#define CONFIG_ISSET(flag)	(ISO2022_CONFIG->flags & (flag))
+#define CONFIG_DESIGNATIONS	(ISO2022_CONFIG->designations)
+
+/* iso2022_config.flags */
+#define NO_SHIFT		0x01
+#define USE_G2			0x02
+#define USE_JISX0208_EXT	0x04
+
+/*-*- internal data structures -*-*/
+
+typedef int (*iso2022_init_func)(void);
+typedef ucs4_t (*iso2022_decode_func)(const unsigned char *data);
+typedef DBCHAR (*iso2022_encode_func)(const ucs4_t *data, Py_ssize_t *length);
+
+struct iso2022_designation {
+	unsigned char mark;
+	unsigned char plane;
+	unsigned char width;
+	iso2022_init_func initializer;
+	iso2022_decode_func decoder;
+	iso2022_encode_func encoder;
+};
+
+struct iso2022_config {
+	int flags;
+	const struct iso2022_designation *designations; /* non-ascii desigs */
+};
+
+/*-*- iso-2022 codec implementation -*-*/
+
+CODEC_INIT(iso2022)
+{
+	const struct iso2022_designation *desig = CONFIG_DESIGNATIONS;
+	for (desig = CONFIG_DESIGNATIONS; desig->mark; desig++)
+		if (desig->initializer != NULL && desig->initializer() != 0)
+			return -1;
+	return 0;
+}
+
+ENCODER_INIT(iso2022)
+{
+	STATE_CLEARFLAGS()
+	STATE_SETG0(CHARSET_ASCII)
+	STATE_SETG1(CHARSET_ASCII)
+	return 0;
+}
+
+ENCODER_RESET(iso2022)
+{
+	if (STATE_GETFLAG(F_SHIFTED)) {
+		WRITE1(SI)
+		NEXT_OUT(1)
+		STATE_CLEARFLAG(F_SHIFTED)
+	}
+	if (STATE_G0 != CHARSET_ASCII) {
+		WRITE3(ESC, '(', 'B')
+		NEXT_OUT(3)
+		STATE_SETG0(CHARSET_ASCII)
+	}
+	return 0;
+}
+
+ENCODER(iso2022)
+{
+	while (inleft > 0) {
+		const struct iso2022_designation *dsg;
+		DBCHAR encoded;
+		ucs4_t c = **inbuf;
+		Py_ssize_t insize;
+
+		if (c < 0x80) {
+			if (STATE_G0 != CHARSET_ASCII) {
+				WRITE3(ESC, '(', 'B')
+				STATE_SETG0(CHARSET_ASCII)
+				NEXT_OUT(3)
+			}
+			if (STATE_GETFLAG(F_SHIFTED)) {
+				WRITE1(SI)
+				STATE_CLEARFLAG(F_SHIFTED)
+				NEXT_OUT(1)
+			}
+			WRITE1((unsigned char)c)
+			NEXT(1, 1)
+			continue;
+		}
+
+		DECODE_SURROGATE(c)
+		insize = GET_INSIZE(c);
+
+		encoded = MAP_UNMAPPABLE;
+		for (dsg = CONFIG_DESIGNATIONS; dsg->mark; dsg++) {
+			Py_ssize_t length = 1;
+			encoded = dsg->encoder(&c, &length);
+			if (encoded == MAP_MULTIPLE_AVAIL) {
+				/* this implementation won't work for pair
+				 * of non-bmp characters. */
+				if (inleft < 2) {
+					if (!(flags & MBENC_FLUSH))
+						return MBERR_TOOFEW;
+					length = -1;
+				}
+				else
+					length = 2;
+#if Py_UNICODE_SIZE == 2
+				if (length == 2) {
+					ucs4_t u4in[2];
+					u4in[0] = (ucs4_t)IN1;
+					u4in[1] = (ucs4_t)IN2;
+					encoded = dsg->encoder(u4in, &length);
+				} else
+					encoded = dsg->encoder(&c, &length);
+#else
+				encoded = dsg->encoder(*inbuf, &length);
+#endif
+				if (encoded != MAP_UNMAPPABLE) {
+					insize = length;
+					break;
+				}
+			}
+			else if (encoded != MAP_UNMAPPABLE)
+				break;
+		}
+
+		if (!dsg->mark)
+			return 1;
+		assert(dsg->width == 1 || dsg->width == 2);
+
+		switch (dsg->plane) {
+		case 0: /* G0 */
+			if (STATE_GETFLAG(F_SHIFTED)) {
+				WRITE1(SI)
+				STATE_CLEARFLAG(F_SHIFTED)
+				NEXT_OUT(1)
+			}
+			if (STATE_G0 != dsg->mark) {
+				if (dsg->width == 1) {
+					WRITE3(ESC, '(', ESCMARK(dsg->mark))
+					STATE_SETG0(dsg->mark)
+					NEXT_OUT(3)
+				}
+				else if (dsg->mark == CHARSET_JISX0208) {
+					WRITE3(ESC, '$', ESCMARK(dsg->mark))
+					STATE_SETG0(dsg->mark)
+					NEXT_OUT(3)
+				}
+				else {
+					WRITE4(ESC, '$', '(',
+						ESCMARK(dsg->mark))
+					STATE_SETG0(dsg->mark)
+					NEXT_OUT(4)
+				}
+			}
+			break;
+		case 1: /* G1 */
+			if (STATE_G1 != dsg->mark) {
+				if (dsg->width == 1) {
+					WRITE3(ESC, ')', ESCMARK(dsg->mark))
+					STATE_SETG1(dsg->mark)
+					NEXT_OUT(3)
+				}
+				else {
+					WRITE4(ESC, '$', ')',
+						ESCMARK(dsg->mark))
+					STATE_SETG1(dsg->mark)
+					NEXT_OUT(4)
+				}
+			}
+			if (!STATE_GETFLAG(F_SHIFTED)) {
+				WRITE1(SO)
+				STATE_SETFLAG(F_SHIFTED)
+				NEXT_OUT(1)
+			}
+			break;
+		default: /* G2 and G3 is not supported: no encoding in
+			  * CJKCodecs are using them yet */
+			return MBERR_INTERNAL;
+		}
+
+		if (dsg->width == 1) {
+			WRITE1((unsigned char)encoded)
+			NEXT_OUT(1)
+		}
+		else {
+			WRITE2(encoded >> 8, encoded & 0xff)
+			NEXT_OUT(2)
+		}
+		NEXT_IN(insize)
+	}
+
+	return 0;
+}
+
+DECODER_INIT(iso2022)
+{
+	STATE_CLEARFLAGS()
+	STATE_SETG0(CHARSET_ASCII)
+	STATE_SETG1(CHARSET_ASCII)
+	STATE_SETG2(CHARSET_ASCII)
+	return 0;
+}
+
+DECODER_RESET(iso2022)
+{
+	STATE_SETG0(CHARSET_ASCII)
+	STATE_CLEARFLAG(F_SHIFTED)
+	return 0;
+}
+
+static Py_ssize_t
+iso2022processesc(const void *config, MultibyteCodec_State *state,
+		  const unsigned char **inbuf, Py_ssize_t *inleft)
+{
+	unsigned char charset, designation;
+	Py_ssize_t i, esclen;
+
+	for (i = 1;i < MAX_ESCSEQLEN;i++) {
+		if (i >= *inleft)
+			return MBERR_TOOFEW;
+		if (IS_ESCEND((*inbuf)[i])) {
+			esclen = i + 1;
+			break;
+		}
+		else if (CONFIG_ISSET(USE_JISX0208_EXT) && i+1 < *inleft &&
+			 (*inbuf)[i] == '&' && (*inbuf)[i+1] == '@')
+			i += 2;
+	}
+
+	if (i >= MAX_ESCSEQLEN)
+		return 1; /* unterminated escape sequence */
+
+	switch (esclen) {
+	case 3:
+		if (IN2 == '$') {
+			charset = IN3 | CHARSET_DBCS;
+			designation = 0;
+		}
+		else {
+			charset = IN3;
+			if (IN2 == '(') designation = 0;
+			else if (IN2 == ')') designation = 1;
+			else if (CONFIG_ISSET(USE_G2) && IN2 == '.')
+				designation = 2;
+			else return 3;
+		}
+		break;
+	case 4:
+		if (IN2 != '$')
+			return 4;
+
+		charset = IN4 | CHARSET_DBCS;
+		if (IN3 == '(') designation = 0;
+		else if (IN3 == ')') designation = 1;
+		else return 4;
+		break;
+	case 6: /* designation with prefix */
+		if (CONFIG_ISSET(USE_JISX0208_EXT) &&
+		    (*inbuf)[3] == ESC && (*inbuf)[4] == '$' &&
+		    (*inbuf)[5] == 'B') {
+			charset = 'B' | CHARSET_DBCS;
+			designation = 0;
+		}
+		else
+			return 6;
+		break;
+	default:
+		return esclen;
+	}
+
+	/* raise error when the charset is not designated for this encoding */
+	if (charset != CHARSET_ASCII) {
+		const struct iso2022_designation *dsg;
+
+		for (dsg = CONFIG_DESIGNATIONS; dsg->mark; dsg++)
+			if (dsg->mark == charset)
+				break;
+		if (!dsg->mark)
+			return esclen;
+	}
+
+	STATE_SETG(designation, charset)
+	*inleft -= esclen;
+	(*inbuf) += esclen;
+	return 0;
+}
+
+#define ISO8859_7_DECODE(c, assi)					\
+	if ((c) < 0xa0) (assi) = (c);					\
+	else if ((c) < 0xc0 && (0x288f3bc9L & (1L << ((c)-0xa0))))	\
+		(assi) = (c);						\
+	else if ((c) >= 0xb4 && (c) <= 0xfe && ((c) >= 0xd4 ||		\
+		 (0xbffffd77L & (1L << ((c)-0xb4)))))			\
+		(assi) = 0x02d0 + (c);					\
+	else if ((c) == 0xa1) (assi) = 0x2018;				\
+	else if ((c) == 0xa2) (assi) = 0x2019;				\
+	else if ((c) == 0xaf) (assi) = 0x2015;
+
+static Py_ssize_t
+iso2022processg2(const void *config, MultibyteCodec_State *state,
+		 const unsigned char **inbuf, Py_ssize_t *inleft,
+		 Py_UNICODE **outbuf, Py_ssize_t *outleft)
+{
+	/* not written to use encoder, decoder functions because only few
+	 * encodings use G2 designations in CJKCodecs */
+	if (STATE_G2 == CHARSET_ISO8859_1) {
+		if (IN3 < 0x80)
+			OUT1(IN3 + 0x80)
+		else
+			return 3;
+	}
+	else if (STATE_G2 == CHARSET_ISO8859_7) {
+		ISO8859_7_DECODE(IN3 ^ 0x80, **outbuf)
+		else return 3;
+	}
+	else if (STATE_G2 == CHARSET_ASCII) {
+		if (IN3 & 0x80) return 3;
+		else **outbuf = IN3;
+	}
+	else
+		return MBERR_INTERNAL;
+
+	(*inbuf) += 3;
+	*inleft -= 3;
+	(*outbuf) += 1;
+	*outleft -= 1;
+	return 0;
+}
+
+DECODER(iso2022)
+{
+	const struct iso2022_designation *dsgcache = NULL;
+
+	while (inleft > 0) {
+		unsigned char c = IN1;
+		Py_ssize_t err;
+
+		if (STATE_GETFLAG(F_ESCTHROUGHOUT)) {
+			/* ESC throughout mode:
+			 * for non-iso2022 escape sequences */
+			WRITE1(c) /* assume as ISO-8859-1 */
+			NEXT(1, 1)
+			if (IS_ESCEND(c)) {
+				STATE_CLEARFLAG(F_ESCTHROUGHOUT)
+			}
+			continue;
+		}
+
+		switch (c) {
+		case ESC:
+			REQUIRE_INBUF(2)
+			if (IS_ISO2022ESC(IN2)) {
+				err = iso2022processesc(config, state,
+							inbuf, &inleft);
+				if (err != 0)
+					return err;
+			}
+			else if (CONFIG_ISSET(USE_G2) && IN2 == 'N') {/* SS2 */
+				REQUIRE_INBUF(3)
+				err = iso2022processg2(config, state,
+					inbuf, &inleft, outbuf, &outleft);
+				if (err != 0)
+					return err;
+			}
+			else {
+				WRITE1(ESC)
+				STATE_SETFLAG(F_ESCTHROUGHOUT)
+				NEXT(1, 1)
+			}
+			break;
+		case SI:
+			if (CONFIG_ISSET(NO_SHIFT))
+				goto bypass;
+			STATE_CLEARFLAG(F_SHIFTED)
+			NEXT_IN(1)
+			break;
+		case SO:
+			if (CONFIG_ISSET(NO_SHIFT))
+				goto bypass;
+			STATE_SETFLAG(F_SHIFTED)
+			NEXT_IN(1)
+			break;
+		case LF:
+			STATE_CLEARFLAG(F_SHIFTED)
+			WRITE1(LF)
+			NEXT(1, 1)
+			break;
+		default:
+			if (c < 0x20) /* C0 */
+				goto bypass;
+			else if (c >= 0x80)
+				return 1;
+			else {
+				const struct iso2022_designation *dsg;
+				unsigned char charset;
+				ucs4_t decoded;
+
+				if (STATE_GETFLAG(F_SHIFTED))
+					charset = STATE_G1;
+				else
+					charset = STATE_G0;
+
+				if (charset == CHARSET_ASCII) {
+bypass:					WRITE1(c)
+					NEXT(1, 1)
+					break;
+				}
+
+				if (dsgcache != NULL &&
+				    dsgcache->mark == charset)
+					dsg = dsgcache;
+				else {
+					for (dsg = CONFIG_DESIGNATIONS;
+					     dsg->mark != charset
+#ifdef Py_DEBUG
+						&& dsg->mark != '\0'
+#endif
+					     ;dsg++)
+						/* noop */;
+					assert(dsg->mark != '\0');
+					dsgcache = dsg;
+				}
+
+				REQUIRE_INBUF(dsg->width)
+				decoded = dsg->decoder(*inbuf);
+				if (decoded == MAP_UNMAPPABLE)
+					return dsg->width;
+
+				if (decoded < 0x10000) {
+					WRITE1(decoded)
+					NEXT_OUT(1)
+				}
+				else if (decoded < 0x30000) {
+					WRITEUCS4(decoded)
+				}
+				else { /* JIS X 0213 pairs */
+					WRITE2(decoded >> 16, decoded & 0xffff)
+					NEXT_OUT(2)
+				}
+				NEXT_IN(dsg->width)
+			}
+			break;
+		}
+	}
+	return 0;
+}
+
+/*-*- mapping table holders -*-*/
+
+#define ENCMAP(enc) static const encode_map *enc##_encmap = NULL;
+#define DECMAP(enc) static const decode_map *enc##_decmap = NULL;
+
+/* kr */
+ENCMAP(cp949)
+DECMAP(ksx1001)
+
+/* jp */
+ENCMAP(jisxcommon)
+DECMAP(jisx0208)
+DECMAP(jisx0212)
+ENCMAP(jisx0213_bmp)
+DECMAP(jisx0213_1_bmp)
+DECMAP(jisx0213_2_bmp)
+ENCMAP(jisx0213_emp)
+DECMAP(jisx0213_1_emp)
+DECMAP(jisx0213_2_emp)
+
+/* cn */
+ENCMAP(gbcommon)
+DECMAP(gb2312)
+
+/* tw */
+
+/*-*- mapping access functions -*-*/
+
+static int
+ksx1001_init(void)
+{
+	static int initialized = 0;
+
+	if (!initialized && (
+			IMPORT_MAP(kr, cp949, &cp949_encmap, NULL) ||
+			IMPORT_MAP(kr, ksx1001, NULL, &ksx1001_decmap)))
+		return -1;
+	initialized = 1;
+	return 0;
+}
+
+static ucs4_t
+ksx1001_decoder(const unsigned char *data)
+{
+	ucs4_t u;
+	TRYMAP_DEC(ksx1001, u, data[0], data[1])
+		return u;
+	else
+		return MAP_UNMAPPABLE;
+}
+
+static DBCHAR
+ksx1001_encoder(const ucs4_t *data, Py_ssize_t *length)
+{
+	DBCHAR coded;
+	assert(*length == 1);
+	if (*data < 0x10000) {
+		TRYMAP_ENC(cp949, coded, *data)
+			if (!(coded & 0x8000))
+				return coded;
+	}
+	return MAP_UNMAPPABLE;
+}
+
+static int
+jisx0208_init(void)
+{
+	static int initialized = 0;
+
+	if (!initialized && (
+			IMPORT_MAP(jp, jisxcommon, &jisxcommon_encmap, NULL) ||
+			IMPORT_MAP(jp, jisx0208, NULL, &jisx0208_decmap)))
+		return -1;
+	initialized = 1;
+	return 0;
+}
+
+static ucs4_t
+jisx0208_decoder(const unsigned char *data)
+{
+	ucs4_t u;
+	if (data[0] == 0x21 && data[1] == 0x40) /* F/W REVERSE SOLIDUS */
+		return 0xff3c;
+	else TRYMAP_DEC(jisx0208, u, data[0], data[1])
+		return u;
+	else
+		return MAP_UNMAPPABLE;
+}
+
+static DBCHAR
+jisx0208_encoder(const ucs4_t *data, Py_ssize_t *length)
+{
+	DBCHAR coded;
+	assert(*length == 1);
+	if (*data < 0x10000) {
+		if (*data == 0xff3c) /* F/W REVERSE SOLIDUS */
+			return 0x2140;
+		else TRYMAP_ENC(jisxcommon, coded, *data) {
+			if (!(coded & 0x8000))
+				return coded;
+		}
+	}
+	return MAP_UNMAPPABLE;
+}
+
+static int
+jisx0212_init(void)
+{
+	static int initialized = 0;
+
+	if (!initialized && (
+			IMPORT_MAP(jp, jisxcommon, &jisxcommon_encmap, NULL) ||
+			IMPORT_MAP(jp, jisx0212, NULL, &jisx0212_decmap)))
+		return -1;
+	initialized = 1;
+	return 0;
+}
+
+static ucs4_t
+jisx0212_decoder(const unsigned char *data)
+{
+	ucs4_t u;
+	TRYMAP_DEC(jisx0212, u, data[0], data[1])
+		return u;
+	else
+		return MAP_UNMAPPABLE;
+}
+
+static DBCHAR
+jisx0212_encoder(const ucs4_t *data, Py_ssize_t *length)
+{
+	DBCHAR coded;
+	assert(*length == 1);
+	if (*data < 0x10000) {
+		TRYMAP_ENC(jisxcommon, coded, *data) {
+			if (coded & 0x8000)
+				return coded & 0x7fff;
+		}
+	}
+	return MAP_UNMAPPABLE;
+}
+
+static int
+jisx0213_init(void)
+{
+	static int initialized = 0;
+
+	if (!initialized && (
+			jisx0208_init() ||
+			IMPORT_MAP(jp, jisx0213_bmp,
+				   &jisx0213_bmp_encmap, NULL) ||
+			IMPORT_MAP(jp, jisx0213_1_bmp,
+				   NULL, &jisx0213_1_bmp_decmap) ||
+			IMPORT_MAP(jp, jisx0213_2_bmp,
+				   NULL, &jisx0213_2_bmp_decmap) ||
+			IMPORT_MAP(jp, jisx0213_emp,
+				   &jisx0213_emp_encmap, NULL) ||
+			IMPORT_MAP(jp, jisx0213_1_emp,
+				   NULL, &jisx0213_1_emp_decmap) ||
+			IMPORT_MAP(jp, jisx0213_2_emp,
+				   NULL, &jisx0213_2_emp_decmap) ||
+			IMPORT_MAP(jp, jisx0213_pair, &jisx0213_pair_encmap,
+				   &jisx0213_pair_decmap)))
+		return -1;
+	initialized = 1;
+	return 0;
+}
+
+#define config ((void *)2000)
+static ucs4_t
+jisx0213_2000_1_decoder(const unsigned char *data)
+{
+	ucs4_t u;
+	EMULATE_JISX0213_2000_DECODE_PLANE1(u, data[0], data[1])
+	else if (data[0] == 0x21 && data[1] == 0x40) /* F/W REVERSE SOLIDUS */
+		return 0xff3c;
+	else TRYMAP_DEC(jisx0208, u, data[0], data[1]);
+	else TRYMAP_DEC(jisx0213_1_bmp, u, data[0], data[1]);
+	else TRYMAP_DEC(jisx0213_1_emp, u, data[0], data[1])
+		u |= 0x20000;
+	else TRYMAP_DEC(jisx0213_pair, u, data[0], data[1]);
+	else
+		return MAP_UNMAPPABLE;
+	return u;
+}
+
+static ucs4_t
+jisx0213_2000_2_decoder(const unsigned char *data)
+{
+	ucs4_t u;
+	EMULATE_JISX0213_2000_DECODE_PLANE2(u, data[0], data[1])
+	TRYMAP_DEC(jisx0213_2_bmp, u, data[0], data[1]);
+	else TRYMAP_DEC(jisx0213_2_emp, u, data[0], data[1])
+		u |= 0x20000;
+	else
+		return MAP_UNMAPPABLE;
+	return u;
+}
+#undef config
+
+static ucs4_t
+jisx0213_2004_1_decoder(const unsigned char *data)
+{
+	ucs4_t u;
+	if (data[0] == 0x21 && data[1] == 0x40) /* F/W REVERSE SOLIDUS */
+		return 0xff3c;
+	else TRYMAP_DEC(jisx0208, u, data[0], data[1]);
+	else TRYMAP_DEC(jisx0213_1_bmp, u, data[0], data[1]);
+	else TRYMAP_DEC(jisx0213_1_emp, u, data[0], data[1])
+		u |= 0x20000;
+	else TRYMAP_DEC(jisx0213_pair, u, data[0], data[1]);
+	else
+		return MAP_UNMAPPABLE;
+	return u;
+}
+
+static ucs4_t
+jisx0213_2004_2_decoder(const unsigned char *data)
+{
+	ucs4_t u;
+	TRYMAP_DEC(jisx0213_2_bmp, u, data[0], data[1]);
+	else TRYMAP_DEC(jisx0213_2_emp, u, data[0], data[1])
+		u |= 0x20000;
+	else
+		return MAP_UNMAPPABLE;
+	return u;
+}
+
+static DBCHAR
+jisx0213_encoder(const ucs4_t *data, Py_ssize_t *length, void *config)
+{
+	DBCHAR coded;
+
+	switch (*length) {
+	case 1: /* first character */
+		if (*data >= 0x10000) {
+			if ((*data) >> 16 == 0x20000 >> 16) {
+				EMULATE_JISX0213_2000_ENCODE_EMP(coded, *data)
+				else TRYMAP_ENC(jisx0213_emp, coded,
+						(*data) & 0xffff)
+					return coded;
+			}
+			return MAP_UNMAPPABLE;
+		}
+
+		EMULATE_JISX0213_2000_ENCODE_BMP(coded, *data)
+		else TRYMAP_ENC(jisx0213_bmp, coded, *data) {
+			if (coded == MULTIC)
+				return MAP_MULTIPLE_AVAIL;
+		}
+		else TRYMAP_ENC(jisxcommon, coded, *data) {
+			if (coded & 0x8000)
+				return MAP_UNMAPPABLE;
+		}
+		else
+			return MAP_UNMAPPABLE;
+		return coded;
+	case 2: /* second character of unicode pair */
+		coded = find_pairencmap((ucs2_t)data[0], (ucs2_t)data[1],
+				jisx0213_pair_encmap, JISX0213_ENCPAIRS);
+		if (coded == DBCINV) {
+			*length = 1;
+			coded = find_pairencmap((ucs2_t)data[0], 0,
+				  jisx0213_pair_encmap, JISX0213_ENCPAIRS);
+			if (coded == DBCINV)
+				return MAP_UNMAPPABLE;
+		}
+		else
+			return coded;
+	case -1: /* flush unterminated */
+		*length = 1;
+		coded = find_pairencmap((ucs2_t)data[0], 0,
+				jisx0213_pair_encmap, JISX0213_ENCPAIRS);
+		if (coded == DBCINV)
+			return MAP_UNMAPPABLE;
+		else
+			return coded;
+	default:
+		return MAP_UNMAPPABLE;
+	}
+}
+
+static DBCHAR
+jisx0213_2000_1_encoder(const ucs4_t *data, Py_ssize_t *length)
+{
+	DBCHAR coded = jisx0213_encoder(data, length, (void *)2000);
+	if (coded == MAP_UNMAPPABLE || coded == MAP_MULTIPLE_AVAIL)
+		return coded;
+	else if (coded & 0x8000)
+		return MAP_UNMAPPABLE;
+	else
+		return coded;
+}
+
+static DBCHAR
+jisx0213_2000_1_encoder_paironly(const ucs4_t *data, Py_ssize_t *length)
+{
+	DBCHAR coded;
+	Py_ssize_t ilength = *length;
+
+	coded = jisx0213_encoder(data, length, (void *)2000);
+	switch (ilength) {
+	case 1:
+		if (coded == MAP_MULTIPLE_AVAIL)
+			return MAP_MULTIPLE_AVAIL;
+		else
+			return MAP_UNMAPPABLE;
+	case 2:
+		if (*length != 2)
+			return MAP_UNMAPPABLE;
+		else
+			return coded;
+	default:
+		return MAP_UNMAPPABLE;
+	}
+}
+
+static DBCHAR
+jisx0213_2000_2_encoder(const ucs4_t *data, Py_ssize_t *length)
+{
+	DBCHAR coded = jisx0213_encoder(data, length, (void *)2000);
+	if (coded == MAP_UNMAPPABLE || coded == MAP_MULTIPLE_AVAIL)
+		return coded;
+	else if (coded & 0x8000)
+		return coded & 0x7fff;
+	else
+		return MAP_UNMAPPABLE;
+}
+
+static DBCHAR
+jisx0213_2004_1_encoder(const ucs4_t *data, Py_ssize_t *length)
+{
+	DBCHAR coded = jisx0213_encoder(data, length, NULL);
+	if (coded == MAP_UNMAPPABLE || coded == MAP_MULTIPLE_AVAIL)
+		return coded;
+	else if (coded & 0x8000)
+		return MAP_UNMAPPABLE;
+	else
+		return coded;
+}
+
+static DBCHAR
+jisx0213_2004_1_encoder_paironly(const ucs4_t *data, Py_ssize_t *length)
+{
+	DBCHAR coded;
+	Py_ssize_t ilength = *length;
+
+	coded = jisx0213_encoder(data, length, NULL);
+	switch (ilength) {
+	case 1:
+		if (coded == MAP_MULTIPLE_AVAIL)
+			return MAP_MULTIPLE_AVAIL;
+		else
+			return MAP_UNMAPPABLE;
+	case 2:
+		if (*length != 2)
+			return MAP_UNMAPPABLE;
+		else
+			return coded;
+	default:
+		return MAP_UNMAPPABLE;
+	}
+}
+
+static DBCHAR
+jisx0213_2004_2_encoder(const ucs4_t *data, Py_ssize_t *length)
+{
+	DBCHAR coded = jisx0213_encoder(data, length, NULL);
+	if (coded == MAP_UNMAPPABLE || coded == MAP_MULTIPLE_AVAIL)
+		return coded;
+	else if (coded & 0x8000)
+		return coded & 0x7fff;
+	else
+		return MAP_UNMAPPABLE;
+}
+
+static ucs4_t
+jisx0201_r_decoder(const unsigned char *data)
+{
+	ucs4_t u;
+	JISX0201_R_DECODE(*data, u)
+	else return MAP_UNMAPPABLE;
+	return u;
+}
+
+static DBCHAR
+jisx0201_r_encoder(const ucs4_t *data, Py_ssize_t *length)
+{
+	DBCHAR coded;
+	JISX0201_R_ENCODE(*data, coded)
+	else return MAP_UNMAPPABLE;
+	return coded;
+}
+
+static ucs4_t
+jisx0201_k_decoder(const unsigned char *data)
+{
+	ucs4_t u;
+	JISX0201_K_DECODE(*data ^ 0x80, u)
+	else return MAP_UNMAPPABLE;
+	return u;
+}
+
+static DBCHAR
+jisx0201_k_encoder(const ucs4_t *data, Py_ssize_t *length)
+{
+	DBCHAR coded;
+	JISX0201_K_ENCODE(*data, coded)
+	else return MAP_UNMAPPABLE;
+	return coded - 0x80;
+}
+
+static int
+gb2312_init(void)
+{
+	static int initialized = 0;
+
+	if (!initialized && (
+			IMPORT_MAP(cn, gbcommon, &gbcommon_encmap, NULL) ||
+			IMPORT_MAP(cn, gb2312, NULL, &gb2312_decmap)))
+		return -1;
+	initialized = 1;
+	return 0;
+}
+
+static ucs4_t
+gb2312_decoder(const unsigned char *data)
+{
+	ucs4_t u;
+	TRYMAP_DEC(gb2312, u, data[0], data[1])
+		return u;
+	else
+		return MAP_UNMAPPABLE;
+}
+
+static DBCHAR
+gb2312_encoder(const ucs4_t *data, Py_ssize_t *length)
+{
+	DBCHAR coded;
+	assert(*length == 1);
+	if (*data < 0x10000) {
+		TRYMAP_ENC(gbcommon, coded, *data) {
+			if (!(coded & 0x8000))
+				return coded;
+		}
+	}
+	return MAP_UNMAPPABLE;
+}
+
+
+static ucs4_t
+dummy_decoder(const unsigned char *data)
+{
+	return MAP_UNMAPPABLE;
+}
+
+static DBCHAR
+dummy_encoder(const ucs4_t *data, Py_ssize_t *length)
+{
+	return MAP_UNMAPPABLE;
+}
+
+/*-*- registry tables -*-*/
+
+#define REGISTRY_KSX1001_G0	{ CHARSET_KSX1001, 0, 2,		\
+				  ksx1001_init,				\
+				  ksx1001_decoder, ksx1001_encoder }
+#define REGISTRY_KSX1001_G1	{ CHARSET_KSX1001, 1, 2,		\
+				  ksx1001_init,				\
+				  ksx1001_decoder, ksx1001_encoder }
+#define REGISTRY_JISX0201_R	{ CHARSET_JISX0201_R, 0, 1,		\
+				  NULL,					\
+				  jisx0201_r_decoder, jisx0201_r_encoder }
+#define REGISTRY_JISX0201_K	{ CHARSET_JISX0201_K, 0, 1,		\
+				  NULL,					\
+				  jisx0201_k_decoder, jisx0201_k_encoder }
+#define REGISTRY_JISX0208	{ CHARSET_JISX0208, 0, 2,		\
+				  jisx0208_init,			\
+				  jisx0208_decoder, jisx0208_encoder }
+#define REGISTRY_JISX0208_O	{ CHARSET_JISX0208_O, 0, 2,		\
+				  jisx0208_init,			\
+				  jisx0208_decoder, jisx0208_encoder }
+#define REGISTRY_JISX0212	{ CHARSET_JISX0212, 0, 2,		\
+				  jisx0212_init,			\
+				  jisx0212_decoder, jisx0212_encoder }
+#define REGISTRY_JISX0213_2000_1 { CHARSET_JISX0213_2000_1, 0, 2,	\
+				  jisx0213_init,			\
+				  jisx0213_2000_1_decoder,		\
+				  jisx0213_2000_1_encoder }
+#define REGISTRY_JISX0213_2000_1_PAIRONLY { CHARSET_JISX0213_2000_1, 0, 2, \
+				  jisx0213_init,			\
+				  jisx0213_2000_1_decoder,		\
+				  jisx0213_2000_1_encoder_paironly }
+#define REGISTRY_JISX0213_2000_2 { CHARSET_JISX0213_2, 0, 2,		\
+				  jisx0213_init,			\
+				  jisx0213_2000_2_decoder,		\
+				  jisx0213_2000_2_encoder }
+#define REGISTRY_JISX0213_2004_1 { CHARSET_JISX0213_2004_1, 0, 2,	\
+				  jisx0213_init,			\
+				  jisx0213_2004_1_decoder,		\
+				  jisx0213_2004_1_encoder }
+#define REGISTRY_JISX0213_2004_1_PAIRONLY { CHARSET_JISX0213_2004_1, 0, 2, \
+				  jisx0213_init,			\
+				  jisx0213_2004_1_decoder,		\
+				  jisx0213_2004_1_encoder_paironly }
+#define REGISTRY_JISX0213_2004_2 { CHARSET_JISX0213_2, 0, 2,		\
+				  jisx0213_init,			\
+				  jisx0213_2004_2_decoder,		\
+				  jisx0213_2004_2_encoder }
+#define REGISTRY_GB2312		{ CHARSET_GB2312, 0, 2,			\
+				  gb2312_init,				\
+				  gb2312_decoder, gb2312_encoder }
+#define REGISTRY_CNS11643_1	{ CHARSET_CNS11643_1, 1, 2,		\
+				  cns11643_init,			\
+				  cns11643_1_decoder, cns11643_1_encoder }
+#define REGISTRY_CNS11643_2	{ CHARSET_CNS11643_2, 2, 2,		\
+				  cns11643_init,			\
+				  cns11643_2_decoder, cns11643_2_encoder }
+#define REGISTRY_ISO8859_1	{ CHARSET_ISO8859_1, 2, 1,		\
+				  NULL, dummy_decoder, dummy_encoder }
+#define REGISTRY_ISO8859_7	{ CHARSET_ISO8859_7, 2, 1,		\
+				  NULL, dummy_decoder, dummy_encoder }
+#define REGISTRY_SENTINEL	{ 0, }
+#define CONFIGDEF(var, attrs)						\
+	static const struct iso2022_config iso2022_##var##_config = {	\
+		attrs, iso2022_##var##_designations			\
+	};
+
+static const struct iso2022_designation iso2022_kr_designations[] = {
+	REGISTRY_KSX1001_G1, REGISTRY_SENTINEL
+};
+CONFIGDEF(kr, 0)
+
+static const struct iso2022_designation iso2022_jp_designations[] = {
+	REGISTRY_JISX0208, REGISTRY_JISX0201_R, REGISTRY_JISX0208_O,
+	REGISTRY_SENTINEL
+};
+CONFIGDEF(jp, NO_SHIFT | USE_JISX0208_EXT)
+
+static const struct iso2022_designation iso2022_jp_1_designations[] = {
+	REGISTRY_JISX0208, REGISTRY_JISX0212, REGISTRY_JISX0201_R,
+	REGISTRY_JISX0208_O, REGISTRY_SENTINEL
+};
+CONFIGDEF(jp_1, NO_SHIFT | USE_JISX0208_EXT)
+
+static const struct iso2022_designation iso2022_jp_2_designations[] = {
+	REGISTRY_JISX0208, REGISTRY_JISX0212, REGISTRY_KSX1001_G0,
+	REGISTRY_GB2312, REGISTRY_JISX0201_R, REGISTRY_JISX0208_O,
+	REGISTRY_ISO8859_1, REGISTRY_ISO8859_7, REGISTRY_SENTINEL
+};
+CONFIGDEF(jp_2, NO_SHIFT | USE_G2 | USE_JISX0208_EXT)
+
+static const struct iso2022_designation iso2022_jp_2004_designations[] = {
+	REGISTRY_JISX0213_2004_1_PAIRONLY, REGISTRY_JISX0208,
+	REGISTRY_JISX0213_2004_1, REGISTRY_JISX0213_2004_2, REGISTRY_SENTINEL
+};
+CONFIGDEF(jp_2004, NO_SHIFT | USE_JISX0208_EXT)
+
+static const struct iso2022_designation iso2022_jp_3_designations[] = {
+	REGISTRY_JISX0213_2000_1_PAIRONLY, REGISTRY_JISX0208,
+	REGISTRY_JISX0213_2000_1, REGISTRY_JISX0213_2000_2, REGISTRY_SENTINEL
+};
+CONFIGDEF(jp_3, NO_SHIFT | USE_JISX0208_EXT)
+
+static const struct iso2022_designation iso2022_jp_ext_designations[] = {
+	REGISTRY_JISX0208, REGISTRY_JISX0212, REGISTRY_JISX0201_R,
+	REGISTRY_JISX0201_K, REGISTRY_JISX0208_O, REGISTRY_SENTINEL
+};
+CONFIGDEF(jp_ext, NO_SHIFT | USE_JISX0208_EXT)
+
+
+BEGIN_MAPPINGS_LIST
+  /* no mapping table here */
+END_MAPPINGS_LIST
+
+#define ISO2022_CODEC(variation) {		\
+	"iso2022_" #variation,			\
+	&iso2022_##variation##_config,		\
+	iso2022_codec_init,			\
+	_STATEFUL_METHODS(iso2022)		\
+},
+
+BEGIN_CODECS_LIST
+  ISO2022_CODEC(kr)
+  ISO2022_CODEC(jp)
+  ISO2022_CODEC(jp_1)
+  ISO2022_CODEC(jp_2)
+  ISO2022_CODEC(jp_2004)
+  ISO2022_CODEC(jp_3)
+  ISO2022_CODEC(jp_ext)
+END_CODECS_LIST
+
+I_AM_A_MODULE_FOR(iso2022)

Added: vendor/Python/current/Modules/cjkcodecs/_codecs_jp.c
===================================================================
--- vendor/Python/current/Modules/cjkcodecs/_codecs_jp.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/cjkcodecs/_codecs_jp.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,731 @@
+/*
+ * _codecs_jp.c: Codecs collection for Japanese encodings
+ *
+ * Written by Hye-Shik Chang <perky at FreeBSD.org>
+ */
+
+#define USING_BINARY_PAIR_SEARCH
+#define EMPBASE 0x20000
+
+#include "cjkcodecs.h"
+#include "mappings_jp.h"
+#include "mappings_jisx0213_pair.h"
+#include "alg_jisx0201.h"
+#include "emu_jisx0213_2000.h"
+
+/*
+ * CP932 codec
+ */
+
+ENCODER(cp932)
+{
+	while (inleft > 0) {
+		Py_UNICODE c = IN1;
+		DBCHAR code;
+		unsigned char c1, c2;
+
+		if (c <= 0x80) {
+			WRITE1((unsigned char)c)
+			NEXT(1, 1)
+			continue;
+		}
+		else if (c >= 0xff61 && c <= 0xff9f) {
+			WRITE1(c - 0xfec0)
+			NEXT(1, 1)
+			continue;
+		}
+		else if (c >= 0xf8f0 && c <= 0xf8f3) {
+			/* Windows compatibility */
+			REQUIRE_OUTBUF(1)
+			if (c == 0xf8f0)
+				OUT1(0xa0)
+			else
+				OUT1(c - 0xfef1 + 0xfd)
+			NEXT(1, 1)
+			continue;
+		}
+
+		UCS4INVALID(c)
+		REQUIRE_OUTBUF(2)
+
+		TRYMAP_ENC(cp932ext, code, c) {
+			OUT1(code >> 8)
+			OUT2(code & 0xff)
+		}
+		else TRYMAP_ENC(jisxcommon, code, c) {
+			if (code & 0x8000) /* MSB set: JIS X 0212 */
+				return 1;
+
+			/* JIS X 0208 */
+			c1 = code >> 8;
+			c2 = code & 0xff;
+			c2 = (((c1 - 0x21) & 1) ? 0x5e : 0) + (c2 - 0x21);
+			c1 = (c1 - 0x21) >> 1;
+			OUT1(c1 < 0x1f ? c1 + 0x81 : c1 + 0xc1)
+			OUT2(c2 < 0x3f ? c2 + 0x40 : c2 + 0x41)
+		}
+		else if (c >= 0xe000 && c < 0xe758) {
+			/* User-defined area */
+			c1 = (Py_UNICODE)(c - 0xe000) / 188;
+			c2 = (Py_UNICODE)(c - 0xe000) % 188;
+			OUT1(c1 + 0xf0)
+			OUT2(c2 < 0x3f ? c2 + 0x40 : c2 + 0x41)
+		}
+		else
+			return 1;
+
+		NEXT(1, 2)
+	}
+
+	return 0;
+}
+
+DECODER(cp932)
+{
+	while (inleft > 0) {
+		unsigned char c = IN1, c2;
+
+		REQUIRE_OUTBUF(1)
+		if (c <= 0x80) {
+			OUT1(c)
+			NEXT(1, 1)
+			continue;
+		}
+		else if (c >= 0xa0 && c <= 0xdf) {
+			if (c == 0xa0)
+				OUT1(0xf8f0) /* half-width katakana */
+			else
+				OUT1(0xfec0 + c)
+			NEXT(1, 1)
+			continue;
+		}
+		else if (c >= 0xfd/* && c <= 0xff*/) {
+			/* Windows compatibility */
+			OUT1(0xf8f1 - 0xfd + c)
+			NEXT(1, 1)
+			continue;
+		}
+
+		REQUIRE_INBUF(2)
+		c2 = IN2;
+
+		TRYMAP_DEC(cp932ext, **outbuf, c, c2);
+		else if ((c >= 0x81 && c <= 0x9f) || (c >= 0xe0 && c <= 0xea)){
+			if (c2 < 0x40 || (c2 > 0x7e && c2 < 0x80) || c2 > 0xfc)
+				return 2;
+
+			c = (c < 0xe0 ? c - 0x81 : c - 0xc1);
+			c2 = (c2 < 0x80 ? c2 - 0x40 : c2 - 0x41);
+			c = (2 * c + (c2 < 0x5e ? 0 : 1) + 0x21);
+			c2 = (c2 < 0x5e ? c2 : c2 - 0x5e) + 0x21;
+
+			TRYMAP_DEC(jisx0208, **outbuf, c, c2);
+			else return 2;
+		}
+		else if (c >= 0xf0 && c <= 0xf9) {
+			if ((c2 >= 0x40 && c2 <= 0x7e) ||
+			    (c2 >= 0x80 && c2 <= 0xfc))
+				OUT1(0xe000 + 188 * (c - 0xf0) +
+				     (c2 < 0x80 ? c2 - 0x40 : c2 - 0x41))
+			else
+				return 2;
+		}
+		else
+			return 2;
+
+		NEXT(2, 1)
+	}
+
+	return 0;
+}
+
+
+/*
+ * EUC-JIS-2004 codec
+ */
+
+ENCODER(euc_jis_2004)
+{
+	while (inleft > 0) {
+		ucs4_t c = IN1;
+		DBCHAR code;
+		Py_ssize_t insize;
+
+		if (c < 0x80) {
+			WRITE1(c)
+			NEXT(1, 1)
+			continue;
+		}
+
+		DECODE_SURROGATE(c)
+		insize = GET_INSIZE(c);
+
+		if (c <= 0xFFFF) {
+			EMULATE_JISX0213_2000_ENCODE_BMP(code, c)
+			else TRYMAP_ENC(jisx0213_bmp, code, c) {
+				if (code == MULTIC) {
+					if (inleft < 2) {
+						if (flags & MBENC_FLUSH) {
+							code = find_pairencmap(
+							    (ucs2_t)c, 0,
+							  jisx0213_pair_encmap,
+							    JISX0213_ENCPAIRS);
+							if (code == DBCINV)
+								return 1;
+						}
+						else
+							return MBERR_TOOFEW;
+					}
+					else {
+						code = find_pairencmap(
+							(ucs2_t)c, (*inbuf)[1],
+							jisx0213_pair_encmap,
+							JISX0213_ENCPAIRS);
+						if (code == DBCINV) {
+							code = find_pairencmap(
+							    (ucs2_t)c, 0,
+							  jisx0213_pair_encmap,
+							    JISX0213_ENCPAIRS);
+							if (code == DBCINV)
+								return 1;
+						} else
+							insize = 2;
+					}
+				}
+			}
+			else TRYMAP_ENC(jisxcommon, code, c);
+			else if (c >= 0xff61 && c <= 0xff9f) {
+				/* JIS X 0201 half-width katakana */
+				WRITE2(0x8e, c - 0xfec0)
+				NEXT(1, 2)
+				continue;
+			}
+			else if (c == 0xff3c)
+				/* F/W REVERSE SOLIDUS (see NOTES) */
+				code = 0x2140;
+			else if (c == 0xff5e)
+				/* F/W TILDE (see NOTES) */
+				code = 0x2232;
+			else
+				return 1;
+		}
+		else if (c >> 16 == EMPBASE >> 16) {
+			EMULATE_JISX0213_2000_ENCODE_EMP(code, c)
+			else TRYMAP_ENC(jisx0213_emp, code, c & 0xffff);
+			else return insize;
+		}
+		else
+			return insize;
+
+		if (code & 0x8000) {
+			/* Codeset 2 */
+			WRITE3(0x8f, code >> 8, (code & 0xFF) | 0x80)
+			NEXT(insize, 3)
+		} else {
+			/* Codeset 1 */
+			WRITE2((code >> 8) | 0x80, (code & 0xFF) | 0x80)
+			NEXT(insize, 2)
+		}
+	}
+
+	return 0;
+}
+
+DECODER(euc_jis_2004)
+{
+	while (inleft > 0) {
+		unsigned char c = IN1;
+		ucs4_t code;
+
+		REQUIRE_OUTBUF(1)
+
+		if (c < 0x80) {
+			OUT1(c)
+			NEXT(1, 1)
+			continue;
+		}
+
+		if (c == 0x8e) {
+			/* JIS X 0201 half-width katakana */
+			unsigned char c2;
+
+			REQUIRE_INBUF(2)
+			c2 = IN2;
+			if (c2 >= 0xa1 && c2 <= 0xdf) {
+				OUT1(0xfec0 + c2)
+				NEXT(2, 1)
+			}
+			else
+				return 2;
+		}
+		else if (c == 0x8f) {
+			unsigned char c2, c3;
+
+			REQUIRE_INBUF(3)
+			c2 = IN2 ^ 0x80;
+			c3 = IN3 ^ 0x80;
+
+			/* JIS X 0213 Plane 2 or JIS X 0212 (see NOTES) */
+			EMULATE_JISX0213_2000_DECODE_PLANE2(**outbuf, c2, c3)
+			else TRYMAP_DEC(jisx0213_2_bmp, **outbuf, c2, c3) ;
+			else TRYMAP_DEC(jisx0213_2_emp, code, c2, c3) {
+				WRITEUCS4(EMPBASE | code)
+				NEXT_IN(3)
+				continue;
+			}
+			else TRYMAP_DEC(jisx0212, **outbuf, c2, c3) ;
+			else return 3;
+			NEXT(3, 1)
+		}
+		else {
+			unsigned char c2;
+
+			REQUIRE_INBUF(2)
+			c ^= 0x80;
+			c2 = IN2 ^ 0x80;
+
+			/* JIS X 0213 Plane 1 */
+			EMULATE_JISX0213_2000_DECODE_PLANE1(**outbuf, c, c2)
+			else if (c == 0x21 && c2 == 0x40) **outbuf = 0xff3c;
+			else if (c == 0x22 && c2 == 0x32) **outbuf = 0xff5e;
+			else TRYMAP_DEC(jisx0208, **outbuf, c, c2);
+			else TRYMAP_DEC(jisx0213_1_bmp, **outbuf, c, c2);
+			else TRYMAP_DEC(jisx0213_1_emp, code, c, c2) {
+				WRITEUCS4(EMPBASE | code)
+				NEXT_IN(2)
+				continue;
+			}
+			else TRYMAP_DEC(jisx0213_pair, code, c, c2) {
+				WRITE2(code >> 16, code & 0xffff)
+				NEXT(2, 2)
+				continue;
+			}
+			else return 2;
+			NEXT(2, 1)
+		}
+	}
+
+	return 0;
+}
+
+
+/*
+ * EUC-JP codec
+ */
+
+ENCODER(euc_jp)
+{
+	while (inleft > 0) {
+		Py_UNICODE c = IN1;
+		DBCHAR code;
+
+		if (c < 0x80) {
+			WRITE1((unsigned char)c)
+			NEXT(1, 1)
+			continue;
+		}
+
+		UCS4INVALID(c)
+
+		TRYMAP_ENC(jisxcommon, code, c);
+		else if (c >= 0xff61 && c <= 0xff9f) {
+			/* JIS X 0201 half-width katakana */
+			WRITE2(0x8e, c - 0xfec0)
+			NEXT(1, 2)
+			continue;
+		}
+#ifndef STRICT_BUILD
+		else if (c == 0xff3c) /* FULL-WIDTH REVERSE SOLIDUS */
+			code = 0x2140;
+		else if (c == 0xa5) { /* YEN SIGN */
+			WRITE1(0x5c);
+			NEXT(1, 1)
+			continue;
+		} else if (c == 0x203e) { /* OVERLINE */
+			WRITE1(0x7e);
+			NEXT(1, 1)
+			continue;
+		}
+#endif
+		else
+			return 1;
+
+		if (code & 0x8000) {
+			/* JIS X 0212 */
+			WRITE3(0x8f, code >> 8, (code & 0xFF) | 0x80)
+			NEXT(1, 3)
+		} else {
+			/* JIS X 0208 */
+			WRITE2((code >> 8) | 0x80, (code & 0xFF) | 0x80)
+			NEXT(1, 2)
+		}
+	}
+
+	return 0;
+}
+
+DECODER(euc_jp)
+{
+	while (inleft > 0) {
+		unsigned char c = IN1;
+
+		REQUIRE_OUTBUF(1)
+
+			if (c < 0x80) {
+				OUT1(c)
+				NEXT(1, 1)
+				continue;
+			}
+
+		if (c == 0x8e) {
+			/* JIS X 0201 half-width katakana */
+			unsigned char c2;
+
+			REQUIRE_INBUF(2)
+			c2 = IN2;
+			if (c2 >= 0xa1 && c2 <= 0xdf) {
+				OUT1(0xfec0 + c2)
+				NEXT(2, 1)
+			}
+			else
+				return 2;
+		}
+		else if (c == 0x8f) {
+			unsigned char c2, c3;
+
+			REQUIRE_INBUF(3)
+			c2 = IN2;
+			c3 = IN3;
+			/* JIS X 0212 */
+			TRYMAP_DEC(jisx0212, **outbuf, c2 ^ 0x80, c3 ^ 0x80) {
+				NEXT(3, 1)
+			}
+			else
+				return 3;
+		}
+		else {
+			unsigned char c2;
+
+			REQUIRE_INBUF(2)
+			c2 = IN2;
+			/* JIS X 0208 */
+#ifndef STRICT_BUILD
+			if (c == 0xa1 && c2 == 0xc0)
+				/* FULL-WIDTH REVERSE SOLIDUS */
+				**outbuf = 0xff3c;
+			else
+#endif
+				TRYMAP_DEC(jisx0208, **outbuf,
+					   c ^ 0x80, c2 ^ 0x80) ;
+			else return 2;
+			NEXT(2, 1)
+		}
+	}
+
+	return 0;
+}
+
+
+/*
+ * SHIFT_JIS codec
+ */
+
+ENCODER(shift_jis)
+{
+	while (inleft > 0) {
+		Py_UNICODE c = IN1;
+		DBCHAR code;
+		unsigned char c1, c2;
+
+#ifdef STRICT_BUILD
+		JISX0201_R_ENCODE(c, code)
+#else
+		if (c < 0x80) code = c;
+		else if (c == 0x00a5) code = 0x5c; /* YEN SIGN */
+		else if (c == 0x203e) code = 0x7e; /* OVERLINE */
+#endif
+		else JISX0201_K_ENCODE(c, code)
+		else UCS4INVALID(c)
+		else code = NOCHAR;
+
+		if (code < 0x80 || (code >= 0xa1 && code <= 0xdf)) {
+			REQUIRE_OUTBUF(1)
+
+			OUT1((unsigned char)code)
+			NEXT(1, 1)
+			continue;
+		}
+
+		REQUIRE_OUTBUF(2)
+
+		if (code == NOCHAR) {
+			TRYMAP_ENC(jisxcommon, code, c);
+#ifndef STRICT_BUILD
+			else if (c == 0xff3c)
+				code = 0x2140; /* FULL-WIDTH REVERSE SOLIDUS */
+#endif
+			else
+				return 1;
+
+			if (code & 0x8000) /* MSB set: JIS X 0212 */
+				return 1;
+		}
+
+		c1 = code >> 8;
+		c2 = code & 0xff;
+		c2 = (((c1 - 0x21) & 1) ? 0x5e : 0) + (c2 - 0x21);
+		c1 = (c1 - 0x21) >> 1;
+		OUT1(c1 < 0x1f ? c1 + 0x81 : c1 + 0xc1)
+		OUT2(c2 < 0x3f ? c2 + 0x40 : c2 + 0x41)
+		NEXT(1, 2)
+	}
+
+	return 0;
+}
+
+DECODER(shift_jis)
+{
+	while (inleft > 0) {
+		unsigned char c = IN1;
+
+		REQUIRE_OUTBUF(1)
+
+#ifdef STRICT_BUILD
+		JISX0201_R_DECODE(c, **outbuf)
+#else
+		if (c < 0x80) **outbuf = c;
+#endif
+		else JISX0201_K_DECODE(c, **outbuf)
+		else if ((c >= 0x81 && c <= 0x9f) || (c >= 0xe0 && c <= 0xea)){
+			unsigned char c1, c2;
+
+			REQUIRE_INBUF(2)
+			c2 = IN2;
+			if (c2 < 0x40 || (c2 > 0x7e && c2 < 0x80) || c2 > 0xfc)
+				return 2;
+
+			c1 = (c < 0xe0 ? c - 0x81 : c - 0xc1);
+			c2 = (c2 < 0x80 ? c2 - 0x40 : c2 - 0x41);
+			c1 = (2 * c1 + (c2 < 0x5e ? 0 : 1) + 0x21);
+			c2 = (c2 < 0x5e ? c2 : c2 - 0x5e) + 0x21;
+
+#ifndef STRICT_BUILD
+			if (c1 == 0x21 && c2 == 0x40) {
+				/* FULL-WIDTH REVERSE SOLIDUS */
+				OUT1(0xff3c)
+				NEXT(2, 1)
+				continue;
+			}
+#endif
+			TRYMAP_DEC(jisx0208, **outbuf, c1, c2) {
+				NEXT(2, 1)
+				continue;
+			}
+			else
+				return 2;
+		}
+		else
+			return 2;
+
+		NEXT(1, 1) /* JIS X 0201 */
+	}
+
+	return 0;
+}
+
+
+/*
+ * SHIFT_JIS-2004 codec
+ */
+
+ENCODER(shift_jis_2004)
+{
+	while (inleft > 0) {
+		ucs4_t c = IN1;
+		DBCHAR code = NOCHAR;
+		int c1, c2;
+		Py_ssize_t insize;
+
+		JISX0201_ENCODE(c, code)
+		else DECODE_SURROGATE(c)
+
+		if (code < 0x80 || (code >= 0xa1 && code <= 0xdf)) {
+			WRITE1((unsigned char)code)
+			NEXT(1, 1)
+			continue;
+		}
+
+		REQUIRE_OUTBUF(2)
+		insize = GET_INSIZE(c);
+
+		if (code == NOCHAR) {
+			if (c <= 0xffff) {
+				EMULATE_JISX0213_2000_ENCODE_BMP(code, c)
+				else TRYMAP_ENC(jisx0213_bmp, code, c) {
+					if (code == MULTIC) {
+						if (inleft < 2) {
+						    if (flags & MBENC_FLUSH) {
+							code = find_pairencmap
+							    ((ucs2_t)c, 0,
+							  jisx0213_pair_encmap,
+							    JISX0213_ENCPAIRS);
+							if (code == DBCINV)
+							    return 1;
+						    }
+						    else
+							    return MBERR_TOOFEW;
+						}
+						else {
+						    code = find_pairencmap(
+							    (ucs2_t)c, IN2,
+							  jisx0213_pair_encmap,
+							    JISX0213_ENCPAIRS);
+						    if (code == DBCINV) {
+							code = find_pairencmap(
+							    (ucs2_t)c, 0,
+							  jisx0213_pair_encmap,
+							    JISX0213_ENCPAIRS);
+							if (code == DBCINV)
+							    return 1;
+							}
+							else
+							    insize = 2;
+						}
+					}
+				}
+				else TRYMAP_ENC(jisxcommon, code, c) {
+					/* abandon JIS X 0212 codes */
+					if (code & 0x8000)
+						return 1;
+				}
+				else return 1;
+			}
+			else if (c >> 16 == EMPBASE >> 16) {
+				EMULATE_JISX0213_2000_ENCODE_EMP(code, c)
+				else TRYMAP_ENC(jisx0213_emp, code, c&0xffff);
+				else return insize;
+			}
+			else
+				return insize;
+		}
+
+		c1 = code >> 8;
+		c2 = (code & 0xff) - 0x21;
+
+		if (c1 & 0x80) { /* Plane 2 */
+			if (c1 >= 0xee) c1 -= 0x87;
+			else if (c1 >= 0xac || c1 == 0xa8) c1 -= 0x49;
+			else c1 -= 0x43;
+		}
+		else /* Plane 1 */
+			c1 -= 0x21;
+
+		if (c1 & 1) c2 += 0x5e;
+		c1 >>= 1;
+		OUT1(c1 + (c1 < 0x1f ? 0x81 : 0xc1))
+		OUT2(c2 + (c2 < 0x3f ? 0x40 : 0x41))
+
+		NEXT(insize, 2)
+	}
+
+	return 0;
+}
+
+DECODER(shift_jis_2004)
+{
+	while (inleft > 0) {
+		unsigned char c = IN1;
+
+		REQUIRE_OUTBUF(1)
+		JISX0201_DECODE(c, **outbuf)
+		else if ((c >= 0x81 && c <= 0x9f) || (c >= 0xe0 && c <= 0xfc)){
+			unsigned char c1, c2;
+			ucs4_t code;
+
+			REQUIRE_INBUF(2)
+			c2 = IN2;
+			if (c2 < 0x40 || (c2 > 0x7e && c2 < 0x80) || c2 > 0xfc)
+				return 2;
+
+			c1 = (c < 0xe0 ? c - 0x81 : c - 0xc1);
+			c2 = (c2 < 0x80 ? c2 - 0x40 : c2 - 0x41);
+			c1 = (2 * c1 + (c2 < 0x5e ? 0 : 1));
+			c2 = (c2 < 0x5e ? c2 : c2 - 0x5e) + 0x21;
+
+			if (c1 < 0x5e) { /* Plane 1 */
+				c1 += 0x21;
+				EMULATE_JISX0213_2000_DECODE_PLANE1(**outbuf,
+						c1, c2)
+				else TRYMAP_DEC(jisx0208, **outbuf, c1, c2) {
+					NEXT_OUT(1)
+				}
+				else TRYMAP_DEC(jisx0213_1_bmp, **outbuf,
+						c1, c2) {
+					NEXT_OUT(1)
+				}
+				else TRYMAP_DEC(jisx0213_1_emp, code, c1, c2) {
+					WRITEUCS4(EMPBASE | code)
+				}
+				else TRYMAP_DEC(jisx0213_pair, code, c1, c2) {
+					WRITE2(code >> 16, code & 0xffff)
+					NEXT_OUT(2)
+				}
+				else
+					return 2;
+				NEXT_IN(2)
+			}
+			else { /* Plane 2 */
+				if (c1 >= 0x67) c1 += 0x07;
+				else if (c1 >= 0x63 || c1 == 0x5f) c1 -= 0x37;
+				else c1 -= 0x3d;
+
+				EMULATE_JISX0213_2000_DECODE_PLANE2(**outbuf,
+						c1, c2)
+				else TRYMAP_DEC(jisx0213_2_bmp, **outbuf,
+						c1, c2) ;
+				else TRYMAP_DEC(jisx0213_2_emp, code, c1, c2) {
+					WRITEUCS4(EMPBASE | code)
+					NEXT_IN(2)
+					continue;
+				}
+				else
+					return 2;
+				NEXT(2, 1)
+			}
+			continue;
+		}
+		else
+			return 2;
+
+		NEXT(1, 1) /* JIS X 0201 */
+	}
+
+	return 0;
+}
+
+
+BEGIN_MAPPINGS_LIST
+  MAPPING_DECONLY(jisx0208)
+  MAPPING_DECONLY(jisx0212)
+  MAPPING_ENCONLY(jisxcommon)
+  MAPPING_DECONLY(jisx0213_1_bmp)
+  MAPPING_DECONLY(jisx0213_2_bmp)
+  MAPPING_ENCONLY(jisx0213_bmp)
+  MAPPING_DECONLY(jisx0213_1_emp)
+  MAPPING_DECONLY(jisx0213_2_emp)
+  MAPPING_ENCONLY(jisx0213_emp)
+  MAPPING_ENCDEC(jisx0213_pair)
+  MAPPING_ENCDEC(cp932ext)
+END_MAPPINGS_LIST
+
+BEGIN_CODECS_LIST
+  CODEC_STATELESS(shift_jis)
+  CODEC_STATELESS(cp932)
+  CODEC_STATELESS(euc_jp)
+  CODEC_STATELESS(shift_jis_2004)
+  CODEC_STATELESS(euc_jis_2004)
+  { "euc_jisx0213", (void *)2000, NULL, _STATELESS_METHODS(euc_jis_2004) },
+  { "shift_jisx0213", (void *)2000, NULL, _STATELESS_METHODS(shift_jis_2004) },
+END_CODECS_LIST
+
+I_AM_A_MODULE_FOR(jp)

Added: vendor/Python/current/Modules/cjkcodecs/_codecs_kr.c
===================================================================
--- vendor/Python/current/Modules/cjkcodecs/_codecs_kr.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/cjkcodecs/_codecs_kr.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,355 @@
+/*
+ * _codecs_kr.c: Codecs collection for Korean encodings
+ *
+ * Written by Hye-Shik Chang <perky at FreeBSD.org>
+ */
+
+#include "cjkcodecs.h"
+#include "mappings_kr.h"
+
+/*
+ * EUC-KR codec
+ */
+
+ENCODER(euc_kr)
+{
+	while (inleft > 0) {
+		Py_UNICODE c = IN1;
+		DBCHAR code;
+
+		if (c < 0x80) {
+			WRITE1((unsigned char)c)
+			NEXT(1, 1)
+			continue;
+		}
+		UCS4INVALID(c)
+
+		REQUIRE_OUTBUF(2)
+		TRYMAP_ENC(cp949, code, c);
+		else return 1;
+
+		if (code & 0x8000) /* MSB set: CP949 */
+			return 1;
+
+		OUT1((code >> 8) | 0x80)
+		OUT2((code & 0xFF) | 0x80)
+		NEXT(1, 2)
+	}
+
+	return 0;
+}
+
+DECODER(euc_kr)
+{
+	while (inleft > 0) {
+		unsigned char c = IN1;
+
+		REQUIRE_OUTBUF(1)
+
+		if (c < 0x80) {
+			OUT1(c)
+			NEXT(1, 1)
+			continue;
+		}
+
+		REQUIRE_INBUF(2)
+
+		TRYMAP_DEC(ksx1001, **outbuf, c ^ 0x80, IN2 ^ 0x80) {
+			NEXT(2, 1)
+		} else return 2;
+	}
+
+	return 0;
+}
+
+
+/*
+ * CP949 codec
+ */
+
+ENCODER(cp949)
+{
+	while (inleft > 0) {
+		Py_UNICODE c = IN1;
+		DBCHAR code;
+
+		if (c < 0x80) {
+			WRITE1((unsigned char)c)
+			NEXT(1, 1)
+			continue;
+		}
+		UCS4INVALID(c)
+
+		REQUIRE_OUTBUF(2)
+		TRYMAP_ENC(cp949, code, c);
+		else return 1;
+
+		OUT1((code >> 8) | 0x80)
+		if (code & 0x8000)
+			OUT2(code & 0xFF) /* MSB set: CP949 */
+		else
+			OUT2((code & 0xFF) | 0x80) /* MSB unset: ks x 1001 */
+		NEXT(1, 2)
+	}
+
+	return 0;
+}
+
+DECODER(cp949)
+{
+	while (inleft > 0) {
+		unsigned char c = IN1;
+
+		REQUIRE_OUTBUF(1)
+
+		if (c < 0x80) {
+			OUT1(c)
+			NEXT(1, 1)
+			continue;
+		}
+
+		REQUIRE_INBUF(2)
+		TRYMAP_DEC(ksx1001, **outbuf, c ^ 0x80, IN2 ^ 0x80);
+		else TRYMAP_DEC(cp949ext, **outbuf, c, IN2);
+		else return 2;
+
+		NEXT(2, 1)
+	}
+
+	return 0;
+}
+
+
+/*
+ * JOHAB codec
+ */
+
+static const unsigned char u2johabidx_choseong[32] = {
+                0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+    0x10, 0x11, 0x12, 0x13, 0x14,
+};
+static const unsigned char u2johabidx_jungseong[32] = {
+                      0x03, 0x04, 0x05, 0x06, 0x07,
+                0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+                0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+                0x1a, 0x1b, 0x1c, 0x1d,
+};
+static const unsigned char u2johabidx_jongseong[32] = {
+          0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+    0x10, 0x11,       0x13, 0x14, 0x15, 0x16, 0x17,
+    0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
+};
+static const DBCHAR u2johabjamo[] = {
+            0x8841, 0x8c41, 0x8444, 0x9041, 0x8446, 0x8447, 0x9441,
+    0x9841, 0x9c41, 0x844a, 0x844b, 0x844c, 0x844d, 0x844e, 0x844f,
+    0x8450, 0xa041, 0xa441, 0xa841, 0x8454, 0xac41, 0xb041, 0xb441,
+    0xb841, 0xbc41, 0xc041, 0xc441, 0xc841, 0xcc41, 0xd041, 0x8461,
+    0x8481, 0x84a1, 0x84c1, 0x84e1, 0x8541, 0x8561, 0x8581, 0x85a1,
+    0x85c1, 0x85e1, 0x8641, 0x8661, 0x8681, 0x86a1, 0x86c1, 0x86e1,
+    0x8741, 0x8761, 0x8781, 0x87a1,
+};
+
+ENCODER(johab)
+{
+	while (inleft > 0) {
+		Py_UNICODE c = IN1;
+		DBCHAR code;
+
+		if (c < 0x80) {
+			WRITE1((unsigned char)c)
+			NEXT(1, 1)
+			continue;
+		}
+		UCS4INVALID(c)
+
+		REQUIRE_OUTBUF(2)
+
+		if (c >= 0xac00 && c <= 0xd7a3) {
+			c -= 0xac00;
+			code = 0x8000 |
+				(u2johabidx_choseong[c / 588] << 10) |
+				(u2johabidx_jungseong[(c / 28) % 21] << 5) |
+				u2johabidx_jongseong[c % 28];
+		}
+		else if (c >= 0x3131 && c <= 0x3163)
+			code = u2johabjamo[c - 0x3131];
+		else TRYMAP_ENC(cp949, code, c) {
+			unsigned char c1, c2, t2;
+			unsigned short t1;
+
+			assert((code & 0x8000) == 0);
+			c1 = code >> 8;
+			c2 = code & 0xff;
+			if (((c1 >= 0x21 && c1 <= 0x2c) ||
+			    (c1 >= 0x4a && c1 <= 0x7d)) &&
+			    (c2 >= 0x21 && c2 <= 0x7e)) {
+				t1 = (c1 < 0x4a ? (c1 - 0x21 + 0x1b2) :
+						  (c1 - 0x21 + 0x197));
+				t2 = ((t1 & 1) ? 0x5e : 0) + (c2 - 0x21);
+				OUT1(t1 >> 1)
+				OUT2(t2 < 0x4e ? t2 + 0x31 : t2 + 0x43)
+				NEXT(1, 2)
+				continue;
+			}
+			else
+				return 1;
+		}
+		else
+			return 1;
+
+		OUT1(code >> 8)
+		OUT2(code & 0xff)
+		NEXT(1, 2)
+	}
+
+	return 0;
+}
+
+#define FILL 0xfd
+#define NONE 0xff
+
+static const unsigned char johabidx_choseong[32] = {
+    NONE, FILL, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
+    0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
+    0x0e, 0x0f, 0x10, 0x11, 0x12, NONE, NONE, NONE,
+    NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
+};
+static const unsigned char johabidx_jungseong[32] = {
+    NONE, NONE, FILL, 0x00, 0x01, 0x02, 0x03, 0x04,
+    NONE, NONE, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
+    NONE, NONE, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
+    NONE, NONE, 0x11, 0x12, 0x13, 0x14, NONE, NONE,
+};
+static const unsigned char johabidx_jongseong[32] = {
+    NONE, FILL, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
+    0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
+    0x0f, 0x10, NONE, 0x11, 0x12, 0x13, 0x14, 0x15,
+    0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, NONE, NONE,
+};
+
+static const unsigned char johabjamo_choseong[32] = {
+    NONE, FILL, 0x31, 0x32, 0x34, 0x37, 0x38, 0x39,
+    0x41, 0x42, 0x43, 0x45, 0x46, 0x47, 0x48, 0x49,
+    0x4a, 0x4b, 0x4c, 0x4d, 0x4e, NONE, NONE, NONE,
+    NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
+};
+static const unsigned char johabjamo_jungseong[32] = {
+    NONE, NONE, FILL, 0x4f, 0x50, 0x51, 0x52, 0x53,
+    NONE, NONE, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
+    NONE, NONE, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+    NONE, NONE, 0x60, 0x61, 0x62, 0x63, NONE, NONE,
+};
+static const unsigned char johabjamo_jongseong[32] = {
+    NONE, FILL, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
+    0x37, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+    0x40, 0x41, NONE, 0x42, 0x44, 0x45, 0x46, 0x47,
+    0x48, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, NONE, NONE,
+};
+
+DECODER(johab)
+{
+	while (inleft > 0) {
+		unsigned char    c = IN1, c2;
+
+		REQUIRE_OUTBUF(1)
+
+		if (c < 0x80) {
+			OUT1(c)
+			NEXT(1, 1)
+			continue;
+		}
+
+		REQUIRE_INBUF(2)
+		c2 = IN2;
+
+		if (c < 0xd8) {
+			/* johab hangul */
+			unsigned char c_cho, c_jung, c_jong;
+			unsigned char i_cho, i_jung, i_jong;
+
+			c_cho = (c >> 2) & 0x1f;
+			c_jung = ((c << 3) | c2 >> 5) & 0x1f;
+			c_jong = c2 & 0x1f;
+
+			i_cho = johabidx_choseong[c_cho];
+			i_jung = johabidx_jungseong[c_jung];
+			i_jong = johabidx_jongseong[c_jong];
+
+			if (i_cho == NONE || i_jung == NONE || i_jong == NONE)
+				return 2;
+
+			/* we don't use U+1100 hangul jamo yet. */
+			if (i_cho == FILL) {
+				if (i_jung == FILL) {
+					if (i_jong == FILL)
+						OUT1(0x3000)
+					else
+						OUT1(0x3100 |
+						  johabjamo_jongseong[c_jong])
+				}
+				else {
+					if (i_jong == FILL)
+						OUT1(0x3100 |
+						  johabjamo_jungseong[c_jung])
+					else
+						return 2;
+				}
+			} else {
+				if (i_jung == FILL) {
+					if (i_jong == FILL)
+						OUT1(0x3100 |
+						  johabjamo_choseong[c_cho])
+					else
+						return 2;
+				}
+				else
+					OUT1(0xac00 +
+					     i_cho * 588 +
+					     i_jung * 28 +
+					     (i_jong == FILL ? 0 : i_jong))
+			}
+			NEXT(2, 1)
+		} else {
+			/* KS X 1001 except hangul jamos and syllables */
+			if (c == 0xdf || c > 0xf9 ||
+			    c2 < 0x31 || (c2 >= 0x80 && c2 < 0x91) ||
+			    (c2 & 0x7f) == 0x7f ||
+			    (c == 0xda && (c2 >= 0xa1 && c2 <= 0xd3)))
+				return 2;
+			else {
+				unsigned char t1, t2;
+
+				t1 = (c < 0xe0 ? 2 * (c - 0xd9) :
+						 2 * c - 0x197);
+				t2 = (c2 < 0x91 ? c2 - 0x31 : c2 - 0x43);
+				t1 = t1 + (t2 < 0x5e ? 0 : 1) + 0x21;
+				t2 = (t2 < 0x5e ? t2 : t2 - 0x5e) + 0x21;
+
+				TRYMAP_DEC(ksx1001, **outbuf, t1, t2);
+				else return 2;
+				NEXT(2, 1)
+			}
+		}
+	}
+
+	return 0;
+}
+#undef NONE
+#undef FILL
+
+
+BEGIN_MAPPINGS_LIST
+  MAPPING_DECONLY(ksx1001)
+  MAPPING_ENCONLY(cp949)
+  MAPPING_DECONLY(cp949ext)
+END_MAPPINGS_LIST
+
+BEGIN_CODECS_LIST
+  CODEC_STATELESS(euc_kr)
+  CODEC_STATELESS(cp949)
+  CODEC_STATELESS(johab)
+END_CODECS_LIST
+
+I_AM_A_MODULE_FOR(kr)

Added: vendor/Python/current/Modules/cjkcodecs/_codecs_tw.c
===================================================================
--- vendor/Python/current/Modules/cjkcodecs/_codecs_tw.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/cjkcodecs/_codecs_tw.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,132 @@
+/*
+ * _codecs_tw.c: Codecs collection for Taiwan's encodings
+ *
+ * Written by Hye-Shik Chang <perky at FreeBSD.org>
+ */
+
+#include "cjkcodecs.h"
+#include "mappings_tw.h"
+
+/*
+ * BIG5 codec
+ */
+
+ENCODER(big5)
+{
+	while (inleft > 0) {
+		Py_UNICODE c = **inbuf;
+		DBCHAR code;
+
+		if (c < 0x80) {
+			REQUIRE_OUTBUF(1)
+			**outbuf = (unsigned char)c;
+			NEXT(1, 1)
+			continue;
+		}
+		UCS4INVALID(c)
+
+		REQUIRE_OUTBUF(2)
+
+		TRYMAP_ENC(big5, code, c);
+		else return 1;
+
+		OUT1(code >> 8)
+		OUT2(code & 0xFF)
+		NEXT(1, 2)
+	}
+
+	return 0;
+}
+
+DECODER(big5)
+{
+	while (inleft > 0) {
+		unsigned char c = IN1;
+
+		REQUIRE_OUTBUF(1)
+
+		if (c < 0x80) {
+			OUT1(c)
+			NEXT(1, 1)
+			continue;
+		}
+
+		REQUIRE_INBUF(2)
+		TRYMAP_DEC(big5, **outbuf, c, IN2) {
+			NEXT(2, 1)
+		}
+		else return 2;
+	}
+
+	return 0;
+}
+
+
+/*
+ * CP950 codec
+ */
+
+ENCODER(cp950)
+{
+	while (inleft > 0) {
+		Py_UNICODE c = IN1;
+		DBCHAR code;
+
+		if (c < 0x80) {
+			WRITE1((unsigned char)c)
+			NEXT(1, 1)
+			continue;
+		}
+		UCS4INVALID(c)
+
+		REQUIRE_OUTBUF(2)
+		TRYMAP_ENC(cp950ext, code, c);
+		else TRYMAP_ENC(big5, code, c);
+		else return 1;
+
+		OUT1(code >> 8)
+		OUT2(code & 0xFF)
+		NEXT(1, 2)
+	}
+
+	return 0;
+}
+
+DECODER(cp950)
+{
+	while (inleft > 0) {
+		unsigned char c = IN1;
+
+		REQUIRE_OUTBUF(1)
+
+		if (c < 0x80) {
+			OUT1(c)
+			NEXT(1, 1)
+			continue;
+		}
+
+		REQUIRE_INBUF(2)
+
+		TRYMAP_DEC(cp950ext, **outbuf, c, IN2);
+		else TRYMAP_DEC(big5, **outbuf, c, IN2);
+		else return 2;
+
+		NEXT(2, 1)
+	}
+
+	return 0;
+}
+
+
+
+BEGIN_MAPPINGS_LIST
+  MAPPING_ENCDEC(big5)
+  MAPPING_ENCDEC(cp950ext)
+END_MAPPINGS_LIST
+
+BEGIN_CODECS_LIST
+  CODEC_STATELESS(big5)
+  CODEC_STATELESS(cp950)
+END_CODECS_LIST
+
+I_AM_A_MODULE_FOR(tw)

Added: vendor/Python/current/Modules/cjkcodecs/alg_jisx0201.h
===================================================================
--- vendor/Python/current/Modules/cjkcodecs/alg_jisx0201.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/cjkcodecs/alg_jisx0201.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,24 @@
+#define JISX0201_R_ENCODE(c, assi)			\
+	if ((c) < 0x80 && (c) != 0x5c && (c) != 0x7e)	\
+		(assi) = (c);				\
+	else if ((c) == 0x00a5) (assi) = 0x5c;		\
+	else if ((c) == 0x203e) (assi) = 0x7e;
+#define JISX0201_K_ENCODE(c, assi)			\
+	if ((c) >= 0xff61 && (c) <= 0xff9f)		\
+		(assi) = (c) - 0xfec0;
+#define JISX0201_ENCODE(c, assi)			\
+	JISX0201_R_ENCODE(c, assi)			\
+	else JISX0201_K_ENCODE(c, assi)
+
+#define JISX0201_R_DECODE(c, assi)			\
+	if ((c) < 0x5c) (assi) = (c);			\
+	else if ((c) == 0x5c) (assi) = 0x00a5;		\
+	else if ((c) < 0x7e) (assi) = (c);		\
+	else if ((c) == 0x7e) (assi) = 0x203e;		\
+	else if ((c) == 0x7f) (assi) = 0x7f;
+#define JISX0201_K_DECODE(c, assi)			\
+	if ((c) >= 0xa1 && (c) <= 0xdf)			\
+	(assi) = 0xfec0 + (c);
+#define JISX0201_DECODE(c, assi)			\
+	JISX0201_R_DECODE(c, assi)			\
+	else JISX0201_K_DECODE(c, assi)

Added: vendor/Python/current/Modules/cjkcodecs/cjkcodecs.h
===================================================================
--- vendor/Python/current/Modules/cjkcodecs/cjkcodecs.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/cjkcodecs/cjkcodecs.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,398 @@
+/*
+ * cjkcodecs.h: common header for cjkcodecs
+ *
+ * Written by Hye-Shik Chang <perky at FreeBSD.org>
+ */
+
+#ifndef _CJKCODECS_H_
+#define _CJKCODECS_H_
+
+#define PY_SSIZE_T_CLEAN
+#include "Python.h"
+#include "multibytecodec.h"
+
+
+/* a unicode "undefined" codepoint */
+#define UNIINV	0xFFFE
+
+/* internal-use DBCS codepoints which aren't used by any charsets */
+#define NOCHAR	0xFFFF
+#define MULTIC	0xFFFE
+#define DBCINV	0xFFFD
+
+/* shorter macros to save source size of mapping tables */
+#define U UNIINV
+#define N NOCHAR
+#define M MULTIC
+#define D DBCINV
+
+struct dbcs_index {
+	const ucs2_t *map;
+	unsigned char bottom, top;
+};
+typedef struct dbcs_index decode_map;
+
+struct widedbcs_index {
+	const ucs4_t *map;
+	unsigned char bottom, top;
+};
+typedef struct widedbcs_index widedecode_map;
+
+struct unim_index {
+	const DBCHAR *map;
+	unsigned char bottom, top;
+};
+typedef struct unim_index encode_map;
+
+struct unim_index_bytebased {
+	const unsigned char *map;
+	unsigned char bottom, top;
+};
+
+struct dbcs_map {
+	const char *charset;
+	const struct unim_index *encmap;
+	const struct dbcs_index *decmap;
+};
+
+struct pair_encodemap {
+	ucs4_t uniseq;
+	DBCHAR code;
+};
+
+static const MultibyteCodec *codec_list;
+static const struct dbcs_map *mapping_list;
+
+#define CODEC_INIT(encoding)						\
+	static int encoding##_codec_init(const void *config)
+
+#define ENCODER_INIT(encoding)						\
+	static int encoding##_encode_init(				\
+		MultibyteCodec_State *state, const void *config)
+#define ENCODER(encoding)						\
+	static Py_ssize_t encoding##_encode(				\
+		MultibyteCodec_State *state, const void *config,	\
+		const Py_UNICODE **inbuf, Py_ssize_t inleft,		\
+		unsigned char **outbuf, Py_ssize_t outleft, int flags)
+#define ENCODER_RESET(encoding)						\
+	static Py_ssize_t encoding##_encode_reset(			\
+		MultibyteCodec_State *state, const void *config,	\
+		unsigned char **outbuf, Py_ssize_t outleft)
+
+#define DECODER_INIT(encoding)						\
+	static int encoding##_decode_init(				\
+		MultibyteCodec_State *state, const void *config)
+#define DECODER(encoding)						\
+	static Py_ssize_t encoding##_decode(				\
+		MultibyteCodec_State *state, const void *config,	\
+		const unsigned char **inbuf, Py_ssize_t inleft,		\
+		Py_UNICODE **outbuf, Py_ssize_t outleft)
+#define DECODER_RESET(encoding)						\
+	static Py_ssize_t encoding##_decode_reset(			\
+		MultibyteCodec_State *state, const void *config)
+
+#if Py_UNICODE_SIZE == 4
+#define UCS4INVALID(code)	\
+	if ((code) > 0xFFFF)	\
+	return 1;
+#else
+#define UCS4INVALID(code)	\
+	if (0) ;
+#endif
+
+#define NEXT_IN(i)				\
+	(*inbuf) += (i);			\
+	(inleft) -= (i);
+#define NEXT_OUT(o)				\
+	(*outbuf) += (o);			\
+	(outleft) -= (o);
+#define NEXT(i, o)				\
+	NEXT_IN(i) NEXT_OUT(o)
+
+#define REQUIRE_INBUF(n)			\
+	if (inleft < (n))			\
+		return MBERR_TOOFEW;
+#define REQUIRE_OUTBUF(n)			\
+	if (outleft < (n))			\
+		return MBERR_TOOSMALL;
+
+#define IN1 ((*inbuf)[0])
+#define IN2 ((*inbuf)[1])
+#define IN3 ((*inbuf)[2])
+#define IN4 ((*inbuf)[3])
+
+#define OUT1(c) ((*outbuf)[0]) = (c);
+#define OUT2(c) ((*outbuf)[1]) = (c);
+#define OUT3(c) ((*outbuf)[2]) = (c);
+#define OUT4(c) ((*outbuf)[3]) = (c);
+
+#define WRITE1(c1)		\
+	REQUIRE_OUTBUF(1)	\
+	(*outbuf)[0] = (c1);
+#define WRITE2(c1, c2)		\
+	REQUIRE_OUTBUF(2)	\
+	(*outbuf)[0] = (c1);	\
+	(*outbuf)[1] = (c2);
+#define WRITE3(c1, c2, c3)	\
+	REQUIRE_OUTBUF(3)	\
+	(*outbuf)[0] = (c1);	\
+	(*outbuf)[1] = (c2);	\
+	(*outbuf)[2] = (c3);
+#define WRITE4(c1, c2, c3, c4)	\
+	REQUIRE_OUTBUF(4)	\
+	(*outbuf)[0] = (c1);	\
+	(*outbuf)[1] = (c2);	\
+	(*outbuf)[2] = (c3);	\
+	(*outbuf)[3] = (c4);
+
+#if Py_UNICODE_SIZE == 2
+# define WRITEUCS4(c)						\
+	REQUIRE_OUTBUF(2)					\
+	(*outbuf)[0] = 0xd800 + (((c) - 0x10000) >> 10);	\
+	(*outbuf)[1] = 0xdc00 + (((c) - 0x10000) & 0x3ff);	\
+	NEXT_OUT(2)
+#else
+# define WRITEUCS4(c)						\
+	REQUIRE_OUTBUF(1)					\
+	**outbuf = (Py_UNICODE)(c);				\
+	NEXT_OUT(1)
+#endif
+
+#define _TRYMAP_ENC(m, assi, val)				\
+	((m)->map != NULL && (val) >= (m)->bottom &&		\
+	    (val)<= (m)->top && ((assi) = (m)->map[(val) -	\
+	    (m)->bottom]) != NOCHAR)
+#define TRYMAP_ENC_COND(charset, assi, uni)			\
+	_TRYMAP_ENC(&charset##_encmap[(uni) >> 8], assi, (uni) & 0xff)
+#define TRYMAP_ENC(charset, assi, uni)				\
+	if TRYMAP_ENC_COND(charset, assi, uni)
+
+#define _TRYMAP_DEC(m, assi, val)				\
+	((m)->map != NULL && (val) >= (m)->bottom &&		\
+	    (val)<= (m)->top && ((assi) = (m)->map[(val) -	\
+	    (m)->bottom]) != UNIINV)
+#define TRYMAP_DEC(charset, assi, c1, c2)			\
+	if _TRYMAP_DEC(&charset##_decmap[c1], assi, c2)
+
+#define _TRYMAP_ENC_MPLANE(m, assplane, asshi, asslo, val)	\
+	((m)->map != NULL && (val) >= (m)->bottom &&		\
+	    (val)<= (m)->top &&					\
+	    ((assplane) = (m)->map[((val) - (m)->bottom)*3]) != 0 && \
+	    (((asshi) = (m)->map[((val) - (m)->bottom)*3 + 1]), 1) && \
+	    (((asslo) = (m)->map[((val) - (m)->bottom)*3 + 2]), 1))
+#define TRYMAP_ENC_MPLANE(charset, assplane, asshi, asslo, uni)	\
+	if _TRYMAP_ENC_MPLANE(&charset##_encmap[(uni) >> 8], \
+			   assplane, asshi, asslo, (uni) & 0xff)
+#define TRYMAP_DEC_MPLANE(charset, assi, plane, c1, c2)		\
+	if _TRYMAP_DEC(&charset##_decmap[plane][c1], assi, c2)
+
+#if Py_UNICODE_SIZE == 2
+#define DECODE_SURROGATE(c)					\
+	if (c >> 10 == 0xd800 >> 10) { /* high surrogate */	\
+		REQUIRE_INBUF(2)				\
+		if (IN2 >> 10 == 0xdc00 >> 10) { /* low surrogate */ \
+		    c = 0x10000 + ((ucs4_t)(c - 0xd800) << 10) + \
+			((ucs4_t)(IN2) - 0xdc00);		\
+		}						\
+	}
+#define GET_INSIZE(c)	((c) > 0xffff ? 2 : 1)
+#else
+#define DECODE_SURROGATE(c) {;}
+#define GET_INSIZE(c)	1
+#endif
+
+#define BEGIN_MAPPINGS_LIST static const struct dbcs_map _mapping_list[] = {
+#define MAPPING_ENCONLY(enc) {#enc, (void*)enc##_encmap, NULL},
+#define MAPPING_DECONLY(enc) {#enc, NULL, (void*)enc##_decmap},
+#define MAPPING_ENCDEC(enc) {#enc, (void*)enc##_encmap, (void*)enc##_decmap},
+#define END_MAPPINGS_LIST				\
+	{"", NULL, NULL} };				\
+	static const struct dbcs_map *mapping_list =	\
+		(const struct dbcs_map *)_mapping_list;
+
+#define BEGIN_CODECS_LIST static const MultibyteCodec _codec_list[] = {
+#define _STATEFUL_METHODS(enc)		\
+	enc##_encode,			\
+	enc##_encode_init,		\
+	enc##_encode_reset,		\
+	enc##_decode,			\
+	enc##_decode_init,		\
+	enc##_decode_reset,
+#define _STATELESS_METHODS(enc)		\
+	enc##_encode, NULL, NULL,	\
+	enc##_decode, NULL, NULL,
+#define CODEC_STATEFUL(enc) {		\
+	#enc, NULL, NULL,		\
+	_STATEFUL_METHODS(enc)		\
+},
+#define CODEC_STATELESS(enc) {		\
+	#enc, NULL, NULL,		\
+	_STATELESS_METHODS(enc)		\
+},
+#define CODEC_STATELESS_WINIT(enc) {	\
+	#enc, NULL,			\
+	enc##_codec_init,		\
+	_STATELESS_METHODS(enc)		\
+},
+#define END_CODECS_LIST					\
+	{"", NULL,} };					\
+	static const MultibyteCodec *codec_list =	\
+		(const MultibyteCodec *)_codec_list;
+
+static PyObject *
+getmultibytecodec(void)
+{
+	static PyObject *cofunc = NULL;
+
+	if (cofunc == NULL) {
+		PyObject *mod = PyImport_ImportModule("_multibytecodec");
+		if (mod == NULL)
+			return NULL;
+		cofunc = PyObject_GetAttrString(mod, "__create_codec");
+		Py_DECREF(mod);
+	}
+	return cofunc;
+}
+
+static PyObject *
+getcodec(PyObject *self, PyObject *encoding)
+{
+	PyObject *codecobj, *r, *cofunc;
+	const MultibyteCodec *codec;
+	const char *enc;
+
+	if (!PyString_Check(encoding)) {
+		PyErr_SetString(PyExc_TypeError,
+				"encoding name must be a string.");
+		return NULL;
+	}
+
+	cofunc = getmultibytecodec();
+	if (cofunc == NULL)
+		return NULL;
+
+	enc = PyString_AS_STRING(encoding);
+	for (codec = codec_list; codec->encoding[0]; codec++)
+		if (strcmp(codec->encoding, enc) == 0)
+			break;
+
+	if (codec->encoding[0] == '\0') {
+		PyErr_SetString(PyExc_LookupError,
+				"no such codec is supported.");
+		return NULL;
+	}
+
+	codecobj = PyCObject_FromVoidPtr((void *)codec, NULL);
+	if (codecobj == NULL)
+		return NULL;
+
+	r = PyObject_CallFunctionObjArgs(cofunc, codecobj, NULL);
+	Py_DECREF(codecobj);
+
+	return r;
+}
+
+static struct PyMethodDef __methods[] = {
+	{"getcodec", (PyCFunction)getcodec, METH_O, ""},
+	{NULL, NULL},
+};
+
+static int
+register_maps(PyObject *module)
+{
+	const struct dbcs_map *h;
+
+	for (h = mapping_list; h->charset[0] != '\0'; h++) {
+		char mhname[256] = "__map_";
+		int r;
+		strcpy(mhname + sizeof("__map_") - 1, h->charset);
+		r = PyModule_AddObject(module, mhname,
+				PyCObject_FromVoidPtr((void *)h, NULL));
+		if (r == -1)
+			return -1;
+	}
+	return 0;
+}
+
+#ifdef USING_BINARY_PAIR_SEARCH
+static DBCHAR
+find_pairencmap(ucs2_t body, ucs2_t modifier,
+		const struct pair_encodemap *haystack, int haystacksize)
+{
+	int pos, min, max;
+	ucs4_t value = body << 16 | modifier;
+
+	min = 0;
+	max = haystacksize;
+
+	for (pos = haystacksize >> 1; min != max; pos = (min + max) >> 1)
+		if (value < haystack[pos].uniseq) {
+			if (max == pos) break;
+			else max = pos;
+		}
+		else if (value > haystack[pos].uniseq) {
+			if (min == pos) break;
+			else min = pos;
+		}
+		else
+			break;
+
+		if (value == haystack[pos].uniseq)
+			return haystack[pos].code;
+		else
+			return DBCINV;
+}
+#endif
+
+#ifdef USING_IMPORTED_MAPS
+#define IMPORT_MAP(locale, charset, encmap, decmap) \
+	importmap("_codecs_" #locale, "__map_" #charset, \
+		  (const void**)encmap, (const void**)decmap)
+
+static int
+importmap(const char *modname, const char *symbol,
+	  const void **encmap, const void **decmap)
+{
+	PyObject *o, *mod;
+
+	mod = PyImport_ImportModule((char *)modname);
+	if (mod == NULL)
+		return -1;
+
+	o = PyObject_GetAttrString(mod, (char*)symbol);
+	if (o == NULL)
+		goto errorexit;
+	else if (!PyCObject_Check(o)) {
+		PyErr_SetString(PyExc_ValueError,
+				"map data must be a CObject.");
+		goto errorexit;
+	}
+	else {
+		struct dbcs_map *map;
+		map = PyCObject_AsVoidPtr(o);
+		if (encmap != NULL)
+			*encmap = map->encmap;
+		if (decmap != NULL)
+			*decmap = map->decmap;
+		Py_DECREF(o);
+	}
+
+	Py_DECREF(mod);
+	return 0;
+
+errorexit:
+	Py_DECREF(mod);
+	return -1;
+}
+#endif
+
+#define I_AM_A_MODULE_FOR(loc)						\
+	void								\
+	init_codecs_##loc(void)						\
+	{								\
+		PyObject *m = Py_InitModule("_codecs_" #loc, __methods);\
+		if (m != NULL)						\
+			(void)register_maps(m);				\
+	}
+
+#endif

Added: vendor/Python/current/Modules/cjkcodecs/emu_jisx0213_2000.h
===================================================================
--- vendor/Python/current/Modules/cjkcodecs/emu_jisx0213_2000.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/cjkcodecs/emu_jisx0213_2000.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,43 @@
+/* These routines may be quite inefficient, but it's used only to emulate old
+ * standards. */
+
+#ifndef EMULATE_JISX0213_2000_ENCODE_INVALID
+#define EMULATE_JISX0213_2000_ENCODE_INVALID 1
+#endif
+
+#define EMULATE_JISX0213_2000_ENCODE_BMP(assi, c)			\
+	if (config == (void *)2000 && (					\
+			(c) == 0x9B1C || (c) == 0x4FF1 ||		\
+			(c) == 0x525D || (c) == 0x541E ||		\
+			(c) == 0x5653 || (c) == 0x59F8 ||		\
+			(c) == 0x5C5B || (c) == 0x5E77 ||		\
+			(c) == 0x7626 || (c) == 0x7E6B))		\
+		return EMULATE_JISX0213_2000_ENCODE_INVALID;		\
+	else if (config == (void *)2000 && (c) == 0x9B1D)		\
+		(assi) = 0x8000 | 0x7d3b;				\
+
+#define EMULATE_JISX0213_2000_ENCODE_EMP(assi, c)			\
+	if (config == (void *)2000 && (c) == 0x20B9F)			\
+		return EMULATE_JISX0213_2000_ENCODE_INVALID;
+
+#ifndef EMULATE_JISX0213_2000_DECODE_INVALID
+#define EMULATE_JISX0213_2000_DECODE_INVALID 2
+#endif
+
+#define EMULATE_JISX0213_2000_DECODE_PLANE1(assi, c1, c2)		\
+	if (config == (void *)2000 &&					\
+			(((c1) == 0x2E && (c2) == 0x21) ||		\
+			 ((c1) == 0x2F && (c2) == 0x7E) ||		\
+			 ((c1) == 0x4F && (c2) == 0x54) ||		\
+			 ((c1) == 0x4F && (c2) == 0x7E) ||		\
+			 ((c1) == 0x74 && (c2) == 0x27) ||		\
+			 ((c1) == 0x7E && (c2) == 0x7A) ||		\
+			 ((c1) == 0x7E && (c2) == 0x7B) ||		\
+			 ((c1) == 0x7E && (c2) == 0x7C) ||		\
+			 ((c1) == 0x7E && (c2) == 0x7D) ||		\
+			 ((c1) == 0x7E && (c2) == 0x7E)))		\
+		return EMULATE_JISX0213_2000_DECODE_INVALID;
+
+#define EMULATE_JISX0213_2000_DECODE_PLANE2(assi, c1, c2)		\
+	if (config == (void *)2000 && (c1) == 0x7D && (c2) == 0x3B)	\
+		(assi) = 0x9B1D;

Added: vendor/Python/current/Modules/cjkcodecs/mappings_cn.h
===================================================================
--- vendor/Python/current/Modules/cjkcodecs/mappings_cn.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/cjkcodecs/mappings_cn.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,4103 @@
+static const ucs2_t __gb2312_decmap[7482] = {
+12288,12289,12290,12539,713,711,168,12291,12293,8213,65374,8214,8230,8216,
+8217,8220,8221,12308,12309,12296,12297,12298,12299,12300,12301,12302,12303,
+12310,12311,12304,12305,177,215,247,8758,8743,8744,8721,8719,8746,8745,8712,
+8759,8730,8869,8741,8736,8978,8857,8747,8750,8801,8780,8776,8765,8733,8800,
+8814,8815,8804,8805,8734,8757,8756,9794,9792,176,8242,8243,8451,65284,164,
+65504,65505,8240,167,8470,9734,9733,9675,9679,9678,9671,9670,9633,9632,9651,
+9650,8251,8594,8592,8593,8595,12307,9352,9353,9354,9355,9356,9357,9358,9359,
+9360,9361,9362,9363,9364,9365,9366,9367,9368,9369,9370,9371,9332,9333,9334,
+9335,9336,9337,9338,9339,9340,9341,9342,9343,9344,9345,9346,9347,9348,9349,
+9350,9351,9312,9313,9314,9315,9316,9317,9318,9319,9320,9321,U,U,12832,12833,
+12834,12835,12836,12837,12838,12839,12840,12841,U,U,8544,8545,8546,8547,8548,
+8549,8550,8551,8552,8553,8554,8555,65281,65282,65283,65509,65285,65286,65287,
+65288,65289,65290,65291,65292,65293,65294,65295,65296,65297,65298,65299,65300,
+65301,65302,65303,65304,65305,65306,65307,65308,65309,65310,65311,65312,65313,
+65314,65315,65316,65317,65318,65319,65320,65321,65322,65323,65324,65325,65326,
+65327,65328,65329,65330,65331,65332,65333,65334,65335,65336,65337,65338,65339,
+65340,65341,65342,65343,65344,65345,65346,65347,65348,65349,65350,65351,65352,
+65353,65354,65355,65356,65357,65358,65359,65360,65361,65362,65363,65364,65365,
+65366,65367,65368,65369,65370,65371,65372,65373,65507,12353,12354,12355,12356,
+12357,12358,12359,12360,12361,12362,12363,12364,12365,12366,12367,12368,12369,
+12370,12371,12372,12373,12374,12375,12376,12377,12378,12379,12380,12381,12382,
+12383,12384,12385,12386,12387,12388,12389,12390,12391,12392,12393,12394,12395,
+12396,12397,12398,12399,12400,12401,12402,12403,12404,12405,12406,12407,12408,
+12409,12410,12411,12412,12413,12414,12415,12416,12417,12418,12419,12420,12421,
+12422,12423,12424,12425,12426,12427,12428,12429,12430,12431,12432,12433,12434,
+12435,12449,12450,12451,12452,12453,12454,12455,12456,12457,12458,12459,12460,
+12461,12462,12463,12464,12465,12466,12467,12468,12469,12470,12471,12472,12473,
+12474,12475,12476,12477,12478,12479,12480,12481,12482,12483,12484,12485,12486,
+12487,12488,12489,12490,12491,12492,12493,12494,12495,12496,12497,12498,12499,
+12500,12501,12502,12503,12504,12505,12506,12507,12508,12509,12510,12511,12512,
+12513,12514,12515,12516,12517,12518,12519,12520,12521,12522,12523,12524,12525,
+12526,12527,12528,12529,12530,12531,12532,12533,12534,913,914,915,916,917,918,
+919,920,921,922,923,924,925,926,927,928,929,931,932,933,934,935,936,937,U,U,U,
+U,U,U,U,U,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,
+963,964,965,966,967,968,969,1040,1041,1042,1043,1044,1045,1025,1046,1047,1048,
+1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,
+1064,1065,1066,1067,1068,1069,1070,1071,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,1072,
+1073,1074,1075,1076,1077,1105,1078,1079,1080,1081,1082,1083,1084,1085,1086,
+1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,
+1102,1103,257,225,462,224,275,233,283,232,299,237,464,236,333,243,466,242,363,
+250,468,249,470,472,474,476,252,234,U,U,U,U,U,U,U,U,U,U,12549,12550,12551,
+12552,12553,12554,12555,12556,12557,12558,12559,12560,12561,12562,12563,12564,
+12565,12566,12567,12568,12569,12570,12571,12572,12573,12574,12575,12576,12577,
+12578,12579,12580,12581,12582,12583,12584,12585,9472,9473,9474,9475,9476,9477,
+9478,9479,9480,9481,9482,9483,9484,9485,9486,9487,9488,9489,9490,9491,9492,
+9493,9494,9495,9496,9497,9498,9499,9500,9501,9502,9503,9504,9505,9506,9507,
+9508,9509,9510,9511,9512,9513,9514,9515,9516,9517,9518,9519,9520,9521,9522,
+9523,9524,9525,9526,9527,9528,9529,9530,9531,9532,9533,9534,9535,9536,9537,
+9538,9539,9540,9541,9542,9543,9544,9545,9546,9547,21834,38463,22467,25384,
+21710,21769,21696,30353,30284,34108,30702,33406,30861,29233,38552,38797,27688,
+23433,20474,25353,26263,23736,33018,26696,32942,26114,30414,20985,25942,29100,
+32753,34948,20658,22885,25034,28595,33453,25420,25170,21485,21543,31494,20843,
+30116,24052,25300,36299,38774,25226,32793,22365,38712,32610,29240,30333,26575,
+30334,25670,20336,36133,25308,31255,26001,29677,25644,25203,33324,39041,26495,
+29256,25198,25292,20276,29923,21322,21150,32458,37030,24110,26758,27036,33152,
+32465,26834,30917,34444,38225,20621,35876,33502,32990,21253,35090,21093,34180,
+38649,20445,22561,39281,23453,25265,25253,26292,35961,40077,29190,26479,30865,
+24754,21329,21271,36744,32972,36125,38049,20493,29384,22791,24811,28953,34987,
+22868,33519,26412,31528,23849,32503,29997,27893,36454,36856,36924,40763,27604,
+37145,31508,24444,30887,34006,34109,27605,27609,27606,24065,24199,30201,38381,
+25949,24330,24517,36767,22721,33218,36991,38491,38829,36793,32534,36140,25153,
+20415,21464,21342,36776,36777,36779,36941,26631,24426,33176,34920,40150,24971,
+21035,30250,24428,25996,28626,28392,23486,25672,20853,20912,26564,19993,31177,
+39292,28851,30149,24182,29627,33760,25773,25320,38069,27874,21338,21187,25615,
+38082,31636,20271,24091,33334,33046,33162,28196,27850,39539,25429,21340,21754,
+34917,22496,19981,24067,27493,31807,37096,24598,25830,29468,35009,26448,25165,
+36130,30572,36393,37319,24425,33756,34081,39184,21442,34453,27531,24813,24808,
+28799,33485,33329,20179,27815,34255,25805,31961,27133,26361,33609,21397,31574,
+20391,20876,27979,23618,36461,25554,21449,33580,33590,26597,30900,25661,23519,
+23700,24046,35815,25286,26612,35962,25600,25530,34633,39307,35863,32544,38130,
+20135,38416,39076,26124,29462,22330,23581,24120,38271,20607,32928,21378,25950,
+30021,21809,20513,36229,25220,38046,26397,22066,28526,24034,21557,28818,36710,
+25199,25764,25507,24443,28552,37108,33251,36784,23576,26216,24561,27785,38472,
+36225,34924,25745,31216,22478,27225,25104,21576,20056,31243,24809,28548,35802,
+25215,36894,39563,31204,21507,30196,25345,21273,27744,36831,24347,39536,32827,
+40831,20360,23610,36196,32709,26021,28861,20805,20914,34411,23815,23456,25277,
+37228,30068,36364,31264,24833,31609,20167,32504,30597,19985,33261,21021,20986,
+27249,21416,36487,38148,38607,28353,38500,26970,30784,20648,30679,25616,35302,
+22788,25571,24029,31359,26941,20256,33337,21912,20018,30126,31383,24162,24202,
+38383,21019,21561,28810,25462,38180,22402,26149,26943,37255,21767,28147,32431,
+34850,25139,32496,30133,33576,30913,38604,36766,24904,29943,35789,27492,21050,
+36176,27425,32874,33905,22257,21254,20174,19995,20945,31895,37259,31751,20419,
+36479,31713,31388,25703,23828,20652,33030,30209,31929,28140,32736,26449,23384,
+23544,30923,25774,25619,25514,25387,38169,25645,36798,31572,30249,25171,22823,
+21574,27513,20643,25140,24102,27526,20195,36151,34955,24453,36910,24608,32829,
+25285,20025,21333,37112,25528,32966,26086,27694,20294,24814,28129,35806,24377,
+34507,24403,25377,20826,33633,26723,20992,25443,36424,20498,23707,31095,23548,
+21040,31291,24764,36947,30423,24503,24471,30340,36460,28783,30331,31561,30634,
+20979,37011,22564,20302,28404,36842,25932,31515,29380,28068,32735,23265,25269,
+24213,22320,33922,31532,24093,24351,36882,32532,39072,25474,28359,30872,28857,
+20856,38747,22443,30005,20291,30008,24215,24806,22880,28096,27583,30857,21500,
+38613,20939,20993,25481,21514,38035,35843,36300,29241,30879,34678,36845,35853,
+21472,19969,30447,21486,38025,39030,40718,38189,23450,35746,20002,19996,20908,
+33891,25026,21160,26635,20375,24683,20923,27934,20828,25238,26007,38497,35910,
+36887,30168,37117,30563,27602,29322,29420,35835,22581,30585,36172,26460,38208,
+32922,24230,28193,22930,31471,30701,38203,27573,26029,32526,22534,20817,38431,
+23545,22697,21544,36466,25958,39039,22244,38045,30462,36929,25479,21702,22810,
+22842,22427,36530,26421,36346,33333,21057,24816,22549,34558,23784,40517,20420,
+39069,35769,23077,24694,21380,25212,36943,37122,39295,24681,32780,20799,32819,
+23572,39285,27953,20108,36144,21457,32602,31567,20240,20047,38400,27861,29648,
+34281,24070,30058,32763,27146,30718,38034,32321,20961,28902,21453,36820,33539,
+36137,29359,39277,27867,22346,33459,26041,32938,25151,38450,22952,20223,35775,
+32442,25918,33778,38750,21857,39134,32933,21290,35837,21536,32954,24223,27832,
+36153,33452,37210,21545,27675,20998,32439,22367,28954,27774,31881,22859,20221,
+24575,24868,31914,20016,23553,26539,34562,23792,38155,39118,30127,28925,36898,
+20911,32541,35773,22857,20964,20315,21542,22827,25975,32932,23413,25206,25282,
+36752,24133,27679,31526,20239,20440,26381,28014,28074,31119,34993,24343,29995,
+25242,36741,20463,37340,26023,33071,33105,24220,33104,36212,21103,35206,36171,
+22797,20613,20184,38428,29238,33145,36127,23500,35747,38468,22919,32538,21648,
+22134,22030,35813,25913,27010,38041,30422,28297,24178,29976,26438,26577,31487,
+32925,36214,24863,31174,25954,36195,20872,21018,38050,32568,32923,32434,23703,
+28207,26464,31705,30347,39640,33167,32660,31957,25630,38224,31295,21578,21733,
+27468,25601,25096,40509,33011,30105,21106,38761,33883,26684,34532,38401,38548,
+38124,20010,21508,32473,26681,36319,32789,26356,24218,32697,22466,32831,26775,
+24037,25915,21151,24685,40858,20379,36524,20844,23467,24339,24041,27742,25329,
+36129,20849,38057,21246,27807,33503,29399,22434,26500,36141,22815,36764,33735,
+21653,31629,20272,27837,23396,22993,40723,21476,34506,39592,35895,32929,25925,
+39038,22266,38599,21038,29916,21072,23521,25346,35074,20054,25296,24618,26874,
+20851,23448,20896,35266,31649,39302,32592,24815,28748,36143,20809,24191,36891,
+29808,35268,22317,30789,24402,40863,38394,36712,39740,35809,30328,26690,26588,
+36330,36149,21053,36746,28378,26829,38149,37101,22269,26524,35065,36807,21704,
+39608,23401,28023,27686,20133,23475,39559,37219,25000,37039,38889,21547,28085,
+23506,20989,21898,32597,32752,25788,25421,26097,25022,24717,28938,27735,27721,
+22831,26477,33322,22741,22158,35946,27627,37085,22909,32791,21495,28009,21621,
+21917,33655,33743,26680,31166,21644,20309,21512,30418,35977,38402,27827,28088,
+36203,35088,40548,36154,22079,40657,30165,24456,29408,24680,21756,20136,27178,
+34913,24658,36720,21700,28888,34425,40511,27946,23439,24344,32418,21897,20399,
+29492,21564,21402,20505,21518,21628,20046,24573,29786,22774,33899,32993,34676,
+29392,31946,28246,24359,34382,21804,25252,20114,27818,25143,33457,21719,21326,
+29502,28369,30011,21010,21270,35805,27088,24458,24576,28142,22351,27426,29615,
+26707,36824,32531,25442,24739,21796,30186,35938,28949,28067,23462,24187,33618,
+24908,40644,30970,34647,31783,30343,20976,24822,29004,26179,24140,24653,35854,
+28784,25381,36745,24509,24674,34516,22238,27585,24724,24935,21321,24800,26214,
+36159,31229,20250,28905,27719,35763,35826,32472,33636,26127,23130,39746,27985,
+28151,35905,27963,20249,28779,33719,25110,24785,38669,36135,31096,20987,22334,
+22522,26426,30072,31293,31215,31637,32908,39269,36857,28608,35749,40481,23020,
+32489,32521,21513,26497,26840,36753,31821,38598,21450,24613,30142,27762,21363,
+23241,32423,25380,20960,33034,24049,34015,25216,20864,23395,20238,31085,21058,
+24760,27982,23492,23490,35745,35760,26082,24524,38469,22931,32487,32426,22025,
+26551,22841,20339,23478,21152,33626,39050,36158,30002,38078,20551,31292,20215,
+26550,39550,23233,27516,30417,22362,23574,31546,38388,29006,20860,32937,33392,
+22904,32516,33575,26816,26604,30897,30839,25315,25441,31616,20461,21098,20943,
+33616,27099,37492,36341,36145,35265,38190,31661,20214,20581,33328,21073,39279,
+28176,28293,28071,24314,20725,23004,23558,27974,27743,30086,33931,26728,22870,
+35762,21280,37233,38477,34121,26898,30977,28966,33014,20132,37066,27975,39556,
+23047,22204,25605,38128,30699,20389,33050,29409,35282,39290,32564,32478,21119,
+25945,37237,36735,36739,21483,31382,25581,25509,30342,31224,34903,38454,25130,
+21163,33410,26708,26480,25463,30571,31469,27905,32467,35299,22992,25106,34249,
+33445,30028,20511,20171,30117,35819,23626,24062,31563,26020,37329,20170,27941,
+35167,32039,38182,20165,35880,36827,38771,26187,31105,36817,28908,28024,23613,
+21170,33606,20834,33550,30555,26230,40120,20140,24778,31934,31923,32463,20117,
+35686,26223,39048,38745,22659,25964,38236,24452,30153,38742,31455,31454,20928,
+28847,31384,25578,31350,32416,29590,38893,20037,28792,20061,37202,21417,25937,
+26087,33276,33285,21646,23601,30106,38816,25304,29401,30141,23621,39545,33738,
+23616,21632,30697,20030,27822,32858,25298,25454,24040,20855,36317,36382,38191,
+20465,21477,24807,28844,21095,25424,40515,23071,20518,30519,21367,32482,25733,
+25899,25225,25496,20500,29237,35273,20915,35776,32477,22343,33740,38055,20891,
+21531,23803,20426,31459,27994,37089,39567,21888,21654,21345,21679,24320,25577,
+26999,20975,24936,21002,22570,21208,22350,30733,30475,24247,24951,31968,25179,
+25239,20130,28821,32771,25335,28900,38752,22391,33499,26607,26869,30933,39063,
+31185,22771,21683,21487,28212,20811,21051,23458,35838,32943,21827,22438,24691,
+22353,21549,31354,24656,23380,25511,25248,21475,25187,23495,26543,21741,31391,
+33510,37239,24211,35044,22840,22446,25358,36328,33007,22359,31607,20393,24555,
+23485,27454,21281,31568,29378,26694,30719,30518,26103,20917,20111,30420,23743,
+31397,33909,22862,39745,20608,39304,24871,28291,22372,26118,25414,22256,25324,
+25193,24275,38420,22403,25289,21895,34593,33098,36771,21862,33713,26469,36182,
+34013,23146,26639,25318,31726,38417,20848,28572,35888,25597,35272,25042,32518,
+28866,28389,29701,27028,29436,24266,37070,26391,28010,25438,21171,29282,32769,
+20332,23013,37226,28889,28061,21202,20048,38647,38253,34174,30922,32047,20769,
+22418,25794,32907,31867,27882,26865,26974,20919,21400,26792,29313,40654,31729,
+29432,31163,28435,29702,26446,37324,40100,31036,33673,33620,21519,26647,20029,
+21385,21169,30782,21382,21033,20616,20363,20432,30178,31435,31890,27813,38582,
+21147,29827,21737,20457,32852,33714,36830,38256,24265,24604,28063,24088,25947,
+33080,38142,24651,28860,32451,31918,20937,26753,31921,33391,20004,36742,37327,
+26238,20142,35845,25769,32842,20698,30103,29134,23525,36797,28518,20102,25730,
+38243,24278,26009,21015,35010,28872,21155,29454,29747,26519,30967,38678,20020,
+37051,40158,28107,20955,36161,21533,25294,29618,33777,38646,40836,38083,20278,
+32666,20940,28789,38517,23725,39046,21478,20196,28316,29705,27060,30827,39311,
+30041,21016,30244,27969,26611,20845,40857,32843,21657,31548,31423,38534,22404,
+25314,38471,27004,23044,25602,31699,28431,38475,33446,21346,39045,24208,28809,
+25523,21348,34383,40065,40595,30860,38706,36335,36162,40575,28510,31108,24405,
+38470,25134,39540,21525,38109,20387,26053,23653,23649,32533,34385,27695,24459,
+29575,28388,32511,23782,25371,23402,28390,21365,20081,25504,30053,25249,36718,
+20262,20177,27814,32438,35770,33821,34746,32599,36923,38179,31657,39585,35064,
+33853,27931,39558,32476,22920,40635,29595,30721,34434,39532,39554,22043,21527,
+22475,20080,40614,21334,36808,33033,30610,39314,34542,28385,34067,26364,24930,
+28459,35881,33426,33579,30450,27667,24537,33725,29483,33541,38170,27611,30683,
+38086,21359,33538,20882,24125,35980,36152,20040,29611,26522,26757,37238,38665,
+29028,27809,30473,23186,38209,27599,32654,26151,23504,22969,23194,38376,38391,
+20204,33804,33945,27308,30431,38192,29467,26790,23391,30511,37274,38753,31964,
+36855,35868,24357,31859,31192,35269,27852,34588,23494,24130,26825,30496,32501,
+20885,20813,21193,23081,32517,38754,33495,25551,30596,34256,31186,28218,24217,
+22937,34065,28781,27665,25279,30399,25935,24751,38397,26126,34719,40483,38125,
+21517,21629,35884,25720,25721,34321,27169,33180,30952,25705,39764,25273,26411,
+33707,22696,40664,27819,28448,23518,38476,35851,29279,26576,25287,29281,20137,
+22982,27597,22675,26286,24149,21215,24917,26408,30446,30566,29287,31302,25343,
+21738,21584,38048,37027,23068,32435,27670,20035,22902,32784,22856,21335,30007,
+38590,22218,25376,33041,24700,38393,28118,21602,39297,20869,23273,33021,22958,
+38675,20522,27877,23612,25311,20320,21311,33147,36870,28346,34091,25288,24180,
+30910,25781,25467,24565,23064,37247,40479,23615,25423,32834,23421,21870,38218,
+38221,28037,24744,26592,29406,20957,23425,25319,27870,29275,25197,38062,32445,
+33043,27987,20892,24324,22900,21162,24594,22899,26262,34384,30111,25386,25062,
+31983,35834,21734,27431,40485,27572,34261,21589,20598,27812,21866,36276,29228,
+24085,24597,29750,25293,25490,29260,24472,28227,27966,25856,28504,30424,30928,
+30460,30036,21028,21467,20051,24222,26049,32810,32982,25243,21638,21032,28846,
+34957,36305,27873,21624,32986,22521,35060,36180,38506,37197,20329,27803,21943,
+30406,30768,25256,28921,28558,24429,34028,26842,30844,31735,33192,26379,40527,
+25447,30896,22383,30738,38713,25209,25259,21128,29749,27607,21860,33086,30130,
+30382,21305,30174,20731,23617,35692,31687,20559,29255,39575,39128,28418,29922,
+31080,25735,30629,25340,39057,36139,21697,32856,20050,22378,33529,33805,24179,
+20973,29942,35780,23631,22369,27900,39047,23110,30772,39748,36843,31893,21078,
+25169,38138,20166,33670,33889,33769,33970,22484,26420,22275,26222,28006,35889,
+26333,28689,26399,27450,26646,25114,22971,19971,20932,28422,26578,27791,20854,
+26827,22855,27495,30054,23822,33040,40784,26071,31048,31041,39569,36215,23682,
+20062,20225,21551,22865,30732,22120,27668,36804,24323,27773,27875,35755,25488,
+24688,27965,29301,25190,38030,38085,21315,36801,31614,20191,35878,20094,40660,
+38065,38067,21069,28508,36963,27973,35892,22545,23884,27424,27465,26538,21595,
+33108,32652,22681,34103,24378,25250,27207,38201,25970,24708,26725,30631,20052,
+20392,24039,38808,25772,32728,23789,20431,31373,20999,33540,19988,24623,31363,
+38054,20405,20146,31206,29748,21220,33465,25810,31165,23517,27777,38738,36731,
+27682,20542,21375,28165,25806,26228,27696,24773,39031,35831,24198,29756,31351,
+31179,19992,37041,29699,27714,22234,37195,27845,36235,21306,34502,26354,36527,
+23624,39537,28192,21462,23094,40843,36259,21435,22280,39079,26435,37275,27849,
+20840,30154,25331,29356,21048,21149,32570,28820,30264,21364,40522,27063,30830,
+38592,35033,32676,28982,29123,20873,26579,29924,22756,25880,22199,35753,39286,
+25200,32469,24825,28909,22764,20161,20154,24525,38887,20219,35748,20995,22922,
+32427,25172,20173,26085,25102,33592,33993,33635,34701,29076,28342,23481,32466,
+20887,25545,26580,32905,33593,34837,20754,23418,22914,36785,20083,27741,20837,
+35109,36719,38446,34122,29790,38160,38384,28070,33509,24369,25746,27922,33832,
+33134,40131,22622,36187,19977,21441,20254,25955,26705,21971,20007,25620,39578,
+25195,23234,29791,33394,28073,26862,20711,33678,30722,26432,21049,27801,32433,
+20667,21861,29022,31579,26194,29642,33515,26441,23665,21024,29053,34923,38378,
+38485,25797,36193,33203,21892,27733,25159,32558,22674,20260,21830,36175,26188,
+19978,23578,35059,26786,25422,31245,28903,33421,21242,38902,23569,21736,37045,
+32461,22882,36170,34503,33292,33293,36198,25668,23556,24913,28041,31038,35774,
+30775,30003,21627,20280,36523,28145,23072,32453,31070,27784,23457,23158,29978,
+32958,24910,28183,22768,29983,29989,29298,21319,32499,30465,30427,21097,32988,
+22307,24072,22833,29422,26045,28287,35799,23608,34417,21313,30707,25342,26102,
+20160,39135,34432,23454,35782,21490,30690,20351,23630,39542,22987,24335,31034,
+22763,19990,26623,20107,25325,35475,36893,21183,26159,21980,22124,36866,20181,
+20365,37322,39280,27663,24066,24643,23460,35270,35797,25910,25163,39318,23432,
+23551,25480,21806,21463,30246,20861,34092,26530,26803,27530,25234,36755,21460,
+33298,28113,30095,20070,36174,23408,29087,34223,26257,26329,32626,34560,40653,
+40736,23646,26415,36848,26641,26463,25101,31446,22661,24246,25968,28465,24661,
+21047,32781,25684,34928,29993,24069,26643,25332,38684,21452,29245,35841,27700,
+30561,31246,21550,30636,39034,33308,35828,30805,26388,28865,26031,25749,22070,
+24605,31169,21496,19997,27515,32902,23546,21987,22235,20282,20284,39282,24051,
+26494,32824,24578,39042,36865,23435,35772,35829,25628,33368,25822,22013,33487,
+37221,20439,32032,36895,31903,20723,22609,28335,23487,35785,32899,37240,33948,
+31639,34429,38539,38543,32485,39635,30862,23681,31319,36930,38567,31071,23385,
+25439,31499,34001,26797,21766,32553,29712,32034,38145,25152,22604,20182,23427,
+22905,22612,29549,25374,36427,36367,32974,33492,25260,21488,27888,37214,22826,
+24577,27760,22349,25674,36138,30251,28393,22363,27264,30192,28525,35885,35848,
+22374,27631,34962,30899,25506,21497,28845,27748,22616,25642,22530,26848,33179,
+21776,31958,20504,36538,28108,36255,28907,25487,28059,28372,32486,33796,26691,
+36867,28120,38518,35752,22871,29305,34276,33150,30140,35466,26799,21076,36386,
+38161,25552,39064,36420,21884,20307,26367,22159,24789,28053,21059,23625,22825,
+28155,22635,30000,29980,24684,33300,33094,25361,26465,36834,30522,36339,36148,
+38081,24086,21381,21548,28867,27712,24311,20572,20141,24237,25402,33351,36890,
+26704,37230,30643,21516,38108,24420,31461,26742,25413,31570,32479,30171,20599,
+25237,22836,36879,20984,31171,31361,22270,24466,36884,28034,23648,22303,21520,
+20820,28237,22242,25512,39059,33151,34581,35114,36864,21534,23663,33216,25302,
+25176,33073,40501,38464,39534,39548,26925,22949,25299,21822,25366,21703,34521,
+27964,23043,29926,34972,27498,22806,35916,24367,28286,29609,39037,20024,28919,
+23436,30871,25405,26202,30358,24779,23451,23113,19975,33109,27754,29579,20129,
+26505,32593,24448,26106,26395,24536,22916,23041,24013,24494,21361,38886,36829,
+26693,22260,21807,24799,20026,28493,32500,33479,33806,22996,20255,20266,23614,
+32428,26410,34074,21619,30031,32963,21890,39759,20301,28205,35859,23561,24944,
+21355,30239,28201,34442,25991,38395,32441,21563,31283,32010,38382,21985,32705,
+29934,25373,34583,28065,31389,25105,26017,21351,25569,27779,24043,21596,38056,
+20044,27745,35820,23627,26080,33436,26791,21566,21556,27595,27494,20116,25410,
+21320,33310,20237,20398,22366,25098,38654,26212,29289,21247,21153,24735,35823,
+26132,29081,26512,35199,30802,30717,26224,22075,21560,38177,29306,31232,24687,
+24076,24713,33181,22805,24796,29060,28911,28330,27728,29312,27268,34989,24109,
+20064,23219,21916,38115,27927,31995,38553,25103,32454,30606,34430,21283,38686,
+36758,26247,23777,20384,29421,19979,21414,22799,21523,25472,38184,20808,20185,
+40092,32420,21688,36132,34900,33335,38386,28046,24358,23244,26174,38505,29616,
+29486,21439,33146,39301,32673,23466,38519,38480,32447,30456,21410,38262,39321,
+31665,35140,28248,20065,32724,31077,35814,24819,21709,20139,39033,24055,27233,
+20687,21521,35937,33831,30813,38660,21066,21742,22179,38144,28040,23477,28102,
+26195,23567,23389,26657,32918,21880,31505,25928,26964,20123,27463,34638,38795,
+21327,25375,25658,37034,26012,32961,35856,20889,26800,21368,34809,25032,27844,
+27899,35874,23633,34218,33455,38156,27427,36763,26032,24571,24515,20449,34885,
+26143,33125,29481,24826,20852,21009,22411,24418,37026,34892,37266,24184,26447,
+24615,22995,20804,20982,33016,21256,27769,38596,29066,20241,20462,32670,26429,
+21957,38152,31168,34966,32483,22687,25100,38656,34394,22040,39035,24464,35768,
+33988,37207,21465,26093,24207,30044,24676,32110,23167,32490,32493,36713,21927,
+23459,24748,26059,29572,36873,30307,30505,32474,38772,34203,23398,31348,38634,
+34880,21195,29071,24490,26092,35810,23547,39535,24033,27529,27739,35757,35759,
+36874,36805,21387,25276,40486,40493,21568,20011,33469,29273,34460,23830,34905,
+28079,38597,21713,20122,35766,28937,21693,38409,28895,28153,30416,20005,30740,
+34578,23721,24310,35328,39068,38414,28814,27839,22852,25513,30524,34893,28436,
+33395,22576,29141,21388,30746,38593,21761,24422,28976,23476,35866,39564,27523,
+22830,40495,31207,26472,25196,20335,30113,32650,27915,38451,27687,20208,30162,
+20859,26679,28478,36992,33136,22934,29814,25671,23591,36965,31377,35875,23002,
+21676,33280,33647,35201,32768,26928,22094,32822,29239,37326,20918,20063,39029,
+25494,19994,21494,26355,33099,22812,28082,19968,22777,21307,25558,38129,20381,
+20234,34915,39056,22839,36951,31227,20202,33008,30097,27778,23452,23016,24413,
+26885,34433,20506,24050,20057,30691,20197,33402,25233,26131,37009,23673,20159,
+24441,33222,36920,32900,30123,20134,35028,24847,27589,24518,20041,30410,28322,
+35811,35758,35850,35793,24322,32764,32716,32462,33589,33643,22240,27575,38899,
+38452,23035,21535,38134,28139,23493,39278,23609,24341,38544,21360,33521,27185,
+23156,40560,24212,32552,33721,33828,33829,33639,34631,36814,36194,30408,24433,
+39062,30828,26144,21727,25317,20323,33219,30152,24248,38605,36362,34553,21647,
+27891,28044,27704,24703,21191,29992,24189,20248,24736,24551,23588,30001,37038,
+38080,29369,27833,28216,37193,26377,21451,21491,20305,37321,35825,21448,24188,
+36802,28132,20110,30402,27014,34398,24858,33286,20313,20446,36926,40060,24841,
+28189,28180,38533,20104,23089,38632,19982,23679,31161,23431,35821,32701,29577,
+22495,33419,37057,21505,36935,21947,23786,24481,24840,27442,29425,32946,35465,
+28020,23507,35029,39044,35947,39533,40499,28170,20900,20803,22435,34945,21407,
+25588,36757,22253,21592,22278,29503,28304,32536,36828,33489,24895,24616,38498,
+26352,32422,36234,36291,38053,23731,31908,26376,24742,38405,32792,20113,37095,
+21248,38504,20801,36816,34164,37213,26197,38901,23381,21277,30776,26434,26685,
+21705,28798,23472,36733,20877,22312,21681,25874,26242,36190,36163,33039,33900,
+36973,31967,20991,34299,26531,26089,28577,34468,36481,22122,36896,30338,28790,
+29157,36131,25321,21017,27901,36156,24590,22686,24974,26366,36192,25166,21939,
+28195,26413,36711,38113,38392,30504,26629,27048,21643,20045,28856,35784,25688,
+25995,23429,31364,20538,23528,30651,27617,35449,31896,27838,30415,26025,36759,
+23853,23637,34360,26632,21344,25112,31449,28251,32509,27167,31456,24432,28467,
+24352,25484,28072,26454,19976,24080,36134,20183,32960,30260,38556,25307,26157,
+25214,27836,36213,29031,32617,20806,32903,21484,36974,25240,21746,34544,36761,
+32773,38167,34071,36825,27993,29645,26015,30495,29956,30759,33275,36126,38024,
+20390,26517,30137,35786,38663,25391,38215,38453,33976,25379,30529,24449,29424,
+20105,24596,25972,25327,27491,25919,24103,30151,37073,35777,33437,26525,25903,
+21553,34584,30693,32930,33026,27713,20043,32455,32844,30452,26893,27542,25191,
+20540,20356,22336,25351,27490,36286,21482,26088,32440,24535,25370,25527,33267,
+33268,32622,24092,23769,21046,26234,31209,31258,36136,28825,30164,28382,27835,
+31378,20013,30405,24544,38047,34935,32456,31181,32959,37325,20210,20247,33311,
+21608,24030,27954,35788,31909,36724,32920,24090,21650,30385,23449,26172,39588,
+29664,26666,34523,26417,29482,35832,35803,36880,31481,28891,29038,25284,30633,
+22065,20027,33879,26609,21161,34496,36142,38136,31569,20303,27880,31069,39547,
+25235,29226,25341,19987,30742,36716,25776,36186,31686,26729,24196,35013,22918,
+25758,22766,29366,26894,38181,36861,36184,22368,32512,35846,20934,25417,25305,
+21331,26700,29730,33537,37196,21828,30528,28796,27978,20857,21672,36164,23039,
+28363,28100,23388,32043,20180,31869,28371,23376,33258,28173,23383,39683,26837,
+36394,23447,32508,24635,32437,37049,36208,22863,25549,31199,36275,21330,26063,
+31062,35781,38459,32452,38075,32386,22068,37257,26368,32618,23562,36981,26152,
+24038,20304,26590,20570,20316,22352,24231,20109,19980,20800,19984,24319,21317,
+19989,20120,19998,39730,23404,22121,20008,31162,20031,21269,20039,22829,29243,
+21358,27664,22239,32996,39319,27603,30590,40727,20022,20127,40720,20060,20073,
+20115,33416,23387,21868,22031,20164,21389,21405,21411,21413,21422,38757,36189,
+21274,21493,21286,21294,21310,36188,21350,21347,20994,21000,21006,21037,21043,
+21055,21056,21068,21086,21089,21084,33967,21117,21122,21121,21136,21139,20866,
+32596,20155,20163,20169,20162,20200,20193,20203,20190,20251,20211,20258,20324,
+20213,20261,20263,20233,20267,20318,20327,25912,20314,20317,20319,20311,20274,
+20285,20342,20340,20369,20361,20355,20367,20350,20347,20394,20348,20396,20372,
+20454,20456,20458,20421,20442,20451,20444,20433,20447,20472,20521,20556,20467,
+20524,20495,20526,20525,20478,20508,20492,20517,20520,20606,20547,20565,20552,
+20558,20588,20603,20645,20647,20649,20666,20694,20742,20717,20716,20710,20718,
+20743,20747,20189,27709,20312,20325,20430,40864,27718,31860,20846,24061,40649,
+39320,20865,22804,21241,21261,35335,21264,20971,22809,20821,20128,20822,20147,
+34926,34980,20149,33044,35026,31104,23348,34819,32696,20907,20913,20925,20924,
+20935,20886,20898,20901,35744,35750,35751,35754,35764,35765,35767,35778,35779,
+35787,35791,35790,35794,35795,35796,35798,35800,35801,35804,35807,35808,35812,
+35816,35817,35822,35824,35827,35830,35833,35836,35839,35840,35842,35844,35847,
+35852,35855,35857,35858,35860,35861,35862,35865,35867,35864,35869,35871,35872,
+35873,35877,35879,35882,35883,35886,35887,35890,35891,35893,35894,21353,21370,
+38429,38434,38433,38449,38442,38461,38460,38466,38473,38484,38495,38503,38508,
+38514,38516,38536,38541,38551,38576,37015,37019,37021,37017,37036,37025,37044,
+37043,37046,37050,37048,37040,37071,37061,37054,37072,37060,37063,37075,37094,
+37090,37084,37079,37083,37099,37103,37118,37124,37154,37150,37155,37169,37167,
+37177,37187,37190,21005,22850,21154,21164,21165,21182,21759,21200,21206,21232,
+21471,29166,30669,24308,20981,20988,39727,21430,24321,30042,24047,22348,22441,
+22433,22654,22716,22725,22737,22313,22316,22314,22323,22329,22318,22319,22364,
+22331,22338,22377,22405,22379,22406,22396,22395,22376,22381,22390,22387,22445,
+22436,22412,22450,22479,22439,22452,22419,22432,22485,22488,22490,22489,22482,
+22456,22516,22511,22520,22500,22493,22539,22541,22525,22509,22528,22558,22553,
+22596,22560,22629,22636,22657,22665,22682,22656,39336,40729,25087,33401,33405,
+33407,33423,33418,33448,33412,33422,33425,33431,33433,33451,33464,33470,33456,
+33480,33482,33507,33432,33463,33454,33483,33484,33473,33449,33460,33441,33450,
+33439,33476,33486,33444,33505,33545,33527,33508,33551,33543,33500,33524,33490,
+33496,33548,33531,33491,33553,33562,33542,33556,33557,33504,33493,33564,33617,
+33627,33628,33544,33682,33596,33588,33585,33691,33630,33583,33615,33607,33603,
+33631,33600,33559,33632,33581,33594,33587,33638,33637,33640,33563,33641,33644,
+33642,33645,33646,33712,33656,33715,33716,33696,33706,33683,33692,33669,33660,
+33718,33705,33661,33720,33659,33688,33694,33704,33722,33724,33729,33793,33765,
+33752,22535,33816,33803,33757,33789,33750,33820,33848,33809,33798,33748,33759,
+33807,33795,33784,33785,33770,33733,33728,33830,33776,33761,33884,33873,33882,
+33881,33907,33927,33928,33914,33929,33912,33852,33862,33897,33910,33932,33934,
+33841,33901,33985,33997,34000,34022,33981,34003,33994,33983,33978,34016,33953,
+33977,33972,33943,34021,34019,34060,29965,34104,34032,34105,34079,34106,34134,
+34107,34047,34044,34137,34120,34152,34148,34142,34170,30626,34115,34162,34171,
+34212,34216,34183,34191,34169,34222,34204,34181,34233,34231,34224,34259,34241,
+34268,34303,34343,34309,34345,34326,34364,24318,24328,22844,22849,32823,22869,
+22874,22872,21263,23586,23589,23596,23604,25164,25194,25247,25275,25290,25306,
+25303,25326,25378,25334,25401,25419,25411,25517,25590,25457,25466,25486,25524,
+25453,25516,25482,25449,25518,25532,25586,25592,25568,25599,25540,25566,25550,
+25682,25542,25534,25669,25665,25611,25627,25632,25612,25638,25633,25694,25732,
+25709,25750,25722,25783,25784,25753,25786,25792,25808,25815,25828,25826,25865,
+25893,25902,24331,24530,29977,24337,21343,21489,21501,21481,21480,21499,21522,
+21526,21510,21579,21586,21587,21588,21590,21571,21537,21591,21593,21539,21554,
+21634,21652,21623,21617,21604,21658,21659,21636,21622,21606,21661,21712,21677,
+21698,21684,21714,21671,21670,21715,21716,21618,21667,21717,21691,21695,21708,
+21721,21722,21724,21673,21674,21668,21725,21711,21726,21787,21735,21792,21757,
+21780,21747,21794,21795,21775,21777,21799,21802,21863,21903,21941,21833,21869,
+21825,21845,21823,21840,21820,21815,21846,21877,21878,21879,21811,21808,21852,
+21899,21970,21891,21937,21945,21896,21889,21919,21886,21974,21905,21883,21983,
+21949,21950,21908,21913,21994,22007,21961,22047,21969,21995,21996,21972,21990,
+21981,21956,21999,21989,22002,22003,21964,21965,21992,22005,21988,36756,22046,
+22024,22028,22017,22052,22051,22014,22016,22055,22061,22104,22073,22103,22060,
+22093,22114,22105,22108,22092,22100,22150,22116,22129,22123,22139,22140,22149,
+22163,22191,22228,22231,22237,22241,22261,22251,22265,22271,22276,22282,22281,
+22300,24079,24089,24084,24081,24113,24123,24124,24119,24132,24148,24155,24158,
+24161,23692,23674,23693,23696,23702,23688,23704,23705,23697,23706,23708,23733,
+23714,23741,23724,23723,23729,23715,23745,23735,23748,23762,23780,23755,23781,
+23810,23811,23847,23846,23854,23844,23838,23814,23835,23896,23870,23860,23869,
+23916,23899,23919,23901,23915,23883,23882,23913,23924,23938,23961,23965,35955,
+23991,24005,24435,24439,24450,24455,24457,24460,24469,24473,24476,24488,24493,
+24501,24508,34914,24417,29357,29360,29364,29367,29368,29379,29377,29390,29389,
+29394,29416,29423,29417,29426,29428,29431,29441,29427,29443,29434,29435,29463,
+29459,29473,29450,29470,29469,29461,29474,29497,29477,29484,29496,29489,29520,
+29517,29527,29536,29548,29551,29566,33307,22821,39143,22820,22786,39267,39271,
+39272,39273,39274,39275,39276,39284,39287,39293,39296,39300,39303,39306,39309,
+39312,39313,39315,39316,39317,24192,24209,24203,24214,24229,24224,24249,24245,
+24254,24243,36179,24274,24273,24283,24296,24298,33210,24516,24521,24534,24527,
+24579,24558,24580,24545,24548,24574,24581,24582,24554,24557,24568,24601,24629,
+24614,24603,24591,24589,24617,24619,24586,24639,24609,24696,24697,24699,24698,
+24642,24682,24701,24726,24730,24749,24733,24707,24722,24716,24731,24812,24763,
+24753,24797,24792,24774,24794,24756,24864,24870,24853,24867,24820,24832,24846,
+24875,24906,24949,25004,24980,24999,25015,25044,25077,24541,38579,38377,38379,
+38385,38387,38389,38390,38396,38398,38403,38404,38406,38408,38410,38411,38412,
+38413,38415,38418,38421,38422,38423,38425,38426,20012,29247,25109,27701,27732,
+27740,27722,27811,27781,27792,27796,27788,27752,27753,27764,27766,27782,27817,
+27856,27860,27821,27895,27896,27889,27863,27826,27872,27862,27898,27883,27886,
+27825,27859,27887,27902,27961,27943,27916,27971,27976,27911,27908,27929,27918,
+27947,27981,27950,27957,27930,27983,27986,27988,27955,28049,28015,28062,28064,
+27998,28051,28052,27996,28000,28028,28003,28186,28103,28101,28126,28174,28095,
+28128,28177,28134,28125,28121,28182,28075,28172,28078,28203,28270,28238,28267,
+28338,28255,28294,28243,28244,28210,28197,28228,28383,28337,28312,28384,28461,
+28386,28325,28327,28349,28347,28343,28375,28340,28367,28303,28354,28319,28514,
+28486,28487,28452,28437,28409,28463,28470,28491,28532,28458,28425,28457,28553,
+28557,28556,28536,28530,28540,28538,28625,28617,28583,28601,28598,28610,28641,
+28654,28638,28640,28655,28698,28707,28699,28729,28725,28751,28766,23424,23428,
+23445,23443,23461,23480,29999,39582,25652,23524,23534,35120,23536,36423,35591,
+36790,36819,36821,36837,36846,36836,36841,36838,36851,36840,36869,36868,36875,
+36902,36881,36877,36886,36897,36917,36918,36909,36911,36932,36945,36946,36944,
+36968,36952,36962,36955,26297,36980,36989,36994,37000,36995,37003,24400,24407,
+24406,24408,23611,21675,23632,23641,23409,23651,23654,32700,24362,24361,24365,
+33396,24380,39739,23662,22913,22915,22925,22953,22954,22947,22935,22986,22955,
+22942,22948,22994,22962,22959,22999,22974,23045,23046,23005,23048,23011,23000,
+23033,23052,23049,23090,23092,23057,23075,23059,23104,23143,23114,23125,23100,
+23138,23157,33004,23210,23195,23159,23162,23230,23275,23218,23250,23252,23224,
+23264,23267,23281,23254,23270,23256,23260,23305,23319,23318,23346,23351,23360,
+23573,23580,23386,23397,23411,23377,23379,23394,39541,39543,39544,39546,39551,
+39549,39552,39553,39557,39560,39562,39568,39570,39571,39574,39576,39579,39580,
+39581,39583,39584,39586,39587,39589,39591,32415,32417,32419,32421,32424,32425,
+32429,32432,32446,32448,32449,32450,32457,32459,32460,32464,32468,32471,32475,
+32480,32481,32488,32491,32494,32495,32497,32498,32525,32502,32506,32507,32510,
+32513,32514,32515,32519,32520,32523,32524,32527,32529,32530,32535,32537,32540,
+32539,32543,32545,32546,32547,32548,32549,32550,32551,32554,32555,32556,32557,
+32559,32560,32561,32562,32563,32565,24186,30079,24027,30014,37013,29582,29585,
+29614,29602,29599,29647,29634,29649,29623,29619,29632,29641,29640,29669,29657,
+39036,29706,29673,29671,29662,29626,29682,29711,29738,29787,29734,29733,29736,
+29744,29742,29740,29723,29722,29761,29788,29783,29781,29785,29815,29805,29822,
+29852,29838,29824,29825,29831,29835,29854,29864,29865,29840,29863,29906,29882,
+38890,38891,38892,26444,26451,26462,26440,26473,26533,26503,26474,26483,26520,
+26535,26485,26536,26526,26541,26507,26487,26492,26608,26633,26584,26634,26601,
+26544,26636,26585,26549,26586,26547,26589,26624,26563,26552,26594,26638,26561,
+26621,26674,26675,26720,26721,26702,26722,26692,26724,26755,26653,26709,26726,
+26689,26727,26688,26686,26698,26697,26665,26805,26767,26740,26743,26771,26731,
+26818,26990,26876,26911,26912,26873,26916,26864,26891,26881,26967,26851,26896,
+26993,26937,26976,26946,26973,27012,26987,27008,27032,27000,26932,27084,27015,
+27016,27086,27017,26982,26979,27001,27035,27047,27067,27051,27053,27092,27057,
+27073,27082,27103,27029,27104,27021,27135,27183,27117,27159,27160,27237,27122,
+27204,27198,27296,27216,27227,27189,27278,27257,27197,27176,27224,27260,27281,
+27280,27305,27287,27307,29495,29522,27521,27522,27527,27524,27538,27539,27533,
+27546,27547,27553,27562,36715,36717,36721,36722,36723,36725,36726,36728,36727,
+36729,36730,36732,36734,36737,36738,36740,36743,36747,36749,36750,36751,36760,
+36762,36558,25099,25111,25115,25119,25122,25121,25125,25124,25132,33255,29935,
+29940,29951,29967,29969,29971,25908,26094,26095,26096,26122,26137,26482,26115,
+26133,26112,28805,26359,26141,26164,26161,26166,26165,32774,26207,26196,26177,
+26191,26198,26209,26199,26231,26244,26252,26279,26269,26302,26331,26332,26342,
+26345,36146,36147,36150,36155,36157,36160,36165,36166,36168,36169,36167,36173,
+36181,36185,35271,35274,35275,35276,35278,35279,35280,35281,29294,29343,29277,
+29286,29295,29310,29311,29316,29323,29325,29327,29330,25352,25394,25520,25663,
+25816,32772,27626,27635,27645,27637,27641,27653,27655,27654,27661,27669,27672,
+27673,27674,27681,27689,27684,27690,27698,25909,25941,25963,29261,29266,29270,
+29232,34402,21014,32927,32924,32915,32956,26378,32957,32945,32939,32941,32948,
+32951,32999,33000,33001,33002,32987,32962,32964,32985,32973,32983,26384,32989,
+33003,33009,33012,33005,33037,33038,33010,33020,26389,33042,35930,33078,33054,
+33068,33048,33074,33096,33100,33107,33140,33113,33114,33137,33120,33129,33148,
+33149,33133,33127,22605,23221,33160,33154,33169,28373,33187,33194,33228,26406,
+33226,33211,33217,33190,27428,27447,27449,27459,27462,27481,39121,39122,39123,
+39125,39129,39130,27571,24384,27586,35315,26000,40785,26003,26044,26054,26052,
+26051,26060,26062,26066,26070,28800,28828,28822,28829,28859,28864,28855,28843,
+28849,28904,28874,28944,28947,28950,28975,28977,29043,29020,29032,28997,29042,
+29002,29048,29050,29080,29107,29109,29096,29088,29152,29140,29159,29177,29213,
+29224,28780,28952,29030,29113,25150,25149,25155,25160,25161,31035,31040,31046,
+31049,31067,31068,31059,31066,31074,31063,31072,31087,31079,31098,31109,31114,
+31130,31143,31155,24529,24528,24636,24669,24666,24679,24641,24665,24675,24747,
+24838,24845,24925,25001,24989,25035,25041,25094,32896,32895,27795,27894,28156,
+30710,30712,30720,30729,30743,30744,30737,26027,30765,30748,30749,30777,30778,
+30779,30751,30780,30757,30764,30755,30761,30798,30829,30806,30807,30758,30800,
+30791,30796,30826,30875,30867,30874,30855,30876,30881,30883,30898,30905,30885,
+30932,30937,30921,30956,30962,30981,30964,30995,31012,31006,31028,40859,40697,
+40699,40700,30449,30468,30477,30457,30471,30472,30490,30498,30489,30509,30502,
+30517,30520,30544,30545,30535,30531,30554,30568,30562,30565,30591,30605,30589,
+30592,30604,30609,30623,30624,30640,30645,30653,30010,30016,30030,30027,30024,
+30043,30066,30073,30083,32600,32609,32607,35400,32616,32628,32625,32633,32641,
+32638,30413,30437,34866,38021,38022,38023,38027,38026,38028,38029,38031,38032,
+38036,38039,38037,38042,38043,38044,38051,38052,38059,38058,38061,38060,38063,
+38064,38066,38068,38070,38071,38072,38073,38074,38076,38077,38079,38084,38088,
+38089,38090,38091,38092,38093,38094,38096,38097,38098,38101,38102,38103,38105,
+38104,38107,38110,38111,38112,38114,38116,38117,38119,38120,38122,38121,38123,
+38126,38127,38131,38132,38133,38135,38137,38140,38141,38143,38147,38146,38150,
+38151,38153,38154,38157,38158,38159,38162,38163,38164,38165,38166,38168,38171,
+38173,38174,38175,38178,38186,38187,38185,38188,38193,38194,38196,38198,38199,
+38200,38204,38206,38207,38210,38197,38212,38213,38214,38217,38220,38222,38223,
+38226,38227,38228,38230,38231,38232,38233,38235,38238,38239,38237,38241,38242,
+38244,38245,38246,38247,38248,38249,38250,38251,38252,38255,38257,38258,38259,
+38202,30695,30700,38601,31189,31213,31203,31211,31238,23879,31235,31234,31262,
+31252,31289,31287,31313,40655,39333,31344,30344,30350,30355,30361,30372,29918,
+29920,29996,40480,40482,40488,40489,40490,40491,40492,40498,40497,40502,40504,
+40503,40505,40506,40510,40513,40514,40516,40518,40519,40520,40521,40523,40524,
+40526,40529,40533,40535,40538,40539,40540,40542,40547,40550,40551,40552,40553,
+40554,40555,40556,40561,40557,40563,30098,30100,30102,30112,30109,30124,30115,
+30131,30132,30136,30148,30129,30128,30147,30146,30166,30157,30179,30184,30182,
+30180,30187,30183,30211,30193,30204,30207,30224,30208,30213,30220,30231,30218,
+30245,30232,30229,30233,30235,30268,30242,30240,30272,30253,30256,30271,30261,
+30275,30270,30259,30285,30302,30292,30300,30294,30315,30319,32714,31462,31352,
+31353,31360,31366,31368,31381,31398,31392,31404,31400,31405,31411,34916,34921,
+34930,34941,34943,34946,34978,35014,34999,35004,35017,35042,35022,35043,35045,
+35057,35098,35068,35048,35070,35056,35105,35097,35091,35099,35082,35124,35115,
+35126,35137,35174,35195,30091,32997,30386,30388,30684,32786,32788,32790,32796,
+32800,32802,32805,32806,32807,32809,32808,32817,32779,32821,32835,32838,32845,
+32850,32873,32881,35203,39032,39040,39043,39049,39052,39053,39055,39060,39066,
+39067,39070,39071,39073,39074,39077,39078,34381,34388,34412,34414,34431,34426,
+34428,34427,34472,34445,34443,34476,34461,34471,34467,34474,34451,34473,34486,
+34500,34485,34510,34480,34490,34481,34479,34505,34511,34484,34537,34545,34546,
+34541,34547,34512,34579,34526,34548,34527,34520,34513,34563,34567,34552,34568,
+34570,34573,34569,34595,34619,34590,34597,34606,34586,34622,34632,34612,34609,
+34601,34615,34623,34690,34594,34685,34686,34683,34656,34672,34636,34670,34699,
+34643,34659,34684,34660,34649,34661,34707,34735,34728,34770,34758,34696,34693,
+34733,34711,34691,34731,34789,34732,34741,34739,34763,34771,34749,34769,34752,
+34762,34779,34794,34784,34798,34838,34835,34814,34826,34843,34849,34873,34876,
+32566,32578,32580,32581,33296,31482,31485,31496,31491,31492,31509,31498,31531,
+31503,31559,31544,31530,31513,31534,31537,31520,31525,31524,31539,31550,31518,
+31576,31578,31557,31605,31564,31581,31584,31598,31611,31586,31602,31601,31632,
+31654,31655,31672,31660,31645,31656,31621,31658,31644,31650,31659,31668,31697,
+31681,31692,31709,31706,31717,31718,31722,31756,31742,31740,31759,31766,31755,
+31775,31786,31782,31800,31809,31808,33278,33281,33282,33284,33260,34884,33313,
+33314,33315,33325,33327,33320,33323,33336,33339,33331,33332,33342,33348,33353,
+33355,33359,33370,33375,33384,34942,34949,34952,35032,35039,35166,32669,32671,
+32679,32687,32688,32690,31868,25929,31889,31901,31900,31902,31906,31922,31932,
+31933,31937,31943,31948,31949,31944,31941,31959,31976,33390,26280,32703,32718,
+32725,32741,32737,32742,32745,32750,32755,31992,32119,32166,32174,32327,32411,
+40632,40628,36211,36228,36244,36241,36273,36199,36205,35911,35913,37194,37200,
+37198,37199,37220,37218,37217,37232,37225,37231,37245,37246,37234,37236,37241,
+37260,37253,37264,37261,37265,37282,37283,37290,37293,37294,37295,37301,37300,
+37306,35925,40574,36280,36331,36357,36441,36457,36277,36287,36284,36282,36292,
+36310,36311,36314,36318,36302,36303,36315,36294,36332,36343,36344,36323,36345,
+36347,36324,36361,36349,36372,36381,36383,36396,36398,36387,36399,36410,36416,
+36409,36405,36413,36401,36425,36417,36418,36433,36434,36426,36464,36470,36476,
+36463,36468,36485,36495,36500,36496,36508,36510,35960,35970,35978,35973,35992,
+35988,26011,35286,35294,35290,35292,35301,35307,35311,35390,35622,38739,38633,
+38643,38639,38662,38657,38664,38671,38670,38698,38701,38704,38718,40832,40835,
+40837,40838,40839,40840,40841,40842,40844,40702,40715,40717,38585,38588,38589,
+38606,38610,30655,38624,37518,37550,37576,37694,37738,37834,37775,37950,37995,
+40063,40066,40069,40070,40071,40072,31267,40075,40078,40080,40081,40082,40084,
+40085,40090,40091,40094,40095,40096,40097,40098,40099,40101,40102,40103,40104,
+40105,40107,40109,40110,40112,40113,40114,40115,40116,40117,40118,40119,40122,
+40123,40124,40125,40132,40133,40134,40135,40138,40139,40140,40141,40142,40143,
+40144,40147,40148,40149,40151,40152,40153,40156,40157,40159,40162,38780,38789,
+38801,38802,38804,38831,38827,38819,38834,38836,39601,39600,39607,40536,39606,
+39610,39612,39617,39616,39621,39618,39627,39628,39633,39749,39747,39751,39753,
+39752,39757,39761,39144,39181,39214,39253,39252,39647,39649,39654,39663,39659,
+39675,39661,39673,39688,39695,39699,39711,39715,40637,40638,32315,40578,40583,
+40584,40587,40594,37846,40605,40607,40667,40668,40669,40672,40671,40674,40681,
+40679,40677,40682,40687,40738,40748,40751,40761,40759,40765,40766,40772,
+};
+
+static const struct dbcs_index gb2312_decmap[256] = {
+{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{__gb2312_decmap+0,33,126},{__gb2312_decmap+94,
+49,124},{__gb2312_decmap+170,33,126},{__gb2312_decmap+264,33,115},{
+__gb2312_decmap+347,33,118},{__gb2312_decmap+433,33,88},{__gb2312_decmap+489,
+33,113},{__gb2312_decmap+570,33,105},{__gb2312_decmap+643,36,111},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__gb2312_decmap+719,33,126},{
+__gb2312_decmap+813,33,126},{__gb2312_decmap+907,33,126},{__gb2312_decmap+1001
+,33,126},{__gb2312_decmap+1095,33,126},{__gb2312_decmap+1189,33,126},{
+__gb2312_decmap+1283,33,126},{__gb2312_decmap+1377,33,126},{__gb2312_decmap+
+1471,33,126},{__gb2312_decmap+1565,33,126},{__gb2312_decmap+1659,33,126},{
+__gb2312_decmap+1753,33,126},{__gb2312_decmap+1847,33,126},{__gb2312_decmap+
+1941,33,126},{__gb2312_decmap+2035,33,126},{__gb2312_decmap+2129,33,126},{
+__gb2312_decmap+2223,33,126},{__gb2312_decmap+2317,33,126},{__gb2312_decmap+
+2411,33,126},{__gb2312_decmap+2505,33,126},{__gb2312_decmap+2599,33,126},{
+__gb2312_decmap+2693,33,126},{__gb2312_decmap+2787,33,126},{__gb2312_decmap+
+2881,33,126},{__gb2312_decmap+2975,33,126},{__gb2312_decmap+3069,33,126},{
+__gb2312_decmap+3163,33,126},{__gb2312_decmap+3257,33,126},{__gb2312_decmap+
+3351,33,126},{__gb2312_decmap+3445,33,126},{__gb2312_decmap+3539,33,126},{
+__gb2312_decmap+3633,33,126},{__gb2312_decmap+3727,33,126},{__gb2312_decmap+
+3821,33,126},{__gb2312_decmap+3915,33,126},{__gb2312_decmap+4009,33,126},{
+__gb2312_decmap+4103,33,126},{__gb2312_decmap+4197,33,126},{__gb2312_decmap+
+4291,33,126},{__gb2312_decmap+4385,33,121},{__gb2312_decmap+4474,33,126},{
+__gb2312_decmap+4568,33,126},{__gb2312_decmap+4662,33,126},{__gb2312_decmap+
+4756,33,126},{__gb2312_decmap+4850,33,126},{__gb2312_decmap+4944,33,126},{
+__gb2312_decmap+5038,33,126},{__gb2312_decmap+5132,33,126},{__gb2312_decmap+
+5226,33,126},{__gb2312_decmap+5320,33,126},{__gb2312_decmap+5414,33,126},{
+__gb2312_decmap+5508,33,126},{__gb2312_decmap+5602,33,126},{__gb2312_decmap+
+5696,33,126},{__gb2312_decmap+5790,33,126},{__gb2312_decmap+5884,33,126},{
+__gb2312_decmap+5978,33,126},{__gb2312_decmap+6072,33,126},{__gb2312_decmap+
+6166,33,126},{__gb2312_decmap+6260,33,126},{__gb2312_decmap+6354,33,126},{
+__gb2312_decmap+6448,33,126},{__gb2312_decmap+6542,33,126},{__gb2312_decmap+
+6636,33,126},{__gb2312_decmap+6730,33,126},{__gb2312_decmap+6824,33,126},{
+__gb2312_decmap+6918,33,126},{__gb2312_decmap+7012,33,126},{__gb2312_decmap+
+7106,33,126},{__gb2312_decmap+7200,33,126},{__gb2312_decmap+7294,33,126},{
+__gb2312_decmap+7388,33,126},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
+};
+
+static const ucs2_t __gbkext_decmap[14531] = {
+19970,19972,19973,19974,19983,19986,19991,19999,20000,20001,20003,20006,20009,
+20014,20015,20017,20019,20021,20023,20028,20032,20033,20034,20036,20038,20042,
+20049,20053,20055,20058,20059,20066,20067,20068,20069,20071,20072,20074,20075,
+20076,20077,20078,20079,20082,20084,20085,20086,20087,20088,20089,20090,20091,
+20092,20093,20095,20096,20097,20098,20099,20100,20101,20103,20106,U,20112,
+20118,20119,20121,20124,20125,20126,20131,20138,20143,20144,20145,20148,20150,
+20151,20152,20153,20156,20157,20158,20168,20172,20175,20176,20178,20186,20187,
+20188,20192,20194,20198,20199,20201,20205,20206,20207,20209,20212,20216,20217,
+20218,20220,20222,20224,20226,20227,20228,20229,20230,20231,20232,20235,20236,
+20242,20243,20244,20245,20246,20252,20253,20257,20259,20264,20265,20268,20269,
+20270,20273,20275,20277,20279,20281,20283,20286,20287,20288,20289,20290,20292,
+20293,20295,20296,20297,20298,20299,20300,20306,20308,20310,20321,20322,20326,
+20328,20330,20331,20333,20334,20337,20338,20341,20343,20344,20345,20346,20349,
+20352,20353,20354,20357,20358,20359,20362,20364,20366,20368,20370,20371,20373,
+20374,20376,20377,20378,20380,20382,20383,20385,20386,20388,20395,20397,20400,
+20401,20402,20403,20404,20406,20407,20408,20409,20410,20411,20412,20413,20414,
+20416,20417,20418,20422,20423,20424,20425,20427,20428,20429,20434,20435,20436,
+20437,20438,20441,20443,20448,20450,20452,20453,20455,20459,20460,20464,20466,
+20468,20469,20470,20471,20473,20475,20476,20477,20479,20480,20481,20482,20483,
+20484,20485,20486,20487,20488,20489,20490,U,20491,20494,20496,20497,20499,
+20501,20502,20503,20507,20509,20510,20512,20514,20515,20516,20519,20523,20527,
+20528,20529,20530,20531,20532,20533,20534,20535,20536,20537,20539,20541,20543,
+20544,20545,20546,20548,20549,20550,20553,20554,20555,20557,20560,20561,20562,
+20563,20564,20566,20567,20568,20569,20571,20573,20574,20575,20576,20577,20578,
+20579,20580,20582,20583,20584,20585,20586,20587,20589,20590,20591,20592,20593,
+20594,20595,20596,20597,20600,20601,20602,20604,20605,20609,20610,20611,20612,
+20614,20615,20617,20618,20619,20620,20622,20623,20624,20625,20626,20627,20628,
+20629,20630,20631,20632,20633,20634,20635,20636,20637,20638,20639,20640,20641,
+20642,20644,20646,20650,20651,20653,20654,20655,20656,20657,20659,20660,20661,
+20662,20663,20664,20665,20668,20669,20670,20671,20672,20673,20674,20675,20676,
+20677,20678,20679,20680,20681,20682,20683,20684,20685,20686,20688,20689,20690,
+20691,20692,20693,20695,20696,20697,20699,20700,20701,20702,20703,20704,20705,
+20706,20707,20708,20709,20712,20713,20714,20715,20719,20720,20721,20722,20724,
+20726,20727,20728,20729,20730,20732,20733,20734,20735,20736,20737,20738,20739,
+20740,20741,20744,U,20745,20746,20748,20749,20750,20751,20752,20753,20755,
+20756,20757,20758,20759,20760,20761,20762,20763,20764,20765,20766,20767,20768,
+20770,20771,20772,20773,20774,20775,20776,20777,20778,20779,20780,20781,20782,
+20783,20784,20785,20786,20787,20788,20789,20790,20791,20792,20793,20794,20795,
+20796,20797,20798,20802,20807,20810,20812,20814,20815,20816,20818,20819,20823,
+20824,20825,20827,20829,20830,20831,20832,20833,20835,20836,20838,20839,20841,
+20842,20847,20850,20858,20862,20863,20867,20868,20870,20871,20874,20875,20878,
+20879,20880,20881,20883,20884,20888,20890,20893,20894,20895,20897,20899,20902,
+20903,20904,20905,20906,20909,20910,20916,20920,20921,20922,20926,20927,20929,
+20930,20931,20933,20936,20938,20941,20942,20944,20946,20947,20948,20949,20950,
+20951,20952,20953,20954,20956,20958,20959,20962,20963,20965,20966,20967,20968,
+20969,20970,20972,20974,20977,20978,20980,20983,20990,20996,20997,21001,21003,
+21004,21007,21008,21011,21012,21013,21020,21022,21023,21025,21026,21027,21029,
+21030,21031,21034,21036,21039,21041,21042,21044,21045,21052,21054,21060,21061,
+21062,21063,21064,21065,21067,21070,21071,21074,21075,21077,21079,21080,U,
+21081,21082,21083,21085,21087,21088,21090,21091,21092,21094,21096,21099,21100,
+21101,21102,21104,21105,21107,21108,21109,21110,21111,21112,21113,21114,21115,
+21116,21118,21120,21123,21124,21125,21126,21127,21129,21130,21131,21132,21133,
+21134,21135,21137,21138,21140,21141,21142,21143,21144,21145,21146,21148,21156,
+21157,21158,21159,21166,21167,21168,21172,21173,21174,21175,21176,21177,21178,
+21179,21180,21181,21184,21185,21186,21188,21189,21190,21192,21194,21196,21197,
+21198,21199,21201,21203,21204,21205,21207,21209,21210,21211,21212,21213,21214,
+21216,21217,21218,21219,21221,21222,21223,21224,21225,21226,21227,21228,21229,
+21230,21231,21233,21234,21235,21236,21237,21238,21239,21240,21243,21244,21245,
+21249,21250,21251,21252,21255,21257,21258,21259,21260,21262,21265,21266,21267,
+21268,21272,21275,21276,21278,21279,21282,21284,21285,21287,21288,21289,21291,
+21292,21293,21295,21296,21297,21298,21299,21300,21301,21302,21303,21304,21308,
+21309,21312,21314,21316,21318,21323,21324,21325,21328,21332,21336,21337,21339,
+21341,21349,21352,21354,21356,21357,21362,21366,21369,21371,21372,21373,21374,
+21376,21377,21379,21383,21384,21386,21390,21391,U,21392,21393,21394,21395,
+21396,21398,21399,21401,21403,21404,21406,21408,21409,21412,21415,21418,21419,
+21420,21421,21423,21424,21425,21426,21427,21428,21429,21431,21432,21433,21434,
+21436,21437,21438,21440,21443,21444,21445,21446,21447,21454,21455,21456,21458,
+21459,21461,21466,21468,21469,21470,21473,21474,21479,21492,21498,21502,21503,
+21504,21506,21509,21511,21515,21524,21528,21529,21530,21532,21538,21540,21541,
+21546,21552,21555,21558,21559,21562,21565,21567,21569,21570,21572,21573,21575,
+21577,21580,21581,21582,21583,21585,21594,21597,21598,21599,21600,21601,21603,
+21605,21607,21609,21610,21611,21612,21613,21614,21615,21616,21620,21625,21626,
+21630,21631,21633,21635,21637,21639,21640,21641,21642,21645,21649,21651,21655,
+21656,21660,21662,21663,21664,21665,21666,21669,21678,21680,21682,21685,21686,
+21687,21689,21690,21692,21694,21699,21701,21706,21707,21718,21720,21723,21728,
+21729,21730,21731,21732,21739,21740,21743,21744,21745,21748,21749,21750,21751,
+21752,21753,21755,21758,21760,21762,21763,21764,21765,21768,21770,21771,21772,
+21773,21774,21778,21779,21781,21782,21783,21784,21785,21786,21788,21789,21790,
+21791,21793,21797,21798,U,21800,21801,21803,21805,21810,21812,21813,21814,
+21816,21817,21818,21819,21821,21824,21826,21829,21831,21832,21835,21836,21837,
+21838,21839,21841,21842,21843,21844,21847,21848,21849,21850,21851,21853,21854,
+21855,21856,21858,21859,21864,21865,21867,21871,21872,21873,21874,21875,21876,
+21881,21882,21885,21887,21893,21894,21900,21901,21902,21904,21906,21907,21909,
+21910,21911,21914,21915,21918,21920,21921,21922,21923,21924,21925,21926,21928,
+21929,21930,21931,21932,21933,21934,21935,21936,21938,21940,21942,21944,21946,
+21948,21951,21952,21953,21954,21955,21958,21959,21960,21962,21963,21966,21967,
+21968,21973,21975,21976,21977,21978,21979,21982,21984,21986,21991,21993,21997,
+21998,22000,22001,22004,22006,22008,22009,22010,22011,22012,22015,22018,22019,
+22020,22021,22022,22023,22026,22027,22029,22032,22033,22034,22035,22036,22037,
+22038,22039,22041,22042,22044,22045,22048,22049,22050,22053,22054,22056,22057,
+22058,22059,22062,22063,22064,22067,22069,22071,22072,22074,22076,22077,22078,
+22080,22081,22082,22083,22084,22085,22086,22087,22088,22089,22090,22091,22095,
+22096,22097,22098,22099,22101,22102,22106,22107,22109,22110,22111,22112,22113,
+U,22115,22117,22118,22119,22125,22126,22127,22128,22130,22131,22132,22133,
+22135,22136,22137,22138,22141,22142,22143,22144,22145,22146,22147,22148,22151,
+22152,22153,22154,22155,22156,22157,22160,22161,22162,22164,22165,22166,22167,
+22168,22169,22170,22171,22172,22173,22174,22175,22176,22177,22178,22180,22181,
+22182,22183,22184,22185,22186,22187,22188,22189,22190,22192,22193,22194,22195,
+22196,22197,22198,22200,22201,22202,22203,22205,22206,22207,22208,22209,22210,
+22211,22212,22213,22214,22215,22216,22217,22219,22220,22221,22222,22223,22224,
+22225,22226,22227,22229,22230,22232,22233,22236,22243,22245,22246,22247,22248,
+22249,22250,22252,22254,22255,22258,22259,22262,22263,22264,22267,22268,22272,
+22273,22274,22277,22279,22283,22284,22285,22286,22287,22288,22289,22290,22291,
+22292,22293,22294,22295,22296,22297,22298,22299,22301,22302,22304,22305,22306,
+22308,22309,22310,22311,22315,22321,22322,22324,22325,22326,22327,22328,22332,
+22333,22335,22337,22339,22340,22341,22342,22344,22345,22347,22354,22355,22356,
+22357,22358,22360,22361,22370,22371,22373,22375,22380,22382,22384,22385,22386,
+22388,22389,22392,22393,22394,22397,22398,22399,22400,U,22401,22407,22408,
+22409,22410,22413,22414,22415,22416,22417,22420,22421,22422,22423,22424,22425,
+22426,22428,22429,22430,22431,22437,22440,22442,22444,22447,22448,22449,22451,
+22453,22454,22455,22457,22458,22459,22460,22461,22462,22463,22464,22465,22468,
+22469,22470,22471,22472,22473,22474,22476,22477,22480,22481,22483,22486,22487,
+22491,22492,22494,22497,22498,22499,22501,22502,22503,22504,22505,22506,22507,
+22508,22510,22512,22513,22514,22515,22517,22518,22519,22523,22524,22526,22527,
+22529,22531,22532,22533,22536,22537,22538,22540,22542,22543,22544,22546,22547,
+22548,22550,22551,22552,22554,22555,22556,22557,22559,22562,22563,22565,22566,
+22567,22568,22569,22571,22572,22573,22574,22575,22577,22578,22579,22580,22582,
+22583,22584,22585,22586,22587,22588,22589,22590,22591,22592,22593,22594,22595,
+22597,22598,22599,22600,22601,22602,22603,22606,22607,22608,22610,22611,22613,
+22614,22615,22617,22618,22619,22620,22621,22623,22624,22625,22626,22627,22628,
+22630,22631,22632,22633,22634,22637,22638,22639,22640,22641,22642,22643,22644,
+22645,22646,22647,22648,22649,22650,22651,22652,22653,22655,22658,22660,22662,
+22663,22664,22666,22667,22668,U,22669,22670,22671,22672,22673,22676,22677,
+22678,22679,22680,22683,22684,22685,22688,22689,22690,22691,22692,22693,22694,
+22695,22698,22699,22700,22701,22702,22703,22704,22705,22706,22707,22708,22709,
+22710,22711,22712,22713,22714,22715,22717,22718,22719,22720,22722,22723,22724,
+22726,22727,22728,22729,22730,22731,22732,22733,22734,22735,22736,22738,22739,
+22740,22742,22743,22744,22745,22746,22747,22748,22749,22750,22751,22752,22753,
+22754,22755,22757,22758,22759,22760,22761,22762,22765,22767,22769,22770,22772,
+22773,22775,22776,22778,22779,22780,22781,22782,22783,22784,22785,22787,22789,
+22790,22792,22793,22794,22795,22796,22798,22800,22801,22802,22803,22807,22808,
+22811,22813,22814,22816,22817,22818,22819,22822,22824,22828,22832,22834,22835,
+22837,22838,22843,22845,22846,22847,22848,22851,22853,22854,22858,22860,22861,
+22864,22866,22867,22873,22875,22876,22877,22878,22879,22881,22883,22884,22886,
+22887,22888,22889,22890,22891,22892,22893,22894,22895,22896,22897,22898,22901,
+22903,22906,22907,22908,22910,22911,22912,22917,22921,22923,22924,22926,22927,
+22928,22929,22932,22933,22936,22938,22939,22940,22941,22943,22944,22945,22946,
+22950,U,22951,22956,22957,22960,22961,22963,22964,22965,22966,22967,22968,
+22970,22972,22973,22975,22976,22977,22978,22979,22980,22981,22983,22984,22985,
+22988,22989,22990,22991,22997,22998,23001,23003,23006,23007,23008,23009,23010,
+23012,23014,23015,23017,23018,23019,23021,23022,23023,23024,23025,23026,23027,
+23028,23029,23030,23031,23032,23034,23036,23037,23038,23040,23042,23050,23051,
+23053,23054,23055,23056,23058,23060,23061,23062,23063,23065,23066,23067,23069,
+23070,23073,23074,23076,23078,23079,23080,23082,23083,23084,23085,23086,23087,
+23088,23091,23093,23095,23096,23097,23098,23099,23101,23102,23103,23105,23106,
+23107,23108,23109,23111,23112,23115,23116,23117,23118,23119,23120,23121,23122,
+23123,23124,23126,23127,23128,23129,23131,23132,23133,23134,23135,23136,23137,
+23139,23140,23141,23142,23144,23145,23147,23148,23149,23150,23151,23152,23153,
+23154,23155,23160,23161,23163,23164,23165,23166,23168,23169,23170,23171,23172,
+23173,23174,23175,23176,23177,23178,23179,23180,23181,23182,23183,23184,23185,
+23187,23188,23189,23190,23191,23192,23193,23196,23197,23198,23199,23200,23201,
+23202,23203,23204,23205,23206,23207,23208,23209,23211,23212,U,23213,23214,
+23215,23216,23217,23220,23222,23223,23225,23226,23227,23228,23229,23231,23232,
+23235,23236,23237,23238,23239,23240,23242,23243,23245,23246,23247,23248,23249,
+23251,23253,23255,23257,23258,23259,23261,23262,23263,23266,23268,23269,23271,
+23272,23274,23276,23277,23278,23279,23280,23282,23283,23284,23285,23286,23287,
+23288,23289,23290,23291,23292,23293,23294,23295,23296,23297,23298,23299,23300,
+23301,23302,23303,23304,23306,23307,23308,23309,23310,23311,23312,23313,23314,
+23315,23316,23317,23320,23321,23322,23323,23324,23325,23326,23327,23328,23329,
+23330,23331,23332,23333,23334,23335,23336,23337,23338,23339,23340,23341,23342,
+23343,23344,23345,23347,23349,23350,23352,23353,23354,23355,23356,23357,23358,
+23359,23361,23362,23363,23364,23365,23366,23367,23368,23369,23370,23371,23372,
+23373,23374,23375,23378,23382,23390,23392,23393,23399,23400,23403,23405,23406,
+23407,23410,23412,23414,23415,23416,23417,23419,23420,23422,23423,23426,23430,
+23434,23437,23438,23440,23441,23442,23444,23446,23455,23463,23464,23465,23468,
+23469,23470,23471,23473,23474,23479,23482,23483,23484,23488,23489,23491,23496,
+23497,23498,23499,23501,23502,23503,U,23505,23508,23509,23510,23511,23512,
+23513,23514,23515,23516,23520,23522,23523,23526,23527,23529,23530,23531,23532,
+23533,23535,23537,23538,23539,23540,23541,23542,23543,23549,23550,23552,23554,
+23555,23557,23559,23560,23563,23564,23565,23566,23568,23570,23571,23575,23577,
+23579,23582,23583,23584,23585,23587,23590,23592,23593,23594,23595,23597,23598,
+23599,23600,23602,23603,23605,23606,23607,23619,23620,23622,23623,23628,23629,
+23634,23635,23636,23638,23639,23640,23642,23643,23644,23645,23647,23650,23652,
+23655,23656,23657,23658,23659,23660,23661,23664,23666,23667,23668,23669,23670,
+23671,23672,23675,23676,23677,23678,23680,23683,23684,23685,23686,23687,23689,
+23690,23691,23694,23695,23698,23699,23701,23709,23710,23711,23712,23713,23716,
+23717,23718,23719,23720,23722,23726,23727,23728,23730,23732,23734,23737,23738,
+23739,23740,23742,23744,23746,23747,23749,23750,23751,23752,23753,23754,23756,
+23757,23758,23759,23760,23761,23763,23764,23765,23766,23767,23768,23770,23771,
+23772,23773,23774,23775,23776,23778,23779,23783,23785,23787,23788,23790,23791,
+23793,23794,23795,23796,23797,23798,23799,23800,23801,23802,23804,23805,23806,
+23807,23808,U,23809,23812,23813,23816,23817,23818,23819,23820,23821,23823,
+23824,23825,23826,23827,23829,23831,23832,23833,23834,23836,23837,23839,23840,
+23841,23842,23843,23845,23848,23850,23851,23852,23855,23856,23857,23858,23859,
+23861,23862,23863,23864,23865,23866,23867,23868,23871,23872,23873,23874,23875,
+23876,23877,23878,23880,23881,23885,23886,23887,23888,23889,23890,23891,23892,
+23893,23894,23895,23897,23898,23900,23902,23903,23904,23905,23906,23907,23908,
+23909,23910,23911,23912,23914,23917,23918,23920,23921,23922,23923,23925,23926,
+23927,23928,23929,23930,23931,23932,23933,23934,23935,23936,23937,23939,23940,
+23941,23942,23943,23944,23945,23946,23947,23948,23949,23950,23951,23952,23953,
+23954,23955,23956,23957,23958,23959,23960,23962,23963,23964,23966,23967,23968,
+23969,23970,23971,23972,23973,23974,23975,23976,23977,23978,23979,23980,23981,
+23982,23983,23984,23985,23986,23987,23988,23989,23990,23992,23993,23994,23995,
+23996,23997,23998,23999,24000,24001,24002,24003,24004,24006,24007,24008,24009,
+24010,24011,24012,24014,24015,24016,24017,24018,24019,24020,24021,24022,24023,
+24024,24025,24026,24028,24031,24032,24035,24036,24042,24044,24045,U,24048,
+24053,24054,24056,24057,24058,24059,24060,24063,24064,24068,24071,24073,24074,
+24075,24077,24078,24082,24083,24087,24094,24095,24096,24097,24098,24099,24100,
+24101,24104,24105,24106,24107,24108,24111,24112,24114,24115,24116,24117,24118,
+24121,24122,24126,24127,24128,24129,24131,24134,24135,24136,24137,24138,24139,
+24141,24142,24143,24144,24145,24146,24147,24150,24151,24152,24153,24154,24156,
+24157,24159,24160,24163,24164,24165,24166,24167,24168,24169,24170,24171,24172,
+24173,24174,24175,24176,24177,24181,24183,24185,24190,24193,24194,24195,24197,
+24200,24201,24204,24205,24206,24210,24216,24219,24221,24225,24226,24227,24228,
+24232,24233,24234,24235,24236,24238,24239,24240,24241,24242,24244,24250,24251,
+24252,24253,24255,24256,24257,24258,24259,24260,24261,24262,24263,24264,24267,
+24268,24269,24270,24271,24272,24276,24277,24279,24280,24281,24282,24284,24285,
+24286,24287,24288,24289,24290,24291,24292,24293,24294,24295,24297,24299,24300,
+24301,24302,24303,24304,24305,24306,24307,24309,24312,24313,24315,24316,24317,
+24325,24326,24327,24329,24332,24333,24334,24336,24338,24340,24342,24345,24346,
+24348,24349,24350,24353,24354,24355,24356,U,24360,24363,24364,24366,24368,
+24370,24371,24372,24373,24374,24375,24376,24379,24381,24382,24383,24385,24386,
+24387,24388,24389,24390,24391,24392,24393,24394,24395,24396,24397,24398,24399,
+24401,24404,24409,24410,24411,24412,24414,24415,24416,24419,24421,24423,24424,
+24427,24430,24431,24434,24436,24437,24438,24440,24442,24445,24446,24447,24451,
+24454,24461,24462,24463,24465,24467,24468,24470,24474,24475,24477,24478,24479,
+24480,24482,24483,24484,24485,24486,24487,24489,24491,24492,24495,24496,24497,
+24498,24499,24500,24502,24504,24505,24506,24507,24510,24511,24512,24513,24514,
+24519,24520,24522,24523,24526,24531,24532,24533,24538,24539,24540,24542,24543,
+24546,24547,24549,24550,24552,24553,24556,24559,24560,24562,24563,24564,24566,
+24567,24569,24570,24572,24583,24584,24585,24587,24588,24592,24593,24595,24599,
+24600,24602,24606,24607,24610,24611,24612,24620,24621,24622,24624,24625,24626,
+24627,24628,24630,24631,24632,24633,24634,24637,24638,24640,24644,24645,24646,
+24647,24648,24649,24650,24652,24654,24655,24657,24659,24660,24662,24663,24664,
+24667,24668,24670,24671,24672,24673,24677,24678,24686,24689,24690,24692,24693,
+24695,24702,24704,U,24705,24706,24709,24710,24711,24712,24714,24715,24718,
+24719,24720,24721,24723,24725,24727,24728,24729,24732,24734,24737,24738,24740,
+24741,24743,24745,24746,24750,24752,24755,24757,24758,24759,24761,24762,24765,
+24766,24767,24768,24769,24770,24771,24772,24775,24776,24777,24780,24781,24782,
+24783,24784,24786,24787,24788,24790,24791,24793,24795,24798,24801,24802,24803,
+24804,24805,24810,24817,24818,24821,24823,24824,24827,24828,24829,24830,24831,
+24834,24835,24836,24837,24839,24842,24843,24844,24848,24849,24850,24851,24852,
+24854,24855,24856,24857,24859,24860,24861,24862,24865,24866,24869,24872,24873,
+24874,24876,24877,24878,24879,24880,24881,24882,24883,24884,24885,24886,24887,
+24888,24889,24890,24891,24892,24893,24894,24896,24897,24898,24899,24900,24901,
+24902,24903,24905,24907,24909,24911,24912,24914,24915,24916,24918,24919,24920,
+24921,24922,24923,24924,24926,24927,24928,24929,24931,24932,24933,24934,24937,
+24938,24939,24940,24941,24942,24943,24945,24946,24947,24948,24950,24952,24953,
+24954,24955,24956,24957,24958,24959,24960,24961,24962,24963,24964,24965,24966,
+24967,24968,24969,24970,24972,24973,24975,24976,24977,24978,24979,24981,U,
+24982,24983,24984,24985,24986,24987,24988,24990,24991,24992,24993,24994,24995,
+24996,24997,24998,25002,25003,25005,25006,25007,25008,25009,25010,25011,25012,
+25013,25014,25016,25017,25018,25019,25020,25021,25023,25024,25025,25027,25028,
+25029,25030,25031,25033,25036,25037,25038,25039,25040,25043,25045,25046,25047,
+25048,25049,25050,25051,25052,25053,25054,25055,25056,25057,25058,25059,25060,
+25061,25063,25064,25065,25066,25067,25068,25069,25070,25071,25072,25073,25074,
+25075,25076,25078,25079,25080,25081,25082,25083,25084,25085,25086,25088,25089,
+25090,25091,25092,25093,25095,25097,25107,25108,25113,25116,25117,25118,25120,
+25123,25126,25127,25128,25129,25131,25133,25135,25136,25137,25138,25141,25142,
+25144,25145,25146,25147,25148,25154,25156,25157,25158,25162,25167,25168,25173,
+25174,25175,25177,25178,25180,25181,25182,25183,25184,25185,25186,25188,25189,
+25192,25201,25202,25204,25205,25207,25208,25210,25211,25213,25217,25218,25219,
+25221,25222,25223,25224,25227,25228,25229,25230,25231,25232,25236,25241,25244,
+25245,25246,25251,25254,25255,25257,25258,25261,25262,25263,25264,25266,25267,
+25268,25270,25271,25272,25274,25278,25280,25281,U,25283,25291,25295,25297,
+25301,25309,25310,25312,25313,25316,25322,25323,25328,25330,25333,25336,25337,
+25338,25339,25344,25347,25348,25349,25350,25354,25355,25356,25357,25359,25360,
+25362,25363,25364,25365,25367,25368,25369,25372,25382,25383,25385,25388,25389,
+25390,25392,25393,25395,25396,25397,25398,25399,25400,25403,25404,25406,25407,
+25408,25409,25412,25415,25416,25418,25425,25426,25427,25428,25430,25431,25432,
+25433,25434,25435,25436,25437,25440,25444,25445,25446,25448,25450,25451,25452,
+25455,25456,25458,25459,25460,25461,25464,25465,25468,25469,25470,25471,25473,
+25475,25476,25477,25478,25483,25485,25489,25491,25492,25493,25495,25497,25498,
+25499,25500,25501,25502,25503,25505,25508,25510,25515,25519,25521,25522,25525,
+25526,25529,25531,25533,25535,25536,25537,25538,25539,25541,25543,25544,25546,
+25547,25548,25553,25555,25556,25557,25559,25560,25561,25562,25563,25564,25565,
+25567,25570,25572,25573,25574,25575,25576,25579,25580,25582,25583,25584,25585,
+25587,25589,25591,25593,25594,25595,25596,25598,25603,25604,25606,25607,25608,
+25609,25610,25613,25614,25617,25618,25621,25622,25623,25624,25625,25626,25629,
+25631,25634,25635,25636,U,25637,25639,25640,25641,25643,25646,25647,25648,
+25649,25650,25651,25653,25654,25655,25656,25657,25659,25660,25662,25664,25666,
+25667,25673,25675,25676,25677,25678,25679,25680,25681,25683,25685,25686,25687,
+25689,25690,25691,25692,25693,25695,25696,25697,25698,25699,25700,25701,25702,
+25704,25706,25707,25708,25710,25711,25712,25713,25714,25715,25716,25717,25718,
+25719,25723,25724,25725,25726,25727,25728,25729,25731,25734,25736,25737,25738,
+25739,25740,25741,25742,25743,25744,25747,25748,25751,25752,25754,25755,25756,
+25757,25759,25760,25761,25762,25763,25765,25766,25767,25768,25770,25771,25775,
+25777,25778,25779,25780,25782,25785,25787,25789,25790,25791,25793,25795,25796,
+25798,25799,25800,25801,25802,25803,25804,25807,25809,25811,25812,25813,25814,
+25817,25818,25819,25820,25821,25823,25824,25825,25827,25829,25831,25832,25833,
+25834,25835,25836,25837,25838,25839,25840,25841,25842,25843,25844,25845,25846,
+25847,25848,25849,25850,25851,25852,25853,25854,25855,25857,25858,25859,25860,
+25861,25862,25863,25864,25866,25867,25868,25869,25870,25871,25872,25873,25875,
+25876,25877,25878,25879,25881,25882,25883,25884,25885,25886,25887,25888,25889,
+U,25890,25891,25892,25894,25895,25896,25897,25898,25900,25901,25904,25905,
+25906,25907,25911,25914,25916,25917,25920,25921,25922,25923,25924,25926,25927,
+25930,25931,25933,25934,25936,25938,25939,25940,25943,25944,25946,25948,25951,
+25952,25953,25956,25957,25959,25960,25961,25962,25965,25966,25967,25969,25971,
+25973,25974,25976,25977,25978,25979,25980,25981,25982,25983,25984,25985,25986,
+25987,25988,25989,25990,25992,25993,25994,25997,25998,25999,26002,26004,26005,
+26006,26008,26010,26013,26014,26016,26018,26019,26022,26024,26026,26028,26030,
+26033,26034,26035,26036,26037,26038,26039,26040,26042,26043,26046,26047,26048,
+26050,26055,26056,26057,26058,26061,26064,26065,26067,26068,26069,26072,26073,
+26074,26075,26076,26077,26078,26079,26081,26083,26084,26090,26091,26098,26099,
+26100,26101,26104,26105,26107,26108,26109,26110,26111,26113,26116,26117,26119,
+26120,26121,26123,26125,26128,26129,26130,26134,26135,26136,26138,26139,26140,
+26142,26145,26146,26147,26148,26150,26153,26154,26155,26156,26158,26160,26162,
+26163,26167,26168,26169,26170,26171,26173,26175,26176,26178,26180,26181,26182,
+26183,26184,26185,26186,26189,26190,26192,26193,26200,U,26201,26203,26204,
+26205,26206,26208,26210,26211,26213,26215,26217,26218,26219,26220,26221,26225,
+26226,26227,26229,26232,26233,26235,26236,26237,26239,26240,26241,26243,26245,
+26246,26248,26249,26250,26251,26253,26254,26255,26256,26258,26259,26260,26261,
+26264,26265,26266,26267,26268,26270,26271,26272,26273,26274,26275,26276,26277,
+26278,26281,26282,26283,26284,26285,26287,26288,26289,26290,26291,26293,26294,
+26295,26296,26298,26299,26300,26301,26303,26304,26305,26306,26307,26308,26309,
+26310,26311,26312,26313,26314,26315,26316,26317,26318,26319,26320,26321,26322,
+26323,26324,26325,26326,26327,26328,26330,26334,26335,26336,26337,26338,26339,
+26340,26341,26343,26344,26346,26347,26348,26349,26350,26351,26353,26357,26358,
+26360,26362,26363,26365,26369,26370,26371,26372,26373,26374,26375,26380,26382,
+26383,26385,26386,26387,26390,26392,26393,26394,26396,26398,26400,26401,26402,
+26403,26404,26405,26407,26409,26414,26416,26418,26419,26422,26423,26424,26425,
+26427,26428,26430,26431,26433,26436,26437,26439,26442,26443,26445,26450,26452,
+26453,26455,26456,26457,26458,26459,26461,26466,26467,26468,26470,26471,26475,
+26476,26478,26481,26484,26486,U,26488,26489,26490,26491,26493,26496,26498,
+26499,26501,26502,26504,26506,26508,26509,26510,26511,26513,26514,26515,26516,
+26518,26521,26523,26527,26528,26529,26532,26534,26537,26540,26542,26545,26546,
+26548,26553,26554,26555,26556,26557,26558,26559,26560,26562,26565,26566,26567,
+26568,26569,26570,26571,26572,26573,26574,26581,26582,26583,26587,26591,26593,
+26595,26596,26598,26599,26600,26602,26603,26605,26606,26610,26613,26614,26615,
+26616,26617,26618,26619,26620,26622,26625,26626,26627,26628,26630,26637,26640,
+26642,26644,26645,26648,26649,26650,26651,26652,26654,26655,26656,26658,26659,
+26660,26661,26662,26663,26664,26667,26668,26669,26670,26671,26672,26673,26676,
+26677,26678,26682,26683,26687,26695,26699,26701,26703,26706,26710,26711,26712,
+26713,26714,26715,26716,26717,26718,26719,26730,26732,26733,26734,26735,26736,
+26737,26738,26739,26741,26744,26745,26746,26747,26748,26749,26750,26751,26752,
+26754,26756,26759,26760,26761,26762,26763,26764,26765,26766,26768,26769,26770,
+26772,26773,26774,26776,26777,26778,26779,26780,26781,26782,26783,26784,26785,
+26787,26788,26789,26793,26794,26795,26796,26798,26801,26802,26804,26806,26807,
+26808,U,26809,26810,26811,26812,26813,26814,26815,26817,26819,26820,26821,
+26822,26823,26824,26826,26828,26830,26831,26832,26833,26835,26836,26838,26839,
+26841,26843,26844,26845,26846,26847,26849,26850,26852,26853,26854,26855,26856,
+26857,26858,26859,26860,26861,26863,26866,26867,26868,26870,26871,26872,26875,
+26877,26878,26879,26880,26882,26883,26884,26886,26887,26888,26889,26890,26892,
+26895,26897,26899,26900,26901,26902,26903,26904,26905,26906,26907,26908,26909,
+26910,26913,26914,26915,26917,26918,26919,26920,26921,26922,26923,26924,26926,
+26927,26929,26930,26931,26933,26934,26935,26936,26938,26939,26940,26942,26944,
+26945,26947,26948,26949,26950,26951,26952,26953,26954,26955,26956,26957,26958,
+26959,26960,26961,26962,26963,26965,26966,26968,26969,26971,26972,26975,26977,
+26978,26980,26981,26983,26984,26985,26986,26988,26989,26991,26992,26994,26995,
+26996,26997,26998,27002,27003,27005,27006,27007,27009,27011,27013,27018,27019,
+27020,27022,27023,27024,27025,27026,27027,27030,27031,27033,27034,27037,27038,
+27039,27040,27041,27042,27043,27044,27045,27046,27049,27050,27052,27054,27055,
+27056,27058,27059,27061,27062,27064,27065,27066,27068,27069,U,27070,27071,
+27072,27074,27075,27076,27077,27078,27079,27080,27081,27083,27085,27087,27089,
+27090,27091,27093,27094,27095,27096,27097,27098,27100,27101,27102,27105,27106,
+27107,27108,27109,27110,27111,27112,27113,27114,27115,27116,27118,27119,27120,
+27121,27123,27124,27125,27126,27127,27128,27129,27130,27131,27132,27134,27136,
+27137,27138,27139,27140,27141,27142,27143,27144,27145,27147,27148,27149,27150,
+27151,27152,27153,27154,27155,27156,27157,27158,27161,27162,27163,27164,27165,
+27166,27168,27170,27171,27172,27173,27174,27175,27177,27179,27180,27181,27182,
+27184,27186,27187,27188,27190,27191,27192,27193,27194,27195,27196,27199,27200,
+27201,27202,27203,27205,27206,27208,27209,27210,27211,27212,27213,27214,27215,
+27217,27218,27219,27220,27221,27222,27223,27226,27228,27229,27230,27231,27232,
+27234,27235,27236,27238,27239,27240,27241,27242,27243,27244,27245,27246,27247,
+27248,27250,27251,27252,27253,27254,27255,27256,27258,27259,27261,27262,27263,
+27265,27266,27267,27269,27270,27271,27272,27273,27274,27275,27276,27277,27279,
+27282,27283,27284,27285,27286,27288,27289,27290,27291,27292,27293,27294,27295,
+27297,27298,27299,27300,27301,27302,U,27303,27304,27306,27309,27310,27311,
+27312,27313,27314,27315,27316,27317,27318,27319,27320,27321,27322,27323,27324,
+27325,27326,27327,27328,27329,27330,27331,27332,27333,27334,27335,27336,27337,
+27338,27339,27340,27341,27342,27343,27344,27345,27346,27347,27348,27349,27350,
+27351,27352,27353,27354,27355,27356,27357,27358,27359,27360,27361,27362,27363,
+27364,27365,27366,27367,27368,27369,27370,27371,27372,27373,27374,27375,27376,
+27377,27378,27379,27380,27381,27382,27383,27384,27385,27386,27387,27388,27389,
+27390,27391,27392,27393,27394,27395,27396,27397,27398,27399,27400,27401,27402,
+27403,27404,27405,27406,27407,27408,27409,27410,27411,27412,27413,27414,27415,
+27416,27417,27418,27419,27420,27421,27422,27423,27429,27430,27432,27433,27434,
+27435,27436,27437,27438,27439,27440,27441,27443,27444,27445,27446,27448,27451,
+27452,27453,27455,27456,27457,27458,27460,27461,27464,27466,27467,27469,27470,
+27471,27472,27473,27474,27475,27476,27477,27478,27479,27480,27482,27483,27484,
+27485,27486,27487,27488,27489,27496,27497,27499,27500,27501,27502,27503,27504,
+27505,27506,27507,27508,27509,27510,27511,27512,27514,27517,27518,27519,27520,
+27525,27528,U,27532,27534,27535,27536,27537,27540,27541,27543,27544,27545,
+27548,27549,27550,27551,27552,27554,27555,27556,27557,27558,27559,27560,27561,
+27563,27564,27565,27566,27567,27568,27569,27570,27574,27576,27577,27578,27579,
+27580,27581,27582,27584,27587,27588,27590,27591,27592,27593,27594,27596,27598,
+27600,27601,27608,27610,27612,27613,27614,27615,27616,27618,27619,27620,27621,
+27622,27623,27624,27625,27628,27629,27630,27632,27633,27634,27636,27638,27639,
+27640,27642,27643,27644,27646,27647,27648,27649,27650,27651,27652,27656,27657,
+27658,27659,27660,27662,27666,27671,27676,27677,27678,27680,27683,27685,27691,
+27692,27693,27697,27699,27702,27703,27705,27706,27707,27708,27710,27711,27715,
+27716,27717,27720,27723,27724,27725,27726,27727,27729,27730,27731,27734,27736,
+27737,27738,27746,27747,27749,27750,27751,27755,27756,27757,27758,27759,27761,
+27763,27765,27767,27768,27770,27771,27772,27775,27776,27780,27783,27786,27787,
+27789,27790,27793,27794,27797,27798,27799,27800,27802,27804,27805,27806,27808,
+27810,27816,27820,27823,27824,27828,27829,27830,27831,27834,27840,27841,27842,
+27843,27846,27847,27848,27851,27853,27854,27855,27857,27858,27864,U,27865,
+27866,27868,27869,27871,27876,27878,27879,27881,27884,27885,27890,27892,27897,
+27903,27904,27906,27907,27909,27910,27912,27913,27914,27917,27919,27920,27921,
+27923,27924,27925,27926,27928,27932,27933,27935,27936,27937,27938,27939,27940,
+27942,27944,27945,27948,27949,27951,27952,27956,27958,27959,27960,27962,27967,
+27968,27970,27972,27977,27980,27984,27989,27990,27991,27992,27995,27997,27999,
+28001,28002,28004,28005,28007,28008,28011,28012,28013,28016,28017,28018,28019,
+28021,28022,28025,28026,28027,28029,28030,28031,28032,28033,28035,28036,28038,
+28039,28042,28043,28045,28047,28048,28050,28054,28055,28056,28057,28058,28060,
+28066,28069,28076,28077,28080,28081,28083,28084,28086,28087,28089,28090,28091,
+28092,28093,28094,28097,28098,28099,28104,28105,28106,28109,28110,28111,28112,
+28114,28115,28116,28117,28119,28122,28123,28124,28127,28130,28131,28133,28135,
+28136,28137,28138,28141,28143,28144,28146,28148,28149,28150,28152,28154,28157,
+28158,28159,28160,28161,28162,28163,28164,28166,28167,28168,28169,28171,28175,
+28178,28179,28181,28184,28185,28187,28188,28190,28191,28194,28198,28199,28200,
+28202,28204,28206,28208,28209,28211,28213,U,28214,28215,28217,28219,28220,
+28221,28222,28223,28224,28225,28226,28229,28230,28231,28232,28233,28234,28235,
+28236,28239,28240,28241,28242,28245,28247,28249,28250,28252,28253,28254,28256,
+28257,28258,28259,28260,28261,28262,28263,28264,28265,28266,28268,28269,28271,
+28272,28273,28274,28275,28276,28277,28278,28279,28280,28281,28282,28283,28284,
+28285,28288,28289,28290,28292,28295,28296,28298,28299,28300,28301,28302,28305,
+28306,28307,28308,28309,28310,28311,28313,28314,28315,28317,28318,28320,28321,
+28323,28324,28326,28328,28329,28331,28332,28333,28334,28336,28339,28341,28344,
+28345,28348,28350,28351,28352,28355,28356,28357,28358,28360,28361,28362,28364,
+28365,28366,28368,28370,28374,28376,28377,28379,28380,28381,28387,28391,28394,
+28395,28396,28397,28398,28399,28400,28401,28402,28403,28405,28406,28407,28408,
+28410,28411,28412,28413,28414,28415,28416,28417,28419,28420,28421,28423,28424,
+28426,28427,28428,28429,28430,28432,28433,28434,28438,28439,28440,28441,28442,
+28443,28444,28445,28446,28447,28449,28450,28451,28453,28454,28455,28456,28460,
+28462,28464,28466,28468,28469,28471,28472,28473,28474,28475,28476,28477,28479,
+28480,28481,28482,U,28483,28484,28485,28488,28489,28490,28492,28494,28495,
+28496,28497,28498,28499,28500,28501,28502,28503,28505,28506,28507,28509,28511,
+28512,28513,28515,28516,28517,28519,28520,28521,28522,28523,28524,28527,28528,
+28529,28531,28533,28534,28535,28537,28539,28541,28542,28543,28544,28545,28546,
+28547,28549,28550,28551,28554,28555,28559,28560,28561,28562,28563,28564,28565,
+28566,28567,28568,28569,28570,28571,28573,28574,28575,28576,28578,28579,28580,
+28581,28582,28584,28585,28586,28587,28588,28589,28590,28591,28592,28593,28594,
+28596,28597,28599,28600,28602,28603,28604,28605,28606,28607,28609,28611,28612,
+28613,28614,28615,28616,28618,28619,28620,28621,28622,28623,28624,28627,28628,
+28629,28630,28631,28632,28633,28634,28635,28636,28637,28639,28642,28643,28644,
+28645,28646,28647,28648,28649,28650,28651,28652,28653,28656,28657,28658,28659,
+28660,28661,28662,28663,28664,28665,28666,28667,28668,28669,28670,28671,28672,
+28673,28674,28675,28676,28677,28678,28679,28680,28681,28682,28683,28684,28685,
+28686,28687,28688,28690,28691,28692,28693,28694,28695,28696,28697,28700,28701,
+28702,28703,28704,28705,28706,28708,28709,28710,28711,28712,28713,28714,U,
+28715,28716,28717,28718,28719,28720,28721,28722,28723,28724,28726,28727,28728,
+28730,28731,28732,28733,28734,28735,28736,28737,28738,28739,28740,28741,28742,
+28743,28744,28745,28746,28747,28749,28750,28752,28753,28754,28755,28756,28757,
+28758,28759,28760,28761,28762,28763,28764,28765,28767,28768,28769,28770,28771,
+28772,28773,28774,28775,28776,28777,28778,28782,28785,28786,28787,28788,28791,
+28793,28794,28795,28797,28801,28802,28803,28804,28806,28807,28808,28811,28812,
+28813,28815,28816,28817,28819,28823,28824,28826,28827,28830,28831,28832,28833,
+28834,28835,28836,28837,28838,28839,28840,28841,28842,28848,28850,28852,28853,
+28854,28858,28862,28863,28868,28869,28870,28871,28873,28875,28876,28877,28878,
+28879,28880,28881,28882,28883,28884,28885,28886,28887,28890,28892,28893,28894,
+28896,28897,28898,28899,28901,28906,28910,28912,28913,28914,28915,28916,28917,
+28918,28920,28922,28923,28924,28926,28927,28928,28929,28930,28931,28932,28933,
+28934,28935,28936,28939,28940,28941,28942,28943,28945,28946,28948,28951,28955,
+28956,28957,28958,28959,28960,28961,28962,28963,28964,28965,28967,28968,28969,
+28970,28971,28972,28973,28974,28978,28979,28980,U,28981,28983,28984,28985,
+28986,28987,28988,28989,28990,28991,28992,28993,28994,28995,28996,28998,28999,
+29000,29001,29003,29005,29007,29008,29009,29010,29011,29012,29013,29014,29015,
+29016,29017,29018,29019,29021,29023,29024,29025,29026,29027,29029,29033,29034,
+29035,29036,29037,29039,29040,29041,29044,29045,29046,29047,29049,29051,29052,
+29054,29055,29056,29057,29058,29059,29061,29062,29063,29064,29065,29067,29068,
+29069,29070,29072,29073,29074,29075,29077,29078,29079,29082,29083,29084,29085,
+29086,29089,29090,29091,29092,29093,29094,29095,29097,29098,29099,29101,29102,
+29103,29104,29105,29106,29108,29110,29111,29112,29114,29115,29116,29117,29118,
+29119,29120,29121,29122,29124,29125,29126,29127,29128,29129,29130,29131,29132,
+29133,29135,29136,29137,29138,29139,29142,29143,29144,29145,29146,29147,29148,
+29149,29150,29151,29153,29154,29155,29156,29158,29160,29161,29162,29163,29164,
+29165,29167,29168,29169,29170,29171,29172,29173,29174,29175,29176,29178,29179,
+29180,29181,29182,29183,29184,29185,29186,29187,29188,29189,29191,29192,29193,
+29194,29195,29196,29197,29198,29199,29200,29201,29202,29203,29204,29205,29206,
+29207,29208,29209,29210,U,29211,29212,29214,29215,29216,29217,29218,29219,
+29220,29221,29222,29223,29225,29227,29229,29230,29231,29234,29235,29236,29242,
+29244,29246,29248,29249,29250,29251,29252,29253,29254,29257,29258,29259,29262,
+29263,29264,29265,29267,29268,29269,29271,29272,29274,29276,29278,29280,29283,
+29284,29285,29288,29290,29291,29292,29293,29296,29297,29299,29300,29302,29303,
+29304,29307,29308,29309,29314,29315,29317,29318,29319,29320,29321,29324,29326,
+29328,29329,29331,29332,29333,29334,29335,29336,29337,29338,29339,29340,29341,
+29342,29344,29345,29346,29347,29348,29349,29350,29351,29352,29353,29354,29355,
+29358,29361,29362,29363,29365,29370,29371,29372,29373,29374,29375,29376,29381,
+29382,29383,29385,29386,29387,29388,29391,29393,29395,29396,29397,29398,29400,
+29402,29403,183,U,U,U,U,U,8212,8560,8561,8562,8563,8564,8565,8566,8567,8568,
+8569,65077,65078,65081,65082,65087,65088,65085,65086,65089,65090,65091,65092,
+U,U,65083,65084,65079,65080,65073,U,65075,65076,714,715,729,8211,8213,8229,
+8245,8453,8457,8598,8599,8600,8601,8725,8735,8739,8786,8806,8807,8895,9552,
+9553,9554,9555,9556,9557,9558,9559,9560,9561,9562,9563,9564,9565,9566,9567,
+9568,9569,9570,9571,9572,9573,9574,9575,9576,9577,9578,9579,9580,9581,9582,
+9583,9584,9585,9586,9587,9601,9602,9603,9604,9605,9606,9607,U,9608,9609,9610,
+9611,9612,9613,9614,9615,9619,9620,9621,9660,9661,9698,9699,9700,9701,9737,
+8853,12306,12317,12318,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,593,U,324,328,U,609,12321,12322,12323,12324,12325,12326,
+12327,12328,12329,12963,13198,13199,13212,13213,13214,13217,13252,13262,13265,
+13266,13269,65072,65506,65508,U,8481,12849,U,8208,U,U,U,12540,12443,12444,
+12541,12542,12294,12445,12446,65097,65098,65099,65100,65101,65102,65103,65104,
+65105,65106,65108,65109,65110,65111,65113,65114,65115,65116,65117,65118,65119,
+65120,65121,U,65122,65123,65124,65125,65126,65128,65129,65130,65131,U,U,U,U,U,
+U,U,U,U,U,U,U,U,12295,29404,29405,29407,29410,29411,29412,29413,29414,29415,
+29418,29419,29429,29430,29433,29437,29438,29439,29440,29442,29444,29445,29446,
+29447,29448,29449,29451,29452,29453,29455,29456,29457,29458,29460,29464,29465,
+29466,29471,29472,29475,29476,29478,29479,29480,29485,29487,29488,29490,29491,
+29493,29494,29498,29499,29500,29501,29504,29505,29506,29507,29508,29509,29510,
+29511,29512,U,29513,29514,29515,29516,29518,29519,29521,29523,29524,29525,
+29526,29528,29529,29530,29531,29532,29533,29534,29535,29537,29538,29539,29540,
+29541,29542,29543,29544,29545,29546,29547,29550,29552,29553,29554,29555,29556,
+29557,29558,29559,29560,29561,29562,29563,29564,29565,29567,29568,29569,29570,
+29571,29573,29574,29576,29578,29580,29581,29583,29584,29586,29587,29588,29589,
+29591,29592,29593,29594,29596,29597,29598,29600,29601,29603,29604,29605,29606,
+29607,29608,29610,29612,29613,29617,29620,29621,29622,29624,29625,29628,29629,
+29630,29631,29633,29635,29636,29637,29638,29639,U,29643,29644,29646,29650,
+29651,29652,29653,29654,29655,29656,29658,29659,29660,29661,29663,29665,29666,
+29667,29668,29670,29672,29674,29675,29676,29678,29679,29680,29681,29683,29684,
+29685,29686,29687,29688,29689,29690,29691,29692,29693,29694,29695,29696,29697,
+29698,29700,29703,29704,29707,29708,29709,29710,29713,29714,29715,29716,29717,
+29718,29719,29720,29721,29724,29725,29726,29727,29728,29729,29731,29732,29735,
+29737,29739,29741,29743,29745,29746,29751,29752,29753,29754,29755,29757,29758,
+29759,29760,29762,29763,29764,29765,29766,29767,29768,29769,29770,29771,29772,
+29773,U,29774,29775,29776,29777,29778,29779,29780,29782,29784,29789,29792,
+29793,29794,29795,29796,29797,29798,29799,29800,29801,29802,29803,29804,29806,
+29807,29809,29810,29811,29812,29813,29816,29817,29818,29819,29820,29821,29823,
+29826,29828,29829,29830,29832,29833,29834,29836,29837,29839,29841,29842,29843,
+29844,29845,29846,29847,29848,29849,29850,29851,29853,29855,29856,29857,29858,
+29859,29860,29861,29862,29866,29867,29868,29869,29870,29871,29872,29873,29874,
+29875,29876,29877,29878,29879,29880,29881,29883,29884,29885,29886,29887,29888,
+29889,29890,29891,29892,29893,29894,29895,U,29896,29897,29898,29899,29900,
+29901,29902,29903,29904,29905,29907,29908,29909,29910,29911,29912,29913,29914,
+29915,29917,29919,29921,29925,29927,29928,29929,29930,29931,29932,29933,29936,
+29937,29938,29939,29941,29944,29945,29946,29947,29948,29949,29950,29952,29953,
+29954,29955,29957,29958,29959,29960,29961,29962,29963,29964,29966,29968,29970,
+29972,29973,29974,29975,29979,29981,29982,29984,29985,29986,29987,29988,29990,
+29991,29994,29998,30004,30006,30009,30012,30013,30015,30017,30018,30019,30020,
+30022,30023,30025,30026,30029,30032,30033,30034,30035,30037,30038,30039,30040,
+U,30045,30046,30047,30048,30049,30050,30051,30052,30055,30056,30057,30059,
+30060,30061,30062,30063,30064,30065,30067,30069,30070,30071,30074,30075,30076,
+30077,30078,30080,30081,30082,30084,30085,30087,30088,30089,30090,30092,30093,
+30094,30096,30099,30101,30104,30107,30108,30110,30114,30118,30119,30120,30121,
+30122,30125,30134,30135,30138,30139,30143,30144,30145,30150,30155,30156,30158,
+30159,30160,30161,30163,30167,30169,30170,30172,30173,30175,30176,30177,30181,
+30185,30188,30189,30190,30191,30194,30195,30197,30198,30199,30200,30202,30203,
+30205,30206,30210,30212,30214,30215,U,30216,30217,30219,30221,30222,30223,
+30225,30226,30227,30228,30230,30234,30236,30237,30238,30241,30243,30247,30248,
+30252,30254,30255,30257,30258,30262,30263,30265,30266,30267,30269,30273,30274,
+30276,30277,30278,30279,30280,30281,30282,30283,30286,30287,30288,30289,30290,
+30291,30293,30295,30296,30297,30298,30299,30301,30303,30304,30305,30306,30308,
+30309,30310,30311,30312,30313,30314,30316,30317,30318,30320,30321,30322,30323,
+30324,30325,30326,30327,30329,30330,30332,30335,30336,30337,30339,30341,30345,
+30346,30348,30349,30351,30352,30354,30356,30357,30359,30360,30362,30363,U,
+30364,30365,30366,30367,30368,30369,30370,30371,30373,30374,30375,30376,30377,
+30378,30379,30380,30381,30383,30384,30387,30389,30390,30391,30392,30393,30394,
+30395,30396,30397,30398,30400,30401,30403,30404,30407,30409,30411,30412,30419,
+30421,30425,30426,30428,30429,30430,30432,30433,30434,30435,30436,30438,30439,
+30440,30441,30442,30443,30444,30445,30448,30451,30453,30454,30455,30458,30459,
+30461,30463,30464,30466,30467,30469,30470,30474,30476,30478,30479,30480,30481,
+30482,30483,30484,30485,30486,30487,30488,30491,30492,30493,30494,30497,30499,
+30500,30501,30503,30506,30507,U,30508,30510,30512,30513,30514,30515,30516,
+30521,30523,30525,30526,30527,30530,30532,30533,30534,30536,30537,30538,30539,
+30540,30541,30542,30543,30546,30547,30548,30549,30550,30551,30552,30553,30556,
+30557,30558,30559,30560,30564,30567,30569,30570,30573,30574,30575,30576,30577,
+30578,30579,30580,30581,30582,30583,30584,30586,30587,30588,30593,30594,30595,
+30598,30599,30600,30601,30602,30603,30607,30608,30611,30612,30613,30614,30615,
+30616,30617,30618,30619,30620,30621,30622,30625,30627,30628,30630,30632,30635,
+30637,30638,30639,30641,30642,30644,30646,30647,30648,30649,30650,U,30652,
+30654,30656,30657,30658,30659,30660,30661,30662,30663,30664,30665,30666,30667,
+30668,30670,30671,30672,30673,30674,30675,30676,30677,30678,30680,30681,30682,
+30685,30686,30687,30688,30689,30692,30694,30696,30698,30703,30704,30705,30706,
+30708,30709,30711,30713,30714,30715,30716,30723,30724,30725,30726,30727,30728,
+30730,30731,30734,30735,30736,30739,30741,30745,30747,30750,30752,30753,30754,
+30756,30760,30762,30763,30766,30767,30769,30770,30771,30773,30774,30781,30783,
+30785,30786,30787,30788,30790,30792,30793,30794,30795,30797,30799,30801,30803,
+30804,30808,30809,30810,U,30811,30812,30814,30815,30816,30817,30818,30819,
+30820,30821,30822,30823,30824,30825,30831,30832,30833,30834,30835,30836,30837,
+30838,30840,30841,30842,30843,30845,30846,30847,30848,30849,30850,30851,30852,
+30853,30854,30856,30858,30859,30863,30864,30866,30868,30869,30870,30873,30877,
+30878,30880,30882,30884,30886,30888,30889,30890,30891,30892,30893,30894,30895,
+30901,30902,30903,30904,30906,30907,30908,30909,30911,30912,30914,30915,30916,
+30918,30919,30920,30924,30925,30926,30927,30929,30930,30931,30934,30935,30936,
+30938,30939,30940,30941,30942,30943,30944,30945,30946,30947,U,30948,30949,
+30950,30951,30953,30954,30955,30957,30958,30959,30960,30961,30963,30965,30966,
+30968,30969,30971,30972,30973,30974,30975,30976,30978,30979,30980,30982,30983,
+30984,30985,30986,30987,30988,30989,30990,30991,30992,30993,30994,30996,30997,
+30998,30999,31000,31001,31002,31003,31004,31005,31007,31008,31009,31010,31011,
+31013,31014,31015,31016,31017,31018,31019,31020,31021,31022,31023,31024,31025,
+31026,31027,31029,31030,31031,31032,31033,31037,31039,31042,31043,31044,31045,
+31047,31050,31051,31052,31053,31054,31055,31056,31057,31058,31060,31061,31064,
+31065,31073,31075,U,31076,31078,31081,31082,31083,31084,31086,31088,31089,
+31090,31091,31092,31093,31094,31097,31099,31100,31101,31102,31103,31106,31107,
+31110,31111,31112,31113,31115,31116,31117,31118,31120,31121,31122,31123,31124,
+31125,31126,31127,31128,31129,31131,31132,31133,31134,31135,31136,31137,31138,
+31139,31140,31141,31142,31144,31145,31146,31147,31148,31149,31150,31151,31152,
+31153,31154,31156,31157,31158,31159,31160,31164,31167,31170,31172,31173,31175,
+31176,31178,31180,31182,31183,31184,31187,31188,31190,31191,31193,31194,31195,
+31196,31197,31198,31200,31201,31202,31205,31208,31210,U,31212,31214,31217,
+31218,31219,31220,31221,31222,31223,31225,31226,31228,31230,31231,31233,31236,
+31237,31239,31240,31241,31242,31244,31247,31248,31249,31250,31251,31253,31254,
+31256,31257,31259,31260,31261,31263,31265,31266,31268,31269,31270,31271,31272,
+31273,31274,31275,31276,31277,31278,31279,31280,31281,31282,31284,31285,31286,
+31288,31290,31294,31296,31297,31298,31299,31300,31301,31303,31304,31305,31306,
+31307,31308,31309,31310,31311,31312,31314,31315,31316,31317,31318,31320,31321,
+31322,31323,31324,31325,31326,31327,31328,31329,31330,31331,31332,31333,31334,
+31335,31336,U,31337,31338,31339,31340,31341,31342,31343,31345,31346,31347,
+31349,31355,31356,31357,31358,31362,31365,31367,31369,31370,31371,31372,31374,
+31375,31376,31379,31380,31385,31386,31387,31390,31393,31394,31395,31396,31399,
+31401,31402,31403,31406,31407,31408,31409,31410,31412,31413,31414,31415,31416,
+31417,31418,31419,31420,31421,31422,31424,31425,31426,31427,31428,31429,31430,
+31431,31432,31433,31434,31436,31437,31438,31439,31440,31441,31442,31443,31444,
+31445,31447,31448,31450,31451,31452,31453,31457,31458,31460,31463,31464,31465,
+31466,31467,31468,31470,31472,31473,31474,31475,U,31476,31477,31478,31479,
+31480,31483,31484,31486,31488,31489,31490,31493,31495,31497,31500,31501,31502,
+31504,31506,31507,31510,31511,31512,31514,31516,31517,31519,31521,31522,31523,
+31527,31529,31533,31535,31536,31538,31540,31541,31542,31543,31545,31547,31549,
+31551,31552,31553,31554,31555,31556,31558,31560,31562,31565,31566,31571,31573,
+31575,31577,31580,31582,31583,31585,31587,31588,31589,31590,31591,31592,31593,
+31594,31595,31596,31597,31599,31600,31603,31604,31606,31608,31610,31612,31613,
+31615,31617,31618,31619,31620,31622,31623,31624,31625,31626,31627,31628,31630,
+31631,U,31633,31634,31635,31638,31640,31641,31642,31643,31646,31647,31648,
+31651,31652,31653,31662,31663,31664,31666,31667,31669,31670,31671,31673,31674,
+31675,31676,31677,31678,31679,31680,31682,31683,31684,31685,31688,31689,31690,
+31691,31693,31694,31695,31696,31698,31700,31701,31702,31703,31704,31707,31708,
+31710,31711,31712,31714,31715,31716,31719,31720,31721,31723,31724,31725,31727,
+31728,31730,31731,31732,31733,31734,31736,31737,31738,31739,31741,31743,31744,
+31745,31746,31747,31748,31749,31750,31752,31753,31754,31757,31758,31760,31761,
+31762,31763,31764,31765,31767,31768,31769,U,31770,31771,31772,31773,31774,
+31776,31777,31778,31779,31780,31781,31784,31785,31787,31788,31789,31790,31791,
+31792,31793,31794,31795,31796,31797,31798,31799,31801,31802,31803,31804,31805,
+31806,31810,31811,31812,31813,31814,31815,31816,31817,31818,31819,31820,31822,
+31823,31824,31825,31826,31827,31828,31829,31830,31831,31832,31833,31834,31835,
+31836,31837,31838,31839,31840,31841,31842,31843,31844,31845,31846,31847,31848,
+31849,31850,31851,31852,31853,31854,31855,31856,31857,31858,31861,31862,31863,
+31864,31865,31866,31870,31871,31872,31873,31874,31875,31876,31877,31878,31879,
+U,31880,31882,31883,31884,31885,31886,31887,31888,31891,31892,31894,31897,
+31898,31899,31904,31905,31907,31910,31911,31912,31913,31915,31916,31917,31919,
+31920,31924,31925,31926,31927,31928,31930,31931,31935,31936,31938,31939,31940,
+31942,31945,31947,31950,31951,31952,31953,31954,31955,31956,31960,31962,31963,
+31965,31966,31969,31970,31971,31972,31973,31974,31975,31977,31978,31979,31980,
+31981,31982,31984,31985,31986,31987,31988,31989,31990,31991,31993,31994,31996,
+31997,31998,31999,32000,32001,32002,32003,32004,32005,32006,32007,32008,32009,
+32011,32012,32013,32014,32015,32016,U,32017,32018,32019,32020,32021,32022,
+32023,32024,32025,32026,32027,32028,32029,32030,32031,32033,32035,32036,32037,
+32038,32040,32041,32042,32044,32045,32046,32048,32049,32050,32051,32052,32053,
+32054,32055,32056,32057,32058,32059,32060,32061,32062,32063,32064,32065,32066,
+32067,32068,32069,32070,32071,32072,32073,32074,32075,32076,32077,32078,32079,
+32080,32081,32082,32083,32084,32085,32086,32087,32088,32089,32090,32091,32092,
+32093,32094,32095,32096,32097,32098,32099,32100,32101,32102,32103,32104,32105,
+32106,32107,32108,32109,32111,32112,32113,32114,32115,32116,32117,32118,U,
+32120,32121,32122,32123,32124,32125,32126,32127,32128,32129,32130,32131,32132,
+32133,32134,32135,32136,32137,32138,32139,32140,32141,32142,32143,32144,32145,
+32146,32147,32148,32149,32150,32151,32152,32153,32154,32155,32156,32157,32158,
+32159,32160,32161,32162,32163,32164,32165,32167,32168,32169,32170,32171,32172,
+32173,32175,32176,32177,32178,32179,32180,32181,32182,32183,32184,32185,32186,
+32187,32188,32189,32190,32191,32192,32193,32194,32195,32196,32197,32198,32199,
+32200,32201,32202,32203,32204,32205,32206,32207,32208,32209,32210,32211,32212,
+32213,32214,32215,32216,32217,U,32218,32219,32220,32221,32222,32223,32224,
+32225,32226,32227,32228,32229,32230,32231,32232,32233,32234,32235,32236,32237,
+32238,32239,32240,32241,32242,32243,32244,32245,32246,32247,32248,32249,32250,
+32251,32252,32253,32254,32255,32256,32257,32258,32259,32260,32261,32262,32263,
+32264,32265,32266,32267,32268,32269,32270,32271,32272,32273,32274,32275,32276,
+32277,32278,32279,32280,32281,32282,32283,32284,32285,32286,32287,32288,32289,
+32290,32291,32292,32293,32294,32295,32296,32297,32298,32299,32300,32301,32302,
+32303,32304,32305,32306,32307,32308,32309,32310,32311,32312,32313,U,32314,
+32316,32317,32318,32319,32320,32322,32323,32324,32325,32326,32328,32329,32330,
+32331,32332,32333,32334,32335,32336,32337,32338,32339,32340,32341,32342,32343,
+32344,32345,32346,32347,32348,32349,32350,32351,32352,32353,32354,32355,32356,
+32357,32358,32359,32360,32361,32362,32363,32364,32365,32366,32367,32368,32369,
+32370,32371,32372,32373,32374,32375,32376,32377,32378,32379,32380,32381,32382,
+32383,32384,32385,32387,32388,32389,32390,32391,32392,32393,32394,32395,32396,
+32397,32398,32399,32400,32401,32402,32403,32404,32405,32406,32407,32408,32409,
+32410,32412,32413,32414,U,32430,32436,32443,32444,32470,32484,32492,32505,
+32522,32528,32542,32567,32569,32571,32572,32573,32574,32575,32576,32577,32579,
+32582,32583,32584,32585,32586,32587,32588,32589,32590,32591,32594,32595,32598,
+32601,32603,32604,32605,32606,32608,32611,32612,32613,32614,32615,32619,32620,
+32621,32623,32624,32627,32629,32630,32631,32632,32634,32635,32636,32637,32639,
+32640,32642,32643,32644,32645,32646,32647,32648,32649,32651,32653,32655,32656,
+32657,32658,32659,32661,32662,32663,32664,32665,32667,32668,32672,32674,32675,
+32677,32678,32680,32681,32682,32683,32684,32685,32686,32689,U,32691,32692,
+32693,32694,32695,32698,32699,32702,32704,32706,32707,32708,32710,32711,32712,
+32713,32715,32717,32719,32720,32721,32722,32723,32726,32727,32729,32730,32731,
+32732,32733,32734,32738,32739,32740,32743,32744,32746,32747,32748,32749,32751,
+32754,32756,32757,32758,32759,32760,32761,32762,32765,32766,32767,32770,32775,
+32776,32777,32778,32782,32783,32785,32787,32794,32795,32797,32798,32799,32801,
+32803,32804,32811,32812,32813,32814,32815,32816,32818,32820,32825,32826,32828,
+32830,32832,32833,32836,32837,32839,32840,32841,32846,32847,32848,32849,32851,
+32853,32854,32855,U,32857,32859,32860,32861,32862,32863,32864,32865,32866,
+32867,32868,32869,32870,32871,32872,32875,32876,32877,32878,32879,32880,32882,
+32883,32884,32885,32886,32887,32888,32889,32890,32891,32892,32893,32894,32897,
+32898,32901,32904,32906,32909,32910,32911,32912,32913,32914,32916,32917,32919,
+32921,32926,32931,32934,32935,32936,32940,32944,32947,32949,32950,32952,32953,
+32955,32965,32967,32968,32969,32970,32971,32975,32976,32977,32978,32979,32980,
+32981,32984,32991,32992,32994,32995,32998,33006,33013,33015,33017,33019,33022,
+33023,33024,33025,33027,33028,33029,33031,33032,33035,U,33036,33045,33047,
+33049,33051,33052,33053,33055,33056,33057,33058,33059,33060,33061,33062,33063,
+33064,33065,33066,33067,33069,33070,33072,33075,33076,33077,33079,33081,33082,
+33083,33084,33085,33087,33088,33089,33090,33091,33092,33093,33095,33097,33101,
+33102,33103,33106,33110,33111,33112,33115,33116,33117,33118,33119,33121,33122,
+33123,33124,33126,33128,33130,33131,33132,33135,33138,33139,33141,33142,33143,
+33144,33153,33155,33156,33157,33158,33159,33161,33163,33164,33165,33166,33168,
+33170,33171,33172,33173,33174,33175,33177,33178,33182,33183,33184,33185,33186,
+33188,33189,U,33191,33193,33195,33196,33197,33198,33199,33200,33201,33202,
+33204,33205,33206,33207,33208,33209,33212,33213,33214,33215,33220,33221,33223,
+33224,33225,33227,33229,33230,33231,33232,33233,33234,33235,33236,33237,33238,
+33239,33240,33241,33242,33243,33244,33245,33246,33247,33248,33249,33250,33252,
+33253,33254,33256,33257,33259,33262,33263,33264,33265,33266,33269,33270,33271,
+33272,33273,33274,33277,33279,33283,33287,33288,33289,33290,33291,33294,33295,
+33297,33299,33301,33302,33303,33304,33305,33306,33309,33312,33316,33317,33318,
+33319,33321,33326,33330,33338,33340,33341,33343,U,33344,33345,33346,33347,
+33349,33350,33352,33354,33356,33357,33358,33360,33361,33362,33363,33364,33365,
+33366,33367,33369,33371,33372,33373,33374,33376,33377,33378,33379,33380,33381,
+33382,33383,33385,33386,33387,33388,33389,33393,33397,33398,33399,33400,33403,
+33404,33408,33409,33411,33413,33414,33415,33417,33420,33424,33427,33428,33429,
+33430,33434,33435,33438,33440,33442,33443,33447,33458,33461,33462,33466,33467,
+33468,33471,33472,33474,33475,33477,33478,33481,33488,33494,33497,33498,33501,
+33506,33511,33512,33513,33514,33516,33517,33518,33520,33522,33523,33525,33526,
+33528,U,33530,33532,33533,33534,33535,33536,33546,33547,33549,33552,33554,
+33555,33558,33560,33561,33565,33566,33567,33568,33569,33570,33571,33572,33573,
+33574,33577,33578,33582,33584,33586,33591,33595,33597,33598,33599,33601,33602,
+33604,33605,33608,33610,33611,33612,33613,33614,33619,33621,33622,33623,33624,
+33625,33629,33634,33648,33649,33650,33651,33652,33653,33654,33657,33658,33662,
+33663,33664,33665,33666,33667,33668,33671,33672,33674,33675,33676,33677,33679,
+33680,33681,33684,33685,33686,33687,33689,33690,33693,33695,33697,33698,33699,
+33700,33701,33702,33703,33708,33709,33710,U,33711,33717,33723,33726,33727,
+33730,33731,33732,33734,33736,33737,33739,33741,33742,33744,33745,33746,33747,
+33749,33751,33753,33754,33755,33758,33762,33763,33764,33766,33767,33768,33771,
+33772,33773,33774,33775,33779,33780,33781,33782,33783,33786,33787,33788,33790,
+33791,33792,33794,33797,33799,33800,33801,33802,33808,33810,33811,33812,33813,
+33814,33815,33817,33818,33819,33822,33823,33824,33825,33826,33827,33833,33834,
+33835,33836,33837,33838,33839,33840,33842,33843,33844,33845,33846,33847,33849,
+33850,33851,33854,33855,33856,33857,33858,33859,33860,33861,33863,33864,33865,
+U,33866,33867,33868,33869,33870,33871,33872,33874,33875,33876,33877,33878,
+33880,33885,33886,33887,33888,33890,33892,33893,33894,33895,33896,33898,33902,
+33903,33904,33906,33908,33911,33913,33915,33916,33917,33918,33919,33920,33921,
+33923,33924,33925,33926,33930,33933,33935,33936,33937,33938,33939,33940,33941,
+33942,33944,33946,33947,33949,33950,33951,33952,33954,33955,33956,33957,33958,
+33959,33960,33961,33962,33963,33964,33965,33966,33968,33969,33971,33973,33974,
+33975,33979,33980,33982,33984,33986,33987,33989,33990,33991,33992,33995,33996,
+33998,33999,34002,34004,34005,34007,U,34008,34009,34010,34011,34012,34014,
+34017,34018,34020,34023,34024,34025,34026,34027,34029,34030,34031,34033,34034,
+34035,34036,34037,34038,34039,34040,34041,34042,34043,34045,34046,34048,34049,
+34050,34051,34052,34053,34054,34055,34056,34057,34058,34059,34061,34062,34063,
+34064,34066,34068,34069,34070,34072,34073,34075,34076,34077,34078,34080,34082,
+34083,34084,34085,34086,34087,34088,34089,34090,34093,34094,34095,34096,34097,
+34098,34099,34100,34101,34102,34110,34111,34112,34113,34114,34116,34117,34118,
+34119,34123,34124,34125,34126,34127,34128,34129,34130,34131,34132,34133,U,
+34135,34136,34138,34139,34140,34141,34143,34144,34145,34146,34147,34149,34150,
+34151,34153,34154,34155,34156,34157,34158,34159,34160,34161,34163,34165,34166,
+34167,34168,34172,34173,34175,34176,34177,34178,34179,34182,34184,34185,34186,
+34187,34188,34189,34190,34192,34193,34194,34195,34196,34197,34198,34199,34200,
+34201,34202,34205,34206,34207,34208,34209,34210,34211,34213,34214,34215,34217,
+34219,34220,34221,34225,34226,34227,34228,34229,34230,34232,34234,34235,34236,
+34237,34238,34239,34240,34242,34243,34244,34245,34246,34247,34248,34250,34251,
+34252,34253,34254,34257,34258,U,34260,34262,34263,34264,34265,34266,34267,
+34269,34270,34271,34272,34273,34274,34275,34277,34278,34279,34280,34282,34283,
+34284,34285,34286,34287,34288,34289,34290,34291,34292,34293,34294,34295,34296,
+34297,34298,34300,34301,34302,34304,34305,34306,34307,34308,34310,34311,34312,
+34313,34314,34315,34316,34317,34318,34319,34320,34322,34323,34324,34325,34327,
+34328,34329,34330,34331,34332,34333,34334,34335,34336,34337,34338,34339,34340,
+34341,34342,34344,34346,34347,34348,34349,34350,34351,34352,34353,34354,34355,
+34356,34357,34358,34359,34361,34362,34363,34365,34366,34367,34368,U,34369,
+34370,34371,34372,34373,34374,34375,34376,34377,34378,34379,34380,34386,34387,
+34389,34390,34391,34392,34393,34395,34396,34397,34399,34400,34401,34403,34404,
+34405,34406,34407,34408,34409,34410,34413,34415,34416,34418,34419,34420,34421,
+34422,34423,34424,34435,34436,34437,34438,34439,34440,34441,34446,34447,34448,
+34449,34450,34452,34454,34455,34456,34457,34458,34459,34462,34463,34464,34465,
+34466,34469,34470,34475,34477,34478,34482,34483,34487,34488,34489,34491,34492,
+34493,34494,34495,34497,34498,34499,34501,34504,34508,34509,34514,34515,34517,
+34518,34519,34522,34524,U,34525,34528,34529,34530,34531,34533,34534,34535,
+34536,34538,34539,34540,34543,34549,34550,34551,34554,34555,34556,34557,34559,
+34561,34564,34565,34566,34571,34572,34574,34575,34576,34577,34580,34582,34585,
+34587,34589,34591,34592,34596,34598,34599,34600,34602,34603,34604,34605,34607,
+34608,34610,34611,34613,34614,34616,34617,34618,34620,34621,34624,34625,34626,
+34627,34628,34629,34630,34634,34635,34637,34639,34640,34641,34642,34644,34645,
+34646,34648,34650,34651,34652,34653,34654,34655,34657,34658,34662,34663,34664,
+34665,34666,34667,34668,34669,34671,34673,34674,34675,34677,U,34679,34680,
+34681,34682,34687,34688,34689,34692,34694,34695,34697,34698,34700,34702,34703,
+34704,34705,34706,34708,34709,34710,34712,34713,34714,34715,34716,34717,34718,
+34720,34721,34722,34723,34724,34725,34726,34727,34729,34730,34734,34736,34737,
+34738,34740,34742,34743,34744,34745,34747,34748,34750,34751,34753,34754,34755,
+34756,34757,34759,34760,34761,34764,34765,34766,34767,34768,34772,34773,34774,
+34775,34776,34777,34778,34780,34781,34782,34783,34785,34786,34787,34788,34790,
+34791,34792,34793,34795,34796,34797,34799,34800,34801,34802,34803,34804,34805,
+34806,34807,34808,U,34810,34811,34812,34813,34815,34816,34817,34818,34820,
+34821,34822,34823,34824,34825,34827,34828,34829,34830,34831,34832,34833,34834,
+34836,34839,34840,34841,34842,34844,34845,34846,34847,34848,34851,34852,34853,
+34854,34855,34856,34857,34858,34859,34860,34861,34862,34863,34864,34865,34867,
+34868,34869,34870,34871,34872,34874,34875,34877,34878,34879,34881,34882,34883,
+34886,34887,34888,34889,34890,34891,34894,34895,34896,34897,34898,34899,34901,
+34902,34904,34906,34907,34908,34909,34910,34911,34912,34918,34919,34922,34925,
+34927,34929,34931,34932,34933,34934,34936,34937,34938,U,34939,34940,34944,
+34947,34950,34951,34953,34954,34956,34958,34959,34960,34961,34963,34964,34965,
+34967,34968,34969,34970,34971,34973,34974,34975,34976,34977,34979,34981,34982,
+34983,34984,34985,34986,34988,34990,34991,34992,34994,34995,34996,34997,34998,
+35000,35001,35002,35003,35005,35006,35007,35008,35011,35012,35015,35016,35018,
+35019,35020,35021,35023,35024,35025,35027,35030,35031,35034,35035,35036,35037,
+35038,35040,35041,35046,35047,35049,35050,35051,35052,35053,35054,35055,35058,
+35061,35062,35063,35066,35067,35069,35071,35072,35073,35075,35076,35077,35078,
+35079,35080,U,35081,35083,35084,35085,35086,35087,35089,35092,35093,35094,
+35095,35096,35100,35101,35102,35103,35104,35106,35107,35108,35110,35111,35112,
+35113,35116,35117,35118,35119,35121,35122,35123,35125,35127,35128,35129,35130,
+35131,35132,35133,35134,35135,35136,35138,35139,35141,35142,35143,35144,35145,
+35146,35147,35148,35149,35150,35151,35152,35153,35154,35155,35156,35157,35158,
+35159,35160,35161,35162,35163,35164,35165,35168,35169,35170,35171,35172,35173,
+35175,35176,35177,35178,35179,35180,35181,35182,35183,35184,35185,35186,35187,
+35188,35189,35190,35191,35192,35193,35194,35196,U,35197,35198,35200,35202,
+35204,35205,35207,35208,35209,35210,35211,35212,35213,35214,35215,35216,35217,
+35218,35219,35220,35221,35222,35223,35224,35225,35226,35227,35228,35229,35230,
+35231,35232,35233,35234,35235,35236,35237,35238,35239,35240,35241,35242,35243,
+35244,35245,35246,35247,35248,35249,35250,35251,35252,35253,35254,35255,35256,
+35257,35258,35259,35260,35261,35262,35263,35264,35267,35277,35283,35284,35285,
+35287,35288,35289,35291,35293,35295,35296,35297,35298,35300,35303,35304,35305,
+35306,35308,35309,35310,35312,35313,35314,35316,35317,35318,35319,35320,35321,
+35322,U,35323,35324,35325,35326,35327,35329,35330,35331,35332,35333,35334,
+35336,35337,35338,35339,35340,35341,35342,35343,35344,35345,35346,35347,35348,
+35349,35350,35351,35352,35353,35354,35355,35356,35357,35358,35359,35360,35361,
+35362,35363,35364,35365,35366,35367,35368,35369,35370,35371,35372,35373,35374,
+35375,35376,35377,35378,35379,35380,35381,35382,35383,35384,35385,35386,35387,
+35388,35389,35391,35392,35393,35394,35395,35396,35397,35398,35399,35401,35402,
+35403,35404,35405,35406,35407,35408,35409,35410,35411,35412,35413,35414,35415,
+35416,35417,35418,35419,35420,35421,35422,U,35423,35424,35425,35426,35427,
+35428,35429,35430,35431,35432,35433,35434,35435,35436,35437,35438,35439,35440,
+35441,35442,35443,35444,35445,35446,35447,35448,35450,35451,35452,35453,35454,
+35455,35456,35457,35458,35459,35460,35461,35462,35463,35464,35467,35468,35469,
+35470,35471,35472,35473,35474,35476,35477,35478,35479,35480,35481,35482,35483,
+35484,35485,35486,35487,35488,35489,35490,35491,35492,35493,35494,35495,35496,
+35497,35498,35499,35500,35501,35502,35503,35504,35505,35506,35507,35508,35509,
+35510,35511,35512,35513,35514,35515,35516,35517,35518,35519,35520,35521,35522,
+U,35523,35524,35525,35526,35527,35528,35529,35530,35531,35532,35533,35534,
+35535,35536,35537,35538,35539,35540,35541,35542,35543,35544,35545,35546,35547,
+35548,35549,35550,35551,35552,35553,35554,35555,35556,35557,35558,35559,35560,
+35561,35562,35563,35564,35565,35566,35567,35568,35569,35570,35571,35572,35573,
+35574,35575,35576,35577,35578,35579,35580,35581,35582,35583,35584,35585,35586,
+35587,35588,35589,35590,35592,35593,35594,35595,35596,35597,35598,35599,35600,
+35601,35602,35603,35604,35605,35606,35607,35608,35609,35610,35611,35612,35613,
+35614,35615,35616,35617,35618,35619,U,35620,35621,35623,35624,35625,35626,
+35627,35628,35629,35630,35631,35632,35633,35634,35635,35636,35637,35638,35639,
+35640,35641,35642,35643,35644,35645,35646,35647,35648,35649,35650,35651,35652,
+35653,35654,35655,35656,35657,35658,35659,35660,35661,35662,35663,35664,35665,
+35666,35667,35668,35669,35670,35671,35672,35673,35674,35675,35676,35677,35678,
+35679,35680,35681,35682,35683,35684,35685,35687,35688,35689,35690,35691,35693,
+35694,35695,35696,35697,35698,35699,35700,35701,35702,35703,35704,35705,35706,
+35707,35708,35709,35710,35711,35712,35713,35714,35715,35716,35717,35718,U,
+35719,35720,35721,35722,35723,35724,35725,35726,35727,35728,35729,35730,35731,
+35732,35733,35734,35735,35736,35737,35738,35739,35740,35741,35742,35743,35756,
+35761,35771,35783,35792,35818,35849,35870,35896,35897,35898,35899,35900,35901,
+35902,35903,35904,35906,35907,35908,35909,35912,35914,35915,35917,35918,35919,
+35920,35921,35922,35923,35924,35926,35927,35928,35929,35931,35932,35933,35934,
+35935,35936,35939,35940,35941,35942,35943,35944,35945,35948,35949,35950,35951,
+35952,35953,35954,35956,35957,35958,35959,35963,35964,35965,35966,35967,35968,
+35969,35971,35972,35974,35975,U,35976,35979,35981,35982,35983,35984,35985,
+35986,35987,35989,35990,35991,35993,35994,35995,35996,35997,35998,35999,36000,
+36001,36002,36003,36004,36005,36006,36007,36008,36009,36010,36011,36012,36013,
+36014,36015,36016,36017,36018,36019,36020,36021,36022,36023,36024,36025,36026,
+36027,36028,36029,36030,36031,36032,36033,36034,36035,36036,36037,36038,36039,
+36040,36041,36042,36043,36044,36045,36046,36047,36048,36049,36050,36051,36052,
+36053,36054,36055,36056,36057,36058,36059,36060,36061,36062,36063,36064,36065,
+36066,36067,36068,36069,36070,36071,36072,36073,36074,36075,36076,U,36077,
+36078,36079,36080,36081,36082,36083,36084,36085,36086,36087,36088,36089,36090,
+36091,36092,36093,36094,36095,36096,36097,36098,36099,36100,36101,36102,36103,
+36104,36105,36106,36107,36108,36109,36110,36111,36112,36113,36114,36115,36116,
+36117,36118,36119,36120,36121,36122,36123,36124,36128,36177,36178,36183,36191,
+36197,36200,36201,36202,36204,36206,36207,36209,36210,36216,36217,36218,36219,
+36220,36221,36222,36223,36224,36226,36227,36230,36231,36232,36233,36236,36237,
+36238,36239,36240,36242,36243,36245,36246,36247,36248,36249,36250,36251,36252,
+36253,36254,36256,36257,U,36258,36260,36261,36262,36263,36264,36265,36266,
+36267,36268,36269,36270,36271,36272,36274,36278,36279,36281,36283,36285,36288,
+36289,36290,36293,36295,36296,36297,36298,36301,36304,36306,36307,36308,36309,
+36312,36313,36316,36320,36321,36322,36325,36326,36327,36329,36333,36334,36336,
+36337,36338,36340,36342,36348,36350,36351,36352,36353,36354,36355,36356,36358,
+36359,36360,36363,36365,36366,36368,36369,36370,36371,36373,36374,36375,36376,
+36377,36378,36379,36380,36384,36385,36388,36389,36390,36391,36392,36395,36397,
+36400,36402,36403,36404,36406,36407,36408,36411,36412,36414,U,36415,36419,
+36421,36422,36428,36429,36430,36431,36432,36435,36436,36437,36438,36439,36440,
+36442,36443,36444,36445,36446,36447,36448,36449,36450,36451,36452,36453,36455,
+36456,36458,36459,36462,36465,36467,36469,36471,36472,36473,36474,36475,36477,
+36478,36480,36482,36483,36484,36486,36488,36489,36490,36491,36492,36493,36494,
+36497,36498,36499,36501,36502,36503,36504,36505,36506,36507,36509,36511,36512,
+36513,36514,36515,36516,36517,36518,36519,36520,36521,36522,36525,36526,36528,
+36529,36531,36532,36533,36534,36535,36536,36537,36539,36540,36541,36542,36543,
+36544,36545,36546,U,36547,36548,36549,36550,36551,36552,36553,36554,36555,
+36556,36557,36559,36560,36561,36562,36563,36564,36565,36566,36567,36568,36569,
+36570,36571,36572,36573,36574,36575,36576,36577,36578,36579,36580,36581,36582,
+36583,36584,36585,36586,36587,36588,36589,36590,36591,36592,36593,36594,36595,
+36596,36597,36598,36599,36600,36601,36602,36603,36604,36605,36606,36607,36608,
+36609,36610,36611,36612,36613,36614,36615,36616,36617,36618,36619,36620,36621,
+36622,36623,36624,36625,36626,36627,36628,36629,36630,36631,36632,36633,36634,
+36635,36636,36637,36638,36639,36640,36641,36642,36643,U,36644,36645,36646,
+36647,36648,36649,36650,36651,36652,36653,36654,36655,36656,36657,36658,36659,
+36660,36661,36662,36663,36664,36665,36666,36667,36668,36669,36670,36671,36672,
+36673,36674,36675,36676,36677,36678,36679,36680,36681,36682,36683,36684,36685,
+36686,36687,36688,36689,36690,36691,36692,36693,36694,36695,36696,36697,36698,
+36699,36700,36701,36702,36703,36704,36705,36706,36707,36708,36709,36714,36736,
+36748,36754,36765,36768,36769,36770,36772,36773,36774,36775,36778,36780,36781,
+36782,36783,36786,36787,36788,36789,36791,36792,36794,36795,36796,36799,36800,
+36803,36806,U,36809,36810,36811,36812,36813,36815,36818,36822,36823,36826,
+36832,36833,36835,36839,36844,36847,36849,36850,36852,36853,36854,36858,36859,
+36860,36862,36863,36871,36872,36876,36878,36883,36885,36888,36889,36892,36899,
+36900,36901,36903,36904,36905,36906,36907,36908,36912,36913,36914,36915,36916,
+36919,36921,36922,36925,36927,36928,36931,36933,36934,36936,36937,36938,36939,
+36940,36942,36948,36949,36950,36953,36954,36956,36957,36958,36959,36960,36961,
+36964,36966,36967,36969,36970,36971,36972,36975,36976,36977,36978,36979,36982,
+36983,36984,36985,36986,36987,36988,36990,36993,U,36996,36997,36998,36999,
+37001,37002,37004,37005,37006,37007,37008,37010,37012,37014,37016,37018,37020,
+37022,37023,37024,37028,37029,37031,37032,37033,37035,37037,37042,37047,37052,
+37053,37055,37056,37058,37059,37062,37064,37065,37067,37068,37069,37074,37076,
+37077,37078,37080,37081,37082,37086,37087,37088,37091,37092,37093,37097,37098,
+37100,37102,37104,37105,37106,37107,37109,37110,37111,37113,37114,37115,37116,
+37119,37120,37121,37123,37125,37126,37127,37128,37129,37130,37131,37132,37133,
+37134,37135,37136,37137,37138,37139,37140,37141,37142,37143,37144,37146,37147,
+37148,U,37149,37151,37152,37153,37156,37157,37158,37159,37160,37161,37162,
+37163,37164,37165,37166,37168,37170,37171,37172,37173,37174,37175,37176,37178,
+37179,37180,37181,37182,37183,37184,37185,37186,37188,37189,37191,37192,37201,
+37203,37204,37205,37206,37208,37209,37211,37212,37215,37216,37222,37223,37224,
+37227,37229,37235,37242,37243,37244,37248,37249,37250,37251,37252,37254,37256,
+37258,37262,37263,37267,37268,37269,37270,37271,37272,37273,37276,37277,37278,
+37279,37280,37281,37284,37285,37286,37287,37288,37289,37291,37292,37296,37297,
+37298,37299,37302,37303,37304,37305,37307,U,37308,37309,37310,37311,37312,
+37313,37314,37315,37316,37317,37318,37320,37323,37328,37330,37331,37332,37333,
+37334,37335,37336,37337,37338,37339,37341,37342,37343,37344,37345,37346,37347,
+37348,37349,37350,37351,37352,37353,37354,37355,37356,37357,37358,37359,37360,
+37361,37362,37363,37364,37365,37366,37367,37368,37369,37370,37371,37372,37373,
+37374,37375,37376,37377,37378,37379,37380,37381,37382,37383,37384,37385,37386,
+37387,37388,37389,37390,37391,37392,37393,37394,37395,37396,37397,37398,37399,
+37400,37401,37402,37403,37404,37405,37406,37407,37408,37409,37410,37411,37412,
+U,37413,37414,37415,37416,37417,37418,37419,37420,37421,37422,37423,37424,
+37425,37426,37427,37428,37429,37430,37431,37432,37433,37434,37435,37436,37437,
+37438,37439,37440,37441,37442,37443,37444,37445,37446,37447,37448,37449,37450,
+37451,37452,37453,37454,37455,37456,37457,37458,37459,37460,37461,37462,37463,
+37464,37465,37466,37467,37468,37469,37470,37471,37472,37473,37474,37475,37476,
+37477,37478,37479,37480,37481,37482,37483,37484,37485,37486,37487,37488,37489,
+37490,37491,37493,37494,37495,37496,37497,37498,37499,37500,37501,37502,37503,
+37504,37505,37506,37507,37508,37509,U,37510,37511,37512,37513,37514,37515,
+37516,37517,37519,37520,37521,37522,37523,37524,37525,37526,37527,37528,37529,
+37530,37531,37532,37533,37534,37535,37536,37537,37538,37539,37540,37541,37542,
+37543,37544,37545,37546,37547,37548,37549,37551,37552,37553,37554,37555,37556,
+37557,37558,37559,37560,37561,37562,37563,37564,37565,37566,37567,37568,37569,
+37570,37571,37572,37573,37574,37575,37577,37578,37579,37580,37581,37582,37583,
+37584,37585,37586,37587,37588,37589,37590,37591,37592,37593,37594,37595,37596,
+37597,37598,37599,37600,37601,37602,37603,37604,37605,37606,37607,37608,U,
+37609,37610,37611,37612,37613,37614,37615,37616,37617,37618,37619,37620,37621,
+37622,37623,37624,37625,37626,37627,37628,37629,37630,37631,37632,37633,37634,
+37635,37636,37637,37638,37639,37640,37641,37642,37643,37644,37645,37646,37647,
+37648,37649,37650,37651,37652,37653,37654,37655,37656,37657,37658,37659,37660,
+37661,37662,37663,37664,37665,37666,37667,37668,37669,37670,37671,37672,37673,
+37674,37675,37676,37677,37678,37679,37680,37681,37682,37683,37684,37685,37686,
+37687,37688,37689,37690,37691,37692,37693,37695,37696,37697,37698,37699,37700,
+37701,37702,37703,37704,37705,U,37706,37707,37708,37709,37710,37711,37712,
+37713,37714,37715,37716,37717,37718,37719,37720,37721,37722,37723,37724,37725,
+37726,37727,37728,37729,37730,37731,37732,37733,37734,37735,37736,37737,37739,
+37740,37741,37742,37743,37744,37745,37746,37747,37748,37749,37750,37751,37752,
+37753,37754,37755,37756,37757,37758,37759,37760,37761,37762,37763,37764,37765,
+37766,37767,37768,37769,37770,37771,37772,37773,37774,37776,37777,37778,37779,
+37780,37781,37782,37783,37784,37785,37786,37787,37788,37789,37790,37791,37792,
+37793,37794,37795,37796,37797,37798,37799,37800,37801,37802,37803,U,37804,
+37805,37806,37807,37808,37809,37810,37811,37812,37813,37814,37815,37816,37817,
+37818,37819,37820,37821,37822,37823,37824,37825,37826,37827,37828,37829,37830,
+37831,37832,37833,37835,37836,37837,37838,37839,37840,37841,37842,37843,37844,
+37845,37847,37848,37849,37850,37851,37852,37853,37854,37855,37856,37857,37858,
+37859,37860,37861,37862,37863,37864,37865,37866,37867,37868,37869,37870,37871,
+37872,37873,37874,37875,37876,37877,37878,37879,37880,37881,37882,37883,37884,
+37885,37886,37887,37888,37889,37890,37891,37892,37893,37894,37895,37896,37897,
+37898,37899,37900,37901,U,37902,37903,37904,37905,37906,37907,37908,37909,
+37910,37911,37912,37913,37914,37915,37916,37917,37918,37919,37920,37921,37922,
+37923,37924,37925,37926,37927,37928,37929,37930,37931,37932,37933,37934,37935,
+37936,37937,37938,37939,37940,37941,37942,37943,37944,37945,37946,37947,37948,
+37949,37951,37952,37953,37954,37955,37956,37957,37958,37959,37960,37961,37962,
+37963,37964,37965,37966,37967,37968,37969,37970,37971,37972,37973,37974,37975,
+37976,37977,37978,37979,37980,37981,37982,37983,37984,37985,37986,37987,37988,
+37989,37990,37991,37992,37993,37994,37996,37997,37998,37999,U,38000,38001,
+38002,38003,38004,38005,38006,38007,38008,38009,38010,38011,38012,38013,38014,
+38015,38016,38017,38018,38019,38020,38033,38038,38040,38087,38095,38099,38100,
+38106,38118,38139,38172,38176,38183,38195,38205,38211,38216,38219,38229,38234,
+38240,38254,38260,38261,38263,38264,38265,38266,38267,38268,38269,38270,38272,
+38273,38274,38275,38276,38277,38278,38279,38280,38281,38282,38283,38284,38285,
+38286,38287,38288,38289,38290,38291,38292,38293,38294,38295,38296,38297,38298,
+38299,38300,38301,38302,38303,38304,38305,38306,38307,38308,38309,38310,38311,
+38312,38313,38314,U,38315,38316,38317,38318,38319,38320,38321,38322,38323,
+38324,38325,38326,38327,38328,38329,38330,38331,38332,38333,38334,38335,38336,
+38337,38338,38339,38340,38341,38342,38343,38344,38345,38346,38347,38348,38349,
+38350,38351,38352,38353,38354,38355,38356,38357,38358,38359,38360,38361,38362,
+38363,38364,38365,38366,38367,38368,38369,38370,38371,38372,38373,38374,38375,
+38380,38399,38407,38419,38424,38427,38430,38432,38435,38436,38437,38438,38439,
+38440,38441,38443,38444,38445,38447,38448,38455,38456,38457,38458,38462,38465,
+38467,38474,38478,38479,38481,38482,38483,38486,38487,U,38488,38489,38490,
+38492,38493,38494,38496,38499,38501,38502,38507,38509,38510,38511,38512,38513,
+38515,38520,38521,38522,38523,38524,38525,38526,38527,38528,38529,38530,38531,
+38532,38535,38537,38538,38540,38542,38545,38546,38547,38549,38550,38554,38555,
+38557,38558,38559,38560,38561,38562,38563,38564,38565,38566,38568,38569,38570,
+38571,38572,38573,38574,38575,38577,38578,38580,38581,38583,38584,38586,38587,
+38591,38594,38595,38600,38602,38603,38608,38609,38611,38612,38614,38615,38616,
+38617,38618,38619,38620,38621,38622,38623,38625,38626,38627,38628,38629,38630,
+38631,38635,U,38636,38637,38638,38640,38641,38642,38644,38645,38648,38650,
+38651,38652,38653,38655,38658,38659,38661,38666,38667,38668,38672,38673,38674,
+38676,38677,38679,38680,38681,38682,38683,38685,38687,38688,38689,38690,38691,
+38692,38693,38694,38695,38696,38697,38699,38700,38702,38703,38705,38707,38708,
+38709,38710,38711,38714,38715,38716,38717,38719,38720,38721,38722,38723,38724,
+38725,38726,38727,38728,38729,38730,38731,38732,38733,38734,38735,38736,38737,
+38740,38741,38743,38744,38746,38748,38749,38751,38755,38756,38758,38759,38760,
+38762,38763,38764,38765,38766,38767,38768,38769,U,38770,38773,38775,38776,
+38777,38778,38779,38781,38782,38783,38784,38785,38786,38787,38788,38790,38791,
+38792,38793,38794,38796,38798,38799,38800,38803,38805,38806,38807,38809,38810,
+38811,38812,38813,38814,38815,38817,38818,38820,38821,38822,38823,38824,38825,
+38826,38828,38830,38832,38833,38835,38837,38838,38839,38840,38841,38842,38843,
+38844,38845,38846,38847,38848,38849,38850,38851,38852,38853,38854,38855,38856,
+38857,38858,38859,38860,38861,38862,38863,38864,38865,38866,38867,38868,38869,
+38870,38871,38872,38873,38874,38875,38876,38877,38878,38879,38880,38881,38882,
+38883,U,38884,38885,38888,38894,38895,38896,38897,38898,38900,38903,38904,
+38905,38906,38907,38908,38909,38910,38911,38912,38913,38914,38915,38916,38917,
+38918,38919,38920,38921,38922,38923,38924,38925,38926,38927,38928,38929,38930,
+38931,38932,38933,38934,38935,38936,38937,38938,38939,38940,38941,38942,38943,
+38944,38945,38946,38947,38948,38949,38950,38951,38952,38953,38954,38955,38956,
+38957,38958,38959,38960,38961,38962,38963,38964,38965,38966,38967,38968,38969,
+38970,38971,38972,38973,38974,38975,38976,38977,38978,38979,38980,38981,38982,
+38983,38984,38985,38986,38987,38988,38989,U,38990,38991,38992,38993,38994,
+38995,38996,38997,38998,38999,39000,39001,39002,39003,39004,39005,39006,39007,
+39008,39009,39010,39011,39012,39013,39014,39015,39016,39017,39018,39019,39020,
+39021,39022,39023,39024,39025,39026,39027,39028,39051,39054,39058,39061,39065,
+39075,39080,39081,39082,39083,39084,39085,39086,39087,39088,39089,39090,39091,
+39092,39093,39094,39095,39096,39097,39098,39099,39100,39101,39102,39103,39104,
+39105,39106,39107,39108,39109,39110,39111,39112,39113,39114,39115,39116,39117,
+39119,39120,39124,39126,39127,39131,39132,39133,39136,39137,39138,39139,39140,
+U,39141,39142,39145,39146,39147,39148,39149,39150,39151,39152,39153,39154,
+39155,39156,39157,39158,39159,39160,39161,39162,39163,39164,39165,39166,39167,
+39168,39169,39170,39171,39172,39173,39174,39175,39176,39177,39178,39179,39180,
+39182,39183,39185,39186,39187,39188,39189,39190,39191,39192,39193,39194,39195,
+39196,39197,39198,39199,39200,39201,39202,39203,39204,39205,39206,39207,39208,
+39209,39210,39211,39212,39213,39215,39216,39217,39218,39219,39220,39221,39222,
+39223,39224,39225,39226,39227,39228,39229,39230,39231,39232,39233,39234,39235,
+39236,39237,39238,39239,39240,39241,U,39242,39243,39244,39245,39246,39247,
+39248,39249,39250,39251,39254,39255,39256,39257,39258,39259,39260,39261,39262,
+39263,39264,39265,39266,39268,39270,39283,39288,39289,39291,39294,39298,39299,
+39305,39308,39310,39322,39323,39324,39325,39326,39327,39328,39329,39330,39331,
+39332,39334,39335,39337,39338,39339,39340,39341,39342,39343,39344,39345,39346,
+39347,39348,39349,39350,39351,39352,39353,39354,39355,39356,39357,39358,39359,
+39360,39361,39362,39363,39364,39365,39366,39367,39368,39369,39370,39371,39372,
+39373,39374,39375,39376,39377,39378,39379,39380,39381,39382,39383,39384,U,
+39385,39386,39387,39388,39389,39390,39391,39392,39393,39394,39395,39396,39397,
+39398,39399,39400,39401,39402,39403,39404,39405,39406,39407,39408,39409,39410,
+39411,39412,39413,39414,39415,39416,39417,39418,39419,39420,39421,39422,39423,
+39424,39425,39426,39427,39428,39429,39430,39431,39432,39433,39434,39435,39436,
+39437,39438,39439,39440,39441,39442,39443,39444,39445,39446,39447,39448,39449,
+39450,39451,39452,39453,39454,39455,39456,39457,39458,39459,39460,39461,39462,
+39463,39464,39465,39466,39467,39468,39469,39470,39471,39472,39473,39474,39475,
+39476,39477,39478,39479,39480,U,39481,39482,39483,39484,39485,39486,39487,
+39488,39489,39490,39491,39492,39493,39494,39495,39496,39497,39498,39499,39500,
+39501,39502,39503,39504,39505,39506,39507,39508,39509,39510,39511,39512,39513,
+39514,39515,39516,39517,39518,39519,39520,39521,39522,39523,39524,39525,39526,
+39527,39528,39529,39530,39531,39538,39555,39561,39565,39566,39572,39573,39577,
+39590,39593,39594,39595,39596,39597,39598,39599,39602,39603,39604,39605,39609,
+39611,39613,39614,39615,39619,39620,39622,39623,39624,39625,39626,39629,39630,
+39631,39632,39634,39636,39637,39638,39639,39641,39642,39643,39644,U,39645,
+39646,39648,39650,39651,39652,39653,39655,39656,39657,39658,39660,39662,39664,
+39665,39666,39667,39668,39669,39670,39671,39672,39674,39676,39677,39678,39679,
+39680,39681,39682,39684,39685,39686,39687,39689,39690,39691,39692,39693,39694,
+39696,39697,39698,39700,39701,39702,39703,39704,39705,39706,39707,39708,39709,
+39710,39712,39713,39714,39716,39717,39718,39719,39720,39721,39722,39723,39724,
+39725,39726,39728,39729,39731,39732,39733,39734,39735,39736,39737,39738,39741,
+39742,39743,39744,39750,39754,39755,39756,39758,39760,39762,39763,39765,39766,
+39767,39768,39769,39770,U,39771,39772,39773,39774,39775,39776,39777,39778,
+39779,39780,39781,39782,39783,39784,39785,39786,39787,39788,39789,39790,39791,
+39792,39793,39794,39795,39796,39797,39798,39799,39800,39801,39802,39803,39804,
+39805,39806,39807,39808,39809,39810,39811,39812,39813,39814,39815,39816,39817,
+39818,39819,39820,39821,39822,39823,39824,39825,39826,39827,39828,39829,39830,
+39831,39832,39833,39834,39835,39836,39837,39838,39839,39840,39841,39842,39843,
+39844,39845,39846,39847,39848,39849,39850,39851,39852,39853,39854,39855,39856,
+39857,39858,39859,39860,39861,39862,39863,39864,39865,39866,U,39867,39868,
+39869,39870,39871,39872,39873,39874,39875,39876,39877,39878,39879,39880,39881,
+39882,39883,39884,39885,39886,39887,39888,39889,39890,39891,39892,39893,39894,
+39895,39896,39897,39898,39899,39900,39901,39902,39903,39904,39905,39906,39907,
+39908,39909,39910,39911,39912,39913,39914,39915,39916,39917,39918,39919,39920,
+39921,39922,39923,39924,39925,39926,39927,39928,39929,39930,39931,39932,39933,
+39934,39935,39936,39937,39938,39939,39940,39941,39942,39943,39944,39945,39946,
+39947,39948,39949,39950,39951,39952,39953,39954,39955,39956,39957,39958,39959,
+39960,39961,39962,U,39963,39964,39965,39966,39967,39968,39969,39970,39971,
+39972,39973,39974,39975,39976,39977,39978,39979,39980,39981,39982,39983,39984,
+39985,39986,39987,39988,39989,39990,39991,39992,39993,39994,39995,39996,39997,
+39998,39999,40000,40001,40002,40003,40004,40005,40006,40007,40008,40009,40010,
+40011,40012,40013,40014,40015,40016,40017,40018,40019,40020,40021,40022,40023,
+40024,40025,40026,40027,40028,40029,40030,40031,40032,40033,40034,40035,40036,
+40037,40038,40039,40040,40041,40042,40043,40044,40045,40046,40047,40048,40049,
+40050,40051,40052,40053,40054,40055,40056,40057,40058,U,40059,40061,40062,
+40064,40067,40068,40073,40074,40076,40079,40083,40086,40087,40088,40089,40093,
+40106,40108,40111,40121,40126,40127,40128,40129,40130,40136,40137,40145,40146,
+40154,40155,40160,40161,40163,40164,40165,40166,40167,40168,40169,40170,40171,
+40172,40173,40174,40175,40176,40177,40178,40179,40180,40181,40182,40183,40184,
+40185,40186,40187,40188,40189,40190,40191,40192,40193,40194,40195,40196,40197,
+40198,40199,40200,40201,40202,40203,40204,40205,40206,40207,40208,40209,40210,
+40211,40212,40213,40214,40215,40216,40217,40218,40219,40220,40221,40222,40223,
+40224,40225,U,40226,40227,40228,40229,40230,40231,40232,40233,40234,40235,
+40236,40237,40238,40239,40240,40241,40242,40243,40244,40245,40246,40247,40248,
+40249,40250,40251,40252,40253,40254,40255,40256,40257,40258,40259,40260,40261,
+40262,40263,40264,40265,40266,40267,40268,40269,40270,40271,40272,40273,40274,
+40275,40276,40277,40278,40279,40280,40281,40282,40283,40284,40285,40286,40287,
+40288,40289,40290,40291,40292,40293,40294,40295,40296,40297,40298,40299,40300,
+40301,40302,40303,40304,40305,40306,40307,40308,40309,40310,40311,40312,40313,
+40314,40315,40316,40317,40318,40319,40320,40321,U,40322,40323,40324,40325,
+40326,40327,40328,40329,40330,40331,40332,40333,40334,40335,40336,40337,40338,
+40339,40340,40341,40342,40343,40344,40345,40346,40347,40348,40349,40350,40351,
+40352,40353,40354,40355,40356,40357,40358,40359,40360,40361,40362,40363,40364,
+40365,40366,40367,40368,40369,40370,40371,40372,40373,40374,40375,40376,40377,
+40378,40379,40380,40381,40382,40383,40384,40385,40386,40387,40388,40389,40390,
+40391,40392,40393,40394,40395,40396,40397,40398,40399,40400,40401,40402,40403,
+40404,40405,40406,40407,40408,40409,40410,40411,40412,40413,40414,40415,40416,
+40417,U,40418,40419,40420,40421,40422,40423,40424,40425,40426,40427,40428,
+40429,40430,40431,40432,40433,40434,40435,40436,40437,40438,40439,40440,40441,
+40442,40443,40444,40445,40446,40447,40448,40449,40450,40451,40452,40453,40454,
+40455,40456,40457,40458,40459,40460,40461,40462,40463,40464,40465,40466,40467,
+40468,40469,40470,40471,40472,40473,40474,40475,40476,40477,40478,40484,40487,
+40494,40496,40500,40507,40508,40512,40525,40528,40530,40531,40532,40534,40537,
+40541,40543,40544,40545,40546,40549,40558,40559,40562,40564,40565,40566,40567,
+40568,40569,40570,40571,40572,40573,40576,U,40577,40579,40580,40581,40582,
+40585,40586,40588,40589,40590,40591,40592,40593,40596,40597,40598,40599,40600,
+40601,40602,40603,40604,40606,40608,40609,40610,40611,40612,40613,40615,40616,
+40617,40618,40619,40620,40621,40622,40623,40624,40625,40626,40627,40629,40630,
+40631,40633,40634,40636,40639,40640,40641,40642,40643,40645,40646,40647,40648,
+40650,40651,40652,40656,40658,40659,40661,40662,40663,40665,40666,40670,40673,
+40675,40676,40678,40680,40683,40684,40685,40686,40688,40689,40690,40691,40692,
+40693,40694,40695,40696,40698,40701,40703,40704,40705,40706,40707,40708,40709,
+U,40710,40711,40712,40713,40714,40716,40719,40721,40722,40724,40725,40726,
+40728,40730,40731,40732,40733,40734,40735,40737,40739,40740,40741,40742,40743,
+40744,40745,40746,40747,40749,40750,40752,40753,40754,40755,40756,40757,40758,
+40760,40762,40764,40767,40768,40769,40770,40771,40773,40774,40775,40776,40777,
+40778,40779,40780,40781,40782,40783,40786,40787,40788,40789,40790,40791,40792,
+40793,40794,40795,40796,40797,40798,40799,40800,40801,40802,40803,40804,40805,
+40806,40807,40808,40809,40810,40811,40812,40813,40814,40815,40816,40817,40818,
+40819,40820,40821,40822,40823,40824,U,40825,40826,40827,40828,40829,40830,
+40833,40834,40845,40846,40847,40848,40849,40850,40851,40852,40853,40854,40855,
+40856,40860,40861,40862,40865,40866,40867,40868,40869,63788,63865,63893,63975,
+63985,64012,64013,64014,64015,64017,64019,64020,64024,64031,64032,64033,64035,
+64036,64039,64040,64041,
+};
+
+static const struct dbcs_index gbkext_decmap[256] = {
+{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{__gbkext_decmap+0,64,254},{__gbkext_decmap+191,64,
+254},{__gbkext_decmap+382,64,254},{__gbkext_decmap+573,64,254},{
+__gbkext_decmap+764,64,254},{__gbkext_decmap+955,64,254},{__gbkext_decmap+1146
+,64,254},{__gbkext_decmap+1337,64,254},{__gbkext_decmap+1528,64,254},{
+__gbkext_decmap+1719,64,254},{__gbkext_decmap+1910,64,254},{__gbkext_decmap+
+2101,64,254},{__gbkext_decmap+2292,64,254},{__gbkext_decmap+2483,64,254},{
+__gbkext_decmap+2674,64,254},{__gbkext_decmap+2865,64,254},{__gbkext_decmap+
+3056,64,254},{__gbkext_decmap+3247,64,254},{__gbkext_decmap+3438,64,254},{
+__gbkext_decmap+3629,64,254},{__gbkext_decmap+3820,64,254},{__gbkext_decmap+
+4011,64,254},{__gbkext_decmap+4202,64,254},{__gbkext_decmap+4393,64,254},{
+__gbkext_decmap+4584,64,254},{__gbkext_decmap+4775,64,254},{__gbkext_decmap+
+4966,64,254},{__gbkext_decmap+5157,64,254},{__gbkext_decmap+5348,64,254},{
+__gbkext_decmap+5539,64,254},{__gbkext_decmap+5730,64,254},{__gbkext_decmap+
+5921,64,254},{__gbkext_decmap+6112,164,170},{__gbkext_decmap+6119,161,170},{0,
+0,0},{0,0,0},{0,0,0},{__gbkext_decmap+6129,224,245},{0,0,0},{__gbkext_decmap+
+6151,64,192},{__gbkext_decmap+6280,64,150},{__gbkext_decmap+6367,64,160},{
+__gbkext_decmap+6464,64,160},{__gbkext_decmap+6561,64,160},{__gbkext_decmap+
+6658,64,160},{__gbkext_decmap+6755,64,160},{__gbkext_decmap+6852,64,160},{
+__gbkext_decmap+6949,64,160},{__gbkext_decmap+7046,64,160},{__gbkext_decmap+
+7143,64,160},{__gbkext_decmap+7240,64,160},{__gbkext_decmap+7337,64,160},{
+__gbkext_decmap+7434,64,160},{__gbkext_decmap+7531,64,160},{__gbkext_decmap+
+7628,64,160},{__gbkext_decmap+7725,64,160},{__gbkext_decmap+7822,64,160},{
+__gbkext_decmap+7919,64,160},{__gbkext_decmap+8016,64,160},{__gbkext_decmap+
+8113,64,160},{__gbkext_decmap+8210,64,160},{__gbkext_decmap+8307,64,160},{
+__gbkext_decmap+8404,64,160},{__gbkext_decmap+8501,64,160},{__gbkext_decmap+
+8598,64,160},{__gbkext_decmap+8695,64,160},{__gbkext_decmap+8792,64,160},{
+__gbkext_decmap+8889,64,160},{__gbkext_decmap+8986,64,160},{__gbkext_decmap+
+9083,64,160},{__gbkext_decmap+9180,64,160},{__gbkext_decmap+9277,64,160},{
+__gbkext_decmap+9374,64,160},{__gbkext_decmap+9471,64,160},{__gbkext_decmap+
+9568,64,160},{__gbkext_decmap+9665,64,160},{__gbkext_decmap+9762,64,160},{
+__gbkext_decmap+9859,64,160},{__gbkext_decmap+9956,64,160},{__gbkext_decmap+
+10053,64,160},{__gbkext_decmap+10150,64,160},{__gbkext_decmap+10247,64,160},{
+__gbkext_decmap+10344,64,160},{__gbkext_decmap+10441,64,160},{__gbkext_decmap+
+10538,64,160},{__gbkext_decmap+10635,64,160},{__gbkext_decmap+10732,64,160},{
+__gbkext_decmap+10829,64,160},{__gbkext_decmap+10926,64,160},{__gbkext_decmap+
+11023,64,160},{__gbkext_decmap+11120,64,160},{__gbkext_decmap+11217,64,160},{
+__gbkext_decmap+11314,64,160},{__gbkext_decmap+11411,64,160},{__gbkext_decmap+
+11508,64,160},{__gbkext_decmap+11605,64,160},{__gbkext_decmap+11702,64,160},{
+__gbkext_decmap+11799,64,160},{__gbkext_decmap+11896,64,160},{__gbkext_decmap+
+11993,64,160},{__gbkext_decmap+12090,64,160},{__gbkext_decmap+12187,64,160},{
+__gbkext_decmap+12284,64,160},{__gbkext_decmap+12381,64,160},{__gbkext_decmap+
+12478,64,160},{__gbkext_decmap+12575,64,160},{__gbkext_decmap+12672,64,160},{
+__gbkext_decmap+12769,64,160},{__gbkext_decmap+12866,64,160},{__gbkext_decmap+
+12963,64,160},{__gbkext_decmap+13060,64,160},{__gbkext_decmap+13157,64,160},{
+__gbkext_decmap+13254,64,160},{__gbkext_decmap+13351,64,160},{__gbkext_decmap+
+13448,64,160},{__gbkext_decmap+13545,64,160},{__gbkext_decmap+13642,64,160},{
+__gbkext_decmap+13739,64,160},{__gbkext_decmap+13836,64,160},{__gbkext_decmap+
+13933,64,160},{__gbkext_decmap+14030,64,160},{__gbkext_decmap+14127,64,160},{
+__gbkext_decmap+14224,64,160},{__gbkext_decmap+14321,64,160},{__gbkext_decmap+
+14418,64,160},{__gbkext_decmap+14515,64,79},{0,0,0},
+};
+
+static const DBCHAR __gbcommon_encmap[23231] = {
+8552,N,N,8556,8487,N,N,N,N,N,N,N,8547,8512,N,N,N,N,N,41380,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8513,N,N,N,N,N,N,N,N,10276,10274,
+N,N,N,N,N,N,10280,10278,10298,N,10284,10282,N,N,N,N,10288,10286,N,N,N,8514,N,
+10292,10290,N,10297,10273,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,10277,N,N,N,N,N,N,
+N,10279,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,10281,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,43197,N,N,N,43198,N,N,N,N,10285,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,10289,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,10275,
+N,10283,N,10287,N,10291,N,10293,N,10294,N,10295,N,10296,43195,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,43200,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8486,N,8485,
+43072,43073,N,N,N,N,N,N,N,N,N,N,N,N,N,43074,9761,9762,9763,9764,9765,9766,
+9767,9768,9769,9770,9771,9772,9773,9774,9775,9776,9777,N,9778,9779,9780,9781,
+9782,9783,9784,N,N,N,N,N,N,N,9793,9794,9795,9796,9797,9798,9799,9800,9801,
+9802,9803,9804,9805,9806,9807,9808,9809,N,9810,9811,9812,9813,9814,9815,9816,
+10023,N,N,N,N,N,N,N,N,N,N,N,N,N,N,10017,10018,10019,10020,10021,10022,10024,
+10025,10026,10027,10028,10029,10030,10031,10032,10033,10034,10035,10036,10037,
+10038,10039,10040,10041,10042,10043,10044,10045,10046,10047,10048,10049,10065,
+10066,10067,10068,10069,10070,10072,10073,10074,10075,10076,10077,10078,10079,
+10080,10081,10082,10083,10084,10085,10086,10087,10088,10089,10090,10091,10092,
+10093,10094,10095,10096,10097,N,10071,43356,N,N,43075,41386,8490,8492,N,8494,
+8495,N,N,8496,8497,N,N,N,N,N,N,N,43077,8493,N,N,N,N,N,N,N,N,N,8555,N,8548,
+8549,N,43078,N,N,N,N,N,8569,8550,N,43079,N,N,N,43080,N,N,N,N,N,N,N,N,N,N,N,N,
+8557,N,N,N,N,N,N,N,N,N,N,43353,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+8817,8818,8819,8820,8821,8822,8823,8824,8825,8826,8827,8828,N,N,N,N,41633,
+41634,41635,41636,41637,41638,41639,41640,41641,41642,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,8571,8572,8570,8573,N,N,43081,43082,43083,43084,8522,N,N,
+N,N,N,N,8519,N,8518,N,N,N,43085,N,N,N,N,8524,N,N,8536,8542,43086,8527,N,N,
+43087,N,8526,N,8516,8517,8521,8520,8530,N,N,8531,N,N,N,N,N,8544,8543,8515,
+8523,N,N,N,N,N,8535,N,N,N,N,N,N,N,N,N,N,8534,N,N,N,8533,N,N,N,N,N,43088,N,N,N,
+N,N,N,N,N,N,N,N,N,N,8537,8532,N,N,8540,8541,43089,43090,N,N,N,N,N,N,8538,8539,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+43154,N,N,N,8529,N,N,N,N,N,N,N,N,N,N,N,8525,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,43091,8528,8793,8794,8795,8796,8797,8798,8799,8800,8801,8802,
+N,N,N,N,N,N,N,N,N,N,8773,8774,8775,8776,8777,8778,8779,8780,8781,8782,8783,
+8784,8785,8786,8787,8788,8789,8790,8791,8792,8753,8754,8755,8756,8757,8758,
+8759,8760,8761,8762,8763,8764,8765,8766,8767,8768,8769,8770,8771,8772,10532,
+10533,10534,10535,10536,10537,10538,10539,10540,10541,10542,10543,10544,10545,
+10546,10547,10548,10549,10550,10551,10552,10553,10554,10555,10556,10557,10558,
+10559,10560,10561,10562,10563,10564,10565,10566,10567,10568,10569,10570,10571,
+10572,10573,10574,10575,10576,10577,10578,10579,10580,10581,10582,10583,10584,
+10585,10586,10587,10588,10589,10590,10591,10592,10593,10594,10595,10596,10597,
+10598,10599,10600,10601,10602,10603,10604,10605,10606,10607,N,N,N,N,43092,
+43093,43094,43095,43096,43097,43098,43099,43100,43101,43102,43103,43104,43105,
+43106,43107,43108,43109,43110,43111,43112,43113,43114,43115,43116,43117,43118,
+43119,43120,43121,43122,43123,43124,43125,43126,43127,N,N,N,N,N,N,N,N,N,N,N,N,
+N,43128,43129,43130,43131,43132,43133,43134,43136,43137,43138,43139,43140,
+43141,43142,43143,N,N,N,43144,43145,43146,N,N,N,N,N,N,N,N,N,N,8566,8565,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,8568,8567,N,N,N,N,N,N,N,N,43147,43148,N,N,N,N,N,N,N,
+N,8564,8563,N,N,N,8560,N,N,8562,8561,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+43149,43150,43151,43152,8559,8558,N,N,43153,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+8546,N,8545,8481,8482,8483,8488,N,8489,43365,43414,8500,8501,8502,8503,8504,
+8505,8506,8507,8510,8511,43155,8574,8498,8499,8508,8509,N,N,N,N,N,43156,43157,
+N,N,43328,43329,43330,43331,43332,43333,43334,43335,43336,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,9249,9250,9251,9252,9253,9254,9255,9256,9257,9258,
+9259,9260,9261,9262,9263,9264,9265,9266,9267,9268,9269,9270,9271,9272,9273,
+9274,9275,9276,9277,9278,9279,9280,9281,9282,9283,9284,9285,9286,9287,9288,
+9289,9290,9291,9292,9293,9294,9295,9296,9297,9298,9299,9300,9301,9302,9303,
+9304,9305,9306,9307,9308,9309,9310,9311,9312,9313,9314,9315,9316,9317,9318,
+9319,9320,9321,9322,9323,9324,9325,9326,9327,9328,9329,9330,9331,N,N,N,N,N,N,
+N,43361,43362,43366,43367,N,N,9505,9506,9507,9508,9509,9510,9511,9512,9513,
+9514,9515,9516,9517,9518,9519,9520,9521,9522,9523,9524,9525,9526,9527,9528,
+9529,9530,9531,9532,9533,9534,9535,9536,9537,9538,9539,9540,9541,9542,9543,
+9544,9545,9546,9547,9548,9549,9550,9551,9552,9553,9554,9555,9556,9557,9558,
+9559,9560,9561,9562,9563,9564,9565,9566,9567,9568,9569,9570,9571,9572,9573,
+9574,9575,9576,9577,9578,9579,9580,9581,9582,9583,9584,9585,9586,9587,9588,
+9589,9590,N,N,N,N,8484,43360,43363,43364,10309,10310,10311,10312,10313,10314,
+10315,10316,10317,10318,10319,10320,10321,10322,10323,10324,10325,10326,10327,
+10328,10329,10330,10331,10332,10333,10334,10335,10336,10337,10338,10339,10340,
+10341,10342,10343,10344,10345,8805,8806,8807,8808,8809,8810,8811,8812,8813,
+8814,N,N,N,N,N,N,N,43354,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,43337,43338,43339,N,N,N,N,N,N,N,N,N,N,N,N,43340,43341,43342,
+N,N,43343,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+43344,N,N,N,N,N,N,N,N,N,43345,N,N,43346,43347,N,N,43348,21051,13857,33088,
+18015,33089,33090,33091,19826,21833,18557,18767,20290,22562,12859,21355,33092,
+22564,13171,33093,22312,18258,22567,19008,33094,18288,12667,21045,13396,13867,
+19263,22569,33095,33096,33097,13866,33098,16701,20815,33099,18725,22573,33100,
+14454,20798,25436,22096,33101,33102,14177,33103,13358,33104,16729,33105,22588,
+33106,19816,13604,20010,22135,33107,16502,15961,22575,33108,33109,33110,17483,
+33111,15939,33112,22577,17204,21093,33113,22062,20058,21799,14965,14118,16470,
+33114,17977,17746,18247,33115,14676,33116,13131,21074,33117,33118,22591,15941,
+18034,21042,20272,20327,33119,33120,33121,33122,19049,33123,33124,22592,33125,
+33126,33127,33128,33129,33130,17010,16978,33131,18537,33132,33133,33134,33135,
+33136,33137,33138,33139,33140,33141,18220,33142,33143,33144,33145,33146,33147,
+33148,16715,33149,21352,21881,33150,19010,13950,22561,21338,16247,33152,21574,
+15141,22593,20069,15918,33153,33154,22568,33155,20807,20521,33156,33157,33158,
+22589,22895,19830,16186,33159,15675,14885,21088,12922,14944,17462,33160,20333,
+15913,19748,16705,33161,33162,33163,18263,22897,33164,22900,33165,33166,33167,
+33168,18507,22633,33169,33170,33171,21082,18994,18506,22636,22634,22598,15734,
+17997,13168,33172,22635,15729,15721,33173,18516,13395,33174,33175,16984,33176,
+12886,22352,19019,19323,21836,14390,20297,33177,33178,33179,22874,22640,18218,
+33180,22638,33181,13434,16750,21076,33182,33183,22637,33184,21063,22639,17223,
+33185,33186,33187,20854,33188,22105,22642,33189,22645,15486,15451,33190,33191,
+33192,18510,33193,14173,33194,14146,33195,18035,33196,33197,33198,33199,33200,
+33201,33202,22648,21057,33203,33204,20073,15423,14204,14117,20573,33205,33206,
+33207,33208,33209,22106,21317,15215,15201,22641,33210,33211,18721,20016,13355,
+33212,22643,33213,18763,22646,16983,22647,33214,33215,20017,22649,33216,33217,
+33218,12846,14656,33219,22819,33220,12393,33221,16742,33222,18796,33223,19269,
+33224,19270,22820,33225,33226,33227,33228,33229,13672,33230,33231,13611,33232,
+33233,33234,33235,33236,33237,20027,13645,22305,22388,21331,33238,19557,33239,
+14926,33240,22818,22876,21344,22653,14192,22391,22654,22650,22817,17507,33241,
+33242,21302,22644,22877,33243,22651,33244,17765,33245,33246,16464,33247,33248,
+20848,12379,33249,33250,15441,22822,33251,22821,33252,33253,33254,33255,22828,
+22830,33256,22827,19001,33257,33258,33259,22825,22070,33260,33261,33262,13150,
+22824,33263,16509,33264,19020,33265,22826,33266,22823,33267,33268,22832,33269,
+33270,13873,33271,33272,33273,14633,33274,21056,33275,33276,20288,33277,33278,
+16962,33344,15684,21868,12896,18248,16235,22829,33345,22831,33346,20074,14958,
+33347,33348,33349,33350,33351,18262,33352,33353,33354,33355,33356,33357,33358,
+33359,33360,12643,33361,33362,33363,13401,13933,22836,33364,33365,33366,33367,
+16161,33368,33369,33370,22878,18254,16510,22840,33371,33372,33373,33374,33375,
+19287,14205,33376,22837,33377,22839,12579,21345,22841,33378,20549,33379,22838,
+33380,33381,22833,33382,22834,16681,22835,33383,33384,15475,20574,14377,33385,
+15971,33386,22845,33387,33388,33389,33390,22842,33391,12339,33392,33393,33394,
+22850,33395,33396,33397,33398,33399,33400,33401,33402,33403,33404,33405,33406,
+33408,22852,12598,33409,22847,33410,33411,13625,33412,15987,33413,33414,33415,
+19528,14962,21072,33416,22851,33417,33418,15720,33419,13099,33420,33421,33422,
+22853,15979,33423,22854,22843,17503,33424,22846,22849,22848,33425,33426,33427,
+33428,33429,33430,33431,33432,33433,33434,33435,21806,33436,22069,33437,18275,
+33438,33439,33440,33441,22856,33442,33443,33444,15449,22858,33445,33446,33447,
+22844,33448,22859,17963,33449,33450,33451,33452,33453,22857,33454,33455,33456,
+33457,22390,33458,19747,33459,33460,33461,33462,33463,33464,33465,33466,15649,
+33467,33468,33469,33470,33471,33472,22860,33473,33474,33475,33476,33477,33478,
+33479,33480,33481,17724,19765,33482,33483,33484,22861,33485,33486,22855,13093,
+16254,33487,33488,33489,33490,14389,33491,33492,16508,33493,33494,33495,33496,
+12408,33497,33498,33499,33500,33501,33502,33503,33504,33505,33506,33507,33508,
+33509,33510,33511,33512,33513,33514,33515,33516,33517,13430,33518,22862,33519,
+22863,13346,22864,33520,33521,13407,33522,33523,33524,33525,33526,12353,33527,
+33528,33529,33530,33531,33532,33533,22865,18741,33534,33600,33601,33602,33603,
+33604,33605,33606,33607,33608,33609,33610,33611,33612,33613,33614,33615,33616,
+33617,20337,33618,33619,33620,33621,33622,33623,22866,33624,33625,33626,16709,
+33627,33628,33629,33630,33631,33632,33633,33634,33635,33636,33637,22870,18734,
+33638,33639,33640,33641,22869,22868,22871,33642,33643,33644,33645,19291,33646,
+15657,33647,33648,33649,33650,33651,17959,33652,33653,33654,33655,33656,33657,
+33658,33659,33660,33661,22867,22872,33662,33664,33665,22873,33666,33667,33668,
+33669,33670,33671,18533,33672,33673,33674,33675,33676,33677,33678,33679,33680,
+33681,33682,33683,33684,33685,16476,33686,33687,33688,33689,33690,33691,33692,
+33693,33694,33695,33696,33697,33698,33699,33700,33701,33702,33703,33704,33705,
+33706,33707,33708,33709,33710,33711,33712,33713,33714,13945,22563,21578,33715,
+21546,20566,13156,21847,33716,20296,14690,33717,16203,33718,17250,33719,33720,
+33721,13906,33722,33723,19779,22894,22896,33724,33725,33726,13619,33727,13877,
+33728,33729,33730,33731,33732,15908,33733,33734,18539,33735,33736,18475,33737,
+33738,12363,14635,16761,22882,33739,16444,14642,33740,14680,20555,12664,18020,
+15967,13668,22344,33741,20856,15462,19038,33742,33743,15421,22886,22631,33744,
+33745,17498,33746,33747,14420,18493,33748,33749,12897,21593,33750,33751,33752,
+33753,17200,33754,33755,17249,23074,18527,33756,20532,33757,15996,17705,33758,
+33759,33760,14682,33761,23075,33762,21545,23076,33763,33764,33765,33766,33767,
+22907,13868,33768,33769,14187,12665,22908,13157,15990,33770,16246,21041,16484,
+33771,33772,33773,13875,22910,22909,33774,33775,15931,33776,33777,33778,18016,
+33779,22332,23073,33780,16697,33781,13682,16744,33782,33783,15477,33784,13397,
+33785,33786,33787,33788,33789,33790,33856,33857,33858,16733,33859,17533,33860,
+33861,15416,14130,33862,33863,14191,33864,33865,33866,33867,33868,33869,22892,
+33870,17982,33871,16173,15179,33872,33873,13642,33874,23369,20567,33875,19769,
+12348,13174,15223,23370,14895,33876,21604,13622,13683,22614,18512,33877,33878,
+14166,18256,22615,33879,16175,33880,33881,23355,22616,33882,33883,20556,15150,
+33884,33885,33886,27454,16720,16757,21618,14421,13364,33887,13173,33888,33889,
+18750,33890,33891,33892,17744,33893,33894,33895,17753,16507,33896,12656,33897,
+22617,14670,33898,13629,33899,33900,22618,33901,33902,22086,19234,18479,18738,
+13388,16204,33903,14708,33904,22619,22620,13927,15425,19562,33905,33906,33907,
+33908,33909,33910,20343,33911,22621,18224,33912,33913,14672,15651,33914,33915,
+19550,33916,17994,33917,33918,33920,33921,33922,22624,33923,22622,33924,33925,
+22623,33926,33927,33928,12414,33929,15975,33930,18979,15476,33931,33932,33933,
+33934,14385,33935,33936,14446,33937,33938,33939,33940,33941,33942,33943,33944,
+33945,33946,22626,33947,15691,33948,22628,22627,33949,33950,33951,33952,33953,
+17788,33954,33955,33956,33957,33958,33959,33960,22629,33961,33962,22630,33963,
+33964,33965,33966,33967,33968,33969,16678,33970,18480,12396,14630,15443,20081,
+23357,16723,33971,33972,33973,33974,13871,22138,17708,15705,23358,23359,33975,
+33976,33977,16504,15906,16461,33978,33979,33980,33981,33982,33983,33984,33985,
+33986,33987,23360,19014,33988,33989,33990,12842,33991,33992,33993,21314,33994,
+17251,33995,20779,33996,33997,33998,33999,23362,34000,16469,34001,34002,34003,
+23363,34004,16177,34005,34006,34007,34008,34009,34010,17468,34011,34012,34013,
+34014,18266,34015,34016,34017,34018,34019,34020,34021,34022,34023,34024,34025,
+23364,34026,34027,34028,34029,34030,34031,34032,34033,22888,18775,34034,34035,
+34036,14644,20080,21576,34037,34038,34039,34040,12412,13394,34041,20569,34042,
+34043,34044,34045,22889,34046,24139,22891,34112,34113,34114,34115,22576,15151,
+12593,34116,13143,22606,34117,34118,21585,34119,34120,15667,16239,34121,20283,
+34122,34123,22608,34124,34125,34126,14155,34127,34128,34129,22609,34130,34131,
+34132,34133,34134,34135,34136,34137,34138,34139,17957,18296,21053,34140,34141,
+22610,17508,34142,18990,34143,18215,34144,22566,34145,18813,20071,15196,12395,
+34146,34147,34148,15146,20525,34149,12592,22372,22335,34150,13605,17012,17487,
+34151,34152,12841,34153,12855,34154,12645,24370,21820,16168,16940,22613,16945,
+34155,22612,20052,34156,23136,34157,20032,34158,34159,22580,17198,21281,20003,
+34160,15412,18484,16977,34161,15981,20534,34162,23137,34163,34164,34165,34166,
+18276,34167,34168,13095,34169,13938,19580,16506,34170,34171,16503,34172,20793,
+20833,22599,34173,34174,34176,34177,34178,34179,34180,12894,34181,34182,16485,
+34183,14961,34184,34185,22600,34186,21549,34187,34188,20321,22601,34189,22602,
+20291,34190,13176,15943,34191,34192,34193,34194,22603,34195,34196,34197,34198,
+34199,34200,34201,23372,34202,34203,34204,34205,18469,34206,34207,34208,20312,
+34209,18558,12878,34210,34211,34212,34213,34214,21334,12902,15408,21329,19243,
+14132,34215,34216,34217,14114,34218,34219,19045,34220,18465,19036,12644,20592,
+34221,17745,34222,34223,34224,23365,13694,34225,34226,16218,14661,15972,16749,
+34227,24374,24373,22075,15696,21849,12360,13859,16201,19496,24371,18999,21330,
+34228,22607,21046,14917,19262,19518,34229,24375,13680,24372,34230,34231,34232,
+21365,34233,13140,14455,34234,24378,34235,14927,15402,13685,34236,19756,17275,
+14963,16500,19778,20338,24376,20293,34237,16960,24377,17008,34238,34239,34240,
+15997,34241,16735,19788,21111,14157,24385,34242,24388,34243,34244,14193,12361,
+13910,14164,34245,14892,19581,16212,19249,18036,34246,22056,24389,34247,20066,
+13107,34248,34249,20092,13365,34250,20039,14960,34251,20065,34252,20797,34253,
+34254,24384,34255,34256,13428,34257,13130,34258,14438,24379,34259,34260,34261,
+34262,17477,34263,24380,24381,24382,17723,24383,24386,21553,24387,34264,18234,
+20056,34265,34266,34267,34268,34269,17496,34270,24394,34271,24399,34272,22108,
+34273,34274,34275,34276,34277,34278,34279,34280,24393,24410,20022,34281,14919,
+24398,24392,17758,34282,34283,18795,14964,17276,34284,34285,15959,34286,24390,
+34287,24397,34288,17752,34289,34290,34291,34292,21798,14925,34293,15948,21309,
+14400,34294,22116,34295,24391,14654,16167,34296,34297,16764,24395,24396,34298,
+24400,34299,34300,34301,34302,34368,24411,24421,34369,24407,24406,22345,24419,
+24420,25963,21031,24402,34370,16169,34371,21595,34372,16200,24404,34373,34374,
+34375,20300,34376,34377,24413,34378,20810,34379,24414,12327,17975,24403,34380,
+14949,34381,13919,19803,14718,21589,34382,34383,24415,20332,12325,24423,24401,
+20806,24405,24408,24409,24412,34384,15145,34385,24416,24417,34386,24418,24422,
+24424,21300,34387,34388,34389,34390,34391,14439,17718,24426,18778,16680,17476,
+34392,34393,16222,20344,34394,34395,34396,21852,24430,34397,34398,34399,34400,
+34401,34402,12856,34403,14943,24428,34404,23361,34405,20836,34406,34407,34408,
+34409,19316,13373,34410,12326,34411,34412,34413,34414,34415,24433,19526,24434,
+34416,34417,24429,34418,34419,34420,34421,34422,34423,24425,34424,34425,34426,
+34427,24427,34428,24431,24432,15165,34429,34430,24435,34432,34433,24436,34434,
+15139,34435,19035,20008,24615,13098,34436,24614,34437,34438,34439,24609,34440,
+34441,34442,34443,24446,34444,19801,24444,34445,24442,34446,16208,22340,34447,
+18764,34448,34449,24440,12321,34450,34451,34452,34453,34454,24445,34455,34456,
+34457,34458,24443,24610,34459,34460,34461,34462,34463,24616,34464,34465,34466,
+34467,14152,34468,34469,17953,18742,16434,24437,34470,34471,17726,34472,22596,
+24441,17526,34473,34474,34475,34476,34477,34478,24611,24612,24613,20517,34479,
+34480,24628,19556,34481,24625,34482,16166,24623,20025,24619,18758,34483,34484,
+16430,24622,14957,14896,24617,34485,34486,34487,24438,34488,24627,34489,34490,
+24632,34491,34492,34493,13357,24633,34494,34495,20274,14920,34496,24624,34497,
+34498,34499,34500,34501,34502,34503,20602,34504,34505,34506,34507,34508,34509,
+34510,34511,34512,24620,34513,21627,34514,24439,34515,17767,34516,24621,34517,
+21367,34518,24630,24631,34519,34520,34521,34522,34523,24644,20577,34524,34525,
+34526,24636,34527,34528,24649,24650,34529,34530,34531,24638,24618,18724,24641,
+34532,24626,34533,34534,34535,34536,34537,19016,24643,34538,24629,34539,20043,
+34540,19267,24653,24646,24642,34541,24651,34542,24634,24639,24640,34543,34544,
+24645,34545,34546,24647,24648,34547,24652,34548,24635,34549,34550,34551,34552,
+34553,19284,24661,34554,24662,24658,34555,34556,34557,34558,34624,34625,24656,
+15438,34626,34627,24657,34628,14402,22597,34629,34630,34631,34632,34633,34634,
+34635,34636,20586,34637,34638,17007,34639,34640,24655,24637,34641,34642,34643,
+24660,24659,34644,34645,24663,34646,34647,34648,34649,24668,24664,34650,34651,
+34652,22134,13104,34653,22380,34654,19259,34655,34656,24666,34657,20091,34658,
+34659,34660,14937,34661,34662,34663,34664,34665,34666,34667,34668,34669,34670,
+34671,34672,24673,24669,21037,34673,34674,34675,34676,34677,24674,34678,34679,
+24667,24665,24671,34680,34681,24672,34682,34683,34684,34685,34686,24670,34688,
+24676,34689,34690,34691,18039,22572,21611,24678,19017,34692,34693,34694,34695,
+24677,34696,34697,34698,34699,14401,34700,34701,34702,34703,24679,24680,34704,
+34705,34706,34707,34708,34709,34710,34711,24681,24675,34712,34713,34714,34715,
+34716,34717,34718,14911,19559,34719,34720,34721,24682,34722,34723,34724,34725,
+34726,34727,34728,34729,34730,34731,34732,34733,34734,34735,34736,20345,34737,
+34738,34739,34740,34741,34742,34743,34744,34745,34746,34747,24683,34748,34749,
+34750,34751,34752,34753,34754,18498,34755,34756,34757,34758,15680,34759,34760,
+34761,34762,34763,34764,34765,34766,34767,34768,34769,34770,34771,17490,34772,
+34773,34774,34775,34776,34777,34778,34779,34780,24684,34781,34782,24685,34783,
+34784,18292,19268,34785,24686,15192,22582,21106,24687,19781,34786,13914,34787,
+34788,34789,34790,34791,34792,24689,34793,21552,34794,34795,16423,13393,34796,
+34797,20007,24688,34798,34799,34800,24690,14668,34801,34802,14714,19772,24691,
+34803,34804,34805,18004,24692,34806,21554,34807,18470,24694,24693,34808,34809,
+34810,34811,34812,34813,34814,34880,34881,34882,34883,34884,34885,34886,34887,
+34888,34889,24695,34890,34891,19777,34892,34893,34894,18981,34895,34896,34897,
+34898,21594,23383,23385,34899,23384,14695,23388,23389,13656,34900,34901,23386,
+34902,34903,34904,34905,34906,23387,13089,23391,34907,34908,15224,34909,22071,
+34910,23392,34911,34912,34913,34914,15993,34915,34916,14139,34917,23376,19502,
+16178,15157,22392,16211,34918,34919,34920,34921,34922,16233,34923,34924,15457,
+19507,23390,12371,20075,14168,22329,17986,34925,34926,16420,34927,19513,34928,
+23399,23393,17978,23395,34929,23400,34930,17783,34931,34932,34933,23402,34934,
+34935,23401,16192,34936,34937,34938,23398,23397,34939,34940,34941,34942,34944,
+13369,16428,16930,23394,23396,34945,34946,34947,34948,20557,23405,34949,34950,
+34951,34952,34953,16477,23410,34954,34955,34956,34957,34958,34959,34960,13922,
+34961,34962,34963,34964,23411,23378,14648,21547,23404,34965,16209,23408,34966,
+23377,34967,13670,34968,23403,16229,34969,34970,34971,23406,34972,23409,34973,
+34974,34975,23417,34976,34977,34978,34979,34980,34981,34982,34983,34984,14625,
+12323,34985,34986,34987,34988,34989,34990,34991,17009,34992,34993,13127,23407,
+34994,34995,23416,34996,18002,23412,34997,34998,23413,23415,23414,34999,35000,
+23422,35001,21362,12858,35002,35003,35004,23421,35005,35006,35007,35008,35009,
+35010,35011,35012,23588,35013,23419,35014,35015,35016,35017,23418,35018,35019,
+35020,23420,17760,15225,35021,35022,23587,35023,35024,23589,35025,19523,35026,
+35027,35028,13905,23872,35029,35030,35031,23585,35032,23586,35033,35034,35035,
+18229,35036,35037,35038,13929,35039,35040,35041,23591,35042,35043,35044,35045,
+23590,35046,23593,12580,35047,35048,13644,35049,35050,35051,35052,35053,16176,
+35054,35055,35056,35057,35058,20831,35059,35060,35061,35062,13890,35063,35064,
+35065,35066,35067,35068,35069,35070,35136,35137,35138,35139,35140,35141,23592,
+35142,35143,35144,35145,35146,35147,35148,19322,27507,35149,35150,35151,19292,
+35152,35153,19326,35154,35155,35156,19521,35157,35158,35159,35160,35161,18555,
+35162,35163,35164,35165,35166,35167,23594,35168,35169,35170,35171,35172,19566,
+23595,35173,35174,35175,35176,35177,35178,35179,35180,35181,35182,35183,35184,
+35185,35186,35187,35188,35189,23379,35190,23599,23596,35191,15923,35192,19067,
+35193,35194,35195,23597,35196,35197,35198,35200,35201,35202,35203,35204,18762,
+17465,35205,35206,35207,35208,35209,18237,23598,35210,35211,35212,21622,20582,
+35213,35214,35215,35216,35217,35218,35219,35220,17451,13909,35221,35222,35223,
+35224,35225,35226,35227,35228,35229,35230,35231,35232,35233,35234,35235,35236,
+35237,35238,23380,35239,35240,35241,35242,12634,35243,35244,35245,23381,35246,
+35247,35248,35249,35250,35251,35252,35253,35254,35255,35256,23382,35257,35258,
+35259,14910,35260,35261,35262,35263,35264,35265,35266,35267,35268,35269,35270,
+35271,35272,35273,18496,35274,35275,35276,35277,35278,35279,19007,18505,35280,
+22323,35281,18809,35282,35283,16199,35284,35285,14968,35286,35287,21052,35288,
+35289,35290,35291,35292,35293,35294,35295,25146,35296,13350,35297,35298,12600,
+35299,35300,35301,35302,35303,14388,35304,20292,35305,35306,35307,35308,22887,
+20262,19810,35309,35310,22893,13920,35311,21049,35312,35313,14651,35314,35315,
+35316,35317,25145,25143,35318,13427,35319,19564,19499,14194,35320,22578,20843,
+14907,35321,18983,35322,35323,19767,35324,35325,21060,16228,15440,13921,35326,
+24133,35392,35393,35394,35395,24134,23356,35396,20825,35397,35398,18022,17486,
+14190,35399,14172,35400,35401,16252,22368,35402,18037,35403,35404,12604,24136,
+15665,19543,24138,35405,24137,35406,35407,35408,35409,35410,13676,35411,18781,
+35412,35413,12354,35414,35415,35416,35417,35418,35419,35420,35421,35422,35423,
+35424,35425,35426,17710,17707,35427,17484,35428,15465,19325,35429,35430,35431,
+14915,35432,35433,35434,25977,18535,25978,19837,35435,22321,14398,17000,35436,
+18513,35437,35438,25979,35439,35440,35441,35442,13898,15435,35443,35444,20861,
+26145,35445,17262,35446,35447,35448,35449,26148,35450,35451,35452,35453,25982,
+26149,19799,35454,35456,14145,25980,25981,26147,35457,35458,17501,26152,35459,
+35460,26151,35461,35462,35463,35464,35465,35466,17219,35467,18014,35468,35469,
+26154,35470,35471,35472,35473,35474,35475,35476,17463,35477,35478,35479,26146,
+19004,35480,35481,35482,35483,15715,14659,26150,20565,20015,35484,35485,26153,
+26160,35486,21030,35487,15658,26157,35488,35489,35490,35491,35492,26159,35493,
+16465,35494,35495,21068,35496,35497,35498,15399,35499,35500,35501,35502,35503,
+35504,35505,35506,35507,35508,35509,35510,26161,35511,21110,35512,35513,35514,
+22347,35515,19838,35516,19806,16934,26155,26156,15679,26158,26163,35517,35518,
+26162,35519,35520,35521,35522,26166,35523,26168,35524,35525,35526,35527,17519,
+35528,35529,35530,17480,35531,35532,15978,18799,35533,35534,26167,35535,13936,
+35536,35537,35538,17252,35539,35540,35541,35542,35543,35544,35545,21353,26164,
+35546,26165,35547,18466,35548,35549,35550,35551,35552,26173,35553,35554,35555,
+26169,35556,35557,35558,35559,35560,17989,35561,35562,19825,26171,35563,35564,
+35565,35566,35567,35568,35569,35570,35571,35572,26172,35573,35574,35575,35576,
+15209,35577,35578,35579,35580,35581,35582,35648,26174,35649,35650,35651,35652,
+26170,35653,35654,16439,35655,35656,35657,35658,35659,35660,35661,35662,35663,
+21284,26175,18804,26179,35664,35665,26180,35666,35667,35668,35669,20598,35670,
+35671,35672,35673,35674,35675,35676,35677,35678,35679,35680,35681,35682,35683,
+35684,35685,35686,35687,17213,35688,35689,35690,35691,35692,35693,35694,17220,
+26178,35695,35696,35697,35698,35699,35700,35701,35702,35703,35704,35705,35706,
+35707,35708,26177,35709,35710,35712,35713,35714,35715,35716,26183,20273,35717,
+27508,35718,35719,26186,35720,35721,35722,35723,35724,26181,35725,35726,15454,
+18729,35727,35728,35729,35730,35731,35732,15413,35733,35734,20307,35735,35736,
+35737,35738,35739,26184,35740,26185,35741,26190,35742,26192,35743,35744,35745,
+26193,35746,35747,35748,26187,13653,35749,26188,35750,35751,26191,35752,35753,
+17499,35754,26182,35755,35756,35757,35758,35759,26189,35760,35761,35762,35763,
+35764,35765,35766,35767,35768,35769,35770,35771,35772,35773,35774,35775,35776,
+35777,35778,35779,35780,35781,35782,26194,35783,35784,35785,35786,35787,35788,
+35789,35790,35791,35792,35793,35794,26196,26195,35795,35796,35797,35798,35799,
+35800,35801,35802,35803,35804,35805,35806,35807,35808,35809,35810,35811,35812,
+35813,35814,35815,35816,35817,35818,35819,35820,26197,35821,22904,35822,35823,
+26198,35824,35825,35826,35827,35828,35829,35830,35831,26199,35832,35833,35834,
+35835,35836,35837,35838,35904,35905,35906,35907,35908,35909,35910,35911,22355,
+26205,35912,26206,16215,21584,35913,22358,13414,19311,26202,22595,22350,20514,
+35914,17231,35915,35916,26207,15422,14658,26203,20775,35917,35918,14882,16975,
+35919,22571,35920,35921,35922,19051,25966,35923,26204,35924,14197,35925,35926,
+35927,35928,18534,35929,35930,17525,35931,35932,25906,17534,35933,19324,25907,
+21804,35934,21358,19032,12338,35935,19278,19818,35936,35937,14954,35938,35939,
+35940,25909,35941,25908,35942,22362,14681,22118,13864,19824,21067,12582,18997,
+35943,13160,18803,16205,20603,19026,25910,15170,35944,35945,35946,20316,14636,
+35947,35948,35949,35950,21591,35951,35952,14886,20839,20348,15442,35953,25911,
+18525,35954,35955,35956,16237,12662,19294,35957,35958,15429,35959,15428,21114,
+17244,16220,35960,35961,35962,35963,14395,35964,35965,35966,17218,35968,14894,
+21538,35969,35970,35971,35972,35973,35974,35975,35976,35977,18270,17455,12908,
+35978,14673,35979,35980,25915,16712,35981,35982,21807,35983,35984,35985,35986,
+35987,25916,35988,25918,35989,35990,35991,35992,35993,35994,35995,13415,13908,
+19266,20784,13628,35996,35997,19033,35998,14178,35999,36000,18788,36001,15659,
+36002,36003,20030,22384,36004,36005,36006,36007,20513,36008,18777,36009,36010,
+13947,26200,15458,36011,13118,36012,18768,36013,26201,13090,36014,36015,36016,
+36017,24140,36018,21320,24141,36019,21026,36020,36021,36022,36023,24142,36024,
+36025,36026,36027,15949,36028,36029,24143,36030,36031,36032,18988,21116,13151,
+25962,17505,15905,20018,17522,15958,17960,12899,36033,36034,15955,36035,36036,
+18300,19563,15724,20061,36037,36038,19002,17985,25964,20540,36039,36040,36041,
+21817,36042,36043,36044,25965,36045,36046,36047,36048,19060,36049,19776,16965,
+36050,25967,36051,16964,25968,36052,36053,36054,36055,36056,36057,36058,25976,
+19789,36059,18749,36060,36061,36062,36063,36064,36065,36066,21081,24872,36067,
+36068,36069,36070,21356,36071,19306,18033,36072,36073,36074,36075,36076,24876,
+36077,36078,36079,24871,24873,36080,36081,24874,24879,36082,36083,12909,36084,
+24875,14426,24877,24878,24880,13626,24881,36085,36086,36087,36088,36089,24883,
+24888,36090,36091,36092,36093,36094,20818,36160,24886,24885,16747,36161,36162,
+36163,24887,36164,21568,36165,24882,36166,24890,12342,36167,36168,36169,36170,
+24884,36171,16249,36172,24889,36173,36174,24891,36175,36176,36177,36178,36179,
+36180,24894,36181,36182,36183,36184,36185,36186,24892,36187,36188,36189,36190,
+36191,36192,22085,36193,36194,36195,36196,36197,36198,36199,20287,36200,36201,
+24893,24895,16973,36202,13931,36203,21368,36204,36205,18253,36206,36207,14181,
+36208,36209,36210,36211,36212,36213,36214,36215,36216,36217,15998,36218,36219,
+36220,36221,36222,36224,24896,24897,36225,36226,24903,13159,36227,36228,36229,
+36230,36231,36232,18025,36233,36234,36235,36236,36237,13406,36238,20802,36239,
+36240,36241,36242,24904,36243,36244,24902,36245,36246,36247,36248,36249,24901,
+36250,24899,24898,36251,12608,36252,36253,36254,21816,24900,36255,36256,36257,
+36258,36259,24907,36260,36261,36262,36263,36264,36265,36266,36267,24908,24906,
+36268,36269,36270,36271,36272,36273,36274,36275,28538,36276,36277,24915,24914,
+18230,36278,36279,36280,36281,36282,36283,36284,36285,36286,36287,36288,24905,
+36289,36290,24910,36291,24912,36292,36293,36294,36295,36296,36297,36298,36299,
+36300,36301,36302,24916,36303,24913,24909,36304,36305,24911,36306,36307,36308,
+36309,24917,36310,36311,36312,36313,36314,36315,36316,36317,36318,36319,36320,
+36321,36322,24918,36323,36324,36325,36326,36327,36328,36329,36330,36331,36332,
+36333,36334,36335,36336,36337,36338,36339,36340,36341,36342,36343,36344,24919,
+36345,36346,36347,24920,36348,36349,36350,36416,36417,36418,36419,36420,36421,
+36422,36423,36424,36425,36426,36427,36428,36429,36430,36431,36432,36433,36434,
+36435,36436,36437,24922,36438,36439,36440,36441,36442,36443,36444,36445,36446,
+36447,36448,36449,36450,24923,36451,36452,36453,36454,36455,36456,36457,20001,
+36458,36459,36460,36461,36462,36463,36464,36465,36466,36467,36468,36469,36470,
+26461,36471,13352,22109,36472,36473,20786,13106,36474,36475,14628,22387,18249,
+15966,14638,36476,20055,36477,36478,12910,23375,36480,15418,21073,19272,12365,
+36481,36482,20335,36483,36484,36485,36486,36487,22883,15725,36488,36489,12626,
+19024,12860,36490,19239,14123,36491,18982,36492,36493,36494,20259,36495,36496,
+24696,21834,24699,36497,36498,24698,17729,19579,36499,16689,24697,22115,12847,
+22084,13659,36500,36501,36502,36503,36504,36505,36506,36507,13432,22049,36508,
+36509,36510,36511,36512,20271,12399,36513,36514,24700,36515,36516,36517,36518,
+36519,24865,13091,36520,36521,24701,24702,17201,36522,36523,36524,36525,17245,
+36526,24866,14201,36527,36528,36529,36530,36531,36532,15183,36533,36534,36535,
+36536,36537,36538,36539,24867,17467,36540,36541,36542,36543,36544,24868,36545,
+36546,24869,36547,36548,24870,13361,36549,36550,36551,36552,36553,36554,36555,
+36556,36557,36558,36559,36560,36561,36562,36563,14409,17981,17514,36564,12834,
+36565,20562,36566,26459,15171,21335,21316,36567,14691,25167,36568,36569,36570,
+22319,36571,18284,12627,36572,36573,13362,25169,36574,36575,36576,20594,16942,
+25168,36577,16226,21286,13655,25170,13674,36578,17261,14461,36579,14382,36580,
+17747,14159,25172,36581,36582,36583,36584,25171,13896,22393,36585,36586,36587,
+36588,36589,19749,36590,36591,36592,36593,36594,25176,36595,25174,19068,16181,
+21305,25173,36596,36597,36598,36599,25175,36600,36601,36602,36603,36604,36605,
+36606,36672,36673,36674,16686,16456,36675,36676,36677,36678,36679,36680,25179,
+25178,16426,36681,36682,16718,36683,36684,36685,36686,25180,36687,36688,36689,
+36690,36691,36692,36693,36694,36695,36696,36697,36698,25181,36699,25182,36700,
+36701,36702,36703,36704,36705,36706,36707,36708,23368,36709,20819,19746,36710,
+36711,15656,36712,36713,36714,24131,22565,16170,23373,21100,18042,17706,36715,
+36716,36717,24132,36718,12631,24366,36719,36720,36721,19005,36722,24369,36723,
+14637,36724,21117,36725,14373,14955,36726,36727,13146,36728,36729,36730,13660,
+21829,36731,36732,36733,36734,17238,20306,15137,36736,25971,25970,36737,36738,
+25972,36739,19812,36740,18549,36741,36742,36743,36744,36745,36746,36747,13615,
+18239,36748,25974,36749,36750,36751,27696,36752,36753,36754,36755,36756,36757,
+36758,36759,36760,36761,36762,36763,36764,36765,36766,25958,36767,14697,13617,
+36768,16956,25960,25959,25961,36769,36770,36771,36772,21069,36773,36774,36775,
+24938,20558,36776,19758,36777,20837,36778,36779,12874,12651,36780,12658,17773,
+36781,36782,21827,21296,36783,24924,36784,36785,36786,24925,36787,21083,36788,
+13113,12619,36789,36790,36791,19833,21879,24926,36792,15926,13437,36793,24927,
+14940,24928,15154,16969,24929,36794,36795,36796,20588,36797,19773,36798,36799,
+24930,36800,13635,17735,24931,36801,36802,24932,36803,36804,36805,36806,21369,
+36807,36808,36809,36810,36811,36812,24933,36813,20781,36814,36815,24934,20002,
+36816,36817,36818,36819,36820,36821,24935,36822,13634,36823,36824,36825,36826,
+24936,15189,36827,36828,36829,36830,36831,20548,25184,12632,21092,36832,36833,
+25185,36834,36835,15433,18508,36836,25187,27774,27773,24367,36837,36838,36839,
+25186,22078,19836,17190,36840,36841,36842,25411,36843,36844,22098,25191,36845,
+36846,25192,36847,36848,21319,36849,36850,25196,16236,36851,25197,25189,36852,
+36853,13120,36854,36855,36856,17518,36857,36858,25198,36859,36860,20547,36861,
+14966,25193,14174,15155,19500,19275,25188,25190,25194,25195,36862,36928,36929,
+25207,36930,36931,25204,21621,25203,36932,36933,17709,36934,21882,17730,12864,
+36935,36936,25199,36937,25202,16687,19260,36938,36939,13601,25209,36940,36941,
+36942,15409,25201,20564,21561,25205,14678,25206,36943,36944,36945,18259,36946,
+36947,36948,36949,36950,25200,36951,36952,36953,36954,36955,22364,27937,36956,
+36957,25208,36958,27941,25214,19025,36959,36960,36961,36962,36963,36964,36965,
+16693,36966,15184,36967,36968,16214,36969,14947,36970,36971,19233,36972,36973,
+36974,27942,27939,36975,36976,27938,36977,36978,36979,36980,15190,27943,20596,
+36981,36982,27940,14942,13943,25377,13874,19569,14631,36983,20258,18209,36984,
+36985,16210,36986,36987,13937,36988,25210,25211,25213,25212,17493,25378,36989,
+21313,36990,36992,36993,25383,18244,36994,36995,36996,36997,20260,36998,36999,
+25385,14903,37000,37001,37002,37003,25384,37004,15194,37005,25379,37006,37007,
+37008,25380,25386,37009,25382,37010,20082,21318,37011,37012,15164,37013,37014,
+21571,37015,17530,37016,37017,27944,20604,25381,37018,17269,37019,25389,12591,
+37020,25394,37021,37022,37023,15426,37024,37025,25388,13631,37026,37027,37028,
+37029,37030,37031,37032,37033,18281,25392,37034,37035,37036,15914,19823,37037,
+37038,37039,37040,37041,15219,37042,37043,37044,19560,37045,37046,25391,37047,
+25393,37048,20263,25390,37049,20009,15197,37050,37051,37052,37053,37054,13675,
+15973,12882,13133,37055,12601,25387,12881,13612,14687,13928,37056,37057,20331,
+25399,37058,15180,37059,37060,18503,20554,37061,37062,37063,37064,37065,25400,
+13166,37066,37067,37068,37069,27945,37070,21370,21348,37071,37072,37073,27946,
+25401,21090,37074,37075,37076,37077,37078,25397,37079,37080,37081,37082,21342,
+37083,37084,37085,37086,14416,25395,37087,37088,25398,14175,37089,25396,16418,
+37090,37091,37092,25402,37093,37094,37095,37096,37097,37098,37099,37100,37101,
+37102,37103,37104,37105,37106,37107,37108,37109,37110,37111,21560,37112,37113,
+37114,37115,37116,37117,37118,37184,13384,37185,25403,37186,15173,37187,18807,
+37188,37189,18789,37190,37191,37192,17469,37193,37194,37195,37196,37197,37198,
+37199,27947,37200,37201,37202,37203,17021,37204,37205,37206,37207,15195,16174,
+37208,37209,37210,37211,37212,37213,37214,20031,37215,37216,37217,37218,25404,
+37219,16182,37220,37221,37222,37223,37224,37225,37226,37227,37228,37229,37230,
+37231,37232,37233,37234,37235,37236,37237,37238,12655,37239,37240,21623,37241,
+37242,37243,37244,37245,25406,37246,37248,37249,37250,37251,37252,37253,37254,
+27949,37255,37256,37257,37258,37259,37260,37261,37262,37263,25407,14889,27948,
+37264,37265,25405,37266,37267,37268,37269,37270,37271,37272,37273,37274,37275,
+25408,37276,37277,37278,37279,37280,37281,14902,37282,37283,37284,13870,37285,
+37286,37287,37288,37289,20536,37290,12355,27950,37291,37292,37293,37294,37295,
+27951,16449,37296,25409,37297,37298,37299,37300,37301,37302,37303,37304,37305,
+37306,37307,37308,37309,37310,37311,37312,37313,17715,37314,37315,37316,37317,
+37318,37319,37320,37321,37322,37323,37324,37325,37326,37327,25410,37328,37329,
+37330,37331,37332,37333,37334,37335,37336,23602,37337,37338,37339,37340,37341,
+37342,27952,37343,14442,37344,20076,27175,20583,19065,18518,20279,13129,20050,
+15716,37345,37346,25438,15218,27176,21821,37347,18013,27177,37348,37349,37350,
+27178,37351,27180,27179,37352,27182,27181,37353,37354,37355,37356,15704,37357,
+27183,37358,16958,37359,37360,37361,37362,13377,13431,37363,37364,15143,37365,
+37366,37367,37368,37369,27750,27749,14143,19321,12642,37370,27751,37371,37372,
+37373,18760,27752,27753,37374,19030,24144,12869,21626,37440,37441,17995,12359,
+13426,18515,37442,37443,37444,19792,37445,37446,16184,37447,37448,37449,37450,
+37451,37452,37453,16219,37454,37455,18212,22068,37456,16425,24145,18728,20847,
+17700,12391,13110,18501,37457,37458,12386,37459,37460,14198,37461,37462,17786,
+37463,37464,13939,37465,21842,13136,15420,37466,37467,37468,13101,37469,37470,
+37471,37472,15985,12369,37473,37474,37475,37476,37477,37478,21078,19043,22309,
+37479,19766,13878,16185,21851,37480,14375,17751,37481,37482,37483,24146,16217,
+16981,18240,37484,15140,12584,37485,37486,17770,37487,37488,17787,19495,37489,
+37490,37491,37492,12583,37493,37494,37495,13654,37496,37497,37498,17448,37499,
+24147,20794,13161,37500,17266,37501,37502,14199,37504,22132,13603,12912,17460,
+17513,16429,24148,37505,12392,17732,16736,37506,14677,37507,15964,19800,12366,
+37508,19791,24150,15952,22334,24149,21840,12381,37509,37510,17506,37511,37512,
+16931,15472,37513,21301,16441,17697,12838,21617,37514,37515,16424,19011,24151,
+21884,37516,14640,37517,18477,19241,37518,24153,16189,37519,37520,37521,37522,
+17972,22311,18992,17475,37523,13142,14674,37524,37525,37526,37527,22072,27260,
+12340,37528,37529,37530,37531,16230,37532,37533,19572,37534,37535,37536,37537,
+19802,37538,37539,37540,22079,16974,37541,20046,19490,20526,17491,13618,24152,
+21877,15415,15187,37542,37543,12324,37544,17714,13420,37545,37546,37547,21873,
+37548,37549,27261,37550,37551,37552,37553,37554,37555,24154,19750,37556,37557,
+19820,37558,37559,37560,37561,20070,24156,37562,19761,16422,37563,37564,22333,
+37565,24155,12358,14900,18771,17523,15976,37566,37567,37568,37569,12854,37570,
+37571,37572,37573,37574,37575,37576,37577,16460,19312,37578,15473,15163,13623,
+37579,37580,37581,17781,37582,24166,37583,37584,37585,24163,15965,37586,37587,
+24159,37588,37589,37590,37591,13367,15709,37592,37593,24160,17517,37594,37595,
+37596,37597,20294,37598,13664,37599,37600,37601,37602,13918,19034,13684,24165,
+37603,21830,37604,24161,19533,18046,37605,17733,37606,37607,37608,21044,37609,
+15986,37610,37611,37612,37613,37614,37615,37616,16979,37617,19517,13112,37618,
+15699,37619,16216,19782,20826,13419,37620,24164,24157,24167,37621,27262,37622,
+37623,16944,24162,37624,37625,22080,13607,37626,12916,37627,24168,37628,24178,
+37629,37630,37696,37697,37698,24173,37699,24177,37700,37701,18528,37702,37703,
+37704,22369,24175,17256,19553,37705,12901,37706,37707,37708,21054,37709,37710,
+37711,37712,37713,37714,37715,24174,37716,24171,20053,37717,13351,37718,37719,
+37720,37721,37722,16171,15934,37723,37724,15698,37725,37726,37727,37728,24169,
+37729,21550,37730,24158,37731,24170,37732,37733,37734,37735,16447,37736,24172,
+12915,14441,16935,37737,37738,15681,37739,37740,37741,37742,37743,24181,24184,
+37744,37745,12843,13348,37746,37747,13418,18726,37748,37749,37750,37751,37752,
+37753,24182,19281,37754,14435,37755,24183,24186,37756,37757,37758,37760,24185,
+37761,37762,37763,19522,37764,12385,13422,37765,37766,37767,37768,37769,37770,
+25914,37771,37772,37773,37774,37775,20527,37776,37777,12907,37778,27425,37779,
+24180,37780,37781,18787,24179,12378,21025,12663,37782,19503,37783,37784,37785,
+37786,37787,37788,37789,24176,37790,19236,37791,37792,37793,21802,37794,37795,
+37796,37797,37798,24187,37799,37800,37801,37802,37803,37804,37805,37806,13405,
+37807,17446,37808,37809,37810,24189,37811,37812,37813,37814,37815,37816,37817,
+37818,37819,37820,17278,17441,24353,37821,37822,37823,37824,37825,37826,37827,
+16716,37828,24188,15983,37829,17970,37830,37831,37832,37833,37834,37835,37836,
+37837,37838,13125,18550,37839,37840,19258,24190,37841,37842,24356,37843,37844,
+37845,37846,22322,37847,37848,37849,37850,37851,13111,37852,37853,37854,37855,
+16707,37856,37857,18251,12837,13417,37858,22315,37859,37860,37861,37862,17516,
+37863,24354,24355,37864,24357,37865,14899,37866,37867,37868,24358,37869,16478,
+37870,37871,18755,37872,37873,37874,37875,37876,37877,37878,12889,18278,37879,
+24359,37880,18268,37881,37882,37883,37884,24360,27426,37885,37886,37952,37953,
+37954,19283,37955,37956,37957,24362,37958,24361,37959,12865,37960,37961,37962,
+37963,37964,37965,37966,37967,37968,37969,37970,37971,37972,37973,37974,37975,
+37976,37977,37978,37979,37980,37981,37982,37983,37984,17738,37985,37986,37987,
+37988,37989,37990,37991,37992,24363,37993,37994,37995,37996,37997,37998,37999,
+38000,21596,38001,38002,38003,38004,38005,18497,38006,38007,38008,38009,38010,
+38011,38012,38013,38014,38016,38017,38018,24364,38019,38020,38021,38022,38023,
+15984,38024,38025,24365,22055,38026,38027,38028,38029,27191,27446,19029,38030,
+22652,14404,38031,14629,38032,38033,14149,21886,38034,38035,38036,38037,38038,
+14666,38039,38040,20519,29773,38041,38042,13648,38043,38044,17268,38045,15944,
+38046,38047,38048,27447,12349,38049,38050,15692,38051,16690,38052,12630,13096,
+38053,38054,38055,14418,18722,38056,38057,13912,38058,38059,38060,38061,27448,
+15924,38062,38063,38064,19069,38065,18243,38066,21883,38067,38068,14195,38069,
+38070,38071,38072,38073,38074,38075,38076,38077,38078,38079,38080,38081,38082,
+38083,20036,38084,38085,38086,21803,12659,38087,38088,38089,27699,12383,38090,
+27701,38091,38092,38093,13879,38094,16719,38095,30074,20529,38096,38097,21861,
+38098,20051,38099,38100,15727,13154,38101,14379,38102,21814,38103,27965,38104,
+13903,38105,19257,20546,38106,38107,38108,38109,38110,38111,38112,38113,14141,
+38114,38115,27702,18985,38116,38117,38118,17748,38119,27705,27704,16963,27703,
+38120,38121,38122,38123,20605,27706,38124,27707,22373,38125,38126,27708,38127,
+38128,38129,27709,18028,38130,38131,38132,38133,38134,38135,38136,38137,20062,
+38138,15432,38139,38140,18517,13609,15945,22076,21607,38141,38142,20782,20593,
+27192,27193,27194,14901,38208,38209,38210,38211,18993,16245,38212,38213,19834,
+38214,38215,38216,38217,38218,27200,38219,12346,27198,38220,38221,16421,38222,
+38223,38224,27195,38225,12925,38226,17271,15208,38227,38228,38229,21079,20084,
+27199,38230,38231,38232,27196,38233,38234,38235,27203,38236,20551,21299,38237,
+38238,38239,38240,13370,38241,17217,22386,38242,38243,38244,38245,21841,38246,
+19015,38247,27205,38248,38249,27204,27207,27206,38250,38251,38252,38253,38254,
+22119,38255,20308,38256,38257,27211,38258,15182,38259,38260,38261,38262,38263,
+38264,38265,15738,18766,38266,38267,27212,38268,38269,18745,20350,27210,21582,
+27213,27215,38270,38272,19821,38273,38274,38275,38276,27209,38277,27214,38278,
+38279,20078,38280,15198,38281,13119,38282,38283,38284,38285,38286,18005,15920,
+20090,38287,38288,38289,18279,38290,15911,27216,38291,38292,22087,38293,38294,
+38295,16704,38296,38297,38298,21597,38299,27217,38300,38301,20286,38302,38303,
+38304,38305,27218,38306,38307,38308,38309,19054,38310,38311,38312,38313,17711,
+12341,38314,38315,38316,38317,38318,27220,38319,38320,38321,38322,38323,38324,
+38325,38326,38327,27219,29791,38328,38329,38330,38331,38332,17466,38333,38334,
+38335,38336,38337,12585,38338,38339,38340,38341,25951,38342,38343,38344,38345,
+27221,38346,38347,38348,38349,38350,38351,38352,38353,38354,38355,38356,38357,
+38358,38359,38360,38361,38362,38363,38364,38365,38366,38367,38368,38369,38370,
+38371,19055,38372,27222,27223,18008,38373,38374,38375,38376,38377,38378,38379,
+38380,27224,38381,38382,27225,38383,38384,38385,38386,38387,38388,21563,38389,
+18298,21047,14460,38390,38391,27202,38392,12892,38393,38394,17020,38395,21624,
+19558,22382,38396,38397,38398,38464,38465,38466,38467,21570,21328,27459,17779,
+38468,14206,38469,38470,27476,38471,38472,38473,19255,27486,38474,16458,38475,
+38476,38477,19835,38478,13103,38479,18010,38480,38481,38482,38483,38484,38485,
+27516,38486,17470,38487,20020,17449,12606,21629,38488,19061,38489,22124,38490,
+38491,18003,13924,38492,38493,38494,38495,15226,38496,38497,20576,38498,38499,
+18737,38500,21587,18472,38501,38502,14411,38503,26686,18748,38504,38505,26683,
+38506,16494,20563,12868,13413,38507,26684,38508,38509,21832,38510,38511,38512,
+38513,38514,13893,38515,26685,19064,14428,19573,38516,38517,38518,16436,38519,
+38520,20846,26687,26690,38521,38522,14908,38523,12589,15708,38524,27197,26691,
+38525,26694,38526,26699,38528,38529,38530,38531,26700,38532,19273,12389,38533,
+15403,38534,38535,14649,38536,38537,26689,38538,19831,38539,26698,38540,38541,
+38542,38543,20086,38544,38545,38546,38547,21869,38548,16726,26692,38549,17206,
+38550,14715,22054,26696,38551,38552,38553,19040,21606,38554,26688,38555,26693,
+26695,38556,18233,14179,38557,26697,38558,16221,26706,38559,38560,26711,38561,
+26709,15452,15439,26715,38562,38563,38564,38565,38566,38567,38568,38569,26718,
+38570,26714,12666,38571,38572,38573,38574,38575,38576,38577,38578,38579,38580,
+12376,17459,14412,18018,18494,18529,38581,38582,38583,26703,26708,26710,38584,
+14705,26712,22389,38585,17531,38586,26716,38587,38588,12905,38589,38590,38591,
+26705,38592,38593,15469,38594,38595,16194,26701,22137,38596,16760,12913,38597,
+38598,38599,38600,38601,38602,38603,38604,26719,38605,19009,26713,38606,38607,
+38608,38609,21796,38610,12650,21819,26702,26704,13872,26707,38611,26717,16440,
+38612,19063,38613,19240,38614,38615,18012,16501,38616,38617,38618,38619,38620,
+26729,38621,38622,38623,20515,38624,38625,38626,38627,38628,38629,38630,26738,
+22122,38631,38632,38633,38634,38635,38636,38637,26720,26721,38638,38639,38640,
+20857,14923,14457,38641,38642,14449,21588,26735,38643,26734,26732,14704,19538,
+26726,20006,16242,38644,12344,26737,26736,38645,22336,38646,26724,38647,19753,
+18723,38648,15160,15707,26730,38649,38650,38651,38652,38653,38654,38720,38721,
+38722,38723,26722,26723,26725,13621,26727,18245,26731,26733,15664,22318,38724,
+26744,38725,38726,38727,38728,38729,38730,38731,38732,26741,38733,19760,26742,
+38734,38735,38736,38737,38738,38739,38740,38741,38742,16698,38743,26728,38744,
+17207,12400,38745,38746,38747,38748,38749,38750,38751,38752,26740,38753,38754,
+38755,26743,38756,38757,38758,14627,38759,38760,38761,38762,38763,38764,38765,
+38766,38767,38768,18770,38769,38770,38771,17230,20064,16486,38772,38773,38774,
+38775,19315,38776,19549,20533,38777,38778,19041,38779,26739,38780,38781,38782,
+38784,38785,38786,38787,38788,38789,38790,15468,38791,26745,38792,38793,38794,
+38795,38796,38797,17246,38798,18021,38799,14711,38800,38801,38802,38803,12404,
+38804,38805,22360,38806,38807,15404,38808,17775,38809,38810,38811,38812,38813,
+19524,38814,38815,26918,38816,38817,38818,38819,38820,38821,38822,38823,38824,
+38825,18733,38826,26914,16482,38827,38828,38829,16195,38830,38831,38832,26750,
+14679,38833,26747,38834,38835,38836,38837,26916,38838,38839,38840,21070,38841,
+38842,38843,38844,38845,26915,38846,22066,22325,38847,26919,38848,15671,38849,
+38850,38851,38852,38853,38854,38855,38856,38857,38858,38859,38860,26748,26749,
+38861,38862,38863,26913,38864,38865,38866,38867,38868,38869,38870,38871,19798,
+38872,38873,21036,38874,38875,38876,26930,38877,38878,38879,38880,26921,38881,
+38882,38883,13354,38884,13371,38885,38886,26923,38887,38888,38889,38890,38891,
+38892,38893,38894,38895,38896,38897,38898,38899,38900,38901,38902,38903,20520,
+38904,38905,26917,38906,38907,13182,38908,38909,26924,16483,38910,26922,38976,
+38977,26937,38978,38979,26936,38980,38981,38982,38983,26926,38984,38985,26746,
+38986,38987,26920,38988,38989,38990,38991,38992,16172,26929,26938,38993,38994,
+16933,38995,38996,38997,26927,38998,14405,38999,26925,39000,21340,26932,26933,
+26935,39001,39002,39003,26951,39004,39005,39006,39007,39008,39009,16454,26949,
+39010,39011,26928,39012,39013,26939,12401,39014,39015,39016,39017,39018,39019,
+39020,39021,39022,39023,26940,21797,39024,39025,26942,39026,26943,39027,39028,
+39029,26945,39030,39031,16753,39032,39033,18486,39034,39035,39036,26941,39037,
+39038,39040,39041,39042,26946,39043,39044,39045,39046,39047,39048,39049,39050,
+26947,39051,26931,39052,26934,39053,15153,39054,39055,39056,26944,39057,39058,
+39059,39060,39061,39062,15479,39063,39064,39065,26948,26950,39066,39067,39068,
+39069,39070,39071,39072,39073,39074,39075,39076,39077,26954,39078,39079,39080,
+39081,26958,39082,39083,39084,39085,39086,39087,39088,39089,39090,39091,12891,
+39092,26952,39093,39094,39095,39096,39097,39098,39099,39100,39101,39102,14126,
+39103,39104,39105,39106,39107,39108,39109,39110,39111,39112,39113,39114,26955,
+26956,39115,39116,39117,39118,39119,39120,21825,39121,17443,39122,39123,39124,
+39125,39126,39127,26968,39128,14945,39129,39130,39131,39132,26953,39133,21283,
+39134,39135,39136,26964,39137,39138,39139,39140,39141,39142,39143,26967,26960,
+39144,39145,39146,39147,39148,26959,39149,39150,18241,39151,39152,39153,39154,
+39155,39156,39157,39158,26962,39159,39160,39161,39162,39163,39164,39165,26969,
+13128,39166,26963,39232,39233,39234,39235,39236,20336,39237,39238,39239,26957,
+39240,39241,39242,39243,39244,39245,39246,39247,39248,39249,39250,13175,39251,
+39252,39253,39254,39255,39256,39257,26966,39258,39259,26970,39260,39261,39262,
+19508,39263,39264,39265,20269,39266,39267,39268,39269,39270,39271,39272,39273,
+39274,26965,39275,26972,26971,39276,39277,39278,39279,39280,26974,39281,39282,
+39283,39284,39285,39286,39287,39288,26961,39289,39290,39291,39292,39293,39294,
+39296,39297,26973,39298,26975,17226,39299,39300,39301,39302,39303,39304,39305,
+39306,39307,39308,39309,39310,39311,39312,39313,39314,39315,39316,39317,39318,
+39319,39320,39321,39322,39323,39324,39325,39326,39327,39328,39329,39330,39331,
+39332,39333,39334,39335,39336,39337,39338,39339,39340,39341,39342,39343,39344,
+39345,39346,39347,39348,39349,39350,39351,39352,39353,39354,39355,39356,39357,
+39358,39359,39360,39361,39362,39363,39364,39365,39366,39367,39368,39369,39370,
+39371,39372,39373,39374,39375,39376,39377,39378,39379,39380,39381,39382,39383,
+39384,39385,39386,39387,39388,39389,39390,39391,39392,39393,39394,39395,39396,
+39397,39398,39399,39400,39401,39402,39403,39404,39405,39406,39407,39408,39409,
+39410,39411,39412,39413,18231,13390,15158,20544,27683,39414,39415,17719,39416,
+39417,39418,39419,39420,39421,39422,39488,39489,39490,21371,39491,39492,39493,
+39494,27684,39495,27685,18011,39496,39497,39498,16238,39499,39500,39501,39502,
+27686,39503,39504,27687,20522,39505,18232,39506,39507,14440,39508,39509,39510,
+39511,39512,39513,39514,39515,39516,39517,39518,39519,27688,39520,39521,39522,
+39523,39524,39525,39526,39527,22073,21885,13387,12861,20068,18023,39528,39529,
+19809,39530,39531,39532,39533,39534,39535,39536,39537,39538,39539,39540,39541,
+39542,39543,13429,39544,19264,15455,39545,39546,39547,39548,26978,26979,20842,
+26981,39549,13433,26980,39550,20787,19042,12880,39552,26984,39553,39554,39555,
+39556,26982,26983,39557,39558,22067,39559,39560,39561,26985,26986,39562,39563,
+39564,39565,39566,26987,39567,39568,39569,39570,39571,39572,39573,39574,26988,
+39575,39576,39577,39578,39579,39580,39581,39582,27695,17721,13902,39583,21107,
+39584,39585,39586,39587,39588,39589,39590,13678,39591,15193,27697,39592,39593,
+21091,39594,39595,39596,39597,39598,20067,39599,17464,39600,17215,39601,39602,
+13886,22585,12616,12623,12625,17790,39603,12624,39604,17195,39605,39606,39607,
+39608,39609,21809,39610,39611,39612,39613,39614,39615,39616,39617,27428,14913,
+39618,39619,39620,19514,39621,39622,39623,27429,39624,27431,39625,39626,39627,
+27432,39628,39629,39630,27430,39631,39632,39633,39634,39635,39636,39637,27433,
+27435,27434,39638,39639,39640,39641,39642,27436,39643,19023,22581,17265,39644,
+17189,18040,27437,17482,39645,27438,27439,27440,14165,39646,39647,39648,14202,
+39649,27441,18274,39650,27443,39651,14884,20853,12337,27442,27444,39652,39653,
+39654,13610,16968,18280,39655,27445,39656,19246,25439,39657,39658,21312,39659,
+39660,39661,39662,22875,39663,39664,19745,22061,18291,39665,39666,39667,22880,
+15203,39668,14906,25442,39669,39670,39671,39672,39673,20267,39674,39675,39676,
+25440,18759,39677,14905,39678,39744,39745,20788,25441,18538,14639,15661,13144,
+20059,39746,39747,19520,39748,39749,39750,25448,25449,19828,39751,39752,39753,
+39754,39755,19501,39756,15411,39757,25450,39758,25451,39759,39760,20570,39761,
+39762,39763,18043,14170,39764,39765,18271,21066,20054,39766,25444,25452,39767,
+18802,13121,39768,39769,25447,39770,39771,18019,25445,39772,39773,27955,25446,
+39774,39775,39776,39777,18739,39778,17766,39779,39780,39781,14645,39782,17211,
+39783,25443,17725,16676,16985,12887,39784,25453,15142,17453,39785,25456,15962,
+39786,39787,25467,25461,14931,39788,39789,39790,39791,14160,21325,39792,22094,
+21843,14657,21812,20824,39793,39794,39795,39796,20537,18294,39797,39798,39799,
+18474,12852,39800,17242,39801,39802,39803,25454,39804,39805,25468,25455,14120,
+25463,25460,39806,39808,39809,14138,39810,39811,17698,39812,25462,17757,12840,
+18044,39813,17504,39814,39815,22306,39816,16481,25465,39817,39818,25466,25469,
+19497,25459,39819,21310,39820,12611,27956,25457,25458,39821,25464,20538,17987,
+21619,25470,39822,39823,15712,39824,39825,25639,39826,39827,25638,39828,39829,
+39830,20851,25635,39831,25641,39832,39833,39834,18551,39835,39836,39837,39838,
+20276,39839,25640,25646,16997,39840,39841,13876,39842,39843,39844,39845,39846,
+39847,15730,39848,25634,39849,39850,14953,25642,39851,39852,25644,39853,39854,
+13949,22110,25650,39855,25645,39856,39857,39858,25633,39859,15214,19805,18210,
+17737,39860,39861,16759,39862,25636,39863,18227,15660,15677,25637,39864,22343,
+12898,39865,25643,15427,25647,39866,15211,25648,17704,25649,39867,39868,39869,
+39870,21859,16163,39871,25658,39872,25655,39873,25659,39874,39875,25661,39876,
+39877,18006,39878,39879,14918,16459,39880,39881,39882,14369,25652,39883,39884,
+39885,39886,21537,39887,39888,14883,15742,39889,39890,39891,25660,39892,39893,
+39894,39895,39896,19775,39897,39898,17529,39899,39900,20347,18790,39901,39902,
+21311,39903,20305,39904,39905,25651,39906,25656,25657,19561,39907,39908,39909,
+39910,39911,19534,39912,16468,25653,16688,25654,20048,39913,15169,13651,39914,
+18547,15655,21831,18732,14370,25674,39915,39916,25676,20804,39917,39918,21050,
+39919,39920,14893,39921,39922,14932,39923,39924,39925,39926,39927,39928,25667,
+13677,39929,39930,39931,22349,25664,20349,25663,39932,39933,39934,16732,19530,
+40000,40001,40002,40003,19047,40004,40005,40006,40007,17495,40008,19540,25672,
+40009,40010,40011,25671,25665,40012,25668,13613,40013,40014,21337,40015,25670,
+40016,40017,40018,40019,21113,13411,40020,15156,40021,40022,18798,40023,13374,
+40024,40025,40026,15212,40027,20813,40028,19565,27957,40029,40030,40031,40032,
+40033,40034,40035,40036,18277,40037,40038,40039,40040,21544,40041,25675,22357,
+25666,40042,15653,25669,40043,40044,21350,40045,25673,18808,40046,40047,25662,
+40048,40049,21349,40050,40051,18302,13897,40052,21628,12851,25687,40053,40054,
+40055,20034,40056,25677,40057,20028,40058,14427,40059,40060,25686,40061,16202,
+40062,40064,40065,21326,40066,17260,40067,40068,40069,40070,40071,40072,40073,
+40074,17736,25688,40075,40076,40077,40078,40079,40080,40081,40082,19780,25679,
+40083,40084,40085,40086,25684,25685,40087,14974,40088,20326,40089,40090,21823,
+40091,40092,40093,25682,40094,40095,40096,40097,40098,40099,40100,40101,40102,
+40103,40104,25680,40105,40106,25678,40107,40108,40109,40110,40111,40112,40113,
+40114,40115,40116,40117,40118,40119,40120,40121,19813,18986,40122,40123,40124,
+16419,40125,15654,25683,40126,40127,14408,40128,40129,40130,40131,40132,25703,
+21556,40133,40134,40135,40136,40137,40138,40139,25691,40140,40141,40142,16751,
+40143,40144,25705,40145,40146,21095,40147,40148,25695,40149,25696,40150,40151,
+20266,40152,40153,40154,40155,19293,40156,25690,25681,40157,25701,40158,18524,
+25699,40159,40160,17511,25698,40161,25697,40162,40163,40164,13180,25704,40165,
+40166,40167,40168,13665,40169,40170,40171,22348,40172,40173,40174,25702,40175,
+15148,40176,22354,19535,27512,40177,25700,40178,40179,14710,40180,40181,40182,
+22093,25689,25692,17018,25694,40183,16971,16452,16976,40184,12661,19506,40185,
+40186,40187,40188,40189,40190,40256,40257,40258,40259,13646,40260,40261,40262,
+40263,25711,40264,40265,40266,40267,40268,40269,40270,40271,17967,40272,40273,
+40274,18017,40275,40276,25717,40277,40278,40279,40280,40281,16937,40282,40283,
+40284,16492,20829,25710,40285,40286,40287,40288,40289,40290,40291,40292,40293,
+40294,17454,40295,40296,40297,25709,40298,40299,40300,40301,25718,25716,17022,
+40302,25693,40303,25712,40304,19070,40305,21828,40306,40307,25713,40308,40309,
+40310,40311,40312,40313,40314,20858,40315,40316,40317,40318,40320,40321,40322,
+25707,25708,40323,40324,40325,25714,40326,20011,40327,40328,40329,40330,40331,
+40332,40333,40334,40335,40336,17739,40337,40338,40339,18225,40340,16954,40341,
+40342,40343,25706,40344,40345,40346,16714,40347,40348,40349,40350,40351,40352,
+19510,13105,40353,40354,40355,25723,40356,25715,40357,40358,40359,25722,40360,
+25725,40361,25724,40362,40363,40364,40365,40366,40367,40368,13134,40369,40370,
+40371,13114,25719,40372,40373,25721,25720,17772,40374,40375,40376,40377,40378,
+40379,40380,40381,40382,40383,40384,40385,40386,16445,40387,40388,40389,40390,
+21608,40391,40392,40393,40394,40395,25890,40396,40397,40398,40399,40400,40401,
+40402,40403,40404,40405,40406,12356,40407,40408,25892,40409,40410,25891,40411,
+40412,40413,40414,40415,40416,15396,40417,25893,40418,40419,40420,40421,40422,
+40423,25889,40424,40425,40426,40427,40428,40429,40430,25726,12660,40431,40432,
+40433,40434,40435,40436,40437,40438,40439,40440,40441,25896,40442,25897,25894,
+40443,40444,40445,40446,40512,40513,40514,40515,40516,40517,40518,40519,25895,
+25898,40520,40521,40522,40523,40524,40525,40526,40527,40528,40529,40530,40531,
+40532,40533,40534,40535,40536,40537,40538,40539,40540,40541,40542,40543,40544,
+40545,40546,40547,40548,40549,40550,40551,40552,18009,40553,40554,40555,40556,
+40557,40558,40559,40560,25899,25901,40561,40562,40563,40564,40565,40566,40567,
+25900,40568,40569,40570,40571,40572,40573,40574,40576,40577,40578,40579,40580,
+40581,40582,40583,40584,40585,25903,40586,40587,40588,25902,40589,40590,40591,
+40592,40593,40594,40595,40596,40597,40598,40599,40600,40601,40602,40603,40604,
+40605,40606,14688,40607,40608,25904,40609,40610,40611,40612,40613,40614,40615,
+40616,40617,40618,40619,40620,40621,40622,25905,40623,40624,40625,40626,40627,
+40628,40629,40630,40631,40632,40633,40634,15216,27745,17264,40635,13638,15186,
+40636,40637,40638,40639,16745,21614,40640,15940,40641,40642,40643,22342,40644,
+21590,12883,27710,40645,40646,40647,40648,27201,40649,40650,40651,16943,13366,
+40652,40653,40654,20823,40655,40656,40657,13108,40658,18482,16187,27712,40659,
+40660,22091,40661,40662,27711,27713,40663,40664,40665,40666,40667,40668,40669,
+40670,40671,40672,40673,40674,40675,27717,15974,19519,17754,15932,40676,27718,
+40677,12670,40678,40679,40680,27716,21800,13667,40681,27714,16694,13155,40682,
+40683,27715,19256,16451,19582,40684,40685,40686,40687,16722,40688,27720,40689,
+40690,40691,40692,40693,40694,40695,40696,40697,40698,40699,40700,40701,14950,
+16467,40702,22130,40768,40769,40770,20812,40771,40772,40773,40774,16190,40775,
+14131,18773,27719,15202,40776,19532,15741,18504,40777,20265,40778,40779,40780,
+40781,40782,40783,40784,19817,40785,17771,40786,40787,40788,14185,40789,40790,
+40791,40792,40793,40794,40795,40796,40797,40798,40799,20809,14904,40800,40801,
+40802,40803,40804,27721,40805,40806,27722,40807,15168,27723,40808,27746,12602,
+14169,40809,40810,40811,40812,40813,40814,40815,40816,40817,40818,40819,15673,
+40820,40821,40822,40823,40824,40825,40826,40827,27724,20838,27725,40828,40829,
+40830,40832,18491,40833,40834,40835,40836,40837,40838,40839,40840,40841,40842,
+40843,40844,40845,40846,27729,40847,40848,40849,40850,27731,40851,15181,40852,
+15461,40853,40854,40855,40856,40857,40858,40859,40860,40861,40862,40863,40864,
+40865,27727,40866,18743,40867,40868,40869,40870,40871,17210,40872,27747,21845,
+27728,40873,40874,40875,40876,40877,22131,40878,40879,40880,27730,27726,40881,
+40882,40883,40884,27732,40885,27733,40886,40887,18751,40888,40889,40890,40891,
+40892,40893,20264,40894,40895,40896,40897,40898,20572,40899,40900,40901,40902,
+20780,40903,40904,40905,40906,18523,40907,40908,40909,27734,20085,40910,40911,
+40912,40913,40914,19052,27738,40915,40916,40917,40918,40919,40920,40921,27737,
+40922,40923,40924,12350,40925,40926,40927,40928,40929,40930,27735,40931,27736,
+40932,40933,40934,27748,40935,40936,40937,40938,40939,40940,40941,40942,40943,
+18492,40944,40945,40946,40947,40948,40949,40950,40951,40952,40953,16711,40954,
+40955,40956,40957,40958,27740,20832,41024,41025,41026,41027,41028,41029,41030,
+41031,41032,41033,27739,41034,41035,41036,41037,21615,41038,27741,41039,41040,
+41041,41042,41043,41044,23366,41045,41046,41047,41048,41049,41050,41051,41052,
+41053,41054,27742,41055,41056,41057,41058,41059,41060,41061,41062,41063,41064,
+41065,41066,12588,41067,41068,41069,41070,41071,41072,41073,41074,41075,41076,
+41077,41078,41079,41080,41081,41082,41083,41084,41085,41086,41088,41089,27743,
+41090,41091,41092,41093,41094,41095,41096,41097,41098,41099,27744,41100,22310,
+41101,17728,41102,41103,41104,27452,12334,41105,41106,41107,15988,14392,21039,
+12374,13689,41108,22579,41109,19244,41110,25437,41111,41112,41113,41114,41115,
+41116,41117,17964,12390,41118,41119,41120,17734,27449,41121,41122,41123,41124,
+27450,41125,41126,41127,27451,41128,41129,20800,41130,17699,41131,27250,41132,
+17458,41133,17461,16462,41134,41135,41136,27251,17473,41137,20079,41138,41139,
+41140,41141,27248,27252,41142,41143,18812,41144,41145,18211,41146,41147,41148,
+19544,20094,41149,41150,41151,27253,27254,20268,16487,41152,41153,27255,41154,
+41155,41156,41157,41158,13887,27256,41159,27257,41160,27258,41161,41162,27259,
+41163,41164,41165,41166,41167,41168,41169,41170,41171,41172,41173,41174,27249,
+41175,41176,41177,41178,41179,41180,41181,41182,41183,41184,41185,41186,18478,
+24939,41187,14136,24940,41188,41189,41190,24941,41191,22324,24942,24943,21324,
+41192,41193,41194,41195,41196,41197,41198,24945,16241,24944,13650,41199,41200,
+41201,12599,41202,41203,41204,41205,24947,24946,41206,14972,41207,24948,41208,
+41209,41210,41211,14647,41212,15953,41213,41214,43584,43585,17532,43586,14941,
+15686,43587,43588,43589,43590,43591,43592,24949,24951,43593,43594,13888,20289,
+18984,24950,21880,21372,24952,24956,24953,43595,43596,24954,16490,43597,24958,
+25121,16455,43598,43599,43600,43601,24955,43602,24957,43603,43604,43605,43606,
+43607,43608,25125,43609,43610,43611,16724,43612,43613,43614,43615,25123,43616,
+25128,12926,25122,43617,43618,43619,17229,12866,25127,25126,43620,43621,25124,
+25129,43622,43623,25131,43624,43625,43626,20553,22125,17192,25132,43627,20311,
+43628,43629,25134,43630,43631,14959,43632,43633,26976,25133,25130,43634,43635,
+43636,43637,15147,21555,43638,43639,43640,43641,43642,43643,43644,43645,43646,
+43648,43649,43650,43651,25136,43652,43653,25135,43654,26977,43655,43656,43657,
+43658,25137,43659,43660,43661,43662,43663,43664,43665,43666,25138,43667,43668,
+43669,43670,43671,43672,43673,43674,43675,43676,43677,25139,19489,43678,25140,
+43679,43680,43840,43841,43842,43843,43844,43845,43846,43847,43848,43849,43850,
+43851,25141,43852,43853,43854,43855,43856,20606,43857,43858,16970,43859,21361,
+43860,19829,43861,43862,26464,43863,43864,26465,43865,43866,43867,43868,15937,
+43869,43870,43871,43872,17002,43873,43874,43875,26468,43876,43877,26467,43878,
+43879,43880,43881,43882,43883,19814,43884,17205,43885,43886,26466,15159,20310,
+43887,16737,26473,43888,43889,43890,26472,43891,43892,26484,12835,43893,43894,
+43895,43896,26474,43897,26470,43898,43899,43900,43901,43902,26476,26475,18746,
+43904,43905,21860,43906,26469,14121,26471,43907,43908,43909,43910,43911,43912,
+43913,26478,43914,43915,43916,43917,26483,43918,22121,43919,43920,43921,43922,
+26477,43923,26482,43924,26481,43925,43926,43927,12384,43928,43929,43930,43931,
+26485,43932,43933,43934,43935,43936,44096,44097,44098,44099,44100,44101,44102,
+44103,44104,44105,44106,18290,44107,16453,16493,44108,44109,16752,26480,44110,
+44111,44112,44113,26486,19318,44114,44115,44116,44117,44118,44119,44120,44121,
+44122,26658,26657,44123,44124,44125,44126,44127,44128,22337,44129,44130,26490,
+26489,44131,26491,44132,26487,44133,26494,44134,26493,44135,26492,44136,44137,
+16725,18265,17789,17731,44138,44139,44140,44141,44142,18285,44143,44144,44145,
+44146,26659,44147,44148,44149,44150,44151,44152,44153,44154,44155,44156,44157,
+44158,44160,44161,44162,44163,44164,44165,44166,26662,44167,26661,44168,26663,
+14967,26488,26660,44169,18544,18730,44170,44171,44172,44173,44174,44175,44176,
+44177,44178,44179,44180,44181,44182,26665,44183,44184,14693,44185,44186,44187,
+44188,44189,20862,26664,44190,44191,44192,44352,44353,44354,26666,44355,26669,
+26670,44356,16679,44357,44358,44359,26671,44360,44361,44362,26672,44363,44364,
+26668,44365,26676,44366,44367,44368,44369,44370,44371,44372,44373,44374,44375,
+44376,26667,44377,26673,44378,44379,44380,44381,44382,44383,44384,44385,26677,
+26674,26675,44386,44387,44388,44389,44390,44391,44392,44393,44394,44395,44396,
+44397,44398,44399,44400,44401,26679,44402,44403,44404,44405,44406,44407,44408,
+44409,44410,44411,44412,44413,44414,44416,44417,44418,44419,44420,44421,44422,
+44423,44424,44425,26678,44426,44427,44428,44429,44430,44431,44432,44433,44434,
+14671,44435,28716,44436,28717,44437,17968,12394,18495,44438,19807,44439,44440,
+44441,44442,44443,44444,44445,20045,27185,44446,44447,44448,44608,27186,44609,
+17983,13385,44610,44611,44612,44613,44614,44615,44616,27187,44617,44618,44619,
+44620,21863,44621,44622,44623,44624,44625,44626,44627,44628,23929,44629,27188,
+44630,27189,44631,27190,44632,44633,44634,44635,14410,24368,18805,44636,19568,
+44637,44638,18810,44639,44640,44641,44642,44643,18811,44644,44645,21315,19238,
+44646,14374,28718,12610,44647,25912,19567,21321,15447,18794,44648,13671,44649,
+17488,13673,44650,28206,15149,44651,44652,26462,44653,28207,44654,44655,44656,
+44657,13097,44658,44659,28210,44660,44661,28209,15719,44662,28208,20023,44663,
+44664,44665,44666,17743,44667,44668,44669,44670,16756,23374,28211,20595,44672,
+44673,44674,44675,44676,44677,44678,44679,16980,18024,44680,44681,44682,14124,
+44683,44684,44685,44686,44687,44688,44689,28212,44690,13163,44691,44692,44693,
+15227,28213,44694,44695,44696,44697,44698,26460,44699,44700,44701,28214,44702,
+44703,15662,44704,44864,44865,44866,29026,44867,44868,44869,19048,44870,21065,
+28762,44871,28763,44872,28764,16710,44873,14445,15950,44874,44875,28766,44876,
+17713,28765,20849,44877,28768,12364,15722,44878,44879,44880,44881,44882,21087,
+28767,44883,13359,14184,28774,28773,17955,28769,28770,13379,44884,44885,28771,
+21870,44886,44887,19547,15954,15410,44888,44889,44890,28776,28775,28772,12833,
+44891,22050,21304,15927,18476,44892,44893,28778,44894,44895,44896,44897,20855,
+44898,22092,14939,28777,44899,13883,44900,44901,19764,44902,44903,17958,44904,
+44905,44906,16673,28779,28782,44907,28781,28784,28780,44908,15166,28783,44909,
+44910,44911,44912,19509,28786,44913,44914,13141,44915,44916,44917,44918,12628,
+44919,44920,28787,44921,44922,28788,28790,13409,44923,28785,44924,28791,44925,
+44926,44928,44929,28794,44930,28792,44931,44932,44933,28789,44934,44935,44936,
+44937,28797,44938,28793,28796,28798,44939,28961,44940,44941,44942,20033,28964,
+44943,28963,44944,16758,28795,19037,44945,44946,13425,12657,19505,44947,28966,
+44948,44949,28967,44950,44951,28972,21838,28969,44952,44953,18483,44954,44955,
+44956,28962,44957,28971,28968,28965,44958,44959,28970,44960,45120,45121,45122,
+45123,45124,45125,45126,12329,28973,45127,45128,45129,45130,45131,45132,28975,
+45133,28977,45134,45135,45136,45137,45138,28976,45139,28974,45140,45141,45142,
+45143,20770,45144,45145,45146,45147,45148,45149,45150,28978,45151,45152,45153,
+28979,45154,45155,45156,45157,45158,45159,45160,45161,14703,45162,45163,13639,
+45164,12375,12377,45165,45166,45167,21613,45168,13636,45169,15700,15178,28711,
+45170,45171,14430,45172,45173,28712,45174,45175,12328,45176,28713,45177,45178,
+19822,45179,45180,28714,45181,45182,45184,45185,45186,45187,45188,45189,45190,
+45191,28715,45192,45193,45194,45195,45196,45197,45198,45199,45200,17956,45201,
+45202,22117,29028,45203,29029,45204,45205,45206,45207,45208,45209,45210,45211,
+45212,45213,17267,45214,45215,21339,45216,45376,22097,17768,45377,21295,45378,
+21094,45379,45380,28225,12347,21813,20814,15456,14928,45381,16248,45382,14407,
+13633,17740,45383,45384,18978,45385,45386,45387,17227,45388,45389,45390,45391,
+45392,28226,45393,45394,45395,45396,45397,45398,45399,45400,17471,13858,45401,
+28012,17188,45402,22065,45403,45404,45405,20320,28015,45406,45407,17742,45408,
+13916,45409,45410,18977,45411,45412,28013,45413,45414,28016,28017,17212,45415,
+16180,45416,28014,45417,45418,45419,45420,45421,45422,45423,45424,45425,45426,
+45427,28020,28018,45428,45429,45430,45431,21862,17247,45432,28019,45433,45434,
+45435,28022,45436,21795,20771,45437,45438,45440,28021,45441,17232,45442,45443,
+45444,45445,45446,28023,16244,15980,28024,45447,19575,45448,20827,45449,45450,
+45451,22341,21878,45452,28028,45453,45454,45455,28027,45456,45457,45458,45459,
+45460,45461,45462,45463,28025,28026,45464,45465,45466,45467,45468,45469,45470,
+45471,28029,15910,45472,45632,45633,45634,45635,19247,28193,13885,45636,28194,
+17472,45637,28030,45638,45639,15710,12871,45640,45641,45642,45643,45644,45645,
+45646,45647,45648,45649,45650,45651,13891,45652,45653,45654,28197,22586,28195,
+28198,45655,45656,45657,17257,13170,45658,45659,45660,45661,45662,45663,28199,
+28196,20281,45664,45665,28200,17015,45666,45667,45668,45669,45670,45671,45672,
+45673,45674,45675,45676,45677,28201,28202,45678,24107,45679,45680,17971,45681,
+18246,45682,22133,13641,45683,19250,45684,45685,45686,28203,45687,45688,19755,
+45689,28204,45690,45691,45692,45693,45694,21808,45696,28205,45697,30276,45698,
+45699,45700,45701,45702,45703,45704,45705,45706,45707,45708,45709,45710,23367,
+45711,45712,45713,45714,45715,45716,45717,45718,45719,13347,45720,45721,45722,
+17196,29030,45723,45724,45725,45726,45727,19000,21075,45728,22058,45888,28530,
+45889,15960,45890,15683,28531,13900,12331,45891,45892,45893,45894,18991,45895,
+45896,27958,45897,27959,45898,45899,45900,45901,20089,14127,16243,27960,17003,
+18736,45902,45903,45904,45905,45906,45907,27961,45908,45909,18038,16179,45910,
+45911,45912,27964,17784,45913,20816,45914,22313,27962,27963,45915,20834,45916,
+27967,27968,45917,27972,45918,45919,45920,27976,45921,27974,27982,21864,45922,
+27977,45923,45924,27975,27966,45925,45926,17769,45927,45928,45929,17990,45930,
+45931,18793,21586,27969,27970,27971,27973,45932,16505,45933,13345,45934,45935,
+45936,45937,14696,45938,27984,45939,45940,45941,45942,27985,45943,27978,45944,
+27983,45945,20088,45946,45947,19254,27980,27981,45948,45949,45950,45952,45953,
+20341,45954,45955,45956,45957,45958,45959,45960,45961,45962,45963,45964,45965,
+27986,16754,21298,27979,18487,45966,45967,45968,45969,45970,45971,45972,45973,
+15471,45974,45975,45976,45977,17776,45978,45979,45980,45981,45982,45983,45984,
+46144,46145,46146,27990,46147,13679,46148,46149,16949,12333,19305,46150,46151,
+12590,46152,27988,46153,46154,46155,19819,13666,46156,27989,27987,27991,46157,
+46158,13690,46159,27992,46160,27993,46161,27996,46162,12620,46163,46164,46165,
+46166,46167,46168,46169,46170,17782,15470,27994,19516,12906,46171,46172,46173,
+46174,27995,46175,46176,46177,46178,17515,46179,46180,13381,46181,46182,46183,
+12405,46184,46185,46186,27999,16474,13416,46187,46188,46189,46190,17741,46191,
+46192,46193,27997,16196,46194,46195,46196,27998,46197,46198,46199,46200,46201,
+46202,46203,46204,46205,46206,46208,46209,46210,46211,17445,46212,46213,46214,
+28000,46215,46216,46217,46218,46219,28001,46220,28003,46221,46222,16727,46223,
+46224,15175,46225,46226,46227,46228,46229,46230,15672,46231,46232,46233,28002,
+46234,46235,46236,46237,46238,46239,46240,46400,46401,46402,46403,46404,46405,
+28004,46406,46407,46408,46409,46410,46411,46412,46413,46414,46415,28006,46416,
+46417,46418,46419,46420,28005,46421,46422,46423,46424,46425,46426,46427,46428,
+46429,46430,46431,46432,46433,46434,46435,28007,46436,46437,46438,46439,46440,
+19006,27754,16497,46441,18791,46442,27755,18030,46443,46444,46445,46446,27756,
+46447,18029,27757,46448,46449,46450,46451,46452,46453,46454,46455,46456,27760,
+46457,46458,22374,27763,46459,46460,27761,27758,27759,22307,18801,19310,27764,
+46461,27762,46462,46464,20329,46465,27766,17969,46466,46467,46468,46469,15424,
+46470,27765,46471,46472,46473,46474,46475,46476,46477,13627,15222,46478,27767,
+46479,46480,46481,46482,46483,22903,15739,46484,46485,16955,27768,46486,46487,
+46488,46489,27769,46490,46491,46492,46493,14371,46494,46495,46496,46656,46657,
+46658,46659,46660,46661,46662,27770,46663,46664,46665,46666,46667,46668,46669,
+46670,46671,46672,46673,46674,27771,46675,46676,46677,46678,46679,46680,46681,
+46682,46683,46684,46685,27772,46686,46687,46688,46689,46690,21357,22574,16491,
+46691,18269,14924,46692,20579,19261,46693,19770,46694,46695,14417,46696,46697,
+12668,46698,18287,46699,22102,46700,46701,46702,16198,17259,46703,46704,28533,
+46705,46706,17240,46707,46708,46709,46710,46711,46712,22370,46713,46714,46715,
+28535,13139,46716,18264,20845,46717,22088,46718,28536,46720,28534,46721,15229,
+13126,46722,46723,46724,46725,46726,46727,46728,15701,46729,46730,21062,46731,
+15200,46732,46733,20257,46734,28540,28539,46735,46736,28537,46737,46738,46739,
+46740,13132,46741,18772,19248,46742,46743,46744,46745,46746,28542,46747,46748,
+12382,46749,46750,22089,46751,46752,46912,28541,46913,13165,46914,46915,30293,
+46916,46917,46918,46919,46920,46921,46922,46923,46924,46925,46926,46927,46928,
+46929,46930,20040,46931,46932,46933,28706,46934,28705,46935,13630,15450,15228,
+46936,14437,46937,46938,46939,46940,46941,46942,17474,46943,46944,46945,46946,
+46947,46948,46949,46950,46951,46952,28707,46953,46954,46955,46956,46957,19307,
+46958,46959,46960,46961,46962,46963,46964,46965,46966,46967,46968,46969,46970,
+46971,46972,46973,46974,46976,46977,46978,46979,46980,46981,46982,28710,46983,
+46984,46985,20776,46986,15935,18286,28982,28983,16213,46987,46988,46989,46990,
+13353,28984,19771,46991,18260,21805,46992,28985,46993,28986,46994,46995,46996,
+46997,18255,46998,46999,47000,21028,22095,47001,47002,28987,15697,13360,15933,
+47003,47004,47005,13404,20049,47006,16223,28989,47007,47008,47168,47169,16250,
+28988,47170,28991,47171,47172,47173,28990,28992,47174,47175,47176,47177,47178,
+28993,47179,47180,47181,47182,47183,47184,47185,47186,47187,47188,47189,16766,
+47190,47191,47192,47193,47194,47195,47196,47197,47198,47199,47200,16674,47201,
+47202,47203,47204,47205,47206,47207,47208,47209,47210,19066,47211,47212,21822,
+47213,47214,47215,47216,15930,15929,21826,47217,47218,16162,47219,19759,28981,
+47220,47221,47222,47223,47224,47225,15711,47226,13899,47227,47228,47229,47230,
+47232,47233,47234,47235,47236,22129,29507,47237,47238,29508,47239,14413,47240,
+47241,47242,29510,29511,47243,12362,47244,29509,47245,29513,19313,47246,47247,
+47248,29515,47249,20518,47250,47251,12618,29512,47252,47253,47254,29519,47255,
+13649,47256,47257,29527,47258,29522,47259,47260,47261,29524,29523,14203,47262,
+12607,47263,29518,29514,13658,47264,29520,47424,47425,29521,47426,29525,47427,
+47428,47429,47430,29517,47431,15459,47432,16765,47433,29526,47434,47435,47436,
+47437,47438,47439,29530,47440,29516,47441,13640,47442,15726,29532,47443,47444,
+14116,16240,22142,19762,47445,13424,47446,12895,47447,29528,47448,29529,18744,
+47449,29533,47450,47451,29534,47452,29537,47453,47454,47455,47456,47457,47458,
+47459,47460,47461,47462,47463,29535,47464,47465,29539,29538,47466,47467,29531,
+47468,16234,47469,13167,47470,29536,47471,47472,18217,47473,15474,47474,47475,
+47476,47477,29547,47478,47479,47480,47481,47482,47483,47484,14655,47485,47486,
+29540,47488,47489,47490,12845,15230,47491,19299,47492,47493,47494,47495,29549,
+29545,47496,47497,47498,14684,29550,47499,47500,47501,29541,29542,29546,16993,
+29548,29551,29544,15485,47502,47503,47504,20324,47505,47506,29552,47507,47508,
+47509,29543,47510,47511,47512,47513,47514,47515,47516,47517,29554,47518,47519,
+47520,47680,22317,17962,47681,47682,47683,47684,29555,47685,47686,47687,47688,
+29553,47689,16936,47690,47691,47692,47693,47694,14429,29557,47695,47696,29556,
+47697,47698,47699,13403,47700,47701,47702,29558,29559,47703,47704,47705,29560,
+47706,47707,47708,16442,47709,47710,16489,47711,47712,47713,47714,47715,17777,
+47716,47717,47718,47719,29563,47720,29562,47721,47722,47723,47724,47725,47726,
+47727,47728,13400,47729,47730,47731,29566,29561,47732,47733,29564,47734,47735,
+47736,47737,47738,47739,29565,47740,47741,47742,47744,47745,47746,47747,47748,
+29729,47749,47750,47751,47752,47753,47754,29731,15177,47755,47756,29730,47757,
+47758,47759,47760,47761,47762,47763,47764,47765,47766,47767,47768,47769,29732,
+47770,47771,47772,47773,47774,47775,12862,29734,29733,47776,47936,47937,47938,
+47939,47940,47941,47942,47943,47944,47945,15406,47946,47947,47948,47949,47950,
+47951,47952,47953,47954,47955,47956,47957,47958,47959,47960,47961,47962,47963,
+47964,47965,47966,47967,47968,47969,47970,47971,47972,47973,47974,47975,47976,
+47977,47978,47979,47980,47981,47982,17239,22881,47983,47984,47985,47986,47987,
+47988,16480,29772,22353,47989,47990,47991,47992,47993,47994,47995,47996,47997,
+47998,48000,14171,48001,48002,48003,48004,48005,48006,48007,29774,16675,48008,
+48009,17993,48010,13398,21811,48011,48012,48013,29776,29775,29777,19290,48014,
+48015,29778,48016,21569,22112,48017,48018,48019,48020,14176,48021,48022,48023,
+16696,48024,48025,16699,29779,15916,48026,48027,48028,48029,48030,13410,48031,
+48032,29780,29781,15915,48192,48193,29782,48194,48195,48196,29787,48197,29783,
+29786,48198,14973,48199,29784,29785,48200,48201,48202,48203,48204,48205,48206,
+14434,19527,29788,48207,12890,48208,48209,17235,48210,48211,21603,16183,48212,
+48213,48214,48215,48216,48217,48218,29789,48219,48220,48221,48222,48223,48224,
+17716,48225,48226,48227,48228,48229,48230,48231,48232,29801,48233,48234,20277,
+48235,48236,48237,48238,48239,48240,48241,48242,48243,48244,48245,48246,48247,
+48248,20041,48249,48250,48251,48252,48253,48254,48256,48257,48258,48259,48260,
+48261,48262,48263,48264,48265,48266,48267,48268,48269,48270,19288,48271,19319,
+48272,48273,48274,48275,15732,48276,48277,48278,22351,48279,48280,48281,16475,
+48282,48283,48284,48285,48286,48287,48288,48448,48449,48450,48451,48452,48453,
+48454,48455,48456,48457,48458,48459,48460,48461,48462,48463,48464,48465,48466,
+48467,48468,48469,48470,48471,48472,48473,48474,48475,48476,48477,48478,48479,
+48480,48481,48482,48483,48484,48485,48486,48487,48488,48489,48490,48491,48492,
+48493,48494,48495,48496,48497,48498,48499,48500,48501,48502,20597,48503,48504,
+48505,48506,48507,48508,48509,48510,29802,48512,48513,48514,48515,48516,48517,
+48518,48519,48520,48521,48522,48523,48524,48525,48526,48527,48528,48529,48530,
+48531,48532,48533,48534,48535,48536,48537,48538,48539,48540,48541,48542,48543,
+48544,48704,48705,48706,48707,48708,48709,48710,48711,48712,48713,48714,48715,
+48716,29803,48717,48718,48719,48720,48721,48722,48723,29804,48724,48725,48726,
+48727,48728,48729,48730,48731,48732,48733,48734,48735,48736,48737,48738,48739,
+48740,48741,48742,48743,48744,48745,48746,48747,48748,48749,48750,48751,48752,
+48753,48754,48755,48756,48757,48758,48759,48760,48761,48762,48763,48764,48765,
+48766,48768,48769,48770,48771,48772,48773,48774,48775,48776,48777,48778,48779,
+48780,48781,48782,48783,48784,48785,48786,48787,48788,48789,48790,48791,48792,
+48793,48794,48795,48796,48797,48798,48799,48800,48960,48961,48962,48963,48964,
+48965,48966,48967,48968,48969,48970,48971,48972,48973,48974,48975,48976,48977,
+48978,48979,48980,48981,48982,48983,48984,48985,48986,48987,48988,48989,48990,
+48991,48992,48993,48994,48995,48996,48997,48998,48999,49000,49001,49002,49003,
+49004,49005,49006,49007,49008,49009,49010,49011,49012,49013,49014,49015,49016,
+49017,49018,49019,49020,49021,49022,49024,30563,49025,49026,49027,49028,49029,
+14129,49030,49031,49032,49033,49034,29805,49035,49036,49037,49038,49039,49040,
+49041,49042,49043,49044,49045,49046,49047,49048,49049,49050,49051,49052,49053,
+49054,49055,49056,49216,49217,49218,49219,49220,49221,49222,49223,49224,49225,
+49226,49227,49228,49229,49230,49231,49232,49233,49234,49235,49236,49237,49238,
+49239,49240,49241,49242,49243,49244,49245,49246,49247,49248,49249,49250,49251,
+22379,49252,49253,49254,49255,49256,49257,49258,49259,49260,49261,49262,49263,
+49264,49265,49266,49267,49268,49269,49270,49271,49272,49273,49274,49275,29806,
+49276,49277,49278,26233,15936,26234,14956,26235,20299,26236,21564,15414,26237,
+26238,15437,18514,20019,26401,49280,13375,26402,18740,14425,17481,49281,22365,
+16986,14167,22077,20038,14148,49282,49283,17702,26403,20319,26404,26405,26406,
+16695,22377,18800,20280,22063,22101,26407,12397,26408,26409,18780,21103,15917,
+26410,12403,18526,15713,26411,18502,49284,26412,15206,14456,20772,26413,16999,
+15992,15690,19763,26414,26415,15982,20581,49285,19303,19536,15436,26416,15400,
+20599,26417,49286,20600,26418,26419,13378,26420,26421,18814,20012,17248,26423,
+12609,13169,49287,26424,26425,22363,21824,26426,16972,22330,26427,26428,26429,
+15466,17253,16450,26430,26431,15401,49288,26432,26433,26422,13904,26434,49289,
+26435,26436,15162,13662,16966,12640,26437,21557,26438,14399,26440,26439,14188,
+49290,26441,12920,26442,26443,26444,26445,26446,26447,26448,21287,19317,26449,
+26450,26451,26452,18761,26453,26454,26455,26456,26457,15689,26458,29502,49291,
+14423,49292,18481,49293,49294,49295,49296,49297,49298,49299,29503,49300,29504,
+29505,49301,49302,49303,49304,49305,49306,49307,49308,49309,49310,14686,19832,
+49311,49312,22632,14897,49472,16990,28215,49473,14115,49474,49475,49476,49477,
+28217,49478,28216,12373,49479,49480,49481,49482,49483,28219,21846,22383,49484,
+49485,49486,22083,49487,49488,28221,19056,49489,28220,49490,49491,49492,49493,
+28222,49494,49495,49496,49497,28224,49498,49499,28223,49500,49501,49502,49503,
+49504,49505,49506,49507,20850,49508,18236,49509,17216,49510,49511,49512,49513,
+49514,14433,49515,49516,49517,49518,49519,16743,49520,49521,29766,20575,29767,
+49522,20315,49523,49524,18490,49525,49526,29768,49527,49528,49529,49530,49531,
+49532,49533,29769,29770,49534,29771,49536,49537,49538,49539,49540,22906,14462,
+49541,49542,25969,21360,49543,29792,49544,20044,49545,49546,49547,13153,49548,
+49549,49550,49551,28980,49552,21102,49553,29793,49554,49555,49556,49557,49558,
+20328,29794,49559,49560,18252,49561,49562,49563,49564,49565,49566,13652,13412,
+29796,49567,49568,49728,29795,29797,49729,49730,29798,49731,49732,49733,49734,
+29799,49735,14898,12351,49736,29800,49737,49738,49739,49740,49741,49742,49743,
+14125,21101,49744,49745,49746,21035,16463,49747,16188,27427,21855,27208,49748,
+49749,49750,49751,29043,13944,19235,49752,49753,17485,49754,29031,49755,29032,
+14459,29033,14916,21573,12370,49756,49757,29034,49758,49759,49760,29035,49761,
+29036,49762,49763,29037,29038,29039,29041,29040,17749,49764,49765,49766,49767,
+49768,49769,29042,49770,13946,49771,29044,21038,24135,19274,49772,49773,13148,
+49774,13602,49775,14626,49776,49777,17524,29045,49778,49779,29046,49780,49781,
+49782,16708,16763,22064,29047,49783,49784,49785,49786,29048,49787,16682,49788,
+49789,49790,17976,49792,15963,49793,49794,49795,49796,49797,49798,49799,49800,
+49801,49802,49803,49804,49805,49806,29049,13391,49807,49808,49809,49810,49811,
+49812,29050,49813,49814,49815,49816,49817,49818,49819,49820,49821,49822,49823,
+49824,49984,27954,27953,49985,49986,19296,21086,49987,19265,21848,49988,18530,
+49989,16479,15393,49990,49991,49992,49993,49994,49995,27457,49996,49997,20516,
+49998,22114,49999,13895,14424,27456,14414,50000,27455,13094,14665,22059,50001,
+14196,14154,50002,50003,50004,15463,14142,27462,50005,27463,12345,16207,50006,
+27461,21373,50007,27464,50008,50009,27465,50010,50011,14158,50012,27458,27460,
+18806,22103,21837,20530,27471,20024,27472,50013,13608,50014,50015,50016,50017,
+50018,12595,27474,19493,50019,50020,50021,50022,50023,50024,50025,17750,27475,
+50026,27473,17759,27470,18980,27477,12411,50027,50028,14970,50029,50030,22583,
+29027,50031,27466,27467,27468,27469,27478,26176,27481,50032,16232,21064,27479,
+27484,14444,27480,50033,15674,50034,20568,50035,12343,50036,27485,17500,50037,
+50038,50039,50040,22060,50041,50042,50043,13408,50044,50045,17014,15417,50046,
+50048,27482,27483,21600,18026,17492,27487,17703,22901,50049,12849,50050,27492,
+50051,15685,50052,50053,50054,27490,50055,50056,50057,50058,50059,50060,50061,
+50062,50063,50064,50065,50066,50067,27491,50068,50069,14380,50070,19793,27493,
+50071,50072,50073,27489,50074,16691,50075,50076,50077,50078,50079,17954,50080,
+50240,50241,50242,50243,50244,50245,19571,50246,27494,50247,16432,21048,27495,
+50248,50249,50250,14383,14381,50251,27496,18235,19827,50252,50253,50254,27498,
+27499,50255,50256,50257,50258,50259,27501,50260,50261,50262,50263,20552,50264,
+27506,50265,27502,50266,50267,50268,27505,18553,50269,20860,27500,50270,50271,
+27497,50272,50273,50274,50275,14393,20313,17509,27503,27504,19546,19784,12402,
+50276,27510,50277,50278,50279,50280,50281,27509,50282,12850,50283,50284,50285,
+50286,14432,50287,27511,50288,50289,50290,50291,50292,50293,12652,50294,50295,
+19525,17444,20261,50296,50297,50298,50299,50300,27513,50301,50302,27682,50304,
+17778,50305,27514,50306,50307,50308,50309,50310,50311,50312,50313,18757,50314,
+50315,50316,50317,50318,50319,25183,27518,50320,50321,50322,50323,19790,27681,
+12635,21303,50324,50325,21084,50326,50327,50328,27517,50329,27515,50330,50331,
+50332,50333,50334,50335,50336,50496,50497,50498,50499,50500,50501,50502,50503,
+50504,50505,50506,50507,50508,50509,50510,13116,50511,50512,50513,27184,50514,
+50515,22356,50516,29739,13172,50517,50518,50519,50520,50521,22081,22082,50522,
+50523,50524,50525,50526,50527,21865,15946,50528,29735,50529,21032,29736,29737,
+50530,29738,15947,21343,50531,50532,50533,50534,50535,18784,18785,50536,50537,
+29506,50538,19046,50539,19570,50540,50541,50542,50543,50544,50545,25142,19252,
+50546,20072,22107,50547,29741,29742,29743,50548,50549,50550,50551,29746,50552,
+14909,29747,12387,29744,50553,29745,15650,12885,50554,29750,29751,13926,12848,
+20303,29748,13356,50555,29749,50556,50557,29752,50558,50560,50561,50562,50563,
+29753,50564,50565,19751,50566,29754,50567,29755,50568,50569,50570,29756,50571,
+50572,50573,50574,50575,50576,50577,50578,19282,50579,29757,50580,50581,50582,
+50583,29758,50584,50585,50586,50587,50588,50589,50590,50591,29759,50592,50752,
+50753,50754,50755,29790,16700,15464,50756,18731,20830,25973,50757,50758,50759,
+50760,23603,21077,50761,50762,23604,12332,23605,50763,50764,15706,50765,23609,
+50766,50767,50768,22594,50769,23607,21363,50770,18774,23610,23606,50771,23611,
+17186,50772,50773,50774,50775,23612,23621,23613,50776,50777,20063,22053,50778,
+23631,50779,23629,50780,50781,23634,15718,16939,50782,23608,23627,23630,23614,
+14162,12357,23623,20542,23617,15144,50783,14140,23628,50784,50785,23622,23615,
+18267,50786,50787,50788,20799,23616,50789,50790,23626,50791,50792,23632,50793,
+50794,20013,23618,50795,23619,23624,23625,12884,23633,19285,50796,21559,23643,
+23647,19494,23654,50797,17255,23644,50798,50799,16193,23641,50800,12410,14646,
+23653,23635,50801,23620,23638,18548,16224,50802,50803,50804,50805,18747,50806,
+50807,50808,12605,50809,21282,50810,50811,23642,50812,50813,23637,50814,17979,
+50816,23646,50817,50818,50819,50820,50821,22338,17199,14134,18257,17193,23650,
+23640,23659,23636,50822,50823,23645,50824,15909,23639,50825,23648,50826,50827,
+23651,23652,50828,23672,50829,50830,23649,23842,23655,50831,50832,50833,50834,
+50835,50836,50837,50838,50839,50840,15467,13380,50841,50842,17187,12903,23674,
+50843,23666,50844,23663,50845,23676,23662,21104,12904,50846,18519,18531,23675,
+50847,23661,50848,51008,51009,23671,51010,51011,23669,51012,51013,15907,23668,
+51014,12893,51015,51016,51017,51018,51019,23667,15478,23656,15172,51020,16499,
+51021,51022,51023,51024,51025,15444,23657,23658,51026,23665,23670,23673,13620,
+51027,18521,15207,23678,23677,21291,23841,23843,23845,21105,23844,23846,23847,
+21033,51028,51029,51030,51031,51032,51033,51034,14921,23849,51035,51036,23862,
+23857,23860,51037,51038,51039,51040,51041,51042,51043,23856,17998,51044,51045,
+16498,51046,51047,51048,51049,18735,51050,51051,51052,23660,23854,51053,51054,
+51055,51056,23863,51057,51058,23664,23855,51059,23864,51060,23852,51061,51062,
+51063,51064,51065,51066,51067,23865,23859,23853,17450,51068,51069,51070,51072,
+23848,16435,16683,23850,23851,51073,23858,15217,23861,21288,23866,51074,23867,
+17191,51075,51076,23890,23868,51077,51078,51079,23889,51080,14653,51081,51082,
+15957,51083,15994,51084,51085,14922,51086,51087,51088,51089,23882,51090,23877,
+51091,23871,51092,51093,51094,12875,23875,51095,23883,12836,23893,51096,51097,
+51098,23870,51099,51100,51101,18000,23888,51102,51103,51104,51264,51265,23892,
+16738,14150,51266,51267,51268,51269,51270,23886,23887,51271,51272,51273,23876,
+51274,51275,51276,23869,51277,23885,19537,51278,23881,51279,51280,51281,51282,
+23874,17224,17980,20014,23884,51283,23880,51284,51285,51286,51287,51288,51289,
+23873,51290,51291,51292,23878,16988,51293,51294,51295,51296,51297,51298,21289,
+21290,23891,20340,18552,51299,51300,51301,51302,51303,51304,51305,51306,23910,
+51307,51308,51309,51310,51311,51312,23879,51313,51314,51315,23904,16996,51316,
+51317,51318,51319,51320,51321,51322,51323,23905,51324,51325,51326,51328,51329,
+51330,51331,51332,51333,51334,23895,51335,51336,51337,51338,51339,22136,51340,
+23897,23896,14448,23894,51341,51342,51343,51344,17999,51345,13869,51346,51347,
+51348,51349,51350,23906,51351,14969,21601,23911,51352,51353,51354,13392,51355,
+23898,51356,16251,23907,51357,23903,51358,23901,51359,51360,51520,51521,51522,
+51523,51524,13657,51525,51526,51527,51528,23899,23900,23902,51529,15663,23908,
+51530,23909,51531,51532,51533,51534,51535,51536,51537,51538,23925,51539,17225,
+51540,51541,19298,51542,51543,51544,51545,23922,51546,51547,51548,51549,51550,
+51551,51552,51553,51554,51555,51556,51557,51558,22625,51559,51560,18001,51561,
+23924,51562,51563,51564,21876,23923,23920,51565,51566,23916,51567,23919,51568,
+23912,51569,51570,20590,51571,51572,51573,51574,18520,23918,51575,51576,23913,
+51577,51578,23914,19314,51579,23917,51580,51581,12621,51582,51584,51585,51586,
+51587,51588,16438,51589,15419,23921,51590,51591,23927,51592,23926,23915,51593,
+51594,51595,51596,51597,17774,51598,51599,51600,23931,51601,51602,51603,51604,
+51605,51606,51607,51608,51609,51610,51611,24100,51612,51613,24099,51614,51615,
+51616,51776,51777,51778,51779,51780,51781,51782,51783,51784,23928,51785,51786,
+51787,51788,17263,51789,17019,51790,51791,51792,21857,51793,51794,20021,51795,
+51796,51797,51798,23933,51799,12876,51800,51801,51802,51803,51804,51805,51806,
+51807,51808,17512,19039,51809,51810,51811,51812,51813,51814,51815,51816,51817,
+51818,18238,23930,23932,23934,24098,12330,12622,51819,51820,51821,51822,51823,
+24108,51824,51825,51826,51827,24102,15670,18543,51828,51829,51830,51831,51832,
+51833,51834,51835,51836,51837,51838,24097,51840,51841,24101,51842,51843,51844,
+51845,24105,51846,51847,51848,51849,51850,24104,51851,51852,51853,24103,51854,
+51855,51856,51857,51858,51859,51860,51861,51862,24109,51863,21580,51864,51865,
+51866,51867,24115,24106,24110,51868,51869,16473,51870,51871,51872,52032,52033,
+12577,24118,52034,24113,52035,52036,52037,52038,52039,52040,52041,24114,52042,
+52043,52044,52045,52046,52047,52048,52049,52050,52051,52052,20774,24117,52053,
+52054,52055,52056,52057,52058,52059,24111,52060,52061,52062,24112,52063,20541,
+52064,52065,52066,24116,19053,24121,52067,52068,52069,52070,52071,52072,24120,
+52073,24119,52074,52075,52076,52077,52078,52079,52080,24123,52081,52082,52083,
+52084,52085,52086,52087,15717,52088,52089,52090,52091,52092,12888,17258,52093,
+52094,24122,52096,17722,52097,52098,52099,52100,52101,52102,24124,52103,52104,
+52105,52106,52107,52108,52109,19545,52110,52111,52112,52113,14122,52114,52115,
+52116,52117,52118,52119,52120,52121,52122,52123,52124,52125,52126,52127,52128,
+52288,52289,21605,52290,52291,52292,24125,52293,52294,52295,52296,52297,24127,
+52298,52299,52300,52301,52302,52303,52304,52305,52306,52307,52308,17442,52309,
+52310,52311,52312,24129,52313,52314,52315,52316,52317,52318,52319,52320,52321,
+52322,52323,52324,52325,52326,52327,52328,24126,52329,24128,52330,52331,52332,
+52333,52334,52335,52336,52337,52338,52339,52340,52341,52342,52343,21818,52344,
+52345,52346,24130,52347,52348,52349,52350,52352,52353,52354,52355,52356,52357,
+52358,52359,52360,52361,52362,52363,29230,15138,16946,17712,16967,52364,52365,
+29231,52366,52367,52368,52369,52370,20585,52371,52372,52373,21341,52374,52375,
+52376,27453,52377,52378,52379,52380,52381,52382,52383,52384,13158,29232,52544,
+29233,52545,52546,18989,52547,52548,52549,52550,52551,52552,52553,14951,29235,
+29237,29236,19300,20282,29234,18996,21071,17004,52554,52555,52556,52557,52558,
+52559,52560,20035,29240,12406,29239,52561,52562,52563,52564,52565,29246,52566,
+12879,52567,52568,52569,52570,52571,52572,20801,29242,52573,52574,52575,52576,
+52577,29244,21609,52578,52579,29243,29238,29247,29245,52580,29241,52581,52582,
+29255,29252,29254,52583,52584,29258,29250,29248,52585,52586,52587,29253,52588,
+52589,52590,52591,52592,22139,52593,52594,52595,29249,52596,18297,18783,52597,
+29256,14662,13616,52598,52599,29251,29257,29264,29270,52600,52601,15191,52602,
+52603,52604,29269,19804,52605,22123,52606,52608,29266,29268,52609,52610,52611,
+52612,14450,52613,52614,52615,52616,29259,52617,52618,52619,29262,17017,52620,
+21853,29260,29261,29263,29267,52621,52622,52623,29273,21308,52624,52625,52626,
+52627,13930,52628,19057,52629,14180,29271,52630,52631,52632,29272,29274,29277,
+29275,52633,52634,29276,52635,52636,52637,52638,20817,29265,52639,19785,52640,
+20047,22057,52800,29283,52801,17243,52802,29280,52803,52804,16431,29292,29278,
+52805,29281,52806,52807,52808,29288,52809,52810,52811,52812,29282,52813,52814,
+29287,52815,52816,29286,52817,52818,29289,52819,52820,52821,29279,52822,52823,
+29284,29290,52824,52825,52826,52827,52828,52829,52830,21292,29285,12917,52831,
+52832,29298,52833,20523,52834,52835,52836,52837,29301,52838,52839,52840,15176,
+52841,29305,52842,52843,52844,52845,52846,52847,29296,52848,52849,29302,29304,
+29306,52850,52851,52852,52853,52854,52855,52856,52857,29299,52858,29297,52859,
+52860,52861,14971,52862,13691,52864,52865,52866,52867,29295,29303,29293,29294,
+52868,52869,52870,29291,29478,52871,29475,52872,52873,29474,52874,52875,29300,
+52876,18522,52877,52878,52879,52880,52881,29307,52882,52883,52884,29477,52885,
+52886,52887,52888,52889,52890,52891,17272,52892,52893,52894,52895,52896,53056,
+53057,53058,29309,53059,53060,29479,29481,29476,53061,29308,53062,53063,53064,
+29483,53065,29482,53066,53067,53068,53069,16989,53070,53071,29486,53072,53073,
+29488,53074,53075,53076,53077,53078,29473,53079,53080,53081,29489,29484,53082,
+53083,53084,53085,53086,29487,29310,29485,53087,53088,53089,53090,53091,53092,
+53093,29490,53094,53095,53096,53097,29492,53098,53099,53100,53101,29480,53102,
+53103,53104,53105,29491,53106,53107,53108,29493,53109,53110,53111,53112,53113,
+53114,53115,53116,53117,53118,20535,53120,53121,53122,53123,29496,53124,53125,
+53126,53127,22905,53128,53129,53130,53131,53132,53133,29497,53134,53135,53136,
+53137,53138,53139,53140,53141,29495,53142,18532,29494,53143,53144,53145,53146,
+29498,53147,53148,53149,53150,53151,29499,13376,53152,53312,53313,53314,53315,
+53316,53317,53318,53319,53320,53321,53322,53323,53324,53325,28227,53326,53327,
+53328,53329,53330,53331,29500,53332,53333,29501,53334,53335,53336,20778,53337,
+53338,53339,29740,20550,53340,53341,53342,53343,53344,53345,20560,20828,53346,
+53347,53348,53349,53350,53351,20302,53352,53353,15702,53354,20803,53355,53356,
+53357,53358,53359,53360,53361,14946,24937,21058,28994,12857,53362,53363,12653,
+28995,53364,18752,13124,53365,22898,53366,19237,53367,28996,53368,53369,53370,
+53371,22100,53372,53373,53374,53376,53377,28997,29760,28998,53378,21548,28999,
+53379,12352,29761,53380,53381,29762,53382,53383,13436,53384,17755,53385,53386,
+53387,53388,19515,53389,53390,53391,20580,53392,53393,53394,53395,53396,19808,
+53397,53398,53399,53400,53401,29000,53402,22899,53403,53404,53405,53406,53407,
+53408,12603,53568,20270,53569,53570,53571,14372,53572,53573,53574,53575,53576,
+29002,53577,53578,53579,53580,29003,53581,53582,53583,53584,12867,16721,53585,
+53586,22320,29001,53587,53588,29004,53589,53590,53591,53592,29006,53593,53594,
+53595,22902,53596,21089,21539,53597,53598,29763,18489,53599,53600,53601,53602,
+53603,29764,53604,53605,29005,29007,16227,29008,53606,53607,29012,53608,53609,
+53610,53611,53612,53613,53614,29014,29009,53615,18769,17761,53616,53617,53618,
+16995,14716,53619,53620,29011,53621,29013,53622,53623,53624,14675,53625,53626,
+53627,53628,53629,53630,53632,29019,53633,53634,53635,53636,53637,14934,53638,
+12413,29017,53639,53640,53641,53642,53643,29016,29010,29018,53644,53645,53646,
+53647,53648,29015,53649,53650,53651,18540,53652,53653,53654,53655,19786,29021,
+53656,53657,53658,53659,25917,53660,53661,53662,29020,53663,29022,53664,53824,
+53825,53826,53827,53828,53829,53830,53831,53832,29023,53833,53834,20325,53835,
+53836,53837,53838,53839,53840,53841,53842,53843,53844,53845,53846,53847,53848,
+53849,53850,53851,53852,53853,53854,53855,53856,53857,53858,53859,29765,15731,
+53860,53861,53862,53863,53864,53865,29024,53866,53867,53868,53869,53870,53871,
+53872,53873,53874,53875,53876,53877,53878,53879,53880,53881,53882,53883,53884,
+53885,29025,53886,53888,53889,20087,53890,21034,53891,29051,53892,53893,14386,
+53894,53895,53896,53897,53898,53899,53900,53901,53902,53903,53904,53905,53906,
+53907,53908,53909,53910,53911,53912,53913,53914,53915,53916,53917,53918,53919,
+53920,54080,54081,54082,54083,54084,54085,54086,54087,54088,54089,54090,54091,
+54092,54093,54094,54095,54096,54097,54098,54099,54100,54101,54102,54103,54104,
+54105,54106,54107,54108,54109,54110,15483,14683,54111,14694,17241,19027,27240,
+16448,15989,27241,27242,27243,54112,27244,27245,27246,27247,15687,54113,54114,
+54115,30075,54116,54117,54118,30077,54119,30078,54120,30076,54121,54122,54123,
+54124,15714,54125,30241,13349,54126,54127,54128,54129,30242,54130,54131,54132,
+30243,54133,54134,54135,27698,54136,54137,54138,54139,54140,54141,54142,54144,
+54145,54146,54147,54148,20820,54149,54150,54151,54152,54153,54154,22890,54155,
+54156,54157,54158,54159,54160,54161,54162,54163,54164,54165,54166,54167,54168,
+54169,54170,54171,54172,54173,54174,54175,54176,54336,54337,54338,54339,54340,
+54341,54342,54343,54344,54345,54346,54347,54348,54349,54350,54351,54352,54353,
+54354,54355,54356,54357,54358,54359,54360,54361,54362,54363,54364,54365,54366,
+54367,30244,54368,54369,54370,54371,54372,54373,54374,54375,54376,28218,54377,
+54378,54379,54380,54381,54382,54383,54384,54385,54386,54387,54388,54389,54390,
+54391,54392,54393,54394,54395,54396,54397,54398,54400,54401,54402,54403,54404,
+54405,54406,54407,54408,54409,54410,54411,54412,54413,54414,54415,54416,54417,
+54418,54419,54420,54421,54422,54423,54424,54425,21810,54426,54427,54428,54429,
+54430,54431,54432,54592,54593,54594,54595,54596,54597,54598,54599,21374,19548,
+54600,54601,54602,54603,54604,54605,54606,54607,19012,54608,54609,54610,54611,
+54612,54613,54614,54615,54616,54617,54618,54619,54620,54621,54622,54623,54624,
+54625,54626,54627,54628,54629,54630,54631,54632,54633,54634,54635,54636,54637,
+54638,54639,54640,54641,54642,54643,54644,54645,54646,54647,54648,54649,54650,
+54651,54652,54653,54654,54656,54657,54658,54659,54660,54661,54662,54663,54664,
+54665,54666,54667,54668,54669,54670,54671,54672,54673,54674,54675,54676,54677,
+54678,54679,54680,54681,54682,54683,54684,54685,54686,54687,54688,54848,54849,
+54850,54851,54852,54853,54854,54855,54856,54857,54858,54859,54860,54861,54862,
+54863,54864,54865,54866,54867,54868,54869,54870,54871,54872,54873,54874,54875,
+54876,54877,54878,54879,54880,54881,54882,25920,54883,54884,54885,54886,54887,
+54888,54889,54890,54891,54892,54893,54894,54895,54896,54897,54898,54899,54900,
+54901,54902,54903,54904,54905,54906,54907,54908,54909,54910,54912,54913,30245,
+54914,54915,54916,54917,54918,54919,54920,54921,54922,54923,54924,54925,54926,
+54927,54928,54929,54930,54931,54932,54933,54934,54935,54936,54937,54938,54939,
+54940,54941,54942,54943,54944,55104,55105,55106,55107,55108,55109,55110,55111,
+55112,55113,55114,55115,55116,55117,55118,55119,55120,55121,55122,55123,55124,
+55125,55126,55127,55128,55129,55130,55131,55132,55133,55134,55135,15919,55136,
+55137,55138,55139,55140,17961,55141,55142,55143,55144,55145,55146,55147,55148,
+55149,55150,55151,55152,55153,55154,55155,55156,55157,55158,55159,55160,55161,
+55162,55163,55164,55165,55166,55168,55169,55170,55171,55172,55173,55174,55175,
+55176,55177,55178,55179,55180,55181,55182,55183,55184,55185,55186,55187,55188,
+55189,55190,55191,55192,23077,15430,13865,14396,18511,15397,23078,23079,19542,
+18499,23080,18045,55193,20789,21097,20790,15431,55194,15666,15204,23081,23082,
+20808,23083,20589,13935,16987,55195,19279,14189,18792,14147,15991,22052,23084,
+23085,17984,22375,18998,55196,21801,19295,21871,23086,22111,13386,23088,23087,
+55197,21099,23089,23090,23091,19028,23092,18987,23093,23094,13135,22127,23095,
+15152,13614,23096,23097,14702,20783,21096,23098,14403,20330,12911,23099,23100,
+55198,15723,20060,21359,23101,20083,23102,21333,15205,23103,19253,19280,23104,
+18283,22126,23105,17717,13889,23106,14156,16206,23107,23108,19245,23109,13687,
+23110,16706,22331,23111,19512,55199,21098,17457,23112,13693,15185,23113,20531,
+23114,23115,20029,23116,23117,23118,12919,23121,23119,20840,23120,17237,23122,
+55200,23123,23124,23125,20539,21029,12409,23126,18219,23127,15735,17185,23128,
+23129,17277,19511,23130,23131,16446,18007,23132,23133,18228,23134,23135,14664,
+55360,55361,55362,55363,55364,55365,55366,55367,55368,15213,55369,55370,55371,
+55372,13881,29816,55373,29817,55374,55375,19811,55376,55377,55378,55379,55380,
+55381,55382,55383,30009,55384,55385,55386,55387,27488,55388,55389,55390,55391,
+55392,55393,20339,15167,55394,55395,55396,55397,55398,55399,55400,14912,21541,
+55401,55402,55403,55404,55405,55406,55407,24921,55408,55409,55410,55411,30068,
+12586,12914,55412,55413,55414,55415,55416,55417,55418,30069,55419,55420,30071,
+55421,55422,55424,14929,30070,55425,17202,55426,55427,55428,55429,55430,55431,
+55432,30073,55433,55434,55435,30072,55436,55437,55438,55439,55440,55441,55442,
+55443,55444,55445,55446,55447,55448,55449,55450,55451,55452,55453,55454,55455,
+55456,55616,55617,55618,55619,55620,55621,55622,55623,55624,55625,55626,55627,
+55628,55629,55630,55631,55632,55633,55634,55635,55636,55637,55638,55639,55640,
+55641,55642,55643,55644,55645,55646,55647,55648,55649,55650,55651,55652,55653,
+55654,55655,55656,55657,55658,55659,55660,55661,55662,55663,55664,55665,55666,
+55667,55668,55669,55670,55671,55672,55673,55674,55675,55676,55677,55678,55680,
+55681,55682,55683,55684,55685,55686,55687,55688,55689,55690,55691,55692,55693,
+55694,55695,55696,55697,55698,55699,55700,55701,55702,55703,55704,55705,55706,
+55707,55708,55709,55710,55711,55712,55872,55873,55874,55875,55876,55877,55878,
+55879,55880,55881,55882,55883,55884,55885,55886,12596,21866,14394,55887,14641,
+12870,21616,20301,12380,21835,15221,22090,14135,19504,17974,12641,14650,22140,
+14689,14113,15482,27226,27227,19577,14707,27228,13435,17203,14161,14936,27229,
+21620,27230,15446,15199,27231,16734,16952,21599,22346,27232,27233,27236,27234,
+27235,18782,14387,13892,27237,19050,18765,13389,55888,55889,25177,17762,27238,
+16437,55890,22328,27239,22316,18556,22611,22605,21598,55891,21625,18756,21294,
+14419,13152,55892,18786,29814,55893,55894,55895,14933,55896,29815,55897,55898,
+22367,55899,55900,29809,14384,21844,14415,18032,55901,55902,55903,55904,55905,
+55906,55907,55908,55909,13123,55910,55911,29810,13100,55912,55913,55914,55915,
+21565,18295,55916,55917,55918,55919,55920,29812,55921,55922,29811,55923,55924,
+55925,55926,55927,55928,55929,55930,55931,55932,19531,55933,55934,55936,18468,
+55937,55938,55939,55940,55941,55942,55943,55944,55945,55946,55947,55948,55949,
+29813,55950,22371,17727,30016,55951,55952,30011,55953,30019,55954,30018,55955,
+22074,30017,55956,55957,55958,21566,30020,55959,30028,55960,55961,55962,55963,
+12367,13688,55964,30025,30026,55965,17756,55966,55967,55968,56128,30021,30022,
+56129,56130,30023,30027,56131,15968,30024,14458,56132,56133,56134,30032,30035,
+56135,56136,56137,16231,56138,14706,30012,30029,56139,56140,16951,56141,56142,
+56143,19576,56144,15481,56145,30030,30031,30033,13925,30034,56146,30037,56147,
+56148,56149,56150,56151,56152,56153,30013,56154,56155,56156,30036,21307,56157,
+13164,56158,56159,19492,56160,56161,56162,56163,30038,56164,56165,56166,56167,
+56168,56169,56170,56171,30039,15969,30040,56172,56173,19551,30043,56174,56175,
+56176,56177,56178,12872,22361,56179,30041,56180,30042,30044,56181,30050,56182,
+56183,56184,30048,56185,56186,56187,30047,30045,56188,56189,30049,56190,56192,
+30046,30052,30053,56193,19555,56194,56195,25919,13624,30051,30056,19491,56196,
+56197,56198,56199,56200,30054,30055,56201,56202,56203,56204,56205,56206,30014,
+56207,56208,56209,56210,56211,56212,56213,56214,56215,56216,56217,56218,12612,
+56219,56220,30015,56221,56222,13637,12900,56223,30060,30057,56224,13911,56384,
+30061,56385,30058,56386,56387,56388,56389,56390,30059,56391,56392,13402,56393,
+21610,56394,56395,56396,30062,56397,13177,56398,56399,56400,56401,56402,56403,
+56404,30063,30065,56405,56406,56407,30064,56408,56409,56410,56411,56412,56413,
+56414,30066,56415,30067,56416,56417,56418,56419,56420,56421,56422,56423,56424,
+56425,56426,56427,18797,14634,56428,56429,18299,56430,56431,13923,56432,56433,
+56434,56435,56436,56437,56438,19529,56439,56440,56441,56442,56443,56444,56445,
+56446,56448,56449,56450,56451,56452,56453,56454,56455,56456,56457,56458,27174,
+56459,56460,56461,56462,56463,56464,56465,56466,56467,56468,56469,56470,56471,
+56472,56473,56474,56475,56476,56477,56478,56479,56480,56640,56641,56642,56643,
+56644,56645,56646,56647,56648,56649,56650,56651,56652,56653,56654,56655,56656,
+56657,56658,56659,56660,56661,56662,56663,56664,56665,56666,56667,56668,56669,
+56670,56671,56672,56673,56674,56675,56676,56677,56678,56679,56680,56681,56682,
+56683,56684,56685,56686,56687,56688,56689,56690,56691,56692,56693,56694,56695,
+56696,56697,56698,56699,56700,56701,56702,56704,56705,56706,56707,56708,56709,
+56710,56711,56712,56713,56714,56715,56716,56717,56718,56719,56720,56721,56722,
+56723,56724,56725,56726,56727,56728,56729,56730,56731,56732,56733,56734,56735,
+56736,56896,56897,56898,56899,56900,56901,56902,56903,56904,56905,56906,56907,
+56908,56909,56910,56911,56912,56913,56914,56915,56916,56917,56918,56919,56920,
+56921,56922,56923,56924,56925,56926,56927,56928,13109,21630,14700,20601,56929,
+26989,22314,26990,16982,18541,14948,26991,26992,26993,22113,26994,26995,26997,
+26996,26998,26999,18273,27000,21592,27001,15694,56930,27002,27003,15695,27004,
+14376,16702,27005,12594,15188,14709,27006,56931,27169,27170,27171,14200,15405,
+56932,19044,24654,21551,20285,21815,27172,21854,27173,20545,14652,56933,13383,
+12633,56934,56935,56936,16433,56937,56938,56939,56940,12646,12647,56941,12648,
+56942,56943,56944,56945,13117,18536,56946,56947,56948,56949,25921,56950,56951,
+12639,56952,56953,56954,16713,13423,56955,56956,18216,21336,56957,18041,20792,
+56958,14717,17013,56960,56961,56962,56963,56964,21293,56965,21579,15740,56966,
+25922,14133,25923,56967,56968,15161,21858,56969,15736,21558,20005,16684,13145,
+56970,56971,19574,56972,25926,25924,25928,56973,25930,25927,13647,17992,56974,
+13692,25925,56975,19062,56976,56977,25929,56978,56979,56980,17236,12613,15395,
+56981,56982,56983,22327,56984,56985,19787,19277,19018,19539,25932,25931,17510,
+56986,56987,20769,20791,25933,56988,25936,56989,19768,22128,25935,13661,56990,
+19774,56991,25937,13882,56992,57152,19752,14692,57153,19013,13137,19289,21612,
+25938,14186,57154,57155,57156,25934,57157,57158,57159,57160,57161,57162,25941,
+13438,25942,57163,57164,57165,57166,57167,25939,25940,57168,21085,57169,57170,
+16991,12614,57171,21346,57172,57173,13917,19308,57174,25943,57175,57176,21366,
+57177,57178,57179,57180,57181,12649,57182,13940,25946,25944,25945,13632,57183,
+57184,57185,21061,25948,57186,57187,25950,57188,57189,57190,57191,57192,57193,
+25949,18226,57194,21027,57195,57196,25947,57197,57198,57199,57200,21602,21850,
+57201,57202,57203,57204,57205,25952,22385,57206,57207,57208,57209,57210,57211,
+57212,25953,57213,12636,20859,57214,25954,25956,57216,57217,57218,57219,25955,
+57220,57221,25957,57222,57223,57224,57225,57226,21080,57227,13643,57228,26463,
+57229,23157,57230,23160,57231,23158,57232,23159,57233,57234,57235,23162,20559,
+17479,57236,57237,12398,57238,57239,57240,20528,57241,23161,57242,21322,14890,
+23330,18289,57243,23164,23163,18779,23165,57244,23329,22366,23166,16730,57245,
+57246,23333,57247,57248,21364,57408,57409,23335,23332,57410,23336,57411,57412,
+15676,57413,57414,57415,16457,23331,23334,22051,57416,23337,57417,57418,57419,
+23341,57420,57421,57422,23342,23340,14914,57423,57424,57425,16164,23339,57426,
+57427,57428,23338,21575,12863,57429,57430,23343,57431,14713,57432,23344,57433,
+57434,57435,57436,13115,57437,57438,57439,13606,57440,57441,57442,57443,13884,
+23345,57444,57445,57446,13941,57447,23346,57448,57449,57450,57451,57452,57453,
+57454,57455,57456,57457,57458,57459,57460,57461,57462,57463,57464,57465,57466,
+57467,12617,57468,57469,57470,57472,23348,57473,57474,57475,23347,23349,57476,
+57477,57478,57479,57480,57481,57482,57483,57484,57485,57486,23351,57487,23350,
+57488,57489,57490,57491,57492,57493,57494,23352,57495,57496,57497,57498,57499,
+57500,57501,57502,57503,23353,57504,57664,23354,57665,57666,21327,29818,18293,
+22339,17764,29820,29821,29819,57667,15942,57668,57669,57670,57671,20591,57672,
+57673,14163,57674,57675,21581,19498,57676,57677,29986,29985,14888,29822,19286,
+57678,57679,57680,29988,16466,57681,13162,57682,19754,29989,29987,15668,29992,
+57683,29993,15693,17208,16225,19297,29994,57684,57685,57686,29990,29991,17520,
+57687,57688,57689,57690,57691,29996,57692,13372,57693,22381,57694,13399,29995,
+29998,57695,57696,29997,29999,20561,57697,57698,57699,57700,57701,57702,57703,
+17233,18473,57704,57705,57706,57707,57708,57709,30000,30001,57710,57711,57712,
+57713,57714,57715,30002,57716,57717,30003,30004,30005,57718,57719,57720,57721,
+30007,30006,57722,57723,57724,57725,30008,57726,57728,57729,57730,57731,57732,
+57733,57734,57735,57736,57737,57738,12873,57739,21332,19021,57740,16495,22104,
+21040,16703,57741,15728,57742,57743,57744,57745,57746,57747,57748,57749,57750,
+57751,14378,57752,57753,57754,57755,57756,57757,57758,57759,57760,57920,57921,
+57922,57923,57924,57925,57926,57927,57928,57929,57930,57931,57932,57933,57934,
+57935,57936,57937,57938,57939,57940,57941,57942,57943,57944,57945,57946,57947,
+57948,57949,57950,57951,57952,57953,57954,57955,57956,57957,57958,57959,57960,
+57961,57962,57963,57964,57965,57966,57967,57968,57969,57970,57971,57972,57973,
+57974,57975,57976,57977,57978,57979,57980,57981,57982,57984,57985,57986,57987,
+57988,57989,57990,57991,57992,57993,57994,57995,57996,57997,57998,57999,58000,
+58001,58002,58003,58004,58005,58006,58007,58008,58009,58010,58011,58012,58013,
+58014,58015,58016,58176,58177,58178,58179,58180,58181,58182,58183,58184,58185,
+58186,58187,58188,58189,58190,58191,58192,58193,58194,58195,58196,58197,58198,
+58199,58200,58201,58202,58203,58204,58205,58206,58207,58208,58209,58210,58211,
+58212,58213,58214,58215,58216,58217,58218,58219,58220,58221,15480,58222,58223,
+58224,58225,58226,58227,58228,58229,58230,58231,58232,58233,58234,58235,58236,
+58237,58238,58240,58241,58242,58243,58244,58245,58246,58247,30278,58248,58249,
+58250,58251,58252,58253,58254,58255,58256,58257,58258,58259,58260,58261,58262,
+58263,58264,58265,58266,58267,58268,58269,58270,58271,58272,58432,58433,58434,
+58435,58436,58437,30279,58438,58439,58440,58441,58442,58443,58444,58445,58446,
+58447,58448,58449,58450,58451,58452,58453,58454,58455,58456,58457,58458,58459,
+58460,58461,58462,30280,58463,58464,58465,58466,58467,58468,58469,58470,58471,
+58472,58473,58474,58475,58476,58477,58478,58479,58480,58481,58482,58483,58484,
+58485,58486,58487,58488,58489,58490,58491,58492,58493,58494,58496,58497,58498,
+58499,58500,58501,58502,58503,58504,58505,58506,58507,58508,58509,58510,58511,
+58512,58513,58514,58515,58516,58517,58518,58519,58520,58521,58522,58523,58524,
+58525,58526,58527,58528,58688,58689,58690,58691,58692,58693,58694,58695,58696,
+58697,58698,58699,58700,58701,58702,58703,58704,58705,58706,58707,58708,58709,
+58710,58711,58712,58713,58714,58715,58716,58717,58718,58719,58720,58721,58722,
+58723,58724,58725,58726,58727,58728,58729,58730,58731,58732,58733,58734,58735,
+58736,58737,58738,58739,30281,58740,58741,58742,58743,58744,58745,58746,58747,
+58748,58749,58750,58752,58753,58754,58755,58756,58757,58758,58759,58760,58761,
+58762,58763,58764,58765,58766,58767,58768,58769,58770,58771,58772,58773,58774,
+58775,58776,58777,58778,58779,58780,58781,58782,58783,30282,58784,58944,58945,
+58946,58947,58948,58949,58950,58951,58952,58953,58954,58955,58956,58957,58958,
+58959,58960,58961,58962,58963,58964,58965,58966,58967,58968,58969,58970,58971,
+58972,58973,58974,58975,58976,58977,58978,30284,58979,58980,58981,58982,58983,
+58984,58985,58986,58987,58988,58989,58990,58991,58992,58993,58994,58995,58996,
+58997,58998,58999,59000,59001,59002,59003,59004,59005,59006,59008,59009,59010,
+59011,59012,59013,59014,59015,59016,59017,59018,59019,59020,59021,59022,59023,
+59024,59025,59026,59027,59028,59029,59030,59031,59032,59033,59034,59035,59036,
+59037,30283,59038,59039,59040,59200,59201,59202,59203,59204,59205,59206,59207,
+30569,59208,59209,59210,59211,59212,59213,59214,59215,59216,59217,59218,59219,
+59220,59221,59222,59223,59224,59225,59226,59227,59228,59229,59230,59231,59232,
+59233,59234,59235,59236,59237,59238,59239,59240,59241,59242,59243,59244,59245,
+59246,59247,59248,59249,59250,59251,59252,59253,59254,59255,59256,59257,59258,
+59259,59260,59261,59262,59264,59265,59266,59267,59268,59269,59270,59271,59272,
+59273,59274,59275,59276,59277,59278,59279,59280,59281,59282,59283,59284,59285,
+59286,59287,59288,59289,59290,59291,59292,59293,59294,59295,59296,59456,59457,
+59458,59459,59460,59461,59462,59463,59464,59465,59466,59467,59468,59469,59470,
+30285,59471,59472,59473,59474,59475,59476,59477,59478,59479,59480,59481,59482,
+59483,59484,59485,59486,59487,59488,59489,59490,59491,59492,59493,59494,59495,
+59496,59497,59498,59499,59500,59501,59502,59503,59504,59505,59506,59507,59508,
+59509,59510,59511,59512,59513,59514,30286,59515,59516,59517,59518,59520,59521,
+59522,59523,59524,59525,59526,59527,59528,59529,59530,59531,59532,59533,59534,
+59535,59536,59537,59538,59539,59540,28228,28229,28230,21867,13860,28232,28231,
+28233,28234,18213,28235,28236,59541,14128,13686,28237,28239,59542,28238,59543,
+14406,28240,28241,28242,13915,13102,22099,17478,12597,14422,28243,28244,21567,
+18261,15995,20057,14643,28246,28245,28248,28247,17701,28249,28250,18222,28251,
+18223,28252,12839,28253,28254,28255,28256,28257,22378,28258,28259,15448,28260,
+21323,19578,12844,16741,28261,18214,17197,59544,28262,28263,28264,28265,28266,
+28267,28268,59545,28269,28270,28271,59546,59547,28272,28273,28274,28276,28275,
+59548,28277,19757,16961,28278,28279,28280,21793,28281,20275,28282,28283,59549,
+28284,28285,28449,28286,28450,14453,17274,28451,28452,15682,21055,12921,28453,
+28454,28455,21112,28456,22141,28457,17996,59550,28458,28459,16692,28460,20346,
+19320,28462,28461,13178,14712,28463,28464,20578,28465,28466,14182,20543,28467,
+28468,28469,18545,19552,28470,28471,28472,28473,28474,21856,28475,13421,17194,
+28476,59551,28477,28478,28479,59552,20093,28480,16992,13368,22326,15733,59712,
+20295,28483,28481,28482,28484,13863,15484,15970,17228,28485,28486,59713,28487,
+28495,28488,28489,28490,18242,28529,13901,28491,59714,28492,28493,13894,17214,
+28494,59715,28496,28497,28498,21874,59716,28499,17527,59717,28500,17528,28501,
+28502,14436,12407,28503,28504,28505,59718,28506,28507,28508,28509,59719,28510,
+15925,28513,28511,28512,59720,28514,28515,16717,28516,28517,28518,28519,28520,
+28521,28522,28523,28524,16472,59721,28525,16685,28526,28527,28528,59722,59723,
+20322,59724,59725,59726,59727,59728,59729,59730,59731,13092,59732,59733,59734,
+59735,59736,59737,59738,59739,59740,59741,59742,59743,59744,59745,59746,59747,
+59748,59749,59750,59751,59752,59753,59754,59755,59756,59757,59758,59759,59760,
+59761,59762,59763,59764,59765,59766,59767,59768,59769,59770,59771,59772,59773,
+59774,59776,59777,59778,59779,59780,59781,59782,59783,59784,59785,59786,59787,
+59788,59789,59790,59791,59792,59793,59794,59795,59796,59797,59798,59799,59800,
+59801,59802,59803,59804,59805,59806,59807,59808,59968,59969,59970,59971,59972,
+59973,59974,59975,59976,59977,59978,59979,59980,59981,59982,59983,59984,59985,
+59986,59987,59988,59989,59990,59991,59992,59993,59994,59995,17221,25413,18753,
+25414,59996,12629,20042,13363,18546,25415,20304,25416,15460,25417,25418,17222,
+21794,17494,14699,20037,25419,17270,25420,59997,14119,14451,14930,25421,25422,
+21572,25423,59998,25424,20811,25425,25426,25427,25428,20822,25429,12923,16443,
+25430,59999,16427,25431,25432,25433,60000,25434,25435,60001,14391,23138,60002,
+13907,60003,23140,23139,60004,60005,60006,60007,60008,60009,60010,23142,60011,
+60012,60013,18542,60014,60015,23141,14144,20852,21109,21875,15703,60016,60017,
+60018,60019,22376,23144,23143,60020,12322,19795,60021,23145,60022,14397,15434,
+16957,16932,13122,23146,60023,16938,17456,15669,60024,60025,20318,60026,60027,
+60028,23147,18754,60029,60030,60032,60033,60034,12637,60035,60036,60037,23148,
+60038,13880,21562,60039,13181,60040,60041,23149,21577,20309,17763,60042,23150,
+60043,60044,60045,60046,60047,23151,60048,23152,16746,19541,20317,60049,60050,
+60051,60052,60053,60054,60055,60056,60057,60058,60059,60060,60061,21351,16929,
+60062,23153,60063,60064,19301,60224,23154,60225,19302,21118,60226,60227,60228,
+14452,60229,60230,23155,12335,20278,60231,60232,21839,60233,60234,60235,60236,
+60237,60238,60239,60240,60241,60242,19309,60243,60244,60245,60246,60247,60248,
+60249,60250,23156,60251,60252,25412,60253,60254,16677,60255,60256,30271,60257,
+60258,30272,30273,17489,60259,18488,20835,60260,60261,20571,20805,15407,14669,
+60262,28532,60263,60264,13382,21306,30274,13179,60265,60266,30275,60267,60268,
+13681,60269,60270,60271,60272,60273,60274,60275,60276,60277,60278,30277,60279,
+60280,60281,60282,60283,60284,60285,21354,30247,20777,60286,60288,60289,60290,
+30249,60291,60292,60293,30248,60294,60295,16739,16471,60296,12578,60297,60298,
+60299,60300,20077,60301,20584,30251,60302,60303,20342,60304,30250,21872,30252,
+17209,60305,60306,60307,15220,30254,30253,60308,60309,60310,17502,60311,60312,
+16728,60313,60314,60315,60316,60317,19242,60318,20284,60319,60320,60480,60481,
+60482,60483,60484,60485,60486,60487,60488,30255,60489,60490,30256,60491,60492,
+30257,60493,16950,60494,60495,60496,60497,60498,12372,17785,60499,60500,60501,
+60502,30258,60503,60504,60505,60506,60507,60508,60509,60510,60511,60512,60513,
+60514,60515,60516,60517,60518,60519,60520,60521,18272,30246,60522,60523,15928,
+60524,60525,15922,60526,13669,60527,60528,14151,60529,16191,17234,17254,60530,
+60531,22604,60532,60533,60534,14447,60535,60536,60537,60538,60539,60540,60541,
+60542,60544,15737,20773,60545,12368,60546,60547,60548,60549,60550,30512,60551,
+60552,60553,60554,60555,60556,60557,60558,30513,60559,60560,60561,60562,60563,
+20524,60564,12336,60565,60566,60567,30514,30515,60568,30516,60569,60570,60571,
+18250,60572,60573,60574,60575,60576,60736,60737,15951,60738,60739,30519,60740,
+60741,60742,60743,60744,60745,60746,30518,60747,12638,60748,30517,60749,60750,
+30520,60751,30521,60752,60753,60754,60755,60756,60757,60758,60759,60760,60761,
+60762,60763,60764,60765,60766,60767,60768,60769,60770,60771,60772,60773,60774,
+60775,60776,60777,60778,60779,60780,60781,60782,60783,60784,60785,60786,60787,
+60788,60789,60790,60791,60792,60793,60794,60795,60796,60797,60798,60800,60801,
+20004,18509,60802,14891,26680,26681,26682,15938,60803,60804,60805,60806,60807,
+21108,60808,21583,18776,60809,60810,60811,60812,60813,60814,60815,60816,60817,
+60818,60819,60820,60821,60822,60823,60824,60825,60826,60827,60828,60829,60830,
+60831,60832,60992,60993,60994,60995,60996,60997,60998,60999,61000,61001,61002,
+61003,61004,61005,61006,61007,61008,61009,61010,61011,61012,61013,61014,61015,
+61016,61017,61018,61019,61020,61021,61022,61023,61024,61025,61026,61027,61028,
+61029,61030,61031,61032,61033,61034,61035,61036,61037,61038,61039,61040,61041,
+61042,61043,61044,61045,61046,61047,61048,61049,61050,61051,61052,61053,61054,
+61056,61057,61058,61059,61060,61061,61062,61063,61064,61065,61066,61067,61068,
+61069,61070,61071,61072,61073,61074,61075,61076,61077,61078,61079,61080,61081,
+61082,61083,61084,61085,61086,61087,61088,61248,61249,61250,61251,61252,61253,
+21043,13861,18282,29052,20334,19251,20587,26479,19815,14667,13913,29053,12388,
+19276,29054,21540,16941,16748,17988,15921,29217,15445,61254,29218,29219,61255,
+29220,21059,17973,61256,19783,29221,61257,21297,16197,19554,61258,29222,29223,
+20821,13934,29224,29225,13663,29226,29227,61259,12924,29228,29229,18471,61260,
+61261,61262,61263,61264,61265,61266,61267,61268,61269,61270,61271,61272,61273,
+61274,61275,61276,61277,61278,61279,61280,61281,61282,61283,61284,61285,61286,
+61287,61288,61289,61290,61291,61292,61293,61294,61295,61296,61297,14183,61298,
+61299,27689,27690,27691,61300,27692,61301,61302,17966,27693,27694,61303,61304,
+61305,14153,18995,61306,61307,61308,61309,61310,61312,61313,25144,30543,61314,
+61315,61316,61317,61318,61319,61320,61321,61322,61323,61324,61325,61326,61327,
+61328,61329,61330,61331,61332,61333,61334,61335,61336,61337,61338,61339,61340,
+61341,61342,61343,61344,61504,61505,61506,61507,61508,30544,61509,61510,12877,
+61511,61512,61513,61514,61515,61516,61517,61518,61519,61520,61521,61522,61523,
+61524,61525,61526,61527,61528,61529,61530,61531,61532,61533,61534,61535,61536,
+61537,61538,61539,30545,61540,61541,61542,61543,61544,61545,61546,61547,61548,
+61549,61550,61551,61552,61553,61554,61555,61556,61557,61558,61559,61560,61561,
+61562,61563,61564,61565,61566,61568,61569,61570,61571,61572,61573,61574,61575,
+61576,61577,30547,30546,61578,61579,61580,61581,61582,61583,61584,61585,61586,
+61587,61588,61589,61590,25147,61591,15394,61592,25148,25149,25150,25151,25152,
+25153,14137,21115,15652,19022,12581,19271,61593,25154,13948,18500,25155,61594,
+61595,15688,61596,12669,25156,61597,13942,25157,17497,61598,61599,25158,20314,
+14685,25159,16417,61600,25160,12918,61760,25161,61761,16755,25162,25163,17016,
+25164,25165,25166,19031,22584,22885,20323,61762,61763,61764,61765,61766,61767,
+61768,61769,61770,61771,61772,28709,61773,61774,23600,61775,61776,61777,61778,
+61779,61780,61781,61782,61783,61784,61785,61786,61787,61788,61789,61790,61791,
+61792,61793,61794,61795,61796,61797,61798,61799,61800,61801,61802,61803,61804,
+61805,61806,61807,61808,61809,61810,61811,61812,61813,61814,61815,61816,61817,
+61818,61819,61820,61821,61822,61824,61825,61826,61827,61828,61829,61830,61831,
+61832,61833,61834,61835,61836,61837,61838,61839,61840,61841,61842,61843,61844,
+61845,61846,61847,61848,61849,61850,61851,61852,61853,61854,61855,61856,62016,
+62017,62018,62019,62020,62021,62022,62023,62024,62025,62026,62027,62028,62029,
+62030,62031,62032,62033,62034,62035,62036,62037,62038,62039,62040,62041,62042,
+62043,62044,62045,62046,62047,62048,62049,62050,62051,62052,62053,62054,62055,
+62056,62057,62058,62059,62060,62061,62062,62063,62064,62065,62066,62067,62068,
+62069,62070,62071,62072,62073,62074,62075,62076,62077,62078,62080,62081,62082,
+62083,62084,62085,62086,62087,62088,62089,62090,62091,62092,62093,62094,62095,
+62096,62097,62098,62099,62100,62101,62102,62103,62104,62105,62106,62107,62108,
+62109,62110,62111,62112,62272,62273,62274,62275,62276,62277,62278,62279,62280,
+62281,62282,62283,62284,62285,62286,62287,62288,62289,17005,21542,19796,20785,
+13147,18301,62290,12853,16959,26208,19003,26209,26210,15956,26211,22308,19797,
+26213,15453,26212,26214,26215,17006,62291,15678,26216,16998,14887,26217,62292,
+26218,13138,20841,62293,62294,16165,26219,18031,26220,26221,62295,62296,26222,
+17965,26223,62297,18727,26224,26225,26226,25913,26227,26228,16994,26229,26230,
+22120,26231,62298,26232,14663,62299,62300,62301,62302,62303,62304,62305,30523,
+30522,62306,62307,62308,62309,30526,30524,14881,62310,30527,62311,30528,62312,
+62313,62314,30530,30529,30532,62315,62316,30531,62317,62318,62319,62320,62321,
+30533,30534,62322,62323,62324,62325,30535,62326,19304,62327,62328,62329,62330,
+14431,62331,62332,62333,62334,62336,62337,30548,62338,30549,62339,62340,62341,
+62342,30550,62343,62344,62345,62346,30552,62347,30554,62348,30551,62349,62350,
+62351,62352,62353,62354,62355,62356,62357,30555,62358,30553,62359,62360,62361,
+62362,62363,62364,62365,22359,62366,62367,62368,62528,30556,62529,62530,62531,
+62532,62533,62534,30557,62535,62536,62537,30558,62538,62539,62540,62541,62542,
+62543,62544,62545,62546,62547,62548,30559,62549,62550,62551,30560,62552,62553,
+62554,62555,62556,62557,62558,62559,62560,62561,62562,23371,62563,62564,22570,
+62565,62566,62567,62568,62569,62570,62571,62572,25975,14701,62573,62574,62575,
+62576,16253,15210,30537,17991,30536,62577,30538,30540,30539,62578,62579,62580,
+30541,62581,20026,62582,30542,62583,62584,17447,62585,62586,62587,62588,62589,
+62590,62592,62593,62594,62595,62596,62597,62598,62599,62600,62601,62602,62603,
+62604,62605,62606,62607,62608,62609,62610,62611,62612,62613,62614,62615,62616,
+62617,62618,62619,62620,62621,62622,62623,62624,62784,62785,62786,62787,62788,
+62789,62790,62791,62792,62793,62794,62795,62796,62797,62798,62799,62800,62801,
+62802,62803,62804,62805,62806,62807,62808,62809,62810,62811,62812,62813,62814,
+62815,62816,62817,62818,62819,62820,62821,62822,62823,62824,62825,62826,62827,
+62828,62829,62830,62831,62832,62833,62834,62835,62836,62837,62838,62839,62840,
+62841,62842,62843,62844,62845,62846,62848,62849,62850,62851,62852,62853,62854,
+62855,62856,62857,62858,62859,62860,62861,62862,62863,62864,62865,62866,62867,
+62868,62869,62870,62871,62872,62873,62874,62875,62876,62877,62878,62879,62880,
+63040,63041,63042,63043,63044,63045,63046,63047,63048,63049,63050,63051,63052,
+63053,63054,63055,63056,63057,63058,63059,63060,63061,63062,63063,63064,63065,
+63066,63067,63068,63069,63070,63071,63072,63073,63074,63075,63076,63077,63078,
+63079,63080,63081,63082,63083,63084,63085,63086,63087,63088,63089,63090,63091,
+63092,63093,63094,63095,63096,63097,63098,63099,63100,63101,63102,63104,63105,
+63106,63107,63108,63109,63110,63111,63112,63113,63114,63115,63116,63117,63118,
+63119,63120,63121,63122,63123,63124,63125,63126,63127,63128,63129,63130,63131,
+63132,63133,63134,63135,63136,63296,63297,63298,63299,63300,63301,63302,63303,
+63304,63305,63306,63307,63308,63309,63310,63311,63312,63313,63314,63315,63316,
+63317,63318,63319,63320,63321,63322,63323,63324,63325,63326,63327,63328,63329,
+63330,63331,63332,63333,63334,63335,63336,63337,63338,63339,63340,63341,63342,
+63343,63344,63345,63346,63347,63348,63349,63350,63351,63352,63353,63354,63355,
+63356,63357,63358,63360,21347,63361,63362,30287,63363,16947,30288,63364,63365,
+30289,30290,30291,30292,63366,63367,30294,63368,12587,30295,63369,30296,30297,
+30298,63370,30299,30300,63371,63372,63373,63374,30301,30302,20298,63375,30303,
+30304,30305,30306,30307,30308,16496,30309,30310,30311,30312,30313,63376,30314,
+63377,30315,30316,63378,30317,30318,30319,30320,30321,30322,30323,30324,15912,
+63379,30325,30326,30327,30328,63380,63381,63382,63383,63384,18554,30329,30330,
+30331,30332,63385,63386,30333,30334,30497,30498,30499,30500,30501,63387,63388,
+30502,30503,30504,12654,30505,30506,30507,63389,63390,30508,30509,16731,30510,
+63391,63392,30511,63552,63553,63554,63555,63556,63557,63558,63559,63560,63561,
+63562,63563,63564,63565,63566,63567,63568,63569,63570,63571,63572,63573,63574,
+63575,63576,63577,63578,63579,63580,63581,63582,63583,63584,63585,63586,63587,
+63588,63589,63590,63591,63592,63593,63594,63595,63596,63597,63598,63599,63600,
+63601,63602,63603,63604,63605,63606,63607,63608,63609,63610,63611,63612,63613,
+63614,63616,63617,63618,63619,63620,63621,63622,63623,63624,63625,63626,63627,
+63628,63629,63630,63631,63632,63633,63634,63635,63636,63637,63638,63639,63640,
+63641,63642,63643,63644,63645,63646,63647,63648,63808,63809,63810,63811,63812,
+63813,63814,63815,63816,63817,63818,63819,63820,63821,63822,63823,63824,63825,
+63826,63827,63828,63829,63830,63831,63832,63833,63834,63835,63836,63837,63838,
+63839,63840,63841,63842,63843,63844,63845,63846,63847,63848,63849,63850,63851,
+63852,63853,63854,63855,63856,63857,63858,63859,63860,63861,63862,63863,63864,
+63865,63866,63867,63868,63869,63870,63872,63873,63874,63875,63876,63877,63878,
+63879,63880,63881,63882,63883,63884,63885,63886,63887,63888,63889,63890,63891,
+63892,63893,63894,63895,63896,63897,63898,63899,63900,63901,63902,63903,63904,
+64064,64065,64066,64067,64068,64069,64070,64071,64072,64073,64074,64075,64076,
+64077,64078,64079,64080,64081,64082,64083,64084,64085,64086,64087,64088,64089,
+64090,64091,64092,64093,64094,64095,64096,64097,64098,64099,64100,64101,64102,
+64103,64104,64105,64106,64107,64108,64109,64110,64111,64112,64113,64114,64115,
+64116,64117,64118,64119,64120,64121,64122,64123,64124,64125,64126,64128,64129,
+64130,64131,64132,64133,64134,64135,64136,64137,64138,64139,64140,64141,64142,
+64143,64144,64145,64146,64147,64148,64149,64150,64151,64152,64153,64154,64155,
+64156,64157,64158,64159,64160,64320,64321,64322,64323,64324,64325,64326,64327,
+64328,64329,64330,64331,64332,64333,64334,64335,64336,64337,64338,64339,64340,
+64341,64342,64343,64344,64345,64346,64347,17521,28719,15398,28720,17273,64348,
+17720,20795,64349,28721,28722,28723,28724,28725,20796,64350,20844,64351,28727,
+28726,21543,64352,19794,28728,28730,28729,28731,28732,64353,64354,14443,28733,
+14952,64355,28734,28735,15977,28736,13932,28737,28738,28739,28740,18485,28741,
+28742,64356,28743,17780,64357,28744,64358,64359,64360,28745,64361,28746,30525,
+64362,28747,28748,28749,64363,28750,64364,64365,64366,64367,28751,14935,64368,
+28752,28753,28754,28755,28756,28757,28758,28760,64369,64370,21285,28759,64371,
+28761,64372,64373,64374,64375,64376,64377,64378,64379,64380,64381,30010,16953,
+64382,64384,30564,64385,64386,64387,64388,30565,30566,64389,64390,30567,64391,
+64392,64393,64394,64395,64396,30568,16948,64397,64398,64399,64400,64401,64402,
+64403,64404,64405,30570,64406,30571,64407,64408,64409,64410,64411,64412,17011,
+64413,64414,64415,64416,64576,64577,64578,64579,64580,64581,64582,64583,64584,
+29808,64585,64586,64587,29807,64588,64589,17001,64590,30561,30562,64591,64592,
+64593,64594,64595,15174,64596,64597,64598,64599,22884,64600,64601,64602,19058,
+16488,28708,64603,14938,64604,64605,18221,64606,64607,64608,17452,64609,64610,
+30572,30573,30574,64611,30576,30575,64612,30577,64613,64614,30580,64615,30579,
+64616,30578,30581,64617,64618,64619,64620,30582,64621,64622,64623,64624,64625,
+64626,64627,64628,64629,28009,64630,28010,28011,64631,30268,64632,64633,64634,
+64635,64636,64637,64638,64640,64641,64642,64643,64644,30269,64645,30270,13862,
+64646,22590,64647,64648,14660,64649,64650,64651,22587,64652,23601,64653,64654,
+64655,64656,64657,64658,19059,64659,30583,64660,64661,64662,64663,64664,64665,
+64666,64667,64668,30584,64669,64670,30585,64671,64672,64832,64833,64834,64835,
+64836,30587,64837,30586,64838,12615,64839,30588,30589,64840,64841,64842,64843,
+64844,30590,64845,64846,64847,64848,64849,64850,64851,64852,64853,64854,64855,
+18027,27700,64856,64857,64858,64859,64860,64861,64862,64863,64864,64865,64866,
+64867,64868,64869,64870,64871,64872,64873,64874,64875,64876,64877,64878,64879,
+64880,64881,64882,64883,64884,64885,64886,64887,64888,64889,64890,64891,64892,
+64893,64894,64896,64897,64898,64899,64900,64901,13149,30259,64902,64903,30260,
+16740,30261,30262,30263,30264,30265,30266,18467,30267,64904,64905,64906,64907,
+64908,64909,64910,64911,64912,64913,64914,64915,16762,14632,28008,64916,64917,
+64918,14698,22879,64919,64920,64921,64922,64923,64924,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64925,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64926,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64927,N,N,N,N,N,N,N,N,N,64928,
+65088,65089,65090,65091,N,65092,N,65093,65094,N,N,N,65095,N,N,N,N,N,N,65096,
+65097,65098,N,65099,65100,N,N,65101,65102,65103,43349,42738,N,42740,42741,
+42720,42721,42736,42737,42722,42723,42734,42735,42726,42727,42724,42725,42728,
+42729,42730,42731,N,N,N,N,43368,43369,43370,43371,43372,43373,43374,43375,
+43376,43377,N,43378,43379,43380,43381,N,43382,43383,43384,43385,43386,43387,
+43388,43389,43390,43392,43393,43394,43395,43396,N,43397,43398,43399,43400,
+8993,8994,8995,8551,8997,8998,8999,9000,9001,9002,9003,9004,9005,9006,9007,
+9008,9009,9010,9011,9012,9013,9014,9015,9016,9017,9018,9019,9020,9021,9022,
+9023,9024,9025,9026,9027,9028,9029,9030,9031,9032,9033,9034,9035,9036,9037,
+9038,9039,9040,9041,9042,9043,9044,9045,9046,9047,9048,9049,9050,9051,9052,
+9053,9054,9055,9056,9057,9058,9059,9060,9061,9062,9063,9064,9065,9066,9067,
+9068,9069,9070,9071,9072,9073,9074,9075,9076,9077,9078,9079,9080,9081,9082,
+9083,9084,9085,8491,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8553,8554,43350,9086,43351,8996,
+};
+
+static const struct unim_index gbcommon_encmap[256] = {
+{__gbcommon_encmap+0,164,252},{__gbcommon_encmap+89,1,220},{__gbcommon_encmap+
+309,81,217},{__gbcommon_encmap+446,145,201},{__gbcommon_encmap+503,1,81},{0,0,
+0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__gbcommon_encmap+584,
+16,59},{__gbcommon_encmap+628,3,153},{__gbcommon_encmap+779,8,191},{
+__gbcommon_encmap+963,18,18},{__gbcommon_encmap+964,96,155},{__gbcommon_encmap
++1024,0,229},{__gbcommon_encmap+1254,5,66},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__gbcommon_encmap+1316,0,254},{
+__gbcommon_encmap+1571,5,41},{__gbcommon_encmap+1608,32,163},{
+__gbcommon_encmap+1740,142,213},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{__gbcommon_encmap+1812,0,255},{__gbcommon_encmap+2068,0,255},{
+__gbcommon_encmap+2324,0,255},{__gbcommon_encmap+2580,0,255},{
+__gbcommon_encmap+2836,0,255},{__gbcommon_encmap+3092,0,255},{
+__gbcommon_encmap+3348,0,255},{__gbcommon_encmap+3604,0,255},{
+__gbcommon_encmap+3860,0,255},{__gbcommon_encmap+4116,0,255},{
+__gbcommon_encmap+4372,0,255},{__gbcommon_encmap+4628,0,255},{
+__gbcommon_encmap+4884,0,255},{__gbcommon_encmap+5140,0,255},{
+__gbcommon_encmap+5396,0,255},{__gbcommon_encmap+5652,0,255},{
+__gbcommon_encmap+5908,0,255},{__gbcommon_encmap+6164,0,255},{
+__gbcommon_encmap+6420,0,255},{__gbcommon_encmap+6676,0,255},{
+__gbcommon_encmap+6932,0,255},{__gbcommon_encmap+7188,0,255},{
+__gbcommon_encmap+7444,0,255},{__gbcommon_encmap+7700,0,255},{
+__gbcommon_encmap+7956,0,255},{__gbcommon_encmap+8212,0,255},{
+__gbcommon_encmap+8468,0,255},{__gbcommon_encmap+8724,0,255},{
+__gbcommon_encmap+8980,0,255},{__gbcommon_encmap+9236,0,255},{
+__gbcommon_encmap+9492,0,255},{__gbcommon_encmap+9748,0,255},{
+__gbcommon_encmap+10004,0,255},{__gbcommon_encmap+10260,0,255},{
+__gbcommon_encmap+10516,0,255},{__gbcommon_encmap+10772,0,255},{
+__gbcommon_encmap+11028,0,255},{__gbcommon_encmap+11284,0,255},{
+__gbcommon_encmap+11540,0,255},{__gbcommon_encmap+11796,0,255},{
+__gbcommon_encmap+12052,0,255},{__gbcommon_encmap+12308,0,255},{
+__gbcommon_encmap+12564,0,255},{__gbcommon_encmap+12820,0,255},{
+__gbcommon_encmap+13076,0,255},{__gbcommon_encmap+13332,0,255},{
+__gbcommon_encmap+13588,0,255},{__gbcommon_encmap+13844,0,255},{
+__gbcommon_encmap+14100,0,255},{__gbcommon_encmap+14356,0,255},{
+__gbcommon_encmap+14612,0,255},{__gbcommon_encmap+14868,0,255},{
+__gbcommon_encmap+15124,0,255},{__gbcommon_encmap+15380,0,255},{
+__gbcommon_encmap+15636,0,255},{__gbcommon_encmap+15892,0,255},{
+__gbcommon_encmap+16148,0,255},{__gbcommon_encmap+16404,0,255},{
+__gbcommon_encmap+16660,0,255},{__gbcommon_encmap+16916,0,255},{
+__gbcommon_encmap+17172,0,255},{__gbcommon_encmap+17428,0,255},{
+__gbcommon_encmap+17684,0,255},{__gbcommon_encmap+17940,0,255},{
+__gbcommon_encmap+18196,0,255},{__gbcommon_encmap+18452,0,255},{
+__gbcommon_encmap+18708,0,255},{__gbcommon_encmap+18964,0,255},{
+__gbcommon_encmap+19220,0,255},{__gbcommon_encmap+19476,0,255},{
+__gbcommon_encmap+19732,0,255},{__gbcommon_encmap+19988,0,255},{
+__gbcommon_encmap+20244,0,255},{__gbcommon_encmap+20500,0,255},{
+__gbcommon_encmap+20756,0,255},{__gbcommon_encmap+21012,0,255},{
+__gbcommon_encmap+21268,0,255},{__gbcommon_encmap+21524,0,255},{
+__gbcommon_encmap+21780,0,255},{__gbcommon_encmap+22036,0,255},{
+__gbcommon_encmap+22292,0,255},{__gbcommon_encmap+22548,0,165},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{__gbcommon_encmap+22714,44,241},{__gbcommon_encmap+22912,12,41},{0,0,0},{0,
+0,0},{0,0,0},{__gbcommon_encmap+22942,48,107},{__gbcommon_encmap+23002,1,229},
+};
+
+static const ucs2_t __gb18030ext_decmap[2729] = {
+58566,58567,58568,58569,58570,58571,58572,58573,58574,58575,58576,58577,58578,
+58579,58580,58581,58582,58583,58584,58585,58586,58587,58588,58589,58590,58591,
+58592,58593,58594,58595,58596,58597,58598,58599,58600,58601,58602,58603,58604,
+58605,58606,58607,58608,58609,58610,58611,58612,58613,58614,58615,58616,58617,
+58618,58619,58620,58621,58622,58623,58624,58625,58626,58627,58628,U,58629,
+58630,58631,58632,58633,58634,58635,58636,58637,58638,58639,58640,58641,58642,
+58643,58644,58645,58646,58647,58648,58649,58650,58651,58652,58653,58654,58655,
+58656,58657,58658,58659,58660,58661,58662,58663,58664,58665,58666,58667,58668,
+58669,58670,58671,58672,58673,58674,58675,58676,58677,58678,58679,58680,58681,
+58682,58683,58684,58685,58686,58687,58688,58689,58690,58691,58692,58693,58694,
+58695,58696,58697,58698,58699,58700,58701,58702,58703,58704,58705,58706,58707,
+58708,58709,58710,58711,58712,58713,58714,58715,58716,58717,58718,58719,58720,
+58721,58722,58723,58724,U,58725,58726,58727,58728,58729,58730,58731,58732,
+58733,58734,58735,58736,58737,58738,58739,58740,58741,58742,58743,58744,58745,
+58746,58747,58748,58749,58750,58751,58752,58753,58754,58755,58756,58757,U,U,U,
+U,U,U,U,U,U,U,59238,59239,59240,59241,59242,59243,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,8364,
+59245,U,U,U,U,U,U,U,U,U,U,59246,59247,U,U,U,U,U,U,U,U,U,U,U,U,59248,59249,
+58758,58759,58760,58761,58762,58763,58764,58765,58766,58767,58768,58769,58770,
+58771,58772,58773,58774,58775,58776,58777,58778,58779,58780,58781,58782,58783,
+58784,58785,58786,58787,58788,58789,58790,58791,58792,58793,58794,58795,58796,
+58797,58798,58799,58800,58801,58802,58803,58804,58805,58806,58807,58808,58809,
+58810,58811,58812,58813,58814,58815,58816,58817,58818,58819,58820,U,58821,
+58822,58823,58824,58825,58826,58827,58828,58829,58830,58831,58832,58833,58834,
+58835,58836,58837,58838,58839,58840,58841,58842,58843,58844,58845,58846,58847,
+58848,58849,58850,58851,58852,58853,58854,58855,58856,58857,58858,58859,58860,
+58861,58862,58863,58864,58865,58866,58867,58868,58869,58870,58871,58872,58873,
+58874,58875,58876,58877,58878,58879,58880,58881,58882,58883,58884,58885,58886,
+58887,58888,58889,58890,58891,58892,58893,58894,58895,58896,58897,58898,58899,
+58900,58901,58902,58903,58904,58905,58906,58907,58908,58909,58910,58911,58912,
+58913,58914,58915,58916,U,58917,58918,58919,58920,58921,58922,58923,58924,
+58925,58926,58927,58928,58929,58930,58931,58932,58933,58934,58935,58936,58937,
+58938,58939,58940,58941,58942,58943,58944,58945,58946,58947,58948,58949,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,59250,59251,59252,59253,59254,59255,59256,59257,59258,59259,59260,58950,
+58951,58952,58953,58954,58955,58956,58957,58958,58959,58960,58961,58962,58963,
+58964,58965,58966,58967,58968,58969,58970,58971,58972,58973,58974,58975,58976,
+58977,58978,58979,58980,58981,58982,58983,58984,58985,58986,58987,58988,58989,
+58990,58991,58992,58993,58994,58995,58996,58997,58998,58999,59000,59001,59002,
+59003,59004,59005,59006,59007,59008,59009,59010,59011,59012,U,59013,59014,
+59015,59016,59017,59018,59019,59020,59021,59022,59023,59024,59025,59026,59027,
+59028,59029,59030,59031,59032,59033,59034,59035,59036,59037,59038,59039,59040,
+59041,59042,59043,59044,59045,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,59261,59262,59263,59264,59265,
+59266,59267,59268,59046,59047,59048,59049,59050,59051,59052,59053,59054,59055,
+59056,59057,59058,59059,59060,59061,59062,59063,59064,59065,59066,59067,59068,
+59069,59070,59071,59072,59073,59074,59075,59076,59077,59078,59079,59080,59081,
+59082,59083,59084,59085,59086,59087,59088,59089,59090,59091,59092,59093,59094,
+59095,59096,59097,59098,59099,59100,59101,59102,59103,59104,59105,59106,59107,
+59108,U,59109,59110,59111,59112,59113,59114,59115,59116,59117,59118,59119,
+59120,59121,59122,59123,59124,59125,59126,59127,59128,59129,59130,59131,59132,
+59133,59134,59135,59136,59137,59138,59139,59140,59141,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,59269,59270,59271,59272,59273,59274,59275,59276,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,59277,59278,59279,59280,59281,59282,
+59283,U,U,U,U,U,U,U,U,U,U,U,U,59284,59285,U,U,U,U,U,59286,U,U,59287,59288,
+59289,59290,59291,59292,59293,59294,59295,59142,59143,59144,59145,59146,59147,
+59148,59149,59150,59151,59152,59153,59154,59155,59156,59157,59158,59159,59160,
+59161,59162,59163,59164,59165,59166,59167,59168,59169,59170,59171,59172,59173,
+59174,59175,59176,59177,59178,59179,59180,59181,59182,59183,59184,59185,59186,
+59187,59188,59189,59190,59191,59192,59193,59194,59195,59196,59197,59198,59199,
+59200,59201,59202,59203,59204,U,59205,59206,59207,59208,59209,59210,59211,
+59212,59213,59214,59215,59216,59217,59218,59219,59220,59221,59222,59223,59224,
+59225,59226,59227,59228,59229,59230,59231,59232,59233,59234,59235,59236,59237,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,59296,59297,
+59298,59299,59300,59301,59302,59303,59304,59305,59306,59307,59308,59309,59310,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,59311,59312,
+59313,59314,59315,59316,59317,59318,59319,59320,59321,59322,59323,59324,59325,
+59326,59327,59328,59329,59330,59331,59332,59333,59334,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,59335,U,U,505,U,59337,59338,59339,59340,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,59341,59342,
+59343,59344,59345,59346,59347,59348,59349,59350,59351,59352,59353,59354,59355,
+59356,59357,59358,59359,59360,59361,59362,U,U,59363,U,59364,59365,59366,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+12350,12272,12273,12274,12275,12276,12277,12278,12279,12280,12281,12282,12283,
+U,59380,59381,59382,59383,59384,59385,59386,59387,59388,59389,59390,59391,
+59392,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,59393,59394,59395,59396,59397,59398,59399,59400,59401,59402,59403,59404,
+59405,59406,59407,57344,57345,57346,57347,57348,57349,57350,57351,57352,57353,
+57354,57355,57356,57357,57358,57359,57360,57361,57362,57363,57364,57365,57366,
+57367,57368,57369,57370,57371,57372,57373,57374,57375,57376,57377,57378,57379,
+57380,57381,57382,57383,57384,57385,57386,57387,57388,57389,57390,57391,57392,
+57393,57394,57395,57396,57397,57398,57399,57400,57401,57402,57403,57404,57405,
+57406,57407,57408,57409,57410,57411,57412,57413,57414,57415,57416,57417,57418,
+57419,57420,57421,57422,57423,57424,57425,57426,57427,57428,57429,57430,57431,
+57432,57433,57434,57435,57436,57437,57438,57439,57440,57441,57442,57443,57444,
+57445,57446,57447,57448,57449,57450,57451,57452,57453,57454,57455,57456,57457,
+57458,57459,57460,57461,57462,57463,57464,57465,57466,57467,57468,57469,57470,
+57471,57472,57473,57474,57475,57476,57477,57478,57479,57480,57481,57482,57483,
+57484,57485,57486,57487,57488,57489,57490,57491,57492,57493,57494,57495,57496,
+57497,57498,57499,57500,57501,57502,57503,57504,57505,57506,57507,57508,57509,
+57510,57511,57512,57513,57514,57515,57516,57517,57518,57519,57520,57521,57522,
+57523,57524,57525,57526,57527,57528,57529,57530,57531,57532,57533,57534,57535,
+57536,57537,57538,57539,57540,57541,57542,57543,57544,57545,57546,57547,57548,
+57549,57550,57551,57552,57553,57554,57555,57556,57557,57558,57559,57560,57561,
+57562,57563,57564,57565,57566,57567,57568,57569,57570,57571,57572,57573,57574,
+57575,57576,57577,57578,57579,57580,57581,57582,57583,57584,57585,57586,57587,
+57588,57589,57590,57591,57592,57593,57594,57595,57596,57597,57598,57599,57600,
+57601,57602,57603,57604,57605,57606,57607,57608,57609,57610,57611,57612,57613,
+57614,57615,57616,57617,57618,57619,57620,57621,57622,57623,57624,57625,57626,
+57627,57628,57629,57630,57631,57632,57633,57634,57635,57636,57637,57638,57639,
+57640,57641,57642,57643,57644,57645,57646,57647,57648,57649,57650,57651,57652,
+57653,57654,57655,57656,57657,57658,57659,57660,57661,57662,57663,57664,57665,
+57666,57667,57668,57669,57670,57671,57672,57673,57674,57675,57676,57677,57678,
+57679,57680,57681,57682,57683,57684,57685,57686,57687,57688,57689,57690,57691,
+57692,57693,57694,57695,57696,57697,57698,57699,57700,57701,57702,57703,57704,
+57705,57706,57707,57708,57709,57710,57711,57712,57713,57714,57715,57716,57717,
+57718,57719,57720,57721,57722,57723,57724,57725,57726,57727,57728,57729,57730,
+57731,57732,57733,57734,57735,57736,57737,57738,57739,57740,57741,57742,57743,
+57744,57745,57746,57747,57748,57749,57750,57751,57752,57753,57754,57755,57756,
+57757,57758,57759,57760,57761,57762,57763,57764,57765,57766,57767,57768,57769,
+57770,57771,57772,57773,57774,57775,57776,57777,57778,57779,57780,57781,57782,
+57783,57784,57785,57786,57787,57788,57789,57790,57791,57792,57793,57794,57795,
+57796,57797,57798,57799,57800,57801,57802,57803,57804,57805,57806,57807,57808,
+57809,57810,57811,57812,57813,57814,57815,57816,57817,57818,57819,57820,57821,
+57822,57823,57824,57825,57826,57827,57828,57829,57830,57831,57832,57833,57834,
+57835,57836,57837,57838,57839,57840,57841,57842,57843,57844,57845,57846,57847,
+57848,57849,57850,57851,57852,57853,57854,57855,57856,57857,57858,57859,57860,
+57861,57862,57863,57864,57865,57866,57867,57868,57869,57870,57871,57872,57873,
+57874,57875,57876,57877,57878,57879,57880,57881,57882,57883,57884,57885,57886,
+57887,57888,57889,57890,57891,57892,57893,57894,57895,57896,57897,57898,57899,
+57900,57901,57902,57903,57904,57905,57906,57907,59408,59409,59410,59411,59412,
+57908,57909,57910,57911,57912,57913,57914,57915,57916,57917,57918,57919,57920,
+57921,57922,57923,57924,57925,57926,57927,57928,57929,57930,57931,57932,57933,
+57934,57935,57936,57937,57938,57939,57940,57941,57942,57943,57944,57945,57946,
+57947,57948,57949,57950,57951,57952,57953,57954,57955,57956,57957,57958,57959,
+57960,57961,57962,57963,57964,57965,57966,57967,57968,57969,57970,57971,57972,
+57973,57974,57975,57976,57977,57978,57979,57980,57981,57982,57983,57984,57985,
+57986,57987,57988,57989,57990,57991,57992,57993,57994,57995,57996,57997,57998,
+57999,58000,58001,58002,58003,58004,58005,58006,58007,58008,58009,58010,58011,
+58012,58013,58014,58015,58016,58017,58018,58019,58020,58021,58022,58023,58024,
+58025,58026,58027,58028,58029,58030,58031,58032,58033,58034,58035,58036,58037,
+58038,58039,58040,58041,58042,58043,58044,58045,58046,58047,58048,58049,58050,
+58051,58052,58053,58054,58055,58056,58057,58058,58059,58060,58061,58062,58063,
+58064,58065,58066,58067,58068,58069,58070,58071,58072,58073,58074,58075,58076,
+58077,58078,58079,58080,58081,58082,58083,58084,58085,58086,58087,58088,58089,
+58090,58091,58092,58093,58094,58095,58096,58097,58098,58099,58100,58101,58102,
+58103,58104,58105,58106,58107,58108,58109,58110,58111,58112,58113,58114,58115,
+58116,58117,58118,58119,58120,58121,58122,58123,58124,58125,58126,58127,58128,
+58129,58130,58131,58132,58133,58134,58135,58136,58137,58138,58139,58140,58141,
+58142,58143,58144,58145,58146,58147,58148,58149,58150,58151,58152,58153,58154,
+58155,58156,58157,58158,58159,58160,58161,58162,58163,58164,58165,58166,58167,
+58168,58169,58170,58171,58172,58173,58174,58175,58176,58177,58178,58179,58180,
+58181,58182,58183,58184,58185,58186,58187,58188,58189,58190,58191,58192,58193,
+58194,58195,58196,58197,58198,58199,58200,58201,58202,58203,58204,58205,58206,
+58207,58208,58209,58210,58211,58212,58213,58214,58215,58216,58217,58218,58219,
+58220,58221,58222,58223,58224,58225,58226,58227,58228,58229,58230,58231,58232,
+58233,58234,58235,58236,58237,58238,58239,58240,58241,58242,58243,58244,58245,
+58246,58247,58248,58249,58250,58251,58252,58253,58254,58255,58256,58257,58258,
+58259,58260,58261,58262,58263,58264,58265,58266,58267,58268,58269,58270,58271,
+58272,58273,58274,58275,58276,58277,58278,58279,58280,58281,58282,58283,58284,
+58285,58286,58287,58288,58289,58290,58291,58292,58293,58294,58295,58296,58297,
+58298,58299,58300,58301,58302,58303,58304,58305,58306,58307,58308,58309,58310,
+58311,58312,58313,58314,58315,58316,58317,58318,58319,58320,58321,58322,58323,
+58324,58325,58326,58327,58328,58329,58330,58331,58332,58333,58334,58335,58336,
+58337,58338,58339,58340,58341,58342,58343,58344,58345,58346,58347,58348,58349,
+58350,58351,58352,58353,58354,58355,58356,58357,58358,58359,58360,58361,58362,
+58363,58364,58365,58366,58367,58368,58369,58370,58371,58372,58373,58374,58375,
+58376,58377,58378,58379,58380,58381,58382,58383,58384,58385,58386,58387,58388,
+58389,58390,58391,58392,58393,58394,58395,58396,58397,58398,58399,58400,58401,
+58402,58403,58404,58405,58406,58407,58408,58409,58410,58411,58412,58413,58414,
+58415,58416,58417,58418,58419,58420,58421,58422,58423,58424,58425,58426,58427,
+58428,58429,58430,58431,58432,58433,58434,58435,58436,58437,58438,58439,58440,
+58441,58442,58443,58444,58445,58446,58447,58448,58449,58450,58451,58452,58453,
+58454,58455,58456,58457,58458,58459,58460,58461,58462,58463,58464,58465,58466,
+58467,58468,58469,58470,58471,11905,59414,59415,59416,11908,13427,13383,11912,
+11915,59422,13726,13850,13838,11916,11927,14702,14616,59430,14799,14815,14963,
+14800,59435,59436,15182,15470,15584,11943,59441,59442,11946,16470,16735,11950,
+17207,11955,11958,11959,59451,17329,17324,11963,17373,17622,18017,17996,59459,
+U,18211,18217,18300,18317,11978,18759,18810,18813,18818,18819,18821,18822,
+18847,18843,18871,18870,59476,59477,19619,19615,19616,19617,19575,19618,19731,
+19732,19733,19734,19735,19736,19737,19886,59492,58472,58473,58474,58475,58476,
+58477,58478,58479,58480,58481,58482,58483,58484,58485,58486,58487,58488,58489,
+58490,58491,58492,58493,58494,58495,58496,58497,58498,58499,58500,58501,58502,
+58503,58504,58505,58506,58507,58508,58509,58510,58511,58512,58513,58514,58515,
+58516,58517,58518,58519,58520,58521,58522,58523,58524,58525,58526,58527,58528,
+58529,58530,58531,58532,58533,58534,58535,58536,58537,58538,58539,58540,58541,
+58542,58543,58544,58545,58546,58547,58548,58549,58550,58551,58552,58553,58554,
+58555,58556,58557,58558,58559,58560,58561,58562,58563,58564,58565,
+};
+
+static const struct dbcs_index gb18030ext_decmap[256] = {
+{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__gb18030ext_decmap+0,64,
+160},{__gb18030ext_decmap+97,64,254},{__gb18030ext_decmap+288,64,160},{
+__gb18030ext_decmap+385,64,254},{__gb18030ext_decmap+576,64,254},{
+__gb18030ext_decmap+767,64,254},{__gb18030ext_decmap+958,64,254},{
+__gb18030ext_decmap+1149,150,254},{__gb18030ext_decmap+1254,88,254},{
+__gb18030ext_decmap+1421,161,254},{__gb18030ext_decmap+1515,161,254},{
+__gb18030ext_decmap+1609,161,254},{__gb18030ext_decmap+1703,161,254},{
+__gb18030ext_decmap+1797,161,254},{__gb18030ext_decmap+1891,161,254},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+__gb18030ext_decmap+1985,250,254},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__gb18030ext_decmap
++1990,161,254},{__gb18030ext_decmap+2084,161,254},{__gb18030ext_decmap+2178,
+161,254},{__gb18030ext_decmap+2272,161,254},{__gb18030ext_decmap+2366,161,254
+},{__gb18030ext_decmap+2460,161,254},{__gb18030ext_decmap+2554,80,254},{0,0,0
+},
+};
+
+static const DBCHAR __gb18030ext_encmap[3227] = {
+43199,41699,65104,N,N,65108,N,N,N,65111,N,N,65112,65117,N,N,N,N,N,N,N,N,N,N,
+65118,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65131,N,N,65134,N,N,N,65137,N,N,N,N,65139,
+N,N,65140,65141,N,N,N,65145,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65156,43402,43403,
+43404,43405,43406,43407,43408,43409,43410,43411,43412,43413,43401,65110,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,65109,65114,65116,N,N,N,N,N,N,N,N,N,N,N,65115,65120,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65119,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65122,65125,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65123,
+65124,65128,65129,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,65130,65135,65136,65138,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65144,N,N,N,N,65143,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65146,65147,65149,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65148,65152,N,N,N,N,N,65153,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+65154,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65155,65157,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65158,
+N,N,65159,N,N,N,N,65160,65161,N,65162,65163,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,65165,N,N,N,65164,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65167,
+65166,65174,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,65171,65172,65173,65175,65170,65176,65177,65178,65179,65180,65181,
+65182,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65183,
+43681,43682,43683,43684,43685,43686,43687,43688,43689,43690,43691,43692,43693,
+43694,43695,43696,43697,43698,43699,43700,43701,43702,43703,43704,43705,43706,
+43707,43708,43709,43710,43711,43712,43713,43714,43715,43716,43717,43718,43719,
+43720,43721,43722,43723,43724,43725,43726,43727,43728,43729,43730,43731,43732,
+43733,43734,43735,43736,43737,43738,43739,43740,43741,43742,43743,43744,43745,
+43746,43747,43748,43749,43750,43751,43752,43753,43754,43755,43756,43757,43758,
+43759,43760,43761,43762,43763,43764,43765,43766,43767,43768,43769,43770,43771,
+43772,43773,43774,43937,43938,43939,43940,43941,43942,43943,43944,43945,43946,
+43947,43948,43949,43950,43951,43952,43953,43954,43955,43956,43957,43958,43959,
+43960,43961,43962,43963,43964,43965,43966,43967,43968,43969,43970,43971,43972,
+43973,43974,43975,43976,43977,43978,43979,43980,43981,43982,43983,43984,43985,
+43986,43987,43988,43989,43990,43991,43992,43993,43994,43995,43996,43997,43998,
+43999,44000,44001,44002,44003,44004,44005,44006,44007,44008,44009,44010,44011,
+44012,44013,44014,44015,44016,44017,44018,44019,44020,44021,44022,44023,44024,
+44025,44026,44027,44028,44029,44030,44193,44194,44195,44196,44197,44198,44199,
+44200,44201,44202,44203,44204,44205,44206,44207,44208,44209,44210,44211,44212,
+44213,44214,44215,44216,44217,44218,44219,44220,44221,44222,44223,44224,44225,
+44226,44227,44228,44229,44230,44231,44232,44233,44234,44235,44236,44237,44238,
+44239,44240,44241,44242,44243,44244,44245,44246,44247,44248,44249,44250,44251,
+44252,44253,44254,44255,44256,44257,44258,44259,44260,44261,44262,44263,44264,
+44265,44266,44267,44268,44269,44270,44271,44272,44273,44274,44275,44276,44277,
+44278,44279,44280,44281,44282,44283,44284,44285,44286,44449,44450,44451,44452,
+44453,44454,44455,44456,44457,44458,44459,44460,44461,44462,44463,44464,44465,
+44466,44467,44468,44469,44470,44471,44472,44473,44474,44475,44476,44477,44478,
+44479,44480,44481,44482,44483,44484,44485,44486,44487,44488,44489,44490,44491,
+44492,44493,44494,44495,44496,44497,44498,44499,44500,44501,44502,44503,44504,
+44505,44506,44507,44508,44509,44510,44511,44512,44513,44514,44515,44516,44517,
+44518,44519,44520,44521,44522,44523,44524,44525,44526,44527,44528,44529,44530,
+44531,44532,44533,44534,44535,44536,44537,44538,44539,44540,44541,44542,44705,
+44706,44707,44708,44709,44710,44711,44712,44713,44714,44715,44716,44717,44718,
+44719,44720,44721,44722,44723,44724,44725,44726,44727,44728,44729,44730,44731,
+44732,44733,44734,44735,44736,44737,44738,44739,44740,44741,44742,44743,44744,
+44745,44746,44747,44748,44749,44750,44751,44752,44753,44754,44755,44756,44757,
+44758,44759,44760,44761,44762,44763,44764,44765,44766,44767,44768,44769,44770,
+44771,44772,44773,44774,44775,44776,44777,44778,44779,44780,44781,44782,44783,
+44784,44785,44786,44787,44788,44789,44790,44791,44792,44793,44794,44795,44796,
+44797,44798,44961,44962,44963,44964,44965,44966,44967,44968,44969,44970,44971,
+44972,44973,44974,44975,44976,44977,44978,44979,44980,44981,44982,44983,44984,
+44985,44986,44987,44988,44989,44990,44991,44992,44993,44994,44995,44996,44997,
+44998,44999,45000,45001,45002,45003,45004,45005,45006,45007,45008,45009,45010,
+45011,45012,45013,45014,45015,45016,45017,45018,45019,45020,45021,45022,45023,
+45024,45025,45026,45027,45028,45029,45030,45031,45032,45033,45034,45035,45036,
+45037,45038,45039,45040,45041,45042,45043,45044,45045,45046,45047,45048,45049,
+45050,45051,45052,45053,45054,63649,63650,63651,63652,63653,63654,63655,63656,
+63657,63658,63659,63660,63661,63662,63663,63664,63665,63666,63667,63668,63669,
+63670,63671,63672,63673,63674,63675,63676,63677,63678,63679,63680,63681,63682,
+63683,63684,63685,63686,63687,63688,63689,63690,63691,63692,63693,63694,63695,
+63696,63697,63698,63699,63700,63701,63702,63703,63704,63705,63706,63707,63708,
+63709,63710,63711,63712,63713,63714,63715,63716,63717,63718,63719,63720,63721,
+63722,63723,63724,63725,63726,63727,63728,63729,63730,63731,63732,63733,63734,
+63735,63736,63737,63738,63739,63740,63741,63742,63905,63906,63907,63908,63909,
+63910,63911,63912,63913,63914,63915,63916,63917,63918,63919,63920,63921,63922,
+63923,63924,63925,63926,63927,63928,63929,63930,63931,63932,63933,63934,63935,
+63936,63937,63938,63939,63940,63941,63942,63943,63944,63945,63946,63947,63948,
+63949,63950,63951,63952,63953,63954,63955,63956,63957,63958,63959,63960,63961,
+63962,63963,63964,63965,63966,63967,63968,63969,63970,63971,63972,63973,63974,
+63975,63976,63977,63978,63979,63980,63981,63982,63983,63984,63985,63986,63987,
+63988,63989,63990,63991,63992,63993,63994,63995,63996,63997,63998,64161,64162,
+64163,64164,64165,64166,64167,64168,64169,64170,64171,64172,64173,64174,64175,
+64176,64177,64178,64179,64180,64181,64182,64183,64184,64185,64186,64187,64188,
+64189,64190,64191,64192,64193,64194,64195,64196,64197,64198,64199,64200,64201,
+64202,64203,64204,64205,64206,64207,64208,64209,64210,64211,64212,64213,64214,
+64215,64216,64217,64218,64219,64220,64221,64222,64223,64224,64225,64226,64227,
+64228,64229,64230,64231,64232,64233,64234,64235,64236,64237,64238,64239,64240,
+64241,64242,64243,64244,64245,64246,64247,64248,64249,64250,64251,64252,64253,
+64254,64417,64418,64419,64420,64421,64422,64423,64424,64425,64426,64427,64428,
+64429,64430,64431,64432,64433,64434,64435,64436,64437,64438,64439,64440,64441,
+64442,64443,64444,64445,64446,64447,64448,64449,64450,64451,64452,64453,64454,
+64455,64456,64457,64458,64459,64460,64461,64462,64463,64464,64465,64466,64467,
+64468,64469,64470,64471,64472,64473,64474,64475,64476,64477,64478,64479,64480,
+64481,64482,64483,64484,64485,64486,64487,64488,64489,64490,64491,64492,64493,
+64494,64495,64496,64497,64498,64499,64500,64501,64502,64503,64504,64505,64506,
+64507,64508,64509,64510,64673,64674,64675,64676,64677,64678,64679,64680,64681,
+64682,64683,64684,64685,64686,64687,64688,64689,64690,64691,64692,64693,64694,
+64695,64696,64697,64698,64699,64700,64701,64702,64703,64704,64705,64706,64707,
+64708,64709,64710,64711,64712,64713,64714,64715,64716,64717,64718,64719,64720,
+64721,64722,64723,64724,64725,64726,64727,64728,64729,64730,64731,64732,64733,
+64734,64735,64736,64737,64738,64739,64740,64741,64742,64743,64744,64745,64746,
+64747,64748,64749,64750,64751,64752,64753,64754,64755,64756,64757,64758,64759,
+64760,64761,64762,64763,64764,64765,64766,64929,64930,64931,64932,64933,64934,
+64935,64936,64937,64938,64939,64940,64941,64942,64943,64944,64945,64946,64947,
+64948,64949,64950,64951,64952,64953,64954,64955,64956,64957,64958,64959,64960,
+64961,64962,64963,64964,64965,64966,64967,64968,64969,64970,64971,64972,64973,
+64974,64975,64976,64977,64978,64979,64980,64981,64982,64983,64984,64985,64986,
+64987,64988,64989,64990,64991,64992,64993,64994,64995,64996,64997,64998,64999,
+65000,65001,65002,65003,65004,65005,65006,65007,65008,65009,65010,65011,65012,
+65013,65014,65015,65016,65017,65018,65019,65020,65021,65022,65185,65186,65187,
+65188,65189,65190,65191,65192,65193,65194,65195,65196,65197,65198,65199,65200,
+65201,65202,65203,65204,65205,65206,65207,65208,65209,65210,65211,65212,65213,
+65214,65215,65216,65217,65218,65219,65220,65221,65222,65223,65224,65225,65226,
+65227,65228,65229,65230,65231,65232,65233,65234,65235,65236,65237,65238,65239,
+65240,65241,65242,65243,65244,65245,65246,65247,65248,65249,65250,65251,65252,
+65253,65254,65255,65256,65257,65258,65259,65260,65261,65262,65263,65264,65265,
+65266,65267,65268,65269,65270,65271,65272,65273,65274,65275,65276,65277,65278,
+41280,41281,41282,41283,41284,41285,41286,41287,41288,41289,41290,41291,41292,
+41293,41294,41295,41296,41297,41298,41299,41300,41301,41302,41303,41304,41305,
+41306,41307,41308,41309,41310,41311,41312,41313,41314,41315,41316,41317,41318,
+41319,41320,41321,41322,41323,41324,41325,41326,41327,41328,41329,41330,41331,
+41332,41333,41334,41335,41336,41337,41338,41339,41340,41341,41342,41344,41345,
+41346,41347,41348,41349,41350,41351,41352,41353,41354,41355,41356,41357,41358,
+41359,41360,41361,41362,41363,41364,41365,41366,41367,41368,41369,41370,41371,
+41372,41373,41374,41375,41376,41536,41537,41538,41539,41540,41541,41542,41543,
+41544,41545,41546,41547,41548,41549,41550,41551,41552,41553,41554,41555,41556,
+41557,41558,41559,41560,41561,41562,41563,41564,41565,41566,41567,41568,41569,
+41570,41571,41572,41573,41574,41575,41576,41577,41578,41579,41580,41581,41582,
+41583,41584,41585,41586,41587,41588,41589,41590,41591,41592,41593,41594,41595,
+41596,41597,41598,41600,41601,41602,41603,41604,41605,41606,41607,41608,41609,
+41610,41611,41612,41613,41614,41615,41616,41617,41618,41619,41620,41621,41622,
+41623,41624,41625,41626,41627,41628,41629,41630,41631,41632,41792,41793,41794,
+41795,41796,41797,41798,41799,41800,41801,41802,41803,41804,41805,41806,41807,
+41808,41809,41810,41811,41812,41813,41814,41815,41816,41817,41818,41819,41820,
+41821,41822,41823,41824,41825,41826,41827,41828,41829,41830,41831,41832,41833,
+41834,41835,41836,41837,41838,41839,41840,41841,41842,41843,41844,41845,41846,
+41847,41848,41849,41850,41851,41852,41853,41854,41856,41857,41858,41859,41860,
+41861,41862,41863,41864,41865,41866,41867,41868,41869,41870,41871,41872,41873,
+41874,41875,41876,41877,41878,41879,41880,41881,41882,41883,41884,41885,41886,
+41887,41888,42048,42049,42050,42051,42052,42053,42054,42055,42056,42057,42058,
+42059,42060,42061,42062,42063,42064,42065,42066,42067,42068,42069,42070,42071,
+42072,42073,42074,42075,42076,42077,42078,42079,42080,42081,42082,42083,42084,
+42085,42086,42087,42088,42089,42090,42091,42092,42093,42094,42095,42096,42097,
+42098,42099,42100,42101,42102,42103,42104,42105,42106,42107,42108,42109,42110,
+42112,42113,42114,42115,42116,42117,42118,42119,42120,42121,42122,42123,42124,
+42125,42126,42127,42128,42129,42130,42131,42132,42133,42134,42135,42136,42137,
+42138,42139,42140,42141,42142,42143,42144,42304,42305,42306,42307,42308,42309,
+42310,42311,42312,42313,42314,42315,42316,42317,42318,42319,42320,42321,42322,
+42323,42324,42325,42326,42327,42328,42329,42330,42331,42332,42333,42334,42335,
+42336,42337,42338,42339,42340,42341,42342,42343,42344,42345,42346,42347,42348,
+42349,42350,42351,42352,42353,42354,42355,42356,42357,42358,42359,42360,42361,
+42362,42363,42364,42365,42366,42368,42369,42370,42371,42372,42373,42374,42375,
+42376,42377,42378,42379,42380,42381,42382,42383,42384,42385,42386,42387,42388,
+42389,42390,42391,42392,42393,42394,42395,42396,42397,42398,42399,42400,42560,
+42561,42562,42563,42564,42565,42566,42567,42568,42569,42570,42571,42572,42573,
+42574,42575,42576,42577,42578,42579,42580,42581,42582,42583,42584,42585,42586,
+42587,42588,42589,42590,42591,42592,42593,42594,42595,42596,42597,42598,42599,
+42600,42601,42602,42603,42604,42605,42606,42607,42608,42609,42610,42611,42612,
+42613,42614,42615,42616,42617,42618,42619,42620,42621,42622,42624,42625,42626,
+42627,42628,42629,42630,42631,42632,42633,42634,42635,42636,42637,42638,42639,
+42640,42641,42642,42643,42644,42645,42646,42647,42648,42649,42650,42651,42652,
+42653,42654,42655,42656,42816,42817,42818,42819,42820,42821,42822,42823,42824,
+42825,42826,42827,42828,42829,42830,42831,42832,42833,42834,42835,42836,42837,
+42838,42839,42840,42841,42842,42843,42844,42845,42846,42847,42848,42849,42850,
+42851,42852,42853,42854,42855,42856,42857,42858,42859,42860,42861,42862,42863,
+42864,42865,42866,42867,42868,42869,42870,42871,42872,42873,42874,42875,42876,
+42877,42878,42880,42881,42882,42883,42884,42885,42886,42887,42888,42889,42890,
+42891,42892,42893,42894,42895,42896,42897,42898,42899,42900,42901,42902,42903,
+42904,42905,42906,42907,42908,42909,42910,42911,42912,41643,41644,41645,41646,
+41647,41648,N,41700,41711,41712,41725,41726,42228,42229,42230,42231,42232,
+42233,42234,42235,42236,42237,42238,42487,42488,42489,42490,42491,42492,42493,
+42494,42681,42682,42683,42684,42685,42686,42687,42688,42713,42714,42715,42716,
+42717,42718,42719,42732,42733,42739,42742,42743,42744,42745,42746,42747,42748,
+42749,42750,42946,42947,42948,42949,42950,42951,42952,42953,42954,42955,42956,
+42957,42958,42959,42960,42994,42995,42996,42997,42998,42999,43000,43001,43002,
+43003,43004,43005,43006,43158,43159,43160,43161,43162,43163,43164,43165,43166,
+43167,43168,43196,N,43201,43202,43203,43204,43242,43243,43244,43245,43246,
+43247,43248,43249,43250,43251,43252,43253,43254,43255,43256,43257,43258,43259,
+43260,43261,43262,43352,43355,43357,43358,43359,N,N,N,N,N,N,N,N,N,N,N,N,N,
+43415,43416,43417,43418,43419,43420,43421,43422,43423,43424,43425,43426,43427,
+43504,43505,43506,43507,43508,43509,43510,43511,43512,43513,43514,43515,43516,
+43517,43518,55290,55291,55292,55293,55294,N,65105,65106,65107,N,N,N,N,N,65113,
+N,N,N,N,N,N,N,65121,N,N,N,N,65126,65127,N,N,N,N,65132,65133,N,N,N,N,N,N,N,N,
+65142,N,N,N,N,N,N,N,65150,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65168,65169,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,65184,
+};
+
+static const struct unim_index gb18030ext_encmap[256] = {
+{0,0,0},{__gb18030ext_encmap+0,249,249},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__gb18030ext_encmap+1,172,172
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{__gb18030ext_encmap+2,129,202},{
+__gb18030ext_encmap+76,240,251},{__gb18030ext_encmap+88,62,62},{0,0,0},{0,0,0
+},{0,0,0},{__gb18030ext_encmap+89,71,115},{__gb18030ext_encmap+134,158,158},{
+__gb18030ext_encmap+135,14,26},{0,0,0},{0,0,0},{__gb18030ext_encmap+148,24,223
+},{__gb18030ext_encmap+348,115,115},{__gb18030ext_encmap+349,78,78},{
+__gb18030ext_encmap+350,110,224},{0,0,0},{0,0,0},{0,0,0},{__gb18030ext_encmap+
+465,86,86},{__gb18030ext_encmap+466,95,95},{0,0,0},{__gb18030ext_encmap+467,
+55,221},{__gb18030ext_encmap+634,214,214},{0,0,0},{__gb18030ext_encmap+635,76,
+97},{__gb18030ext_encmap+657,35,141},{0,0,0},{__gb18030ext_encmap+764,71,183},
+{0,0,0},{0,0,0},{__gb18030ext_encmap+877,119,163},{__gb18030ext_encmap+922,19,
+174},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{__gb18030ext_encmap+1078,0,255},{__gb18030ext_encmap+1334,0,255
+},{__gb18030ext_encmap+1590,0,255},{__gb18030ext_encmap+1846,0,255},{
+__gb18030ext_encmap+2102,0,255},{__gb18030ext_encmap+2358,0,255},{
+__gb18030ext_encmap+2614,0,255},{__gb18030ext_encmap+2870,0,255},{
+__gb18030ext_encmap+3126,0,100},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
+};
+
+
+static const struct _gb18030_to_unibmp_ranges {
+    Py_UNICODE   first, last;
+    DBCHAR       base;
+} gb18030_to_unibmp_ranges[] = {
+{128,163,0},{165,166,36},{169,175,38},{178,182,45},{184,214,50},{216,223,81},{
+226,231,89},{235,235,95},{238,241,96},{244,246,100},{248,248,103},{251,251,104
+},{253,256,105},{258,274,109},{276,282,126},{284,298,133},{300,323,148},{325,
+327,172},{329,332,175},{334,362,179},{364,461,208},{463,463,306},{465,465,307
+},{467,467,308},{469,469,309},{471,471,310},{473,473,311},{475,475,312},{477,
+504,313},{506,592,341},{594,608,428},{610,710,443},{712,712,544},{716,728,545
+},{730,912,558},{930,930,741},{938,944,742},{962,962,749},{970,1024,750},{1026
+,1039,805},{1104,1104,819},{1106,8207,820},{8209,8210,7922},{8215,8215,7924},{
+8218,8219,7925},{8222,8228,7927},{8231,8239,7934},{8241,8241,7943},{8244,8244,
+7944},{8246,8250,7945},{8252,8363,7950},{8365,8450,8062},{8452,8452,8148},{
+8454,8456,8149},{8458,8469,8152},{8471,8480,8164},{8482,8543,8174},{8556,8559,
+8236},{8570,8591,8240},{8596,8597,8262},{8602,8711,8264},{8713,8718,8374},{
+8720,8720,8380},{8722,8724,8381},{8726,8729,8384},{8731,8732,8388},{8737,8738,
+8390},{8740,8740,8392},{8742,8742,8393},{8748,8749,8394},{8751,8755,8396},{
+8760,8764,8401},{8766,8775,8406},{8777,8779,8416},{8781,8785,8419},{8787,8799,
+8424},{8802,8803,8437},{8808,8813,8439},{8816,8852,8445},{8854,8856,8482},{
+8858,8868,8485},{8870,8894,8496},{8896,8977,8521},{8979,9311,8603},{9322,9331,
+8936},{9372,9471,8946},{9548,9551,9046},{9588,9600,9050},{9616,9618,9063},{
+9622,9631,9066},{9634,9649,9076},{9652,9659,9092},{9662,9669,9100},{9672,9674,
+9108},{9676,9677,9111},{9680,9697,9113},{9702,9732,9131},{9735,9736,9162},{
+9738,9791,9164},{9793,9793,9218},{9795,11904,9219},{11906,11907,11329},{11909,
+11911,11331},{11913,11914,11334},{11917,11926,11336},{11928,11942,11346},{
+11944,11945,11361},{11947,11949,11363},{11951,11954,11366},{11956,11957,11370
+},{11960,11962,11372},{11964,11977,11375},{11979,12271,11389},{12284,12287,
+11682},{12292,12292,11686},{12312,12316,11687},{12319,12320,11692},{12330,
+12349,11694},{12351,12352,11714},{12436,12442,11716},{12447,12448,11723},{
+12535,12539,11725},{12543,12548,11730},{12586,12831,11736},{12842,12848,11982
+},{12850,12962,11989},{12964,13197,12102},{13200,13211,12336},{13215,13216,
+12348},{13218,13251,12350},{13253,13261,12384},{13263,13264,12393},{13267,
+13268,12395},{13270,13382,12397},{13384,13426,12510},{13428,13725,12553},{
+13727,13837,12851},{13839,13849,12962},{13851,14615,12973},{14617,14701,13738
+},{14703,14798,13823},{14801,14814,13919},{14816,14962,13933},{14964,15181,
+14080},{15183,15469,14298},{15471,15583,14585},{15585,16469,14698},{16471,
+16734,15583},{16736,17206,15847},{17208,17323,16318},{17325,17328,16434},{
+17330,17372,16438},{17374,17621,16481},{17623,17995,16729},{17997,18016,17102
+},{18018,18210,17122},{18212,18216,17315},{18218,18299,17320},{18301,18316,
+17402},{18318,18758,17418},{18760,18809,17859},{18811,18812,17909},{18814,
+18817,17911},{18820,18820,17915},{18823,18842,17916},{18844,18846,17936},{
+18848,18869,17939},{18872,19574,17961},{19576,19614,18664},{19620,19730,18703
+},{19738,19885,18814},{19887,19967,18962},{40870,55295,19043},{59244,59244,
+33469},{59336,59336,33470},{59367,59379,33471},{59413,59413,33484},{59417,
+59421,33485},{59423,59429,33490},{59431,59434,33497},{59437,59440,33501},{
+59443,59450,33505},{59452,59458,33513},{59460,59475,33520},{59478,59491,33536
+},{59493,63787,33550},{63789,63864,37845},{63866,63892,37921},{63894,63974,
+37948},{63976,63984,38029},{63986,64011,38038},{64016,64016,38064},{64018,
+64018,38065},{64021,64023,38066},{64025,64030,38069},{64034,64034,38075},{
+64037,64038,38076},{64042,65071,38078},{65074,65074,39108},{65093,65096,39109
+},{65107,65107,39113},{65112,65112,39114},{65127,65127,39115},{65132,65280,
+39116},{65375,65503,39265},{65510,65535,39394},{0,0,39420}};

Added: vendor/Python/current/Modules/cjkcodecs/mappings_hk.h
===================================================================
--- vendor/Python/current/Modules/cjkcodecs/mappings_hk.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/cjkcodecs/mappings_hk.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2340 @@
+static const ucs2_t __big5hkscs_decmap[6095] = {
+62211,62212,62213,62214,62215,268,62217,209,205,62220,62221,203,8168,62224,
+202,62226,62227,62228,62229,270,62231,62232,256,193,461,192,274,201,282,200,
+332,211,465,210,62245,7870,62247,7872,202,257,225,462,224,593,275,233,283,232,
+299,237,464,236,333,243,466,242,363,250,468,249,470,472,474,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,476,252,62276,7871,62278,
+7873,234,609,62282,62283,41897,4421,U,25866,U,U,20029,28381,40270,37343,U,U,
+30517,25745,20250,20264,20392,20822,20852,20892,20964,21153,21160,21307,21326,
+21457,21464,22242,22768,22788,22791,22834,22836,23398,23454,23455,23706,24198,
+24635,25993,26622,26628,26725,27982,28860,30005,32420,32428,32442,32455,32463,
+32479,32518,32567,33402,33487,33647,35270,35774,35810,36710,36711,36718,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,29713,31996,
+32205,26950,31433,21031,U,U,U,U,37260,30904,37214,32956,U,36107,33014,2535,U,
+U,32927,40647,19661,40393,40460,19518,40438,28686,40458,41267,13761,U,28314,
+33342,29977,U,18705,39532,39567,40857,31111,33900,7626,1488,10982,20004,20097,
+20096,20103,20159,20203,20279,13388,20413,15944,20483,20616,13437,13459,13477,
+20870,22789,20955,20988,20997,20105,21113,21136,21287,13767,21417,13649,21424,
+13651,21442,21539,13677,13682,13953,21651,21667,21684,21689,21712,21743,21784,
+21795,21800,13720,21823,13733,13759,21975,13765,32132,21797,U,3138,3349,20779,
+21904,11462,14828,833,36422,19896,38117,16467,32958,30586,11320,14900,18389,
+33117,27122,19946,25821,3452,4020,3285,4340,25741,36478,3734,3083,3940,11433,
+33366,17619,U,3398,39501,33001,18420,20135,11458,39602,14951,38388,16365,
+13574,21191,38868,30920,11588,40302,38933,U,17369,24741,25780,21731,11596,
+11210,4215,14843,4207,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,26330,26390,31136,25834,20562,3139,36456,8609,35660,1841,U,18443,
+425,16378,22643,11661,U,17864,1276,24727,3916,3478,21881,16571,17338,U,19124,
+10854,4253,33194,39157,3484,25465,14846,10101,36288,22177,25724,15939,U,42497,
+3593,10959,11465,U,4296,14786,14738,14854,33435,13688,24137,8391,22098,3889,
+11442,38688,13500,27709,20027,U,U,30068,11915,8712,42587,36045,3706,3124,
+26652,32659,4303,10243,10553,13819,20963,3724,3981,3754,16275,3888,3399,4431,
+3660,U,3755,2985,3400,4288,4413,16377,9878,25650,4013,13300,30265,11214,3454,
+3455,11345,11349,14872,3736,4295,3886,42546,27472,36050,36249,36042,38314,
+21708,33476,21945,U,40643,39974,39606,30558,11758,28992,33133,33004,23580,
+25970,33076,14231,21343,32957,37302,3834,3599,3703,3835,13789,19947,13833,
+3286,22191,10165,4297,3600,3704,4216,4424,33287,5205,3705,20048,11684,23124,
+4125,4126,4341,4342,22428,3601,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,30356,33485,4021,3707,20862,14083,4022,4480,21208,41661,
+18906,6202,16759,33404,22681,21096,13850,22333,31666,23400,18432,19244,40743,
+18919,39967,39821,23412,12605,22011,13810,22153,20008,22786,7105,63608,38737,
+134,20059,20155,13630,23587,24401,24516,14586,25164,25909,27514,27701,27706,
+28780,29227,20012,29357,18665,32594,31035,31993,32595,25194,13505,U,25419,
+32770,32896,26130,26961,21341,34916,35265,30898,35744,36125,38021,38264,38271,
+38376,36367,38886,39029,39118,39134,39267,38928,40060,40479,40644,27503,63751,
+20023,135,38429,25143,38050,20539,28158,40051,62842,15817,34959,16718,28791,
+23797,19232,20941,13657,23856,24866,35378,36775,37366,29073,26393,29626,12929,
+41223,15499,6528,19216,30948,29698,20910,34575,16393,27235,41658,16931,34319,
+U,31274,39239,35562,38741,28749,21284,8318,37876,30425,35299,62884,30685,
+20131,20464,20668,20015,20247,62891,21556,32139,22674,22736,7606,24210,24217,
+24514,10002,25995,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,13305,26905,27203,15459,27903,U,29184,17669,29580,16091,18963,23317,
+29881,35715,23716,22165,31379,31724,31939,32364,33528,34199,62924,34960,62926,
+36537,62928,36815,34143,39392,37409,62933,36281,5183,16497,17058,23066,U,U,U,
+39016,26475,17014,22333,U,34262,18811,33471,28941,19585,28020,23931,27413,
+28606,62956,62957,23446,62959,U,32347,23870,23880,23894,15868,14351,23972,
+23993,14368,14392,24130,24253,24357,24451,14600,14612,14655,14669,24791,24893,
+23781,14729,25015,25017,25039,14776,25132,25232,25317,25368,14840,22193,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,14851,25570,
+25595,25607,25690,14923,25792,23829,22049,40863,14999,25990,15037,26111,26195,
+15090,26258,15138,26390,15170,26532,26624,15192,26698,26756,15218,15217,15227,
+26889,26947,29276,26980,27039,27013,15292,27094,15325,27237,27252,27249,27266,
+15340,27289,15346,27307,27317,27348,27382,27521,27585,27626,27765,27818,15563,
+27906,27910,27942,28033,15599,28068,28081,28181,28184,28201,28294,35264,28347,
+28386,28378,40831,28392,28393,28452,28468,15686,16193,28545,28606,15722,15733,
+29111,23705,15754,28716,15761,28752,28756,28783,28799,28809,805,17345,13809,
+3800,16087,22462,28371,28990,22496,13902,27042,35817,23412,31305,22753,38105,
+31333,31357,22956,31419,31408,31426,31427,29137,25741,16842,31450,31453,31466,
+16879,21682,23553,31499,31573,31529,21262,23806,31650,31599,33692,23476,27775,
+31696,33825,31634,U,23840,15789,23653,33938,31738,U,31797,23745,31812,31875,
+18562,31910,26237,17784,31945,31943,31974,31860,31987,31989,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,32359,17693,28228,32093,
+28374,29837,32137,32171,28981,32179,U,16471,24617,32228,15635,32245,6137,
+32229,33645,U,24865,24922,32366,32402,17195,37996,32295,32576,32577,32583,
+31030,25296,39393,32663,25425,32675,5729,104,17756,14182,17667,33594,32762,
+25737,U,32776,32797,U,32815,41095,27843,32827,32828,32865,10004,18825,26150,
+15843,26344,26405,32935,35400,33031,33050,22704,9974,27775,25752,20408,25831,
+5258,33304,6238,27219,19045,19093,17530,33321,2829,27218,15742,20473,5373,
+34018,33634,27402,18855,13616,6003,15864,33450,26907,63892,16859,34123,33488,
+33562,3606,6068,14017,12669,13658,33403,33506,33560,16011,28067,27397,27543,
+13774,15807,33565,21996,33669,17675,28069,33708,U,33747,13438,28372,27223,
+34138,13462,28226,12015,33880,23524,33905,15827,17636,27303,33866,15541,31064,
+U,27542,28279,28227,34014,U,33681,17568,33939,34020,23697,16960,23744,17731,
+34100,23282,28313,17703,34163,17686,26559,34326,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,34341,34363,34241,28808,34306,5506,
+28877,63922,17770,34344,13896,6306,21495,29594,34430,34673,41208,34798,11303,
+34737,34778,34831,22113,34412,26710,17935,34885,34886,30176,15801,30180,34910,
+34972,18011,34996,34997,25537,35013,30583,30479,35207,35210,U,U,35239,35260,
+35365,35303,31012,31421,35484,30611,37374,35472,31321,31465,31546,16271,18195,
+31544,29052,35596,35615,21552,21861,35647,35660,35661,35497,19066,35728,35739,
+35503,5855,17941,34895,35995,32084,32143,63956,14117,32083,36054,32152,32189,
+36114,36099,6416,36059,28764,36113,19657,16080,36265,32770,4116,18826,15228,
+33212,28940,31463,36525,36534,36547,37588,36633,36653,33637,33810,36773,37635,
+41631,2640,36787,18730,35294,34109,15803,24312,12898,36857,40980,34492,34049,
+8997,14720,28375,36919,34108,31422,36961,34156,34315,37032,34579,37060,34534,
+37038,U,37223,15088,37289,37316,31916,35123,7817,37390,27807,37441,37474,
+21945,U,35526,15515,35596,21979,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,3377,37676,37739,35553,35819,28815,23235,35554,35557,
+18789,37444,35820,35897,35839,37747,37979,36540,38277,38310,37926,38304,28662,
+17081,9850,34520,4732,15918,18911,27676,38523,38550,16748,38563,28373,25050,
+38582,30965,35552,38589,21452,18849,27832,628,25616,37039,37093,19153,6421,
+13066,38705,34370,38710,18959,17725,17797,19177,28789,23361,38683,U,37333,
+38743,23370,37355,38751,37925,20688,12471,12476,38793,38815,38833,38846,38848,
+38866,38880,21612,38894,29724,37939,U,38901,37917,31098,19153,38964,38963,
+38987,39014,15118,29045,15697,1584,16732,22278,39114,39095,39112,39111,19199,
+27943,5843,21936,39137,39142,39148,37752,39225,18985,19314,38999,39173,39413,
+39436,39483,39440,39512,22309,14020,37041,39893,39648,39650,39685,39668,19470,
+39700,39725,34304,20532,39732,27048,14531,12413,39760,39744,40254,23109,6243,
+39822,16971,39938,39935,39948,40552,40404,40887,41362,41387,41185,41251,41439,
+40318,40323,41268,40462,26760,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,40388,8539,41363,41504,6459,41523,40249,41145,41652,40592,
+40597,40606,40610,19764,40618,40623,17252,40641,15200,14821,15645,20274,14270,
+35883,40706,40712,19350,37924,28066,40727,U,40761,22175,22154,40773,39352,
+37003,38898,33919,40802,40809,31452,40846,29206,19390,18805,18875,29047,18936,
+17224,19025,29598,35802,6394,31135,35198,36406,37737,37875,35396,37612,37761,
+37835,35180,17593,29207,16107,30578,31299,28880,17523,17400,29054,6127,28835,
+6334,13721,16071,6277,21551,6136,14114,5883,6201,14049,6004,6353,24395,14115,
+5824,22363,18981,5118,4776,5062,5302,34051,13990,U,33877,18836,29029,15921,
+21852,16123,28754,17652,14062,39325,28454,26617,14131,15381,15847,22636,6434,
+26640,16471,14143,16609,16523,16655,27681,21707,22174,26289,22162,4063,2984,
+3597,37830,35603,37788,20216,20779,14361,17462,20156,1125,895,20299,20362,
+22097,23144,427,971,14745,778,1044,13365,20265,704,36531,629,35546,524,20120,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,20685,
+20749,20386,20227,18958,16010,20290,20526,20588,20609,20428,20453,20568,20732,
+U,U,U,U,28278,13717,15929,16063,28018,6276,16009,20904,20931,1504,17629,1187,
+1170,1169,36218,35484,1806,21081,21156,2163,21217,U,18042,29068,17292,3104,
+18860,4324,27089,3613,U,16094,29849,29716,29782,29592,19342,19132,16525,21456,
+13700,29199,16585,21940,837,21709,3014,22301,37469,38644,37734,22493,22413,
+22399,13886,22731,23193,35398,5882,5999,5904,23084,22968,37519,23166,23247,
+23058,22854,6643,6241,17045,14069,27909,29763,23073,24195,23169,35799,1043,
+37856,29836,4867,28933,18802,37896,35323,37821,14240,23582,23710,24158,24136,
+6550,6524,15086,24269,23375,6403,6404,14081,6304,14045,5886,14035,33066,35399,
+7610,13426,35240,24332,24334,6439,6059,23147,5947,23364,34324,30205,34912,
+24702,10336,9771,24539,16056,9647,9662,37000,28531,25024,62,70,9755,24985,
+24984,24693,11419,11527,18132,37197,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,25713,18021,11114,14889,11042,13392,39146,11896,
+25399,42075,25782,25393,25553,18915,11623,25252,11425,25659,25963,26994,15348,
+12430,12973,18825,12971,21773,13024,6361,37951,26318,12937,12723,15072,16784,
+21892,35618,21903,5884,21851,21541,30958,12547,6186,12852,13412,12815,12674,
+17097,26254,27940,26219,19347,26160,30832,7659,26211,13010,13025,26142,22642,
+14545,14394,14268,15257,14242,13310,29904,15254,26511,17962,26806,26654,15300,
+27326,14435,14293,17543,27187,27218,27337,27397,6418,25873,26776,27212,15319,
+27258,27479,16320,15514,37792,37618,35818,35531,37513,32798,35292,37991,28069,
+28427,18924,U,16255,15759,28164,16444,23101,28170,22599,27940,30786,28987,
+17178,17014,28913,29264,29319,29332,18319,18213,20857,19108,1515,29818,16120,
+13919,19018,18711,24545,16134,16049,19167,35875,16181,24743,16115,29900,29756,
+37767,29751,17567,28138,17745,30083,16227,19673,19718,16216,30037,30323,42438,
+15129,29800,35532,18859,18830,15099,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,15821,19022,16127,18885,18675,37370,22322,37698,
+35555,6244,20703,21025,20967,30584,12850,30478,30479,30587,18071,14209,14942,
+18672,29752,29851,16063,19130,19143,16584,19094,25006,37639,21889,30750,30861,
+30856,30930,29648,31065,30529,22243,16654,U,33942,31141,27181,16122,31290,
+31220,16750,5862,16690,37429,31217,3404,18828,665,15802,5998,13719,21867,
+13680,13994,468,3085,31458,23129,9973,23215,23196,23053,603,30960,23082,23494,
+31486,16889,31837,31853,16913,23475,24252,24230,31949,18937,6064,31886,31868,
+31918,27314,32220,32263,32211,32590,25185,24924,31560,32151,24194,17002,27509,
+2326,26582,78,13775,22468,25618,25592,18786,32733,31527,2092,23273,23875,
+31500,24078,39398,34373,39523,27164,13375,14818,18935,26029,39455,26016,33920,
+28967,27857,17642,33079,17410,32966,33033,33090,26548,39107,27202,33378,33381,
+27217,33875,28071,34320,29211,23174,16767,6208,23339,6305,23268,6360,34464,
+63932,15759,34861,29730,23042,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,34926,20293,34951,35007,35046,35173,35149,22147,35156,
+30597,30596,35829,35801,35740,35321,16045,33955,18165,18127,14322,35389,35356,
+37960,24397,37419,17028,26068,28969,28868,6213,40301,35999,36073,32220,22938,
+30659,23024,17262,14036,36394,36519,19465,36656,36682,17140,27736,28603,8993,
+18587,28537,28299,6106,39913,14005,18735,37051,U,21873,18694,37307,37892,
+35403,16482,35580,37927,35869,35899,34021,35371,38297,38311,38295,38294,36148,
+29765,16066,18687,19010,17386,16103,12837,38543,36583,36454,36453,16076,18925,
+19064,16366,29714,29803,16124,38721,37040,26695,18973,37011,22495,U,37736,
+35209,35878,35631,25534,37562,23313,35689,18748,29689,16923,38811,38769,39224,
+3878,24001,35781,19122,38943,38106,37622,38359,37349,17600,35664,19047,35684,
+39132,35397,16128,37418,18725,33812,39227,39245,31494,15869,39323,19311,39338,
+39516,35685,22728,27279,39457,23294,39471,39153,19344,39240,39356,19389,19351,
+37757,22642,4866,22562,18872,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,5352,30788,10015,15800,26821,15741,37976,14631,24912,
+10113,10603,24839,40015,40019,40059,39989,39952,39807,39887,40493,39839,41461,
+41214,40225,19630,16644,40472,19632,40204,41396,41197,41203,39215,40357,33981,
+28178,28639,27522,34300,17715,28068,28292,28144,33824,34286,28160,14295,24676,
+31202,13724,13888,18733,18910,15714,37851,37566,37704,703,30905,37495,37965,
+20452,13376,36964,21853,30781,30804,30902,30795,5975,12745,18753,13978,20338,
+28634,28633,U,28702,21524,16821,22459,22771,22410,40214,22487,28980,13487,
+16812,29163,27712,20375,U,6069,35401,24844,23246,23051,17084,17544,14124,
+19323,35324,37819,37816,6358,3869,33906,27840,5139,17146,11302,17345,22932,
+15799,26433,32168,24923,24740,18873,18827,35322,37605,29666,16105,29876,35683,
+6303,16097,19123,27352,29683,29691,16086,19006,19092,6105,19046,935,5156,
+18917,29768,18710,28837,18806,37508,29670,37727,1278,37681,35534,35350,37766,
+35815,21973,18741,35458,29035,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,18755,3327,22180,1562,3051,3256,21762,31172,6138,32254,
+5826,19024,6226,17710,37889,14090,35520,18861,22960,6335,6275,29828,23201,
+14050,15707,14000,37471,23161,35457,6242,37748,15565,2740,19094,14730,20724,
+15721,15692,5020,29045,17147,33304,28175,37092,17643,27991,32335,28775,27823,
+15574,16365,15917,28162,28428,15727,1013,30033,14012,13512,18048,16090,18545,
+22980,37486,18750,36673,35868,27584,22546,22472,14038,5202,28926,17250,19057,
+12259,4784,9149,26809,26983,5016,13541,31732,14047,35459,14294,13306,19615,
+27162,13997,27831,33854,17631,17614,27942,27985,27778,28638,28439,28937,33597,
+5946,33773,27776,28755,6107,22921,23170,6067,23137,23153,6405,16892,14125,
+23023,5948,14023,29070,37776,26266,17061,23150,23083,17043,27179,16121,30518,
+17499,17098,28957,16985,35297,20400,27944,23746,17614,32333,17341,27148,16982,
+4868,28838,28979,17385,15781,27871,63525,19023,32357,23019,23855,15859,24412,
+19037,6111,32164,33830,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,21637,15098,13056,532,22398,2261,1561,16357,8094,41654,28675,
+37211,23920,29583,31955,35417,37920,20424,32743,29389,29456,31476,29496,29497,
+22262,29505,29512,16041,31512,36972,29173,18674,29665,33270,16074,30476,16081,
+27810,22269,29721,29726,29727,16098,16112,16116,16122,29907,16142,16211,30018,
+30061,30066,30093,16252,30152,30172,16320,30285,16343,30324,16348,30330,20316,
+29064,22051,35200,22633,16413,30531,16441,26465,16453,13787,30616,16490,16495,
+23646,30654,30667,22770,30744,28857,30748,16552,30777,30791,30801,30822,33864,
+21813,31027,26627,31026,16643,16649,31121,31129,36795,31238,36796,16743,31377,
+16818,31420,33401,16836,31439,31451,16847,20001,31586,31596,31611,31762,31771,
+16992,17018,31867,31900,17036,31928,17044,31981,36755,28864,3279,32207,32212,
+32208,32253,32686,32692,29343,17303,32800,32805,31545,32814,32817,32852,15820,
+22452,28832,32951,33001,17389,33036,29482,33038,33042,30048,33044,17409,15161,
+33110,33113,33114,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,17427,22586,33148,33156,17445,33171,17453,33189,22511,33217,33252,
+33364,17551,33446,33398,33482,33496,33535,17584,33623,38505,27018,33797,28917,
+33892,24803,33928,17668,33982,34017,34040,34064,34104,34130,17723,34159,34160,
+34272,17783,34418,34450,34482,34543,38469,34699,17926,17943,34990,35071,35108,
+35143,35217,31079,35369,35384,35476,35508,35921,36052,36082,36124,18328,22623,
+36291,18413,20206,36410,21976,22356,36465,22005,36528,18487,36558,36578,36580,
+36589,36594,36791,36801,36810,36812,36915,39364,18605,39136,37395,18718,37416,
+37464,37483,37553,37550,37567,37603,37611,37619,37620,37629,37699,37764,37805,
+18757,18769,40639,37911,21249,37917,37933,37950,18794,37972,38009,38189,38306,
+18855,38388,38451,18917,26528,18980,38720,18997,38834,38850,22100,19172,24808,
+39097,19225,39153,22596,39182,39193,20916,39196,39223,39234,39261,39266,19312,
+39365,19357,39484,39695,31363,39785,39809,39901,39921,39924,19565,39968,14191,
+7106,40265,39994,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,40702,22096,40339,40381,40384,40444,38134,36790,40571,40620,40625,
+40637,40646,38108,40674,40689,40696,31432,40772,148,695,928,26906,38083,22956,
+1239,22592,38081,14265,1493,1557,1654,5818,22359,29043,2754,2765,3007,21610,
+63547,3019,21662,3067,3131,3155,3173,3196,24807,3213,22138,3253,3293,3309,
+3439,3506,3528,26965,39983,34725,3588,3598,3799,3984,3885,3699,23584,4028,
+24075,4188,4175,4214,26398,4219,4232,4246,13895,4287,4307,4399,4411,21348,
+33965,4835,4981,4918,35713,5495,5657,6083,6087,20088,28859,6189,6506,6701,
+6725,7210,7280,7340,7880,25283,7893,7957,29080,26709,8261,27113,14024,8828,
+9175,9210,10026,10353,10575,33533,10599,10643,10965,35237,10984,36768,11022,
+38840,11071,38983,39613,11340,U,11400,11447,23528,11528,11538,11703,11669,
+11842,12148,12236,12339,12390,13087,13278,24497,26184,26303,31353,13671,13811,
+U,18874,U,13850,14102,U,838,22709,26382,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,26904,15015,30295,24546,15889,16057,30206,8346,
+18640,19128,16665,35482,17134,17165,16443,17204,17302,19013,1482,20946,1553,
+22943,7848,15294,15615,17412,17622,22408,18036,14747,18223,34280,39369,14178,
+8643,35678,35662,U,18450,18683,18965,29193,19136,3192,22885,20133,20358,1913,
+36570,20524,21135,22335,29041,21145,21529,16202,19111,21948,21574,21614,27474,
+U,13427,21823,30258,21854,18200,21858,21862,22471,18751,22621,20582,13563,
+13260,U,22787,18300,35144,23214,23433,23558,7568,22433,29009,U,24834,31762,
+36950,25010,20378,35682,25602,25674,23899,27639,U,25732,6428,35562,18934,
+25736,16367,25874,19392,26047,26293,10011,37989,22497,24981,23079,63693,U,
+22201,17697,26364,20074,18740,38486,28047,27837,13848,35191,26521,26734,25617,
+26718,U,26823,31554,37056,2577,26918,U,26937,31301,U,27130,39462,27181,13919,
+25705,33,31107,27188,27483,23852,13593,U,27549,18128,27812,30011,34917,28078,
+22710,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+14108,9613,28747,29133,15444,29312,29317,37505,8570,29323,37680,29414,18896,
+27705,38047,29776,3832,34855,35061,10534,33907,6065,28344,18986,6176,14756,
+14009,U,U,17727,26294,40109,39076,35139,30668,30808,22230,16607,5642,14753,
+14127,33000,5061,29101,33638,31197,37288,U,19639,28847,35243,31229,31242,
+31499,32102,16762,31555,31102,32777,28597,41695,27139,33560,21410,28167,37823,
+26678,38749,33135,32803,27061,5101,12847,32840,23941,35888,32899,22293,38947,
+35145,23979,18824,26046,27093,21458,19109,16257,15377,26422,32912,33012,33070,
+8097,33103,33161,33199,33306,33542,33583,33674,13770,33896,34474,18682,25574,
+35158,30728,37461,35256,17394,35303,17375,35304,35654,35796,23032,35849,U,
+36805,37100,U,37136,37180,15863,37214,19146,36816,29327,22155,38119,38377,
+38320,38328,38706,39121,39241,39274,39363,39464,39694,40282,40347,32415,40696,
+40739,19620,38215,41619,29090,41727,19857,36882,42443,19868,3228,36798,21953,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,36794,
+9392,36793,19091,17673,32383,28502,27313,20202,13540,35628,30877,14138,36480,
+6133,32804,35692,35737,31294,26287,15851,30293,15543,22069,22870,20122,24193,
+25176,22207,3693,36366,23405,16008,19614,25566,U,6134,6267,25904,22061,23626,
+21530,21265,15814,40344,19581,22050,22046,32585,24280,22901,15680,34672,19996,
+4074,3401,14010,33047,40286,36120,30267,40005,30286,30649,37701,21554,33096,
+33527,22053,33074,33816,32957,21994,31074,22083,21526,3741,13774,22021,22001,
+26353,33506,13869,30004,22000,21946,21655,21874,3137,3222,24272,20808,3702,
+11362,3746,40619,32090,21982,4213,25245,38765,21652,36045,29174,37238,25596,
+25529,25598,21865,11075,40050,11955,20890,13535,3495,20903,21581,21790,21779,
+30310,36397,26762,30129,32950,34820,34694,35015,33206,33820,4289,17644,29444,
+18182,23440,33547,26771,22139,9972,32047,16803,32115,28368,29366,37232,4569,
+37384,15612,42665,3756,3833,29286,7330,18254,20418,32761,4075,16634,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,40029,25887,11680,
+18675,18400,40316,4076,3594,U,30115,4077,U,24648,4487,29091,32398,40272,19994,
+19972,13687,23309,27826,21351,13996,14812,21373,13989,17944,22682,19310,33325,
+21579,22442,23189,2425,U,14930,9317,29556,40620,19721,39917,15614,40752,19547,
+20393,38302,40926,33884,15798,29362,26547,14112,25390,32037,16119,15916,14890,
+36872,21196,15988,13946,17897,1166,30272,23280,3766,30842,18358,22695,16575,
+22140,39819,23924,30292,42036,40581,19681,U,14331,24857,12506,17394,U,22109,
+4777,22439,18787,40454,21044,28846,13741,U,40316,31830,39737,22494,5996,23635,
+25811,38096,25397,29028,34477,3368,27938,19170,3441,U,20990,7951,23950,38659,
+7633,40577,36940,31519,39682,23761,31651,25192,25397,39679,31695,39722,31870,
+U,31810,31878,39957,31740,39689,U,39963,18750,40794,21875,23491,20477,40600,
+20466,21088,15878,21201,22375,20566,22967,24082,38856,40363,36700,21609,38836,
+39232,38842,21292,24880,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,26924,21466,39946,40194,19515,38465,27008,20646,30022,5997,
+39386,21107,U,37209,38529,37212,U,37201,36503,25471,27939,27338,22033,37262,
+30074,25221,1020,29519,31856,23585,15613,U,18713,30422,39837,20010,3284,33726,
+34882,U,23626,27072,U,22394,21023,24053,20174,27697,498,20281,21660,21722,
+21146,36226,13822,U,13811,U,27474,37244,40869,39831,38958,39092,39610,40616,
+40580,29050,31508,U,27642,34840,32632,U,22048,42570,36471,40787,U,36308,36431,
+40476,36353,25218,33661,36392,36469,31443,19063,31294,30936,27882,35431,30215,
+35418,40742,27854,34774,30147,41650,30803,63552,36108,29410,29553,35629,29442,
+29937,36075,19131,34351,24506,34976,17591,U,6203,28165,U,35454,9499,U,24829,
+30311,39639,40260,37742,39823,34805,U,U,36087,29484,38689,39856,13782,29362,
+19463,31825,39242,24921,24921,19460,40598,24957,U,22367,24943,25254,25145,U,
+14940,25058,21418,13301,25444,26626,13778,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,23895,35778,36826,36409,U,20697,7494,30982,
+21298,38456,3899,16485,U,30718,U,31938,24346,31962,31277,32870,32867,32077,
+29957,29938,35220,33306,26380,32866,29830,32859,29936,33027,30500,35209,26572,
+30035,28369,34729,34766,33224,34700,35401,36013,35651,30507,29944,34010,13877,
+27058,36262,U,35241,U,28089,34753,16401,29927,15835,29046,24740,24988,15569,U,
+24695,U,32625,35629,U,24809,19326,21024,15384,15559,24279,30294,21809,6468,
+4862,39171,28124,28845,23745,25005,35343,13943,238,26694,20238,17762,23327,
+25420,40784,40614,25195,9312,9313,9314,9315,9316,9317,9318,9319,9320,9321,
+9332,9333,9334,9335,9336,9337,9338,9339,9340,9341,8560,8561,8562,8563,8564,
+8565,8566,8567,8568,8569,20022,20031,20101,20128,20866,20886,20907,21241,
+21304,21353,21430,22794,23424,24027,12083,24191,U,24400,24417,25908,U,30098,U,
+36789,U,168,710,12541,12542,12445,12446,U,U,12293,12294,12295,12540,65339,
+65341,10045,12353,12354,12355,12356,12357,12358,12359,12360,12361,12362,12363,
+12364,12365,12366,12367,12368,12369,12370,12371,12372,12373,12374,12375,12376,
+12377,12378,12379,12380,12381,12382,12383,12384,12385,12386,12387,12388,12389,
+12390,12391,12392,12393,12394,12395,12396,12397,12398,12399,12400,12401,12402,
+12403,12404,12405,12406,12407,12408,12409,12410,12411,12412,12413,12414,12415,
+12416,12417,12418,12419,12420,12421,12422,12423,12424,12425,12426,12427,12428,
+12429,12430,12431,12432,12433,12434,12435,12449,12450,12451,12452,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,12453,12454,12455,
+12456,12457,12458,12459,12460,12461,12462,12463,12464,12465,12466,12467,12468,
+12469,12470,12471,12472,12473,12474,12475,12476,12477,12478,12479,12480,12481,
+12482,12483,12484,12485,12486,12487,12488,12489,12490,12491,12492,12493,12494,
+12495,12496,12497,12498,12499,12500,12501,12502,12503,12504,12505,12506,12507,
+12508,12509,12510,12511,12512,12513,12514,12515,12516,12517,12518,12519,12520,
+12521,12522,12523,12524,12525,12526,12527,12528,12529,12530,12531,12532,12533,
+12534,1040,1041,1042,1043,1044,1045,1025,1046,1047,1048,1049,1050,1051,1052,
+1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,
+1068,1069,1070,1071,1072,1073,1074,1075,1076,1077,1105,1078,1079,1080,1081,
+1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,
+1097,1098,1099,1100,1101,1102,1103,8679,8632,8633,63461,204,20058,138,20994,
+63466,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+63467,20872,63469,30215,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,65506,65508,65287,65282,12849,8470,8481,12443,12444,
+11904,11908,11910,11911,11912,11914,11916,11917,11925,11932,11933,11941,11943,
+11946,11948,11950,11958,11964,11966,11974,11978,11980,11981,11983,11990,11991,
+11998,12003,U,U,U,643,592,603,596,629,339,248,331,650,618,30849,37561,35023,
+22715,24658,31911,23290,9556,9574,9559,9568,9580,9571,9562,9577,9565,9554,
+9572,9557,9566,9578,9569,9560,9575,9563,9555,9573,9558,9567,9579,9570,9561,
+9576,9564,9553,9552,9581,9582,9584,9583,65517,1351,37595,1503,16325,34124,
+17077,29679,20917,13897,18754,35300,37700,6619,33518,15560,30780,26436,25311,
+18739,35242,672,27571,4869,20395,9453,20488,27945,31364,13824,19121,9491,U,
+894,24484,896,839,28379,1055,U,20737,13434,20750,39020,14147,33814,18852,1159,
+20832,13236,20842,3071,8444,741,9520,1422,12851,6531,23426,34685,1459,15513,
+20914,20920,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,40244,20937,20943,20945,15580,20947,19110,20915,20962,21314,20973,33741,
+26942,14125,24443,21003,21030,21052,21173,21079,21140,21177,21189,31765,34114,
+21216,34317,27411,U,35550,21833,28377,16256,2388,16364,21299,U,3042,27851,
+5926,26651,29653,24650,16042,14540,5864,29149,17570,21357,21364,34475,21374,U,
+5526,5651,30694,21395,35483,21408,21419,21422,29607,22386,16217,29596,21441,
+21445,27721,20041,22526,21465,15019,2959,21472,16363,11683,21494,3191,21523,
+28793,21803,26199,27995,21613,27475,3444,21853,21647,21668,18342,5901,3805,
+15796,3405,35260,9880,21831,19693,21551,29719,21894,21929,U,6359,16442,17746,
+17461,26291,4276,22071,26317,12938,26276,26285,22093,22095,30961,22257,38791,
+21502,22272,22255,22253,35686,13859,4687,22342,16805,27758,28811,22338,14001,
+27774,22502,5142,22531,5204,17251,22566,19445,22620,22698,13665,22752,22748,
+4668,22779,23551,22339,41296,17016,37843,13729,22815,26790,14019,28249,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,5694,23076,
+21843,5778,34053,22985,3406,27777,27946,6108,23001,6139,6066,28070,28017,6184,
+5845,23033,28229,23211,23139,14054,18857,U,14088,23190,29797,23251,28577,9556,
+15749,6417,14130,5816,24195,21200,23414,25992,23420,31246,16388,18525,516,
+23509,24928,6708,22988,1445,23539,23453,19728,23557,6980,23571,29646,23572,
+7333,27432,23625,18653,23685,23785,23791,23947,7673,7735,23824,23832,23878,
+7844,23738,24023,33532,14381,18689,8265,8563,33415,14390,15298,24110,27274,U,
+24186,17596,3283,21414,20151,U,21416,6001,24073,24308,33922,24313,24315,14496,
+24316,26686,37915,24333,449,63636,15070,18606,4922,24378,26760,9168,U,9329,
+24419,38845,28270,24434,37696,35382,24487,23990,15711,21072,8042,28920,9832,
+37334,670,35369,24625,26245,6263,14691,15815,13881,22416,10164,31089,15936,
+24734,U,24755,18818,18831,31315,29860,20705,23200,24932,33828,24898,63654,
+28370,24961,20980,1622,24967,23466,16311,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,10335,25043,35741,39261,25040,14642,10624,
+10433,24611,24924,25886,25483,280,25285,6000,25301,11789,25452,18911,14871,
+25656,25592,5006,6140,U,28554,11830,38932,16524,22301,25825,25829,38011,14950,
+25658,14935,25933,28438,18984,18979,25989,25965,25951,12414,26037,18752,19255,
+26065,16600,6185,26080,26083,24543,13312,26136,12791,12792,26180,12708,12709,
+26187,3701,26215,20966,26227,U,7741,12849,34292,12744,21267,30661,10487,39332,
+26370,17308,18977,15147,27130,14274,U,26471,26466,16845,37101,26583,17641,
+26658,28240,37436,26625,13286,28064,26717,13423,27105,27147,35551,26995,26819,
+13773,26881,26880,15666,14849,13884,15232,26540,26977,35402,17148,26934,27032,
+15265,969,33635,20624,27129,13913,8490,27205,14083,27293,15347,26545,27336,
+37276,15373,27421,2339,24798,27445,27508,10189,28341,15067,949,6488,14144,
+21537,15194,27617,16124,27612,27703,9355,18673,27473,27738,33318,27769,15804,
+17605,15805,16804,18700,18688,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,15561,14053,15595,3378,39811,12793,9361,32655,26679,27941,
+28065,28139,28054,27996,28284,28420,18815,16517,28274,34099,28532,20935,U,U,
+33838,35617,U,15919,29779,16258,31180,28239,23185,12363,28664,14093,28573,
+15920,28410,5271,16445,17749,37872,28484,28508,15694,28532,37232,15675,28575,
+16708,28627,16529,16725,16441,16368,16308,16703,20959,16726,16727,16704,25053,
+28747,28798,28839,28801,28876,28885,28886,28895,16644,15848,29108,29078,17015,
+28971,28997,23176,29002,U,23708,17253,29007,37730,17089,28972,17498,18983,
+18978,29114,35816,28861,29198,37954,29205,22801,37955,29220,37697,22021,29230,
+29248,18804,26813,29269,29271,15957,12356,26637,28477,29314,U,29483,18467,
+34859,18669,34820,29480,29486,29647,29610,3130,27182,29641,29769,16866,5863,
+18980,26147,14021,18871,18829,18939,29687,29717,26883,18982,29753,1475,16087,
+U,10413,29792,36530,29767,29668,29814,33721,29804,14128,29812,37873,27180,
+29826,18771,19084,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,16735,19065,35727,23366,35843,6302,29896,6536,29966,U,29982,36569,
+6731,23511,36524,37765,30029,30026,30055,30062,20354,16132,19731,30094,29789,
+30110,30132,30210,30252,30289,30287,30319,30326,25589,30352,33263,14328,26897,
+26894,30369,30373,30391,30412,28575,33890,20637,20861,7708,30494,30502,30528,
+25775,21024,30552,12972,30639,35172,35176,5825,30708,U,4982,18962,26826,30895,
+30919,30931,38565,31022,21984,30935,31028,30897,30220,36792,34948,35627,24707,
+9756,31110,35072,26882,31104,22615,31133,31545,31036,31145,28202,28966,16040,
+31174,37133,31188,
+};
+
+static const struct dbcs_index big5hkscs_decmap[256] = {
+{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{__big5hkscs_decmap+0,64,170},{__big5hkscs_decmap+107,64,254},{
+__big5hkscs_decmap+298,64,254},{__big5hkscs_decmap+489,64,253},{
+__big5hkscs_decmap+679,64,220},{__big5hkscs_decmap+836,96,254},{
+__big5hkscs_decmap+995,64,254},{__big5hkscs_decmap+1186,64,253},{
+__big5hkscs_decmap+1376,64,254},{__big5hkscs_decmap+1567,64,254},{
+__big5hkscs_decmap+1758,64,254},{__big5hkscs_decmap+1949,64,254},{
+__big5hkscs_decmap+2140,64,254},{__big5hkscs_decmap+2331,64,254},{
+__big5hkscs_decmap+2522,64,254},{__big5hkscs_decmap+2713,64,254},{
+__big5hkscs_decmap+2904,64,254},{__big5hkscs_decmap+3095,64,254},{
+__big5hkscs_decmap+3286,64,254},{__big5hkscs_decmap+3477,64,254},{
+__big5hkscs_decmap+3668,64,254},{__big5hkscs_decmap+3859,64,254},{
+__big5hkscs_decmap+4050,64,254},{__big5hkscs_decmap+4241,64,254},{
+__big5hkscs_decmap+4432,64,254},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{__big5hkscs_decmap+4623,161,254},{__big5hkscs_decmap+4717,
+64,254},{__big5hkscs_decmap+4908,64,254},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,
+0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__big5hkscs_decmap+5099,214,254},{
+__big5hkscs_decmap+5140,64,254},{__big5hkscs_decmap+5331,64,254},{
+__big5hkscs_decmap+5522,64,254},{__big5hkscs_decmap+5713,64,254},{
+__big5hkscs_decmap+5904,64,254},{0,0,0},
+};
+
+static const unsigned char big5hkscs_phint_0[] = {
+160,89,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,1,8,0,0,0,0,0,0,0,0,0,0,
+0,0,2,44,0,30,0,0,0,0,0,64,174,86,238,249,221,228,33,23,0,0,0,128,219,73,31,
+76,130,55,237,228,223,189,247,245,239,31,100,136,94,253,223,11,0,0,0,192,247,
+143,0,131,5,0,8,201,8,4,129,64,68,5,11,9,35,1,32,2,0,0,0,32,145,24,0,96,0,168,
+6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,128,0,64,86,50,65,32,198,
+80,72,2,0,0,0,0,160,192,168,1,164,85,48,58,209,106,46,159,176,241,65,136,5,57,
+80,4,0,0,0,0,172,163,20,192,1,2,13,45,134,136,107,34,110,192,204,245,218,10,
+24,122,0,0,0,0,50,115,0,15,68,252,3,33,49,32,25,232,96,160,65,19,82,42,250,9,
+0,0,0,0,190,1,129,16,16,96,183,137,193,218,237,250,242,59,200,167,11,77,155,
+11,0,0,0,0,24,0,220,116,19,94,192,168,0,60,240,208,68,224,172,60,75,230,29,15,
+0,0,0,128,189,88,120,55,191,187,216,218,8,134,192,108,148,192,176,125,14,136,
+145,3,0,0,0,64,99,139,197,22,24,68,124,152,75,112,3,92,219,185,208,26,40,149,
+106,1,0,0,0,0,232,7,36,34,32,136,4,106,32,215,29,50,15,162,149,11,4,67,65,1,0,
+0,0,104,48,64,19,207,57,183,16,8,7,4,180,33,217,183,15,11,127,69,91,0,0,0,0,
+236,116,236,196,4,41,49,2,48,250,252,27,175,78,38,164,183,110,50,24,0,0,0,0,
+220,22,67,34,1,0,0,128,0,0,0,4,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,
+0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,28,241,220,190,126,252,186,123,238,249,55,249,
+93,165,255,31,215,2,0,0,0,128,63,255,213,117,117,187,120,231,62,245,177,173,
+189,75,150,188,46,181,85,2,0,0,0,192,109,51,55,176,233,204,159,42,126,83,204,
+255,77,234,218,198,255,55,165,0,0,0,0,160,192,252,222,50,83,161,28,0,0,33,176,
+71,0,74,32,32,233,215,235,0,0,0,0,160,183,1,64,49,101,247,12,36,64,48,45,144,
+123,18,0,0,2,0,0,0,0,0,0,0,8,80,144,69,0,4,0,0,32,64,4,161,128,96,2,0,32,0,8,
+0,0,0,0,148,8,2,32,40,0,0,1,8,254,251,73,
+};
+
+static const unsigned char big5hkscs_phint_11939[] = {
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,128,2,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,
+};
+
+static const unsigned char big5hkscs_phint_21733[] = {
+0,0,0,0,0,26,172,248,250,90,192,250,51,0,0,0,0,0,129,0,160,156,130,144,9,1,
+180,192,176,3,86,2,160,66,45,136,1,0,0,0,0,146,119,139,96,5,201,33,6,70,56,96,
+72,192,180,36,222,132,224,192,36,0,0,0,0,205,80,197,52,192,40,162,173,124,153,
+24,88,18,34,196,66,162,83,142,30,0,0,0,128,52,135,11,21,209,64,250,61,0,4,210,
+5,72,8,22,230,28,165,0,8,0,0,0,192,45,22,20,128,24,58,212,25,136,28,138,4,
+};
+
+static const DBCHAR __big5hkscs_bmp_encmap[26537] = {
+50904,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,34905,34903,N,N,N,N,N,N,
+34909,34907,34918,N,N,N,N,N,N,N,34913,34911,N,N,N,N,N,N,N,N,N,N,N,N,34922,
+34920,N,N,N,N,N,N,34927,34925,34983,N,34931,34929,N,N,N,N,34935,34933,N,N,N,N,
+51451,34939,34937,N,34978,34902,34919,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,34906,
+34924,N,N,N,N,N,N,34908,34926,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,34928,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,51452,34910,34932,N,N,N,N,N,
+51450,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,34936,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,34904,34921,N,34930,34912,34934,N,34938,N,34940,N,34941,N,
+34942,N,34977,51446,34923,N,N,51448,N,N,N,N,N,N,51447,N,N,N,N,N,34984,N,N,N,N,
+N,N,N,N,51454,N,N,N,N,N,N,N,N,N,N,51449,N,N,N,N,N,N,N,N,N,N,N,N,N,51445,N,N,N,
+N,N,N,51453,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,50905,51193,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,51187,51188,51189,51190,51191,51192,51194,51195,51196,51197,
+51198,51264,51265,51266,51267,51268,51269,51270,51271,51272,51273,51274,51275,
+51276,51277,51278,51279,51280,51281,51282,51283,51284,51285,51286,51287,51288,
+51289,51290,51292,51293,51294,51295,51296,51297,51298,51299,51300,51301,51302,
+51303,51304,51305,51306,51307,51308,51309,51310,51311,51312,51313,51314,51315,
+51316,51317,N,51291,34915,34980,34917,34982,51410,N,N,N,N,N,N,N,N,N,N,51411,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+50869,50870,50871,50872,50873,50874,50875,50876,50877,50878,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,51319,51320,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,51318,50849,50850,50851,
+50852,50853,50854,50855,50856,50857,50858,N,N,N,N,N,N,N,N,N,N,50859,50860,
+50861,50862,50863,50864,50865,50866,50867,50868,63993,63992,63974,63983,63965,
+63976,63985,63967,63980,63989,63971,63982,63991,63973,63977,63986,63968,63979,
+63988,63970,63975,63984,63966,63981,63990,63972,63978,63987,63969,63994,63995,
+63997,63996,50918,51414,N,N,N,51415,N,51416,51417,51418,N,51419,N,51420,51421,
+N,N,N,N,N,N,N,51422,N,N,N,N,N,N,51423,51424,N,N,N,N,N,N,N,51425,N,51426,N,N,
+51427,N,51428,N,51429,N,N,N,N,N,N,N,51430,N,N,N,N,N,51431,N,51432,N,N,N,N,N,N,
+N,51433,N,N,N,51434,N,51435,51436,N,51437,N,N,N,N,N,N,51438,51439,N,N,N,N,N,N,
+51440,N,N,N,N,51441,50893,50912,50913,50914,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,50919,50920,50921,50922,50923,50924,50925,50926,50927,50928,50929,50930,
+50931,50932,50933,50934,50935,50936,50937,50938,50939,50940,50941,50942,51008,
+51009,51010,51011,51012,51013,51014,51015,51016,51017,51018,51019,51020,51021,
+51022,51023,51024,51025,51026,51027,51028,51029,51030,51031,51032,51033,51034,
+51035,51036,51037,51038,51039,51040,51041,51042,51043,51044,51045,51046,51047,
+51048,51049,51050,51051,51052,51053,51054,51055,51056,51057,51058,51059,51060,
+51061,51062,51063,51064,51065,51066,N,N,N,N,N,N,N,51412,51413,50908,50909,N,N,
+51067,51068,51069,51070,51105,51106,51107,51108,51109,51110,51111,51112,51113,
+51114,51115,51116,51117,51118,51119,51120,51121,51122,51123,51124,51125,51126,
+51127,51128,51129,51130,51131,51132,51133,51134,51135,51136,51137,51138,51139,
+51140,51141,51142,51143,51144,51145,51146,51147,51148,51149,51150,51151,51152,
+51153,51154,51155,51156,51157,51158,51159,51160,51161,51162,51163,51164,51165,
+51166,51167,51168,51169,51170,51171,51172,51173,51174,51175,51176,51177,51178,
+51179,51180,51181,51182,51183,51184,51185,51186,N,N,N,N,N,50915,50906,50907,
+51409,37495,N,N,N,N,N,N,N,N,N,N,38623,N,N,N,N,N,N,N,N,N,N,N,35285,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37837,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39903,N,N,
+N,N,N,N,64104,N,N,35290,36697,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35291,N,
+N,36701,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35292,N,N,N,N,N,N,N,N,N,38647,N,N,N,N,N,N,
+N,N,N,N,N,N,35546,N,N,N,N,35804,N,N,N,N,N,N,38875,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,40531,N,N,N,N,40362,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,39914,35438,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35784,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,35304,N,35306,N,N,N,N,N,35915,N,N,N,N,N,N,N,64368,N,N,N,N,N,N,N,N,N,
+N,N,35309,N,N,38109,N,35310,N,N,N,N,40628,35539,N,N,N,N,N,N,N,N,N,N,N,37595,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38107,35321,N,N,N,N,N,N,N,N,64378,N,N,N,
+35323,N,N,N,N,N,N,N,40700,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35324,N,35263,N,N,
+N,35326,N,35302,N,N,40262,N,N,N,40430,N,N,N,41086,N,N,N,41064,N,N,N,N,39145,N,
+35688,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36349,35774,40921,N,N,N,N,N,N,N,
+35563,N,N,40919,35690,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40028,N,35761,N,N,N,N,N,N,N,
+N,64350,N,N,N,N,N,N,N,N,N,40435,N,N,N,N,N,N,N,41168,N,N,N,64614,N,N,N,N,37609,
+N,N,N,N,N,N,N,N,39660,36779,64072,N,N,N,N,36421,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,40047,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40670,N,N,N,N,N,N,
+35311,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38633,N,N,N,N,N,N,N,N,N,
+N,40635,N,N,N,N,38110,N,40632,N,N,N,38842,64357,N,N,N,38358,N,N,N,40123,N,N,
+38874,N,N,N,N,36677,N,64381,37208,65124,N,38998,39757,N,N,N,N,N,N,N,N,N,N,
+37723,38343,N,38887,N,N,N,N,N,N,37721,N,N,N,37365,38840,N,N,64930,64438,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,37626,37719,N,35750,N,N,N,N,64441,N,38832,N,N,64964,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,40097,N,N,N,N,N,37362,37369,N,36849,N,N,N,N,N,N,38725,
+38995,N,N,65144,N,64449,37457,N,N,N,N,N,N,40365,N,N,N,N,N,64876,N,N,64107,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39874,N,N,N,N,N,N,N,N,
+N,N,N,N,39547,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,35680,N,N,N,N,N,N,N,N,37707,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,39613,N,N,N,N,37303,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38324,N,N,N,N,N,65221,
+N,N,40688,36196,N,N,N,N,N,N,N,N,N,37481,N,N,N,N,N,N,36199,N,N,N,N,N,N,N,N,N,N,
+N,N,64490,N,N,N,N,N,N,N,N,64495,N,36200,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37867,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,64578,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,37222,N,N,N,N,N,N,N,N,64205,N,N,N,N,37853,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35788,36205,N,N,N,N,N,
+N,N,N,N,N,N,36206,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38568,N,N,N,N,N,N,N,N,N,
+N,64678,N,N,N,N,N,N,N,N,N,N,N,N,36207,N,N,N,N,N,N,N,N,N,N,N,N,N,36208,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64612,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,36960,N,N,N,N,N,N,N,N,36212,38851,N,N,N,N,N,N,N,35536,N,N,N,
+N,N,N,37492,N,39870,N,N,N,N,N,40136,N,N,40122,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,36216,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,40633,N,N,N,N,N,38234,N,N,37300,N,N,N,N,N,N,35400,N,N,N,N,N,N,N,N,N,N,N,
+36221,N,N,35453,N,N,35522,64842,N,36257,N,N,35537,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,64692,35655,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37796,40666,N,N,N,N,N,N,N,N,N,
+35409,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36262,N,N,N,N,N,N,40645,N,N,
+N,N,64708,N,N,N,N,41080,N,38069,N,N,N,N,N,N,N,64706,35435,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+36267,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64232,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,36269,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+64585,N,37825,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36975,N,36272,N,N,N,N,N,N,N,N,
+38014,37114,N,N,N,N,N,N,N,N,N,N,38009,N,N,N,N,N,N,N,N,36274,N,N,N,N,N,N,N,N,
+64750,N,N,N,N,N,N,N,N,N,N,N,N,N,39291,N,N,N,N,N,N,N,N,36276,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,36279,N,N,N,N,N,N,N,37299,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,36283,36282,N,N,N,N,N,N,N,N,36284,36932,N,N,N,64844,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,37860,N,N,37856,N,N,N,N,N,N,N,64851,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36291,N,39864,N,N,N,64496,N,37865,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,37878,N,N,N,N,N,36293,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36298,
+N,N,N,N,N,36300,64861,37813,64865,N,N,N,40184,N,N,N,37458,N,N,41192,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40101,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35926,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36310,N,38848,N,N,N,41182,N,N,N,N,
+38866,N,N,N,N,N,64165,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64931,N,N,N,36315,36527,N,N,
+N,N,N,N,N,N,N,37301,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64841,N,N,N,N,N,N,
+N,N,64977,N,N,N,N,N,N,N,N,N,N,36331,N,N,N,N,N,38854,N,64974,N,N,37116,N,N,N,N,
+N,N,N,N,N,N,N,N,N,64601,N,N,38614,N,N,N,N,N,N,38853,36335,N,N,N,N,38871,N,N,N,
+N,N,36336,N,N,N,N,N,N,N,38566,N,N,N,N,N,N,N,64447,N,N,N,N,36339,N,N,N,N,37961,
+N,36341,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39026,N,N,N,N,N,N,N,36459,N,N,N,
+N,N,N,64253,N,N,N,N,N,N,N,N,N,N,36688,N,N,N,N,N,N,40396,64613,N,35908,N,N,
+39278,38049,N,N,N,N,N,36707,N,N,N,N,N,N,N,41178,N,N,N,N,N,N,N,N,N,N,N,37459,
+65001,N,N,40373,N,N,N,N,N,N,N,39033,N,N,N,40285,N,N,N,N,36195,38505,40816,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64618,N,N,35527,N,N,N,N,35287,N,N,N,N,N,N,N,N,
+N,N,N,N,65101,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+40669,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65275,39100,64204,N,N,38320,N,N,N,37988,N,N,N,N,
+N,N,37743,N,N,N,N,N,N,38073,N,N,38380,N,N,N,N,37358,N,N,39107,N,38390,N,N,N,
+36861,39109,N,N,N,N,38758,65134,N,N,38877,36010,N,N,37586,N,N,38753,39115,N,N,
+N,N,38384,N,38749,N,37347,N,N,N,N,39116,N,N,37993,39117,N,N,N,N,N,39118,N,
+38396,N,N,38051,38498,N,N,N,65206,N,37987,N,N,N,N,N,N,N,39120,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39121,N,N,N,N,38005,64224,N,N,N,N,N,
+N,N,N,N,38002,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39126,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35568,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39129,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,39131,N,N,N,N,39133,N,N,N,N,N,N,N,N,39080,N,N,N,N,N,N,N,
+35437,N,N,N,N,N,N,N,N,N,N,N,35579,35502,64457,N,N,N,N,35933,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,39140,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,39142,N,N,N,N,N,N,N,N,N,N,N,39144,N,N,N,N,N,N,N,N,N,N,N,N,N,35405,N,N,N,
+37463,N,N,N,N,N,N,N,N,N,N,38367,N,N,41132,N,N,N,N,39147,N,N,N,N,39148,N,36035,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39156,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35512,
+N,N,N,40679,N,N,N,N,N,N,N,N,38076,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64721,N,N,N,N,
+N,N,40134,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40574,39166,
+65000,N,N,N,N,39232,N,N,N,N,38089,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,38099,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39238,N,N,N,N,37056,
+N,38097,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38259,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+37826,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39240,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39243,N,N,N,N,N,36437,N,N,N,N,39246,N,N,N,N,
+N,N,N,N,N,N,N,36606,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36441,N,N,N,N,N,N,N,
+N,N,38124,38127,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35936,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36724,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,39253,N,N,N,N,N,N,N,N,N,38212,N,N,N,N,N,N,N,N,N,N,N,
+36043,N,N,N,39254,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39257,N,N,N,N,N,N,N,39259,
+N,N,N,N,N,N,N,N,N,N,N,N,N,36036,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64069,N,N,
+N,37047,N,N,38723,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38349,N,N,N,N,N,N,38857,
+64848,36537,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38342,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+39271,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+35513,N,N,N,N,N,N,36348,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35446,N,
+N,N,N,N,40273,N,N,N,N,N,N,N,N,N,N,N,N,N,39283,N,N,N,N,40271,39290,38244,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,39329,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39333,N,N,N,
+N,N,N,N,39335,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,36589,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39341,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,37998,36720,N,64208,N,N,N,N,N,N,N,N,N,N,N,N,N,39347,N,N,N,N,N,N,
+41043,N,N,N,N,N,N,N,N,38492,N,N,N,N,64890,N,N,N,N,N,N,N,N,38910,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,37565,N,38909,N,N,N,N,36708,N,N,N,N,64759,38242,38861,40548,N,N,
+N,N,N,N,N,37452,36553,39356,N,N,N,N,40357,N,36692,N,N,N,N,N,N,N,N,N,N,36732,N,
+N,N,N,N,N,36514,N,N,N,N,N,N,N,N,N,36730,N,N,N,N,N,N,38830,N,N,N,N,38600,N,N,N,
+N,N,N,N,39363,N,37078,N,40126,N,N,N,36726,N,N,N,N,N,N,N,N,N,N,N,N,N,38000,
+64331,N,N,64970,N,N,N,N,N,N,36551,N,N,N,N,N,41209,N,N,N,N,N,N,N,36777,N,N,N,N,
+N,N,N,N,N,N,N,N,39367,N,N,N,N,N,N,N,N,N,N,N,N,N,37079,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,40671,39374,N,N,N,N,N,N,N,N,36794,N,N,N,N,N,36843,N,39375,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36802,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37577,N,N,N,N,N,38876,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38323,40057,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38322,
+36827,N,N,N,N,39907,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40570,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39918,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39390,N,N,N,N,N,N,N,N,N,N,N,N,
+N,64250,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40677,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,35410,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+39393,N,N,N,N,N,N,35431,35765,N,N,N,N,N,N,N,N,N,N,35500,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39401,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64458,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38878,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38353,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,39413,64586,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,39849,N,N,N,N,N,N,N,N,N,N,N,N,64476,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65110,N,
+N,N,N,N,40612,N,N,N,N,N,N,40265,38363,N,N,N,N,N,N,N,N,N,N,35269,N,N,N,N,N,N,N,
+N,N,N,N,N,39416,N,N,N,N,N,N,38500,N,N,N,N,36949,N,N,38612,N,N,N,N,N,N,N,38780,
+N,N,N,N,N,N,38477,N,38881,N,N,N,N,N,N,39496,N,N,N,N,N,N,N,N,N,N,N,39497,N,
+65149,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37034,N,N,N,N,39504,N,N,N,N,N,N,N,
+37703,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36568,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,37065,N,N,N,N,N,39509,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+37052,N,N,N,N,N,39512,N,35768,37077,N,N,N,N,N,N,N,N,N,N,N,N,N,38465,N,N,N,N,N,
+N,39514,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39516,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,38850,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35515,N,N,
+N,39850,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37109,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,39520,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+37189,35928,N,N,N,N,N,N,N,N,39523,N,N,N,N,N,N,35913,N,N,N,N,N,N,N,N,N,N,N,
+35766,N,N,N,N,N,N,N,N,N,N,64719,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38507,39534,N,
+37199,N,N,N,N,N,N,N,N,38726,N,N,41190,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37591,N,
+38517,N,N,37844,N,N,37307,38521,N,N,N,N,N,39536,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38520,37325,N,40010,41071,N,N,41066,N,N,N,N,N,
+N,37215,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,40869,N,N,35258,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,40653,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39545,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,40398,N,N,N,36050,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,40307,N,N,N,N,N,N,N,N,N,38585,N,38588,N,N,N,N,N,N,40145,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35255,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,40686,N,N,N,N,N,N,N,N,N,N,N,64323,40649,N,N,N,N,N,N,64467,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37294,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,40312,N,N,N,N,N,N,N,N,N,N,40315,40627,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,40626,N,40406,N,N,N,N,39247,N,N,35278,N,N,N,35776,N,40900,N,35796,
+N,N,35954,N,N,N,N,N,N,50879,35833,N,N,N,N,N,35142,N,50880,N,N,N,N,N,N,N,N,N,
+64229,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,51323,35782,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+40023,N,N,N,N,N,N,N,N,N,N,N,N,N,39675,N,N,N,N,N,N,N,35280,35279,N,N,N,50881,N,
+35281,N,35298,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37502,N,40378,N,N,N,N,N,50882,N,N,
+35951,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64504,N,N,N,35783,37483,N,N,35282,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,40911,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,40361,35283,N,N,39394,N,N,N,N,N,N,N,N,N,37479,37540,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,35955,N,N,35150,N,N,N,N,N,N,N,N,N,N,N,N,N,35151,37496,N,
+N,N,N,N,N,N,N,37302,N,N,N,N,35284,N,40914,N,N,N,N,N,N,N,N,37543,N,N,38306,N,N,
+N,N,N,37486,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,38634,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37487,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37539,N,N,N,N,N,35152,N,N,64087,N,N,N,N,
+39014,N,N,N,N,N,N,N,N,N,N,N,N,35286,N,N,N,N,N,N,N,N,N,N,39090,N,N,N,37547,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38622,37548,N,N,N,N,N,N,N,N,N,N,
+35952,N,40814,N,N,N,N,N,N,36594,N,N,N,40812,35288,N,N,N,N,64089,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37544,N,N,N,N,N,
+37219,N,N,N,N,N,N,35904,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+40819,N,37549,N,N,N,N,N,N,N,N,N,N,N,N,N,39913,N,N,N,N,N,37545,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,37546,N,N,N,N,N,N,35289,N,N,N,N,N,N,N,64854,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40872,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,35953,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37537,N,N,37091,N,N,N,N,N,N,N,N,41126,
+N,N,N,N,N,38059,N,64626,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38852,N,N,N,N,N,N,
+N,37550,64103,N,N,N,N,N,N,N,N,N,N,N,37538,64105,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,37480,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35153,N,N,N,N,N,N,N,N,N,64111,N,N,N,N,N,
+N,N,N,N,64113,N,N,N,N,N,N,N,N,N,35154,N,N,N,N,37978,N,N,N,N,N,N,N,N,50883,N,N,
+N,35293,N,51362,N,N,N,N,N,N,N,N,N,N,N,N,N,50884,N,N,N,40530,N,35155,N,N,N,N,N,
+N,N,N,N,N,40533,37562,N,N,50885,N,N,35931,N,N,N,64125,64168,39528,64071,N,N,
+64126,N,N,N,N,N,N,N,N,N,N,37563,N,N,N,64950,N,64162,N,N,N,N,N,64163,N,64164,
+39860,64166,N,N,N,N,N,N,N,35295,N,N,N,64987,N,N,64169,N,35156,N,N,N,N,N,N,N,N,
+64171,N,N,N,N,N,N,64634,N,N,N,N,N,N,N,35296,N,40783,51325,N,N,35297,N,N,N,N,N,
+64176,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40909,41191,N,N,N,N,N,64177,35238,
+N,N,N,N,N,N,N,N,N,N,N,N,40698,N,N,N,N,N,N,N,64178,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,64180,N,37572,N,N,N,N,N,N,40815,N,N,N,N,N,N,N,35760,N,
+N,N,N,N,N,N,N,N,N,40876,N,N,N,N,N,35299,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,39891,35300,N,N,N,64181,N,N,N,N,N,40917,N,N,N,N,N,N,35157,N,N,37573,N,N,N,
+35158,N,N,N,N,N,N,N,N,N,N,N,N,64179,N,N,N,64182,N,N,N,N,N,N,N,N,N,N,N,64183,N,
+N,N,N,N,N,40668,N,N,N,64452,40817,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64186,37575,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,50886,39500,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35944,N,N,35301,N,N,N,N,40829,N,N,
+N,N,N,41129,64196,N,N,N,N,50887,N,N,35159,N,N,N,N,N,N,64170,N,N,N,N,N,N,N,N,N,
+N,N,35160,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35811,N,35681,N,N,N,N,39665,N,N,40631,N,
+50888,N,N,N,64209,N,N,N,N,N,N,64210,N,N,N,N,N,N,N,N,40634,64212,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,64217,N,N,N,N,N,N,N,N,N,N,N,N,64219,N,40160,N,N,N,
+64503,N,64506,35303,41082,64220,N,N,64221,N,35305,N,N,N,N,N,50889,N,N,N,N,N,N,
+N,N,N,N,64226,35307,N,N,64227,N,N,N,N,N,N,37064,N,N,N,37594,35161,40181,N,N,N,
+N,N,35162,64231,40866,N,N,N,N,N,64234,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,64237,36781,N,N,N,N,N,N,64345,64239,38639,N,40428,N,N,N,40394,N,N,N,N,N,N,
+64877,N,35308,N,N,N,N,N,N,N,N,N,N,N,64324,N,N,40418,N,35957,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,40640,N,40534,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,40825,39623,N,N,64244,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,39073,N,N,N,N,N,N,N,N,N,64248,N,N,N,35312,40519,N,N,40439,N,N,N,N,40915,
+N,39626,N,N,N,N,35313,64249,N,N,N,N,N,N,N,N,N,N,N,N,N,36442,N,35314,N,N,N,N,
+35315,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37469,35665,37600,N,N,35316,N,N,N,N,N,
+N,N,N,N,40916,N,N,N,N,N,N,N,N,35449,N,N,N,N,N,N,N,N,N,N,N,35317,38823,N,N,N,N,
+N,N,N,N,N,N,37818,N,N,N,N,N,40536,N,N,N,N,35318,N,N,N,N,N,40535,N,N,N,N,35319,
+N,35393,N,N,35320,N,N,64241,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35322,N,N,N,
+N,N,N,N,64322,N,64191,N,N,N,N,N,N,N,N,N,64419,N,N,N,N,N,N,N,N,N,64247,N,N,N,N,
+N,N,N,N,N,N,N,40526,N,38108,N,N,N,N,N,38362,40440,40810,N,N,N,N,N,35511,N,N,N,
+N,N,N,N,N,N,N,N,N,64326,N,N,N,N,N,N,N,N,N,35398,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,64327,N,N,N,N,N,N,37192,N,N,N,37598,N,N,N,N,35667,40438,N,
+39898,N,N,N,N,40318,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35325,39396,N,N,
+N,N,N,40515,N,N,N,N,N,N,N,N,N,N,N,40425,N,36690,N,N,N,40437,40432,N,N,N,39399,
+N,N,N,N,N,35773,40431,N,N,N,N,N,N,N,N,N,N,N,40887,N,N,N,N,N,N,N,N,N,N,N,N,
+40400,N,40939,36265,40399,39137,N,40421,N,N,N,N,N,N,N,40392,N,N,N,N,N,N,N,N,N,
+64335,N,N,N,N,N,N,N,N,N,N,N,40427,N,N,N,N,N,N,N,N,N,64340,N,64341,39586,N,
+35542,N,39519,N,N,N,N,N,N,N,N,40693,N,N,N,36791,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,39634,40554,40680,N,N,N,N,N,N,N,N,N,N,N,N,35775,37314,40290,
+N,N,N,N,N,N,37472,N,N,N,N,N,N,N,N,N,N,N,37470,37313,N,35525,N,N,38819,N,N,N,N,
+N,N,N,N,N,N,35692,N,36222,N,N,N,N,N,N,N,40020,N,N,N,N,N,40381,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,40133,N,N,N,N,N,N,N,N,N,N,N,35163,N,N,N,N,N,N,N,N,
+N,N,64348,N,64347,N,64343,N,N,N,N,N,N,N,N,N,N,N,39111,64346,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,40174,N,N,N,N,N,N,N,37602,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,38055,N,N,N,N,N,N,N,N,N,N,36044,N,39892,N,N,64356,64374,N,N,64352,N,
+N,N,N,N,N,N,N,N,N,N,N,N,39397,N,N,39618,N,N,N,37371,N,N,N,41075,N,N,N,N,N,N,N,
+40818,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40908,N,N,N,39077,37608,N,N,N,N,N,N,
+N,N,39868,N,38643,N,N,37607,N,N,64615,N,N,N,N,N,N,N,N,N,N,N,35709,N,N,N,N,
+39924,N,N,N,N,N,40695,N,N,40641,N,N,N,N,N,N,N,N,N,39279,N,N,N,N,N,N,38641,N,N,
+36417,N,N,N,N,N,38218,N,N,N,38886,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38645,N,N,N,N,N,
+37606,40770,N,N,N,N,N,N,N,64359,N,N,N,N,N,N,N,N,39337,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,64230,64361,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38885,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,38525,N,N,N,64364,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39330,N,N,N,N,N,
+39611,N,N,N,39525,N,N,37966,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64366,N,N,
+39391,N,N,N,N,N,N,N,N,N,39139,N,N,37460,N,N,N,N,N,38523,35503,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35959,N,N,N,N,N,N,35759,40637,N,N,
+N,N,N,N,N,N,N,N,N,N,40678,N,N,64367,N,N,N,N,N,36577,N,N,N,N,39805,40062,N,N,N,
+N,63961,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37610,N,N,N,N,35960,N,N,N,N,N,N,N,N,N,N,
+N,64370,N,N,N,64369,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35164,N,39152,38642,N,N,N,N,
+N,N,N,64372,35777,N,35165,35294,N,35166,N,N,50890,N,N,N,N,N,N,65090,N,N,N,N,N,
+N,N,N,N,N,N,N,N,64379,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35167,N,35168,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,39885,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40403,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,38988,N,N,N,N,N,N,N,N,N,N,38738,N,N,N,N,N,38339,N,N,N,N,39862,N,
+N,N,N,N,N,N,N,N,N,N,N,39609,N,N,N,38835,N,N,N,N,N,N,40820,37617,N,N,N,N,N,N,N,
+N,N,N,N,38879,N,N,N,N,64422,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64427,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,39031,N,N,N,38996,38341,N,N,N,N,N,N,N,40277,64434,38270,N,
+N,N,N,N,N,N,N,38722,N,38118,N,N,N,N,37621,N,N,N,N,N,N,N,36037,N,N,N,N,N,N,
+37629,N,N,64418,N,N,40017,N,N,38121,39004,37616,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,37964,N,N,N,N,N,N,N,37227,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35704,N,N,N,N,38114,N,
+N,N,N,N,N,N,38991,N,64437,N,N,N,N,37489,N,N,37733,N,N,39003,N,N,38992,N,N,N,N,
+N,N,N,38844,N,N,N,N,37619,N,N,37696,38989,N,N,N,38258,N,65007,N,N,N,N,N,N,N,N,
+64961,N,N,N,N,64442,N,N,37611,N,N,N,N,N,N,64627,38839,N,N,N,N,N,N,N,N,N,64436,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37031,N,N,N,N,N,N,N,N,N,N,38721,
+37620,N,N,N,64444,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38263,N,N,N,N,N,N,N,N,N,N,N,
+40674,N,36728,N,N,N,N,N,N,N,63964,N,N,N,38514,40629,N,N,N,38475,N,N,N,36012,N,
+N,N,N,N,N,N,N,N,41210,N,N,N,N,N,N,N,N,N,N,N,38261,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,37082,N,N,37735,N,65188,N,N,N,37087,N,N,N,N,37716,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35169,N,35764,N,N,N,N,40384,N,N,N,N,N,N,36424,N,
+64453,N,N,N,N,N,64455,N,N,N,50891,N,64121,N,N,N,N,N,N,N,N,N,N,N,N,N,40551,N,N,
+N,N,N,36057,N,N,N,N,N,N,64466,35170,35171,N,N,N,N,N,N,N,N,N,N,64637,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40811,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+64460,N,65198,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64465,N,N,
+N,N,N,N,N,N,N,N,N,64373,64468,N,N,N,N,N,N,N,N,N,N,N,N,N,64470,64472,N,N,N,N,N,
+N,N,35677,N,37708,N,39650,N,N,35785,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64475,40905,N,N,N,N,N,N,N,N,40772,N,N,N,N,N,N,
+N,N,N,N,39149,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,64477,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36338,35172,N,65010,N,
+37709,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64487,N,N,N,N,N,N,
+41202,39016,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40792,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,36211,N,N,N,64478,N,N,N,N,N,64479,N,N,N,N,N,35912,64483,N,N,N,N,36264,N,
+N,64484,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40053,N,N,39032,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,36192,N,N,N,N,N,N,N,64485,N,36193,N,N,N,N,N,N,N,N,N,N,N,N,N,36194,
+41121,N,N,N,40000,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39085,N,N,N,40682,N,
+N,N,N,N,N,36052,N,N,N,N,N,N,N,N,N,40171,N,N,N,N,N,64480,N,N,40785,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36197,N,N,N,N,N,N,40177,N,N,N,N,N,N,N,N,N,N,
+64600,N,N,36198,N,N,N,N,N,N,N,38484,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+64488,N,N,N,50892,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40910,
+64508,N,39652,N,N,N,N,N,N,40821,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,64497,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36201,N,N,N,N,N,37711,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37710,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,64500,N,N,N,N,50894,N,N,N,64451,N,N,35173,N,N,N,N,N,N,N,N,
+N,N,N,35962,N,N,N,N,N,N,35963,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,36202,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37715,N,N,40443,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64509,N,N,N,
+36953,64576,N,64577,64579,37729,64582,37730,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,36203,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64588,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,38328,N,N,50896,35786,N,N,N,N,N,N,N,N,N,N,39034,N,N,N,N,
+50897,N,64593,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64596,N,N,N,N,N,N,N,N,64175,N,N,N,N,
+N,N,N,36204,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+64097,N,N,64599,N,N,N,N,N,N,N,N,N,39792,N,N,N,N,N,N,N,N,41041,N,N,N,N,N,N,N,
+35964,N,35787,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37742,N,N,N,64725,
+64681,N,N,N,N,N,N,N,N,N,N,N,N,N,64609,N,N,N,N,N,N,N,N,N,35174,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,64203,N,N,N,N,N,N,N,63962,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,37754,N,41184,N,N,N,N,N,N,37739,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64619,N,N,N,N,N,41180,N,N,37992,N,
+N,N,N,N,N,N,N,N,N,N,64621,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,36209,N,N,N,N,N,N,64868,N,N,N,N,39354,N,N,N,39632,39521,
+41189,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41051,38572,N,N,N,N,38720,N,N,N,N,
+N,N,N,N,N,N,N,N,40689,N,N,N,N,N,N,N,N,35917,N,N,N,N,N,N,N,N,N,N,N,N,N,40830,N,
+N,N,N,N,N,N,N,N,N,N,N,36210,N,N,N,N,64630,N,N,N,N,N,N,N,N,N,N,N,N,N,38569,N,N,
+N,N,N,N,N,N,41070,N,N,64682,N,N,N,64461,N,N,N,64628,N,N,N,N,N,N,N,N,N,N,41076,
+N,N,N,N,N,N,N,N,N,N,N,N,N,41073,N,N,N,64633,N,N,N,N,N,64636,N,N,N,N,N,N,N,N,N,
+N,N,N,N,40016,N,N,37753,37752,N,N,41181,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,36213,N,36214,N,N,N,N,N,N,37748,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+36215,64677,N,N,64674,N,N,N,N,N,N,37059,N,N,N,N,N,N,N,41081,36217,N,N,N,N,N,N,
+N,N,N,N,35836,N,41078,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35789,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40794,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,40948,N,N,40890,N,N,N,N,N,N,N,N,N,N,36218,N,N,N,N,N,N,N,N,N,
+N,N,N,40517,N,N,N,N,N,N,37808,N,41077,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,39750,N,64686,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64688,N,N,N,N,N,N,
+N,N,N,64081,N,N,N,N,N,36219,36220,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+40662,N,N,37804,N,N,N,40795,N,37801,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41084,N,N,N,N,N,N,N,64690,N,N,N,
+N,N,N,N,N,N,N,N,N,35521,N,N,N,N,N,40884,N,N,N,N,N,N,N,N,N,N,N,64684,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,40524,N,N,N,N,N,N,N,36805,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37805,N,N,N,N,N,N,N,
+N,N,N,N,N,40387,N,N,N,36258,N,N,N,40266,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+64694,N,N,36259,40523,N,40525,36260,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35581,N,N,N,N,N,64693,N,64707,37810,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36261,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37793,N,N,N,N,N,N,N,N,N,N,35526,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,35419,N,N,N,35149,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,65236,N,N,N,N,35448,N,37803,N,N,N,N,N,N,N,N,N,36263,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,40773,N,N,N,N,N,N,N,N,N,35414,N,N,N,64703,N,N,N,
+64704,N,36582,N,N,35492,35139,N,N,N,N,N,N,37875,N,N,N,N,N,N,N,N,N,N,N,N,64683,
+40610,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40391,N,N,N,50898,35790,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64709,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64715,N,
+N,N,N,N,N,N,N,N,N,N,37811,N,64714,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,64713,36268,N,64454,35175,N,35966,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64717,N,N,N,N,N,N,N,N,40179,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,64720,N,N,38331,N,N,N,N,N,N,N,N,N,N,N,64723,N,N,
+64724,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36270,64727,N,N,N,
+N,N,37851,N,N,N,N,65123,N,N,N,N,N,N,N,N,N,N,N,N,37845,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,64730,N,N,N,39793,N,N,64733,N,N,N,N,N,N,N,36271,N,N,N,64242,N,N,
+N,N,N,N,N,N,N,N,N,37848,N,N,N,64735,N,N,N,37843,N,N,N,N,N,N,N,64737,N,N,N,N,N,
+N,N,N,N,36470,N,N,N,N,N,N,N,64610,N,N,N,N,N,N,N,N,37841,N,N,N,36273,N,N,N,N,N,
+N,N,39001,N,N,N,N,N,N,N,N,N,64338,N,N,N,N,N,N,N,N,64339,N,N,N,N,N,64333,N,N,
+40127,N,N,N,N,N,N,N,N,39794,N,N,N,N,N,N,N,N,N,N,N,N,N,64336,37822,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40433,64747,N,N,N,N,N,
+N,N,N,N,41147,N,39806,N,N,N,N,N,N,N,36275,N,N,35922,N,N,N,N,39656,N,N,N,N,N,N,
+36572,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40185,N,N,N,N,N,N,N,N,N,N,N,N,N,64080,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39143,64755,N,N,N,N,
+64754,N,N,N,36042,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,37861,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39513,N,N,N,36277,N,N,N,N,N,N,
+N,64845,N,N,N,N,64862,N,N,N,N,N,N,N,N,N,N,N,N,N,36733,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,38215,64758,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,37456,N,N,N,N,35176,36278,64763,41085,39164,35177,N,N,N,N,
+N,N,N,N,65103,N,N,37462,N,N,N,N,N,N,N,N,N,N,64201,N,N,37864,N,N,N,64760,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40163,64937,N,N,N,N,N,N,64580,N,N,N,N,N,N,N,N,
+38464,N,N,36280,N,N,N,N,N,N,N,N,N,N,39754,36793,N,N,N,N,N,N,64766,N,N,N,N,N,N,
+N,35178,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36281,N,N,
+N,37246,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37876,N,N,N,N,N,N,N,N,N,N,N,N,N,64380,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,37863,N,N,38895,N,N,N,65098,N,N,N,N,N,64837,N,
+38565,N,N,N,N,65248,64840,64839,65266,65130,N,N,N,N,N,36285,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,39841,36002,39607,36604,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40865,N,N,N,
+N,N,N,N,N,N,64849,N,N,N,N,N,N,N,64173,N,N,N,N,36286,N,N,35236,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,39641,N,N,N,N,N,N,N,N,N,N,N,64846,N,N,36288,N,N,38896,N,N,N,N,N,N,
+N,N,N,N,37812,64836,N,N,N,N,N,N,N,N,N,N,N,N,40871,N,N,N,N,36290,N,N,N,N,39350,
+N,N,N,N,N,N,N,N,N,N,N,N,N,64850,N,N,N,N,N,N,36289,N,N,36422,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,41169,N,N,N,N,N,N,N,N,N,N,N,N,N,40906,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,37583,N,N,N,40180,36292,N,N,N,N,N,N,N,N,N,N,64833,N,N,N,N,N,N,N,39756,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,64855,64751,40158,N,N,N,N,N,N,N,64834,39020,N,N,N,N,
+N,N,N,N,N,N,N,N,N,38905,N,38232,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39006,65147,38093,
+N,N,N,N,N,37870,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36003,N,64858,N,N,N,N,N,N,37877,
+N,N,N,N,N,37871,36586,N,N,N,36699,N,N,N,N,N,N,N,N,N,N,N,35934,N,36294,N,N,N,N,
+N,N,N,N,N,N,N,36296,N,N,36295,N,N,N,N,N,37879,N,N,N,N,N,N,N,36297,N,N,N,N,N,N,
+N,64498,N,N,N,N,38512,N,N,N,N,N,N,N,N,N,36299,N,N,N,64860,N,N,N,N,N,N,N,N,N,
+36709,N,N,N,36301,N,N,N,N,N,40360,38137,N,N,36302,N,N,N,N,N,N,N,N,37866,N,N,N,
+N,N,N,N,N,N,64863,37872,40886,N,N,N,N,N,N,N,N,N,36303,N,N,N,38755,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36304,37873,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,64866,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+64869,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40923,N,N,N,N,
+37880,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35831,N,N,N,N,64870,N,N,N,
+N,N,35791,N,N,N,N,N,N,36305,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+36306,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64881,N,N,N,N,64879,
+N,N,N,N,N,N,N,N,36307,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40935,37053,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,40912,N,N,N,35792,N,64882,N,40110,35793,N,N,35547,N,
+N,N,N,N,N,N,N,N,N,N,64228,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38350,N,64886,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,64354,N,N,N,N,N,N,36308,N,N,N,64888,N,N,N,N,N,
+36579,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36982,N,N,
+39110,N,N,N,N,N,N,N,36309,N,N,N,N,38865,N,N,40630,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,64199,N,N,41026,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39027,N,N,
+N,N,N,N,N,N,N,N,40956,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36005,36311,N,N,
+37627,36312,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37967,N,
+36313,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,35179,N,N,N,N,N,N,N,N,38862,N,N,N,64243,64942,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,64431,37559,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36314,N,N,N,N,N,N,N,N,N,
+N,N,N,N,40026,N,N,N,N,N,N,64941,N,N,N,N,N,N,N,N,N,N,N,N,N,36316,37956,N,N,N,N,
+N,N,N,N,N,N,N,36317,N,N,N,N,N,N,N,41174,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,35905,38869,N,37962,N,N,N,N,N,37965,N,N,N,N,38859,N,N,N,N,
+N,36318,N,N,36319,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36320,65273,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64960,64761,N,N,N,N,N,
+N,N,N,64382,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37555,N,N,
+N,N,N,64943,N,N,N,N,N,N,N,N,N,36321,N,N,N,N,38355,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+35265,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64872,N,N,40119,N,N,
+36323,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64192,36325,
+64100,N,35143,N,N,N,N,36324,N,N,N,N,N,36327,36328,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,64967,64944,N,N,N,N,N,N,37957,38870,N,N,N,N,N,N,N,N,N,64710,38980,N,N,N,N,
+N,N,N,N,N,N,N,N,36329,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36330,N,N,N,N,N,N,N,N,
+65104,N,N,N,N,N,N,64972,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40359,N,N,N,N,N,
+64973,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64975,N,N,N,N,38354,N,N,N,
+N,N,N,N,36333,N,N,N,N,N,N,N,N,64698,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64965,
+N,64978,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40156,N,N,N,N,N,38351,N,N,
+36334,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64980,N,N,N,N,N,38636,38635,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37046,N,64963,39083,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38638,N,N,N,N,N,N,N,N,N,N,N,N,N,
+36340,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64992,N,
+35943,N,N,36342,N,N,N,36343,N,N,N,N,N,N,N,36858,N,N,N,N,N,N,N,N,N,N,38864,N,N,
+N,N,35794,N,N,36344,N,N,N,N,N,37081,N,35911,N,64240,N,N,N,N,64993,36345,N,
+64995,N,N,N,N,N,N,N,36346,N,64355,N,N,N,37030,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+39280,N,N,37355,N,38768,39023,64994,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39154,N,
+39676,35180,65021,N,N,39262,N,N,N,38333,N,N,N,N,N,N,N,64996,N,N,N,37350,N,N,N,
+N,64997,64998,N,N,N,N,N,N,N,N,64999,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37972,N,
+N,N,39352,N,N,N,N,N,N,N,N,38889,37702,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,39011,N,N,N,N,N,N,N,N,N,N,N,38332,N,65005,65015,N,N,N,N,N,N,39024,38646,
+36521,N,N,N,N,N,37969,N,N,36419,N,35674,N,N,N,N,65006,N,N,N,N,65008,N,N,N,N,
+65012,N,39925,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38782,N,N,N,N,
+N,39893,N,39619,N,38856,41179,37328,N,N,40932,N,36829,N,37353,N,N,N,N,N,N,N,N,
+N,39136,N,N,N,37578,N,38999,N,N,35921,N,N,N,N,65003,N,39753,N,N,N,N,N,N,N,N,N,
+40310,40623,N,N,N,N,N,N,N,N,N,40140,N,N,N,N,N,N,65002,N,N,36337,N,N,65019,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36435,N,N,N,N,N,N,N,N,N,N,N,64207,N,N,
+N,N,N,N,N,N,N,N,N,N,N,38649,N,N,N,N,N,N,N,N,N,39103,40521,36007,N,N,N,N,N,N,N,
+N,39882,N,N,N,N,65022,37596,N,N,N,N,N,65089,37324,37346,N,N,N,N,N,N,N,N,N,N,N,
+N,65092,N,N,N,N,N,N,35795,N,N,65095,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65096,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,37973,N,N,N,N,65099,N,65100,N,N,N,N,36287,N,N,N,N,
+N,N,N,N,N,40568,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65105,N,
+N,N,N,37974,N,N,N,N,N,N,N,40289,N,N,N,N,37975,N,N,N,N,N,N,N,N,N,N,39270,N,N,N,
+N,N,N,N,N,N,N,N,N,N,35797,N,N,N,N,41065,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,39092,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41033,41036,N,
+40549,N,N,N,N,N,N,N,N,N,N,N,39093,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,65112,N,39285,65107,41061,N,65113,N,N,N,N,N,N,N,N,N,39095,39096,N,N,N,N,N,N,
+N,39098,N,N,N,N,N,N,39099,N,N,N,N,N,N,40892,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41034,N,N,40647,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,36009,N,N,39086,N,N,N,N,N,N,N,N,37590,N,N,N,64225,N,37332,N,N,
+N,N,N,N,N,N,64222,N,N,65115,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35923,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,65118,N,N,N,N,64471,65114,38085,N,N,N,N,64202,N,N,N,N,N,N,N,N,N,
+N,N,39105,38748,N,65140,N,38771,N,N,N,N,N,N,N,N,64070,N,N,N,38756,N,N,N,65128,
+N,38478,N,38757,35930,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35233,38394,N,37588,65129,N,
+64325,N,39112,N,N,37103,N,39113,39114,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,37997,38071,65132,N,N,37995,N,N,N,N,N,N,37628,N,38379,N,65139,38766,
+65119,N,N,N,N,N,N,N,N,N,64957,N,N,37589,N,N,N,N,N,N,65209,N,N,65137,N,N,N,N,
+64443,N,N,38010,N,N,38395,65143,N,N,N,N,N,N,N,65145,N,65141,N,N,N,37981,N,N,N,
+N,N,N,N,65148,N,N,N,N,N,N,N,N,N,37700,36518,N,N,N,N,N,N,N,N,N,N,N,37587,N,
+38072,N,N,N,N,N,N,N,N,64625,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38750,N,N,N,N,36013,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,65191,N,N,N,37994,N,N,N,37859,N,N,39119,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,41177,N,N,N,N,N,N,N,N,41151,41037,41144,N,N,N,N,N,
+41166,41143,N,N,N,N,N,N,N,N,65193,N,N,N,N,N,N,N,N,N,N,35267,N,N,N,N,65195,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40436,35181,N,N,N,N,N,40059,N,N,N,N,N,N,
+39122,N,N,N,40873,N,N,N,65202,N,N,65201,N,N,N,38873,N,41156,N,38006,N,N,N,N,N,
+N,N,N,N,N,39288,N,N,N,N,N,N,65203,N,N,N,N,N,39123,65204,N,N,N,39124,N,N,N,N,N,
+N,N,40889,N,N,N,N,N,N,N,N,38001,N,N,N,N,N,N,N,N,N,39125,65208,N,N,N,50900,N,N,
+N,N,N,N,N,N,N,N,N,65210,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40540,N,N,65211,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,41028,N,N,N,N,39127,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,39128,65212,N,N,N,N,40958,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,65213,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40413,N,N,N,N,
+40673,N,N,N,N,N,N,N,N,N,N,N,N,39130,40415,65215,N,65214,N,N,40683,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,40537,41052,N,N,N,N,N,N,N,65216,N,N,N,38007,39132,N,
+65217,N,N,N,39134,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65219,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,65224,N,N,N,65225,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65226,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65227,N,N,N,N,N,N,N,N,N,40898,N,N,
+35947,39108,N,38064,38065,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65233,N,N,N,N,N,41153,N,
+65234,N,N,N,N,41165,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65235,N,N,39141,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65238,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,37348,N,N,N,N,36807,38062,N,35407,38066,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,36820,N,N,N,N,39146,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,65240,N,N,N,N,N,N,N,N,N,40416,N,N,N,N,39150,N,N,N,N,38340,N,64744,N,
+N,N,N,N,39151,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35950,N,N,N,N,N,N,N,N,64216,N,
+N,N,N,N,N,N,N,N,N,N,N,N,65244,N,N,N,N,N,N,N,N,N,41134,40268,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,39153,N,N,N,39155,N,38081,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,39157,N,N,64079,38626,N,N,N,N,37968,N,38562,N,N,39158,N,N,N,38629,
+N,N,N,N,N,39159,N,41030,38627,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39160,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40676,N,N,N,N,N,N,63958,N,N,N,N,N,N,38083,N,N,N,
+N,38082,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+65249,N,65257,N,N,N,N,38628,N,35244,38619,N,N,N,N,N,N,N,N,N,N,N,N,N,65250,N,N,
+N,N,N,N,N,N,N,N,38084,65251,N,N,N,65255,40955,N,N,N,N,N,N,N,N,N,N,N,35929,N,N,
+N,N,N,N,N,N,N,37833,N,38120,64342,N,N,N,37061,41128,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65253,N,N,N,39165,39163,
+65256,N,36543,N,N,N,N,35800,65271,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,36712,38086,N,N,N,N,N,N,N,N,40426,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64617,
+N,N,N,N,N,N,N,N,N,N,N,N,40154,N,65267,N,N,40050,N,N,65264,35273,N,N,N,N,N,N,N,
+N,N,39233,N,N,N,N,N,N,N,39234,N,N,N,65269,N,37335,N,N,N,N,N,38092,N,N,N,65272,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38824,N,65276,N,N,N,N,N,
+64959,N,N,N,N,N,N,N,65278,N,N,N,N,N,N,N,N,N,N,N,N,N,38609,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,38101,N,N,38096,39236,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,35939,N,N,41139,N,N,N,N,N,N,N,N,N,N,N,N,38095,N,N,N,
+40954,N,N,N,N,37349,N,40042,N,N,N,36425,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,36428,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36429,N,N,
+N,N,N,39539,N,N,N,N,N,N,N,N,N,N,N,N,N,39239,N,36017,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36432,N,N,N,N,N,N,N,N,N,N,36431,39241,N,N,N,N,N,
+36433,36434,N,N,N,N,39602,35237,N,N,N,N,N,39244,N,N,N,40952,N,N,N,N,N,N,36438,
+39245,37322,36439,N,N,N,N,38113,N,N,N,N,36935,N,36824,36440,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,38123,36444,38227,N,N,N,N,N,N,N,40933,N,N,N,N,N,N,N,N,N,N,
+40790,N,N,N,N,N,N,N,38223,N,36446,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39274,N,N,N,N,
+N,N,N,N,40036,40153,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36445,N,N,N,N,N,N,N,N,N,
+N,N,N,39248,N,N,N,N,N,N,N,N,N,39249,N,N,36450,N,N,N,N,N,N,N,N,N,N,N,39250,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36456,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+36449,40793,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35763,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,40797,36454,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,36018,N,N,N,N,N,N,N,N,N,N,N,N,N,36462,N,40804,39251,N,N,64184,N,N,
+N,N,N,39252,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36464,N,N,N,N,N,
+N,N,N,N,N,N,N,40801,N,36466,N,N,N,N,N,N,N,N,N,N,N,N,41067,N,N,N,N,40768,N,N,N,
+N,N,N,38125,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38126,N,N,40893,N,N,N,36475,N,N,N,N,
+N,N,39255,38135,N,40799,N,N,N,N,36467,N,N,40802,N,N,N,N,N,N,N,38134,N,N,N,N,N,
+N,N,N,N,N,N,N,N,39256,N,N,N,N,N,N,N,N,N,36469,63963,N,N,N,N,36978,N,38136,N,N,
+N,N,N,N,N,N,N,39258,N,N,N,N,N,N,N,N,N,41136,36019,N,N,N,36473,N,36472,N,N,N,
+38131,N,N,N,N,N,39087,N,N,N,N,N,N,41138,N,N,N,N,N,N,N,N,N,N,N,36474,N,N,N,N,N,
+N,39260,N,N,N,N,N,36476,N,36477,N,N,N,35801,N,N,35234,40663,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41142,N,N,N,N,N,N,
+N,N,N,N,N,N,40514,N,N,36516,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36519,N,35958,N,N,N,N,N,N,N,N,N,N,N,38210,
+N,N,N,N,N,N,N,N,N,N,N,N,39037,N,N,N,38741,N,N,36520,N,N,N,N,N,N,N,36522,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35235,N,39264,39266,N,N,38140,
+39265,N,N,N,N,N,N,N,38138,N,N,N,N,N,N,N,36526,36530,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,36528,N,N,N,N,N,N,N,39267,38826,38139,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,36539,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36060,N,N,N,N,N,N,N,N,
+N,39030,N,36513,N,N,N,N,36020,N,36535,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40358,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,40624,N,N,N,36536,N,N,N,N,N,N,N,N,N,N,N,N,40304,N,N,
+N,N,35182,N,N,N,N,N,N,N,35183,N,N,N,N,N,N,N,N,N,N,N,N,N,35184,N,N,N,N,N,N,N,N,
+N,N,N,N,35185,N,N,N,N,N,N,N,35186,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35187,35188,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,35189,N,N,N,N,N,N,N,N,36540,36541,N,N,N,N,N,36542,N,40401,N,N,
+N,N,38141,N,N,N,35799,35802,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,41186,N,N,N,N,N,N,40937,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+64936,N,N,N,35559,N,N,N,36546,N,N,N,N,N,N,N,N,N,N,N,36548,N,N,N,N,N,N,N,N,N,N,
+39268,N,N,N,N,N,39269,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,38222,N,N,N,N,N,N,N,N,N,39091,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,36555,35807,N,N,N,N,N,36558,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,36559,N,N,39272,N,N,N,N,39273,N,N,N,N,N,N,N,N,39275,36561,N,39276,N,N,N,N,N,
+N,N,N,N,36564,36565,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39277,N,N,N,
+N,N,N,41150,N,N,N,N,N,36566,41148,41141,N,N,41140,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,35808,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,35253,N,N,N,N,N,N,N,36573,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40541,39281,N,
+N,N,N,35246,40424,N,N,N,N,N,N,N,N,38245,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39282,N,N,35676,N,N,N,N,N,N,N,N,N,35249,41152,N,
+N,N,36575,N,38246,N,N,39284,N,39286,N,N,N,39287,N,39289,N,N,40410,N,N,36576,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,37724,N,N,N,N,N,N,N,40422,N,35679,N,N,38243,N,N,N,
+N,N,N,N,N,N,N,38247,N,N,N,N,N,40419,N,N,N,N,N,N,N,N,N,N,N,N,N,39292,N,N,39293,
+39294,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35675,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+39331,N,N,N,N,N,N,N,39332,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39334,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,39336,N,N,N,N,35518,N,N,N,N,N,N,N,N,N,N,N,40545,N,N,N,N,N,N,N,
+N,N,N,39338,N,N,N,N,N,N,41160,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,39339,N,N,N,N,N,N,N,N,N,N,65220,N,N,N,N,N,N,39106,36584,N,41146,N,N,N,N,
+N,N,N,N,N,N,N,64887,N,N,36590,N,N,N,40639,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+35266,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39340,N,N,N,N,N,N,N,N,N,N,N,N,
+N,38251,N,N,38252,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39343,N,N,39242,35190,36680,
+N,N,N,N,N,N,N,N,N,N,N,64494,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,39342,N,N,N,36603,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36048,N,N,
+N,N,35666,N,N,N,N,N,39344,N,N,N,N,35191,36673,N,N,N,N,N,N,N,39345,N,N,N,N,N,N,
+N,N,N,36681,N,N,N,N,N,N,N,N,N,N,N,64077,N,N,N,N,N,N,N,N,40420,36021,N,N,N,
+64489,39764,N,39346,40552,N,N,N,N,N,N,N,N,N,N,N,N,36682,N,36674,N,N,36689,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38982,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39348,N,N,N,N,N,N,N,N,N,N,36597,64853,N,N,
+40141,N,N,N,N,N,N,N,N,35192,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36691,N,
+N,N,N,N,N,N,N,N,N,N,36719,N,N,N,N,N,N,N,N,N,N,36451,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,36694,N,N,N,N,N,N,N,N,N,N,N,N,65142,N,N,N,N,40902,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,64172,N,N,N,N,N,36696,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+38984,39351,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38501,N,64108,N,40423,N,N,N,40546,N,N,
+N,38604,36455,N,N,64629,N,39038,N,N,N,N,N,N,N,64953,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,38908,N,N,N,N,N,N,N,N,N,39161,N,36710,N,N,N,N,N,N,N,N,38254,N,37445,N,N,
+36704,N,N,N,40657,N,N,N,N,N,65229,N,39353,N,N,N,N,N,N,N,N,N,N,N,N,36706,38732,
+N,N,N,N,N,N,N,N,N,N,N,N,37319,38239,N,N,N,N,N,N,N,39355,N,N,N,N,N,N,N,N,N,
+36461,36721,N,N,38091,N,N,N,N,N,N,N,N,N,N,N,N,38321,N,N,N,N,N,N,N,N,N,39666,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,38595,39357,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,41167,N,N,N,36717,N,N,39358,36596,N,36722,38372,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,39359,37442,N,64421,N,N,N,N,N,N,N,N,N,N,39360,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64948,36727,N,N,N,
+39361,N,N,N,N,N,N,N,N,N,64185,N,N,N,N,N,N,N,N,36672,64068,N,N,N,N,N,39362,N,N,
+N,N,N,N,N,36700,N,N,N,N,36029,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39364,39365,N,N,
+36731,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+36022,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,36771,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36046,N,N,N,N,N,N,N,N,
+N,39366,N,N,N,N,N,N,N,N,N,N,N,N,N,38605,N,N,N,N,N,N,N,N,N,N,N,N,N,38599,36773,
+N,N,N,N,N,N,N,N,N,N,64187,N,35937,38256,N,N,N,37736,N,36734,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,36778,N,N,N,N,N,N,41040,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+37075,N,N,38230,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,36792,N,N,N,N,N,39368,N,N,N,N,N,N,N,N,N,N,N,36783,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,39369,N,N,N,N,N,N,N,N,N,N,N,N,N,38265,N,N,N,N,N,N,N,N,
+N,N,N,N,40777,N,N,N,N,39370,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39371,
+40405,36784,N,N,N,N,N,N,N,N,N,N,N,64122,N,N,N,N,N,N,N,N,40543,N,N,N,N,39373,
+41161,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39643,N,N,N,41158,N,N,N,
+N,N,N,N,36788,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41175,N,N,N,N,N,N,N,N,N,N,N,N,
+41159,N,N,N,N,N,N,N,41027,N,N,N,36789,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+36786,N,N,N,N,N,N,41057,40542,N,N,N,N,N,N,N,N,N,N,36790,N,N,N,N,N,N,N,N,40936,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,40114,N,N,N,N,N,38268,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,40903,N,N,36795,36796,N,N,N,N,N,N,N,N,36844,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,36800,N,37738,N,N,N,35812,40060,N,N,N,N,N,N,N,N,38305,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,65260,N,N,38307,N,N,N,N,N,N,N,35909,36024,N,N,N,N,N,N,
+N,N,N,N,N,36801,N,N,N,41042,N,N,N,N,N,N,N,N,N,N,N,N,N,39376,N,N,N,N,N,36803,
+36804,N,N,N,N,N,N,N,N,N,38308,N,N,N,N,N,36806,N,40544,N,N,N,N,N,N,N,63960,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38309,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+40115,N,N,N,N,N,N,N,N,N,39377,65265,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,39378,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,40130,N,N,N,39379,N,N,N,N,N,38311,N,N,N,N,N,N,38313,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,38310,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40029,N,N,N,N,N,
+N,N,N,39138,N,N,N,N,N,N,36809,N,41154,36810,N,N,N,N,N,N,39380,N,N,41145,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,39768,N,36813,N,41172,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,36814,N,N,N,N,35813,N,N,N,N,35193,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,36816,38326,N,N,N,N,N,N,N,N,N,N,N,N,39382,N,38373,N,
+N,N,N,N,N,N,N,N,N,N,N,39383,N,N,N,N,38325,N,N,N,N,N,N,N,N,N,N,N,41162,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40957,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,41048,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36822,N,N,N,
+39384,N,N,N,N,N,N,N,36819,N,N,N,N,N,N,N,N,N,N,N,N,36837,N,N,N,N,N,36841,N,N,N,
+N,39385,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,37500,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40005,36830,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,36831,N,N,N,N,N,N,N,N,N,N,N,N,N,41035,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,36834,N,N,N,41164,N,N,N,N,N,N,N,N,36835,36836,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,39876,N,N,N,39932,N,N,N,N,N,N,38476,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,39670,N,36014,N,N,N,N,N,N,N,N,N,N,N,N,36839,N,N,N,N,N,N,N,N,N,N,36840,
+N,N,N,N,35815,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35194,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35195,
+39386,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+36845,N,N,N,38336,N,N,N,N,N,N,N,N,N,N,N,N,N,41163,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40520,N,N,N,N,N,N,39387,N,36851,N,N,N,N,
+36857,N,N,N,N,N,N,N,N,N,N,N,N,N,38337,N,41038,N,N,N,N,N,N,39388,N,N,N,N,41060,
+36855,N,N,N,N,N,N,N,35248,41032,N,N,N,N,36859,36854,N,N,N,N,N,40412,N,N,N,
+39389,35816,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37569,N,N,N,N,N,N,N,40918,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41170,N,N,36928,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35524,N,N,39392,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,40944,40947,N,N,N,N,N,N,N,N,N,N,N,N,40383,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,40950,N,38344,N,N,40538,N,N,N,N,N,N,N,N,N,N,N,N,39395,
+N,N,N,N,N,N,N,N,N,N,N,35402,N,N,N,N,N,N,N,N,40945,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,35495,N,N,N,N,N,N,N,N,39398,N,N,N,40951,N,40941,N,N,N,N,N,
+N,35420,N,40366,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,38345,N,N,N,N,N,36936,N,N,39400,N,N,N,N,N,36937,N,N,36026,N,N,
+37041,N,N,N,N,N,N,36938,N,N,N,N,N,N,N,N,N,N,39402,N,N,N,N,N,N,N,N,N,N,N,39889,
+N,N,N,N,N,N,N,39403,N,39404,N,N,N,N,N,N,N,N,39405,N,N,N,N,39406,36940,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36941,N,N,38347,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+38882,N,N,N,N,N,N,N,N,38348,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40824,N,N,N,N,N,
+N,N,N,N,35196,35197,N,N,N,N,N,N,35198,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39261,N,N,N,N,N,N,N,N,N,N,N,N,39770,N,N,N,N,
+36944,N,35919,N,N,N,N,N,N,N,N,N,N,N,36948,N,50902,39592,39407,65259,40355,
+40353,39235,39237,N,40317,N,N,39408,N,N,N,N,N,N,N,N,39409,N,39410,N,N,36028,
+40288,N,N,N,N,N,N,N,N,N,41123,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,36955,40667,N,N,N,N,N,N,N,N,N,40313,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39411,N,N,N,36962,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,40789,N,N,N,N,N,N,N,N,N,39929,N,N,N,N,N,N,N,N,N,N,36965,N,N,
+38624,N,N,N,N,N,N,N,39102,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36968,N,N,N,
+N,N,36972,N,N,N,N,N,N,N,N,N,N,N,N,38360,N,N,N,N,N,N,N,N,36970,40882,N,N,N,N,N,
+N,N,40878,N,N,40880,N,35245,N,N,N,N,N,N,N,N,36974,N,N,N,N,N,N,N,N,40561,N,N,N,
+N,N,40522,N,N,N,N,N,40924,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35243,N,40888,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36976,N,N,N,N,N,N,N,N,N,N,N,N,
+35683,N,N,N,N,38364,N,N,N,N,N,N,N,N,36977,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+64606,N,N,N,N,N,N,N,N,35145,N,N,N,N,N,38491,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+35920,N,N,N,38054,N,N,N,36821,40563,N,N,N,N,N,36981,N,N,N,N,39415,N,N,N,N,N,N,
+N,N,N,N,N,N,N,36031,N,N,N,N,N,N,39417,N,38499,38329,N,N,N,N,N,N,N,N,N,38100,N,
+N,N,N,N,N,64762,N,N,N,N,36983,N,N,37035,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40269,
+N,N,39418,N,N,N,N,37603,N,38843,N,N,36984,N,N,N,N,N,N,N,N,39419,N,N,38880,N,N,
+N,N,N,N,N,N,38620,N,N,N,N,N,N,N,N,N,40104,N,N,38770,N,N,N,N,37952,N,N,N,N,N,
+37618,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39421,N,N,
+39420,N,N,N,N,N,N,N,63959,38474,N,N,N,38616,39422,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,36939,N,N,N,N,N,N,64065,N,N,N,N,N,N,N,39488,N,38747,N,N,N,N,N,
+39489,37341,N,N,N,N,N,37884,39490,39491,N,38489,N,N,N,N,N,N,39492,36945,N,N,N,
+38079,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+37026,N,N,N,40107,38774,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64597,65093,38056,39493,
+64075,40417,N,N,38617,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38772,N,N,
+65013,N,N,N,37605,N,38469,37338,N,37027,N,N,41055,N,N,N,N,37039,38847,N,N,N,
+37196,N,N,N,N,38522,N,N,N,37342,N,N,39494,65200,38777,37996,N,N,N,N,N,N,N,N,
+39000,N,N,N,N,N,N,N,N,N,N,N,37478,N,N,N,37883,N,N,N,N,N,N,N,N,N,N,N,N,39495,N,
+N,N,N,N,N,N,N,N,N,38729,N,N,38728,N,37706,N,40162,N,N,N,N,N,N,37476,N,N,N,N,
+37343,N,N,N,N,N,N,N,64377,N,N,N,N,N,N,N,38615,N,N,N,N,37699,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,64971,65146,N,37339,35946,38831,N,N,38365,N,N,N,37704,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,39499,N,N,N,64581,N,39501,N,N,N,N,N,N,37308,37090,37044,38369,
+N,N,N,N,N,39502,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39503,N,N,N,65088,65091,N,N,N,
+N,N,N,N,N,N,38621,N,N,N,N,N,N,39505,N,N,N,38567,N,N,37040,N,N,N,N,N,N,N,N,N,
+40014,N,37955,N,N,N,N,36538,N,N,N,N,N,N,N,N,N,N,N,N,39506,N,64705,N,N,N,N,N,N,
+N,N,N,35817,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40111,N,N,35837,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39612,N,39608,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39598,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,39591,39507,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,40308,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35818,N,N,N,N,N,N,35819,N,N,N,N,N,37042,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,38377,38376,N,38374,N,N,N,N,N,N,37045,N,39508,N,N,N,
+37043,38375,N,N,35664,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35820,N,N,N,
+N,N,N,N,N,N,N,N,39510,35835,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39511,N,
+N,N,N,41130,N,N,N,N,N,N,N,N,40870,N,N,N,39372,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+40025,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39349,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,37054,N,N,N,N,N,40879,N,N,N,N,N,N,N,N,N,N,N,N,N,38386,N,N,N,N,N,N,37055,N,
+N,N,N,N,N,N,N,N,N,N,N,37057,N,65252,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37060,N,N,
+N,N,N,N,37063,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37604,40786,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,37083,N,N,N,N,N,41062,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+37074,N,N,N,N,37076,N,N,N,N,N,N,N,N,N,39515,38397,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,35780,N,N,N,35942,N,37086,N,N,N,N,N,40164,N,37089,N,N,N,N,N,N,N,N,N,N,N,N,N,
+40518,N,N,N,38481,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64344,N,37094,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38480,N,N,N,37095,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,37096,39517,N,40826,N,N,N,39772,N,40828,N,N,64594,37097,N,37098,N,39518,N,
+N,N,N,N,40822,N,N,N,N,N,N,N,N,N,37099,N,N,N,N,N,N,N,N,N,N,N,N,N,37100,N,N,N,N,
+N,35822,N,N,N,N,N,N,N,37102,N,N,N,37318,N,N,37106,64700,35444,N,N,N,N,N,N,N,N,
+N,38487,N,N,N,40175,N,N,N,N,N,N,N,N,N,N,40927,N,N,N,N,37111,37110,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,39774,N,N,N,37112,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,37113,N,36041,N,N,N,64106,N,N,N,N,N,N,N,N,35823,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40928,N,N,37186,N,39522,N,N,N,N,N,N,N,N,N,
+38249,N,N,N,37188,37187,N,37185,N,N,N,35824,N,N,N,N,N,N,N,N,N,N,N,N,N,38496,N,
+35825,N,39414,37193,N,N,N,N,37194,N,N,N,N,N,37195,N,N,N,N,39524,N,N,N,35519,
+39526,N,N,N,N,N,N,N,N,N,N,39527,N,N,39529,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,39530,38482,37197,N,38502,N,N,N,N,40827,N,39531,N,N,N,N,N,N,N,
+41068,N,N,38503,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39532,N,N,N,N,39533,35826,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,38506,N,N,N,N,N,N,N,N,64746,N,N,N,N,N,38508,N,N,N,N,
+N,N,N,N,N,N,N,N,N,37316,N,N,N,38519,N,N,N,N,N,N,N,39412,39535,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,40875,N,N,N,N,N,36030,36545,N,N,N,N,38229,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,37202,37203,N,N,N,37205,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38237,N,
+38513,N,N,N,N,40045,N,N,N,N,N,N,N,N,38515,N,N,N,N,N,N,N,N,N,N,N,37204,39537,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37206,N,N,N,38509,N,N,N,N,
+N,N,38231,N,N,N,N,N,N,N,N,35270,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,35271,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,35434,N,N,N,35671,N,N,N,40929,N,N,39775,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41053,N,N,N,N,N,N,N,N,37211,N,37212,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,37214,N,N,N,N,N,N,N,N,N,N,40796,40791,N,N,N,N,N,N,40805,
+N,N,N,N,N,39538,N,N,N,N,37216,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40798,
+N,N,37217,N,N,N,N,N,N,37220,N,N,N,N,40769,N,N,N,N,N,N,37225,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,37224,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39540,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38578,N,39541,N,64933,N,N,N,N,N,N,N,40681,
+N,35770,37229,41056,N,N,N,N,N,N,N,40926,N,N,N,N,N,40899,N,38581,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,41063,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,38579,N,N,N,N,N,N,N,N,N,N,N,N,N,39542,N,N,N,N,N,N,N,N,N,N,N,38357,N,N,N,
+40650,N,N,N,39543,N,N,39544,N,N,N,N,N,N,N,N,N,N,37232,37231,N,N,N,N,N,N,N,
+40867,N,37233,N,N,N,38577,N,N,N,N,40803,N,N,N,N,N,40807,N,N,N,35769,39546,N,N,
+N,N,N,35670,N,N,N,N,N,N,N,N,39642,N,N,N,N,N,38576,N,N,N,N,39550,N,N,N,N,N,N,N,
+N,N,N,40414,N,N,N,N,N,N,N,N,N,38573,N,N,N,38574,N,N,N,N,N,N,N,N,N,40609,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40528,N,N,N,N,N,N,N,N,38575,35828,40868,N,N,
+N,N,N,N,N,N,N,38589,N,N,N,N,N,N,N,N,N,38644,N,N,N,N,N,N,N,N,N,N,38584,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,64161,N,N,N,N,37287,N,N,N,N,N,N,N,N,N,N,41054,N,N,
+N,N,39549,N,N,N,N,35144,N,40625,N,N,N,N,N,N,N,N,N,N,N,N,N,40411,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,38335,35443,N,N,N,N,N,N,N,N,N,N,N,N,N,40702,N,37242,N,N,N,N,
+37243,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39587,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+38594,N,N,N,N,N,40823,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39588,N,N,39589,N,N,N,
+37281,N,N,N,N,35256,N,N,N,N,N,N,N,N,N,N,37235,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39590,35261,N,35257,N,37245,N,N,
+N,N,N,N,N,N,N,38587,N,N,N,40946,N,N,35829,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39593,N,N,
+N,N,N,40788,N,N,40931,40685,N,N,N,N,N,N,N,N,N,N,37290,N,N,N,N,37291,41072,N,
+40813,N,N,N,N,N,37292,N,N,N,37293,N,N,N,41213,N,40930,N,37295,40513,39594,N,N,
+37296,N,39595,N,N,N,N,N,N,N,N,N,N,N,39596,N,39498,N,37298,N,N,35830,N,39597,
+35254,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39599,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,39600,N,N,N,N,N,N,39601,N,N,N,N,N,39585,37305,N,N,N,N,N,37306,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,37310,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41025,35767,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,37312,N,N,N,N,N,N,N,N,N,N,39603,37315,N,N,N,N,N,N,
+N,N,N,N,41212,N,N,40942,N,N,N,N,N,N,40809,N,N,N,N,N,N,N,37320,N,N,N,N,N,N,
+37321,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36326,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,37323,N,N,N,N,N,N,N,N,N,N,35272,N,N,N,N,N,36266,N,N,N,N,N,40925,34880,
+34881,34882,34883,34884,N,34886,N,N,34889,34890,N,N,34893,N,34895,34896,34897,
+34898,N,34900,34901,N,N,N,N,N,N,N,N,N,N,N,N,34914,N,34916,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,34979,N,34981,N,N,N,34985,34986,35907,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+35949,N,N,N,N,N,N,35956,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,36023,N,36025,N,36027,N,N,N,N,36032,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,36055,36056,N,36058,51321,N,N,N,N,51326,51361,N,51363,35832,51408,
+N,N,N,N,51407,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,50916,N,50917,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,51405,N,
+51406,N,N,N,N,N,N,N,N,63998,
+};
+
+static const struct unim_index big5hkscs_bmp_encmap[256] = {
+{__big5hkscs_bmp_encmap+0,168,252},{__big5hkscs_bmp_encmap+85,0,220},{
+__big5hkscs_bmp_encmap+306,80,198},{0,0,0},{__big5hkscs_bmp_encmap+425,1,81},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__big5hkscs_bmp_encmap+506,190,
+193},{0,0,0},{0,0,0},{__big5hkscs_bmp_encmap+510,22,231},{0,0,0},{0,0,0},{
+__big5hkscs_bmp_encmap+720,96,125},{__big5hkscs_bmp_encmap+750,80,112},{0,0,0
+},{__big5hkscs_bmp_encmap+783,61,61},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{__big5hkscs_bmp_encmap+784,128,227},{__big5hkscs_bmp_encmap+884,51,51
+},{__big5hkscs_bmp_encmap+885,5,254},{0,0,0},{__big5hkscs_bmp_encmap+1135,49,
+49},{0,0,0},{__big5hkscs_bmp_encmap+1136,53,251},{__big5hkscs_bmp_encmap+1335,
+6,254},{__big5hkscs_bmp_encmap+1584,9,245},{__big5hkscs_bmp_encmap+1821,1,251
+},{__big5hkscs_bmp_encmap+2072,15,250},{__big5hkscs_bmp_encmap+2308,8,254},{
+__big5hkscs_bmp_encmap+2555,1,251},{__big5hkscs_bmp_encmap+2806,14,244},{
+__big5hkscs_bmp_encmap+3037,13,239},{__big5hkscs_bmp_encmap+3264,19,253},{
+__big5hkscs_bmp_encmap+3499,6,255},{__big5hkscs_bmp_encmap+3749,0,250},{
+__big5hkscs_bmp_encmap+4000,4,250},{__big5hkscs_bmp_encmap+4247,3,249},{
+__big5hkscs_bmp_encmap+4494,17,252},{__big5hkscs_bmp_encmap+4730,43,242},{
+__big5hkscs_bmp_encmap+4930,1,244},{__big5hkscs_bmp_encmap+5174,3,233},{
+__big5hkscs_bmp_encmap+5405,6,245},{__big5hkscs_bmp_encmap+5645,19,244},{
+__big5hkscs_bmp_encmap+5871,0,250},{__big5hkscs_bmp_encmap+6122,6,231},{
+__big5hkscs_bmp_encmap+6348,15,255},{__big5hkscs_bmp_encmap+6589,16,192},{
+__big5hkscs_bmp_encmap+6766,4,237},{__big5hkscs_bmp_encmap+7000,9,156},{
+__big5hkscs_bmp_encmap+7148,4,248},{__big5hkscs_bmp_encmap+7393,3,253},{
+__big5hkscs_bmp_encmap+7644,3,252},{__big5hkscs_bmp_encmap+7894,1,254},{
+__big5hkscs_bmp_encmap+8148,2,249},{__big5hkscs_bmp_encmap+8396,1,254},{
+__big5hkscs_bmp_encmap+8650,19,239},{__big5hkscs_bmp_encmap+8871,2,251},{
+__big5hkscs_bmp_encmap+9121,5,253},{__big5hkscs_bmp_encmap+9370,0,254},{
+__big5hkscs_bmp_encmap+9625,3,251},{__big5hkscs_bmp_encmap+9874,2,249},{
+__big5hkscs_bmp_encmap+10122,2,254},{__big5hkscs_bmp_encmap+10375,13,255},{
+__big5hkscs_bmp_encmap+10618,5,245},{__big5hkscs_bmp_encmap+10859,16,245},{
+__big5hkscs_bmp_encmap+11089,9,252},{__big5hkscs_bmp_encmap+11333,12,223},{
+__big5hkscs_bmp_encmap+11545,35,253},{__big5hkscs_bmp_encmap+11764,7,226},{
+__big5hkscs_bmp_encmap+11984,44,229},{__big5hkscs_bmp_encmap+12170,24,254},{
+__big5hkscs_bmp_encmap+12401,7,234},{__big5hkscs_bmp_encmap+12629,10,255},{
+__big5hkscs_bmp_encmap+12875,24,241},{__big5hkscs_bmp_encmap+13093,2,254},{
+__big5hkscs_bmp_encmap+13346,0,202},{__big5hkscs_bmp_encmap+13549,0,250},{
+__big5hkscs_bmp_encmap+13800,3,246},{__big5hkscs_bmp_encmap+14044,5,250},{
+__big5hkscs_bmp_encmap+14290,28,255},{__big5hkscs_bmp_encmap+14518,2,254},{
+__big5hkscs_bmp_encmap+14771,2,250},{__big5hkscs_bmp_encmap+15020,4,248},{
+__big5hkscs_bmp_encmap+15265,3,254},{__big5hkscs_bmp_encmap+15517,5,246},{
+__big5hkscs_bmp_encmap+15759,0,226},{__big5hkscs_bmp_encmap+15986,2,251},{
+__big5hkscs_bmp_encmap+16236,2,248},{__big5hkscs_bmp_encmap+16483,5,220},{
+__big5hkscs_bmp_encmap+16699,2,217},{__big5hkscs_bmp_encmap+16915,12,254},{
+__big5hkscs_bmp_encmap+17158,8,245},{__big5hkscs_bmp_encmap+17396,6,244},{
+__big5hkscs_bmp_encmap+17635,6,254},{__big5hkscs_bmp_encmap+17884,11,252},{
+__big5hkscs_bmp_encmap+18126,18,252},{__big5hkscs_bmp_encmap+18361,37,254},{
+__big5hkscs_bmp_encmap+18579,7,223},{__big5hkscs_bmp_encmap+18796,6,250},{
+__big5hkscs_bmp_encmap+19041,2,246},{__big5hkscs_bmp_encmap+19286,3,246},{
+__big5hkscs_bmp_encmap+19530,24,255},{__big5hkscs_bmp_encmap+19762,11,237},{
+__big5hkscs_bmp_encmap+19989,5,248},{__big5hkscs_bmp_encmap+20233,3,252},{
+__big5hkscs_bmp_encmap+20483,2,239},{__big5hkscs_bmp_encmap+20721,112,245},{
+__big5hkscs_bmp_encmap+20855,4,255},{__big5hkscs_bmp_encmap+21107,0,231},{
+__big5hkscs_bmp_encmap+21339,28,234},{__big5hkscs_bmp_encmap+21546,12,226},{
+__big5hkscs_bmp_encmap+21761,81,247},{__big5hkscs_bmp_encmap+21928,3,212},{
+__big5hkscs_bmp_encmap+22138,1,242},{__big5hkscs_bmp_encmap+22380,25,249},{
+__big5hkscs_bmp_encmap+22605,8,196},{__big5hkscs_bmp_encmap+22794,81,254},{
+__big5hkscs_bmp_encmap+22968,8,253},{__big5hkscs_bmp_encmap+23214,3,244},{
+__big5hkscs_bmp_encmap+23456,1,246},{__big5hkscs_bmp_encmap+23702,45,244},{
+__big5hkscs_bmp_encmap+23902,29,244},{__big5hkscs_bmp_encmap+24118,3,245},{
+__big5hkscs_bmp_encmap+24361,20,245},{__big5hkscs_bmp_encmap+24587,14,245},{
+__big5hkscs_bmp_encmap+24819,12,255},{__big5hkscs_bmp_encmap+25063,2,255},{
+__big5hkscs_bmp_encmap+25317,2,124},{__big5hkscs_bmp_encmap+25440,2,252},{
+__big5hkscs_bmp_encmap+25691,10,254},{__big5hkscs_bmp_encmap+25936,2,165},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__big5hkscs_bmp_encmap+26100,3,75},
+{0,0,0},{__big5hkscs_bmp_encmap+26173,122,239},{0,0,0},{__big5hkscs_bmp_encmap
++26291,229,237},{0,0,0},{__big5hkscs_bmp_encmap+26300,7,7},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{__big5hkscs_bmp_encmap+26301,2,237},
+};
+
+static const DBCHAR __big5hkscs_nonbmp_encmap[28325] = {
+40049,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37749,N,N,N,N,N,
+N,N,37750,N,N,N,N,N,N,N,38216,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,36550,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35781,35834,
+N,N,51324,N,N,N,N,N,N,N,N,N,39604,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,34894,34891,
+51322,34888,N,N,N,34887,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,41206,34885,N,34899,N,N,N,N,N,N,N,N,N,64685,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,35501,N,37490,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+64583,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38111,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,40913,64459,N,N,N,N,N,N,N,37501,N,N,N,N,N,N,N,
+39076,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38119,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37067,37499,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38104,N,N,N,N,64607,N,64084,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39605,N,N,N,N,N,N,N,38618,37497,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64116,
+37493,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36347,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35401,N,N,N,37599,39804,64099,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,64096,37485,64098,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,39606,N,N,N,N,N,N,38763,N,N,N,N,N,N,N,N,N,N,N,N,N,
+64874,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64852,N,37491,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38872,N,N,N,N,N,
+N,40891,37698,37494,N,N,N,N,N,N,N,N,N,N,64101,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,37484,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,64110,N,N,N,N,N,N,40672,N,N,37568,37567,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,37566,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39610,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35507,N,38773,64064,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64118,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,64464,N,N,N,N,N,N,N,N,N,N,N,N,N,64123,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,65133,N,N,N,N,N,N,39859,N,N,N,N,N,35276,N,N,N,N,39614,N,N,N,N,N,N,
+N,N,N,64066,37564,N,N,N,N,N,N,N,N,N,N,37980,39861,N,N,N,39615,N,N,N,39079,
+38820,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37117,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64635,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39616,37571,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35498,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39888,38224,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37574,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+39078,38214,N,N,N,N,N,N,N,N,N,N,N,N,64867,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64194,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40643,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35250,40038,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36947,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+38849,N,N,N,N,N,N,N,N,N,N,N,N,N,39620,N,N,N,N,N,N,N,N,N,N,39621,36591,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,64233,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37474,
+35575,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39622,N,N,N,N,N,N,37601,N,N,N,
+N,39625,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64198,N,N,N,N,N,N,N,N,
+38821,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39627,N,N,N,64114,35422,N,38112,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,37580,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35557,N,
+N,N,N,N,65116,39628,N,N,N,N,N,40441,35395,35494,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+39629,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39630,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,64238,39884,N,N,N,39631,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39633,N,N,N,N,N,N,N,
+N,40442,N,N,N,N,N,40316,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39635,
+N,N,38822,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39263,N,N,N,64502,40901,
+35417,35691,N,N,N,N,N,N,39636,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39637,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,38818,35396,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40778,N,
+N,N,N,N,N,N,N,37025,64932,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35428,35570,
+35576,40408,N,N,38102,64254,64423,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,39638,N,40781,N,N,64246,N,N,N,N,N,N,N,35415,N,35651,35652,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35510,N,N,N,N,N,35520,N,N,N,N,N,N,
+N,N,N,N,40532,N,N,N,N,N,N,N,N,N,N,39639,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,39640,39644,N,N,N,N,35530,40616,N,N,37475,39645,35685,35695,35710,N,N,N,N,
+36675,N,N,N,N,N,N,37584,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35572,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40382,N,N,N,N,N,39649,N,64734,40445,35686,35696,
+35701,35556,35748,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35565,N,N,N,N,N,N,N,N,N,
+35421,N,35656,N,N,N,N,40429,N,N,N,N,40512,N,N,N,N,N,N,N,35567,35574,40566,N,N,
+N,N,N,N,N,N,N,40675,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,39646,36350,N,N,N,N,64252,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,40113,40567,35684,35687,38731,N,N,N,N,N,N,N,N,38483,N,N,N,N,N,N,39648,
+35658,N,35569,35543,N,N,N,N,N,N,N,N,N,41131,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+35509,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35423,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35566,N,N,39647,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35582,N,N,N,N,N,N,35416,
+35747,35751,N,N,N,N,N,39651,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,37473,N,N,N,N,N,N,N,N,N,N,40407,40573,40615,40619,36930,N,N,
+N,N,N,N,N,N,35705,35706,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39654,N,N,N,N,N,N,N,N,N,N,N,N,39653,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35454,N,N,N,N,N,40516,39655,35452,35697,N,
+N,39657,N,N,N,N,N,N,N,N,N,N,N,N,39658,N,N,N,N,N,N,N,N,N,N,N,N,N,39659,N,N,N,N,
+N,N,35517,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64334,N,N,N,N,N,N,N,N,N,
+N,39661,35577,40547,N,N,N,N,N,35657,35534,35694,N,N,N,N,N,35560,N,N,N,39662,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37582,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35418,35707,
+35708,39663,N,N,N,N,N,N,N,N,N,N,N,39664,N,35578,N,N,N,N,N,N,N,35137,N,N,35698,
+N,N,N,N,N,N,35571,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35752,N,N,N,N,N,N,40622,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40562,64371,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64351,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37050,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37374,40694,
+N,N,N,N,N,N,38893,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39667,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,41198,38524,37701,39022,64086,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39669,N,N,
+N,64587,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39668,65246,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,64695,N,N,N,N,N,N,N,N,N,38897,N,N,N,38855,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40139,
+37440,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,40168,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37373,38734,N,N,64360,N,N,N,N,N,N,N,
+N,N,N,N,N,N,38764,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36034,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38888,N,64362,35700,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,36583,N,N,N,N,N,N,N,N,N,N,N,N,64968,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,37441,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38561,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,36595,39671,N,N,N,N,N,N,N,N,N,N,36774,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,64214,40135,N,N,N,N,N,N,N,N,64215,N,N,N,N,N,39672,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64417,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36549,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+64420,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,64450,N,39617,N,N,N,N,N,37370,65243,38827,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+37191,N,64433,N,N,N,N,N,N,N,N,N,36842,N,N,N,N,N,N,38098,65121,64206,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,37613,37363,37830,N,37722,64251,N,N,37615,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64200,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+38983,37734,38997,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38630,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40771,40874,38106,37614,64687,64507,N,
+36601,37366,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37732,N,N,N,N,38133,40118,64429,
+38990,36676,38653,N,N,N,N,N,N,N,N,N,N,N,N,N,39673,N,N,N,39674,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,38761,38356,38987,64426,N,N,39036,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,37354,N,N,N,N,N,40367,40389,N,37361,36529,38825,64428,64696,40121,N,N,N,N,
+N,N,N,64432,64722,37835,N,N,39677,N,N,N,N,N,N,N,N,N,N,N,37364,35756,41045,N,N,
+N,N,38260,N,N,N,N,38334,N,N,N,N,N,N,N,N,N,N,N,N,38829,N,N,N,N,N,N,N,N,N,N,N,
+36585,N,N,37624,38846,37228,38058,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64611,N,
+N,N,40390,N,N,N,N,N,N,N,38837,37560,37359,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,65190,38752,37720,38262,36780,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,37356,38836,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37367,N,N,N,N,
+38730,64329,38264,37820,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,37334,37717,37718,38993,N,N,N,N,N,N,N,N,N,N,36856,64448,37874,N,N,
+37072,N,N,N,N,N,N,40004,N,N,N,N,N,37461,N,N,N,N,37731,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,37285,N,N,N,N,N,N,N,N,41197,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,64875,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39678,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,37713,N,N,N,35927,N,N,64120,N,N,N,N,65192,N,N,N,N,N,N,N,N,N,N,N,N,N,37712,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64076,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37623,39744,N,N,N,N,N,N,64462,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,39745,N,N,N,N,N,65197,64469,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35778,39548,39746,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39747,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,40569,N,N,64473,N,N,N,N,N,N,39748,41127,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39923,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35961,N,N,N,37726,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,35275,N,N,N,N,N,N,40787,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,37847,N,N,N,N,N,N,N,N,N,N,N,N,N,64481,65232,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,64482,N,N,N,N,N,64739,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36980,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,64486,N,N,N,39863,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,39749,N,N,N,N,N,N,N,N,N,N,N,N,39751,40784,N,N,N,N,N,39752,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,64603,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39081,N,N,40189,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,34892,39755,N,N,N,64492,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,35945,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+39848,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,35541,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64115,64857,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+37282,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64493,N,N,N,N,N,N,40105,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+35496,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39875,
+35553,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,39758,38352,N,N,N,36959,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,38894,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64590,N,N,N,N,N,N,
+39759,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+39760,40646,N,N,N,N,N,N,N,N,N,N,N,64592,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,64883,N,N,N,N,N,64935,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,40354,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64088,64094,N,
+N,N,N,N,N,N,41049,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64117,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64446,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,40098,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,37744,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37745,37751,65263,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,37741,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64605,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,37048,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,35580,N,64321,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40555,38115,36578,35965,N,36567,
+N,N,N,N,N,N,40013,N,N,N,38563,N,N,N,N,N,N,N,N,N,N,39761,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35523,N,N,N,N,N,N,N,N,N,N,N,
+38570,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,64616,35693,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,64871,35561,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64673,37740,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,39762,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65136,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,64680,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64745,40116,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,35562,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+39763,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39765,N,N,N,38571,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64679,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+39766,35516,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35531,N,N,N,N,
+N,39767,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35277,N,39769,39771,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,37797,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,39773,N,N,N,40527,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,37795,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35451,N,N,N,35650,
+38736,36787,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35408,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,39776,N,N,N,N,35653,N,N,N,35654,N,N,N,N,N,N,N,N,N,N,N,N,40446,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39778,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37755,N,N,N,N,N,37809,N,N,N,N,N,N,N,35424,N,N,
+N,N,N,N,N,N,35544,N,N,N,N,39779,N,N,N,N,N,N,N,N,N,N,35433,N,N,N,35399,N,N,
+35532,37756,39781,N,N,N,N,N,N,N,N,N,39782,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35442,N,N,N,N,N,
+N,N,35450,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37807,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35504,N,N,N,N,
+N,N,N,39784,N,N,N,N,N,N,N,N,N,N,40611,N,N,64236,35703,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,39783,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35673,64689,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64699,N,N,N,N,N,
+N,N,N,N,N,N,39785,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37800,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,35552,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,40529,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36703,39786,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,39787,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38892,39788,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65102,N,N,N,N,N,N,64962,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,39789,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+37223,64716,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37814,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37092,N,N,N,N,37093,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40690,37834,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,35772,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+36678,N,N,N,N,37839,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,64731,64732,N,N,N,N,N,N,N,N,N,N,N,N,N,37824,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,64742,38631,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64728,64729,64934,37838,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,38385,N,N,N,N,N,N,N,N,N,40169,N,64740,38063,64119,
+37836,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,36954,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,35924,N,N,N,N,N,N,N,37823,64337,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,37817,65239,37815,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37849,N,N,N,N,N,N,N,N,N,N,N,N,N,37819,
+37850,39075,N,N,N,N,N,N,N,N,N,37073,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+39790,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64112,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39915,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,39791,N,N,N,N,N,N,N,64764,N,N,N,N,N,N,N,N,N,N,N,N,N,35648,41083,N,N,N,
+36001,38903,N,N,N,37858,64726,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+38233,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37798,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,64832,N,N,37727,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38898,40054,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,36600,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,36679,N,N,N,N,N,N,N,N,N,N,N,N,39796,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37556,
+N,N,N,37357,N,N,38610,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64838,36687,38217,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39797,64092,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39801,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,64843,N,N,N,38611,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,64856,N,N,N,N,N,37983,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,41205,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,37443,N,N,N,N,N,N,38906,N,N,N,N,N,N,N,N,N,N,N,N,
+40409,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+38900,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37453,64859,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,39802,N,N,N,N,N,N,N,N,N,40661,N,N,N,N,N,N,N,N,N,N,N,N,64174,N,40137,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,37464,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,36552,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,38068,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+37857,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37855,N,N,N,N,N,64752,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37868,38902,38607,37854,35535,39842,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,64873,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37714,N,N,N,N,N,N,
+N,N,N,N,N,39074,64878,36004,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64124,37882,36988,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36711,N,40375,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,41193,64078,64929,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40564,40895,40651,39865,
+40404,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38841,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36593,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,38267,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,40658,38739,38564,36798,38105,36952,64889,64891,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36570,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36602,39845,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,40665,38868,37051,64956,64966,37448,N,N,N,N,N,N,N,37557,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40385,
+37561,37542,36683,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39846,N,N,N,N,N,37558,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,36416,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,40664,37982,39007,38094,37450,64880,37991,N,N,N,N,N,N,N,N,N,N,N,
+36332,N,N,N,N,N,N,N,N,39896,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37960,64193,40183,64958,
+N,N,N,N,N,N,N,N,N,N,N,N,36826,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,64985,N,N,64638,N,N,N,N,N,N,N,N,37881,N,N,N,N,64067,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64235,
+64195,38867,38393,40008,64984,41176,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64983,64330,39855,37963,64969,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36524,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64946,N,N,N,N,N,37466,
+64701,37593,N,N,N,64981,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37597,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37465,38586,N,N,N,N,N,N,N,N,N,N,37467,N,N,N,N,N,
+N,N,N,N,39851,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,64986,64990,N,N,N,64979,N,N,N,N,N,N,N,N,N,35910,N,N,N,N,N,N,64982,
+64988,64989,N,N,N,N,37118,N,N,65185,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,35757,N,N,40152,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,40557,64892,64353,N,N,N,N,N,N,38648,N,N,N,N,N,N,N,N,
+38640,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64756,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,65120,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+38994,38479,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,37230,N,N,N,N,N,N,N,N,N,N,39021,N,N,39012,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37971,65004,64376,N,N,N,N,N,N,
+N,N,N,N,N,38330,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39005,N,37625,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,39002,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65014,N,
+N,N,N,N,N,N,37840,39010,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,39853,N,N,N,N,N,N,N,N,N,N,N,38735,39854,N,N,N,N,N,N,N,N,N,N,N,
+N,37970,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39856,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,37330,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,38890,64363,37297,65011,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,37579,N,N,N,N,N,N,N,N,N,39857,N,N,N,N,N,64748,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39019,N,N,N,38737,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+39025,38383,N,N,N,N,N,N,N,40691,N,N,N,N,N,37352,39866,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64332,
+37482,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+65016,39009,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37351,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,37869,38724,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37345,N,N,64501,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,39017,N,N,N,N,35426,N,N,39867,36008,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40021,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36471,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35506,
+40636,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37862,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,37794,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39869,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38067,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,37757,40550,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+37977,N,N,N,N,N,N,N,N,N,39871,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37976,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+40613,39879,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65108,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,36468,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35798,N,N,N,N,N,N,
+38070,64884,39104,38053,N,N,N,N,N,N,N,39880,N,N,N,38381,64894,64491,N,N,N,N,N,
+N,N,N,N,N,64893,N,N,N,N,N,N,N,N,N,38767,37985,N,40897,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,38359,N,N,N,64082,40024,N,N,N,N,N,N,N,N,N,40808,39911,64718,
+38632,64073,38817,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+38221,40696,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65097,37326,38769,N,N,N,N,36047,N,
+N,N,64945,N,N,64622,N,N,N,N,N,40178,37816,36931,38745,38103,65126,38013,64623,
+N,N,N,N,37446,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64109,N,N,36599,N,64439,N,38012,
+37581,38834,N,N,N,N,N,N,N,N,N,65125,38526,38744,39799,37327,N,N,N,N,N,N,N,N,N,
+38052,N,N,N,N,N,N,N,N,N,N,40109,N,N,N,N,N,N,N,N,N,35755,N,N,N,38613,64691,N,N,
+N,37806,N,38765,N,N,N,N,N,N,37958,38391,N,N,N,N,N,N,N,N,40006,38235,37329,
+38132,N,65127,37541,N,N,N,65247,36011,N,39881,N,N,N,N,N,N,N,N,N,N,N,64749,
+65018,64712,65122,37372,65131,65017,64711,37198,40120,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,38759,N,N,N,38382,N,N,39858,N,N,N,N,37984,N,N,N,38050,39029,
+38828,37331,N,N,N,N,N,N,N,N,N,N,N,39035,N,N,N,N,N,N,N,36587,38762,38494,N,N,N,
+N,N,N,N,N,N,38891,N,N,N,N,N,40953,38392,65186,36838,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,65150,N,N,N,N,N,N,40356,38760,36588,38077,N,N,N,N,N,N,N,N,N,N,N,N,N,
+37979,40182,64167,39897,N,N,N,N,N,N,N,N,N,64093,38486,38754,N,N,N,N,N,N,38074,
+41039,37592,N,N,N,39883,N,N,N,N,N,N,38075,N,N,40287,N,N,N,N,N,N,37071,N,N,N,N,
+N,N,N,N,N,N,N,N,N,37989,N,N,40780,N,N,N,N,N,N,37080,40638,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,64365,38346,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,40386,38904,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,36860,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38003,38004,N,N,
+N,N,N,N,N,N,N,N,N,N,65207,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35403,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35413,
+35689,35548,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35702,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39886,N,
+35432,41208,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,39135,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,65205,N,N,N,39887,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38651,N,N,39931,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,40654,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36581,N,N,N,N,N,
+N,N,N,N,40571,39890,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,35493,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,65230,35397,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,40444,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65231,35749,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35914,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,35564,N,N,64736,38061,65237,38060,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64602,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39894,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+35439,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35753,36447,N,N,40395,N,64743,39895,N,N,
+N,N,N,N,N,N,N,N,N,37832,N,N,N,N,N,N,N,N,N,37360,36832,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,39899,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,37101,N,39900,41196,N,N,N,39162,N,N,N,N,N,N,N,N,N,39904,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37831,37449,38625,39906,N,
+N,N,39908,N,N,36833,39909,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+38080,N,N,37827,N,N,N,N,N,N,N,N,N,N,37829,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36985,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,38779,N,N,N,N,N,36990,N,N,N,N,65254,65094,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,40376,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37488,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,38312,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36016,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38088,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,39097,37184,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,64702,N,N,N,N,N,N,N,37207,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+35762,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64223,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39910,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,38467,36420,40015,65268,N,N,N,N,N,39912,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,37852,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38511,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,36426,39917,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,37622,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40377,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36430,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64463,40642,N,N,N,N,N,
+N,38117,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39920,38116,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,38225,35771,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39921,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+38128,36452,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38122,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36705,N,N,N,39780,36443,N,N,N,N,39922,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40894,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40393,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36460,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36723,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,36015,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36725,
+36465,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36448,36458,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,35916,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38226,38228,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,35540,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40379,38211,
+37630,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+38130,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38129,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,41194,40402,41137,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37368,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37986,39844,36525,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40621,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38608,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,65262,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35508,N,
+N,N,N,N,N,N,N,N,N,N,N,38743,35447,39927,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,36533,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41069,36534,38742,
+38208,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,41203,38078,N,N,N,39930,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64991,40380,N,N,N,N,N,N,N,N,38142,N,N,
+N,N,N,N,N,N,35803,41214,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36544,
+40775,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35806,41211,N,N,N,N,36547,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38473,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,65218,N,N,38220,39933,N,N,N,N,N,N,N,N,N,N,N,N,N,37068,40032,
+38219,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39934,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,40048,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,40003,N,N,N,40007,36556,N,N,N,36436,N,N,N,N,N,N,N,N,N,N,36580,40009,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35678,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38238,N,N,N,N,N,N,N,N,N,N,N,N,
+38236,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40011,35809,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,36569,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40372,N,37471,N,N,N,
+40012,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+35489,N,N,N,N,N,N,N,N,N,N,N,N,N,36571,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+40022,35490,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,38740,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40030,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,40660,38248,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+41155,35558,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,41207,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40033,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,40031,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,64589,N,40539,N,N,N,N,N,N,N,N,40553,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40035,65223,N,
+N,65222,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40039,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,40041,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35810,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,37221,N,N,N,N,N,N,N,N,N,N,N,N,40167,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,35412,N,N,N,N,N,N,N,40044,40046,65117,N,N,N,N,N,40051,N,N,N,N,N,N,N,N,
+N,N,N,N,N,38250,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38253,36592,36685,N,N,N,N,36598,N,
+N,N,N,N,N,N,N,64188,N,36053,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64474,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35660,
+64885,39901,64245,N,N,N,N,N,N,N,40052,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,38213,N,N,N,N,N,N,N,N,N,N,N,N,38598,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,36714,36686,N,N,N,N,N,40056,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+64085,N,N,N,N,N,N,N,N,N,N,N,N,38884,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40001,37468,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38650,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64358,36453,38985,64424,38978,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40058,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,38907,37066,N,N,N,N,40027,N,N,38733,N,N,36563,N,N,N,N,N,N,N,N,N,
+N,N,N,N,38241,40779,40885,37842,64938,38976,37190,39015,64090,64425,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38977,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36051,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+64765,64939,37309,36684,38601,36693,64430,38255,N,N,N,N,N,N,40061,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+41200,N,N,N,N,N,N,N,N,N,N,N,N,N,37999,64940,N,N,N,N,38603,38606,N,N,N,N,41046,
+N,40161,N,N,N,N,N,N,N,N,N,N,38596,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36702,36716,36515,64435,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+64595,N,N,N,64947,N,N,N,N,36715,N,N,N,N,N,N,N,N,N,N,N,N,38602,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,36729,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40559,41157,64632,
+36418,36698,37058,36517,36961,37455,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37747,64949,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65228,N,64445,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36054,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38979,38597,35260,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,40099,N,N,N,N,N,N,37451,38986,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36772,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41201,
+40699,40146,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36775,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,64604,38981,N,N,36934,36049,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,65274,38240,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40776,37447,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,37115,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40100,38257,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,40102,N,N,N,N,40103,N,N,N,N,N,40106,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40659,N,N,N,40560,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,40108,36782,38269,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40112,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38838,
+N,41149,35551,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,40618,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+36797,N,N,N,36799,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37737,39847,
+51364,N,N,N,N,65258,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,39905,N,N,N,N,N,N,35649,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,40374,41195,39843,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+35745,36808,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,35148,39008,N,N,N,N,N,N,N,N,N,N,38087,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,35672,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,38315,38314,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,40131,40132,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,37846,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,40364,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35814,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35441,36817,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,39381,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37108,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35491,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40142,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,40148,40149,N,N,N,64456,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40371,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64624,N,N,N,N,N,36823,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39795,N,N,N,N,N,N,N,N,N,N,64091,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,36818,36964,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39094,
+38504,N,N,N,N,40150,N,N,N,N,N,N,N,N,N,N,N,N,39101,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36828,65270,36825,N,N,N,N,N,N,N,N,N,N,N,N,N,
+38209,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38899,39928,40556,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36850,36846,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,40151,N,N,N,N,N,N,N,N,N,N,N,N,40558,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,35392,N,N,N,N,N,N,N,N,N,N,36847,N,N,N,N,N,N,N,N,36852,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36853,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38338,39018,N,38863,40572,36929,N,N,N,
+N,N,N,40155,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37953,N,N,N,N,40166,40368,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40170,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40173,N,N,N,N,N,N,N,N,N,N,N,N,40186,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,35682,35406,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,40138,35430,N,N,N,N,N,N,N,N,N,N,40187,40188,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40190,N,N,N,N,N,N,N,N,N,N,N,
+N,N,35411,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40165,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,40256,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,40257,N,N,N,N,N,N,N,N,N,N,N,N,36933,35699,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,38858,N,40258,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+35425,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,35758,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35538,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,35746,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40434,40259,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40159,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,40260,N,N,N,N,N,N,N,N,N,N,36554,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36942,N,N,N,N,N,N,N,36531,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,40949,N,N,N,N,N,N,N,N,N,N,N,N,40261,36943,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+40263,N,N,N,35274,N,N,N,N,N,N,40117,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64510,36958,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36963,36951,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36966,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,39872,N,N,N,N,N,N,N,N,N,N,N,64741,37218,N,N,N,N,N,N,N,N,N,N,36967,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36769,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,36770,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,40264,64211,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36957,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,37049,N,N,N,N,N,N,N,N,N,N,N,N,N,36971,35932,N,N,N,
+36969,65111,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,65109,36979,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39919,40176,N,N,
+N,N,N,N,N,N,N,N,N,N,40267,N,N,N,N,N,N,N,N,N,N,N,N,N,65241,N,N,N,65242,N,N,N,
+37344,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37336,N,N,N,N,N,N,N,N,N,N,38470,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37728,N,64083,40147,N,N,
+N,N,N,N,N,N,N,N,N,N,40270,N,N,N,64320,N,N,N,36322,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,37954,N,36950,N,N,39013,N,35948,64074,N,N,40272,
+40274,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38319,38746,37705,38727,41204,N,N,N,N,N,
+N,38776,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36815,N,N,N,64608,N,N,N,N,N,N,N,N,35918,N,
+N,N,64598,N,N,N,N,N,N,N,N,N,N,N,N,N,37340,38497,37612,37725,36574,38654,64847,
+38366,N,N,N,N,N,N,N,N,N,N,N,N,N,39088,41024,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38845,38781,38901,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,39852,64218,37570,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38833,N,N,N,N,N,36987,N,N,N,N,37886,38011,
+N,38775,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64190,64835,37062,37028,37032,38057,N,
+37033,N,N,N,N,35941,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38368,36989,N,N,N,N,N,N,
+37477,N,N,N,N,N,N,N,N,N,N,N,N,N,64954,37828,N,N,N,N,N,N,N,N,65261,40363,41187,
+N,38472,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40275,N,N,N,N,N,35497,N,
+39877,N,38493,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38751,38495,38510,64349,N,N,
+N,N,N,40369,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,65187,N,N,N,N,N,N,N,N,N,40370,N,N,38318,64675,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41122,N,N,38485,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,40276,N,N,37697,N,38317,37333,N,N,N,N,N,N,N,N,N,N,N,N,38778,65020,
+36423,37885,37029,37036,N,N,N,N,N,N,N,N,38316,N,N,N,N,N,N,N,N,N,37038,65189,N,
+N,N,N,N,40278,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38883,38370,N,N,N,N,N,37990,
+N,N,38471,N,N,N,N,37304,N,N,N,N,40172,N,N,N,N,N,N,N,N,37037,N,38371,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35663,N,N,35555,N,N,N,N,35661,38378,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35662,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36033,35821,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37337,N,N,41124,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38389,38388,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,40883,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65199,N,N,N,N,
+N,65138,37498,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,65196,N,N,N,N,N,N,N,N,N,N,N,N,N,38387,40280,37746,N,N,37317,N,N,N,N,
+N,N,N,38466,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37069,38398,
+37209,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40037,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38860,37070,N,N,N,N,N,N,40281,64757,65277,N,N,
+40283,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,40284,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37758,N,N,N,N,N,N,N,N,N,N,
+N,N,N,39084,N,N,40286,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64976,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64864,N,
+N,N,N,N,N,N,N,N,N,N,40143,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37085,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,37088,37107,N,N,39089,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37104,N,N,N,N,
+N,N,N,N,N,N,N,37821,N,N,N,N,N,N,N,N,38327,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+40774,N,N,N,N,N,N,N,N,36427,38488,N,N,N,N,N,N,N,N,N,N,35404,N,40291,40655,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40293,N,N,N,N,N,N,N,40294,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38490,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+40292,N,N,N,N,N,N,N,N,N,N,35436,35545,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40295,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,35440,35827,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,37200,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,40129,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,40296,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+37799,N,N,N,N,N,N,38516,41199,N,37201,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38593,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,35940,38518,40297,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64676,
+N,N,N,N,N,N,N,N,N,N,N,N,40298,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37454,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40299,N,N,N,N,N,39873,
+40300,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+35429,37213,N,N,N,N,N,N,N,N,40301,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37210,35906,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,40128,37226,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+40302,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40614,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40397,N,N,40303,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,35259,40697,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,38580,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37234,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40648,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,35669,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40305,40306,N,N,N,N,
+N,N,N,N,N,N,N,N,40652,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37236,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40656,36956,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36562,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,37288,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,37239,N,N,N,N,N,N,N,N,N,N,N,38591,N,N,N,N,N,38592,N,N,N,N,
+36785,N,N,N,N,N,38583,35925,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,37240,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35262,37244,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,64375,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,37237,37283,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37238,N,N,N,
+N,N,N,N,N,38590,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,37241,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38582,
+37284,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37286,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,40309,N,N,N,N,N,N,N,N,N,N,N,36946,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+41029,N,37289,N,39082,N,N,N,35935,N,N,35754,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40157,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,40311,35136,40684,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37802,38008,N,N,N,N,40314,35529,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,35659,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40940,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,35554,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,40565,39028,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,39624,N,N,N,N,41031,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35779,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64584,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+64631,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,40018,36605,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+36776,N,N,N,N,N,N,N,N,N,38266,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+36848,
+};
+
+static const struct unim_index big5hkscs_nonbmp_encmap[256] = {
+{__big5hkscs_nonbmp_encmap+0,33,238},{__big5hkscs_nonbmp_encmap+206,12,242},{
+__big5hkscs_nonbmp_encmap+437,4,229},{__big5hkscs_nonbmp_encmap+663,10,252},{
+__big5hkscs_nonbmp_encmap+906,19,254},{__big5hkscs_nonbmp_encmap+1142,71,235},
+{__big5hkscs_nonbmp_encmap+1307,17,118},{__big5hkscs_nonbmp_encmap+1409,14,121
+},{__big5hkscs_nonbmp_encmap+1517,44,213},{__big5hkscs_nonbmp_encmap+1687,22,
+231},{__big5hkscs_nonbmp_encmap+1897,17,205},{__big5hkscs_nonbmp_encmap+2086,
+13,255},{__big5hkscs_nonbmp_encmap+2329,11,255},{__big5hkscs_nonbmp_encmap+
+2574,21,200},{__big5hkscs_nonbmp_encmap+2754,4,251},{__big5hkscs_nonbmp_encmap
++3002,29,237},{__big5hkscs_nonbmp_encmap+3211,20,246},{
+__big5hkscs_nonbmp_encmap+3438,47,217},{__big5hkscs_nonbmp_encmap+3609,60,254
+},{__big5hkscs_nonbmp_encmap+3804,2,254},{__big5hkscs_nonbmp_encmap+4057,19,
+253},{__big5hkscs_nonbmp_encmap+4292,119,150},{__big5hkscs_nonbmp_encmap+4324,
+10,254},{__big5hkscs_nonbmp_encmap+4569,13,252},{__big5hkscs_nonbmp_encmap+
+4809,32,250},{__big5hkscs_nonbmp_encmap+5028,3,243},{__big5hkscs_nonbmp_encmap
++5269,45,75},{__big5hkscs_nonbmp_encmap+5300,68,194},{
+__big5hkscs_nonbmp_encmap+5427,42,172},{__big5hkscs_nonbmp_encmap+5558,70,249
+},{__big5hkscs_nonbmp_encmap+5738,28,213},{__big5hkscs_nonbmp_encmap+5924,15,
+232},{__big5hkscs_nonbmp_encmap+6142,69,252},{__big5hkscs_nonbmp_encmap+6326,
+42,195},{__big5hkscs_nonbmp_encmap+6480,8,124},{__big5hkscs_nonbmp_encmap+6597
+,33,250},{__big5hkscs_nonbmp_encmap+6815,101,237},{__big5hkscs_nonbmp_encmap+
+6952,19,190},{__big5hkscs_nonbmp_encmap+7124,27,246},{
+__big5hkscs_nonbmp_encmap+7344,18,205},{__big5hkscs_nonbmp_encmap+7532,3,247},
+{__big5hkscs_nonbmp_encmap+7777,38,147},{__big5hkscs_nonbmp_encmap+7887,102,
+232},{__big5hkscs_nonbmp_encmap+8018,14,206},{__big5hkscs_nonbmp_encmap+8211,
+38,201},{__big5hkscs_nonbmp_encmap+8375,7,238},{__big5hkscs_nonbmp_encmap+8607
+,13,239},{__big5hkscs_nonbmp_encmap+8834,116,227},{__big5hkscs_nonbmp_encmap+
+8946,51,218},{__big5hkscs_nonbmp_encmap+9114,3,249},{__big5hkscs_nonbmp_encmap
++9361,15,225},{__big5hkscs_nonbmp_encmap+9572,0,254},{
+__big5hkscs_nonbmp_encmap+9827,0,229},{__big5hkscs_nonbmp_encmap+10057,25,243
+},{__big5hkscs_nonbmp_encmap+10276,0,238},{__big5hkscs_nonbmp_encmap+10515,3,
+215},{__big5hkscs_nonbmp_encmap+10728,58,58},{__big5hkscs_nonbmp_encmap+10729,
+194,194},{__big5hkscs_nonbmp_encmap+10730,167,250},{__big5hkscs_nonbmp_encmap+
+10814,90,90},{__big5hkscs_nonbmp_encmap+10815,99,255},{
+__big5hkscs_nonbmp_encmap+10972,64,248},{__big5hkscs_nonbmp_encmap+11157,17,
+252},{__big5hkscs_nonbmp_encmap+11393,53,240},{__big5hkscs_nonbmp_encmap+11581
+,17,225},{__big5hkscs_nonbmp_encmap+11790,4,252},{__big5hkscs_nonbmp_encmap+
+12039,27,250},{__big5hkscs_nonbmp_encmap+12263,13,248},{
+__big5hkscs_nonbmp_encmap+12499,4,214},{__big5hkscs_nonbmp_encmap+12710,5,200
+},{__big5hkscs_nonbmp_encmap+12906,24,212},{__big5hkscs_nonbmp_encmap+13095,6,
+224},{__big5hkscs_nonbmp_encmap+13314,18,255},{__big5hkscs_nonbmp_encmap+13552
+,0,251},{__big5hkscs_nonbmp_encmap+13804,14,233},{__big5hkscs_nonbmp_encmap+
+14024,110,245},{__big5hkscs_nonbmp_encmap+14160,9,217},{
+__big5hkscs_nonbmp_encmap+14369,6,235},{__big5hkscs_nonbmp_encmap+14599,59,167
+},{__big5hkscs_nonbmp_encmap+14708,14,194},{__big5hkscs_nonbmp_encmap+14889,
+44,157},{__big5hkscs_nonbmp_encmap+15003,43,231},{__big5hkscs_nonbmp_encmap+
+15192,32,216},{__big5hkscs_nonbmp_encmap+15377,14,19},{
+__big5hkscs_nonbmp_encmap+15383,25,110},{__big5hkscs_nonbmp_encmap+15469,49,
+224},{__big5hkscs_nonbmp_encmap+15645,5,246},{__big5hkscs_nonbmp_encmap+15887,
+6,225},{__big5hkscs_nonbmp_encmap+16107,87,225},{__big5hkscs_nonbmp_encmap+
+16246,3,204},{__big5hkscs_nonbmp_encmap+16448,149,233},{
+__big5hkscs_nonbmp_encmap+16533,116,232},{__big5hkscs_nonbmp_encmap+16650,1,
+254},{__big5hkscs_nonbmp_encmap+16904,32,67},{__big5hkscs_nonbmp_encmap+16940,
+14,216},{__big5hkscs_nonbmp_encmap+17143,26,226},{__big5hkscs_nonbmp_encmap+
+17344,41,165},{__big5hkscs_nonbmp_encmap+17469,2,221},{
+__big5hkscs_nonbmp_encmap+17689,88,208},{__big5hkscs_nonbmp_encmap+17810,53,
+248},{__big5hkscs_nonbmp_encmap+18006,2,152},{__big5hkscs_nonbmp_encmap+18157,
+18,191},{__big5hkscs_nonbmp_encmap+18331,18,252},{__big5hkscs_nonbmp_encmap+
+18566,22,204},{__big5hkscs_nonbmp_encmap+18749,28,199},{
+__big5hkscs_nonbmp_encmap+18921,14,250},{__big5hkscs_nonbmp_encmap+19158,45,82
+},{__big5hkscs_nonbmp_encmap+19196,5,247},{__big5hkscs_nonbmp_encmap+19439,33,
+209},{__big5hkscs_nonbmp_encmap+19616,34,240},{__big5hkscs_nonbmp_encmap+19823
+,0,215},{__big5hkscs_nonbmp_encmap+20039,38,223},{__big5hkscs_nonbmp_encmap+
+20225,14,248},{__big5hkscs_nonbmp_encmap+20460,9,205},{
+__big5hkscs_nonbmp_encmap+20657,27,230},{__big5hkscs_nonbmp_encmap+20861,154,
+154},{__big5hkscs_nonbmp_encmap+20862,34,134},{__big5hkscs_nonbmp_encmap+20963
+,116,254},{__big5hkscs_nonbmp_encmap+21102,7,148},{__big5hkscs_nonbmp_encmap+
+21244,15,204},{__big5hkscs_nonbmp_encmap+21434,88,200},{
+__big5hkscs_nonbmp_encmap+21547,36,253},{__big5hkscs_nonbmp_encmap+21765,10,
+244},{__big5hkscs_nonbmp_encmap+22000,6,244},{__big5hkscs_nonbmp_encmap+22239,
+18,18},{__big5hkscs_nonbmp_encmap+22240,47,220},{__big5hkscs_nonbmp_encmap+
+22414,77,79},{__big5hkscs_nonbmp_encmap+22417,249,249},{
+__big5hkscs_nonbmp_encmap+22418,2,244},{__big5hkscs_nonbmp_encmap+22661,46,188
+},{__big5hkscs_nonbmp_encmap+22804,7,226},{__big5hkscs_nonbmp_encmap+23024,6,
+138},{__big5hkscs_nonbmp_encmap+23157,18,130},{__big5hkscs_nonbmp_encmap+23270
+,1,244},{__big5hkscs_nonbmp_encmap+23514,0,230},{__big5hkscs_nonbmp_encmap+
+23745,15,19},{__big5hkscs_nonbmp_encmap+23750,4,43},{__big5hkscs_nonbmp_encmap
++23790,51,252},{__big5hkscs_nonbmp_encmap+23992,15,252},{
+__big5hkscs_nonbmp_encmap+24230,12,255},{__big5hkscs_nonbmp_encmap+24474,3,210
+},{__big5hkscs_nonbmp_encmap+24682,52,185},{__big5hkscs_nonbmp_encmap+24816,
+15,231},{__big5hkscs_nonbmp_encmap+25033,197,197},{__big5hkscs_nonbmp_encmap+
+25034,136,237},{__big5hkscs_nonbmp_encmap+25136,13,235},{0,0,0},{0,0,0},{
+__big5hkscs_nonbmp_encmap+25359,29,231},{__big5hkscs_nonbmp_encmap+25562,158,
+244},{0,0,0},{__big5hkscs_nonbmp_encmap+25649,32,212},{
+__big5hkscs_nonbmp_encmap+25830,16,241},{__big5hkscs_nonbmp_encmap+26056,3,201
+},{__big5hkscs_nonbmp_encmap+26255,40,77},{__big5hkscs_nonbmp_encmap+26293,5,
+213},{__big5hkscs_nonbmp_encmap+26502,115,173},{__big5hkscs_nonbmp_encmap+
+26561,62,246},{__big5hkscs_nonbmp_encmap+26746,6,248},{
+__big5hkscs_nonbmp_encmap+26989,35,222},{__big5hkscs_nonbmp_encmap+27177,20,
+254},{__big5hkscs_nonbmp_encmap+27412,7,245},{__big5hkscs_nonbmp_encmap+27651,
+32,255},{__big5hkscs_nonbmp_encmap+27875,169,169},{__big5hkscs_nonbmp_encmap+
+27876,52,91},{__big5hkscs_nonbmp_encmap+27916,198,203},{
+__big5hkscs_nonbmp_encmap+27922,1,169},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+__big5hkscs_nonbmp_encmap+28091,37,205},{__big5hkscs_nonbmp_encmap+28260,148,
+212},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
+};

Added: vendor/Python/current/Modules/cjkcodecs/mappings_jisx0213_pair.h
===================================================================
--- vendor/Python/current/Modules/cjkcodecs/mappings_jisx0213_pair.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/cjkcodecs/mappings_jisx0213_pair.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,59 @@
+#define JISX0213_ENCPAIRS 46
+#ifdef EXTERN_JISX0213_PAIR
+static const struct widedbcs_index *jisx0213_pair_decmap;
+static const struct pair_encodemap *jisx0213_pair_encmap;
+#else
+static const ucs4_t __jisx0213_pair_decmap[49] = {
+810234010,810365082,810496154,810627226,810758298,816525466,816656538,
+816787610,816918682,817049754,817574042,818163866,818426010,838283418,
+15074048,U,U,U,39060224,39060225,42730240,42730241,39387904,39387905,39453440,
+39453441,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,48825061,48562921,
+};
+
+static const struct widedbcs_index jisx0213_pair_decmap[256] = {
+{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__jisx0213_pair_decmap
++0,119,123},{__jisx0213_pair_decmap+5,119,126},{__jisx0213_pair_decmap+13,120,
+120},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__jisx0213_pair_decmap+14,68,102},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
+};
+
+static const struct pair_encodemap jisx0213_pair_encmap[JISX0213_ENCPAIRS] = {
+{0x00e60000,0x295c},{0x00e60300,0x2b44},{0x02540000,0x2b38},{0x02540300,0x2b48
+},{0x02540301,0x2b49},{0x02590000,0x2b30},{0x02590300,0x2b4c},{0x02590301,
+0x2b4d},{0x025a0000,0x2b43},{0x025a0300,0x2b4e},{0x025a0301,0x2b4f},{
+0x028c0000,0x2b37},{0x028c0300,0x2b4a},{0x028c0301,0x2b4b},{0x02e50000,0x2b60
+},{0x02e502e9,0x2b66},{0x02e90000,0x2b64},{0x02e902e5,0x2b65},{0x304b0000,
+0x242b},{0x304b309a,0x2477},{0x304d0000,0x242d},{0x304d309a,0x2478},{
+0x304f0000,0x242f},{0x304f309a,0x2479},{0x30510000,0x2431},{0x3051309a,0x247a
+},{0x30530000,0x2433},{0x3053309a,0x247b},{0x30ab0000,0x252b},{0x30ab309a,
+0x2577},{0x30ad0000,0x252d},{0x30ad309a,0x2578},{0x30af0000,0x252f},{
+0x30af309a,0x2579},{0x30b10000,0x2531},{0x30b1309a,0x257a},{0x30b30000,0x2533
+},{0x30b3309a,0x257b},{0x30bb0000,0x253b},{0x30bb309a,0x257c},{0x30c40000,
+0x2544},{0x30c4309a,0x257d},{0x30c80000,0x2548},{0x30c8309a,0x257e},{
+0x31f70000,0x2675},{0x31f7309a,0x2678},
+};
+#endif

Added: vendor/Python/current/Modules/cjkcodecs/mappings_jp.h
===================================================================
--- vendor/Python/current/Modules/cjkcodecs/mappings_jp.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/cjkcodecs/mappings_jp.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,4765 @@
+static const ucs2_t __jisx0208_decmap[6956] = {
+12288,12289,12290,65292,65294,12539,65306,65307,65311,65281,12443,12444,180,
+65344,168,65342,65507,65343,12541,12542,12445,12446,12291,20189,12293,12294,
+12295,12540,8213,8208,65295,92,12316,8214,65372,8230,8229,8216,8217,8220,8221,
+65288,65289,12308,12309,65339,65341,65371,65373,12296,12297,12298,12299,12300,
+12301,12302,12303,12304,12305,65291,8722,177,215,247,65309,8800,65308,65310,
+8806,8807,8734,8756,9794,9792,176,8242,8243,8451,65509,65284,162,163,65285,
+65283,65286,65290,65312,167,9734,9733,9675,9679,9678,9671,9670,9633,9632,9651,
+9650,9661,9660,8251,12306,8594,8592,8593,8595,12307,U,U,U,U,U,U,U,U,U,U,U,
+8712,8715,8838,8839,8834,8835,8746,8745,U,U,U,U,U,U,U,U,8743,8744,172,8658,
+8660,8704,8707,U,U,U,U,U,U,U,U,U,U,U,8736,8869,8978,8706,8711,8801,8786,8810,
+8811,8730,8765,8733,8757,8747,8748,U,U,U,U,U,U,U,8491,8240,9839,9837,9834,
+8224,8225,182,U,U,U,U,9711,65296,65297,65298,65299,65300,65301,65302,65303,
+65304,65305,U,U,U,U,U,U,U,65313,65314,65315,65316,65317,65318,65319,65320,
+65321,65322,65323,65324,65325,65326,65327,65328,65329,65330,65331,65332,65333,
+65334,65335,65336,65337,65338,U,U,U,U,U,U,65345,65346,65347,65348,65349,65350,
+65351,65352,65353,65354,65355,65356,65357,65358,65359,65360,65361,65362,65363,
+65364,65365,65366,65367,65368,65369,65370,12353,12354,12355,12356,12357,12358,
+12359,12360,12361,12362,12363,12364,12365,12366,12367,12368,12369,12370,12371,
+12372,12373,12374,12375,12376,12377,12378,12379,12380,12381,12382,12383,12384,
+12385,12386,12387,12388,12389,12390,12391,12392,12393,12394,12395,12396,12397,
+12398,12399,12400,12401,12402,12403,12404,12405,12406,12407,12408,12409,12410,
+12411,12412,12413,12414,12415,12416,12417,12418,12419,12420,12421,12422,12423,
+12424,12425,12426,12427,12428,12429,12430,12431,12432,12433,12434,12435,12449,
+12450,12451,12452,12453,12454,12455,12456,12457,12458,12459,12460,12461,12462,
+12463,12464,12465,12466,12467,12468,12469,12470,12471,12472,12473,12474,12475,
+12476,12477,12478,12479,12480,12481,12482,12483,12484,12485,12486,12487,12488,
+12489,12490,12491,12492,12493,12494,12495,12496,12497,12498,12499,12500,12501,
+12502,12503,12504,12505,12506,12507,12508,12509,12510,12511,12512,12513,12514,
+12515,12516,12517,12518,12519,12520,12521,12522,12523,12524,12525,12526,12527,
+12528,12529,12530,12531,12532,12533,12534,913,914,915,916,917,918,919,920,921,
+922,923,924,925,926,927,928,929,931,932,933,934,935,936,937,U,U,U,U,U,U,U,U,
+945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,963,964,
+965,966,967,968,969,1040,1041,1042,1043,1044,1045,1025,1046,1047,1048,1049,
+1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,
+1065,1066,1067,1068,1069,1070,1071,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,1072,1073,
+1074,1075,1076,1077,1105,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,
+1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,
+1103,9472,9474,9484,9488,9496,9492,9500,9516,9508,9524,9532,9473,9475,9487,
+9491,9499,9495,9507,9523,9515,9531,9547,9504,9519,9512,9527,9535,9501,9520,
+9509,9528,9538,20124,21782,23043,38463,21696,24859,25384,23030,36898,33909,
+33564,31312,24746,25569,28197,26093,33894,33446,39925,26771,22311,26017,25201,
+23451,22992,34427,39156,32098,32190,39822,25110,31903,34999,23433,24245,25353,
+26263,26696,38343,38797,26447,20197,20234,20301,20381,20553,22258,22839,22996,
+23041,23561,24799,24847,24944,26131,26885,28858,30031,30064,31227,32173,32239,
+32963,33806,34915,35586,36949,36986,21307,20117,20133,22495,32946,37057,30959,
+19968,22769,28322,36920,31282,33576,33419,39983,20801,21360,21693,21729,22240,
+23035,24341,39154,28139,32996,34093,38498,38512,38560,38907,21515,21491,23431,
+28879,32701,36802,38632,21359,40284,31418,19985,30867,33276,28198,22040,21764,
+27421,34074,39995,23013,21417,28006,29916,38287,22082,20113,36939,38642,33615,
+39180,21473,21942,23344,24433,26144,26355,26628,27704,27891,27945,29787,30408,
+31310,38964,33521,34907,35424,37613,28082,30123,30410,39365,24742,35585,36234,
+38322,27022,21421,20870,22290,22576,22852,23476,24310,24616,25513,25588,27839,
+28436,28814,28948,29017,29141,29503,32257,33398,33489,34199,36960,37467,40219,
+22633,26044,27738,29989,20985,22830,22885,24448,24540,25276,26106,27178,27431,
+27572,29579,32705,35158,40236,40206,40644,23713,27798,33659,20740,23627,25014,
+33222,26742,29281,20057,20474,21368,24681,28201,31311,38899,19979,21270,20206,
+20309,20285,20385,20339,21152,21487,22025,22799,23233,23478,23521,31185,26247,
+26524,26550,27468,27827,28779,29634,31117,31166,31292,31623,33457,33499,33540,
+33655,33775,33747,34662,35506,22057,36008,36838,36942,38686,34442,20420,23784,
+25105,29273,30011,33253,33469,34558,36032,38597,39187,39381,20171,20250,35299,
+22238,22602,22730,24315,24555,24618,24724,24674,25040,25106,25296,25913,39745,
+26214,26800,28023,28784,30028,30342,32117,33445,34809,38283,38542,35997,20977,
+21182,22806,21683,23475,23830,24936,27010,28079,30861,33995,34903,35442,37799,
+39608,28012,39336,34521,22435,26623,34510,37390,21123,22151,21508,24275,25313,
+25785,26684,26680,27579,29554,30906,31339,35226,35282,36203,36611,37101,38307,
+38548,38761,23398,23731,27005,38989,38990,25499,31520,27179,27263,26806,39949,
+28511,21106,21917,24688,25324,27963,28167,28369,33883,35088,36676,19988,39993,
+21494,26907,27194,38788,26666,20828,31427,33970,37340,37772,22107,40232,26658,
+33541,33841,31909,21000,33477,29926,20094,20355,20896,23506,21002,21208,21223,
+24059,21914,22570,23014,23436,23448,23515,24178,24185,24739,24863,24931,25022,
+25563,25954,26577,26707,26874,27454,27475,27735,28450,28567,28485,29872,29976,
+30435,30475,31487,31649,31777,32233,32566,32752,32925,33382,33694,35251,35532,
+36011,36996,37969,38291,38289,38306,38501,38867,39208,33304,20024,21547,23736,
+24012,29609,30284,30524,23721,32747,36107,38593,38929,38996,39000,20225,20238,
+21361,21916,22120,22522,22855,23305,23492,23696,24076,24190,24524,25582,26426,
+26071,26082,26399,26827,26820,27231,24112,27589,27671,27773,30079,31048,23395,
+31232,32000,24509,35215,35352,36020,36215,36556,36637,39138,39438,39740,20096,
+20605,20736,22931,23452,25135,25216,25836,27450,29344,30097,31047,32681,34811,
+35516,35696,25516,33738,38816,21513,21507,21931,26708,27224,35440,30759,26485,
+40653,21364,23458,33050,34384,36870,19992,20037,20167,20241,21450,21560,23470,
+24339,24613,25937,26429,27714,27762,27875,28792,29699,31350,31406,31496,32026,
+31998,32102,26087,29275,21435,23621,24040,25298,25312,25369,28192,34394,35377,
+36317,37624,28417,31142,39770,20136,20139,20140,20379,20384,20689,20807,31478,
+20849,20982,21332,21281,21375,21483,21932,22659,23777,24375,24394,24623,24656,
+24685,25375,25945,27211,27841,29378,29421,30703,33016,33029,33288,34126,37111,
+37857,38911,39255,39514,20208,20957,23597,26241,26989,23616,26354,26997,29577,
+26704,31873,20677,21220,22343,24062,37670,26020,27427,27453,29748,31105,31165,
+31563,32202,33465,33740,34943,35167,35641,36817,37329,21535,37504,20061,20534,
+21477,21306,29399,29590,30697,33510,36527,39366,39368,39378,20855,24858,34398,
+21936,31354,20598,23507,36935,38533,20018,27355,37351,23633,23624,25496,31391,
+27795,38772,36705,31402,29066,38536,31874,26647,32368,26705,37740,21234,21531,
+34219,35347,32676,36557,37089,21350,34952,31041,20418,20670,21009,20804,21843,
+22317,29674,22411,22865,24418,24452,24693,24950,24935,25001,25522,25658,25964,
+26223,26690,28179,30054,31293,31995,32076,32153,32331,32619,33550,33610,34509,
+35336,35427,35686,36605,38938,40335,33464,36814,39912,21127,25119,25731,28608,
+38553,26689,20625,27424,27770,28500,31348,32080,34880,35363,26376,20214,20537,
+20518,20581,20860,21048,21091,21927,22287,22533,23244,24314,25010,25080,25331,
+25458,26908,27177,29309,29356,29486,30740,30831,32121,30476,32937,35211,35609,
+36066,36562,36963,37749,38522,38997,39443,40568,20803,21407,21427,24187,24358,
+28187,28304,29572,29694,32067,33335,35328,35578,38480,20046,20491,21476,21628,
+22266,22993,23396,24049,24235,24359,25144,25925,26543,28246,29392,31946,34996,
+32929,32993,33776,34382,35463,36328,37431,38599,39015,40723,20116,20114,20237,
+21320,21577,21566,23087,24460,24481,24735,26791,27278,29786,30849,35486,35492,
+35703,37264,20062,39881,20132,20348,20399,20505,20502,20809,20844,21151,21177,
+21246,21402,21475,21521,21518,21897,22353,22434,22909,23380,23389,23439,24037,
+24039,24055,24184,24195,24218,24247,24344,24658,24908,25239,25304,25511,25915,
+26114,26179,26356,26477,26657,26775,27083,27743,27946,28009,28207,28317,30002,
+30343,30828,31295,31968,32005,32024,32094,32177,32789,32771,32943,32945,33108,
+33167,33322,33618,34892,34913,35611,36002,36092,37066,37237,37489,30783,37628,
+38308,38477,38917,39321,39640,40251,21083,21163,21495,21512,22741,25335,28640,
+35946,36703,40633,20811,21051,21578,22269,31296,37239,40288,40658,29508,28425,
+33136,29969,24573,24794,39592,29403,36796,27492,38915,20170,22256,22372,22718,
+23130,24680,25031,26127,26118,26681,26801,28151,30165,32058,33390,39746,20123,
+20304,21449,21766,23919,24038,24046,26619,27801,29811,30722,35408,37782,35039,
+22352,24231,25387,20661,20652,20877,26368,21705,22622,22971,23472,24425,25165,
+25505,26685,27507,28168,28797,37319,29312,30741,30758,31085,25998,32048,33756,
+35009,36617,38555,21092,22312,26448,32618,36001,20916,22338,38442,22586,27018,
+32948,21682,23822,22524,30869,40442,20316,21066,21643,25662,26152,26388,26613,
+31364,31574,32034,37679,26716,39853,31545,21273,20874,21047,23519,25334,25774,
+25830,26413,27578,34217,38609,30352,39894,25420,37638,39851,30399,26194,19977,
+20632,21442,23665,24808,25746,25955,26719,29158,29642,29987,31639,32386,34453,
+35715,36059,37240,39184,26028,26283,27531,20181,20180,20282,20351,21050,21496,
+21490,21987,22235,22763,22987,22985,23039,23376,23629,24066,24107,24535,24605,
+25351,25903,23388,26031,26045,26088,26525,27490,27515,27663,29509,31049,31169,
+31992,32025,32043,32930,33026,33267,35222,35422,35433,35430,35468,35566,36039,
+36060,38604,39164,27503,20107,20284,20365,20816,23383,23546,24904,25345,26178,
+27425,28363,27835,29246,29885,30164,30913,31034,32780,32819,33258,33940,36766,
+27728,40575,24335,35672,40235,31482,36600,23437,38635,19971,21489,22519,22833,
+23241,23460,24713,28287,28422,30142,36074,23455,34048,31712,20594,26612,33437,
+23649,34122,32286,33294,20889,23556,25448,36198,26012,29038,31038,32023,32773,
+35613,36554,36974,34503,37034,20511,21242,23610,26451,28796,29237,37196,37320,
+37675,33509,23490,24369,24825,20027,21462,23432,25163,26417,27530,29417,29664,
+31278,33131,36259,37202,39318,20754,21463,21610,23551,25480,27193,32172,38656,
+22234,21454,21608,23447,23601,24030,20462,24833,25342,27954,31168,31179,32066,
+32333,32722,33261,33311,33936,34886,35186,35728,36468,36655,36913,37195,37228,
+38598,37276,20160,20303,20805,21313,24467,25102,26580,27713,28171,29539,32294,
+37325,37507,21460,22809,23487,28113,31069,32302,31899,22654,29087,20986,34899,
+36848,20426,23803,26149,30636,31459,33308,39423,20934,24490,26092,26991,27529,
+28147,28310,28516,30462,32020,24033,36981,37255,38918,20966,21021,25152,26257,
+26329,28186,24246,32210,32626,26360,34223,34295,35576,21161,21465,22899,24207,
+24464,24661,37604,38500,20663,20767,21213,21280,21319,21484,21736,21830,21809,
+22039,22888,22974,23100,23477,23558,23567,23569,23578,24196,24202,24288,24432,
+25215,25220,25307,25484,25463,26119,26124,26157,26230,26494,26786,27167,27189,
+27836,28040,28169,28248,28988,28966,29031,30151,30465,30813,30977,31077,31216,
+31456,31505,31911,32057,32918,33750,33931,34121,34909,35059,35359,35388,35412,
+35443,35937,36062,37284,37478,37758,37912,38556,38808,19978,19976,19998,20055,
+20887,21104,22478,22580,22732,23330,24120,24773,25854,26465,26454,27972,29366,
+30067,31331,33976,35698,37304,37664,22065,22516,39166,25325,26893,27542,29165,
+32340,32887,33394,35302,39135,34645,36785,23611,20280,20449,20405,21767,23072,
+23517,23529,24515,24910,25391,26032,26187,26862,27035,28024,28145,30003,30137,
+30495,31070,31206,32051,33251,33455,34218,35242,35386,36523,36763,36914,37341,
+38663,20154,20161,20995,22645,22764,23563,29978,23613,33102,35338,36805,38499,
+38765,31525,35535,38920,37218,22259,21416,36887,21561,22402,24101,25512,27700,
+28810,30561,31883,32736,34928,36930,37204,37648,37656,38543,29790,39620,23815,
+23913,25968,26530,36264,38619,25454,26441,26905,33733,38935,38592,35070,28548,
+25722,23544,19990,28716,30045,26159,20932,21046,21218,22995,24449,24615,25104,
+25919,25972,26143,26228,26866,26646,27491,28165,29298,29983,30427,31934,32854,
+22768,35069,35199,35488,35475,35531,36893,37266,38738,38745,25993,31246,33030,
+38587,24109,24796,25114,26021,26132,26512,30707,31309,31821,32318,33034,36012,
+36196,36321,36447,30889,20999,25305,25509,25666,25240,35373,31363,31680,35500,
+38634,32118,33292,34633,20185,20808,21315,21344,23459,23554,23574,24029,25126,
+25159,25776,26643,26676,27849,27973,27927,26579,28508,29006,29053,26059,31359,
+31661,32218,32330,32680,33146,33307,33337,34214,35438,36046,36341,36984,36983,
+37549,37521,38275,39854,21069,21892,28472,28982,20840,31109,32341,33203,31950,
+22092,22609,23720,25514,26366,26365,26970,29401,30095,30094,30990,31062,31199,
+31895,32032,32068,34311,35380,38459,36961,40736,20711,21109,21452,21474,20489,
+21930,22766,22863,29245,23435,23652,21277,24803,24819,25436,25475,25407,25531,
+25805,26089,26361,24035,27085,27133,28437,29157,20105,30185,30456,31379,31967,
+32207,32156,32865,33609,33624,33900,33980,34299,35013,36208,36865,36973,37783,
+38684,39442,20687,22679,24974,33235,34101,36104,36896,20419,20596,21063,21363,
+24687,25417,26463,28204,36275,36895,20439,23646,36042,26063,32154,21330,34966,
+20854,25539,23384,23403,23562,25613,26449,36956,20182,22810,22826,27760,35409,
+21822,22549,22949,24816,25171,26561,33333,26965,38464,39364,39464,20307,22534,
+23550,32784,23729,24111,24453,24608,24907,25140,26367,27888,28382,32974,33151,
+33492,34955,36024,36864,36910,38538,40667,39899,20195,21488,22823,31532,37261,
+38988,40441,28381,28711,21331,21828,23429,25176,25246,25299,27810,28655,29730,
+35351,37944,28609,35582,33592,20967,34552,21482,21481,20294,36948,36784,22890,
+33073,24061,31466,36799,26842,35895,29432,40008,27197,35504,20025,21336,22022,
+22374,25285,25506,26086,27470,28129,28251,28845,30701,31471,31658,32187,32829,
+32966,34507,35477,37723,22243,22727,24382,26029,26262,27264,27573,30007,35527,
+20516,30693,22320,24347,24677,26234,27744,30196,31258,32622,33268,34584,36933,
+39347,31689,30044,31481,31569,33988,36880,31209,31378,33590,23265,30528,20013,
+20210,23449,24544,25277,26172,26609,27880,34411,34935,35387,37198,37619,39376,
+27159,28710,29482,33511,33879,36015,19969,20806,20939,21899,23541,24086,24115,
+24193,24340,24373,24427,24500,25074,25361,26274,26397,28526,29266,30010,30522,
+32884,33081,33144,34678,35519,35548,36229,36339,37530,38263,38914,40165,21189,
+25431,30452,26389,27784,29645,36035,37806,38515,27941,22684,26894,27084,36861,
+37786,30171,36890,22618,26626,25524,27131,20291,28460,26584,36795,34086,32180,
+37716,26943,28528,22378,22775,23340,32044,29226,21514,37347,40372,20141,20302,
+20572,20597,21059,35998,21576,22564,23450,24093,24213,24237,24311,24351,24716,
+25269,25402,25552,26799,27712,30855,31118,31243,32224,33351,35330,35558,36420,
+36883,37048,37165,37336,40718,27877,25688,25826,25973,28404,30340,31515,36969,
+37841,28346,21746,24505,25764,36685,36845,37444,20856,22635,22825,23637,24215,
+28155,32399,29980,36028,36578,39003,28857,20253,27583,28593,30000,38651,20814,
+21520,22581,22615,22956,23648,24466,26007,26460,28193,30331,33759,36077,36884,
+37117,37709,30757,30778,21162,24230,22303,22900,24594,20498,20826,20908,20941,
+20992,21776,22612,22616,22871,23445,23798,23947,24764,25237,25645,26481,26691,
+26812,26847,30423,28120,28271,28059,28783,29128,24403,30168,31095,31561,31572,
+31570,31958,32113,21040,33891,34153,34276,35342,35588,35910,36367,36867,36879,
+37913,38518,38957,39472,38360,20685,21205,21516,22530,23566,24999,25758,27934,
+30643,31461,33012,33796,36947,37509,23776,40199,21311,24471,24499,28060,29305,
+30563,31167,31716,27602,29420,35501,26627,27233,20984,31361,26932,23626,40182,
+33515,23493,37193,28702,22136,23663,24775,25958,27788,35930,36929,38931,21585,
+26311,37389,22856,37027,20869,20045,20970,34201,35598,28760,25466,37707,26978,
+39348,32260,30071,21335,26976,36575,38627,27741,20108,23612,24336,36841,21250,
+36049,32905,34425,24319,26085,20083,20837,22914,23615,38894,20219,22922,24525,
+35469,28641,31152,31074,23527,33905,29483,29105,24180,24565,25467,25754,29123,
+31896,20035,24316,20043,22492,22178,24745,28611,32013,33021,33075,33215,36786,
+35223,34468,24052,25226,25773,35207,26487,27874,27966,29750,30772,23110,32629,
+33453,39340,20467,24259,25309,25490,25943,26479,30403,29260,32972,32954,36649,
+37197,20493,22521,23186,26757,26995,29028,29437,36023,22770,36064,38506,36889,
+34687,31204,30695,33833,20271,21093,21338,25293,26575,27850,30333,31636,31893,
+33334,34180,36843,26333,28448,29190,32283,33707,39361,40614,20989,31665,30834,
+31672,32903,31560,27368,24161,32908,30033,30048,20843,37474,28300,30330,37271,
+39658,20240,32624,25244,31567,38309,40169,22138,22617,34532,38588,20276,21028,
+21322,21453,21467,24070,25644,26001,26495,27710,27726,29256,29359,29677,30036,
+32321,33324,34281,36009,31684,37318,29033,38930,39151,25405,26217,30058,30436,
+30928,34115,34542,21290,21329,21542,22915,24199,24444,24754,25161,25209,25259,
+26000,27604,27852,30130,30382,30865,31192,32203,32631,32933,34987,35513,36027,
+36991,38750,39131,27147,31800,20633,23614,24494,26503,27608,29749,30473,32654,
+40763,26570,31255,21305,30091,39661,24422,33181,33777,32920,24380,24517,30050,
+31558,36924,26727,23019,23195,32016,30334,35628,20469,24426,27161,27703,28418,
+29922,31080,34920,35413,35961,24287,25551,30149,31186,33495,37672,37618,33948,
+34541,39981,21697,24428,25996,27996,28693,36007,36051,38971,25935,29942,19981,
+20184,22496,22827,23142,23500,20904,24067,24220,24598,25206,25975,26023,26222,
+28014,29238,31526,33104,33178,33433,35676,36000,36070,36212,38428,38468,20398,
+25771,27494,33310,33889,34154,37096,23553,26963,39080,33914,34135,20239,21103,
+24489,24133,26381,31119,33145,35079,35206,28149,24343,25173,27832,20175,29289,
+39826,20998,21563,22132,22707,24996,25198,28954,22894,31881,31966,32027,38640,
+25991,32862,19993,20341,20853,22592,24163,24179,24330,26564,20006,34109,38281,
+38491,31859,38913,20731,22721,30294,30887,21029,30629,34065,31622,20559,22793,
+29255,31687,32232,36794,36820,36941,20415,21193,23081,24321,38829,20445,33303,
+37610,22275,25429,27497,29995,35036,36628,31298,21215,22675,24917,25098,26286,
+27597,31807,33769,20515,20472,21253,21574,22577,22857,23453,23792,23791,23849,
+24214,25265,25447,25918,26041,26379,27861,27873,28921,30770,32299,32990,33459,
+33804,34028,34562,35090,35370,35914,37030,37586,39165,40179,40300,20047,20129,
+20621,21078,22346,22952,24125,24536,24537,25151,26292,26395,26576,26834,20882,
+32033,32938,33192,35584,35980,36031,37502,38450,21536,38956,21271,20693,21340,
+22696,25778,26420,29287,30566,31302,37350,21187,27809,27526,22528,24140,22868,
+26412,32763,20961,30406,25705,30952,39764,40635,22475,22969,26151,26522,27598,
+21737,27097,24149,33180,26517,39850,26622,40018,26717,20134,20451,21448,25273,
+26411,27819,36804,20397,32365,40639,19975,24930,28288,28459,34067,21619,26410,
+39749,24051,31637,23724,23494,34588,28234,34001,31252,33032,22937,31885,27665,
+30496,21209,22818,28961,29279,30683,38695,40289,26891,23167,23064,20901,21517,
+21629,26126,30431,36855,37528,40180,23018,29277,28357,20813,26825,32191,32236,
+38754,40634,25720,27169,33538,22916,23391,27611,29467,30450,32178,32791,33945,
+20786,26408,40665,30446,26466,21247,39173,23588,25147,31870,36016,21839,24758,
+32011,38272,21249,20063,20918,22812,29242,32822,37326,24357,30690,21380,24441,
+32004,34220,35379,36493,38742,26611,34222,37971,24841,24840,27833,30290,35565,
+36664,21807,20305,20778,21191,21451,23461,24189,24736,24962,25558,26377,26586,
+28263,28044,29494,29495,30001,31056,35029,35480,36938,37009,37109,38596,34701,
+22805,20104,20313,19982,35465,36671,38928,20653,24188,22934,23481,24248,25562,
+25594,25793,26332,26954,27096,27915,28342,29076,29992,31407,32650,32768,33865,
+33993,35201,35617,36362,36965,38525,39178,24958,25233,27442,27779,28020,32716,
+32764,28096,32645,34746,35064,26469,33713,38972,38647,27931,32097,33853,37226,
+20081,21365,23888,27396,28651,34253,34349,35239,21033,21519,23653,26446,26792,
+29702,29827,30178,35023,35041,37324,38626,38520,24459,29575,31435,33870,25504,
+30053,21129,27969,28316,29705,30041,30827,31890,38534,31452,40845,20406,24942,
+26053,34396,20102,20142,20698,20001,20940,23534,26009,26753,28092,29471,30274,
+30637,31260,31975,33391,35538,36988,37327,38517,38936,21147,32209,20523,21400,
+26519,28107,29136,29747,33256,36650,38563,40023,40607,29792,22593,28057,32047,
+39006,20196,20278,20363,20919,21169,23994,24604,29618,31036,33491,37428,38583,
+38646,38666,40599,40802,26278,27508,21015,21155,28872,35010,24265,24651,24976,
+28451,29001,31806,32244,32879,34030,36899,37676,21570,39791,27347,28809,36034,
+36335,38706,21172,23105,24266,24324,26391,27004,27028,28010,28431,29282,29436,
+31725,32769,32894,34635,37070,20845,40595,31108,32907,37682,35542,20525,21644,
+35441,27498,36036,33031,24785,26528,40434,20121,20120,39952,35435,34241,34152,
+26880,28286,30871,33109,24332,19984,19989,20010,20017,20022,20028,20031,20034,
+20054,20056,20098,20101,35947,20106,33298,24333,20110,20126,20127,20128,20130,
+20144,20147,20150,20174,20173,20164,20166,20162,20183,20190,20205,20191,20215,
+20233,20314,20272,20315,20317,20311,20295,20342,20360,20367,20376,20347,20329,
+20336,20369,20335,20358,20374,20760,20436,20447,20430,20440,20443,20433,20442,
+20432,20452,20453,20506,20520,20500,20522,20517,20485,20252,20470,20513,20521,
+20524,20478,20463,20497,20486,20547,20551,26371,20565,20560,20552,20570,20566,
+20588,20600,20608,20634,20613,20660,20658,20681,20682,20659,20674,20694,20702,
+20709,20717,20707,20718,20729,20725,20745,20737,20738,20758,20757,20756,20762,
+20769,20794,20791,20796,20795,20799,20800,20818,20812,20820,20834,31480,20841,
+20842,20846,20864,20866,22232,20876,20873,20879,20881,20883,20885,20886,20900,
+20902,20898,20905,20906,20907,20915,20913,20914,20912,20917,20925,20933,20937,
+20955,20960,34389,20969,20973,20976,20981,20990,20996,21003,21012,21006,21031,
+21034,21038,21043,21049,21071,21060,21067,21068,21086,21076,21098,21108,21097,
+21107,21119,21117,21133,21140,21138,21105,21128,21137,36776,36775,21164,21165,
+21180,21173,21185,21197,21207,21214,21219,21222,39149,21216,21235,21237,21240,
+21241,21254,21256,30008,21261,21264,21263,21269,21274,21283,21295,21297,21299,
+21304,21312,21318,21317,19991,21321,21325,20950,21342,21353,21358,22808,21371,
+21367,21378,21398,21408,21414,21413,21422,21424,21430,21443,31762,38617,21471,
+26364,29166,21486,21480,21485,21498,21505,21565,21568,21548,21549,21564,21550,
+21558,21545,21533,21582,21647,21621,21646,21599,21617,21623,21616,21650,21627,
+21632,21622,21636,21648,21638,21703,21666,21688,21669,21676,21700,21704,21672,
+21675,21698,21668,21694,21692,21720,21733,21734,21775,21780,21757,21742,21741,
+21754,21730,21817,21824,21859,21836,21806,21852,21829,21846,21847,21816,21811,
+21853,21913,21888,21679,21898,21919,21883,21886,21912,21918,21934,21884,21891,
+21929,21895,21928,21978,21957,21983,21956,21980,21988,21972,22036,22007,22038,
+22014,22013,22043,22009,22094,22096,29151,22068,22070,22066,22072,22123,22116,
+22063,22124,22122,22150,22144,22154,22176,22164,22159,22181,22190,22198,22196,
+22210,22204,22209,22211,22208,22216,22222,22225,22227,22231,22254,22265,22272,
+22271,22276,22281,22280,22283,22285,22291,22296,22294,21959,22300,22310,22327,
+22328,22350,22331,22336,22351,22377,22464,22408,22369,22399,22409,22419,22432,
+22451,22436,22442,22448,22467,22470,22484,22482,22483,22538,22486,22499,22539,
+22553,22557,22642,22561,22626,22603,22640,27584,22610,22589,22649,22661,22713,
+22687,22699,22714,22750,22715,22712,22702,22725,22739,22737,22743,22745,22744,
+22757,22748,22756,22751,22767,22778,22777,22779,22780,22781,22786,22794,22800,
+22811,26790,22821,22828,22829,22834,22840,22846,31442,22869,22864,22862,22874,
+22872,22882,22880,22887,22892,22889,22904,22913,22941,20318,20395,22947,22962,
+22982,23016,23004,22925,23001,23002,23077,23071,23057,23068,23049,23066,23104,
+23148,23113,23093,23094,23138,23146,23194,23228,23230,23243,23234,23229,23267,
+23255,23270,23273,23254,23290,23291,23308,23307,23318,23346,23248,23338,23350,
+23358,23363,23365,23360,23377,23381,23386,23387,23397,23401,23408,23411,23413,
+23416,25992,23418,23424,23427,23462,23480,23491,23495,23497,23508,23504,23524,
+23526,23522,23518,23525,23531,23536,23542,23539,23557,23559,23560,23565,23571,
+23584,23586,23592,23608,23609,23617,23622,23630,23635,23632,23631,23409,23660,
+23662,20066,23670,23673,23692,23697,23700,22939,23723,23739,23734,23740,23735,
+23749,23742,23751,23769,23785,23805,23802,23789,23948,23786,23819,23829,23831,
+23900,23839,23835,23825,23828,23842,23834,23833,23832,23884,23890,23886,23883,
+23916,23923,23926,23943,23940,23938,23970,23965,23980,23982,23997,23952,23991,
+23996,24009,24013,24019,24018,24022,24027,24043,24050,24053,24075,24090,24089,
+24081,24091,24118,24119,24132,24131,24128,24142,24151,24148,24159,24162,24164,
+24135,24181,24182,24186,40636,24191,24224,24257,24258,24264,24272,24271,24278,
+24291,24285,24282,24283,24290,24289,24296,24297,24300,24305,24307,24304,24308,
+24312,24318,24323,24329,24413,24412,24331,24337,24342,24361,24365,24376,24385,
+24392,24396,24398,24367,24401,24406,24407,24409,24417,24429,24435,24439,24451,
+24450,24447,24458,24456,24465,24455,24478,24473,24472,24480,24488,24493,24508,
+24534,24571,24548,24568,24561,24541,24755,24575,24609,24672,24601,24592,24617,
+24590,24625,24603,24597,24619,24614,24591,24634,24666,24641,24682,24695,24671,
+24650,24646,24653,24675,24643,24676,24642,24684,24683,24665,24705,24717,24807,
+24707,24730,24708,24731,24726,24727,24722,24743,24715,24801,24760,24800,24787,
+24756,24560,24765,24774,24757,24792,24909,24853,24838,24822,24823,24832,24820,
+24826,24835,24865,24827,24817,24845,24846,24903,24894,24872,24871,24906,24895,
+24892,24876,24884,24893,24898,24900,24947,24951,24920,24921,24922,24939,24948,
+24943,24933,24945,24927,24925,24915,24949,24985,24982,24967,25004,24980,24986,
+24970,24977,25003,25006,25036,25034,25033,25079,25032,25027,25030,25018,25035,
+32633,25037,25062,25059,25078,25082,25076,25087,25085,25084,25086,25088,25096,
+25097,25101,25100,25108,25115,25118,25121,25130,25134,25136,25138,25139,25153,
+25166,25182,25187,25179,25184,25192,25212,25218,25225,25214,25234,25235,25238,
+25300,25219,25236,25303,25297,25275,25295,25343,25286,25812,25288,25308,25292,
+25290,25282,25287,25243,25289,25356,25326,25329,25383,25346,25352,25327,25333,
+25424,25406,25421,25628,25423,25494,25486,25472,25515,25462,25507,25487,25481,
+25503,25525,25451,25449,25534,25577,25536,25542,25571,25545,25554,25590,25540,
+25622,25652,25606,25619,25638,25654,25885,25623,25640,25615,25703,25711,25718,
+25678,25898,25749,25747,25765,25769,25736,25788,25818,25810,25797,25799,25787,
+25816,25794,25841,25831,33289,25824,25825,25260,25827,25839,25900,25846,25844,
+25842,25850,25856,25853,25880,25884,25861,25892,25891,25899,25908,25909,25911,
+25910,25912,30027,25928,25942,25941,25933,25944,25950,25949,25970,25976,25986,
+25987,35722,26011,26015,26027,26039,26051,26054,26049,26052,26060,26066,26075,
+26073,26080,26081,26097,26482,26122,26115,26107,26483,26165,26166,26164,26140,
+26191,26180,26185,26177,26206,26205,26212,26215,26216,26207,26210,26224,26243,
+26248,26254,26249,26244,26264,26269,26305,26297,26313,26302,26300,26308,26296,
+26326,26330,26336,26175,26342,26345,26352,26357,26359,26383,26390,26398,26406,
+26407,38712,26414,26431,26422,26433,26424,26423,26438,26462,26464,26457,26467,
+26468,26505,26480,26537,26492,26474,26508,26507,26534,26529,26501,26551,26607,
+26548,26604,26547,26601,26552,26596,26590,26589,26594,26606,26553,26574,26566,
+26599,27292,26654,26694,26665,26688,26701,26674,26702,26803,26667,26713,26723,
+26743,26751,26783,26767,26797,26772,26781,26779,26755,27310,26809,26740,26805,
+26784,26810,26895,26765,26750,26881,26826,26888,26840,26914,26918,26849,26892,
+26829,26836,26855,26837,26934,26898,26884,26839,26851,26917,26873,26848,26863,
+26920,26922,26906,26915,26913,26822,27001,26999,26972,27000,26987,26964,27006,
+26990,26937,26996,26941,26969,26928,26977,26974,26973,27009,26986,27058,27054,
+27088,27071,27073,27091,27070,27086,23528,27082,27101,27067,27075,27047,27182,
+27025,27040,27036,27029,27060,27102,27112,27138,27163,27135,27402,27129,27122,
+27111,27141,27057,27166,27117,27156,27115,27146,27154,27329,27171,27155,27204,
+27148,27250,27190,27256,27207,27234,27225,27238,27208,27192,27170,27280,27277,
+27296,27268,27298,27299,27287,34327,27323,27331,27330,27320,27315,27308,27358,
+27345,27359,27306,27354,27370,27387,27397,34326,27386,27410,27414,39729,27423,
+27448,27447,30428,27449,39150,27463,27459,27465,27472,27481,27476,27483,27487,
+27489,27512,27513,27519,27520,27524,27523,27533,27544,27541,27550,27556,27562,
+27563,27567,27570,27569,27571,27575,27580,27590,27595,27603,27615,27628,27627,
+27635,27631,40638,27656,27667,27668,27675,27684,27683,27742,27733,27746,27754,
+27778,27789,27802,27777,27803,27774,27752,27763,27794,27792,27844,27889,27859,
+27837,27863,27845,27869,27822,27825,27838,27834,27867,27887,27865,27882,27935,
+34893,27958,27947,27965,27960,27929,27957,27955,27922,27916,28003,28051,28004,
+27994,28025,27993,28046,28053,28644,28037,28153,28181,28170,28085,28103,28134,
+28088,28102,28140,28126,28108,28136,28114,28101,28154,28121,28132,28117,28138,
+28142,28205,28270,28206,28185,28274,28255,28222,28195,28267,28203,28278,28237,
+28191,28227,28218,28238,28196,28415,28189,28216,28290,28330,28312,28361,28343,
+28371,28349,28335,28356,28338,28372,28373,28303,28325,28354,28319,28481,28433,
+28748,28396,28408,28414,28479,28402,28465,28399,28466,28364,28478,28435,28407,
+28550,28538,28536,28545,28544,28527,28507,28659,28525,28546,28540,28504,28558,
+28561,28610,28518,28595,28579,28577,28580,28601,28614,28586,28639,28629,28652,
+28628,28632,28657,28654,28635,28681,28683,28666,28689,28673,28687,28670,28699,
+28698,28532,28701,28696,28703,28720,28734,28722,28753,28771,28825,28818,28847,
+28913,28844,28856,28851,28846,28895,28875,28893,28889,28937,28925,28956,28953,
+29029,29013,29064,29030,29026,29004,29014,29036,29071,29179,29060,29077,29096,
+29100,29143,29113,29118,29138,29129,29140,29134,29152,29164,29159,29173,29180,
+29177,29183,29197,29200,29211,29224,29229,29228,29232,29234,29243,29244,29247,
+29248,29254,29259,29272,29300,29310,29314,29313,29319,29330,29334,29346,29351,
+29369,29362,29379,29382,29380,29390,29394,29410,29408,29409,29433,29431,20495,
+29463,29450,29468,29462,29469,29492,29487,29481,29477,29502,29518,29519,40664,
+29527,29546,29544,29552,29560,29557,29563,29562,29640,29619,29646,29627,29632,
+29669,29678,29662,29858,29701,29807,29733,29688,29746,29754,29781,29759,29791,
+29785,29761,29788,29801,29808,29795,29802,29814,29822,29835,29854,29863,29898,
+29903,29908,29681,29920,29923,29927,29929,29934,29938,29936,29937,29944,29943,
+29956,29955,29957,29964,29966,29965,29973,29971,29982,29990,29996,30012,30020,
+30029,30026,30025,30043,30022,30042,30057,30052,30055,30059,30061,30072,30070,
+30086,30087,30068,30090,30089,30082,30100,30106,30109,30117,30115,30146,30131,
+30147,30133,30141,30136,30140,30129,30157,30154,30162,30169,30179,30174,30206,
+30207,30204,30209,30192,30202,30194,30195,30219,30221,30217,30239,30247,30240,
+30241,30242,30244,30260,30256,30267,30279,30280,30278,30300,30296,30305,30306,
+30312,30313,30314,30311,30316,30320,30322,30326,30328,30332,30336,30339,30344,
+30347,30350,30358,30355,30361,30362,30384,30388,30392,30393,30394,30402,30413,
+30422,30418,30430,30433,30437,30439,30442,34351,30459,30472,30471,30468,30505,
+30500,30494,30501,30502,30491,30519,30520,30535,30554,30568,30571,30555,30565,
+30591,30590,30585,30606,30603,30609,30624,30622,30640,30646,30649,30655,30652,
+30653,30651,30663,30669,30679,30682,30684,30691,30702,30716,30732,30738,31014,
+30752,31018,30789,30862,30836,30854,30844,30874,30860,30883,30901,30890,30895,
+30929,30918,30923,30932,30910,30908,30917,30922,30956,30951,30938,30973,30964,
+30983,30994,30993,31001,31020,31019,31040,31072,31063,31071,31066,31061,31059,
+31098,31103,31114,31133,31143,40779,31146,31150,31155,31161,31162,31177,31189,
+31207,31212,31201,31203,31240,31245,31256,31257,31264,31263,31104,31281,31291,
+31294,31287,31299,31319,31305,31329,31330,31337,40861,31344,31353,31357,31368,
+31383,31381,31384,31382,31401,31432,31408,31414,31429,31428,31423,36995,31431,
+31434,31437,31439,31445,31443,31449,31450,31453,31457,31458,31462,31469,31472,
+31490,31503,31498,31494,31539,31512,31513,31518,31541,31528,31542,31568,31610,
+31492,31565,31499,31564,31557,31605,31589,31604,31591,31600,31601,31596,31598,
+31645,31640,31647,31629,31644,31642,31627,31634,31631,31581,31641,31691,31681,
+31692,31695,31668,31686,31709,31721,31761,31764,31718,31717,31840,31744,31751,
+31763,31731,31735,31767,31757,31734,31779,31783,31786,31775,31799,31787,31805,
+31820,31811,31828,31823,31808,31824,31832,31839,31844,31830,31845,31852,31861,
+31875,31888,31908,31917,31906,31915,31905,31912,31923,31922,31921,31918,31929,
+31933,31936,31941,31938,31960,31954,31964,31970,39739,31983,31986,31988,31990,
+31994,32006,32002,32028,32021,32010,32069,32075,32046,32050,32063,32053,32070,
+32115,32086,32078,32114,32104,32110,32079,32099,32147,32137,32091,32143,32125,
+32155,32186,32174,32163,32181,32199,32189,32171,32317,32162,32175,32220,32184,
+32159,32176,32216,32221,32228,32222,32251,32242,32225,32261,32266,32291,32289,
+32274,32305,32287,32265,32267,32290,32326,32358,32315,32309,32313,32323,32311,
+32306,32314,32359,32349,32342,32350,32345,32346,32377,32362,32361,32380,32379,
+32387,32213,32381,36782,32383,32392,32393,32396,32402,32400,32403,32404,32406,
+32398,32411,32412,32568,32570,32581,32588,32589,32590,32592,32593,32597,32596,
+32600,32607,32608,32616,32617,32615,32632,32642,32646,32643,32648,32647,32652,
+32660,32670,32669,32666,32675,32687,32690,32697,32686,32694,32696,35697,32709,
+32710,32714,32725,32724,32737,32742,32745,32755,32761,39132,32774,32772,32779,
+32786,32792,32793,32796,32801,32808,32831,32827,32842,32838,32850,32856,32858,
+32863,32866,32872,32883,32882,32880,32886,32889,32893,32895,32900,32902,32901,
+32923,32915,32922,32941,20880,32940,32987,32997,32985,32989,32964,32986,32982,
+33033,33007,33009,33051,33065,33059,33071,33099,38539,33094,33086,33107,33105,
+33020,33137,33134,33125,33126,33140,33155,33160,33162,33152,33154,33184,33173,
+33188,33187,33119,33171,33193,33200,33205,33214,33208,33213,33216,33218,33210,
+33225,33229,33233,33241,33240,33224,33242,33247,33248,33255,33274,33275,33278,
+33281,33282,33285,33287,33290,33293,33296,33302,33321,33323,33336,33331,33344,
+33369,33368,33373,33370,33375,33380,33378,33384,33386,33387,33326,33393,33399,
+33400,33406,33421,33426,33451,33439,33467,33452,33505,33507,33503,33490,33524,
+33523,33530,33683,33539,33531,33529,33502,33542,33500,33545,33497,33589,33588,
+33558,33586,33585,33600,33593,33616,33605,33583,33579,33559,33560,33669,33690,
+33706,33695,33698,33686,33571,33678,33671,33674,33660,33717,33651,33653,33696,
+33673,33704,33780,33811,33771,33742,33789,33795,33752,33803,33729,33783,33799,
+33760,33778,33805,33826,33824,33725,33848,34054,33787,33901,33834,33852,34138,
+33924,33911,33899,33965,33902,33922,33897,33862,33836,33903,33913,33845,33994,
+33890,33977,33983,33951,34009,33997,33979,34010,34000,33985,33990,34006,33953,
+34081,34047,34036,34071,34072,34092,34079,34069,34068,34044,34112,34147,34136,
+34120,34113,34306,34123,34133,34176,34212,34184,34193,34186,34216,34157,34196,
+34203,34282,34183,34204,34167,34174,34192,34249,34234,34255,34233,34256,34261,
+34269,34277,34268,34297,34314,34323,34315,34302,34298,34310,34338,34330,34352,
+34367,34381,20053,34388,34399,34407,34417,34451,34467,34473,34474,34443,34444,
+34486,34479,34500,34502,34480,34505,34851,34475,34516,34526,34537,34540,34527,
+34523,34543,34578,34566,34568,34560,34563,34555,34577,34569,34573,34553,34570,
+34612,34623,34615,34619,34597,34601,34586,34656,34655,34680,34636,34638,34676,
+34647,34664,34670,34649,34643,34659,34666,34821,34722,34719,34690,34735,34763,
+34749,34752,34768,38614,34731,34756,34739,34759,34758,34747,34799,34802,34784,
+34831,34829,34814,34806,34807,34830,34770,34833,34838,34837,34850,34849,34865,
+34870,34873,34855,34875,34884,34882,34898,34905,34910,34914,34923,34945,34942,
+34974,34933,34941,34997,34930,34946,34967,34962,34990,34969,34978,34957,34980,
+34992,35007,34993,35011,35012,35028,35032,35033,35037,35065,35074,35068,35060,
+35048,35058,35076,35084,35082,35091,35139,35102,35109,35114,35115,35137,35140,
+35131,35126,35128,35148,35101,35168,35166,35174,35172,35181,35178,35183,35188,
+35191,35198,35203,35208,35210,35219,35224,35233,35241,35238,35244,35247,35250,
+35258,35261,35263,35264,35290,35292,35293,35303,35316,35320,35331,35350,35344,
+35340,35355,35357,35365,35382,35393,35419,35410,35398,35400,35452,35437,35436,
+35426,35461,35458,35460,35496,35489,35473,35493,35494,35482,35491,35524,35533,
+35522,35546,35563,35571,35559,35556,35569,35604,35552,35554,35575,35550,35547,
+35596,35591,35610,35553,35606,35600,35607,35616,35635,38827,35622,35627,35646,
+35624,35649,35660,35663,35662,35657,35670,35675,35674,35691,35679,35692,35695,
+35700,35709,35712,35724,35726,35730,35731,35734,35737,35738,35898,35905,35903,
+35912,35916,35918,35920,35925,35938,35948,35960,35962,35970,35977,35973,35978,
+35981,35982,35988,35964,35992,25117,36013,36010,36029,36018,36019,36014,36022,
+36040,36033,36068,36067,36058,36093,36090,36091,36100,36101,36106,36103,36111,
+36109,36112,40782,36115,36045,36116,36118,36199,36205,36209,36211,36225,36249,
+36290,36286,36282,36303,36314,36310,36300,36315,36299,36330,36331,36319,36323,
+36348,36360,36361,36351,36381,36382,36368,36383,36418,36405,36400,36404,36426,
+36423,36425,36428,36432,36424,36441,36452,36448,36394,36451,36437,36470,36466,
+36476,36481,36487,36485,36484,36491,36490,36499,36497,36500,36505,36522,36513,
+36524,36528,36550,36529,36542,36549,36552,36555,36571,36579,36604,36603,36587,
+36606,36618,36613,36629,36626,36633,36627,36636,36639,36635,36620,36646,36659,
+36667,36665,36677,36674,36670,36684,36681,36678,36686,36695,36700,36706,36707,
+36708,36764,36767,36771,36781,36783,36791,36826,36837,36834,36842,36847,36999,
+36852,36869,36857,36858,36881,36885,36897,36877,36894,36886,36875,36903,36918,
+36917,36921,36856,36943,36944,36945,36946,36878,36937,36926,36950,36952,36958,
+36968,36975,36982,38568,36978,36994,36989,36993,36992,37002,37001,37007,37032,
+37039,37041,37045,37090,37092,25160,37083,37122,37138,37145,37170,37168,37194,
+37206,37208,37219,37221,37225,37235,37234,37259,37257,37250,37282,37291,37295,
+37290,37301,37300,37306,37312,37313,37321,37323,37328,37334,37343,37345,37339,
+37372,37365,37366,37406,37375,37396,37420,37397,37393,37470,37463,37445,37449,
+37476,37448,37525,37439,37451,37456,37532,37526,37523,37531,37466,37583,37561,
+37559,37609,37647,37626,37700,37678,37657,37666,37658,37667,37690,37685,37691,
+37724,37728,37756,37742,37718,37808,37804,37805,37780,37817,37846,37847,37864,
+37861,37848,37827,37853,37840,37832,37860,37914,37908,37907,37891,37895,37904,
+37942,37931,37941,37921,37946,37953,37970,37956,37979,37984,37986,37982,37994,
+37417,38000,38005,38007,38013,37978,38012,38014,38017,38015,38274,38279,38282,
+38292,38294,38296,38297,38304,38312,38311,38317,38332,38331,38329,38334,38346,
+28662,38339,38349,38348,38357,38356,38358,38364,38369,38373,38370,38433,38440,
+38446,38447,38466,38476,38479,38475,38519,38492,38494,38493,38495,38502,38514,
+38508,38541,38552,38549,38551,38570,38567,38577,38578,38576,38580,38582,38584,
+38585,38606,38603,38601,38605,35149,38620,38669,38613,38649,38660,38662,38664,
+38675,38670,38673,38671,38678,38681,38692,38698,38704,38713,38717,38718,38724,
+38726,38728,38722,38729,38748,38752,38756,38758,38760,21202,38763,38769,38777,
+38789,38780,38785,38778,38790,38795,38799,38800,38812,38824,38822,38819,38835,
+38836,38851,38854,38856,38859,38876,38893,40783,38898,31455,38902,38901,38927,
+38924,38968,38948,38945,38967,38973,38982,38991,38987,39019,39023,39024,39025,
+39028,39027,39082,39087,39089,39094,39108,39107,39110,39145,39147,39171,39177,
+39186,39188,39192,39201,39197,39198,39204,39200,39212,39214,39229,39230,39234,
+39241,39237,39248,39243,39249,39250,39244,39253,39319,39320,39333,39341,39342,
+39356,39391,39387,39389,39384,39377,39405,39406,39409,39410,39419,39416,39425,
+39439,39429,39394,39449,39467,39479,39493,39490,39488,39491,39486,39509,39501,
+39515,39511,39519,39522,39525,39524,39529,39531,39530,39597,39600,39612,39616,
+39631,39633,39635,39636,39646,39647,39650,39651,39654,39663,39659,39662,39668,
+39665,39671,39675,39686,39704,39706,39711,39714,39715,39717,39719,39720,39721,
+39722,39726,39727,39730,39748,39747,39759,39757,39758,39761,39768,39796,39827,
+39811,39825,39830,39831,39839,39840,39848,39860,39872,39882,39865,39878,39887,
+39889,39890,39907,39906,39908,39892,39905,39994,39922,39921,39920,39957,39956,
+39945,39955,39948,39942,39944,39954,39946,39940,39982,39963,39973,39972,39969,
+39984,40007,39986,40006,39998,40026,40032,40039,40054,40056,40167,40172,40176,
+40201,40200,40171,40195,40198,40234,40230,40367,40227,40223,40260,40213,40210,
+40257,40255,40254,40262,40264,40285,40286,40292,40273,40272,40281,40306,40329,
+40327,40363,40303,40314,40346,40356,40361,40370,40388,40385,40379,40376,40378,
+40390,40399,40386,40409,40403,40440,40422,40429,40431,40445,40474,40475,40478,
+40565,40569,40573,40577,40584,40587,40588,40594,40597,40593,40605,40613,40617,
+40632,40618,40621,38753,40652,40654,40655,40656,40660,40668,40670,40669,40672,
+40677,40680,40687,40692,40694,40695,40697,40699,40700,40701,40711,40712,30391,
+40725,40737,40748,40766,40778,40786,40788,40803,40799,40800,40801,40806,40807,
+40812,40810,40823,40818,40822,40853,40860,40864,22575,27079,36953,29796,20956,
+29081,
+};
+
+static const struct dbcs_index jisx0208_decmap[256] = {
+{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{__jisx0208_decmap+0,33,126},{__jisx0208_decmap
++94,33,126},{__jisx0208_decmap+188,48,122},{__jisx0208_decmap+263,33,115},{
+__jisx0208_decmap+346,33,118},{__jisx0208_decmap+432,33,88},{__jisx0208_decmap
++488,33,113},{__jisx0208_decmap+569,33,64},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{__jisx0208_decmap+601,33,126},{__jisx0208_decmap+695,33,
+126},{__jisx0208_decmap+789,33,126},{__jisx0208_decmap+883,33,126},{
+__jisx0208_decmap+977,33,126},{__jisx0208_decmap+1071,33,126},{
+__jisx0208_decmap+1165,33,126},{__jisx0208_decmap+1259,33,126},{
+__jisx0208_decmap+1353,33,126},{__jisx0208_decmap+1447,33,126},{
+__jisx0208_decmap+1541,33,126},{__jisx0208_decmap+1635,33,126},{
+__jisx0208_decmap+1729,33,126},{__jisx0208_decmap+1823,33,126},{
+__jisx0208_decmap+1917,33,126},{__jisx0208_decmap+2011,33,126},{
+__jisx0208_decmap+2105,33,126},{__jisx0208_decmap+2199,33,126},{
+__jisx0208_decmap+2293,33,126},{__jisx0208_decmap+2387,33,126},{
+__jisx0208_decmap+2481,33,126},{__jisx0208_decmap+2575,33,126},{
+__jisx0208_decmap+2669,33,126},{__jisx0208_decmap+2763,33,126},{
+__jisx0208_decmap+2857,33,126},{__jisx0208_decmap+2951,33,126},{
+__jisx0208_decmap+3045,33,126},{__jisx0208_decmap+3139,33,126},{
+__jisx0208_decmap+3233,33,126},{__jisx0208_decmap+3327,33,126},{
+__jisx0208_decmap+3421,33,126},{__jisx0208_decmap+3515,33,83},{
+__jisx0208_decmap+3566,33,126},{__jisx0208_decmap+3660,33,126},{
+__jisx0208_decmap+3754,33,126},{__jisx0208_decmap+3848,33,126},{
+__jisx0208_decmap+3942,33,126},{__jisx0208_decmap+4036,33,126},{
+__jisx0208_decmap+4130,33,126},{__jisx0208_decmap+4224,33,126},{
+__jisx0208_decmap+4318,33,126},{__jisx0208_decmap+4412,33,126},{
+__jisx0208_decmap+4506,33,126},{__jisx0208_decmap+4600,33,126},{
+__jisx0208_decmap+4694,33,126},{__jisx0208_decmap+4788,33,126},{
+__jisx0208_decmap+4882,33,126},{__jisx0208_decmap+4976,33,126},{
+__jisx0208_decmap+5070,33,126},{__jisx0208_decmap+5164,33,126},{
+__jisx0208_decmap+5258,33,126},{__jisx0208_decmap+5352,33,126},{
+__jisx0208_decmap+5446,33,126},{__jisx0208_decmap+5540,33,126},{
+__jisx0208_decmap+5634,33,126},{__jisx0208_decmap+5728,33,126},{
+__jisx0208_decmap+5822,33,126},{__jisx0208_decmap+5916,33,126},{
+__jisx0208_decmap+6010,33,126},{__jisx0208_decmap+6104,33,126},{
+__jisx0208_decmap+6198,33,126},{__jisx0208_decmap+6292,33,126},{
+__jisx0208_decmap+6386,33,126},{__jisx0208_decmap+6480,33,126},{
+__jisx0208_decmap+6574,33,126},{__jisx0208_decmap+6668,33,126},{
+__jisx0208_decmap+6762,33,126},{__jisx0208_decmap+6856,33,126},{
+__jisx0208_decmap+6950,33,38},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
+{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
+};
+
+static const ucs2_t __jisx0212_decmap[6179] = {
+728,711,184,729,733,175,731,730,126,900,901,U,U,U,U,U,U,U,U,161,166,191,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,186,170,
+169,174,8482,164,8470,902,904,905,906,938,U,908,U,910,939,U,911,U,U,U,U,940,
+941,942,943,970,912,972,962,973,971,944,974,1026,1027,1028,1029,1030,1031,
+1032,1033,1034,1035,1036,1038,1039,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,1106,1107,1108,1109,1110,1111,1112,1113,1114,1115,
+1116,1118,1119,198,272,U,294,U,306,U,321,319,U,330,216,338,U,358,222,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,230,273,240,295,305,307,312,322,320,329,331,248,339,
+223,359,254,193,192,196,194,258,461,256,260,197,195,262,264,268,199,266,270,
+201,200,203,202,282,278,274,280,U,284,286,290,288,292,205,204,207,206,463,304,
+298,302,296,308,310,313,317,315,323,327,325,209,211,210,214,212,465,336,332,
+213,340,344,342,346,348,352,350,356,354,218,217,220,219,364,467,368,362,370,
+366,360,471,475,473,469,372,221,376,374,377,381,379,225,224,228,226,259,462,
+257,261,229,227,263,265,269,231,267,271,233,232,235,234,283,279,275,281,501,
+285,287,U,289,293,237,236,239,238,464,U,299,303,297,309,311,314,318,316,324,
+328,326,241,243,242,246,244,466,337,333,245,341,345,343,347,349,353,351,357,
+355,250,249,252,251,365,468,369,363,371,367,361,472,476,474,470,373,253,255,
+375,378,382,380,19970,19972,19973,19980,19986,19999,20003,20004,20008,20011,
+20014,20015,20016,20021,20032,20033,20036,20039,20049,20058,20060,20067,20072,
+20073,20084,20085,20089,20095,20109,20118,20119,20125,20143,20153,20163,20176,
+20186,20187,20192,20193,20194,20200,20207,20209,20211,20213,20221,20222,20223,
+20224,20226,20227,20232,20235,20236,20242,20245,20246,20247,20249,20270,20273,
+20320,20275,20277,20279,20281,20283,20286,20288,20290,20296,20297,20299,20300,
+20306,20308,20310,20312,20319,20323,20330,20332,20334,20337,20343,20344,20345,
+20346,20349,20350,20353,20354,20356,20357,20361,20362,20364,20366,20368,20370,
+20371,20372,20375,20377,20378,20382,20383,20402,20407,20409,20411,20412,20413,
+20414,20416,20417,20421,20422,20424,20425,20427,20428,20429,20431,20434,20444,
+20448,20450,20464,20466,20476,20477,20479,20480,20481,20484,20487,20490,20492,
+20494,20496,20499,20503,20504,20507,20508,20509,20510,20514,20519,20526,20528,
+20530,20531,20533,20544,20545,20546,20549,20550,20554,20556,20558,20561,20562,
+20563,20567,20569,20575,20576,20578,20579,20582,20583,20586,20589,20592,20593,
+20539,20609,20611,20612,20614,20618,20622,20623,20624,20626,20627,20628,20630,
+20635,20636,20638,20639,20640,20641,20642,20650,20655,20656,20665,20666,20669,
+20672,20675,20676,20679,20684,20686,20688,20691,20692,20696,20700,20701,20703,
+20706,20708,20710,20712,20713,20719,20721,20726,20730,20734,20739,20742,20743,
+20744,20747,20748,20749,20750,20722,20752,20759,20761,20763,20764,20765,20766,
+20771,20775,20776,20780,20781,20783,20785,20787,20788,20789,20792,20793,20802,
+20810,20815,20819,20821,20823,20824,20831,20836,20838,20862,20867,20868,20875,
+20878,20888,20893,20897,20899,20909,20920,20922,20924,20926,20927,20930,20936,
+20943,20945,20946,20947,20949,20952,20958,20962,20965,20974,20978,20979,20980,
+20983,20993,20994,20997,21010,21011,21013,21014,21016,21026,21032,21041,21042,
+21045,21052,21061,21065,21077,21079,21080,21082,21084,21087,21088,21089,21094,
+21102,21111,21112,21113,21120,21122,21125,21130,21132,21139,21141,21142,21143,
+21144,21146,21148,21156,21157,21158,21159,21167,21168,21174,21175,21176,21178,
+21179,21181,21184,21188,21190,21192,21196,21199,21201,21204,21206,21211,21212,
+21217,21221,21224,21225,21226,21228,21232,21233,21236,21238,21239,21248,21251,
+21258,21259,21260,21265,21267,21272,21275,21276,21278,21279,21285,21287,21288,
+21289,21291,21292,21293,21296,21298,21301,21308,21309,21310,21314,21324,21323,
+21337,21339,21345,21347,21349,21356,21357,21362,21369,21374,21379,21383,21384,
+21390,21395,21396,21401,21405,21409,21412,21418,21419,21423,21426,21428,21429,
+21431,21432,21434,21437,21440,21445,21455,21458,21459,21461,21466,21469,21470,
+21472,21478,21479,21493,21506,21523,21530,21537,21543,21544,21546,21551,21553,
+21556,21557,21571,21572,21575,21581,21583,21598,21602,21604,21606,21607,21609,
+21611,21613,21614,21620,21631,21633,21635,21637,21640,21641,21645,21649,21653,
+21654,21660,21663,21665,21670,21671,21673,21674,21677,21678,21681,21687,21689,
+21690,21691,21695,21702,21706,21709,21710,21728,21738,21740,21743,21750,21756,
+21758,21759,21760,21761,21765,21768,21769,21772,21773,21774,21781,21802,21803,
+21810,21813,21814,21819,21820,21821,21825,21831,21833,21834,21837,21840,21841,
+21848,21850,21851,21854,21856,21857,21860,21862,21887,21889,21890,21894,21896,
+21902,21903,21905,21906,21907,21908,21911,21923,21924,21933,21938,21951,21953,
+21955,21958,21961,21963,21964,21966,21969,21970,21971,21975,21976,21979,21982,
+21986,21993,22006,22015,22021,22024,22026,22029,22030,22031,22032,22033,22034,
+22041,22060,22064,22067,22069,22071,22073,22075,22076,22077,22079,22080,22081,
+22083,22084,22086,22089,22091,22093,22095,22100,22110,22112,22113,22114,22115,
+22118,22121,22125,22127,22129,22130,22133,22148,22149,22152,22155,22156,22165,
+22169,22170,22173,22174,22175,22182,22183,22184,22185,22187,22188,22189,22193,
+22195,22199,22206,22213,22217,22218,22219,22223,22224,22220,22221,22233,22236,
+22237,22239,22241,22244,22245,22246,22247,22248,22257,22251,22253,22262,22263,
+22273,22274,22279,22282,22284,22289,22293,22298,22299,22301,22304,22306,22307,
+22308,22309,22313,22314,22316,22318,22319,22323,22324,22333,22334,22335,22341,
+22342,22348,22349,22354,22370,22373,22375,22376,22379,22381,22382,22383,22384,
+22385,22387,22388,22389,22391,22393,22394,22395,22396,22398,22401,22403,22412,
+22420,22423,22425,22426,22428,22429,22430,22431,22433,22421,22439,22440,22441,
+22444,22456,22461,22471,22472,22476,22479,22485,22493,22494,22500,22502,22503,
+22505,22509,22512,22517,22518,22520,22525,22526,22527,22531,22532,22536,22537,
+22497,22540,22541,22555,22558,22559,22560,22566,22567,22573,22578,22585,22591,
+22601,22604,22605,22607,22608,22613,22623,22625,22628,22631,22632,22648,22652,
+22655,22656,22657,22663,22664,22665,22666,22668,22669,22671,22672,22676,22678,
+22685,22688,22689,22690,22694,22697,22705,22706,22724,22716,22722,22728,22733,
+22734,22736,22738,22740,22742,22746,22749,22753,22754,22761,22771,22789,22790,
+22795,22796,22802,22803,22804,34369,22813,22817,22819,22820,22824,22831,22832,
+22835,22837,22838,22847,22851,22854,22866,22867,22873,22875,22877,22878,22879,
+22881,22883,22891,22893,22895,22898,22901,22902,22905,22907,22908,22923,22924,
+22926,22930,22933,22935,22943,22948,22951,22957,22958,22959,22960,22963,22967,
+22970,22972,22977,22979,22980,22984,22986,22989,22994,23005,23006,23007,23011,
+23012,23015,23022,23023,23025,23026,23028,23031,23040,23044,23052,23053,23054,
+23058,23059,23070,23075,23076,23079,23080,23082,23085,23088,23108,23109,23111,
+23112,23116,23120,23125,23134,23139,23141,23143,23149,23159,23162,23163,23166,
+23179,23184,23187,23190,23193,23196,23198,23199,23200,23202,23207,23212,23217,
+23218,23219,23221,23224,23226,23227,23231,23236,23238,23240,23247,23258,23260,
+23264,23269,23274,23278,23285,23286,23293,23296,23297,23304,23319,23348,23321,
+23323,23325,23329,23333,23341,23352,23361,23371,23372,23378,23382,23390,23400,
+23406,23407,23420,23421,23422,23423,23425,23428,23430,23434,23438,23440,23441,
+23443,23444,23446,23464,23465,23468,23469,23471,23473,23474,23479,23482,23484,
+23488,23489,23501,23503,23510,23511,23512,23513,23514,23520,23535,23537,23540,
+23549,23564,23575,23582,23583,23587,23590,23593,23595,23596,23598,23600,23602,
+23605,23606,23641,23642,23644,23650,23651,23655,23656,23657,23661,23664,23668,
+23669,23674,23675,23676,23677,23687,23688,23690,23695,23698,23709,23711,23712,
+23714,23715,23718,23722,23730,23732,23733,23738,23753,23755,23762,23773,23767,
+23790,23793,23794,23796,23809,23814,23821,23826,23851,23843,23844,23846,23847,
+23857,23860,23865,23869,23871,23874,23875,23878,23880,23893,23889,23897,23882,
+23903,23904,23905,23906,23908,23914,23917,23920,23929,23930,23934,23935,23937,
+23939,23944,23946,23954,23955,23956,23957,23961,23963,23967,23968,23975,23979,
+23984,23988,23992,23993,24003,24007,24011,24016,24014,24024,24025,24032,24036,
+24041,24056,24057,24064,24071,24077,24082,24084,24085,24088,24095,24096,24110,
+24104,24114,24117,24126,24139,24144,24137,24145,24150,24152,24155,24156,24158,
+24168,24170,24171,24172,24173,24174,24176,24192,24203,24206,24226,24228,24229,
+24232,24234,24236,24241,24243,24253,24254,24255,24262,24268,24267,24270,24273,
+24274,24276,24277,24284,24286,24293,24299,24322,24326,24327,24328,24334,24345,
+24348,24349,24353,24354,24355,24356,24360,24363,24364,24366,24368,24372,24374,
+24379,24381,24383,24384,24388,24389,24391,24397,24400,24404,24408,24411,24416,
+24419,24420,24423,24431,24434,24436,24437,24440,24442,24445,24446,24457,24461,
+24463,24470,24476,24477,24482,24487,24491,24484,24492,24495,24496,24497,24504,
+24516,24519,24520,24521,24523,24528,24529,24530,24531,24532,24542,24545,24546,
+24552,24553,24554,24556,24557,24558,24559,24562,24563,24566,24570,24572,24583,
+24586,24589,24595,24596,24599,24600,24602,24607,24612,24621,24627,24629,24640,
+24647,24648,24649,24652,24657,24660,24662,24663,24669,24673,24679,24689,24702,
+24703,24706,24710,24712,24714,24718,24721,24723,24725,24728,24733,24734,24738,
+24740,24741,24744,24752,24753,24759,24763,24766,24770,24772,24776,24777,24778,
+24779,24782,24783,24788,24789,24793,24795,24797,24798,24802,24805,24818,24821,
+24824,24828,24829,24834,24839,24842,24844,24848,24849,24850,24851,24852,24854,
+24855,24857,24860,24862,24866,24874,24875,24880,24881,24885,24886,24887,24889,
+24897,24901,24902,24905,24926,24928,24940,24946,24952,24955,24956,24959,24960,
+24961,24963,24964,24971,24973,24978,24979,24983,24984,24988,24989,24991,24992,
+24997,25000,25002,25005,25016,25017,25020,25024,25025,25026,25038,25039,25045,
+25052,25053,25054,25055,25057,25058,25063,25065,25061,25068,25069,25071,25089,
+25091,25092,25095,25107,25109,25116,25120,25122,25123,25127,25129,25131,25145,
+25149,25154,25155,25156,25158,25164,25168,25169,25170,25172,25174,25178,25180,
+25188,25197,25199,25203,25210,25213,25229,25230,25231,25232,25254,25256,25267,
+25270,25271,25274,25278,25279,25284,25294,25301,25302,25306,25322,25330,25332,
+25340,25341,25347,25348,25354,25355,25357,25360,25363,25366,25368,25385,25386,
+25389,25397,25398,25401,25404,25409,25410,25411,25412,25414,25418,25419,25422,
+25426,25427,25428,25432,25435,25445,25446,25452,25453,25457,25460,25461,25464,
+25468,25469,25471,25474,25476,25479,25482,25488,25492,25493,25497,25498,25502,
+25508,25510,25517,25518,25519,25533,25537,25541,25544,25550,25553,25555,25556,
+25557,25564,25568,25573,25578,25580,25586,25587,25589,25592,25593,25609,25610,
+25616,25618,25620,25624,25630,25632,25634,25636,25637,25641,25642,25647,25648,
+25653,25661,25663,25675,25679,25681,25682,25683,25684,25690,25691,25692,25693,
+25695,25696,25697,25699,25709,25715,25716,25723,25725,25733,25735,25743,25744,
+25745,25752,25753,25755,25757,25759,25761,25763,25766,25768,25772,25779,25789,
+25790,25791,25796,25801,25802,25803,25804,25806,25808,25809,25813,25815,25828,
+25829,25833,25834,25837,25840,25845,25847,25851,25855,25857,25860,25864,25865,
+25866,25871,25875,25876,25878,25881,25883,25886,25887,25890,25894,25897,25902,
+25905,25914,25916,25917,25923,25927,25929,25936,25938,25940,25951,25952,25959,
+25963,25978,25981,25985,25989,25994,26002,26005,26008,26013,26016,26019,26022,
+26030,26034,26035,26036,26047,26050,26056,26057,26062,26064,26068,26070,26072,
+26079,26096,26098,26100,26101,26105,26110,26111,26112,26116,26120,26121,26125,
+26129,26130,26133,26134,26141,26142,26145,26146,26147,26148,26150,26153,26154,
+26155,26156,26158,26160,26161,26163,26169,26167,26176,26181,26182,26186,26188,
+26193,26190,26199,26200,26201,26203,26204,26208,26209,26363,26218,26219,26220,
+26238,26227,26229,26239,26231,26232,26233,26235,26240,26236,26251,26252,26253,
+26256,26258,26265,26266,26267,26268,26271,26272,26276,26285,26289,26290,26293,
+26299,26303,26304,26306,26307,26312,26316,26318,26319,26324,26331,26335,26344,
+26347,26348,26350,26362,26373,26375,26382,26387,26393,26396,26400,26402,26419,
+26430,26437,26439,26440,26444,26452,26453,26461,26470,26476,26478,26484,26486,
+26491,26497,26500,26510,26511,26513,26515,26518,26520,26521,26523,26544,26545,
+26546,26549,26555,26556,26557,26617,26560,26562,26563,26565,26568,26569,26578,
+26583,26585,26588,26593,26598,26608,26610,26614,26615,26706,26644,26649,26653,
+26655,26664,26663,26668,26669,26671,26672,26673,26675,26683,26687,26692,26693,
+26698,26700,26709,26711,26712,26715,26731,26734,26735,26736,26737,26738,26741,
+26745,26746,26747,26748,26754,26756,26758,26760,26774,26776,26778,26780,26785,
+26787,26789,26793,26794,26798,26802,26811,26821,26824,26828,26831,26832,26833,
+26835,26838,26841,26844,26845,26853,26856,26858,26859,26860,26861,26864,26865,
+26869,26870,26875,26876,26877,26886,26889,26890,26896,26897,26899,26902,26903,
+26929,26931,26933,26936,26939,26946,26949,26953,26958,26967,26971,26979,26980,
+26981,26982,26984,26985,26988,26992,26993,26994,27002,27003,27007,27008,27021,
+27026,27030,27032,27041,27045,27046,27048,27051,27053,27055,27063,27064,27066,
+27068,27077,27080,27089,27094,27095,27106,27109,27118,27119,27121,27123,27125,
+27134,27136,27137,27139,27151,27153,27157,27162,27165,27168,27172,27176,27184,
+27186,27188,27191,27195,27198,27199,27205,27206,27209,27210,27214,27216,27217,
+27218,27221,27222,27227,27236,27239,27242,27249,27251,27262,27265,27267,27270,
+27271,27273,27275,27281,27291,27293,27294,27295,27301,27307,27311,27312,27313,
+27316,27325,27326,27327,27334,27337,27336,27340,27344,27348,27349,27350,27356,
+27357,27364,27367,27372,27376,27377,27378,27388,27389,27394,27395,27398,27399,
+27401,27407,27408,27409,27415,27419,27422,27428,27432,27435,27436,27439,27445,
+27446,27451,27455,27462,27466,27469,27474,27478,27480,27485,27488,27495,27499,
+27502,27504,27509,27517,27518,27522,27525,27543,27547,27551,27552,27554,27555,
+27560,27561,27564,27565,27566,27568,27576,27577,27581,27582,27587,27588,27593,
+27596,27606,27610,27617,27619,27622,27623,27630,27633,27639,27641,27647,27650,
+27652,27653,27657,27661,27662,27664,27666,27673,27679,27686,27687,27688,27692,
+27694,27699,27701,27702,27706,27707,27711,27722,27723,27725,27727,27730,27732,
+27737,27739,27740,27755,27757,27759,27764,27766,27768,27769,27771,27781,27782,
+27783,27785,27796,27797,27799,27800,27804,27807,27824,27826,27828,27842,27846,
+27853,27855,27856,27857,27858,27860,27862,27866,27868,27872,27879,27881,27883,
+27884,27886,27890,27892,27908,27911,27914,27918,27919,27921,27923,27930,27942,
+27943,27944,27751,27950,27951,27953,27961,27964,27967,27991,27998,27999,28001,
+28005,28007,28015,28016,28028,28034,28039,28049,28050,28052,28054,28055,28056,
+28074,28076,28084,28087,28089,28093,28095,28100,28104,28106,28110,28111,28118,
+28123,28125,28127,28128,28130,28133,28137,28143,28144,28148,28150,28156,28160,
+28164,28190,28194,28199,28210,28214,28217,28219,28220,28228,28229,28232,28233,
+28235,28239,28241,28242,28243,28244,28247,28252,28253,28254,28258,28259,28264,
+28275,28283,28285,28301,28307,28313,28320,28327,28333,28334,28337,28339,28347,
+28351,28352,28353,28355,28359,28360,28362,28365,28366,28367,28395,28397,28398,
+28409,28411,28413,28420,28424,28426,28428,28429,28438,28440,28442,28443,28454,
+28457,28458,28463,28464,28467,28470,28475,28476,28461,28495,28497,28498,28499,
+28503,28505,28506,28509,28510,28513,28514,28520,28524,28541,28542,28547,28551,
+28552,28555,28556,28557,28560,28562,28563,28564,28566,28570,28575,28576,28581,
+28582,28583,28584,28590,28591,28592,28597,28598,28604,28613,28615,28616,28618,
+28634,28638,28648,28649,28656,28661,28665,28668,28669,28672,28677,28678,28679,
+28685,28695,28704,28707,28719,28724,28727,28729,28732,28739,28740,28744,28745,
+28746,28747,28756,28757,28765,28766,28750,28772,28773,28780,28782,28789,28790,
+28798,28801,28805,28806,28820,28821,28822,28823,28824,28827,28836,28843,28848,
+28849,28852,28855,28874,28881,28883,28884,28885,28886,28888,28892,28900,28922,
+28931,28932,28933,28934,28935,28939,28940,28943,28958,28960,28971,28973,28975,
+28976,28977,28984,28993,28997,28998,28999,29002,29003,29008,29010,29015,29018,
+29020,29022,29024,29032,29049,29056,29061,29063,29068,29074,29082,29083,29088,
+29090,29103,29104,29106,29107,29114,29119,29120,29121,29124,29131,29132,29139,
+29142,29145,29146,29148,29176,29182,29184,29191,29192,29193,29203,29207,29210,
+29213,29215,29220,29227,29231,29236,29240,29241,29249,29250,29251,29253,29262,
+29263,29264,29267,29269,29270,29274,29276,29278,29280,29283,29288,29291,29294,
+29295,29297,29303,29304,29307,29308,29311,29316,29321,29325,29326,29331,29339,
+29352,29357,29358,29361,29364,29374,29377,29383,29385,29388,29397,29398,29400,
+29407,29413,29427,29428,29434,29435,29438,29442,29444,29445,29447,29451,29453,
+29458,29459,29464,29465,29470,29474,29476,29479,29480,29484,29489,29490,29493,
+29498,29499,29501,29507,29517,29520,29522,29526,29528,29533,29534,29535,29536,
+29542,29543,29545,29547,29548,29550,29551,29553,29559,29561,29564,29568,29569,
+29571,29573,29574,29582,29584,29587,29589,29591,29592,29596,29598,29599,29600,
+29602,29605,29606,29610,29611,29613,29621,29623,29625,29628,29629,29631,29637,
+29638,29641,29643,29644,29647,29650,29651,29654,29657,29661,29665,29667,29670,
+29671,29673,29684,29685,29687,29689,29690,29691,29693,29695,29696,29697,29700,
+29703,29706,29713,29722,29723,29732,29734,29736,29737,29738,29739,29740,29741,
+29742,29743,29744,29745,29753,29760,29763,29764,29766,29767,29771,29773,29777,
+29778,29783,29789,29794,29798,29799,29800,29803,29805,29806,29809,29810,29824,
+29825,29829,29830,29831,29833,29839,29840,29841,29842,29848,29849,29850,29852,
+29855,29856,29857,29859,29862,29864,29865,29866,29867,29870,29871,29873,29874,
+29877,29881,29883,29887,29896,29897,29900,29904,29907,29912,29914,29915,29918,
+29919,29924,29928,29930,29931,29935,29940,29946,29947,29948,29951,29958,29970,
+29974,29975,29984,29985,29988,29991,29993,29994,29999,30006,30009,30013,30014,
+30015,30016,30019,30023,30024,30030,30032,30034,30039,30046,30047,30049,30063,
+30065,30073,30074,30075,30076,30077,30078,30081,30085,30096,30098,30099,30101,
+30105,30108,30114,30116,30132,30138,30143,30144,30145,30148,30150,30156,30158,
+30159,30167,30172,30175,30176,30177,30180,30183,30188,30190,30191,30193,30201,
+30208,30210,30211,30212,30215,30216,30218,30220,30223,30226,30227,30229,30230,
+30233,30235,30236,30237,30238,30243,30245,30246,30249,30253,30258,30259,30261,
+30264,30265,30266,30268,30282,30272,30273,30275,30276,30277,30281,30283,30293,
+30297,30303,30308,30309,30317,30318,30319,30321,30324,30337,30341,30348,30349,
+30357,30363,30364,30365,30367,30368,30370,30371,30372,30373,30374,30375,30376,
+30378,30381,30397,30401,30405,30409,30411,30412,30414,30420,30425,30432,30438,
+30440,30444,30448,30449,30454,30457,30460,30464,30470,30474,30478,30482,30484,
+30485,30487,30489,30490,30492,30498,30504,30509,30510,30511,30516,30517,30518,
+30521,30525,30526,30530,30533,30534,30538,30541,30542,30543,30546,30550,30551,
+30556,30558,30559,30560,30562,30564,30567,30570,30572,30576,30578,30579,30580,
+30586,30589,30592,30596,30604,30605,30612,30613,30614,30618,30623,30626,30631,
+30634,30638,30639,30641,30645,30654,30659,30665,30673,30674,30677,30681,30686,
+30687,30688,30692,30694,30698,30700,30704,30705,30708,30712,30715,30725,30726,
+30729,30733,30734,30737,30749,30753,30754,30755,30765,30766,30768,30773,30775,
+30787,30788,30791,30792,30796,30798,30802,30812,30814,30816,30817,30819,30820,
+30824,30826,30830,30842,30846,30858,30863,30868,30872,30881,30877,30878,30879,
+30884,30888,30892,30893,30896,30897,30898,30899,30907,30909,30911,30919,30920,
+30921,30924,30926,30930,30931,30933,30934,30948,30939,30943,30944,30945,30950,
+30954,30962,30963,30976,30966,30967,30970,30971,30975,30982,30988,30992,31002,
+31004,31006,31007,31008,31013,31015,31017,31021,31025,31028,31029,31035,31037,
+31039,31044,31045,31046,31050,31051,31055,31057,31060,31064,31067,31068,31079,
+31081,31083,31090,31097,31099,31100,31102,31115,31116,31121,31123,31124,31125,
+31126,31128,31131,31132,31137,31144,31145,31147,31151,31153,31156,31160,31163,
+31170,31172,31175,31176,31178,31183,31188,31190,31194,31197,31198,31200,31202,
+31205,31210,31211,31213,31217,31224,31228,31234,31235,31239,31241,31242,31244,
+31249,31253,31259,31262,31265,31271,31275,31277,31279,31280,31284,31285,31288,
+31289,31290,31300,31301,31303,31304,31308,31317,31318,31321,31324,31325,31327,
+31328,31333,31335,31338,31341,31349,31352,31358,31360,31362,31365,31366,31370,
+31371,31376,31377,31380,31390,31392,31395,31404,31411,31413,31417,31419,31420,
+31430,31433,31436,31438,31441,31451,31464,31465,31467,31468,31473,31476,31483,
+31485,31486,31495,31508,31519,31523,31527,31529,31530,31531,31533,31534,31535,
+31536,31537,31540,31549,31551,31552,31553,31559,31566,31573,31584,31588,31590,
+31593,31594,31597,31599,31602,31603,31607,31620,31625,31630,31632,31633,31638,
+31643,31646,31648,31653,31660,31663,31664,31666,31669,31670,31674,31675,31676,
+31677,31682,31685,31688,31690,31700,31702,31703,31705,31706,31707,31720,31722,
+31730,31732,31733,31736,31737,31738,31740,31742,31745,31746,31747,31748,31750,
+31753,31755,31756,31758,31759,31769,31771,31776,31781,31782,31784,31788,31793,
+31795,31796,31798,31801,31802,31814,31818,31829,31825,31826,31827,31833,31834,
+31835,31836,31837,31838,31841,31843,31847,31849,31853,31854,31856,31858,31865,
+31868,31869,31878,31879,31887,31892,31902,31904,31910,31920,31926,31927,31930,
+31931,31932,31935,31940,31943,31944,31945,31949,31951,31955,31956,31957,31959,
+31961,31962,31965,31974,31977,31979,31989,32003,32007,32008,32009,32015,32017,
+32018,32019,32022,32029,32030,32035,32038,32042,32045,32049,32060,32061,32062,
+32064,32065,32071,32072,32077,32081,32083,32087,32089,32090,32092,32093,32101,
+32103,32106,32112,32120,32122,32123,32127,32129,32130,32131,32133,32134,32136,
+32139,32140,32141,32145,32150,32151,32157,32158,32166,32167,32170,32179,32182,
+32183,32185,32194,32195,32196,32197,32198,32204,32205,32206,32215,32217,32256,
+32226,32229,32230,32234,32235,32237,32241,32245,32246,32249,32250,32264,32272,
+32273,32277,32279,32284,32285,32288,32295,32296,32300,32301,32303,32307,32310,
+32319,32324,32325,32327,32334,32336,32338,32344,32351,32353,32354,32357,32363,
+32366,32367,32371,32376,32382,32385,32390,32391,32394,32397,32401,32405,32408,
+32410,32413,32414,32572,32571,32573,32574,32575,32579,32580,32583,32591,32594,
+32595,32603,32604,32605,32609,32611,32612,32613,32614,32621,32625,32637,32638,
+32639,32640,32651,32653,32655,32656,32657,32662,32663,32668,32673,32674,32678,
+32682,32685,32692,32700,32703,32704,32707,32712,32718,32719,32731,32735,32739,
+32741,32744,32748,32750,32751,32754,32762,32765,32766,32767,32775,32776,32778,
+32781,32782,32783,32785,32787,32788,32790,32797,32798,32799,32800,32804,32806,
+32812,32814,32816,32820,32821,32823,32825,32826,32828,32830,32832,32836,32864,
+32868,32870,32877,32881,32885,32897,32904,32910,32924,32926,32934,32935,32939,
+32952,32953,32968,32973,32975,32978,32980,32981,32983,32984,32992,33005,33006,
+33008,33010,33011,33014,33017,33018,33022,33027,33035,33046,33047,33048,33052,
+33054,33056,33060,33063,33068,33072,33077,33082,33084,33093,33095,33098,33100,
+33106,33111,33120,33121,33127,33128,33129,33133,33135,33143,33153,33168,33156,
+33157,33158,33163,33166,33174,33176,33179,33182,33186,33198,33202,33204,33211,
+33227,33219,33221,33226,33230,33231,33237,33239,33243,33245,33246,33249,33252,
+33259,33260,33264,33265,33266,33269,33270,33272,33273,33277,33279,33280,33283,
+33295,33299,33300,33305,33306,33309,33313,33314,33320,33330,33332,33338,33347,
+33348,33349,33350,33355,33358,33359,33361,33366,33372,33376,33379,33383,33389,
+33396,33403,33405,33407,33408,33409,33411,33412,33415,33417,33418,33422,33425,
+33428,33430,33432,33434,33435,33440,33441,33443,33444,33447,33448,33449,33450,
+33454,33456,33458,33460,33463,33466,33468,33470,33471,33478,33488,33493,33498,
+33504,33506,33508,33512,33514,33517,33519,33526,33527,33533,33534,33536,33537,
+33543,33544,33546,33547,33620,33563,33565,33566,33567,33569,33570,33580,33581,
+33582,33584,33587,33591,33594,33596,33597,33602,33603,33604,33607,33613,33614,
+33617,33621,33622,33623,33648,33656,33661,33663,33664,33666,33668,33670,33677,
+33682,33684,33685,33688,33689,33691,33692,33693,33702,33703,33705,33708,33726,
+33727,33728,33735,33737,33743,33744,33745,33748,33757,33619,33768,33770,33782,
+33784,33785,33788,33793,33798,33802,33807,33809,33813,33817,33709,33839,33849,
+33861,33863,33864,33866,33869,33871,33873,33874,33878,33880,33881,33882,33884,
+33888,33892,33893,33895,33898,33904,33907,33908,33910,33912,33916,33917,33921,
+33925,33938,33939,33941,33950,33958,33960,33961,33962,33967,33969,33972,33978,
+33981,33982,33984,33986,33991,33992,33996,33999,34003,34012,34023,34026,34031,
+34032,34033,34034,34039,34098,34042,34043,34045,34050,34051,34055,34060,34062,
+34064,34076,34078,34082,34083,34084,34085,34087,34090,34091,34095,34099,34100,
+34102,34111,34118,34127,34128,34129,34130,34131,34134,34137,34140,34141,34142,
+34143,34144,34145,34146,34148,34155,34159,34169,34170,34171,34173,34175,34177,
+34181,34182,34185,34187,34188,34191,34195,34200,34205,34207,34208,34210,34213,
+34215,34228,34230,34231,34232,34236,34237,34238,34239,34242,34247,34250,34251,
+34254,34221,34264,34266,34271,34272,34278,34280,34285,34291,34294,34300,34303,
+34304,34308,34309,34317,34318,34320,34321,34322,34328,34329,34331,34334,34337,
+34343,34345,34358,34360,34362,34364,34365,34368,34370,34374,34386,34387,34390,
+34391,34392,34393,34397,34400,34401,34402,34403,34404,34409,34412,34415,34421,
+34422,34423,34426,34445,34449,34454,34456,34458,34460,34465,34470,34471,34472,
+34477,34481,34483,34484,34485,34487,34488,34489,34495,34496,34497,34499,34501,
+34513,34514,34517,34519,34522,34524,34528,34531,34533,34535,34440,34554,34556,
+34557,34564,34565,34567,34571,34574,34575,34576,34579,34580,34585,34590,34591,
+34593,34595,34600,34606,34607,34609,34610,34617,34618,34620,34621,34622,34624,
+34627,34629,34637,34648,34653,34657,34660,34661,34671,34673,34674,34683,34691,
+34692,34693,34694,34695,34696,34697,34699,34700,34704,34707,34709,34711,34712,
+34713,34718,34720,34723,34727,34732,34733,34734,34737,34741,34750,34751,34753,
+34760,34761,34762,34766,34773,34774,34777,34778,34780,34783,34786,34787,34788,
+34794,34795,34797,34801,34803,34808,34810,34815,34817,34819,34822,34825,34826,
+34827,34832,34841,34834,34835,34836,34840,34842,34843,34844,34846,34847,34856,
+34861,34862,34864,34866,34869,34874,34876,34881,34883,34885,34888,34889,34890,
+34891,34894,34897,34901,34902,34904,34906,34908,34911,34912,34916,34921,34929,
+34937,34939,34944,34968,34970,34971,34972,34975,34976,34984,34986,35002,35005,
+35006,35008,35018,35019,35020,35021,35022,35025,35026,35027,35035,35038,35047,
+35055,35056,35057,35061,35063,35073,35078,35085,35086,35087,35093,35094,35096,
+35097,35098,35100,35104,35110,35111,35112,35120,35121,35122,35125,35129,35130,
+35134,35136,35138,35141,35142,35145,35151,35154,35159,35162,35163,35164,35169,
+35170,35171,35179,35182,35184,35187,35189,35194,35195,35196,35197,35209,35213,
+35216,35220,35221,35227,35228,35231,35232,35237,35248,35252,35253,35254,35255,
+35260,35284,35285,35286,35287,35288,35301,35305,35307,35309,35313,35315,35318,
+35321,35325,35327,35332,35333,35335,35343,35345,35346,35348,35349,35358,35360,
+35362,35364,35366,35371,35372,35375,35381,35383,35389,35390,35392,35395,35397,
+35399,35401,35405,35406,35411,35414,35415,35416,35420,35421,35425,35429,35431,
+35445,35446,35447,35449,35450,35451,35454,35455,35456,35459,35462,35467,35471,
+35472,35474,35478,35479,35481,35487,35495,35497,35502,35503,35507,35510,35511,
+35515,35518,35523,35526,35528,35529,35530,35537,35539,35540,35541,35543,35549,
+35551,35564,35568,35572,35573,35574,35580,35583,35589,35590,35595,35601,35612,
+35614,35615,35594,35629,35632,35639,35644,35650,35651,35652,35653,35654,35656,
+35666,35667,35668,35673,35661,35678,35683,35693,35702,35704,35705,35708,35710,
+35713,35716,35717,35723,35725,35727,35732,35733,35740,35742,35743,35896,35897,
+35901,35902,35909,35911,35913,35915,35919,35921,35923,35924,35927,35928,35931,
+35933,35929,35939,35940,35942,35944,35945,35949,35955,35957,35958,35963,35966,
+35974,35975,35979,35984,35986,35987,35993,35995,35996,36004,36025,36026,36037,
+36038,36041,36043,36047,36054,36053,36057,36061,36065,36072,36076,36079,36080,
+36082,36085,36087,36088,36094,36095,36097,36099,36105,36114,36119,36123,36197,
+36201,36204,36206,36223,36226,36228,36232,36237,36240,36241,36245,36254,36255,
+36256,36262,36267,36268,36271,36274,36277,36279,36281,36283,36288,36293,36294,
+36295,36296,36298,36302,36305,36308,36309,36311,36313,36324,36325,36327,36332,
+36336,36284,36337,36338,36340,36349,36353,36356,36357,36358,36363,36369,36372,
+36374,36384,36385,36386,36387,36390,36391,36401,36403,36406,36407,36408,36409,
+36413,36416,36417,36427,36429,36430,36431,36436,36443,36444,36445,36446,36449,
+36450,36457,36460,36461,36463,36464,36465,36473,36474,36475,36482,36483,36489,
+36496,36498,36501,36506,36507,36509,36510,36514,36519,36521,36525,36526,36531,
+36533,36538,36539,36544,36545,36547,36548,36551,36559,36561,36564,36572,36584,
+36590,36592,36593,36599,36601,36602,36589,36608,36610,36615,36616,36623,36624,
+36630,36631,36632,36638,36640,36641,36643,36645,36647,36648,36652,36653,36654,
+36660,36661,36662,36663,36666,36672,36673,36675,36679,36687,36689,36690,36691,
+36692,36693,36696,36701,36702,36709,36765,36768,36769,36772,36773,36774,36789,
+36790,36792,36798,36800,36801,36806,36810,36811,36813,36816,36818,36819,36821,
+36832,36835,36836,36840,36846,36849,36853,36854,36859,36862,36866,36868,36872,
+36876,36888,36891,36904,36905,36911,36906,36908,36909,36915,36916,36919,36927,
+36931,36932,36940,36955,36957,36962,36966,36967,36972,36976,36980,36985,36997,
+37000,37003,37004,37006,37008,37013,37015,37016,37017,37019,37024,37025,37026,
+37029,37040,37042,37043,37044,37046,37053,37068,37054,37059,37060,37061,37063,
+37064,37077,37079,37080,37081,37084,37085,37087,37093,37074,37110,37099,37103,
+37104,37108,37118,37119,37120,37124,37125,37126,37128,37133,37136,37140,37142,
+37143,37144,37146,37148,37150,37152,37157,37154,37155,37159,37161,37166,37167,
+37169,37172,37174,37175,37177,37178,37180,37181,37187,37191,37192,37199,37203,
+37207,37209,37210,37211,37217,37220,37223,37229,37236,37241,37242,37243,37249,
+37251,37253,37254,37258,37262,37265,37267,37268,37269,37272,37278,37281,37286,
+37288,37292,37293,37294,37296,37297,37298,37299,37302,37307,37308,37309,37311,
+37314,37315,37317,37331,37332,37335,37337,37338,37342,37348,37349,37353,37354,
+37356,37357,37358,37359,37360,37361,37367,37369,37371,37373,37376,37377,37380,
+37381,37382,37383,37385,37386,37388,37392,37394,37395,37398,37400,37404,37405,
+37411,37412,37413,37414,37416,37422,37423,37424,37427,37429,37430,37432,37433,
+37434,37436,37438,37440,37442,37443,37446,37447,37450,37453,37454,37455,37457,
+37464,37465,37468,37469,37472,37473,37477,37479,37480,37481,37486,37487,37488,
+37493,37494,37495,37496,37497,37499,37500,37501,37503,37512,37513,37514,37517,
+37518,37522,37527,37529,37535,37536,37540,37541,37543,37544,37547,37551,37554,
+37558,37560,37562,37563,37564,37565,37567,37568,37569,37570,37571,37573,37574,
+37575,37576,37579,37580,37581,37582,37584,37587,37589,37591,37592,37593,37596,
+37597,37599,37600,37601,37603,37605,37607,37608,37612,37614,37616,37625,37627,
+37631,37632,37634,37640,37645,37649,37652,37653,37660,37661,37662,37663,37665,
+37668,37669,37671,37673,37674,37683,37684,37686,37687,37703,37704,37705,37712,
+37713,37714,37717,37719,37720,37722,37726,37732,37733,37735,37737,37738,37741,
+37743,37744,37745,37747,37748,37750,37754,37757,37759,37760,37761,37762,37768,
+37770,37771,37773,37775,37778,37781,37784,37787,37790,37793,37795,37796,37798,
+37800,37803,37812,37813,37814,37818,37801,37825,37828,37829,37830,37831,37833,
+37834,37835,37836,37837,37843,37849,37852,37854,37855,37858,37862,37863,37881,
+37879,37880,37882,37883,37885,37889,37890,37892,37896,37897,37901,37902,37903,
+37909,37910,37911,37919,37934,37935,37937,37938,37939,37940,37947,37951,37949,
+37955,37957,37960,37962,37964,37973,37977,37980,37983,37985,37987,37992,37995,
+37997,37998,37999,38001,38002,38020,38019,38264,38265,38270,38276,38280,38284,
+38285,38286,38301,38302,38303,38305,38310,38313,38315,38316,38324,38326,38330,
+38333,38335,38342,38344,38345,38347,38352,38353,38354,38355,38361,38362,38365,
+38366,38367,38368,38372,38374,38429,38430,38434,38436,38437,38438,38444,38449,
+38451,38455,38456,38457,38458,38460,38461,38465,38482,38484,38486,38487,38488,
+38497,38510,38516,38523,38524,38526,38527,38529,38530,38531,38532,38537,38545,
+38550,38554,38557,38559,38564,38565,38566,38569,38574,38575,38579,38586,38602,
+38610,23986,38616,38618,38621,38622,38623,38633,38639,38641,38650,38658,38659,
+38661,38665,38682,38683,38685,38689,38690,38691,38696,38705,38707,38721,38723,
+38730,38734,38735,38741,38743,38744,38746,38747,38755,38759,38762,38766,38771,
+38774,38775,38776,38779,38781,38783,38784,38793,38805,38806,38807,38809,38810,
+38814,38815,38818,38828,38830,38833,38834,38837,38838,38840,38841,38842,38844,
+38846,38847,38849,38852,38853,38855,38857,38858,38860,38861,38862,38864,38865,
+38868,38871,38872,38873,38877,38878,38880,38875,38881,38884,38895,38897,38900,
+38903,38904,38906,38919,38922,38937,38925,38926,38932,38934,38940,38942,38944,
+38947,38950,38955,38958,38959,38960,38962,38963,38965,38949,38974,38980,38983,
+38986,38993,38994,38995,38998,38999,39001,39002,39010,39011,39013,39014,39018,
+39020,39083,39085,39086,39088,39092,39095,39096,39098,39099,39103,39106,39109,
+39112,39116,39137,39139,39141,39142,39143,39146,39155,39158,39170,39175,39176,
+39185,39189,39190,39191,39194,39195,39196,39199,39202,39206,39207,39211,39217,
+39218,39219,39220,39221,39225,39226,39227,39228,39232,39233,39238,39239,39240,
+39245,39246,39252,39256,39257,39259,39260,39262,39263,39264,39323,39325,39327,
+39334,39344,39345,39346,39349,39353,39354,39357,39359,39363,39369,39379,39380,
+39385,39386,39388,39390,39399,39402,39403,39404,39408,39412,39413,39417,39421,
+39422,39426,39427,39428,39435,39436,39440,39441,39446,39454,39456,39458,39459,
+39460,39463,39469,39470,39475,39477,39478,39480,39495,39489,39492,39498,39499,
+39500,39502,39505,39508,39510,39517,39594,39596,39598,39599,39602,39604,39605,
+39606,39609,39611,39614,39615,39617,39619,39622,39624,39630,39632,39634,39637,
+39638,39639,39643,39644,39648,39652,39653,39655,39657,39660,39666,39667,39669,
+39673,39674,39677,39679,39680,39681,39682,39683,39684,39685,39688,39689,39691,
+39692,39693,39694,39696,39698,39702,39705,39707,39708,39712,39718,39723,39725,
+39731,39732,39733,39735,39737,39738,39741,39752,39755,39756,39765,39766,39767,
+39771,39774,39777,39779,39781,39782,39784,39786,39787,39788,39789,39790,39795,
+39797,39799,39800,39801,39807,39808,39812,39813,39814,39815,39817,39818,39819,
+39821,39823,39824,39828,39834,39837,39838,39846,39847,39849,39852,39856,39857,
+39858,39863,39864,39867,39868,39870,39871,39873,39879,39880,39886,39888,39895,
+39896,39901,39903,39909,39911,39914,39915,39919,39923,39927,39928,39929,39930,
+39933,39935,39936,39938,39947,39951,39953,39958,39960,39961,39962,39964,39966,
+39970,39971,39974,39975,39976,39977,39978,39985,39989,39990,39991,39997,40001,
+40003,40004,40005,40009,40010,40014,40015,40016,40019,40020,40022,40024,40027,
+40029,40030,40031,40035,40041,40042,40028,40043,40040,40046,40048,40050,40053,
+40055,40059,40166,40178,40183,40185,40203,40194,40209,40215,40216,40220,40221,
+40222,40239,40240,40242,40243,40244,40250,40252,40261,40253,40258,40259,40263,
+40266,40275,40276,40287,40291,40290,40293,40297,40298,40299,40304,40310,40311,
+40315,40316,40318,40323,40324,40326,40330,40333,40334,40338,40339,40341,40342,
+40343,40344,40353,40362,40364,40366,40369,40373,40377,40380,40383,40387,40391,
+40393,40394,40404,40405,40406,40407,40410,40414,40415,40416,40421,40423,40425,
+40427,40430,40432,40435,40436,40446,40458,40450,40455,40462,40464,40465,40466,
+40469,40470,40473,40476,40477,40570,40571,40572,40576,40578,40579,40580,40581,
+40583,40590,40591,40598,40600,40603,40606,40612,40616,40620,40622,40623,40624,
+40627,40628,40629,40646,40648,40651,40661,40671,40676,40679,40684,40685,40686,
+40688,40689,40690,40693,40696,40703,40706,40707,40713,40719,40720,40721,40722,
+40724,40726,40727,40729,40730,40731,40735,40738,40742,40746,40747,40751,40753,
+40754,40756,40759,40761,40762,40764,40765,40767,40769,40771,40772,40773,40774,
+40775,40787,40789,40790,40791,40792,40794,40797,40798,40808,40809,40813,40814,
+40815,40816,40817,40819,40821,40826,40829,40847,40848,40849,40850,40852,40854,
+40855,40862,40865,40866,40867,40869,
+};
+
+static const struct dbcs_index jisx0212_decmap[256] = {
+{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__jisx0212_decmap+0,47,113},{0,0,0},{
+0,0,0},{0,0,0},{__jisx0212_decmap+67,97,124},{__jisx0212_decmap+95,66,126},{0,
+0,0},{__jisx0212_decmap+156,33,80},{__jisx0212_decmap+204,33,119},{
+__jisx0212_decmap+291,33,119},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+__jisx0212_decmap+378,33,126},{__jisx0212_decmap+472,33,126},{
+__jisx0212_decmap+566,33,126},{__jisx0212_decmap+660,33,126},{
+__jisx0212_decmap+754,33,126},{__jisx0212_decmap+848,33,126},{
+__jisx0212_decmap+942,33,126},{__jisx0212_decmap+1036,33,126},{
+__jisx0212_decmap+1130,33,126},{__jisx0212_decmap+1224,33,126},{
+__jisx0212_decmap+1318,33,126},{__jisx0212_decmap+1412,33,126},{
+__jisx0212_decmap+1506,33,126},{__jisx0212_decmap+1600,33,126},{
+__jisx0212_decmap+1694,33,126},{__jisx0212_decmap+1788,33,126},{
+__jisx0212_decmap+1882,33,126},{__jisx0212_decmap+1976,33,126},{
+__jisx0212_decmap+2070,33,126},{__jisx0212_decmap+2164,33,126},{
+__jisx0212_decmap+2258,33,126},{__jisx0212_decmap+2352,33,126},{
+__jisx0212_decmap+2446,33,126},{__jisx0212_decmap+2540,33,126},{
+__jisx0212_decmap+2634,33,126},{__jisx0212_decmap+2728,33,126},{
+__jisx0212_decmap+2822,33,126},{__jisx0212_decmap+2916,33,126},{
+__jisx0212_decmap+3010,33,126},{__jisx0212_decmap+3104,33,126},{
+__jisx0212_decmap+3198,33,126},{__jisx0212_decmap+3292,33,126},{
+__jisx0212_decmap+3386,33,126},{__jisx0212_decmap+3480,33,126},{
+__jisx0212_decmap+3574,33,126},{__jisx0212_decmap+3668,33,126},{
+__jisx0212_decmap+3762,33,126},{__jisx0212_decmap+3856,33,126},{
+__jisx0212_decmap+3950,33,126},{__jisx0212_decmap+4044,33,126},{
+__jisx0212_decmap+4138,33,126},{__jisx0212_decmap+4232,33,126},{
+__jisx0212_decmap+4326,33,126},{__jisx0212_decmap+4420,33,126},{
+__jisx0212_decmap+4514,33,126},{__jisx0212_decmap+4608,33,126},{
+__jisx0212_decmap+4702,33,126},{__jisx0212_decmap+4796,33,126},{
+__jisx0212_decmap+4890,33,126},{__jisx0212_decmap+4984,33,126},{
+__jisx0212_decmap+5078,33,126},{__jisx0212_decmap+5172,33,126},{
+__jisx0212_decmap+5266,33,126},{__jisx0212_decmap+5360,33,126},{
+__jisx0212_decmap+5454,33,126},{__jisx0212_decmap+5548,33,126},{
+__jisx0212_decmap+5642,33,126},{__jisx0212_decmap+5736,33,126},{
+__jisx0212_decmap+5830,33,126},{__jisx0212_decmap+5924,33,126},{
+__jisx0212_decmap+6018,33,126},{__jisx0212_decmap+6112,33,99},{0,0,0},{0,0,0},
+{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
+};
+
+static const DBCHAR __jisxcommon_encmap[22016] = {
+8512,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41527,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41538,
+8561,8562,41584,N,41539,8568,8495,41581,41580,N,8780,N,41582,41524,8555,8542,
+N,N,8493,N,8825,N,41521,N,41579,N,N,N,N,41540,43554,43553,43556,43562,43555,
+43561,43297,43566,43570,43569,43572,43571,43584,43583,43586,43585,N,43600,
+43602,43601,43604,43608,43603,8543,43308,43619,43618,43621,43620,43634,43312,
+43342,43810,43809,43812,43818,43811,43817,43329,43822,43826,43825,43828,43827,
+43840,43839,43842,43841,43331,43856,43858,43857,43860,43864,43859,8544,43340,
+43875,43874,43877,43876,43890,43344,43891,43559,43815,43557,43813,43560,43816,
+43563,43819,43564,43820,43567,43823,43565,43821,43568,43824,43298,43330,43575,
+43831,N,N,43574,43830,43576,43832,43573,43829,43578,43834,43579,43835,43581,
+43837,43580,N,43582,43838,43300,43332,43591,43847,43589,43845,N,N,43590,43846,
+43588,43333,43302,43334,43592,43848,43593,43849,43335,43594,43850,43596,43852,
+43595,43851,43305,43337,43304,43336,43597,43853,43599,43855,43598,43854,43338,
+43307,43339,43607,43863,N,N,43606,43862,43309,43341,43609,43865,43611,43867,
+43610,43866,43612,43868,43613,43869,43615,43871,43614,43870,43617,43873,43616,
+43872,43311,43343,43628,43884,43625,43881,43622,43878,43627,43883,43624,43880,
+43626,43882,43633,43889,43636,43892,43635,43637,43893,43639,43895,43638,43894,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+43558,43814,43587,43843,43605,43861,43623,43879,43632,43888,43629,43885,43631,
+43887,43630,43886,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43833,41520,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41519,41522,41526,41525,N,41523,41528,41529,
+42593,N,42594,42595,42596,N,42599,N,42601,42604,42614,9761,9762,9763,9764,
+9765,9766,9767,9768,9769,9770,9771,9772,9773,9774,9775,9776,9777,N,9778,9779,
+9780,9781,9782,9783,9784,42597,42602,42609,42610,42611,42612,42619,9793,9794,
+9795,9796,9797,9798,9799,9800,9801,9802,9803,9804,9805,9806,9807,9808,9809,
+42616,9810,9811,9812,9813,9814,9815,9816,42613,42618,42615,42617,42620,10023,
+42818,42819,42820,42821,42822,42823,42824,42825,42826,42827,42828,N,42829,
+42830,10017,10018,10019,10020,10021,10022,10024,10025,10026,10027,10028,10029,
+10030,10031,10032,10033,10034,10035,10036,10037,10038,10039,10040,10041,10042,
+10043,10044,10045,10046,10047,10048,10049,10065,10066,10067,10068,10069,10070,
+10072,10073,10074,10075,10076,10077,10078,10079,10080,10081,10082,10083,10084,
+10085,10086,10087,10088,10089,10090,10091,10092,10093,10094,10095,10096,10097,
+N,10071,42866,42867,42868,42869,42870,42871,42872,42873,42874,42875,42876,N,
+42877,42878,8510,N,N,N,N,8509,8514,N,8518,8519,N,N,8520,8521,N,N,8823,8824,N,
+N,N,8517,8516,N,N,N,N,N,N,N,N,N,8819,N,8556,8557,N,N,N,N,N,N,N,8744,8558,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41585,N,N,N,N,N,N,N,N,N,N,N,41583,N,N,N,N,N,N,
+N,N,8818,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8747,8748,8746,8749,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8781,N,8782,8783,N,8799,8784,N,N,N,
+8800,8762,N,N,8763,N,N,N,N,N,N,8541,N,N,N,N,N,N,N,8805,N,N,8807,8551,N,8796,N,
+N,N,N,N,N,8778,8779,8769,8768,8809,8810,N,N,N,N,N,N,N,8552,8808,N,N,N,N,N,N,N,
+8806,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8802,N,N,N,N,N,N,N,N,N,N,N,N,N,
+8546,8801,N,N,N,N,8549,8550,N,N,8803,8804,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,8766,8767,N,N,8764,8765,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,8797,8798,10273,10284,10274,10285,N,N,N,N,N,N,N,N,10275,N,N,10286,
+10276,N,N,10287,10278,N,N,10289,10277,N,N,10288,10279,10300,N,N,10295,N,N,
+10290,10281,10302,N,N,10297,N,N,10292,10280,N,N,10296,10301,N,N,10291,10282,N,
+N,10298,10303,N,N,10293,10283,N,N,10299,N,N,10304,N,N,N,N,N,N,N,N,10294,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,8739,8738,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8741,8740,N,N,N,N,N,N,N,N,
+8743,8742,N,N,N,N,N,N,N,N,8737,8574,N,N,N,8571,N,N,8573,8572,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8830,8570,8569,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,8554,N,8553,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8822,N,N,8821,N,8820,8481,8482,8483,8503,N,
+8505,8506,8507,8530,8531,8532,8533,8534,8535,8536,8537,8538,8539,8745,8750,
+8524,8525,N,N,N,N,N,N,8513,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,9249,9250,9251,9252,9253,9254,9255,9256,9257,9258,9259,
+9260,9261,9262,9263,9264,9265,9266,9267,9268,9269,9270,9271,9272,9273,9274,
+9275,9276,9277,9278,9279,9280,9281,9282,9283,9284,9285,9286,9287,9288,9289,
+9290,9291,9292,9293,9294,9295,9296,9297,9298,9299,9300,9301,9302,9303,9304,
+9305,9306,9307,9308,9309,9310,9311,9312,9313,9314,9315,9316,9317,9318,9319,
+9320,9321,9322,9323,9324,9325,9326,9327,9328,9329,9330,9331,N,N,N,N,N,N,N,
+8491,8492,8501,8502,N,N,9505,9506,9507,9508,9509,9510,9511,9512,9513,9514,
+9515,9516,9517,9518,9519,9520,9521,9522,9523,9524,9525,9526,9527,9528,9529,
+9530,9531,9532,9533,9534,9535,9536,9537,9538,9539,9540,9541,9542,9543,9544,
+9545,9546,9547,9548,9549,9550,9551,9552,9553,9554,9555,9556,9557,9558,9559,
+9560,9561,9562,9563,9564,9565,9566,9567,9568,9569,9570,9571,9572,9573,9574,
+9575,9576,9577,9578,9579,9580,9581,9582,9583,9584,9585,9586,9587,9588,9589,
+9590,N,N,N,N,8486,8508,8499,8500,12396,17274,45089,15415,45090,45091,N,19324,
+15974,15152,15973,12860,45092,18772,19775,N,20514,12591,45093,N,13166,20515,
+16420,21058,13654,19002,N,N,N,N,15975,45094,N,20030,N,45095,45096,N,19010,N,
+45097,N,20516,45098,N,17254,45099,45100,45101,20517,13946,N,N,45102,20518,N,
+13405,17200,N,15463,20519,N,N,20520,45103,45104,20521,18229,45105,13655,N,
+45106,N,N,N,18231,N,18019,14403,19251,N,45107,N,N,N,26953,20522,15976,20523,
+12853,45108,N,45109,13925,14448,19561,N,N,22054,45110,N,N,N,N,45111,45112,N,N,
+N,N,N,N,N,19824,N,18045,45113,45114,N,N,N,45115,N,N,N,N,13349,45116,13621,N,
+20524,N,N,20525,20027,N,19773,16744,20527,15222,18035,45117,20530,N,N,12606,
+14431,N,14430,12390,45118,45119,20299,20298,N,14899,12321,45120,20531,20532,
+20533,19252,20534,N,14450,12391,19314,N,13692,N,N,13693,13694,17506,20028,
+45121,20535,N,N,20536,N,N,20537,N,N,45122,16205,N,N,N,N,N,15674,16206,20542,
+45123,20540,N,20541,13656,N,N,14883,12912,N,20539,20538,18985,45124,N,N,N,
+15174,15173,16958,20543,18773,16487,45125,45126,N,8504,20544,20546,45127,
+45128,45129,16997,20065,12362,N,N,45130,N,N,N,N,20545,12862,45131,13892,45132,
+17255,45133,N,45134,14191,20547,N,N,N,18212,N,45135,45136,45137,45138,13419,
+45139,45140,N,N,N,N,45141,20548,12363,45142,45143,14432,13420,18810,18482,
+13657,45144,N,N,45145,45146,45147,N,45148,12913,N,20583,17729,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,45149,18284,20550,45150,N,45152,18492,45153,20066,45154,16173,
+45155,15175,45156,15223,12864,45157,N,45158,N,45159,17489,N,N,17186,20554,
+45160,45161,N,45162,45163,12364,17507,15675,14900,19748,45164,16974,45165,
+12863,45166,20553,45167,19774,20549,20551,14958,20552,21796,45168,45151,N,N,
+45169,N,N,N,N,N,20560,45170,N,45171,N,45172,20563,20561,45173,N,12866,N,19003,
+20555,45174,45175,45176,45177,20559,14451,45178,45179,15176,N,45180,45181,
+13350,45182,45345,20564,N,20556,45346,45347,20067,45348,15224,45349,20557,
+45350,20562,45351,45352,45353,N,20565,45354,20558,45355,45356,13857,N,12365,
+45357,45358,13858,12865,N,N,N,N,N,N,N,N,N,21797,N,19321,18798,14452,N,N,45359,
+N,N,16175,20023,45360,N,45361,N,45362,45363,45364,45365,19032,45366,45367,
+14136,16933,12900,45368,45369,N,45370,45371,15699,45372,45373,45374,20569,
+45375,20574,20572,45376,N,20567,N,N,16943,20570,N,20573,20571,45377,19037,N,
+20568,45378,16174,45379,19315,20575,20576,N,N,N,N,N,N,N,N,15652,20589,45380,N,
+45381,18256,N,18742,20584,N,19056,N,12854,N,45382,45383,20588,45384,45385,
+45386,N,N,45387,20582,20591,45388,N,16722,45389,14404,45390,18268,45391,24647,
+45392,20590,17757,45393,20579,N,14454,45394,45395,14453,20577,45396,45397,
+45398,45399,15450,N,20585,45400,19055,17229,20581,14193,45401,20578,20586,
+20580,20049,20587,20289,45402,N,45403,N,45404,45405,N,45406,13926,N,N,14192,N,
+45430,N,N,N,N,45407,45408,45409,20592,N,45410,45411,20593,20597,12366,45412,N,
+45413,N,45414,19024,20596,45415,45416,45417,N,20595,20599,45418,N,45419,20598,
+N,17508,N,N,45420,45421,N,45422,45423,N,14194,45424,45425,N,N,45426,N,20600,
+45427,N,N,45428,45429,15429,N,16934,17509,13942,N,20601,N,N,N,N,13622,N,N,
+20602,45431,N,45432,45433,20604,45434,N,N,N,45435,N,N,19253,45436,45437,45438,
+14182,45601,45602,45603,N,45604,N,15153,18551,20603,45605,45606,N,45607,45608,
+45609,45610,45611,N,N,N,N,N,N,N,45612,N,14917,19779,N,45613,45614,N,20606,
+20771,20605,14916,N,15741,N,45615,45616,N,N,45617,14137,N,45618,N,20772,45619,
+45620,13903,N,45621,N,20769,20770,N,45622,17967,45623,16764,45624,13859,N,
+45625,45626,19277,20773,N,45627,N,20029,N,45628,45629,20774,45630,N,N,45631,
+20777,45632,20775,45633,16718,45634,45635,N,N,N,20776,20778,45636,N,45637,
+45649,N,N,20780,45638,N,N,20779,45639,19016,N,N,45640,13623,20782,20783,45641,
+12847,N,45642,45643,45644,20781,N,45645,45646,45647,45648,N,45650,N,15476,N,
+20786,20785,20784,45651,20566,45652,20787,45653,45654,45655,45656,15742,N,
+20788,N,45657,N,N,N,45658,45659,N,19749,N,45660,45661,N,45662,N,45663,19545,
+45664,45665,45666,N,20790,45667,45668,20789,20792,20791,N,N,20793,20794,12404,
+45669,14389,14139,15676,17275,13860,16488,14455,45670,14702,20796,19528,17734,
+45671,15225,N,20795,45672,20797,45673,N,45674,45675,N,17758,N,13173,N,N,45676,
+N,N,20798,N,45677,18046,45678,N,16692,20800,20801,18476,14456,20283,20802,N,N,
+13862,N,N,N,19004,16950,13937,17717,N,N,N,14195,N,45679,N,20803,N,20804,45680,
+45681,18018,12639,N,N,20807,14973,45682,20806,14918,45683,20808,26222,20809,
+19265,20810,N,20811,20812,15977,45684,15436,N,N,N,45685,N,N,13351,45686,20815,
+45687,20813,19517,20814,N,18778,20816,20817,20818,17759,45688,N,N,20822,20820,
+20821,20819,14947,20823,19562,20068,45689,N,45690,N,45691,20824,45692,45693,N,
+N,45694,N,16424,20825,15706,N,45857,20826,N,17276,20031,17760,N,45858,N,45859,
+45860,45861,N,45862,21061,N,45863,N,N,20827,29733,13893,45864,N,20828,19294,
+45865,N,N,45866,15720,17020,N,20830,18020,N,N,20831,45867,N,20832,13102,45868,
+45869,45870,20833,13863,45871,17996,12666,15696,N,N,18465,20834,17761,45872,
+45873,16207,20835,45874,18988,16474,13346,N,13353,20836,N,N,20838,N,N,14138,
+45875,45876,20837,45877,45878,20083,45879,N,N,N,N,15721,N,N,N,N,45880,N,18493,
+19020,N,20839,45881,19832,20840,N,N,N,20841,N,17790,45882,45883,20842,N,45884,
+16425,14974,14196,20843,15177,14703,45885,N,N,N,N,N,N,17510,20845,45886,N,
+16935,N,45887,14959,20846,20847,16688,N,20844,N,N,N,N,20849,45888,19254,45889,
+45890,N,45891,14692,45892,N,20848,45893,45894,45895,N,14197,14942,18285,45896,
+N,N,20852,20850,N,N,N,45897,18811,15978,20859,13156,20853,20851,16719,N,45898,
+45899,45900,N,N,N,20855,N,20854,45901,N,45902,13124,N,45903,N,14176,20860,
+20013,45904,N,45905,20856,N,N,N,20861,20858,45906,20857,45907,45908,45909,
+45910,N,45911,20047,45912,N,N,14457,12867,N,N,20084,45913,45914,45915,45916,N,
+15733,17752,14693,21026,21027,N,45917,45918,20069,N,N,20267,21029,45919,45920,
+45921,14458,45922,45923,21028,45924,13103,N,45925,21030,N,19286,45926,17468,
+45927,19750,45928,19033,N,N,45929,21031,N,45930,N,45931,28757,N,45932,17968,
+45933,21032,13354,19507,N,45934,45935,15905,21033,19047,21037,45936,16426,
+21034,13904,45937,21035,13355,45938,45939,45940,N,45941,N,N,N,45942,45943,
+14126,21038,45944,21039,45945,45946,21040,21041,15451,N,N,N,14459,19550,45947,
+19560,18039,45948,N,19057,21042,N,21043,N,45949,45950,46113,21045,N,21047,
+21046,46114,N,46115,N,21048,12861,19276,46116,14972,21049,46117,46118,16729,
+46119,46120,15906,13865,N,21050,N,46121,N,46122,46123,46124,18523,46125,46126,
+46127,N,21051,46128,21052,46129,21053,N,46130,N,N,21054,18724,13928,12389,
+46131,46132,46133,17983,21055,15677,46134,16489,N,21057,21056,15907,14433,
+21059,18494,46136,46135,21060,N,N,N,18524,16948,17006,13864,N,N,18030,17201,
+46137,18286,46138,19278,N,21062,N,16490,46139,N,46140,N,46141,14133,N,N,21063,
+N,N,46142,46143,21064,12588,12405,13421,46144,16936,13649,19825,N,21067,12855,
+46145,N,21066,N,N,46146,13866,N,N,21068,46147,19569,N,N,46148,46149,N,N,N,N,N,
+46150,N,N,N,N,46151,46152,N,21069,N,20050,46153,14460,N,N,46154,N,14390,21070,
+46155,N,N,46156,21072,21071,N,16223,12601,46157,46158,N,12638,21073,46159,
+21074,N,46160,14391,46161,46162,21075,46163,46164,N,46165,13678,N,46166,N,N,
+46167,N,15154,21076,N,46168,N,N,19316,14901,13658,19751,16720,18495,15485,
+46169,N,N,46170,46171,15687,46172,15464,15477,N,15734,46173,18496,N,46174,
+46175,21079,46176,12611,16721,14461,14405,13927,46177,46178,21083,17185,17022,
+13867,15908,21084,21082,12868,16998,15416,15179,12582,N,46179,13168,14694,
+15178,N,21085,21086,46180,13641,13126,N,N,N,14695,13640,17503,12581,17969,
+19518,14625,19833,17735,14462,N,46181,N,N,N,N,N,N,46182,14127,N,21095,N,13923,
+19274,46183,N,N,N,N,18525,46184,46185,21094,46186,13406,21089,21090,21092,
+46187,N,46188,N,N,46189,46190,21093,N,13659,16225,N,18989,21091,21087,14435,N,
+21088,N,20260,46191,46192,N,19058,46193,17512,14434,14704,N,N,46194,21096,
+46195,N,18013,N,N,N,N,N,N,N,N,N,N,N,N,46196,21100,N,N,46197,N,46198,N,46199,
+46200,15486,46201,15478,46202,N,46203,46204,N,21103,21101,N,19491,46205,21098,
+21107,21102,N,N,N,21105,14406,19519,N,46206,21106,46369,N,46370,21108,46371,
+21110,N,46372,46373,N,14960,20290,46374,21099,21097,21109,46375,21104,N,N,
+46376,46377,N,N,N,N,N,46378,N,N,46379,N,46380,21112,N,21283,21114,46381,46382,
+21118,46383,46384,21281,21115,46385,46386,21310,N,46387,14953,13105,N,N,N,
+46388,21113,46389,46390,46391,21285,12406,21284,46392,12325,18762,21282,N,
+21116,N,46393,21111,21117,14920,46394,N,N,46395,46396,N,N,N,N,N,N,N,N,N,21286,
+N,N,N,N,N,N,N,46397,12407,21295,N,N,21287,21288,N,15909,19305,46398,N,46399,
+21293,21292,46400,N,N,17711,N,N,N,46401,N,N,N,21294,N,46402,21291,46403,46404,
+46405,46406,N,N,12596,46407,14902,16176,46408,46409,N,N,46410,46411,46412,
+21289,17762,N,N,N,21290,46413,12322,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+46414,46415,N,N,21300,19747,N,15911,46416,21306,N,46417,46418,N,21305,21296,N,
+46419,46420,46421,16963,N,21297,46422,N,N,17007,21302,15910,46423,N,46424,
+46425,N,21299,46426,N,19556,46427,46428,N,14140,N,N,21303,21304,46429,N,46430,
+46431,21301,21307,46432,N,46433,46434,N,21298,46435,N,46436,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,21313,21318,N,21314,46437,21309,46438,46439,21319,16689,
+N,46440,21321,46441,14626,21311,17277,N,N,46442,46443,N,46444,46445,46446,
+46447,N,N,46448,21315,21308,13357,N,13422,13157,21316,21312,N,N,N,46449,46450,
+N,N,14198,21322,21320,16723,13642,13868,46451,21317,N,13940,N,46452,N,N,N,
+12612,N,N,N,N,N,N,N,N,46453,N,46454,N,46455,21326,21324,46456,21543,N,46457,N,
+46458,46459,N,46460,N,N,46461,46462,46625,21329,N,N,46626,46627,N,21323,46628,
+21327,N,46629,21325,N,N,46630,15180,21328,N,N,N,N,46631,N,N,N,N,N,N,N,N,N,N,N,
+N,46632,21331,N,21336,N,N,N,21334,21333,46633,46634,17202,N,46635,12869,46636,
+N,N,46637,46638,46639,46640,46641,46642,N,21330,N,21332,15912,12595,46643,N,
+21335,N,N,N,N,N,N,N,N,N,N,N,N,N,12894,N,N,46644,N,N,21346,46645,15996,21342,
+46646,21340,46647,21341,46648,21343,46649,N,46650,46651,46652,N,46653,46654,
+46655,12605,46656,46657,N,46658,N,N,46659,N,46660,16697,46661,21337,46662,
+21338,N,N,N,46663,N,N,N,N,N,N,13178,N,N,46664,N,46665,46666,46667,46668,21345,
+N,46669,N,13423,46670,21348,21344,21347,46671,N,46672,N,46673,46674,N,18990,
+46675,N,N,18005,N,18488,N,N,N,N,N,21350,N,N,N,46676,46677,21349,13125,46678,N,
+21351,46679,46680,N,N,21354,N,N,N,N,21353,46681,N,N,N,46682,46683,N,N,46684,
+46685,46686,21352,N,18233,N,N,21355,46687,46688,46689,46690,N,46691,46692,
+46693,21356,N,N,46694,N,46695,21358,N,21357,46696,N,N,N,N,21360,N,46697,N,
+21363,21361,21359,21362,N,46698,N,N,21364,46699,46700,46701,46704,46705,21365,
+46702,46703,21366,N,21367,N,N,N,21368,20805,46706,15484,15181,46707,46708,
+12915,46709,12408,46710,N,17220,46711,46712,46713,46714,46715,N,N,46717,N,
+46718,21369,N,14884,46716,12367,16222,N,N,46881,46882,N,21370,14407,N,N,14705,
+N,21372,21371,46883,46884,19040,21373,N,N,46885,21537,21374,46886,21538,46887,
+21539,N,14199,N,46888,12640,21540,N,46889,21542,N,21541,N,46890,46891,21544,
+46892,N,17754,46893,N,46894,46895,46896,46897,21545,12341,14943,46898,46899,N,
+46900,14141,46901,46902,17231,N,N,46903,46904,N,N,21546,21547,N,N,21549,N,
+46905,46906,46907,21550,N,14948,N,N,46908,46909,13905,N,N,19255,N,46910,46911,
+21548,21551,14913,14627,46912,N,N,N,N,N,N,N,N,N,N,N,N,N,N,21555,46913,N,14885,
+46914,17203,46915,46916,21552,17498,46917,N,46918,46919,46920,46921,46922,N,
+46923,46924,46925,N,46926,N,46927,46928,46929,46930,N,46931,21556,N,46932,
+16226,46933,N,N,N,N,21554,21557,N,14143,46934,N,N,N,N,N,N,21558,46935,46944,N,
+46936,N,46937,46938,N,46939,46940,46941,46942,21559,46943,14628,13120,21561,N,
+N,46945,46946,46947,21562,N,46948,N,N,N,21563,N,N,21560,N,N,N,N,46949,N,N,N,N,
+46950,N,N,21553,N,N,21564,N,N,21565,46951,46952,N,N,19300,46953,N,15979,46954,
+N,N,21567,21568,21566,46955,21570,N,N,N,N,N,18232,46956,46957,12392,18774,
+46974,N,21571,46958,N,46959,46960,N,46961,N,N,N,46962,N,N,46963,N,N,N,15997,
+46964,46965,15417,46966,18269,13424,N,14955,46967,46968,46969,19289,N,17970,
+46970,46971,14200,16975,N,46972,46973,21569,21572,47137,47138,N,N,N,N,N,N,N,
+16964,N,N,N,21573,N,47139,N,21574,47140,47141,47142,21576,N,N,17513,N,47143,
+47144,N,N,13358,N,N,47145,N,29729,12641,19059,47146,N,15980,17736,N,N,N,47147,
+14950,N,N,21582,N,47148,19005,20061,N,N,N,N,N,N,N,47149,12916,21578,47150,
+47151,N,47152,47153,16698,21581,N,17763,47154,N,17737,17764,18489,17485,N,N,N,
+14921,47155,N,47156,21577,N,47157,N,N,47158,47159,12662,N,17718,N,N,N,N,21579,
+N,21575,N,N,16208,N,N,47160,21583,N,N,47161,N,15694,47162,47163,47164,N,13869,
+N,21584,N,47165,47166,47167,47168,N,47169,47170,N,47171,47172,N,N,19048,47173,
+N,47174,16765,N,N,N,N,17478,47175,N,21586,47176,47177,47178,N,N,N,47179,N,
+19279,47180,N,21587,N,N,21592,N,N,47181,47182,18991,N,N,N,N,21591,21585,21588,
+21590,47184,N,14886,N,N,19017,47185,N,47183,21593,N,17221,47186,N,12917,N,
+15981,47187,47188,N,47189,21595,47190,21594,47191,14696,47192,21596,21598,
+21597,47193,N,21600,47194,21589,21602,N,47195,47196,N,21601,21599,N,N,N,47197,
+N,15182,16209,N,16724,21603,16444,12397,18276,47198,N,N,N,17499,N,21605,21604,
+21606,21607,21608,21609,N,N,47199,47200,N,N,19025,21610,47201,47202,N,N,12870,
+21611,N,47203,47204,47205,19772,13104,N,21065,15688,16959,21612,19563,47207,N,
+N,N,47208,19508,47209,47210,21614,N,16999,47211,17719,16960,18775,21615,21616,
+12667,47212,47213,15418,21617,47214,N,47215,47216,12368,21618,N,N,N,N,N,21619,
+47217,N,N,N,47218,12642,N,47219,13425,18016,19060,N,N,N,N,21623,16725,21622,
+14144,47220,47221,19291,21621,N,17765,21625,47222,21624,47223,N,47224,47225,
+47226,21627,47227,21626,47228,N,12668,N,21628,15913,21630,17189,47229,21629,
+47230,18995,47393,N,N,47394,15735,17755,47395,47396,N,21793,47397,N,47398,
+47399,14629,N,N,N,21794,18209,18526,19537,N,N,N,N,N,18213,47400,47401,21803,
+47402,N,N,N,47403,13624,N,47404,19781,47405,N,19503,N,22060,N,21795,N,47406,N,
+N,N,21798,47407,16965,N,47408,19256,N,N,N,17738,47409,47410,47411,47412,N,
+21799,47413,N,N,N,47414,N,19301,47415,14922,47416,N,15914,N,N,47417,N,47418,
+47419,N,21800,N,47420,15184,47421,15183,N,47422,N,N,12345,14408,47423,16427,
+12369,N,N,N,N,21804,21805,N,21802,47424,47425,47426,N,N,N,47427,47428,12600,
+13359,47429,21801,N,19525,18737,N,N,47430,47431,N,47432,47433,N,47434,N,12328,
+47435,N,N,N,12409,N,N,N,15185,47436,12370,N,12323,47437,N,N,N,N,21810,N,N,
+47438,47439,47440,N,N,21808,47441,47442,N,N,N,N,19516,N,21811,N,21809,N,47443,
+21807,16177,N,N,47444,47445,21806,N,47446,47447,19034,47448,N,N,47449,N,14436,
+47450,N,N,N,N,21815,21816,N,N,N,N,N,15915,N,N,N,21812,20268,N,N,47451,47452,
+18252,47453,47454,21814,N,N,47455,N,N,N,47456,N,N,N,N,47457,N,N,N,N,14887,N,N,
+N,47458,N,N,N,21817,47459,N,47460,18776,47461,N,N,21818,N,21813,47462,N,N,N,N,
+N,N,N,N,N,47463,N,N,47464,47465,N,N,47466,19515,N,N,N,N,N,N,N,N,N,N,N,47467,N,
+N,N,N,47468,N,18270,47469,N,N,47470,N,N,47471,21819,18738,47472,N,47473,47474,
+47475,N,47476,N,N,N,N,47477,N,N,N,N,47478,N,N,N,N,47479,47480,47481,N,47482,N,
+N,47483,N,47484,47485,21820,21824,21821,47486,N,12871,21823,N,47649,N,47650,N,
+47651,15419,N,21822,14201,N,N,47652,21836,N,N,N,N,N,21829,21826,N,N,47653,N,
+47654,N,N,N,47655,17252,N,21825,N,47656,21827,N,N,21828,47657,N,N,N,47658,N,N,
+N,N,N,N,47659,47660,N,N,N,21830,21831,N,47661,47662,47663,N,N,N,N,N,N,47664,
+13426,N,21833,21832,N,N,N,N,N,N,N,N,N,21834,47665,N,47667,N,47668,N,47669,N,N,
+N,47670,15982,N,N,47671,N,N,N,N,21837,N,17500,47672,N,N,12613,N,21835,N,47666,
+N,21838,N,47673,N,N,N,N,N,21839,N,21842,47674,N,21840,N,21841,N,N,N,N,N,47675,
+47676,N,N,N,15186,21843,47677,N,14630,21844,47678,15226,16952,N,21845,21846,
+15194,14631,47679,19538,N,N,N,13608,14409,21847,13144,N,47680,21848,N,16953,N,
+N,47681,47682,21849,22051,N,21850,N,21851,N,N,21852,N,21854,N,47683,47684,
+47685,47686,21855,47687,N,21856,47688,17008,47689,12583,15465,12354,47690,
+16727,13360,15413,47691,14632,47692,47693,N,47694,47695,17766,47696,15649,
+13361,17256,17514,12344,13625,19061,N,15426,N,N,13650,16491,15420,19752,21857,
+N,47697,47698,N,N,47699,47700,13660,47701,14923,47702,47703,13106,12643,15916,
+12872,47704,21858,19782,47705,N,47706,N,N,15689,47707,47708,15460,21859,13427,
+18002,19497,21860,N,21861,N,N,18777,47709,N,47710,21863,N,13352,13943,21862,N,
+47711,47712,47713,47714,47715,13362,N,16178,21867,15137,47716,12873,21866,N,
+21864,21868,21865,18219,23629,16179,N,21869,N,N,20032,47717,21870,47718,N,
+21872,47719,17278,21871,N,16419,N,15227,N,N,47720,16976,15479,18805,16492,N,
+15437,21873,15917,21874,21875,12371,16954,16210,47721,21876,17971,15918,N,
+15919,N,21877,N,N,16493,47722,N,N,15920,N,N,N,47723,47724,21878,N,21879,47725,
+19552,N,47726,N,21880,47727,N,47728,47729,13894,47730,N,47731,15650,47732,N,N,
+47733,47734,N,21881,21882,15452,16172,18036,16212,18552,18210,13897,21883,N,N,
+N,13679,21884,N,13950,N,17999,12848,N,15187,21885,22050,22049,13949,N,21886,N,
+17720,N,N,N,47735,47736,N,47737,N,16944,N,17739,15432,47738,47739,16728,19834,
+N,47740,47741,47742,N,N,22052,47905,22053,18006,47906,15155,N,N,47907,47908,
+22055,N,N,22056,47909,47910,47911,47912,N,N,N,N,N,N,N,N,N,47913,47914,N,47915,
+N,22057,N,N,47916,13428,22058,47917,N,22059,N,N,N,N,N,N,N,N,47918,N,47919,
+47920,12844,47921,47922,N,N,47923,N,16699,13412,47924,22061,19496,N,N,N,N,
+16978,47925,13145,47926,47927,22063,22065,13407,N,47928,22062,22064,N,22067,N,
+N,N,N,N,N,22066,N,22068,N,47929,N,47930,N,N,N,N,N,N,47931,N,N,N,N,47933,N,
+22069,N,N,N,47932,N,N,17981,13870,N,N,N,N,N,N,12901,22070,22075,N,N,22073,
+47934,19063,19062,47935,47936,N,47937,N,17767,N,N,N,22072,15700,N,22071,47938,
+N,N,N,N,47939,16242,N,N,N,22076,N,47940,14954,N,N,22082,47941,N,22083,22077,
+13107,22078,22087,22086,22085,22081,N,N,N,22080,N,N,22084,47943,47944,N,47945,
+47946,N,19064,N,47942,N,N,N,N,N,47947,N,N,47948,N,N,N,N,47949,N,N,N,47950,N,
+47951,N,N,47952,47953,N,N,47954,N,47955,N,47959,22091,22088,N,22090,N,19826,
+47957,22089,N,N,47956,N,N,N,47958,N,N,22079,N,N,47960,47961,47962,47963,N,
+47964,N,N,N,N,16243,47965,N,22092,47966,N,14903,47967,N,N,22093,N,N,22094,N,N,
+47968,47969,N,N,N,47970,47971,N,47972,22097,47973,22096,N,N,22095,47974,N,
+47975,17768,22074,N,N,N,22103,N,47976,47977,47978,47979,N,N,N,47980,N,47981,N,
+22099,N,47982,47983,N,22098,N,N,N,N,47984,N,N,N,47985,22100,N,22101,N,47986,N,
+58996,N,47987,N,N,22104,47988,47989,20070,N,22105,22102,N,N,N,N,N,47990,N,N,N,
+47991,N,22106,N,47992,13408,22107,47994,N,47993,N,22109,22108,N,N,22110,N,
+47995,47996,N,22111,N,16494,15651,N,47997,15716,N,16739,47998,14633,14904,
+14634,13680,48161,N,22112,N,N,14905,N,N,14410,22113,19494,18243,22114,N,14635,
+48162,48163,N,13356,N,17191,13906,48164,N,15188,18779,N,N,18497,48165,N,N,N,
+22115,13429,48166,N,N,N,22118,48167,N,48168,48169,17441,N,48170,22117,22116,
+22119,N,17515,N,48171,48172,N,N,N,N,16227,N,N,48174,N,N,15189,N,16458,48173,
+16979,13602,N,48175,17442,N,48176,22120,22121,15983,N,N,N,N,19257,48177,N,
+22124,N,N,22123,22122,18813,N,22131,N,48180,N,48178,19290,N,22125,N,48179,
+48181,N,N,22127,19307,48182,22126,48183,N,N,48184,48185,N,48186,22128,N,18472,
+22129,19006,22130,N,N,N,48187,N,48188,48189,48190,48191,48192,N,48193,N,13363,
+19007,18223,22132,22133,N,14636,13364,22134,14392,19780,19753,13430,22136,
+48194,17443,N,14637,15921,N,N,18527,N,N,15922,48195,N,N,48196,15736,N,N,N,N,N,
+17516,19065,17721,N,N,14638,N,18780,N,N,N,22137,N,48197,N,48198,48199,17753,
+14914,48200,N,48201,14411,48202,17517,N,N,N,48203,N,48204,N,12355,15726,14639,
+19783,N,N,N,N,48205,48206,48207,N,22138,22139,18257,N,N,48208,N,22140,20087,
+20269,48210,48209,N,48211,22142,22141,48212,48213,13127,48214,48215,22305,N,N,
+N,22308,22309,48216,22307,48217,18752,15923,22311,22310,22306,N,48218,N,N,
+22312,22313,N,48219,22314,N,N,N,22317,22315,N,22316,22318,N,12644,17518,22319,
+N,14202,12918,18230,N,22320,18043,19035,48220,22321,20270,N,48221,48222,48223,
+22322,19008,22325,20513,20529,48224,15408,18037,22326,N,13661,17444,12410,
+22327,18982,14640,48225,N,17232,48226,48227,N,17519,N,48228,48229,48230,48231,
+19567,14393,14412,48232,22328,N,48233,48234,22329,48235,22335,48236,15461,N,N,
+48237,17445,48238,13871,22330,N,N,48239,18731,48240,17222,48241,48242,22331,N,
+N,48243,48244,N,48245,22332,N,13872,N,22333,48246,22334,N,48247,22336,N,17782,
+48248,N,22337,22338,48249,22339,N,48250,22324,22323,N,N,48251,22340,14145,
+48252,48253,N,18727,48254,N,14924,18743,17446,18763,22341,N,48417,15924,12614,
+48418,22342,48419,48420,N,22343,48421,19570,48422,N,18528,48423,48424,22346,
+12669,16428,22345,22344,14146,16980,N,22350,22348,48425,22347,20007,14437,
+48426,N,48427,15737,22349,17740,15678,N,N,48428,17984,22353,22352,N,N,48429,
+48430,22351,N,22354,14438,48431,N,48434,N,N,48432,22355,18812,15707,48433,
+48435,22356,18553,48436,48437,48438,N,17985,17447,N,N,N,48439,17712,N,N,22357,
+13611,N,N,N,N,N,16180,48440,18732,N,48441,48442,48443,N,48444,13431,18214,N,N,
+48445,48446,48447,48448,48449,N,22358,15190,19258,19259,N,N,12670,22363,48450,
+N,17257,48451,48452,N,22360,N,N,N,48453,48454,48455,12919,48456,48457,48458,
+48459,22573,22362,48460,48461,N,18224,48462,N,22361,N,48463,22359,48464,14714,
+N,22365,48465,N,N,48466,N,N,48467,22371,22377,22369,N,17756,48468,48469,22374,
+18781,48470,48471,22368,48472,22373,20071,15191,N,48473,16981,22366,N,N,48474,
+13662,22376,16429,12645,22370,12920,22375,N,48475,N,13873,N,22372,N,48476,N,
+48477,N,N,N,N,22378,N,N,N,N,N,48478,22380,22390,22388,N,N,22385,48479,48480,
+48481,22384,20088,48482,22386,N,N,13874,48483,14641,N,48484,15738,48485,48486,
+N,22393,22379,N,N,48487,N,22383,22367,48488,12922,22387,22389,17233,N,48489,
+14888,12856,22381,22392,22391,13875,N,16937,13158,48490,N,N,N,14147,N,22382,N,
+N,N,N,N,N,48491,48492,N,22394,48493,22397,22561,N,48494,N,48495,15421,48496,
+22567,17520,22395,48497,N,N,48498,22565,48499,12921,48500,22563,22564,48501,N,
+22398,22562,N,48502,48503,14439,19754,N,48504,13365,48505,48506,12633,22566,
+48507,18234,12333,N,N,N,N,N,48508,48509,18529,22364,22572,22576,19557,48510,
+22569,N,N,48673,17769,22574,48674,N,N,N,48675,N,48676,15984,22575,18007,48677,
+48678,48679,48680,N,N,48681,48682,N,20295,N,22571,48683,48684,N,N,22577,48685,
+14715,48686,16459,48687,48688,12372,22570,22568,48689,16730,N,48690,N,22396,
+15156,N,N,N,N,N,N,N,16966,22589,48691,16731,22584,48692,22581,22582,48693,
+15462,22585,22588,48694,48695,22583,15653,48696,22586,N,N,22580,48697,19580,
+19579,48698,N,48699,22590,22591,12373,48700,48701,48702,48703,48704,22579,
+48705,48706,N,48707,13938,12326,48708,N,48709,13366,N,22587,48710,N,N,N,N,
+22595,22594,N,48711,48712,22599,N,N,N,48713,48714,N,N,22600,48715,48716,48717,
+N,48718,N,N,22598,22601,22593,22597,N,48719,22602,N,22603,48720,48721,22592,
+15228,48722,22596,16982,14642,22578,16181,N,N,N,N,22616,N,19049,N,N,22606,
+22607,22608,N,N,22615,48723,22614,48724,N,19325,13367,N,22612,N,14149,13108,N,
+N,22609,48725,N,20024,22611,12374,22613,48726,22604,22610,22617,14148,22605,
+48727,N,N,48728,48729,N,19805,48730,48731,48732,19755,48733,48734,N,N,22620,N,
+N,22624,48735,N,48736,16766,N,20089,22625,48737,48738,22622,N,22619,48739,
+48740,22618,22623,N,48741,48742,N,48743,48744,N,N,N,18992,48745,N,17972,48746,
+14150,48747,22626,22621,48748,22627,N,N,N,14203,N,N,N,12849,N,48749,48750,
+22635,N,48751,N,13368,N,48752,48753,48754,22633,N,N,22634,14889,22632,22630,
+22629,22636,22628,22638,48755,48756,12923,N,N,N,N,48757,N,N,N,N,N,N,48758,
+48759,48760,48761,N,48762,48763,22640,N,48766,22639,48764,N,48765,N,N,48929,
+48930,N,48931,N,N,17448,N,22643,N,22641,22631,14204,N,22642,N,22646,22645,
+22647,22644,22648,48932,N,48933,48934,N,N,48935,22649,22650,19050,N,22652,
+22651,15679,N,16430,12902,12924,48936,22653,48937,12351,N,N,N,16460,22654,
+48938,27715,22817,14177,48939,22818,48940,48941,N,N,16495,48942,N,48943,22819,
+48944,N,N,22820,13626,22821,N,22822,22823,16983,N,N,N,14413,48945,N,19553,N,
+48946,N,19260,15722,22824,48947,48948,48949,N,48950,16496,28221,18530,N,15466,
+48951,14925,22825,N,48952,48953,48954,16967,48955,18983,48956,N,17009,N,48957,
+22828,48958,N,22826,N,22829,N,N,22827,48959,N,N,N,22830,N,N,N,N,48960,18993,
+48961,N,12343,N,48962,N,N,18782,N,N,18531,48963,N,22831,48964,22834,15925,
+13627,N,22832,22839,15926,N,N,N,N,22833,18244,N,N,48965,48966,48967,48968,
+19806,22835,22836,22840,17770,22837,14643,16478,N,N,22854,18484,N,17010,N,N,N,
+N,N,N,N,48969,N,48970,N,N,18532,23085,N,N,N,N,19066,N,48971,N,17521,48972,
+48973,N,19317,48974,22843,12833,17258,48975,48976,N,N,22852,N,48977,17204,
+22846,22853,22848,22855,22851,N,22850,18287,48978,22844,12925,22842,13681,
+17011,22838,48979,48980,22841,14644,16475,48981,15927,22849,18258,N,N,13682,
+13128,N,N,N,N,N,N,N,N,48982,N,13159,16161,22857,22862,N,22858,48983,14205,
+48984,22863,15138,14697,N,N,N,N,48985,48986,15654,22845,15229,22860,48987,
+48988,N,N,15192,22861,12356,48989,48990,22856,48991,N,N,48992,17449,N,48993,N,
+N,48994,N,48995,13683,N,N,N,N,N,13876,N,N,N,N,N,N,N,22859,12327,48996,48997,
+14915,N,48998,N,16182,N,N,N,N,N,48999,49000,N,N,49001,17522,N,49002,18516,
+22865,16734,N,49003,49004,49005,49006,N,49007,N,N,16938,49008,49009,15147,
+22866,49010,22868,22864,N,49011,49012,49013,19041,N,17469,49014,N,N,49015,
+16732,N,N,N,N,N,N,N,N,49016,49017,19067,15438,22880,N,22879,49018,49019,16248,
+N,N,49020,14206,N,49021,49022,22873,15929,49185,N,18024,18225,49186,49187,N,
+49188,22871,N,49189,16733,49190,N,N,49191,15480,22876,49192,N,15928,N,22870,
+22875,49193,N,18259,N,49194,49195,22869,N,14113,49196,49197,13149,N,N,49198,
+22877,20011,14926,17205,22874,49199,16476,49200,14645,16228,12646,16700,22872,
+13637,49201,49202,49203,N,N,14151,N,17487,22878,N,N,N,N,N,16735,N,49204,22881,
+N,22883,49205,N,16951,22889,49206,22884,N,49207,22886,N,N,N,N,49208,18753,
+17523,49209,22887,49210,49211,49212,19756,N,N,N,19784,13369,49213,N,N,N,49214,
+12334,N,22885,N,49215,N,N,N,22882,49216,N,49217,N,13432,N,N,N,49218,49219,
+12647,49220,22888,N,49221,49222,19785,22892,N,N,49223,49224,N,N,16955,N,22899,
+49225,N,49226,22893,49227,N,22890,22897,49228,N,N,N,22867,N,49229,N,49230,N,
+49231,N,49232,49233,22894,N,22898,49234,49235,N,18498,17771,N,49236,49237,N,N,
+N,22891,49238,22895,N,N,N,14152,N,N,49239,14961,49240,N,N,16477,N,N,N,N,N,N,N,
+N,49241,N,N,22903,49242,N,49243,49244,49245,49246,N,N,N,17702,N,49247,49248,
+49249,49250,N,49251,49252,49253,N,49254,N,N,N,22900,N,19296,N,N,N,49255,N,
+22901,N,N,N,49256,49257,N,22902,N,19534,N,16418,49258,N,49259,N,N,N,N,N,14178,
+N,49260,N,49261,22909,N,N,N,N,N,N,49262,49263,49264,15157,22906,N,22905,N,N,
+49265,49266,18226,49267,N,49268,17973,49269,N,49270,N,49271,17713,22907,49272,
+N,49273,22908,N,18799,49274,18245,15139,N,16497,N,19280,49275,N,N,N,N,N,13129,
+N,23077,22910,49276,49277,49278,N,19786,23079,N,49441,23075,N,23076,N,49442,
+49443,49444,49445,16736,49446,N,49447,49448,23074,N,22847,49449,N,49450,23078,
+N,23073,N,N,N,N,N,23083,23084,17703,23086,49451,49452,15140,23081,N,49453,
+49454,N,13628,49455,N,23087,49456,23080,23091,N,23090,49457,23089,49458,N,N,
+23092,49459,N,23094,15985,49460,23093,49461,N,N,49462,23097,N,N,49463,49464,
+49465,N,N,N,N,49466,N,N,N,49467,49468,N,49469,N,23095,49470,N,49471,23096,
+22896,49472,49473,N,N,49474,23099,23098,N,49475,N,N,49476,22904,23100,23088,N,
+49477,15193,N,49478,N,N,23101,23102,23104,23103,23105,12926,49479,14646,49480,
+49481,19068,16431,N,N,N,49482,N,14414,N,49483,23107,49484,N,N,N,23110,N,18770,
+49485,13663,49486,N,49487,23109,23108,18260,23111,13877,N,N,N,23113,23112,
+49488,49489,N,13370,15158,N,N,18008,49490,N,N,N,49491,14153,N,N,N,16244,N,
+23114,N,16432,17704,N,18783,23115,N,49492,N,N,49493,N,N,N,49494,23116,23117,N,
+49495,N,19000,21853,16454,49496,N,18764,N,14936,N,18533,18499,49497,N,N,49498,
+N,17741,49499,20033,N,23119,15440,49500,N,23120,49501,12342,N,49502,13908,
+16461,49503,18784,N,N,N,23121,15170,17223,49504,15195,16183,N,49505,49506,
+49507,N,N,23122,N,19069,N,N,12663,15196,N,49508,N,23125,49509,23123,23126,
+20025,23124,N,49510,49511,N,16507,23127,N,49512,16946,49513,N,23128,N,49514,N,
+49515,13434,49516,23130,N,23129,N,N,N,49517,23131,23132,13435,N,N,18044,17206,
+13676,15197,16737,N,N,15708,12336,N,N,49518,23133,49519,N,49520,49521,N,N,N,
+49522,12834,23137,N,N,49523,49524,49525,N,14647,23136,49526,N,14891,15930,
+49527,49528,23135,N,15931,49529,19520,14890,N,49530,49531,12375,16462,49532,
+49533,N,N,N,N,N,23142,49534,49697,16433,12615,49698,49699,49700,49701,15701,
+49702,19302,14962,49703,49704,49705,49706,15932,49707,16423,49708,49709,N,
+49710,23141,23139,23140,49712,N,49711,N,N,17259,N,N,23334,49713,23146,15230,
+14648,23144,49714,49715,N,N,23145,49716,16184,49717,N,49719,23143,N,49718,
+15151,N,N,N,N,49720,49721,49722,N,49723,49724,23148,23147,23152,49725,49726,
+23153,N,23149,N,13090,23150,23151,18517,49728,49729,49730,N,18785,14154,23154,
+N,N,49732,16434,49733,15933,49735,49736,49737,17234,49738,49740,N,49731,49734,
+49739,13895,N,23155,23159,N,N,12875,23156,23158,N,49741,49742,49743,23157,N,
+49744,15723,49745,N,N,N,17224,12357,23160,49746,49747,49748,49749,23161,N,
+49750,49751,N,17450,N,49752,N,20081,N,N,N,N,15171,N,49753,19051,N,N,49754,
+49755,N,19261,49756,N,N,23330,23163,N,49757,23166,N,23165,49758,49759,23162,
+49760,49761,23329,N,N,18014,49762,23164,N,N,49763,N,49764,49765,N,N,N,N,49766,
+N,23331,N,N,15724,23332,49767,19787,18296,N,49768,23333,N,N,N,N,N,23335,N,
+49769,23336,N,49770,49771,N,49772,N,23337,N,13898,12616,14649,23338,N,23339,
+15729,16738,49773,49727,21080,16702,16701,16984,14919,N,N,20594,N,49774,N,
+49775,14190,19757,N,19070,N,18814,49776,23340,N,N,N,49777,14963,17471,23341,
+20271,N,49778,N,19262,49779,17451,23342,13436,49780,N,49781,N,N,N,23343,23344,
+19546,N,19492,19318,19292,15141,23346,N,N,15467,N,49782,19281,N,23348,23351,
+23350,N,13433,N,N,13664,49783,23347,N,23349,N,N,N,49784,23352,49785,49786,
+16249,N,N,49787,N,19835,12361,14944,16956,N,15453,49788,49789,15987,N,N,23355,
+N,N,17742,49790,23353,16939,23354,15986,19549,23356,23357,19816,49953,N,N,N,
+23362,N,49954,14650,49955,18261,23359,17772,23134,23138,49956,13647,49957,
+18247,N,N,N,49958,23361,N,15934,18500,N,49959,N,N,49960,23367,N,18554,N,23358,
+N,23364,23363,N,49961,49962,16463,49963,N,49964,N,19309,49965,20051,49966,
+49967,19303,49968,12876,15198,N,N,20296,23366,16245,N,N,N,23365,N,N,23360,N,N,
+N,N,N,14415,49969,49970,49971,23372,23370,49972,12877,23368,23374,23380,N,
+49973,49974,49975,N,N,49977,16968,49978,49979,19009,49980,23382,N,49981,49982,
+18722,N,N,N,23381,18288,19263,13371,49983,16503,15680,N,N,49984,17491,49985,
+19758,N,49986,23377,23376,N,N,49987,23378,N,23375,N,49988,23383,N,23373,N,N,
+23371,N,23379,23369,49989,17260,49990,19576,15430,14964,49991,49992,N,49976,N,
+14906,N,N,19311,13121,17486,17994,12617,N,N,N,N,N,N,N,N,N,N,N,N,N,N,16498,
+49994,N,16436,14122,N,49995,N,N,N,49996,23385,49997,N,14651,13180,N,N,N,N,
+49999,49998,23387,13172,23393,50000,50001,N,50002,50003,50004,23390,50005,
+16499,N,N,N,13131,14892,N,50006,13130,14927,N,50007,23388,14181,14155,17773,
+50008,50009,23386,N,12358,N,50010,N,50011,23389,23391,N,13901,14124,49993,
+13372,13643,50012,N,50013,50014,23394,N,50015,14969,19313,N,15159,N,N,N,23395,
+N,N,N,18736,N,N,N,50016,N,N,50017,50018,50019,50020,50021,N,23407,50022,12851,
+23396,N,50023,50024,50025,50026,N,23413,23397,N,20034,50027,23404,50028,18271,
+50029,N,50030,N,N,N,N,23412,N,23399,N,N,N,12340,23401,N,50031,14652,50032,N,
+50033,23403,50034,23402,N,23398,23409,50035,15935,50036,N,50037,21613,14440,
+19836,50038,50039,N,N,23400,50040,17524,13091,14893,50041,23392,N,23408,13153,
+N,N,23406,23410,50042,17774,N,N,N,N,N,N,N,13438,50043,23602,N,50044,19529,
+23415,13437,50045,23422,N,50046,50209,50210,19264,50211,23585,23587,50212,
+23591,23417,50213,17194,N,50214,50215,N,17775,23595,23420,N,23592,N,50216,N,
+23586,50217,N,50218,50219,50220,50221,16185,23596,50222,50223,16435,N,N,50224,
+50225,N,N,23594,13373,50226,50227,50228,20304,23414,N,N,23590,12376,50229,N,
+23416,50230,50231,19514,23421,16162,17479,23411,50232,50233,23589,50234,N,N,
+50235,50236,N,16250,23599,13169,14369,N,N,N,N,23601,23418,23600,N,23593,23419,
+N,23597,N,23598,N,N,N,N,N,23615,50237,N,50238,17998,50239,23588,N,50240,23611,
+N,50241,N,23613,N,17496,N,N,50242,N,N,50243,N,N,N,50244,19788,N,N,N,50245,N,N,
+N,N,18806,23608,16970,N,50246,N,23614,16703,50247,23605,23618,23617,N,18031,
+23616,18026,50248,50249,50250,50251,N,50252,50253,23620,23607,50254,13896,
+23610,15709,50255,50256,50257,18272,23612,13899,N,23604,23606,23603,50258,
+50259,20272,13146,23609,50260,50261,23619,13109,N,N,N,N,N,N,N,14951,N,N,50262,
+12637,N,N,23636,50263,N,20273,23639,50264,N,50265,N,N,16186,23638,N,N,N,23637,
+50266,N,N,N,50267,50268,23634,50269,N,N,50270,N,50271,23622,50272,N,23651,
+23621,N,23640,N,N,50273,50274,N,50275,23632,50276,N,23627,23624,N,23625,N,
+23633,N,50277,N,29730,50278,N,23630,14653,17480,16740,23628,N,23623,50279,N,
+23626,N,N,50280,50281,19789,19306,N,N,N,23631,23641,N,N,N,50282,N,N,50283,N,
+23649,23642,N,N,23655,N,23653,50284,50285,N,50286,23648,50287,N,50288,N,N,N,
+23647,N,17488,N,16741,50289,23645,50290,50291,23643,50292,N,23650,N,N,N,N,
+23656,18549,23662,N,N,50293,N,50294,23657,23660,23654,50295,N,17268,N,18744,
+50296,23644,N,50297,23652,15936,50298,19535,23672,23659,50299,N,N,N,50300,
+14370,12835,13151,N,N,23635,N,50301,N,50302,N,50465,15937,23664,50466,23671,
+15481,13170,50467,N,17198,50468,50469,N,N,N,N,23661,50470,50471,23666,23670,
+50472,50473,13878,N,N,50474,N,50475,50476,50477,N,N,50478,50479,N,13644,23668,
+N,50480,N,N,N,13601,N,17995,23667,N,50481,N,23669,50482,N,N,50483,N,N,N,N,N,N,
+50484,23663,50485,N,N,N,N,23665,N,N,N,N,N,50486,13152,17225,50487,N,50488,
+23676,N,50489,50490,N,50491,N,50492,N,23674,14441,N,23673,50493,N,N,N,N,N,
+23841,N,N,N,50494,23384,50495,50496,50497,23675,N,23677,23678,N,50498,N,N,N,N,
+23852,50499,23848,N,23405,50500,50501,50502,N,23847,50503,N,N,N,23846,N,N,
+23843,N,50504,50505,50506,N,23658,23845,23844,N,N,50507,N,50509,50508,N,N,
+50510,N,N,N,50511,23850,N,20262,50512,50513,50514,N,N,N,23853,13947,50515,
+50516,23849,23851,N,N,N,N,50517,N,N,50518,18471,N,23854,N,50519,N,N,N,50520,
+50521,50522,N,N,N,N,N,N,N,23858,23855,50523,50524,50525,50526,19827,23856,
+50527,50528,N,50529,23646,N,N,N,N,50530,50531,50532,23859,N,N,N,23860,50533,N,
+N,N,50534,N,12597,50535,23862,14183,15393,N,13909,50536,N,N,12836,50537,N,N,
+50538,50539,N,N,50540,N,N,19807,N,N,50541,50542,23864,23863,23866,13629,50543,
+N,13910,13374,50544,N,N,N,23869,N,N,50545,23868,N,23870,50546,N,12878,50547,
+17207,N,23871,N,50548,13375,23873,N,50549,N,50550,23872,N,23874,N,50551,N,
+23875,50552,23876,15199,16437,14881,N,18800,50553,N,19042,20292,50554,N,N,
+50555,15221,50556,N,N,14928,20082,50557,N,N,23877,23878,N,15200,N,50558,50721,
+23879,23880,N,50722,23882,23881,50723,19288,N,N,15710,15468,15172,N,23883,N,N,
+N,N,N,N,N,23885,16163,50724,23884,N,N,50725,N,N,23886,50726,50727,N,50728,
+50729,23887,N,N,N,50730,50731,23888,23889,50732,50733,50734,23890,50735,23892,
+23891,23893,12837,17226,N,23894,50736,50737,15142,13132,23895,50738,50739,
+17730,21580,N,N,50740,50741,13603,23896,N,N,50742,N,23897,50743,19052,19304,N,
+N,N,17991,23898,18534,N,50744,N,18555,N,50745,19539,N,N,N,23899,N,50746,N,
+50747,N,N,50748,50749,N,N,N,23901,23900,N,50750,23903,N,50751,N,23902,N,N,N,
+50752,N,50753,N,N,N,N,N,50754,50755,N,50756,50757,N,N,23905,50758,N,N,N,50759,
+50760,15201,50761,19505,50762,23906,23907,N,N,13604,N,50763,N,23908,N,N,N,
+50764,N,N,N,23910,23909,N,50765,50766,50767,N,N,N,50768,N,50769,N,N,N,N,50770,
+16229,50771,50772,18745,12618,N,50773,50774,N,N,18501,50775,17525,15681,13665,
+N,N,N,N,N,N,N,50776,50777,N,50778,18502,50779,15406,N,50780,N,50781,23912,N,
+13376,N,50782,12664,50783,50784,18034,23911,14654,17235,N,23913,N,N,N,N,50998,
+23921,N,23914,50785,N,50786,N,50787,16961,N,13666,23922,50788,N,50789,N,50790,
+50791,14184,50792,N,13605,23920,N,N,23918,23915,19808,N,50793,50794,50795,
+17472,50796,N,N,18009,23916,N,N,23924,N,23923,14115,50797,50798,12845,50799,
+50800,14907,23917,23919,50801,N,N,50802,N,19287,17012,N,N,N,N,N,N,N,N,19319,N,
+N,23932,N,50803,23933,50804,12879,50805,N,N,N,18984,19581,24097,15395,15938,
+23928,23934,12648,N,13879,50806,N,23925,23930,50807,N,N,16500,18289,N,18535,
+50808,N,50809,50810,50811,50812,23927,50813,19233,50814,23929,N,24100,50977,
+24098,50978,23931,N,N,50979,19234,18248,13667,N,17701,N,50980,17261,50981,
+24101,50982,50983,N,50984,24099,16985,23926,50985,12619,50986,50987,N,N,50988,
+N,N,50989,19790,24112,N,50990,50991,N,50992,24111,50993,N,N,N,16502,N,24108,
+50994,19820,N,N,17974,24102,N,N,N,N,N,17477,50995,50996,50997,12620,14655,
+24105,N,N,50999,51000,N,51001,15655,24110,N,24109,24104,N,24107,51002,N,13160,
+51003,24106,18249,51004,N,20014,N,N,15988,16501,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,51005,N,24118,24116,N,18765,N,51006,51007,N,51008,N,24113,24115,51009,
+12602,51010,N,14656,20274,N,13117,N,18786,51011,51012,N,N,N,19809,N,N,13092,
+16187,24117,N,N,51013,N,N,N,N,N,51014,N,N,24122,N,51015,15939,N,N,N,19760,N,
+24119,N,N,51016,51017,24114,51018,24120,51019,51020,51021,20062,N,17779,17986,
+N,N,N,N,N,N,N,N,N,N,N,N,N,51022,N,51023,N,N,13110,N,N,12629,N,51024,24126,N,
+51025,24129,51026,N,N,20035,51027,N,51028,19812,N,N,N,51029,24136,24130,24127,
+51030,N,51031,20052,24133,N,51032,51033,N,15690,24135,N,N,24140,51034,N,17777,
+24138,N,51035,N,51036,24132,51037,51038,17208,51039,N,24139,51040,24128,N,
+24134,51041,24141,12412,24131,N,24142,51042,51043,16188,N,15711,51044,18981,
+51045,14894,N,24123,24137,17722,51046,51047,N,N,N,51048,16438,N,13161,14929,
+15940,24125,15682,N,N,N,N,N,N,N,14156,N,24124,N,N,N,24146,15725,14394,N,24161,
+51049,24155,13684,17743,51050,24150,24159,12335,12594,51051,N,12857,N,24152,
+16940,24143,24145,14657,N,N,51052,N,N,N,51053,N,24162,51054,24157,51055,51056,
+N,24149,N,N,N,N,24156,51057,51058,N,N,51059,51060,19499,51061,N,24154,24158,
+51062,N,51063,51064,51065,51066,N,14416,51067,15941,N,N,17209,51068,51069,
+51070,24148,N,N,51233,51234,N,N,N,19759,51235,N,N,24151,N,N,24144,17778,N,N,
+24147,51236,N,N,24153,N,N,N,N,51237,N,51238,20305,15422,19326,N,24163,N,N,N,N,
+N,N,N,N,N,18478,51239,N,24175,14395,N,N,51240,N,N,15712,N,24165,51241,N,N,
+20015,14658,N,24178,51242,N,12398,N,N,24176,N,51243,N,N,24164,N,N,51244,51245,
+24170,N,51246,24172,51247,N,N,19791,24167,N,N,17710,51248,N,24169,N,51249,
+51250,51251,24177,51252,24171,19527,N,51253,51254,24166,51255,15394,24190,
+51256,51257,51258,N,13162,N,24168,24173,24174,N,N,N,N,N,N,N,17004,16986,N,N,N,
+N,N,N,N,N,N,N,N,N,51259,24182,51260,51261,24188,N,N,24186,N,17705,N,N,24355,
+24183,51262,N,51263,N,51264,24184,24160,13689,18746,N,51265,N,15423,N,51266,
+14711,51267,N,51268,51269,N,20275,N,24180,N,24354,12649,16742,51270,N,51271,N,
+51272,51273,N,N,N,N,18297,N,13377,20090,N,N,51274,N,N,51275,51276,19489,17490,
+51283,N,51277,51278,24187,24189,51279,N,N,51280,N,16690,N,N,51281,51282,N,
+24353,24185,N,24179,N,N,N,13379,N,N,N,N,N,N,N,N,N,51284,N,51285,51286,51287,
+14185,N,N,51288,24367,51289,51290,24362,16504,51291,51292,13155,N,51293,51294,
+N,15713,N,24371,N,51295,N,N,N,51296,24364,17452,24361,17497,N,N,N,24396,N,N,N,
+24358,N,24357,N,24366,51297,51298,N,24360,24359,24365,51299,16417,N,24356,
+51300,51301,N,N,51302,51303,51304,24368,N,51305,24369,51306,51307,51308,N,
+51309,13378,N,N,51310,N,N,N,N,51311,51312,24374,N,24373,24375,51313,51314,
+51315,51316,N,24378,N,N,N,51317,51318,51319,17731,N,24372,N,51320,51321,N,N,
+24376,N,N,51322,N,N,N,14179,17017,24370,18235,N,51323,24377,51324,51325,N,
+51326,N,N,N,N,N,N,N,N,N,24382,24380,N,N,24383,N,51489,24386,N,N,51490,24379,
+14698,18216,N,N,24121,N,N,N,51491,51492,N,19828,24381,N,24385,17013,51493,
+24384,N,24363,N,51494,28521,N,N,51495,24389,N,51496,51497,24393,51498,24391,N,
+N,N,51499,51500,51501,N,24387,N,24388,N,51502,N,24392,N,24390,N,N,N,18766,N,
+51503,24398,N,24395,24394,N,24397,18004,24399,51504,N,N,51505,N,N,17269,17005,
+N,N,N,N,16421,N,N,51506,24400,N,24402,N,51507,N,N,51508,N,51509,N,N,51510,N,
+24401,N,N,N,N,51511,51512,N,N,N,51513,51514,51515,51516,24181,N,51521,N,N,
+24403,N,N,51517,51518,N,N,18023,N,N,N,N,51519,51520,N,N,N,N,24404,51522,51523,
+N,N,N,N,N,12880,51524,N,51525,17780,13093,N,N,N,N,51526,51527,N,13668,N,N,N,
+15454,14930,51528,N,N,51529,N,N,N,51530,51531,N,N,20263,16230,N,N,N,12650,N,N,
+N,24406,N,51532,51533,51534,51535,51536,24405,N,51537,N,N,N,N,N,N,N,N,51538,N,
+N,N,N,N,N,51539,24409,17210,24412,24407,51540,51541,N,24411,51542,N,N,51543,
+24410,17728,12377,N,N,N,N,N,N,N,N,N,N,N,N,N,20085,N,51544,24414,N,N,N,12584,N,
+51545,N,51546,51547,51548,51549,N,51550,24416,N,N,51551,24415,N,24413,N,N,N,N,
+51552,N,N,N,N,N,N,N,N,N,N,N,N,24408,N,N,N,N,N,N,N,19235,51553,N,N,24418,51554,
+51555,51556,51557,51558,N,24417,N,51559,51560,N,N,51561,N,N,N,N,12651,N,N,N,N,
+24420,18994,N,24419,N,51562,N,51563,19509,N,N,N,N,15943,N,N,N,N,51564,N,51565,
+N,51566,51567,51568,N,N,N,N,16691,N,51569,N,N,N,15942,N,N,N,N,51570,N,N,N,
+51571,51572,51573,N,20091,51574,51575,24426,N,16505,N,51576,N,51577,N,N,24422,
+24427,51578,N,12652,51579,N,51580,N,51581,N,51582,N,24425,N,18273,24421,24424,
+15944,51745,18513,N,N,24428,N,15441,N,N,N,N,N,N,N,N,N,N,51746,N,N,N,16506,N,N,
+51747,N,N,N,24431,51748,N,51749,24423,N,14119,N,51750,N,N,24429,N,N,51751,N,
+19792,24432,N,N,N,29734,51752,51753,N,N,N,15695,51754,N,51755,N,N,N,N,N,24433,
+N,N,N,24434,N,N,51756,51757,18222,51758,51759,N,N,N,N,N,24436,51760,N,N,N,
+24437,51761,51762,51763,N,18227,51764,N,N,N,17781,24439,N,51765,51766,N,24441,
+N,20053,N,24438,51767,24440,12653,51768,24435,N,51769,51770,N,51771,N,N,21339,
+24442,N,N,N,N,16743,15160,24444,N,N,N,N,24443,16164,21081,N,N,N,N,N,N,24445,N,
+N,51772,24609,N,24430,24446,N,51773,24610,51774,N,N,N,N,N,18298,51775,51776,
+51777,N,N,N,24611,N,N,24612,N,N,51778,N,N,N,51779,N,N,51780,24613,N,51781,N,
+51782,N,N,N,N,51783,N,N,N,24614,N,17502,51784,24616,24615,N,51785,24617,N,
+24618,N,51786,15455,18787,N,51787,51788,19564,24619,24620,16726,15396,24621,
+24622,51789,51790,51791,N,51792,24623,19026,18503,N,N,24624,18263,N,51793,
+51794,51795,N,17453,51796,N,51797,51798,N,24625,12903,51799,13677,51800,19526,
+51801,19510,51802,12852,20276,51803,N,N,N,19282,51804,18986,N,51805,N,N,51806,
+51807,N,51808,16439,N,24626,N,N,51809,51810,17987,N,51811,51812,14371,24627,
+51813,14932,24629,24628,N,51814,N,N,24630,N,51815,N,N,N,51816,51817,N,N,N,
+24631,51818,N,N,24632,N,N,N,N,51819,N,N,N,N,13630,N,24633,N,N,N,N,24634,51820,
+N,N,N,14372,51821,51822,18504,N,51823,24636,N,51824,N,15989,N,N,24635,N,N,N,N,
+51825,N,N,51826,13880,24637,24639,N,24638,51827,N,51828,N,N,51829,N,24640,N,
+14417,N,24641,N,N,51830,51831,13929,51832,16704,N,14717,N,N,N,51833,24643,
+24644,24642,N,N,51834,N,N,N,15469,N,N,17992,13881,N,N,N,N,N,51835,51836,N,N,
+24646,17196,24645,51837,51838,20277,18274,52001,52002,N,52003,52004,N,52005,N,
+N,24649,52006,N,52007,N,N,N,N,52008,52009,N,N,24651,24648,52010,52011,N,19540,
+24650,24652,52012,20036,N,N,52013,N,52014,24656,N,52015,52016,24655,17270,
+18221,52017,N,14373,24654,N,52018,52019,N,24653,52020,19761,19762,N,N,52021,
+52022,N,52023,24657,12654,N,N,N,52024,14710,15202,N,N,N,N,N,N,N,52025,24658,
+24659,52026,N,52027,N,N,N,52028,24661,52029,N,N,N,N,52030,52031,52032,52033,N,
+N,15683,N,N,52034,52035,24663,52036,24662,52037,52038,N,52039,52040,24664,
+52041,13133,N,N,24666,N,52042,24665,52043,24668,24667,52044,N,N,N,52045,52046,
+N,52047,14396,52048,52049,20008,N,13900,N,12838,N,N,52050,N,52051,N,N,52052,N,
+52053,13930,52054,52055,N,N,N,52056,N,52057,52058,52059,N,52060,N,N,52061,
+52062,N,N,13409,52063,52064,N,52065,N,N,N,N,20072,24670,N,52066,N,52067,N,
+52068,N,24672,52069,52070,N,52071,24673,N,12881,N,N,52072,52073,N,24669,52074,
+15161,52075,52076,17473,24671,52077,N,N,52078,52079,N,N,52080,N,N,52081,N,N,N,
+52082,24676,N,15470,52083,N,52084,N,24674,52085,52086,N,52087,14142,N,N,18505,
+24675,N,N,24702,N,N,52088,52089,N,52090,24681,52091,52092,52093,N,52094,14397,
+52257,52258,52259,N,13669,52260,24678,19837,52261,N,20016,52262,N,N,N,N,N,N,
+52263,N,N,N,N,N,N,N,N,52264,52265,N,N,N,N,N,N,17014,N,52266,24680,52267,N,
+52268,52269,52270,52271,52272,52273,52274,52275,52276,52277,24682,20054,13911,
+18556,18250,N,N,52278,24683,N,N,N,N,24685,52279,24688,N,52280,52281,N,52282,
+52283,N,N,N,52284,N,52285,N,N,N,52286,52287,N,N,24684,N,52288,N,24687,14442,
+12621,24689,52289,16240,24686,20060,N,52290,24692,29732,N,52291,52292,52293,
+24690,24693,52294,N,52295,52296,24679,24691,52297,52298,14908,N,N,24694,N,N,N,
+N,N,N,N,24695,N,52299,52300,N,19838,N,52301,52302,52303,N,52304,N,24696,N,N,N,
+52305,52306,52307,52308,N,N,N,N,N,52309,52310,52311,N,52312,N,24697,52313,
+52314,52315,24677,52316,N,N,52317,24698,52318,52319,52320,52321,N,N,52322,
+52323,13380,52324,52325,N,N,52326,N,N,N,52327,N,52328,N,15397,N,52329,N,N,N,N,
+N,N,N,N,52330,52331,24699,N,52332,N,N,24700,52333,N,N,52334,24701,N,N,N,52335,
+N,52336,52337,12603,N,52338,52339,24865,N,18747,24866,52340,N,13348,24867,
+52341,24868,52342,52343,N,N,24869,52344,24871,24872,24870,N,52345,N,18771,
+24874,24873,N,52346,52347,52348,N,N,52349,24876,24875,24877,52350,N,N,N,N,N,
+24878,24880,24879,N,N,14713,52513,24882,N,24881,52514,52515,13381,N,16211,N,
+17724,N,24883,16440,52516,52517,N,15162,52518,12665,24884,52519,19793,52520,
+52521,19043,24885,N,N,52522,17732,19763,14659,16189,N,N,52523,17227,21044,
+52524,17454,12904,24886,52525,52526,52527,52528,N,N,52529,24887,N,24892,52530,
+52531,24890,24889,23106,13094,24888,52532,12378,52533,18474,52534,N,18506,N,N,
+52535,N,20017,24893,24891,17244,16422,52536,52537,18475,52538,18733,N,24895,
+20012,14157,24896,N,24894,18518,24897,N,24898,N,52539,12379,52540,N,15990,
+24903,N,24900,18029,24899,52541,52542,52543,52544,52545,52546,13606,N,52547,
+24906,N,N,52548,24901,24902,N,24905,24904,18725,N,N,16706,16705,52549,13631,
+52550,52551,24907,52552,N,N,N,52553,24908,N,52554,24909,N,N,N,N,52555,24911,
+52556,24910,N,N,N,N,N,12630,N,N,N,N,N,24919,18536,24913,52557,24915,N,N,24917,
+16190,52558,N,24918,24916,15424,52559,52560,52561,24912,24914,52562,18754,
+52563,15945,N,N,24921,N,52564,24920,52565,52566,N,N,24922,N,15398,14895,N,
+52567,17783,24923,N,17483,52568,N,24925,52569,52570,52571,20001,24924,52572,N,
+N,52573,N,16745,N,N,52574,N,52575,52576,24930,52577,24932,24933,17236,N,N,N,N,
+52578,24931,N,24928,N,24926,24927,52579,24929,52580,52581,52582,N,N,52583,
+52584,24936,52585,24934,52586,24935,N,52587,N,N,52588,52589,N,52590,52591,N,N,
+52592,N,52593,52594,52595,52596,24937,24939,24940,24941,52597,24942,52598,
+52599,24938,N,52600,N,N,N,52601,N,N,24944,N,52602,52603,24943,52604,N,N,52605,
+52606,52769,24945,52770,N,N,N,52772,52773,20037,52774,52775,52776,24948,24946,
+24947,52777,52771,52778,13410,N,N,N,N,N,19582,N,N,52779,19018,N,24950,52780,N,
+N,24949,N,N,52781,N,24951,24952,N,52782,52783,N,24956,24953,24954,24955,N,
+24957,52784,52785,52786,24958,52787,25121,N,52788,N,25122,N,25123,N,18479,
+17744,25124,18290,18740,N,25125,52789,N,25126,17706,52790,13095,14660,25127,N,
+N,25128,52791,52792,25129,N,15145,N,N,25131,N,52793,25130,N,N,25132,25133,
+52794,52795,52796,N,52797,52798,N,52799,52800,52801,52802,52803,52804,52805,N,
+52806,N,N,52807,18537,N,25134,N,N,N,25135,N,N,29545,25136,25137,25138,N,N,
+52808,N,15150,N,52809,25139,18262,N,52810,19295,N,12622,52811,12631,52812,
+52813,25140,52814,N,N,N,25142,N,52815,N,25141,17776,N,52816,N,16441,23865,N,
+25143,19521,52817,25144,N,13382,18519,25145,52818,25146,52819,N,25147,N,52820,
+N,19548,N,52821,52822,19541,N,17470,N,52823,N,16746,52824,N,25149,52825,N,
+15714,52826,15946,N,N,25152,N,52827,25151,25150,18557,52828,13383,14377,N,
+52829,N,N,N,52830,N,52831,52832,N,52833,N,52834,52835,25158,52836,N,25155,
+16191,19506,N,52837,N,25154,25156,25157,N,52838,25153,N,N,N,52839,52840,52841,
+N,N,N,N,52842,52843,52844,25159,25160,52845,17455,N,13411,52846,52847,N,17253,
+N,52848,N,N,52849,52850,25161,N,N,52851,N,N,52852,52853,52854,N,N,52855,N,N,N,
+52856,52857,N,N,25162,25165,52858,N,52859,52860,52861,16231,52862,17988,53025,
+25166,19283,53026,25163,N,53027,25164,53028,N,N,N,53029,N,53030,53031,53032,N,
+N,N,N,25169,53033,N,N,53034,25168,25167,53035,N,N,N,53036,N,N,N,N,N,N,25171,
+53037,53038,25170,N,N,25172,N,N,53039,53040,53041,N,N,N,53042,N,N,N,25174,
+53043,25173,N,53044,N,N,19021,N,53045,N,N,53046,N,15702,20038,53047,53048,
+25175,53049,N,17975,N,53050,25176,N,N,25177,N,25181,25179,25180,53051,25178,N,
+N,N,53052,N,N,N,25182,N,53053,N,N,N,25183,N,N,N,53054,53055,N,N,53056,N,25184,
+N,53057,25185,19511,25186,N,53058,53059,53060,N,19568,25187,53061,17230,53062,
+18282,N,13931,53063,N,53064,17211,25188,13882,53065,53066,N,16464,53067,N,N,N,
+53068,N,N,53069,25189,14909,N,N,53070,53071,N,N,53072,N,N,25190,53073,53074,N,
+N,53075,25191,N,14374,14933,N,N,N,N,N,N,N,53076,N,N,25193,53077,53078,53079,N,
+17750,14934,13646,N,N,N,N,N,53080,53081,N,53082,N,19236,N,18251,53083,N,53084,
+N,N,17751,N,N,N,N,14684,N,N,N,53085,53086,25195,N,53087,53088,N,N,N,53089,N,
+53090,N,N,N,53091,N,N,N,N,N,N,N,N,N,53092,15947,53093,N,53094,53095,N,53096,
+53097,N,N,N,53098,N,53099,20018,14661,N,53100,14375,N,N,18467,N,25197,N,N,N,N,
+N,53101,N,25199,N,53102,N,N,14443,N,N,N,N,25198,17526,N,N,53103,N,25201,13111,
+25196,53104,N,18538,N,12592,53105,14956,N,20306,53106,N,25200,N,N,53108,53109,
+53110,N,53107,N,25202,53111,N,N,19019,53112,16473,25204,N,53113,53114,N,25205,
+53115,53116,53117,53118,N,25203,N,N,N,N,13134,53281,25211,53282,25210,53283,N,
+15399,N,N,N,25212,25207,53284,53285,53286,25213,25208,53287,N,53288,N,18520,
+25206,53289,53290,25209,53291,53292,N,N,N,25378,53294,N,N,N,53295,53296,53297,
+N,N,53293,N,53298,25377,19297,N,53299,N,25214,N,N,12395,N,N,53300,53301,25380,
+N,53303,53304,N,N,53305,53306,N,25379,N,53307,53302,15948,N,N,N,N,53308,25381,
+N,N,N,N,53309,N,16707,N,53310,25383,25382,N,N,N,N,N,N,25384,53311,N,53312,N,
+53313,53314,53315,N,N,N,N,53316,25192,53317,N,53318,25194,25386,25385,53319,N,
+N,N,53320,N,N,53321,53322,N,N,N,N,15400,53323,20073,53324,15442,53325,25387,
+14135,N,N,53326,53327,53328,13632,13607,15203,53329,53330,N,N,N,53331,19764,
+53332,N,25393,53333,25392,16708,25389,53334,N,25391,53335,53336,15691,16192,
+25390,25388,N,18218,N,N,15949,N,53337,18748,53338,N,53339,N,14935,N,N,N,N,
+53340,N,N,N,N,17784,N,53341,25394,53342,53343,N,53344,25395,25417,13912,N,N,
+20285,16693,N,N,N,N,25396,53345,53346,12882,17527,18977,N,53347,N,53348,53349,
+53350,53351,N,53352,N,N,53353,53354,25397,N,N,N,53355,N,N,N,N,13690,25398,
+53356,53357,25400,53358,N,N,25401,53359,18217,53360,N,25402,53361,N,N,N,53362,
+25403,25404,53363,N,13913,12883,17989,15656,15204,53364,N,53365,N,N,53366,
+53367,25405,53368,15657,N,N,N,53369,N,12874,18755,N,53370,25406,53371,N,18539,
+N,53372,N,N,53373,53374,16709,53537,25409,53538,25410,18281,53539,16193,25407,
+N,17249,53540,53541,25408,53542,N,N,15950,53543,N,N,N,N,N,N,53544,N,N,12380,
+53545,13609,N,53546,53547,N,N,N,53548,25411,53549,53550,17528,53551,25412,
+16455,N,N,53552,N,N,19501,53553,N,18723,25413,25414,17237,53554,20039,N,53555,
+25416,25415,53556,N,N,N,N,N,53557,N,N,N,53558,N,53559,15471,53560,53561,25418,
+12400,N,53562,53563,N,25421,53564,53565,53566,25419,12884,14158,25420,14662,
+14706,N,19046,25422,53567,53568,19284,53569,53570,25424,N,N,53571,16465,12623,
+12858,12332,N,N,N,N,53572,53573,25423,N,53574,N,N,53575,53576,N,53577,53578,
+25425,25426,15991,N,53579,N,53580,N,25427,53581,13135,N,53582,N,N,25429,N,N,N,
+14186,53583,13670,N,53584,25430,13941,N,N,25431,53585,16508,53586,17997,53587,
+16480,14965,53588,53589,N,25432,N,53590,53591,N,N,N,N,53592,53593,17250,16747,
+53594,25434,25436,25433,25435,N,N,N,N,N,53595,14114,53596,N,N,53597,N,N,N,N,N,
+25437,14118,N,53598,N,13671,19794,25439,N,N,53599,N,53600,25440,N,N,53601,
+12590,53602,53603,N,N,25443,N,N,N,13174,25442,25441,53604,25445,25438,53605,
+25446,20009,53606,25447,53607,25448,N,53608,21620,25450,N,25449,N,N,N,25451,
+25452,53609,20021,25453,N,28783,15951,25454,25455,15703,N,17976,25456,N,53610,
+53611,17192,53612,53613,25457,N,17212,25458,53614,N,N,53615,N,13861,N,20799,
+17245,15411,53616,N,53617,53618,13384,25459,N,25634,N,25462,53619,13672,N,
+25461,25636,N,N,N,25460,N,15952,N,N,53620,N,N,N,25464,25465,N,17707,N,N,25466,
+53621,13150,N,N,53622,N,16218,18788,53623,25468,53624,53625,53626,17000,53627,
+53628,53629,53630,53793,N,25463,53794,25467,25469,N,N,14971,N,N,N,53795,N,
+53796,53797,53798,N,N,N,25638,18734,53799,18470,17785,N,13914,25637,25635,
+53800,18485,25470,17246,17787,N,17786,53801,14966,N,N,N,N,N,N,25656,N,N,53802,
+N,N,N,53803,25640,53804,25642,N,53805,53806,N,25645,53807,25646,53808,25643,
+25644,53809,53810,25641,25639,N,53811,N,N,25633,N,N,N,N,N,N,N,N,N,53812,N,
+19023,12885,N,53813,N,25653,N,25650,53814,25655,53815,53816,25654,N,18291,
+19495,53817,15163,25648,25657,25652,53818,25651,25647,53819,25649,53820,13385,
+N,N,N,53821,N,N,N,N,17213,N,53822,16509,N,53823,53824,18466,53825,N,25662,
+53826,53827,N,18468,N,53828,53829,53830,53831,N,N,16481,25659,53832,N,18511,
+53833,25663,19027,53834,17243,53835,25658,25660,N,N,25661,N,N,N,N,53836,N,
+53837,53838,N,53839,53840,53841,N,25664,N,N,15428,N,N,N,17990,25669,25668,N,
+53842,25665,53843,N,N,20278,N,N,N,N,53844,25674,53845,53846,25678,25675,53847,
+53848,53849,N,53850,N,53851,25671,53852,53853,53854,53855,N,53856,25672,N,
+53857,N,53858,53859,25677,53860,53861,N,25666,21077,25673,25667,N,N,25676,N,
+53862,N,53863,N,N,N,25682,53864,13386,N,25679,N,53865,53866,25680,53867,N,
+25681,25684,53868,N,N,N,N,53869,N,53870,53871,N,53872,25683,18550,53873,53874,
+N,N,25685,20092,19053,25690,N,N,25687,N,N,53875,N,N,N,53876,N,25686,16466,N,
+25689,25691,53878,53879,53880,25688,53877,25695,N,25692,53881,53882,53883,
+53884,53885,53886,25693,25670,54049,N,54050,25694,25696,N,54051,N,54052,N,N,
+25697,54053,54054,N,54055,N,54056,19014,N,25698,N,N,N,54057,N,N,54058,54059,
+19554,N,N,13902,14121,25699,N,N,54060,54061,N,18996,N,16232,N,19504,N,54062,
+25700,N,20019,N,54063,18292,N,16710,18228,N,N,15693,N,N,54064,12352,54065,
+25705,25703,N,25701,13345,54066,15953,25706,N,N,25704,N,25702,25710,N,54067,
+25709,25708,25707,N,N,54068,54069,N,25711,54070,54071,54072,25712,16442,54073,
+25713,N,25715,N,54074,25714,N,54075,54076,54077,14418,N,N,54078,16696,54079,N,
+N,25717,54080,54081,54082,17788,54083,25716,54084,54085,N,25718,54086,18997,
+16748,14663,N,25719,N,N,N,54087,20040,N,54088,N,54089,N,N,N,25721,N,N,25722,N,
+25723,54090,25724,N,15205,N,25725,14159,N,N,13674,13610,N,25889,54091,19571,
+14664,25726,54092,54093,54094,25892,19558,N,18236,N,54095,18739,54096,54097,
+54098,15715,25891,54099,15443,14665,15206,13673,18998,25890,54100,54101,N,
+16711,19266,14967,54102,N,N,54103,N,N,N,54104,15207,17501,54105,25895,20063,
+14937,54106,25896,16194,N,25898,N,N,N,15954,14896,N,54107,54108,54109,25897,
+54110,54111,15658,14398,16712,25893,25899,54112,54113,N,N,25894,14160,54114,
+25902,25906,14187,54115,N,54116,N,N,25901,54117,N,54118,54119,25910,54120,
+54121,14666,N,N,19821,12348,25907,N,54122,13675,54123,25904,N,54124,N,N,N,
+25905,N,54125,17789,25903,25900,N,13096,16484,N,54126,14376,54127,54128,N,
+25912,N,54129,N,54130,54131,54132,N,54133,54134,N,54135,25909,N,54136,54137,
+54138,N,25911,N,54139,N,25908,N,N,54140,54141,N,14161,16947,25913,16750,54142,
+54305,25926,N,N,25922,25916,N,N,54306,54307,N,N,54308,25920,15482,12381,25915,
+25923,25927,14667,19542,54309,17494,25917,54310,54311,25925,54312,25914,17214,
+N,25919,12349,19530,N,N,54313,54314,54315,54316,54317,25918,N,N,13915,18540,
+54318,54319,54320,16749,N,20048,15727,N,N,25966,N,54321,25928,54322,16510,N,
+25924,25929,25931,N,17529,25934,54324,N,25930,54325,54326,N,19028,13387,54327,
+54328,19531,54329,N,12382,N,54330,25933,N,20093,54331,54332,N,N,54333,54334,
+25932,54323,12655,N,N,18028,25935,N,N,54335,25942,25936,25943,N,N,N,N,54336,
+54337,25939,N,N,54338,N,54339,N,N,N,18299,54340,54341,15434,25941,54342,25938,
+25944,25937,N,N,15684,54343,54344,N,N,19237,54345,54346,15692,54347,N,25940,
+25952,54348,N,25948,54349,25951,N,25949,25953,25947,N,25921,16467,54350,N,
+18507,N,25950,54351,54352,25945,54353,N,N,16673,14162,N,15659,54354,N,54355,N,
+54356,N,16165,16694,25956,N,54357,25958,25959,N,N,25955,25957,54358,N,54359,
+54360,N,N,54361,25946,25954,N,25962,25961,54362,N,19322,54363,54364,14123,N,N,
+54365,N,N,N,N,54366,25960,N,25964,25963,25967,54367,25969,N,54368,15164,25965,
+N,N,54369,54370,25970,25971,54371,N,25972,54372,25978,17723,25974,54373,25973,
+25975,25976,54374,25977,N,54375,N,54376,25979,25980,54377,54378,13388,N,25981,
+N,25982,54380,54379,54381,54382,54383,N,N,N,54384,54385,26145,N,54386,N,N,N,N,
+26146,26147,26148,54387,26149,26150,54388,54389,26152,26151,N,N,26153,N,N,
+54390,54391,54392,N,26154,26155,54393,N,54394,54395,54396,54397,26158,26156,
+26157,14945,14163,N,54398,17238,N,18483,54561,15728,N,N,18253,N,18541,26159,
+22637,N,N,N,54562,54563,54564,54565,N,26160,26162,N,19813,26161,26164,26163,N,
+19795,54566,26165,54567,18558,54568,54569,54570,N,N,26166,N,54571,54572,N,N,
+26169,N,54573,26168,26167,N,N,54574,54575,26170,14130,N,54576,N,16674,13633,
+54577,N,N,54578,26174,26171,N,N,26172,N,54579,N,26175,N,26176,26173,N,N,54580,
+12585,N,54581,54582,12839,N,54583,N,26178,26179,N,54584,N,26180,N,19810,N,
+54585,54586,N,N,15660,N,26182,26181,N,N,N,N,N,54587,N,N,N,54588,16233,26183,N,
+54589,N,54590,26184,N,54591,26185,N,13413,54592,N,54593,54594,13389,N,54595,
+26186,N,N,N,N,N,26187,54596,19293,19811,54597,54598,54599,19796,20279,N,14669,
+26190,15444,26189,54600,54601,N,54602,26191,15401,54603,54604,54605,16977,
+54606,26192,54607,54608,14668,54609,19543,26193,26194,N,N,26195,54610,54611,
+54612,54613,26196,N,N,54614,N,54615,N,26197,N,N,N,54616,N,54617,N,54618,N,N,
+15402,54619,54620,19565,54621,N,54622,54623,26199,54624,17215,54625,26198,
+54626,N,N,N,54627,N,26201,N,N,N,26200,N,N,N,N,N,N,N,26202,N,N,N,16443,N,26203,
+N,26204,N,N,N,19001,26205,54628,16751,26206,N,54629,N,54630,N,26207,N,N,N,N,
+54631,N,20094,26210,54632,26209,26208,17456,54633,26211,16166,N,26212,N,N,N,
+26213,20280,26214,N,54634,N,N,26215,26217,26216,18469,54635,18041,N,20286,
+18473,N,54636,N,N,N,N,26219,N,N,15955,N,18730,N,26220,26218,54637,13390,54638,
+N,N,14420,15208,N,N,18542,54639,54640,N,14378,19267,54641,26223,26221,N,14670,
+N,14671,12393,N,14952,N,N,N,54642,54643,18265,N,N,N,N,N,N,N,N,12383,26228,N,
+17216,N,54644,N,N,N,18264,54645,16987,54646,N,N,54647,N,54648,54649,26230,
+54650,54651,26226,26229,26224,N,26227,19238,N,54652,14421,N,N,12413,26225,N,N,
+N,N,N,N,N,54653,54654,26232,54817,26233,54818,54819,17977,N,54820,N,13883,
+54821,54822,N,26406,18237,54823,15209,54824,N,13884,16456,20294,19502,26231,
+16468,54825,N,N,N,N,N,N,N,N,N,N,54826,54827,54828,N,13651,26234,54829,N,54830,
+N,54831,N,N,26236,54832,N,N,54833,N,26235,N,N,54834,N,N,26237,54835,17190,N,
+18238,N,54836,N,N,N,17457,54837,N,54838,N,26403,N,N,N,N,N,N,54839,26402,54840,
+N,N,54841,26238,54842,N,16213,N,18789,26405,54843,26404,14672,20307,N,54844,N,
+N,N,N,N,N,N,26421,54845,54846,N,N,N,26409,26410,54847,54848,54849,N,15472,N,
+54850,26408,54851,14712,26407,N,N,26411,N,N,54852,17458,18978,16675,N,N,N,N,
+16988,26415,54853,26416,26412,54855,54856,54857,N,26413,N,26414,54858,N,N,
+54859,14673,54854,N,N,26422,N,26418,54860,N,54861,N,18790,54862,19308,18728,
+54863,N,26417,N,54864,26420,26419,N,N,N,19268,26423,N,N,N,N,54865,N,26424,N,
+54866,16695,54867,26425,N,N,26427,N,26431,54868,N,26428,26426,18239,26429,N,
+26430,54870,N,54871,12850,N,26437,26432,54872,54869,N,26433,54873,54874,N,
+26434,N,16929,N,54875,N,54876,26436,26435,26438,54877,N,54878,54879,26439,
+26440,54880,N,16195,54881,12905,N,26441,20055,N,15403,54882,54883,15661,N,N,
+54884,54885,54886,15210,17239,54887,54888,N,54889,54890,26442,26443,12593,
+54891,26444,54892,54893,26445,26446,54894,N,26447,N,26448,13885,23082,26449,N,
+16485,26450,15435,54895,26451,N,20528,54896,54897,N,26452,19038,13404,54898,
+54899,16676,15704,54900,18801,15662,N,54901,54902,N,N,N,N,N,54903,26453,14674,
+26454,18508,N,26468,N,N,N,54904,26456,54905,16969,18293,14399,26455,16677,
+54906,N,N,N,N,N,26457,N,N,54907,54908,54909,54910,17530,N,N,N,55073,N,N,55074,
+55075,N,55076,N,N,N,N,55077,N,26459,26458,26461,N,55078,26460,N,26462,55079,N,
+26464,55080,26463,N,13391,55081,26465,N,26466,26467,N,55082,14897,20041,N,
+26469,16167,N,55083,N,12656,26470,26471,N,N,55084,N,55085,26472,55086,55087,
+55088,N,55089,55090,N,N,55091,N,55092,55093,12402,N,26473,55094,N,N,55095,
+26474,N,55096,N,55097,N,55098,18791,55099,55100,N,15431,N,26476,55101,55102,N,
+55103,55104,13097,12338,55105,55106,55107,55108,26475,26478,18254,55109,16196,
+55110,12886,55111,19239,55112,N,N,55113,14173,13916,55114,26477,55115,12906,
+55116,55117,N,N,N,N,N,13347,55118,N,N,N,N,N,N,N,N,N,55119,12657,26482,20074,
+16989,55120,N,18756,N,26494,55121,12887,26492,N,26490,26481,55122,26479,55123,
+26480,55124,15459,13932,17271,55125,N,55126,18001,N,55127,N,55128,N,12625,N,
+26484,26483,N,55129,55130,N,26489,26485,26488,N,55131,55132,55133,55134,19536,
+26487,12888,13181,26491,55135,55136,26493,55137,55138,N,N,14164,N,N,N,N,N,N,N,
+26659,26668,26669,N,N,55140,12331,55141,55142,55143,N,55144,55145,26676,N,N,N,
+N,12401,N,N,26667,55146,55147,55148,26666,55149,26661,26660,55150,26658,26657,
+17251,55151,17019,26663,55152,N,55153,55154,N,N,26662,N,55155,55156,55157,
+26665,N,55158,N,16752,14165,N,N,55159,55160,12609,26664,55161,14675,55358,
+55139,55162,55163,55164,16753,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+55165,N,N,26682,N,26683,N,12889,55166,N,N,12846,26680,55329,N,55330,55331,N,
+55332,N,55333,26670,55334,26678,N,26685,26679,N,N,55335,26677,N,N,N,55336,
+26486,55337,55338,26675,N,55339,55340,26671,55341,55342,55343,13392,26673,
+26684,N,26674,N,N,N,55344,55345,26686,55346,26672,18300,55347,55372,N,N,N,
+19817,N,N,N,26681,N,N,N,N,N,N,N,26703,55348,55349,55350,26695,N,N,N,16251,N,
+55351,N,55352,13638,N,13917,N,26690,55353,55354,55355,N,12891,55356,N,15956,N,
+26693,N,N,N,14938,55357,N,17745,26698,N,N,N,N,N,N,N,55359,19054,55360,26689,N,
+N,N,12890,14422,18729,26699,N,26687,N,55361,26696,55362,55363,N,26706,55364,
+26691,55365,N,26692,17978,N,55366,26697,N,N,55367,26694,19240,26700,12384,
+55368,N,55369,N,26688,N,55370,N,N,N,55371,N,N,N,N,N,N,26702,N,26701,N,N,N,N,N,
+N,18283,26708,N,26719,N,N,55373,N,13182,N,N,N,26722,N,N,26704,55374,N,N,26709,
+19822,N,N,N,N,N,N,N,55375,26718,55376,55377,19797,55378,N,N,55379,20010,55380,
+N,55381,55382,N,N,N,55383,17272,55384,55385,55386,13163,55387,N,N,N,55388,
+18802,26724,17953,55389,55390,12337,55391,N,26717,55392,26713,16754,26707,
+26715,26720,55393,18220,N,55394,55395,12330,55396,26712,55397,26721,18808,N,
+55398,55399,N,N,N,55400,26716,N,26711,55401,N,N,N,N,N,15957,N,N,N,N,15663,N,
+55402,55403,15404,55404,N,N,N,19544,N,N,18759,N,55405,26727,N,26736,N,N,N,N,
+55406,N,55407,55408,55409,N,N,26714,N,55410,N,55411,13175,N,55412,N,N,N,15992,
+26725,55413,26730,16755,55414,55415,26726,55416,26733,55417,N,17247,N,26734,
+55418,55419,19798,26723,13112,55420,26729,N,55421,26732,19500,N,55422,N,N,
+26735,N,N,26728,26731,N,55585,N,N,N,N,N,N,N,N,N,N,55586,N,N,55587,N,19241,N,
+20257,55588,55589,55590,55591,N,26739,N,N,55592,N,N,55594,55595,26746,55596,N,
+26738,15427,N,55597,55598,N,N,26705,55599,N,N,N,N,55600,N,55601,N,55602,19022,
+N,19490,26745,26744,N,26740,26741,N,12598,N,55603,N,55604,26743,N,26737,55605,
+55606,55607,55608,17493,55609,N,N,55610,55611,26742,12414,N,55612,N,N,55593,
+55613,55614,16930,55615,N,N,N,N,N,N,19011,N,55616,26747,26913,N,18521,N,N,
+55617,N,26750,15958,15433,26915,N,N,13886,55618,55619,55620,55621,55622,N,
+26916,55623,18809,26749,55624,26710,N,55625,55626,55627,55628,55629,55630,
+55631,26748,55632,N,N,N,20303,17954,18803,55633,N,26923,N,55634,N,N,N,N,N,N,N,
+26929,N,55635,55636,55637,N,55638,26930,55639,26917,55640,N,N,18294,55641,
+55642,26927,26919,55643,26921,55644,55645,N,N,55646,26931,26920,N,55647,26924,
+N,N,12658,55648,18021,N,26925,26928,55649,N,55650,55651,N,55652,N,26918,55653,
+16678,55654,26922,15143,16197,14128,19572,55668,19577,15730,N,N,N,N,55655,N,
+55656,55657,55658,26935,26933,N,55659,55660,55661,55662,N,20302,55663,N,N,N,N,
+55664,N,26932,55665,55666,N,19829,55667,26934,26936,N,N,N,N,26937,N,N,55669,N,
+55670,N,26940,26938,N,55671,55672,N,N,N,17955,26939,55673,N,55674,18509,26926,
+N,N,55675,N,N,N,N,N,55676,N,N,55677,15731,N,26941,26946,16756,55678,N,26945,
+55841,55842,N,26914,N,55843,55844,26947,16713,N,N,26942,26944,N,55845,55846,N,
+55847,55848,55849,26943,N,N,23857,23842,55850,55851,26949,55852,N,N,55853,N,N,
+55854,26948,N,N,N,N,55855,N,55856,N,N,N,19830,N,25148,26950,N,N,N,N,N,55857,N,
+55858,N,55859,N,55860,55861,N,26951,55862,47206,55863,N,N,N,55864,N,N,N,N,N,N,
+26952,14423,N,13652,N,55865,55866,26954,20829,55867,55868,55869,55870,13685,N,
+20026,55871,13939,26955,55872,55873,55874,55875,55876,N,N,26956,N,55877,N,
+17262,55878,N,N,55879,N,26957,N,N,N,55880,55881,55882,N,18042,55883,12346,N,N,
+N,N,N,N,N,N,N,N,N,N,55917,N,12899,26962,26963,55884,N,N,N,55885,N,26958,N,
+15165,55886,N,55887,N,55888,N,55889,N,N,N,N,55890,N,26959,18242,N,55891,55892,
+55893,26960,26961,26971,N,55894,N,26965,26968,55895,N,55896,55897,55898,26964,
+55899,55900,55901,N,N,N,N,N,55902,55903,55904,N,55905,26966,55906,26967,15448,
+N,26969,N,17217,N,14166,13122,N,N,55907,55908,N,26972,55909,N,55910,N,13119,
+55911,26977,55912,N,26973,26976,55913,N,N,55914,18490,55915,N,55916,N,26974,N,
+N,26975,18760,18522,26978,N,N,N,N,N,N,N,N,17021,26988,55918,26984,55919,55920,
+12907,26982,N,19242,26983,55921,55922,26980,55923,26981,26986,26989,55924,N,
+26987,55925,55926,55927,26985,26979,55928,55929,N,N,N,17240,55930,26996,N,
+19498,N,55931,55932,N,55933,N,55934,N,26994,N,N,56097,26995,N,N,N,N,56098,
+56099,N,56100,56101,N,26990,N,N,26992,N,56102,56103,26993,56104,56105,56106,
+26991,56107,N,N,56108,N,56109,N,N,N,16486,N,20281,27000,56110,27001,N,N,N,N,
+27169,N,16170,N,27003,56111,27006,N,N,N,56112,N,26998,26997,56113,N,27170,
+56114,56115,12892,N,27004,N,27171,N,N,N,27005,56116,N,56117,56118,N,27002,N,
+17459,N,26999,N,N,56119,N,N,N,18280,N,N,27175,56120,56121,56122,56123,56124,
+56125,56126,N,56127,56128,19771,N,N,56129,N,N,56130,N,56131,N,56132,56133,
+56134,N,N,N,N,56135,27174,56136,N,27173,56137,N,N,N,56138,N,N,N,27182,56139,
+56140,56141,27176,N,56142,N,27184,N,56143,N,N,N,N,19814,27187,N,27178,56144,
+56145,27179,56146,N,N,27183,N,27186,27185,56147,56148,56149,27177,N,N,56150,N,
+27180,N,27197,N,N,56151,56152,N,N,56153,56154,N,56155,N,N,56156,27190,N,56157,
+56158,56159,N,N,N,N,N,56160,56161,N,56162,N,27188,N,56163,27189,56164,N,N,
+27194,27195,56165,13098,56166,13634,N,N,27193,56167,56168,N,56169,N,27172,
+56170,N,N,56171,56172,56173,N,27192,27196,27191,56174,27198,56176,56177,56178,
+27200,27199,N,56179,56175,56180,56181,56182,N,56183,56184,N,27202,27201,26970,
+N,N,N,27206,56185,N,N,N,N,56186,56187,N,56188,27203,56189,N,N,56190,27204,N,N,
+27205,56353,27207,56354,N,N,N,14188,56355,27209,56356,27208,56357,15664,N,
+56358,56359,56360,56361,14676,24103,56362,N,N,56363,27210,15697,N,56364,56365,
+13113,56366,27211,56367,12626,56368,15959,27212,56369,56370,14677,27213,12385,
+56371,N,N,N,18749,56372,N,27214,N,N,N,N,16234,56373,27221,N,N,27218,N,17263,N,
+56374,N,56375,N,27219,27216,13918,56376,27215,27222,N,N,N,N,N,14134,N,N,16990,
+N,27228,N,N,N,N,27224,N,N,N,16949,27223,56377,27226,56378,56379,56380,N,27217,
+56381,56382,N,27227,N,27229,N,N,N,56383,N,56384,18543,N,N,27225,N,27230,27232,
+N,N,14419,27220,N,12353,N,N,56385,N,N,56386,56387,27231,56388,14939,20086,
+27233,27234,16757,N,N,N,N,56389,56390,56391,56392,56393,20002,N,56394,56395,
+56396,27235,19765,N,N,27236,27237,N,56397,19044,27238,56398,14912,N,20003,N,N,
+N,N,N,56399,27243,N,N,N,N,N,N,56400,56401,56402,27244,15960,27242,56403,N,
+56404,19815,27239,N,N,27241,16445,16254,56405,27240,N,27245,N,56406,18979,N,N,
+27247,N,27246,56407,56408,56409,13164,N,19243,27248,N,56410,56411,N,56412,
+56413,56414,N,56415,27260,27250,N,56416,N,N,N,N,27251,56417,56418,56419,N,
+27252,27253,N,N,N,N,56420,56421,56422,N,N,56423,27257,N,27258,56424,56425,
+27256,N,N,56426,N,56427,27254,56428,27249,27255,56429,56430,N,N,56431,N,N,
+27259,28727,N,56432,N,N,56433,N,N,N,12840,56434,N,N,56435,56436,56437,N,27262,
+13919,27261,56438,56439,56440,27426,N,27425,N,N,N,27428,56441,N,27427,56442,
+27429,56443,N,15665,56444,27430,56445,N,27431,N,N,56446,56609,56610,56611,
+27432,16446,N,19799,N,27433,N,N,18980,18246,27434,56612,27435,14379,N,56613,N,
+13612,56614,N,N,27436,56615,56616,15211,18241,27437,N,13136,56617,56618,N,N,
+56619,56620,27438,N,N,N,56621,27440,19831,N,27439,16198,N,27441,N,N,27442,
+56622,N,27443,13393,56623,56624,56625,56626,N,N,27444,N,56627,27445,N,27446,
+27447,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,13137,N,56628,56629,56630,56631,56632,
+N,27448,N,27449,27450,N,N,N,N,N,12914,N,56633,16168,27451,N,56634,N,56635,N,
+56636,N,N,N,56637,N,56638,27452,N,56639,N,27453,56640,N,N,N,56641,N,56642,
+14400,N,17531,27454,56643,56644,N,56645,14167,N,16214,N,27457,N,17956,56646,
+27456,56647,56648,14129,56649,56650,27455,17015,13613,N,N,27458,N,27459,56651,
+15961,56652,N,56653,14189,56654,27460,56655,N,N,N,19244,56656,56657,16479,N,
+56658,N,13686,N,19573,16714,56659,27461,56660,N,N,16199,17264,15962,56661,
+56662,N,56663,27462,N,56664,N,56665,27465,56666,27466,56667,N,N,N,56668,56669,
+N,14910,16962,27464,56670,15963,18750,56671,56672,56673,N,N,27463,56674,56675,
+15212,N,12627,56676,27470,14168,N,56677,15214,56678,N,15213,N,20301,27469,
+27468,16679,N,13645,20291,13114,15964,N,56679,56680,56681,N,56682,56683,56684,
+27467,N,56685,56686,56687,N,27472,56688,27473,27471,56689,14424,N,19776,N,
+56690,15215,18215,N,56691,56692,27476,56693,16448,N,17218,56694,56695,19766,
+56696,27479,N,N,N,14444,56697,16447,27475,N,27480,14445,27477,27478,56698,
+27474,56699,N,N,16482,17993,56700,56701,17199,N,12893,56702,N,N,56865,56866,N,
+18544,N,56867,13635,N,56868,17460,N,N,27483,56869,27481,N,56870,17228,56871,
+56872,56873,16449,13394,27482,N,16219,N,56874,20042,56875,56876,56877,20288,
+56878,N,N,27484,27495,17461,56879,27494,56880,27491,27499,27492,N,27488,N,
+17532,27487,N,N,N,27485,56881,19745,15216,N,56882,27489,N,27486,56883,56884,
+56885,27493,15732,N,14401,N,56886,N,17018,56887,19269,12634,12386,N,17957,
+56888,56889,27497,N,N,56895,56890,27496,N,18022,N,27501,56891,N,N,27490,N,
+27500,27502,N,14380,27498,14678,56892,15445,56893,56894,27503,19800,N,N,N,N,
+27506,N,27509,N,N,27507,18741,56896,N,N,56897,N,N,27504,N,N,N,56898,N,13920,N,
+N,56899,N,27508,N,N,27510,56900,56901,56902,56903,56904,N,56905,27514,N,N,
+27511,56910,27513,27512,N,N,56906,56907,56908,N,27515,N,15409,56909,27517,
+27516,18792,N,56911,27681,N,N,N,56912,N,N,14169,N,N,N,N,27518,27682,56913,N,
+27683,13636,26177,15993,N,27684,N,56914,14446,56915,56916,N,N,56917,27685,
+56918,N,27686,56919,N,15166,56920,56921,N,N,N,N,23118,56922,27687,56923,27688,
+56924,15666,N,27689,27690,56925,56926,27691,N,N,27692,27693,N,56927,N,56928,
+56929,17195,56930,56931,27694,N,N,56932,56933,27696,N,27695,N,N,N,56934,17958,
+56935,27697,56936,19245,56937,27698,N,27699,56938,27700,56939,N,56940,56941,
+27701,N,56942,56943,56946,18010,56944,N,56945,N,N,N,15965,27702,56947,56948,N,
+56949,N,56950,56951,14699,20526,27703,56952,N,N,N,N,N,56953,N,56954,56955,N,
+27704,18751,27705,56956,27713,N,56957,N,N,N,27706,N,N,27708,56958,57121,N,
+27707,27709,57122,19270,27710,27711,N,57123,N,57124,57125,27712,N,N,N,27714,
+57126,N,57127,57128,13101,17511,N,18793,14946,14679,N,57129,N,N,18767,12895,
+18510,27717,13395,16469,27716,27721,17273,19555,N,27719,27720,13614,N,27722,
+18275,16991,57130,57131,18545,17725,27718,N,19271,12908,27724,20264,17474,
+20293,57132,57133,15217,27723,57134,16945,57135,N,27740,16680,57136,N,18040,N,
+18768,N,57138,57137,N,N,57139,27727,15167,15218,57140,15966,N,18277,57141,
+14381,27726,27725,N,18794,N,57142,N,15425,N,57143,17746,N,57144,57145,N,57146,
+N,N,57147,N,57148,57149,N,27729,27730,14680,27728,57150,57151,57152,N,57153,
+27731,27732,N,27734,16931,57154,27733,13414,N,27736,N,27735,27737,N,57155,
+27739,27741,N,27742,57156,N,N,N,57157,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,16470,57158,15439,27743,N,57159,N,13138,57160,27744,
+57161,N,16758,27745,N,27746,18795,N,N,13615,N,N,N,N,N,N,N,57162,N,27747,57163,
+N,57164,17462,N,N,57165,N,12635,N,N,57166,N,N,57167,57168,N,N,N,57169,N,N,N,
+27748,N,N,N,N,57170,57171,57172,N,N,15473,N,N,57173,N,16246,N,N,57174,57175,N,
+N,57176,N,N,57177,16941,N,57178,N,57179,N,57180,27751,57181,57199,N,27750,N,
+57182,N,27749,N,N,57183,57184,57185,57186,N,57187,27757,27755,N,57188,27752,N,
+57189,N,N,57190,57191,27754,57192,N,57193,27753,27756,N,13687,N,27760,N,16471,
+N,27761,57194,57195,N,57196,14425,N,27758,27759,57197,N,N,20265,57198,57200,
+57201,17463,57202,16681,N,N,N,N,N,N,27762,57203,N,27765,57204,N,N,57205,57206,
+57207,N,27763,27764,19801,57208,N,N,N,17959,27768,57209,N,N,57210,N,57211,N,N,
+N,N,N,N,27766,27767,27769,57212,57213,57214,57377,N,N,57378,57379,N,N,27945,N,
+N,N,N,N,27772,57380,N,57381,27773,27771,57382,57383,57384,57385,N,N,N,57386,N,
+N,57387,57388,27770,N,17533,N,N,27937,27941,27938,27774,57389,27939,57390,
+57391,57392,27940,N,N,N,57393,27947,N,N,N,27942,N,57394,57395,57396,57397,
+16472,27944,57398,57399,27946,27943,N,N,N,N,57400,N,N,57401,57402,N,57403,
+57404,57405,27949,N,15667,N,27948,N,N,57406,57407,57408,27950,N,N,N,N,27951,
+57409,57410,27954,27953,N,27952,N,57411,27956,27955,N,19574,N,N,57412,27958,
+57413,27957,27959,57414,N,N,N,27960,57415,57416,N,57417,57418,N,N,27962,57419,
+N,N,N,N,57420,N,57421,27961,16200,27963,57422,57423,13933,27964,27966,N,57424,
+N,57425,N,N,N,N,57426,57427,N,N,27967,N,57428,57429,N,57430,57431,27968,27965,
+57432,27969,N,15446,27970,13616,14131,N,57433,N,57434,14382,N,57435,N,N,N,N,N,
+N,27971,57436,N,N,18032,N,N,17726,27972,N,N,N,N,57437,N,N,27975,N,57444,57438,
+N,57439,57440,N,N,N,N,N,57441,15412,57442,57443,27974,27973,14170,27976,57445,
+N,57446,13139,N,27978,N,57447,57448,14940,27977,N,27986,N,N,57449,57450,N,
+27980,27982,19045,27979,57451,57452,57453,27981,N,27985,27983,13617,57454,
+27984,57455,57456,N,57457,N,57458,27987,57459,57460,18266,20056,N,57461,57462,
+57463,15668,N,N,N,27988,57464,57465,57466,57467,19746,27990,57468,27989,N,N,
+27993,19777,57469,57470,27992,57633,13165,27991,27996,57634,N,27995,N,N,27994,
+17714,27997,57635,N,57636,57637,57638,57639,57640,N,27998,57641,N,N,N,27999,
+57642,57643,14700,N,14117,28000,28001,28002,57644,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+16201,28003,57645,15405,28004,57646,57647,N,28005,57648,57649,57650,21025,
+20862,N,N,N,N,28006,25968,28007,17188,16171,18240,N,N,57651,57652,28008,57653,
+N,19029,17492,14718,N,57654,17193,57655,57656,12586,N,19320,16215,57657,N,N,N,
+57658,57659,N,57660,14174,N,57661,13921,57662,57663,19030,57664,N,N,N,N,28009,
+N,N,N,N,N,57665,N,28011,57666,57667,28010,12896,N,57668,18038,28012,18295,N,
+17715,57669,28013,15698,57670,N,N,28015,57671,57672,19522,28030,28017,28018,
+57673,N,17481,57674,16992,16759,57675,17960,57676,28016,13653,N,57677,N,N,
+28025,57678,28022,28197,17961,17248,28019,N,17534,17747,28020,28024,16224,
+57679,18279,17484,57680,N,16450,28023,16942,16932,28021,12329,20258,N,N,N,
+28026,57681,57682,57684,N,57685,57686,16993,57683,N,15669,16202,57687,57688,
+28028,28027,57689,12399,28029,N,N,18735,N,28199,57690,N,18011,16235,57691,
+57692,17241,N,13944,N,28198,19767,12607,57693,19031,12897,28193,28194,28195,
+28196,17979,17187,12387,28200,N,28201,29731,N,57694,16957,57695,28202,N,12659,
+16716,57696,14383,N,19802,57697,57698,28203,17708,N,N,57699,16760,15447,28204,
+57700,N,28207,N,57701,15717,28205,16683,16682,57702,12388,N,20043,28209,N,
+18546,28211,28210,28208,25444,13396,57703,N,28014,57704,28213,28212,57705,
+57706,N,57707,28214,57708,19768,N,N,N,57709,N,57710,57711,57712,N,57713,N,N,N,
+N,57714,57715,57716,18017,N,57717,19246,N,28215,N,15449,N,N,N,N,28216,57718,
+28217,57719,57720,57721,28218,57722,N,17697,N,N,N,N,57723,57725,N,N,12394,N,
+57726,57889,57890,N,57891,57892,N,14681,N,57724,N,20282,N,N,N,57901,N,N,57893,
+N,57894,57895,57896,N,28222,57897,57898,N,57899,N,14132,28219,N,28220,57900,N,
+N,18804,N,N,57903,N,13140,N,57904,57905,N,N,N,57906,19769,57902,13887,N,N,N,N,
+N,17748,57907,57908,57909,N,28223,N,57910,57911,57912,N,57913,N,N,N,N,57914,N,
+N,57915,N,28224,N,57916,N,57917,57918,57919,28225,57920,N,57921,N,57922,N,
+57923,N,57925,57926,N,57924,N,57927,N,57928,N,N,N,17698,57929,57930,28227,
+57931,28226,N,57932,N,57933,57934,N,57935,57936,N,57937,57938,N,N,N,N,N,57939,
+N,N,N,57940,57941,18003,28228,15670,15456,18267,17265,57942,N,N,15474,57943,
+16236,N,28229,57944,28230,57945,57946,57947,N,N,N,N,N,57948,16221,28231,57949,
+28232,N,57950,N,28233,19823,N,15671,57951,N,N,N,N,28235,28234,57952,14682,N,
+14707,15168,57953,57954,57955,N,N,N,N,N,57956,28238,57957,N,57958,57959,15718,
+N,28237,57960,28236,N,17001,57961,N,14447,57962,16451,57963,57964,57965,N,
+18480,57966,N,N,N,15673,N,57967,N,N,57968,28239,N,15967,N,57969,N,57970,N,
+28242,28240,57971,57972,57973,28241,57974,57975,57976,57977,28244,28243,57978,
+N,15994,N,28245,57979,57980,57981,N,57982,28246,28247,58145,58146,N,58147,
+18512,14931,15457,28248,N,28249,20004,15685,19566,20044,28250,13922,N,58148,
+58149,N,28251,58150,17699,58151,58152,28254,13176,16203,58153,28252,N,28253,N,
+17504,58154,58155,19285,13948,N,58156,58157,N,58158,58159,58160,58161,58162,
+58163,N,N,N,28256,28257,58164,N,58165,N,58166,28255,58167,N,28259,58168,58169,
+N,N,58170,58171,58172,58173,N,58174,58175,N,58176,18015,13123,N,58177,28263,
+58178,58179,28260,28262,58180,N,58181,N,N,N,58182,58183,28258,N,N,N,N,58184,
+58185,58186,58187,N,58188,28495,N,N,28261,N,58189,58190,58191,N,N,58192,20075,
+58193,58194,14426,58195,58196,58197,N,58198,N,58199,28271,58200,N,58201,58202,
+17716,28266,58203,58204,28269,28267,58205,28272,N,58206,58207,58208,28273,
+58209,N,N,N,N,N,28265,58210,58211,28278,12660,58212,58213,28264,N,58214,58215,
+18477,N,28268,58216,15968,58217,58218,58219,N,N,N,N,58220,58221,58222,14683,N,
+N,N,58223,58224,58225,58226,58227,N,58228,58229,58230,19272,58231,13924,N,N,
+15686,N,17980,N,N,58232,58233,58234,N,N,58235,58236,N,N,16685,58237,28276,N,
+28270,28275,58238,19523,58401,17464,28277,28274,N,N,58402,58403,N,N,N,58404,
+58405,N,58406,58407,N,N,58408,N,16684,N,58409,N,N,58410,N,N,N,58411,28281,
+58412,28280,58413,58414,58415,58416,N,58417,58418,58419,58420,58421,N,58422,
+58423,58424,58425,N,N,58426,58427,58428,58429,28279,58430,N,19247,58431,N,
+58432,N,58433,58434,58435,N,N,58436,58437,N,58438,58439,58440,N,58441,15739,
+58442,N,58443,58444,28282,19039,N,58445,12628,58446,N,58447,N,18758,17266,N,N,
+N,N,13688,58448,28284,58449,14685,N,N,58450,58451,N,58452,N,N,N,15148,N,58453,
+N,N,N,N,58454,N,28283,16237,58455,N,N,58456,58457,N,N,16238,28449,28451,N,
+58458,58459,58460,58461,15995,58462,28450,28452,58463,58464,13907,58465,18757,
+58466,58467,15458,20259,N,28286,14968,N,N,20287,58468,58469,28454,58470,58471,
+N,N,28453,28455,N,N,N,N,N,N,N,N,28285,N,N,58472,58473,58474,N,18025,N,17749,N,
+N,58475,58476,58477,N,17495,58478,28460,58479,58480,N,58481,17219,28456,N,
+58482,N,28457,N,N,N,58483,58484,N,58485,N,58486,58487,N,14125,58488,28459,
+58489,58490,58491,N,58492,58493,14384,58494,N,N,N,58657,N,28458,58658,15969,
+58659,58660,58661,58662,N,N,N,N,N,58663,N,58664,58665,13177,58666,N,58667,N,N,
+58668,N,28464,58669,14911,16761,58670,N,17482,58671,N,N,58672,N,N,58673,N,
+58674,58675,N,58676,13115,58677,58683,N,58678,28462,28463,17475,N,28461,N,N,N,
+58679,58680,58681,N,N,28465,58682,N,N,N,N,N,N,58684,N,28471,58685,58686,58687,
+58688,28474,58689,58690,58691,58692,58693,N,N,28473,17709,N,58694,N,N,28466,
+28467,28470,58695,N,N,58696,28472,58697,58698,N,13888,58699,N,28475,28469,
+58700,58701,28468,N,N,N,N,N,N,N,N,N,N,N,N,N,N,58703,58704,58702,58705,58706,N,
+58707,58708,58709,28479,58710,N,N,28480,58711,58712,N,N,N,58713,58714,58715,
+28481,N,N,28478,28477,58716,58717,58718,15970,17962,28476,N,N,N,N,58719,N,
+28485,N,N,N,N,N,N,N,N,N,28483,N,N,58720,58721,N,58722,58723,58724,58725,28484,
+28482,N,17016,N,28486,58726,N,58728,N,58727,N,28487,N,58729,28489,58730,N,N,
+58731,N,58732,N,58733,N,N,N,N,13397,28488,19578,N,58734,N,N,N,58735,28500,
+28490,58736,N,28493,58737,28491,58738,28492,58739,N,N,N,N,58740,N,28494,58741,
+N,58742,58743,58744,28496,58745,58746,N,N,28497,N,28498,N,N,N,N,28501,28499,
+28502,28504,N,28503,N,58748,58747,17465,58749,58750,N,N,N,N,58913,N,19559,N,
+28505,16686,58914,N,N,28506,58915,19012,28507,13099,58916,58917,58918,12604,N,
+13399,N,13398,28508,N,28509,N,28510,28511,N,N,N,58919,58920,58921,28512,58922,
+13400,13141,14686,18486,58923,28514,28513,58924,N,58925,58926,28515,N,N,N,N,
+12636,N,58927,N,58928,N,N,28518,58929,28517,28516,58930,28519,58931,N,N,N,
+28522,N,N,58932,12359,58933,58934,28520,58935,28524,28523,N,N,58936,58937,
+58938,58939,28526,28525,28527,N,17966,58940,58941,N,28528,58942,58943,58944,
+58945,28529,28531,N,58946,28530,58947,18796,58948,58949,N,N,28532,58950,N,
+58951,58952,58953,N,28533,N,14949,N,58954,N,28534,28535,N,58955,19273,58956,N,
+N,N,58957,58958,58959,58960,16715,58961,58962,N,12324,16971,58963,28536,N,
+18797,N,N,N,N,N,N,28539,28537,14687,N,28538,14402,N,58964,N,58965,N,58966,
+58967,58968,N,N,19013,28541,28705,28542,28706,N,58969,12577,16216,15740,13401,
+28707,N,N,N,18278,N,28709,N,58970,N,12578,N,28708,17476,58971,20045,17963,
+28540,20006,N,14385,58972,58973,19803,58974,58975,N,58976,58977,58978,58979,
+13945,20020,N,14120,58980,16994,26401,N,28710,13100,16239,N,58981,N,N,13142,
+28712,58982,28713,28711,14180,58983,14941,15971,58984,N,58985,12579,N,N,20057,
+58986,58987,58988,28715,28206,58989,28714,N,N,N,58990,58991,28718,28716,28717,
+58992,28719,N,28720,20076,28721,28722,58993,16457,18491,N,N,N,16253,13415,N,N,
+19770,12909,15672,14427,N,28725,58994,28724,15219,28726,28723,N,N,15144,58995,
+N,N,28730,27181,N,58997,21078,58998,16247,28728,58999,59000,59001,N,N,20005,
+18033,N,N,N,N,12587,59002,16483,15414,N,N,N,59003,18999,59004,12608,N,N,N,
+20077,19819,N,28731,59005,17733,15483,N,59006,59169,28732,59170,28733,16204,
+28734,59171,20078,N,N,28729,28736,28738,N,28737,N,28735,N,N,28739,N,N,28740,
+59172,59173,16762,59174,12898,N,N,59175,59176,59177,28741,N,N,19512,59178,N,
+28742,N,N,N,N,N,28743,59179,20266,59180,N,N,N,N,23345,28744,N,N,N,28745,28746,
+N,N,59181,28750,59182,28747,N,28748,N,28749,28751,59183,N,N,N,59184,59185,N,N,
+16452,N,N,59186,19575,59187,59188,16453,59189,59190,28752,N,18547,N,28753,
+29523,19532,59191,28754,N,28755,59192,28756,13143,59193,28758,N,16217,59194,N,
+N,28759,N,59195,14116,N,59196,59197,59198,28760,28764,59199,28762,59200,N,
+59201,59202,28763,N,N,13171,28761,28765,N,N,59203,N,28766,N,12360,N,28767,
+28768,N,N,N,N,59204,59205,59206,15972,59207,59208,N,28769,N,59209,59210,13639,
+N,59211,28772,N,N,28771,N,28770,N,N,27505,59212,19036,59213,N,N,59214,59215,
+28773,28774,59216,59217,N,59218,59219,59220,N,59221,N,59222,59223,N,59224,N,
+28775,59225,59226,28776,59227,28777,59228,59229,28778,59230,59231,59232,N,
+59233,59234,N,13402,59235,N,N,59236,59237,59238,N,59242,28779,59239,59240,N,
+59241,59243,N,N,59244,N,N,N,N,N,N,N,N,28780,18211,59245,N,59246,28782,12859,
+59247,28785,28784,59248,59249,N,59250,12580,N,N,N,13889,19015,17466,14882,N,
+14688,15719,59251,16220,N,59252,N,28787,59254,59255,28786,19778,13416,18514,
+18012,59256,N,59257,16252,20046,59253,14171,N,59258,N,59259,N,59260,28790,N,
+59261,28789,59432,59262,N,N,N,N,59425,19275,17964,59426,59427,59428,N,59429,
+59430,12624,59431,N,28791,28788,N,N,18769,19818,28792,59433,N,N,N,N,N,59434,N,
+28793,59435,N,N,59436,28795,17002,13147,13148,28794,N,59437,59438,59439,13417,
+14386,59440,59441,13418,59442,59443,17727,N,N,20064,N,N,N,59444,59445,N,59446,
+59447,14428,N,N,59448,28796,59449,N,N,28797,28798,28961,N,28963,28962,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,18807,N,28964,59450,N,59451,59452,28965,59453,28966,N,N,59454,
+N,28967,59455,59456,N,59457,59458,N,N,N,59459,N,N,59460,28969,28968,59461,
+28970,N,59462,N,N,N,59463,N,N,N,N,N,N,N,N,N,N,N,N,N,N,18548,26188,N,N,16169,N,
+59464,13618,59465,N,59466,59467,59468,N,28971,59469,28972,N,21036,23867,18515,
+N,N,12411,59470,12347,N,59471,N,N,N,N,N,15220,19248,15998,59472,28973,N,19551,
+N,59473,59474,28974,19804,N,12610,N,N,N,15169,59475,28975,12910,28976,59476,
+59477,59478,28977,N,59479,59480,59481,28979,28980,59482,28982,28978,59483,N,
+28981,N,59484,59485,13403,N,N,59486,28983,N,28984,N,N,59487,59488,59489,59490,
+59491,N,N,N,59492,59493,59494,59495,28985,28986,N,59496,59497,28987,N,N,28989,
+59498,59499,59500,28988,N,28991,28994,59501,59502,N,28990,28992,28993,N,59503,
+28995,N,13890,59504,59505,N,59506,59507,N,59508,59509,59510,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,15475,28996,28997,14689,N,59511,N,59512,N,59513,N,N,N,N,N,28998,
+59514,N,13118,N,N,N,18255,28999,29000,N,59515,59516,59517,17242,18027,59518,N,
+N,N,59681,59682,N,29001,59683,N,59684,N,18301,N,59685,16972,12632,13934,N,
+13935,59686,N,N,N,N,N,N,17267,29006,13936,59687,59688,12911,N,N,29005,59689,
+59690,29003,59691,29004,59692,29002,N,N,29016,N,N,N,N,59693,N,N,59694,59695,
+59696,29007,29008,N,59697,29009,29010,N,59698,59699,N,N,29012,59700,N,29011,N,
+59701,59702,15705,29013,59703,59704,59705,29015,N,N,N,N,N,59706,59707,N,13619,
+29014,59708,59709,16763,14387,N,N,59710,N,N,29017,N,N,N,N,59711,N,59712,N,
+59713,59714,59715,N,N,59716,16973,N,N,29018,N,59717,59718,N,17965,N,N,59719,N,
+59720,59721,29019,59722,N,N,N,N,N,29024,N,29022,59724,29021,29023,59725,29020,
+N,59723,N,N,59726,59727,59728,29026,59729,N,N,59730,N,N,59731,29025,59732,
+29028,N,N,13891,29027,N,59733,N,29029,N,N,29030,N,29032,29031,N,N,N,29033,
+29035,29034,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,14716,N,59734,N,59735,
+29036,59736,59737,29037,N,59738,N,59739,59740,59741,N,13116,59742,N,59743,
+29038,N,59744,59745,29039,59746,N,59747,16241,N,59748,N,59749,N,N,N,N,N,59750,
+29040,59751,29041,59752,29042,29043,59753,59754,59755,14690,N,N,59756,59757,N,
+29044,29045,59758,N,29046,29047,59759,59760,29048,59761,N,59762,18481,29050,
+59763,18726,29051,29049,N,29053,59764,59765,29052,59766,N,29054,N,59767,59768,
+29217,N,59769,N,59770,59771,59772,59773,59774,59937,59938,29218,N,59939,59940,
+N,59941,59942,59943,59944,N,59945,N,59946,N,N,N,59947,N,29219,59948,29220,
+59949,59950,N,N,29221,59951,N,29222,29223,N,29224,59952,29225,29226,29227,
+29228,59953,N,59954,29229,29230,N,23861,29231,59955,59956,59957,N,59958,N,
+59959,59960,25720,13620,59961,N,N,N,13089,14898,29233,29232,19493,N,N,59962,N,
+N,59963,59964,29235,29236,29234,N,29237,N,N,19298,59965,59966,59967,29238,N,
+13691,59968,N,N,59969,N,N,59970,N,59971,N,59972,59973,N,59974,N,59975,59976,
+59977,59978,59979,20261,N,N,N,59980,29239,59981,N,59982,59983,59984,N,N,N,N,N,
+59985,59986,N,N,29241,59987,59988,59989,59990,N,59991,59992,59993,N,59994,
+12350,59995,59996,29242,18987,29240,59997,N,29243,29244,N,N,59998,N,N,59999,
+60000,29245,29246,N,N,N,N,N,60001,60002,29247,60003,19310,15149,60004,14970,
+16687,N,60005,60006,60007,N,29248,N,N,60008,60009,29251,N,60010,60011,N,60012,
+60013,29249,60014,N,N,N,N,29252,60015,60016,14449,29250,N,N,N,60017,29253,
+60018,29254,29255,N,29259,N,15146,60019,60020,N,N,16996,N,60021,N,60022,N,
+29260,29257,29256,29258,60023,N,60024,14175,N,60025,60026,N,N,N,60027,29264,
+29263,29262,60028,N,12339,N,60029,60030,60193,60194,N,N,60195,N,60196,60197,N,
+60198,N,29274,N,29270,N,29271,29267,29273,60199,29269,13154,N,60200,20300,
+60201,29272,29268,29266,29265,60202,N,60203,60204,60205,29276,60206,N,60207,N,
+N,29279,60208,60209,29278,29277,60210,60211,60212,60213,60214,N,N,18761,29275,
+12403,29280,60215,29282,N,N,60216,60217,60218,N,13167,29261,12599,N,60219,
+29284,N,N,60220,N,60221,60222,60223,29283,29281,17197,60224,60225,N,N,N,60226,
+60227,60228,N,19312,60229,60230,N,60231,20058,60232,N,29285,60233,60240,60234,
+60235,60236,29286,N,N,60237,N,N,N,29287,60242,60238,60239,60241,N,N,60243,N,
+60244,N,60245,N,N,60246,29288,60247,29289,N,N,60248,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,17467,60249,29290,N,18487,N,29295,29291,N,N,N,
+29292,N,60250,19249,19524,N,18000,60251,N,60252,60254,29296,N,N,29297,17982,
+29294,29293,N,60253,N,N,12842,N,N,60255,29305,N,N,29304,N,60256,60257,N,N,
+12661,60258,60259,60260,29302,N,N,N,29301,N,N,29299,N,13179,N,29298,15410,
+12841,N,N,60261,60262,N,60263,60264,60265,N,N,N,N,N,60266,14691,60267,60269,
+29308,29307,N,29306,60270,60271,29303,60268,29309,60272,29310,N,60273,N,N,N,N,
+N,29477,29476,N,60274,60275,N,N,N,N,29478,N,N,12589,29473,29474,60276,14708,
+19513,60278,60277,29475,60279,N,N,N,60280,60281,60282,19250,N,N,29483,60283,N,
+29479,N,N,N,60284,60285,N,N,29484,60286,60449,N,60450,N,N,N,N,60451,60452,N,
+60453,29481,N,29480,60454,N,N,60455,60456,14172,N,N,60457,60458,N,60459,60460,
+60461,60462,N,29485,N,N,N,N,N,N,60463,N,N,29486,N,N,N,N,29487,60464,29482,
+60465,N,60466,29300,N,60467,29488,N,17505,60468,N,N,29492,60469,29493,29491,
+60470,N,N,60471,N,29490,29496,60472,29489,N,29494,60473,N,60474,60475,N,N,N,N,
+29495,N,N,N,29498,60476,60477,60478,60479,N,29497,60480,N,N,N,60481,60482,
+60483,N,N,N,N,60484,29500,60485,N,60486,N,60487,N,29501,60488,29502,60489,N,
+20297,60490,60491,N,N,N,29499,17003,14957,N,N,29503,60492,60494,N,N,N,N,60495,
+N,N,60493,N,N,N,60496,N,60497,60498,60499,N,N,60500,60501,N,N,60502,29504,
+29505,60503,60504,29506,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29507,N,N,14388,29508,60505,60506,
+60507,29509,N,15407,60508,29510,60509,60510,60511,60512,N,60513,29511,N,N,
+29512,29513,N,60514,60515,N,29516,29514,20284,N,29515,60516,20079,60517,N,N,
+60518,N,29517,60519,20059,N,N,N,N,60520,29518,18302,N,60521,29519,29521,N,
+60522,29522,60523,60524,60525,N,N,60526,60527,60528,N,N,29520,14701,19533,
+19299,22135,N,23904,19323,N,N,N,N,12843,N,60529,N,60530,N,N,60531,29524,13648,
+29525,29526,29527,N,14709,N,29528,60532,N,N,24660,19547,N,16995,29529,29531,
+29530,60533,29532,N,N,N,60534,29533,N,60535,29534,N,N,N,60536,60537,60538,
+29535,60539,60540,60541,N,29536,60542,29537,29538,60705,29539,N,29540,29541,
+29542,N,60706,60707,60708,N,N,N,29543,29544,60709,N,N,N,N,17700,60710,60711,
+60712,60713,14429,60714,29546,60715,60716,N,60717,60718,60719,N,N,N,60720,
+16717,29547,60721,N,N,N,60722,N,N,N,60723,60724,29548,N,N,60725,N,60726,60727,
+N,60728,N,N,60729,N,60730,60731,18721,60732,60733,29549,60734,N,60735,N,60736,
+60737,60738,60739,60740,N,N,29550,25399,N,N,27738,28781,N,N,29551,60741,29552,
+60742,60743,60744,60745,N,60746,N,N,60747,60748,29554,29555,29556,20080,29553,
+N,N,29557,29558,60749,60750,29560,N,29559,60751,60752,60753,60754,60755,29562,
+60756,N,60757,29563,29561,N,N,60758,N,N,60759,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+20022,N,60760,60761,60762,60763,N,60764,29564,60765,60766,N,N,N,N,29565,25428,
+60767,N,29566,60768,60769,60770,N,60771,8490,N,8564,8560,8563,8565,N,8522,
+8523,8566,8540,8484,N,8485,8511,9008,9009,9010,9011,9012,9013,9014,9015,9016,
+9017,8487,8488,8547,8545,8548,8489,8567,9025,9026,9027,9028,9029,9030,9031,
+9032,9033,9034,9035,9036,9037,9038,9039,9040,9041,9042,9043,9044,9045,9046,
+9047,9048,9049,9050,8526,N,8527,8496,8498,8494,9057,9058,9059,9060,9061,9062,
+9063,9064,9065,9066,9067,9068,9069,9070,9071,9072,9073,9074,9075,9076,9077,
+9078,9079,9080,9081,9082,8528,8515,8529,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8497,
+N,8559,
+};
+
+static const struct unim_index jisxcommon_encmap[256] = {
+{__jisxcommon_encmap+0,92,255},{__jisxcommon_encmap+164,0,245},{
+__jisxcommon_encmap+410,199,221},{__jisxcommon_encmap+433,132,206},{
+__jisxcommon_encmap+508,1,95},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
+{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{__jisxcommon_encmap+603,16,59},{__jisxcommon_encmap+647,3,212},{
+__jisxcommon_encmap+857,0,165},{__jisxcommon_encmap+1023,18,18},{0,0,0},{
+__jisxcommon_encmap+1024,0,239},{__jisxcommon_encmap+1264,5,111},{0,0,0},{0,0,
+0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+__jisxcommon_encmap+1371,0,254},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{__jisxcommon_encmap+1626,0,255},{
+__jisxcommon_encmap+1882,0,255},{__jisxcommon_encmap+2138,0,254},{
+__jisxcommon_encmap+2393,0,254},{__jisxcommon_encmap+2648,0,255},{
+__jisxcommon_encmap+2904,0,250},{__jisxcommon_encmap+3155,1,255},{
+__jisxcommon_encmap+3410,0,255},{__jisxcommon_encmap+3666,5,255},{
+__jisxcommon_encmap+3917,0,255},{__jisxcommon_encmap+4173,0,253},{
+__jisxcommon_encmap+4427,2,255},{__jisxcommon_encmap+4681,0,253},{
+__jisxcommon_encmap+4935,0,255},{__jisxcommon_encmap+5191,1,253},{
+__jisxcommon_encmap+5444,1,254},{__jisxcommon_encmap+5698,0,255},{
+__jisxcommon_encmap+5954,1,255},{__jisxcommon_encmap+6209,7,253},{
+__jisxcommon_encmap+6456,0,255},{__jisxcommon_encmap+6712,0,255},{
+__jisxcommon_encmap+6968,1,250},{__jisxcommon_encmap+7218,6,255},{
+__jisxcommon_encmap+7468,0,255},{__jisxcommon_encmap+7724,0,255},{
+__jisxcommon_encmap+7980,0,255},{__jisxcommon_encmap+8236,2,253},{
+__jisxcommon_encmap+8488,0,255},{__jisxcommon_encmap+8744,0,253},{
+__jisxcommon_encmap+8998,2,255},{__jisxcommon_encmap+9252,2,244},{
+__jisxcommon_encmap+9495,4,252},{__jisxcommon_encmap+9744,0,255},{
+__jisxcommon_encmap+10000,1,254},{__jisxcommon_encmap+10254,0,253},{
+__jisxcommon_encmap+10508,3,255},{__jisxcommon_encmap+10761,0,254},{
+__jisxcommon_encmap+11016,2,255},{__jisxcommon_encmap+11270,0,255},{
+__jisxcommon_encmap+11526,3,255},{__jisxcommon_encmap+11779,0,254},{
+__jisxcommon_encmap+12034,0,252},{__jisxcommon_encmap+12287,2,255},{
+__jisxcommon_encmap+12541,0,252},{__jisxcommon_encmap+12794,0,255},{
+__jisxcommon_encmap+13050,2,254},{__jisxcommon_encmap+13303,0,254},{
+__jisxcommon_encmap+13558,0,251},{__jisxcommon_encmap+13810,0,158},{
+__jisxcommon_encmap+13969,54,255},{__jisxcommon_encmap+14171,0,254},{
+__jisxcommon_encmap+14426,2,255},{__jisxcommon_encmap+14680,0,254},{
+__jisxcommon_encmap+14935,0,253},{__jisxcommon_encmap+15189,1,255},{
+__jisxcommon_encmap+15444,0,255},{__jisxcommon_encmap+15700,0,254},{
+__jisxcommon_encmap+15955,0,255},{__jisxcommon_encmap+16211,1,254},{
+__jisxcommon_encmap+16465,1,255},{__jisxcommon_encmap+16720,0,255},{
+__jisxcommon_encmap+16976,0,159},{__jisxcommon_encmap+17136,55,255},{
+__jisxcommon_encmap+17337,1,255},{__jisxcommon_encmap+17592,1,254},{
+__jisxcommon_encmap+17846,0,254},{__jisxcommon_encmap+18101,0,255},{
+__jisxcommon_encmap+18357,0,255},{__jisxcommon_encmap+18613,0,255},{
+__jisxcommon_encmap+18869,0,253},{__jisxcommon_encmap+19123,1,132},{
+__jisxcommon_encmap+19255,119,230},{__jisxcommon_encmap+19367,28,251},{
+__jisxcommon_encmap+19591,0,255},{__jisxcommon_encmap+19847,1,254},{
+__jisxcommon_encmap+20101,2,255},{__jisxcommon_encmap+20355,1,255},{
+__jisxcommon_encmap+20610,0,255},{__jisxcommon_encmap+20866,0,249},{
+__jisxcommon_encmap+21116,2,254},{__jisxcommon_encmap+21369,2,255},{
+__jisxcommon_encmap+21623,2,165},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,
+0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{__jisxcommon_encmap+21787,1,229},
+};
+
+static const ucs2_t __cp932ext_decmap[969] = {
+65340,65374,8741,65372,8230,8229,8216,8217,8220,8221,65288,65289,12308,12309,
+65339,65341,65371,65373,12296,12297,12298,12299,12300,12301,12302,12303,12304,
+12305,65291,65293,177,215,U,247,65309,8800,65308,65310,8806,8807,8734,8756,
+9794,9792,176,8242,8243,8451,65509,65284,65504,65505,65285,65283,65286,65290,
+65312,167,9734,9733,9675,9679,9678,9671,9670,9633,9632,9651,9650,9661,9660,
+8251,12306,8594,8592,8593,8595,12307,U,U,U,U,U,U,U,U,U,U,U,8712,8715,8838,
+8839,8834,8835,8746,8745,U,U,U,U,U,U,U,U,8743,8744,65506,9312,9313,9314,9315,
+9316,9317,9318,9319,9320,9321,9322,9323,9324,9325,9326,9327,9328,9329,9330,
+9331,8544,8545,8546,8547,8548,8549,8550,8551,8552,8553,U,13129,13076,13090,
+13133,13080,13095,13059,13110,13137,13143,13069,13094,13091,13099,13130,13115,
+13212,13213,13214,13198,13199,13252,13217,U,U,U,U,U,U,U,U,13179,U,12317,12319,
+8470,13261,8481,12964,12965,12966,12967,12968,12849,12850,12857,13182,13181,
+13180,8786,8801,8747,8750,8721,8730,8869,8736,8735,8895,8757,8745,8746,32394,
+35100,37704,37512,34012,20425,28859,26161,26824,37625,26363,24389,20008,20193,
+20220,20224,20227,20281,20310,20370,20362,20378,20372,20429,20544,20514,20479,
+20510,20550,20592,20546,20628,20724,20696,20810,20836,20893,20926,20972,21013,
+21148,21158,21184,21211,21248,21255,21284,21362,21395,21426,21469,64014,21660,
+21642,21673,21759,21894,22361,22373,22444,22472,22471,64015,U,64016,22686,
+22706,22795,22867,22875,22877,22883,22948,22970,23382,23488,29999,23512,23532,
+23582,23718,23738,23797,23847,23891,64017,23874,23917,23992,23993,24016,24353,
+24372,24423,24503,24542,24669,24709,24714,24798,24789,24864,24818,24849,24887,
+24880,24984,25107,25254,25589,25696,25757,25806,25934,26112,26133,26171,26121,
+26158,26142,26148,26213,26199,26201,64018,26227,26265,26272,26290,26303,26362,
+26382,63785,26470,26555,26706,26560,26625,26692,26831,64019,26984,64020,27032,
+27106,27184,27243,27206,27251,27262,27362,27364,27606,27711,27740,27782,27759,
+27866,27908,28039,28015,28054,28076,28111,28152,28146,28156,28217,28252,28199,
+28220,28351,28552,28597,28661,28677,28679,28712,28805,28843,28943,28932,29020,
+28998,28999,64021,29121,29182,29361,29374,29476,64022,29559,29629,29641,29654,
+29667,29650,29703,29685,29734,29738,29737,29742,29794,29833,29855,29953,30063,
+30338,30364,30366,30363,30374,64023,30534,21167,30753,30798,30820,30842,31024,
+64024,64025,64026,31124,64027,31131,31441,31463,64028,31467,31646,64029,32072,
+32092,32183,32160,32214,32338,32583,32673,64030,33537,33634,33663,33735,33782,
+33864,33972,34131,34137,U,34155,64031,34224,64032,64033,34823,35061,35346,
+35383,35449,35495,35518,35551,64034,35574,35667,35711,36080,36084,36114,36214,
+64035,36559,64036,64037,36967,37086,64038,37141,37159,37338,37335,37342,37357,
+37358,37348,37349,37382,37392,37386,37434,37440,37436,37454,37465,37457,37433,
+37479,37543,37495,37496,37607,37591,37593,37584,64039,37589,37600,37587,37669,
+37665,37627,64040,37662,37631,37661,37634,37744,37719,37796,37830,37854,37880,
+37937,37957,37960,38290,63964,64041,38557,38575,38707,38715,38723,38733,38735,
+38737,38741,38999,39013,64042,64043,39207,64044,39326,39502,39641,39644,39797,
+39794,39823,39857,39867,39936,40304,40299,64045,40473,40657,U,U,8560,8561,
+8562,8563,8564,8565,8566,8567,8568,8569,65506,65508,65287,65282,8560,8561,
+8562,8563,8564,8565,8566,8567,8568,8569,8544,8545,8546,8547,8548,8549,8550,
+8551,8552,8553,65506,65508,65287,65282,12849,8470,8481,8757,32394,35100,37704,
+37512,34012,20425,28859,26161,26824,37625,26363,24389,20008,20193,20220,20224,
+20227,20281,20310,20370,20362,20378,20372,20429,20544,20514,20479,20510,20550,
+20592,20546,20628,20724,20696,20810,U,20836,20893,20926,20972,21013,21148,
+21158,21184,21211,21248,21255,21284,21362,21395,21426,21469,64014,21660,21642,
+21673,21759,21894,22361,22373,22444,22472,22471,64015,64016,22686,22706,22795,
+22867,22875,22877,22883,22948,22970,23382,23488,29999,23512,23532,23582,23718,
+23738,23797,23847,23891,64017,23874,23917,23992,23993,24016,24353,24372,24423,
+24503,24542,24669,24709,24714,24798,24789,24864,24818,24849,24887,24880,24984,
+25107,25254,25589,25696,25757,25806,25934,26112,26133,26171,26121,26158,26142,
+26148,26213,26199,26201,64018,26227,26265,26272,26290,26303,26362,26382,63785,
+26470,26555,26706,26560,26625,26692,26831,64019,26984,64020,27032,27106,27184,
+27243,27206,27251,27262,27362,27364,27606,27711,27740,27782,27759,27866,27908,
+28039,28015,28054,28076,28111,28152,28146,28156,28217,28252,28199,28220,28351,
+28552,28597,28661,28677,28679,28712,28805,28843,28943,28932,29020,28998,28999,
+64021,29121,29182,29361,29374,29476,64022,29559,29629,29641,29654,29667,29650,
+29703,29685,29734,29738,29737,29742,29794,29833,29855,29953,30063,30338,30364,
+30366,30363,30374,64023,30534,21167,30753,30798,30820,30842,31024,64024,64025,
+U,64026,31124,64027,31131,31441,31463,64028,31467,31646,64029,32072,32092,
+32183,32160,32214,32338,32583,32673,64030,33537,33634,33663,33735,33782,33864,
+33972,34131,34137,34155,64031,34224,64032,64033,34823,35061,35346,35383,35449,
+35495,35518,35551,64034,35574,35667,35711,36080,36084,36114,36214,64035,36559,
+64036,64037,36967,37086,64038,37141,37159,37338,37335,37342,37357,37358,37348,
+37349,37382,37392,37386,37434,37440,37436,37454,37465,37457,37433,37479,37543,
+37495,37496,37607,37591,37593,37584,64039,37589,37600,37587,37669,37665,37627,
+64040,37662,37631,37661,37634,37744,37719,37796,37830,37854,37880,37937,37957,
+37960,38290,63964,64041,38557,38575,38707,38715,38723,38733,38735,38737,38741,
+38999,39013,64042,64043,39207,64044,39326,39502,39641,39644,39797,39794,39823,
+39857,39867,39936,40304,40299,64045,40473,40657,
+};
+
+static const struct dbcs_index cp932ext_decmap[256] = {
+{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{__cp932ext_decmap+0,95,202},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{__cp932ext_decmap+108,64,156},{0,0,0},{0,0,0},{0,0,0},{0,0,
+0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{__cp932ext_decmap+201,64,252},{__cp932ext_decmap+390,64,252},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+__cp932ext_decmap+579,64,252},{__cp932ext_decmap+768,64,252},{
+__cp932ext_decmap+957,64,75},{0,0,0},{0,0,0},{0,0,0},
+};
+
+static const DBCHAR __cp932ext_encmap[9686] = {
+34690,N,N,N,N,N,N,N,N,N,N,34692,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+34644,34645,34646,34647,34648,34649,34650,34651,34652,34653,N,N,N,N,N,N,61167,
+61168,61169,61170,61171,61172,61173,61174,61175,61176,34708,N,N,N,N,N,N,N,N,N,
+N,N,N,N,34712,N,N,N,N,N,33121,N,N,N,N,N,N,N,N,34707,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,34713,34624,34625,34626,34627,34628,34629,34630,
+34631,34632,34633,34634,34635,34636,34637,34638,34639,34640,34641,34642,34643,
+34688,N,34689,34698,34699,N,N,N,N,N,N,34700,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,34693,34694,34695,34696,34697,34661,N,N,N,N,N,N,N,N,N,
+34665,N,N,N,N,N,N,34656,N,N,N,34659,N,N,N,N,N,N,N,N,N,34657,34667,N,N,34666,
+34660,N,N,N,34668,N,N,N,N,N,N,N,N,N,N,34662,N,N,N,N,34670,N,N,N,N,N,N,N,N,N,N,
+N,N,N,34655,34669,N,N,34658,N,N,N,34663,N,N,N,N,N,34664,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,34686,34703,34702,34701,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,34674,34675,N,N,N,N,N,N,N,N,N,N,N,N,34671,34672,34673,
+N,N,34677,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+34676,N,N,N,N,N,N,N,N,34691,60748,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,60749,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60750,
+60751,N,N,60752,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60753,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,60754,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60756,N,N,N,N,N,N,N,
+60755,N,60758,N,N,N,N,N,60757,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60741,N,N,N,60759,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,60762,60763,N,N,N,60761,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,60760,N,60766,N,N,N,60764,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60765,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60767,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,60769,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,60768,60770,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60771,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,60772,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,60773,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60774,60775,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,60776,N,N,N,N,N,N,N,N,N,60777,N,N,N,N,N,N,N,N,61019,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,60778,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60779,
+60780,N,N,N,N,N,N,60781,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,60782,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,60783,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+60784,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60785,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+60786,60789,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60788,N,N,N,N,N,N,N,N,N,N,N,N,
+60790,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,60791,60792,60793,N,N,N,N,N,N,N,N,N,N,N,60794,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60795,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60797,60796,60801,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,60802,60803,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,60804,N,N,N,N,N,N,N,60805,N,60806,N,N,N,N,N,60807,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,60808,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+60809,60810,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60811,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60813,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,60814,60815,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60816,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,60817,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60818,60819,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60822,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,60820,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60823,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60824,60825,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60826,60827,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,60828,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60747,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60829,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60830,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60831,60832,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60833,N,N,
+N,N,60834,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,60836,N,N,N,N,N,N,N,N,60835,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60838,
+60839,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60837,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60841,N,
+N,N,N,N,N,60840,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60842,60843,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60844,60845,60846,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,60847,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60848,60849,60850,N,N,N,N,N,
+N,N,N,60853,N,N,N,N,N,N,N,N,N,N,N,60851,N,N,N,N,N,N,N,N,60855,N,N,N,N,N,60856,
+N,N,N,N,N,N,N,N,N,60854,N,N,60743,N,N,N,N,N,N,N,N,N,60852,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60858,N,60859,N,N,N,N,N,N,N,N,N,N,N,60857,N,
+N,N,N,N,N,N,N,N,N,N,N,N,60861,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,60862,N,N,N,N,N,N,60863,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,60864,N,N,N,N,N,N,N,N,N,N,N,N,60865,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,60866,60746,60867,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60869,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60870,N,N,N,N,60872,
+60873,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60874,N,N,N,N,N,N,
+N,N,N,N,N,N,N,60871,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,60744,N,N,N,N,N,N,60875,60877,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60879,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60880,60881,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60883,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60882,N,N,N,N,N,N,N,60884,N,N,N,N,N,N,N,
+N,N,N,60885,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60886,N,60887,60888,
+60889,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60890,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,60892,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+60891,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,60893,60894,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,60896,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60895,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,60897,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60898,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60899,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60901,N,N,N,N,N,60900,N,
+N,N,60902,60905,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60903,N,N,60906,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60904,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,60907,60908,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60909,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,60910,60911,N,60912,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,60913,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60914,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60915,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,60742,60917,N,N,N,N,N,N,N,N,N,N,60916,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,60919,60920,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60918,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60922,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+60923,60924,N,N,N,N,N,N,N,N,N,N,N,N,60992,60993,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60995,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60996,N,N,N,N,N,N,N,N,N,N,N,60997,
+N,N,N,N,N,N,N,N,61000,N,N,N,60998,N,N,N,N,N,N,N,N,N,N,N,N,60999,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,61002,61001,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,61003,N,N,61005,61004,N,N,N,61006,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61007,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+61008,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61009,61010,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60812,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61011,61012,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61015,61013,N,61014,N,N,N,N,N,N,N,61016,61018,
+61020,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,61021,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61022,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61023,61024,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,61028,N,N,N,N,N,N,61030,61031,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,61032,N,N,N,61034,61035,61037,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61038,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61040,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,61039,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,61041,61042,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60736,61043,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,61044,61046,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61047,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61048,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61049,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61050,61051,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61052,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60740,61053,N,N,N,N,
+N,61054,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61056,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,61058,61061,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61062,60737,61063,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61064,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61065,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61066,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,61067,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,61068,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61070,
+61071,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,61072,61073,N,N,N,61074,61075,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,61076,61078,61081,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,61082,61084,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+61085,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61087,N,N,61086,N,N,N,61088,N,N,N,
+N,N,61091,61092,N,N,N,N,N,N,N,61089,61090,61093,N,N,N,61095,N,N,N,N,N,61094,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+61102,61096,N,61098,N,N,N,61097,N,N,N,N,N,N,N,N,N,N,N,N,N,61099,N,N,61101,N,N,
+N,N,N,N,N,61100,N,N,N,N,N,N,N,N,N,N,N,N,N,61103,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+61105,61106,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60739,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61104,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61110,N,N,61114,N,61112,N,61108,N,61109,
+N,N,N,N,N,N,61113,N,N,N,N,N,N,61107,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60745,N,
+61117,N,N,N,61120,61122,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+61121,61119,N,N,61116,N,N,N,61115,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,60738,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61124,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61123,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61125,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61126,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61127,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,61128,61129,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61130,N,N,61131,
+61132,61135,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61136,61137,N,N,N,N,N,N,N,61138,
+N,N,N,N,N,N,N,61139,N,N,N,N,N,N,N,N,N,61140,N,61141,N,61142,N,N,N,61143,61144,
+N,N,N,N,N,N,N,N,N,N,N,N,N,61145,61148,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61150,61151,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,61152,N,N,61153,61155,N,N,61154,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,61156,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,61157,N,N,N,N,N,N,N,N,N,61158,61159,61161,N,N,N,N,61160,61163,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61164,60868,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61133,60787,60798,60800,60821,60860,60876,60878,
+60921,60994,61017,61025,61026,61027,61029,61033,61036,61045,61057,61059,61060,
+61069,61077,61079,61080,61083,61111,61118,61134,61146,61147,61149,61162,61180,
+N,N,N,N,61179,N,N,N,N,N,33148,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,33119,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,33120,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,33169,
+33170,33226,N,61178,
+};
+
+static const struct unim_index cp932ext_encmap[256] = {
+{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp932ext_encmap+0,22,121},{__cp932ext_encmap
++100,17,191},{0,0,0},{__cp932ext_encmap+275,96,115},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+__cp932ext_encmap+295,29,31},{0,0,0},{__cp932ext_encmap+298,49,168},{
+__cp932ext_encmap+418,3,205},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{__cp932ext_encmap+621,40,252},{__cp932ext_encmap+834,0,255},{
+__cp932ext_encmap+1090,30,244},{__cp932ext_encmap+1305,74,236},{
+__cp932ext_encmap+1468,21,219},{__cp932ext_encmap+1667,0,221},{
+__cp932ext_encmap+1889,138,255},{__cp932ext_encmap+2007,134,134},{0,0,0},{
+__cp932ext_encmap+2008,89,200},{__cp932ext_encmap+2120,158,178},{
+__cp932ext_encmap+2141,11,186},{0,0,0},{__cp932ext_encmap+2317,86,236},{
+__cp932ext_encmap+2468,30,245},{__cp932ext_encmap+2684,39,208},{0,0,0},{
+__cp932ext_encmap+2854,33,222},{__cp932ext_encmap+3044,93,242},{
+__cp932ext_encmap+3194,17,152},{__cp932ext_encmap+3330,19,166},{
+__cp932ext_encmap+3478,245,245},{__cp932ext_encmap+3479,96,206},{
+__cp932ext_encmap+3590,78,78},{__cp932ext_encmap+3591,0,251},{
+__cp932ext_encmap+3843,14,192},{__cp932ext_encmap+4022,1,207},{
+__cp932ext_encmap+4229,104,226},{__cp932ext_encmap+4352,48,228},{
+__cp932ext_encmap+4533,214,214},{__cp932ext_encmap+4534,63,218},{
+__cp932ext_encmap+4690,4,252},{__cp932ext_encmap+4939,39,191},{
+__cp932ext_encmap+5092,136,245},{__cp932ext_encmap+5202,5,187},{
+__cp932ext_encmap+5385,4,254},{__cp932ext_encmap+5636,177,190},{
+__cp932ext_encmap+5650,36,245},{__cp932ext_encmap+5860,7,159},{
+__cp932ext_encmap+6013,1,111},{__cp932ext_encmap+6124,130,166},{
+__cp932ext_encmap+6161,70,70},{__cp932ext_encmap+6162,33,122},{
+__cp932ext_encmap+6252,48,155},{__cp932ext_encmap+6360,209,235},{
+__cp932ext_encmap+6387,158,158},{0,0,0},{__cp932ext_encmap+6388,72,214},{
+__cp932ext_encmap+6531,82,138},{__cp932ext_encmap+6588,71,161},{0,0,0},{0,0,0
+},{0,0,0},{__cp932ext_encmap+6679,1,246},{__cp932ext_encmap+6925,72,220},{
+__cp932ext_encmap+7074,83,176},{0,0,0},{0,0,0},{__cp932ext_encmap+7168,7,245},
+{__cp932ext_encmap+7407,28,28},{__cp932ext_encmap+7408,18,246},{
+__cp932ext_encmap+7637,83,127},{__cp932ext_encmap+7682,240,244},{
+__cp932ext_encmap+7687,18,118},{__cp932ext_encmap+7788,207,207},{0,0,0},{
+__cp932ext_encmap+7789,103,222},{__cp932ext_encmap+7909,21,238},{
+__cp932ext_encmap+8127,6,255},{__cp932ext_encmap+8377,2,248},{
+__cp932ext_encmap+8624,49,72},{__cp932ext_encmap+8648,146,146},{
+__cp932ext_encmap+8649,157,175},{__cp932ext_encmap+8668,51,85},{
+__cp932ext_encmap+8703,87,101},{__cp932ext_encmap+8718,39,158},{
+__cp932ext_encmap+8838,78,220},{__cp932ext_encmap+8981,114,187},{
+__cp932ext_encmap+9055,0,0},{__cp932ext_encmap+9056,107,112},{
+__cp932ext_encmap+9062,25,209},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp932ext_encmap+9247
+,41,220},{__cp932ext_encmap+9427,14,45},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+__cp932ext_encmap+9459,2,228},
+};
+
+static const ucs2_t __jisx0213_1_bmp_decmap[2197] = {
+65287,65282,65293,126,12339,12340,12341,12347,12348,12543,12447,U,U,U,U,U,U,U,
+U,8836,8837,8842,8843,8713,8709,8965,8966,U,U,U,U,U,U,U,8853,8854,8855,8741,
+8742,10629,10630,12312,12313,12310,12311,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,8802,
+8771,8773,8776,8822,8823,8596,U,U,U,U,U,U,U,U,9838,9835,9836,9833,9655,9654,
+9665,9664,8599,8600,8598,8601,8644,8680,8678,8679,8681,10548,10549,U,U,U,U,U,
+U,U,U,U,U,10687,9673,12349,65094,65093,9702,8226,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,8723,8501,8463,13259,8467,8487,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,12448,8211,10746,10747,12363,U,12365,U,12367,U,
+12369,U,12371,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,12436,12437,
+12438,12459,U,12461,U,12463,U,12465,U,12467,U,U,U,U,U,U,U,12475,U,U,U,U,U,U,U,
+U,12484,U,U,U,12488,9828,9824,9826,9830,9825,9829,9831,9827,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,962,9461,9462,9463,9464,9465,9466,9467,9468,
+9469,9470,9750,9751,12320,9742,9728,9729,9730,9731,9832,9649,12784,12785,
+12786,12787,12788,12789,12790,12791,12792,12793,U,12794,12795,12796,12797,
+12798,12799,9150,9151,9152,9153,9154,9155,9156,9157,9158,9159,9160,9161,9162,
+9163,9164,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+12535,12536,12537,12538,8922,8923,8531,8532,8533,10003,8984,9251,9166,12881,
+12882,12883,12884,12885,12886,12887,12888,12889,12890,12891,12892,12893,12894,
+12895,12977,12978,12979,12980,12981,12982,12983,12984,12985,12986,12987,12988,
+12989,12990,12991,U,U,U,U,U,U,U,U,9680,9681,9682,9683,8252,8263,8264,8265,461,
+462,464,7742,7743,504,505,465,466,468,470,472,474,476,8364,160,161,164,166,
+169,170,171,173,174,175,178,179,183,184,185,186,187,188,189,190,191,192,193,
+194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,
+213,214,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,
+233,234,235,236,237,238,239,240,241,242,243,244,245,246,248,249,250,251,252,
+253,254,255,256,298,362,274,332,257,299,363,275,333,260,728,321,317,346,352,
+350,356,377,381,379,261,731,322,318,347,711,353,351,357,378,733,382,380,340,
+258,313,262,268,280,282,270,323,327,336,344,366,368,354,341,259,314,263,269,
+281,283,271,273,324,328,337,345,367,369,355,729,264,284,292,308,348,364,265,
+285,293,309,349,365,625,651,638,643,658,620,622,633,648,598,627,637,642,656,
+635,621,607,626,669,654,609,331,624,641,295,661,660,614,664,450,595,599,644,
+608,403,339,338,616,649,600,629,601,604,606,592,623,650,612,652,596,593,594,
+653,613,674,673,597,657,634,615,602,U,509,8048,8049,U,U,U,U,U,U,U,U,8050,8051,
+865,712,716,720,721,774,8255,779,769,772,768,783,780,770,741,742,743,744,745,
+U,U,805,812,825,796,799,800,776,829,809,815,734,804,816,828,820,797,798,792,
+793,810,826,827,771,794,10102,10103,10104,10105,10106,10107,10108,10109,10110,
+10111,9451,9452,9453,9454,9455,9456,9457,9458,9459,9460,8560,8561,8562,8563,
+8564,8565,8566,8567,8568,8569,8570,8571,9424,9425,9426,9427,9428,9429,9430,
+9431,9432,9433,9434,9435,9436,9437,9438,9439,9440,9441,9442,9443,9444,9445,
+9446,9447,9448,9449,13008,13009,13010,13011,13012,13013,13014,13015,13016,
+13017,13018,13019,13020,13021,13022,13023,13024,13025,13026,13027,13050,13033,
+13029,13037,13036,U,U,U,U,U,U,U,U,U,8273,8258,9312,9313,9314,9315,9316,9317,
+9318,9319,9320,9321,9322,9323,9324,9325,9326,9327,9328,9329,9330,9331,8544,
+8545,8546,8547,8548,8549,8550,8551,8552,8553,8554,13129,13076,13090,13133,
+13080,13095,13059,13110,13137,13143,13069,13094,13091,13099,13130,13115,13212,
+13213,13214,13198,13199,13252,13217,8555,U,U,U,U,U,U,U,13179,12317,12319,8470,
+13261,8481,12964,12965,12966,12967,12968,12849,12850,12857,13182,13181,13180,
+U,U,U,8750,U,U,U,U,8735,8895,U,U,U,10070,9758,20465,U,13314,20008,20015,20016,
+20109,20193,20221,20223,20227,20235,20320,20296,20297,20310,20319,20330,20332,
+20350,20362,20372,20375,64048,20425,20448,20481,20482,20494,20504,20519,20526,
+20544,20539,20545,20628,20684,20722,20688,20710,64049,20742,20739,20747,20766,
+20789,20810,64050,20821,20823,13493,20893,20931,20938,20958,20962,20974,20993,
+13531,21011,21013,21065,21079,21089,21139,21192,64051,21196,21200,21206,21211,
+64052,21232,21243,21248,21255,21276,64053,21345,21347,21373,21395,21405,21426,
+21522,21543,21581,21660,21611,21620,21631,21640,21654,21665,21673,21702,21759,
+21774,21803,21813,21840,21854,21889,21894,21902,64054,21933,21966,64055,22024,
+22030,22075,22089,22134,22118,64056,22127,22129,22130,22169,22174,22185,22188,
+22195,22217,22218,22282,U,22305,22319,22323,22324,22384,22391,22396,22428,
+64015,U,22456,22471,22472,22479,22500,22509,22517,22518,22527,22537,64016,
+22625,22628,64057,22652,22665,22686,64058,22697,U,22738,22734,22740,22746,
+22752,22761,22796,34369,22877,22893,22923,22930,22948,22979,22994,23005,23059,
+23075,23143,23149,23159,23166,23172,23198,23207,23236,U,23321,23333,21085,
+23361,23382,23421,23443,23512,23532,23570,23582,23587,23595,14221,23650,64059,
+64060,U,23674,23695,23711,23715,23722,23738,23755,23760,23762,23796,U,14306,
+23821,23847,64017,23878,23879,23891,23882,23917,23937,23968,23972,23975,23992,
+24011,21534,22099,24034,24084,24088,24152,24158,24254,63784,24267,24313,24320,
+24322,24327,24349,24355,24372,24374,24381,24384,24389,24404,24408,24420,24423,
+24445,24457,24476,24487,24495,24501,24503,24521,24542,24545,24553,24589,24596,
+24600,24627,24629,24647,64061,24733,24734,24779,24788,24789,24797,24824,24860,
+24875,24880,24887,64062,24973,64063,25020,25017,64064,25122,25150,25155,25174,
+25178,25199,25221,25284,25302,25340,25354,25368,25401,25411,25445,25468,25573,
+25581,25589,25616,25620,25634,25721,25681,25696,25709,25806,25790,25791,25796,
+25802,25808,25847,25851,25890,25897,64065,25959,26013,64066,26112,26121,26133,
+26142,26170,26146,26148,26155,26160,26161,26163,26363,26184,26188,U,26201,
+26202,26209,26213,26227,26231,26232,26253,64067,26272,26290,26299,26310,26312,
+15138,26331,26344,26362,26387,63785,26419,26470,26439,26440,26491,26497,26515,
+26520,26523,26555,26617,26560,26583,26620,26625,26706,26653,26668,26673,26715,
+26738,26741,64068,26787,26789,26802,26824,26832,26856,26861,26864,26865,26876,
+26890,26953,U,26933,26946,26967,26979,26980,26984,27008,64020,27045,27053,
+27087,15286,15299,27106,27113,27114,27125,27126,27151,27157,U,27195,27198,
+27205,27216,27222,27227,27243,27251,U,27273,27284,27293,27294,27301,27364,
+27367,15375,63773,27419,27422,27436,27445,27462,27478,27488,27493,27495,27511,
+27522,27561,27565,63856,27599,27606,27607,27647,27653,27664,27699,27737,27740,
+27818,27764,27766,27781,27782,27800,27804,27899,27846,27860,27872,27883,27886,
+U,27908,27918,27950,27953,27961,27967,27992,28005,64069,28034,28039,28041,
+28052,28074,28076,28095,28100,28118,28122,28123,28125,28156,64070,28212,28228,
+28252,28254,28331,28337,28353,28359,28366,28432,28442,64071,28458,28463,28467,
+28497,28505,28510,28513,28514,28542,28552,28556,28557,28564,28576,28583,28598,
+28604,28615,28618,28665,28656,28661,28677,28678,28712,28746,28765,28766,28750,
+28772,28789,28805,28836,28843,28855,28884,28888,28900,28943,28971,28958,28960,
+28974,28976,28998,28999,29009,64072,29010,29020,29024,29032,64021,29061,29063,
+29074,29121,29114,29124,29182,29184,29205,29269,29270,15935,29325,29339,29374,
+29376,29435,U,29479,29480,64022,29520,29542,29564,29589,29599,29600,29602,
+29606,29611,29641,29647,29654,29657,29667,29673,29703,29706,29722,29723,64074,
+29734,29736,29738,29739,29740,29742,29743,29744,29764,29766,29767,29771,29783,
+29794,29803,29805,29830,29831,29833,29848,29852,29855,29859,29840,29862,29864,
+29865,29877,29887,29896,29897,29914,29951,29953,29975,29999,30063,30073,30098,
+16242,30158,30180,30208,30210,30216,30229,30230,30233,30238,30253,30261,30275,
+30283,30308,30309,30317,30319,30321,30337,30363,30365,30366,30374,30378,30390,
+30405,30412,30414,30420,30438,30449,30460,30474,30489,30516,30518,30534,30541,
+30542,30556,30559,30562,30586,30592,30612,30634,30688,30765,30787,30798,30799,
+30801,30824,30830,64075,30896,U,30893,30948,30962,30976,30967,31004,31022,
+31025,31028,64076,64077,31045,31046,64078,64079,64080,31068,64081,64025,64026,
+31097,64082,64083,64027,31128,31153,31160,31176,31178,U,31188,31198,31211,
+31213,31235,64084,31289,31325,31341,64085,31365,31392,U,31411,31419,31438,
+31467,31485,31506,31533,31547,31559,31566,31584,31597,31599,31602,31646,64086,
+31703,31705,31745,31793,31774,31776,31795,31798,16996,U,31833,31853,31865,
+31887,31892,31904,31932,31957,31961,31965,32007,32008,32019,32029,32035,32049,
+32065,32072,32083,32092,32122,32131,32139,32160,32166,32194,32204,32214,32227,
+64087,32296,32264,32273,32277,64089,32327,32338,32353,32394,32397,32583,64090,
+32657,32663,32703,32718,32731,32735,32748,32750,32762,64091,32788,32806,32821,
+32823,32828,32970,32983,32992,33011,33048,33098,33120,33127,33128,33133,33211,
+33226,33231,33239,64092,17491,17499,33376,33396,U,33422,33441,33443,33444,
+33449,33454,33463,33470,33471,33478,33493,33533,33534,33536,33537,33634,33570,
+33581,33594,33603,33607,33617,33621,33661,33670,33682,33688,33703,33705,33727,
+33728,33735,33743,33745,33761,33770,33793,33798,33802,64095,33864,33887,33904,
+33907,33925,33950,33967,33972,33978,33984,33986,U,34098,34078,34083,34095,
+34137,34148,64031,34221,34170,34188,34191,34210,34224,34251,34254,34285,34322,
+34303,34308,34309,34320,U,34328,34345,34360,34391,34395,63798,34402,17821,
+34412,34421,34456,34488,34554,34556,34557,34571,34673,34695,34696,34732,34733,
+34741,17898,34774,34796,34822,34826,34832,34836,34847,34968,34986,35018,35022,
+U,35061,35100,64096,35096,35097,35098,35111,35120,35122,35129,35136,35220,
+64097,35284,35301,35318,35346,35349,35362,35383,35399,35406,35421,35425,35445,
+35449,35495,35536,35551,35572,35574,64034,64098,64099,35654,35668,35673,35689,
+35741,35913,35944,64100,36065,36084,36088,36094,64101,36114,36123,36271,36302,
+36305,36311,36384,36387,36413,36464,36475,U,36544,18500,36602,36638,36653,
+36662,36692,U,36774,36789,36836,36840,36846,36872,36909,64103,37000,37013,
+37015,37017,37019,37026,37043,37054,37060,37061,37063,37079,37085,37086,37103,
+37108,64038,37140,37141,37142,37154,37155,37159,37167,37169,37172,37181,37192,
+37211,37251,37278,37292,37297,37308,37335,37371,37348,37349,37357,37361,37383,
+37392,37432,37433,37434,37436,37440,37443,37455,37496,37512,37570,37579,37580,
+37587,37600,37631,37636,37663,37665,37669,37704,37705,37706,37732,37733,37738,
+37744,37787,37795,37818,37830,37854,37855,37892,37885,37939,37962,37987,37995,
+38001,38002,38286,38303,38310,38313,38316,38326,38333,38347,38352,38355,18864,
+38362,38366,38488,38532,63964,38557,38564,38565,38610,38622,64104,38633,38639,
+38707,38715,38733,38734,38735,38746,38766,38771,38805,38830,38842,38849,38857,
+38878,38875,38900,64105,38922,38942,38955,38960,64106,38994,38995,38998,38999,
+39001,39002,63952,39013,39020,39098,39112,39143,39256,39326,39426,39427,39460,
+39469,39470,39480,39498,39502,39506,39606,39617,39619,39630,39638,39673,39682,
+39688,39712,19479,39725,39774,39801,39782,39794,39797,39812,39818,39823,39838,
+39847,39873,39886,39909,39928,39933,39936,39971,40001,40015,40016,40019,40035,
+40037,40055,40221,40222,40259,40263,40274,40291,40304,40316,40330,40342,40384,
+40364,40380,40407,U,40423,40455,40469,40572,40606,40612,40620,40623,40628,
+40629,40643,40657,40720,40761,40791,40848,40852,40855,40866,23032,23643,24183,
+30246,32363,
+};
+
+static const struct dbcs_index jisx0213_1_bmp_decmap[256] = {
+{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__jisx0213_1_bmp_decmap+0,47,125},{
+__jisx0213_1_bmp_decmap+79,33,126},{__jisx0213_1_bmp_decmap+173,43,118},{
+__jisx0213_1_bmp_decmap+249,43,72},{__jisx0213_1_bmp_decmap+279,57,126},{
+__jisx0213_1_bmp_decmap+349,66,126},{__jisx0213_1_bmp_decmap+410,65,124},{
+__jisx0213_1_bmp_decmap+470,33,126},{__jisx0213_1_bmp_decmap+564,33,126},{
+__jisx0213_1_bmp_decmap+658,33,126},{__jisx0213_1_bmp_decmap+752,33,126},{
+__jisx0213_1_bmp_decmap+846,33,126},{__jisx0213_1_bmp_decmap+940,33,126},{
+__jisx0213_1_bmp_decmap+1034,33,126},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__jisx0213_1_bmp_decmap+
+1128,85,126},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+__jisx0213_1_bmp_decmap+1170,39,126},{__jisx0213_1_bmp_decmap+1258,33,126},{
+__jisx0213_1_bmp_decmap+1352,33,126},{__jisx0213_1_bmp_decmap+1446,33,126},{
+__jisx0213_1_bmp_decmap+1540,33,125},{__jisx0213_1_bmp_decmap+1633,33,126},{
+__jisx0213_1_bmp_decmap+1727,33,126},{__jisx0213_1_bmp_decmap+1821,33,126},{
+__jisx0213_1_bmp_decmap+1915,33,126},{__jisx0213_1_bmp_decmap+2009,33,126},{
+__jisx0213_1_bmp_decmap+2103,33,126},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
+};
+
+static const ucs2_t __jisx0213_2_bmp_decmap[2425] = {
+19970,19983,19986,20009,20011,20014,20032,20039,20040,U,20049,13318,U,20058,
+20073,20125,13356,13358,20153,20155,U,20156,20163,20168,20176,20203,20186,
+20209,20213,20224,20246,20324,20279,20286,20308,20312,U,20343,20344,20346,
+20349,20354,20357,20370,20378,20454,20402,20414,20421,20427,20431,20434,13418,
+20466,20480,20496,20499,20508,20510,20514,13416,20546,20550,20558,20563,20567,
+20579,20582,20586,20592,20643,20616,20626,20627,20629,20630,20636,20650,U,
+20657,20666,20667,20676,20679,20723,U,20686,U,20692,20697,20705,20713,13458,
+20744,U,20759,20763,U,20832,U,20851,20867,20875,13500,20888,20899,20909,13511,
+20924,U,U,20979,20980,20994,21010,21014,U,21077,21084,21100,21111,21124,21122,
+U,21144,U,21156,21158,21167,21178,21179,21194,13599,21201,U,21239,21258,21259,
+21284,21301,21310,21314,U,U,21351,21356,21370,21412,21428,U,21431,21440,U,
+13661,13662,21461,21466,13667,21492,21493,21589,21540,21544,13678,21571,21602,
+21606,21612,21642,21645,21653,21664,21670,21677,21678,21687,21690,21695,21699,
+U,21740,21743,21745,21747,21760,21761,21769,21820,21825,13734,21831,21834,
+13736,21856,21857,21860,U,21885,21890,21896,21905,13765,21970,U,U,21951,21961,
+21964,21969,21981,13786,21986,U,21993,22056,U,22023,22032,22064,22071,13812,
+22077,22079,22080,22087,22110,22112,22125,13829,22152,22156,22165,22170,22173,
+22184,22189,22194,22213,22221,22239,22248,22262,22263,U,22293,22307,U,22313,U,
+22341,22342,22348,22349,U,22376,22383,22387,22388,22389,22395,U,U,22444,22426,
+22429,22430,22440,22487,U,22476,U,U,22494,22502,22512,13898,22520,22523,22525,
+22532,22558,22560,22567,22578,22585,U,22601,22604,22631,22666,22667,22669,
+22671,22672,22676,22685,22698,22705,U,22723,22733,22754,22771,22772,22789,
+22790,22795,22797,22804,22820,U,13969,22845,13977,22854,13974,U,22875,22879,U,
+22901,22902,22908,22943,22958,22972,22984,22989,23006,23011,23012,23015,23022,
+U,U,14031,23052,23053,23063,23079,23085,23125,23141,23162,23179,23196,23199,
+23200,23202,23217,23219,23221,23226,23231,23258,23260,23264,23269,23280,23278,
+23285,23296,23304,23319,23348,23341,23372,23378,23400,23407,23420,23423,23425,
+23428,23446,23468,14177,23488,14178,23502,23510,14188,14187,23537,23549,14197,
+23555,23593,23600,U,23647,23651,23655,23656,23657,23664,U,U,23676,U,U,23688,
+23690,14273,U,U,23712,23714,23718,23719,U,23725,23733,U,23753,U,U,23814,23824,
+23851,23837,23840,23844,23846,23857,23865,23874,14312,23905,23914,14324,23920,
+U,14333,23944,14336,23954,23956,23959,23961,23984,23986,23988,U,23993,24017,
+24023,24024,24032,U,24036,24041,14383,24064,14390,24082,24085,14400,24095,
+24110,24126,24137,14428,24150,14433,24171,24172,24173,24174,U,24229,24234,
+24236,24249,24255,24262,24274,24281,U,24317,24328,24334,24348,U,24350,24391,
+24419,24434,24446,24463,24482,24484,24504,24516,14586,24519,24523,24530,24531,
+24532,24546,24558,24559,24563,24572,14615,24599,24610,24612,14618,24652,24703,
+24714,24725,24744,U,24752,24753,24766,24776,24793,24795,24814,24818,24821,
+24848,24850,24851,24857,24862,24890,14703,24897,24902,24928,24956,U,24978,
+24979,24983,24984,24997,25000,25005,U,25045,25053,25055,25077,U,25109,25123,
+25129,25158,25164,25169,25170,25185,25188,25211,25197,25203,25241,25254,25301,
+U,25341,25347,25357,25360,U,U,25394,25397,25403,25404,25409,25412,25422,U,
+25433,U,U,25452,25476,25497,U,25492,25533,25591,25556,25557,25564,25568,25579,
+25580,25586,25609,25630,25637,25641,25647,25690,25691,25693,25715,25725,25735,
+25745,25757,25759,25803,25804,25813,25815,U,25828,25829,25855,25860,14958,
+25871,25876,25878,14963,25886,25906,25924,25940,25963,25978,25985,25988,25989,
+25994,26034,26037,26040,26047,26050,26057,26068,15062,26098,26105,26108,26116,
+26120,26145,26154,26181,26193,26190,15082,U,26199,26203,26211,U,U,26218,26219,
+26220,26221,26235,26240,26256,26258,26265,15118,26285,26289,26293,15130,26303,
+15132,26348,15063,26369,26373,26386,U,26393,U,U,26444,26445,26452,26461,U,U,U,
+26484,26486,U,26514,U,33635,26640,26544,26546,26563,26568,26578,26585,26587,
+26608,26615,U,U,U,26648,26655,26669,U,26675,26683,26686,26692,26693,26697,
+26700,26709,26711,15223,26731,26734,26746,26748,26754,26768,26774,15213,26776,
+26777,26778,26780,26794,26795,26804,26811,26875,U,U,64019,26819,26821,26828,
+26831,26838,26841,26852,26853,26860,26871,26883,26887,15239,15240,U,26939,
+15245,26950,26985,26988,26994,27002,27007,27026,15268,27030,27032,27046,27056,
+27063,27066,27068,27072,27089,27094,U,U,27184,U,U,27107,27118,27119,27123,
+15309,27124,27134,27153,27162,27165,U,27186,27187,27188,27199,27206,27209,
+27258,27214,27218,27236,U,27262,27267,27275,15344,27281,27295,27297,U,27307,
+27325,27334,27348,27344,27356,27357,U,U,27372,27377,27378,27379,27389,U,27403,
+27407,27408,27409,U,27415,15398,27439,27466,27480,27500,27509,27514,27521,
+27547,27566,U,27581,27582,27591,27592,27593,27610,27622,27623,27630,27633,
+27650,27658,27662,27701,27702,27706,U,27711,27725,27739,27757,27780,27785,
+15555,27796,27797,27799,27821,27842,27856,15570,27862,27866,27868,27881,27884,
+27885,U,27904,27914,27940,27942,27943,27751,27951,27964,27995,27998,28000,
+28016,28032,28033,28042,28045,28049,28056,U,28183,U,U,U,28075,28078,28084,
+28098,27956,28104,28110,28111,28112,28127,28137,28150,28214,28190,28194,28199,
+15633,28210,28220,28232,28233,28235,28236,28239,28241,28243,28244,28247,28259,
+15646,28307,28327,28340,28351,28355,28362,28377,28469,28395,28409,28411,28426,
+28428,28440,28453,28470,28476,U,28498,28503,28506,28512,28520,28568,28541,
+28560,28566,28606,28575,28581,28591,15716,28597,28616,28617,28634,28638,28649,
+U,28668,28672,28679,28682,28707,U,28729,28730,28732,28739,28743,28747,15770,
+28756,28773,28777,28780,28782,28790,28798,28801,28806,28821,28823,28859,U,
+28831,28849,U,28908,28874,28881,28883,28892,28931,28932,28934,28935,28936,
+28940,15808,28975,28977,29008,29002,29011,29022,15828,29078,29056,29083,29088,
+29090,29102,29103,29107,U,29131,29139,29145,29148,29191,15877,64073,29227,
+29236,29240,29241,20012,29250,29267,29271,29283,U,29294,29295,29304,29311,
+29326,U,29357,29358,29360,29361,29377,15968,29388,15974,15976,29427,29434,
+29447,29458,29464,29465,16003,29497,29484,29489,29491,29501,29522,16020,29547,
+29548,U,29550,29551,29553,29559,29569,29573,29578,29588,29592,29596,29598,
+29605,29608,29621,29623,29625,29628,29631,29637,29643,29665,29671,29689,29715,
+29690,29697,29732,29745,29753,29779,29760,29763,29773,29778,29789,29809,29825,
+29829,29832,U,29842,29847,29849,29856,29857,29861,29866,29867,29881,29883,
+29882,29910,29912,29918,29935,29931,U,29946,U,29984,29988,29994,16215,U,30013,
+30014,30016,30024,30030,30032,30034,30060,30066,30065,30074,30077,30078,30081,
+U,30092,16245,30114,16247,30128,30135,30143,30144,30150,30159,30163,30173,
+30175,30176,30183,30188,30190,30193,30201,30211,30232,30215,30223,16302,U,
+30227,30235,30236,U,30245,30248,30268,30259,U,16329,30273,U,30281,30293,16343,
+30318,30357,30364,30369,30368,30375,30376,30383,U,30409,U,30440,30444,U,30487,
+30490,30509,30517,16441,U,U,30552,30560,30570,U,30578,30588,30589,U,16472,
+30618,30623,30626,30628,30633,30686,30687,30692,30694,30698,30700,16531,30704,
+30708,30715,U,30725,30726,30729,30733,30745,30753,30764,30791,30820,30826,U,
+30858,30868,30884,30877,30878,30879,30907,30920,30924,30926,30933,30944,30945,
+30950,30969,30970,30971,30974,U,30992,31003,31024,31013,31035,31050,31064,
+31067,16645,31079,31090,31124,31125,31126,31131,31137,31145,31156,31163,31170,
+31175,31180,31181,31190,16712,U,U,16719,31242,31249,31253,31259,31262,16739,
+31277,31288,31303,31308,31318,31321,31324,31327,31328,31335,31338,31349,31352,
+31362,31370,31376,31395,31404,U,16820,31417,31420,31422,16831,31436,31441,
+31463,31464,31476,U,U,31495,U,31549,31527,31530,31534,31535,31537,16870,16883,
+31615,31553,16878,31573,31609,31588,31590,31593,31603,U,16903,31632,31633,
+31643,16910,31663,31669,31676,31685,31690,U,U,31700,31702,31706,31722,31728,
+31747,31755,31758,31759,31782,31813,31818,31825,31831,31838,31841,31849,31854,
+31855,31856,U,U,U,31910,U,31926,31927,31935,U,31940,U,31944,31949,U,31959,U,
+31974,31979,U,31989,32003,32009,17094,32018,32030,U,U,32061,32062,32064,32071,
+U,U,17110,32089,32090,32106,32112,17117,32127,U,32134,32136,32140,32151,U,
+32157,32167,32170,32182,32183,32192,32215,32217,32230,32241,32249,17154,U,
+64088,32272,32279,32285,32288,32295,32300,32325,32371,32373,32382,32390,32391,
+17195,32401,32408,32410,17219,32572,32571,32574,32579,32580,32591,13505,U,
+32594,U,32609,32611,32612,32621,32637,32638,U,32656,20859,U,32662,32668,32685,
+U,32707,32719,32739,32741,32751,32754,32770,32778,32776,32782,32785,32790,
+32804,32812,32816,32835,32870,32881,32885,32891,32921,32924,32932,32935,32952,
+U,32965,32981,32984,32998,U,33037,33013,33019,17390,33077,33046,33054,17392,
+33060,33063,33068,U,33085,17416,33129,17431,33153,17436,33156,33157,17442,
+33176,33202,33217,33219,33238,33243,U,33252,U,33260,U,33277,33279,U,33284,U,
+33305,33313,33314,U,33330,33332,33340,33350,33353,33349,U,33355,17526,33359,
+17530,33367,U,33372,33379,U,64093,64094,33401,17553,33405,33407,33411,33418,
+33427,33447,33448,33458,33460,33466,33468,33506,33512,33527,33543,33544,33548,
+33620,33563,33565,33584,33596,33604,33623,17598,33663,17620,17587,33677,33684,
+33685,33691,33693,33737,33744,33748,33757,33765,33785,33807,33809,33813,U,
+33815,33849,33866,33871,33873,33874,33881,33882,33884,U,33893,33910,33912,
+33916,33921,17677,34012,33943,33958,33982,17672,33998,33999,34003,U,34023,
+34026,34031,34032,34033,34042,34045,34060,34075,34084,34085,34091,34100,34127,
+34159,17701,17731,34110,34129,34131,34142,34145,34146,U,34171,34173,34175,
+34177,34182,34195,34205,34207,34231,34236,34247,34250,34264,34265,34271,34273,
+34278,34294,34304,34321,34334,34337,34340,34343,U,34361,34364,U,34368,64032,
+34387,34390,34415,34423,34426,34439,34441,34445,34449,34460,34461,34472,64033,
+34481,34483,34497,34499,34513,34517,34519,34531,34534,17848,34565,34567,34574,
+34576,34579,34585,34591,34593,34595,34609,34618,34622,34624,34627,34641,34648,
+34660,34661,34674,34684,U,U,34727,34697,34699,34707,34720,U,17893,34750,U,
+34753,34766,34805,34783,U,34787,34789,34790,34794,34795,34797,34817,34819,
+34827,34835,34856,34862,34866,34876,17935,34890,34904,34911,34916,U,U,34921,U,
+34927,34976,35004,35005,35006,35008,35026,U,35025,35027,35035,35056,35057,
+17985,35073,U,35127,U,35138,35141,35145,U,18021,35170,35200,35209,35216,35231,
+35248,35255,35286,35288,35307,18081,35313,35315,35325,35327,18095,35345,35348,
+U,35361,35381,35390,35397,35405,35416,35502,35472,35511,35518,35543,35580,U,
+35594,35589,35597,35612,35615,35629,35651,18188,35665,35678,35702,35711,35713,
+35723,35732,35733,35740,35742,35897,U,35901,U,U,35909,35911,35919,35924,35927,
+35945,35949,35955,U,35987,35986,35993,18276,35995,36004,36054,36053,36057,U,
+36080,36081,U,36105,36110,36204,36228,36245,36262,U,36294,36296,36313,36332,
+36364,18429,36349,36358,U,36372,36374,36385,36386,36391,U,18454,36406,36409,
+36427,36436,36450,36460,36461,36463,36504,36510,36526,36531,36533,36534,36539,
+U,36561,36564,18510,36601,U,36608,36616,36631,36651,36672,36682,36696,U,36772,
+36788,64102,36790,U,36801,36806,64036,36810,36813,36819,36821,36832,36849,
+36853,36859,36866,36876,36919,U,36931,36932,36957,36997,37004,37008,38429,
+37025,18613,37040,37046,37059,37064,U,37084,37087,U,37110,37106,37120,37099,
+37118,37119,37124,37126,37144,37148,37150,37175,37177,37178,37190,37191,37207,
+37209,37217,37220,37236,37241,37253,37262,37288,37294,37299,37302,37315,37316,
+37338,U,U,37356,37358,37377,37386,37398,37399,U,37427,37442,37447,37450,37454,
+37457,37462,37465,37472,37473,37477,37479,37480,U,U,37500,37501,37503,37513,
+37517,37527,37529,37535,37543,37547,U,U,37554,37567,37568,37574,37582,37584,
+37591,37593,37605,37607,37649,37623,37625,37627,37634,37645,37653,37661,37662,
+37671,37673,U,U,37703,37713,37719,37722,37739,37745,37747,37793,U,U,37768,
+37771,37775,37790,37877,U,U,37873,37825,37831,37852,37858,37863,37897,37903,
+37910,37911,37883,37938,37940,37947,37957,U,U,37997,37999,38264,38265,38278,
+38284,38285,U,38315,38324,U,38344,U,U,38444,38451,38452,U,38460,38465,38497,U,
+38530,U,38554,U,18919,38569,38575,38579,38586,38589,18938,U,38616,38618,38621,
+18948,38676,38691,18985,38710,38721,38727,38741,38743,38747,38762,U,U,38806,
+38810,38814,38818,38833,38834,38846,38860,38865,38868,38872,38873,38881,38897,
+38916,38925,38926,38932,38934,19132,U,38947,38962,38963,38949,38983,39014,
+39083,39085,39088,U,39095,39096,39099,39100,39103,39106,39111,39115,39136,U,
+39137,39139,39141,39146,39152,39153,39155,39176,19259,U,39190,39191,U,39194,
+39195,39196,U,39217,39218,39219,39226,39227,39228,39232,39233,39238,39245,
+39246,39260,39263,39264,39331,39334,39353,39357,39359,39363,39369,39380,39385,
+39390,U,39408,39417,39420,39434,39441,39446,39450,39456,39473,39478,39492,
+39500,39512,19394,39599,19402,39607,19410,39609,U,39622,39632,39634,39637,
+19432,39644,39648,39653,39657,39683,39692,39696,39698,39702,39708,39723,39731,
+39741,19488,39755,39779,39781,39787,39788,39795,39798,39799,39846,39852,39857,
+U,U,39858,39864,39870,39879,39923,39896,39901,39911,39914,39915,39919,39918,U,
+39930,U,39927,U,39958,39960,39961,39962,39965,39970,39975,39977,39978,U,39985,
+39990,39991,40005,40028,U,40009,40010,U,40020,40024,40027,40029,40031,40041,
+40042,40043,40045,40046,40048,40050,40053,40058,40166,40178,40203,40194,U,
+40209,40215,40216,U,19652,U,40242,19665,40258,40266,40287,40290,U,40297,40299,
+U,40307,40310,40311,40318,40324,40333,40345,40353,40383,40373,40377,40381,
+40387,40391,40393,40406,40410,40415,40416,40419,40436,19719,40458,40450,40461,
+40473,40476,40477,40571,U,40576,40581,40603,40616,U,40637,U,40671,40679,40686,
+40703,40706,19831,40707,40727,40729,40751,40759,40762,40765,40769,40773,40774,
+40787,40789,40792,U,40797,U,40809,U,40813,40816,40821,
+};
+
+static const struct dbcs_index jisx0213_2_bmp_decmap[256] = {
+{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{__jisx0213_2_bmp_decmap+0,34,126},{0,0,0},{
+__jisx0213_2_bmp_decmap+93,33,126},{__jisx0213_2_bmp_decmap+187,33,126},{
+__jisx0213_2_bmp_decmap+281,33,125},{0,0,0},{0,0,0},{__jisx0213_2_bmp_decmap+
+374,33,126},{0,0,0},{0,0,0},{0,0,0},{__jisx0213_2_bmp_decmap+468,33,126},{
+__jisx0213_2_bmp_decmap+562,33,126},{__jisx0213_2_bmp_decmap+656,33,126},{
+__jisx0213_2_bmp_decmap+750,33,126},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+__jisx0213_2_bmp_decmap+844,33,126},{__jisx0213_2_bmp_decmap+938,33,126},{
+__jisx0213_2_bmp_decmap+1032,33,126},{__jisx0213_2_bmp_decmap+1126,33,126},{
+__jisx0213_2_bmp_decmap+1220,34,126},{__jisx0213_2_bmp_decmap+1313,33,126},{
+__jisx0213_2_bmp_decmap+1407,33,126},{__jisx0213_2_bmp_decmap+1501,33,126},{
+__jisx0213_2_bmp_decmap+1595,33,125},{__jisx0213_2_bmp_decmap+1688,35,126},{
+__jisx0213_2_bmp_decmap+1780,33,126},{__jisx0213_2_bmp_decmap+1874,33,125},{
+__jisx0213_2_bmp_decmap+1967,34,125},{__jisx0213_2_bmp_decmap+2059,34,126},{
+__jisx0213_2_bmp_decmap+2152,33,126},{__jisx0213_2_bmp_decmap+2246,33,126},{
+__jisx0213_2_bmp_decmap+2340,33,117},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
+};
+
+static const DBCHAR __jisx0213_bmp_encmap[27287] = {
+8754,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,10530,
+10531,N,N,10532,N,10533,N,N,10534,10535,10536,N,10537,10538,10539,N,N,10540,
+10541,N,N,N,10542,10543,10544,10545,10546,10547,10548,10549,10550,10551,10552,
+10553,10554,10555,10556,10557,10558,10559,10560,10561,10562,10563,10564,10565,
+10566,10567,10568,10569,10570,10571,10572,10573,N,10574,10575,10576,10577,
+10578,10579,10580,10581,10582,10583,10584,10585,10586,10587,M,10589,10590,
+10591,10592,10593,10594,10595,10596,10597,10598,10599,10600,10601,10602,10603,
+10604,N,10605,10606,10607,10608,10609,10610,10611,10612,10613,10618,10810,
+10825,10785,10796,10812,10827,10841,10847,N,N,10813,10828,10816,10831,N,10832,
+10616,10621,N,N,N,N,10814,10829,10815,10830,10842,10848,N,N,N,N,N,N,10843,
+10849,N,10877,N,N,10614,10619,N,N,N,N,N,N,N,N,10844,10850,N,N,N,10811,10826,N,
+N,10788,10799,N,N,10787,10798,10817,10833,N,N,10818,10834,N,N,10874,10617,
+10622,N,N,10819,10835,11051,11050,10809,10824,N,N,10820,10836,10789,10800,
+10845,10851,10791,10803,10790,10802,10823,10839,10792,10804,N,N,N,N,10615,
+10620,10846,10852,10821,10837,10822,10838,N,N,N,N,N,N,N,10793,10805,10795,
+10808,10794,10807,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11049,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+11044,N,N,N,N,N,N,N,N,N,N,10351,10352,N,10353,10358,10359,N,10360,N,10361,N,
+10362,N,10363,N,10364,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+10356,10357,N,N,N,11077,11059,11065,11066,11045,M,11071,10862,11046,11054,M,M,
+N,11057,N,11058,10869,11048,10873,N,N,11062,11068,11042,11074,11052,N,N,N,
+10858,10868,10859,11060,10875,10853,10870,10863,N,11055,N,N,N,10860,11073,
+10867,N,10864,10855,N,N,10876,10865,10856,11047,N,N,N,10861,11053,11061,10854,
+M,11067,10872,N,10866,11072,10857,N,11041,10878,N,N,11043,N,N,N,N,10871,N,N,N,
+11070,11069,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,10801,11091,N,N,N,11092,N,N,N,11093,11094,N,N,N,N,N,N,10786,10840,N,
+10797,N,10806,11121,N,N,N,N,N,N,M,11105,11106,11107,M,11100,11098,11103,11133,
+11099,N,11095,N,11117,N,N,11097,11102,N,N,11101,N,N,N,N,N,N,N,N,11128,11129,
+11134,N,11114,11126,11127,11115,11116,N,N,N,11122,11111,N,N,N,11119,11130,N,
+11112,N,N,11120,11123,N,N,N,11125,N,N,N,N,11113,11131,11132,11124,11118,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11090,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,9817,10354,10355,11078,11079,11088,11089,9084,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,9024,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,10347,N,N,11096,N,N,11390,N,N,N,N,10348,10349,10350,N,N,N,N,N,N,N,11389,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,10529,9053,N,N,N,9055,N,N,11618,N,N,N,N,N,N,N,N,N,N,11620,
+N,N,N,N,N,9056,N,N,N,N,N,N,N,N,N,N,N,N,N,9052,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,10104,10105,10106,N,N,N,N,N,N,N,N,N,N,11573,11574,
+11575,11576,11577,11578,11579,11580,11581,11582,11583,11607,N,N,N,N,11317,
+11318,11319,11320,11321,11322,11323,11324,11325,11326,11327,11328,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8817,N,8999,8997,8998,9000,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,9001,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,9003,9004,
+9002,9005,8775,N,N,N,8774,N,N,N,N,N,N,N,N,N,9051,N,N,N,N,N,N,N,N,N,N,N,11640,
+N,N,N,N,N,8788,8789,N,N,N,N,N,N,N,11635,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,8812,N,8813,N,N,8814,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8811,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8815,8816,N,N,N,N,N,N,N,N,N,N,N,N,8770,
+8771,N,N,N,N,8772,8773,N,N,N,N,N,N,N,N,N,8785,8786,8787,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11641,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,10102,10103,8776,8777,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,10108,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,10050,10051,10052,10053,10054,10055,
+10056,10057,10058,10059,10060,10061,10062,10063,10064,N,10110,10109,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11553,11554,11555,11556,11557,11558,11559,
+11560,11561,11562,11563,11564,11565,11566,11567,11568,11569,11570,11571,11572,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,11329,11330,11331,11332,11333,11334,11335,11336,
+11337,11338,11339,11340,11341,11342,11343,11344,11345,11346,11347,11348,11349,
+11350,11351,11352,11353,11354,N,11307,11308,11309,11310,11311,11312,11313,
+11314,11315,11316,9818,9819,9820,9821,9822,9823,9824,9825,9826,9827,9837,N,N,
+N,N,8994,8993,N,N,N,N,N,N,N,N,8996,8995,N,N,N,N,N,N,N,9019,N,N,N,N,N,N,10343,
+10344,10345,10346,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,9023,9832,9833,9834,
+9835,N,N,N,N,N,N,N,N,N,N,9831,N,N,N,N,N,N,N,9828,9829,N,N,N,N,N,N,11646,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,9786,9789,9787,9792,9785,9790,
+9788,9791,9836,8829,N,8827,8828,N,8826,10107,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,11645,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,11297,11298,11299,11300,11301,11302,11303,11304,11305,11306,9006,
+9007,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,8790,8791,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,9018,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,9085,9086,8794,8795,8792,8793,N,N,N,11616,N,11617,9830,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8755,8756,8757,N,N,N,N,N,8758,8759,9020,N,N,N,
+N,N,N,N,N,N,N,N,N,N,M,N,M,N,M,N,M,N,M,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,9332,9333,9334,N,N,N,N,N,N,N,N,8761,9083,N,N,N,N,N,N,N,N,N,N,M,N,M,
+N,M,N,M,N,M,N,N,N,N,N,N,N,M,N,N,N,N,N,N,N,N,M,N,N,N,M,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,10098,
+10099,10100,10101,N,N,N,N,8760,9838,9839,9840,9841,9842,9843,9844,M,9846,9847,
+9849,9850,9851,9852,9853,9854,11626,11627,N,N,N,N,N,N,11628,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,10305,10306,10307,10308,10309,10310,10311,10312,
+10313,10314,10315,10316,10317,10318,10319,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,11621,11622,11623,11624,11625,N,N,N,N,N,N,N,N,10320,
+10321,10322,10323,10324,10325,10326,10327,10328,10329,10330,10331,10332,10333,
+10334,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11355,11356,11357,11358,11359,11360,
+11361,11362,11363,11364,11365,11366,11367,11368,11369,11370,11371,11372,11373,
+11374,N,11377,N,N,N,11376,N,N,11379,11378,N,N,N,N,N,N,N,N,N,N,N,N,11375,11590,
+N,N,N,N,N,N,N,N,N,11594,N,N,N,N,N,N,11585,N,N,N,11588,N,N,N,N,N,N,N,N,N,11586,
+11596,N,N,11595,11589,N,N,N,11597,N,N,N,N,N,N,N,N,N,N,11591,N,N,N,N,11599,N,N,
+N,N,N,N,N,N,N,N,N,N,N,11584,11598,N,N,11587,N,N,N,11592,N,N,N,N,N,11593,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11615,11631,
+11630,11629,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11603,11604,N,N,N,N,N,N,N,N,N,N,N,N,
+11600,11601,11602,N,N,11606,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,11605,N,N,N,N,N,N,9054,N,11619,11811,N,N,N,41261,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41266,N,41267,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41310,N,41302,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41342,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11859,N,N,N,N,N,N,41771,N,N,N,N,
+62568,N,N,N,N,N,41775,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11867,41800,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41821,41822,N,N,N,N,41825,N,N,N,N,N,N,N,
+N,N,N,41831,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42019,N,42022,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42031,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,42040,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42050,42058,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42105,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42303,N,N,N,N,42307,N,N,42305,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,42327,43043,43045,N,N,N,N,N,N,N,N,43049,43048,N,N,N,N,N,
+N,N,N,43052,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,20319,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,43070,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,20335,N,N,N,N,N,43094,N,N,N,N,N,N,N,N,N,N,N,43097,N,N,N,N,N,N,N,N,43100,
+43102,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,43119,N,N,N,N,N,N,43121,N,N,N,N,N,N,N,N,N,43124,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43129,N,N,N,N,43131,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44091,44102,N,N,44106,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,44128,44379,N,N,N,N,44383,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+44401,44598,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44412,44590,N,N,N,N,N,N,N,N,N,
+N,N,44594,N,44596,N,N,N,N,N,30025,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,44653,N,N,N,N,N,N,N,N,N,44645,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,44840,44841,N,N,N,N,44844,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+44852,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30078,N,N,N,N,N,N,N,N,N,N,N,N,30241,N,
+N,N,N,N,N,N,N,N,44872,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,44893,30266,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44919,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+60987,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60994,61041,N,N,N,N,N,N,N,N,N,N,N,N,61054,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61248,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,61268,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,61296,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61303,61480,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30566,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,61503,N,N,N,N,N,61505,N,61506,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,61513,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61520,61748,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30797,N,N,61766,N,61768,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,61788,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,61799,N,N,N,N,N,N,N,N,N,N,N,N,N,61804,61986,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61997,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+62009,62052,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62068,N,N,N,
+N,N,N,62071,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62077,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62259,N,N,N,N,N,N,
+N,N,N,N,62263,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,62279,N,N,N,N,N,N,N,62283,N,N,N,N,62280,62291,N,N,N,N,N,N,62295,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,31085,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62507,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,62518,N,N,N,N,N,N,62523,62542,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62557,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,62561,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62782,N,62786,62792,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,62794,N,N,N,N,62796,N,N,N,N,N,62799,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+31321,N,N,N,N,N,N,N,31322,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+62828,N,N,N,62830,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62839,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63029,N,N,N,N,N,N,N,N,
+N,N,63026,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63028,63065,N,N,N,N,63060,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63085,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63086,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31569,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63311,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63340,N,N,N,N,31584,
+63524,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,63546,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,63555,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63566,N,
+N,N,N,N,N,N,N,N,N,N,N,N,63571,63595,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63785,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63807,63817,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+31819,N,N,N,N,N,N,N,N,N,63836,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+64039,32088,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64362,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,64368,64373,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,64376,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+64567,64597,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64806,N,N,N,N,N,N,N,64808,N,N,N,
+N,N,N,N,64810,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64817,32318,N,N,N,N,N,
+N,N,N,64831,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,65066,N,N,N,N,N,N,N,N,N,N,N,N,65069,65099,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65120,41250,N,N,N,N,N,
+N,N,N,N,N,N,N,41251,N,N,41252,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11812,
+41253,N,41254,61486,N,41255,11813,11814,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41256,N,
+N,N,N,N,N,41257,41258,N,N,N,N,N,N,N,N,41260,N,N,N,N,N,N,N,N,41263,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,41264,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,11815,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41265,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41268,N,41269,41271,N,N,N,N,N,N,41272,N,N,N,N,
+41273,N,N,N,N,N,N,N,41274,N,N,N,N,N,N,N,N,N,41276,N,N,N,N,N,N,11816,N,N,N,N,N,
+N,N,N,N,41275,N,N,N,N,N,41277,N,N,N,41278,N,N,N,N,N,N,N,11817,N,11818,41279,N,
+N,11819,N,N,N,N,N,N,N,11820,N,N,N,N,N,N,N,N,N,N,41280,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41282,N,N,N,N,N,N,41283,N,N,N,N,N,N,N,
+N,N,11822,11823,N,N,N,N,N,N,N,N,N,N,41284,N,11824,N,41285,N,N,N,N,N,N,11825,
+11821,N,N,N,41281,N,N,N,N,N,11826,N,11827,N,N,N,N,N,N,N,N,N,N,41287,41288,N,
+41289,N,N,41290,11828,N,N,N,41291,N,N,41292,N,N,N,N,11829,N,N,N,N,N,N,N,41293,
+N,11830,N,N,11831,N,N,41294,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+41296,N,N,N,N,N,N,N,N,N,N,N,41297,N,N,N,N,N,N,41298,N,N,N,11833,N,41299,N,N,N,
+41300,N,N,41301,N,N,N,N,N,N,N,N,N,N,N,N,N,11834,N,N,N,N,N,41295,N,N,N,N,N,N,N,
+N,N,N,11809,41303,41304,11835,11836,N,N,N,N,N,N,N,N,N,N,N,11837,N,41305,N,N,
+41306,N,N,N,N,11838,N,N,N,41307,N,41308,N,N,N,41309,N,N,N,N,11839,N,N,N,N,N,N,
+11840,N,N,N,N,N,N,N,N,N,N,N,N,11842,N,N,N,N,11841,11843,41311,N,N,N,41312,N,N,
+N,N,N,N,N,41313,N,N,N,N,41314,N,N,N,41315,N,N,N,N,N,N,N,N,N,N,N,41316,N,N,
+41317,N,N,N,41318,N,N,N,N,N,41319,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,41321,N,N,N,N,N,N,N,N,N,41322,41323,11844,41324,41325,N,N,N,N,N,41326,N,N,N,
+N,N,N,41320,N,N,N,N,N,N,41327,N,N,N,N,N,N,41329,N,N,N,N,N,N,N,N,41330,41331,N,
+N,N,N,N,N,N,N,41332,N,N,41333,N,N,N,N,11845,N,41336,N,11847,N,N,N,41338,N,N,N,
+N,41339,N,N,N,N,N,N,N,41340,N,N,N,N,11848,N,N,41341,N,N,N,N,N,N,N,N,11846,
+41334,11851,N,N,11850,N,41761,N,N,11852,N,N,N,N,N,N,N,N,N,N,N,41763,N,N,N,
+41764,N,N,11853,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11854,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,11855,N,N,N,N,N,N,N,N,N,N,11857,N,11858,N,N,N,N,N,
+N,N,N,41766,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41768,N,N,N,N,N,N,N,62580,N,N,
+N,N,N,N,N,41769,N,N,N,N,N,N,N,41770,N,N,N,N,N,N,N,N,N,N,N,N,41772,N,N,N,N,
+11860,N,N,N,N,N,41773,N,N,N,N,N,N,N,N,N,41774,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+41776,N,N,N,N,N,N,11861,N,N,N,N,N,N,11862,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,11863,N,N,N,11864,N,N,N,N,N,N,N,N,N,N,N,11865,N,N,N,N,41779,41780,11866,
+41781,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41782,11868,N,11869,41783,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,11870,N,N,N,N,N,N,N,N,N,N,N,41785,N,11871,N,N,N,N,41786,12158,N,N,N,
+11872,N,N,N,N,N,N,N,N,N,N,41787,N,N,N,N,N,N,N,N,N,N,41788,N,N,N,N,N,N,N,N,N,N,
+41790,N,41789,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11873,N,N,N,N,41792,N,N,N,N,N,N,N,N,
+N,N,N,41794,N,41795,N,N,N,N,N,N,N,N,41796,N,N,N,N,N,N,N,N,N,N,41797,41798,N,N,
+N,N,N,N,N,N,N,N,N,N,11874,N,41799,N,11876,N,N,N,11877,41801,N,N,N,N,11878,N,N,
+N,N,11879,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11881,N,N,N,N,N,N,41803,N,N,
+N,11882,11883,N,N,N,N,N,N,11884,N,N,41804,41805,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,11885,N,N,N,N,N,N,N,41806,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41807,N,N,N,N,N,N,
+N,N,41808,N,N,N,41809,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,11887,N,11888,N,N,N,41812,N,N,N,N,41813,N,N,N,N,N,N,N,N,N,N,N,N,N,41814,N,
+N,11889,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11890,N,N,N,N,N,N,N,N,N,
+11891,N,N,N,N,N,N,41815,N,N,N,N,N,N,N,N,N,N,N,N,N,11892,N,41816,N,N,41818,N,N,
+N,N,N,N,N,N,41819,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41823,N,N,N,N,41824,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41826,41827,11893,N,N,N,N,N,
+N,N,N,N,N,N,20350,N,N,N,N,N,41829,N,N,11894,41830,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,41832,N,N,N,N,N,N,N,N,N,11895,N,N,N,N,N,N,N,41828,N,N,
+N,N,N,N,N,N,N,N,N,N,41833,N,N,N,41834,N,N,N,N,11897,41835,N,N,N,N,N,N,N,11898,
+N,N,N,N,N,N,N,N,N,N,11899,N,N,N,N,N,N,N,N,11900,N,41836,N,N,41837,N,N,N,N,N,N,
+N,41838,11901,N,N,N,N,N,11896,N,N,N,41839,11902,N,N,N,N,41840,N,N,12065,N,N,N,
+41841,41842,N,N,N,N,N,N,N,N,41843,N,N,41844,N,N,N,N,41845,N,N,N,41846,N,N,
+12066,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,41848,N,N,41849,N,41850,N,41851,N,N,N,N,N,N,N,N,N,N,N,12067,41852,41853,N,N,
+N,N,N,N,N,41854,N,N,N,N,12068,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,12069,N,N,N,N,N,N,N,N,N,12070,N,N,N,N,N,N,42017,N,N,N,N,42018,N,N,N,N,
+N,42020,N,N,42021,N,N,N,N,N,12071,N,N,N,N,N,N,N,N,N,N,N,N,N,12072,N,42023,
+42024,N,N,42025,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42027,N,N,N,
+12073,42028,N,N,N,12074,N,42029,N,N,N,N,N,12075,N,N,42030,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,12077,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+42035,N,N,N,N,N,N,N,N,N,42036,N,N,42037,N,12078,N,N,42038,42032,N,N,N,N,N,N,N,
+N,N,N,42039,N,N,N,N,42041,N,N,N,N,N,N,42043,42046,12080,N,N,N,N,N,12081,N,
+42047,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42044,N,N,N,N,N,N,N,42048,
+N,N,N,N,N,N,42049,N,N,N,12082,N,42051,N,42052,42053,N,N,N,N,N,N,42054,N,12083,
+N,N,N,N,N,N,N,N,N,29735,N,N,N,N,N,N,N,N,N,N,42055,N,42056,N,N,N,N,N,12085,N,N,
+N,N,N,N,42057,N,12087,N,12088,12089,N,N,N,12084,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,42059,N,N,N,42060,N,N,N,N,N,N,N,N,42061,N,N,N,12090,42062,N,N,42063,12091,
+N,N,N,N,N,N,N,N,N,42064,12092,N,N,12093,42065,N,N,N,N,42066,12094,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,42067,N,N,N,12095,12096,N,N,42068,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,42069,N,N,N,N,N,N,N,N,42070,N,N,N,N,N,N,N,N,N,N,N,N,N,42071,42072,
+12097,N,N,N,N,N,N,N,N,N,N,42074,N,N,N,N,N,N,N,N,N,N,N,12099,N,42075,N,N,N,N,N,
+42077,N,N,N,N,N,12100,N,N,N,12101,12102,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42079,
+42080,N,N,N,N,N,42081,42082,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,42084,N,N,N,N,N,N,42085,12103,N,N,42086,42087,42088,N,12104,N,N,N,42089,
+12105,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42093,N,12106,
+42094,42095,N,N,N,N,N,N,N,N,N,42096,N,N,N,42092,N,N,N,N,N,N,N,N,N,N,N,12109,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,12110,12111,N,N,N,42099,N,N,12112,N,N,N,N,N,N,N,
+42097,N,N,N,N,N,N,42102,N,N,N,N,N,12113,N,42103,N,N,N,N,N,N,12114,N,N,42104,N,
+N,N,N,12115,12116,N,42106,N,N,42107,N,42108,N,12117,42109,N,N,N,N,12118,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42110,N,42273,N,N,N,N,N,N,42274,N,N,N,N,N,N,
+N,N,N,N,42275,N,N,N,N,N,N,42276,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42278,N,N,42279,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,12120,N,N,12121,N,N,42280,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,12123,N,N,N,N,N,N,N,N,N,N,N,N,12124,42281,42282,N,
+42283,N,42284,42285,N,N,N,42286,N,N,N,N,N,N,N,N,42287,12125,N,N,N,N,N,N,N,N,N,
+N,12127,42288,N,N,N,N,N,N,42289,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42291,N,N,N,
+N,N,N,N,N,N,42292,12130,N,N,N,12129,N,12131,N,N,N,N,N,12132,N,N,N,N,N,12133,N,
+42293,N,N,N,N,N,N,12134,N,N,N,N,N,N,N,N,N,42294,42295,42296,42297,N,N,N,N,
+42298,12135,42299,N,N,N,N,N,N,42300,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42301,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42304,N,N,N,N,N,N,N,N,42306,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42309,N,12137,N,42310,N,N,N,N,N,N,N,N,N,N,N,N,
+N,12138,N,N,N,N,N,N,N,42312,42313,N,N,N,N,N,42314,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+12139,N,N,N,N,N,N,12140,N,N,N,N,N,N,N,N,N,N,N,N,42315,N,N,N,N,12141,N,N,N,N,N,
+N,N,N,N,42316,N,N,N,N,N,N,N,N,N,N,N,N,N,42317,N,N,N,N,N,N,12142,N,N,N,N,42318,
+N,N,N,N,42319,N,N,N,N,12143,N,N,N,N,N,N,N,N,N,N,12144,42320,N,N,N,N,42321,
+42322,N,N,42323,N,N,N,N,N,N,42324,N,N,N,N,N,N,N,N,N,32378,42328,42329,N,N,N,N,
+N,12145,N,N,N,42330,N,N,N,N,N,N,N,N,N,N,N,12146,N,N,N,42331,N,N,N,N,N,42332,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+42333,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42334,N,12147,N,N,N,N,N,12148,N,N,N,N,N,N,
+N,N,N,12149,N,N,42335,N,N,N,12150,N,N,N,N,N,12151,N,N,N,N,N,N,42336,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,42337,N,12152,42338,42339,N,42340,N,N,N,N,12153,N,N,N,N,
+N,N,N,N,N,42341,N,42342,N,42343,N,N,N,N,42344,N,N,N,N,42345,N,N,N,N,12154,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42346,N,42347,N,N,N,42348,N,N,N,N,42349,
+N,N,N,N,N,N,N,N,42351,N,42350,N,N,N,N,42352,42353,N,N,N,N,N,N,N,42354,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,42355,N,12156,N,N,N,N,N,N,N,N,N,N,N,12157,N,N,N,N,N,N,N,
+42357,N,N,N,N,N,N,42356,N,N,N,N,N,N,N,N,N,N,N,N,20309,N,N,N,N,N,N,N,N,N,N,
+42358,N,N,N,N,N,42359,N,N,N,20310,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42360,N,N,
+N,N,N,N,42361,N,N,N,N,N,N,N,N,N,N,N,N,42362,20311,N,42363,N,42364,N,N,42365,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,20312,N,N,43041,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,43042,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43044,N,N,N,N,N,N,N,N,N,N,N,
+N,N,43046,N,N,N,N,N,N,N,43047,N,20313,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+20314,N,N,N,N,43050,N,N,N,N,N,N,N,N,N,N,N,43051,43053,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,20315,N,N,N,N,N,N,N,N,N,N,N,20316,N,N,N,N,20317,N,N,N,N,N,43054,N,20318,N,
+N,N,N,43055,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,32379,N,N,N,43057,N,N,20320,43058,N,N,N,43059,43060,43061,N,
+N,N,N,N,N,43062,N,N,N,N,N,N,N,N,N,20324,N,43065,N,N,N,N,N,N,N,N,N,N,N,43068,N,
+43069,N,N,N,N,20325,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,20326,43073,N,43074,20327,N,
+N,43075,43076,N,N,20328,N,N,43078,N,N,N,N,N,N,N,43079,N,N,N,N,20329,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,43081,N,20330,N,N,N,N,20331,N,20332,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,20333,43084,N,N,N,N,N,N,20336,N,N,
+43085,N,N,N,N,N,N,N,N,N,N,N,N,43087,N,N,43088,N,N,N,43089,N,43090,20337,N,N,N,
+43086,N,N,N,N,N,43091,N,N,N,N,N,N,N,43092,N,N,N,N,N,N,N,N,43093,N,N,N,20339,
+20340,N,N,20342,N,N,N,N,N,N,N,N,20341,N,N,N,N,N,N,N,N,N,N,N,N,N,43095,N,N,N,N,
+N,N,N,N,43096,N,N,20343,N,N,43098,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,20344,N,N,N,
+N,N,N,43101,N,N,N,N,N,N,N,N,N,43103,N,43104,N,N,43105,N,43106,N,N,N,N,N,N,
+20345,N,N,N,20346,N,N,20347,N,N,N,N,N,N,N,N,43107,N,43108,N,43109,N,N,N,20348,
+43111,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,20349,N,N,N,N,N,43112,N,N,N,N,N,43113,
+43114,N,N,N,N,N,N,N,43115,N,29736,N,43117,N,N,N,N,43118,43120,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,43122,N,29737,43123,N,N,29738,N,N,N,N,N,N,43125,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,43126,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43127,N,N,N,N,N,N,N,N,N,N,
+43128,N,N,N,N,N,N,N,N,N,N,N,N,43130,N,29739,N,N,N,N,N,29740,N,N,N,N,N,N,N,N,N,
+N,N,N,43132,43133,43134,44065,N,N,N,N,N,N,N,N,32380,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44067,N,N,N,N,
+44068,N,44069,N,N,N,N,N,N,N,N,N,N,N,N,44070,N,N,N,N,29741,44071,N,N,N,N,N,N,
+44072,N,N,N,N,29743,N,N,N,N,N,N,44073,N,N,N,N,N,N,44074,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29744,N,N,N,44076,29745,N,29746,N,N,N,
+N,29747,44077,N,N,N,N,N,44078,N,N,N,N,N,N,N,N,N,N,N,N,N,44079,29748,44081,N,N,
+N,N,29749,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29750,N,29751,N,N,N,N,N,N,29752,N,N,
+29753,N,N,N,N,29754,N,44082,N,N,N,N,N,N,N,N,N,N,N,N,29755,N,N,N,29756,N,N,N,N,
+N,N,N,N,N,N,44083,29757,N,N,29758,N,N,N,N,N,N,N,N,N,N,44084,N,N,N,N,N,N,N,N,N,
+N,29759,44085,N,N,N,N,N,N,N,N,N,N,29760,N,N,N,N,N,44086,N,N,N,N,N,N,N,N,N,N,N,
+N,29761,N,N,N,N,N,44087,N,44088,N,N,29762,N,N,N,N,N,N,N,29763,N,N,N,N,N,29764,
+N,29765,44089,N,N,N,N,N,N,N,N,N,N,N,44090,N,N,44092,N,29766,N,44093,N,N,N,N,N,
+N,44094,44095,44096,N,N,N,N,N,N,N,N,N,29767,N,N,29768,44097,N,N,N,N,N,N,29769,
+N,N,N,N,44098,44099,N,N,N,44100,N,N,N,N,N,N,N,N,44101,29770,N,N,N,N,N,N,29771,
+N,N,44103,29772,N,N,N,N,N,N,N,N,N,44104,N,44105,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+29773,N,29774,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29775,N,N,N,N,44107,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,44108,N,N,N,N,N,N,N,N,N,N,44109,N,N,N,N,N,N,N,N,N,N,44110,N,N,N,N,
+N,N,N,29777,29778,N,N,N,N,N,N,N,N,N,44111,N,N,N,N,N,N,N,44113,44114,N,N,N,N,N,
+N,N,N,N,N,N,N,44115,N,N,N,N,N,N,N,N,N,44116,N,N,29779,N,N,N,N,N,N,N,N,29780,
+29781,N,N,N,44117,N,44118,N,29782,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44119,N,N,N,
+44120,N,N,44121,N,N,29783,44122,N,44123,44124,N,N,N,N,N,44125,N,N,29784,N,
+44126,N,N,N,N,N,N,N,N,N,N,N,N,29785,N,N,N,N,29786,N,N,N,N,N,N,29787,N,N,44127,
+N,N,N,N,N,N,44129,N,N,N,N,44130,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,44131,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44132,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,29789,N,N,N,N,44134,44135,N,N,N,44136,44137,N,N,N,N,N,
+N,N,N,N,N,N,N,44138,N,N,44139,N,N,N,N,44140,N,N,N,N,N,N,N,N,N,N,N,29792,N,N,
+29791,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44142,N,N,N,N,N,N,N,
+44143,N,44144,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44145,44147,N,N,N,N,N,
+N,N,N,N,N,N,N,29794,44148,N,N,N,N,N,44149,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,29795,N,N,N,N,29796,N,N,44150,N,N,N,N,N,44151,N,N,N,N,44152,44153,N,N,N,
+29797,N,N,N,29798,N,N,N,N,N,N,44154,N,N,44155,N,N,N,N,N,N,N,N,44157,N,29799,N,
+N,N,44158,N,N,N,N,N,N,N,44156,N,N,N,N,N,N,N,N,N,29800,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,44321,N,N,N,N,N,N,N,N,N,N,N,N,44322,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29801,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44323,
+29802,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,29803,44325,44326,N,N,N,N,N,N,29804,N,N,44327,N,N,44328,N,N,N,N,N,N,N,29805,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44331,N,N,44332,N,N,N,29806,
+N,44333,44334,N,N,N,N,44335,N,29807,44336,N,N,N,N,N,N,N,N,N,44337,N,N,N,N,N,N,
+N,N,N,N,44339,N,N,N,N,N,N,N,N,N,N,N,29808,N,N,N,N,N,N,44342,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,29809,N,N,N,N,N,N,N,44343,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44346,N,N,
+N,N,44344,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,44347,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44349,44350,N,N,N,N,N,N,
+44351,N,N,N,44352,N,N,N,N,29810,N,N,N,N,N,44353,44354,29811,N,N,N,N,44355,N,N,
+29812,N,44348,44356,N,N,N,N,N,N,29813,N,N,N,29814,N,N,N,N,N,N,N,N,N,44357,N,N,
+N,29815,N,N,44358,N,N,N,44359,N,N,N,N,N,44360,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29817,N,N,N,N,N,N,N,N,44361,44362,N,44363,N,
+N,29818,N,N,N,N,N,N,N,N,N,N,N,N,29819,N,N,N,N,N,44364,N,N,N,N,N,29816,N,N,N,
+44365,N,N,N,N,N,N,N,N,N,44366,N,N,N,N,N,N,N,N,N,44367,N,N,N,N,N,N,N,N,N,N,N,
+44368,N,44369,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+29821,29822,N,N,N,N,29985,N,N,N,N,N,29986,44370,44371,N,29820,N,29987,N,N,N,N,
+44372,N,44373,N,N,N,N,N,N,N,N,N,N,N,N,44375,44376,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,29988,N,N,N,29989,N,N,N,44377,44378,N,N,N,N,N,N,N,N,N,N,44380,N,N,N,N,
+44381,N,44382,N,N,N,N,N,N,N,44384,N,N,N,29990,N,N,N,N,N,N,29991,N,N,N,N,N,N,N,
+N,44385,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44386,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+44387,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29993,N,N,N,44388,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,44389,N,N,N,N,N,N,44390,N,N,44391,44392,N,N,N,N,44393,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,29994,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44394,N,N,
+44395,N,N,44396,N,N,N,N,N,N,44397,N,N,44398,N,N,N,N,N,N,44399,N,N,N,N,N,N,N,N,
+N,N,44400,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44402,N,N,
+N,N,N,N,44403,N,N,44404,29996,N,N,N,44405,N,N,N,44406,29997,N,N,N,N,N,N,N,N,N,
+N,N,29998,N,N,N,N,N,N,N,N,29999,N,N,44407,30001,N,30002,N,N,N,N,N,44408,30003,
+N,N,N,N,30004,30005,N,30006,N,N,N,N,N,N,30000,N,N,N,N,N,N,N,N,N,N,44409,N,N,
+30008,N,N,N,30009,N,44411,N,N,44410,N,N,N,N,N,44414,N,30011,30012,44577,N,N,N,
+N,N,30013,N,44578,N,30014,N,N,N,N,44581,44582,44583,44584,N,N,N,N,N,30015,N,N,
+N,30016,30017,N,N,44585,N,N,N,N,44586,N,N,N,N,N,N,N,N,N,N,N,N,30018,N,N,44587,
+N,44588,N,N,N,N,N,N,44589,N,N,N,N,N,N,30020,N,N,N,N,N,N,N,N,N,N,N,N,44591,N,N,
+N,44592,30021,N,N,44593,N,N,N,N,N,30022,N,N,N,44595,N,N,N,N,N,N,30023,N,30024,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30026,N,N,N,N,N,N,N,N,N,N,N,N,30027,N,N,N,
+44597,N,N,N,N,N,N,N,N,N,N,N,N,N,30028,30007,44599,N,N,N,44600,N,N,N,N,N,N,N,N,
+N,N,N,N,44601,30029,N,N,N,N,N,44603,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,30031,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30033,30034,N,N,N,44606,
+44607,N,N,N,N,N,N,44608,N,N,N,N,N,N,N,N,44609,N,N,N,N,N,N,N,N,30032,N,N,N,N,N,
+N,N,N,N,N,N,N,N,44613,N,44614,N,N,N,N,30035,N,N,N,N,N,30036,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,44616,30037,N,N,N,N,30038,N,N,30039,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,44620,N,44621,N,N,N,N,N,N,N,N,30040,N,N,N,N,30042,N,N,44622,N,N,N,
+N,44623,N,N,N,N,N,N,N,N,N,44624,N,N,N,N,30043,N,44625,N,44626,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,44627,N,N,N,N,N,N,44628,N,30041,N,N,30044,30045,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,44619,N,N,N,N,N,N,N,44632,N,N,N,N,30047,N,44633,N,N,N,N,
+N,N,N,N,N,N,N,N,30048,44634,N,N,N,30049,N,44636,N,N,N,N,N,N,N,44637,N,N,44638,
+N,N,N,N,N,44639,44640,N,N,N,44641,N,N,44642,N,N,N,N,N,30046,N,N,44643,N,44644,
+N,N,N,30050,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44646,N,N,44647,N,N,N,30051,N,N,
+30052,N,N,N,N,44648,N,44649,N,N,N,N,N,44650,N,N,N,N,N,N,N,N,N,N,N,N,N,44651,N,
+N,N,N,N,44652,N,44654,44655,44656,N,44657,N,N,N,N,N,N,30054,N,30055,N,N,N,N,
+44658,44659,N,N,N,N,N,N,30056,N,44660,N,N,N,N,N,N,44661,N,N,N,N,N,N,N,44666,N,
+44667,N,N,30057,N,N,N,44668,N,N,44669,30058,N,N,N,N,N,44670,N,N,44833,N,N,N,N,
+N,N,N,N,N,N,44834,44835,N,N,30059,N,N,N,44836,30060,N,N,30061,30062,N,N,N,N,N,
+44837,N,N,N,44662,30063,44838,N,N,N,44839,N,N,30064,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30067,N,N,N,N,N,
+44843,N,N,N,N,N,N,30068,N,N,N,44845,N,N,30065,N,N,N,N,N,N,N,N,N,N,N,N,N,30069,
+N,N,N,N,N,N,N,N,N,N,N,30070,30071,N,N,N,30072,44846,N,N,44847,N,N,N,N,N,44848,
+N,N,N,N,N,N,N,44849,N,N,N,N,44850,30073,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+44851,N,N,N,44853,N,44854,N,N,N,N,N,N,N,N,N,N,N,N,30075,44855,N,N,N,N,N,N,
+30076,N,N,44856,N,N,N,N,N,N,44857,N,N,44858,N,44859,N,N,N,44860,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,30077,N,44861,N,N,N,N,44862,N,N,N,N,N,N,N,N,N,N,N,30242,44868,N,
+N,N,N,N,30243,30244,N,N,N,44869,44870,N,N,N,44871,44873,30245,30246,N,N,N,N,N,
+N,N,44874,30247,N,44875,N,N,N,30248,N,N,N,N,44876,N,N,44877,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,44865,N,44879,44880,44881,N,N,N,N,N,N,30250,N,N,30251,44882,
+N,N,N,N,N,30252,44883,N,N,44884,N,N,N,N,44886,N,30253,N,44887,N,N,N,30254,N,N,
+N,N,30255,N,N,N,N,N,N,N,N,44888,N,N,N,N,N,N,30256,N,N,N,N,N,N,N,30257,N,N,N,N,
+N,N,44885,N,N,N,44890,N,N,N,N,44891,N,N,N,N,N,30259,N,44892,N,N,N,N,N,44894,N,
+N,30260,N,N,N,N,N,N,N,N,30261,30262,44895,N,44896,N,N,N,30263,N,N,N,N,N,44898,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44899,N,N,N,N,N,N,N,N,44900,N,N,N,N,N,N,N,N,
+N,44902,N,N,N,44901,N,N,N,N,N,N,N,44903,44904,N,N,N,N,N,N,30264,N,N,30265,N,N,
+N,N,44907,N,N,N,N,44908,44909,44910,N,N,N,N,N,N,N,N,N,44911,44913,N,N,N,44914,
+44915,44916,N,N,N,N,N,44918,N,N,N,30268,N,N,30269,N,N,N,N,N,N,N,N,N,N,N,N,N,
+30270,N,N,44920,N,N,N,N,N,30271,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30272,N,N,N,
+44921,N,N,N,N,N,N,N,N,N,N,N,30273,N,44922,N,N,N,N,N,N,N,30274,N,N,N,N,30275,N,
+30276,N,N,N,N,44923,N,N,N,N,N,N,N,N,44924,N,30277,N,N,44925,N,N,N,N,N,N,44926,
+30278,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60961,N,N,N,N,N,N,N,N,N,
+N,N,N,N,30279,N,N,N,30280,60962,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60964,60965,N,N,N,
+N,N,N,N,N,60966,60967,60968,N,N,N,N,N,30282,N,N,N,N,N,N,30283,30284,N,N,60969,
+N,N,N,N,N,N,N,N,N,N,N,60970,60971,N,N,N,N,N,N,60972,N,N,60973,N,N,N,N,N,N,N,N,
+N,N,N,N,N,30285,60974,N,N,30286,N,N,N,N,60975,N,N,N,60976,N,30287,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30288,N,60977,60978,N,
+N,N,60979,N,N,N,N,60981,N,N,N,N,N,N,N,N,N,N,N,N,N,60982,N,N,N,N,N,N,N,N,N,N,N,
+30289,N,60983,30290,N,N,N,N,N,N,N,N,N,N,61007,N,N,N,N,N,60984,N,N,N,N,N,N,
+30292,N,30293,N,N,N,N,N,N,N,N,N,N,N,N,N,60985,30294,30295,N,N,60986,N,N,N,N,N,
+N,N,N,N,N,60988,60989,N,60990,30296,N,N,N,30297,N,N,N,N,N,N,N,N,N,N,N,N,N,
+30291,N,N,60991,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60992,N,N,N,30299,N,N,
+N,N,N,N,N,N,N,60993,N,N,N,30300,N,60995,N,N,N,60996,N,60997,N,N,N,30301,N,N,N,
+N,N,N,N,N,60998,N,30302,60999,61000,30303,N,N,N,N,N,N,N,N,N,N,N,N,30298,61002,
+N,N,N,30305,N,N,N,N,N,61003,N,N,N,30306,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,61004,N,61005,61006,N,N,N,N,N,N,30307,61008,N,30308,N,N,61029,N,N,N,N,
+30309,N,N,61009,N,N,30310,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+30311,N,N,61010,N,N,61011,N,61012,N,N,N,N,30312,N,N,N,N,N,N,N,N,N,N,61013,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,61014,61015,30314,N,N,N,N,30315,N,30316,61016,N,N,
+61017,N,N,N,61018,N,N,30317,N,N,N,61019,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+30318,61025,30319,N,61026,N,N,N,N,N,61027,N,N,N,N,N,N,N,N,N,N,30320,N,N,61028,
+N,30321,N,N,N,61030,N,N,N,N,N,61031,61032,61033,N,N,N,N,N,30322,N,N,N,30323,
+30324,N,30325,N,61034,N,N,N,N,N,N,N,N,N,61035,N,N,N,N,N,N,N,N,N,N,N,N,61036,N,
+N,N,N,N,30326,61021,N,N,N,N,N,N,61038,N,N,N,61039,N,N,N,N,61040,N,N,N,N,N,N,N,
+N,N,N,61042,N,30328,N,61037,N,N,N,N,N,61043,N,N,N,N,N,N,N,30329,N,N,N,61044,
+61045,N,61046,61047,N,N,61048,N,61049,N,61050,61051,N,N,61052,N,N,N,N,30330,N,
+30331,N,N,N,N,61053,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61217,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,61218,N,N,N,30332,N,N,N,N,N,30333,N,N,61219,N,N,N,N,N,N,N,N,N,N,61220,N,
+30334,N,61221,N,N,N,30497,N,N,61222,N,N,N,30498,N,N,N,N,N,N,N,N,N,N,61223,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61225,N,N,N,N,N,N,N,N,N,N,N,N,N,61226,N,61227,
+61228,N,61229,N,N,N,30499,N,N,N,N,N,N,N,61230,N,30500,N,N,N,N,N,N,N,N,N,N,
+61231,N,N,N,N,30502,N,N,N,N,30503,N,N,N,30504,N,61224,61232,N,N,N,N,N,61233,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30505,61235,N,N,N,N,61236,N,30506,61237,
+N,N,N,30507,N,61238,30508,30509,N,N,N,N,N,61239,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,61241,30510,N,N,N,N,N,N,N,N,N,30511,N,N,N,30512,30513,N,N,61242,N,N,
+N,30514,N,61243,N,61240,N,N,N,N,N,N,61245,30515,N,N,N,N,61246,N,30516,N,N,N,N,
+N,N,N,61247,N,N,N,N,N,61249,30517,N,N,N,N,N,30518,N,61244,N,N,N,N,N,N,N,N,
+30519,61250,61251,30520,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61252,N,N,N,61253,N,N,N,
+N,N,N,N,N,N,N,61254,N,N,N,N,N,N,30522,N,N,N,N,30523,N,N,N,30521,N,N,61256,
+61257,N,N,N,N,30524,30525,61258,N,N,61259,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,61260,N,N,N,N,30526,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61262,61263,N,
+61264,N,N,N,N,N,N,61265,N,N,N,61266,N,N,30527,61267,N,N,30530,N,N,N,N,N,61269,
+N,N,N,N,N,N,N,N,30528,30529,N,N,N,N,N,30531,61270,N,N,N,61271,N,N,61272,N,
+61273,N,N,N,N,N,N,30532,61274,N,N,N,N,N,N,N,61275,N,N,61276,N,N,N,30533,61277,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,61278,N,61279,N,N,N,N,N,N,N,61282,N,N,N,N,30534,N,
+N,N,N,N,N,30535,N,N,N,N,N,61283,N,N,N,N,N,30536,N,N,N,61280,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,61286,N,N,N,N,N,N,61287,N,61288,30537,N,N,N,30538,N,N,N,61289,N,N,N,
+N,N,N,N,30539,N,N,N,N,N,N,N,61285,61290,61291,N,61292,61293,61294,N,N,N,61295,
+N,N,30540,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30542,N,30543,N,N,N,N,N,N,N,N,N,N,30541,
+N,N,30544,61297,30545,61298,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30546,
+30547,N,N,61300,N,N,N,N,N,61299,30548,30550,61301,N,N,N,N,N,N,N,N,30551,N,
+61302,N,30552,N,N,N,N,N,N,N,30553,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,61305,N,N,N,N,30555,N,30556,N,N,N,N,N,N,N,N,N,N,30557,N,N,N,61304,N,N,N,N,
+61306,N,N,N,N,61307,N,61308,N,N,N,N,N,N,N,N,N,N,N,61309,61310,N,N,N,61473,N,N,
+N,N,N,N,30559,N,N,N,N,N,N,30558,N,N,30560,N,N,N,N,N,N,61475,N,N,N,N,N,N,N,
+61476,N,N,N,N,N,61477,N,N,61478,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,30561,30562,N,N,N,N,N,N,61479,N,N,N,N,N,N,N,N,N,N,N,N,N,
+30563,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61482,N,N,N,N,N,N,N,N,61483,N,
+N,N,61484,61485,N,N,N,N,N,N,N,N,61487,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61488,N,
+30564,30565,61489,N,N,N,N,N,N,N,N,N,N,N,61490,N,N,N,N,N,N,N,N,N,N,61492,61493,
+N,N,N,N,N,N,N,N,61494,N,N,N,N,N,N,61495,N,N,N,N,N,N,N,N,N,N,N,N,N,30567,61496,
+N,N,N,N,N,N,N,N,N,N,N,N,30568,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61498,61499,N,
+61500,61501,N,N,N,N,N,N,N,N,N,N,N,N,30569,N,30570,61502,N,N,N,N,N,N,N,N,N,N,
+61504,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,61507,N,N,N,N,N,N,61508,30571,61509,N,N,N,N,N,N,N,N,N,N,61510,N,N,N,N,N,
+61511,61512,N,N,N,N,N,N,N,N,N,N,N,N,N,30573,30574,N,N,N,61515,N,N,N,N,61516,N,
+61517,N,N,N,N,N,61514,N,N,N,61518,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30576,N,
+61519,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30577,N,N,N,N,61521,61522,N,61524,
+61525,N,61526,N,N,N,N,N,61527,N,N,N,N,30578,N,N,N,N,61528,N,N,N,61529,N,N,N,N,
+61530,N,N,N,N,N,N,N,N,N,61531,30579,N,N,61532,N,N,N,61533,N,61534,30580,30581,
+N,30582,N,N,61535,30583,N,61536,N,N,30584,N,N,N,N,N,N,N,N,N,61537,N,61538,N,
+61539,N,N,61540,N,N,61541,N,N,N,N,N,61542,N,N,N,30585,N,61543,N,N,N,30586,N,N,
+N,N,N,N,30587,N,N,30588,N,N,N,N,N,N,N,61544,N,30589,N,N,N,61545,N,30590,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,61546,61548,61549,N,N,N,N,N,30753,N,N,30754,N,N,N,N,N,
+N,N,N,61547,N,N,N,N,N,N,30755,30756,N,N,N,N,N,N,N,N,61550,N,30758,N,30759,N,
+30760,30761,30762,N,30763,30764,30765,61551,N,N,N,N,N,N,N,61552,N,N,N,N,N,N,
+61554,N,N,61555,30766,N,30767,30768,N,N,N,30769,N,61556,N,N,N,N,61557,61553,N,
+N,N,30770,N,N,N,N,N,61558,N,N,N,N,30771,N,N,N,N,N,N,N,N,30772,N,30773,N,N,N,
+61559,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61560,N,N,N,61561,30774,30775,61562,30776,
+N,N,N,N,N,N,30781,N,61564,N,N,N,N,61565,30777,61566,N,N,30778,N,N,30779,61729,
+61730,N,30780,N,61731,30782,N,30783,30784,61732,61733,N,N,N,N,N,N,N,N,N,30785,
+N,N,N,61734,61736,61735,N,N,N,30786,N,N,N,N,N,N,N,N,30787,30788,N,N,N,N,N,N,N,
+N,N,N,N,N,61737,N,61738,N,30789,N,N,N,61739,N,N,N,N,N,N,N,N,N,N,N,N,61741,N,N,
+N,61740,N,N,N,N,N,N,N,N,N,N,61743,N,N,N,N,30790,30791,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,30792,N,N,N,N,N,N,N,N,61745,N,N,N,61746,N,N,N,N,N,61747,N,N,
+N,N,30793,N,N,N,N,N,N,N,N,N,N,N,N,N,61750,61751,N,61752,N,N,N,N,N,N,N,61753,N,
+N,N,N,N,61754,N,61755,N,61756,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,61757,N,N,30794,N,61759,61758,N,N,N,N,N,N,30795,61760,N,N,61761,61762,N,N,
+61763,N,N,N,N,N,N,N,N,N,N,61765,N,N,N,N,N,30796,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+61767,N,N,N,N,N,N,N,N,N,N,N,N,N,61769,N,N,N,N,N,N,61770,N,N,N,N,N,N,N,61771,
+61772,N,N,N,N,N,61773,N,N,N,N,N,N,N,30798,61774,N,N,N,61775,N,N,N,N,N,N,N,N,N,
+61776,N,61777,61778,N,N,N,30799,N,N,61779,N,N,N,N,61780,N,61781,N,N,61782,N,N,
+N,N,N,N,N,61783,30800,N,30801,61784,N,N,N,61786,30802,N,N,N,N,N,N,61787,N,N,N,
+61790,N,30803,30804,N,61785,30805,N,61791,61792,N,30806,N,N,N,N,N,N,61794,
+32381,N,61795,N,N,N,N,30807,N,N,N,N,N,61797,N,30808,N,N,N,N,N,N,61796,N,N,N,N,
+61800,N,30809,N,N,N,N,N,61802,N,30810,N,N,N,N,N,N,N,N,N,61803,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,30811,30812,N,N,N,N,N,N,N,30813,61805,30814,N,30815,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,30816,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61806,N,N,N,N,N,
+30817,61807,30818,30819,N,61809,61808,N,N,N,N,30820,61810,61811,N,30821,N,N,N,
+N,61812,N,N,N,N,N,N,30822,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30823,N,N,N,61814,N,N,
+30824,N,30825,N,N,N,N,N,30826,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30827,N,61816,
+N,N,N,61817,N,N,N,N,30828,N,N,N,N,N,N,N,N,N,N,30829,30830,N,N,N,N,N,N,N,N,N,N,
+N,N,61819,N,30831,61820,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61821,N,N,N,N,N,N,
+30832,61822,30833,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30834,N,N,N,N,N,N,30835,30836,
+N,N,N,N,N,N,N,N,N,61989,N,N,N,30837,N,N,30838,61990,N,30839,N,N,N,N,N,N,N,
+61991,N,N,N,N,N,N,N,61993,N,N,N,N,N,N,N,30840,N,61994,61995,N,N,30841,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30842,N,N,N,N,N,61998,N,N,N,N,61999,N,N,62000,N,
+62001,N,N,N,N,62002,30843,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62003,62004,30844,N,N,N,
+62005,N,62006,N,N,N,62007,N,62008,N,N,N,62010,N,N,N,62011,N,N,N,N,N,N,62012,
+62014,62015,N,N,62016,N,N,N,62017,N,N,N,N,N,N,N,N,N,N,N,62018,N,N,N,N,N,N,N,
+62019,N,N,N,N,N,N,N,N,N,N,62020,30845,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,31009,N,N,N,62021,N,N,N,N,N,N,31010,31011,N,31012,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,62022,N,N,N,31013,N,62023,N,N,N,31014,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,62025,N,N,N,N,N,N,N,N,N,62026,N,N,N,N,N,N,N,N,62028,
+62029,62030,N,N,N,N,62027,N,N,N,N,N,N,N,N,31018,N,N,31016,N,N,N,N,N,N,N,N,N,N,
+62031,N,N,N,N,N,N,N,N,N,N,N,N,62032,N,N,N,62033,N,62034,N,N,N,N,N,N,62035,N,N,
+N,N,N,N,N,N,N,N,62036,62037,N,N,31019,N,62038,N,N,N,N,N,N,N,N,N,N,N,31020,N,N,
+N,N,31022,N,62039,62040,62041,N,N,62042,31021,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+62044,N,N,N,N,N,N,N,N,N,N,62045,31023,N,N,N,N,N,N,N,N,62047,N,N,N,N,N,N,N,N,
+31024,N,62046,31025,N,N,31026,N,N,N,N,N,N,62048,N,N,N,N,N,N,N,N,N,31029,31030,
+N,N,N,62049,N,N,N,N,N,N,N,N,N,N,N,N,N,62050,N,N,62051,31034,N,N,N,N,N,N,N,N,N,
+N,62053,N,N,N,N,N,N,N,N,N,N,62054,N,N,N,N,N,N,31038,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,62055,62056,62057,N,31042,N,N,62058,N,N,N,N,N,62059,
+N,N,N,N,N,N,N,62060,N,N,N,N,N,N,N,31043,N,N,62061,N,N,N,31044,N,N,62062,N,N,N,
+N,N,N,62063,N,N,N,N,62064,31045,N,31046,N,62065,62066,N,N,N,N,N,N,31048,N,
+62067,N,N,N,N,N,N,N,31049,N,N,N,N,N,N,N,N,N,N,N,N,31050,N,31051,31052,N,N,N,N,
+N,N,62072,N,N,N,N,N,N,62073,N,N,N,62074,N,N,N,N,N,62075,N,N,62076,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,62078,N,N,N,N,N,N,N,N,N,N,62241,31054,N,N,N,N,N,N,N,N,N,N,N,N,
+N,62242,N,N,N,N,62243,N,N,N,N,N,N,N,N,N,62244,N,N,62245,N,N,62246,31055,N,
+62247,62248,N,N,N,N,N,N,62249,N,N,62250,N,N,31056,N,N,N,N,N,N,N,62251,N,N,
+62252,N,N,N,N,N,N,N,N,N,62253,N,N,31058,N,N,N,N,62254,N,N,N,N,N,62255,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,31059,N,N,62256,N,N,N,N,N,N,N,N,62257,N,N,N,N,N,N,31061,
+N,N,N,N,N,62260,N,31062,62261,N,62262,N,N,N,N,N,N,N,N,N,N,N,N,N,62264,N,31063,
+N,N,62265,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62266,62267,N,N,31064,N,N,
+N,N,N,N,N,N,62268,N,N,N,N,N,N,N,N,31065,62271,N,N,N,N,N,N,N,N,N,N,31066,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62274,N,N,62275,N,N,31067,62276,62277,N,
+62278,N,N,N,N,N,N,N,N,N,31068,N,62273,N,N,N,62282,N,N,N,N,N,31069,N,N,N,N,N,N,
+31070,N,N,N,N,N,N,62284,N,N,N,N,N,N,N,N,N,N,31071,N,N,N,62286,N,62287,N,N,
+62288,N,N,N,31072,N,31073,N,N,31074,62289,N,N,N,N,N,62285,N,N,N,N,N,62281,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,62292,62293,N,N,N,N,N,N,N,N,N,62294,N,N,31075,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,62296,N,N,N,N,N,62297,N,N,N,N,N,N,62298,N,N,N,N,N,
+N,N,N,62299,N,N,N,N,62300,N,N,N,N,N,N,N,N,N,62303,N,62304,31077,N,31078,62305,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62306,N,N,N,N,N,62307,31079,N,62308,N,N,N,N,N,N,
+N,62309,N,N,62310,62311,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31081,N,31082,N,N,N,N,N,
+62312,N,N,N,N,N,N,N,N,N,N,31080,N,31083,N,N,31084,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+62313,N,N,N,N,62314,N,N,N,N,N,N,62315,N,N,N,N,N,62316,N,31087,N,N,N,N,62317,N,
+N,62318,N,N,N,N,N,N,N,62319,N,N,N,31088,62320,62321,62322,N,N,N,N,N,N,N,N,
+31089,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31090,N,N,N,N,31091,N,N,N,N,N,
+N,N,N,N,N,N,31092,N,N,N,N,N,62326,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62328,62329,N,
+N,N,N,31093,N,N,62330,N,N,N,N,62332,N,N,N,62334,N,N,N,N,62497,N,N,N,N,N,N,N,
+31094,N,62499,N,31095,N,N,N,31096,N,N,N,N,N,N,N,N,62501,N,N,N,N,62502,N,N,N,N,
+N,N,N,N,N,62504,62505,N,N,N,31097,31098,62506,N,N,N,N,N,N,N,N,62508,31099,N,N,
+N,N,N,N,N,N,N,31100,62509,N,N,N,N,31101,N,N,N,N,N,N,N,N,N,N,N,N,N,31102,N,N,N,
+N,N,N,N,N,N,N,N,62512,62513,N,62514,31265,N,N,N,N,N,62515,31266,N,N,N,N,N,N,N,
+N,N,N,31267,N,N,N,N,N,62519,62520,N,31268,N,N,N,N,N,N,N,N,N,N,N,N,N,62521,N,N,
+N,N,N,62522,N,N,N,N,N,N,N,N,N,31269,N,N,N,N,62524,N,N,N,31270,N,N,62526,N,
+62527,N,N,31271,62528,N,N,N,N,N,N,N,N,N,N,62529,N,N,N,N,N,62531,N,N,31272,N,N,
+N,N,N,31273,62532,N,N,62533,N,N,N,N,N,N,N,N,N,N,N,62534,62535,N,N,N,N,N,N,N,N,
+62536,N,31274,N,N,N,N,N,N,N,N,N,31275,N,N,N,N,N,N,N,N,N,31276,62537,N,62538,N,
+N,N,N,N,N,N,N,N,31277,N,N,62539,N,N,N,N,N,N,N,N,N,N,62540,N,N,N,N,N,N,N,62541,
+31280,N,N,N,N,N,N,N,62545,31281,N,N,N,31282,N,62546,N,N,N,N,N,62547,N,N,62548,
+N,N,N,N,N,N,62549,31279,N,N,N,62550,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,62551,N,31284,N,N,N,N,N,N,N,N,N,N,31285,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+31286,N,N,N,N,N,N,N,N,N,32382,N,N,N,N,N,N,N,62552,N,62553,N,N,N,N,N,N,N,N,
+62554,N,N,N,N,N,N,N,62555,62556,N,N,31287,N,N,31288,N,N,N,62558,N,N,N,N,N,N,
+62559,N,62560,62563,62562,N,62564,N,N,N,N,62565,62566,N,N,31289,N,N,N,N,N,N,N,
+62567,N,N,62570,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62572,N,62573,62574,N,N,N,N,N,N,N,
+N,62575,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62576,62577,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,62579,31291,N,N,N,N,62582,31292,N,N,N,N,62583,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,62584,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31293,N,N,N,62586,N,N,N,N,N,N,N,
+N,N,N,31294,62587,N,N,N,N,N,N,N,N,N,N,N,31295,N,N,N,31296,N,N,N,62588,N,62589,
+N,N,N,N,N,N,31297,N,31298,62590,N,N,62753,N,N,N,N,N,N,N,31299,62754,N,N,N,N,N,
+62756,N,62755,N,N,N,62757,N,N,62758,N,N,31301,N,62759,N,N,N,N,N,N,N,N,N,N,N,N,
+N,62760,N,31302,N,N,N,N,N,62761,N,N,N,62762,N,N,N,N,31303,N,31304,N,N,N,N,
+31305,N,N,N,N,N,N,62763,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,62764,N,N,N,N,N,N,N,N,N,N,62765,N,N,N,62766,N,N,N,N,N,62767,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62768,N,N,62769,N,N,N,N,
+N,N,N,62770,N,N,62771,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62772,N,N,N,N,N,N,N,N,N,
+N,N,N,62774,N,N,N,N,31306,N,N,N,N,N,N,N,N,N,N,62775,N,31307,62776,N,N,N,N,N,N,
+N,31308,N,N,N,N,N,62777,N,N,N,N,N,N,N,N,N,N,N,N,31309,N,62780,N,N,N,N,N,62781,
+62779,N,N,N,N,N,N,N,N,62784,N,31310,N,N,N,N,N,62785,N,N,N,N,N,62787,N,N,62788,
+N,N,N,N,62789,N,N,N,N,N,N,N,N,62783,N,N,N,N,N,N,N,62791,N,N,N,N,N,N,N,N,N,N,N,
+N,31311,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31312,N,N,N,N,N,N,31313,
+31314,62793,N,N,N,31315,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62795,N,N,62797,
+62798,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62800,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,62801,N,N,N,N,N,N,N,N,31316,N,N,N,N,N,62802,N,62803,N,N,N,
+N,N,N,31317,N,N,N,N,31318,N,N,N,N,N,N,62804,31319,N,N,N,62805,N,N,N,N,N,N,N,N,
+62807,N,N,N,N,N,N,N,62809,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62811,N,62812,62814,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62816,N,N,N,N,N,N,N,62817,62818,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,62820,N,62821,N,N,N,N,N,N,N,62822,N,N,N,N,N,N,N,N,
+62825,62823,N,N,62824,N,62827,N,N,N,62829,N,N,N,N,N,N,N,62831,N,N,N,N,62833,N,
+N,N,31323,N,N,62834,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31324,N,N,N,N,62838,N,N,N,
+62840,N,62841,N,N,N,62842,N,N,N,N,N,N,62843,N,N,N,31326,N,N,N,N,62844,N,N,N,N,
+N,N,N,N,N,N,N,N,N,31327,N,31328,31329,N,N,62845,62846,31330,N,N,N,N,31331,N,N,
+N,63009,N,63010,N,N,31332,N,N,63011,N,63012,N,31333,31334,N,N,N,N,N,N,31335,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,31336,N,N,N,N,N,N,N,N,N,N,N,N,63013,N,N,N,N,N,63014,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,63015,N,N,N,N,N,31337,31338,31339,31340,N,N,N,N,N,
+63016,63017,N,N,N,63018,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63020,N,63021,N,N,N,N,
+31342,N,N,N,N,N,N,N,N,N,N,31343,N,N,63022,N,N,N,N,N,N,N,N,N,31344,N,63023,N,N,
+N,N,N,N,31345,63024,N,N,31346,N,N,N,N,N,N,N,N,N,31347,N,N,63019,31348,N,63025,
+N,N,N,N,N,N,N,N,N,N,31341,44618,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,31349,N,63027,N,N,N,N,N,N,31350,N,N,N,N,N,N,63030,N,N,N,N,31351,N,63031,
+63032,N,N,31352,N,N,63033,N,63034,N,N,N,N,N,N,N,N,N,31353,N,31354,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31355,31356,N,N,N,N,N,N,31357,N,63035,N,N,N,N,N,
+31358,63036,31521,N,N,63037,N,N,N,N,N,N,N,N,63038,N,N,N,31522,N,N,N,63039,N,N,
+N,N,31523,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63040,31524,N,N,N,N,31525,N,N,N,31526,N,
+N,N,N,63041,N,63042,N,N,N,63043,N,63045,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,63046,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31528,N,63047,N,
+N,N,N,63048,N,63049,63050,N,N,N,N,N,N,63051,63052,N,63053,N,N,31529,N,N,N,N,N,
+63055,N,N,N,N,N,N,N,N,N,N,31530,N,N,31531,N,N,63056,N,63057,N,N,N,63058,N,N,N,
+N,63059,N,N,N,31532,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63062,N,N,N,N,N,N,31533,
+N,N,N,N,N,N,N,63063,N,N,N,N,N,N,N,N,31534,N,N,N,N,31535,N,N,N,N,N,31536,N,N,N,
+63064,N,31537,N,31538,N,N,N,N,N,N,N,N,N,N,N,63066,63067,N,N,N,63068,N,N,N,N,N,
+N,N,N,63061,N,N,N,N,N,N,N,N,N,N,63070,N,N,63071,N,N,N,N,63072,63073,63074,N,N,
+N,N,N,N,N,N,63075,N,N,63076,63077,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63078,N,N,31541,
+N,N,N,N,31542,63079,63080,N,N,N,N,N,63081,N,N,N,31543,N,N,31540,N,63082,N,N,N,
+N,N,N,N,N,N,63087,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63083,N,63088,N,63089,N,N,N,
+N,N,31544,N,N,N,N,63090,N,N,63091,63092,N,31545,N,N,N,N,N,N,N,N,N,N,63084,N,N,
+N,N,N,N,N,N,N,N,31548,63094,N,63095,N,63096,N,63097,N,N,N,N,63098,N,N,N,N,N,
+31549,N,N,31550,N,N,N,63099,N,N,N,N,N,N,N,N,N,63100,N,63101,N,N,31551,N,N,N,N,
+N,N,N,N,N,N,31547,N,N,31552,N,N,N,N,N,N,63267,N,N,N,N,63268,N,N,N,N,N,N,N,N,N,
+N,63269,N,N,63270,31553,N,N,31554,N,N,N,N,N,N,N,N,N,63271,63272,N,N,N,N,N,
+63273,N,63274,N,N,N,N,63275,N,N,N,N,N,N,31555,N,N,N,N,N,N,N,N,63276,N,N,N,N,N,
+N,N,N,31557,63277,N,N,N,31558,31559,N,N,N,N,N,N,N,N,N,N,31560,63278,31556,N,N,
+N,N,N,31562,N,N,N,N,N,63279,N,N,63280,N,N,63281,N,N,63282,N,31563,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,31564,63284,N,N,63285,N,N,N,63287,12136,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,63289,N,N,63290,31565,N,N,N,31566,N,N,N,N,N,N,31568,N,N,N,N,N,N,N,
+N,N,31570,N,N,63291,N,N,N,N,N,31571,N,63292,N,N,63293,N,N,N,N,N,N,N,N,N,N,N,N,
+63294,N,63295,N,N,N,63296,N,N,N,63297,N,N,N,N,N,N,31572,N,N,N,63298,63299,N,N,
+N,N,N,N,N,N,N,N,63300,N,N,N,N,N,N,N,N,63302,N,63303,N,N,N,N,31573,N,N,N,N,N,N,
+N,N,63304,N,63305,N,N,N,N,N,N,N,N,N,N,N,N,N,63306,N,N,N,63307,N,63308,N,N,N,N,
+N,N,N,N,N,N,N,63309,N,N,63310,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31574,N,
+31575,31576,63312,N,63313,N,N,N,31577,N,N,63314,N,63315,N,N,63316,N,N,N,N,N,
+63317,N,N,N,N,N,63318,N,63319,N,63320,N,N,N,N,N,N,N,N,N,N,N,N,N,63321,N,N,N,N,
+N,N,N,N,63322,N,N,N,63323,N,63324,N,N,63325,N,N,N,N,N,N,N,N,N,N,N,N,N,63326,N,
+N,N,N,N,N,63327,N,N,N,N,N,N,N,N,N,N,N,63328,63329,N,N,N,N,N,N,N,N,N,N,N,31578,
+63330,N,N,N,N,N,N,N,N,N,63331,N,N,N,N,N,N,N,N,N,N,31579,31580,63335,N,63336,N,
+N,N,N,N,N,N,63337,N,N,N,N,N,N,N,N,N,N,N,N,63338,N,N,N,N,N,N,63334,N,N,N,N,
+31581,31582,N,N,N,N,N,N,N,31583,N,N,N,N,N,N,N,N,63341,N,N,63343,N,N,N,N,N,N,N,
+N,N,N,N,N,63344,N,N,N,N,N,N,N,31585,N,N,N,N,N,N,N,N,63346,N,N,N,63348,N,63349,
+63350,N,N,N,63351,63352,31586,63353,N,N,N,N,N,N,N,63345,63354,N,63355,N,N,
+31587,N,N,N,31588,63356,N,N,N,N,31589,N,N,63357,31590,N,N,N,N,N,N,N,N,N,N,
+31591,N,N,N,N,N,N,N,N,63358,N,N,N,N,N,63521,N,N,N,63522,N,N,N,N,N,N,N,N,N,
+63523,N,N,N,N,N,N,N,N,N,N,N,N,N,63525,N,N,N,N,N,N,N,N,N,N,N,N,N,63526,N,N,N,N,
+N,N,63527,N,N,N,N,63528,N,N,N,N,63531,N,N,N,N,N,63533,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31592,N,N,N,N,N,N,N,
+63534,N,N,N,N,N,N,N,N,N,31593,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63535,63536,
+63537,N,63538,N,N,N,N,N,N,N,N,N,31594,N,N,N,31595,N,N,63541,63539,63542,N,N,N,
+N,N,N,N,63543,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63544,63545,N,N,N,31597,
+63547,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31600,31601,31602,N,31598,N,
+N,N,N,N,N,N,N,N,N,31603,N,N,N,N,N,N,N,N,31604,N,31605,N,N,N,N,63549,N,31606,N,
+N,N,N,N,N,31607,N,63551,N,N,63552,N,N,N,63553,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,63556,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,63557,N,N,N,N,N,N,N,N,63558,N,N,N,N,N,N,63559,N,N,N,31608,N,N,N,N,N,N,N,N,N,
+N,63560,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63561,N,N,N,N,N,N,63562,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31610,N,63563,N,63564,N,N,N,N,N,N,N,
+N,N,N,N,N,31611,N,N,N,N,N,63565,N,N,N,N,N,63567,N,63568,N,N,31612,N,N,N,N,N,N,
+63569,N,63570,63572,31613,N,63573,31614,N,N,N,N,N,N,N,N,N,N,N,63575,31777,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63576,N,31778,N,N,N,N,N,N,63577,N,N,N,N,N,N,
+63578,N,31779,N,N,N,N,N,63579,31780,N,N,N,N,N,N,N,N,N,63580,N,N,N,N,31781,N,N,
+N,31782,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31783,N,N,N,31784,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63582,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,31785,N,N,N,N,N,N,63581,N,N,N,N,N,N,N,N,63583,N,N,N,N,N,N,63584,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,31786,N,N,N,N,N,N,63585,N,N,N,N,N,N,N,31787,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,31788,N,31789,N,N,N,N,N,63586,63589,N,N,N,N,63588,
+N,N,63590,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63591,N,N,63592,N,N,N,N,N,N,N,N,N,N,N,N,
+N,63593,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63594,N,N,31793,N,N,N,N,N,N,
+N,N,N,N,63596,N,N,31794,N,N,N,N,31795,N,N,N,N,63597,N,N,N,N,N,N,N,N,N,N,31796,
+N,N,N,N,N,N,N,N,N,N,N,N,63598,N,N,N,N,N,N,N,N,63599,N,63600,N,N,N,N,N,N,N,N,N,
+63601,N,N,N,N,N,N,N,N,63602,63603,N,N,N,N,N,N,63604,31797,63605,63606,N,N,N,
+63608,N,N,N,N,N,N,N,63611,N,63612,N,31798,N,N,N,N,N,63613,N,N,N,N,63614,N,N,
+63777,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31799,63778,N,N,N,63779,N,N,N,N,N,63780,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63783,63782,N,N,N,
+N,N,63784,N,63786,N,N,N,N,N,N,N,N,63787,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63789,63788,N,N,
+63790,N,N,N,N,N,N,N,31801,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63792,63793,N,N,31802,N,
+N,N,31803,N,N,N,N,N,31804,63795,N,N,N,N,63796,N,N,N,31806,N,N,N,N,N,N,N,N,
+31807,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,63797,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63798,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,63799,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63800,N,N,N,N,N,N,
+N,N,31808,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63802,N,63803,N,N,N,N,N,
+31809,N,N,31810,N,N,N,N,N,31811,N,63804,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+63805,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63808,63809,N,N,N,N,N,63806,N,N,N,N,N,N,
+N,63811,N,63812,N,N,N,N,N,N,N,N,N,31812,63813,63814,31813,N,N,N,63815,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,63818,N,N,63819,N,N,N,31814,N,N,N,N,N,N,N,N,N,N,N,N,N,
+63820,N,N,N,N,N,N,N,N,63821,N,N,N,N,N,N,N,N,N,N,N,N,N,63822,N,N,N,N,N,N,N,N,N,
+63823,63824,N,63825,31815,N,N,N,N,N,N,N,N,N,N,31816,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63826,N,N,N,N,N,63827,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,63828,N,N,N,N,63829,N,63830,63831,N,N,N,N,63832,N,N,N,N,31818,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,63834,N,N,63835,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63837,31820,63839,N,N,N,N,N,N,N,63840,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,63841,N,N,N,N,N,N,31821,N,N,N,N,N,N,N,N,N,N,N,N,63842,N,
+31822,N,N,N,N,N,N,N,N,31823,N,N,N,N,N,N,N,N,N,63843,N,N,N,N,N,N,N,N,N,63844,N,
+N,N,N,N,N,N,N,N,31824,N,N,N,63845,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,63847,N,31826,N,N,N,N,N,N,N,N,N,N,N,N,N,63848,
+31827,63850,N,N,N,N,N,N,N,N,N,N,63852,N,N,N,N,63853,N,N,N,63855,N,N,63856,N,N,
+N,N,N,63857,N,63858,N,N,N,N,N,N,N,N,N,N,63859,N,N,N,31828,N,N,N,31829,N,N,N,N,
+N,31830,N,N,63860,N,N,N,63861,N,N,N,N,N,63862,63863,N,N,N,N,N,31831,N,N,N,
+63864,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31832,N,
+N,N,N,N,N,N,N,N,63865,N,N,N,N,N,N,N,N,N,N,N,63867,63868,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,63869,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64034,N,N,31834,N,N,N,64035,N,N,N,64036,N,N,N,
+N,31835,N,31836,N,31837,N,31838,N,N,N,N,N,64038,31839,N,N,N,N,N,N,N,N,N,N,N,N,
+N,64040,N,N,31840,N,N,64041,N,N,N,N,N,N,N,31841,N,N,N,N,64042,31842,31843,N,
+31844,64043,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31845,N,N,N,N,64045,31846,31847,64046,
+N,N,N,N,N,N,N,N,N,N,N,64051,N,N,N,31848,N,N,64049,N,31849,N,64048,N,N,N,N,N,N,
+N,64052,64053,64050,N,N,N,64054,N,64055,N,N,N,N,N,N,N,N,N,N,N,N,N,31851,31852,
+31853,N,64056,N,N,N,64057,N,64058,N,N,N,31854,31855,N,N,N,31856,N,N,N,N,N,N,N,
+31857,N,31858,N,N,31859,N,N,64059,N,64060,64061,N,N,31860,N,N,N,N,N,N,N,N,
+64062,64063,31861,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64064,N,64065,N,31862,N,N,N,N,N,
+64066,N,N,64067,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64068,N,N,N,N,64069,N,N,N,N,N,N,
+N,N,N,31863,N,64070,N,N,N,N,N,N,N,N,64071,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31864,
+N,N,N,N,N,N,N,N,N,64072,N,N,N,31865,N,64073,N,N,31866,N,64074,N,N,64075,N,N,N,
+N,N,31867,N,N,N,N,N,N,64076,64077,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31868,N,
+N,64078,N,N,N,N,N,N,N,N,N,31870,32033,N,N,N,N,N,N,64081,32034,64082,N,N,32035,
+N,N,N,N,N,N,N,N,N,31869,64083,N,N,N,N,N,32036,N,N,64084,N,N,N,N,N,32037,N,N,N,
+N,N,64085,64086,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64088,N,
+N,N,N,32038,32039,32040,N,32041,N,N,N,32042,N,64089,32043,N,N,N,64090,N,N,
+64091,N,N,N,64092,32044,N,64093,N,N,N,N,64094,N,N,64095,N,N,N,N,N,N,64096,
+64097,N,N,N,64098,N,64099,64100,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,32045,N,N,N,
+64103,64104,N,64105,N,N,N,N,N,N,N,N,32046,64106,N,N,N,64107,N,N,N,N,N,N,N,N,N,
+64108,N,64109,N,N,N,N,N,64110,N,N,N,N,N,N,N,64111,N,N,N,64112,N,N,N,N,N,N,
+64115,N,N,N,N,N,N,N,N,N,N,N,N,64116,64117,N,32047,N,N,N,64118,N,N,N,N,32048,
+32049,N,64119,N,64120,N,N,32050,N,N,N,64121,N,64122,N,N,N,N,N,N,32051,N,N,N,N,
+64123,N,64124,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64290,N,64291,N,64292,N,N,N,32052,
+64293,N,32053,N,N,N,N,N,N,N,N,64294,N,N,N,64125,N,N,N,64295,N,N,N,N,N,N,N,
+64296,64297,32054,N,32055,N,N,N,32056,N,64298,N,64299,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64302,32057,32058,32059,N,N,N,N,N,N,64303,N,
+N,N,N,N,64304,N,N,64305,N,N,N,N,N,N,N,N,N,32060,32061,N,N,N,N,32062,64306,N,N,
+N,N,32063,64307,N,64308,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64312,N,N,
+64313,N,N,N,64314,N,N,N,N,N,N,N,N,N,N,N,32064,N,N,64315,N,N,64309,N,32065,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,32066,N,N,N,N,N,N,64320,N,N,N,N,32067,
+64321,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64322,N,32068,32069,N,N,64323,N,
+N,N,N,64324,N,N,N,N,N,N,N,N,N,64319,N,N,N,64316,N,N,N,N,N,64329,N,32071,32070,
+N,N,N,N,64325,N,N,N,N,N,64326,N,N,N,N,N,N,64327,64328,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,64330,32072,64331,N,N,N,N,N,N,64332,N,N,N,N,N,N,N,
+N,N,64333,N,N,N,N,32073,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,32074,
+N,N,N,N,N,N,N,32075,N,64336,N,64337,N,32076,32077,64338,64339,N,N,N,N,N,N,N,N,
+N,N,N,N,64340,N,N,N,N,N,64341,64342,32078,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+32079,N,N,N,N,N,N,32080,N,N,32081,N,64344,32082,N,N,N,N,N,N,N,64345,N,32083,N,
+N,N,N,N,N,32084,N,N,N,N,N,N,N,N,N,N,64347,N,N,32085,N,N,N,N,32086,N,N,32087,N,
+N,N,N,N,N,32089,N,N,N,32090,64037,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64350,N,N,N,N,N,
+N,64351,64352,N,N,N,N,N,N,N,64354,N,N,N,N,64355,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,32091,N,N,N,N,N,N,N,N,64356,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,64358,N,32092,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,64360,N,N,32094,N,N,N,N,N,N,32095,32096,N,N,N,64363,N,N,N,N,N,64364,N,N,
+N,64365,N,N,N,N,N,N,64366,N,N,64367,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+32097,N,N,N,N,N,64370,N,64371,N,N,64372,32098,N,N,N,N,N,N,N,N,N,N,32100,N,N,N,
+N,N,32101,64374,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64375,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,32102,N,N,64377,N,N,N,N,32103,N,N,N,N,N,64378,N,N,N,N,N,64379,N,N,N,N,N,
+32104,32105,32106,N,N,N,N,N,64380,N,64381,N,N,32107,64382,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,64545,N,N,N,32108,N,N,N,N,32109,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,32110,64548,N,N,N,64549,N,N,N,64550,N,N,N,64551,N,
+N,N,N,N,N,N,N,N,N,N,32111,N,N,64552,64553,N,N,N,N,N,N,N,32112,N,N,N,64554,N,N,
+32113,N,N,N,N,N,N,N,32114,N,N,64555,N,N,N,N,64556,N,N,64557,N,N,N,64558,64559,
+N,32116,N,N,32115,N,N,64560,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64561,N,N,32117,
+64562,N,N,N,N,N,32119,N,N,64563,64564,N,N,N,N,N,64565,N,64566,N,N,N,N,N,N,N,
+32120,N,N,N,N,64569,N,64572,N,N,N,N,N,32121,N,N,N,N,32122,N,64570,64571,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64573,N,N,N,N,N,N,N,N,N,N,32124,32125,N,N,
+32126,32289,N,32290,32291,N,N,N,N,N,N,N,N,N,N,32293,64574,N,N,N,N,N,32294,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64575,N,64576,N,N,64577,N,N,N,N,N,N,
+64579,64580,N,32295,64581,64582,N,N,64583,N,N,64584,N,N,N,N,64585,32296,N,N,
+64586,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64587,64589,N,64590,N,64591,N,
+32297,N,N,64592,N,N,N,N,N,64593,64594,N,64595,64596,N,N,N,N,N,N,N,N,N,N,N,N,N,
+64599,64600,N,N,64602,64603,64604,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+64606,64607,64608,N,N,N,N,N,N,64609,64610,64611,N,N,N,64612,64613,N,N,N,N,
+64614,N,N,N,N,N,N,64615,64616,N,N,N,N,N,N,N,N,N,32298,N,N,N,64617,N,N,64618,
+64619,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,32299,N,N,N,N,64620,N,N,
+64621,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64622,N,N,N,64623,N,64624,N,N,N,
+64625,N,N,N,N,N,64626,N,N,N,N,N,N,N,N,N,N,64627,N,N,N,N,64628,N,N,N,N,64629,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64631,N,N,N,N,N,N,N,N,64632,N,N,64633,32300,
+32301,N,N,N,N,N,N,64634,N,N,N,N,N,N,64635,N,N,N,N,64636,N,N,N,64637,N,N,N,N,N,
+64638,N,N,N,32302,N,N,N,N,N,N,N,N,32303,32304,N,N,64801,N,N,N,N,64802,N,32305,
+N,N,N,N,N,N,N,N,N,N,N,64803,N,N,N,N,N,32306,N,64804,N,32307,N,N,N,32308,N,N,N,
+N,N,64805,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,64807,N,N,N,N,N,N,32309,64809,N,64811,N,N,N,N,N,N,N,
+32310,N,32311,N,N,64813,N,N,N,N,N,N,N,32312,N,64814,N,64815,N,N,64816,32313,N,
+N,N,N,N,64818,N,N,N,64819,N,N,N,N,64820,N,N,N,64821,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,32314,32315,64822,N,N,N,N,32316,N,N,N,64823,N,N,N,64824,N,64825,N,N,N,
+64826,N,N,N,N,N,64827,N,N,N,32317,N,N,N,N,N,N,N,N,N,N,64828,N,32319,N,N,N,N,N,
+64829,N,N,N,N,N,N,N,N,N,64830,N,N,N,N,N,N,N,N,N,N,N,N,N,64832,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,32320,N,N,N,N,64833,N,64834,32322,N,N,N,N,64835,64836,N,N,
+N,N,N,32323,64837,N,32324,64838,64839,N,32321,N,N,N,N,N,N,N,N,N,N,32325,N,N,N,
+N,N,32326,N,N,N,N,32327,N,N,N,N,N,N,N,N,N,N,N,N,N,N,32328,N,N,N,N,N,N,N,64840,
+32329,N,N,N,N,64841,N,N,N,N,64842,64845,N,N,N,N,N,64846,N,N,N,N,N,64847,N,N,
+32330,N,N,N,N,N,64848,N,N,N,N,N,N,32331,N,N,N,N,N,N,N,N,N,64850,N,N,N,N,64851,
+N,N,N,N,N,N,N,32332,N,64852,N,N,64853,64854,N,N,64856,64855,N,N,N,64849,N,N,N,
+64860,32333,N,64858,N,N,32334,32335,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+64862,N,64863,64864,64865,N,N,64866,N,N,N,N,64867,32336,N,N,N,64868,N,64869,
+64870,N,N,N,N,N,N,64872,N,N,N,N,64873,64874,N,N,N,N,N,N,N,N,N,32337,N,N,N,
+64875,N,N,N,64878,64879,N,N,N,N,32338,32339,N,N,32340,64881,N,N,N,64882,N,N,
+64883,64876,64884,N,64885,N,N,N,32341,N,32342,N,N,N,64886,64887,64888,N,64889,
+64890,N,64891,N,64892,N,N,64893,N,32343,N,N,64894,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65057,N,N,N,N,N,N,N,N,N,N,N,65058,65060,N,N,N,N,
+N,N,N,N,65059,N,N,N,N,N,65062,N,N,N,N,N,65063,65064,N,N,N,N,32344,32345,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65068,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65070,
+32346,N,N,N,32347,N,N,65071,N,N,N,N,N,N,N,32348,N,N,N,N,N,N,N,N,N,N,N,N,65072,
+N,N,65073,32349,N,N,N,N,N,65075,N,65076,N,N,N,N,32350,N,N,65078,N,N,65079,
+65080,N,N,N,N,32351,N,65081,N,N,N,N,N,65082,N,N,N,N,N,32352,N,N,65083,N,N,N,N,
+N,N,N,N,32353,N,N,65084,N,N,N,N,N,N,N,65085,N,N,N,N,N,N,N,N,N,N,32355,N,N,N,N,
+N,N,N,N,65087,N,N,N,65088,N,N,32356,65089,N,65086,32354,N,N,65090,N,N,N,65091,
+N,65092,N,N,N,N,N,N,N,N,N,N,N,N,65093,32357,N,N,65094,N,N,N,N,65095,65096,N,N,
+65097,N,N,N,32359,N,N,N,N,N,N,N,N,N,N,N,N,65098,65101,N,N,N,N,32360,N,N,65100,
+N,N,65102,N,N,N,N,N,N,N,32361,N,N,N,65103,N,N,65104,65105,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,65106,32362,N,N,N,65108,N,N,N,N,65109,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,65110,N,N,32363,N,N,N,N,N,32364,N,N,N,65111,N,N,N,32365,N,N,32366,
+N,N,N,N,32367,32368,N,N,N,N,N,N,N,65113,N,N,N,N,N,32369,N,N,N,N,N,N,N,N,N,N,N,
+N,N,32370,N,N,N,N,N,N,N,N,N,N,N,N,N,65115,N,N,N,N,N,N,N,65116,N,N,N,N,N,N,
+65117,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65118,65119,65121,N,N,N,N,N,N,N,N,N,N,N,
+N,32371,N,N,N,N,N,N,65122,N,65123,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+65124,N,N,N,N,N,N,N,65125,N,32372,65126,N,N,65127,N,N,N,65128,N,N,N,65129,
+65130,N,N,N,N,N,N,N,N,N,N,N,N,65131,N,65132,N,32373,65133,N,N,N,N,65135,N,N,N,
+N,N,N,N,N,N,N,N,65137,N,N,N,65139,N,N,65140,N,N,N,N,65141,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,32374,N,N,N,32375,N,N,32376,N,N,N,N,N,N,N,N,N,
+N,32377,30267,N,N,N,N,N,N,N,N,N,N,29742,30030,N,N,N,N,N,N,N,N,N,N,N,N,31567,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30281,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+32292,N,N,N,N,N,N,N,N,N,N,N,32093,12107,12119,20338,N,44665,30074,30554,30575,
+N,N,31036,31037,31041,N,N,N,31546,63288,63301,31790,N,63854,N,31850,N,N,N,N,N,
+N,N,N,N,11832,11849,11856,11875,11880,11886,12076,12079,12086,12122,12126,
+20321,20322,29776,29788,29790,29793,29992,29995,30019,30053,30313,30327,30501,
+30549,61481,30757,31015,31027,31028,31031,31032,31033,31035,31039,31040,31053,
+31057,31076,31278,62544,31283,31290,31300,31320,62836,62837,31527,31599,31609,
+31791,31792,31800,31805,63849,31833,32099,32118,32123,9022,9021,8752,N,N,N,N,
+8751,N,N,N,N,N,8753,
+};
+
+static const struct unim_index jisx0213_bmp_encmap[256] = {
+{__jisx0213_bmp_encmap+0,126,255},{__jisx0213_bmp_encmap+130,0,253},{
+__jisx0213_bmp_encmap+384,80,233},{__jisx0213_bmp_encmap+538,0,194},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__jisx0213_bmp_encmap+733,62,63
+},{__jisx0213_bmp_encmap+735,112,115},{__jisx0213_bmp_encmap+739,19,172},{
+__jisx0213_bmp_encmap+893,15,233},{__jisx0213_bmp_encmap+1112,5,219},{
+__jisx0213_bmp_encmap+1327,5,206},{__jisx0213_bmp_encmap+1529,35,254},{
+__jisx0213_bmp_encmap+1749,177,230},{__jisx0213_bmp_encmap+1803,0,110},{
+__jisx0213_bmp_encmap+1914,19,127},{0,0,0},{__jisx0213_bmp_encmap+2023,52,251
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__jisx0213_bmp_encmap+2223,
+22,255},{__jisx0213_bmp_encmap+2457,240,255},{__jisx0213_bmp_encmap+2473,49,
+250},{__jisx0213_bmp_encmap+2675,3,205},{__jisx0213_bmp_encmap+2878,2,219},{
+__jisx0213_bmp_encmap+3096,31,244},{__jisx0213_bmp_encmap+3310,5,207},{
+__jisx0213_bmp_encmap+3513,97,253},{__jisx0213_bmp_encmap+3670,0,250},{
+__jisx0213_bmp_encmap+3921,23,111},{__jisx0213_bmp_encmap+4010,110,234},{
+__jisx0213_bmp_encmap+4135,14,240},{__jisx0213_bmp_encmap+4362,15,210},{
+__jisx0213_bmp_encmap+4558,17,212},{__jisx0213_bmp_encmap+4754,5,148},{
+__jisx0213_bmp_encmap+4898,87,215},{__jisx0213_bmp_encmap+5027,57,147},{
+__jisx0213_bmp_encmap+5118,5,243},{__jisx0213_bmp_encmap+5357,7,221},{
+__jisx0213_bmp_encmap+5572,2,240},{__jisx0213_bmp_encmap+5811,8,212},{
+__jisx0213_bmp_encmap+6016,8,234},{__jisx0213_bmp_encmap+6243,15,175},{
+__jisx0213_bmp_encmap+6404,12,253},{__jisx0213_bmp_encmap+6646,22,181},{
+__jisx0213_bmp_encmap+6806,176,250},{__jisx0213_bmp_encmap+6881,4,188},{
+__jisx0213_bmp_encmap+7066,59,232},{__jisx0213_bmp_encmap+7240,23,209},{
+__jisx0213_bmp_encmap+7427,7,119},{__jisx0213_bmp_encmap+7540,2,255},{
+__jisx0213_bmp_encmap+7794,0,242},{__jisx0213_bmp_encmap+8037,0,243},{
+__jisx0213_bmp_encmap+8281,3,244},{__jisx0213_bmp_encmap+8523,1,251},{
+__jisx0213_bmp_encmap+8774,0,245},{__jisx0213_bmp_encmap+9020,18,255},{
+__jisx0213_bmp_encmap+9258,0,233},{__jisx0213_bmp_encmap+9492,7,247},{
+__jisx0213_bmp_encmap+9733,10,255},{__jisx0213_bmp_encmap+9979,4,244},{
+__jisx0213_bmp_encmap+10220,5,248},{__jisx0213_bmp_encmap+10464,12,245},{
+__jisx0213_bmp_encmap+10698,0,253},{__jisx0213_bmp_encmap+10952,3,244},{
+__jisx0213_bmp_encmap+11194,6,233},{__jisx0213_bmp_encmap+11422,0,253},{
+__jisx0213_bmp_encmap+11676,0,252},{__jisx0213_bmp_encmap+11929,13,248},{
+__jisx0213_bmp_encmap+12165,16,245},{__jisx0213_bmp_encmap+12395,21,253},{
+__jisx0213_bmp_encmap+12628,3,247},{__jisx0213_bmp_encmap+12873,9,255},{
+__jisx0213_bmp_encmap+13120,4,252},{__jisx0213_bmp_encmap+13369,0,251},{
+__jisx0213_bmp_encmap+13621,1,252},{__jisx0213_bmp_encmap+13873,1,252},{
+__jisx0213_bmp_encmap+14125,3,254},{__jisx0213_bmp_encmap+14377,15,253},{
+__jisx0213_bmp_encmap+14616,11,255},{__jisx0213_bmp_encmap+14861,2,251},{
+__jisx0213_bmp_encmap+15111,0,252},{__jisx0213_bmp_encmap+15364,23,251},{
+__jisx0213_bmp_encmap+15593,10,252},{__jisx0213_bmp_encmap+15836,0,236},{
+__jisx0213_bmp_encmap+16073,3,254},{__jisx0213_bmp_encmap+16325,0,251},{
+__jisx0213_bmp_encmap+16577,7,250},{__jisx0213_bmp_encmap+16821,1,255},{
+__jisx0213_bmp_encmap+17076,1,249},{__jisx0213_bmp_encmap+17325,0,252},{
+__jisx0213_bmp_encmap+17578,10,251},{__jisx0213_bmp_encmap+17820,5,254},{
+__jisx0213_bmp_encmap+18070,0,237},{__jisx0213_bmp_encmap+18308,3,253},{
+__jisx0213_bmp_encmap+18559,7,240},{__jisx0213_bmp_encmap+18793,1,245},{
+__jisx0213_bmp_encmap+19038,3,249},{__jisx0213_bmp_encmap+19285,8,154},{
+__jisx0213_bmp_encmap+19432,59,250},{__jisx0213_bmp_encmap+19624,2,251},{
+__jisx0213_bmp_encmap+19874,13,255},{__jisx0213_bmp_encmap+20117,4,254},{
+__jisx0213_bmp_encmap+20368,0,249},{__jisx0213_bmp_encmap+20618,1,253},{
+__jisx0213_bmp_encmap+20871,12,255},{__jisx0213_bmp_encmap+21115,0,253},{
+__jisx0213_bmp_encmap+21369,5,245},{__jisx0213_bmp_encmap+21610,1,245},{
+__jisx0213_bmp_encmap+21855,1,255},{__jisx0213_bmp_encmap+22110,17,252},{
+__jisx0213_bmp_encmap+22346,5,158},{__jisx0213_bmp_encmap+22500,57,254},{
+__jisx0213_bmp_encmap+22698,9,253},{__jisx0213_bmp_encmap+22943,6,250},{
+__jisx0213_bmp_encmap+23188,0,251},{__jisx0213_bmp_encmap+23440,2,255},{
+__jisx0213_bmp_encmap+23694,0,251},{__jisx0213_bmp_encmap+23946,1,255},{
+__jisx0213_bmp_encmap+24201,2,253},{__jisx0213_bmp_encmap+24453,4,114},{
+__jisx0213_bmp_encmap+24564,120,222},{__jisx0213_bmp_encmap+24667,29,239},{
+__jisx0213_bmp_encmap+24878,20,244},{__jisx0213_bmp_encmap+25103,4,243},{
+__jisx0213_bmp_encmap+25343,8,252},{__jisx0213_bmp_encmap+25588,2,249},{
+__jisx0213_bmp_encmap+25836,2,253},{__jisx0213_bmp_encmap+26088,0,242},{
+__jisx0213_bmp_encmap+26331,2,244},{__jisx0213_bmp_encmap+26574,2,255},{
+__jisx0213_bmp_encmap+26828,2,162},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__jisx0213_bmp_encmap+26989
+,29,220},{__jisx0213_bmp_encmap+27181,15,106},{0,0,0},{0,0,0},{0,0,0},{
+__jisx0213_bmp_encmap+27273,69,70},{__jisx0213_bmp_encmap+27275,2,13},
+};
+
+static const ucs2_t __jisx0213_1_emp_decmap[340] = {
+11,4669,U,U,U,U,U,U,U,U,U,4891,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,5230,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,6333,2975,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,5812,U,U,U,U,U,U,U,U,U,U,7732,12740,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+13764,14143,U,U,U,U,U,U,U,U,14179,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,15614,18417,21646,21774,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,22385,U,U,U,U,U,U,U,U,U,U,U,
+U,22980,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,23969,27391,28224,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,28916,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,30340,33399,U,U,U,U,U,U,U,33741,41360,
+};
+
+static const struct dbcs_index jisx0213_1_emp_decmap[256] = {
+{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+__jisx0213_1_emp_decmap+0,34,34},{__jisx0213_1_emp_decmap+1,66,123},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{__jisx0213_1_emp_decmap+59,84,110},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{__jisx0213_1_emp_decmap+86,58,114},{
+__jisx0213_1_emp_decmap+143,41,96},{__jisx0213_1_emp_decmap+199,108,108},{
+__jisx0213_1_emp_decmap+200,126,126},{__jisx0213_1_emp_decmap+201,41,110},{
+__jisx0213_1_emp_decmap+271,93,93},{__jisx0213_1_emp_decmap+272,51,108},{
+__jisx0213_1_emp_decmap+330,73,81},{0,0,0},{__jisx0213_1_emp_decmap+339,102,
+102},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},
+};
+
+static const ucs2_t __jisx0213_2_emp_decmap[2053] = {
+137,U,U,U,U,U,U,U,U,U,162,U,U,164,U,U,U,U,U,U,U,418,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,531,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,811,U,U,U,U,U,U,897,U,881,1017,U,U,1098,U,1289,U,U,U,U,U,U,U,U,U,
+1494,1576,U,U,U,U,U,1871,U,U,U,U,U,U,2055,U,2106,U,U,U,U,U,U,U,U,2233,U,U,U,U,
+U,U,U,2428,2461,U,U,U,U,U,2771,U,U,2845,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,3397,3553,U,U,U,U,U,U,3733,3693,U,U,U,U,U,U,U,3684,U,U,3935,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,4609,U,U,4693,U,4731,U,U,U,
+U,4724,U,U,U,U,U,U,4836,4823,U,U,U,U,U,U,4861,U,4918,4932,5060,U,U,U,U,U,U,U,
+U,U,U,U,U,5229,U,U,U,U,U,U,U,U,U,U,U,5591,U,U,U,U,U,27689,U,U,5703,U,U,U,U,U,
+U,U,U,U,U,U,U,U,5894,5954,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,6595,7254,U,U,U,U,U,U,7469,7493,U,7544,7522,U,U,U,
+7585,7580,U,U,U,U,7570,U,U,7607,U,7648,7731,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+7966,U,U,U,U,U,U,U,U,U,U,8054,U,U,U,U,U,8186,8571,U,U,U,U,U,U,U,U,8990,U,U,U,
+U,9133,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,9971,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,10331,U,U,U,U,U,U,U,10411,U,U,U,U,10639,
+10936,U,U,U,U,11087,11088,U,U,U,U,U,U,U,11078,U,11293,11174,U,U,U,11300,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,11745,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,12739,12789,12726,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,13170,U,13267,13266,U,U,U,U,13264,13284,
+13269,U,U,13274,U,13279,U,U,U,U,U,U,U,U,U,U,U,13386,13393,13387,U,U,U,13413,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,13540,13658,13716,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,13881,13895,U,13880,13882,U,U,U,U,U,U,U,U,U,U,
+14108,U,U,U,U,U,U,U,U,U,U,14092,U,U,U,U,U,U,U,14180,U,U,U,U,U,U,U,14335,14311,
+U,U,U,U,U,14372,U,U,U,U,14397,15000,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,15487,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,15616,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+15680,U,15866,15865,15827,16254,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,16534,
+U,U,U,U,U,16643,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,16838,U,U,16894,17340,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,17961,U,U,U,U,U,18085,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,18582,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,19021,19286,U,19311,U,U,U,U,19478,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,19732,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,19982,U,U,
+U,20023,U,U,U,U,20074,U,U,20107,U,U,U,U,U,U,U,U,U,U,U,20554,U,20565,U,U,20770,
+20905,U,20965,20941,U,U,U,21022,U,U,U,21068,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+21550,U,U,U,U,U,U,U,U,U,U,21721,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,21927,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,22441,22452,22996,U,U,U,U,U,U,U,
+U,U,U,23268,23267,U,23281,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,23474,U,U,U,U,U,U,
+U,U,U,U,23627,23652,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,24110,24150,24165,
+U,24162,U,U,U,24280,U,24258,24296,U,24355,U,U,24412,U,U,U,U,U,U,24544,24532,U,
+U,U,U,24588,24571,U,U,U,U,U,U,U,24599,U,U,U,U,24672,U,U,U,U,U,U,U,U,U,U,U,U,
+24813,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,25200,U,25222,U,U,U,U,
+U,U,25420,U,U,15630,U,U,U,25602,26238,U,U,U,U,26288,U,U,U,U,U,U,U,U,U,U,U,
+26397,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,26845,U,26858,U,26961,U,U,26991,U,27101,U,
+U,U,27166,U,U,U,U,U,U,27224,U,U,U,U,U,27276,U,U,27319,27763,U,U,U,U,U,U,U,U,U,
+27869,U,U,U,U,U,U,U,U,U,U,U,U,U,U,28261,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,28564,U,U,U,U,U,U,U,U,28664,28662,28663,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,28941,U,U,28985,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,29659,29658,U,U,U,U,U,29694,U,U,29712,U,U,U,U,
+29769,30229,30228,U,30257,U,U,U,U,U,U,U,30355,U,U,U,U,U,U,U,30478,U,30499,U,U,
+U,30546,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,31109,U,U,U,U,U,U,U,U,U,U,U,U,
+31364,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,31667,U,31678,31687,31928,U,U,U,U,
+U,U,U,U,U,32160,U,U,32272,U,U,U,U,U,U,32695,U,U,U,U,U,U,U,U,32906,U,U,U,U,U,
+32955,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,33410,U,U,U,U,33523,U,U,U,U,U,U,U,33804,
+U,U,U,U,33877,U,U,U,U,U,U,U,U,U,U,U,U,U,U,34155,U,U,U,34248,34249,U,U,U,U,U,U,
+U,U,U,U,34519,U,U,34554,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,35145,35142,U,U,U,U,U,U,35179,U,U,U,U,U,U,U,U,U,U,U,U,U,35207,35208,U,
+U,U,U,U,U,U,U,U,U,35258,35259,U,U,U,U,U,U,U,U,U,U,U,35358,35369,U,U,U,U,U,U,U,
+U,U,U,35441,35395,U,U,U,U,U,U,U,U,35481,35533,U,U,U,U,U,35556,35549,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,35777,35823,U,U,U,U,U,U,U,36112,U,U,36209,U,36347,36383,U,
+U,U,36406,U,U,U,36489,U,36587,U,36658,U,U,U,U,U,U,U,36856,37536,37553,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,38032,U,U,U,U,U,U,U,U,U,38351,U,U,U,U,U,U,U,U,
+U,38527,U,U,U,U,U,U,U,U,U,38640,U,U,38681,U,U,U,38736,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,39110,39538,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,40411,40509,U,U,U,U,U,U,U,U,U,U,U,U,40469,U,40586,U,40521,U,
+U,U,U,U,U,U,U,U,40644,U,U,U,U,U,40681,U,U,40667,40910,U,U,U,41007,U,40986,U,U,
+U,U,U,U,41209,U,U,41090,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,8728,U,U,U,U,41868,U,42039,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,42481,U,
+42498,U,42522,U,U,U,42674,
+};
+
+static const struct dbcs_index jisx0213_2_emp_decmap[256] = {
+{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{__jisx0213_2_emp_decmap+0,33,121},{0,0,0},{
+__jisx0213_2_emp_decmap+89,34,119},{__jisx0213_2_emp_decmap+175,42,117},{
+__jisx0213_2_emp_decmap+251,37,126},{0,0,0},{0,0,0},{__jisx0213_2_emp_decmap+
+341,48,108},{0,0,0},{0,0,0},{0,0,0},{__jisx0213_2_emp_decmap+402,34,114},{
+__jisx0213_2_emp_decmap+483,36,125},{__jisx0213_2_emp_decmap+573,35,120},{
+__jisx0213_2_emp_decmap+659,42,117},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+__jisx0213_2_emp_decmap+735,35,96},{__jisx0213_2_emp_decmap+797,50,100},{
+__jisx0213_2_emp_decmap+848,34,123},{__jisx0213_2_emp_decmap+938,46,122},{
+__jisx0213_2_emp_decmap+1015,33,118},{__jisx0213_2_emp_decmap+1101,50,125},{
+__jisx0213_2_emp_decmap+1177,34,121},{__jisx0213_2_emp_decmap+1265,53,115},{
+__jisx0213_2_emp_decmap+1328,68,126},{__jisx0213_2_emp_decmap+1387,33,115},{
+__jisx0213_2_emp_decmap+1470,41,122},{__jisx0213_2_emp_decmap+1552,37,126},{
+__jisx0213_2_emp_decmap+1642,33,126},{__jisx0213_2_emp_decmap+1736,33,113},{
+__jisx0213_2_emp_decmap+1817,34,118},{__jisx0213_2_emp_decmap+1902,44,112},{
+__jisx0213_2_emp_decmap+1971,37,118},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
+};
+
+static const DBCHAR __jisx0213_emp_encmap[8787] = {
+11810,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,41249,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+41259,N,41262,41270,41286,41328,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,41337,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41335,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41762,41765,41767,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,41777,41778,41784,41791,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41793,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,41802,41810,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,41811,41817,41820,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,20308,41847,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42026,42042,N,N,N,
+N,N,N,N,N,42034,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,42033,42045,42073,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+12098,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42076,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42083,N,N,N,N,N,N,42078,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,42091,N,N,N,N,N,N,N,N,N,N,N,N,42090,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,42098,12108,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,42100,N,N,N,N,N,N,N,N,N,N,N,N,N,42101,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42277,42290,
+12128,42302,42311,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+20323,42325,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42326,12155,42366,43056,
+43063,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43064,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43067,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,43066,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43077,N,N,N,N,N,
+N,N,N,N,43072,N,N,N,N,43071,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43080,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+43082,43083,20334,43099,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43110,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+43116,44066,65107,44075,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+44080,44112,44133,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,44141,44146,44324,44338,N,N,N,N,N,N,N,N,44329,44330,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,44341,44340,N,N,N,N,N,N,44345,44374,44580,N,N,N,N,N,N,N,N,N,N,N,N,
+44413,30010,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44579,44602,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44610,
+N,44605,44604,N,44612,N,N,N,N,44615,N,N,N,N,44617,N,N,N,N,44611,44629,44631,N,
+N,N,N,N,44630,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44635,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+44663,44664,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44842,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30066,
+44866,44863,44867,N,N,N,N,N,N,N,N,N,N,N,N,44864,44889,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,44878,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,30249,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+30258,44897,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44906,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,44905,44912,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44917,
+60963,60980,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30304,61001,N,N,N,N,N,N,N,N,N,N,N,N,N,62581,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,61020,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,61024,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,61023,61022,61234,61255,61261,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61281,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61284,
+61474,61491,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,61497,30572,61523,61563,61742,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,61744,61749,61764,61789,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61793,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+61798,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61801,
+61813,N,N,N,N,N,N,N,N,N,N,61815,61818,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61985,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61988,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61987,61992,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61996,
+62013,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30846,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62024,31017,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62043,31047,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,62069,N,N,N,N,N,N,N,N,N,N,62070,31060,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+62258,62270,62269,N,N,N,N,N,N,N,N,N,N,N,N,62272,62290,62301,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62302,31086,62323,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62324,N,N,N,N,N,N,N,N,N,N,N,
+62327,N,N,62325,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62333,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,62331,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62498,62500,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,62503,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,62511,N,N,N,N,N,N,N,N,N,N,N,62510,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62517,62516,N,N,N,N,N,N,N,N,N,N,62525,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62530,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62543,62569,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,62571,62578,62585,62773,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62778,62790,62806,N,N,
+N,N,N,N,N,N,N,N,N,N,62808,62810,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,62813,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,62815,62819,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62826,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,62832,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,62835,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,31325,42308,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,63044,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63054,
+31539,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+63069,63093,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63265,63266,63102,31561,
+63283,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,63286,63333,63332,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,63339,63342,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63347,
+63530,63529,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63532,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,31596,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63540,63548,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,63550,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63554,63574,63587,63607,N,N,N,N,N,N,N,N,N,N,
+63609,N,N,N,N,N,N,N,N,63610,63781,63791,63794,63801,63810,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+63816,31817,N,N,N,N,N,N,N,N,N,N,63833,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,63838,31825,63846,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63851,63866,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+63870,64033,64044,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,64047,64080,N,N,64079,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,64087,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+64101,64102,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64113,64114,64126,N,N,N,N,N,N,N,N,N,N,64289,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64301,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64300,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64310,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,64311,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64318,N,N,N,N,N,N,
+64317,64334,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,64335,64343,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64346,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64348,64349,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,64353,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64357,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+64359,64361,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,64369,64546,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64547,64568,64578,
+64588,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+64598,64601,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64605,64630,64812,64843,64857,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64844,
+N,N,N,N,N,N,N,N,N,N,N,64861,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+64859,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64871,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,64880,N,N,N,N,N,N,N,N,N,N,N,N,N,64877,65061,65067,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,65065,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65077,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65074,32358,65112,65114,65134,
+65136,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65138,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65142,
+};
+
+static const struct unim_index jisx0213_emp_encmap[256] = {
+{__jisx0213_emp_encmap+0,11,164},{__jisx0213_emp_encmap+154,162,162},{
+__jisx0213_emp_encmap+155,19,19},{__jisx0213_emp_encmap+156,43,249},{
+__jisx0213_emp_encmap+363,74,74},{__jisx0213_emp_encmap+364,9,214},{
+__jisx0213_emp_encmap+570,40,40},{__jisx0213_emp_encmap+571,79,79},{
+__jisx0213_emp_encmap+572,7,185},{__jisx0213_emp_encmap+751,124,157},{
+__jisx0213_emp_encmap+785,211,211},{__jisx0213_emp_encmap+786,29,159},{0,0,0},
+{__jisx0213_emp_encmap+917,69,225},{__jisx0213_emp_encmap+1074,100,149},{
+__jisx0213_emp_encmap+1124,95,95},{0,0,0},{0,0,0},{__jisx0213_emp_encmap+1125,
+1,253},{__jisx0213_emp_encmap+1378,27,196},{__jisx0213_emp_encmap+1548,109,110
+},{__jisx0213_emp_encmap+1550,215,215},{__jisx0213_emp_encmap+1551,71,180},{
+__jisx0213_emp_encmap+1661,6,66},{__jisx0213_emp_encmap+1722,189,189},{
+__jisx0213_emp_encmap+1723,195,195},{0,0,0},{0,0,0},{__jisx0213_emp_encmap+
+1724,86,86},{__jisx0213_emp_encmap+1725,45,224},{__jisx0213_emp_encmap+1905,
+51,52},{__jisx0213_emp_encmap+1907,30,250},{0,0,0},{__jisx0213_emp_encmap+2128
+,123,123},{__jisx0213_emp_encmap+2129,24,24},{__jisx0213_emp_encmap+2130,30,
+173},{0,0,0},{0,0,0},{__jisx0213_emp_encmap+2274,243,243},{0,0,0},{
+__jisx0213_emp_encmap+2275,91,171},{__jisx0213_emp_encmap+2356,143,143},{
+__jisx0213_emp_encmap+2357,184,184},{__jisx0213_emp_encmap+2358,70,166},{
+__jisx0213_emp_encmap+2455,29,36},{__jisx0213_emp_encmap+2463,225,225},{0,0,0
+},{0,0,0},{0,0,0},{__jisx0213_emp_encmap+2464,182,245},{0,0,0},{
+__jisx0213_emp_encmap+2528,114,228},{__jisx0213_emp_encmap+2643,74,228},{
+__jisx0213_emp_encmap+2798,90,196},{__jisx0213_emp_encmap+2905,56,71},{
+__jisx0213_emp_encmap+2921,12,255},{__jisx0213_emp_encmap+3165,36,61},{0,0,0},
+{__jisx0213_emp_encmap+3191,152,152},{0,0,0},{__jisx0213_emp_encmap+3192,127,
+254},{__jisx0213_emp_encmap+3320,0,250},{0,0,0},{__jisx0213_emp_encmap+3571,
+126,126},{__jisx0213_emp_encmap+3572,150,150},{__jisx0213_emp_encmap+3573,3,
+254},{0,0,0},{__jisx0213_emp_encmap+3825,188,188},{0,0,0},{0,0,0},{
+__jisx0213_emp_encmap+3826,41,165},{__jisx0213_emp_encmap+3951,241,241},{
+__jisx0213_emp_encmap+3952,150,150},{0,0,0},{__jisx0213_emp_encmap+3953,77,77
+},{__jisx0213_emp_encmap+3954,86,111},{__jisx0213_emp_encmap+3980,22,22},{
+__jisx0213_emp_encmap+3981,20,20},{__jisx0213_emp_encmap+3982,14,139},{0,0,0},
+{__jisx0213_emp_encmap+4108,74,85},{__jisx0213_emp_encmap+4120,34,229},{
+__jisx0213_emp_encmap+4316,30,76},{0,0,0},{__jisx0213_emp_encmap+4363,46,217},
+{__jisx0213_emp_encmap+4535,14,167},{0,0,0},{__jisx0213_emp_encmap+4689,113,
+180},{0,0,0},{__jisx0213_emp_encmap+4757,196,212},{__jisx0213_emp_encmap+4774,
+227,241},{__jisx0213_emp_encmap+4789,178,178},{__jisx0213_emp_encmap+4790,75,
+100},{__jisx0213_emp_encmap+4816,161,161},{__jisx0213_emp_encmap+4817,46,232},
+{__jisx0213_emp_encmap+5004,35,251},{__jisx0213_emp_encmap+5221,12,237},{0,0,0
+},{__jisx0213_emp_encmap+5447,112,134},{__jisx0213_emp_encmap+5470,76,76},{
+__jisx0213_emp_encmap+5471,2,2},{0,0,0},{__jisx0213_emp_encmap+5472,126,176},{
+__jisx0213_emp_encmap+5523,29,29},{__jisx0213_emp_encmap+5524,221,234},{
+__jisx0213_emp_encmap+5538,81,221},{__jisx0213_emp_encmap+5679,30,255},{0,0,0
+},{__jisx0213_emp_encmap+5905,41,221},{0,0,0},{__jisx0213_emp_encmap+6086,64,
+101},{__jisx0213_emp_encmap+6124,148,248},{__jisx0213_emp_encmap+6225,244,244
+},{__jisx0213_emp_encmap+6226,13,57},{0,0,0},{__jisx0213_emp_encmap+6271,218,
+254},{__jisx0213_emp_encmap+6308,16,73},{0,0,0},{__jisx0213_emp_encmap+6366,
+20,147},{__jisx0213_emp_encmap+6494,14,82},{0,0,0},{__jisx0213_emp_encmap+6563
+,133,133},{__jisx0213_emp_encmap+6564,132,132},{__jisx0213_emp_encmap+6565,
+179,199},{__jisx0213_emp_encmap+6586,184,184},{__jisx0213_emp_encmap+6587,160,
+160},{__jisx0213_emp_encmap+6588,16,16},{__jisx0213_emp_encmap+6589,183,183},{
+__jisx0213_emp_encmap+6590,138,187},{0,0,0},{__jisx0213_emp_encmap+6640,119,
+243},{__jisx0213_emp_encmap+6765,205,205},{__jisx0213_emp_encmap+6766,12,85},{
+__jisx0213_emp_encmap+6840,107,201},{__jisx0213_emp_encmap+6935,215,250},{0,0,
+0},{0,0,0},{__jisx0213_emp_encmap+6971,70,187},{__jisx0213_emp_encmap+7089,30,
+228},{__jisx0213_emp_encmap+7288,193,239},{0,0,0},{__jisx0213_emp_encmap+7335,
+16,251},{__jisx0213_emp_encmap+7571,31,235},{__jisx0213_emp_encmap+7776,50,248
+},{0,0,0},{0,0,0},{__jisx0213_emp_encmap+7975,160,177},{0,0,0},{
+__jisx0213_emp_encmap+7993,144,144},{__jisx0213_emp_encmap+7994,207,207},{
+__jisx0213_emp_encmap+7995,127,240},{__jisx0213_emp_encmap+8109,25,80},{
+__jisx0213_emp_encmap+8165,198,198},{0,0,0},{__jisx0213_emp_encmap+8166,114,
+114},{0,0,0},{0,0,0},{__jisx0213_emp_encmap+8167,219,219},{
+__jisx0213_emp_encmap+8168,21,233},{__jisx0213_emp_encmap+8381,206,206},{
+__jisx0213_emp_encmap+8382,26,249},{__jisx0213_emp_encmap+8606,144,144},{0,0,0
+},{__jisx0213_emp_encmap+8607,140,140},{__jisx0213_emp_encmap+8608,55,55},{
+__jisx0213_emp_encmap+8609,241,241},{__jisx0213_emp_encmap+8610,2,178},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},
+};
+

Added: vendor/Python/current/Modules/cjkcodecs/mappings_kr.h
===================================================================
--- vendor/Python/current/Modules/cjkcodecs/mappings_kr.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/cjkcodecs/mappings_kr.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,3251 @@
+static const ucs2_t __ksx1001_decmap[8264] = {
+12288,12289,12290,183,8229,8230,168,12291,173,8213,8741,65340,8764,8216,8217,
+8220,8221,12308,12309,12296,12297,12298,12299,12300,12301,12302,12303,12304,
+12305,177,215,247,8800,8804,8805,8734,8756,176,8242,8243,8451,8491,65504,
+65505,65509,9794,9792,8736,8869,8978,8706,8711,8801,8786,167,8251,9734,9733,
+9675,9679,9678,9671,9670,9633,9632,9651,9650,9661,9660,8594,8592,8593,8595,
+8596,12307,8810,8811,8730,8765,8733,8757,8747,8748,8712,8715,8838,8839,8834,
+8835,8746,8745,8743,8744,65506,8658,8660,8704,8707,180,65374,711,728,733,730,
+729,184,731,161,191,720,8750,8721,8719,164,8457,8240,9665,9664,9655,9654,9828,
+9824,9825,9829,9831,9827,8857,9672,9635,9680,9681,9618,9636,9637,9640,9639,
+9638,9641,9832,9743,9742,9756,9758,182,8224,8225,8597,8599,8601,8598,8600,
+9837,9833,9834,9836,12927,12828,8470,13255,8482,13250,13272,8481,8364,174,
+65281,65282,65283,65284,65285,65286,65287,65288,65289,65290,65291,65292,65293,
+65294,65295,65296,65297,65298,65299,65300,65301,65302,65303,65304,65305,65306,
+65307,65308,65309,65310,65311,65312,65313,65314,65315,65316,65317,65318,65319,
+65320,65321,65322,65323,65324,65325,65326,65327,65328,65329,65330,65331,65332,
+65333,65334,65335,65336,65337,65338,65339,65510,65341,65342,65343,65344,65345,
+65346,65347,65348,65349,65350,65351,65352,65353,65354,65355,65356,65357,65358,
+65359,65360,65361,65362,65363,65364,65365,65366,65367,65368,65369,65370,65371,
+65372,65373,65507,12593,12594,12595,12596,12597,12598,12599,12600,12601,12602,
+12603,12604,12605,12606,12607,12608,12609,12610,12611,12612,12613,12614,12615,
+12616,12617,12618,12619,12620,12621,12622,12623,12624,12625,12626,12627,12628,
+12629,12630,12631,12632,12633,12634,12635,12636,12637,12638,12639,12640,12641,
+12642,12643,12644,12645,12646,12647,12648,12649,12650,12651,12652,12653,12654,
+12655,12656,12657,12658,12659,12660,12661,12662,12663,12664,12665,12666,12667,
+12668,12669,12670,12671,12672,12673,12674,12675,12676,12677,12678,12679,12680,
+12681,12682,12683,12684,12685,12686,8560,8561,8562,8563,8564,8565,8566,8567,
+8568,8569,U,U,U,U,U,8544,8545,8546,8547,8548,8549,8550,8551,8552,8553,U,U,U,U,
+U,U,U,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,931,
+932,933,934,935,936,937,U,U,U,U,U,U,U,U,945,946,947,948,949,950,951,952,953,
+954,955,956,957,958,959,960,961,963,964,965,966,967,968,969,9472,9474,9484,
+9488,9496,9492,9500,9516,9508,9524,9532,9473,9475,9487,9491,9499,9495,9507,
+9523,9515,9531,9547,9504,9519,9512,9527,9535,9501,9520,9509,9528,9538,9490,
+9489,9498,9497,9494,9493,9486,9485,9502,9503,9505,9506,9510,9511,9513,9514,
+9517,9518,9521,9522,9525,9526,9529,9530,9533,9534,9536,9537,9539,9540,9541,
+9542,9543,9544,9545,9546,13205,13206,13207,8467,13208,13252,13219,13220,13221,
+13222,13209,13210,13211,13212,13213,13214,13215,13216,13217,13218,13258,13197,
+13198,13199,13263,13192,13193,13256,13223,13224,13232,13233,13234,13235,13236,
+13237,13238,13239,13240,13241,13184,13185,13186,13187,13188,13242,13243,13244,
+13245,13246,13247,13200,13201,13202,13203,13204,8486,13248,13249,13194,13195,
+13196,13270,13253,13229,13230,13231,13275,13225,13226,13227,13228,13277,13264,
+13267,13251,13257,13276,13254,198,208,170,294,U,306,U,319,321,216,338,186,222,
+358,330,U,12896,12897,12898,12899,12900,12901,12902,12903,12904,12905,12906,
+12907,12908,12909,12910,12911,12912,12913,12914,12915,12916,12917,12918,12919,
+12920,12921,12922,12923,9424,9425,9426,9427,9428,9429,9430,9431,9432,9433,
+9434,9435,9436,9437,9438,9439,9440,9441,9442,9443,9444,9445,9446,9447,9448,
+9449,9312,9313,9314,9315,9316,9317,9318,9319,9320,9321,9322,9323,9324,9325,
+9326,189,8531,8532,188,190,8539,8540,8541,8542,230,273,240,295,305,307,312,
+320,322,248,339,223,254,359,331,329,12800,12801,12802,12803,12804,12805,12806,
+12807,12808,12809,12810,12811,12812,12813,12814,12815,12816,12817,12818,12819,
+12820,12821,12822,12823,12824,12825,12826,12827,9372,9373,9374,9375,9376,9377,
+9378,9379,9380,9381,9382,9383,9384,9385,9386,9387,9388,9389,9390,9391,9392,
+9393,9394,9395,9396,9397,9332,9333,9334,9335,9336,9337,9338,9339,9340,9341,
+9342,9343,9344,9345,9346,185,178,179,8308,8319,8321,8322,8323,8324,12353,
+12354,12355,12356,12357,12358,12359,12360,12361,12362,12363,12364,12365,12366,
+12367,12368,12369,12370,12371,12372,12373,12374,12375,12376,12377,12378,12379,
+12380,12381,12382,12383,12384,12385,12386,12387,12388,12389,12390,12391,12392,
+12393,12394,12395,12396,12397,12398,12399,12400,12401,12402,12403,12404,12405,
+12406,12407,12408,12409,12410,12411,12412,12413,12414,12415,12416,12417,12418,
+12419,12420,12421,12422,12423,12424,12425,12426,12427,12428,12429,12430,12431,
+12432,12433,12434,12435,12449,12450,12451,12452,12453,12454,12455,12456,12457,
+12458,12459,12460,12461,12462,12463,12464,12465,12466,12467,12468,12469,12470,
+12471,12472,12473,12474,12475,12476,12477,12478,12479,12480,12481,12482,12483,
+12484,12485,12486,12487,12488,12489,12490,12491,12492,12493,12494,12495,12496,
+12497,12498,12499,12500,12501,12502,12503,12504,12505,12506,12507,12508,12509,
+12510,12511,12512,12513,12514,12515,12516,12517,12518,12519,12520,12521,12522,
+12523,12524,12525,12526,12527,12528,12529,12530,12531,12532,12533,12534,1040,
+1041,1042,1043,1044,1045,1025,1046,1047,1048,1049,1050,1051,1052,1053,1054,
+1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,
+1070,1071,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,1072,1073,1074,1075,1076,1077,1105,
+1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,
+1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,44032,44033,44036,
+44039,44040,44041,44042,44048,44049,44050,44051,44052,44053,44054,44055,44057,
+44058,44059,44060,44061,44064,44068,44076,44077,44079,44080,44081,44088,44089,
+44092,44096,44107,44109,44116,44120,44124,44144,44145,44148,44151,44152,44154,
+44160,44161,44163,44164,44165,44166,44169,44170,44171,44172,44176,44180,44188,
+44189,44191,44192,44193,44200,44201,44202,44204,44207,44208,44216,44217,44219,
+44220,44221,44225,44228,44232,44236,44245,44247,44256,44257,44260,44263,44264,
+44266,44268,44271,44272,44273,44275,44277,44278,44284,44285,44288,44292,44294,
+44300,44301,44303,44305,44312,44316,44320,44329,44332,44333,44340,44341,44344,
+44348,44356,44357,44359,44361,44368,44372,44376,44385,44387,44396,44397,44400,
+44403,44404,44405,44406,44411,44412,44413,44415,44417,44418,44424,44425,44428,
+44432,44444,44445,44452,44471,44480,44481,44484,44488,44496,44497,44499,44508,
+44512,44516,44536,44537,44540,44543,44544,44545,44552,44553,44555,44557,44564,
+44592,44593,44596,44599,44600,44602,44608,44609,44611,44613,44614,44618,44620,
+44621,44622,44624,44628,44630,44636,44637,44639,44640,44641,44645,44648,44649,
+44652,44656,44664,44665,44667,44668,44669,44676,44677,44684,44732,44733,44734,
+44736,44740,44748,44749,44751,44752,44753,44760,44761,44764,44776,44779,44781,
+44788,44792,44796,44807,44808,44813,44816,44844,44845,44848,44850,44852,44860,
+44861,44863,44865,44866,44867,44872,44873,44880,44892,44893,44900,44901,44921,
+44928,44932,44936,44944,44945,44949,44956,44984,44985,44988,44992,44999,45000,
+45001,45003,45005,45006,45012,45020,45032,45033,45040,45041,45044,45048,45056,
+45057,45060,45068,45072,45076,45084,45085,45096,45124,45125,45128,45130,45132,
+45134,45139,45140,45141,45143,45145,45149,45180,45181,45184,45188,45196,45197,
+45199,45201,45208,45209,45210,45212,45215,45216,45217,45218,45224,45225,45227,
+45228,45229,45230,45231,45233,45235,45236,45237,45240,45244,45252,45253,45255,
+45256,45257,45264,45265,45268,45272,45280,45285,45320,45321,45323,45324,45328,
+45330,45331,45336,45337,45339,45340,45341,45347,45348,45349,45352,45356,45364,
+45365,45367,45368,45369,45376,45377,45380,45384,45392,45393,45396,45397,45400,
+45404,45408,45432,45433,45436,45440,45442,45448,45449,45451,45453,45458,45459,
+45460,45464,45468,45480,45516,45520,45524,45532,45533,45535,45544,45545,45548,
+45552,45561,45563,45565,45572,45573,45576,45579,45580,45588,45589,45591,45593,
+45600,45620,45628,45656,45660,45664,45672,45673,45684,45685,45692,45700,45701,
+45705,45712,45713,45716,45720,45721,45722,45728,45729,45731,45733,45734,45738,
+45740,45744,45748,45768,45769,45772,45776,45778,45784,45785,45787,45789,45794,
+45796,45797,45798,45800,45803,45804,45805,45806,45807,45811,45812,45813,45815,
+45816,45817,45818,45819,45823,45824,45825,45828,45832,45840,45841,45843,45844,
+45845,45852,45908,45909,45910,45912,45915,45916,45918,45919,45924,45925,45927,
+45929,45931,45934,45936,45937,45940,45944,45952,45953,45955,45956,45957,45964,
+45968,45972,45984,45985,45992,45996,46020,46021,46024,46027,46028,46030,46032,
+46036,46037,46039,46041,46043,46045,46048,46052,46056,46076,46096,46104,46108,
+46112,46120,46121,46123,46132,46160,46161,46164,46168,46176,46177,46179,46181,
+46188,46208,46216,46237,46244,46248,46252,46261,46263,46265,46272,46276,46280,
+46288,46293,46300,46301,46304,46307,46308,46310,46316,46317,46319,46321,46328,
+46356,46357,46360,46363,46364,46372,46373,46375,46376,46377,46378,46384,46385,
+46388,46392,46400,46401,46403,46404,46405,46411,46412,46413,46416,46420,46428,
+46429,46431,46432,46433,46496,46497,46500,46504,46506,46507,46512,46513,46515,
+46516,46517,46523,46524,46525,46528,46532,46540,46541,46543,46544,46545,46552,
+46572,46608,46609,46612,46616,46629,46636,46644,46664,46692,46696,46748,46749,
+46752,46756,46763,46764,46769,46804,46832,46836,46840,46848,46849,46853,46888,
+46889,46892,46895,46896,46904,46905,46907,46916,46920,46924,46932,46933,46944,
+46948,46952,46960,46961,46963,46965,46972,46973,46976,46980,46988,46989,46991,
+46992,46993,46994,46998,46999,47000,47001,47004,47008,47016,47017,47019,47020,
+47021,47028,47029,47032,47047,47049,47084,47085,47088,47092,47100,47101,47103,
+47104,47105,47111,47112,47113,47116,47120,47128,47129,47131,47133,47140,47141,
+47144,47148,47156,47157,47159,47160,47161,47168,47172,47185,47187,47196,47197,
+47200,47204,47212,47213,47215,47217,47224,47228,47245,47272,47280,47284,47288,
+47296,47297,47299,47301,47308,47312,47316,47325,47327,47329,47336,47337,47340,
+47344,47352,47353,47355,47357,47364,47384,47392,47420,47421,47424,47428,47436,
+47439,47441,47448,47449,47452,47456,47464,47465,47467,47469,47476,47477,47480,
+47484,47492,47493,47495,47497,47498,47501,47502,47532,47533,47536,47540,47548,
+47549,47551,47553,47560,47561,47564,47566,47567,47568,47569,47570,47576,47577,
+47579,47581,47582,47585,47587,47588,47589,47592,47596,47604,47605,47607,47608,
+47609,47610,47616,47617,47624,47637,47672,47673,47676,47680,47682,47688,47689,
+47691,47693,47694,47699,47700,47701,47704,47708,47716,47717,47719,47720,47721,
+47728,47729,47732,47736,47747,47748,47749,47751,47756,47784,47785,47787,47788,
+47792,47794,47800,47801,47803,47805,47812,47816,47832,47833,47868,47872,47876,
+47885,47887,47889,47896,47900,47904,47913,47915,47924,47925,47926,47928,47931,
+47932,47933,47934,47940,47941,47943,47945,47949,47951,47952,47956,47960,47969,
+47971,47980,48008,48012,48016,48036,48040,48044,48052,48055,48064,48068,48072,
+48080,48083,48120,48121,48124,48127,48128,48130,48136,48137,48139,48140,48141,
+48143,48145,48148,48149,48150,48151,48152,48155,48156,48157,48158,48159,48164,
+48165,48167,48169,48173,48176,48177,48180,48184,48192,48193,48195,48196,48197,
+48201,48204,48205,48208,48221,48260,48261,48264,48267,48268,48270,48276,48277,
+48279,48281,48282,48288,48289,48292,48295,48296,48304,48305,48307,48308,48309,
+48316,48317,48320,48324,48333,48335,48336,48337,48341,48344,48348,48372,48373,
+48374,48376,48380,48388,48389,48391,48393,48400,48404,48420,48428,48448,48456,
+48457,48460,48464,48472,48473,48484,48488,48512,48513,48516,48519,48520,48521,
+48522,48528,48529,48531,48533,48537,48538,48540,48548,48560,48568,48596,48597,
+48600,48604,48617,48624,48628,48632,48640,48643,48645,48652,48653,48656,48660,
+48668,48669,48671,48708,48709,48712,48716,48718,48724,48725,48727,48729,48730,
+48731,48736,48737,48740,48744,48746,48752,48753,48755,48756,48757,48763,48764,
+48765,48768,48772,48780,48781,48783,48784,48785,48792,48793,48808,48848,48849,
+48852,48855,48856,48864,48867,48868,48869,48876,48897,48904,48905,48920,48921,
+48923,48924,48925,48960,48961,48964,48968,48976,48977,48981,49044,49072,49093,
+49100,49101,49104,49108,49116,49119,49121,49212,49233,49240,49244,49248,49256,
+49257,49296,49297,49300,49304,49312,49313,49315,49317,49324,49325,49327,49328,
+49331,49332,49333,49334,49340,49341,49343,49344,49345,49349,49352,49353,49356,
+49360,49368,49369,49371,49372,49373,49380,49381,49384,49388,49396,49397,49399,
+49401,49408,49412,49416,49424,49429,49436,49437,49438,49439,49440,49443,49444,
+49446,49447,49452,49453,49455,49456,49457,49462,49464,49465,49468,49472,49480,
+49481,49483,49484,49485,49492,49493,49496,49500,49508,49509,49511,49512,49513,
+49520,49524,49528,49541,49548,49549,49550,49552,49556,49558,49564,49565,49567,
+49569,49573,49576,49577,49580,49584,49597,49604,49608,49612,49620,49623,49624,
+49632,49636,49640,49648,49649,49651,49660,49661,49664,49668,49676,49677,49679,
+49681,49688,49689,49692,49695,49696,49704,49705,49707,49709,49711,49713,49714,
+49716,49736,49744,49745,49748,49752,49760,49765,49772,49773,49776,49780,49788,
+49789,49791,49793,49800,49801,49808,49816,49819,49821,49828,49829,49832,49836,
+49837,49844,49845,49847,49849,49884,49885,49888,49891,49892,49899,49900,49901,
+49903,49905,49910,49912,49913,49915,49916,49920,49928,49929,49932,49933,49939,
+49940,49941,49944,49948,49956,49957,49960,49961,49989,50024,50025,50028,50032,
+50034,50040,50041,50044,50045,50052,50056,50060,50112,50136,50137,50140,50143,
+50144,50146,50152,50153,50157,50164,50165,50168,50184,50192,50212,50220,50224,
+50228,50236,50237,50248,50276,50277,50280,50284,50292,50293,50297,50304,50324,
+50332,50360,50364,50409,50416,50417,50420,50424,50426,50431,50432,50433,50444,
+50448,50452,50460,50472,50473,50476,50480,50488,50489,50491,50493,50500,50501,
+50504,50505,50506,50508,50509,50510,50515,50516,50517,50519,50520,50521,50525,
+50526,50528,50529,50532,50536,50544,50545,50547,50548,50549,50556,50557,50560,
+50564,50567,50572,50573,50575,50577,50581,50583,50584,50588,50592,50601,50612,
+50613,50616,50617,50619,50620,50621,50622,50628,50629,50630,50631,50632,50633,
+50634,50636,50638,50640,50641,50644,50648,50656,50657,50659,50661,50668,50669,
+50670,50672,50676,50678,50679,50684,50685,50686,50687,50688,50689,50693,50694,
+50695,50696,50700,50704,50712,50713,50715,50716,50724,50725,50728,50732,50733,
+50734,50736,50739,50740,50741,50743,50745,50747,50752,50753,50756,50760,50768,
+50769,50771,50772,50773,50780,50781,50784,50796,50799,50801,50808,50809,50812,
+50816,50824,50825,50827,50829,50836,50837,50840,50844,50852,50853,50855,50857,
+50864,50865,50868,50872,50873,50874,50880,50881,50883,50885,50892,50893,50896,
+50900,50908,50909,50912,50913,50920,50921,50924,50928,50936,50937,50941,50948,
+50949,50952,50956,50964,50965,50967,50969,50976,50977,50980,50984,50992,50993,
+50995,50997,50999,51004,51005,51008,51012,51018,51020,51021,51023,51025,51026,
+51027,51028,51029,51030,51031,51032,51036,51040,51048,51051,51060,51061,51064,
+51068,51069,51070,51075,51076,51077,51079,51080,51081,51082,51086,51088,51089,
+51092,51094,51095,51096,51098,51104,51105,51107,51108,51109,51110,51116,51117,
+51120,51124,51132,51133,51135,51136,51137,51144,51145,51148,51150,51152,51160,
+51165,51172,51176,51180,51200,51201,51204,51208,51210,51216,51217,51219,51221,
+51222,51228,51229,51232,51236,51244,51245,51247,51249,51256,51260,51264,51272,
+51273,51276,51277,51284,51312,51313,51316,51320,51322,51328,51329,51331,51333,
+51334,51335,51339,51340,51341,51348,51357,51359,51361,51368,51388,51389,51396,
+51400,51404,51412,51413,51415,51417,51424,51425,51428,51445,51452,51453,51456,
+51460,51461,51462,51468,51469,51471,51473,51480,51500,51508,51536,51537,51540,
+51544,51552,51553,51555,51564,51568,51572,51580,51592,51593,51596,51600,51608,
+51609,51611,51613,51648,51649,51652,51655,51656,51658,51664,51665,51667,51669,
+51670,51673,51674,51676,51677,51680,51682,51684,51687,51692,51693,51695,51696,
+51697,51704,51705,51708,51712,51720,51721,51723,51724,51725,51732,51736,51753,
+51788,51789,51792,51796,51804,51805,51807,51808,51809,51816,51837,51844,51864,
+51900,51901,51904,51908,51916,51917,51919,51921,51923,51928,51929,51936,51948,
+51956,51976,51984,51988,51992,52000,52001,52033,52040,52041,52044,52048,52056,
+52057,52061,52068,52088,52089,52124,52152,52180,52196,52199,52201,52236,52237,
+52240,52244,52252,52253,52257,52258,52263,52264,52265,52268,52270,52272,52280,
+52281,52283,52284,52285,52286,52292,52293,52296,52300,52308,52309,52311,52312,
+52313,52320,52324,52326,52328,52336,52341,52376,52377,52380,52384,52392,52393,
+52395,52396,52397,52404,52405,52408,52412,52420,52421,52423,52425,52432,52436,
+52452,52460,52464,52481,52488,52489,52492,52496,52504,52505,52507,52509,52516,
+52520,52524,52537,52572,52576,52580,52588,52589,52591,52593,52600,52616,52628,
+52629,52632,52636,52644,52645,52647,52649,52656,52676,52684,52688,52712,52716,
+52720,52728,52729,52731,52733,52740,52744,52748,52756,52761,52768,52769,52772,
+52776,52784,52785,52787,52789,52824,52825,52828,52831,52832,52833,52840,52841,
+52843,52845,52852,52853,52856,52860,52868,52869,52871,52873,52880,52881,52884,
+52888,52896,52897,52899,52900,52901,52908,52909,52929,52964,52965,52968,52971,
+52972,52980,52981,52983,52984,52985,52992,52993,52996,53000,53008,53009,53011,
+53013,53020,53024,53028,53036,53037,53039,53040,53041,53048,53076,53077,53080,
+53084,53092,53093,53095,53097,53104,53105,53108,53112,53120,53125,53132,53153,
+53160,53168,53188,53216,53217,53220,53224,53232,53233,53235,53237,53244,53248,
+53252,53265,53272,53293,53300,53301,53304,53308,53316,53317,53319,53321,53328,
+53332,53336,53344,53356,53357,53360,53364,53372,53373,53377,53412,53413,53416,
+53420,53428,53429,53431,53433,53440,53441,53444,53448,53449,53456,53457,53459,
+53460,53461,53468,53469,53472,53476,53484,53485,53487,53488,53489,53496,53517,
+53552,53553,53556,53560,53562,53568,53569,53571,53572,53573,53580,53581,53584,
+53588,53596,53597,53599,53601,53608,53612,53628,53636,53640,53664,53665,53668,
+53672,53680,53681,53683,53685,53690,53692,53696,53720,53748,53752,53767,53769,
+53776,53804,53805,53808,53812,53820,53821,53823,53825,53832,53852,53860,53888,
+53889,53892,53896,53904,53905,53909,53916,53920,53924,53932,53937,53944,53945,
+53948,53951,53952,53954,53960,53961,53963,53972,53976,53980,53988,53989,54000,
+54001,54004,54008,54016,54017,54019,54021,54028,54029,54030,54032,54036,54038,
+54044,54045,54047,54048,54049,54053,54056,54057,54060,54064,54072,54073,54075,
+54076,54077,54084,54085,54140,54141,54144,54148,54156,54157,54159,54160,54161,
+54168,54169,54172,54176,54184,54185,54187,54189,54196,54200,54204,54212,54213,
+54216,54217,54224,54232,54241,54243,54252,54253,54256,54260,54268,54269,54271,
+54273,54280,54301,54336,54340,54364,54368,54372,54381,54383,54392,54393,54396,
+54399,54400,54402,54408,54409,54411,54413,54420,54441,54476,54480,54484,54492,
+54495,54504,54508,54512,54520,54523,54525,54532,54536,54540,54548,54549,54551,
+54588,54589,54592,54596,54604,54605,54607,54609,54616,54617,54620,54624,54629,
+54632,54633,54635,54637,54644,54645,54648,54652,54660,54661,54663,54664,54665,
+54672,54693,54728,54729,54732,54736,54738,54744,54745,54747,54749,54756,54757,
+54760,54764,54772,54773,54775,54777,54784,54785,54788,54792,54800,54801,54803,
+54804,54805,54812,54816,54820,54829,54840,54841,54844,54848,54853,54856,54857,
+54859,54861,54865,54868,54869,54872,54876,54887,54889,54896,54897,54900,54915,
+54917,54924,54925,54928,54932,54941,54943,54945,54952,54956,54960,54969,54971,
+54980,54981,54984,54988,54993,54996,54999,55001,55008,55012,55016,55024,55029,
+55036,55037,55040,55044,55057,55064,55065,55068,55072,55080,55081,55083,55085,
+55092,55093,55096,55100,55108,55111,55113,55120,55121,55124,55126,55127,55128,
+55129,55136,55137,55139,55141,55145,55148,55152,55156,55164,55165,55169,55176,
+55177,55180,55184,55192,55193,55195,55197,20285,20339,20551,20729,21152,21487,
+21621,21733,22025,23233,23478,26247,26550,26551,26607,27468,29634,30146,31292,
+33499,33540,34903,34952,35382,36040,36303,36603,36838,39381,21051,21364,21508,
+24682,24932,27580,29647,33050,35258,35282,38307,20355,21002,22718,22904,23014,
+24178,24185,25031,25536,26438,26604,26751,28567,30286,30475,30965,31240,31487,
+31777,32925,33390,33393,35563,38291,20075,21917,26359,28212,30883,31469,33883,
+35088,34638,38824,21208,22350,22570,23884,24863,25022,25121,25954,26577,27204,
+28187,29976,30131,30435,30640,32058,37039,37969,37970,40853,21283,23724,30002,
+32987,37440,38296,21083,22536,23004,23713,23831,24247,24378,24394,24951,27743,
+30074,30086,31968,32115,32177,32652,33108,33313,34193,35137,35611,37628,38477,
+40007,20171,20215,20491,20977,22607,24887,24894,24936,25913,27114,28433,30117,
+30342,30422,31623,33445,33995,63744,37799,38283,21888,23458,22353,63745,31923,
+32697,37301,20520,21435,23621,24040,25298,25454,25818,25831,28192,28844,31067,
+36317,36382,63746,36989,37445,37624,20094,20214,20581,24062,24314,24838,26967,
+33137,34388,36423,37749,39467,20062,20625,26480,26688,20745,21133,21138,27298,
+30652,37392,40660,21163,24623,36850,20552,25001,25581,25802,26684,27268,28608,
+33160,35233,38548,22533,29309,29356,29956,32121,32365,32937,35211,35700,36963,
+40273,25225,27770,28500,32080,32570,35363,20860,24906,31645,35609,37463,37772,
+20140,20435,20510,20670,20742,21185,21197,21375,22384,22659,24218,24465,24950,
+25004,25806,25964,26223,26299,26356,26775,28039,28805,28913,29855,29861,29898,
+30169,30828,30956,31455,31478,32069,32147,32789,32831,33051,33686,35686,36629,
+36885,37857,38915,38968,39514,39912,20418,21843,22586,22865,23395,23622,24760,
+25106,26690,26800,26856,28330,30028,30328,30926,31293,31995,32363,32380,35336,
+35489,35903,38542,40388,21476,21481,21578,21617,22266,22993,23396,23611,24235,
+25335,25911,25925,25970,26272,26543,27073,27837,30204,30352,30590,31295,32660,
+32771,32929,33167,33510,33533,33776,34241,34865,34996,35493,63747,36764,37678,
+38599,39015,39640,40723,21741,26011,26354,26767,31296,35895,40288,22256,22372,
+23825,26118,26801,26829,28414,29736,34974,39908,27752,63748,39592,20379,20844,
+20849,21151,23380,24037,24656,24685,25329,25511,25915,29657,31354,34467,36002,
+38799,20018,23521,25096,26524,29916,31185,33747,35463,35506,36328,36942,37707,
+38982,24275,27112,34303,37101,63749,20896,23448,23532,24931,26874,27454,28748,
+29743,29912,31649,32592,33733,35264,36011,38364,39208,21038,24669,25324,36866,
+20362,20809,21281,22745,24291,26336,27960,28826,29378,29654,31568,33009,37979,
+21350,25499,32619,20054,20608,22602,22750,24618,24871,25296,27088,39745,23439,
+32024,32945,36703,20132,20689,21676,21932,23308,23968,24039,25898,25934,26657,
+27211,29409,30350,30703,32094,32761,33184,34126,34527,36611,36686,37066,39171,
+39509,39851,19992,20037,20061,20167,20465,20855,21246,21312,21475,21477,21646,
+22036,22389,22434,23495,23943,24272,25084,25304,25937,26552,26601,27083,27472,
+27590,27628,27714,28317,28792,29399,29590,29699,30655,30697,31350,32127,32777,
+33276,33285,33290,33503,34914,35635,36092,36544,36881,37041,37476,37558,39378,
+39493,40169,40407,40860,22283,23616,33738,38816,38827,40628,21531,31384,32676,
+35033,36557,37089,22528,23624,25496,31391,23470,24339,31353,31406,33422,36524,
+20518,21048,21240,21367,22280,25331,25458,27402,28099,30519,21413,29527,34152,
+36470,38357,26426,27331,28528,35437,36556,39243,63750,26231,27512,36020,39740,
+63751,21483,22317,22862,25542,27131,29674,30789,31418,31429,31998,33909,35215,
+36211,36917,38312,21243,22343,30023,31584,33740,37406,63752,27224,20811,21067,
+21127,25119,26840,26997,38553,20677,21156,21220,25027,26020,26681,27135,29822,
+31563,33465,33771,35250,35641,36817,39241,63753,20170,22935,25810,26129,27278,
+29748,31105,31165,33449,34942,34943,35167,63754,37670,20235,21450,24613,25201,
+27762,32026,32102,20120,20834,30684,32943,20225,20238,20854,20864,21980,22120,
+22331,22522,22524,22804,22855,22931,23492,23696,23822,24049,24190,24524,25216,
+26071,26083,26398,26399,26462,26827,26820,27231,27450,27683,27773,27778,28103,
+29592,29734,29738,29826,29859,30072,30079,30849,30959,31041,31047,31048,31098,
+31637,32000,32186,32648,32774,32813,32908,35352,35663,35912,36215,37665,37668,
+39138,39249,39438,39439,39525,40594,32202,20342,21513,25326,26708,37329,21931,
+20794,63755,63756,23068,25062,63757,25295,25343,63758,63759,63760,63761,63762,
+63763,37027,63764,63765,63766,63767,63768,35582,63769,63770,63771,63772,26262,
+63773,29014,63774,63775,38627,63776,25423,25466,21335,63777,26511,26976,28275,
+63778,30007,63779,63780,63781,32013,63782,63783,34930,22218,23064,63784,63785,
+63786,63787,63788,20035,63789,20839,22856,26608,32784,63790,22899,24180,25754,
+31178,24565,24684,25288,25467,23527,23511,21162,63791,22900,24361,24594,63792,
+63793,63794,29785,63795,63796,63797,63798,63799,63800,39377,63801,63802,63803,
+63804,63805,63806,63807,63808,63809,63810,63811,28611,63812,63813,33215,36786,
+24817,63814,63815,33126,63816,63817,23615,63818,63819,63820,63821,63822,63823,
+63824,63825,23273,35365,26491,32016,63826,63827,63828,63829,63830,63831,33021,
+63832,63833,23612,27877,21311,28346,22810,33590,20025,20150,20294,21934,22296,
+22727,24406,26039,26086,27264,27573,28237,30701,31471,31774,32222,34507,34962,
+37170,37723,25787,28606,29562,30136,36948,21846,22349,25018,25812,26311,28129,
+28251,28525,28601,30192,32835,33213,34113,35203,35527,35674,37663,27795,30035,
+31572,36367,36957,21776,22530,22616,24162,25095,25758,26848,30070,31958,34739,
+40680,20195,22408,22382,22823,23565,23729,24118,24453,25140,25825,29619,33274,
+34955,36024,38538,40667,23429,24503,24755,20498,20992,21040,22294,22581,22615,
+23566,23648,23798,23947,24230,24466,24764,25361,25481,25623,26691,26873,27330,
+28120,28193,28372,28644,29182,30428,30585,31153,31291,33796,35241,36077,36339,
+36424,36867,36884,36947,37117,37709,38518,38876,27602,28678,29272,29346,29544,
+30563,31167,31716,32411,35712,22697,24775,25958,26109,26302,27788,28958,29129,
+35930,38931,20077,31361,20189,20908,20941,21205,21516,24999,26481,26704,26847,
+27934,28540,30140,30643,31461,33012,33891,37509,20828,26007,26460,26515,30168,
+31431,33651,63834,35910,36887,38957,23663,33216,33434,36929,36975,37389,24471,
+23965,27225,29128,30331,31561,34276,35588,37159,39472,21895,25078,63835,30313,
+32645,34367,34746,35064,37007,63836,27931,28889,29662,32097,33853,63837,37226,
+39409,63838,20098,21365,27396,27410,28734,29211,34349,40478,21068,36771,23888,
+25829,25900,27414,28651,31811,32412,34253,35172,35261,25289,33240,34847,24266,
+26391,28010,29436,29701,29807,34690,37086,20358,23821,24480,33802,20919,25504,
+30053,20142,20486,20841,20937,26753,27153,31918,31921,31975,33391,35538,36635,
+37327,20406,20791,21237,21570,24300,24942,25150,26053,27354,28670,31018,34268,
+34851,38317,39522,39530,40599,40654,21147,26310,27511,28701,31019,36706,38722,
+24976,25088,25891,28451,29001,29833,32244,32879,34030,36646,36899,37706,20925,
+21015,21155,27916,28872,35010,24265,25986,27566,28610,31806,29557,20196,20278,
+22265,63839,23738,23994,24604,29618,31533,32666,32718,32838,36894,37428,38646,
+38728,38936,40801,20363,28583,31150,37300,38583,21214,63840,25736,25796,27347,
+28510,28696,29200,30439,32769,34310,34396,36335,36613,38706,39791,40442,40565,
+30860,31103,32160,33737,37636,40575,40595,35542,22751,24324,26407,28711,29903,
+31840,32894,20769,28712,29282,30922,36034,36058,36084,38647,20102,20698,23534,
+24278,26009,29134,30274,30637,32842,34044,36988,39719,40845,22744,23105,23650,
+27155,28122,28431,30267,32047,32311,34078,35128,37860,38475,21129,26066,26611,
+27060,27969,28316,28687,29705,29792,30041,30244,30827,35628,39006,20845,25134,
+38520,20374,20523,23833,28138,32184,36650,24459,24900,26647,63841,38534,21202,
+32907,20956,20940,26974,31260,32190,33777,38517,20442,21033,21400,21519,21774,
+23653,24743,26446,26792,28012,29313,29432,29702,29827,63842,30178,31852,32633,
+32696,33673,35023,35041,37324,37328,38626,39881,21533,28542,29136,29848,34298,
+36522,38563,40023,40607,26519,28107,29747,33256,38678,30764,31435,31520,31890,
+25705,29802,30194,30908,30952,39340,39764,40635,23518,24149,28448,33180,33707,
+37000,19975,21325,23081,24018,24398,24930,25405,26217,26364,28415,28459,28771,
+30622,33836,34067,34875,36627,39237,39995,21788,25273,26411,27819,33545,35178,
+38778,20129,22916,24536,24537,26395,32178,32596,33426,33579,33725,36638,37017,
+22475,22969,23186,23504,26151,26522,26757,27599,29028,32629,36023,36067,36993,
+39749,33032,35978,38476,39488,40613,23391,27667,29467,30450,30431,33804,20906,
+35219,20813,20885,21193,26825,27796,30468,30496,32191,32236,38754,40629,28357,
+34065,20901,21517,21629,26126,26269,26919,28319,30399,30609,33559,33986,34719,
+37225,37528,40180,34946,20398,20882,21215,22982,24125,24917,25720,25721,26286,
+26576,27169,27597,27611,29279,29281,29761,30520,30683,32791,33468,33541,35584,
+35624,35980,26408,27792,29287,30446,30566,31302,40361,27519,27794,22818,26406,
+33945,21359,22675,22937,24287,25551,26164,26483,28218,29483,31447,33495,37672,
+21209,24043,25006,25035,25098,25287,25771,26080,26969,27494,27595,28961,29687,
+30045,32326,33310,33538,34154,35491,36031,38695,40289,22696,40664,20497,21006,
+21563,21839,25991,27766,32010,32011,32862,34442,38272,38639,21247,27797,29289,
+21619,23194,23614,23883,24396,24494,26410,26806,26979,28220,28228,30473,31859,
+32654,34183,35598,36855,38753,40692,23735,24758,24845,25003,25935,26107,26108,
+27665,27887,29599,29641,32225,38292,23494,34588,35600,21085,21338,25293,25615,
+25778,26420,27192,27850,29632,29854,31636,31893,32283,33162,33334,34180,36843,
+38649,39361,20276,21322,21453,21467,25292,25644,25856,26001,27075,27886,28504,
+29677,30036,30242,30436,30460,30928,30971,31020,32070,33324,34784,36820,38930,
+39151,21187,25300,25765,28196,28497,30332,36299,37297,37474,39662,39747,20515,
+20621,22346,22952,23592,24135,24439,25151,25918,26041,26049,26121,26507,27036,
+28354,30917,32033,32938,33152,33323,33459,33953,34444,35370,35607,37030,38450,
+40848,20493,20467,63843,22521,24472,25308,25490,26479,28227,28953,30403,32972,
+32986,35060,35061,35097,36064,36649,37197,38506,20271,20336,24091,26575,26658,
+30333,30334,39748,24161,27146,29033,29140,30058,63844,32321,34115,34281,39132,
+20240,31567,32624,38309,20961,24070,26805,27710,27726,27867,29359,31684,33539,
+27861,29754,20731,21128,22721,25816,27287,29863,30294,30887,34327,38370,38713,
+63845,21342,24321,35722,36776,36783,37002,21029,30629,40009,40712,19993,20482,
+20853,23643,24183,26142,26170,26564,26821,28851,29953,30149,31177,31453,36647,
+39200,39432,20445,22561,22577,23542,26222,27493,27921,28282,28541,29668,29995,
+33769,35036,35091,35676,36628,20239,20693,21264,21340,23443,24489,26381,31119,
+33145,33583,34068,35079,35206,36665,36667,39333,39954,26412,20086,20472,22857,
+23553,23791,23792,25447,26834,28925,29090,29739,32299,34028,34562,36898,37586,
+40179,19981,20184,20463,20613,21078,21103,21542,21648,22496,22827,23142,23386,
+23413,23500,24220,63846,25206,25975,26023,28014,28325,29238,31526,31807,32566,
+33104,33105,33178,33344,33433,33705,35331,36000,36070,36091,36212,36282,37096,
+37340,38428,38468,39385,40167,21271,20998,21545,22132,22707,22868,22894,24575,
+24996,25198,26128,27774,28954,30406,31881,31966,32027,33452,36033,38640,63847,
+20315,24343,24447,25282,23849,26379,26842,30844,32323,40300,19989,20633,21269,
+21290,21329,22915,23138,24199,24754,24970,25161,25209,26000,26503,27047,27604,
+27606,27607,27608,27832,63848,29749,30202,30738,30865,31189,31192,31875,32203,
+32737,32933,33086,33218,33778,34586,35048,35513,35692,36027,37145,38750,39131,
+40763,22188,23338,24428,25996,27315,27567,27996,28657,28693,29277,29613,36007,
+36051,38971,24977,27703,32856,39425,20045,20107,20123,20181,20282,20284,20351,
+20447,20735,21490,21496,21766,21987,22235,22763,22882,23057,23531,23546,23556,
+24051,24107,24473,24605,25448,26012,26031,26614,26619,26797,27515,27801,27863,
+28195,28681,29509,30722,31038,31040,31072,31169,31721,32023,32114,32902,33293,
+33678,34001,34503,35039,35408,35422,35613,36060,36198,36781,37034,39164,39391,
+40605,21066,63849,26388,63850,20632,21034,23665,25955,27733,29642,29987,30109,
+31639,33948,37240,38704,20087,25746,27578,29022,34217,19977,63851,26441,26862,
+28183,33439,34072,34923,25591,28545,37394,39087,19978,20663,20687,20767,21830,
+21930,22039,23360,23577,23776,24120,24202,24224,24258,24819,26705,27233,28248,
+29245,29248,29376,30456,31077,31665,32724,35059,35316,35443,35937,36062,38684,
+22622,29885,36093,21959,63852,31329,32034,33394,29298,29983,29989,63853,31513,
+22661,22779,23996,24207,24246,24464,24661,25234,25471,25933,26257,26329,26360,
+26646,26866,29312,29790,31598,32110,32214,32626,32997,33298,34223,35199,35475,
+36893,37604,40653,40736,22805,22893,24109,24796,26132,26227,26512,27728,28101,
+28511,30707,30889,33990,37323,37675,20185,20682,20808,21892,23307,23459,25159,
+25982,26059,28210,29053,29697,29764,29831,29887,30316,31146,32218,32341,32680,
+33146,33203,33337,34330,34796,35445,36323,36984,37521,37925,39245,39854,21352,
+23633,26964,27844,27945,28203,33292,34203,35131,35373,35498,38634,40807,21089,
+26297,27570,32406,34814,36109,38275,38493,25885,28041,29166,63854,22478,22995,
+23468,24615,24826,25104,26143,26207,29481,29689,30427,30465,31596,32854,32882,
+33125,35488,37266,19990,21218,27506,27927,31237,31545,32048,63855,36016,21484,
+22063,22609,23477,23567,23569,24034,25152,25475,25620,26157,26803,27836,28040,
+28335,28703,28836,29138,29990,30095,30094,30233,31505,31712,31787,32032,32057,
+34092,34157,34311,35380,36877,36961,37045,37559,38902,39479,20439,23660,26463,
+28049,31903,32396,35606,36118,36895,23403,24061,25613,33984,36956,39137,29575,
+23435,24730,26494,28126,35359,35494,36865,38924,21047,63856,28753,30862,37782,
+34928,37335,20462,21463,22013,22234,22402,22781,23234,23432,23723,23744,24101,
+24833,25101,25163,25480,25628,25910,25976,27193,27530,27700,27929,28465,29159,
+29417,29560,29703,29874,30246,30561,31168,31319,31466,31929,32143,32172,32353,
+32670,33065,33585,33936,34010,34282,34966,35504,35728,36664,36930,36995,37228,
+37526,37561,38539,38567,38568,38614,38656,38920,39318,39635,39706,21460,22654,
+22809,23408,23487,28113,28506,29087,29729,29881,32901,33789,24033,24455,24490,
+24642,26092,26642,26991,27219,27529,27957,28147,29667,30462,30636,31565,32020,
+33059,33308,33600,34036,34147,35426,35524,37255,37662,38918,39348,25100,34899,
+36848,37477,23815,23847,23913,29791,33181,34664,28629,25342,32722,35126,35186,
+19998,20056,20711,21213,21319,25215,26119,32361,34821,38494,20365,21273,22070,
+22987,23204,23608,23630,23629,24066,24337,24643,26045,26159,26178,26558,26612,
+29468,30690,31034,32709,33940,33997,35222,35430,35433,35553,35925,35962,22516,
+23508,24335,24687,25325,26893,27542,28252,29060,31698,34645,35672,36606,39135,
+39166,20280,20353,20449,21627,23072,23480,24892,26032,26216,29180,30003,31070,
+32051,33102,33251,33688,34218,34254,34563,35338,36523,36763,63857,36805,22833,
+23460,23526,24713,23529,23563,24515,27777,63858,28145,28683,29978,33455,35574,
+20160,21313,63859,38617,27663,20126,20420,20818,21854,23077,23784,25105,29273,
+33469,33706,34558,34905,35357,38463,38597,39187,40201,40285,22538,23731,23997,
+24132,24801,24853,25569,27138,28197,37122,37716,38990,39952,40823,23433,23736,
+25353,26191,26696,30524,38593,38797,38996,39839,26017,35585,36555,38332,21813,
+23721,24022,24245,26263,30284,33780,38343,22739,25276,29390,40232,20208,22830,
+24591,26171,27523,31207,40230,21395,21696,22467,23830,24859,26326,28079,30861,
+33406,38552,38724,21380,25212,25494,28082,32266,33099,38989,27387,32588,40367,
+40474,20063,20539,20918,22812,24825,25590,26928,29242,32822,63860,37326,24369,
+63861,63862,32004,33509,33903,33979,34277,36493,63863,20335,63864,63865,22756,
+23363,24665,25562,25880,25965,26264,63866,26954,27171,27915,28673,29036,30162,
+30221,31155,31344,63867,32650,63868,35140,63869,35731,37312,38525,63870,39178,
+22276,24481,26044,28417,30208,31142,35486,39341,39770,40812,20740,25014,25233,
+27277,33222,20547,22576,24422,28937,35328,35578,23420,34326,20474,20796,22196,
+22852,25513,28153,23978,26989,20870,20104,20313,63871,63872,63873,22914,63874,
+63875,27487,27741,63876,29877,30998,63877,33287,33349,33593,36671,36701,63878,
+39192,63879,63880,63881,20134,63882,22495,24441,26131,63883,63884,30123,32377,
+35695,63885,36870,39515,22181,22567,23032,23071,23476,63886,24310,63887,63888,
+25424,25403,63889,26941,27783,27839,28046,28051,28149,28436,63890,28895,28982,
+29017,63891,29123,29141,63892,30799,30831,63893,31605,32227,63894,32303,63895,
+34893,36575,63896,63897,63898,37467,63899,40182,63900,63901,63902,24709,28037,
+63903,29105,63904,63905,38321,21421,63906,63907,63908,26579,63909,28814,28976,
+29744,33398,33490,63910,38331,39653,40573,26308,63911,29121,33865,63912,63913,
+22603,63914,63915,23992,24433,63916,26144,26254,27001,27054,27704,27891,28214,
+28481,28634,28699,28719,29008,29151,29552,63917,29787,63918,29908,30408,31310,
+32403,63919,63920,33521,35424,36814,63921,37704,63922,38681,63923,63924,20034,
+20522,63925,21000,21473,26355,27757,28618,29450,30591,31330,33454,34269,34306,
+63926,35028,35427,35709,35947,63927,37555,63928,38675,38928,20116,20237,20425,
+20658,21320,21566,21555,21978,22626,22714,22887,23067,23524,24735,63929,25034,
+25942,26111,26212,26791,27738,28595,28879,29100,29522,31613,34568,35492,39986,
+40711,23627,27779,29508,29577,37434,28331,29797,30239,31337,32277,34314,20800,
+22725,25793,29934,29973,30320,32705,37013,38605,39252,28198,29926,31401,31402,
+33253,34521,34680,35355,23113,23436,23451,26785,26880,28003,29609,29715,29740,
+30871,32233,32747,33048,33109,33694,35916,38446,38929,26352,24448,26106,26505,
+27754,29579,20525,23043,27498,30702,22806,23916,24013,29477,30031,63930,63931,
+20709,20985,22575,22829,22934,23002,23525,63932,63933,23970,25303,25622,25747,
+25854,63934,26332,63935,27208,63936,29183,29796,63937,31368,31407,32327,32350,
+32768,33136,63938,34799,35201,35616,36953,63939,36992,39250,24958,27442,28020,
+32287,35109,36785,20433,20653,20887,21191,22471,22665,23481,24248,24898,27029,
+28044,28263,28342,29076,29794,29992,29996,32883,33592,33993,36362,37780,37854,
+63940,20110,20305,20598,20778,21448,21451,21491,23431,23507,23588,24858,24962,
+26100,29275,29591,29760,30402,31056,31121,31161,32006,32701,33419,34261,34398,
+36802,36935,37109,37354,38533,38632,38633,21206,24423,26093,26161,26671,29020,
+31286,37057,38922,20113,63941,27218,27550,28560,29065,32792,33464,34131,36939,
+38549,38642,38907,34074,39729,20112,29066,38596,20803,21407,21729,22291,22290,
+22435,23195,23236,23491,24616,24895,25588,27781,27961,28274,28304,29232,29503,
+29783,33489,34945,36677,36960,63942,38498,39000,40219,26376,36234,37470,20301,
+20553,20702,21361,22285,22996,23041,23561,24944,26256,28205,29234,29771,32239,
+32963,33806,33894,34111,34655,34907,35096,35586,36949,38859,39759,20083,20369,
+20754,20842,63943,21807,21929,23418,23461,24188,24189,24254,24736,24799,24840,
+24841,25540,25912,26377,63944,26580,26586,63945,26977,26978,27833,27943,63946,
+28216,63947,28641,29494,29495,63948,29788,30001,63949,30290,63950,63951,32173,
+33278,33848,35029,35480,35547,35565,36400,36418,36938,36926,36986,37193,37321,
+37742,63952,63953,22537,63954,27603,32905,32946,63955,63956,20801,22891,23609,
+63957,63958,28516,29607,32996,36103,63959,37399,38287,63960,63961,63962,63963,
+32895,25102,28700,32104,34701,63964,22432,24681,24903,27575,35518,37504,38577,
+20057,21535,28139,34093,38512,38899,39150,25558,27875,37009,20957,25033,33210,
+40441,20381,20506,20736,23452,24847,25087,25836,26885,27589,30097,30691,32681,
+33380,34191,34811,34915,35516,35696,37291,20108,20197,20234,63965,63966,22839,
+23016,63967,24050,24347,24411,24609,63968,63969,63970,63971,29246,29669,63972,
+30064,30157,63973,31227,63974,32780,32819,32900,33505,33617,63975,63976,36029,
+36019,36999,63977,63978,39156,39180,63979,63980,28727,30410,32714,32716,32764,
+35610,20154,20161,20995,21360,63981,21693,22240,23035,23493,24341,24525,28270,
+63982,63983,32106,33589,63984,34451,35469,63985,38765,38775,63986,63987,19968,
+20314,20350,22777,26085,28322,36920,37808,39353,20219,22764,22922,23001,24641,
+63988,63989,31252,63990,33615,36035,20837,21316,63991,63992,63993,20173,21097,
+23381,33471,20180,21050,21672,22985,23039,23376,23383,23388,24675,24904,28363,
+28825,29038,29574,29943,30133,30913,32043,32773,33258,33576,34071,34249,35566,
+36039,38604,20316,21242,22204,26027,26152,28796,28856,29237,32189,33421,37196,
+38592,40306,23409,26855,27544,28538,30430,23697,26283,28507,31668,31786,34870,
+38620,19976,20183,21280,22580,22715,22767,22892,23559,24115,24196,24373,25484,
+26290,26454,27167,27299,27404,28479,29254,63994,29520,29835,31456,31911,33144,
+33247,33255,33674,33900,34083,34196,34255,35037,36115,37292,38263,38556,20877,
+21705,22312,23472,25165,26448,26685,26771,28221,28371,28797,32289,35009,36001,
+36617,40779,40782,29229,31631,35533,37658,20295,20302,20786,21632,22992,24213,
+25269,26485,26990,27159,27822,28186,29401,29482,30141,31672,32053,33511,33785,
+33879,34295,35419,36015,36487,36889,37048,38606,40799,21219,21514,23265,23490,
+25688,25973,28404,29380,63995,30340,31309,31515,31821,32318,32735,33659,35627,
+36042,36196,36321,36447,36842,36857,36969,37841,20291,20346,20659,20840,20856,
+21069,21098,22625,22652,22880,23560,23637,24283,24731,25136,26643,27583,27656,
+28593,29006,29728,30000,30008,30033,30322,31564,31627,31661,31686,32399,35438,
+36670,36681,37439,37523,37666,37931,38651,39002,39019,39198,20999,25130,25240,
+27993,30308,31434,31680,32118,21344,23742,24215,28472,28857,31896,38673,39822,
+40670,25509,25722,34678,19969,20117,20141,20572,20597,21576,22979,23450,24128,
+24237,24311,24449,24773,25402,25919,25972,26060,26230,26232,26622,26984,27273,
+27491,27712,28096,28136,28191,28254,28702,28833,29582,29693,30010,30555,30855,
+31118,31243,31357,31934,32142,33351,35330,35562,35998,37165,37194,37336,37478,
+37580,37664,38662,38742,38748,38914,40718,21046,21137,21884,22564,24093,24351,
+24716,25552,26799,28639,31085,31532,33229,34234,35069,35576,36420,37261,38500,
+38555,38717,38988,40778,20430,20806,20939,21161,22066,24340,24427,25514,25805,
+26089,26177,26362,26361,26397,26781,26839,27133,28437,28526,29031,29157,29226,
+29866,30522,31062,31066,31199,31264,31381,31895,31967,32068,32368,32903,34299,
+34468,35412,35519,36249,36481,36896,36973,37347,38459,38613,40165,26063,31751,
+36275,37827,23384,23562,21330,25305,29469,20519,23447,24478,24752,24939,26837,
+28121,29742,31278,32066,32156,32305,33131,36394,36405,37758,37912,20304,22352,
+24038,24231,25387,32618,20027,20303,20367,20570,23005,32964,21610,21608,22014,
+22863,23449,24030,24282,26205,26417,26609,26666,27880,27954,28234,28557,28855,
+29664,30087,31820,32002,32044,32162,33311,34523,35387,35461,36208,36490,36659,
+36913,37198,37202,37956,39376,31481,31909,20426,20737,20934,22472,23535,23803,
+26201,27197,27994,28310,28652,28940,30063,31459,34850,36897,36981,38603,39423,
+33537,20013,20210,34886,37325,21373,27355,26987,27713,33914,22686,24974,26366,
+25327,28893,29969,30151,32338,33976,35657,36104,20043,21482,21675,22320,22336,
+24535,25345,25351,25711,25903,26088,26234,26525,26547,27490,27744,27802,28460,
+30693,30757,31049,31063,32025,32930,33026,33267,33437,33463,34584,35468,63996,
+36100,36286,36978,30452,31257,31287,32340,32887,21767,21972,22645,25391,25634,
+26185,26187,26733,27035,27524,27941,28337,29645,29800,29857,30043,30137,30433,
+30494,30603,31206,32265,32285,33275,34095,34967,35386,36049,36587,36784,36914,
+37805,38499,38515,38663,20356,21489,23018,23241,24089,26702,29894,30142,31209,
+31378,33187,34541,36074,36300,36845,26015,26389,63997,22519,28503,32221,36655,
+37878,38598,24501,25074,28548,19988,20376,20511,21449,21983,23919,24046,27425,
+27492,30923,31642,63998,36425,36554,36974,25417,25662,30528,31364,37679,38015,
+40810,25776,28591,29158,29864,29914,31428,31762,32386,31922,32408,35738,36106,
+38013,39184,39244,21049,23519,25830,26413,32046,20717,21443,22649,24920,24921,
+25082,26028,31449,35730,35734,20489,20513,21109,21809,23100,24288,24432,24884,
+25950,26124,26166,26274,27085,28356,28466,29462,30241,31379,33081,33369,33750,
+33980,20661,22512,23488,23528,24425,25505,30758,32181,33756,34081,37319,37365,
+20874,26613,31574,36012,20932,22971,24765,34389,20508,63999,21076,23610,24957,
+25114,25299,25842,26021,28364,30240,33034,36448,38495,38587,20191,21315,21912,
+22825,24029,25797,27849,28154,29588,31359,33307,34214,36068,36368,36983,37351,
+38369,38433,38854,20984,21746,21894,24505,25764,28552,32180,36639,36685,37941,
+20681,23574,27838,28155,29979,30651,31805,31844,35449,35522,22558,22974,24086,
+25463,29266,30090,30571,35548,36028,36626,24307,26228,28152,32893,33729,35531,
+38737,39894,64000,21059,26367,28053,28399,32224,35558,36910,36958,39636,21021,
+21119,21736,24980,25220,25307,26786,26898,26970,27189,28818,28966,30813,30977,
+30990,31186,31245,32918,33400,33493,33609,34121,35970,36229,37218,37259,37294,
+20419,22225,29165,30679,34560,35320,23544,24534,26449,37032,21474,22618,23541,
+24740,24961,25696,32317,32880,34085,37507,25774,20652,23828,26368,22684,25277,
+25512,26894,27000,27166,28267,30394,31179,33467,33833,35535,36264,36861,37138,
+37195,37276,37648,37656,37786,38619,39478,39949,19985,30044,31069,31482,31569,
+31689,32302,33988,36441,36468,36600,36880,26149,26943,29763,20986,26414,40668,
+20805,24544,27798,34802,34909,34935,24756,33205,33795,36101,21462,21561,22068,
+23094,23601,28810,32736,32858,33030,33261,36259,37257,39519,40434,20596,20164,
+21408,24827,28204,23652,20360,20516,21988,23769,24159,24677,26772,27835,28100,
+29118,30164,30196,30305,31258,31305,32199,32251,32622,33268,34473,36636,38601,
+39347,40786,21063,21189,39149,35242,19971,26578,28422,20405,23522,26517,27784,
+28024,29723,30759,37341,37756,34756,31204,31281,24555,20182,21668,21822,22702,
+22949,24816,25171,25302,26422,26965,33333,38464,39345,39389,20524,21331,21828,
+22396,64001,25176,64002,25826,26219,26589,28609,28655,29730,29752,35351,37944,
+21585,22022,22374,24392,24986,27470,28760,28845,32187,35477,22890,33067,25506,
+30472,32829,36010,22612,25645,27067,23445,24081,28271,64003,34153,20812,21488,
+22826,24608,24907,27526,27760,27888,31518,32974,33492,36294,37040,39089,64004,
+25799,28580,25745,25860,20814,21520,22303,35342,24927,26742,64005,30171,31570,
+32113,36890,22534,27084,33151,35114,36864,38969,20600,22871,22956,25237,36879,
+39722,24925,29305,38358,22369,23110,24052,25226,25773,25850,26487,27874,27966,
+29228,29750,30772,32631,33453,36315,38935,21028,22338,26495,29256,29923,36009,
+36774,37393,38442,20843,21485,25420,20329,21764,24726,25943,27803,28031,29260,
+29437,31255,35207,35997,24429,28558,28921,33192,24846,20415,20559,25153,29255,
+31687,32232,32745,36941,38829,39449,36022,22378,24179,26544,33805,35413,21536,
+23318,24163,24290,24330,25987,32954,34109,38281,38491,20296,21253,21261,21263,
+21638,21754,22275,24067,24598,25243,25265,25429,64006,27873,28006,30129,30770,
+32990,33071,33502,33889,33970,34957,35090,36875,37610,39165,39825,24133,26292,
+26333,28689,29190,64007,20469,21117,24426,24915,26451,27161,28418,29922,31080,
+34920,35961,39111,39108,39491,21697,31263,26963,35575,35914,39080,39342,24444,
+25259,30130,30382,34987,36991,38466,21305,24380,24517,27852,29644,30050,30091,
+31558,33534,39325,20047,36924,19979,20309,21414,22799,24264,26160,27827,29781,
+33655,34662,36032,36944,38686,39957,22737,23416,34384,35604,40372,23506,24680,
+24717,26097,27735,28450,28579,28698,32597,32752,38289,38290,38480,38867,21106,
+36676,20989,21547,21688,21859,21898,27323,28085,32216,33382,37532,38519,40569,
+21512,21704,30418,34532,38308,38356,38492,20130,20233,23022,23270,24055,24658,
+25239,26477,26689,27782,28207,32568,32923,33322,64008,64009,38917,20133,20565,
+21683,22419,22874,23401,23475,25032,26999,28023,28707,34809,35299,35442,35559,
+36994,39405,39608,21182,26680,20502,24184,26447,33607,34892,20139,21521,22190,
+29670,37141,38911,39177,39255,39321,22099,22687,34395,35377,25010,27382,29563,
+36562,27463,38570,39511,22869,29184,36203,38761,20436,23796,24358,25080,26203,
+27883,28843,29572,29625,29694,30505,30541,32067,32098,32291,33335,34898,64010,
+36066,37449,39023,23377,31348,34880,38913,23244,20448,21332,22846,23805,25406,
+28025,29433,33029,33031,33698,37583,38960,20136,20804,21009,22411,24418,27842,
+28366,28677,28752,28847,29074,29673,29801,33610,34722,34913,36872,37026,37795,
+39336,20846,24407,24800,24935,26291,34137,36426,37295,38795,20046,20114,21628,
+22741,22778,22909,23733,24359,25142,25160,26122,26215,27627,28009,28111,28246,
+28408,28564,28640,28649,28765,29392,29733,29786,29920,30355,31068,31946,32286,
+32993,33446,33899,33983,34382,34399,34676,35703,35946,37804,38912,39013,24785,
+25110,37239,23130,26127,28151,28222,29759,39746,24573,24794,31503,21700,24344,
+27742,27859,27946,28888,32005,34425,35340,40251,21270,21644,23301,27194,28779,
+30069,31117,31166,33457,33775,35441,35649,36008,38772,64011,25844,25899,30906,
+30907,31339,20024,21914,22864,23462,24187,24739,25563,27489,26213,26707,28185,
+29029,29872,32008,36996,39529,39973,27963,28369,29502,35905,38346,20976,24140,
+24488,24653,24822,24880,24908,26179,26180,27045,27841,28255,28361,28514,29004,
+29852,30343,31681,31783,33618,34647,36945,38541,40643,21295,22238,24315,24458,
+24674,24724,25079,26214,26371,27292,28142,28590,28784,29546,32362,33214,33588,
+34516,35496,36036,21123,29554,23446,27243,37892,21742,22150,23389,25928,25989,
+26313,26783,28045,28102,29243,32948,37237,39501,20399,20505,21402,21518,21564,
+21897,21957,24127,24460,26429,29030,29661,36869,21211,21235,22628,22734,28932,
+29071,29179,34224,35347,26248,34216,21927,26244,29002,33841,21321,21913,27585,
+24409,24509,25582,26249,28999,35569,36637,40638,20241,25658,28875,30054,34407,
+24676,35662,40440,20807,20982,21256,27958,33016,40657,26133,27427,28824,30165,
+21507,23673,32007,35350,27424,27453,27462,21560,24688,27965,32725,33288,20694,
+20958,21916,22123,22221,23020,23305,24076,24985,24984,25137,26206,26342,29081,
+29113,29114,29351,31143,31232,32690,35440,
+};
+
+static const struct dbcs_index ksx1001_decmap[256] = {
+{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{__ksx1001_decmap+0,33,126},{__ksx1001_decmap+
+94,33,103},{__ksx1001_decmap+165,33,126},{__ksx1001_decmap+259,33,126},{
+__ksx1001_decmap+353,33,120},{__ksx1001_decmap+441,33,100},{__ksx1001_decmap+
+509,33,111},{__ksx1001_decmap+588,33,126},{__ksx1001_decmap+682,33,126},{
+__ksx1001_decmap+776,33,115},{__ksx1001_decmap+859,33,118},{__ksx1001_decmap+
+945,33,113},{0,0,0},{0,0,0},{0,0,0},{__ksx1001_decmap+1026,33,126},{
+__ksx1001_decmap+1120,33,126},{__ksx1001_decmap+1214,33,126},{__ksx1001_decmap
++1308,33,126},{__ksx1001_decmap+1402,33,126},{__ksx1001_decmap+1496,33,126},{
+__ksx1001_decmap+1590,33,126},{__ksx1001_decmap+1684,33,126},{__ksx1001_decmap
++1778,33,126},{__ksx1001_decmap+1872,33,126},{__ksx1001_decmap+1966,33,126},{
+__ksx1001_decmap+2060,33,126},{__ksx1001_decmap+2154,33,126},{__ksx1001_decmap
++2248,33,126},{__ksx1001_decmap+2342,33,126},{__ksx1001_decmap+2436,33,126},{
+__ksx1001_decmap+2530,33,126},{__ksx1001_decmap+2624,33,126},{__ksx1001_decmap
++2718,33,126},{__ksx1001_decmap+2812,33,126},{__ksx1001_decmap+2906,33,126},{
+__ksx1001_decmap+3000,33,126},{__ksx1001_decmap+3094,33,126},{__ksx1001_decmap
++3188,33,126},{__ksx1001_decmap+3282,33,126},{0,0,0},{__ksx1001_decmap+3376,
+33,126},{__ksx1001_decmap+3470,33,126},{__ksx1001_decmap+3564,33,126},{
+__ksx1001_decmap+3658,33,126},{__ksx1001_decmap+3752,33,126},{__ksx1001_decmap
++3846,33,126},{__ksx1001_decmap+3940,33,126},{__ksx1001_decmap+4034,33,126},{
+__ksx1001_decmap+4128,33,126},{__ksx1001_decmap+4222,33,126},{__ksx1001_decmap
++4316,33,126},{__ksx1001_decmap+4410,33,126},{__ksx1001_decmap+4504,33,126},{
+__ksx1001_decmap+4598,33,126},{__ksx1001_decmap+4692,33,126},{__ksx1001_decmap
++4786,33,126},{__ksx1001_decmap+4880,33,126},{__ksx1001_decmap+4974,33,126},{
+__ksx1001_decmap+5068,33,126},{__ksx1001_decmap+5162,33,126},{__ksx1001_decmap
++5256,33,126},{__ksx1001_decmap+5350,33,126},{__ksx1001_decmap+5444,33,126},{
+__ksx1001_decmap+5538,33,126},{__ksx1001_decmap+5632,33,126},{__ksx1001_decmap
++5726,33,126},{__ksx1001_decmap+5820,33,126},{__ksx1001_decmap+5914,33,126},{
+__ksx1001_decmap+6008,33,126},{__ksx1001_decmap+6102,33,126},{__ksx1001_decmap
++6196,33,126},{__ksx1001_decmap+6290,33,126},{__ksx1001_decmap+6384,33,126},{
+__ksx1001_decmap+6478,33,126},{__ksx1001_decmap+6572,33,126},{__ksx1001_decmap
++6666,33,126},{__ksx1001_decmap+6760,33,126},{__ksx1001_decmap+6854,33,126},{
+__ksx1001_decmap+6948,33,126},{__ksx1001_decmap+7042,33,126},{__ksx1001_decmap
++7136,33,126},{__ksx1001_decmap+7230,33,126},{__ksx1001_decmap+7324,33,126},{
+__ksx1001_decmap+7418,33,126},{__ksx1001_decmap+7512,33,126},{__ksx1001_decmap
++7606,33,126},{__ksx1001_decmap+7700,33,126},{__ksx1001_decmap+7794,33,126},{
+__ksx1001_decmap+7888,33,126},{__ksx1001_decmap+7982,33,126},{__ksx1001_decmap
++8076,33,126},{__ksx1001_decmap+8170,33,126},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},
+};
+
+static const ucs2_t __cp949ext_decmap[9650] = {
+44034,44035,44037,44038,44043,44044,44045,44046,44047,44056,44062,44063,44065,
+44066,44067,44069,44070,44071,44072,44073,44074,44075,44078,44082,44083,44084,
+U,U,U,U,U,U,44085,44086,44087,44090,44091,44093,44094,44095,44097,44098,44099,
+44100,44101,44102,44103,44104,44105,44106,44108,44110,44111,44112,44113,44114,
+44115,44117,U,U,U,U,U,U,44118,44119,44121,44122,44123,44125,44126,44127,44128,
+44129,44130,44131,44132,44133,44134,44135,44136,44137,44138,44139,44140,44141,
+44142,44143,44146,44147,44149,44150,44153,44155,44156,44157,44158,44159,44162,
+44167,44168,44173,44174,44175,44177,44178,44179,44181,44182,44183,44184,44185,
+44186,44187,44190,44194,44195,44196,44197,44198,44199,44203,44205,44206,44209,
+44210,44211,44212,44213,44214,44215,44218,44222,44223,44224,44226,44227,44229,
+44230,44231,44233,44234,44235,44237,44238,44239,44240,44241,44242,44243,44244,
+44246,44248,44249,44250,44251,44252,44253,44254,44255,44258,44259,44261,44262,
+44265,44267,44269,44270,44274,44276,44279,44280,44281,44282,44283,44286,44287,
+44289,44290,44291,44293,44295,44296,44297,44298,44299,44302,44304,44306,44307,
+44308,44309,44310,44311,44313,44314,44315,44317,44318,44319,44321,44322,44323,
+44324,44325,44326,44327,44328,44330,44331,44334,44335,44336,44337,44338,44339,
+U,U,U,U,U,U,44342,44343,44345,44346,44347,44349,44350,44351,44352,44353,44354,
+44355,44358,44360,44362,44363,44364,44365,44366,44367,44369,44370,44371,44373,
+44374,44375,U,U,U,U,U,U,44377,44378,44379,44380,44381,44382,44383,44384,44386,
+44388,44389,44390,44391,44392,44393,44394,44395,44398,44399,44401,44402,44407,
+44408,44409,44410,44414,44416,44419,44420,44421,44422,44423,44426,44427,44429,
+44430,44431,44433,44434,44435,44436,44437,44438,44439,44440,44441,44442,44443,
+44446,44447,44448,44449,44450,44451,44453,44454,44455,44456,44457,44458,44459,
+44460,44461,44462,44463,44464,44465,44466,44467,44468,44469,44470,44472,44473,
+44474,44475,44476,44477,44478,44479,44482,44483,44485,44486,44487,44489,44490,
+44491,44492,44493,44494,44495,44498,44500,44501,44502,44503,44504,44505,44506,
+44507,44509,44510,44511,44513,44514,44515,44517,44518,44519,44520,44521,44522,
+44523,44524,44525,44526,44527,44528,44529,44530,44531,44532,44533,44534,44535,
+44538,44539,44541,44542,44546,44547,44548,44549,44550,44551,44554,44556,44558,
+44559,44560,44561,44562,44563,44565,44566,44567,44568,44569,44570,44571,44572,
+U,U,U,U,U,U,44573,44574,44575,44576,44577,44578,44579,44580,44581,44582,44583,
+44584,44585,44586,44587,44588,44589,44590,44591,44594,44595,44597,44598,44601,
+44603,44604,U,U,U,U,U,U,44605,44606,44607,44610,44612,44615,44616,44617,44619,
+44623,44625,44626,44627,44629,44631,44632,44633,44634,44635,44638,44642,44643,
+44644,44646,44647,44650,44651,44653,44654,44655,44657,44658,44659,44660,44661,
+44662,44663,44666,44670,44671,44672,44673,44674,44675,44678,44679,44680,44681,
+44682,44683,44685,44686,44687,44688,44689,44690,44691,44692,44693,44694,44695,
+44696,44697,44698,44699,44700,44701,44702,44703,44704,44705,44706,44707,44708,
+44709,44710,44711,44712,44713,44714,44715,44716,44717,44718,44719,44720,44721,
+44722,44723,44724,44725,44726,44727,44728,44729,44730,44731,44735,44737,44738,
+44739,44741,44742,44743,44744,44745,44746,44747,44750,44754,44755,44756,44757,
+44758,44759,44762,44763,44765,44766,44767,44768,44769,44770,44771,44772,44773,
+44774,44775,44777,44778,44780,44782,44783,44784,44785,44786,44787,44789,44790,
+44791,44793,44794,44795,44797,44798,44799,44800,44801,44802,44803,44804,44805,
+U,U,U,U,U,U,44806,44809,44810,44811,44812,44814,44815,44817,44818,44819,44820,
+44821,44822,44823,44824,44825,44826,44827,44828,44829,44830,44831,44832,44833,
+44834,44835,U,U,U,U,U,U,44836,44837,44838,44839,44840,44841,44842,44843,44846,
+44847,44849,44851,44853,44854,44855,44856,44857,44858,44859,44862,44864,44868,
+44869,44870,44871,44874,44875,44876,44877,44878,44879,44881,44882,44883,44884,
+44885,44886,44887,44888,44889,44890,44891,44894,44895,44896,44897,44898,44899,
+44902,44903,44904,44905,44906,44907,44908,44909,44910,44911,44912,44913,44914,
+44915,44916,44917,44918,44919,44920,44922,44923,44924,44925,44926,44927,44929,
+44930,44931,44933,44934,44935,44937,44938,44939,44940,44941,44942,44943,44946,
+44947,44948,44950,44951,44952,44953,44954,44955,44957,44958,44959,44960,44961,
+44962,44963,44964,44965,44966,44967,44968,44969,44970,44971,44972,44973,44974,
+44975,44976,44977,44978,44979,44980,44981,44982,44983,44986,44987,44989,44990,
+44991,44993,44994,44995,44996,44997,44998,45002,45004,45007,45008,45009,45010,
+45011,45013,45014,45015,45016,45017,45018,45019,45021,45022,45023,45024,45025,
+U,U,U,U,U,U,45026,45027,45028,45029,45030,45031,45034,45035,45036,45037,45038,
+45039,45042,45043,45045,45046,45047,45049,45050,45051,45052,45053,45054,45055,
+45058,45059,U,U,U,U,U,U,45061,45062,45063,45064,45065,45066,45067,45069,45070,
+45071,45073,45074,45075,45077,45078,45079,45080,45081,45082,45083,45086,45087,
+45088,45089,45090,45091,45092,45093,45094,45095,45097,45098,45099,45100,45101,
+45102,45103,45104,45105,45106,45107,45108,45109,45110,45111,45112,45113,45114,
+45115,45116,45117,45118,45119,45120,45121,45122,45123,45126,45127,45129,45131,
+45133,45135,45136,45137,45138,45142,45144,45146,45147,45148,45150,45151,45152,
+45153,45154,45155,45156,45157,45158,45159,45160,45161,45162,45163,45164,45165,
+45166,45167,45168,45169,45170,45171,45172,45173,45174,45175,45176,45177,45178,
+45179,45182,45183,45185,45186,45187,45189,45190,45191,45192,45193,45194,45195,
+45198,45200,45202,45203,45204,45205,45206,45207,45211,45213,45214,45219,45220,
+45221,45222,45223,45226,45232,45234,45238,45239,45241,45242,45243,45245,45246,
+45247,45248,45249,45250,45251,45254,45258,45259,45260,45261,45262,45263,45266,
+U,U,U,U,U,U,45267,45269,45270,45271,45273,45274,45275,45276,45277,45278,45279,
+45281,45282,45283,45284,45286,45287,45288,45289,45290,45291,45292,45293,45294,
+45295,45296,U,U,U,U,U,U,45297,45298,45299,45300,45301,45302,45303,45304,45305,
+45306,45307,45308,45309,45310,45311,45312,45313,45314,45315,45316,45317,45318,
+45319,45322,45325,45326,45327,45329,45332,45333,45334,45335,45338,45342,45343,
+45344,45345,45346,45350,45351,45353,45354,45355,45357,45358,45359,45360,45361,
+45362,45363,45366,45370,45371,45372,45373,45374,45375,45378,45379,45381,45382,
+45383,45385,45386,45387,45388,45389,45390,45391,45394,45395,45398,45399,45401,
+45402,45403,45405,45406,45407,45409,45410,45411,45412,45413,45414,45415,45416,
+45417,45418,45419,45420,45421,45422,45423,45424,45425,45426,45427,45428,45429,
+45430,45431,45434,45435,45437,45438,45439,45441,45443,45444,45445,45446,45447,
+45450,45452,45454,45455,45456,45457,45461,45462,45463,45465,45466,45467,45469,
+45470,45471,45472,45473,45474,45475,45476,45477,45478,45479,45481,45482,45483,
+45484,45485,45486,45487,45488,45489,45490,45491,45492,45493,45494,45495,45496,
+U,U,U,U,U,U,45497,45498,45499,45500,45501,45502,45503,45504,45505,45506,45507,
+45508,45509,45510,45511,45512,45513,45514,45515,45517,45518,45519,45521,45522,
+45523,45525,U,U,U,U,U,U,45526,45527,45528,45529,45530,45531,45534,45536,45537,
+45538,45539,45540,45541,45542,45543,45546,45547,45549,45550,45551,45553,45554,
+45555,45556,45557,45558,45559,45560,45562,45564,45566,45567,45568,45569,45570,
+45571,45574,45575,45577,45578,45581,45582,45583,45584,45585,45586,45587,45590,
+45592,45594,45595,45596,45597,45598,45599,45601,45602,45603,45604,45605,45606,
+45607,45608,45609,45610,45611,45612,45613,45614,45615,45616,45617,45618,45619,
+45621,45622,45623,45624,45625,45626,45627,45629,45630,45631,45632,45633,45634,
+45635,45636,45637,45638,45639,45640,45641,45642,45643,45644,45645,45646,45647,
+45648,45649,45650,45651,45652,45653,45654,45655,45657,45658,45659,45661,45662,
+45663,45665,45666,45667,45668,45669,45670,45671,45674,45675,45676,45677,45678,
+45679,45680,45681,45682,45683,45686,45687,45688,45689,45690,45691,45693,45694,
+45695,45696,45697,45698,45699,45702,45703,45704,45706,45707,45708,45709,45710,
+U,U,U,U,U,U,45711,45714,45715,45717,45718,45719,45723,45724,45725,45726,45727,
+45730,45732,45735,45736,45737,45739,45741,45742,45743,45745,45746,45747,45749,
+45750,45751,U,U,U,U,U,U,45752,45753,45754,45755,45756,45757,45758,45759,45760,
+45761,45762,45763,45764,45765,45766,45767,45770,45771,45773,45774,45775,45777,
+45779,45780,45781,45782,45783,45786,45788,45790,45791,45792,45793,45795,45799,
+45801,45802,45808,45809,45810,45814,45820,45821,45822,45826,45827,45829,45830,
+45831,45833,45834,45835,45836,45837,45838,45839,45842,45846,45847,45848,45849,
+45850,45851,45853,45854,45855,45856,45857,45858,45859,45860,45861,45862,45863,
+45864,45865,45866,45867,45868,45869,45870,45871,45872,45873,45874,45875,45876,
+45877,45878,45879,45880,45881,45882,45883,45884,45885,45886,45887,45888,45889,
+45890,45891,45892,45893,45894,45895,45896,45897,45898,45899,45900,45901,45902,
+45903,45904,45905,45906,45907,45911,45913,45914,45917,45920,45921,45922,45923,
+45926,45928,45930,45932,45933,45935,45938,45939,45941,45942,45943,45945,45946,
+45947,45948,45949,45950,45951,45954,45958,45959,45960,45961,45962,45963,45965,
+U,U,U,U,U,U,45966,45967,45969,45970,45971,45973,45974,45975,45976,45977,45978,
+45979,45980,45981,45982,45983,45986,45987,45988,45989,45990,45991,45993,45994,
+45995,45997,U,U,U,U,U,U,45998,45999,46000,46001,46002,46003,46004,46005,46006,
+46007,46008,46009,46010,46011,46012,46013,46014,46015,46016,46017,46018,46019,
+46022,46023,46025,46026,46029,46031,46033,46034,46035,46038,46040,46042,46044,
+46046,46047,46049,46050,46051,46053,46054,46055,46057,46058,46059,46060,46061,
+46062,46063,46064,46065,46066,46067,46068,46069,46070,46071,46072,46073,46074,
+46075,46077,46078,46079,46080,46081,46082,46083,46084,46085,46086,46087,46088,
+46089,46090,46091,46092,46093,46094,46095,46097,46098,46099,46100,46101,46102,
+46103,46105,46106,46107,46109,46110,46111,46113,46114,46115,46116,46117,46118,
+46119,46122,46124,46125,46126,46127,46128,46129,46130,46131,46133,46134,46135,
+46136,46137,46138,46139,46140,46141,46142,46143,46144,46145,46146,46147,46148,
+46149,46150,46151,46152,46153,46154,46155,46156,46157,46158,46159,46162,46163,
+46165,46166,46167,46169,46170,46171,46172,46173,46174,46175,46178,46180,46182,
+U,U,U,U,U,U,46183,46184,46185,46186,46187,46189,46190,46191,46192,46193,46194,
+46195,46196,46197,46198,46199,46200,46201,46202,46203,46204,46205,46206,46207,
+46209,46210,U,U,U,U,U,U,46211,46212,46213,46214,46215,46217,46218,46219,46220,
+46221,46222,46223,46224,46225,46226,46227,46228,46229,46230,46231,46232,46233,
+46234,46235,46236,46238,46239,46240,46241,46242,46243,46245,46246,46247,46249,
+46250,46251,46253,46254,46255,46256,46257,46258,46259,46260,46262,46264,46266,
+46267,46268,46269,46270,46271,46273,46274,46275,46277,46278,46279,46281,46282,
+46283,46284,46285,46286,46287,46289,46290,46291,46292,46294,46295,46296,46297,
+46298,46299,46302,46303,46305,46306,46309,46311,46312,46313,46314,46315,46318,
+46320,46322,46323,46324,46325,46326,46327,46329,46330,46331,46332,46333,46334,
+46335,46336,46337,46338,46339,46340,46341,46342,46343,46344,46345,46346,46347,
+46348,46349,46350,46351,46352,46353,46354,46355,46358,46359,46361,46362,46365,
+46366,46367,46368,46369,46370,46371,46374,46379,46380,46381,46382,46383,46386,
+46387,46389,46390,46391,46393,46394,46395,46396,46397,46398,46399,46402,46406,
+U,U,U,U,U,U,46407,46408,46409,46410,46414,46415,46417,46418,46419,46421,46422,
+46423,46424,46425,46426,46427,46430,46434,46435,46436,46437,46438,46439,46440,
+46441,46442,U,U,U,U,U,U,46443,46444,46445,46446,46447,46448,46449,46450,46451,
+46452,46453,46454,46455,46456,46457,46458,46459,46460,46461,46462,46463,46464,
+46465,46466,46467,46468,46469,46470,46471,46472,46473,46474,46475,46476,46477,
+46478,46479,46480,46481,46482,46483,46484,46485,46486,46487,46488,46489,46490,
+46491,46492,46493,46494,46495,46498,46499,46501,46502,46503,46505,46508,46509,
+46510,46511,46514,46518,46519,46520,46521,46522,46526,46527,46529,46530,46531,
+46533,46534,46535,46536,46537,46538,46539,46542,46546,46547,46548,46549,46550,
+46551,46553,46554,46555,46556,46557,46558,46559,46560,46561,46562,46563,46564,
+46565,46566,46567,46568,46569,46570,46571,46573,46574,46575,46576,46577,46578,
+46579,46580,46581,46582,46583,46584,46585,46586,46587,46588,46589,46590,46591,
+46592,46593,46594,46595,46596,46597,46598,46599,46600,46601,46602,46603,46604,
+46605,46606,46607,46610,46611,46613,46614,46615,46617,46618,46619,46620,46621,
+U,U,U,U,U,U,46622,46623,46624,46625,46626,46627,46628,46630,46631,46632,46633,
+46634,46635,46637,46638,46639,46640,46641,46642,46643,46645,46646,46647,46648,
+46649,46650,U,U,U,U,U,U,46651,46652,46653,46654,46655,46656,46657,46658,46659,
+46660,46661,46662,46663,46665,46666,46667,46668,46669,46670,46671,46672,46673,
+46674,46675,46676,46677,46678,46679,46680,46681,46682,46683,46684,46685,46686,
+46687,46688,46689,46690,46691,46693,46694,46695,46697,46698,46699,46700,46701,
+46702,46703,46704,46705,46706,46707,46708,46709,46710,46711,46712,46713,46714,
+46715,46716,46717,46718,46719,46720,46721,46722,46723,46724,46725,46726,46727,
+46728,46729,46730,46731,46732,46733,46734,46735,46736,46737,46738,46739,46740,
+46741,46742,46743,46744,46745,46746,46747,46750,46751,46753,46754,46755,46757,
+46758,46759,46760,46761,46762,46765,46766,46767,46768,46770,46771,46772,46773,
+46774,46775,46776,46777,46778,46779,46780,46781,46782,46783,46784,46785,46786,
+46787,46788,46789,46790,46791,46792,46793,46794,46795,46796,46797,46798,46799,
+46800,46801,46802,46803,46805,46806,46807,46808,46809,46810,46811,46812,46813,
+U,U,U,U,U,U,46814,46815,46816,46817,46818,46819,46820,46821,46822,46823,46824,
+46825,46826,46827,46828,46829,46830,46831,46833,46834,46835,46837,46838,46839,
+46841,46842,U,U,U,U,U,U,46843,46844,46845,46846,46847,46850,46851,46852,46854,
+46855,46856,46857,46858,46859,46860,46861,46862,46863,46864,46865,46866,46867,
+46868,46869,46870,46871,46872,46873,46874,46875,46876,46877,46878,46879,46880,
+46881,46882,46883,46884,46885,46886,46887,46890,46891,46893,46894,46897,46898,
+46899,46900,46901,46902,46903,46906,46908,46909,46910,46911,46912,46913,46914,
+46915,46917,46918,46919,46921,46922,46923,46925,46926,46927,46928,46929,46930,
+46931,46934,46935,46936,46937,46938,46939,46940,46941,46942,46943,46945,46946,
+46947,46949,46950,46951,46953,46954,46955,46956,46957,46958,46959,46962,46964,
+46966,46967,46968,46969,46970,46971,46974,46975,46977,46978,46979,46981,46982,
+46983,46984,46985,46986,46987,46990,46995,46996,46997,47002,47003,47005,47006,
+47007,47009,47010,47011,47012,47013,47014,47015,47018,47022,47023,47024,47025,
+47026,47027,47030,47031,47033,47034,47035,47036,47037,47038,47039,47040,47041,
+U,U,U,U,U,U,47042,47043,47044,47045,47046,47048,47050,47051,47052,47053,47054,
+47055,47056,47057,47058,47059,47060,47061,47062,47063,47064,47065,47066,47067,
+47068,47069,U,U,U,U,U,U,47070,47071,47072,47073,47074,47075,47076,47077,47078,
+47079,47080,47081,47082,47083,47086,47087,47089,47090,47091,47093,47094,47095,
+47096,47097,47098,47099,47102,47106,47107,47108,47109,47110,47114,47115,47117,
+47118,47119,47121,47122,47123,47124,47125,47126,47127,47130,47132,47134,47135,
+47136,47137,47138,47139,47142,47143,47145,47146,47147,47149,47150,47151,47152,
+47153,47154,47155,47158,47162,47163,47164,47165,47166,47167,47169,47170,47171,
+47173,47174,47175,47176,47177,47178,47179,47180,47181,47182,47183,47184,47186,
+47188,47189,47190,47191,47192,47193,47194,47195,47198,47199,47201,47202,47203,
+47205,47206,47207,47208,47209,47210,47211,47214,47216,47218,47219,47220,47221,
+47222,47223,47225,47226,47227,47229,47230,47231,47232,47233,47234,47235,47236,
+47237,47238,47239,47240,47241,47242,47243,47244,47246,47247,47248,47249,47250,
+47251,47252,47253,47254,47255,47256,47257,47258,47259,47260,47261,47262,47263,
+U,U,U,U,U,U,47264,47265,47266,47267,47268,47269,47270,47271,47273,47274,47275,
+47276,47277,47278,47279,47281,47282,47283,47285,47286,47287,47289,47290,47291,
+47292,47293,U,U,U,U,U,U,47294,47295,47298,47300,47302,47303,47304,47305,47306,
+47307,47309,47310,47311,47313,47314,47315,47317,47318,47319,47320,47321,47322,
+47323,47324,47326,47328,47330,47331,47332,47333,47334,47335,47338,47339,47341,
+47342,47343,47345,47346,47347,47348,47349,47350,47351,47354,47356,47358,47359,
+47360,47361,47362,47363,47365,47366,47367,47368,47369,47370,47371,47372,47373,
+47374,47375,47376,47377,47378,47379,47380,47381,47382,47383,47385,47386,47387,
+47388,47389,47390,47391,47393,47394,47395,47396,47397,47398,47399,47400,47401,
+47402,47403,47404,47405,47406,47407,47408,47409,47410,47411,47412,47413,47414,
+47415,47416,47417,47418,47419,47422,47423,47425,47426,47427,47429,47430,47431,
+47432,47433,47434,47435,47437,47438,47440,47442,47443,47444,47445,47446,47447,
+47450,47451,47453,47454,47455,47457,47458,47459,47460,47461,47462,47463,47466,
+47468,47470,47471,47472,47473,47474,47475,47478,47479,47481,47482,47483,47485,
+U,U,U,U,U,U,47486,47487,47488,47489,47490,47491,47494,47496,47499,47500,47503,
+47504,47505,47506,47507,47508,47509,47510,47511,47512,47513,47514,47515,47516,
+47517,47518,U,U,U,U,U,U,47519,47520,47521,47522,47523,47524,47525,47526,47527,
+47528,47529,47530,47531,47534,47535,47537,47538,47539,47541,47542,47543,47544,
+47545,47546,47547,47550,47552,47554,47555,47556,47557,47558,47559,47562,47563,
+47565,47571,47572,47573,47574,47575,47578,47580,47583,47584,47586,47590,47591,
+47593,47594,47595,47597,47598,47599,47600,47601,47602,47603,47606,47611,47612,
+47613,47614,47615,47618,47619,47620,47621,47622,47623,47625,47626,47627,47628,
+47629,47630,47631,47632,47633,47634,47635,47636,47638,47639,47640,47641,47642,
+47643,47644,47645,47646,47647,47648,47649,47650,47651,47652,47653,47654,47655,
+47656,47657,47658,47659,47660,47661,47662,47663,47664,47665,47666,47667,47668,
+47669,47670,47671,47674,47675,47677,47678,47679,47681,47683,47684,47685,47686,
+47687,47690,47692,47695,47696,47697,47698,47702,47703,47705,47706,47707,47709,
+47710,47711,47712,47713,47714,47715,47718,47722,47723,47724,47725,47726,47727,
+U,U,U,U,U,U,47730,47731,47733,47734,47735,47737,47738,47739,47740,47741,47742,
+47743,47744,47745,47746,47750,47752,47753,47754,47755,47757,47758,47759,47760,
+47761,47762,U,U,U,U,U,U,47763,47764,47765,47766,47767,47768,47769,47770,47771,
+47772,47773,47774,47775,47776,47777,47778,47779,47780,47781,47782,47783,47786,
+47789,47790,47791,47793,47795,47796,47797,47798,47799,47802,47804,47806,47807,
+47808,47809,47810,47811,47813,47814,47815,47817,47818,47819,47820,47821,47822,
+47823,47824,47825,47826,47827,47828,47829,47830,47831,47834,47835,47836,47837,
+47838,47839,47840,47841,47842,47843,47844,47845,47846,47847,47848,47849,47850,
+47851,47852,47853,47854,47855,47856,47857,47858,47859,47860,47861,47862,47863,
+47864,47865,47866,47867,47869,47870,47871,47873,47874,47875,47877,47878,47879,
+47880,47881,47882,47883,47884,47886,47888,47890,47891,47892,47893,47894,47895,
+47897,47898,47899,47901,47902,47903,47905,47906,47907,47908,47909,47910,47911,
+47912,47914,47916,47917,47918,47919,47920,47921,47922,47923,47927,47929,47930,
+47935,47936,47937,47938,47939,47942,47944,47946,47947,47948,47950,47953,47954,
+U,U,U,U,U,U,47955,47957,47958,47959,47961,47962,47963,47964,47965,47966,47967,
+47968,47970,47972,47973,47974,47975,47976,47977,47978,47979,47981,47982,47983,
+47984,47985,U,U,U,U,U,U,47986,47987,47988,47989,47990,47991,47992,47993,47994,
+47995,47996,47997,47998,47999,48000,48001,48002,48003,48004,48005,48006,48007,
+48009,48010,48011,48013,48014,48015,48017,48018,48019,48020,48021,48022,48023,
+48024,48025,48026,48027,48028,48029,48030,48031,48032,48033,48034,48035,48037,
+48038,48039,48041,48042,48043,48045,48046,48047,48048,48049,48050,48051,48053,
+48054,48056,48057,48058,48059,48060,48061,48062,48063,48065,48066,48067,48069,
+48070,48071,48073,48074,48075,48076,48077,48078,48079,48081,48082,48084,48085,
+48086,48087,48088,48089,48090,48091,48092,48093,48094,48095,48096,48097,48098,
+48099,48100,48101,48102,48103,48104,48105,48106,48107,48108,48109,48110,48111,
+48112,48113,48114,48115,48116,48117,48118,48119,48122,48123,48125,48126,48129,
+48131,48132,48133,48134,48135,48138,48142,48144,48146,48147,48153,48154,48160,
+48161,48162,48163,48166,48168,48170,48171,48172,48174,48175,48178,48179,48181,
+U,U,U,U,U,U,48182,48183,48185,48186,48187,48188,48189,48190,48191,48194,48198,
+48199,48200,48202,48203,48206,48207,48209,48210,48211,48212,48213,48214,48215,
+48216,48217,U,U,U,U,U,U,48218,48219,48220,48222,48223,48224,48225,48226,48227,
+48228,48229,48230,48231,48232,48233,48234,48235,48236,48237,48238,48239,48240,
+48241,48242,48243,48244,48245,48246,48247,48248,48249,48250,48251,48252,48253,
+48254,48255,48256,48257,48258,48259,48262,48263,48265,48266,48269,48271,48272,
+48273,48274,48275,48278,48280,48283,48284,48285,48286,48287,48290,48291,48293,
+48294,48297,48298,48299,48300,48301,48302,48303,48306,48310,48311,48312,48313,
+48314,48315,48318,48319,48321,48322,48323,48325,48326,48327,48328,48329,48330,
+48331,48332,48334,48338,48339,48340,48342,48343,48345,48346,48347,48349,48350,
+48351,48352,48353,48354,48355,48356,48357,48358,48359,48360,48361,48362,48363,
+48364,48365,48366,48367,48368,48369,48370,48371,48375,48377,48378,48379,48381,
+48382,48383,48384,48385,48386,48387,48390,48392,48394,48395,48396,48397,48398,
+48399,48401,48402,48403,48405,48406,48407,48408,48409,48410,48411,48412,48413,
+U,U,U,U,U,U,48414,48415,48416,48417,48418,48419,48421,48422,48423,48424,48425,
+48426,48427,48429,48430,48431,48432,48433,48434,48435,48436,48437,48438,48439,
+48440,48441,U,U,U,U,U,U,48442,48443,48444,48445,48446,48447,48449,48450,48451,
+48452,48453,48454,48455,48458,48459,48461,48462,48463,48465,48466,48467,48468,
+48469,48470,48471,48474,48475,48476,48477,48478,48479,48480,48481,48482,48483,
+48485,48486,48487,48489,48490,48491,48492,48493,48494,48495,48496,48497,48498,
+48499,48500,48501,48502,48503,48504,48505,48506,48507,48508,48509,48510,48511,
+48514,48515,48517,48518,48523,48524,48525,48526,48527,48530,48532,48534,48535,
+48536,48539,48541,48542,48543,48544,48545,48546,48547,48549,48550,48551,48552,
+48553,48554,48555,48556,48557,48558,48559,48561,48562,48563,48564,48565,48566,
+48567,48569,48570,48571,48572,48573,48574,48575,48576,48577,48578,48579,48580,
+48581,48582,48583,48584,48585,48586,48587,48588,48589,48590,48591,48592,48593,
+48594,48595,48598,48599,48601,48602,48603,48605,48606,48607,48608,48609,48610,
+48611,48612,48613,48614,48615,48616,48618,48619,48620,48621,48622,48623,48625,
+U,U,U,U,U,U,48626,48627,48629,48630,48631,48633,48634,48635,48636,48637,48638,
+48639,48641,48642,48644,48646,48647,48648,48649,48650,48651,48654,48655,48657,
+48658,48659,U,U,U,U,U,U,48661,48662,48663,48664,48665,48666,48667,48670,48672,
+48673,48674,48675,48676,48677,48678,48679,48680,48681,48682,48683,48684,48685,
+48686,48687,48688,48689,48690,48691,48692,48693,48694,48695,48696,48697,48698,
+48699,48700,48701,48702,48703,48704,48705,48706,48707,48710,48711,48713,48714,
+48715,48717,48719,48720,48721,48722,48723,48726,48728,48732,48733,48734,48735,
+48738,48739,48741,48742,48743,48745,48747,48748,48749,48750,48751,48754,48758,
+48759,48760,48761,48762,48766,48767,48769,48770,48771,48773,48774,48775,48776,
+48777,48778,48779,48782,48786,48787,48788,48789,48790,48791,48794,48795,48796,
+48797,48798,48799,48800,48801,48802,48803,48804,48805,48806,48807,48809,48810,
+48811,48812,48813,48814,48815,48816,48817,48818,48819,48820,48821,48822,48823,
+48824,48825,48826,48827,48828,48829,48830,48831,48832,48833,48834,48835,48836,
+48837,48838,48839,48840,48841,48842,48843,48844,48845,48846,48847,48850,48851,
+U,U,U,U,U,U,48853,48854,48857,48858,48859,48860,48861,48862,48863,48865,48866,
+48870,48871,48872,48873,48874,48875,48877,48878,48879,48880,48881,48882,48883,
+48884,48885,U,U,U,U,U,U,48886,48887,48888,48889,48890,48891,48892,48893,48894,
+48895,48896,48898,48899,48900,48901,48902,48903,48906,48907,48908,48909,48910,
+48911,48912,48913,48914,48915,48916,48917,48918,48919,48922,48926,48927,48928,
+48929,48930,48931,48932,48933,48934,48935,48936,48937,48938,48939,48940,48941,
+48942,48943,48944,48945,48946,48947,48948,48949,48950,48951,48952,48953,48954,
+48955,48956,48957,48958,48959,48962,48963,48965,48966,48967,48969,48970,48971,
+48972,48973,48974,48975,48978,48979,48980,48982,48983,48984,48985,48986,48987,
+48988,48989,48990,48991,48992,48993,48994,48995,48996,48997,48998,48999,49000,
+49001,49002,49003,49004,49005,49006,49007,49008,49009,49010,49011,49012,49013,
+49014,49015,49016,49017,49018,49019,49020,49021,49022,49023,49024,49025,49026,
+49027,49028,49029,49030,49031,49032,49033,49034,49035,49036,49037,49038,49039,
+49040,49041,49042,49043,49045,49046,49047,49048,49049,49050,49051,49052,49053,
+U,U,U,U,U,U,49054,49055,49056,49057,49058,49059,49060,49061,49062,49063,49064,
+49065,49066,49067,49068,49069,49070,49071,49073,49074,49075,49076,49077,49078,
+49079,49080,U,U,U,U,U,U,49081,49082,49083,49084,49085,49086,49087,49088,49089,
+49090,49091,49092,49094,49095,49096,49097,49098,49099,49102,49103,49105,49106,
+49107,49109,49110,49111,49112,49113,49114,49115,49117,49118,49120,49122,49123,
+49124,49125,49126,49127,49128,49129,49130,49131,49132,49133,49134,49135,49136,
+49137,49138,49139,49140,49141,49142,49143,49144,49145,49146,49147,49148,49149,
+49150,49151,49152,49153,49154,49155,49156,49157,49158,49159,49160,49161,49162,
+49163,49164,49165,49166,49167,49168,49169,49170,49171,49172,49173,49174,49175,
+49176,49177,49178,49179,49180,49181,49182,49183,49184,49185,49186,49187,49188,
+49189,49190,49191,49192,49193,49194,49195,49196,49197,49198,49199,49200,49201,
+49202,49203,49204,49205,49206,49207,49208,49209,49210,49211,49213,49214,49215,
+49216,49217,49218,49219,49220,49221,49222,49223,49224,49225,49226,49227,49228,
+49229,49230,49231,49232,49234,49235,49236,49237,49238,49239,49241,49242,49243,
+U,U,U,U,U,U,49245,49246,49247,49249,49250,49251,49252,49253,49254,49255,49258,
+49259,49260,49261,49262,49263,49264,49265,49266,49267,49268,49269,49270,49271,
+49272,49273,U,U,U,U,U,U,49274,49275,49276,49277,49278,49279,49280,49281,49282,
+49283,49284,49285,49286,49287,49288,49289,49290,49291,49292,49293,49294,49295,
+49298,49299,49301,49302,49303,49305,49306,49307,49308,49309,49310,49311,49314,
+49316,49318,49319,49320,49321,49322,49323,49326,49329,49330,49335,49336,49337,
+49338,49339,49342,49346,49347,49348,49350,49351,49354,49355,49357,49358,49359,
+49361,49362,49363,49364,49365,49366,49367,49370,49374,49375,49376,49377,49378,
+49379,49382,49383,49385,49386,49387,49389,49390,49391,49392,49393,49394,49395,
+49398,49400,49402,49403,49404,49405,49406,49407,49409,49410,49411,49413,49414,
+49415,49417,49418,49419,49420,49421,49422,49423,49425,49426,49427,49428,49430,
+49431,49432,49433,49434,49435,49441,49442,49445,49448,49449,49450,49451,49454,
+49458,49459,49460,49461,49463,49466,49467,49469,49470,49471,49473,49474,49475,
+49476,49477,49478,49479,49482,49486,49487,49488,49489,49490,49491,49494,49495,
+U,U,U,U,U,U,49497,49498,49499,49501,49502,49503,49504,49505,49506,49507,49510,
+49514,49515,49516,49517,49518,49519,49521,49522,49523,49525,49526,49527,49529,
+49530,49531,U,U,U,U,U,U,49532,49533,49534,49535,49536,49537,49538,49539,49540,
+49542,49543,49544,49545,49546,49547,49551,49553,49554,49555,49557,49559,49560,
+49561,49562,49563,49566,49568,49570,49571,49572,49574,49575,49578,49579,49581,
+49582,49583,49585,49586,49587,49588,49589,49590,49591,49592,49593,49594,49595,
+49596,49598,49599,49600,49601,49602,49603,49605,49606,49607,49609,49610,49611,
+49613,49614,49615,49616,49617,49618,49619,49621,49622,49625,49626,49627,49628,
+49629,49630,49631,49633,49634,49635,49637,49638,49639,49641,49642,49643,49644,
+49645,49646,49647,49650,49652,49653,49654,49655,49656,49657,49658,49659,49662,
+49663,49665,49666,49667,49669,49670,49671,49672,49673,49674,49675,49678,49680,
+49682,49683,49684,49685,49686,49687,49690,49691,49693,49694,49697,49698,49699,
+49700,49701,49702,49703,49706,49708,49710,49712,49715,49717,49718,49719,49720,
+49721,49722,49723,49724,49725,49726,49727,49728,49729,49730,49731,49732,49733,
+U,U,U,U,U,U,49734,49735,49737,49738,49739,49740,49741,49742,49743,49746,49747,
+49749,49750,49751,49753,49754,49755,49756,49757,49758,49759,49761,49762,49763,
+49764,49766,U,U,U,U,U,U,49767,49768,49769,49770,49771,49774,49775,49777,49778,
+49779,49781,49782,49783,49784,49785,49786,49787,49790,49792,49794,49795,49796,
+49797,49798,49799,49802,49803,49804,49805,49806,49807,49809,49810,49811,49812,
+49813,49814,49815,49817,49818,49820,49822,49823,49824,49825,49826,49827,49830,
+49831,49833,49834,49835,49838,49839,49840,49841,49842,49843,49846,49848,49850,
+49851,49852,49853,49854,49855,49856,49857,49858,49859,49860,49861,49862,49863,
+49864,49865,49866,49867,49868,49869,49870,49871,49872,49873,49874,49875,49876,
+49877,49878,49879,49880,49881,49882,49883,49886,49887,49889,49890,49893,49894,
+49895,49896,49897,49898,49902,49904,49906,49907,49908,49909,49911,49914,49917,
+49918,49919,49921,49922,49923,49924,49925,49926,49927,49930,49931,49934,49935,
+49936,49937,49938,49942,49943,49945,49946,49947,49949,49950,49951,49952,49953,
+49954,49955,49958,49959,49962,49963,49964,49965,49966,49967,49968,49969,49970,
+U,U,U,U,U,U,49971,49972,49973,49974,49975,49976,49977,49978,49979,49980,49981,
+49982,49983,49984,49985,49986,49987,49988,49990,49991,49992,49993,49994,49995,
+49996,49997,U,U,U,U,U,U,49998,49999,50000,50001,50002,50003,50004,50005,50006,
+50007,50008,50009,50010,50011,50012,50013,50014,50015,50016,50017,50018,50019,
+50020,50021,50022,50023,50026,50027,50029,50030,50031,50033,50035,50036,50037,
+50038,50039,50042,50043,50046,50047,50048,50049,50050,50051,50053,50054,50055,
+50057,50058,50059,50061,50062,50063,50064,50065,50066,50067,50068,50069,50070,
+50071,50072,50073,50074,50075,50076,50077,50078,50079,50080,50081,50082,50083,
+50084,50085,50086,50087,50088,50089,50090,50091,50092,50093,50094,50095,50096,
+50097,50098,50099,50100,50101,50102,50103,50104,50105,50106,50107,50108,50109,
+50110,50111,50113,50114,50115,50116,50117,50118,50119,50120,50121,50122,50123,
+50124,50125,50126,50127,50128,50129,50130,50131,50132,50133,50134,50135,50138,
+50139,50141,50142,50145,50147,50148,50149,50150,50151,50154,50155,50156,50158,
+50159,50160,50161,50162,50163,50166,50167,50169,50170,50171,50172,50173,50174,
+U,U,U,U,U,U,50175,50176,50177,50178,50179,50180,50181,50182,50183,50185,50186,
+50187,50188,50189,50190,50191,50193,50194,50195,50196,50197,50198,50199,50200,
+50201,50202,U,U,U,U,U,U,50203,50204,50205,50206,50207,50208,50209,50210,50211,
+50213,50214,50215,50216,50217,50218,50219,50221,50222,50223,50225,50226,50227,
+50229,50230,50231,50232,50233,50234,50235,50238,50239,50240,50241,50242,50243,
+50244,50245,50246,50247,50249,50250,50251,50252,50253,50254,50255,50256,50257,
+50258,50259,50260,50261,50262,50263,50264,50265,50266,50267,50268,50269,50270,
+50271,50272,50273,50274,50275,50278,50279,50281,50282,50283,50285,50286,50287,
+50288,50289,50290,50291,50294,50295,50296,50298,50299,50300,50301,50302,50303,
+50305,50306,50307,50308,50309,50310,50311,50312,50313,50314,50315,50316,50317,
+50318,50319,50320,50321,50322,50323,50325,50326,50327,50328,50329,50330,50331,
+50333,50334,50335,50336,50337,50338,50339,50340,50341,50342,50343,50344,50345,
+50346,50347,50348,50349,50350,50351,50352,50353,50354,50355,50356,50357,50358,
+50359,50361,50362,50363,50365,50366,50367,50368,50369,50370,50371,50372,50373,
+U,U,U,U,U,U,50374,50375,50376,50377,50378,50379,50380,50381,50382,50383,50384,
+50385,50386,50387,50388,50389,50390,50391,50392,50393,50394,50395,50396,50397,
+50398,50399,U,U,U,U,U,U,50400,50401,50402,50403,50404,50405,50406,50407,50408,
+50410,50411,50412,50413,50414,50415,50418,50419,50421,50422,50423,50425,50427,
+50428,50429,50430,50434,50435,50436,50437,50438,50439,50440,50441,50442,50443,
+50445,50446,50447,50449,50450,50451,50453,50454,50455,50456,50457,50458,50459,
+50461,50462,50463,50464,50465,50466,50467,50468,50469,50470,50471,50474,50475,
+50477,50478,50479,50481,50482,50483,50484,50485,50486,50487,50490,50492,50494,
+50495,50496,50497,50498,50499,50502,50503,50507,50511,50512,50513,50514,50518,
+50522,50523,50524,50527,50530,50531,50533,50534,50535,50537,50538,50539,50540,
+50541,50542,50543,50546,50550,50551,50552,50553,50554,50555,50558,50559,50561,
+50562,50563,50565,50566,50568,50569,50570,50571,50574,50576,50578,50579,50580,
+50582,50585,50586,50587,50589,50590,50591,50593,50594,50595,50596,50597,50598,
+50599,50600,50602,50603,50604,50605,50606,50607,50608,50609,50610,50611,50614,
+U,U,U,U,U,U,50615,50618,50623,50624,50625,50626,50627,50635,50637,50639,50642,
+50643,50645,50646,50647,50649,50650,50651,50652,50653,50654,50655,50658,50660,
+50662,50663,U,U,U,U,U,U,50664,50665,50666,50667,50671,50673,50674,50675,50677,
+50680,50681,50682,50683,50690,50691,50692,50697,50698,50699,50701,50702,50703,
+50705,50706,50707,50708,50709,50710,50711,50714,50717,50718,50719,50720,50721,
+50722,50723,50726,50727,50729,50730,50731,50735,50737,50738,50742,50744,50746,
+50748,50749,50750,50751,50754,50755,50757,50758,50759,50761,50762,50763,50764,
+50765,50766,50767,50770,50774,50775,50776,50777,50778,50779,50782,50783,50785,
+50786,50787,50788,50789,50790,50791,50792,50793,50794,50795,50797,50798,50800,
+50802,50803,50804,50805,50806,50807,50810,50811,50813,50814,50815,50817,50818,
+50819,50820,50821,50822,50823,50826,50828,50830,50831,50832,50833,50834,50835,
+50838,50839,50841,50842,50843,50845,50846,50847,50848,50849,50850,50851,50854,
+50856,50858,50859,50860,50861,50862,50863,50866,50867,50869,50870,50871,50875,
+50876,50877,50878,50879,50882,50884,50886,50887,50888,50889,50890,50891,50894,
+U,U,U,U,U,U,50895,50897,50898,50899,50901,50902,50903,50904,50905,50906,50907,
+50910,50911,50914,50915,50916,50917,50918,50919,50922,50923,50925,50926,50927,
+50929,50930,U,U,U,U,U,U,50931,50932,50933,50934,50935,50938,50939,50940,50942,
+50943,50944,50945,50946,50947,50950,50951,50953,50954,50955,50957,50958,50959,
+50960,50961,50962,50963,50966,50968,50970,50971,50972,50973,50974,50975,50978,
+50979,50981,50982,50983,50985,50986,50987,50988,50989,50990,50991,50994,50996,
+50998,51000,51001,51002,51003,51006,51007,51009,51010,51011,51013,51014,51015,
+51016,51017,51019,51022,51024,51033,51034,51035,51037,51038,51039,51041,51042,
+51043,51044,51045,51046,51047,51049,51050,51052,51053,51054,51055,51056,51057,
+51058,51059,51062,51063,51065,51066,51067,51071,51072,51073,51074,51078,51083,
+51084,51085,51087,51090,51091,51093,51097,51099,51100,51101,51102,51103,51106,
+51111,51112,51113,51114,51115,51118,51119,51121,51122,51123,51125,51126,51127,
+51128,51129,51130,51131,51134,51138,51139,51140,51141,51142,51143,51146,51147,
+51149,51151,51153,51154,51155,51156,51157,51158,51159,51161,51162,51163,51164,
+U,U,U,U,U,U,51166,51167,51168,51169,51170,51171,51173,51174,51175,51177,51178,
+51179,51181,51182,51183,51184,51185,51186,51187,51188,51189,51190,51191,51192,
+51193,51194,U,U,U,U,U,U,51195,51196,51197,51198,51199,51202,51203,51205,51206,
+51207,51209,51211,51212,51213,51214,51215,51218,51220,51223,51224,51225,51226,
+51227,51230,51231,51233,51234,51235,51237,51238,51239,51240,51241,51242,51243,
+51246,51248,51250,51251,51252,51253,51254,51255,51257,51258,51259,51261,51262,
+51263,51265,51266,51267,51268,51269,51270,51271,51274,51275,51278,51279,51280,
+51281,51282,51283,51285,51286,51287,51288,51289,51290,51291,51292,51293,51294,
+51295,51296,51297,51298,51299,51300,51301,51302,51303,51304,51305,51306,51307,
+51308,51309,51310,51311,51314,51315,51317,51318,51319,51321,51323,51324,51325,
+51326,51327,51330,51332,51336,51337,51338,51342,51343,51344,51345,51346,51347,
+51349,51350,51351,51352,51353,51354,51355,51356,51358,51360,51362,51363,51364,
+51365,51366,51367,51369,51370,51371,51372,51373,51374,51375,51376,51377,51378,
+51379,51380,51381,51382,51383,51384,51385,51386,51387,51390,51391,51392,51393,
+U,U,U,U,U,U,51394,51395,51397,51398,51399,51401,51402,51403,51405,51406,51407,
+51408,51409,51410,51411,51414,51416,51418,51419,51420,51421,51422,51423,51426,
+51427,51429,U,U,U,U,U,U,51430,51431,51432,51433,51434,51435,51436,51437,51438,
+51439,51440,51441,51442,51443,51444,51446,51447,51448,51449,51450,51451,51454,
+51455,51457,51458,51459,51463,51464,51465,51466,51467,51470,51472,51474,51475,
+51476,51477,51478,51479,51481,51482,51483,51484,51485,51486,51487,51488,51489,
+51490,51491,51492,51493,51494,51495,51496,51497,51498,51499,U,U,U,U,U,U,51501,
+51502,51503,51504,51505,51506,51507,51509,51510,51511,51512,51513,51514,51515,
+51516,51517,51518,51519,51520,51521,51522,51523,51524,51525,51526,51527,U,U,U,
+U,U,U,51528,51529,51530,51531,51532,51533,51534,51535,51538,51539,51541,51542,
+51543,51545,51546,51547,51548,51549,51550,51551,51554,51556,51557,51558,51559,
+51560,51561,51562,51563,51565,51566,51567,51569,51570,51571,51573,51574,51575,
+51576,51577,51578,51579,51581,51582,51583,51584,51585,51586,51587,51588,51589,
+51590,51591,51594,51595,51597,51598,51599,U,U,U,U,U,U,51601,51602,51603,51604,
+51605,51606,51607,51610,51612,51614,51615,51616,51617,51618,51619,51620,51621,
+51622,51623,51624,51625,51626,51627,51628,51629,51630,U,U,U,U,U,U,51631,51632,
+51633,51634,51635,51636,51637,51638,51639,51640,51641,51642,51643,51644,51645,
+51646,51647,51650,51651,51653,51654,51657,51659,51660,51661,51662,51663,51666,
+51668,51671,51672,51675,51678,51679,51681,51683,51685,51686,51688,51689,51690,
+51691,51694,51698,51699,51700,51701,51702,51703,51706,51707,51709,51710,51711,
+51713,51714,51715,51716,U,U,U,U,U,U,51717,51718,51719,51722,51726,51727,51728,
+51729,51730,51731,51733,51734,51735,51737,51738,51739,51740,51741,51742,51743,
+51744,51745,51746,51747,51748,51749,U,U,U,U,U,U,51750,51751,51752,51754,51755,
+51756,51757,51758,51759,51760,51761,51762,51763,51764,51765,51766,51767,51768,
+51769,51770,51771,51772,51773,51774,51775,51776,51777,51778,51779,51780,51781,
+51782,51783,51784,51785,51786,51787,51790,51791,51793,51794,51795,51797,51798,
+51799,51800,51801,51802,51803,51806,51810,51811,51812,51813,51814,51815,51817,
+51818,U,U,U,U,U,U,51819,51820,51821,51822,51823,51824,51825,51826,51827,51828,
+51829,51830,51831,51832,51833,51834,51835,51836,51838,51839,51840,51841,51842,
+51843,51845,51846,U,U,U,U,U,U,51847,51848,51849,51850,51851,51852,51853,51854,
+51855,51856,51857,51858,51859,51860,51861,51862,51863,51865,51866,51867,51868,
+51869,51870,51871,51872,51873,51874,51875,51876,51877,51878,51879,51880,51881,
+51882,51883,51884,51885,51886,51887,51888,51889,51890,51891,51892,51893,51894,
+51895,51896,51897,51898,51899,51902,51903,51905,51906,51907,51909,U,U,U,U,U,U,
+51910,51911,51912,51913,51914,51915,51918,51920,51922,51924,51925,51926,51927,
+51930,51931,51932,51933,51934,51935,51937,51938,51939,51940,51941,51942,51943,
+U,U,U,U,U,U,51944,51945,51946,51947,51949,51950,51951,51952,51953,51954,51955,
+51957,51958,51959,51960,51961,51962,51963,51964,51965,51966,51967,51968,51969,
+51970,51971,51972,51973,51974,51975,51977,51978,51979,51980,51981,51982,51983,
+51985,51986,51987,51989,51990,51991,51993,51994,51995,51996,51997,51998,51999,
+52002,52003,52004,52005,52006,52007,52008,52009,U,U,U,U,U,U,52010,52011,52012,
+52013,52014,52015,52016,52017,52018,52019,52020,52021,52022,52023,52024,52025,
+52026,52027,52028,52029,52030,52031,52032,52034,52035,52036,U,U,U,U,U,U,52037,
+52038,52039,52042,52043,52045,52046,52047,52049,52050,52051,52052,52053,52054,
+52055,52058,52059,52060,52062,52063,52064,52065,52066,52067,52069,52070,52071,
+52072,52073,52074,52075,52076,52077,52078,52079,52080,52081,52082,52083,52084,
+52085,52086,52087,52090,52091,52092,52093,52094,52095,52096,52097,52098,52099,
+52100,52101,52102,52103,52104,U,U,U,U,U,U,52105,52106,52107,52108,52109,52110,
+52111,52112,52113,52114,52115,52116,52117,52118,52119,52120,52121,52122,52123,
+52125,52126,52127,52128,52129,52130,52131,U,U,U,U,U,U,52132,52133,52134,52135,
+52136,52137,52138,52139,52140,52141,52142,52143,52144,52145,52146,52147,52148,
+52149,52150,52151,52153,52154,52155,52156,52157,52158,52159,52160,52161,52162,
+52163,52164,52165,52166,52167,52168,52169,52170,52171,52172,52173,52174,52175,
+52176,52177,52178,52179,52181,52182,52183,52184,52185,52186,52187,52188,52189,
+52190,52191,U,U,U,U,U,U,52192,52193,52194,52195,52197,52198,52200,52202,52203,
+52204,52205,52206,52207,52208,52209,52210,52211,52212,52213,52214,52215,52216,
+52217,52218,52219,52220,U,U,U,U,U,U,52221,52222,52223,52224,52225,52226,52227,
+52228,52229,52230,52231,52232,52233,52234,52235,52238,52239,52241,52242,52243,
+52245,52246,52247,52248,52249,52250,52251,52254,52255,52256,52259,52260,52261,
+52262,52266,52267,52269,52271,52273,52274,52275,52276,52277,52278,52279,52282,
+52287,52288,52289,52290,52291,52294,52295,52297,52298,52299,52301,52302,U,U,U,
+U,U,U,52303,52304,52305,52306,52307,52310,52314,52315,52316,52317,52318,52319,
+52321,52322,52323,52325,52327,52329,52330,52331,52332,52333,52334,52335,52337,
+52338,U,U,U,U,U,U,52339,52340,52342,52343,52344,52345,52346,52347,52348,52349,
+52350,52351,52352,52353,52354,52355,52356,52357,52358,52359,52360,52361,52362,
+52363,52364,52365,52366,52367,52368,52369,52370,52371,52372,52373,52374,52375,
+52378,52379,52381,52382,52383,52385,52386,52387,52388,52389,52390,52391,52394,
+52398,52399,52400,52401,52402,52403,52406,52407,52409,U,U,U,U,U,U,52410,52411,
+52413,52414,52415,52416,52417,52418,52419,52422,52424,52426,52427,52428,52429,
+52430,52431,52433,52434,52435,52437,52438,52439,52440,52441,52442,U,U,U,U,U,U,
+52443,52444,52445,52446,52447,52448,52449,52450,52451,52453,52454,52455,52456,
+52457,52458,52459,52461,52462,52463,52465,52466,52467,52468,52469,52470,52471,
+52472,52473,52474,52475,52476,52477,52478,52479,52480,52482,52483,52484,52485,
+52486,52487,52490,52491,52493,52494,52495,52497,52498,52499,52500,52501,52502,
+52503,52506,52508,52510,52511,52512,U,U,U,U,U,U,52513,52514,52515,52517,52518,
+52519,52521,52522,52523,52525,52526,52527,52528,52529,52530,52531,52532,52533,
+52534,52535,52536,52538,52539,52540,52541,52542,U,U,U,U,U,U,52543,52544,52545,
+52546,52547,52548,52549,52550,52551,52552,52553,52554,52555,52556,52557,52558,
+52559,52560,52561,52562,52563,52564,52565,52566,52567,52568,52569,52570,52571,
+52573,52574,52575,52577,52578,52579,52581,52582,52583,52584,52585,52586,52587,
+52590,52592,52594,52595,52596,52597,52598,52599,52601,52602,52603,52604,52605,
+52606,52607,52608,U,U,U,U,U,U,52609,52610,52611,52612,52613,52614,52615,52617,
+52618,52619,52620,52621,52622,52623,52624,52625,52626,52627,52630,52631,52633,
+52634,52635,52637,52638,52639,U,U,U,U,U,U,52640,52641,52642,52643,52646,52648,
+52650,52651,52652,52653,52654,52655,52657,52658,52659,52660,52661,52662,52663,
+52664,52665,52666,52667,52668,52669,52670,52671,52672,52673,52674,52675,52677,
+52678,52679,52680,52681,52682,52683,52685,52686,52687,52689,52690,52691,52692,
+52693,52694,52695,52696,52697,52698,52699,52700,52701,52702,52703,52704,52705,
+U,U,U,U,U,U,52706,52707,52708,52709,52710,52711,52713,52714,52715,52717,52718,
+52719,52721,52722,52723,52724,52725,52726,52727,52730,52732,52734,52735,52736,
+52737,52738,U,U,U,U,U,U,52739,52741,52742,52743,52745,52746,52747,52749,52750,
+52751,52752,52753,52754,52755,52757,52758,52759,52760,52762,52763,52764,52765,
+52766,52767,52770,52771,52773,52774,52775,52777,52778,52779,52780,52781,52782,
+52783,52786,52788,52790,52791,52792,52793,52794,52795,52796,52797,52798,52799,
+52800,52801,52802,52803,52804,52805,52806,52807,52808,52809,U,U,U,U,U,U,52810,
+52811,52812,52813,52814,52815,52816,52817,52818,52819,52820,52821,52822,52823,
+52826,52827,52829,52830,52834,52835,52836,52837,52838,52839,52842,52844,U,U,U,
+U,U,U,52846,52847,52848,52849,52850,52851,52854,52855,52857,52858,52859,52861,
+52862,52863,52864,52865,52866,52867,52870,52872,52874,52875,52876,52877,52878,
+52879,52882,52883,52885,52886,52887,52889,52890,52891,52892,52893,52894,52895,
+52898,52902,52903,52904,52905,52906,52907,52910,52911,52912,52913,52914,52915,
+52916,52917,52918,52919,52920,52921,52922,U,U,U,U,U,U,52923,52924,52925,52926,
+52927,52928,52930,52931,52932,52933,52934,52935,52936,52937,52938,52939,52940,
+52941,52942,52943,52944,52945,52946,52947,52948,52949,U,U,U,U,U,U,52950,52951,
+52952,52953,52954,52955,52956,52957,52958,52959,52960,52961,52962,52963,52966,
+52967,52969,52970,52973,52974,52975,52976,52977,52978,52979,52982,52986,52987,
+52988,52989,52990,52991,52994,52995,52997,52998,52999,53001,53002,53003,53004,
+53005,53006,53007,53010,53012,53014,53015,53016,53017,53018,53019,53021,53022,
+53023,53025,53026,53027,U,U,U,U,U,U,53029,53030,53031,53032,53033,53034,53035,
+53038,53042,53043,53044,53045,53046,53047,53049,53050,53051,53052,53053,53054,
+53055,53056,53057,53058,53059,53060,U,U,U,U,U,U,53061,53062,53063,53064,53065,
+53066,53067,53068,53069,53070,53071,53072,53073,53074,53075,53078,53079,53081,
+53082,53083,53085,53086,53087,53088,53089,53090,53091,53094,53096,53098,53099,
+53100,53101,53102,53103,53106,53107,53109,53110,53111,53113,53114,53115,53116,
+53117,53118,53119,53121,53122,53123,53124,53126,53127,53128,53129,53130,53131,
+53133,U,U,U,U,U,U,53134,53135,53136,53137,53138,53139,53140,53141,53142,53143,
+53144,53145,53146,53147,53148,53149,53150,53151,53152,53154,53155,53156,53157,
+53158,53159,53161,U,U,U,U,U,U,53162,53163,53164,53165,53166,53167,53169,53170,
+53171,53172,53173,53174,53175,53176,53177,53178,53179,53180,53181,53182,53183,
+53184,53185,53186,53187,53189,53190,53191,53192,53193,53194,53195,53196,53197,
+53198,53199,53200,53201,53202,53203,53204,53205,53206,53207,53208,53209,53210,
+53211,53212,53213,53214,53215,53218,53219,53221,53222,53223,53225,U,U,U,U,U,U,
+53226,53227,53228,53229,53230,53231,53234,53236,53238,53239,53240,53241,53242,
+53243,53245,53246,53247,53249,53250,53251,53253,53254,53255,53256,53257,53258,
+U,U,U,U,U,U,53259,53260,53261,53262,53263,53264,53266,53267,53268,53269,53270,
+53271,53273,53274,53275,53276,53277,53278,53279,53280,53281,53282,53283,53284,
+53285,53286,53287,53288,53289,53290,53291,53292,53294,53295,53296,53297,53298,
+53299,53302,53303,53305,53306,53307,53309,53310,53311,53312,53313,53314,53315,
+53318,53320,53322,53323,53324,53325,53326,53327,U,U,U,U,U,U,53329,53330,53331,
+53333,53334,53335,53337,53338,53339,53340,53341,53342,53343,53345,53346,53347,
+53348,53349,53350,53351,53352,53353,53354,53355,53358,53359,U,U,U,U,U,U,53361,
+53362,53363,53365,53366,53367,53368,53369,53370,53371,53374,53375,53376,53378,
+53379,53380,53381,53382,53383,53384,53385,53386,53387,53388,53389,53390,53391,
+53392,53393,53394,53395,53396,53397,53398,53399,53400,53401,53402,53403,53404,
+53405,53406,53407,53408,53409,53410,53411,53414,53415,53417,53418,53419,53421,
+53422,53423,53424,53425,53426,U,U,U,U,U,U,53427,53430,53432,53434,53435,53436,
+53437,53438,53439,53442,53443,53445,53446,53447,53450,53451,53452,53453,53454,
+53455,53458,53462,53463,53464,53465,53466,U,U,U,U,U,U,53467,53470,53471,53473,
+53474,53475,53477,53478,53479,53480,53481,53482,53483,53486,53490,53491,53492,
+53493,53494,53495,53497,53498,53499,53500,53501,53502,53503,53504,53505,53506,
+53507,53508,53509,53510,53511,53512,53513,53514,53515,53516,53518,53519,53520,
+53521,53522,53523,53524,53525,53526,53527,53528,53529,53530,53531,53532,53533,
+53534,53535,U,U,U,U,U,U,53536,53537,53538,53539,53540,53541,53542,53543,53544,
+53545,53546,53547,53548,53549,53550,53551,53554,53555,53557,53558,53559,53561,
+53563,53564,53565,53566,U,U,U,U,U,U,53567,53570,53574,53575,53576,53577,53578,
+53579,53582,53583,53585,53586,53587,53589,53590,53591,53592,53593,53594,53595,
+53598,53600,53602,53603,53604,53605,53606,53607,53609,53610,53611,53613,53614,
+53615,53616,53617,53618,53619,53620,53621,53622,53623,53624,53625,53626,53627,
+53629,53630,53631,53632,53633,53634,53635,53637,53638,53639,53641,53642,U,U,U,
+U,U,U,53643,53644,53645,53646,53647,53648,53649,53650,53651,53652,53653,53654,
+53655,53656,53657,53658,53659,53660,53661,53662,53663,53666,53667,53669,53670,
+53671,U,U,U,U,U,U,53673,53674,53675,53676,53677,53678,53679,53682,53684,53686,
+53687,53688,53689,53691,53693,53694,53695,53697,53698,53699,53700,53701,53702,
+53703,53704,53705,53706,53707,53708,53709,53710,53711,53712,53713,53714,53715,
+53716,53717,53718,53719,53721,53722,53723,53724,53725,53726,53727,53728,53729,
+53730,53731,53732,53733,53734,53735,53736,53737,53738,U,U,U,U,U,U,53739,53740,
+53741,53742,53743,53744,53745,53746,53747,53749,53750,53751,53753,53754,53755,
+53756,53757,53758,53759,53760,53761,53762,53763,53764,53765,53766,U,U,U,U,U,U,
+53768,53770,53771,53772,53773,53774,53775,53777,53778,53779,53780,53781,53782,
+53783,53784,53785,53786,53787,53788,53789,53790,53791,53792,53793,53794,53795,
+53796,53797,53798,53799,53800,53801,53802,53803,53806,53807,53809,53810,53811,
+53813,53814,53815,53816,53817,53818,53819,53822,53824,53826,53827,53828,53829,
+53830,53831,53833,53834,53835,53836,U,U,U,U,U,U,53837,53838,53839,53840,53841,
+53842,53843,53844,53845,53846,53847,53848,53849,53850,53851,53853,53854,53855,
+53856,53857,53858,53859,53861,53862,53863,53864,U,U,U,U,U,U,53865,53866,53867,
+53868,53869,53870,53871,53872,53873,53874,53875,53876,53877,53878,53879,53880,
+53881,53882,53883,53884,53885,53886,53887,53890,53891,53893,53894,53895,53897,
+53898,53899,53900,53901,53902,53903,53906,53907,53908,53910,53911,53912,53913,
+53914,53915,53917,53918,53919,53921,53922,53923,53925,53926,53927,53928,53929,
+53930,53931,53933,U,U,U,U,U,U,53934,53935,53936,53938,53939,53940,53941,53942,
+53943,53946,53947,53949,53950,53953,53955,53956,53957,53958,53959,53962,53964,
+53965,53966,53967,53968,53969,U,U,U,U,U,U,53970,53971,53973,53974,53975,53977,
+53978,53979,53981,53982,53983,53984,53985,53986,53987,53990,53991,53992,53993,
+53994,53995,53996,53997,53998,53999,54002,54003,54005,54006,54007,54009,54010,
+54011,54012,54013,54014,54015,54018,54020,54022,54023,54024,54025,54026,54027,
+54031,54033,54034,54035,54037,54039,54040,54041,54042,54043,54046,54050,54051,
+U,U,U,U,U,U,54052,54054,54055,54058,54059,54061,54062,54063,54065,54066,54067,
+54068,54069,54070,54071,54074,54078,54079,54080,54081,54082,54083,54086,54087,
+54088,54089,U,U,U,U,U,U,54090,54091,54092,54093,54094,54095,54096,54097,54098,
+54099,54100,54101,54102,54103,54104,54105,54106,54107,54108,54109,54110,54111,
+54112,54113,54114,54115,54116,54117,54118,54119,54120,54121,54122,54123,54124,
+54125,54126,54127,54128,54129,54130,54131,54132,54133,54134,54135,54136,54137,
+54138,54139,54142,54143,54145,54146,54147,54149,54150,54151,U,U,U,U,U,U,54152,
+54153,54154,54155,54158,54162,54163,54164,54165,54166,54167,54170,54171,54173,
+54174,54175,54177,54178,54179,54180,54181,54182,54183,54186,54188,54190,U,U,U,
+U,U,U,54191,54192,54193,54194,54195,54197,54198,54199,54201,54202,54203,54205,
+54206,54207,54208,54209,54210,54211,54214,54215,54218,54219,54220,54221,54222,
+54223,54225,54226,54227,54228,54229,54230,54231,54233,54234,54235,54236,54237,
+54238,54239,54240,54242,54244,54245,54246,54247,54248,54249,54250,54251,54254,
+54255,54257,54258,54259,54261,54262,54263,U,U,U,U,U,U,54264,54265,54266,54267,
+54270,54272,54274,54275,54276,54277,54278,54279,54281,54282,54283,54284,54285,
+54286,54287,54288,54289,54290,54291,54292,54293,54294,U,U,U,U,U,U,54295,54296,
+54297,54298,54299,54300,54302,54303,54304,54305,54306,54307,54308,54309,54310,
+54311,54312,54313,54314,54315,54316,54317,54318,54319,54320,54321,54322,54323,
+54324,54325,54326,54327,54328,54329,54330,54331,54332,54333,54334,54335,54337,
+54338,54339,54341,54342,54343,54344,54345,54346,54347,54348,54349,54350,54351,
+54352,54353,54354,54355,U,U,U,U,U,U,54356,54357,54358,54359,54360,54361,54362,
+54363,54365,54366,54367,54369,54370,54371,54373,54374,54375,54376,54377,54378,
+54379,54380,54382,54384,54385,54386,U,U,U,U,U,U,54387,54388,54389,54390,54391,
+54394,54395,54397,54398,54401,54403,54404,54405,54406,54407,54410,54412,54414,
+54415,54416,54417,54418,54419,54421,54422,54423,54424,54425,54426,54427,54428,
+54429,54430,54431,54432,54433,54434,54435,54436,54437,54438,54439,54440,54442,
+54443,54444,54445,54446,54447,54448,54449,54450,54451,54452,54453,54454,54455,
+54456,U,U,U,U,U,U,54457,54458,54459,54460,54461,54462,54463,54464,54465,54466,
+54467,54468,54469,54470,54471,54472,54473,54474,54475,54477,54478,54479,54481,
+54482,54483,54485,U,U,U,U,U,U,54486,54487,54488,54489,54490,54491,54493,54494,
+54496,54497,54498,54499,54500,54501,54502,54503,54505,54506,54507,54509,54510,
+54511,54513,54514,54515,54516,54517,54518,54519,54521,54522,54524,54526,54527,
+54528,54529,54530,54531,54533,54534,54535,54537,54538,54539,54541,54542,54543,
+54544,54545,54546,54547,54550,54552,54553,54554,54555,54556,54557,U,U,U,U,U,U,
+54558,54559,54560,54561,54562,54563,54564,54565,54566,54567,54568,54569,54570,
+54571,54572,54573,54574,54575,54576,54577,54578,54579,54580,54581,54582,54583,
+U,U,U,U,U,U,54584,54585,54586,54587,54590,54591,54593,54594,54595,54597,54598,
+54599,54600,54601,54602,54603,54606,54608,54610,54611,54612,54613,54614,54615,
+54618,54619,54621,54622,54623,54625,54626,54627,54628,54630,54631,54634,54636,
+54638,54639,54640,54641,54642,54643,54646,54647,54649,54650,54651,54653,54654,
+54655,54656,54657,54658,54659,54662,54666,54667,U,U,U,U,U,U,54668,54669,54670,
+54671,54673,54674,54675,54676,54677,54678,54679,54680,54681,54682,54683,54684,
+54685,54686,54687,54688,54689,54690,54691,54692,54694,54695,U,U,U,U,U,U,54696,
+54697,54698,54699,54700,54701,54702,54703,54704,54705,54706,54707,54708,54709,
+54710,54711,54712,54713,54714,54715,54716,54717,54718,54719,54720,54721,54722,
+54723,54724,54725,54726,54727,54730,54731,54733,54734,54735,54737,54739,54740,
+54741,54742,54743,54746,54748,54750,54751,54752,54753,54754,54755,54758,54759,
+54761,54762,54763,54765,54766,U,U,U,U,U,U,54767,54768,54769,54770,54771,54774,
+54776,54778,54779,54780,54781,54782,54783,54786,54787,54789,54790,54791,54793,
+54794,54795,54796,54797,54798,54799,54802,U,U,U,U,U,U,54806,54807,54808,54809,
+54810,54811,54813,54814,54815,54817,54818,54819,54821,54822,54823,54824,54825,
+54826,54827,54828,54830,54831,54832,54833,54834,54835,54836,54837,54838,54839,
+54842,54843,54845,54846,54847,54849,54850,54851,54852,54854,54855,54858,54860,
+54862,54863,54864,54866,54867,54870,54871,54873,54874,54875,54877,54878,54879,
+54880,54881,U,U,U,U,U,U,54882,54883,54884,54885,54886,54888,54890,54891,54892,
+54893,54894,54895,54898,54899,54901,54902,54903,54904,54905,54906,54907,54908,
+54909,54910,54911,54912,U,U,U,U,U,U,54913,54914,54916,54918,54919,54920,54921,
+54922,54923,54926,54927,54929,54930,54931,54933,54934,54935,54936,54937,54938,
+54939,54940,54942,54944,54946,54947,54948,54949,54950,54951,54953,54954,54955,
+54957,54958,54959,54961,54962,54963,54964,54965,54966,54967,54968,54970,54972,
+54973,54974,54975,54976,54977,54978,54979,54982,54983,54985,54986,54987,U,U,U,
+U,U,U,54989,54990,54991,54992,54994,54995,54997,54998,55000,55002,55003,55004,
+55005,55006,55007,55009,55010,55011,55013,55014,55015,55017,55018,55019,55020,
+55021,U,U,U,U,U,U,55022,55023,55025,55026,55027,55028,55030,55031,55032,55033,
+55034,55035,55038,55039,55041,55042,55043,55045,55046,55047,55048,55049,55050,
+55051,55052,55053,55054,55055,55056,55058,55059,55060,55061,55062,55063,55066,
+55067,55069,55070,55071,55073,55074,55075,55076,55077,55078,55079,55082,55084,
+55086,55087,55088,55089,55090,55091,55094,55095,55097,U,U,U,U,U,U,55098,55099,
+55101,55102,55103,55104,55105,55106,55107,55109,55110,55112,55114,55115,55116,
+55117,55118,55119,55122,55123,55125,55130,55131,55132,55133,55134,U,U,U,U,U,U,
+55135,55138,55140,55142,55143,55144,55146,55147,55149,55150,55151,55153,55154,
+55155,55157,55158,55159,55160,55161,55162,55163,55166,55167,55168,55170,55171,
+55172,55173,55174,55175,55178,55179,55181,55182,55183,55185,55186,55187,55188,
+55189,55190,55191,55194,55196,55198,55199,55200,55201,55202,55203,
+};
+
+static const struct dbcs_index cp949ext_decmap[256] = {
+{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{__cp949ext_decmap+0,65,254},{__cp949ext_decmap+190,
+65,254},{__cp949ext_decmap+380,65,254},{__cp949ext_decmap+570,65,254},{
+__cp949ext_decmap+760,65,254},{__cp949ext_decmap+950,65,254},{
+__cp949ext_decmap+1140,65,254},{__cp949ext_decmap+1330,65,254},{
+__cp949ext_decmap+1520,65,254},{__cp949ext_decmap+1710,65,254},{
+__cp949ext_decmap+1900,65,254},{__cp949ext_decmap+2090,65,254},{
+__cp949ext_decmap+2280,65,254},{__cp949ext_decmap+2470,65,254},{
+__cp949ext_decmap+2660,65,254},{__cp949ext_decmap+2850,65,254},{
+__cp949ext_decmap+3040,65,254},{__cp949ext_decmap+3230,65,254},{
+__cp949ext_decmap+3420,65,254},{__cp949ext_decmap+3610,65,254},{
+__cp949ext_decmap+3800,65,254},{__cp949ext_decmap+3990,65,254},{
+__cp949ext_decmap+4180,65,254},{__cp949ext_decmap+4370,65,254},{
+__cp949ext_decmap+4560,65,254},{__cp949ext_decmap+4750,65,254},{
+__cp949ext_decmap+4940,65,254},{__cp949ext_decmap+5130,65,254},{
+__cp949ext_decmap+5320,65,254},{__cp949ext_decmap+5510,65,254},{
+__cp949ext_decmap+5700,65,254},{__cp949ext_decmap+5890,65,254},{
+__cp949ext_decmap+6080,65,160},{__cp949ext_decmap+6176,65,160},{
+__cp949ext_decmap+6272,65,160},{__cp949ext_decmap+6368,65,160},{
+__cp949ext_decmap+6464,65,160},{__cp949ext_decmap+6560,65,160},{
+__cp949ext_decmap+6656,65,160},{__cp949ext_decmap+6752,65,160},{
+__cp949ext_decmap+6848,65,160},{__cp949ext_decmap+6944,65,160},{
+__cp949ext_decmap+7040,65,160},{__cp949ext_decmap+7136,65,160},{
+__cp949ext_decmap+7232,65,160},{__cp949ext_decmap+7328,65,160},{
+__cp949ext_decmap+7424,65,160},{__cp949ext_decmap+7520,65,160},{
+__cp949ext_decmap+7616,65,160},{__cp949ext_decmap+7712,65,160},{
+__cp949ext_decmap+7808,65,160},{__cp949ext_decmap+7904,65,160},{
+__cp949ext_decmap+8000,65,160},{__cp949ext_decmap+8096,65,160},{
+__cp949ext_decmap+8192,65,160},{__cp949ext_decmap+8288,65,160},{
+__cp949ext_decmap+8384,65,160},{__cp949ext_decmap+8480,65,160},{
+__cp949ext_decmap+8576,65,160},{__cp949ext_decmap+8672,65,160},{
+__cp949ext_decmap+8768,65,160},{__cp949ext_decmap+8864,65,160},{
+__cp949ext_decmap+8960,65,160},{__cp949ext_decmap+9056,65,160},{
+__cp949ext_decmap+9152,65,160},{__cp949ext_decmap+9248,65,160},{
+__cp949ext_decmap+9344,65,160},{__cp949ext_decmap+9440,65,160},{
+__cp949ext_decmap+9536,65,160},{__cp949ext_decmap+9632,65,82},{0,0,0},{0,0,0},
+{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
+};
+
+static const DBCHAR __cp949_encmap[33133] = {
+8750,N,N,8756,N,N,8535,8487,N,10275,N,N,8489,8807,N,8518,8510,10615,10616,
+8741,N,8786,8484,8748,10614,10284,N,10361,10358,10362,8751,N,N,N,N,N,N,10273,
+N,N,N,N,N,N,N,N,N,10274,N,N,N,N,N,N,8511,10282,N,N,N,N,N,10285,10540,N,N,N,N,
+N,N,10529,N,N,N,N,N,N,N,N,N,10531,N,N,N,N,N,N,8512,10538,N,N,N,N,N,10541,
+10530,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,10276,10532,N,N,N,N,N,N,N,N,N,
+10533,10278,10534,N,N,N,N,10535,N,N,N,N,N,N,10280,10536,10281,10537,N,N,N,N,N,
+N,10544,10287,10543,N,N,N,N,N,N,10283,10539,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,10286,10542,8743,N,N,N,N,N,N,N,N,8752,N,N,N,N,N,N,N,8744,8747,8746,8749,N,
+8745,9537,9538,9539,9540,9541,9542,9543,9544,9545,9546,9547,9548,9549,9550,
+9551,9552,9553,N,9554,9555,9556,9557,9558,9559,9560,N,N,N,N,N,N,N,9569,9570,
+9571,9572,9573,9574,9575,9576,9577,9578,9579,9580,9581,9582,9583,9584,9585,N,
+9586,9587,9588,9589,9590,9591,9592,11303,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11297,
+11298,11299,11300,11301,11302,11304,11305,11306,11307,11308,11309,11310,11311,
+11312,11313,11314,11315,11316,11317,11318,11319,11320,11321,11322,11323,11324,
+11325,11326,11327,11328,11329,11345,11346,11347,11348,11349,11350,11352,11353,
+11354,11355,11356,11357,11358,11359,11360,11361,11362,11363,11364,11365,11366,
+11367,11368,11369,11370,11371,11372,11373,11374,11375,11376,11377,N,11351,
+8490,N,N,8494,8495,N,N,8496,8497,N,N,8787,8788,N,N,N,8485,8486,N,N,N,N,N,N,N,
+N,N,8758,N,8519,8520,N,N,N,N,N,N,N,8536,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+10617,N,N,N,N,N,N,N,N,N,N,10618,N,10619,10620,10621,10622,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8806,8521,N,N,N,N,N,
+8757,N,N,N,N,N,N,N,N,N,10020,N,N,8800,N,N,N,N,N,N,N,N,N,N,8805,8802,N,N,N,
+10073,N,N,N,N,8522,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,10359,10360,N,N,N,N,N,N,10363,10364,10365,10366,N,9520,
+9521,9522,9523,9524,9525,9526,9527,9528,9529,N,N,N,N,N,N,9505,9506,9507,9508,
+9509,9510,9511,9512,9513,9514,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+8551,8552,8550,8553,8554,8789,8792,8790,8793,8791,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,8737,N,8738,8739,N,8531,8740,N,N,N,8532,8564,N,N,8565,N,N,N,8755,N,8754,
+N,N,N,N,N,N,N,N,8558,N,N,8560,8516,N,8528,N,N,N,N,8491,N,8572,8573,8571,8570,
+8562,8563,N,8753,N,N,N,N,N,8517,8561,N,N,N,N,N,N,8493,8559,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,8534,N,N,N,N,N,N,N,N,N,N,N,N,N,8513,8533,N,N,8514,8515,
+N,N,N,N,8556,8557,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8568,8569,N,N,
+8566,8567,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8769,N,N,N,N,N,N,N,N,N,N,N,8529,
+8530,10343,10344,10345,10346,10347,10348,10349,10350,10351,10352,10353,10354,
+10355,10356,10357,N,N,N,N,N,10599,10600,10601,10602,10603,10604,10605,10606,
+10607,10608,10609,10610,10611,10612,10613,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,10573,10574,10575,10576,10577,10578,10579,10580,10581,10582,
+10583,10584,10585,10586,10587,10588,10589,10590,10591,10592,10593,10594,10595,
+10596,10597,10598,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,10317,
+10318,10319,10320,10321,10322,10323,10324,10325,10326,10327,10328,10329,10330,
+10331,10332,10333,10334,10335,10336,10337,10338,10339,10340,10341,10342,9761,
+9772,9762,9773,N,N,N,N,N,N,N,N,9763,9800,9799,9774,9764,9794,9793,9775,9766,
+9798,9797,9777,9765,9796,9795,9776,9767,9788,9801,9802,9783,9803,9804,9778,
+9769,9790,9805,9806,9785,9807,9808,9780,9768,9809,9810,9784,9789,9811,9812,
+9779,9770,9813,9814,9786,9791,9815,9816,9781,9771,9817,9818,9787,9819,9820,
+9792,9821,9822,9823,9824,9825,9826,9827,9828,9782,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8774,N,N,N,N,N,N,N,N,N,N,N,N,N,8545,8544,N,
+8771,8775,8776,8779,8778,8777,8780,N,N,N,N,N,N,N,N,8547,8546,N,N,8762,8761,N,
+N,N,N,8549,8548,N,N,8760,8759,N,N,N,N,8543,8542,8770,N,N,8539,N,N,8541,8540,
+8772,8773,8538,8537,N,N,N,N,N,N,N,8783,8782,N,N,N,N,N,N,N,N,N,N,N,N,8784,N,
+8785,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8527,N,
+8526,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8764,8765,N,
+8768,8763,8766,N,8767,8781,8795,8796,N,8797,8794,8481,8482,8483,8488,N,N,N,N,
+8500,8501,8502,8503,8504,8505,8506,8507,8508,8509,N,8555,8498,8499,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+10785,10786,10787,10788,10789,10790,10791,10792,10793,10794,10795,10796,10797,
+10798,10799,10800,10801,10802,10803,10804,10805,10806,10807,10808,10809,10810,
+10811,10812,10813,10814,10815,10816,10817,10818,10819,10820,10821,10822,10823,
+10824,10825,10826,10827,10828,10829,10830,10831,10832,10833,10834,10835,10836,
+10837,10838,10839,10840,10841,10842,10843,10844,10845,10846,10847,10848,10849,
+10850,10851,10852,10853,10854,10855,10856,10857,10858,10859,10860,10861,10862,
+10863,10864,10865,10866,10867,N,N,N,N,N,N,N,N,N,N,N,N,N,11041,11042,11043,
+11044,11045,11046,11047,11048,11049,11050,11051,11052,11053,11054,11055,11056,
+11057,11058,11059,11060,11061,11062,11063,11064,11065,11066,11067,11068,11069,
+11070,11071,11072,11073,11074,11075,11076,11077,11078,11079,11080,11081,11082,
+11083,11084,11085,11086,11087,11088,11089,11090,11091,11092,11093,11094,11095,
+11096,11097,11098,11099,11100,11101,11102,11103,11104,11105,11106,11107,11108,
+11109,11110,11111,11112,11113,11114,11115,11116,11117,11118,11119,11120,11121,
+11122,11123,11124,11125,11126,9249,9250,9251,9252,9253,9254,9255,9256,9257,
+9258,9259,9260,9261,9262,9263,9264,9265,9266,9267,9268,9269,9270,9271,9272,
+9273,9274,9275,9276,9277,9278,9279,9280,9281,9282,9283,9284,9285,9286,9287,
+9288,9289,9290,9291,9292,9293,9294,9295,9296,9297,9298,9299,9300,9301,9302,
+9303,9304,9305,9306,9307,9308,9309,9310,9311,9312,9313,9314,9315,9316,9317,
+9318,9319,9320,9321,9322,9323,9324,9325,9326,9327,9328,9329,9330,9331,9332,
+9333,9334,9335,9336,9337,9338,9339,9340,9341,9342,10545,10546,10547,10548,
+10549,10550,10551,10552,10553,10554,10555,10556,10557,10558,10559,10560,10561,
+10562,10563,10564,10565,10566,10567,10568,10569,10570,10571,10572,8799,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,10289,10290,10291,10292,
+10293,10294,10295,10296,10297,10298,10299,10300,10301,10302,10303,10304,10305,
+10306,10307,10308,10309,10310,10311,10312,10313,10314,10315,10316,N,N,N,8798,
+10057,10058,10059,10060,10061,N,N,N,10042,10043,10076,10077,10078,10038,10039,
+10040,10068,10069,10070,10071,10072,10017,10018,10019,10021,10027,10028,10029,
+10030,10031,10032,10033,10034,10035,10036,10023,10024,10025,10026,10045,10046,
+10085,10086,10087,10088,10081,10082,10083,10047,10048,10049,10050,10051,10052,
+10053,10054,10055,10056,10062,10063,10064,10065,10066,10067,10074,10075,8803,
+10092,10022,10080,10095,8801,10044,10093,10037,N,N,N,N,10041,10090,N,N,10091,
+N,N,10079,N,8804,N,N,10084,10094,10089,27753,28491,N,30290,N,N,N,22578,27995,
+24370,24382,31035,N,23668,N,N,N,30052,N,N,29478,23904,24870,N,20088,23600,N,N,
+N,N,25386,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29033,N,N,N,N,19834,N,N,N,N,N,31791,
+21281,N,28971,N,N,N,N,N,N,26449,21036,N,20089,N,N,N,N,N,29053,N,24127,31546,
+31033,N,N,N,N,N,N,20050,N,25387,27488,N,N,N,20090,19319,25893,N,N,N,N,N,N,N,N,
+N,N,N,19041,N,21580,N,N,N,N,N,27233,N,N,23651,24365,N,N,N,N,N,N,19307,N,N,N,
+21807,N,N,N,22133,N,25976,N,N,24128,27683,N,26957,N,27175,26998,31547,N,26473,
+28492,N,N,20582,N,N,24129,N,N,25644,N,N,22604,31089,N,20063,31268,26162,N,
+31355,N,N,31293,19528,28493,21845,N,N,N,N,N,N,N,21282,N,N,N,27729,N,N,N,N,N,
+25639,27730,N,N,30257,N,N,20091,N,N,20561,19263,N,27940,N,N,N,N,N,N,27944,
+24130,30306,27996,23669,24633,N,N,N,21582,N,29749,N,N,N,21339,22069,27684,N,N,
+N,N,N,N,N,N,N,N,25702,N,29034,N,N,N,19308,19264,N,N,N,27762,20586,N,N,N,N,N,N,
+N,31090,27685,20575,N,26474,20587,23633,23401,32076,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,23383,N,N,N,N,23137,N,22070,N,25439,N,24131,N,
+24132,18977,N,N,N,N,N,28268,N,N,21283,28215,30799,N,N,N,N,27208,28216,28972,
+28965,26958,N,N,N,31036,N,N,N,25977,27754,23894,27970,N,N,N,N,N,N,N,N,N,N,N,N,
+30757,N,N,N,N,N,25914,23384,N,N,18978,N,N,20813,N,N,N,28269,N,N,N,27755,24133,
+N,25440,N,19017,29289,N,21838,N,30262,N,20034,22087,N,25396,N,28973,N,27234,N,
+N,N,N,22338,N,29479,N,N,19818,N,27502,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22834,
+32037,N,N,N,N,N,30293,21858,N,N,N,N,N,N,N,N,30773,N,N,19573,30005,25645,N,N,N,
+N,26475,29013,N,N,N,28731,N,N,26933,N,19529,31317,N,N,24916,N,N,22358,N,N,
+23617,N,24134,31343,25441,N,N,N,N,N,N,N,N,N,N,N,N,24947,23670,N,20092,N,23364,
+N,30833,N,N,23652,N,25967,23601,N,N,N,21846,N,N,29530,N,19265,N,23363,N,N,N,
+22906,21358,N,N,N,31288,N,N,32038,27503,N,29734,N,19530,29480,N,29531,N,23335,
+30263,N,20326,28786,19290,N,26450,22339,30320,26718,N,N,N,N,N,N,N,N,N,N,N,N,N,
+25894,N,N,N,N,N,N,N,25959,N,N,N,18979,19495,27209,N,N,N,N,N,30774,N,N,N,N,N,
+31269,N,N,N,N,28974,N,28494,N,N,N,N,N,N,N,N,19309,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+30256,28495,26959,N,30558,N,N,N,N,N,N,N,20051,N,N,N,N,23671,N,N,N,N,N,N,N,
+23336,N,N,N,19320,N,N,N,N,N,N,24353,23905,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+30026,26934,N,N,N,N,26476,28270,N,29552,N,24383,N,N,N,N,N,N,19531,N,N,N,N,N,N,
+20545,N,N,N,29778,24634,N,N,N,N,24384,N,20064,N,N,N,23634,32106,N,N,N,22134,N,
+N,N,27210,N,N,N,N,N,N,26729,N,25388,N,N,N,N,N,29520,N,N,N,N,N,N,N,N,N,N,N,
+18980,N,23416,N,N,N,24135,27504,29014,N,N,25954,N,19532,N,N,19323,N,N,N,N,N,N,
+N,N,27235,N,N,N,N,N,N,N,N,N,N,N,N,24385,N,22125,N,N,N,N,N,N,N,N,26960,N,N,N,N,
+N,N,N,28217,N,N,N,N,21859,N,N,20819,N,25968,N,N,N,26676,27459,N,27178,31356,
+30070,28732,32084,24635,20035,N,20538,30522,22643,30541,N,N,N,25646,N,N,N,N,N,
+N,N,N,N,21599,N,N,N,N,N,20583,N,N,27773,N,21038,28271,21847,27236,30754,19819,
+22335,31537,N,N,19820,N,N,N,23602,20588,20093,28272,N,N,N,19522,N,N,N,20589,N,
+N,N,N,N,25975,N,N,N,29564,N,N,28194,N,N,N,N,22835,N,N,22644,N,26935,N,N,N,N,N,
+N,N,N,20014,N,N,N,N,22818,N,N,N,N,22641,N,21583,N,N,N,N,N,N,N,N,N,25895,21842,
+N,N,N,N,N,22057,N,N,N,N,N,N,29730,N,29015,N,N,21848,N,28733,22352,21584,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,22351,27498,32107,N,N,23405,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+31813,19266,N,N,N,N,32085,N,29768,26730,30067,N,N,31070,21359,N,N,27731,N,N,
+23874,28471,26452,N,19018,N,N,N,22907,N,N,31357,N,N,N,N,N,22058,N,N,N,N,N,
+29816,N,N,N,N,N,N,30583,23596,N,N,N,22359,24354,N,N,N,20030,N,21360,N,N,N,N,N,
+28708,24940,20327,29515,27945,19006,N,N,N,N,N,N,N,29807,N,N,N,30286,N,N,24187,
+20539,21815,28273,N,N,N,N,N,N,29736,N,23672,N,N,N,N,19239,N,23118,N,N,N,24678,
+N,N,N,N,N,N,N,27941,28274,N,N,N,N,23673,N,N,31068,N,N,29532,N,N,N,N,N,N,N,
+30834,N,29817,N,N,N,31857,N,N,N,20540,23417,22321,N,N,N,19324,N,N,N,28709,
+19325,N,N,N,N,N,N,N,N,21876,N,N,N,19821,18981,N,N,22059,20546,N,N,N,N,28734,
+21053,19492,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31286,N,N,19533,N,23162,N,
+30287,N,26936,N,22645,N,N,N,19534,N,N,N,N,22349,N,N,21585,26989,N,19051,22882,
+N,32050,N,25389,22092,22836,N,N,24871,28243,20547,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+32051,N,21860,N,N,20328,N,27971,20530,N,N,20094,23080,30800,N,N,32086,N,N,N,N,
+30801,N,30802,23635,N,N,N,N,23906,31609,23873,N,25397,N,N,N,N,N,N,27997,20036,
+N,19233,N,N,N,N,N,N,23907,N,N,N,N,31837,N,N,N,N,N,N,N,N,N,31023,N,N,N,N,N,
+21115,20257,25640,N,29750,27774,N,N,25390,26477,32065,23138,N,N,22579,N,N,N,
+23908,28783,30321,31344,N,N,20853,N,N,23119,N,23636,N,23590,N,28479,N,N,N,N,N,
+20047,N,24665,N,N,N,N,N,N,22870,27732,27211,N,N,19007,21808,N,20329,N,N,N,N,N,
+29037,N,19535,N,N,N,N,25720,N,N,N,N,N,N,N,N,N,N,N,N,N,N,25709,N,N,N,N,22360,N,
+32039,N,N,N,N,27179,30258,N,N,N,N,20336,31037,N,N,N,N,N,N,26228,N,N,N,N,N,N,N,
+N,N,N,N,N,N,19291,N,N,N,N,N,N,N,29521,N,N,N,N,26961,29481,20576,26962,N,23139,
+N,N,N,N,N,N,25170,N,30242,24948,N,N,N,23140,N,N,N,N,N,26453,30015,20258,19759,
+20259,N,N,N,19760,29054,20515,24879,30755,N,18982,30523,29290,24136,26963,N,N,
+N,N,24137,32094,19008,N,N,N,31082,20814,28244,N,21586,22819,32040,22361,30542,
+31294,N,N,N,N,N,N,N,N,N,20310,N,22384,N,27489,30789,N,N,N,N,N,23674,N,N,23875,
+N,31071,N,N,N,N,N,N,N,26479,N,N,N,N,32101,30243,N,22908,32041,N,26478,N,N,N,
+21861,N,N,N,N,N,28496,N,19761,N,N,N,N,N,N,30498,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,28978,N,28977,N,N,N,N,N,N,19762,N,23083,N,18983,N,N,N,N,N,25442,
+31548,22820,N,N,28218,N,N,N,N,N,30803,N,N,N,N,N,31610,N,20260,N,23675,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30307,N,N,N,27946,N,N,29217,20065,N,N,N,N,N,N,
+31270,N,N,N,N,31072,N,N,N,N,27734,N,N,25710,31009,N,N,31599,N,N,N,31083,28195,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,27180,N,N,N,18984,N,N,29818,N,N,
+N,N,19798,31862,N,N,N,29769,N,N,N,N,N,N,N,30804,30758,N,24138,29254,N,N,N,N,N,
+N,22362,N,21328,N,N,N,N,N,N,N,N,N,N,N,22597,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,27238,N,29533,N,N,N,25690,N,N,N,N,N,N,N,N,30308,N,N,N,N,N,30322,N,24386,N,N,
+N,N,N,N,N,N,22909,N,N,N,19574,N,N,21306,N,N,N,N,N,N,N,25647,N,N,N,N,31073,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,28710,N,N,N,19283,N,N,N,24636,N,
+29770,21626,N,32042,31074,N,N,N,N,N,N,N,N,N,N,N,N,N,29751,32066,31792,N,32108,
+19042,N,N,N,N,N,N,N,N,N,32061,N,27239,24387,20818,20066,N,21284,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,32043,N,24416,N,N,N,N,N,N,N,N,N,N,N,N,29255,N,N,
+N,N,N,26480,N,20590,N,N,29482,N,N,N,24139,30264,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,24949,28979,30499,N,N,18985,N,N,N,N,N,N,N,N,N,N,20261,N,N,
+24388,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,24880,N,N,28735,N,30244,N,
+25398,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31302,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,20591,N,N,32109,N,N,N,N,N,N,N,N,23876,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,31863,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,26175,N,N,N,N,N,N,24109,N,31295,N,N,N,N,N,25969,N,N,N,N,N,N,N,
+27972,N,N,N,N,N,N,N,N,N,N,N,N,N,21029,N,N,32110,N,N,N,30006,N,N,N,N,N,N,N,N,
+24950,24140,N,N,31838,N,27735,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,19805,N,N,N,N,N,N,
+N,N,22071,19763,30805,25944,N,N,N,20330,N,N,20304,N,27212,N,N,N,N,27182,27181,
+N,N,21361,N,21285,N,N,N,N,N,N,30543,N,N,N,N,N,N,N,N,28196,N,N,N,N,20516,N,N,
+29218,N,N,N,N,N,N,N,N,N,N,20592,N,N,N,N,29219,N,30584,N,N,N,N,20531,N,N,23337,
+N,N,21307,19052,N,28966,19285,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30567,N,N,19806,N,
+30500,N,N,N,30784,N,N,N,21341,N,19536,N,N,N,N,20262,N,N,N,N,N,N,30323,N,N,N,N,
+N,24951,N,N,N,N,N,21340,N,N,31358,N,N,N,N,N,N,N,31271,N,N,N,N,N,N,N,N,N,N,N,N,
+27481,N,20263,27183,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,25711,N,N,N,26937,29016,N,N,22616,N,N,24690,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,26164,23676,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29553,N,N,N,25424,N,N,29307,N,
+23366,20593,N,20594,20316,N,21329,N,N,19505,30552,N,19240,27452,25662,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29788,N,N,23618,N,N,28711,N,N,26176,N,N,19053,N,
+N,N,N,26731,25960,23619,N,N,27998,21362,N,N,N,N,19575,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,20052,26411,N,N,N,19267,N,24881,N,N,30514,N,N,21363,21330,N,30016,N,N,N,
+24413,N,N,28275,26481,N,32052,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29256,N,N,N,
+29522,N,N,28276,N,25171,N,N,N,N,19537,N,24426,N,N,N,26938,N,N,N,N,N,N,N,N,N,
+22871,N,N,N,N,N,N,N,N,30029,N,29042,31303,N,N,N,N,N,N,N,N,22904,21570,N,N,N,N,
+30309,N,N,N,N,23877,N,N,N,N,N,N,26482,27999,N,N,19019,N,N,23418,N,N,N,26677,N,
+21286,N,N,N,N,N,N,32053,N,N,31049,N,25698,N,31549,N,N,22308,20037,N,N,N,N,
+20053,22118,N,N,N,N,25917,N,N,N,N,N,N,24141,27763,N,N,28000,N,N,N,N,N,N,N,N,N,
+27756,31550,24427,N,24952,31038,N,N,N,N,20595,24618,26722,N,N,25172,21117,N,
+25896,N,N,N,N,N,22867,N,N,N,N,21342,N,29752,30524,23677,N,26732,25703,N,N,
+25463,N,N,N,N,N,27688,N,N,N,N,N,N,31345,N,N,N,N,N,25970,N,N,20596,21039,23653,
+N,N,N,N,20517,28980,31793,19576,N,N,23878,31313,N,30559,N,N,31272,N,N,N,N,N,
+28277,N,24142,N,N,N,N,26483,N,N,30508,27460,28001,24619,23879,N,N,N,N,21043,
+21055,N,N,N,19020,N,N,N,N,31551,N,N,N,N,25981,23909,22605,N,N,N,N,N,27764,N,N,
+N,N,N,N,N,N,20597,N,N,26733,20562,N,22872,N,N,N,N,N,N,N,N,N,N,N,30310,N,N,
+23338,N,N,N,30560,N,N,N,N,N,N,N,N,N,N,N,N,22617,N,29731,N,N,29789,N,N,N,N,
+28497,N,N,22837,N,N,27947,N,25399,N,N,N,N,28219,19764,N,24691,27213,N,N,N,N,
+27765,26734,N,19241,28975,N,N,N,N,N,N,N,N,19021,N,27689,N,29291,N,32111,N,
+31091,N,N,N,N,N,N,N,N,N,26177,N,N,27736,N,N,N,27948,27214,N,26719,N,N,N,N,N,N,
+N,N,N,N,N,N,N,24143,N,N,N,N,N,N,21030,N,N,26484,20822,N,N,26178,25443,N,N,N,N,
+25648,N,N,N,22580,N,N,N,N,N,N,N,N,N,N,N,N,30245,N,N,N,N,N,29534,N,N,N,N,22309,
+N,N,N,N,30568,N,N,26694,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31590,N,N,N,N,N,N,N,
+23910,N,N,N,23678,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,22618,N,N,N,N,N,N,N,23084,27184,N,N,N,N,N,N,N,N,
+25400,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,18986,24953,N,
+27185,N,N,N,N,29292,N,N,31342,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,28245,N,
+N,N,N,31092,N,N,21100,31611,N,N,N,32112,N,24637,20067,N,N,N,N,N,N,N,N,N,30790,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,24110,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,24389,N,N,25918,N,N,N,N,N,N,N,N,N,N,N,N,27949,31338,N,N,19822,27942,N,
+27950,28781,N,23841,N,27951,31864,N,22635,N,N,N,19577,19765,N,N,N,N,31273,N,
+24925,N,N,N,N,25173,27983,N,N,N,23842,N,N,31050,N,27240,N,25965,N,N,N,N,N,N,N,
+N,21355,N,26964,24954,25676,N,24932,26695,N,N,20059,N,N,N,23637,N,30517,31859,
+28787,20015,28981,28498,26696,27505,N,N,N,N,N,19284,24638,25464,27241,31794,N,
+N,N,N,N,24692,N,20320,N,28197,N,N,31274,26179,24882,18987,N,25444,26939,N,N,N,
+N,N,25174,29554,N,28246,27186,20598,27737,23115,20264,N,N,N,N,23843,N,N,N,
+22619,N,31054,26965,25425,N,N,21052,N,N,N,N,N,N,22572,29516,N,19835,30294,N,
+26485,26735,25465,21051,29555,25467,N,24144,20016,N,22135,29017,N,N,N,N,N,
+30017,23620,N,30011,N,24145,23654,N,N,24146,N,N,28002,28278,27215,28782,25468,
+N,21343,21364,24883,N,24884,N,N,N,N,29779,N,N,24390,N,N,N,N,N,N,N,N,N,N,26966,
+N,N,N,23339,N,N,N,N,N,N,N,N,30246,N,N,N,N,N,N,25401,27461,29737,19766,21113,N,
+23085,21091,20305,N,N,N,N,19292,19578,N,20317,N,N,26665,N,25403,25402,N,N,
+24666,N,N,N,28279,N,N,N,N,N,23603,N,N,N,N,21365,N,22310,N,30261,22363,N,N,N,N,
+N,N,24917,N,N,21610,N,24355,N,N,N,N,N,N,N,32095,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,20599,27988,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,19242,N,N,N,N,N,N,N,
+25691,N,24955,19234,N,N,N,N,21344,N,25663,N,31552,N,23102,25677,N,22073,N,N,N,
+28480,N,24956,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30265,N,N,N,N,N,
+N,24391,N,N,N,N,N,N,N,25649,N,N,N,N,N,N,23655,23656,N,N,N,31318,N,21366,N,N,N,
+N,29018,N,31346,25213,N,N,N,N,N,21839,20600,N,N,19807,N,N,30027,N,25712,19243,
+N,22340,N,N,N,N,N,N,N,N,N,N,N,N,N,25214,N,23898,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,23086,19054,N,N,N,21817,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,25377,N,N,26723,N,N,29483,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,20265,N,N,N,21367,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+21617,N,N,20068,N,26738,N,N,N,N,N,N,N,25973,N,N,N,N,N,N,N,N,N,N,N,N,N,26414,N,
+22074,N,24428,25664,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,26724,N,N,N,N,22581,N,N,N,
+25692,N,N,N,N,N,N,29753,28982,N,N,25182,24885,N,N,19823,28967,20069,19293,N,N,
+22883,N,N,29484,N,N,20601,27691,24147,30569,N,N,31093,N,N,N,N,N,24926,19310,
+25404,30806,N,N,23406,N,N,N,N,N,32113,N,N,N,N,30518,N,N,N,N,29790,N,N,29293,N,
+23385,N,28712,N,N,N,N,N,N,N,24957,N,N,N,N,N,24148,N,24620,N,N,N,N,N,28003,N,N,
+21345,N,24392,N,N,N,N,22838,N,32044,28499,N,N,N,25665,30827,N,23340,N,N,N,N,
+31814,N,N,N,N,N,N,N,N,22573,N,N,N,N,N,N,N,N,N,30266,N,23391,21331,30791,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,19022,30785,21044,N,N,23604,31289,19023,N,31795,27242,
+27243,20602,N,N,N,N,N,28004,N,N,23911,N,N,24393,N,N,N,N,24429,N,N,N,N,N,28220,
+N,28481,N,N,19538,N,23844,N,N,N,24394,N,N,N,N,N,21368,28968,N,N,N,19767,N,
+28500,N,N,N,N,N,N,N,25693,24430,19244,26940,N,N,N,N,N,27244,N,N,N,24395,N,N,N,
+N,N,31039,22063,21830,N,N,N,N,N,20266,N,N,20009,N,N,22136,N,N,N,28983,28280,N,
+N,N,22873,29535,N,30792,20038,N,N,N,N,N,N,N,N,21862,N,N,N,N,N,N,29798,N,N,
+26181,28501,N,N,19311,31839,23591,N,N,22119,N,N,N,N,N,30793,N,N,N,N,25426,N,
+25405,N,20321,28736,27738,N,23895,31600,N,N,27692,N,N,N,28713,N,N,N,N,N,N,
+31319,31553,N,21056,N,N,N,N,N,N,N,25904,N,N,N,28005,N,N,N,N,19245,N,31024,N,N,
+N,N,N,N,N,N,N,N,N,30501,N,19246,N,23087,N,22582,N,N,N,N,N,N,N,21287,31538,N,
+32068,N,27693,N,N,N,N,N,N,31521,N,N,N,25961,26990,N,29556,30835,28737,24111,
+30768,N,N,29536,26415,N,N,N,N,N,23341,N,26165,N,N,31016,N,N,23896,26713,28502,
+N,N,N,21346,N,25183,N,N,31840,22344,32045,N,N,N,24431,19539,21369,N,N,N,N,
+21616,23367,24149,N,N,N,N,28788,N,21840,25945,N,N,N,N,N,N,31815,23638,25184,N,
+N,N,23088,N,N,N,N,N,N,29475,N,21356,N,29771,N,N,N,32069,N,N,N,N,N,25469,N,
+31025,N,N,N,N,N,N,20603,27739,N,N,N,N,N,N,N,N,30012,29220,22606,22607,N,N,N,N,
+N,N,30071,N,N,N,N,N,N,N,N,N,N,30305,N,N,N,N,N,N,N,N,N,21047,N,N,N,N,N,N,N,
+31596,N,23880,25704,N,N,21057,N,N,N,30807,N,N,N,N,N,22075,24150,N,N,30525,
+27694,N,N,N,20577,N,24693,27187,N,20054,N,N,N,N,19493,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,27766,25185,25406,N,N,N,N,N,N,N,N,N,31816,N,N,19824,N,31094,N,N,
+24432,N,N,N,25919,N,N,N,20031,N,N,N,N,31841,27952,32081,30267,N,N,31055,27482,
+19009,N,21048,19825,N,25427,32102,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+26221,N,N,N,25466,N,N,28714,31056,N,N,N,N,N,N,31842,N,30759,N,N,N,24933,28281,
+N,N,N,26486,27245,N,N,31796,30018,N,N,22364,N,N,N,N,N,N,N,N,28789,N,23912,
+21357,30076,N,23103,N,19579,N,N,N,21370,29732,N,N,N,N,N,N,N,28503,N,21571,N,N,
+N,N,N,N,N,N,N,31587,N,N,N,N,N,N,N,N,31597,N,24621,N,N,27246,31539,25666,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,30311,21085,N,24396,N,N,31817,N,N,25897,24694,30259,
+24958,N,N,N,N,19312,N,27247,27248,N,N,N,23104,30772,27506,N,N,N,N,N,25667,N,N,
+N,N,26967,25713,N,N,N,19055,N,N,N,N,N,N,N,20055,N,N,N,N,N,N,N,N,31818,N,N,N,
+29537,N,N,19268,N,N,N,N,25445,N,19269,27188,N,N,26941,N,22345,N,N,27483,27953,
+N,19523,30526,31819,N,N,N,N,N,N,30836,N,22839,N,N,29523,29524,N,N,N,30564,N,
+30545,N,N,22583,20017,19010,N,N,31540,19270,N,N,28790,N,N,21863,N,27216,N,N,N,
+N,N,19540,19247,N,N,N,N,N,29738,26927,N,N,30019,26968,N,N,N,N,N,N,N,23913,N,N,
+N,29043,N,21883,24123,N,N,29819,N,N,N,32115,32114,30502,N,N,N,N,N,N,N,N,N,
+23881,N,N,21587,N,19496,N,23105,19541,N,22884,N,N,N,31306,N,N,N,25955,N,N,N,
+21308,N,N,N,19056,N,N,N,N,20548,N,N,N,19024,31275,27499,26488,22885,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,20823,N,N,N,N,N,N,N,N,N,N,N,29476,N,
+N,N,21627,31843,31320,N,29525,N,20267,N,N,27507,21884,N,N,N,N,N,N,21332,19836,
+N,22886,N,25209,25121,27476,N,24695,25650,19580,N,N,N,31588,N,N,N,29739,N,N,N,
+N,20541,N,19057,N,N,N,N,N,N,N,N,28472,N,N,N,22336,N,28282,32116,N,N,21347,N,
+31554,N,N,N,N,N,N,N,21864,23342,24886,30775,N,N,N,N,N,24639,31555,23914,N,
+25122,N,28198,N,N,N,N,N,30312,N,N,N,N,30325,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,23882,N,N,20578,N,N,N,N,23846,N,N,23915,N,N,25721,N,N,25391,20604,N,N,
+N,29820,N,N,N,N,19516,30570,N,N,N,N,N,N,25956,24433,N,N,30561,N,31095,28473,N,
+N,30808,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31017,N,N,N,N,N,30809,N,N,N,28221,N,N,N,
+22598,N,N,25699,30030,N,N,N,N,23897,N,N,N,N,22887,21049,21827,N,N,23141,23120,
+N,20825,20056,N,19294,29740,23163,N,30313,26739,20268,28784,N,29821,23368,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,20032,25428,20815,29045,N,19826,N,20331,N,N,N,19768,
+N,N,N,N,N,N,25382,20826,29221,N,N,N,N,N,29222,N,25678,N,N,N,N,N,N,N,21371,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,28969,N,N,N,29257,N,N,N,N,N,N,N,
+N,N,N,28504,26185,N,22584,31347,N,N,N,N,N,N,N,N,N,N,29493,N,N,30756,N,N,20851,
+26184,N,N,N,N,30810,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,23657,24151,N,N,N,N,N,
+19295,N,N,N,20332,N,N,N,N,29791,N,N,20852,21050,N,N,N,24434,N,N,N,24887,N,N,N,
+N,25123,21372,N,N,28006,N,N,N,N,N,23369,N,N,N,25722,N,20318,N,N,20048,N,N,N,N,
+21843,29557,30510,N,N,28488,N,19827,30031,25971,28738,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,19025,N,N,N,27249,N,20518,N,N,N,N,N,N,N,N,22874,28715,N,N,N,
+N,N,27495,N,N,N,25920,31797,N,N,N,N,N,25668,N,N,N,N,N,N,N,N,N,N,N,19497,32070,
+N,N,N,N,N,27189,N,25898,24378,24927,N,23121,N,N,N,N,24888,N,26740,21373,N,N,N,
+N,25124,N,N,N,N,N,29258,N,N,N,N,N,N,N,N,N,23142,30515,N,N,N,N,N,N,N,N,N,N,N,N,
+32077,N,N,N,29494,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,28247,N,N,
+N,N,N,N,N,30020,N,N,N,N,N,N,N,N,22564,N,N,N,N,N,29223,N,N,N,N,N,N,N,N,22840,
+22841,28489,N,N,N,N,N,N,N,N,N,N,N,N,N,22094,N,N,N,N,N,N,N,N,30539,24366,26741,
+N,N,N,N,N,N,21045,N,N,N,21333,N,N,N,N,N,29772,23164,N,N,N,N,N,22888,N,30571,
+30025,N,29500,N,23122,N,N,N,N,N,N,N,N,21301,N,N,N,N,N,26678,N,N,22095,29754,N,
+30537,N,N,19498,N,N,28739,19542,N,N,N,20563,N,21309,N,N,N,23419,N,19296,N,N,N,
+N,N,N,21348,30327,N,N,21818,29517,19297,N,N,N,N,27508,N,N,N,N,N,29741,N,31786,
+N,N,N,N,N,30572,N,N,N,26742,23143,N,N,N,30540,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,25921,N,N,N,N,24686,N,N,N,N,N,21885,N,N,N,N,N,N,20070,31787,21819,N,N,
+29224,N,N,N,N,N,N,25125,19769,27250,19271,N,19828,N,N,23343,28505,N,N,N,N,N,
+19770,N,N,31865,N,N,N,N,24435,20071,23106,N,20269,N,N,N,N,26489,30760,N,N,N,N,
+N,N,29538,N,N,N,19058,24356,N,N,21572,N,N,N,N,N,19543,25922,N,N,N,N,19771,N,
+28506,28248,N,23847,25126,N,N,N,N,N,24640,N,N,N,22064,30794,N,31866,N,22910,N,
+N,N,N,24112,N,N,N,23916,23144,N,N,N,N,N,21600,N,22137,N,19799,24152,N,N,29304,
+N,25686,N,N,20549,29742,N,23848,N,N,N,27973,29526,N,N,24153,25446,N,N,N,N,N,N,
+21288,N,23344,N,N,25946,25407,N,N,N,23345,N,N,N,21865,N,N,N,N,N,24641,28507,N,
+N,28777,N,N,22322,N,N,N,N,20605,N,N,N,N,N,N,N,N,22889,N,N,20606,N,27757,21289,
+N,29225,28740,N,N,25186,26991,N,N,N,31057,N,N,26969,N,N,N,N,N,26714,23107,
+23108,21573,N,26490,19808,25392,N,23346,31556,N,29539,N,22821,31591,23883,
+20564,N,26166,24622,32090,N,N,N,N,N,N,N,N,23605,24696,26417,N,N,N,N,30064,N,
+22620,27974,N,N,N,N,24889,N,25408,31040,26992,N,N,22875,N,29540,N,N,N,23606,
+25705,N,N,N,N,N,28741,25409,31820,31821,N,N,N,N,29259,N,29260,N,N,N,25679,N,N,
+N,N,N,N,N,N,N,29019,N,31321,N,28984,32117,24697,N,N,N,N,26491,31799,31844,
+31557,25447,22585,N,30328,N,N,23621,19544,N,N,N,24623,29799,N,28508,20348,
+28509,N,29226,N,N,N,N,N,N,N,N,N,32062,N,N,18988,32059,32071,N,N,N,N,26418,N,
+27217,24436,N,N,N,N,20844,25694,25923,N,N,N,N,22822,N,N,19772,N,29541,N,N,N,N,
+N,N,N,N,27989,N,N,22842,N,N,N,28007,31541,30828,N,N,N,N,24679,N,19545,N,N,
+21574,N,N,N,N,N,26405,N,21877,21310,N,31867,N,N,N,N,N,N,N,N,N,N,N,N,25714,N,N,
+24437,N,N,26744,30829,N,N,20039,N,N,N,N,N,32118,N,N,N,N,N,N,N,N,N,26712,N,
+19800,26454,19546,N,N,19043,24438,28743,28742,N,22586,N,29044,29808,30028,N,N,
+31845,N,N,N,N,27205,27251,N,23899,N,23639,N,N,N,N,N,N,24189,29305,N,21831,N,N,
+N,22608,N,28744,20769,20770,N,N,N,N,N,N,22868,22120,22858,N,23089,22599,23650,
+29518,30068,N,N,28985,N,N,23123,N,30314,N,N,N,20341,N,N,32046,N,N,N,N,N,N,N,N,
+19026,N,N,24372,N,N,N,N,22365,31290,28199,30013,N,30837,N,N,28008,N,N,N,N,N,
+21601,N,20771,24918,N,N,N,N,N,N,N,N,N,N,N,N,N,31096,N,23370,19321,21588,N,
+22876,N,28222,N,30573,N,N,N,21102,N,N,24934,30585,N,N,N,N,N,N,N,23917,N,26715,
+N,23347,N,N,N,20855,24624,N,N,21602,N,30295,N,22393,N,N,22621,N,19837,29227,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,19773,30786,N,N,29228,N,N,18989,18990,20270,N,
+N,N,N,N,25410,N,N,N,N,N,23607,N,N,N,N,N,N,N,N,N,N,23386,22843,19059,30291,
+26232,27253,N,N,N,N,N,27254,N,N,30329,N,N,N,N,N,N,N,N,N,N,N,20271,N,N,19027,N,
+N,18991,21040,28986,N,22323,25411,29565,24154,N,N,N,N,24155,N,N,28510,25187,
+28283,N,N,24439,22346,N,N,N,N,N,N,N,N,N,20072,23387,N,N,N,N,N,N,N,28987,N,N,N,
+N,26993,N,N,N,N,N,N,N,N,31287,20550,N,N,19499,28200,N,N,19322,31097,19581,
+21374,N,N,N,N,25680,N,N,N,N,N,29294,N,21589,24397,N,31800,20816,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29261,N,N,N,N,N,N,N,N,30546,N,N,N,N,N,N,N,N,
+19028,N,21849,N,N,N,22622,N,N,N,N,N,N,N,N,N,19801,N,N,N,28201,30268,N,N,19547,
+N,N,N,N,N,28745,N,31868,N,26697,29822,N,N,N,N,26492,22366,N,N,N,N,24156,N,
+28716,19582,19809,N,24890,N,23407,23090,N,N,N,N,N,N,N,N,N,N,N,N,N,20773,23608,
+N,N,N,22646,N,20772,N,19810,N,N,N,N,23658,N,N,28791,N,28746,20542,N,23900,N,N,
+N,N,21590,21334,N,N,N,N,N,N,27984,19745,N,N,N,N,N,24373,N,N,N,24440,N,N,N,N,N,
+N,21537,20018,26698,N,N,N,N,27509,N,N,N,N,N,N,N,25429,30032,N,N,N,29985,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22823,N,N,N,N,N,N,N,N,25899,N,N,N,N,N,N,N,N,
+N,N,N,N,26187,N,30065,N,N,N,N,N,N,N,N,N,N,25925,N,N,N,N,N,N,N,N,31011,24667,
+30315,N,19313,N,22890,29986,N,N,N,22353,N,20856,27256,27257,23091,N,N,N,N,
+28511,N,N,29039,N,25974,28223,25188,N,N,N,N,N,20543,N,31276,30033,26419,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,26942,N,N,N,N,N,29262,23348,N,
+N,N,N,N,N,N,N,31822,N,23918,N,N,N,N,N,N,26420,N,N,N,N,N,22324,N,N,N,N,N,N,
+30516,N,N,N,N,N,19774,N,23145,N,N,N,N,N,N,N,20272,30553,29542,N,N,20057,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,20010,N,19272,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,20519,N,28747,N,20551,25669,N,N,N,N,N,N,N,23392,N,N,N,N,N,N,21850,N,
+22311,N,N,N,28224,N,30838,N,N,N,N,30034,28009,N,22844,N,25926,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,29987,N,N,23124,25127,31612,N,N,29020,N,N,N,N,N,N,19060,N,N,
+N,26746,N,N,20073,N,N,N,N,N,N,27000,25189,N,N,N,N,20537,21618,N,N,N,N,N,20774,
+N,24398,N,N,N,N,N,N,N,N,N,31860,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,21290,
+N,N,N,19500,N,N,N,N,28512,N,N,N,25957,20565,N,N,N,N,N,N,N,N,23420,N,N,N,N,
+31846,N,N,N,N,N,19326,28010,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,24113,N,N,N,N,N,N,N,
+31075,N,N,N,N,N,N,21538,20342,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22096,N,N,N,N,N,N,
+21866,29038,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31307,N,N,N,N,
+25889,21809,N,N,N,N,N,20333,N,28011,N,N,N,N,N,21810,N,N,N,21820,N,N,N,N,N,N,N,
+N,N,32098,29485,N,32091,N,N,N,N,N,N,N,N,N,N,N,N,N,N,26928,N,N,N,N,N,N,N,20775,
+N,N,32099,20019,N,N,N,N,N,N,N,32100,31310,N,N,N,N,18992,N,30503,N,20273,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,26146,N,31798,29229,28513,29486,23622,22891,N,N,N,26720,
+N,N,N,N,N,N,N,24872,N,N,N,N,21878,20349,N,N,24157,N,N,N,22865,N,N,N,25706,
+29263,N,30527,N,N,25190,25128,N,N,N,N,N,N,N,N,N,N,N,25430,N,27985,N,N,N,N,N,
+27001,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22065,24114,N,N,24680,N,N,21291,N,27484,N,
+N,24367,N,19011,N,N,28284,N,32067,N,N,N,27510,20274,N,N,N,N,22892,N,22845,N,
+22623,N,N,21560,27454,23919,N,23920,23921,23922,N,N,22846,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,31558,20275,28285,N,N,N,N,N,N,25643,N,23109,N,22636,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,20776,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,25129,N,N,24124,26421,N,N,
+N,N,N,23408,N,28514,29040,20276,N,N,N,N,N,N,N,N,N,N,N,23409,N,24625,N,N,N,N,
+24357,N,31058,N,N,26493,N,N,26147,31601,19248,29230,N,N,N,N,N,N,N,19815,N,
+26716,N,N,26455,N,N,30528,N,20579,N,N,N,23073,N,N,N,19517,N,N,20777,23884,N,N,
+25470,20778,26666,N,27190,31098,26188,30296,N,N,N,21575,N,N,N,22859,N,22866,
+21323,22647,23081,30072,N,N,24158,29231,30761,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+22600,N,N,28225,N,N,N,N,31041,N,N,N,N,23923,27258,N,30269,24891,19775,29780,
+26189,N,31823,31522,N,24668,N,N,N,N,29755,23125,N,31026,N,N,N,N,N,N,31602,N,
+23414,N,24159,N,N,N,23410,N,N,N,N,N,30812,30574,27496,N,21114,N,N,28988,N,N,
+31322,N,N,23146,23110,30529,N,N,26422,25927,22060,N,N,N,N,23623,N,N,N,N,N,
+24873,N,25130,N,21798,N,N,21591,N,N,N,N,N,N,29264,N,27259,N,24669,31603,N,N,N,
+N,N,N,N,28989,N,N,25191,32087,N,20040,27191,N,31808,N,32103,30575,N,N,22325,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,28474,29021,N,24115,N,N,N,N,N,N,
+26699,N,N,30813,N,N,31559,21832,N,22367,N,23849,N,N,N,N,N,26929,N,N,31277,
+30297,31348,N,N,N,N,N,30762,N,N,N,N,N,26222,N,19548,24892,24687,N,N,26943,
+31869,26190,N,N,24919,N,26191,N,29809,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,25715,N,N,25723,N,N,31076,N,N,N,N,N,N,N,N,N,N,28515,N,N,20334,30270,
+24626,31870,20779,N,N,N,22394,N,N,N,31560,N,25175,N,N,N,N,N,N,21539,28792,
+22312,N,N,N,24935,N,N,21311,N,N,N,N,N,N,28516,N,22341,27490,N,N,31847,N,N,
+25634,N,25192,N,26192,N,31592,29800,25972,29756,29781,24374,N,31801,28226,
+19061,N,N,N,28517,19298,21540,N,24160,23165,25670,26686,N,N,N,N,24670,30260,
+27218,N,31099,N,N,24642,N,19044,N,26423,N,27261,N,22877,N,23092,28202,31593,N,
+N,N,N,23371,23093,N,N,N,N,N,28990,N,N,21292,N,N,N,N,N,N,N,N,31561,N,24399,N,N,
+21312,25431,N,28518,31824,N,N,N,N,N,N,N,26944,N,N,N,30035,N,N,27740,30519,N,N,
+27192,20857,N,N,N,N,N,N,23624,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,27193,
+N,N,N,N,N,29022,N,N,N,N,N,22326,20277,N,22824,N,N,27758,N,N,23850,N,N,N,N,
+19746,26670,N,N,N,24893,N,29265,N,N,N,N,26945,N,N,N,21116,N,N,N,N,N,N,N,23349,
+N,29543,22654,N,N,N,31825,N,27954,29743,N,31523,N,N,31809,N,28203,21541,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29810,N,N,N,N,28249,N,N,N,31562,
+N,N,N,N,N,19811,22587,25947,30839,N,N,N,30292,N,N,N,N,N,N,N,N,22313,N,19273,N,
+N,26193,28748,N,N,N,N,N,N,N,N,N,N,22574,N,31059,21886,N,N,N,N,N,N,N,22588,
+29232,N,N,N,N,25131,29544,N,N,N,N,N,28482,N,N,N,N,N,N,28012,N,26424,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,23166,N,N,19518,N,N,29308,23147,N,25176,27990,N,N,22097,
+24627,N,N,31826,N,27464,N,N,N,N,N,N,N,N,21313,28749,N,20343,N,N,N,N,N,N,N,N,N,
+27986,N,21592,23625,22385,N,N,24379,N,N,29477,N,N,N,29773,N,N,N,N,28991,30769,
+N,27002,N,N,N,31563,N,N,19029,N,N,N,N,N,N,N,N,N,N,N,31060,30538,N,N,22088,N,N,
+N,N,N,N,31848,29501,N,28286,N,26494,N,N,N,N,N,21314,N,N,N,N,21302,N,19501,
+30330,22066,21080,N,N,N,N,N,N,26456,N,N,N,N,N,N,N,N,N,N,25381,N,N,N,N,26425,N,
+N,N,N,28717,31564,27425,N,N,21542,N,N,N,N,31565,N,21821,29023,N,N,30331,N,
+24116,N,N,N,N,N,N,N,N,N,N,N,N,21867,25928,N,N,N,31524,21561,N,N,24161,N,25635,
+N,N,N,22327,N,30830,N,N,N,24117,N,N,22098,N,31061,26426,27477,21879,28519,
+24894,N,N,N,31278,N,N,N,22121,22126,N,N,N,N,N,N,26427,N,N,N,N,N,N,N,27723,N,N,
+N,N,N,N,21811,N,N,N,N,N,N,N,N,N,N,N,N,N,20020,N,N,N,31525,24942,N,N,N,N,N,N,
+30504,N,N,N,N,31566,N,N,N,N,N,22589,N,N,N,N,N,N,N,31613,N,N,N,N,31849,N,N,N,N,
+N,N,N,20278,N,N,N,27975,28204,N,N,N,N,N,N,N,19549,N,N,N,N,30247,N,N,N,26234,N,
+N,N,29988,N,N,N,N,N,32092,27955,20041,N,N,N,N,N,N,28520,N,N,24895,N,N,N,N,N,N,
+31323,19299,30505,N,31526,N,N,N,23609,N,N,N,28992,27976,28483,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,22061,N,N,32078,N,N,N,26657,N,N,N,N,N,N,N,N,31604,21799,N,N,N,
+29046,N,26195,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,19550,N,N,N,N,N,N,N,30770,N,N,
+N,23659,32054,N,N,N,N,25962,N,N,29024,N,N,N,N,N,N,N,N,N,N,N,N,23372,23885,N,N,
+N,21576,N,N,22893,N,N,N,N,29989,N,N,N,N,N,N,N,N,N,26235,N,N,N,N,N,26196,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,32072,N,22049,32063,N,31827,N,28449,N,26428,N,N,N,N,
+N,20846,N,N,26197,N,N,26994,N,24368,N,N,N,N,N,22624,31802,32047,28750,N,23393,
+N,N,25929,N,27956,N,N,N,N,N,N,N,N,N,N,N,N,N,N,24643,N,N,N,N,N,N,25432,N,N,N,N,
+27003,27176,N,N,N,N,32055,N,N,31527,N,26946,N,N,N,N,32119,N,N,N,N,N,25177,N,N,
+23660,N,N,N,N,N,N,N,N,N,26658,N,N,N,N,26224,N,N,N,N,N,N,N,32120,32121,N,N,N,
+30271,N,N,26407,N,26199,N,N,N,N,21619,21577,N,N,N,N,22138,N,22386,N,24896,N,
+23394,26200,N,N,N,N,N,N,N,N,N,26429,N,N,N,N,N,28751,29502,25132,N,N,N,N,N,
+30007,24688,N,N,N,N,N,N,N,N,N,N,N,N,32056,25448,N,21543,26748,31314,N,N,N,N,N,
+30831,N,N,N,N,N,N,N,N,N,22099,N,N,N,N,N,N,N,N,N,N,21812,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,28752,N,30576,28211,N,N,27194,N,27219,N,N,27977,23851,N,N,N,25900,32033,
+N,24400,27699,N,24401,N,N,N,N,N,28013,30776,30586,N,N,N,30763,N,N,N,N,N,29792,
+N,N,N,N,N,21562,25651,N,26970,N,24118,N,22847,N,22848,22127,N,N,N,N,22860,N,
+23082,N,N,N,N,N,N,N,N,24421,N,N,N,N,N,N,30565,N,N,N,19506,N,N,24441,22368,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,21563,N,N,N,N,
+32122,N,N,N,N,19507,N,N,23411,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,24402,N,20042,N,
+28250,N,N,N,N,N,N,N,N,N,25700,N,31567,N,N,N,N,N,N,20279,N,28227,N,N,N,N,N,N,N,
+20074,N,N,N,N,N,N,N,25133,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22369,31349,N,N,21833,
+30764,26457,N,N,N,N,N,N,N,N,N,N,N,29545,N,N,N,N,22637,25412,28785,N,N,N,N,N,N,
+N,26725,N,N,N,24698,28228,22878,N,N,N,N,N,N,N,N,N,N,27426,27427,N,N,N,N,N,N,
+31810,27195,N,N,N,N,26667,24162,N,N,N,N,N,N,N,N,N,N,28015,N,26659,N,N,N,N,
+20337,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,21564,N,31850,N,N,N,N,N,26430,N,31858,N,
+N,22068,N,N,25134,N,21303,31308,N,N,N,N,N,N,N,N,31324,N,27957,24931,N,26668,N,
+26717,N,N,28521,N,N,N,N,N,29757,N,20280,26971,20780,N,N,N,N,N,N,23111,N,N,N,N,
+N,N,N,27465,N,26700,N,N,N,24119,N,N,N,N,22076,21349,N,N,N,N,N,31325,N,N,N,N,N,
+N,23126,N,18993,N,N,N,N,N,N,23112,24358,N,31027,29266,N,19012,N,N,N,N,N,N,
+20043,N,N,19829,N,N,N,32048,21800,N,28993,N,N,25193,23626,27700,31296,N,N,
+31528,20520,N,N,23148,N,N,N,N,N,N,N,N,N,22894,N,24699,N,N,N,28522,31326,24644,
+N,20281,N,21834,22370,25135,N,22328,N,N,N,N,N,N,N,N,N,26701,N,N,N,N,N,N,N,
+30298,N,N,N,N,28450,25178,30332,N,N,31568,20781,N,19812,N,20782,23661,26702,N,
+28793,20021,26236,N,N,22395,20566,23925,30577,N,30333,N,23415,N,N,N,N,31594,
+26972,22849,N,30066,24645,N,N,N,N,N,N,27220,N,N,N,N,N,N,N,N,N,31042,N,27196,N,
+21061,31569,26432,27429,N,24442,25378,22329,N,26947,N,26749,26671,N,N,29267,
+31529,22565,N,N,N,N,21835,N,N,N,N,N,N,N,N,N,N,N,N,N,N,20552,N,N,N,20783,22371,
+N,N,N,24646,N,22050,N,28016,N,N,N,N,N,N,N,N,N,N,N,N,22387,N,N,N,31828,N,23127,
+19551,N,29268,N,20784,N,19552,N,23421,29503,N,28753,N,N,N,N,N,31803,N,25136,N,
+N,26149,N,N,N,25179,N,N,N,24414,N,24647,N,N,N,N,N,N,29295,N,N,N,19553,N,N,N,N,
+22122,N,N,N,N,26434,N,N,N,20022,N,29504,N,19838,N,N,N,31570,N,30840,30587,N,N,
+26687,N,N,N,N,N,N,N,26679,N,N,N,N,N,N,N,N,27958,23610,N,N,19508,N,N,N,N,N,N,N,
+N,N,N,N,N,29047,N,N,N,26680,N,N,19062,N,25636,29782,N,N,N,24422,N,N,N,24359,N,
+24423,24897,N,26948,N,N,23627,26949,N,N,N,28451,27430,19235,25449,N,N,N,20859,
+28452,N,28523,N,N,N,N,N,N,N,N,N,N,N,N,20532,N,N,N,N,19747,N,N,26726,N,28453,N,
+21324,23149,N,N,N,N,22330,N,29269,30053,22895,N,N,N,N,31028,N,N,21844,32079,N,
+N,N,23395,N,N,N,N,29025,27702,N,N,N,N,31614,21335,N,20785,N,19249,N,N,N,N,
+20786,N,N,N,N,N,N,19250,28994,N,N,29793,31029,N,N,24899,24898,N,27511,N,N,N,N,
+N,N,N,N,N,N,N,24360,N,N,N,N,N,N,N,19274,N,N,N,N,N,26169,N,N,N,N,N,30814,31018,
+19063,N,27959,N,N,21304,29270,N,N,21593,28229,29296,N,N,N,18994,N,N,23611,N,
+29048,N,N,N,N,N,27703,N,N,N,N,25930,N,30272,32093,N,N,21603,19554,N,30548,N,N,
+N,N,N,N,22373,N,N,N,N,N,N,N,N,N,N,N,N,N,21315,N,22566,N,30273,N,N,N,N,N,23926,
+N,19776,25948,N,N,N,N,N,N,N,N,N,N,N,N,25931,N,N,N,N,N,N,N,N,N,N,N,24900,N,N,N,
+N,N,26672,29744,29546,23150,N,22331,N,25137,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,22314,N,N,N,N,N,N,22139,N,N,N,N,N,N,N,N,N,25695,N,19030,N,N,N,27432,N,N,
+N,23422,N,N,N,N,N,N,N,N,N,N,30274,N,N,28475,N,N,N,N,21629,N,N,24648,N,N,N,
+26681,N,28454,N,N,N,N,N,19748,N,N,21620,23329,23388,23389,N,N,N,N,N,28252,N,
+19275,31829,N,N,N,N,N,N,20075,N,19777,N,N,31571,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,31019,N,N,N,N,N,N,N,N,N,N,N,30036,N,N,N,N,22825,N,N,
+26973,23373,N,N,23886,N,26435,N,27724,N,N,N,N,N,N,N,31084,N,N,N,19276,N,N,N,N,
+24700,21544,N,27987,22639,N,29271,N,19064,23151,N,N,22100,N,N,N,N,N,N,22861,N,
+N,N,22638,N,29249,N,N,N,24403,N,N,N,23152,N,25194,24701,N,N,22648,N,N,N,30511,
+23094,N,19031,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29272,N,22649,N,N,N,N,N,N,N,
+N,31327,N,N,N,N,N,N,N,N,N,N,N,N,N,20335,22850,N,28754,N,25681,N,N,N,29495,N,N,
+N,N,N,N,N,N,N,N,N,N,31328,N,N,N,N,N,N,N,N,N,N,N,N,N,28524,N,N,N,N,N,25138,N,
+21565,N,N,22862,N,N,N,N,29794,N,N,N,N,N,N,N,N,N,N,N,N,N,21545,N,N,N,N,19778,
+26458,N,N,N,N,N,N,N,N,N,N,N,29273,N,N,N,N,N,22826,N,N,N,N,N,N,N,N,N,N,N,N,
+22590,N,N,N,N,N,N,23597,N,N,N,N,N,N,25195,22140,N,N,19065,N,N,21594,N,N,N,N,N,
+N,N,29783,19489,N,N,20282,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30008,
+N,N,N,22851,20584,N,N,N,N,N,25413,27512,N,29233,N,N,N,20283,N,N,N,21293,26721,
+20076,N,N,N,24628,24163,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,23927,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,29234,29558,30299,N,N,N,N,22398,N,N,N,N,N,30815,N,30578,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,20521,N,N,N,N,N,N,N,N,N,26202,N,N,N,N,N,N,N,N,N,N,
+N,N,N,29990,N,N,N,N,N,N,N,N,N,N,N,N,N,22332,19555,N,N,26203,N,N,N,N,N,N,N,N,N,
+N,N,N,23901,N,N,N,N,20787,N,N,N,N,N,28525,N,N,N,N,22110,25716,24943,N,N,23928,
+N,N,N,N,N,26703,N,N,N,N,N,N,N,N,N,N,N,19045,N,N,N,23585,N,24629,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,31788,31789,22567,N,N,N,N,27960,N,N,N,23350,N,N,N,N,22128,
+29487,N,N,19749,N,23153,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22568,N,
+N,N,19556,N,N,20788,N,N,N,N,N,19032,N,N,N,N,N,23154,29991,N,N,N,N,N,N,N,N,N,N,
+N,N,29992,N,N,N,N,N,N,N,26150,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,21868,
+21880,23155,N,N,N,N,N,N,N,N,N,N,N,N,N,25414,N,N,N,24164,N,24165,20789,N,N,N,N,
+N,20790,20791,29235,N,N,N,N,N,N,26974,N,N,N,N,N,28755,29236,N,N,28756,19300,
+31572,30054,25450,N,24166,N,N,N,N,24404,N,N,30841,N,N,N,N,28718,N,N,N,N,N,N,N,
+N,N,N,N,N,20792,N,N,N,N,22111,N,20567,N,N,N,N,N,N,N,N,N,N,N,31777,28526,23640,
+N,26975,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,25949,32123,N,N,24649,N,N,N,
+22089,N,N,21546,N,25932,N,N,N,N,N,26976,N,N,N,20568,31778,21566,25139,24167,N,
+N,N,N,N,N,N,23612,21046,30037,N,N,N,N,N,20001,29993,N,N,23929,N,N,23930,N,N,N,
+N,N,N,28757,N,N,N,N,30303,N,29274,25707,N,29297,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,27705,32124,N,N,N,N,24874,N,N,19033,N,N,28527,N,29994,N,N,N,N,N,N,27769,N,
+N,30765,N,29250,30275,N,22354,N,N,31010,28758,N,N,N,N,N,N,N,N,N,N,N,N,N,28794,
+N,N,30304,N,N,N,N,26995,29251,N,N,N,21547,18995,19750,N,19779,19802,N,N,N,N,N,
+22863,N,N,30276,N,N,N,28253,26436,N,N,N,N,N,N,N,N,25140,N,N,N,N,N,N,N,N,N,
+24418,26459,N,N,N,N,N,N,26673,N,31790,N,N,N,N,25933,N,N,N,31339,N,20284,N,N,
+20322,19830,N,N,28528,N,29758,N,21581,N,N,29496,N,N,N,26913,N,N,N,N,N,N,N,N,N,
+29298,29547,N,28759,N,N,20311,N,N,N,N,N,N,20319,N,N,N,N,N,N,N,N,N,26688,26689,
+N,N,N,20323,26914,N,N,N,N,N,N,N,N,N,N,20522,N,N,N,N,N,N,N,N,N,29505,20523,N,
+21604,N,N,28476,22561,N,N,N,N,N,N,N,N,N,N,N,22879,N,29527,N,N,N,23613,N,19557,
+28017,N,N,29026,N,21595,N,N,N,N,25141,N,N,19046,N,21294,N,N,N,N,N,N,19558,N,N,
+29011,30055,N,N,N,N,19034,31598,N,24901,N,N,N,N,N,N,N,24425,N,28254,N,N,30530,
+N,22562,N,N,N,N,N,23852,N,N,N,N,N,28719,22077,N,N,N,N,N,N,N,N,N,N,N,24875,N,N,
+N,N,N,N,N,N,N,N,N,N,31030,N,N,21621,N,20553,28455,25196,N,23402,20044,30056,
+30549,N,21325,N,29566,N,N,N,N,N,N,N,N,N,20533,N,N,N,N,N,N,N,N,N,N,N,24702,N,
+24443,N,N,N,N,N,N,26205,N,N,N,N,N,N,N,26660,N,N,N,N,N,N,N,N,N,19277,N,N,N,
+28456,N,N,N,28212,N,N,N,N,23128,20793,N,24361,N,N,29488,N,N,19524,N,N,N,20023,
+N,N,N,N,N,N,N,N,N,N,N,28457,N,N,N,24405,N,N,27991,N,N,N,28230,N,N,N,N,N,N,N,
+28477,31830,N,N,23412,N,28458,30777,N,30057,N,N,N,N,N,N,N,N,25433,N,N,N,N,N,N,
+N,N,N,N,N,N,N,24902,N,N,N,21567,N,N,N,N,24168,28778,N,N,N,N,N,N,N,N,N,N,29506,
+N,N,N,N,N,N,N,N,N,N,N,21295,N,N,19035,N,N,N,N,N,31831,N,N,27992,24903,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,29784,22067,23853,N,N,N,21822,N,N,N,N,N,N,N,N,28995,
+28255,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22123,N,N,N,29785,N,N,N,N,N,N,N,
+22374,N,N,N,N,N,N,23095,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,23931,N,N,N,N,N,23887,N,
+N,N,N,N,N,N,N,22563,N,N,23129,N,28760,28484,N,N,N,N,N,N,24920,N,N,N,N,N,29012,
+N,28018,N,N,N,N,N,N,21851,N,N,21852,29508,19287,N,N,N,N,N,25142,N,N,N,N,28529,
+N,N,N,N,N,N,N,N,N,N,N,31573,N,N,N,N,N,N,N,N,N,N,N,21336,N,N,N,N,N,N,N,23888,
+28761,19251,N,N,N,N,N,N,21853,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,19751,N,N,
+20524,20794,N,28996,N,25907,31605,26977,32096,31804,N,23074,23075,N,21025,N,N,
+21103,N,N,N,25197,N,N,24169,20060,29237,20580,23889,N,N,N,N,24904,23351,24419,
+N,N,N,N,N,N,N,N,27961,28997,N,29519,22315,24876,N,N,25451,N,28231,N,N,N,24905,
+19066,N,N,N,N,N,N,N,28795,31329,28762,19559,23156,N,N,N,N,N,N,N,N,N,19519,N,N,
+N,N,N,N,N,N,N,N,N,N,N,20077,N,N,21801,31330,N,N,N,20581,N,27478,N,27743,N,N,N,
+24444,N,N,30550,24170,19252,N,N,28478,N,N,19509,N,N,N,N,N,20285,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,28530,25143,N,N,N,19560,N,N,N,N,N,N,N,N,28796,N,N,N,22112,N,
+28998,N,N,N,N,N,N,N,N,N,25144,27435,N,N,N,19253,22609,N,29774,29559,N,N,22342,
+N,20795,30506,N,27978,22355,22650,N,N,N,N,N,N,N,30277,N,N,20812,23932,N,N,N,N,
+N,N,N,N,N,N,24445,N,31077,N,24650,N,N,29309,21296,N,29811,23113,N,26206,N,N,N,
+N,30778,26704,N,N,22651,N,N,27221,N,N,N,N,22051,N,N,N,N,N,N,30278,29275,25724,
+N,N,N,N,N,N,N,N,N,N,26674,N,N,N,N,N,23130,N,29276,31574,26930,N,28205,N,31331,
+N,N,N,N,N,N,N,23662,N,N,30058,26208,N,28797,N,N,N,N,N,22316,N,N,N,N,N,30021,
+28256,N,N,23397,N,23902,N,N,22896,26915,N,N,N,N,N,N,N,N,N,N,29049,N,29252,
+24651,N,N,N,N,N,N,N,N,26916,N,N,25145,N,N,N,N,N,N,N,25393,31851,19752,N,19510,
+N,N,28763,N,N,N,N,N,N,N,N,26170,N,N,19753,N,N,N,N,N,29507,N,N,N,N,N,N,N,N,N,
+24921,N,N,28459,N,N,N,26437,N,N,24681,N,29509,N,N,21568,21823,23854,N,31100,N,
+19520,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,25890,N,N,N,20024,N,N,N,22610,31062,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,28970,20049,N,N,30279,N,23403,N,24446,N,
+N,22625,N,30579,N,22375,N,N,N,N,N,N,N,N,N,N,N,21630,N,N,20796,N,25935,N,19254,
+N,23096,N,N,N,N,N,19780,N,N,N,N,N,22078,N,N,N,25146,N,N,N,N,N,20312,N,N,N,
+24652,27513,N,N,N,N,N,N,N,N,32125,N,N,N,N,N,22376,19288,N,N,N,26978,N,N,N,
+26682,N,N,N,25415,N,N,N,N,27725,N,27726,N,22079,N,N,N,25383,N,24406,32104,N,N,
+N,N,N,N,N,N,N,28257,30248,23933,N,N,N,N,N,N,N,30779,N,26705,N,N,N,N,31063,N,N,
+N,N,N,N,N,N,20078,N,N,27727,26917,22101,N,19781,N,27962,20797,N,N,20286,N,N,
+27707,N,N,N,21041,N,N,N,N,19561,N,22852,27004,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,20798,N,N,N,N,N,27708,N,N,25901,N,N,N,N,N,N,30512,N,19562,N,N,N,21316,
+N,N,22080,N,N,N,22141,N,N,N,N,N,N,N,N,N,N,N,24865,N,24125,N,30249,N,N,N,23076,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22052,30022,N,24866,26950,N,N,N,29253,N,N,N,N,
+N,29801,22124,27475,N,N,N,N,27709,25180,24171,28764,N,27455,N,22350,20799,N,N,
+N,N,N,N,N,N,N,29995,N,N,N,N,31101,N,19036,N,N,N,19782,29238,N,N,23934,N,N,N,
+19511,23352,N,N,N,N,20585,N,20061,27456,N,32034,N,N,N,N,N,30795,N,N,N,N,N,N,N,
+N,27222,28976,N,N,N,N,N,N,N,23374,N,30531,N,N,N,N,N,N,N,N,N,N,N,23375,19236,N,
+N,30816,N,N,31575,N,N,27466,24609,N,N,N,N,N,N,N,N,N,N,N,20045,N,N,21596,N,N,N,
+32088,N,N,N,N,21110,29239,N,N,31350,30250,31351,22630,N,29745,N,N,N,N,N,N,N,N,
+N,N,N,N,N,26706,N,19013,19563,N,N,N,N,N,N,N,25198,N,N,N,N,N,25147,N,30509,N,N,
+N,30817,N,N,N,N,N,N,N,N,N,29548,N,N,N,N,24097,N,N,N,N,N,N,N,N,N,N,N,N,25725,N,
+N,25452,N,23855,23856,N,N,19255,26707,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,24867,
+21088,N,N,N,N,28798,N,N,N,N,26918,19314,N,N,N,N,N,N,28019,23641,24653,N,N,N,N,
+30554,23353,N,N,N,N,N,N,N,19502,N,23131,N,N,N,N,19783,N,N,N,N,N,N,N,N,N,N,
+23857,N,22575,25379,N,N,20079,N,N,29299,N,N,N,N,30771,N,N,N,N,N,N,N,N,N,N,
+24654,N,30077,N,N,N,N,27500,N,N,21317,31852,21083,21611,N,24098,N,N,N,25958,N,
+N,N,N,N,N,28720,N,N,N,N,N,N,N,N,N,N,21828,N,N,N,N,N,N,28020,N,N,N,25453,N,
+26690,N,28021,22396,N,27963,N,N,30251,N,N,N,N,N,29240,30280,N,N,N,N,N,21350,
+29277,20287,N,27436,20288,N,26152,32105,N,20289,N,24671,24172,N,N,N,N,24610,N,
+N,N,N,N,N,N,N,29759,25199,N,22897,28999,N,19256,N,N,N,N,N,N,N,N,31102,23354,
+23157,N,N,N,N,N,N,N,N,30316,23132,31332,N,24655,N,N,N,N,N,N,23858,N,N,N,N,
+26153,N,28531,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29549,N,N,N,N,N,N,N,N,N,N,
+27514,N,31078,N,N,N,N,N,N,N,19037,21854,N,19038,24420,N,N,N,26237,N,29996,N,N,
+N,N,N,25717,N,N,N,N,N,N,N,N,N,N,N,N,26979,N,27979,20324,N,N,N,22611,N,N,N,N,N,
+N,23859,21612,N,N,29241,N,24375,N,N,N,N,N,19278,31576,N,N,20569,N,N,23890,
+30580,26460,25637,N,31779,N,23355,N,N,N,29242,27005,20554,N,30038,22853,25652,
+N,27943,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,27197,26238,N,30532,29997,N,22880,N,
+N,N,18996,N,N,30818,20290,N,27710,N,N,N,25908,19784,28232,N,N,N,N,N,N,N,N,N,
+26440,N,N,N,N,N,N,N,N,N,N,N,19785,31031,29032,22898,23413,18997,22854,N,N,N,
+22601,N,N,N,N,N,N,N,N,N,N,N,N,N,22827,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,27964,N,
+N,22612,N,N,N,23642,N,25148,N,N,31853,27744,21118,N,26951,26154,N,N,N,N,N,N,
+25200,N,N,N,N,N,N,31291,N,29998,31530,N,N,N,N,27771,N,27711,31832,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,21605,N,N,N,31043,N,N,N,
+28258,N,N,N,N,N,N,N,N,N,N,N,N,N,22377,28022,N,N,N,24173,N,N,N,N,N,N,N,19564,N,
+25454,N,N,N,N,N,26708,N,N,N,31352,N,N,N,N,N,N,23860,25653,22576,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,22613,N,N,N,29802,N,N,N,20025,N,N,N,22113,20306,N,20534,N,
+N,N,N,N,N,20002,N,N,29550,N,N,N,N,N,29560,N,N,N,N,N,N,N,N,N,N,N,N,23628,N,
+20555,N,N,N,31780,19786,22356,24099,N,25696,N,N,N,N,28233,N,N,N,25181,30078,
+21548,N,N,N,N,N,21841,N,22640,30787,27223,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,30039,N,N,22591,N,N,N,N,32064,N,N,N,N,N,N,27437,N,N,N,N,21802,
+N,N,N,N,N,N,N,N,N,N,N,26408,N,N,N,N,N,N,N,N,N,N,N,N,N,28234,N,N,N,19047,N,N,N,
+N,N,30819,N,21597,N,N,27224,N,N,N,N,31577,28023,N,N,25909,N,N,N,N,N,20525,N,N,
+N,N,29041,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,25149,N,N,N,25416,N,N,N,N,
+22869,N,N,24362,N,N,N,N,23356,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30820,N,N,N,N,N,
+29050,N,N,25910,29551,N,N,31578,24928,N,22828,N,30059,N,24630,N,N,26952,N,
+19279,N,25417,N,N,N,24174,N,N,N,N,N,N,N,N,25150,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,23663,N,22053,N,N,N,N,N,25201,N,N,N,N,N,N,N,22142,22817,N,22592,23643,N,N,
+27965,24376,N,27173,N,N,N,22317,N,N,29561,N,28024,N,30023,N,N,N,N,N,N,24906,
+27491,N,29278,N,N,N,N,N,N,N,N,N,N,N,N,N,30796,N,27225,N,21318,N,23398,N,N,N,N,
+N,29999,N,N,N,N,20080,N,N,N,N,27006,N,N,N,N,N,31542,N,N,N,N,N,N,N,N,N,25202,N,
+N,N,N,20338,30521,22899,N,N,24907,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+23133,N,N,23097,N,N,N,N,N,N,N,27515,N,19257,N,N,28025,N,N,N,N,N,N,24672,N,N,N,
+N,N,N,N,N,N,N,29760,N,32060,24369,25455,N,N,N,N,24611,32057,N,N,N,N,N,N,N,N,N,
+28721,N,N,N,N,N,N,19787,N,N,N,N,N,N,N,27966,N,N,N,21824,25456,28026,N,N,N,N,N,
+26980,N,N,N,N,N,N,21869,26461,N,N,N,N,N,N,21622,25911,N,N,N,23399,25151,N,N,N,
+N,N,N,N,N,N,N,N,N,28235,N,N,22388,28765,N,N,N,20011,26462,N,N,N,22102,24908,N,
+N,26675,N,N,N,N,N,N,N,N,N,N,N,25966,23586,N,N,24656,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,21813,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,21793,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,31579,N,31051,N,N,N,19315,29733,N,N,N,N,N,31304,22103,N,26981,31580,N,N,
+N,N,N,N,N,32080,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31606,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,23077,N,23357,N,N,N,N,N,N,27746,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,19831,
+28766,N,N,N,N,30281,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+24175,N,N,N,21297,N,N,N,N,N,N,N,N,31854,N,N,N,N,26691,N,29000,N,N,N,20081,N,N,
+N,N,31085,N,N,N,N,N,N,N,N,29300,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,25654,30009,N,
+23664,25457,N,N,N,N,26661,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29243,N,24100,N,23116,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,19049,N,N,N,N,N,N,25434,N,31833,N,N,N,N,N,N,N,27226,N,N,N,
+N,N,N,31044,N,25380,N,N,N,N,N,N,N,N,N,N,N,31581,N,28490,N,26692,N,N,N,N,N,N,N,
+N,N,21836,N,N,N,N,N,N,N,N,N,N,27479,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22829,N,
+N,31531,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,21337,N,N,N,N,N,N,21794,N,N,N,N,N,N,N,
+N,N,30302,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,23158,N,N,N,N,
+N,N,N,N,N,N,N,24657,N,N,26920,N,N,30073,N,N,N,N,N,N,31279,N,27516,N,N,24682,
+25394,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,21829,N,N,29027,21870,
+N,N,N,N,N,N,N,N,N,N,N,N,N,19788,N,N,N,N,27993,N,N,N,N,22593,N,N,N,N,31340,N,N,
+N,N,N,29035,N,N,N,N,N,31292,26210,N,N,N,N,31333,25210,N,N,N,18998,N,25655,N,
+27227,N,30074,N,N,N,31532,20291,27517,N,N,N,N,30842,N,N,24377,N,N,N,N,24945,N,
+21028,N,N,N,N,30075,N,N,N,N,N,N,20570,20571,N,27198,22833,N,N,N,N,N,18999,N,N,
+21351,N,30821,N,N,N,N,21298,N,N,N,25152,29279,N,N,N,N,N,N,19813,N,N,N,N,N,N,N,
+N,N,N,N,N,31020,N,N,N,N,N,N,N,N,19789,N,N,N,N,N,N,N,N,N,N,N,N,28206,22062,N,N,
+N,N,N,N,N,N,N,N,N,N,22378,N,N,N,N,26464,27438,N,N,N,20313,N,N,23629,28027,N,
+24176,N,22379,N,N,N,N,N,N,24101,N,N,N,N,N,N,N,N,N,N,24407,23376,23377,N,N,
+21795,N,N,N,N,28722,23644,N,N,N,N,N,N,N,N,19048,N,30822,23630,N,N,N,N,27228,
+23378,N,N,N,N,N,N,N,N,N,N,N,26931,N,N,N,N,30555,N,N,N,N,N,N,N,N,N,N,N,25384,N,
+22318,N,N,24673,N,N,N,N,N,19258,N,N,25937,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,20572,N,N,N,N,21825,N,N,N,N,N,22602,N,N,N,N,N,N,N,25385,N,N,N,
+N,N,N,N,N,N,N,N,N,24612,N,26921,N,21319,N,N,23645,30766,N,N,N,19512,N,N,N,
+20526,N,N,N,22642,N,N,25418,N,N,N,N,N,N,N,N,N,N,19503,N,N,N,N,N,N,N,21549,
+30289,N,N,N,N,N,N,N,20556,N,N,N,N,N,N,N,19014,N,N,21826,N,N,20026,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,19015,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31280,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,24408,N,N,N,30010,25963,N,28532,23861,N,N,N,N,19754,N,
+25458,N,31607,N,30544,N,N,N,N,32058,N,N,32097,30334,20800,N,N,26693,N,25656,N,
+24936,N,N,N,19521,N,21101,N,N,N,N,23358,N,N,24674,N,N,N,31305,N,N,24909,N,
+19000,N,N,N,29280,29001,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,24177,N,N,N,
+28767,30788,N,N,N,N,N,28236,N,N,24178,N,26441,N,25203,26465,N,N,25419,N,N,
+25420,N,N,N,20344,28460,N,32126,31781,31281,24409,N,24658,N,N,N,29786,N,N,N,N,
+N,N,N,N,N,N,N,29002,N,20003,N,N,N,N,29244,27747,N,N,N,N,N,24613,N,30507,N,N,
+27439,N,N,N,N,N,25950,N,24868,19755,N,22900,26662,19790,24937,N,31855,N,24675,
+N,N,N,N,N,25153,N,20004,N,N,N,N,N,N,24102,N,N,27518,N,27485,28768,N,N,29787,N,
+25204,N,N,21320,N,N,N,29803,N,28213,N,30040,N,N,21855,N,N,N,22117,N,N,N,N,
+27440,29795,N,N,N,N,25421,N,N,N,N,29812,31282,N,N,28533,19039,N,27441,27967,N,
+N,32073,N,N,N,N,25638,31012,28723,N,25964,N,N,N,20839,22855,25687,27229,N,
+21623,N,N,N,N,N,N,N,N,N,23098,N,23117,N,N,N,31052,N,24922,23359,N,19525,27728,
+19259,N,24179,N,N,26922,N,N,N,N,N,N,N,22856,N,N,28259,22333,N,N,N,N,N,N,20292,
+N,N,N,N,N,20557,N,N,N,N,N,N,N,31782,N,N,N,N,N,N,N,29051,N,N,N,N,32082,20801,N,
+N,N,N,N,N,N,N,25435,N,21321,N,23631,N,N,N,N,N,N,N,N,N,19565,N,N,N,N,N,24103,N,
+N,26171,27681,N,N,N,19513,N,N,31582,N,N,N,N,N,26466,N,N,21569,N,N,N,N,N,N,N,N,
+N,23592,N,N,N,N,N,25154,N,29528,25939,N,N,29529,N,N,N,29510,19803,N,N,N,N,N,N,
+N,19756,N,31811,N,N,N,N,21607,N,20802,N,31013,N,26709,N,N,N,N,N,N,N,N,25422,N,
+N,N,N,21578,N,N,N,N,N,N,24410,N,N,N,N,N,N,N,N,31583,26467,N,N,N,N,N,N,N,N,N,N,
+N,N,N,30843,25423,N,N,N,N,N,N,N,30000,N,N,N,N,N,N,N,22631,N,22857,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,30767,28534,N,23862,28207,19832,N,N,N,N,24120,31783,30588,
+30513,20027,29729,N,N,28237,24878,N,N,27715,20350,N,30783,22626,21352,N,N,
+24104,29796,27714,N,22901,31045,23891,22129,27772,31856,N,N,27968,19001,N,
+28260,N,N,N,N,N,N,29281,N,24121,N,N,N,N,N,N,22130,N,24180,N,24411,N,23379,N,
+31335,22627,29761,N,23863,N,N,N,29301,N,N,21550,N,N,N,N,N,N,22131,N,N,N,N,N,N,
+23864,20293,24415,29246,30241,N,27467,29052,N,29511,N,N,24683,N,N,N,N,N,28028,
+N,N,24923,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,28261,N,24181,N,N,N,N,31315,N,N,N,N,29003,N,N,20527,23865,N,N,20803,N,
+N,N,N,N,N,N,N,N,N,N,N,N,30001,N,N,N,N,27206,N,N,N,N,N,N,N,N,N,N,N,N,N,N,28769,
+N,N,N,N,N,N,N,N,N,30252,N,N,N,N,30041,N,N,N,N,N,N,N,N,N,N,28779,N,N,N,N,N,N,
+23866,N,N,N,29247,N,N,N,N,N,N,N,30533,N,N,N,N,23330,29302,N,N,19002,N,N,N,N,N,
+N,N,N,N,N,N,30581,N,19301,N,N,N,28262,N,24659,N,N,N,N,20005,N,N,N,N,N,N,22104,
+N,N,N,21551,26953,N,N,N,N,21326,29762,N,N,N,N,N,N,N,N,N,N,N,N,N,19302,N,N,N,N,
+N,N,N,N,N,N,N,28961,N,N,N,N,N,27442,N,N,N,N,28962,N,N,N,N,N,N,N,N,N,N,N,N,
+27443,N,28724,N,N,19316,21552,29490,31543,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30060,N,
+N,N,N,N,28263,29746,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30061,N,20339,N,N,N,
+N,N,N,N,N,N,N,28770,N,N,N,N,N,28238,N,N,29004,N,N,25912,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22389,25459,20325,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,20294,N,N,N,N,N,N,N,N,N,29491,25688,20345,20314,N,N,N,N,31309,N,N,
+N,N,N,N,N,N,N,N,N,N,26211,N,N,N,N,N,N,N,N,N,N,N,29282,N,N,N,N,N,N,N,N,N,N,N,N,
+30062,N,N,19003,N,N,25436,20082,N,22105,N,N,N,28208,N,N,N,N,N,N,N,N,29797,
+22594,23632,19566,N,N,N,N,N,21856,30282,32074,22614,29775,N,N,N,N,N,N,22054,
+23614,N,23380,22343,N,N,N,N,29310,N,N,N,29005,N,N,N,N,25155,23646,N,23647,N,N,
+28461,26155,N,N,N,N,31069,27199,N,N,N,28462,N,N,N,29776,20083,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,26156,N,20062,N,N,21881,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,25460,
+19792,N,N,N,N,N,N,21816,N,N,30589,N,23593,N,N,N,N,24182,N,23594,29283,26932,
+21084,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,26982,N,N,25462,N,N,N,N,N,N,N,N,26442,N,N,
+20558,N,N,23159,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,19004,N,N,N,28264,23134,N,
+29303,N,N,25211,N,19494,N,N,N,N,23099,N,28265,N,N,N,30042,30556,24938,20033,
+21553,N,32049,26173,N,31533,N,N,30823,N,24910,N,30562,30063,20295,N,N,21554,
+19567,N,21608,N,28239,30551,N,N,24614,22081,24924,28771,29028,23665,22055,N,N,
+N,N,N,N,N,N,N,N,29813,N,N,29006,29284,N,N,20528,N,N,27759,N,N,N,31034,N,27445,
+N,N,21613,25156,N,N,N,N,26983,N,N,27444,27169,N,30780,20006,N,31046,31834,N,
+21555,21305,27230,N,N,N,26923,N,N,24929,21327,29814,N,27200,24911,N,19514,N,N,
+N,N,N,28266,N,N,N,28772,29492,21614,N,N,29248,N,N,29029,N,29763,24660,N,27446,
+N,22305,19304,N,31021,26925,22628,31283,25157,31805,N,N,27716,22577,N,23595,N,
+N,N,N,21796,N,27497,N,N,N,26683,N,N,N,22615,N,N,N,N,N,N,N,N,31534,20833,N,N,
+23360,N,30014,N,24183,N,N,N,N,19067,30534,20296,N,N,N,24912,N,N,28240,N,N,N,N,
+N,N,N,N,26996,N,N,N,N,N,N,N,N,20084,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+21837,N,N,20315,N,N,N,N,N,N,23867,N,N,N,N,20012,N,N,N,N,N,N,N,26984,N,N,N,N,N,
+N,N,21556,25671,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30043,N,N,31297,N,N,N,24105,N,N,
+N,N,N,N,N,N,N,N,N,N,N,21624,N,N,N,N,N,28535,N,N,N,N,21299,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,27447,28536,30044,27980,23381,29007,N,N,N,29008,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,30002,N,N,N,N,N,N,22830,21804,N,25158,N,N,N,N,N,N,N,N,
+32035,N,31589,24363,N,N,N,N,N,N,N,N,N,N,N,N,N,N,25205,N,30253,N,30003,N,28725,
+N,N,N,N,24869,N,N,N,N,N,N,N,N,N,30045,N,N,N,N,N,N,N,N,N,N,N,N,N,N,27682,28029,
+N,30004,31544,N,23331,N,N,22090,19289,N,N,N,N,N,N,N,N,N,N,25940,N,N,N,N,N,N,
+29562,N,27448,N,24631,22380,29036,25903,21857,22381,20817,N,N,N,N,N,24946,
+28537,N,N,N,23868,30300,N,N,N,N,N,28773,N,N,N,29764,N,N,26985,N,N,N,N,N,N,N,N,
+N,N,29563,21615,N,N,19490,30590,24380,N,N,N,N,27469,N,N,N,N,N,N,20535,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22082,N,N,N,N,N,26669,N,N,N,N,28463,19237,N,
+N,N,N,19305,N,N,N,31336,N,N,N,N,N,N,N,N,N,N,N,N,N,19526,N,N,N,26215,N,N,27207,
+N,N,N,23332,N,20297,25212,28538,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,27486,N,N,30024,N,21598,N,N,N,N,N,N,N,N,N,N,N,24661,N,28464,N,N,25159,N,
+22831,N,N,N,31079,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,26469,N,N,20298,
+24913,N,25160,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,28539,N,N,31353,N,N,23666,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,24615,N,N,N,N,N,30824,N,N,N,N,N,N,N,N,N,N,N,N,
+N,19306,N,N,N,19260,22114,N,N,N,N,N,N,N,N,N,N,N,30046,N,N,N,N,N,N,N,30047,N,
+28214,N,N,N,25206,21322,28540,20804,28465,N,20805,N,20574,N,22881,N,N,24632,N,
+N,19793,29497,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,26444,N,22056,
+20007,N,21557,N,N,N,N,N,N,25672,N,N,N,N,N,N,21300,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,27449,N,N,N,N,N,N,19317,N,N,N,N,N,N,30301,N,28963,N,N,N,N,N,N,N,N,N,N,
+N,N,N,19527,N,N,N,N,N,N,N,26954,N,24944,N,N,N,30048,N,N,N,N,N,N,N,N,31535,N,N,
+N,19281,N,N,N,N,31584,29285,N,N,27760,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+28780,N,N,N,N,N,N,N,N,N,N,N,N,N,28267,N,N,N,N,N,N,N,N,N,N,N,N,26955,N,N,19568,
+N,N,22319,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29473,31861,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,28964,N,N,N,N,N,N,N,N,N,N,N,N,24662,N,N,N,N,N,28466,N,N,N,N,N,
+N,N,N,N,29777,N,N,30497,N,N,N,N,N,N,N,N,N,N,N,29009,N,N,N,N,N,N,N,N,N,N,N,N,
+19068,19069,N,N,N,N,N,N,N,N,20046,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,29512,N,29498,28030,N,N,N,N,N,N,N,N,23078,N,N,24684,N,N,
+N,N,N,30797,N,19282,N,N,N,27470,N,31064,31065,19040,23114,N,N,N,19238,N,N,N,N,
+N,N,N,N,N,N,19016,31086,23404,N,N,20529,N,N,N,N,21871,N,N,N,26227,N,N,N,N,N,N,
+N,N,N,26402,25689,N,N,N,N,N,N,N,N,N,N,25697,N,N,31812,N,N,N,N,N,N,N,N,N,31087,
+20340,30566,N,N,N,N,N,20028,N,N,N,N,29765,23587,23869,N,N,N,N,29766,N,N,N,N,N,
+N,N,N,30753,N,N,N,26710,N,N,N,23361,N,N,N,N,N,N,N,N,28774,N,N,N,25657,30317,N,
+31022,N,23870,N,N,N,N,N,N,22320,22632,19261,N,N,31066,N,N,N,N,N,N,N,N,N,N,
+30798,31088,24685,25395,29747,N,N,27202,29286,28726,N,N,N,N,N,23382,N,N,N,N,N,
+27492,N,N,29287,N,22357,21558,31080,22337,N,N,N,N,25941,N,N,N,N,N,N,N,26986,
+22348,N,N,N,21353,25161,N,31835,19757,N,N,N,N,N,19504,27170,N,N,25718,20544,N,
+28727,28193,N,N,N,N,N,N,22390,N,N,N,25162,25163,N,31311,N,N,N,N,N,N,27487,N,N,
+N,N,N,22091,N,N,N,29748,N,N,N,N,27981,25682,N,N,27177,25658,29474,19794,N,
+30283,N,29030,27969,26684,28241,N,N,N,N,N,N,28775,25164,N,N,25642,N,30049,
+27994,N,N,N,N,N,22382,20849,N,N,N,N,26987,26988,24676,N,N,N,N,23079,23892,N,
+27171,N,N,N,22083,22132,N,23135,N,28467,25165,N,N,N,N,N,28541,29288,N,N,N,N,N,
+N,N,N,N,28485,N,26471,N,N,22397,N,N,26446,N,N,24412,N,31047,N,N,N,N,N,N,N,N,
+22902,N,N,N,N,N,N,N,N,24364,N,22106,N,N,N,N,N,N,23588,N,N,N,28728,N,N,N,N,
+21882,N,25719,N,N,N,22084,N,N,N,N,N,N,N,N,29804,N,N,N,N,28542,N,N,N,N,N,28705,
+N,24106,N,N,23100,22652,N,N,N,N,N,N,31316,N,N,N,27749,N,N,N,N,N,N,31784,N,N,
+27750,N,N,22603,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31545,N,25683,N,19833,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,20307,N,N,N,N,N,N,N,19050,N,N,20308,N,30781,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29767,N,N,N,N,27231,N,N,N,N,N,N,N,31067,
+N,N,N,N,N,N,N,N,21559,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,27493,N,N,
+24914,N,N,N,N,27172,N,N,N,31298,31585,31341,28706,19569,N,31267,25207,N,25166,
+N,26997,N,24939,N,N,N,26472,26711,23160,21579,N,N,N,30582,22085,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,21609,N,N,31354,N,N,N,N,N,N,N,19570,30557,N,24122,N,
+N,N,N,N,N,N,N,N,N,20008,N,N,N,N,N,28729,25726,25673,N,N,N,N,N,25684,N,N,N,
+27203,N,28468,N,N,N,22334,N,N,N,N,N,N,31586,N,19795,N,N,N,28469,N,N,N,31337,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31014,N,N,N,N,N,N,24381,N,30535,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,30845,N,N,30844,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+24107,23400,N,N,25437,N,24930,20806,N,N,N,N,N,N,N,N,N,N,30288,27494,23161,N,N,
+N,N,27719,N,N,N,N,N,N,N,24184,30825,25438,20085,N,N,N,N,N,31299,25943,N,27720,
+N,N,N,29513,N,N,25659,N,N,N,N,26158,N,N,N,N,N,28470,N,23615,N,N,N,N,N,N,N,
+20029,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22595,N,N,N,
+20559,N,20346,29514,24663,N,N,N,20807,26926,N,26685,N,N,31300,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,25167,N,N,31301,N,N,N,31032,N,N,N,N,N,N,N,23648,
+N,N,31536,N,N,N,22569,25951,31015,N,N,30318,N,30284,25208,N,N,N,N,27761,N,N,N,
+N,N,N,N,23136,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29010,21068,20299,N,N,19005,N,N,N,
+23871,N,N,N,30319,N,24185,N,N,N,N,N,N,N,N,N,N,N,N,N,31284,N,N,N,21805,N,N,N,N,
+N,N,N,N,N,N,N,N,N,29031,24126,N,N,N,N,N,N,23616,N,N,N,N,N,20808,20809,N,N,N,N,
+N,N,N,N,N,30782,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,19318,N,N,N,N,21625,N,N,N,N,
+N,30050,24915,N,N,N,N,N,N,N,N,22633,N,N,30846,N,20300,N,N,N,N,N,N,N,32036,N,N,
+N,N,N,N,N,20086,N,31312,N,N,19571,26174,N,N,N,30254,N,N,21872,N,N,20810,N,N,N,
+31806,21873,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,19817,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,31285,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,25168,
+29815,N,N,N,19796,N,N,N,N,N,N,N,N,N,N,N,N,26403,N,N,N,N,N,N,N,N,23333,25169,N,
+N,N,N,N,N,N,N,N,N,N,N,22306,N,N,30563,N,N,N,N,N,N,27174,N,N,N,N,N,N,N,N,N,N,
+20513,N,N,N,N,20058,31595,23334,23390,22629,N,N,N,N,N,N,N,N,N,27232,N,N,N,N,
+22570,N,N,N,N,N,25952,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22107,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,28486,N,N,30826,N,N,N,N,N,N,
+N,N,N,N,N,N,N,25685,N,N,N,N,N,N,N,N,N,N,N,20087,N,N,24664,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22383,N,N,N,N,N,N,N,N,N,N,N,N,29805,N,N,N,N,N,
+N,N,N,N,N,N,N,N,19814,N,N,N,19572,30051,N,N,25674,N,23649,N,N,31048,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,31807,N,N,N,N,N,N,N,N,N,N,N,N,26663,N,N,N,N,N,N,N,N,22596,
+N,N,N,N,N,N,N,N,N,N,N,19262,N,23598,N,N,N,N,N,N,N,N,N,N,N,N,N,22391,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,28776,N,23872,N,20301,N,N,N,N,N,N,N,N,N,
+23667,22832,N,26217,25660,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,27204,N,N,N,N,N,N,
+N,N,N,N,25708,N,25701,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31608,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,19515,N,N,N,N,N,N,N,N,N,N,N,25661,N,N,19804,22903,
+N,N,N,N,N,N,N,N,N,N,23903,N,N,N,N,N,27982,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22864,
+N,N,N,N,N,25891,N,N,N,N,31053,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,19758,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,20302,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,30255,N,N,N,N,N,32083,27501,22108,25892,N,N,N,21814,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22109,
+N,N,N,31081,N,N,N,26404,N,22115,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,20811,
+22116,N,N,N,21874,N,N,N,N,N,24186,N,22392,N,N,N,N,N,22634,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,20309,22653,N,N,N,N,N,22571,N,N,32075,N,N,N,N,31836,N,N,N,N,N,N,N,N,N,
+24616,21875,N,N,32089,N,N,19491,N,N,N,22905,N,N,21354,30069,N,28487,N,N,N,N,N,
+N,N,N,N,21338,N,N,N,N,N,N,N,N,N,N,N,23101,26664,23599,N,N,N,N,N,28707,N,N,N,N,
+19797,N,N,N,N,N,N,N,N,N,N,N,N,24617,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,24108,N,N,N,N,N,N,N,N,N,N,N,N,N,N,28730,28209,N,N,28210,N,N,N,30285,
+N,N,N,N,N,N,N,N,N,N,N,N,28242,N,22086,N,N,N,N,N,24677,N,N,29499,N,25953,N,N,N,
+N,N,N,N,N,N,N,25675,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22307,N,N,23362,
+N,N,N,N,19070,N,N,N,N,N,N,20303,12321,12322,33089,33090,12323,33091,33092,
+12324,12325,12326,12327,33093,33094,33095,33096,33097,12328,12329,12330,12331,
+12332,12333,12334,12335,33098,12336,12337,12338,12339,12340,33099,33100,12341,
+33101,33102,33103,12342,33104,33105,33106,33107,33108,33109,33110,12343,12344,
+33111,12345,12346,12347,33112,33113,33114,33121,33122,33123,12348,12349,33124,
+33125,12350,33126,33127,33128,12351,33129,33130,33131,33132,33133,33134,33135,
+33136,33137,33138,12352,33139,12353,33140,33141,33142,33143,33144,33145,12354,
+33146,33153,33154,12355,33155,33156,33157,12356,33158,33159,33160,33161,33162,
+33163,33164,33165,33166,33167,33168,33169,33170,33171,33172,33173,33174,33175,
+33176,12357,12358,33177,33178,12359,33179,33180,12360,12361,33181,12362,33182,
+33183,33184,33185,33186,12363,12364,33187,12365,12366,12367,12368,33188,33189,
+12369,12370,12371,12372,33190,33191,33192,12373,33193,33194,33195,12374,33196,
+33197,33198,33199,33200,33201,33202,12375,12376,33203,12377,12378,12379,33204,
+33205,33206,33207,33208,33209,12380,12381,12382,33210,12383,33211,33212,12384,
+12385,33213,33214,33215,33216,33217,33218,33219,12386,12387,33220,12388,12389,
+12390,33221,33222,33223,12391,33224,33225,12392,33226,33227,33228,12393,33229,
+33230,33231,12394,33232,33233,33234,33235,33236,33237,33238,33239,12395,33240,
+12396,33241,33242,33243,33244,33245,33246,33247,33248,12397,12398,33249,33250,
+12399,33251,33252,12400,12401,33253,12402,33254,12403,33255,33256,12404,12405,
+12406,33257,12407,33258,12408,12409,33259,33260,33261,33262,33263,12410,12411,
+33264,33265,12412,33266,33267,33268,12413,33269,12414,33270,33271,33272,33273,
+33274,12577,12578,33275,12579,33276,12580,33277,33278,33345,33346,33347,33348,
+12581,33349,33350,33351,12582,33352,33353,33354,12583,33355,33356,33357,33358,
+33359,33360,33361,33362,12584,33363,33364,12585,12586,33365,33366,33367,33368,
+33369,33370,12587,12588,33377,33378,12589,33379,33380,33381,12590,33382,33383,
+33384,33385,33386,33387,33388,12591,12592,33389,12593,33390,12594,33391,33392,
+33393,33394,33395,33396,12595,33397,33398,33399,12596,33400,33401,33402,12597,
+33409,33410,33411,33412,33413,33414,33415,33416,12598,33417,12599,33418,33419,
+33420,33421,33422,33423,33424,33425,12600,12601,33426,33427,12602,33428,33429,
+12603,12604,12605,12606,33430,33431,33432,33433,12607,12608,12609,33434,12610,
+33435,12611,12612,33436,33437,33438,33439,33440,12613,12614,33441,33442,12615,
+33443,33444,33445,12616,33446,33447,33448,33449,33450,33451,33452,33453,33454,
+33455,33456,12617,12618,33457,33458,33459,33460,33461,33462,12619,33463,33464,
+33465,33466,33467,33468,33469,33470,33471,33472,33473,33474,33475,33476,33477,
+33478,33479,33480,12620,33481,33482,33483,33484,33485,33486,33487,33488,12621,
+12622,33489,33490,12623,33491,33492,33493,12624,33494,33495,33496,33497,33498,
+33499,33500,12625,12626,33501,12627,33502,33503,33504,33505,33506,33507,33508,
+33509,12628,33510,33511,33512,12629,33513,33514,33515,12630,33516,33517,33518,
+33519,33520,33521,33522,33523,33524,33525,33526,33527,33528,33529,33530,33531,
+33532,33533,33534,12631,12632,33601,33602,12633,33603,33604,12634,12635,12636,
+33605,33606,33607,33608,33609,33610,12637,12638,33611,12639,33612,12640,33613,
+33614,33615,33616,33617,33618,12641,33619,33620,33621,33622,33623,33624,33625,
+33626,33633,33634,33635,33636,33637,33638,33639,33640,33641,33642,33643,33644,
+33645,33646,33647,33648,33649,33650,33651,12642,12643,33652,33653,12644,33654,
+33655,12645,12646,33656,12647,33657,33658,33665,33666,33667,12648,12649,33668,
+12650,33669,12651,12652,33670,33671,33672,12653,33673,12654,12655,12656,33674,
+12657,33675,33676,33677,12658,33678,12659,33679,33680,33681,33682,33683,12660,
+12661,33684,12662,12663,12664,33685,33686,33687,12665,33688,33689,12666,12667,
+33690,33691,12668,33692,33693,33694,12669,33695,33696,33697,33698,33699,33700,
+33701,12670,12833,33702,12834,12835,12836,33703,33704,33705,33706,33707,33708,
+12837,12838,33709,33710,33711,33712,33713,33714,12839,33715,33716,33717,33718,
+33719,33720,33721,33722,33723,33724,33725,33726,33727,33728,33729,33730,33731,
+33732,33733,33734,33735,33736,33737,33738,33739,33740,33741,33742,33743,33744,
+33745,33746,33747,33748,33749,33750,33751,33752,33753,33754,33755,33756,33757,
+33758,33759,33760,33761,12840,12841,12842,33762,12843,33763,33764,33765,12844,
+33766,33767,33768,33769,33770,33771,33772,12845,12846,33773,12847,12848,12849,
+33774,33775,33776,33777,33778,33779,12850,12851,33780,33781,12852,33782,33783,
+33784,33785,33786,33787,33788,33789,33790,33857,33858,12853,33859,33860,12854,
+33861,12855,33862,33863,33864,33865,33866,33867,12856,33868,33869,33870,12857,
+33871,33872,33873,12858,33874,33875,33876,33877,33878,33879,33880,33881,33882,
+33889,12859,12860,33890,33891,33892,33893,12861,33894,33895,12862,33896,33897,
+33898,33899,33900,33901,33902,33903,33904,33905,33906,33907,33908,33909,33910,
+33911,33912,33913,33914,33921,33922,33923,33924,33925,33926,33927,33928,12863,
+12864,33929,33930,12865,33931,12866,33932,12867,33933,33934,33935,33936,33937,
+33938,33939,12868,12869,33940,12870,33941,12871,12872,12873,33942,33943,33944,
+33945,12874,12875,33946,33947,33948,33949,33950,33951,12876,33952,33953,33954,
+33955,33956,33957,33958,33959,33960,33961,33962,12877,12878,33963,33964,33965,
+33966,33967,33968,12879,12880,33969,33970,33971,33972,33973,33974,33975,33976,
+33977,33978,33979,33980,33981,33982,33983,33984,33985,33986,33987,12881,33988,
+33989,33990,33991,33992,33993,12882,33994,33995,33996,12883,33997,33998,33999,
+12884,34000,34001,34002,34003,34004,34005,34006,12885,12886,34007,34008,34009,
+12887,34010,34011,34012,34013,34014,34015,12888,34016,34017,34018,34019,34020,
+34021,34022,34023,34024,34025,34026,34027,34028,34029,34030,34031,34032,34033,
+34034,34035,34036,34037,34038,34039,34040,34041,34042,12889,12890,34043,34044,
+12891,34045,34046,34113,12892,34114,34115,34116,34117,34118,34119,12893,12894,
+12895,34120,12896,34121,12897,12898,34122,34123,34124,34125,34126,12899,34127,
+34128,34129,34130,34131,34132,34133,12900,34134,34135,34136,34137,34138,34145,
+34146,34147,34148,34149,34150,12901,12902,34151,34152,34153,34154,34155,34156,
+12903,12904,34157,34158,12905,34159,34160,34161,12906,34162,34163,34164,34165,
+34166,34167,34168,12907,12908,34169,34170,12909,34177,34178,34179,34180,34181,
+34182,34183,12910,34184,34185,34186,12911,34187,34188,34189,12912,34190,34191,
+34192,34193,34194,34195,34196,12913,12914,34197,34198,34199,34200,34201,34202,
+34203,34204,34205,34206,12915,34207,34208,34209,34210,34211,34212,34213,34214,
+34215,34216,34217,34218,34219,34220,34221,34222,34223,34224,34225,34226,34227,
+34228,34229,34230,34231,34232,34233,12916,12917,34234,34235,12918,34236,12919,
+34237,12920,34238,12921,34239,34240,34241,34242,12922,12923,12924,34243,12925,
+34244,12926,34245,34246,34247,13089,34248,34249,34250,34251,34252,34253,34254,
+34255,34256,34257,34258,34259,34260,34261,34262,34263,34264,34265,34266,34267,
+34268,34269,34270,34271,34272,34273,34274,34275,34276,34277,13090,13091,34278,
+34279,13092,34280,34281,34282,13093,34283,34284,34285,34286,34287,34288,34289,
+13094,13095,34290,13096,34291,13097,34292,34293,34294,34295,34296,34297,13098,
+13099,13100,34298,13101,34299,34300,13102,13103,13104,13105,34301,34302,34369,
+34370,34371,13106,13107,34372,13108,13109,13110,13111,13112,34373,13113,34374,
+13114,13115,13116,34375,34376,13117,34377,34378,34379,13118,34380,34381,34382,
+34383,34384,34385,34386,13119,13120,34387,13121,13122,13123,34388,34389,34390,
+34391,34392,34393,13124,13125,34394,34401,13126,34402,34403,34404,13127,34405,
+34406,34407,34408,34409,34410,34411,13128,34412,34413,34414,34415,13129,34416,
+34417,34418,34419,34420,34421,34422,34423,34424,34425,34426,34433,34434,34435,
+34436,34437,34438,34439,34440,34441,34442,34443,34444,34445,34446,34447,34448,
+34449,34450,34451,34452,34453,34454,34455,13130,13131,34456,13132,13133,34457,
+34458,34459,13134,34460,13135,13136,34461,34462,34463,34464,13137,13138,34465,
+13139,13140,13141,34466,34467,34468,34469,34470,13142,13143,13144,34471,34472,
+13145,34473,34474,34475,13146,34476,34477,34478,34479,34480,34481,34482,13147,
+13148,34483,13149,13150,13151,34484,34485,34486,34487,34488,34489,13152,13153,
+34490,34491,13154,34492,34493,34494,13155,34495,34496,34497,34498,34499,34500,
+34501,13156,13157,34502,34503,13158,13159,34504,34505,13160,34506,34507,34508,
+13161,34509,34510,34511,13162,34512,34513,34514,34515,34516,34517,34518,34519,
+34520,34521,34522,34523,34524,34525,34526,34527,34528,34529,34530,34531,34532,
+34533,34534,13163,13164,34535,34536,13165,34537,34538,34539,13166,34540,13167,
+34541,34542,34543,34544,34545,13168,13169,34546,13170,34547,13171,34548,34549,
+34550,34551,13172,13173,13174,34552,34553,34554,13175,34555,34556,34557,13176,
+34558,34625,34626,34627,34628,34629,34630,34631,34632,34633,34634,13177,34635,
+34636,34637,34638,34639,34640,34641,34642,34643,34644,34645,34646,34647,34648,
+34649,34650,34657,34658,34659,34660,34661,34662,34663,34664,34665,34666,34667,
+34668,34669,34670,34671,34672,34673,34674,34675,13178,34676,34677,34678,13179,
+34679,34680,34681,13180,34682,34689,34690,34691,34692,34693,34694,13181,13182,
+34695,13345,34696,34697,34698,34699,34700,34701,34702,34703,13346,13347,34704,
+34705,13348,34706,34707,34708,13349,34709,34710,34711,34712,34713,34714,34715,
+34716,13350,34717,13351,34718,13352,34719,34720,34721,34722,34723,34724,13353,
+13354,34725,34726,13355,34727,34728,13356,13357,34729,34730,34731,34732,34733,
+34734,34735,13358,13359,34736,13360,34737,13361,34738,34739,34740,34741,34742,
+34743,13362,34744,34745,34746,34747,34748,34749,34750,34751,34752,34753,34754,
+34755,34756,34757,34758,34759,34760,34761,34762,13363,34763,34764,34765,34766,
+34767,34768,34769,13364,34770,34771,34772,34773,34774,34775,34776,34777,34778,
+34779,34780,34781,34782,34783,34784,34785,34786,34787,34788,34789,34790,34791,
+34792,34793,34794,34795,34796,13365,34797,34798,34799,13366,34800,34801,34802,
+13367,34803,34804,34805,34806,34807,34808,34809,13368,13369,34810,34811,34812,
+34813,34814,34881,34882,34883,34884,34885,13370,13371,34886,34887,34888,34889,
+34890,34891,13372,34892,34893,34894,34895,34896,34897,34898,13373,13374,34899,
+34900,34901,13375,34902,34903,34904,34905,34906,34913,13376,13377,34914,34915,
+13378,34916,34917,34918,13379,13380,13381,34919,34920,34921,34922,34923,13382,
+13383,34924,13384,34925,13385,13386,34926,34927,34928,13387,34929,13388,34930,
+34931,34932,13389,34933,34934,34935,13390,34936,34937,34938,34945,34946,34947,
+34948,34949,34950,34951,34952,34953,34954,34955,34956,34957,34958,34959,34960,
+13391,13392,34961,34962,13393,34963,34964,34965,13394,34966,13395,34967,34968,
+34969,34970,34971,13396,13397,34972,13398,34973,13399,34974,34975,34976,34977,
+13400,34978,13401,13402,13403,34979,13404,34980,34981,13405,13406,13407,13408,
+13409,34982,34983,34984,13410,13411,13412,34985,13413,13414,13415,13416,13417,
+34986,34987,34988,13418,13419,13420,34989,34990,13421,34991,34992,34993,13422,
+34994,34995,34996,34997,34998,34999,35000,13423,13424,35001,13425,13426,13427,
+35002,35003,35004,35005,35006,35007,13428,35008,35009,35010,35011,35012,35013,
+35014,35015,35016,35017,35018,35019,35020,35021,35022,35023,35024,35025,35026,
+35027,35028,35029,35030,35031,35032,35033,35034,35035,35036,35037,35038,35039,
+35040,35041,35042,35043,35044,35045,35046,35047,35048,35049,35050,35051,35052,
+35053,35054,35055,35056,35057,35058,35059,35060,35061,35062,13429,13430,13431,
+35063,13432,35064,35065,13433,13434,35066,13435,13436,35067,35068,35069,35070,
+13437,13438,35137,13601,35138,13602,35139,13603,35140,35141,13604,35142,13605,
+13606,35143,35144,13607,35145,35146,35147,13608,35148,35149,35150,35151,35152,
+35153,35154,13609,13610,35155,13611,13612,13613,35156,35157,35158,35159,35160,
+35161,13614,35162,35169,35170,13615,35171,35172,35173,13616,35174,35175,35176,
+35177,35178,35179,35180,35181,35182,35183,35184,13617,13618,35185,35186,35187,
+35188,35189,35190,13619,35191,35192,35193,13620,35194,35201,35202,35203,35204,
+35205,35206,35207,35208,35209,35210,35211,35212,35213,35214,35215,35216,35217,
+35218,35219,35220,35221,35222,13621,13622,35223,35224,13623,35225,35226,13624,
+13625,35227,13626,35228,13627,35229,35230,35231,13628,13629,35232,13630,35233,
+13631,35234,13632,35235,13633,35236,35237,13634,35238,35239,35240,13635,35241,
+35242,35243,13636,35244,35245,35246,35247,35248,35249,35250,35251,35252,35253,
+35254,35255,35256,35257,35258,35259,35260,35261,35262,13637,35263,35264,35265,
+35266,35267,35268,35269,35270,35271,35272,35273,35274,35275,35276,35277,35278,
+35279,35280,35281,13638,35282,35283,35284,35285,35286,35287,35288,13639,35289,
+35290,35291,13640,35292,35293,35294,13641,35295,35296,35297,35298,35299,35300,
+35301,13642,13643,35302,13644,35303,35304,35305,35306,35307,35308,35309,35310,
+13645,35311,35312,35313,35314,35315,35316,35317,35318,35319,35320,35321,35322,
+35323,35324,35325,35326,35393,35394,35395,35396,35397,35398,35399,35400,35401,
+35402,35403,13646,13647,35404,35405,13648,35406,35407,35408,13649,35409,35410,
+35411,35412,35413,35414,35415,13650,13651,35416,13652,35417,13653,35418,35425,
+35426,35427,35428,35429,13654,35430,35431,35432,35433,35434,35435,35436,35437,
+35438,35439,35440,35441,35442,35443,35444,35445,35446,35447,35448,13655,35449,
+35450,35457,35458,35459,35460,35461,13656,35462,35463,35464,35465,35466,35467,
+35468,35469,35470,35471,35472,35473,35474,35475,35476,35477,35478,35479,35480,
+35481,13657,35482,35483,35484,35485,35486,35487,13658,35488,35489,35490,13659,
+35491,35492,35493,13660,35494,35495,35496,35497,35498,35499,35500,35501,13661,
+35502,13662,35503,13663,35504,35505,35506,35507,35508,35509,13664,35510,35511,
+35512,13665,35513,35514,35515,13666,35516,35517,35518,35519,35520,35521,35522,
+13667,35523,35524,35525,35526,13668,35527,35528,35529,35530,35531,35532,13669,
+13670,35533,35534,13671,35535,35536,13672,13673,35537,13674,35538,35539,35540,
+35541,35542,13675,13676,35543,13677,35544,13678,35545,35546,35547,35548,35549,
+35550,13679,35551,35552,35553,35554,35555,35556,35557,35558,35559,35560,35561,
+35562,35563,35564,35565,35566,35567,35568,35569,35570,35571,35572,35573,35574,
+35575,35576,35577,13680,13681,35578,35579,13682,35580,35581,13683,13684,35582,
+35649,35650,35651,35652,35653,35654,13685,13686,35655,13687,13688,13689,13690,
+35656,35657,35658,35659,35660,13691,13692,35661,35662,13693,35663,35664,35665,
+13694,35666,35667,35668,35669,35670,35671,35672,13857,13858,35673,13859,13860,
+13861,35674,35681,35682,35683,35684,13862,13863,13864,35685,35686,13865,35687,
+35688,35689,13866,35690,35691,35692,35693,35694,35695,35696,13867,13868,35697,
+13869,13870,13871,35698,35699,35700,35701,35702,35703,35704,35705,35706,35713,
+35714,35715,35716,35717,35718,35719,35720,35721,35722,35723,35724,35725,35726,
+35727,35728,35729,35730,35731,35732,35733,35734,35735,35736,35737,35738,35739,
+35740,35741,35742,35743,35744,35745,35746,35747,35748,35749,35750,35751,35752,
+35753,35754,35755,35756,35757,35758,35759,35760,35761,35762,35763,35764,35765,
+13872,13873,35766,35767,13874,35768,35769,35770,13875,35771,13876,13877,35772,
+35773,35774,35775,13878,13879,35776,13880,13881,13882,35777,35778,35779,35780,
+35781,13883,13884,13885,35782,35783,13886,35784,35785,35786,13887,35787,35788,
+35789,35790,35791,35792,35793,13888,13889,35794,13890,13891,13892,35795,35796,
+35797,35798,35799,35800,13893,35801,35802,35803,35804,35805,35806,35807,35808,
+35809,35810,35811,35812,35813,35814,35815,35816,35817,35818,35819,13894,35820,
+35821,35822,35823,35824,35825,35826,35827,35828,35829,35830,35831,35832,35833,
+35834,35835,35836,35837,35838,35905,35906,35907,35908,35909,35910,35911,35912,
+35913,35914,35915,35916,35917,35918,35919,35920,13895,13896,35921,35922,13897,
+35923,35924,35925,13898,35926,35927,35928,35929,35930,35937,35938,35939,35940,
+35941,35942,35943,13899,35944,35945,35946,35947,35948,35949,13900,35950,35951,
+35952,35953,35954,35955,35956,13901,35957,35958,35959,35960,35961,35962,35969,
+35970,35971,35972,35973,35974,35975,35976,35977,35978,35979,35980,35981,13902,
+35982,35983,35984,35985,35986,35987,35988,35989,35990,35991,35992,35993,35994,
+35995,35996,35997,35998,35999,36000,36001,36002,36003,36004,36005,36006,36007,
+36008,13903,36009,36010,36011,13904,36012,36013,36014,36015,36016,36017,36018,
+36019,36020,36021,36022,36023,36024,36025,36026,36027,36028,36029,36030,36031,
+36032,36033,36034,36035,36036,36037,36038,36039,36040,36041,36042,36043,36044,
+36045,36046,36047,36048,36049,36050,36051,36052,36053,36054,36055,36056,36057,
+36058,36059,36060,36061,36062,13905,13906,36063,36064,13907,36065,36066,36067,
+13908,36068,36069,36070,36071,36072,36073,13909,13910,36074,36075,36076,36077,
+13911,36078,36079,36080,36081,36082,36083,36084,36085,36086,36087,36088,36089,
+36090,36091,36092,36093,36094,36161,36162,36163,36164,36165,36166,36167,36168,
+36169,36170,36171,36172,36173,36174,36175,36176,36177,13912,36178,36179,36180,
+36181,36182,36183,36184,36185,36186,36193,36194,36195,36196,36197,36198,36199,
+36200,36201,36202,36203,36204,36205,36206,36207,36208,36209,36210,13913,36211,
+36212,36213,13914,36214,36215,36216,13915,36217,36218,36225,36226,36227,36228,
+36229,13916,13917,36230,36231,36232,13918,36233,36234,36235,36236,36237,36238,
+36239,36240,36241,36242,36243,36244,36245,36246,36247,36248,36249,36250,36251,
+36252,36253,36254,36255,36256,36257,36258,36259,36260,36261,36262,36263,36264,
+36265,36266,13919,13920,36267,36268,13921,36269,36270,13922,13923,36271,36272,
+36273,36274,36275,36276,36277,13924,13925,36278,13926,36279,36280,36281,36282,
+36283,36284,36285,36286,13927,36287,36288,36289,13928,36290,36291,36292,13929,
+36293,36294,36295,36296,36297,36298,36299,13930,13931,36300,36301,36302,36303,
+36304,36305,36306,36307,36308,36309,13932,36310,36311,36312,13933,36313,36314,
+36315,13934,36316,36317,36318,36319,36320,36321,36322,13935,13936,36323,13937,
+36324,13938,36325,36326,36327,36328,36329,36330,13939,13940,36331,36332,13941,
+36333,36334,36335,13942,36336,36337,36338,36339,36340,36341,36342,13943,13944,
+36343,13945,13946,13947,13948,36344,36345,36346,13949,13950,14113,14114,36347,
+36348,14115,36349,36350,36417,14116,36418,36419,36420,36421,36422,36423,36424,
+14117,14118,36425,14119,14120,14121,36426,36427,36428,36429,36430,36431,14122,
+14123,36432,36433,14124,36434,36435,36436,36437,36438,36439,36440,36441,36442,
+36449,36450,36451,36452,36453,14125,36454,14126,36455,36456,36457,36458,36459,
+36460,36461,36462,36463,36464,36465,36466,36467,36468,36469,36470,36471,36472,
+36473,36474,36481,36482,36483,36484,36485,36486,36487,36488,36489,36490,36491,
+36492,36493,36494,14127,14128,36495,36496,14129,36497,36498,36499,14130,36500,
+36501,36502,36503,36504,36505,36506,14131,14132,36507,14133,14134,14135,36508,
+36509,36510,36511,36512,14136,14137,14138,36513,36514,14139,36515,36516,36517,
+14140,36518,36519,36520,36521,36522,36523,36524,14141,14142,36525,14143,36526,
+14144,36527,36528,36529,36530,36531,36532,14145,14146,36533,36534,14147,36535,
+36536,36537,14148,36538,36539,36540,36541,36542,36543,36544,14149,14150,36545,
+14151,14152,14153,36546,36547,36548,36549,36550,36551,14154,36552,36553,36554,
+14155,36555,36556,36557,36558,36559,36560,36561,36562,36563,36564,36565,36566,
+14156,36567,14157,36568,36569,36570,36571,36572,36573,36574,36575,14158,14159,
+36576,36577,14160,36578,36579,36580,14161,36581,36582,36583,36584,36585,36586,
+36587,14162,14163,36588,14164,36589,14165,36590,36591,36592,36593,36594,36595,
+14166,36596,36597,36598,14167,36599,36600,36601,36602,36603,36604,36605,36606,
+36673,36674,36675,36676,36677,36678,36679,36680,14168,36681,36682,36683,36684,
+36685,36686,36687,36688,36689,36690,36691,36692,36693,36694,36695,36696,36697,
+36698,36705,36706,36707,36708,36709,36710,36711,36712,14169,36713,36714,36715,
+36716,36717,36718,36719,14170,36720,36721,36722,14171,36723,36724,36725,14172,
+36726,36727,36728,36729,36730,36737,36738,14173,14174,36739,14175,36740,14176,
+36741,36742,36743,36744,36745,36746,14177,36747,36748,36749,14178,36750,36751,
+36752,14179,36753,36754,36755,36756,36757,36758,36759,36760,14180,36761,14181,
+36762,14182,36763,36764,36765,36766,36767,36768,14183,14184,36769,36770,14185,
+36771,36772,36773,14186,36774,36775,36776,36777,36778,36779,36780,14187,14188,
+36781,14189,36782,14190,36783,36784,36785,36786,36787,36788,14191,36789,36790,
+36791,36792,36793,36794,36795,36796,36797,36798,36799,36800,36801,36802,36803,
+36804,36805,36806,36807,14192,36808,36809,36810,36811,36812,36813,36814,14193,
+36815,36816,36817,36818,36819,36820,36821,36822,36823,36824,36825,36826,36827,
+36828,36829,36830,36831,36832,36833,36834,36835,36836,36837,36838,36839,36840,
+36841,14194,14195,36842,36843,14196,36844,36845,36846,14197,36847,36848,36849,
+36850,36851,36852,36853,14198,36854,36855,14199,36856,14200,36857,36858,36859,
+36860,36861,36862,14201,14202,36929,36930,14203,36931,36932,36933,14204,36934,
+36935,36936,36937,36938,36939,36940,14205,14206,36941,14369,36942,14370,36943,
+36944,36945,36946,36947,36948,14371,14372,36949,36950,14373,36951,36952,36953,
+14374,36954,36961,36962,36963,36964,36965,36966,14375,14376,36967,14377,36968,
+14378,14379,36969,36970,14380,14381,36971,36972,36973,36974,36975,36976,36977,
+36978,36979,36980,36981,36982,36983,36984,36985,36986,36993,36994,36995,36996,
+36997,36998,36999,37000,37001,37002,37003,37004,37005,14382,14383,37006,37007,
+14384,37008,37009,37010,14385,37011,37012,37013,37014,37015,37016,37017,14386,
+14387,37018,14388,37019,14389,37020,37021,37022,37023,37024,37025,14390,14391,
+37026,37027,14392,37028,14393,14394,14395,14396,14397,37029,37030,37031,37032,
+37033,14398,14399,37034,14400,37035,14401,14402,37036,37037,14403,37038,14404,
+14405,14406,37039,37040,14407,37041,37042,37043,14408,37044,37045,37046,37047,
+37048,37049,37050,14409,14410,37051,14411,14412,14413,14414,37052,37053,37054,
+37055,37056,14415,14416,37057,37058,37059,37060,37061,37062,14417,37063,37064,
+37065,37066,37067,37068,37069,37070,37071,37072,37073,37074,14418,37075,37076,
+37077,37078,37079,37080,37081,37082,37083,37084,37085,37086,37087,37088,37089,
+37090,37091,37092,37093,37094,37095,37096,37097,37098,37099,37100,37101,37102,
+37103,37104,37105,37106,37107,37108,14419,14420,37109,37110,14421,37111,37112,
+37113,14422,37114,14423,37115,37116,37117,37118,37185,14424,14425,37186,14426,
+37187,14427,14428,37188,37189,37190,37191,14429,14430,14431,37192,37193,14432,
+37194,37195,37196,14433,37197,37198,37199,37200,37201,37202,37203,14434,14435,
+37204,14436,14437,14438,37205,37206,37207,37208,37209,37210,14439,14440,37217,
+37218,14441,37219,37220,37221,14442,37222,37223,37224,37225,37226,37227,37228,
+37229,37230,37231,14443,14444,14445,37232,14446,37233,37234,37235,37236,14447,
+37237,37238,37239,37240,37241,37242,37249,37250,37251,37252,37253,37254,37255,
+37256,37257,37258,37259,37260,37261,37262,37263,37264,37265,37266,37267,37268,
+37269,14448,14449,37270,14450,14451,37271,37272,37273,14452,37274,14453,37275,
+37276,37277,37278,37279,14454,14455,37280,14456,37281,14457,37282,37283,37284,
+37285,37286,37287,14458,37288,37289,37290,14459,37291,37292,37293,37294,37295,
+37296,37297,37298,37299,37300,37301,37302,37303,37304,37305,14460,14461,37306,
+37307,37308,37309,37310,37311,37312,37313,37314,37315,37316,37317,37318,37319,
+37320,37321,37322,37323,37324,37325,37326,37327,37328,37329,37330,37331,37332,
+37333,37334,37335,37336,37337,37338,37339,14462,37340,37341,37342,14625,37343,
+37344,37345,14626,37346,37347,37348,37349,37350,37351,37352,37353,14627,37354,
+14628,37355,14629,37356,37357,37358,37359,37360,37361,14630,37362,37363,37364,
+14631,37365,37366,37367,14632,37368,37369,37370,37371,37372,37373,37374,37441,
+14633,37442,14634,37443,37444,37445,37446,37447,37448,37449,37450,14635,14636,
+14637,37451,14638,37452,37453,14639,14640,14641,14642,37454,37455,37456,37457,
+37458,14643,14644,37459,14645,37460,14646,37461,37462,37463,14647,37464,14648,
+14649,37465,37466,37473,14650,37474,37475,37476,14651,37477,37478,37479,37480,
+37481,37482,37483,37484,14652,37485,14653,37486,37487,37488,37489,37490,37491,
+37492,37493,14654,37494,37495,37496,37497,37498,37505,37506,37507,37508,37509,
+37510,37511,37512,37513,37514,37515,37516,37517,37518,37519,37520,37521,37522,
+37523,37524,37525,37526,14655,37527,37528,37529,14656,37530,37531,37532,14657,
+37533,37534,37535,37536,37537,37538,37539,37540,37541,37542,37543,37544,37545,
+37546,37547,37548,37549,37550,37551,14658,37552,37553,37554,14659,37555,37556,
+37557,14660,37558,37559,37560,37561,37562,37563,37564,14661,37565,37566,14662,
+37567,37568,37569,37570,37571,37572,37573,37574,14663,37575,37576,37577,14664,
+37578,37579,37580,14665,37581,37582,37583,37584,37585,37586,37587,14666,37588,
+37589,14667,37590,37591,37592,37593,37594,37595,37596,37597,37598,37599,37600,
+37601,37602,37603,37604,37605,37606,37607,37608,37609,37610,37611,37612,37613,
+37614,37615,37616,37617,37618,37619,37620,37621,37622,37623,37624,37625,14668,
+14669,37626,37627,14670,37628,37629,14671,14672,37630,14673,37697,37698,37699,
+37700,37701,14674,14675,37702,14676,14677,14678,37703,14679,37704,14680,37705,
+37706,14681,14682,14683,14684,14685,37707,37708,14686,14687,14688,14689,14690,
+37709,37710,37711,37712,14691,14692,37713,14693,37714,14694,37715,37716,37717,
+14695,37718,37719,14696,14697,37720,37721,14698,37722,37729,37730,14699,37731,
+37732,37733,37734,37735,37736,37737,14700,14701,37738,14702,14703,14704,37739,
+37740,37741,14705,37742,37743,14706,14707,37744,37745,14708,37746,37747,37748,
+37749,37750,37751,37752,37753,37754,37761,37762,37763,14709,37764,37765,37766,
+37767,37768,37769,37770,37771,37772,37773,37774,37775,37776,37777,37778,37779,
+37780,37781,37782,37783,37784,37785,37786,37787,37788,37789,37790,37791,37792,
+37793,37794,37795,37796,37797,37798,37799,37800,37801,14710,14711,37802,37803,
+14712,37804,37805,14713,14714,37806,14715,37807,37808,37809,37810,37811,14716,
+14717,37812,14718,37813,14881,14882,37814,37815,37816,37817,37818,14883,14884,
+37819,37820,14885,37821,37822,14886,14887,37823,37824,37825,37826,37827,37828,
+37829,14888,14889,37830,14890,14891,14892,37831,37832,37833,37834,37835,37836,
+14893,14894,37837,37838,14895,37839,37840,37841,14896,37842,37843,37844,37845,
+37846,37847,37848,37849,14897,37850,14898,14899,14900,37851,37852,37853,14901,
+37854,37855,14902,37856,37857,37858,14903,37859,37860,37861,37862,37863,37864,
+37865,37866,37867,37868,37869,37870,37871,37872,37873,37874,37875,37876,37877,
+37878,37879,37880,37881,14904,14905,14906,37882,14907,37883,37884,37885,14908,
+37886,37953,37954,37955,37956,37957,37958,14909,14910,37959,14911,37960,14912,
+37961,37962,37963,37964,37965,37966,14913,37967,37968,37969,14914,37970,37971,
+37972,37973,37974,37975,37976,37977,37978,37985,37986,37987,37988,37989,37990,
+14915,37991,37992,37993,37994,37995,37996,37997,14916,37998,37999,38000,38001,
+38002,38003,38004,38005,38006,38007,38008,38009,38010,38017,38018,38019,38020,
+38021,38022,14917,38023,38024,38025,38026,38027,38028,38029,14918,14919,38030,
+38031,14920,38032,38033,38034,14921,38035,38036,38037,38038,38039,38040,38041,
+14922,14923,38042,38043,38044,38045,38046,38047,38048,38049,38050,38051,14924,
+38052,38053,38054,14925,38055,38056,38057,38058,38059,38060,38061,38062,38063,
+38064,38065,38066,38067,38068,38069,38070,38071,38072,38073,38074,38075,38076,
+38077,14926,14927,38078,38079,14928,38080,38081,14929,14930,14931,14932,38082,
+38083,38084,38085,38086,14933,14934,38087,14935,38088,14936,38089,38090,38091,
+14937,14938,38092,14939,38093,38094,38095,38096,38097,38098,38099,14940,38100,
+38101,38102,38103,38104,38105,38106,38107,38108,38109,38110,14941,38111,38112,
+38113,38114,38115,38116,38117,14942,38118,38119,38120,38121,38122,38123,38124,
+38125,38126,38127,38128,38129,38130,38131,38132,38133,38134,38135,38136,38137,
+38138,38139,38140,38141,38142,38209,38210,14943,14944,38211,38212,14945,38213,
+38214,38215,14946,38216,38217,38218,38219,38220,38221,38222,38223,38224,38225,
+38226,38227,14947,38228,38229,38230,38231,38232,38233,14948,38234,38241,38242,
+14949,38243,38244,38245,14950,38246,38247,38248,38249,38250,38251,38252,14951,
+38253,38254,14952,38255,14953,38256,38257,38258,38259,38260,38261,14954,14955,
+38262,38263,14956,38264,38265,38266,14957,38273,38274,38275,38276,38277,38278,
+38279,14958,14959,38280,14960,38281,38282,38283,38284,38285,38286,38287,38288,
+38289,38290,38291,38292,38293,38294,38295,38296,38297,38298,38299,38300,38301,
+38302,38303,38304,38305,38306,38307,38308,38309,38310,38311,38312,38313,38314,
+38315,38316,14961,14962,38317,38318,14963,38319,38320,38321,14964,38322,14965,
+38323,38324,38325,38326,38327,14966,14967,38328,14968,38329,14969,14970,14971,
+38330,38331,38332,38333,14972,14973,38334,38335,14974,38336,38337,38338,15137,
+38339,15138,38340,38341,38342,38343,38344,15139,15140,38345,15141,15142,15143,
+38346,38347,38348,38349,38350,15144,15145,15146,38351,38352,15147,38353,38354,
+38355,15148,38356,38357,38358,38359,38360,38361,38362,15149,15150,38363,15151,
+15152,15153,38364,38365,38366,38367,38368,38369,15154,15155,38370,38371,38372,
+38373,38374,38375,38376,38377,38378,38379,38380,38381,38382,38383,15156,38384,
+38385,38386,38387,38388,38389,38390,38391,38392,38393,38394,38395,38396,38397,
+38398,38465,38466,38467,38468,38469,38470,38471,38472,38473,38474,38475,38476,
+38477,38478,38479,38480,38481,38482,38483,38484,38485,38486,38487,38488,15157,
+15158,38489,38490,15159,38497,38498,15160,15161,38499,38500,38501,38502,38503,
+38504,38505,15162,38506,38507,15163,15164,15165,38508,38509,38510,38511,38512,
+38513,15166,38514,38515,38516,38517,38518,38519,38520,38521,38522,38529,38530,
+38531,38532,38533,38534,38535,38536,38537,38538,38539,15167,38540,38541,38542,
+38543,38544,38545,15168,15169,38546,38547,38548,38549,38550,38551,38552,38553,
+38554,38555,38556,38557,38558,38559,15170,15171,38560,15172,15173,15174,38561,
+38562,38563,38564,38565,38566,38567,38568,38569,38570,38571,38572,38573,38574,
+38575,38576,38577,38578,38579,38580,38581,38582,38583,38584,38585,38586,38587,
+38588,38589,38590,38591,38592,38593,38594,15175,15176,38595,38596,15177,38597,
+38598,38599,15178,38600,38601,38602,38603,38604,38605,38606,15179,15180,38607,
+38608,38609,15181,38610,38611,38612,38613,38614,38615,38616,38617,38618,38619,
+38620,38621,38622,38623,38624,38625,38626,38627,38628,38629,38630,38631,38632,
+38633,38634,38635,38636,38637,38638,38639,38640,38641,38642,38643,38644,38645,
+38646,38647,38648,38649,38650,38651,38652,38653,38654,38721,38722,38723,38724,
+38725,38726,38727,38728,38729,38730,38731,38732,38733,38734,38735,38736,38737,
+15182,38738,38739,38740,38741,38742,38743,38744,38745,38746,38753,38754,38755,
+38756,38757,38758,38759,38760,38761,38762,38763,38764,38765,38766,38767,38768,
+38769,38770,15183,38771,38772,38773,38774,38775,38776,38777,38778,38785,38786,
+38787,38788,38789,38790,38791,38792,38793,38794,38795,38796,15184,38797,38798,
+38799,38800,38801,38802,15185,15186,38803,38804,15187,38805,38806,38807,15188,
+38808,38809,38810,38811,38812,38813,38814,15189,38815,38816,15190,38817,15191,
+38818,38819,38820,38821,38822,38823,38824,38825,38826,38827,38828,38829,38830,
+38831,38832,38833,38834,38835,38836,38837,38838,38839,38840,38841,38842,38843,
+38844,38845,38846,38847,38848,38849,38850,38851,38852,38853,38854,38855,38856,
+38857,38858,38859,38860,38861,38862,38863,38864,38865,38866,38867,38868,38869,
+38870,38871,38872,38873,38874,38875,38876,38877,38878,38879,38880,38881,38882,
+38883,38884,38885,38886,38887,38888,38889,38890,38891,38892,38893,38894,38895,
+38896,38897,38898,38899,38900,38901,38902,38903,38904,38905,38906,38907,15192,
+38908,38909,38910,38977,38978,38979,38980,38981,38982,38983,38984,38985,38986,
+38987,38988,38989,38990,38991,38992,38993,15193,38994,38995,38996,38997,38998,
+38999,15194,39000,39001,39002,15195,39009,39010,39011,15196,39012,39013,39014,
+39015,39016,39017,39018,15197,15198,39019,39020,39021,39022,39023,39024,39025,
+39026,39027,39028,39029,39030,39031,39032,39033,39034,39041,39042,39043,39044,
+39045,39046,39047,39048,39049,39050,39051,39052,39053,39054,39055,39056,39057,
+39058,39059,39060,39061,39062,15199,15200,39063,39064,15201,39065,39066,39067,
+15202,39068,39069,39070,39071,39072,39073,39074,15203,15204,39075,15205,39076,
+15206,39077,39078,39079,39080,39081,39082,15207,15208,39083,15209,15210,39084,
+39085,15211,15212,15213,15214,39086,39087,39088,39089,39090,15215,15216,39091,
+15217,15218,15219,39092,39093,39094,15220,39095,39096,15221,15222,39097,39098,
+15223,39099,39100,39101,15224,39102,39103,39104,39105,39106,39107,39108,15225,
+15226,39109,15227,15228,15229,39110,39111,39112,39113,39114,39115,15230,15393,
+39116,39117,15394,39118,39119,39120,15395,39121,39122,39123,39124,39125,39126,
+39127,15396,15397,39128,15398,39129,15399,39130,39131,39132,39133,39134,39135,
+15400,39136,39137,39138,15401,39139,39140,39141,15402,39142,39143,39144,39145,
+39146,39147,39148,15403,39149,39150,39151,39152,15404,39153,39154,39155,39156,
+39157,39158,15405,15406,15407,15408,15409,39159,39160,15410,15411,39161,15412,
+15413,39162,39163,39164,39165,15414,15415,39166,15416,15417,15418,39233,39234,
+39235,39236,15419,39237,15420,15421,39238,39239,15422,39240,39241,39242,15423,
+39243,39244,39245,39246,39247,39248,39249,15424,15425,39250,15426,15427,15428,
+39251,39252,39253,39254,39255,39256,15429,15430,39257,39258,15431,39265,39266,
+39267,15432,39268,39269,39270,39271,39272,39273,39274,15433,15434,39275,15435,
+15436,15437,39276,39277,39278,39279,39280,39281,15438,39282,39283,39284,15439,
+39285,39286,39287,15440,39288,39289,39290,39297,39298,39299,39300,39301,39302,
+39303,39304,39305,15441,39306,39307,39308,39309,39310,39311,15442,15443,15444,
+39312,15445,39313,39314,39315,15446,39316,15447,39317,39318,39319,39320,39321,
+15448,15449,39322,15450,39323,15451,39324,39325,39326,15452,39327,39328,15453,
+15454,39329,39330,15455,39331,39332,39333,15456,39334,39335,39336,39337,39338,
+39339,39340,39341,39342,39343,39344,39345,15457,39346,39347,39348,39349,39350,
+39351,15458,39352,39353,39354,15459,39355,39356,39357,15460,39358,39359,39360,
+39361,39362,39363,39364,15461,39365,39366,15462,15463,39367,39368,39369,39370,
+39371,39372,39373,15464,39374,39375,39376,15465,39377,39378,39379,15466,39380,
+39381,39382,39383,39384,39385,39386,15467,15468,39387,15469,39388,39389,39390,
+39391,39392,39393,39394,39395,15470,15471,39396,39397,15472,39398,39399,39400,
+15473,39401,39402,39403,39404,39405,39406,39407,15474,15475,39408,15476,39409,
+15477,39410,39411,39412,39413,39414,39415,15478,15479,39416,39417,15480,39418,
+39419,15481,15482,39420,39421,39422,39489,39490,39491,39492,15483,15484,39493,
+15485,39494,15486,39495,15649,39496,15650,15651,39497,15652,39498,39499,39500,
+39501,39502,39503,39504,39505,39506,39507,39508,39509,39510,39511,39512,39513,
+39514,39521,39522,15653,39523,39524,39525,39526,39527,39528,39529,15654,15655,
+39530,39531,15656,39532,39533,39534,15657,39535,39536,39537,39538,39539,39540,
+39541,15658,39542,39543,39544,39545,15659,39546,39553,39554,39555,39556,39557,
+15660,15661,39558,39559,15662,39560,39561,39562,15663,39563,39564,39565,39566,
+39567,39568,39569,15664,15665,39570,15666,39571,15667,39572,39573,39574,39575,
+39576,39577,15668,15669,39578,39579,39580,39581,39582,39583,15670,39584,39585,
+39586,39587,39588,39589,39590,15671,39591,39592,15672,39593,15673,39594,39595,
+39596,39597,39598,39599,15674,15675,39600,39601,15676,39602,39603,39604,15677,
+15678,39605,39606,39607,39608,39609,39610,15679,15680,39611,15681,39612,15682,
+39613,39614,39615,39616,39617,39618,39619,39620,39621,39622,39623,39624,39625,
+39626,39627,39628,39629,39630,39631,39632,39633,39634,39635,39636,39637,39638,
+39639,39640,39641,39642,39643,39644,39645,39646,15683,15684,39647,39648,15685,
+39649,39650,15686,15687,39651,39652,39653,39654,39655,39656,15688,15689,15690,
+39657,15691,39658,15692,39659,39660,39661,39662,15693,39663,15694,15695,39664,
+15696,15697,39665,39666,39667,15698,39668,39669,39670,39671,39672,39673,39674,
+15699,15700,39675,39676,15701,15702,39677,39678,39745,39746,39747,15703,15704,
+15705,39748,39749,15706,39750,39751,39752,15707,39753,39754,39755,39756,39757,
+39758,39759,15708,15709,39760,39761,15710,15711,39762,39763,39764,39765,39766,
+39767,39768,39769,39770,39777,39778,39779,39780,39781,39782,39783,39784,39785,
+39786,39787,39788,39789,39790,39791,39792,39793,39794,15712,39795,39796,39797,
+39798,39799,39800,39801,39802,39809,39810,39811,39812,39813,39814,39815,39816,
+39817,39818,39819,39820,39821,39822,39823,39824,39825,39826,39827,39828,39829,
+39830,39831,39832,39833,39834,15713,15714,39835,39836,15715,39837,39838,39839,
+15716,39840,15717,39841,39842,39843,39844,39845,15718,15719,39846,39847,15720,
+15721,39848,39849,39850,39851,39852,39853,15722,39854,39855,39856,15723,39857,
+39858,39859,15724,39860,39861,39862,39863,39864,39865,39866,39867,39868,39869,
+39870,39871,39872,39873,39874,39875,39876,39877,39878,39879,39880,39881,39882,
+39883,39884,39885,39886,39887,39888,39889,39890,39891,39892,39893,39894,39895,
+39896,39897,39898,39899,39900,39901,39902,39903,39904,39905,39906,39907,39908,
+39909,39910,15725,39911,39912,39913,39914,39915,39916,39917,39918,39919,39920,
+39921,39922,39923,39924,39925,39926,39927,39928,39929,39930,39931,39932,39933,
+15726,15727,39934,40001,15728,40002,40003,15729,15730,40004,15731,40005,40006,
+40007,40008,40009,15732,15733,40010,40011,40012,15734,40013,40014,40015,40016,
+40017,40018,15735,15736,40019,40020,15737,40021,40022,40023,40024,40025,40026,
+40033,40034,40035,40036,40037,40038,40039,40040,40041,15738,40042,40043,40044,
+40045,40046,40047,40048,15739,40049,40050,40051,40052,40053,40054,40055,40056,
+40057,40058,40065,40066,40067,40068,40069,40070,40071,40072,40073,15740,40074,
+40075,40076,40077,40078,40079,40080,15741,40081,40082,40083,15742,40084,40085,
+40086,15905,40087,40088,40089,40090,40091,40092,40093,15906,15907,40094,40095,
+40096,40097,40098,40099,40100,40101,40102,40103,15908,40104,40105,40106,40107,
+40108,40109,40110,40111,40112,40113,40114,40115,40116,40117,40118,40119,40120,
+40121,40122,40123,40124,40125,40126,40127,40128,40129,40130,15909,15910,40131,
+40132,15911,40133,40134,40135,15912,40136,40137,40138,40139,40140,40141,40142,
+15913,15914,40143,40144,40145,15915,40146,40147,40148,40149,40150,40151,15916,
+40152,40153,40154,40155,40156,40157,40158,40159,40160,40161,40162,40163,40164,
+40165,40166,40167,40168,40169,40170,15917,40171,40172,40173,40174,40175,40176,
+40177,15918,40178,40179,40180,40181,40182,40183,40184,40185,40186,40187,40188,
+40189,40190,40257,40258,40259,40260,40261,40262,40263,40264,40265,40266,40267,
+40268,40269,40270,15919,40271,40272,40273,15920,40274,40275,40276,40277,40278,
+40279,40280,40281,40282,40289,40290,40291,40292,40293,40294,40295,40296,40297,
+40298,40299,40300,40301,40302,40303,40304,40305,40306,40307,40308,40309,40310,
+40311,40312,40313,40314,40321,40322,40323,40324,40325,40326,40327,40328,40329,
+15921,40330,40331,40332,40333,40334,40335,15922,15923,40336,40337,15924,40338,
+40339,40340,15925,40341,15926,40342,40343,40344,40345,15927,15928,15929,40346,
+40347,40348,40349,40350,40351,40352,40353,40354,40355,15930,40356,40357,40358,
+15931,40359,40360,40361,15932,40362,40363,40364,40365,40366,40367,40368,15933,
+40369,40370,40371,40372,40373,40374,40375,40376,40377,40378,40379,15934,15935,
+40380,40381,15936,40382,40383,40384,15937,40385,40386,40387,40388,40389,40390,
+40391,15938,15939,40392,15940,40393,15941,40394,40395,40396,40397,40398,40399,
+15942,15943,40400,40401,15944,15945,15946,40402,15947,15948,15949,40403,40404,
+40405,40406,15950,15951,15952,40407,15953,15954,15955,40408,40409,40410,15956,
+15957,40411,15958,15959,40412,40413,15960,40414,40415,40416,15961,40417,40418,
+40419,40420,40421,40422,40423,15962,15963,40424,15964,15965,15966,40425,40426,
+40427,40428,40429,40430,15967,15968,40431,40432,15969,40433,40434,40435,15970,
+40436,40437,15971,40438,40439,40440,40441,15972,15973,40442,15974,40443,15975,
+40444,40445,40446,15976,40513,15977,15978,40514,40515,40516,15979,40517,40518,
+40519,15980,40520,40521,40522,40523,40524,40525,40526,40527,15981,40528,40529,
+40530,40531,40532,40533,40534,40535,40536,40537,15982,15983,40538,40545,15984,
+15985,40546,15986,15987,15988,15989,40547,40548,40549,40550,40551,15990,15991,
+15992,15993,15994,15995,15996,40552,15997,40553,15998,40554,16161,16162,40555,
+40556,16163,40557,40558,40559,16164,40560,40561,40562,40563,40564,40565,40566,
+16165,16166,40567,16167,40568,16168,40569,40570,40577,40578,40579,40580,16169,
+16170,16171,40581,16172,40582,40583,40584,16173,40585,16174,16175,40586,40587,
+40588,40589,16176,16177,16178,16179,16180,16181,40590,40591,40592,16182,16183,
+16184,16185,40593,40594,40595,16186,40596,40597,40598,16187,40599,40600,40601,
+40602,40603,40604,40605,16188,16189,40606,16190,16191,40607,40608,40609,40610,
+40611,40612,40613,16192,16193,40614,40615,16194,40616,40617,40618,16195,16196,
+16197,40619,16198,40620,40621,16199,16200,16201,40622,16202,40623,16203,40624,
+16204,40625,40626,40627,40628,16205,16206,40629,40630,16207,40631,40632,40633,
+16208,40634,40635,40636,40637,40638,40639,40640,16209,16210,40641,16211,16212,
+16213,40642,40643,40644,40645,40646,40647,16214,16215,40648,40649,16216,40650,
+40651,40652,40653,40654,40655,40656,40657,40658,40659,40660,16217,40661,40662,
+16218,40663,16219,40664,40665,40666,40667,40668,40669,16220,16221,40670,40671,
+16222,40672,40673,40674,16223,40675,40676,40677,40678,40679,40680,40681,16224,
+16225,40682,16226,40683,16227,40684,40685,40686,40687,40688,40689,16228,16229,
+40690,40691,16230,40692,40693,40694,16231,40695,40696,40697,40698,40699,40700,
+40701,16232,16233,40702,16234,40769,16235,40770,40771,40772,40773,40774,40775,
+16236,16237,40776,40777,16238,40778,40779,40780,16239,16240,16241,40781,40782,
+40783,40784,40785,16242,16243,40786,16244,40787,16245,40788,40789,40790,40791,
+40792,40793,16246,16247,40794,40801,16248,40802,40803,40804,16249,40805,40806,
+40807,40808,40809,40810,40811,16250,16251,40812,40813,16252,16253,40814,40815,
+40816,40817,40818,40819,16254,16417,40820,40821,16418,40822,40823,40824,16419,
+40825,40826,40833,40834,40835,40836,40837,16420,16421,40838,40839,40840,16422,
+40841,40842,40843,40844,40845,40846,16423,16424,40847,40848,16425,40849,40850,
+40851,16426,40852,40853,40854,40855,40856,40857,40858,16427,16428,40859,16429,
+40860,16430,40861,40862,40863,40864,40865,40866,16431,16432,40867,40868,16433,
+40869,40870,40871,16434,40872,40873,40874,40875,40876,40877,40878,16435,16436,
+40879,16437,40880,16438,40881,16439,40882,40883,40884,40885,16440,16441,40886,
+40887,16442,40888,40889,40890,16443,40891,40892,40893,40894,40895,16444,40896,
+16445,16446,40897,16447,40898,16448,16449,16450,16451,16452,16453,16454,16455,
+40899,40900,40901,16456,40902,40903,40904,16457,40905,40906,40907,40908,40909,
+40910,40911,16458,40912,40913,16459,40914,40915,40916,40917,40918,40919,40920,
+40921,16460,16461,40922,40923,16462,40924,40925,40926,16463,16464,16465,40927,
+40928,40929,40930,16466,16467,16468,40931,16469,16470,16471,16472,40932,40933,
+40934,16473,40935,16474,16475,40936,40937,16476,40938,16477,16478,16479,40939,
+16480,40940,40941,40942,40943,40944,16481,16482,40945,16483,16484,16485,16486,
+40946,40947,40948,40949,40950,16487,16488,40951,40952,16489,40953,40954,40955,
+16490,40956,40957,40958,41025,41026,41027,41028,16491,16492,41029,16493,16494,
+16495,41030,41031,41032,41033,41034,41035,16496,16497,41036,41037,16498,41038,
+16499,41039,16500,41040,41041,41042,41043,41044,41045,41046,16501,41047,41048,
+41049,41050,16502,41057,41058,41059,41060,41061,41062,16503,41063,41064,41065,
+16504,41066,41067,41068,16505,41069,41070,41071,41072,41073,41074,41075,41076,
+41077,41078,41079,41080,41081,41082,41089,41090,41091,41092,41093,16506,16507,
+41094,41095,16508,41096,41097,41098,16509,41099,16510,41100,41101,41102,41103,
+41104,16673,16674,41105,16675,41106,16676,16677,41107,41108,41109,41110,41111,
+16678,16679,41112,41113,16680,41114,41115,41116,16681,41117,41118,41119,41120,
+41121,41122,41123,16682,16683,41124,16684,41125,16685,41126,41127,41128,41129,
+41130,41131,16686,41132,41133,41134,16687,41135,41136,41137,16688,41138,41139,
+41140,41141,41142,41143,41144,16689,16690,41145,41146,16691,16692,41147,41148,
+41149,41150,41151,41152,16693,41153,41154,41155,41156,41157,41158,41159,41160,
+41161,41162,41163,41164,41165,41166,41167,41168,41169,41170,41171,41172,41173,
+41174,41175,41176,41177,41178,41179,16694,16695,41180,41181,16696,41182,41183,
+41184,16697,41185,16698,41186,41187,41188,41189,41190,16699,16700,41191,16701,
+41192,16702,16703,16704,41193,41194,41195,16705,16706,16707,41196,41197,41198,
+41199,41200,41201,16708,41202,41203,41204,41205,41206,41207,41208,41209,16709,
+41210,16710,41211,16711,41212,41213,41214,41281,41282,41283,16712,41284,41285,
+41286,41287,41288,41289,41290,41291,41292,41293,41294,41295,41296,41297,41298,
+41299,41300,41301,41302,16713,16714,41303,41304,41305,41306,41313,41314,16715,
+41315,41316,41317,16716,41318,41319,41320,16717,41321,41322,41323,41324,41325,
+41326,41327,16718,16719,41328,16720,41329,16721,41330,41331,41332,41333,41334,
+41335,16722,16723,41336,41337,16724,41338,41345,41346,41347,41348,41349,41350,
+41351,41352,41353,41354,41355,41356,41357,41358,41359,16725,41360,41361,41362,
+41363,41364,41365,16726,16727,41366,41367,16728,41368,41369,41370,16729,16730,
+16731,41371,41372,41373,41374,41375,16732,16733,41376,16734,41537,16735,41538,
+41539,41540,41541,41542,41543,16736,41544,41545,41546,41547,41548,41549,41550,
+41551,41552,41553,41554,41555,41556,41557,41558,41559,41560,41561,41562,16737,
+41569,41570,41571,41572,41573,41574,41575,16738,41576,41577,41578,41579,41580,
+41581,41582,41583,41584,41585,41586,41587,41588,41589,41590,41591,41592,41593,
+41594,41601,41602,41603,41604,41605,41606,41607,41608,16739,16740,41609,41610,
+16741,41611,41612,41613,16742,41614,41615,41616,41617,41618,41619,41620,16743,
+16744,41621,16745,41622,41623,41624,41625,41626,41627,41628,41629,16746,41630,
+41631,41632,16747,41793,41794,41795,16748,41796,41797,41798,41799,41800,41801,
+41802,16749,41803,41804,41805,41806,41807,41808,41809,41810,41811,41812,41813,
+16750,16751,41814,41815,16752,41816,41817,41818,16753,41825,41826,41827,41828,
+41829,41830,41831,16754,16755,41832,16756,41833,16757,41834,41835,41836,41837,
+41838,41839,41840,41841,41842,41843,41844,41845,41846,41847,41848,41849,41850,
+41857,41858,41859,41860,41861,41862,41863,41864,41865,41866,41867,41868,41869,
+41870,41871,41872,41873,16758,16759,41874,41875,16760,41876,41877,16761,16762,
+41878,16763,41879,41880,41881,41882,41883,16764,16765,41884,16766,41885,16929,
+16930,41886,41887,16931,16932,41888,16933,16934,42049,42050,16935,42051,16936,
+42052,16937,42053,42054,16938,42055,42056,42057,42058,16939,16940,42059,16941,
+16942,16943,42060,42061,42062,42063,42064,42065,16944,16945,42066,42067,16946,
+42068,42069,42070,16947,42071,42072,42073,42074,42081,42082,42083,16948,16949,
+42084,16950,16951,16952,42085,42086,42087,42088,42089,42090,16953,42091,42092,
+42093,16954,42094,42095,42096,42097,42098,42099,42100,42101,42102,42103,42104,
+42105,42106,42113,42114,42115,16955,42116,42117,42118,42119,42120,42121,42122,
+42123,42124,42125,42126,42127,42128,42129,42130,42131,42132,42133,42134,42135,
+42136,42137,42138,42139,42140,42141,42142,42143,42144,42305,42306,42307,42308,
+42309,16956,16957,42310,42311,16958,42312,42313,42314,16959,42315,42316,42317,
+42318,42319,42320,42321,16960,16961,42322,16962,16963,16964,42323,42324,42325,
+42326,42327,42328,16965,42329,42330,42337,42338,42339,42340,42341,42342,42343,
+42344,42345,42346,42347,42348,42349,42350,42351,42352,42353,42354,16966,42355,
+42356,42357,42358,42359,42360,16967,42361,42362,42369,42370,42371,42372,42373,
+42374,42375,42376,42377,42378,42379,42380,42381,42382,42383,42384,42385,16968,
+42386,42387,42388,42389,42390,42391,42392,42393,42394,42395,42396,42397,42398,
+42399,42400,42561,42562,42563,42564,42565,42566,42567,42568,42569,42570,42571,
+42572,42573,42574,42575,42576,42577,42578,42579,42580,16969,16970,42581,42582,
+16971,42583,42584,42585,16972,42586,42593,42594,42595,42596,42597,42598,16973,
+16974,42599,16975,42600,16976,42601,16977,42602,42603,42604,42605,16978,16979,
+42606,42607,42608,42609,42610,42611,16980,42612,42613,42614,42615,42616,42617,
+42618,42625,42626,42627,42628,16981,42629,42630,42631,42632,42633,42634,42635,
+16982,42636,42637,42638,42639,42640,42641,42642,42643,42644,42645,42646,42647,
+42648,42649,42650,42651,42652,42653,42654,16983,42655,42656,42817,42818,42819,
+42820,42821,16984,42822,42823,42824,16985,42825,42826,42827,16986,42828,42829,
+42830,42831,42832,42833,42834,16987,16988,42835,42836,42837,42838,42839,42840,
+42841,42842,42849,42850,42851,42852,42853,42854,42855,42856,42857,42858,42859,
+42860,42861,42862,42863,42864,42865,42866,42867,42868,42869,42870,42871,16989,
+42872,42873,42874,42881,42882,42883,16990,16991,42884,42885,16992,42886,42887,
+42888,16993,42889,42890,42891,42892,42893,42894,42895,16994,16995,42896,42897,
+42898,16996,42899,42900,42901,42902,42903,42904,16997,42905,42906,42907,42908,
+42909,42910,42911,42912,43073,43074,43075,43076,43077,43078,43079,43080,43081,
+43082,43083,16998,16999,43084,43085,43086,43087,43088,43089,43090,43091,43092,
+43093,43094,43095,43096,43097,43098,43105,43106,43107,43108,43109,43110,43111,
+43112,43113,43114,43115,43116,43117,43118,43119,43120,43121,43122,43123,17000,
+43124,43125,43126,43127,43128,43129,43130,43137,43138,43139,43140,43141,43142,
+43143,43144,43145,43146,43147,43148,43149,43150,43151,43152,43153,43154,43155,
+43156,17001,43157,43158,43159,43160,43161,43162,43163,43164,43165,43166,43167,
+43168,43329,43330,43331,43332,43333,43334,43335,43336,43337,43338,43339,43340,
+43341,43342,43343,17002,43344,43345,43346,43347,43348,43349,43350,43351,43352,
+43353,43354,43361,43362,43363,43364,17003,43365,43366,17004,43367,17005,43368,
+43369,43370,43371,43372,43373,43374,43375,43376,43377,43378,43379,43380,43381,
+43382,43383,43384,43385,43386,43393,43394,43395,43396,43397,43398,43399,43400,
+43401,43402,43403,43404,43405,43406,43407,17006,17007,43408,43409,17008,43410,
+43411,43412,17009,43413,43414,43415,43416,43417,43418,43419,17010,17011,43420,
+43421,43422,17012,17013,43423,43424,43585,43586,17014,17015,17016,43587,43588,
+17017,43589,17018,43590,17019,43591,43592,43593,43594,43595,43596,43597,17020,
+17021,43598,17022,17185,17186,17187,43599,43600,43601,43602,43603,17188,17189,
+43604,43605,17190,43606,43607,43608,17191,43609,43610,43617,43618,43619,43620,
+43621,17192,17193,43622,17194,17195,17196,43623,43624,43625,43626,43627,43628,
+17197,43629,43630,43631,17198,43632,17199,43633,17200,43634,43635,43636,43637,
+43638,43639,43640,17201,43641,43642,43649,43650,17202,43651,43652,43653,43654,
+43655,43656,43657,43658,43659,43660,43661,43662,43663,43664,43665,43666,43667,
+43668,43669,43670,43671,43672,43673,43674,43675,43676,43677,43678,43679,43680,
+43841,43842,43843,43844,17203,17204,43845,43846,17205,43847,43848,43849,17206,
+43850,43851,43852,43853,43854,43855,43856,17207,17208,43857,17209,17210,17211,
+43858,43859,43860,43861,43862,43863,17212,17213,43864,43865,17214,43866,43873,
+43874,17215,43875,43876,43877,43878,43879,43880,43881,17216,17217,43882,17218,
+43883,17219,43884,43885,43886,43887,43888,43889,17220,43890,43891,43892,17221,
+43893,43894,43895,43896,43897,43898,43905,43906,43907,43908,43909,43910,43911,
+43912,43913,17222,43914,43915,43916,43917,43918,43919,43920,17223,43921,43922,
+43923,17224,43924,43925,43926,43927,43928,43929,43930,43931,43932,43933,43934,
+43935,43936,44097,44098,44099,17225,44100,44101,44102,44103,44104,44105,17226,
+17227,44106,44107,17228,44108,44109,44110,17229,44111,44112,44113,44114,44115,
+44116,44117,17230,17231,44118,17232,44119,17233,44120,44121,44122,44129,44130,
+44131,17234,44132,44133,44134,17235,44135,44136,44137,17236,44138,44139,44140,
+44141,44142,44143,44144,44145,44146,44147,44148,44149,17237,44150,44151,44152,
+44153,44154,44161,44162,44163,44164,44165,44166,44167,44168,44169,44170,44171,
+44172,44173,44174,44175,44176,44177,44178,44179,44180,44181,44182,44183,44184,
+44185,44186,44187,44188,44189,17238,44190,44191,44192,17239,44353,44354,44355,
+17240,44356,44357,44358,44359,44360,44361,44362,17241,17242,44363,17243,44364,
+17244,44365,44366,44367,44368,44369,44370,17245,44371,44372,44373,44374,44375,
+44376,44377,44378,44385,44386,44387,44388,44389,44390,44391,17246,44392,44393,
+44394,44395,44396,44397,44398,44399,44400,44401,44402,17247,17248,44403,44404,
+17249,44405,44406,44407,17250,44408,44409,44410,44417,44418,44419,44420,17251,
+17252,44421,17253,44422,17254,44423,44424,44425,44426,44427,44428,17255,44429,
+44430,44431,44432,44433,44434,44435,44436,44437,44438,44439,44440,44441,44442,
+44443,44444,44445,44446,44447,17256,44448,44609,44610,44611,44612,44613,44614,
+17257,44615,44616,44617,17258,44618,44619,44620,44621,44622,44623,44624,44625,
+44626,44627,44628,44629,44630,44631,44632,44633,44634,44641,44642,44643,44644,
+44645,44646,17259,44647,44648,44649,17260,44650,44651,44652,17261,44653,44654,
+44655,44656,44657,44658,44659,17262,17263,44660,17264,44661,17265,44662,44663,
+44664,44665,44666,44673,17266,44674,44675,44676,17267,44677,44678,44679,17268,
+44680,44681,44682,44683,44684,44685,44686,17269,44687,44688,44689,44690,17270,
+44691,44692,44693,44694,44695,44696,17271,17272,44697,44698,17273,44699,44700,
+44701,17274,44702,44703,44704,44865,44866,44867,44868,17275,17276,44869,17277,
+44870,17278,44871,44872,44873,44874,44875,44876,44877,44878,44879,44880,44881,
+44882,44883,44884,44885,44886,44887,44888,44889,44890,44897,44898,44899,44900,
+44901,44902,44903,44904,44905,44906,44907,44908,44909,44910,17441,17442,44911,
+44912,17443,44913,44914,17444,17445,17446,44915,44916,44917,44918,44919,44920,
+17447,17448,44921,17449,44922,17450,44929,44930,44931,44932,44933,44934,17451,
+17452,44935,44936,17453,44937,44938,44939,17454,44940,44941,44942,44943,44944,
+44945,44946,17455,17456,44947,17457,44948,17458,44949,44950,44951,44952,44953,
+44954,17459,17460,44955,44956,17461,44957,44958,44959,17462,44960,45121,45122,
+45123,45124,45125,45126,17463,17464,45127,17465,17466,17467,45128,45129,45130,
+45131,45132,45133,17468,17469,45134,45135,45136,45137,45138,45139,45140,45141,
+45142,45143,45144,45145,45146,45153,45154,45155,45156,45157,45158,17470,45159,
+45160,45161,45162,45163,45164,45165,45166,45167,45168,45169,45170,45171,45172,
+45173,45174,45175,45176,45177,45178,45185,45186,45187,45188,45189,45190,45191,
+45192,45193,45194,45195,45196,45197,45198,17471,17472,45199,45200,17473,45201,
+45202,17474,17475,45203,45204,45205,45206,45207,45208,45209,17476,17477,45210,
+17478,17479,17480,45211,45212,45213,45214,45215,45216,17481,17482,45377,45378,
+17483,45379,45380,45381,17484,45382,45383,45384,45385,45386,45387,45388,17485,
+17486,45389,17487,45390,17488,45391,45392,45393,45394,45395,45396,17489,45397,
+45398,45399,17490,45400,45401,45402,17491,45409,45410,45411,45412,45413,45414,
+45415,17492,17493,45416,17494,17495,17496,45417,45418,45419,45420,45421,45422,
+17497,45423,45424,45425,45426,45427,45428,45429,45430,45431,45432,45433,45434,
+45441,45442,45443,45444,45445,45446,45447,45448,45449,45450,45451,45452,45453,
+45454,45455,17498,17499,45456,45457,17500,45458,45459,45460,17501,45461,45462,
+45463,45464,45465,45466,45467,17502,17503,45468,17504,45469,17505,45470,45471,
+45472,45633,45634,45635,17506,17507,45636,45637,17508,45638,45639,45640,17509,
+45641,45642,45643,45644,45645,45646,45647,17510,45648,45649,45650,45651,17511,
+45652,45653,45654,45655,45656,45657,17512,45658,45665,45666,45667,45668,45669,
+45670,45671,45672,45673,45674,45675,45676,45677,45678,45679,45680,45681,45682,
+45683,17513,45684,45685,45686,45687,45688,45689,17514,45690,45697,45698,45699,
+45700,45701,45702,17515,45703,45704,45705,45706,45707,45708,45709,45710,45711,
+45712,45713,45714,45715,45716,45717,45718,45719,45720,45721,17516,45722,45723,
+45724,45725,45726,45727,45728,45889,45890,45891,45892,45893,45894,45895,45896,
+45897,45898,45899,45900,45901,45902,45903,45904,45905,45906,45907,45908,17517,
+17518,45909,45910,17519,45911,45912,45913,17520,45914,45921,45922,45923,45924,
+45925,45926,17521,17522,45927,17523,45928,17524,45929,45930,45931,45932,45933,
+45934,17525,45935,45936,45937,17526,45938,45939,45940,17527,45941,45942,45943,
+45944,45945,45946,45953,45954,45955,45956,45957,45958,17528,45959,45960,45961,
+45962,45963,45964,17529,45965,45966,45967,45968,45969,45970,45971,45972,45973,
+45974,45975,45976,45977,45978,45979,45980,45981,45982,45983,45984,17530,46145,
+46146,46147,46148,46149,46150,17531,17532,46151,46152,17533,46153,46154,46155,
+17534,46156,46157,46158,46159,46160,46161,46162,17697,17698,46163,17699,46164,
+17700,46165,46166,46167,46168,46169,46170,17701,46177,46178,46179,17702,46180,
+46181,46182,17703,46183,46184,46185,46186,46187,46188,46189,17704,46190,46191,
+46192,46193,46194,46195,46196,46197,46198,46199,46200,17705,17706,46201,46202,
+17707,46209,46210,46211,17708,46212,46213,46214,46215,46216,46217,46218,17709,
+17710,46219,46220,46221,17711,46222,46223,46224,46225,46226,46227,46228,46229,
+46230,46231,46232,46233,46234,46235,46236,46237,46238,46239,46240,46401,46402,
+46403,46404,46405,46406,46407,46408,46409,46410,46411,46412,46413,46414,46415,
+17712,17713,46416,46417,17714,46418,46419,46420,17715,46421,46422,46423,46424,
+46425,46426,46433,17716,17717,46434,17718,46435,17719,46436,46437,46438,46439,
+46440,46441,17720,17721,46442,46443,17722,46444,46445,46446,17723,17724,46447,
+46448,46449,46450,46451,46452,17725,17726,46453,17727,17728,17729,46454,46455,
+46456,46457,46458,46465,17730,17731,46466,46467,17732,46468,46469,46470,17733,
+46471,46472,46473,46474,46475,46476,46477,17734,17735,46478,17736,17737,17738,
+46479,46480,46481,46482,46483,46484,17739,46485,46486,46487,46488,46489,46490,
+46491,46492,46493,46494,46495,46496,46657,46658,46659,46660,46661,46662,46663,
+46664,17740,46665,46666,46667,46668,46669,46670,46671,46672,46673,46674,46675,
+46676,46677,46678,46679,46680,46681,46682,46689,46690,46691,46692,46693,46694,
+46695,46696,46697,46698,46699,46700,46701,46702,46703,46704,17741,17742,46705,
+46706,17743,46707,46708,46709,17744,46710,17745,46711,46712,46713,46714,46721,
+17746,17747,46722,17748,17749,17750,46723,46724,46725,46726,46727,46728,17751,
+17752,46729,46730,17753,46731,46732,46733,17754,46734,46735,46736,46737,46738,
+46739,46740,17755,17756,46741,17757,46742,17758,46743,46744,46745,46746,46747,
+46748,17759,46749,46750,46751,17760,46752,46913,46914,46915,46916,46917,46918,
+46919,46920,46921,46922,46923,46924,46925,46926,17761,46927,46928,46929,46930,
+46931,46932,46933,17762,46934,46935,46936,17763,46937,46938,46945,46946,46947,
+46948,46949,46950,46951,46952,46953,46954,46955,46956,46957,46958,46959,46960,
+46961,46962,46963,46964,46965,17764,17765,46966,46967,17766,46968,46969,46970,
+17767,46977,46978,46979,46980,46981,46982,46983,17768,17769,46984,17770,46985,
+17771,46986,46987,46988,46989,17772,46990,17773,46991,46992,46993,17774,46994,
+46995,46996,46997,46998,46999,47000,47001,47002,47003,47004,47005,47006,47007,
+47008,47169,47170,47171,47172,47173,47174,47175,47176,17775,47177,47178,47179,
+47180,47181,47182,47183,47184,47185,47186,47187,47188,47189,47190,47191,47192,
+47193,47194,47201,47202,47203,47204,47205,47206,47207,47208,47209,17776,47210,
+47211,47212,17777,47213,47214,47215,47216,47217,47218,47219,47220,47221,47222,
+47223,47224,47225,47226,17778,47233,17779,47234,47235,47236,47237,47238,47239,
+17780,47240,47241,47242,47243,47244,47245,47246,47247,47248,47249,47250,47251,
+47252,47253,47254,47255,47256,47257,47258,47259,47260,47261,47262,47263,47264,
+47425,47426,17781,17782,47427,47428,17783,47429,47430,47431,17784,47432,47433,
+47434,47435,47436,47437,47438,17785,17786,47439,17787,47440,17788,47441,47442,
+47443,47444,47445,47446,17789,47447,47448,47449,47450,47457,47458,47459,47460,
+47461,47462,47463,47464,47465,47466,47467,47468,47469,47470,47471,17790,47472,
+47473,47474,47475,47476,47477,47478,17953,47479,47480,47481,47482,47489,47490,
+47491,47492,47493,47494,47495,47496,47497,47498,47499,47500,47501,47502,47503,
+47504,47505,47506,47507,47508,47509,47510,47511,17954,17955,47512,47513,17956,
+47514,47515,47516,17957,47517,47518,47519,47520,47681,47682,47683,17958,17959,
+47684,47685,47686,17960,47687,47688,47689,47690,47691,47692,17961,47693,47694,
+47695,17962,47696,47697,47698,17963,47699,47700,47701,47702,47703,47704,47705,
+17964,47706,47713,47714,47715,17965,47716,47717,47718,47719,47720,47721,17966,
+17967,47722,47723,17968,47724,47725,17969,17970,47726,17971,47727,47728,47729,
+47730,47731,17972,17973,47732,17974,47733,47734,47735,47736,47737,47738,47745,
+47746,17975,47747,47748,47749,17976,47750,47751,47752,17977,47753,47754,47755,
+47756,47757,47758,47759,17978,17979,47760,47761,47762,47763,47764,47765,47766,
+47767,47768,47769,17980,17981,47770,47771,17982,47772,47773,47774,17983,47775,
+47776,47937,47938,47939,47940,47941,17984,17985,47942,17986,47943,17987,47944,
+47945,47946,47947,47948,47949,17988,17989,17990,47950,17991,47951,47952,47953,
+17992,47954,17993,47955,47956,47957,47958,47959,17994,17995,47960,17996,17997,
+17998,47961,47962,47969,17999,47970,47971,18000,18001,47972,47973,18002,47974,
+47975,47976,18003,47977,47978,47979,47980,47981,47982,47983,18004,18005,47984,
+18006,18007,18008,47985,47986,47987,47988,47989,47990,18009,18010,47991,47992,
+47993,47994,48001,48002,48003,48004,48005,48006,48007,48008,48009,48010,48011,
+48012,48013,48014,48015,48016,48017,48018,48019,48020,48021,48022,48023,48024,
+48025,48026,48027,48028,48029,48030,48031,48032,48193,48194,48195,48196,48197,
+48198,48199,48200,48201,48202,48203,48204,48205,48206,48207,48208,48209,48210,
+18011,18012,48211,48212,18013,48213,48214,48215,18014,48216,48217,48218,48225,
+48226,48227,48228,18015,18016,48229,18017,18018,18019,48230,48231,48232,48233,
+48234,48235,18020,18021,48236,48237,18022,48238,48239,48240,18023,48241,48242,
+48243,48244,48245,48246,48247,18024,18025,48248,18026,48249,18027,48250,48257,
+48258,48259,48260,48261,18028,48262,48263,48264,18029,48265,48266,48267,18030,
+48268,48269,48270,48271,48272,48273,48274,18031,18032,48275,48276,18033,18034,
+48277,48278,48279,48280,48281,48282,18035,48283,48284,48285,48286,48287,48288,
+48449,18036,48450,48451,48452,48453,48454,48455,48456,48457,18037,48458,18038,
+48459,48460,48461,48462,48463,48464,48465,48466,18039,18040,48467,48468,18041,
+48469,48470,48471,18042,48472,48473,48474,48481,48482,48483,48484,18043,18044,
+48485,18045,48486,18046,48487,48488,48489,48490,48491,48492,18209,48493,48494,
+48495,48496,48497,48498,48499,48500,48501,48502,48503,48504,48505,48506,48513,
+48514,48515,48516,48517,48518,18210,48519,48520,48521,48522,48523,48524,48525,
+48526,48527,48528,48529,48530,48531,48532,48533,48534,48535,48536,48537,48538,
+48539,48540,48541,48542,48543,48544,48705,48706,48707,48708,48709,48710,48711,
+48712,18211,48713,48714,48715,18212,48716,48717,48718,48719,48720,48721,48722,
+48723,48724,48725,48726,48727,48728,48729,48730,48737,48738,48739,48740,48741,
+48742,48743,48744,18213,48745,48746,48747,18214,48748,48749,48750,18215,48751,
+48752,48753,48754,48755,48756,48757,48758,18216,48759,18217,48760,48761,48762,
+48769,48770,48771,48772,48773,18218,18219,48774,48775,18220,48776,48777,18221,
+18222,48778,18223,48779,48780,48781,48782,48783,18224,18225,48784,18226,48785,
+18227,48786,48787,48788,48789,48790,48791,18228,48792,48793,48794,48795,48796,
+48797,48798,48799,48800,48961,48962,48963,48964,48965,48966,48967,48968,48969,
+48970,48971,18229,48972,48973,48974,48975,48976,48977,48978,48979,48980,48981,
+48982,48983,48984,48985,48986,48993,48994,48995,48996,48997,48998,48999,49000,
+49001,49002,49003,49004,49005,49006,49007,49008,49009,49010,49011,18230,49012,
+49013,49014,18231,49015,49016,49017,18232,49018,49025,49026,49027,49028,49029,
+49030,18233,49031,49032,18234,49033,49034,49035,49036,49037,49038,49039,49040,
+18235,49041,49042,49043,18236,49044,49045,49046,18237,49047,49048,49049,49050,
+49051,49052,49053,18238,49054,49055,18239,49056,18240,49217,49218,49219,49220,
+49221,49222,18241,49223,49224,49225,18242,49226,49227,49228,18243,49229,49230,
+49231,49232,49233,49234,49235,18244,18245,49236,18246,49237,49238,49239,49240,
+49241,49242,49249,49250,49251,49252,49253,49254,49255,49256,49257,49258,49259,
+49260,49261,49262,49263,49264,49265,49266,49267,49268,49269,49270,49271,49272,
+49273,49274,49281,49282,49283,49284,18247,18248,49285,49286,18249,49287,49288,
+49289,18250,49290,49291,49292,49293,49294,49295,49296,18251,18252,49297,18253,
+49298,18254,49299,49300,49301,49302,49303,49304,18255,18256,49305,49306,18257,
+49307,49308,49309,18258,49310,49311,49312,49473,18259,49474,49475,18260,18261,
+49476,18262,49477,18263,49478,49479,49480,49481,49482,49483,18264,18265,49484,
+49485,18266,49486,49487,49488,18267,49489,49490,49491,49492,49493,49494,49495,
+18268,18269,49496,18270,18271,18272,49497,49498,49505,49506,49507,49508,18273,
+49509,49510,49511,49512,49513,49514,49515,49516,49517,49518,49519,49520,49521,
+49522,49523,49524,49525,49526,49527,49528,18274,49529,49530,49537,49538,49539,
+49540,49541,49542,49543,49544,49545,49546,49547,49548,49549,49550,49551,49552,
+49553,49554,49555,49556,49557,49558,49559,49560,49561,49562,49563,49564,49565,
+49566,49567,49568,18275,18276,49729,49730,18277,49731,49732,49733,18278,49734,
+18279,49735,49736,49737,49738,49739,18280,18281,49740,18282,49741,18283,49742,
+49743,49744,49745,49746,49747,18284,18285,49748,49749,18286,49750,49751,49752,
+18287,49753,49754,49761,49762,49763,49764,49765,18288,18289,49766,18290,49767,
+18291,49768,49769,49770,49771,49772,49773,18292,18293,49774,49775,18294,49776,
+49777,49778,18295,49779,49780,49781,49782,49783,49784,49785,18296,18297,49786,
+18298,18299,18300,49793,49794,49795,49796,49797,49798,18301,49799,49800,49801,
+18302,49802,49803,49804,18465,49805,49806,49807,49808,49809,49810,49811,49812,
+18466,49813,49814,49815,49816,49817,49818,49819,49820,49821,49822,18467,18468,
+49823,49824,18469,49985,49986,49987,18470,49988,49989,49990,49991,18471,49992,
+49993,18472,18473,49994,18474,49995,18475,49996,49997,49998,18476,49999,50000,
+18477,18478,50001,50002,18479,50003,50004,50005,18480,50006,50007,50008,50009,
+50010,50017,50018,50019,50020,50021,18481,50022,18482,50023,50024,50025,50026,
+50027,50028,18483,18484,50029,50030,18485,50031,50032,50033,50034,50035,50036,
+50037,50038,50039,50040,50041,50042,50049,50050,18486,50051,18487,50052,50053,
+50054,50055,50056,50057,18488,18489,50058,50059,18490,50060,50061,50062,18491,
+50063,50064,50065,50066,50067,50068,50069,50070,18492,50071,18493,50072,18494,
+50073,50074,50075,50076,50077,50078,18495,50079,50080,50241,18496,50242,50243,
+50244,18497,50245,50246,50247,50248,50249,50250,50251,50252,18498,50253,18499,
+50254,50255,50256,50257,50258,50259,50260,50261,18500,18501,50262,50263,18502,
+50264,50265,50266,18503,50273,50274,50275,50276,18504,50277,50278,18505,50279,
+50280,18506,50281,18507,50282,50283,50284,50285,50286,50287,18508,50288,50289,
+50290,18509,50291,50292,50293,18510,50294,50295,50296,50297,50298,50305,50306,
+18511,50307,50308,50309,50310,18512,50311,50312,50313,50314,50315,50316,18513,
+18514,50317,50318,18515,50319,50320,50321,18516,50322,50323,50324,50325,50326,
+50327,50328,50329,50330,50331,50332,50333,18517,50334,50335,50336,50497,50498,
+50499,18518,18519,50500,50501,18520,50502,50503,50504,18521,50505,50506,50507,
+50508,50509,50510,50511,18522,18523,50512,18524,50513,18525,50514,50515,50516,
+50517,50518,50519,18526,18527,50520,50521,18528,50522,50529,50530,18529,50531,
+50532,50533,50534,50535,50536,50537,18530,50538,50539,18531,50540,18532,50541,
+50542,50543,50544,50545,50546,18533,18534,50547,50548,18535,50549,18536,18537,
+18538,18539,50550,50551,50552,50553,50554,50561,18540,18541,50562,18542,50563,
+18543,50564,50565,50566,18544,50567,50568,18545,50569,50570,50571,18546,50572,
+50573,50574,18547,50575,50576,50577,50578,50579,50580,50581,18548,18549,50582,
+50583,50584,18550,50585,50586,50587,50588,50589,50590,18551,18552,50591,50592,
+18553,50753,50754,50755,18554,50756,50757,50758,50759,50760,50761,50762,18555,
+18556,50763,18557,50764,18558,50765,50766,50767,50768,50769,50770,19280,19286,
+19303,19791,19816,20013,20347,20514,20536,20560,20573,20820,20821,20824,20827,
+20828,20829,20830,20831,20832,20834,20835,20836,20837,20838,20840,20841,20842,
+20843,20845,20847,20848,20850,20854,20858,20860,20861,20862,21026,21027,21031,
+21032,21033,21034,21035,21037,21042,21054,21058,21059,21060,21062,21063,21064,
+21065,21066,21067,21069,21070,21071,21072,21073,21074,21075,21076,21077,21078,
+21079,21081,21082,21086,21087,21089,21090,21092,21093,21094,21095,21096,21097,
+21098,21099,21104,21105,21106,21107,21108,21109,21111,21112,21606,21628,21797,
+21803,21806,22072,22093,22347,22372,23365,23396,23589,23845,23893,23924,24188,
+24190,24371,24417,24424,24689,24877,24941,25461,25633,25641,25902,25905,25906,
+25913,25915,25916,25924,25934,25936,25938,25942,25978,25979,25980,25982,26145,
+26148,26151,26157,26159,26160,26161,26163,26167,26168,26172,26180,26182,26183,
+26186,26194,26198,26201,26204,26207,26209,26212,26213,26214,26216,26218,26219,
+26220,26223,26225,26226,26229,26230,26231,26233,26401,26406,26409,26410,26412,
+26413,26416,26431,26433,26438,26439,26443,26445,26447,26448,26451,26463,26468,
+26470,26487,26727,26728,26736,26737,26743,26745,26747,26750,26919,26924,26956,
+26999,27201,27237,27252,27255,27260,27262,27428,27431,27433,27434,27450,27451,
+27453,27457,27458,27462,27463,27468,27471,27472,27473,27474,27480,27686,27687,
+27690,27695,27696,27697,27698,27701,27704,27706,27712,27713,27717,27718,27721,
+27722,27733,27741,27742,27745,27748,27751,27752,27767,27768,27770,27937,27938,
+27939,28014,28251,29245,29306,29489,29735,29806,30324,30326,30520,30536,30547,
+30811,30832,31265,31266,31334,31785,8993,8994,8995,8996,8997,8998,8999,9000,
+9001,9002,9003,9004,9005,9006,9007,9008,9009,9010,9011,9012,9013,9014,9015,
+9016,9017,9018,9019,9020,9021,9022,9023,9024,9025,9026,9027,9028,9029,9030,
+9031,9032,9033,9034,9035,9036,9037,9038,9039,9040,9041,9042,9043,9044,9045,
+9046,9047,9048,9049,9050,9051,8492,9053,9054,9055,9056,9057,9058,9059,9060,
+9061,9062,9063,9064,9065,9066,9067,9068,9069,9070,9071,9072,9073,9074,9075,
+9076,9077,9078,9079,9080,9081,9082,9083,9084,9085,8742,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,8523,8524,8574,9086,N,8525,9052,
+};
+
+static const struct unim_index cp949_encmap[256] = {
+{__cp949_encmap+0,161,254},{__cp949_encmap+94,17,103},{__cp949_encmap+181,199,
+221},{__cp949_encmap+204,145,201},{__cp949_encmap+261,1,81},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp949_encmap+342,21,172},{
+__cp949_encmap+494,3,212},{__cp949_encmap+704,0,165},{__cp949_encmap+870,18,18
+},{__cp949_encmap+871,96,233},{__cp949_encmap+1009,0,209},{__cp949_encmap+1219
+,5,109},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{__cp949_encmap+1324,0,246},{__cp949_encmap+1571,49,142},{__cp949_encmap+
+1665,0,127},{__cp949_encmap+1793,128,221},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{__cp949_encmap+1887,0,251},{__cp949_encmap+2139,1,250},{
+__cp949_encmap+2389,2,255},{__cp949_encmap+2643,0,253},{__cp949_encmap+2897,0,
+255},{__cp949_encmap+3153,5,248},{__cp949_encmap+3397,3,250},{__cp949_encmap+
+3645,4,254},{__cp949_encmap+3896,6,250},{__cp949_encmap+4141,3,252},{
+__cp949_encmap+4391,0,253},{__cp949_encmap+4645,15,255},{__cp949_encmap+4886,
+1,233},{__cp949_encmap+5119,5,250},{__cp949_encmap+5365,1,253},{__cp949_encmap
++5618,7,254},{__cp949_encmap+5866,2,251},{__cp949_encmap+6116,1,255},{
+__cp949_encmap+6371,15,251},{__cp949_encmap+6608,1,255},{__cp949_encmap+6863,
+0,255},{__cp949_encmap+7119,1,247},{__cp949_encmap+7366,13,254},{
+__cp949_encmap+7608,0,255},{__cp949_encmap+7864,6,255},{__cp949_encmap+8114,0,
+254},{__cp949_encmap+8369,18,250},{__cp949_encmap+8602,0,255},{__cp949_encmap+
+8858,2,251},{__cp949_encmap+9108,4,236},{__cp949_encmap+9341,8,243},{
+__cp949_encmap+9577,11,251},{__cp949_encmap+9818,23,255},{__cp949_encmap+10051
+,1,254},{__cp949_encmap+10305,1,253},{__cp949_encmap+10558,4,255},{
+__cp949_encmap+10810,0,253},{__cp949_encmap+11064,10,254},{__cp949_encmap+
+11309,1,247},{__cp949_encmap+11556,1,252},{__cp949_encmap+11808,0,254},{
+__cp949_encmap+12063,1,243},{__cp949_encmap+12306,2,251},{__cp949_encmap+12556
+,1,251},{__cp949_encmap+12807,0,255},{__cp949_encmap+13063,15,233},{
+__cp949_encmap+13282,7,254},{__cp949_encmap+13530,0,251},{__cp949_encmap+13782
+,9,156},{__cp949_encmap+13930,54,252},{__cp949_encmap+14129,0,253},{
+__cp949_encmap+14383,2,254},{__cp949_encmap+14636,5,254},{__cp949_encmap+14886
+,1,253},{__cp949_encmap+15139,3,252},{__cp949_encmap+15389,17,255},{
+__cp949_encmap+15628,2,254},{__cp949_encmap+15881,0,254},{__cp949_encmap+16136
+,5,253},{__cp949_encmap+16385,7,248},{__cp949_encmap+16627,0,254},{
+__cp949_encmap+16882,0,154},{__cp949_encmap+17037,55,253},{__cp949_encmap+
+17236,4,243},{__cp949_encmap+17476,10,254},{__cp949_encmap+17721,3,253},{
+__cp949_encmap+17972,0,253},{__cp949_encmap+18226,2,245},{__cp949_encmap+18470
+,13,252},{__cp949_encmap+18710,4,246},{__cp949_encmap+18953,4,127},{
+__cp949_encmap+19077,119,226},{__cp949_encmap+19185,28,251},{__cp949_encmap+
+19409,0,255},{__cp949_encmap+19665,0,254},{__cp949_encmap+19920,3,255},{
+__cp949_encmap+20173,1,238},{__cp949_encmap+20411,26,232},{__cp949_encmap+
+20618,13,246},{__cp949_encmap+20852,9,250},{__cp949_encmap+21094,26,244},{
+__cp949_encmap+21313,7,156},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp949_encmap+21463,0,255},{
+__cp949_encmap+21719,0,255},{__cp949_encmap+21975,0,255},{__cp949_encmap+22231
+,0,255},{__cp949_encmap+22487,0,255},{__cp949_encmap+22743,0,255},{
+__cp949_encmap+22999,0,255},{__cp949_encmap+23255,0,255},{__cp949_encmap+23511
+,0,255},{__cp949_encmap+23767,0,255},{__cp949_encmap+24023,0,255},{
+__cp949_encmap+24279,0,255},{__cp949_encmap+24535,0,255},{__cp949_encmap+24791
+,0,255},{__cp949_encmap+25047,0,255},{__cp949_encmap+25303,0,255},{
+__cp949_encmap+25559,0,255},{__cp949_encmap+25815,0,255},{__cp949_encmap+26071
+,0,255},{__cp949_encmap+26327,0,255},{__cp949_encmap+26583,0,255},{
+__cp949_encmap+26839,0,255},{__cp949_encmap+27095,0,255},{__cp949_encmap+27351
+,0,255},{__cp949_encmap+27607,0,255},{__cp949_encmap+27863,0,255},{
+__cp949_encmap+28119,0,255},{__cp949_encmap+28375,0,255},{__cp949_encmap+28631
+,0,255},{__cp949_encmap+28887,0,255},{__cp949_encmap+29143,0,255},{
+__cp949_encmap+29399,0,255},{__cp949_encmap+29655,0,255},{__cp949_encmap+29911
+,0,255},{__cp949_encmap+30167,0,255},{__cp949_encmap+30423,0,255},{
+__cp949_encmap+30679,0,255},{__cp949_encmap+30935,0,255},{__cp949_encmap+31191
+,0,255},{__cp949_encmap+31447,0,255},{__cp949_encmap+31703,0,255},{
+__cp949_encmap+31959,0,255},{__cp949_encmap+32215,0,255},{__cp949_encmap+32471
+,0,163},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp949_encmap+32635,0,255},{
+__cp949_encmap+32891,0,11},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp949_encmap+
+32903,1,230},
+};

Added: vendor/Python/current/Modules/cjkcodecs/mappings_tw.h
===================================================================
--- vendor/Python/current/Modules/cjkcodecs/mappings_tw.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/cjkcodecs/mappings_tw.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2633 @@
+static const ucs2_t __big5_decmap[16702] = {
+12288,65292,12289,12290,65294,8226,65307,65306,65311,65281,65072,8230,8229,
+65104,65380,65106,183,65108,65109,65110,65111,65372,8211,65073,8212,65075,
+9588,65076,65103,65288,65289,65077,65078,65371,65373,65079,65080,12308,12309,
+65081,65082,12304,12305,65083,65084,12298,12299,65085,65086,12296,12297,65087,
+65088,12300,12301,65089,65090,12302,12303,65091,65092,65113,65114,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,65115,65116,65117,
+65118,8216,8217,8220,8221,12317,12318,8245,8242,65283,65286,65290,8251,167,
+12291,9675,9679,9651,9650,9678,9734,9733,9671,9670,9633,9632,9661,9660,12963,
+8453,8254,65507,65343,717,65097,65098,65101,65102,65099,65100,65119,65120,
+65121,65291,65293,215,247,177,8730,65308,65310,65309,8806,8807,8800,8734,8786,
+8801,65122,65123,65124,65125,65126,8764,8745,8746,8869,8736,8735,8895,13266,
+13265,8747,8750,8757,8756,9792,9794,9793,9737,8593,8595,8592,8594,8598,8599,
+8601,8600,8741,8739,65295,65340,65295,65340,65284,165,12306,162,163,65285,
+65312,8451,8457,65129,65130,65131,13269,13212,13213,13214,13262,13217,13198,
+13199,13252,176,20825,20827,20830,20829,20833,20835,21991,29929,31950,9601,
+9602,9603,9604,9605,9606,9607,9608,9615,9614,9613,9612,9611,9610,9609,9532,
+9524,9516,9508,9500,9620,9472,9474,9621,9484,9488,9492,9496,9581,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,9582,9584,9583,9552,
+9566,9578,9569,9698,9699,9701,9700,9585,9586,9587,65296,65297,65298,65299,
+65300,65301,65302,65303,65304,65305,8544,8545,8546,8547,8548,8549,8550,8551,
+8552,8553,12321,12322,12323,12324,12325,12326,12327,12328,12329,21313,21316,
+21317,65313,65314,65315,65316,65317,65318,65319,65320,65321,65322,65323,65324,
+65325,65326,65327,65328,65329,65330,65331,65332,65333,65334,65335,65336,65337,
+65338,65345,65346,65347,65348,65349,65350,65351,65352,65353,65354,65355,65356,
+65357,65358,65359,65360,65361,65362,65363,65364,65365,65366,65367,65368,65369,
+65370,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,931,
+932,933,934,935,936,937,945,946,947,948,949,950,951,952,953,954,955,956,957,
+958,959,960,961,963,964,965,966,967,968,969,12549,12550,12551,12552,12553,
+12554,12555,12556,12557,12558,12559,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,12560,12561,12562,12563,12564,12565,12566,12567,
+12568,12569,12570,12571,12572,12573,12574,12575,12576,12577,12578,12579,12580,
+12581,12582,12583,12584,12585,729,713,714,711,715,19968,20057,19969,19971,
+20035,20061,20102,20108,20154,20799,20837,20843,20960,20992,20993,21147,21269,
+21313,21340,21448,19977,19979,19976,19978,20011,20024,20961,20037,20040,20063,
+20062,20110,20129,20800,20995,21242,21315,21449,21475,22303,22763,22805,22823,
+22899,23376,23377,23379,23544,23567,23586,23608,23665,24029,24037,24049,24050,
+24051,24062,24178,24318,24331,24339,25165,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,19985,19984,19981,20013,20016,20025,20043,
+23609,20104,20113,20117,20114,20116,20130,20161,20160,20163,20166,20167,20173,
+20170,20171,20164,20803,20801,20839,20845,20846,20844,20887,20982,20998,20999,
+21000,21243,21246,21247,21270,21305,21320,21319,21317,21342,21380,21451,21450,
+21453,22764,22825,22827,22826,22829,23380,23569,23588,23610,23663,24052,24187,
+24319,24340,24341,24515,25096,25142,25163,25166,25903,25991,26007,26020,26041,
+26085,26352,26376,26408,27424,27490,27513,27595,27604,27611,27663,27700,28779,
+29226,29238,29243,29255,29273,29275,29356,29579,19993,19990,19989,19988,19992,
+20027,20045,20047,20046,20197,20184,20180,20181,20182,20183,20195,20196,20185,
+20190,20805,20804,20873,20874,20908,20985,20986,20984,21002,21152,21151,21253,
+21254,21271,21277,20191,21322,21321,21345,21344,21359,21358,21435,21487,21476,
+21491,21484,21486,21481,21480,21500,21496,21493,21483,21478,21482,21490,21489,
+21488,21477,21485,21499,22235,22234,22806,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,22830,22833,22900,22902,23381,23427,23612,
+24040,24039,24038,24066,24067,24179,24188,24321,24344,24343,24517,25098,25171,
+25172,25170,25169,26021,26086,26414,26412,26410,26411,26413,27491,27597,27665,
+27664,27704,27713,27712,27710,29359,29572,29577,29916,29926,29976,29983,29992,
+29993,30000,30001,30002,30003,30091,30333,30382,30399,30446,30683,30690,30707,
+31034,31166,31348,31435,19998,19999,20050,20051,20073,20121,20132,20134,20133,
+20223,20233,20249,20234,20245,20237,20240,20241,20239,20210,20214,20219,20208,
+20211,20221,20225,20235,20809,20807,20806,20808,20840,20849,20877,20912,21015,
+21009,21010,21006,21014,21155,21256,21281,21280,21360,21361,21513,21519,21516,
+21514,21520,21505,21515,21508,21521,21517,21512,21507,21518,21510,21522,22240,
+22238,22237,22323,22320,22312,22317,22316,22319,22313,22809,22810,22839,22840,
+22916,22904,22915,22909,22905,22914,22913,23383,23384,23431,23432,23429,23433,
+23546,23574,23673,24030,24070,24182,24180,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,24335,24347,24537,24534,25102,25100,25101,
+25104,25187,25179,25176,25910,26089,26088,26092,26093,26354,26355,26377,26429,
+26420,26417,26421,27425,27492,27515,27670,27741,27735,27737,27743,27744,27728,
+27733,27745,27739,27725,27726,28784,29279,29277,30334,31481,31859,31992,32566,
+32650,32701,32769,32771,32780,32786,32819,32895,32905,32907,32908,33251,33258,
+33267,33276,33292,33307,33311,33390,33394,33406,34411,34880,34892,34915,35199,
+38433,20018,20136,20301,20303,20295,20311,20318,20276,20315,20309,20272,20304,
+20305,20285,20282,20280,20291,20308,20284,20294,20323,20316,20320,20271,20302,
+20278,20313,20317,20296,20314,20812,20811,20813,20853,20918,20919,21029,21028,
+21033,21034,21032,21163,21161,21162,21164,21283,21363,21365,21533,21549,21534,
+21566,21542,21582,21543,21574,21571,21555,21576,21570,21531,21545,21578,21561,
+21563,21560,21550,21557,21558,21536,21564,21568,21553,21547,21535,21548,22250,
+22256,22244,22251,22346,22353,22336,22349,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,22343,22350,22334,22352,22351,22331,22767,
+22846,22941,22930,22952,22942,22947,22937,22934,22925,22948,22931,22922,22949,
+23389,23388,23386,23387,23436,23435,23439,23596,23616,23617,23615,23614,23696,
+23697,23700,23692,24043,24076,24207,24199,24202,24311,24324,24351,24420,24418,
+24439,24441,24536,24524,24535,24525,24561,24555,24568,24554,25106,25105,25220,
+25239,25238,25216,25206,25225,25197,25226,25212,25214,25209,25203,25234,25199,
+25240,25198,25237,25235,25233,25222,25913,25915,25912,26097,26356,26463,26446,
+26447,26448,26449,26460,26454,26462,26441,26438,26464,26451,26455,27493,27599,
+27714,27742,27801,27777,27784,27785,27781,27803,27754,27770,27792,27760,27788,
+27752,27798,27794,27773,27779,27762,27774,27764,27782,27766,27789,27796,27800,
+27778,28790,28796,28797,28792,29282,29281,29280,29380,29378,29590,29996,29995,
+30007,30008,30338,30447,30691,31169,31168,31167,31350,31995,32597,32918,32915,
+32925,32920,32923,32922,32946,33391,33426,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,33419,33421,35211,35282,35328,35895,35910,
+35925,35997,36196,36208,36275,36523,36554,36763,36784,36802,36806,36805,36804,
+24033,37009,37026,37034,37030,37027,37193,37318,37324,38450,38446,38449,38442,
+38444,20006,20054,20083,20107,20123,20126,20139,20140,20335,20381,20365,20339,
+20351,20332,20379,20363,20358,20355,20336,20341,20360,20329,20347,20374,20350,
+20367,20369,20346,20820,20818,20821,20841,20855,20854,20856,20925,20989,21051,
+21048,21047,21050,21040,21038,21046,21057,21182,21179,21330,21332,21331,21329,
+21350,21367,21368,21369,21462,21460,21463,21619,21621,21654,21624,21653,21632,
+21627,21623,21636,21650,21638,21628,21648,21617,21622,21644,21658,21602,21608,
+21643,21629,21646,22266,22403,22391,22378,22377,22369,22374,22372,22396,22812,
+22857,22855,22856,22852,22868,22974,22971,22996,22969,22958,22993,22982,22992,
+22989,22987,22995,22986,22959,22963,22994,22981,23391,23396,23395,23447,23450,
+23448,23452,23449,23451,23578,23624,23621,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,23622,23735,23713,23736,23721,23723,23729,
+23731,24088,24090,24086,24085,24091,24081,24184,24218,24215,24220,24213,24214,
+24310,24358,24359,24361,24448,24449,24447,24444,24541,24544,24573,24565,24575,
+24591,24596,24623,24629,24598,24618,24597,24609,24615,24617,24619,24603,25110,
+25109,25151,25150,25152,25215,25289,25292,25284,25279,25282,25273,25298,25307,
+25259,25299,25300,25291,25288,25256,25277,25276,25296,25305,25287,25293,25269,
+25306,25265,25304,25302,25303,25286,25260,25294,25918,26023,26044,26106,26132,
+26131,26124,26118,26114,26126,26112,26127,26133,26122,26119,26381,26379,26477,
+26507,26517,26481,26524,26483,26487,26503,26525,26519,26479,26480,26495,26505,
+26494,26512,26485,26522,26515,26492,26474,26482,27427,27494,27495,27519,27667,
+27675,27875,27880,27891,27825,27852,27877,27827,27837,27838,27836,27874,27819,
+27861,27859,27832,27844,27833,27841,27822,27863,27845,27889,27839,27835,27873,
+27867,27850,27820,27887,27868,27862,27872,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,28821,28814,28818,28810,28825,29228,29229,
+29240,29256,29287,29289,29376,29390,29401,29399,29392,29609,29608,29599,29611,
+29605,30013,30109,30105,30106,30340,30402,30450,30452,30693,30717,31038,31040,
+31041,31177,31176,31354,31353,31482,31998,32596,32652,32651,32773,32954,32933,
+32930,32945,32929,32939,32937,32948,32938,32943,33253,33278,33293,33459,33437,
+33433,33453,33469,33439,33465,33457,33452,33445,33455,33464,33443,33456,33470,
+33463,34382,34417,21021,34920,36555,36814,36820,36817,37045,37048,37041,37046,
+37319,37329,38263,38272,38428,38464,38463,38459,38468,38466,38585,38632,38738,
+38750,20127,20141,20142,20449,20405,20399,20415,20448,20433,20431,20445,20419,
+20406,20440,20447,20426,20439,20398,20432,20420,20418,20442,20430,20446,20407,
+20823,20882,20881,20896,21070,21059,21066,21069,21068,21067,21063,21191,21193,
+21187,21185,21261,21335,21371,21402,21467,21676,21696,21672,21710,21705,21688,
+21670,21683,21703,21698,21693,21674,21697,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,21700,21704,21679,21675,21681,21691,21673,
+21671,21695,22271,22402,22411,22432,22435,22434,22478,22446,22419,22869,22865,
+22863,22862,22864,23004,23000,23039,23011,23016,23043,23013,23018,23002,23014,
+23041,23035,23401,23459,23462,23460,23458,23461,23553,23630,23631,23629,23627,
+23769,23762,24055,24093,24101,24095,24189,24224,24230,24314,24328,24365,24421,
+24456,24453,24458,24459,24455,24460,24457,24594,24605,24608,24613,24590,24616,
+24653,24688,24680,24674,24646,24643,24684,24683,24682,24676,25153,25308,25366,
+25353,25340,25325,25345,25326,25341,25351,25329,25335,25327,25324,25342,25332,
+25361,25346,25919,25925,26027,26045,26082,26149,26157,26144,26151,26159,26143,
+26152,26161,26148,26359,26623,26579,26609,26580,26576,26604,26550,26543,26613,
+26601,26607,26564,26577,26548,26586,26597,26552,26575,26590,26611,26544,26585,
+26594,26589,26578,27498,27523,27526,27573,27602,27607,27679,27849,27915,27954,
+27946,27969,27941,27916,27953,27934,27927,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,27963,27965,27966,27958,27931,27893,27961,
+27943,27960,27945,27950,27957,27918,27947,28843,28858,28851,28844,28847,28845,
+28856,28846,28836,29232,29298,29295,29300,29417,29408,29409,29623,29642,29627,
+29618,29645,29632,29619,29978,29997,30031,30028,30030,30027,30123,30116,30117,
+30114,30115,30328,30342,30343,30344,30408,30406,30403,30405,30465,30457,30456,
+30473,30475,30462,30460,30471,30684,30722,30740,30732,30733,31046,31049,31048,
+31047,31161,31162,31185,31186,31179,31359,31361,31487,31485,31869,32002,32005,
+32000,32009,32007,32004,32006,32568,32654,32703,32772,32784,32781,32785,32822,
+32982,32997,32986,32963,32964,32972,32993,32987,32974,32990,32996,32989,33268,
+33314,33511,33539,33541,33507,33499,33510,33540,33509,33538,33545,33490,33495,
+33521,33537,33500,33492,33489,33502,33491,33503,33519,33542,34384,34425,34427,
+34426,34893,34923,35201,35284,35336,35330,35331,35998,36000,36212,36211,36276,
+36557,36556,36848,36838,36834,36842,36837,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,36845,36843,36836,36840,37066,37070,37057,
+37059,37195,37194,37325,38274,38480,38475,38476,38477,38754,38761,38859,38893,
+38899,38913,39080,39131,39135,39318,39321,20056,20147,20492,20493,20515,20463,
+20518,20517,20472,20521,20502,20486,20540,20511,20506,20498,20497,20474,20480,
+20500,20520,20465,20513,20491,20505,20504,20467,20462,20525,20522,20478,20523,
+20489,20860,20900,20901,20898,20941,20940,20934,20939,21078,21084,21076,21083,
+21085,21290,21375,21407,21405,21471,21736,21776,21761,21815,21756,21733,21746,
+21766,21754,21780,21737,21741,21729,21769,21742,21738,21734,21799,21767,21757,
+21775,22275,22276,22466,22484,22475,22467,22537,22799,22871,22872,22874,23057,
+23064,23068,23071,23067,23059,23020,23072,23075,23081,23077,23052,23049,23403,
+23640,23472,23475,23478,23476,23470,23477,23481,23480,23556,23633,23637,23632,
+23789,23805,23803,23786,23784,23792,23798,23809,23796,24046,24109,24107,24235,
+24237,24231,24369,24466,24465,24464,24665,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,24675,24677,24656,24661,24685,24681,24687,
+24708,24735,24730,24717,24724,24716,24709,24726,25159,25331,25352,25343,25422,
+25406,25391,25429,25410,25414,25423,25417,25402,25424,25405,25386,25387,25384,
+25421,25420,25928,25929,26009,26049,26053,26178,26185,26191,26179,26194,26188,
+26181,26177,26360,26388,26389,26391,26657,26680,26696,26694,26707,26681,26690,
+26708,26665,26803,26647,26700,26705,26685,26612,26704,26688,26684,26691,26666,
+26693,26643,26648,26689,27530,27529,27575,27683,27687,27688,27686,27684,27888,
+28010,28053,28040,28039,28006,28024,28023,27993,28051,28012,28041,28014,27994,
+28020,28009,28044,28042,28025,28037,28005,28052,28874,28888,28900,28889,28872,
+28879,29241,29305,29436,29433,29437,29432,29431,29574,29677,29705,29678,29664,
+29674,29662,30036,30045,30044,30042,30041,30142,30149,30151,30130,30131,30141,
+30140,30137,30146,30136,30347,30384,30410,30413,30414,30505,30495,30496,30504,
+30697,30768,30759,30776,30749,30772,30775,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,30757,30765,30752,30751,30770,31061,31056,
+31072,31071,31062,31070,31069,31063,31066,31204,31203,31207,31199,31206,31209,
+31192,31364,31368,31449,31494,31505,31881,32033,32023,32011,32010,32032,32034,
+32020,32016,32021,32026,32028,32013,32025,32027,32570,32607,32660,32709,32705,
+32774,32792,32789,32793,32791,32829,32831,33009,33026,33008,33029,33005,33012,
+33030,33016,33011,33032,33021,33034,33020,33007,33261,33260,33280,33296,33322,
+33323,33320,33324,33467,33579,33618,33620,33610,33592,33616,33609,33589,33588,
+33615,33586,33593,33590,33559,33600,33585,33576,33603,34388,34442,34474,34451,
+34468,34473,34444,34467,34460,34928,34935,34945,34946,34941,34937,35352,35344,
+35342,35340,35349,35338,35351,35347,35350,35343,35345,35912,35962,35961,36001,
+36002,36215,36524,36562,36564,36559,36785,36865,36870,36855,36864,36858,36852,
+36867,36861,36869,36856,37013,37089,37085,37090,37202,37197,37196,37336,37341,
+37335,37340,37337,38275,38498,38499,38497,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,38491,38493,38500,38488,38494,38587,39138,
+39340,39592,39640,39717,39730,39740,20094,20602,20605,20572,20551,20547,20556,
+20570,20553,20581,20598,20558,20565,20597,20596,20599,20559,20495,20591,20589,
+20828,20885,20976,21098,21103,21202,21209,21208,21205,21264,21263,21273,21311,
+21312,21310,21443,26364,21830,21866,21862,21828,21854,21857,21827,21834,21809,
+21846,21839,21845,21807,21860,21816,21806,21852,21804,21859,21811,21825,21847,
+22280,22283,22281,22495,22533,22538,22534,22496,22500,22522,22530,22581,22519,
+22521,22816,22882,23094,23105,23113,23142,23146,23104,23100,23138,23130,23110,
+23114,23408,23495,23493,23492,23490,23487,23494,23561,23560,23559,23648,23644,
+23645,23815,23814,23822,23835,23830,23842,23825,23849,23828,23833,23844,23847,
+23831,24034,24120,24118,24115,24119,24247,24248,24246,24245,24254,24373,24375,
+24407,24428,24425,24427,24471,24473,24478,24472,24481,24480,24476,24703,24739,
+24713,24736,24744,24779,24756,24806,24765,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,24773,24763,24757,24796,24764,24792,24789,
+24774,24799,24760,24794,24775,25114,25115,25160,25504,25511,25458,25494,25506,
+25509,25463,25447,25496,25514,25457,25513,25481,25475,25499,25451,25512,25476,
+25480,25497,25505,25516,25490,25487,25472,25467,25449,25448,25466,25949,25942,
+25937,25945,25943,21855,25935,25944,25941,25940,26012,26011,26028,26063,26059,
+26060,26062,26205,26202,26212,26216,26214,26206,26361,21207,26395,26753,26799,
+26786,26771,26805,26751,26742,26801,26791,26775,26800,26755,26820,26797,26758,
+26757,26772,26781,26792,26783,26785,26754,27442,27578,27627,27628,27691,28046,
+28092,28147,28121,28082,28129,28108,28132,28155,28154,28165,28103,28107,28079,
+28113,28078,28126,28153,28088,28151,28149,28101,28114,28186,28085,28122,28139,
+28120,28138,28145,28142,28136,28102,28100,28074,28140,28095,28134,28921,28937,
+28938,28925,28911,29245,29309,29313,29468,29467,29462,29459,29465,29575,29701,
+29706,29699,29702,29694,29709,29920,29942,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,29943,29980,29986,30053,30054,30050,30064,
+30095,30164,30165,30133,30154,30157,30350,30420,30418,30427,30519,30526,30524,
+30518,30520,30522,30827,30787,30798,31077,31080,31085,31227,31378,31381,31520,
+31528,31515,31532,31526,31513,31518,31534,31890,31895,31893,32070,32067,32113,
+32046,32057,32060,32064,32048,32051,32068,32047,32066,32050,32049,32573,32670,
+32666,32716,32718,32722,32796,32842,32838,33071,33046,33059,33067,33065,33072,
+33060,33282,33333,33335,33334,33337,33678,33694,33688,33656,33698,33686,33725,
+33707,33682,33674,33683,33673,33696,33655,33659,33660,33670,33703,34389,24426,
+34503,34496,34486,34500,34485,34502,34507,34481,34479,34505,34899,34974,34952,
+34987,34962,34966,34957,34955,35219,35215,35370,35357,35363,35365,35377,35373,
+35359,35355,35362,35913,35930,36009,36012,36011,36008,36010,36007,36199,36198,
+36286,36282,36571,36575,36889,36877,36890,36887,36899,36895,36893,36880,36885,
+36894,36896,36879,36898,36886,36891,36884,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,37096,37101,37117,37207,37326,37365,37350,
+37347,37351,37357,37353,38281,38506,38517,38515,38520,38512,38516,38518,38519,
+38508,38592,38634,38633,31456,31455,38914,38915,39770,40165,40565,40575,40613,
+40635,20642,20621,20613,20633,20625,20608,20630,20632,20634,26368,20977,21106,
+21108,21109,21097,21214,21213,21211,21338,21413,21883,21888,21927,21884,21898,
+21917,21912,21890,21916,21930,21908,21895,21899,21891,21939,21934,21919,21822,
+21938,21914,21947,21932,21937,21886,21897,21931,21913,22285,22575,22570,22580,
+22564,22576,22577,22561,22557,22560,22777,22778,22880,23159,23194,23167,23186,
+23195,23207,23411,23409,23506,23500,23507,23504,23562,23563,23601,23884,23888,
+23860,23879,24061,24133,24125,24128,24131,24190,24266,24257,24258,24260,24380,
+24429,24489,24490,24488,24785,24801,24754,24758,24800,24860,24867,24826,24853,
+24816,24827,24820,24936,24817,24846,24822,24841,24832,24850,25119,25161,25507,
+25484,25551,25536,25577,25545,25542,25549,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,25554,25571,25552,25569,25558,25581,25582,
+25462,25588,25578,25563,25682,25562,25593,25950,25958,25954,25955,26001,26000,
+26031,26222,26224,26228,26230,26223,26257,26234,26238,26231,26366,26367,26399,
+26397,26874,26837,26848,26840,26839,26885,26847,26869,26862,26855,26873,26834,
+26866,26851,26827,26829,26893,26898,26894,26825,26842,26990,26875,27454,27450,
+27453,27544,27542,27580,27631,27694,27695,27692,28207,28216,28244,28193,28210,
+28263,28234,28192,28197,28195,28187,28251,28248,28196,28246,28270,28205,28198,
+28271,28212,28237,28218,28204,28227,28189,28222,28363,28297,28185,28238,28259,
+28228,28274,28265,28255,28953,28954,28966,28976,28961,28982,29038,28956,29260,
+29316,29312,29494,29477,29492,29481,29754,29738,29747,29730,29733,29749,29750,
+29748,29743,29723,29734,29736,29989,29990,30059,30058,30178,30171,30179,30169,
+30168,30174,30176,30331,30332,30358,30355,30388,30428,30543,30701,30813,30828,
+30831,31245,31240,31243,31237,31232,31384,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,31383,31382,31461,31459,31561,31574,31558,
+31568,31570,31572,31565,31563,31567,31569,31903,31909,32094,32080,32104,32085,
+32043,32110,32114,32097,32102,32098,32112,32115,21892,32724,32725,32779,32850,
+32901,33109,33108,33099,33105,33102,33081,33094,33086,33100,33107,33140,33298,
+33308,33769,33795,33784,33805,33760,33733,33803,33729,33775,33777,33780,33879,
+33802,33776,33804,33740,33789,33778,33738,33848,33806,33796,33756,33799,33748,
+33759,34395,34527,34521,34541,34516,34523,34532,34512,34526,34903,35009,35010,
+34993,35203,35222,35387,35424,35413,35422,35388,35393,35412,35419,35408,35398,
+35380,35386,35382,35414,35937,35970,36015,36028,36019,36029,36033,36027,36032,
+36020,36023,36022,36031,36024,36234,36229,36225,36302,36317,36299,36314,36305,
+36300,36315,36294,36603,36600,36604,36764,36910,36917,36913,36920,36914,36918,
+37122,37109,37129,37118,37219,37221,37327,37396,37397,37411,37385,37406,37389,
+37392,37383,37393,38292,38287,38283,38289,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,38291,38290,38286,38538,38542,38539,38525,
+38533,38534,38541,38514,38532,38593,38597,38596,38598,38599,38639,38642,38860,
+38917,38918,38920,39143,39146,39151,39145,39154,39149,39342,39341,40643,40653,
+40657,20098,20653,20661,20658,20659,20677,20670,20652,20663,20667,20655,20679,
+21119,21111,21117,21215,21222,21220,21218,21219,21295,21983,21992,21971,21990,
+21966,21980,21959,21969,21987,21988,21999,21978,21985,21957,21958,21989,21961,
+22290,22291,22622,22609,22616,22615,22618,22612,22635,22604,22637,22602,22626,
+22610,22603,22887,23233,23241,23244,23230,23229,23228,23219,23234,23218,23913,
+23919,24140,24185,24265,24264,24338,24409,24492,24494,24858,24847,24904,24863,
+24819,24859,24825,24833,24840,24910,24908,24900,24909,24894,24884,24871,24845,
+24838,24887,25121,25122,25619,25662,25630,25642,25645,25661,25644,25615,25628,
+25620,25613,25654,25622,25623,25606,25964,26015,26032,26263,26249,26247,26248,
+26262,26244,26264,26253,26371,27028,26989,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,26970,26999,26976,26964,26997,26928,27010,
+26954,26984,26987,26974,26963,27001,27014,26973,26979,26971,27463,27506,27584,
+27583,27603,27645,28322,28335,28371,28342,28354,28304,28317,28359,28357,28325,
+28312,28348,28346,28331,28369,28310,28316,28356,28372,28330,28327,28340,29006,
+29017,29033,29028,29001,29031,29020,29036,29030,29004,29029,29022,28998,29032,
+29014,29242,29266,29495,29509,29503,29502,29807,29786,29781,29791,29790,29761,
+29759,29785,29787,29788,30070,30072,30208,30192,30209,30194,30193,30202,30207,
+30196,30195,30430,30431,30555,30571,30566,30558,30563,30585,30570,30572,30556,
+30565,30568,30562,30702,30862,30896,30871,30872,30860,30857,30844,30865,30867,
+30847,31098,31103,31105,33836,31165,31260,31258,31264,31252,31263,31262,31391,
+31392,31607,31680,31584,31598,31591,31921,31923,31925,32147,32121,32145,32129,
+32143,32091,32622,32617,32618,32626,32681,32680,32676,32854,32856,32902,32900,
+33137,33136,33144,33125,33134,33139,33131,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,33145,33146,33126,33285,33351,33922,33911,
+33853,33841,33909,33894,33899,33865,33900,33883,33852,33845,33889,33891,33897,
+33901,33862,34398,34396,34399,34553,34579,34568,34567,34560,34558,34555,34562,
+34563,34566,34570,34905,35039,35028,35033,35036,35032,35037,35041,35018,35029,
+35026,35228,35299,35435,35442,35443,35430,35433,35440,35463,35452,35427,35488,
+35441,35461,35437,35426,35438,35436,35449,35451,35390,35432,35938,35978,35977,
+36042,36039,36040,36036,36018,36035,36034,36037,36321,36319,36328,36335,36339,
+36346,36330,36324,36326,36530,36611,36617,36606,36618,36767,36786,36939,36938,
+36947,36930,36948,36924,36949,36944,36935,36943,36942,36941,36945,36926,36929,
+37138,37143,37228,37226,37225,37321,37431,37463,37432,37437,37440,37438,37467,
+37451,37476,37457,37428,37449,37453,37445,37433,37439,37466,38296,38552,38548,
+38549,38605,38603,38601,38602,38647,38651,38649,38646,38742,38772,38774,38928,
+38929,38931,38922,38930,38924,39164,39156,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,39165,39166,39347,39345,39348,39649,40169,
+40578,40718,40723,40736,20711,20718,20709,20694,20717,20698,20693,20687,20689,
+20721,20686,20713,20834,20979,21123,21122,21297,21421,22014,22016,22043,22039,
+22013,22036,22022,22025,22029,22030,22007,22038,22047,22024,22032,22006,22296,
+22294,22645,22654,22659,22675,22666,22649,22661,22653,22781,22821,22818,22820,
+22890,22889,23265,23270,23273,23255,23254,23256,23267,23413,23518,23527,23521,
+23525,23526,23528,23522,23524,23519,23565,23650,23940,23943,24155,24163,24149,
+24151,24148,24275,24278,24330,24390,24432,24505,24903,24895,24907,24951,24930,
+24931,24927,24922,24920,24949,25130,25735,25688,25684,25764,25720,25695,25722,
+25681,25703,25652,25709,25723,25970,26017,26071,26070,26274,26280,26269,27036,
+27048,27029,27073,27054,27091,27083,27035,27063,27067,27051,27060,27088,27085,
+27053,27084,27046,27075,27043,27465,27468,27699,28467,28436,28414,28435,28404,
+28457,28478,28448,28460,28431,28418,28450,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,28415,28399,28422,28465,28472,28466,28451,
+28437,28459,28463,28552,28458,28396,28417,28402,28364,28407,29076,29081,29053,
+29066,29060,29074,29246,29330,29334,29508,29520,29796,29795,29802,29808,29805,
+29956,30097,30247,30221,30219,30217,30227,30433,30435,30596,30589,30591,30561,
+30913,30879,30887,30899,30889,30883,31118,31119,31117,31278,31281,31402,31401,
+31469,31471,31649,31637,31627,31605,31639,31645,31636,31631,31672,31623,31620,
+31929,31933,31934,32187,32176,32156,32189,32190,32160,32202,32180,32178,32177,
+32186,32162,32191,32181,32184,32173,32210,32199,32172,32624,32736,32737,32735,
+32862,32858,32903,33104,33152,33167,33160,33162,33151,33154,33255,33274,33287,
+33300,33310,33355,33993,33983,33990,33988,33945,33950,33970,33948,33995,33976,
+33984,34003,33936,33980,34001,33994,34623,34588,34619,34594,34597,34612,34584,
+34645,34615,34601,35059,35074,35060,35065,35064,35069,35048,35098,35055,35494,
+35468,35486,35491,35469,35489,35475,35492,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,35498,35493,35496,35480,35473,35482,35495,
+35946,35981,35980,36051,36049,36050,36203,36249,36245,36348,36628,36626,36629,
+36627,36771,36960,36952,36956,36963,36953,36958,36962,36957,36955,37145,37144,
+37150,37237,37240,37239,37236,37496,37504,37509,37528,37526,37499,37523,37532,
+37544,37500,37521,38305,38312,38313,38307,38309,38308,38553,38556,38555,38604,
+38610,38656,38780,38789,38902,38935,38936,39087,39089,39171,39173,39180,39177,
+39361,39599,39600,39654,39745,39746,40180,40182,40179,40636,40763,40778,20740,
+20736,20731,20725,20729,20738,20744,20745,20741,20956,21127,21128,21129,21133,
+21130,21232,21426,22062,22075,22073,22066,22079,22068,22057,22099,22094,22103,
+22132,22070,22063,22064,22656,22687,22686,22707,22684,22702,22697,22694,22893,
+23305,23291,23307,23285,23308,23304,23534,23532,23529,23531,23652,23653,23965,
+23956,24162,24159,24161,24290,24282,24287,24285,24291,24288,24392,24433,24503,
+24501,24950,24935,24942,24925,24917,24962,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,24956,24944,24939,24958,24999,24976,25003,
+24974,25004,24986,24996,24980,25006,25134,25705,25711,25721,25758,25778,25736,
+25744,25776,25765,25747,25749,25769,25746,25774,25773,25771,25754,25772,25753,
+25762,25779,25973,25975,25976,26286,26283,26292,26289,27171,27167,27112,27137,
+27166,27161,27133,27169,27155,27146,27123,27138,27141,27117,27153,27472,27470,
+27556,27589,27590,28479,28540,28548,28497,28518,28500,28550,28525,28507,28536,
+28526,28558,28538,28528,28516,28567,28504,28373,28527,28512,28511,29087,29100,
+29105,29096,29270,29339,29518,29527,29801,29835,29827,29822,29824,30079,30240,
+30249,30239,30244,30246,30241,30242,30362,30394,30436,30606,30599,30604,30609,
+30603,30923,30917,30906,30922,30910,30933,30908,30928,31295,31292,31296,31293,
+31287,31291,31407,31406,31661,31665,31684,31668,31686,31687,31681,31648,31692,
+31946,32224,32244,32239,32251,32216,32236,32221,32232,32227,32218,32222,32233,
+32158,32217,32242,32249,32629,32631,32687,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,32745,32806,33179,33180,33181,33184,33178,
+33176,34071,34109,34074,34030,34092,34093,34067,34065,34083,34081,34068,34028,
+34085,34047,34054,34690,34676,34678,34656,34662,34680,34664,34649,34647,34636,
+34643,34907,34909,35088,35079,35090,35091,35093,35082,35516,35538,35527,35524,
+35477,35531,35576,35506,35529,35522,35519,35504,35542,35533,35510,35513,35547,
+35916,35918,35948,36064,36062,36070,36068,36076,36077,36066,36067,36060,36074,
+36065,36205,36255,36259,36395,36368,36381,36386,36367,36393,36383,36385,36382,
+36538,36637,36635,36639,36649,36646,36650,36636,36638,36645,36969,36974,36968,
+36973,36983,37168,37165,37159,37169,37255,37257,37259,37251,37573,37563,37559,
+37610,37548,37604,37569,37555,37564,37586,37575,37616,37554,38317,38321,38660,
+38662,38663,38665,38752,38797,38795,38799,38945,38955,38940,39091,39178,39187,
+39186,39192,39389,39376,39391,39387,39377,39381,39378,39385,39607,39662,39663,
+39719,39749,39748,39799,39791,40198,40201,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,40195,40617,40638,40654,22696,40786,20754,
+20760,20756,20752,20757,20864,20906,20957,21137,21139,21235,22105,22123,22137,
+22121,22116,22136,22122,22120,22117,22129,22127,22124,22114,22134,22721,22718,
+22727,22725,22894,23325,23348,23416,23536,23566,24394,25010,24977,25001,24970,
+25037,25014,25022,25034,25032,25136,25797,25793,25803,25787,25788,25818,25796,
+25799,25794,25805,25791,25810,25812,25790,25972,26310,26313,26297,26308,26311,
+26296,27197,27192,27194,27225,27243,27224,27193,27204,27234,27233,27211,27207,
+27189,27231,27208,27481,27511,27653,28610,28593,28577,28611,28580,28609,28583,
+28595,28608,28601,28598,28582,28576,28596,29118,29129,29136,29138,29128,29141,
+29113,29134,29145,29148,29123,29124,29544,29852,29859,29848,29855,29854,29922,
+29964,29965,30260,30264,30266,30439,30437,30624,30622,30623,30629,30952,30938,
+30956,30951,31142,31309,31310,31302,31308,31307,31418,31705,31761,31689,31716,
+31707,31713,31721,31718,31957,31958,32266,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,32273,32264,32283,32291,32286,32285,32265,
+32272,32633,32690,32752,32753,32750,32808,33203,33193,33192,33275,33288,33368,
+33369,34122,34137,34120,34152,34153,34115,34121,34157,34154,34142,34691,34719,
+34718,34722,34701,34913,35114,35122,35109,35115,35105,35242,35238,35558,35578,
+35563,35569,35584,35548,35559,35566,35582,35585,35586,35575,35565,35571,35574,
+35580,35947,35949,35987,36084,36420,36401,36404,36418,36409,36405,36667,36655,
+36664,36659,36776,36774,36981,36980,36984,36978,36988,36986,37172,37266,37664,
+37686,37624,37683,37679,37666,37628,37675,37636,37658,37648,37670,37665,37653,
+37678,37657,38331,38567,38568,38570,38613,38670,38673,38678,38669,38675,38671,
+38747,38748,38758,38808,38960,38968,38971,38967,38957,38969,38948,39184,39208,
+39198,39195,39201,39194,39405,39394,39409,39608,39612,39675,39661,39720,39825,
+40213,40227,40230,40232,40210,40219,40664,40660,40845,40860,20778,20767,20769,
+20786,21237,22158,22144,22160,22149,22151,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,22159,22741,22739,22737,22734,23344,23338,
+23332,23418,23607,23656,23996,23994,23997,23992,24171,24396,24509,25033,25026,
+25031,25062,25035,25138,25140,25806,25802,25816,25824,25840,25830,25836,25841,
+25826,25837,25986,25987,26329,26326,27264,27284,27268,27298,27292,27355,27299,
+27262,27287,27280,27296,27484,27566,27610,27656,28632,28657,28639,28640,28635,
+28644,28651,28655,28544,28652,28641,28649,28629,28654,28656,29159,29151,29166,
+29158,29157,29165,29164,29172,29152,29237,29254,29552,29554,29865,29872,29862,
+29864,30278,30274,30284,30442,30643,30634,30640,30636,30631,30637,30703,30967,
+30970,30964,30959,30977,31143,31146,31319,31423,31751,31757,31742,31735,31756,
+31712,31968,31964,31966,31970,31967,31961,31965,32302,32318,32326,32311,32306,
+32323,32299,32317,32305,32325,32321,32308,32313,32328,32309,32319,32303,32580,
+32755,32764,32881,32882,32880,32879,32883,33222,33219,33210,33218,33216,33215,
+33213,33225,33214,33256,33289,33393,34218,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,34180,34174,34204,34193,34196,34223,34203,
+34183,34216,34186,34407,34752,34769,34739,34770,34758,34731,34747,34746,34760,
+34763,35131,35126,35140,35128,35133,35244,35598,35607,35609,35611,35594,35616,
+35613,35588,35600,35905,35903,35955,36090,36093,36092,36088,36091,36264,36425,
+36427,36424,36426,36676,36670,36674,36677,36671,36991,36989,36996,36993,36994,
+36992,37177,37283,37278,37276,37709,37762,37672,37749,37706,37733,37707,37656,
+37758,37740,37723,37744,37722,37716,38346,38347,38348,38344,38342,38577,38584,
+38614,38684,38686,38816,38867,38982,39094,39221,39425,39423,39854,39851,39850,
+39853,40251,40255,40587,40655,40670,40668,40669,40667,40766,40779,21474,22165,
+22190,22745,22744,23352,24413,25059,25139,25844,25842,25854,25862,25850,25851,
+25847,26039,26332,26406,27315,27308,27331,27323,27320,27330,27310,27311,27487,
+27512,27567,28681,28683,28670,28678,28666,28689,28687,29179,29180,29182,29176,
+29559,29557,29863,29887,29973,30294,30296,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,30290,30653,30655,30651,30652,30990,31150,
+31329,31330,31328,31428,31429,31787,31783,31786,31774,31779,31777,31975,32340,
+32341,32350,32346,32353,32338,32345,32584,32761,32763,32887,32886,33229,33231,
+33290,34255,34217,34253,34256,34249,34224,34234,34233,34214,34799,34796,34802,
+34784,35206,35250,35316,35624,35641,35628,35627,35920,36101,36441,36451,36454,
+36452,36447,36437,36544,36681,36685,36999,36995,37000,37291,37292,37328,37780,
+37770,37782,37794,37811,37806,37804,37808,37784,37786,37783,38356,38358,38352,
+38357,38626,38620,38617,38619,38622,38692,38819,38822,38829,38905,38989,38991,
+38988,38990,38995,39098,39230,39231,39229,39214,39333,39438,39617,39683,39686,
+39759,39758,39757,39882,39881,39933,39880,39872,40273,40285,40288,40672,40725,
+40748,20787,22181,22750,22751,22754,23541,40848,24300,25074,25079,25078,25077,
+25856,25871,26336,26333,27365,27357,27354,27347,28699,28703,28712,28698,28701,
+28693,28696,29190,29197,29272,29346,29560,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,29562,29885,29898,29923,30087,30086,30303,
+30305,30663,31001,31153,31339,31337,31806,31807,31800,31805,31799,31808,32363,
+32365,32377,32361,32362,32645,32371,32694,32697,32696,33240,34281,34269,34282,
+34261,34276,34277,34295,34811,34821,34829,34809,34814,35168,35167,35158,35166,
+35649,35676,35672,35657,35674,35662,35663,35654,35673,36104,36106,36476,36466,
+36487,36470,36460,36474,36468,36692,36686,36781,37002,37003,37297,37294,37857,
+37841,37855,37827,37832,37852,37853,37846,37858,37837,37848,37860,37847,37864,
+38364,38580,38627,38698,38695,38753,38876,38907,39006,39000,39003,39100,39237,
+39241,39446,39449,39693,39912,39911,39894,39899,40329,40289,40306,40298,40300,
+40594,40599,40595,40628,21240,22184,22199,22198,22196,22204,22756,23360,23363,
+23421,23542,24009,25080,25082,25880,25876,25881,26342,26407,27372,28734,28720,
+28722,29200,29563,29903,30306,30309,31014,31018,31020,31019,31431,31478,31820,
+31811,31821,31983,31984,36782,32381,32380,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,32386,32588,32768,33242,33382,34299,34297,
+34321,34298,34310,34315,34311,34314,34836,34837,35172,35258,35320,35696,35692,
+35686,35695,35679,35691,36111,36109,36489,36481,36485,36482,37300,37323,37912,
+37891,37885,38369,38704,39108,39250,39249,39336,39467,39472,39479,39477,39955,
+39949,40569,40629,40680,40751,40799,40803,40801,20791,20792,22209,22208,22210,
+22804,23660,24013,25084,25086,25885,25884,26005,26345,27387,27396,27386,27570,
+28748,29211,29351,29910,29908,30313,30675,31824,32399,32396,32700,34327,34349,
+34330,34851,34850,34849,34847,35178,35180,35261,35700,35703,35709,36115,36490,
+36493,36491,36703,36783,37306,37934,37939,37941,37946,37944,37938,37931,38370,
+38712,38713,38706,38911,39015,39013,39255,39493,39491,39488,39486,39631,39764,
+39761,39981,39973,40367,40372,40386,40376,40605,40687,40729,40796,40806,40807,
+20796,20795,22216,22218,22217,23423,24020,24018,24398,25087,25892,27402,27489,
+28753,28760,29568,29924,30090,30318,30316,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,31155,31840,31839,32894,32893,33247,35186,
+35183,35324,35712,36118,36119,36497,36499,36705,37192,37956,37969,37970,38717,
+38718,38851,38849,39019,39253,39509,39501,39634,39706,40009,39985,39998,39995,
+40403,40407,40756,40812,40810,40852,22220,24022,25088,25891,25899,25898,26348,
+27408,29914,31434,31844,31843,31845,32403,32406,32404,33250,34360,34367,34865,
+35722,37008,37007,37987,37984,37988,38760,39023,39260,39514,39515,39511,39635,
+39636,39633,40020,40023,40022,40421,40607,40692,22225,22761,25900,28766,30321,
+30322,30679,32592,32648,34870,34873,34914,35731,35730,35734,33399,36123,37312,
+37994,38722,38728,38724,38854,39024,39519,39714,39768,40031,40441,40442,40572,
+40573,40711,40823,40818,24307,27414,28771,31852,31854,34875,35264,36513,37313,
+38002,38000,39025,39262,39638,39715,40652,28772,30682,35738,38007,38857,39522,
+39525,32412,35740,36522,37317,38013,38014,38012,40055,40056,40695,35924,38015,
+40474,29224,39530,39729,40475,40478,31858,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,12542,12445,12446,12293,12353,12354,12355,
+12356,12357,12358,12359,12360,12361,12362,12363,12364,12365,12366,12367,12368,
+12369,12370,12371,12372,12373,12374,12375,12376,12377,12378,12379,12380,12381,
+12382,12383,12384,12385,12386,12387,12388,12389,12390,12391,12392,12393,12394,
+12395,12396,12397,12398,12399,12400,12401,12402,12403,12404,12405,12406,12407,
+12408,12409,12410,12411,12412,12413,12414,12415,12416,12417,12418,12419,12420,
+12421,12422,12423,12424,12425,12426,12427,12428,12429,12430,12431,12432,12433,
+12434,12435,12449,12450,12451,12452,12453,12454,12455,12456,12457,12458,12459,
+12460,12461,12462,12463,12464,12465,12466,12467,12468,12469,12470,12471,12472,
+12473,12474,12475,12476,12477,12478,12479,12480,12481,12482,12483,12484,12485,
+12486,12487,12488,12489,12490,12491,12492,12493,12494,12495,12496,12497,12498,
+12499,12500,12501,12502,12503,12504,12505,12506,12507,12508,12509,12510,12511,
+12512,12513,12514,12515,12516,12517,12518,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,12519,12520,12521,12522,12523,12524,12525,
+12526,12527,12528,12529,12530,12531,12532,12533,12534,1044,1045,1025,1046,
+1047,1048,1049,1050,1051,1052,1059,1060,1061,1062,1063,1064,1065,1066,1067,
+1068,1069,1070,1071,1072,1073,1074,1075,1076,1077,1105,1078,1079,1080,1081,
+1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,
+1097,1098,1099,1100,1101,1102,1103,9312,9313,9314,9315,9316,9317,9318,9319,
+9320,9321,9332,9333,9334,9335,9336,9337,9338,9339,9340,9341,20034,20060,20981,
+21274,21378,19975,19980,20039,20109,22231,64012,23662,24435,19983,20871,19982,
+20014,20115,20162,20169,20168,20888,21244,21356,21433,22304,22787,22828,23568,
+24063,26081,27571,27596,27668,29247,20017,20028,20200,20188,20201,20193,20189,
+20186,21004,21276,21324,22306,22307,22807,22831,23425,23428,23570,23611,23668,
+23667,24068,24192,24194,24521,25097,25168,27669,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,27702,27715,27711,27707,29358,29360,
+29578,31160,32906,38430,20238,20248,20268,20213,20244,20209,20224,20215,20232,
+20253,20226,20229,20258,20243,20228,20212,20242,20913,21011,21001,21008,21158,
+21282,21279,21325,21386,21511,22241,22239,22318,22314,22324,22844,22912,22908,
+22917,22907,22910,22903,22911,23382,23573,23589,23676,23674,23675,23678,24031,
+24181,24196,24322,24346,24436,24533,24532,24527,25180,25182,25188,25185,25190,
+25186,25177,25184,25178,25189,26095,26094,26430,26425,26424,26427,26426,26431,
+26428,26419,27672,27718,27730,27740,27727,27722,27732,27723,27724,28785,29278,
+29364,29365,29582,29994,30335,31349,32593,33400,33404,33408,33405,33407,34381,
+35198,37017,37015,37016,37019,37012,38434,38436,38432,38435,20310,20283,20322,
+20297,20307,20324,20286,20327,20306,20319,20289,20312,20269,20275,20287,20321,
+20879,20921,21020,21022,21025,21165,21166,21257,21347,21362,21390,21391,21552,
+21559,21546,21588,21573,21529,21532,21541,21528,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,21565,21583,21569,21544,21540,21575,
+22254,22247,22245,22337,22341,22348,22345,22347,22354,22790,22848,22950,22936,
+22944,22935,22926,22946,22928,22927,22951,22945,23438,23442,23592,23594,23693,
+23695,23688,23691,23689,23698,23690,23686,23699,23701,24032,24074,24078,24203,
+24201,24204,24200,24205,24325,24349,24440,24438,24530,24529,24528,24557,24552,
+24558,24563,24545,24548,24547,24570,24559,24567,24571,24576,24564,25146,25219,
+25228,25230,25231,25236,25223,25201,25211,25210,25200,25217,25224,25207,25213,
+25202,25204,25911,26096,26100,26099,26098,26101,26437,26439,26457,26453,26444,
+26440,26461,26445,26458,26443,27600,27673,27674,27768,27751,27755,27780,27787,
+27791,27761,27759,27753,27802,27757,27783,27797,27804,27750,27763,27749,27771,
+27790,28788,28794,29283,29375,29373,29379,29382,29377,29370,29381,29589,29591,
+29587,29588,29586,30010,30009,30100,30101,30337,31037,32820,32917,32921,32912,
+32914,32924,33424,33423,33413,33422,33425,33427,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,33418,33411,33412,35960,36809,36799,
+37023,37025,37029,37022,37031,37024,38448,38440,38447,38445,20019,20376,20348,
+20357,20349,20352,20359,20342,20340,20361,20356,20343,20300,20375,20330,20378,
+20345,20353,20344,20368,20380,20372,20382,20370,20354,20373,20331,20334,20894,
+20924,20926,21045,21042,21043,21062,21041,21180,21258,21259,21308,21394,21396,
+21639,21631,21633,21649,21634,21640,21611,21626,21630,21605,21612,21620,21606,
+21645,21615,21601,21600,21656,21603,21607,21604,22263,22265,22383,22386,22381,
+22379,22385,22384,22390,22400,22389,22395,22387,22388,22370,22376,22397,22796,
+22853,22965,22970,22991,22990,22962,22988,22977,22966,22972,22979,22998,22961,
+22973,22976,22984,22964,22983,23394,23397,23443,23445,23620,23623,23726,23716,
+23712,23733,23727,23720,23724,23711,23715,23725,23714,23722,23719,23709,23717,
+23734,23728,23718,24087,24084,24089,24360,24354,24355,24356,24404,24450,24446,
+24445,24542,24549,24621,24614,24601,24626,24587,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,24628,24586,24599,24627,24602,24606,
+24620,24610,24589,24592,24622,24595,24593,24588,24585,24604,25108,25149,25261,
+25268,25297,25278,25258,25270,25290,25262,25267,25263,25275,25257,25264,25272,
+25917,26024,26043,26121,26108,26116,26130,26120,26107,26115,26123,26125,26117,
+26109,26129,26128,26358,26378,26501,26476,26510,26514,26486,26491,26520,26502,
+26500,26484,26509,26508,26490,26527,26513,26521,26499,26493,26497,26488,26489,
+26516,27429,27520,27518,27614,27677,27795,27884,27883,27886,27865,27830,27860,
+27821,27879,27831,27856,27842,27834,27843,27846,27885,27890,27858,27869,27828,
+27786,27805,27776,27870,27840,27952,27853,27847,27824,27897,27855,27881,27857,
+28820,28824,28805,28819,28806,28804,28817,28822,28802,28826,28803,29290,29398,
+29387,29400,29385,29404,29394,29396,29402,29388,29393,29604,29601,29613,29606,
+29602,29600,29612,29597,29917,29928,30015,30016,30014,30092,30104,30383,30451,
+30449,30448,30453,30712,30716,30713,30715,30714,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,30711,31042,31039,31173,31352,31355,
+31483,31861,31997,32821,32911,32942,32931,32952,32949,32941,33312,33440,33472,
+33451,33434,33432,33435,33461,33447,33454,33468,33438,33466,33460,33448,33441,
+33449,33474,33444,33475,33462,33442,34416,34415,34413,34414,35926,36818,36811,
+36819,36813,36822,36821,36823,37042,37044,37039,37043,37040,38457,38461,38460,
+38458,38467,20429,20421,20435,20402,20425,20427,20417,20436,20444,20441,20411,
+20403,20443,20423,20438,20410,20416,20409,20460,21060,21065,21184,21186,21309,
+21372,21399,21398,21401,21400,21690,21665,21677,21669,21711,21699,33549,21687,
+21678,21718,21686,21701,21702,21664,21616,21692,21666,21694,21618,21726,21680,
+22453,22430,22431,22436,22412,22423,22429,22427,22420,22424,22415,22425,22437,
+22426,22421,22772,22797,22867,23009,23006,23022,23040,23025,23005,23034,23037,
+23036,23030,23012,23026,23031,23003,23017,23027,23029,23008,23038,23028,23021,
+23464,23628,23760,23768,23756,23767,23755,23771,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,23774,23770,23753,23751,23754,23766,
+23763,23764,23759,23752,23750,23758,23775,23800,24057,24097,24098,24099,24096,
+24100,24240,24228,24226,24219,24227,24229,24327,24366,24406,24454,24631,24633,
+24660,24690,24670,24645,24659,24647,24649,24667,24652,24640,24642,24671,24612,
+24644,24664,24678,24686,25154,25155,25295,25357,25355,25333,25358,25347,25323,
+25337,25359,25356,25336,25334,25344,25363,25364,25338,25365,25339,25328,25921,
+25923,26026,26047,26166,26145,26162,26165,26140,26150,26146,26163,26155,26170,
+26141,26164,26169,26158,26383,26384,26561,26610,26568,26554,26588,26555,26616,
+26584,26560,26551,26565,26603,26596,26591,26549,26573,26547,26615,26614,26606,
+26595,26562,26553,26574,26599,26608,26546,26620,26566,26605,26572,26542,26598,
+26587,26618,26569,26570,26563,26602,26571,27432,27522,27524,27574,27606,27608,
+27616,27680,27681,27944,27956,27949,27935,27964,27967,27922,27914,27866,27955,
+27908,27929,27962,27930,27921,27904,27933,27970,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,27905,27928,27959,27907,27919,27968,
+27911,27936,27948,27912,27938,27913,27920,28855,28831,28862,28849,28848,28833,
+28852,28853,28841,29249,29257,29258,29292,29296,29299,29294,29386,29412,29416,
+29419,29407,29418,29414,29411,29573,29644,29634,29640,29637,29625,29622,29621,
+29620,29675,29631,29639,29630,29635,29638,29624,29643,29932,29934,29998,30023,
+30024,30119,30122,30329,30404,30472,30467,30468,30469,30474,30455,30459,30458,
+30695,30696,30726,30737,30738,30725,30736,30735,30734,30729,30723,30739,31050,
+31052,31051,31045,31044,31189,31181,31183,31190,31182,31360,31358,31441,31488,
+31489,31866,31864,31865,31871,31872,31873,32003,32008,32001,32600,32657,32653,
+32702,32775,32782,32783,32788,32823,32984,32967,32992,32977,32968,32962,32976,
+32965,32995,32985,32988,32970,32981,32969,32975,32983,32998,32973,33279,33313,
+33428,33497,33534,33529,33543,33512,33536,33493,33594,33515,33494,33524,33516,
+33505,33522,33525,33548,33531,33526,33520,33514,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,33508,33504,33530,33523,33517,34423,
+34420,34428,34419,34881,34894,34919,34922,34921,35283,35332,35335,36210,36835,
+36833,36846,36832,37105,37053,37055,37077,37061,37054,37063,37067,37064,37332,
+37331,38484,38479,38481,38483,38474,38478,20510,20485,20487,20499,20514,20528,
+20507,20469,20468,20531,20535,20524,20470,20471,20503,20508,20512,20519,20533,
+20527,20529,20494,20826,20884,20883,20938,20932,20933,20936,20942,21089,21082,
+21074,21086,21087,21077,21090,21197,21262,21406,21798,21730,21783,21778,21735,
+21747,21732,21786,21759,21764,21768,21739,21777,21765,21745,21770,21755,21751,
+21752,21728,21774,21763,21771,22273,22274,22476,22578,22485,22482,22458,22470,
+22461,22460,22456,22454,22463,22471,22480,22457,22465,22798,22858,23065,23062,
+23085,23086,23061,23055,23063,23050,23070,23091,23404,23463,23469,23468,23555,
+23638,23636,23788,23807,23790,23793,23799,23808,23801,24105,24104,24232,24238,
+24234,24236,24371,24368,24423,24669,24666,24679,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,24641,24738,24712,24704,24722,24705,
+24733,24707,24725,24731,24727,24711,24732,24718,25113,25158,25330,25360,25430,
+25388,25412,25413,25398,25411,25572,25401,25419,25418,25404,25385,25409,25396,
+25432,25428,25433,25389,25415,25395,25434,25425,25400,25431,25408,25416,25930,
+25926,26054,26051,26052,26050,26186,26207,26183,26193,26386,26387,26655,26650,
+26697,26674,26675,26683,26699,26703,26646,26673,26652,26677,26667,26669,26671,
+26702,26692,26676,26653,26642,26644,26662,26664,26670,26701,26682,26661,26656,
+27436,27439,27437,27441,27444,27501,32898,27528,27622,27620,27624,27619,27618,
+27623,27685,28026,28003,28004,28022,27917,28001,28050,27992,28002,28013,28015,
+28049,28045,28143,28031,28038,27998,28007,28000,28055,28016,28028,27999,28034,
+28056,27951,28008,28043,28030,28032,28036,27926,28035,28027,28029,28021,28048,
+28892,28883,28881,28893,28875,32569,28898,28887,28882,28894,28896,28884,28877,
+28869,28870,28871,28890,28878,28897,29250,29304,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,29303,29302,29440,29434,29428,29438,
+29430,29427,29435,29441,29651,29657,29669,29654,29628,29671,29667,29673,29660,
+29650,29659,29652,29661,29658,29655,29656,29672,29918,29919,29940,29941,29985,
+30043,30047,30128,30145,30139,30148,30144,30143,30134,30138,30346,30409,30493,
+30491,30480,30483,30482,30499,30481,30485,30489,30490,30498,30503,30755,30764,
+30754,30773,30767,30760,30766,30763,30753,30761,30771,30762,30769,31060,31067,
+31055,31068,31059,31058,31057,31211,31212,31200,31214,31213,31210,31196,31198,
+31197,31366,31369,31365,31371,31372,31370,31367,31448,31504,31492,31507,31493,
+31503,31496,31498,31502,31497,31506,31876,31889,31882,31884,31880,31885,31877,
+32030,32029,32017,32014,32024,32022,32019,32031,32018,32015,32012,32604,32609,
+32606,32608,32605,32603,32662,32658,32707,32706,32704,32790,32830,32825,33018,
+33010,33017,33013,33025,33019,33024,33281,33327,33317,33587,33581,33604,33561,
+33617,33573,33622,33599,33601,33574,33564,33570,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,33602,33614,33563,33578,33544,33596,
+33613,33558,33572,33568,33591,33583,33577,33607,33605,33612,33619,33566,33580,
+33611,33575,33608,34387,34386,34466,34472,34454,34445,34449,34462,34439,34455,
+34438,34443,34458,34437,34469,34457,34465,34471,34453,34456,34446,34461,34448,
+34452,34883,34884,34925,34933,34934,34930,34944,34929,34943,34927,34947,34942,
+34932,34940,35346,35911,35927,35963,36004,36003,36214,36216,36277,36279,36278,
+36561,36563,36862,36853,36866,36863,36859,36868,36860,36854,37078,37088,37081,
+37082,37091,37087,37093,37080,37083,37079,37084,37092,37200,37198,37199,37333,
+37346,37338,38492,38495,38588,39139,39647,39727,20095,20592,20586,20577,20574,
+20576,20563,20555,20573,20594,20552,20557,20545,20571,20554,20578,20501,20549,
+20575,20585,20587,20579,20580,20550,20544,20590,20595,20567,20561,20944,21099,
+21101,21100,21102,21206,21203,21293,21404,21877,21878,21820,21837,21840,21812,
+21802,21841,21858,21814,21813,21808,21842,21829,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,21772,21810,21861,21838,21817,21832,
+21805,21819,21824,21835,22282,22279,22523,22548,22498,22518,22492,22516,22528,
+22509,22525,22536,22520,22539,22515,22479,22535,22510,22499,22514,22501,22508,
+22497,22542,22524,22544,22503,22529,22540,22513,22505,22512,22541,22532,22876,
+23136,23128,23125,23143,23134,23096,23093,23149,23120,23135,23141,23148,23123,
+23140,23127,23107,23133,23122,23108,23131,23112,23182,23102,23117,23097,23116,
+23152,23145,23111,23121,23126,23106,23132,23410,23406,23489,23488,23641,23838,
+23819,23837,23834,23840,23820,23848,23821,23846,23845,23823,23856,23826,23843,
+23839,23854,24126,24116,24241,24244,24249,24242,24243,24374,24376,24475,24470,
+24479,24714,24720,24710,24766,24752,24762,24787,24788,24783,24804,24793,24797,
+24776,24753,24795,24759,24778,24767,24771,24781,24768,25394,25445,25482,25474,
+25469,25533,25502,25517,25501,25495,25515,25486,25455,25479,25488,25454,25519,
+25461,25500,25453,25518,25468,25508,25403,25503,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,25464,25477,25473,25489,25485,25456,
+25939,26061,26213,26209,26203,26201,26204,26210,26392,26745,26759,26768,26780,
+26733,26734,26798,26795,26966,26735,26787,26796,26793,26741,26740,26802,26767,
+26743,26770,26748,26731,26738,26794,26752,26737,26750,26779,26774,26763,26784,
+26761,26788,26744,26747,26769,26764,26762,26749,27446,27443,27447,27448,27537,
+27535,27533,27534,27532,27690,28096,28075,28084,28083,28276,28076,28137,28130,
+28087,28150,28116,28160,28104,28128,28127,28118,28094,28133,28124,28125,28123,
+28148,28106,28093,28141,28144,28090,28117,28098,28111,28105,28112,28146,28115,
+28157,28119,28109,28131,28091,28922,28941,28919,28951,28916,28940,28912,28932,
+28915,28944,28924,28927,28934,28947,28928,28920,28918,28939,28930,28942,29310,
+29307,29308,29311,29469,29463,29447,29457,29464,29450,29448,29439,29455,29470,
+29576,29686,29688,29685,29700,29697,29693,29703,29696,29690,29692,29695,29708,
+29707,29684,29704,30052,30051,30158,30162,30159,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,30155,30156,30161,30160,30351,30345,
+30419,30521,30511,30509,30513,30514,30516,30515,30525,30501,30523,30517,30792,
+30802,30793,30797,30794,30796,30758,30789,30800,31076,31079,31081,31082,31075,
+31083,31073,31163,31226,31224,31222,31223,31375,31380,31376,31541,31559,31540,
+31525,31536,31522,31524,31539,31512,31530,31517,31537,31531,31533,31535,31538,
+31544,31514,31523,31892,31896,31894,31907,32053,32061,32056,32054,32058,32069,
+32044,32041,32065,32071,32062,32063,32074,32059,32040,32611,32661,32668,32669,
+32667,32714,32715,32717,32720,32721,32711,32719,32713,32799,32798,32795,32839,
+32835,32840,33048,33061,33049,33051,33069,33055,33068,33054,33057,33045,33063,
+33053,33058,33297,33336,33331,33338,33332,33330,33396,33680,33699,33704,33677,
+33658,33651,33700,33652,33679,33665,33685,33689,33653,33684,33705,33661,33667,
+33676,33693,33691,33706,33675,33662,33701,33711,33672,33687,33712,33663,33702,
+33671,33710,33654,33690,34393,34390,34495,34487,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,34498,34497,34501,34490,34480,34504,
+34489,34483,34488,34508,34484,34491,34492,34499,34493,34494,34898,34953,34965,
+34984,34978,34986,34970,34961,34977,34975,34968,34983,34969,34971,34967,34980,
+34988,34956,34963,34958,35202,35286,35289,35285,35376,35367,35372,35358,35897,
+35899,35932,35933,35965,36005,36221,36219,36217,36284,36290,36281,36287,36289,
+36568,36574,36573,36572,36567,36576,36577,36900,36875,36881,36892,36876,36897,
+37103,37098,37104,37108,37106,37107,37076,37099,37100,37097,37206,37208,37210,
+37203,37205,37356,37364,37361,37363,37368,37348,37369,37354,37355,37367,37352,
+37358,38266,38278,38280,38524,38509,38507,38513,38511,38591,38762,38916,39141,
+39319,20635,20629,20628,20638,20619,20643,20611,20620,20622,20637,20584,20636,
+20626,20610,20615,20831,20948,21266,21265,21412,21415,21905,21928,21925,21933,
+21879,22085,21922,21907,21896,21903,21941,21889,21923,21906,21924,21885,21900,
+21926,21887,21909,21921,21902,22284,22569,22583,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,22553,22558,22567,22563,22568,22517,
+22600,22565,22556,22555,22579,22591,22582,22574,22585,22584,22573,22572,22587,
+22881,23215,23188,23199,23162,23202,23198,23160,23206,23164,23205,23212,23189,
+23214,23095,23172,23178,23191,23171,23179,23209,23163,23165,23180,23196,23183,
+23187,23197,23530,23501,23499,23508,23505,23498,23502,23564,23600,23863,23875,
+23915,23873,23883,23871,23861,23889,23886,23893,23859,23866,23890,23869,23857,
+23897,23874,23865,23881,23864,23868,23858,23862,23872,23877,24132,24129,24408,
+24486,24485,24491,24777,24761,24780,24802,24782,24772,24852,24818,24842,24854,
+24837,24821,24851,24824,24828,24830,24769,24835,24856,24861,24848,24831,24836,
+24843,25162,25492,25521,25520,25550,25573,25576,25583,25539,25757,25587,25546,
+25568,25590,25557,25586,25589,25697,25567,25534,25565,25564,25540,25560,25555,
+25538,25543,25548,25547,25544,25584,25559,25561,25906,25959,25962,25956,25948,
+25960,25957,25996,26013,26014,26030,26064,26066,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,26236,26220,26235,26240,26225,26233,
+26218,26226,26369,26892,26835,26884,26844,26922,26860,26858,26865,26895,26838,
+26871,26859,26852,26870,26899,26896,26867,26849,26887,26828,26888,26992,26804,
+26897,26863,26822,26900,26872,26832,26877,26876,26856,26891,26890,26903,26830,
+26824,26845,26846,26854,26868,26833,26886,26836,26857,26901,26917,26823,27449,
+27451,27455,27452,27540,27543,27545,27541,27581,27632,27634,27635,27696,28156,
+28230,28231,28191,28233,28296,28220,28221,28229,28258,28203,28223,28225,28253,
+28275,28188,28211,28235,28224,28241,28219,28163,28206,28254,28264,28252,28257,
+28209,28200,28256,28273,28267,28217,28194,28208,28243,28261,28199,28280,28260,
+28279,28245,28281,28242,28262,28213,28214,28250,28960,28958,28975,28923,28974,
+28977,28963,28965,28962,28978,28959,28968,28986,28955,29259,29274,29320,29321,
+29318,29317,29323,29458,29451,29488,29474,29489,29491,29479,29490,29485,29478,
+29475,29493,29452,29742,29740,29744,29739,29718,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,29722,29729,29741,29745,29732,29731,
+29725,29737,29728,29746,29947,29999,30063,30060,30183,30170,30177,30182,30173,
+30175,30180,30167,30357,30354,30426,30534,30535,30532,30541,30533,30538,30542,
+30539,30540,30686,30700,30816,30820,30821,30812,30829,30833,30826,30830,30832,
+30825,30824,30814,30818,31092,31091,31090,31088,31234,31242,31235,31244,31236,
+31385,31462,31460,31562,31547,31556,31560,31564,31566,31552,31576,31557,31906,
+31902,31912,31905,32088,32111,32099,32083,32086,32103,32106,32079,32109,32092,
+32107,32082,32084,32105,32081,32095,32078,32574,32575,32613,32614,32674,32672,
+32673,32727,32849,32847,32848,33022,32980,33091,33098,33106,33103,33095,33085,
+33101,33082,33254,33262,33271,33272,33273,33284,33340,33341,33343,33397,33595,
+33743,33785,33827,33728,33768,33810,33767,33764,33788,33782,33808,33734,33736,
+33771,33763,33727,33793,33757,33765,33752,33791,33761,33739,33742,33750,33781,
+33737,33801,33807,33758,33809,33798,33730,33779,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,33749,33786,33735,33745,33770,33811,
+33731,33772,33774,33732,33787,33751,33762,33819,33755,33790,34520,34530,34534,
+34515,34531,34522,34538,34525,34539,34524,34540,34537,34519,34536,34513,34888,
+34902,34901,35002,35031,35001,35000,35008,35006,34998,35004,34999,35005,34994,
+35073,35017,35221,35224,35223,35293,35290,35291,35406,35405,35385,35417,35392,
+35415,35416,35396,35397,35410,35400,35409,35402,35404,35407,35935,35969,35968,
+36026,36030,36016,36025,36021,36228,36224,36233,36312,36307,36301,36295,36310,
+36316,36303,36309,36313,36296,36311,36293,36591,36599,36602,36601,36582,36590,
+36581,36597,36583,36584,36598,36587,36593,36588,36596,36585,36909,36916,36911,
+37126,37164,37124,37119,37116,37128,37113,37115,37121,37120,37127,37125,37123,
+37217,37220,37215,37218,37216,37377,37386,37413,37379,37402,37414,37391,37388,
+37376,37394,37375,37373,37382,37380,37415,37378,37404,37412,37401,37399,37381,
+37398,38267,38285,38284,38288,38535,38526,38536,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,38537,38531,38528,38594,38600,38595,
+38641,38640,38764,38768,38766,38919,39081,39147,40166,40697,20099,20100,20150,
+20669,20671,20678,20654,20676,20682,20660,20680,20674,20656,20673,20666,20657,
+20683,20681,20662,20664,20951,21114,21112,21115,21116,21955,21979,21964,21968,
+21963,21962,21981,21952,21972,21956,21993,21951,21970,21901,21967,21973,21986,
+21974,21960,22002,21965,21977,21954,22292,22611,22632,22628,22607,22605,22601,
+22639,22613,22606,22621,22617,22629,22619,22589,22627,22641,22780,23239,23236,
+23243,23226,23224,23217,23221,23216,23231,23240,23227,23238,23223,23232,23242,
+23220,23222,23245,23225,23184,23510,23512,23513,23583,23603,23921,23907,23882,
+23909,23922,23916,23902,23912,23911,23906,24048,24143,24142,24138,24141,24139,
+24261,24268,24262,24267,24263,24384,24495,24493,24823,24905,24906,24875,24901,
+24886,24882,24878,24902,24879,24911,24873,24896,25120,37224,25123,25125,25124,
+25541,25585,25579,25616,25618,25609,25632,25636,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,25651,25667,25631,25621,25624,25657,
+25655,25634,25635,25612,25638,25648,25640,25665,25653,25647,25610,25626,25664,
+25637,25639,25611,25575,25627,25646,25633,25614,25967,26002,26067,26246,26252,
+26261,26256,26251,26250,26265,26260,26232,26400,26982,26975,26936,26958,26978,
+26993,26943,26949,26986,26937,26946,26967,26969,27002,26952,26953,26933,26988,
+26931,26941,26981,26864,27000,26932,26985,26944,26991,26948,26998,26968,26945,
+26996,26956,26939,26955,26935,26972,26959,26961,26930,26962,26927,27003,26940,
+27462,27461,27459,27458,27464,27457,27547,64013,27643,27644,27641,27639,27640,
+28315,28374,28360,28303,28352,28319,28307,28308,28320,28337,28345,28358,28370,
+28349,28353,28318,28361,28343,28336,28365,28326,28367,28338,28350,28355,28380,
+28376,28313,28306,28302,28301,28324,28321,28351,28339,28368,28362,28311,28334,
+28323,28999,29012,29010,29027,29024,28993,29021,29026,29042,29048,29034,29025,
+28994,29016,28995,29003,29040,29023,29008,29011,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,28996,29005,29018,29263,29325,29324,
+29329,29328,29326,29500,29506,29499,29498,29504,29514,29513,29764,29770,29771,
+29778,29777,29783,29760,29775,29776,29774,29762,29766,29773,29780,29921,29951,
+29950,29949,29981,30073,30071,27011,30191,30223,30211,30199,30206,30204,30201,
+30200,30224,30203,30198,30189,30197,30205,30361,30389,30429,30549,30559,30560,
+30546,30550,30554,30569,30567,30548,30553,30573,30688,30855,30874,30868,30863,
+30852,30869,30853,30854,30881,30851,30841,30873,30848,30870,30843,31100,31106,
+31101,31097,31249,31256,31257,31250,31255,31253,31266,31251,31259,31248,31395,
+31394,31390,31467,31590,31588,31597,31604,31593,31602,31589,31603,31601,31600,
+31585,31608,31606,31587,31922,31924,31919,32136,32134,32128,32141,32127,32133,
+32122,32142,32123,32131,32124,32140,32148,32132,32125,32146,32621,32619,32615,
+32616,32620,32678,32677,32679,32731,32732,32801,33124,33120,33143,33116,33129,
+33115,33122,33138,26401,33118,33142,33127,33135,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,33092,33121,33309,33353,33348,33344,
+33346,33349,34033,33855,33878,33910,33913,33935,33933,33893,33873,33856,33926,
+33895,33840,33869,33917,33882,33881,33908,33907,33885,34055,33886,33847,33850,
+33844,33914,33859,33912,33842,33861,33833,33753,33867,33839,33858,33837,33887,
+33904,33849,33870,33868,33874,33903,33989,33934,33851,33863,33846,33843,33896,
+33918,33860,33835,33888,33876,33902,33872,34571,34564,34551,34572,34554,34518,
+34549,34637,34552,34574,34569,34561,34550,34573,34565,35030,35019,35021,35022,
+35038,35035,35034,35020,35024,35205,35227,35295,35301,35300,35297,35296,35298,
+35292,35302,35446,35462,35455,35425,35391,35447,35458,35460,35445,35459,35457,
+35444,35450,35900,35915,35914,35941,35940,35942,35974,35972,35973,36044,36200,
+36201,36241,36236,36238,36239,36237,36243,36244,36240,36242,36336,36320,36332,
+36337,36334,36304,36329,36323,36322,36327,36338,36331,36340,36614,36607,36609,
+36608,36613,36615,36616,36610,36619,36946,36927,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,36932,36937,36925,37136,37133,37135,
+37137,37142,37140,37131,37134,37230,37231,37448,37458,37424,37434,37478,37427,
+37477,37470,37507,37422,37450,37446,37485,37484,37455,37472,37479,37487,37430,
+37473,37488,37425,37460,37475,37456,37490,37454,37459,37452,37462,37426,38303,
+38300,38302,38299,38546,38547,38545,38551,38606,38650,38653,38648,38645,38771,
+38775,38776,38770,38927,38925,38926,39084,39158,39161,39343,39346,39344,39349,
+39597,39595,39771,40170,40173,40167,40576,40701,20710,20692,20695,20712,20723,
+20699,20714,20701,20708,20691,20716,20720,20719,20707,20704,20952,21120,21121,
+21225,21227,21296,21420,22055,22037,22028,22034,22012,22031,22044,22017,22035,
+22018,22010,22045,22020,22015,22009,22665,22652,22672,22680,22662,22657,22655,
+22644,22667,22650,22663,22673,22670,22646,22658,22664,22651,22676,22671,22782,
+22891,23260,23278,23269,23253,23274,23258,23277,23275,23283,23266,23264,23259,
+23276,23262,23261,23257,23272,23263,23415,23520,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,23523,23651,23938,23936,23933,23942,
+23930,23937,23927,23946,23945,23944,23934,23932,23949,23929,23935,24152,24153,
+24147,24280,24273,24279,24270,24284,24277,24281,24274,24276,24388,24387,24431,
+24502,24876,24872,24897,24926,24945,24947,24914,24915,24946,24940,24960,24948,
+24916,24954,24923,24933,24891,24938,24929,24918,25129,25127,25131,25643,25677,
+25691,25693,25716,25718,25714,25715,25725,25717,25702,25766,25678,25730,25694,
+25692,25675,25683,25696,25680,25727,25663,25708,25707,25689,25701,25719,25971,
+26016,26273,26272,26271,26373,26372,26402,27057,27062,27081,27040,27086,27030,
+27056,27052,27068,27025,27033,27022,27047,27021,27049,27070,27055,27071,27076,
+27069,27044,27092,27065,27082,27034,27087,27059,27027,27050,27041,27038,27097,
+27031,27024,27074,27061,27045,27078,27466,27469,27467,27550,27551,27552,27587,
+27588,27646,28366,28405,28401,28419,28453,28408,28471,28411,28462,28425,28494,
+28441,28442,28455,28440,28475,28434,28397,28426,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,28470,28531,28409,28398,28461,28480,
+28464,28476,28469,28395,28423,28430,28483,28421,28413,28406,28473,28444,28412,
+28474,28447,28429,28446,28424,28449,29063,29072,29065,29056,29061,29058,29071,
+29051,29062,29057,29079,29252,29267,29335,29333,29331,29507,29517,29521,29516,
+29794,29811,29809,29813,29810,29799,29806,29952,29954,29955,30077,30096,30230,
+30216,30220,30229,30225,30218,30228,30392,30593,30588,30597,30594,30574,30592,
+30575,30590,30595,30898,30890,30900,30893,30888,30846,30891,30878,30885,30880,
+30892,30882,30884,31128,31114,31115,31126,31125,31124,31123,31127,31112,31122,
+31120,31275,31306,31280,31279,31272,31270,31400,31403,31404,31470,31624,31644,
+31626,31633,31632,31638,31629,31628,31643,31630,31621,31640,21124,31641,31652,
+31618,31931,31935,31932,31930,32167,32183,32194,32163,32170,32193,32192,32197,
+32157,32206,32196,32198,32203,32204,32175,32185,32150,32188,32159,32166,32174,
+32169,32161,32201,32627,32738,32739,32741,32734,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,32804,32861,32860,33161,33158,33155,
+33159,33165,33164,33163,33301,33943,33956,33953,33951,33978,33998,33986,33964,
+33966,33963,33977,33972,33985,33997,33962,33946,33969,34000,33949,33959,33979,
+33954,33940,33991,33996,33947,33961,33967,33960,34006,33944,33974,33999,33952,
+34007,34004,34002,34011,33968,33937,34401,34611,34595,34600,34667,34624,34606,
+34590,34593,34585,34587,34627,34604,34625,34622,34630,34592,34610,34602,34605,
+34620,34578,34618,34609,34613,34626,34598,34599,34616,34596,34586,34608,34577,
+35063,35047,35057,35058,35066,35070,35054,35068,35062,35067,35056,35052,35051,
+35229,35233,35231,35230,35305,35307,35304,35499,35481,35467,35474,35471,35478,
+35901,35944,35945,36053,36047,36055,36246,36361,36354,36351,36365,36349,36362,
+36355,36359,36358,36357,36350,36352,36356,36624,36625,36622,36621,37155,37148,
+37152,37154,37151,37149,37146,37156,37153,37147,37242,37234,37241,37235,37541,
+37540,37494,37531,37498,37536,37524,37546,37517,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,37542,37530,37547,37497,37527,37503,
+37539,37614,37518,37506,37525,37538,37501,37512,37537,37514,37510,37516,37529,
+37543,37502,37511,37545,37533,37515,37421,38558,38561,38655,38744,38781,38778,
+38782,38787,38784,38786,38779,38788,38785,38783,38862,38861,38934,39085,39086,
+39170,39168,39175,39325,39324,39363,39353,39355,39354,39362,39357,39367,39601,
+39651,39655,39742,39743,39776,39777,39775,40177,40178,40181,40615,20735,20739,
+20784,20728,20742,20743,20726,20734,20747,20748,20733,20746,21131,21132,21233,
+21231,22088,22082,22092,22069,22081,22090,22089,22086,22104,22106,22080,22067,
+22077,22060,22078,22072,22058,22074,22298,22699,22685,22705,22688,22691,22703,
+22700,22693,22689,22783,23295,23284,23293,23287,23286,23299,23288,23298,23289,
+23297,23303,23301,23311,23655,23961,23959,23967,23954,23970,23955,23957,23968,
+23964,23969,23962,23966,24169,24157,24160,24156,32243,24283,24286,24289,24393,
+24498,24971,24963,24953,25009,25008,24994,24969,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,24987,24979,25007,25005,24991,24978,
+25002,24993,24973,24934,25011,25133,25710,25712,25750,25760,25733,25751,25756,
+25743,25739,25738,25740,25763,25759,25704,25777,25752,25974,25978,25977,25979,
+26034,26035,26293,26288,26281,26290,26295,26282,26287,27136,27142,27159,27109,
+27128,27157,27121,27108,27168,27135,27116,27106,27163,27165,27134,27175,27122,
+27118,27156,27127,27111,27200,27144,27110,27131,27149,27132,27115,27145,27140,
+27160,27173,27151,27126,27174,27143,27124,27158,27473,27557,27555,27554,27558,
+27649,27648,27647,27650,28481,28454,28542,28551,28614,28562,28557,28553,28556,
+28514,28495,28549,28506,28566,28534,28524,28546,28501,28530,28498,28496,28503,
+28564,28563,28509,28416,28513,28523,28541,28519,28560,28499,28555,28521,28543,
+28565,28515,28535,28522,28539,29106,29103,29083,29104,29088,29082,29097,29109,
+29085,29093,29086,29092,29089,29098,29084,29095,29107,29336,29338,29528,29522,
+29534,29535,29536,29533,29531,29537,29530,29529,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,29538,29831,29833,29834,29830,29825,
+29821,29829,29832,29820,29817,29960,29959,30078,30245,30238,30233,30237,30236,
+30243,30234,30248,30235,30364,30365,30366,30363,30605,30607,30601,30600,30925,
+30907,30927,30924,30929,30926,30932,30920,30915,30916,30921,31130,31137,31136,
+31132,31138,31131,27510,31289,31410,31412,31411,31671,31691,31678,31660,31694,
+31663,31673,31690,31669,31941,31944,31948,31947,32247,32219,32234,32231,32215,
+32225,32259,32250,32230,32246,32241,32240,32238,32223,32630,32684,32688,32685,
+32749,32747,32746,32748,32742,32744,32868,32871,33187,33183,33182,33173,33186,
+33177,33175,33302,33359,33363,33362,33360,33358,33361,34084,34107,34063,34048,
+34089,34062,34057,34061,34079,34058,34087,34076,34043,34091,34042,34056,34060,
+34036,34090,34034,34069,34039,34027,34035,34044,34066,34026,34025,34070,34046,
+34088,34077,34094,34050,34045,34078,34038,34097,34086,34023,34024,34032,34031,
+34041,34072,34080,34096,34059,34073,34095,34402,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,34646,34659,34660,34679,34785,34675,
+34648,34644,34651,34642,34657,34650,34641,34654,34669,34666,34640,34638,34655,
+34653,34671,34668,34682,34670,34652,34661,34639,34683,34677,34658,34663,34665,
+34906,35077,35084,35092,35083,35095,35096,35097,35078,35094,35089,35086,35081,
+35234,35236,35235,35309,35312,35308,35535,35526,35512,35539,35537,35540,35541,
+35515,35543,35518,35520,35525,35544,35523,35514,35517,35545,35902,35917,35983,
+36069,36063,36057,36072,36058,36061,36071,36256,36252,36257,36251,36384,36387,
+36389,36388,36398,36373,36379,36374,36369,36377,36390,36391,36372,36370,36376,
+36371,36380,36375,36378,36652,36644,36632,36634,36640,36643,36630,36631,36979,
+36976,36975,36967,36971,37167,37163,37161,37162,37170,37158,37166,37253,37254,
+37258,37249,37250,37252,37248,37584,37571,37572,37568,37593,37558,37583,37617,
+37599,37592,37609,37591,37597,37580,37615,37570,37608,37578,37576,37582,37606,
+37581,37589,37577,37600,37598,37607,37585,37587,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,37557,37601,37574,37556,38268,38316,
+38315,38318,38320,38564,38562,38611,38661,38664,38658,38746,38794,38798,38792,
+38864,38863,38942,38941,38950,38953,38952,38944,38939,38951,39090,39176,39162,
+39185,39188,39190,39191,39189,39388,39373,39375,39379,39380,39374,39369,39382,
+39384,39371,39383,39372,39603,39660,39659,39667,39666,39665,39750,39747,39783,
+39796,39793,39782,39798,39797,39792,39784,39780,39788,40188,40186,40189,40191,
+40183,40199,40192,40185,40187,40200,40197,40196,40579,40659,40719,40720,20764,
+20755,20759,20762,20753,20958,21300,21473,22128,22112,22126,22131,22118,22115,
+22125,22130,22110,22135,22300,22299,22728,22717,22729,22719,22714,22722,22716,
+22726,23319,23321,23323,23329,23316,23315,23312,23318,23336,23322,23328,23326,
+23535,23980,23985,23977,23975,23989,23984,23982,23978,23976,23986,23981,23983,
+23988,24167,24168,24166,24175,24297,24295,24294,24296,24293,24395,24508,24989,
+25000,24982,25029,25012,25030,25025,25036,25018,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,25023,25016,24972,25815,25814,25808,
+25807,25801,25789,25737,25795,25819,25843,25817,25907,25983,25980,26018,26312,
+26302,26304,26314,26315,26319,26301,26299,26298,26316,26403,27188,27238,27209,
+27239,27186,27240,27198,27229,27245,27254,27227,27217,27176,27226,27195,27199,
+27201,27242,27236,27216,27215,27220,27247,27241,27232,27196,27230,27222,27221,
+27213,27214,27206,27477,27476,27478,27559,27562,27563,27592,27591,27652,27651,
+27654,28589,28619,28579,28615,28604,28622,28616,28510,28612,28605,28574,28618,
+28584,28676,28581,28590,28602,28588,28586,28623,28607,28600,28578,28617,28587,
+28621,28591,28594,28592,29125,29122,29119,29112,29142,29120,29121,29131,29140,
+29130,29127,29135,29117,29144,29116,29126,29146,29147,29341,29342,29545,29542,
+29543,29548,29541,29547,29546,29823,29850,29856,29844,29842,29845,29857,29963,
+30080,30255,30253,30257,30269,30259,30268,30261,30258,30256,30395,30438,30618,
+30621,30625,30620,30619,30626,30627,30613,30617,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,30615,30941,30953,30949,30954,30942,
+30947,30939,30945,30946,30957,30943,30944,31140,31300,31304,31303,31414,31416,
+31413,31409,31415,31710,31715,31719,31709,31701,31717,31706,31720,31737,31700,
+31722,31714,31708,31723,31704,31711,31954,31956,31959,31952,31953,32274,32289,
+32279,32268,32287,32288,32275,32270,32284,32277,32282,32290,32267,32271,32278,
+32269,32276,32293,32292,32579,32635,32636,32634,32689,32751,32810,32809,32876,
+33201,33190,33198,33209,33205,33195,33200,33196,33204,33202,33207,33191,33266,
+33365,33366,33367,34134,34117,34155,34125,34131,34145,34136,34112,34118,34148,
+34113,34146,34116,34129,34119,34147,34110,34139,34161,34126,34158,34165,34133,
+34151,34144,34188,34150,34141,34132,34149,34156,34403,34405,34404,34715,34703,
+34711,34707,34706,34696,34689,34710,34712,34681,34695,34723,34693,34704,34705,
+34717,34692,34708,34716,34714,34697,35102,35110,35120,35117,35118,35111,35121,
+35106,35113,35107,35119,35116,35103,35313,35552,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,35554,35570,35572,35573,35549,35604,
+35556,35551,35568,35528,35550,35553,35560,35583,35567,35579,35985,35986,35984,
+36085,36078,36081,36080,36083,36204,36206,36261,36263,36403,36414,36408,36416,
+36421,36406,36412,36413,36417,36400,36415,36541,36662,36654,36661,36658,36665,
+36663,36660,36982,36985,36987,36998,37114,37171,37173,37174,37267,37264,37265,
+37261,37263,37671,37662,37640,37663,37638,37647,37754,37688,37692,37659,37667,
+37650,37633,37702,37677,37646,37645,37579,37661,37626,37669,37651,37625,37623,
+37684,37634,37668,37631,37673,37689,37685,37674,37652,37644,37643,37630,37641,
+37632,37627,37654,38332,38349,38334,38329,38330,38326,38335,38325,38333,38569,
+38612,38667,38674,38672,38809,38807,38804,38896,38904,38965,38959,38962,39204,
+39199,39207,39209,39326,39406,39404,39397,39396,39408,39395,39402,39401,39399,
+39609,39615,39604,39611,39670,39674,39673,39671,39731,39808,39813,39815,39804,
+39806,39803,39810,39827,39826,39824,39802,39829,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,39805,39816,40229,40215,40224,40222,
+40212,40233,40221,40216,40226,40208,40217,40223,40584,40582,40583,40622,40621,
+40661,40662,40698,40722,40765,20774,20773,20770,20772,20768,20777,21236,22163,
+22156,22157,22150,22148,22147,22142,22146,22143,22145,22742,22740,22735,22738,
+23341,23333,23346,23331,23340,23335,23334,23343,23342,23419,23537,23538,23991,
+24172,24170,24510,24507,25027,25013,25020,25063,25056,25061,25060,25064,25054,
+25839,25833,25827,25835,25828,25832,25985,25984,26038,26074,26322,27277,27286,
+27265,27301,27273,27295,27291,27297,27294,27271,27283,27278,27285,27267,27304,
+27300,27281,27263,27302,27290,27269,27276,27282,27483,27565,27657,28620,28585,
+28660,28628,28643,28636,28653,28647,28646,28638,28658,28637,28642,28648,29153,
+29169,29160,29170,29156,29168,29154,29555,29550,29551,29847,29874,29867,29840,
+29866,29869,29873,29861,29871,29968,29969,29970,29967,30084,30275,30280,30281,
+30279,30372,30441,30645,30635,30642,30647,30646,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,30644,30641,30632,30704,30963,30973,
+30978,30971,30972,30962,30981,30969,30974,30980,31147,31144,31324,31323,31318,
+31320,31316,31322,31422,31424,31425,31749,31759,31730,31744,31743,31739,31758,
+31732,31755,31731,31746,31753,31747,31745,31736,31741,31750,31728,31729,31760,
+31754,31976,32301,32316,32322,32307,38984,32312,32298,32329,32320,32327,32297,
+32332,32304,32315,32310,32324,32314,32581,32639,32638,32637,32756,32754,32812,
+33211,33220,33228,33226,33221,33223,33212,33257,33371,33370,33372,34179,34176,
+34191,34215,34197,34208,34187,34211,34171,34212,34202,34206,34167,34172,34185,
+34209,34170,34168,34135,34190,34198,34182,34189,34201,34205,34177,34210,34178,
+34184,34181,34169,34166,34200,34192,34207,34408,34750,34730,34733,34757,34736,
+34732,34745,34741,34748,34734,34761,34755,34754,34764,34743,34735,34756,34762,
+34740,34742,34751,34744,34749,34782,34738,35125,35123,35132,35134,35137,35154,
+35127,35138,35245,35247,35246,35314,35315,35614,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,35608,35606,35601,35589,35595,35618,
+35599,35602,35605,35591,35597,35592,35590,35612,35603,35610,35919,35952,35954,
+35953,35951,35989,35988,36089,36207,36430,36429,36435,36432,36428,36423,36675,
+36672,36997,36990,37176,37274,37282,37275,37273,37279,37281,37277,37280,37793,
+37763,37807,37732,37718,37703,37756,37720,37724,37750,37705,37712,37713,37728,
+37741,37775,37708,37738,37753,37719,37717,37714,37711,37745,37751,37755,37729,
+37726,37731,37735,37760,37710,37721,38343,38336,38345,38339,38341,38327,38574,
+38576,38572,38688,38687,38680,38685,38681,38810,38817,38812,38814,38813,38869,
+38868,38897,38977,38980,38986,38985,38981,38979,39205,39211,39212,39210,39219,
+39218,39215,39213,39217,39216,39320,39331,39329,39426,39418,39412,39415,39417,
+39416,39414,39419,39421,39422,39420,39427,39614,39678,39677,39681,39676,39752,
+39834,39848,39838,39835,39846,39841,39845,39844,39814,39842,39840,39855,40243,
+40257,40295,40246,40238,40239,40241,40248,40240,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,40261,40258,40259,40254,40247,40256,
+40253,32757,40237,40586,40585,40589,40624,40648,40666,40699,40703,40740,40739,
+40738,40788,40864,20785,20781,20782,22168,22172,22167,22170,22173,22169,22896,
+23356,23657,23658,24000,24173,24174,25048,25055,25069,25070,25073,25066,25072,
+25067,25046,25065,25855,25860,25853,25848,25857,25859,25852,26004,26075,26330,
+26331,26328,27333,27321,27325,27361,27334,27322,27318,27319,27335,27316,27309,
+27486,27593,27659,28679,28684,28685,28673,28677,28692,28686,28671,28672,28667,
+28710,28668,28663,28682,29185,29183,29177,29187,29181,29558,29880,29888,29877,
+29889,29886,29878,29883,29890,29972,29971,30300,30308,30297,30288,30291,30295,
+30298,30374,30397,30444,30658,30650,30975,30988,30995,30996,30985,30992,30994,
+30993,31149,31148,31327,31772,31785,31769,31776,31775,31789,31773,31782,31784,
+31778,31781,31792,32348,32336,32342,32355,32344,32354,32351,32337,32352,32343,
+32339,32693,32691,32759,32760,32885,33233,33234,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,33232,33375,33374,34228,34246,34240,
+34243,34242,34227,34229,34237,34247,34244,34239,34251,34254,34248,34245,34225,
+34230,34258,34340,34232,34231,34238,34409,34791,34790,34786,34779,34795,34794,
+34789,34783,34803,34788,34772,34780,34771,34797,34776,34787,34724,34775,34777,
+34817,34804,34792,34781,35155,35147,35151,35148,35142,35152,35153,35145,35626,
+35623,35619,35635,35632,35637,35655,35631,35644,35646,35633,35621,35639,35622,
+35638,35630,35620,35643,35645,35642,35906,35957,35993,35992,35991,36094,36100,
+36098,36096,36444,36450,36448,36439,36438,36446,36453,36455,36443,36442,36449,
+36445,36457,36436,36678,36679,36680,36683,37160,37178,37179,37182,37288,37285,
+37287,37295,37290,37813,37772,37778,37815,37787,37789,37769,37799,37774,37802,
+37790,37798,37781,37768,37785,37791,37773,37809,37777,37810,37796,37800,37812,
+37795,37797,38354,38355,38353,38579,38615,38618,24002,38623,38616,38621,38691,
+38690,38693,38828,38830,38824,38827,38820,38826,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,38818,38821,38871,38873,38870,38872,
+38906,38992,38993,38994,39096,39233,39228,39226,39439,39435,39433,39437,39428,
+39441,39434,39429,39431,39430,39616,39644,39688,39684,39685,39721,39733,39754,
+39756,39755,39879,39878,39875,39871,39873,39861,39864,39891,39862,39876,39865,
+39869,40284,40275,40271,40266,40283,40267,40281,40278,40268,40279,40274,40276,
+40287,40280,40282,40590,40588,40671,40705,40704,40726,40741,40747,40746,40745,
+40744,40780,40789,20788,20789,21142,21239,21428,22187,22189,22182,22183,22186,
+22188,22746,22749,22747,22802,23357,23358,23359,24003,24176,24511,25083,25863,
+25872,25869,25865,25868,25870,25988,26078,26077,26334,27367,27360,27340,27345,
+27353,27339,27359,27356,27344,27371,27343,27341,27358,27488,27568,27660,28697,
+28711,28704,28694,28715,28705,28706,28707,28713,28695,28708,28700,28714,29196,
+29194,29191,29186,29189,29349,29350,29348,29347,29345,29899,29893,29879,29891,
+29974,30304,30665,30666,30660,30705,31005,31003,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,31009,31004,30999,31006,31152,31335,
+31336,31795,31804,31801,31788,31803,31980,31978,32374,32373,32376,32368,32375,
+32367,32378,32370,32372,32360,32587,32586,32643,32646,32695,32765,32766,32888,
+33239,33237,33380,33377,33379,34283,34289,34285,34265,34273,34280,34266,34263,
+34284,34290,34296,34264,34271,34275,34268,34257,34288,34278,34287,34270,34274,
+34816,34810,34819,34806,34807,34825,34828,34827,34822,34812,34824,34815,34826,
+34818,35170,35162,35163,35159,35169,35164,35160,35165,35161,35208,35255,35254,
+35318,35664,35656,35658,35648,35667,35670,35668,35659,35669,35665,35650,35666,
+35671,35907,35959,35958,35994,36102,36103,36105,36268,36266,36269,36267,36461,
+36472,36467,36458,36463,36475,36546,36690,36689,36687,36688,36691,36788,37184,
+37183,37296,37293,37854,37831,37839,37826,37850,37840,37881,37868,37836,37849,
+37801,37862,37834,37844,37870,37859,37845,37828,37838,37824,37842,37863,38269,
+38362,38363,38625,38697,38699,38700,38696,38694,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,38835,38839,38838,38877,38878,38879,
+39004,39001,39005,38999,39103,39101,39099,39102,39240,39239,39235,39334,39335,
+39450,39445,39461,39453,39460,39451,39458,39456,39463,39459,39454,39452,39444,
+39618,39691,39690,39694,39692,39735,39914,39915,39904,39902,39908,39910,39906,
+39920,39892,39895,39916,39900,39897,39909,39893,39905,39898,40311,40321,40330,
+40324,40328,40305,40320,40312,40326,40331,40332,40317,40299,40308,40309,40304,
+40297,40325,40307,40315,40322,40303,40313,40319,40327,40296,40596,40593,40640,
+40700,40749,40768,40769,40781,40790,40791,40792,21303,22194,22197,22195,22755,
+23365,24006,24007,24302,24303,24512,24513,25081,25879,25878,25877,25875,26079,
+26344,26339,26340,27379,27376,27370,27368,27385,27377,27374,27375,28732,28725,
+28719,28727,28724,28721,28738,28728,28735,28730,28729,28736,28731,28723,28737,
+29203,29204,29352,29565,29564,29882,30379,30378,30398,30445,30668,30670,30671,
+30669,30706,31013,31011,31015,31016,31012,31017,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,31154,31342,31340,31341,31479,31817,
+31816,31818,31815,31813,31982,32379,32382,32385,32384,32698,32767,32889,33243,
+33241,33291,33384,33385,34338,34303,34305,34302,34331,34304,34294,34308,34313,
+34309,34316,34301,34841,34832,34833,34839,34835,34838,35171,35174,35257,35319,
+35680,35690,35677,35688,35683,35685,35687,35693,36270,36486,36488,36484,36697,
+36694,36695,36693,36696,36698,37005,37187,37185,37303,37301,37298,37299,37899,
+37907,37883,37920,37903,37908,37886,37909,37904,37928,37913,37901,37877,37888,
+37879,37895,37902,37910,37906,37882,37897,37880,37898,37887,37884,37900,37878,
+37905,37894,38366,38368,38367,38702,38703,38841,38843,38909,38910,39008,39010,
+39011,39007,39105,39106,39248,39246,39257,39244,39243,39251,39474,39476,39473,
+39468,39466,39478,39465,39470,39480,39469,39623,39626,39622,39696,39698,39697,
+39947,39944,39927,39941,39954,39928,40000,39943,39950,39942,39959,39956,39945,
+40351,40345,40356,40349,40338,40344,40336,40347,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,40352,40340,40348,40362,40343,40353,
+40346,40354,40360,40350,40355,40383,40361,40342,40358,40359,40601,40603,40602,
+40677,40676,40679,40678,40752,40750,40795,40800,40798,40797,40793,40849,20794,
+20793,21144,21143,22211,22205,22206,23368,23367,24011,24015,24305,25085,25883,
+27394,27388,27395,27384,27392,28739,28740,28746,28744,28745,28741,28742,29213,
+29210,29209,29566,29975,30314,30672,31021,31025,31023,31828,31827,31986,32394,
+32391,32392,32395,32390,32397,32589,32699,32816,33245,34328,34346,34342,34335,
+34339,34332,34329,34343,34350,34337,34336,34345,34334,34341,34857,34845,34843,
+34848,34852,34844,34859,34890,35181,35177,35182,35179,35322,35705,35704,35653,
+35706,35707,36112,36116,36271,36494,36492,36702,36699,36701,37190,37188,37189,
+37305,37951,37947,37942,37929,37949,37948,37936,37945,37930,37943,37932,37952,
+37937,38373,38372,38371,38709,38714,38847,38881,39012,39113,39110,39104,39256,
+39254,39481,39485,39494,39492,39490,39489,39482,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,39487,39629,39701,39703,39704,39702,
+39738,39762,39979,39965,39964,39980,39971,39976,39977,39972,39969,40375,40374,
+40380,40385,40391,40394,40399,40382,40389,40387,40379,40373,40398,40377,40378,
+40364,40392,40369,40365,40396,40371,40397,40370,40570,40604,40683,40686,40685,
+40731,40728,40730,40753,40782,40805,40804,40850,20153,22214,22213,22219,22897,
+23371,23372,24021,24017,24306,25889,25888,25894,25890,27403,27400,27401,27661,
+28757,28758,28759,28754,29214,29215,29353,29567,29912,29909,29913,29911,30317,
+30381,31029,31156,31344,31345,31831,31836,31833,31835,31834,31988,31985,32401,
+32591,32647,33246,33387,34356,34357,34355,34348,34354,34358,34860,34856,34854,
+34858,34853,35185,35263,35262,35323,35710,35716,35714,35718,35717,35711,36117,
+36501,36500,36506,36498,36496,36502,36503,36704,36706,37191,37964,37968,37962,
+37963,37967,37959,37957,37960,37961,37958,38719,38883,39018,39017,39115,39252,
+39259,39502,39507,39508,39500,39503,39496,39498,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,39497,39506,39504,39632,39705,39723,
+39739,39766,39765,40006,40008,39999,40004,39993,39987,40001,39996,39991,39988,
+39986,39997,39990,40411,40402,40414,40410,40395,40400,40412,40401,40415,40425,
+40409,40408,40406,40437,40405,40413,40630,40688,40757,40755,40754,40770,40811,
+40853,40866,20797,21145,22760,22759,22898,23373,24024,34863,24399,25089,25091,
+25092,25897,25893,26006,26347,27409,27410,27407,27594,28763,28762,29218,29570,
+29569,29571,30320,30676,31847,31846,32405,33388,34362,34368,34361,34364,34353,
+34363,34366,34864,34866,34862,34867,35190,35188,35187,35326,35724,35726,35723,
+35720,35909,36121,36504,36708,36707,37308,37986,37973,37981,37975,37982,38852,
+38853,38912,39510,39513,39710,39711,39712,40018,40024,40016,40010,40013,40011,
+40021,40025,40012,40014,40443,40439,40431,40419,40427,40440,40420,40438,40417,
+40430,40422,40434,40432,40418,40428,40436,40435,40424,40429,40642,40656,40690,
+40691,40710,40732,40760,40759,40758,40771,40783,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,40817,40816,40814,40815,22227,22221,
+23374,23661,25901,26349,26350,27411,28767,28769,28765,28768,29219,29915,29925,
+30677,31032,31159,31158,31850,32407,32649,33389,34371,34872,34871,34869,34891,
+35732,35733,36510,36511,36512,36509,37310,37309,37314,37995,37992,37993,38629,
+38726,38723,38727,38855,38885,39518,39637,39769,40035,40039,40038,40034,40030,
+40032,40450,40446,40455,40451,40454,40453,40448,40449,40457,40447,40445,40452,
+40608,40734,40774,40820,40821,40822,22228,25902,26040,27416,27417,27415,27418,
+28770,29222,29354,30680,30681,31033,31849,31851,31990,32410,32408,32411,32409,
+33248,33249,34374,34375,34376,35193,35194,35196,35195,35327,35736,35737,36517,
+36516,36515,37998,37997,37999,38001,38003,38729,39026,39263,40040,40046,40045,
+40459,40461,40464,40463,40466,40465,40609,40693,40713,40775,40824,40827,40826,
+40825,22302,28774,31855,34876,36274,36518,37315,38004,38008,38006,38005,39520,
+40052,40051,40049,40053,40468,40467,40694,40714,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,40868,28776,28773,31991,34410,34878,
+34877,34879,35742,35996,36521,36553,38731,39027,39028,39116,39265,39339,39524,
+39526,39527,39716,40469,40471,40776,25095,27422,29223,34380,36520,38018,38016,
+38017,39529,39528,39726,40473,29225,34379,35743,38019,40057,40631,30325,39531,
+40058,40477,28777,28778,40612,40830,40777,40856,
+};
+
+static const struct dbcs_index big5_decmap[256] = {
+{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__big5_decmap+0,64,254},{
+__big5_decmap+191,64,254},{__big5_decmap+382,64,191},{__big5_decmap+510,64,254
+},{__big5_decmap+701,64,254},{__big5_decmap+892,64,254},{__big5_decmap+1083,
+64,254},{__big5_decmap+1274,64,254},{__big5_decmap+1465,64,254},{__big5_decmap
++1656,64,254},{__big5_decmap+1847,64,254},{__big5_decmap+2038,64,254},{
+__big5_decmap+2229,64,254},{__big5_decmap+2420,64,254},{__big5_decmap+2611,64,
+254},{__big5_decmap+2802,64,254},{__big5_decmap+2993,64,254},{__big5_decmap+
+3184,64,254},{__big5_decmap+3375,64,254},{__big5_decmap+3566,64,254},{
+__big5_decmap+3757,64,254},{__big5_decmap+3948,64,254},{__big5_decmap+4139,64,
+254},{__big5_decmap+4330,64,254},{__big5_decmap+4521,64,254},{__big5_decmap+
+4712,64,254},{__big5_decmap+4903,64,254},{__big5_decmap+5094,64,254},{
+__big5_decmap+5285,64,254},{__big5_decmap+5476,64,254},{__big5_decmap+5667,64,
+254},{__big5_decmap+5858,64,254},{__big5_decmap+6049,64,254},{__big5_decmap+
+6240,64,254},{__big5_decmap+6431,64,254},{__big5_decmap+6622,64,254},{
+__big5_decmap+6813,64,254},{__big5_decmap+7004,64,254},{__big5_decmap+7195,64,
+252},{0,0,0},{__big5_decmap+7384,64,254},{__big5_decmap+7575,64,254},{
+__big5_decmap+7766,64,254},{__big5_decmap+7957,64,254},{__big5_decmap+8148,64,
+254},{__big5_decmap+8339,64,254},{__big5_decmap+8530,64,254},{__big5_decmap+
+8721,64,254},{__big5_decmap+8912,64,254},{__big5_decmap+9103,64,254},{
+__big5_decmap+9294,64,254},{__big5_decmap+9485,64,254},{__big5_decmap+9676,64,
+254},{__big5_decmap+9867,64,254},{__big5_decmap+10058,64,254},{__big5_decmap+
+10249,64,254},{__big5_decmap+10440,64,254},{__big5_decmap+10631,64,254},{
+__big5_decmap+10822,64,254},{__big5_decmap+11013,64,254},{__big5_decmap+11204,
+64,254},{__big5_decmap+11395,64,254},{__big5_decmap+11586,64,254},{
+__big5_decmap+11777,64,254},{__big5_decmap+11968,64,254},{__big5_decmap+12159,
+64,254},{__big5_decmap+12350,64,254},{__big5_decmap+12541,64,254},{
+__big5_decmap+12732,64,254},{__big5_decmap+12923,64,254},{__big5_decmap+13114,
+64,254},{__big5_decmap+13305,64,254},{__big5_decmap+13496,64,254},{
+__big5_decmap+13687,64,254},{__big5_decmap+13878,64,254},{__big5_decmap+14069,
+64,254},{__big5_decmap+14260,64,254},{__big5_decmap+14451,64,254},{
+__big5_decmap+14642,64,254},{__big5_decmap+14833,64,254},{__big5_decmap+15024,
+64,254},{__big5_decmap+15215,64,254},{__big5_decmap+15406,64,254},{
+__big5_decmap+15597,64,254},{__big5_decmap+15788,64,254},{__big5_decmap+15979,
+64,254},{__big5_decmap+16170,64,254},{__big5_decmap+16361,64,254},{
+__big5_decmap+16552,64,213},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
+};
+
+static const DBCHAR __big5_encmap[21764] = {
+41542,41543,N,41540,N,41393,N,N,N,N,N,N,N,N,41560,41427,N,N,N,N,N,41296,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41425,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41426,41918,N,41916,41917,41919,
+N,41413,N,N,N,N,N,N,N,N,N,N,N,41915,41796,41797,41798,41799,41800,41801,41802,
+41803,41804,41805,41806,41807,41808,41809,41810,41811,41812,N,41813,41814,
+41815,41816,41817,41818,41819,N,N,N,N,N,N,N,41820,41821,41822,41823,41824,
+41825,41826,41827,41828,41829,41830,41831,41832,41833,41834,41835,41836,N,
+41837,41838,41839,41840,41841,41842,41843,51123,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,51121,51122,51124,51125,51126,51127,51128,51129,51130,N,N,N,N,N,N,51131,
+51132,51133,51134,51135,51136,51137,51138,51139,51140,51141,51142,51143,51144,
+51145,51146,51147,51148,51149,51151,51152,51153,51154,51155,51156,51157,51158,
+51159,51160,51161,51162,51163,51164,51165,51166,51167,51168,51169,51170,51171,
+51172,51173,51174,51175,51176,N,51150,41302,41304,N,N,N,41381,41382,N,N,41383,
+41384,N,N,N,N,41285,N,N,41292,41291,N,N,N,N,N,N,N,N,N,N,N,41388,N,N,41387,N,N,
+N,N,N,41392,N,N,41410,41546,N,41409,N,N,N,41547,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41657,41658,
+41659,41660,41661,41662,41663,41664,41665,41666,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41462,41460,41463,41461,N,N,
+41464,41465,41467,41466,41428,N,N,N,41435,41448,41447,N,N,41469,N,41468,N,N,N,
+41444,41445,41452,N,N,41453,N,N,N,N,N,41455,41454,N,N,N,N,N,N,41443,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41436,N,N,N,N,N,N,N,N,N,N,N,N,N,41434,41437,N,
+N,N,N,41432,41433,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41446,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41449,51177,51178,51179,51180,51181,
+51182,51183,51184,51185,51186,N,N,N,N,N,N,N,N,N,N,51187,51188,51189,51190,
+51191,51192,51193,51194,51195,51196,41591,N,41592,N,N,N,N,N,N,N,N,N,41594,N,N,
+N,41595,N,N,N,41596,N,N,N,41597,N,N,N,41589,N,N,N,N,N,N,N,41588,N,N,N,N,N,N,N,
+41587,N,N,N,N,N,N,N,41586,N,N,N,N,N,N,N,41585,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,41636,N,N,N,N,N,N,N,N,N,N,N,N,N,41637,N,N,41639,N,N,N,N,N,N,N,N,41638,N,
+N,41598,41633,41635,41634,41644,41645,41646,41306,N,N,N,N,N,N,N,N,N,N,N,N,
+41570,41571,41572,41573,41574,41575,41576,41577,41584,41583,41582,41581,41580,
+41579,41578,N,N,N,N,41590,41593,N,N,N,N,N,N,N,N,N,N,41405,41404,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,41398,41397,N,N,N,N,N,N,N,N,41407,41406,N,N,N,N,N,N,N,N,
+41403,41402,N,N,N,41395,N,N,41399,41396,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+41640,41641,41643,41642,41401,41400,N,N,41459,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+41456,41458,41457,41280,41282,41283,41394,N,50852,N,N,41329,41330,41325,41326,
+41333,41334,41337,41338,41321,41322,41541,N,41317,41318,N,N,N,N,N,N,N,41385,
+41386,N,N,41667,41668,41669,41670,41671,41672,41673,41674,41675,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,50853,50854,50855,50856,50857,50858,50859,
+50860,50861,50862,50863,50864,50865,50866,50867,50868,50869,50870,50871,50872,
+50873,50874,50875,50876,50877,50878,50879,50880,50881,50882,50883,50884,50885,
+50886,50887,50888,50889,50890,50891,50892,50893,50894,50895,50896,50897,50898,
+50899,50900,50901,50902,50903,50904,50905,50906,50907,50908,50909,50910,50911,
+50912,50913,50914,50915,50916,50917,50918,50919,50920,50921,50922,50923,50924,
+50925,50926,50927,50928,50929,50930,50931,50932,50933,50934,50935,N,N,N,N,N,N,
+N,N,N,50850,50851,N,N,50936,50937,50938,50939,50940,50941,50942,51008,51009,
+51010,51011,51012,51013,51014,51015,51016,51017,51018,51019,51020,51021,51022,
+51023,51024,51025,51026,51027,51028,51029,51030,51031,51032,51033,51034,51035,
+51036,51037,51038,51039,51040,51041,51042,51043,51044,51045,51046,51047,51048,
+51049,51050,51051,51052,51053,51054,51055,51056,51057,51058,51059,51060,51061,
+51062,51063,51064,51065,51066,51067,51068,51069,51070,51105,51106,51107,51108,
+51109,51110,51111,51112,51113,51114,51115,51116,51117,51118,51119,51120,N,N,N,
+N,N,N,N,50849,41844,41845,41846,41847,41848,41849,41850,41851,41852,41853,
+41854,41889,41890,41891,41892,41893,41894,41895,41896,41897,41898,41899,41900,
+41901,41902,41903,41904,41905,41906,41907,41908,41909,41910,41911,41912,41913,
+41914,41408,41557,41558,N,N,N,N,N,N,N,N,N,N,N,N,41552,41553,41554,N,N,41556,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41559,N,N,N,
+N,N,N,N,N,N,41555,N,N,41451,41450,N,N,41551,42048,42050,N,42051,N,N,N,51525,
+42070,42068,42071,42069,51526,42147,51535,51533,42146,42145,N,N,42306,42305,
+42304,N,42307,42238,N,N,N,N,42464,42465,N,N,N,N,N,N,43203,N,N,N,N,42072,N,
+42148,51536,N,42149,51555,42730,52145,N,N,N,N,42073,42150,N,42308,51556,N,N,N,
+N,N,51520,42052,N,42075,N,51527,42076,N,N,42151,N,42309,42311,42310,N,N,42466,
+42467,N,N,43204,N,44476,42049,N,N,51521,42053,42078,42077,N,N,N,N,N,N,N,N,N,
+42468,N,N,N,N,N,N,N,N,N,43205,N,N,N,N,N,N,N,N,N,N,45230,54347,N,N,46787,56497,
+56498,N,42054,N,42153,N,N,43206,42055,51528,42079,N,N,42154,42156,51537,42157,
+42155,N,N,N,42469,N,43207,N,N,43208,43845,N,42080,42158,N,42470,42472,42471,N,
+42731,N,N,43209,43210,43846,43847,N,N,N,N,44477,N,N,56499,N,N,63190,42056,N,N,
+N,N,N,42160,42159,51538,42161,42167,N,42162,42163,51540,51539,42165,42166,N,
+42164,N,N,N,N,N,N,42314,42315,42316,42317,42313,42320,51562,N,51558,51561,
+42321,42337,N,51560,N,42318,42319,42312,N,N,51557,51559,N,N,N,N,N,N,42485,
+51632,42482,42486,51642,51630,42483,51634,N,N,N,42484,N,42487,N,42473,51633,
+42488,51637,N,51641,51638,N,N,51635,42474,42476,42489,N,42478,51627,42481,
+42479,42480,51643,51640,51631,42477,N,N,51628,42475,N,N,N,51636,N,N,N,N,51639,
+N,N,N,N,N,N,N,N,N,51629,51814,N,42818,42740,N,N,51815,42737,N,42820,N,42745,N,
+42744,51803,42748,42743,51808,51816,N,51812,N,42746,N,N,42749,42734,42823,
+51805,N,N,52157,42732,42819,42733,42741,42742,51810,51806,42747,42739,51802,
+42735,51813,42821,42824,42738,42816,42822,42736,51811,42817,51817,51804,42750,
+51807,N,N,51809,N,43224,52159,52171,43216,N,52172,43211,43221,N,N,43214,52153,
+43222,52152,52156,52163,52161,43230,43225,52147,52149,43227,43215,52150,52162,
+52169,43220,52155,52148,43219,52151,43223,52154,N,43218,N,43213,N,43228,52164,
+43229,52168,N,52166,52170,43226,52158,52146,N,52160,43217,52165,43212,52167,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,43862,43850,N,N,52704,52712,N,43849,43857,43869,N,
+52718,52716,52711,N,N,N,43851,52717,52707,43865,43856,43864,52702,N,52714,N,
+52705,43860,52706,N,52701,43867,43854,43863,43853,N,52703,52708,N,52715,43861,
+43858,52710,43866,52713,52709,43855,43868,43859,43852,43848,N,N,N,N,N,N,N,N,N,
+N,52719,N,44503,44481,N,44497,N,44502,53456,53455,53460,53461,44484,N,44493,N,
+N,N,44506,44494,N,N,N,N,53449,44487,53450,N,44508,N,44499,44478,44479,53469,
+45247,N,44492,44491,53451,44495,54363,44486,53462,44501,44500,44490,53454,
+53463,N,53448,44489,53464,44498,53452,44480,N,44483,44482,53465,44496,44485,
+44505,44507,53459,44504,N,53467,53453,53468,N,53457,N,53466,N,53458,N,N,N,N,
+44488,N,N,N,54371,54359,N,45235,N,54364,54370,45234,54357,45238,54361,54354,
+45236,54358,45241,45246,N,54375,N,54353,N,45242,N,54374,N,N,45237,54360,45233,
+54355,54351,54365,54352,54350,54362,54368,54369,45239,N,N,55387,54366,54349,
+54367,N,45249,54372,45248,54348,N,54356,54373,45244,45243,45240,45245,N,N,
+45231,N,N,45232,N,N,46024,N,55390,55383,N,46021,N,55391,N,N,N,55381,55384,
+46020,55385,N,N,46023,55389,N,55379,55378,46025,N,46026,46022,46027,55377,
+55388,55386,55380,N,N,N,46019,55382,N,N,N,N,N,N,N,N,46794,46788,56503,46797,
+56509,56512,46790,46791,56506,46789,56515,46795,56516,N,56511,46796,N,56500,
+46793,56501,N,56510,56508,N,56504,46792,56502,46798,56507,56514,56505,56513,N,
+N,47542,47539,N,47540,N,57593,57585,47538,47535,57586,N,N,47537,57589,N,57591,
+N,N,57598,N,N,57597,57592,47534,57584,47532,57587,47543,57590,N,57594,47536,
+47533,57596,57595,47541,N,57588,N,48120,58604,N,58601,48121,N,48119,N,58608,
+58605,58598,48118,N,48122,58599,48117,48125,58602,58603,48123,48124,58609,
+58606,58607,N,N,N,48810,59640,48807,59637,48809,48811,N,59638,48808,N,59639,N,
+59636,N,N,49270,60605,49271,60603,N,60604,60602,60601,N,N,60606,49269,N,N,
+61368,61369,N,58600,61367,49272,50015,61931,61932,N,50391,50392,62913,62912,
+50540,50539,63440,N,42057,42081,42169,N,42168,42323,42322,42492,42491,42493,
+42490,N,42826,42825,42827,N,N,N,N,43232,N,43231,43233,N,43870,N,41561,53470,
+41562,45250,41564,41563,55392,N,41565,47544,41566,N,42058,N,42170,42494,43234,
+N,42059,42173,42171,42172,N,N,42560,N,N,N,42828,43236,43235,43237,N,N,N,44509,
+N,N,N,48812,N,N,N,N,N,N,51534,N,42324,42325,N,N,42561,N,51818,N,43872,43871,
+53472,53471,45251,N,42174,51541,N,N,N,N,N,52173,N,43873,N,44512,N,44510,44511,
+N,N,N,N,48813,N,42326,N,N,N,42562,51644,N,N,N,N,42829,42830,N,51819,N,N,52174,
+43238,52175,N,N,N,N,N,53474,53475,44515,N,53476,N,53473,44516,44514,44513,
+53477,N,54376,N,N,N,55393,N,N,56517,57664,N,N,N,48126,48814,59641,N,42060,
+42074,N,N,N,N,N,N,N,N,N,N,N,N,N,N,45252,46029,N,47545,N,51522,42175,N,42329,
+42327,42328,N,N,43239,42061,42062,N,42082,N,N,42176,42177,42178,51646,42330,N,
+51563,N,42566,N,51647,42564,42565,51645,N,N,42567,42563,N,N,N,N,51820,43756,
+51821,N,N,51822,N,N,42832,42831,N,N,42835,42833,42834,N,N,N,43245,N,43244,
+52180,52177,52178,N,52176,43246,43242,43241,N,43243,43240,N,N,N,N,N,43247,N,
+43875,52720,N,52179,43880,N,52721,43876,43879,43878,43877,43874,N,N,N,53480,N,
+44519,53483,44517,N,N,N,53479,44520,44518,44521,53481,53482,N,53478,53484,N,N,
+N,N,N,N,46033,45253,54377,54379,54378,54380,45254,N,N,46030,N,46031,46032,N,
+46800,56519,N,56518,56520,56521,46801,N,46799,57665,57666,47547,47546,58202,N,
+N,48192,48193,48194,48196,58610,58611,48195,N,N,N,48815,N,48816,N,N,61933,
+62915,62914,63441,N,42063,N,N,N,42332,42331,N,N,42568,N,N,51648,N,N,42837,
+42838,42836,42839,51823,51824,N,N,N,N,N,N,N,N,N,N,N,N,43249,52181,N,43248,N,
+52722,43884,52723,43883,N,N,N,43881,N,43882,N,N,N,53485,N,N,N,N,45255,54382,N,
+45258,54381,45541,45257,45256,N,46036,N,46035,46034,46802,N,N,46805,46806,
+46804,N,46803,N,N,57667,N,57668,N,N,N,58613,48197,58612,N,48817,60607,49273,N,
+61934,50261,N,42083,42179,51542,N,42180,42181,42333,42334,N,42569,51825,52182,
+52183,N,43885,53486,45260,45259,55395,55394,N,N,42064,42182,42335,N,45261,
+51523,N,51564,42336,N,51650,42571,42570,51649,42840,N,N,N,N,N,N,44522,N,N,
+54383,N,46807,57669,47548,N,N,59642,N,N,62461,N,42183,N,N,52184,52724,45264,
+45262,45263,42065,N,42084,41677,42186,N,42185,42184,42339,42338,N,51565,51651,
+N,N,N,43253,43250,43252,43251,N,N,43886,N,N,46037,N,42066,N,42187,N,42341,
+42340,N,51826,N,N,43254,N,N,N,N,N,51543,N,42343,42342,42572,42573,51827,42841,
+N,42842,N,43255,43256,43257,N,43887,52725,N,N,44523,N,N,51524,N,42188,N,N,N,N,
+N,51652,N,N,N,51828,51829,N,N,52185,N,52186,N,52727,52726,52729,52728,43888,N,
+54384,44525,53487,44524,N,N,N,N,55396,46038,N,55397,N,N,N,N,57670,47549,N,N,N,
+N,48198,N,61935,N,N,N,N,51544,N,42344,N,N,N,N,N,N,N,45265,N,N,N,N,42067,42085,
+42190,42189,N,42191,N,N,N,N,N,N,43259,N,43258,43260,N,N,N,43889,N,N,N,44526,N,
+59643,49743,42086,42346,42361,42356,N,42351,42350,42357,42355,42348,42362,
+42349,42345,42360,42359,42358,42347,N,42354,N,N,42353,N,N,42363,42352,42579,N,
+42585,42581,N,42587,51653,42584,42574,42577,42580,42576,42583,42586,42575,
+42578,42582,42588,N,N,N,N,N,51838,51835,N,42855,51836,42843,42845,42869,42864,
+N,N,N,51877,51837,42847,42849,51876,42856,51832,42868,42870,42844,42861,N,
+51830,42867,N,42852,N,42862,42863,51831,42860,42858,N,42859,42865,51873,42846,
+N,42866,51875,42854,42851,N,51834,42850,51878,42853,N,42857,N,N,N,42848,51874,
+N,N,N,N,51833,N,N,N,N,N,N,N,N,N,N,N,52203,52202,43343,52205,52207,52196,52199,
+52206,43344,N,N,52193,52197,N,N,52201,52809,43339,52813,43261,52198,43262,
+43340,43333,43329,N,52194,43332,43337,43346,52195,52188,43331,52189,52191,N,
+43334,N,43336,52187,52192,N,N,43345,43341,52200,43347,N,43338,52190,43335,N,N,
+43330,43328,N,52204,N,43342,N,N,N,N,N,52808,52731,52811,N,N,52733,43896,43944,
+43892,43943,43901,43940,43890,52732,52803,43939,52815,43941,N,43897,N,N,52805,
+52802,43895,N,52730,43942,52810,43900,52812,43945,43891,43902,43899,52800,
+43937,52806,52807,43898,43938,43894,N,N,N,N,43893,52734,N,N,N,N,N,N,52804,N,N,
+N,N,N,N,N,52814,N,53572,44539,53489,N,53494,44532,44608,53492,44527,44537,
+44542,53499,N,44538,44541,N,N,53502,44533,53493,N,N,N,53570,53571,N,44535,
+53569,44531,44611,N,53496,44529,N,53574,53497,53501,44534,44610,53498,44540,
+53568,53575,54433,N,53573,44612,44528,53500,53491,N,44536,N,N,53490,N,N,53495,
+N,N,N,N,N,N,N,N,N,N,N,53488,44609,N,N,54391,N,45284,54439,45282,45279,54396,
+45275,54434,45286,54390,54395,54394,44530,45281,54437,N,54440,54387,N,46056,N,
+54441,45287,N,45273,45270,54398,45267,N,54438,N,45274,54442,N,54388,54436,
+45277,54389,54392,54397,N,N,45278,45276,45288,N,N,N,N,45283,N,45271,45522,N,
+45272,54393,45285,45280,54435,45269,N,N,N,45268,N,N,N,N,N,N,N,N,N,N,54385,
+54386,55402,N,N,N,46039,46042,55413,46062,55416,46040,55409,46046,46052,46525,
+N,N,46050,55406,46063,46043,46051,55414,56535,55419,55407,N,55398,55411,55405,
+46049,55417,N,N,46045,46065,46058,N,46047,46044,N,46055,N,55418,55404,55410,
+55412,55400,55415,46041,55399,N,46048,46064,46060,55401,46054,N,N,46061,46057,
+46053,N,55408,N,N,N,N,N,46059,N,N,N,56533,56529,N,56544,56522,56531,46821,
+46822,46814,56540,46824,56527,56526,56524,56542,46812,56536,56525,46815,56534,
+46810,56530,56537,56539,N,N,56543,46819,56523,46813,56528,N,46808,N,46820,
+56538,46816,46817,46823,46811,41567,46809,56532,N,N,N,N,N,46818,N,N,56541,N,N,
+N,47565,47560,N,57685,57681,N,57675,47554,47550,57684,47551,57678,57680,N,
+57683,N,47556,N,47563,47557,N,N,57673,47558,47559,57676,47564,N,57674,57679,
+47555,57672,47561,47553,N,N,N,47552,57677,57682,N,47562,N,N,N,N,N,N,N,57671,N,
+48205,58695,N,58692,N,48199,48211,48212,N,48202,58690,48204,58617,48210,N,
+58694,48201,58696,48200,N,58691,58693,48203,58689,58618,58615,N,N,55403,58621,
+N,58614,58620,58619,N,58616,N,48207,N,N,N,N,48206,N,N,N,48208,58622,48818,
+58688,N,N,N,59717,N,59645,N,48830,59714,48822,48826,59713,N,48825,48821,48824,
+48819,48829,59715,59646,48828,59644,48827,59716,59712,48209,N,48831,59718,
+48823,48820,N,N,N,N,60614,60616,49275,60617,60615,60613,60612,49277,60611,
+49278,N,N,N,N,60609,60610,49274,49313,49276,N,N,60608,N,49744,N,61372,61370,
+61375,61373,N,61371,61374,N,N,N,N,N,N,N,50016,61938,61939,50262,N,61940,61936,
+61941,61937,49745,N,N,N,62462,62529,50265,62528,50264,50263,N,N,N,N,50266,
+62917,62918,N,50394,50393,50395,62916,N,63192,63191,N,50541,50543,50542,63193,
+50632,63654,N,N,N,50673,N,63653,63726,N,N,51529,N,N,42365,42364,N,42591,42590,
+51655,42589,51654,N,N,42873,51881,N,51880,N,N,42871,42874,N,N,51879,N,42872,N,
+N,N,N,N,N,52208,N,52209,43348,N,N,N,N,43946,53576,53577,44613,44614,N,N,54444,
+45289,45291,54443,45290,55420,46066,N,N,N,N,46825,46826,56545,N,47567,N,47566,
+N,58697,59720,59719,N,63851,42087,51545,N,51566,51567,N,N,N,N,42594,42598,
+51657,N,42596,42595,51656,42597,42593,N,N,42592,51658,N,N,N,N,N,N,42918,N,N,
+42915,N,42877,51882,N,N,N,51883,N,42913,N,51885,42875,51886,51884,42878,42914,
+42917,42916,42876,51887,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43353,52222,N,43355,N,
+43354,N,52288,43352,43351,52213,N,52212,N,52210,52215,52214,52211,52220,52221,
+52218,52216,43350,N,N,N,52219,43356,52289,N,N,52217,N,43947,43349,N,N,N,N,N,N,
+N,43948,52820,N,N,52826,N,N,N,43954,52824,52830,N,52821,52825,52827,52829,
+52823,N,52822,52817,52818,43949,N,43951,43950,52819,52828,N,N,N,N,N,N,N,N,
+43953,N,N,N,N,N,N,52816,53587,N,53586,53591,53582,N,53585,53584,N,53588,N,
+53592,44615,44618,N,N,53583,53589,N,N,N,44617,53578,N,43952,54458,53590,N,
+53581,N,44616,53580,N,N,N,N,N,N,54449,N,N,45292,45296,54465,54447,54461,45297,
+54463,N,54469,N,54473,N,N,54464,54452,54460,N,54474,54472,54462,54457,54450,
+55462,54448,45301,54455,45302,45298,54445,54467,54453,54451,54470,45299,N,
+54476,45293,45295,54459,54454,44619,45294,54456,54471,54475,54466,N,54468,N,N,
+N,54446,N,N,N,N,55457,N,55466,55465,46074,55458,N,46075,46073,N,55460,46070,
+55464,N,55459,55461,55421,46068,N,55474,55473,55470,46067,46071,46072,53579,
+55467,46069,45300,55469,55422,55472,55471,N,55475,N,56559,N,55468,N,N,N,N,N,N,
+N,N,55463,56551,46836,46839,46834,56550,56554,56549,N,46828,46838,56546,46832,
+56553,N,46830,46829,56556,46831,56558,N,56555,46827,N,N,N,46837,56560,56548,
+56557,N,N,56547,N,N,46833,N,46835,N,56552,N,56561,N,N,57693,47568,57699,N,N,
+47573,57695,57702,57687,47575,47569,57692,48213,57691,57700,47570,N,47574,
+57690,57696,57701,57686,47572,57694,N,N,57698,57704,57688,57697,N,47571,57703,
+N,N,N,57689,N,N,N,48217,58699,48215,48214,58701,58706,N,58702,N,58705,48220,N,
+48805,48219,N,58698,58704,N,48218,58703,N,58700,N,48216,N,N,N,N,N,N,59725,N,
+59727,59722,48833,59724,N,48832,59726,N,N,48835,59728,48834,59721,59723,N,N,N,
+N,49317,60620,N,49316,60621,49315,60619,49314,60618,N,49747,49746,61942,61944,
+N,61943,50017,50018,N,N,50019,62530,50267,N,N,63443,63442,50674,N,42088,42192,
+N,N,42919,N,N,N,N,52831,N,N,N,N,46076,46077,N,56562,47576,57705,58707,51546,N,
+N,51888,N,N,N,N,N,52290,52832,53593,44620,N,N,61945,N,50396,42089,42366,51568,
+N,42599,42600,N,43357,N,N,N,45303,N,47578,N,47579,47577,N,42090,N,42193,42195,
+42194,51547,42196,42401,51569,N,42402,N,N,N,N,N,42601,42602,N,N,N,51659,N,
+42920,N,51889,N,N,N,43361,52291,N,43359,43360,43358,53594,N,N,N,43958,43957,
+43959,43956,N,52833,43362,43955,N,44621,44622,N,44623,N,54477,N,N,N,46078,
+55476,45304,N,N,N,N,46840,N,47581,47580,57706,N,48221,48836,N,61376,63194,
+63444,42091,42403,N,42404,51665,42604,42607,N,51663,51661,42606,51664,51666,
+51660,42609,42608,42605,42603,51662,N,N,N,N,42931,N,N,42928,51894,51897,51896,
+N,42922,42930,N,N,42927,51893,51891,42926,N,N,N,42921,42924,N,51892,51899,
+51895,42925,42929,42932,51890,51898,42923,N,N,N,N,N,43367,43375,N,52303,52296,
+43376,52307,52292,52299,N,N,43366,52293,43364,52300,52304,43363,N,52305,52298,
+N,52301,N,43378,43369,52308,52306,N,43374,43372,52297,43371,52295,52294,43370,
+43368,43377,43373,43365,N,52302,N,43961,N,43968,52847,43960,52839,52835,N,
+52851,52834,N,43963,52844,43966,43969,N,43964,52848,43967,N,44630,52854,52836,
+N,N,52838,52845,52849,52853,52850,52843,52846,N,N,52840,43971,52842,52841,
+52852,43962,52837,43970,N,43965,N,N,N,N,N,44636,53602,N,44635,N,N,53600,N,
+44624,N,44629,N,53599,53596,53601,44625,53595,N,44628,44626,N,53603,44627,
+44631,N,N,44632,N,44634,N,N,N,44633,N,N,N,53597,53598,N,N,N,N,53604,N,54484,
+45305,55490,54483,54502,N,N,45376,N,54500,N,45310,45306,54509,54493,54496,N,
+45379,54506,54498,45307,45380,N,54503,54501,N,N,54486,54507,54495,54490,N,
+54480,54508,54492,54479,N,45378,54497,54510,54494,54482,54487,54478,N,45377,N,
+54491,54488,45308,54481,N,54505,45309,N,54489,54485,N,N,54504,N,N,N,N,N,N,
+46144,55483,N,55480,55497,55485,55498,N,46146,N,N,N,55494,55491,N,N,N,N,N,
+55492,55495,55499,N,54499,55501,56647,N,46147,55502,55478,55488,N,55493,N,N,
+46145,46148,55500,55503,55482,55479,N,N,55481,N,N,55486,55484,46149,N,55496,N,
+N,55487,N,55489,55477,56570,56568,46914,46912,56643,56569,56644,56640,56567,
+56646,56566,56573,46846,46845,46844,56571,56641,46841,46913,N,56564,N,56574,
+56563,56572,46842,56642,56565,46843,56645,N,N,N,N,N,N,N,57710,47586,47585,
+47587,57722,57712,57718,57707,57721,57720,57724,57717,47582,57716,47588,N,
+57709,47583,N,57723,47584,57711,57714,57719,57713,57708,N,N,N,N,57715,58709,
+48225,58712,58711,58714,58716,N,48223,N,58710,N,58708,58717,58715,58713,N,
+58719,N,58718,48227,48222,N,48224,48226,N,N,58720,59735,N,N,59734,59733,N,
+59736,59729,N,59730,59738,59731,N,48837,59740,N,59739,59732,N,60625,49320,
+60623,60628,60627,59737,N,49319,N,60626,60622,60630,60629,49318,N,60624,N,
+48838,N,N,N,49748,N,N,N,61377,61946,61947,61948,50268,N,N,50269,N,62531,N,
+62920,62919,N,N,63195,63196,63445,63655,N,42092,42093,N,42094,42197,42405,
+51667,42610,42611,N,42935,42936,42934,42933,N,43379,N,N,52309,43381,43380,
+52310,N,N,N,43972,N,44637,53605,N,54512,N,45381,46151,54511,46150,N,47589,N,
+57725,48839,N,49321,60631,N,50270,N,50544,N,51570,N,42406,51571,42614,N,42612,
+42613,42615,N,42938,42937,N,51900,42939,N,N,51901,52311,N,52312,N,43382,43384,
+43386,43383,43387,43385,N,N,N,N,N,43976,43973,43975,43977,43974,53606,52855,N,
+N,N,53608,53607,44643,N,44639,N,N,44640,44642,44644,44641,N,44646,44645,N,N,N,
+N,N,45386,54514,54513,45385,N,45384,45383,45387,45382,N,N,55509,55506,46153,
+55505,55510,N,46155,55508,46152,46154,55507,N,56648,N,56649,56650,N,N,N,N,
+47590,47598,57726,47592,47596,57761,47597,47593,47594,47591,47595,48230,55504,
+48231,48229,N,48228,59741,48840,60632,60633,N,N,50020,50271,N,42095,N,42616,
+43978,N,53609,44647,N,N,45390,45389,45388,46156,46157,55511,47599,48841,42096,
+51548,42198,51572,N,N,51668,42617,N,N,N,43388,N,N,N,N,56651,N,N,42097,N,42199,
+51669,N,N,51902,N,51903,N,42940,N,N,N,55512,46158,N,56652,N,N,N,49322,42098,
+42152,42200,51573,42407,N,42944,42943,42941,42942,N,N,52313,43390,43425,52314,
+43389,N,N,43982,52856,43981,43979,43980,44650,44648,N,N,53611,44649,53610,N,
+44638,54515,N,N,45392,45393,N,N,45391,N,47600,57762,48232,48233,N,58721,49323,
+61378,61379,N,50397,63656,51531,42201,N,42099,N,51575,51574,N,N,N,N,42618,
+51671,51672,51670,N,51673,N,N,N,N,N,N,N,51911,N,51906,51908,51910,51907,42948,
+51904,N,51905,42945,42946,51909,51912,42947,51913,N,N,N,N,N,N,N,52328,N,52322,
+52317,43427,52325,52323,52316,52329,52332,52327,52320,43429,52326,43430,52321,
+52324,52315,52319,52331,43431,N,43432,N,52318,52330,43426,43428,N,N,N,N,N,N,N,
+N,N,N,N,N,N,52907,52900,52906,52899,52901,52861,52859,N,52908,52905,52857,N,
+43984,52903,52904,N,52902,52860,52858,43983,52898,52862,N,N,52897,52909,N,N,N,
+N,N,N,N,N,44655,N,44654,N,53612,44651,53614,N,44656,53615,N,N,44659,N,44657,
+53616,52910,53618,N,44653,N,44652,N,53613,53617,44658,N,N,N,N,45395,45394,N,N,
+N,54517,54521,54523,45396,54526,N,45400,54593,N,45402,N,45398,45406,N,45403,
+54519,45397,N,54518,54516,54595,54520,N,45399,54594,45404,54525,54524,45405,
+54522,45401,N,N,N,N,54596,N,54592,55527,55534,55523,46161,55519,55535,55513,
+55532,55530,55524,N,55533,55526,N,55518,55536,55516,55529,55514,N,55537,N,
+46162,N,55531,56655,55517,46159,N,55521,N,46160,55520,55525,N,N,55522,N,N,N,
+55528,N,N,N,N,56659,N,N,N,56662,56654,N,56656,N,56661,56660,46915,N,55515,
+56658,N,N,46916,N,56653,56657,N,N,N,N,57769,N,57776,57767,N,57774,57765,57773,
+57777,57764,57768,57763,N,47601,N,57766,47602,57772,57771,57770,N,N,57775,N,N,
+N,N,58725,58727,48235,58728,N,58723,N,58722,58732,N,58730,48234,58733,58724,
+58729,58731,58726,N,N,N,N,59745,59750,59744,59749,N,59742,59752,59748,59753,
+59747,59743,59751,N,59754,59746,N,60634,49327,N,49325,N,49324,49326,N,N,61380,
+N,61810,61949,N,N,62532,62533,N,50272,N,62921,N,50398,N,62922,N,63198,50546,N,
+50545,63197,50633,N,63446,N,N,N,N,42100,42619,51674,51914,43189,45407,N,N,
+42101,42410,42409,42408,N,N,42949,N,N,44660,N,56663,42102,42103,42104,42202,N,
+N,43985,N,52911,N,N,N,46163,42105,51549,42411,42412,51576,N,42620,N,N,N,51915,
+N,42950,N,51916,N,N,43438,N,N,52334,43436,43435,52333,43433,52335,43434,43437,
+N,43986,N,43988,52915,52912,52913,52914,52916,43987,N,N,53620,53619,N,44662,N,
+44661,N,N,N,N,N,45410,54598,N,45409,45411,45408,N,N,N,N,46165,54597,N,46166,
+55539,N,46167,55538,46164,N,N,N,N,56666,56668,46917,56667,56665,56664,N,N,N,
+57780,47607,47605,N,47606,57778,57779,N,47603,58737,58735,N,48237,58736,48238,
+48236,47604,N,N,59757,59755,59756,58734,60636,49328,60635,61381,61382,59758,
+61950,N,42106,42413,42622,51675,42621,N,43439,46918,N,42203,42414,43989,46168,
+N,51577,N,51578,N,51676,N,N,42952,51920,51918,42953,51917,51919,51921,N,42951,
+N,N,N,N,N,43443,43444,43441,N,N,43440,52920,43442,N,N,N,43990,N,52919,52921,
+52918,52922,43991,44665,53621,N,53623,44663,53624,44664,53622,N,52917,54599,
+54602,54603,54600,45415,45414,45412,45413,54601,N,N,N,N,45416,N,N,46170,46171,
+N,46172,56669,56671,56673,46920,46919,46169,56672,56670,N,57784,N,N,57782,
+57788,47608,57789,57786,47609,57783,57781,57787,48240,58739,57785,48242,58740,
+48241,48244,58741,48239,48243,N,59763,59761,59760,59762,59759,N,N,50022,N,
+62534,62535,N,62923,63199,50773,N,N,43445,42954,N,N,43992,N,N,N,42107,42204,
+42415,51677,N,42955,51922,N,52923,43993,N,47610,42108,N,N,N,42657,N,N,46921,
+42109,42205,42206,N,42417,42416,N,51678,42658,N,51923,N,42956,N,N,52337,52338,
+52339,N,43446,43447,52336,43448,N,N,N,43994,52924,N,53626,44666,N,53625,N,
+45417,54604,45418,54605,N,N,N,46173,N,N,N,56674,N,N,57791,57790,N,47611,N,
+48245,58742,48842,59764,49329,N,50547,63448,N,N,N,N,52340,N,52925,45419,55540,
+46922,N,N,N,49749,N,N,N,N,42958,N,42957,43995,N,53627,N,45421,45891,45422,
+45420,46174,N,57792,47612,48246,N,51532,51679,N,51925,42959,51924,42960,N,N,
+43452,52343,52342,43451,43449,43450,52341,N,N,43997,52926,44000,43996,44002,
+43998,43999,44001,N,N,N,44669,44668,44667,N,N,N,54607,45423,45426,45424,N,
+54606,45429,N,45425,54608,45428,45427,N,N,N,55542,55541,N,46177,46175,46176,
+55543,46923,56676,46924,56675,N,N,58743,N,N,48248,57793,48247,N,47613,N,60638,
+59765,49330,60637,62016,62536,62537,N,42207,N,42418,N,N,N,51579,N,N,42962,
+42964,N,51682,51928,51927,51926,N,51681,51680,42660,42963,42961,42659,N,N,N,
+43453,52344,N,43454,51933,N,51935,51934,52345,N,N,51930,N,42968,42966,N,51929,
+51931,51937,N,42965,N,51932,51941,43456,N,51938,42967,N,51936,51939,N,43455,N,
+43457,51940,N,N,N,N,N,N,N,N,52399,52386,52350,52398,52393,44007,43458,52394,
+52397,44003,52396,43459,43464,43462,52387,N,52348,52389,43469,52400,44004,
+52390,N,44005,43465,52392,N,52941,44006,52347,43466,44008,43467,43463,43468,
+52391,52346,52395,43460,N,N,52349,52388,52385,43461,N,52927,N,52928,N,N,N,N,N,
+N,52938,53665,52939,44014,52942,52932,44013,52934,N,52935,N,N,52937,44009,N,N,
+44707,N,N,52933,52929,44708,N,N,52943,44670,53629,52936,N,53628,52931,52940,N,
+N,44012,44705,44018,44706,52944,53630,44011,44710,44017,44016,44015,44709,
+52945,44711,44010,N,52930,N,N,N,N,N,N,N,N,N,N,N,N,45430,53668,53670,N,53672,
+44712,44718,54611,53676,53667,45432,54609,N,44717,44715,53678,N,54610,N,53669,
+N,44716,53673,44719,53675,N,N,44714,53674,53677,53671,N,44713,45433,N,53666,
+45431,N,N,N,N,45434,N,N,N,N,N,N,N,54613,54622,46180,N,45436,45475,46181,54624,
+45482,55545,54614,45474,45477,45438,54612,54626,54629,55625,N,54627,55549,
+45473,45480,45484,54621,55544,54625,45435,55546,54628,55548,54617,N,46178,N,
+54615,54616,45479,N,N,45478,54619,45483,54623,45476,54620,N,45481,46182,46179,
+55547,N,54618,N,45437,N,N,N,N,N,N,N,N,N,46187,46191,55616,46929,46189,55620,
+46193,56677,55622,46931,46185,46188,55623,N,55624,55630,46195,46932,N,55626,
+55631,55619,46942,N,46933,46194,55617,55632,N,46941,46192,46926,55629,N,46196,
+55621,55550,46186,55618,N,55627,N,46925,46930,46183,55628,N,46928,N,N,N,46184,
+N,N,N,46940,57795,56688,N,56680,57794,N,56684,56686,N,N,56683,N,46939,N,56682,
+46943,N,N,N,57810,N,N,46938,47680,56689,57796,N,N,46936,56681,56685,47614,
+46927,56678,56679,47681,46935,46937,46934,56687,N,N,57800,57801,57806,48253,
+57813,N,47687,N,47686,57808,N,48252,57797,47685,N,57812,47683,47684,N,57809,
+58794,48250,46190,N,57811,48291,57803,N,48251,N,48290,57798,57802,57799,57805,
+47688,48249,47682,N,58746,57807,N,48289,N,48292,N,57804,N,48254,58745,N,N,N,N,
+N,58750,48846,58744,59811,58793,48296,N,48294,48844,58790,58786,48300,N,59768,
+N,N,N,48298,58785,N,59766,N,58789,N,58792,58749,N,48299,N,N,48293,59767,48845,
+58791,48295,48297,58788,48301,58787,58748,58747,48843,58795,59770,60640,48848,
+N,59810,N,59774,N,60641,N,48849,59809,N,59772,49332,60639,N,59769,59771,49333,
+48851,49331,48850,49335,59773,48847,N,N,N,N,N,N,N,N,61391,N,61383,N,N,N,N,N,
+60647,61384,60643,N,N,49750,60645,60644,49334,60642,60646,61392,61388,61390,N,
+61385,61386,N,61389,61387,50023,N,N,50026,50025,50024,50273,62538,50274,62017,
+50399,62924,50400,50548,50634,63449,N,63450,63451,N,N,63930,42208,51580,42419,
+N,42662,42663,42661,N,42664,42970,42969,N,52401,43471,43470,N,N,53679,45485,
+45486,N,N,N,46197,56690,46944,46945,56692,56694,56693,N,57815,N,57814,47689,
+57816,N,58796,48302,N,48852,N,49336,49751,49337,N,42209,N,N,N,51942,N,N,52402,
+43473,43472,43474,44019,52946,52947,N,N,53680,44720,45487,46198,55633,42210,N,
+42110,42211,N,51581,42423,42422,42420,42421,N,N,N,42667,51689,51691,42666,
+51683,N,51684,N,51690,51686,51688,42665,51685,51692,51687,N,N,N,N,N,N,42977,
+42986,42984,51952,51949,51957,42982,51958,N,42975,51955,N,42981,51951,51950,
+42979,51956,42980,43475,42974,51953,N,51943,42971,N,42990,51948,51954,42976,
+42978,N,51944,N,51945,51946,N,42989,42983,42988,51947,42987,42973,42972,42985,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43489,52414,52407,43484,43503,52403,52410,52412,
+52415,43498,N,52411,52404,43496,52408,N,52416,43481,N,52413,43491,43490,52406,
+43479,N,N,43480,N,43478,N,43502,43494,43488,43476,52409,43487,43477,43495,
+43504,52948,43492,52405,43482,43485,43486,N,43500,43501,43499,43493,43497,
+43483,44020,N,N,N,N,N,N,N,N,N,N,N,N,N,N,52954,44097,44024,44026,44096,52966,
+44029,53681,44721,44099,52951,52959,44030,52958,52955,52963,52965,44023,44027,
+44098,44723,52960,44025,44101,52953,N,N,N,44028,44722,44022,N,52950,52957,
+52949,52952,52956,53682,44100,N,52961,52962,52964,44021,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,44737,53694,44735,44736,53684,53700,N,44726,N,N,54630,53702,53696,
+N,53687,N,53705,53690,44732,54653,53693,44734,44725,N,53707,53695,44728,53688,
+53685,53686,44729,53701,53708,44731,53692,53691,44739,44738,44724,44730,44733,
+53704,N,N,53698,44727,53683,53706,53697,53699,53703,N,N,N,N,N,N,N,N,N,N,54631,
+N,45495,45515,45514,N,45503,N,54649,54645,54642,54694,45498,45490,N,N,54647,
+46248,45494,54689,N,45516,45513,54651,54634,N,N,45512,54691,54633,45501,45505,
+54690,N,54643,45506,45500,54632,N,46200,54693,54641,45511,54644,54692,45510,N,
+55634,N,45491,54639,45496,45507,N,45502,54648,54638,54636,54654,45488,45508,
+45492,46199,54652,45493,N,45489,45504,45499,45497,54640,45509,54637,54650,
+54646,55636,55635,N,N,N,N,N,N,N,N,N,N,N,54635,55652,N,46202,N,55658,55641,
+55655,56695,46205,55659,55662,46204,55644,55661,55660,46206,55637,46201,46243,
+N,46241,55657,N,55647,46245,55664,55656,55665,46253,46251,55654,55653,N,55651,
+55645,46244,N,46242,53689,55638,N,56759,55639,46203,46250,56697,N,46246,46247,
+55640,55663,56696,55648,55643,46249,55649,55646,N,N,46254,46960,N,N,56700,
+56753,56758,56746,46956,56763,46953,56698,N,56699,46946,46955,56740,46958,
+46959,56741,N,56754,56760,46954,N,46948,56739,56701,56762,56744,56745,56702,
+56756,56747,56757,56749,N,46949,57817,46952,46950,56761,56752,56748,N,N,56737,
+47699,56751,46957,56743,N,56742,N,N,N,46951,46947,57838,56755,56750,N,56738,N,
+N,N,N,N,N,N,57833,N,57818,57829,N,57836,47697,46252,57834,47692,N,N,N,47691,
+57841,N,57819,57832,57820,57831,47695,57835,55650,N,N,N,57842,57827,47698,
+58810,48303,N,57840,57839,47700,58797,48304,58798,N,57823,57824,57821,57826,
+57822,57843,47694,48305,47696,47701,N,57825,N,57837,N,N,57830,N,N,58801,N,
+47690,48308,59818,58806,58805,58807,N,N,58804,48309,N,48315,48312,N,48313,
+58799,58802,58812,48321,48319,N,58803,55642,48306,58809,58800,N,48322,58808,
+47693,48311,57828,N,N,48314,N,48318,48320,48317,48316,N,48310,58811,48307,
+48323,N,N,N,N,N,N,N,48856,48857,59817,48866,48863,N,48854,48861,59819,48859,
+48853,N,48860,N,59816,49339,48855,N,48862,49338,59815,59814,N,48864,N,48865,N,
+59813,59812,49340,59822,48858,59820,N,N,N,N,49341,N,49346,60650,60652,N,49343,
+N,60653,60649,N,60651,49344,49347,N,60648,49342,49345,49753,59821,49752,N,N,
+49758,61396,N,49756,49757,61399,61395,49754,61393,50027,61397,N,61398,61394,N,
+49755,62018,N,62021,N,N,62022,62020,62023,50028,62019,N,N,62542,50276,62541,
+62540,62539,50275,50277,N,62925,50402,50401,N,N,63201,63200,63203,50635,50549,
+63453,63202,N,N,63452,50637,50636,50675,63657,63727,42212,N,N,55666,59823,N,N,
+42668,51959,42993,42991,N,42992,N,52417,43505,44102,N,52967,N,52968,N,44103,
+53710,N,44740,44741,53709,N,N,N,N,45523,N,45519,N,54695,45526,45525,45518,
+45521,45524,45520,N,N,55670,45517,46255,N,N,N,46257,46258,55669,55672,46256,
+55667,55671,N,55668,N,46961,N,N,56764,N,N,47702,57844,48867,48324,58813,48325,
+48326,58815,58814,58816,59825,N,N,59824,60655,60654,49348,49349,62024,N,N,
+42213,N,N,N,N,55673,N,N,N,46260,46259,56765,N,61400,50403,63454,42214,N,44742,
+N,45528,45527,55674,55675,46962,57845,47703,59826,N,42215,42424,N,43506,52418,
+N,52969,44104,45529,N,55676,46261,46963,N,58817,58818,N,N,60656,49759,63728,
+42216,N,52419,43507,44105,N,52970,N,44743,53714,53712,53713,44744,53711,N,N,N,
+N,45531,45532,54696,45533,45530,55677,N,55678,56766,N,N,47705,47704,N,N,60657,
+61401,N,62026,62025,62543,N,51550,44106,N,N,42217,42425,N,42670,42669,N,N,
+42671,42672,51694,51693,51960,42994,51963,51962,51961,51964,N,N,N,N,43508,
+52425,52421,52430,43515,N,43513,52426,52422,52429,43512,43584,52424,52420,
+43518,52427,43511,52428,43514,43516,52432,52431,52423,43510,43509,43517,N,N,N,
+N,N,N,52975,52981,N,44112,44109,52972,52977,N,44115,44107,52976,44110,44113,N,
+N,52979,N,44108,52984,44111,N,44114,52973,52978,52982,52974,52971,N,N,52983,
+52980,N,N,N,N,N,N,44752,44745,44748,N,44751,N,53717,N,44746,53715,N,44750,N,N,
+44747,N,53718,44749,N,N,N,N,N,N,54700,45535,54699,54701,45534,45539,53716,N,
+54698,54702,N,45536,54697,45538,N,45537,N,55719,N,55714,N,46262,46266,46263,
+55717,55720,N,46264,N,46265,46270,56775,55718,46268,55715,55713,N,46269,N,
+55716,N,N,N,46969,N,56767,46966,46967,46965,56772,56771,56768,46971,N,N,56770,
+46267,N,N,56774,56769,46968,46964,46970,56773,N,N,N,47708,N,57848,57847,57846,
+47706,N,N,N,N,N,47707,58821,58824,48328,N,N,48327,58825,58820,48330,58822,N,
+48329,58819,N,58823,48873,48870,59835,59834,N,59833,59828,N,59829,N,N,N,48871,
+N,48868,48872,59827,48869,59830,59831,59836,N,N,59832,N,N,60658,N,N,N,49351,N,
+61404,49350,61402,61403,49760,50030,62027,N,50029,N,N,62545,62546,N,50278,N,
+62544,50404,N,63455,50638,63658,63659,N,42218,N,42673,42674,42995,N,52433,
+44116,44753,45540,N,N,45266,N,46271,46272,46028,55721,N,46972,57850,57849,N,N,
+42219,42675,52434,43586,N,43585,N,52985,52986,N,53719,53720,44754,44755,N,
+44756,54703,N,N,45542,N,46274,N,46273,56776,57210,57851,59837,N,N,49761,50279,
+42220,N,42428,42429,42427,42430,42426,N,N,42678,N,51702,42677,42679,N,N,51697,
+51696,51699,51698,51701,42676,51695,51700,N,N,N,N,N,51965,43005,51966,52035,
+43004,N,52039,52034,52037,42997,42998,42999,43000,N,43072,N,52033,43002,43073,
+N,52032,52038,N,43001,52036,43003,42996,43006,N,N,N,N,N,N,N,N,N,43607,N,52436,
+43587,N,43597,43598,43590,43608,43592,52444,43603,52439,43593,52454,52455,
+52447,52440,43606,52452,43601,43599,N,52453,N,52451,52443,52435,52442,43594,N,
+43600,N,43588,52446,52445,52437,N,43602,52449,52438,43605,52456,43589,N,43596,
+52441,52450,43604,N,43591,43595,N,52448,N,N,N,N,N,N,N,N,N,N,N,N,N,N,53083,
+44124,44137,N,53078,53068,44130,53066,44123,53061,44133,53074,52990,53057,N,N,
+N,N,53060,52987,53073,53089,44128,53062,53080,N,52989,53087,53088,53091,53082,
+53067,53075,44134,44121,44129,44141,44118,44120,N,N,N,53059,44138,44131,53085,
+53056,44140,44135,53065,N,N,44139,53072,53064,44132,53084,53076,N,44126,53090,
+53063,44122,53081,53071,44127,53077,44119,52988,44136,44771,44125,53070,53069,
+53058,N,53086,N,53079,N,N,44117,53740,44778,53741,N,53729,44767,44779,N,53722,
+N,53731,53739,N,53721,53748,44757,N,N,N,53747,53742,N,53743,44765,44776,53733,
+N,53734,53744,53735,N,53730,53724,53725,53738,53732,N,N,44758,44762,53746,
+53726,44774,44770,N,N,44773,44780,44763,44775,53737,44777,44760,N,44759,53723,
+N,53727,44768,53745,53736,53728,44772,44769,N,44761,44764,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,54724,N,54708,54709,54713,N,54728,54725,N,54718,54717,
+45549,54721,54736,54704,N,54737,54723,54741,54729,45548,54727,45543,45564,
+45554,N,45558,45557,54705,N,54734,54740,54732,54739,N,N,54720,54706,54738,
+54722,45546,45559,N,54731,45552,N,N,N,54730,54707,45560,N,45562,54733,45563,
+45545,54714,54735,N,N,45551,45561,54716,54726,54711,54715,45556,54710,45544,
+45553,45550,54719,44766,55744,45547,N,N,N,N,N,N,N,N,N,N,N,N,N,N,45555,N,55747,
+55769,55758,46294,N,46289,55741,46290,55757,N,55750,55763,46286,55723,55765,
+46276,55731,46279,46278,N,46295,N,55725,55759,55760,46281,46277,55739,N,46288,
+55734,N,55761,46284,55753,55766,55728,55733,55727,N,46283,55746,56798,55729,
+46287,55738,55762,46282,55735,55732,55749,46285,46275,46297,55752,55751,55724,
+46280,55764,55740,55742,N,55755,55754,55722,46291,46293,55730,55737,55745,
+46292,55736,55748,55767,N,55756,N,N,N,N,N,N,N,N,N,N,N,N,N,55768,N,N,N,N,55726,
+N,N,N,N,56818,47014,N,56816,56795,56800,56793,N,56812,56779,56786,N,56810,
+56820,56796,N,56783,56802,56807,56787,N,56804,56784,N,N,56791,56792,47016,
+56811,56809,N,56780,56814,N,56815,56817,47020,47012,N,54712,56788,56806,56789,
+47009,47025,56813,47023,47019,56778,47011,N,56781,47024,N,56797,56777,N,47017,
+56801,56785,47018,56794,46974,46296,56803,55743,56782,N,N,56808,47013,56805,
+47010,56799,47021,56790,56819,N,N,N,N,N,N,47015,57030,N,N,47022,N,N,N,N,N,N,
+57930,57928,N,57950,57926,N,57944,46973,47711,57922,57949,N,57927,57941,47716,
+47709,N,57947,N,57920,57946,N,47727,57937,57953,47725,57929,47710,57931,57945,
+47719,57924,47723,47713,57933,57923,57852,N,57943,47720,57952,57853,47717,N,
+57939,N,47718,57925,57936,57932,57934,N,47712,57951,47726,57935,N,57954,N,N,
+57854,57940,47715,47724,47722,57921,57942,47721,N,N,47714,57938,N,N,N,N,57948,
+N,N,N,N,N,N,N,N,58837,N,58833,58829,58849,58846,48333,N,N,58853,58836,48344,
+58843,N,N,58832,58842,48341,58862,N,58859,58845,58830,N,N,58850,58852,48337,
+58840,58835,58826,48334,48342,N,58855,48343,58827,58861,58848,58854,48340,N,N,
+58851,N,58858,N,48345,N,48339,58844,58831,58863,58828,58856,48336,N,58838,N,
+58839,48335,48332,58834,48338,N,48331,N,58857,58860,58841,59850,N,N,N,N,N,N,N,
+N,N,59842,N,59838,48886,N,N,48875,48880,48876,59852,59863,48874,59844,59853,
+58847,59854,N,N,48881,N,59869,48885,48888,59840,N,48884,N,59867,59868,59858,
+59857,59849,N,N,59859,59866,59865,N,48879,48877,59851,59848,N,59845,59864,
+48887,59862,48883,48882,N,59856,N,59839,59841,59843,59861,59855,48878,N,59846,
+N,59860,N,N,N,N,N,N,59847,N,N,N,N,N,N,N,49359,60741,49352,60661,N,60737,49354,
+60744,N,60668,N,60663,N,N,60745,60659,60670,N,49361,60740,60746,60669,49353,
+60736,60660,49360,N,N,60743,60665,49356,N,60667,60664,49362,60666,49355,49358,
+60739,60662,60742,N,60738,N,N,N,49763,61415,49768,49769,N,N,N,49762,61414,N,
+61411,61412,49766,61406,61410,49765,N,61407,N,N,N,N,49767,49764,N,61405,61409,
+61413,N,N,N,62033,62030,62039,N,62038,62036,62031,N,50034,N,N,N,N,N,62032,
+50033,49357,62035,50032,62040,62034,62029,61408,N,N,N,50031,N,62028,62550,N,
+62549,62037,50280,N,62553,62554,62548,62552,N,62547,N,N,N,N,62929,62551,50407,
+50405,62927,62930,N,62926,62928,50406,N,N,N,63205,63206,50550,63204,N,N,N,
+63458,50639,63456,63457,63660,N,N,50774,63731,63729,63730,63732,N,N,N,63931,N,
+42221,42680,N,43609,N,52457,N,N,53092,N,N,N,53749,53751,N,53750,N,53752,45565,
+54743,53753,N,54742,54744,54745,55770,46299,55771,55773,46300,46298,55772,N,
+56826,56824,56823,N,56822,56821,47026,56825,47728,57955,57957,47729,57956,
+48347,N,48346,58864,N,N,59871,59870,59872,N,N,48889,N,60747,49363,N,61416,
+49770,62041,50551,42222,42431,42681,43074,43610,43611,N,N,44142,N,N,53754,N,N,
+N,N,47027,N,N,N,59089,48890,49771,42223,N,42682,N,N,52459,43612,52458,N,53093,
+44143,53094,N,44144,N,53756,44782,44781,N,54750,54748,54749,54747,N,54746,N,N,
+55774,55777,46302,55775,46301,55776,N,56827,N,N,57958,57959,57960,N,58867,
+58866,48348,58865,58868,59873,N,N,59874,59875,N,60748,49364,49772,62042,N,
+50408,51551,N,44145,53095,44783,N,N,45566,N,46303,55778,N,47029,47028,N,N,
+57961,57962,48349,48350,59877,59876,61417,63459,42224,51552,42432,N,43075,
+52040,N,44146,47030,42225,N,53096,44147,53097,N,49365,42226,N,N,52460,N,53098,
+N,53826,53825,53758,N,53757,53827,53824,N,N,45632,45633,N,N,46304,55779,N,
+55780,55781,N,N,N,56897,56898,56896,N,56829,56830,47031,57963,58871,58870,
+58869,58872,59879,59878,48891,59880,N,49366,60749,N,61418,62043,63207,N,42227,
+42434,42433,N,43613,51553,51582,42683,N,51703,52041,52042,43614,N,52461,N,
+44148,53099,53100,N,44784,44788,53828,44787,44785,44786,N,54751,45634,46307,N,
+46305,46306,55782,N,N,47730,42228,N,51617,N,42435,N,N,51620,N,N,42438,51619,
+42437,42436,43076,51618,N,N,51704,N,N,N,51708,51710,51776,42693,42694,51707,
+42689,N,51705,N,51709,42690,N,42685,N,42686,N,42692,51706,42684,43077,42687,
+42688,42691,N,N,N,52059,52057,52044,43089,52051,43084,52045,N,52053,N,52050,
+43087,52049,43094,52058,43096,N,43098,N,52043,N,43085,52060,N,43092,43095,N,
+52549,43079,43102,43093,52046,43082,43097,52054,43080,43081,52547,52047,43088,
+43099,52061,52048,43086,N,43091,52462,43100,52055,43090,N,43101,43078,52052,
+43083,52056,52548,N,N,N,N,N,N,N,N,N,N,N,N,N,43626,43642,52469,43633,N,52555,
+43618,N,43621,52546,N,52467,52471,43629,43631,52474,43638,43624,43622,43623,
+43637,52551,43632,52473,52475,43630,43635,52476,52554,N,44149,43641,N,43619,
+52553,N,52557,52472,52559,52544,43628,52468,43627,43645,43634,N,52466,53109,
+43640,43644,52545,52550,N,43646,43639,43625,43615,N,43620,N,52470,43616,52558,
+N,52464,52463,52477,52465,43643,44789,43636,52478,43617,N,44198,N,N,N,52556,
+53116,53153,N,53156,53111,N,N,53159,53162,53164,53108,44150,44155,53833,44205,
+53157,53165,53115,53107,N,N,N,53860,44158,53154,53112,53114,44197,N,53117,
+44157,53104,53160,N,53163,N,N,44154,N,44200,53101,44202,44152,44206,53161,
+53103,44203,53854,52552,44156,44151,53110,53102,44204,44196,53155,44201,44199,
+53113,44193,53105,44194,44195,53106,53158,44153,53118,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,53836,44797,44867,N,N,N,53845,53851,53847,53834,53837,53830,
+53831,44874,44794,53846,53855,44869,44790,N,44864,53838,44866,53839,53849,N,N,
+N,44868,53864,53832,44796,44795,44872,53829,53862,53850,53863,53857,53843,
+53858,N,53852,53861,53859,44873,53844,44793,44792,44865,44871,53856,44870,
+53841,45635,N,53865,53840,53835,44798,44875,44791,N,53848,53853,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,45669,54753,54757,N,45650,45648,N,N,45639,54755,54754,
+45659,N,54760,45653,N,54778,54855,45636,54775,54768,45671,54752,N,54780,N,
+45668,45656,45667,45646,54764,54782,54774,45647,45641,54853,N,54781,54848,
+45649,45657,54850,54762,54779,54767,54852,45662,45638,45660,54772,54770,54771,
+45651,54766,54765,45640,54759,54854,45642,54769,45672,N,45666,54758,45663,
+45661,45670,54776,45665,53842,54777,45664,54849,45637,54773,45655,54761,45654,
+N,45652,45644,45643,55783,54851,54763,N,N,55804,N,45645,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,46401,45658,46318,55798,46332,N,55786,46315,46311,55881,46317,
+46321,46316,46325,55885,55876,N,N,55793,46330,46324,55805,46308,55882,55875,
+46312,55799,46327,55893,55894,N,46309,55880,46329,55803,55789,55790,46333,
+55794,55801,55795,N,46331,46404,55791,55784,55785,N,55787,46314,55800,N,46328,
+46402,N,N,55802,55891,55883,46310,55889,46322,N,46320,N,55895,46319,55873,
+55796,55806,46407,55877,55874,55792,46403,55887,55884,55892,46313,55872,46406,
+N,55879,N,N,46323,46326,N,55878,46405,55797,54756,N,N,55888,55886,55890,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,55788,46400,N,N,N,56929,56928,56902,47037,N,56927,56905,
+56906,N,47047,56936,47042,56926,N,56899,47048,47038,56914,56904,56907,56931,
+47032,56938,56930,47041,56919,47052,N,N,47051,47045,N,N,56937,47033,56917,
+56908,56921,56933,47053,N,47035,56916,N,56909,47044,N,47043,56912,56922,56932,
+56903,56913,47036,56923,47049,47040,56910,47039,56901,56915,56935,46334,47792,
+56918,57964,56920,56934,47046,56911,47034,47050,48368,56900,N,56925,N,N,N,
+56924,N,N,N,N,N,N,N,N,N,N,N,N,N,N,58026,47789,57981,58020,47778,N,57966,47791,
+N,47735,57965,58032,47793,57969,58019,N,57971,58035,58031,47733,47777,58963,
+47790,47741,57967,N,58030,47779,58027,58040,57973,57982,N,N,58038,58028,47740,
+N,N,57980,47734,47732,47784,N,N,57978,57975,57976,N,58034,N,58039,58037,47738,
+58041,47742,47783,N,57968,58874,57977,N,47736,47788,47785,47739,58021,57972,
+47786,58023,47780,47782,47731,N,58025,58017,57970,47781,58033,58036,57979,
+58024,N,47737,48351,58022,58873,N,58029,N,N,N,N,N,N,N,N,N,N,57974,58948,58958,
+48354,58957,58969,48356,58955,N,58959,48367,N,58950,48359,N,58962,59888,48371,
+48370,58964,58947,58974,48365,N,48355,58967,N,58971,58976,58965,58953,48358,
+48361,48369,48364,N,58956,58018,N,N,58952,58975,48360,N,48363,58977,48352,
+58966,58875,58972,49375,N,58954,N,48353,58949,48357,58876,47787,58945,N,58970,
+58946,58944,48362,N,58968,N,58878,58961,58960,58973,58951,48366,N,N,N,N,N,N,
+59891,N,48969,48894,59968,59883,48961,59895,48968,48963,59893,60751,59899,
+59970,59898,59881,59896,59972,59974,48893,59973,48964,48970,N,48967,N,59902,
+48966,59897,N,59885,59890,N,59901,48965,48962,48892,48960,59889,N,58877,59884,
+59887,59969,59892,59882,60750,59971,59886,59900,N,N,N,N,60753,49379,N,N,49367,
+N,N,49371,60755,60761,60759,49369,49370,49377,60762,60754,49372,N,60758,60757,
+60763,49378,N,49373,49376,60756,49380,49374,49381,49368,60760,N,60752,N,N,
+61431,N,N,49777,61428,61430,N,49775,61426,61427,61422,N,N,59894,61423,49776,
+61419,N,49773,61432,49774,61420,61421,61425,49779,N,49778,N,N,61424,50040,
+62047,62053,50041,62044,50038,50035,62055,50039,N,50036,62046,62049,62050,
+62051,62054,N,61429,62045,50037,62052,62056,62048,N,N,N,62557,50282,62560,
+50283,62568,62559,62556,N,62558,62562,62565,62564,62567,62555,N,50281,62563,
+62566,62569,62561,62931,62932,62936,62937,N,62934,62935,62933,N,50409,N,N,N,N,
+50552,63211,N,N,63208,63209,63210,50553,N,63461,63460,N,63663,50676,63661,
+63664,63662,63733,50775,50789,63907,63852,N,63906,63952,63953,42229,N,N,N,N,
+42695,51777,N,N,52062,N,43103,N,43106,N,52063,N,43104,43105,N,N,N,N,52568,
+52570,52565,52562,52564,N,N,N,43684,N,N,N,43682,N,N,52566,43683,52563,52560,
+43681,52567,N,52561,43685,52569,N,N,N,N,53167,N,53171,N,N,44215,N,N,N,N,53174,
+N,44207,44210,44212,44214,44211,53170,53169,N,44209,53172,53173,N,53166,44213,
+N,44208,N,N,N,53168,N,N,N,N,N,N,53879,53880,53881,44880,N,44876,53870,N,53878,
+53883,44881,N,53868,53874,53867,53877,N,N,53873,44877,44879,53882,N,53866,
+53869,53875,N,53876,53884,53872,N,44878,N,N,N,N,N,N,N,N,N,N,45677,54862,N,N,
+54864,54860,N,54872,54858,54871,45673,54856,55899,54866,45676,N,54867,54870,N,
+54874,N,54863,N,54868,N,N,45674,45675,54873,54861,54857,54875,N,54865,N,N,
+54869,N,N,N,54859,N,46408,46409,55909,46415,N,55897,55906,55896,46412,55904,
+55902,N,55903,46410,N,55907,N,N,N,N,N,55900,55898,46411,55901,55905,N,N,N,
+46413,N,N,N,55908,N,N,N,N,N,N,56944,56951,56953,56993,N,47066,56939,N,47058,N,
+56954,47063,56994,47054,N,56957,N,56941,56958,56940,N,47068,N,56952,47055,
+56995,N,47060,56945,47065,56956,56943,56950,56946,56942,47057,47064,47062,
+47059,47067,47056,56949,N,47061,N,46414,N,56955,N,56947,N,N,N,N,N,56948,N,N,
+58049,N,47796,N,N,58045,58051,58047,N,47798,58046,58050,58042,N,58044,47797,N,
+N,N,N,58048,58043,N,47799,N,47794,N,N,58052,N,47795,58983,58980,58992,58986,
+58988,48372,58982,58990,N,N,58989,58987,N,58993,48375,58984,58991,N,48373,N,N,
+58979,58981,48374,58978,58994,N,58985,N,N,59978,48977,N,N,59989,59987,48971,
+59977,59980,59981,59976,48981,48982,59975,59990,59985,48975,48972,59984,59982,
+N,N,48978,59986,48973,N,48974,N,59983,48976,59979,N,59988,48979,59991,59992,
+48980,N,N,49383,49390,60764,60770,N,60768,49386,49385,49382,60766,N,N,N,49388,
+49387,49384,N,60769,60765,60767,N,49389,N,N,N,49783,61435,N,49780,49781,61437,
+49782,61434,61433,62060,61436,N,62061,50042,62059,N,N,62058,N,62057,50043,N,N,
+50284,N,N,62570,62571,N,N,N,N,62940,62939,50410,N,62938,63212,63213,N,N,63462,
+63665,N,N,63734,63932,50809,63942,42230,N,43686,43687,N,N,44216,N,N,N,N,49391,
+42231,N,43688,44882,47069,42232,N,45678,47800,51554,N,53175,53885,N,58053,N,
+49392,42233,43689,53176,53177,55910,46416,N,N,56996,N,N,47070,58054,N,N,48376,
+N,50044,42234,55911,42235,N,42697,51778,42696,43109,43108,43107,52064,N,N,N,
+43690,N,43691,52571,N,53178,N,53181,44218,53179,N,44217,53180,44219,N,53922,
+53921,53886,44883,N,54877,54878,45679,54876,54879,46418,45680,N,N,46417,55915,
+55914,N,55912,55913,N,55916,56998,56997,57001,N,57000,56999,47801,58057,N,
+58056,47802,58055,58995,N,58996,48377,N,59993,59994,N,N,62066,50045,62065,
+62064,62062,62063,50411,62572,63214,63735,N,42236,N,51621,42439,51622,N,N,N,
+51779,51780,N,N,N,N,52070,N,N,52066,N,52065,43692,52069,43111,52067,43110,
+52071,52068,N,N,52575,53182,52573,52580,N,43693,N,43696,52581,52577,N,52578,N,
+52572,43695,52574,43694,52579,N,52576,N,N,53186,44221,44222,N,53189,53183,N,
+53188,N,53184,44220,53187,53185,N,N,N,N,N,N,N,53928,53925,N,53927,44888,44887,
+44885,53924,53929,44884,44886,53926,54887,53923,53930,N,N,N,N,N,54882,54886,N,
+54885,55918,55929,N,N,54888,N,54883,55917,45684,N,N,45683,54881,54884,45685,N,
+45682,45681,54880,54889,N,N,N,55920,55927,N,46420,55926,55923,N,46422,N,N,N,
+55925,N,N,55919,55921,55924,55922,46421,55928,46419,47071,N,N,57005,57004,
+57002,N,47074,47073,57006,N,57003,58058,47803,47072,N,N,N,57008,57007,N,58061,
+58059,48378,N,47804,58060,58998,N,N,N,N,48379,58997,59006,59005,59003,N,59002,
+58999,59000,59001,59004,59041,N,N,59999,59996,59997,48983,59995,60001,60000,
+59998,N,60772,60773,49393,N,49394,60771,N,49785,61438,49784,50046,N,50081,
+50285,62574,62573,62941,63215,50554,63464,63463,63465,42440,53190,44889,45686,
+54890,42441,51623,42237,N,N,51781,N,N,N,52076,52074,52075,52072,43112,52073,N,
+N,N,N,N,52589,N,43699,52587,52583,52586,N,52582,43701,52585,N,43698,43697,N,
+43700,52588,52584,N,N,N,N,44226,44229,53198,53197,53196,44223,53205,53195,N,
+44225,53935,N,53202,53200,44228,N,53192,53203,N,53194,53204,53201,53193,N,
+44224,53206,53191,44227,N,N,N,N,53940,53931,53942,N,53934,53945,53946,53932,
+53944,53941,53939,53943,44895,N,44893,N,N,53937,N,53933,N,53936,53947,53938,
+44894,53199,N,44890,44892,N,N,N,N,N,54904,54893,54891,N,54892,N,54899,N,54900,
+54896,45691,54901,54898,54895,N,45689,54894,45687,45690,54897,54905,44891,
+45688,54903,54902,45692,N,N,N,N,N,N,N,N,55934,N,N,N,55969,46432,N,55975,N,N,
+55977,55970,46426,55974,55973,46427,46433,N,46434,55976,46424,55933,55931,
+55971,55930,46431,55932,55972,55978,46425,46430,46428,46429,N,N,N,46423,N,N,N,
+N,47081,57015,47080,57019,N,57009,N,57020,N,N,N,57010,57011,N,57021,57018,
+57016,57017,57013,57012,N,57022,47077,N,57014,N,47082,47076,47083,47084,N,
+47079,47078,N,N,58062,47806,47805,N,N,58067,N,48380,47807,N,N,47809,58068,
+47075,47808,58064,58066,58063,N,58065,N,N,N,59051,N,N,59050,59047,48448,60002,
+48449,59046,N,48382,N,59048,59045,59042,59049,59043,59044,48381,N,N,N,N,60777,
+N,60006,N,60005,60007,N,60774,48986,N,60003,N,48984,N,48988,48987,60004,60008,
+N,48985,N,60781,49397,49786,49398,49395,60778,60776,N,60779,N,60782,49396,
+60780,60775,N,N,61506,61509,62069,61504,N,62575,61510,N,50082,61508,49787,
+61505,61507,61511,62070,N,62068,N,N,N,N,50083,62067,N,N,N,50286,N,N,N,N,50413,
+63217,50412,63219,63216,63218,50640,63666,42442,52590,53948,53949,45693,57023,
+48989,50084,50555,63667,42443,N,52591,41568,N,N,53207,N,53208,N,N,N,N,N,53950,
+53951,45694,45729,N,N,N,55979,N,57026,57025,57024,58069,N,58070,58071,47810,N,
+N,59053,59052,N,N,60009,48990,48991,N,60786,60783,60784,60785,61513,61512,
+49788,62071,62942,42444,N,44230,N,45730,57027,N,42445,N,53952,45731,N,N,46435,
+46436,N,42446,42447,51782,43114,43113,44231,53209,55980,42448,42449,42450,
+42451,N,N,N,43115,43116,52078,52077,N,N,43702,52594,52592,52593,N,N,N,N,N,N,
+53210,53211,N,N,44235,44233,N,44234,44232,N,N,N,N,44896,N,N,N,N,44900,44899,
+53953,44898,44897,N,53954,N,N,45734,54907,54906,45732,45733,N,N,N,46438,46437,
+55982,N,N,55981,45735,N,N,N,N,N,47085,57029,47086,57028,N,N,N,58072,59054,
+48450,60010,N,N,N,60787,N,50086,50085,N,N,50556,42452,52595,N,N,45736,58073,
+47811,N,N,52079,52080,N,N,52596,43704,43705,N,N,43703,N,N,N,N,44239,44240,
+44237,44238,N,53212,N,N,53213,44236,N,N,N,N,53955,N,44904,44905,N,45739,53961,
+N,44910,44908,53962,53957,44907,44906,44901,53960,53959,53956,44909,N,53958,
+44902,N,44903,N,N,45740,54945,54946,45741,54908,54910,54948,54947,54909,N,
+45737,45738,N,55990,46443,46442,55984,46440,N,55987,46444,55988,46445,55985,
+46439,46441,55989,N,55986,55983,N,N,N,N,N,57042,N,57031,47088,47091,47090,
+47095,47094,57043,57041,57034,57038,57037,47092,57040,57036,57044,57035,47093,
+47087,47089,N,57033,N,N,N,N,58075,47815,58079,47814,58076,47813,N,57032,57039,
+58078,N,47816,58080,58077,58074,N,N,59057,59061,59063,59059,59058,59056,48453,
+48451,48456,48457,59060,48454,59055,48455,47812,59062,48452,N,N,N,60012,N,
+60011,60019,60013,60018,60015,48992,60017,N,N,48993,N,48994,N,60016,60014,N,N,
+N,N,49400,60788,N,N,49399,60791,60789,60790,N,N,49401,N,N,N,61517,N,49825,
+61518,N,N,49789,61519,49790,61516,61520,N,61514,N,N,50087,62072,50088,50287,N,
+61515,50288,N,N,N,50414,62943,N,50558,63220,50557,N,63466,50677,50678,N,N,
+63948,N,N,44241,53214,N,46446,46447,42453,42698,51783,N,52081,43117,N,43706,N,
+44242,44243,44244,54950,53963,44911,N,N,45742,54949,N,N,55992,46449,N,55991,
+46448,N,N,57045,48458,59067,59064,59065,59066,N,N,N,N,N,60792,N,61521,N,N,N,
+62577,62576,N,63221,42454,52597,44912,N,N,N,46450,57046,N,N,58081,N,48459,
+60020,N,61522,62578,42455,N,N,43707,44247,53215,44248,44246,N,44245,53964,
+44913,N,N,44914,44915,N,N,N,45744,54951,45743,N,N,N,N,N,55993,45745,46451,
+57047,47096,47097,N,47817,N,47818,48460,48996,60021,48995,N,60793,49402,N,
+61523,62579,42456,43118,52600,52599,43708,52598,43709,52601,N,53221,44251,
+44250,53223,53222,44255,N,44254,44249,N,53217,53218,53219,N,44256,53216,44252,
+53220,44253,N,N,N,N,53967,53971,53969,53968,N,53972,N,N,N,53973,53974,53966,N,
+53965,N,44917,44918,N,53975,53970,N,54960,N,53976,44919,44916,N,N,N,54954,N,
+54953,N,54955,54956,54958,54957,54962,45749,45746,45750,54952,45751,54961,
+45748,54959,45747,N,N,N,N,N,55996,55998,55994,55995,N,N,55999,56001,56002,
+55997,56000,46452,N,N,57051,N,57056,57048,57052,N,N,57057,57053,47098,47171,N,
+47101,57049,57050,47822,47174,47102,N,47172,47100,57055,47173,57054,47169,
+47099,47170,57058,58086,58088,N,N,N,N,N,N,N,N,N,47168,N,N,58083,47820,58089,
+47821,58087,58082,58085,58090,47819,58084,N,48462,59071,59070,N,48465,48463,
+59068,48461,59069,N,48464,N,N,N,60029,N,60065,N,60030,60022,60026,60025,60023,
+48998,48999,48997,60024,60027,60028,N,49000,N,49472,60835,N,49404,60795,49406,
+49473,N,N,49405,60834,60796,49403,60833,60794,60798,60797,N,N,61525,49828,
+49829,49826,N,49827,N,N,61524,N,62075,N,N,50089,N,62073,62074,N,62580,62583,
+62581,62582,62944,N,N,50415,63467,63668,N,50679,63736,63737,50790,42457,44257,
+N,56003,N,57059,N,42458,43119,N,43710,N,53224,53225,44920,N,N,56004,46453,
+47175,49474,60836,62076,62584,42459,N,N,N,52641,52602,52604,52606,52605,52603,
+43711,44258,53234,N,53229,53226,N,N,53233,N,N,44260,44261,53232,53231,53230,
+53227,53228,53235,44259,N,N,N,N,N,N,N,N,44924,N,44964,44963,53985,53979,53977,
+N,44961,54969,44922,53982,53986,53988,53984,53978,44962,53983,53981,44921,
+53989,44965,53987,44925,53980,N,44926,44923,N,N,N,N,N,N,N,N,N,N,45753,N,54970,
+N,N,54963,54965,54967,N,54968,54966,45754,N,54971,N,54964,N,N,N,N,N,N,N,N,N,
+56008,46454,56016,N,56005,N,56017,N,56006,56007,N,N,56015,56014,56011,45752,
+46455,56009,56012,46456,56013,56010,N,N,N,N,N,N,N,57070,N,57074,47182,N,58096,
+47185,57072,N,N,57069,57064,57066,57067,57060,N,47181,N,N,47180,N,47176,57063,
+N,47183,N,47184,57062,57065,57073,47178,47179,57071,57061,N,N,N,58098,47824,
+58100,57068,58102,47828,58103,58099,N,47825,58095,47827,58092,58097,58101,
+58094,N,N,47177,N,58091,47826,58093,N,N,N,N,N,48468,59073,48472,N,48470,N,N,
+47823,N,59080,59081,48467,N,N,59079,59082,48469,48466,59075,59072,59077,59074,
+48473,59076,N,N,59078,48471,N,N,N,N,49002,60072,N,60066,60070,60076,60077,
+60073,60074,60071,N,60068,N,49004,49001,60067,60069,N,49003,60075,N,49478,N,N,
+60842,60837,49477,N,N,49475,N,60844,49476,60840,60841,60838,60845,61526,49479,
+60839,N,60846,60843,N,N,N,61530,N,N,61527,N,49830,N,61531,61533,61532,61528,
+61529,N,N,62115,N,50090,N,62078,62114,62077,62116,N,N,62113,N,62586,62589,
+62585,50289,62587,62588,62590,50290,50292,50291,62945,N,62947,N,62946,N,N,N,
+63222,N,N,63669,63738,42460,N,N,52082,43712,52643,43713,43714,52642,N,53240,
+53239,44262,44265,44264,44263,53236,53238,53237,N,N,53992,44967,53996,53995,
+53994,53990,44966,44970,44973,N,N,44974,53991,53993,44972,44971,44969,44968,
+54978,N,54976,54972,45755,N,54973,45756,54974,54975,54977,N,45757,N,N,56021,N,
+56020,56019,56018,N,N,N,N,57078,47186,N,57075,57077,N,47187,N,47188,57076,N,N,
+N,N,N,58177,N,58105,58106,N,47831,47829,47830,58179,N,58178,58110,58109,58108,
+58107,58176,58104,N,59083,59088,59086,N,N,N,59085,59084,59087,N,60078,N,49005,
+49480,60848,N,49481,60847,61535,61534,49831,N,62117,50091,62625,50593,63223,N,
+63671,63670,51624,44266,44267,54979,N,47190,42461,43122,43121,43120,N,N,N,
+52644,N,N,43716,43715,N,44270,N,53242,53245,53243,N,44268,44269,N,N,53241,
+53244,N,44981,N,N,N,54003,54005,54004,44978,53999,N,N,44976,44975,N,44979,
+44977,N,44980,54002,53997,53998,54001,54000,N,N,N,N,N,N,N,54982,54983,54981,N,
+54980,45758,46461,N,56022,56024,56026,46460,N,N,46458,N,56023,46459,56025,
+46457,N,N,57153,57079,57082,57086,47194,57084,N,57083,57080,57081,47192,57152,
+47191,N,47196,47195,47193,N,57085,N,N,N,58185,N,58184,N,N,58180,N,N,47832,
+58183,58182,47833,N,N,N,N,N,48478,N,59090,N,48479,48475,48477,N,48474,48476,N,
+N,N,60079,N,49008,60081,60080,N,58181,49010,49009,49006,49007,N,N,N,N,N,60853,
+N,60851,49482,60852,N,60854,60850,60849,N,N,61536,49834,49832,49833,N,N,N,N,
+62118,62119,50093,N,50092,62627,62628,62626,N,63224,63225,N,N,42462,51784,
+43123,N,52645,43718,43717,52646,N,N,53312,44271,53246,44272,N,N,44982,54008,
+54006,54012,44983,54007,54011,54009,54010,N,N,54984,54986,N,45759,N,54985,
+45760,46498,46497,46462,56027,N,N,N,N,57156,47197,47198,N,57155,57154,N,N,N,N,
+58186,47835,47834,58187,58188,N,48481,48480,N,60085,59091,59093,59092,60084,
+60082,60086,60083,N,49011,N,N,N,60855,49483,60856,60857,N,N,49835,49836,N,
+50293,N,N,50641,42463,N,N,N,N,N,53313,N,N,N,N,N,N,54013,44984,N,N,N,N,N,46010,
+46009,N,N,46500,56029,46499,56028,N,N,N,N,57157,N,47836,58189,47837,N,N,N,N,N,
+N,50294,62629,N,42699,43719,52647,N,44274,N,44273,53314,53315,N,N,54080,54082,
+44985,N,54084,54087,54085,N,N,N,54086,54083,54014,44986,54088,54081,N,N,N,N,
+54995,45766,55004,45763,N,54997,45767,N,45761,N,54992,55005,54993,54990,45765,
+N,45762,N,54996,54999,45764,55000,45768,55001,54991,54998,55002,54994,54989,
+54987,N,N,55003,N,N,56031,N,N,N,N,56036,N,N,N,56032,56038,46503,54988,56033,
+46501,56030,46508,56034,46507,56035,46509,46504,46510,46505,N,46506,N,46502,N,
+56037,N,N,N,N,N,N,N,47201,57168,N,57171,57159,57164,57158,47203,N,57162,N,N,N,
+57160,47202,N,57167,57166,57163,57165,57161,47841,57170,47199,57169,N,N,N,N,N,
+N,N,N,N,58205,N,47848,58200,N,47847,58190,N,58192,47840,58197,58196,58199,
+47845,58194,58193,N,N,47844,47839,58195,47842,58201,58203,N,58198,58191,47843,
+N,N,48489,47838,N,N,58204,N,N,N,N,N,N,N,59097,48482,N,59099,N,48483,N,N,48485,
+59102,N,59094,47846,59100,N,N,N,N,59096,N,47200,48488,N,N,48484,N,48486,48487,
+N,49014,59101,59095,48490,N,59098,N,N,N,N,N,60096,60091,N,N,60101,49012,60093,
+49016,60099,60090,60087,60102,49489,49017,60098,60088,49015,60092,49019,60089,
+60094,49018,60097,60100,N,N,N,N,60875,60876,60860,60867,60865,N,N,49487,60872,
+60095,N,60863,N,60873,49486,60862,60861,60871,60868,60870,N,60858,60874,49484,
+N,60869,60878,60866,49488,49485,60864,60859,60877,49013,N,N,N,N,N,N,N,61539,N,
+N,61537,61543,49840,61541,61540,49842,61546,49841,N,61547,61544,49838,61545,
+61538,49839,49837,62123,61542,N,N,61548,N,N,62120,N,N,N,50098,50096,62122,N,
+62124,62121,50097,50094,50095,50099,N,N,50296,N,62634,N,62633,62631,62630,
+62632,N,50295,50297,N,N,50416,N,N,62949,62948,N,N,63226,N,63228,63230,63229,
+63227,N,N,50595,50594,N,N,50643,50642,50644,63469,63468,N,63739,63672,63740,
+50776,N,50777,63853,N,N,50814,42700,N,52648,N,N,53317,53318,53316,N,N,44275,N,
+53319,53320,53321,N,N,54089,54095,N,N,54093,44987,54091,N,54092,54094,N,N,N,
+54090,45769,N,55006,45771,55008,45770,55007,N,N,N,N,N,56040,46511,N,56042,
+56039,55009,N,46512,N,N,56041,N,N,N,N,N,N,57174,N,47204,57172,47205,57173,
+47206,N,N,N,47849,58209,58206,58208,47850,47851,58207,N,N,N,N,N,59103,N,N,
+59104,N,48491,59106,59105,N,41569,N,60106,60107,60103,N,60104,49020,49021,
+60105,N,49495,N,N,49491,49496,49492,49494,49490,N,49493,N,N,N,N,49843,60879,N,
+62126,N,62125,N,62635,50298,50299,63297,62950,N,63296,N,63741,63908,42701,N,N,
+43124,N,52649,43720,44278,53324,44276,53322,44281,44277,44282,44280,53323,
+44279,44991,44990,54106,44999,54099,54105,44995,54098,54104,54102,44994,44996,
+54101,44989,54100,45000,44997,45001,44998,54097,54096,54103,44992,44988,44993,
+N,N,N,N,N,55024,55017,N,46517,55016,N,45775,45782,45779,45785,45784,45780,N,
+55010,55013,N,55012,45776,55014,55023,45777,55011,55020,55021,45778,55018,
+45783,45773,45781,55015,45772,55019,N,N,55022,N,N,N,56059,56050,46514,56057,
+56054,56046,56055,46516,56047,N,56043,N,N,47212,56052,N,46513,56058,N,46520,
+46522,56045,N,N,46521,56048,46515,56056,56049,56053,N,56051,46518,56044,46523,
+45774,46519,46524,N,N,N,N,N,47208,57181,57183,57185,57189,N,57179,57177,47210,
+N,57184,57188,57180,57176,N,57175,N,N,N,57186,57178,57182,47211,N,47209,57190,
+47207,57187,N,58226,N,N,N,N,N,47854,58218,48504,58228,47857,58232,47863,58213,
+N,N,58229,58210,N,58231,58214,N,47870,47867,58230,58224,47853,47861,47860,N,
+47859,47865,N,58211,47866,58225,47862,47852,58227,47855,47856,47864,58216,
+58215,58212,N,58220,58217,58221,47869,N,58233,47858,58222,58223,N,58219,N,N,N,
+47868,N,N,N,N,59111,48496,48505,48501,59108,N,48498,48502,59120,48492,59112,N,
+48500,N,N,59115,59110,48499,48503,59109,N,48497,N,59119,48494,59118,59117,
+48506,58738,48493,N,59116,59107,N,48507,59114,48495,59113,N,N,N,N,49058,49063,
+49022,60120,60111,60123,60115,60121,49064,49057,60108,60114,60124,60117,60122,
+60110,N,N,60118,49059,60116,49062,49061,60112,60113,60109,60119,49060,60126,
+60125,N,N,N,60890,60886,49503,N,60880,49497,49513,60892,49505,49501,60883,
+49508,49511,60894,49500,60885,49509,60896,60893,60881,49504,49498,49512,60888,
+49507,60882,49502,60895,49506,49499,60889,49510,60887,N,N,60891,N,N,N,61550,
+61556,49849,61559,49844,49845,61551,61558,61553,49850,49847,N,61549,N,49846,
+61555,61557,49848,61554,61552,N,N,N,N,62136,50103,50104,50100,N,50101,N,62132,
+62130,N,62134,50106,62135,62128,62127,62131,62129,50102,62133,62636,50302,
+50301,62637,N,62639,62638,50337,N,N,N,62955,62952,62953,N,62951,62954,50418,
+62956,N,50417,N,63298,N,50645,50647,63470,50646,63673,63808,63810,63742,63809,
+50796,42702,N,44283,53871,45002,N,N,45786,56060,56061,N,N,N,60127,49514,60897,
+N,N,49851,N,62138,62137,50338,62957,N,63299,50680,51785,N,N,43721,43125,N,N,
+53325,N,N,54112,54107,54111,54109,45003,54110,54108,N,55025,N,56062,56128,
+57193,57194,47214,47215,57192,57195,57191,47213,N,47936,N,47216,58234,N,48508,
+59121,48509,N,49065,60130,60128,60129,60900,60899,60898,N,N,N,62139,N,50105,
+62140,63300,50681,63674,42703,43723,43722,53327,44284,N,N,53326,54114,N,45004,
+55026,54113,N,N,N,45788,55029,55027,55028,45787,N,56130,56131,56129,N,47219,
+57197,57196,57198,47218,47217,N,N,59122,59124,N,48510,59123,60131,49066,61561,
+N,61560,50107,62141,50109,50108,62640,62958,50419,42704,53328,44285,54117,
+45006,54116,54115,N,45005,N,55035,N,55037,55030,55031,45789,55032,45790,55036,
+55033,55034,45791,N,46526,46527,N,56132,N,N,N,57199,57200,N,58238,47939,47937,
+47938,58235,58236,N,58237,59129,N,59130,48545,59127,59126,59128,59125,49069,
+60132,49067,49068,60902,49515,60901,61352,N,61562,61563,49852,N,49853,49516,
+62142,62143,62641,50339,42705,N,42706,44286,43724,45007,53329,N,N,N,46528,
+42707,44353,53330,53331,44352,44354,42708,N,53332,45009,54118,45011,45008,
+45010,N,55105,45792,N,55104,55038,N,57201,N,N,58273,N,48546,N,49070,60134,
+60133,N,60903,N,N,N,62959,N,N,42709,52083,52650,44355,53333,N,54120,N,N,N,
+45012,54119,45013,N,N,N,55107,N,N,45794,55106,55108,N,45793,N,N,N,N,56134,
+56135,56133,46529,N,N,N,47220,N,47221,N,47941,N,58275,58274,47940,N,N,N,N,N,
+59131,N,N,59132,N,N,N,N,60135,N,N,49520,49519,49517,49518,49521,N,61564,49855,
+49854,62144,62642,N,N,N,50597,50596,42710,N,N,53755,N,47223,46530,47222,47942,
+N,42711,51625,42712,42713,N,N,52651,52086,N,52087,43127,N,52084,43126,N,43129,
+52085,43131,43130,52088,43128,N,N,N,43729,43727,52653,N,43726,N,N,N,43731,
+43733,43730,N,52656,52652,43734,N,43728,43132,N,43732,52655,N,N,52654,N,43725,
+N,N,N,N,N,N,N,53339,44359,44360,53341,N,53335,53338,53347,53345,N,44361,53351,
+44364,53348,53340,53337,N,N,56137,53346,44356,53349,53334,53343,44358,44363,
+53344,44367,44365,N,53336,44362,N,53342,44366,44357,53350,N,N,N,N,N,N,45018,N,
+45027,45016,45014,54122,45022,45019,54124,N,N,45021,54123,54121,54126,45026,
+45024,56136,54127,54125,45015,N,N,45017,45020,N,45023,N,45025,N,N,N,N,N,N,N,N,
+N,N,55118,45796,N,55109,55111,N,55112,N,55120,55116,55114,N,55117,55121,45797,
+45801,55110,N,55119,N,45799,N,45798,55115,55113,N,45795,45800,N,N,N,N,N,N,N,N,
+46536,56145,N,N,56143,46538,N,N,N,N,56138,57249,N,46537,56142,N,N,56139,46533,
+46539,56144,46535,56141,47943,46534,56140,46540,46532,46531,N,N,N,N,N,57207,
+57205,N,57211,N,57203,57250,57208,N,57202,47227,47267,57213,N,57206,N,47230,N,
+N,47228,57214,47225,47224,57209,47229,46541,N,57212,57204,47226,47265,47266,N,
+N,N,N,47948,47944,N,47949,58278,N,N,58277,58279,47946,58276,47947,58282,58281,
+58280,N,47945,N,N,N,N,N,59201,N,59204,48552,59203,48551,48547,48548,48549,
+59200,59134,48550,N,59202,59133,N,N,60137,60147,49073,49072,N,60141,60143,N,
+60138,N,60142,60136,60145,49071,60144,60140,N,60146,N,60139,49524,60904,60910,
+49528,49530,49527,49526,N,49525,49523,60905,60908,49522,60909,N,49529,60907,N,
+60906,49856,N,49857,61601,61565,61566,N,N,62146,N,62145,50110,62644,50340,
+62643,N,62960,63301,50598,63811,63812,50648,42714,N,43735,56146,47950,49531,
+60911,42715,N,45029,45028,56147,N,N,N,60148,42716,44368,N,N,56148,56149,56150,
+47951,49074,42717,N,43736,53352,45030,54128,45802,N,56151,47268,N,47952,49075,
+49532,49858,62645,42718,43737,N,N,45031,55122,46542,N,47953,58283,59205,N,N,N,
+N,42719,46543,57251,47954,42720,52657,53353,44369,N,N,54130,N,N,45034,N,45032,
+45033,45035,N,N,54129,N,N,55127,55124,55126,45803,45805,45804,55123,45806,
+55125,N,56152,56153,N,56154,57254,N,57255,N,57253,57256,N,47269,N,57252,N,
+47955,N,N,59210,59206,59209,59211,59208,59207,N,60149,60150,60151,49076,49077,
+60913,60912,60914,N,61603,61602,N,62148,N,62149,62147,N,50341,N,62646,62647,N,
+63302,63471,63675,42721,43133,N,49533,42722,N,55128,56155,N,50753,51786,N,N,N,
+51787,51789,42723,51790,51788,N,N,52130,52131,52091,N,N,N,N,52129,43169,N,
+43170,52092,52090,52089,52093,43134,52094,53354,N,N,N,52662,43740,52661,52663,
+N,43739,52668,43743,52658,52672,52678,43750,52675,43747,N,52665,52671,52673,N,
+52660,43746,43741,52666,43748,43751,43745,N,43738,52670,52664,52677,43753,
+43749,43744,52669,45036,52667,43742,43752,N,52659,N,52674,52676,N,N,N,N,N,N,N,
+N,N,N,N,N,N,44386,44380,44388,44385,53361,53364,44381,N,53355,N,44374,44384,N,
+44387,44389,53410,53367,N,44373,53409,44377,44375,44370,53359,N,53374,53363,
+53366,53413,N,44390,53373,44382,53368,53412,53365,53369,53372,N,N,53357,53411,
+53371,N,N,53356,53360,44383,44378,44371,44376,44372,44391,53358,54181,44379,N,
+N,53370,52801,N,N,N,N,N,N,N,N,54184,45050,N,54134,N,54179,54141,N,54194,N,
+54186,N,54142,N,54185,54136,54140,54197,45053,54189,54180,45037,54195,54132,N,
+54188,N,45052,45047,54131,45045,45044,45049,54187,45041,45048,53362,56156,
+54182,N,N,54138,45051,54139,54177,45054,54133,54191,N,54190,54198,45043,45040,
+54196,54192,54183,54178,45046,45042,54135,45038,54193,45039,N,54137,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,55134,55136,55141,55161,45820,
+45810,N,55133,45821,45822,55144,55151,55157,N,55138,N,55145,N,N,45888,55159,
+55154,45818,45816,55150,55146,55132,45807,55137,55129,N,45815,45817,55142,
+55139,45812,55155,45809,55140,55162,55148,N,55147,45808,N,45819,N,45811,55130,
+55135,55152,55158,45889,55131,55143,55149,45814,N,N,55160,55153,55156,N,N,N,N,
+N,N,N,N,N,N,N,N,45813,N,56172,56160,46551,56189,56231,56234,46549,56168,56227,
+56169,56183,46562,56179,46559,N,56180,56157,N,56228,N,N,46568,56225,56181,
+56236,56176,57288,N,56239,46566,56174,56186,46569,46548,56178,56237,56171,
+56164,56175,N,56163,56161,46544,56229,56170,56232,N,56233,46552,46557,46553,
+46561,56190,46554,56182,56166,N,46546,56158,56226,56235,56165,46560,56240,
+56177,56173,N,46545,46565,N,56188,46567,N,56184,46556,46550,46558,46547,46564,
+56185,56167,56187,56162,56230,N,N,N,N,N,N,N,56238,N,N,N,N,N,N,N,56159,N,N,N,N,
+N,57287,N,57309,47189,57292,N,57290,57269,47273,57285,57305,57281,47281,57304,
+57279,46563,57295,57280,57302,47280,47272,N,57258,57266,N,57291,57283,57308,
+57286,47286,57303,N,47277,N,57289,57297,57270,57296,N,57313,57265,57298,N,
+57311,N,57259,46555,N,57273,57272,47279,N,57276,57278,57293,57310,47282,N,
+47283,N,57264,47275,57268,57306,47284,N,47276,47278,47285,57312,57299,57294,N,
+N,57275,57274,47274,57260,47271,57284,57261,57282,N,N,57271,57307,N,N,N,47270,
+N,N,N,57267,N,N,N,N,N,N,57263,57301,57262,47968,58323,N,N,58306,N,N,58284,
+58314,47960,58299,58309,47963,58302,47961,58287,58317,58286,58305,N,58285,N,N,
+58303,58312,58310,58298,58293,58291,N,58292,58311,58322,58300,47962,N,58295,N,
+58315,N,47965,58294,58288,58304,47969,N,N,47957,47966,58296,58290,N,47959,
+57300,47958,58307,N,47956,47971,47964,58308,58297,58289,58316,58301,47970,
+58320,47967,58319,N,58313,58318,N,N,N,58321,N,N,N,N,N,N,N,N,N,N,N,59251,59252,
+59239,59238,59234,48564,N,48556,59254,59253,57257,59231,59235,59229,N,59248,
+59233,N,59255,59226,59224,59236,59246,59241,48566,59215,N,59245,N,N,N,48567,
+57277,59227,59218,59221,59259,59228,59219,59217,59214,N,48560,59237,48559,
+48563,59232,59240,48553,59256,59260,48555,N,59223,59243,59247,59220,59257,
+48562,N,48561,59212,48565,59250,59222,59242,59216,59230,59225,48557,48558,
+59244,59261,59258,59249,N,N,N,N,N,N,N,N,N,59213,N,48554,60233,N,60224,60227,N,
+49083,60229,60153,60225,60231,49080,49084,49078,N,N,60155,60236,N,N,60230,N,
+60156,60245,60239,60152,60998,60158,49079,N,60234,N,60244,49087,N,60241,60157,
+60228,60232,60226,60246,60243,60240,49081,49082,49086,60154,60247,49085,60237,
+N,N,60235,N,N,N,60238,61011,60992,60997,61010,60996,60923,60993,N,49570,N,
+60916,61005,61007,60915,49569,61009,61001,49576,61008,60994,49578,60921,60242,
+61002,60999,60917,61013,49572,N,N,49573,60919,61000,N,61012,61003,60925,49575,
+49571,61004,60926,61014,60920,60995,61006,60922,60924,N,49867,60918,49577,
+49860,49534,N,N,N,N,49574,49864,61619,N,61609,61604,61610,61620,61624,61623,
+49866,49865,N,N,61611,61625,61614,61606,N,61608,61607,61613,61618,61605,61612,
+61617,49863,N,61615,N,49861,61616,49859,49862,62165,61621,N,N,50114,N,62157,
+62161,62153,62156,N,62164,50112,62169,62162,N,62154,62170,62163,50115,50116,
+62167,N,62155,50111,50113,62150,62158,62152,N,62168,62166,62151,62159,N,N,N,
+62654,50117,62160,50343,50345,50342,N,62659,62651,62649,62653,62650,N,N,62655,
+62657,50346,50348,N,62656,50349,50347,62658,N,N,N,N,50344,N,N,N,N,N,50420,
+62961,62967,50422,62652,62966,N,62973,62964,62971,62970,62648,62965,61622,
+62974,62963,62968,N,62972,62962,N,63306,50421,62969,N,N,63476,63307,63305,
+63303,63304,63308,N,50649,63474,63472,63477,63475,N,63478,50650,63473,N,N,
+63676,N,N,63813,63814,63815,N,N,63943,63933,51791,43754,N,44392,N,54200,54199,
+45120,45890,55164,N,N,55163,N,46570,47288,N,47287,47289,N,58324,59262,60248,
+60250,60249,N,49579,61015,61626,63909,42724,N,52681,52682,52680,52679,43755,N,
+53417,53415,N,N,53414,N,44393,44395,44394,53416,N,N,N,N,N,N,N,N,54212,54209,
+54207,N,N,45121,54210,45126,54204,54219,N,54221,54205,N,45123,54222,54217,
+54203,54208,54218,54214,54211,N,45128,54220,54206,N,N,54215,54201,45127,45124,
+54213,N,54216,54202,45125,45122,N,N,N,N,45900,55205,45899,N,55208,55211,45896,
+45894,55166,55209,55207,55204,55212,55213,55215,55216,55165,45893,55202,55201,
+55214,45895,55203,45897,45892,55206,45901,N,45898,55210,N,N,N,46577,56255,N,
+56244,46574,N,57319,56253,56241,46572,56246,46575,56250,56248,46578,46571,N,N,
+56242,56245,46576,N,56243,N,56254,56252,56247,56249,56251,46573,N,N,N,N,N,N,N,
+57320,57326,57316,57322,47290,57318,47296,N,N,47295,47294,57325,47297,47298,
+57315,57328,47299,47293,47292,57324,47300,57314,57317,57327,57323,N,N,58356,
+58345,47291,N,N,N,N,47978,58333,58354,58334,47973,N,58331,N,58340,58332,47975,
+58326,58353,47976,58350,58351,58327,47981,58342,N,58336,58343,58330,N,58355,
+58347,58341,58325,47977,58348,N,47980,58352,N,58346,47974,58344,N,58338,47972,
+58329,58337,58349,58335,N,N,58339,N,N,N,N,N,48577,57321,59314,59323,59313,
+59309,59306,48578,59304,47979,59297,48576,59303,48575,59308,59305,59321,59316,
+59310,59315,48571,59307,59326,59298,59299,59322,48572,59327,48574,59328,59312,
+58328,59318,59311,59320,59317,N,N,N,59302,48569,59325,48570,59300,48573,60260,
+59319,59324,N,N,N,N,N,60257,48568,49088,60267,60263,N,60261,60256,60271,N,N,N,
+49092,N,60252,60264,60265,60255,60254,60268,N,60258,60253,60259,N,60270,60251,
+60269,60266,49090,49089,N,N,49091,60262,61643,N,N,N,N,N,61017,49585,61021,
+61018,61025,61031,61020,N,61040,49582,61034,61023,61035,61030,61037,61022,
+49587,49586,61024,61038,61016,61036,49580,N,61028,61027,61032,61019,49584,N,
+49588,61026,61033,49589,61029,N,N,N,N,49581,49583,61639,61637,N,N,61644,61641,
+61645,N,61630,61638,61649,61039,61634,49871,59301,61629,61642,61636,61633,
+61628,61627,61648,N,61632,61631,49869,61640,N,49868,N,N,49870,61635,61647,N,
+62174,62175,N,50121,62172,50118,62180,N,50122,62182,62171,61646,62184,62173,N,
+50119,62179,N,62181,62176,62183,62178,62177,50120,N,N,62661,62662,N,62664,
+50350,50351,62665,62663,N,62660,N,63042,63045,63041,N,50426,63043,50425,50424,
+50423,63044,63313,63311,N,63310,63040,63312,63046,63309,N,63481,63447,63479,
+50651,63480,63482,N,63679,50682,63678,63677,50683,N,50778,63854,63911,63910,
+63912,42725,53418,N,54223,54224,N,N,N,56256,N,63047,63680,42726,44396,53419,N,
+N,N,55217,45902,N,56258,56257,46579,N,47301,59329,48579,N,48580,N,N,N,49093,
+50684,42727,N,N,N,53420,43757,53422,53421,44397,N,54225,N,54232,45129,54230,
+54228,N,54235,54226,54227,45130,N,45134,N,N,54236,45133,54234,54231,54229,
+45131,45132,54233,N,N,N,N,45904,55218,N,45909,55234,45908,55236,N,N,55224,
+45906,55235,N,55219,45907,55231,55227,55229,55223,55230,N,N,45903,55226,N,
+55225,55221,N,55232,N,N,55228,55220,N,55222,45905,55233,N,N,N,N,46582,56269,N,
+N,N,56265,56267,56262,56261,56259,N,56266,56268,56264,N,56263,46580,46581,N,N,
+N,N,N,N,56271,47309,57330,57336,57331,57332,N,57337,N,47311,N,47303,47310,
+57329,56260,47306,47304,57335,57334,47305,47307,57333,47302,N,47308,N,N,N,N,N,
+58358,47988,N,N,58434,58433,N,58363,47990,58432,58359,58360,47982,47984,N,
+58365,58357,47986,47985,58361,58366,58364,47987,58362,56270,47983,N,N,59330,
+59337,48582,N,59341,48586,59333,59331,N,59340,N,48581,59339,48583,48584,59332,
+48585,59338,59334,59335,59336,47989,N,N,N,60272,60284,N,49098,60279,60281,N,
+49096,60273,60277,N,60280,49094,49097,60283,60275,60276,60282,60274,60278,
+49095,61042,N,61041,49591,61047,49593,N,N,49590,61043,49594,61044,N,N,61045,
+61048,N,49592,N,61654,N,N,61657,N,61651,61653,N,N,61652,61655,61656,61046,
+61650,N,N,50125,62188,62191,62193,62186,62187,62190,62192,50126,50124,50123,
+62189,62185,62666,50352,N,62667,N,N,63049,50427,63051,50428,63048,63050,50600,
+N,63314,50599,63485,63484,N,63483,N,N,63816,63817,63819,63818,N,51792,42728,N,
+44398,55237,46583,N,57338,49872,N,62194,N,N,43171,N,N,N,45911,N,N,N,45910,N,
+56272,46584,56274,56273,N,N,57339,47312,58435,58438,58437,N,58436,59342,59344,
+59343,N,49100,N,N,N,49099,N,49595,61049,61051,61050,N,N,49873,N,N,N,62196,
+62195,N,62668,50353,N,N,50429,63316,63315,50779,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,43172,53423,44399,55240,55238,N,N,55239,56276,56277,57411,56275,N,57340,
+57409,57408,57410,47313,57342,57341,57412,N,58441,58439,N,58440,59347,59345,N,
+N,59346,60285,61052,61053,49874,N,62197,62669,50354,N,63052,63317,50601,N,
+63486,63820,43173,N,44401,44402,53424,N,N,53425,44400,N,45140,N,45138,N,45137,
+45144,45136,45145,54237,45142,N,45139,45143,45141,45135,N,N,45919,N,45913,
+55244,45918,N,N,45920,45914,N,45915,N,55242,N,N,45912,N,55243,45917,N,N,55241,
+45916,N,N,46660,N,46662,N,N,56280,46661,46585,46589,N,47332,57417,56282,46590,
+N,N,56285,56286,46659,N,56288,N,56290,N,56291,56279,56278,56292,46658,56289,
+56287,N,46656,46587,46663,56283,56284,56281,N,46657,N,N,46588,N,46586,57416,
+47327,47322,N,N,47317,N,47333,47318,N,47314,47329,47326,47328,N,47319,47324,
+47315,47316,57424,57421,57413,57418,N,47330,57425,47331,47321,N,N,57415,N,
+57423,57419,57422,57420,47325,57414,47320,N,N,N,58444,47992,47995,N,58446,N,
+48037,58445,47997,N,48591,58447,N,48036,58443,48038,N,N,N,47993,N,47323,47996,
+N,47994,47998,48034,47991,48039,48035,N,48033,58442,N,N,N,N,48598,N,48594,N,N,
+N,48601,N,59350,48602,59362,59355,48587,59363,59357,48597,59358,N,48596,59361,
+48590,59359,59349,48589,60330,48595,N,48592,N,48600,N,59348,N,59352,48588,
+59351,59353,59354,48599,59356,59360,59364,N,48603,49106,60325,60331,60328,
+60286,60332,60321,N,60327,N,49101,49107,60333,N,N,49103,N,49113,49108,60335,
+60329,49104,60322,49114,60323,60324,49115,49112,48593,N,49102,60336,49116,N,
+49109,60334,49105,49110,49111,N,49603,61092,61101,61098,61100,N,49600,61093,N,
+61099,49596,61095,49604,61091,61096,61103,60326,61097,61090,49597,61089,49598,
+61104,49599,61102,49602,61054,N,49601,N,61094,61660,61674,61669,61671,61659,
+49875,N,61658,49878,49877,N,61673,61665,61662,61668,N,61661,N,61663,61672,
+61670,N,49876,61677,61675,61666,61676,61667,N,62201,50127,62273,N,N,63055,
+50134,61664,62199,50130,62200,62205,N,N,50132,50133,62198,62272,62274,62202,
+62204,62206,62203,62275,50129,50135,50131,N,50128,62672,N,50359,62670,N,N,
+62674,N,62675,50357,62676,62673,N,62671,50360,50356,62677,N,50358,50355,N,N,N,
+50430,N,N,50496,63054,63053,63056,63057,N,50497,63318,63323,50602,N,63320,N,
+63319,63322,63321,N,63555,N,50652,63554,63552,N,63553,N,N,N,50686,50685,63681,
+63682,50752,N,63821,63822,50791,N,50797,N,63913,63944,43174,N,55245,N,55246,
+57426,58448,59365,49606,N,49605,61678,62276,N,63556,43175,54238,45146,45921,
+57428,57427,48604,59366,48605,61105,49879,N,N,N,50806,43176,52683,54239,N,N,
+45922,N,55247,55248,N,56293,N,46664,47334,N,57430,57429,57431,N,58449,58450,
+48040,49117,48606,49118,N,61109,61106,61108,61107,49607,N,61679,62278,62277,
+52132,45148,45147,54240,N,55249,N,N,56295,56294,46665,N,57433,57434,57432,N,N,
+47336,47335,N,48042,48041,N,59367,60339,60337,60338,49119,61111,61110,N,61682,
+61681,61680,62279,N,63914,43177,44403,N,44404,45149,45150,54242,54241,55250,N,
+45928,45926,45923,45927,45925,45924,N,N,46666,56298,N,47341,46668,46673,56300,
+46675,46674,46677,56299,56296,46671,46667,46669,56297,46676,46672,46670,47343,
+47342,47340,47344,N,47338,47339,N,47337,N,57435,N,N,58452,N,48044,48045,48043,
+N,58451,N,58453,N,59370,59372,N,48615,59373,48608,59369,48607,48617,48613,
+48614,48610,59368,48609,59374,59371,N,48616,N,48611,48612,60341,N,60343,60342,
+N,60344,49120,60340,N,N,49611,61112,49608,49612,49610,49609,61683,61686,N,
+61685,N,61684,49880,62280,62281,50136,62282,50137,N,N,50362,N,50361,63058,N,N,
+50498,63059,63324,50603,50604,N,63557,N,50754,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43178,N,45930,45929,57436,57437,N,48046,
+60345,48618,60346,61113,43179,N,53426,44406,44405,N,54243,45151,54244,55253,N,
+55252,N,55251,N,N,56302,46680,N,N,56301,46679,N,N,N,56303,46678,N,57439,57442,
+57440,57441,57445,57438,57446,57443,57444,48048,58454,N,N,48047,N,59378,59376,
+N,N,48619,59375,59377,N,48620,N,60347,N,60348,49613,N,62284,62286,62283,62285,
+62678,63060,N,N,63855,43180,44407,54245,54247,54246,N,55256,45932,N,55254,N,
+45931,55257,N,55258,55255,N,N,56315,46688,56307,56313,N,N,46683,46686,56306,
+46681,56310,57452,46685,N,56305,N,56311,56308,56314,56304,56312,46684,46687,
+56309,46682,N,47346,57448,47345,57455,57454,47352,N,47353,57456,47347,57453,
+47351,57458,57449,N,57451,47348,57447,57450,57457,47349,57459,N,N,N,N,N,47350,
+N,48049,58459,58465,58457,58466,N,58456,58461,58467,58464,58463,58462,N,58455,
+58460,N,N,58458,N,48625,48622,59387,59457,59459,59456,59384,59386,59461,59458,
+59388,59462,59385,59460,48623,48629,48627,59379,48628,48624,59380,59382,59381,
+59389,59390,N,48626,N,48621,N,N,59383,N,60358,49122,N,60349,49123,49126,60354,
+N,60351,49125,N,N,60355,60356,60350,60359,60352,60357,49124,N,49121,60353,N,
+61119,49616,49614,49617,49615,61118,61115,61114,N,61117,N,N,61116,61765,49886,
+61691,61690,N,49881,61761,61760,61687,61763,61692,49885,61689,61762,61688,
+49882,49884,61693,49883,61694,N,61764,62290,N,50142,62287,N,62291,N,N,50139,
+62289,50144,N,50141,N,62288,N,50143,62292,50138,N,N,N,N,50364,50366,N,62681,
+50365,62679,50140,62680,50363,50499,50501,63062,50500,63061,N,63329,50605,
+63328,50606,63326,63325,63330,63331,63558,N,63327,N,N,63686,63683,63684,63685,
+50780,N,63825,63824,63823,63856,N,63934,63915,50798,43181,45152,N,N,N,N,N,
+47354,N,N,N,N,N,N,N,48630,N,N,60360,N,N,49887,N,62293,N,N,N,N,N,N,63916,43182,
+43758,44409,44408,N,45155,N,54248,45153,54249,45154,N,N,55263,55259,N,N,45933,
+55262,55261,55260,45934,55264,55265,N,N,N,56387,56385,56389,56390,56396,N,
+56392,56394,N,56386,56316,N,56393,N,N,56395,56388,56391,56317,46690,56384,
+56318,46689,46691,N,47357,57461,57463,57462,57467,47355,N,57464,57460,57465,
+57466,47356,47358,57468,N,58471,58470,N,58468,58469,48051,48053,48050,48052,
+59469,59470,59465,N,59466,48632,48637,48631,48638,48633,59467,N,N,59468,59464,
+48704,48635,N,N,48634,48636,N,59463,N,60362,49128,N,N,60364,49130,60367,60363,
+60361,60366,49129,60365,N,49127,N,N,49619,49622,61121,N,49620,61120,49618,
+49621,61766,61767,61768,49888,N,61769,N,49889,50146,62296,62297,62295,62294,
+62298,50145,62685,62683,62684,62686,62682,62687,63064,N,63065,63063,50502,
+63332,50607,63333,63560,63559,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43183,46692,N,N,
+47424,N,N,N,48054,N,N,49132,N,49131,N,N,N,N,50147,50300,50503,43184,45156,
+47425,N,62299,N,N,N,N,N,N,N,N,N,N,52134,N,N,43185,N,43188,43187,43186,N,N,
+52133,N,52685,N,52687,43759,N,N,43761,52684,52686,43760,52689,52688,52690,N,N,
+N,N,N,N,N,N,53430,53428,44412,53427,44451,44414,44411,N,44452,N,44413,44450,N,
+44449,53429,N,44410,N,N,N,45162,54251,54257,45159,45166,N,45161,54254,54256,
+45164,54250,54253,45160,45157,54252,45163,54255,45165,45158,N,N,N,N,55267,
+55270,45936,N,45946,45942,55268,N,N,45950,45943,45948,45938,N,45935,45937,
+45949,55269,45941,45944,45940,45945,55271,45947,45939,55266,N,N,N,N,N,N,N,N,
+56397,46693,56399,N,46695,46697,N,56398,46694,46698,N,46696,N,N,N,47431,57507,
+47439,57470,N,47440,47429,N,57505,N,N,47434,N,57506,47427,47426,N,47437,47436,
+47435,47433,47438,57469,47428,47430,47432,N,N,48056,48059,N,48063,48057,48062,
+48060,N,48055,N,48061,48058,N,N,N,59474,48707,48705,N,59475,N,48708,48706,
+59473,59472,N,49136,59471,49134,49133,60368,48709,49135,60369,49138,60370,
+49137,49624,61123,49623,49628,49626,49627,49891,49625,61122,60371,49890,49892,
+N,50148,50149,N,62688,N,50654,50653,43190,N,N,51797,45167,N,51794,51795,51793,
+N,51796,N,N,52138,52135,52140,52136,43191,43194,N,52137,43193,52139,N,N,43192,
+N,N,N,N,52693,52695,43764,52691,52694,52692,43762,43765,N,43763,N,N,N,N,53432,
+53436,53433,N,44455,N,44456,N,53435,N,53437,53439,N,44453,53438,N,N,44454,N,N,
+N,N,N,55278,53434,54258,54267,54265,54260,54261,54266,54268,45169,N,54263,
+54259,45168,45170,54262,54269,54264,N,N,45985,55281,55273,55279,55280,45986,N,
+55272,55274,53431,55276,55277,55275,46700,N,N,N,56406,60372,56407,56404,45987,
+46702,56403,56409,56408,46699,56412,56402,56411,56400,56410,56405,46701,N,
+57514,N,57509,57515,57510,57508,57511,47441,N,57513,N,57512,47442,48065,48064,
+58478,58481,58473,58477,48066,58476,58474,58480,58475,58472,58479,N,59481,
+48712,61770,59478,59479,59477,56401,48711,59482,59476,48710,48713,59480,60373,
+49139,60374,60375,N,61124,49629,61771,61772,N,N,61773,62301,62300,62690,N,
+62689,63067,63068,63066,63334,50608,43195,44458,44457,45173,45172,54336,54337,
+54270,N,45171,55285,N,55286,55282,45988,55283,N,55284,N,N,N,N,56415,56417,
+56413,56416,46703,56414,46704,N,N,56691,47445,47444,N,47443,N,57516,57517,N,N,
+58483,58485,48070,48067,N,48069,48068,58484,58482,N,N,N,N,N,59489,59486,59487,
+48717,59488,59483,59484,48714,N,48715,59485,48716,N,60379,N,60380,60377,60378,
+49140,60376,N,N,N,N,N,61128,61125,61127,49632,61131,49631,61129,61132,61130,
+61126,49630,N,61775,N,61776,61774,N,61778,49893,49894,62303,50151,61777,62302,
+50150,62693,62694,50367,62692,N,62691,N,63069,50504,N,63561,63688,63687,N,
+50755,50781,63689,63857,N,50799,43196,43766,N,47446,N,50368,43197,44459,45989,
+46705,49895,43767,N,53441,53440,54338,N,45176,45174,45178,54340,N,45177,45175,
+N,N,N,N,54339,45992,55292,N,45991,45993,55362,45995,55294,55360,55287,45994,
+55363,N,N,55289,N,55290,55288,45990,N,55361,55291,55293,N,N,N,56429,N,56428,
+56426,56418,56433,56421,56431,56438,56430,46713,N,46709,56419,N,56425,46711,N,
+56424,46712,46714,56427,N,46706,46707,56439,56437,N,56436,56422,N,56434,N,
+46710,N,N,N,N,46708,56435,56420,56423,56432,N,N,N,N,N,58554,57527,N,57520,
+57539,57548,57523,47457,N,57536,47447,47449,47461,57521,N,N,47450,47452,47462,
+47451,N,N,N,N,47460,57529,N,57518,47458,57528,47454,57546,47459,57544,57532,
+57542,47456,57519,57545,57540,N,57547,47448,N,N,47463,47453,N,N,57525,N,57533,
+57537,N,57541,47455,57524,57522,57534,N,N,N,N,57531,57530,N,57535,57538,N,
+57543,N,N,N,58488,N,48071,58532,58490,48076,48080,58541,58549,58534,48072,N,
+58538,57526,N,48073,58545,58550,58542,N,58544,58553,58546,58494,58537,N,N,
+48081,N,48077,58492,58539,48075,58533,48074,58547,58530,58489,48078,58552,N,N,
+58491,58543,58540,58535,58487,58486,58529,58548,48079,58551,58493,58531,48722,
+N,N,N,N,N,48730,48725,59556,59553,59495,48720,N,N,N,48719,48726,N,N,N,59493,
+48724,59505,59491,59492,48718,59555,48728,59508,59513,59507,60398,59503,59511,
+59509,59496,59490,59517,48727,59518,N,59512,N,59501,59499,59494,N,N,N,59502,
+59515,59498,59514,59554,N,N,48723,N,59510,59516,59506,59500,48721,N,N,N,58536,
+59504,48729,59497,N,N,N,N,N,60404,49143,60403,60400,60484,49147,N,60481,60408,
+60483,60393,60406,N,49149,N,60385,N,60383,60482,N,60480,60414,60397,60396,
+60386,49216,N,60392,60402,60413,49219,60485,N,49640,49221,49150,60390,N,60399,
+60382,60384,49141,49218,49146,60391,60407,60401,49217,60381,49635,60409,60412,
+49148,N,60395,49220,49145,N,N,N,49144,60405,60411,49142,N,60388,60410,N,N,
+60389,N,N,N,N,N,N,N,N,N,60394,61138,N,61143,49637,49639,61149,49633,61164,
+61155,61144,61145,61154,N,49646,61153,61137,61152,61140,61165,49645,49643,
+61141,N,61160,N,61146,61159,N,61161,61136,49638,N,61162,N,N,61150,N,49642,
+61147,N,N,49644,61156,N,N,N,49636,61142,61157,N,61151,60387,61158,61139,N,
+49641,N,61163,N,49634,61134,N,N,N,N,61792,61785,49897,N,61780,61795,61787,
+61148,N,61797,61781,N,49896,61791,49898,49906,49904,61793,49905,61783,N,61784,
+61789,61794,N,61133,49899,61802,61799,61803,61790,61786,61800,62314,61788,N,
+49902,N,49901,61135,49903,61796,61798,49900,61801,61779,N,61782,N,N,N,N,N,N,N,
+N,62323,N,62307,50155,62321,N,N,62305,50156,N,62316,N,62312,50161,62322,62306,
+62309,50153,62324,N,62317,62320,50159,50164,50162,62313,62308,N,50157,50158,
+62304,50154,N,50152,50160,62319,50163,N,62315,62325,50165,N,N,N,62311,N,62318,
+N,N,N,N,N,N,62707,62786,62709,62716,62310,62714,62697,62784,50371,62701,62718,
+62708,N,N,50370,N,N,62788,62710,N,62715,62717,62695,62785,62706,62711,62699,
+62703,62787,62713,62696,62700,62702,62712,N,50369,62705,N,N,N,N,N,N,62698,N,N,
+N,N,N,N,N,62704,63073,63078,50511,63080,N,50505,N,63076,63082,50510,50506,N,
+50507,63072,63079,50509,63077,50508,63071,63075,63074,N,63070,63081,N,N,N,
+50609,63341,63344,63340,63342,63343,63337,63338,63335,N,N,63339,63336,50610,
+50611,N,N,63563,N,63565,N,N,N,N,N,63564,63566,N,50656,N,63562,50655,50657,N,N,
+N,63691,63692,50756,63690,N,63827,63826,63828,50783,63829,50782,63830,63858,
+63861,63860,50792,63859,N,N,N,50802,50800,50801,50807,63936,63937,63935,63945,
+43768,N,N,55364,56440,59557,62326,N,N,43769,N,44460,45179,N,N,55365,N,55366,
+45996,N,46717,56442,56441,46755,46716,56443,46718,46754,46753,46715,N,N,N,
+47464,N,N,57552,57550,N,57551,57549,N,48082,N,48085,48087,48086,N,N,48083,
+48084,N,59559,59558,48731,59560,N,59561,48732,N,N,N,60493,60491,61171,N,60489,
+60490,49222,60486,60494,60488,60492,61167,N,N,61169,N,61170,49651,61166,49650,
+61168,49647,49648,49649,60487,N,N,49909,61806,61804,61805,49907,49910,49908,N,
+N,N,62327,62328,50166,N,62789,62791,62790,50372,50512,63085,63084,63083,43770,
+N,51626,N,51800,42729,51798,51801,51799,N,N,N,52142,N,43201,N,43202,52144,
+43199,52143,52141,43200,43198,N,N,N,N,N,N,52696,52699,43773,52698,52697,N,
+43772,43771,N,43840,52700,43774,N,N,N,N,N,53446,44462,44463,44464,53447,53443,
+44461,53444,N,53445,53442,N,N,N,45220,N,N,45217,54341,45218,45221,54342,N,
+45182,45180,45181,45219,N,N,N,N,N,45997,55369,46005,55368,N,55371,46001,55370,
+46763,45999,46002,45998,46003,46004,46000,N,N,N,55367,46759,56445,N,56483,N,N,
+56482,46764,46760,46761,56444,56446,56481,46756,46758,N,46762,46757,N,N,57555,
+57553,57554,47466,47467,N,57556,47465,48088,N,48090,48089,N,58555,N,N,58556,
+59563,N,59562,N,N,49223,49224,60495,49225,N,61174,N,61172,N,61173,49652,N,
+61807,50167,N,N,N,49653,43841,N,45222,54343,N,N,55372,46006,46765,56484,56486,
+46767,46766,46768,46769,56485,47470,47471,47469,48091,47468,57557,N,N,N,48092,
+59564,60496,49226,49654,61808,61812,49913,61809,49914,49912,61813,49915,61811,
+N,62329,49911,50168,N,63693,N,N,43842,46008,46007,N,N,N,N,46770,56488,56487,
+46771,N,N,57561,47475,47472,57560,47474,57558,47473,N,57559,N,58557,48093,N,
+59567,N,48733,59565,48734,48735,59566,48736,N,60497,N,49230,49227,49232,60499,
+49228,60498,49231,N,N,49229,N,61177,61179,N,N,49655,61178,49656,61176,61175,N,
+61815,61814,49916,61816,62334,50170,62333,62330,50169,62331,62332,N,62792,
+62793,50373,N,50515,N,N,63086,N,N,50513,50514,63087,N,N,50612,50613,63345,N,N,
+50757,63695,50759,N,63694,63696,50758,63831,N,63917,N,N,N,N,N,N,43843,N,N,N,
+47476,N,58558,N,59568,49233,49234,N,43844,N,48737,50171,44465,N,N,N,49235,N,
+50658,44466,55373,N,56489,N,56491,N,56490,N,57565,57562,47477,N,47478,57563,
+57564,N,58560,58565,48094,58559,58561,58568,58563,58567,58564,58562,58566,
+48095,N,N,59571,N,59569,48739,N,48738,59570,48740,N,N,N,N,60502,N,N,60501,
+49236,60500,61180,N,61182,61249,61248,N,49657,61181,61857,49917,61821,61858,
+49918,N,61819,N,61822,61820,61817,49984,61818,N,N,N,N,62369,N,N,62371,62370,N,
+62794,N,62795,N,N,N,63088,N,50615,N,50614,63567,63568,50760,63697,N,50793,N,
+44467,46772,58570,58569,59573,59572,N,N,49658,61251,61250,61861,61859,61862,
+61860,N,N,50172,62372,62373,62374,N,63089,N,63346,N,63698,N,N,N,N,N,N,N,44468,
+N,N,60503,61252,N,44469,N,N,48096,N,60504,49985,61863,50173,N,62796,62797,
+50516,63569,44470,46011,46012,55374,46773,46774,56492,46775,N,47482,N,47484,
+57567,57568,57566,47479,47480,47483,47481,N,N,58571,48097,48098,N,N,59580,
+48743,59575,59574,N,59579,48741,N,N,49243,N,59576,59581,59578,59577,N,48742,N,
+49241,N,60506,49237,N,60507,N,N,60505,N,49240,49238,49242,N,49239,N,N,N,N,N,
+61253,N,61258,61254,61257,49659,N,60884,61256,61255,N,49988,49986,49989,49987,
+61864,61865,61866,49990,N,N,N,62378,50240,62376,N,50241,62375,62377,50174,
+62801,62798,N,62799,62800,63090,50518,N,50517,N,63348,63347,50616,N,N,N,50659,
+50761,50784,63832,63918,63919,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44471,56493,N,N,57569,
+58572,58573,48099,N,48100,59582,48744,N,N,49660,N,61867,N,49991,62381,50242,
+62380,62382,62379,63093,62802,62803,N,50374,N,63092,N,N,63091,N,63349,63920,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,44472,N,N,N,44473,N,N,45223,54344,N,55375,N,46776,N,
+46779,46777,56494,N,46781,N,46778,N,N,46780,N,47486,N,57570,N,N,57571,59584,N,
+47485,47521,47522,58575,N,58574,48101,N,48102,N,58576,59583,48104,48745,N,
+48103,N,N,N,49244,59585,48747,48746,59586,59589,59587,59588,48748,N,49249,
+49247,N,N,49246,60509,N,49248,N,N,60508,61259,N,60510,49245,60511,61262,61260,
+61261,61266,49995,61265,61268,61267,61264,61263,N,49661,N,N,N,N,61870,N,61869,
+49994,49992,49993,N,61868,N,62385,N,50243,N,62384,62383,50244,N,62808,62807,N,
+62805,N,62804,50376,50375,62809,63350,50617,63095,50519,63094,62806,N,63351,
+50660,N,50785,63833,N,63921,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44474,55376,61269,44475,
+N,N,58578,58577,60512,N,N,61271,N,61270,N,49996,62386,62387,50377,N,N,63922,
+45224,46783,46782,57572,57574,47524,57573,47523,47525,57575,N,N,N,58580,58582,
+58581,N,58584,N,N,N,48105,58583,58579,N,N,N,58585,N,59596,N,59599,59601,59591,
+59595,59592,48750,48753,48755,59593,59594,48754,59597,59600,59598,48756,N,
+48752,59590,48749,N,48751,N,N,49251,60518,60516,60515,N,60521,N,60520,60519,N,
+60514,49250,60513,N,60517,49252,N,N,61274,N,61278,61275,61277,61276,61273,
+61279,61282,61280,61281,49728,49662,61272,61283,61875,61878,61880,61879,N,
+61873,61877,61872,N,61874,49997,61871,N,61876,N,N,62400,62389,50245,N,N,50246,
+62388,62393,62399,62391,62398,N,62395,N,62394,62397,62392,62390,N,62396,N,
+62816,62814,50378,62813,62819,62817,N,50379,62812,62810,N,62811,50381,62815,
+50380,62818,63096,63102,N,N,63097,50523,63137,50522,63101,63100,50521,63099,
+50520,63098,N,63357,63393,63358,N,63355,50619,63352,63356,63395,N,63394,63353,
+63354,50618,63570,50663,N,63571,50661,50662,N,N,63699,50762,63862,N,50794,N,
+63923,50795,63924,63925,63939,63938,50810,63949,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,45225,N,N,57577,N,57576,N,48106,48107,58586,N,59602,60524,N,N,
+48757,49253,60522,N,60525,49254,N,61284,60523,61881,49998,62401,N,N,N,62822,
+62820,N,N,62821,N,N,63138,N,50524,63396,50666,50620,50664,50665,63700,50786,N,
+45226,N,N,N,61882,N,N,54345,N,47526,N,58587,N,N,48108,58588,N,N,N,59604,59603,
+49256,48758,48759,N,59607,59606,59605,N,N,60526,60529,N,60528,60527,49255,
+61288,61286,61285,61287,N,49999,61884,61885,50000,N,61883,N,62403,62402,62405,
+50247,62404,N,62823,62825,62824,N,N,63139,63142,63140,63141,63397,50621,N,N,N,
+63572,63573,63574,N,50763,50787,63926,45227,N,48760,49257,61886,N,63398,N,N,
+63940,54346,N,50811,45228,60530,N,61887,N,62406,N,N,63143,63399,45229,N,58589,
+58590,N,48109,48110,59609,48762,48761,59608,N,61289,N,61888,61890,61889,50003,
+50002,50001,N,50526,63144,N,50525,63401,63400,N,50764,63701,46013,57578,N,N,N,
+58593,58591,58592,N,N,59618,N,59613,59610,59617,N,N,N,59619,N,N,48764,59616,
+59612,N,N,59611,59615,59614,48763,N,N,60541,60536,60534,60577,60535,N,60531,N,
+60537,N,N,60532,61298,60533,60578,N,N,N,N,N,N,N,60540,49258,60539,60538,N,
+60542,N,N,N,N,61290,61293,N,N,61292,N,61300,61295,61299,N,61297,61296,61294,N,
+61291,N,49731,49730,N,49732,49729,61301,N,N,N,N,N,61896,61899,N,61897,61901,N,
+N,N,61902,N,61894,50008,61895,N,61893,61900,N,61892,61891,50007,50005,50004,N,
+N,N,N,N,N,N,N,61898,62415,62421,50250,62416,N,62419,62423,50251,62418,N,62410,
+N,62409,62422,62413,N,62411,62420,62412,50249,50248,N,62407,62408,62417,N,N,N,
+62414,N,N,N,N,N,N,62828,62831,N,N,N,N,50006,62829,62835,62833,62827,62838,N,
+62826,N,50383,62834,N,N,N,62830,50382,62837,N,N,62836,N,N,N,N,63147,63146,N,N,
+N,63153,N,63149,63152,50528,N,N,63150,63151,N,63145,63148,50527,N,N,N,50623,
+63412,63407,63411,N,63414,63410,N,63406,N,50625,63409,63413,50624,63404,62832,
+63408,N,N,63405,N,63402,N,63403,50622,63578,63580,63583,63579,63584,N,63577,N,
+63575,N,50667,63581,50669,50668,63576,63582,N,N,N,N,63706,50765,63707,N,63705,
+63702,N,N,63704,63703,63834,N,N,N,N,63836,63835,N,N,63865,N,63864,63863,63866,
+N,50803,50804,63946,63950,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,46014,56495,57581,N,47527,57579,N,N,57580,N,N,N,58594,58595,48113,48111,
+58596,48112,59624,N,59627,59621,59628,59620,59622,N,59623,59626,N,N,48801,
+59631,59630,48765,59625,59629,48766,N,N,N,N,N,N,60588,N,49263,N,60583,49259,N,
+60580,60586,60589,N,49264,N,60585,60582,60590,60581,N,60587,49260,N,60579,
+49261,N,49262,60584,N,N,N,61353,61306,61307,61310,61308,N,61302,N,N,61305,
+61349,61309,N,N,49733,N,61351,61348,49734,61350,61303,61346,61347,N,61345,N,N,
+N,N,61906,61908,61911,N,N,61905,N,50009,61913,61904,61914,N,61910,61912,61916,
+61909,61917,61907,61903,50010,N,61915,50011,50253,N,N,N,N,N,61304,62449,62440,
+50255,62436,50256,N,N,62445,62439,62429,50254,62442,62437,62438,N,62424,62431,
+62446,N,62443,N,62435,N,62447,62430,62425,62444,N,62427,62441,62432,62448,
+62428,50252,62426,62433,62434,N,N,N,62845,N,62843,N,62882,N,62894,62885,62844,
+62840,62887,62846,62883,62842,62890,62839,62881,62886,62888,62891,62841,N,
+62895,62896,62889,62893,62884,N,63169,63172,N,50529,N,63171,63176,63174,50530,
+63165,63155,63154,50532,63167,63168,63164,63156,N,63161,62892,N,63157,50531,
+63163,N,63162,N,63158,63170,N,63159,63419,63173,63175,63166,63160,63420,63422,
+63416,50626,N,63429,63427,50627,63426,63425,63418,63415,63421,63430,63417,
+63423,N,63593,63598,63588,63591,50670,63595,N,63602,63424,N,63589,63599,63603,
+63594,63587,63597,N,63596,63601,63600,63428,63592,63586,63590,50766,50767,
+63585,N,63718,63709,63717,63714,63715,63708,63711,63719,63713,63712,63710,N,
+63716,N,63837,N,63838,N,63840,63839,63842,63841,63868,63867,63927,N,63928,N,
+63941,50808,50812,N,63951,50813,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,46015,N,N,N,50384,63177,N,
+50768,50769,N,46016,57582,N,47528,59632,N,N,60592,60593,60591,61355,61354,
+49735,61919,61356,61918,N,N,62451,50257,50259,62450,N,N,50258,N,62897,62899,
+62898,63178,50533,N,50671,63720,63843,N,N,63954,46017,N,58597,N,48802,N,N,N,
+60595,60594,N,61357,N,N,N,50260,50385,63431,63947,N,N,N,46018,48114,N,48803,N,
+62452,N,63604,46784,N,N,N,N,61358,N,N,N,50788,46785,48804,49736,63605,46786,N,
+59633,49266,60596,60597,N,49265,N,61359,49740,49738,49739,49737,61920,50012,N,
+N,N,62901,62900,62903,62902,50386,N,N,63179,N,63181,63180,50534,63432,N,63606,
+63607,50672,63844,63869,50805,N,56496,60598,61360,62453,57583,N,61361,61922,
+61921,N,N,N,N,63608,50770,N,63845,63870,N,N,N,47529,59634,59635,N,60599,47530,
+N,50013,61923,N,63183,50535,63184,63182,63609,N,63721,N,47531,N,61364,61363,
+61362,61924,N,N,61928,61927,61926,61925,50014,62454,62905,50387,62904,63185,
+63435,63434,50628,63433,63612,63611,63610,N,N,48115,N,60600,49741,N,62455,
+62456,63436,63613,N,N,63722,63846,63929,63956,48116,49742,61929,62457,63186,
+63614,N,N,48806,N,61365,61930,62458,62459,62460,62910,N,62906,50536,62909,
+62908,50388,62907,50390,N,50389,63188,63187,50537,50538,N,N,50630,63437,50629,
+N,63651,63652,63650,63649,50772,N,63723,63724,63725,50771,63847,63850,63849,
+63848,N,N,63955,N,N,N,N,N,N,N,N,N,N,N,N,N,N,49267,N,N,50021,62911,63189,N,
+50631,63438,N,N,63957,N,N,N,49268,N,N,N,61366,N,63439,N,63905,51530,56828,
+41290,41303,N,41305,41307,41311,41312,41315,41316,41319,41320,41323,41324,
+41327,41328,41331,41332,41335,41336,41339,41340,N,N,N,N,41414,41415,41418,
+41419,41416,41417,41308,41293,N,41295,N,41297,41298,41299,41300,N,41341,41342,
+41377,41378,41379,41380,41420,41421,41422,41438,41439,41440,41441,41442,N,N,
+41548,41549,41550,41289,N,41389,41539,41544,41390,N,41309,41310,41391,41423,
+41281,41424,41284,41537,41647,41648,41649,41650,41651,41652,41653,41654,41655,
+41656,41287,41286,41429,41431,41430,41288,41545,41679,41680,41681,41682,41683,
+41684,41685,41686,41687,41688,41689,41690,41691,41692,41693,41694,41695,41696,
+41697,41698,41699,41700,41701,41702,41703,41704,N,41538,N,N,41412,N,41705,
+41706,41707,41708,41709,41710,41711,41712,41713,41714,41715,41716,41717,41718,
+41719,41720,41721,41722,41723,41724,41725,41726,41792,41793,41794,41795,41313,
+41301,41314,N,N,N,N,N,N,41294,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41411,
+};
+
+static const struct unim_index big5_encmap[256] = {
+{__big5_encmap+0,162,247},{0,0,0},{__big5_encmap+86,199,217},{__big5_encmap+
+105,145,201},{__big5_encmap+162,1,81},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
+{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{__big5_encmap+243,19,62},{__big5_encmap+287,3,153},{
+__big5_encmap+438,26,191},{0,0,0},{__big5_encmap+604,96,125},{__big5_encmap+
+634,0,229},{__big5_encmap+864,5,66},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{__big5_encmap+926,0,254},{__big5_encmap+1181,
+5,41},{__big5_encmap+1218,163,163},{__big5_encmap+1219,142,213},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__big5_encmap+1291,0,255},{
+__big5_encmap+1547,0,254},{__big5_encmap+1802,0,255},{__big5_encmap+2058,0,253
+},{__big5_encmap+2312,0,255},{__big5_encmap+2568,5,252},{__big5_encmap+2816,1,
+255},{__big5_encmap+3071,1,255},{__big5_encmap+3326,0,255},{__big5_encmap+3582
+,1,253},{__big5_encmap+3835,0,255},{__big5_encmap+4091,3,255},{__big5_encmap+
+4344,0,255},{__big5_encmap+4600,1,250},{__big5_encmap+4850,1,255},{
+__big5_encmap+5105,0,255},{__big5_encmap+5361,2,255},{__big5_encmap+5615,1,255
+},{__big5_encmap+5870,0,255},{__big5_encmap+6126,0,255},{__big5_encmap+6382,0,
+255},{__big5_encmap+6638,0,249},{__big5_encmap+6888,6,255},{__big5_encmap+7138
+,0,253},{__big5_encmap+7392,0,255},{__big5_encmap+7648,0,255},{__big5_encmap+
+7904,18,253},{__big5_encmap+8140,4,255},{__big5_encmap+8392,0,252},{
+__big5_encmap+8645,0,255},{__big5_encmap+8901,0,249},{__big5_encmap+9151,0,253
+},{__big5_encmap+9405,0,255},{__big5_encmap+9661,0,255},{__big5_encmap+9917,0,
+255},{__big5_encmap+10173,0,255},{__big5_encmap+10429,1,255},{__big5_encmap+
+10684,0,255},{__big5_encmap+10940,0,255},{__big5_encmap+11196,0,255},{
+__big5_encmap+11452,0,254},{__big5_encmap+11707,1,253},{__big5_encmap+11960,2,
+255},{__big5_encmap+12214,1,251},{__big5_encmap+12465,0,255},{__big5_encmap+
+12721,0,255},{__big5_encmap+12977,0,254},{__big5_encmap+13232,0,251},{
+__big5_encmap+13484,3,156},{__big5_encmap+13638,54,255},{__big5_encmap+13840,
+0,254},{__big5_encmap+14095,0,255},{__big5_encmap+14351,0,254},{__big5_encmap+
+14606,0,255},{__big5_encmap+14862,1,255},{__big5_encmap+15117,0,255},{
+__big5_encmap+15373,0,254},{__big5_encmap+15628,0,255},{__big5_encmap+15884,0,
+254},{__big5_encmap+16139,1,255},{__big5_encmap+16394,0,255},{__big5_encmap+
+16650,0,159},{__big5_encmap+16810,55,254},{__big5_encmap+17010,0,255},{
+__big5_encmap+17266,0,255},{__big5_encmap+17522,0,255},{__big5_encmap+17778,0,
+255},{__big5_encmap+18034,0,255},{__big5_encmap+18290,0,255},{__big5_encmap+
+18546,0,255},{__big5_encmap+18802,0,131},{__big5_encmap+18934,119,229},{
+__big5_encmap+19045,28,255},{__big5_encmap+19273,0,255},{__big5_encmap+19529,
+0,254},{__big5_encmap+19784,0,255},{__big5_encmap+20040,1,254},{__big5_encmap+
+20294,1,253},{__big5_encmap+20547,5,255},{__big5_encmap+20798,0,255},{
+__big5_encmap+21054,0,255},{__big5_encmap+21310,0,164},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{__big5_encmap+21475,12,13},{0,0,0},{0,0,0},{0,0,0},{__big5_encmap+21477,48,
+107},{__big5_encmap+21537,1,227},
+};
+
+static const ucs2_t __cp950ext_decmap[224] = {
+8231,U,U,U,U,U,U,U,U,65105,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,175,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,65374,U,U,U,U,U,U,U,U,U,U,U,U,U,U,8853,8857,8725,65128,U,65509,
+U,65504,65505,8364,30849,37561,35023,22715,24658,31911,23290,9556,9574,9559,
+9568,9580,9571,9562,9577,9565,9554,9572,9557,9566,9578,9569,9560,9575,9563,
+9555,9573,9558,9567,9579,9570,9561,9576,9564,9553,9552,9581,9582,9584,9583,
+9619,
+};
+
+static const struct dbcs_index cp950ext_decmap[256] = {
+{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp950ext_decmap+0,69,243
+},{__cp950ext_decmap+175,65,71},{__cp950ext_decmap+182,225,225},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp950ext_decmap+183,214,254
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
+};
+
+static const DBCHAR __cp950ext_encmap[581] = {
+41410,41285,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41953,41537,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+41458,N,N,N,41459,63992,63974,63983,63965,63976,63985,63967,63980,63989,63971,
+63982,63991,63973,N,63986,63968,N,63988,63970,63975,63984,63966,63981,63990,
+63972,N,63987,63969,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,63998,63961,63964,63962,63958,63963,63960,63959,41294,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41538,41470,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41536,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41443,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,41542,41543,N,N,N,41540,
+};
+
+static const struct unim_index cp950ext_encmap[256] = {
+{__cp950ext_encmap+0,175,175},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
+{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp950ext_encmap+1,39,172},{0,
+0,0},{__cp950ext_encmap+135,21,153},{0,0,0},{0,0,0},{__cp950ext_encmap+268,81,
+147},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{__cp950ext_encmap+335,187,187},{0,0,0},{__cp950ext_encmap+
+336,250,250},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp950ext_encmap+337,
+82,82},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp950ext_encmap+338,129,129},{0,0,0},{
+0,0,0},{0,0,0},{__cp950ext_encmap+339,167,167},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp950ext_encmap+
+340,207,207},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{__cp950ext_encmap+341,185,185},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp950ext_encmap+342,81,104},{
+__cp950ext_encmap+366,15,229},
+};

Added: vendor/Python/current/Modules/cjkcodecs/multibytecodec.c
===================================================================
--- vendor/Python/current/Modules/cjkcodecs/multibytecodec.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/cjkcodecs/multibytecodec.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1793 @@
+/*
+ * multibytecodec.c: Common Multibyte Codec Implementation
+ *
+ * Written by Hye-Shik Chang <perky at FreeBSD.org>
+ */
+
+#define PY_SSIZE_T_CLEAN
+#include "Python.h"
+#include "structmember.h"
+#include "multibytecodec.h"
+
+typedef struct {
+    const Py_UNICODE    *inbuf, *inbuf_top, *inbuf_end;
+    unsigned char       *outbuf, *outbuf_end;
+    PyObject            *excobj, *outobj;
+} MultibyteEncodeBuffer;
+
+typedef struct {
+    const unsigned char *inbuf, *inbuf_top, *inbuf_end;
+    Py_UNICODE          *outbuf, *outbuf_end;
+    PyObject            *excobj, *outobj;
+} MultibyteDecodeBuffer;
+
+PyDoc_STRVAR(MultibyteCodec_Encode__doc__,
+"I.encode(unicode[, errors]) -> (string, length consumed)\n\
+\n\
+Return an encoded string version of `unicode'. errors may be given to\n\
+set a different error handling scheme. Default is 'strict' meaning that\n\
+encoding errors raise a UnicodeEncodeError. Other possible values are\n\
+'ignore', 'replace' and 'xmlcharrefreplace' as well as any other name\n\
+registered with codecs.register_error that can handle UnicodeEncodeErrors.");
+
+PyDoc_STRVAR(MultibyteCodec_Decode__doc__,
+"I.decode(string[, errors]) -> (unicodeobject, length consumed)\n\
+\n\
+Decodes `string' using I, an MultibyteCodec instance. errors may be given\n\
+to set a different error handling scheme. Default is 'strict' meaning\n\
+that encoding errors raise a UnicodeDecodeError. Other possible values\n\
+are 'ignore' and 'replace' as well as any other name registerd with\n\
+codecs.register_error that is able to handle UnicodeDecodeErrors.");
+
+static char *codeckwarglist[] = {"input", "errors", NULL};
+static char *incnewkwarglist[] = {"errors", NULL};
+static char *incrementalkwarglist[] = {"input", "final", NULL};
+static char *streamkwarglist[] = {"stream", "errors", NULL};
+
+static PyObject *multibytecodec_encode(MultibyteCodec *,
+		MultibyteCodec_State *, const Py_UNICODE **, Py_ssize_t,
+		PyObject *, int);
+
+#define MBENC_RESET	MBENC_MAX<<1 /* reset after an encoding session */
+
+static PyObject *
+make_tuple(PyObject *object, Py_ssize_t len)
+{
+	PyObject *v, *w;
+
+	if (object == NULL)
+		return NULL;
+
+	v = PyTuple_New(2);
+	if (v == NULL) {
+		Py_DECREF(object);
+		return NULL;
+	}
+	PyTuple_SET_ITEM(v, 0, object);
+
+	w = PyInt_FromSsize_t(len);
+	if (w == NULL) {
+		Py_DECREF(v);
+		return NULL;
+	}
+	PyTuple_SET_ITEM(v, 1, w);
+
+	return v;
+}
+
+static PyObject *
+internal_error_callback(const char *errors)
+{
+	if (errors == NULL || strcmp(errors, "strict") == 0)
+		return ERROR_STRICT;
+	else if (strcmp(errors, "ignore") == 0)
+		return ERROR_IGNORE;
+	else if (strcmp(errors, "replace") == 0)
+		return ERROR_REPLACE;
+	else
+		return PyString_FromString(errors);
+}
+
+static PyObject *
+call_error_callback(PyObject *errors, PyObject *exc)
+{
+	PyObject *args, *cb, *r;
+
+	assert(PyString_Check(errors));
+	cb = PyCodec_LookupError(PyString_AS_STRING(errors));
+	if (cb == NULL)
+		return NULL;
+
+	args = PyTuple_New(1);
+	if (args == NULL) {
+		Py_DECREF(cb);
+		return NULL;
+	}
+
+	PyTuple_SET_ITEM(args, 0, exc);
+	Py_INCREF(exc);
+
+	r = PyObject_CallObject(cb, args);
+	Py_DECREF(args);
+	Py_DECREF(cb);
+	return r;
+}
+
+static PyObject *
+codecctx_errors_get(MultibyteStatefulCodecContext *self)
+{
+	const char *errors;
+
+	if (self->errors == ERROR_STRICT)
+		errors = "strict";
+	else if (self->errors == ERROR_IGNORE)
+		errors = "ignore";
+	else if (self->errors == ERROR_REPLACE)
+		errors = "replace";
+	else {
+		Py_INCREF(self->errors);
+		return self->errors;
+	}
+
+	return PyString_FromString(errors);
+}
+
+static int
+codecctx_errors_set(MultibyteStatefulCodecContext *self, PyObject *value,
+		    void *closure)
+{
+	PyObject *cb;
+
+	if (!PyString_Check(value)) {
+		PyErr_SetString(PyExc_TypeError, "errors must be a string");
+		return -1;
+	}
+
+	cb = internal_error_callback(PyString_AS_STRING(value));
+	if (cb == NULL)
+		return -1;
+
+	ERROR_DECREF(self->errors);
+	self->errors = cb;
+	return 0;
+}
+
+/* This getset handlers list is used by all the stateful codec objects */
+static PyGetSetDef codecctx_getsets[] = {
+	{"errors",	(getter)codecctx_errors_get,
+			(setter)codecctx_errors_set,
+			PyDoc_STR("how to treat errors")},
+	{NULL,}
+};
+
+static int
+expand_encodebuffer(MultibyteEncodeBuffer *buf, Py_ssize_t esize)
+{
+	Py_ssize_t orgpos, orgsize;
+
+	orgpos = (Py_ssize_t)((char *)buf->outbuf -
+				PyString_AS_STRING(buf->outobj));
+	orgsize = PyString_GET_SIZE(buf->outobj);
+	if (_PyString_Resize(&buf->outobj, orgsize + (
+	    esize < (orgsize >> 1) ? (orgsize >> 1) | 1 : esize)) == -1)
+		return -1;
+
+	buf->outbuf = (unsigned char *)PyString_AS_STRING(buf->outobj) +orgpos;
+	buf->outbuf_end = (unsigned char *)PyString_AS_STRING(buf->outobj)
+		+ PyString_GET_SIZE(buf->outobj);
+
+	return 0;
+}
+#define REQUIRE_ENCODEBUFFER(buf, s) {					\
+	if ((s) < 1 || (buf)->outbuf + (s) > (buf)->outbuf_end)		\
+		if (expand_encodebuffer(buf, s) == -1)			\
+			goto errorexit;					\
+}
+
+static int
+expand_decodebuffer(MultibyteDecodeBuffer *buf, Py_ssize_t esize)
+{
+	Py_ssize_t orgpos, orgsize;
+
+	orgpos = (Py_ssize_t)(buf->outbuf - PyUnicode_AS_UNICODE(buf->outobj));
+	orgsize = PyUnicode_GET_SIZE(buf->outobj);
+	if (PyUnicode_Resize(&buf->outobj, orgsize + (
+	    esize < (orgsize >> 1) ? (orgsize >> 1) | 1 : esize)) == -1)
+		return -1;
+
+	buf->outbuf = PyUnicode_AS_UNICODE(buf->outobj) + orgpos;
+	buf->outbuf_end = PyUnicode_AS_UNICODE(buf->outobj)
+			  + PyUnicode_GET_SIZE(buf->outobj);
+
+	return 0;
+}
+#define REQUIRE_DECODEBUFFER(buf, s) {					\
+	if ((s) < 1 || (buf)->outbuf + (s) > (buf)->outbuf_end)		\
+		if (expand_decodebuffer(buf, s) == -1)			\
+			goto errorexit;					\
+}
+
+
+/**
+ * MultibyteCodec object
+ */
+
+static int
+multibytecodec_encerror(MultibyteCodec *codec,
+			MultibyteCodec_State *state,
+			MultibyteEncodeBuffer *buf,
+			PyObject *errors, Py_ssize_t e)
+{
+	PyObject *retobj = NULL, *retstr = NULL, *tobj;
+	Py_ssize_t retstrsize, newpos;
+	Py_ssize_t esize, start, end;
+	const char *reason;
+
+	if (e > 0) {
+		reason = "illegal multibyte sequence";
+		esize = e;
+	}
+	else {
+		switch (e) {
+		case MBERR_TOOSMALL:
+			REQUIRE_ENCODEBUFFER(buf, -1);
+			return 0; /* retry it */
+		case MBERR_TOOFEW:
+			reason = "incomplete multibyte sequence";
+			esize = (Py_ssize_t)(buf->inbuf_end - buf->inbuf);
+			break;
+		case MBERR_INTERNAL:
+			PyErr_SetString(PyExc_RuntimeError,
+					"internal codec error");
+			return -1;
+		default:
+			PyErr_SetString(PyExc_RuntimeError,
+					"unknown runtime error");
+			return -1;
+		}
+	}
+
+	if (errors == ERROR_REPLACE) {
+		const Py_UNICODE replchar = '?', *inbuf = &replchar;
+		Py_ssize_t r;
+
+		for (;;) {
+			Py_ssize_t outleft;
+
+			outleft = (Py_ssize_t)(buf->outbuf_end - buf->outbuf);
+			r = codec->encode(state, codec->config, &inbuf, 1,
+					  &buf->outbuf, outleft, 0);
+			if (r == MBERR_TOOSMALL) {
+				REQUIRE_ENCODEBUFFER(buf, -1);
+				continue;
+			}
+			else
+				break;
+		}
+
+		if (r != 0) {
+			REQUIRE_ENCODEBUFFER(buf, 1);
+			*buf->outbuf++ = '?';
+		}
+	}
+	if (errors == ERROR_IGNORE || errors == ERROR_REPLACE) {
+		buf->inbuf += esize;
+		return 0;
+	}
+
+	start = (Py_ssize_t)(buf->inbuf - buf->inbuf_top);
+	end = start + esize;
+
+	/* use cached exception object if available */
+	if (buf->excobj == NULL) {
+		buf->excobj = PyUnicodeEncodeError_Create(codec->encoding,
+				buf->inbuf_top,
+				buf->inbuf_end - buf->inbuf_top,
+				start, end, reason);
+		if (buf->excobj == NULL)
+			goto errorexit;
+	}
+	else
+		if (PyUnicodeEncodeError_SetStart(buf->excobj, start) != 0 ||
+		    PyUnicodeEncodeError_SetEnd(buf->excobj, end) != 0 ||
+		    PyUnicodeEncodeError_SetReason(buf->excobj, reason) != 0)
+			goto errorexit;
+
+	if (errors == ERROR_STRICT) {
+		PyCodec_StrictErrors(buf->excobj);
+		goto errorexit;
+	}
+
+	retobj = call_error_callback(errors, buf->excobj);
+	if (retobj == NULL)
+		goto errorexit;
+
+	if (!PyTuple_Check(retobj) || PyTuple_GET_SIZE(retobj) != 2 ||
+	    !PyUnicode_Check((tobj = PyTuple_GET_ITEM(retobj, 0))) ||
+	    !(PyInt_Check(PyTuple_GET_ITEM(retobj, 1)) ||
+	      PyLong_Check(PyTuple_GET_ITEM(retobj, 1)))) {
+		PyErr_SetString(PyExc_TypeError,
+				"encoding error handler must return "
+				"(unicode, int) tuple");
+		goto errorexit;
+	}
+
+	{
+		const Py_UNICODE *uraw = PyUnicode_AS_UNICODE(tobj);
+
+		retstr = multibytecodec_encode(codec, state, &uraw,
+				PyUnicode_GET_SIZE(tobj), ERROR_STRICT,
+				MBENC_FLUSH);
+		if (retstr == NULL)
+			goto errorexit;
+	}
+
+	retstrsize = PyString_GET_SIZE(retstr);
+	REQUIRE_ENCODEBUFFER(buf, retstrsize);
+
+	memcpy(buf->outbuf, PyString_AS_STRING(retstr), retstrsize);
+	buf->outbuf += retstrsize;
+
+	newpos = PyInt_AsSsize_t(PyTuple_GET_ITEM(retobj, 1));
+	if (newpos < 0 && !PyErr_Occurred())
+		newpos += (Py_ssize_t)(buf->inbuf_end - buf->inbuf_top);
+	if (newpos < 0 || buf->inbuf_top + newpos > buf->inbuf_end) {
+		PyErr_Clear();
+		PyErr_Format(PyExc_IndexError,
+			     "position %zd from error handler out of bounds",
+			     newpos);
+		goto errorexit;
+	}
+	buf->inbuf = buf->inbuf_top + newpos;
+
+	Py_DECREF(retobj);
+	Py_DECREF(retstr);
+	return 0;
+
+errorexit:
+	Py_XDECREF(retobj);
+	Py_XDECREF(retstr);
+	return -1;
+}
+
+static int
+multibytecodec_decerror(MultibyteCodec *codec,
+			MultibyteCodec_State *state,
+			MultibyteDecodeBuffer *buf,
+			PyObject *errors, Py_ssize_t e)
+{
+	PyObject *retobj = NULL, *retuni = NULL;
+	Py_ssize_t retunisize, newpos;
+	const char *reason;
+	Py_ssize_t esize, start, end;
+
+	if (e > 0) {
+		reason = "illegal multibyte sequence";
+		esize = e;
+	}
+	else {
+		switch (e) {
+		case MBERR_TOOSMALL:
+			REQUIRE_DECODEBUFFER(buf, -1);
+			return 0; /* retry it */
+		case MBERR_TOOFEW:
+			reason = "incomplete multibyte sequence";
+			esize = (Py_ssize_t)(buf->inbuf_end - buf->inbuf);
+			break;
+		case MBERR_INTERNAL:
+			PyErr_SetString(PyExc_RuntimeError,
+					"internal codec error");
+			return -1;
+		default:
+			PyErr_SetString(PyExc_RuntimeError,
+					"unknown runtime error");
+			return -1;
+		}
+	}
+
+	if (errors == ERROR_REPLACE) {
+		REQUIRE_DECODEBUFFER(buf, 1);
+		*buf->outbuf++ = Py_UNICODE_REPLACEMENT_CHARACTER;
+	}
+	if (errors == ERROR_IGNORE || errors == ERROR_REPLACE) {
+		buf->inbuf += esize;
+		return 0;
+	}
+
+	start = (Py_ssize_t)(buf->inbuf - buf->inbuf_top);
+	end = start + esize;
+
+	/* use cached exception object if available */
+	if (buf->excobj == NULL) {
+		buf->excobj = PyUnicodeDecodeError_Create(codec->encoding,
+				(const char *)buf->inbuf_top,
+				(Py_ssize_t)(buf->inbuf_end - buf->inbuf_top),
+				start, end, reason);
+		if (buf->excobj == NULL)
+			goto errorexit;
+	}
+	else
+		if (PyUnicodeDecodeError_SetStart(buf->excobj, start) ||
+		    PyUnicodeDecodeError_SetEnd(buf->excobj, end) ||
+		    PyUnicodeDecodeError_SetReason(buf->excobj, reason))
+			goto errorexit;
+
+	if (errors == ERROR_STRICT) {
+		PyCodec_StrictErrors(buf->excobj);
+		goto errorexit;
+	}
+
+	retobj = call_error_callback(errors, buf->excobj);
+	if (retobj == NULL)
+		goto errorexit;
+
+	if (!PyTuple_Check(retobj) || PyTuple_GET_SIZE(retobj) != 2 ||
+	    !PyUnicode_Check((retuni = PyTuple_GET_ITEM(retobj, 0))) ||
+	    !(PyInt_Check(PyTuple_GET_ITEM(retobj, 1)) ||
+	      PyLong_Check(PyTuple_GET_ITEM(retobj, 1)))) {
+		PyErr_SetString(PyExc_TypeError,
+				"decoding error handler must return "
+				"(unicode, int) tuple");
+		goto errorexit;
+	}
+
+	retunisize = PyUnicode_GET_SIZE(retuni);
+	if (retunisize > 0) {
+		REQUIRE_DECODEBUFFER(buf, retunisize);
+		memcpy((char *)buf->outbuf, PyUnicode_AS_DATA(retuni),
+				retunisize * Py_UNICODE_SIZE);
+		buf->outbuf += retunisize;
+	}
+
+	newpos = PyInt_AsSsize_t(PyTuple_GET_ITEM(retobj, 1));
+	if (newpos < 0 && !PyErr_Occurred())
+		newpos += (Py_ssize_t)(buf->inbuf_end - buf->inbuf_top);
+	if (newpos < 0 || buf->inbuf_top + newpos > buf->inbuf_end) {
+		PyErr_Clear();
+		PyErr_Format(PyExc_IndexError,
+			     "position %zd from error handler out of bounds",
+			     newpos);
+		goto errorexit;
+	}
+	buf->inbuf = buf->inbuf_top + newpos;
+	Py_DECREF(retobj);
+	return 0;
+
+errorexit:
+	Py_XDECREF(retobj);
+	return -1;
+}
+
+static PyObject *
+multibytecodec_encode(MultibyteCodec *codec,
+		      MultibyteCodec_State *state,
+		      const Py_UNICODE **data, Py_ssize_t datalen,
+		      PyObject *errors, int flags)
+{
+	MultibyteEncodeBuffer buf;
+	Py_ssize_t finalsize, r = 0;
+
+	if (datalen == 0)
+		return PyString_FromString("");
+
+	buf.excobj = NULL;
+	buf.inbuf = buf.inbuf_top = *data;
+	buf.inbuf_end = buf.inbuf_top + datalen;
+	buf.outobj = PyString_FromStringAndSize(NULL, datalen * 2 + 16);
+	if (buf.outobj == NULL)
+		goto errorexit;
+	buf.outbuf = (unsigned char *)PyString_AS_STRING(buf.outobj);
+	buf.outbuf_end = buf.outbuf + PyString_GET_SIZE(buf.outobj);
+
+	while (buf.inbuf < buf.inbuf_end) {
+		Py_ssize_t inleft, outleft;
+
+		/* we don't reuse inleft and outleft here.
+		 * error callbacks can relocate the cursor anywhere on buffer*/
+		inleft = (Py_ssize_t)(buf.inbuf_end - buf.inbuf);
+		outleft = (Py_ssize_t)(buf.outbuf_end - buf.outbuf);
+		r = codec->encode(state, codec->config, &buf.inbuf, inleft,
+				  &buf.outbuf, outleft, flags);
+		*data = buf.inbuf;
+		if ((r == 0) || (r == MBERR_TOOFEW && !(flags & MBENC_FLUSH)))
+			break;
+		else if (multibytecodec_encerror(codec, state, &buf, errors,r))
+			goto errorexit;
+		else if (r == MBERR_TOOFEW)
+			break;
+	}
+
+	if (codec->encreset != NULL)
+		for (;;) {
+			Py_ssize_t outleft;
+
+			outleft = (Py_ssize_t)(buf.outbuf_end - buf.outbuf);
+			r = codec->encreset(state, codec->config, &buf.outbuf,
+					    outleft);
+			if (r == 0)
+				break;
+			else if (multibytecodec_encerror(codec, state,
+							 &buf, errors, r))
+				goto errorexit;
+		}
+
+	finalsize = (Py_ssize_t)((char *)buf.outbuf -
+				 PyString_AS_STRING(buf.outobj));
+
+	if (finalsize != PyString_GET_SIZE(buf.outobj))
+		if (_PyString_Resize(&buf.outobj, finalsize) == -1)
+			goto errorexit;
+
+	Py_XDECREF(buf.excobj);
+	return buf.outobj;
+
+errorexit:
+	Py_XDECREF(buf.excobj);
+	Py_XDECREF(buf.outobj);
+	return NULL;
+}
+
+static PyObject *
+MultibyteCodec_Encode(MultibyteCodecObject *self,
+		      PyObject *args, PyObject *kwargs)
+{
+	MultibyteCodec_State state;
+	Py_UNICODE *data;
+	PyObject *errorcb, *r, *arg, *ucvt;
+	const char *errors = NULL;
+	Py_ssize_t datalen;
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|z:encode",
+				codeckwarglist, &arg, &errors))
+		return NULL;
+
+	if (PyUnicode_Check(arg))
+		ucvt = NULL;
+	else {
+		arg = ucvt = PyObject_Unicode(arg);
+		if (arg == NULL)
+			return NULL;
+		else if (!PyUnicode_Check(arg)) {
+			PyErr_SetString(PyExc_TypeError,
+				"couldn't convert the object to unicode.");
+			Py_DECREF(ucvt);
+			return NULL;
+		}
+	}
+
+	data = PyUnicode_AS_UNICODE(arg);
+	datalen = PyUnicode_GET_SIZE(arg);
+
+	errorcb = internal_error_callback(errors);
+	if (errorcb == NULL) {
+		Py_XDECREF(ucvt);
+		return NULL;
+	}
+
+	if (self->codec->encinit != NULL &&
+	    self->codec->encinit(&state, self->codec->config) != 0)
+		goto errorexit;
+	r = multibytecodec_encode(self->codec, &state,
+			(const Py_UNICODE **)&data, datalen, errorcb,
+			MBENC_FLUSH | MBENC_RESET);
+	if (r == NULL)
+		goto errorexit;
+
+	ERROR_DECREF(errorcb);
+	Py_XDECREF(ucvt);
+	return make_tuple(r, datalen);
+
+errorexit:
+	ERROR_DECREF(errorcb);
+	Py_XDECREF(ucvt);
+	return NULL;
+}
+
+static PyObject *
+MultibyteCodec_Decode(MultibyteCodecObject *self,
+		      PyObject *args, PyObject *kwargs)
+{
+	MultibyteCodec_State state;
+	MultibyteDecodeBuffer buf;
+	PyObject *errorcb;
+	const char *data, *errors = NULL;
+	Py_ssize_t datalen, finalsize;
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#|z:decode",
+				codeckwarglist, &data, &datalen, &errors))
+		return NULL;
+
+	errorcb = internal_error_callback(errors);
+	if (errorcb == NULL)
+		return NULL;
+
+	if (datalen == 0) {
+		ERROR_DECREF(errorcb);
+		return make_tuple(PyUnicode_FromUnicode(NULL, 0), 0);
+	}
+
+	buf.excobj = NULL;
+	buf.inbuf = buf.inbuf_top = (unsigned char *)data;
+	buf.inbuf_end = buf.inbuf_top + datalen;
+	buf.outobj = PyUnicode_FromUnicode(NULL, datalen);
+	if (buf.outobj == NULL)
+		goto errorexit;
+	buf.outbuf = PyUnicode_AS_UNICODE(buf.outobj);
+	buf.outbuf_end = buf.outbuf + PyUnicode_GET_SIZE(buf.outobj);
+
+	if (self->codec->decinit != NULL &&
+	    self->codec->decinit(&state, self->codec->config) != 0)
+		goto errorexit;
+
+	while (buf.inbuf < buf.inbuf_end) {
+		Py_ssize_t inleft, outleft, r;
+
+		inleft = (Py_ssize_t)(buf.inbuf_end - buf.inbuf);
+		outleft = (Py_ssize_t)(buf.outbuf_end - buf.outbuf);
+
+		r = self->codec->decode(&state, self->codec->config,
+				&buf.inbuf, inleft, &buf.outbuf, outleft);
+		if (r == 0)
+			break;
+		else if (multibytecodec_decerror(self->codec, &state,
+						 &buf, errorcb, r))
+			goto errorexit;
+	}
+
+	finalsize = (Py_ssize_t)(buf.outbuf -
+				 PyUnicode_AS_UNICODE(buf.outobj));
+
+	if (finalsize != PyUnicode_GET_SIZE(buf.outobj))
+		if (PyUnicode_Resize(&buf.outobj, finalsize) == -1)
+			goto errorexit;
+
+	Py_XDECREF(buf.excobj);
+	ERROR_DECREF(errorcb);
+	return make_tuple(buf.outobj, datalen);
+
+errorexit:
+	ERROR_DECREF(errorcb);
+	Py_XDECREF(buf.excobj);
+	Py_XDECREF(buf.outobj);
+
+	return NULL;
+}
+
+static struct PyMethodDef multibytecodec_methods[] = {
+	{"encode",	(PyCFunction)MultibyteCodec_Encode,
+			METH_VARARGS | METH_KEYWORDS,
+			MultibyteCodec_Encode__doc__},
+	{"decode",	(PyCFunction)MultibyteCodec_Decode,
+			METH_VARARGS | METH_KEYWORDS,
+			MultibyteCodec_Decode__doc__},
+	{NULL,		NULL},
+};
+
+static void
+multibytecodec_dealloc(MultibyteCodecObject *self)
+{
+	PyObject_Del(self);
+}
+
+static PyTypeObject MultibyteCodec_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0,				/* ob_size */
+	"MultibyteCodec",		/* tp_name */
+	sizeof(MultibyteCodecObject),	/* tp_basicsize */
+	0,				/* tp_itemsize */
+	/* methods */
+	(destructor)multibytecodec_dealloc, /* tp_dealloc */
+	0,				/* tp_print */
+	0,				/* tp_getattr */
+	0,				/* tp_setattr */
+	0,				/* tp_compare */
+	0,				/* tp_repr */
+	0,				/* tp_as_number */
+	0,				/* tp_as_sequence */
+	0,				/* tp_as_mapping */
+	0,				/* tp_hash */
+	0,				/* tp_call */
+	0,				/* tp_str */
+	PyObject_GenericGetAttr,	/* tp_getattro */
+	0,				/* tp_setattro */
+	0,				/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT,		/* tp_flags */
+	0,				/* tp_doc */
+	0,				/* tp_traverse */
+	0,				/* tp_clear */
+	0,				/* tp_richcompare */
+	0,				/* tp_weaklistoffset */
+	0,				/* tp_iter */
+	0,				/* tp_iterext */
+	multibytecodec_methods,		/* tp_methods */
+};
+
+
+/**
+ * Utility functions for stateful codec mechanism
+ */
+
+#define STATEFUL_DCTX(o)	((MultibyteStatefulDecoderContext *)(o))
+#define STATEFUL_ECTX(o)	((MultibyteStatefulEncoderContext *)(o))
+
+static PyObject *
+encoder_encode_stateful(MultibyteStatefulEncoderContext *ctx,
+			PyObject *unistr, int final)
+{
+	PyObject *ucvt, *r = NULL;
+	Py_UNICODE *inbuf, *inbuf_end, *inbuf_tmp = NULL;
+	Py_ssize_t datalen, origpending;
+
+	if (PyUnicode_Check(unistr))
+		ucvt = NULL;
+	else {
+		unistr = ucvt = PyObject_Unicode(unistr);
+		if (unistr == NULL)
+			return NULL;
+		else if (!PyUnicode_Check(unistr)) {
+			PyErr_SetString(PyExc_TypeError,
+				"couldn't convert the object to unicode.");
+			Py_DECREF(ucvt);
+			return NULL;
+		}
+	}
+
+	datalen = PyUnicode_GET_SIZE(unistr);
+	origpending = ctx->pendingsize;
+
+	if (origpending > 0) {
+		inbuf_tmp = PyMem_New(Py_UNICODE, datalen + ctx->pendingsize);
+		if (inbuf_tmp == NULL)
+			goto errorexit;
+		memcpy(inbuf_tmp, ctx->pending,
+			Py_UNICODE_SIZE * ctx->pendingsize);
+		memcpy(inbuf_tmp + ctx->pendingsize,
+			PyUnicode_AS_UNICODE(unistr),
+			Py_UNICODE_SIZE * datalen);
+		datalen += ctx->pendingsize;
+		ctx->pendingsize = 0;
+		inbuf = inbuf_tmp;
+	}
+	else
+		inbuf = (Py_UNICODE *)PyUnicode_AS_UNICODE(unistr);
+
+	inbuf_end = inbuf + datalen;
+
+	r = multibytecodec_encode(ctx->codec, &ctx->state,
+			(const Py_UNICODE **)&inbuf,
+			datalen, ctx->errors, final ? MBENC_FLUSH : 0);
+	if (r == NULL) {
+		/* recover the original pending buffer */
+		if (origpending > 0)
+			memcpy(ctx->pending, inbuf_tmp,
+				Py_UNICODE_SIZE * origpending);
+		ctx->pendingsize = origpending;
+		goto errorexit;
+	}
+
+	if (inbuf < inbuf_end) {
+		ctx->pendingsize = (Py_ssize_t)(inbuf_end - inbuf);
+		if (ctx->pendingsize > MAXENCPENDING) {
+			/* normal codecs can't reach here */
+			ctx->pendingsize = 0;
+			PyErr_SetString(PyExc_UnicodeError,
+					"pending buffer overflow");
+			goto errorexit;
+		}
+		memcpy(ctx->pending, inbuf,
+			ctx->pendingsize * Py_UNICODE_SIZE);
+	}
+
+	if (inbuf_tmp != NULL)
+		PyMem_Del(inbuf_tmp);
+	Py_XDECREF(ucvt);
+	return r;
+
+errorexit:
+	if (inbuf_tmp != NULL)
+		PyMem_Del(inbuf_tmp);
+	Py_XDECREF(r);
+	Py_XDECREF(ucvt);
+	return NULL;
+}
+
+static int
+decoder_append_pending(MultibyteStatefulDecoderContext *ctx,
+		       MultibyteDecodeBuffer *buf)
+{
+	Py_ssize_t npendings;
+
+	npendings = (Py_ssize_t)(buf->inbuf_end - buf->inbuf);
+	if (npendings + ctx->pendingsize > MAXDECPENDING) {
+		PyErr_SetString(PyExc_UnicodeError, "pending buffer overflow");
+		return -1;
+	}
+	memcpy(ctx->pending + ctx->pendingsize, buf->inbuf, npendings);
+	ctx->pendingsize += npendings;
+	return 0;
+}
+
+static int
+decoder_prepare_buffer(MultibyteDecodeBuffer *buf, const char *data,
+		       Py_ssize_t size)
+{
+	buf->inbuf = buf->inbuf_top = (const unsigned char *)data;
+	buf->inbuf_end = buf->inbuf_top + size;
+	if (buf->outobj == NULL) { /* only if outobj is not allocated yet */
+		buf->outobj = PyUnicode_FromUnicode(NULL, size);
+		if (buf->outobj == NULL)
+			return -1;
+		buf->outbuf = PyUnicode_AS_UNICODE(buf->outobj);
+		buf->outbuf_end = buf->outbuf +
+				  PyUnicode_GET_SIZE(buf->outobj);
+	}
+
+	return 0;
+}
+
+static int
+decoder_feed_buffer(MultibyteStatefulDecoderContext *ctx,
+		    MultibyteDecodeBuffer *buf)
+{
+	while (buf->inbuf < buf->inbuf_end) {
+		Py_ssize_t inleft, outleft;
+		Py_ssize_t r;
+
+		inleft = (Py_ssize_t)(buf->inbuf_end - buf->inbuf);
+		outleft = (Py_ssize_t)(buf->outbuf_end - buf->outbuf);
+
+		r = ctx->codec->decode(&ctx->state, ctx->codec->config,
+			&buf->inbuf, inleft, &buf->outbuf, outleft);
+		if (r == 0 || r == MBERR_TOOFEW)
+			break;
+		else if (multibytecodec_decerror(ctx->codec, &ctx->state,
+						 buf, ctx->errors, r))
+			return -1;
+	}
+	return 0;
+}
+
+
+/**
+ * MultibyteIncrementalEncoder object
+ */
+
+static PyObject *
+mbiencoder_encode(MultibyteIncrementalEncoderObject *self,
+		  PyObject *args, PyObject *kwargs)
+{
+	PyObject *data;
+	int final = 0;
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|i:encode",
+			incrementalkwarglist, &data, &final))
+		return NULL;
+
+	return encoder_encode_stateful(STATEFUL_ECTX(self), data, final);
+}
+
+static PyObject *
+mbiencoder_reset(MultibyteIncrementalEncoderObject *self)
+{
+	if (self->codec->decreset != NULL &&
+	    self->codec->decreset(&self->state, self->codec->config) != 0)
+		return NULL;
+	self->pendingsize = 0;
+
+	Py_RETURN_NONE;
+}
+
+static struct PyMethodDef mbiencoder_methods[] = {
+	{"encode",	(PyCFunction)mbiencoder_encode,
+			METH_VARARGS | METH_KEYWORDS, NULL},
+	{"reset",	(PyCFunction)mbiencoder_reset,
+			METH_NOARGS, NULL},
+	{NULL,		NULL},
+};
+
+static PyObject *
+mbiencoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	MultibyteIncrementalEncoderObject *self;
+	PyObject *codec = NULL;
+	char *errors = NULL;
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwds, "|s:IncrementalEncoder",
+					 incnewkwarglist, &errors))
+		return NULL;
+
+	self = (MultibyteIncrementalEncoderObject *)type->tp_alloc(type, 0);
+	if (self == NULL)
+		return NULL;
+
+	codec = PyObject_GetAttrString((PyObject *)type, "codec");
+	if (codec == NULL)
+		goto errorexit;
+	if (!MultibyteCodec_Check(codec)) {
+		PyErr_SetString(PyExc_TypeError, "codec is unexpected type");
+		goto errorexit;
+	}
+
+	self->codec = ((MultibyteCodecObject *)codec)->codec;
+	self->pendingsize = 0;
+	self->errors = internal_error_callback(errors);
+	if (self->errors == NULL)
+		goto errorexit;
+	if (self->codec->encinit != NULL &&
+	    self->codec->encinit(&self->state, self->codec->config) != 0)
+		goto errorexit;
+
+	Py_DECREF(codec);
+	return (PyObject *)self;
+
+errorexit:
+	Py_XDECREF(self);
+	Py_XDECREF(codec);
+	return NULL;
+}
+
+static int
+mbiencoder_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+	return 0;
+}
+
+static int
+mbiencoder_traverse(MultibyteIncrementalEncoderObject *self,
+		    visitproc visit, void *arg)
+{
+	if (ERROR_ISCUSTOM(self->errors))
+		Py_VISIT(self->errors);
+	return 0;
+}
+
+static void
+mbiencoder_dealloc(MultibyteIncrementalEncoderObject *self)
+{
+	PyObject_GC_UnTrack(self);
+	ERROR_DECREF(self->errors);
+	self->ob_type->tp_free(self);
+}
+
+static PyTypeObject MultibyteIncrementalEncoder_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0,				/* ob_size */
+	"MultibyteIncrementalEncoder",	/* tp_name */
+	sizeof(MultibyteIncrementalEncoderObject), /* tp_basicsize */
+	0,				/* tp_itemsize */
+	/*  methods  */
+	(destructor)mbiencoder_dealloc, /* tp_dealloc */
+	0,				/* tp_print */
+	0,				/* tp_getattr */
+	0,				/* tp_setattr */
+	0,				/* tp_compare */
+	0,				/* tp_repr */
+	0,				/* tp_as_number */
+	0,				/* tp_as_sequence */
+	0,				/* tp_as_mapping */
+	0,				/* tp_hash */
+	0,				/* tp_call */
+	0,				/* tp_str */
+	PyObject_GenericGetAttr,	/* tp_getattro */
+	0,				/* tp_setattro */
+	0,				/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC
+		| Py_TPFLAGS_BASETYPE,	/* tp_flags */
+	0,				/* tp_doc */
+	(traverseproc)mbiencoder_traverse,	/* tp_traverse */
+	0,				/* tp_clear */
+	0,				/* tp_richcompare */
+	0,				/* tp_weaklistoffset */
+	0,				/* tp_iter */
+	0,				/* tp_iterext */
+	mbiencoder_methods,		/* tp_methods */
+	0,				/* tp_members */
+	codecctx_getsets,		/* tp_getset */
+	0,				/* tp_base */
+	0,				/* tp_dict */
+	0,				/* tp_descr_get */
+	0,				/* tp_descr_set */
+	0,				/* tp_dictoffset */
+	mbiencoder_init,		/* tp_init */
+	0,				/* tp_alloc */
+	mbiencoder_new,			/* tp_new */
+};
+
+
+/**
+ * MultibyteIncrementalDecoder object
+ */
+
+static PyObject *
+mbidecoder_decode(MultibyteIncrementalDecoderObject *self,
+		  PyObject *args, PyObject *kwargs)
+{
+	MultibyteDecodeBuffer buf;
+	char *data, *wdata;
+	Py_ssize_t wsize, finalsize = 0, size, origpending;
+	int final = 0;
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "t#|i:decode",
+			incrementalkwarglist, &data, &size, &final))
+		return NULL;
+
+	buf.outobj = buf.excobj = NULL;
+	origpending = self->pendingsize;
+
+	if (self->pendingsize == 0) {
+		wsize = size;
+		wdata = data;
+	}
+	else {
+		wsize = size + self->pendingsize;
+		wdata = PyMem_Malloc(wsize);
+		if (wdata == NULL)
+			goto errorexit;
+		memcpy(wdata, self->pending, self->pendingsize);
+		memcpy(wdata + self->pendingsize, data, size);
+		self->pendingsize = 0;
+	}
+
+	if (decoder_prepare_buffer(&buf, wdata, wsize) != 0)
+		goto errorexit;
+
+	if (decoder_feed_buffer(STATEFUL_DCTX(self), &buf))
+		goto errorexit;
+
+	if (final && buf.inbuf < buf.inbuf_end) {
+		if (multibytecodec_decerror(self->codec, &self->state,
+				&buf, self->errors, MBERR_TOOFEW)) {
+			/* recover the original pending buffer */
+			memcpy(self->pending, wdata, origpending);
+			self->pendingsize = origpending;
+			goto errorexit;
+		}
+	}
+
+	if (buf.inbuf < buf.inbuf_end) { /* pending sequence still exists */
+		if (decoder_append_pending(STATEFUL_DCTX(self), &buf) != 0)
+			goto errorexit;
+	}
+
+	finalsize = (Py_ssize_t)(buf.outbuf - PyUnicode_AS_UNICODE(buf.outobj));
+	if (finalsize != PyUnicode_GET_SIZE(buf.outobj))
+		if (PyUnicode_Resize(&buf.outobj, finalsize) == -1)
+			goto errorexit;
+
+	if (wdata != data)
+		PyMem_Del(wdata);
+	Py_XDECREF(buf.excobj);
+	return buf.outobj;
+
+errorexit:
+	if (wdata != NULL && wdata != data)
+		PyMem_Del(wdata);
+	Py_XDECREF(buf.excobj);
+	Py_XDECREF(buf.outobj);
+	return NULL;
+}
+
+static PyObject *
+mbidecoder_reset(MultibyteIncrementalDecoderObject *self)
+{
+	if (self->codec->decreset != NULL &&
+	    self->codec->decreset(&self->state, self->codec->config) != 0)
+		return NULL;
+	self->pendingsize = 0;
+
+	Py_RETURN_NONE;
+}
+
+static struct PyMethodDef mbidecoder_methods[] = {
+	{"decode",	(PyCFunction)mbidecoder_decode,
+			METH_VARARGS | METH_KEYWORDS, NULL},
+	{"reset",	(PyCFunction)mbidecoder_reset,
+			METH_NOARGS, NULL},
+	{NULL,		NULL},
+};
+
+static PyObject *
+mbidecoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	MultibyteIncrementalDecoderObject *self;
+	PyObject *codec = NULL;
+	char *errors = NULL;
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwds, "|s:IncrementalDecoder",
+					 incnewkwarglist, &errors))
+		return NULL;
+
+	self = (MultibyteIncrementalDecoderObject *)type->tp_alloc(type, 0);
+	if (self == NULL)
+		return NULL;
+
+	codec = PyObject_GetAttrString((PyObject *)type, "codec");
+	if (codec == NULL)
+		goto errorexit;
+	if (!MultibyteCodec_Check(codec)) {
+		PyErr_SetString(PyExc_TypeError, "codec is unexpected type");
+		goto errorexit;
+	}
+
+	self->codec = ((MultibyteCodecObject *)codec)->codec;
+	self->pendingsize = 0;
+	self->errors = internal_error_callback(errors);
+	if (self->errors == NULL)
+		goto errorexit;
+	if (self->codec->decinit != NULL &&
+	    self->codec->decinit(&self->state, self->codec->config) != 0)
+		goto errorexit;
+
+	Py_DECREF(codec);
+	return (PyObject *)self;
+
+errorexit:
+	Py_XDECREF(self);
+	Py_XDECREF(codec);
+	return NULL;
+}
+
+static int
+mbidecoder_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+	return 0;
+}
+
+static int
+mbidecoder_traverse(MultibyteIncrementalDecoderObject *self,
+		    visitproc visit, void *arg)
+{
+	if (ERROR_ISCUSTOM(self->errors))
+		Py_VISIT(self->errors);
+	return 0;
+}
+
+static void
+mbidecoder_dealloc(MultibyteIncrementalDecoderObject *self)
+{
+	PyObject_GC_UnTrack(self);
+	ERROR_DECREF(self->errors);
+	self->ob_type->tp_free(self);
+}
+
+static PyTypeObject MultibyteIncrementalDecoder_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0,				/* ob_size */
+	"MultibyteIncrementalDecoder",	/* tp_name */
+	sizeof(MultibyteIncrementalDecoderObject), /* tp_basicsize */
+	0,				/* tp_itemsize */
+	/*  methods  */
+	(destructor)mbidecoder_dealloc, /* tp_dealloc */
+	0,				/* tp_print */
+	0,				/* tp_getattr */
+	0,				/* tp_setattr */
+	0,				/* tp_compare */
+	0,				/* tp_repr */
+	0,				/* tp_as_number */
+	0,				/* tp_as_sequence */
+	0,				/* tp_as_mapping */
+	0,				/* tp_hash */
+	0,				/* tp_call */
+	0,				/* tp_str */
+	PyObject_GenericGetAttr,	/* tp_getattro */
+	0,				/* tp_setattro */
+	0,				/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC
+		| Py_TPFLAGS_BASETYPE,	/* tp_flags */
+	0,				/* tp_doc */
+	(traverseproc)mbidecoder_traverse,	/* tp_traverse */
+	0,				/* tp_clear */
+	0,				/* tp_richcompare */
+	0,				/* tp_weaklistoffset */
+	0,				/* tp_iter */
+	0,				/* tp_iterext */
+	mbidecoder_methods,		/* tp_methods */
+	0,				/* tp_members */
+	codecctx_getsets,		/* tp_getset */
+	0,				/* tp_base */
+	0,				/* tp_dict */
+	0,				/* tp_descr_get */
+	0,				/* tp_descr_set */
+	0,				/* tp_dictoffset */
+	mbidecoder_init,		/* tp_init */
+	0,				/* tp_alloc */
+	mbidecoder_new,			/* tp_new */
+};
+
+
+/**
+ * MultibyteStreamReader object
+ */
+
+static PyObject *
+mbstreamreader_iread(MultibyteStreamReaderObject *self,
+		     const char *method, Py_ssize_t sizehint)
+{
+	MultibyteDecodeBuffer buf;
+	PyObject *cres;
+	Py_ssize_t rsize, finalsize = 0;
+
+	if (sizehint == 0)
+		return PyUnicode_FromUnicode(NULL, 0);
+
+	buf.outobj = buf.excobj = NULL;
+	cres = NULL;
+
+	for (;;) {
+		if (sizehint < 0)
+			cres = PyObject_CallMethod(self->stream,
+					(char *)method, NULL);
+		else
+			cres = PyObject_CallMethod(self->stream,
+					(char *)method, "i", sizehint);
+		if (cres == NULL)
+			goto errorexit;
+
+		if (!PyString_Check(cres)) {
+			PyErr_SetString(PyExc_TypeError,
+					"stream function returned a "
+					"non-string object");
+			goto errorexit;
+		}
+
+		if (self->pendingsize > 0) {
+			PyObject *ctr;
+			char *ctrdata;
+
+			rsize = PyString_GET_SIZE(cres) + self->pendingsize;
+			ctr = PyString_FromStringAndSize(NULL, rsize);
+			if (ctr == NULL)
+				goto errorexit;
+			ctrdata = PyString_AS_STRING(ctr);
+			memcpy(ctrdata, self->pending, self->pendingsize);
+			memcpy(ctrdata + self->pendingsize,
+				PyString_AS_STRING(cres),
+				PyString_GET_SIZE(cres));
+			Py_DECREF(cres);
+			cres = ctr;
+			self->pendingsize = 0;
+		}
+
+		rsize = PyString_GET_SIZE(cres);
+		if (decoder_prepare_buffer(&buf, PyString_AS_STRING(cres),
+					   rsize) != 0)
+			goto errorexit;
+
+		if (rsize > 0 && decoder_feed_buffer(
+				(MultibyteStatefulDecoderContext *)self, &buf))
+			goto errorexit;
+
+		if (rsize == 0 || sizehint < 0) { /* end of file */
+			if (buf.inbuf < buf.inbuf_end &&
+			    multibytecodec_decerror(self->codec, &self->state,
+					&buf, self->errors, MBERR_TOOFEW))
+				goto errorexit;
+		}
+
+		if (buf.inbuf < buf.inbuf_end) { /* pending sequence exists */
+			if (decoder_append_pending(STATEFUL_DCTX(self),
+						   &buf) != 0)
+				goto errorexit;
+		}
+
+		finalsize = (Py_ssize_t)(buf.outbuf -
+				PyUnicode_AS_UNICODE(buf.outobj));
+		Py_DECREF(cres);
+		cres = NULL;
+
+		if (sizehint < 0 || finalsize != 0 || rsize == 0)
+			break;
+
+		sizehint = 1; /* read 1 more byte and retry */
+	}
+
+	if (finalsize != PyUnicode_GET_SIZE(buf.outobj))
+		if (PyUnicode_Resize(&buf.outobj, finalsize) == -1)
+			goto errorexit;
+
+	Py_XDECREF(cres);
+	Py_XDECREF(buf.excobj);
+	return buf.outobj;
+
+errorexit:
+	Py_XDECREF(cres);
+	Py_XDECREF(buf.excobj);
+	Py_XDECREF(buf.outobj);
+	return NULL;
+}
+
+static PyObject *
+mbstreamreader_read(MultibyteStreamReaderObject *self, PyObject *args)
+{
+	PyObject *sizeobj = NULL;
+	Py_ssize_t size;
+
+	if (!PyArg_UnpackTuple(args, "read", 0, 1, &sizeobj))
+		return NULL;
+
+	if (sizeobj == Py_None || sizeobj == NULL)
+		size = -1;
+	else if (PyInt_Check(sizeobj))
+		size = PyInt_AsSsize_t(sizeobj);
+	else {
+		PyErr_SetString(PyExc_TypeError, "arg 1 must be an integer");
+		return NULL;
+	}
+
+	return mbstreamreader_iread(self, "read", size);
+}
+
+static PyObject *
+mbstreamreader_readline(MultibyteStreamReaderObject *self, PyObject *args)
+{
+	PyObject *sizeobj = NULL;
+	Py_ssize_t size;
+
+	if (!PyArg_UnpackTuple(args, "readline", 0, 1, &sizeobj))
+		return NULL;
+
+	if (sizeobj == Py_None || sizeobj == NULL)
+		size = -1;
+	else if (PyInt_Check(sizeobj))
+		size = PyInt_AsSsize_t(sizeobj);
+	else {
+		PyErr_SetString(PyExc_TypeError, "arg 1 must be an integer");
+		return NULL;
+	}
+
+	return mbstreamreader_iread(self, "readline", size);
+}
+
+static PyObject *
+mbstreamreader_readlines(MultibyteStreamReaderObject *self, PyObject *args)
+{
+	PyObject *sizehintobj = NULL, *r, *sr;
+	Py_ssize_t sizehint;
+
+	if (!PyArg_UnpackTuple(args, "readlines", 0, 1, &sizehintobj))
+		return NULL;
+
+	if (sizehintobj == Py_None || sizehintobj == NULL)
+		sizehint = -1;
+	else if (PyInt_Check(sizehintobj))
+		sizehint = PyInt_AsSsize_t(sizehintobj);
+	else {
+		PyErr_SetString(PyExc_TypeError, "arg 1 must be an integer");
+		return NULL;
+	}
+
+	r = mbstreamreader_iread(self, "read", sizehint);
+	if (r == NULL)
+		return NULL;
+
+	sr = PyUnicode_Splitlines(r, 1);
+	Py_DECREF(r);
+	return sr;
+}
+
+static PyObject *
+mbstreamreader_reset(MultibyteStreamReaderObject *self)
+{
+	if (self->codec->decreset != NULL &&
+	    self->codec->decreset(&self->state, self->codec->config) != 0)
+		return NULL;
+	self->pendingsize = 0;
+
+	Py_RETURN_NONE;
+}
+
+static struct PyMethodDef mbstreamreader_methods[] = {
+	{"read",	(PyCFunction)mbstreamreader_read,
+			METH_VARARGS, NULL},
+	{"readline",	(PyCFunction)mbstreamreader_readline,
+			METH_VARARGS, NULL},
+	{"readlines",	(PyCFunction)mbstreamreader_readlines,
+			METH_VARARGS, NULL},
+	{"reset",	(PyCFunction)mbstreamreader_reset,
+			METH_NOARGS, NULL},
+	{NULL,		NULL},
+};
+
+static PyMemberDef mbstreamreader_members[] = {
+	{"stream",	T_OBJECT,
+			offsetof(MultibyteStreamReaderObject, stream),
+			READONLY, NULL},
+	{NULL,}
+};
+
+static PyObject *
+mbstreamreader_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	MultibyteStreamReaderObject *self;
+	PyObject *stream, *codec = NULL;
+	char *errors = NULL;
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|s:StreamReader",
+				streamkwarglist, &stream, &errors))
+		return NULL;
+
+	self = (MultibyteStreamReaderObject *)type->tp_alloc(type, 0);
+	if (self == NULL)
+		return NULL;
+
+	codec = PyObject_GetAttrString((PyObject *)type, "codec");
+	if (codec == NULL)
+		goto errorexit;
+	if (!MultibyteCodec_Check(codec)) {
+		PyErr_SetString(PyExc_TypeError, "codec is unexpected type");
+		goto errorexit;
+	}
+
+	self->codec = ((MultibyteCodecObject *)codec)->codec;
+	self->stream = stream;
+	Py_INCREF(stream);
+	self->pendingsize = 0;
+	self->errors = internal_error_callback(errors);
+	if (self->errors == NULL)
+		goto errorexit;
+	if (self->codec->decinit != NULL &&
+	    self->codec->decinit(&self->state, self->codec->config) != 0)
+		goto errorexit;
+
+	Py_DECREF(codec);
+	return (PyObject *)self;
+
+errorexit:
+	Py_XDECREF(self);
+	Py_XDECREF(codec);
+	return NULL;
+}
+
+static int
+mbstreamreader_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+	return 0;
+}
+
+static int
+mbstreamreader_traverse(MultibyteStreamReaderObject *self,
+			visitproc visit, void *arg)
+{
+	if (ERROR_ISCUSTOM(self->errors))
+		Py_VISIT(self->errors);
+	Py_VISIT(self->stream);
+	return 0;
+}
+
+static void
+mbstreamreader_dealloc(MultibyteStreamReaderObject *self)
+{
+	PyObject_GC_UnTrack(self);
+	ERROR_DECREF(self->errors);
+	Py_DECREF(self->stream);
+	self->ob_type->tp_free(self);
+}
+
+static PyTypeObject MultibyteStreamReader_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0,				/* ob_size */
+	"MultibyteStreamReader",	/* tp_name */
+	sizeof(MultibyteStreamReaderObject), /* tp_basicsize */
+	0,				/* tp_itemsize */
+	/*  methods  */
+	(destructor)mbstreamreader_dealloc, /* tp_dealloc */
+	0,				/* tp_print */
+	0,				/* tp_getattr */
+	0,				/* tp_setattr */
+	0,				/* tp_compare */
+	0,				/* tp_repr */
+	0,				/* tp_as_number */
+	0,				/* tp_as_sequence */
+	0,				/* tp_as_mapping */
+	0,				/* tp_hash */
+	0,				/* tp_call */
+	0,				/* tp_str */
+	PyObject_GenericGetAttr,	/* tp_getattro */
+	0,				/* tp_setattro */
+	0,				/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC
+		| Py_TPFLAGS_BASETYPE,	/* tp_flags */
+	0,				/* tp_doc */
+	(traverseproc)mbstreamreader_traverse,	/* tp_traverse */
+	0,				/* tp_clear */
+	0,				/* tp_richcompare */
+	0,				/* tp_weaklistoffset */
+	0,				/* tp_iter */
+	0,				/* tp_iterext */
+	mbstreamreader_methods,		/* tp_methods */
+	mbstreamreader_members,		/* tp_members */
+	codecctx_getsets,		/* tp_getset */
+	0,				/* tp_base */
+	0,				/* tp_dict */
+	0,				/* tp_descr_get */
+	0,				/* tp_descr_set */
+	0,				/* tp_dictoffset */
+	mbstreamreader_init,		/* tp_init */
+	0,				/* tp_alloc */
+	mbstreamreader_new,		/* tp_new */
+};
+
+
+/**
+ * MultibyteStreamWriter object
+ */
+
+static int
+mbstreamwriter_iwrite(MultibyteStreamWriterObject *self,
+		      PyObject *unistr)
+{
+	PyObject *str, *wr;
+
+	str = encoder_encode_stateful(STATEFUL_ECTX(self), unistr, 0);
+	if (str == NULL)
+		return -1;
+
+	wr = PyObject_CallMethod(self->stream, "write", "O", str);
+	Py_DECREF(str);
+	if (wr == NULL)
+		return -1;
+
+	Py_DECREF(wr);
+	return 0;
+}
+
+static PyObject *
+mbstreamwriter_write(MultibyteStreamWriterObject *self, PyObject *strobj)
+{
+	if (mbstreamwriter_iwrite(self, strobj))
+		return NULL;
+	else
+		Py_RETURN_NONE;
+}
+
+static PyObject *
+mbstreamwriter_writelines(MultibyteStreamWriterObject *self, PyObject *lines)
+{
+	PyObject *strobj;
+	int i, r;
+
+	if (!PySequence_Check(lines)) {
+		PyErr_SetString(PyExc_TypeError,
+				"arg must be a sequence object");
+		return NULL;
+	}
+
+	for (i = 0; i < PySequence_Length(lines); i++) {
+		/* length can be changed even within this loop */
+		strobj = PySequence_GetItem(lines, i);
+		if (strobj == NULL)
+			return NULL;
+
+		r = mbstreamwriter_iwrite(self, strobj);
+		Py_DECREF(strobj);
+		if (r == -1)
+			return NULL;
+	}
+
+	Py_RETURN_NONE;
+}
+
+static PyObject *
+mbstreamwriter_reset(MultibyteStreamWriterObject *self)
+{
+	const Py_UNICODE *pending;
+	PyObject *pwrt;
+
+	pending = self->pending;
+	pwrt = multibytecodec_encode(self->codec, &self->state,
+			&pending, self->pendingsize, self->errors,
+			MBENC_FLUSH | MBENC_RESET);
+	/* some pending buffer can be truncated when UnicodeEncodeError is
+	 * raised on 'strict' mode. but, 'reset' method is designed to
+	 * reset the pending buffer or states so failed string sequence
+	 * ought to be missed */
+	self->pendingsize = 0;
+	if (pwrt == NULL)
+		return NULL;
+
+	if (PyString_Size(pwrt) > 0) {
+		PyObject *wr;
+		wr = PyObject_CallMethod(self->stream, "write", "O", pwrt);
+		if (wr == NULL) {
+			Py_DECREF(pwrt);
+			return NULL;
+		}
+	}
+	Py_DECREF(pwrt);
+
+	Py_RETURN_NONE;
+}
+
+static PyObject *
+mbstreamwriter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	MultibyteStreamWriterObject *self;
+	PyObject *stream, *codec = NULL;
+	char *errors = NULL;
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|s:StreamWriter",
+				streamkwarglist, &stream, &errors))
+		return NULL;
+
+	self = (MultibyteStreamWriterObject *)type->tp_alloc(type, 0);
+	if (self == NULL)
+		return NULL;
+
+	codec = PyObject_GetAttrString((PyObject *)type, "codec");
+	if (codec == NULL)
+		goto errorexit;
+	if (!MultibyteCodec_Check(codec)) {
+		PyErr_SetString(PyExc_TypeError, "codec is unexpected type");
+		goto errorexit;
+	}
+
+	self->codec = ((MultibyteCodecObject *)codec)->codec;
+	self->stream = stream;
+	Py_INCREF(stream);
+	self->pendingsize = 0;
+	self->errors = internal_error_callback(errors);
+	if (self->errors == NULL)
+		goto errorexit;
+	if (self->codec->encinit != NULL &&
+	    self->codec->encinit(&self->state, self->codec->config) != 0)
+		goto errorexit;
+
+	Py_DECREF(codec);
+	return (PyObject *)self;
+
+errorexit:
+	Py_XDECREF(self);
+	Py_XDECREF(codec);
+	return NULL;
+}
+
+static int
+mbstreamwriter_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+	return 0;
+}
+
+static int
+mbstreamwriter_traverse(MultibyteStreamWriterObject *self,
+			visitproc visit, void *arg)
+{
+	if (ERROR_ISCUSTOM(self->errors))
+		Py_VISIT(self->errors);
+	Py_VISIT(self->stream);
+	return 0;
+}
+
+static void
+mbstreamwriter_dealloc(MultibyteStreamWriterObject *self)
+{
+	PyObject_GC_UnTrack(self);
+	ERROR_DECREF(self->errors);
+	Py_DECREF(self->stream);
+	self->ob_type->tp_free(self);
+}
+
+static struct PyMethodDef mbstreamwriter_methods[] = {
+	{"write",	(PyCFunction)mbstreamwriter_write,
+			METH_O, NULL},
+	{"writelines",	(PyCFunction)mbstreamwriter_writelines,
+			METH_O, NULL},
+	{"reset",	(PyCFunction)mbstreamwriter_reset,
+			METH_NOARGS, NULL},
+	{NULL,		NULL},
+};
+
+static PyMemberDef mbstreamwriter_members[] = {
+	{"stream",	T_OBJECT,
+			offsetof(MultibyteStreamWriterObject, stream),
+			READONLY, NULL},
+	{NULL,}
+};
+
+static PyTypeObject MultibyteStreamWriter_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0,				/* ob_size */
+	"MultibyteStreamWriter",	/* tp_name */
+	sizeof(MultibyteStreamWriterObject), /* tp_basicsize */
+	0,				/* tp_itemsize */
+	/*  methods  */
+	(destructor)mbstreamwriter_dealloc, /* tp_dealloc */
+	0,				/* tp_print */
+	0,				/* tp_getattr */
+	0,				/* tp_setattr */
+	0,				/* tp_compare */
+	0,				/* tp_repr */
+	0,				/* tp_as_number */
+	0,				/* tp_as_sequence */
+	0,				/* tp_as_mapping */
+	0,				/* tp_hash */
+	0,				/* tp_call */
+	0,				/* tp_str */
+	PyObject_GenericGetAttr,	/* tp_getattro */
+	0,				/* tp_setattro */
+	0,				/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC
+		| Py_TPFLAGS_BASETYPE,	/* tp_flags */
+	0,				/* tp_doc */
+	(traverseproc)mbstreamwriter_traverse,	/* tp_traverse */
+	0,				/* tp_clear */
+	0,				/* tp_richcompare */
+	0,				/* tp_weaklistoffset */
+	0,				/* tp_iter */
+	0,				/* tp_iterext */
+	mbstreamwriter_methods,		/* tp_methods */
+	mbstreamwriter_members,		/* tp_members */
+	codecctx_getsets,		/* tp_getset */
+	0,				/* tp_base */
+	0,				/* tp_dict */
+	0,				/* tp_descr_get */
+	0,				/* tp_descr_set */
+	0,				/* tp_dictoffset */
+	mbstreamwriter_init,		/* tp_init */
+	0,				/* tp_alloc */
+	mbstreamwriter_new,		/* tp_new */
+};
+
+
+/**
+ * Exposed factory function
+ */
+
+static PyObject *
+__create_codec(PyObject *ignore, PyObject *arg)
+{
+	MultibyteCodecObject *self;
+	MultibyteCodec *codec;
+
+	if (!PyCObject_Check(arg)) {
+		PyErr_SetString(PyExc_ValueError, "argument type invalid");
+		return NULL;
+	}
+
+	codec = PyCObject_AsVoidPtr(arg);
+	if (codec->codecinit != NULL && codec->codecinit(codec->config) != 0)
+		return NULL;
+
+	self = PyObject_New(MultibyteCodecObject, &MultibyteCodec_Type);
+	if (self == NULL)
+		return NULL;
+	self->codec = codec;
+
+	return (PyObject *)self;
+}
+
+static struct PyMethodDef __methods[] = {
+	{"__create_codec", (PyCFunction)__create_codec, METH_O},
+	{NULL, NULL},
+};
+
+PyMODINIT_FUNC
+init_multibytecodec(void)
+{
+	int i;
+	PyObject *m;
+	PyTypeObject *typelist[] = {
+		&MultibyteIncrementalEncoder_Type,
+		&MultibyteIncrementalDecoder_Type,
+		&MultibyteStreamReader_Type,
+		&MultibyteStreamWriter_Type,
+		NULL
+	};
+
+	if (PyType_Ready(&MultibyteCodec_Type) < 0)
+		return;
+
+	m = Py_InitModule("_multibytecodec", __methods);
+	if (m == NULL)
+		return;
+
+	for (i = 0; typelist[i] != NULL; i++) {
+		if (PyType_Ready(typelist[i]) < 0)
+			return;
+		Py_INCREF(typelist[i]);
+		PyModule_AddObject(m, typelist[i]->tp_name,
+				   (PyObject *)typelist[i]);
+	}
+
+	if (PyErr_Occurred())
+		Py_FatalError("can't initialize the _multibytecodec module");
+}

Added: vendor/Python/current/Modules/cjkcodecs/multibytecodec.h
===================================================================
--- vendor/Python/current/Modules/cjkcodecs/multibytecodec.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/cjkcodecs/multibytecodec.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,138 @@
+/*
+ * multibytecodec.h: Common Multibyte Codec Implementation
+ *
+ * Written by Hye-Shik Chang <perky at FreeBSD.org>
+ */
+
+#ifndef _PYTHON_MULTIBYTECODEC_H_
+#define _PYTHON_MULTIBYTECODEC_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef uint32_t
+typedef uint32_t ucs4_t;
+#else
+typedef unsigned int ucs4_t;
+#endif
+
+#ifdef uint16_t
+typedef uint16_t ucs2_t, DBCHAR;
+#else
+typedef unsigned short ucs2_t, DBCHAR;
+#endif
+
+typedef union {
+	void *p;
+	int i;
+	unsigned char c[8];
+	ucs2_t u2[4];
+	ucs4_t u4[2];
+} MultibyteCodec_State;
+
+typedef int (*mbcodec_init)(const void *config);
+typedef Py_ssize_t (*mbencode_func)(MultibyteCodec_State *state,
+			const void *config,
+			const Py_UNICODE **inbuf, Py_ssize_t inleft,
+			unsigned char **outbuf, Py_ssize_t outleft,
+			int flags);
+typedef int (*mbencodeinit_func)(MultibyteCodec_State *state,
+				 const void *config);
+typedef Py_ssize_t (*mbencodereset_func)(MultibyteCodec_State *state,
+			const void *config,
+			unsigned char **outbuf, Py_ssize_t outleft);
+typedef Py_ssize_t (*mbdecode_func)(MultibyteCodec_State *state,
+			const void *config,
+			const unsigned char **inbuf, Py_ssize_t inleft,
+			Py_UNICODE **outbuf, Py_ssize_t outleft);
+typedef int (*mbdecodeinit_func)(MultibyteCodec_State *state,
+				 const void *config);
+typedef Py_ssize_t (*mbdecodereset_func)(MultibyteCodec_State *state,
+					 const void *config);
+
+typedef struct {
+	const char *encoding;
+	const void *config;
+	mbcodec_init codecinit;
+	mbencode_func encode;
+	mbencodeinit_func encinit;
+	mbencodereset_func encreset;
+	mbdecode_func decode;
+	mbdecodeinit_func decinit;
+	mbdecodereset_func decreset;
+} MultibyteCodec;
+
+typedef struct {
+	PyObject_HEAD
+	MultibyteCodec *codec;
+} MultibyteCodecObject;
+
+#define MultibyteCodec_Check(op) ((op)->ob_type == &MultibyteCodec_Type)
+
+#define _MultibyteStatefulCodec_HEAD		\
+	PyObject_HEAD				\
+	MultibyteCodec *codec;			\
+	MultibyteCodec_State state;		\
+	PyObject *errors;
+typedef struct {
+	_MultibyteStatefulCodec_HEAD
+} MultibyteStatefulCodecContext;
+
+#define MAXENCPENDING	2
+#define _MultibyteStatefulEncoder_HEAD		\
+	_MultibyteStatefulCodec_HEAD		\
+	Py_UNICODE pending[MAXENCPENDING];	\
+	Py_ssize_t pendingsize;
+typedef struct {
+	_MultibyteStatefulEncoder_HEAD
+} MultibyteStatefulEncoderContext;
+
+#define MAXDECPENDING	8
+#define _MultibyteStatefulDecoder_HEAD		\
+	_MultibyteStatefulCodec_HEAD		\
+	unsigned char pending[MAXDECPENDING];	\
+	Py_ssize_t pendingsize;
+typedef struct {
+	_MultibyteStatefulDecoder_HEAD
+} MultibyteStatefulDecoderContext;
+
+typedef struct {
+	_MultibyteStatefulEncoder_HEAD
+} MultibyteIncrementalEncoderObject;
+
+typedef struct {
+	_MultibyteStatefulDecoder_HEAD
+} MultibyteIncrementalDecoderObject;
+
+typedef struct {
+	_MultibyteStatefulDecoder_HEAD
+	PyObject *stream;
+} MultibyteStreamReaderObject;
+
+typedef struct {
+	_MultibyteStatefulEncoder_HEAD
+	PyObject *stream;
+} MultibyteStreamWriterObject;
+
+/* positive values for illegal sequences */
+#define MBERR_TOOSMALL		(-1) /* insufficient output buffer space */
+#define MBERR_TOOFEW		(-2) /* incomplete input buffer */
+#define MBERR_INTERNAL		(-3) /* internal runtime error */
+
+#define ERROR_STRICT		(PyObject *)(1)
+#define ERROR_IGNORE		(PyObject *)(2)
+#define ERROR_REPLACE		(PyObject *)(3)
+#define ERROR_ISCUSTOM(p)	((p) < ERROR_STRICT || ERROR_REPLACE < (p))
+#define ERROR_DECREF(p) do {			\
+	if (p != NULL && ERROR_ISCUSTOM(p)) {	\
+		Py_DECREF(p);			\
+	}					\
+} while (0);
+
+#define MBENC_FLUSH		0x0001 /* encode all characters encodable */
+#define MBENC_MAX		MBENC_FLUSH
+
+#ifdef __cplusplus
+}
+#endif
+#endif

Added: vendor/Python/current/Modules/clmodule.c
===================================================================
--- vendor/Python/current/Modules/clmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/clmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2559 @@
+
+
+/* Cl objects */
+
+#define CLDEBUG
+
+#include <stdarg.h>
+#include <cl.h>
+#if defined(CL_JPEG_SOFTWARE) && !defined(CL_JPEG_COSMO)
+#include <dmedia/cl_cosmo.h>
+#endif
+#include "Python.h"
+
+typedef struct {
+	PyObject_HEAD
+	int ob_isCompressor;	/* Compressor or Decompressor */
+	CL_Handle ob_compressorHdl;
+	int *ob_paramtypes;
+	int ob_nparams;
+} clobject;
+
+static PyObject *ClError;		/* exception cl.error */
+
+static int error_handler_called = 0;
+
+/*
+ * We want to use the function prototypes that are available in the C
+ * compiler on the SGI.  Because of that, we need to declare the first
+ * argument of the compressor and decompressor methods as "object *",
+ * even though they are really "clobject *".  Therefore we cast the
+ * argument to the proper type using this macro.
+ */
+#define SELF	((clobject *) self)
+
+/********************************************************************
+			  Utility routines.
+********************************************************************/
+static void
+cl_ErrorHandler(CL_Handle handle, int code, const char *fmt, ...)
+{
+	va_list ap;
+	char errbuf[BUFSIZ];	/* hopefully big enough */
+	char *p;
+
+	if (PyErr_Occurred())	/* don't change existing error */
+		return;
+	error_handler_called = 1;
+	va_start(ap, fmt);
+	vsprintf(errbuf, fmt, ap);
+	va_end(ap);
+	p = &errbuf[strlen(errbuf) - 1]; /* swat the line feed */
+	if (*p == '\n')
+		*p = 0;
+	PyErr_SetString(ClError, errbuf);
+}
+
+/*
+ * This assumes that params are always in the range 0 to some maximum.
+ */
+static int
+param_type_is_float(clobject *self, int param)
+{
+	int bufferlength;
+
+	if (self->ob_paramtypes == NULL) {
+		error_handler_called = 0;
+		bufferlength = clQueryParams(self->ob_compressorHdl, 0, 0);
+		if (error_handler_called)
+			return -1;
+
+		self->ob_paramtypes = PyMem_NEW(int, bufferlength);
+		if (self->ob_paramtypes == NULL)
+			return -1;
+		self->ob_nparams = bufferlength / 2;
+
+		(void) clQueryParams(self->ob_compressorHdl,
+				     self->ob_paramtypes, bufferlength);
+		if (error_handler_called) {
+			PyMem_DEL(self->ob_paramtypes);
+			self->ob_paramtypes = NULL;
+			return -1;
+		}
+	}
+
+	if (param < 0 || param >= self->ob_nparams)
+		return -1;
+
+	if (self->ob_paramtypes[param*2 + 1] == CL_FLOATING_ENUM_VALUE ||
+	    self->ob_paramtypes[param*2 + 1] == CL_FLOATING_RANGE_VALUE)
+		return 1;
+	else
+		return 0;
+}
+
+/********************************************************************
+	       Single image compression/decompression.
+********************************************************************/
+static PyObject *
+cl_CompressImage(PyObject *self, PyObject *args)
+{
+	int compressionScheme, width, height, originalFormat;
+	float compressionRatio;
+	int frameBufferSize, compressedBufferSize;
+	char *frameBuffer;
+	PyObject *compressedBuffer;
+
+	if (!PyArg_ParseTuple(args, "iiiifs#", &compressionScheme,
+			 &width, &height,
+			 &originalFormat, &compressionRatio, &frameBuffer,
+			 &frameBufferSize))
+		return NULL;
+
+  retry:
+	compressedBuffer = PyString_FromStringAndSize(NULL, frameBufferSize);
+	if (compressedBuffer == NULL)
+		return NULL;
+
+	compressedBufferSize = frameBufferSize;
+	error_handler_called = 0;
+	if (clCompressImage(compressionScheme, width, height, originalFormat,
+			    compressionRatio, (void *) frameBuffer,
+			    &compressedBufferSize,
+			    (void *) PyString_AsString(compressedBuffer))
+	    == FAILURE || error_handler_called) {
+		Py_DECREF(compressedBuffer);
+		if (!error_handler_called)
+			PyErr_SetString(ClError, "clCompressImage failed");
+		return NULL;
+	}
+
+	if (compressedBufferSize > frameBufferSize) {
+		frameBufferSize = compressedBufferSize;
+		Py_DECREF(compressedBuffer);
+		goto retry;
+	}
+
+	if (compressedBufferSize < frameBufferSize)
+		_PyString_Resize(&compressedBuffer, compressedBufferSize);
+
+	return compressedBuffer;
+}
+
+static PyObject *
+cl_DecompressImage(PyObject *self, PyObject *args)
+{
+	int compressionScheme, width, height, originalFormat;
+	char *compressedBuffer;
+	int compressedBufferSize, frameBufferSize;
+	PyObject *frameBuffer;
+
+	if (!PyArg_ParseTuple(args, "iiiis#", &compressionScheme, &width, &height,
+			 &originalFormat, &compressedBuffer,
+			 &compressedBufferSize))
+		return NULL;
+
+	frameBufferSize = width * height * CL_BytesPerPixel(originalFormat);
+
+	frameBuffer = PyString_FromStringAndSize(NULL, frameBufferSize);
+	if (frameBuffer == NULL)
+		return NULL;
+
+	error_handler_called = 0;
+	if (clDecompressImage(compressionScheme, width, height, originalFormat,
+			      compressedBufferSize, compressedBuffer,
+			      (void *) PyString_AsString(frameBuffer))
+	    == FAILURE || error_handler_called) {
+		Py_DECREF(frameBuffer);
+		if (!error_handler_called)
+			PyErr_SetString(ClError, "clDecompressImage failed");
+		return NULL;
+	}
+
+	return frameBuffer;
+}
+
+/********************************************************************
+		Sequential compression/decompression.
+********************************************************************/
+#define CheckCompressor(self)	if ((self)->ob_compressorHdl == NULL) { \
+	PyErr_SetString(PyExc_RuntimeError, "(de)compressor not active"); \
+	return NULL; \
+}
+
+static PyObject *
+doClose(clobject *self, int (*close_func)(CL_Handle))
+{
+	CheckCompressor(self);
+
+	error_handler_called = 0;
+	if ((*close_func)(self->ob_compressorHdl) == FAILURE ||
+	    error_handler_called) {
+		if (!error_handler_called)
+			PyErr_SetString(ClError, "close failed");
+		return NULL;
+	}
+
+	self->ob_compressorHdl = NULL;
+
+	if (self->ob_paramtypes)
+		PyMem_DEL(self->ob_paramtypes);
+	self->ob_paramtypes = NULL;
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+clm_CloseCompressor(PyObject *self)
+{
+	return doClose(SELF, clCloseCompressor);
+}
+
+static PyObject *
+clm_CloseDecompressor(PyObject *self)
+{
+	return doClose(SELF, clCloseDecompressor);
+}
+
+static PyObject *
+clm_Compress(PyObject *self, PyObject *args)
+{
+	int numberOfFrames;
+	int frameBufferSize, compressedBufferSize, size;
+	char *frameBuffer;
+	PyObject *data;
+
+	CheckCompressor(SELF);
+
+	if (!PyArg_Parse(args, "(is#)", &numberOfFrames,
+			 &frameBuffer, &frameBufferSize))
+		return NULL;
+
+	error_handler_called = 0;
+	size = clGetParam(SELF->ob_compressorHdl, CL_COMPRESSED_BUFFER_SIZE);
+	compressedBufferSize = size;
+	if (error_handler_called)
+		return NULL;
+
+	data = PyString_FromStringAndSize(NULL, size);
+	if (data == NULL)
+		return NULL;
+
+	error_handler_called = 0;
+	if (clCompress(SELF->ob_compressorHdl, numberOfFrames,
+		       (void *) frameBuffer, &compressedBufferSize,
+		       (void *) PyString_AsString(data)) == FAILURE ||
+	    error_handler_called) {
+		Py_DECREF(data);
+		if (!error_handler_called)
+			PyErr_SetString(ClError, "compress failed");
+		return NULL;
+	}
+
+	if (compressedBufferSize < size)
+		if (_PyString_Resize(&data, compressedBufferSize))
+			return NULL;
+
+	if (compressedBufferSize > size) {
+		/* we didn't get all "compressed" data */
+		Py_DECREF(data);
+		PyErr_SetString(ClError,
+				"compressed data is more than fitted");
+		return NULL;
+	}
+
+	return data;
+}
+
+static PyObject *
+clm_Decompress(PyObject *self, PyObject *args)
+{
+	PyObject *data;
+	int numberOfFrames;
+	char *compressedData;
+	int compressedDataSize, dataSize;
+
+	CheckCompressor(SELF);
+
+	if (!PyArg_Parse(args, "(is#)", &numberOfFrames, &compressedData,
+			 &compressedDataSize))
+		return NULL;
+
+	error_handler_called = 0;
+	dataSize = clGetParam(SELF->ob_compressorHdl, CL_FRAME_BUFFER_SIZE);
+	if (error_handler_called)
+		return NULL;
+
+	data = PyString_FromStringAndSize(NULL, dataSize);
+	if (data == NULL)
+		return NULL;
+
+	error_handler_called = 0;
+	if (clDecompress(SELF->ob_compressorHdl, numberOfFrames,
+			 compressedDataSize, (void *) compressedData,
+			 (void *) PyString_AsString(data)) == FAILURE ||
+	    error_handler_called) {
+		Py_DECREF(data);
+		if (!error_handler_called)
+			PyErr_SetString(ClError, "decompress failed");
+		return NULL;
+	}
+
+	return data;
+}
+
+static PyObject *
+doParams(clobject *self, PyObject *args, int (*func)(CL_Handle, int *, int),
+	 int modified)
+{
+	PyObject *list, *v;
+	int *PVbuffer;
+	int length;
+	int i;
+	float number;
+	
+	CheckCompressor(self);
+
+	if (!PyArg_Parse(args, "O", &list))
+		return NULL;
+	if (!PyList_Check(list)) {
+		PyErr_BadArgument();
+		return NULL;
+	}
+	length = PyList_Size(list);
+	PVbuffer = PyMem_NEW(int, length);
+	if (PVbuffer == NULL)
+		return PyErr_NoMemory();
+	for (i = 0; i < length; i++) {
+		v = PyList_GetItem(list, i);
+		if (PyFloat_Check(v)) {
+			number = PyFloat_AsDouble(v);
+			PVbuffer[i] = CL_TypeIsInt(number);
+		} else if (PyInt_Check(v)) {
+			PVbuffer[i] = PyInt_AsLong(v);
+			if ((i & 1) &&
+			    param_type_is_float(self, PVbuffer[i-1]) > 0) {
+				number = PVbuffer[i];
+				PVbuffer[i] = CL_TypeIsInt(number);
+			}
+		} else {
+			PyMem_DEL(PVbuffer);
+			PyErr_BadArgument();
+			return NULL;
+		}
+	}
+
+	error_handler_called = 0;
+	(*func)(self->ob_compressorHdl, PVbuffer, length);
+	if (error_handler_called) {
+		PyMem_DEL(PVbuffer);
+		return NULL;
+	}
+
+	if (modified) {
+		for (i = 0; i < length; i++) {
+			if ((i & 1) &&
+			    param_type_is_float(self, PVbuffer[i-1]) > 0) {
+				number = CL_TypeIsFloat(PVbuffer[i]);
+				v = PyFloat_FromDouble(number);
+			} else
+				v = PyInt_FromLong(PVbuffer[i]);
+			PyList_SetItem(list, i, v);
+		}
+	}
+
+	PyMem_DEL(PVbuffer);
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+clm_GetParams(PyObject *self, PyObject *args)
+{
+	return doParams(SELF, args, clGetParams, 1);
+}
+
+static PyObject *
+clm_SetParams(PyObject *self, PyObject *args)
+{
+	return doParams(SELF, args, clSetParams, 0);
+}
+
+static PyObject *
+do_get(clobject *self, PyObject *args, int (*func)(CL_Handle, int))
+{
+	int paramID, value;
+	float fvalue;
+
+	CheckCompressor(self);
+
+	if (!PyArg_Parse(args, "i", &paramID))
+		return NULL;
+
+	error_handler_called = 0;
+	value = (*func)(self->ob_compressorHdl, paramID);
+	if (error_handler_called)
+		return NULL;
+
+	if (param_type_is_float(self, paramID) > 0) {
+		fvalue = CL_TypeIsFloat(value);
+		return PyFloat_FromDouble(fvalue);
+	}
+
+	return PyInt_FromLong(value);
+}
+
+static PyObject *
+clm_GetParam(PyObject *self, PyObject *args)
+{
+	return do_get(SELF, args, clGetParam);
+}
+
+static PyObject *
+clm_GetDefault(PyObject *self, PyObject *args)
+{
+	return do_get(SELF, args, clGetDefault);
+}
+
+static PyObject *
+clm_SetParam(PyObject *self, PyObject *args)
+{
+	int paramID, value;
+	float fvalue;
+
+	CheckCompressor(SELF);
+
+	if (!PyArg_Parse(args, "(ii)", &paramID, &value)) {
+		PyErr_Clear();
+		if (!PyArg_Parse(args, "(if)", &paramID, &fvalue)) {
+			PyErr_Clear();
+			PyErr_SetString(PyExc_TypeError,
+			       "bad argument list (format '(ii)' or '(if)')");
+			return NULL;
+		}
+		value = CL_TypeIsInt(fvalue);
+	} else {
+		if (param_type_is_float(SELF, paramID) > 0) {
+			fvalue = value;
+			value = CL_TypeIsInt(fvalue);
+		}
+	}
+
+ 	error_handler_called = 0;
+	value = clSetParam(SELF->ob_compressorHdl, paramID, value);
+	if (error_handler_called)
+		return NULL;
+
+	if (param_type_is_float(SELF, paramID) > 0)
+		return PyFloat_FromDouble(CL_TypeIsFloat(value));
+	else
+		return PyInt_FromLong(value);
+}
+
+static PyObject *
+clm_GetParamID(PyObject *self, PyObject *args)
+{
+	char *name;
+	int value;
+
+	CheckCompressor(SELF);
+
+	if (!PyArg_Parse(args, "s", &name))
+		return NULL;
+
+	error_handler_called = 0;
+	value = clGetParamID(SELF->ob_compressorHdl, name);
+	if (value == FAILURE || error_handler_called) {
+		if (!error_handler_called)
+			PyErr_SetString(ClError, "getparamid failed");
+		return NULL;
+	}
+
+	return PyInt_FromLong(value);
+}
+
+static PyObject *
+clm_QueryParams(PyObject *self)
+{
+	int bufferlength;
+	int *PVbuffer;
+	PyObject *list;
+	int i;
+
+	CheckCompressor(SELF);
+
+	error_handler_called = 0;
+	bufferlength = clQueryParams(SELF->ob_compressorHdl, 0, 0);
+	if (error_handler_called)
+		return NULL;
+
+	PVbuffer = PyMem_NEW(int, bufferlength);
+	if (PVbuffer == NULL)
+		return PyErr_NoMemory();
+
+	bufferlength = clQueryParams(SELF->ob_compressorHdl, PVbuffer,
+				     bufferlength);
+	if (error_handler_called) {
+		PyMem_DEL(PVbuffer);
+		return NULL;
+	}
+
+	list = PyList_New(bufferlength);
+	if (list == NULL) {
+		PyMem_DEL(PVbuffer);
+		return NULL;
+	}
+
+	for (i = 0; i < bufferlength; i++) {
+		if (i & 1)
+			PyList_SetItem(list, i, PyInt_FromLong(PVbuffer[i]));
+		else if (PVbuffer[i] == 0) {
+			Py_INCREF(Py_None);
+			PyList_SetItem(list, i, Py_None);
+		} else
+			PyList_SetItem(list, i,
+				   PyString_FromString((char *) PVbuffer[i]));
+	}
+
+	PyMem_DEL(PVbuffer);
+
+	return list;
+}
+
+static PyObject *
+clm_GetMinMax(PyObject *self, PyObject *args)
+{
+	int param, min, max;
+	float fmin, fmax;
+
+	CheckCompressor(SELF);
+
+	if (!PyArg_Parse(args, "i", &param))
+		return NULL;
+
+	clGetMinMax(SELF->ob_compressorHdl, param, &min, &max);
+
+	if (param_type_is_float(SELF, param) > 0) {
+		fmin = CL_TypeIsFloat(min);
+		fmax = CL_TypeIsFloat(max);
+		return Py_BuildValue("(ff)", fmin, fmax);
+	}
+
+	return Py_BuildValue("(ii)", min, max);
+}
+
+static PyObject *
+clm_GetName(PyObject *self, PyObject *args)
+{
+	int param;
+	char *name;
+
+	CheckCompressor(SELF);
+
+	if (!PyArg_Parse(args, "i", &param))
+		return NULL;
+
+	error_handler_called = 0;
+	name = clGetName(SELF->ob_compressorHdl, param);
+	if (name == NULL || error_handler_called) {
+		if (!error_handler_called)
+			PyErr_SetString(ClError, "getname failed");
+		return NULL;
+	}
+
+	return PyString_FromString(name);
+}
+
+static PyObject *
+clm_QuerySchemeFromHandle(PyObject *self)
+{
+	CheckCompressor(SELF);
+	return PyInt_FromLong(clQuerySchemeFromHandle(SELF->ob_compressorHdl));
+}
+
+static PyObject *
+clm_ReadHeader(PyObject *self, PyObject *args)
+{
+	char *header;
+	int headerSize;
+
+	CheckCompressor(SELF);
+
+	if (!PyArg_Parse(args, "s#", &header, &headerSize))
+		return NULL;
+
+	return PyInt_FromLong(clReadHeader(SELF->ob_compressorHdl,
+					   headerSize, header));
+}
+
+static PyMethodDef compressor_methods[] = {
+	{"close",		clm_CloseCompressor, METH_NOARGS}, /* alias */
+	{"CloseCompressor",	clm_CloseCompressor, METH_NOARGS},
+	{"Compress",		clm_Compress, METH_OLDARGS},
+	{"GetDefault",		clm_GetDefault, METH_OLDARGS},
+	{"GetMinMax",		clm_GetMinMax, METH_OLDARGS},
+	{"GetName",		clm_GetName, METH_OLDARGS},
+	{"GetParam",		clm_GetParam, METH_OLDARGS},
+	{"GetParamID",		clm_GetParamID, METH_OLDARGS},
+	{"GetParams",		clm_GetParams, METH_OLDARGS},
+	{"QueryParams",		clm_QueryParams, METH_NOARGS},
+	{"QuerySchemeFromHandle",clm_QuerySchemeFromHandle, METH_NOARGS},
+	{"SetParam",		clm_SetParam, METH_OLDARGS},
+	{"SetParams",		clm_SetParams, METH_OLDARGS},
+	{NULL,			NULL}		/* sentinel */
+};
+
+static PyMethodDef decompressor_methods[] = {
+	{"close",		clm_CloseDecompressor, METH_NOARGS},	/* alias */
+	{"CloseDecompressor",	clm_CloseDecompressor, METH_NOARGS},
+	{"Decompress",		clm_Decompress, METH_OLDARGS},
+	{"GetDefault",		clm_GetDefault, METH_OLDARGS},
+	{"GetMinMax",		clm_GetMinMax, METH_OLDARGS},
+	{"GetName",		clm_GetName, METH_OLDARGS},
+	{"GetParam",		clm_GetParam, METH_OLDARGS},
+	{"GetParamID",		clm_GetParamID, METH_OLDARGS},
+	{"GetParams",		clm_GetParams, METH_OLDARGS},
+	{"ReadHeader",		clm_ReadHeader, METH_OLDARGS},
+	{"QueryParams",		clm_QueryParams, METH_NOARGS},
+	{"QuerySchemeFromHandle",clm_QuerySchemeFromHandle, METH_NOARGS},
+	{"SetParam",		clm_SetParam, METH_OLDARGS},
+	{"SetParams",		clm_SetParams, METH_OLDARGS},
+	{NULL,			NULL}		/* sentinel */
+};
+
+static void
+cl_dealloc(PyObject *self)
+{
+	if (SELF->ob_compressorHdl) {
+		if (SELF->ob_isCompressor)
+			clCloseCompressor(SELF->ob_compressorHdl);
+		else
+			clCloseDecompressor(SELF->ob_compressorHdl);
+	}
+	PyObject_Del(self);
+}
+
+static PyObject *
+cl_getattr(PyObject *self, char *name)
+{
+	if (SELF->ob_isCompressor)
+		return Py_FindMethod(compressor_methods, self, name);
+	else
+		return Py_FindMethod(decompressor_methods, self, name);
+}
+
+static PyTypeObject Cltype = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,			/*ob_size*/
+	"cl.cl",		/*tp_name*/
+	sizeof(clobject),	/*tp_size*/
+	0,			/*tp_itemsize*/
+	/* methods */
+	(destructor)cl_dealloc,	/*tp_dealloc*/
+	0,			/*tp_print*/
+	(getattrfunc)cl_getattr, /*tp_getattr*/
+	0,			/*tp_setattr*/
+	0,			/*tp_compare*/
+	0,			/*tp_repr*/
+	0,			/*tp_as_number*/
+	0,			/*tp_as_sequence*/
+	0,			/*tp_as_mapping*/
+};
+
+static PyObject *
+doOpen(PyObject *self, PyObject *args, int (*open_func)(int, CL_Handle *),
+       int iscompressor)
+{
+	int scheme;
+	clobject *new;
+
+	if (!PyArg_ParseTuple(args, "i", &scheme))
+		return NULL;
+
+	new = PyObject_New(clobject, &Cltype);
+	if (new == NULL)
+		return NULL;
+
+	new->ob_compressorHdl = NULL;
+	new->ob_isCompressor = iscompressor;
+	new->ob_paramtypes = NULL;
+
+	error_handler_called = 0;
+	if ((*open_func)(scheme, &new->ob_compressorHdl) == FAILURE ||
+	    error_handler_called) {
+		Py_DECREF(new);
+		if (!error_handler_called)
+			PyErr_SetString(ClError, "Open(De)Compressor failed");
+		return NULL;
+	}
+	return (PyObject *)new;
+}
+
+static PyObject *
+cl_OpenCompressor(PyObject *self, PyObject *args)
+{
+	return doOpen(self, args, clOpenCompressor, 1);
+}
+
+static PyObject *
+cl_OpenDecompressor(PyObject *self, PyObject *args)
+{
+	return doOpen(self, args, clOpenDecompressor, 0);
+}
+
+static PyObject *
+cl_QueryScheme(PyObject *self, PyObject *args)
+{
+	char *header;
+	int headerlen;
+	int scheme;
+
+	if (!PyArg_ParseTuple(args, "s#", &header, &headerlen))
+		return NULL;
+
+	scheme = clQueryScheme(header);
+	if (scheme < 0) {
+		PyErr_SetString(ClError, "unknown compression scheme");
+		return NULL;
+	}
+
+	return PyInt_FromLong(scheme);
+}
+
+static PyObject *
+cl_QueryMaxHeaderSize(PyObject *self, PyObject *args)
+{
+	int scheme;
+
+	if (!PyArg_ParseTuple(args, "i", &scheme))
+		return NULL;
+
+	return PyInt_FromLong(clQueryMaxHeaderSize(scheme));
+}
+
+static PyObject *
+cl_QueryAlgorithms(PyObject *self, PyObject *args)
+{
+	int algorithmMediaType;
+	int bufferlength;
+	int *PVbuffer;
+	PyObject *list;
+	int i;
+
+	if (!PyArg_ParseTuple(args, "i", &algorithmMediaType))
+		return NULL;
+
+	error_handler_called = 0;
+	bufferlength = clQueryAlgorithms(algorithmMediaType, 0, 0);
+	if (error_handler_called)
+		return NULL;
+
+	PVbuffer = PyMem_NEW(int, bufferlength);
+	if (PVbuffer == NULL)
+		return PyErr_NoMemory();
+
+	bufferlength = clQueryAlgorithms(algorithmMediaType, PVbuffer,
+					 bufferlength);
+	if (error_handler_called) {
+		PyMem_DEL(PVbuffer);
+		return NULL;
+	}
+
+	list = PyList_New(bufferlength);
+	if (list == NULL) {
+		PyMem_DEL(PVbuffer);
+		return NULL;
+	}
+
+	for (i = 0; i < bufferlength; i++) {
+		if (i & 1)
+			PyList_SetItem(list, i, PyInt_FromLong(PVbuffer[i]));
+		else if (PVbuffer[i] == 0) {
+			Py_INCREF(Py_None);
+			PyList_SetItem(list, i, Py_None);
+		} else
+			PyList_SetItem(list, i,
+				   PyString_FromString((char *) PVbuffer[i]));
+	}
+
+	PyMem_DEL(PVbuffer);
+
+	return list;
+}
+
+static PyObject *
+cl_QuerySchemeFromName(PyObject *self, PyObject *args)
+{
+	int algorithmMediaType;
+	char *name;
+	int scheme;
+
+	if (!PyArg_ParseTuple(args, "is", &algorithmMediaType, &name))
+		return NULL;
+
+	error_handler_called = 0;
+	scheme = clQuerySchemeFromName(algorithmMediaType, name);
+	if (error_handler_called) {
+		PyErr_SetString(ClError, "unknown compression scheme");
+		return NULL;
+	}
+
+	return PyInt_FromLong(scheme);
+}
+
+static PyObject *
+cl_GetAlgorithmName(PyObject *self, PyObject *args)
+{
+	int scheme;
+	char *name;
+
+	if (!PyArg_ParseTuple(args, "i", &scheme))
+		return NULL;
+
+	name = clGetAlgorithmName(scheme);
+	if (name == 0) {
+		PyErr_SetString(ClError, "unknown compression scheme");
+		return NULL;
+	}
+
+	return PyString_FromString(name);
+}
+
+static PyObject *
+do_set(PyObject *self, PyObject *args, int (*func)(int, int, int))
+{
+	int scheme, paramID, value;
+	float fvalue;
+	int is_float = 0;
+
+	if (!PyArg_ParseTuple(args, "iii", &scheme, &paramID, &value)) {
+		PyErr_Clear();
+		if (!PyArg_ParseTuple(args, "iif", &scheme, &paramID, &fvalue)) {
+			PyErr_Clear();
+			PyErr_SetString(PyExc_TypeError,
+			     "bad argument list (format '(iii)' or '(iif)')");
+			return NULL;
+		}
+		value = CL_TypeIsInt(fvalue);
+		is_float = 1;
+	} else {
+		/* check some parameters which we know to be floats */
+		switch (scheme) {
+		case CL_COMPRESSION_RATIO:
+		case CL_SPEED:
+			fvalue = value;
+			value = CL_TypeIsInt(fvalue);
+			is_float = 1;
+			break;
+		}
+	}
+
+ 	error_handler_called = 0;
+	value = (*func)(scheme, paramID, value);
+	if (error_handler_called)
+		return NULL;
+
+	if (is_float)
+		return PyFloat_FromDouble(CL_TypeIsFloat(value));
+	else
+		return PyInt_FromLong(value);
+}
+
+static PyObject *
+cl_SetDefault(PyObject *self, PyObject *args)
+{
+	return do_set(self, args, clSetDefault);
+}
+
+static PyObject *
+cl_SetMin(PyObject *self, PyObject *args)
+{
+	return do_set(self, args, clSetMin);
+}
+
+static PyObject *
+cl_SetMax(PyObject *self, PyObject *args)
+{
+	return do_set(self, args, clSetMax);
+}
+
+#define func(name, handler)	\
+static PyObject *cl_##name(PyObject *self, PyObject *args) \
+{ \
+	  int x; \
+	  if (!PyArg_ParseTuple(args, "i", &x)) return NULL; \
+	  return Py##handler(CL_##name(x)); \
+}
+
+#define func2(name, handler)	\
+static PyObject *cl_##name(PyObject *self, PyObject *args) \
+{ \
+	  int a1, a2; \
+	  if (!PyArg_ParseTuple(args, "ii", &a1, &a2)) return NULL; \
+	  return Py##handler(CL_##name(a1, a2)); \
+}
+
+func(BytesPerSample, Int_FromLong)
+func(BytesPerPixel, Int_FromLong)
+func(AudioFormatName, String_FromString)
+func(VideoFormatName, String_FromString)
+func(AlgorithmNumber, Int_FromLong)
+func(AlgorithmType, Int_FromLong)
+func2(Algorithm, Int_FromLong)
+func(ParamNumber, Int_FromLong)
+func(ParamType, Int_FromLong)
+func2(ParamID, Int_FromLong)
+
+#ifdef CLDEBUG
+	static PyObject *
+cvt_type(PyObject *self, PyObject *args)
+{
+	int number;
+	float fnumber;
+
+	if (PyArg_Parse(args, "i", &number))
+		return PyFloat_FromDouble(CL_TypeIsFloat(number));
+	else {
+		PyErr_Clear();
+		if (PyArg_Parse(args, "f", &fnumber))
+			return PyInt_FromLong(CL_TypeIsInt(fnumber));
+		return NULL;
+	}
+}
+#endif
+
+static PyMethodDef cl_methods[] = {
+	{"CompressImage",	cl_CompressImage, METH_VARARGS},
+	{"DecompressImage",	cl_DecompressImage, METH_VARARGS},
+	{"GetAlgorithmName",	cl_GetAlgorithmName, METH_VARARGS},
+	{"OpenCompressor",	cl_OpenCompressor, METH_VARARGS},
+	{"OpenDecompressor",	cl_OpenDecompressor, METH_VARARGS},
+	{"QueryAlgorithms",	cl_QueryAlgorithms, METH_VARARGS},
+	{"QueryMaxHeaderSize",	cl_QueryMaxHeaderSize, METH_VARARGS},
+	{"QueryScheme",		cl_QueryScheme, METH_VARARGS},
+	{"QuerySchemeFromName",	cl_QuerySchemeFromName, METH_VARARGS},
+	{"SetDefault",		cl_SetDefault, METH_VARARGS},
+	{"SetMax",		cl_SetMax, METH_VARARGS},
+	{"SetMin",		cl_SetMin, METH_VARARGS},
+	{"BytesPerSample",	cl_BytesPerSample, METH_VARARGS},
+	{"BytesPerPixel",	cl_BytesPerPixel, METH_VARARGS},
+	{"AudioFormatName",	cl_AudioFormatName, METH_VARARGS},
+	{"VideoFormatName",	cl_VideoFormatName, METH_VARARGS},
+	{"AlgorithmNumber",	cl_AlgorithmNumber, METH_VARARGS},
+	{"AlgorithmType",	cl_AlgorithmType, METH_VARARGS},
+	{"Algorithm",		cl_Algorithm, METH_VARARGS},
+	{"ParamNumber",		cl_ParamNumber, METH_VARARGS},
+	{"ParamType",		cl_ParamType, METH_VARARGS},
+	{"ParamID",		cl_ParamID, METH_VARARGS},
+#ifdef CLDEBUG
+	{"cvt_type",		cvt_type, METH_VARARGS},
+#endif
+	{NULL,			NULL} /* Sentinel */
+};
+
+#ifdef CL_JPEG_SOFTWARE
+#define IRIX_5_3_LIBRARY
+#endif
+
+void
+initcl(void)
+{
+	PyObject *m, *d, *x;
+
+	m = Py_InitModule("cl", cl_methods);
+	if (m == NULL)
+		return;
+	d = PyModule_GetDict(m);
+
+	ClError = PyErr_NewException("cl.error", NULL, NULL);
+	(void) PyDict_SetItemString(d, "error", ClError);
+
+#ifdef CL_ADDED_ALGORITHM_ERROR
+	x = PyInt_FromLong(CL_ADDED_ALGORITHM_ERROR);
+	if (x == NULL || PyDict_SetItemString(d, "ADDED_ALGORITHM_ERROR", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_ALAW
+	x = PyInt_FromLong(CL_ALAW);
+	if (x == NULL || PyDict_SetItemString(d, "ALAW", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_ALGORITHM_ID
+	x = PyInt_FromLong(CL_ALGORITHM_ID);
+	if (x == NULL || PyDict_SetItemString(d, "ALGORITHM_ID", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_ALGORITHM_TABLE_FULL
+	x = PyInt_FromLong(CL_ALGORITHM_TABLE_FULL);
+	if (x == NULL || PyDict_SetItemString(d, "ALGORITHM_TABLE_FULL", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_ALGORITHM_VERSION
+	x = PyInt_FromLong(CL_ALGORITHM_VERSION);
+	if (x == NULL || PyDict_SetItemString(d, "ALGORITHM_VERSION", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_ALG_AUDIO
+	x = PyInt_FromLong(CL_ALG_AUDIO);
+	if (x == NULL || PyDict_SetItemString(d, "ALG_AUDIO", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_ALG_VIDEO
+	x = PyInt_FromLong(CL_ALG_VIDEO);
+	if (x == NULL || PyDict_SetItemString(d, "ALG_VIDEO", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_AUDIO
+	x = PyInt_FromLong(CL_AUDIO);
+	if (x == NULL || PyDict_SetItemString(d, "AUDIO", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_AWARE_BITRATE_POLICY
+	x = PyInt_FromLong(CL_AWARE_BITRATE_POLICY);
+	if (x == NULL || PyDict_SetItemString(d, "AWARE_BITRATE_POLICY", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_AWARE_BITRATE_TARGET
+	x = PyInt_FromLong(CL_AWARE_BITRATE_TARGET);
+	if (x == NULL || PyDict_SetItemString(d, "AWARE_BITRATE_TARGET", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_AWARE_CHANNEL_POLICY
+	x = PyInt_FromLong(CL_AWARE_CHANNEL_POLICY);
+	if (x == NULL || PyDict_SetItemString(d, "AWARE_CHANNEL_POLICY", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_AWARE_CONST_QUAL
+	x = PyInt_FromLong(CL_AWARE_CONST_QUAL);
+	if (x == NULL || PyDict_SetItemString(d, "AWARE_CONST_QUAL", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_AWARE_ERROR
+	x = PyInt_FromLong(CL_AWARE_ERROR);
+	if (x == NULL || PyDict_SetItemString(d, "AWARE_ERROR", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_AWARE_FIXED_RATE
+	x = PyInt_FromLong(CL_AWARE_FIXED_RATE);
+	if (x == NULL || PyDict_SetItemString(d, "AWARE_FIXED_RATE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_AWARE_INDEPENDENT
+	x = PyInt_FromLong(CL_AWARE_INDEPENDENT);
+	if (x == NULL || PyDict_SetItemString(d, "AWARE_INDEPENDENT", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_AWARE_JOINT_STEREO
+	x = PyInt_FromLong(CL_AWARE_JOINT_STEREO);
+	if (x == NULL || PyDict_SetItemString(d, "AWARE_JOINT_STEREO", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_AWARE_LAYER
+	x = PyInt_FromLong(CL_AWARE_LAYER);
+	if (x == NULL || PyDict_SetItemString(d, "AWARE_LAYER", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_AWARE_LOSSLESS
+	x = PyInt_FromLong(CL_AWARE_LOSSLESS);
+	if (x == NULL || PyDict_SetItemString(d, "AWARE_LOSSLESS", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_AWARE_MPEG_AUDIO
+	x = PyInt_FromLong(CL_AWARE_MPEG_AUDIO);
+	if (x == NULL || PyDict_SetItemString(d, "AWARE_MPEG_AUDIO", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_AWARE_MPEG_LAYER_I
+	x = PyInt_FromLong(CL_AWARE_MPEG_LAYER_I);
+	if (x == NULL || PyDict_SetItemString(d, "AWARE_MPEG_LAYER_I", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_AWARE_MPEG_LAYER_II
+	x = PyInt_FromLong(CL_AWARE_MPEG_LAYER_II);
+	if (x == NULL || PyDict_SetItemString(d, "AWARE_MPEG_LAYER_II", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_AWARE_MULTIRATE
+	x = PyInt_FromLong(CL_AWARE_MULTIRATE);
+	if (x == NULL || PyDict_SetItemString(d, "AWARE_MULTIRATE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_AWARE_NOISE_MARGIN
+	x = PyInt_FromLong(CL_AWARE_NOISE_MARGIN);
+	if (x == NULL || PyDict_SetItemString(d, "AWARE_NOISE_MARGIN", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_AWARE_STEREO
+	x = PyInt_FromLong(CL_AWARE_STEREO);
+	if (x == NULL || PyDict_SetItemString(d, "AWARE_STEREO", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_BAD_ALGORITHM_NAME
+	x = PyInt_FromLong(CL_BAD_ALGORITHM_NAME);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_ALGORITHM_NAME", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_BAD_ALGORITHM_TYPE
+	x = PyInt_FromLong(CL_BAD_ALGORITHM_TYPE);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_ALGORITHM_TYPE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_BAD_BLOCK_SIZE
+	x = PyInt_FromLong(CL_BAD_BLOCK_SIZE);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_BLOCK_SIZE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_BAD_BOARD
+	x = PyInt_FromLong(CL_BAD_BOARD);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_BOARD", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_BAD_BUFFERING
+	x = PyInt_FromLong(CL_BAD_BUFFERING);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_BUFFERING", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_BAD_BUFFERLENGTH_NEG
+	x = PyInt_FromLong(CL_BAD_BUFFERLENGTH_NEG);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_BUFFERLENGTH_NEG", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_BAD_BUFFERLENGTH_ODD
+	x = PyInt_FromLong(CL_BAD_BUFFERLENGTH_ODD);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_BUFFERLENGTH_ODD", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_BAD_BUFFER_EXISTS
+	x = PyInt_FromLong(CL_BAD_BUFFER_EXISTS);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_BUFFER_EXISTS", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_BAD_BUFFER_HANDLE
+	x = PyInt_FromLong(CL_BAD_BUFFER_HANDLE);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_BUFFER_HANDLE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_BAD_BUFFER_POINTER
+	x = PyInt_FromLong(CL_BAD_BUFFER_POINTER);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_BUFFER_POINTER", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_BAD_BUFFER_QUERY_SIZE
+	x = PyInt_FromLong(CL_BAD_BUFFER_QUERY_SIZE);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_BUFFER_QUERY_SIZE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_BAD_BUFFER_SIZE
+	x = PyInt_FromLong(CL_BAD_BUFFER_SIZE);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_BUFFER_SIZE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_BAD_BUFFER_SIZE_POINTER
+	x = PyInt_FromLong(CL_BAD_BUFFER_SIZE_POINTER);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_BUFFER_SIZE_POINTER", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_BAD_BUFFER_TYPE
+	x = PyInt_FromLong(CL_BAD_BUFFER_TYPE);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_BUFFER_TYPE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_BAD_COMPRESSION_SCHEME
+	x = PyInt_FromLong(CL_BAD_COMPRESSION_SCHEME);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_COMPRESSION_SCHEME", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_BAD_COMPRESSOR_HANDLE
+	x = PyInt_FromLong(CL_BAD_COMPRESSOR_HANDLE);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_COMPRESSOR_HANDLE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_BAD_COMPRESSOR_HANDLE_POINTER
+	x = PyInt_FromLong(CL_BAD_COMPRESSOR_HANDLE_POINTER);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_COMPRESSOR_HANDLE_POINTER", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_BAD_FRAME_SIZE
+	x = PyInt_FromLong(CL_BAD_FRAME_SIZE);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_FRAME_SIZE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_BAD_FUNCTIONALITY
+	x = PyInt_FromLong(CL_BAD_FUNCTIONALITY);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_FUNCTIONALITY", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_BAD_FUNCTION_POINTER
+	x = PyInt_FromLong(CL_BAD_FUNCTION_POINTER);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_FUNCTION_POINTER", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_BAD_HEADER_SIZE
+	x = PyInt_FromLong(CL_BAD_HEADER_SIZE);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_HEADER_SIZE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_BAD_INITIAL_VALUE
+	x = PyInt_FromLong(CL_BAD_INITIAL_VALUE);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_INITIAL_VALUE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_BAD_INTERNAL_FORMAT
+	x = PyInt_FromLong(CL_BAD_INTERNAL_FORMAT);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_INTERNAL_FORMAT", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_BAD_LICENSE
+	x = PyInt_FromLong(CL_BAD_LICENSE);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_LICENSE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_BAD_MIN_GT_MAX
+	x = PyInt_FromLong(CL_BAD_MIN_GT_MAX);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_MIN_GT_MAX", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_BAD_NO_BUFFERSPACE
+	x = PyInt_FromLong(CL_BAD_NO_BUFFERSPACE);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_NO_BUFFERSPACE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_BAD_NUMBER_OF_BLOCKS
+	x = PyInt_FromLong(CL_BAD_NUMBER_OF_BLOCKS);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_NUMBER_OF_BLOCKS", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_BAD_PARAM
+	x = PyInt_FromLong(CL_BAD_PARAM);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_PARAM", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_BAD_PARAM_ID_POINTER
+	x = PyInt_FromLong(CL_BAD_PARAM_ID_POINTER);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_PARAM_ID_POINTER", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_BAD_PARAM_TYPE
+	x = PyInt_FromLong(CL_BAD_PARAM_TYPE);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_PARAM_TYPE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_BAD_POINTER
+	x = PyInt_FromLong(CL_BAD_POINTER);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_POINTER", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_BAD_PVBUFFER
+	x = PyInt_FromLong(CL_BAD_PVBUFFER);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_PVBUFFER", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_BAD_SCHEME_POINTER
+	x = PyInt_FromLong(CL_BAD_SCHEME_POINTER);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_SCHEME_POINTER", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_BAD_STREAM_HEADER
+	x = PyInt_FromLong(CL_BAD_STREAM_HEADER);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_STREAM_HEADER", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_BAD_STRING_POINTER
+	x = PyInt_FromLong(CL_BAD_STRING_POINTER);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_STRING_POINTER", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_BAD_TEXT_STRING_PTR
+	x = PyInt_FromLong(CL_BAD_TEXT_STRING_PTR);
+	if (x == NULL || PyDict_SetItemString(d, "BAD_TEXT_STRING_PTR", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_BEST_FIT
+	x = PyInt_FromLong(CL_BEST_FIT);
+	if (x == NULL || PyDict_SetItemString(d, "BEST_FIT", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_BIDIRECTIONAL
+	x = PyInt_FromLong(CL_BIDIRECTIONAL);
+	if (x == NULL || PyDict_SetItemString(d, "BIDIRECTIONAL", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_BITRATE
+	x = PyInt_FromLong(CL_BITRATE);
+	if (x == NULL || PyDict_SetItemString(d, "BITRATE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_BITRATE_POLICY
+	x = PyInt_FromLong(CL_BITRATE_POLICY);
+	if (x == NULL || PyDict_SetItemString(d, "BITRATE_POLICY", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_BITRATE_TARGET
+	x = PyInt_FromLong(CL_BITRATE_TARGET);
+	if (x == NULL || PyDict_SetItemString(d, "BITRATE_TARGET", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_BITS_PER_COMPONENT
+	x = PyInt_FromLong(CL_BITS_PER_COMPONENT);
+	if (x == NULL || PyDict_SetItemString(d, "BITS_PER_COMPONENT", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_BLENDING
+	x = PyInt_FromLong(CL_BLENDING);
+	if (x == NULL || PyDict_SetItemString(d, "BLENDING", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_BLOCK_SIZE
+	x = PyInt_FromLong(CL_BLOCK_SIZE);
+	if (x == NULL || PyDict_SetItemString(d, "BLOCK_SIZE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_BOTTOM_UP
+	x = PyInt_FromLong(CL_BOTTOM_UP);
+	if (x == NULL || PyDict_SetItemString(d, "BOTTOM_UP", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_BUFFER_NOT_CREATED
+	x = PyInt_FromLong(CL_BUFFER_NOT_CREATED);
+	if (x == NULL || PyDict_SetItemString(d, "BUFFER_NOT_CREATED", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_BUF_COMPRESSED
+	x = PyInt_FromLong(CL_BUF_COMPRESSED);
+	if (x == NULL || PyDict_SetItemString(d, "BUF_COMPRESSED", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_BUF_DATA
+	x = PyInt_FromLong(CL_BUF_DATA);
+	if (x == NULL || PyDict_SetItemString(d, "BUF_DATA", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_BUF_FRAME
+	x = PyInt_FromLong(CL_BUF_FRAME);
+	if (x == NULL || PyDict_SetItemString(d, "BUF_FRAME", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_CHANNEL_POLICY
+	x = PyInt_FromLong(CL_CHANNEL_POLICY);
+	if (x == NULL || PyDict_SetItemString(d, "CHANNEL_POLICY", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_CHROMA_THRESHOLD
+	x = PyInt_FromLong(CL_CHROMA_THRESHOLD);
+	if (x == NULL || PyDict_SetItemString(d, "CHROMA_THRESHOLD", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_CODEC
+	x = PyInt_FromLong(CL_CODEC);
+	if (x == NULL || PyDict_SetItemString(d, "CODEC", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_COMPONENTS
+	x = PyInt_FromLong(CL_COMPONENTS);
+	if (x == NULL || PyDict_SetItemString(d, "COMPONENTS", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_COMPRESSED_BUFFER_SIZE
+	x = PyInt_FromLong(CL_COMPRESSED_BUFFER_SIZE);
+	if (x == NULL || PyDict_SetItemString(d, "COMPRESSED_BUFFER_SIZE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_COMPRESSION_RATIO
+	x = PyInt_FromLong(CL_COMPRESSION_RATIO);
+	if (x == NULL || PyDict_SetItemString(d, "COMPRESSION_RATIO", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_COMPRESSOR
+	x = PyInt_FromLong(CL_COMPRESSOR);
+	if (x == NULL || PyDict_SetItemString(d, "COMPRESSOR", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_CONTINUOUS_BLOCK
+	x = PyInt_FromLong(CL_CONTINUOUS_BLOCK);
+	if (x == NULL || PyDict_SetItemString(d, "CONTINUOUS_BLOCK", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_CONTINUOUS_NONBLOCK
+	x = PyInt_FromLong(CL_CONTINUOUS_NONBLOCK);
+	if (x == NULL || PyDict_SetItemString(d, "CONTINUOUS_NONBLOCK", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_COSMO_CODEC_CONTROL
+	x = PyInt_FromLong(CL_COSMO_CODEC_CONTROL);
+	if (x == NULL || PyDict_SetItemString(d, "COSMO_CODEC_CONTROL", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_COSMO_NUM_PARAMS
+	x = PyInt_FromLong(CL_COSMO_NUM_PARAMS);
+	if (x == NULL || PyDict_SetItemString(d, "COSMO_NUM_PARAMS", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_COSMO_VALUE_BASE
+	x = PyInt_FromLong(CL_COSMO_VALUE_BASE);
+	if (x == NULL || PyDict_SetItemString(d, "COSMO_VALUE_BASE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_COSMO_VIDEO_MANUAL_CONTROL
+	x = PyInt_FromLong(CL_COSMO_VIDEO_MANUAL_CONTROL);
+	if (x == NULL || PyDict_SetItemString(d, "COSMO_VIDEO_MANUAL_CONTROL", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_COSMO_VIDEO_TRANSFER_MODE
+	x = PyInt_FromLong(CL_COSMO_VIDEO_TRANSFER_MODE);
+	if (x == NULL || PyDict_SetItemString(d, "COSMO_VIDEO_TRANSFER_MODE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_DATA
+	x = PyInt_FromLong(CL_DATA);
+	if (x == NULL || PyDict_SetItemString(d, "DATA", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_DECOMPRESSOR
+	x = PyInt_FromLong(CL_DECOMPRESSOR);
+	if (x == NULL || PyDict_SetItemString(d, "DECOMPRESSOR", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_DSO_ERROR
+	x = PyInt_FromLong(CL_DSO_ERROR);
+	if (x == NULL || PyDict_SetItemString(d, "DSO_ERROR", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_EDGE_THRESHOLD
+	x = PyInt_FromLong(CL_EDGE_THRESHOLD);
+	if (x == NULL || PyDict_SetItemString(d, "EDGE_THRESHOLD", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_ENABLE_IMAGEINFO
+	x = PyInt_FromLong(CL_ENABLE_IMAGEINFO);
+	if (x == NULL || PyDict_SetItemString(d, "ENABLE_IMAGEINFO", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_END_OF_SEQUENCE
+	x = PyInt_FromLong(CL_END_OF_SEQUENCE);
+	if (x == NULL || PyDict_SetItemString(d, "END_OF_SEQUENCE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_ENUM_VALUE
+	x = PyInt_FromLong(CL_ENUM_VALUE);
+	if (x == NULL || PyDict_SetItemString(d, "ENUM_VALUE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_EXACT_COMPRESSION_RATIO
+	x = PyInt_FromLong(CL_EXACT_COMPRESSION_RATIO);
+	if (x == NULL || PyDict_SetItemString(d, "EXACT_COMPRESSION_RATIO", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_EXTERNAL_DEVICE
+	x = PyInt_FromLong((long) CL_EXTERNAL_DEVICE);
+	if (x == NULL || PyDict_SetItemString(d, "EXTERNAL_DEVICE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_FLOATING_ENUM_VALUE
+	x = PyInt_FromLong(CL_FLOATING_ENUM_VALUE);
+	if (x == NULL || PyDict_SetItemString(d, "FLOATING_ENUM_VALUE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_FLOATING_RANGE_VALUE
+	x = PyInt_FromLong(CL_FLOATING_RANGE_VALUE);
+	if (x == NULL || PyDict_SetItemString(d, "FLOATING_RANGE_VALUE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_FORMAT
+	x = PyInt_FromLong(CL_FORMAT);
+	if (x == NULL || PyDict_SetItemString(d, "FORMAT", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_FORMAT_ABGR
+	x = PyInt_FromLong(CL_FORMAT_ABGR);
+	if (x == NULL || PyDict_SetItemString(d, "FORMAT_ABGR", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_FORMAT_BGR
+	x = PyInt_FromLong(CL_FORMAT_BGR);
+	if (x == NULL || PyDict_SetItemString(d, "FORMAT_BGR", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_FORMAT_BGR233
+	x = PyInt_FromLong(CL_FORMAT_BGR233);
+	if (x == NULL || PyDict_SetItemString(d, "FORMAT_BGR233", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_FORMAT_GRAYSCALE
+	x = PyInt_FromLong(CL_FORMAT_GRAYSCALE);
+	if (x == NULL || PyDict_SetItemString(d, "FORMAT_GRAYSCALE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_FORMAT_MONO
+	x = PyInt_FromLong(CL_FORMAT_MONO);
+	if (x == NULL || PyDict_SetItemString(d, "FORMAT_MONO", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_FORMAT_RBG323
+	x = PyInt_FromLong(CL_FORMAT_RBG323);
+	if (x == NULL || PyDict_SetItemString(d, "FORMAT_RBG323", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_FORMAT_STEREO_INTERLEAVED
+	x = PyInt_FromLong(CL_FORMAT_STEREO_INTERLEAVED);
+	if (x == NULL || PyDict_SetItemString(d, "FORMAT_STEREO_INTERLEAVED", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_FORMAT_XBGR
+	x = PyInt_FromLong(CL_FORMAT_XBGR);
+	if (x == NULL || PyDict_SetItemString(d, "FORMAT_XBGR", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_FORMAT_YCbCr
+	x = PyInt_FromLong(CL_FORMAT_YCbCr);
+	if (x == NULL || PyDict_SetItemString(d, "FORMAT_YCbCr", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_FORMAT_YCbCr422
+	x = PyInt_FromLong(CL_FORMAT_YCbCr422);
+	if (x == NULL || PyDict_SetItemString(d, "FORMAT_YCbCr422", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_FORMAT_YCbCr422DC
+	x = PyInt_FromLong(CL_FORMAT_YCbCr422DC);
+	if (x == NULL || PyDict_SetItemString(d, "FORMAT_YCbCr422DC", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_FRAME
+	x = PyInt_FromLong(CL_FRAME);
+	if (x == NULL || PyDict_SetItemString(d, "FRAME", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_FRAMES_PER_CHUNK
+	x = PyInt_FromLong(CL_FRAMES_PER_CHUNK);
+	if (x == NULL || PyDict_SetItemString(d, "FRAMES_PER_CHUNK", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_FRAME_BUFFER_SIZE
+	x = PyInt_FromLong(CL_FRAME_BUFFER_SIZE);
+	if (x == NULL || PyDict_SetItemString(d, "FRAME_BUFFER_SIZE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_FRAME_BUFFER_SIZE_ZERO
+	x = PyInt_FromLong(CL_FRAME_BUFFER_SIZE_ZERO);
+	if (x == NULL || PyDict_SetItemString(d, "FRAME_BUFFER_SIZE_ZERO", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_FRAME_INDEX
+	x = PyInt_FromLong(CL_FRAME_INDEX);
+	if (x == NULL || PyDict_SetItemString(d, "FRAME_INDEX", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_FRAME_RATE
+	x = PyInt_FromLong(CL_FRAME_RATE);
+	if (x == NULL || PyDict_SetItemString(d, "FRAME_RATE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_FRAME_SIZE
+	x = PyInt_FromLong(CL_FRAME_SIZE);
+	if (x == NULL || PyDict_SetItemString(d, "FRAME_SIZE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_FRAME_TYPE
+	x = PyInt_FromLong(CL_FRAME_TYPE);
+	if (x == NULL || PyDict_SetItemString(d, "FRAME_TYPE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_G711_ALAW
+	x = PyInt_FromLong(CL_G711_ALAW);
+	if (x == NULL || PyDict_SetItemString(d, "G711_ALAW", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_G711_ALAW_SOFTWARE
+	x = PyInt_FromLong(CL_G711_ALAW_SOFTWARE);
+	if (x == NULL || PyDict_SetItemString(d, "G711_ALAW_SOFTWARE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_G711_ULAW
+	x = PyInt_FromLong(CL_G711_ULAW);
+	if (x == NULL || PyDict_SetItemString(d, "G711_ULAW", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_G711_ULAW_SOFTWARE
+	x = PyInt_FromLong(CL_G711_ULAW_SOFTWARE);
+	if (x == NULL || PyDict_SetItemString(d, "G711_ULAW_SOFTWARE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_GRAYSCALE
+	x = PyInt_FromLong(CL_GRAYSCALE);
+	if (x == NULL || PyDict_SetItemString(d, "GRAYSCALE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_HDCC
+	x = PyInt_FromLong(CL_HDCC);
+	if (x == NULL || PyDict_SetItemString(d, "HDCC", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_HDCC_SAMPLES_PER_TILE
+	x = PyInt_FromLong(CL_HDCC_SAMPLES_PER_TILE);
+	if (x == NULL || PyDict_SetItemString(d, "HDCC_SAMPLES_PER_TILE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_HDCC_SOFTWARE
+	x = PyInt_FromLong(CL_HDCC_SOFTWARE);
+	if (x == NULL || PyDict_SetItemString(d, "HDCC_SOFTWARE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_HDCC_TILE_THRESHOLD
+	x = PyInt_FromLong(CL_HDCC_TILE_THRESHOLD);
+	if (x == NULL || PyDict_SetItemString(d, "HDCC_TILE_THRESHOLD", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_HEADER_START_CODE
+	x = PyInt_FromLong(CL_HEADER_START_CODE);
+	if (x == NULL || PyDict_SetItemString(d, "HEADER_START_CODE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_IMAGEINFO_FIELDMASK
+	x = PyInt_FromLong(CL_IMAGEINFO_FIELDMASK);
+	if (x == NULL || PyDict_SetItemString(d, "IMAGEINFO_FIELDMASK", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_IMAGE_CROP_BOTTOM
+	x = PyInt_FromLong(CL_IMAGE_CROP_BOTTOM);
+	if (x == NULL || PyDict_SetItemString(d, "IMAGE_CROP_BOTTOM", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_IMAGE_CROP_LEFT
+	x = PyInt_FromLong(CL_IMAGE_CROP_LEFT);
+	if (x == NULL || PyDict_SetItemString(d, "IMAGE_CROP_LEFT", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_IMAGE_CROP_RIGHT
+	x = PyInt_FromLong(CL_IMAGE_CROP_RIGHT);
+	if (x == NULL || PyDict_SetItemString(d, "IMAGE_CROP_RIGHT", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_IMAGE_CROP_TOP
+	x = PyInt_FromLong(CL_IMAGE_CROP_TOP);
+	if (x == NULL || PyDict_SetItemString(d, "IMAGE_CROP_TOP", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_IMAGE_HEIGHT
+	x = PyInt_FromLong(CL_IMAGE_HEIGHT);
+	if (x == NULL || PyDict_SetItemString(d, "IMAGE_HEIGHT", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_IMAGE_WIDTH
+	x = PyInt_FromLong(CL_IMAGE_WIDTH);
+	if (x == NULL || PyDict_SetItemString(d, "IMAGE_WIDTH", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_IMPACT_CODEC_CONTROL
+	x = PyInt_FromLong(CL_IMPACT_CODEC_CONTROL);
+	if (x == NULL || PyDict_SetItemString(d, "IMPACT_CODEC_CONTROL", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_IMPACT_FRAME_INTERLEAVE
+	x = PyInt_FromLong(CL_IMPACT_FRAME_INTERLEAVE);
+	if (x == NULL || PyDict_SetItemString(d, "IMPACT_FRAME_INTERLEAVE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_IMPACT_NUM_PARAMS
+	x = PyInt_FromLong(CL_IMPACT_NUM_PARAMS);
+	if (x == NULL || PyDict_SetItemString(d, "IMPACT_NUM_PARAMS", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_INTERNAL_FORMAT
+	x = PyInt_FromLong(CL_INTERNAL_FORMAT);
+	if (x == NULL || PyDict_SetItemString(d, "INTERNAL_FORMAT", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_INTERNAL_IMAGE_HEIGHT
+	x = PyInt_FromLong(CL_INTERNAL_IMAGE_HEIGHT);
+	if (x == NULL || PyDict_SetItemString(d, "INTERNAL_IMAGE_HEIGHT", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_INTERNAL_IMAGE_WIDTH
+	x = PyInt_FromLong(CL_INTERNAL_IMAGE_WIDTH);
+	if (x == NULL || PyDict_SetItemString(d, "INTERNAL_IMAGE_WIDTH", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_INTRA
+	x = PyInt_FromLong(CL_INTRA);
+	if (x == NULL || PyDict_SetItemString(d, "INTRA", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_JPEG
+	x = PyInt_FromLong(CL_JPEG);
+	if (x == NULL || PyDict_SetItemString(d, "JPEG", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_JPEG_COSMO
+	x = PyInt_FromLong(CL_JPEG_COSMO);
+	if (x == NULL || PyDict_SetItemString(d, "JPEG_COSMO", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_JPEG_ERROR
+	x = PyInt_FromLong(CL_JPEG_ERROR);
+	if (x == NULL || PyDict_SetItemString(d, "JPEG_ERROR", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_JPEG_IMPACT
+	x = PyInt_FromLong(CL_JPEG_IMPACT);
+	if (x == NULL || PyDict_SetItemString(d, "JPEG_IMPACT", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_JPEG_NUM_PARAMS
+	x = PyInt_FromLong(CL_JPEG_NUM_PARAMS);
+	if (x == NULL || PyDict_SetItemString(d, "JPEG_NUM_PARAMS", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_JPEG_QUALITY_FACTOR
+	x = PyInt_FromLong(CL_JPEG_QUALITY_FACTOR);
+	if (x == NULL || PyDict_SetItemString(d, "JPEG_QUALITY_FACTOR", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_JPEG_QUANTIZATION_TABLES
+	x = PyInt_FromLong(CL_JPEG_QUANTIZATION_TABLES);
+	if (x == NULL || PyDict_SetItemString(d, "JPEG_QUANTIZATION_TABLES", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_JPEG_SOFTWARE
+	x = PyInt_FromLong(CL_JPEG_SOFTWARE);
+	if (x == NULL || PyDict_SetItemString(d, "JPEG_SOFTWARE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_JPEG_STREAM_HEADERS
+	x = PyInt_FromLong(CL_JPEG_STREAM_HEADERS);
+	if (x == NULL || PyDict_SetItemString(d, "JPEG_STREAM_HEADERS", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_KEYFRAME
+	x = PyInt_FromLong(CL_KEYFRAME);
+	if (x == NULL || PyDict_SetItemString(d, "KEYFRAME", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_KEYFRAME_DISTANCE
+	x = PyInt_FromLong(CL_KEYFRAME_DISTANCE);
+	if (x == NULL || PyDict_SetItemString(d, "KEYFRAME_DISTANCE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_LAST_FRAME_INDEX
+	x = PyInt_FromLong(CL_LAST_FRAME_INDEX);
+	if (x == NULL || PyDict_SetItemString(d, "LAST_FRAME_INDEX", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_LAYER
+	x = PyInt_FromLong(CL_LAYER);
+	if (x == NULL || PyDict_SetItemString(d, "LAYER", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_LUMA_THRESHOLD
+	x = PyInt_FromLong(CL_LUMA_THRESHOLD);
+	if (x == NULL || PyDict_SetItemString(d, "LUMA_THRESHOLD", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_MAX_NUMBER_OF_AUDIO_ALGORITHMS
+	x = PyInt_FromLong(CL_MAX_NUMBER_OF_AUDIO_ALGORITHMS);
+	if (x == NULL || PyDict_SetItemString(d, "MAX_NUMBER_OF_AUDIO_ALGORITHMS", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_MAX_NUMBER_OF_FORMATS
+	x = PyInt_FromLong(CL_MAX_NUMBER_OF_FORMATS);
+	if (x == NULL || PyDict_SetItemString(d, "MAX_NUMBER_OF_FORMATS", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_MAX_NUMBER_OF_ORIGINAL_FORMATS
+	x = PyInt_FromLong(CL_MAX_NUMBER_OF_ORIGINAL_FORMATS);
+	if (x == NULL || PyDict_SetItemString(d, "MAX_NUMBER_OF_ORIGINAL_FORMATS", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_MAX_NUMBER_OF_PARAMS
+	x = PyInt_FromLong(CL_MAX_NUMBER_OF_PARAMS);
+	if (x == NULL || PyDict_SetItemString(d, "MAX_NUMBER_OF_PARAMS", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_MAX_NUMBER_OF_VIDEO_ALGORITHMS
+	x = PyInt_FromLong(CL_MAX_NUMBER_OF_VIDEO_ALGORITHMS);
+	if (x == NULL || PyDict_SetItemString(d, "MAX_NUMBER_OF_VIDEO_ALGORITHMS", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_MONO
+	x = PyInt_FromLong(CL_MONO);
+	if (x == NULL || PyDict_SetItemString(d, "MONO", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_MPEG1_AUDIO_AWARE
+	x = PyInt_FromLong(CL_MPEG1_AUDIO_AWARE);
+	if (x == NULL || PyDict_SetItemString(d, "MPEG1_AUDIO_AWARE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_MPEG1_AUDIO_LAYER
+	x = PyInt_FromLong(CL_MPEG1_AUDIO_LAYER);
+	if (x == NULL || PyDict_SetItemString(d, "MPEG1_AUDIO_LAYER", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_MPEG1_AUDIO_LAYER_I
+	x = PyInt_FromLong(CL_MPEG1_AUDIO_LAYER_I);
+	if (x == NULL || PyDict_SetItemString(d, "MPEG1_AUDIO_LAYER_I", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_MPEG1_AUDIO_LAYER_II
+	x = PyInt_FromLong(CL_MPEG1_AUDIO_LAYER_II);
+	if (x == NULL || PyDict_SetItemString(d, "MPEG1_AUDIO_LAYER_II", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_MPEG1_AUDIO_MODE
+	x = PyInt_FromLong(CL_MPEG1_AUDIO_MODE);
+	if (x == NULL || PyDict_SetItemString(d, "MPEG1_AUDIO_MODE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_MPEG1_AUDIO_MODE_DUAL
+	x = PyInt_FromLong(CL_MPEG1_AUDIO_MODE_DUAL);
+	if (x == NULL || PyDict_SetItemString(d, "MPEG1_AUDIO_MODE_DUAL", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_MPEG1_AUDIO_MODE_JOINT
+	x = PyInt_FromLong(CL_MPEG1_AUDIO_MODE_JOINT);
+	if (x == NULL || PyDict_SetItemString(d, "MPEG1_AUDIO_MODE_JOINT", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_MPEG1_AUDIO_MODE_SINGLE
+	x = PyInt_FromLong(CL_MPEG1_AUDIO_MODE_SINGLE);
+	if (x == NULL || PyDict_SetItemString(d, "MPEG1_AUDIO_MODE_SINGLE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_MPEG1_AUDIO_MODE_STEREO
+	x = PyInt_FromLong(CL_MPEG1_AUDIO_MODE_STEREO);
+	if (x == NULL || PyDict_SetItemString(d, "MPEG1_AUDIO_MODE_STEREO", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_MPEG1_AUDIO_SOFTWARE
+	x = PyInt_FromLong(CL_MPEG1_AUDIO_SOFTWARE);
+	if (x == NULL || PyDict_SetItemString(d, "MPEG1_AUDIO_SOFTWARE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_MPEG1_END_OF_STREAM
+	x = PyInt_FromLong(CL_MPEG1_END_OF_STREAM);
+	if (x == NULL || PyDict_SetItemString(d, "MPEG1_END_OF_STREAM", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_MPEG1_ERROR
+	x = PyInt_FromLong(CL_MPEG1_ERROR);
+	if (x == NULL || PyDict_SetItemString(d, "MPEG1_ERROR", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_MPEG1_NUM_PARAMS
+	x = PyInt_FromLong(CL_MPEG1_NUM_PARAMS);
+	if (x == NULL || PyDict_SetItemString(d, "MPEG1_NUM_PARAMS", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_MPEG1_VIDEO_M
+	x = PyInt_FromLong(CL_MPEG1_VIDEO_M);
+	if (x == NULL || PyDict_SetItemString(d, "MPEG1_VIDEO_M", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_MPEG1_VIDEO_MAX_MOTION_VECTOR_LENGTH_B_X
+	x = PyInt_FromLong(CL_MPEG1_VIDEO_MAX_MOTION_VECTOR_LENGTH_B_X);
+	if (x == NULL || PyDict_SetItemString(d, "MPEG1_VIDEO_MAX_MOTION_VECTOR_LENGTH_B_X", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_MPEG1_VIDEO_MAX_MOTION_VECTOR_LENGTH_B_Y
+	x = PyInt_FromLong(CL_MPEG1_VIDEO_MAX_MOTION_VECTOR_LENGTH_B_Y);
+	if (x == NULL || PyDict_SetItemString(d, "MPEG1_VIDEO_MAX_MOTION_VECTOR_LENGTH_B_Y", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_MPEG1_VIDEO_MAX_MOTION_VECTOR_LENGTH_P_X
+	x = PyInt_FromLong(CL_MPEG1_VIDEO_MAX_MOTION_VECTOR_LENGTH_P_X);
+	if (x == NULL || PyDict_SetItemString(d, "MPEG1_VIDEO_MAX_MOTION_VECTOR_LENGTH_P_X", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_MPEG1_VIDEO_MAX_MOTION_VECTOR_LENGTH_P_Y
+	x = PyInt_FromLong(CL_MPEG1_VIDEO_MAX_MOTION_VECTOR_LENGTH_P_Y);
+	if (x == NULL || PyDict_SetItemString(d, "MPEG1_VIDEO_MAX_MOTION_VECTOR_LENGTH_P_Y", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_MPEG1_VIDEO_N
+	x = PyInt_FromLong(CL_MPEG1_VIDEO_N);
+	if (x == NULL || PyDict_SetItemString(d, "MPEG1_VIDEO_N", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_MPEG1_VIDEO_SOFTNESS
+	x = PyInt_FromLong(CL_MPEG1_VIDEO_SOFTNESS);
+	if (x == NULL || PyDict_SetItemString(d, "MPEG1_VIDEO_SOFTNESS", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_MPEG1_VIDEO_SOFTNESS_MAXIMUM
+	x = PyInt_FromLong(CL_MPEG1_VIDEO_SOFTNESS_MAXIMUM);
+	if (x == NULL || PyDict_SetItemString(d, "MPEG1_VIDEO_SOFTNESS_MAXIMUM", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_MPEG1_VIDEO_SOFTNESS_MEDIUM
+	x = PyInt_FromLong(CL_MPEG1_VIDEO_SOFTNESS_MEDIUM);
+	if (x == NULL || PyDict_SetItemString(d, "MPEG1_VIDEO_SOFTNESS_MEDIUM", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_MPEG1_VIDEO_SOFTNESS_NONE
+	x = PyInt_FromLong(CL_MPEG1_VIDEO_SOFTNESS_NONE);
+	if (x == NULL || PyDict_SetItemString(d, "MPEG1_VIDEO_SOFTNESS_NONE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_MPEG1_VIDEO_SOFTWARE
+	x = PyInt_FromLong(CL_MPEG1_VIDEO_SOFTWARE);
+	if (x == NULL || PyDict_SetItemString(d, "MPEG1_VIDEO_SOFTWARE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_MPEG_VIDEO
+	x = PyInt_FromLong(CL_MPEG_VIDEO);
+	if (x == NULL || PyDict_SetItemString(d, "MPEG_VIDEO", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_MULTIRATE_AWARE
+	x = PyInt_FromLong(CL_MULTIRATE_AWARE);
+	if (x == NULL || PyDict_SetItemString(d, "MULTIRATE_AWARE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_MVC1
+	x = PyInt_FromLong(CL_MVC1);
+	if (x == NULL || PyDict_SetItemString(d, "MVC1", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_MVC1_SOFTWARE
+	x = PyInt_FromLong(CL_MVC1_SOFTWARE);
+	if (x == NULL || PyDict_SetItemString(d, "MVC1_SOFTWARE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_MVC2
+	x = PyInt_FromLong(CL_MVC2);
+	if (x == NULL || PyDict_SetItemString(d, "MVC2", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_MVC2_BLENDING
+	x = PyInt_FromLong(CL_MVC2_BLENDING);
+	if (x == NULL || PyDict_SetItemString(d, "MVC2_BLENDING", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_MVC2_BLENDING_OFF
+	x = PyInt_FromLong(CL_MVC2_BLENDING_OFF);
+	if (x == NULL || PyDict_SetItemString(d, "MVC2_BLENDING_OFF", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_MVC2_BLENDING_ON
+	x = PyInt_FromLong(CL_MVC2_BLENDING_ON);
+	if (x == NULL || PyDict_SetItemString(d, "MVC2_BLENDING_ON", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_MVC2_CHROMA_THRESHOLD
+	x = PyInt_FromLong(CL_MVC2_CHROMA_THRESHOLD);
+	if (x == NULL || PyDict_SetItemString(d, "MVC2_CHROMA_THRESHOLD", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_MVC2_EDGE_THRESHOLD
+	x = PyInt_FromLong(CL_MVC2_EDGE_THRESHOLD);
+	if (x == NULL || PyDict_SetItemString(d, "MVC2_EDGE_THRESHOLD", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_MVC2_ERROR
+	x = PyInt_FromLong(CL_MVC2_ERROR);
+	if (x == NULL || PyDict_SetItemString(d, "MVC2_ERROR", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_MVC2_LUMA_THRESHOLD
+	x = PyInt_FromLong(CL_MVC2_LUMA_THRESHOLD);
+	if (x == NULL || PyDict_SetItemString(d, "MVC2_LUMA_THRESHOLD", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_MVC2_SOFTWARE
+	x = PyInt_FromLong(CL_MVC2_SOFTWARE);
+	if (x == NULL || PyDict_SetItemString(d, "MVC2_SOFTWARE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_MVC3_QUALITY_LEVEL
+	x = PyInt_FromLong(CL_MVC3_QUALITY_LEVEL);
+	if (x == NULL || PyDict_SetItemString(d, "MVC3_QUALITY_LEVEL", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_MVC3_SOFTWARE
+	x = PyInt_FromLong(CL_MVC3_SOFTWARE);
+	if (x == NULL || PyDict_SetItemString(d, "MVC3_SOFTWARE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_NEXT_NOT_AVAILABLE
+	x = PyInt_FromLong(CL_NEXT_NOT_AVAILABLE);
+	if (x == NULL || PyDict_SetItemString(d, "NEXT_NOT_AVAILABLE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_NOISE_MARGIN
+	x = PyInt_FromLong(CL_NOISE_MARGIN);
+	if (x == NULL || PyDict_SetItemString(d, "NOISE_MARGIN", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_NONE
+	x = PyInt_FromLong(CL_NONE);
+	if (x == NULL || PyDict_SetItemString(d, "NONE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_NUMBER_OF_FORMATS
+	x = PyInt_FromLong(CL_NUMBER_OF_FORMATS);
+	if (x == NULL || PyDict_SetItemString(d, "NUMBER_OF_FORMATS", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_NUMBER_OF_FRAMES
+	x = PyInt_FromLong(CL_NUMBER_OF_FRAMES);
+	if (x == NULL || PyDict_SetItemString(d, "NUMBER_OF_FRAMES", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_NUMBER_OF_PARAMS
+	x = PyInt_FromLong(CL_NUMBER_OF_PARAMS);
+	if (x == NULL || PyDict_SetItemString(d, "NUMBER_OF_PARAMS", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_NUMBER_OF_PARAMS_FREEZE
+	x = PyInt_FromLong(CL_NUMBER_OF_PARAMS_FREEZE);
+	if (x == NULL || PyDict_SetItemString(d, "NUMBER_OF_PARAMS_FREEZE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_NUMBER_OF_VIDEO_FORMATS
+	x = PyInt_FromLong(CL_NUMBER_OF_VIDEO_FORMATS);
+	if (x == NULL || PyDict_SetItemString(d, "NUMBER_OF_VIDEO_FORMATS", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_ORIENTATION
+	x = PyInt_FromLong(CL_ORIENTATION);
+	if (x == NULL || PyDict_SetItemString(d, "ORIENTATION", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_ORIGINAL_FORMAT
+	x = PyInt_FromLong(CL_ORIGINAL_FORMAT);
+	if (x == NULL || PyDict_SetItemString(d, "ORIGINAL_FORMAT", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_PARAM_OUT_OF_RANGE
+	x = PyInt_FromLong(CL_PARAM_OUT_OF_RANGE);
+	if (x == NULL || PyDict_SetItemString(d, "PARAM_OUT_OF_RANGE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_PIXEL_ASPECT
+	x = PyInt_FromLong(CL_PIXEL_ASPECT);
+	if (x == NULL || PyDict_SetItemString(d, "PIXEL_ASPECT", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_PREDICTED
+	x = PyInt_FromLong(CL_PREDICTED);
+	if (x == NULL || PyDict_SetItemString(d, "PREDICTED", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_PREROLL
+	x = PyInt_FromLong(CL_PREROLL);
+	if (x == NULL || PyDict_SetItemString(d, "PREROLL", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_QUALITY_FACTOR
+	x = PyInt_FromLong(CL_QUALITY_FACTOR);
+	if (x == NULL || PyDict_SetItemString(d, "QUALITY_FACTOR", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_QUALITY_LEVEL
+	x = PyInt_FromLong(CL_QUALITY_LEVEL);
+	if (x == NULL || PyDict_SetItemString(d, "QUALITY_LEVEL", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_QUALITY_SPATIAL
+	x = PyInt_FromLong(CL_QUALITY_SPATIAL);
+	if (x == NULL || PyDict_SetItemString(d, "QUALITY_SPATIAL", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_QUALITY_TEMPORAL
+	x = PyInt_FromLong(CL_QUALITY_TEMPORAL);
+	if (x == NULL || PyDict_SetItemString(d, "QUALITY_TEMPORAL", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_QUANTIZATION_TABLES
+	x = PyInt_FromLong(CL_QUANTIZATION_TABLES);
+	if (x == NULL || PyDict_SetItemString(d, "QUANTIZATION_TABLES", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_RANGE_VALUE
+	x = PyInt_FromLong(CL_RANGE_VALUE);
+	if (x == NULL || PyDict_SetItemString(d, "RANGE_VALUE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_RGB
+	x = PyInt_FromLong(CL_RGB);
+	if (x == NULL || PyDict_SetItemString(d, "RGB", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_RGB332
+	x = PyInt_FromLong(CL_RGB332);
+	if (x == NULL || PyDict_SetItemString(d, "RGB332", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_RGB8
+	x = PyInt_FromLong(CL_RGB8);
+	if (x == NULL || PyDict_SetItemString(d, "RGB8", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_RGBA
+	x = PyInt_FromLong(CL_RGBA);
+	if (x == NULL || PyDict_SetItemString(d, "RGBA", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_RGBX
+	x = PyInt_FromLong(CL_RGBX);
+	if (x == NULL || PyDict_SetItemString(d, "RGBX", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_RLE
+	x = PyInt_FromLong(CL_RLE);
+	if (x == NULL || PyDict_SetItemString(d, "RLE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_RLE24
+	x = PyInt_FromLong(CL_RLE24);
+	if (x == NULL || PyDict_SetItemString(d, "RLE24", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_RLE24_SOFTWARE
+	x = PyInt_FromLong(CL_RLE24_SOFTWARE);
+	if (x == NULL || PyDict_SetItemString(d, "RLE24_SOFTWARE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_RLE_SOFTWARE
+	x = PyInt_FromLong(CL_RLE_SOFTWARE);
+	if (x == NULL || PyDict_SetItemString(d, "RLE_SOFTWARE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_RTR
+	x = PyInt_FromLong(CL_RTR);
+	if (x == NULL || PyDict_SetItemString(d, "RTR", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_RTR1
+	x = PyInt_FromLong(CL_RTR1);
+	if (x == NULL || PyDict_SetItemString(d, "RTR1", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_RTR_QUALITY_LEVEL
+	x = PyInt_FromLong(CL_RTR_QUALITY_LEVEL);
+	if (x == NULL || PyDict_SetItemString(d, "RTR_QUALITY_LEVEL", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_SAMPLES_PER_TILE
+	x = PyInt_FromLong(CL_SAMPLES_PER_TILE);
+	if (x == NULL || PyDict_SetItemString(d, "SAMPLES_PER_TILE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_SCHEME_BUSY
+	x = PyInt_FromLong(CL_SCHEME_BUSY);
+	if (x == NULL || PyDict_SetItemString(d, "SCHEME_BUSY", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_SCHEME_NOT_AVAILABLE
+	x = PyInt_FromLong(CL_SCHEME_NOT_AVAILABLE);
+	if (x == NULL || PyDict_SetItemString(d, "SCHEME_NOT_AVAILABLE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_SPEED
+	x = PyInt_FromLong(CL_SPEED);
+	if (x == NULL || PyDict_SetItemString(d, "SPEED", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_STEREO_INTERLEAVED
+	x = PyInt_FromLong(CL_STEREO_INTERLEAVED);
+	if (x == NULL || PyDict_SetItemString(d, "STEREO_INTERLEAVED", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_STREAM_HEADERS
+	x = PyInt_FromLong(CL_STREAM_HEADERS);
+	if (x == NULL || PyDict_SetItemString(d, "STREAM_HEADERS", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_TILE_THRESHOLD
+	x = PyInt_FromLong(CL_TILE_THRESHOLD);
+	if (x == NULL || PyDict_SetItemString(d, "TILE_THRESHOLD", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_TOP_DOWN
+	x = PyInt_FromLong(CL_TOP_DOWN);
+	if (x == NULL || PyDict_SetItemString(d, "TOP_DOWN", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_ULAW
+	x = PyInt_FromLong(CL_ULAW);
+	if (x == NULL || PyDict_SetItemString(d, "ULAW", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_UNCOMPRESSED
+	x = PyInt_FromLong(CL_UNCOMPRESSED);
+	if (x == NULL || PyDict_SetItemString(d, "UNCOMPRESSED", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_UNCOMPRESSED_AUDIO
+	x = PyInt_FromLong(CL_UNCOMPRESSED_AUDIO);
+	if (x == NULL || PyDict_SetItemString(d, "UNCOMPRESSED_AUDIO", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_UNCOMPRESSED_VIDEO
+	x = PyInt_FromLong(CL_UNCOMPRESSED_VIDEO);
+	if (x == NULL || PyDict_SetItemString(d, "UNCOMPRESSED_VIDEO", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_UNKNOWN_SCHEME
+	x = PyInt_FromLong(CL_UNKNOWN_SCHEME);
+	if (x == NULL || PyDict_SetItemString(d, "UNKNOWN_SCHEME", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_VIDEO
+	x = PyInt_FromLong(CL_VIDEO);
+	if (x == NULL || PyDict_SetItemString(d, "VIDEO", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_Y
+	x = PyInt_FromLong(CL_Y);
+	if (x == NULL || PyDict_SetItemString(d, "Y", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_YCbCr
+	x = PyInt_FromLong(CL_YCbCr);
+	if (x == NULL || PyDict_SetItemString(d, "YCbCr", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_YCbCr422
+	x = PyInt_FromLong(CL_YCbCr422);
+	if (x == NULL || PyDict_SetItemString(d, "YCbCr422", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_YCbCr422DC
+	x = PyInt_FromLong(CL_YCbCr422DC);
+	if (x == NULL || PyDict_SetItemString(d, "YCbCr422DC", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_YCbCr422HC
+	x = PyInt_FromLong(CL_YCbCr422HC);
+	if (x == NULL || PyDict_SetItemString(d, "YCbCr422HC", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_YUV
+	x = PyInt_FromLong(CL_YUV);
+	if (x == NULL || PyDict_SetItemString(d, "YUV", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_YUV422
+	x = PyInt_FromLong(CL_YUV422);
+	if (x == NULL || PyDict_SetItemString(d, "YUV422", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_YUV422DC
+	x = PyInt_FromLong(CL_YUV422DC);
+	if (x == NULL || PyDict_SetItemString(d, "YUV422DC", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef CL_YUV422HC
+	x = PyInt_FromLong(CL_YUV422HC);
+	if (x == NULL || PyDict_SetItemString(d, "YUV422HC", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef AWCMP_STEREO
+	x = PyInt_FromLong(AWCMP_STEREO);
+	if (x == NULL || PyDict_SetItemString(d, "AWCMP_STEREO", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef AWCMP_JOINT_STEREO
+	x = PyInt_FromLong(AWCMP_JOINT_STEREO);
+	if (x == NULL || PyDict_SetItemString(d, "AWCMP_JOINT_STEREO", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef AWCMP_INDEPENDENT
+	x = PyInt_FromLong(AWCMP_INDEPENDENT);
+	if (x == NULL || PyDict_SetItemString(d, "AWCMP_INDEPENDENT", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef AWCMP_FIXED_RATE
+	x = PyInt_FromLong(AWCMP_FIXED_RATE);
+	if (x == NULL || PyDict_SetItemString(d, "AWCMP_FIXED_RATE", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef AWCMP_CONST_QUAL
+	x = PyInt_FromLong(AWCMP_CONST_QUAL);
+	if (x == NULL || PyDict_SetItemString(d, "AWCMP_CONST_QUAL", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef AWCMP_LOSSLESS
+	x = PyInt_FromLong(AWCMP_LOSSLESS);
+	if (x == NULL || PyDict_SetItemString(d, "AWCMP_LOSSLESS", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef AWCMP_MPEG_LAYER_I
+	x = PyInt_FromLong(AWCMP_MPEG_LAYER_I);
+	if (x == NULL || PyDict_SetItemString(d, "AWCMP_MPEG_LAYER_I", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+#ifdef AWCMP_MPEG_LAYER_II
+	x = PyInt_FromLong(AWCMP_MPEG_LAYER_II);
+	if (x == NULL || PyDict_SetItemString(d, "AWCMP_MPEG_LAYER_II", x) < 0)
+		return;
+	Py_DECREF(x);
+#endif
+
+	(void) clSetErrorHandler(cl_ErrorHandler);
+}

Added: vendor/Python/current/Modules/cmathmodule.c
===================================================================
--- vendor/Python/current/Modules/cmathmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/cmathmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,426 @@
+/* Complex math module */
+
+/* much code borrowed from mathmodule.c */
+
+#include "Python.h"
+
+#ifndef M_PI
+#define M_PI (3.141592653589793239)
+#endif
+
+/* First, the C functions that do the real work */
+
+/* constants */
+static Py_complex c_one = {1., 0.};
+static Py_complex c_half = {0.5, 0.};
+static Py_complex c_i = {0., 1.};
+static Py_complex c_halfi = {0., 0.5};
+
+/* forward declarations */
+static Py_complex c_log(Py_complex);
+static Py_complex c_prodi(Py_complex);
+static Py_complex c_sqrt(Py_complex);
+static PyObject * math_error(void);
+
+
+static Py_complex
+c_acos(Py_complex x)
+{
+	return c_neg(c_prodi(c_log(c_sum(x,c_prod(c_i,
+		    c_sqrt(c_diff(c_one,c_prod(x,x))))))));
+}
+
+PyDoc_STRVAR(c_acos_doc,
+"acos(x)\n"
+"\n"
+"Return the arc cosine of x.");
+
+
+static Py_complex
+c_acosh(Py_complex x)
+{
+	Py_complex z;
+	z = c_sqrt(c_half);
+	z = c_log(c_prod(z, c_sum(c_sqrt(c_sum(x,c_one)),
+				  c_sqrt(c_diff(x,c_one)))));
+	return c_sum(z, z);
+}
+
+PyDoc_STRVAR(c_acosh_doc,
+"acosh(x)\n"
+"\n"
+"Return the hyperbolic arccosine of x.");
+
+
+static Py_complex
+c_asin(Py_complex x)
+{
+	/* -i * log[(sqrt(1-x**2) + i*x] */
+	const Py_complex squared = c_prod(x, x);
+	const Py_complex sqrt_1_minus_x_sq = c_sqrt(c_diff(c_one, squared));
+        return c_neg(c_prodi(c_log(
+        		c_sum(sqrt_1_minus_x_sq, c_prodi(x))
+		    )       )     );
+}
+
+PyDoc_STRVAR(c_asin_doc,
+"asin(x)\n"
+"\n"
+"Return the arc sine of x.");
+
+
+static Py_complex
+c_asinh(Py_complex x)
+{
+	Py_complex z;
+	z = c_sqrt(c_half);
+	z = c_log(c_prod(z, c_sum(c_sqrt(c_sum(x, c_i)),
+				  c_sqrt(c_diff(x, c_i)))));
+	return c_sum(z, z);
+}
+
+PyDoc_STRVAR(c_asinh_doc,
+"asinh(x)\n"
+"\n"
+"Return the hyperbolic arc sine of x.");
+
+
+static Py_complex
+c_atan(Py_complex x)
+{
+	return c_prod(c_halfi,c_log(c_quot(c_sum(c_i,x),c_diff(c_i,x))));
+}
+
+PyDoc_STRVAR(c_atan_doc,
+"atan(x)\n"
+"\n"
+"Return the arc tangent of x.");
+
+
+static Py_complex
+c_atanh(Py_complex x)
+{
+	return c_prod(c_half,c_log(c_quot(c_sum(c_one,x),c_diff(c_one,x))));
+}
+
+PyDoc_STRVAR(c_atanh_doc,
+"atanh(x)\n"
+"\n"
+"Return the hyperbolic arc tangent of x.");
+
+
+static Py_complex
+c_cos(Py_complex x)
+{
+	Py_complex r;
+	r.real = cos(x.real)*cosh(x.imag);
+	r.imag = -sin(x.real)*sinh(x.imag);
+	return r;
+}
+
+PyDoc_STRVAR(c_cos_doc,
+"cos(x)\n"
+"n"
+"Return the cosine of x.");
+
+
+static Py_complex
+c_cosh(Py_complex x)
+{
+	Py_complex r;
+	r.real = cos(x.imag)*cosh(x.real);
+	r.imag = sin(x.imag)*sinh(x.real);
+	return r;
+}
+
+PyDoc_STRVAR(c_cosh_doc,
+"cosh(x)\n"
+"n"
+"Return the hyperbolic cosine of x.");
+
+
+static Py_complex
+c_exp(Py_complex x)
+{
+	Py_complex r;
+	double l = exp(x.real);
+	r.real = l*cos(x.imag);
+	r.imag = l*sin(x.imag);
+	return r;
+}
+
+PyDoc_STRVAR(c_exp_doc,
+"exp(x)\n"
+"\n"
+"Return the exponential value e**x.");
+
+
+static Py_complex
+c_log(Py_complex x)
+{
+	Py_complex r;
+	double l = hypot(x.real,x.imag);
+	r.imag = atan2(x.imag, x.real);
+	r.real = log(l);
+	return r;
+}
+
+
+static Py_complex
+c_log10(Py_complex x)
+{
+	Py_complex r;
+	double l = hypot(x.real,x.imag);
+	r.imag = atan2(x.imag, x.real)/log(10.);
+	r.real = log10(l);
+	return r;
+}
+
+PyDoc_STRVAR(c_log10_doc,
+"log10(x)\n"
+"\n"
+"Return the base-10 logarithm of x.");
+
+
+/* internal function not available from Python */
+static Py_complex
+c_prodi(Py_complex x)
+{
+	Py_complex r;
+	r.real = -x.imag;
+	r.imag = x.real;
+	return r;
+}
+
+
+static Py_complex
+c_sin(Py_complex x)
+{
+	Py_complex r;
+	r.real = sin(x.real) * cosh(x.imag);
+	r.imag = cos(x.real) * sinh(x.imag);
+	return r;
+}
+
+PyDoc_STRVAR(c_sin_doc,
+"sin(x)\n"
+"\n"
+"Return the sine of x.");
+
+
+static Py_complex
+c_sinh(Py_complex x)
+{
+	Py_complex r;
+	r.real = cos(x.imag) * sinh(x.real);
+	r.imag = sin(x.imag) * cosh(x.real);
+	return r;
+}
+
+PyDoc_STRVAR(c_sinh_doc,
+"sinh(x)\n"
+"\n"
+"Return the hyperbolic sine of x.");
+
+
+static Py_complex
+c_sqrt(Py_complex x)
+{
+	Py_complex r;
+	double s,d;
+	if (x.real == 0. && x.imag == 0.)
+		r = x;
+	else {
+		s = sqrt(0.5*(fabs(x.real) + hypot(x.real,x.imag)));
+		d = 0.5*x.imag/s;
+		if (x.real > 0.) {
+			r.real = s;
+			r.imag = d;
+		}
+		else if (x.imag >= 0.) {
+			r.real = d;
+			r.imag = s;
+		}
+		else {
+			r.real = -d;
+			r.imag = -s;
+		}
+	}
+	return r;
+}
+
+PyDoc_STRVAR(c_sqrt_doc,
+"sqrt(x)\n"
+"\n"
+"Return the square root of x.");
+
+
+static Py_complex
+c_tan(Py_complex x)
+{
+	Py_complex r;
+	double sr,cr,shi,chi;
+	double rs,is,rc,ic;
+	double d;
+	sr = sin(x.real);
+	cr = cos(x.real);
+	shi = sinh(x.imag);
+	chi = cosh(x.imag);
+	rs = sr * chi;
+	is = cr * shi;
+	rc = cr * chi;
+	ic = -sr * shi;
+	d = rc*rc + ic * ic;
+	r.real = (rs*rc + is*ic) / d;
+	r.imag = (is*rc - rs*ic) / d;
+	return r;
+}
+
+PyDoc_STRVAR(c_tan_doc,
+"tan(x)\n"
+"\n"
+"Return the tangent of x.");
+
+
+static Py_complex
+c_tanh(Py_complex x)
+{
+	Py_complex r;
+	double si,ci,shr,chr;
+	double rs,is,rc,ic;
+	double d;
+	si = sin(x.imag);
+	ci = cos(x.imag);
+	shr = sinh(x.real);
+	chr = cosh(x.real);
+	rs = ci * shr;
+	is = si * chr;
+	rc = ci * chr;
+	ic = si * shr;
+	d = rc*rc + ic*ic;
+	r.real = (rs*rc + is*ic) / d;
+	r.imag = (is*rc - rs*ic) / d;
+	return r;
+}
+
+PyDoc_STRVAR(c_tanh_doc,
+"tanh(x)\n"
+"\n"
+"Return the hyperbolic tangent of x.");
+
+static PyObject *
+cmath_log(PyObject *self, PyObject *args)
+{
+	Py_complex x;
+	Py_complex y;
+
+	if (!PyArg_ParseTuple(args, "D|D", &x, &y))
+		return NULL;
+
+	errno = 0;
+	PyFPE_START_PROTECT("complex function", return 0)
+	x = c_log(x);
+	if (PyTuple_GET_SIZE(args) == 2)
+		x = c_quot(x, c_log(y));
+	PyFPE_END_PROTECT(x)
+	if (errno != 0)
+		return math_error();
+	Py_ADJUST_ERANGE2(x.real, x.imag);
+	return PyComplex_FromCComplex(x);
+}
+
+PyDoc_STRVAR(cmath_log_doc,
+"log(x[, base]) -> the logarithm of x to the given base.\n\
+If the base not specified, returns the natural logarithm (base e) of x.");
+
+
+/* And now the glue to make them available from Python: */
+
+static PyObject *
+math_error(void)
+{
+	if (errno == EDOM)
+		PyErr_SetString(PyExc_ValueError, "math domain error");
+	else if (errno == ERANGE)
+		PyErr_SetString(PyExc_OverflowError, "math range error");
+	else    /* Unexpected math error */
+		PyErr_SetFromErrno(PyExc_ValueError);
+	return NULL;
+}
+
+static PyObject *
+math_1(PyObject *args, Py_complex (*func)(Py_complex))
+{
+	Py_complex x;
+	if (!PyArg_ParseTuple(args, "D", &x))
+		return NULL;
+	errno = 0;
+	PyFPE_START_PROTECT("complex function", return 0)
+	x = (*func)(x);
+	PyFPE_END_PROTECT(x)
+	Py_ADJUST_ERANGE2(x.real, x.imag);
+	if (errno != 0)
+		return math_error();
+	else
+		return PyComplex_FromCComplex(x);
+}
+
+#define FUNC1(stubname, func) \
+	static PyObject * stubname(PyObject *self, PyObject *args) { \
+		return math_1(args, func); \
+	}
+
+FUNC1(cmath_acos, c_acos)
+FUNC1(cmath_acosh, c_acosh)
+FUNC1(cmath_asin, c_asin)
+FUNC1(cmath_asinh, c_asinh)
+FUNC1(cmath_atan, c_atan)
+FUNC1(cmath_atanh, c_atanh)
+FUNC1(cmath_cos, c_cos)
+FUNC1(cmath_cosh, c_cosh)
+FUNC1(cmath_exp, c_exp)
+FUNC1(cmath_log10, c_log10)
+FUNC1(cmath_sin, c_sin)
+FUNC1(cmath_sinh, c_sinh)
+FUNC1(cmath_sqrt, c_sqrt)
+FUNC1(cmath_tan, c_tan)
+FUNC1(cmath_tanh, c_tanh)
+
+
+PyDoc_STRVAR(module_doc,
+"This module is always available. It provides access to mathematical\n"
+"functions for complex numbers.");
+
+static PyMethodDef cmath_methods[] = {
+	{"acos",   cmath_acos,  METH_VARARGS, c_acos_doc},
+	{"acosh",  cmath_acosh, METH_VARARGS, c_acosh_doc},
+	{"asin",   cmath_asin,  METH_VARARGS, c_asin_doc},
+	{"asinh",  cmath_asinh, METH_VARARGS, c_asinh_doc},
+	{"atan",   cmath_atan,  METH_VARARGS, c_atan_doc},
+	{"atanh",  cmath_atanh, METH_VARARGS, c_atanh_doc},
+	{"cos",    cmath_cos,   METH_VARARGS, c_cos_doc},
+	{"cosh",   cmath_cosh,  METH_VARARGS, c_cosh_doc},
+	{"exp",    cmath_exp,   METH_VARARGS, c_exp_doc},
+	{"log",    cmath_log,   METH_VARARGS, cmath_log_doc},
+	{"log10",  cmath_log10, METH_VARARGS, c_log10_doc},
+	{"sin",    cmath_sin,   METH_VARARGS, c_sin_doc},
+	{"sinh",   cmath_sinh,  METH_VARARGS, c_sinh_doc},
+	{"sqrt",   cmath_sqrt,  METH_VARARGS, c_sqrt_doc},
+	{"tan",    cmath_tan,   METH_VARARGS, c_tan_doc},
+	{"tanh",   cmath_tanh,  METH_VARARGS, c_tanh_doc},
+	{NULL,		NULL}		/* sentinel */
+};
+
+PyMODINIT_FUNC
+initcmath(void)
+{
+	PyObject *m;
+
+	m = Py_InitModule3("cmath", cmath_methods, module_doc);
+	if (m == NULL)
+		return;
+
+	PyModule_AddObject(m, "pi",
+                           PyFloat_FromDouble(atan(1.0) * 4.0));
+	PyModule_AddObject(m, "e", PyFloat_FromDouble(exp(1.0)));
+}

Added: vendor/Python/current/Modules/collectionsmodule.c
===================================================================
--- vendor/Python/current/Modules/collectionsmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/collectionsmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1370 @@
+#include "Python.h"
+#include "structmember.h"
+
+/* collections module implementation of a deque() datatype
+   Written and maintained by Raymond D. Hettinger <python at rcn.com>
+   Copyright (c) 2004 Python Software Foundation.
+   All rights reserved.
+*/
+
+/* The block length may be set to any number over 1.  Larger numbers
+ * reduce the number of calls to the memory allocator but take more
+ * memory.  Ideally, BLOCKLEN should be set with an eye to the
+ * length of a cache line.
+ */
+
+#define BLOCKLEN 62
+#define CENTER ((BLOCKLEN - 1) / 2)
+
+/* A `dequeobject` is composed of a doubly-linked list of `block` nodes.
+ * This list is not circular (the leftmost block has leftlink==NULL,
+ * and the rightmost block has rightlink==NULL).  A deque d's first
+ * element is at d.leftblock[leftindex] and its last element is at
+ * d.rightblock[rightindex]; note that, unlike as for Python slice
+ * indices, these indices are inclusive on both ends.  By being inclusive
+ * on both ends, algorithms for left and right operations become
+ * symmetrical which simplifies the design.
+ *
+ * The list of blocks is never empty, so d.leftblock and d.rightblock
+ * are never equal to NULL.
+ *
+ * The indices, d.leftindex and d.rightindex are always in the range
+ *     0 <= index < BLOCKLEN.
+ * Their exact relationship is:
+ *     (d.leftindex + d.len - 1) % BLOCKLEN == d.rightindex.
+ *
+ * Empty deques have d.len == 0; d.leftblock==d.rightblock;
+ * d.leftindex == CENTER+1; and d.rightindex == CENTER.
+ * Checking for d.len == 0 is the intended way to see whether d is empty.
+ *
+ * Whenever d.leftblock == d.rightblock,
+ *     d.leftindex + d.len - 1 == d.rightindex.
+ *
+ * However, when d.leftblock != d.rightblock, d.leftindex and d.rightindex
+ * become indices into distinct blocks and either may be larger than the
+ * other.
+ */
+
+typedef struct BLOCK {
+	struct BLOCK *leftlink;
+	struct BLOCK *rightlink;
+	PyObject *data[BLOCKLEN];
+} block;
+
+static block *
+newblock(block *leftlink, block *rightlink, int len) {
+	block *b;
+	/* To prevent len from overflowing INT_MAX on 64-bit machines, we
+	 * refuse to allocate new blocks if the current len is dangerously
+	 * close.  There is some extra margin to prevent spurious arithmetic
+	 * overflows at various places.  The following check ensures that
+	 * the blocks allocated to the deque, in the worst case, can only
+	 * have INT_MAX-2 entries in total.
+	 */
+	if (len >= INT_MAX - 2*BLOCKLEN) {
+		PyErr_SetString(PyExc_OverflowError,
+				"cannot add more blocks to the deque");
+		return NULL;
+	}
+	b = PyMem_Malloc(sizeof(block));
+	if (b == NULL) {
+		PyErr_NoMemory();
+		return NULL;
+	}
+	b->leftlink = leftlink;
+	b->rightlink = rightlink;
+	return b;
+}
+
+typedef struct {
+	PyObject_HEAD
+	block *leftblock;
+	block *rightblock;
+	int leftindex;	/* in range(BLOCKLEN) */
+	int rightindex;	/* in range(BLOCKLEN) */
+	int len;
+	long state;	/* incremented whenever the indices move */
+	PyObject *weakreflist; /* List of weak references */
+} dequeobject;
+
+static PyTypeObject deque_type;
+
+static PyObject *
+deque_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	dequeobject *deque;
+	block *b;
+
+	if (type == &deque_type && !_PyArg_NoKeywords("deque()", kwds))
+		return NULL;
+
+	/* create dequeobject structure */
+	deque = (dequeobject *)type->tp_alloc(type, 0);
+	if (deque == NULL)
+		return NULL;
+
+	b = newblock(NULL, NULL, 0);
+	if (b == NULL) {
+		Py_DECREF(deque);
+		return NULL;
+	}
+
+	assert(BLOCKLEN >= 2);
+	deque->leftblock = b;
+	deque->rightblock = b;
+	deque->leftindex = CENTER + 1;
+	deque->rightindex = CENTER;
+	deque->len = 0;
+	deque->state = 0;
+	deque->weakreflist = NULL;
+
+	return (PyObject *)deque;
+}
+
+static PyObject *
+deque_append(dequeobject *deque, PyObject *item)
+{
+	deque->state++;
+	if (deque->rightindex == BLOCKLEN-1) {
+		block *b = newblock(deque->rightblock, NULL, deque->len);
+		if (b == NULL)
+			return NULL;
+		assert(deque->rightblock->rightlink == NULL);
+		deque->rightblock->rightlink = b;
+		deque->rightblock = b;
+		deque->rightindex = -1;
+	}
+	Py_INCREF(item);
+	deque->len++;
+	deque->rightindex++;
+	deque->rightblock->data[deque->rightindex] = item;
+	Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(append_doc, "Add an element to the right side of the deque.");
+
+static PyObject *
+deque_appendleft(dequeobject *deque, PyObject *item)
+{
+	deque->state++;
+	if (deque->leftindex == 0) {
+		block *b = newblock(NULL, deque->leftblock, deque->len);
+		if (b == NULL)
+			return NULL;
+		assert(deque->leftblock->leftlink == NULL);
+		deque->leftblock->leftlink = b;
+		deque->leftblock = b;
+		deque->leftindex = BLOCKLEN;
+	}
+	Py_INCREF(item);
+	deque->len++;
+	deque->leftindex--;
+	deque->leftblock->data[deque->leftindex] = item;
+	Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(appendleft_doc, "Add an element to the left side of the deque.");
+
+static PyObject *
+deque_pop(dequeobject *deque, PyObject *unused)
+{
+	PyObject *item;
+	block *prevblock;
+
+	if (deque->len == 0) {
+		PyErr_SetString(PyExc_IndexError, "pop from an empty deque");
+		return NULL;
+	}
+	item = deque->rightblock->data[deque->rightindex];
+	deque->rightindex--;
+	deque->len--;
+	deque->state++;
+
+	if (deque->rightindex == -1) {
+		if (deque->len == 0) {
+			assert(deque->leftblock == deque->rightblock);
+			assert(deque->leftindex == deque->rightindex+1);
+			/* re-center instead of freeing a block */
+			deque->leftindex = CENTER + 1;
+			deque->rightindex = CENTER;
+		} else {
+			prevblock = deque->rightblock->leftlink;
+			assert(deque->leftblock != deque->rightblock);
+			PyMem_Free(deque->rightblock);
+			prevblock->rightlink = NULL;
+			deque->rightblock = prevblock;
+			deque->rightindex = BLOCKLEN - 1;
+		}
+	}
+	return item;
+}
+
+PyDoc_STRVAR(pop_doc, "Remove and return the rightmost element.");
+
+static PyObject *
+deque_popleft(dequeobject *deque, PyObject *unused)
+{
+	PyObject *item;
+	block *prevblock;
+
+	if (deque->len == 0) {
+		PyErr_SetString(PyExc_IndexError, "pop from an empty deque");
+		return NULL;
+	}
+	assert(deque->leftblock != NULL);
+	item = deque->leftblock->data[deque->leftindex];
+	deque->leftindex++;
+	deque->len--;
+	deque->state++;
+
+	if (deque->leftindex == BLOCKLEN) {
+		if (deque->len == 0) {
+			assert(deque->leftblock == deque->rightblock);
+			assert(deque->leftindex == deque->rightindex+1);
+			/* re-center instead of freeing a block */
+			deque->leftindex = CENTER + 1;
+			deque->rightindex = CENTER;
+		} else {
+			assert(deque->leftblock != deque->rightblock);
+			prevblock = deque->leftblock->rightlink;
+			PyMem_Free(deque->leftblock);
+			assert(prevblock != NULL);
+			prevblock->leftlink = NULL;
+			deque->leftblock = prevblock;
+			deque->leftindex = 0;
+		}
+	}
+	return item;
+}
+
+PyDoc_STRVAR(popleft_doc, "Remove and return the leftmost element.");
+
+static PyObject *
+deque_extend(dequeobject *deque, PyObject *iterable)
+{
+	PyObject *it, *item;
+
+	it = PyObject_GetIter(iterable);
+	if (it == NULL)
+		return NULL;
+
+	while ((item = PyIter_Next(it)) != NULL) {
+		deque->state++;
+		if (deque->rightindex == BLOCKLEN-1) {
+			block *b = newblock(deque->rightblock, NULL,
+					    deque->len);
+			if (b == NULL) {
+				Py_DECREF(item);
+				Py_DECREF(it);
+				return NULL;
+			}
+			assert(deque->rightblock->rightlink == NULL);
+			deque->rightblock->rightlink = b;
+			deque->rightblock = b;
+			deque->rightindex = -1;
+		}
+		deque->len++;
+		deque->rightindex++;
+		deque->rightblock->data[deque->rightindex] = item;
+	}
+	Py_DECREF(it);
+	if (PyErr_Occurred())
+		return NULL;
+	Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(extend_doc,
+"Extend the right side of the deque with elements from the iterable");
+
+static PyObject *
+deque_extendleft(dequeobject *deque, PyObject *iterable)
+{
+	PyObject *it, *item;
+
+	it = PyObject_GetIter(iterable);
+	if (it == NULL)
+		return NULL;
+
+	while ((item = PyIter_Next(it)) != NULL) {
+		deque->state++;
+		if (deque->leftindex == 0) {
+			block *b = newblock(NULL, deque->leftblock,
+					    deque->len);
+			if (b == NULL) {
+				Py_DECREF(item);
+				Py_DECREF(it);
+				return NULL;
+			}
+			assert(deque->leftblock->leftlink == NULL);
+			deque->leftblock->leftlink = b;
+			deque->leftblock = b;
+			deque->leftindex = BLOCKLEN;
+		}
+		deque->len++;
+		deque->leftindex--;
+		deque->leftblock->data[deque->leftindex] = item;
+	}
+	Py_DECREF(it);
+	if (PyErr_Occurred())
+		return NULL;
+	Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(extendleft_doc,
+"Extend the left side of the deque with elements from the iterable");
+
+static int
+_deque_rotate(dequeobject *deque, Py_ssize_t n)
+{
+	int i, len=deque->len, halflen=(len+1)>>1;
+	PyObject *item, *rv;
+
+	if (len == 0)
+		return 0;
+	if (n > halflen || n < -halflen) {
+		n %= len;
+		if (n > halflen)
+			n -= len;
+		else if (n < -halflen)
+			n += len;
+	}
+
+	for (i=0 ; i<n ; i++) {
+		item = deque_pop(deque, NULL);
+		assert (item != NULL);
+		rv = deque_appendleft(deque, item);
+		Py_DECREF(item);
+		if (rv == NULL)
+			return -1;
+		Py_DECREF(rv);
+	}
+	for (i=0 ; i>n ; i--) {
+		item = deque_popleft(deque, NULL);
+		assert (item != NULL);
+		rv = deque_append(deque, item);
+		Py_DECREF(item);
+		if (rv == NULL)
+			return -1;
+		Py_DECREF(rv);
+	}
+	return 0;
+}
+
+static PyObject *
+deque_rotate(dequeobject *deque, PyObject *args)
+{
+	int n=1;
+
+	if (!PyArg_ParseTuple(args, "|i:rotate", &n))
+		return NULL;
+	if (_deque_rotate(deque, n) == 0)
+		Py_RETURN_NONE;
+	return NULL;
+}
+
+PyDoc_STRVAR(rotate_doc,
+"Rotate the deque n steps to the right (default n=1).  If n is negative, rotates left.");
+
+static Py_ssize_t
+deque_len(dequeobject *deque)
+{
+	return deque->len;
+}
+
+static PyObject *
+deque_remove(dequeobject *deque, PyObject *value)
+{
+	Py_ssize_t i, n=deque->len;
+
+	for (i=0 ; i<n ; i++) {
+		PyObject *item = deque->leftblock->data[deque->leftindex];
+		int cmp = PyObject_RichCompareBool(item, value, Py_EQ);
+
+		if (deque->len != n) {
+			PyErr_SetString(PyExc_IndexError,
+				"deque mutated during remove().");
+			return NULL;
+		}
+		if (cmp > 0) {
+			PyObject *tgt = deque_popleft(deque, NULL);
+			assert (tgt != NULL);
+			Py_DECREF(tgt);
+			if (_deque_rotate(deque, i) == -1)
+				return NULL;
+			Py_RETURN_NONE;
+		}
+		else if (cmp < 0) {
+			_deque_rotate(deque, i);
+			return NULL;
+		}
+		_deque_rotate(deque, -1);
+	}
+	PyErr_SetString(PyExc_ValueError, "deque.remove(x): x not in deque");
+	return NULL;
+}
+
+PyDoc_STRVAR(remove_doc,
+"D.remove(value) -- remove first occurrence of value.");
+
+static int
+deque_clear(dequeobject *deque)
+{
+	PyObject *item;
+
+	while (deque->len) {
+		item = deque_pop(deque, NULL);
+		assert (item != NULL);
+		Py_DECREF(item);
+	}
+	assert(deque->leftblock == deque->rightblock &&
+	       deque->leftindex - 1 == deque->rightindex &&
+	       deque->len == 0);
+	return 0;
+}
+
+static PyObject *
+deque_item(dequeobject *deque, int i)
+{
+	block *b;
+	PyObject *item;
+	int n, index=i;
+
+	if (i < 0 || i >= deque->len) {
+		PyErr_SetString(PyExc_IndexError,
+				"deque index out of range");
+		return NULL;
+	}
+
+	if (i == 0) {
+		i = deque->leftindex;
+		b = deque->leftblock;
+	} else if (i == deque->len - 1) {
+		i = deque->rightindex;
+		b = deque->rightblock;
+	} else {
+		i += deque->leftindex;
+		n = i / BLOCKLEN;
+		i %= BLOCKLEN;
+		if (index < (deque->len >> 1)) {
+			b = deque->leftblock;
+			while (n--)
+				b = b->rightlink;
+		} else {
+			n = (deque->leftindex + deque->len - 1) / BLOCKLEN - n;
+			b = deque->rightblock;
+			while (n--)
+				b = b->leftlink;
+		}
+	}
+	item = b->data[i];
+	Py_INCREF(item);
+	return item;
+}
+
+/* delitem() implemented in terms of rotate for simplicity and reasonable
+   performance near the end points.  If for some reason this method becomes
+   popular, it is not hard to re-implement this using direct data movement
+   (similar to code in list slice assignment) and achieve a two or threefold
+   performance boost.
+*/
+
+static int
+deque_del_item(dequeobject *deque, Py_ssize_t i)
+{
+	PyObject *item;
+
+	assert (i >= 0 && i < deque->len);
+	if (_deque_rotate(deque, -i) == -1)
+		return -1;
+
+	item = deque_popleft(deque, NULL);
+	assert (item != NULL);
+	Py_DECREF(item);
+
+	return _deque_rotate(deque, i);
+}
+
+static int
+deque_ass_item(dequeobject *deque, Py_ssize_t i, PyObject *v)
+{
+	PyObject *old_value;
+	block *b;
+	Py_ssize_t n, len=deque->len, halflen=(len+1)>>1, index=i;
+
+	if (i < 0 || i >= len) {
+		PyErr_SetString(PyExc_IndexError,
+				"deque index out of range");
+		return -1;
+	}
+	if (v == NULL)
+		return deque_del_item(deque, i);
+
+	i += deque->leftindex;
+	n = i / BLOCKLEN;
+	i %= BLOCKLEN;
+	if (index <= halflen) {
+		b = deque->leftblock;
+		while (n--)
+			b = b->rightlink;
+	} else {
+		n = (deque->leftindex + len - 1) / BLOCKLEN - n;
+		b = deque->rightblock;
+		while (n--)
+			b = b->leftlink;
+	}
+	Py_INCREF(v);
+	old_value = b->data[i];
+	b->data[i] = v;
+	Py_DECREF(old_value);
+	return 0;
+}
+
+static PyObject *
+deque_clearmethod(dequeobject *deque)
+{
+	int rv;
+
+	rv = deque_clear(deque);
+	assert (rv != -1);
+	Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(clear_doc, "Remove all elements from the deque.");
+
+static void
+deque_dealloc(dequeobject *deque)
+{
+	PyObject_GC_UnTrack(deque);
+	if (deque->weakreflist != NULL)
+		PyObject_ClearWeakRefs((PyObject *) deque);
+	if (deque->leftblock != NULL) {
+		deque_clear(deque);
+		assert(deque->leftblock != NULL);
+		PyMem_Free(deque->leftblock);
+	}
+	deque->leftblock = NULL;
+	deque->rightblock = NULL;
+	deque->ob_type->tp_free(deque);
+}
+
+static int
+deque_traverse(dequeobject *deque, visitproc visit, void *arg)
+{
+	block *b;
+	PyObject *item;
+	int index;
+	int indexlo = deque->leftindex;
+
+	for (b = deque->leftblock; b != NULL; b = b->rightlink) {
+		const int indexhi = b == deque->rightblock ?
+					 deque->rightindex :
+				    	 BLOCKLEN - 1;
+
+		for (index = indexlo; index <= indexhi; ++index) {
+			item = b->data[index];
+			Py_VISIT(item);
+		}
+		indexlo = 0;
+	}
+	return 0;
+}
+
+static long
+deque_nohash(PyObject *self)
+{
+	PyErr_SetString(PyExc_TypeError, "deque objects are unhashable");
+	return -1;
+}
+
+static PyObject *
+deque_copy(PyObject *deque)
+{
+	return PyObject_CallFunctionObjArgs((PyObject *)(deque->ob_type),
+		deque, NULL);
+}
+
+PyDoc_STRVAR(copy_doc, "Return a shallow copy of a deque.");
+
+static PyObject *
+deque_reduce(dequeobject *deque)
+{
+	PyObject *dict, *result, *it;
+
+	dict = PyObject_GetAttrString((PyObject *)deque, "__dict__");
+	if (dict == NULL) {
+		PyErr_Clear();
+		dict = Py_None;
+		Py_INCREF(dict);
+	}
+	it = PyObject_GetIter((PyObject *)deque);
+	if (it == NULL) {
+		Py_DECREF(dict);
+		return NULL;
+	}
+	result = Py_BuildValue("O()ON", deque->ob_type, dict, it);
+	Py_DECREF(dict);
+	return result;
+}
+
+PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
+
+static PyObject *
+deque_repr(PyObject *deque)
+{
+	PyObject *aslist, *result, *fmt;
+	int i;
+
+	i = Py_ReprEnter(deque);
+	if (i != 0) {
+		if (i < 0)
+			return NULL;
+		return PyString_FromString("[...]");
+	}
+
+	aslist = PySequence_List(deque);
+	if (aslist == NULL) {
+		Py_ReprLeave(deque);
+		return NULL;
+	}
+
+	fmt = PyString_FromString("deque(%r)");
+	if (fmt == NULL) {
+		Py_DECREF(aslist);
+		Py_ReprLeave(deque);
+		return NULL;
+	}
+	result = PyString_Format(fmt, aslist);
+	Py_DECREF(fmt);
+	Py_DECREF(aslist);
+	Py_ReprLeave(deque);
+	return result;
+}
+
+static int
+deque_tp_print(PyObject *deque, FILE *fp, int flags)
+{
+	PyObject *it, *item;
+	char *emit = "";	/* No separator emitted on first pass */
+	char *separator = ", ";
+	int i;
+
+	i = Py_ReprEnter(deque);
+	if (i != 0) {
+		if (i < 0)
+			return i;
+		fputs("[...]", fp);
+		return 0;
+	}
+
+	it = PyObject_GetIter(deque);
+	if (it == NULL)
+		return -1;
+
+	fputs("deque([", fp);
+	while ((item = PyIter_Next(it)) != NULL) {
+		fputs(emit, fp);
+		emit = separator;
+		if (PyObject_Print(item, fp, 0) != 0) {
+			Py_DECREF(item);
+			Py_DECREF(it);
+			Py_ReprLeave(deque);
+			return -1;
+		}
+		Py_DECREF(item);
+	}
+	Py_ReprLeave(deque);
+	Py_DECREF(it);
+	if (PyErr_Occurred())
+		return -1;
+	fputs("])", fp);
+	return 0;
+}
+
+static PyObject *
+deque_richcompare(PyObject *v, PyObject *w, int op)
+{
+	PyObject *it1=NULL, *it2=NULL, *x, *y;
+	int b, vs, ws, cmp=-1;
+
+	if (!PyObject_TypeCheck(v, &deque_type) ||
+	    !PyObject_TypeCheck(w, &deque_type)) {
+		Py_INCREF(Py_NotImplemented);
+		return Py_NotImplemented;
+	}
+
+	/* Shortcuts */
+	vs = ((dequeobject *)v)->len;
+	ws = ((dequeobject *)w)->len;
+	if (op == Py_EQ) {
+		if (v == w)
+			Py_RETURN_TRUE;
+		if (vs != ws)
+			Py_RETURN_FALSE;
+	}
+	if (op == Py_NE) {
+		if (v == w)
+			Py_RETURN_FALSE;
+		if (vs != ws)
+			Py_RETURN_TRUE;
+	}
+
+	/* Search for the first index where items are different */
+	it1 = PyObject_GetIter(v);
+	if (it1 == NULL)
+		goto done;
+	it2 = PyObject_GetIter(w);
+	if (it2 == NULL)
+		goto done;
+	for (;;) {
+		x = PyIter_Next(it1);
+		if (x == NULL && PyErr_Occurred())
+			goto done;
+		y = PyIter_Next(it2);
+		if (x == NULL || y == NULL)
+			break;
+		b = PyObject_RichCompareBool(x, y, Py_EQ);
+		if (b == 0) {
+			cmp = PyObject_RichCompareBool(x, y, op);
+			Py_DECREF(x);
+			Py_DECREF(y);
+			goto done;
+		}
+		Py_DECREF(x);
+		Py_DECREF(y);
+		if (b == -1)
+			goto done;
+	}
+	/* We reached the end of one deque or both */
+	Py_XDECREF(x);
+	Py_XDECREF(y);
+	if (PyErr_Occurred())
+		goto done;
+	switch (op) {
+	case Py_LT: cmp = y != NULL; break;  /* if w was longer */
+	case Py_LE: cmp = x == NULL; break;  /* if v was not longer */
+	case Py_EQ: cmp = x == y;    break;  /* if we reached the end of both */
+	case Py_NE: cmp = x != y;    break;  /* if one deque continues */
+	case Py_GT: cmp = x != NULL; break;  /* if v was longer */
+	case Py_GE: cmp = y == NULL; break;  /* if w was not longer */
+	}
+
+done:
+	Py_XDECREF(it1);
+	Py_XDECREF(it2);
+	if (cmp == 1)
+		Py_RETURN_TRUE;
+	if (cmp == 0)
+		Py_RETURN_FALSE;
+	return NULL;
+}
+
+static int
+deque_init(dequeobject *deque, PyObject *args, PyObject *kwds)
+{
+	PyObject *iterable = NULL;
+
+	if (!PyArg_UnpackTuple(args, "deque", 0, 1, &iterable))
+		return -1;
+
+	if (iterable != NULL) {
+		PyObject *rv = deque_extend(deque, iterable);
+		if (rv == NULL)
+			return -1;
+		Py_DECREF(rv);
+	}
+	return 0;
+}
+
+static PySequenceMethods deque_as_sequence = {
+	(lenfunc)deque_len,		/* sq_length */
+	0,				/* sq_concat */
+	0,				/* sq_repeat */
+	(ssizeargfunc)deque_item,	/* sq_item */
+	0,				/* sq_slice */
+	(ssizeobjargproc)deque_ass_item,	/* sq_ass_item */
+};
+
+/* deque object ********************************************************/
+
+static PyObject *deque_iter(dequeobject *deque);
+static PyObject *deque_reviter(dequeobject *deque);
+PyDoc_STRVAR(reversed_doc,
+	"D.__reversed__() -- return a reverse iterator over the deque");
+
+static PyMethodDef deque_methods[] = {
+	{"append",		(PyCFunction)deque_append,
+		METH_O,		 append_doc},
+	{"appendleft",		(PyCFunction)deque_appendleft,
+		METH_O,		 appendleft_doc},
+	{"clear",		(PyCFunction)deque_clearmethod,
+		METH_NOARGS,	 clear_doc},
+	{"__copy__",		(PyCFunction)deque_copy,
+		METH_NOARGS,	 copy_doc},
+	{"extend",		(PyCFunction)deque_extend,
+		METH_O,		 extend_doc},
+	{"extendleft",		(PyCFunction)deque_extendleft,
+		METH_O,		 extendleft_doc},
+	{"pop",			(PyCFunction)deque_pop,
+		METH_NOARGS,	 pop_doc},
+	{"popleft",		(PyCFunction)deque_popleft,
+		METH_NOARGS,	 popleft_doc},
+	{"__reduce__",	(PyCFunction)deque_reduce,
+		METH_NOARGS,	 reduce_doc},
+	{"remove",		(PyCFunction)deque_remove,
+		METH_O,		 remove_doc},
+	{"__reversed__",	(PyCFunction)deque_reviter,
+		METH_NOARGS,	 reversed_doc},
+	{"rotate",		(PyCFunction)deque_rotate,
+		METH_VARARGS,	rotate_doc},
+	{NULL,		NULL}	/* sentinel */
+};
+
+PyDoc_STRVAR(deque_doc,
+"deque(iterable) --> deque object\n\
+\n\
+Build an ordered collection accessible from endpoints only.");
+
+static PyTypeObject deque_type = {
+	PyObject_HEAD_INIT(NULL)
+	0,				/* ob_size */
+	"collections.deque",		/* tp_name */
+	sizeof(dequeobject),		/* tp_basicsize */
+	0,				/* tp_itemsize */
+	/* methods */
+	(destructor)deque_dealloc,	/* tp_dealloc */
+	deque_tp_print,			/* tp_print */
+	0,				/* tp_getattr */
+	0,				/* tp_setattr */
+	0,				/* tp_compare */
+	deque_repr,			/* tp_repr */
+	0,				/* tp_as_number */
+	&deque_as_sequence,		/* tp_as_sequence */
+	0,				/* tp_as_mapping */
+	deque_nohash,			/* tp_hash */
+	0,				/* tp_call */
+	0,				/* tp_str */
+	PyObject_GenericGetAttr,	/* tp_getattro */
+	0,				/* tp_setattro */
+	0,				/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
+		Py_TPFLAGS_HAVE_WEAKREFS,	/* tp_flags */
+	deque_doc,			/* tp_doc */
+	(traverseproc)deque_traverse,	/* tp_traverse */
+	(inquiry)deque_clear,		/* tp_clear */
+	(richcmpfunc)deque_richcompare,	/* tp_richcompare */
+	offsetof(dequeobject, weakreflist),	/* tp_weaklistoffset*/
+	(getiterfunc)deque_iter,	/* tp_iter */
+	0,				/* tp_iternext */
+	deque_methods,			/* tp_methods */
+	0,				/* tp_members */
+	0,				/* tp_getset */
+	0,				/* tp_base */
+	0,				/* tp_dict */
+	0,				/* tp_descr_get */
+	0,				/* tp_descr_set */
+	0,				/* tp_dictoffset */
+	(initproc)deque_init,		/* tp_init */
+	PyType_GenericAlloc,		/* tp_alloc */
+	deque_new,			/* tp_new */
+	PyObject_GC_Del,		/* tp_free */
+};
+
+/*********************** Deque Iterator **************************/
+
+typedef struct {
+	PyObject_HEAD
+	int index;
+	block *b;
+	dequeobject *deque;
+	long state;	/* state when the iterator is created */
+	int counter;    /* number of items remaining for iteration */
+} dequeiterobject;
+
+PyTypeObject dequeiter_type;
+
+static PyObject *
+deque_iter(dequeobject *deque)
+{
+	dequeiterobject *it;
+
+	it = PyObject_New(dequeiterobject, &dequeiter_type);
+	if (it == NULL)
+		return NULL;
+	it->b = deque->leftblock;
+	it->index = deque->leftindex;
+	Py_INCREF(deque);
+	it->deque = deque;
+	it->state = deque->state;
+	it->counter = deque->len;
+	return (PyObject *)it;
+}
+
+static void
+dequeiter_dealloc(dequeiterobject *dio)
+{
+	Py_XDECREF(dio->deque);
+	dio->ob_type->tp_free(dio);
+}
+
+static PyObject *
+dequeiter_next(dequeiterobject *it)
+{
+	PyObject *item;
+
+	if (it->deque->state != it->state) {
+		it->counter = 0;
+		PyErr_SetString(PyExc_RuntimeError,
+				"deque mutated during iteration");
+		return NULL;
+	}
+	if (it->counter == 0)
+		return NULL;        
+	assert (!(it->b == it->deque->rightblock &&
+		  it->index > it->deque->rightindex));
+
+	item = it->b->data[it->index];
+	it->index++;
+	it->counter--;
+	if (it->index == BLOCKLEN && it->counter > 0) {
+		assert (it->b->rightlink != NULL);
+		it->b = it->b->rightlink;
+		it->index = 0;
+	}
+	Py_INCREF(item);
+	return item;
+}
+
+static PyObject *
+dequeiter_len(dequeiterobject *it)
+{
+	return PyInt_FromLong(it->counter);
+}
+
+PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
+
+static PyMethodDef dequeiter_methods[] = {
+	{"__length_hint__", (PyCFunction)dequeiter_len, METH_NOARGS, length_hint_doc},
+ 	{NULL,		NULL}		/* sentinel */
+};
+
+PyTypeObject dequeiter_type = {
+	PyObject_HEAD_INIT(NULL)
+	0,					/* ob_size */
+	"deque_iterator",			/* tp_name */
+	sizeof(dequeiterobject),		/* tp_basicsize */
+	0,					/* tp_itemsize */
+	/* methods */
+	(destructor)dequeiter_dealloc,		/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	0,					/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT,			/* tp_flags */
+	0,					/* tp_doc */
+	0,					/* tp_traverse */
+	0,					/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	PyObject_SelfIter,			/* tp_iter */
+	(iternextfunc)dequeiter_next,		/* tp_iternext */
+	dequeiter_methods,			/* tp_methods */
+	0,
+};
+
+/*********************** Deque Reverse Iterator **************************/
+
+PyTypeObject dequereviter_type;
+
+static PyObject *
+deque_reviter(dequeobject *deque)
+{
+	dequeiterobject *it;
+
+	it = PyObject_New(dequeiterobject, &dequereviter_type);
+	if (it == NULL)
+		return NULL;
+	it->b = deque->rightblock;
+	it->index = deque->rightindex;
+	Py_INCREF(deque);
+	it->deque = deque;
+	it->state = deque->state;
+	it->counter = deque->len;
+	return (PyObject *)it;
+}
+
+static PyObject *
+dequereviter_next(dequeiterobject *it)
+{
+	PyObject *item;
+	if (it->counter == 0)
+		return NULL;
+
+	if (it->deque->state != it->state) {
+		it->counter = 0;
+		PyErr_SetString(PyExc_RuntimeError,
+				"deque mutated during iteration");
+		return NULL;
+	}
+	assert (!(it->b == it->deque->leftblock &&
+		  it->index < it->deque->leftindex));
+
+	item = it->b->data[it->index];
+	it->index--;
+	it->counter--;
+	if (it->index == -1 && it->counter > 0) {
+		assert (it->b->leftlink != NULL);
+		it->b = it->b->leftlink;
+		it->index = BLOCKLEN - 1;
+	}
+	Py_INCREF(item);
+	return item;
+}
+
+PyTypeObject dequereviter_type = {
+	PyObject_HEAD_INIT(NULL)
+	0,					/* ob_size */
+	"deque_reverse_iterator",		/* tp_name */
+	sizeof(dequeiterobject),		/* tp_basicsize */
+	0,					/* tp_itemsize */
+	/* methods */
+	(destructor)dequeiter_dealloc,		/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	0,					/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT,			/* tp_flags */
+	0,					/* tp_doc */
+	0,					/* tp_traverse */
+	0,					/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	PyObject_SelfIter,			/* tp_iter */
+	(iternextfunc)dequereviter_next,	/* tp_iternext */
+	dequeiter_methods,			/* tp_methods */
+	0,
+};
+
+/* defaultdict type *********************************************************/
+
+typedef struct {
+	PyDictObject dict;
+	PyObject *default_factory;
+} defdictobject;
+
+static PyTypeObject defdict_type; /* Forward */
+
+PyDoc_STRVAR(defdict_missing_doc,
+"__missing__(key) # Called by __getitem__ for missing key; pseudo-code:\n\
+  if self.default_factory is None: raise KeyError((key,))\n\
+  self[key] = value = self.default_factory()\n\
+  return value\n\
+");
+
+static PyObject *
+defdict_missing(defdictobject *dd, PyObject *key)
+{
+	PyObject *factory = dd->default_factory;
+	PyObject *value;
+	if (factory == NULL || factory == Py_None) {
+		/* XXX Call dict.__missing__(key) */
+		PyObject *tup;
+		tup = PyTuple_Pack(1, key);
+		if (!tup) return NULL;
+		PyErr_SetObject(PyExc_KeyError, tup);
+		Py_DECREF(tup);
+		return NULL;
+	}
+	value = PyEval_CallObject(factory, NULL);
+	if (value == NULL)
+		return value;
+	if (PyObject_SetItem((PyObject *)dd, key, value) < 0) {
+		Py_DECREF(value);
+		return NULL;
+	}
+	return value;
+}
+
+PyDoc_STRVAR(defdict_copy_doc, "D.copy() -> a shallow copy of D.");
+
+static PyObject *
+defdict_copy(defdictobject *dd)
+{
+	/* This calls the object's class.  That only works for subclasses
+	   whose class constructor has the same signature.  Subclasses that
+	   define a different constructor signature must override copy().
+	*/
+	return PyObject_CallFunctionObjArgs((PyObject *)dd->dict.ob_type,
+					    dd->default_factory, dd, NULL);
+}
+
+static PyObject *
+defdict_reduce(defdictobject *dd)
+{
+	/* __reduce__ must return a 5-tuple as follows:
+
+	   - factory function
+	   - tuple of args for the factory function
+	   - additional state (here None)
+	   - sequence iterator (here None)
+	   - dictionary iterator (yielding successive (key, value) pairs
+
+	   This API is used by pickle.py and copy.py.
+
+	   For this to be useful with pickle.py, the default_factory
+	   must be picklable; e.g., None, a built-in, or a global
+	   function in a module or package.
+
+	   Both shallow and deep copying are supported, but for deep
+	   copying, the default_factory must be deep-copyable; e.g. None,
+	   or a built-in (functions are not copyable at this time).
+
+	   This only works for subclasses as long as their constructor
+	   signature is compatible; the first argument must be the
+	   optional default_factory, defaulting to None.
+	*/
+	PyObject *args;
+	PyObject *items;
+	PyObject *result;
+	if (dd->default_factory == NULL || dd->default_factory == Py_None)
+		args = PyTuple_New(0);
+	else
+		args = PyTuple_Pack(1, dd->default_factory);
+	if (args == NULL)
+		return NULL;
+	items = PyObject_CallMethod((PyObject *)dd, "iteritems", "()");
+	if (items == NULL) {
+		Py_DECREF(args);
+		return NULL;
+	}
+	result = PyTuple_Pack(5, dd->dict.ob_type, args,
+			      Py_None, Py_None, items);
+	Py_DECREF(items);
+	Py_DECREF(args);
+	return result;
+}
+
+static PyMethodDef defdict_methods[] = {
+	{"__missing__", (PyCFunction)defdict_missing, METH_O,
+	 defdict_missing_doc},
+	{"copy", (PyCFunction)defdict_copy, METH_NOARGS,
+	 defdict_copy_doc},
+	{"__copy__", (PyCFunction)defdict_copy, METH_NOARGS,
+	 defdict_copy_doc},
+	{"__reduce__", (PyCFunction)defdict_reduce, METH_NOARGS,
+	 reduce_doc},
+	{NULL}
+};
+
+static PyMemberDef defdict_members[] = {
+	{"default_factory", T_OBJECT,
+	 offsetof(defdictobject, default_factory), 0,
+	 PyDoc_STR("Factory for default value called by __missing__().")},
+	{NULL}
+};
+
+static void
+defdict_dealloc(defdictobject *dd)
+{
+	Py_CLEAR(dd->default_factory);
+	PyDict_Type.tp_dealloc((PyObject *)dd);
+}
+
+static int
+defdict_print(defdictobject *dd, FILE *fp, int flags)
+{
+	int sts;
+	fprintf(fp, "defaultdict(");
+	if (dd->default_factory == NULL)
+		fprintf(fp, "None");
+	else {
+		PyObject_Print(dd->default_factory, fp, 0);
+	}
+	fprintf(fp, ", ");
+	sts = PyDict_Type.tp_print((PyObject *)dd, fp, 0);
+	fprintf(fp, ")");
+	return sts;
+}
+
+static PyObject *
+defdict_repr(defdictobject *dd)
+{
+	PyObject *defrepr;
+	PyObject *baserepr;
+	PyObject *result;
+	baserepr = PyDict_Type.tp_repr((PyObject *)dd);
+	if (baserepr == NULL)
+		return NULL;
+	if (dd->default_factory == NULL)
+		defrepr = PyString_FromString("None");
+	else
+		defrepr = PyObject_Repr(dd->default_factory);
+	if (defrepr == NULL) {
+		Py_DECREF(baserepr);
+		return NULL;
+	}
+	result = PyString_FromFormat("defaultdict(%s, %s)",
+				     PyString_AS_STRING(defrepr),
+				     PyString_AS_STRING(baserepr));
+	Py_DECREF(defrepr);
+	Py_DECREF(baserepr);
+	return result;
+}
+
+static int
+defdict_traverse(PyObject *self, visitproc visit, void *arg)
+{
+	Py_VISIT(((defdictobject *)self)->default_factory);
+	return PyDict_Type.tp_traverse(self, visit, arg);
+}
+
+static int
+defdict_tp_clear(defdictobject *dd)
+{
+	Py_CLEAR(dd->default_factory);
+	return PyDict_Type.tp_clear((PyObject *)dd);
+}
+
+static int
+defdict_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+	defdictobject *dd = (defdictobject *)self;
+	PyObject *olddefault = dd->default_factory;
+	PyObject *newdefault = NULL;
+	PyObject *newargs;
+	int result;
+	if (args == NULL || !PyTuple_Check(args))
+		newargs = PyTuple_New(0);
+	else {
+		Py_ssize_t n = PyTuple_GET_SIZE(args);
+		if (n > 0) {
+			newdefault = PyTuple_GET_ITEM(args, 0);
+			if (!PyCallable_Check(newdefault)) {
+				PyErr_SetString(PyExc_TypeError,
+					"first argument must be callable");                           
+				return -1;
+			}
+		}
+		newargs = PySequence_GetSlice(args, 1, n);
+	}
+	if (newargs == NULL)
+		return -1;
+	Py_XINCREF(newdefault);
+	dd->default_factory = newdefault;
+	result = PyDict_Type.tp_init(self, newargs, kwds);
+	Py_DECREF(newargs);
+	Py_XDECREF(olddefault);
+	return result;
+}
+
+PyDoc_STRVAR(defdict_doc,
+"defaultdict(default_factory) --> dict with default factory\n\
+\n\
+The default factory is called without arguments to produce\n\
+a new value when a key is not present, in __getitem__ only.\n\
+A defaultdict compares equal to a dict with the same items.\n\
+");
+
+/* See comment in xxsubtype.c */
+#define DEFERRED_ADDRESS(ADDR) 0
+
+static PyTypeObject defdict_type = {
+	PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
+	0,				/* ob_size */
+	"collections.defaultdict",	/* tp_name */
+	sizeof(defdictobject),		/* tp_basicsize */
+	0,				/* tp_itemsize */
+	/* methods */
+	(destructor)defdict_dealloc,	/* tp_dealloc */
+	(printfunc)defdict_print,	/* tp_print */
+	0,				/* tp_getattr */
+	0,				/* tp_setattr */
+	0,				/* tp_compare */
+	(reprfunc)defdict_repr,		/* tp_repr */
+	0,				/* tp_as_number */
+	0,				/* tp_as_sequence */
+	0,				/* tp_as_mapping */
+	0,	       			/* tp_hash */
+	0,				/* tp_call */
+	0,				/* tp_str */
+	PyObject_GenericGetAttr,	/* tp_getattro */
+	0,				/* tp_setattro */
+	0,				/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
+		Py_TPFLAGS_HAVE_WEAKREFS,	/* tp_flags */
+	defdict_doc,			/* tp_doc */
+	defdict_traverse,		/* tp_traverse */
+	(inquiry)defdict_tp_clear,	/* tp_clear */
+	0,				/* tp_richcompare */
+	0,				/* tp_weaklistoffset*/
+	0,				/* tp_iter */
+	0,				/* tp_iternext */
+	defdict_methods,		/* tp_methods */
+	defdict_members,		/* tp_members */
+	0,				/* tp_getset */
+	DEFERRED_ADDRESS(&PyDict_Type),	/* tp_base */
+	0,				/* tp_dict */
+	0,				/* tp_descr_get */
+	0,				/* tp_descr_set */
+	0,				/* tp_dictoffset */
+	defdict_init,			/* tp_init */
+	PyType_GenericAlloc,		/* tp_alloc */
+	0,				/* tp_new */
+	PyObject_GC_Del,		/* tp_free */
+};
+
+/* module level code ********************************************************/
+
+PyDoc_STRVAR(module_doc,
+"High performance data structures.\n\
+- deque:        ordered collection accessible from endpoints only\n\
+- defaultdict:  dict subclass with a default value factory\n\
+");
+
+PyMODINIT_FUNC
+initcollections(void)
+{
+	PyObject *m;
+
+	m = Py_InitModule3("collections", NULL, module_doc);
+	if (m == NULL)
+		return;
+
+	if (PyType_Ready(&deque_type) < 0)
+		return;
+	Py_INCREF(&deque_type);
+	PyModule_AddObject(m, "deque", (PyObject *)&deque_type);
+
+	defdict_type.tp_base = &PyDict_Type;
+	if (PyType_Ready(&defdict_type) < 0)
+		return;
+	Py_INCREF(&defdict_type);
+	PyModule_AddObject(m, "defaultdict", (PyObject *)&defdict_type);
+
+	if (PyType_Ready(&dequeiter_type) < 0)
+		return;
+
+	if (PyType_Ready(&dequereviter_type) < 0)
+		return;
+
+	return;
+}

Added: vendor/Python/current/Modules/config.c.in
===================================================================
--- vendor/Python/current/Modules/config.c.in	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/config.c.in	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,66 @@
+/* -*- C -*- ***********************************************
+Copyright (c) 2000, BeOpen.com.
+Copyright (c) 1995-2000, Corporation for National Research Initiatives.
+Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
+All rights reserved.
+
+See the file "Misc/COPYRIGHT" for information on usage and
+redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+******************************************************************/
+
+/* Module configuration */
+
+/* !!! !!! !!! This file is edited by the makesetup script !!! !!! !!! */
+
+/* This file contains the table of built-in modules.
+   See init_builtin() in import.c. */
+
+#include "Python.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* -- ADDMODULE MARKER 1 -- */
+
+extern void PyMarshal_Init(void);
+extern void initimp(void);
+extern void initgc(void);
+extern void init_ast(void);
+extern void init_types(void);
+
+struct _inittab _PyImport_Inittab[] = {
+
+/* -- ADDMODULE MARKER 2 -- */
+
+	/* This module lives in marshal.c */
+	{"marshal", PyMarshal_Init},
+
+	/* This lives in import.c */
+	{"imp", initimp},
+
+	/* This lives in Python/Python-ast.c */
+	{"_ast", init_ast},
+
+	/* This lives in Python/_types.c */
+	{"_types", init_types},
+
+	/* These entries are here for sys.builtin_module_names */
+	{"__main__", NULL},
+	{"__builtin__", NULL},
+	{"sys", NULL},
+	{"exceptions", NULL},
+
+	/* This lives in gcmodule.c */
+	{"gc", initgc},
+
+	/* Sentinel */
+	{0, 0}
+};
+
+
+#ifdef __cplusplus
+}
+#endif
+

Added: vendor/Python/current/Modules/cryptmodule.c
===================================================================
--- vendor/Python/current/Modules/cryptmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/cryptmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,49 @@
+/* cryptmodule.c - by Steve Majewski
+ */
+
+#include "Python.h"
+
+#include <sys/types.h>
+
+#ifdef __VMS
+#include <openssl/des.h>
+#endif
+
+/* Module crypt */
+
+
+static PyObject *crypt_crypt(PyObject *self, PyObject *args)
+{
+	char *word, *salt; 
+#ifndef __VMS
+	extern char * crypt(const char *, const char *);
+#endif
+
+	if (!PyArg_ParseTuple(args, "ss:crypt", &word, &salt)) {
+		return NULL;
+	}
+	/* On some platforms (AtheOS) crypt returns NULL for an invalid
+	   salt. Return None in that case. XXX Maybe raise an exception?  */
+	return Py_BuildValue("s", crypt(word, salt));
+
+}
+
+PyDoc_STRVAR(crypt_crypt__doc__,
+"crypt(word, salt) -> string\n\
+word will usually be a user's password. salt is a 2-character string\n\
+which will be used to select one of 4096 variations of DES. The characters\n\
+in salt must be either \".\", \"/\", or an alphanumeric character. Returns\n\
+the hashed password as a string, which will be composed of characters from\n\
+the same alphabet as the salt.");
+
+
+static PyMethodDef crypt_methods[] = {
+	{"crypt",	crypt_crypt, METH_VARARGS, crypt_crypt__doc__},
+	{NULL,		NULL}		/* sentinel */
+};
+
+PyMODINIT_FUNC
+initcrypt(void)
+{
+	Py_InitModule("crypt", crypt_methods);
+}

Added: vendor/Python/current/Modules/cstubs
===================================================================
--- vendor/Python/current/Modules/cstubs	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/cstubs	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1364 @@
+
+/*
+Input used to generate the Python module "glmodule.c".
+The stub generator is a Python script called "cgen.py".
+
+Each definition must be contained on one line:
+
+<returntype> <name> <type> <arg> <type> <arg>
+
+<returntype> can be: void, short, long (XXX maybe others?)
+
+<type> can be: char, string, short, float, long, or double
+	string indicates a null terminated string;
+	if <type> is char and <arg> begins with a *, the * is stripped
+	and <type> is changed into string
+
+<arg> has the form <mode> or <mode>[<subscript>]
+	where <mode> can be
+		s: arg is sent
+		r: arg is received		(arg is a pointer)
+	and <subscript> can be (N and I are numbers):
+		N
+		argI
+		retval
+		N*argI
+		N*I
+		N*retval
+	In the case where the subscript consists of two parts
+	separated by *, the first part is the width of the matrix, and
+	the second part is the length of the matrix.  This order is
+	opposite from the order used in C to declare a two-dimensional
+	matrix.
+*/
+
+/*
+ * An attempt has been made to make this module switch threads on qread
+ * calls. It is far from safe, though.
+ */
+
+#include <gl.h>
+#include <device.h>
+
+#ifdef __sgi
+extern int devport();
+extern int textwritemask();
+extern int pagewritemask();
+extern int gewrite();
+extern int gettp();
+#endif
+
+#include "Python.h"
+#include "cgensupport.h"
+
+/*
+Some stubs are too complicated for the stub generator.
+We can include manually written versions of them here.
+A line starting with '%' gives the name of the function so the stub
+generator can include it in the table of functions.
+*/
+
+% qread
+
+static PyObject *
+gl_qread(self, args)
+	PyObject *self;
+	PyObject *args;
+{
+	long retval;
+	short arg1 ;
+	Py_BEGIN_ALLOW_THREADS
+	retval = qread( & arg1 );
+	Py_END_ALLOW_THREADS
+	{ PyObject *v = PyTuple_New( 2 );
+	  if (v == NULL) return NULL;
+	  PyTuple_SetItem(v, 0, mknewlongobject(retval));
+	  PyTuple_SetItem(v, 1, mknewshortobject(arg1));
+	  return v;
+	}
+}
+
+
+/*
+varray -- an array of v.. calls.
+The argument is an array (maybe list or tuple) of points.
+Each point must be a tuple or list of coordinates (x, y, z).
+The points may be 2- or 3-dimensional but must all have the
+same dimension.  Float and int values may be mixed however.
+The points are always converted to 3D double precision points
+by assuming z=0.0 if necessary (as indicated in the man page),
+and for each point v3d() is called.
+*/
+
+% varray
+
+static PyObject *
+gl_varray(self, args)
+	PyObject *self;
+	PyObject *args;
+{
+	PyObject *v, *w=NULL;
+	int i, n, width;
+	double vec[3];
+	PyObject * (*getitem)(PyObject *, int);
+	
+	if (!PyArg_GetObject(args, 1, 0, &v))
+		return NULL;
+	
+	if (PyList_Check(v)) {
+		n = PyList_Size(v);
+		getitem = PyList_GetItem;
+	}
+	else if (PyTuple_Check(v)) {
+		n = PyTuple_Size(v);
+		getitem = PyTuple_GetItem;
+	}
+	else {
+		PyErr_BadArgument();
+		return NULL;
+	}
+	
+	if (n == 0) {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+	if (n > 0)
+		w = (*getitem)(v, 0);
+	
+	width = 0;
+	if (w == NULL) {
+	}
+	else if (PyList_Check(w)) {
+		width = PyList_Size(w);
+	}
+	else if (PyTuple_Check(w)) {
+		width = PyTuple_Size(w);
+	}
+	
+	switch (width) {
+	case 2:
+		vec[2] = 0.0;
+		/* Fall through */
+	case 3:
+		break;
+	default:
+		PyErr_BadArgument();
+		return NULL;
+	}
+	
+	for (i = 0; i < n; i++) {
+		w = (*getitem)(v, i);
+		if (!PyArg_GetDoubleArray(w, 1, 0, width, vec))
+			return NULL;
+		v3d(vec);
+	}
+	
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/*
+vnarray, nvarray -- an array of n3f and v3f calls.
+The argument is an array (list or tuple) of pairs of points and normals.
+Each pair is a tuple (NOT a list) of a point and a normal for that point.
+Each point or normal must be a tuple (NOT a list) of coordinates (x, y, z).
+Three coordinates must be given.  Float and int values may be mixed.
+For each pair, n3f() is called for the normal, and then v3f() is called
+for the vector.
+
+vnarray and nvarray differ only in the order of the vector and normal in
+the pair: vnarray expects (v, n) while nvarray expects (n, v).
+*/
+
+static PyObject *gen_nvarray(); /* Forward */
+
+% nvarray
+
+static PyObject *
+gl_nvarray(self, args)
+	PyObject *self;
+	PyObject *args;
+{
+	return gen_nvarray(args, 0);
+}
+
+% vnarray
+
+static PyObject *
+gl_vnarray(self, args)
+	PyObject *self;
+	PyObject *args;
+{
+	return gen_nvarray(args, 1);
+}
+
+/* Generic, internal version of {nv,nv}array: inorm indicates the
+   argument order, 0: normal first, 1: vector first. */
+
+static PyObject *
+gen_nvarray(args, inorm)
+	PyObject *args;
+	int inorm;
+{
+	PyObject *v, *w, *wnorm, *wvec;
+	int i, n;
+	float norm[3], vec[3];
+	PyObject * (*getitem)(PyObject *, int);
+	
+	if (!PyArg_GetObject(args, 1, 0, &v))
+		return NULL;
+	
+	if (PyList_Check(v)) {
+		n = PyList_Size(v);
+		getitem = PyList_GetItem;
+	}
+	else if (PyTuple_Check(v)) {
+		n = PyTuple_Size(v);
+		getitem = PyTuple_GetItem;
+	}
+	else {
+		PyErr_BadArgument();
+		return NULL;
+	}
+	
+	for (i = 0; i < n; i++) {
+		w = (*getitem)(v, i);
+		if (!PyTuple_Check(w) || PyTuple_Size(w) != 2) {
+			PyErr_BadArgument();
+			return NULL;
+		}
+		wnorm = PyTuple_GetItem(w, inorm);
+		wvec = PyTuple_GetItem(w, 1 - inorm);
+		if (!PyArg_GetFloatArray(wnorm, 1, 0, 3, norm) ||
+			!PyArg_GetFloatArray(wvec, 1, 0, 3, vec))
+			return NULL;
+		n3f(norm);
+		v3f(vec);
+	}
+	
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* nurbssurface(s_knots[], t_knots[], ctl[][], s_order, t_order, type).
+   The dimensions of ctl[] are computed as follows:
+   [len(s_knots) - s_order], [len(t_knots) - t_order]
+*/
+
+% nurbssurface
+
+static PyObject *
+gl_nurbssurface(self, args)
+	PyObject *self;
+	PyObject *args;
+{
+	long arg1 ;
+	double * arg2 ;
+	long arg3 ;
+	double * arg4 ;
+	double *arg5 ;
+	long arg6 ;
+	long arg7 ;
+	long arg8 ;
+	long ncoords;
+	long s_byte_stride, t_byte_stride;
+	long s_nctl, t_nctl;
+	long s, t;
+	PyObject *v, *w, *pt;
+	double *pnext;
+	if (!PyArg_GetLongArraySize(args, 6, 0, &arg1))
+		return NULL;
+	if ((arg2 = PyMem_NEW(double, arg1 )) == NULL) {
+		return PyErr_NoMemory();
+	}
+	if (!PyArg_GetDoubleArray(args, 6, 0, arg1 , arg2))
+		return NULL;
+	if (!PyArg_GetLongArraySize(args, 6, 1, &arg3))
+		return NULL;
+	if ((arg4 = PyMem_NEW(double, arg3 )) == NULL) {
+		return PyErr_NoMemory();
+	}
+	if (!PyArg_GetDoubleArray(args, 6, 1, arg3 , arg4))
+		return NULL;
+	if (!PyArg_GetLong(args, 6, 3, &arg6))
+		return NULL;
+	if (!PyArg_GetLong(args, 6, 4, &arg7))
+		return NULL;
+	if (!PyArg_GetLong(args, 6, 5, &arg8))
+		return NULL;
+	if (arg8 == N_XYZ)
+		ncoords = 3;
+	else if (arg8 == N_XYZW)
+		ncoords = 4;
+	else {
+		PyErr_BadArgument();
+		return NULL;
+	}
+	s_nctl = arg1 - arg6;
+	t_nctl = arg3 - arg7;
+	if (!PyArg_GetObject(args, 6, 2, &v))
+		return NULL;
+	if (!PyList_Check(v) || PyList_Size(v) != s_nctl) {
+		PyErr_BadArgument();
+		return NULL;
+	}
+	if ((arg5 = PyMem_NEW(double, s_nctl*t_nctl*ncoords )) == NULL) {
+		return PyErr_NoMemory();
+	}
+	pnext = arg5;
+	for (s = 0; s < s_nctl; s++) {
+		w = PyList_GetItem(v, s);
+		if (w == NULL || !PyList_Check(w) ||
+					PyList_Size(w) != t_nctl) {
+			PyErr_BadArgument();
+			return NULL;
+		}
+		for (t = 0; t < t_nctl; t++) {
+			pt = PyList_GetItem(w, t);
+			if (!PyArg_GetDoubleArray(pt, 1, 0, ncoords, pnext))
+				return NULL;
+			pnext += ncoords;
+		}
+	}
+	s_byte_stride = sizeof(double) * ncoords;
+	t_byte_stride = s_byte_stride * s_nctl;
+	nurbssurface( arg1 , arg2 , arg3 , arg4 ,
+		s_byte_stride , t_byte_stride , arg5 , arg6 , arg7 , arg8 );
+	PyMem_DEL(arg2);
+	PyMem_DEL(arg4);
+	PyMem_DEL(arg5);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* nurbscurve(knots, ctlpoints, order, type).
+   The length of ctlpoints is len(knots)-order. */
+
+%nurbscurve
+
+static PyObject *
+gl_nurbscurve(self, args)
+	PyObject *self;
+	PyObject *args;
+{
+	long arg1 ;
+	double * arg2 ;
+	long arg3 ;
+	double * arg4 ;
+	long arg5 ;
+	long arg6 ;
+	int ncoords, npoints;
+	int i;
+	PyObject *v;
+	double *pnext;
+	if (!PyArg_GetLongArraySize(args, 4, 0, &arg1))
+		return NULL;
+	if ((arg2 = PyMem_NEW(double, arg1 )) == NULL) {
+		return PyErr_NoMemory();
+	}
+	if (!PyArg_GetDoubleArray(args, 4, 0, arg1 , arg2))
+		return NULL;
+	if (!PyArg_GetLong(args, 4, 2, &arg5))
+		return NULL;
+	if (!PyArg_GetLong(args, 4, 3, &arg6))
+		return NULL;
+	if (arg6 == N_ST)
+		ncoords = 2;
+	else if (arg6 == N_STW)
+		ncoords = 3;
+	else {
+		PyErr_BadArgument();
+		return NULL;
+	}
+	npoints = arg1 - arg5;
+	if (!PyArg_GetObject(args, 4, 1, &v))
+		return NULL;
+	if (!PyList_Check(v) || PyList_Size(v) != npoints) {
+		PyErr_BadArgument();
+		return NULL;
+	}
+	if ((arg4 = PyMem_NEW(double, npoints*ncoords )) == NULL) {
+		return PyErr_NoMemory();
+	}
+	pnext = arg4;
+	for (i = 0; i < npoints; i++) {
+		if (!PyArg_GetDoubleArray(PyList_GetItem(v, i), 1, 0, ncoords, pnext))
+			return NULL;
+		pnext += ncoords;
+	}
+	arg3 = (sizeof(double)) * ncoords;
+	nurbscurve( arg1 , arg2 , arg3 , arg4 , arg5 , arg6 );
+	PyMem_DEL(arg2);
+	PyMem_DEL(arg4);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* pwlcurve(points, type).
+   Points is a list of points. Type must be N_ST. */
+
+%pwlcurve
+
+static PyObject *
+gl_pwlcurve(self, args)
+	PyObject *self;
+	PyObject *args;
+{
+	PyObject *v;
+	long type;
+	double *data, *pnext;
+	long npoints, ncoords;
+	int i;
+	if (!PyArg_GetObject(args, 2, 0, &v))
+		return NULL;
+	if (!PyArg_GetLong(args, 2, 1, &type))
+		return NULL;
+	if (!PyList_Check(v)) {
+		PyErr_BadArgument();
+		return NULL;
+	}
+	npoints = PyList_Size(v);
+	if (type == N_ST)
+		ncoords = 2;
+	else {
+		PyErr_BadArgument();
+		return NULL;
+	}
+	if ((data = PyMem_NEW(double, npoints*ncoords)) == NULL) {
+		return PyErr_NoMemory();
+	}
+	pnext = data;
+	for (i = 0; i < npoints; i++) {
+		if (!PyArg_GetDoubleArray(PyList_GetItem(v, i), 1, 0, ncoords, pnext))
+			return NULL;
+		pnext += ncoords;
+	}
+	pwlcurve(npoints, data, sizeof(double)*ncoords, type);
+	PyMem_DEL(data);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+
+/* Picking and Selecting */
+
+static short *pickbuffer = NULL;
+static long pickbuffersize;
+
+static PyObject *
+pick_select(args, func)
+	PyObject *args;
+	void (*func)();
+{
+	if (!PyArg_GetLong(args, 1, 0, &pickbuffersize))
+		return NULL;
+	if (pickbuffer != NULL) {
+		PyErr_SetString(PyExc_RuntimeError,
+			"pick/gselect: already picking/selecting");
+		return NULL;
+	}
+	if ((pickbuffer = PyMem_NEW(short, pickbuffersize)) == NULL) {
+		return PyErr_NoMemory();
+	}
+	(*func)(pickbuffer, pickbuffersize);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+endpick_select(args, func)
+	PyObject *args;
+	long (*func)();
+{
+	PyObject *v, *w;
+	int i, nhits, n;
+	if (!PyArg_NoArgs(args))
+		return NULL;
+	if (pickbuffer == NULL) {
+		PyErr_SetString(PyExc_RuntimeError,
+			"endpick/endselect: not in pick/select mode");
+		return NULL;
+	}
+	nhits = (*func)(pickbuffer);
+	if (nhits < 0) {
+		nhits = -nhits; /* How to report buffer overflow otherwise? */
+	}
+	/* Scan the buffer to see how many integers */
+	n = 0;
+	for (; nhits > 0; nhits--) {
+		n += 1 + pickbuffer[n];
+	}
+	v = PyList_New(n);
+	if (v == NULL)
+		return NULL;
+	/* XXX Could do it nicer and interpret the data structure here,
+	   returning a list of lists. But this can be done in Python... */
+	for (i = 0; i < n; i++) {
+		w = PyInt_FromLong((long)pickbuffer[i]);
+		if (w == NULL) {
+			Py_DECREF(v);
+			return NULL;
+		}
+		PyList_SetItem(v, i, w);
+	}
+	PyMem_DEL(pickbuffer);
+	pickbuffer = NULL;
+	return v;
+}
+
+extern void pick(), gselect();
+extern long endpick(), endselect();
+
+%pick
+static PyObject *gl_pick(self, args) PyObject *self, *args; {
+	return pick_select(args, pick);
+}
+
+%endpick
+static PyObject *gl_endpick(self, args) PyObject *self, *args; {
+	return endpick_select(args, endpick);
+}
+
+%gselect
+static PyObject *gl_gselect(self, args) PyObject *self, *args; {
+	return pick_select(args, gselect);
+}
+
+%endselect
+static PyObject *gl_endselect(self, args) PyObject *self, *args; {
+	return endpick_select(args, endselect);
+}
+
+
+/* XXX The generator botches this one.  Here's a quick hack to fix it. */
+
+/* XXX The generator botches this one.  Here's a quick hack to fix it. */
+
+% getmatrix float r[16]
+
+static PyObject *
+gl_getmatrix(self, args)
+	PyObject *self;
+	PyObject *args;
+{
+	Matrix arg1;
+	PyObject *v, *w;
+	int i, j;
+	getmatrix( arg1 );
+	v = PyList_New(16);
+	if (v == NULL) {
+		return PyErr_NoMemory();
+	}
+	for (i = 0; i < 4; i++) for (j = 0; j < 4; j++) {
+		w = mknewfloatobject(arg1[i][j]);
+		if (w == NULL) {
+			Py_DECREF(v);
+			return NULL;
+		}
+		PyList_SetItem(v, i*4+j, w);
+	}
+	return v;
+}
+
+/* Here's an alternate version that returns a 4x4 matrix instead of
+   a vector.  Unfortunately it is incompatible with loadmatrix and
+   multmatrix... */
+
+% altgetmatrix float r[4][4]
+
+static PyObject *
+gl_altgetmatrix(self, args)
+	PyObject *self;
+	PyObject *args;
+{
+	Matrix arg1;
+	PyObject *v, *w;
+	int i, j;
+	getmatrix( arg1 );
+	v = PyList_New(4);
+	if (v == NULL) {
+		return NULL;
+	}
+	for (i = 0; i < 4; i++) {
+		w = PyList_New(4);
+		if (w == NULL) {
+			Py_DECREF(v);
+			return NULL;
+		}
+		PyList_SetItem(v, i, w);
+	}
+	for (i = 0; i < 4; i++) {
+		for (j = 0; j < 4; j++) {
+			w = mknewfloatobject(arg1[i][j]);
+			if (w == NULL) {
+				Py_DECREF(v);
+				return NULL;
+			}
+			PyList_SetItem(PyList_GetItem(v, i), j, w);
+		}
+	}
+	return v;
+}
+
+% lrectwrite
+
+static PyObject *
+gl_lrectwrite(self, args)
+	PyObject *self;
+	PyObject *args;
+{
+	short x1 ;
+	short y1 ;
+	short x2 ;
+	short y2 ;
+	string parray ;
+	PyObject *s;
+#if 0
+	int pixcount;
+#endif
+	if (!PyArg_GetShort(args, 5, 0, &x1))
+		return NULL;
+	if (!PyArg_GetShort(args, 5, 1, &y1))
+		return NULL;
+	if (!PyArg_GetShort(args, 5, 2, &x2))
+		return NULL;
+	if (!PyArg_GetShort(args, 5, 3, &y2))
+		return NULL;
+	if (!PyArg_GetString(args, 5, 4, &parray))
+		return NULL;
+	if (!PyArg_GetObject(args, 5, 4, &s))
+		return NULL;
+#if 0
+/* Don't check this, it breaks experiments with pixmode(PM_SIZE, ...) */
+	pixcount = (long)(x2+1-x1) * (long)(y2+1-y1);
+	if (!PyString_Check(s) || PyString_Size(s) != pixcount*sizeof(long)) {
+		PyErr_SetString(PyExc_RuntimeError,
+			   "string arg to lrectwrite has wrong size");
+		return NULL;
+	}
+#endif
+	lrectwrite( x1 , y1 , x2 , y2 , (unsigned long *) parray );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+% lrectread
+
+static PyObject *
+gl_lrectread(self, args)
+	PyObject *self;
+	PyObject *args;
+{
+	short x1 ;
+	short y1 ;
+	short x2 ;
+	short y2 ;
+	PyObject *parray;
+	int pixcount;
+	if (!PyArg_GetShort(args, 4, 0, &x1))
+		return NULL;
+	if (!PyArg_GetShort(args, 4, 1, &y1))
+		return NULL;
+	if (!PyArg_GetShort(args, 4, 2, &x2))
+		return NULL;
+	if (!PyArg_GetShort(args, 4, 3, &y2))
+		return NULL;
+	pixcount = (long)(x2+1-x1) * (long)(y2+1-y1);
+	parray = PyString_FromStringAndSize((char *)NULL, pixcount*sizeof(long));
+	if (parray == NULL)
+		return NULL; /* No memory */
+	lrectread(x1, y1, x2, y2, (unsigned long *) PyString_AsString(parray));
+	return parray;
+}
+
+% readdisplay
+
+static PyObject *
+gl_readdisplay(self, args)
+	PyObject *self;
+        PyObject *args;
+{
+        short x1, y1, x2, y2;
+	unsigned long *parray, hints;
+	long size, size_ret;
+	PyObject *rv;
+
+	if ( !PyArg_Parse(args, "hhhhl", &x1, &y1, &x2, &y2, &hints) )
+	  return 0;
+	size = (long)(x2+1-x1) * (long)(y2+1-y1);
+	rv = PyString_FromStringAndSize((char *)NULL, size*sizeof(long));
+	if ( rv == NULL )
+	  return NULL;
+	parray = (unsigned long *)PyString_AsString(rv);
+	size_ret = readdisplay(x1, y1, x2, y2, parray, hints);
+	if ( size_ret != size ) {
+	    printf("gl_readdisplay: got %ld pixels, expected %ld\n",
+		   size_ret, size);
+	    PyErr_SetString(PyExc_RuntimeError, "readdisplay returned unexpected length");
+	    return NULL;
+	}
+	return rv;
+}
+
+/* Desperately needed, here are tools to compress and decompress
+   the data manipulated by lrectread/lrectwrite.
+
+   gl.packrect(width, height, packfactor, bigdata) --> smalldata
+		makes 'bigdata' 4*(packfactor**2) times smaller by:
+		- turning it into B/W (a factor 4)
+		- replacing squares of size pacfactor by one
+		  representative
+
+   gl.unpackrect(width, height, packfactor, smalldata) --> bigdata
+		is the inverse; the numeric arguments must be *the same*.
+
+   Both work best if width and height are multiples of packfactor
+   (in fact unpackrect will leave garbage bytes).
+*/
+
+% packrect
+
+static PyObject *
+gl_packrect(self, args)
+	PyObject *self;
+	PyObject *args;
+{
+	long width, height, packfactor;
+	char *s;
+	PyObject *unpacked, *packed;
+	int pixcount, packedcount, x, y, r, g, b;
+	unsigned long pixel;
+	unsigned char *p;
+	unsigned long *parray;
+	if (!PyArg_GetLong(args, 4, 0, &width))
+		return NULL;
+	if (!PyArg_GetLong(args, 4, 1, &height))
+		return NULL;
+	if (!PyArg_GetLong(args, 4, 2, &packfactor))
+		return NULL;
+	if (!PyArg_GetString(args, 4, 3, &s)) /* For type checking only */
+		return NULL;
+	if (!PyArg_GetObject(args, 4, 3, &unpacked))
+		return NULL;
+	if (width <= 0 || height <= 0 || packfactor <= 0) {
+		PyErr_SetString(PyExc_RuntimeError, "packrect args must be > 0");
+		return NULL;
+	}
+	pixcount = width*height;
+	packedcount = ((width+packfactor-1)/packfactor) *
+		((height+packfactor-1)/packfactor);
+	if (PyString_Size(unpacked) != pixcount*sizeof(long)) {
+		PyErr_SetString(PyExc_RuntimeError,
+			   "string arg to packrect has wrong size");
+		return NULL;
+	}
+	packed = PyString_FromStringAndSize((char *)NULL, packedcount);
+	if (packed == NULL)
+		return NULL;
+	parray = (unsigned long *) PyString_AsString(unpacked);
+	p = (unsigned char *) PyString_AsString(packed);
+	for (y = 0; y < height; y += packfactor, parray += packfactor*width) {
+		for (x = 0; x < width; x += packfactor) {
+			pixel = parray[x];
+			r = pixel & 0xff;
+			g = (pixel >> 8) & 0xff;
+			b = (pixel >> 16) & 0xff;
+			*p++ = (30*r+59*g+11*b) / 100;
+		}
+	}
+	return packed;
+}
+
+% unpackrect
+
+static unsigned long unpacktab[256];
+static int unpacktab_inited = 0;
+
+static PyObject *
+gl_unpackrect(self, args)
+	PyObject *self;
+	PyObject *args;
+{
+	long width, height, packfactor;
+	char *s;
+	PyObject *unpacked, *packed;
+	int pixcount, packedcount;
+	register unsigned char *p;
+	register unsigned long *parray;
+	if (!unpacktab_inited) {
+		register int white;
+		for (white = 256; --white >= 0; )
+			unpacktab[white] = white * 0x010101L;
+		unpacktab_inited++;
+	}
+	if (!PyArg_GetLong(args, 4, 0, &width))
+		return NULL;
+	if (!PyArg_GetLong(args, 4, 1, &height))
+		return NULL;
+	if (!PyArg_GetLong(args, 4, 2, &packfactor))
+		return NULL;
+	if (!PyArg_GetString(args, 4, 3, &s)) /* For type checking only */
+		return NULL;
+	if (!PyArg_GetObject(args, 4, 3, &packed))
+		return NULL;
+	if (width <= 0 || height <= 0 || packfactor <= 0) {
+		PyErr_SetString(PyExc_RuntimeError, "packrect args must be > 0");
+		return NULL;
+	}
+	pixcount = width*height;
+	packedcount = ((width+packfactor-1)/packfactor) *
+		((height+packfactor-1)/packfactor);
+	if (PyString_Size(packed) != packedcount) {
+		PyErr_SetString(PyExc_RuntimeError,
+			   "string arg to unpackrect has wrong size");
+		return NULL;
+	}
+	unpacked = PyString_FromStringAndSize((char *)NULL, pixcount*sizeof(long));
+	if (unpacked == NULL)
+		return NULL;
+	parray = (unsigned long *) PyString_AsString(unpacked);
+	p = (unsigned char *) PyString_AsString(packed);
+	if (packfactor == 1 && width*height > 0) {
+		/* Just expand bytes to longs */
+		register int x = width * height;
+		do {
+			*parray++ = unpacktab[*p++];
+		} while (--x >= 0);
+	}
+	else {
+		register int y;
+		for (y = 0; y < height-packfactor+1;
+		     y += packfactor, parray += packfactor*width) {
+			register int x;
+			for (x = 0; x < width-packfactor+1; x += packfactor) {
+				register unsigned long pixel = unpacktab[*p++];
+				register int i;
+				for (i = packfactor*width; (i-=width) >= 0;) {
+					register int j;
+					for (j = packfactor; --j >= 0; )
+						parray[i+x+j] = pixel;
+				}
+			}
+		}
+	}
+	return unpacked;
+}
+
+% gversion
+static PyObject *
+gl_gversion(self, args)
+	PyObject *self;
+	PyObject *args;
+{
+	char buf[20];
+	gversion(buf);
+	return PyString_FromString(buf);
+}
+
+
+/* void clear - Manual because of clash with termcap */
+%clear
+static PyObject *
+gl_clear(self, args)
+	PyObject *self;
+	PyObject *args;
+{
+	__GLclear( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* End of manually written stubs */
+
+%%
+
+long 	getshade
+if !solaris	void 	devport 	short s long s
+void 	rdr2i 		long s long s
+void	rectfs 		short s short s short s short s
+void 	rects 		short s short s short s short s
+void 	rmv2i 		long s long s
+void	noport
+void	popviewport
+void	clearhitcode
+void	closeobj
+void	cursoff
+void	curson
+void	doublebuffer
+void 	finish
+void	gconfig
+void	ginit
+void	greset
+void	multimap
+void	onemap
+void	popattributes
+void	popmatrix
+void	pushattributes
+void	pushmatrix
+void	pushviewport
+void	qreset
+void	RGBmode
+void	singlebuffer
+void	swapbuffers
+void	gsync
+void	gflush
+void	tpon
+void	tpoff
+void	clkon
+void	clkoff
+void	ringbell
+#void	callfunc
+void	gbegin
+void	textinit
+void	initnames
+void	pclos
+void	popname
+if !solaris	void	spclos
+void	zclear
+void	screenspace
+void	reshapeviewport
+void	winpush
+void	winpop
+void	foreground
+void	endfullscrn
+if !solaris	void	endpupmode
+void	fullscrn
+if !solaris	void	pupmode
+void	winconstraints
+void	pagecolor 	short s
+void	textcolor 	short s
+void 	color 	  	short s
+void	curveit		short s
+void	font		short s
+void 	linewidth	short s
+void    setlinestyle	short s
+void	setmap		short s
+void	swapinterval	short s
+void	writemask	short s
+if !solaris	void	textwritemask	short s
+void	qdevice		short s
+void	unqdevice	short s
+void	curvebasis	short s
+void	curveprecision	short s
+void	loadname	short s
+void	passthrough	short s
+void	pushname	short s
+void	setmonitor	short s
+if !solaris	void	setshade	short s
+void	setpattern	short s
+if !solaris	void	pagewritemask	short s
+#
+void	callobj		long s
+void	delobj		long s
+void 	editobj		long s
+void	makeobj		long s
+void	maketag		long s
+void	chunksize	long s
+void	compactify	long s
+void	deltag		long s
+void	lsrepeat	long s
+void	objinsert	long s
+void 	objreplace	long s
+void	winclose	long s
+void	blanktime	long s
+void 	freepup		long s
+# This is not in the library!?
+###void	pupcolor	long s
+#
+void	backbuffer	long s
+void 	frontbuffer	long s
+if !solaris	void	lsbackup	long s
+void	resetls		long s
+void	lampon		long s
+void	lampoff		long s
+void	setbell		long s
+void	blankscreen	long s
+void 	depthcue	long s
+void	zbuffer		long s
+void	backface	long s
+#
+void 	cmov2i		long s long s
+void 	draw2i		long s long s
+void	move2i		long s long s
+void	pnt2i		long s long s
+void 	patchbasis	long s long s
+void 	patchprecision	long s long s
+void	pdr2i		long s long s
+void	pmv2i		long s long s
+void	rpdr2i		long s long s
+void	rpmv2i		long s long s
+void	xfpt2i		long s long s
+void	objdelete	long s long s
+void	patchcurves	long s long s
+void	minsize		long s long s
+void 	maxsize		long s long s
+void	keepaspect	long s long s
+void	prefsize	long s long s
+void	stepunit	long s long s
+void 	fudge		long s long s
+void 	winmove		long s long s
+#
+void 	attachcursor	short s short s
+void 	deflinestyle	short s short s
+void 	noise		short s short s
+void 	picksize	short s short s
+void 	qenter		short s short s
+void 	setdepth	short s short s
+void 	cmov2s		short s short s
+void 	draw2s		short s	short s
+void 	move2s		short s short s
+void 	pdr2s		short s short s
+void 	pmv2s		short s short s
+void 	pnt2s		short s short s
+void 	rdr2s		short s short s
+void 	rmv2s		short s short s
+void 	rpdr2s		short s short s
+void 	rpmv2s		short s short s
+void 	xfpt2s		short s short s
+#
+void cmov2		float s float s
+void draw2		float s float s
+void move2		float s float s
+void pnt2		float s float s
+void pdr2		float s float s
+void pmv2		float s float s
+void rdr2		float s float s
+void rmv2		float s float s
+void rpdr2		float s float s
+void rpmv2		float s float s
+void xfpt2		float s float s
+#
+void loadmatrix		float s[4*4]
+# Really [4][4]
+void multmatrix		float s[4*4]
+# Really [4][4]
+void crv			float s[3*4]
+# Really [4][3]
+void rcrv			float s[4*4]
+# Really [4][4]
+#
+# Methods that have strings.  
+#
+void addtopup		long s char *s long s
+void charstr		char *s
+void getport	 	char *s
+long strwidth		char *s
+long winopen		char *s
+void wintitle		char *s
+#
+# Methods that have 1 long (# of elements) and an array 
+#
+void polf		long s float s[3*arg1]
+void polf2		long s float s[2*arg1]
+void poly		long s float s[3*arg1]
+void poly2		long s float s[2*arg1]
+void crvn		long s float s[3*arg1]
+void rcrvn		long s float s[4*arg1]
+#
+void polf2i		long s long s[2*arg1]
+void polfi		long s long s[3*arg1]
+void poly2i		long s long s[2*arg1]
+void polyi		long s long s[3*arg1]
+#
+void polf2s		long s short s[2*arg1]
+void polfs		long s short s[3*arg1]
+void polys		long s short s[3*arg1]
+void poly2s		long s short s[2*arg1]
+#
+void defcursor		short s u_short s[128]
+# Is this useful?
+void writepixels	short s u_short s[arg1]
+# Should be unsigned short...
+void defbasis		long s float s[4*4]
+if !solaris	void gewrite		short s short s[arg1]
+#
+void rotate		short s char s
+# This is not in the library!?
+###void setbutton		short s char s
+void rot		float s char s
+#
+void circfi		long s long s long s
+void circi		long s long s long s
+void cmovi		long s long s long s
+void drawi		long s long s long s
+void movei		long s long s long s
+void pnti 		long s long s long s
+void newtag		long s long s long s
+void pdri  		long s long s long s
+void pmvi  		long s long s long s
+void rdri  		long s long s long s
+void rmvi  		long s long s long s
+void rpdri 		long s long s long s
+void rpmvi 		long s long s long s
+void xfpti 		long s long s long s
+#
+void circ		float s float s float s
+void circf		float s float s float s
+void cmov		float s float s float s
+void draw		float s float s float s
+void move		float s float s float s
+void pnt		float s float s float s
+void scale		float s float s float s
+void translate		float s float s float s
+void pdr		float s float s float s
+void pmv		float s float s float s
+void rdr		float s float s float s
+void rmv		float s float s float s
+void rpdr		float s float s float s
+void rpmv		float s float s float s
+void xfpt		float s float s float s
+#
+void RGBcolor		short s short s short s
+void RGBwritemask	short s short s short s
+void setcursor		short s short s short s
+void tie		short s short s short s
+void circfs		short s short s short s
+void circs		short s short s short s
+void cmovs		short s short s short s
+void draws		short s short s short s
+void moves		short s short s short s
+void pdrs		short s short s short s
+void pmvs		short s short s short s
+void pnts		short s short s short s
+void rdrs		short s short s short s
+void rmvs		short s short s short s
+void rpdrs		short s short s short s
+void rpmvs		short s short s short s
+void xfpts		short s short s short s
+void curorigin		short s short s short s
+void cyclemap		short s short s short s
+#
+void patch		float s[4*4] float s[4*4] float s[4*4]
+void splf		long s float s[3*arg1] u_short s[arg1]
+void splf2		long s float s[2*arg1] u_short s[arg1]
+void splfi		long s long s[3*arg1] u_short s[arg1]
+void splf2i		long s long s[2*arg1] u_short s[arg1]
+void splfs		long s short s[3*arg1] u_short s[arg1]
+void splf2s		long s short s[2*arg1] u_short s[arg1]
+###void defpattern		short s short s u_short s[arg2*arg2/16]
+#
+void rpatch		float s[4*4] float s[4*4] float s[4*4] float s[4*4]
+#
+# routines that send 4 floats
+#
+void ortho2		float s float s float s float s
+void rect		float s float s float s float s
+void rectf		float s float s float s float s
+void xfpt4		float s float s float s float s
+#
+void textport		short s short s short s short s
+void mapcolor		short s short s short s short s
+void scrmask		short s short s short s short s
+void setvaluator	short s short s short s short s
+void viewport		short s short s short s short s
+void shaderange		short s short s short s short s
+void xfpt4s		short s short s short s short s
+void rectfi		long s long s long s long s
+void recti		long s long s long s long s
+void xfpt4i		long s long s long s long s
+void prefposition	long s long s long s long s
+#
+void arc		float s float s float s short s short s
+void arcf		float s float s float s short s short s
+void arcfi		long s long s long s short s short s
+void arci		long s long s long s short s short s
+#
+void bbox2		short s short s float s float s float s float s
+void bbox2i		short s short s long s long s long s long s
+void bbox2s		short s short s short s short s short s short s
+void blink		short s short s short s short s short s
+void ortho		float s float s float s float s float s float s
+void window		float s float s float s float s float s float s
+void lookat		float s float s float s float s float s float s short s
+#
+void perspective	short s float s float s float s
+void polarview		float s short s short s short s
+# XXX getichararray not supported
+#void writeRGB		short s char s[arg1] char s[arg1] char s[arg1]
+#
+void arcfs		short s short s short s short s short s
+void arcs		short s short s short s short s short s
+void rectcopy		short s short s short s short s short s short s
+if !solaris	void RGBcursor		short s short s short s short s short s short s short s
+#
+long getbutton		short s
+long getcmmode
+long getlsbackup
+long getresetls
+long getdcm
+long getzbuffer
+long ismex
+long isobj		long s
+long isqueued		short s
+long istag		long s
+#
+long genobj
+long gentag
+long getbuffer
+long getcolor
+long getdisplaymode
+long getfont
+long getheight
+long gethitcode
+long getlstyle
+long getlwidth
+long getmap
+long getplanes
+long getwritemask
+long qtest
+long getlsrepeat
+long getmonitor
+long getopenobj
+long getpattern
+long winget
+long winattach
+long getothermonitor
+long newpup
+#
+long getvaluator	short s
+void winset		long s
+long dopup		long s
+void getdepth		short r short r
+void getcpos		short r short r
+void getsize		long r long r
+void getorigin		long r long r
+void getviewport	short r short r short r short r
+if !solaris	void gettp		short r short r short r short r
+void getgpos		float r float r float r float r
+void winposition	long s long s long s long s
+void gRGBcolor		short r short r short r
+void gRGBmask		short r short r short r
+void getscrmask	short r short r short r short r
+###void gRGBcursor	short r short r short r short r short r short r short r short r
+void getmcolor		short s short r short r short r
+void mapw		long s short s short s float r float r float r float r float r float r
+void mapw2		long s short s short s float r float r
+###void defrasterfont	short s short s short s Fontchar s[arg3] short s short s[4*arg5]
+###long qread		short r
+void getcursor		short r u_short r u_short r long r
+#
+#   For these we receive arrays of stuff
+#
+###void getdev 		long s short s[arg1] short r[arg1]
+#XXX not generated correctly yet
+#void getmatrix		float r[16]
+###long readpixels		short s short r[retval]
+###long readRGB		short s char r[retval] char r[retval] char r[retval]
+###long blkqread		short s short r[arg1]
+#
+#   New 4D routines
+#
+void cmode
+void concave		long s
+void curstype		long s
+void drawmode		long s
+void gammaramp		short s[256] short s[256] short s[256]
+long getbackface
+long getdescender
+long getdrawmode
+long getmmode
+long getsm
+long getvideo		long s
+void imakebackground
+void lmbind		short s short s
+void lmdef		long s long s long s float s[arg3]
+void mmode		long s
+void normal		float s[3]
+void overlay		long s
+void RGBrange		short s short s short s short s short s short s short s short s
+if !solaris	void setvideo 		long s long s
+void shademodel		long s
+void underlay		long s
+#
+# New Personal Iris/GT Routines
+#
+void bgnclosedline
+void bgnline
+void bgnpoint
+void bgnpolygon
+void bgnsurface
+void bgntmesh
+void bgntrim
+void endclosedline
+void endline
+void endpoint
+void endpolygon
+void endsurface
+void endtmesh
+void endtrim
+void blendfunction	long s long s
+void c3f		float s[3]
+void c3i		long  s[3]
+void c3s		short s[3]
+void c4f		float s[4]
+void c4i		long  s[4]
+void c4s		short s[4]
+void colorf		float s
+void cpack		long s
+void czclear		long s long s
+void dglclose		long s
+long dglopen		char *s long s
+long getgdesc		long s
+void getnurbsproperty	long s float r
+void glcompat		long s long s
+void iconsize 		long s long s
+void icontitle		char *s
+void lRGBrange		short s short s short s short s short s short s long s long s
+void linesmooth		long s
+void lmcolor		long s
+void logicop		long s
+###long lrectread	 	short s short s short s short s long r[retval]
+###void lrectwrite		short s short s short s short s long s[(arg2-arg1+1)*(arg4-arg3+1)]
+### Now manual, with string last arg
+###long rectread	 	short s short s short s short s short r[retval]
+###void rectwrite		short s short s short s short s short s[(arg2-arg1+1)*(arg4-arg3+1)]
+void lsetdepth		long s long s
+void lshaderange	short s short s long s long s
+void n3f		float s[3]
+void noborder
+void pntsmooth		long s
+void readsource		long s
+void rectzoom		float s float s
+void sbox		float s float s float s float s
+void sboxi		long s long s long s long s
+void sboxs		short s short s short s short s
+void sboxf		float s float s float s float s
+void sboxfi		long s long s long s long s
+void sboxfs		short s short s short s short s
+void setnurbsproperty	long s float s
+void setpup 		long s long s long s
+void smoothline		long s
+void subpixel		long s
+void swaptmesh
+long swinopen		long s
+void v2f		float s[2]
+void v2i		long  s[2]
+void v2s		short s[2]
+void v3f		float s[3]
+void v3i		long  s[3]
+void v3s		short s[3]
+void v4f		float s[4]
+void v4i		long  s[4]
+void v4s		short s[4]
+void videocmd		long s
+long windepth		long s
+void wmpack		long s
+void zdraw		long s
+void zfunction		long s
+void zsource		long s
+void zwritemask		long s
+#
+#   uses doubles
+#
+void v2d		double s[2]
+void v3d		double s[3]
+void v4d		double s[4]
+#
+# Why isn't this here?
+#
+void pixmode		long s long s
+#
+# New in IRIX 4.0
+#
+long qgetfd
+void dither		long s

Added: vendor/Python/current/Modules/datetimemodule.c
===================================================================
--- vendor/Python/current/Modules/datetimemodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/datetimemodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,4988 @@
+/*  C implementation for the date/time type documented at
+ *  http://www.zope.org/Members/fdrake/DateTimeWiki/FrontPage
+ */
+
+#include "Python.h"
+#include "modsupport.h"
+#include "structmember.h"
+
+#include <time.h>
+
+#include "timefuncs.h"
+
+/* Differentiate between building the core module and building extension
+ * modules.
+ */
+#define Py_BUILD_CORE
+#include "datetime.h"
+#undef Py_BUILD_CORE
+
+/* We require that C int be at least 32 bits, and use int virtually
+ * everywhere.  In just a few cases we use a temp long, where a Python
+ * API returns a C long.  In such cases, we have to ensure that the
+ * final result fits in a C int (this can be an issue on 64-bit boxes).
+ */
+#if SIZEOF_INT < 4
+#	error "datetime.c requires that C int have at least 32 bits"
+#endif
+
+#define MINYEAR 1
+#define MAXYEAR 9999
+
+/* Nine decimal digits is easy to communicate, and leaves enough room
+ * so that two delta days can be added w/o fear of overflowing a signed
+ * 32-bit int, and with plenty of room left over to absorb any possible
+ * carries from adding seconds.
+ */
+#define MAX_DELTA_DAYS 999999999
+
+/* Rename the long macros in datetime.h to more reasonable short names. */
+#define GET_YEAR		PyDateTime_GET_YEAR
+#define GET_MONTH		PyDateTime_GET_MONTH
+#define GET_DAY			PyDateTime_GET_DAY
+#define DATE_GET_HOUR		PyDateTime_DATE_GET_HOUR
+#define DATE_GET_MINUTE		PyDateTime_DATE_GET_MINUTE
+#define DATE_GET_SECOND		PyDateTime_DATE_GET_SECOND
+#define DATE_GET_MICROSECOND	PyDateTime_DATE_GET_MICROSECOND
+
+/* Date accessors for date and datetime. */
+#define SET_YEAR(o, v)		(((o)->data[0] = ((v) & 0xff00) >> 8), \
+                                 ((o)->data[1] = ((v) & 0x00ff)))
+#define SET_MONTH(o, v)		(PyDateTime_GET_MONTH(o) = (v))
+#define SET_DAY(o, v)		(PyDateTime_GET_DAY(o) = (v))
+
+/* Date/Time accessors for datetime. */
+#define DATE_SET_HOUR(o, v)	(PyDateTime_DATE_GET_HOUR(o) = (v))
+#define DATE_SET_MINUTE(o, v)	(PyDateTime_DATE_GET_MINUTE(o) = (v))
+#define DATE_SET_SECOND(o, v)	(PyDateTime_DATE_GET_SECOND(o) = (v))
+#define DATE_SET_MICROSECOND(o, v)	\
+	(((o)->data[7] = ((v) & 0xff0000) >> 16), \
+         ((o)->data[8] = ((v) & 0x00ff00) >> 8), \
+         ((o)->data[9] = ((v) & 0x0000ff)))
+
+/* Time accessors for time. */
+#define TIME_GET_HOUR		PyDateTime_TIME_GET_HOUR
+#define TIME_GET_MINUTE		PyDateTime_TIME_GET_MINUTE
+#define TIME_GET_SECOND		PyDateTime_TIME_GET_SECOND
+#define TIME_GET_MICROSECOND	PyDateTime_TIME_GET_MICROSECOND
+#define TIME_SET_HOUR(o, v)	(PyDateTime_TIME_GET_HOUR(o) = (v))
+#define TIME_SET_MINUTE(o, v)	(PyDateTime_TIME_GET_MINUTE(o) = (v))
+#define TIME_SET_SECOND(o, v)	(PyDateTime_TIME_GET_SECOND(o) = (v))
+#define TIME_SET_MICROSECOND(o, v)	\
+	(((o)->data[3] = ((v) & 0xff0000) >> 16), \
+         ((o)->data[4] = ((v) & 0x00ff00) >> 8), \
+         ((o)->data[5] = ((v) & 0x0000ff)))
+
+/* Delta accessors for timedelta. */
+#define GET_TD_DAYS(o)		(((PyDateTime_Delta *)(o))->days)
+#define GET_TD_SECONDS(o)	(((PyDateTime_Delta *)(o))->seconds)
+#define GET_TD_MICROSECONDS(o)	(((PyDateTime_Delta *)(o))->microseconds)
+
+#define SET_TD_DAYS(o, v)	((o)->days = (v))
+#define SET_TD_SECONDS(o, v)	((o)->seconds = (v))
+#define SET_TD_MICROSECONDS(o, v) ((o)->microseconds = (v))
+
+/* p is a pointer to a time or a datetime object; HASTZINFO(p) returns
+ * p->hastzinfo.
+ */
+#define HASTZINFO(p)		(((_PyDateTime_BaseTZInfo *)(p))->hastzinfo)
+
+/* M is a char or int claiming to be a valid month.  The macro is equivalent
+ * to the two-sided Python test
+ *	1 <= M <= 12
+ */
+#define MONTH_IS_SANE(M) ((unsigned int)(M) - 1 < 12)
+
+/* Forward declarations. */
+static PyTypeObject PyDateTime_DateType;
+static PyTypeObject PyDateTime_DateTimeType;
+static PyTypeObject PyDateTime_DeltaType;
+static PyTypeObject PyDateTime_TimeType;
+static PyTypeObject PyDateTime_TZInfoType;
+
+/* ---------------------------------------------------------------------------
+ * Math utilities.
+ */
+
+/* k = i+j overflows iff k differs in sign from both inputs,
+ * iff k^i has sign bit set and k^j has sign bit set,
+ * iff (k^i)&(k^j) has sign bit set.
+ */
+#define SIGNED_ADD_OVERFLOWED(RESULT, I, J) \
+	((((RESULT) ^ (I)) & ((RESULT) ^ (J))) < 0)
+
+/* Compute Python divmod(x, y), returning the quotient and storing the
+ * remainder into *r.  The quotient is the floor of x/y, and that's
+ * the real point of this.  C will probably truncate instead (C99
+ * requires truncation; C89 left it implementation-defined).
+ * Simplification:  we *require* that y > 0 here.  That's appropriate
+ * for all the uses made of it.  This simplifies the code and makes
+ * the overflow case impossible (divmod(LONG_MIN, -1) is the only
+ * overflow case).
+ */
+static int
+divmod(int x, int y, int *r)
+{
+	int quo;
+
+	assert(y > 0);
+	quo = x / y;
+	*r = x - quo * y;
+	if (*r < 0) {
+		--quo;
+		*r += y;
+	}
+	assert(0 <= *r && *r < y);
+	return quo;
+}
+
+/* Round a double to the nearest long.  |x| must be small enough to fit
+ * in a C long; this is not checked.
+ */
+static long
+round_to_long(double x)
+{
+	if (x >= 0.0)
+		x = floor(x + 0.5);
+	else
+		x = ceil(x - 0.5);
+	return (long)x;
+}
+
+/* ---------------------------------------------------------------------------
+ * General calendrical helper functions
+ */
+
+/* For each month ordinal in 1..12, the number of days in that month,
+ * and the number of days before that month in the same year.  These
+ * are correct for non-leap years only.
+ */
+static int _days_in_month[] = {
+	0, /* unused; this vector uses 1-based indexing */
+	31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+};
+
+static int _days_before_month[] = {
+	0, /* unused; this vector uses 1-based indexing */
+	0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
+};
+
+/* year -> 1 if leap year, else 0. */
+static int
+is_leap(int year)
+{
+	/* Cast year to unsigned.  The result is the same either way, but
+	 * C can generate faster code for unsigned mod than for signed
+	 * mod (especially for % 4 -- a good compiler should just grab
+	 * the last 2 bits when the LHS is unsigned).
+	 */
+	const unsigned int ayear = (unsigned int)year;
+	return ayear % 4 == 0 && (ayear % 100 != 0 || ayear % 400 == 0);
+}
+
+/* year, month -> number of days in that month in that year */
+static int
+days_in_month(int year, int month)
+{
+	assert(month >= 1);
+	assert(month <= 12);
+	if (month == 2 && is_leap(year))
+		return 29;
+	else
+		return _days_in_month[month];
+}
+
+/* year, month -> number of days in year preceeding first day of month */
+static int
+days_before_month(int year, int month)
+{
+	int days;
+
+	assert(month >= 1);
+	assert(month <= 12);
+	days = _days_before_month[month];
+	if (month > 2 && is_leap(year))
+		++days;
+	return days;
+}
+
+/* year -> number of days before January 1st of year.  Remember that we
+ * start with year 1, so days_before_year(1) == 0.
+ */
+static int
+days_before_year(int year)
+{
+	int y = year - 1;
+	/* This is incorrect if year <= 0; we really want the floor
+	 * here.  But so long as MINYEAR is 1, the smallest year this
+	 * can see is 0 (this can happen in some normalization endcases),
+	 * so we'll just special-case that.
+	 */
+	assert (year >= 0);
+	if (y >= 0)
+		return y*365 + y/4 - y/100 + y/400;
+	else {
+		assert(y == -1);
+		return -366;
+	}
+}
+
+/* Number of days in 4, 100, and 400 year cycles.  That these have
+ * the correct values is asserted in the module init function.
+ */
+#define DI4Y	1461	/* days_before_year(5); days in 4 years */
+#define DI100Y	36524	/* days_before_year(101); days in 100 years */
+#define DI400Y	146097	/* days_before_year(401); days in 400 years  */
+
+/* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */
+static void
+ord_to_ymd(int ordinal, int *year, int *month, int *day)
+{
+	int n, n1, n4, n100, n400, leapyear, preceding;
+
+	/* ordinal is a 1-based index, starting at 1-Jan-1.  The pattern of
+	 * leap years repeats exactly every 400 years.  The basic strategy is
+	 * to find the closest 400-year boundary at or before ordinal, then
+	 * work with the offset from that boundary to ordinal.  Life is much
+	 * clearer if we subtract 1 from ordinal first -- then the values
+	 * of ordinal at 400-year boundaries are exactly those divisible
+	 * by DI400Y:
+	 *
+	 *    D  M   Y            n              n-1
+	 *    -- --- ----        ----------     ----------------
+	 *    31 Dec -400        -DI400Y       -DI400Y -1
+	 *     1 Jan -399         -DI400Y +1   -DI400Y      400-year boundary
+	 *    ...
+	 *    30 Dec  000        -1             -2
+	 *    31 Dec  000         0             -1
+	 *     1 Jan  001         1              0          400-year boundary
+	 *     2 Jan  001         2              1
+	 *     3 Jan  001         3              2
+	 *    ...
+	 *    31 Dec  400         DI400Y        DI400Y -1
+	 *     1 Jan  401         DI400Y +1     DI400Y      400-year boundary
+	 */
+	assert(ordinal >= 1);
+	--ordinal;
+	n400 = ordinal / DI400Y;
+	n = ordinal % DI400Y;
+	*year = n400 * 400 + 1;
+
+	/* Now n is the (non-negative) offset, in days, from January 1 of
+	 * year, to the desired date.  Now compute how many 100-year cycles
+	 * precede n.
+	 * Note that it's possible for n100 to equal 4!  In that case 4 full
+	 * 100-year cycles precede the desired day, which implies the
+	 * desired day is December 31 at the end of a 400-year cycle.
+	 */
+	n100 = n / DI100Y;
+	n = n % DI100Y;
+
+	/* Now compute how many 4-year cycles precede it. */
+	n4 = n / DI4Y;
+	n = n % DI4Y;
+
+	/* And now how many single years.  Again n1 can be 4, and again
+	 * meaning that the desired day is December 31 at the end of the
+	 * 4-year cycle.
+	 */
+	n1 = n / 365;
+	n = n % 365;
+
+	*year += n100 * 100 + n4 * 4 + n1;
+	if (n1 == 4 || n100 == 4) {
+		assert(n == 0);
+		*year -= 1;
+		*month = 12;
+		*day = 31;
+		return;
+	}
+
+	/* Now the year is correct, and n is the offset from January 1.  We
+	 * find the month via an estimate that's either exact or one too
+	 * large.
+	 */
+	leapyear = n1 == 3 && (n4 != 24 || n100 == 3);
+	assert(leapyear == is_leap(*year));
+	*month = (n + 50) >> 5;
+	preceding = (_days_before_month[*month] + (*month > 2 && leapyear));
+	if (preceding > n) {
+		/* estimate is too large */
+		*month -= 1;
+		preceding -= days_in_month(*year, *month);
+	}
+	n -= preceding;
+	assert(0 <= n);
+	assert(n < days_in_month(*year, *month));
+
+	*day = n + 1;
+}
+
+/* year, month, day -> ordinal, considering 01-Jan-0001 as day 1. */
+static int
+ymd_to_ord(int year, int month, int day)
+{
+	return days_before_year(year) + days_before_month(year, month) + day;
+}
+
+/* Day of week, where Monday==0, ..., Sunday==6.  1/1/1 was a Monday. */
+static int
+weekday(int year, int month, int day)
+{
+	return (ymd_to_ord(year, month, day) + 6) % 7;
+}
+
+/* Ordinal of the Monday starting week 1 of the ISO year.  Week 1 is the
+ * first calendar week containing a Thursday.
+ */
+static int
+iso_week1_monday(int year)
+{
+	int first_day = ymd_to_ord(year, 1, 1);	/* ord of 1/1 */
+	/* 0 if 1/1 is a Monday, 1 if a Tue, etc. */
+	int first_weekday = (first_day + 6) % 7;
+	/* ordinal of closest Monday at or before 1/1 */
+	int week1_monday  = first_day - first_weekday;
+
+	if (first_weekday > 3)	/* if 1/1 was Fri, Sat, Sun */
+		week1_monday += 7;
+	return week1_monday;
+}
+
+/* ---------------------------------------------------------------------------
+ * Range checkers.
+ */
+
+/* Check that -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS.  If so, return 0.
+ * If not, raise OverflowError and return -1.
+ */
+static int
+check_delta_day_range(int days)
+{
+	if (-MAX_DELTA_DAYS <= days && days <= MAX_DELTA_DAYS)
+		return 0;
+	PyErr_Format(PyExc_OverflowError,
+		     "days=%d; must have magnitude <= %d",
+		     days, MAX_DELTA_DAYS);
+	return -1;
+}
+
+/* Check that date arguments are in range.  Return 0 if they are.  If they
+ * aren't, raise ValueError and return -1.
+ */
+static int
+check_date_args(int year, int month, int day)
+{
+
+	if (year < MINYEAR || year > MAXYEAR) {
+		PyErr_SetString(PyExc_ValueError,
+				"year is out of range");
+		return -1;
+	}
+	if (month < 1 || month > 12) {
+		PyErr_SetString(PyExc_ValueError,
+				"month must be in 1..12");
+		return -1;
+	}
+	if (day < 1 || day > days_in_month(year, month)) {
+		PyErr_SetString(PyExc_ValueError,
+				"day is out of range for month");
+		return -1;
+	}
+	return 0;
+}
+
+/* Check that time arguments are in range.  Return 0 if they are.  If they
+ * aren't, raise ValueError and return -1.
+ */
+static int
+check_time_args(int h, int m, int s, int us)
+{
+	if (h < 0 || h > 23) {
+		PyErr_SetString(PyExc_ValueError,
+				"hour must be in 0..23");
+		return -1;
+	}
+	if (m < 0 || m > 59) {
+		PyErr_SetString(PyExc_ValueError,
+				"minute must be in 0..59");
+		return -1;
+	}
+	if (s < 0 || s > 59) {
+		PyErr_SetString(PyExc_ValueError,
+				"second must be in 0..59");
+		return -1;
+	}
+	if (us < 0 || us > 999999) {
+		PyErr_SetString(PyExc_ValueError,
+				"microsecond must be in 0..999999");
+		return -1;
+	}
+	return 0;
+}
+
+/* ---------------------------------------------------------------------------
+ * Normalization utilities.
+ */
+
+/* One step of a mixed-radix conversion.  A "hi" unit is equivalent to
+ * factor "lo" units.  factor must be > 0.  If *lo is less than 0, or
+ * at least factor, enough of *lo is converted into "hi" units so that
+ * 0 <= *lo < factor.  The input values must be such that int overflow
+ * is impossible.
+ */
+static void
+normalize_pair(int *hi, int *lo, int factor)
+{
+	assert(factor > 0);
+	assert(lo != hi);
+	if (*lo < 0 || *lo >= factor) {
+		const int num_hi = divmod(*lo, factor, lo);
+		const int new_hi = *hi + num_hi;
+		assert(! SIGNED_ADD_OVERFLOWED(new_hi, *hi, num_hi));
+		*hi = new_hi;
+	}
+	assert(0 <= *lo && *lo < factor);
+}
+
+/* Fiddle days (d), seconds (s), and microseconds (us) so that
+ * 	0 <= *s < 24*3600
+ * 	0 <= *us < 1000000
+ * The input values must be such that the internals don't overflow.
+ * The way this routine is used, we don't get close.
+ */
+static void
+normalize_d_s_us(int *d, int *s, int *us)
+{
+	if (*us < 0 || *us >= 1000000) {
+		normalize_pair(s, us, 1000000);
+		/* |s| can't be bigger than about
+		 * |original s| + |original us|/1000000 now.
+		 */
+
+	}
+	if (*s < 0 || *s >= 24*3600) {
+		normalize_pair(d, s, 24*3600);
+		/* |d| can't be bigger than about
+		 * |original d| +
+		 * (|original s| + |original us|/1000000) / (24*3600) now.
+		 */
+	}
+	assert(0 <= *s && *s < 24*3600);
+	assert(0 <= *us && *us < 1000000);
+}
+
+/* Fiddle years (y), months (m), and days (d) so that
+ * 	1 <= *m <= 12
+ * 	1 <= *d <= days_in_month(*y, *m)
+ * The input values must be such that the internals don't overflow.
+ * The way this routine is used, we don't get close.
+ */
+static void
+normalize_y_m_d(int *y, int *m, int *d)
+{
+	int dim;	/* # of days in month */
+
+	/* This gets muddy:  the proper range for day can't be determined
+	 * without knowing the correct month and year, but if day is, e.g.,
+	 * plus or minus a million, the current month and year values make
+	 * no sense (and may also be out of bounds themselves).
+	 * Saying 12 months == 1 year should be non-controversial.
+	 */
+	if (*m < 1 || *m > 12) {
+		--*m;
+		normalize_pair(y, m, 12);
+		++*m;
+		/* |y| can't be bigger than about
+		 * |original y| + |original m|/12 now.
+		 */
+	}
+	assert(1 <= *m && *m <= 12);
+
+	/* Now only day can be out of bounds (year may also be out of bounds
+	 * for a datetime object, but we don't care about that here).
+	 * If day is out of bounds, what to do is arguable, but at least the
+	 * method here is principled and explainable.
+	 */
+	dim = days_in_month(*y, *m);
+	if (*d < 1 || *d > dim) {
+		/* Move day-1 days from the first of the month.  First try to
+		 * get off cheap if we're only one day out of range
+		 * (adjustments for timezone alone can't be worse than that).
+		 */
+		if (*d == 0) {
+			--*m;
+			if (*m > 0)
+				*d = days_in_month(*y, *m);
+			else {
+				--*y;
+				*m = 12;
+				*d = 31;
+			}
+		}
+		else if (*d == dim + 1) {
+			/* move forward a day */
+			++*m;
+			*d = 1;
+			if (*m > 12) {
+				*m = 1;
+				++*y;
+			}
+		}
+		else {
+			int ordinal = ymd_to_ord(*y, *m, 1) +
+						  *d - 1;
+			ord_to_ymd(ordinal, y, m, d);
+		}
+	}
+	assert(*m > 0);
+	assert(*d > 0);
+}
+
+/* Fiddle out-of-bounds months and days so that the result makes some kind
+ * of sense.  The parameters are both inputs and outputs.  Returns < 0 on
+ * failure, where failure means the adjusted year is out of bounds.
+ */
+static int
+normalize_date(int *year, int *month, int *day)
+{
+	int result;
+
+	normalize_y_m_d(year, month, day);
+	if (MINYEAR <= *year && *year <= MAXYEAR)
+		result = 0;
+	else {
+		PyErr_SetString(PyExc_OverflowError,
+				"date value out of range");
+		result = -1;
+	}
+	return result;
+}
+
+/* Force all the datetime fields into range.  The parameters are both
+ * inputs and outputs.  Returns < 0 on error.
+ */
+static int
+normalize_datetime(int *year, int *month, int *day,
+                   int *hour, int *minute, int *second,
+                   int *microsecond)
+{
+	normalize_pair(second, microsecond, 1000000);
+	normalize_pair(minute, second, 60);
+	normalize_pair(hour, minute, 60);
+	normalize_pair(day, hour, 24);
+	return normalize_date(year, month, day);
+}
+
+/* ---------------------------------------------------------------------------
+ * Basic object allocation:  tp_alloc implementations.  These allocate
+ * Python objects of the right size and type, and do the Python object-
+ * initialization bit.  If there's not enough memory, they return NULL after
+ * setting MemoryError.  All data members remain uninitialized trash.
+ *
+ * We abuse the tp_alloc "nitems" argument to communicate whether a tzinfo
+ * member is needed.  This is ugly, imprecise, and possibly insecure.
+ * tp_basicsize for the time and datetime types is set to the size of the
+ * struct that has room for the tzinfo member, so subclasses in Python will
+ * allocate enough space for a tzinfo member whether or not one is actually
+ * needed.  That's the "ugly and imprecise" parts.  The "possibly insecure"
+ * part is that PyType_GenericAlloc() (which subclasses in Python end up
+ * using) just happens today to effectively ignore the nitems argument
+ * when tp_itemsize is 0, which it is for these type objects.  If that
+ * changes, perhaps the callers of tp_alloc slots in this file should
+ * be changed to force a 0 nitems argument unless the type being allocated
+ * is a base type implemented in this file (so that tp_alloc is time_alloc
+ * or datetime_alloc below, which know about the nitems abuse).
+ */
+
+static PyObject *
+time_alloc(PyTypeObject *type, Py_ssize_t aware)
+{
+	PyObject *self;
+
+	self = (PyObject *)
+		PyObject_MALLOC(aware ?
+				sizeof(PyDateTime_Time) :
+				sizeof(_PyDateTime_BaseTime));
+	if (self == NULL)
+		return (PyObject *)PyErr_NoMemory();
+	PyObject_INIT(self, type);
+	return self;
+}
+
+static PyObject *
+datetime_alloc(PyTypeObject *type, Py_ssize_t aware)
+{
+	PyObject *self;
+
+	self = (PyObject *)
+		PyObject_MALLOC(aware ?
+				sizeof(PyDateTime_DateTime) :
+				sizeof(_PyDateTime_BaseDateTime));
+	if (self == NULL)
+		return (PyObject *)PyErr_NoMemory();
+	PyObject_INIT(self, type);
+	return self;
+}
+
+/* ---------------------------------------------------------------------------
+ * Helpers for setting object fields.  These work on pointers to the
+ * appropriate base class.
+ */
+
+/* For date and datetime. */
+static void
+set_date_fields(PyDateTime_Date *self, int y, int m, int d)
+{
+	self->hashcode = -1;
+	SET_YEAR(self, y);
+	SET_MONTH(self, m);
+	SET_DAY(self, d);
+}
+
+/* ---------------------------------------------------------------------------
+ * Create various objects, mostly without range checking.
+ */
+
+/* Create a date instance with no range checking. */
+static PyObject *
+new_date_ex(int year, int month, int day, PyTypeObject *type)
+{
+	PyDateTime_Date *self;
+
+	self = (PyDateTime_Date *) (type->tp_alloc(type, 0));
+	if (self != NULL)
+		set_date_fields(self, year, month, day);
+	return (PyObject *) self;
+}
+
+#define new_date(year, month, day) \
+	new_date_ex(year, month, day, &PyDateTime_DateType)
+
+/* Create a datetime instance with no range checking. */
+static PyObject *
+new_datetime_ex(int year, int month, int day, int hour, int minute,
+	     int second, int usecond, PyObject *tzinfo, PyTypeObject *type)
+{
+	PyDateTime_DateTime *self;
+	char aware = tzinfo != Py_None;
+
+	self = (PyDateTime_DateTime *) (type->tp_alloc(type, aware));
+	if (self != NULL) {
+		self->hastzinfo = aware;
+		set_date_fields((PyDateTime_Date *)self, year, month, day);
+		DATE_SET_HOUR(self, hour);
+		DATE_SET_MINUTE(self, minute);
+		DATE_SET_SECOND(self, second);
+		DATE_SET_MICROSECOND(self, usecond);
+		if (aware) {
+			Py_INCREF(tzinfo);
+			self->tzinfo = tzinfo;
+		}
+	}
+	return (PyObject *)self;
+}
+
+#define new_datetime(y, m, d, hh, mm, ss, us, tzinfo)		\
+	new_datetime_ex(y, m, d, hh, mm, ss, us, tzinfo,	\
+			&PyDateTime_DateTimeType)
+
+/* Create a time instance with no range checking. */
+static PyObject *
+new_time_ex(int hour, int minute, int second, int usecond,
+	    PyObject *tzinfo, PyTypeObject *type)
+{
+	PyDateTime_Time *self;
+	char aware = tzinfo != Py_None;
+
+	self = (PyDateTime_Time *) (type->tp_alloc(type, aware));
+	if (self != NULL) {
+		self->hastzinfo = aware;
+		self->hashcode = -1;
+		TIME_SET_HOUR(self, hour);
+		TIME_SET_MINUTE(self, minute);
+		TIME_SET_SECOND(self, second);
+		TIME_SET_MICROSECOND(self, usecond);
+		if (aware) {
+			Py_INCREF(tzinfo);
+			self->tzinfo = tzinfo;
+		}
+	}
+	return (PyObject *)self;
+}
+
+#define new_time(hh, mm, ss, us, tzinfo)		\
+	new_time_ex(hh, mm, ss, us, tzinfo, &PyDateTime_TimeType)
+
+/* Create a timedelta instance.  Normalize the members iff normalize is
+ * true.  Passing false is a speed optimization, if you know for sure
+ * that seconds and microseconds are already in their proper ranges.  In any
+ * case, raises OverflowError and returns NULL if the normalized days is out
+ * of range).
+ */
+static PyObject *
+new_delta_ex(int days, int seconds, int microseconds, int normalize,
+	     PyTypeObject *type)
+{
+	PyDateTime_Delta *self;
+
+	if (normalize)
+		normalize_d_s_us(&days, &seconds, &microseconds);
+	assert(0 <= seconds && seconds < 24*3600);
+	assert(0 <= microseconds && microseconds < 1000000);
+
+ 	if (check_delta_day_range(days) < 0)
+ 		return NULL;
+
+	self = (PyDateTime_Delta *) (type->tp_alloc(type, 0));
+	if (self != NULL) {
+		self->hashcode = -1;
+		SET_TD_DAYS(self, days);
+		SET_TD_SECONDS(self, seconds);
+		SET_TD_MICROSECONDS(self, microseconds);
+	}
+	return (PyObject *) self;
+}
+
+#define new_delta(d, s, us, normalize)	\
+	new_delta_ex(d, s, us, normalize, &PyDateTime_DeltaType)
+
+/* ---------------------------------------------------------------------------
+ * tzinfo helpers.
+ */
+
+/* Ensure that p is None or of a tzinfo subclass.  Return 0 if OK; if not
+ * raise TypeError and return -1.
+ */
+static int
+check_tzinfo_subclass(PyObject *p)
+{
+	if (p == Py_None || PyTZInfo_Check(p))
+		return 0;
+	PyErr_Format(PyExc_TypeError,
+		     "tzinfo argument must be None or of a tzinfo subclass, "
+		     "not type '%s'",
+		     p->ob_type->tp_name);
+	return -1;
+}
+
+/* Return tzinfo.methname(tzinfoarg), without any checking of results.
+ * If tzinfo is None, returns None.
+ */
+static PyObject *
+call_tzinfo_method(PyObject *tzinfo, char *methname, PyObject *tzinfoarg)
+{
+	PyObject *result;
+
+	assert(tzinfo && methname && tzinfoarg);
+	assert(check_tzinfo_subclass(tzinfo) >= 0);
+	if (tzinfo == Py_None) {
+		result = Py_None;
+		Py_INCREF(result);
+	}
+	else
+		result = PyObject_CallMethod(tzinfo, methname, "O", tzinfoarg);
+	return result;
+}
+
+/* If self has a tzinfo member, return a BORROWED reference to it.  Else
+ * return NULL, which is NOT AN ERROR.  There are no error returns here,
+ * and the caller must not decref the result.
+ */
+static PyObject *
+get_tzinfo_member(PyObject *self)
+{
+	PyObject *tzinfo = NULL;
+
+	if (PyDateTime_Check(self) && HASTZINFO(self))
+		tzinfo = ((PyDateTime_DateTime *)self)->tzinfo;
+	else if (PyTime_Check(self) && HASTZINFO(self))
+		tzinfo = ((PyDateTime_Time *)self)->tzinfo;
+
+	return tzinfo;
+}
+
+/* Call getattr(tzinfo, name)(tzinfoarg), and extract an int from the
+ * result.  tzinfo must be an instance of the tzinfo class.  If the method
+ * returns None, this returns 0 and sets *none to 1.  If the method doesn't
+ * return None or timedelta, TypeError is raised and this returns -1.  If it
+ * returnsa timedelta and the value is out of range or isn't a whole number
+ * of minutes, ValueError is raised and this returns -1.
+ * Else *none is set to 0 and the integer method result is returned.
+ */
+static int
+call_utc_tzinfo_method(PyObject *tzinfo, char *name, PyObject *tzinfoarg,
+		       int *none)
+{
+	PyObject *u;
+	int result = -1;
+
+	assert(tzinfo != NULL);
+	assert(PyTZInfo_Check(tzinfo));
+	assert(tzinfoarg != NULL);
+
+	*none = 0;
+	u = call_tzinfo_method(tzinfo, name, tzinfoarg);
+	if (u == NULL)
+		return -1;
+
+	else if (u == Py_None) {
+		result = 0;
+		*none = 1;
+	}
+	else if (PyDelta_Check(u)) {
+		const int days = GET_TD_DAYS(u);
+		if (days < -1 || days > 0)
+			result = 24*60;	/* trigger ValueError below */
+		else {
+			/* next line can't overflow because we know days
+			 * is -1 or 0 now
+			 */
+			int ss = days * 24 * 3600 + GET_TD_SECONDS(u);
+			result = divmod(ss, 60, &ss);
+			if (ss || GET_TD_MICROSECONDS(u)) {
+				PyErr_Format(PyExc_ValueError,
+					     "tzinfo.%s() must return a "
+					     "whole number of minutes",
+					     name);
+				result = -1;
+			}
+		}
+	}
+	else {
+		PyErr_Format(PyExc_TypeError,
+			     "tzinfo.%s() must return None or "
+			     "timedelta, not '%s'",
+			     name, u->ob_type->tp_name);
+	}
+
+	Py_DECREF(u);
+	if (result < -1439 || result > 1439) {
+		PyErr_Format(PyExc_ValueError,
+			     "tzinfo.%s() returned %d; must be in "
+			     "-1439 .. 1439",
+			     name, result);
+		result = -1;
+	}
+	return result;
+}
+
+/* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the
+ * result.  tzinfo must be an instance of the tzinfo class.  If utcoffset()
+ * returns None, call_utcoffset returns 0 and sets *none to 1.  If uctoffset()
+ * doesn't return None or timedelta, TypeError is raised and this returns -1.
+ * If utcoffset() returns an invalid timedelta (out of range, or not a whole
+ * # of minutes), ValueError is raised and this returns -1.  Else *none is
+ * set to 0 and the offset is returned (as int # of minutes east of UTC).
+ */
+static int
+call_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg, int *none)
+{
+	return call_utc_tzinfo_method(tzinfo, "utcoffset", tzinfoarg, none);
+}
+
+/* Call tzinfo.name(tzinfoarg), and return the offset as a timedelta or None.
+ */
+static PyObject *
+offset_as_timedelta(PyObject *tzinfo, char *name, PyObject *tzinfoarg) {
+	PyObject *result;
+
+	assert(tzinfo && name && tzinfoarg);
+	if (tzinfo == Py_None) {
+		result = Py_None;
+		Py_INCREF(result);
+	}
+	else {
+		int none;
+		int offset = call_utc_tzinfo_method(tzinfo, name, tzinfoarg,
+						    &none);
+		if (offset < 0 && PyErr_Occurred())
+			return NULL;
+		if (none) {
+			result = Py_None;
+			Py_INCREF(result);
+		}
+		else
+			result = new_delta(0, offset * 60, 0, 1);
+	}
+	return result;
+}
+
+/* Call tzinfo.dst(tzinfoarg), and extract an integer from the
+ * result.  tzinfo must be an instance of the tzinfo class.  If dst()
+ * returns None, call_dst returns 0 and sets *none to 1.  If dst()
+ & doesn't return None or timedelta, TypeError is raised and this
+ * returns -1.  If dst() returns an invalid timedelta for a UTC offset,
+ * ValueError is raised and this returns -1.  Else *none is set to 0 and
+ * the offset is returned (as an int # of minutes east of UTC).
+ */
+static int
+call_dst(PyObject *tzinfo, PyObject *tzinfoarg, int *none)
+{
+	return call_utc_tzinfo_method(tzinfo, "dst", tzinfoarg, none);
+}
+
+/* Call tzinfo.tzname(tzinfoarg), and return the result.  tzinfo must be
+ * an instance of the tzinfo class or None.  If tzinfo isn't None, and
+ * tzname() doesn't return None or a string, TypeError is raised and this
+ * returns NULL.
+ */
+static PyObject *
+call_tzname(PyObject *tzinfo, PyObject *tzinfoarg)
+{
+	PyObject *result;
+
+	assert(tzinfo != NULL);
+	assert(check_tzinfo_subclass(tzinfo) >= 0);
+	assert(tzinfoarg != NULL);
+
+	if (tzinfo == Py_None) {
+		result = Py_None;
+		Py_INCREF(result);
+	}
+	else
+		result = PyObject_CallMethod(tzinfo, "tzname", "O", tzinfoarg);
+
+	if (result != NULL && result != Py_None && ! PyString_Check(result)) {
+		PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
+			     "return None or a string, not '%s'",
+			     result->ob_type->tp_name);
+		Py_DECREF(result);
+		result = NULL;
+	}
+	return result;
+}
+
+typedef enum {
+	      /* an exception has been set; the caller should pass it on */
+	      OFFSET_ERROR,
+
+	      /* type isn't date, datetime, or time subclass */
+	      OFFSET_UNKNOWN,
+
+	      /* date,
+	       * datetime with !hastzinfo
+	       * datetime with None tzinfo,
+	       * datetime where utcoffset() returns None
+	       * time with !hastzinfo
+	       * time with None tzinfo,
+	       * time where utcoffset() returns None
+	       */
+	      OFFSET_NAIVE,
+
+	      /* time or datetime where utcoffset() doesn't return None */
+	      OFFSET_AWARE
+} naivety;
+
+/* Classify an object as to whether it's naive or offset-aware.  See
+ * the "naivety" typedef for details.  If the type is aware, *offset is set
+ * to minutes east of UTC (as returned by the tzinfo.utcoffset() method).
+ * If the type is offset-naive (or unknown, or error), *offset is set to 0.
+ * tzinfoarg is the argument to pass to the tzinfo.utcoffset() method.
+ */
+static naivety
+classify_utcoffset(PyObject *op, PyObject *tzinfoarg, int *offset)
+{
+	int none;
+	PyObject *tzinfo;
+
+	assert(tzinfoarg != NULL);
+	*offset = 0;
+	tzinfo = get_tzinfo_member(op);	/* NULL means no tzinfo, not error */
+	if (tzinfo == Py_None)
+		return OFFSET_NAIVE;
+	if (tzinfo == NULL) {
+		/* note that a datetime passes the PyDate_Check test */
+		return (PyTime_Check(op) || PyDate_Check(op)) ?
+		       OFFSET_NAIVE : OFFSET_UNKNOWN;
+	}
+	*offset = call_utcoffset(tzinfo, tzinfoarg, &none);
+	if (*offset == -1 && PyErr_Occurred())
+		return OFFSET_ERROR;
+	return none ? OFFSET_NAIVE : OFFSET_AWARE;
+}
+
+/* Classify two objects as to whether they're naive or offset-aware.
+ * This isn't quite the same as calling classify_utcoffset() twice:  for
+ * binary operations (comparison and subtraction), we generally want to
+ * ignore the tzinfo members if they're identical.  This is by design,
+ * so that results match "naive" expectations when mixing objects from a
+ * single timezone.  So in that case, this sets both offsets to 0 and
+ * both naiveties to OFFSET_NAIVE.
+ * The function returns 0 if everything's OK, and -1 on error.
+ */
+static int
+classify_two_utcoffsets(PyObject *o1, int *offset1, naivety *n1,
+			PyObject *tzinfoarg1,
+			PyObject *o2, int *offset2, naivety *n2,
+			PyObject *tzinfoarg2)
+{
+	if (get_tzinfo_member(o1) == get_tzinfo_member(o2)) {
+		*offset1 = *offset2 = 0;
+		*n1 = *n2 = OFFSET_NAIVE;
+	}
+	else {
+		*n1 = classify_utcoffset(o1, tzinfoarg1, offset1);
+		if (*n1 == OFFSET_ERROR)
+			return -1;
+		*n2 = classify_utcoffset(o2, tzinfoarg2, offset2);
+		if (*n2 == OFFSET_ERROR)
+			return -1;
+	}
+	return 0;
+}
+
+/* repr is like "someclass(arg1, arg2)".  If tzinfo isn't None,
+ * stuff
+ *     ", tzinfo=" + repr(tzinfo)
+ * before the closing ")".
+ */
+static PyObject *
+append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
+{
+	PyObject *temp;
+
+	assert(PyString_Check(repr));
+	assert(tzinfo);
+	if (tzinfo == Py_None)
+		return repr;
+	/* Get rid of the trailing ')'. */
+	assert(PyString_AsString(repr)[PyString_Size(repr)-1] == ')');
+	temp = PyString_FromStringAndSize(PyString_AsString(repr),
+					  PyString_Size(repr) - 1);
+	Py_DECREF(repr);
+	if (temp == NULL)
+		return NULL;
+	repr = temp;
+
+	/* Append ", tzinfo=". */
+	PyString_ConcatAndDel(&repr, PyString_FromString(", tzinfo="));
+
+	/* Append repr(tzinfo). */
+	PyString_ConcatAndDel(&repr, PyObject_Repr(tzinfo));
+
+	/* Add a closing paren. */
+	PyString_ConcatAndDel(&repr, PyString_FromString(")"));
+	return repr;
+}
+
+/* ---------------------------------------------------------------------------
+ * String format helpers.
+ */
+
+static PyObject *
+format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
+{
+	static const char *DayNames[] = {
+		"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
+	};
+	static const char *MonthNames[] = {
+		"Jan", "Feb", "Mar", "Apr", "May", "Jun",
+		"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+	};
+
+	char buffer[128];
+	int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
+
+	PyOS_snprintf(buffer, sizeof(buffer), "%s %s %2d %02d:%02d:%02d %04d",
+		      DayNames[wday], MonthNames[GET_MONTH(date) - 1],
+		      GET_DAY(date), hours, minutes, seconds,
+		      GET_YEAR(date));
+	return PyString_FromString(buffer);
+}
+
+/* Add an hours & minutes UTC offset string to buf.  buf has no more than
+ * buflen bytes remaining.  The UTC offset is gotten by calling
+ * tzinfo.uctoffset(tzinfoarg).  If that returns None, \0 is stored into
+ * *buf, and that's all.  Else the returned value is checked for sanity (an
+ * integer in range), and if that's OK it's converted to an hours & minutes
+ * string of the form
+ *   sign HH sep MM
+ * Returns 0 if everything is OK.  If the return value from utcoffset() is
+ * bogus, an appropriate exception is set and -1 is returned.
+ */
+static int
+format_utcoffset(char *buf, size_t buflen, const char *sep,
+		PyObject *tzinfo, PyObject *tzinfoarg)
+{
+	int offset;
+	int hours;
+	int minutes;
+	char sign;
+	int none;
+
+	offset = call_utcoffset(tzinfo, tzinfoarg, &none);
+	if (offset == -1 && PyErr_Occurred())
+		return -1;
+	if (none) {
+		*buf = '\0';
+		return 0;
+	}
+	sign = '+';
+	if (offset < 0) {
+		sign = '-';
+		offset = - offset;
+	}
+	hours = divmod(offset, 60, &minutes);
+	PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
+	return 0;
+}
+
+/* I sure don't want to reproduce the strftime code from the time module,
+ * so this imports the module and calls it.  All the hair is due to
+ * giving special meanings to the %z and %Z format codes via a preprocessing
+ * step on the format string.
+ * tzinfoarg is the argument to pass to the object's tzinfo method, if
+ * needed.
+ */
+static PyObject *
+wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
+	      PyObject *tzinfoarg)
+{
+	PyObject *result = NULL;	/* guilty until proved innocent */
+
+	PyObject *zreplacement = NULL;	/* py string, replacement for %z */
+	PyObject *Zreplacement = NULL;	/* py string, replacement for %Z */
+
+	char *pin;	/* pointer to next char in input format */
+	char ch;	/* next char in input format */
+
+	PyObject *newfmt = NULL;	/* py string, the output format */
+	char *pnew;	/* pointer to available byte in output format */
+	int totalnew;	/* number bytes total in output format buffer,
+			   exclusive of trailing \0 */
+	int usednew;	/* number bytes used so far in output format buffer */
+
+	char *ptoappend; /* pointer to string to append to output buffer */
+	int ntoappend;	/* # of bytes to append to output buffer */
+
+	assert(object && format && timetuple);
+	assert(PyString_Check(format));
+
+	/* Give up if the year is before 1900.
+	 * Python strftime() plays games with the year, and different
+	 * games depending on whether envar PYTHON2K is set.  This makes
+	 * years before 1900 a nightmare, even if the platform strftime
+	 * supports them (and not all do).
+	 * We could get a lot farther here by avoiding Python's strftime
+	 * wrapper and calling the C strftime() directly, but that isn't
+	 * an option in the Python implementation of this module.
+	 */
+	{
+		long year;
+		PyObject *pyyear = PySequence_GetItem(timetuple, 0);
+		if (pyyear == NULL) return NULL;
+		assert(PyInt_Check(pyyear));
+		year = PyInt_AsLong(pyyear);
+		Py_DECREF(pyyear);
+		if (year < 1900) {
+			PyErr_Format(PyExc_ValueError, "year=%ld is before "
+				     "1900; the datetime strftime() "
+	                             "methods require year >= 1900",
+	                             year);
+	                return NULL;
+		}
+	}
+
+	/* Scan the input format, looking for %z and %Z escapes, building
+	 * a new format.  Since computing the replacements for those codes
+	 * is expensive, don't unless they're actually used.
+	 */
+	totalnew = PyString_Size(format) + 1;	/* realistic if no %z/%Z */
+	newfmt = PyString_FromStringAndSize(NULL, totalnew);
+	if (newfmt == NULL) goto Done;
+	pnew = PyString_AsString(newfmt);
+	usednew = 0;
+
+	pin = PyString_AsString(format);
+	while ((ch = *pin++) != '\0') {
+		if (ch != '%') {
+			ptoappend = pin - 1;
+			ntoappend = 1;
+		}
+		else if ((ch = *pin++) == '\0') {
+			/* There's a lone trailing %; doesn't make sense. */
+			PyErr_SetString(PyExc_ValueError, "strftime format "
+					"ends with raw %");
+			goto Done;
+		}
+		/* A % has been seen and ch is the character after it. */
+		else if (ch == 'z') {
+			if (zreplacement == NULL) {
+				/* format utcoffset */
+				char buf[100];
+				PyObject *tzinfo = get_tzinfo_member(object);
+				zreplacement = PyString_FromString("");
+				if (zreplacement == NULL) goto Done;
+				if (tzinfo != Py_None && tzinfo != NULL) {
+					assert(tzinfoarg != NULL);
+					if (format_utcoffset(buf,
+							     sizeof(buf),
+							     "",
+							     tzinfo,
+							     tzinfoarg) < 0)
+						goto Done;
+					Py_DECREF(zreplacement);
+					zreplacement = PyString_FromString(buf);
+					if (zreplacement == NULL) goto Done;
+				}
+			}
+			assert(zreplacement != NULL);
+			ptoappend = PyString_AS_STRING(zreplacement);
+			ntoappend = PyString_GET_SIZE(zreplacement);
+		}
+		else if (ch == 'Z') {
+			/* format tzname */
+			if (Zreplacement == NULL) {
+				PyObject *tzinfo = get_tzinfo_member(object);
+				Zreplacement = PyString_FromString("");
+				if (Zreplacement == NULL) goto Done;
+				if (tzinfo != Py_None && tzinfo != NULL) {
+					PyObject *temp;
+					assert(tzinfoarg != NULL);
+					temp = call_tzname(tzinfo, tzinfoarg);
+					if (temp == NULL) goto Done;
+					if (temp != Py_None) {
+						assert(PyString_Check(temp));
+						/* Since the tzname is getting
+						 * stuffed into the format, we
+						 * have to double any % signs
+						 * so that strftime doesn't
+						 * treat them as format codes.
+						 */
+						Py_DECREF(Zreplacement);
+						Zreplacement = PyObject_CallMethod(
+							temp, "replace",
+							"ss", "%", "%%");
+						Py_DECREF(temp);
+						if (Zreplacement == NULL)
+							goto Done;
+						if (!PyString_Check(Zreplacement)) {
+							PyErr_SetString(PyExc_TypeError, "tzname.replace() did not return a string");
+							goto Done;
+						}
+					}
+					else
+						Py_DECREF(temp);
+				}
+			}
+			assert(Zreplacement != NULL);
+			ptoappend = PyString_AS_STRING(Zreplacement);
+			ntoappend = PyString_GET_SIZE(Zreplacement);
+		}
+		else {
+			/* percent followed by neither z nor Z */
+			ptoappend = pin - 2;
+			ntoappend = 2;
+		}
+
+ 		/* Append the ntoappend chars starting at ptoappend to
+ 		 * the new format.
+ 		 */
+ 		assert(ptoappend != NULL);
+ 		assert(ntoappend >= 0);
+ 		if (ntoappend == 0)
+ 			continue;
+ 		while (usednew + ntoappend > totalnew) {
+ 			int bigger = totalnew << 1;
+ 			if ((bigger >> 1) != totalnew) { /* overflow */
+ 				PyErr_NoMemory();
+ 				goto Done;
+ 			}
+ 			if (_PyString_Resize(&newfmt, bigger) < 0)
+ 				goto Done;
+ 			totalnew = bigger;
+ 			pnew = PyString_AsString(newfmt) + usednew;
+ 		}
+		memcpy(pnew, ptoappend, ntoappend);
+		pnew += ntoappend;
+		usednew += ntoappend;
+		assert(usednew <= totalnew);
+	}  /* end while() */
+
+	if (_PyString_Resize(&newfmt, usednew) < 0)
+		goto Done;
+	{
+		PyObject *time = PyImport_ImportModule("time");
+		if (time == NULL)
+			goto Done;
+		result = PyObject_CallMethod(time, "strftime", "OO",
+					     newfmt, timetuple);
+		Py_DECREF(time);
+    	}
+ Done:
+	Py_XDECREF(zreplacement);
+	Py_XDECREF(Zreplacement);
+	Py_XDECREF(newfmt);
+    	return result;
+}
+
+static char *
+isoformat_date(PyDateTime_Date *dt, char buffer[], int bufflen)
+{
+	int x;
+	x = PyOS_snprintf(buffer, bufflen,
+			  "%04d-%02d-%02d",
+			  GET_YEAR(dt), GET_MONTH(dt), GET_DAY(dt));
+	return buffer + x;
+}
+
+static void
+isoformat_time(PyDateTime_DateTime *dt, char buffer[], int bufflen)
+{
+	int us = DATE_GET_MICROSECOND(dt);
+
+	PyOS_snprintf(buffer, bufflen,
+		      "%02d:%02d:%02d",	/* 8 characters */
+		      DATE_GET_HOUR(dt),
+		      DATE_GET_MINUTE(dt),
+		      DATE_GET_SECOND(dt));
+	if (us)
+		PyOS_snprintf(buffer + 8, bufflen - 8, ".%06d", us);
+}
+
+/* ---------------------------------------------------------------------------
+ * Wrap functions from the time module.  These aren't directly available
+ * from C.  Perhaps they should be.
+ */
+
+/* Call time.time() and return its result (a Python float). */
+static PyObject *
+time_time(void)
+{
+	PyObject *result = NULL;
+	PyObject *time = PyImport_ImportModule("time");
+
+	if (time != NULL) {
+		result = PyObject_CallMethod(time, "time", "()");
+		Py_DECREF(time);
+	}
+	return result;
+}
+
+/* Build a time.struct_time.  The weekday and day number are automatically
+ * computed from the y,m,d args.
+ */
+static PyObject *
+build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
+{
+	PyObject *time;
+	PyObject *result = NULL;
+
+	time = PyImport_ImportModule("time");
+	if (time != NULL) {
+		result = PyObject_CallMethod(time, "struct_time",
+					     "((iiiiiiiii))",
+					     y, m, d,
+					     hh, mm, ss,
+				 	     weekday(y, m, d),
+				 	     days_before_month(y, m) + d,
+				 	     dstflag);
+		Py_DECREF(time);
+	}
+	return result;
+}
+
+/* ---------------------------------------------------------------------------
+ * Miscellaneous helpers.
+ */
+
+/* For obscure reasons, we need to use tp_richcompare instead of tp_compare.
+ * The comparisons here all most naturally compute a cmp()-like result.
+ * This little helper turns that into a bool result for rich comparisons.
+ */
+static PyObject *
+diff_to_bool(int diff, int op)
+{
+	PyObject *result;
+	int istrue;
+
+	switch (op) {
+		case Py_EQ: istrue = diff == 0; break;
+		case Py_NE: istrue = diff != 0; break;
+		case Py_LE: istrue = diff <= 0; break;
+		case Py_GE: istrue = diff >= 0; break;
+		case Py_LT: istrue = diff < 0; break;
+		case Py_GT: istrue = diff > 0; break;
+		default:
+			assert(! "op unknown");
+			istrue = 0; /* To shut up compiler */
+	}
+	result = istrue ? Py_True : Py_False;
+	Py_INCREF(result);
+	return result;
+}
+
+/* Raises a "can't compare" TypeError and returns NULL. */
+static PyObject *
+cmperror(PyObject *a, PyObject *b)
+{
+	PyErr_Format(PyExc_TypeError,
+		     "can't compare %s to %s",
+		     a->ob_type->tp_name, b->ob_type->tp_name);
+	return NULL;
+}
+
+/* ---------------------------------------------------------------------------
+ * Cached Python objects; these are set by the module init function.
+ */
+
+/* Conversion factors. */
+static PyObject *us_per_us = NULL;	/* 1 */
+static PyObject *us_per_ms = NULL;	/* 1000 */
+static PyObject *us_per_second = NULL;	/* 1000000 */
+static PyObject *us_per_minute = NULL;	/* 1e6 * 60 as Python int */
+static PyObject *us_per_hour = NULL;	/* 1e6 * 3600 as Python long */
+static PyObject *us_per_day = NULL;	/* 1e6 * 3600 * 24 as Python long */
+static PyObject *us_per_week = NULL;	/* 1e6*3600*24*7 as Python long */
+static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
+
+/* ---------------------------------------------------------------------------
+ * Class implementations.
+ */
+
+/*
+ * PyDateTime_Delta implementation.
+ */
+
+/* Convert a timedelta to a number of us,
+ * 	(24*3600*self.days + self.seconds)*1000000 + self.microseconds
+ * as a Python int or long.
+ * Doing mixed-radix arithmetic by hand instead is excruciating in C,
+ * due to ubiquitous overflow possibilities.
+ */
+static PyObject *
+delta_to_microseconds(PyDateTime_Delta *self)
+{
+	PyObject *x1 = NULL;
+	PyObject *x2 = NULL;
+	PyObject *x3 = NULL;
+	PyObject *result = NULL;
+
+	x1 = PyInt_FromLong(GET_TD_DAYS(self));
+	if (x1 == NULL)
+		goto Done;
+	x2 = PyNumber_Multiply(x1, seconds_per_day);	/* days in seconds */
+	if (x2 == NULL)
+		goto Done;
+	Py_DECREF(x1);
+	x1 = NULL;
+
+	/* x2 has days in seconds */
+	x1 = PyInt_FromLong(GET_TD_SECONDS(self));	/* seconds */
+	if (x1 == NULL)
+		goto Done;
+	x3 = PyNumber_Add(x1, x2);	/* days and seconds in seconds */
+	if (x3 == NULL)
+		goto Done;
+	Py_DECREF(x1);
+	Py_DECREF(x2);
+	x1 = x2 = NULL;
+
+	/* x3 has days+seconds in seconds */
+	x1 = PyNumber_Multiply(x3, us_per_second);	/* us */
+	if (x1 == NULL)
+		goto Done;
+	Py_DECREF(x3);
+	x3 = NULL;
+
+	/* x1 has days+seconds in us */
+	x2 = PyInt_FromLong(GET_TD_MICROSECONDS(self));
+	if (x2 == NULL)
+		goto Done;
+	result = PyNumber_Add(x1, x2);
+
+Done:
+	Py_XDECREF(x1);
+	Py_XDECREF(x2);
+	Py_XDECREF(x3);
+	return result;
+}
+
+/* Convert a number of us (as a Python int or long) to a timedelta.
+ */
+static PyObject *
+microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
+{
+	int us;
+	int s;
+	int d;
+	long temp;
+
+	PyObject *tuple = NULL;
+	PyObject *num = NULL;
+	PyObject *result = NULL;
+
+	tuple = PyNumber_Divmod(pyus, us_per_second);
+	if (tuple == NULL)
+		goto Done;
+
+	num = PyTuple_GetItem(tuple, 1);	/* us */
+	if (num == NULL)
+		goto Done;
+	temp = PyLong_AsLong(num);
+	num = NULL;
+	if (temp == -1 && PyErr_Occurred())
+		goto Done;
+	assert(0 <= temp && temp < 1000000);
+	us = (int)temp;
+	if (us < 0) {
+		/* The divisor was positive, so this must be an error. */
+		assert(PyErr_Occurred());
+		goto Done;
+	}
+
+	num = PyTuple_GetItem(tuple, 0);	/* leftover seconds */
+	if (num == NULL)
+		goto Done;
+	Py_INCREF(num);
+	Py_DECREF(tuple);
+
+	tuple = PyNumber_Divmod(num, seconds_per_day);
+	if (tuple == NULL)
+		goto Done;
+	Py_DECREF(num);
+
+	num = PyTuple_GetItem(tuple, 1); 	/* seconds */
+	if (num == NULL)
+		goto Done;
+	temp = PyLong_AsLong(num);
+	num = NULL;
+	if (temp == -1 && PyErr_Occurred())
+		goto Done;
+	assert(0 <= temp && temp < 24*3600);
+	s = (int)temp;
+
+	if (s < 0) {
+		/* The divisor was positive, so this must be an error. */
+		assert(PyErr_Occurred());
+		goto Done;
+	}
+
+	num = PyTuple_GetItem(tuple, 0);	/* leftover days */
+	if (num == NULL)
+		goto Done;
+	Py_INCREF(num);
+	temp = PyLong_AsLong(num);
+	if (temp == -1 && PyErr_Occurred())
+		goto Done;
+	d = (int)temp;
+	if ((long)d != temp) {
+		PyErr_SetString(PyExc_OverflowError, "normalized days too "
+				"large to fit in a C int");
+		goto Done;
+	}
+	result = new_delta_ex(d, s, us, 0, type);
+
+Done:
+	Py_XDECREF(tuple);
+	Py_XDECREF(num);
+	return result;
+}
+
+#define microseconds_to_delta(pymicros)	\
+	microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
+
+static PyObject *
+multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
+{
+	PyObject *pyus_in;
+	PyObject *pyus_out;
+	PyObject *result;
+
+	pyus_in = delta_to_microseconds(delta);
+	if (pyus_in == NULL)
+		return NULL;
+
+	pyus_out = PyNumber_Multiply(pyus_in, intobj);
+	Py_DECREF(pyus_in);
+	if (pyus_out == NULL)
+		return NULL;
+
+	result = microseconds_to_delta(pyus_out);
+	Py_DECREF(pyus_out);
+	return result;
+}
+
+static PyObject *
+divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
+{
+	PyObject *pyus_in;
+	PyObject *pyus_out;
+	PyObject *result;
+
+	pyus_in = delta_to_microseconds(delta);
+	if (pyus_in == NULL)
+		return NULL;
+
+	pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
+	Py_DECREF(pyus_in);
+	if (pyus_out == NULL)
+		return NULL;
+
+	result = microseconds_to_delta(pyus_out);
+	Py_DECREF(pyus_out);
+	return result;
+}
+
+static PyObject *
+delta_add(PyObject *left, PyObject *right)
+{
+	PyObject *result = Py_NotImplemented;
+
+	if (PyDelta_Check(left) && PyDelta_Check(right)) {
+		/* delta + delta */
+		/* The C-level additions can't overflow because of the
+		 * invariant bounds.
+		 */
+		int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
+		int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
+		int microseconds = GET_TD_MICROSECONDS(left) +
+				   GET_TD_MICROSECONDS(right);
+		result = new_delta(days, seconds, microseconds, 1);
+	}
+
+	if (result == Py_NotImplemented)
+		Py_INCREF(result);
+	return result;
+}
+
+static PyObject *
+delta_negative(PyDateTime_Delta *self)
+{
+	return new_delta(-GET_TD_DAYS(self),
+			 -GET_TD_SECONDS(self),
+			 -GET_TD_MICROSECONDS(self),
+			 1);
+}
+
+static PyObject *
+delta_positive(PyDateTime_Delta *self)
+{
+	/* Could optimize this (by returning self) if this isn't a
+	 * subclass -- but who uses unary + ?  Approximately nobody.
+	 */
+	return new_delta(GET_TD_DAYS(self),
+			 GET_TD_SECONDS(self),
+			 GET_TD_MICROSECONDS(self),
+			 0);
+}
+
+static PyObject *
+delta_abs(PyDateTime_Delta *self)
+{
+	PyObject *result;
+
+	assert(GET_TD_MICROSECONDS(self) >= 0);
+	assert(GET_TD_SECONDS(self) >= 0);
+
+	if (GET_TD_DAYS(self) < 0)
+		result = delta_negative(self);
+	else
+		result = delta_positive(self);
+
+	return result;
+}
+
+static PyObject *
+delta_subtract(PyObject *left, PyObject *right)
+{
+	PyObject *result = Py_NotImplemented;
+
+	if (PyDelta_Check(left) && PyDelta_Check(right)) {
+	    	/* delta - delta */
+	    	PyObject *minus_right = PyNumber_Negative(right);
+	    	if (minus_right) {
+	    		result = delta_add(left, minus_right);
+	    		Py_DECREF(minus_right);
+	    	}
+	    	else
+	    		result = NULL;
+	}
+
+	if (result == Py_NotImplemented)
+		Py_INCREF(result);
+	return result;
+}
+
+/* This is more natural as a tp_compare, but doesn't work then:  for whatever
+ * reason, Python's try_3way_compare ignores tp_compare unless
+ * PyInstance_Check returns true, but these aren't old-style classes.
+ */
+static PyObject *
+delta_richcompare(PyDateTime_Delta *self, PyObject *other, int op)
+{
+	int diff = 42;	/* nonsense */
+
+	if (PyDelta_Check(other)) {
+		diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
+		if (diff == 0) {
+			diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
+			if (diff == 0)
+				diff = GET_TD_MICROSECONDS(self) -
+				       GET_TD_MICROSECONDS(other);
+		}
+	}
+	else if (op == Py_EQ || op == Py_NE)
+		diff = 1;	/* any non-zero value will do */
+
+	else /* stop this from falling back to address comparison */
+		return cmperror((PyObject *)self, other);
+
+	return diff_to_bool(diff, op);
+}
+
+static PyObject *delta_getstate(PyDateTime_Delta *self);
+
+static long
+delta_hash(PyDateTime_Delta *self)
+{
+	if (self->hashcode == -1) {
+		PyObject *temp = delta_getstate(self);
+		if (temp != NULL) {
+			self->hashcode = PyObject_Hash(temp);
+			Py_DECREF(temp);
+		}
+	}
+	return self->hashcode;
+}
+
+static PyObject *
+delta_multiply(PyObject *left, PyObject *right)
+{
+	PyObject *result = Py_NotImplemented;
+
+	if (PyDelta_Check(left)) {
+		/* delta * ??? */
+		if (PyInt_Check(right) || PyLong_Check(right))
+			result = multiply_int_timedelta(right,
+					(PyDateTime_Delta *) left);
+	}
+	else if (PyInt_Check(left) || PyLong_Check(left))
+		result = multiply_int_timedelta(left,
+						(PyDateTime_Delta *) right);
+
+	if (result == Py_NotImplemented)
+		Py_INCREF(result);
+	return result;
+}
+
+static PyObject *
+delta_divide(PyObject *left, PyObject *right)
+{
+	PyObject *result = Py_NotImplemented;
+
+	if (PyDelta_Check(left)) {
+		/* delta * ??? */
+		if (PyInt_Check(right) || PyLong_Check(right))
+			result = divide_timedelta_int(
+					(PyDateTime_Delta *)left,
+					right);
+	}
+
+	if (result == Py_NotImplemented)
+		Py_INCREF(result);
+	return result;
+}
+
+/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
+ * timedelta constructor.  sofar is the # of microseconds accounted for
+ * so far, and there are factor microseconds per current unit, the number
+ * of which is given by num.  num * factor is added to sofar in a
+ * numerically careful way, and that's the result.  Any fractional
+ * microseconds left over (this can happen if num is a float type) are
+ * added into *leftover.
+ * Note that there are many ways this can give an error (NULL) return.
+ */
+static PyObject *
+accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
+      double *leftover)
+{
+	PyObject *prod;
+	PyObject *sum;
+
+	assert(num != NULL);
+
+	if (PyInt_Check(num) || PyLong_Check(num)) {
+		prod = PyNumber_Multiply(num, factor);
+		if (prod == NULL)
+			return NULL;
+		sum = PyNumber_Add(sofar, prod);
+		Py_DECREF(prod);
+		return sum;
+	}
+
+	if (PyFloat_Check(num)) {
+		double dnum;
+		double fracpart;
+		double intpart;
+		PyObject *x;
+		PyObject *y;
+
+		/* The Plan:  decompose num into an integer part and a
+		 * fractional part, num = intpart + fracpart.
+		 * Then num * factor ==
+		 *      intpart * factor + fracpart * factor
+		 * and the LHS can be computed exactly in long arithmetic.
+		 * The RHS is again broken into an int part and frac part.
+		 * and the frac part is added into *leftover.
+		 */
+		dnum = PyFloat_AsDouble(num);
+		if (dnum == -1.0 && PyErr_Occurred())
+			return NULL;
+		fracpart = modf(dnum, &intpart);
+		x = PyLong_FromDouble(intpart);
+		if (x == NULL)
+			return NULL;
+
+		prod = PyNumber_Multiply(x, factor);
+		Py_DECREF(x);
+		if (prod == NULL)
+			return NULL;
+
+		sum = PyNumber_Add(sofar, prod);
+		Py_DECREF(prod);
+		if (sum == NULL)
+			return NULL;
+
+		if (fracpart == 0.0)
+			return sum;
+		/* So far we've lost no information.  Dealing with the
+		 * fractional part requires float arithmetic, and may
+		 * lose a little info.
+		 */
+		assert(PyInt_Check(factor) || PyLong_Check(factor));
+		if (PyInt_Check(factor))
+			dnum = (double)PyInt_AsLong(factor);
+		else
+			dnum = PyLong_AsDouble(factor);
+
+		dnum *= fracpart;
+		fracpart = modf(dnum, &intpart);
+		x = PyLong_FromDouble(intpart);
+		if (x == NULL) {
+			Py_DECREF(sum);
+			return NULL;
+		}
+
+		y = PyNumber_Add(sum, x);
+		Py_DECREF(sum);
+		Py_DECREF(x);
+		*leftover += fracpart;
+		return y;
+	}
+
+	PyErr_Format(PyExc_TypeError,
+		     "unsupported type for timedelta %s component: %s",
+		     tag, num->ob_type->tp_name);
+	return NULL;
+}
+
+static PyObject *
+delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
+{
+	PyObject *self = NULL;
+
+	/* Argument objects. */
+	PyObject *day = NULL;
+	PyObject *second = NULL;
+	PyObject *us = NULL;
+	PyObject *ms = NULL;
+	PyObject *minute = NULL;
+	PyObject *hour = NULL;
+	PyObject *week = NULL;
+
+	PyObject *x = NULL;	/* running sum of microseconds */
+	PyObject *y = NULL;	/* temp sum of microseconds */
+	double leftover_us = 0.0;
+
+	static char *keywords[] = {
+		"days", "seconds", "microseconds", "milliseconds",
+		"minutes", "hours", "weeks", NULL
+	};
+
+	if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
+					keywords,
+					&day, &second, &us,
+					&ms, &minute, &hour, &week) == 0)
+		goto Done;
+
+	x = PyInt_FromLong(0);
+	if (x == NULL)
+		goto Done;
+
+#define CLEANUP 	\
+	Py_DECREF(x);	\
+	x = y;		\
+	if (x == NULL)	\
+		goto Done
+
+	if (us) {
+		y = accum("microseconds", x, us, us_per_us, &leftover_us);
+		CLEANUP;
+	}
+	if (ms) {
+		y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
+		CLEANUP;
+	}
+	if (second) {
+		y = accum("seconds", x, second, us_per_second, &leftover_us);
+		CLEANUP;
+	}
+	if (minute) {
+		y = accum("minutes", x, minute, us_per_minute, &leftover_us);
+		CLEANUP;
+	}
+	if (hour) {
+		y = accum("hours", x, hour, us_per_hour, &leftover_us);
+		CLEANUP;
+	}
+	if (day) {
+		y = accum("days", x, day, us_per_day, &leftover_us);
+		CLEANUP;
+	}
+	if (week) {
+		y = accum("weeks", x, week, us_per_week, &leftover_us);
+		CLEANUP;
+	}
+	if (leftover_us) {
+		/* Round to nearest whole # of us, and add into x. */
+		PyObject *temp = PyLong_FromLong(round_to_long(leftover_us));
+		if (temp == NULL) {
+			Py_DECREF(x);
+			goto Done;
+		}
+		y = PyNumber_Add(x, temp);
+		Py_DECREF(temp);
+		CLEANUP;
+	}
+
+	self = microseconds_to_delta_ex(x, type);
+	Py_DECREF(x);
+Done:
+	return self;
+
+#undef CLEANUP
+}
+
+static int
+delta_nonzero(PyDateTime_Delta *self)
+{
+	return (GET_TD_DAYS(self) != 0
+		|| GET_TD_SECONDS(self) != 0
+		|| GET_TD_MICROSECONDS(self) != 0);
+}
+
+static PyObject *
+delta_repr(PyDateTime_Delta *self)
+{
+	if (GET_TD_MICROSECONDS(self) != 0)
+		return PyString_FromFormat("%s(%d, %d, %d)",
+					   self->ob_type->tp_name,
+					   GET_TD_DAYS(self),
+					   GET_TD_SECONDS(self),
+					   GET_TD_MICROSECONDS(self));
+	if (GET_TD_SECONDS(self) != 0)
+		return PyString_FromFormat("%s(%d, %d)",
+					   self->ob_type->tp_name,
+					   GET_TD_DAYS(self),
+					   GET_TD_SECONDS(self));
+
+	return PyString_FromFormat("%s(%d)",
+				   self->ob_type->tp_name,
+				   GET_TD_DAYS(self));
+}
+
+static PyObject *
+delta_str(PyDateTime_Delta *self)
+{
+	int days = GET_TD_DAYS(self);
+	int seconds = GET_TD_SECONDS(self);
+	int us = GET_TD_MICROSECONDS(self);
+	int hours;
+	int minutes;
+	char buf[100];
+	char *pbuf = buf;
+	size_t buflen = sizeof(buf);
+	int n;
+
+	minutes = divmod(seconds, 60, &seconds);
+	hours = divmod(minutes, 60, &minutes);
+
+	if (days) {
+		n = PyOS_snprintf(pbuf, buflen, "%d day%s, ", days,
+				  (days == 1 || days == -1) ? "" : "s");
+		if (n < 0 || (size_t)n >= buflen)
+			goto Fail;
+		pbuf += n;
+		buflen -= (size_t)n;
+	}
+
+	n = PyOS_snprintf(pbuf, buflen, "%d:%02d:%02d",
+			  hours, minutes, seconds);
+	if (n < 0 || (size_t)n >= buflen)
+		goto Fail;
+	pbuf += n;
+	buflen -= (size_t)n;
+
+	if (us) {
+		n = PyOS_snprintf(pbuf, buflen, ".%06d", us);
+		if (n < 0 || (size_t)n >= buflen)
+			goto Fail;
+		pbuf += n;
+	}
+
+	return PyString_FromStringAndSize(buf, pbuf - buf);
+
+ Fail:
+	PyErr_SetString(PyExc_SystemError, "goofy result from PyOS_snprintf");
+	return NULL;
+}
+
+/* Pickle support, a simple use of __reduce__. */
+
+/* __getstate__ isn't exposed */
+static PyObject *
+delta_getstate(PyDateTime_Delta *self)
+{
+	return Py_BuildValue("iii", GET_TD_DAYS(self),
+				    GET_TD_SECONDS(self),
+				    GET_TD_MICROSECONDS(self));
+}
+
+static PyObject *
+delta_reduce(PyDateTime_Delta* self)
+{
+	return Py_BuildValue("ON", self->ob_type, delta_getstate(self));
+}
+
+#define OFFSET(field)  offsetof(PyDateTime_Delta, field)
+
+static PyMemberDef delta_members[] = {
+
+	{"days",         T_INT, OFFSET(days),         READONLY,
+	 PyDoc_STR("Number of days.")},
+
+	{"seconds",      T_INT, OFFSET(seconds),      READONLY,
+	 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
+
+	{"microseconds", T_INT, OFFSET(microseconds), READONLY,
+	 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
+	{NULL}
+};
+
+static PyMethodDef delta_methods[] = {
+	{"__reduce__", (PyCFunction)delta_reduce,     METH_NOARGS,
+	 PyDoc_STR("__reduce__() -> (cls, state)")},
+
+	{NULL,	NULL},
+};
+
+static char delta_doc[] =
+PyDoc_STR("Difference between two datetime values.");
+
+static PyNumberMethods delta_as_number = {
+	delta_add,				/* nb_add */
+	delta_subtract,				/* nb_subtract */
+	delta_multiply,				/* nb_multiply */
+	delta_divide,				/* nb_divide */
+	0,					/* nb_remainder */
+	0,					/* nb_divmod */
+	0,					/* nb_power */
+	(unaryfunc)delta_negative,		/* nb_negative */
+	(unaryfunc)delta_positive,		/* nb_positive */
+	(unaryfunc)delta_abs,			/* nb_absolute */
+	(inquiry)delta_nonzero,			/* nb_nonzero */
+	0,					/*nb_invert*/
+	0,					/*nb_lshift*/
+	0,					/*nb_rshift*/
+	0,					/*nb_and*/
+	0,					/*nb_xor*/
+	0,					/*nb_or*/
+	0,					/*nb_coerce*/
+	0,					/*nb_int*/
+	0,					/*nb_long*/
+	0,					/*nb_float*/
+	0,					/*nb_oct*/
+	0, 					/*nb_hex*/
+	0,					/*nb_inplace_add*/
+	0,					/*nb_inplace_subtract*/
+	0,					/*nb_inplace_multiply*/
+	0,					/*nb_inplace_divide*/
+	0,					/*nb_inplace_remainder*/
+	0,					/*nb_inplace_power*/
+	0,					/*nb_inplace_lshift*/
+	0,					/*nb_inplace_rshift*/
+	0,					/*nb_inplace_and*/
+	0,					/*nb_inplace_xor*/
+	0,					/*nb_inplace_or*/
+	delta_divide,				/* nb_floor_divide */
+	0,					/* nb_true_divide */
+	0,					/* nb_inplace_floor_divide */
+	0,					/* nb_inplace_true_divide */
+};
+
+static PyTypeObject PyDateTime_DeltaType = {
+	PyObject_HEAD_INIT(NULL)
+	0,						/* ob_size */
+	"datetime.timedelta",				/* tp_name */
+	sizeof(PyDateTime_Delta),			/* tp_basicsize */
+	0,						/* tp_itemsize */
+	0,						/* tp_dealloc */
+	0,						/* tp_print */
+	0,						/* tp_getattr */
+	0,						/* tp_setattr */
+	0,						/* tp_compare */
+	(reprfunc)delta_repr,				/* tp_repr */
+	&delta_as_number,				/* tp_as_number */
+	0,						/* tp_as_sequence */
+	0,						/* tp_as_mapping */
+	(hashfunc)delta_hash,				/* tp_hash */
+	0,              				/* tp_call */
+	(reprfunc)delta_str,				/* tp_str */
+	PyObject_GenericGetAttr,			/* tp_getattro */
+	0,						/* tp_setattro */
+	0,						/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
+	        Py_TPFLAGS_BASETYPE,			/* tp_flags */
+	delta_doc,					/* tp_doc */
+	0,						/* tp_traverse */
+	0,						/* tp_clear */
+	(richcmpfunc)delta_richcompare,			/* tp_richcompare */
+	0,						/* tp_weaklistoffset */
+	0,						/* tp_iter */
+	0,						/* tp_iternext */
+	delta_methods,					/* tp_methods */
+	delta_members,					/* tp_members */
+	0,						/* tp_getset */
+	0,						/* tp_base */
+	0,						/* tp_dict */
+	0,						/* tp_descr_get */
+	0,						/* tp_descr_set */
+	0,						/* tp_dictoffset */
+	0,						/* tp_init */
+	0,						/* tp_alloc */
+	delta_new,					/* tp_new */
+	0,						/* tp_free */
+};
+
+/*
+ * PyDateTime_Date implementation.
+ */
+
+/* Accessor properties. */
+
+static PyObject *
+date_year(PyDateTime_Date *self, void *unused)
+{
+	return PyInt_FromLong(GET_YEAR(self));
+}
+
+static PyObject *
+date_month(PyDateTime_Date *self, void *unused)
+{
+	return PyInt_FromLong(GET_MONTH(self));
+}
+
+static PyObject *
+date_day(PyDateTime_Date *self, void *unused)
+{
+	return PyInt_FromLong(GET_DAY(self));
+}
+
+static PyGetSetDef date_getset[] = {
+	{"year",        (getter)date_year},
+	{"month",       (getter)date_month},
+	{"day",         (getter)date_day},
+	{NULL}
+};
+
+/* Constructors. */
+
+static char *date_kws[] = {"year", "month", "day", NULL};
+
+static PyObject *
+date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
+{
+	PyObject *self = NULL;
+	PyObject *state;
+	int year;
+	int month;
+	int day;
+
+	/* Check for invocation from pickle with __getstate__ state */
+	if (PyTuple_GET_SIZE(args) == 1 &&
+	    PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
+	    PyString_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
+	    MONTH_IS_SANE(PyString_AS_STRING(state)[2]))
+	{
+	    	PyDateTime_Date *me;
+
+		me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
+		if (me != NULL) {
+			char *pdata = PyString_AS_STRING(state);
+			memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
+			me->hashcode = -1;
+		}
+		return (PyObject *)me;
+	}
+
+	if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
+					&year, &month, &day)) {
+		if (check_date_args(year, month, day) < 0)
+			return NULL;
+		self = new_date_ex(year, month, day, type);
+	}
+	return self;
+}
+
+/* Return new date from localtime(t). */
+static PyObject *
+date_local_from_time_t(PyObject *cls, double ts)
+{
+	struct tm *tm;
+	time_t t;
+	PyObject *result = NULL;
+
+	t = _PyTime_DoubleToTimet(ts);
+	if (t == (time_t)-1 && PyErr_Occurred())
+		return NULL;
+	tm = localtime(&t);
+	if (tm)
+		result = PyObject_CallFunction(cls, "iii",
+					       tm->tm_year + 1900,
+					       tm->tm_mon + 1,
+					       tm->tm_mday);
+	else
+		PyErr_SetString(PyExc_ValueError,
+				"timestamp out of range for "
+				"platform localtime() function");
+	return result;
+}
+
+/* Return new date from current time.
+ * We say this is equivalent to fromtimestamp(time.time()), and the
+ * only way to be sure of that is to *call* time.time().  That's not
+ * generally the same as calling C's time.
+ */
+static PyObject *
+date_today(PyObject *cls, PyObject *dummy)
+{
+	PyObject *time;
+	PyObject *result;
+
+	time = time_time();
+	if (time == NULL)
+		return NULL;
+
+	/* Note well:  today() is a class method, so this may not call
+	 * date.fromtimestamp.  For example, it may call
+	 * datetime.fromtimestamp.  That's why we need all the accuracy
+	 * time.time() delivers; if someone were gonzo about optimization,
+	 * date.today() could get away with plain C time().
+	 */
+	result = PyObject_CallMethod(cls, "fromtimestamp", "O", time);
+	Py_DECREF(time);
+	return result;
+}
+
+/* Return new date from given timestamp (Python timestamp -- a double). */
+static PyObject *
+date_fromtimestamp(PyObject *cls, PyObject *args)
+{
+	double timestamp;
+	PyObject *result = NULL;
+
+	if (PyArg_ParseTuple(args, "d:fromtimestamp", &timestamp))
+		result = date_local_from_time_t(cls, timestamp);
+	return result;
+}
+
+/* Return new date from proleptic Gregorian ordinal.  Raises ValueError if
+ * the ordinal is out of range.
+ */
+static PyObject *
+date_fromordinal(PyObject *cls, PyObject *args)
+{
+	PyObject *result = NULL;
+	int ordinal;
+
+	if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
+		int year;
+		int month;
+		int day;
+
+		if (ordinal < 1)
+			PyErr_SetString(PyExc_ValueError, "ordinal must be "
+							  ">= 1");
+		else {
+			ord_to_ymd(ordinal, &year, &month, &day);
+			result = PyObject_CallFunction(cls, "iii",
+						       year, month, day);
+		}
+	}
+	return result;
+}
+
+/*
+ * Date arithmetic.
+ */
+
+/* date + timedelta -> date.  If arg negate is true, subtract the timedelta
+ * instead.
+ */
+static PyObject *
+add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
+{
+	PyObject *result = NULL;
+	int year = GET_YEAR(date);
+	int month = GET_MONTH(date);
+	int deltadays = GET_TD_DAYS(delta);
+	/* C-level overflow is impossible because |deltadays| < 1e9. */
+	int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
+
+	if (normalize_date(&year, &month, &day) >= 0)
+		result = new_date(year, month, day);
+	return result;
+}
+
+static PyObject *
+date_add(PyObject *left, PyObject *right)
+{
+	if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
+		Py_INCREF(Py_NotImplemented);
+		return Py_NotImplemented;
+	}
+	if (PyDate_Check(left)) {
+		/* date + ??? */
+		if (PyDelta_Check(right))
+			/* date + delta */
+			return add_date_timedelta((PyDateTime_Date *) left,
+						  (PyDateTime_Delta *) right,
+						  0);
+	}
+	else {
+		/* ??? + date
+		 * 'right' must be one of us, or we wouldn't have been called
+		 */
+		if (PyDelta_Check(left))
+			/* delta + date */
+			return add_date_timedelta((PyDateTime_Date *) right,
+						  (PyDateTime_Delta *) left,
+						  0);
+	}
+	Py_INCREF(Py_NotImplemented);
+	return Py_NotImplemented;
+}
+
+static PyObject *
+date_subtract(PyObject *left, PyObject *right)
+{
+	if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
+		Py_INCREF(Py_NotImplemented);
+		return Py_NotImplemented;
+	}
+	if (PyDate_Check(left)) {
+		if (PyDate_Check(right)) {
+			/* date - date */
+			int left_ord = ymd_to_ord(GET_YEAR(left),
+						  GET_MONTH(left),
+						  GET_DAY(left));
+			int right_ord = ymd_to_ord(GET_YEAR(right),
+						   GET_MONTH(right),
+						   GET_DAY(right));
+			return new_delta(left_ord - right_ord, 0, 0, 0);
+		}
+		if (PyDelta_Check(right)) {
+			/* date - delta */
+			return add_date_timedelta((PyDateTime_Date *) left,
+						  (PyDateTime_Delta *) right,
+						  1);
+		}
+	}
+	Py_INCREF(Py_NotImplemented);
+	return Py_NotImplemented;
+}
+
+
+/* Various ways to turn a date into a string. */
+
+static PyObject *
+date_repr(PyDateTime_Date *self)
+{
+	char buffer[1028];
+	const char *type_name;
+
+	type_name = self->ob_type->tp_name;
+	PyOS_snprintf(buffer, sizeof(buffer), "%s(%d, %d, %d)",
+		      type_name,
+		      GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
+
+	return PyString_FromString(buffer);
+}
+
+static PyObject *
+date_isoformat(PyDateTime_Date *self)
+{
+	char buffer[128];
+
+	isoformat_date(self, buffer, sizeof(buffer));
+	return PyString_FromString(buffer);
+}
+
+/* str() calls the appropriate isoformat() method. */
+static PyObject *
+date_str(PyDateTime_Date *self)
+{
+	return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
+}
+
+
+static PyObject *
+date_ctime(PyDateTime_Date *self)
+{
+	return format_ctime(self, 0, 0, 0);
+}
+
+static PyObject *
+date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
+{
+	/* This method can be inherited, and needs to call the
+	 * timetuple() method appropriate to self's class.
+	 */
+	PyObject *result;
+	PyObject *format;
+	PyObject *tuple;
+	static char *keywords[] = {"format", NULL};
+
+	if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:strftime", keywords,
+					  &PyString_Type, &format))
+		return NULL;
+
+	tuple = PyObject_CallMethod((PyObject *)self, "timetuple", "()");
+	if (tuple == NULL)
+		return NULL;
+	result = wrap_strftime((PyObject *)self, format, tuple,
+			       (PyObject *)self);
+	Py_DECREF(tuple);
+	return result;
+}
+
+/* ISO methods. */
+
+static PyObject *
+date_isoweekday(PyDateTime_Date *self)
+{
+	int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
+
+	return PyInt_FromLong(dow + 1);
+}
+
+static PyObject *
+date_isocalendar(PyDateTime_Date *self)
+{
+	int  year         = GET_YEAR(self);
+	int  week1_monday = iso_week1_monday(year);
+	int today         = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
+	int  week;
+	int  day;
+
+	week = divmod(today - week1_monday, 7, &day);
+	if (week < 0) {
+		--year;
+		week1_monday = iso_week1_monday(year);
+		week = divmod(today - week1_monday, 7, &day);
+	}
+	else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
+		++year;
+		week = 0;
+	}
+	return Py_BuildValue("iii", year, week + 1, day + 1);
+}
+
+/* Miscellaneous methods. */
+
+/* This is more natural as a tp_compare, but doesn't work then:  for whatever
+ * reason, Python's try_3way_compare ignores tp_compare unless
+ * PyInstance_Check returns true, but these aren't old-style classes.
+ */
+static PyObject *
+date_richcompare(PyDateTime_Date *self, PyObject *other, int op)
+{
+	int diff = 42;	/* nonsense */
+
+	if (PyDate_Check(other))
+		diff = memcmp(self->data, ((PyDateTime_Date *)other)->data,
+			      _PyDateTime_DATE_DATASIZE);
+
+	else if (PyObject_HasAttrString(other, "timetuple")) {
+		/* A hook for other kinds of date objects. */
+		Py_INCREF(Py_NotImplemented);
+		return Py_NotImplemented;
+	}
+	else if (op == Py_EQ || op == Py_NE)
+		diff = 1;	/* any non-zero value will do */
+
+	else /* stop this from falling back to address comparison */
+		return cmperror((PyObject *)self, other);
+
+	return diff_to_bool(diff, op);
+}
+
+static PyObject *
+date_timetuple(PyDateTime_Date *self)
+{
+	return build_struct_time(GET_YEAR(self),
+				 GET_MONTH(self),
+				 GET_DAY(self),
+				 0, 0, 0, -1);
+}
+
+static PyObject *
+date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
+{
+	PyObject *clone;
+	PyObject *tuple;
+	int year = GET_YEAR(self);
+	int month = GET_MONTH(self);
+	int day = GET_DAY(self);
+
+	if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
+					  &year, &month, &day))
+		return NULL;
+	tuple = Py_BuildValue("iii", year, month, day);
+	if (tuple == NULL)
+		return NULL;
+	clone = date_new(self->ob_type, tuple, NULL);
+	Py_DECREF(tuple);
+	return clone;
+}
+
+static PyObject *date_getstate(PyDateTime_Date *self);
+
+static long
+date_hash(PyDateTime_Date *self)
+{
+	if (self->hashcode == -1) {
+		PyObject *temp = date_getstate(self);
+		if (temp != NULL) {
+			self->hashcode = PyObject_Hash(temp);
+			Py_DECREF(temp);
+		}
+	}
+	return self->hashcode;
+}
+
+static PyObject *
+date_toordinal(PyDateTime_Date *self)
+{
+	return PyInt_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
+					 GET_DAY(self)));
+}
+
+static PyObject *
+date_weekday(PyDateTime_Date *self)
+{
+	int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
+
+	return PyInt_FromLong(dow);
+}
+
+/* Pickle support, a simple use of __reduce__. */
+
+/* __getstate__ isn't exposed */
+static PyObject *
+date_getstate(PyDateTime_Date *self)
+{
+	return Py_BuildValue(
+		"(N)",
+		PyString_FromStringAndSize((char *)self->data,
+					   _PyDateTime_DATE_DATASIZE));
+}
+
+static PyObject *
+date_reduce(PyDateTime_Date *self, PyObject *arg)
+{
+	return Py_BuildValue("(ON)", self->ob_type, date_getstate(self));
+}
+
+static PyMethodDef date_methods[] = {
+
+	/* Class methods: */
+
+	{"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
+							   METH_CLASS,
+	 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
+	 	   "time.time()).")},
+
+	{"fromordinal", (PyCFunction)date_fromordinal,	METH_VARARGS |
+							METH_CLASS,
+	 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
+	 	   "ordinal.")},
+
+	{"today",         (PyCFunction)date_today,   METH_NOARGS | METH_CLASS,
+	 PyDoc_STR("Current date or datetime:  same as "
+	 	   "self.__class__.fromtimestamp(time.time()).")},
+
+	/* Instance methods: */
+
+	{"ctime",       (PyCFunction)date_ctime,        METH_NOARGS,
+	 PyDoc_STR("Return ctime() style string.")},
+
+	{"strftime",   	(PyCFunction)date_strftime,	METH_KEYWORDS,
+	 PyDoc_STR("format -> strftime() style string.")},
+
+	{"timetuple",   (PyCFunction)date_timetuple,    METH_NOARGS,
+         PyDoc_STR("Return time tuple, compatible with time.localtime().")},
+
+	{"isocalendar", (PyCFunction)date_isocalendar,  METH_NOARGS,
+	 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
+	 	   "weekday.")},
+
+	{"isoformat",   (PyCFunction)date_isoformat,	METH_NOARGS,
+	 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
+
+	{"isoweekday",  (PyCFunction)date_isoweekday,   METH_NOARGS,
+	 PyDoc_STR("Return the day of the week represented by the date.\n"
+	 	   "Monday == 1 ... Sunday == 7")},
+
+	{"toordinal",   (PyCFunction)date_toordinal,    METH_NOARGS,
+	 PyDoc_STR("Return proleptic Gregorian ordinal.  January 1 of year "
+	 	   "1 is day 1.")},
+
+	{"weekday",     (PyCFunction)date_weekday,      METH_NOARGS,
+	 PyDoc_STR("Return the day of the week represented by the date.\n"
+		   "Monday == 0 ... Sunday == 6")},
+
+	{"replace",     (PyCFunction)date_replace,      METH_KEYWORDS,
+	 PyDoc_STR("Return date with new specified fields.")},
+
+	{"__reduce__", (PyCFunction)date_reduce,        METH_NOARGS,
+	 PyDoc_STR("__reduce__() -> (cls, state)")},
+
+	{NULL,	NULL}
+};
+
+static char date_doc[] =
+PyDoc_STR("date(year, month, day) --> date object");
+
+static PyNumberMethods date_as_number = {
+	date_add,					/* nb_add */
+	date_subtract,					/* nb_subtract */
+	0,						/* nb_multiply */
+	0,						/* nb_divide */
+	0,						/* nb_remainder */
+	0,						/* nb_divmod */
+	0,						/* nb_power */
+	0,						/* nb_negative */
+	0,						/* nb_positive */
+	0,						/* nb_absolute */
+	0,						/* nb_nonzero */
+};
+
+static PyTypeObject PyDateTime_DateType = {
+	PyObject_HEAD_INIT(NULL)
+	0,						/* ob_size */
+	"datetime.date",				/* tp_name */
+	sizeof(PyDateTime_Date),			/* tp_basicsize */
+	0,						/* tp_itemsize */
+	0,						/* tp_dealloc */
+	0,						/* tp_print */
+	0,						/* tp_getattr */
+	0,						/* tp_setattr */
+	0,						/* tp_compare */
+	(reprfunc)date_repr,				/* tp_repr */
+	&date_as_number,				/* tp_as_number */
+	0,						/* tp_as_sequence */
+	0,						/* tp_as_mapping */
+	(hashfunc)date_hash,				/* tp_hash */
+	0,              				/* tp_call */
+	(reprfunc)date_str,				/* tp_str */
+	PyObject_GenericGetAttr,			/* tp_getattro */
+	0,						/* tp_setattro */
+	0,						/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
+        Py_TPFLAGS_BASETYPE,				/* tp_flags */
+	date_doc,					/* tp_doc */
+	0,						/* tp_traverse */
+	0,						/* tp_clear */
+	(richcmpfunc)date_richcompare,			/* tp_richcompare */
+	0,						/* tp_weaklistoffset */
+	0,						/* tp_iter */
+	0,						/* tp_iternext */
+	date_methods,					/* tp_methods */
+	0,						/* tp_members */
+	date_getset,					/* tp_getset */
+	0,						/* tp_base */
+	0,						/* tp_dict */
+	0,						/* tp_descr_get */
+	0,						/* tp_descr_set */
+	0,						/* tp_dictoffset */
+	0,						/* tp_init */
+	0,						/* tp_alloc */
+	date_new,					/* tp_new */
+	0,						/* tp_free */
+};
+
+/*
+ * PyDateTime_TZInfo implementation.
+ */
+
+/* This is a pure abstract base class, so doesn't do anything beyond
+ * raising NotImplemented exceptions.  Real tzinfo classes need
+ * to derive from this.  This is mostly for clarity, and for efficiency in
+ * datetime and time constructors (their tzinfo arguments need to
+ * be subclasses of this tzinfo class, which is easy and quick to check).
+ *
+ * Note:  For reasons having to do with pickling of subclasses, we have
+ * to allow tzinfo objects to be instantiated.  This wasn't an issue
+ * in the Python implementation (__init__() could raise NotImplementedError
+ * there without ill effect), but doing so in the C implementation hit a
+ * brick wall.
+ */
+
+static PyObject *
+tzinfo_nogo(const char* methodname)
+{
+	PyErr_Format(PyExc_NotImplementedError,
+		     "a tzinfo subclass must implement %s()",
+		     methodname);
+	return NULL;
+}
+
+/* Methods.  A subclass must implement these. */
+
+static PyObject *
+tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
+{
+	return tzinfo_nogo("tzname");
+}
+
+static PyObject *
+tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
+{
+	return tzinfo_nogo("utcoffset");
+}
+
+static PyObject *
+tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
+{
+	return tzinfo_nogo("dst");
+}
+
+static PyObject *
+tzinfo_fromutc(PyDateTime_TZInfo *self, PyDateTime_DateTime *dt)
+{
+	int y, m, d, hh, mm, ss, us;
+
+	PyObject *result;
+	int off, dst;
+	int none;
+	int delta;
+
+	if (! PyDateTime_Check(dt)) {
+		PyErr_SetString(PyExc_TypeError,
+				"fromutc: argument must be a datetime");
+		return NULL;
+	}
+	if (! HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
+	    	PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
+	    			"is not self");
+	    	return NULL;
+	}
+
+	off = call_utcoffset(dt->tzinfo, (PyObject *)dt, &none);
+	if (off == -1 && PyErr_Occurred())
+		return NULL;
+	if (none) {
+		PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
+				"utcoffset() result required");
+		return NULL;
+	}
+
+	dst = call_dst(dt->tzinfo, (PyObject *)dt, &none);
+	if (dst == -1 && PyErr_Occurred())
+		return NULL;
+	if (none) {
+		PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
+				"dst() result required");
+		return NULL;
+	}
+
+	y = GET_YEAR(dt);
+	m = GET_MONTH(dt);
+	d = GET_DAY(dt);
+	hh = DATE_GET_HOUR(dt);
+	mm = DATE_GET_MINUTE(dt);
+	ss = DATE_GET_SECOND(dt);
+	us = DATE_GET_MICROSECOND(dt);
+
+	delta = off - dst;
+	mm += delta;
+	if ((mm < 0 || mm >= 60) &&
+	    normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
+		return NULL;
+	result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
+	if (result == NULL)
+		return result;
+
+	dst = call_dst(dt->tzinfo, result, &none);
+	if (dst == -1 && PyErr_Occurred())
+		goto Fail;
+	if (none)
+		goto Inconsistent;
+	if (dst == 0)
+		return result;
+
+	mm += dst;
+	if ((mm < 0 || mm >= 60) &&
+	    normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
+		goto Fail;
+	Py_DECREF(result);
+	result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
+	return result;
+
+Inconsistent:
+	PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
+			"inconsistent results; cannot convert");
+
+	/* fall thru to failure */
+Fail:
+	Py_DECREF(result);
+	return NULL;
+}
+
+/*
+ * Pickle support.  This is solely so that tzinfo subclasses can use
+ * pickling -- tzinfo itself is supposed to be uninstantiable.
+ */
+
+static PyObject *
+tzinfo_reduce(PyObject *self)
+{
+	PyObject *args, *state, *tmp;
+	PyObject *getinitargs, *getstate;
+
+	tmp = PyTuple_New(0);
+	if (tmp == NULL)
+		return NULL;
+
+	getinitargs = PyObject_GetAttrString(self, "__getinitargs__");
+	if (getinitargs != NULL) {
+		args = PyObject_CallObject(getinitargs, tmp);
+		Py_DECREF(getinitargs);
+		if (args == NULL) {
+			Py_DECREF(tmp);
+			return NULL;
+		}
+	}
+	else {
+		PyErr_Clear();
+		args = tmp;
+		Py_INCREF(args);
+	}
+
+	getstate = PyObject_GetAttrString(self, "__getstate__");
+	if (getstate != NULL) {
+		state = PyObject_CallObject(getstate, tmp);
+		Py_DECREF(getstate);
+		if (state == NULL) {
+			Py_DECREF(args);
+			Py_DECREF(tmp);
+			return NULL;
+		}
+	}
+	else {
+		PyObject **dictptr;
+		PyErr_Clear();
+		state = Py_None;
+		dictptr = _PyObject_GetDictPtr(self);
+		if (dictptr && *dictptr && PyDict_Size(*dictptr))
+			state = *dictptr;
+		Py_INCREF(state);
+	}
+
+	Py_DECREF(tmp);
+
+	if (state == Py_None) {
+		Py_DECREF(state);
+		return Py_BuildValue("(ON)", self->ob_type, args);
+	}
+	else
+		return Py_BuildValue("(ONN)", self->ob_type, args, state);
+}
+
+static PyMethodDef tzinfo_methods[] = {
+
+	{"tzname",	(PyCFunction)tzinfo_tzname,		METH_O,
+	 PyDoc_STR("datetime -> string name of time zone.")},
+
+	{"utcoffset",	(PyCFunction)tzinfo_utcoffset,		METH_O,
+	 PyDoc_STR("datetime -> minutes east of UTC (negative for "
+	 	   "west of UTC).")},
+
+	{"dst",		(PyCFunction)tzinfo_dst,		METH_O,
+	 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
+
+	{"fromutc",	(PyCFunction)tzinfo_fromutc,		METH_O,
+	 PyDoc_STR("datetime in UTC -> datetime in local time.")},
+
+	{"__reduce__",  (PyCFunction)tzinfo_reduce,             METH_NOARGS,
+	 PyDoc_STR("-> (cls, state)")},
+
+	{NULL, NULL}
+};
+
+static char tzinfo_doc[] =
+PyDoc_STR("Abstract base class for time zone info objects.");
+
+statichere PyTypeObject PyDateTime_TZInfoType = {
+	PyObject_HEAD_INIT(NULL)
+	0,					/* ob_size */
+	"datetime.tzinfo",			/* tp_name */
+	sizeof(PyDateTime_TZInfo),		/* tp_basicsize */
+	0,					/* tp_itemsize */
+	0,					/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	0,					/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	0,              			/* tp_call */
+	0,					/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
+        Py_TPFLAGS_BASETYPE,			/* tp_flags */
+	tzinfo_doc,				/* tp_doc */
+	0,					/* tp_traverse */
+	0,					/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	tzinfo_methods,				/* tp_methods */
+	0,					/* tp_members */
+	0,					/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	0,					/* tp_init */
+	0,					/* tp_alloc */
+	PyType_GenericNew,			/* tp_new */
+	0,					/* tp_free */
+};
+
+/*
+ * PyDateTime_Time implementation.
+ */
+
+/* Accessor properties.
+ */
+
+static PyObject *
+time_hour(PyDateTime_Time *self, void *unused)
+{
+	return PyInt_FromLong(TIME_GET_HOUR(self));
+}
+
+static PyObject *
+time_minute(PyDateTime_Time *self, void *unused)
+{
+	return PyInt_FromLong(TIME_GET_MINUTE(self));
+}
+
+/* The name time_second conflicted with some platform header file. */
+static PyObject *
+py_time_second(PyDateTime_Time *self, void *unused)
+{
+	return PyInt_FromLong(TIME_GET_SECOND(self));
+}
+
+static PyObject *
+time_microsecond(PyDateTime_Time *self, void *unused)
+{
+	return PyInt_FromLong(TIME_GET_MICROSECOND(self));
+}
+
+static PyObject *
+time_tzinfo(PyDateTime_Time *self, void *unused)
+{
+	PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
+	Py_INCREF(result);
+	return result;
+}
+
+static PyGetSetDef time_getset[] = {
+	{"hour",        (getter)time_hour},
+	{"minute",      (getter)time_minute},
+	{"second",      (getter)py_time_second},
+	{"microsecond", (getter)time_microsecond},
+	{"tzinfo",	(getter)time_tzinfo},
+	{NULL}
+};
+
+/*
+ * Constructors.
+ */
+
+static char *time_kws[] = {"hour", "minute", "second", "microsecond",
+			   "tzinfo", NULL};
+
+static PyObject *
+time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
+{
+	PyObject *self = NULL;
+	PyObject *state;
+	int hour = 0;
+	int minute = 0;
+	int second = 0;
+	int usecond = 0;
+	PyObject *tzinfo = Py_None;
+
+	/* Check for invocation from pickle with __getstate__ state */
+	if (PyTuple_GET_SIZE(args) >= 1 &&
+	    PyTuple_GET_SIZE(args) <= 2 &&
+	    PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
+	    PyString_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
+	    ((unsigned char) (PyString_AS_STRING(state)[0])) < 24)
+	{
+		PyDateTime_Time *me;
+		char aware;
+
+		if (PyTuple_GET_SIZE(args) == 2) {
+			tzinfo = PyTuple_GET_ITEM(args, 1);
+			if (check_tzinfo_subclass(tzinfo) < 0) {
+				PyErr_SetString(PyExc_TypeError, "bad "
+					"tzinfo state arg");
+				return NULL;
+			}
+		}
+		aware = (char)(tzinfo != Py_None);
+		me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
+		if (me != NULL) {
+			char *pdata = PyString_AS_STRING(state);
+
+			memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
+			me->hashcode = -1;
+			me->hastzinfo = aware;
+			if (aware) {
+				Py_INCREF(tzinfo);
+				me->tzinfo = tzinfo;
+			}
+		}
+		return (PyObject *)me;
+	}
+
+	if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", time_kws,
+					&hour, &minute, &second, &usecond,
+					&tzinfo)) {
+		if (check_time_args(hour, minute, second, usecond) < 0)
+			return NULL;
+		if (check_tzinfo_subclass(tzinfo) < 0)
+			return NULL;
+		self = new_time_ex(hour, minute, second, usecond, tzinfo,
+				   type);
+	}
+	return self;
+}
+
+/*
+ * Destructor.
+ */
+
+static void
+time_dealloc(PyDateTime_Time *self)
+{
+	if (HASTZINFO(self)) {
+		Py_XDECREF(self->tzinfo);
+	}
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+/*
+ * Indirect access to tzinfo methods.
+ */
+
+/* These are all METH_NOARGS, so don't need to check the arglist. */
+static PyObject *
+time_utcoffset(PyDateTime_Time *self, PyObject *unused) {
+	return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
+				   "utcoffset", Py_None);
+}
+
+static PyObject *
+time_dst(PyDateTime_Time *self, PyObject *unused) {
+	return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
+				   "dst", Py_None);
+}
+
+static PyObject *
+time_tzname(PyDateTime_Time *self, PyObject *unused) {
+	return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
+			   Py_None);
+}
+
+/*
+ * Various ways to turn a time into a string.
+ */
+
+static PyObject *
+time_repr(PyDateTime_Time *self)
+{
+	char buffer[100];
+	const char *type_name = self->ob_type->tp_name;
+	int h = TIME_GET_HOUR(self);
+	int m = TIME_GET_MINUTE(self);
+	int s = TIME_GET_SECOND(self);
+	int us = TIME_GET_MICROSECOND(self);
+	PyObject *result = NULL;
+
+	if (us)
+		PyOS_snprintf(buffer, sizeof(buffer),
+			      "%s(%d, %d, %d, %d)", type_name, h, m, s, us);
+	else if (s)
+		PyOS_snprintf(buffer, sizeof(buffer),
+			      "%s(%d, %d, %d)", type_name, h, m, s);
+	else
+		PyOS_snprintf(buffer, sizeof(buffer),
+			      "%s(%d, %d)", type_name, h, m);
+	result = PyString_FromString(buffer);
+	if (result != NULL && HASTZINFO(self))
+		result = append_keyword_tzinfo(result, self->tzinfo);
+	return result;
+}
+
+static PyObject *
+time_str(PyDateTime_Time *self)
+{
+	return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
+}
+
+/* Even though this silently ignores all arguments, it cannot
+   be fixed to reject them in release25-maint */
+static PyObject *
+time_isoformat(PyDateTime_Time *self, PyObject *unused_args, 
+	       PyObject *unused_keywords)
+{
+	char buf[100];
+	PyObject *result;
+	/* Reuse the time format code from the datetime type. */
+	PyDateTime_DateTime datetime;
+	PyDateTime_DateTime *pdatetime = &datetime;
+
+	/* Copy over just the time bytes. */
+	memcpy(pdatetime->data + _PyDateTime_DATE_DATASIZE,
+	       self->data,
+	       _PyDateTime_TIME_DATASIZE);
+
+	isoformat_time(pdatetime, buf, sizeof(buf));
+	result = PyString_FromString(buf);
+	if (result == NULL || ! HASTZINFO(self) || self->tzinfo == Py_None)
+		return result;
+
+	/* We need to append the UTC offset. */
+	if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
+			     Py_None) < 0) {
+		Py_DECREF(result);
+		return NULL;
+	}
+	PyString_ConcatAndDel(&result, PyString_FromString(buf));
+	return result;
+}
+
+static PyObject *
+time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
+{
+	PyObject *result;
+	PyObject *format;
+	PyObject *tuple;
+	static char *keywords[] = {"format", NULL};
+
+	if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:strftime", keywords,
+					  &PyString_Type, &format))
+		return NULL;
+
+	/* Python's strftime does insane things with the year part of the
+	 * timetuple.  The year is forced to (the otherwise nonsensical)
+	 * 1900 to worm around that.
+	 */
+	tuple = Py_BuildValue("iiiiiiiii",
+		              1900, 1, 1, /* year, month, day */
+			      TIME_GET_HOUR(self),
+			      TIME_GET_MINUTE(self),
+			      TIME_GET_SECOND(self),
+			      0, 1, -1); /* weekday, daynum, dst */
+	if (tuple == NULL)
+		return NULL;
+	assert(PyTuple_Size(tuple) == 9);
+	result = wrap_strftime((PyObject *)self, format, tuple, Py_None);
+	Py_DECREF(tuple);
+	return result;
+}
+
+/*
+ * Miscellaneous methods.
+ */
+
+/* This is more natural as a tp_compare, but doesn't work then:  for whatever
+ * reason, Python's try_3way_compare ignores tp_compare unless
+ * PyInstance_Check returns true, but these aren't old-style classes.
+ */
+static PyObject *
+time_richcompare(PyDateTime_Time *self, PyObject *other, int op)
+{
+	int diff;
+	naivety n1, n2;
+	int offset1, offset2;
+
+	if (! PyTime_Check(other)) {
+		if (op == Py_EQ || op == Py_NE) {
+			PyObject *result = op == Py_EQ ? Py_False : Py_True;
+			Py_INCREF(result);
+			return result;
+		}
+		/* Stop this from falling back to address comparison. */
+		return cmperror((PyObject *)self, other);
+	}
+	if (classify_two_utcoffsets((PyObject *)self, &offset1, &n1, Py_None,
+				     other, &offset2, &n2, Py_None) < 0)
+		return NULL;
+	assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
+	/* If they're both naive, or both aware and have the same offsets,
+	 * we get off cheap.  Note that if they're both naive, offset1 ==
+	 * offset2 == 0 at this point.
+	 */
+	if (n1 == n2 && offset1 == offset2) {
+		diff = memcmp(self->data, ((PyDateTime_Time *)other)->data,
+			      _PyDateTime_TIME_DATASIZE);
+		return diff_to_bool(diff, op);
+	}
+
+	if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
+		assert(offset1 != offset2);	/* else last "if" handled it */
+		/* Convert everything except microseconds to seconds.  These
+		 * can't overflow (no more than the # of seconds in 2 days).
+		 */
+		offset1 = TIME_GET_HOUR(self) * 3600 +
+			  (TIME_GET_MINUTE(self) - offset1) * 60 +
+			  TIME_GET_SECOND(self);
+		offset2 = TIME_GET_HOUR(other) * 3600 +
+			  (TIME_GET_MINUTE(other) - offset2) * 60 +
+			  TIME_GET_SECOND(other);
+		diff = offset1 - offset2;
+		if (diff == 0)
+			diff = TIME_GET_MICROSECOND(self) -
+			       TIME_GET_MICROSECOND(other);
+		return diff_to_bool(diff, op);
+	}
+
+	assert(n1 != n2);
+	PyErr_SetString(PyExc_TypeError,
+			"can't compare offset-naive and "
+			"offset-aware times");
+	return NULL;
+}
+
+static long
+time_hash(PyDateTime_Time *self)
+{
+	if (self->hashcode == -1) {
+		naivety n;
+		int offset;
+		PyObject *temp;
+
+		n = classify_utcoffset((PyObject *)self, Py_None, &offset);
+		assert(n != OFFSET_UNKNOWN);
+		if (n == OFFSET_ERROR)
+			return -1;
+
+		/* Reduce this to a hash of another object. */
+		if (offset == 0)
+			temp = PyString_FromStringAndSize((char *)self->data,
+						_PyDateTime_TIME_DATASIZE);
+		else {
+			int hour;
+			int minute;
+
+			assert(n == OFFSET_AWARE);
+			assert(HASTZINFO(self));
+			hour = divmod(TIME_GET_HOUR(self) * 60 +
+					TIME_GET_MINUTE(self) - offset,
+				      60,
+				      &minute);
+			if (0 <= hour && hour < 24)
+				temp = new_time(hour, minute,
+						TIME_GET_SECOND(self),
+						TIME_GET_MICROSECOND(self),
+						Py_None);
+			else
+				temp = Py_BuildValue("iiii",
+					   hour, minute,
+					   TIME_GET_SECOND(self),
+					   TIME_GET_MICROSECOND(self));
+		}
+		if (temp != NULL) {
+			self->hashcode = PyObject_Hash(temp);
+			Py_DECREF(temp);
+		}
+	}
+	return self->hashcode;
+}
+
+static PyObject *
+time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
+{
+	PyObject *clone;
+	PyObject *tuple;
+	int hh = TIME_GET_HOUR(self);
+	int mm = TIME_GET_MINUTE(self);
+	int ss = TIME_GET_SECOND(self);
+	int us = TIME_GET_MICROSECOND(self);
+	PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
+
+	if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace",
+					  time_kws,
+					  &hh, &mm, &ss, &us, &tzinfo))
+		return NULL;
+	tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
+	if (tuple == NULL)
+		return NULL;
+	clone = time_new(self->ob_type, tuple, NULL);
+	Py_DECREF(tuple);
+	return clone;
+}
+
+static int
+time_nonzero(PyDateTime_Time *self)
+{
+	int offset;
+	int none;
+
+	if (TIME_GET_SECOND(self) || TIME_GET_MICROSECOND(self)) {
+		/* Since utcoffset is in whole minutes, nothing can
+		 * alter the conclusion that this is nonzero.
+		 */
+		return 1;
+	}
+	offset = 0;
+	if (HASTZINFO(self) && self->tzinfo != Py_None) {
+		offset = call_utcoffset(self->tzinfo, Py_None, &none);
+		if (offset == -1 && PyErr_Occurred())
+			return -1;
+	}
+	return (TIME_GET_MINUTE(self) - offset + TIME_GET_HOUR(self)*60) != 0;
+}
+
+/* Pickle support, a simple use of __reduce__. */
+
+/* Let basestate be the non-tzinfo data string.
+ * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
+ * So it's a tuple in any (non-error) case.
+ * __getstate__ isn't exposed.
+ */
+static PyObject *
+time_getstate(PyDateTime_Time *self)
+{
+	PyObject *basestate;
+	PyObject *result = NULL;
+
+	basestate =  PyString_FromStringAndSize((char *)self->data,
+						_PyDateTime_TIME_DATASIZE);
+	if (basestate != NULL) {
+		if (! HASTZINFO(self) || self->tzinfo == Py_None)
+			result = PyTuple_Pack(1, basestate);
+		else
+			result = PyTuple_Pack(2, basestate, self->tzinfo);
+		Py_DECREF(basestate);
+	}
+	return result;
+}
+
+static PyObject *
+time_reduce(PyDateTime_Time *self, PyObject *arg)
+{
+	return Py_BuildValue("(ON)", self->ob_type, time_getstate(self));
+}
+
+static PyMethodDef time_methods[] = {
+
+	{"isoformat",   (PyCFunction)time_isoformat,	METH_KEYWORDS,
+	 PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
+	 	   "[+HH:MM].")},
+
+	{"strftime",   	(PyCFunction)time_strftime,	METH_KEYWORDS,
+	 PyDoc_STR("format -> strftime() style string.")},
+
+	{"utcoffset",	(PyCFunction)time_utcoffset,	METH_NOARGS,
+	 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
+
+	{"tzname",	(PyCFunction)time_tzname,	METH_NOARGS,
+	 PyDoc_STR("Return self.tzinfo.tzname(self).")},
+
+	{"dst",		(PyCFunction)time_dst,		METH_NOARGS,
+	 PyDoc_STR("Return self.tzinfo.dst(self).")},
+
+	{"replace",     (PyCFunction)time_replace,	METH_KEYWORDS,
+	 PyDoc_STR("Return time with new specified fields.")},
+
+	{"__reduce__", (PyCFunction)time_reduce,        METH_NOARGS,
+	 PyDoc_STR("__reduce__() -> (cls, state)")},
+
+	{NULL,	NULL}
+};
+
+static char time_doc[] =
+PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
+\n\
+All arguments are optional. tzinfo may be None, or an instance of\n\
+a tzinfo subclass. The remaining arguments may be ints or longs.\n");
+
+static PyNumberMethods time_as_number = {
+	0,					/* nb_add */
+	0,					/* nb_subtract */
+	0,					/* nb_multiply */
+	0,					/* nb_divide */
+	0,					/* nb_remainder */
+	0,					/* nb_divmod */
+	0,					/* nb_power */
+	0,					/* nb_negative */
+	0,					/* nb_positive */
+	0,					/* nb_absolute */
+	(inquiry)time_nonzero,			/* nb_nonzero */
+};
+
+statichere PyTypeObject PyDateTime_TimeType = {
+	PyObject_HEAD_INIT(NULL)
+	0,					/* ob_size */
+	"datetime.time",			/* tp_name */
+	sizeof(PyDateTime_Time),		/* tp_basicsize */
+	0,					/* tp_itemsize */
+	(destructor)time_dealloc,		/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	(reprfunc)time_repr,			/* tp_repr */
+	&time_as_number,			/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	(hashfunc)time_hash,			/* tp_hash */
+	0,              			/* tp_call */
+	(reprfunc)time_str,			/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
+        Py_TPFLAGS_BASETYPE,			/* tp_flags */
+	time_doc,				/* tp_doc */
+	0,					/* tp_traverse */
+	0,					/* tp_clear */
+	(richcmpfunc)time_richcompare,		/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	time_methods,				/* tp_methods */
+	0,					/* tp_members */
+	time_getset,				/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	0,					/* tp_init */
+	time_alloc,				/* tp_alloc */
+	time_new,				/* tp_new */
+	0,					/* tp_free */
+};
+
+/*
+ * PyDateTime_DateTime implementation.
+ */
+
+/* Accessor properties.  Properties for day, month, and year are inherited
+ * from date.
+ */
+
+static PyObject *
+datetime_hour(PyDateTime_DateTime *self, void *unused)
+{
+	return PyInt_FromLong(DATE_GET_HOUR(self));
+}
+
+static PyObject *
+datetime_minute(PyDateTime_DateTime *self, void *unused)
+{
+	return PyInt_FromLong(DATE_GET_MINUTE(self));
+}
+
+static PyObject *
+datetime_second(PyDateTime_DateTime *self, void *unused)
+{
+	return PyInt_FromLong(DATE_GET_SECOND(self));
+}
+
+static PyObject *
+datetime_microsecond(PyDateTime_DateTime *self, void *unused)
+{
+	return PyInt_FromLong(DATE_GET_MICROSECOND(self));
+}
+
+static PyObject *
+datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
+{
+	PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
+	Py_INCREF(result);
+	return result;
+}
+
+static PyGetSetDef datetime_getset[] = {
+	{"hour",        (getter)datetime_hour},
+	{"minute",      (getter)datetime_minute},
+	{"second",      (getter)datetime_second},
+	{"microsecond", (getter)datetime_microsecond},
+	{"tzinfo",	(getter)datetime_tzinfo},
+	{NULL}
+};
+
+/*
+ * Constructors.
+ */
+
+static char *datetime_kws[] = {
+	"year", "month", "day", "hour", "minute", "second",
+	"microsecond", "tzinfo", NULL
+};
+
+static PyObject *
+datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
+{
+	PyObject *self = NULL;
+	PyObject *state;
+	int year;
+	int month;
+	int day;
+	int hour = 0;
+	int minute = 0;
+	int second = 0;
+	int usecond = 0;
+	PyObject *tzinfo = Py_None;
+
+	/* Check for invocation from pickle with __getstate__ state */
+	if (PyTuple_GET_SIZE(args) >= 1 &&
+	    PyTuple_GET_SIZE(args) <= 2 &&
+	    PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
+	    PyString_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
+	    MONTH_IS_SANE(PyString_AS_STRING(state)[2]))
+	{
+		PyDateTime_DateTime *me;
+		char aware;
+
+		if (PyTuple_GET_SIZE(args) == 2) {
+			tzinfo = PyTuple_GET_ITEM(args, 1);
+			if (check_tzinfo_subclass(tzinfo) < 0) {
+				PyErr_SetString(PyExc_TypeError, "bad "
+					"tzinfo state arg");
+				return NULL;
+			}
+		}
+		aware = (char)(tzinfo != Py_None);
+		me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
+		if (me != NULL) {
+			char *pdata = PyString_AS_STRING(state);
+
+			memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
+			me->hashcode = -1;
+			me->hastzinfo = aware;
+			if (aware) {
+				Py_INCREF(tzinfo);
+				me->tzinfo = tzinfo;
+			}
+		}
+		return (PyObject *)me;
+	}
+
+	if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", datetime_kws,
+					&year, &month, &day, &hour, &minute,
+					&second, &usecond, &tzinfo)) {
+		if (check_date_args(year, month, day) < 0)
+			return NULL;
+		if (check_time_args(hour, minute, second, usecond) < 0)
+			return NULL;
+		if (check_tzinfo_subclass(tzinfo) < 0)
+			return NULL;
+		self = new_datetime_ex(year, month, day,
+				    	hour, minute, second, usecond,
+				    	tzinfo, type);
+	}
+	return self;
+}
+
+/* TM_FUNC is the shared type of localtime() and gmtime(). */
+typedef struct tm *(*TM_FUNC)(const time_t *timer);
+
+/* Internal helper.
+ * Build datetime from a time_t and a distinct count of microseconds.
+ * Pass localtime or gmtime for f, to control the interpretation of timet.
+ */
+static PyObject *
+datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
+			   PyObject *tzinfo)
+{
+	struct tm *tm;
+	PyObject *result = NULL;
+
+	tm = f(&timet);
+	if (tm) {
+		/* The platform localtime/gmtime may insert leap seconds,
+		 * indicated by tm->tm_sec > 59.  We don't care about them,
+		 * except to the extent that passing them on to the datetime
+		 * constructor would raise ValueError for a reason that
+		 * made no sense to the user.
+		 */
+		if (tm->tm_sec > 59)
+			tm->tm_sec = 59;
+		result = PyObject_CallFunction(cls, "iiiiiiiO",
+					       tm->tm_year + 1900,
+					       tm->tm_mon + 1,
+					       tm->tm_mday,
+					       tm->tm_hour,
+					       tm->tm_min,
+					       tm->tm_sec,
+					       us,
+					       tzinfo);
+	}
+	else
+		PyErr_SetString(PyExc_ValueError,
+				"timestamp out of range for "
+				"platform localtime()/gmtime() function");
+	return result;
+}
+
+/* Internal helper.
+ * Build datetime from a Python timestamp.  Pass localtime or gmtime for f,
+ * to control the interpretation of the timestamp.  Since a double doesn't
+ * have enough bits to cover a datetime's full range of precision, it's
+ * better to call datetime_from_timet_and_us provided you have a way
+ * to get that much precision (e.g., C time() isn't good enough).
+ */
+static PyObject *
+datetime_from_timestamp(PyObject *cls, TM_FUNC f, double timestamp,
+			PyObject *tzinfo)
+{
+	time_t timet;
+	double fraction;
+	int us;
+
+	timet = _PyTime_DoubleToTimet(timestamp);
+	if (timet == (time_t)-1 && PyErr_Occurred())
+		return NULL;
+	fraction = timestamp - (double)timet;
+	us = (int)round_to_long(fraction * 1e6);
+	if (us < 0) {
+		/* Truncation towards zero is not what we wanted
+		   for negative numbers (Python's mod semantics) */
+		timet -= 1;
+		us += 1000000;
+	}
+	/* If timestamp is less than one microsecond smaller than a
+	 * full second, round up. Otherwise, ValueErrors are raised
+	 * for some floats. */
+	if (us == 1000000) {
+		timet += 1;
+		us = 0;
+	}
+	return datetime_from_timet_and_us(cls, f, timet, us, tzinfo);
+}
+
+/* Internal helper.
+ * Build most accurate possible datetime for current time.  Pass localtime or
+ * gmtime for f as appropriate.
+ */
+static PyObject *
+datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
+{
+#ifdef HAVE_GETTIMEOFDAY
+	struct timeval t;
+
+#ifdef GETTIMEOFDAY_NO_TZ
+	gettimeofday(&t);
+#else
+	gettimeofday(&t, (struct timezone *)NULL);
+#endif
+	return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec,
+					  tzinfo);
+
+#else	/* ! HAVE_GETTIMEOFDAY */
+	/* No flavor of gettimeofday exists on this platform.  Python's
+	 * time.time() does a lot of other platform tricks to get the
+	 * best time it can on the platform, and we're not going to do
+	 * better than that (if we could, the better code would belong
+	 * in time.time()!)  We're limited by the precision of a double,
+	 * though.
+	 */
+	PyObject *time;
+	double dtime;
+
+	time = time_time();
+    	if (time == NULL)
+    		return NULL;
+	dtime = PyFloat_AsDouble(time);
+	Py_DECREF(time);
+	if (dtime == -1.0 && PyErr_Occurred())
+		return NULL;
+	return datetime_from_timestamp(cls, f, dtime, tzinfo);
+#endif	/* ! HAVE_GETTIMEOFDAY */
+}
+
+/* Return best possible local time -- this isn't constrained by the
+ * precision of a timestamp.
+ */
+static PyObject *
+datetime_now(PyObject *cls, PyObject *args, PyObject *kw)
+{
+	PyObject *self;
+	PyObject *tzinfo = Py_None;
+	static char *keywords[] = {"tz", NULL};
+
+	if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:now", keywords,
+					  &tzinfo))
+		return NULL;
+	if (check_tzinfo_subclass(tzinfo) < 0)
+		return NULL;
+
+	self = datetime_best_possible(cls,
+				      tzinfo == Py_None ? localtime : gmtime,
+				      tzinfo);
+	if (self != NULL && tzinfo != Py_None) {
+		/* Convert UTC to tzinfo's zone. */
+		PyObject *temp = self;
+		self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
+		Py_DECREF(temp);
+	}
+	return self;
+}
+
+/* Return best possible UTC time -- this isn't constrained by the
+ * precision of a timestamp.
+ */
+static PyObject *
+datetime_utcnow(PyObject *cls, PyObject *dummy)
+{
+	return datetime_best_possible(cls, gmtime, Py_None);
+}
+
+/* Return new local datetime from timestamp (Python timestamp -- a double). */
+static PyObject *
+datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
+{
+	PyObject *self;
+	double timestamp;
+	PyObject *tzinfo = Py_None;
+	static char *keywords[] = {"timestamp", "tz", NULL};
+
+	if (! PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp",
+					  keywords, &timestamp, &tzinfo))
+		return NULL;
+	if (check_tzinfo_subclass(tzinfo) < 0)
+		return NULL;
+
+	self = datetime_from_timestamp(cls,
+				       tzinfo == Py_None ? localtime : gmtime,
+				       timestamp,
+				       tzinfo);
+	if (self != NULL && tzinfo != Py_None) {
+		/* Convert UTC to tzinfo's zone. */
+		PyObject *temp = self;
+		self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
+		Py_DECREF(temp);
+	}
+	return self;
+}
+
+/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
+static PyObject *
+datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
+{
+	double timestamp;
+	PyObject *result = NULL;
+
+	if (PyArg_ParseTuple(args, "d:utcfromtimestamp", &timestamp))
+		result = datetime_from_timestamp(cls, gmtime, timestamp,
+						 Py_None);
+	return result;
+}
+
+/* Return new datetime from time.strptime(). */
+static PyObject *
+datetime_strptime(PyObject *cls, PyObject *args)
+{
+	PyObject *result = NULL, *obj, *module;
+	const char *string, *format;
+
+	if (!PyArg_ParseTuple(args, "ss:strptime", &string, &format))
+		return NULL;
+
+	if ((module = PyImport_ImportModule("time")) == NULL)
+		return NULL;
+	obj = PyObject_CallMethod(module, "strptime", "ss", string, format);
+	Py_DECREF(module);
+
+	if (obj != NULL) {
+		int i, good_timetuple = 1;
+		long int ia[6];
+		if (PySequence_Check(obj) && PySequence_Size(obj) >= 6)
+			for (i=0; i < 6; i++) {
+				PyObject *p = PySequence_GetItem(obj, i);
+				if (p == NULL) {
+					Py_DECREF(obj);
+					return NULL;
+				}
+				if (PyInt_Check(p))
+					ia[i] = PyInt_AsLong(p);
+				else
+					good_timetuple = 0;
+				Py_DECREF(p);
+			}
+		else
+			good_timetuple = 0;
+		if (good_timetuple)
+			result = PyObject_CallFunction(cls, "iiiiii",
+				ia[0], ia[1], ia[2], ia[3], ia[4], ia[5]);
+		else
+			PyErr_SetString(PyExc_ValueError,
+				"unexpected value from time.strptime");
+		Py_DECREF(obj);
+	}
+	return result;
+}
+
+/* Return new datetime from date/datetime and time arguments. */
+static PyObject *
+datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
+{
+ 	static char *keywords[] = {"date", "time", NULL};
+	PyObject *date;
+	PyObject *time;
+	PyObject *result = NULL;
+
+	if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
+					&PyDateTime_DateType, &date,
+					&PyDateTime_TimeType, &time)) {
+		PyObject *tzinfo = Py_None;
+
+		if (HASTZINFO(time))
+			tzinfo = ((PyDateTime_Time *)time)->tzinfo;
+		result = PyObject_CallFunction(cls, "iiiiiiiO",
+						GET_YEAR(date),
+				    		GET_MONTH(date),
+						GET_DAY(date),
+				    		TIME_GET_HOUR(time),
+				    		TIME_GET_MINUTE(time),
+				    		TIME_GET_SECOND(time),
+				    		TIME_GET_MICROSECOND(time),
+				    		tzinfo);
+	}
+	return result;
+}
+
+/*
+ * Destructor.
+ */
+
+static void
+datetime_dealloc(PyDateTime_DateTime *self)
+{
+	if (HASTZINFO(self)) {
+		Py_XDECREF(self->tzinfo);
+	}
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+/*
+ * Indirect access to tzinfo methods.
+ */
+
+/* These are all METH_NOARGS, so don't need to check the arglist. */
+static PyObject *
+datetime_utcoffset(PyDateTime_DateTime *self, PyObject *unused) {
+	return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
+				   "utcoffset", (PyObject *)self);
+}
+
+static PyObject *
+datetime_dst(PyDateTime_DateTime *self, PyObject *unused) {
+	return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
+				   "dst", (PyObject *)self);
+}
+
+static PyObject *
+datetime_tzname(PyDateTime_DateTime *self, PyObject *unused) {
+	return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
+			   (PyObject *)self);
+}
+
+/*
+ * datetime arithmetic.
+ */
+
+/* factor must be 1 (to add) or -1 (to subtract).  The result inherits
+ * the tzinfo state of date.
+ */
+static PyObject *
+add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
+		       int factor)
+{
+	/* Note that the C-level additions can't overflow, because of
+	 * invariant bounds on the member values.
+	 */
+	int year = GET_YEAR(date);
+	int month = GET_MONTH(date);
+	int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
+	int hour = DATE_GET_HOUR(date);
+	int minute = DATE_GET_MINUTE(date);
+	int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
+	int microsecond = DATE_GET_MICROSECOND(date) +
+			  GET_TD_MICROSECONDS(delta) * factor;
+
+	assert(factor == 1 || factor == -1);
+	if (normalize_datetime(&year, &month, &day,
+			       &hour, &minute, &second, &microsecond) < 0)
+		return NULL;
+	else
+		return new_datetime(year, month, day,
+				    hour, minute, second, microsecond,
+				    HASTZINFO(date) ? date->tzinfo : Py_None);
+}
+
+static PyObject *
+datetime_add(PyObject *left, PyObject *right)
+{
+	if (PyDateTime_Check(left)) {
+		/* datetime + ??? */
+		if (PyDelta_Check(right))
+			/* datetime + delta */
+			return add_datetime_timedelta(
+					(PyDateTime_DateTime *)left,
+					(PyDateTime_Delta *)right,
+					1);
+	}
+	else if (PyDelta_Check(left)) {
+		/* delta + datetime */
+		return add_datetime_timedelta((PyDateTime_DateTime *) right,
+					      (PyDateTime_Delta *) left,
+					      1);
+	}
+	Py_INCREF(Py_NotImplemented);
+	return Py_NotImplemented;
+}
+
+static PyObject *
+datetime_subtract(PyObject *left, PyObject *right)
+{
+	PyObject *result = Py_NotImplemented;
+
+	if (PyDateTime_Check(left)) {
+		/* datetime - ??? */
+		if (PyDateTime_Check(right)) {
+			/* datetime - datetime */
+			naivety n1, n2;
+			int offset1, offset2;
+			int delta_d, delta_s, delta_us;
+
+			if (classify_two_utcoffsets(left, &offset1, &n1, left,
+						    right, &offset2, &n2,
+						    right) < 0)
+				return NULL;
+			assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
+			if (n1 != n2) {
+				PyErr_SetString(PyExc_TypeError,
+					"can't subtract offset-naive and "
+					"offset-aware datetimes");
+				return NULL;
+			}
+			delta_d = ymd_to_ord(GET_YEAR(left),
+					     GET_MONTH(left),
+					     GET_DAY(left)) -
+				  ymd_to_ord(GET_YEAR(right),
+					     GET_MONTH(right),
+					     GET_DAY(right));
+			/* These can't overflow, since the values are
+			 * normalized.  At most this gives the number of
+			 * seconds in one day.
+			 */
+			delta_s = (DATE_GET_HOUR(left) -
+				   DATE_GET_HOUR(right)) * 3600 +
+			          (DATE_GET_MINUTE(left) -
+			           DATE_GET_MINUTE(right)) * 60 +
+				  (DATE_GET_SECOND(left) -
+				   DATE_GET_SECOND(right));
+			delta_us = DATE_GET_MICROSECOND(left) -
+				   DATE_GET_MICROSECOND(right);
+			/* (left - offset1) - (right - offset2) =
+			 * (left - right) + (offset2 - offset1)
+			 */
+			delta_s += (offset2 - offset1) * 60;
+			result = new_delta(delta_d, delta_s, delta_us, 1);
+		}
+		else if (PyDelta_Check(right)) {
+			/* datetime - delta */
+			result = add_datetime_timedelta(
+					(PyDateTime_DateTime *)left,
+					(PyDateTime_Delta *)right,
+					-1);
+		}
+	}
+
+	if (result == Py_NotImplemented)
+		Py_INCREF(result);
+	return result;
+}
+
+/* Various ways to turn a datetime into a string. */
+
+static PyObject *
+datetime_repr(PyDateTime_DateTime *self)
+{
+	char buffer[1000];
+	const char *type_name = self->ob_type->tp_name;
+	PyObject *baserepr;
+
+	if (DATE_GET_MICROSECOND(self)) {
+		PyOS_snprintf(buffer, sizeof(buffer),
+			      "%s(%d, %d, %d, %d, %d, %d, %d)",
+			      type_name,
+			      GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
+			      DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
+			      DATE_GET_SECOND(self),
+			      DATE_GET_MICROSECOND(self));
+	}
+	else if (DATE_GET_SECOND(self)) {
+		PyOS_snprintf(buffer, sizeof(buffer),
+			      "%s(%d, %d, %d, %d, %d, %d)",
+			      type_name,
+			      GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
+			      DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
+			      DATE_GET_SECOND(self));
+	}
+	else {
+		PyOS_snprintf(buffer, sizeof(buffer),
+			      "%s(%d, %d, %d, %d, %d)",
+			      type_name,
+			      GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
+			      DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
+	}
+	baserepr = PyString_FromString(buffer);
+	if (baserepr == NULL || ! HASTZINFO(self))
+		return baserepr;
+	return append_keyword_tzinfo(baserepr, self->tzinfo);
+}
+
+static PyObject *
+datetime_str(PyDateTime_DateTime *self)
+{
+	return PyObject_CallMethod((PyObject *)self, "isoformat", "(s)", " ");
+}
+
+static PyObject *
+datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
+{
+	char sep = 'T';
+	static char *keywords[] = {"sep", NULL};
+	char buffer[100];
+	char *cp;
+	PyObject *result;
+
+	if (!PyArg_ParseTupleAndKeywords(args, kw, "|c:isoformat", keywords,
+					 &sep))
+		return NULL;
+	cp = isoformat_date((PyDateTime_Date *)self, buffer, sizeof(buffer));
+	assert(cp != NULL);
+	*cp++ = sep;
+	isoformat_time(self, cp, sizeof(buffer) - (cp - buffer));
+	result = PyString_FromString(buffer);
+	if (result == NULL || ! HASTZINFO(self))
+		return result;
+
+	/* We need to append the UTC offset. */
+	if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
+			     (PyObject *)self) < 0) {
+		Py_DECREF(result);
+		return NULL;
+	}
+	PyString_ConcatAndDel(&result, PyString_FromString(buffer));
+	return result;
+}
+
+static PyObject *
+datetime_ctime(PyDateTime_DateTime *self)
+{
+	return format_ctime((PyDateTime_Date *)self,
+			    DATE_GET_HOUR(self),
+			    DATE_GET_MINUTE(self),
+			    DATE_GET_SECOND(self));
+}
+
+/* Miscellaneous methods. */
+
+/* This is more natural as a tp_compare, but doesn't work then:  for whatever
+ * reason, Python's try_3way_compare ignores tp_compare unless
+ * PyInstance_Check returns true, but these aren't old-style classes.
+ */
+static PyObject *
+datetime_richcompare(PyDateTime_DateTime *self, PyObject *other, int op)
+{
+	int diff;
+	naivety n1, n2;
+	int offset1, offset2;
+
+	if (! PyDateTime_Check(other)) {
+		/* If other has a "timetuple" attr, that's an advertised
+		 * hook for other classes to ask to get comparison control.
+		 * However, date instances have a timetuple attr, and we
+		 * don't want to allow that comparison.  Because datetime
+		 * is a subclass of date, when mixing date and datetime
+		 * in a comparison, Python gives datetime the first shot
+		 * (it's the more specific subtype).  So we can stop that
+		 * combination here reliably.
+		 */
+		if (PyObject_HasAttrString(other, "timetuple") &&
+		    ! PyDate_Check(other)) {
+			/* A hook for other kinds of datetime objects. */
+			Py_INCREF(Py_NotImplemented);
+			return Py_NotImplemented;
+		}
+		if (op == Py_EQ || op == Py_NE) {
+			PyObject *result = op == Py_EQ ? Py_False : Py_True;
+			Py_INCREF(result);
+			return result;
+		}
+		/* Stop this from falling back to address comparison. */
+		return cmperror((PyObject *)self, other);
+	}
+
+	if (classify_two_utcoffsets((PyObject *)self, &offset1, &n1,
+				    (PyObject *)self,
+				     other, &offset2, &n2,
+				     other) < 0)
+		return NULL;
+	assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
+ 	/* If they're both naive, or both aware and have the same offsets,
+	 * we get off cheap.  Note that if they're both naive, offset1 ==
+	 * offset2 == 0 at this point.
+	 */
+	if (n1 == n2 && offset1 == offset2) {
+		diff = memcmp(self->data, ((PyDateTime_DateTime *)other)->data,
+			      _PyDateTime_DATETIME_DATASIZE);
+		return diff_to_bool(diff, op);
+	}
+
+	if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
+		PyDateTime_Delta *delta;
+
+		assert(offset1 != offset2);	/* else last "if" handled it */
+		delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
+							       other);
+		if (delta == NULL)
+			return NULL;
+		diff = GET_TD_DAYS(delta);
+		if (diff == 0)
+			diff = GET_TD_SECONDS(delta) |
+			       GET_TD_MICROSECONDS(delta);
+		Py_DECREF(delta);
+		return diff_to_bool(diff, op);
+	}
+
+	assert(n1 != n2);
+	PyErr_SetString(PyExc_TypeError,
+			"can't compare offset-naive and "
+			"offset-aware datetimes");
+	return NULL;
+}
+
+static long
+datetime_hash(PyDateTime_DateTime *self)
+{
+	if (self->hashcode == -1) {
+		naivety n;
+		int offset;
+		PyObject *temp;
+
+		n = classify_utcoffset((PyObject *)self, (PyObject *)self,
+				       &offset);
+		assert(n != OFFSET_UNKNOWN);
+		if (n == OFFSET_ERROR)
+			return -1;
+
+		/* Reduce this to a hash of another object. */
+		if (n == OFFSET_NAIVE)
+			temp = PyString_FromStringAndSize(
+					(char *)self->data,
+					_PyDateTime_DATETIME_DATASIZE);
+		else {
+			int days;
+			int seconds;
+
+			assert(n == OFFSET_AWARE);
+			assert(HASTZINFO(self));
+			days = ymd_to_ord(GET_YEAR(self),
+					  GET_MONTH(self),
+					  GET_DAY(self));
+			seconds = DATE_GET_HOUR(self) * 3600 +
+				  (DATE_GET_MINUTE(self) - offset) * 60 +
+				  DATE_GET_SECOND(self);
+			temp = new_delta(days,
+					 seconds,
+					 DATE_GET_MICROSECOND(self),
+					 1);
+		}
+		if (temp != NULL) {
+			self->hashcode = PyObject_Hash(temp);
+			Py_DECREF(temp);
+		}
+	}
+	return self->hashcode;
+}
+
+static PyObject *
+datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
+{
+	PyObject *clone;
+	PyObject *tuple;
+	int y = GET_YEAR(self);
+	int m = GET_MONTH(self);
+	int d = GET_DAY(self);
+	int hh = DATE_GET_HOUR(self);
+	int mm = DATE_GET_MINUTE(self);
+	int ss = DATE_GET_SECOND(self);
+	int us = DATE_GET_MICROSECOND(self);
+	PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
+
+	if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO:replace",
+					  datetime_kws,
+					  &y, &m, &d, &hh, &mm, &ss, &us,
+					  &tzinfo))
+		return NULL;
+	tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
+	if (tuple == NULL)
+		return NULL;
+	clone = datetime_new(self->ob_type, tuple, NULL);
+	Py_DECREF(tuple);
+	return clone;
+}
+
+static PyObject *
+datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
+{
+	int y, m, d, hh, mm, ss, us;
+	PyObject *result;
+	int offset, none;
+
+	PyObject *tzinfo;
+	static char *keywords[] = {"tz", NULL};
+
+	if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:astimezone", keywords,
+					  &PyDateTime_TZInfoType, &tzinfo))
+		return NULL;
+
+        if (!HASTZINFO(self) || self->tzinfo == Py_None)
+        	goto NeedAware;
+
+        /* Conversion to self's own time zone is a NOP. */
+	if (self->tzinfo == tzinfo) {
+		Py_INCREF(self);
+		return (PyObject *)self;
+	}
+
+        /* Convert self to UTC. */
+        offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
+        if (offset == -1 && PyErr_Occurred())
+        	return NULL;
+        if (none)
+        	goto NeedAware;
+
+	y = GET_YEAR(self);
+	m = GET_MONTH(self);
+	d = GET_DAY(self);
+	hh = DATE_GET_HOUR(self);
+	mm = DATE_GET_MINUTE(self);
+	ss = DATE_GET_SECOND(self);
+	us = DATE_GET_MICROSECOND(self);
+
+	mm -= offset;
+	if ((mm < 0 || mm >= 60) &&
+	    normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
+		return NULL;
+
+	/* Attach new tzinfo and let fromutc() do the rest. */
+	result = new_datetime(y, m, d, hh, mm, ss, us, tzinfo);
+	if (result != NULL) {
+		PyObject *temp = result;
+
+		result = PyObject_CallMethod(tzinfo, "fromutc", "O", temp);
+		Py_DECREF(temp);
+	}
+	return result;
+
+NeedAware:
+	PyErr_SetString(PyExc_ValueError, "astimezone() cannot be applied to "
+					  "a naive datetime");
+	return NULL;
+}
+
+static PyObject *
+datetime_timetuple(PyDateTime_DateTime *self)
+{
+	int dstflag = -1;
+
+	if (HASTZINFO(self) && self->tzinfo != Py_None) {
+		int none;
+
+		dstflag = call_dst(self->tzinfo, (PyObject *)self, &none);
+		if (dstflag == -1 && PyErr_Occurred())
+			return NULL;
+
+		if (none)
+			dstflag = -1;
+		else if (dstflag != 0)
+			dstflag = 1;
+
+	}
+	return build_struct_time(GET_YEAR(self),
+				 GET_MONTH(self),
+				 GET_DAY(self),
+				 DATE_GET_HOUR(self),
+				 DATE_GET_MINUTE(self),
+				 DATE_GET_SECOND(self),
+				 dstflag);
+}
+
+static PyObject *
+datetime_getdate(PyDateTime_DateTime *self)
+{
+	return new_date(GET_YEAR(self),
+			GET_MONTH(self),
+			GET_DAY(self));
+}
+
+static PyObject *
+datetime_gettime(PyDateTime_DateTime *self)
+{
+	return new_time(DATE_GET_HOUR(self),
+			DATE_GET_MINUTE(self),
+			DATE_GET_SECOND(self),
+			DATE_GET_MICROSECOND(self),
+			Py_None);
+}
+
+static PyObject *
+datetime_gettimetz(PyDateTime_DateTime *self)
+{
+	return new_time(DATE_GET_HOUR(self),
+			DATE_GET_MINUTE(self),
+			DATE_GET_SECOND(self),
+			DATE_GET_MICROSECOND(self),
+			HASTZINFO(self) ? self->tzinfo : Py_None);
+}
+
+static PyObject *
+datetime_utctimetuple(PyDateTime_DateTime *self)
+{
+	int y = GET_YEAR(self);
+	int m = GET_MONTH(self);
+	int d = GET_DAY(self);
+	int hh = DATE_GET_HOUR(self);
+	int mm = DATE_GET_MINUTE(self);
+	int ss = DATE_GET_SECOND(self);
+	int us = 0;	/* microseconds are ignored in a timetuple */
+	int offset = 0;
+
+	if (HASTZINFO(self) && self->tzinfo != Py_None) {
+		int none;
+
+		offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
+		if (offset == -1 && PyErr_Occurred())
+			return NULL;
+	}
+	/* Even if offset is 0, don't call timetuple() -- tm_isdst should be
+	 * 0 in a UTC timetuple regardless of what dst() says.
+	 */
+	if (offset) {
+		/* Subtract offset minutes & normalize. */
+		int stat;
+
+		mm -= offset;
+		stat = normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us);
+		if (stat < 0) {
+			/* At the edges, it's possible we overflowed
+			 * beyond MINYEAR or MAXYEAR.
+			 */
+			if (PyErr_ExceptionMatches(PyExc_OverflowError))
+				PyErr_Clear();
+			else
+				return NULL;
+		}
+	}
+	return build_struct_time(y, m, d, hh, mm, ss, 0);
+}
+
+/* Pickle support, a simple use of __reduce__. */
+
+/* Let basestate be the non-tzinfo data string.
+ * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
+ * So it's a tuple in any (non-error) case.
+ * __getstate__ isn't exposed.
+ */
+static PyObject *
+datetime_getstate(PyDateTime_DateTime *self)
+{
+	PyObject *basestate;
+	PyObject *result = NULL;
+
+	basestate = PyString_FromStringAndSize((char *)self->data,
+					  _PyDateTime_DATETIME_DATASIZE);
+	if (basestate != NULL) {
+		if (! HASTZINFO(self) || self->tzinfo == Py_None)
+			result = PyTuple_Pack(1, basestate);
+		else
+			result = PyTuple_Pack(2, basestate, self->tzinfo);
+		Py_DECREF(basestate);
+	}
+	return result;
+}
+
+static PyObject *
+datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
+{
+	return Py_BuildValue("(ON)", self->ob_type, datetime_getstate(self));
+}
+
+static PyMethodDef datetime_methods[] = {
+
+	/* Class methods: */
+
+	{"now",         (PyCFunction)datetime_now,
+	 METH_KEYWORDS | METH_CLASS,
+	 PyDoc_STR("[tz] -> new datetime with tz's local day and time.")},
+
+	{"utcnow",         (PyCFunction)datetime_utcnow,
+	 METH_NOARGS | METH_CLASS,
+	 PyDoc_STR("Return a new datetime representing UTC day and time.")},
+
+	{"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
+	 METH_KEYWORDS | METH_CLASS,
+	 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
+
+	{"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
+	 METH_VARARGS | METH_CLASS,
+	 PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
+	 	   "(like time.time()).")},
+
+	{"strptime", (PyCFunction)datetime_strptime,
+	 METH_VARARGS | METH_CLASS,
+	 PyDoc_STR("string, format -> new datetime parsed from a string "
+	 	   "(like time.strptime()).")},
+
+	{"combine", (PyCFunction)datetime_combine,
+	 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
+	 PyDoc_STR("date, time -> datetime with same date and time fields")},
+
+	/* Instance methods: */
+
+	{"date",   (PyCFunction)datetime_getdate, METH_NOARGS,
+         PyDoc_STR("Return date object with same year, month and day.")},
+
+	{"time",   (PyCFunction)datetime_gettime, METH_NOARGS,
+         PyDoc_STR("Return time object with same time but with tzinfo=None.")},
+
+	{"timetz",   (PyCFunction)datetime_gettimetz, METH_NOARGS,
+         PyDoc_STR("Return time object with same time and tzinfo.")},
+
+	{"ctime",       (PyCFunction)datetime_ctime,	METH_NOARGS,
+	 PyDoc_STR("Return ctime() style string.")},
+
+	{"timetuple",   (PyCFunction)datetime_timetuple, METH_NOARGS,
+         PyDoc_STR("Return time tuple, compatible with time.localtime().")},
+
+	{"utctimetuple",   (PyCFunction)datetime_utctimetuple, METH_NOARGS,
+         PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
+
+	{"isoformat",   (PyCFunction)datetime_isoformat, METH_KEYWORDS,
+	 PyDoc_STR("[sep] -> string in ISO 8601 format, "
+	 	   "YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n"
+	 	   "sep is used to separate the year from the time, and "
+	 	   "defaults to 'T'.")},
+
+	{"utcoffset",	(PyCFunction)datetime_utcoffset, METH_NOARGS,
+	 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
+
+	{"tzname",	(PyCFunction)datetime_tzname,	METH_NOARGS,
+	 PyDoc_STR("Return self.tzinfo.tzname(self).")},
+
+	{"dst",		(PyCFunction)datetime_dst, METH_NOARGS,
+	 PyDoc_STR("Return self.tzinfo.dst(self).")},
+
+	{"replace",     (PyCFunction)datetime_replace,	METH_KEYWORDS,
+	 PyDoc_STR("Return datetime with new specified fields.")},
+
+	{"astimezone",  (PyCFunction)datetime_astimezone, METH_KEYWORDS,
+	 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
+
+	{"__reduce__", (PyCFunction)datetime_reduce,     METH_NOARGS,
+	 PyDoc_STR("__reduce__() -> (cls, state)")},
+
+	{NULL,	NULL}
+};
+
+static char datetime_doc[] =
+PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
+\n\
+The year, month and day arguments are required. tzinfo may be None, or an\n\
+instance of a tzinfo subclass. The remaining arguments may be ints or longs.\n");
+
+static PyNumberMethods datetime_as_number = {
+	datetime_add,				/* nb_add */
+	datetime_subtract,			/* nb_subtract */
+	0,					/* nb_multiply */
+	0,					/* nb_divide */
+	0,					/* nb_remainder */
+	0,					/* nb_divmod */
+	0,					/* nb_power */
+	0,					/* nb_negative */
+	0,					/* nb_positive */
+	0,					/* nb_absolute */
+	0,					/* nb_nonzero */
+};
+
+statichere PyTypeObject PyDateTime_DateTimeType = {
+	PyObject_HEAD_INIT(NULL)
+	0,					/* ob_size */
+	"datetime.datetime",			/* tp_name */
+	sizeof(PyDateTime_DateTime),		/* tp_basicsize */
+	0,					/* tp_itemsize */
+	(destructor)datetime_dealloc,		/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	(reprfunc)datetime_repr,		/* tp_repr */
+	&datetime_as_number,			/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	(hashfunc)datetime_hash,		/* tp_hash */
+	0,              			/* tp_call */
+	(reprfunc)datetime_str,			/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
+        Py_TPFLAGS_BASETYPE,			/* tp_flags */
+	datetime_doc,				/* tp_doc */
+	0,					/* tp_traverse */
+	0,					/* tp_clear */
+	(richcmpfunc)datetime_richcompare,	/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	datetime_methods,			/* tp_methods */
+	0,					/* tp_members */
+	datetime_getset,			/* tp_getset */
+	&PyDateTime_DateType,			/* tp_base */
+	0,					/* tp_dict */
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	0,					/* tp_init */
+	datetime_alloc,				/* tp_alloc */
+	datetime_new,				/* tp_new */
+	0,					/* tp_free */
+};
+
+/* ---------------------------------------------------------------------------
+ * Module methods and initialization.
+ */
+
+static PyMethodDef module_methods[] = {
+	{NULL, NULL}
+};
+
+/* C API.  Clients get at this via PyDateTime_IMPORT, defined in
+ * datetime.h.
+ */
+static PyDateTime_CAPI CAPI = {
+        &PyDateTime_DateType,
+        &PyDateTime_DateTimeType,
+        &PyDateTime_TimeType,
+        &PyDateTime_DeltaType,
+        &PyDateTime_TZInfoType,
+        new_date_ex,
+        new_datetime_ex,
+        new_time_ex,
+        new_delta_ex,
+        datetime_fromtimestamp,
+        date_fromtimestamp
+};
+
+
+PyMODINIT_FUNC
+initdatetime(void)
+{
+	PyObject *m;	/* a module object */
+	PyObject *d;	/* its dict */
+	PyObject *x;
+
+	m = Py_InitModule3("datetime", module_methods,
+			   "Fast implementation of the datetime type.");
+	if (m == NULL)
+		return;
+
+	if (PyType_Ready(&PyDateTime_DateType) < 0)
+		return;
+	if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
+		return;
+	if (PyType_Ready(&PyDateTime_DeltaType) < 0)
+		return;
+	if (PyType_Ready(&PyDateTime_TimeType) < 0)
+		return;
+	if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
+		return;
+
+	/* timedelta values */
+	d = PyDateTime_DeltaType.tp_dict;
+
+	x = new_delta(0, 0, 1, 0);
+	if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
+		return;
+	Py_DECREF(x);
+
+	x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
+	if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
+		return;
+	Py_DECREF(x);
+
+	x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
+	if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
+		return;
+	Py_DECREF(x);
+
+	/* date values */
+	d = PyDateTime_DateType.tp_dict;
+
+	x = new_date(1, 1, 1);
+	if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
+		return;
+	Py_DECREF(x);
+
+	x = new_date(MAXYEAR, 12, 31);
+	if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
+		return;
+	Py_DECREF(x);
+
+	x = new_delta(1, 0, 0, 0);
+	if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
+		return;
+	Py_DECREF(x);
+
+	/* time values */
+	d = PyDateTime_TimeType.tp_dict;
+
+	x = new_time(0, 0, 0, 0, Py_None);
+	if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
+		return;
+	Py_DECREF(x);
+
+	x = new_time(23, 59, 59, 999999, Py_None);
+	if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
+		return;
+	Py_DECREF(x);
+
+	x = new_delta(0, 0, 1, 0);
+	if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
+		return;
+	Py_DECREF(x);
+
+	/* datetime values */
+	d = PyDateTime_DateTimeType.tp_dict;
+
+	x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None);
+	if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
+		return;
+	Py_DECREF(x);
+
+	x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
+	if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
+		return;
+	Py_DECREF(x);
+
+	x = new_delta(0, 0, 1, 0);
+	if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
+		return;
+	Py_DECREF(x);
+
+	/* module initialization */
+	PyModule_AddIntConstant(m, "MINYEAR", MINYEAR);
+	PyModule_AddIntConstant(m, "MAXYEAR", MAXYEAR);
+
+	Py_INCREF(&PyDateTime_DateType);
+	PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
+
+	Py_INCREF(&PyDateTime_DateTimeType);
+	PyModule_AddObject(m, "datetime",
+			   (PyObject *)&PyDateTime_DateTimeType);
+
+	Py_INCREF(&PyDateTime_TimeType);
+	PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
+
+	Py_INCREF(&PyDateTime_DeltaType);
+	PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
+
+	Py_INCREF(&PyDateTime_TZInfoType);
+	PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
+
+        x = PyCObject_FromVoidPtrAndDesc(&CAPI, (void*) DATETIME_API_MAGIC,
+                NULL);
+        if (x == NULL)
+            return;
+        PyModule_AddObject(m, "datetime_CAPI", x);
+
+	/* A 4-year cycle has an extra leap day over what we'd get from
+	 * pasting together 4 single years.
+	 */
+	assert(DI4Y == 4 * 365 + 1);
+	assert(DI4Y == days_before_year(4+1));
+
+	/* Similarly, a 400-year cycle has an extra leap day over what we'd
+	 * get from pasting together 4 100-year cycles.
+	 */
+	assert(DI400Y == 4 * DI100Y + 1);
+	assert(DI400Y == days_before_year(400+1));
+
+	/* OTOH, a 100-year cycle has one fewer leap day than we'd get from
+	 * pasting together 25 4-year cycles.
+	 */
+	assert(DI100Y == 25 * DI4Y - 1);
+	assert(DI100Y == days_before_year(100+1));
+
+	us_per_us = PyInt_FromLong(1);
+	us_per_ms = PyInt_FromLong(1000);
+	us_per_second = PyInt_FromLong(1000000);
+	us_per_minute = PyInt_FromLong(60000000);
+	seconds_per_day = PyInt_FromLong(24 * 3600);
+	if (us_per_us == NULL || us_per_ms == NULL || us_per_second == NULL ||
+	    us_per_minute == NULL || seconds_per_day == NULL)
+		return;
+
+	/* The rest are too big for 32-bit ints, but even
+	 * us_per_week fits in 40 bits, so doubles should be exact.
+	 */
+	us_per_hour = PyLong_FromDouble(3600000000.0);
+	us_per_day = PyLong_FromDouble(86400000000.0);
+	us_per_week = PyLong_FromDouble(604800000000.0);
+	if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
+		return;
+}
+
+/* ---------------------------------------------------------------------------
+Some time zone algebra.  For a datetime x, let
+    x.n = x stripped of its timezone -- its naive time.
+    x.o = x.utcoffset(), and assuming that doesn't raise an exception or
+          return None
+    x.d = x.dst(), and assuming that doesn't raise an exception or
+          return None
+    x.s = x's standard offset, x.o - x.d
+
+Now some derived rules, where k is a duration (timedelta).
+
+1. x.o = x.s + x.d
+   This follows from the definition of x.s.
+
+2. If x and y have the same tzinfo member, x.s = y.s.
+   This is actually a requirement, an assumption we need to make about
+   sane tzinfo classes.
+
+3. The naive UTC time corresponding to x is x.n - x.o.
+   This is again a requirement for a sane tzinfo class.
+
+4. (x+k).s = x.s
+   This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
+
+5. (x+k).n = x.n + k
+   Again follows from how arithmetic is defined.
+
+Now we can explain tz.fromutc(x).  Let's assume it's an interesting case
+(meaning that the various tzinfo methods exist, and don't blow up or return
+None when called).
+
+The function wants to return a datetime y with timezone tz, equivalent to x.
+x is already in UTC.
+
+By #3, we want
+
+    y.n - y.o = x.n                             [1]
+
+The algorithm starts by attaching tz to x.n, and calling that y.  So
+x.n = y.n at the start.  Then it wants to add a duration k to y, so that [1]
+becomes true; in effect, we want to solve [2] for k:
+
+   (y+k).n - (y+k).o = x.n                      [2]
+
+By #1, this is the same as
+
+   (y+k).n - ((y+k).s + (y+k).d) = x.n          [3]
+
+By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
+Substituting that into [3],
+
+   x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
+   k - (y+k).s - (y+k).d = 0; rearranging,
+   k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
+   k = y.s - (y+k).d
+
+On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
+approximate k by ignoring the (y+k).d term at first.  Note that k can't be
+very large, since all offset-returning methods return a duration of magnitude
+less than 24 hours.  For that reason, if y is firmly in std time, (y+k).d must
+be 0, so ignoring it has no consequence then.
+
+In any case, the new value is
+
+    z = y + y.s                                 [4]
+
+It's helpful to step back at look at [4] from a higher level:  it's simply
+mapping from UTC to tz's standard time.
+
+At this point, if
+
+    z.n - z.o = x.n                             [5]
+
+we have an equivalent time, and are almost done.  The insecurity here is
+at the start of daylight time.  Picture US Eastern for concreteness.  The wall
+time jumps from 1:59 to 3:00, and wall hours of the form 2:MM don't make good
+sense then.  The docs ask that an Eastern tzinfo class consider such a time to
+be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
+on the day DST starts.  We want to return the 1:MM EST spelling because that's
+the only spelling that makes sense on the local wall clock.
+
+In fact, if [5] holds at this point, we do have the standard-time spelling,
+but that takes a bit of proof.  We first prove a stronger result.  What's the
+difference between the LHS and RHS of [5]?  Let
+
+    diff = x.n - (z.n - z.o)                    [6]
+
+Now
+    z.n =                       by [4]
+    (y + y.s).n =               by #5
+    y.n + y.s =                 since y.n = x.n
+    x.n + y.s =                 since z and y are have the same tzinfo member,
+                                    y.s = z.s by #2
+    x.n + z.s
+
+Plugging that back into [6] gives
+
+    diff =
+    x.n - ((x.n + z.s) - z.o) =     expanding
+    x.n - x.n - z.s + z.o =         cancelling
+    - z.s + z.o =                   by #2
+    z.d
+
+So diff = z.d.
+
+If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
+spelling we wanted in the endcase described above.  We're done.  Contrarily,
+if z.d = 0, then we have a UTC equivalent, and are also done.
+
+If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
+add to z (in effect, z is in tz's standard time, and we need to shift the
+local clock into tz's daylight time).
+
+Let
+
+    z' = z + z.d = z + diff                     [7]
+
+and we can again ask whether
+
+    z'.n - z'.o = x.n                           [8]
+
+If so, we're done.  If not, the tzinfo class is insane, according to the
+assumptions we've made.  This also requires a bit of proof.  As before, let's
+compute the difference between the LHS and RHS of [8] (and skipping some of
+the justifications for the kinds of substitutions we've done several times
+already):
+
+    diff' = x.n - (z'.n - z'.o) =           replacing z'.n via [7]
+            x.n  - (z.n + diff - z'.o) =    replacing diff via [6]
+            x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
+            x.n - z.n - x.n + z.n - z.o + z'.o =    cancel x.n
+            - z.n + z.n - z.o + z'.o =              cancel z.n
+            - z.o + z'.o =                      #1 twice
+            -z.s - z.d + z'.s + z'.d =          z and z' have same tzinfo
+            z'.d - z.d
+
+So z' is UTC-equivalent to x iff z'.d = z.d at this point.  If they are equal,
+we've found the UTC-equivalent so are done.  In fact, we stop with [7] and
+return z', not bothering to compute z'.d.
+
+How could z.d and z'd differ?  z' = z + z.d [7], so merely moving z' by
+a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
+would have to change the result dst() returns:  we start in DST, and moving
+a little further into it takes us out of DST.
+
+There isn't a sane case where this can happen.  The closest it gets is at
+the end of DST, where there's an hour in UTC with no spelling in a hybrid
+tzinfo class.  In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT.  During
+that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
+UTC) because the docs insist on that, but 0:MM is taken as being in daylight
+time (4:MM UTC).  There is no local time mapping to 5:MM UTC.  The local
+clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
+standard time.  Since that's what the local clock *does*, we want to map both
+UTC hours 5:MM and 6:MM to 1:MM Eastern.  The result is ambiguous
+in local time, but so it goes -- it's the way the local clock works.
+
+When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
+so z=0:MM.  z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
+z' = z + z.d = 1:MM then, and z'.d=0, and z'.d - z.d = -60 != 0 so [8]
+(correctly) concludes that z' is not UTC-equivalent to x.
+
+Because we know z.d said z was in daylight time (else [5] would have held and
+we would have stopped then), and we know z.d != z'.d (else [8] would have held
+and we would have stopped then), and there are only 2 possible values dst() can
+return in Eastern, it follows that z'.d must be 0 (which it is in the example,
+but the reasoning doesn't depend on the example -- it depends on there being
+two possible dst() outcomes, one zero and the other non-zero).  Therefore
+z' must be in standard time, and is the spelling we want in this case.
+
+Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
+concerned (because it takes z' as being in standard time rather than the
+daylight time we intend here), but returning it gives the real-life "local
+clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
+tz.
+
+When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
+the 1:MM standard time spelling we want.
+
+So how can this break?  One of the assumptions must be violated.  Two
+possibilities:
+
+1) [2] effectively says that y.s is invariant across all y belong to a given
+   time zone.  This isn't true if, for political reasons or continental drift,
+   a region decides to change its base offset from UTC.
+
+2) There may be versions of "double daylight" time where the tail end of
+   the analysis gives up a step too early.  I haven't thought about that
+   enough to say.
+
+In any case, it's clear that the default fromutc() is strong enough to handle
+"almost all" time zones:  so long as the standard offset is invariant, it
+doesn't matter if daylight time transition points change from year to year, or
+if daylight time is skipped in some years; it doesn't matter how large or
+small dst() may get within its bounds; and it doesn't even matter if some
+perverse time zone returns a negative dst()).  So a breaking case must be
+pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
+--------------------------------------------------------------------------- */

Added: vendor/Python/current/Modules/dbmmodule.c
===================================================================
--- vendor/Python/current/Modules/dbmmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/dbmmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,370 @@
+
+/* DBM module using dictionary interface */
+
+
+#include "Python.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+/* Some Linux systems install gdbm/ndbm.h, but not ndbm.h.  This supports
+ * whichever configure was able to locate.
+ */
+#if defined(HAVE_NDBM_H)
+#include <ndbm.h>
+#if defined(PYOS_OS2) && !defined(PYCC_GCC)
+static char *which_dbm = "ndbm";
+#else
+static char *which_dbm = "GNU gdbm";  /* EMX port of GDBM */
+#endif
+#elif defined(HAVE_GDBM_NDBM_H)
+#include <gdbm/ndbm.h>
+static char *which_dbm = "GNU gdbm";
+#elif defined(HAVE_BERKDB_H)
+#include <db.h>
+static char *which_dbm = "Berkeley DB";
+#else
+#error "No ndbm.h available!"
+#endif
+
+typedef struct {
+	PyObject_HEAD
+	int di_size;	/* -1 means recompute */
+	DBM *di_dbm;
+} dbmobject;
+
+static PyTypeObject Dbmtype;
+
+#define is_dbmobject(v) ((v)->ob_type == &Dbmtype)
+#define check_dbmobject_open(v) if ((v)->di_dbm == NULL) \
+               { PyErr_SetString(DbmError, "DBM object has already been closed"); \
+                 return NULL; }
+
+static PyObject *DbmError;
+
+static PyObject *
+newdbmobject(char *file, int flags, int mode)
+{
+        dbmobject *dp;
+
+	dp = PyObject_New(dbmobject, &Dbmtype);
+	if (dp == NULL)
+		return NULL;
+	dp->di_size = -1;
+	if ( (dp->di_dbm = dbm_open(file, flags, mode)) == 0 ) {
+		PyErr_SetFromErrno(DbmError);
+		Py_DECREF(dp);
+		return NULL;
+	}
+	return (PyObject *)dp;
+}
+
+/* Methods */
+
+static void
+dbm_dealloc(register dbmobject *dp)
+{
+        if ( dp->di_dbm )
+		dbm_close(dp->di_dbm);
+	PyObject_Del(dp);
+}
+
+static Py_ssize_t
+dbm_length(dbmobject *dp)
+{
+        if (dp->di_dbm == NULL) {
+                 PyErr_SetString(DbmError, "DBM object has already been closed"); 
+                 return -1; 
+        }
+        if ( dp->di_size < 0 ) {
+		datum key;
+		int size;
+
+		size = 0;
+		for ( key=dbm_firstkey(dp->di_dbm); key.dptr;
+		      key = dbm_nextkey(dp->di_dbm))
+			size++;
+		dp->di_size = size;
+	}
+	return dp->di_size;
+}
+
+static PyObject *
+dbm_subscript(dbmobject *dp, register PyObject *key)
+{
+	datum drec, krec;
+	int tmp_size;
+	
+	if (!PyArg_Parse(key, "s#", &krec.dptr, &tmp_size) )
+		return NULL;
+	
+	krec.dsize = tmp_size;
+        check_dbmobject_open(dp);
+	drec = dbm_fetch(dp->di_dbm, krec);
+	if ( drec.dptr == 0 ) {
+		PyErr_SetString(PyExc_KeyError,
+				PyString_AS_STRING((PyStringObject *)key));
+		return NULL;
+	}
+	if ( dbm_error(dp->di_dbm) ) {
+		dbm_clearerr(dp->di_dbm);
+		PyErr_SetString(DbmError, "");
+		return NULL;
+	}
+	return PyString_FromStringAndSize(drec.dptr, drec.dsize);
+}
+
+static int
+dbm_ass_sub(dbmobject *dp, PyObject *v, PyObject *w)
+{
+        datum krec, drec;
+	int tmp_size;
+	
+        if ( !PyArg_Parse(v, "s#", &krec.dptr, &tmp_size) ) {
+		PyErr_SetString(PyExc_TypeError,
+				"dbm mappings have string indices only");
+		return -1;
+	}
+	krec.dsize = tmp_size;
+        if (dp->di_dbm == NULL) {
+                 PyErr_SetString(DbmError, "DBM object has already been closed"); 
+                 return -1;
+        }
+	dp->di_size = -1;
+	if (w == NULL) {
+		if ( dbm_delete(dp->di_dbm, krec) < 0 ) {
+			dbm_clearerr(dp->di_dbm);
+			PyErr_SetString(PyExc_KeyError,
+				      PyString_AS_STRING((PyStringObject *)v));
+			return -1;
+		}
+	} else {
+		if ( !PyArg_Parse(w, "s#", &drec.dptr, &tmp_size) ) {
+			PyErr_SetString(PyExc_TypeError,
+				     "dbm mappings have string elements only");
+			return -1;
+		}
+		drec.dsize = tmp_size;
+		if ( dbm_store(dp->di_dbm, krec, drec, DBM_REPLACE) < 0 ) {
+			dbm_clearerr(dp->di_dbm);
+			PyErr_SetString(DbmError,
+					"cannot add item to database");
+			return -1;
+		}
+	}
+	if ( dbm_error(dp->di_dbm) ) {
+		dbm_clearerr(dp->di_dbm);
+		PyErr_SetString(DbmError, "");
+		return -1;
+	}
+	return 0;
+}
+
+static PyMappingMethods dbm_as_mapping = {
+	(lenfunc)dbm_length,		/*mp_length*/
+	(binaryfunc)dbm_subscript,	/*mp_subscript*/
+	(objobjargproc)dbm_ass_sub,	/*mp_ass_subscript*/
+};
+
+static PyObject *
+dbm__close(register dbmobject *dp, PyObject *unused)
+{
+        if (dp->di_dbm)
+		dbm_close(dp->di_dbm);
+	dp->di_dbm = NULL;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+dbm_keys(register dbmobject *dp, PyObject *unused)
+{
+	register PyObject *v, *item;
+	datum key;
+	int err;
+
+        check_dbmobject_open(dp);
+	v = PyList_New(0);
+	if (v == NULL)
+		return NULL;
+	for (key = dbm_firstkey(dp->di_dbm); key.dptr;
+	     key = dbm_nextkey(dp->di_dbm)) {
+		item = PyString_FromStringAndSize(key.dptr, key.dsize);
+		if (item == NULL) {
+			Py_DECREF(v);
+			return NULL;
+		}
+		err = PyList_Append(v, item);
+		Py_DECREF(item);
+		if (err != 0) {
+			Py_DECREF(v);
+			return NULL;
+		}
+	}
+	return v;
+}
+
+static PyObject *
+dbm_has_key(register dbmobject *dp, PyObject *args)
+{
+	datum key, val;
+	int tmp_size;
+	
+	if (!PyArg_ParseTuple(args, "s#:has_key", &key.dptr, &tmp_size))
+		return NULL;
+	key.dsize = tmp_size;
+        check_dbmobject_open(dp);
+	val = dbm_fetch(dp->di_dbm, key);
+	return PyInt_FromLong(val.dptr != NULL);
+}
+
+static PyObject *
+dbm_get(register dbmobject *dp, PyObject *args)
+{
+	datum key, val;
+	PyObject *defvalue = Py_None;
+	int tmp_size;
+
+	if (!PyArg_ParseTuple(args, "s#|O:get",
+                              &key.dptr, &tmp_size, &defvalue))
+		return NULL;
+	key.dsize = tmp_size;
+        check_dbmobject_open(dp);
+	val = dbm_fetch(dp->di_dbm, key);
+	if (val.dptr != NULL)
+		return PyString_FromStringAndSize(val.dptr, val.dsize);
+	else {
+		Py_INCREF(defvalue);
+		return defvalue;
+	}
+}
+
+static PyObject *
+dbm_setdefault(register dbmobject *dp, PyObject *args)
+{
+	datum key, val;
+	PyObject *defvalue = NULL;
+	int tmp_size;
+
+	if (!PyArg_ParseTuple(args, "s#|S:setdefault",
+                              &key.dptr, &tmp_size, &defvalue))
+		return NULL;
+	key.dsize = tmp_size;
+        check_dbmobject_open(dp);
+	val = dbm_fetch(dp->di_dbm, key);
+	if (val.dptr != NULL)
+		return PyString_FromStringAndSize(val.dptr, val.dsize);
+	if (defvalue == NULL) {
+		defvalue = PyString_FromStringAndSize(NULL, 0);
+		if (defvalue == NULL)
+			return NULL;
+	}
+	else
+		Py_INCREF(defvalue);
+	val.dptr = PyString_AS_STRING(defvalue);
+	val.dsize = PyString_GET_SIZE(defvalue);
+	if (dbm_store(dp->di_dbm, key, val, DBM_INSERT) < 0) {
+		dbm_clearerr(dp->di_dbm);
+		PyErr_SetString(DbmError, "cannot add item to database");
+		return NULL;
+	}
+	return defvalue;
+}
+
+static PyMethodDef dbm_methods[] = {
+	{"close",	(PyCFunction)dbm__close,	METH_NOARGS,
+	 "close()\nClose the database."},
+	{"keys",	(PyCFunction)dbm_keys,		METH_NOARGS,
+	 "keys() -> list\nReturn a list of all keys in the database."},
+	{"has_key",	(PyCFunction)dbm_has_key,	METH_VARARGS,
+	 "has_key(key} -> boolean\nReturn true iff key is in the database."},
+	{"get",		(PyCFunction)dbm_get,		METH_VARARGS,
+	 "get(key[, default]) -> value\n"
+	 "Return the value for key if present, otherwise default."},
+	{"setdefault",	(PyCFunction)dbm_setdefault,	METH_VARARGS,
+	 "setdefault(key[, default]) -> value\n"
+	 "Return the value for key if present, otherwise default.  If key\n"
+	 "is not in the database, it is inserted with default as the value."},
+	{NULL,		NULL}		/* sentinel */
+};
+
+static PyObject *
+dbm_getattr(dbmobject *dp, char *name)
+{
+	return Py_FindMethod(dbm_methods, (PyObject *)dp, name);
+}
+
+static PyTypeObject Dbmtype = {
+	PyObject_HEAD_INIT(NULL)
+	0,
+	"dbm.dbm",
+	sizeof(dbmobject),
+	0,
+	(destructor)dbm_dealloc,  /*tp_dealloc*/
+	0,			  /*tp_print*/
+	(getattrfunc)dbm_getattr, /*tp_getattr*/
+	0,			  /*tp_setattr*/
+	0,			  /*tp_compare*/
+	0,			  /*tp_repr*/
+	0,			  /*tp_as_number*/
+	0,			  /*tp_as_sequence*/
+	&dbm_as_mapping,	  /*tp_as_mapping*/
+};
+
+/* ----------------------------------------------------------------- */
+
+static PyObject *
+dbmopen(PyObject *self, PyObject *args)
+{
+	char *name;
+	char *flags = "r";
+	int iflags;
+	int mode = 0666;
+
+        if ( !PyArg_ParseTuple(args, "s|si:open", &name, &flags, &mode) )
+		return NULL;
+	if ( strcmp(flags, "r") == 0 )
+		iflags = O_RDONLY;
+	else if ( strcmp(flags, "w") == 0 )
+		iflags = O_RDWR;
+	else if ( strcmp(flags, "rw") == 0 ) /* B/W compat */
+		iflags = O_RDWR|O_CREAT; 
+	else if ( strcmp(flags, "c") == 0 )
+		iflags = O_RDWR|O_CREAT;
+	else if ( strcmp(flags, "n") == 0 )
+		iflags = O_RDWR|O_CREAT|O_TRUNC;
+	else {
+		PyErr_SetString(DbmError,
+				"arg 2 to open should be 'r', 'w', 'c', or 'n'");
+		return NULL;
+	}
+        return newdbmobject(name, iflags, mode);
+}
+
+static PyMethodDef dbmmodule_methods[] = {
+	{ "open", (PyCFunction)dbmopen, METH_VARARGS,
+	  "open(path[, flag[, mode]]) -> mapping\n"
+	  "Return a database object."},
+	{ 0, 0 },
+};
+
+PyMODINIT_FUNC
+initdbm(void) {
+	PyObject *m, *d, *s;
+
+	Dbmtype.ob_type = &PyType_Type;
+	m = Py_InitModule("dbm", dbmmodule_methods);
+	if (m == NULL)
+		return;
+	d = PyModule_GetDict(m);
+	if (DbmError == NULL)
+		DbmError = PyErr_NewException("dbm.error", NULL, NULL);
+	s = PyString_FromString(which_dbm);
+	if (s != NULL) {
+		PyDict_SetItemString(d, "library", s);
+		Py_DECREF(s);
+	}
+	if (DbmError != NULL)
+		PyDict_SetItemString(d, "error", DbmError);
+}

Added: vendor/Python/current/Modules/dlmodule.c
===================================================================
--- vendor/Python/current/Modules/dlmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/dlmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,278 @@
+
+/* dl module */
+
+#include "Python.h"
+
+#include <dlfcn.h>
+
+#ifdef __VMS
+#include <unistd.h>
+#endif
+
+#ifndef RTLD_LAZY
+#define RTLD_LAZY 1
+#endif
+
+typedef void *PyUnivPtr;
+typedef struct {
+	PyObject_HEAD
+	PyUnivPtr *dl_handle;
+} dlobject;
+
+static PyTypeObject Dltype;
+
+static PyObject *Dlerror;
+
+static PyObject *
+newdlobject(PyUnivPtr *handle)
+{
+	dlobject *xp;
+	xp = PyObject_New(dlobject, &Dltype);
+	if (xp == NULL)
+		return NULL;
+	xp->dl_handle = handle;
+	return (PyObject *)xp;
+}
+
+static void
+dl_dealloc(dlobject *xp)
+{
+	if (xp->dl_handle != NULL)
+		dlclose(xp->dl_handle);
+	PyObject_Del(xp);
+}
+
+static PyObject *
+dl_close(dlobject *xp)
+{
+	if (xp->dl_handle != NULL) {
+		dlclose(xp->dl_handle);
+		xp->dl_handle = NULL;
+	}
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+dl_sym(dlobject *xp, PyObject *args)
+{
+	char *name;
+	PyUnivPtr *func;
+	if (PyString_Check(args)) {
+		name = PyString_AS_STRING(args);
+	} else {
+		PyErr_Format(PyExc_TypeError, "expected string, found %.200s",
+			     args->ob_type->tp_name);
+		return NULL;
+	}
+	func = dlsym(xp->dl_handle, name);
+	if (func == NULL) {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+	return PyInt_FromLong((long)func);
+}
+
+static PyObject *
+dl_call(dlobject *xp, PyObject *args)
+{
+	PyObject *name;
+	long (*func)(long, long, long, long, long,
+                     long, long, long, long, long);
+	long alist[10];
+	long res;
+	Py_ssize_t i;
+	Py_ssize_t n = PyTuple_Size(args);
+	if (n < 1) {
+		PyErr_SetString(PyExc_TypeError, "at least a name is needed");
+		return NULL;
+	}
+	name = PyTuple_GetItem(args, 0);
+	if (!PyString_Check(name)) {
+		PyErr_SetString(PyExc_TypeError,
+				"function name must be a string");
+		return NULL;
+	}
+	func = (long (*)(long, long, long, long, long, 
+                         long, long, long, long, long)) 
+          dlsym(xp->dl_handle, PyString_AsString(name));
+	if (func == NULL) {
+		PyErr_SetString(PyExc_ValueError, dlerror());
+		return NULL;
+	}
+	if (n-1 > 10) {
+		PyErr_SetString(PyExc_TypeError,
+				"too many arguments (max 10)");
+		return NULL;
+	}
+	for (i = 1; i < n; i++) {
+		PyObject *v = PyTuple_GetItem(args, i);
+		if (PyInt_Check(v))
+			alist[i-1] = PyInt_AsLong(v);
+		else if (PyString_Check(v))
+			alist[i-1] = (long)PyString_AsString(v);
+		else if (v == Py_None)
+			alist[i-1] = (long) ((char *)NULL);
+		else {
+			PyErr_SetString(PyExc_TypeError,
+				   "arguments must be int, string or None");
+			return NULL;
+		}
+	}
+	for (; i <= 10; i++)
+		alist[i-1] = 0;
+	res = (*func)(alist[0], alist[1], alist[2], alist[3], alist[4],
+		      alist[5], alist[6], alist[7], alist[8], alist[9]);
+	return PyInt_FromLong(res);
+}
+
+static PyMethodDef dlobject_methods[] = {
+	{"call",	(PyCFunction)dl_call, METH_VARARGS},
+	{"sym", 	(PyCFunction)dl_sym, METH_O},
+	{"close",	(PyCFunction)dl_close, METH_NOARGS},
+	{NULL,  	NULL}			 /* Sentinel */
+};
+
+static PyObject *
+dl_getattr(dlobject *xp, char *name)
+{
+	return Py_FindMethod(dlobject_methods, (PyObject *)xp, name);
+}
+
+
+static PyTypeObject Dltype = {
+	PyObject_HEAD_INIT(NULL)
+	0,			/*ob_size*/
+	"dl.dl",		/*tp_name*/
+	sizeof(dlobject),	/*tp_basicsize*/
+	0,			/*tp_itemsize*/
+	/* methods */
+	(destructor)dl_dealloc, /*tp_dealloc*/
+	0,			/*tp_print*/
+	(getattrfunc)dl_getattr,/*tp_getattr*/
+	0,			/*tp_setattr*/
+	0,			/*tp_compare*/
+	0,			/*tp_repr*/
+	0,			/*tp_as_number*/
+	0,			/*tp_as_sequence*/
+	0,			/*tp_as_mapping*/
+	0,			/*tp_hash*/
+};
+
+static PyObject *
+dl_open(PyObject *self, PyObject *args)
+{
+	char *name;
+	int mode;
+	PyUnivPtr *handle;
+	if (sizeof(int) != sizeof(long) ||
+	    sizeof(long) != sizeof(char *)) {
+		PyErr_SetString(PyExc_SystemError,
+ "module dl requires sizeof(int) == sizeof(long) == sizeof(char*)");
+		return NULL;
+	}
+
+	if (PyArg_ParseTuple(args, "z:open", &name))
+		mode = RTLD_LAZY;
+	else {
+		PyErr_Clear();
+		if (!PyArg_ParseTuple(args, "zi:open", &name, &mode))
+			return NULL;
+#ifndef RTLD_NOW
+		if (mode != RTLD_LAZY) {
+			PyErr_SetString(PyExc_ValueError, "mode must be 1");
+			return NULL;
+		}
+#endif
+	}
+	handle = dlopen(name, mode);
+	if (handle == NULL) {
+		PyErr_SetString(Dlerror, dlerror());
+		return NULL;
+	}
+#ifdef __VMS
+	/*   Under OpenVMS dlopen doesn't do any check, just save the name
+	 * for later use, so we have to check if the file is readable,
+	 * the name can be a logical or a file from SYS$SHARE.
+	 */
+	if (access(name, R_OK)) {
+		char fname[strlen(name) + 20];
+		strcpy(fname, "SYS$SHARE:");
+		strcat(fname, name);
+		strcat(fname, ".EXE");
+		if (access(fname, R_OK)) {
+			dlclose(handle);
+			PyErr_SetString(Dlerror,
+				"File not found or protection violation");
+			return NULL;
+		}
+	}
+#endif
+	return newdlobject(handle);
+}
+
+static PyMethodDef dl_methods[] = {
+	{"open",	dl_open, METH_VARARGS},
+	{NULL,		NULL}		/* sentinel */
+};
+
+/* From socketmodule.c
+ * Convenience routine to export an integer value.
+ *
+ * Errors are silently ignored, for better or for worse...
+ */
+static void
+insint(PyObject *d, char *name, int value)
+{
+	PyObject *v = PyInt_FromLong((long) value);
+	if (!v || PyDict_SetItemString(d, name, v))
+		PyErr_Clear();
+
+	Py_XDECREF(v);
+}
+
+PyMODINIT_FUNC
+initdl(void)
+{
+	PyObject *m, *d, *x;
+
+	/* Initialize object type */
+	Dltype.ob_type = &PyType_Type;
+
+	/* Create the module and add the functions */
+	m = Py_InitModule("dl", dl_methods);
+	if (m == NULL)
+		return;
+
+	/* Add some symbolic constants to the module */
+	d = PyModule_GetDict(m);
+	Dlerror = x = PyErr_NewException("dl.error", NULL, NULL);
+	PyDict_SetItemString(d, "error", x);
+	x = PyInt_FromLong((long)RTLD_LAZY);
+	PyDict_SetItemString(d, "RTLD_LAZY", x);
+#define INSINT(X)    insint(d,#X,X)
+#ifdef RTLD_NOW
+        INSINT(RTLD_NOW);
+#endif
+#ifdef RTLD_NOLOAD
+        INSINT(RTLD_NOLOAD);
+#endif
+#ifdef RTLD_GLOBAL
+        INSINT(RTLD_GLOBAL);
+#endif
+#ifdef RTLD_LOCAL
+        INSINT(RTLD_LOCAL);
+#endif
+#ifdef RTLD_PARENT
+        INSINT(RTLD_PARENT);
+#endif
+#ifdef RTLD_GROUP
+        INSINT(RTLD_GROUP);
+#endif
+#ifdef RTLD_WORLD
+        INSINT(RTLD_WORLD);
+#endif
+#ifdef RTLD_NODELETE
+        INSINT(RTLD_NODELETE);
+#endif
+}

Added: vendor/Python/current/Modules/errnomodule.c
===================================================================
--- vendor/Python/current/Modules/errnomodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/errnomodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,788 @@
+
+/* Errno module */
+
+#include "Python.h"
+
+/* Windows socket errors (WSA*)  */
+#ifdef MS_WINDOWS
+#include <winsock.h>
+#endif
+
+/*
+ * Pull in the system error definitions
+ */ 
+
+static PyMethodDef errno_methods[] = {
+	{NULL,	      	NULL}
+};
+
+/* Helper function doing the dictionary inserting */
+
+static void
+_inscode(PyObject *d, PyObject *de, char *name, int code)
+{
+	PyObject *u = PyString_FromString(name);
+	PyObject *v = PyInt_FromLong((long) code);
+
+	/* Don't bother checking for errors; they'll be caught at the end
+	 * of the module initialization function by the caller of
+	 * initerrno().
+	 */
+	if (u && v) {
+		/* insert in modules dict */
+		PyDict_SetItem(d, u, v);
+		/* insert in errorcode dict */
+		PyDict_SetItem(de, v, u);
+	}
+	Py_XDECREF(u);
+	Py_XDECREF(v);
+}
+
+PyDoc_STRVAR(errno__doc__,
+"This module makes available standard errno system symbols.\n\
+\n\
+The value of each symbol is the corresponding integer value,\n\
+e.g., on most systems, errno.ENOENT equals the integer 2.\n\
+\n\
+The dictionary errno.errorcode maps numeric codes to symbol names,\n\
+e.g., errno.errorcode[2] could be the string 'ENOENT'.\n\
+\n\
+Symbols that are not relevant to the underlying system are not defined.\n\
+\n\
+To map error codes to error messages, use the function os.strerror(),\n\
+e.g. os.strerror(2) could return 'No such file or directory'.");
+
+PyMODINIT_FUNC
+initerrno(void)
+{
+	PyObject *m, *d, *de;
+	m = Py_InitModule3("errno", errno_methods, errno__doc__);
+	if (m == NULL)
+		return;
+	d = PyModule_GetDict(m);
+	de = PyDict_New();
+	if (!d || !de || PyDict_SetItemString(d, "errorcode", de) < 0)
+		return;
+
+/* Macro so I don't have to edit each and every line below... */
+#define inscode(d, ds, de, name, code, comment) _inscode(d, de, name, code)
+
+	/*
+	 * The names and comments are borrowed from linux/include/errno.h,
+	 * which should be pretty all-inclusive
+	 */ 
+
+#ifdef ENODEV
+	inscode(d, ds, de, "ENODEV", ENODEV, "No such device");
+#endif
+#ifdef ENOCSI
+	inscode(d, ds, de, "ENOCSI", ENOCSI, "No CSI structure available");
+#endif
+#ifdef EHOSTUNREACH
+	inscode(d, ds, de, "EHOSTUNREACH", EHOSTUNREACH, "No route to host");
+#else
+#ifdef WSAEHOSTUNREACH
+	inscode(d, ds, de, "EHOSTUNREACH", WSAEHOSTUNREACH, "No route to host");
+#endif
+#endif
+#ifdef ENOMSG
+	inscode(d, ds, de, "ENOMSG", ENOMSG, "No message of desired type");
+#endif
+#ifdef EUCLEAN
+	inscode(d, ds, de, "EUCLEAN", EUCLEAN, "Structure needs cleaning");
+#endif
+#ifdef EL2NSYNC
+	inscode(d, ds, de, "EL2NSYNC", EL2NSYNC, "Level 2 not synchronized");
+#endif
+#ifdef EL2HLT
+	inscode(d, ds, de, "EL2HLT", EL2HLT, "Level 2 halted");
+#endif
+#ifdef ENODATA
+	inscode(d, ds, de, "ENODATA", ENODATA, "No data available");
+#endif
+#ifdef ENOTBLK
+	inscode(d, ds, de, "ENOTBLK", ENOTBLK, "Block device required");
+#endif
+#ifdef ENOSYS
+	inscode(d, ds, de, "ENOSYS", ENOSYS, "Function not implemented");
+#endif
+#ifdef EPIPE
+	inscode(d, ds, de, "EPIPE", EPIPE, "Broken pipe");
+#endif
+#ifdef EINVAL
+	inscode(d, ds, de, "EINVAL", EINVAL, "Invalid argument");
+#else
+#ifdef WSAEINVAL
+	inscode(d, ds, de, "EINVAL", WSAEINVAL, "Invalid argument");
+#endif
+#endif
+#ifdef EOVERFLOW
+	inscode(d, ds, de, "EOVERFLOW", EOVERFLOW, "Value too large for defined data type");
+#endif
+#ifdef EADV
+	inscode(d, ds, de, "EADV", EADV, "Advertise error");
+#endif
+#ifdef EINTR
+	inscode(d, ds, de, "EINTR", EINTR, "Interrupted system call");
+#else
+#ifdef WSAEINTR
+	inscode(d, ds, de, "EINTR", WSAEINTR, "Interrupted system call");
+#endif
+#endif
+#ifdef EUSERS
+	inscode(d, ds, de, "EUSERS", EUSERS, "Too many users");
+#else
+#ifdef WSAEUSERS
+	inscode(d, ds, de, "EUSERS", WSAEUSERS, "Too many users");
+#endif
+#endif
+#ifdef ENOTEMPTY
+	inscode(d, ds, de, "ENOTEMPTY", ENOTEMPTY, "Directory not empty");
+#else
+#ifdef WSAENOTEMPTY
+	inscode(d, ds, de, "ENOTEMPTY", WSAENOTEMPTY, "Directory not empty");
+#endif
+#endif
+#ifdef ENOBUFS
+	inscode(d, ds, de, "ENOBUFS", ENOBUFS, "No buffer space available");
+#else
+#ifdef WSAENOBUFS
+	inscode(d, ds, de, "ENOBUFS", WSAENOBUFS, "No buffer space available");
+#endif
+#endif
+#ifdef EPROTO
+	inscode(d, ds, de, "EPROTO", EPROTO, "Protocol error");
+#endif
+#ifdef EREMOTE
+	inscode(d, ds, de, "EREMOTE", EREMOTE, "Object is remote");
+#else
+#ifdef WSAEREMOTE
+	inscode(d, ds, de, "EREMOTE", WSAEREMOTE, "Object is remote");
+#endif
+#endif
+#ifdef ENAVAIL
+	inscode(d, ds, de, "ENAVAIL", ENAVAIL, "No XENIX semaphores available");
+#endif
+#ifdef ECHILD
+	inscode(d, ds, de, "ECHILD", ECHILD, "No child processes");
+#endif
+#ifdef ELOOP
+	inscode(d, ds, de, "ELOOP", ELOOP, "Too many symbolic links encountered");
+#else
+#ifdef WSAELOOP
+	inscode(d, ds, de, "ELOOP", WSAELOOP, "Too many symbolic links encountered");
+#endif
+#endif
+#ifdef EXDEV
+	inscode(d, ds, de, "EXDEV", EXDEV, "Cross-device link");
+#endif
+#ifdef E2BIG
+	inscode(d, ds, de, "E2BIG", E2BIG, "Arg list too long");
+#endif
+#ifdef ESRCH
+	inscode(d, ds, de, "ESRCH", ESRCH, "No such process");
+#endif
+#ifdef EMSGSIZE
+	inscode(d, ds, de, "EMSGSIZE", EMSGSIZE, "Message too long");
+#else
+#ifdef WSAEMSGSIZE
+	inscode(d, ds, de, "EMSGSIZE", WSAEMSGSIZE, "Message too long");
+#endif
+#endif
+#ifdef EAFNOSUPPORT
+	inscode(d, ds, de, "EAFNOSUPPORT", EAFNOSUPPORT, "Address family not supported by protocol");
+#else
+#ifdef WSAEAFNOSUPPORT
+	inscode(d, ds, de, "EAFNOSUPPORT", WSAEAFNOSUPPORT, "Address family not supported by protocol");
+#endif
+#endif
+#ifdef EBADR
+	inscode(d, ds, de, "EBADR", EBADR, "Invalid request descriptor");
+#endif
+#ifdef EHOSTDOWN
+	inscode(d, ds, de, "EHOSTDOWN", EHOSTDOWN, "Host is down");
+#else
+#ifdef WSAEHOSTDOWN
+	inscode(d, ds, de, "EHOSTDOWN", WSAEHOSTDOWN, "Host is down");
+#endif
+#endif
+#ifdef EPFNOSUPPORT
+	inscode(d, ds, de, "EPFNOSUPPORT", EPFNOSUPPORT, "Protocol family not supported");
+#else
+#ifdef WSAEPFNOSUPPORT
+	inscode(d, ds, de, "EPFNOSUPPORT", WSAEPFNOSUPPORT, "Protocol family not supported");
+#endif
+#endif
+#ifdef ENOPROTOOPT
+	inscode(d, ds, de, "ENOPROTOOPT", ENOPROTOOPT, "Protocol not available");
+#else
+#ifdef WSAENOPROTOOPT
+	inscode(d, ds, de, "ENOPROTOOPT", WSAENOPROTOOPT, "Protocol not available");
+#endif
+#endif
+#ifdef EBUSY
+	inscode(d, ds, de, "EBUSY", EBUSY, "Device or resource busy");
+#endif
+#ifdef EWOULDBLOCK
+	inscode(d, ds, de, "EWOULDBLOCK", EWOULDBLOCK, "Operation would block");
+#else
+#ifdef WSAEWOULDBLOCK
+	inscode(d, ds, de, "EWOULDBLOCK", WSAEWOULDBLOCK, "Operation would block");
+#endif
+#endif
+#ifdef EBADFD
+	inscode(d, ds, de, "EBADFD", EBADFD, "File descriptor in bad state");
+#endif
+#ifdef EDOTDOT
+	inscode(d, ds, de, "EDOTDOT", EDOTDOT, "RFS specific error");
+#endif
+#ifdef EISCONN
+	inscode(d, ds, de, "EISCONN", EISCONN, "Transport endpoint is already connected");
+#else
+#ifdef WSAEISCONN
+	inscode(d, ds, de, "EISCONN", WSAEISCONN, "Transport endpoint is already connected");
+#endif
+#endif
+#ifdef ENOANO
+	inscode(d, ds, de, "ENOANO", ENOANO, "No anode");
+#endif
+#ifdef ESHUTDOWN
+	inscode(d, ds, de, "ESHUTDOWN", ESHUTDOWN, "Cannot send after transport endpoint shutdown");
+#else
+#ifdef WSAESHUTDOWN
+	inscode(d, ds, de, "ESHUTDOWN", WSAESHUTDOWN, "Cannot send after transport endpoint shutdown");
+#endif
+#endif
+#ifdef ECHRNG
+	inscode(d, ds, de, "ECHRNG", ECHRNG, "Channel number out of range");
+#endif
+#ifdef ELIBBAD
+	inscode(d, ds, de, "ELIBBAD", ELIBBAD, "Accessing a corrupted shared library");
+#endif
+#ifdef ENONET
+	inscode(d, ds, de, "ENONET", ENONET, "Machine is not on the network");
+#endif
+#ifdef EBADE
+	inscode(d, ds, de, "EBADE", EBADE, "Invalid exchange");
+#endif
+#ifdef EBADF
+	inscode(d, ds, de, "EBADF", EBADF, "Bad file number");
+#else
+#ifdef WSAEBADF
+	inscode(d, ds, de, "EBADF", WSAEBADF, "Bad file number");
+#endif
+#endif
+#ifdef EMULTIHOP
+	inscode(d, ds, de, "EMULTIHOP", EMULTIHOP, "Multihop attempted");
+#endif
+#ifdef EIO
+	inscode(d, ds, de, "EIO", EIO, "I/O error");
+#endif
+#ifdef EUNATCH
+	inscode(d, ds, de, "EUNATCH", EUNATCH, "Protocol driver not attached");
+#endif
+#ifdef EPROTOTYPE
+	inscode(d, ds, de, "EPROTOTYPE", EPROTOTYPE, "Protocol wrong type for socket");
+#else
+#ifdef WSAEPROTOTYPE
+	inscode(d, ds, de, "EPROTOTYPE", WSAEPROTOTYPE, "Protocol wrong type for socket");
+#endif
+#endif
+#ifdef ENOSPC
+	inscode(d, ds, de, "ENOSPC", ENOSPC, "No space left on device");
+#endif
+#ifdef ENOEXEC
+	inscode(d, ds, de, "ENOEXEC", ENOEXEC, "Exec format error");
+#endif
+#ifdef EALREADY
+	inscode(d, ds, de, "EALREADY", EALREADY, "Operation already in progress");
+#else
+#ifdef WSAEALREADY
+	inscode(d, ds, de, "EALREADY", WSAEALREADY, "Operation already in progress");
+#endif
+#endif
+#ifdef ENETDOWN
+	inscode(d, ds, de, "ENETDOWN", ENETDOWN, "Network is down");
+#else
+#ifdef WSAENETDOWN
+	inscode(d, ds, de, "ENETDOWN", WSAENETDOWN, "Network is down");
+#endif
+#endif
+#ifdef ENOTNAM
+	inscode(d, ds, de, "ENOTNAM", ENOTNAM, "Not a XENIX named type file");
+#endif
+#ifdef EACCES
+	inscode(d, ds, de, "EACCES", EACCES, "Permission denied");
+#else
+#ifdef WSAEACCES
+	inscode(d, ds, de, "EACCES", WSAEACCES, "Permission denied");
+#endif
+#endif
+#ifdef ELNRNG
+	inscode(d, ds, de, "ELNRNG", ELNRNG, "Link number out of range");
+#endif
+#ifdef EILSEQ
+	inscode(d, ds, de, "EILSEQ", EILSEQ, "Illegal byte sequence");
+#endif
+#ifdef ENOTDIR
+	inscode(d, ds, de, "ENOTDIR", ENOTDIR, "Not a directory");
+#endif
+#ifdef ENOTUNIQ
+	inscode(d, ds, de, "ENOTUNIQ", ENOTUNIQ, "Name not unique on network");
+#endif
+#ifdef EPERM
+	inscode(d, ds, de, "EPERM", EPERM, "Operation not permitted");
+#endif
+#ifdef EDOM
+	inscode(d, ds, de, "EDOM", EDOM, "Math argument out of domain of func");
+#endif
+#ifdef EXFULL
+	inscode(d, ds, de, "EXFULL", EXFULL, "Exchange full");
+#endif
+#ifdef ECONNREFUSED
+	inscode(d, ds, de, "ECONNREFUSED", ECONNREFUSED, "Connection refused");
+#else
+#ifdef WSAECONNREFUSED
+	inscode(d, ds, de, "ECONNREFUSED", WSAECONNREFUSED, "Connection refused");
+#endif
+#endif
+#ifdef EISDIR
+	inscode(d, ds, de, "EISDIR", EISDIR, "Is a directory");
+#endif
+#ifdef EPROTONOSUPPORT
+	inscode(d, ds, de, "EPROTONOSUPPORT", EPROTONOSUPPORT, "Protocol not supported");
+#else
+#ifdef WSAEPROTONOSUPPORT
+	inscode(d, ds, de, "EPROTONOSUPPORT", WSAEPROTONOSUPPORT, "Protocol not supported");
+#endif
+#endif
+#ifdef EROFS
+	inscode(d, ds, de, "EROFS", EROFS, "Read-only file system");
+#endif
+#ifdef EADDRNOTAVAIL
+	inscode(d, ds, de, "EADDRNOTAVAIL", EADDRNOTAVAIL, "Cannot assign requested address");
+#else
+#ifdef WSAEADDRNOTAVAIL
+	inscode(d, ds, de, "EADDRNOTAVAIL", WSAEADDRNOTAVAIL, "Cannot assign requested address");
+#endif
+#endif
+#ifdef EIDRM
+	inscode(d, ds, de, "EIDRM", EIDRM, "Identifier removed");
+#endif
+#ifdef ECOMM
+	inscode(d, ds, de, "ECOMM", ECOMM, "Communication error on send");
+#endif
+#ifdef ESRMNT
+	inscode(d, ds, de, "ESRMNT", ESRMNT, "Srmount error");
+#endif
+#ifdef EREMOTEIO
+	inscode(d, ds, de, "EREMOTEIO", EREMOTEIO, "Remote I/O error");
+#endif
+#ifdef EL3RST
+	inscode(d, ds, de, "EL3RST", EL3RST, "Level 3 reset");
+#endif
+#ifdef EBADMSG
+	inscode(d, ds, de, "EBADMSG", EBADMSG, "Not a data message");
+#endif
+#ifdef ENFILE
+	inscode(d, ds, de, "ENFILE", ENFILE, "File table overflow");
+#endif
+#ifdef ELIBMAX
+	inscode(d, ds, de, "ELIBMAX", ELIBMAX, "Attempting to link in too many shared libraries");
+#endif
+#ifdef ESPIPE
+	inscode(d, ds, de, "ESPIPE", ESPIPE, "Illegal seek");
+#endif
+#ifdef ENOLINK
+	inscode(d, ds, de, "ENOLINK", ENOLINK, "Link has been severed");
+#endif
+#ifdef ENETRESET
+	inscode(d, ds, de, "ENETRESET", ENETRESET, "Network dropped connection because of reset");
+#else
+#ifdef WSAENETRESET
+	inscode(d, ds, de, "ENETRESET", WSAENETRESET, "Network dropped connection because of reset");
+#endif
+#endif
+#ifdef ETIMEDOUT
+	inscode(d, ds, de, "ETIMEDOUT", ETIMEDOUT, "Connection timed out");
+#else
+#ifdef WSAETIMEDOUT
+	inscode(d, ds, de, "ETIMEDOUT", WSAETIMEDOUT, "Connection timed out");
+#endif
+#endif
+#ifdef ENOENT
+	inscode(d, ds, de, "ENOENT", ENOENT, "No such file or directory");
+#endif
+#ifdef EEXIST
+	inscode(d, ds, de, "EEXIST", EEXIST, "File exists");
+#endif
+#ifdef EDQUOT
+	inscode(d, ds, de, "EDQUOT", EDQUOT, "Quota exceeded");
+#else
+#ifdef WSAEDQUOT
+	inscode(d, ds, de, "EDQUOT", WSAEDQUOT, "Quota exceeded");
+#endif
+#endif
+#ifdef ENOSTR
+	inscode(d, ds, de, "ENOSTR", ENOSTR, "Device not a stream");
+#endif
+#ifdef EBADSLT
+	inscode(d, ds, de, "EBADSLT", EBADSLT, "Invalid slot");
+#endif
+#ifdef EBADRQC
+	inscode(d, ds, de, "EBADRQC", EBADRQC, "Invalid request code");
+#endif
+#ifdef ELIBACC
+	inscode(d, ds, de, "ELIBACC", ELIBACC, "Can not access a needed shared library");
+#endif
+#ifdef EFAULT
+	inscode(d, ds, de, "EFAULT", EFAULT, "Bad address");
+#else
+#ifdef WSAEFAULT
+	inscode(d, ds, de, "EFAULT", WSAEFAULT, "Bad address");
+#endif
+#endif
+#ifdef EFBIG
+	inscode(d, ds, de, "EFBIG", EFBIG, "File too large");
+#endif
+#ifdef EDEADLK
+	inscode(d, ds, de, "EDEADLK", EDEADLK, "Resource deadlock would occur");
+#endif
+#ifdef ENOTCONN
+	inscode(d, ds, de, "ENOTCONN", ENOTCONN, "Transport endpoint is not connected");
+#else
+#ifdef WSAENOTCONN
+	inscode(d, ds, de, "ENOTCONN", WSAENOTCONN, "Transport endpoint is not connected");
+#endif
+#endif
+#ifdef EDESTADDRREQ
+	inscode(d, ds, de, "EDESTADDRREQ", EDESTADDRREQ, "Destination address required");
+#else
+#ifdef WSAEDESTADDRREQ
+	inscode(d, ds, de, "EDESTADDRREQ", WSAEDESTADDRREQ, "Destination address required");
+#endif
+#endif
+#ifdef ELIBSCN
+	inscode(d, ds, de, "ELIBSCN", ELIBSCN, ".lib section in a.out corrupted");
+#endif
+#ifdef ENOLCK
+	inscode(d, ds, de, "ENOLCK", ENOLCK, "No record locks available");
+#endif
+#ifdef EISNAM
+	inscode(d, ds, de, "EISNAM", EISNAM, "Is a named type file");
+#endif
+#ifdef ECONNABORTED
+	inscode(d, ds, de, "ECONNABORTED", ECONNABORTED, "Software caused connection abort");
+#else
+#ifdef WSAECONNABORTED
+	inscode(d, ds, de, "ECONNABORTED", WSAECONNABORTED, "Software caused connection abort");
+#endif
+#endif
+#ifdef ENETUNREACH
+	inscode(d, ds, de, "ENETUNREACH", ENETUNREACH, "Network is unreachable");
+#else
+#ifdef WSAENETUNREACH
+	inscode(d, ds, de, "ENETUNREACH", WSAENETUNREACH, "Network is unreachable");
+#endif
+#endif
+#ifdef ESTALE
+	inscode(d, ds, de, "ESTALE", ESTALE, "Stale NFS file handle");
+#else
+#ifdef WSAESTALE
+	inscode(d, ds, de, "ESTALE", WSAESTALE, "Stale NFS file handle");
+#endif
+#endif
+#ifdef ENOSR
+	inscode(d, ds, de, "ENOSR", ENOSR, "Out of streams resources");
+#endif
+#ifdef ENOMEM
+	inscode(d, ds, de, "ENOMEM", ENOMEM, "Out of memory");
+#endif
+#ifdef ENOTSOCK
+	inscode(d, ds, de, "ENOTSOCK", ENOTSOCK, "Socket operation on non-socket");
+#else
+#ifdef WSAENOTSOCK
+	inscode(d, ds, de, "ENOTSOCK", WSAENOTSOCK, "Socket operation on non-socket");
+#endif
+#endif
+#ifdef ESTRPIPE
+	inscode(d, ds, de, "ESTRPIPE", ESTRPIPE, "Streams pipe error");
+#endif
+#ifdef EMLINK
+	inscode(d, ds, de, "EMLINK", EMLINK, "Too many links");
+#endif
+#ifdef ERANGE
+	inscode(d, ds, de, "ERANGE", ERANGE, "Math result not representable");
+#endif
+#ifdef ELIBEXEC
+	inscode(d, ds, de, "ELIBEXEC", ELIBEXEC, "Cannot exec a shared library directly");
+#endif
+#ifdef EL3HLT
+	inscode(d, ds, de, "EL3HLT", EL3HLT, "Level 3 halted");
+#endif
+#ifdef ECONNRESET
+	inscode(d, ds, de, "ECONNRESET", ECONNRESET, "Connection reset by peer");
+#else
+#ifdef WSAECONNRESET
+	inscode(d, ds, de, "ECONNRESET", WSAECONNRESET, "Connection reset by peer");
+#endif
+#endif
+#ifdef EADDRINUSE
+	inscode(d, ds, de, "EADDRINUSE", EADDRINUSE, "Address already in use");
+#else
+#ifdef WSAEADDRINUSE
+	inscode(d, ds, de, "EADDRINUSE", WSAEADDRINUSE, "Address already in use");
+#endif
+#endif
+#ifdef EOPNOTSUPP
+	inscode(d, ds, de, "EOPNOTSUPP", EOPNOTSUPP, "Operation not supported on transport endpoint");
+#else
+#ifdef WSAEOPNOTSUPP
+	inscode(d, ds, de, "EOPNOTSUPP", WSAEOPNOTSUPP, "Operation not supported on transport endpoint");
+#endif
+#endif
+#ifdef EREMCHG
+	inscode(d, ds, de, "EREMCHG", EREMCHG, "Remote address changed");
+#endif
+#ifdef EAGAIN
+	inscode(d, ds, de, "EAGAIN", EAGAIN, "Try again");
+#endif
+#ifdef ENAMETOOLONG
+	inscode(d, ds, de, "ENAMETOOLONG", ENAMETOOLONG, "File name too long");
+#else
+#ifdef WSAENAMETOOLONG
+	inscode(d, ds, de, "ENAMETOOLONG", WSAENAMETOOLONG, "File name too long");
+#endif
+#endif
+#ifdef ENOTTY
+	inscode(d, ds, de, "ENOTTY", ENOTTY, "Not a typewriter");
+#endif
+#ifdef ERESTART
+	inscode(d, ds, de, "ERESTART", ERESTART, "Interrupted system call should be restarted");
+#endif
+#ifdef ESOCKTNOSUPPORT
+	inscode(d, ds, de, "ESOCKTNOSUPPORT", ESOCKTNOSUPPORT, "Socket type not supported");
+#else
+#ifdef WSAESOCKTNOSUPPORT
+	inscode(d, ds, de, "ESOCKTNOSUPPORT", WSAESOCKTNOSUPPORT, "Socket type not supported");
+#endif
+#endif
+#ifdef ETIME
+	inscode(d, ds, de, "ETIME", ETIME, "Timer expired");
+#endif
+#ifdef EBFONT
+	inscode(d, ds, de, "EBFONT", EBFONT, "Bad font file format");
+#endif
+#ifdef EDEADLOCK
+	inscode(d, ds, de, "EDEADLOCK", EDEADLOCK, "Error EDEADLOCK");
+#endif
+#ifdef ETOOMANYREFS
+	inscode(d, ds, de, "ETOOMANYREFS", ETOOMANYREFS, "Too many references: cannot splice");
+#else
+#ifdef WSAETOOMANYREFS
+	inscode(d, ds, de, "ETOOMANYREFS", WSAETOOMANYREFS, "Too many references: cannot splice");
+#endif
+#endif
+#ifdef EMFILE
+	inscode(d, ds, de, "EMFILE", EMFILE, "Too many open files");
+#else
+#ifdef WSAEMFILE
+	inscode(d, ds, de, "EMFILE", WSAEMFILE, "Too many open files");
+#endif
+#endif
+#ifdef ETXTBSY
+	inscode(d, ds, de, "ETXTBSY", ETXTBSY, "Text file busy");
+#endif
+#ifdef EINPROGRESS
+	inscode(d, ds, de, "EINPROGRESS", EINPROGRESS, "Operation now in progress");
+#else
+#ifdef WSAEINPROGRESS
+	inscode(d, ds, de, "EINPROGRESS", WSAEINPROGRESS, "Operation now in progress");
+#endif
+#endif
+#ifdef ENXIO
+	inscode(d, ds, de, "ENXIO", ENXIO, "No such device or address");
+#endif
+#ifdef ENOPKG
+	inscode(d, ds, de, "ENOPKG", ENOPKG, "Package not installed");
+#endif
+#ifdef WSASY
+	inscode(d, ds, de, "WSASY", WSASY, "Error WSASY");
+#endif
+#ifdef WSAEHOSTDOWN
+	inscode(d, ds, de, "WSAEHOSTDOWN", WSAEHOSTDOWN, "Host is down");
+#endif
+#ifdef WSAENETDOWN
+	inscode(d, ds, de, "WSAENETDOWN", WSAENETDOWN, "Network is down");
+#endif
+#ifdef WSAENOTSOCK
+	inscode(d, ds, de, "WSAENOTSOCK", WSAENOTSOCK, "Socket operation on non-socket");
+#endif
+#ifdef WSAEHOSTUNREACH
+	inscode(d, ds, de, "WSAEHOSTUNREACH", WSAEHOSTUNREACH, "No route to host");
+#endif
+#ifdef WSAELOOP
+	inscode(d, ds, de, "WSAELOOP", WSAELOOP, "Too many symbolic links encountered");
+#endif
+#ifdef WSAEMFILE
+	inscode(d, ds, de, "WSAEMFILE", WSAEMFILE, "Too many open files");
+#endif
+#ifdef WSAESTALE
+	inscode(d, ds, de, "WSAESTALE", WSAESTALE, "Stale NFS file handle");
+#endif
+#ifdef WSAVERNOTSUPPORTED
+	inscode(d, ds, de, "WSAVERNOTSUPPORTED", WSAVERNOTSUPPORTED, "Error WSAVERNOTSUPPORTED");
+#endif
+#ifdef WSAENETUNREACH
+	inscode(d, ds, de, "WSAENETUNREACH", WSAENETUNREACH, "Network is unreachable");
+#endif
+#ifdef WSAEPROCLIM
+	inscode(d, ds, de, "WSAEPROCLIM", WSAEPROCLIM, "Error WSAEPROCLIM");
+#endif
+#ifdef WSAEFAULT
+	inscode(d, ds, de, "WSAEFAULT", WSAEFAULT, "Bad address");
+#endif
+#ifdef WSANOTINITIALISED
+	inscode(d, ds, de, "WSANOTINITIALISED", WSANOTINITIALISED, "Error WSANOTINITIALISED");
+#endif
+#ifdef WSAEUSERS
+	inscode(d, ds, de, "WSAEUSERS", WSAEUSERS, "Too many users");
+#endif
+#ifdef WSAMAKEASYNCREPL
+	inscode(d, ds, de, "WSAMAKEASYNCREPL", WSAMAKEASYNCREPL, "Error WSAMAKEASYNCREPL");
+#endif
+#ifdef WSAENOPROTOOPT
+	inscode(d, ds, de, "WSAENOPROTOOPT", WSAENOPROTOOPT, "Protocol not available");
+#endif
+#ifdef WSAECONNABORTED
+	inscode(d, ds, de, "WSAECONNABORTED", WSAECONNABORTED, "Software caused connection abort");
+#endif
+#ifdef WSAENAMETOOLONG
+	inscode(d, ds, de, "WSAENAMETOOLONG", WSAENAMETOOLONG, "File name too long");
+#endif
+#ifdef WSAENOTEMPTY
+	inscode(d, ds, de, "WSAENOTEMPTY", WSAENOTEMPTY, "Directory not empty");
+#endif
+#ifdef WSAESHUTDOWN
+	inscode(d, ds, de, "WSAESHUTDOWN", WSAESHUTDOWN, "Cannot send after transport endpoint shutdown");
+#endif
+#ifdef WSAEAFNOSUPPORT
+	inscode(d, ds, de, "WSAEAFNOSUPPORT", WSAEAFNOSUPPORT, "Address family not supported by protocol");
+#endif
+#ifdef WSAETOOMANYREFS
+	inscode(d, ds, de, "WSAETOOMANYREFS", WSAETOOMANYREFS, "Too many references: cannot splice");
+#endif
+#ifdef WSAEACCES
+	inscode(d, ds, de, "WSAEACCES", WSAEACCES, "Permission denied");
+#endif
+#ifdef WSATR
+	inscode(d, ds, de, "WSATR", WSATR, "Error WSATR");
+#endif
+#ifdef WSABASEERR
+	inscode(d, ds, de, "WSABASEERR", WSABASEERR, "Error WSABASEERR");
+#endif
+#ifdef WSADESCRIPTIO
+	inscode(d, ds, de, "WSADESCRIPTIO", WSADESCRIPTIO, "Error WSADESCRIPTIO");
+#endif
+#ifdef WSAEMSGSIZE
+	inscode(d, ds, de, "WSAEMSGSIZE", WSAEMSGSIZE, "Message too long");
+#endif
+#ifdef WSAEBADF
+	inscode(d, ds, de, "WSAEBADF", WSAEBADF, "Bad file number");
+#endif
+#ifdef WSAECONNRESET
+	inscode(d, ds, de, "WSAECONNRESET", WSAECONNRESET, "Connection reset by peer");
+#endif
+#ifdef WSAGETSELECTERRO
+	inscode(d, ds, de, "WSAGETSELECTERRO", WSAGETSELECTERRO, "Error WSAGETSELECTERRO");
+#endif
+#ifdef WSAETIMEDOUT
+	inscode(d, ds, de, "WSAETIMEDOUT", WSAETIMEDOUT, "Connection timed out");
+#endif
+#ifdef WSAENOBUFS
+	inscode(d, ds, de, "WSAENOBUFS", WSAENOBUFS, "No buffer space available");
+#endif
+#ifdef WSAEDISCON
+	inscode(d, ds, de, "WSAEDISCON", WSAEDISCON, "Error WSAEDISCON");
+#endif
+#ifdef WSAEINTR
+	inscode(d, ds, de, "WSAEINTR", WSAEINTR, "Interrupted system call");
+#endif
+#ifdef WSAEPROTOTYPE
+	inscode(d, ds, de, "WSAEPROTOTYPE", WSAEPROTOTYPE, "Protocol wrong type for socket");
+#endif
+#ifdef WSAHOS
+	inscode(d, ds, de, "WSAHOS", WSAHOS, "Error WSAHOS");
+#endif
+#ifdef WSAEADDRINUSE
+	inscode(d, ds, de, "WSAEADDRINUSE", WSAEADDRINUSE, "Address already in use");
+#endif
+#ifdef WSAEADDRNOTAVAIL
+	inscode(d, ds, de, "WSAEADDRNOTAVAIL", WSAEADDRNOTAVAIL, "Cannot assign requested address");
+#endif
+#ifdef WSAEALREADY
+	inscode(d, ds, de, "WSAEALREADY", WSAEALREADY, "Operation already in progress");
+#endif
+#ifdef WSAEPROTONOSUPPORT
+	inscode(d, ds, de, "WSAEPROTONOSUPPORT", WSAEPROTONOSUPPORT, "Protocol not supported");
+#endif
+#ifdef WSASYSNOTREADY
+	inscode(d, ds, de, "WSASYSNOTREADY", WSASYSNOTREADY, "Error WSASYSNOTREADY");
+#endif
+#ifdef WSAEWOULDBLOCK
+	inscode(d, ds, de, "WSAEWOULDBLOCK", WSAEWOULDBLOCK, "Operation would block");
+#endif
+#ifdef WSAEPFNOSUPPORT
+	inscode(d, ds, de, "WSAEPFNOSUPPORT", WSAEPFNOSUPPORT, "Protocol family not supported");
+#endif
+#ifdef WSAEOPNOTSUPP
+	inscode(d, ds, de, "WSAEOPNOTSUPP", WSAEOPNOTSUPP, "Operation not supported on transport endpoint");
+#endif
+#ifdef WSAEISCONN
+	inscode(d, ds, de, "WSAEISCONN", WSAEISCONN, "Transport endpoint is already connected");
+#endif
+#ifdef WSAEDQUOT
+	inscode(d, ds, de, "WSAEDQUOT", WSAEDQUOT, "Quota exceeded");
+#endif
+#ifdef WSAENOTCONN
+	inscode(d, ds, de, "WSAENOTCONN", WSAENOTCONN, "Transport endpoint is not connected");
+#endif
+#ifdef WSAEREMOTE
+	inscode(d, ds, de, "WSAEREMOTE", WSAEREMOTE, "Object is remote");
+#endif
+#ifdef WSAEINVAL
+	inscode(d, ds, de, "WSAEINVAL", WSAEINVAL, "Invalid argument");
+#endif
+#ifdef WSAEINPROGRESS
+	inscode(d, ds, de, "WSAEINPROGRESS", WSAEINPROGRESS, "Operation now in progress");
+#endif
+#ifdef WSAGETSELECTEVEN
+	inscode(d, ds, de, "WSAGETSELECTEVEN", WSAGETSELECTEVEN, "Error WSAGETSELECTEVEN");
+#endif
+#ifdef WSAESOCKTNOSUPPORT
+	inscode(d, ds, de, "WSAESOCKTNOSUPPORT", WSAESOCKTNOSUPPORT, "Socket type not supported");
+#endif
+#ifdef WSAGETASYNCERRO
+	inscode(d, ds, de, "WSAGETASYNCERRO", WSAGETASYNCERRO, "Error WSAGETASYNCERRO");
+#endif
+#ifdef WSAMAKESELECTREPL
+	inscode(d, ds, de, "WSAMAKESELECTREPL", WSAMAKESELECTREPL, "Error WSAMAKESELECTREPL");
+#endif
+#ifdef WSAGETASYNCBUFLE
+	inscode(d, ds, de, "WSAGETASYNCBUFLE", WSAGETASYNCBUFLE, "Error WSAGETASYNCBUFLE");
+#endif
+#ifdef WSAEDESTADDRREQ
+	inscode(d, ds, de, "WSAEDESTADDRREQ", WSAEDESTADDRREQ, "Destination address required");
+#endif
+#ifdef WSAECONNREFUSED
+	inscode(d, ds, de, "WSAECONNREFUSED", WSAECONNREFUSED, "Connection refused");
+#endif
+#ifdef WSAENETRESET
+	inscode(d, ds, de, "WSAENETRESET", WSAENETRESET, "Network dropped connection because of reset");
+#endif
+#ifdef WSAN
+	inscode(d, ds, de, "WSAN", WSAN, "Error WSAN");
+#endif
+
+	Py_DECREF(de);
+}

Added: vendor/Python/current/Modules/expat/amigaconfig.h
===================================================================
--- vendor/Python/current/Modules/expat/amigaconfig.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/expat/amigaconfig.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,96 @@
+#ifndef AMIGACONFIG_H
+#define AMIGACONFIG_H
+
+/* 1234 = LIL_ENDIAN, 4321 = BIGENDIAN */
+#define BYTEORDER 4321
+
+/* Define to 1 if you have the `bcopy' function. */
+#define HAVE_BCOPY 1
+
+/* Define to 1 if you have the <check.h> header file. */
+#undef HAVE_CHECK_H
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define to 1 if you have the `getpagesize' function. */
+#undef HAVE_GETPAGESIZE
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the `memmove' function. */
+#define HAVE_MEMMOVE 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have a working `mmap' system call. */
+#undef HAVE_MMAP
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "expat-bugs at mail.libexpat.org"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "expat"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "expat 1.95.8"
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "1.95.8"
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* whether byteorder is bigendian */
+#define WORDS_BIGENDIAN
+
+/* Define to specify how much context to retain around the current parse
+   point. */
+#define XML_CONTEXT_BYTES 1024
+
+/* Define to make parameter entity parsing functionality available. */
+#define XML_DTD
+
+/* Define to make XML Namespaces functionality available. */
+#define XML_NS
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to `long' if <sys/types.h> does not define. */
+#undef off_t
+
+/* Define to `unsigned' if <sys/types.h> does not define. */
+#undef size_t
+
+
+#endif  /* AMIGACONFIG_H */

Added: vendor/Python/current/Modules/expat/ascii.h
===================================================================
--- vendor/Python/current/Modules/expat/ascii.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/expat/ascii.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,85 @@
+/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+   See the file COPYING for copying permission.
+*/
+
+#define ASCII_A 0x41
+#define ASCII_B 0x42
+#define ASCII_C 0x43
+#define ASCII_D 0x44
+#define ASCII_E 0x45
+#define ASCII_F 0x46
+#define ASCII_G 0x47
+#define ASCII_H 0x48
+#define ASCII_I 0x49
+#define ASCII_J 0x4A
+#define ASCII_K 0x4B
+#define ASCII_L 0x4C
+#define ASCII_M 0x4D
+#define ASCII_N 0x4E
+#define ASCII_O 0x4F
+#define ASCII_P 0x50
+#define ASCII_Q 0x51
+#define ASCII_R 0x52
+#define ASCII_S 0x53
+#define ASCII_T 0x54
+#define ASCII_U 0x55
+#define ASCII_V 0x56
+#define ASCII_W 0x57
+#define ASCII_X 0x58
+#define ASCII_Y 0x59
+#define ASCII_Z 0x5A
+
+#define ASCII_a 0x61
+#define ASCII_b 0x62
+#define ASCII_c 0x63
+#define ASCII_d 0x64
+#define ASCII_e 0x65
+#define ASCII_f 0x66
+#define ASCII_g 0x67
+#define ASCII_h 0x68
+#define ASCII_i 0x69
+#define ASCII_j 0x6A
+#define ASCII_k 0x6B
+#define ASCII_l 0x6C
+#define ASCII_m 0x6D
+#define ASCII_n 0x6E
+#define ASCII_o 0x6F
+#define ASCII_p 0x70
+#define ASCII_q 0x71
+#define ASCII_r 0x72
+#define ASCII_s 0x73
+#define ASCII_t 0x74
+#define ASCII_u 0x75
+#define ASCII_v 0x76
+#define ASCII_w 0x77
+#define ASCII_x 0x78
+#define ASCII_y 0x79
+#define ASCII_z 0x7A
+
+#define ASCII_0 0x30
+#define ASCII_1 0x31
+#define ASCII_2 0x32
+#define ASCII_3 0x33
+#define ASCII_4 0x34
+#define ASCII_5 0x35
+#define ASCII_6 0x36
+#define ASCII_7 0x37
+#define ASCII_8 0x38
+#define ASCII_9 0x39
+
+#define ASCII_TAB 0x09
+#define ASCII_SPACE 0x20
+#define ASCII_EXCL 0x21
+#define ASCII_QUOT 0x22
+#define ASCII_AMP 0x26
+#define ASCII_APOS 0x27
+#define ASCII_MINUS 0x2D
+#define ASCII_PERIOD 0x2E
+#define ASCII_COLON 0x3A
+#define ASCII_SEMI 0x3B
+#define ASCII_LT 0x3C
+#define ASCII_EQUALS 0x3D
+#define ASCII_GT 0x3E
+#define ASCII_LSQB 0x5B
+#define ASCII_RSQB 0x5D
+#define ASCII_UNDERSCORE 0x5F

Added: vendor/Python/current/Modules/expat/asciitab.h
===================================================================
--- vendor/Python/current/Modules/expat/asciitab.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/expat/asciitab.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,36 @@
+/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+   See the file COPYING for copying permission.
+*/
+
+/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML,
+/* 0x0C */ BT_NONXML, BT_CR, BT_NONXML, BT_NONXML,
+/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM,
+/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS,
+/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS,
+/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL,
+/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
+/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
+/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI,
+/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST,
+/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
+/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
+/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB,
+/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT,
+/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
+/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
+/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
+/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER,

Added: vendor/Python/current/Modules/expat/expat.h
===================================================================
--- vendor/Python/current/Modules/expat/expat.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/expat/expat.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1013 @@
+/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
+   See the file COPYING for copying permission.
+*/
+
+#ifndef Expat_INCLUDED
+#define Expat_INCLUDED 1
+
+#ifdef __VMS
+/*      0        1         2         3      0        1         2         3
+        1234567890123456789012345678901     1234567890123456789012345678901 */
+#define XML_SetProcessingInstructionHandler XML_SetProcessingInstrHandler
+#define XML_SetUnparsedEntityDeclHandler    XML_SetUnparsedEntDeclHandler
+#define XML_SetStartNamespaceDeclHandler    XML_SetStartNamespcDeclHandler
+#define XML_SetExternalEntityRefHandlerArg  XML_SetExternalEntRefHandlerArg
+#endif
+
+#include <stdlib.h>
+#include "expat_external.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct XML_ParserStruct;
+typedef struct XML_ParserStruct *XML_Parser;
+
+/* Should this be defined using stdbool.h when C99 is available? */
+typedef unsigned char XML_Bool;
+#define XML_TRUE   ((XML_Bool) 1)
+#define XML_FALSE  ((XML_Bool) 0)
+
+/* The XML_Status enum gives the possible return values for several
+   API functions.  The preprocessor #defines are included so this
+   stanza can be added to code that still needs to support older
+   versions of Expat 1.95.x:
+
+   #ifndef XML_STATUS_OK
+   #define XML_STATUS_OK    1
+   #define XML_STATUS_ERROR 0
+   #endif
+
+   Otherwise, the #define hackery is quite ugly and would have been
+   dropped.
+*/
+enum XML_Status {
+  XML_STATUS_ERROR = 0,
+#define XML_STATUS_ERROR XML_STATUS_ERROR
+  XML_STATUS_OK = 1,
+#define XML_STATUS_OK XML_STATUS_OK
+  XML_STATUS_SUSPENDED = 2
+#define XML_STATUS_SUSPENDED XML_STATUS_SUSPENDED
+};
+
+enum XML_Error {
+  XML_ERROR_NONE,
+  XML_ERROR_NO_MEMORY,
+  XML_ERROR_SYNTAX,
+  XML_ERROR_NO_ELEMENTS,
+  XML_ERROR_INVALID_TOKEN,
+  XML_ERROR_UNCLOSED_TOKEN,
+  XML_ERROR_PARTIAL_CHAR,
+  XML_ERROR_TAG_MISMATCH,
+  XML_ERROR_DUPLICATE_ATTRIBUTE,
+  XML_ERROR_JUNK_AFTER_DOC_ELEMENT,
+  XML_ERROR_PARAM_ENTITY_REF,
+  XML_ERROR_UNDEFINED_ENTITY,
+  XML_ERROR_RECURSIVE_ENTITY_REF,
+  XML_ERROR_ASYNC_ENTITY,
+  XML_ERROR_BAD_CHAR_REF,
+  XML_ERROR_BINARY_ENTITY_REF,
+  XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF,
+  XML_ERROR_MISPLACED_XML_PI,
+  XML_ERROR_UNKNOWN_ENCODING,
+  XML_ERROR_INCORRECT_ENCODING,
+  XML_ERROR_UNCLOSED_CDATA_SECTION,
+  XML_ERROR_EXTERNAL_ENTITY_HANDLING,
+  XML_ERROR_NOT_STANDALONE,
+  XML_ERROR_UNEXPECTED_STATE,
+  XML_ERROR_ENTITY_DECLARED_IN_PE,
+  XML_ERROR_FEATURE_REQUIRES_XML_DTD,
+  XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING,
+  /* Added in 1.95.7. */
+  XML_ERROR_UNBOUND_PREFIX,
+  /* Added in 1.95.8. */
+  XML_ERROR_UNDECLARING_PREFIX,
+  XML_ERROR_INCOMPLETE_PE,
+  XML_ERROR_XML_DECL,
+  XML_ERROR_TEXT_DECL,
+  XML_ERROR_PUBLICID,
+  XML_ERROR_SUSPENDED,
+  XML_ERROR_NOT_SUSPENDED,
+  XML_ERROR_ABORTED,
+  XML_ERROR_FINISHED,
+  XML_ERROR_SUSPEND_PE,
+  /* Added in 2.0. */
+  XML_ERROR_RESERVED_PREFIX_XML,
+  XML_ERROR_RESERVED_PREFIX_XMLNS,
+  XML_ERROR_RESERVED_NAMESPACE_URI
+};
+
+enum XML_Content_Type {
+  XML_CTYPE_EMPTY = 1,
+  XML_CTYPE_ANY,
+  XML_CTYPE_MIXED,
+  XML_CTYPE_NAME,
+  XML_CTYPE_CHOICE,
+  XML_CTYPE_SEQ
+};
+
+enum XML_Content_Quant {
+  XML_CQUANT_NONE,
+  XML_CQUANT_OPT,
+  XML_CQUANT_REP,
+  XML_CQUANT_PLUS
+};
+
+/* If type == XML_CTYPE_EMPTY or XML_CTYPE_ANY, then quant will be
+   XML_CQUANT_NONE, and the other fields will be zero or NULL.
+   If type == XML_CTYPE_MIXED, then quant will be NONE or REP and
+   numchildren will contain number of elements that may be mixed in
+   and children point to an array of XML_Content cells that will be
+   all of XML_CTYPE_NAME type with no quantification.
+
+   If type == XML_CTYPE_NAME, then the name points to the name, and
+   the numchildren field will be zero and children will be NULL. The
+   quant fields indicates any quantifiers placed on the name.
+
+   CHOICE and SEQ will have name NULL, the number of children in
+   numchildren and children will point, recursively, to an array
+   of XML_Content cells.
+
+   The EMPTY, ANY, and MIXED types will only occur at top level.
+*/
+
+typedef struct XML_cp XML_Content;
+
+struct XML_cp {
+  enum XML_Content_Type         type;
+  enum XML_Content_Quant        quant;
+  XML_Char *                    name;
+  unsigned int                  numchildren;
+  XML_Content *                 children;
+};
+
+
+/* This is called for an element declaration. See above for
+   description of the model argument. It's the caller's responsibility
+   to free model when finished with it.
+*/
+typedef void (XMLCALL *XML_ElementDeclHandler) (void *userData,
+                                                const XML_Char *name,
+                                                XML_Content *model);
+
+XMLPARSEAPI(void)
+XML_SetElementDeclHandler(XML_Parser parser,
+                          XML_ElementDeclHandler eldecl);
+
+/* The Attlist declaration handler is called for *each* attribute. So
+   a single Attlist declaration with multiple attributes declared will
+   generate multiple calls to this handler. The "default" parameter
+   may be NULL in the case of the "#IMPLIED" or "#REQUIRED"
+   keyword. The "isrequired" parameter will be true and the default
+   value will be NULL in the case of "#REQUIRED". If "isrequired" is
+   true and default is non-NULL, then this is a "#FIXED" default.
+*/
+typedef void (XMLCALL *XML_AttlistDeclHandler) (
+                                    void            *userData,
+                                    const XML_Char  *elname,
+                                    const XML_Char  *attname,
+                                    const XML_Char  *att_type,
+                                    const XML_Char  *dflt,
+                                    int              isrequired);
+
+XMLPARSEAPI(void)
+XML_SetAttlistDeclHandler(XML_Parser parser,
+                          XML_AttlistDeclHandler attdecl);
+
+/* The XML declaration handler is called for *both* XML declarations
+   and text declarations. The way to distinguish is that the version
+   parameter will be NULL for text declarations. The encoding
+   parameter may be NULL for XML declarations. The standalone
+   parameter will be -1, 0, or 1 indicating respectively that there
+   was no standalone parameter in the declaration, that it was given
+   as no, or that it was given as yes.
+*/
+typedef void (XMLCALL *XML_XmlDeclHandler) (void           *userData,
+                                            const XML_Char *version,
+                                            const XML_Char *encoding,
+                                            int             standalone);
+
+XMLPARSEAPI(void)
+XML_SetXmlDeclHandler(XML_Parser parser,
+                      XML_XmlDeclHandler xmldecl);
+
+
+typedef struct {
+  void *(*malloc_fcn)(size_t size);
+  void *(*realloc_fcn)(void *ptr, size_t size);
+  void (*free_fcn)(void *ptr);
+} XML_Memory_Handling_Suite;
+
+/* Constructs a new parser; encoding is the encoding specified by the
+   external protocol or NULL if there is none specified.
+*/
+XMLPARSEAPI(XML_Parser)
+XML_ParserCreate(const XML_Char *encoding);
+
+/* Constructs a new parser and namespace processor.  Element type
+   names and attribute names that belong to a namespace will be
+   expanded; unprefixed attribute names are never expanded; unprefixed
+   element type names are expanded only if there is a default
+   namespace. The expanded name is the concatenation of the namespace
+   URI, the namespace separator character, and the local part of the
+   name.  If the namespace separator is '\0' then the namespace URI
+   and the local part will be concatenated without any separator.
+   It is a programming error to use the separator '\0' with namespace
+   triplets (see XML_SetReturnNSTriplet).
+*/
+XMLPARSEAPI(XML_Parser)
+XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator);
+
+
+/* Constructs a new parser using the memory management suite referred to
+   by memsuite. If memsuite is NULL, then use the standard library memory
+   suite. If namespaceSeparator is non-NULL it creates a parser with
+   namespace processing as described above. The character pointed at
+   will serve as the namespace separator.
+
+   All further memory operations used for the created parser will come from
+   the given suite.
+*/
+XMLPARSEAPI(XML_Parser)
+XML_ParserCreate_MM(const XML_Char *encoding,
+                    const XML_Memory_Handling_Suite *memsuite,
+                    const XML_Char *namespaceSeparator);
+
+/* Prepare a parser object to be re-used.  This is particularly
+   valuable when memory allocation overhead is disproportionatly high,
+   such as when a large number of small documnents need to be parsed.
+   All handlers are cleared from the parser, except for the
+   unknownEncodingHandler. The parser's external state is re-initialized
+   except for the values of ns and ns_triplets.
+
+   Added in Expat 1.95.3.
+*/
+XMLPARSEAPI(XML_Bool)
+XML_ParserReset(XML_Parser parser, const XML_Char *encoding);
+
+/* atts is array of name/value pairs, terminated by 0;
+   names and values are 0 terminated.
+*/
+typedef void (XMLCALL *XML_StartElementHandler) (void *userData,
+                                                 const XML_Char *name,
+                                                 const XML_Char **atts);
+
+typedef void (XMLCALL *XML_EndElementHandler) (void *userData,
+                                               const XML_Char *name);
+
+
+/* s is not 0 terminated. */
+typedef void (XMLCALL *XML_CharacterDataHandler) (void *userData,
+                                                  const XML_Char *s,
+                                                  int len);
+
+/* target and data are 0 terminated */
+typedef void (XMLCALL *XML_ProcessingInstructionHandler) (
+                                                void *userData,
+                                                const XML_Char *target,
+                                                const XML_Char *data);
+
+/* data is 0 terminated */
+typedef void (XMLCALL *XML_CommentHandler) (void *userData,
+                                            const XML_Char *data);
+
+typedef void (XMLCALL *XML_StartCdataSectionHandler) (void *userData);
+typedef void (XMLCALL *XML_EndCdataSectionHandler) (void *userData);
+
+/* This is called for any characters in the XML document for which
+   there is no applicable handler.  This includes both characters that
+   are part of markup which is of a kind that is not reported
+   (comments, markup declarations), or characters that are part of a
+   construct which could be reported but for which no handler has been
+   supplied. The characters are passed exactly as they were in the XML
+   document except that they will be encoded in UTF-8 or UTF-16.
+   Line boundaries are not normalized. Note that a byte order mark
+   character is not passed to the default handler. There are no
+   guarantees about how characters are divided between calls to the
+   default handler: for example, a comment might be split between
+   multiple calls.
+*/
+typedef void (XMLCALL *XML_DefaultHandler) (void *userData,
+                                            const XML_Char *s,
+                                            int len);
+
+/* This is called for the start of the DOCTYPE declaration, before
+   any DTD or internal subset is parsed.
+*/
+typedef void (XMLCALL *XML_StartDoctypeDeclHandler) (
+                                            void *userData,
+                                            const XML_Char *doctypeName,
+                                            const XML_Char *sysid,
+                                            const XML_Char *pubid,
+                                            int has_internal_subset);
+
+/* This is called for the start of the DOCTYPE declaration when the
+   closing > is encountered, but after processing any external
+   subset.
+*/
+typedef void (XMLCALL *XML_EndDoctypeDeclHandler)(void *userData);
+
+/* This is called for entity declarations. The is_parameter_entity
+   argument will be non-zero if the entity is a parameter entity, zero
+   otherwise.
+
+   For internal entities (<!ENTITY foo "bar">), value will
+   be non-NULL and systemId, publicID, and notationName will be NULL.
+   The value string is NOT nul-terminated; the length is provided in
+   the value_length argument. Since it is legal to have zero-length
+   values, do not use this argument to test for internal entities.
+
+   For external entities, value will be NULL and systemId will be
+   non-NULL. The publicId argument will be NULL unless a public
+   identifier was provided. The notationName argument will have a
+   non-NULL value only for unparsed entity declarations.
+
+   Note that is_parameter_entity can't be changed to XML_Bool, since
+   that would break binary compatibility.
+*/
+typedef void (XMLCALL *XML_EntityDeclHandler) (
+                              void *userData,
+                              const XML_Char *entityName,
+                              int is_parameter_entity,
+                              const XML_Char *value,
+                              int value_length,
+                              const XML_Char *base,
+                              const XML_Char *systemId,
+                              const XML_Char *publicId,
+                              const XML_Char *notationName);
+
+XMLPARSEAPI(void)
+XML_SetEntityDeclHandler(XML_Parser parser,
+                         XML_EntityDeclHandler handler);
+
+/* OBSOLETE -- OBSOLETE -- OBSOLETE
+   This handler has been superceded by the EntityDeclHandler above.
+   It is provided here for backward compatibility.
+
+   This is called for a declaration of an unparsed (NDATA) entity.
+   The base argument is whatever was set by XML_SetBase. The
+   entityName, systemId and notationName arguments will never be
+   NULL. The other arguments may be.
+*/
+typedef void (XMLCALL *XML_UnparsedEntityDeclHandler) (
+                                    void *userData,
+                                    const XML_Char *entityName,
+                                    const XML_Char *base,
+                                    const XML_Char *systemId,
+                                    const XML_Char *publicId,
+                                    const XML_Char *notationName);
+
+/* This is called for a declaration of notation.  The base argument is
+   whatever was set by XML_SetBase. The notationName will never be
+   NULL.  The other arguments can be.
+*/
+typedef void (XMLCALL *XML_NotationDeclHandler) (
+                                    void *userData,
+                                    const XML_Char *notationName,
+                                    const XML_Char *base,
+                                    const XML_Char *systemId,
+                                    const XML_Char *publicId);
+
+/* When namespace processing is enabled, these are called once for
+   each namespace declaration. The call to the start and end element
+   handlers occur between the calls to the start and end namespace
+   declaration handlers. For an xmlns attribute, prefix will be
+   NULL.  For an xmlns="" attribute, uri will be NULL.
+*/
+typedef void (XMLCALL *XML_StartNamespaceDeclHandler) (
+                                    void *userData,
+                                    const XML_Char *prefix,
+                                    const XML_Char *uri);
+
+typedef void (XMLCALL *XML_EndNamespaceDeclHandler) (
+                                    void *userData,
+                                    const XML_Char *prefix);
+
+/* This is called if the document is not standalone, that is, it has an
+   external subset or a reference to a parameter entity, but does not
+   have standalone="yes". If this handler returns XML_STATUS_ERROR,
+   then processing will not continue, and the parser will return a
+   XML_ERROR_NOT_STANDALONE error.
+   If parameter entity parsing is enabled, then in addition to the
+   conditions above this handler will only be called if the referenced
+   entity was actually read.
+*/
+typedef int (XMLCALL *XML_NotStandaloneHandler) (void *userData);
+
+/* This is called for a reference to an external parsed general
+   entity.  The referenced entity is not automatically parsed.  The
+   application can parse it immediately or later using
+   XML_ExternalEntityParserCreate.
+
+   The parser argument is the parser parsing the entity containing the
+   reference; it can be passed as the parser argument to
+   XML_ExternalEntityParserCreate.  The systemId argument is the
+   system identifier as specified in the entity declaration; it will
+   not be NULL.
+
+   The base argument is the system identifier that should be used as
+   the base for resolving systemId if systemId was relative; this is
+   set by XML_SetBase; it may be NULL.
+
+   The publicId argument is the public identifier as specified in the
+   entity declaration, or NULL if none was specified; the whitespace
+   in the public identifier will have been normalized as required by
+   the XML spec.
+
+   The context argument specifies the parsing context in the format
+   expected by the context argument to XML_ExternalEntityParserCreate;
+   context is valid only until the handler returns, so if the
+   referenced entity is to be parsed later, it must be copied.
+   context is NULL only when the entity is a parameter entity.
+
+   The handler should return XML_STATUS_ERROR if processing should not
+   continue because of a fatal error in the handling of the external
+   entity.  In this case the calling parser will return an
+   XML_ERROR_EXTERNAL_ENTITY_HANDLING error.
+
+   Note that unlike other handlers the first argument is the parser,
+   not userData.
+*/
+typedef int (XMLCALL *XML_ExternalEntityRefHandler) (
+                                    XML_Parser parser,
+                                    const XML_Char *context,
+                                    const XML_Char *base,
+                                    const XML_Char *systemId,
+                                    const XML_Char *publicId);
+
+/* This is called in two situations:
+   1) An entity reference is encountered for which no declaration
+      has been read *and* this is not an error.
+   2) An internal entity reference is read, but not expanded, because
+      XML_SetDefaultHandler has been called.
+   Note: skipped parameter entities in declarations and skipped general
+         entities in attribute values cannot be reported, because
+         the event would be out of sync with the reporting of the
+         declarations or attribute values
+*/
+typedef void (XMLCALL *XML_SkippedEntityHandler) (
+                                    void *userData,
+                                    const XML_Char *entityName,
+                                    int is_parameter_entity);
+
+/* This structure is filled in by the XML_UnknownEncodingHandler to
+   provide information to the parser about encodings that are unknown
+   to the parser.
+
+   The map[b] member gives information about byte sequences whose
+   first byte is b.
+
+   If map[b] is c where c is >= 0, then b by itself encodes the
+   Unicode scalar value c.
+
+   If map[b] is -1, then the byte sequence is malformed.
+
+   If map[b] is -n, where n >= 2, then b is the first byte of an
+   n-byte sequence that encodes a single Unicode scalar value.
+
+   The data member will be passed as the first argument to the convert
+   function.
+
+   The convert function is used to convert multibyte sequences; s will
+   point to a n-byte sequence where map[(unsigned char)*s] == -n.  The
+   convert function must return the Unicode scalar value represented
+   by this byte sequence or -1 if the byte sequence is malformed.
+
+   The convert function may be NULL if the encoding is a single-byte
+   encoding, that is if map[b] >= -1 for all bytes b.
+
+   When the parser is finished with the encoding, then if release is
+   not NULL, it will call release passing it the data member; once
+   release has been called, the convert function will not be called
+   again.
+
+   Expat places certain restrictions on the encodings that are supported
+   using this mechanism.
+
+   1. Every ASCII character that can appear in a well-formed XML document,
+      other than the characters
+
+      $@\^`{}~
+
+      must be represented by a single byte, and that byte must be the
+      same byte that represents that character in ASCII.
+
+   2. No character may require more than 4 bytes to encode.
+
+   3. All characters encoded must have Unicode scalar values <=
+      0xFFFF, (i.e., characters that would be encoded by surrogates in
+      UTF-16 are  not allowed).  Note that this restriction doesn't
+      apply to the built-in support for UTF-8 and UTF-16.
+
+   4. No Unicode character may be encoded by more than one distinct
+      sequence of bytes.
+*/
+typedef struct {
+  int map[256];
+  void *data;
+  int (XMLCALL *convert)(void *data, const char *s);
+  void (XMLCALL *release)(void *data);
+} XML_Encoding;
+
+/* This is called for an encoding that is unknown to the parser.
+
+   The encodingHandlerData argument is that which was passed as the
+   second argument to XML_SetUnknownEncodingHandler.
+
+   The name argument gives the name of the encoding as specified in
+   the encoding declaration.
+
+   If the callback can provide information about the encoding, it must
+   fill in the XML_Encoding structure, and return XML_STATUS_OK.
+   Otherwise it must return XML_STATUS_ERROR.
+
+   If info does not describe a suitable encoding, then the parser will
+   return an XML_UNKNOWN_ENCODING error.
+*/
+typedef int (XMLCALL *XML_UnknownEncodingHandler) (
+                                    void *encodingHandlerData,
+                                    const XML_Char *name,
+                                    XML_Encoding *info);
+
+XMLPARSEAPI(void)
+XML_SetElementHandler(XML_Parser parser,
+                      XML_StartElementHandler start,
+                      XML_EndElementHandler end);
+
+XMLPARSEAPI(void)
+XML_SetStartElementHandler(XML_Parser parser,
+                           XML_StartElementHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetEndElementHandler(XML_Parser parser,
+                         XML_EndElementHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetCharacterDataHandler(XML_Parser parser,
+                            XML_CharacterDataHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetProcessingInstructionHandler(XML_Parser parser,
+                                    XML_ProcessingInstructionHandler handler);
+XMLPARSEAPI(void)
+XML_SetCommentHandler(XML_Parser parser,
+                      XML_CommentHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetCdataSectionHandler(XML_Parser parser,
+                           XML_StartCdataSectionHandler start,
+                           XML_EndCdataSectionHandler end);
+
+XMLPARSEAPI(void)
+XML_SetStartCdataSectionHandler(XML_Parser parser,
+                                XML_StartCdataSectionHandler start);
+
+XMLPARSEAPI(void)
+XML_SetEndCdataSectionHandler(XML_Parser parser,
+                              XML_EndCdataSectionHandler end);
+
+/* This sets the default handler and also inhibits expansion of
+   internal entities. These entity references will be passed to the
+   default handler, or to the skipped entity handler, if one is set.
+*/
+XMLPARSEAPI(void)
+XML_SetDefaultHandler(XML_Parser parser,
+                      XML_DefaultHandler handler);
+
+/* This sets the default handler but does not inhibit expansion of
+   internal entities.  The entity reference will not be passed to the
+   default handler.
+*/
+XMLPARSEAPI(void)
+XML_SetDefaultHandlerExpand(XML_Parser parser,
+                            XML_DefaultHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetDoctypeDeclHandler(XML_Parser parser,
+                          XML_StartDoctypeDeclHandler start,
+                          XML_EndDoctypeDeclHandler end);
+
+XMLPARSEAPI(void)
+XML_SetStartDoctypeDeclHandler(XML_Parser parser,
+                               XML_StartDoctypeDeclHandler start);
+
+XMLPARSEAPI(void)
+XML_SetEndDoctypeDeclHandler(XML_Parser parser,
+                             XML_EndDoctypeDeclHandler end);
+
+XMLPARSEAPI(void)
+XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
+                                 XML_UnparsedEntityDeclHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetNotationDeclHandler(XML_Parser parser,
+                           XML_NotationDeclHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetNamespaceDeclHandler(XML_Parser parser,
+                            XML_StartNamespaceDeclHandler start,
+                            XML_EndNamespaceDeclHandler end);
+
+XMLPARSEAPI(void)
+XML_SetStartNamespaceDeclHandler(XML_Parser parser,
+                                 XML_StartNamespaceDeclHandler start);
+
+XMLPARSEAPI(void)
+XML_SetEndNamespaceDeclHandler(XML_Parser parser,
+                               XML_EndNamespaceDeclHandler end);
+
+XMLPARSEAPI(void)
+XML_SetNotStandaloneHandler(XML_Parser parser,
+                            XML_NotStandaloneHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetExternalEntityRefHandler(XML_Parser parser,
+                                XML_ExternalEntityRefHandler handler);
+
+/* If a non-NULL value for arg is specified here, then it will be
+   passed as the first argument to the external entity ref handler
+   instead of the parser object.
+*/
+XMLPARSEAPI(void)
+XML_SetExternalEntityRefHandlerArg(XML_Parser parser,
+                                   void *arg);
+
+XMLPARSEAPI(void)
+XML_SetSkippedEntityHandler(XML_Parser parser,
+                            XML_SkippedEntityHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetUnknownEncodingHandler(XML_Parser parser,
+                              XML_UnknownEncodingHandler handler,
+                              void *encodingHandlerData);
+
+/* This can be called within a handler for a start element, end
+   element, processing instruction or character data.  It causes the
+   corresponding markup to be passed to the default handler.
+*/
+XMLPARSEAPI(void)
+XML_DefaultCurrent(XML_Parser parser);
+
+/* If do_nst is non-zero, and namespace processing is in effect, and
+   a name has a prefix (i.e. an explicit namespace qualifier) then
+   that name is returned as a triplet in a single string separated by
+   the separator character specified when the parser was created: URI
+   + sep + local_name + sep + prefix.
+
+   If do_nst is zero, then namespace information is returned in the
+   default manner (URI + sep + local_name) whether or not the name
+   has a prefix.
+
+   Note: Calling XML_SetReturnNSTriplet after XML_Parse or
+     XML_ParseBuffer has no effect.
+*/
+
+XMLPARSEAPI(void)
+XML_SetReturnNSTriplet(XML_Parser parser, int do_nst);
+
+/* This value is passed as the userData argument to callbacks. */
+XMLPARSEAPI(void)
+XML_SetUserData(XML_Parser parser, void *userData);
+
+/* Returns the last value set by XML_SetUserData or NULL. */
+#define XML_GetUserData(parser) (*(void **)(parser))
+
+/* This is equivalent to supplying an encoding argument to
+   XML_ParserCreate. On success XML_SetEncoding returns non-zero,
+   zero otherwise.
+   Note: Calling XML_SetEncoding after XML_Parse or XML_ParseBuffer
+     has no effect and returns XML_STATUS_ERROR.
+*/
+XMLPARSEAPI(enum XML_Status)
+XML_SetEncoding(XML_Parser parser, const XML_Char *encoding);
+
+/* If this function is called, then the parser will be passed as the
+   first argument to callbacks instead of userData.  The userData will
+   still be accessible using XML_GetUserData.
+*/
+XMLPARSEAPI(void)
+XML_UseParserAsHandlerArg(XML_Parser parser);
+
+/* If useDTD == XML_TRUE is passed to this function, then the parser
+   will assume that there is an external subset, even if none is
+   specified in the document. In such a case the parser will call the
+   externalEntityRefHandler with a value of NULL for the systemId
+   argument (the publicId and context arguments will be NULL as well).
+   Note: For the purpose of checking WFC: Entity Declared, passing
+     useDTD == XML_TRUE will make the parser behave as if the document
+     had a DTD with an external subset.
+   Note: If this function is called, then this must be done before
+     the first call to XML_Parse or XML_ParseBuffer, since it will
+     have no effect after that.  Returns
+     XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING.
+   Note: If the document does not have a DOCTYPE declaration at all,
+     then startDoctypeDeclHandler and endDoctypeDeclHandler will not
+     be called, despite an external subset being parsed.
+   Note: If XML_DTD is not defined when Expat is compiled, returns
+     XML_ERROR_FEATURE_REQUIRES_XML_DTD.
+*/
+XMLPARSEAPI(enum XML_Error)
+XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD);
+
+
+/* Sets the base to be used for resolving relative URIs in system
+   identifiers in declarations.  Resolving relative identifiers is
+   left to the application: this value will be passed through as the
+   base argument to the XML_ExternalEntityRefHandler,
+   XML_NotationDeclHandler and XML_UnparsedEntityDeclHandler. The base
+   argument will be copied.  Returns XML_STATUS_ERROR if out of memory,
+   XML_STATUS_OK otherwise.
+*/
+XMLPARSEAPI(enum XML_Status)
+XML_SetBase(XML_Parser parser, const XML_Char *base);
+
+XMLPARSEAPI(const XML_Char *)
+XML_GetBase(XML_Parser parser);
+
+/* Returns the number of the attribute/value pairs passed in last call
+   to the XML_StartElementHandler that were specified in the start-tag
+   rather than defaulted. Each attribute/value pair counts as 2; thus
+   this correspondds to an index into the atts array passed to the
+   XML_StartElementHandler.
+*/
+XMLPARSEAPI(int)
+XML_GetSpecifiedAttributeCount(XML_Parser parser);
+
+/* Returns the index of the ID attribute passed in the last call to
+   XML_StartElementHandler, or -1 if there is no ID attribute.  Each
+   attribute/value pair counts as 2; thus this correspondds to an
+   index into the atts array passed to the XML_StartElementHandler.
+*/
+XMLPARSEAPI(int)
+XML_GetIdAttributeIndex(XML_Parser parser);
+
+/* Parses some input. Returns XML_STATUS_ERROR if a fatal error is
+   detected.  The last call to XML_Parse must have isFinal true; len
+   may be zero for this call (or any other).
+
+   Though the return values for these functions has always been
+   described as a Boolean value, the implementation, at least for the
+   1.95.x series, has always returned exactly one of the XML_Status
+   values.
+*/
+XMLPARSEAPI(enum XML_Status)
+XML_Parse(XML_Parser parser, const char *s, int len, int isFinal);
+
+XMLPARSEAPI(void *)
+XML_GetBuffer(XML_Parser parser, int len);
+
+XMLPARSEAPI(enum XML_Status)
+XML_ParseBuffer(XML_Parser parser, int len, int isFinal);
+
+/* Stops parsing, causing XML_Parse() or XML_ParseBuffer() to return.
+   Must be called from within a call-back handler, except when aborting
+   (resumable = 0) an already suspended parser. Some call-backs may
+   still follow because they would otherwise get lost. Examples:
+   - endElementHandler() for empty elements when stopped in
+     startElementHandler(), 
+   - endNameSpaceDeclHandler() when stopped in endElementHandler(), 
+   and possibly others.
+
+   Can be called from most handlers, including DTD related call-backs,
+   except when parsing an external parameter entity and resumable != 0.
+   Returns XML_STATUS_OK when successful, XML_STATUS_ERROR otherwise.
+   Possible error codes: 
+   - XML_ERROR_SUSPENDED: when suspending an already suspended parser.
+   - XML_ERROR_FINISHED: when the parser has already finished.
+   - XML_ERROR_SUSPEND_PE: when suspending while parsing an external PE.
+
+   When resumable != 0 (true) then parsing is suspended, that is, 
+   XML_Parse() and XML_ParseBuffer() return XML_STATUS_SUSPENDED. 
+   Otherwise, parsing is aborted, that is, XML_Parse() and XML_ParseBuffer()
+   return XML_STATUS_ERROR with error code XML_ERROR_ABORTED.
+
+   *Note*:
+   This will be applied to the current parser instance only, that is, if
+   there is a parent parser then it will continue parsing when the
+   externalEntityRefHandler() returns. It is up to the implementation of
+   the externalEntityRefHandler() to call XML_StopParser() on the parent
+   parser (recursively), if one wants to stop parsing altogether.
+
+   When suspended, parsing can be resumed by calling XML_ResumeParser(). 
+*/
+XMLPARSEAPI(enum XML_Status)
+XML_StopParser(XML_Parser parser, XML_Bool resumable);
+
+/* Resumes parsing after it has been suspended with XML_StopParser().
+   Must not be called from within a handler call-back. Returns same
+   status codes as XML_Parse() or XML_ParseBuffer().
+   Additional error code XML_ERROR_NOT_SUSPENDED possible.   
+
+   *Note*:
+   This must be called on the most deeply nested child parser instance
+   first, and on its parent parser only after the child parser has finished,
+   to be applied recursively until the document entity's parser is restarted.
+   That is, the parent parser will not resume by itself and it is up to the
+   application to call XML_ResumeParser() on it at the appropriate moment.
+*/
+XMLPARSEAPI(enum XML_Status)
+XML_ResumeParser(XML_Parser parser);
+
+enum XML_Parsing {
+  XML_INITIALIZED,
+  XML_PARSING,
+  XML_FINISHED,
+  XML_SUSPENDED
+};
+
+typedef struct {
+  enum XML_Parsing parsing;
+  XML_Bool finalBuffer;
+} XML_ParsingStatus;
+
+/* Returns status of parser with respect to being initialized, parsing,
+   finished, or suspended and processing the final buffer.
+   XXX XML_Parse() and XML_ParseBuffer() should return XML_ParsingStatus,
+   XXX with XML_FINISHED_OK or XML_FINISHED_ERROR replacing XML_FINISHED
+*/
+XMLPARSEAPI(void)
+XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status);
+
+/* Creates an XML_Parser object that can parse an external general
+   entity; context is a '\0'-terminated string specifying the parse
+   context; encoding is a '\0'-terminated string giving the name of
+   the externally specified encoding, or NULL if there is no
+   externally specified encoding.  The context string consists of a
+   sequence of tokens separated by formfeeds (\f); a token consisting
+   of a name specifies that the general entity of the name is open; a
+   token of the form prefix=uri specifies the namespace for a
+   particular prefix; a token of the form =uri specifies the default
+   namespace.  This can be called at any point after the first call to
+   an ExternalEntityRefHandler so longer as the parser has not yet
+   been freed.  The new parser is completely independent and may
+   safely be used in a separate thread.  The handlers and userData are
+   initialized from the parser argument.  Returns NULL if out of memory.
+   Otherwise returns a new XML_Parser object.
+*/
+XMLPARSEAPI(XML_Parser)
+XML_ExternalEntityParserCreate(XML_Parser parser,
+                               const XML_Char *context,
+                               const XML_Char *encoding);
+
+enum XML_ParamEntityParsing {
+  XML_PARAM_ENTITY_PARSING_NEVER,
+  XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE,
+  XML_PARAM_ENTITY_PARSING_ALWAYS
+};
+
+/* Controls parsing of parameter entities (including the external DTD
+   subset). If parsing of parameter entities is enabled, then
+   references to external parameter entities (including the external
+   DTD subset) will be passed to the handler set with
+   XML_SetExternalEntityRefHandler.  The context passed will be 0.
+
+   Unlike external general entities, external parameter entities can
+   only be parsed synchronously.  If the external parameter entity is
+   to be parsed, it must be parsed during the call to the external
+   entity ref handler: the complete sequence of
+   XML_ExternalEntityParserCreate, XML_Parse/XML_ParseBuffer and
+   XML_ParserFree calls must be made during this call.  After
+   XML_ExternalEntityParserCreate has been called to create the parser
+   for the external parameter entity (context must be 0 for this
+   call), it is illegal to make any calls on the old parser until
+   XML_ParserFree has been called on the newly created parser.
+   If the library has been compiled without support for parameter
+   entity parsing (ie without XML_DTD being defined), then
+   XML_SetParamEntityParsing will return 0 if parsing of parameter
+   entities is requested; otherwise it will return non-zero.
+   Note: If XML_SetParamEntityParsing is called after XML_Parse or
+      XML_ParseBuffer, then it has no effect and will always return 0.
+*/
+XMLPARSEAPI(int)
+XML_SetParamEntityParsing(XML_Parser parser,
+                          enum XML_ParamEntityParsing parsing);
+
+/* If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then
+   XML_GetErrorCode returns information about the error.
+*/
+XMLPARSEAPI(enum XML_Error)
+XML_GetErrorCode(XML_Parser parser);
+
+/* These functions return information about the current parse
+   location.  They may be called from any callback called to report
+   some parse event; in this case the location is the location of the
+   first of the sequence of characters that generated the event.  When
+   called from callbacks generated by declarations in the document
+   prologue, the location identified isn't as neatly defined, but will
+   be within the relevant markup.  When called outside of the callback
+   functions, the position indicated will be just past the last parse
+   event (regardless of whether there was an associated callback).
+   
+   They may also be called after returning from a call to XML_Parse
+   or XML_ParseBuffer.  If the return value is XML_STATUS_ERROR then
+   the location is the location of the character at which the error
+   was detected; otherwise the location is the location of the last
+   parse event, as described above.
+*/
+XMLPARSEAPI(XML_Size) XML_GetCurrentLineNumber(XML_Parser parser);
+XMLPARSEAPI(XML_Size) XML_GetCurrentColumnNumber(XML_Parser parser);
+XMLPARSEAPI(XML_Index) XML_GetCurrentByteIndex(XML_Parser parser);
+
+/* Return the number of bytes in the current event.
+   Returns 0 if the event is in an internal entity.
+*/
+XMLPARSEAPI(int)
+XML_GetCurrentByteCount(XML_Parser parser);
+
+/* If XML_CONTEXT_BYTES is defined, returns the input buffer, sets
+   the integer pointed to by offset to the offset within this buffer
+   of the current parse position, and sets the integer pointed to by size
+   to the size of this buffer (the number of input bytes). Otherwise
+   returns a NULL pointer. Also returns a NULL pointer if a parse isn't
+   active.
+
+   NOTE: The character pointer returned should not be used outside
+   the handler that makes the call.
+*/
+XMLPARSEAPI(const char *)
+XML_GetInputContext(XML_Parser parser,
+                    int *offset,
+                    int *size);
+
+/* For backwards compatibility with previous versions. */
+#define XML_GetErrorLineNumber   XML_GetCurrentLineNumber
+#define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber
+#define XML_GetErrorByteIndex    XML_GetCurrentByteIndex
+
+/* Frees the content model passed to the element declaration handler */
+XMLPARSEAPI(void)
+XML_FreeContentModel(XML_Parser parser, XML_Content *model);
+
+/* Exposing the memory handling functions used in Expat */
+XMLPARSEAPI(void *)
+XML_MemMalloc(XML_Parser parser, size_t size);
+
+XMLPARSEAPI(void *)
+XML_MemRealloc(XML_Parser parser, void *ptr, size_t size);
+
+XMLPARSEAPI(void)
+XML_MemFree(XML_Parser parser, void *ptr);
+
+/* Frees memory used by the parser. */
+XMLPARSEAPI(void)
+XML_ParserFree(XML_Parser parser);
+
+/* Returns a string describing the error. */
+XMLPARSEAPI(const XML_LChar *)
+XML_ErrorString(enum XML_Error code);
+
+/* Return a string containing the version number of this expat */
+XMLPARSEAPI(const XML_LChar *)
+XML_ExpatVersion(void);
+
+typedef struct {
+  int major;
+  int minor;
+  int micro;
+} XML_Expat_Version;
+
+/* Return an XML_Expat_Version structure containing numeric version
+   number information for this version of expat.
+*/
+XMLPARSEAPI(XML_Expat_Version)
+XML_ExpatVersionInfo(void);
+
+/* Added in Expat 1.95.5. */
+enum XML_FeatureEnum {
+  XML_FEATURE_END = 0,
+  XML_FEATURE_UNICODE,
+  XML_FEATURE_UNICODE_WCHAR_T,
+  XML_FEATURE_DTD,
+  XML_FEATURE_CONTEXT_BYTES,
+  XML_FEATURE_MIN_SIZE,
+  XML_FEATURE_SIZEOF_XML_CHAR,
+  XML_FEATURE_SIZEOF_XML_LCHAR,
+  XML_FEATURE_NS
+  /* Additional features must be added to the end of this enum. */
+};
+
+typedef struct {
+  enum XML_FeatureEnum  feature;
+  const XML_LChar       *name;
+  long int              value;
+} XML_Feature;
+
+XMLPARSEAPI(const XML_Feature *)
+XML_GetFeatureList(void);
+
+
+/* Expat follows the GNU/Linux convention of odd number minor version for
+   beta/development releases and even number minor version for stable
+   releases. Micro is bumped with each release, and set to 0 with each
+   change to major or minor version.
+*/
+#define XML_MAJOR_VERSION 2
+#define XML_MINOR_VERSION 0
+#define XML_MICRO_VERSION 0
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* not Expat_INCLUDED */

Added: vendor/Python/current/Modules/expat/expat_config.h
===================================================================
--- vendor/Python/current/Modules/expat/expat_config.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/expat/expat_config.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,19 @@
+/*
+ * Expat configuration for python. This file is not part of the expat
+ * distribution.
+ */
+#ifndef EXPAT_CONFIG_H
+#define EXPAT_CONFIG_H
+
+#include <pyconfig.h>
+#ifdef WORDS_BIGENDIAN
+#define BYTEORDER 4321
+#else
+#define BYTEORDER 1234
+#endif
+
+#define XML_NS 1
+#define XML_DTD 1
+#define XML_CONTEXT_BYTES 1024
+
+#endif /* EXPAT_CONFIG_H */

Added: vendor/Python/current/Modules/expat/expat_external.h
===================================================================
--- vendor/Python/current/Modules/expat/expat_external.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/expat/expat_external.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,119 @@
+/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
+   See the file COPYING for copying permission.
+*/
+
+#ifndef Expat_External_INCLUDED
+#define Expat_External_INCLUDED 1
+
+/* External API definitions */
+
+/* Namespace external symbols to allow multiple libexpat version to
+   co-exist. */
+#include "pyexpatns.h"
+
+#if defined(_MSC_EXTENSIONS) && !defined(__BEOS__) && !defined(__CYGWIN__)
+#define XML_USE_MSC_EXTENSIONS 1
+#endif
+
+/* Expat tries very hard to make the API boundary very specifically
+   defined.  There are two macros defined to control this boundary;
+   each of these can be defined before including this header to
+   achieve some different behavior, but doing so it not recommended or
+   tested frequently.
+
+   XMLCALL    - The calling convention to use for all calls across the
+                "library boundary."  This will default to cdecl, and
+                try really hard to tell the compiler that's what we
+                want.
+
+   XMLIMPORT  - Whatever magic is needed to note that a function is
+                to be imported from a dynamically loaded library
+                (.dll, .so, or .sl, depending on your platform).
+
+   The XMLCALL macro was added in Expat 1.95.7.  The only one which is
+   expected to be directly useful in client code is XMLCALL.
+
+   Note that on at least some Unix versions, the Expat library must be
+   compiled with the cdecl calling convention as the default since
+   system headers may assume the cdecl convention.
+*/
+#ifndef XMLCALL
+#if defined(XML_USE_MSC_EXTENSIONS)
+#define XMLCALL __cdecl
+#elif defined(__GNUC__) && defined(__i386)
+#define XMLCALL __attribute__((cdecl))
+#else
+/* For any platform which uses this definition and supports more than
+   one calling convention, we need to extend this definition to
+   declare the convention used on that platform, if it's possible to
+   do so.
+
+   If this is the case for your platform, please file a bug report
+   with information on how to identify your platform via the C
+   pre-processor and how to specify the same calling convention as the
+   platform's malloc() implementation.
+*/
+#define XMLCALL
+#endif
+#endif  /* not defined XMLCALL */
+
+
+#if !defined(XML_STATIC) && !defined(XMLIMPORT)
+#ifndef XML_BUILDING_EXPAT
+/* using Expat from an application */
+
+#ifdef XML_USE_MSC_EXTENSIONS
+#define XMLIMPORT __declspec(dllimport)
+#endif
+
+#endif
+#endif  /* not defined XML_STATIC */
+
+
+/* If we didn't define it above, define it away: */
+#ifndef XMLIMPORT
+#define XMLIMPORT
+#endif
+
+
+#define XMLPARSEAPI(type) XMLIMPORT type XMLCALL
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef XML_UNICODE_WCHAR_T
+#define XML_UNICODE
+#endif
+
+#ifdef XML_UNICODE     /* Information is UTF-16 encoded. */
+#ifdef XML_UNICODE_WCHAR_T
+typedef wchar_t XML_Char;
+typedef wchar_t XML_LChar;
+#else
+typedef unsigned short XML_Char;
+typedef char XML_LChar;
+#endif /* XML_UNICODE_WCHAR_T */
+#else                  /* Information is UTF-8 encoded. */
+typedef char XML_Char;
+typedef char XML_LChar;
+#endif /* XML_UNICODE */
+
+#ifdef XML_LARGE_SIZE  /* Use large integers for file/stream positions. */
+#if defined(XML_USE_MSC_EXTENSIONS) && _MSC_VER < 1400
+typedef __int64 XML_Index; 
+typedef unsigned __int64 XML_Size;
+#else
+typedef long long XML_Index;
+typedef unsigned long long XML_Size;
+#endif
+#else
+typedef long XML_Index;
+typedef unsigned long XML_Size;
+#endif /* XML_LARGE_SIZE */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* not Expat_External_INCLUDED */

Added: vendor/Python/current/Modules/expat/iasciitab.h
===================================================================
--- vendor/Python/current/Modules/expat/iasciitab.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/expat/iasciitab.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,37 @@
+/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+   See the file COPYING for copying permission.
+*/
+
+/* Like asciitab.h, except that 0xD has code BT_S rather than BT_CR */
+/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML,
+/* 0x0C */ BT_NONXML, BT_S, BT_NONXML, BT_NONXML,
+/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM,
+/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS,
+/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS,
+/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL,
+/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
+/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
+/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI,
+/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST,
+/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
+/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
+/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB,
+/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT,
+/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
+/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
+/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
+/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER,

Added: vendor/Python/current/Modules/expat/internal.h
===================================================================
--- vendor/Python/current/Modules/expat/internal.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/expat/internal.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,73 @@
+/* internal.h
+
+   Internal definitions used by Expat.  This is not needed to compile
+   client code.
+
+   The following calling convention macros are defined for frequently
+   called functions:
+
+   FASTCALL    - Used for those internal functions that have a simple
+                 body and a low number of arguments and local variables.
+
+   PTRCALL     - Used for functions called though function pointers.
+
+   PTRFASTCALL - Like PTRCALL, but for low number of arguments.
+
+   inline      - Used for selected internal functions for which inlining
+                 may improve performance on some platforms.
+
+   Note: Use of these macros is based on judgement, not hard rules,
+         and therefore subject to change.
+*/
+
+#if defined(__GNUC__) && defined(__i386__)
+/* We'll use this version by default only where we know it helps.
+
+   regparm() generates warnings on Solaris boxes.   See SF bug #692878.
+
+   Instability reported with egcs on a RedHat Linux 7.3.
+   Let's comment out:
+   #define FASTCALL __attribute__((stdcall, regparm(3)))
+   and let's try this:
+*/
+#define FASTCALL __attribute__((regparm(3)))
+#define PTRFASTCALL __attribute__((regparm(3)))
+#endif
+
+/* Using __fastcall seems to have an unexpected negative effect under
+   MS VC++, especially for function pointers, so we won't use it for
+   now on that platform. It may be reconsidered for a future release
+   if it can be made more effective.
+   Likely reason: __fastcall on Windows is like stdcall, therefore
+   the compiler cannot perform stack optimizations for call clusters.
+*/
+
+/* Make sure all of these are defined if they aren't already. */
+
+#ifndef FASTCALL
+#define FASTCALL
+#endif
+
+#ifndef PTRCALL
+#define PTRCALL
+#endif
+
+#ifndef PTRFASTCALL
+#define PTRFASTCALL
+#endif
+
+#ifndef XML_MIN_SIZE
+#if !defined(__cplusplus) && !defined(inline)
+#ifdef __GNUC__
+#define inline __inline
+#endif /* __GNUC__ */
+#endif
+#endif /* XML_MIN_SIZE */
+
+#ifdef __cplusplus
+#define inline inline
+#else
+#ifndef inline
+#define inline
+#endif
+#endif

Added: vendor/Python/current/Modules/expat/latin1tab.h
===================================================================
--- vendor/Python/current/Modules/expat/latin1tab.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/expat/latin1tab.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,36 @@
+/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+   See the file COPYING for copying permission.
+*/
+
+/* 0x80 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0x84 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0x88 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0x8C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0x90 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0x94 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0x98 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0x9C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0xA0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0xA4 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0xA8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER,
+/* 0xAC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0xB0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0xB4 */ BT_OTHER, BT_NMSTRT, BT_OTHER, BT_NAME,
+/* 0xB8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER,
+/* 0xBC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0xC0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xC4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xC8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xCC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xD0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xD4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
+/* 0xD8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xDC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xE0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xE4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xE8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xEC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xF0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xF4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
+/* 0xF8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xFC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,

Added: vendor/Python/current/Modules/expat/macconfig.h
===================================================================
--- vendor/Python/current/Modules/expat/macconfig.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/expat/macconfig.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,53 @@
+/*================================================================
+** Copyright 2000, Clark Cooper
+** All rights reserved.
+**
+** This is free software. You are permitted to copy, distribute, or modify
+** it under the terms of the MIT/X license (contained in the COPYING file
+** with this distribution.)
+**
+*/
+
+#ifndef MACCONFIG_H
+#define MACCONFIG_H
+
+
+/* 1234 = LIL_ENDIAN, 4321 = BIGENDIAN */
+#define BYTEORDER  4321
+
+/* Define to 1 if you have the `bcopy' function. */
+#undef HAVE_BCOPY
+
+/* Define to 1 if you have the `memmove' function. */
+#define HAVE_MEMMOVE
+
+/* Define to 1 if you have a working `mmap' system call. */
+#undef HAVE_MMAP
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* whether byteorder is bigendian */
+#define WORDS_BIGENDIAN
+
+/* Define to specify how much context to retain around the current parse
+   point. */
+#undef XML_CONTEXT_BYTES
+
+/* Define to make parameter entity parsing functionality available. */
+#define XML_DTD
+
+/* Define to make XML Namespaces functionality available. */
+#define XML_NS
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to `long' if <sys/types.h> does not define. */
+#define off_t  long
+
+/* Define to `unsigned' if <sys/types.h> does not define. */
+#undef size_t
+
+
+#endif /* ifndef MACCONFIG_H */

Added: vendor/Python/current/Modules/expat/nametab.h
===================================================================
--- vendor/Python/current/Modules/expat/nametab.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/expat/nametab.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,150 @@
+static const unsigned namingBitmap[] = {
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+0x00000000, 0x04000000, 0x87FFFFFE, 0x07FFFFFE,
+0x00000000, 0x00000000, 0xFF7FFFFF, 0xFF7FFFFF,
+0xFFFFFFFF, 0x7FF3FFFF, 0xFFFFFDFE, 0x7FFFFFFF,
+0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFE00F, 0xFC31FFFF,
+0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF,
+0xFFFFFFFF, 0xF80001FF, 0x00000003, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0xFFFFD740, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD,
+0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF,
+0xFFFF0003, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF,
+0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE,
+0x0000007F, 0x00000000, 0xFFFF0000, 0x000707FF,
+0x00000000, 0x07FFFFFE, 0x000007FE, 0xFFFE0000,
+0xFFFFFFFF, 0x7CFFFFFF, 0x002F7FFF, 0x00000060,
+0xFFFFFFE0, 0x23FFFFFF, 0xFF000000, 0x00000003,
+0xFFF99FE0, 0x03C5FDFF, 0xB0000000, 0x00030003,
+0xFFF987E0, 0x036DFDFF, 0x5E000000, 0x001C0000,
+0xFFFBAFE0, 0x23EDFDFF, 0x00000000, 0x00000001,
+0xFFF99FE0, 0x23CDFDFF, 0xB0000000, 0x00000003,
+0xD63DC7E0, 0x03BFC718, 0x00000000, 0x00000000,
+0xFFFDDFE0, 0x03EFFDFF, 0x00000000, 0x00000003,
+0xFFFDDFE0, 0x03EFFDFF, 0x40000000, 0x00000003,
+0xFFFDDFE0, 0x03FFFDFF, 0x00000000, 0x00000003,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0xFFFFFFFE, 0x000D7FFF, 0x0000003F, 0x00000000,
+0xFEF02596, 0x200D6CAE, 0x0000001F, 0x00000000,
+0x00000000, 0x00000000, 0xFFFFFEFF, 0x000003FF,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0xFFFFFFFF, 0xFFFF003F, 0x007FFFFF,
+0x0007DAED, 0x50000000, 0x82315001, 0x002C62AB,
+0x40000000, 0xF580C900, 0x00000007, 0x02010800,
+0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+0x0FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x03FFFFFF,
+0x3F3FFFFF, 0xFFFFFFFF, 0xAAFF3F3F, 0x3FFFFFFF,
+0xFFFFFFFF, 0x5FDFFFFF, 0x0FCF1FDC, 0x1FDC1FFF,
+0x00000000, 0x00004C40, 0x00000000, 0x00000000,
+0x00000007, 0x00000000, 0x00000000, 0x00000000,
+0x00000080, 0x000003FE, 0xFFFFFFFE, 0xFFFFFFFF,
+0x001FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x07FFFFFF,
+0xFFFFFFE0, 0x00001FFF, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+0xFFFFFFFF, 0x0000003F, 0x00000000, 0x00000000,
+0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+0xFFFFFFFF, 0x0000000F, 0x00000000, 0x00000000,
+0x00000000, 0x07FF6000, 0x87FFFFFE, 0x07FFFFFE,
+0x00000000, 0x00800000, 0xFF7FFFFF, 0xFF7FFFFF,
+0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF,
+0xFFFFFFFF, 0xF80001FF, 0x00030003, 0x00000000,
+0xFFFFFFFF, 0xFFFFFFFF, 0x0000003F, 0x00000003,
+0xFFFFD7C0, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD,
+0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF,
+0xFFFF007B, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF,
+0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE,
+0xFFFE007F, 0xBBFFFFFB, 0xFFFF0016, 0x000707FF,
+0x00000000, 0x07FFFFFE, 0x0007FFFF, 0xFFFF03FF,
+0xFFFFFFFF, 0x7CFFFFFF, 0xFFEF7FFF, 0x03FF3DFF,
+0xFFFFFFEE, 0xF3FFFFFF, 0xFF1E3FFF, 0x0000FFCF,
+0xFFF99FEE, 0xD3C5FDFF, 0xB080399F, 0x0003FFCF,
+0xFFF987E4, 0xD36DFDFF, 0x5E003987, 0x001FFFC0,
+0xFFFBAFEE, 0xF3EDFDFF, 0x00003BBF, 0x0000FFC1,
+0xFFF99FEE, 0xF3CDFDFF, 0xB0C0398F, 0x0000FFC3,
+0xD63DC7EC, 0xC3BFC718, 0x00803DC7, 0x0000FF80,
+0xFFFDDFEE, 0xC3EFFDFF, 0x00603DDF, 0x0000FFC3,
+0xFFFDDFEC, 0xC3EFFDFF, 0x40603DDF, 0x0000FFC3,
+0xFFFDDFEC, 0xC3FFFDFF, 0x00803DCF, 0x0000FFC3,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0xFFFFFFFE, 0x07FF7FFF, 0x03FF7FFF, 0x00000000,
+0xFEF02596, 0x3BFF6CAE, 0x03FF3F5F, 0x00000000,
+0x03000000, 0xC2A003FF, 0xFFFFFEFF, 0xFFFE03FF,
+0xFEBF0FDF, 0x02FE3FFF, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x1FFF0000, 0x00000002,
+0x000000A0, 0x003EFFFE, 0xFFFFFFFE, 0xFFFFFFFF,
+0x661FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x77FFFFFF,
+};
+static const unsigned char nmstrtPages[] = {
+0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00,
+0x00, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13,
+0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x15, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+static const unsigned char namePages[] = {
+0x19, 0x03, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x00,
+0x00, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25,
+0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13,
+0x26, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x27, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};

Added: vendor/Python/current/Modules/expat/pyexpatns.h
===================================================================
--- vendor/Python/current/Modules/expat/pyexpatns.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/expat/pyexpatns.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,124 @@
+/* Copyright (c) 2005-2006 ActiveState Software Inc.
+ *
+ * Namespace all expat exported symbols to avoid dynamic loading symbol
+ * collisions when embedding Python.
+ *
+ * The Problem:
+ * - you embed Python in some app
+ * - the app dynamically loads libexpat of version X
+ * - the embedded Python imports pyexpat (which was built against
+ *   libexpat version X+n)
+ * --> pyexpat gets the expat symbols from the already loaded and *older*
+ *     libexpat: crash (Specifically the crash we observed was in
+ *     getting an old XML_ErrorString (from xmlparse.c) and then calling
+ *     it with newer values in the XML_Error enum:
+ *
+ *       // pyexpat.c, line 1970
+ *       ...
+ *       // Added in Expat 1.95.7.
+ *       MYCONST(XML_ERROR_UNBOUND_PREFIX);
+ *       ...
+ *
+ *
+ * The Solution:
+ * Prefix all a exported symbols with "PyExpat_". This is similar to
+ * what Mozilla does for some common libs:
+ * http://lxr.mozilla.org/seamonkey/source/modules/libimg/png/mozpngconf.h#115
+ *
+ * The list of relevant exported symbols can be had with this command:
+ * 
+       nm pyexpat.so \
+           | grep -v " [a-zBUA] " \
+           | grep -v "_fini\|_init\|initpyexpat"
+ *
+ * If any of those symbols are NOT prefixed with "PyExpat_" then
+ * a #define should be added for it here.
+ */
+
+#ifndef PYEXPATNS_H
+#define PYEXPATNS_H
+
+#define XML_DefaultCurrent              PyExpat_XML_DefaultCurrent
+#define XML_ErrorString                 PyExpat_XML_ErrorString
+#define XML_ExpatVersion                PyExpat_XML_ExpatVersion
+#define XML_ExpatVersionInfo            PyExpat_XML_ExpatVersionInfo
+#define XML_ExternalEntityParserCreate  PyExpat_XML_ExternalEntityParserCreate
+#define XML_FreeContentModel            PyExpat_XML_FreeContentModel
+#define XML_GetBase                     PyExpat_XML_GetBase
+#define XML_GetBuffer                   PyExpat_XML_GetBuffer
+#define XML_GetCurrentByteCount         PyExpat_XML_GetCurrentByteCount
+#define XML_GetCurrentByteIndex         PyExpat_XML_GetCurrentByteIndex
+#define XML_GetCurrentColumnNumber      PyExpat_XML_GetCurrentColumnNumber
+#define XML_GetCurrentLineNumber        PyExpat_XML_GetCurrentLineNumber
+#define XML_GetErrorCode                PyExpat_XML_GetErrorCode
+#define XML_GetFeatureList              PyExpat_XML_GetFeatureList
+#define XML_GetIdAttributeIndex         PyExpat_XML_GetIdAttributeIndex
+#define XML_GetInputContext             PyExpat_XML_GetInputContext
+#define XML_GetParsingStatus            PyExpat_XML_GetParsingStatus
+#define XML_GetSpecifiedAttributeCount  PyExpat_XML_GetSpecifiedAttributeCount
+#define XmlGetUtf16InternalEncoding     PyExpat_XmlGetUtf16InternalEncoding
+#define XmlGetUtf16InternalEncodingNS   PyExpat_XmlGetUtf16InternalEncodingNS
+#define XmlGetUtf8InternalEncoding      PyExpat_XmlGetUtf8InternalEncoding
+#define XmlGetUtf8InternalEncodingNS    PyExpat_XmlGetUtf8InternalEncodingNS
+#define XmlInitEncoding                 PyExpat_XmlInitEncoding
+#define XmlInitEncodingNS               PyExpat_XmlInitEncodingNS
+#define XmlInitUnknownEncoding          PyExpat_XmlInitUnknownEncoding
+#define XmlInitUnknownEncodingNS        PyExpat_XmlInitUnknownEncodingNS
+#define XML_MemFree                     PyExpat_XML_MemFree
+#define XML_MemMalloc                   PyExpat_XML_MemMalloc
+#define XML_MemRealloc                  PyExpat_XML_MemRealloc
+#define XML_Parse                       PyExpat_XML_Parse
+#define XML_ParseBuffer                 PyExpat_XML_ParseBuffer
+#define XML_ParserCreate                PyExpat_XML_ParserCreate
+#define XML_ParserCreate_MM             PyExpat_XML_ParserCreate_MM
+#define XML_ParserCreateNS              PyExpat_XML_ParserCreateNS
+#define XML_ParserFree                  PyExpat_XML_ParserFree
+#define XML_ParserReset                 PyExpat_XML_ParserReset
+#define XmlParseXmlDecl                 PyExpat_XmlParseXmlDecl
+#define XmlParseXmlDeclNS               PyExpat_XmlParseXmlDeclNS
+#define XmlPrologStateInit              PyExpat_XmlPrologStateInit
+#define XmlPrologStateInitExternalEntity    PyExpat_XmlPrologStateInitExternalEntity
+#define XML_ResumeParser                PyExpat_XML_ResumeParser
+#define XML_SetAttlistDeclHandler       PyExpat_XML_SetAttlistDeclHandler
+#define XML_SetBase                     PyExpat_XML_SetBase
+#define XML_SetCdataSectionHandler      PyExpat_XML_SetCdataSectionHandler
+#define XML_SetCharacterDataHandler     PyExpat_XML_SetCharacterDataHandler
+#define XML_SetCommentHandler           PyExpat_XML_SetCommentHandler
+#define XML_SetDefaultHandler           PyExpat_XML_SetDefaultHandler
+#define XML_SetDefaultHandlerExpand     PyExpat_XML_SetDefaultHandlerExpand
+#define XML_SetDoctypeDeclHandler       PyExpat_XML_SetDoctypeDeclHandler
+#define XML_SetElementDeclHandler       PyExpat_XML_SetElementDeclHandler
+#define XML_SetElementHandler           PyExpat_XML_SetElementHandler
+#define XML_SetEncoding                 PyExpat_XML_SetEncoding
+#define XML_SetEndCdataSectionHandler   PyExpat_XML_SetEndCdataSectionHandler
+#define XML_SetEndDoctypeDeclHandler    PyExpat_XML_SetEndDoctypeDeclHandler
+#define XML_SetEndElementHandler        PyExpat_XML_SetEndElementHandler
+#define XML_SetEndNamespaceDeclHandler  PyExpat_XML_SetEndNamespaceDeclHandler
+#define XML_SetEntityDeclHandler        PyExpat_XML_SetEntityDeclHandler
+#define XML_SetExternalEntityRefHandler PyExpat_XML_SetExternalEntityRefHandler
+#define XML_SetExternalEntityRefHandlerArg  PyExpat_XML_SetExternalEntityRefHandlerArg
+#define XML_SetNamespaceDeclHandler     PyExpat_XML_SetNamespaceDeclHandler
+#define XML_SetNotationDeclHandler      PyExpat_XML_SetNotationDeclHandler
+#define XML_SetNotStandaloneHandler     PyExpat_XML_SetNotStandaloneHandler
+#define XML_SetParamEntityParsing       PyExpat_XML_SetParamEntityParsing
+#define XML_SetProcessingInstructionHandler PyExpat_XML_SetProcessingInstructionHandler
+#define XML_SetReturnNSTriplet          PyExpat_XML_SetReturnNSTriplet
+#define XML_SetSkippedEntityHandler     PyExpat_XML_SetSkippedEntityHandler
+#define XML_SetStartCdataSectionHandler PyExpat_XML_SetStartCdataSectionHandler
+#define XML_SetStartDoctypeDeclHandler  PyExpat_XML_SetStartDoctypeDeclHandler
+#define XML_SetStartElementHandler      PyExpat_XML_SetStartElementHandler
+#define XML_SetStartNamespaceDeclHandler    PyExpat_XML_SetStartNamespaceDeclHandler
+#define XML_SetUnknownEncodingHandler   PyExpat_XML_SetUnknownEncodingHandler
+#define XML_SetUnparsedEntityDeclHandler    PyExpat_XML_SetUnparsedEntityDeclHandler
+#define XML_SetUserData                 PyExpat_XML_SetUserData
+#define XML_SetXmlDeclHandler           PyExpat_XML_SetXmlDeclHandler
+#define XmlSizeOfUnknownEncoding        PyExpat_XmlSizeOfUnknownEncoding
+#define XML_StopParser                  PyExpat_XML_StopParser
+#define XML_UseForeignDTD               PyExpat_XML_UseForeignDTD
+#define XML_UseParserAsHandlerArg       PyExpat_XML_UseParserAsHandlerArg
+#define XmlUtf16Encode                  PyExpat_XmlUtf16Encode
+#define XmlUtf8Encode                   PyExpat_XmlUtf8Encode
+
+
+#endif /* !PYEXPATNS_H */
+

Added: vendor/Python/current/Modules/expat/utf8tab.h
===================================================================
--- vendor/Python/current/Modules/expat/utf8tab.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/expat/utf8tab.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,37 @@
+/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+   See the file COPYING for copying permission.
+*/
+
+
+/* 0x80 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0x84 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0x88 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0x8C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0x90 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0x94 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0x98 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0x9C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xA0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xA4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xA8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xAC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xB0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xB4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xB8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xBC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xC0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xC4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xC8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xCC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xD0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xD4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xD8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xDC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xE0 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
+/* 0xE4 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
+/* 0xE8 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
+/* 0xEC */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
+/* 0xF0 */ BT_LEAD4, BT_LEAD4, BT_LEAD4, BT_LEAD4,
+/* 0xF4 */ BT_LEAD4, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0xF8 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0xFC */ BT_NONXML, BT_NONXML, BT_MALFORM, BT_MALFORM,

Added: vendor/Python/current/Modules/expat/winconfig.h
===================================================================
--- vendor/Python/current/Modules/expat/winconfig.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/expat/winconfig.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,30 @@
+/*================================================================
+** Copyright 2000, Clark Cooper
+** All rights reserved.
+**
+** This is free software. You are permitted to copy, distribute, or modify
+** it under the terms of the MIT/X license (contained in the COPYING file
+** with this distribution.)
+*/
+
+#ifndef WINCONFIG_H
+#define WINCONFIG_H
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+
+#include <memory.h>
+#include <string.h>
+
+#define XML_NS 1
+#define XML_DTD 1
+#define XML_CONTEXT_BYTES 1024
+
+/* we will assume all Windows platforms are little endian */
+#define BYTEORDER 1234
+
+/* Windows has memmove() available. */
+#define HAVE_MEMMOVE
+
+#endif /* ndef WINCONFIG_H */

Added: vendor/Python/current/Modules/expat/xmlparse.c
===================================================================
--- vendor/Python/current/Modules/expat/xmlparse.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/expat/xmlparse.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,6268 @@
+/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
+   See the file COPYING for copying permission.
+*/
+
+#define XML_BUILDING_EXPAT 1
+
+#ifdef COMPILED_FROM_DSP
+#include "winconfig.h"
+#elif defined(MACOS_CLASSIC)
+#include "macconfig.h"
+#elif defined(__amigaos4__)
+#include "amigaconfig.h"
+#elif defined(HAVE_EXPAT_CONFIG_H)
+#include <expat_config.h>
+#endif /* ndef COMPILED_FROM_DSP */
+
+#include <stddef.h>
+#include <string.h>                     /* memset(), memcpy() */
+#include <assert.h>
+
+#include "expat.h"
+
+#ifdef XML_UNICODE
+#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
+#define XmlConvert XmlUtf16Convert
+#define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
+#define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
+#define XmlEncode XmlUtf16Encode
+#define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1))
+typedef unsigned short ICHAR;
+#else
+#define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
+#define XmlConvert XmlUtf8Convert
+#define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
+#define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
+#define XmlEncode XmlUtf8Encode
+#define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
+typedef char ICHAR;
+#endif
+
+
+#ifndef XML_NS
+
+#define XmlInitEncodingNS XmlInitEncoding
+#define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
+#undef XmlGetInternalEncodingNS
+#define XmlGetInternalEncodingNS XmlGetInternalEncoding
+#define XmlParseXmlDeclNS XmlParseXmlDecl
+
+#endif
+
+#ifdef XML_UNICODE
+
+#ifdef XML_UNICODE_WCHAR_T
+#define XML_T(x) (const wchar_t)x
+#define XML_L(x) L ## x
+#else
+#define XML_T(x) (const unsigned short)x
+#define XML_L(x) x
+#endif
+
+#else
+
+#define XML_T(x) x
+#define XML_L(x) x
+
+#endif
+
+/* Round up n to be a multiple of sz, where sz is a power of 2. */
+#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
+
+/* Handle the case where memmove() doesn't exist. */
+#ifndef HAVE_MEMMOVE
+#ifdef HAVE_BCOPY
+#define memmove(d,s,l) bcopy((s),(d),(l))
+#else
+#error memmove does not exist on this platform, nor is a substitute available
+#endif /* HAVE_BCOPY */
+#endif /* HAVE_MEMMOVE */
+
+#include "internal.h"
+#include "xmltok.h"
+#include "xmlrole.h"
+
+typedef const XML_Char *KEY;
+
+typedef struct {
+  KEY name;
+} NAMED;
+
+typedef struct {
+  NAMED **v;
+  unsigned char power;
+  size_t size;
+  size_t used;
+  const XML_Memory_Handling_Suite *mem;
+} HASH_TABLE;
+
+/* Basic character hash algorithm, taken from Python's string hash:
+   h = h * 1000003 ^ character, the constant being a prime number.
+
+*/
+#ifdef XML_UNICODE
+#define CHAR_HASH(h, c) \
+  (((h) * 0xF4243) ^ (unsigned short)(c))
+#else
+#define CHAR_HASH(h, c) \
+  (((h) * 0xF4243) ^ (unsigned char)(c))
+#endif
+
+/* For probing (after a collision) we need a step size relative prime
+   to the hash table size, which is a power of 2. We use double-hashing,
+   since we can calculate a second hash value cheaply by taking those bits
+   of the first hash value that were discarded (masked out) when the table
+   index was calculated: index = hash & mask, where mask = table->size - 1.
+   We limit the maximum step size to table->size / 4 (mask >> 2) and make
+   it odd, since odd numbers are always relative prime to a power of 2.
+*/
+#define SECOND_HASH(hash, mask, power) \
+  ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2))
+#define PROBE_STEP(hash, mask, power) \
+  ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
+
+typedef struct {
+  NAMED **p;
+  NAMED **end;
+} HASH_TABLE_ITER;
+
+#define INIT_TAG_BUF_SIZE 32  /* must be a multiple of sizeof(XML_Char) */
+#define INIT_DATA_BUF_SIZE 1024
+#define INIT_ATTS_SIZE 16
+#define INIT_ATTS_VERSION 0xFFFFFFFF
+#define INIT_BLOCK_SIZE 1024
+#define INIT_BUFFER_SIZE 1024
+
+#define EXPAND_SPARE 24
+
+typedef struct binding {
+  struct prefix *prefix;
+  struct binding *nextTagBinding;
+  struct binding *prevPrefixBinding;
+  const struct attribute_id *attId;
+  XML_Char *uri;
+  int uriLen;
+  int uriAlloc;
+} BINDING;
+
+typedef struct prefix {
+  const XML_Char *name;
+  BINDING *binding;
+} PREFIX;
+
+typedef struct {
+  const XML_Char *str;
+  const XML_Char *localPart;
+  const XML_Char *prefix;
+  int strLen;
+  int uriLen;
+  int prefixLen;
+} TAG_NAME;
+
+/* TAG represents an open element.
+   The name of the element is stored in both the document and API
+   encodings.  The memory buffer 'buf' is a separately-allocated
+   memory area which stores the name.  During the XML_Parse()/
+   XMLParseBuffer() when the element is open, the memory for the 'raw'
+   version of the name (in the document encoding) is shared with the
+   document buffer.  If the element is open across calls to
+   XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
+   contain the 'raw' name as well.
+
+   A parser re-uses these structures, maintaining a list of allocated
+   TAG objects in a free list.
+*/
+typedef struct tag {
+  struct tag *parent;           /* parent of this element */
+  const char *rawName;          /* tagName in the original encoding */
+  int rawNameLength;
+  TAG_NAME name;                /* tagName in the API encoding */
+  char *buf;                    /* buffer for name components */
+  char *bufEnd;                 /* end of the buffer */
+  BINDING *bindings;
+} TAG;
+
+typedef struct {
+  const XML_Char *name;
+  const XML_Char *textPtr;
+  int textLen;                  /* length in XML_Chars */
+  int processed;                /* # of processed bytes - when suspended */
+  const XML_Char *systemId;
+  const XML_Char *base;
+  const XML_Char *publicId;
+  const XML_Char *notation;
+  XML_Bool open;
+  XML_Bool is_param;
+  XML_Bool is_internal; /* true if declared in internal subset outside PE */
+} ENTITY;
+
+typedef struct {
+  enum XML_Content_Type         type;
+  enum XML_Content_Quant        quant;
+  const XML_Char *              name;
+  int                           firstchild;
+  int                           lastchild;
+  int                           childcnt;
+  int                           nextsib;
+} CONTENT_SCAFFOLD;
+
+#define INIT_SCAFFOLD_ELEMENTS 32
+
+typedef struct block {
+  struct block *next;
+  int size;
+  XML_Char s[1];
+} BLOCK;
+
+typedef struct {
+  BLOCK *blocks;
+  BLOCK *freeBlocks;
+  const XML_Char *end;
+  XML_Char *ptr;
+  XML_Char *start;
+  const XML_Memory_Handling_Suite *mem;
+} STRING_POOL;
+
+/* The XML_Char before the name is used to determine whether
+   an attribute has been specified. */
+typedef struct attribute_id {
+  XML_Char *name;
+  PREFIX *prefix;
+  XML_Bool maybeTokenized;
+  XML_Bool xmlns;
+} ATTRIBUTE_ID;
+
+typedef struct {
+  const ATTRIBUTE_ID *id;
+  XML_Bool isCdata;
+  const XML_Char *value;
+} DEFAULT_ATTRIBUTE;
+
+typedef struct {
+  unsigned long version;
+  unsigned long hash;
+  const XML_Char *uriName;
+} NS_ATT;
+
+typedef struct {
+  const XML_Char *name;
+  PREFIX *prefix;
+  const ATTRIBUTE_ID *idAtt;
+  int nDefaultAtts;
+  int allocDefaultAtts;
+  DEFAULT_ATTRIBUTE *defaultAtts;
+} ELEMENT_TYPE;
+
+typedef struct {
+  HASH_TABLE generalEntities;
+  HASH_TABLE elementTypes;
+  HASH_TABLE attributeIds;
+  HASH_TABLE prefixes;
+  STRING_POOL pool;
+  STRING_POOL entityValuePool;
+  /* false once a parameter entity reference has been skipped */
+  XML_Bool keepProcessing;
+  /* true once an internal or external PE reference has been encountered;
+     this includes the reference to an external subset */
+  XML_Bool hasParamEntityRefs;
+  XML_Bool standalone;
+#ifdef XML_DTD
+  /* indicates if external PE has been read */
+  XML_Bool paramEntityRead;
+  HASH_TABLE paramEntities;
+#endif /* XML_DTD */
+  PREFIX defaultPrefix;
+  /* === scaffolding for building content model === */
+  XML_Bool in_eldecl;
+  CONTENT_SCAFFOLD *scaffold;
+  unsigned contentStringLen;
+  unsigned scaffSize;
+  unsigned scaffCount;
+  int scaffLevel;
+  int *scaffIndex;
+} DTD;
+
+typedef struct open_internal_entity {
+  const char *internalEventPtr;
+  const char *internalEventEndPtr;
+  struct open_internal_entity *next;
+  ENTITY *entity;
+  int startTagLevel;
+  XML_Bool betweenDecl; /* WFC: PE Between Declarations */
+} OPEN_INTERNAL_ENTITY;
+
+typedef enum XML_Error PTRCALL Processor(XML_Parser parser,
+                                         const char *start,
+                                         const char *end,
+                                         const char **endPtr);
+
+static Processor prologProcessor;
+static Processor prologInitProcessor;
+static Processor contentProcessor;
+static Processor cdataSectionProcessor;
+#ifdef XML_DTD
+static Processor ignoreSectionProcessor;
+static Processor externalParEntProcessor;
+static Processor externalParEntInitProcessor;
+static Processor entityValueProcessor;
+static Processor entityValueInitProcessor;
+#endif /* XML_DTD */
+static Processor epilogProcessor;
+static Processor errorProcessor;
+static Processor externalEntityInitProcessor;
+static Processor externalEntityInitProcessor2;
+static Processor externalEntityInitProcessor3;
+static Processor externalEntityContentProcessor;
+static Processor internalEntityProcessor;
+
+static enum XML_Error
+handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
+static enum XML_Error
+processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
+               const char *s, const char *next);
+static enum XML_Error
+initializeEncoding(XML_Parser parser);
+static enum XML_Error
+doProlog(XML_Parser parser, const ENCODING *enc, const char *s, 
+         const char *end, int tok, const char *next, const char **nextPtr, 
+         XML_Bool haveMore);
+static enum XML_Error
+processInternalEntity(XML_Parser parser, ENTITY *entity, 
+                      XML_Bool betweenDecl);
+static enum XML_Error
+doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
+          const char *start, const char *end, const char **endPtr, 
+          XML_Bool haveMore);
+static enum XML_Error
+doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr,
+               const char *end, const char **nextPtr, XML_Bool haveMore);
+#ifdef XML_DTD
+static enum XML_Error
+doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr,
+                const char *end, const char **nextPtr, XML_Bool haveMore);
+#endif /* XML_DTD */
+
+static enum XML_Error
+storeAtts(XML_Parser parser, const ENCODING *, const char *s,
+          TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
+static enum XML_Error
+addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
+           const XML_Char *uri, BINDING **bindingsPtr);
+static int
+defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata, 
+                XML_Bool isId, const XML_Char *dfltValue, XML_Parser parser);
+static enum XML_Error
+storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
+                    const char *, const char *, STRING_POOL *);
+static enum XML_Error
+appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
+                     const char *, const char *, STRING_POOL *);
+static ATTRIBUTE_ID *
+getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,
+               const char *end);
+static int
+setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
+static enum XML_Error
+storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start,
+                 const char *end);
+static int
+reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
+                            const char *start, const char *end);
+static int
+reportComment(XML_Parser parser, const ENCODING *enc, const char *start,
+              const char *end);
+static void
+reportDefault(XML_Parser parser, const ENCODING *enc, const char *start,
+              const char *end);
+
+static const XML_Char * getContext(XML_Parser parser);
+static XML_Bool
+setContext(XML_Parser parser, const XML_Char *context);
+
+static void FASTCALL normalizePublicId(XML_Char *s);
+
+static DTD * dtdCreate(const XML_Memory_Handling_Suite *ms);
+/* do not call if parentParser != NULL */
+static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms);
+static void
+dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms);
+static int
+dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms);
+static int
+copyEntityTable(HASH_TABLE *, STRING_POOL *, const HASH_TABLE *);
+
+static NAMED *
+lookup(HASH_TABLE *table, KEY name, size_t createSize);
+static void FASTCALL
+hashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms);
+static void FASTCALL hashTableClear(HASH_TABLE *);
+static void FASTCALL hashTableDestroy(HASH_TABLE *);
+static void FASTCALL
+hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
+static NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *);
+
+static void FASTCALL
+poolInit(STRING_POOL *, const XML_Memory_Handling_Suite *ms);
+static void FASTCALL poolClear(STRING_POOL *);
+static void FASTCALL poolDestroy(STRING_POOL *);
+static XML_Char *
+poolAppend(STRING_POOL *pool, const ENCODING *enc,
+           const char *ptr, const char *end);
+static XML_Char *
+poolStoreString(STRING_POOL *pool, const ENCODING *enc,
+                const char *ptr, const char *end);
+static XML_Bool FASTCALL poolGrow(STRING_POOL *pool);
+static const XML_Char * FASTCALL
+poolCopyString(STRING_POOL *pool, const XML_Char *s);
+static const XML_Char *
+poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
+static const XML_Char * FASTCALL
+poolAppendString(STRING_POOL *pool, const XML_Char *s);
+
+static int FASTCALL nextScaffoldPart(XML_Parser parser);
+static XML_Content * build_model(XML_Parser parser);
+static ELEMENT_TYPE *
+getElementType(XML_Parser parser, const ENCODING *enc,
+               const char *ptr, const char *end);
+
+static XML_Parser
+parserCreate(const XML_Char *encodingName,
+             const XML_Memory_Handling_Suite *memsuite,
+             const XML_Char *nameSep,
+             DTD *dtd);
+static void
+parserInit(XML_Parser parser, const XML_Char *encodingName);
+
+#define poolStart(pool) ((pool)->start)
+#define poolEnd(pool) ((pool)->ptr)
+#define poolLength(pool) ((pool)->ptr - (pool)->start)
+#define poolChop(pool) ((void)--(pool->ptr))
+#define poolLastChar(pool) (((pool)->ptr)[-1])
+#define poolDiscard(pool) ((pool)->ptr = (pool)->start)
+#define poolFinish(pool) ((pool)->start = (pool)->ptr)
+#define poolAppendChar(pool, c) \
+  (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
+   ? 0 \
+   : ((*((pool)->ptr)++ = c), 1))
+
+struct XML_ParserStruct {
+  /* The first member must be userData so that the XML_GetUserData
+     macro works. */
+  void *m_userData;
+  void *m_handlerArg;
+  char *m_buffer;
+  const XML_Memory_Handling_Suite m_mem;
+  /* first character to be parsed */
+  const char *m_bufferPtr;
+  /* past last character to be parsed */
+  char *m_bufferEnd;
+  /* allocated end of buffer */
+  const char *m_bufferLim;
+  XML_Index m_parseEndByteIndex;
+  const char *m_parseEndPtr;
+  XML_Char *m_dataBuf;
+  XML_Char *m_dataBufEnd;
+  XML_StartElementHandler m_startElementHandler;
+  XML_EndElementHandler m_endElementHandler;
+  XML_CharacterDataHandler m_characterDataHandler;
+  XML_ProcessingInstructionHandler m_processingInstructionHandler;
+  XML_CommentHandler m_commentHandler;
+  XML_StartCdataSectionHandler m_startCdataSectionHandler;
+  XML_EndCdataSectionHandler m_endCdataSectionHandler;
+  XML_DefaultHandler m_defaultHandler;
+  XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;
+  XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;
+  XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
+  XML_NotationDeclHandler m_notationDeclHandler;
+  XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
+  XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
+  XML_NotStandaloneHandler m_notStandaloneHandler;
+  XML_ExternalEntityRefHandler m_externalEntityRefHandler;
+  XML_Parser m_externalEntityRefHandlerArg;
+  XML_SkippedEntityHandler m_skippedEntityHandler;
+  XML_UnknownEncodingHandler m_unknownEncodingHandler;
+  XML_ElementDeclHandler m_elementDeclHandler;
+  XML_AttlistDeclHandler m_attlistDeclHandler;
+  XML_EntityDeclHandler m_entityDeclHandler;
+  XML_XmlDeclHandler m_xmlDeclHandler;
+  const ENCODING *m_encoding;
+  INIT_ENCODING m_initEncoding;
+  const ENCODING *m_internalEncoding;
+  const XML_Char *m_protocolEncodingName;
+  XML_Bool m_ns;
+  XML_Bool m_ns_triplets;
+  void *m_unknownEncodingMem;
+  void *m_unknownEncodingData;
+  void *m_unknownEncodingHandlerData;
+  void (XMLCALL *m_unknownEncodingRelease)(void *);
+  PROLOG_STATE m_prologState;
+  Processor *m_processor;
+  enum XML_Error m_errorCode;
+  const char *m_eventPtr;
+  const char *m_eventEndPtr;
+  const char *m_positionPtr;
+  OPEN_INTERNAL_ENTITY *m_openInternalEntities;
+  OPEN_INTERNAL_ENTITY *m_freeInternalEntities;
+  XML_Bool m_defaultExpandInternalEntities;
+  int m_tagLevel;
+  ENTITY *m_declEntity;
+  const XML_Char *m_doctypeName;
+  const XML_Char *m_doctypeSysid;
+  const XML_Char *m_doctypePubid;
+  const XML_Char *m_declAttributeType;
+  const XML_Char *m_declNotationName;
+  const XML_Char *m_declNotationPublicId;
+  ELEMENT_TYPE *m_declElementType;
+  ATTRIBUTE_ID *m_declAttributeId;
+  XML_Bool m_declAttributeIsCdata;
+  XML_Bool m_declAttributeIsId;
+  DTD *m_dtd;
+  const XML_Char *m_curBase;
+  TAG *m_tagStack;
+  TAG *m_freeTagList;
+  BINDING *m_inheritedBindings;
+  BINDING *m_freeBindingList;
+  int m_attsSize;
+  int m_nSpecifiedAtts;
+  int m_idAttIndex;
+  ATTRIBUTE *m_atts;
+  NS_ATT *m_nsAtts;
+  unsigned long m_nsAttsVersion;
+  unsigned char m_nsAttsPower;
+  POSITION m_position;
+  STRING_POOL m_tempPool;
+  STRING_POOL m_temp2Pool;
+  char *m_groupConnector;
+  unsigned int m_groupSize;
+  XML_Char m_namespaceSeparator;
+  XML_Parser m_parentParser;
+  XML_ParsingStatus m_parsingStatus;
+#ifdef XML_DTD
+  XML_Bool m_isParamEntity;
+  XML_Bool m_useForeignDTD;
+  enum XML_ParamEntityParsing m_paramEntityParsing;
+#endif
+};
+
+#define MALLOC(s) (parser->m_mem.malloc_fcn((s)))
+#define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))
+#define FREE(p) (parser->m_mem.free_fcn((p)))
+
+#define userData (parser->m_userData)
+#define handlerArg (parser->m_handlerArg)
+#define startElementHandler (parser->m_startElementHandler)
+#define endElementHandler (parser->m_endElementHandler)
+#define characterDataHandler (parser->m_characterDataHandler)
+#define processingInstructionHandler \
+        (parser->m_processingInstructionHandler)
+#define commentHandler (parser->m_commentHandler)
+#define startCdataSectionHandler \
+        (parser->m_startCdataSectionHandler)
+#define endCdataSectionHandler (parser->m_endCdataSectionHandler)
+#define defaultHandler (parser->m_defaultHandler)
+#define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)
+#define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)
+#define unparsedEntityDeclHandler \
+        (parser->m_unparsedEntityDeclHandler)
+#define notationDeclHandler (parser->m_notationDeclHandler)
+#define startNamespaceDeclHandler \
+        (parser->m_startNamespaceDeclHandler)
+#define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)
+#define notStandaloneHandler (parser->m_notStandaloneHandler)
+#define externalEntityRefHandler \
+        (parser->m_externalEntityRefHandler)
+#define externalEntityRefHandlerArg \
+        (parser->m_externalEntityRefHandlerArg)
+#define internalEntityRefHandler \
+        (parser->m_internalEntityRefHandler)
+#define skippedEntityHandler (parser->m_skippedEntityHandler)
+#define unknownEncodingHandler (parser->m_unknownEncodingHandler)
+#define elementDeclHandler (parser->m_elementDeclHandler)
+#define attlistDeclHandler (parser->m_attlistDeclHandler)
+#define entityDeclHandler (parser->m_entityDeclHandler)
+#define xmlDeclHandler (parser->m_xmlDeclHandler)
+#define encoding (parser->m_encoding)
+#define initEncoding (parser->m_initEncoding)
+#define internalEncoding (parser->m_internalEncoding)
+#define unknownEncodingMem (parser->m_unknownEncodingMem)
+#define unknownEncodingData (parser->m_unknownEncodingData)
+#define unknownEncodingHandlerData \
+  (parser->m_unknownEncodingHandlerData)
+#define unknownEncodingRelease (parser->m_unknownEncodingRelease)
+#define protocolEncodingName (parser->m_protocolEncodingName)
+#define ns (parser->m_ns)
+#define ns_triplets (parser->m_ns_triplets)
+#define prologState (parser->m_prologState)
+#define processor (parser->m_processor)
+#define errorCode (parser->m_errorCode)
+#define eventPtr (parser->m_eventPtr)
+#define eventEndPtr (parser->m_eventEndPtr)
+#define positionPtr (parser->m_positionPtr)
+#define position (parser->m_position)
+#define openInternalEntities (parser->m_openInternalEntities)
+#define freeInternalEntities (parser->m_freeInternalEntities)
+#define defaultExpandInternalEntities \
+        (parser->m_defaultExpandInternalEntities)
+#define tagLevel (parser->m_tagLevel)
+#define buffer (parser->m_buffer)
+#define bufferPtr (parser->m_bufferPtr)
+#define bufferEnd (parser->m_bufferEnd)
+#define parseEndByteIndex (parser->m_parseEndByteIndex)
+#define parseEndPtr (parser->m_parseEndPtr)
+#define bufferLim (parser->m_bufferLim)
+#define dataBuf (parser->m_dataBuf)
+#define dataBufEnd (parser->m_dataBufEnd)
+#define _dtd (parser->m_dtd)
+#define curBase (parser->m_curBase)
+#define declEntity (parser->m_declEntity)
+#define doctypeName (parser->m_doctypeName)
+#define doctypeSysid (parser->m_doctypeSysid)
+#define doctypePubid (parser->m_doctypePubid)
+#define declAttributeType (parser->m_declAttributeType)
+#define declNotationName (parser->m_declNotationName)
+#define declNotationPublicId (parser->m_declNotationPublicId)
+#define declElementType (parser->m_declElementType)
+#define declAttributeId (parser->m_declAttributeId)
+#define declAttributeIsCdata (parser->m_declAttributeIsCdata)
+#define declAttributeIsId (parser->m_declAttributeIsId)
+#define freeTagList (parser->m_freeTagList)
+#define freeBindingList (parser->m_freeBindingList)
+#define inheritedBindings (parser->m_inheritedBindings)
+#define tagStack (parser->m_tagStack)
+#define atts (parser->m_atts)
+#define attsSize (parser->m_attsSize)
+#define nSpecifiedAtts (parser->m_nSpecifiedAtts)
+#define idAttIndex (parser->m_idAttIndex)
+#define nsAtts (parser->m_nsAtts)
+#define nsAttsVersion (parser->m_nsAttsVersion)
+#define nsAttsPower (parser->m_nsAttsPower)
+#define tempPool (parser->m_tempPool)
+#define temp2Pool (parser->m_temp2Pool)
+#define groupConnector (parser->m_groupConnector)
+#define groupSize (parser->m_groupSize)
+#define namespaceSeparator (parser->m_namespaceSeparator)
+#define parentParser (parser->m_parentParser)
+#define ps_parsing (parser->m_parsingStatus.parsing)
+#define ps_finalBuffer (parser->m_parsingStatus.finalBuffer)
+#ifdef XML_DTD
+#define isParamEntity (parser->m_isParamEntity)
+#define useForeignDTD (parser->m_useForeignDTD)
+#define paramEntityParsing (parser->m_paramEntityParsing)
+#endif /* XML_DTD */
+
+XML_Parser XMLCALL
+XML_ParserCreate(const XML_Char *encodingName)
+{
+  return XML_ParserCreate_MM(encodingName, NULL, NULL);
+}
+
+XML_Parser XMLCALL
+XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
+{
+  XML_Char tmp[2];
+  *tmp = nsSep;
+  return XML_ParserCreate_MM(encodingName, NULL, tmp);
+}
+
+static const XML_Char implicitContext[] = {
+  'x', 'm', 'l', '=', 'h', 't', 't', 'p', ':', '/', '/',
+  'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
+  'X', 'M', 'L', '/', '1', '9', '9', '8', '/',
+  'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0'
+};
+
+XML_Parser XMLCALL
+XML_ParserCreate_MM(const XML_Char *encodingName,
+                    const XML_Memory_Handling_Suite *memsuite,
+                    const XML_Char *nameSep)
+{
+  XML_Parser parser = parserCreate(encodingName, memsuite, nameSep, NULL);
+  if (parser != NULL && ns) {
+    /* implicit context only set for root parser, since child
+       parsers (i.e. external entity parsers) will inherit it
+    */
+    if (!setContext(parser, implicitContext)) {
+      XML_ParserFree(parser);
+      return NULL;
+    }
+  }
+  return parser;
+}
+
+static XML_Parser
+parserCreate(const XML_Char *encodingName,
+             const XML_Memory_Handling_Suite *memsuite,
+             const XML_Char *nameSep,
+             DTD *dtd)
+{
+  XML_Parser parser;
+
+  if (memsuite) {
+    XML_Memory_Handling_Suite *mtemp;
+    parser = (XML_Parser)
+      memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));
+    if (parser != NULL) {
+      mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
+      mtemp->malloc_fcn = memsuite->malloc_fcn;
+      mtemp->realloc_fcn = memsuite->realloc_fcn;
+      mtemp->free_fcn = memsuite->free_fcn;
+    }
+  }
+  else {
+    XML_Memory_Handling_Suite *mtemp;
+    parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct));
+    if (parser != NULL) {
+      mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
+      mtemp->malloc_fcn = malloc;
+      mtemp->realloc_fcn = realloc;
+      mtemp->free_fcn = free;
+    }
+  }
+
+  if (!parser)
+    return parser;
+
+  buffer = NULL;
+  bufferLim = NULL;
+
+  attsSize = INIT_ATTS_SIZE;
+  atts = (ATTRIBUTE *)MALLOC(attsSize * sizeof(ATTRIBUTE));
+  if (atts == NULL) {
+    FREE(parser);
+    return NULL;
+  }
+  dataBuf = (XML_Char *)MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
+  if (dataBuf == NULL) {
+    FREE(atts);
+    FREE(parser);
+    return NULL;
+  }
+  dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
+
+  if (dtd)
+    _dtd = dtd;
+  else {
+    _dtd = dtdCreate(&parser->m_mem);
+    if (_dtd == NULL) {
+      FREE(dataBuf);
+      FREE(atts);
+      FREE(parser);
+      return NULL;
+    }
+  }
+
+  freeBindingList = NULL;
+  freeTagList = NULL;
+  freeInternalEntities = NULL;
+
+  groupSize = 0;
+  groupConnector = NULL;
+
+  unknownEncodingHandler = NULL;
+  unknownEncodingHandlerData = NULL;
+
+  namespaceSeparator = '!';
+  ns = XML_FALSE;
+  ns_triplets = XML_FALSE;
+
+  nsAtts = NULL;
+  nsAttsVersion = 0;
+  nsAttsPower = 0;
+
+  poolInit(&tempPool, &(parser->m_mem));
+  poolInit(&temp2Pool, &(parser->m_mem));
+  parserInit(parser, encodingName);
+
+  if (encodingName && !protocolEncodingName) {
+    XML_ParserFree(parser);
+    return NULL;
+  }
+
+  if (nameSep) {
+    ns = XML_TRUE;
+    internalEncoding = XmlGetInternalEncodingNS();
+    namespaceSeparator = *nameSep;
+  }
+  else {
+    internalEncoding = XmlGetInternalEncoding();
+  }
+
+  return parser;
+}
+
+static void
+parserInit(XML_Parser parser, const XML_Char *encodingName)
+{
+  processor = prologInitProcessor;
+  XmlPrologStateInit(&prologState);
+  protocolEncodingName = (encodingName != NULL
+                          ? poolCopyString(&tempPool, encodingName)
+                          : NULL);
+  curBase = NULL;
+  XmlInitEncoding(&initEncoding, &encoding, 0);
+  userData = NULL;
+  handlerArg = NULL;
+  startElementHandler = NULL;
+  endElementHandler = NULL;
+  characterDataHandler = NULL;
+  processingInstructionHandler = NULL;
+  commentHandler = NULL;
+  startCdataSectionHandler = NULL;
+  endCdataSectionHandler = NULL;
+  defaultHandler = NULL;
+  startDoctypeDeclHandler = NULL;
+  endDoctypeDeclHandler = NULL;
+  unparsedEntityDeclHandler = NULL;
+  notationDeclHandler = NULL;
+  startNamespaceDeclHandler = NULL;
+  endNamespaceDeclHandler = NULL;
+  notStandaloneHandler = NULL;
+  externalEntityRefHandler = NULL;
+  externalEntityRefHandlerArg = parser;
+  skippedEntityHandler = NULL;
+  elementDeclHandler = NULL;
+  attlistDeclHandler = NULL;
+  entityDeclHandler = NULL;
+  xmlDeclHandler = NULL;
+  bufferPtr = buffer;
+  bufferEnd = buffer;
+  parseEndByteIndex = 0;
+  parseEndPtr = NULL;
+  declElementType = NULL;
+  declAttributeId = NULL;
+  declEntity = NULL;
+  doctypeName = NULL;
+  doctypeSysid = NULL;
+  doctypePubid = NULL;
+  declAttributeType = NULL;
+  declNotationName = NULL;
+  declNotationPublicId = NULL;
+  declAttributeIsCdata = XML_FALSE;
+  declAttributeIsId = XML_FALSE;
+  memset(&position, 0, sizeof(POSITION));
+  errorCode = XML_ERROR_NONE;
+  eventPtr = NULL;
+  eventEndPtr = NULL;
+  positionPtr = NULL;
+  openInternalEntities = NULL;
+  defaultExpandInternalEntities = XML_TRUE;
+  tagLevel = 0;
+  tagStack = NULL;
+  inheritedBindings = NULL;
+  nSpecifiedAtts = 0;
+  unknownEncodingMem = NULL;
+  unknownEncodingRelease = NULL;
+  unknownEncodingData = NULL;
+  parentParser = NULL;
+  ps_parsing = XML_INITIALIZED;
+#ifdef XML_DTD
+  isParamEntity = XML_FALSE;
+  useForeignDTD = XML_FALSE;
+  paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
+#endif
+}
+
+/* moves list of bindings to freeBindingList */
+static void FASTCALL
+moveToFreeBindingList(XML_Parser parser, BINDING *bindings)
+{
+  while (bindings) {
+    BINDING *b = bindings;
+    bindings = bindings->nextTagBinding;
+    b->nextTagBinding = freeBindingList;
+    freeBindingList = b;
+  }
+}
+
+XML_Bool XMLCALL
+XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)
+{
+  TAG *tStk;
+  OPEN_INTERNAL_ENTITY *openEntityList;
+  if (parentParser)
+    return XML_FALSE;
+  /* move tagStack to freeTagList */
+  tStk = tagStack;
+  while (tStk) {
+    TAG *tag = tStk;
+    tStk = tStk->parent;
+    tag->parent = freeTagList;
+    moveToFreeBindingList(parser, tag->bindings);
+    tag->bindings = NULL;
+    freeTagList = tag;
+  }
+  /* move openInternalEntities to freeInternalEntities */
+  openEntityList = openInternalEntities;
+  while (openEntityList) {
+    OPEN_INTERNAL_ENTITY *openEntity = openEntityList;
+    openEntityList = openEntity->next;
+    openEntity->next = freeInternalEntities;
+    freeInternalEntities = openEntity;
+  }
+  moveToFreeBindingList(parser, inheritedBindings);
+  FREE(unknownEncodingMem);
+  if (unknownEncodingRelease)
+    unknownEncodingRelease(unknownEncodingData);
+  poolClear(&tempPool);
+  poolClear(&temp2Pool);
+  parserInit(parser, encodingName);
+  dtdReset(_dtd, &parser->m_mem);
+  return setContext(parser, implicitContext);
+}
+
+enum XML_Status XMLCALL
+XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
+{
+  /* Block after XML_Parse()/XML_ParseBuffer() has been called.
+     XXX There's no way for the caller to determine which of the
+     XXX possible error cases caused the XML_STATUS_ERROR return.
+  */
+  if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
+    return XML_STATUS_ERROR;
+  if (encodingName == NULL)
+    protocolEncodingName = NULL;
+  else {
+    protocolEncodingName = poolCopyString(&tempPool, encodingName);
+    if (!protocolEncodingName)
+      return XML_STATUS_ERROR;
+  }
+  return XML_STATUS_OK;
+}
+
+XML_Parser XMLCALL
+XML_ExternalEntityParserCreate(XML_Parser oldParser,
+                               const XML_Char *context,
+                               const XML_Char *encodingName)
+{
+  XML_Parser parser = oldParser;
+  DTD *newDtd = NULL;
+  DTD *oldDtd = _dtd;
+  XML_StartElementHandler oldStartElementHandler = startElementHandler;
+  XML_EndElementHandler oldEndElementHandler = endElementHandler;
+  XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
+  XML_ProcessingInstructionHandler oldProcessingInstructionHandler
+      = processingInstructionHandler;
+  XML_CommentHandler oldCommentHandler = commentHandler;
+  XML_StartCdataSectionHandler oldStartCdataSectionHandler
+      = startCdataSectionHandler;
+  XML_EndCdataSectionHandler oldEndCdataSectionHandler
+      = endCdataSectionHandler;
+  XML_DefaultHandler oldDefaultHandler = defaultHandler;
+  XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
+      = unparsedEntityDeclHandler;
+  XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;
+  XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
+      = startNamespaceDeclHandler;
+  XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
+      = endNamespaceDeclHandler;
+  XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
+  XML_ExternalEntityRefHandler oldExternalEntityRefHandler
+      = externalEntityRefHandler;
+  XML_SkippedEntityHandler oldSkippedEntityHandler = skippedEntityHandler;
+  XML_UnknownEncodingHandler oldUnknownEncodingHandler
+      = unknownEncodingHandler;
+  XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler;
+  XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler;
+  XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler;
+  XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler;
+  ELEMENT_TYPE * oldDeclElementType = declElementType;
+
+  void *oldUserData = userData;
+  void *oldHandlerArg = handlerArg;
+  XML_Bool oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
+  XML_Parser oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
+#ifdef XML_DTD
+  enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing;
+  int oldInEntityValue = prologState.inEntityValue;
+#endif
+  XML_Bool oldns_triplets = ns_triplets;
+
+#ifdef XML_DTD
+  if (!context)
+    newDtd = oldDtd;
+#endif /* XML_DTD */
+
+  /* Note that the magical uses of the pre-processor to make field
+     access look more like C++ require that `parser' be overwritten
+     here.  This makes this function more painful to follow than it
+     would be otherwise.
+  */
+  if (ns) {
+    XML_Char tmp[2];
+    *tmp = namespaceSeparator;
+    parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);
+  }
+  else {
+    parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);
+  }
+
+  if (!parser)
+    return NULL;
+
+  startElementHandler = oldStartElementHandler;
+  endElementHandler = oldEndElementHandler;
+  characterDataHandler = oldCharacterDataHandler;
+  processingInstructionHandler = oldProcessingInstructionHandler;
+  commentHandler = oldCommentHandler;
+  startCdataSectionHandler = oldStartCdataSectionHandler;
+  endCdataSectionHandler = oldEndCdataSectionHandler;
+  defaultHandler = oldDefaultHandler;
+  unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
+  notationDeclHandler = oldNotationDeclHandler;
+  startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
+  endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
+  notStandaloneHandler = oldNotStandaloneHandler;
+  externalEntityRefHandler = oldExternalEntityRefHandler;
+  skippedEntityHandler = oldSkippedEntityHandler;
+  unknownEncodingHandler = oldUnknownEncodingHandler;
+  elementDeclHandler = oldElementDeclHandler;
+  attlistDeclHandler = oldAttlistDeclHandler;
+  entityDeclHandler = oldEntityDeclHandler;
+  xmlDeclHandler = oldXmlDeclHandler;
+  declElementType = oldDeclElementType;
+  userData = oldUserData;
+  if (oldUserData == oldHandlerArg)
+    handlerArg = userData;
+  else
+    handlerArg = parser;
+  if (oldExternalEntityRefHandlerArg != oldParser)
+    externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
+  defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
+  ns_triplets = oldns_triplets;
+  parentParser = oldParser;
+#ifdef XML_DTD
+  paramEntityParsing = oldParamEntityParsing;
+  prologState.inEntityValue = oldInEntityValue;
+  if (context) {
+#endif /* XML_DTD */
+    if (!dtdCopy(_dtd, oldDtd, &parser->m_mem)
+      || !setContext(parser, context)) {
+      XML_ParserFree(parser);
+      return NULL;
+    }
+    processor = externalEntityInitProcessor;
+#ifdef XML_DTD
+  }
+  else {
+    /* The DTD instance referenced by _dtd is shared between the document's
+       root parser and external PE parsers, therefore one does not need to
+       call setContext. In addition, one also *must* not call setContext,
+       because this would overwrite existing prefix->binding pointers in
+       _dtd with ones that get destroyed with the external PE parser.
+       This would leave those prefixes with dangling pointers.
+    */
+    isParamEntity = XML_TRUE;
+    XmlPrologStateInitExternalEntity(&prologState);
+    processor = externalParEntInitProcessor;
+  }
+#endif /* XML_DTD */
+  return parser;
+}
+
+static void FASTCALL
+destroyBindings(BINDING *bindings, XML_Parser parser)
+{
+  for (;;) {
+    BINDING *b = bindings;
+    if (!b)
+      break;
+    bindings = b->nextTagBinding;
+    FREE(b->uri);
+    FREE(b);
+  }
+}
+
+void XMLCALL
+XML_ParserFree(XML_Parser parser)
+{
+  TAG *tagList;
+  OPEN_INTERNAL_ENTITY *entityList;
+  if (parser == NULL)
+    return;
+  /* free tagStack and freeTagList */
+  tagList = tagStack;
+  for (;;) {
+    TAG *p;
+    if (tagList == NULL) {
+      if (freeTagList == NULL)
+        break;
+      tagList = freeTagList;
+      freeTagList = NULL;
+    }
+    p = tagList;
+    tagList = tagList->parent;
+    FREE(p->buf);
+    destroyBindings(p->bindings, parser);
+    FREE(p);
+  }
+  /* free openInternalEntities and freeInternalEntities */
+  entityList = openInternalEntities;
+  for (;;) {
+    OPEN_INTERNAL_ENTITY *openEntity;
+    if (entityList == NULL) {
+      if (freeInternalEntities == NULL)
+        break;
+      entityList = freeInternalEntities;
+      freeInternalEntities = NULL;
+    }
+    openEntity = entityList;
+    entityList = entityList->next;
+    FREE(openEntity);
+  }
+
+  destroyBindings(freeBindingList, parser);
+  destroyBindings(inheritedBindings, parser);
+  poolDestroy(&tempPool);
+  poolDestroy(&temp2Pool);
+#ifdef XML_DTD
+  /* external parameter entity parsers share the DTD structure
+     parser->m_dtd with the root parser, so we must not destroy it
+  */
+  if (!isParamEntity && _dtd)
+#else
+  if (_dtd)
+#endif /* XML_DTD */
+    dtdDestroy(_dtd, (XML_Bool)!parentParser, &parser->m_mem);
+  FREE((void *)atts);
+  FREE(groupConnector);
+  FREE(buffer);
+  FREE(dataBuf);
+  FREE(nsAtts);
+  FREE(unknownEncodingMem);
+  if (unknownEncodingRelease)
+    unknownEncodingRelease(unknownEncodingData);
+  FREE(parser);
+}
+
+void XMLCALL
+XML_UseParserAsHandlerArg(XML_Parser parser)
+{
+  handlerArg = parser;
+}
+
+enum XML_Error XMLCALL
+XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)
+{
+#ifdef XML_DTD
+  /* block after XML_Parse()/XML_ParseBuffer() has been called */
+  if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
+    return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;
+  useForeignDTD = useDTD;
+  return XML_ERROR_NONE;
+#else
+  return XML_ERROR_FEATURE_REQUIRES_XML_DTD;
+#endif
+}
+
+void XMLCALL
+XML_SetReturnNSTriplet(XML_Parser parser, int do_nst)
+{
+  /* block after XML_Parse()/XML_ParseBuffer() has been called */
+  if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
+    return;
+  ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
+}
+
+void XMLCALL
+XML_SetUserData(XML_Parser parser, void *p)
+{
+  if (handlerArg == userData)
+    handlerArg = userData = p;
+  else
+    userData = p;
+}
+
+enum XML_Status XMLCALL
+XML_SetBase(XML_Parser parser, const XML_Char *p)
+{
+  if (p) {
+    p = poolCopyString(&_dtd->pool, p);
+    if (!p)
+      return XML_STATUS_ERROR;
+    curBase = p;
+  }
+  else
+    curBase = NULL;
+  return XML_STATUS_OK;
+}
+
+const XML_Char * XMLCALL
+XML_GetBase(XML_Parser parser)
+{
+  return curBase;
+}
+
+int XMLCALL
+XML_GetSpecifiedAttributeCount(XML_Parser parser)
+{
+  return nSpecifiedAtts;
+}
+
+int XMLCALL
+XML_GetIdAttributeIndex(XML_Parser parser)
+{
+  return idAttIndex;
+}
+
+void XMLCALL
+XML_SetElementHandler(XML_Parser parser,
+                      XML_StartElementHandler start,
+                      XML_EndElementHandler end)
+{
+  startElementHandler = start;
+  endElementHandler = end;
+}
+
+void XMLCALL
+XML_SetStartElementHandler(XML_Parser parser,
+                           XML_StartElementHandler start) {
+  startElementHandler = start;
+}
+
+void XMLCALL
+XML_SetEndElementHandler(XML_Parser parser,
+                         XML_EndElementHandler end) {
+  endElementHandler = end;
+}
+
+void XMLCALL
+XML_SetCharacterDataHandler(XML_Parser parser,
+                            XML_CharacterDataHandler handler)
+{
+  characterDataHandler = handler;
+}
+
+void XMLCALL
+XML_SetProcessingInstructionHandler(XML_Parser parser,
+                                    XML_ProcessingInstructionHandler handler)
+{
+  processingInstructionHandler = handler;
+}
+
+void XMLCALL
+XML_SetCommentHandler(XML_Parser parser,
+                      XML_CommentHandler handler)
+{
+  commentHandler = handler;
+}
+
+void XMLCALL
+XML_SetCdataSectionHandler(XML_Parser parser,
+                           XML_StartCdataSectionHandler start,
+                           XML_EndCdataSectionHandler end)
+{
+  startCdataSectionHandler = start;
+  endCdataSectionHandler = end;
+}
+
+void XMLCALL
+XML_SetStartCdataSectionHandler(XML_Parser parser,
+                                XML_StartCdataSectionHandler start) {
+  startCdataSectionHandler = start;
+}
+
+void XMLCALL
+XML_SetEndCdataSectionHandler(XML_Parser parser,
+                              XML_EndCdataSectionHandler end) {
+  endCdataSectionHandler = end;
+}
+
+void XMLCALL
+XML_SetDefaultHandler(XML_Parser parser,
+                      XML_DefaultHandler handler)
+{
+  defaultHandler = handler;
+  defaultExpandInternalEntities = XML_FALSE;
+}
+
+void XMLCALL
+XML_SetDefaultHandlerExpand(XML_Parser parser,
+                            XML_DefaultHandler handler)
+{
+  defaultHandler = handler;
+  defaultExpandInternalEntities = XML_TRUE;
+}
+
+void XMLCALL
+XML_SetDoctypeDeclHandler(XML_Parser parser,
+                          XML_StartDoctypeDeclHandler start,
+                          XML_EndDoctypeDeclHandler end)
+{
+  startDoctypeDeclHandler = start;
+  endDoctypeDeclHandler = end;
+}
+
+void XMLCALL
+XML_SetStartDoctypeDeclHandler(XML_Parser parser,
+                               XML_StartDoctypeDeclHandler start) {
+  startDoctypeDeclHandler = start;
+}
+
+void XMLCALL
+XML_SetEndDoctypeDeclHandler(XML_Parser parser,
+                             XML_EndDoctypeDeclHandler end) {
+  endDoctypeDeclHandler = end;
+}
+
+void XMLCALL
+XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
+                                 XML_UnparsedEntityDeclHandler handler)
+{
+  unparsedEntityDeclHandler = handler;
+}
+
+void XMLCALL
+XML_SetNotationDeclHandler(XML_Parser parser,
+                           XML_NotationDeclHandler handler)
+{
+  notationDeclHandler = handler;
+}
+
+void XMLCALL
+XML_SetNamespaceDeclHandler(XML_Parser parser,
+                            XML_StartNamespaceDeclHandler start,
+                            XML_EndNamespaceDeclHandler end)
+{
+  startNamespaceDeclHandler = start;
+  endNamespaceDeclHandler = end;
+}
+
+void XMLCALL
+XML_SetStartNamespaceDeclHandler(XML_Parser parser,
+                                 XML_StartNamespaceDeclHandler start) {
+  startNamespaceDeclHandler = start;
+}
+
+void XMLCALL
+XML_SetEndNamespaceDeclHandler(XML_Parser parser,
+                               XML_EndNamespaceDeclHandler end) {
+  endNamespaceDeclHandler = end;
+}
+
+void XMLCALL
+XML_SetNotStandaloneHandler(XML_Parser parser,
+                            XML_NotStandaloneHandler handler)
+{
+  notStandaloneHandler = handler;
+}
+
+void XMLCALL
+XML_SetExternalEntityRefHandler(XML_Parser parser,
+                                XML_ExternalEntityRefHandler handler)
+{
+  externalEntityRefHandler = handler;
+}
+
+void XMLCALL
+XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
+{
+  if (arg)
+    externalEntityRefHandlerArg = (XML_Parser)arg;
+  else
+    externalEntityRefHandlerArg = parser;
+}
+
+void XMLCALL
+XML_SetSkippedEntityHandler(XML_Parser parser,
+                            XML_SkippedEntityHandler handler)
+{
+  skippedEntityHandler = handler;
+}
+
+void XMLCALL
+XML_SetUnknownEncodingHandler(XML_Parser parser,
+                              XML_UnknownEncodingHandler handler,
+                              void *data)
+{
+  unknownEncodingHandler = handler;
+  unknownEncodingHandlerData = data;
+}
+
+void XMLCALL
+XML_SetElementDeclHandler(XML_Parser parser,
+                          XML_ElementDeclHandler eldecl)
+{
+  elementDeclHandler = eldecl;
+}
+
+void XMLCALL
+XML_SetAttlistDeclHandler(XML_Parser parser,
+                          XML_AttlistDeclHandler attdecl)
+{
+  attlistDeclHandler = attdecl;
+}
+
+void XMLCALL
+XML_SetEntityDeclHandler(XML_Parser parser,
+                         XML_EntityDeclHandler handler)
+{
+  entityDeclHandler = handler;
+}
+
+void XMLCALL
+XML_SetXmlDeclHandler(XML_Parser parser,
+                      XML_XmlDeclHandler handler) {
+  xmlDeclHandler = handler;
+}
+
+int XMLCALL
+XML_SetParamEntityParsing(XML_Parser parser,
+                          enum XML_ParamEntityParsing peParsing)
+{
+  /* block after XML_Parse()/XML_ParseBuffer() has been called */
+  if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
+    return 0;
+#ifdef XML_DTD
+  paramEntityParsing = peParsing;
+  return 1;
+#else
+  return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;
+#endif
+}
+
+enum XML_Status XMLCALL
+XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
+{
+  switch (ps_parsing) {
+  case XML_SUSPENDED:
+    errorCode = XML_ERROR_SUSPENDED;
+    return XML_STATUS_ERROR;
+  case XML_FINISHED:
+    errorCode = XML_ERROR_FINISHED;
+    return XML_STATUS_ERROR;
+  default:
+    ps_parsing = XML_PARSING;
+  }
+
+  if (len == 0) {
+    ps_finalBuffer = (XML_Bool)isFinal;
+    if (!isFinal)
+      return XML_STATUS_OK;
+    positionPtr = bufferPtr;
+    parseEndPtr = bufferEnd;
+
+    /* If data are left over from last buffer, and we now know that these
+       data are the final chunk of input, then we have to check them again
+       to detect errors based on that fact.
+    */
+    errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
+
+    if (errorCode == XML_ERROR_NONE) {
+      switch (ps_parsing) {
+      case XML_SUSPENDED:
+        XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
+        positionPtr = bufferPtr;
+        return XML_STATUS_SUSPENDED;
+      case XML_INITIALIZED: 
+      case XML_PARSING:
+        ps_parsing = XML_FINISHED;
+        /* fall through */
+      default:
+        return XML_STATUS_OK;
+      }
+    }
+    eventEndPtr = eventPtr;
+    processor = errorProcessor;
+    return XML_STATUS_ERROR;
+  }
+#ifndef XML_CONTEXT_BYTES
+  else if (bufferPtr == bufferEnd) {
+    const char *end;
+    int nLeftOver;
+    enum XML_Error result;
+    parseEndByteIndex += len;
+    positionPtr = s;
+    ps_finalBuffer = (XML_Bool)isFinal;
+
+    errorCode = processor(parser, s, parseEndPtr = s + len, &end);
+
+    if (errorCode != XML_ERROR_NONE) {
+      eventEndPtr = eventPtr;
+      processor = errorProcessor;
+      return XML_STATUS_ERROR;
+    }
+    else {
+      switch (ps_parsing) {
+      case XML_SUSPENDED:
+        result = XML_STATUS_SUSPENDED;
+        break;
+      case XML_INITIALIZED:
+      case XML_PARSING:
+        result = XML_STATUS_OK;
+        if (isFinal) {
+          ps_parsing = XML_FINISHED;
+          return result;
+        }
+      }
+    }
+
+    XmlUpdatePosition(encoding, positionPtr, end, &position);
+    nLeftOver = s + len - end;
+    if (nLeftOver) {
+      if (buffer == NULL || nLeftOver > bufferLim - buffer) {
+        /* FIXME avoid integer overflow */
+        char *temp;
+        temp = (buffer == NULL
+                ? (char *)MALLOC(len * 2)
+                : (char *)REALLOC(buffer, len * 2));
+        if (temp == NULL) {
+          errorCode = XML_ERROR_NO_MEMORY;
+          return XML_STATUS_ERROR;
+        }
+        buffer = temp;
+        if (!buffer) {
+          errorCode = XML_ERROR_NO_MEMORY;
+          eventPtr = eventEndPtr = NULL;
+          processor = errorProcessor;
+          return XML_STATUS_ERROR;
+        }
+        bufferLim = buffer + len * 2;
+      }
+      memcpy(buffer, end, nLeftOver);
+    }
+    bufferPtr = buffer;
+    bufferEnd = buffer + nLeftOver;
+    positionPtr = bufferPtr;
+    parseEndPtr = bufferEnd;
+    eventPtr = bufferPtr;
+    eventEndPtr = bufferPtr;
+    return result;
+  }
+#endif  /* not defined XML_CONTEXT_BYTES */
+  else {
+    void *buff = XML_GetBuffer(parser, len);
+    if (buff == NULL)
+      return XML_STATUS_ERROR;
+    else {
+      memcpy(buff, s, len);
+      return XML_ParseBuffer(parser, len, isFinal);
+    }
+  }
+}
+
+enum XML_Status XMLCALL
+XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
+{
+  const char *start;
+  enum XML_Status result = XML_STATUS_OK;
+
+  switch (ps_parsing) {
+  case XML_SUSPENDED:
+    errorCode = XML_ERROR_SUSPENDED;
+    return XML_STATUS_ERROR;
+  case XML_FINISHED:
+    errorCode = XML_ERROR_FINISHED;
+    return XML_STATUS_ERROR;
+  default:
+    ps_parsing = XML_PARSING;
+  }
+
+  start = bufferPtr;
+  positionPtr = start;
+  bufferEnd += len;
+  parseEndPtr = bufferEnd;
+  parseEndByteIndex += len;
+  ps_finalBuffer = (XML_Bool)isFinal;
+
+  errorCode = processor(parser, start, parseEndPtr, &bufferPtr);
+
+  if (errorCode != XML_ERROR_NONE) {
+    eventEndPtr = eventPtr;
+    processor = errorProcessor;
+    return XML_STATUS_ERROR;
+  }
+  else {
+    switch (ps_parsing) {
+    case XML_SUSPENDED:
+      result = XML_STATUS_SUSPENDED;
+      break;
+    case XML_INITIALIZED: 
+    case XML_PARSING:
+      if (isFinal) {
+        ps_parsing = XML_FINISHED;
+        return result;
+      }
+    default: ;  /* should not happen */
+    }
+  }
+
+  XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
+  positionPtr = bufferPtr;
+  return result;
+}
+
+void * XMLCALL
+XML_GetBuffer(XML_Parser parser, int len)
+{
+  switch (ps_parsing) {
+  case XML_SUSPENDED:
+    errorCode = XML_ERROR_SUSPENDED;
+    return NULL;
+  case XML_FINISHED:
+    errorCode = XML_ERROR_FINISHED;
+    return NULL;
+  default: ;
+  }
+
+  if (len > bufferLim - bufferEnd) {
+    /* FIXME avoid integer overflow */
+    int neededSize = len + (int)(bufferEnd - bufferPtr);
+#ifdef XML_CONTEXT_BYTES
+    int keep = (int)(bufferPtr - buffer);
+
+    if (keep > XML_CONTEXT_BYTES)
+      keep = XML_CONTEXT_BYTES;
+    neededSize += keep;
+#endif  /* defined XML_CONTEXT_BYTES */
+    if (neededSize  <= bufferLim - buffer) {
+#ifdef XML_CONTEXT_BYTES
+      if (keep < bufferPtr - buffer) {
+        int offset = (int)(bufferPtr - buffer) - keep;
+        memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);
+        bufferEnd -= offset;
+        bufferPtr -= offset;
+      }
+#else
+      memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
+      bufferEnd = buffer + (bufferEnd - bufferPtr);
+      bufferPtr = buffer;
+#endif  /* not defined XML_CONTEXT_BYTES */
+    }
+    else {
+      char *newBuf;
+      int bufferSize = (int)(bufferLim - bufferPtr);
+      if (bufferSize == 0)
+        bufferSize = INIT_BUFFER_SIZE;
+      do {
+        bufferSize *= 2;
+      } while (bufferSize < neededSize);
+      newBuf = (char *)MALLOC(bufferSize);
+      if (newBuf == 0) {
+        errorCode = XML_ERROR_NO_MEMORY;
+        return NULL;
+      }
+      bufferLim = newBuf + bufferSize;
+#ifdef XML_CONTEXT_BYTES
+      if (bufferPtr) {
+        int keep = (int)(bufferPtr - buffer);
+        if (keep > XML_CONTEXT_BYTES)
+          keep = XML_CONTEXT_BYTES;
+        memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep);
+        FREE(buffer);
+        buffer = newBuf;
+        bufferEnd = buffer + (bufferEnd - bufferPtr) + keep;
+        bufferPtr = buffer + keep;
+      }
+      else {
+        bufferEnd = newBuf + (bufferEnd - bufferPtr);
+        bufferPtr = buffer = newBuf;
+      }
+#else
+      if (bufferPtr) {
+        memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
+        FREE(buffer);
+      }
+      bufferEnd = newBuf + (bufferEnd - bufferPtr);
+      bufferPtr = buffer = newBuf;
+#endif  /* not defined XML_CONTEXT_BYTES */
+    }
+  }
+  return bufferEnd;
+}
+
+enum XML_Status XMLCALL
+XML_StopParser(XML_Parser parser, XML_Bool resumable)
+{
+  switch (ps_parsing) {
+  case XML_SUSPENDED:
+    if (resumable) {
+      errorCode = XML_ERROR_SUSPENDED;
+      return XML_STATUS_ERROR;
+    }
+    ps_parsing = XML_FINISHED;
+    break;
+  case XML_FINISHED:
+    errorCode = XML_ERROR_FINISHED;
+    return XML_STATUS_ERROR;
+  default:
+    if (resumable) {
+#ifdef XML_DTD
+      if (isParamEntity) {
+        errorCode = XML_ERROR_SUSPEND_PE;
+        return XML_STATUS_ERROR;
+      }
+#endif
+      ps_parsing = XML_SUSPENDED;
+    }
+    else
+      ps_parsing = XML_FINISHED;
+  }
+  return XML_STATUS_OK;
+}
+
+enum XML_Status XMLCALL
+XML_ResumeParser(XML_Parser parser)
+{
+  enum XML_Status result = XML_STATUS_OK;
+
+  if (ps_parsing != XML_SUSPENDED) {
+    errorCode = XML_ERROR_NOT_SUSPENDED;
+    return XML_STATUS_ERROR;
+  }
+  ps_parsing = XML_PARSING;
+
+  errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
+
+  if (errorCode != XML_ERROR_NONE) {
+    eventEndPtr = eventPtr;
+    processor = errorProcessor;
+    return XML_STATUS_ERROR;
+  }
+  else {
+    switch (ps_parsing) {
+    case XML_SUSPENDED:
+      result = XML_STATUS_SUSPENDED;
+      break;
+    case XML_INITIALIZED: 
+    case XML_PARSING:
+      if (ps_finalBuffer) {
+        ps_parsing = XML_FINISHED;
+        return result;
+      }
+    default: ;
+    }
+  }
+
+  XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
+  positionPtr = bufferPtr;
+  return result;
+}
+
+void XMLCALL
+XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status)
+{
+  assert(status != NULL);
+  *status = parser->m_parsingStatus;
+}
+
+enum XML_Error XMLCALL
+XML_GetErrorCode(XML_Parser parser)
+{
+  return errorCode;
+}
+
+XML_Index XMLCALL
+XML_GetCurrentByteIndex(XML_Parser parser)
+{
+  if (eventPtr)
+    return parseEndByteIndex - (parseEndPtr - eventPtr);
+  return -1;
+}
+
+int XMLCALL
+XML_GetCurrentByteCount(XML_Parser parser)
+{
+  if (eventEndPtr && eventPtr)
+    return (int)(eventEndPtr - eventPtr);
+  return 0;
+}
+
+const char * XMLCALL
+XML_GetInputContext(XML_Parser parser, int *offset, int *size)
+{
+#ifdef XML_CONTEXT_BYTES
+  if (eventPtr && buffer) {
+    *offset = (int)(eventPtr - buffer);
+    *size   = (int)(bufferEnd - buffer);
+    return buffer;
+  }
+#endif /* defined XML_CONTEXT_BYTES */
+  return (char *) 0;
+}
+
+XML_Size XMLCALL
+XML_GetCurrentLineNumber(XML_Parser parser)
+{
+  if (eventPtr && eventPtr >= positionPtr) {
+    XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
+    positionPtr = eventPtr;
+  }
+  return position.lineNumber + 1;
+}
+
+XML_Size XMLCALL
+XML_GetCurrentColumnNumber(XML_Parser parser)
+{
+  if (eventPtr && eventPtr >= positionPtr) {
+    XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
+    positionPtr = eventPtr;
+  }
+  return position.columnNumber;
+}
+
+void XMLCALL
+XML_FreeContentModel(XML_Parser parser, XML_Content *model)
+{
+  FREE(model);
+}
+
+void * XMLCALL
+XML_MemMalloc(XML_Parser parser, size_t size)
+{
+  return MALLOC(size);
+}
+
+void * XMLCALL
+XML_MemRealloc(XML_Parser parser, void *ptr, size_t size)
+{
+  return REALLOC(ptr, size);
+}
+
+void XMLCALL
+XML_MemFree(XML_Parser parser, void *ptr)
+{
+  FREE(ptr);
+}
+
+void XMLCALL
+XML_DefaultCurrent(XML_Parser parser)
+{
+  if (defaultHandler) {
+    if (openInternalEntities)
+      reportDefault(parser,
+                    internalEncoding,
+                    openInternalEntities->internalEventPtr,
+                    openInternalEntities->internalEventEndPtr);
+    else
+      reportDefault(parser, encoding, eventPtr, eventEndPtr);
+  }
+}
+
+const XML_LChar * XMLCALL
+XML_ErrorString(enum XML_Error code)
+{
+  static const XML_LChar* const message[] = {
+    0,
+    XML_L("out of memory"),
+    XML_L("syntax error"),
+    XML_L("no element found"),
+    XML_L("not well-formed (invalid token)"),
+    XML_L("unclosed token"),
+    XML_L("partial character"),
+    XML_L("mismatched tag"),
+    XML_L("duplicate attribute"),
+    XML_L("junk after document element"),
+    XML_L("illegal parameter entity reference"),
+    XML_L("undefined entity"),
+    XML_L("recursive entity reference"),
+    XML_L("asynchronous entity"),
+    XML_L("reference to invalid character number"),
+    XML_L("reference to binary entity"),
+    XML_L("reference to external entity in attribute"),
+    XML_L("XML or text declaration not at start of entity"),
+    XML_L("unknown encoding"),
+    XML_L("encoding specified in XML declaration is incorrect"),
+    XML_L("unclosed CDATA section"),
+    XML_L("error in processing external entity reference"),
+    XML_L("document is not standalone"),
+    XML_L("unexpected parser state - please send a bug report"),
+    XML_L("entity declared in parameter entity"),
+    XML_L("requested feature requires XML_DTD support in Expat"),
+    XML_L("cannot change setting once parsing has begun"),
+    XML_L("unbound prefix"),
+    XML_L("must not undeclare prefix"),
+    XML_L("incomplete markup in parameter entity"),
+    XML_L("XML declaration not well-formed"),
+    XML_L("text declaration not well-formed"),
+    XML_L("illegal character(s) in public id"),
+    XML_L("parser suspended"),
+    XML_L("parser not suspended"),
+    XML_L("parsing aborted"),
+    XML_L("parsing finished"),
+    XML_L("cannot suspend in external parameter entity"),
+    XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name"),
+    XML_L("reserved prefix (xmlns) must not be declared or undeclared"),
+    XML_L("prefix must not be bound to one of the reserved namespace names")
+  };
+  if (code > 0 && code < sizeof(message)/sizeof(message[0]))
+    return message[code];
+  return NULL;
+}
+
+const XML_LChar * XMLCALL
+XML_ExpatVersion(void) {
+
+  /* V1 is used to string-ize the version number. However, it would
+     string-ize the actual version macro *names* unless we get them
+     substituted before being passed to V1. CPP is defined to expand
+     a macro, then rescan for more expansions. Thus, we use V2 to expand
+     the version macros, then CPP will expand the resulting V1() macro
+     with the correct numerals. */
+  /* ### I'm assuming cpp is portable in this respect... */
+
+#define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)
+#define V2(a,b,c) XML_L("expat_")V1(a,b,c)
+
+  return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION);
+
+#undef V1
+#undef V2
+}
+
+XML_Expat_Version XMLCALL
+XML_ExpatVersionInfo(void)
+{
+  XML_Expat_Version version;
+
+  version.major = XML_MAJOR_VERSION;
+  version.minor = XML_MINOR_VERSION;
+  version.micro = XML_MICRO_VERSION;
+
+  return version;
+}
+
+const XML_Feature * XMLCALL
+XML_GetFeatureList(void)
+{
+  static const XML_Feature features[] = {
+    {XML_FEATURE_SIZEOF_XML_CHAR,  XML_L("sizeof(XML_Char)"),
+     sizeof(XML_Char)},
+    {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"),
+     sizeof(XML_LChar)},
+#ifdef XML_UNICODE
+    {XML_FEATURE_UNICODE,          XML_L("XML_UNICODE"), 0},
+#endif
+#ifdef XML_UNICODE_WCHAR_T
+    {XML_FEATURE_UNICODE_WCHAR_T,  XML_L("XML_UNICODE_WCHAR_T"), 0},
+#endif
+#ifdef XML_DTD
+    {XML_FEATURE_DTD,              XML_L("XML_DTD"), 0},
+#endif
+#ifdef XML_CONTEXT_BYTES
+    {XML_FEATURE_CONTEXT_BYTES,    XML_L("XML_CONTEXT_BYTES"),
+     XML_CONTEXT_BYTES},
+#endif
+#ifdef XML_MIN_SIZE
+    {XML_FEATURE_MIN_SIZE,         XML_L("XML_MIN_SIZE"), 0},
+#endif
+#ifdef XML_NS
+    {XML_FEATURE_NS,               XML_L("XML_NS"), 0},
+#endif
+    {XML_FEATURE_END,              NULL, 0}
+  };
+
+  return features;
+}
+
+/* Initially tag->rawName always points into the parse buffer;
+   for those TAG instances opened while the current parse buffer was
+   processed, and not yet closed, we need to store tag->rawName in a more
+   permanent location, since the parse buffer is about to be discarded.
+*/
+static XML_Bool
+storeRawNames(XML_Parser parser)
+{
+  TAG *tag = tagStack;
+  while (tag) {
+    int bufSize;
+    int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);
+    char *rawNameBuf = tag->buf + nameLen;
+    /* Stop if already stored.  Since tagStack is a stack, we can stop
+       at the first entry that has already been copied; everything
+       below it in the stack is already been accounted for in a
+       previous call to this function.
+    */
+    if (tag->rawName == rawNameBuf)
+      break;
+    /* For re-use purposes we need to ensure that the
+       size of tag->buf is a multiple of sizeof(XML_Char).
+    */
+    bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char));
+    if (bufSize > tag->bufEnd - tag->buf) {
+      char *temp = (char *)REALLOC(tag->buf, bufSize);
+      if (temp == NULL)
+        return XML_FALSE;
+      /* if tag->name.str points to tag->buf (only when namespace
+         processing is off) then we have to update it
+      */
+      if (tag->name.str == (XML_Char *)tag->buf)
+        tag->name.str = (XML_Char *)temp;
+      /* if tag->name.localPart is set (when namespace processing is on)
+         then update it as well, since it will always point into tag->buf
+      */
+      if (tag->name.localPart)
+        tag->name.localPart = (XML_Char *)temp + (tag->name.localPart -
+                                                  (XML_Char *)tag->buf);
+      tag->buf = temp;
+      tag->bufEnd = temp + bufSize;
+      rawNameBuf = temp + nameLen;
+    }
+    memcpy(rawNameBuf, tag->rawName, tag->rawNameLength);
+    tag->rawName = rawNameBuf;
+    tag = tag->parent;
+  }
+  return XML_TRUE;
+}
+
+static enum XML_Error PTRCALL
+contentProcessor(XML_Parser parser,
+                 const char *start,
+                 const char *end,
+                 const char **endPtr)
+{
+  enum XML_Error result = doContent(parser, 0, encoding, start, end, 
+                                    endPtr, (XML_Bool)!ps_finalBuffer);
+  if (result == XML_ERROR_NONE) {
+    if (!storeRawNames(parser))
+      return XML_ERROR_NO_MEMORY;
+  }
+  return result;
+}
+
+static enum XML_Error PTRCALL
+externalEntityInitProcessor(XML_Parser parser,
+                            const char *start,
+                            const char *end,
+                            const char **endPtr)
+{
+  enum XML_Error result = initializeEncoding(parser);
+  if (result != XML_ERROR_NONE)
+    return result;
+  processor = externalEntityInitProcessor2;
+  return externalEntityInitProcessor2(parser, start, end, endPtr);
+}
+
+static enum XML_Error PTRCALL
+externalEntityInitProcessor2(XML_Parser parser,
+                             const char *start,
+                             const char *end,
+                             const char **endPtr)
+{
+  const char *next = start; /* XmlContentTok doesn't always set the last arg */
+  int tok = XmlContentTok(encoding, start, end, &next);
+  switch (tok) {
+  case XML_TOK_BOM:
+    /* If we are at the end of the buffer, this would cause the next stage,
+       i.e. externalEntityInitProcessor3, to pass control directly to
+       doContent (by detecting XML_TOK_NONE) without processing any xml text
+       declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
+    */
+    if (next == end && !ps_finalBuffer) {
+      *endPtr = next;
+      return XML_ERROR_NONE;
+    }
+    start = next;
+    break;
+  case XML_TOK_PARTIAL:
+    if (!ps_finalBuffer) {
+      *endPtr = start;
+      return XML_ERROR_NONE;
+    }
+    eventPtr = start;
+    return XML_ERROR_UNCLOSED_TOKEN;
+  case XML_TOK_PARTIAL_CHAR:
+    if (!ps_finalBuffer) {
+      *endPtr = start;
+      return XML_ERROR_NONE;
+    }
+    eventPtr = start;
+    return XML_ERROR_PARTIAL_CHAR;
+  }
+  processor = externalEntityInitProcessor3;
+  return externalEntityInitProcessor3(parser, start, end, endPtr);
+}
+
+static enum XML_Error PTRCALL
+externalEntityInitProcessor3(XML_Parser parser,
+                             const char *start,
+                             const char *end,
+                             const char **endPtr)
+{
+  int tok;
+  const char *next = start; /* XmlContentTok doesn't always set the last arg */
+  eventPtr = start;
+  tok = XmlContentTok(encoding, start, end, &next);
+  eventEndPtr = next;
+
+  switch (tok) {
+  case XML_TOK_XML_DECL:
+    {
+      enum XML_Error result;
+      result = processXmlDecl(parser, 1, start, next);
+      if (result != XML_ERROR_NONE)
+        return result;
+      switch (ps_parsing) {
+      case XML_SUSPENDED: 
+        *endPtr = next;
+        return XML_ERROR_NONE;
+      case XML_FINISHED:
+        return XML_ERROR_ABORTED;
+      default:
+        start = next;
+      }
+    }
+    break;
+  case XML_TOK_PARTIAL:
+    if (!ps_finalBuffer) {
+      *endPtr = start;
+      return XML_ERROR_NONE;
+    }
+    return XML_ERROR_UNCLOSED_TOKEN;
+  case XML_TOK_PARTIAL_CHAR:
+    if (!ps_finalBuffer) {
+      *endPtr = start;
+      return XML_ERROR_NONE;
+    }
+    return XML_ERROR_PARTIAL_CHAR;
+  }
+  processor = externalEntityContentProcessor;
+  tagLevel = 1;
+  return externalEntityContentProcessor(parser, start, end, endPtr);
+}
+
+static enum XML_Error PTRCALL
+externalEntityContentProcessor(XML_Parser parser,
+                               const char *start,
+                               const char *end,
+                               const char **endPtr)
+{
+  enum XML_Error result = doContent(parser, 1, encoding, start, end, 
+                                    endPtr, (XML_Bool)!ps_finalBuffer);
+  if (result == XML_ERROR_NONE) {
+    if (!storeRawNames(parser))
+      return XML_ERROR_NO_MEMORY;
+  }
+  return result;
+}
+
+static enum XML_Error
+doContent(XML_Parser parser,
+          int startTagLevel,
+          const ENCODING *enc,
+          const char *s,
+          const char *end,
+          const char **nextPtr,
+          XML_Bool haveMore)
+{
+  /* save one level of indirection */
+  DTD * const dtd = _dtd;  
+
+  const char **eventPP;
+  const char **eventEndPP;
+  if (enc == encoding) {
+    eventPP = &eventPtr;
+    eventEndPP = &eventEndPtr;
+  }
+  else {
+    eventPP = &(openInternalEntities->internalEventPtr);
+    eventEndPP = &(openInternalEntities->internalEventEndPtr);
+  }
+  *eventPP = s;
+
+  for (;;) {
+    const char *next = s; /* XmlContentTok doesn't always set the last arg */
+    int tok = XmlContentTok(enc, s, end, &next);
+    *eventEndPP = next;
+    switch (tok) {
+    case XML_TOK_TRAILING_CR:
+      if (haveMore) {
+        *nextPtr = s;
+        return XML_ERROR_NONE;
+      }
+      *eventEndPP = end;
+      if (characterDataHandler) {
+        XML_Char c = 0xA;
+        characterDataHandler(handlerArg, &c, 1);
+      }
+      else if (defaultHandler)
+        reportDefault(parser, enc, s, end);
+      /* We are at the end of the final buffer, should we check for 
+         XML_SUSPENDED, XML_FINISHED? 
+      */
+      if (startTagLevel == 0)
+        return XML_ERROR_NO_ELEMENTS;
+      if (tagLevel != startTagLevel)
+        return XML_ERROR_ASYNC_ENTITY;
+      *nextPtr = end;
+      return XML_ERROR_NONE;
+    case XML_TOK_NONE:
+      if (haveMore) {
+        *nextPtr = s;
+        return XML_ERROR_NONE;
+      }
+      if (startTagLevel > 0) {
+        if (tagLevel != startTagLevel)
+          return XML_ERROR_ASYNC_ENTITY;
+        *nextPtr = s;
+        return XML_ERROR_NONE;
+      }
+      return XML_ERROR_NO_ELEMENTS;
+    case XML_TOK_INVALID:
+      *eventPP = next;
+      return XML_ERROR_INVALID_TOKEN;
+    case XML_TOK_PARTIAL:
+      if (haveMore) {
+        *nextPtr = s;
+        return XML_ERROR_NONE;
+      }
+      return XML_ERROR_UNCLOSED_TOKEN;
+    case XML_TOK_PARTIAL_CHAR:
+      if (haveMore) {
+        *nextPtr = s;
+        return XML_ERROR_NONE;
+      }
+      return XML_ERROR_PARTIAL_CHAR;
+    case XML_TOK_ENTITY_REF:
+      {
+        const XML_Char *name;
+        ENTITY *entity;
+        XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
+                                              s + enc->minBytesPerChar,
+                                              next - enc->minBytesPerChar);
+        if (ch) {
+          if (characterDataHandler)
+            characterDataHandler(handlerArg, &ch, 1);
+          else if (defaultHandler)
+            reportDefault(parser, enc, s, next);
+          break;
+        }
+        name = poolStoreString(&dtd->pool, enc,
+                                s + enc->minBytesPerChar,
+                                next - enc->minBytesPerChar);
+        if (!name)
+          return XML_ERROR_NO_MEMORY;
+        entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0);
+        poolDiscard(&dtd->pool);
+        /* First, determine if a check for an existing declaration is needed;
+           if yes, check that the entity exists, and that it is internal,
+           otherwise call the skipped entity or default handler.
+        */
+        if (!dtd->hasParamEntityRefs || dtd->standalone) {
+          if (!entity)
+            return XML_ERROR_UNDEFINED_ENTITY;
+          else if (!entity->is_internal)
+            return XML_ERROR_ENTITY_DECLARED_IN_PE;
+        }
+        else if (!entity) {
+          if (skippedEntityHandler)
+            skippedEntityHandler(handlerArg, name, 0);
+          else if (defaultHandler)
+            reportDefault(parser, enc, s, next);
+          break;
+        }
+        if (entity->open)
+          return XML_ERROR_RECURSIVE_ENTITY_REF;
+        if (entity->notation)
+          return XML_ERROR_BINARY_ENTITY_REF;
+        if (entity->textPtr) {
+          enum XML_Error result;
+          if (!defaultExpandInternalEntities) {
+            if (skippedEntityHandler)
+              skippedEntityHandler(handlerArg, entity->name, 0);
+            else if (defaultHandler)
+              reportDefault(parser, enc, s, next);
+            break;
+          }
+          result = processInternalEntity(parser, entity, XML_FALSE);
+          if (result != XML_ERROR_NONE)
+            return result;
+        }
+        else if (externalEntityRefHandler) {
+          const XML_Char *context;
+          entity->open = XML_TRUE;
+          context = getContext(parser);
+          entity->open = XML_FALSE;
+          if (!context)
+            return XML_ERROR_NO_MEMORY;
+          if (!externalEntityRefHandler(externalEntityRefHandlerArg,
+                                        context,
+                                        entity->base,
+                                        entity->systemId,
+                                        entity->publicId))
+            return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
+          poolDiscard(&tempPool);
+        }
+        else if (defaultHandler)
+          reportDefault(parser, enc, s, next);
+        break;
+      }
+    case XML_TOK_START_TAG_NO_ATTS:
+      /* fall through */
+    case XML_TOK_START_TAG_WITH_ATTS:
+      {
+        TAG *tag;
+        enum XML_Error result;
+        XML_Char *toPtr;
+        if (freeTagList) {
+          tag = freeTagList;
+          freeTagList = freeTagList->parent;
+        }
+        else {
+          tag = (TAG *)MALLOC(sizeof(TAG));
+          if (!tag)
+            return XML_ERROR_NO_MEMORY;
+          tag->buf = (char *)MALLOC(INIT_TAG_BUF_SIZE);
+          if (!tag->buf) {
+            FREE(tag);
+            return XML_ERROR_NO_MEMORY;
+          }
+          tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
+        }
+        tag->bindings = NULL;
+        tag->parent = tagStack;
+        tagStack = tag;
+        tag->name.localPart = NULL;
+        tag->name.prefix = NULL;
+        tag->rawName = s + enc->minBytesPerChar;
+        tag->rawNameLength = XmlNameLength(enc, tag->rawName);
+        ++tagLevel;
+        {
+          const char *rawNameEnd = tag->rawName + tag->rawNameLength;
+          const char *fromPtr = tag->rawName;
+          toPtr = (XML_Char *)tag->buf;
+          for (;;) {
+            int bufSize;
+            int convLen;
+            XmlConvert(enc,
+                       &fromPtr, rawNameEnd,
+                       (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
+            convLen = (int)(toPtr - (XML_Char *)tag->buf);
+            if (fromPtr == rawNameEnd) {
+              tag->name.strLen = convLen;
+              break;
+            }
+            bufSize = (int)(tag->bufEnd - tag->buf) << 1;
+            {
+              char *temp = (char *)REALLOC(tag->buf, bufSize);
+              if (temp == NULL)
+                return XML_ERROR_NO_MEMORY;
+              tag->buf = temp;
+              tag->bufEnd = temp + bufSize;
+              toPtr = (XML_Char *)temp + convLen;
+            }
+          }
+        }
+        tag->name.str = (XML_Char *)tag->buf;
+        *toPtr = XML_T('\0');
+        result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
+        if (result)
+          return result;
+        if (startElementHandler)
+          startElementHandler(handlerArg, tag->name.str,
+                              (const XML_Char **)atts);
+        else if (defaultHandler)
+          reportDefault(parser, enc, s, next);
+        poolClear(&tempPool);
+        break;
+      }
+    case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
+      /* fall through */
+    case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
+      {
+        const char *rawName = s + enc->minBytesPerChar;
+        enum XML_Error result;
+        BINDING *bindings = NULL;
+        XML_Bool noElmHandlers = XML_TRUE;
+        TAG_NAME name;
+        name.str = poolStoreString(&tempPool, enc, rawName,
+                                   rawName + XmlNameLength(enc, rawName));
+        if (!name.str)
+          return XML_ERROR_NO_MEMORY;
+        poolFinish(&tempPool);
+        result = storeAtts(parser, enc, s, &name, &bindings);
+        if (result)
+          return result;
+        poolFinish(&tempPool);
+        if (startElementHandler) {
+          startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
+          noElmHandlers = XML_FALSE;
+        }
+        if (endElementHandler) {
+          if (startElementHandler)
+            *eventPP = *eventEndPP;
+          endElementHandler(handlerArg, name.str);
+          noElmHandlers = XML_FALSE;
+        }
+        if (noElmHandlers && defaultHandler)
+          reportDefault(parser, enc, s, next);
+        poolClear(&tempPool);
+        while (bindings) {
+          BINDING *b = bindings;
+          if (endNamespaceDeclHandler)
+            endNamespaceDeclHandler(handlerArg, b->prefix->name);
+          bindings = bindings->nextTagBinding;
+          b->nextTagBinding = freeBindingList;
+          freeBindingList = b;
+          b->prefix->binding = b->prevPrefixBinding;
+        }
+      }
+      if (tagLevel == 0)
+        return epilogProcessor(parser, next, end, nextPtr);
+      break;
+    case XML_TOK_END_TAG:
+      if (tagLevel == startTagLevel)
+        return XML_ERROR_ASYNC_ENTITY;
+      else {
+        int len;
+        const char *rawName;
+        TAG *tag = tagStack;
+        tagStack = tag->parent;
+        tag->parent = freeTagList;
+        freeTagList = tag;
+        rawName = s + enc->minBytesPerChar*2;
+        len = XmlNameLength(enc, rawName);
+        if (len != tag->rawNameLength
+            || memcmp(tag->rawName, rawName, len) != 0) {
+          *eventPP = rawName;
+          return XML_ERROR_TAG_MISMATCH;
+        }
+        --tagLevel;
+        if (endElementHandler) {
+          const XML_Char *localPart;
+          const XML_Char *prefix;
+          XML_Char *uri;
+          localPart = tag->name.localPart;
+          if (ns && localPart) {
+            /* localPart and prefix may have been overwritten in
+               tag->name.str, since this points to the binding->uri
+               buffer which gets re-used; so we have to add them again
+            */
+            uri = (XML_Char *)tag->name.str + tag->name.uriLen;
+            /* don't need to check for space - already done in storeAtts() */
+            while (*localPart) *uri++ = *localPart++;
+            prefix = (XML_Char *)tag->name.prefix;
+            if (ns_triplets && prefix) {
+              *uri++ = namespaceSeparator;
+              while (*prefix) *uri++ = *prefix++;
+             }
+            *uri = XML_T('\0');
+          }
+          endElementHandler(handlerArg, tag->name.str);
+        }
+        else if (defaultHandler)
+          reportDefault(parser, enc, s, next);
+        while (tag->bindings) {
+          BINDING *b = tag->bindings;
+          if (endNamespaceDeclHandler)
+            endNamespaceDeclHandler(handlerArg, b->prefix->name);
+          tag->bindings = tag->bindings->nextTagBinding;
+          b->nextTagBinding = freeBindingList;
+          freeBindingList = b;
+          b->prefix->binding = b->prevPrefixBinding;
+        }
+        if (tagLevel == 0)
+          return epilogProcessor(parser, next, end, nextPtr);
+      }
+      break;
+    case XML_TOK_CHAR_REF:
+      {
+        int n = XmlCharRefNumber(enc, s);
+        if (n < 0)
+          return XML_ERROR_BAD_CHAR_REF;
+        if (characterDataHandler) {
+          XML_Char buf[XML_ENCODE_MAX];
+          characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
+        }
+        else if (defaultHandler)
+          reportDefault(parser, enc, s, next);
+      }
+      break;
+    case XML_TOK_XML_DECL:
+      return XML_ERROR_MISPLACED_XML_PI;
+    case XML_TOK_DATA_NEWLINE:
+      if (characterDataHandler) {
+        XML_Char c = 0xA;
+        characterDataHandler(handlerArg, &c, 1);
+      }
+      else if (defaultHandler)
+        reportDefault(parser, enc, s, next);
+      break;
+    case XML_TOK_CDATA_SECT_OPEN:
+      {
+        enum XML_Error result;
+        if (startCdataSectionHandler)
+          startCdataSectionHandler(handlerArg);
+#if 0
+        /* Suppose you doing a transformation on a document that involves
+           changing only the character data.  You set up a defaultHandler
+           and a characterDataHandler.  The defaultHandler simply copies
+           characters through.  The characterDataHandler does the
+           transformation and writes the characters out escaping them as
+           necessary.  This case will fail to work if we leave out the
+           following two lines (because & and < inside CDATA sections will
+           be incorrectly escaped).
+
+           However, now we have a start/endCdataSectionHandler, so it seems
+           easier to let the user deal with this.
+        */
+        else if (characterDataHandler)
+          characterDataHandler(handlerArg, dataBuf, 0);
+#endif
+        else if (defaultHandler)
+          reportDefault(parser, enc, s, next);
+        result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore);
+        if (result != XML_ERROR_NONE)
+          return result;
+        else if (!next) {
+          processor = cdataSectionProcessor;
+          return result;
+        }
+      }
+      break;
+    case XML_TOK_TRAILING_RSQB:
+      if (haveMore) {
+        *nextPtr = s;
+        return XML_ERROR_NONE;
+      }
+      if (characterDataHandler) {
+        if (MUST_CONVERT(enc, s)) {
+          ICHAR *dataPtr = (ICHAR *)dataBuf;
+          XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
+          characterDataHandler(handlerArg, dataBuf,
+                               (int)(dataPtr - (ICHAR *)dataBuf));
+        }
+        else
+          characterDataHandler(handlerArg,
+                               (XML_Char *)s,
+                               (int)((XML_Char *)end - (XML_Char *)s));
+      }
+      else if (defaultHandler)
+        reportDefault(parser, enc, s, end);
+      /* We are at the end of the final buffer, should we check for 
+         XML_SUSPENDED, XML_FINISHED? 
+      */
+      if (startTagLevel == 0) {
+        *eventPP = end;
+        return XML_ERROR_NO_ELEMENTS;
+      }
+      if (tagLevel != startTagLevel) {
+        *eventPP = end;
+        return XML_ERROR_ASYNC_ENTITY;
+      }
+      *nextPtr = end;
+      return XML_ERROR_NONE;
+    case XML_TOK_DATA_CHARS:
+      if (characterDataHandler) {
+        if (MUST_CONVERT(enc, s)) {
+          for (;;) {
+            ICHAR *dataPtr = (ICHAR *)dataBuf;
+            XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
+            *eventEndPP = s;
+            characterDataHandler(handlerArg, dataBuf,
+                                 (int)(dataPtr - (ICHAR *)dataBuf));
+            if (s == next)
+              break;
+            *eventPP = s;
+          }
+        }
+        else
+          characterDataHandler(handlerArg,
+                               (XML_Char *)s,
+                               (int)((XML_Char *)next - (XML_Char *)s));
+      }
+      else if (defaultHandler)
+        reportDefault(parser, enc, s, next);
+      break;
+    case XML_TOK_PI:
+      if (!reportProcessingInstruction(parser, enc, s, next))
+        return XML_ERROR_NO_MEMORY;
+      break;
+    case XML_TOK_COMMENT:
+      if (!reportComment(parser, enc, s, next))
+        return XML_ERROR_NO_MEMORY;
+      break;
+    default:
+      if (defaultHandler)
+        reportDefault(parser, enc, s, next);
+      break;
+    }
+    *eventPP = s = next;
+    switch (ps_parsing) {
+    case XML_SUSPENDED: 
+      *nextPtr = next;
+      return XML_ERROR_NONE;
+    case XML_FINISHED:
+      return XML_ERROR_ABORTED;
+    default: ;
+    }
+  }
+  /* not reached */
+}
+
+/* Precondition: all arguments must be non-NULL;
+   Purpose:
+   - normalize attributes
+   - check attributes for well-formedness
+   - generate namespace aware attribute names (URI, prefix)
+   - build list of attributes for startElementHandler
+   - default attributes
+   - process namespace declarations (check and report them)
+   - generate namespace aware element name (URI, prefix)
+*/
+static enum XML_Error
+storeAtts(XML_Parser parser, const ENCODING *enc,
+          const char *attStr, TAG_NAME *tagNamePtr,
+          BINDING **bindingsPtr)
+{
+  DTD * const dtd = _dtd;  /* save one level of indirection */
+  ELEMENT_TYPE *elementType;
+  int nDefaultAtts;
+  const XML_Char **appAtts;   /* the attribute list for the application */
+  int attIndex = 0;
+  int prefixLen;
+  int i;
+  int n;
+  XML_Char *uri;
+  int nPrefixes = 0;
+  BINDING *binding;
+  const XML_Char *localPart;
+
+  /* lookup the element type name */
+  elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, tagNamePtr->str,0);
+  if (!elementType) {
+    const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);
+    if (!name)
+      return XML_ERROR_NO_MEMORY;
+    elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, name,
+                                         sizeof(ELEMENT_TYPE));
+    if (!elementType)
+      return XML_ERROR_NO_MEMORY;
+    if (ns && !setElementTypePrefix(parser, elementType))
+      return XML_ERROR_NO_MEMORY;
+  }
+  nDefaultAtts = elementType->nDefaultAtts;
+
+  /* get the attributes from the tokenizer */
+  n = XmlGetAttributes(enc, attStr, attsSize, atts);
+  if (n + nDefaultAtts > attsSize) {
+    int oldAttsSize = attsSize;
+    ATTRIBUTE *temp;
+    attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
+    temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));
+    if (temp == NULL)
+      return XML_ERROR_NO_MEMORY;
+    atts = temp;
+    if (n > oldAttsSize)
+      XmlGetAttributes(enc, attStr, n, atts);
+  }
+
+  appAtts = (const XML_Char **)atts;
+  for (i = 0; i < n; i++) {
+    /* add the name and value to the attribute list */
+    ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name,
+                                         atts[i].name
+                                         + XmlNameLength(enc, atts[i].name));
+    if (!attId)
+      return XML_ERROR_NO_MEMORY;
+    /* Detect duplicate attributes by their QNames. This does not work when
+       namespace processing is turned on and different prefixes for the same
+       namespace are used. For this case we have a check further down.
+    */
+    if ((attId->name)[-1]) {
+      if (enc == encoding)
+        eventPtr = atts[i].name;
+      return XML_ERROR_DUPLICATE_ATTRIBUTE;
+    }
+    (attId->name)[-1] = 1;
+    appAtts[attIndex++] = attId->name;
+    if (!atts[i].normalized) {
+      enum XML_Error result;
+      XML_Bool isCdata = XML_TRUE;
+
+      /* figure out whether declared as other than CDATA */
+      if (attId->maybeTokenized) {
+        int j;
+        for (j = 0; j < nDefaultAtts; j++) {
+          if (attId == elementType->defaultAtts[j].id) {
+            isCdata = elementType->defaultAtts[j].isCdata;
+            break;
+          }
+        }
+      }
+
+      /* normalize the attribute value */
+      result = storeAttributeValue(parser, enc, isCdata,
+                                   atts[i].valuePtr, atts[i].valueEnd,
+                                   &tempPool);
+      if (result)
+        return result;
+      appAtts[attIndex] = poolStart(&tempPool);
+      poolFinish(&tempPool);
+    }
+    else {
+      /* the value did not need normalizing */
+      appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr,
+                                          atts[i].valueEnd);
+      if (appAtts[attIndex] == 0)
+        return XML_ERROR_NO_MEMORY;
+      poolFinish(&tempPool);
+    }
+    /* handle prefixed attribute names */
+    if (attId->prefix) {
+      if (attId->xmlns) {
+        /* deal with namespace declarations here */
+        enum XML_Error result = addBinding(parser, attId->prefix, attId,
+                                           appAtts[attIndex], bindingsPtr);
+        if (result)
+          return result;
+        --attIndex;
+      }
+      else {
+        /* deal with other prefixed names later */
+        attIndex++;
+        nPrefixes++;
+        (attId->name)[-1] = 2;
+      }
+    }
+    else
+      attIndex++;
+  }
+
+  /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
+  nSpecifiedAtts = attIndex;
+  if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
+    for (i = 0; i < attIndex; i += 2)
+      if (appAtts[i] == elementType->idAtt->name) {
+        idAttIndex = i;
+        break;
+      }
+  }
+  else
+    idAttIndex = -1;
+
+  /* do attribute defaulting */
+  for (i = 0; i < nDefaultAtts; i++) {
+    const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i;
+    if (!(da->id->name)[-1] && da->value) {
+      if (da->id->prefix) {
+        if (da->id->xmlns) {
+          enum XML_Error result = addBinding(parser, da->id->prefix, da->id,
+                                             da->value, bindingsPtr);
+          if (result)
+            return result;
+        }
+        else {
+          (da->id->name)[-1] = 2;
+          nPrefixes++;
+          appAtts[attIndex++] = da->id->name;
+          appAtts[attIndex++] = da->value;
+        }
+      }
+      else {
+        (da->id->name)[-1] = 1;
+        appAtts[attIndex++] = da->id->name;
+        appAtts[attIndex++] = da->value;
+      }
+    }
+  }
+  appAtts[attIndex] = 0;
+
+  /* expand prefixed attribute names, check for duplicates,
+     and clear flags that say whether attributes were specified */
+  i = 0;
+  if (nPrefixes) {
+    int j;  /* hash table index */
+    unsigned long version = nsAttsVersion;
+    int nsAttsSize = (int)1 << nsAttsPower;
+    /* size of hash table must be at least 2 * (# of prefixed attributes) */
+    if ((nPrefixes << 1) >> nsAttsPower) {  /* true for nsAttsPower = 0 */
+      NS_ATT *temp;
+      /* hash table size must also be a power of 2 and >= 8 */
+      while (nPrefixes >> nsAttsPower++);
+      if (nsAttsPower < 3)
+        nsAttsPower = 3;
+      nsAttsSize = (int)1 << nsAttsPower;
+      temp = (NS_ATT *)REALLOC(nsAtts, nsAttsSize * sizeof(NS_ATT));
+      if (!temp)
+        return XML_ERROR_NO_MEMORY;
+      nsAtts = temp;
+      version = 0;  /* force re-initialization of nsAtts hash table */
+    }
+    /* using a version flag saves us from initializing nsAtts every time */
+    if (!version) {  /* initialize version flags when version wraps around */
+      version = INIT_ATTS_VERSION;
+      for (j = nsAttsSize; j != 0; )
+        nsAtts[--j].version = version;
+    }
+    nsAttsVersion = --version;
+
+    /* expand prefixed names and check for duplicates */
+    for (; i < attIndex; i += 2) {
+      const XML_Char *s = appAtts[i];
+      if (s[-1] == 2) {  /* prefixed */
+        ATTRIBUTE_ID *id;
+        const BINDING *b;
+        unsigned long uriHash = 0;
+        ((XML_Char *)s)[-1] = 0;  /* clear flag */
+        id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, s, 0);
+        if (!id)
+          return XML_ERROR_NO_MEMORY;
+        b = id->prefix->binding;
+        if (!b)
+          return XML_ERROR_UNBOUND_PREFIX;
+
+        /* as we expand the name we also calculate its hash value */
+        for (j = 0; j < b->uriLen; j++) {
+          const XML_Char c = b->uri[j];
+          if (!poolAppendChar(&tempPool, c))
+            return XML_ERROR_NO_MEMORY;
+          uriHash = CHAR_HASH(uriHash, c);
+        }
+        while (*s++ != XML_T(':'))
+          ;
+        do {  /* copies null terminator */
+          const XML_Char c = *s;
+          if (!poolAppendChar(&tempPool, *s))
+            return XML_ERROR_NO_MEMORY;
+          uriHash = CHAR_HASH(uriHash, c);
+        } while (*s++);
+
+        { /* Check hash table for duplicate of expanded name (uriName).
+             Derived from code in lookup(HASH_TABLE *table, ...).
+          */
+          unsigned char step = 0;
+          unsigned long mask = nsAttsSize - 1;
+          j = uriHash & mask;  /* index into hash table */
+          while (nsAtts[j].version == version) {
+            /* for speed we compare stored hash values first */
+            if (uriHash == nsAtts[j].hash) {
+              const XML_Char *s1 = poolStart(&tempPool);
+              const XML_Char *s2 = nsAtts[j].uriName;
+              /* s1 is null terminated, but not s2 */
+              for (; *s1 == *s2 && *s1 != 0; s1++, s2++);
+              if (*s1 == 0)
+                return XML_ERROR_DUPLICATE_ATTRIBUTE;
+            }
+            if (!step)
+              step = PROBE_STEP(uriHash, mask, nsAttsPower);
+            j < step ? (j += nsAttsSize - step) : (j -= step);
+          }
+        }
+
+        if (ns_triplets) {  /* append namespace separator and prefix */
+          tempPool.ptr[-1] = namespaceSeparator;
+          s = b->prefix->name;
+          do {
+            if (!poolAppendChar(&tempPool, *s))
+              return XML_ERROR_NO_MEMORY;
+          } while (*s++);
+        }
+
+        /* store expanded name in attribute list */
+        s = poolStart(&tempPool);
+        poolFinish(&tempPool);
+        appAtts[i] = s;
+
+        /* fill empty slot with new version, uriName and hash value */
+        nsAtts[j].version = version;
+        nsAtts[j].hash = uriHash;
+        nsAtts[j].uriName = s;
+
+        if (!--nPrefixes) {
+          i += 2;
+          break;
+        }
+      }
+      else  /* not prefixed */
+        ((XML_Char *)s)[-1] = 0;  /* clear flag */
+    }
+  }
+  /* clear flags for the remaining attributes */
+  for (; i < attIndex; i += 2)
+    ((XML_Char *)(appAtts[i]))[-1] = 0;
+  for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
+    binding->attId->name[-1] = 0;
+
+  if (!ns)
+    return XML_ERROR_NONE;
+
+  /* expand the element type name */
+  if (elementType->prefix) {
+    binding = elementType->prefix->binding;
+    if (!binding)
+      return XML_ERROR_UNBOUND_PREFIX;
+    localPart = tagNamePtr->str;
+    while (*localPart++ != XML_T(':'))
+      ;
+  }
+  else if (dtd->defaultPrefix.binding) {
+    binding = dtd->defaultPrefix.binding;
+    localPart = tagNamePtr->str;
+  }
+  else
+    return XML_ERROR_NONE;
+  prefixLen = 0;
+  if (ns_triplets && binding->prefix->name) {
+    for (; binding->prefix->name[prefixLen++];)
+      ;  /* prefixLen includes null terminator */
+  }
+  tagNamePtr->localPart = localPart;
+  tagNamePtr->uriLen = binding->uriLen;
+  tagNamePtr->prefix = binding->prefix->name;
+  tagNamePtr->prefixLen = prefixLen;
+  for (i = 0; localPart[i++];)
+    ;  /* i includes null terminator */
+  n = i + binding->uriLen + prefixLen;
+  if (n > binding->uriAlloc) {
+    TAG *p;
+    uri = (XML_Char *)MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char));
+    if (!uri)
+      return XML_ERROR_NO_MEMORY;
+    binding->uriAlloc = n + EXPAND_SPARE;
+    memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
+    for (p = tagStack; p; p = p->parent)
+      if (p->name.str == binding->uri)
+        p->name.str = uri;
+    FREE(binding->uri);
+    binding->uri = uri;
+  }
+  /* if namespaceSeparator != '\0' then uri includes it already */
+  uri = binding->uri + binding->uriLen;
+  memcpy(uri, localPart, i * sizeof(XML_Char));
+  /* we always have a namespace separator between localPart and prefix */
+  if (prefixLen) {
+    uri += i - 1;
+    *uri = namespaceSeparator;  /* replace null terminator */
+    memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));
+  }
+  tagNamePtr->str = binding->uri;
+  return XML_ERROR_NONE;
+}
+
+/* addBinding() overwrites the value of prefix->binding without checking.
+   Therefore one must keep track of the old value outside of addBinding().
+*/
+static enum XML_Error
+addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
+           const XML_Char *uri, BINDING **bindingsPtr)
+{
+  static const XML_Char xmlNamespace[] = {
+    'h', 't', 't', 'p', ':', '/', '/',
+    'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
+    'X', 'M', 'L', '/', '1', '9', '9', '8', '/',
+    'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0'
+  };
+  static const int xmlLen = 
+    (int)sizeof(xmlNamespace)/sizeof(XML_Char) - 1;
+  static const XML_Char xmlnsNamespace[] = {
+    'h', 't', 't', 'p', ':', '/', '/',
+    'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
+    '2', '0', '0', '0', '/', 'x', 'm', 'l', 'n', 's', '/', '\0'
+  };
+  static const int xmlnsLen = 
+    (int)sizeof(xmlnsNamespace)/sizeof(XML_Char) - 1;
+
+  XML_Bool mustBeXML = XML_FALSE;
+  XML_Bool isXML = XML_TRUE;
+  XML_Bool isXMLNS = XML_TRUE;
+  
+  BINDING *b;
+  int len;
+
+  /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */
+  if (*uri == XML_T('\0') && prefix->name)
+    return XML_ERROR_UNDECLARING_PREFIX;
+
+  if (prefix->name
+      && prefix->name[0] == XML_T('x')
+      && prefix->name[1] == XML_T('m')
+      && prefix->name[2] == XML_T('l')) {
+
+    /* Not allowed to bind xmlns */
+    if (prefix->name[3] == XML_T('n')
+        && prefix->name[4] == XML_T('s')
+        && prefix->name[5] == XML_T('\0'))
+      return XML_ERROR_RESERVED_PREFIX_XMLNS;
+
+    if (prefix->name[3] == XML_T('\0'))
+      mustBeXML = XML_TRUE;
+  }
+
+  for (len = 0; uri[len]; len++) {
+    if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len]))
+      isXML = XML_FALSE;
+
+    if (!mustBeXML && isXMLNS 
+        && (len > xmlnsLen || uri[len] != xmlnsNamespace[len]))
+      isXMLNS = XML_FALSE;
+  }
+  isXML = isXML && len == xmlLen;
+  isXMLNS = isXMLNS && len == xmlnsLen;
+
+  if (mustBeXML != isXML)
+    return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML
+                     : XML_ERROR_RESERVED_NAMESPACE_URI;
+
+  if (isXMLNS)
+    return XML_ERROR_RESERVED_NAMESPACE_URI;
+
+  if (namespaceSeparator)
+    len++;
+  if (freeBindingList) {
+    b = freeBindingList;
+    if (len > b->uriAlloc) {
+      XML_Char *temp = (XML_Char *)REALLOC(b->uri,
+                          sizeof(XML_Char) * (len + EXPAND_SPARE));
+      if (temp == NULL)
+        return XML_ERROR_NO_MEMORY;
+      b->uri = temp;
+      b->uriAlloc = len + EXPAND_SPARE;
+    }
+    freeBindingList = b->nextTagBinding;
+  }
+  else {
+    b = (BINDING *)MALLOC(sizeof(BINDING));
+    if (!b)
+      return XML_ERROR_NO_MEMORY;
+    b->uri = (XML_Char *)MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));
+    if (!b->uri) {
+      FREE(b);
+      return XML_ERROR_NO_MEMORY;
+    }
+    b->uriAlloc = len + EXPAND_SPARE;
+  }
+  b->uriLen = len;
+  memcpy(b->uri, uri, len * sizeof(XML_Char));
+  if (namespaceSeparator)
+    b->uri[len - 1] = namespaceSeparator;
+  b->prefix = prefix;
+  b->attId = attId;
+  b->prevPrefixBinding = prefix->binding;
+  /* NULL binding when default namespace undeclared */
+  if (*uri == XML_T('\0') && prefix == &_dtd->defaultPrefix)
+    prefix->binding = NULL;
+  else
+    prefix->binding = b;
+  b->nextTagBinding = *bindingsPtr;
+  *bindingsPtr = b;
+  /* if attId == NULL then we are not starting a namespace scope */
+  if (attId && startNamespaceDeclHandler)
+    startNamespaceDeclHandler(handlerArg, prefix->name,
+                              prefix->binding ? uri : 0);
+  return XML_ERROR_NONE;
+}
+
+/* The idea here is to avoid using stack for each CDATA section when
+   the whole file is parsed with one call.
+*/
+static enum XML_Error PTRCALL
+cdataSectionProcessor(XML_Parser parser,
+                      const char *start,
+                      const char *end,
+                      const char **endPtr)
+{
+  enum XML_Error result = doCdataSection(parser, encoding, &start, end,
+                                         endPtr, (XML_Bool)!ps_finalBuffer);
+  if (result != XML_ERROR_NONE)
+    return result;
+  if (start) {
+    if (parentParser) {  /* we are parsing an external entity */
+      processor = externalEntityContentProcessor;
+      return externalEntityContentProcessor(parser, start, end, endPtr);
+    }
+    else {
+      processor = contentProcessor;
+      return contentProcessor(parser, start, end, endPtr);
+    }
+  }
+  return result;
+}
+
+/* startPtr gets set to non-null if the section is closed, and to null if
+   the section is not yet closed.
+*/
+static enum XML_Error
+doCdataSection(XML_Parser parser,
+               const ENCODING *enc,
+               const char **startPtr,
+               const char *end,
+               const char **nextPtr,
+               XML_Bool haveMore)
+{
+  const char *s = *startPtr;
+  const char **eventPP;
+  const char **eventEndPP;
+  if (enc == encoding) {
+    eventPP = &eventPtr;
+    *eventPP = s;
+    eventEndPP = &eventEndPtr;
+  }
+  else {
+    eventPP = &(openInternalEntities->internalEventPtr);
+    eventEndPP = &(openInternalEntities->internalEventEndPtr);
+  }
+  *eventPP = s;
+  *startPtr = NULL;
+
+  for (;;) {
+    const char *next;
+    int tok = XmlCdataSectionTok(enc, s, end, &next);
+    *eventEndPP = next;
+    switch (tok) {
+    case XML_TOK_CDATA_SECT_CLOSE:
+      if (endCdataSectionHandler)
+        endCdataSectionHandler(handlerArg);
+#if 0
+      /* see comment under XML_TOK_CDATA_SECT_OPEN */
+      else if (characterDataHandler)
+        characterDataHandler(handlerArg, dataBuf, 0);
+#endif
+      else if (defaultHandler)
+        reportDefault(parser, enc, s, next);
+      *startPtr = next;
+      *nextPtr = next;
+      if (ps_parsing == XML_FINISHED)
+        return XML_ERROR_ABORTED;
+      else
+        return XML_ERROR_NONE;
+    case XML_TOK_DATA_NEWLINE:
+      if (characterDataHandler) {
+        XML_Char c = 0xA;
+        characterDataHandler(handlerArg, &c, 1);
+      }
+      else if (defaultHandler)
+        reportDefault(parser, enc, s, next);
+      break;
+    case XML_TOK_DATA_CHARS:
+      if (characterDataHandler) {
+        if (MUST_CONVERT(enc, s)) {
+          for (;;) {
+            ICHAR *dataPtr = (ICHAR *)dataBuf;
+            XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
+            *eventEndPP = next;
+            characterDataHandler(handlerArg, dataBuf,
+                                 (int)(dataPtr - (ICHAR *)dataBuf));
+            if (s == next)
+              break;
+            *eventPP = s;
+          }
+        }
+        else
+          characterDataHandler(handlerArg,
+                               (XML_Char *)s,
+                               (int)((XML_Char *)next - (XML_Char *)s));
+      }
+      else if (defaultHandler)
+        reportDefault(parser, enc, s, next);
+      break;
+    case XML_TOK_INVALID:
+      *eventPP = next;
+      return XML_ERROR_INVALID_TOKEN;
+    case XML_TOK_PARTIAL_CHAR:
+      if (haveMore) {
+        *nextPtr = s;
+        return XML_ERROR_NONE;
+      }
+      return XML_ERROR_PARTIAL_CHAR;
+    case XML_TOK_PARTIAL:
+    case XML_TOK_NONE:
+      if (haveMore) {
+        *nextPtr = s;
+        return XML_ERROR_NONE;
+      }
+      return XML_ERROR_UNCLOSED_CDATA_SECTION;
+    default:
+      *eventPP = next;
+      return XML_ERROR_UNEXPECTED_STATE;
+    }
+
+    *eventPP = s = next;
+    switch (ps_parsing) {
+    case XML_SUSPENDED:
+      *nextPtr = next;
+      return XML_ERROR_NONE;
+    case XML_FINISHED:
+      return XML_ERROR_ABORTED;
+    default: ;
+    }
+  }
+  /* not reached */
+}
+
+#ifdef XML_DTD
+
+/* The idea here is to avoid using stack for each IGNORE section when
+   the whole file is parsed with one call.
+*/
+static enum XML_Error PTRCALL
+ignoreSectionProcessor(XML_Parser parser,
+                       const char *start,
+                       const char *end,
+                       const char **endPtr)
+{
+  enum XML_Error result = doIgnoreSection(parser, encoding, &start, end, 
+                                          endPtr, (XML_Bool)!ps_finalBuffer);
+  if (result != XML_ERROR_NONE)
+    return result;
+  if (start) {
+    processor = prologProcessor;
+    return prologProcessor(parser, start, end, endPtr);
+  }
+  return result;
+}
+
+/* startPtr gets set to non-null is the section is closed, and to null
+   if the section is not yet closed.
+*/
+static enum XML_Error
+doIgnoreSection(XML_Parser parser,
+                const ENCODING *enc,
+                const char **startPtr,
+                const char *end,
+                const char **nextPtr,
+                XML_Bool haveMore)
+{
+  const char *next;
+  int tok;
+  const char *s = *startPtr;
+  const char **eventPP;
+  const char **eventEndPP;
+  if (enc == encoding) {
+    eventPP = &eventPtr;
+    *eventPP = s;
+    eventEndPP = &eventEndPtr;
+  }
+  else {
+    eventPP = &(openInternalEntities->internalEventPtr);
+    eventEndPP = &(openInternalEntities->internalEventEndPtr);
+  }
+  *eventPP = s;
+  *startPtr = NULL;
+  tok = XmlIgnoreSectionTok(enc, s, end, &next);
+  *eventEndPP = next;
+  switch (tok) {
+  case XML_TOK_IGNORE_SECT:
+    if (defaultHandler)
+      reportDefault(parser, enc, s, next);
+    *startPtr = next;
+    *nextPtr = next;
+    if (ps_parsing == XML_FINISHED)
+      return XML_ERROR_ABORTED;
+    else
+      return XML_ERROR_NONE;
+  case XML_TOK_INVALID:
+    *eventPP = next;
+    return XML_ERROR_INVALID_TOKEN;
+  case XML_TOK_PARTIAL_CHAR:
+    if (haveMore) {
+      *nextPtr = s;
+      return XML_ERROR_NONE;
+    }
+    return XML_ERROR_PARTIAL_CHAR;
+  case XML_TOK_PARTIAL:
+  case XML_TOK_NONE:
+    if (haveMore) {
+      *nextPtr = s;
+      return XML_ERROR_NONE;
+    }
+    return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
+  default:
+    *eventPP = next;
+    return XML_ERROR_UNEXPECTED_STATE;
+  }
+  /* not reached */
+}
+
+#endif /* XML_DTD */
+
+static enum XML_Error
+initializeEncoding(XML_Parser parser)
+{
+  const char *s;
+#ifdef XML_UNICODE
+  char encodingBuf[128];
+  if (!protocolEncodingName)
+    s = NULL;
+  else {
+    int i;
+    for (i = 0; protocolEncodingName[i]; i++) {
+      if (i == sizeof(encodingBuf) - 1
+          || (protocolEncodingName[i] & ~0x7f) != 0) {
+        encodingBuf[0] = '\0';
+        break;
+      }
+      encodingBuf[i] = (char)protocolEncodingName[i];
+    }
+    encodingBuf[i] = '\0';
+    s = encodingBuf;
+  }
+#else
+  s = protocolEncodingName;
+#endif
+  if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))
+    return XML_ERROR_NONE;
+  return handleUnknownEncoding(parser, protocolEncodingName);
+}
+
+static enum XML_Error
+processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
+               const char *s, const char *next)
+{
+  const char *encodingName = NULL;
+  const XML_Char *storedEncName = NULL;
+  const ENCODING *newEncoding = NULL;
+  const char *version = NULL;
+  const char *versionend;
+  const XML_Char *storedversion = NULL;
+  int standalone = -1;
+  if (!(ns
+        ? XmlParseXmlDeclNS
+        : XmlParseXmlDecl)(isGeneralTextEntity,
+                           encoding,
+                           s,
+                           next,
+                           &eventPtr,
+                           &version,
+                           &versionend,
+                           &encodingName,
+                           &newEncoding,
+                           &standalone)) {
+    if (isGeneralTextEntity)
+      return XML_ERROR_TEXT_DECL;
+    else
+      return XML_ERROR_XML_DECL;
+  }
+  if (!isGeneralTextEntity && standalone == 1) {
+    _dtd->standalone = XML_TRUE;
+#ifdef XML_DTD
+    if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
+      paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
+#endif /* XML_DTD */
+  }
+  if (xmlDeclHandler) {
+    if (encodingName != NULL) {
+      storedEncName = poolStoreString(&temp2Pool,
+                                      encoding,
+                                      encodingName,
+                                      encodingName
+                                      + XmlNameLength(encoding, encodingName));
+      if (!storedEncName)
+              return XML_ERROR_NO_MEMORY;
+      poolFinish(&temp2Pool);
+    }
+    if (version) {
+      storedversion = poolStoreString(&temp2Pool,
+                                      encoding,
+                                      version,
+                                      versionend - encoding->minBytesPerChar);
+      if (!storedversion)
+        return XML_ERROR_NO_MEMORY;
+    }
+    xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone);
+  }
+  else if (defaultHandler)
+    reportDefault(parser, encoding, s, next);
+  if (protocolEncodingName == NULL) {
+    if (newEncoding) {
+      if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
+        eventPtr = encodingName;
+        return XML_ERROR_INCORRECT_ENCODING;
+      }
+      encoding = newEncoding;
+    }
+    else if (encodingName) {
+      enum XML_Error result;
+      if (!storedEncName) {
+        storedEncName = poolStoreString(
+          &temp2Pool, encoding, encodingName,
+          encodingName + XmlNameLength(encoding, encodingName));
+        if (!storedEncName)
+          return XML_ERROR_NO_MEMORY;
+      }
+      result = handleUnknownEncoding(parser, storedEncName);
+      poolClear(&temp2Pool);
+      if (result == XML_ERROR_UNKNOWN_ENCODING)
+        eventPtr = encodingName;
+      return result;
+    }
+  }
+
+  if (storedEncName || storedversion)
+    poolClear(&temp2Pool);
+
+  return XML_ERROR_NONE;
+}
+
+static enum XML_Error
+handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
+{
+  if (unknownEncodingHandler) {
+    XML_Encoding info;
+    int i;
+    for (i = 0; i < 256; i++)
+      info.map[i] = -1;
+    info.convert = NULL;
+    info.data = NULL;
+    info.release = NULL;
+    if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName,
+                               &info)) {
+      ENCODING *enc;
+      unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding());
+      if (!unknownEncodingMem) {
+        if (info.release)
+          info.release(info.data);
+        return XML_ERROR_NO_MEMORY;
+      }
+      enc = (ns
+             ? XmlInitUnknownEncodingNS
+             : XmlInitUnknownEncoding)(unknownEncodingMem,
+                                       info.map,
+                                       info.convert,
+                                       info.data);
+      if (enc) {
+        unknownEncodingData = info.data;
+        unknownEncodingRelease = info.release;
+        encoding = enc;
+        return XML_ERROR_NONE;
+      }
+    }
+    if (info.release != NULL)
+      info.release(info.data);
+  }
+  return XML_ERROR_UNKNOWN_ENCODING;
+}
+
+static enum XML_Error PTRCALL
+prologInitProcessor(XML_Parser parser,
+                    const char *s,
+                    const char *end,
+                    const char **nextPtr)
+{
+  enum XML_Error result = initializeEncoding(parser);
+  if (result != XML_ERROR_NONE)
+    return result;
+  processor = prologProcessor;
+  return prologProcessor(parser, s, end, nextPtr);
+}
+
+#ifdef XML_DTD
+
+static enum XML_Error PTRCALL
+externalParEntInitProcessor(XML_Parser parser,
+                            const char *s,
+                            const char *end,
+                            const char **nextPtr)
+{
+  enum XML_Error result = initializeEncoding(parser);
+  if (result != XML_ERROR_NONE)
+    return result;
+
+  /* we know now that XML_Parse(Buffer) has been called,
+     so we consider the external parameter entity read */
+  _dtd->paramEntityRead = XML_TRUE;
+
+  if (prologState.inEntityValue) {
+    processor = entityValueInitProcessor;
+    return entityValueInitProcessor(parser, s, end, nextPtr);
+  }
+  else {
+    processor = externalParEntProcessor;
+    return externalParEntProcessor(parser, s, end, nextPtr);
+  }
+}
+
+static enum XML_Error PTRCALL
+entityValueInitProcessor(XML_Parser parser,
+                         const char *s,
+                         const char *end,
+                         const char **nextPtr)
+{
+  int tok;
+  const char *start = s;
+  const char *next = start;
+  eventPtr = start;
+
+  for (;;) {  
+    tok = XmlPrologTok(encoding, start, end, &next);
+    eventEndPtr = next;
+    if (tok <= 0) {
+      if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
+        *nextPtr = s;
+        return XML_ERROR_NONE;
+      }
+      switch (tok) {
+      case XML_TOK_INVALID:
+        return XML_ERROR_INVALID_TOKEN;
+      case XML_TOK_PARTIAL:
+        return XML_ERROR_UNCLOSED_TOKEN;
+      case XML_TOK_PARTIAL_CHAR:
+        return XML_ERROR_PARTIAL_CHAR;
+      case XML_TOK_NONE:   /* start == end */
+      default:
+        break;
+      }
+      /* found end of entity value - can store it now */
+      return storeEntityValue(parser, encoding, s, end);
+    }
+    else if (tok == XML_TOK_XML_DECL) {
+      enum XML_Error result;
+      result = processXmlDecl(parser, 0, start, next);
+      if (result != XML_ERROR_NONE)
+        return result;
+      switch (ps_parsing) {
+      case XML_SUSPENDED: 
+        *nextPtr = next;
+        return XML_ERROR_NONE;
+      case XML_FINISHED:
+        return XML_ERROR_ABORTED;
+      default:
+        *nextPtr = next;
+      }
+      /* stop scanning for text declaration - we found one */
+      processor = entityValueProcessor;
+      return entityValueProcessor(parser, next, end, nextPtr);
+    }
+    /* If we are at the end of the buffer, this would cause XmlPrologTok to
+       return XML_TOK_NONE on the next call, which would then cause the
+       function to exit with *nextPtr set to s - that is what we want for other
+       tokens, but not for the BOM - we would rather like to skip it;
+       then, when this routine is entered the next time, XmlPrologTok will
+       return XML_TOK_INVALID, since the BOM is still in the buffer
+    */
+    else if (tok == XML_TOK_BOM && next == end && !ps_finalBuffer) {
+      *nextPtr = next;
+      return XML_ERROR_NONE;
+    }
+    start = next;
+    eventPtr = start;
+  }
+}
+
+static enum XML_Error PTRCALL
+externalParEntProcessor(XML_Parser parser,
+                        const char *s,
+                        const char *end,
+                        const char **nextPtr)
+{
+  const char *next = s;
+  int tok;
+
+  tok = XmlPrologTok(encoding, s, end, &next);
+  if (tok <= 0) {
+    if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
+      *nextPtr = s;
+      return XML_ERROR_NONE;
+    }
+    switch (tok) {
+    case XML_TOK_INVALID:
+      return XML_ERROR_INVALID_TOKEN;
+    case XML_TOK_PARTIAL:
+      return XML_ERROR_UNCLOSED_TOKEN;
+    case XML_TOK_PARTIAL_CHAR:
+      return XML_ERROR_PARTIAL_CHAR;
+    case XML_TOK_NONE:   /* start == end */
+    default:
+      break;
+    }
+  }
+  /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
+     However, when parsing an external subset, doProlog will not accept a BOM
+     as valid, and report a syntax error, so we have to skip the BOM
+  */
+  else if (tok == XML_TOK_BOM) {
+    s = next;
+    tok = XmlPrologTok(encoding, s, end, &next);
+  }
+
+  processor = prologProcessor;
+  return doProlog(parser, encoding, s, end, tok, next, 
+                  nextPtr, (XML_Bool)!ps_finalBuffer);
+}
+
+static enum XML_Error PTRCALL
+entityValueProcessor(XML_Parser parser,
+                     const char *s,
+                     const char *end,
+                     const char **nextPtr)
+{
+  const char *start = s;
+  const char *next = s;
+  const ENCODING *enc = encoding;
+  int tok;
+
+  for (;;) {
+    tok = XmlPrologTok(enc, start, end, &next);
+    if (tok <= 0) {
+      if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
+        *nextPtr = s;
+        return XML_ERROR_NONE;
+      }
+      switch (tok) {
+      case XML_TOK_INVALID:
+        return XML_ERROR_INVALID_TOKEN;
+      case XML_TOK_PARTIAL:
+        return XML_ERROR_UNCLOSED_TOKEN;
+      case XML_TOK_PARTIAL_CHAR:
+        return XML_ERROR_PARTIAL_CHAR;
+      case XML_TOK_NONE:   /* start == end */
+      default:
+        break;
+      }
+      /* found end of entity value - can store it now */
+      return storeEntityValue(parser, enc, s, end);
+    }
+    start = next;
+  }
+}
+
+#endif /* XML_DTD */
+
+static enum XML_Error PTRCALL
+prologProcessor(XML_Parser parser,
+                const char *s,
+                const char *end,
+                const char **nextPtr)
+{
+  const char *next = s;
+  int tok = XmlPrologTok(encoding, s, end, &next);
+  return doProlog(parser, encoding, s, end, tok, next, 
+                  nextPtr, (XML_Bool)!ps_finalBuffer);
+}
+
+static enum XML_Error
+doProlog(XML_Parser parser,
+         const ENCODING *enc,
+         const char *s,
+         const char *end,
+         int tok,
+         const char *next,
+         const char **nextPtr,
+         XML_Bool haveMore)
+{
+#ifdef XML_DTD
+  static const XML_Char externalSubsetName[] = { '#' , '\0' };
+#endif /* XML_DTD */
+  static const XML_Char atypeCDATA[] = { 'C', 'D', 'A', 'T', 'A', '\0' };
+  static const XML_Char atypeID[] = { 'I', 'D', '\0' };
+  static const XML_Char atypeIDREF[] = { 'I', 'D', 'R', 'E', 'F', '\0' };
+  static const XML_Char atypeIDREFS[] = { 'I', 'D', 'R', 'E', 'F', 'S', '\0' };
+  static const XML_Char atypeENTITY[] = { 'E', 'N', 'T', 'I', 'T', 'Y', '\0' };
+  static const XML_Char atypeENTITIES[] =
+      { 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S', '\0' };
+  static const XML_Char atypeNMTOKEN[] = {
+      'N', 'M', 'T', 'O', 'K', 'E', 'N', '\0' };
+  static const XML_Char atypeNMTOKENS[] = {
+      'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S', '\0' };
+  static const XML_Char notationPrefix[] = {
+      'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N', '(', '\0' };
+  static const XML_Char enumValueSep[] = { '|', '\0' };
+  static const XML_Char enumValueStart[] = { '(', '\0' };
+
+  /* save one level of indirection */
+  DTD * const dtd = _dtd; 
+
+  const char **eventPP;
+  const char **eventEndPP;
+  enum XML_Content_Quant quant;
+
+  if (enc == encoding) {
+    eventPP = &eventPtr;
+    eventEndPP = &eventEndPtr;
+  }
+  else {
+    eventPP = &(openInternalEntities->internalEventPtr);
+    eventEndPP = &(openInternalEntities->internalEventEndPtr);
+  }
+
+  for (;;) {
+    int role;
+    XML_Bool handleDefault = XML_TRUE;
+    *eventPP = s;
+    *eventEndPP = next;
+    if (tok <= 0) {
+      if (haveMore && tok != XML_TOK_INVALID) {
+        *nextPtr = s;
+        return XML_ERROR_NONE;
+      }
+      switch (tok) {
+      case XML_TOK_INVALID:
+        *eventPP = next;
+        return XML_ERROR_INVALID_TOKEN;
+      case XML_TOK_PARTIAL:
+        return XML_ERROR_UNCLOSED_TOKEN;
+      case XML_TOK_PARTIAL_CHAR:
+        return XML_ERROR_PARTIAL_CHAR;
+      case XML_TOK_NONE:
+#ifdef XML_DTD
+        /* for internal PE NOT referenced between declarations */
+        if (enc != encoding && !openInternalEntities->betweenDecl) {
+          *nextPtr = s;
+          return XML_ERROR_NONE;
+        }
+        /* WFC: PE Between Declarations - must check that PE contains
+           complete markup, not only for external PEs, but also for
+           internal PEs if the reference occurs between declarations.
+        */
+        if (isParamEntity || enc != encoding) {
+          if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
+              == XML_ROLE_ERROR)
+            return XML_ERROR_INCOMPLETE_PE;
+          *nextPtr = s;
+          return XML_ERROR_NONE;
+        }
+#endif /* XML_DTD */
+        return XML_ERROR_NO_ELEMENTS;
+      default:
+        tok = -tok;
+        next = end;
+        break;
+      }
+    }
+    role = XmlTokenRole(&prologState, tok, s, next, enc);
+    switch (role) {
+    case XML_ROLE_XML_DECL:
+      {
+        enum XML_Error result = processXmlDecl(parser, 0, s, next);
+        if (result != XML_ERROR_NONE)
+          return result;
+        enc = encoding;
+        handleDefault = XML_FALSE;
+      }
+      break;
+    case XML_ROLE_DOCTYPE_NAME:
+      if (startDoctypeDeclHandler) {
+        doctypeName = poolStoreString(&tempPool, enc, s, next);
+        if (!doctypeName)
+          return XML_ERROR_NO_MEMORY;
+        poolFinish(&tempPool);
+        doctypePubid = NULL;
+        handleDefault = XML_FALSE;
+      }
+      doctypeSysid = NULL; /* always initialize to NULL */
+      break;
+    case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
+      if (startDoctypeDeclHandler) {
+        startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,
+                                doctypePubid, 1);
+        doctypeName = NULL;
+        poolClear(&tempPool);
+        handleDefault = XML_FALSE;
+      }
+      break;
+#ifdef XML_DTD
+    case XML_ROLE_TEXT_DECL:
+      {
+        enum XML_Error result = processXmlDecl(parser, 1, s, next);
+        if (result != XML_ERROR_NONE)
+          return result;
+        enc = encoding;
+        handleDefault = XML_FALSE;
+      }
+      break;
+#endif /* XML_DTD */
+    case XML_ROLE_DOCTYPE_PUBLIC_ID:
+#ifdef XML_DTD
+      useForeignDTD = XML_FALSE;
+      declEntity = (ENTITY *)lookup(&dtd->paramEntities,
+                                    externalSubsetName,
+                                    sizeof(ENTITY));
+      if (!declEntity)
+        return XML_ERROR_NO_MEMORY;
+#endif /* XML_DTD */
+      dtd->hasParamEntityRefs = XML_TRUE;
+      if (startDoctypeDeclHandler) {
+        if (!XmlIsPublicId(enc, s, next, eventPP))
+          return XML_ERROR_PUBLICID;
+        doctypePubid = poolStoreString(&tempPool, enc,
+                                       s + enc->minBytesPerChar,
+                                       next - enc->minBytesPerChar);
+        if (!doctypePubid)
+          return XML_ERROR_NO_MEMORY;
+        normalizePublicId((XML_Char *)doctypePubid);
+        poolFinish(&tempPool);
+        handleDefault = XML_FALSE;
+        goto alreadyChecked;
+      }
+      /* fall through */
+    case XML_ROLE_ENTITY_PUBLIC_ID:
+      if (!XmlIsPublicId(enc, s, next, eventPP))
+        return XML_ERROR_PUBLICID;
+    alreadyChecked:
+      if (dtd->keepProcessing && declEntity) {
+        XML_Char *tem = poolStoreString(&dtd->pool,
+                                        enc,
+                                        s + enc->minBytesPerChar,
+                                        next - enc->minBytesPerChar);
+        if (!tem)
+          return XML_ERROR_NO_MEMORY;
+        normalizePublicId(tem);
+        declEntity->publicId = tem;
+        poolFinish(&dtd->pool);
+        if (entityDeclHandler)
+          handleDefault = XML_FALSE;
+      }
+      break;
+    case XML_ROLE_DOCTYPE_CLOSE:
+      if (doctypeName) {
+        startDoctypeDeclHandler(handlerArg, doctypeName,
+                                doctypeSysid, doctypePubid, 0);
+        poolClear(&tempPool);
+        handleDefault = XML_FALSE;
+      }
+      /* doctypeSysid will be non-NULL in the case of a previous
+         XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
+         was not set, indicating an external subset
+      */
+#ifdef XML_DTD
+      if (doctypeSysid || useForeignDTD) {
+        XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
+        dtd->hasParamEntityRefs = XML_TRUE;
+        if (paramEntityParsing && externalEntityRefHandler) {
+          ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,
+                                            externalSubsetName,
+                                            sizeof(ENTITY));
+          if (!entity)
+            return XML_ERROR_NO_MEMORY;
+          if (useForeignDTD)
+            entity->base = curBase;
+          dtd->paramEntityRead = XML_FALSE;
+          if (!externalEntityRefHandler(externalEntityRefHandlerArg,
+                                        0,
+                                        entity->base,
+                                        entity->systemId,
+                                        entity->publicId))
+            return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
+          if (dtd->paramEntityRead) {
+            if (!dtd->standalone && 
+                notStandaloneHandler && 
+                !notStandaloneHandler(handlerArg))
+              return XML_ERROR_NOT_STANDALONE;
+          }
+          /* if we didn't read the foreign DTD then this means that there
+             is no external subset and we must reset dtd->hasParamEntityRefs
+          */
+          else if (!doctypeSysid)
+            dtd->hasParamEntityRefs = hadParamEntityRefs;
+          /* end of DTD - no need to update dtd->keepProcessing */
+        }
+        useForeignDTD = XML_FALSE;
+      }
+#endif /* XML_DTD */
+      if (endDoctypeDeclHandler) {
+        endDoctypeDeclHandler(handlerArg);
+        handleDefault = XML_FALSE;
+      }
+      break;
+    case XML_ROLE_INSTANCE_START:
+#ifdef XML_DTD
+      /* if there is no DOCTYPE declaration then now is the
+         last chance to read the foreign DTD
+      */
+      if (useForeignDTD) {
+        XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
+        dtd->hasParamEntityRefs = XML_TRUE;
+        if (paramEntityParsing && externalEntityRefHandler) {
+          ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,
+                                            externalSubsetName,
+                                            sizeof(ENTITY));
+          if (!entity)
+            return XML_ERROR_NO_MEMORY;
+          entity->base = curBase;
+          dtd->paramEntityRead = XML_FALSE;
+          if (!externalEntityRefHandler(externalEntityRefHandlerArg,
+                                        0,
+                                        entity->base,
+                                        entity->systemId,
+                                        entity->publicId))
+            return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
+          if (dtd->paramEntityRead) {
+            if (!dtd->standalone &&
+                notStandaloneHandler &&
+                !notStandaloneHandler(handlerArg))
+              return XML_ERROR_NOT_STANDALONE;
+          }
+          /* if we didn't read the foreign DTD then this means that there
+             is no external subset and we must reset dtd->hasParamEntityRefs
+          */
+          else
+            dtd->hasParamEntityRefs = hadParamEntityRefs;
+          /* end of DTD - no need to update dtd->keepProcessing */
+        }
+      }
+#endif /* XML_DTD */
+      processor = contentProcessor;
+      return contentProcessor(parser, s, end, nextPtr);
+    case XML_ROLE_ATTLIST_ELEMENT_NAME:
+      declElementType = getElementType(parser, enc, s, next);
+      if (!declElementType)
+        return XML_ERROR_NO_MEMORY;
+      goto checkAttListDeclHandler;
+    case XML_ROLE_ATTRIBUTE_NAME:
+      declAttributeId = getAttributeId(parser, enc, s, next);
+      if (!declAttributeId)
+        return XML_ERROR_NO_MEMORY;
+      declAttributeIsCdata = XML_FALSE;
+      declAttributeType = NULL;
+      declAttributeIsId = XML_FALSE;
+      goto checkAttListDeclHandler;
+    case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
+      declAttributeIsCdata = XML_TRUE;
+      declAttributeType = atypeCDATA;
+      goto checkAttListDeclHandler;
+    case XML_ROLE_ATTRIBUTE_TYPE_ID:
+      declAttributeIsId = XML_TRUE;
+      declAttributeType = atypeID;
+      goto checkAttListDeclHandler;
+    case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
+      declAttributeType = atypeIDREF;
+      goto checkAttListDeclHandler;
+    case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
+      declAttributeType = atypeIDREFS;
+      goto checkAttListDeclHandler;
+    case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
+      declAttributeType = atypeENTITY;
+      goto checkAttListDeclHandler;
+    case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
+      declAttributeType = atypeENTITIES;
+      goto checkAttListDeclHandler;
+    case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
+      declAttributeType = atypeNMTOKEN;
+      goto checkAttListDeclHandler;
+    case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
+      declAttributeType = atypeNMTOKENS;
+    checkAttListDeclHandler:
+      if (dtd->keepProcessing && attlistDeclHandler)
+        handleDefault = XML_FALSE;
+      break;
+    case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
+    case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
+      if (dtd->keepProcessing && attlistDeclHandler) {
+        const XML_Char *prefix;
+        if (declAttributeType) {
+          prefix = enumValueSep;
+        }
+        else {
+          prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE
+                    ? notationPrefix
+                    : enumValueStart);
+        }
+        if (!poolAppendString(&tempPool, prefix))
+          return XML_ERROR_NO_MEMORY;
+        if (!poolAppend(&tempPool, enc, s, next))
+          return XML_ERROR_NO_MEMORY;
+        declAttributeType = tempPool.start;
+        handleDefault = XML_FALSE;
+      }
+      break;
+    case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
+    case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
+      if (dtd->keepProcessing) {
+        if (!defineAttribute(declElementType, declAttributeId,
+                             declAttributeIsCdata, declAttributeIsId,
+                             0, parser))
+          return XML_ERROR_NO_MEMORY;
+        if (attlistDeclHandler && declAttributeType) {
+          if (*declAttributeType == XML_T('(')
+              || (*declAttributeType == XML_T('N')
+                  && declAttributeType[1] == XML_T('O'))) {
+            /* Enumerated or Notation type */
+            if (!poolAppendChar(&tempPool, XML_T(')'))
+                || !poolAppendChar(&tempPool, XML_T('\0')))
+              return XML_ERROR_NO_MEMORY;
+            declAttributeType = tempPool.start;
+            poolFinish(&tempPool);
+          }
+          *eventEndPP = s;
+          attlistDeclHandler(handlerArg, declElementType->name,
+                             declAttributeId->name, declAttributeType,
+                             0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
+          poolClear(&tempPool);
+          handleDefault = XML_FALSE;
+        }
+      }
+      break;
+    case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
+    case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
+      if (dtd->keepProcessing) {
+        const XML_Char *attVal;
+        enum XML_Error result =
+          storeAttributeValue(parser, enc, declAttributeIsCdata,
+                              s + enc->minBytesPerChar,
+                              next - enc->minBytesPerChar,
+                              &dtd->pool);
+        if (result)
+          return result;
+        attVal = poolStart(&dtd->pool);
+        poolFinish(&dtd->pool);
+        /* ID attributes aren't allowed to have a default */
+        if (!defineAttribute(declElementType, declAttributeId,
+                             declAttributeIsCdata, XML_FALSE, attVal, parser))
+          return XML_ERROR_NO_MEMORY;
+        if (attlistDeclHandler && declAttributeType) {
+          if (*declAttributeType == XML_T('(')
+              || (*declAttributeType == XML_T('N')
+                  && declAttributeType[1] == XML_T('O'))) {
+            /* Enumerated or Notation type */
+            if (!poolAppendChar(&tempPool, XML_T(')'))
+                || !poolAppendChar(&tempPool, XML_T('\0')))
+              return XML_ERROR_NO_MEMORY;
+            declAttributeType = tempPool.start;
+            poolFinish(&tempPool);
+          }
+          *eventEndPP = s;
+          attlistDeclHandler(handlerArg, declElementType->name,
+                             declAttributeId->name, declAttributeType,
+                             attVal,
+                             role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
+          poolClear(&tempPool);
+          handleDefault = XML_FALSE;
+        }
+      }
+      break;
+    case XML_ROLE_ENTITY_VALUE:
+      if (dtd->keepProcessing) {
+        enum XML_Error result = storeEntityValue(parser, enc,
+                                            s + enc->minBytesPerChar,
+                                            next - enc->minBytesPerChar);
+        if (declEntity) {
+          declEntity->textPtr = poolStart(&dtd->entityValuePool);
+          declEntity->textLen = (int)(poolLength(&dtd->entityValuePool));
+          poolFinish(&dtd->entityValuePool);
+          if (entityDeclHandler) {
+            *eventEndPP = s;
+            entityDeclHandler(handlerArg,
+                              declEntity->name,
+                              declEntity->is_param,
+                              declEntity->textPtr,
+                              declEntity->textLen,
+                              curBase, 0, 0, 0);
+            handleDefault = XML_FALSE;
+          }
+        }
+        else
+          poolDiscard(&dtd->entityValuePool);
+        if (result != XML_ERROR_NONE)
+          return result;
+      }
+      break;
+    case XML_ROLE_DOCTYPE_SYSTEM_ID:
+#ifdef XML_DTD
+      useForeignDTD = XML_FALSE;
+#endif /* XML_DTD */
+      dtd->hasParamEntityRefs = XML_TRUE;
+      if (startDoctypeDeclHandler) {
+        doctypeSysid = poolStoreString(&tempPool, enc,
+                                       s + enc->minBytesPerChar,
+                                       next - enc->minBytesPerChar);
+        if (doctypeSysid == NULL)
+          return XML_ERROR_NO_MEMORY;
+        poolFinish(&tempPool);
+        handleDefault = XML_FALSE;
+      }
+#ifdef XML_DTD
+      else
+        /* use externalSubsetName to make doctypeSysid non-NULL
+           for the case where no startDoctypeDeclHandler is set */
+        doctypeSysid = externalSubsetName;
+#endif /* XML_DTD */
+      if (!dtd->standalone
+#ifdef XML_DTD
+          && !paramEntityParsing
+#endif /* XML_DTD */
+          && notStandaloneHandler
+          && !notStandaloneHandler(handlerArg))
+        return XML_ERROR_NOT_STANDALONE;
+#ifndef XML_DTD
+      break;
+#else /* XML_DTD */
+      if (!declEntity) {
+        declEntity = (ENTITY *)lookup(&dtd->paramEntities,
+                                      externalSubsetName,
+                                      sizeof(ENTITY));
+        if (!declEntity)
+          return XML_ERROR_NO_MEMORY;
+        declEntity->publicId = NULL;
+      }
+      /* fall through */
+#endif /* XML_DTD */
+    case XML_ROLE_ENTITY_SYSTEM_ID:
+      if (dtd->keepProcessing && declEntity) {
+        declEntity->systemId = poolStoreString(&dtd->pool, enc,
+                                               s + enc->minBytesPerChar,
+                                               next - enc->minBytesPerChar);
+        if (!declEntity->systemId)
+          return XML_ERROR_NO_MEMORY;
+        declEntity->base = curBase;
+        poolFinish(&dtd->pool);
+        if (entityDeclHandler)
+          handleDefault = XML_FALSE;
+      }
+      break;
+    case XML_ROLE_ENTITY_COMPLETE:
+      if (dtd->keepProcessing && declEntity && entityDeclHandler) {
+        *eventEndPP = s;
+        entityDeclHandler(handlerArg,
+                          declEntity->name,
+                          declEntity->is_param,
+                          0,0,
+                          declEntity->base,
+                          declEntity->systemId,
+                          declEntity->publicId,
+                          0);
+        handleDefault = XML_FALSE;
+      }
+      break;
+    case XML_ROLE_ENTITY_NOTATION_NAME:
+      if (dtd->keepProcessing && declEntity) {
+        declEntity->notation = poolStoreString(&dtd->pool, enc, s, next);
+        if (!declEntity->notation)
+          return XML_ERROR_NO_MEMORY;
+        poolFinish(&dtd->pool);
+        if (unparsedEntityDeclHandler) {
+          *eventEndPP = s;
+          unparsedEntityDeclHandler(handlerArg,
+                                    declEntity->name,
+                                    declEntity->base,
+                                    declEntity->systemId,
+                                    declEntity->publicId,
+                                    declEntity->notation);
+          handleDefault = XML_FALSE;
+        }
+        else if (entityDeclHandler) {
+          *eventEndPP = s;
+          entityDeclHandler(handlerArg,
+                            declEntity->name,
+                            0,0,0,
+                            declEntity->base,
+                            declEntity->systemId,
+                            declEntity->publicId,
+                            declEntity->notation);
+          handleDefault = XML_FALSE;
+        }
+      }
+      break;
+    case XML_ROLE_GENERAL_ENTITY_NAME:
+      {
+        if (XmlPredefinedEntityName(enc, s, next)) {
+          declEntity = NULL;
+          break;
+        }
+        if (dtd->keepProcessing) {
+          const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
+          if (!name)
+            return XML_ERROR_NO_MEMORY;
+          declEntity = (ENTITY *)lookup(&dtd->generalEntities, name,
+                                        sizeof(ENTITY));
+          if (!declEntity)
+            return XML_ERROR_NO_MEMORY;
+          if (declEntity->name != name) {
+            poolDiscard(&dtd->pool);
+            declEntity = NULL;
+          }
+          else {
+            poolFinish(&dtd->pool);
+            declEntity->publicId = NULL;
+            declEntity->is_param = XML_FALSE;
+            /* if we have a parent parser or are reading an internal parameter
+               entity, then the entity declaration is not considered "internal"
+            */
+            declEntity->is_internal = !(parentParser || openInternalEntities);
+            if (entityDeclHandler)
+              handleDefault = XML_FALSE;
+          }
+        }
+        else {
+          poolDiscard(&dtd->pool);
+          declEntity = NULL;
+        }
+      }
+      break;
+    case XML_ROLE_PARAM_ENTITY_NAME:
+#ifdef XML_DTD
+      if (dtd->keepProcessing) {
+        const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
+        if (!name)
+          return XML_ERROR_NO_MEMORY;
+        declEntity = (ENTITY *)lookup(&dtd->paramEntities,
+                                           name, sizeof(ENTITY));
+        if (!declEntity)
+          return XML_ERROR_NO_MEMORY;
+        if (declEntity->name != name) {
+          poolDiscard(&dtd->pool);
+          declEntity = NULL;
+        }
+        else {
+          poolFinish(&dtd->pool);
+          declEntity->publicId = NULL;
+          declEntity->is_param = XML_TRUE;
+          /* if we have a parent parser or are reading an internal parameter
+             entity, then the entity declaration is not considered "internal"
+          */
+          declEntity->is_internal = !(parentParser || openInternalEntities);
+          if (entityDeclHandler)
+            handleDefault = XML_FALSE;
+        }
+      }
+      else {
+        poolDiscard(&dtd->pool);
+        declEntity = NULL;
+      }
+#else /* not XML_DTD */
+      declEntity = NULL;
+#endif /* XML_DTD */
+      break;
+    case XML_ROLE_NOTATION_NAME:
+      declNotationPublicId = NULL;
+      declNotationName = NULL;
+      if (notationDeclHandler) {
+        declNotationName = poolStoreString(&tempPool, enc, s, next);
+        if (!declNotationName)
+          return XML_ERROR_NO_MEMORY;
+        poolFinish(&tempPool);
+        handleDefault = XML_FALSE;
+      }
+      break;
+    case XML_ROLE_NOTATION_PUBLIC_ID:
+      if (!XmlIsPublicId(enc, s, next, eventPP))
+        return XML_ERROR_PUBLICID;
+      if (declNotationName) {  /* means notationDeclHandler != NULL */
+        XML_Char *tem = poolStoreString(&tempPool,
+                                        enc,
+                                        s + enc->minBytesPerChar,
+                                        next - enc->minBytesPerChar);
+        if (!tem)
+          return XML_ERROR_NO_MEMORY;
+        normalizePublicId(tem);
+        declNotationPublicId = tem;
+        poolFinish(&tempPool);
+        handleDefault = XML_FALSE;
+      }
+      break;
+    case XML_ROLE_NOTATION_SYSTEM_ID:
+      if (declNotationName && notationDeclHandler) {
+        const XML_Char *systemId
+          = poolStoreString(&tempPool, enc,
+                            s + enc->minBytesPerChar,
+                            next - enc->minBytesPerChar);
+        if (!systemId)
+          return XML_ERROR_NO_MEMORY;
+        *eventEndPP = s;
+        notationDeclHandler(handlerArg,
+                            declNotationName,
+                            curBase,
+                            systemId,
+                            declNotationPublicId);
+        handleDefault = XML_FALSE;
+      }
+      poolClear(&tempPool);
+      break;
+    case XML_ROLE_NOTATION_NO_SYSTEM_ID:
+      if (declNotationPublicId && notationDeclHandler) {
+        *eventEndPP = s;
+        notationDeclHandler(handlerArg,
+                            declNotationName,
+                            curBase,
+                            0,
+                            declNotationPublicId);
+        handleDefault = XML_FALSE;
+      }
+      poolClear(&tempPool);
+      break;
+    case XML_ROLE_ERROR:
+      switch (tok) {
+      case XML_TOK_PARAM_ENTITY_REF:
+        /* PE references in internal subset are
+           not allowed within declarations. */  
+        return XML_ERROR_PARAM_ENTITY_REF;
+      case XML_TOK_XML_DECL:
+        return XML_ERROR_MISPLACED_XML_PI;
+      default:
+        return XML_ERROR_SYNTAX;
+      }
+#ifdef XML_DTD
+    case XML_ROLE_IGNORE_SECT:
+      {
+        enum XML_Error result;
+        if (defaultHandler)
+          reportDefault(parser, enc, s, next);
+        handleDefault = XML_FALSE;
+        result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore);
+        if (result != XML_ERROR_NONE)
+          return result;
+        else if (!next) {
+          processor = ignoreSectionProcessor;
+          return result;
+        }
+      }
+      break;
+#endif /* XML_DTD */
+    case XML_ROLE_GROUP_OPEN:
+      if (prologState.level >= groupSize) {
+        if (groupSize) {
+          char *temp = (char *)REALLOC(groupConnector, groupSize *= 2);
+          if (temp == NULL)
+            return XML_ERROR_NO_MEMORY;
+          groupConnector = temp;
+          if (dtd->scaffIndex) {
+            int *temp = (int *)REALLOC(dtd->scaffIndex,
+                          groupSize * sizeof(int));
+            if (temp == NULL)
+              return XML_ERROR_NO_MEMORY;
+            dtd->scaffIndex = temp;
+          }
+        }
+        else {
+          groupConnector = (char *)MALLOC(groupSize = 32);
+          if (!groupConnector)
+            return XML_ERROR_NO_MEMORY;
+        }
+      }
+      groupConnector[prologState.level] = 0;
+      if (dtd->in_eldecl) {
+        int myindex = nextScaffoldPart(parser);
+        if (myindex < 0)
+          return XML_ERROR_NO_MEMORY;
+        dtd->scaffIndex[dtd->scaffLevel] = myindex;
+        dtd->scaffLevel++;
+        dtd->scaffold[myindex].type = XML_CTYPE_SEQ;
+        if (elementDeclHandler)
+          handleDefault = XML_FALSE;
+      }
+      break;
+    case XML_ROLE_GROUP_SEQUENCE:
+      if (groupConnector[prologState.level] == '|')
+        return XML_ERROR_SYNTAX;
+      groupConnector[prologState.level] = ',';
+      if (dtd->in_eldecl && elementDeclHandler)
+        handleDefault = XML_FALSE;
+      break;
+    case XML_ROLE_GROUP_CHOICE:
+      if (groupConnector[prologState.level] == ',')
+        return XML_ERROR_SYNTAX;
+      if (dtd->in_eldecl
+          && !groupConnector[prologState.level]
+          && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
+              != XML_CTYPE_MIXED)
+          ) {
+        dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
+            = XML_CTYPE_CHOICE;
+        if (elementDeclHandler)
+          handleDefault = XML_FALSE;
+      }
+      groupConnector[prologState.level] = '|';
+      break;
+    case XML_ROLE_PARAM_ENTITY_REF:
+#ifdef XML_DTD
+    case XML_ROLE_INNER_PARAM_ENTITY_REF:
+      dtd->hasParamEntityRefs = XML_TRUE;
+      if (!paramEntityParsing)
+        dtd->keepProcessing = dtd->standalone;
+      else {
+        const XML_Char *name;
+        ENTITY *entity;
+        name = poolStoreString(&dtd->pool, enc,
+                                s + enc->minBytesPerChar,
+                                next - enc->minBytesPerChar);
+        if (!name)
+          return XML_ERROR_NO_MEMORY;
+        entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);
+        poolDiscard(&dtd->pool);
+        /* first, determine if a check for an existing declaration is needed;
+           if yes, check that the entity exists, and that it is internal,
+           otherwise call the skipped entity handler
+        */
+        if (prologState.documentEntity &&
+            (dtd->standalone
+             ? !openInternalEntities
+             : !dtd->hasParamEntityRefs)) {
+          if (!entity)
+            return XML_ERROR_UNDEFINED_ENTITY;
+          else if (!entity->is_internal)
+            return XML_ERROR_ENTITY_DECLARED_IN_PE;
+        }
+        else if (!entity) {
+          dtd->keepProcessing = dtd->standalone;
+          /* cannot report skipped entities in declarations */
+          if ((role == XML_ROLE_PARAM_ENTITY_REF) && skippedEntityHandler) {
+            skippedEntityHandler(handlerArg, name, 1);
+            handleDefault = XML_FALSE;
+          }
+          break;
+        }
+        if (entity->open)
+          return XML_ERROR_RECURSIVE_ENTITY_REF;
+        if (entity->textPtr) {
+          enum XML_Error result;
+          XML_Bool betweenDecl = 
+            (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);
+          result = processInternalEntity(parser, entity, betweenDecl);
+          if (result != XML_ERROR_NONE)
+            return result;
+          handleDefault = XML_FALSE;
+          break;
+        }
+        if (externalEntityRefHandler) {
+          dtd->paramEntityRead = XML_FALSE;
+          entity->open = XML_TRUE;
+          if (!externalEntityRefHandler(externalEntityRefHandlerArg,
+                                        0,
+                                        entity->base,
+                                        entity->systemId,
+                                        entity->publicId)) {
+            entity->open = XML_FALSE;
+            return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
+          }
+          entity->open = XML_FALSE;
+          handleDefault = XML_FALSE;
+          if (!dtd->paramEntityRead) {
+            dtd->keepProcessing = dtd->standalone;
+            break;
+          }
+        }
+        else {
+          dtd->keepProcessing = dtd->standalone;
+          break;
+        }
+      }
+#endif /* XML_DTD */
+      if (!dtd->standalone &&
+          notStandaloneHandler &&
+          !notStandaloneHandler(handlerArg))
+        return XML_ERROR_NOT_STANDALONE;
+      break;
+
+    /* Element declaration stuff */
+
+    case XML_ROLE_ELEMENT_NAME:
+      if (elementDeclHandler) {
+        declElementType = getElementType(parser, enc, s, next);
+        if (!declElementType)
+          return XML_ERROR_NO_MEMORY;
+        dtd->scaffLevel = 0;
+        dtd->scaffCount = 0;
+        dtd->in_eldecl = XML_TRUE;
+        handleDefault = XML_FALSE;
+      }
+      break;
+
+    case XML_ROLE_CONTENT_ANY:
+    case XML_ROLE_CONTENT_EMPTY:
+      if (dtd->in_eldecl) {
+        if (elementDeclHandler) {
+          XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content));
+          if (!content)
+            return XML_ERROR_NO_MEMORY;
+          content->quant = XML_CQUANT_NONE;
+          content->name = NULL;
+          content->numchildren = 0;
+          content->children = NULL;
+          content->type = ((role == XML_ROLE_CONTENT_ANY) ?
+                           XML_CTYPE_ANY :
+                           XML_CTYPE_EMPTY);
+          *eventEndPP = s;
+          elementDeclHandler(handlerArg, declElementType->name, content);
+          handleDefault = XML_FALSE;
+        }
+        dtd->in_eldecl = XML_FALSE;
+      }
+      break;
+
+    case XML_ROLE_CONTENT_PCDATA:
+      if (dtd->in_eldecl) {
+        dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
+            = XML_CTYPE_MIXED;
+        if (elementDeclHandler)
+          handleDefault = XML_FALSE;
+      }
+      break;
+
+    case XML_ROLE_CONTENT_ELEMENT:
+      quant = XML_CQUANT_NONE;
+      goto elementContent;
+    case XML_ROLE_CONTENT_ELEMENT_OPT:
+      quant = XML_CQUANT_OPT;
+      goto elementContent;
+    case XML_ROLE_CONTENT_ELEMENT_REP:
+      quant = XML_CQUANT_REP;
+      goto elementContent;
+    case XML_ROLE_CONTENT_ELEMENT_PLUS:
+      quant = XML_CQUANT_PLUS;
+    elementContent:
+      if (dtd->in_eldecl) {
+        ELEMENT_TYPE *el;
+        const XML_Char *name;
+        int nameLen;
+        const char *nxt = (quant == XML_CQUANT_NONE
+                           ? next
+                           : next - enc->minBytesPerChar);
+        int myindex = nextScaffoldPart(parser);
+        if (myindex < 0)
+          return XML_ERROR_NO_MEMORY;
+        dtd->scaffold[myindex].type = XML_CTYPE_NAME;
+        dtd->scaffold[myindex].quant = quant;
+        el = getElementType(parser, enc, s, nxt);
+        if (!el)
+          return XML_ERROR_NO_MEMORY;
+        name = el->name;
+        dtd->scaffold[myindex].name = name;
+        nameLen = 0;
+        for (; name[nameLen++]; );
+        dtd->contentStringLen +=  nameLen;
+        if (elementDeclHandler)
+          handleDefault = XML_FALSE;
+      }
+      break;
+
+    case XML_ROLE_GROUP_CLOSE:
+      quant = XML_CQUANT_NONE;
+      goto closeGroup;
+    case XML_ROLE_GROUP_CLOSE_OPT:
+      quant = XML_CQUANT_OPT;
+      goto closeGroup;
+    case XML_ROLE_GROUP_CLOSE_REP:
+      quant = XML_CQUANT_REP;
+      goto closeGroup;
+    case XML_ROLE_GROUP_CLOSE_PLUS:
+      quant = XML_CQUANT_PLUS;
+    closeGroup:
+      if (dtd->in_eldecl) {
+        if (elementDeclHandler)
+          handleDefault = XML_FALSE;
+        dtd->scaffLevel--;
+        dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant;
+        if (dtd->scaffLevel == 0) {
+          if (!handleDefault) {
+            XML_Content *model = build_model(parser);
+            if (!model)
+              return XML_ERROR_NO_MEMORY;
+            *eventEndPP = s;
+            elementDeclHandler(handlerArg, declElementType->name, model);
+          }
+          dtd->in_eldecl = XML_FALSE;
+          dtd->contentStringLen = 0;
+        }
+      }
+      break;
+      /* End element declaration stuff */
+
+    case XML_ROLE_PI:
+      if (!reportProcessingInstruction(parser, enc, s, next))
+        return XML_ERROR_NO_MEMORY;
+      handleDefault = XML_FALSE;
+      break;
+    case XML_ROLE_COMMENT:
+      if (!reportComment(parser, enc, s, next))
+        return XML_ERROR_NO_MEMORY;
+      handleDefault = XML_FALSE;
+      break;
+    case XML_ROLE_NONE:
+      switch (tok) {
+      case XML_TOK_BOM:
+        handleDefault = XML_FALSE;
+        break;
+      }
+      break;
+    case XML_ROLE_DOCTYPE_NONE:
+      if (startDoctypeDeclHandler)
+        handleDefault = XML_FALSE;
+      break;
+    case XML_ROLE_ENTITY_NONE:
+      if (dtd->keepProcessing && entityDeclHandler)
+        handleDefault = XML_FALSE;
+      break;
+    case XML_ROLE_NOTATION_NONE:
+      if (notationDeclHandler)
+        handleDefault = XML_FALSE;
+      break;
+    case XML_ROLE_ATTLIST_NONE:
+      if (dtd->keepProcessing && attlistDeclHandler)
+        handleDefault = XML_FALSE;
+      break;
+    case XML_ROLE_ELEMENT_NONE:
+      if (elementDeclHandler)
+        handleDefault = XML_FALSE;
+      break;
+    } /* end of big switch */
+
+    if (handleDefault && defaultHandler)
+      reportDefault(parser, enc, s, next);
+
+    switch (ps_parsing) {
+    case XML_SUSPENDED: 
+      *nextPtr = next;
+      return XML_ERROR_NONE;
+    case XML_FINISHED:
+      return XML_ERROR_ABORTED;
+    default:
+      s = next;
+      tok = XmlPrologTok(enc, s, end, &next);
+    }
+  }
+  /* not reached */
+}
+
+static enum XML_Error PTRCALL
+epilogProcessor(XML_Parser parser,
+                const char *s,
+                const char *end,
+                const char **nextPtr)
+{
+  processor = epilogProcessor;
+  eventPtr = s;
+  for (;;) {
+    const char *next = NULL;
+    int tok = XmlPrologTok(encoding, s, end, &next);
+    eventEndPtr = next;
+    switch (tok) {
+    /* report partial linebreak - it might be the last token */
+    case -XML_TOK_PROLOG_S:
+      if (defaultHandler) {
+        reportDefault(parser, encoding, s, next);
+        if (ps_parsing == XML_FINISHED)
+          return XML_ERROR_ABORTED;
+      }
+      *nextPtr = next;
+      return XML_ERROR_NONE;
+    case XML_TOK_NONE:
+      *nextPtr = s;
+      return XML_ERROR_NONE;
+    case XML_TOK_PROLOG_S:
+      if (defaultHandler)
+        reportDefault(parser, encoding, s, next);
+      break;
+    case XML_TOK_PI:
+      if (!reportProcessingInstruction(parser, encoding, s, next))
+        return XML_ERROR_NO_MEMORY;
+      break;
+    case XML_TOK_COMMENT:
+      if (!reportComment(parser, encoding, s, next))
+        return XML_ERROR_NO_MEMORY;
+      break;
+    case XML_TOK_INVALID:
+      eventPtr = next;
+      return XML_ERROR_INVALID_TOKEN;
+    case XML_TOK_PARTIAL:
+      if (!ps_finalBuffer) {
+        *nextPtr = s;
+        return XML_ERROR_NONE;
+      }
+      return XML_ERROR_UNCLOSED_TOKEN;
+    case XML_TOK_PARTIAL_CHAR:
+      if (!ps_finalBuffer) {
+        *nextPtr = s;
+        return XML_ERROR_NONE;
+      }
+      return XML_ERROR_PARTIAL_CHAR;
+    default:
+      return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
+    }
+    eventPtr = s = next;
+    switch (ps_parsing) {
+    case XML_SUSPENDED: 
+      *nextPtr = next;
+      return XML_ERROR_NONE;
+    case XML_FINISHED:
+      return XML_ERROR_ABORTED;
+    default: ;
+    }
+  }
+}
+
+static enum XML_Error
+processInternalEntity(XML_Parser parser, ENTITY *entity,
+                      XML_Bool betweenDecl)
+{
+  const char *textStart, *textEnd;
+  const char *next;
+  enum XML_Error result;
+  OPEN_INTERNAL_ENTITY *openEntity;
+
+  if (freeInternalEntities) {
+    openEntity = freeInternalEntities;
+    freeInternalEntities = openEntity->next;
+  }
+  else {
+    openEntity = (OPEN_INTERNAL_ENTITY *)MALLOC(sizeof(OPEN_INTERNAL_ENTITY));
+    if (!openEntity)
+      return XML_ERROR_NO_MEMORY;
+  }
+  entity->open = XML_TRUE;
+  entity->processed = 0;
+  openEntity->next = openInternalEntities;
+  openInternalEntities = openEntity;
+  openEntity->entity = entity;
+  openEntity->startTagLevel = tagLevel;
+  openEntity->betweenDecl = betweenDecl;
+  openEntity->internalEventPtr = NULL;
+  openEntity->internalEventEndPtr = NULL;
+  textStart = (char *)entity->textPtr;
+  textEnd = (char *)(entity->textPtr + entity->textLen);
+
+#ifdef XML_DTD
+  if (entity->is_param) {
+    int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
+    result = doProlog(parser, internalEncoding, textStart, textEnd, tok, 
+                      next, &next, XML_FALSE);
+  }
+  else 
+#endif /* XML_DTD */
+    result = doContent(parser, tagLevel, internalEncoding, textStart, 
+                       textEnd, &next, XML_FALSE);
+
+  if (result == XML_ERROR_NONE) {
+    if (textEnd != next && ps_parsing == XML_SUSPENDED) {
+      entity->processed = (int)(next - textStart);
+      processor = internalEntityProcessor;
+    }
+    else {
+      entity->open = XML_FALSE;
+      openInternalEntities = openEntity->next;
+      /* put openEntity back in list of free instances */
+      openEntity->next = freeInternalEntities;
+      freeInternalEntities = openEntity;
+    }
+  }
+  return result;
+}
+
+static enum XML_Error PTRCALL
+internalEntityProcessor(XML_Parser parser,
+                        const char *s,
+                        const char *end,
+                        const char **nextPtr)
+{
+  ENTITY *entity;
+  const char *textStart, *textEnd;
+  const char *next;
+  enum XML_Error result;
+  OPEN_INTERNAL_ENTITY *openEntity = openInternalEntities;
+  if (!openEntity)
+    return XML_ERROR_UNEXPECTED_STATE;
+
+  entity = openEntity->entity;
+  textStart = ((char *)entity->textPtr) + entity->processed;
+  textEnd = (char *)(entity->textPtr + entity->textLen);
+
+#ifdef XML_DTD
+  if (entity->is_param) {
+    int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
+    result = doProlog(parser, internalEncoding, textStart, textEnd, tok, 
+                      next, &next, XML_FALSE);
+  }
+  else
+#endif /* XML_DTD */
+    result = doContent(parser, openEntity->startTagLevel, internalEncoding, 
+                       textStart, textEnd, &next, XML_FALSE);  
+
+  if (result != XML_ERROR_NONE)
+    return result;
+  else if (textEnd != next && ps_parsing == XML_SUSPENDED) {
+    entity->processed = (int)(next - (char *)entity->textPtr);
+    return result;
+  }
+  else {
+    entity->open = XML_FALSE;
+    openInternalEntities = openEntity->next;
+    /* put openEntity back in list of free instances */
+    openEntity->next = freeInternalEntities;
+    freeInternalEntities = openEntity;
+  }
+
+#ifdef XML_DTD
+  if (entity->is_param) {
+    int tok;
+    processor = prologProcessor;
+    tok = XmlPrologTok(encoding, s, end, &next);
+    return doProlog(parser, encoding, s, end, tok, next, nextPtr, 
+                    (XML_Bool)!ps_finalBuffer);
+  }
+  else
+#endif /* XML_DTD */
+  {
+    processor = contentProcessor;
+    /* see externalEntityContentProcessor vs contentProcessor */
+    return doContent(parser, parentParser ? 1 : 0, encoding, s, end,
+                     nextPtr, (XML_Bool)!ps_finalBuffer); 
+  }  
+}
+
+static enum XML_Error PTRCALL
+errorProcessor(XML_Parser parser,
+               const char *s,
+               const char *end,
+               const char **nextPtr)
+{
+  return errorCode;
+}
+
+static enum XML_Error
+storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
+                    const char *ptr, const char *end,
+                    STRING_POOL *pool)
+{
+  enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr,
+                                               end, pool);
+  if (result)
+    return result;
+  if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
+    poolChop(pool);
+  if (!poolAppendChar(pool, XML_T('\0')))
+    return XML_ERROR_NO_MEMORY;
+  return XML_ERROR_NONE;
+}
+
+static enum XML_Error
+appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
+                     const char *ptr, const char *end,
+                     STRING_POOL *pool)
+{
+  DTD * const dtd = _dtd;  /* save one level of indirection */
+  for (;;) {
+    const char *next;
+    int tok = XmlAttributeValueTok(enc, ptr, end, &next);
+    switch (tok) {
+    case XML_TOK_NONE:
+      return XML_ERROR_NONE;
+    case XML_TOK_INVALID:
+      if (enc == encoding)
+        eventPtr = next;
+      return XML_ERROR_INVALID_TOKEN;
+    case XML_TOK_PARTIAL:
+      if (enc == encoding)
+        eventPtr = ptr;
+      return XML_ERROR_INVALID_TOKEN;
+    case XML_TOK_CHAR_REF:
+      {
+        XML_Char buf[XML_ENCODE_MAX];
+        int i;
+        int n = XmlCharRefNumber(enc, ptr);
+        if (n < 0) {
+          if (enc == encoding)
+            eventPtr = ptr;
+          return XML_ERROR_BAD_CHAR_REF;
+        }
+        if (!isCdata
+            && n == 0x20 /* space */
+            && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
+          break;
+        n = XmlEncode(n, (ICHAR *)buf);
+        if (!n) {
+          if (enc == encoding)
+            eventPtr = ptr;
+          return XML_ERROR_BAD_CHAR_REF;
+        }
+        for (i = 0; i < n; i++) {
+          if (!poolAppendChar(pool, buf[i]))
+            return XML_ERROR_NO_MEMORY;
+        }
+      }
+      break;
+    case XML_TOK_DATA_CHARS:
+      if (!poolAppend(pool, enc, ptr, next))
+        return XML_ERROR_NO_MEMORY;
+      break;
+    case XML_TOK_TRAILING_CR:
+      next = ptr + enc->minBytesPerChar;
+      /* fall through */
+    case XML_TOK_ATTRIBUTE_VALUE_S:
+    case XML_TOK_DATA_NEWLINE:
+      if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
+        break;
+      if (!poolAppendChar(pool, 0x20))
+        return XML_ERROR_NO_MEMORY;
+      break;
+    case XML_TOK_ENTITY_REF:
+      {
+        const XML_Char *name;
+        ENTITY *entity;
+        char checkEntityDecl;
+        XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
+                                              ptr + enc->minBytesPerChar,
+                                              next - enc->minBytesPerChar);
+        if (ch) {
+          if (!poolAppendChar(pool, ch))
+                return XML_ERROR_NO_MEMORY;
+          break;
+        }
+        name = poolStoreString(&temp2Pool, enc,
+                               ptr + enc->minBytesPerChar,
+                               next - enc->minBytesPerChar);
+        if (!name)
+          return XML_ERROR_NO_MEMORY;
+        entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0);
+        poolDiscard(&temp2Pool);
+        /* First, determine if a check for an existing declaration is needed;
+           if yes, check that the entity exists, and that it is internal.
+        */
+        if (pool == &dtd->pool)  /* are we called from prolog? */
+          checkEntityDecl =
+#ifdef XML_DTD
+              prologState.documentEntity &&
+#endif /* XML_DTD */
+              (dtd->standalone
+               ? !openInternalEntities
+               : !dtd->hasParamEntityRefs);
+        else /* if (pool == &tempPool): we are called from content */
+          checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone;
+        if (checkEntityDecl) {
+          if (!entity)
+            return XML_ERROR_UNDEFINED_ENTITY;
+          else if (!entity->is_internal)
+            return XML_ERROR_ENTITY_DECLARED_IN_PE;
+        }
+        else if (!entity) {
+          /* Cannot report skipped entity here - see comments on
+             skippedEntityHandler.
+          if (skippedEntityHandler)
+            skippedEntityHandler(handlerArg, name, 0);
+          */
+          /* Cannot call the default handler because this would be
+             out of sync with the call to the startElementHandler.
+          if ((pool == &tempPool) && defaultHandler)
+            reportDefault(parser, enc, ptr, next);
+          */
+          break;
+        }
+        if (entity->open) {
+          if (enc == encoding)
+            eventPtr = ptr;
+          return XML_ERROR_RECURSIVE_ENTITY_REF;
+        }
+        if (entity->notation) {
+          if (enc == encoding)
+            eventPtr = ptr;
+          return XML_ERROR_BINARY_ENTITY_REF;
+        }
+        if (!entity->textPtr) {
+          if (enc == encoding)
+            eventPtr = ptr;
+              return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
+        }
+        else {
+          enum XML_Error result;
+          const XML_Char *textEnd = entity->textPtr + entity->textLen;
+          entity->open = XML_TRUE;
+          result = appendAttributeValue(parser, internalEncoding, isCdata,
+                                        (char *)entity->textPtr,
+                                        (char *)textEnd, pool);
+          entity->open = XML_FALSE;
+          if (result)
+            return result;
+        }
+      }
+      break;
+    default:
+      if (enc == encoding)
+        eventPtr = ptr;
+      return XML_ERROR_UNEXPECTED_STATE;
+    }
+    ptr = next;
+  }
+  /* not reached */
+}
+
+static enum XML_Error
+storeEntityValue(XML_Parser parser,
+                 const ENCODING *enc,
+                 const char *entityTextPtr,
+                 const char *entityTextEnd)
+{
+  DTD * const dtd = _dtd;  /* save one level of indirection */
+  STRING_POOL *pool = &(dtd->entityValuePool);
+  enum XML_Error result = XML_ERROR_NONE;
+#ifdef XML_DTD
+  int oldInEntityValue = prologState.inEntityValue;
+  prologState.inEntityValue = 1;
+#endif /* XML_DTD */
+  /* never return Null for the value argument in EntityDeclHandler,
+     since this would indicate an external entity; therefore we
+     have to make sure that entityValuePool.start is not null */
+  if (!pool->blocks) {
+    if (!poolGrow(pool))
+      return XML_ERROR_NO_MEMORY;
+  }
+
+  for (;;) {
+    const char *next;
+    int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
+    switch (tok) {
+    case XML_TOK_PARAM_ENTITY_REF:
+#ifdef XML_DTD
+      if (isParamEntity || enc != encoding) {
+        const XML_Char *name;
+        ENTITY *entity;
+        name = poolStoreString(&tempPool, enc,
+                               entityTextPtr + enc->minBytesPerChar,
+                               next - enc->minBytesPerChar);
+        if (!name) {
+          result = XML_ERROR_NO_MEMORY;
+          goto endEntityValue;
+        }
+        entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);
+        poolDiscard(&tempPool);
+        if (!entity) {
+          /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
+          /* cannot report skipped entity here - see comments on
+             skippedEntityHandler
+          if (skippedEntityHandler)
+            skippedEntityHandler(handlerArg, name, 0);
+          */
+          dtd->keepProcessing = dtd->standalone;
+          goto endEntityValue;
+        }
+        if (entity->open) {
+          if (enc == encoding)
+            eventPtr = entityTextPtr;
+          result = XML_ERROR_RECURSIVE_ENTITY_REF;
+          goto endEntityValue;
+        }
+        if (entity->systemId) {
+          if (externalEntityRefHandler) {
+            dtd->paramEntityRead = XML_FALSE;
+            entity->open = XML_TRUE;
+            if (!externalEntityRefHandler(externalEntityRefHandlerArg,
+                                          0,
+                                          entity->base,
+                                          entity->systemId,
+                                          entity->publicId)) {
+              entity->open = XML_FALSE;
+              result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
+              goto endEntityValue;
+            }
+            entity->open = XML_FALSE;
+            if (!dtd->paramEntityRead)
+              dtd->keepProcessing = dtd->standalone;
+          }
+          else
+            dtd->keepProcessing = dtd->standalone;
+        }
+        else {
+          entity->open = XML_TRUE;
+          result = storeEntityValue(parser,
+                                    internalEncoding,
+                                    (char *)entity->textPtr,
+                                    (char *)(entity->textPtr
+                                             + entity->textLen));
+          entity->open = XML_FALSE;
+          if (result)
+            goto endEntityValue;
+        }
+        break;
+      }
+#endif /* XML_DTD */
+      /* In the internal subset, PE references are not legal
+         within markup declarations, e.g entity values in this case. */
+      eventPtr = entityTextPtr;
+      result = XML_ERROR_PARAM_ENTITY_REF;
+      goto endEntityValue;
+    case XML_TOK_NONE:
+      result = XML_ERROR_NONE;
+      goto endEntityValue;
+    case XML_TOK_ENTITY_REF:
+    case XML_TOK_DATA_CHARS:
+      if (!poolAppend(pool, enc, entityTextPtr, next)) {
+        result = XML_ERROR_NO_MEMORY;
+        goto endEntityValue;
+      }
+      break;
+    case XML_TOK_TRAILING_CR:
+      next = entityTextPtr + enc->minBytesPerChar;
+      /* fall through */
+    case XML_TOK_DATA_NEWLINE:
+      if (pool->end == pool->ptr && !poolGrow(pool)) {
+              result = XML_ERROR_NO_MEMORY;
+        goto endEntityValue;
+      }
+      *(pool->ptr)++ = 0xA;
+      break;
+    case XML_TOK_CHAR_REF:
+      {
+        XML_Char buf[XML_ENCODE_MAX];
+        int i;
+        int n = XmlCharRefNumber(enc, entityTextPtr);
+        if (n < 0) {
+          if (enc == encoding)
+            eventPtr = entityTextPtr;
+          result = XML_ERROR_BAD_CHAR_REF;
+          goto endEntityValue;
+        }
+        n = XmlEncode(n, (ICHAR *)buf);
+        if (!n) {
+          if (enc == encoding)
+            eventPtr = entityTextPtr;
+          result = XML_ERROR_BAD_CHAR_REF;
+          goto endEntityValue;
+        }
+        for (i = 0; i < n; i++) {
+          if (pool->end == pool->ptr && !poolGrow(pool)) {
+            result = XML_ERROR_NO_MEMORY;
+            goto endEntityValue;
+          }
+          *(pool->ptr)++ = buf[i];
+        }
+      }
+      break;
+    case XML_TOK_PARTIAL:
+      if (enc == encoding)
+        eventPtr = entityTextPtr;
+      result = XML_ERROR_INVALID_TOKEN;
+      goto endEntityValue;
+    case XML_TOK_INVALID:
+      if (enc == encoding)
+        eventPtr = next;
+      result = XML_ERROR_INVALID_TOKEN;
+      goto endEntityValue;
+    default:
+      if (enc == encoding)
+        eventPtr = entityTextPtr;
+      result = XML_ERROR_UNEXPECTED_STATE;
+      goto endEntityValue;
+    }
+    entityTextPtr = next;
+  }
+endEntityValue:
+#ifdef XML_DTD
+  prologState.inEntityValue = oldInEntityValue;
+#endif /* XML_DTD */
+  return result;
+}
+
+static void FASTCALL
+normalizeLines(XML_Char *s)
+{
+  XML_Char *p;
+  for (;; s++) {
+    if (*s == XML_T('\0'))
+      return;
+    if (*s == 0xD)
+      break;
+  }
+  p = s;
+  do {
+    if (*s == 0xD) {
+      *p++ = 0xA;
+      if (*++s == 0xA)
+        s++;
+    }
+    else
+      *p++ = *s++;
+  } while (*s);
+  *p = XML_T('\0');
+}
+
+static int
+reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
+                            const char *start, const char *end)
+{
+  const XML_Char *target;
+  XML_Char *data;
+  const char *tem;
+  if (!processingInstructionHandler) {
+    if (defaultHandler)
+      reportDefault(parser, enc, start, end);
+    return 1;
+  }
+  start += enc->minBytesPerChar * 2;
+  tem = start + XmlNameLength(enc, start);
+  target = poolStoreString(&tempPool, enc, start, tem);
+  if (!target)
+    return 0;
+  poolFinish(&tempPool);
+  data = poolStoreString(&tempPool, enc,
+                        XmlSkipS(enc, tem),
+                        end - enc->minBytesPerChar*2);
+  if (!data)
+    return 0;
+  normalizeLines(data);
+  processingInstructionHandler(handlerArg, target, data);
+  poolClear(&tempPool);
+  return 1;
+}
+
+static int
+reportComment(XML_Parser parser, const ENCODING *enc,
+              const char *start, const char *end)
+{
+  XML_Char *data;
+  if (!commentHandler) {
+    if (defaultHandler)
+      reportDefault(parser, enc, start, end);
+    return 1;
+  }
+  data = poolStoreString(&tempPool,
+                         enc,
+                         start + enc->minBytesPerChar * 4,
+                         end - enc->minBytesPerChar * 3);
+  if (!data)
+    return 0;
+  normalizeLines(data);
+  commentHandler(handlerArg, data);
+  poolClear(&tempPool);
+  return 1;
+}
+
+static void
+reportDefault(XML_Parser parser, const ENCODING *enc,
+              const char *s, const char *end)
+{
+  if (MUST_CONVERT(enc, s)) {
+    const char **eventPP;
+    const char **eventEndPP;
+    if (enc == encoding) {
+      eventPP = &eventPtr;
+      eventEndPP = &eventEndPtr;
+    }
+    else {
+      eventPP = &(openInternalEntities->internalEventPtr);
+      eventEndPP = &(openInternalEntities->internalEventEndPtr);
+    }
+    do {
+      ICHAR *dataPtr = (ICHAR *)dataBuf;
+      XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
+      *eventEndPP = s;
+      defaultHandler(handlerArg, dataBuf, (int)(dataPtr - (ICHAR *)dataBuf));
+      *eventPP = s;
+    } while (s != end);
+  }
+  else
+    defaultHandler(handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s));
+}
+
+
+static int
+defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
+                XML_Bool isId, const XML_Char *value, XML_Parser parser)
+{
+  DEFAULT_ATTRIBUTE *att;
+  if (value || isId) {
+    /* The handling of default attributes gets messed up if we have
+       a default which duplicates a non-default. */
+    int i;
+    for (i = 0; i < type->nDefaultAtts; i++)
+      if (attId == type->defaultAtts[i].id)
+        return 1;
+    if (isId && !type->idAtt && !attId->xmlns)
+      type->idAtt = attId;
+  }
+  if (type->nDefaultAtts == type->allocDefaultAtts) {
+    if (type->allocDefaultAtts == 0) {
+      type->allocDefaultAtts = 8;
+      type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(type->allocDefaultAtts
+                            * sizeof(DEFAULT_ATTRIBUTE));
+      if (!type->defaultAtts)
+        return 0;
+    }
+    else {
+      DEFAULT_ATTRIBUTE *temp;
+      int count = type->allocDefaultAtts * 2;
+      temp = (DEFAULT_ATTRIBUTE *)
+        REALLOC(type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE)));
+      if (temp == NULL)
+        return 0;
+      type->allocDefaultAtts = count;
+      type->defaultAtts = temp;
+    }
+  }
+  att = type->defaultAtts + type->nDefaultAtts;
+  att->id = attId;
+  att->value = value;
+  att->isCdata = isCdata;
+  if (!isCdata)
+    attId->maybeTokenized = XML_TRUE;
+  type->nDefaultAtts += 1;
+  return 1;
+}
+
+static int
+setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
+{
+  DTD * const dtd = _dtd;  /* save one level of indirection */
+  const XML_Char *name;
+  for (name = elementType->name; *name; name++) {
+    if (*name == XML_T(':')) {
+      PREFIX *prefix;
+      const XML_Char *s;
+      for (s = elementType->name; s != name; s++) {
+        if (!poolAppendChar(&dtd->pool, *s))
+          return 0;
+      }
+      if (!poolAppendChar(&dtd->pool, XML_T('\0')))
+        return 0;
+      prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),
+                                sizeof(PREFIX));
+      if (!prefix)
+        return 0;
+      if (prefix->name == poolStart(&dtd->pool))
+        poolFinish(&dtd->pool);
+      else
+        poolDiscard(&dtd->pool);
+      elementType->prefix = prefix;
+
+    }
+  }
+  return 1;
+}
+
+static ATTRIBUTE_ID *
+getAttributeId(XML_Parser parser, const ENCODING *enc,
+               const char *start, const char *end)
+{
+  DTD * const dtd = _dtd;  /* save one level of indirection */
+  ATTRIBUTE_ID *id;
+  const XML_Char *name;
+  if (!poolAppendChar(&dtd->pool, XML_T('\0')))
+    return NULL;
+  name = poolStoreString(&dtd->pool, enc, start, end);
+  if (!name)
+    return NULL;
+  /* skip quotation mark - its storage will be re-used (like in name[-1]) */
+  ++name;
+  id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, name, sizeof(ATTRIBUTE_ID));
+  if (!id)
+    return NULL;
+  if (id->name != name)
+    poolDiscard(&dtd->pool);
+  else {
+    poolFinish(&dtd->pool);
+    if (!ns)
+      ;
+    else if (name[0] == XML_T('x')
+        && name[1] == XML_T('m')
+        && name[2] == XML_T('l')
+        && name[3] == XML_T('n')
+        && name[4] == XML_T('s')
+        && (name[5] == XML_T('\0') || name[5] == XML_T(':'))) {
+      if (name[5] == XML_T('\0'))
+        id->prefix = &dtd->defaultPrefix;
+      else
+        id->prefix = (PREFIX *)lookup(&dtd->prefixes, name + 6, sizeof(PREFIX));
+      id->xmlns = XML_TRUE;
+    }
+    else {
+      int i;
+      for (i = 0; name[i]; i++) {
+        /* attributes without prefix are *not* in the default namespace */
+        if (name[i] == XML_T(':')) {
+          int j;
+          for (j = 0; j < i; j++) {
+            if (!poolAppendChar(&dtd->pool, name[j]))
+              return NULL;
+          }
+          if (!poolAppendChar(&dtd->pool, XML_T('\0')))
+            return NULL;
+          id->prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),
+                                        sizeof(PREFIX));
+          if (!id->prefix)
+            return NULL;
+          if (id->prefix->name == poolStart(&dtd->pool))
+            poolFinish(&dtd->pool);
+          else
+            poolDiscard(&dtd->pool);
+          break;
+        }
+      }
+    }
+  }
+  return id;
+}
+
+#define CONTEXT_SEP XML_T('\f')
+
+static const XML_Char *
+getContext(XML_Parser parser)
+{
+  DTD * const dtd = _dtd;  /* save one level of indirection */
+  HASH_TABLE_ITER iter;
+  XML_Bool needSep = XML_FALSE;
+
+  if (dtd->defaultPrefix.binding) {
+    int i;
+    int len;
+    if (!poolAppendChar(&tempPool, XML_T('=')))
+      return NULL;
+    len = dtd->defaultPrefix.binding->uriLen;
+    if (namespaceSeparator)
+      len--;
+    for (i = 0; i < len; i++)
+      if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i]))
+        return NULL;
+    needSep = XML_TRUE;
+  }
+
+  hashTableIterInit(&iter, &(dtd->prefixes));
+  for (;;) {
+    int i;
+    int len;
+    const XML_Char *s;
+    PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
+    if (!prefix)
+      break;
+    if (!prefix->binding)
+      continue;
+    if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
+      return NULL;
+    for (s = prefix->name; *s; s++)
+      if (!poolAppendChar(&tempPool, *s))
+        return NULL;
+    if (!poolAppendChar(&tempPool, XML_T('=')))
+      return NULL;
+    len = prefix->binding->uriLen;
+    if (namespaceSeparator)
+      len--;
+    for (i = 0; i < len; i++)
+      if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
+        return NULL;
+    needSep = XML_TRUE;
+  }
+
+
+  hashTableIterInit(&iter, &(dtd->generalEntities));
+  for (;;) {
+    const XML_Char *s;
+    ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
+    if (!e)
+      break;
+    if (!e->open)
+      continue;
+    if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
+      return NULL;
+    for (s = e->name; *s; s++)
+      if (!poolAppendChar(&tempPool, *s))
+        return 0;
+    needSep = XML_TRUE;
+  }
+
+  if (!poolAppendChar(&tempPool, XML_T('\0')))
+    return NULL;
+  return tempPool.start;
+}
+
+static XML_Bool
+setContext(XML_Parser parser, const XML_Char *context)
+{
+  DTD * const dtd = _dtd;  /* save one level of indirection */
+  const XML_Char *s = context;
+
+  while (*context != XML_T('\0')) {
+    if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
+      ENTITY *e;
+      if (!poolAppendChar(&tempPool, XML_T('\0')))
+        return XML_FALSE;
+      e = (ENTITY *)lookup(&dtd->generalEntities, poolStart(&tempPool), 0);
+      if (e)
+        e->open = XML_TRUE;
+      if (*s != XML_T('\0'))
+        s++;
+      context = s;
+      poolDiscard(&tempPool);
+    }
+    else if (*s == XML_T('=')) {
+      PREFIX *prefix;
+      if (poolLength(&tempPool) == 0)
+        prefix = &dtd->defaultPrefix;
+      else {
+        if (!poolAppendChar(&tempPool, XML_T('\0')))
+          return XML_FALSE;
+        prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&tempPool),
+                                  sizeof(PREFIX));
+        if (!prefix)
+          return XML_FALSE;
+        if (prefix->name == poolStart(&tempPool)) {
+          prefix->name = poolCopyString(&dtd->pool, prefix->name);
+          if (!prefix->name)
+            return XML_FALSE;
+        }
+        poolDiscard(&tempPool);
+      }
+      for (context = s + 1;
+           *context != CONTEXT_SEP && *context != XML_T('\0');
+           context++)
+        if (!poolAppendChar(&tempPool, *context))
+          return XML_FALSE;
+      if (!poolAppendChar(&tempPool, XML_T('\0')))
+        return XML_FALSE;
+      if (addBinding(parser, prefix, NULL, poolStart(&tempPool),
+                     &inheritedBindings) != XML_ERROR_NONE)
+        return XML_FALSE;
+      poolDiscard(&tempPool);
+      if (*context != XML_T('\0'))
+        ++context;
+      s = context;
+    }
+    else {
+      if (!poolAppendChar(&tempPool, *s))
+        return XML_FALSE;
+      s++;
+    }
+  }
+  return XML_TRUE;
+}
+
+static void FASTCALL
+normalizePublicId(XML_Char *publicId)
+{
+  XML_Char *p = publicId;
+  XML_Char *s;
+  for (s = publicId; *s; s++) {
+    switch (*s) {
+    case 0x20:
+    case 0xD:
+    case 0xA:
+      if (p != publicId && p[-1] != 0x20)
+        *p++ = 0x20;
+      break;
+    default:
+      *p++ = *s;
+    }
+  }
+  if (p != publicId && p[-1] == 0x20)
+    --p;
+  *p = XML_T('\0');
+}
+
+static DTD *
+dtdCreate(const XML_Memory_Handling_Suite *ms)
+{
+  DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD));
+  if (p == NULL)
+    return p;
+  poolInit(&(p->pool), ms);
+  poolInit(&(p->entityValuePool), ms);
+  hashTableInit(&(p->generalEntities), ms);
+  hashTableInit(&(p->elementTypes), ms);
+  hashTableInit(&(p->attributeIds), ms);
+  hashTableInit(&(p->prefixes), ms);
+#ifdef XML_DTD
+  p->paramEntityRead = XML_FALSE;
+  hashTableInit(&(p->paramEntities), ms);
+#endif /* XML_DTD */
+  p->defaultPrefix.name = NULL;
+  p->defaultPrefix.binding = NULL;
+
+  p->in_eldecl = XML_FALSE;
+  p->scaffIndex = NULL;
+  p->scaffold = NULL;
+  p->scaffLevel = 0;
+  p->scaffSize = 0;
+  p->scaffCount = 0;
+  p->contentStringLen = 0;
+
+  p->keepProcessing = XML_TRUE;
+  p->hasParamEntityRefs = XML_FALSE;
+  p->standalone = XML_FALSE;
+  return p;
+}
+
+static void
+dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms)
+{
+  HASH_TABLE_ITER iter;
+  hashTableIterInit(&iter, &(p->elementTypes));
+  for (;;) {
+    ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
+    if (!e)
+      break;
+    if (e->allocDefaultAtts != 0)
+      ms->free_fcn(e->defaultAtts);
+  }
+  hashTableClear(&(p->generalEntities));
+#ifdef XML_DTD
+  p->paramEntityRead = XML_FALSE;
+  hashTableClear(&(p->paramEntities));
+#endif /* XML_DTD */
+  hashTableClear(&(p->elementTypes));
+  hashTableClear(&(p->attributeIds));
+  hashTableClear(&(p->prefixes));
+  poolClear(&(p->pool));
+  poolClear(&(p->entityValuePool));
+  p->defaultPrefix.name = NULL;
+  p->defaultPrefix.binding = NULL;
+
+  p->in_eldecl = XML_FALSE;
+
+  ms->free_fcn(p->scaffIndex);
+  p->scaffIndex = NULL;
+  ms->free_fcn(p->scaffold);
+  p->scaffold = NULL;
+
+  p->scaffLevel = 0;
+  p->scaffSize = 0;
+  p->scaffCount = 0;
+  p->contentStringLen = 0;
+
+  p->keepProcessing = XML_TRUE;
+  p->hasParamEntityRefs = XML_FALSE;
+  p->standalone = XML_FALSE;
+}
+
+static void
+dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms)
+{
+  HASH_TABLE_ITER iter;
+  hashTableIterInit(&iter, &(p->elementTypes));
+  for (;;) {
+    ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
+    if (!e)
+      break;
+    if (e->allocDefaultAtts != 0)
+      ms->free_fcn(e->defaultAtts);
+  }
+  hashTableDestroy(&(p->generalEntities));
+#ifdef XML_DTD
+  hashTableDestroy(&(p->paramEntities));
+#endif /* XML_DTD */
+  hashTableDestroy(&(p->elementTypes));
+  hashTableDestroy(&(p->attributeIds));
+  hashTableDestroy(&(p->prefixes));
+  poolDestroy(&(p->pool));
+  poolDestroy(&(p->entityValuePool));
+  if (isDocEntity) {
+    ms->free_fcn(p->scaffIndex);
+    ms->free_fcn(p->scaffold);
+  }
+  ms->free_fcn(p);
+}
+
+/* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
+   The new DTD has already been initialized.
+*/
+static int
+dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms)
+{
+  HASH_TABLE_ITER iter;
+
+  /* Copy the prefix table. */
+
+  hashTableIterInit(&iter, &(oldDtd->prefixes));
+  for (;;) {
+    const XML_Char *name;
+    const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
+    if (!oldP)
+      break;
+    name = poolCopyString(&(newDtd->pool), oldP->name);
+    if (!name)
+      return 0;
+    if (!lookup(&(newDtd->prefixes), name, sizeof(PREFIX)))
+      return 0;
+  }
+
+  hashTableIterInit(&iter, &(oldDtd->attributeIds));
+
+  /* Copy the attribute id table. */
+
+  for (;;) {
+    ATTRIBUTE_ID *newA;
+    const XML_Char *name;
+    const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
+
+    if (!oldA)
+      break;
+    /* Remember to allocate the scratch byte before the name. */
+    if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))
+      return 0;
+    name = poolCopyString(&(newDtd->pool), oldA->name);
+    if (!name)
+      return 0;
+    ++name;
+    newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name,
+                                  sizeof(ATTRIBUTE_ID));
+    if (!newA)
+      return 0;
+    newA->maybeTokenized = oldA->maybeTokenized;
+    if (oldA->prefix) {
+      newA->xmlns = oldA->xmlns;
+      if (oldA->prefix == &oldDtd->defaultPrefix)
+        newA->prefix = &newDtd->defaultPrefix;
+      else
+        newA->prefix = (PREFIX *)lookup(&(newDtd->prefixes),
+                                        oldA->prefix->name, 0);
+    }
+  }
+
+  /* Copy the element type table. */
+
+  hashTableIterInit(&iter, &(oldDtd->elementTypes));
+
+  for (;;) {
+    int i;
+    ELEMENT_TYPE *newE;
+    const XML_Char *name;
+    const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
+    if (!oldE)
+      break;
+    name = poolCopyString(&(newDtd->pool), oldE->name);
+    if (!name)
+      return 0;
+    newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name,
+                                  sizeof(ELEMENT_TYPE));
+    if (!newE)
+      return 0;
+    if (oldE->nDefaultAtts) {
+      newE->defaultAtts = (DEFAULT_ATTRIBUTE *)
+          ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
+      if (!newE->defaultAtts) {
+        ms->free_fcn(newE);
+        return 0;
+      }
+    }
+    if (oldE->idAtt)
+      newE->idAtt = (ATTRIBUTE_ID *)
+          lookup(&(newDtd->attributeIds), oldE->idAtt->name, 0);
+    newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
+    if (oldE->prefix)
+      newE->prefix = (PREFIX *)lookup(&(newDtd->prefixes),
+                                      oldE->prefix->name, 0);
+    for (i = 0; i < newE->nDefaultAtts; i++) {
+      newE->defaultAtts[i].id = (ATTRIBUTE_ID *)
+          lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
+      newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
+      if (oldE->defaultAtts[i].value) {
+        newE->defaultAtts[i].value
+            = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
+        if (!newE->defaultAtts[i].value)
+          return 0;
+      }
+      else
+        newE->defaultAtts[i].value = NULL;
+    }
+  }
+
+  /* Copy the entity tables. */
+  if (!copyEntityTable(&(newDtd->generalEntities),
+                       &(newDtd->pool),
+                       &(oldDtd->generalEntities)))
+      return 0;
+
+#ifdef XML_DTD
+  if (!copyEntityTable(&(newDtd->paramEntities),
+                       &(newDtd->pool),
+                       &(oldDtd->paramEntities)))
+      return 0;
+  newDtd->paramEntityRead = oldDtd->paramEntityRead;
+#endif /* XML_DTD */
+
+  newDtd->keepProcessing = oldDtd->keepProcessing;
+  newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs;
+  newDtd->standalone = oldDtd->standalone;
+
+  /* Don't want deep copying for scaffolding */
+  newDtd->in_eldecl = oldDtd->in_eldecl;
+  newDtd->scaffold = oldDtd->scaffold;
+  newDtd->contentStringLen = oldDtd->contentStringLen;
+  newDtd->scaffSize = oldDtd->scaffSize;
+  newDtd->scaffLevel = oldDtd->scaffLevel;
+  newDtd->scaffIndex = oldDtd->scaffIndex;
+
+  return 1;
+}  /* End dtdCopy */
+
+static int
+copyEntityTable(HASH_TABLE *newTable,
+                STRING_POOL *newPool,
+                const HASH_TABLE *oldTable)
+{
+  HASH_TABLE_ITER iter;
+  const XML_Char *cachedOldBase = NULL;
+  const XML_Char *cachedNewBase = NULL;
+
+  hashTableIterInit(&iter, oldTable);
+
+  for (;;) {
+    ENTITY *newE;
+    const XML_Char *name;
+    const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
+    if (!oldE)
+      break;
+    name = poolCopyString(newPool, oldE->name);
+    if (!name)
+      return 0;
+    newE = (ENTITY *)lookup(newTable, name, sizeof(ENTITY));
+    if (!newE)
+      return 0;
+    if (oldE->systemId) {
+      const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
+      if (!tem)
+        return 0;
+      newE->systemId = tem;
+      if (oldE->base) {
+        if (oldE->base == cachedOldBase)
+          newE->base = cachedNewBase;
+        else {
+          cachedOldBase = oldE->base;
+          tem = poolCopyString(newPool, cachedOldBase);
+          if (!tem)
+            return 0;
+          cachedNewBase = newE->base = tem;
+        }
+      }
+      if (oldE->publicId) {
+        tem = poolCopyString(newPool, oldE->publicId);
+        if (!tem)
+          return 0;
+        newE->publicId = tem;
+      }
+    }
+    else {
+      const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr,
+                                            oldE->textLen);
+      if (!tem)
+        return 0;
+      newE->textPtr = tem;
+      newE->textLen = oldE->textLen;
+    }
+    if (oldE->notation) {
+      const XML_Char *tem = poolCopyString(newPool, oldE->notation);
+      if (!tem)
+        return 0;
+      newE->notation = tem;
+    }
+    newE->is_param = oldE->is_param;
+    newE->is_internal = oldE->is_internal;
+  }
+  return 1;
+}
+
+#define INIT_POWER 6
+
+static XML_Bool FASTCALL
+keyeq(KEY s1, KEY s2)
+{
+  for (; *s1 == *s2; s1++, s2++)
+    if (*s1 == 0)
+      return XML_TRUE;
+  return XML_FALSE;
+}
+
+static unsigned long FASTCALL
+hash(KEY s)
+{
+  unsigned long h = 0;
+  while (*s)
+    h = CHAR_HASH(h, *s++);
+  return h;
+}
+
+static NAMED *
+lookup(HASH_TABLE *table, KEY name, size_t createSize)
+{
+  size_t i;
+  if (table->size == 0) {
+    size_t tsize;
+    if (!createSize)
+      return NULL;
+    table->power = INIT_POWER;
+    /* table->size is a power of 2 */
+    table->size = (size_t)1 << INIT_POWER;
+    tsize = table->size * sizeof(NAMED *);
+    table->v = (NAMED **)table->mem->malloc_fcn(tsize);
+    if (!table->v) {
+      table->size = 0;
+      return NULL;
+    }
+    memset(table->v, 0, tsize);
+    i = hash(name) & ((unsigned long)table->size - 1);
+  }
+  else {
+    unsigned long h = hash(name);
+    unsigned long mask = (unsigned long)table->size - 1;
+    unsigned char step = 0;
+    i = h & mask;
+    while (table->v[i]) {
+      if (keyeq(name, table->v[i]->name))
+        return table->v[i];
+      if (!step)
+        step = PROBE_STEP(h, mask, table->power);
+      i < step ? (i += table->size - step) : (i -= step);
+    }
+    if (!createSize)
+      return NULL;
+
+    /* check for overflow (table is half full) */
+    if (table->used >> (table->power - 1)) {
+      unsigned char newPower = table->power + 1;
+      size_t newSize = (size_t)1 << newPower;
+      unsigned long newMask = (unsigned long)newSize - 1;
+      size_t tsize = newSize * sizeof(NAMED *);
+      NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);
+      if (!newV)
+        return NULL;
+      memset(newV, 0, tsize);
+      for (i = 0; i < table->size; i++)
+        if (table->v[i]) {
+          unsigned long newHash = hash(table->v[i]->name);
+          size_t j = newHash & newMask;
+          step = 0;
+          while (newV[j]) {
+            if (!step)
+              step = PROBE_STEP(newHash, newMask, newPower);
+            j < step ? (j += newSize - step) : (j -= step);
+          }
+          newV[j] = table->v[i];
+        }
+      table->mem->free_fcn(table->v);
+      table->v = newV;
+      table->power = newPower;
+      table->size = newSize;
+      i = h & newMask;
+      step = 0;
+      while (table->v[i]) {
+        if (!step)
+          step = PROBE_STEP(h, newMask, newPower);
+        i < step ? (i += newSize - step) : (i -= step);
+      }
+    }
+  }
+  table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize);
+  if (!table->v[i])
+    return NULL;
+  memset(table->v[i], 0, createSize);
+  table->v[i]->name = name;
+  (table->used)++;
+  return table->v[i];
+}
+
+static void FASTCALL
+hashTableClear(HASH_TABLE *table)
+{
+  size_t i;
+  for (i = 0; i < table->size; i++) {
+    table->mem->free_fcn(table->v[i]);
+    table->v[i] = NULL;
+  }
+  table->used = 0;
+}
+
+static void FASTCALL
+hashTableDestroy(HASH_TABLE *table)
+{
+  size_t i;
+  for (i = 0; i < table->size; i++)
+    table->mem->free_fcn(table->v[i]);
+  table->mem->free_fcn(table->v);
+}
+
+static void FASTCALL
+hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms)
+{
+  p->power = 0;
+  p->size = 0;
+  p->used = 0;
+  p->v = NULL;
+  p->mem = ms;
+}
+
+static void FASTCALL
+hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
+{
+  iter->p = table->v;
+  iter->end = iter->p + table->size;
+}
+
+static NAMED * FASTCALL
+hashTableIterNext(HASH_TABLE_ITER *iter)
+{
+  while (iter->p != iter->end) {
+    NAMED *tem = *(iter->p)++;
+    if (tem)
+      return tem;
+  }
+  return NULL;
+}
+
+static void FASTCALL
+poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms)
+{
+  pool->blocks = NULL;
+  pool->freeBlocks = NULL;
+  pool->start = NULL;
+  pool->ptr = NULL;
+  pool->end = NULL;
+  pool->mem = ms;
+}
+
+static void FASTCALL
+poolClear(STRING_POOL *pool)
+{
+  if (!pool->freeBlocks)
+    pool->freeBlocks = pool->blocks;
+  else {
+    BLOCK *p = pool->blocks;
+    while (p) {
+      BLOCK *tem = p->next;
+      p->next = pool->freeBlocks;
+      pool->freeBlocks = p;
+      p = tem;
+    }
+  }
+  pool->blocks = NULL;
+  pool->start = NULL;
+  pool->ptr = NULL;
+  pool->end = NULL;
+}
+
+static void FASTCALL
+poolDestroy(STRING_POOL *pool)
+{
+  BLOCK *p = pool->blocks;
+  while (p) {
+    BLOCK *tem = p->next;
+    pool->mem->free_fcn(p);
+    p = tem;
+  }
+  p = pool->freeBlocks;
+  while (p) {
+    BLOCK *tem = p->next;
+    pool->mem->free_fcn(p);
+    p = tem;
+  }
+}
+
+static XML_Char *
+poolAppend(STRING_POOL *pool, const ENCODING *enc,
+           const char *ptr, const char *end)
+{
+  if (!pool->ptr && !poolGrow(pool))
+    return NULL;
+  for (;;) {
+    XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
+    if (ptr == end)
+      break;
+    if (!poolGrow(pool))
+      return NULL;
+  }
+  return pool->start;
+}
+
+static const XML_Char * FASTCALL
+poolCopyString(STRING_POOL *pool, const XML_Char *s)
+{
+  do {
+    if (!poolAppendChar(pool, *s))
+      return NULL;
+  } while (*s++);
+  s = pool->start;
+  poolFinish(pool);
+  return s;
+}
+
+static const XML_Char *
+poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
+{
+  if (!pool->ptr && !poolGrow(pool))
+    return NULL;
+  for (; n > 0; --n, s++) {
+    if (!poolAppendChar(pool, *s))
+      return NULL;
+  }
+  s = pool->start;
+  poolFinish(pool);
+  return s;
+}
+
+static const XML_Char * FASTCALL
+poolAppendString(STRING_POOL *pool, const XML_Char *s)
+{
+  while (*s) {
+    if (!poolAppendChar(pool, *s))
+      return NULL;
+    s++;
+  }
+  return pool->start;
+}
+
+static XML_Char *
+poolStoreString(STRING_POOL *pool, const ENCODING *enc,
+                const char *ptr, const char *end)
+{
+  if (!poolAppend(pool, enc, ptr, end))
+    return NULL;
+  if (pool->ptr == pool->end && !poolGrow(pool))
+    return NULL;
+  *(pool->ptr)++ = 0;
+  return pool->start;
+}
+
+static XML_Bool FASTCALL
+poolGrow(STRING_POOL *pool)
+{
+  if (pool->freeBlocks) {
+    if (pool->start == 0) {
+      pool->blocks = pool->freeBlocks;
+      pool->freeBlocks = pool->freeBlocks->next;
+      pool->blocks->next = NULL;
+      pool->start = pool->blocks->s;
+      pool->end = pool->start + pool->blocks->size;
+      pool->ptr = pool->start;
+      return XML_TRUE;
+    }
+    if (pool->end - pool->start < pool->freeBlocks->size) {
+      BLOCK *tem = pool->freeBlocks->next;
+      pool->freeBlocks->next = pool->blocks;
+      pool->blocks = pool->freeBlocks;
+      pool->freeBlocks = tem;
+      memcpy(pool->blocks->s, pool->start,
+             (pool->end - pool->start) * sizeof(XML_Char));
+      pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
+      pool->start = pool->blocks->s;
+      pool->end = pool->start + pool->blocks->size;
+      return XML_TRUE;
+    }
+  }
+  if (pool->blocks && pool->start == pool->blocks->s) {
+    int blockSize = (int)(pool->end - pool->start)*2;
+    pool->blocks = (BLOCK *)
+      pool->mem->realloc_fcn(pool->blocks,
+                             (offsetof(BLOCK, s)
+                              + blockSize * sizeof(XML_Char)));
+    if (pool->blocks == NULL)
+      return XML_FALSE;
+    pool->blocks->size = blockSize;
+    pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
+    pool->start = pool->blocks->s;
+    pool->end = pool->start + blockSize;
+  }
+  else {
+    BLOCK *tem;
+    int blockSize = (int)(pool->end - pool->start);
+    if (blockSize < INIT_BLOCK_SIZE)
+      blockSize = INIT_BLOCK_SIZE;
+    else
+      blockSize *= 2;
+    tem = (BLOCK *)pool->mem->malloc_fcn(offsetof(BLOCK, s)
+                                        + blockSize * sizeof(XML_Char));
+    if (!tem)
+      return XML_FALSE;
+    tem->size = blockSize;
+    tem->next = pool->blocks;
+    pool->blocks = tem;
+    if (pool->ptr != pool->start)
+      memcpy(tem->s, pool->start,
+             (pool->ptr - pool->start) * sizeof(XML_Char));
+    pool->ptr = tem->s + (pool->ptr - pool->start);
+    pool->start = tem->s;
+    pool->end = tem->s + blockSize;
+  }
+  return XML_TRUE;
+}
+
+static int FASTCALL
+nextScaffoldPart(XML_Parser parser)
+{
+  DTD * const dtd = _dtd;  /* save one level of indirection */
+  CONTENT_SCAFFOLD * me;
+  int next;
+
+  if (!dtd->scaffIndex) {
+    dtd->scaffIndex = (int *)MALLOC(groupSize * sizeof(int));
+    if (!dtd->scaffIndex)
+      return -1;
+    dtd->scaffIndex[0] = 0;
+  }
+
+  if (dtd->scaffCount >= dtd->scaffSize) {
+    CONTENT_SCAFFOLD *temp;
+    if (dtd->scaffold) {
+      temp = (CONTENT_SCAFFOLD *)
+        REALLOC(dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
+      if (temp == NULL)
+        return -1;
+      dtd->scaffSize *= 2;
+    }
+    else {
+      temp = (CONTENT_SCAFFOLD *)MALLOC(INIT_SCAFFOLD_ELEMENTS
+                                        * sizeof(CONTENT_SCAFFOLD));
+      if (temp == NULL)
+        return -1;
+      dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS;
+    }
+    dtd->scaffold = temp;
+  }
+  next = dtd->scaffCount++;
+  me = &dtd->scaffold[next];
+  if (dtd->scaffLevel) {
+    CONTENT_SCAFFOLD *parent = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel-1]];
+    if (parent->lastchild) {
+      dtd->scaffold[parent->lastchild].nextsib = next;
+    }
+    if (!parent->childcnt)
+      parent->firstchild = next;
+    parent->lastchild = next;
+    parent->childcnt++;
+  }
+  me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;
+  return next;
+}
+
+static void
+build_node(XML_Parser parser,
+           int src_node,
+           XML_Content *dest,
+           XML_Content **contpos,
+           XML_Char **strpos)
+{
+  DTD * const dtd = _dtd;  /* save one level of indirection */
+  dest->type = dtd->scaffold[src_node].type;
+  dest->quant = dtd->scaffold[src_node].quant;
+  if (dest->type == XML_CTYPE_NAME) {
+    const XML_Char *src;
+    dest->name = *strpos;
+    src = dtd->scaffold[src_node].name;
+    for (;;) {
+      *(*strpos)++ = *src;
+      if (!*src)
+        break;
+      src++;
+    }
+    dest->numchildren = 0;
+    dest->children = NULL;
+  }
+  else {
+    unsigned int i;
+    int cn;
+    dest->numchildren = dtd->scaffold[src_node].childcnt;
+    dest->children = *contpos;
+    *contpos += dest->numchildren;
+    for (i = 0, cn = dtd->scaffold[src_node].firstchild;
+         i < dest->numchildren;
+         i++, cn = dtd->scaffold[cn].nextsib) {
+      build_node(parser, cn, &(dest->children[i]), contpos, strpos);
+    }
+    dest->name = NULL;
+  }
+}
+
+static XML_Content *
+build_model (XML_Parser parser)
+{
+  DTD * const dtd = _dtd;  /* save one level of indirection */
+  XML_Content *ret;
+  XML_Content *cpos;
+  XML_Char * str;
+  int allocsize = (dtd->scaffCount * sizeof(XML_Content)
+                   + (dtd->contentStringLen * sizeof(XML_Char)));
+
+  ret = (XML_Content *)MALLOC(allocsize);
+  if (!ret)
+    return NULL;
+
+  str =  (XML_Char *) (&ret[dtd->scaffCount]);
+  cpos = &ret[1];
+
+  build_node(parser, 0, ret, &cpos, &str);
+  return ret;
+}
+
+static ELEMENT_TYPE *
+getElementType(XML_Parser parser,
+               const ENCODING *enc,
+               const char *ptr,
+               const char *end)
+{
+  DTD * const dtd = _dtd;  /* save one level of indirection */
+  const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end);
+  ELEMENT_TYPE *ret;
+
+  if (!name)
+    return NULL;
+  ret = (ELEMENT_TYPE *) lookup(&dtd->elementTypes, name, sizeof(ELEMENT_TYPE));
+  if (!ret)
+    return NULL;
+  if (ret->name != name)
+    poolDiscard(&dtd->pool);
+  else {
+    poolFinish(&dtd->pool);
+    if (!setElementTypePrefix(parser, ret))
+      return NULL;
+  }
+  return ret;
+}

Added: vendor/Python/current/Modules/expat/xmlrole.c
===================================================================
--- vendor/Python/current/Modules/expat/xmlrole.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/expat/xmlrole.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1330 @@
+/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+   See the file COPYING for copying permission.
+*/
+
+#ifdef COMPILED_FROM_DSP
+#include "winconfig.h"
+#elif defined(MACOS_CLASSIC)
+#include "macconfig.h"
+#elif defined(__amigaos4__)
+#include "amigaconfig.h"
+#else
+#ifdef HAVE_EXPAT_CONFIG_H
+#include <expat_config.h>
+#endif
+#endif /* ndef COMPILED_FROM_DSP */
+
+#include <stddef.h>
+
+#include "expat_external.h"
+#include "internal.h"
+#include "xmlrole.h"
+#include "ascii.h"
+
+/* Doesn't check:
+
+ that ,| are not mixed in a model group
+ content of literals
+
+*/
+
+static const char KW_ANY[] = {
+    ASCII_A, ASCII_N, ASCII_Y, '\0' };
+static const char KW_ATTLIST[] = {
+    ASCII_A, ASCII_T, ASCII_T, ASCII_L, ASCII_I, ASCII_S, ASCII_T, '\0' };
+static const char KW_CDATA[] = {
+    ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
+static const char KW_DOCTYPE[] = {
+    ASCII_D, ASCII_O, ASCII_C, ASCII_T, ASCII_Y, ASCII_P, ASCII_E, '\0' };
+static const char KW_ELEMENT[] = {
+    ASCII_E, ASCII_L, ASCII_E, ASCII_M, ASCII_E, ASCII_N, ASCII_T, '\0' };
+static const char KW_EMPTY[] = {
+    ASCII_E, ASCII_M, ASCII_P, ASCII_T, ASCII_Y, '\0' };
+static const char KW_ENTITIES[] = {
+    ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S,
+    '\0' };
+static const char KW_ENTITY[] = {
+    ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0' };
+static const char KW_FIXED[] = {
+    ASCII_F, ASCII_I, ASCII_X, ASCII_E, ASCII_D, '\0' };
+static const char KW_ID[] = {
+    ASCII_I, ASCII_D, '\0' };
+static const char KW_IDREF[] = {
+    ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0' };
+static const char KW_IDREFS[] = {
+    ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0' };
+static const char KW_IGNORE[] = {
+    ASCII_I, ASCII_G, ASCII_N, ASCII_O, ASCII_R, ASCII_E, '\0' };
+static const char KW_IMPLIED[] = {
+    ASCII_I, ASCII_M, ASCII_P, ASCII_L, ASCII_I, ASCII_E, ASCII_D, '\0' };
+static const char KW_INCLUDE[] = {
+    ASCII_I, ASCII_N, ASCII_C, ASCII_L, ASCII_U, ASCII_D, ASCII_E, '\0' };
+static const char KW_NDATA[] = {
+    ASCII_N, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
+static const char KW_NMTOKEN[] = {
+    ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0' };
+static const char KW_NMTOKENS[] = {
+    ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S,
+    '\0' };
+static const char KW_NOTATION[] =
+    { ASCII_N, ASCII_O, ASCII_T, ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N,
+      '\0' };
+static const char KW_PCDATA[] = {
+    ASCII_P, ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
+static const char KW_PUBLIC[] = {
+    ASCII_P, ASCII_U, ASCII_B, ASCII_L, ASCII_I, ASCII_C, '\0' };
+static const char KW_REQUIRED[] = {
+    ASCII_R, ASCII_E, ASCII_Q, ASCII_U, ASCII_I, ASCII_R, ASCII_E, ASCII_D,
+    '\0' };
+static const char KW_SYSTEM[] = {
+    ASCII_S, ASCII_Y, ASCII_S, ASCII_T, ASCII_E, ASCII_M, '\0' };
+
+#ifndef MIN_BYTES_PER_CHAR
+#define MIN_BYTES_PER_CHAR(enc) ((enc)->minBytesPerChar)
+#endif
+
+#ifdef XML_DTD
+#define setTopLevel(state) \
+  ((state)->handler = ((state)->documentEntity \
+                       ? internalSubset \
+                       : externalSubset1))
+#else /* not XML_DTD */
+#define setTopLevel(state) ((state)->handler = internalSubset)
+#endif /* not XML_DTD */
+
+typedef int PTRCALL PROLOG_HANDLER(PROLOG_STATE *state,
+                                   int tok,
+                                   const char *ptr,
+                                   const char *end,
+                                   const ENCODING *enc);
+
+static PROLOG_HANDLER
+  prolog0, prolog1, prolog2,
+  doctype0, doctype1, doctype2, doctype3, doctype4, doctype5,
+  internalSubset,
+  entity0, entity1, entity2, entity3, entity4, entity5, entity6,
+  entity7, entity8, entity9, entity10,
+  notation0, notation1, notation2, notation3, notation4,
+  attlist0, attlist1, attlist2, attlist3, attlist4, attlist5, attlist6,
+  attlist7, attlist8, attlist9,
+  element0, element1, element2, element3, element4, element5, element6,
+  element7,
+#ifdef XML_DTD
+  externalSubset0, externalSubset1,
+  condSect0, condSect1, condSect2,
+#endif /* XML_DTD */
+  declClose,
+  error;
+
+static int FASTCALL common(PROLOG_STATE *state, int tok);
+
+static int PTRCALL
+prolog0(PROLOG_STATE *state,
+        int tok,
+        const char *ptr,
+        const char *end,
+        const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    state->handler = prolog1;
+    return XML_ROLE_NONE;
+  case XML_TOK_XML_DECL:
+    state->handler = prolog1;
+    return XML_ROLE_XML_DECL;
+  case XML_TOK_PI:
+    state->handler = prolog1;
+    return XML_ROLE_PI;
+  case XML_TOK_COMMENT:
+    state->handler = prolog1;
+    return XML_ROLE_COMMENT;
+  case XML_TOK_BOM:
+    return XML_ROLE_NONE;
+  case XML_TOK_DECL_OPEN:
+    if (!XmlNameMatchesAscii(enc,
+                             ptr + 2 * MIN_BYTES_PER_CHAR(enc),
+                             end,
+                             KW_DOCTYPE))
+      break;
+    state->handler = doctype0;
+    return XML_ROLE_DOCTYPE_NONE;
+  case XML_TOK_INSTANCE_START:
+    state->handler = error;
+    return XML_ROLE_INSTANCE_START;
+  }
+  return common(state, tok);
+}
+
+static int PTRCALL
+prolog1(PROLOG_STATE *state,
+        int tok,
+        const char *ptr,
+        const char *end,
+        const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_PI:
+    return XML_ROLE_PI;
+  case XML_TOK_COMMENT:
+    return XML_ROLE_COMMENT;
+  case XML_TOK_BOM:
+    return XML_ROLE_NONE;
+  case XML_TOK_DECL_OPEN:
+    if (!XmlNameMatchesAscii(enc,
+                             ptr + 2 * MIN_BYTES_PER_CHAR(enc),
+                             end,
+                             KW_DOCTYPE))
+      break;
+    state->handler = doctype0;
+    return XML_ROLE_DOCTYPE_NONE;
+  case XML_TOK_INSTANCE_START:
+    state->handler = error;
+    return XML_ROLE_INSTANCE_START;
+  }
+  return common(state, tok);
+}
+
+static int PTRCALL
+prolog2(PROLOG_STATE *state,
+        int tok,
+        const char *ptr,
+        const char *end,
+        const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_PI:
+    return XML_ROLE_PI;
+  case XML_TOK_COMMENT:
+    return XML_ROLE_COMMENT;
+  case XML_TOK_INSTANCE_START:
+    state->handler = error;
+    return XML_ROLE_INSTANCE_START;
+  }
+  return common(state, tok);
+}
+
+static int PTRCALL
+doctype0(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_DOCTYPE_NONE;
+  case XML_TOK_NAME:
+  case XML_TOK_PREFIXED_NAME:
+    state->handler = doctype1;
+    return XML_ROLE_DOCTYPE_NAME;
+  }
+  return common(state, tok);
+}
+
+static int PTRCALL
+doctype1(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_DOCTYPE_NONE;
+  case XML_TOK_OPEN_BRACKET:
+    state->handler = internalSubset;
+    return XML_ROLE_DOCTYPE_INTERNAL_SUBSET;
+  case XML_TOK_DECL_CLOSE:
+    state->handler = prolog2;
+    return XML_ROLE_DOCTYPE_CLOSE;
+  case XML_TOK_NAME:
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
+      state->handler = doctype3;
+      return XML_ROLE_DOCTYPE_NONE;
+    }
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
+      state->handler = doctype2;
+      return XML_ROLE_DOCTYPE_NONE;
+    }
+    break;
+  }
+  return common(state, tok);
+}
+
+static int PTRCALL
+doctype2(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_DOCTYPE_NONE;
+  case XML_TOK_LITERAL:
+    state->handler = doctype3;
+    return XML_ROLE_DOCTYPE_PUBLIC_ID;
+  }
+  return common(state, tok);
+}
+
+static int PTRCALL
+doctype3(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_DOCTYPE_NONE;
+  case XML_TOK_LITERAL:
+    state->handler = doctype4;
+    return XML_ROLE_DOCTYPE_SYSTEM_ID;
+  }
+  return common(state, tok);
+}
+
+static int PTRCALL
+doctype4(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_DOCTYPE_NONE;
+  case XML_TOK_OPEN_BRACKET:
+    state->handler = internalSubset;
+    return XML_ROLE_DOCTYPE_INTERNAL_SUBSET;
+  case XML_TOK_DECL_CLOSE:
+    state->handler = prolog2;
+    return XML_ROLE_DOCTYPE_CLOSE;
+  }
+  return common(state, tok);
+}
+
+static int PTRCALL
+doctype5(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_DOCTYPE_NONE;
+  case XML_TOK_DECL_CLOSE:
+    state->handler = prolog2;
+    return XML_ROLE_DOCTYPE_CLOSE;
+  }
+  return common(state, tok);
+}
+
+static int PTRCALL
+internalSubset(PROLOG_STATE *state,
+               int tok,
+               const char *ptr,
+               const char *end,
+               const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_DECL_OPEN:
+    if (XmlNameMatchesAscii(enc,
+                            ptr + 2 * MIN_BYTES_PER_CHAR(enc),
+                            end,
+                            KW_ENTITY)) {
+      state->handler = entity0;
+      return XML_ROLE_ENTITY_NONE;
+    }
+    if (XmlNameMatchesAscii(enc,
+                            ptr + 2 * MIN_BYTES_PER_CHAR(enc),
+                            end,
+                            KW_ATTLIST)) {
+      state->handler = attlist0;
+      return XML_ROLE_ATTLIST_NONE;
+    }
+    if (XmlNameMatchesAscii(enc,
+                            ptr + 2 * MIN_BYTES_PER_CHAR(enc),
+                            end,
+                            KW_ELEMENT)) {
+      state->handler = element0;
+      return XML_ROLE_ELEMENT_NONE;
+    }
+    if (XmlNameMatchesAscii(enc,
+                            ptr + 2 * MIN_BYTES_PER_CHAR(enc),
+                            end,
+                            KW_NOTATION)) {
+      state->handler = notation0;
+      return XML_ROLE_NOTATION_NONE;
+    }
+    break;
+  case XML_TOK_PI:
+    return XML_ROLE_PI;
+  case XML_TOK_COMMENT:
+    return XML_ROLE_COMMENT;
+  case XML_TOK_PARAM_ENTITY_REF:
+    return XML_ROLE_PARAM_ENTITY_REF;
+  case XML_TOK_CLOSE_BRACKET:
+    state->handler = doctype5;
+    return XML_ROLE_DOCTYPE_NONE;
+  case XML_TOK_NONE:
+    return XML_ROLE_NONE;
+  }
+  return common(state, tok);
+}
+
+#ifdef XML_DTD
+
+static int PTRCALL
+externalSubset0(PROLOG_STATE *state,
+                int tok,
+                const char *ptr,
+                const char *end,
+                const ENCODING *enc)
+{
+  state->handler = externalSubset1;
+  if (tok == XML_TOK_XML_DECL)
+    return XML_ROLE_TEXT_DECL;
+  return externalSubset1(state, tok, ptr, end, enc);
+}
+
+static int PTRCALL
+externalSubset1(PROLOG_STATE *state,
+                int tok,
+                const char *ptr,
+                const char *end,
+                const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_COND_SECT_OPEN:
+    state->handler = condSect0;
+    return XML_ROLE_NONE;
+  case XML_TOK_COND_SECT_CLOSE:
+    if (state->includeLevel == 0)
+      break;
+    state->includeLevel -= 1;
+    return XML_ROLE_NONE;
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_CLOSE_BRACKET:
+    break;
+  case XML_TOK_NONE:
+    if (state->includeLevel)
+      break;
+    return XML_ROLE_NONE;
+  default:
+    return internalSubset(state, tok, ptr, end, enc);
+  }
+  return common(state, tok);
+}
+
+#endif /* XML_DTD */
+
+static int PTRCALL
+entity0(PROLOG_STATE *state,
+        int tok,
+        const char *ptr,
+        const char *end,
+        const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_ENTITY_NONE;
+  case XML_TOK_PERCENT:
+    state->handler = entity1;
+    return XML_ROLE_ENTITY_NONE;
+  case XML_TOK_NAME:
+    state->handler = entity2;
+    return XML_ROLE_GENERAL_ENTITY_NAME;
+  }
+  return common(state, tok);
+}
+
+static int PTRCALL
+entity1(PROLOG_STATE *state,
+        int tok,
+        const char *ptr,
+        const char *end,
+        const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_ENTITY_NONE;
+  case XML_TOK_NAME:
+    state->handler = entity7;
+    return XML_ROLE_PARAM_ENTITY_NAME;
+  }
+  return common(state, tok);
+}
+
+static int PTRCALL
+entity2(PROLOG_STATE *state,
+        int tok,
+        const char *ptr,
+        const char *end,
+        const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_ENTITY_NONE;
+  case XML_TOK_NAME:
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
+      state->handler = entity4;
+      return XML_ROLE_ENTITY_NONE;
+    }
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
+      state->handler = entity3;
+      return XML_ROLE_ENTITY_NONE;
+    }
+    break;
+  case XML_TOK_LITERAL:
+    state->handler = declClose;
+    state->role_none = XML_ROLE_ENTITY_NONE;
+    return XML_ROLE_ENTITY_VALUE;
+  }
+  return common(state, tok);
+}
+
+static int PTRCALL
+entity3(PROLOG_STATE *state,
+        int tok,
+        const char *ptr,
+        const char *end,
+        const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_ENTITY_NONE;
+  case XML_TOK_LITERAL:
+    state->handler = entity4;
+    return XML_ROLE_ENTITY_PUBLIC_ID;
+  }
+  return common(state, tok);
+}
+
+static int PTRCALL
+entity4(PROLOG_STATE *state,
+        int tok,
+        const char *ptr,
+        const char *end,
+        const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_ENTITY_NONE;
+  case XML_TOK_LITERAL:
+    state->handler = entity5;
+    return XML_ROLE_ENTITY_SYSTEM_ID;
+  }
+  return common(state, tok);
+}
+
+static int PTRCALL
+entity5(PROLOG_STATE *state,
+        int tok,
+        const char *ptr,
+        const char *end,
+        const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_ENTITY_NONE;
+  case XML_TOK_DECL_CLOSE:
+    setTopLevel(state);
+    return XML_ROLE_ENTITY_COMPLETE;
+  case XML_TOK_NAME:
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_NDATA)) {
+      state->handler = entity6;
+      return XML_ROLE_ENTITY_NONE;
+    }
+    break;
+  }
+  return common(state, tok);
+}
+
+static int PTRCALL
+entity6(PROLOG_STATE *state,
+        int tok,
+        const char *ptr,
+        const char *end,
+        const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_ENTITY_NONE;
+  case XML_TOK_NAME:
+    state->handler = declClose;
+    state->role_none = XML_ROLE_ENTITY_NONE;
+    return XML_ROLE_ENTITY_NOTATION_NAME;
+  }
+  return common(state, tok);
+}
+
+static int PTRCALL
+entity7(PROLOG_STATE *state,
+        int tok,
+        const char *ptr,
+        const char *end,
+        const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_ENTITY_NONE;
+  case XML_TOK_NAME:
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
+      state->handler = entity9;
+      return XML_ROLE_ENTITY_NONE;
+    }
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
+      state->handler = entity8;
+      return XML_ROLE_ENTITY_NONE;
+    }
+    break;
+  case XML_TOK_LITERAL:
+    state->handler = declClose;
+    state->role_none = XML_ROLE_ENTITY_NONE;
+    return XML_ROLE_ENTITY_VALUE;
+  }
+  return common(state, tok);
+}
+
+static int PTRCALL
+entity8(PROLOG_STATE *state,
+        int tok,
+        const char *ptr,
+        const char *end,
+        const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_ENTITY_NONE;
+  case XML_TOK_LITERAL:
+    state->handler = entity9;
+    return XML_ROLE_ENTITY_PUBLIC_ID;
+  }
+  return common(state, tok);
+}
+
+static int PTRCALL
+entity9(PROLOG_STATE *state,
+        int tok,
+        const char *ptr,
+        const char *end,
+        const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_ENTITY_NONE;
+  case XML_TOK_LITERAL:
+    state->handler = entity10;
+    return XML_ROLE_ENTITY_SYSTEM_ID;
+  }
+  return common(state, tok);
+}
+
+static int PTRCALL
+entity10(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_ENTITY_NONE;
+  case XML_TOK_DECL_CLOSE:
+    setTopLevel(state);
+    return XML_ROLE_ENTITY_COMPLETE;
+  }
+  return common(state, tok);
+}
+
+static int PTRCALL
+notation0(PROLOG_STATE *state,
+          int tok,
+          const char *ptr,
+          const char *end,
+          const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NOTATION_NONE;
+  case XML_TOK_NAME:
+    state->handler = notation1;
+    return XML_ROLE_NOTATION_NAME;
+  }
+  return common(state, tok);
+}
+
+static int PTRCALL
+notation1(PROLOG_STATE *state,
+          int tok,
+          const char *ptr,
+          const char *end,
+          const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NOTATION_NONE;
+  case XML_TOK_NAME:
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
+      state->handler = notation3;
+      return XML_ROLE_NOTATION_NONE;
+    }
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
+      state->handler = notation2;
+      return XML_ROLE_NOTATION_NONE;
+    }
+    break;
+  }
+  return common(state, tok);
+}
+
+static int PTRCALL
+notation2(PROLOG_STATE *state,
+          int tok,
+          const char *ptr,
+          const char *end,
+          const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NOTATION_NONE;
+  case XML_TOK_LITERAL:
+    state->handler = notation4;
+    return XML_ROLE_NOTATION_PUBLIC_ID;
+  }
+  return common(state, tok);
+}
+
+static int PTRCALL
+notation3(PROLOG_STATE *state,
+          int tok,
+          const char *ptr,
+          const char *end,
+          const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NOTATION_NONE;
+  case XML_TOK_LITERAL:
+    state->handler = declClose;
+    state->role_none = XML_ROLE_NOTATION_NONE;
+    return XML_ROLE_NOTATION_SYSTEM_ID;
+  }
+  return common(state, tok);
+}
+
+static int PTRCALL
+notation4(PROLOG_STATE *state,
+          int tok,
+          const char *ptr,
+          const char *end,
+          const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NOTATION_NONE;
+  case XML_TOK_LITERAL:
+    state->handler = declClose;
+    state->role_none = XML_ROLE_NOTATION_NONE;
+    return XML_ROLE_NOTATION_SYSTEM_ID;
+  case XML_TOK_DECL_CLOSE:
+    setTopLevel(state);
+    return XML_ROLE_NOTATION_NO_SYSTEM_ID;
+  }
+  return common(state, tok);
+}
+
+static int PTRCALL
+attlist0(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_ATTLIST_NONE;
+  case XML_TOK_NAME:
+  case XML_TOK_PREFIXED_NAME:
+    state->handler = attlist1;
+    return XML_ROLE_ATTLIST_ELEMENT_NAME;
+  }
+  return common(state, tok);
+}
+
+static int PTRCALL
+attlist1(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_ATTLIST_NONE;
+  case XML_TOK_DECL_CLOSE:
+    setTopLevel(state);
+    return XML_ROLE_ATTLIST_NONE;
+  case XML_TOK_NAME:
+  case XML_TOK_PREFIXED_NAME:
+    state->handler = attlist2;
+    return XML_ROLE_ATTRIBUTE_NAME;
+  }
+  return common(state, tok);
+}
+
+static int PTRCALL
+attlist2(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_ATTLIST_NONE;
+  case XML_TOK_NAME:
+    {
+      static const char * const types[] = {
+        KW_CDATA,
+        KW_ID,
+        KW_IDREF,
+        KW_IDREFS,
+        KW_ENTITY,
+        KW_ENTITIES,
+        KW_NMTOKEN,
+        KW_NMTOKENS,
+      };
+      int i;
+      for (i = 0; i < (int)(sizeof(types)/sizeof(types[0])); i++)
+        if (XmlNameMatchesAscii(enc, ptr, end, types[i])) {
+          state->handler = attlist8;
+          return XML_ROLE_ATTRIBUTE_TYPE_CDATA + i;
+        }
+    }
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_NOTATION)) {
+      state->handler = attlist5;
+      return XML_ROLE_ATTLIST_NONE;
+    }
+    break;
+  case XML_TOK_OPEN_PAREN:
+    state->handler = attlist3;
+    return XML_ROLE_ATTLIST_NONE;
+  }
+  return common(state, tok);
+}
+
+static int PTRCALL
+attlist3(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_ATTLIST_NONE;
+  case XML_TOK_NMTOKEN:
+  case XML_TOK_NAME:
+  case XML_TOK_PREFIXED_NAME:
+    state->handler = attlist4;
+    return XML_ROLE_ATTRIBUTE_ENUM_VALUE;
+  }
+  return common(state, tok);
+}
+
+static int PTRCALL
+attlist4(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_ATTLIST_NONE;
+  case XML_TOK_CLOSE_PAREN:
+    state->handler = attlist8;
+    return XML_ROLE_ATTLIST_NONE;
+  case XML_TOK_OR:
+    state->handler = attlist3;
+    return XML_ROLE_ATTLIST_NONE;
+  }
+  return common(state, tok);
+}
+
+static int PTRCALL
+attlist5(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_ATTLIST_NONE;
+  case XML_TOK_OPEN_PAREN:
+    state->handler = attlist6;
+    return XML_ROLE_ATTLIST_NONE;
+  }
+  return common(state, tok);
+}
+
+static int PTRCALL
+attlist6(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_ATTLIST_NONE;
+  case XML_TOK_NAME:
+    state->handler = attlist7;
+    return XML_ROLE_ATTRIBUTE_NOTATION_VALUE;
+  }
+  return common(state, tok);
+}
+
+static int PTRCALL
+attlist7(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_ATTLIST_NONE;
+  case XML_TOK_CLOSE_PAREN:
+    state->handler = attlist8;
+    return XML_ROLE_ATTLIST_NONE;
+  case XML_TOK_OR:
+    state->handler = attlist6;
+    return XML_ROLE_ATTLIST_NONE;
+  }
+  return common(state, tok);
+}
+
+/* default value */
+static int PTRCALL
+attlist8(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_ATTLIST_NONE;
+  case XML_TOK_POUND_NAME:
+    if (XmlNameMatchesAscii(enc,
+                            ptr + MIN_BYTES_PER_CHAR(enc),
+                            end,
+                            KW_IMPLIED)) {
+      state->handler = attlist1;
+      return XML_ROLE_IMPLIED_ATTRIBUTE_VALUE;
+    }
+    if (XmlNameMatchesAscii(enc,
+                            ptr + MIN_BYTES_PER_CHAR(enc),
+                            end,
+                            KW_REQUIRED)) {
+      state->handler = attlist1;
+      return XML_ROLE_REQUIRED_ATTRIBUTE_VALUE;
+    }
+    if (XmlNameMatchesAscii(enc,
+                            ptr + MIN_BYTES_PER_CHAR(enc),
+                            end,
+                            KW_FIXED)) {
+      state->handler = attlist9;
+      return XML_ROLE_ATTLIST_NONE;
+    }
+    break;
+  case XML_TOK_LITERAL:
+    state->handler = attlist1;
+    return XML_ROLE_DEFAULT_ATTRIBUTE_VALUE;
+  }
+  return common(state, tok);
+}
+
+static int PTRCALL
+attlist9(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_ATTLIST_NONE;
+  case XML_TOK_LITERAL:
+    state->handler = attlist1;
+    return XML_ROLE_FIXED_ATTRIBUTE_VALUE;
+  }
+  return common(state, tok);
+}
+
+static int PTRCALL
+element0(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_ELEMENT_NONE;
+  case XML_TOK_NAME:
+  case XML_TOK_PREFIXED_NAME:
+    state->handler = element1;
+    return XML_ROLE_ELEMENT_NAME;
+  }
+  return common(state, tok);
+}
+
+static int PTRCALL
+element1(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_ELEMENT_NONE;
+  case XML_TOK_NAME:
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_EMPTY)) {
+      state->handler = declClose;
+      state->role_none = XML_ROLE_ELEMENT_NONE;
+      return XML_ROLE_CONTENT_EMPTY;
+    }
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_ANY)) {
+      state->handler = declClose;
+      state->role_none = XML_ROLE_ELEMENT_NONE;
+      return XML_ROLE_CONTENT_ANY;
+    }
+    break;
+  case XML_TOK_OPEN_PAREN:
+    state->handler = element2;
+    state->level = 1;
+    return XML_ROLE_GROUP_OPEN;
+  }
+  return common(state, tok);
+}
+
+static int PTRCALL
+element2(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_ELEMENT_NONE;
+  case XML_TOK_POUND_NAME:
+    if (XmlNameMatchesAscii(enc,
+                            ptr + MIN_BYTES_PER_CHAR(enc),
+                            end,
+                            KW_PCDATA)) {
+      state->handler = element3;
+      return XML_ROLE_CONTENT_PCDATA;
+    }
+    break;
+  case XML_TOK_OPEN_PAREN:
+    state->level = 2;
+    state->handler = element6;
+    return XML_ROLE_GROUP_OPEN;
+  case XML_TOK_NAME:
+  case XML_TOK_PREFIXED_NAME:
+    state->handler = element7;
+    return XML_ROLE_CONTENT_ELEMENT;
+  case XML_TOK_NAME_QUESTION:
+    state->handler = element7;
+    return XML_ROLE_CONTENT_ELEMENT_OPT;
+  case XML_TOK_NAME_ASTERISK:
+    state->handler = element7;
+    return XML_ROLE_CONTENT_ELEMENT_REP;
+  case XML_TOK_NAME_PLUS:
+    state->handler = element7;
+    return XML_ROLE_CONTENT_ELEMENT_PLUS;
+  }
+  return common(state, tok);
+}
+
+static int PTRCALL
+element3(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_ELEMENT_NONE;
+  case XML_TOK_CLOSE_PAREN:
+    state->handler = declClose;
+    state->role_none = XML_ROLE_ELEMENT_NONE;
+    return XML_ROLE_GROUP_CLOSE;
+  case XML_TOK_CLOSE_PAREN_ASTERISK:
+    state->handler = declClose;
+    state->role_none = XML_ROLE_ELEMENT_NONE;
+    return XML_ROLE_GROUP_CLOSE_REP;
+  case XML_TOK_OR:
+    state->handler = element4;
+    return XML_ROLE_ELEMENT_NONE;
+  }
+  return common(state, tok);
+}
+
+static int PTRCALL
+element4(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_ELEMENT_NONE;
+  case XML_TOK_NAME:
+  case XML_TOK_PREFIXED_NAME:
+    state->handler = element5;
+    return XML_ROLE_CONTENT_ELEMENT;
+  }
+  return common(state, tok);
+}
+
+static int PTRCALL
+element5(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_ELEMENT_NONE;
+  case XML_TOK_CLOSE_PAREN_ASTERISK:
+    state->handler = declClose;
+    state->role_none = XML_ROLE_ELEMENT_NONE;
+    return XML_ROLE_GROUP_CLOSE_REP;
+  case XML_TOK_OR:
+    state->handler = element4;
+    return XML_ROLE_ELEMENT_NONE;
+  }
+  return common(state, tok);
+}
+
+static int PTRCALL
+element6(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_ELEMENT_NONE;
+  case XML_TOK_OPEN_PAREN:
+    state->level += 1;
+    return XML_ROLE_GROUP_OPEN;
+  case XML_TOK_NAME:
+  case XML_TOK_PREFIXED_NAME:
+    state->handler = element7;
+    return XML_ROLE_CONTENT_ELEMENT;
+  case XML_TOK_NAME_QUESTION:
+    state->handler = element7;
+    return XML_ROLE_CONTENT_ELEMENT_OPT;
+  case XML_TOK_NAME_ASTERISK:
+    state->handler = element7;
+    return XML_ROLE_CONTENT_ELEMENT_REP;
+  case XML_TOK_NAME_PLUS:
+    state->handler = element7;
+    return XML_ROLE_CONTENT_ELEMENT_PLUS;
+  }
+  return common(state, tok);
+}
+
+static int PTRCALL
+element7(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_ELEMENT_NONE;
+  case XML_TOK_CLOSE_PAREN:
+    state->level -= 1;
+    if (state->level == 0) {
+      state->handler = declClose;
+      state->role_none = XML_ROLE_ELEMENT_NONE;
+    }
+    return XML_ROLE_GROUP_CLOSE;
+  case XML_TOK_CLOSE_PAREN_ASTERISK:
+    state->level -= 1;
+    if (state->level == 0) {
+      state->handler = declClose;
+      state->role_none = XML_ROLE_ELEMENT_NONE;
+    }
+    return XML_ROLE_GROUP_CLOSE_REP;
+  case XML_TOK_CLOSE_PAREN_QUESTION:
+    state->level -= 1;
+    if (state->level == 0) {
+      state->handler = declClose;
+      state->role_none = XML_ROLE_ELEMENT_NONE;
+    }
+    return XML_ROLE_GROUP_CLOSE_OPT;
+  case XML_TOK_CLOSE_PAREN_PLUS:
+    state->level -= 1;
+    if (state->level == 0) {
+      state->handler = declClose;
+      state->role_none = XML_ROLE_ELEMENT_NONE;
+    }
+    return XML_ROLE_GROUP_CLOSE_PLUS;
+  case XML_TOK_COMMA:
+    state->handler = element6;
+    return XML_ROLE_GROUP_SEQUENCE;
+  case XML_TOK_OR:
+    state->handler = element6;
+    return XML_ROLE_GROUP_CHOICE;
+  }
+  return common(state, tok);
+}
+
+#ifdef XML_DTD
+
+static int PTRCALL
+condSect0(PROLOG_STATE *state,
+          int tok,
+          const char *ptr,
+          const char *end,
+          const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_NAME:
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_INCLUDE)) {
+      state->handler = condSect1;
+      return XML_ROLE_NONE;
+    }
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_IGNORE)) {
+      state->handler = condSect2;
+      return XML_ROLE_NONE;
+    }
+    break;
+  }
+  return common(state, tok);
+}
+
+static int PTRCALL
+condSect1(PROLOG_STATE *state,
+          int tok,
+          const char *ptr,
+          const char *end,
+          const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_OPEN_BRACKET:
+    state->handler = externalSubset1;
+    state->includeLevel += 1;
+    return XML_ROLE_NONE;
+  }
+  return common(state, tok);
+}
+
+static int PTRCALL
+condSect2(PROLOG_STATE *state,
+          int tok,
+          const char *ptr,
+          const char *end,
+          const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_OPEN_BRACKET:
+    state->handler = externalSubset1;
+    return XML_ROLE_IGNORE_SECT;
+  }
+  return common(state, tok);
+}
+
+#endif /* XML_DTD */
+
+static int PTRCALL
+declClose(PROLOG_STATE *state,
+          int tok,
+          const char *ptr,
+          const char *end,
+          const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return state->role_none;
+  case XML_TOK_DECL_CLOSE:
+    setTopLevel(state);
+    return state->role_none;
+  }
+  return common(state, tok);
+}
+
+static int PTRCALL
+error(PROLOG_STATE *state,
+      int tok,
+      const char *ptr,
+      const char *end,
+      const ENCODING *enc)
+{
+  return XML_ROLE_NONE;
+}
+
+static int FASTCALL
+common(PROLOG_STATE *state, int tok)
+{
+#ifdef XML_DTD
+  if (!state->documentEntity && tok == XML_TOK_PARAM_ENTITY_REF)
+    return XML_ROLE_INNER_PARAM_ENTITY_REF;
+#endif
+  state->handler = error;
+  return XML_ROLE_ERROR;
+}
+
+void
+XmlPrologStateInit(PROLOG_STATE *state)
+{
+  state->handler = prolog0;
+#ifdef XML_DTD
+  state->documentEntity = 1;
+  state->includeLevel = 0;
+  state->inEntityValue = 0;
+#endif /* XML_DTD */
+}
+
+#ifdef XML_DTD
+
+void
+XmlPrologStateInitExternalEntity(PROLOG_STATE *state)
+{
+  state->handler = externalSubset0;
+  state->documentEntity = 0;
+  state->includeLevel = 0;
+}
+
+#endif /* XML_DTD */

Added: vendor/Python/current/Modules/expat/xmlrole.h
===================================================================
--- vendor/Python/current/Modules/expat/xmlrole.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/expat/xmlrole.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,114 @@
+/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+   See the file COPYING for copying permission.
+*/
+
+#ifndef XmlRole_INCLUDED
+#define XmlRole_INCLUDED 1
+
+#ifdef __VMS
+/*      0        1         2         3      0        1         2         3
+        1234567890123456789012345678901     1234567890123456789012345678901 */
+#define XmlPrologStateInitExternalEntity    XmlPrologStateInitExternalEnt
+#endif
+
+#include "xmltok.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum {
+  XML_ROLE_ERROR = -1,
+  XML_ROLE_NONE = 0,
+  XML_ROLE_XML_DECL,
+  XML_ROLE_INSTANCE_START,
+  XML_ROLE_DOCTYPE_NONE,
+  XML_ROLE_DOCTYPE_NAME,
+  XML_ROLE_DOCTYPE_SYSTEM_ID,
+  XML_ROLE_DOCTYPE_PUBLIC_ID,
+  XML_ROLE_DOCTYPE_INTERNAL_SUBSET,
+  XML_ROLE_DOCTYPE_CLOSE,
+  XML_ROLE_GENERAL_ENTITY_NAME,
+  XML_ROLE_PARAM_ENTITY_NAME,
+  XML_ROLE_ENTITY_NONE,
+  XML_ROLE_ENTITY_VALUE,
+  XML_ROLE_ENTITY_SYSTEM_ID,
+  XML_ROLE_ENTITY_PUBLIC_ID,
+  XML_ROLE_ENTITY_COMPLETE,
+  XML_ROLE_ENTITY_NOTATION_NAME,
+  XML_ROLE_NOTATION_NONE,
+  XML_ROLE_NOTATION_NAME,
+  XML_ROLE_NOTATION_SYSTEM_ID,
+  XML_ROLE_NOTATION_NO_SYSTEM_ID,
+  XML_ROLE_NOTATION_PUBLIC_ID,
+  XML_ROLE_ATTRIBUTE_NAME,
+  XML_ROLE_ATTRIBUTE_TYPE_CDATA,
+  XML_ROLE_ATTRIBUTE_TYPE_ID,
+  XML_ROLE_ATTRIBUTE_TYPE_IDREF,
+  XML_ROLE_ATTRIBUTE_TYPE_IDREFS,
+  XML_ROLE_ATTRIBUTE_TYPE_ENTITY,
+  XML_ROLE_ATTRIBUTE_TYPE_ENTITIES,
+  XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN,
+  XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS,
+  XML_ROLE_ATTRIBUTE_ENUM_VALUE,
+  XML_ROLE_ATTRIBUTE_NOTATION_VALUE,
+  XML_ROLE_ATTLIST_NONE,
+  XML_ROLE_ATTLIST_ELEMENT_NAME,
+  XML_ROLE_IMPLIED_ATTRIBUTE_VALUE,
+  XML_ROLE_REQUIRED_ATTRIBUTE_VALUE,
+  XML_ROLE_DEFAULT_ATTRIBUTE_VALUE,
+  XML_ROLE_FIXED_ATTRIBUTE_VALUE,
+  XML_ROLE_ELEMENT_NONE,
+  XML_ROLE_ELEMENT_NAME,
+  XML_ROLE_CONTENT_ANY,
+  XML_ROLE_CONTENT_EMPTY,
+  XML_ROLE_CONTENT_PCDATA,
+  XML_ROLE_GROUP_OPEN,
+  XML_ROLE_GROUP_CLOSE,
+  XML_ROLE_GROUP_CLOSE_REP,
+  XML_ROLE_GROUP_CLOSE_OPT,
+  XML_ROLE_GROUP_CLOSE_PLUS,
+  XML_ROLE_GROUP_CHOICE,
+  XML_ROLE_GROUP_SEQUENCE,
+  XML_ROLE_CONTENT_ELEMENT,
+  XML_ROLE_CONTENT_ELEMENT_REP,
+  XML_ROLE_CONTENT_ELEMENT_OPT,
+  XML_ROLE_CONTENT_ELEMENT_PLUS,
+  XML_ROLE_PI,
+  XML_ROLE_COMMENT,
+#ifdef XML_DTD
+  XML_ROLE_TEXT_DECL,
+  XML_ROLE_IGNORE_SECT,
+  XML_ROLE_INNER_PARAM_ENTITY_REF,
+#endif /* XML_DTD */
+  XML_ROLE_PARAM_ENTITY_REF
+};
+
+typedef struct prolog_state {
+  int (PTRCALL *handler) (struct prolog_state *state,
+                          int tok,
+                          const char *ptr,
+                          const char *end,
+                          const ENCODING *enc);
+  unsigned level;
+  int role_none;
+#ifdef XML_DTD
+  unsigned includeLevel;
+  int documentEntity;
+  int inEntityValue;
+#endif /* XML_DTD */
+} PROLOG_STATE;
+
+void XmlPrologStateInit(PROLOG_STATE *);
+#ifdef XML_DTD
+void XmlPrologStateInitExternalEntity(PROLOG_STATE *);
+#endif /* XML_DTD */
+
+#define XmlTokenRole(state, tok, ptr, end, enc) \
+ (((state)->handler)(state, tok, ptr, end, enc))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* not XmlRole_INCLUDED */

Added: vendor/Python/current/Modules/expat/xmltok.c
===================================================================
--- vendor/Python/current/Modules/expat/xmltok.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/expat/xmltok.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1639 @@
+/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+   See the file COPYING for copying permission.
+*/
+
+#ifdef COMPILED_FROM_DSP
+#include "winconfig.h"
+#elif defined(MACOS_CLASSIC)
+#include "macconfig.h"
+#elif defined(__amigaos4__)
+#include "amigaconfig.h"
+#else
+#ifdef HAVE_EXPAT_CONFIG_H
+#include <expat_config.h>
+#endif
+#endif /* ndef COMPILED_FROM_DSP */
+
+#include <stddef.h>
+
+#include "expat_external.h"
+#include "internal.h"
+#include "xmltok.h"
+#include "nametab.h"
+
+#ifdef XML_DTD
+#define IGNORE_SECTION_TOK_VTABLE , PREFIX(ignoreSectionTok)
+#else
+#define IGNORE_SECTION_TOK_VTABLE /* as nothing */
+#endif
+
+#define VTABLE1 \
+  { PREFIX(prologTok), PREFIX(contentTok), \
+    PREFIX(cdataSectionTok) IGNORE_SECTION_TOK_VTABLE }, \
+  { PREFIX(attributeValueTok), PREFIX(entityValueTok) }, \
+  PREFIX(sameName), \
+  PREFIX(nameMatchesAscii), \
+  PREFIX(nameLength), \
+  PREFIX(skipS), \
+  PREFIX(getAtts), \
+  PREFIX(charRefNumber), \
+  PREFIX(predefinedEntityName), \
+  PREFIX(updatePosition), \
+  PREFIX(isPublicId)
+
+#define VTABLE VTABLE1, PREFIX(toUtf8), PREFIX(toUtf16)
+
+#define UCS2_GET_NAMING(pages, hi, lo) \
+   (namingBitmap[(pages[hi] << 3) + ((lo) >> 5)] & (1 << ((lo) & 0x1F)))
+
+/* A 2 byte UTF-8 representation splits the characters 11 bits between
+   the bottom 5 and 6 bits of the bytes.  We need 8 bits to index into
+   pages, 3 bits to add to that index and 5 bits to generate the mask.
+*/
+#define UTF8_GET_NAMING2(pages, byte) \
+    (namingBitmap[((pages)[(((byte)[0]) >> 2) & 7] << 3) \
+                      + ((((byte)[0]) & 3) << 1) \
+                      + ((((byte)[1]) >> 5) & 1)] \
+         & (1 << (((byte)[1]) & 0x1F)))
+
+/* A 3 byte UTF-8 representation splits the characters 16 bits between
+   the bottom 4, 6 and 6 bits of the bytes.  We need 8 bits to index
+   into pages, 3 bits to add to that index and 5 bits to generate the
+   mask.
+*/
+#define UTF8_GET_NAMING3(pages, byte) \
+  (namingBitmap[((pages)[((((byte)[0]) & 0xF) << 4) \
+                             + ((((byte)[1]) >> 2) & 0xF)] \
+                       << 3) \
+                      + ((((byte)[1]) & 3) << 1) \
+                      + ((((byte)[2]) >> 5) & 1)] \
+         & (1 << (((byte)[2]) & 0x1F)))
+
+#define UTF8_GET_NAMING(pages, p, n) \
+  ((n) == 2 \
+  ? UTF8_GET_NAMING2(pages, (const unsigned char *)(p)) \
+  : ((n) == 3 \
+     ? UTF8_GET_NAMING3(pages, (const unsigned char *)(p)) \
+     : 0))
+
+/* Detection of invalid UTF-8 sequences is based on Table 3.1B
+   of Unicode 3.2: http://www.unicode.org/unicode/reports/tr28/
+   with the additional restriction of not allowing the Unicode
+   code points 0xFFFF and 0xFFFE (sequences EF,BF,BF and EF,BF,BE).
+   Implementation details:
+     (A & 0x80) == 0     means A < 0x80
+   and
+     (A & 0xC0) == 0xC0  means A > 0xBF
+*/
+
+#define UTF8_INVALID2(p) \
+  ((*p) < 0xC2 || ((p)[1] & 0x80) == 0 || ((p)[1] & 0xC0) == 0xC0)
+
+#define UTF8_INVALID3(p) \
+  (((p)[2] & 0x80) == 0 \
+  || \
+  ((*p) == 0xEF && (p)[1] == 0xBF \
+    ? \
+    (p)[2] > 0xBD \
+    : \
+    ((p)[2] & 0xC0) == 0xC0) \
+  || \
+  ((*p) == 0xE0 \
+    ? \
+    (p)[1] < 0xA0 || ((p)[1] & 0xC0) == 0xC0 \
+    : \
+    ((p)[1] & 0x80) == 0 \
+    || \
+    ((*p) == 0xED ? (p)[1] > 0x9F : ((p)[1] & 0xC0) == 0xC0)))
+
+#define UTF8_INVALID4(p) \
+  (((p)[3] & 0x80) == 0 || ((p)[3] & 0xC0) == 0xC0 \
+  || \
+  ((p)[2] & 0x80) == 0 || ((p)[2] & 0xC0) == 0xC0 \
+  || \
+  ((*p) == 0xF0 \
+    ? \
+    (p)[1] < 0x90 || ((p)[1] & 0xC0) == 0xC0 \
+    : \
+    ((p)[1] & 0x80) == 0 \
+    || \
+    ((*p) == 0xF4 ? (p)[1] > 0x8F : ((p)[1] & 0xC0) == 0xC0)))
+
+static int PTRFASTCALL
+isNever(const ENCODING *enc, const char *p)
+{
+  return 0;
+}
+
+static int PTRFASTCALL
+utf8_isName2(const ENCODING *enc, const char *p)
+{
+  return UTF8_GET_NAMING2(namePages, (const unsigned char *)p);
+}
+
+static int PTRFASTCALL
+utf8_isName3(const ENCODING *enc, const char *p)
+{
+  return UTF8_GET_NAMING3(namePages, (const unsigned char *)p);
+}
+
+#define utf8_isName4 isNever
+
+static int PTRFASTCALL
+utf8_isNmstrt2(const ENCODING *enc, const char *p)
+{
+  return UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)p);
+}
+
+static int PTRFASTCALL
+utf8_isNmstrt3(const ENCODING *enc, const char *p)
+{
+  return UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)p);
+}
+
+#define utf8_isNmstrt4 isNever
+
+static int PTRFASTCALL
+utf8_isInvalid2(const ENCODING *enc, const char *p)
+{
+  return UTF8_INVALID2((const unsigned char *)p);
+}
+
+static int PTRFASTCALL
+utf8_isInvalid3(const ENCODING *enc, const char *p)
+{
+  return UTF8_INVALID3((const unsigned char *)p);
+}
+
+static int PTRFASTCALL
+utf8_isInvalid4(const ENCODING *enc, const char *p)
+{
+  return UTF8_INVALID4((const unsigned char *)p);
+}
+
+struct normal_encoding {
+  ENCODING enc;
+  unsigned char type[256];
+#ifdef XML_MIN_SIZE
+  int (PTRFASTCALL *byteType)(const ENCODING *, const char *);
+  int (PTRFASTCALL *isNameMin)(const ENCODING *, const char *);
+  int (PTRFASTCALL *isNmstrtMin)(const ENCODING *, const char *);
+  int (PTRFASTCALL *byteToAscii)(const ENCODING *, const char *);
+  int (PTRCALL *charMatches)(const ENCODING *, const char *, int);
+#endif /* XML_MIN_SIZE */
+  int (PTRFASTCALL *isName2)(const ENCODING *, const char *);
+  int (PTRFASTCALL *isName3)(const ENCODING *, const char *);
+  int (PTRFASTCALL *isName4)(const ENCODING *, const char *);
+  int (PTRFASTCALL *isNmstrt2)(const ENCODING *, const char *);
+  int (PTRFASTCALL *isNmstrt3)(const ENCODING *, const char *);
+  int (PTRFASTCALL *isNmstrt4)(const ENCODING *, const char *);
+  int (PTRFASTCALL *isInvalid2)(const ENCODING *, const char *);
+  int (PTRFASTCALL *isInvalid3)(const ENCODING *, const char *);
+  int (PTRFASTCALL *isInvalid4)(const ENCODING *, const char *);
+};
+
+#define AS_NORMAL_ENCODING(enc)   ((const struct normal_encoding *) (enc))
+
+#ifdef XML_MIN_SIZE
+
+#define STANDARD_VTABLE(E) \
+ E ## byteType, \
+ E ## isNameMin, \
+ E ## isNmstrtMin, \
+ E ## byteToAscii, \
+ E ## charMatches,
+
+#else
+
+#define STANDARD_VTABLE(E) /* as nothing */
+
+#endif
+
+#define NORMAL_VTABLE(E) \
+ E ## isName2, \
+ E ## isName3, \
+ E ## isName4, \
+ E ## isNmstrt2, \
+ E ## isNmstrt3, \
+ E ## isNmstrt4, \
+ E ## isInvalid2, \
+ E ## isInvalid3, \
+ E ## isInvalid4
+
+static int FASTCALL checkCharRefNumber(int);
+
+#include "xmltok_impl.h"
+#include "ascii.h"
+
+#ifdef XML_MIN_SIZE
+#define sb_isNameMin isNever
+#define sb_isNmstrtMin isNever
+#endif
+
+#ifdef XML_MIN_SIZE
+#define MINBPC(enc) ((enc)->minBytesPerChar)
+#else
+/* minimum bytes per character */
+#define MINBPC(enc) 1
+#endif
+
+#define SB_BYTE_TYPE(enc, p) \
+  (((struct normal_encoding *)(enc))->type[(unsigned char)*(p)])
+
+#ifdef XML_MIN_SIZE
+static int PTRFASTCALL
+sb_byteType(const ENCODING *enc, const char *p)
+{
+  return SB_BYTE_TYPE(enc, p);
+}
+#define BYTE_TYPE(enc, p) \
+ (AS_NORMAL_ENCODING(enc)->byteType(enc, p))
+#else
+#define BYTE_TYPE(enc, p) SB_BYTE_TYPE(enc, p)
+#endif
+
+#ifdef XML_MIN_SIZE
+#define BYTE_TO_ASCII(enc, p) \
+ (AS_NORMAL_ENCODING(enc)->byteToAscii(enc, p))
+static int PTRFASTCALL
+sb_byteToAscii(const ENCODING *enc, const char *p)
+{
+  return *p;
+}
+#else
+#define BYTE_TO_ASCII(enc, p) (*(p))
+#endif
+
+#define IS_NAME_CHAR(enc, p, n) \
+ (AS_NORMAL_ENCODING(enc)->isName ## n(enc, p))
+#define IS_NMSTRT_CHAR(enc, p, n) \
+ (AS_NORMAL_ENCODING(enc)->isNmstrt ## n(enc, p))
+#define IS_INVALID_CHAR(enc, p, n) \
+ (AS_NORMAL_ENCODING(enc)->isInvalid ## n(enc, p))
+
+#ifdef XML_MIN_SIZE
+#define IS_NAME_CHAR_MINBPC(enc, p) \
+ (AS_NORMAL_ENCODING(enc)->isNameMin(enc, p))
+#define IS_NMSTRT_CHAR_MINBPC(enc, p) \
+ (AS_NORMAL_ENCODING(enc)->isNmstrtMin(enc, p))
+#else
+#define IS_NAME_CHAR_MINBPC(enc, p) (0)
+#define IS_NMSTRT_CHAR_MINBPC(enc, p) (0)
+#endif
+
+#ifdef XML_MIN_SIZE
+#define CHAR_MATCHES(enc, p, c) \
+ (AS_NORMAL_ENCODING(enc)->charMatches(enc, p, c))
+static int PTRCALL
+sb_charMatches(const ENCODING *enc, const char *p, int c)
+{
+  return *p == c;
+}
+#else
+/* c is an ASCII character */
+#define CHAR_MATCHES(enc, p, c) (*(p) == c)
+#endif
+
+#define PREFIX(ident) normal_ ## ident
+#include "xmltok_impl.c"
+
+#undef MINBPC
+#undef BYTE_TYPE
+#undef BYTE_TO_ASCII
+#undef CHAR_MATCHES
+#undef IS_NAME_CHAR
+#undef IS_NAME_CHAR_MINBPC
+#undef IS_NMSTRT_CHAR
+#undef IS_NMSTRT_CHAR_MINBPC
+#undef IS_INVALID_CHAR
+
+enum {  /* UTF8_cvalN is value of masked first byte of N byte sequence */
+  UTF8_cval1 = 0x00,
+  UTF8_cval2 = 0xc0,
+  UTF8_cval3 = 0xe0,
+  UTF8_cval4 = 0xf0
+};
+
+static void PTRCALL
+utf8_toUtf8(const ENCODING *enc,
+            const char **fromP, const char *fromLim,
+            char **toP, const char *toLim)
+{
+  char *to;
+  const char *from;
+  if (fromLim - *fromP > toLim - *toP) {
+    /* Avoid copying partial characters. */
+    for (fromLim = *fromP + (toLim - *toP); fromLim > *fromP; fromLim--)
+      if (((unsigned char)fromLim[-1] & 0xc0) != 0x80)
+        break;
+  }
+  for (to = *toP, from = *fromP; from != fromLim; from++, to++)
+    *to = *from;
+  *fromP = from;
+  *toP = to;
+}
+
+static void PTRCALL
+utf8_toUtf16(const ENCODING *enc,
+             const char **fromP, const char *fromLim,
+             unsigned short **toP, const unsigned short *toLim)
+{
+  unsigned short *to = *toP;
+  const char *from = *fromP;
+  while (from != fromLim && to != toLim) {
+    switch (((struct normal_encoding *)enc)->type[(unsigned char)*from]) {
+    case BT_LEAD2:
+      *to++ = (unsigned short)(((from[0] & 0x1f) << 6) | (from[1] & 0x3f));
+      from += 2;
+      break;
+    case BT_LEAD3:
+      *to++ = (unsigned short)(((from[0] & 0xf) << 12)
+                               | ((from[1] & 0x3f) << 6) | (from[2] & 0x3f));
+      from += 3;
+      break;
+    case BT_LEAD4:
+      {
+        unsigned long n;
+        if (to + 1 == toLim)
+          goto after;
+        n = ((from[0] & 0x7) << 18) | ((from[1] & 0x3f) << 12)
+            | ((from[2] & 0x3f) << 6) | (from[3] & 0x3f);
+        n -= 0x10000;
+        to[0] = (unsigned short)((n >> 10) | 0xD800);
+        to[1] = (unsigned short)((n & 0x3FF) | 0xDC00);
+        to += 2;
+        from += 4;
+      }
+      break;
+    default:
+      *to++ = *from++;
+      break;
+    }
+  }
+after:
+  *fromP = from;
+  *toP = to;
+}
+
+#ifdef XML_NS
+static const struct normal_encoding utf8_encoding_ns = {
+  { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
+  {
+#include "asciitab.h"
+#include "utf8tab.h"
+  },
+  STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
+};
+#endif
+
+static const struct normal_encoding utf8_encoding = {
+  { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
+  {
+#define BT_COLON BT_NMSTRT
+#include "asciitab.h"
+#undef BT_COLON
+#include "utf8tab.h"
+  },
+  STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
+};
+
+#ifdef XML_NS
+
+static const struct normal_encoding internal_utf8_encoding_ns = {
+  { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
+  {
+#include "iasciitab.h"
+#include "utf8tab.h"
+  },
+  STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
+};
+
+#endif
+
+static const struct normal_encoding internal_utf8_encoding = {
+  { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
+  {
+#define BT_COLON BT_NMSTRT
+#include "iasciitab.h"
+#undef BT_COLON
+#include "utf8tab.h"
+  },
+  STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
+};
+
+static void PTRCALL
+latin1_toUtf8(const ENCODING *enc,
+              const char **fromP, const char *fromLim,
+              char **toP, const char *toLim)
+{
+  for (;;) {
+    unsigned char c;
+    if (*fromP == fromLim)
+      break;
+    c = (unsigned char)**fromP;
+    if (c & 0x80) {
+      if (toLim - *toP < 2)
+        break;
+      *(*toP)++ = (char)((c >> 6) | UTF8_cval2);
+      *(*toP)++ = (char)((c & 0x3f) | 0x80);
+      (*fromP)++;
+    }
+    else {
+      if (*toP == toLim)
+        break;
+      *(*toP)++ = *(*fromP)++;
+    }
+  }
+}
+
+static void PTRCALL
+latin1_toUtf16(const ENCODING *enc,
+               const char **fromP, const char *fromLim,
+               unsigned short **toP, const unsigned short *toLim)
+{
+  while (*fromP != fromLim && *toP != toLim)
+    *(*toP)++ = (unsigned char)*(*fromP)++;
+}
+
+#ifdef XML_NS
+
+static const struct normal_encoding latin1_encoding_ns = {
+  { VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 },
+  {
+#include "asciitab.h"
+#include "latin1tab.h"
+  },
+  STANDARD_VTABLE(sb_)
+};
+
+#endif
+
+static const struct normal_encoding latin1_encoding = {
+  { VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 },
+  {
+#define BT_COLON BT_NMSTRT
+#include "asciitab.h"
+#undef BT_COLON
+#include "latin1tab.h"
+  },
+  STANDARD_VTABLE(sb_)
+};
+
+static void PTRCALL
+ascii_toUtf8(const ENCODING *enc,
+             const char **fromP, const char *fromLim,
+             char **toP, const char *toLim)
+{
+  while (*fromP != fromLim && *toP != toLim)
+    *(*toP)++ = *(*fromP)++;
+}
+
+#ifdef XML_NS
+
+static const struct normal_encoding ascii_encoding_ns = {
+  { VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 },
+  {
+#include "asciitab.h"
+/* BT_NONXML == 0 */
+  },
+  STANDARD_VTABLE(sb_)
+};
+
+#endif
+
+static const struct normal_encoding ascii_encoding = {
+  { VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 },
+  {
+#define BT_COLON BT_NMSTRT
+#include "asciitab.h"
+#undef BT_COLON
+/* BT_NONXML == 0 */
+  },
+  STANDARD_VTABLE(sb_)
+};
+
+static int PTRFASTCALL
+unicode_byte_type(char hi, char lo)
+{
+  switch ((unsigned char)hi) {
+  case 0xD8: case 0xD9: case 0xDA: case 0xDB:
+    return BT_LEAD4;
+  case 0xDC: case 0xDD: case 0xDE: case 0xDF:
+    return BT_TRAIL;
+  case 0xFF:
+    switch ((unsigned char)lo) {
+    case 0xFF:
+    case 0xFE:
+      return BT_NONXML;
+    }
+    break;
+  }
+  return BT_NONASCII;
+}
+
+#define DEFINE_UTF16_TO_UTF8(E) \
+static void  PTRCALL \
+E ## toUtf8(const ENCODING *enc, \
+            const char **fromP, const char *fromLim, \
+            char **toP, const char *toLim) \
+{ \
+  const char *from; \
+  for (from = *fromP; from != fromLim; from += 2) { \
+    int plane; \
+    unsigned char lo2; \
+    unsigned char lo = GET_LO(from); \
+    unsigned char hi = GET_HI(from); \
+    switch (hi) { \
+    case 0: \
+      if (lo < 0x80) { \
+        if (*toP == toLim) { \
+          *fromP = from; \
+          return; \
+        } \
+        *(*toP)++ = lo; \
+        break; \
+      } \
+      /* fall through */ \
+    case 0x1: case 0x2: case 0x3: \
+    case 0x4: case 0x5: case 0x6: case 0x7: \
+      if (toLim -  *toP < 2) { \
+        *fromP = from; \
+        return; \
+      } \
+      *(*toP)++ = ((lo >> 6) | (hi << 2) |  UTF8_cval2); \
+      *(*toP)++ = ((lo & 0x3f) | 0x80); \
+      break; \
+    default: \
+      if (toLim -  *toP < 3)  { \
+        *fromP = from; \
+        return; \
+      } \
+      /* 16 bits divided 4, 6, 6 amongst 3 bytes */ \
+      *(*toP)++ = ((hi >> 4) | UTF8_cval3); \
+      *(*toP)++ = (((hi & 0xf) << 2) | (lo >> 6) | 0x80); \
+      *(*toP)++ = ((lo & 0x3f) | 0x80); \
+      break; \
+    case 0xD8: case 0xD9: case 0xDA: case 0xDB: \
+      if (toLim -  *toP < 4) { \
+        *fromP = from; \
+        return; \
+      } \
+      plane = (((hi & 0x3) << 2) | ((lo >> 6) & 0x3)) + 1; \
+      *(*toP)++ = ((plane >> 2) | UTF8_cval4); \
+      *(*toP)++ = (((lo >> 2) & 0xF) | ((plane & 0x3) << 4) | 0x80); \
+      from += 2; \
+      lo2 = GET_LO(from); \
+      *(*toP)++ = (((lo & 0x3) << 4) \
+                   | ((GET_HI(from) & 0x3) << 2) \
+                   | (lo2 >> 6) \
+                   | 0x80); \
+      *(*toP)++ = ((lo2 & 0x3f) | 0x80); \
+      break; \
+    } \
+  } \
+  *fromP = from; \
+}
+
+#define DEFINE_UTF16_TO_UTF16(E) \
+static void  PTRCALL \
+E ## toUtf16(const ENCODING *enc, \
+             const char **fromP, const char *fromLim, \
+             unsigned short **toP, const unsigned short *toLim) \
+{ \
+  /* Avoid copying first half only of surrogate */ \
+  if (fromLim - *fromP > ((toLim - *toP) << 1) \
+      && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) \
+    fromLim -= 2; \
+  for (; *fromP != fromLim && *toP != toLim; *fromP += 2) \
+    *(*toP)++ = (GET_HI(*fromP) << 8) | GET_LO(*fromP); \
+}
+
+#define SET2(ptr, ch) \
+  (((ptr)[0] = ((ch) & 0xff)), ((ptr)[1] = ((ch) >> 8)))
+#define GET_LO(ptr) ((unsigned char)(ptr)[0])
+#define GET_HI(ptr) ((unsigned char)(ptr)[1])
+
+DEFINE_UTF16_TO_UTF8(little2_)
+DEFINE_UTF16_TO_UTF16(little2_)
+
+#undef SET2
+#undef GET_LO
+#undef GET_HI
+
+#define SET2(ptr, ch) \
+  (((ptr)[0] = ((ch) >> 8)), ((ptr)[1] = ((ch) & 0xFF)))
+#define GET_LO(ptr) ((unsigned char)(ptr)[1])
+#define GET_HI(ptr) ((unsigned char)(ptr)[0])
+
+DEFINE_UTF16_TO_UTF8(big2_)
+DEFINE_UTF16_TO_UTF16(big2_)
+
+#undef SET2
+#undef GET_LO
+#undef GET_HI
+
+#define LITTLE2_BYTE_TYPE(enc, p) \
+ ((p)[1] == 0 \
+  ? ((struct normal_encoding *)(enc))->type[(unsigned char)*(p)] \
+  : unicode_byte_type((p)[1], (p)[0]))
+#define LITTLE2_BYTE_TO_ASCII(enc, p) ((p)[1] == 0 ? (p)[0] : -1)
+#define LITTLE2_CHAR_MATCHES(enc, p, c) ((p)[1] == 0 && (p)[0] == c)
+#define LITTLE2_IS_NAME_CHAR_MINBPC(enc, p) \
+  UCS2_GET_NAMING(namePages, (unsigned char)p[1], (unsigned char)p[0])
+#define LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p) \
+  UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[1], (unsigned char)p[0])
+
+#ifdef XML_MIN_SIZE
+
+static int PTRFASTCALL
+little2_byteType(const ENCODING *enc, const char *p)
+{
+  return LITTLE2_BYTE_TYPE(enc, p);
+}
+
+static int PTRFASTCALL
+little2_byteToAscii(const ENCODING *enc, const char *p)
+{
+  return LITTLE2_BYTE_TO_ASCII(enc, p);
+}
+
+static int PTRCALL
+little2_charMatches(const ENCODING *enc, const char *p, int c)
+{
+  return LITTLE2_CHAR_MATCHES(enc, p, c);
+}
+
+static int PTRFASTCALL
+little2_isNameMin(const ENCODING *enc, const char *p)
+{
+  return LITTLE2_IS_NAME_CHAR_MINBPC(enc, p);
+}
+
+static int PTRFASTCALL
+little2_isNmstrtMin(const ENCODING *enc, const char *p)
+{
+  return LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p);
+}
+
+#undef VTABLE
+#define VTABLE VTABLE1, little2_toUtf8, little2_toUtf16
+
+#else /* not XML_MIN_SIZE */
+
+#undef PREFIX
+#define PREFIX(ident) little2_ ## ident
+#define MINBPC(enc) 2
+/* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */
+#define BYTE_TYPE(enc, p) LITTLE2_BYTE_TYPE(enc, p)
+#define BYTE_TO_ASCII(enc, p) LITTLE2_BYTE_TO_ASCII(enc, p)
+#define CHAR_MATCHES(enc, p, c) LITTLE2_CHAR_MATCHES(enc, p, c)
+#define IS_NAME_CHAR(enc, p, n) 0
+#define IS_NAME_CHAR_MINBPC(enc, p) LITTLE2_IS_NAME_CHAR_MINBPC(enc, p)
+#define IS_NMSTRT_CHAR(enc, p, n) (0)
+#define IS_NMSTRT_CHAR_MINBPC(enc, p) LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p)
+
+#include "xmltok_impl.c"
+
+#undef MINBPC
+#undef BYTE_TYPE
+#undef BYTE_TO_ASCII
+#undef CHAR_MATCHES
+#undef IS_NAME_CHAR
+#undef IS_NAME_CHAR_MINBPC
+#undef IS_NMSTRT_CHAR
+#undef IS_NMSTRT_CHAR_MINBPC
+#undef IS_INVALID_CHAR
+
+#endif /* not XML_MIN_SIZE */
+
+#ifdef XML_NS
+
+static const struct normal_encoding little2_encoding_ns = {
+  { VTABLE, 2, 0,
+#if BYTEORDER == 1234
+    1
+#else
+    0
+#endif
+  },
+  {
+#include "asciitab.h"
+#include "latin1tab.h"
+  },
+  STANDARD_VTABLE(little2_)
+};
+
+#endif
+
+static const struct normal_encoding little2_encoding = {
+  { VTABLE, 2, 0,
+#if BYTEORDER == 1234
+    1
+#else
+    0
+#endif
+  },
+  {
+#define BT_COLON BT_NMSTRT
+#include "asciitab.h"
+#undef BT_COLON
+#include "latin1tab.h"
+  },
+  STANDARD_VTABLE(little2_)
+};
+
+#if BYTEORDER != 4321
+
+#ifdef XML_NS
+
+static const struct normal_encoding internal_little2_encoding_ns = {
+  { VTABLE, 2, 0, 1 },
+  {
+#include "iasciitab.h"
+#include "latin1tab.h"
+  },
+  STANDARD_VTABLE(little2_)
+};
+
+#endif
+
+static const struct normal_encoding internal_little2_encoding = {
+  { VTABLE, 2, 0, 1 },
+  {
+#define BT_COLON BT_NMSTRT
+#include "iasciitab.h"
+#undef BT_COLON
+#include "latin1tab.h"
+  },
+  STANDARD_VTABLE(little2_)
+};
+
+#endif
+
+
+#define BIG2_BYTE_TYPE(enc, p) \
+ ((p)[0] == 0 \
+  ? ((struct normal_encoding *)(enc))->type[(unsigned char)(p)[1]] \
+  : unicode_byte_type((p)[0], (p)[1]))
+#define BIG2_BYTE_TO_ASCII(enc, p) ((p)[0] == 0 ? (p)[1] : -1)
+#define BIG2_CHAR_MATCHES(enc, p, c) ((p)[0] == 0 && (p)[1] == c)
+#define BIG2_IS_NAME_CHAR_MINBPC(enc, p) \
+  UCS2_GET_NAMING(namePages, (unsigned char)p[0], (unsigned char)p[1])
+#define BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p) \
+  UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[0], (unsigned char)p[1])
+
+#ifdef XML_MIN_SIZE
+
+static int PTRFASTCALL
+big2_byteType(const ENCODING *enc, const char *p)
+{
+  return BIG2_BYTE_TYPE(enc, p);
+}
+
+static int PTRFASTCALL
+big2_byteToAscii(const ENCODING *enc, const char *p)
+{
+  return BIG2_BYTE_TO_ASCII(enc, p);
+}
+
+static int PTRCALL
+big2_charMatches(const ENCODING *enc, const char *p, int c)
+{
+  return BIG2_CHAR_MATCHES(enc, p, c);
+}
+
+static int PTRFASTCALL
+big2_isNameMin(const ENCODING *enc, const char *p)
+{
+  return BIG2_IS_NAME_CHAR_MINBPC(enc, p);
+}
+
+static int PTRFASTCALL
+big2_isNmstrtMin(const ENCODING *enc, const char *p)
+{
+  return BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p);
+}
+
+#undef VTABLE
+#define VTABLE VTABLE1, big2_toUtf8, big2_toUtf16
+
+#else /* not XML_MIN_SIZE */
+
+#undef PREFIX
+#define PREFIX(ident) big2_ ## ident
+#define MINBPC(enc) 2
+/* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */
+#define BYTE_TYPE(enc, p) BIG2_BYTE_TYPE(enc, p)
+#define BYTE_TO_ASCII(enc, p) BIG2_BYTE_TO_ASCII(enc, p)
+#define CHAR_MATCHES(enc, p, c) BIG2_CHAR_MATCHES(enc, p, c)
+#define IS_NAME_CHAR(enc, p, n) 0
+#define IS_NAME_CHAR_MINBPC(enc, p) BIG2_IS_NAME_CHAR_MINBPC(enc, p)
+#define IS_NMSTRT_CHAR(enc, p, n) (0)
+#define IS_NMSTRT_CHAR_MINBPC(enc, p) BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p)
+
+#include "xmltok_impl.c"
+
+#undef MINBPC
+#undef BYTE_TYPE
+#undef BYTE_TO_ASCII
+#undef CHAR_MATCHES
+#undef IS_NAME_CHAR
+#undef IS_NAME_CHAR_MINBPC
+#undef IS_NMSTRT_CHAR
+#undef IS_NMSTRT_CHAR_MINBPC
+#undef IS_INVALID_CHAR
+
+#endif /* not XML_MIN_SIZE */
+
+#ifdef XML_NS
+
+static const struct normal_encoding big2_encoding_ns = {
+  { VTABLE, 2, 0,
+#if BYTEORDER == 4321
+  1
+#else
+  0
+#endif
+  },
+  {
+#include "asciitab.h"
+#include "latin1tab.h"
+  },
+  STANDARD_VTABLE(big2_)
+};
+
+#endif
+
+static const struct normal_encoding big2_encoding = {
+  { VTABLE, 2, 0,
+#if BYTEORDER == 4321
+  1
+#else
+  0
+#endif
+  },
+  {
+#define BT_COLON BT_NMSTRT
+#include "asciitab.h"
+#undef BT_COLON
+#include "latin1tab.h"
+  },
+  STANDARD_VTABLE(big2_)
+};
+
+#if BYTEORDER != 1234
+
+#ifdef XML_NS
+
+static const struct normal_encoding internal_big2_encoding_ns = {
+  { VTABLE, 2, 0, 1 },
+  {
+#include "iasciitab.h"
+#include "latin1tab.h"
+  },
+  STANDARD_VTABLE(big2_)
+};
+
+#endif
+
+static const struct normal_encoding internal_big2_encoding = {
+  { VTABLE, 2, 0, 1 },
+  {
+#define BT_COLON BT_NMSTRT
+#include "iasciitab.h"
+#undef BT_COLON
+#include "latin1tab.h"
+  },
+  STANDARD_VTABLE(big2_)
+};
+
+#endif
+
+#undef PREFIX
+
+static int FASTCALL
+streqci(const char *s1, const char *s2)
+{
+  for (;;) {
+    char c1 = *s1++;
+    char c2 = *s2++;
+    if (ASCII_a <= c1 && c1 <= ASCII_z)
+      c1 += ASCII_A - ASCII_a;
+    if (ASCII_a <= c2 && c2 <= ASCII_z)
+      c2 += ASCII_A - ASCII_a;
+    if (c1 != c2)
+      return 0;
+    if (!c1)
+      break;
+  }
+  return 1;
+}
+
+static void PTRCALL
+initUpdatePosition(const ENCODING *enc, const char *ptr,
+                   const char *end, POSITION *pos)
+{
+  normal_updatePosition(&utf8_encoding.enc, ptr, end, pos);
+}
+
+static int
+toAscii(const ENCODING *enc, const char *ptr, const char *end)
+{
+  char buf[1];
+  char *p = buf;
+  XmlUtf8Convert(enc, &ptr, end, &p, p + 1);
+  if (p == buf)
+    return -1;
+  else
+    return buf[0];
+}
+
+static int FASTCALL
+isSpace(int c)
+{
+  switch (c) {
+  case 0x20:
+  case 0xD:
+  case 0xA:
+  case 0x9:
+    return 1;
+  }
+  return 0;
+}
+
+/* Return 1 if there's just optional white space or there's an S
+   followed by name=val.
+*/
+static int
+parsePseudoAttribute(const ENCODING *enc,
+                     const char *ptr,
+                     const char *end,
+                     const char **namePtr,
+                     const char **nameEndPtr,
+                     const char **valPtr,
+                     const char **nextTokPtr)
+{
+  int c;
+  char open;
+  if (ptr == end) {
+    *namePtr = NULL;
+    return 1;
+  }
+  if (!isSpace(toAscii(enc, ptr, end))) {
+    *nextTokPtr = ptr;
+    return 0;
+  }
+  do {
+    ptr += enc->minBytesPerChar;
+  } while (isSpace(toAscii(enc, ptr, end)));
+  if (ptr == end) {
+    *namePtr = NULL;
+    return 1;
+  }
+  *namePtr = ptr;
+  for (;;) {
+    c = toAscii(enc, ptr, end);
+    if (c == -1) {
+      *nextTokPtr = ptr;
+      return 0;
+    }
+    if (c == ASCII_EQUALS) {
+      *nameEndPtr = ptr;
+      break;
+    }
+    if (isSpace(c)) {
+      *nameEndPtr = ptr;
+      do {
+        ptr += enc->minBytesPerChar;
+      } while (isSpace(c = toAscii(enc, ptr, end)));
+      if (c != ASCII_EQUALS) {
+        *nextTokPtr = ptr;
+        return 0;
+      }
+      break;
+    }
+    ptr += enc->minBytesPerChar;
+  }
+  if (ptr == *namePtr) {
+    *nextTokPtr = ptr;
+    return 0;
+  }
+  ptr += enc->minBytesPerChar;
+  c = toAscii(enc, ptr, end);
+  while (isSpace(c)) {
+    ptr += enc->minBytesPerChar;
+    c = toAscii(enc, ptr, end);
+  }
+  if (c != ASCII_QUOT && c != ASCII_APOS) {
+    *nextTokPtr = ptr;
+    return 0;
+  }
+  open = (char)c;
+  ptr += enc->minBytesPerChar;
+  *valPtr = ptr;
+  for (;; ptr += enc->minBytesPerChar) {
+    c = toAscii(enc, ptr, end);
+    if (c == open)
+      break;
+    if (!(ASCII_a <= c && c <= ASCII_z)
+        && !(ASCII_A <= c && c <= ASCII_Z)
+        && !(ASCII_0 <= c && c <= ASCII_9)
+        && c != ASCII_PERIOD
+        && c != ASCII_MINUS
+        && c != ASCII_UNDERSCORE) {
+      *nextTokPtr = ptr;
+      return 0;
+    }
+  }
+  *nextTokPtr = ptr + enc->minBytesPerChar;
+  return 1;
+}
+
+static const char KW_version[] = {
+  ASCII_v, ASCII_e, ASCII_r, ASCII_s, ASCII_i, ASCII_o, ASCII_n, '\0'
+};
+
+static const char KW_encoding[] = {
+  ASCII_e, ASCII_n, ASCII_c, ASCII_o, ASCII_d, ASCII_i, ASCII_n, ASCII_g, '\0'
+};
+
+static const char KW_standalone[] = {
+  ASCII_s, ASCII_t, ASCII_a, ASCII_n, ASCII_d, ASCII_a, ASCII_l, ASCII_o,
+  ASCII_n, ASCII_e, '\0'
+};
+
+static const char KW_yes[] = {
+  ASCII_y, ASCII_e, ASCII_s,  '\0'
+};
+
+static const char KW_no[] = {
+  ASCII_n, ASCII_o,  '\0'
+};
+
+static int
+doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *,
+                                                 const char *,
+                                                 const char *),
+               int isGeneralTextEntity,
+               const ENCODING *enc,
+               const char *ptr,
+               const char *end,
+               const char **badPtr,
+               const char **versionPtr,
+               const char **versionEndPtr,
+               const char **encodingName,
+               const ENCODING **encoding,
+               int *standalone)
+{
+  const char *val = NULL;
+  const char *name = NULL;
+  const char *nameEnd = NULL;
+  ptr += 5 * enc->minBytesPerChar;
+  end -= 2 * enc->minBytesPerChar;
+  if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)
+      || !name) {
+    *badPtr = ptr;
+    return 0;
+  }
+  if (!XmlNameMatchesAscii(enc, name, nameEnd, KW_version)) {
+    if (!isGeneralTextEntity) {
+      *badPtr = name;
+      return 0;
+    }
+  }
+  else {
+    if (versionPtr)
+      *versionPtr = val;
+    if (versionEndPtr)
+      *versionEndPtr = ptr;
+    if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) {
+      *badPtr = ptr;
+      return 0;
+    }
+    if (!name) {
+      if (isGeneralTextEntity) {
+        /* a TextDecl must have an EncodingDecl */
+        *badPtr = ptr;
+        return 0;
+      }
+      return 1;
+    }
+  }
+  if (XmlNameMatchesAscii(enc, name, nameEnd, KW_encoding)) {
+    int c = toAscii(enc, val, end);
+    if (!(ASCII_a <= c && c <= ASCII_z) && !(ASCII_A <= c && c <= ASCII_Z)) {
+      *badPtr = val;
+      return 0;
+    }
+    if (encodingName)
+      *encodingName = val;
+    if (encoding)
+      *encoding = encodingFinder(enc, val, ptr - enc->minBytesPerChar);
+    if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) {
+      *badPtr = ptr;
+      return 0;
+    }
+    if (!name)
+      return 1;
+  }
+  if (!XmlNameMatchesAscii(enc, name, nameEnd, KW_standalone)
+      || isGeneralTextEntity) {
+    *badPtr = name;
+    return 0;
+  }
+  if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_yes)) {
+    if (standalone)
+      *standalone = 1;
+  }
+  else if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_no)) {
+    if (standalone)
+      *standalone = 0;
+  }
+  else {
+    *badPtr = val;
+    return 0;
+  }
+  while (isSpace(toAscii(enc, ptr, end)))
+    ptr += enc->minBytesPerChar;
+  if (ptr != end) {
+    *badPtr = ptr;
+    return 0;
+  }
+  return 1;
+}
+
+static int FASTCALL
+checkCharRefNumber(int result)
+{
+  switch (result >> 8) {
+  case 0xD8: case 0xD9: case 0xDA: case 0xDB:
+  case 0xDC: case 0xDD: case 0xDE: case 0xDF:
+    return -1;
+  case 0:
+    if (latin1_encoding.type[result] == BT_NONXML)
+      return -1;
+    break;
+  case 0xFF:
+    if (result == 0xFFFE || result == 0xFFFF)
+      return -1;
+    break;
+  }
+  return result;
+}
+
+int FASTCALL
+XmlUtf8Encode(int c, char *buf)
+{
+  enum {
+    /* minN is minimum legal resulting value for N byte sequence */
+    min2 = 0x80,
+    min3 = 0x800,
+    min4 = 0x10000
+  };
+
+  if (c < 0)
+    return 0;
+  if (c < min2) {
+    buf[0] = (char)(c | UTF8_cval1);
+    return 1;
+  }
+  if (c < min3) {
+    buf[0] = (char)((c >> 6) | UTF8_cval2);
+    buf[1] = (char)((c & 0x3f) | 0x80);
+    return 2;
+  }
+  if (c < min4) {
+    buf[0] = (char)((c >> 12) | UTF8_cval3);
+    buf[1] = (char)(((c >> 6) & 0x3f) | 0x80);
+    buf[2] = (char)((c & 0x3f) | 0x80);
+    return 3;
+  }
+  if (c < 0x110000) {
+    buf[0] = (char)((c >> 18) | UTF8_cval4);
+    buf[1] = (char)(((c >> 12) & 0x3f) | 0x80);
+    buf[2] = (char)(((c >> 6) & 0x3f) | 0x80);
+    buf[3] = (char)((c & 0x3f) | 0x80);
+    return 4;
+  }
+  return 0;
+}
+
+int FASTCALL
+XmlUtf16Encode(int charNum, unsigned short *buf)
+{
+  if (charNum < 0)
+    return 0;
+  if (charNum < 0x10000) {
+    buf[0] = (unsigned short)charNum;
+    return 1;
+  }
+  if (charNum < 0x110000) {
+    charNum -= 0x10000;
+    buf[0] = (unsigned short)((charNum >> 10) + 0xD800);
+    buf[1] = (unsigned short)((charNum & 0x3FF) + 0xDC00);
+    return 2;
+  }
+  return 0;
+}
+
+struct unknown_encoding {
+  struct normal_encoding normal;
+  CONVERTER convert;
+  void *userData;
+  unsigned short utf16[256];
+  char utf8[256][4];
+};
+
+#define AS_UNKNOWN_ENCODING(enc)  ((const struct unknown_encoding *) (enc))
+
+int
+XmlSizeOfUnknownEncoding(void)
+{
+  return sizeof(struct unknown_encoding);
+}
+
+static int PTRFASTCALL
+unknown_isName(const ENCODING *enc, const char *p)
+{
+  const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
+  int c = uenc->convert(uenc->userData, p);
+  if (c & ~0xFFFF)
+    return 0;
+  return UCS2_GET_NAMING(namePages, c >> 8, c & 0xFF);
+}
+
+static int PTRFASTCALL
+unknown_isNmstrt(const ENCODING *enc, const char *p)
+{
+  const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
+  int c = uenc->convert(uenc->userData, p);
+  if (c & ~0xFFFF)
+    return 0;
+  return UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xFF);
+}
+
+static int PTRFASTCALL
+unknown_isInvalid(const ENCODING *enc, const char *p)
+{
+  const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
+  int c = uenc->convert(uenc->userData, p);
+  return (c & ~0xFFFF) || checkCharRefNumber(c) < 0;
+}
+
+static void PTRCALL
+unknown_toUtf8(const ENCODING *enc,
+               const char **fromP, const char *fromLim,
+               char **toP, const char *toLim)
+{
+  const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
+  char buf[XML_UTF8_ENCODE_MAX];
+  for (;;) {
+    const char *utf8;
+    int n;
+    if (*fromP == fromLim)
+      break;
+    utf8 = uenc->utf8[(unsigned char)**fromP];
+    n = *utf8++;
+    if (n == 0) {
+      int c = uenc->convert(uenc->userData, *fromP);
+      n = XmlUtf8Encode(c, buf);
+      if (n > toLim - *toP)
+        break;
+      utf8 = buf;
+      *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP]
+                 - (BT_LEAD2 - 2));
+    }
+    else {
+      if (n > toLim - *toP)
+        break;
+      (*fromP)++;
+    }
+    do {
+      *(*toP)++ = *utf8++;
+    } while (--n != 0);
+  }
+}
+
+static void PTRCALL
+unknown_toUtf16(const ENCODING *enc,
+                const char **fromP, const char *fromLim,
+                unsigned short **toP, const unsigned short *toLim)
+{
+  const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
+  while (*fromP != fromLim && *toP != toLim) {
+    unsigned short c = uenc->utf16[(unsigned char)**fromP];
+    if (c == 0) {
+      c = (unsigned short)
+          uenc->convert(uenc->userData, *fromP);
+      *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP]
+                 - (BT_LEAD2 - 2));
+    }
+    else
+      (*fromP)++;
+    *(*toP)++ = c;
+  }
+}
+
+ENCODING *
+XmlInitUnknownEncoding(void *mem,
+                       int *table,
+                       CONVERTER convert, 
+                       void *userData)
+{
+  int i;
+  struct unknown_encoding *e = (struct unknown_encoding *)mem;
+  for (i = 0; i < (int)sizeof(struct normal_encoding); i++)
+    ((char *)mem)[i] = ((char *)&latin1_encoding)[i];
+  for (i = 0; i < 128; i++)
+    if (latin1_encoding.type[i] != BT_OTHER
+        && latin1_encoding.type[i] != BT_NONXML
+        && table[i] != i)
+      return 0;
+  for (i = 0; i < 256; i++) {
+    int c = table[i];
+    if (c == -1) {
+      e->normal.type[i] = BT_MALFORM;
+      /* This shouldn't really get used. */
+      e->utf16[i] = 0xFFFF;
+      e->utf8[i][0] = 1;
+      e->utf8[i][1] = 0;
+    }
+    else if (c < 0) {
+      if (c < -4)
+        return 0;
+      e->normal.type[i] = (unsigned char)(BT_LEAD2 - (c + 2));
+      e->utf8[i][0] = 0;
+      e->utf16[i] = 0;
+    }
+    else if (c < 0x80) {
+      if (latin1_encoding.type[c] != BT_OTHER
+          && latin1_encoding.type[c] != BT_NONXML
+          && c != i)
+        return 0;
+      e->normal.type[i] = latin1_encoding.type[c];
+      e->utf8[i][0] = 1;
+      e->utf8[i][1] = (char)c;
+      e->utf16[i] = (unsigned short)(c == 0 ? 0xFFFF : c);
+    }
+    else if (checkCharRefNumber(c) < 0) {
+      e->normal.type[i] = BT_NONXML;
+      /* This shouldn't really get used. */
+      e->utf16[i] = 0xFFFF;
+      e->utf8[i][0] = 1;
+      e->utf8[i][1] = 0;
+    }
+    else {
+      if (c > 0xFFFF)
+        return 0;
+      if (UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xff))
+        e->normal.type[i] = BT_NMSTRT;
+      else if (UCS2_GET_NAMING(namePages, c >> 8, c & 0xff))
+        e->normal.type[i] = BT_NAME;
+      else
+        e->normal.type[i] = BT_OTHER;
+      e->utf8[i][0] = (char)XmlUtf8Encode(c, e->utf8[i] + 1);
+      e->utf16[i] = (unsigned short)c;
+    }
+  }
+  e->userData = userData;
+  e->convert = convert;
+  if (convert) {
+    e->normal.isName2 = unknown_isName;
+    e->normal.isName3 = unknown_isName;
+    e->normal.isName4 = unknown_isName;
+    e->normal.isNmstrt2 = unknown_isNmstrt;
+    e->normal.isNmstrt3 = unknown_isNmstrt;
+    e->normal.isNmstrt4 = unknown_isNmstrt;
+    e->normal.isInvalid2 = unknown_isInvalid;
+    e->normal.isInvalid3 = unknown_isInvalid;
+    e->normal.isInvalid4 = unknown_isInvalid;
+  }
+  e->normal.enc.utf8Convert = unknown_toUtf8;
+  e->normal.enc.utf16Convert = unknown_toUtf16;
+  return &(e->normal.enc);
+}
+
+/* If this enumeration is changed, getEncodingIndex and encodings
+must also be changed. */
+enum {
+  UNKNOWN_ENC = -1,
+  ISO_8859_1_ENC = 0,
+  US_ASCII_ENC,
+  UTF_8_ENC,
+  UTF_16_ENC,
+  UTF_16BE_ENC,
+  UTF_16LE_ENC,
+  /* must match encodingNames up to here */
+  NO_ENC
+};
+
+static const char KW_ISO_8859_1[] = {
+  ASCII_I, ASCII_S, ASCII_O, ASCII_MINUS, ASCII_8, ASCII_8, ASCII_5, ASCII_9,
+  ASCII_MINUS, ASCII_1, '\0'
+};
+static const char KW_US_ASCII[] = {
+  ASCII_U, ASCII_S, ASCII_MINUS, ASCII_A, ASCII_S, ASCII_C, ASCII_I, ASCII_I,
+  '\0'
+};
+static const char KW_UTF_8[] =  {
+  ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_8, '\0'
+};
+static const char KW_UTF_16[] = {
+  ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, '\0'
+};
+static const char KW_UTF_16BE[] = {
+  ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, ASCII_B, ASCII_E,
+  '\0'
+};
+static const char KW_UTF_16LE[] = {
+  ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, ASCII_L, ASCII_E,
+  '\0'
+};
+
+static int FASTCALL
+getEncodingIndex(const char *name)
+{
+  static const char * const encodingNames[] = {
+    KW_ISO_8859_1,
+    KW_US_ASCII,
+    KW_UTF_8,
+    KW_UTF_16,
+    KW_UTF_16BE,
+    KW_UTF_16LE,
+  };
+  int i;
+  if (name == NULL)
+    return NO_ENC;
+  for (i = 0; i < (int)(sizeof(encodingNames)/sizeof(encodingNames[0])); i++)
+    if (streqci(name, encodingNames[i]))
+      return i;
+  return UNKNOWN_ENC;
+}
+
+/* For binary compatibility, we store the index of the encoding
+   specified at initialization in the isUtf16 member.
+*/
+
+#define INIT_ENC_INDEX(enc) ((int)(enc)->initEnc.isUtf16)
+#define SET_INIT_ENC_INDEX(enc, i) ((enc)->initEnc.isUtf16 = (char)i)
+
+/* This is what detects the encoding.  encodingTable maps from
+   encoding indices to encodings; INIT_ENC_INDEX(enc) is the index of
+   the external (protocol) specified encoding; state is
+   XML_CONTENT_STATE if we're parsing an external text entity, and
+   XML_PROLOG_STATE otherwise.
+*/
+
+
+static int
+initScan(const ENCODING * const *encodingTable,
+         const INIT_ENCODING *enc,
+         int state,
+         const char *ptr,
+         const char *end,
+         const char **nextTokPtr)
+{
+  const ENCODING **encPtr;
+
+  if (ptr == end)
+    return XML_TOK_NONE;
+  encPtr = enc->encPtr;
+  if (ptr + 1 == end) {
+    /* only a single byte available for auto-detection */
+#ifndef XML_DTD /* FIXME */
+    /* a well-formed document entity must have more than one byte */
+    if (state != XML_CONTENT_STATE)
+      return XML_TOK_PARTIAL;
+#endif
+    /* so we're parsing an external text entity... */
+    /* if UTF-16 was externally specified, then we need at least 2 bytes */
+    switch (INIT_ENC_INDEX(enc)) {
+    case UTF_16_ENC:
+    case UTF_16LE_ENC:
+    case UTF_16BE_ENC:
+      return XML_TOK_PARTIAL;
+    }
+    switch ((unsigned char)*ptr) {
+    case 0xFE:
+    case 0xFF:
+    case 0xEF: /* possibly first byte of UTF-8 BOM */
+      if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC
+          && state == XML_CONTENT_STATE)
+        break;
+      /* fall through */
+    case 0x00:
+    case 0x3C:
+      return XML_TOK_PARTIAL;
+    }
+  }
+  else {
+    switch (((unsigned char)ptr[0] << 8) | (unsigned char)ptr[1]) {
+    case 0xFEFF:
+      if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC
+          && state == XML_CONTENT_STATE)
+        break;
+      *nextTokPtr = ptr + 2;
+      *encPtr = encodingTable[UTF_16BE_ENC];
+      return XML_TOK_BOM;
+    /* 00 3C is handled in the default case */
+    case 0x3C00:
+      if ((INIT_ENC_INDEX(enc) == UTF_16BE_ENC
+           || INIT_ENC_INDEX(enc) == UTF_16_ENC)
+          && state == XML_CONTENT_STATE)
+        break;
+      *encPtr = encodingTable[UTF_16LE_ENC];
+      return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
+    case 0xFFFE:
+      if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC
+          && state == XML_CONTENT_STATE)
+        break;
+      *nextTokPtr = ptr + 2;
+      *encPtr = encodingTable[UTF_16LE_ENC];
+      return XML_TOK_BOM;
+    case 0xEFBB:
+      /* Maybe a UTF-8 BOM (EF BB BF) */
+      /* If there's an explicitly specified (external) encoding
+         of ISO-8859-1 or some flavour of UTF-16
+         and this is an external text entity,
+         don't look for the BOM,
+         because it might be a legal data.
+      */
+      if (state == XML_CONTENT_STATE) {
+        int e = INIT_ENC_INDEX(enc);
+        if (e == ISO_8859_1_ENC || e == UTF_16BE_ENC
+            || e == UTF_16LE_ENC || e == UTF_16_ENC)
+          break;
+      }
+      if (ptr + 2 == end)
+        return XML_TOK_PARTIAL;
+      if ((unsigned char)ptr[2] == 0xBF) {
+        *nextTokPtr = ptr + 3;
+        *encPtr = encodingTable[UTF_8_ENC];
+        return XML_TOK_BOM;
+      }
+      break;
+    default:
+      if (ptr[0] == '\0') {
+        /* 0 isn't a legal data character. Furthermore a document
+           entity can only start with ASCII characters.  So the only
+           way this can fail to be big-endian UTF-16 if it it's an
+           external parsed general entity that's labelled as
+           UTF-16LE.
+        */
+        if (state == XML_CONTENT_STATE && INIT_ENC_INDEX(enc) == UTF_16LE_ENC)
+          break;
+        *encPtr = encodingTable[UTF_16BE_ENC];
+        return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
+      }
+      else if (ptr[1] == '\0') {
+        /* We could recover here in the case:
+            - parsing an external entity
+            - second byte is 0
+            - no externally specified encoding
+            - no encoding declaration
+           by assuming UTF-16LE.  But we don't, because this would mean when
+           presented just with a single byte, we couldn't reliably determine
+           whether we needed further bytes.
+        */
+        if (state == XML_CONTENT_STATE)
+          break;
+        *encPtr = encodingTable[UTF_16LE_ENC];
+        return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
+      }
+      break;
+    }
+  }
+  *encPtr = encodingTable[INIT_ENC_INDEX(enc)];
+  return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
+}
+
+
+#define NS(x) x
+#define ns(x) x
+#include "xmltok_ns.c"
+#undef NS
+#undef ns
+
+#ifdef XML_NS
+
+#define NS(x) x ## NS
+#define ns(x) x ## _ns
+
+#include "xmltok_ns.c"
+
+#undef NS
+#undef ns
+
+ENCODING *
+XmlInitUnknownEncodingNS(void *mem,
+                         int *table,
+                         CONVERTER convert, 
+                         void *userData)
+{
+  ENCODING *enc = XmlInitUnknownEncoding(mem, table, convert, userData);
+  if (enc)
+    ((struct normal_encoding *)enc)->type[ASCII_COLON] = BT_COLON;
+  return enc;
+}
+
+#endif /* XML_NS */

Added: vendor/Python/current/Modules/expat/xmltok.h
===================================================================
--- vendor/Python/current/Modules/expat/xmltok.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/expat/xmltok.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,316 @@
+/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+   See the file COPYING for copying permission.
+*/
+
+#ifndef XmlTok_INCLUDED
+#define XmlTok_INCLUDED 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* The following token may be returned by XmlContentTok */
+#define XML_TOK_TRAILING_RSQB -5 /* ] or ]] at the end of the scan; might be
+                                    start of illegal ]]> sequence */
+/* The following tokens may be returned by both XmlPrologTok and
+   XmlContentTok.
+*/
+#define XML_TOK_NONE -4          /* The string to be scanned is empty */
+#define XML_TOK_TRAILING_CR -3   /* A CR at the end of the scan;
+                                    might be part of CRLF sequence */
+#define XML_TOK_PARTIAL_CHAR -2  /* only part of a multibyte sequence */
+#define XML_TOK_PARTIAL -1       /* only part of a token */
+#define XML_TOK_INVALID 0
+
+/* The following tokens are returned by XmlContentTok; some are also
+   returned by XmlAttributeValueTok, XmlEntityTok, XmlCdataSectionTok.
+*/
+#define XML_TOK_START_TAG_WITH_ATTS 1
+#define XML_TOK_START_TAG_NO_ATTS 2
+#define XML_TOK_EMPTY_ELEMENT_WITH_ATTS 3 /* empty element tag <e/> */
+#define XML_TOK_EMPTY_ELEMENT_NO_ATTS 4
+#define XML_TOK_END_TAG 5
+#define XML_TOK_DATA_CHARS 6
+#define XML_TOK_DATA_NEWLINE 7
+#define XML_TOK_CDATA_SECT_OPEN 8
+#define XML_TOK_ENTITY_REF 9
+#define XML_TOK_CHAR_REF 10               /* numeric character reference */
+
+/* The following tokens may be returned by both XmlPrologTok and
+   XmlContentTok.
+*/
+#define XML_TOK_PI 11                     /* processing instruction */
+#define XML_TOK_XML_DECL 12               /* XML decl or text decl */
+#define XML_TOK_COMMENT 13
+#define XML_TOK_BOM 14                    /* Byte order mark */
+
+/* The following tokens are returned only by XmlPrologTok */
+#define XML_TOK_PROLOG_S 15
+#define XML_TOK_DECL_OPEN 16              /* <!foo */
+#define XML_TOK_DECL_CLOSE 17             /* > */
+#define XML_TOK_NAME 18
+#define XML_TOK_NMTOKEN 19
+#define XML_TOK_POUND_NAME 20             /* #name */
+#define XML_TOK_OR 21                     /* | */
+#define XML_TOK_PERCENT 22
+#define XML_TOK_OPEN_PAREN 23
+#define XML_TOK_CLOSE_PAREN 24
+#define XML_TOK_OPEN_BRACKET 25
+#define XML_TOK_CLOSE_BRACKET 26
+#define XML_TOK_LITERAL 27
+#define XML_TOK_PARAM_ENTITY_REF 28
+#define XML_TOK_INSTANCE_START 29
+
+/* The following occur only in element type declarations */
+#define XML_TOK_NAME_QUESTION 30          /* name? */
+#define XML_TOK_NAME_ASTERISK 31          /* name* */
+#define XML_TOK_NAME_PLUS 32              /* name+ */
+#define XML_TOK_COND_SECT_OPEN 33         /* <![ */
+#define XML_TOK_COND_SECT_CLOSE 34        /* ]]> */
+#define XML_TOK_CLOSE_PAREN_QUESTION 35   /* )? */
+#define XML_TOK_CLOSE_PAREN_ASTERISK 36   /* )* */
+#define XML_TOK_CLOSE_PAREN_PLUS 37       /* )+ */
+#define XML_TOK_COMMA 38
+
+/* The following token is returned only by XmlAttributeValueTok */
+#define XML_TOK_ATTRIBUTE_VALUE_S 39
+
+/* The following token is returned only by XmlCdataSectionTok */
+#define XML_TOK_CDATA_SECT_CLOSE 40
+
+/* With namespace processing this is returned by XmlPrologTok for a
+   name with a colon.
+*/
+#define XML_TOK_PREFIXED_NAME 41
+
+#ifdef XML_DTD
+#define XML_TOK_IGNORE_SECT 42
+#endif /* XML_DTD */
+
+#ifdef XML_DTD
+#define XML_N_STATES 4
+#else /* not XML_DTD */
+#define XML_N_STATES 3
+#endif /* not XML_DTD */
+
+#define XML_PROLOG_STATE 0
+#define XML_CONTENT_STATE 1
+#define XML_CDATA_SECTION_STATE 2
+#ifdef XML_DTD
+#define XML_IGNORE_SECTION_STATE 3
+#endif /* XML_DTD */
+
+#define XML_N_LITERAL_TYPES 2
+#define XML_ATTRIBUTE_VALUE_LITERAL 0
+#define XML_ENTITY_VALUE_LITERAL 1
+
+/* The size of the buffer passed to XmlUtf8Encode must be at least this. */
+#define XML_UTF8_ENCODE_MAX 4
+/* The size of the buffer passed to XmlUtf16Encode must be at least this. */
+#define XML_UTF16_ENCODE_MAX 2
+
+typedef struct position {
+  /* first line and first column are 0 not 1 */
+  XML_Size lineNumber;
+  XML_Size columnNumber;
+} POSITION;
+
+typedef struct {
+  const char *name;
+  const char *valuePtr;
+  const char *valueEnd;
+  char normalized;
+} ATTRIBUTE;
+
+struct encoding;
+typedef struct encoding ENCODING;
+
+typedef int (PTRCALL *SCANNER)(const ENCODING *,
+                               const char *,
+                               const char *,
+                               const char **);
+
+struct encoding {
+  SCANNER scanners[XML_N_STATES];
+  SCANNER literalScanners[XML_N_LITERAL_TYPES];
+  int (PTRCALL *sameName)(const ENCODING *,
+                          const char *,
+                          const char *);
+  int (PTRCALL *nameMatchesAscii)(const ENCODING *,
+                                  const char *,
+                                  const char *,
+                                  const char *);
+  int (PTRFASTCALL *nameLength)(const ENCODING *, const char *);
+  const char *(PTRFASTCALL *skipS)(const ENCODING *, const char *);
+  int (PTRCALL *getAtts)(const ENCODING *enc,
+                         const char *ptr,
+                         int attsMax,
+                         ATTRIBUTE *atts);
+  int (PTRFASTCALL *charRefNumber)(const ENCODING *enc, const char *ptr);
+  int (PTRCALL *predefinedEntityName)(const ENCODING *,
+                                      const char *,
+                                      const char *);
+  void (PTRCALL *updatePosition)(const ENCODING *,
+                                 const char *ptr,
+                                 const char *end,
+                                 POSITION *);
+  int (PTRCALL *isPublicId)(const ENCODING *enc,
+                            const char *ptr,
+                            const char *end,
+                            const char **badPtr);
+  void (PTRCALL *utf8Convert)(const ENCODING *enc,
+                              const char **fromP,
+                              const char *fromLim,
+                              char **toP,
+                              const char *toLim);
+  void (PTRCALL *utf16Convert)(const ENCODING *enc,
+                               const char **fromP,
+                               const char *fromLim,
+                               unsigned short **toP,
+                               const unsigned short *toLim);
+  int minBytesPerChar;
+  char isUtf8;
+  char isUtf16;
+};
+
+/* Scan the string starting at ptr until the end of the next complete
+   token, but do not scan past eptr.  Return an integer giving the
+   type of token.
+
+   Return XML_TOK_NONE when ptr == eptr; nextTokPtr will not be set.
+
+   Return XML_TOK_PARTIAL when the string does not contain a complete
+   token; nextTokPtr will not be set.
+
+   Return XML_TOK_INVALID when the string does not start a valid
+   token; nextTokPtr will be set to point to the character which made
+   the token invalid.
+
+   Otherwise the string starts with a valid token; nextTokPtr will be
+   set to point to the character following the end of that token.
+
+   Each data character counts as a single token, but adjacent data
+   characters may be returned together.  Similarly for characters in
+   the prolog outside literals, comments and processing instructions.
+*/
+
+
+#define XmlTok(enc, state, ptr, end, nextTokPtr) \
+  (((enc)->scanners[state])(enc, ptr, end, nextTokPtr))
+
+#define XmlPrologTok(enc, ptr, end, nextTokPtr) \
+   XmlTok(enc, XML_PROLOG_STATE, ptr, end, nextTokPtr)
+
+#define XmlContentTok(enc, ptr, end, nextTokPtr) \
+   XmlTok(enc, XML_CONTENT_STATE, ptr, end, nextTokPtr)
+
+#define XmlCdataSectionTok(enc, ptr, end, nextTokPtr) \
+   XmlTok(enc, XML_CDATA_SECTION_STATE, ptr, end, nextTokPtr)
+
+#ifdef XML_DTD
+
+#define XmlIgnoreSectionTok(enc, ptr, end, nextTokPtr) \
+   XmlTok(enc, XML_IGNORE_SECTION_STATE, ptr, end, nextTokPtr)
+
+#endif /* XML_DTD */
+
+/* This is used for performing a 2nd-level tokenization on the content
+   of a literal that has already been returned by XmlTok.
+*/
+#define XmlLiteralTok(enc, literalType, ptr, end, nextTokPtr) \
+  (((enc)->literalScanners[literalType])(enc, ptr, end, nextTokPtr))
+
+#define XmlAttributeValueTok(enc, ptr, end, nextTokPtr) \
+   XmlLiteralTok(enc, XML_ATTRIBUTE_VALUE_LITERAL, ptr, end, nextTokPtr)
+
+#define XmlEntityValueTok(enc, ptr, end, nextTokPtr) \
+   XmlLiteralTok(enc, XML_ENTITY_VALUE_LITERAL, ptr, end, nextTokPtr)
+
+#define XmlSameName(enc, ptr1, ptr2) (((enc)->sameName)(enc, ptr1, ptr2))
+
+#define XmlNameMatchesAscii(enc, ptr1, end1, ptr2) \
+  (((enc)->nameMatchesAscii)(enc, ptr1, end1, ptr2))
+
+#define XmlNameLength(enc, ptr) \
+  (((enc)->nameLength)(enc, ptr))
+
+#define XmlSkipS(enc, ptr) \
+  (((enc)->skipS)(enc, ptr))
+
+#define XmlGetAttributes(enc, ptr, attsMax, atts) \
+  (((enc)->getAtts)(enc, ptr, attsMax, atts))
+
+#define XmlCharRefNumber(enc, ptr) \
+  (((enc)->charRefNumber)(enc, ptr))
+
+#define XmlPredefinedEntityName(enc, ptr, end) \
+  (((enc)->predefinedEntityName)(enc, ptr, end))
+
+#define XmlUpdatePosition(enc, ptr, end, pos) \
+  (((enc)->updatePosition)(enc, ptr, end, pos))
+
+#define XmlIsPublicId(enc, ptr, end, badPtr) \
+  (((enc)->isPublicId)(enc, ptr, end, badPtr))
+
+#define XmlUtf8Convert(enc, fromP, fromLim, toP, toLim) \
+  (((enc)->utf8Convert)(enc, fromP, fromLim, toP, toLim))
+
+#define XmlUtf16Convert(enc, fromP, fromLim, toP, toLim) \
+  (((enc)->utf16Convert)(enc, fromP, fromLim, toP, toLim))
+
+typedef struct {
+  ENCODING initEnc;
+  const ENCODING **encPtr;
+} INIT_ENCODING;
+
+int XmlParseXmlDecl(int isGeneralTextEntity,
+                    const ENCODING *enc,
+                    const char *ptr,
+                    const char *end,
+                    const char **badPtr,
+                    const char **versionPtr,
+                    const char **versionEndPtr,
+                    const char **encodingNamePtr,
+                    const ENCODING **namedEncodingPtr,
+                    int *standalonePtr);
+
+int XmlInitEncoding(INIT_ENCODING *, const ENCODING **, const char *name);
+const ENCODING *XmlGetUtf8InternalEncoding(void);
+const ENCODING *XmlGetUtf16InternalEncoding(void);
+int FASTCALL XmlUtf8Encode(int charNumber, char *buf);
+int FASTCALL XmlUtf16Encode(int charNumber, unsigned short *buf);
+int XmlSizeOfUnknownEncoding(void);
+
+
+typedef int (XMLCALL *CONVERTER) (void *userData, const char *p);
+
+ENCODING *
+XmlInitUnknownEncoding(void *mem,
+                       int *table,
+                       CONVERTER convert,
+                       void *userData);
+
+int XmlParseXmlDeclNS(int isGeneralTextEntity,
+                      const ENCODING *enc,
+                      const char *ptr,
+                      const char *end,
+                      const char **badPtr,
+                      const char **versionPtr,
+                      const char **versionEndPtr,
+                      const char **encodingNamePtr,
+                      const ENCODING **namedEncodingPtr,
+                      int *standalonePtr);
+
+int XmlInitEncodingNS(INIT_ENCODING *, const ENCODING **, const char *name);
+const ENCODING *XmlGetUtf8InternalEncodingNS(void);
+const ENCODING *XmlGetUtf16InternalEncodingNS(void);
+ENCODING *
+XmlInitUnknownEncodingNS(void *mem,
+                         int *table,
+                         CONVERTER convert,
+                         void *userData);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* not XmlTok_INCLUDED */

Added: vendor/Python/current/Modules/expat/xmltok_impl.c
===================================================================
--- vendor/Python/current/Modules/expat/xmltok_impl.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/expat/xmltok_impl.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1779 @@
+/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+   See the file COPYING for copying permission.
+*/
+
+#ifndef IS_INVALID_CHAR
+#define IS_INVALID_CHAR(enc, ptr, n) (0)
+#endif
+
+#define INVALID_LEAD_CASE(n, ptr, nextTokPtr) \
+    case BT_LEAD ## n: \
+      if (end - ptr < n) \
+        return XML_TOK_PARTIAL_CHAR; \
+      if (IS_INVALID_CHAR(enc, ptr, n)) { \
+        *(nextTokPtr) = (ptr); \
+        return XML_TOK_INVALID; \
+      } \
+      ptr += n; \
+      break;
+
+#define INVALID_CASES(ptr, nextTokPtr) \
+  INVALID_LEAD_CASE(2, ptr, nextTokPtr) \
+  INVALID_LEAD_CASE(3, ptr, nextTokPtr) \
+  INVALID_LEAD_CASE(4, ptr, nextTokPtr) \
+  case BT_NONXML: \
+  case BT_MALFORM: \
+  case BT_TRAIL: \
+    *(nextTokPtr) = (ptr); \
+    return XML_TOK_INVALID;
+
+#define CHECK_NAME_CASE(n, enc, ptr, end, nextTokPtr) \
+   case BT_LEAD ## n: \
+     if (end - ptr < n) \
+       return XML_TOK_PARTIAL_CHAR; \
+     if (!IS_NAME_CHAR(enc, ptr, n)) { \
+       *nextTokPtr = ptr; \
+       return XML_TOK_INVALID; \
+     } \
+     ptr += n; \
+     break;
+
+#define CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) \
+  case BT_NONASCII: \
+    if (!IS_NAME_CHAR_MINBPC(enc, ptr)) { \
+      *nextTokPtr = ptr; \
+      return XML_TOK_INVALID; \
+    } \
+  case BT_NMSTRT: \
+  case BT_HEX: \
+  case BT_DIGIT: \
+  case BT_NAME: \
+  case BT_MINUS: \
+    ptr += MINBPC(enc); \
+    break; \
+  CHECK_NAME_CASE(2, enc, ptr, end, nextTokPtr) \
+  CHECK_NAME_CASE(3, enc, ptr, end, nextTokPtr) \
+  CHECK_NAME_CASE(4, enc, ptr, end, nextTokPtr)
+
+#define CHECK_NMSTRT_CASE(n, enc, ptr, end, nextTokPtr) \
+   case BT_LEAD ## n: \
+     if (end - ptr < n) \
+       return XML_TOK_PARTIAL_CHAR; \
+     if (!IS_NMSTRT_CHAR(enc, ptr, n)) { \
+       *nextTokPtr = ptr; \
+       return XML_TOK_INVALID; \
+     } \
+     ptr += n; \
+     break;
+
+#define CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) \
+  case BT_NONASCII: \
+    if (!IS_NMSTRT_CHAR_MINBPC(enc, ptr)) { \
+      *nextTokPtr = ptr; \
+      return XML_TOK_INVALID; \
+    } \
+  case BT_NMSTRT: \
+  case BT_HEX: \
+    ptr += MINBPC(enc); \
+    break; \
+  CHECK_NMSTRT_CASE(2, enc, ptr, end, nextTokPtr) \
+  CHECK_NMSTRT_CASE(3, enc, ptr, end, nextTokPtr) \
+  CHECK_NMSTRT_CASE(4, enc, ptr, end, nextTokPtr)
+
+#ifndef PREFIX
+#define PREFIX(ident) ident
+#endif
+
+/* ptr points to character following "<!-" */
+
+static int PTRCALL
+PREFIX(scanComment)(const ENCODING *enc, const char *ptr,
+                    const char *end, const char **nextTokPtr)
+{
+  if (ptr != end) {
+    if (!CHAR_MATCHES(enc, ptr, ASCII_MINUS)) {
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+    ptr += MINBPC(enc);
+    while (ptr != end) {
+      switch (BYTE_TYPE(enc, ptr)) {
+      INVALID_CASES(ptr, nextTokPtr)
+      case BT_MINUS:
+        if ((ptr += MINBPC(enc)) == end)
+          return XML_TOK_PARTIAL;
+        if (CHAR_MATCHES(enc, ptr, ASCII_MINUS)) {
+          if ((ptr += MINBPC(enc)) == end)
+            return XML_TOK_PARTIAL;
+          if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+            *nextTokPtr = ptr;
+            return XML_TOK_INVALID;
+          }
+          *nextTokPtr = ptr + MINBPC(enc);
+          return XML_TOK_COMMENT;
+        }
+        break;
+      default:
+        ptr += MINBPC(enc);
+        break;
+      }
+    }
+  }
+  return XML_TOK_PARTIAL;
+}
+
+/* ptr points to character following "<!" */
+
+static int PTRCALL
+PREFIX(scanDecl)(const ENCODING *enc, const char *ptr,
+                 const char *end, const char **nextTokPtr)
+{
+  if (ptr == end)
+    return XML_TOK_PARTIAL;
+  switch (BYTE_TYPE(enc, ptr)) {
+  case BT_MINUS:
+    return PREFIX(scanComment)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+  case BT_LSQB:
+    *nextTokPtr = ptr + MINBPC(enc);
+    return XML_TOK_COND_SECT_OPEN;
+  case BT_NMSTRT:
+  case BT_HEX:
+    ptr += MINBPC(enc);
+    break;
+  default:
+    *nextTokPtr = ptr;
+    return XML_TOK_INVALID;
+  }
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    case BT_PERCNT:
+      if (ptr + MINBPC(enc) == end)
+        return XML_TOK_PARTIAL;
+      /* don't allow <!ENTITY% foo "whatever"> */
+      switch (BYTE_TYPE(enc, ptr + MINBPC(enc))) {
+      case BT_S: case BT_CR: case BT_LF: case BT_PERCNT:
+        *nextTokPtr = ptr;
+        return XML_TOK_INVALID;
+      }
+      /* fall through */
+    case BT_S: case BT_CR: case BT_LF:
+      *nextTokPtr = ptr;
+      return XML_TOK_DECL_OPEN;
+    case BT_NMSTRT:
+    case BT_HEX:
+      ptr += MINBPC(enc);
+      break;
+    default:
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+  }
+  return XML_TOK_PARTIAL;
+}
+
+static int PTRCALL
+PREFIX(checkPiTarget)(const ENCODING *enc, const char *ptr,
+                      const char *end, int *tokPtr)
+{
+  int upper = 0;
+  *tokPtr = XML_TOK_PI;
+  if (end - ptr != MINBPC(enc)*3)
+    return 1;
+  switch (BYTE_TO_ASCII(enc, ptr)) {
+  case ASCII_x:
+    break;
+  case ASCII_X:
+    upper = 1;
+    break;
+  default:
+    return 1;
+  }
+  ptr += MINBPC(enc);
+  switch (BYTE_TO_ASCII(enc, ptr)) {
+  case ASCII_m:
+    break;
+  case ASCII_M:
+    upper = 1;
+    break;
+  default:
+    return 1;
+  }
+  ptr += MINBPC(enc);
+  switch (BYTE_TO_ASCII(enc, ptr)) {
+  case ASCII_l:
+    break;
+  case ASCII_L:
+    upper = 1;
+    break;
+  default:
+    return 1;
+  }
+  if (upper)
+    return 0;
+  *tokPtr = XML_TOK_XML_DECL;
+  return 1;
+}
+
+/* ptr points to character following "<?" */
+
+static int PTRCALL
+PREFIX(scanPi)(const ENCODING *enc, const char *ptr,
+               const char *end, const char **nextTokPtr)
+{
+  int tok;
+  const char *target = ptr;
+  if (ptr == end)
+    return XML_TOK_PARTIAL;
+  switch (BYTE_TYPE(enc, ptr)) {
+  CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+  default:
+    *nextTokPtr = ptr;
+    return XML_TOK_INVALID;
+  }
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+    case BT_S: case BT_CR: case BT_LF:
+      if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) {
+        *nextTokPtr = ptr;
+        return XML_TOK_INVALID;
+      }
+      ptr += MINBPC(enc);
+      while (ptr != end) {
+        switch (BYTE_TYPE(enc, ptr)) {
+        INVALID_CASES(ptr, nextTokPtr)
+        case BT_QUEST:
+          ptr += MINBPC(enc);
+          if (ptr == end)
+            return XML_TOK_PARTIAL;
+          if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+            *nextTokPtr = ptr + MINBPC(enc);
+            return tok;
+          }
+          break;
+        default:
+          ptr += MINBPC(enc);
+          break;
+        }
+      }
+      return XML_TOK_PARTIAL;
+    case BT_QUEST:
+      if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) {
+        *nextTokPtr = ptr;
+        return XML_TOK_INVALID;
+      }
+      ptr += MINBPC(enc);
+      if (ptr == end)
+        return XML_TOK_PARTIAL;
+      if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+        *nextTokPtr = ptr + MINBPC(enc);
+        return tok;
+      }
+      /* fall through */
+    default:
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+  }
+  return XML_TOK_PARTIAL;
+}
+
+static int PTRCALL
+PREFIX(scanCdataSection)(const ENCODING *enc, const char *ptr,
+                         const char *end, const char **nextTokPtr)
+{
+  static const char CDATA_LSQB[] = { ASCII_C, ASCII_D, ASCII_A,
+                                     ASCII_T, ASCII_A, ASCII_LSQB };
+  int i;
+  /* CDATA[ */
+  if (end - ptr < 6 * MINBPC(enc))
+    return XML_TOK_PARTIAL;
+  for (i = 0; i < 6; i++, ptr += MINBPC(enc)) {
+    if (!CHAR_MATCHES(enc, ptr, CDATA_LSQB[i])) {
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+  }
+  *nextTokPtr = ptr;
+  return XML_TOK_CDATA_SECT_OPEN;
+}
+
+static int PTRCALL
+PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr,
+                        const char *end, const char **nextTokPtr)
+{
+  if (ptr == end)
+    return XML_TOK_NONE;
+  if (MINBPC(enc) > 1) {
+    size_t n = end - ptr;
+    if (n & (MINBPC(enc) - 1)) {
+      n &= ~(MINBPC(enc) - 1);
+      if (n == 0)
+        return XML_TOK_PARTIAL;
+      end = ptr + n;
+    }
+  }
+  switch (BYTE_TYPE(enc, ptr)) {
+  case BT_RSQB:
+    ptr += MINBPC(enc);
+    if (ptr == end)
+      return XML_TOK_PARTIAL;
+    if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB))
+      break;
+    ptr += MINBPC(enc);
+    if (ptr == end)
+      return XML_TOK_PARTIAL;
+    if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+      ptr -= MINBPC(enc);
+      break;
+    }
+    *nextTokPtr = ptr + MINBPC(enc);
+    return XML_TOK_CDATA_SECT_CLOSE;
+  case BT_CR:
+    ptr += MINBPC(enc);
+    if (ptr == end)
+      return XML_TOK_PARTIAL;
+    if (BYTE_TYPE(enc, ptr) == BT_LF)
+      ptr += MINBPC(enc);
+    *nextTokPtr = ptr;
+    return XML_TOK_DATA_NEWLINE;
+  case BT_LF:
+    *nextTokPtr = ptr + MINBPC(enc);
+    return XML_TOK_DATA_NEWLINE;
+  INVALID_CASES(ptr, nextTokPtr)
+  default:
+    ptr += MINBPC(enc);
+    break;
+  }
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+#define LEAD_CASE(n) \
+    case BT_LEAD ## n: \
+      if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \
+        *nextTokPtr = ptr; \
+        return XML_TOK_DATA_CHARS; \
+      } \
+      ptr += n; \
+      break;
+    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+    case BT_NONXML:
+    case BT_MALFORM:
+    case BT_TRAIL:
+    case BT_CR:
+    case BT_LF:
+    case BT_RSQB:
+      *nextTokPtr = ptr;
+      return XML_TOK_DATA_CHARS;
+    default:
+      ptr += MINBPC(enc);
+      break;
+    }
+  }
+  *nextTokPtr = ptr;
+  return XML_TOK_DATA_CHARS;
+}
+
+/* ptr points to character following "</" */
+
+static int PTRCALL
+PREFIX(scanEndTag)(const ENCODING *enc, const char *ptr,
+                   const char *end, const char **nextTokPtr)
+{
+  if (ptr == end)
+    return XML_TOK_PARTIAL;
+  switch (BYTE_TYPE(enc, ptr)) {
+  CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+  default:
+    *nextTokPtr = ptr;
+    return XML_TOK_INVALID;
+  }
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+    case BT_S: case BT_CR: case BT_LF:
+      for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
+        switch (BYTE_TYPE(enc, ptr)) {
+        case BT_S: case BT_CR: case BT_LF:
+          break;
+        case BT_GT:
+          *nextTokPtr = ptr + MINBPC(enc);
+          return XML_TOK_END_TAG;
+        default:
+          *nextTokPtr = ptr;
+          return XML_TOK_INVALID;
+        }
+      }
+      return XML_TOK_PARTIAL;
+#ifdef XML_NS
+    case BT_COLON:
+      /* no need to check qname syntax here,
+         since end-tag must match exactly */
+      ptr += MINBPC(enc);
+      break;
+#endif
+    case BT_GT:
+      *nextTokPtr = ptr + MINBPC(enc);
+      return XML_TOK_END_TAG;
+    default:
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+  }
+  return XML_TOK_PARTIAL;
+}
+
+/* ptr points to character following "&#X" */
+
+static int PTRCALL
+PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr,
+                       const char *end, const char **nextTokPtr)
+{
+  if (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    case BT_DIGIT:
+    case BT_HEX:
+      break;
+    default:
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+    for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
+      switch (BYTE_TYPE(enc, ptr)) {
+      case BT_DIGIT:
+      case BT_HEX:
+        break;
+      case BT_SEMI:
+        *nextTokPtr = ptr + MINBPC(enc);
+        return XML_TOK_CHAR_REF;
+      default:
+        *nextTokPtr = ptr;
+        return XML_TOK_INVALID;
+      }
+    }
+  }
+  return XML_TOK_PARTIAL;
+}
+
+/* ptr points to character following "&#" */
+
+static int PTRCALL
+PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr,
+                    const char *end, const char **nextTokPtr)
+{
+  if (ptr != end) {
+    if (CHAR_MATCHES(enc, ptr, ASCII_x))
+      return PREFIX(scanHexCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+    switch (BYTE_TYPE(enc, ptr)) {
+    case BT_DIGIT:
+      break;
+    default:
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+    for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
+      switch (BYTE_TYPE(enc, ptr)) {
+      case BT_DIGIT:
+        break;
+      case BT_SEMI:
+        *nextTokPtr = ptr + MINBPC(enc);
+        return XML_TOK_CHAR_REF;
+      default:
+        *nextTokPtr = ptr;
+        return XML_TOK_INVALID;
+      }
+    }
+  }
+  return XML_TOK_PARTIAL;
+}
+
+/* ptr points to character following "&" */
+
+static int PTRCALL
+PREFIX(scanRef)(const ENCODING *enc, const char *ptr, const char *end,
+                const char **nextTokPtr)
+{
+  if (ptr == end)
+    return XML_TOK_PARTIAL;
+  switch (BYTE_TYPE(enc, ptr)) {
+  CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+  case BT_NUM:
+    return PREFIX(scanCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+  default:
+    *nextTokPtr = ptr;
+    return XML_TOK_INVALID;
+  }
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+    case BT_SEMI:
+      *nextTokPtr = ptr + MINBPC(enc);
+      return XML_TOK_ENTITY_REF;
+    default:
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+  }
+  return XML_TOK_PARTIAL;
+}
+
+/* ptr points to character following first character of attribute name */
+
+static int PTRCALL
+PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end,
+                 const char **nextTokPtr)
+{
+#ifdef XML_NS
+  int hadColon = 0;
+#endif
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+#ifdef XML_NS
+    case BT_COLON:
+      if (hadColon) {
+        *nextTokPtr = ptr;
+        return XML_TOK_INVALID;
+      }
+      hadColon = 1;
+      ptr += MINBPC(enc);
+      if (ptr == end)
+        return XML_TOK_PARTIAL;
+      switch (BYTE_TYPE(enc, ptr)) {
+      CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+      default:
+        *nextTokPtr = ptr;
+        return XML_TOK_INVALID;
+      }
+      break;
+#endif
+    case BT_S: case BT_CR: case BT_LF:
+      for (;;) {
+        int t;
+
+        ptr += MINBPC(enc);
+        if (ptr == end)
+          return XML_TOK_PARTIAL;
+        t = BYTE_TYPE(enc, ptr);
+        if (t == BT_EQUALS)
+          break;
+        switch (t) {
+        case BT_S:
+        case BT_LF:
+        case BT_CR:
+          break;
+        default:
+          *nextTokPtr = ptr;
+          return XML_TOK_INVALID;
+        }
+      }
+    /* fall through */
+    case BT_EQUALS:
+      {
+        int open;
+#ifdef XML_NS
+        hadColon = 0;
+#endif
+        for (;;) {
+          ptr += MINBPC(enc);
+          if (ptr == end)
+            return XML_TOK_PARTIAL;
+          open = BYTE_TYPE(enc, ptr);
+          if (open == BT_QUOT || open == BT_APOS)
+            break;
+          switch (open) {
+          case BT_S:
+          case BT_LF:
+          case BT_CR:
+            break;
+          default:
+            *nextTokPtr = ptr;
+            return XML_TOK_INVALID;
+          }
+        }
+        ptr += MINBPC(enc);
+        /* in attribute value */
+        for (;;) {
+          int t;
+          if (ptr == end)
+            return XML_TOK_PARTIAL;
+          t = BYTE_TYPE(enc, ptr);
+          if (t == open)
+            break;
+          switch (t) {
+          INVALID_CASES(ptr, nextTokPtr)
+          case BT_AMP:
+            {
+              int tok = PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, &ptr);
+              if (tok <= 0) {
+                if (tok == XML_TOK_INVALID)
+                  *nextTokPtr = ptr;
+                return tok;
+              }
+              break;
+            }
+          case BT_LT:
+            *nextTokPtr = ptr;
+            return XML_TOK_INVALID;
+          default:
+            ptr += MINBPC(enc);
+            break;
+          }
+        }
+        ptr += MINBPC(enc);
+        if (ptr == end)
+          return XML_TOK_PARTIAL;
+        switch (BYTE_TYPE(enc, ptr)) {
+        case BT_S:
+        case BT_CR:
+        case BT_LF:
+          break;
+        case BT_SOL:
+          goto sol;
+        case BT_GT:
+          goto gt;
+        default:
+          *nextTokPtr = ptr;
+          return XML_TOK_INVALID;
+        }
+        /* ptr points to closing quote */
+        for (;;) {
+          ptr += MINBPC(enc);
+          if (ptr == end)
+            return XML_TOK_PARTIAL;
+          switch (BYTE_TYPE(enc, ptr)) {
+          CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+          case BT_S: case BT_CR: case BT_LF:
+            continue;
+          case BT_GT:
+          gt:
+            *nextTokPtr = ptr + MINBPC(enc);
+            return XML_TOK_START_TAG_WITH_ATTS;
+          case BT_SOL:
+          sol:
+            ptr += MINBPC(enc);
+            if (ptr == end)
+              return XML_TOK_PARTIAL;
+            if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+              *nextTokPtr = ptr;
+              return XML_TOK_INVALID;
+            }
+            *nextTokPtr = ptr + MINBPC(enc);
+            return XML_TOK_EMPTY_ELEMENT_WITH_ATTS;
+          default:
+            *nextTokPtr = ptr;
+            return XML_TOK_INVALID;
+          }
+          break;
+        }
+        break;
+      }
+    default:
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+  }
+  return XML_TOK_PARTIAL;
+}
+
+/* ptr points to character following "<" */
+
+static int PTRCALL
+PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end,
+               const char **nextTokPtr)
+{
+#ifdef XML_NS
+  int hadColon;
+#endif
+  if (ptr == end)
+    return XML_TOK_PARTIAL;
+  switch (BYTE_TYPE(enc, ptr)) {
+  CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+  case BT_EXCL:
+    if ((ptr += MINBPC(enc)) == end)
+      return XML_TOK_PARTIAL;
+    switch (BYTE_TYPE(enc, ptr)) {
+    case BT_MINUS:
+      return PREFIX(scanComment)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+    case BT_LSQB:
+      return PREFIX(scanCdataSection)(enc, ptr + MINBPC(enc),
+                                      end, nextTokPtr);
+    }
+    *nextTokPtr = ptr;
+    return XML_TOK_INVALID;
+  case BT_QUEST:
+    return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+  case BT_SOL:
+    return PREFIX(scanEndTag)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+  default:
+    *nextTokPtr = ptr;
+    return XML_TOK_INVALID;
+  }
+#ifdef XML_NS
+  hadColon = 0;
+#endif
+  /* we have a start-tag */
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+#ifdef XML_NS
+    case BT_COLON:
+      if (hadColon) {
+        *nextTokPtr = ptr;
+        return XML_TOK_INVALID;
+      }
+      hadColon = 1;
+      ptr += MINBPC(enc);
+      if (ptr == end)
+        return XML_TOK_PARTIAL;
+      switch (BYTE_TYPE(enc, ptr)) {
+      CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+      default:
+        *nextTokPtr = ptr;
+        return XML_TOK_INVALID;
+      }
+      break;
+#endif
+    case BT_S: case BT_CR: case BT_LF:
+      {
+        ptr += MINBPC(enc);
+        while (ptr != end) {
+          switch (BYTE_TYPE(enc, ptr)) {
+          CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+          case BT_GT:
+            goto gt;
+          case BT_SOL:
+            goto sol;
+          case BT_S: case BT_CR: case BT_LF:
+            ptr += MINBPC(enc);
+            continue;
+          default:
+            *nextTokPtr = ptr;
+            return XML_TOK_INVALID;
+          }
+          return PREFIX(scanAtts)(enc, ptr, end, nextTokPtr);
+        }
+        return XML_TOK_PARTIAL;
+      }
+    case BT_GT:
+    gt:
+      *nextTokPtr = ptr + MINBPC(enc);
+      return XML_TOK_START_TAG_NO_ATTS;
+    case BT_SOL:
+    sol:
+      ptr += MINBPC(enc);
+      if (ptr == end)
+        return XML_TOK_PARTIAL;
+      if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+        *nextTokPtr = ptr;
+        return XML_TOK_INVALID;
+      }
+      *nextTokPtr = ptr + MINBPC(enc);
+      return XML_TOK_EMPTY_ELEMENT_NO_ATTS;
+    default:
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+  }
+  return XML_TOK_PARTIAL;
+}
+
+static int PTRCALL
+PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end,
+                   const char **nextTokPtr)
+{
+  if (ptr == end)
+    return XML_TOK_NONE;
+  if (MINBPC(enc) > 1) {
+    size_t n = end - ptr;
+    if (n & (MINBPC(enc) - 1)) {
+      n &= ~(MINBPC(enc) - 1);
+      if (n == 0)
+        return XML_TOK_PARTIAL;
+      end = ptr + n;
+    }
+  }
+  switch (BYTE_TYPE(enc, ptr)) {
+  case BT_LT:
+    return PREFIX(scanLt)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+  case BT_AMP:
+    return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+  case BT_CR:
+    ptr += MINBPC(enc);
+    if (ptr == end)
+      return XML_TOK_TRAILING_CR;
+    if (BYTE_TYPE(enc, ptr) == BT_LF)
+      ptr += MINBPC(enc);
+    *nextTokPtr = ptr;
+    return XML_TOK_DATA_NEWLINE;
+  case BT_LF:
+    *nextTokPtr = ptr + MINBPC(enc);
+    return XML_TOK_DATA_NEWLINE;
+  case BT_RSQB:
+    ptr += MINBPC(enc);
+    if (ptr == end)
+      return XML_TOK_TRAILING_RSQB;
+    if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB))
+      break;
+    ptr += MINBPC(enc);
+    if (ptr == end)
+      return XML_TOK_TRAILING_RSQB;
+    if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+      ptr -= MINBPC(enc);
+      break;
+    }
+    *nextTokPtr = ptr;
+    return XML_TOK_INVALID;
+  INVALID_CASES(ptr, nextTokPtr)
+  default:
+    ptr += MINBPC(enc);
+    break;
+  }
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+#define LEAD_CASE(n) \
+    case BT_LEAD ## n: \
+      if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \
+        *nextTokPtr = ptr; \
+        return XML_TOK_DATA_CHARS; \
+      } \
+      ptr += n; \
+      break;
+    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+    case BT_RSQB:
+      if (ptr + MINBPC(enc) != end) {
+         if (!CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_RSQB)) {
+           ptr += MINBPC(enc);
+           break;
+         }
+         if (ptr + 2*MINBPC(enc) != end) {
+           if (!CHAR_MATCHES(enc, ptr + 2*MINBPC(enc), ASCII_GT)) {
+             ptr += MINBPC(enc);
+             break;
+           }
+           *nextTokPtr = ptr + 2*MINBPC(enc);
+           return XML_TOK_INVALID;
+         }
+      }
+      /* fall through */
+    case BT_AMP:
+    case BT_LT:
+    case BT_NONXML:
+    case BT_MALFORM:
+    case BT_TRAIL:
+    case BT_CR:
+    case BT_LF:
+      *nextTokPtr = ptr;
+      return XML_TOK_DATA_CHARS;
+    default:
+      ptr += MINBPC(enc);
+      break;
+    }
+  }
+  *nextTokPtr = ptr;
+  return XML_TOK_DATA_CHARS;
+}
+
+/* ptr points to character following "%" */
+
+static int PTRCALL
+PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end,
+                    const char **nextTokPtr)
+{
+  if (ptr == end)
+    return -XML_TOK_PERCENT;
+  switch (BYTE_TYPE(enc, ptr)) {
+  CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+  case BT_S: case BT_LF: case BT_CR: case BT_PERCNT:
+    *nextTokPtr = ptr;
+    return XML_TOK_PERCENT;
+  default:
+    *nextTokPtr = ptr;
+    return XML_TOK_INVALID;
+  }
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+    case BT_SEMI:
+      *nextTokPtr = ptr + MINBPC(enc);
+      return XML_TOK_PARAM_ENTITY_REF;
+    default:
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+  }
+  return XML_TOK_PARTIAL;
+}
+
+static int PTRCALL
+PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end,
+                      const char **nextTokPtr)
+{
+  if (ptr == end)
+    return XML_TOK_PARTIAL;
+  switch (BYTE_TYPE(enc, ptr)) {
+  CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+  default:
+    *nextTokPtr = ptr;
+    return XML_TOK_INVALID;
+  }
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+    case BT_CR: case BT_LF: case BT_S:
+    case BT_RPAR: case BT_GT: case BT_PERCNT: case BT_VERBAR:
+      *nextTokPtr = ptr;
+      return XML_TOK_POUND_NAME;
+    default:
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+  }
+  return -XML_TOK_POUND_NAME;
+}
+
+static int PTRCALL
+PREFIX(scanLit)(int open, const ENCODING *enc,
+                const char *ptr, const char *end,
+                const char **nextTokPtr)
+{
+  while (ptr != end) {
+    int t = BYTE_TYPE(enc, ptr);
+    switch (t) {
+    INVALID_CASES(ptr, nextTokPtr)
+    case BT_QUOT:
+    case BT_APOS:
+      ptr += MINBPC(enc);
+      if (t != open)
+        break;
+      if (ptr == end)
+        return -XML_TOK_LITERAL;
+      *nextTokPtr = ptr;
+      switch (BYTE_TYPE(enc, ptr)) {
+      case BT_S: case BT_CR: case BT_LF:
+      case BT_GT: case BT_PERCNT: case BT_LSQB:
+        return XML_TOK_LITERAL;
+      default:
+        return XML_TOK_INVALID;
+      }
+    default:
+      ptr += MINBPC(enc);
+      break;
+    }
+  }
+  return XML_TOK_PARTIAL;
+}
+
+static int PTRCALL
+PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,
+                  const char **nextTokPtr)
+{
+  int tok;
+  if (ptr == end)
+    return XML_TOK_NONE;
+  if (MINBPC(enc) > 1) {
+    size_t n = end - ptr;
+    if (n & (MINBPC(enc) - 1)) {
+      n &= ~(MINBPC(enc) - 1);
+      if (n == 0)
+        return XML_TOK_PARTIAL;
+      end = ptr + n;
+    }
+  }
+  switch (BYTE_TYPE(enc, ptr)) {
+  case BT_QUOT:
+    return PREFIX(scanLit)(BT_QUOT, enc, ptr + MINBPC(enc), end, nextTokPtr);
+  case BT_APOS:
+    return PREFIX(scanLit)(BT_APOS, enc, ptr + MINBPC(enc), end, nextTokPtr);
+  case BT_LT:
+    {
+      ptr += MINBPC(enc);
+      if (ptr == end)
+        return XML_TOK_PARTIAL;
+      switch (BYTE_TYPE(enc, ptr)) {
+      case BT_EXCL:
+        return PREFIX(scanDecl)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+      case BT_QUEST:
+        return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+      case BT_NMSTRT:
+      case BT_HEX:
+      case BT_NONASCII:
+      case BT_LEAD2:
+      case BT_LEAD3:
+      case BT_LEAD4:
+        *nextTokPtr = ptr - MINBPC(enc);
+        return XML_TOK_INSTANCE_START;
+      }
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+  case BT_CR:
+    if (ptr + MINBPC(enc) == end) {
+      *nextTokPtr = end;
+      /* indicate that this might be part of a CR/LF pair */
+      return -XML_TOK_PROLOG_S;
+    }
+    /* fall through */
+  case BT_S: case BT_LF:
+    for (;;) {
+      ptr += MINBPC(enc);
+      if (ptr == end)
+        break;
+      switch (BYTE_TYPE(enc, ptr)) {
+      case BT_S: case BT_LF:
+        break;
+      case BT_CR:
+        /* don't split CR/LF pair */
+        if (ptr + MINBPC(enc) != end)
+          break;
+        /* fall through */
+      default:
+        *nextTokPtr = ptr;
+        return XML_TOK_PROLOG_S;
+      }
+    }
+    *nextTokPtr = ptr;
+    return XML_TOK_PROLOG_S;
+  case BT_PERCNT:
+    return PREFIX(scanPercent)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+  case BT_COMMA:
+    *nextTokPtr = ptr + MINBPC(enc);
+    return XML_TOK_COMMA;
+  case BT_LSQB:
+    *nextTokPtr = ptr + MINBPC(enc);
+    return XML_TOK_OPEN_BRACKET;
+  case BT_RSQB:
+    ptr += MINBPC(enc);
+    if (ptr == end)
+      return -XML_TOK_CLOSE_BRACKET;
+    if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) {
+      if (ptr + MINBPC(enc) == end)
+        return XML_TOK_PARTIAL;
+      if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_GT)) {
+        *nextTokPtr = ptr + 2*MINBPC(enc);
+        return XML_TOK_COND_SECT_CLOSE;
+      }
+    }
+    *nextTokPtr = ptr;
+    return XML_TOK_CLOSE_BRACKET;
+  case BT_LPAR:
+    *nextTokPtr = ptr + MINBPC(enc);
+    return XML_TOK_OPEN_PAREN;
+  case BT_RPAR:
+    ptr += MINBPC(enc);
+    if (ptr == end)
+      return -XML_TOK_CLOSE_PAREN;
+    switch (BYTE_TYPE(enc, ptr)) {
+    case BT_AST:
+      *nextTokPtr = ptr + MINBPC(enc);
+      return XML_TOK_CLOSE_PAREN_ASTERISK;
+    case BT_QUEST:
+      *nextTokPtr = ptr + MINBPC(enc);
+      return XML_TOK_CLOSE_PAREN_QUESTION;
+    case BT_PLUS:
+      *nextTokPtr = ptr + MINBPC(enc);
+      return XML_TOK_CLOSE_PAREN_PLUS;
+    case BT_CR: case BT_LF: case BT_S:
+    case BT_GT: case BT_COMMA: case BT_VERBAR:
+    case BT_RPAR:
+      *nextTokPtr = ptr;
+      return XML_TOK_CLOSE_PAREN;
+    }
+    *nextTokPtr = ptr;
+    return XML_TOK_INVALID;
+  case BT_VERBAR:
+    *nextTokPtr = ptr + MINBPC(enc);
+    return XML_TOK_OR;
+  case BT_GT:
+    *nextTokPtr = ptr + MINBPC(enc);
+    return XML_TOK_DECL_CLOSE;
+  case BT_NUM:
+    return PREFIX(scanPoundName)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+#define LEAD_CASE(n) \
+  case BT_LEAD ## n: \
+    if (end - ptr < n) \
+      return XML_TOK_PARTIAL_CHAR; \
+    if (IS_NMSTRT_CHAR(enc, ptr, n)) { \
+      ptr += n; \
+      tok = XML_TOK_NAME; \
+      break; \
+    } \
+    if (IS_NAME_CHAR(enc, ptr, n)) { \
+      ptr += n; \
+      tok = XML_TOK_NMTOKEN; \
+      break; \
+    } \
+    *nextTokPtr = ptr; \
+    return XML_TOK_INVALID;
+    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+  case BT_NMSTRT:
+  case BT_HEX:
+    tok = XML_TOK_NAME;
+    ptr += MINBPC(enc);
+    break;
+  case BT_DIGIT:
+  case BT_NAME:
+  case BT_MINUS:
+#ifdef XML_NS
+  case BT_COLON:
+#endif
+    tok = XML_TOK_NMTOKEN;
+    ptr += MINBPC(enc);
+    break;
+  case BT_NONASCII:
+    if (IS_NMSTRT_CHAR_MINBPC(enc, ptr)) {
+      ptr += MINBPC(enc);
+      tok = XML_TOK_NAME;
+      break;
+    }
+    if (IS_NAME_CHAR_MINBPC(enc, ptr)) {
+      ptr += MINBPC(enc);
+      tok = XML_TOK_NMTOKEN;
+      break;
+    }
+    /* fall through */
+  default:
+    *nextTokPtr = ptr;
+    return XML_TOK_INVALID;
+  }
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+    case BT_GT: case BT_RPAR: case BT_COMMA:
+    case BT_VERBAR: case BT_LSQB: case BT_PERCNT:
+    case BT_S: case BT_CR: case BT_LF:
+      *nextTokPtr = ptr;
+      return tok;
+#ifdef XML_NS
+    case BT_COLON:
+      ptr += MINBPC(enc);
+      switch (tok) {
+      case XML_TOK_NAME:
+        if (ptr == end)
+          return XML_TOK_PARTIAL;
+        tok = XML_TOK_PREFIXED_NAME;
+        switch (BYTE_TYPE(enc, ptr)) {
+        CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+        default:
+          tok = XML_TOK_NMTOKEN;
+          break;
+        }
+        break;
+      case XML_TOK_PREFIXED_NAME:
+        tok = XML_TOK_NMTOKEN;
+        break;
+      }
+      break;
+#endif
+    case BT_PLUS:
+      if (tok == XML_TOK_NMTOKEN)  {
+        *nextTokPtr = ptr;
+        return XML_TOK_INVALID;
+      }
+      *nextTokPtr = ptr + MINBPC(enc);
+      return XML_TOK_NAME_PLUS;
+    case BT_AST:
+      if (tok == XML_TOK_NMTOKEN)  {
+        *nextTokPtr = ptr;
+        return XML_TOK_INVALID;
+      }
+      *nextTokPtr = ptr + MINBPC(enc);
+      return XML_TOK_NAME_ASTERISK;
+    case BT_QUEST:
+      if (tok == XML_TOK_NMTOKEN)  {
+        *nextTokPtr = ptr;
+        return XML_TOK_INVALID;
+      }
+      *nextTokPtr = ptr + MINBPC(enc);
+      return XML_TOK_NAME_QUESTION;
+    default:
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+  }
+  return -tok;
+}
+
+static int PTRCALL
+PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr,
+                          const char *end, const char **nextTokPtr)
+{
+  const char *start;
+  if (ptr == end)
+    return XML_TOK_NONE;
+  start = ptr;
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+#define LEAD_CASE(n) \
+    case BT_LEAD ## n: ptr += n; break;
+    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+    case BT_AMP:
+      if (ptr == start)
+        return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+      *nextTokPtr = ptr;
+      return XML_TOK_DATA_CHARS;
+    case BT_LT:
+      /* this is for inside entity references */
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    case BT_LF:
+      if (ptr == start) {
+        *nextTokPtr = ptr + MINBPC(enc);
+        return XML_TOK_DATA_NEWLINE;
+      }
+      *nextTokPtr = ptr;
+      return XML_TOK_DATA_CHARS;
+    case BT_CR:
+      if (ptr == start) {
+        ptr += MINBPC(enc);
+        if (ptr == end)
+          return XML_TOK_TRAILING_CR;
+        if (BYTE_TYPE(enc, ptr) == BT_LF)
+          ptr += MINBPC(enc);
+        *nextTokPtr = ptr;
+        return XML_TOK_DATA_NEWLINE;
+      }
+      *nextTokPtr = ptr;
+      return XML_TOK_DATA_CHARS;
+    case BT_S:
+      if (ptr == start) {
+        *nextTokPtr = ptr + MINBPC(enc);
+        return XML_TOK_ATTRIBUTE_VALUE_S;
+      }
+      *nextTokPtr = ptr;
+      return XML_TOK_DATA_CHARS;
+    default:
+      ptr += MINBPC(enc);
+      break;
+    }
+  }
+  *nextTokPtr = ptr;
+  return XML_TOK_DATA_CHARS;
+}
+
+static int PTRCALL
+PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr,
+                       const char *end, const char **nextTokPtr)
+{
+  const char *start;
+  if (ptr == end)
+    return XML_TOK_NONE;
+  start = ptr;
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+#define LEAD_CASE(n) \
+    case BT_LEAD ## n: ptr += n; break;
+    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+    case BT_AMP:
+      if (ptr == start)
+        return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+      *nextTokPtr = ptr;
+      return XML_TOK_DATA_CHARS;
+    case BT_PERCNT:
+      if (ptr == start) {
+        int tok =  PREFIX(scanPercent)(enc, ptr + MINBPC(enc),
+                                       end, nextTokPtr);
+        return (tok == XML_TOK_PERCENT) ? XML_TOK_INVALID : tok;
+      }
+      *nextTokPtr = ptr;
+      return XML_TOK_DATA_CHARS;
+    case BT_LF:
+      if (ptr == start) {
+        *nextTokPtr = ptr + MINBPC(enc);
+        return XML_TOK_DATA_NEWLINE;
+      }
+      *nextTokPtr = ptr;
+      return XML_TOK_DATA_CHARS;
+    case BT_CR:
+      if (ptr == start) {
+        ptr += MINBPC(enc);
+        if (ptr == end)
+          return XML_TOK_TRAILING_CR;
+        if (BYTE_TYPE(enc, ptr) == BT_LF)
+          ptr += MINBPC(enc);
+        *nextTokPtr = ptr;
+        return XML_TOK_DATA_NEWLINE;
+      }
+      *nextTokPtr = ptr;
+      return XML_TOK_DATA_CHARS;
+    default:
+      ptr += MINBPC(enc);
+      break;
+    }
+  }
+  *nextTokPtr = ptr;
+  return XML_TOK_DATA_CHARS;
+}
+
+#ifdef XML_DTD
+
+static int PTRCALL
+PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr,
+                         const char *end, const char **nextTokPtr)
+{
+  int level = 0;
+  if (MINBPC(enc) > 1) {
+    size_t n = end - ptr;
+    if (n & (MINBPC(enc) - 1)) {
+      n &= ~(MINBPC(enc) - 1);
+      end = ptr + n;
+    }
+  }
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    INVALID_CASES(ptr, nextTokPtr)
+    case BT_LT:
+      if ((ptr += MINBPC(enc)) == end)
+        return XML_TOK_PARTIAL;
+      if (CHAR_MATCHES(enc, ptr, ASCII_EXCL)) {
+        if ((ptr += MINBPC(enc)) == end)
+          return XML_TOK_PARTIAL;
+        if (CHAR_MATCHES(enc, ptr, ASCII_LSQB)) {
+          ++level;
+          ptr += MINBPC(enc);
+        }
+      }
+      break;
+    case BT_RSQB:
+      if ((ptr += MINBPC(enc)) == end)
+        return XML_TOK_PARTIAL;
+      if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) {
+        if ((ptr += MINBPC(enc)) == end)
+          return XML_TOK_PARTIAL;
+        if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+          ptr += MINBPC(enc);
+          if (level == 0) {
+            *nextTokPtr = ptr;
+            return XML_TOK_IGNORE_SECT;
+          }
+          --level;
+        }
+      }
+      break;
+    default:
+      ptr += MINBPC(enc);
+      break;
+    }
+  }
+  return XML_TOK_PARTIAL;
+}
+
+#endif /* XML_DTD */
+
+static int PTRCALL
+PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end,
+                   const char **badPtr)
+{
+  ptr += MINBPC(enc);
+  end -= MINBPC(enc);
+  for (; ptr != end; ptr += MINBPC(enc)) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    case BT_DIGIT:
+    case BT_HEX:
+    case BT_MINUS:
+    case BT_APOS:
+    case BT_LPAR:
+    case BT_RPAR:
+    case BT_PLUS:
+    case BT_COMMA:
+    case BT_SOL:
+    case BT_EQUALS:
+    case BT_QUEST:
+    case BT_CR:
+    case BT_LF:
+    case BT_SEMI:
+    case BT_EXCL:
+    case BT_AST:
+    case BT_PERCNT:
+    case BT_NUM:
+#ifdef XML_NS
+    case BT_COLON:
+#endif
+      break;
+    case BT_S:
+      if (CHAR_MATCHES(enc, ptr, ASCII_TAB)) {
+        *badPtr = ptr;
+        return 0;
+      }
+      break;
+    case BT_NAME:
+    case BT_NMSTRT:
+      if (!(BYTE_TO_ASCII(enc, ptr) & ~0x7f))
+        break;
+    default:
+      switch (BYTE_TO_ASCII(enc, ptr)) {
+      case 0x24: /* $ */
+      case 0x40: /* @ */
+        break;
+      default:
+        *badPtr = ptr;
+        return 0;
+      }
+      break;
+    }
+  }
+  return 1;
+}
+
+/* This must only be called for a well-formed start-tag or empty
+   element tag.  Returns the number of attributes.  Pointers to the
+   first attsMax attributes are stored in atts.
+*/
+
+static int PTRCALL
+PREFIX(getAtts)(const ENCODING *enc, const char *ptr,
+                int attsMax, ATTRIBUTE *atts)
+{
+  enum { other, inName, inValue } state = inName;
+  int nAtts = 0;
+  int open = 0; /* defined when state == inValue;
+                   initialization just to shut up compilers */
+
+  for (ptr += MINBPC(enc);; ptr += MINBPC(enc)) {
+    switch (BYTE_TYPE(enc, ptr)) {
+#define START_NAME \
+      if (state == other) { \
+        if (nAtts < attsMax) { \
+          atts[nAtts].name = ptr; \
+          atts[nAtts].normalized = 1; \
+        } \
+        state = inName; \
+      }
+#define LEAD_CASE(n) \
+    case BT_LEAD ## n: START_NAME ptr += (n - MINBPC(enc)); break;
+    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+    case BT_NONASCII:
+    case BT_NMSTRT:
+    case BT_HEX:
+      START_NAME
+      break;
+#undef START_NAME
+    case BT_QUOT:
+      if (state != inValue) {
+        if (nAtts < attsMax)
+          atts[nAtts].valuePtr = ptr + MINBPC(enc);
+        state = inValue;
+        open = BT_QUOT;
+      }
+      else if (open == BT_QUOT) {
+        state = other;
+        if (nAtts < attsMax)
+          atts[nAtts].valueEnd = ptr;
+        nAtts++;
+      }
+      break;
+    case BT_APOS:
+      if (state != inValue) {
+        if (nAtts < attsMax)
+          atts[nAtts].valuePtr = ptr + MINBPC(enc);
+        state = inValue;
+        open = BT_APOS;
+      }
+      else if (open == BT_APOS) {
+        state = other;
+        if (nAtts < attsMax)
+          atts[nAtts].valueEnd = ptr;
+        nAtts++;
+      }
+      break;
+    case BT_AMP:
+      if (nAtts < attsMax)
+        atts[nAtts].normalized = 0;
+      break;
+    case BT_S:
+      if (state == inName)
+        state = other;
+      else if (state == inValue
+               && nAtts < attsMax
+               && atts[nAtts].normalized
+               && (ptr == atts[nAtts].valuePtr
+                   || BYTE_TO_ASCII(enc, ptr) != ASCII_SPACE
+                   || BYTE_TO_ASCII(enc, ptr + MINBPC(enc)) == ASCII_SPACE
+                   || BYTE_TYPE(enc, ptr + MINBPC(enc)) == open))
+        atts[nAtts].normalized = 0;
+      break;
+    case BT_CR: case BT_LF:
+      /* This case ensures that the first attribute name is counted
+         Apart from that we could just change state on the quote. */
+      if (state == inName)
+        state = other;
+      else if (state == inValue && nAtts < attsMax)
+        atts[nAtts].normalized = 0;
+      break;
+    case BT_GT:
+    case BT_SOL:
+      if (state != inValue)
+        return nAtts;
+      break;
+    default:
+      break;
+    }
+  }
+  /* not reached */
+}
+
+static int PTRFASTCALL
+PREFIX(charRefNumber)(const ENCODING *enc, const char *ptr)
+{
+  int result = 0;
+  /* skip &# */
+  ptr += 2*MINBPC(enc);
+  if (CHAR_MATCHES(enc, ptr, ASCII_x)) {
+    for (ptr += MINBPC(enc);
+         !CHAR_MATCHES(enc, ptr, ASCII_SEMI);
+         ptr += MINBPC(enc)) {
+      int c = BYTE_TO_ASCII(enc, ptr);
+      switch (c) {
+      case ASCII_0: case ASCII_1: case ASCII_2: case ASCII_3: case ASCII_4:
+      case ASCII_5: case ASCII_6: case ASCII_7: case ASCII_8: case ASCII_9:
+        result <<= 4;
+        result |= (c - ASCII_0);
+        break;
+      case ASCII_A: case ASCII_B: case ASCII_C:
+      case ASCII_D: case ASCII_E: case ASCII_F:
+        result <<= 4;
+        result += 10 + (c - ASCII_A);
+        break;
+      case ASCII_a: case ASCII_b: case ASCII_c:
+      case ASCII_d: case ASCII_e: case ASCII_f:
+        result <<= 4;
+        result += 10 + (c - ASCII_a);
+        break;
+      }
+      if (result >= 0x110000)
+        return -1;
+    }
+  }
+  else {
+    for (; !CHAR_MATCHES(enc, ptr, ASCII_SEMI); ptr += MINBPC(enc)) {
+      int c = BYTE_TO_ASCII(enc, ptr);
+      result *= 10;
+      result += (c - ASCII_0);
+      if (result >= 0x110000)
+        return -1;
+    }
+  }
+  return checkCharRefNumber(result);
+}
+
+static int PTRCALL
+PREFIX(predefinedEntityName)(const ENCODING *enc, const char *ptr,
+                             const char *end)
+{
+  switch ((end - ptr)/MINBPC(enc)) {
+  case 2:
+    if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_t)) {
+      switch (BYTE_TO_ASCII(enc, ptr)) {
+      case ASCII_l:
+        return ASCII_LT;
+      case ASCII_g:
+        return ASCII_GT;
+      }
+    }
+    break;
+  case 3:
+    if (CHAR_MATCHES(enc, ptr, ASCII_a)) {
+      ptr += MINBPC(enc);
+      if (CHAR_MATCHES(enc, ptr, ASCII_m)) {
+        ptr += MINBPC(enc);
+        if (CHAR_MATCHES(enc, ptr, ASCII_p))
+          return ASCII_AMP;
+      }
+    }
+    break;
+  case 4:
+    switch (BYTE_TO_ASCII(enc, ptr)) {
+    case ASCII_q:
+      ptr += MINBPC(enc);
+      if (CHAR_MATCHES(enc, ptr, ASCII_u)) {
+        ptr += MINBPC(enc);
+        if (CHAR_MATCHES(enc, ptr, ASCII_o)) {
+          ptr += MINBPC(enc);
+          if (CHAR_MATCHES(enc, ptr, ASCII_t))
+            return ASCII_QUOT;
+        }
+      }
+      break;
+    case ASCII_a:
+      ptr += MINBPC(enc);
+      if (CHAR_MATCHES(enc, ptr, ASCII_p)) {
+        ptr += MINBPC(enc);
+        if (CHAR_MATCHES(enc, ptr, ASCII_o)) {
+          ptr += MINBPC(enc);
+          if (CHAR_MATCHES(enc, ptr, ASCII_s))
+            return ASCII_APOS;
+        }
+      }
+      break;
+    }
+  }
+  return 0;
+}
+
+static int PTRCALL
+PREFIX(sameName)(const ENCODING *enc, const char *ptr1, const char *ptr2)
+{
+  for (;;) {
+    switch (BYTE_TYPE(enc, ptr1)) {
+#define LEAD_CASE(n) \
+    case BT_LEAD ## n: \
+      if (*ptr1++ != *ptr2++) \
+        return 0;
+    LEAD_CASE(4) LEAD_CASE(3) LEAD_CASE(2)
+#undef LEAD_CASE
+      /* fall through */
+      if (*ptr1++ != *ptr2++)
+        return 0;
+      break;
+    case BT_NONASCII:
+    case BT_NMSTRT:
+#ifdef XML_NS
+    case BT_COLON:
+#endif
+    case BT_HEX:
+    case BT_DIGIT:
+    case BT_NAME:
+    case BT_MINUS:
+      if (*ptr2++ != *ptr1++)
+        return 0;
+      if (MINBPC(enc) > 1) {
+        if (*ptr2++ != *ptr1++)
+          return 0;
+        if (MINBPC(enc) > 2) {
+          if (*ptr2++ != *ptr1++)
+            return 0;
+          if (MINBPC(enc) > 3) {
+            if (*ptr2++ != *ptr1++)
+              return 0;
+          }
+        }
+      }
+      break;
+    default:
+      if (MINBPC(enc) == 1 && *ptr1 == *ptr2)
+        return 1;
+      switch (BYTE_TYPE(enc, ptr2)) {
+      case BT_LEAD2:
+      case BT_LEAD3:
+      case BT_LEAD4:
+      case BT_NONASCII:
+      case BT_NMSTRT:
+#ifdef XML_NS
+      case BT_COLON:
+#endif
+      case BT_HEX:
+      case BT_DIGIT:
+      case BT_NAME:
+      case BT_MINUS:
+        return 0;
+      default:
+        return 1;
+      }
+    }
+  }
+  /* not reached */
+}
+
+static int PTRCALL
+PREFIX(nameMatchesAscii)(const ENCODING *enc, const char *ptr1,
+                         const char *end1, const char *ptr2)
+{
+  for (; *ptr2; ptr1 += MINBPC(enc), ptr2++) {
+    if (ptr1 == end1)
+      return 0;
+    if (!CHAR_MATCHES(enc, ptr1, *ptr2))
+      return 0;
+  }
+  return ptr1 == end1;
+}
+
+static int PTRFASTCALL
+PREFIX(nameLength)(const ENCODING *enc, const char *ptr)
+{
+  const char *start = ptr;
+  for (;;) {
+    switch (BYTE_TYPE(enc, ptr)) {
+#define LEAD_CASE(n) \
+    case BT_LEAD ## n: ptr += n; break;
+    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+    case BT_NONASCII:
+    case BT_NMSTRT:
+#ifdef XML_NS
+    case BT_COLON:
+#endif
+    case BT_HEX:
+    case BT_DIGIT:
+    case BT_NAME:
+    case BT_MINUS:
+      ptr += MINBPC(enc);
+      break;
+    default:
+      return (int)(ptr - start);
+    }
+  }
+}
+
+static const char * PTRFASTCALL
+PREFIX(skipS)(const ENCODING *enc, const char *ptr)
+{
+  for (;;) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    case BT_LF:
+    case BT_CR:
+    case BT_S:
+      ptr += MINBPC(enc);
+      break;
+    default:
+      return ptr;
+    }
+  }
+}
+
+static void PTRCALL
+PREFIX(updatePosition)(const ENCODING *enc,
+                       const char *ptr,
+                       const char *end,
+                       POSITION *pos)
+{
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+#define LEAD_CASE(n) \
+    case BT_LEAD ## n: \
+      ptr += n; \
+      break;
+    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+    case BT_LF:
+      pos->columnNumber = (XML_Size)-1;
+      pos->lineNumber++;
+      ptr += MINBPC(enc);
+      break;
+    case BT_CR:
+      pos->lineNumber++;
+      ptr += MINBPC(enc);
+      if (ptr != end && BYTE_TYPE(enc, ptr) == BT_LF)
+        ptr += MINBPC(enc);
+      pos->columnNumber = (XML_Size)-1;
+      break;
+    default:
+      ptr += MINBPC(enc);
+      break;
+    }
+    pos->columnNumber++;
+  }
+}
+
+#undef DO_LEAD_CASE
+#undef MULTIBYTE_CASES
+#undef INVALID_CASES
+#undef CHECK_NAME_CASE
+#undef CHECK_NAME_CASES
+#undef CHECK_NMSTRT_CASE
+#undef CHECK_NMSTRT_CASES
+

Added: vendor/Python/current/Modules/expat/xmltok_impl.h
===================================================================
--- vendor/Python/current/Modules/expat/xmltok_impl.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/expat/xmltok_impl.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,46 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file COPYING for copying permission.
+*/
+
+enum {
+  BT_NONXML,
+  BT_MALFORM,
+  BT_LT,
+  BT_AMP,
+  BT_RSQB,
+  BT_LEAD2,
+  BT_LEAD3,
+  BT_LEAD4,
+  BT_TRAIL,
+  BT_CR,
+  BT_LF,
+  BT_GT,
+  BT_QUOT,
+  BT_APOS,
+  BT_EQUALS,
+  BT_QUEST,
+  BT_EXCL,
+  BT_SOL,
+  BT_SEMI,
+  BT_NUM,
+  BT_LSQB,
+  BT_S,
+  BT_NMSTRT,
+  BT_COLON,
+  BT_HEX,
+  BT_DIGIT,
+  BT_NAME,
+  BT_MINUS,
+  BT_OTHER, /* known not to be a name or name start character */
+  BT_NONASCII, /* might be a name or name start character */
+  BT_PERCNT,
+  BT_LPAR,
+  BT_RPAR,
+  BT_AST,
+  BT_PLUS,
+  BT_COMMA,
+  BT_VERBAR
+};
+
+#include <stddef.h>

Added: vendor/Python/current/Modules/expat/xmltok_ns.c
===================================================================
--- vendor/Python/current/Modules/expat/xmltok_ns.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/expat/xmltok_ns.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,106 @@
+const ENCODING *
+NS(XmlGetUtf8InternalEncoding)(void)
+{
+  return &ns(internal_utf8_encoding).enc;
+}
+
+const ENCODING *
+NS(XmlGetUtf16InternalEncoding)(void)
+{
+#if BYTEORDER == 1234
+  return &ns(internal_little2_encoding).enc;
+#elif BYTEORDER == 4321
+  return &ns(internal_big2_encoding).enc;
+#else
+  const short n = 1;
+  return (*(const char *)&n
+          ? &ns(internal_little2_encoding).enc
+          : &ns(internal_big2_encoding).enc);
+#endif
+}
+
+static const ENCODING * const NS(encodings)[] = {
+  &ns(latin1_encoding).enc,
+  &ns(ascii_encoding).enc,
+  &ns(utf8_encoding).enc,
+  &ns(big2_encoding).enc,
+  &ns(big2_encoding).enc,
+  &ns(little2_encoding).enc,
+  &ns(utf8_encoding).enc /* NO_ENC */
+};
+
+static int PTRCALL
+NS(initScanProlog)(const ENCODING *enc, const char *ptr, const char *end,
+                   const char **nextTokPtr)
+{
+  return initScan(NS(encodings), (const INIT_ENCODING *)enc,
+                  XML_PROLOG_STATE, ptr, end, nextTokPtr);
+}
+
+static int PTRCALL
+NS(initScanContent)(const ENCODING *enc, const char *ptr, const char *end,
+                    const char **nextTokPtr)
+{
+  return initScan(NS(encodings), (const INIT_ENCODING *)enc,
+                  XML_CONTENT_STATE, ptr, end, nextTokPtr);
+}
+
+int
+NS(XmlInitEncoding)(INIT_ENCODING *p, const ENCODING **encPtr,
+                    const char *name)
+{
+  int i = getEncodingIndex(name);
+  if (i == UNKNOWN_ENC)
+    return 0;
+  SET_INIT_ENC_INDEX(p, i);
+  p->initEnc.scanners[XML_PROLOG_STATE] = NS(initScanProlog);
+  p->initEnc.scanners[XML_CONTENT_STATE] = NS(initScanContent);
+  p->initEnc.updatePosition = initUpdatePosition;
+  p->encPtr = encPtr;
+  *encPtr = &(p->initEnc);
+  return 1;
+}
+
+static const ENCODING *
+NS(findEncoding)(const ENCODING *enc, const char *ptr, const char *end)
+{
+#define ENCODING_MAX 128
+  char buf[ENCODING_MAX];
+  char *p = buf;
+  int i;
+  XmlUtf8Convert(enc, &ptr, end, &p, p + ENCODING_MAX - 1);
+  if (ptr != end)
+    return 0;
+  *p = 0;
+  if (streqci(buf, KW_UTF_16) && enc->minBytesPerChar == 2)
+    return enc;
+  i = getEncodingIndex(buf);
+  if (i == UNKNOWN_ENC)
+    return 0;
+  return NS(encodings)[i];
+}
+
+int
+NS(XmlParseXmlDecl)(int isGeneralTextEntity,
+                    const ENCODING *enc,
+                    const char *ptr,
+                    const char *end,
+                    const char **badPtr,
+                    const char **versionPtr,
+                    const char **versionEndPtr,
+                    const char **encodingName,
+                    const ENCODING **encoding,
+                    int *standalone)
+{
+  return doParseXmlDecl(NS(findEncoding),
+                        isGeneralTextEntity,
+                        enc,
+                        ptr,
+                        end,
+                        badPtr,
+                        versionPtr,
+                        versionEndPtr,
+                        encodingName,
+                        encoding,
+                        standalone);
+}

Added: vendor/Python/current/Modules/fcntlmodule.c
===================================================================
--- vendor/Python/current/Modules/fcntlmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/fcntlmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,603 @@
+
+/* fcntl module */
+
+#define PY_SSIZE_T_CLEAN
+
+#include "Python.h"
+
+#ifdef HAVE_SYS_FILE_H
+#include <sys/file.h>
+#endif
+
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#ifdef HAVE_STROPTS_H
+#include <stropts.h>
+#endif
+
+static int
+conv_descriptor(PyObject *object, int *target)
+{
+    int fd = PyObject_AsFileDescriptor(object);
+
+    if (fd < 0)
+        return 0;
+    *target = fd;
+    return 1;
+}
+
+
+/* fcntl(fd, opt, [arg]) */
+
+static PyObject *
+fcntl_fcntl(PyObject *self, PyObject *args)
+{
+	int fd;
+	int code;
+	int arg;
+	int ret;
+	char *str;
+	Py_ssize_t len;
+	char buf[1024];
+
+	if (PyArg_ParseTuple(args, "O&is#:fcntl",
+                             conv_descriptor, &fd, &code, &str, &len)) {
+		if (len > sizeof buf) {
+			PyErr_SetString(PyExc_ValueError,
+					"fcntl string arg too long");
+			return NULL;
+		}
+		memcpy(buf, str, len);
+		Py_BEGIN_ALLOW_THREADS
+		ret = fcntl(fd, code, buf);
+		Py_END_ALLOW_THREADS
+		if (ret < 0) {
+			PyErr_SetFromErrno(PyExc_IOError);
+			return NULL;
+		}
+		return PyString_FromStringAndSize(buf, len);
+	}
+
+	PyErr_Clear();
+	arg = 0;
+	if (!PyArg_ParseTuple(args,
+             "O&i|i;fcntl requires a file or file descriptor,"
+             " an integer and optionally a third integer or a string", 
+			      conv_descriptor, &fd, &code, &arg)) {
+	  return NULL;
+	}
+	Py_BEGIN_ALLOW_THREADS
+	ret = fcntl(fd, code, arg);
+	Py_END_ALLOW_THREADS
+	if (ret < 0) {
+		PyErr_SetFromErrno(PyExc_IOError);
+		return NULL;
+	}
+	return PyInt_FromLong((long)ret);
+}
+
+PyDoc_STRVAR(fcntl_doc,
+"fcntl(fd, opt, [arg])\n\
+\n\
+Perform the requested operation on file descriptor fd.  The operation\n\
+is defined by op and is operating system dependent.  These constants are\n\
+available from the fcntl module.  The argument arg is optional, and\n\
+defaults to 0; it may be an int or a string. If arg is given as a string,\n\
+the return value of fcntl is a string of that length, containing the\n\
+resulting value put in the arg buffer by the operating system.The length\n\
+of the arg string is not allowed to exceed 1024 bytes. If the arg given\n\
+is an integer or if none is specified, the result value is an integer\n\
+corresponding to the return value of the fcntl call in the C code.");
+
+
+/* ioctl(fd, opt, [arg]) */
+
+static PyObject *
+fcntl_ioctl(PyObject *self, PyObject *args)
+{
+#define IOCTL_BUFSZ 1024
+	int fd;
+	/* In PyArg_ParseTuple below, use the unsigned int 'I' format for
+	   the signed int 'code' variable, because Python turns 0x8000000
+	   into a large positive number (PyLong, or PyInt on 64-bit
+	   platforms,) whereas C expects it to be a negative int */
+	int code;
+	int arg;
+	int ret;
+	char *str;
+	Py_ssize_t len;
+	int mutate_arg = 1;
+ 	char buf[IOCTL_BUFSZ+1];  /* argument plus NUL byte */
+
+	if (PyArg_ParseTuple(args, "O&Iw#|i:ioctl",
+                             conv_descriptor, &fd, &code, 
+			     &str, &len, &mutate_arg)) {
+		char *arg;
+
+	       	if (mutate_arg) {
+			if (len <= IOCTL_BUFSZ) {
+				memcpy(buf, str, len);
+				buf[len] = '\0';
+				arg = buf;
+			} 
+			else {
+				arg = str;
+			}
+		}
+		else {
+			if (len > IOCTL_BUFSZ) {
+				PyErr_SetString(PyExc_ValueError,
+					"ioctl string arg too long");
+				return NULL;
+			}
+			else {
+				memcpy(buf, str, len);
+				buf[len] = '\0';
+				arg = buf;
+			}
+		}
+		if (buf == arg) {
+			Py_BEGIN_ALLOW_THREADS /* think array.resize() */
+			ret = ioctl(fd, code, arg);
+			Py_END_ALLOW_THREADS
+		}
+		else {
+			ret = ioctl(fd, code, arg);
+		}
+		if (mutate_arg && (len < IOCTL_BUFSZ)) {
+			memcpy(str, buf, len);
+		}
+		if (ret < 0) {
+			PyErr_SetFromErrno(PyExc_IOError);
+			return NULL;
+		}
+		if (mutate_arg) {
+			return PyInt_FromLong(ret);
+		}
+		else {
+			return PyString_FromStringAndSize(buf, len);
+		}
+	}
+
+	PyErr_Clear();
+	if (PyArg_ParseTuple(args, "O&Is#:ioctl",
+                             conv_descriptor, &fd, &code, &str, &len)) {
+		if (len > IOCTL_BUFSZ) {
+			PyErr_SetString(PyExc_ValueError,
+					"ioctl string arg too long");
+			return NULL;
+		}
+		memcpy(buf, str, len);
+		buf[len] = '\0';
+		Py_BEGIN_ALLOW_THREADS
+		ret = ioctl(fd, code, buf);
+		Py_END_ALLOW_THREADS
+		if (ret < 0) {
+			PyErr_SetFromErrno(PyExc_IOError);
+			return NULL;
+		}
+		return PyString_FromStringAndSize(buf, len);
+	}
+
+	PyErr_Clear();
+	arg = 0;
+	if (!PyArg_ParseTuple(args,
+	     "O&I|i;ioctl requires a file or file descriptor,"
+	     " an integer and optionally an integer or buffer argument",
+			      conv_descriptor, &fd, &code, &arg)) {
+	  return NULL;
+	}
+	Py_BEGIN_ALLOW_THREADS
+#ifdef __VMS
+	ret = ioctl(fd, code, (void *)arg);
+#else
+	ret = ioctl(fd, code, arg);
+#endif
+	Py_END_ALLOW_THREADS
+	if (ret < 0) {
+		PyErr_SetFromErrno(PyExc_IOError);
+		return NULL;
+	}
+	return PyInt_FromLong((long)ret);
+#undef IOCTL_BUFSZ
+}
+
+PyDoc_STRVAR(ioctl_doc,
+"ioctl(fd, opt[, arg[, mutate_flag]])\n\
+\n\
+Perform the requested operation on file descriptor fd.  The operation is\n\
+defined by opt and is operating system dependent.  Typically these codes are\n\
+retrieved from the fcntl or termios library modules.\n\
+\n\
+The argument arg is optional, and defaults to 0; it may be an int or a\n\
+buffer containing character data (most likely a string or an array). \n\
+\n\
+If the argument is a mutable buffer (such as an array) and if the\n\
+mutate_flag argument (which is only allowed in this case) is true then the\n\
+buffer is (in effect) passed to the operating system and changes made by\n\
+the OS will be reflected in the contents of the buffer after the call has\n\
+returned.  The return value is the integer returned by the ioctl system\n\
+call.\n\
+\n\
+If the argument is a mutable buffer and the mutable_flag argument is not\n\
+passed or is false, the behavior is as if a string had been passed.  This\n\
+behavior will change in future releases of Python.\n\
+\n\
+If the argument is an immutable buffer (most likely a string) then a copy\n\
+of the buffer is passed to the operating system and the return value is a\n\
+string of the same length containing whatever the operating system put in\n\
+the buffer.  The length of the arg buffer in this case is not allowed to\n\
+exceed 1024 bytes.\n\
+\n\
+If the arg given is an integer or if none is specified, the result value is\n\
+an integer corresponding to the return value of the ioctl call in the C\n\
+code.");
+
+
+/* flock(fd, operation) */
+
+static PyObject *
+fcntl_flock(PyObject *self, PyObject *args)
+{
+	int fd;
+	int code;
+	int ret;
+
+	if (!PyArg_ParseTuple(args, "O&i:flock",
+                              conv_descriptor, &fd, &code))
+		return NULL;
+
+#ifdef HAVE_FLOCK
+	Py_BEGIN_ALLOW_THREADS
+	ret = flock(fd, code);
+	Py_END_ALLOW_THREADS
+#else
+
+#ifndef LOCK_SH
+#define LOCK_SH		1	/* shared lock */
+#define LOCK_EX		2	/* exclusive lock */
+#define LOCK_NB		4	/* don't block when locking */
+#define LOCK_UN		8	/* unlock */
+#endif
+	{
+		struct flock l;
+		if (code == LOCK_UN)
+			l.l_type = F_UNLCK;
+		else if (code & LOCK_SH)
+			l.l_type = F_RDLCK;
+		else if (code & LOCK_EX)
+			l.l_type = F_WRLCK;
+		else {
+			PyErr_SetString(PyExc_ValueError,
+					"unrecognized flock argument");
+			return NULL;
+		}
+		l.l_whence = l.l_start = l.l_len = 0;
+		Py_BEGIN_ALLOW_THREADS
+		ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
+		Py_END_ALLOW_THREADS
+	}
+#endif /* HAVE_FLOCK */
+	if (ret < 0) {
+		PyErr_SetFromErrno(PyExc_IOError);
+		return NULL;
+	}
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(flock_doc,
+"flock(fd, operation)\n\
+\n\
+Perform the lock operation op on file descriptor fd.  See the Unix \n\
+manual page for flock(3) for details.  (On some systems, this function is\n\
+emulated using fcntl().)");
+
+
+/* lockf(fd, operation) */
+static PyObject *
+fcntl_lockf(PyObject *self, PyObject *args)
+{
+	int fd, code, ret, whence = 0;
+	PyObject *lenobj = NULL, *startobj = NULL;
+
+	if (!PyArg_ParseTuple(args, "O&i|OOi:lockf",
+                              conv_descriptor, &fd, &code,
+			      &lenobj, &startobj, &whence))
+	    return NULL;
+
+#if defined(PYOS_OS2) && defined(PYCC_GCC)
+	PyErr_SetString(PyExc_NotImplementedError,
+			"lockf not supported on OS/2 (EMX)");
+	return NULL;
+#else
+#ifndef LOCK_SH
+#define LOCK_SH		1	/* shared lock */
+#define LOCK_EX		2	/* exclusive lock */
+#define LOCK_NB		4	/* don't block when locking */
+#define LOCK_UN		8	/* unlock */
+#endif  /* LOCK_SH */
+	{
+		struct flock l;
+		if (code == LOCK_UN)
+			l.l_type = F_UNLCK;
+		else if (code & LOCK_SH)
+			l.l_type = F_RDLCK;
+		else if (code & LOCK_EX)
+			l.l_type = F_WRLCK;
+		else {
+			PyErr_SetString(PyExc_ValueError,
+					"unrecognized lockf argument");
+			return NULL;
+		}
+		l.l_start = l.l_len = 0;
+		if (startobj != NULL) {
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+			l.l_start = PyInt_AsLong(startobj);
+#else
+			l.l_start = PyLong_Check(startobj) ?
+					PyLong_AsLongLong(startobj) :
+					PyInt_AsLong(startobj);
+#endif
+			if (PyErr_Occurred())
+				return NULL;
+		}
+		if (lenobj != NULL) {
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+			l.l_len = PyInt_AsLong(lenobj);
+#else
+			l.l_len = PyLong_Check(lenobj) ?
+					PyLong_AsLongLong(lenobj) :
+					PyInt_AsLong(lenobj);
+#endif
+			if (PyErr_Occurred())
+				return NULL;
+		}
+		l.l_whence = whence;
+		Py_BEGIN_ALLOW_THREADS
+		ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
+		Py_END_ALLOW_THREADS
+	}
+	if (ret < 0) {
+		PyErr_SetFromErrno(PyExc_IOError);
+		return NULL;
+	}
+	Py_INCREF(Py_None);
+	return Py_None;
+#endif  /* defined(PYOS_OS2) && defined(PYCC_GCC) */
+}
+
+PyDoc_STRVAR(lockf_doc,
+"lockf (fd, operation, length=0, start=0, whence=0)\n\
+\n\
+This is essentially a wrapper around the fcntl() locking calls.  fd is the\n\
+file descriptor of the file to lock or unlock, and operation is one of the\n\
+following values:\n\
+\n\
+    LOCK_UN - unlock\n\
+    LOCK_SH - acquire a shared lock\n\
+    LOCK_EX - acquire an exclusive lock\n\
+\n\
+When operation is LOCK_SH or LOCK_EX, it can also be bit-wise OR'd with\n\
+LOCK_NB to avoid blocking on lock acquisition.  If LOCK_NB is used and the\n\
+lock cannot be acquired, an IOError will be raised and the exception will\n\
+have an errno attribute set to EACCES or EAGAIN (depending on the operating\n\
+system -- for portability, check for either value).\n\
+\n\
+length is the number of bytes to lock, with the default meaning to lock to\n\
+EOF.  start is the byte offset, relative to whence, to that the lock\n\
+starts.  whence is as with fileobj.seek(), specifically:\n\
+\n\
+    0 - relative to the start of the file (SEEK_SET)\n\
+    1 - relative to the current buffer position (SEEK_CUR)\n\
+    2 - relative to the end of the file (SEEK_END)");
+
+/* List of functions */
+
+static PyMethodDef fcntl_methods[] = {
+	{"fcntl",	fcntl_fcntl, METH_VARARGS, fcntl_doc},
+	{"ioctl",	fcntl_ioctl, METH_VARARGS, ioctl_doc},
+	{"flock",	fcntl_flock, METH_VARARGS, flock_doc},
+	{"lockf",       fcntl_lockf, METH_VARARGS, lockf_doc},
+	{NULL,		NULL}		/* sentinel */
+};
+
+
+PyDoc_STRVAR(module_doc,
+"This module performs file control and I/O control on file \n\
+descriptors.  It is an interface to the fcntl() and ioctl() Unix\n\
+routines.  File descriptors can be obtained with the fileno() method of\n\
+a file or socket object.");
+
+/* Module initialisation */
+
+static int
+ins(PyObject* d, char* symbol, long value)
+{
+        PyObject* v = PyInt_FromLong(value);
+        if (!v || PyDict_SetItemString(d, symbol, v) < 0)
+                return -1;
+
+        Py_DECREF(v);
+        return 0;
+}
+
+#define INS(x) if (ins(d, #x, (long)x)) return -1
+
+static int
+all_ins(PyObject* d)
+{
+        if (ins(d, "LOCK_SH", (long)LOCK_SH)) return -1;
+        if (ins(d, "LOCK_EX", (long)LOCK_EX)) return -1;
+        if (ins(d, "LOCK_NB", (long)LOCK_NB)) return -1;
+        if (ins(d, "LOCK_UN", (long)LOCK_UN)) return -1;
+/* GNU extensions, as of glibc 2.2.4 */
+#ifdef LOCK_MAND
+        if (ins(d, "LOCK_MAND", (long)LOCK_MAND)) return -1;
+#endif
+#ifdef LOCK_READ
+        if (ins(d, "LOCK_READ", (long)LOCK_READ)) return -1;
+#endif
+#ifdef LOCK_WRITE
+        if (ins(d, "LOCK_WRITE", (long)LOCK_WRITE)) return -1;
+#endif
+#ifdef LOCK_RW
+        if (ins(d, "LOCK_RW", (long)LOCK_RW)) return -1;
+#endif
+
+#ifdef F_DUPFD
+        if (ins(d, "F_DUPFD", (long)F_DUPFD)) return -1;
+#endif
+#ifdef F_GETFD
+        if (ins(d, "F_GETFD", (long)F_GETFD)) return -1;
+#endif
+#ifdef F_SETFD
+        if (ins(d, "F_SETFD", (long)F_SETFD)) return -1;
+#endif
+#ifdef F_GETFL
+        if (ins(d, "F_GETFL", (long)F_GETFL)) return -1;
+#endif
+#ifdef F_SETFL
+        if (ins(d, "F_SETFL", (long)F_SETFL)) return -1;
+#endif
+#ifdef F_GETLK
+        if (ins(d, "F_GETLK", (long)F_GETLK)) return -1;
+#endif
+#ifdef F_SETLK
+        if (ins(d, "F_SETLK", (long)F_SETLK)) return -1;
+#endif
+#ifdef F_SETLKW
+        if (ins(d, "F_SETLKW", (long)F_SETLKW)) return -1;
+#endif
+#ifdef F_GETOWN
+        if (ins(d, "F_GETOWN", (long)F_GETOWN)) return -1;
+#endif
+#ifdef F_SETOWN
+        if (ins(d, "F_SETOWN", (long)F_SETOWN)) return -1;
+#endif
+#ifdef F_GETSIG
+        if (ins(d, "F_GETSIG", (long)F_GETSIG)) return -1;
+#endif
+#ifdef F_SETSIG
+        if (ins(d, "F_SETSIG", (long)F_SETSIG)) return -1;
+#endif
+#ifdef F_RDLCK
+        if (ins(d, "F_RDLCK", (long)F_RDLCK)) return -1;
+#endif
+#ifdef F_WRLCK
+        if (ins(d, "F_WRLCK", (long)F_WRLCK)) return -1;
+#endif
+#ifdef F_UNLCK
+        if (ins(d, "F_UNLCK", (long)F_UNLCK)) return -1;
+#endif
+/* LFS constants */
+#ifdef F_GETLK64
+        if (ins(d, "F_GETLK64", (long)F_GETLK64)) return -1;
+#endif
+#ifdef F_SETLK64
+        if (ins(d, "F_SETLK64", (long)F_SETLK64)) return -1;
+#endif
+#ifdef F_SETLKW64
+        if (ins(d, "F_SETLKW64", (long)F_SETLKW64)) return -1;
+#endif
+/* GNU extensions, as of glibc 2.2.4. */
+#ifdef F_SETLEASE
+        if (ins(d, "F_SETLEASE", (long)F_SETLEASE)) return -1;
+#endif
+#ifdef F_GETLEASE
+        if (ins(d, "F_GETLEASE", (long)F_GETLEASE)) return -1;
+#endif
+#ifdef F_NOTIFY
+        if (ins(d, "F_NOTIFY", (long)F_NOTIFY)) return -1;
+#endif
+/* Old BSD flock(). */
+#ifdef F_EXLCK
+        if (ins(d, "F_EXLCK", (long)F_EXLCK)) return -1;
+#endif
+#ifdef F_SHLCK
+        if (ins(d, "F_SHLCK", (long)F_SHLCK)) return -1;
+#endif
+
+/* For F_{GET|SET}FL */
+#ifdef FD_CLOEXEC
+        if (ins(d, "FD_CLOEXEC", (long)FD_CLOEXEC)) return -1;
+#endif
+
+/* For F_NOTIFY */
+#ifdef DN_ACCESS
+        if (ins(d, "DN_ACCESS", (long)DN_ACCESS)) return -1;
+#endif
+#ifdef DN_MODIFY
+        if (ins(d, "DN_MODIFY", (long)DN_MODIFY)) return -1;
+#endif
+#ifdef DN_CREATE
+        if (ins(d, "DN_CREATE", (long)DN_CREATE)) return -1;
+#endif
+#ifdef DN_DELETE
+        if (ins(d, "DN_DELETE", (long)DN_DELETE)) return -1;
+#endif
+#ifdef DN_RENAME
+        if (ins(d, "DN_RENAME", (long)DN_RENAME)) return -1;
+#endif
+#ifdef DN_ATTRIB
+        if (ins(d, "DN_ATTRIB", (long)DN_ATTRIB)) return -1;
+#endif
+#ifdef DN_MULTISHOT
+        if (ins(d, "DN_MULTISHOT", (long)DN_MULTISHOT)) return -1;
+#endif
+
+#ifdef HAVE_STROPTS_H
+	/* Unix 98 guarantees that these are in stropts.h. */
+	INS(I_PUSH);
+	INS(I_POP);
+	INS(I_LOOK);
+	INS(I_FLUSH);
+	INS(I_FLUSHBAND);
+	INS(I_SETSIG);
+	INS(I_GETSIG);
+	INS(I_FIND);
+	INS(I_PEEK);
+	INS(I_SRDOPT);
+	INS(I_GRDOPT);
+	INS(I_NREAD);
+	INS(I_FDINSERT);
+	INS(I_STR);
+	INS(I_SWROPT);
+#ifdef I_GWROPT
+	/* despite the comment above, old-ish glibcs miss a couple... */
+	INS(I_GWROPT);
+#endif
+	INS(I_SENDFD);
+	INS(I_RECVFD);
+	INS(I_LIST);
+	INS(I_ATMARK);
+	INS(I_CKBAND);
+	INS(I_GETBAND);
+	INS(I_CANPUT);
+	INS(I_SETCLTIME);
+#ifdef I_GETCLTIME
+	INS(I_GETCLTIME);
+#endif
+	INS(I_LINK);
+	INS(I_UNLINK);
+	INS(I_PLINK);
+	INS(I_PUNLINK);
+#endif
+	
+	return 0;
+}
+
+PyMODINIT_FUNC
+initfcntl(void)
+{
+	PyObject *m, *d;
+
+	/* Create the module and add the functions and documentation */
+	m = Py_InitModule3("fcntl", fcntl_methods, module_doc);
+	if (m == NULL)
+		return;
+
+	/* Add some symbolic constants to the module */
+	d = PyModule_GetDict(m);
+	all_ins(d);
+}

Added: vendor/Python/current/Modules/flmodule.c
===================================================================
--- vendor/Python/current/Modules/flmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/flmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2139 @@
+/* FL module -- interface to Mark Overmars' FORMS Library. */
+
+/* This code works with FORMS version 2.2 (if you defined
+   OBSOLETE_FORMS_CALLS), and 2.3.
+   FORMS can be ftp'ed from ftp.cs.ruu.nl (131.211.80.17), directory
+   /pub/SGI/FORMS. */
+
+/* A half-hearted attempt has been made to allow programs using this
+ * module to exploit parallelism (through the threads module). No provisions
+ * have been made for multiple threads to use this module at the same time,
+ * though. So, a program with a forms thread and a non-forms thread will work
+ * fine but a program with two threads using forms will probably crash (unless
+ * the program takes precaution to ensure that only one thread can be in
+ * this module at any time). This will have to be fixed some time.
+ * (A fix will probably also have to synchronize with the gl module).
+ */
+
+#include "Python.h"
+#include "forms.h"
+#include "structmember.h"
+
+/* Generic Forms Objects */
+
+typedef struct {
+	PyObject_HEAD
+	FL_OBJECT *ob_generic;
+	PyMethodDef *ob_methods;
+	PyObject *ob_callback;
+	PyObject *ob_callback_arg;
+} genericobject;
+
+static PyTypeObject GenericObjecttype;
+
+#define is_genericobject(g) ((g)->ob_type == &GenericObjecttype)
+
+/* List of all objects (XXX this should be a hash table on address...) */
+
+static PyObject *allgenerics = NULL;
+static int nfreeslots = 0;
+
+/* Add an object to the list of known objects */
+
+static void
+knowgeneric(genericobject *g)
+{
+	int i, n;
+	/* Create the list if it doesn't already exist */
+	if (allgenerics == NULL) {
+		allgenerics = PyList_New(0);
+		if (allgenerics == NULL) {
+			PyErr_Clear();
+			return; /* Too bad, live without allgenerics... */
+		}
+	}
+	if (nfreeslots > 0) {
+		/* Search the list for reusable slots (NULL items) */
+		/* XXX This can be made faster! */
+		n = PyList_Size(allgenerics);
+		for (i = 0; i < n; i++) {
+			if (PyList_GetItem(allgenerics, i) == NULL) {
+				Py_INCREF(g);
+				PyList_SetItem(allgenerics, i, (PyObject *)g);
+				nfreeslots--;
+				return;
+			}
+		}
+		/* Strange... no free slots found... */
+		nfreeslots = 0;
+	}
+	/* No free entries, append new item to the end */
+	PyList_Append(allgenerics, (PyObject *)g);
+}
+
+/* Find an object in the list of known objects */
+
+static genericobject *
+findgeneric(FL_OBJECT *generic)
+{
+	int i, n;
+	genericobject *g;
+	
+	if (allgenerics == NULL)
+		return NULL; /* No objects known yet */
+	n = PyList_Size(allgenerics);
+	for (i = 0; i < n; i++) {
+		g = (genericobject *)PyList_GetItem(allgenerics, i);
+		if (g != NULL && g->ob_generic == generic)
+			return g;
+	}
+	return NULL; /* Unknown object */
+}
+
+/* Remove an object from the list of known objects */
+
+static void
+forgetgeneric(genericobject *g)
+{
+	int i, n;
+	
+	Py_XDECREF(g->ob_callback);
+	g->ob_callback = NULL;
+	Py_XDECREF(g->ob_callback_arg);
+	g->ob_callback_arg = NULL;
+	if (allgenerics == NULL)
+		return; /* No objects known yet */
+	n = PyList_Size(allgenerics);
+	for (i = 0; i < n; i++) {
+		if (g == (genericobject *)PyList_GetItem(allgenerics, i)) {
+			PyList_SetItem(allgenerics, i, (PyObject *)NULL);
+			nfreeslots++;
+			break;
+		}
+	}
+}
+
+/* Called when a form is about to be freed --
+   remove all the objects that we know about from it. */
+
+static void
+releaseobjects(FL_FORM *form)
+{
+	int i, n;
+	genericobject *g;
+	
+	if (allgenerics == NULL)
+		return; /* No objects known yet */
+	n = PyList_Size(allgenerics);
+	for (i = 0; i < n; i++) {
+		g = (genericobject *)PyList_GetItem(allgenerics, i);
+		if (g != NULL && g->ob_generic->form == form) {
+			fl_delete_object(g->ob_generic);
+			/* The object is now unreachable for
+			   do_forms and check_forms, so
+			   delete it from the list of known objects */
+			Py_XDECREF(g->ob_callback);
+			g->ob_callback = NULL;
+			Py_XDECREF(g->ob_callback_arg);
+			g->ob_callback_arg = NULL;
+			PyList_SetItem(allgenerics, i, (PyObject *)NULL);
+			nfreeslots++;
+		}
+	}
+}
+
+
+/* Methods of generic objects */
+
+static PyObject *
+generic_set_call_back(genericobject *g, PyObject *args)
+{
+	if (PyTuple_GET_SIZE(args) == 0) {
+		Py_XDECREF(g->ob_callback);
+		Py_XDECREF(g->ob_callback_arg);
+		g->ob_callback = NULL;
+		g->ob_callback_arg = NULL;
+	}
+	else {
+        PyObject *a, *b;
+        if (!PyArg_UnpackTuple(args, "set_call_back", 2, 2, &a, &b)
+            return NULL;
+		Py_XDECREF(g->ob_callback);
+		Py_XDECREF(g->ob_callback_arg);
+		g->ob_callback = a;
+		Py_INCREF(g->ob_callback);
+		g->ob_callback_arg = b;
+		Py_INCREF(g->ob_callback_arg);
+	}
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+generic_call(genericobject *g, void (*func)(FL_OBJECT *))
+{
+	(*func)(g->ob_generic);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+generic_delete_object(genericobject *g)
+{
+	PyObject *res;
+	res = generic_call(g, fl_delete_object);
+	if (res != NULL)
+		forgetgeneric(g);
+	return res;
+}
+
+static PyObject *
+generic_show_object(genericobject *g)
+{
+	return generic_call(g, fl_show_object);
+}
+
+static PyObject *
+generic_hide_object(genericobject *g)
+{
+	return generic_call(g, fl_hide_object);
+}
+
+static PyObject *
+generic_redraw_object(genericobject *g)
+{
+	return generic_call(g, fl_redraw_object);
+}
+
+#ifdef OBSOLETE_FORMS_CALLS
+ 
+ /* (un)freeze_object() are obsolete in FORMS 2.2 and unsupported
+    in 2.3.  Since there's no foolproof way to tell which version we're
+    using, we omit them unconditionally. */
+ 
+static PyObject *
+generic_freeze_object(genericobject *g)
+{
+	return generic_call(g, fl_freeze_object);
+}
+
+static PyObject *
+generic_unfreeze_object(genericobject *g)
+{
+	return generic_call(g, fl_unfreeze_object);
+}
+
+#endif /* OBSOLETE_FORMS_CALLS */
+
+static PyObject *
+generic_activate_object(genericobject *g)
+{
+	return generic_call(g, fl_activate_object);
+}
+
+static PyObject *
+generic_deactivate_object(genericobject *g)
+{
+	return generic_call(g, fl_deactivate_object);
+}
+
+static PyObject *
+generic_set_object_shortcut(genericobject *g, PyObject *args)
+{
+	char *str;
+	if (!PyArg_ParseTuple(args, "s:set_object_shortcut", &str))
+		return NULL;
+	fl_set_object_shortcut(g->ob_generic, str);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyMethodDef generic_methods[] = {
+	{"set_call_back",	(PyCFunction)generic_set_call_back, METH_VARARGS},
+	{"delete_object",	(PyCFunction)generic_delete_object, METH_NOARGS},
+	{"show_object",		(PyCFunction)generic_show_object, METH_NOARGS},
+	{"hide_object",		(PyCFunction)generic_hide_object, METH_NOARGS},
+	{"redraw_object",	(PyCFunction)generic_redraw_object, METH_NOARGS},
+#ifdef OBSOLETE_FORMS_CALLS
+	{"freeze_object",	(PyCFunction)generic_freeze_object, METH_NOARGS},
+	{"unfreeze_object",	(PyCFunction)generic_unfreeze_object, METH_NOARGS},
+#endif
+	{"activate_object",	(PyCFunction)generic_activate_object, METH_NOARGS},
+	{"deactivate_object",	(PyCFunction)generic_deactivate_object, METH_NOARGS},
+	{"set_object_shortcut",	(PyCFunction)generic_set_object_shortcut, METH_VARARGS},
+	{NULL,			NULL}		/* sentinel */
+};
+
+static void
+generic_dealloc(genericobject *g)
+{
+	fl_free_object(g->ob_generic);
+	Py_XDECREF(g->ob_callback);
+	Py_XDECREF(g->ob_callback_arg);
+	PyObject_Del(g);
+}
+
+#define OFF(x) offsetof(FL_OBJECT, x)
+
+static struct memberlist generic_memberlist[] = {
+	{"objclass",	T_INT,		OFF(objclass),	RO},
+	{"type",	T_INT,		OFF(type),	RO},
+	{"boxtype",	T_INT,		OFF(boxtype)},
+	{"x",		T_FLOAT,	OFF(x)},
+	{"y",		T_FLOAT,	OFF(y)},
+	{"w",		T_FLOAT,	OFF(w)},
+	{"h",		T_FLOAT,	OFF(h)},
+	{"col1",	T_INT,		OFF(col1)},
+	{"col2",	T_INT,		OFF(col2)},
+	{"align",	T_INT,		OFF(align)},
+	{"lcol",	T_INT,		OFF(lcol)},
+	{"lsize",	T_FLOAT,	OFF(lsize)},
+	/* "label" is treated specially! */
+	{"lstyle",	T_INT,		OFF(lstyle)},
+	{"pushed",	T_INT,		OFF(pushed),	RO},
+	{"focus",	T_INT,		OFF(focus),	RO},
+	{"belowmouse",	T_INT,		OFF(belowmouse),RO},
+/*	{"frozen",	T_INT,		OFF(frozen),	RO},	*/
+	{"active",	T_INT,		OFF(active)},
+	{"input",	T_INT,		OFF(input)},
+	{"visible",	T_INT,		OFF(visible),	RO},
+	{"radio",	T_INT,		OFF(radio)},
+	{"automatic",	T_INT,		OFF(automatic)},
+	{NULL}	/* Sentinel */
+};
+
+#undef OFF
+
+static PyObject *
+generic_getattr(genericobject *g, char *name)
+{
+	PyObject *meth;
+
+	/* XXX Ought to special-case name "__methods__" */
+	if (g-> ob_methods) {
+		meth = Py_FindMethod(g->ob_methods, (PyObject *)g, name);
+		if (meth != NULL) return meth;
+		PyErr_Clear();
+	}
+
+	meth = Py_FindMethod(generic_methods, (PyObject *)g, name);
+	if (meth != NULL)
+		return meth;
+	PyErr_Clear();
+
+	/* "label" is an exception, getmember only works for char pointers,
+	   not for char arrays */
+	if (strcmp(name, "label") == 0)
+		return PyString_FromString(g->ob_generic->label);
+
+	return PyMember_Get((char *)g->ob_generic, generic_memberlist, name);
+}
+
+static int
+generic_setattr(genericobject *g, char *name, PyObject *v)
+{
+	int ret;
+
+	if (v == NULL) {
+		PyErr_SetString(PyExc_TypeError,
+				"can't delete forms object attributes");
+		return -1;
+	}
+
+	/* "label" is an exception: setmember doesn't set strings;
+	   and FORMS wants you to call a function to set the label */
+	if (strcmp(name, "label") == 0) {
+		if (!PyString_Check(v)) {
+			PyErr_SetString(PyExc_TypeError,
+					"label attr must be string");
+			return -1;
+		}
+		fl_set_object_label(g->ob_generic, PyString_AsString(v));
+		return 0;
+	}
+
+	ret = PyMember_Set((char *)g->ob_generic, generic_memberlist, name, v);
+
+	/* Rather than calling all the various set_object_* functions,
+	   we call fl_redraw_object here.  This is sometimes redundant
+	   but I doubt that's a big problem */
+	if (ret == 0)
+		fl_redraw_object(g->ob_generic);
+
+	return ret;
+}
+
+static PyObject *
+generic_repr(genericobject *g)
+{
+	char buf[100];
+	PyOS_snprintf(buf, sizeof(buf), "<FORMS_object at %p, objclass=%d>",
+		      g, g->ob_generic->objclass);
+	return PyString_FromString(buf);
+}
+
+static PyTypeObject GenericObjecttype = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,				/*ob_size*/
+	"fl.FORMS_object",		/*tp_name*/
+	sizeof(genericobject),		/*tp_size*/
+	0,				/*tp_itemsize*/
+	/* methods */
+	(destructor)generic_dealloc,	/*tp_dealloc*/
+	0,				/*tp_print*/
+	(getattrfunc)generic_getattr,	/*tp_getattr*/
+	(setattrfunc)generic_setattr,	/*tp_setattr*/
+	0,				/*tp_compare*/
+	(reprfunc)generic_repr,		/*tp_repr*/
+};
+
+static PyObject *
+newgenericobject(FL_OBJECT *generic, PyMethodDef *methods)
+{
+	genericobject *g;
+	g = PyObject_New(genericobject, &GenericObjecttype);
+	if (g == NULL)
+		return NULL;
+	g-> ob_generic = generic;
+	g->ob_methods = methods;
+	g->ob_callback = NULL;
+	g->ob_callback_arg = NULL;
+	knowgeneric(g);
+	return (PyObject *)g;
+}
+
+/**********************************************************************/
+/* Some common calling sequences */
+
+/* void func (object, float) */
+static PyObject *
+call_forms_INf (void (*func)(FL_OBJECT *, float), FL_OBJECT *obj, PyObject *args)
+{
+	float parameter;
+
+	if (!PyArg_Parse(args, "f", &parameter)) return NULL;
+
+	(*func) (obj, parameter);
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void func (object, float) */
+static PyObject *
+call_forms_INfINf (void (*func)(FL_OBJECT *, float, float), FL_OBJECT *obj, PyObject *args)
+{
+	float par1, par2;
+
+	if (!PyArg_Parse(args, "(ff)", &par1, &par2)) return NULL;
+
+	(*func) (obj, par1, par2);
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void func (object, int) */
+static PyObject *
+call_forms_INi (void (*func)(FL_OBJECT *, int), FL_OBJECT *obj, PyObject *args)
+{
+	int parameter;
+
+	if (!PyArg_Parse(args, "i", &parameter)) return NULL;
+
+	(*func) (obj, parameter);
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void func (object, char) */
+static PyObject *
+call_forms_INc (void (*func)(FL_OBJECT *, int), FL_OBJECT *obj, PyObject *args)
+{
+	char *a;
+
+	if (!PyArg_Parse(args, "s", &a)) return NULL;
+
+	(*func) (obj, a[0]);
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void func (object, string) */
+static PyObject *
+call_forms_INstr (void (*func)(FL_OBJECT *, char *), FL_OBJECT *obj, PyObject *args)
+{
+	char *a;
+
+	if (!PyArg_Parse(args, "s", &a)) return NULL;
+
+	(*func) (obj, a);
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+
+/* void func (object, int, string) */
+static PyObject *
+call_forms_INiINstr (void (*func)(FL_OBJECT *, int, char *), FL_OBJECT *obj, PyObject *args)
+{
+	char *b;
+	int a;
+	
+	if (!PyArg_Parse(args, "(is)", &a, &b)) return NULL;
+	
+	(*func) (obj, a, b);
+	
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+#ifdef UNUSED
+/* void func (object, int, int) */
+static PyObject *
+call_forms_INiINi (void (*func)(FL_OBJECT *, int, int), FL_OBJECT *obj, PyObject *args)
+{
+	int par1, par2;
+	
+	if (!PyArg_Parse(args, "(ii)", &par1, &par2)) return NULL;
+	
+	(*func) (obj, par1, par2);
+	
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+#endif
+
+/* int func (object) */
+static PyObject *
+call_forms_Ri (int (*func)(FL_OBJECT *), FL_OBJECT *obj)
+{
+	int retval;
+
+	retval = (*func) (obj);
+
+	return PyInt_FromLong ((long) retval);
+}
+
+/* char * func (object) */
+static PyObject *
+call_forms_Rstr (char * (*func)(FL_OBJECT *), FL_OBJECT *obj)
+{
+	char *str;
+
+	str = (*func) (obj);
+
+	if (str == NULL) {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+	return PyString_FromString (str);
+}
+
+/* int func (object) */
+static PyObject *
+call_forms_Rf (float (*func)(FL_OBJECT *), FL_OBJECT *obj)
+{
+	float retval;
+
+	retval = (*func) (obj);
+
+	return PyFloat_FromDouble (retval);
+}
+
+static PyObject *
+call_forms_OUTfOUTf (void (*func)(FL_OBJECT *, float *, float *), FL_OBJECT *obj)
+{
+	float f1, f2;
+
+	(*func) (obj, &f1, &f2);
+
+	return Py_BuildValue("(ff)", f1, f2);
+}
+
+#ifdef UNUSED
+static PyObject *
+call_forms_OUTf (void (*func)(FL_OBJECT *, float *), FL_OBJECT *obj)
+{
+	float f;
+
+	(*func) (obj, &f);
+
+	return PyFloat_FromDouble (f);
+}
+#endif
+
+/**********************************************************************/
+/* Class : browser */
+
+static PyObject *
+set_browser_topline(genericobject *g, PyObject *args)
+{
+	return call_forms_INi (fl_set_browser_topline, g-> ob_generic, args);
+}
+
+static PyObject *
+clear_browser(genericobject *g)
+{
+	return generic_call (g, fl_clear_browser);
+}
+
+static PyObject *
+add_browser_line (genericobject *g, PyObject *args)
+{
+	return call_forms_INstr (fl_add_browser_line, g-> ob_generic, args);
+}
+
+static PyObject *
+addto_browser (genericobject *g, PyObject *args)
+{
+	return call_forms_INstr (fl_addto_browser, g-> ob_generic, args);
+}
+
+static PyObject *
+insert_browser_line (genericobject *g, PyObject *args)
+{
+	return call_forms_INiINstr (fl_insert_browser_line,
+				    g-> ob_generic, args);
+}
+
+static PyObject *
+delete_browser_line (genericobject *g, PyObject *args)
+{
+	return call_forms_INi (fl_delete_browser_line, g-> ob_generic, args);
+}
+
+static PyObject *
+replace_browser_line (genericobject *g, PyObject *args)
+{
+	return call_forms_INiINstr (fl_replace_browser_line,
+				    g-> ob_generic, args);
+}
+
+static PyObject *
+get_browser_line(genericobject *g, PyObject *args)
+{
+	int i;
+	char *str;
+
+	if (!PyArg_Parse(args, "i", &i))
+		return NULL;
+
+	str = fl_get_browser_line (g->ob_generic, i);
+
+	if (str == NULL) {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+	return PyString_FromString (str);
+}
+
+static PyObject *
+load_browser (genericobject *g, PyObject *args)
+{
+	/* XXX strictly speaking this is wrong since fl_load_browser
+	   XXX returns int, not void */
+	return call_forms_INstr (fl_load_browser, g-> ob_generic, args);
+}
+
+static PyObject *
+get_browser_maxline(genericobject *g)
+{
+	return call_forms_Ri (fl_get_browser_maxline, g-> ob_generic);
+}
+
+static PyObject *
+select_browser_line (genericobject *g, PyObject *args)
+{
+	return call_forms_INi (fl_select_browser_line, g-> ob_generic, args);
+}
+
+static PyObject *
+deselect_browser_line (genericobject *g, PyObject *args)
+{
+	return call_forms_INi (fl_deselect_browser_line, g-> ob_generic, args);
+}
+
+static PyObject *
+deselect_browser (genericobject *g)
+{
+	return generic_call (g, fl_deselect_browser);
+}
+
+static PyObject *
+isselected_browser_line (genericobject *g, PyObject *args)
+{
+	int i, j;
+	
+	if (!PyArg_Parse(args, "i", &i))
+		return NULL;
+	
+	j = fl_isselected_browser_line (g->ob_generic, i);
+	
+	return PyInt_FromLong (j);
+}
+
+static PyObject *
+get_browser (genericobject *g)
+{
+	return call_forms_Ri (fl_get_browser, g-> ob_generic);
+}
+
+static PyObject *
+set_browser_fontsize (genericobject *g, PyObject *args)
+{
+	return call_forms_INf (fl_set_browser_fontsize, g-> ob_generic, args);
+}
+
+static PyObject *
+set_browser_fontstyle (genericobject *g, PyObject *args)
+{
+	return call_forms_INi (fl_set_browser_fontstyle, g-> ob_generic, args);
+}
+
+static PyObject *
+set_browser_specialkey (genericobject *g, PyObject *args)
+{
+	return call_forms_INc(fl_set_browser_specialkey, g-> ob_generic, args);
+}
+
+static PyMethodDef browser_methods[] = {
+	{"set_browser_topline",		(PyCFunction)set_browser_topline,
+	 METH_OLDARGS},
+	{"clear_browser",		(PyCFunction)clear_browser,
+	 METH_NOARGS},
+	{"add_browser_line",		(PyCFunction)add_browser_line,
+	 METH_OLDARGS},
+	{"addto_browser",		(PyCFunction)addto_browser,
+	 METH_OLDARGS},
+	{"insert_browser_line",		(PyCFunction)insert_browser_line,
+	 METH_OLDARGS},
+	{"delete_browser_line",		(PyCFunction)delete_browser_line,
+	 METH_OLDARGS},
+	{"replace_browser_line",	(PyCFunction)replace_browser_line,
+	 METH_OLDARGS},
+	{"get_browser_line",		(PyCFunction)get_browser_line,
+	 METH_OLDARGS},
+	{"load_browser",		(PyCFunction)load_browser,
+	 METH_OLDARGS},
+	{"get_browser_maxline",		(PyCFunction)get_browser_maxline,
+	 METH_NOARGS,}
+	{"select_browser_line",		(PyCFunction)select_browser_line,
+	 METH_OLDARGS},
+	{"deselect_browser_line",	(PyCFunction)deselect_browser_line,
+	 METH_OLDARGS},
+	{"deselect_browser",		(PyCFunction)deselect_browser,
+	 METH_NOARGS,}
+	{"isselected_browser_line",	(PyCFunction)isselected_browser_line,
+	 METH_OLDARGS},
+	{"get_browser",			(PyCFunction)get_browser,
+	 METH_NOARGS,}
+	{"set_browser_fontsize",	(PyCFunction)set_browser_fontsize,
+	 METH_OLDARGS},
+	{"set_browser_fontstyle",	(PyCFunction)set_browser_fontstyle,
+	 METH_OLDARGS},
+	{"set_browser_specialkey",	(PyCFunction)set_browser_specialkey,
+	 METH_OLDARGS},
+	{NULL,				NULL}		/* sentinel */
+};
+
+/* Class: button */
+
+static PyObject *
+set_button(genericobject *g, PyObject *args)
+{
+	return call_forms_INi (fl_set_button, g-> ob_generic, args);
+}
+
+static PyObject *
+get_button(genericobject *g)
+{
+	return call_forms_Ri (fl_get_button, g-> ob_generic);
+}
+
+static PyObject *
+get_button_numb(genericobject *g)
+{
+	return call_forms_Ri (fl_get_button_numb, g-> ob_generic);
+}
+
+static PyObject *
+set_button_shortcut(genericobject *g, PyObject *args)
+{
+	return call_forms_INstr (fl_set_button_shortcut, g-> ob_generic, args);
+}
+
+static PyMethodDef button_methods[] = {
+	{"set_button",		(PyCFunction)set_button, METH_OLDARGS},
+	{"get_button",		(PyCFunction)get_button, METH_NOARGS},
+	{"get_button_numb",	(PyCFunction)get_button_numb, METH_NOARGS},
+	{"set_button_shortcut",	(PyCFunction)set_button_shortcut, METH_OLDARGS},
+	{NULL,			NULL}		/* sentinel */
+};
+
+/* Class: choice */
+
+static PyObject *
+set_choice(genericobject *g, PyObject *args)
+{
+	return call_forms_INi (fl_set_choice, g-> ob_generic, args);
+}
+
+static PyObject *
+get_choice(genericobject *g)
+{
+	return call_forms_Ri (fl_get_choice, g-> ob_generic);
+}
+
+static PyObject *
+clear_choice (genericobject *g)
+{
+	return generic_call (g, fl_clear_choice);
+}
+
+static PyObject *
+addto_choice (genericobject *g, PyObject *args)
+{
+	return call_forms_INstr (fl_addto_choice, g-> ob_generic, args);
+}
+
+static PyObject *
+replace_choice (genericobject *g, PyObject *args)
+{
+	return call_forms_INiINstr (fl_replace_choice, g-> ob_generic, args);
+}
+
+static PyObject *
+delete_choice (genericobject *g, PyObject *args)
+{
+	return call_forms_INi (fl_delete_choice, g-> ob_generic, args);
+}
+
+static PyObject *
+get_choice_text (genericobject *g)
+{
+	return call_forms_Rstr (fl_get_choice_text, g-> ob_generic);
+}
+
+static PyObject *
+set_choice_fontsize (genericobject *g, PyObject *args)
+{
+	return call_forms_INf (fl_set_choice_fontsize, g-> ob_generic, args);
+}
+
+static PyObject *
+set_choice_fontstyle (genericobject *g, PyObject *args)
+{
+	return call_forms_INi (fl_set_choice_fontstyle, g-> ob_generic, args);
+}
+
+static PyMethodDef choice_methods[] = {
+	{"set_choice",		(PyCFunction)set_choice,      METH_OLDARGS},
+	{"get_choice",		(PyCFunction)get_choice,      METH_NOARGS},
+	{"clear_choice",	(PyCFunction)clear_choice,    METH_NOARGS},
+	{"addto_choice",	(PyCFunction)addto_choice,    METH_OLDARGS},
+	{"replace_choice",	(PyCFunction)replace_choice,  METH_OLDARGS},
+	{"delete_choice",	(PyCFunction)delete_choice,   METH_OLDARGS},
+	{"get_choice_text",	(PyCFunction)get_choice_text, METH_NOARGS},
+	{"set_choice_fontsize", (PyCFunction)set_choice_fontsize, METH_OLDARGS},
+	{"set_choice_fontstyle",(PyCFunction)set_choice_fontstyle, METH_OLDARGS},
+	{NULL,			NULL}		/* sentinel */
+};
+
+/* Class : Clock */
+
+static PyObject *
+get_clock(genericobject *g)
+{
+	int i0, i1, i2;
+
+	fl_get_clock (g->ob_generic, &i0, &i1, &i2);
+
+	return Py_BuildValue("(iii)", i0, i1, i2);
+}
+
+static PyMethodDef clock_methods[] = {
+	{"get_clock",		(PyCFunction)get_clock, METH_NOARGS},
+	{NULL,			NULL}		/* sentinel */
+};
+
+/* CLass : Counters */
+
+static PyObject *
+get_counter_value(genericobject *g)
+{
+	return call_forms_Rf (fl_get_counter_value, g-> ob_generic);
+}
+
+static PyObject *
+set_counter_value (genericobject *g, PyObject *args)
+{
+	return call_forms_INf (fl_set_counter_value, g-> ob_generic, args);
+}
+
+static PyObject *
+set_counter_precision (genericobject *g, PyObject *args)
+{
+	return call_forms_INi (fl_set_counter_precision, g-> ob_generic, args);
+}
+
+static PyObject *
+set_counter_bounds (genericobject *g, PyObject *args)
+{
+	return call_forms_INfINf (fl_set_counter_bounds, g-> ob_generic, args);
+}
+
+static PyObject *
+set_counter_step (genericobject *g, PyObject *args)
+{
+	return call_forms_INfINf (fl_set_counter_step, g-> ob_generic, args);
+}
+
+static PyObject *
+set_counter_return (genericobject *g, PyObject *args)
+{
+	return call_forms_INi (fl_set_counter_return, g-> ob_generic, args);
+}
+
+static PyMethodDef counter_methods[] = {
+	{"set_counter_value",		(PyCFunction)set_counter_value,
+	 METH_OLDARGS},
+	{"get_counter_value",		(PyCFunction)get_counter_value,
+	 METH_NOARGS},
+	{"set_counter_bounds",		(PyCFunction)set_counter_bounds,
+	 METH_OLDARGS},
+	{"set_counter_step",		(PyCFunction)set_counter_step,
+	 METH_OLDARGS},
+	{"set_counter_precision",	(PyCFunction)set_counter_precision,
+	 METH_OLDARGS},
+	{"set_counter_return",		(PyCFunction)set_counter_return,
+	 METH_OLDARGS},
+	{NULL,				NULL}		/* sentinel */
+};
+
+
+/* Class: Dials */
+
+static PyObject *
+get_dial_value(genericobject *g)
+{
+	return call_forms_Rf (fl_get_dial_value, g-> ob_generic);
+}
+
+static PyObject *
+set_dial_value (genericobject *g, PyObject *args)
+{
+	return call_forms_INf (fl_set_dial_value, g-> ob_generic, args);
+}
+
+static PyObject *
+set_dial_bounds (genericobject *g, PyObject *args)
+{
+	return call_forms_INfINf (fl_set_dial_bounds, g-> ob_generic, args);
+}
+
+static PyObject *
+get_dial_bounds (genericobject *g)
+{
+	return call_forms_OUTfOUTf (fl_get_dial_bounds, g-> ob_generic);
+}
+
+static PyObject *
+set_dial_step (genericobject *g, PyObject *args)
+{
+	return call_forms_INf (fl_set_dial_step, g-> ob_generic, args);
+}
+
+static PyMethodDef dial_methods[] = {
+	{"set_dial_value",	(PyCFunction)set_dial_value,  METH_OLDARGS},
+	{"get_dial_value",	(PyCFunction)get_dial_value,  METH_NOARGS},
+	{"set_dial_bounds",	(PyCFunction)set_dial_bounds, METH_OLDARGS},
+	{"get_dial_bounds",	(PyCFunction)get_dial_bounds, METH_NOARGS},
+	{"set_dial_step",	(PyCFunction)set_dial_step,   METH_OLDARGS},
+	{NULL,			NULL}		/* sentinel */
+};
+
+/* Class : Input */
+
+static PyObject *
+set_input (genericobject *g, PyObject *args)
+{
+	return call_forms_INstr (fl_set_input, g-> ob_generic, args);
+}
+
+static PyObject *
+get_input (genericobject *g)
+{
+	return call_forms_Rstr (fl_get_input, g-> ob_generic);
+}
+
+static PyObject *
+set_input_color (genericobject *g, PyObject *args)
+{
+	return call_forms_INfINf (fl_set_input_color, g-> ob_generic, args);
+}
+
+static PyObject *
+set_input_return (genericobject *g, PyObject *args)
+{
+	return call_forms_INi (fl_set_input_return, g-> ob_generic, args);
+}
+
+static PyMethodDef input_methods[] = {
+	{"set_input",		(PyCFunction)set_input,        METH_OLDARGS},
+	{"get_input",		(PyCFunction)get_input,        METH_NOARGS},
+	{"set_input_color",	(PyCFunction)set_input_color,  METH_OLDARGS},
+	{"set_input_return",	(PyCFunction)set_input_return, METH_OLDARGS},
+	{NULL,			NULL}		/* sentinel */
+};
+
+
+/* Class : Menu */
+
+static PyObject *
+set_menu (genericobject *g, PyObject *args)
+{
+	return call_forms_INstr (fl_set_menu, g-> ob_generic, args);
+}
+
+static PyObject *
+get_menu (genericobject *g)
+{
+	/* XXX strictly speaking this is wrong since fl_get_menu
+	   XXX returns long, not int */
+	return call_forms_Ri (fl_get_menu, g-> ob_generic);
+}
+
+static PyObject *
+get_menu_text (genericobject *g)
+{
+	return call_forms_Rstr (fl_get_menu_text, g-> ob_generic);
+}
+
+static PyObject *
+addto_menu (genericobject *g, PyObject *args)
+{
+	return call_forms_INstr (fl_addto_menu, g-> ob_generic, args);
+}
+
+static PyMethodDef menu_methods[] = {
+	{"set_menu",		(PyCFunction)set_menu,      METH_OLDARGS},
+	{"get_menu",		(PyCFunction)get_menu,      METH_NOARGS},
+	{"get_menu_text",	(PyCFunction)get_menu_text, METH_NOARGS},
+	{"addto_menu",		(PyCFunction)addto_menu,    METH_OLDARGS},
+	{NULL,			NULL}		/* sentinel */
+};
+
+
+/* Class: Sliders */
+
+static PyObject *
+get_slider_value(genericobject *g)
+{
+	return call_forms_Rf (fl_get_slider_value, g-> ob_generic);
+}
+
+static PyObject *
+set_slider_value (genericobject *g, PyObject *args)
+{
+	return call_forms_INf (fl_set_slider_value, g-> ob_generic, args);
+}
+
+static PyObject *
+set_slider_bounds (genericobject *g, PyObject *args)
+{
+	return call_forms_INfINf (fl_set_slider_bounds, g-> ob_generic, args);
+}
+
+static PyObject *
+get_slider_bounds (genericobject *g)
+{
+	return call_forms_OUTfOUTf(fl_get_slider_bounds, g-> ob_generic);
+}
+
+static PyObject *
+set_slider_return (genericobject *g, PyObject *args)
+{
+	return call_forms_INf (fl_set_slider_return, g-> ob_generic, args);
+}
+
+static PyObject *
+set_slider_size (genericobject *g, PyObject *args)
+{
+	return call_forms_INf (fl_set_slider_size, g-> ob_generic, args);
+}
+
+static PyObject *
+set_slider_precision (genericobject *g, PyObject *args)
+{
+	return call_forms_INi (fl_set_slider_precision, g-> ob_generic, args);
+}
+
+static PyObject *
+set_slider_step (genericobject *g, PyObject *args)
+{
+	return call_forms_INf (fl_set_slider_step, g-> ob_generic, args);
+}
+
+
+static PyMethodDef slider_methods[] = {
+	{"set_slider_value",	(PyCFunction)set_slider_value,  METH_OLDARGS},
+	{"get_slider_value",	(PyCFunction)get_slider_value,  METH_NOARGS},
+	{"set_slider_bounds",	(PyCFunction)set_slider_bounds, METH_OLDARGS},
+	{"get_slider_bounds",	(PyCFunction)get_slider_bounds, METH_NOARGS},
+	{"set_slider_return",	(PyCFunction)set_slider_return, METH_OLDARGS},
+	{"set_slider_size",	(PyCFunction)set_slider_size,   METH_OLDARGS},
+	{"set_slider_precision",(PyCFunction)set_slider_precision, METH_OLDARGS},
+	{"set_slider_step",	(PyCFunction)set_slider_step,   METH_OLDARGS},
+	{NULL,			NULL}		/* sentinel */
+};
+
+static PyObject *
+set_positioner_xvalue (genericobject *g, PyObject *args)
+{
+	return call_forms_INf (fl_set_positioner_xvalue, g-> ob_generic, args);
+}
+
+static PyObject *
+set_positioner_xbounds (genericobject *g, PyObject *args)
+{
+	return call_forms_INfINf (fl_set_positioner_xbounds,
+				  g-> ob_generic, args);
+}
+
+static PyObject *
+set_positioner_yvalue (genericobject *g, PyObject *args)
+{
+	return call_forms_INf (fl_set_positioner_yvalue, g-> ob_generic, args);
+}
+
+static PyObject *
+set_positioner_ybounds (genericobject *g, PyObject *args)
+{
+	return call_forms_INfINf (fl_set_positioner_ybounds,
+				  g-> ob_generic, args);
+}
+
+static PyObject *
+get_positioner_xvalue (genericobject *g)
+{
+	return call_forms_Rf (fl_get_positioner_xvalue, g-> ob_generic);
+}
+
+static PyObject *
+get_positioner_xbounds (genericobject *g)
+{
+	return call_forms_OUTfOUTf (fl_get_positioner_xbounds, g-> ob_generic);
+}
+
+static PyObject *
+get_positioner_yvalue (genericobject *g)
+{
+	return call_forms_Rf (fl_get_positioner_yvalue, g-> ob_generic);
+}
+
+static PyObject *
+get_positioner_ybounds (genericobject *g)
+{
+	return call_forms_OUTfOUTf (fl_get_positioner_ybounds, g-> ob_generic);
+}
+
+static PyMethodDef positioner_methods[] = {
+	{"set_positioner_xvalue",	(PyCFunction)set_positioner_xvalue,
+	 METH_OLDARGS},
+	{"set_positioner_yvalue",	(PyCFunction)set_positioner_yvalue,
+	 METH_OLDARGS},
+	{"set_positioner_xbounds",	(PyCFunction)set_positioner_xbounds,
+	 METH_OLDARGS},
+	{"set_positioner_ybounds",	(PyCFunction)set_positioner_ybounds,
+	 METH_OLDARGS},
+	{"get_positioner_xvalue",	(PyCFunction)get_positioner_xvalue,
+	 METH_NOARGS},
+	{"get_positioner_yvalue",	(PyCFunction)get_positioner_yvalue,
+	 METH_NOARGS},
+	{"get_positioner_xbounds",	(PyCFunction)get_positioner_xbounds,
+	 METH_NOARGS},
+	{"get_positioner_ybounds",	(PyCFunction)get_positioner_ybounds,
+	 METH_NOARGS},
+	{NULL,			NULL}		/* sentinel */
+};
+
+/* Class timer */
+
+static PyObject *
+set_timer (genericobject *g, PyObject *args)
+{
+	return call_forms_INf (fl_set_timer, g-> ob_generic, args);
+}
+
+static PyObject *
+get_timer (genericobject *g)
+{
+	return call_forms_Rf (fl_get_timer, g-> ob_generic);
+}
+
+static PyMethodDef timer_methods[] = {
+	{"set_timer",		(PyCFunction)set_timer, METH_OLDARGS},
+	{"get_timer",		(PyCFunction)get_timer, METH_NOARGS},
+	{NULL,			NULL}		/* sentinel */
+};
+
+/* Form objects */
+
+typedef struct {
+	PyObject_HEAD
+	FL_FORM *ob_form;
+} formobject;
+
+static PyTypeObject Formtype;
+
+#define is_formobject(v) ((v)->ob_type == &Formtype)
+
+static PyObject *
+form_show_form(formobject *f, PyObject *args)
+{
+	int place, border;
+	char *name;
+	if (!PyArg_Parse(args, "(iis)", &place, &border, &name))
+		return NULL;
+	fl_show_form(f->ob_form, place, border, name);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+form_call(void (*func)(FL_FORM *), FL_FORM *f)
+{
+	(*func)(f);
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+form_call_INiINi(void (*func)(FL_FORM *, int, int), FL_FORM *f, PyObject *args)
+{
+	int a, b;
+
+	if (!PyArg_Parse(args, "(ii)", &a, &b)) return NULL;
+
+	(*func)(f, a, b);
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+form_call_INfINf(void (*func)(FL_FORM *, float, float), FL_FORM *f, PyObject *args)
+{
+	float a, b;
+
+	if (!PyArg_Parse(args, "(ff)", &a, &b)) return NULL;
+
+	(*func)(f, a, b);
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+form_hide_form(formobject *f)
+{
+	return form_call(fl_hide_form, f-> ob_form);
+}
+
+static PyObject *
+form_redraw_form(formobject *f)
+{
+	return form_call(fl_redraw_form, f-> ob_form);
+}
+
+static PyObject *
+form_set_form_position(formobject *f, PyObject *args)
+{
+	return form_call_INiINi(fl_set_form_position, f-> ob_form, args);
+}
+
+static PyObject *
+form_set_form_size(formobject *f, PyObject *args)
+{
+	return form_call_INiINi(fl_set_form_size, f-> ob_form, args);
+}
+
+static PyObject *
+form_scale_form(formobject *f, PyObject *args)
+{
+	return form_call_INfINf(fl_scale_form, f-> ob_form, args);
+}
+
+static PyObject *
+generic_add_object(formobject *f, PyObject *args, FL_OBJECT *(*func)(int, float, float, float, float, char*), PyMethodDef *internal_methods)
+{
+	int type;
+	float x, y, w, h;
+	char *name;
+	FL_OBJECT *obj;
+
+	if (!PyArg_Parse(args,"(iffffs)", &type,&x,&y,&w,&h,&name))
+		return NULL;
+
+	fl_addto_form (f-> ob_form);
+
+	obj = (*func) (type, x, y, w, h, name);
+
+	fl_end_form();
+
+	if (obj == NULL) {
+		PyErr_NoMemory();
+		return NULL;
+	}
+
+	return newgenericobject (obj, internal_methods);
+}
+
+static PyObject *
+form_add_button(formobject *f, PyObject *args)
+{
+	return generic_add_object(f, args, fl_add_button, button_methods);
+}
+
+static PyObject *
+form_add_lightbutton(formobject *f, PyObject *args)
+{
+	return generic_add_object(f, args, fl_add_lightbutton, button_methods);
+}
+
+static PyObject *
+form_add_roundbutton(formobject *f, PyObject *args)
+{
+	return generic_add_object(f, args, fl_add_roundbutton, button_methods);
+}
+
+static PyObject *
+form_add_menu (formobject *f, PyObject *args)
+{
+	return generic_add_object(f, args, fl_add_menu, menu_methods);
+}
+
+static PyObject *
+form_add_slider(formobject *f, PyObject *args)
+{
+	return generic_add_object(f, args, fl_add_slider, slider_methods);
+}
+
+static PyObject *
+form_add_valslider(formobject *f, PyObject *args)
+{
+	return generic_add_object(f, args, fl_add_valslider, slider_methods);
+}
+
+static PyObject *
+form_add_dial(formobject *f, PyObject *args)
+{
+	return generic_add_object(f, args, fl_add_dial, dial_methods);
+}
+
+static PyObject *
+form_add_counter(formobject *f, PyObject *args)
+{
+	return generic_add_object(f, args, fl_add_counter, counter_methods);
+}
+
+static PyObject *
+form_add_clock(formobject *f, PyObject *args)
+{
+	return generic_add_object(f, args, fl_add_clock, clock_methods);
+}
+
+static PyObject *
+form_add_box(formobject *f, PyObject *args)
+{
+	return generic_add_object(f, args, fl_add_box,
+				  (PyMethodDef *)NULL);
+}
+
+static PyObject *
+form_add_choice(formobject *f, PyObject *args)
+{
+	return generic_add_object(f, args, fl_add_choice, choice_methods);
+}
+
+static PyObject *
+form_add_browser(formobject *f, PyObject *args)
+{
+	return generic_add_object(f, args, fl_add_browser, browser_methods);
+}
+
+static PyObject *
+form_add_positioner(formobject *f, PyObject *args)
+{
+	return generic_add_object(f, args, fl_add_positioner,
+				  positioner_methods);
+}
+
+static PyObject *
+form_add_input(formobject *f, PyObject *args)
+{
+	return generic_add_object(f, args, fl_add_input, input_methods);
+}
+
+static PyObject *
+form_add_text(formobject *f, PyObject *args)
+{
+	return generic_add_object(f, args, fl_add_text,
+				  (PyMethodDef *)NULL);
+}
+
+static PyObject *
+form_add_timer(formobject *f, PyObject *args)
+{
+	return generic_add_object(f, args, fl_add_timer, timer_methods);
+}
+
+static PyObject *
+form_freeze_form(formobject *f)
+{
+	return form_call(fl_freeze_form, f-> ob_form);
+}
+
+static PyObject *
+form_unfreeze_form(formobject *f)
+{
+	return form_call(fl_unfreeze_form, f-> ob_form);
+}
+
+static PyObject *
+form_activate_form(formobject *f)
+{
+	return form_call(fl_activate_form, f-> ob_form);
+}
+
+static PyObject *
+form_deactivate_form(formobject *f)
+{
+	return form_call(fl_deactivate_form, f-> ob_form);
+}
+
+static PyObject *
+form_bgn_group(formobject *f, PyObject *args)
+{
+	FL_OBJECT *obj;
+
+	fl_addto_form(f-> ob_form);
+	obj = fl_bgn_group();
+	fl_end_form();
+
+	if (obj == NULL) {
+		PyErr_NoMemory();
+		return NULL;
+	}
+
+	return newgenericobject (obj, (PyMethodDef *) NULL);
+}
+
+static PyObject *
+form_end_group(formobject *f, PyObject *args)
+{
+	fl_addto_form(f-> ob_form);
+	fl_end_group();
+	fl_end_form();
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+forms_find_first_or_last(FL_OBJECT *(*func)(FL_FORM *, int, float, float), formobject *f, PyObject *args)
+{
+	int type;
+	float mx, my;
+	FL_OBJECT *generic;
+	genericobject *g;
+	
+	if (!PyArg_Parse(args, "(iff)", &type, &mx, &my)) return NULL;
+
+	generic = (*func) (f-> ob_form, type, mx, my);
+
+	if (generic == NULL)
+	{
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+
+	g = findgeneric(generic);
+	if (g == NULL) {
+		PyErr_SetString(PyExc_RuntimeError,
+			   "forms_find_{first|last} returns unknown object");
+		return NULL;
+	}
+	Py_INCREF(g);
+	return (PyObject *) g;
+}
+
+static PyObject *
+form_find_first(formobject *f, PyObject *args)
+{
+	return forms_find_first_or_last(fl_find_first, f, args);
+}
+
+static PyObject *
+form_find_last(formobject *f, PyObject *args)
+{
+	return forms_find_first_or_last(fl_find_last, f, args);
+}
+
+static PyObject *
+form_set_object_focus(formobject *f, PyObject *args)
+{
+	genericobject *g;
+	if (args == NULL || !is_genericobject(args)) {
+		PyErr_BadArgument();
+		return NULL;
+	}
+	g = (genericobject *)args;
+	fl_set_object_focus(f->ob_form, g->ob_generic);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyMethodDef form_methods[] = {
+/* adm */
+	{"show_form",		(PyCFunction)form_show_form,     METH_OLDARGS},
+	{"hide_form",		(PyCFunction)form_hide_form,     METH_NOARGS},
+	{"redraw_form",		(PyCFunction)form_redraw_form,   METH_NOARGS},
+	{"set_form_position",	(PyCFunction)form_set_form_position, METH_OLDARGS},
+	{"set_form_size",	(PyCFunction)form_set_form_size, METH_OLDARGS},
+	{"scale_form",		(PyCFunction)form_scale_form,    METH_OLDARGS},
+	{"freeze_form",		(PyCFunction)form_freeze_form,   METH_NOARGS},
+	{"unfreeze_form",	(PyCFunction)form_unfreeze_form, METH_NOARGS},
+	{"activate_form",	(PyCFunction)form_activate_form, METH_NOARGS},
+	{"deactivate_form",	(PyCFunction)form_deactivate_form, METH_NOARGS},
+	{"bgn_group",		(PyCFunction)form_bgn_group,  METH_OLDARGS},
+	{"end_group",		(PyCFunction)form_end_group,  METH_OLDARGS},
+	{"find_first",		(PyCFunction)form_find_first, METH_OLDARGS},
+	{"find_last",		(PyCFunction)form_find_last,  METH_OLDARGS},
+	{"set_object_focus",	(PyCFunction)form_set_object_focus, METH_OLDARGS},
+
+/* basic objects */
+	{"add_button",		(PyCFunction)form_add_button, METH_OLDARGS},
+/*	{"add_bitmap",		(method)form_add_bitmap, METH_OLDARGS}, */
+	{"add_lightbutton",	(PyCFunction)form_add_lightbutton, METH_OLDARGS},
+	{"add_roundbutton",	(PyCFunction)form_add_roundbutton, METH_OLDARGS},
+	{"add_menu",		(PyCFunction)form_add_menu,      METH_OLDARGS},
+	{"add_slider",		(PyCFunction)form_add_slider,    METH_OLDARGS},
+	{"add_positioner",	(PyCFunction)form_add_positioner, METH_OLDARGS},
+	{"add_valslider",	(PyCFunction)form_add_valslider, METH_OLDARGS},
+	{"add_dial",		(PyCFunction)form_add_dial,      METH_OLDARGS},
+	{"add_counter",		(PyCFunction)form_add_counter,   METH_OLDARGS},
+	{"add_box",		(PyCFunction)form_add_box,       METH_OLDARGS},
+	{"add_clock",		(PyCFunction)form_add_clock,     METH_OLDARGS},
+	{"add_choice",		(PyCFunction)form_add_choice,    METH_OLDARGS},
+	{"add_browser",		(PyCFunction)form_add_browser,   METH_OLDARGS},
+	{"add_input",		(PyCFunction)form_add_input,     METH_OLDARGS},
+	{"add_timer",		(PyCFunction)form_add_timer,     METH_OLDARGS},
+	{"add_text",		(PyCFunction)form_add_text,      METH_OLDARGS},
+	{NULL,			NULL}		/* sentinel */
+};
+
+static void
+form_dealloc(formobject *f)
+{
+	releaseobjects(f->ob_form);
+	if (f->ob_form->visible)
+		fl_hide_form(f->ob_form);
+	fl_free_form(f->ob_form);
+	PyObject_Del(f);
+}
+
+#define OFF(x) offsetof(FL_FORM, x)
+
+static struct memberlist form_memberlist[] = {
+	{"window",	T_LONG,		OFF(window),	RO},
+	{"w",		T_FLOAT,	OFF(w)},
+	{"h",		T_FLOAT,	OFF(h)},
+	{"x",		T_FLOAT,	OFF(x),		RO},
+	{"y",		T_FLOAT,	OFF(y),		RO},
+	{"deactivated",	T_INT,		OFF(deactivated)},
+	{"visible",	T_INT,		OFF(visible),	RO},
+	{"frozen",	T_INT,		OFF(frozen),	RO},
+	{"doublebuf",	T_INT,		OFF(doublebuf)},
+	{NULL}	/* Sentinel */
+};
+
+#undef OFF
+
+static PyObject *
+form_getattr(formobject *f, char *name)
+{
+	PyObject *meth;
+
+	meth = Py_FindMethod(form_methods, (PyObject *)f, name);
+	if (meth != NULL)
+		return meth;
+	PyErr_Clear();
+	return PyMember_Get((char *)f->ob_form, form_memberlist, name);
+}
+
+static int
+form_setattr(formobject *f, char *name, PyObject *v)
+{
+	if (v == NULL) {
+		PyErr_SetString(PyExc_TypeError,
+				"can't delete form attributes");
+		return -1;
+	}
+
+	return PyMember_Set((char *)f->ob_form, form_memberlist, name, v);
+}
+
+static PyObject *
+form_repr(formobject *f)
+{
+	char buf[100];
+	PyOS_snprintf(buf, sizeof(buf), "<FORMS_form at %p, window=%ld>",
+		      f, f->ob_form->window);
+	return PyString_FromString(buf);
+}
+
+static PyTypeObject Formtype = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,				/*ob_size*/
+	"fl.FORMS_form",		/*tp_name*/
+	sizeof(formobject),		/*tp_size*/
+	0,				/*tp_itemsize*/
+	/* methods */
+	(destructor)form_dealloc,	/*tp_dealloc*/
+	0,				/*tp_print*/
+	(getattrfunc)form_getattr,	/*tp_getattr*/
+	(setattrfunc)form_setattr,	/*tp_setattr*/
+	0,				/*tp_compare*/
+	(reprfunc)form_repr,		/*tp_repr*/
+};
+
+static PyObject *
+newformobject(FL_FORM *form)
+{
+	formobject *f;
+	f = PyObject_New(formobject, &Formtype);
+	if (f == NULL)
+		return NULL;
+	f->ob_form = form;
+	return (PyObject *)f;
+}
+
+
+/* The "fl" module */
+
+static PyObject *
+forms_make_form(PyObject *dummy, PyObject *args)
+{
+	int type;
+	float w, h;
+	FL_FORM *form;
+	if (!PyArg_Parse(args, "(iff)", &type, &w, &h))
+		return NULL;
+	form = fl_bgn_form(type, w, h);
+	if (form == NULL) {
+		/* XXX Actually, cannot happen! */
+		PyErr_NoMemory();
+		return NULL;
+	}
+	fl_end_form();
+	return newformobject(form);
+}
+
+static PyObject *
+forms_activate_all_forms(PyObject *f, PyObject *args)
+{
+	fl_activate_all_forms();
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+forms_deactivate_all_forms(PyObject *f, PyObject *args)
+{
+	fl_deactivate_all_forms();
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *my_event_callback = NULL;
+
+static PyObject *
+forms_set_event_call_back(PyObject *dummy, PyObject *args)
+{
+	if (args == Py_None)
+		args = NULL;
+	my_event_callback = args;
+	Py_XINCREF(args);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+forms_do_or_check_forms(PyObject *dummy, FL_OBJECT *(*func)(void))
+{
+	FL_OBJECT *generic;
+	genericobject *g;
+	PyObject *arg, *res;
+
+	for (;;) {
+		Py_BEGIN_ALLOW_THREADS
+		generic = (*func)();
+		Py_END_ALLOW_THREADS
+		if (generic == NULL) {
+			Py_INCREF(Py_None);
+			return Py_None;
+		}
+		if (generic == FL_EVENT) {
+			int dev;
+			short val;
+			if (my_event_callback == NULL)
+				return PyInt_FromLong(-1L);
+			dev = fl_qread(&val);
+			arg = Py_BuildValue("(ih)", dev, val);
+			if (arg == NULL)
+				return NULL;
+			res = PyEval_CallObject(my_event_callback, arg);
+			Py_XDECREF(res);
+			Py_DECREF(arg);
+			if (res == NULL)
+				return NULL; /* Callback raised exception */
+			continue;
+		}
+		g = findgeneric(generic);
+		if (g == NULL) {
+			/* Object not known to us (some dialogs cause this) */
+			continue; /* Ignore it */
+		}
+		if (g->ob_callback == NULL) {
+			Py_INCREF(g);
+			return ((PyObject *) g);
+		}
+		arg = PyTuple_Pack(2, (PyObject *)g, g->ob_callback_arg);
+		if (arg == NULL)
+			return NULL;
+		res = PyEval_CallObject(g->ob_callback, arg);
+		Py_XDECREF(res);
+		Py_DECREF(arg);
+		if (res == NULL)
+			return NULL; /* Callback raised exception */
+	}
+}
+
+static PyObject *
+forms_do_forms(PyObject *dummy)
+{
+	return forms_do_or_check_forms(dummy, fl_do_forms);
+}
+
+static PyObject *
+forms_check_forms(PyObject *dummy)
+{
+	return forms_do_or_check_forms(dummy, fl_check_forms);
+}
+
+static PyObject *
+forms_do_only_forms(PyObject *dummy)
+{
+	return forms_do_or_check_forms(dummy, fl_do_only_forms);
+}
+
+static PyObject *
+forms_check_only_forms(PyObject *dummy)
+{
+	return forms_do_or_check_forms(dummy, fl_check_only_forms);
+}
+
+#ifdef UNUSED
+static PyObject *
+fl_call(void (*func)(void))
+{
+	(*func)();
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+#endif
+
+static PyObject *
+forms_set_graphics_mode(PyObject *dummy, PyObject *args)
+{
+	int rgbmode, doublebuf;
+
+	if (!PyArg_Parse(args, "(ii)", &rgbmode, &doublebuf))
+		return NULL;
+	fl_set_graphics_mode(rgbmode,doublebuf);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+forms_get_rgbmode(PyObject *dummy, PyObject *args)
+{
+	extern int fl_rgbmode;
+
+	if (args != NULL) {
+		PyErr_BadArgument();
+		return NULL;
+	}
+	return PyInt_FromLong((long)fl_rgbmode);
+}
+
+static PyObject *
+forms_show_errors(PyObject *dummy, PyObject *args)
+{
+	int show;
+	if (!PyArg_Parse(args, "i", &show))
+		return NULL;
+	fl_show_errors(show);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+forms_set_font_name(PyObject *dummy, PyObject *args)
+{
+	int numb;
+	char *name;
+	if (!PyArg_Parse(args, "(is)", &numb, &name))
+		return NULL;
+	fl_set_font_name(numb, name);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+
+static PyObject *
+forms_qdevice(PyObject *self, PyObject *args)
+{
+	short arg1;
+	if (!PyArg_Parse(args, "h", &arg1))
+		return NULL;
+	fl_qdevice(arg1);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+forms_unqdevice(PyObject *self, PyObject *args)
+{
+	short arg1;
+	if (!PyArg_Parse(args, "h", &arg1))
+		return NULL;
+	fl_unqdevice(arg1);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+forms_isqueued(PyObject *self, PyObject *args)
+{
+	long retval;
+	short arg1;
+	if (!PyArg_Parse(args, "h", &arg1))
+		return NULL;
+	retval = fl_isqueued(arg1);
+
+	return PyInt_FromLong(retval);
+}
+
+static PyObject *
+forms_qtest(PyObject *self, PyObject *args)
+{
+	long retval;
+	retval = fl_qtest();
+	return PyInt_FromLong(retval);
+}
+
+
+static PyObject *
+forms_qread(PyObject *self, PyObject *args)
+{
+	int dev;
+	short val;
+	Py_BEGIN_ALLOW_THREADS
+	dev = fl_qread(&val);
+	Py_END_ALLOW_THREADS
+	return Py_BuildValue("(ih)", dev, val);
+}
+
+static PyObject *
+forms_qreset(PyObject *self)
+{
+	fl_qreset();
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+forms_qenter(PyObject *self, PyObject *args)
+{
+	short arg1, arg2;
+	if (!PyArg_Parse(args, "(hh)", &arg1, &arg2))
+		return NULL;
+	fl_qenter(arg1, arg2);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+forms_color(PyObject *self, PyObject *args)
+{
+	int arg;
+
+	if (!PyArg_Parse(args, "i", &arg)) return NULL;
+
+	fl_color((short) arg);
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+forms_mapcolor(PyObject *self, PyObject *args)
+{
+	int arg0, arg1, arg2, arg3;
+
+	if (!PyArg_Parse(args, "(iiii)", &arg0, &arg1, &arg2, &arg3))
+		return NULL;
+
+	fl_mapcolor(arg0, (short) arg1, (short) arg2, (short) arg3);
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+forms_getmcolor(PyObject *self, PyObject *args)
+{
+	int arg;
+	short r, g, b;
+
+	if (!PyArg_Parse(args, "i", &arg)) return NULL;
+
+	fl_getmcolor(arg, &r, &g, &b);
+
+	return Py_BuildValue("(hhh)", r, g, b);
+}
+
+static PyObject *
+forms_get_mouse(PyObject *self)
+{
+	float x, y;
+
+	fl_get_mouse(&x, &y);
+
+	return Py_BuildValue("(ff)", x, y);
+}
+
+static PyObject *
+forms_tie(PyObject *self, PyObject *args)
+{
+	short arg1, arg2, arg3;
+	if (!PyArg_Parse(args, "(hhh)", &arg1, &arg2, &arg3))
+		return NULL;
+	fl_tie(arg1, arg2, arg3);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+forms_show_message(PyObject *f, PyObject *args)
+{
+	char *a, *b, *c;
+
+	if (!PyArg_Parse(args, "(sss)", &a, &b, &c)) return NULL;
+
+	Py_BEGIN_ALLOW_THREADS
+	fl_show_message(a, b, c);
+	Py_END_ALLOW_THREADS
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+forms_show_choice(PyObject *f, PyObject *args)
+{
+	char *m1, *m2, *m3, *b1, *b2, *b3;
+	int nb;
+	char *format;
+	long rv;
+
+	if (args == NULL || !PyTuple_Check(args)) {
+		PyErr_BadArgument();
+		return NULL;
+	}
+	nb = PyTuple_Size(args) - 3;
+	if (nb <= 0) {
+		PyErr_SetString(PyExc_TypeError,
+				"need at least one button label");
+		return NULL;
+	}
+	if (PyInt_Check(PyTuple_GetItem(args, 3))) {
+		PyErr_SetString(PyExc_TypeError,
+			   "'number-of-buttons' argument not needed");
+		return NULL;
+	}
+	switch (nb) {
+	case 1: format = "(ssss)"; break;
+	case 2: format = "(sssss)"; break;
+	case 3: format = "(ssssss)"; break;
+	default:
+		PyErr_SetString(PyExc_TypeError, "too many button labels");
+		return NULL;
+	}
+
+	if (!PyArg_Parse(args, format, &m1, &m2, &m3, &b1, &b2, &b3))
+		return NULL;
+
+	Py_BEGIN_ALLOW_THREADS
+	rv = fl_show_choice(m1, m2, m3, nb, b1, b2, b3);
+	Py_END_ALLOW_THREADS
+	return PyInt_FromLong(rv);
+}
+
+static PyObject *
+forms_show_question(PyObject *f, PyObject *args)
+{
+	int ret;
+	char *a, *b, *c;
+
+	if (!PyArg_Parse(args, "(sss)", &a, &b, &c)) return NULL;
+
+	Py_BEGIN_ALLOW_THREADS
+	ret = fl_show_question(a, b, c);
+	Py_END_ALLOW_THREADS
+
+	return PyInt_FromLong((long) ret);
+}
+
+static PyObject *
+forms_show_input(PyObject *f, PyObject *args)
+{
+	char *str;
+	char *a, *b;
+
+	if (!PyArg_Parse(args, "(ss)", &a, &b)) return NULL;
+
+	Py_BEGIN_ALLOW_THREADS
+	str = fl_show_input(a, b);
+	Py_END_ALLOW_THREADS
+
+	if (str == NULL) {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+	return PyString_FromString(str);
+}
+
+static PyObject *
+forms_file_selector(PyObject *f, PyObject *args)
+{
+	char *str;
+	char *a, *b, *c, *d;
+
+	if (!PyArg_Parse(args, "(ssss)", &a, &b, &c, &d)) return NULL;
+
+	Py_BEGIN_ALLOW_THREADS
+	str = fl_show_file_selector(a, b, c, d);
+	Py_END_ALLOW_THREADS
+
+	if (str == NULL) {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+	return PyString_FromString(str);
+}
+
+
+static PyObject *
+forms_file_selector_func(PyObject *args, char *(*func)(void))
+{
+	char *str;
+
+	str = (*func) ();
+
+	if (str == NULL) {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+	return PyString_FromString(str);
+}
+
+static PyObject *
+forms_get_directory(PyObject *f, PyObject *args)
+{
+	return forms_file_selector_func(args, fl_get_directory);
+}
+
+static PyObject *
+forms_get_pattern(PyObject *f, PyObject *args)
+{
+	return forms_file_selector_func(args, fl_get_pattern);
+}
+
+static PyObject *
+forms_get_filename(PyObject *f, PyObject *args)
+{
+	return forms_file_selector_func(args, fl_get_filename);
+}
+
+static PyMethodDef forms_methods[] = {
+/* adm */
+	{"make_form",		forms_make_form, METH_OLDARGS},
+	{"activate_all_forms",	forms_activate_all_forms, METH_OLDARGS},
+	{"deactivate_all_forms",forms_deactivate_all_forms, METH_OLDARGS},
+/* gl support wrappers */
+	{"qdevice",		forms_qdevice, METH_OLDARGS},
+	{"unqdevice",		forms_unqdevice, METH_OLDARGS},
+	{"isqueued",		forms_isqueued, METH_OLDARGS},
+	{"qtest",		forms_qtest, METH_OLDARGS},
+	{"qread",		forms_qread, METH_OLDARGS},
+/*	{"blkqread",		forms_blkqread, METH_OLDARGS}, */
+	{"qreset",		forms_qreset, METH_NOARGS},
+	{"qenter",		forms_qenter, METH_OLDARGS},
+	{"get_mouse",		forms_get_mouse, METH_NOARGS},
+	{"tie",			forms_tie, METH_OLDARGS},
+/*	{"new_events",		forms_new_events, METH_OLDARGS}, */
+	{"color",		forms_color, METH_OLDARGS},
+	{"mapcolor",		forms_mapcolor, METH_OLDARGS},
+	{"getmcolor",		forms_getmcolor, METH_OLDARGS},
+/* interaction */
+	{"do_forms",		forms_do_forms, METH_NOARGS},
+	{"do_only_forms",	forms_do_only_forms, METH_NOARGS},
+	{"check_forms",		forms_check_forms, METH_NOARGS},
+	{"check_only_forms",	forms_check_only_forms, METH_NOARGS},
+	{"set_event_call_back",	forms_set_event_call_back, METH_OLDARGS},
+/* goodies */
+	{"show_message",	forms_show_message, METH_OLDARGS},
+	{"show_question",	forms_show_question, METH_OLDARGS},
+	{"show_choice",		forms_show_choice, METH_OLDARGS},
+	{"show_input",		forms_show_input, METH_OLDARGS},
+	{"show_file_selector",	forms_file_selector, METH_OLDARGS},
+	{"file_selector",	forms_file_selector, METH_OLDARGS}, /* BW compat */
+	{"get_directory",	forms_get_directory, METH_OLDARGS},
+	{"get_pattern",		forms_get_pattern, METH_OLDARGS},
+	{"get_filename",	forms_get_filename, METH_OLDARGS},
+	{"set_graphics_mode",	forms_set_graphics_mode, METH_OLDARGS},
+	{"get_rgbmode",		forms_get_rgbmode, METH_OLDARGS},
+	{"show_errors",		forms_show_errors, METH_OLDARGS},
+	{"set_font_name",	forms_set_font_name, METH_OLDARGS},
+	{NULL,			NULL}		/* sentinel */
+};
+
+PyMODINIT_FUNC
+initfl(void)
+{
+	Py_InitModule("fl", forms_methods);
+	if (m == NULL)
+		return;
+	foreground();
+	fl_init();
+}
+
+
+

Added: vendor/Python/current/Modules/fmmodule.c
===================================================================
--- vendor/Python/current/Modules/fmmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/fmmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,264 @@
+
+/* Font Manager module */
+
+#include "Python.h"
+
+#include <gl.h>
+#include <device.h>
+#include <fmclient.h>
+
+
+/* Font Handle object implementation */
+
+typedef struct {
+	PyObject_HEAD
+	fmfonthandle fh_fh;
+} fhobject;
+
+static PyTypeObject Fhtype;
+
+#define is_fhobject(v)		((v)->ob_type == &Fhtype)
+
+static PyObject *
+newfhobject(fmfonthandle fh)
+{
+	fhobject *fhp;
+	if (fh == NULL) {
+		PyErr_SetString(PyExc_RuntimeError,
+				"error creating new font handle");
+		return NULL;
+	}
+	fhp = PyObject_New(fhobject, &Fhtype);
+	if (fhp == NULL)
+		return NULL;
+	fhp->fh_fh = fh;
+	return (PyObject *)fhp;
+}
+
+/* Font Handle methods */
+
+static PyObject *
+fh_scalefont(fhobject *self, PyObject *args)
+{
+	double size;
+	if (!PyArg_ParseTuple(args, "d", &size))
+		return NULL;
+	return newfhobject(fmscalefont(self->fh_fh, size));
+}
+
+/* XXX fmmakefont */
+
+static PyObject *
+fh_setfont(fhobject *self)
+{
+	fmsetfont(self->fh_fh);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+fh_getfontname(fhobject *self)
+{
+	char fontname[256];
+	int len;
+	len = fmgetfontname(self->fh_fh, sizeof fontname, fontname);
+	if (len < 0) {
+		PyErr_SetString(PyExc_RuntimeError, "error in fmgetfontname");
+		return NULL;
+	}
+	return PyString_FromStringAndSize(fontname, len);
+}
+
+static PyObject *
+fh_getcomment(fhobject *self)
+{
+	char comment[256];
+	int len;
+	len = fmgetcomment(self->fh_fh, sizeof comment, comment);
+	if (len < 0) {
+		PyErr_SetString(PyExc_RuntimeError, "error in fmgetcomment");
+		return NULL;
+	}
+	return PyString_FromStringAndSize(comment, len);
+}
+
+static PyObject *
+fh_getfontinfo(fhobject *self)
+{
+	fmfontinfo info;
+	if (fmgetfontinfo(self->fh_fh, &info) < 0) {
+		PyErr_SetString(PyExc_RuntimeError, "error in fmgetfontinfo");
+		return NULL;
+	}
+	return Py_BuildValue("(llllllll)",
+			     info.printermatched,
+			     info.fixed_width,
+			     info.xorig,
+			     info.yorig,
+			     info.xsize,
+			     info.ysize,
+			     info.height,
+			     info.nglyphs);
+}
+
+#if 0
+static PyObject *
+fh_getwholemetrics(fhobject *self, PyObject *args)
+{
+}
+#endif
+
+static PyObject *
+fh_getstrwidth(fhobject *self, PyObject *args)
+{
+	char *str;
+	if (!PyArg_ParseTuple(args, "s", &str))
+		return NULL;
+	return PyInt_FromLong(fmgetstrwidth(self->fh_fh, str));
+}
+
+static PyMethodDef fh_methods[] = {
+	{"scalefont",	(PyCFunction)fh_scalefont,   METH_VARARGS},
+	{"setfont",	(PyCFunction)fh_setfont,     METH_NOARGS},
+	{"getfontname",	(PyCFunction)fh_getfontname, METH_NOARGS},
+	{"getcomment",	(PyCFunction)fh_getcomment,  METH_NOARGS},
+	{"getfontinfo",	(PyCFunction)fh_getfontinfo, METH_NOARGS},
+#if 0
+	{"getwholemetrics",	(PyCFunction)fh_getwholemetrics, METH_VARARGS},
+#endif
+	{"getstrwidth",	(PyCFunction)fh_getstrwidth, METH_VARARGS},
+	{NULL,		NULL}		/* sentinel */
+};
+
+static PyObject *
+fh_getattr(fhobject *fhp, char *name)
+{
+	return Py_FindMethod(fh_methods, (PyObject *)fhp, name);
+}
+
+static void
+fh_dealloc(fhobject *fhp)
+{
+	fmfreefont(fhp->fh_fh);
+	PyObject_Del(fhp);
+}
+
+static PyTypeObject Fhtype = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,				/*ob_size*/
+	"fm.font handle",		/*tp_name*/
+	sizeof(fhobject),		/*tp_size*/
+	0,				/*tp_itemsize*/
+	/* methods */
+	(destructor)fh_dealloc,		/*tp_dealloc*/
+	0,				/*tp_print*/
+	(getattrfunc)fh_getattr,	/*tp_getattr*/
+	0,				/*tp_setattr*/
+	0,				/*tp_compare*/
+	0,				/*tp_repr*/
+};
+
+
+/* Font Manager functions */
+
+static PyObject *
+fm_init(PyObject *self)
+{
+	fminit();
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+fm_findfont(PyObject *self, PyObject *args)
+{
+	char *str;
+	if (!PyArg_ParseTuple(args, "s", &str))
+		return NULL;
+	return newfhobject(fmfindfont(str));
+}
+
+static PyObject *
+fm_prstr(PyObject *self, PyObject *args)
+{
+	char *str;
+	if (!PyArg_ParseTuple(args, "s", &str))
+		return NULL;
+	fmprstr(str);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* XXX This uses a global variable as temporary! Not re-entrant! */
+
+static PyObject *fontlist;
+
+static void
+clientproc(char *fontname)
+{
+	int err;
+	PyObject *v;
+	if (fontlist == NULL)
+		return;
+	v = PyString_FromString(fontname);
+	if (v == NULL)
+		err = -1;
+	else {
+		err = PyList_Append(fontlist, v);
+		Py_DECREF(v);
+	}
+	if (err != 0) {
+		Py_DECREF(fontlist);
+		fontlist = NULL;
+	}
+}
+
+static PyObject *
+fm_enumerate(PyObject *self)
+{
+	PyObject *res;
+	fontlist = PyList_New(0);
+	if (fontlist == NULL)
+		return NULL;
+	fmenumerate(clientproc);
+	res = fontlist;
+	fontlist = NULL;
+	return res;
+}
+
+static PyObject *
+fm_setpath(PyObject *self, PyObject *args)
+{
+	char *str;
+	if (!PyArg_ParseTuple(args, "s", &str))
+		return NULL;
+	fmsetpath(str);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+fm_fontpath(PyObject *self)
+{
+	return PyString_FromString(fmfontpath());
+}
+
+static PyMethodDef fm_methods[] = {
+	{"init",	fm_init,      METH_NOARGS},
+	{"findfont",	fm_findfont,  METH_VARARGS},
+	{"enumerate",	fm_enumerate, METH_NOARGS},
+	{"prstr",	fm_prstr,     METH_VARARGS},
+	{"setpath",	fm_setpath,   METH_VARARGS},
+	{"fontpath",	fm_fontpath,  METH_NOARGS},
+	{NULL,		NULL}		/* sentinel */
+};
+
+
+void
+initfm(void)
+{
+	Py_InitModule("fm", fm_methods);
+	if (m == NULL)
+		return;
+	fminit();
+}

Added: vendor/Python/current/Modules/fpectlmodule.c
===================================================================
--- vendor/Python/current/Modules/fpectlmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/fpectlmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,303 @@
+/*
+     ---------------------------------------------------------------------  
+    /                       Copyright (c) 1996.                           \ 
+   |          The Regents of the University of California.                 |
+   |                        All rights reserved.                           |
+   |                                                                       |
+   |   Permission to use, copy, modify, and distribute this software for   |
+   |   any purpose without fee is hereby granted, provided that this en-   |
+   |   tire notice is included in all copies of any software which is or   |
+   |   includes  a  copy  or  modification  of  this software and in all   |
+   |   copies of the supporting documentation for such software.           |
+   |                                                                       |
+   |   This  work was produced at the University of California, Lawrence   |
+   |   Livermore National Laboratory under  contract  no.  W-7405-ENG-48   |
+   |   between  the  U.S.  Department  of  Energy and The Regents of the   |
+   |   University of California for the operation of UC LLNL.              |
+   |                                                                       |
+   |                              DISCLAIMER                               |
+   |                                                                       |
+   |   This  software was prepared as an account of work sponsored by an   |
+   |   agency of the United States Government. Neither the United States   |
+   |   Government  nor the University of California nor any of their em-   |
+   |   ployees, makes any warranty, express or implied, or  assumes  any   |
+   |   liability  or  responsibility  for the accuracy, completeness, or   |
+   |   usefulness of any information,  apparatus,  product,  or  process   |
+   |   disclosed,   or  represents  that  its  use  would  not  infringe   |
+   |   privately-owned rights. Reference herein to any specific  commer-   |
+   |   cial  products,  process,  or  service  by trade name, trademark,   |
+   |   manufacturer, or otherwise, does not  necessarily  constitute  or   |
+   |   imply  its endorsement, recommendation, or favoring by the United   |
+   |   States Government or the University of California. The views  and   |
+   |   opinions  of authors expressed herein do not necessarily state or   |
+   |   reflect those of the United States Government or  the  University   |
+   |   of  California,  and shall not be used for advertising or product   |
+    \  endorsement purposes.                                              / 
+     ---------------------------------------------------------------------  
+*/
+
+/*
+		  Floating point exception control module.
+
+   This Python module provides bare-bones control over floating point
+   units from several hardware manufacturers.  Specifically, it allows
+   the user to turn on the generation of SIGFPE whenever any of the
+   three serious IEEE 754 exceptions (Division by Zero, Overflow,
+   Invalid Operation) occurs.  We currently ignore Underflow and
+   Inexact Result exceptions, although those could certainly be added
+   if desired.
+
+   The module also establishes a signal handler for SIGFPE during
+   initialization.  This builds on code found in the Python
+   distribution at Include/pyfpe.h and Python/pyfpe.c.  If those files
+   are not in your Python distribution, find them in a patch at
+   ftp://icf.llnl.gov/pub/python/busby/patches.961108.tgz.
+
+   This module is only useful to you if it happens to include code
+   specific for your hardware and software environment.  If you can
+   contribute OS-specific code for new platforms, or corrections for
+   the code provided, it will be greatly appreciated.
+
+   ** Version 1.0: September 20, 1996.  Lee Busby, LLNL.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "Python.h"
+#include <signal.h>
+
+#if defined(__FreeBSD__)
+#  include <ieeefp.h>
+#elif defined(__VMS)
+#define __NEW_STARLET
+#include <starlet.h>
+#include <ieeedef.h>
+#endif
+
+#ifndef WANT_SIGFPE_HANDLER
+/* Define locally if they are not defined in Python.  This gives only
+ * the limited control to induce a core dump in case of an exception.
+ */
+#include <setjmp.h>
+static jmp_buf PyFPE_jbuf;
+static int PyFPE_counter = 0;
+#endif
+
+typedef void Sigfunc(int);
+static Sigfunc sigfpe_handler;
+static void fpe_reset(Sigfunc *);
+
+static PyObject *fpe_error;
+PyMODINIT_FUNC initfpectl(void);
+static PyObject *turnon_sigfpe            (PyObject *self,PyObject *args);
+static PyObject *turnoff_sigfpe           (PyObject *self,PyObject *args);
+
+static PyMethodDef fpectl_methods[] = {
+    {"turnon_sigfpe",		 (PyCFunction) turnon_sigfpe,		 METH_VARARGS},
+    {"turnoff_sigfpe",		 (PyCFunction) turnoff_sigfpe, 	         METH_VARARGS},
+    {0,0}
+};
+
+static PyObject *turnon_sigfpe(PyObject *self,PyObject *args)
+{
+    /* Do any architecture-specific one-time only initialization here. */
+
+    fpe_reset(sigfpe_handler);
+    Py_INCREF (Py_None);
+    return Py_None;
+}
+
+static void fpe_reset(Sigfunc *handler)
+{
+    /* Reset the exception handling machinery, and reset the signal
+     * handler for SIGFPE to the given handler.
+     */
+
+/*-- IRIX -----------------------------------------------------------------*/
+#if defined(sgi)
+    /* See man page on handle_sigfpes -- must link with -lfpe
+     * My usage doesn't follow the man page exactly.  Maybe somebody
+     * else can explain handle_sigfpes to me....
+     * cc -c -I/usr/local/python/include fpectlmodule.c
+     * ld -shared -o fpectlmodule.so fpectlmodule.o -lfpe 
+     */
+#include <sigfpe.h>
+    typedef void user_routine (unsigned[5], int[2]);
+    typedef void abort_routine (unsigned long);
+    handle_sigfpes(_OFF, 0,
+		 (user_routine *)0,
+		 _TURN_OFF_HANDLER_ON_ERROR,
+		 NULL);
+    handle_sigfpes(_ON, _EN_OVERFL | _EN_DIVZERO | _EN_INVALID,
+		 (user_routine *)0,
+		 _ABORT_ON_ERROR,
+		 NULL);
+    PyOS_setsig(SIGFPE, handler);
+
+/*-- SunOS and Solaris ----------------------------------------------------*/
+#elif defined(sun)
+    /* References: ieee_handler, ieee_sun, ieee_functions, and ieee_flags
+       man pages (SunOS or Solaris)
+       cc -c -I/usr/local/python/include fpectlmodule.c
+       ld -G -o fpectlmodule.so -L/opt/SUNWspro/lib fpectlmodule.o -lsunmath -lm
+     */
+#include <math.h>
+#ifndef _SUNMATH_H
+    extern void nonstandard_arithmetic(void);
+    extern int ieee_flags(const char*, const char*, const char*, char **);
+    extern long ieee_handler(const char*, const char*, sigfpe_handler_type);
+#endif
+
+    char *mode="exception", *in="all", *out;
+    (void) nonstandard_arithmetic();
+    (void) ieee_flags("clearall",mode,in,&out);
+    (void) ieee_handler("set","common",(sigfpe_handler_type)handler);
+    PyOS_setsig(SIGFPE, handler);
+
+/*-- HPUX -----------------------------------------------------------------*/
+#elif defined(__hppa) || defined(hppa)
+    /* References:   fpsetmask man page */
+    /* cc -Aa +z -c -I/usr/local/python/include fpectlmodule.c */
+    /* ld -b -o fpectlmodule.sl fpectlmodule.o -lm */
+#include <math.h>
+    fpsetdefaults();
+    PyOS_setsig(SIGFPE, handler);
+
+/*-- IBM AIX --------------------------------------------------------------*/
+#elif defined(__AIX) || defined(_AIX)
+    /* References:   fp_trap, fp_enable man pages */
+#include <fptrap.h>
+    fp_trap(FP_TRAP_SYNC);
+    fp_enable(TRP_INVALID | TRP_DIV_BY_ZERO | TRP_OVERFLOW);
+    PyOS_setsig(SIGFPE, handler);
+
+/*-- DEC ALPHA OSF --------------------------------------------------------*/
+#elif defined(__alpha) && defined(__osf__)
+    /* References:   exception_intro, ieee man pages */
+    /* cc -c -I/usr/local/python/include fpectlmodule.c */
+    /* ld -shared -o fpectlmodule.so fpectlmodule.o */
+#include <machine/fpu.h>
+    unsigned long fp_control =
+    IEEE_TRAP_ENABLE_INV | IEEE_TRAP_ENABLE_DZE | IEEE_TRAP_ENABLE_OVF;
+    ieee_set_fp_control(fp_control);
+    PyOS_setsig(SIGFPE, handler);
+
+/*-- DEC ALPHA LINUX ------------------------------------------------------*/
+#elif defined(__alpha) && defined(linux)
+#include <asm/fpu.h>
+    unsigned long fp_control =
+    IEEE_TRAP_ENABLE_INV | IEEE_TRAP_ENABLE_DZE | IEEE_TRAP_ENABLE_OVF;
+    ieee_set_fp_control(fp_control);
+    PyOS_setsig(SIGFPE, handler);
+
+/*-- DEC ALPHA VMS --------------------------------------------------------*/
+#elif defined(__ALPHA) && defined(__VMS)
+	IEEE clrmsk;
+	IEEE setmsk;
+	clrmsk.ieee$q_flags =
+		IEEE$M_TRAP_ENABLE_UNF |  IEEE$M_TRAP_ENABLE_INE |
+		 IEEE$M_MAP_UMZ;
+	setmsk.ieee$q_flags =
+		IEEE$M_TRAP_ENABLE_INV | IEEE$M_TRAP_ENABLE_DZE |
+		IEEE$M_TRAP_ENABLE_OVF;
+	sys$ieee_set_fp_control(&clrmsk, &setmsk, 0);
+	PyOS_setsig(SIGFPE, handler);
+
+/*-- HP IA64 VMS --------------------------------------------------------*/
+#elif defined(__ia64) && defined(__VMS)
+    PyOS_setsig(SIGFPE, handler);
+
+/*-- Cray Unicos ----------------------------------------------------------*/
+#elif defined(cray)
+    /* UNICOS delivers SIGFPE by default, but no matherr */
+#ifdef HAS_LIBMSET
+    libmset(-1);
+#endif
+    PyOS_setsig(SIGFPE, handler);
+
+/*-- FreeBSD ----------------------------------------------------------------*/
+#elif defined(__FreeBSD__)
+    fpresetsticky(fpgetsticky());
+    fpsetmask(FP_X_INV | FP_X_DZ | FP_X_OFL);
+    PyOS_setsig(SIGFPE, handler);
+
+/*-- Linux ----------------------------------------------------------------*/
+#elif defined(linux)
+#ifdef __GLIBC__
+#include <fpu_control.h>
+#else
+#include <i386/fpu_control.h>
+#endif
+#ifdef _FPU_SETCW
+    {
+        fpu_control_t cw = 0x1372;
+        _FPU_SETCW(cw);
+    }
+#else
+    __setfpucw(0x1372);
+#endif
+    PyOS_setsig(SIGFPE, handler);
+
+/*-- Microsoft Windows, NT ------------------------------------------------*/
+#elif defined(_MSC_VER)
+    /* Reference: Visual C++ Books Online 4.2,
+       Run-Time Library Reference, _control87, _controlfp */
+#include <float.h>
+    unsigned int cw = _EM_INVALID | _EM_ZERODIVIDE | _EM_OVERFLOW;
+    (void)_controlfp(0, cw);
+    PyOS_setsig(SIGFPE, handler);
+
+/*-- Give Up --------------------------------------------------------------*/
+#else
+    fputs("Operation not implemented\n", stderr);
+#endif
+
+}
+
+static PyObject *turnoff_sigfpe(PyObject *self,PyObject *args)
+{
+#ifdef __FreeBSD__
+    fpresetsticky(fpgetsticky());
+    fpsetmask(0);
+#elif defined(__VMS)
+	IEEE clrmsk;
+	 clrmsk.ieee$q_flags =
+		IEEE$M_TRAP_ENABLE_UNF |  IEEE$M_TRAP_ENABLE_INE |
+		IEEE$M_MAP_UMZ | IEEE$M_TRAP_ENABLE_INV |
+		IEEE$M_TRAP_ENABLE_DZE | IEEE$M_TRAP_ENABLE_OVF |
+		IEEE$M_INHERIT;
+	sys$ieee_set_fp_control(&clrmsk, 0, 0);
+#else
+    fputs("Operation not implemented\n", stderr);
+#endif
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static void sigfpe_handler(int signo)
+{
+    fpe_reset(sigfpe_handler);
+    if(PyFPE_counter) {
+        longjmp(PyFPE_jbuf, 1);
+    } else {
+        Py_FatalError("Unprotected floating point exception");
+    }
+}
+
+PyMODINIT_FUNC initfpectl(void)
+{
+    PyObject *m, *d;
+    m = Py_InitModule("fpectl", fpectl_methods);
+    if (m == NULL)
+    	return;
+    d = PyModule_GetDict(m);
+    fpe_error = PyErr_NewException("fpectl.error", NULL, NULL);
+    if (fpe_error != NULL)
+	PyDict_SetItemString(d, "error", fpe_error);
+}
+
+#ifdef __cplusplus
+}
+#endif

Added: vendor/Python/current/Modules/fpetestmodule.c
===================================================================
--- vendor/Python/current/Modules/fpetestmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/fpetestmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,186 @@
+/*
+     ---------------------------------------------------------------------  
+    /                       Copyright (c) 1996.                           \ 
+   |          The Regents of the University of California.                 |
+   |                        All rights reserved.                           |
+   |                                                                       |
+   |   Permission to use, copy, modify, and distribute this software for   |
+   |   any purpose without fee is hereby granted, provided that this en-   |
+   |   tire notice is included in all copies of any software which is or   |
+   |   includes  a  copy  or  modification  of  this software and in all   |
+   |   copies of the supporting documentation for such software.           |
+   |                                                                       |
+   |   This  work was produced at the University of California, Lawrence   |
+   |   Livermore National Laboratory under  contract  no.  W-7405-ENG-48   |
+   |   between  the  U.S.  Department  of  Energy and The Regents of the   |
+   |   University of California for the operation of UC LLNL.              |
+   |                                                                       |
+   |                              DISCLAIMER                               |
+   |                                                                       |
+   |   This  software was prepared as an account of work sponsored by an   |
+   |   agency of the United States Government. Neither the United States   |
+   |   Government  nor the University of California nor any of their em-   |
+   |   ployees, makes any warranty, express or implied, or  assumes  any   |
+   |   liability  or  responsibility  for the accuracy, completeness, or   |
+   |   usefulness of any information,  apparatus,  product,  or  process   |
+   |   disclosed,   or  represents  that  its  use  would  not  infringe   |
+   |   privately-owned rights. Reference herein to any specific  commer-   |
+   |   cial  products,  process,  or  service  by trade name, trademark,   |
+   |   manufacturer, or otherwise, does not  necessarily  constitute  or   |
+   |   imply  its endorsement, recommendation, or favoring by the United   |
+   |   States Government or the University of California. The views  and   |
+   |   opinions  of authors expressed herein do not necessarily state or   |
+   |   reflect those of the United States Government or  the  University   |
+   |   of  California,  and shall not be used for advertising or product   |
+    \  endorsement purposes.                                              / 
+     ---------------------------------------------------------------------  
+*/
+
+/*
+		  Floating point exception test module.
+
+ */
+
+#include "Python.h"
+
+static PyObject *fpe_error;
+PyMODINIT_FUNC initfpetest(void);
+static PyObject *test(PyObject *self,PyObject *args);
+static double db0(double);
+static double overflow(double);
+static double nest1(int, double);
+static double nest2(int, double);
+static double nest3(double);
+static void printerr(double);
+
+static PyMethodDef fpetest_methods[] = {
+    {"test",		 (PyCFunction) test,		 METH_VARARGS},
+    {0,0}
+};
+
+static PyObject *test(PyObject *self,PyObject *args)
+{
+    double r;
+
+    fprintf(stderr,"overflow");
+    r = overflow(1.e160);
+    printerr(r);
+
+    fprintf(stderr,"\ndiv by 0");
+    r = db0(0.0);
+    printerr(r);
+
+    fprintf(stderr,"\nnested outer");
+    r = nest1(0, 0.0);
+    printerr(r);
+
+    fprintf(stderr,"\nnested inner");
+    r = nest1(1, 1.0);
+    printerr(r);
+
+    fprintf(stderr,"\ntrailing outer");
+    r = nest1(2, 2.0);
+    printerr(r);
+
+    fprintf(stderr,"\nnested prior");
+    r = nest2(0, 0.0);
+    printerr(r);
+
+    fprintf(stderr,"\nnested interior");
+    r = nest2(1, 1.0);
+    printerr(r);
+
+    fprintf(stderr,"\nnested trailing");
+    r = nest2(2, 2.0);
+    printerr(r);
+
+    Py_INCREF (Py_None);
+    return Py_None;
+}
+
+static void printerr(double r)
+{
+    if(r == 3.1416){
+      fprintf(stderr,"\tPASS\n");
+      PyErr_Print();
+    }else{
+      fprintf(stderr,"\tFAIL\n");
+    }
+    PyErr_Clear();
+}
+
+static double nest1(int i, double x)
+{
+  double a = 1.0;
+
+  PyFPE_START_PROTECT("Division by zero, outer zone", return 3.1416)
+  if(i == 0){
+    a = 1./x;
+  }else if(i == 1){
+    /* This (following) message is never seen. */
+    PyFPE_START_PROTECT("Division by zero, inner zone", return 3.1416)
+    a = 1./(1. - x);
+    PyFPE_END_PROTECT(a)
+  }else if(i == 2){
+    a = 1./(2. - x);
+  }
+  PyFPE_END_PROTECT(a)
+
+  return a;
+}
+
+static double nest2(int i, double x)
+{
+  double a = 1.0;
+  PyFPE_START_PROTECT("Division by zero, prior error", return 3.1416)
+  if(i == 0){
+    a = 1./x;
+  }else if(i == 1){
+    a = nest3(x);
+  }else if(i == 2){
+    a = 1./(2. - x);
+  }
+  PyFPE_END_PROTECT(a)
+  return a;
+}
+
+static double nest3(double x)
+{
+  double result;
+  /* This (following) message is never seen. */
+  PyFPE_START_PROTECT("Division by zero, nest3 error", return 3.1416)
+  result = 1./(1. - x);
+  PyFPE_END_PROTECT(result)
+  return result;
+}
+
+static double db0(double x)
+{
+  double a;
+  PyFPE_START_PROTECT("Division by zero", return 3.1416)
+  a = 1./x;
+  PyFPE_END_PROTECT(a)
+  return a;
+}
+
+static double overflow(double b)
+{
+  double a;
+  PyFPE_START_PROTECT("Overflow", return 3.1416)
+  a = b*b;
+  PyFPE_END_PROTECT(a)
+  return a;
+}
+
+PyMODINIT_FUNC initfpetest(void)
+{
+    PyObject *m, *d;
+
+    m = Py_InitModule("fpetest", fpetest_methods);
+    if (m == NULL)
+    	return;
+    d = PyModule_GetDict(m);
+    fpe_error = PyErr_NewException("fpetest.error", NULL, NULL);
+    if (fpe_error != NULL)
+	    PyDict_SetItemString(d, "error", fpe_error);
+}

Added: vendor/Python/current/Modules/gc_weakref.txt
===================================================================
--- vendor/Python/current/Modules/gc_weakref.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/gc_weakref.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,219 @@
+Intro
+=====
+
+The basic rule for dealing with weakref callbacks (and __del__ methods too,
+for that matter) during cyclic gc:
+
+    Once gc has computed the set of unreachable objects, no Python-level
+    code can be allowed to access an unreachable object.
+
+If that can happen, then the Python code can resurrect unreachable objects
+too, and gc can't detect that without starting over.  Since gc eventually
+runs tp_clear on all unreachable objects, if an unreachable object is
+resurrected then tp_clear will eventually be called on it (or may already
+have been called before resurrection).  At best (and this has been an
+historically common bug), tp_clear empties an instance's __dict__, and
+"impossible" AttributeErrors result.  At worst, tp_clear leaves behind an
+insane object at the C level, and segfaults result (historically, most
+often by setting a new-style class's mro pointer to NULL, after which
+attribute lookups performed by the class can segfault).
+
+OTOH, it's OK to run Python-level code that can't access unreachable
+objects, and sometimes that's necessary.  The chief example is the callback
+attached to a reachable weakref W to an unreachable object O.  Since O is
+going away, and W is still alive, the callback must be invoked.  Because W
+is still alive, everything reachable from its callback is also reachable,
+so it's also safe to invoke the callback (although that's trickier than it
+sounds, since other reachable weakrefs to other unreachable objects may
+still exist, and be accessible to the callback -- there are lots of painful
+details like this covered in the rest of this file).
+
+Python 2.4/2.3.5
+================
+
+The "Before 2.3.3" section below turned out to be wrong in some ways, but
+I'm leaving it as-is because it's more right than wrong, and serves as a
+wonderful example of how painful analysis can miss not only the forest for
+the trees, but also miss the trees for the aphids sucking the trees
+dry <wink>.
+
+The primary thing it missed is that when a weakref to a piece of cyclic
+trash (CT) exists, then any call to any Python code whatsoever can end up
+materializing a strong reference to that weakref's CT referent, and so
+possibly resurrect an insane object (one for which cyclic gc has called-- or
+will call before it's done --tp_clear()).  It's not even necessarily that a
+weakref callback or __del__ method does something nasty on purpose:  as
+soon as we execute Python code, threads other than the gc thread can run
+too, and they can do ordinary things with weakrefs that end up resurrecting
+CT while gc is running.
+
+    http://www.python.org/sf/1055820
+
+shows how innocent it can be, and also how nasty.  Variants of the three
+focussed test cases attached to that bug report are now part of Python's
+standard Lib/test/test_gc.py.
+
+Jim Fulton gave the best nutshell summary of the new (in 2.4 and 2.3.5)
+approach:
+
+    Clearing cyclic trash can call Python code.  If there are weakrefs to
+    any of the cyclic trash, then those weakrefs can be used to resurrect
+    the objects.  Therefore, *before* clearing cyclic trash, we need to
+    remove any weakrefs.  If any of the weakrefs being removed have
+    callbacks, then we need to save the callbacks and call them *after* all
+    of the weakrefs have been cleared.
+
+Alas, doing just that much doesn't work, because it overlooks what turned
+out to be the much subtler problems that were fixed earlier, and described
+below.  We do clear all weakrefs to CT now before breaking cycles, but not
+all callbacks encountered can be run later.  That's explained in horrid
+detail below.
+
+Older text follows, with a some later comments in [] brackets:
+
+Before 2.3.3
+============
+
+Before 2.3.3, Python's cyclic gc didn't pay any attention to weakrefs.
+Segfaults in Zope3 resulted.
+
+weakrefs in Python are designed to, at worst, let *other* objects learn
+that a given object has died, via a callback function.  The weakly
+referenced object itself is not passed to the callback, and the presumption
+is that the weakly referenced object is unreachable trash at the time the
+callback is invoked.
+
+That's usually true, but not always.  Suppose a weakly referenced object
+becomes part of a clump of cyclic trash.  When enough cycles are broken by
+cyclic gc that the object is reclaimed, the callback is invoked.  If it's
+possible for the callback to get at objects in the cycle(s), then it may be
+possible for those objects to access (via strong references in the cycle)
+the weakly referenced object being torn down, or other objects in the cycle
+that have already suffered a tp_clear() call.  There's no guarantee that an
+object is in a sane state after tp_clear().  Bad things (including
+segfaults) can happen right then, during the callback's execution, or can
+happen at any later time if the callback manages to resurrect an insane
+object.
+
+[That missed that, in addition, a weakref to CT can exist outside CT, and
+ any callback into Python can use such a non-CT weakref to resurrect its CT
+ referent.  The same bad kinds of things can happen then.]
+
+Note that if it's possible for the callback to get at objects in the trash
+cycles, it must also be the case that the callback itself is part of the
+trash cycles.  Else the callback would have acted as an external root to
+the current collection, and nothing reachable from it would be in cyclic
+trash either.
+
+[Except that a non-CT callback can also use a non-CT weakref to get at
+ CT objects.]
+
+More, if the callback itself is in cyclic trash, then the weakref to which
+the callback is attached must also be trash, and for the same kind of
+reason:  if the weakref acted as an external root, then the callback could
+not have been cyclic trash.
+
+So a problem here requires that a weakref, that weakref's callback, and the
+weakly referenced object, all be in cyclic trash at the same time.  This
+isn't easy to stumble into by accident while Python is running, and, indeed,
+it took quite a while to dream up failing test cases.  Zope3 saw segfaults
+during shutdown, during the second call of gc in Py_Finalize, after most
+modules had been torn down.  That creates many trash cycles (esp. those
+involving new-style classes), making the problem much more likely.  Once you
+know what's required to provoke the problem, though, it's easy to create
+tests that segfault before shutdown.
+
+In 2.3.3, before breaking cycles, we first clear all the weakrefs with
+callbacks in cyclic trash.  Since the weakrefs *are* trash, and there's no
+defined-- or even predictable --order in which tp_clear() gets called on
+cyclic trash, it's defensible to first clear weakrefs with callbacks.  It's
+a feature of Python's weakrefs too that when a weakref goes away, the
+callback (if any) associated with it is thrown away too, unexecuted.
+
+[In 2.4/2.3.5, we first clear all weakrefs to CT objects, whether or not
+ those weakrefs are themselves CT, and whether or not they have callbacks.
+ The callbacks (if any) on non-CT weakrefs (if any) are invoked later,
+ after all weakrefs-to-CT have been cleared.  The callbacks (if any) on CT
+ weakrefs (if any) are never invoked, for the excruciating reasons
+ explained here.]
+
+Just that much is almost enough to prevent problems, by throwing away
+*almost* all the weakref callbacks that could get triggered by gc.  The
+problem remaining is that clearing a weakref with a callback decrefs the
+callback object, and the callback object may *itself* be weakly referenced,
+via another weakref with another callback.  So the process of clearing
+weakrefs can trigger callbacks attached to other weakrefs, and those
+latter weakrefs may or may not be part of cyclic trash.
+
+So, to prevent any Python code from running while gc is invoking tp_clear()
+on all the objects in cyclic trash,
+
+[That was always wrong:  we can't stop Python code from running when gc
+ is breaking cycles.  If an object with a __del__ method is not itself in
+ a cycle, but is reachable only from CT, then breaking cycles will, as a
+ matter of course, drop the refcount on that object to 0, and its __del__
+ will run right then.  What we can and must stop is running any Python
+ code that could access CT.]
+                                     it's not quite enough just to invoke
+tp_clear() on weakrefs with callbacks first.  Instead the weakref module
+grew a new private function (_PyWeakref_ClearRef) that does only part of
+tp_clear():  it removes the weakref from the weakly-referenced object's list
+of weakrefs, but does not decref the callback object.  So calling
+_PyWeakref_ClearRef(wr) ensures that wr's callback object will never
+trigger, and (unlike weakref's tp_clear()) also prevents any callback
+associated *with* wr's callback object from triggering.
+
+[Although we may trigger such callbacks later, as explained below.]
+
+Then we can call tp_clear on all the cyclic objects and never trigger
+Python code.
+
+[As above, not so:  it means never trigger Python code that can access CT.]
+
+After we do that, the callback objects still need to be decref'ed.  Callbacks
+(if any) *on* the callback objects that were also part of cyclic trash won't
+get invoked, because we cleared all trash weakrefs with callbacks at the
+start.  Callbacks on the callback objects that were not part of cyclic trash
+acted as external roots to everything reachable from them, so nothing
+reachable from them was part of cyclic trash, so gc didn't do any damage to
+objects reachable from them, and it's safe to call them at the end of gc.
+
+[That's so.  In addition, now we also invoke (if any) the callbacks on
+ non-CT weakrefs to CT objects, during the same pass that decrefs the
+ callback objects.]
+
+An alternative would have been to treat objects with callbacks like objects
+with __del__ methods, refusing to collect them, appending them to gc.garbage
+instead.  That would have been much easier.  Jim Fulton gave a strong
+argument against that (on Python-Dev):
+
+    There's a big difference between __del__ and weakref callbacks.
+    The __del__ method is "internal" to a design.  When you design a
+    class with a del method, you know you have to avoid including the
+    class in cycles.
+
+    Now, suppose you have a design that makes has no __del__ methods but
+    that does use cyclic data structures.  You reason about the design,
+    run tests, and convince yourself you don't have a leak.
+
+    Now, suppose some external code creates a weakref to one of your
+    objects.  All of a sudden, you start leaking.  You can look at your
+    code all you want and you won't find a reason for the leak.
+
+IOW, a class designer can out-think __del__ problems, but has no control
+over who creates weakrefs to his classes or class instances.  The class
+user has little chance either of predicting when the weakrefs he creates
+may end up in cycles.
+
+Callbacks on weakref callbacks are executed in an arbitrary order, and
+that's not good (a primary reason not to collect cycles with objects with
+__del__ methods is to avoid running finalizers in an arbitrary order).
+However, a weakref callback on a weakref callback has got to be rare.
+It's possible to do such a thing, so gc has to be robust against it, but
+I doubt anyone has done it outside the test case I wrote for it.
+
+[The callbacks (if any) on non-CT weakrefs to CT objects are also executed
+ in an arbitrary order now.  But they were before too, depending on the
+ vagaries of when tp_clear() happened to break enough cycles to trigger
+ them.  People simply shouldn't try to use __del__ or weakref callbacks to
+ do fancy stuff.]

Added: vendor/Python/current/Modules/gcmodule.c
===================================================================
--- vendor/Python/current/Modules/gcmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/gcmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1390 @@
+/*
+
+  Reference Cycle Garbage Collection
+  ==================================
+
+  Neil Schemenauer <nas at arctrix.com>
+
+  Based on a post on the python-dev list.  Ideas from Guido van Rossum,
+  Eric Tiedemann, and various others.
+
+  http://www.arctrix.com/nas/python/gc/
+  http://www.python.org/pipermail/python-dev/2000-March/003869.html
+  http://www.python.org/pipermail/python-dev/2000-March/004010.html
+  http://www.python.org/pipermail/python-dev/2000-March/004022.html
+
+  For a highlevel view of the collection process, read the collect
+  function.
+
+*/
+
+#include "Python.h"
+
+/* Get an object's GC head */
+#define AS_GC(o) ((PyGC_Head *)(o)-1)
+
+/* Get the object given the GC head */
+#define FROM_GC(g) ((PyObject *)(((PyGC_Head *)g)+1))
+
+/*** Global GC state ***/
+
+struct gc_generation {
+	PyGC_Head head;
+	int threshold; /* collection threshold */
+	int count; /* count of allocations or collections of younger
+		      generations */
+};
+
+#define NUM_GENERATIONS 3
+#define GEN_HEAD(n) (&generations[n].head)
+
+/* linked lists of container objects */
+static struct gc_generation generations[NUM_GENERATIONS] = {
+	/* PyGC_Head,				threshold,	count */
+	{{{GEN_HEAD(0), GEN_HEAD(0), 0}},	700,		0},
+	{{{GEN_HEAD(1), GEN_HEAD(1), 0}},	10,		0},
+	{{{GEN_HEAD(2), GEN_HEAD(2), 0}},	10,		0},
+};
+
+PyGC_Head *_PyGC_generation0 = GEN_HEAD(0);
+
+static int enabled = 1; /* automatic collection enabled? */
+
+/* true if we are currently running the collector */
+static int collecting = 0;
+
+/* list of uncollectable objects */
+static PyObject *garbage = NULL;
+
+/* Python string to use if unhandled exception occurs */
+static PyObject *gc_str = NULL;
+
+/* Python string used to look for __del__ attribute. */
+static PyObject *delstr = NULL;
+
+/* set for debugging information */
+#define DEBUG_STATS		(1<<0) /* print collection statistics */
+#define DEBUG_COLLECTABLE	(1<<1) /* print collectable objects */
+#define DEBUG_UNCOLLECTABLE	(1<<2) /* print uncollectable objects */
+#define DEBUG_INSTANCES		(1<<3) /* print instances */
+#define DEBUG_OBJECTS		(1<<4) /* print other objects */
+#define DEBUG_SAVEALL		(1<<5) /* save all garbage in gc.garbage */
+#define DEBUG_LEAK		DEBUG_COLLECTABLE | \
+				DEBUG_UNCOLLECTABLE | \
+				DEBUG_INSTANCES | \
+				DEBUG_OBJECTS | \
+				DEBUG_SAVEALL
+static int debug;
+static PyObject *tmod = NULL;
+
+/*--------------------------------------------------------------------------
+gc_refs values.
+
+Between collections, every gc'ed object has one of two gc_refs values:
+
+GC_UNTRACKED
+    The initial state; objects returned by PyObject_GC_Malloc are in this
+    state.  The object doesn't live in any generation list, and its
+    tp_traverse slot must not be called.
+
+GC_REACHABLE
+    The object lives in some generation list, and its tp_traverse is safe to
+    call.  An object transitions to GC_REACHABLE when PyObject_GC_Track
+    is called.
+
+During a collection, gc_refs can temporarily take on other states:
+
+>= 0
+    At the start of a collection, update_refs() copies the true refcount
+    to gc_refs, for each object in the generation being collected.
+    subtract_refs() then adjusts gc_refs so that it equals the number of
+    times an object is referenced directly from outside the generation
+    being collected.
+    gc_refs remains >= 0 throughout these steps.
+
+GC_TENTATIVELY_UNREACHABLE
+    move_unreachable() then moves objects not reachable (whether directly or
+    indirectly) from outside the generation into an "unreachable" set.
+    Objects that are found to be reachable have gc_refs set to GC_REACHABLE
+    again.  Objects that are found to be unreachable have gc_refs set to
+    GC_TENTATIVELY_UNREACHABLE.  It's "tentatively" because the pass doing
+    this can't be sure until it ends, and GC_TENTATIVELY_UNREACHABLE may
+    transition back to GC_REACHABLE.
+
+    Only objects with GC_TENTATIVELY_UNREACHABLE still set are candidates
+    for collection.  If it's decided not to collect such an object (e.g.,
+    it has a __del__ method), its gc_refs is restored to GC_REACHABLE again.
+----------------------------------------------------------------------------
+*/
+#define GC_UNTRACKED			_PyGC_REFS_UNTRACKED
+#define GC_REACHABLE			_PyGC_REFS_REACHABLE
+#define GC_TENTATIVELY_UNREACHABLE	_PyGC_REFS_TENTATIVELY_UNREACHABLE
+
+#define IS_TRACKED(o) ((AS_GC(o))->gc.gc_refs != GC_UNTRACKED)
+#define IS_REACHABLE(o) ((AS_GC(o))->gc.gc_refs == GC_REACHABLE)
+#define IS_TENTATIVELY_UNREACHABLE(o) ( \
+	(AS_GC(o))->gc.gc_refs == GC_TENTATIVELY_UNREACHABLE)
+
+/*** list functions ***/
+
+static void
+gc_list_init(PyGC_Head *list)
+{
+	list->gc.gc_prev = list;
+	list->gc.gc_next = list;
+}
+
+static int
+gc_list_is_empty(PyGC_Head *list)
+{
+	return (list->gc.gc_next == list);
+}
+
+#if 0
+/* This became unused after gc_list_move() was introduced. */
+/* Append `node` to `list`. */
+static void
+gc_list_append(PyGC_Head *node, PyGC_Head *list)
+{
+	node->gc.gc_next = list;
+	node->gc.gc_prev = list->gc.gc_prev;
+	node->gc.gc_prev->gc.gc_next = node;
+	list->gc.gc_prev = node;
+}
+#endif
+
+/* Remove `node` from the gc list it's currently in. */
+static void
+gc_list_remove(PyGC_Head *node)
+{
+	node->gc.gc_prev->gc.gc_next = node->gc.gc_next;
+	node->gc.gc_next->gc.gc_prev = node->gc.gc_prev;
+	node->gc.gc_next = NULL; /* object is not currently tracked */
+}
+
+/* Move `node` from the gc list it's currently in (which is not explicitly
+ * named here) to the end of `list`.  This is semantically the same as
+ * gc_list_remove(node) followed by gc_list_append(node, list).
+ */
+static void
+gc_list_move(PyGC_Head *node, PyGC_Head *list)
+{
+	PyGC_Head *new_prev;
+	PyGC_Head *current_prev = node->gc.gc_prev;
+	PyGC_Head *current_next = node->gc.gc_next;
+	/* Unlink from current list. */
+	current_prev->gc.gc_next = current_next;
+	current_next->gc.gc_prev = current_prev;
+	/* Relink at end of new list. */
+	new_prev = node->gc.gc_prev = list->gc.gc_prev;
+	new_prev->gc.gc_next = list->gc.gc_prev = node;
+	node->gc.gc_next = list;
+}
+
+/* append list `from` onto list `to`; `from` becomes an empty list */
+static void
+gc_list_merge(PyGC_Head *from, PyGC_Head *to)
+{
+	PyGC_Head *tail;
+	assert(from != to);
+	if (!gc_list_is_empty(from)) {
+		tail = to->gc.gc_prev;
+		tail->gc.gc_next = from->gc.gc_next;
+		tail->gc.gc_next->gc.gc_prev = tail;
+		to->gc.gc_prev = from->gc.gc_prev;
+		to->gc.gc_prev->gc.gc_next = to;
+	}
+	gc_list_init(from);
+}
+
+static Py_ssize_t
+gc_list_size(PyGC_Head *list)
+{
+	PyGC_Head *gc;
+	Py_ssize_t n = 0;
+	for (gc = list->gc.gc_next; gc != list; gc = gc->gc.gc_next) {
+		n++;
+	}
+	return n;
+}
+
+/* Append objects in a GC list to a Python list.
+ * Return 0 if all OK, < 0 if error (out of memory for list).
+ */
+static int
+append_objects(PyObject *py_list, PyGC_Head *gc_list)
+{
+	PyGC_Head *gc;
+	for (gc = gc_list->gc.gc_next; gc != gc_list; gc = gc->gc.gc_next) {
+		PyObject *op = FROM_GC(gc);
+		if (op != py_list) {
+			if (PyList_Append(py_list, op)) {
+				return -1; /* exception */
+			}
+		}
+	}
+	return 0;
+}
+
+/*** end of list stuff ***/
+
+
+/* Set all gc_refs = ob_refcnt.  After this, gc_refs is > 0 for all objects
+ * in containers, and is GC_REACHABLE for all tracked gc objects not in
+ * containers.
+ */
+static void
+update_refs(PyGC_Head *containers)
+{
+	PyGC_Head *gc = containers->gc.gc_next;
+	for (; gc != containers; gc = gc->gc.gc_next) {
+		assert(gc->gc.gc_refs == GC_REACHABLE);
+		gc->gc.gc_refs = FROM_GC(gc)->ob_refcnt;
+		/* Python's cyclic gc should never see an incoming refcount
+		 * of 0:  if something decref'ed to 0, it should have been
+		 * deallocated immediately at that time.
+		 * Possible cause (if the assert triggers):  a tp_dealloc
+		 * routine left a gc-aware object tracked during its teardown
+		 * phase, and did something-- or allowed something to happen --
+		 * that called back into Python.  gc can trigger then, and may
+		 * see the still-tracked dying object.  Before this assert
+		 * was added, such mistakes went on to allow gc to try to
+		 * delete the object again.  In a debug build, that caused
+		 * a mysterious segfault, when _Py_ForgetReference tried
+		 * to remove the object from the doubly-linked list of all
+		 * objects a second time.  In a release build, an actual
+		 * double deallocation occurred, which leads to corruption
+		 * of the allocator's internal bookkeeping pointers.  That's
+		 * so serious that maybe this should be a release-build
+		 * check instead of an assert?
+		 */
+		assert(gc->gc.gc_refs != 0);
+	}
+}
+
+/* A traversal callback for subtract_refs. */
+static int
+visit_decref(PyObject *op, void *data)
+{
+        assert(op != NULL);
+	if (PyObject_IS_GC(op)) {
+		PyGC_Head *gc = AS_GC(op);
+		/* We're only interested in gc_refs for objects in the
+		 * generation being collected, which can be recognized
+		 * because only they have positive gc_refs.
+		 */
+		assert(gc->gc.gc_refs != 0); /* else refcount was too small */
+		if (gc->gc.gc_refs > 0)
+			gc->gc.gc_refs--;
+	}
+	return 0;
+}
+
+/* Subtract internal references from gc_refs.  After this, gc_refs is >= 0
+ * for all objects in containers, and is GC_REACHABLE for all tracked gc
+ * objects not in containers.  The ones with gc_refs > 0 are directly
+ * reachable from outside containers, and so can't be collected.
+ */
+static void
+subtract_refs(PyGC_Head *containers)
+{
+	traverseproc traverse;
+	PyGC_Head *gc = containers->gc.gc_next;
+	for (; gc != containers; gc=gc->gc.gc_next) {
+		traverse = FROM_GC(gc)->ob_type->tp_traverse;
+		(void) traverse(FROM_GC(gc),
+			       (visitproc)visit_decref,
+			       NULL);
+	}
+}
+
+/* A traversal callback for move_unreachable. */
+static int
+visit_reachable(PyObject *op, PyGC_Head *reachable)
+{
+	if (PyObject_IS_GC(op)) {
+		PyGC_Head *gc = AS_GC(op);
+		const Py_ssize_t gc_refs = gc->gc.gc_refs;
+
+		if (gc_refs == 0) {
+			/* This is in move_unreachable's 'young' list, but
+			 * the traversal hasn't yet gotten to it.  All
+			 * we need to do is tell move_unreachable that it's
+			 * reachable.
+			 */
+			gc->gc.gc_refs = 1;
+		}
+		else if (gc_refs == GC_TENTATIVELY_UNREACHABLE) {
+			/* This had gc_refs = 0 when move_unreachable got
+			 * to it, but turns out it's reachable after all.
+			 * Move it back to move_unreachable's 'young' list,
+			 * and move_unreachable will eventually get to it
+			 * again.
+			 */
+			gc_list_move(gc, reachable);
+			gc->gc.gc_refs = 1;
+		}
+		/* Else there's nothing to do.
+		 * If gc_refs > 0, it must be in move_unreachable's 'young'
+		 * list, and move_unreachable will eventually get to it.
+		 * If gc_refs == GC_REACHABLE, it's either in some other
+		 * generation so we don't care about it, or move_unreachable
+		 * already dealt with it.
+		 * If gc_refs == GC_UNTRACKED, it must be ignored.
+		 */
+		 else {
+		 	assert(gc_refs > 0
+		 	       || gc_refs == GC_REACHABLE
+		 	       || gc_refs == GC_UNTRACKED);
+		 }
+	}
+	return 0;
+}
+
+/* Move the unreachable objects from young to unreachable.  After this,
+ * all objects in young have gc_refs = GC_REACHABLE, and all objects in
+ * unreachable have gc_refs = GC_TENTATIVELY_UNREACHABLE.  All tracked
+ * gc objects not in young or unreachable still have gc_refs = GC_REACHABLE.
+ * All objects in young after this are directly or indirectly reachable
+ * from outside the original young; and all objects in unreachable are
+ * not.
+ */
+static void
+move_unreachable(PyGC_Head *young, PyGC_Head *unreachable)
+{
+	PyGC_Head *gc = young->gc.gc_next;
+
+	/* Invariants:  all objects "to the left" of us in young have gc_refs
+	 * = GC_REACHABLE, and are indeed reachable (directly or indirectly)
+	 * from outside the young list as it was at entry.  All other objects
+	 * from the original young "to the left" of us are in unreachable now,
+	 * and have gc_refs = GC_TENTATIVELY_UNREACHABLE.  All objects to the
+	 * left of us in 'young' now have been scanned, and no objects here
+	 * or to the right have been scanned yet.
+	 */
+
+	while (gc != young) {
+		PyGC_Head *next;
+
+		if (gc->gc.gc_refs) {
+                        /* gc is definitely reachable from outside the
+                         * original 'young'.  Mark it as such, and traverse
+                         * its pointers to find any other objects that may
+                         * be directly reachable from it.  Note that the
+                         * call to tp_traverse may append objects to young,
+                         * so we have to wait until it returns to determine
+                         * the next object to visit.
+                         */
+                        PyObject *op = FROM_GC(gc);
+                        traverseproc traverse = op->ob_type->tp_traverse;
+                        assert(gc->gc.gc_refs > 0);
+                        gc->gc.gc_refs = GC_REACHABLE;
+                        (void) traverse(op,
+                                        (visitproc)visit_reachable,
+                                        (void *)young);
+                        next = gc->gc.gc_next;
+		}
+		else {
+			/* This *may* be unreachable.  To make progress,
+			 * assume it is.  gc isn't directly reachable from
+			 * any object we've already traversed, but may be
+			 * reachable from an object we haven't gotten to yet.
+			 * visit_reachable will eventually move gc back into
+			 * young if that's so, and we'll see it again.
+			 */
+			next = gc->gc.gc_next;
+			gc_list_move(gc, unreachable);
+			gc->gc.gc_refs = GC_TENTATIVELY_UNREACHABLE;
+		}
+		gc = next;
+	}
+}
+
+/* Return true if object has a finalization method.
+ * CAUTION:  An instance of an old-style class has to be checked for a
+ *__del__ method, and earlier versions of this used to call PyObject_HasAttr,
+ * which in turn could call the class's __getattr__ hook (if any).  That
+ * could invoke arbitrary Python code, mutating the object graph in arbitrary
+ * ways, and that was the source of some excruciatingly subtle bugs.
+ */
+static int
+has_finalizer(PyObject *op)
+{
+	if (PyInstance_Check(op)) {
+		assert(delstr != NULL);
+		return _PyInstance_Lookup(op, delstr) != NULL;
+	}
+	else if (PyType_HasFeature(op->ob_type, Py_TPFLAGS_HEAPTYPE))
+		return op->ob_type->tp_del != NULL;
+	else if (PyGen_CheckExact(op))
+		return PyGen_NeedsFinalizing((PyGenObject *)op);
+	else
+		return 0;
+}
+
+/* Move the objects in unreachable with __del__ methods into `finalizers`.
+ * Objects moved into `finalizers` have gc_refs set to GC_REACHABLE; the
+ * objects remaining in unreachable are left at GC_TENTATIVELY_UNREACHABLE.
+ */
+static void
+move_finalizers(PyGC_Head *unreachable, PyGC_Head *finalizers)
+{
+	PyGC_Head *gc;
+	PyGC_Head *next;
+
+	/* March over unreachable.  Move objects with finalizers into
+	 * `finalizers`.
+	 */
+	for (gc = unreachable->gc.gc_next; gc != unreachable; gc = next) {
+		PyObject *op = FROM_GC(gc);
+
+		assert(IS_TENTATIVELY_UNREACHABLE(op));
+		next = gc->gc.gc_next;
+
+		if (has_finalizer(op)) {
+			gc_list_move(gc, finalizers);
+			gc->gc.gc_refs = GC_REACHABLE;
+		}
+	}
+}
+
+/* A traversal callback for move_finalizer_reachable. */
+static int
+visit_move(PyObject *op, PyGC_Head *tolist)
+{
+	if (PyObject_IS_GC(op)) {
+		if (IS_TENTATIVELY_UNREACHABLE(op)) {
+			PyGC_Head *gc = AS_GC(op);
+			gc_list_move(gc, tolist);
+			gc->gc.gc_refs = GC_REACHABLE;
+		}
+	}
+	return 0;
+}
+
+/* Move objects that are reachable from finalizers, from the unreachable set
+ * into finalizers set.
+ */
+static void
+move_finalizer_reachable(PyGC_Head *finalizers)
+{
+	traverseproc traverse;
+	PyGC_Head *gc = finalizers->gc.gc_next;
+	for (; gc != finalizers; gc = gc->gc.gc_next) {
+		/* Note that the finalizers list may grow during this. */
+		traverse = FROM_GC(gc)->ob_type->tp_traverse;
+		(void) traverse(FROM_GC(gc),
+				(visitproc)visit_move,
+				(void *)finalizers);
+	}
+}
+
+/* Clear all weakrefs to unreachable objects, and if such a weakref has a
+ * callback, invoke it if necessary.  Note that it's possible for such
+ * weakrefs to be outside the unreachable set -- indeed, those are precisely
+ * the weakrefs whose callbacks must be invoked.  See gc_weakref.txt for
+ * overview & some details.  Some weakrefs with callbacks may be reclaimed
+ * directly by this routine; the number reclaimed is the return value.  Other
+ * weakrefs with callbacks may be moved into the `old` generation.  Objects
+ * moved into `old` have gc_refs set to GC_REACHABLE; the objects remaining in
+ * unreachable are left at GC_TENTATIVELY_UNREACHABLE.  When this returns,
+ * no object in `unreachable` is weakly referenced anymore.
+ */
+static int
+handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old)
+{
+	PyGC_Head *gc;
+	PyObject *op;		/* generally FROM_GC(gc) */
+	PyWeakReference *wr;	/* generally a cast of op */
+	PyGC_Head wrcb_to_call;	/* weakrefs with callbacks to call */
+	PyGC_Head *next;
+	int num_freed = 0;
+
+	gc_list_init(&wrcb_to_call);
+
+	/* Clear all weakrefs to the objects in unreachable.  If such a weakref
+	 * also has a callback, move it into `wrcb_to_call` if the callback
+	 * needs to be invoked.  Note that we cannot invoke any callbacks until
+	 * all weakrefs to unreachable objects are cleared, lest the callback
+	 * resurrect an unreachable object via a still-active weakref.  We
+	 * make another pass over wrcb_to_call, invoking callbacks, after this
+	 * pass completes.
+	 */
+	for (gc = unreachable->gc.gc_next; gc != unreachable; gc = next) {
+		PyWeakReference **wrlist;
+
+		op = FROM_GC(gc);
+		assert(IS_TENTATIVELY_UNREACHABLE(op));
+		next = gc->gc.gc_next;
+
+		if (! PyType_SUPPORTS_WEAKREFS(op->ob_type))
+			continue;
+
+		/* It supports weakrefs.  Does it have any? */
+		wrlist = (PyWeakReference **)
+			     		PyObject_GET_WEAKREFS_LISTPTR(op);
+
+		/* `op` may have some weakrefs.  March over the list, clear
+		 * all the weakrefs, and move the weakrefs with callbacks
+		 * that must be called into wrcb_to_call.
+		 */
+		for (wr = *wrlist; wr != NULL; wr = *wrlist) {
+			PyGC_Head *wrasgc;	/* AS_GC(wr) */
+
+			/* _PyWeakref_ClearRef clears the weakref but leaves
+			 * the callback pointer intact.  Obscure:  it also
+			 * changes *wrlist.
+			 */
+			assert(wr->wr_object == op);
+			_PyWeakref_ClearRef(wr);
+			assert(wr->wr_object == Py_None);
+			if (wr->wr_callback == NULL)
+				continue;	/* no callback */
+
+	/* Headache time.  `op` is going away, and is weakly referenced by
+	 * `wr`, which has a callback.  Should the callback be invoked?  If wr
+	 * is also trash, no:
+	 *
+	 * 1. There's no need to call it.  The object and the weakref are
+	 *    both going away, so it's legitimate to pretend the weakref is
+	 *    going away first.  The user has to ensure a weakref outlives its
+	 *    referent if they want a guarantee that the wr callback will get
+	 *    invoked.
+	 *
+	 * 2. It may be catastrophic to call it.  If the callback is also in
+	 *    cyclic trash (CT), then although the CT is unreachable from
+	 *    outside the current generation, CT may be reachable from the
+	 *    callback.  Then the callback could resurrect insane objects.
+	 *
+	 * Since the callback is never needed and may be unsafe in this case,
+	 * wr is simply left in the unreachable set.  Note that because we
+	 * already called _PyWeakref_ClearRef(wr), its callback will never
+	 * trigger.
+	 *
+	 * OTOH, if wr isn't part of CT, we should invoke the callback:  the
+	 * weakref outlived the trash.  Note that since wr isn't CT in this
+	 * case, its callback can't be CT either -- wr acted as an external
+	 * root to this generation, and therefore its callback did too.  So
+	 * nothing in CT is reachable from the callback either, so it's hard
+	 * to imagine how calling it later could create a problem for us.  wr
+	 * is moved to wrcb_to_call in this case.
+	 */
+	 		if (IS_TENTATIVELY_UNREACHABLE(wr))
+	 			continue;
+			assert(IS_REACHABLE(wr));
+
+			/* Create a new reference so that wr can't go away
+			 * before we can process it again.
+			 */
+			Py_INCREF(wr);
+
+			/* Move wr to wrcb_to_call, for the next pass. */
+			wrasgc = AS_GC(wr);
+			assert(wrasgc != next); /* wrasgc is reachable, but
+			                           next isn't, so they can't
+			                           be the same */
+			gc_list_move(wrasgc, &wrcb_to_call);
+		}
+	}
+
+	/* Invoke the callbacks we decided to honor.  It's safe to invoke them
+	 * because they can't reference unreachable objects.
+	 */
+	while (! gc_list_is_empty(&wrcb_to_call)) {
+		PyObject *temp;
+		PyObject *callback;
+
+		gc = wrcb_to_call.gc.gc_next;
+		op = FROM_GC(gc);
+		assert(IS_REACHABLE(op));
+		assert(PyWeakref_Check(op));
+		wr = (PyWeakReference *)op;
+		callback = wr->wr_callback;
+		assert(callback != NULL);
+
+		/* copy-paste of weakrefobject.c's handle_callback() */
+		temp = PyObject_CallFunctionObjArgs(callback, wr, NULL);
+		if (temp == NULL)
+			PyErr_WriteUnraisable(callback);
+		else
+			Py_DECREF(temp);
+
+		/* Give up the reference we created in the first pass.  When
+		 * op's refcount hits 0 (which it may or may not do right now),
+		 * op's tp_dealloc will decref op->wr_callback too.  Note
+		 * that the refcount probably will hit 0 now, and because this
+		 * weakref was reachable to begin with, gc didn't already
+		 * add it to its count of freed objects.  Example:  a reachable
+		 * weak value dict maps some key to this reachable weakref.
+		 * The callback removes this key->weakref mapping from the
+		 * dict, leaving no other references to the weakref (excepting
+		 * ours).
+		 */
+		Py_DECREF(op);
+		if (wrcb_to_call.gc.gc_next == gc) {
+			/* object is still alive -- move it */
+			gc_list_move(gc, old);
+		}
+		else
+			++num_freed;
+	}
+
+	return num_freed;
+}
+
+static void
+debug_instance(char *msg, PyInstanceObject *inst)
+{
+	char *cname;
+	/* simple version of instance_repr */
+	PyObject *classname = inst->in_class->cl_name;
+	if (classname != NULL && PyString_Check(classname))
+		cname = PyString_AsString(classname);
+	else
+		cname = "?";
+	PySys_WriteStderr("gc: %.100s <%.100s instance at %p>\n",
+			  msg, cname, inst);
+}
+
+static void
+debug_cycle(char *msg, PyObject *op)
+{
+	if ((debug & DEBUG_INSTANCES) && PyInstance_Check(op)) {
+		debug_instance(msg, (PyInstanceObject *)op);
+	}
+	else if (debug & DEBUG_OBJECTS) {
+		PySys_WriteStderr("gc: %.100s <%.100s %p>\n",
+				  msg, op->ob_type->tp_name, op);
+	}
+}
+
+/* Handle uncollectable garbage (cycles with finalizers, and stuff reachable
+ * only from such cycles).
+ * If DEBUG_SAVEALL, all objects in finalizers are appended to the module
+ * garbage list (a Python list), else only the objects in finalizers with
+ * __del__ methods are appended to garbage.  All objects in finalizers are
+ * merged into the old list regardless.
+ * Returns 0 if all OK, <0 on error (out of memory to grow the garbage list).
+ * The finalizers list is made empty on a successful return.
+ */
+static int
+handle_finalizers(PyGC_Head *finalizers, PyGC_Head *old)
+{
+	PyGC_Head *gc = finalizers->gc.gc_next;
+
+	if (garbage == NULL) {
+		garbage = PyList_New(0);
+		if (garbage == NULL)
+			Py_FatalError("gc couldn't create gc.garbage list");
+	}
+	for (; gc != finalizers; gc = gc->gc.gc_next) {
+		PyObject *op = FROM_GC(gc);
+
+		if ((debug & DEBUG_SAVEALL) || has_finalizer(op)) {
+			if (PyList_Append(garbage, op) < 0)
+				return -1;
+		}
+	}
+
+	gc_list_merge(finalizers, old);
+	return 0;
+}
+
+/* Break reference cycles by clearing the containers involved.	This is
+ * tricky business as the lists can be changing and we don't know which
+ * objects may be freed.  It is possible I screwed something up here.
+ */
+static void
+delete_garbage(PyGC_Head *collectable, PyGC_Head *old)
+{
+	inquiry clear;
+
+	while (!gc_list_is_empty(collectable)) {
+		PyGC_Head *gc = collectable->gc.gc_next;
+		PyObject *op = FROM_GC(gc);
+
+		assert(IS_TENTATIVELY_UNREACHABLE(op));
+		if (debug & DEBUG_SAVEALL) {
+			PyList_Append(garbage, op);
+		}
+		else {
+			if ((clear = op->ob_type->tp_clear) != NULL) {
+				Py_INCREF(op);
+				clear(op);
+				Py_DECREF(op);
+			}
+		}
+		if (collectable->gc.gc_next == gc) {
+			/* object is still alive, move it, it may die later */
+			gc_list_move(gc, old);
+			gc->gc.gc_refs = GC_REACHABLE;
+		}
+	}
+}
+
+/* This is the main function.  Read this to understand how the
+ * collection process works. */
+static Py_ssize_t
+collect(int generation)
+{
+	int i;
+	Py_ssize_t m = 0; /* # objects collected */
+	Py_ssize_t n = 0; /* # unreachable objects that couldn't be collected */
+	PyGC_Head *young; /* the generation we are examining */
+	PyGC_Head *old; /* next older generation */
+	PyGC_Head unreachable; /* non-problematic unreachable trash */
+	PyGC_Head finalizers;  /* objects with, & reachable from, __del__ */
+	PyGC_Head *gc;
+	double t1 = 0.0;
+
+	if (delstr == NULL) {
+		delstr = PyString_InternFromString("__del__");
+		if (delstr == NULL)
+			Py_FatalError("gc couldn't allocate \"__del__\"");
+	}
+
+	if (debug & DEBUG_STATS) {
+		if (tmod != NULL) {
+			PyObject *f = PyObject_CallMethod(tmod, "time", NULL);
+			if (f == NULL) {
+				PyErr_Clear();
+			}
+			else {
+				t1 = PyFloat_AsDouble(f);
+				Py_DECREF(f);
+			}
+		}
+		PySys_WriteStderr("gc: collecting generation %d...\n",
+				  generation);
+		PySys_WriteStderr("gc: objects in each generation:");
+		for (i = 0; i < NUM_GENERATIONS; i++)
+			PySys_WriteStderr(" %" PY_FORMAT_SIZE_T "d",
+					  gc_list_size(GEN_HEAD(i)));
+		PySys_WriteStderr("\n");
+	}
+
+	/* update collection and allocation counters */
+	if (generation+1 < NUM_GENERATIONS)
+		generations[generation+1].count += 1;
+	for (i = 0; i <= generation; i++)
+		generations[i].count = 0;
+
+	/* merge younger generations with one we are currently collecting */
+	for (i = 0; i < generation; i++) {
+		gc_list_merge(GEN_HEAD(i), GEN_HEAD(generation));
+	}
+
+	/* handy references */
+	young = GEN_HEAD(generation);
+	if (generation < NUM_GENERATIONS-1)
+		old = GEN_HEAD(generation+1);
+	else
+		old = young;
+
+	/* Using ob_refcnt and gc_refs, calculate which objects in the
+	 * container set are reachable from outside the set (i.e., have a
+	 * refcount greater than 0 when all the references within the
+	 * set are taken into account).
+	 */
+	update_refs(young);
+	subtract_refs(young);
+
+	/* Leave everything reachable from outside young in young, and move
+	 * everything else (in young) to unreachable.
+	 * NOTE:  This used to move the reachable objects into a reachable
+	 * set instead.  But most things usually turn out to be reachable,
+	 * so it's more efficient to move the unreachable things.
+	 */
+	gc_list_init(&unreachable);
+	move_unreachable(young, &unreachable);
+
+	/* Move reachable objects to next generation. */
+	if (young != old)
+		gc_list_merge(young, old);
+
+	/* All objects in unreachable are trash, but objects reachable from
+	 * finalizers can't safely be deleted.  Python programmers should take
+	 * care not to create such things.  For Python, finalizers means
+	 * instance objects with __del__ methods.  Weakrefs with callbacks
+	 * can also call arbitrary Python code but they will be dealt with by
+	 * handle_weakrefs().
+ 	 */
+	gc_list_init(&finalizers);
+	move_finalizers(&unreachable, &finalizers);
+	/* finalizers contains the unreachable objects with a finalizer;
+	 * unreachable objects reachable *from* those are also uncollectable,
+	 * and we move those into the finalizers list too.
+	 */
+	move_finalizer_reachable(&finalizers);
+
+	/* Collect statistics on collectable objects found and print
+	 * debugging information.
+	 */
+	for (gc = unreachable.gc.gc_next; gc != &unreachable;
+			gc = gc->gc.gc_next) {
+		m++;
+		if (debug & DEBUG_COLLECTABLE) {
+			debug_cycle("collectable", FROM_GC(gc));
+		}
+		if (tmod != NULL && (debug & DEBUG_STATS)) {
+			PyObject *f = PyObject_CallMethod(tmod, "time", NULL);
+			if (f == NULL) {
+				PyErr_Clear();
+			}
+			else {
+				t1 = PyFloat_AsDouble(f)-t1;
+				Py_DECREF(f);
+				PySys_WriteStderr("gc: %.4fs elapsed.\n", t1);
+			}
+		}
+	}
+
+	/* Clear weakrefs and invoke callbacks as necessary. */
+	m += handle_weakrefs(&unreachable, old);
+
+	/* Call tp_clear on objects in the unreachable set.  This will cause
+	 * the reference cycles to be broken.  It may also cause some objects
+	 * in finalizers to be freed.
+	 */
+	delete_garbage(&unreachable, old);
+
+	/* Collect statistics on uncollectable objects found and print
+	 * debugging information. */
+	for (gc = finalizers.gc.gc_next;
+	     gc != &finalizers;
+	     gc = gc->gc.gc_next) {
+		n++;
+		if (debug & DEBUG_UNCOLLECTABLE)
+			debug_cycle("uncollectable", FROM_GC(gc));
+	}
+	if (debug & DEBUG_STATS) {
+		if (m == 0 && n == 0)
+			PySys_WriteStderr("gc: done.\n");
+		else
+			PySys_WriteStderr(
+			    "gc: done, "
+			    "%" PY_FORMAT_SIZE_T "d unreachable, "
+			    "%" PY_FORMAT_SIZE_T "d uncollectable.\n",
+			    n+m, n);
+	}
+
+	/* Append instances in the uncollectable set to a Python
+	 * reachable list of garbage.  The programmer has to deal with
+	 * this if they insist on creating this type of structure.
+	 */
+	(void)handle_finalizers(&finalizers, old);
+
+	if (PyErr_Occurred()) {
+		if (gc_str == NULL)
+			gc_str = PyString_FromString("garbage collection");
+		PyErr_WriteUnraisable(gc_str);
+		Py_FatalError("unexpected exception during garbage collection");
+	}
+	return n+m;
+}
+
+static Py_ssize_t
+collect_generations(void)
+{
+	int i;
+	Py_ssize_t n = 0;
+
+	/* Find the oldest generation (higest numbered) where the count
+	 * exceeds the threshold.  Objects in the that generation and
+	 * generations younger than it will be collected. */
+	for (i = NUM_GENERATIONS-1; i >= 0; i--) {
+		if (generations[i].count > generations[i].threshold) {
+			n = collect(i);
+			break;
+		}
+	}
+	return n;
+}
+
+PyDoc_STRVAR(gc_enable__doc__,
+"enable() -> None\n"
+"\n"
+"Enable automatic garbage collection.\n");
+
+static PyObject *
+gc_enable(PyObject *self, PyObject *noargs)
+{
+	enabled = 1;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(gc_disable__doc__,
+"disable() -> None\n"
+"\n"
+"Disable automatic garbage collection.\n");
+
+static PyObject *
+gc_disable(PyObject *self, PyObject *noargs)
+{
+	enabled = 0;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(gc_isenabled__doc__,
+"isenabled() -> status\n"
+"\n"
+"Returns true if automatic garbage collection is enabled.\n");
+
+static PyObject *
+gc_isenabled(PyObject *self, PyObject *noargs)
+{
+	return PyBool_FromLong((long)enabled);
+}
+
+PyDoc_STRVAR(gc_collect__doc__,
+"collect([generation]) -> n\n"
+"\n"
+"With no arguments, run a full collection.  The optional argument\n"
+"may be an integer specifying which generation to collect.  A ValueError\n"
+"is raised if the generation number is invalid.\n\n"
+"The number of unreachable objects is returned.\n");
+
+static PyObject *
+gc_collect(PyObject *self, PyObject *args, PyObject *kws)
+{
+	static char *keywords[] = {"generation", NULL};
+	int genarg = NUM_GENERATIONS - 1;
+	Py_ssize_t n;
+
+	if (!PyArg_ParseTupleAndKeywords(args, kws, "|i", keywords, &genarg))
+		return NULL;
+
+	else if (genarg < 0 || genarg >= NUM_GENERATIONS) {
+		PyErr_SetString(PyExc_ValueError, "invalid generation");
+		return NULL;
+	}
+
+	if (collecting)
+		n = 0; /* already collecting, don't do anything */
+	else {
+		collecting = 1;
+		n = collect(genarg);
+		collecting = 0;
+	}
+
+	return PyInt_FromSsize_t(n);
+}
+
+PyDoc_STRVAR(gc_set_debug__doc__,
+"set_debug(flags) -> None\n"
+"\n"
+"Set the garbage collection debugging flags. Debugging information is\n"
+"written to sys.stderr.\n"
+"\n"
+"flags is an integer and can have the following bits turned on:\n"
+"\n"
+"  DEBUG_STATS - Print statistics during collection.\n"
+"  DEBUG_COLLECTABLE - Print collectable objects found.\n"
+"  DEBUG_UNCOLLECTABLE - Print unreachable but uncollectable objects found.\n"
+"  DEBUG_INSTANCES - Print instance objects.\n"
+"  DEBUG_OBJECTS - Print objects other than instances.\n"
+"  DEBUG_SAVEALL - Save objects to gc.garbage rather than freeing them.\n"
+"  DEBUG_LEAK - Debug leaking programs (everything but STATS).\n");
+
+static PyObject *
+gc_set_debug(PyObject *self, PyObject *args)
+{
+	if (!PyArg_ParseTuple(args, "i:set_debug", &debug))
+		return NULL;
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(gc_get_debug__doc__,
+"get_debug() -> flags\n"
+"\n"
+"Get the garbage collection debugging flags.\n");
+
+static PyObject *
+gc_get_debug(PyObject *self, PyObject *noargs)
+{
+	return Py_BuildValue("i", debug);
+}
+
+PyDoc_STRVAR(gc_set_thresh__doc__,
+"set_threshold(threshold0, [threshold1, threshold2]) -> None\n"
+"\n"
+"Sets the collection thresholds.  Setting threshold0 to zero disables\n"
+"collection.\n");
+
+static PyObject *
+gc_set_thresh(PyObject *self, PyObject *args)
+{
+	int i;
+	if (!PyArg_ParseTuple(args, "i|ii:set_threshold",
+			      &generations[0].threshold,
+			      &generations[1].threshold,
+			      &generations[2].threshold))
+		return NULL;
+	for (i = 2; i < NUM_GENERATIONS; i++) {
+ 		/* generations higher than 2 get the same threshold */
+		generations[i].threshold = generations[2].threshold;
+	}
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(gc_get_thresh__doc__,
+"get_threshold() -> (threshold0, threshold1, threshold2)\n"
+"\n"
+"Return the current collection thresholds\n");
+
+static PyObject *
+gc_get_thresh(PyObject *self, PyObject *noargs)
+{
+	return Py_BuildValue("(iii)",
+			     generations[0].threshold,
+			     generations[1].threshold,
+			     generations[2].threshold);
+}
+
+PyDoc_STRVAR(gc_get_count__doc__,
+"get_count() -> (count0, count1, count2)\n"
+"\n"
+"Return the current collection counts\n");
+
+static PyObject *
+gc_get_count(PyObject *self, PyObject *noargs)
+{
+	return Py_BuildValue("(iii)",
+			     generations[0].count,
+			     generations[1].count,
+			     generations[2].count);
+}
+
+static int
+referrersvisit(PyObject* obj, PyObject *objs)
+{
+	Py_ssize_t i;
+	for (i = 0; i < PyTuple_GET_SIZE(objs); i++)
+		if (PyTuple_GET_ITEM(objs, i) == obj)
+			return 1;
+	return 0;
+}
+
+static int
+gc_referrers_for(PyObject *objs, PyGC_Head *list, PyObject *resultlist)
+{
+	PyGC_Head *gc;
+	PyObject *obj;
+	traverseproc traverse;
+	for (gc = list->gc.gc_next; gc != list; gc = gc->gc.gc_next) {
+		obj = FROM_GC(gc);
+		traverse = obj->ob_type->tp_traverse;
+		if (obj == objs || obj == resultlist)
+			continue;
+		if (traverse(obj, (visitproc)referrersvisit, objs)) {
+			if (PyList_Append(resultlist, obj) < 0)
+				return 0; /* error */
+		}
+	}
+	return 1; /* no error */
+}
+
+PyDoc_STRVAR(gc_get_referrers__doc__,
+"get_referrers(*objs) -> list\n\
+Return the list of objects that directly refer to any of objs.");
+
+static PyObject *
+gc_get_referrers(PyObject *self, PyObject *args)
+{
+	int i;
+	PyObject *result = PyList_New(0);
+	if (!result) return NULL;
+
+	for (i = 0; i < NUM_GENERATIONS; i++) {
+		if (!(gc_referrers_for(args, GEN_HEAD(i), result))) {
+			Py_DECREF(result);
+			return NULL;
+		}
+	}
+	return result;
+}
+
+/* Append obj to list; return true if error (out of memory), false if OK. */
+static int
+referentsvisit(PyObject *obj, PyObject *list)
+{
+	return PyList_Append(list, obj) < 0;
+}
+
+PyDoc_STRVAR(gc_get_referents__doc__,
+"get_referents(*objs) -> list\n\
+Return the list of objects that are directly referred to by objs.");
+
+static PyObject *
+gc_get_referents(PyObject *self, PyObject *args)
+{
+	Py_ssize_t i;
+	PyObject *result = PyList_New(0);
+
+	if (result == NULL)
+		return NULL;
+
+	for (i = 0; i < PyTuple_GET_SIZE(args); i++) {
+		traverseproc traverse;
+		PyObject *obj = PyTuple_GET_ITEM(args, i);
+
+		if (! PyObject_IS_GC(obj))
+			continue;
+		traverse = obj->ob_type->tp_traverse;
+		if (! traverse)
+			continue;
+		if (traverse(obj, (visitproc)referentsvisit, result)) {
+			Py_DECREF(result);
+			return NULL;
+		}
+	}
+	return result;
+}
+
+PyDoc_STRVAR(gc_get_objects__doc__,
+"get_objects() -> [...]\n"
+"\n"
+"Return a list of objects tracked by the collector (excluding the list\n"
+"returned).\n");
+
+static PyObject *
+gc_get_objects(PyObject *self, PyObject *noargs)
+{
+	int i;
+	PyObject* result;
+
+	result = PyList_New(0);
+	if (result == NULL)
+		return NULL;
+	for (i = 0; i < NUM_GENERATIONS; i++) {
+		if (append_objects(result, GEN_HEAD(i))) {
+			Py_DECREF(result);
+			return NULL;
+		}
+	}
+	return result;
+}
+
+
+PyDoc_STRVAR(gc__doc__,
+"This module provides access to the garbage collector for reference cycles.\n"
+"\n"
+"enable() -- Enable automatic garbage collection.\n"
+"disable() -- Disable automatic garbage collection.\n"
+"isenabled() -- Returns true if automatic collection is enabled.\n"
+"collect() -- Do a full collection right now.\n"
+"get_count() -- Return the current collection counts.\n"
+"set_debug() -- Set debugging flags.\n"
+"get_debug() -- Get debugging flags.\n"
+"set_threshold() -- Set the collection thresholds.\n"
+"get_threshold() -- Return the current the collection thresholds.\n"
+"get_objects() -- Return a list of all objects tracked by the collector.\n"
+"get_referrers() -- Return the list of objects that refer to an object.\n"
+"get_referents() -- Return the list of objects that an object refers to.\n");
+
+static PyMethodDef GcMethods[] = {
+	{"enable",	   gc_enable,	  METH_NOARGS,  gc_enable__doc__},
+	{"disable",	   gc_disable,	  METH_NOARGS,  gc_disable__doc__},
+	{"isenabled",	   gc_isenabled,  METH_NOARGS,  gc_isenabled__doc__},
+	{"set_debug",	   gc_set_debug,  METH_VARARGS, gc_set_debug__doc__},
+	{"get_debug",	   gc_get_debug,  METH_NOARGS,  gc_get_debug__doc__},
+	{"get_count",	   gc_get_count,  METH_NOARGS,  gc_get_count__doc__},
+	{"set_threshold",  gc_set_thresh, METH_VARARGS, gc_set_thresh__doc__},
+	{"get_threshold",  gc_get_thresh, METH_NOARGS,  gc_get_thresh__doc__},
+	{"collect",	   (PyCFunction)gc_collect,
+         	METH_VARARGS | METH_KEYWORDS,           gc_collect__doc__},
+	{"get_objects",    gc_get_objects,METH_NOARGS,  gc_get_objects__doc__},
+	{"get_referrers",  gc_get_referrers, METH_VARARGS,
+		gc_get_referrers__doc__},
+	{"get_referents",  gc_get_referents, METH_VARARGS,
+		gc_get_referents__doc__},
+	{NULL,	NULL}		/* Sentinel */
+};
+
+PyMODINIT_FUNC
+initgc(void)
+{
+	PyObject *m;
+
+	m = Py_InitModule4("gc",
+			      GcMethods,
+			      gc__doc__,
+			      NULL,
+			      PYTHON_API_VERSION);
+	if (m == NULL)
+		return;
+
+	if (garbage == NULL) {
+		garbage = PyList_New(0);
+		if (garbage == NULL)
+			return;
+	}
+	Py_INCREF(garbage);
+	if (PyModule_AddObject(m, "garbage", garbage) < 0)
+		return;
+
+	/* Importing can't be done in collect() because collect()
+	 * can be called via PyGC_Collect() in Py_Finalize().
+	 * This wouldn't be a problem, except that <initialized> is
+	 * reset to 0 before calling collect which trips up
+	 * the import and triggers an assertion.
+	 */
+	if (tmod == NULL) {
+		tmod = PyImport_ImportModule("time");
+		if (tmod == NULL)
+			PyErr_Clear();
+	}
+
+#define ADD_INT(NAME) if (PyModule_AddIntConstant(m, #NAME, NAME) < 0) return
+	ADD_INT(DEBUG_STATS);
+	ADD_INT(DEBUG_COLLECTABLE);
+	ADD_INT(DEBUG_UNCOLLECTABLE);
+	ADD_INT(DEBUG_INSTANCES);
+	ADD_INT(DEBUG_OBJECTS);
+	ADD_INT(DEBUG_SAVEALL);
+	ADD_INT(DEBUG_LEAK);
+#undef ADD_INT
+}
+
+/* API to invoke gc.collect() from C */
+Py_ssize_t
+PyGC_Collect(void)
+{
+	Py_ssize_t n;
+
+	if (collecting)
+		n = 0; /* already collecting, don't do anything */
+	else {
+		collecting = 1;
+		n = collect(NUM_GENERATIONS - 1);
+		collecting = 0;
+	}
+
+	return n;
+}
+
+/* for debugging */
+void
+_PyGC_Dump(PyGC_Head *g)
+{
+	_PyObject_Dump(FROM_GC(g));
+}
+
+/* extension modules might be compiled with GC support so these
+   functions must always be available */
+
+#undef PyObject_GC_Track
+#undef PyObject_GC_UnTrack
+#undef PyObject_GC_Del
+#undef _PyObject_GC_Malloc
+
+void
+PyObject_GC_Track(void *op)
+{
+	_PyObject_GC_TRACK(op);
+}
+
+/* for binary compatibility with 2.2 */
+void
+_PyObject_GC_Track(PyObject *op)
+{
+    PyObject_GC_Track(op);
+}
+
+void
+PyObject_GC_UnTrack(void *op)
+{
+	/* Obscure:  the Py_TRASHCAN mechanism requires that we be able to
+	 * call PyObject_GC_UnTrack twice on an object.
+	 */
+	if (IS_TRACKED(op))
+		_PyObject_GC_UNTRACK(op);
+}
+
+/* for binary compatibility with 2.2 */
+void
+_PyObject_GC_UnTrack(PyObject *op)
+{
+    PyObject_GC_UnTrack(op);
+}
+
+PyObject *
+_PyObject_GC_Malloc(size_t basicsize)
+{
+	PyObject *op;
+	PyGC_Head *g = (PyGC_Head *)PyObject_MALLOC(
+                sizeof(PyGC_Head) + basicsize);
+	if (g == NULL)
+		return PyErr_NoMemory();
+	g->gc.gc_refs = GC_UNTRACKED;
+	generations[0].count++; /* number of allocated GC objects */
+ 	if (generations[0].count > generations[0].threshold &&
+ 	    enabled &&
+ 	    generations[0].threshold &&
+ 	    !collecting &&
+ 	    !PyErr_Occurred()) {
+		collecting = 1;
+		collect_generations();
+		collecting = 0;
+	}
+	op = FROM_GC(g);
+	return op;
+}
+
+PyObject *
+_PyObject_GC_New(PyTypeObject *tp)
+{
+	PyObject *op = _PyObject_GC_Malloc(_PyObject_SIZE(tp));
+	if (op != NULL)
+		op = PyObject_INIT(op, tp);
+	return op;
+}
+
+PyVarObject *
+_PyObject_GC_NewVar(PyTypeObject *tp, Py_ssize_t nitems)
+{
+	const size_t size = _PyObject_VAR_SIZE(tp, nitems);
+	PyVarObject *op = (PyVarObject *) _PyObject_GC_Malloc(size);
+	if (op != NULL)
+		op = PyObject_INIT_VAR(op, tp, nitems);
+	return op;
+}
+
+PyVarObject *
+_PyObject_GC_Resize(PyVarObject *op, Py_ssize_t nitems)
+{
+	const size_t basicsize = _PyObject_VAR_SIZE(op->ob_type, nitems);
+	PyGC_Head *g = AS_GC(op);
+	g = (PyGC_Head *)PyObject_REALLOC(g,  sizeof(PyGC_Head) + basicsize);
+	if (g == NULL)
+		return (PyVarObject *)PyErr_NoMemory();
+	op = (PyVarObject *) FROM_GC(g);
+	op->ob_size = nitems;
+	return op;
+}
+
+void
+PyObject_GC_Del(void *op)
+{
+	PyGC_Head *g = AS_GC(op);
+	if (IS_TRACKED(op))
+		gc_list_remove(g);
+	if (generations[0].count > 0) {
+		generations[0].count--;
+	}
+	PyObject_FREE(g);
+}
+
+/* for binary compatibility with 2.2 */
+#undef _PyObject_GC_Del
+void
+_PyObject_GC_Del(PyObject *op)
+{
+    PyObject_GC_Del(op);
+}

Added: vendor/Python/current/Modules/gdbmmodule.c
===================================================================
--- vendor/Python/current/Modules/gdbmmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/gdbmmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,515 @@
+
+/* DBM module using dictionary interface */
+/* Author: Anthony Baxter, after dbmmodule.c */
+/* Doc strings: Mitch Chapman */
+
+
+#include "Python.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "gdbm.h"
+
+#if defined(WIN32) && !defined(__CYGWIN__)
+#include "gdbmerrno.h"
+extern const char * gdbm_strerror(gdbm_error);
+#endif
+
+PyDoc_STRVAR(gdbmmodule__doc__,
+"This module provides an interface to the GNU DBM (GDBM) library.\n\
+\n\
+This module is quite similar to the dbm module, but uses GDBM instead to\n\
+provide some additional functionality. Please note that the file formats\n\
+created by GDBM and dbm are incompatible. \n\
+\n\
+GDBM objects behave like mappings (dictionaries), except that keys and\n\
+values are always strings. Printing a GDBM object doesn't print the\n\
+keys and values, and the items() and values() methods are not\n\
+supported.");
+
+typedef struct {
+    PyObject_HEAD
+    int di_size;	/* -1 means recompute */
+    GDBM_FILE di_dbm;
+} dbmobject;
+
+static PyTypeObject Dbmtype;
+
+#define is_dbmobject(v) ((v)->ob_type == &Dbmtype)
+#define check_dbmobject_open(v) if ((v)->di_dbm == NULL) \
+    { PyErr_SetString(DbmError, "GDBM object has already been closed"); \
+      return NULL; }
+
+
+
+static PyObject *DbmError;
+
+PyDoc_STRVAR(gdbm_object__doc__,
+"This object represents a GDBM database.\n\
+GDBM objects behave like mappings (dictionaries), except that keys and\n\
+values are always strings. Printing a GDBM object doesn't print the\n\
+keys and values, and the items() and values() methods are not\n\
+supported.\n\
+\n\
+GDBM objects also support additional operations such as firstkey,\n\
+nextkey, reorganize, and sync.");
+
+static PyObject *
+newdbmobject(char *file, int flags, int mode)
+{
+    dbmobject *dp;
+
+    dp = PyObject_New(dbmobject, &Dbmtype);
+    if (dp == NULL)
+        return NULL;
+    dp->di_size = -1;
+    errno = 0;
+    if ((dp->di_dbm = gdbm_open(file, 0, flags, mode, NULL)) == 0) {
+        if (errno != 0)
+            PyErr_SetFromErrno(DbmError);
+        else
+            PyErr_SetString(DbmError, gdbm_strerror(gdbm_errno));
+        Py_DECREF(dp);
+        return NULL;
+    }
+    return (PyObject *)dp;
+}
+
+/* Methods */
+
+static void
+dbm_dealloc(register dbmobject *dp)
+{
+    if (dp->di_dbm)
+        gdbm_close(dp->di_dbm);
+    PyObject_Del(dp);
+}
+
+static Py_ssize_t
+dbm_length(dbmobject *dp)
+{
+    if (dp->di_dbm == NULL) {
+        PyErr_SetString(DbmError, "GDBM object has already been closed"); 
+        return -1; 
+    }
+    if (dp->di_size < 0) {
+        datum key,okey;
+        int size;
+        okey.dsize=0;
+        okey.dptr=NULL;
+
+        size = 0;
+        for (key=gdbm_firstkey(dp->di_dbm); key.dptr;
+             key = gdbm_nextkey(dp->di_dbm,okey)) {
+            size++;
+            if(okey.dsize) free(okey.dptr);
+            okey=key;
+        }
+        dp->di_size = size;
+    }
+    return dp->di_size;
+}
+
+static PyObject *
+dbm_subscript(dbmobject *dp, register PyObject *key)
+{
+    PyObject *v;
+    datum drec, krec;
+
+    if (!PyArg_Parse(key, "s#", &krec.dptr, &krec.dsize) )
+        return NULL;
+
+    if (dp->di_dbm == NULL) {
+        PyErr_SetString(DbmError,
+                        "GDBM object has already been closed");
+        return NULL;
+    }
+    drec = gdbm_fetch(dp->di_dbm, krec);
+    if (drec.dptr == 0) {
+        PyErr_SetString(PyExc_KeyError,
+                        PyString_AS_STRING((PyStringObject *)key));
+        return NULL;
+    }
+    v = PyString_FromStringAndSize(drec.dptr, drec.dsize);
+    free(drec.dptr);
+    return v;
+}
+
+static int
+dbm_ass_sub(dbmobject *dp, PyObject *v, PyObject *w)
+{
+    datum krec, drec;
+
+    if (!PyArg_Parse(v, "s#", &krec.dptr, &krec.dsize) ) {
+        PyErr_SetString(PyExc_TypeError,
+                        "gdbm mappings have string indices only");
+        return -1;
+    }
+    if (dp->di_dbm == NULL) {
+        PyErr_SetString(DbmError,
+                        "GDBM object has already been closed"); 
+        return -1; 
+    }
+    dp->di_size = -1;
+    if (w == NULL) {
+        if (gdbm_delete(dp->di_dbm, krec) < 0) {
+            PyErr_SetString(PyExc_KeyError,
+                            PyString_AS_STRING((PyStringObject *)v));
+            return -1;
+        }
+    }
+    else {
+        if (!PyArg_Parse(w, "s#", &drec.dptr, &drec.dsize)) {
+            PyErr_SetString(PyExc_TypeError,
+                            "gdbm mappings have string elements only");
+            return -1;
+        }
+        errno = 0;
+        if (gdbm_store(dp->di_dbm, krec, drec, GDBM_REPLACE) < 0) {
+            if (errno != 0)
+                PyErr_SetFromErrno(DbmError);
+            else
+                PyErr_SetString(DbmError,
+                                gdbm_strerror(gdbm_errno));
+            return -1;
+        }
+    }
+    return 0;
+}
+
+static PyMappingMethods dbm_as_mapping = {
+    (lenfunc)dbm_length,		/*mp_length*/
+    (binaryfunc)dbm_subscript,          /*mp_subscript*/
+    (objobjargproc)dbm_ass_sub,         /*mp_ass_subscript*/
+};
+
+PyDoc_STRVAR(dbm_close__doc__,
+"close() -> None\n\
+Closes the database.");
+
+static PyObject *
+dbm_close(register dbmobject *dp, PyObject *unused)
+{
+    if (dp->di_dbm)
+        gdbm_close(dp->di_dbm);
+    dp->di_dbm = NULL;
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+PyDoc_STRVAR(dbm_keys__doc__,
+"keys() -> list_of_keys\n\
+Get a list of all keys in the database.");
+
+static PyObject *
+dbm_keys(register dbmobject *dp, PyObject *unused)
+{
+    register PyObject *v, *item;
+    datum key, nextkey;
+    int err;
+
+    if (dp == NULL || !is_dbmobject(dp)) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+    check_dbmobject_open(dp);
+
+    v = PyList_New(0);
+    if (v == NULL)
+        return NULL;
+
+    key = gdbm_firstkey(dp->di_dbm);
+    while (key.dptr) {
+        item = PyString_FromStringAndSize(key.dptr, key.dsize);
+        if (item == NULL) {
+            free(key.dptr);
+            Py_DECREF(v);
+            return NULL;
+        }
+        err = PyList_Append(v, item);
+        Py_DECREF(item);
+        if (err != 0) {
+            free(key.dptr);
+            Py_DECREF(v);
+            return NULL;
+        }
+        nextkey = gdbm_nextkey(dp->di_dbm, key);
+        free(key.dptr);
+        key = nextkey;
+    }
+    return v;
+}
+
+PyDoc_STRVAR(dbm_has_key__doc__,
+"has_key(key) -> boolean\n\
+Find out whether or not the database contains a given key.");
+
+static PyObject *
+dbm_has_key(register dbmobject *dp, PyObject *args)
+{
+    datum key;
+
+    if (!PyArg_ParseTuple(args, "s#:has_key", &key.dptr, &key.dsize))
+        return NULL;
+    check_dbmobject_open(dp);
+    return PyInt_FromLong((long) gdbm_exists(dp->di_dbm, key));
+}
+
+PyDoc_STRVAR(dbm_firstkey__doc__,
+"firstkey() -> key\n\
+It's possible to loop over every key in the database using this method\n\
+and the nextkey() method. The traversal is ordered by GDBM's internal\n\
+hash values, and won't be sorted by the key values. This method\n\
+returns the starting key.");
+
+static PyObject *
+dbm_firstkey(register dbmobject *dp, PyObject *unused)
+{
+    register PyObject *v;
+    datum key;
+
+    check_dbmobject_open(dp);
+    key = gdbm_firstkey(dp->di_dbm);
+    if (key.dptr) {
+        v = PyString_FromStringAndSize(key.dptr, key.dsize);
+        free(key.dptr);
+        return v;
+    }
+    else {
+        Py_INCREF(Py_None);
+        return Py_None;
+    }
+}
+
+PyDoc_STRVAR(dbm_nextkey__doc__,
+"nextkey(key) -> next_key\n\
+Returns the key that follows key in the traversal.\n\
+The following code prints every key in the database db, without having\n\
+to create a list in memory that contains them all:\n\
+\n\
+      k = db.firstkey()\n\
+      while k != None:\n\
+          print k\n\
+          k = db.nextkey(k)");
+
+static PyObject *
+dbm_nextkey(register dbmobject *dp, PyObject *args)
+{
+    register PyObject *v;
+    datum key, nextkey;
+
+    if (!PyArg_ParseTuple(args, "s#:nextkey", &key.dptr, &key.dsize))
+        return NULL;
+    check_dbmobject_open(dp);
+    nextkey = gdbm_nextkey(dp->di_dbm, key);
+    if (nextkey.dptr) {
+        v = PyString_FromStringAndSize(nextkey.dptr, nextkey.dsize);
+        free(nextkey.dptr);
+        return v;
+    }
+    else {
+        Py_INCREF(Py_None);
+        return Py_None;
+    }
+}
+
+PyDoc_STRVAR(dbm_reorganize__doc__,
+"reorganize() -> None\n\
+If you have carried out a lot of deletions and would like to shrink\n\
+the space used by the GDBM file, this routine will reorganize the\n\
+database. GDBM will not shorten the length of a database file except\n\
+by using this reorganization; otherwise, deleted file space will be\n\
+kept and reused as new (key,value) pairs are added.");
+
+static PyObject *
+dbm_reorganize(register dbmobject *dp, PyObject *unused)
+{
+    check_dbmobject_open(dp);
+    errno = 0;
+    if (gdbm_reorganize(dp->di_dbm) < 0) {
+        if (errno != 0)
+            PyErr_SetFromErrno(DbmError);
+        else
+            PyErr_SetString(DbmError, gdbm_strerror(gdbm_errno));
+        return NULL;
+    }
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+PyDoc_STRVAR(dbm_sync__doc__,
+"sync() -> None\n\
+When the database has been opened in fast mode, this method forces\n\
+any unwritten data to be written to the disk.");
+
+static PyObject *
+dbm_sync(register dbmobject *dp, PyObject *unused)
+{
+    check_dbmobject_open(dp);
+    gdbm_sync(dp->di_dbm);
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyMethodDef dbm_methods[] = {
+    {"close",	  (PyCFunction)dbm_close,   METH_NOARGS, dbm_close__doc__},
+    {"keys",	  (PyCFunction)dbm_keys,    METH_NOARGS, dbm_keys__doc__},
+    {"has_key",   (PyCFunction)dbm_has_key, METH_VARARGS, dbm_has_key__doc__},
+    {"firstkey",  (PyCFunction)dbm_firstkey,METH_NOARGS, dbm_firstkey__doc__},
+    {"nextkey",	  (PyCFunction)dbm_nextkey, METH_VARARGS, dbm_nextkey__doc__},
+    {"reorganize",(PyCFunction)dbm_reorganize,METH_NOARGS, dbm_reorganize__doc__},
+    {"sync",      (PyCFunction)dbm_sync,    METH_NOARGS, dbm_sync__doc__},
+    {NULL,		NULL}		/* sentinel */
+};
+
+static PyObject *
+dbm_getattr(dbmobject *dp, char *name)
+{
+    return Py_FindMethod(dbm_methods, (PyObject *)dp, name);
+}
+
+static PyTypeObject Dbmtype = {
+    PyObject_HEAD_INIT(0)
+    0,
+    "gdbm.gdbm",
+    sizeof(dbmobject),
+    0,
+    (destructor)dbm_dealloc,            /*tp_dealloc*/
+    0,                                  /*tp_print*/
+    (getattrfunc)dbm_getattr,           /*tp_getattr*/
+    0,                                  /*tp_setattr*/
+    0,                                  /*tp_compare*/
+    0,                                  /*tp_repr*/
+    0,                                  /*tp_as_number*/
+    0,                                  /*tp_as_sequence*/
+    &dbm_as_mapping,                    /*tp_as_mapping*/
+    0,                                  /*tp_hash*/
+    0,                                  /*tp_call*/
+    0,                                  /*tp_str*/
+    0,                                  /*tp_getattro*/
+    0,                                  /*tp_setattro*/
+    0,                                  /*tp_as_buffer*/
+    0,                                  /*tp_xxx4*/
+    gdbm_object__doc__,                 /*tp_doc*/
+};
+
+/* ----------------------------------------------------------------- */
+
+PyDoc_STRVAR(dbmopen__doc__,
+"open(filename, [flags, [mode]])  -> dbm_object\n\
+Open a dbm database and return a dbm object. The filename argument is\n\
+the name of the database file.\n\
+\n\
+The optional flags argument can be 'r' (to open an existing database\n\
+for reading only -- default), 'w' (to open an existing database for\n\
+reading and writing), 'c' (which creates the database if it doesn't\n\
+exist), or 'n' (which always creates a new empty database).\n\
+\n\
+Some versions of gdbm support additional flags which must be\n\
+appended to one of the flags described above. The module constant\n\
+'open_flags' is a string of valid additional flags. The 'f' flag\n\
+opens the database in fast mode; altered data will not automatically\n\
+be written to the disk after every change. This results in faster\n\
+writes to the database, but may result in an inconsistent database\n\
+if the program crashes while the database is still open. Use the\n\
+sync() method to force any unwritten data to be written to the disk.\n\
+The 's' flag causes all database operations to be synchronized to\n\
+disk. The 'u' flag disables locking of the database file.\n\
+\n\
+The optional mode argument is the Unix mode of the file, used only\n\
+when the database has to be created. It defaults to octal 0666. ");
+
+static PyObject *
+dbmopen(PyObject *self, PyObject *args)
+{
+    char *name;
+    char *flags = "r";
+    int iflags;
+    int mode = 0666;
+
+    if (!PyArg_ParseTuple(args, "s|si:open", &name, &flags, &mode))
+        return NULL;
+    switch (flags[0]) {
+    case 'r':
+        iflags = GDBM_READER;
+        break;
+    case 'w':
+        iflags = GDBM_WRITER;
+        break;
+    case 'c':
+        iflags = GDBM_WRCREAT;
+        break;
+    case 'n':
+        iflags = GDBM_NEWDB;
+        break;
+    default:
+        PyErr_SetString(DbmError,
+                        "First flag must be one of 'r', 'w', 'c' or 'n'");
+        return NULL;
+    }
+    for (flags++; *flags != '\0'; flags++) {
+        char buf[40];
+        switch (*flags) {
+#ifdef GDBM_FAST
+            case 'f':
+                iflags |= GDBM_FAST;
+                break;
+#endif
+#ifdef GDBM_SYNC
+            case 's':
+                iflags |= GDBM_SYNC;
+                break;
+#endif
+#ifdef GDBM_NOLOCK
+            case 'u':
+                iflags |= GDBM_NOLOCK;
+                break;
+#endif
+            default:
+                PyOS_snprintf(buf, sizeof(buf), "Flag '%c' is not supported.",
+                	      *flags);
+                PyErr_SetString(DbmError, buf);
+                return NULL;
+        }
+    }
+
+    return newdbmobject(name, iflags, mode);
+}
+
+static char dbmmodule_open_flags[] = "rwcn"
+#ifdef GDBM_FAST
+                                     "f"
+#endif
+#ifdef GDBM_SYNC
+                                     "s"
+#endif
+#ifdef GDBM_NOLOCK
+                                     "u"
+#endif
+                                     ;
+
+static PyMethodDef dbmmodule_methods[] = {
+    { "open", (PyCFunction)dbmopen, METH_VARARGS, dbmopen__doc__},
+    { 0, 0 },
+};
+
+PyMODINIT_FUNC
+initgdbm(void) {
+    PyObject *m, *d, *s;
+
+    Dbmtype.ob_type = &PyType_Type;
+    m = Py_InitModule4("gdbm", dbmmodule_methods,
+                       gdbmmodule__doc__, (PyObject *)NULL,
+                       PYTHON_API_VERSION);
+    if (m == NULL)
+	return;
+    d = PyModule_GetDict(m);
+    DbmError = PyErr_NewException("gdbm.error", NULL, NULL);
+    if (DbmError != NULL) {
+        PyDict_SetItemString(d, "error", DbmError);
+        s = PyString_FromString(dbmmodule_open_flags);
+        PyDict_SetItemString(d, "open_flags", s);
+        Py_DECREF(s);
+    }
+}

Added: vendor/Python/current/Modules/getaddrinfo.c
===================================================================
--- vendor/Python/current/Modules/getaddrinfo.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/getaddrinfo.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,638 @@
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * GAI_ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR GAI_ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON GAI_ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN GAI_ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * "#ifdef FAITH" part is local hack for supporting IPv4-v6 translator.
+ *
+ * Issues to be discussed:
+ * - Thread safe-ness must be checked.
+ * - Return values.  There are nonstandard return values defined and used
+ *   in the source code.  This is because RFC2133 is silent about which error
+ *   code must be returned for which situation.
+ * - PF_UNSPEC case would be handled in getipnodebyname() with the AI_ALL flag.
+ */
+
+#if 0
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <netdb.h>
+#include <resolv.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <ctype.h>
+#include <unistd.h>
+
+#include "addrinfo.h"
+#endif
+
+#if defined(__KAME__) && defined(ENABLE_IPV6)
+# define FAITH
+#endif
+
+#define SUCCESS 0
+#define GAI_ANY 0
+#define YES 1
+#define NO  0
+
+#ifdef FAITH
+static int translate = NO;
+static struct in6_addr faith_prefix = IN6ADDR_GAI_ANY_INIT;
+#endif
+
+static const char in_addrany[] = { 0, 0, 0, 0 };
+static const char in6_addrany[] = {
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+static const char in_loopback[] = { 127, 0, 0, 1 }; 
+static const char in6_loopback[] = {
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
+};
+
+struct sockinet {
+	u_char	si_len;
+	u_char	si_family;
+	u_short	si_port;
+};
+
+static struct gai_afd {
+	int a_af;
+	int a_addrlen;
+	int a_socklen;
+	int a_off;
+	const char *a_addrany;
+	const char *a_loopback;	
+} gai_afdl [] = {
+#ifdef ENABLE_IPV6
+#define N_INET6 0
+	{PF_INET6, sizeof(struct in6_addr),
+	 sizeof(struct sockaddr_in6),
+	 offsetof(struct sockaddr_in6, sin6_addr),
+	 in6_addrany, in6_loopback},
+#define N_INET  1
+#else
+#define N_INET  0
+#endif
+	{PF_INET, sizeof(struct in_addr),
+	 sizeof(struct sockaddr_in),
+	 offsetof(struct sockaddr_in, sin_addr),
+	 in_addrany, in_loopback},
+	{0, 0, 0, 0, NULL, NULL},
+};
+
+#ifdef ENABLE_IPV6
+#define PTON_MAX	16
+#else
+#define PTON_MAX	4
+#endif
+
+#ifndef IN_MULTICAST
+#define IN_MULTICAST(i)	    (((i) & 0xf0000000U) == 0xe0000000U)
+#endif
+
+#ifndef IN_EXPERIMENTAL
+#define IN_EXPERIMENTAL(i)  (((i) & 0xe0000000U) == 0xe0000000U)
+#endif
+
+#ifndef IN_LOOPBACKNET
+#define IN_LOOPBACKNET	    127
+#endif
+
+static int get_name Py_PROTO((const char *, struct gai_afd *,
+			  struct addrinfo **, char *, struct addrinfo *,
+			  int));
+static int get_addr Py_PROTO((const char *, int, struct addrinfo **,
+			struct addrinfo *, int));
+static int str_isnumber Py_PROTO((const char *));
+	
+static char *ai_errlist[] = {
+	"success.",
+	"address family for hostname not supported.",	/* EAI_ADDRFAMILY */
+	"temporary failure in name resolution.",	/* EAI_AGAIN      */
+	"invalid value for ai_flags.",		       	/* EAI_BADFLAGS   */
+	"non-recoverable failure in name resolution.", 	/* EAI_FAIL       */
+	"ai_family not supported.",			/* EAI_FAMILY     */
+	"memory allocation failure.", 			/* EAI_MEMORY     */
+	"no address associated with hostname.", 	/* EAI_NODATA     */
+	"hostname nor servname provided, or not known.",/* EAI_NONAME     */
+	"servname not supported for ai_socktype.",	/* EAI_SERVICE    */
+	"ai_socktype not supported.", 			/* EAI_SOCKTYPE   */
+	"system error returned in errno.", 		/* EAI_SYSTEM     */
+	"invalid value for hints.",			/* EAI_BADHINTS	  */
+	"resolved protocol is unknown.",		/* EAI_PROTOCOL   */
+	"unknown error.", 				/* EAI_MAX        */
+};
+
+#define GET_CANONNAME(ai, str) \
+if (pai->ai_flags & AI_CANONNAME) {\
+	if (((ai)->ai_canonname = (char *)malloc(strlen(str) + 1)) != NULL) {\
+		strcpy((ai)->ai_canonname, (str));\
+	} else {\
+		error = EAI_MEMORY;\
+		goto free;\
+	}\
+}
+
+#ifdef HAVE_SOCKADDR_SA_LEN
+#define GET_AI(ai, gai_afd, addr, port) {\
+	char *p;\
+	if (((ai) = (struct addrinfo *)malloc(sizeof(struct addrinfo) +\
+					      ((gai_afd)->a_socklen)))\
+	    == NULL) goto free;\
+	memcpy(ai, pai, sizeof(struct addrinfo));\
+	(ai)->ai_addr = (struct sockaddr *)((ai) + 1);\
+	memset((ai)->ai_addr, 0, (gai_afd)->a_socklen);\
+	(ai)->ai_addr->sa_len = (ai)->ai_addrlen = (gai_afd)->a_socklen;\
+	(ai)->ai_addr->sa_family = (ai)->ai_family = (gai_afd)->a_af;\
+	((struct sockinet *)(ai)->ai_addr)->si_port = port;\
+	p = (char *)((ai)->ai_addr);\
+	memcpy(p + (gai_afd)->a_off, (addr), (gai_afd)->a_addrlen);\
+}
+#else
+#define GET_AI(ai, gai_afd, addr, port) {\
+	char *p;\
+	if (((ai) = (struct addrinfo *)malloc(sizeof(struct addrinfo) +\
+					      ((gai_afd)->a_socklen)))\
+	    == NULL) goto free;\
+	memcpy(ai, pai, sizeof(struct addrinfo));\
+	(ai)->ai_addr = (struct sockaddr *)((ai) + 1);\
+	memset((ai)->ai_addr, 0, (gai_afd)->a_socklen);\
+	(ai)->ai_addrlen = (gai_afd)->a_socklen;\
+	(ai)->ai_addr->sa_family = (ai)->ai_family = (gai_afd)->a_af;\
+	((struct sockinet *)(ai)->ai_addr)->si_port = port;\
+	p = (char *)((ai)->ai_addr);\
+	memcpy(p + (gai_afd)->a_off, (addr), (gai_afd)->a_addrlen);\
+}
+#endif
+
+#define ERR(err) { error = (err); goto bad; }
+
+char *
+gai_strerror(int ecode)
+{
+	if (ecode < 0 || ecode > EAI_MAX)
+		ecode = EAI_MAX;
+	return ai_errlist[ecode];
+}
+
+void
+freeaddrinfo(struct addrinfo *ai)
+{
+	struct addrinfo *next;
+
+	do {
+		next = ai->ai_next;
+		if (ai->ai_canonname)
+			free(ai->ai_canonname);
+		/* no need to free(ai->ai_addr) */
+		free(ai);
+	} while ((ai = next) != NULL);
+}
+
+static int
+str_isnumber(const char *p)
+{
+	unsigned char *q = (unsigned char *)p;
+	while (*q) {
+		if (! isdigit(*q))
+			return NO;
+		q++;
+	}
+	return YES;
+}
+
+int
+getaddrinfo(const char*hostname, const char*servname,
+            const struct addrinfo *hints, struct addrinfo **res)
+{
+	struct addrinfo sentinel;
+	struct addrinfo *top = NULL;
+	struct addrinfo *cur;
+	int i, error = 0;
+	char pton[PTON_MAX];
+	struct addrinfo ai;
+	struct addrinfo *pai;
+	u_short port;
+
+#ifdef FAITH
+	static int firsttime = 1;
+
+	if (firsttime) {
+		/* translator hack */
+		{
+			char *q = getenv("GAI");
+			if (q && inet_pton(AF_INET6, q, &faith_prefix) == 1)
+				translate = YES;
+		}
+		firsttime = 0;
+	}
+#endif
+
+	/* initialize file static vars */
+	sentinel.ai_next = NULL;
+	cur = &sentinel;
+	pai = &ai;
+	pai->ai_flags = 0;
+	pai->ai_family = PF_UNSPEC;
+	pai->ai_socktype = GAI_ANY;
+	pai->ai_protocol = GAI_ANY;
+	pai->ai_addrlen = 0;
+	pai->ai_canonname = NULL;
+	pai->ai_addr = NULL;
+	pai->ai_next = NULL;
+	port = GAI_ANY;
+	
+	if (hostname == NULL && servname == NULL)
+		return EAI_NONAME;
+	if (hints) {
+		/* error check for hints */
+		if (hints->ai_addrlen || hints->ai_canonname ||
+		    hints->ai_addr || hints->ai_next)
+			ERR(EAI_BADHINTS); /* xxx */
+		if (hints->ai_flags & ~AI_MASK)
+			ERR(EAI_BADFLAGS);
+		switch (hints->ai_family) {
+		case PF_UNSPEC:
+		case PF_INET:
+#ifdef ENABLE_IPV6
+		case PF_INET6:
+#endif
+			break;
+		default:
+			ERR(EAI_FAMILY);
+		}
+		memcpy(pai, hints, sizeof(*pai));
+		switch (pai->ai_socktype) {
+		case GAI_ANY:
+			switch (pai->ai_protocol) {
+			case GAI_ANY:
+				break;
+			case IPPROTO_UDP:
+				pai->ai_socktype = SOCK_DGRAM;
+				break;
+			case IPPROTO_TCP:
+				pai->ai_socktype = SOCK_STREAM;
+				break;
+			default:
+				pai->ai_socktype = SOCK_RAW;
+				break;
+			}
+			break;
+		case SOCK_RAW:
+			break;
+		case SOCK_DGRAM:
+			if (pai->ai_protocol != IPPROTO_UDP &&
+			    pai->ai_protocol != GAI_ANY)
+				ERR(EAI_BADHINTS);	/*xxx*/
+			pai->ai_protocol = IPPROTO_UDP;
+			break;
+		case SOCK_STREAM:
+			if (pai->ai_protocol != IPPROTO_TCP &&
+			    pai->ai_protocol != GAI_ANY)
+				ERR(EAI_BADHINTS);	/*xxx*/
+			pai->ai_protocol = IPPROTO_TCP;
+			break;
+		default:
+			ERR(EAI_SOCKTYPE);
+			/* unreachable */
+		}
+	}
+
+	/*
+	 * service port
+	 */
+	if (servname) {
+		if (str_isnumber(servname)) {
+			if (pai->ai_socktype == GAI_ANY) {
+				/* caller accept *GAI_ANY* socktype */
+				pai->ai_socktype = SOCK_DGRAM;
+				pai->ai_protocol = IPPROTO_UDP;
+			}
+			port = htons((u_short)atoi(servname));
+		} else {
+			struct servent *sp;
+			char *proto;
+
+			proto = NULL;
+			switch (pai->ai_socktype) {
+			case GAI_ANY:
+				proto = NULL;
+				break;
+			case SOCK_DGRAM:
+				proto = "udp";
+				break;
+			case SOCK_STREAM:
+				proto = "tcp";
+				break;
+			default:
+				fprintf(stderr, "panic!\n");
+				break;
+			}
+			if ((sp = getservbyname(servname, proto)) == NULL)
+				ERR(EAI_SERVICE);
+			port = sp->s_port;
+			if (pai->ai_socktype == GAI_ANY) {
+				if (strcmp(sp->s_proto, "udp") == 0) {
+					pai->ai_socktype = SOCK_DGRAM;
+					pai->ai_protocol = IPPROTO_UDP;
+				} else if (strcmp(sp->s_proto, "tcp") == 0) {
+                                        pai->ai_socktype = SOCK_STREAM;
+                                        pai->ai_protocol = IPPROTO_TCP;
+                                } else
+                                        ERR(EAI_PROTOCOL);	/*xxx*/
+                        }
+		}
+	}
+	
+	/*
+	 * hostname == NULL.
+	 * passive socket -> anyaddr (0.0.0.0 or ::)
+	 * non-passive socket -> localhost (127.0.0.1 or ::1)
+	 */
+	if (hostname == NULL) {
+		struct gai_afd *gai_afd;
+
+		for (gai_afd = &gai_afdl[0]; gai_afd->a_af; gai_afd++) {
+			if (!(pai->ai_family == PF_UNSPEC
+			   || pai->ai_family == gai_afd->a_af)) {
+				continue;
+			}
+
+			if (pai->ai_flags & AI_PASSIVE) {
+				GET_AI(cur->ai_next, gai_afd, gai_afd->a_addrany, port);
+				/* xxx meaningless?
+				 * GET_CANONNAME(cur->ai_next, "anyaddr");
+				 */
+			} else {
+				GET_AI(cur->ai_next, gai_afd, gai_afd->a_loopback,
+					port);
+				/* xxx meaningless?
+				 * GET_CANONNAME(cur->ai_next, "localhost");
+				 */
+			}
+			cur = cur->ai_next;
+		}
+		top = sentinel.ai_next;
+		if (top)
+			goto good;
+		else
+			ERR(EAI_FAMILY);
+	}
+	
+	/* hostname as numeric name */
+	for (i = 0; gai_afdl[i].a_af; i++) {
+		if (inet_pton(gai_afdl[i].a_af, hostname, pton)) {
+			u_long v4a;
+#ifdef ENABLE_IPV6
+			u_char pfx;
+#endif
+
+			switch (gai_afdl[i].a_af) {
+			case AF_INET:
+				v4a = ((struct in_addr *)pton)->s_addr;
+				v4a = ntohl(v4a);
+				if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a))
+					pai->ai_flags &= ~AI_CANONNAME;
+				v4a >>= IN_CLASSA_NSHIFT;
+				if (v4a == 0 || v4a == IN_LOOPBACKNET)
+					pai->ai_flags &= ~AI_CANONNAME;
+				break;
+#ifdef ENABLE_IPV6
+			case AF_INET6:
+				pfx = ((struct in6_addr *)pton)->s6_addr8[0];
+				if (pfx == 0 || pfx == 0xfe || pfx == 0xff)
+					pai->ai_flags &= ~AI_CANONNAME;
+				break;
+#endif
+			}
+			
+			if (pai->ai_family == gai_afdl[i].a_af ||
+			    pai->ai_family == PF_UNSPEC) {
+				if (! (pai->ai_flags & AI_CANONNAME)) {
+					GET_AI(top, &gai_afdl[i], pton, port);
+					goto good;
+				}
+				/*
+				 * if AI_CANONNAME and if reverse lookup
+				 * fail, return ai anyway to pacify
+				 * calling application.
+				 *
+				 * XXX getaddrinfo() is a name->address
+				 * translation function, and it looks strange
+				 * that we do addr->name translation here.
+				 */
+				get_name(pton, &gai_afdl[i], &top, pton, pai, port);
+				goto good;
+			} else 
+				ERR(EAI_FAMILY);	/*xxx*/
+		}
+	}
+
+	if (pai->ai_flags & AI_NUMERICHOST)
+		ERR(EAI_NONAME);
+
+	/* hostname as alphabetical name */
+	error = get_addr(hostname, pai->ai_family, &top, pai, port);
+	if (error == 0) {
+		if (top) {
+ good:
+			*res = top;
+			return SUCCESS;
+		} else
+			error = EAI_FAIL;
+	}
+ free:
+	if (top)
+		freeaddrinfo(top);
+ bad:
+	*res = NULL;
+	return error;
+}
+
+static int
+get_name(addr, gai_afd, res, numaddr, pai, port0)
+	const char *addr;
+	struct gai_afd *gai_afd;
+	struct addrinfo **res;
+	char *numaddr;
+	struct addrinfo *pai;
+	int port0;
+{
+	u_short port = port0 & 0xffff;
+	struct hostent *hp;
+	struct addrinfo *cur;
+	int error = 0;
+#ifdef ENABLE_IPV6
+	int h_error;
+#endif
+	
+#ifdef ENABLE_IPV6
+	hp = getipnodebyaddr(addr, gai_afd->a_addrlen, gai_afd->a_af, &h_error);
+#else
+	hp = gethostbyaddr(addr, gai_afd->a_addrlen, AF_INET);
+#endif
+	if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) {
+		GET_AI(cur, gai_afd, hp->h_addr_list[0], port);
+		GET_CANONNAME(cur, hp->h_name);
+	} else
+		GET_AI(cur, gai_afd, numaddr, port);
+	
+#ifdef ENABLE_IPV6
+	if (hp)
+		freehostent(hp);
+#endif
+	*res = cur;
+	return SUCCESS;
+ free:
+	if (cur)
+		freeaddrinfo(cur);
+#ifdef ENABLE_IPV6
+	if (hp)
+		freehostent(hp);
+#endif
+ /* bad: */
+	*res = NULL;
+	return error;
+}
+
+static int
+get_addr(hostname, af, res, pai, port0)
+	const char *hostname;
+	int af;
+	struct addrinfo **res;
+	struct addrinfo *pai;
+	int port0;
+{
+	u_short port = port0 & 0xffff;
+	struct addrinfo sentinel;
+	struct hostent *hp;
+	struct addrinfo *top, *cur;
+	struct gai_afd *gai_afd;
+	int i, error = 0, h_error;
+	char *ap;
+
+	top = NULL;
+	sentinel.ai_next = NULL;
+	cur = &sentinel;
+#ifdef ENABLE_IPV6
+	if (af == AF_UNSPEC) {
+		hp = getipnodebyname(hostname, AF_INET6,
+				AI_ADDRCONFIG|AI_ALL|AI_V4MAPPED, &h_error);
+	} else
+		hp = getipnodebyname(hostname, af, AI_ADDRCONFIG, &h_error);
+#else
+	hp = gethostbyname(hostname);
+	h_error = h_errno;
+#endif
+	if (hp == NULL) {
+		switch (h_error) {
+		case HOST_NOT_FOUND:
+		case NO_DATA:
+			error = EAI_NODATA;
+			break;
+		case TRY_AGAIN:
+			error = EAI_AGAIN;
+			break;
+		case NO_RECOVERY:
+		default:
+			error = EAI_FAIL;
+			break;
+		}
+		goto free;
+	}
+
+	if ((hp->h_name == NULL) || (hp->h_name[0] == 0) ||
+	    (hp->h_addr_list[0] == NULL)) {
+		error = EAI_FAIL;
+		goto free;
+	}
+	
+	for (i = 0; (ap = hp->h_addr_list[i]) != NULL; i++) {
+		switch (af) {
+#ifdef ENABLE_IPV6
+		case AF_INET6:
+			gai_afd = &gai_afdl[N_INET6];
+			break;
+#endif
+#ifndef ENABLE_IPV6
+		default:	/* AF_UNSPEC */
+#endif
+		case AF_INET:
+			gai_afd = &gai_afdl[N_INET];
+			break;
+#ifdef ENABLE_IPV6
+		default:	/* AF_UNSPEC */
+			if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)ap)) {
+				ap += sizeof(struct in6_addr) -
+					sizeof(struct in_addr);
+				gai_afd = &gai_afdl[N_INET];
+			} else
+				gai_afd = &gai_afdl[N_INET6];
+			break;
+#endif
+		}
+#ifdef FAITH
+		if (translate && gai_afd->a_af == AF_INET) {
+			struct in6_addr *in6;
+
+			GET_AI(cur->ai_next, &gai_afdl[N_INET6], ap, port);
+			in6 = &((struct sockaddr_in6 *)cur->ai_next->ai_addr)->sin6_addr;
+			memcpy(&in6->s6_addr32[0], &faith_prefix,
+			    sizeof(struct in6_addr) - sizeof(struct in_addr));
+			memcpy(&in6->s6_addr32[3], ap, sizeof(struct in_addr));
+		} else
+#endif /* FAITH */
+		GET_AI(cur->ai_next, gai_afd, ap, port);
+		if (cur == &sentinel) {
+			top = cur->ai_next;
+			GET_CANONNAME(top, hp->h_name);
+		}
+		cur = cur->ai_next;
+	}
+#ifdef ENABLE_IPV6
+	freehostent(hp);
+#endif
+	*res = top;
+	return SUCCESS;
+ free:
+	if (top)
+		freeaddrinfo(top);
+#ifdef ENABLE_IPV6
+	if (hp)
+		freehostent(hp);
+#endif
+/* bad: */
+	*res = NULL;
+	return error;
+}

Added: vendor/Python/current/Modules/getbuildinfo.c
===================================================================
--- vendor/Python/current/Modules/getbuildinfo.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/getbuildinfo.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,48 @@
+#include "Python.h"
+
+#ifndef DONT_HAVE_STDIO_H
+#include <stdio.h>
+#endif
+
+#ifndef DATE
+#ifdef __DATE__
+#define DATE __DATE__
+#else
+#define DATE "xx/xx/xx"
+#endif
+#endif
+
+#ifndef TIME
+#ifdef __TIME__
+#define TIME __TIME__
+#else
+#define TIME "xx:xx:xx"
+#endif
+#endif
+
+#ifdef SUBWCREV
+#define SVNVERSION "$WCRANGE$$WCMODS?M:$"
+#endif
+
+const char *
+Py_GetBuildInfo(void)
+{
+	static char buildinfo[50];
+	const char *revision = Py_SubversionRevision();
+	const char *sep = *revision ? ":" : "";
+	const char *branch = Py_SubversionShortBranch();
+	PyOS_snprintf(buildinfo, sizeof(buildinfo),
+		      "%s%s%s, %.20s, %.9s", branch, sep, revision, 
+		      DATE, TIME);
+	return buildinfo;
+}
+
+const char *
+_Py_svnversion(void)
+{
+#ifdef SVNVERSION
+	return SVNVERSION;
+#else
+	return "exported";
+#endif
+}

Added: vendor/Python/current/Modules/getnameinfo.c
===================================================================
--- vendor/Python/current/Modules/getnameinfo.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/getnameinfo.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Issues to be discussed:
+ * - Thread safe-ness must be checked
+ * - Return values.  There seems to be no standard for return value (RFC2133)
+ *   but INRIA implementation returns EAI_xxx defined for getaddrinfo().
+ */
+
+#if 0
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <netdb.h>
+#include <resolv.h>
+#include <string.h>
+#include <stddef.h>
+
+#include "addrinfo.h"
+#endif
+
+#define SUCCESS 0
+#define YES 1
+#define NO  0
+
+static struct gni_afd {
+	int a_af;
+	int a_addrlen;
+	int a_socklen;
+	int a_off;
+} gni_afdl [] = {
+#ifdef ENABLE_IPV6
+	{PF_INET6, sizeof(struct in6_addr), sizeof(struct sockaddr_in6),
+		offsetof(struct sockaddr_in6, sin6_addr)},
+#endif
+	{PF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in),
+		offsetof(struct sockaddr_in, sin_addr)},
+	{0, 0, 0},
+};
+
+struct gni_sockinet {
+	u_char	si_len;
+	u_char	si_family;
+	u_short	si_port;
+};
+
+#define ENI_NOSOCKET 	0
+#define ENI_NOSERVNAME	1
+#define ENI_NOHOSTNAME	2
+#define ENI_MEMORY	3
+#define ENI_SYSTEM	4
+#define ENI_FAMILY	5
+#define ENI_SALEN	6
+
+/* forward declaration to make gcc happy */
+int getnameinfo Py_PROTO((const struct sockaddr *, size_t, char *, size_t,
+			  char *, size_t, int));
+
+int
+getnameinfo(sa, salen, host, hostlen, serv, servlen, flags)
+	const struct sockaddr *sa;
+	size_t salen;
+	char *host;
+	size_t hostlen;
+	char *serv;
+	size_t servlen;
+	int flags;
+{
+	struct gni_afd *gni_afd;
+	struct servent *sp;
+	struct hostent *hp;
+	u_short port;
+	int family, len, i;
+	char *addr, *p;
+	u_long v4a;
+#ifdef ENABLE_IPV6
+	u_char pfx;
+#endif
+	int h_error;
+	char numserv[512];
+	char numaddr[512];
+
+	if (sa == NULL)
+		return ENI_NOSOCKET;
+
+#ifdef HAVE_SOCKADDR_SA_LEN
+	len = sa->sa_len;
+	if (len != salen) return ENI_SALEN;
+#else
+	len = salen;
+#endif
+	
+	family = sa->sa_family;
+	for (i = 0; gni_afdl[i].a_af; i++)
+		if (gni_afdl[i].a_af == family) {
+			gni_afd = &gni_afdl[i];
+			goto found;
+		}
+	return ENI_FAMILY;
+	
+ found:
+	if (len != gni_afd->a_socklen) return ENI_SALEN;
+	
+	port = ((struct gni_sockinet *)sa)->si_port; /* network byte order */
+	addr = (char *)sa + gni_afd->a_off;
+
+	if (serv == NULL || servlen == 0) {
+		/* what we should do? */
+	} else if (flags & NI_NUMERICSERV) {
+		sprintf(numserv, "%d", ntohs(port));
+		if (strlen(numserv) > servlen)
+			return ENI_MEMORY;
+		strcpy(serv, numserv);
+	} else {
+		sp = getservbyport(port, (flags & NI_DGRAM) ? "udp" : "tcp");
+		if (sp) {
+			if (strlen(sp->s_name) > servlen)
+				return ENI_MEMORY;
+			strcpy(serv, sp->s_name);
+		} else
+			return ENI_NOSERVNAME;
+	}
+
+	switch (sa->sa_family) {
+	case AF_INET:
+		v4a = ((struct sockaddr_in *)sa)->sin_addr.s_addr;
+		if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a))
+			flags |= NI_NUMERICHOST;
+		v4a >>= IN_CLASSA_NSHIFT;
+		if (v4a == 0 || v4a == IN_LOOPBACKNET)
+			flags |= NI_NUMERICHOST;			
+		break;
+#ifdef ENABLE_IPV6
+	case AF_INET6:
+		pfx = ((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr8[0];
+		if (pfx == 0 || pfx == 0xfe || pfx == 0xff)
+			flags |= NI_NUMERICHOST;
+		break;
+#endif
+	}
+	if (host == NULL || hostlen == 0) {
+		/* what should we do? */
+	} else if (flags & NI_NUMERICHOST) {
+		if (inet_ntop(gni_afd->a_af, addr, numaddr, sizeof(numaddr))
+		    == NULL)
+			return ENI_SYSTEM;
+		if (strlen(numaddr) > hostlen)
+			return ENI_MEMORY;
+		strcpy(host, numaddr);
+	} else {
+#ifdef ENABLE_IPV6
+		hp = getipnodebyaddr(addr, gni_afd->a_addrlen, gni_afd->a_af, &h_error);
+#else
+		hp = gethostbyaddr(addr, gni_afd->a_addrlen, gni_afd->a_af);
+		h_error = h_errno;
+#endif
+
+		if (hp) {
+			if (flags & NI_NOFQDN) {
+				p = strchr(hp->h_name, '.');
+				if (p) *p = '\0';
+			}
+			if (strlen(hp->h_name) > hostlen) {
+#ifdef ENABLE_IPV6
+				freehostent(hp);
+#endif
+				return ENI_MEMORY;
+			}
+			strcpy(host, hp->h_name);
+#ifdef ENABLE_IPV6
+			freehostent(hp);
+#endif
+		} else {
+			if (flags & NI_NAMEREQD)
+				return ENI_NOHOSTNAME;
+			if (inet_ntop(gni_afd->a_af, addr, numaddr, sizeof(numaddr))
+			    == NULL)
+				return ENI_NOHOSTNAME;
+			if (strlen(numaddr) > hostlen)
+				return ENI_MEMORY;
+			strcpy(host, numaddr);
+		}
+	}
+	return SUCCESS;
+}

Added: vendor/Python/current/Modules/getpath.c
===================================================================
--- vendor/Python/current/Modules/getpath.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/getpath.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,694 @@
+/* Return the initial module search path. */
+
+#include "Python.h"
+#include "osdefs.h"
+
+#include <sys/types.h>
+#include <string.h>
+
+#ifdef __APPLE__
+#include <mach-o/dyld.h>
+#endif
+
+/* Search in some common locations for the associated Python libraries.
+ *
+ * Two directories must be found, the platform independent directory
+ * (prefix), containing the common .py and .pyc files, and the platform
+ * dependent directory (exec_prefix), containing the shared library
+ * modules.  Note that prefix and exec_prefix can be the same directory,
+ * but for some installations, they are different.
+ *
+ * Py_GetPath() carries out separate searches for prefix and exec_prefix.
+ * Each search tries a number of different locations until a ``landmark''
+ * file or directory is found.  If no prefix or exec_prefix is found, a
+ * warning message is issued and the preprocessor defined PREFIX and
+ * EXEC_PREFIX are used (even though they will not work); python carries on
+ * as best as is possible, but most imports will fail.
+ *
+ * Before any searches are done, the location of the executable is
+ * determined.  If argv[0] has one or more slashs in it, it is used
+ * unchanged.  Otherwise, it must have been invoked from the shell's path,
+ * so we search $PATH for the named executable and use that.  If the
+ * executable was not found on $PATH (or there was no $PATH environment
+ * variable), the original argv[0] string is used.
+ *
+ * Next, the executable location is examined to see if it is a symbolic
+ * link.  If so, the link is chased (correctly interpreting a relative
+ * pathname if one is found) and the directory of the link target is used.
+ *
+ * Finally, argv0_path is set to the directory containing the executable
+ * (i.e. the last component is stripped).
+ *
+ * With argv0_path in hand, we perform a number of steps.  The same steps
+ * are performed for prefix and for exec_prefix, but with a different
+ * landmark.
+ *
+ * Step 1. Are we running python out of the build directory?  This is
+ * checked by looking for a different kind of landmark relative to
+ * argv0_path.  For prefix, the landmark's path is derived from the VPATH
+ * preprocessor variable (taking into account that its value is almost, but
+ * not quite, what we need).  For exec_prefix, the landmark is
+ * Modules/Setup.  If the landmark is found, we're done.
+ *
+ * For the remaining steps, the prefix landmark will always be
+ * lib/python$VERSION/os.py and the exec_prefix will always be
+ * lib/python$VERSION/lib-dynload, where $VERSION is Python's version
+ * number as supplied by the Makefile.  Note that this means that no more
+ * build directory checking is performed; if the first step did not find
+ * the landmarks, the assumption is that python is running from an
+ * installed setup.
+ *
+ * Step 2. See if the $PYTHONHOME environment variable points to the
+ * installed location of the Python libraries.  If $PYTHONHOME is set, then
+ * it points to prefix and exec_prefix.  $PYTHONHOME can be a single
+ * directory, which is used for both, or the prefix and exec_prefix
+ * directories separated by a colon.
+ *
+ * Step 3. Try to find prefix and exec_prefix relative to argv0_path,
+ * backtracking up the path until it is exhausted.  This is the most common
+ * step to succeed.  Note that if prefix and exec_prefix are different,
+ * exec_prefix is more likely to be found; however if exec_prefix is a
+ * subdirectory of prefix, both will be found.
+ *
+ * Step 4. Search the directories pointed to by the preprocessor variables
+ * PREFIX and EXEC_PREFIX.  These are supplied by the Makefile but can be
+ * passed in as options to the configure script.
+ *
+ * That's it!
+ *
+ * Well, almost.  Once we have determined prefix and exec_prefix, the
+ * preprocessor variable PYTHONPATH is used to construct a path.  Each
+ * relative path on PYTHONPATH is prefixed with prefix.  Then the directory
+ * containing the shared library modules is appended.  The environment
+ * variable $PYTHONPATH is inserted in front of it all.  Finally, the
+ * prefix and exec_prefix globals are tweaked so they reflect the values
+ * expected by other code, by stripping the "lib/python$VERSION/..." stuff
+ * off.  If either points to the build directory, the globals are reset to
+ * the corresponding preprocessor variables (so sys.prefix will reflect the
+ * installation location, even though sys.path points into the build
+ * directory).  This seems to make more sense given that currently the only
+ * known use of sys.prefix and sys.exec_prefix is for the ILU installation
+ * process to find the installed Python tree.
+ */
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+#ifndef VERSION
+#define VERSION "2.1"
+#endif
+
+#ifndef VPATH
+#define VPATH "."
+#endif
+
+#ifndef PREFIX
+#  ifdef __VMS
+#    define PREFIX ""
+#  else
+#    define PREFIX "/usr/local"
+#  endif
+#endif
+
+#ifndef EXEC_PREFIX
+#define EXEC_PREFIX PREFIX
+#endif
+
+#ifndef PYTHONPATH
+#define PYTHONPATH PREFIX "/lib/python" VERSION ":" \
+              EXEC_PREFIX "/lib/python" VERSION "/lib-dynload"
+#endif
+
+#ifndef LANDMARK
+#define LANDMARK "os.py"
+#endif
+
+static char prefix[MAXPATHLEN+1];
+static char exec_prefix[MAXPATHLEN+1];
+static char progpath[MAXPATHLEN+1];
+static char *module_search_path = NULL;
+static char lib_python[] = "lib/python" VERSION;
+
+static void
+reduce(char *dir)
+{
+    size_t i = strlen(dir);
+    while (i > 0 && dir[i] != SEP)
+        --i;
+    dir[i] = '\0';
+}
+
+
+static int
+isfile(char *filename)          /* Is file, not directory */
+{
+    struct stat buf;
+    if (stat(filename, &buf) != 0)
+        return 0;
+    if (!S_ISREG(buf.st_mode))
+        return 0;
+    return 1;
+}
+
+
+static int
+ismodule(char *filename)        /* Is module -- check for .pyc/.pyo too */
+{
+    if (isfile(filename))
+        return 1;
+
+    /* Check for the compiled version of prefix. */
+    if (strlen(filename) < MAXPATHLEN) {
+        strcat(filename, Py_OptimizeFlag ? "o" : "c");
+        if (isfile(filename))
+            return 1;
+    }
+    return 0;
+}
+
+
+static int
+isxfile(char *filename)         /* Is executable file */
+{
+    struct stat buf;
+    if (stat(filename, &buf) != 0)
+        return 0;
+    if (!S_ISREG(buf.st_mode))
+        return 0;
+    if ((buf.st_mode & 0111) == 0)
+        return 0;
+    return 1;
+}
+
+
+static int
+isdir(char *filename)                   /* Is directory */
+{
+    struct stat buf;
+    if (stat(filename, &buf) != 0)
+        return 0;
+    if (!S_ISDIR(buf.st_mode))
+        return 0;
+    return 1;
+}
+
+
+/* Add a path component, by appending stuff to buffer.
+   buffer must have at least MAXPATHLEN + 1 bytes allocated, and contain a
+   NUL-terminated string with no more than MAXPATHLEN characters (not counting
+   the trailing NUL).  It's a fatal error if it contains a string longer than
+   that (callers must be careful!).  If these requirements are met, it's
+   guaranteed that buffer will still be a NUL-terminated string with no more
+   than MAXPATHLEN characters at exit.  If stuff is too long, only as much of
+   stuff as fits will be appended.
+*/
+static void
+joinpath(char *buffer, char *stuff)
+{
+    size_t n, k;
+    if (stuff[0] == SEP)
+        n = 0;
+    else {
+        n = strlen(buffer);
+        if (n > 0 && buffer[n-1] != SEP && n < MAXPATHLEN)
+            buffer[n++] = SEP;
+    }
+    if (n > MAXPATHLEN)
+    	Py_FatalError("buffer overflow in getpath.c's joinpath()");
+    k = strlen(stuff);
+    if (n + k > MAXPATHLEN)
+        k = MAXPATHLEN - n;
+    strncpy(buffer+n, stuff, k);
+    buffer[n+k] = '\0';
+}
+
+/* copy_absolute requires that path be allocated at least
+   MAXPATHLEN + 1 bytes and that p be no more than MAXPATHLEN bytes. */
+static void
+copy_absolute(char *path, char *p)
+{
+    if (p[0] == SEP)
+        strcpy(path, p);
+    else {
+        getcwd(path, MAXPATHLEN);
+        if (p[0] == '.' && p[1] == SEP)
+            p += 2;
+        joinpath(path, p);
+    }
+}
+
+/* absolutize() requires that path be allocated at least MAXPATHLEN+1 bytes. */
+static void
+absolutize(char *path)
+{
+    char buffer[MAXPATHLEN + 1];
+
+    if (path[0] == SEP)
+        return;
+    copy_absolute(buffer, path);
+    strcpy(path, buffer);
+}
+
+/* search_for_prefix requires that argv0_path be no more than MAXPATHLEN
+   bytes long.
+*/
+static int
+search_for_prefix(char *argv0_path, char *home)
+{
+    size_t n;
+    char *vpath;
+
+    /* If PYTHONHOME is set, we believe it unconditionally */
+    if (home) {
+        char *delim;
+        strncpy(prefix, home, MAXPATHLEN);
+        delim = strchr(prefix, DELIM);
+        if (delim)
+            *delim = '\0';
+        joinpath(prefix, lib_python);
+        joinpath(prefix, LANDMARK);
+        return 1;
+    }
+
+    /* Check to see if argv[0] is in the build directory */
+    strcpy(prefix, argv0_path);
+    joinpath(prefix, "Modules/Setup");
+    if (isfile(prefix)) {
+        /* Check VPATH to see if argv0_path is in the build directory. */
+        vpath = VPATH;
+        strcpy(prefix, argv0_path);
+        joinpath(prefix, vpath);
+        joinpath(prefix, "Lib");
+        joinpath(prefix, LANDMARK);
+        if (ismodule(prefix))
+            return -1;
+    }
+
+    /* Search from argv0_path, until root is found */
+    copy_absolute(prefix, argv0_path);
+    do {
+        n = strlen(prefix);
+        joinpath(prefix, lib_python);
+        joinpath(prefix, LANDMARK);
+        if (ismodule(prefix))
+            return 1;
+        prefix[n] = '\0';
+        reduce(prefix);
+    } while (prefix[0]);
+
+    /* Look at configure's PREFIX */
+    strncpy(prefix, PREFIX, MAXPATHLEN);
+    joinpath(prefix, lib_python);
+    joinpath(prefix, LANDMARK);
+    if (ismodule(prefix))
+        return 1;
+
+    /* Fail */
+    return 0;
+}
+
+
+/* search_for_exec_prefix requires that argv0_path be no more than
+   MAXPATHLEN bytes long.
+*/
+static int
+search_for_exec_prefix(char *argv0_path, char *home)
+{
+    size_t n;
+
+    /* If PYTHONHOME is set, we believe it unconditionally */
+    if (home) {
+        char *delim;
+        delim = strchr(home, DELIM);
+        if (delim)
+            strncpy(exec_prefix, delim+1, MAXPATHLEN);
+        else
+            strncpy(exec_prefix, home, MAXPATHLEN);
+        joinpath(exec_prefix, lib_python);
+        joinpath(exec_prefix, "lib-dynload");
+        return 1;
+    }
+
+    /* Check to see if argv[0] is in the build directory */
+    strcpy(exec_prefix, argv0_path);
+    joinpath(exec_prefix, "Modules/Setup");
+    if (isfile(exec_prefix)) {
+        reduce(exec_prefix);
+        return -1;
+    }
+
+    /* Search from argv0_path, until root is found */
+    copy_absolute(exec_prefix, argv0_path);
+    do {
+        n = strlen(exec_prefix);
+        joinpath(exec_prefix, lib_python);
+        joinpath(exec_prefix, "lib-dynload");
+        if (isdir(exec_prefix))
+            return 1;
+        exec_prefix[n] = '\0';
+        reduce(exec_prefix);
+    } while (exec_prefix[0]);
+
+    /* Look at configure's EXEC_PREFIX */
+    strncpy(exec_prefix, EXEC_PREFIX, MAXPATHLEN);
+    joinpath(exec_prefix, lib_python);
+    joinpath(exec_prefix, "lib-dynload");
+    if (isdir(exec_prefix))
+        return 1;
+
+    /* Fail */
+    return 0;
+}
+
+
+static void
+calculate_path(void)
+{
+    extern char *Py_GetProgramName(void);
+
+    static char delimiter[2] = {DELIM, '\0'};
+    static char separator[2] = {SEP, '\0'};
+    char *pythonpath = PYTHONPATH;
+    char *rtpypath = Py_GETENV("PYTHONPATH");
+    char *home = Py_GetPythonHome();
+    char *path = getenv("PATH");
+    char *prog = Py_GetProgramName();
+    char argv0_path[MAXPATHLEN+1];
+    char zip_path[MAXPATHLEN+1];
+    int pfound, efound; /* 1 if found; -1 if found build directory */
+    char *buf;
+    size_t bufsz;
+    size_t prefixsz;
+    char *defpath = pythonpath;
+#ifdef WITH_NEXT_FRAMEWORK
+    NSModule pythonModule;
+#endif
+#ifdef __APPLE__
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
+    uint32_t nsexeclength = MAXPATHLEN;
+#else
+    unsigned long nsexeclength = MAXPATHLEN;
+#endif
+#endif
+
+	/* If there is no slash in the argv0 path, then we have to
+	 * assume python is on the user's $PATH, since there's no
+	 * other way to find a directory to start the search from.  If
+	 * $PATH isn't exported, you lose.
+	 */
+	if (strchr(prog, SEP))
+		strncpy(progpath, prog, MAXPATHLEN);
+#ifdef __APPLE__
+     /* On Mac OS X, if a script uses an interpreter of the form
+      * "#!/opt/python2.3/bin/python", the kernel only passes "python"
+      * as argv[0], which falls through to the $PATH search below.
+      * If /opt/python2.3/bin isn't in your path, or is near the end,
+      * this algorithm may incorrectly find /usr/bin/python. To work
+      * around this, we can use _NSGetExecutablePath to get a better
+      * hint of what the intended interpreter was, although this
+      * will fail if a relative path was used. but in that case,
+      * absolutize() should help us out below
+      */
+     else if(0 == _NSGetExecutablePath(progpath, &nsexeclength) && progpath[0] == SEP)
+       ;
+#endif /* __APPLE__ */
+	else if (path) {
+		while (1) {
+			char *delim = strchr(path, DELIM);
+
+			if (delim) {
+				size_t len = delim - path;
+				if (len > MAXPATHLEN)
+					len = MAXPATHLEN;
+				strncpy(progpath, path, len);
+				*(progpath + len) = '\0';
+			}
+			else
+				strncpy(progpath, path, MAXPATHLEN);
+
+			joinpath(progpath, prog);
+			if (isxfile(progpath))
+				break;
+
+			if (!delim) {
+				progpath[0] = '\0';
+				break;
+			}
+			path = delim + 1;
+		}
+	}
+	else
+		progpath[0] = '\0';
+	if (progpath[0] != SEP)
+		absolutize(progpath);
+	strncpy(argv0_path, progpath, MAXPATHLEN);
+	argv0_path[MAXPATHLEN] = '\0';
+
+#ifdef WITH_NEXT_FRAMEWORK
+	/* On Mac OS X we have a special case if we're running from a framework.
+	** This is because the python home should be set relative to the library,
+	** which is in the framework, not relative to the executable, which may
+	** be outside of the framework. Except when we're in the build directory...
+	*/
+    pythonModule = NSModuleForSymbol(NSLookupAndBindSymbol("_Py_Initialize"));
+    /* Use dylib functions to find out where the framework was loaded from */
+    buf = (char *)NSLibraryNameForModule(pythonModule);
+    if (buf != NULL) {
+        /* We're in a framework. */
+        /* See if we might be in the build directory. The framework in the
+        ** build directory is incomplete, it only has the .dylib and a few
+        ** needed symlinks, it doesn't have the Lib directories and such.
+        ** If we're running with the framework from the build directory we must
+        ** be running the interpreter in the build directory, so we use the
+        ** build-directory-specific logic to find Lib and such.
+        */
+        strncpy(argv0_path, buf, MAXPATHLEN);
+        reduce(argv0_path);
+        joinpath(argv0_path, lib_python);
+        joinpath(argv0_path, LANDMARK);
+        if (!ismodule(argv0_path)) {
+                /* We are in the build directory so use the name of the
+                   executable - we know that the absolute path is passed */
+                strncpy(argv0_path, prog, MAXPATHLEN);
+        }
+        else {
+                /* Use the location of the library as the progpath */
+                strncpy(argv0_path, buf, MAXPATHLEN);
+        }
+    }
+#endif
+
+#if HAVE_READLINK
+    {
+        char tmpbuffer[MAXPATHLEN+1];
+        int linklen = readlink(progpath, tmpbuffer, MAXPATHLEN);
+        while (linklen != -1) {
+            /* It's not null terminated! */
+            tmpbuffer[linklen] = '\0';
+            if (tmpbuffer[0] == SEP)
+                /* tmpbuffer should never be longer than MAXPATHLEN,
+                   but extra check does not hurt */
+                strncpy(argv0_path, tmpbuffer, MAXPATHLEN);
+            else {
+                /* Interpret relative to progpath */
+                reduce(argv0_path);
+                joinpath(argv0_path, tmpbuffer);
+            }
+            linklen = readlink(argv0_path, tmpbuffer, MAXPATHLEN);
+        }
+    }
+#endif /* HAVE_READLINK */
+
+    reduce(argv0_path);
+    /* At this point, argv0_path is guaranteed to be less than
+       MAXPATHLEN bytes long.
+    */
+
+    if (!(pfound = search_for_prefix(argv0_path, home))) {
+        if (!Py_FrozenFlag)
+            fprintf(stderr,
+                "Could not find platform independent libraries <prefix>\n");
+        strncpy(prefix, PREFIX, MAXPATHLEN);
+        joinpath(prefix, lib_python);
+    }
+    else
+        reduce(prefix);
+
+    strncpy(zip_path, prefix, MAXPATHLEN);
+    zip_path[MAXPATHLEN] = '\0';
+    if (pfound > 0) { /* Use the reduced prefix returned by Py_GetPrefix() */
+        reduce(zip_path);
+        reduce(zip_path);
+    }
+    else
+        strncpy(zip_path, PREFIX, MAXPATHLEN);
+    joinpath(zip_path, "lib/python00.zip");
+    bufsz = strlen(zip_path);	/* Replace "00" with version */
+    zip_path[bufsz - 6] = VERSION[0];
+    zip_path[bufsz - 5] = VERSION[2];
+
+    if (!(efound = search_for_exec_prefix(argv0_path, home))) {
+        if (!Py_FrozenFlag)
+            fprintf(stderr,
+                "Could not find platform dependent libraries <exec_prefix>\n");
+        strncpy(exec_prefix, EXEC_PREFIX, MAXPATHLEN);
+        joinpath(exec_prefix, "lib/lib-dynload");
+    }
+    /* If we found EXEC_PREFIX do *not* reduce it!  (Yet.) */
+
+    if ((!pfound || !efound) && !Py_FrozenFlag)
+        fprintf(stderr,
+                "Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]\n");
+
+    /* Calculate size of return buffer.
+     */
+    bufsz = 0;
+
+    if (rtpypath)
+        bufsz += strlen(rtpypath) + 1;
+
+    prefixsz = strlen(prefix) + 1;
+
+    while (1) {
+        char *delim = strchr(defpath, DELIM);
+
+        if (defpath[0] != SEP)
+            /* Paths are relative to prefix */
+            bufsz += prefixsz;
+
+        if (delim)
+            bufsz += delim - defpath + 1;
+        else {
+            bufsz += strlen(defpath) + 1;
+            break;
+        }
+        defpath = delim + 1;
+    }
+
+    bufsz += strlen(zip_path) + 1;
+    bufsz += strlen(exec_prefix) + 1;
+
+    /* This is the only malloc call in this file */
+    buf = (char *)PyMem_Malloc(bufsz);
+
+    if (buf == NULL) {
+        /* We can't exit, so print a warning and limp along */
+        fprintf(stderr, "Not enough memory for dynamic PYTHONPATH.\n");
+        fprintf(stderr, "Using default static PYTHONPATH.\n");
+        module_search_path = PYTHONPATH;
+    }
+    else {
+        /* Run-time value of $PYTHONPATH goes first */
+        if (rtpypath) {
+            strcpy(buf, rtpypath);
+            strcat(buf, delimiter);
+        }
+        else
+            buf[0] = '\0';
+
+        /* Next is the default zip path */
+        strcat(buf, zip_path);
+        strcat(buf, delimiter);
+
+        /* Next goes merge of compile-time $PYTHONPATH with
+         * dynamically located prefix.
+         */
+        defpath = pythonpath;
+        while (1) {
+            char *delim = strchr(defpath, DELIM);
+
+            if (defpath[0] != SEP) {
+                strcat(buf, prefix);
+                strcat(buf, separator);
+            }
+
+            if (delim) {
+                size_t len = delim - defpath + 1;
+                size_t end = strlen(buf) + len;
+                strncat(buf, defpath, len);
+                *(buf + end) = '\0';
+            }
+            else {
+                strcat(buf, defpath);
+                break;
+            }
+            defpath = delim + 1;
+        }
+        strcat(buf, delimiter);
+
+        /* Finally, on goes the directory for dynamic-load modules */
+        strcat(buf, exec_prefix);
+
+        /* And publish the results */
+        module_search_path = buf;
+    }
+
+    /* Reduce prefix and exec_prefix to their essence,
+     * e.g. /usr/local/lib/python1.5 is reduced to /usr/local.
+     * If we're loading relative to the build directory,
+     * return the compiled-in defaults instead.
+     */
+    if (pfound > 0) {
+        reduce(prefix);
+        reduce(prefix);
+	/* The prefix is the root directory, but reduce() chopped
+	 * off the "/". */
+	if (!prefix[0])
+		strcpy(prefix, separator);
+    }
+    else
+        strncpy(prefix, PREFIX, MAXPATHLEN);
+
+    if (efound > 0) {
+        reduce(exec_prefix);
+        reduce(exec_prefix);
+        reduce(exec_prefix);
+	if (!exec_prefix[0])
+		strcpy(exec_prefix, separator);
+    }
+    else
+        strncpy(exec_prefix, EXEC_PREFIX, MAXPATHLEN);
+}
+
+
+/* External interface */
+
+char *
+Py_GetPath(void)
+{
+    if (!module_search_path)
+        calculate_path();
+    return module_search_path;
+}
+
+char *
+Py_GetPrefix(void)
+{
+    if (!module_search_path)
+        calculate_path();
+    return prefix;
+}
+
+char *
+Py_GetExecPrefix(void)
+{
+    if (!module_search_path)
+        calculate_path();
+    return exec_prefix;
+}
+
+char *
+Py_GetProgramFullPath(void)
+{
+    if (!module_search_path)
+        calculate_path();
+    return progpath;
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+

Added: vendor/Python/current/Modules/glmodule.c
===================================================================
--- vendor/Python/current/Modules/glmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/glmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,7628 @@
+
+/*
+Input used to generate the Python module "glmodule.c".
+The stub generator is a Python script called "cgen.py".
+
+Each definition must be contained on one line:
+
+<returntype> <name> <type> <arg> <type> <arg>
+
+<returntype> can be: void, short, long (XXX maybe others?)
+
+<type> can be: char, string, short, float, long, or double
+	string indicates a null terminated string;
+	if <type> is char and <arg> begins with a *, the * is stripped
+	and <type> is changed into string
+
+<arg> has the form <mode> or <mode>[<subscript>]
+	where <mode> can be
+		s: arg is sent
+		r: arg is received		(arg is a pointer)
+	and <subscript> can be (N and I are numbers):
+		N
+		argI
+		retval
+		N*argI
+		N*I
+		N*retval
+	In the case where the subscript consists of two parts
+	separated by *, the first part is the width of the matrix, and
+	the second part is the length of the matrix.  This order is
+	opposite from the order used in C to declare a two-dimensional
+	matrix.
+*/
+
+/*
+ * An attempt has been made to make this module switch threads on qread
+ * calls. It is far from safe, though.
+ */
+
+#include <gl.h>
+#include <device.h>
+
+#ifdef __sgi
+extern int devport();
+extern int textwritemask();
+extern int pagewritemask();
+extern int gewrite();
+extern int gettp();
+#endif
+
+#include "Python.h"
+#include "cgensupport.h"
+
+/*
+Some stubs are too complicated for the stub generator.
+We can include manually written versions of them here.
+A line starting with '%' gives the name of the function so the stub
+generator can include it in the table of functions.
+*/
+
+
+static PyObject *
+gl_qread(PyObject *self, PyObject *args)
+{
+	long retval;
+	short arg1 ;
+	Py_BEGIN_ALLOW_THREADS
+	retval = qread( & arg1 );
+	Py_END_ALLOW_THREADS
+	{ PyObject *v = PyTuple_New( 2 );
+	  if (v == NULL) return NULL;
+	  PyTuple_SetItem(v, 0, mknewlongobject(retval));
+	  PyTuple_SetItem(v, 1, mknewshortobject(arg1));
+	  return v;
+	}
+}
+
+
+/*
+varray -- an array of v.. calls.
+The argument is an array (maybe list or tuple) of points.
+Each point must be a tuple or list of coordinates (x, y, z).
+The points may be 2- or 3-dimensional but must all have the
+same dimension.  Float and int values may be mixed however.
+The points are always converted to 3D double precision points
+by assuming z=0.0 if necessary (as indicated in the man page),
+and for each point v3d() is called.
+*/
+
+
+static PyObject *
+gl_varray(PyObject *self, PyObject *args)
+{
+	PyObject *v, *w=NULL;
+	int i, n, width;
+	double vec[3];
+	PyObject * (*getitem)(PyObject *, int);
+	
+	if (!PyArg_GetObject(args, 1, 0, &v))
+		return NULL;
+	
+	if (PyList_Check(v)) {
+		n = PyList_Size(v);
+		getitem = PyList_GetItem;
+	}
+	else if (PyTuple_Check(v)) {
+		n = PyTuple_Size(v);
+		getitem = PyTuple_GetItem;
+	}
+	else {
+		PyErr_BadArgument();
+		return NULL;
+	}
+	
+	if (n == 0) {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+	if (n > 0)
+		w = (*getitem)(v, 0);
+	
+	width = 0;
+	if (w == NULL) {
+	}
+	else if (PyList_Check(w)) {
+		width = PyList_Size(w);
+	}
+	else if (PyTuple_Check(w)) {
+		width = PyTuple_Size(w);
+	}
+	
+	switch (width) {
+	case 2:
+		vec[2] = 0.0;
+		/* Fall through */
+	case 3:
+		break;
+	default:
+		PyErr_BadArgument();
+		return NULL;
+	}
+	
+	for (i = 0; i < n; i++) {
+		w = (*getitem)(v, i);
+		if (!PyArg_GetDoubleArray(w, 1, 0, width, vec))
+			return NULL;
+		v3d(vec);
+	}
+	
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/*
+vnarray, nvarray -- an array of n3f and v3f calls.
+The argument is an array (list or tuple) of pairs of points and normals.
+Each pair is a tuple (NOT a list) of a point and a normal for that point.
+Each point or normal must be a tuple (NOT a list) of coordinates (x, y, z).
+Three coordinates must be given.  Float and int values may be mixed.
+For each pair, n3f() is called for the normal, and then v3f() is called
+for the vector.
+
+vnarray and nvarray differ only in the order of the vector and normal in
+the pair: vnarray expects (v, n) while nvarray expects (n, v).
+*/
+
+static PyObject *gen_nvarray(); /* Forward */
+
+
+static PyObject *
+gl_nvarray(PyObject *self, PyObject *args)
+{
+	return gen_nvarray(args, 0);
+}
+
+
+static PyObject *
+gl_vnarray(PyObject *self, PyObject *args)
+{
+	return gen_nvarray(args, 1);
+}
+
+/* Generic, internal version of {nv,nv}array: inorm indicates the
+   argument order, 0: normal first, 1: vector first. */
+
+static PyObject *
+gen_nvarray(PyObject *args, int inorm)
+{
+	PyObject *v, *w, *wnorm, *wvec;
+	int i, n;
+	float norm[3], vec[3];
+	PyObject * (*getitem)(PyObject *, int);
+	
+	if (!PyArg_GetObject(args, 1, 0, &v))
+		return NULL;
+	
+	if (PyList_Check(v)) {
+		n = PyList_Size(v);
+		getitem = PyList_GetItem;
+	}
+	else if (PyTuple_Check(v)) {
+		n = PyTuple_Size(v);
+		getitem = PyTuple_GetItem;
+	}
+	else {
+		PyErr_BadArgument();
+		return NULL;
+	}
+	
+	for (i = 0; i < n; i++) {
+		w = (*getitem)(v, i);
+		if (!PyTuple_Check(w) || PyTuple_Size(w) != 2) {
+			PyErr_BadArgument();
+			return NULL;
+		}
+		wnorm = PyTuple_GetItem(w, inorm);
+		wvec = PyTuple_GetItem(w, 1 - inorm);
+		if (!PyArg_GetFloatArray(wnorm, 1, 0, 3, norm) ||
+			!PyArg_GetFloatArray(wvec, 1, 0, 3, vec))
+			return NULL;
+		n3f(norm);
+		v3f(vec);
+	}
+	
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* nurbssurface(s_knots[], t_knots[], ctl[][], s_order, t_order, type).
+   The dimensions of ctl[] are computed as follows:
+   [len(s_knots) - s_order], [len(t_knots) - t_order]
+*/
+
+
+static PyObject *
+gl_nurbssurface(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	double * arg2 ;
+	long arg3 ;
+	double * arg4 ;
+	double *arg5 ;
+	long arg6 ;
+	long arg7 ;
+	long arg8 ;
+	long ncoords;
+	long s_byte_stride, t_byte_stride;
+	long s_nctl, t_nctl;
+	long s, t;
+	PyObject *v, *w, *pt;
+	double *pnext;
+	if (!PyArg_GetLongArraySize(args, 6, 0, &arg1))
+		return NULL;
+	if ((arg2 = PyMem_NEW(double, arg1 )) == NULL) {
+		return PyErr_NoMemory();
+	}
+	if (!PyArg_GetDoubleArray(args, 6, 0, arg1 , arg2))
+		return NULL;
+	if (!PyArg_GetLongArraySize(args, 6, 1, &arg3))
+		return NULL;
+	if ((arg4 = PyMem_NEW(double, arg3 )) == NULL) {
+		return PyErr_NoMemory();
+	}
+	if (!PyArg_GetDoubleArray(args, 6, 1, arg3 , arg4))
+		return NULL;
+	if (!PyArg_GetLong(args, 6, 3, &arg6))
+		return NULL;
+	if (!PyArg_GetLong(args, 6, 4, &arg7))
+		return NULL;
+	if (!PyArg_GetLong(args, 6, 5, &arg8))
+		return NULL;
+	if (arg8 == N_XYZ)
+		ncoords = 3;
+	else if (arg8 == N_XYZW)
+		ncoords = 4;
+	else {
+		PyErr_BadArgument();
+		return NULL;
+	}
+	s_nctl = arg1 - arg6;
+	t_nctl = arg3 - arg7;
+	if (!PyArg_GetObject(args, 6, 2, &v))
+		return NULL;
+	if (!PyList_Check(v) || PyList_Size(v) != s_nctl) {
+		PyErr_BadArgument();
+		return NULL;
+	}
+	if ((arg5 = PyMem_NEW(double, s_nctl*t_nctl*ncoords )) == NULL) {
+		return PyErr_NoMemory();
+	}
+	pnext = arg5;
+	for (s = 0; s < s_nctl; s++) {
+		w = PyList_GetItem(v, s);
+		if (w == NULL || !PyList_Check(w) ||
+					PyList_Size(w) != t_nctl) {
+			PyErr_BadArgument();
+			return NULL;
+		}
+		for (t = 0; t < t_nctl; t++) {
+			pt = PyList_GetItem(w, t);
+			if (!PyArg_GetDoubleArray(pt, 1, 0, ncoords, pnext))
+				return NULL;
+			pnext += ncoords;
+		}
+	}
+	s_byte_stride = sizeof(double) * ncoords;
+	t_byte_stride = s_byte_stride * s_nctl;
+	nurbssurface( arg1 , arg2 , arg3 , arg4 ,
+		s_byte_stride , t_byte_stride , arg5 , arg6 , arg7 , arg8 );
+	PyMem_DEL(arg2);
+	PyMem_DEL(arg4);
+	PyMem_DEL(arg5);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* nurbscurve(knots, ctlpoints, order, type).
+   The length of ctlpoints is len(knots)-order. */
+
+
+static PyObject *
+gl_nurbscurve(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	double * arg2 ;
+	long arg3 ;
+	double * arg4 ;
+	long arg5 ;
+	long arg6 ;
+	int ncoords, npoints;
+	int i;
+	PyObject *v;
+	double *pnext;
+	if (!PyArg_GetLongArraySize(args, 4, 0, &arg1))
+		return NULL;
+	if ((arg2 = PyMem_NEW(double, arg1 )) == NULL) {
+		return PyErr_NoMemory();
+	}
+	if (!PyArg_GetDoubleArray(args, 4, 0, arg1 , arg2))
+		return NULL;
+	if (!PyArg_GetLong(args, 4, 2, &arg5))
+		return NULL;
+	if (!PyArg_GetLong(args, 4, 3, &arg6))
+		return NULL;
+	if (arg6 == N_ST)
+		ncoords = 2;
+	else if (arg6 == N_STW)
+		ncoords = 3;
+	else {
+		PyErr_BadArgument();
+		return NULL;
+	}
+	npoints = arg1 - arg5;
+	if (!PyArg_GetObject(args, 4, 1, &v))
+		return NULL;
+	if (!PyList_Check(v) || PyList_Size(v) != npoints) {
+		PyErr_BadArgument();
+		return NULL;
+	}
+	if ((arg4 = PyMem_NEW(double, npoints*ncoords )) == NULL) {
+		return PyErr_NoMemory();
+	}
+	pnext = arg4;
+	for (i = 0; i < npoints; i++) {
+		if (!PyArg_GetDoubleArray(PyList_GetItem(v, i), 1, 0, ncoords, pnext))
+			return NULL;
+		pnext += ncoords;
+	}
+	arg3 = (sizeof(double)) * ncoords;
+	nurbscurve( arg1 , arg2 , arg3 , arg4 , arg5 , arg6 );
+	PyMem_DEL(arg2);
+	PyMem_DEL(arg4);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* pwlcurve(points, type).
+   Points is a list of points. Type must be N_ST. */
+
+
+static PyObject *
+gl_pwlcurve(PyObject *self, PyObject *args)
+{
+	PyObject *v;
+	long type;
+	double *data, *pnext;
+	long npoints, ncoords;
+	int i;
+	if (!PyArg_GetObject(args, 2, 0, &v))
+		return NULL;
+	if (!PyArg_GetLong(args, 2, 1, &type))
+		return NULL;
+	if (!PyList_Check(v)) {
+		PyErr_BadArgument();
+		return NULL;
+	}
+	npoints = PyList_Size(v);
+	if (type == N_ST)
+		ncoords = 2;
+	else {
+		PyErr_BadArgument();
+		return NULL;
+	}
+	if ((data = PyMem_NEW(double, npoints*ncoords)) == NULL) {
+		return PyErr_NoMemory();
+	}
+	pnext = data;
+	for (i = 0; i < npoints; i++) {
+		if (!PyArg_GetDoubleArray(PyList_GetItem(v, i), 1, 0, ncoords, pnext))
+			return NULL;
+		pnext += ncoords;
+	}
+	pwlcurve(npoints, data, sizeof(double)*ncoords, type);
+	PyMem_DEL(data);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+
+/* Picking and Selecting */
+
+static short *pickbuffer = NULL;
+static long pickbuffersize;
+
+static PyObject *
+pick_select(PyObject *args, void (*func)())
+{
+	if (!PyArg_GetLong(args, 1, 0, &pickbuffersize))
+		return NULL;
+	if (pickbuffer != NULL) {
+		PyErr_SetString(PyExc_RuntimeError,
+			"pick/gselect: already picking/selecting");
+		return NULL;
+	}
+	if ((pickbuffer = PyMem_NEW(short, pickbuffersize)) == NULL) {
+		return PyErr_NoMemory();
+	}
+	(*func)(pickbuffer, pickbuffersize);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+endpick_select(long (*func)())
+{
+	PyObject *v, *w;
+	int i, nhits, n;
+	if (pickbuffer == NULL) {
+		PyErr_SetString(PyExc_RuntimeError,
+			"endpick/endselect: not in pick/select mode");
+		return NULL;
+	}
+	nhits = (*func)(pickbuffer);
+	if (nhits < 0) {
+		nhits = -nhits; /* How to report buffer overflow otherwise? */
+	}
+	/* Scan the buffer to see how many integers */
+	n = 0;
+	for (; nhits > 0; nhits--) {
+		n += 1 + pickbuffer[n];
+	}
+	v = PyList_New(n);
+	if (v == NULL)
+		return NULL;
+	/* XXX Could do it nicer and interpret the data structure here,
+	   returning a list of lists. But this can be done in Python... */
+	for (i = 0; i < n; i++) {
+		w = PyInt_FromLong((long)pickbuffer[i]);
+		if (w == NULL) {
+			Py_DECREF(v);
+			return NULL;
+		}
+		PyList_SetItem(v, i, w);
+	}
+	PyMem_DEL(pickbuffer);
+	pickbuffer = NULL;
+	return v;
+}
+
+extern void pick(), gselect();
+extern long endpick(), endselect();
+
+static PyObject *gl_pick(PyObject *self, PyObject *args)
+{
+	return pick_select(args, pick);
+}
+
+static PyObject *gl_endpick(PyObject *self)
+{
+	return endpick_select(endpick);
+}
+
+static PyObject *gl_gselect(PyObject *self, PyObject *args)
+{
+	return pick_select(args, gselect);
+}
+
+static PyObject *gl_endselect(PyObject *self)
+{
+	return endpick_select(endselect);
+}
+
+
+/* XXX The generator botches this one.  Here's a quick hack to fix it. */
+
+/* XXX The generator botches this one.  Here's a quick hack to fix it. */
+
+
+static PyObject *
+gl_getmatrix(PyObject *self, PyObject *args)
+{
+	Matrix arg1;
+	PyObject *v, *w;
+	int i, j;
+	getmatrix( arg1 );
+	v = PyList_New(16);
+	if (v == NULL) {
+		return PyErr_NoMemory();
+	}
+	for (i = 0; i < 4; i++) for (j = 0; j < 4; j++) {
+		w = mknewfloatobject(arg1[i][j]);
+		if (w == NULL) {
+			Py_DECREF(v);
+			return NULL;
+		}
+		PyList_SetItem(v, i*4+j, w);
+	}
+	return v;
+}
+
+/* Here's an alternate version that returns a 4x4 matrix instead of
+   a vector.  Unfortunately it is incompatible with loadmatrix and
+   multmatrix... */
+
+
+static PyObject *
+gl_altgetmatrix(PyObject *self, PyObject *args)
+{
+	Matrix arg1;
+	PyObject *v, *w;
+	int i, j;
+	getmatrix( arg1 );
+	v = PyList_New(4);
+	if (v == NULL) {
+		return NULL;
+	}
+	for (i = 0; i < 4; i++) {
+		w = PyList_New(4);
+		if (w == NULL) {
+			Py_DECREF(v);
+			return NULL;
+		}
+		PyList_SetItem(v, i, w);
+	}
+	for (i = 0; i < 4; i++) {
+		for (j = 0; j < 4; j++) {
+			w = mknewfloatobject(arg1[i][j]);
+			if (w == NULL) {
+				Py_DECREF(v);
+				return NULL;
+			}
+			PyList_SetItem(PyList_GetItem(v, i), j, w);
+		}
+	}
+	return v;
+}
+
+
+static PyObject *
+gl_lrectwrite(PyObject *self, PyObject *args)
+{
+	short x1 ;
+	short y1 ;
+	short x2 ;
+	short y2 ;
+	string parray ;
+	PyObject *s;
+#if 0
+	int pixcount;
+#endif
+	if (!PyArg_GetShort(args, 5, 0, &x1))
+		return NULL;
+	if (!PyArg_GetShort(args, 5, 1, &y1))
+		return NULL;
+	if (!PyArg_GetShort(args, 5, 2, &x2))
+		return NULL;
+	if (!PyArg_GetShort(args, 5, 3, &y2))
+		return NULL;
+	if (!PyArg_GetString(args, 5, 4, &parray))
+		return NULL;
+	if (!PyArg_GetObject(args, 5, 4, &s))
+		return NULL;
+#if 0
+/* Don't check this, it breaks experiments with pixmode(PM_SIZE, ...) */
+	pixcount = (long)(x2+1-x1) * (long)(y2+1-y1);
+	if (!PyString_Check(s) || PyString_Size(s) != pixcount*sizeof(long)) {
+		PyErr_SetString(PyExc_RuntimeError,
+			   "string arg to lrectwrite has wrong size");
+		return NULL;
+	}
+#endif
+	lrectwrite( x1 , y1 , x2 , y2 , (unsigned long *) parray );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+
+static PyObject *
+gl_lrectread(PyObject *self, PyObject *args)
+{
+	short x1 ;
+	short y1 ;
+	short x2 ;
+	short y2 ;
+	PyObject *parray;
+	int pixcount;
+	if (!PyArg_GetShort(args, 4, 0, &x1))
+		return NULL;
+	if (!PyArg_GetShort(args, 4, 1, &y1))
+		return NULL;
+	if (!PyArg_GetShort(args, 4, 2, &x2))
+		return NULL;
+	if (!PyArg_GetShort(args, 4, 3, &y2))
+		return NULL;
+	pixcount = (long)(x2+1-x1) * (long)(y2+1-y1);
+	parray = PyString_FromStringAndSize((char *)NULL, pixcount*sizeof(long));
+	if (parray == NULL)
+		return NULL; /* No memory */
+	lrectread(x1, y1, x2, y2, (unsigned long *) PyString_AsString(parray));
+	return parray;
+}
+
+
+static PyObject *
+gl_readdisplay(PyObject *self, PyObject *args)
+{
+        short x1, y1, x2, y2;
+	unsigned long *parray, hints;
+	long size, size_ret;
+	PyObject *rv;
+
+	if ( !PyArg_Parse(args, "hhhhl", &x1, &y1, &x2, &y2, &hints) )
+	  return 0;
+	size = (long)(x2+1-x1) * (long)(y2+1-y1);
+	rv = PyString_FromStringAndSize((char *)NULL, size*sizeof(long));
+	if ( rv == NULL )
+	  return NULL;
+	parray = (unsigned long *)PyString_AsString(rv);
+	size_ret = readdisplay(x1, y1, x2, y2, parray, hints);
+	if ( size_ret != size ) {
+	    printf("gl_readdisplay: got %ld pixels, expected %ld\n",
+		   size_ret, size);
+	    PyErr_SetString(PyExc_RuntimeError, "readdisplay returned unexpected length");
+	    return NULL;
+	}
+	return rv;
+}
+
+/* Desperately needed, here are tools to compress and decompress
+   the data manipulated by lrectread/lrectwrite.
+
+   gl.packrect(width, height, packfactor, bigdata) --> smalldata
+		makes 'bigdata' 4*(packfactor**2) times smaller by:
+		- turning it into B/W (a factor 4)
+		- replacing squares of size pacfactor by one
+		  representative
+
+   gl.unpackrect(width, height, packfactor, smalldata) --> bigdata
+		is the inverse; the numeric arguments must be *the same*.
+
+   Both work best if width and height are multiples of packfactor
+   (in fact unpackrect will leave garbage bytes).
+*/
+
+
+static PyObject *
+gl_packrect(PyObject *self, PyObject *args)
+{
+	long width, height, packfactor;
+	char *s;
+	PyObject *unpacked, *packed;
+	int pixcount, packedcount, x, y, r, g, b;
+	unsigned long pixel;
+	unsigned char *p;
+	unsigned long *parray;
+	if (!PyArg_GetLong(args, 4, 0, &width))
+		return NULL;
+	if (!PyArg_GetLong(args, 4, 1, &height))
+		return NULL;
+	if (!PyArg_GetLong(args, 4, 2, &packfactor))
+		return NULL;
+	if (!PyArg_GetString(args, 4, 3, &s)) /* For type checking only */
+		return NULL;
+	if (!PyArg_GetObject(args, 4, 3, &unpacked))
+		return NULL;
+	if (width <= 0 || height <= 0 || packfactor <= 0) {
+		PyErr_SetString(PyExc_RuntimeError, "packrect args must be > 0");
+		return NULL;
+	}
+	pixcount = width*height;
+	packedcount = ((width+packfactor-1)/packfactor) *
+		((height+packfactor-1)/packfactor);
+	if (PyString_Size(unpacked) != pixcount*sizeof(long)) {
+		PyErr_SetString(PyExc_RuntimeError,
+			   "string arg to packrect has wrong size");
+		return NULL;
+	}
+	packed = PyString_FromStringAndSize((char *)NULL, packedcount);
+	if (packed == NULL)
+		return NULL;
+	parray = (unsigned long *) PyString_AsString(unpacked);
+	p = (unsigned char *) PyString_AsString(packed);
+	for (y = 0; y < height; y += packfactor, parray += packfactor*width) {
+		for (x = 0; x < width; x += packfactor) {
+			pixel = parray[x];
+			r = pixel & 0xff;
+			g = (pixel >> 8) & 0xff;
+			b = (pixel >> 16) & 0xff;
+			*p++ = (30*r+59*g+11*b) / 100;
+		}
+	}
+	return packed;
+}
+
+
+static unsigned long unpacktab[256];
+static int unpacktab_inited = 0;
+
+static PyObject *
+gl_unpackrect(PyObject *self, PyObject *args)
+{
+	long width, height, packfactor;
+	char *s;
+	PyObject *unpacked, *packed;
+	int pixcount, packedcount;
+	register unsigned char *p;
+	register unsigned long *parray;
+	if (!unpacktab_inited) {
+		register int white;
+		for (white = 256; --white >= 0; )
+			unpacktab[white] = white * 0x010101L;
+		unpacktab_inited++;
+	}
+	if (!PyArg_GetLong(args, 4, 0, &width))
+		return NULL;
+	if (!PyArg_GetLong(args, 4, 1, &height))
+		return NULL;
+	if (!PyArg_GetLong(args, 4, 2, &packfactor))
+		return NULL;
+	if (!PyArg_GetString(args, 4, 3, &s)) /* For type checking only */
+		return NULL;
+	if (!PyArg_GetObject(args, 4, 3, &packed))
+		return NULL;
+	if (width <= 0 || height <= 0 || packfactor <= 0) {
+		PyErr_SetString(PyExc_RuntimeError, "packrect args must be > 0");
+		return NULL;
+	}
+	pixcount = width*height;
+	packedcount = ((width+packfactor-1)/packfactor) *
+		((height+packfactor-1)/packfactor);
+	if (PyString_Size(packed) != packedcount) {
+		PyErr_SetString(PyExc_RuntimeError,
+			   "string arg to unpackrect has wrong size");
+		return NULL;
+	}
+	unpacked = PyString_FromStringAndSize((char *)NULL, pixcount*sizeof(long));
+	if (unpacked == NULL)
+		return NULL;
+	parray = (unsigned long *) PyString_AsString(unpacked);
+	p = (unsigned char *) PyString_AsString(packed);
+	if (packfactor == 1 && width*height > 0) {
+		/* Just expand bytes to longs */
+		register int x = width * height;
+		do {
+			*parray++ = unpacktab[*p++];
+		} while (--x >= 0);
+	}
+	else {
+		register int y;
+		for (y = 0; y < height-packfactor+1;
+		     y += packfactor, parray += packfactor*width) {
+			register int x;
+			for (x = 0; x < width-packfactor+1; x += packfactor) {
+				register unsigned long pixel = unpacktab[*p++];
+				register int i;
+				for (i = packfactor*width; (i-=width) >= 0;) {
+					register int j;
+					for (j = packfactor; --j >= 0; )
+						parray[i+x+j] = pixel;
+				}
+			}
+		}
+	}
+	return unpacked;
+}
+
+static PyObject *
+gl_gversion(PyObject *self, PyObject *args)
+{
+	char buf[20];
+	gversion(buf);
+	return PyString_FromString(buf);
+}
+
+
+/* void clear - Manual because of clash with termcap */
+static PyObject *
+gl_clear(PyObject *self, PyObject *args)
+{
+	__GLclear( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* End of manually written stubs */
+
+
+/* long getshade */
+
+static PyObject *
+gl_getshade(PyObject *self, PyObject *args)
+{
+	long retval;
+	retval = getshade( );
+	return mknewlongobject(retval);
+}
+
+/* void devport short s long s */
+
+static PyObject *
+gl_devport(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	long arg2 ;
+	if (!getishortarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 2, 1, &arg2))
+		return NULL;
+	devport( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void rdr2i long s long s */
+
+static PyObject *
+gl_rdr2i(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	if (!getilongarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 2, 1, &arg2))
+		return NULL;
+	rdr2i( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void rectfs short s short s short s short s */
+
+static PyObject *
+gl_rectfs(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	short arg3 ;
+	short arg4 ;
+	if (!getishortarg(args, 4, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 4, 1, &arg2))
+		return NULL;
+	if (!getishortarg(args, 4, 2, &arg3))
+		return NULL;
+	if (!getishortarg(args, 4, 3, &arg4))
+		return NULL;
+	rectfs( arg1 , arg2 , arg3 , arg4 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void rects short s short s short s short s */
+
+static PyObject *
+gl_rects(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	short arg3 ;
+	short arg4 ;
+	if (!getishortarg(args, 4, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 4, 1, &arg2))
+		return NULL;
+	if (!getishortarg(args, 4, 2, &arg3))
+		return NULL;
+	if (!getishortarg(args, 4, 3, &arg4))
+		return NULL;
+	rects( arg1 , arg2 , arg3 , arg4 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void rmv2i long s long s */
+
+static PyObject *
+gl_rmv2i(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	if (!getilongarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 2, 1, &arg2))
+		return NULL;
+	rmv2i( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void noport */
+
+static PyObject *
+gl_noport(PyObject *self, PyObject *args)
+{
+	noport( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void popviewport */
+
+static PyObject *
+gl_popviewport(PyObject *self, PyObject *args)
+{
+	popviewport( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void clearhitcode */
+
+static PyObject *
+gl_clearhitcode(PyObject *self, PyObject *args)
+{
+	clearhitcode( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void closeobj */
+
+static PyObject *
+gl_closeobj(PyObject *self, PyObject *args)
+{
+	closeobj( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void cursoff */
+
+static PyObject *
+gl_cursoff(PyObject *self, PyObject *args)
+{
+	cursoff( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void curson */
+
+static PyObject *
+gl_curson(PyObject *self, PyObject *args)
+{
+	curson( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void doublebuffer */
+
+static PyObject *
+gl_doublebuffer(PyObject *self, PyObject *args)
+{
+	doublebuffer( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void finish */
+
+static PyObject *
+gl_finish(PyObject *self, PyObject *args)
+{
+	finish( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void gconfig */
+
+static PyObject *
+gl_gconfig(PyObject *self, PyObject *args)
+{
+	gconfig( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void ginit */
+
+static PyObject *
+gl_ginit(PyObject *self, PyObject *args)
+{
+	ginit( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void greset */
+
+static PyObject *
+gl_greset(PyObject *self, PyObject *args)
+{
+	greset( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void multimap */
+
+static PyObject *
+gl_multimap(PyObject *self, PyObject *args)
+{
+	multimap( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void onemap */
+
+static PyObject *
+gl_onemap(PyObject *self, PyObject *args)
+{
+	onemap( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void popattributes */
+
+static PyObject *
+gl_popattributes(PyObject *self, PyObject *args)
+{
+	popattributes( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void popmatrix */
+
+static PyObject *
+gl_popmatrix(PyObject *self, PyObject *args)
+{
+	popmatrix( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void pushattributes */
+
+static PyObject *
+gl_pushattributes(PyObject *self, PyObject *args)
+{
+	pushattributes( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void pushmatrix */
+
+static PyObject *
+gl_pushmatrix(PyObject *self, PyObject *args)
+{
+	pushmatrix( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void pushviewport */
+
+static PyObject *
+gl_pushviewport(PyObject *self, PyObject *args)
+{
+	pushviewport( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void qreset */
+
+static PyObject *
+gl_qreset(PyObject *self, PyObject *args)
+{
+	qreset( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void RGBmode */
+
+static PyObject *
+gl_RGBmode(PyObject *self, PyObject *args)
+{
+	RGBmode( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void singlebuffer */
+
+static PyObject *
+gl_singlebuffer(PyObject *self, PyObject *args)
+{
+	singlebuffer( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void swapbuffers */
+
+static PyObject *
+gl_swapbuffers(PyObject *self, PyObject *args)
+{
+	swapbuffers( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void gsync */
+
+static PyObject *
+gl_gsync(PyObject *self, PyObject *args)
+{
+	gsync( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void gflush */
+
+static PyObject *
+gl_gflush(PyObject *self, PyObject *args)
+{
+	gflush( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void tpon */
+
+static PyObject *
+gl_tpon(PyObject *self, PyObject *args)
+{
+	tpon( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void tpoff */
+
+static PyObject *
+gl_tpoff(PyObject *self, PyObject *args)
+{
+	tpoff( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void clkon */
+
+static PyObject *
+gl_clkon(PyObject *self, PyObject *args)
+{
+	clkon( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void clkoff */
+
+static PyObject *
+gl_clkoff(PyObject *self, PyObject *args)
+{
+	clkoff( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void ringbell */
+
+static PyObject *
+gl_ringbell(PyObject *self, PyObject *args)
+{
+	ringbell( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void gbegin */
+
+static PyObject *
+gl_gbegin(PyObject *self, PyObject *args)
+{
+	gbegin( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void textinit */
+
+static PyObject *
+gl_textinit(PyObject *self, PyObject *args)
+{
+	textinit( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void initnames */
+
+static PyObject *
+gl_initnames(PyObject *self, PyObject *args)
+{
+	initnames( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void pclos */
+
+static PyObject *
+gl_pclos(PyObject *self, PyObject *args)
+{
+	pclos( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void popname */
+
+static PyObject *
+gl_popname(PyObject *self, PyObject *args)
+{
+	popname( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void spclos */
+
+static PyObject *
+gl_spclos(PyObject *self, PyObject *args)
+{
+	spclos( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void zclear */
+
+static PyObject *
+gl_zclear(PyObject *self, PyObject *args)
+{
+	zclear( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void screenspace */
+
+static PyObject *
+gl_screenspace(PyObject *self, PyObject *args)
+{
+	screenspace( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void reshapeviewport */
+
+static PyObject *
+gl_reshapeviewport(PyObject *self, PyObject *args)
+{
+	reshapeviewport( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void winpush */
+
+static PyObject *
+gl_winpush(PyObject *self, PyObject *args)
+{
+	winpush( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void winpop */
+
+static PyObject *
+gl_winpop(PyObject *self, PyObject *args)
+{
+	winpop( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void foreground */
+
+static PyObject *
+gl_foreground(PyObject *self, PyObject *args)
+{
+	foreground( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void endfullscrn */
+
+static PyObject *
+gl_endfullscrn(PyObject *self, PyObject *args)
+{
+	endfullscrn( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void endpupmode */
+
+static PyObject *
+gl_endpupmode(PyObject *self, PyObject *args)
+{
+	endpupmode( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void fullscrn */
+
+static PyObject *
+gl_fullscrn(PyObject *self, PyObject *args)
+{
+	fullscrn( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void pupmode */
+
+static PyObject *
+gl_pupmode(PyObject *self, PyObject *args)
+{
+	pupmode( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void winconstraints */
+
+static PyObject *
+gl_winconstraints(PyObject *self, PyObject *args)
+{
+	winconstraints( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void pagecolor short s */
+
+static PyObject *
+gl_pagecolor(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	if (!getishortarg(args, 1, 0, &arg1))
+		return NULL;
+	pagecolor( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void textcolor short s */
+
+static PyObject *
+gl_textcolor(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	if (!getishortarg(args, 1, 0, &arg1))
+		return NULL;
+	textcolor( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void color short s */
+
+static PyObject *
+gl_color(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	if (!getishortarg(args, 1, 0, &arg1))
+		return NULL;
+	color( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void curveit short s */
+
+static PyObject *
+gl_curveit(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	if (!getishortarg(args, 1, 0, &arg1))
+		return NULL;
+	curveit( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void font short s */
+
+static PyObject *
+gl_font(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	if (!getishortarg(args, 1, 0, &arg1))
+		return NULL;
+	font( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void linewidth short s */
+
+static PyObject *
+gl_linewidth(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	if (!getishortarg(args, 1, 0, &arg1))
+		return NULL;
+	linewidth( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void setlinestyle short s */
+
+static PyObject *
+gl_setlinestyle(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	if (!getishortarg(args, 1, 0, &arg1))
+		return NULL;
+	setlinestyle( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void setmap short s */
+
+static PyObject *
+gl_setmap(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	if (!getishortarg(args, 1, 0, &arg1))
+		return NULL;
+	setmap( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void swapinterval short s */
+
+static PyObject *
+gl_swapinterval(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	if (!getishortarg(args, 1, 0, &arg1))
+		return NULL;
+	swapinterval( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void writemask short s */
+
+static PyObject *
+gl_writemask(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	if (!getishortarg(args, 1, 0, &arg1))
+		return NULL;
+	writemask( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void textwritemask short s */
+
+static PyObject *
+gl_textwritemask(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	if (!getishortarg(args, 1, 0, &arg1))
+		return NULL;
+	textwritemask( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void qdevice short s */
+
+static PyObject *
+gl_qdevice(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	if (!getishortarg(args, 1, 0, &arg1))
+		return NULL;
+	qdevice( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void unqdevice short s */
+
+static PyObject *
+gl_unqdevice(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	if (!getishortarg(args, 1, 0, &arg1))
+		return NULL;
+	unqdevice( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void curvebasis short s */
+
+static PyObject *
+gl_curvebasis(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	if (!getishortarg(args, 1, 0, &arg1))
+		return NULL;
+	curvebasis( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void curveprecision short s */
+
+static PyObject *
+gl_curveprecision(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	if (!getishortarg(args, 1, 0, &arg1))
+		return NULL;
+	curveprecision( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void loadname short s */
+
+static PyObject *
+gl_loadname(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	if (!getishortarg(args, 1, 0, &arg1))
+		return NULL;
+	loadname( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void passthrough short s */
+
+static PyObject *
+gl_passthrough(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	if (!getishortarg(args, 1, 0, &arg1))
+		return NULL;
+	passthrough( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void pushname short s */
+
+static PyObject *
+gl_pushname(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	if (!getishortarg(args, 1, 0, &arg1))
+		return NULL;
+	pushname( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void setmonitor short s */
+
+static PyObject *
+gl_setmonitor(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	if (!getishortarg(args, 1, 0, &arg1))
+		return NULL;
+	setmonitor( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void setshade short s */
+
+static PyObject *
+gl_setshade(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	if (!getishortarg(args, 1, 0, &arg1))
+		return NULL;
+	setshade( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void setpattern short s */
+
+static PyObject *
+gl_setpattern(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	if (!getishortarg(args, 1, 0, &arg1))
+		return NULL;
+	setpattern( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void pagewritemask short s */
+
+static PyObject *
+gl_pagewritemask(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	if (!getishortarg(args, 1, 0, &arg1))
+		return NULL;
+	pagewritemask( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void callobj long s */
+
+static PyObject *
+gl_callobj(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	callobj( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void delobj long s */
+
+static PyObject *
+gl_delobj(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	delobj( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void editobj long s */
+
+static PyObject *
+gl_editobj(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	editobj( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void makeobj long s */
+
+static PyObject *
+gl_makeobj(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	makeobj( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void maketag long s */
+
+static PyObject *
+gl_maketag(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	maketag( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void chunksize long s */
+
+static PyObject *
+gl_chunksize(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	chunksize( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void compactify long s */
+
+static PyObject *
+gl_compactify(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	compactify( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void deltag long s */
+
+static PyObject *
+gl_deltag(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	deltag( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void lsrepeat long s */
+
+static PyObject *
+gl_lsrepeat(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	lsrepeat( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void objinsert long s */
+
+static PyObject *
+gl_objinsert(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	objinsert( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void objreplace long s */
+
+static PyObject *
+gl_objreplace(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	objreplace( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void winclose long s */
+
+static PyObject *
+gl_winclose(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	winclose( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void blanktime long s */
+
+static PyObject *
+gl_blanktime(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	blanktime( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void freepup long s */
+
+static PyObject *
+gl_freepup(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	freepup( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void backbuffer long s */
+
+static PyObject *
+gl_backbuffer(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	backbuffer( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void frontbuffer long s */
+
+static PyObject *
+gl_frontbuffer(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	frontbuffer( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void lsbackup long s */
+
+static PyObject *
+gl_lsbackup(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	lsbackup( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void resetls long s */
+
+static PyObject *
+gl_resetls(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	resetls( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void lampon long s */
+
+static PyObject *
+gl_lampon(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	lampon( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void lampoff long s */
+
+static PyObject *
+gl_lampoff(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	lampoff( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void setbell long s */
+
+static PyObject *
+gl_setbell(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	setbell( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void blankscreen long s */
+
+static PyObject *
+gl_blankscreen(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	blankscreen( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void depthcue long s */
+
+static PyObject *
+gl_depthcue(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	depthcue( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void zbuffer long s */
+
+static PyObject *
+gl_zbuffer(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	zbuffer( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void backface long s */
+
+static PyObject *
+gl_backface(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	backface( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void cmov2i long s long s */
+
+static PyObject *
+gl_cmov2i(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	if (!getilongarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 2, 1, &arg2))
+		return NULL;
+	cmov2i( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void draw2i long s long s */
+
+static PyObject *
+gl_draw2i(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	if (!getilongarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 2, 1, &arg2))
+		return NULL;
+	draw2i( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void move2i long s long s */
+
+static PyObject *
+gl_move2i(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	if (!getilongarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 2, 1, &arg2))
+		return NULL;
+	move2i( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void pnt2i long s long s */
+
+static PyObject *
+gl_pnt2i(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	if (!getilongarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 2, 1, &arg2))
+		return NULL;
+	pnt2i( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void patchbasis long s long s */
+
+static PyObject *
+gl_patchbasis(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	if (!getilongarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 2, 1, &arg2))
+		return NULL;
+	patchbasis( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void patchprecision long s long s */
+
+static PyObject *
+gl_patchprecision(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	if (!getilongarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 2, 1, &arg2))
+		return NULL;
+	patchprecision( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void pdr2i long s long s */
+
+static PyObject *
+gl_pdr2i(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	if (!getilongarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 2, 1, &arg2))
+		return NULL;
+	pdr2i( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void pmv2i long s long s */
+
+static PyObject *
+gl_pmv2i(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	if (!getilongarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 2, 1, &arg2))
+		return NULL;
+	pmv2i( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void rpdr2i long s long s */
+
+static PyObject *
+gl_rpdr2i(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	if (!getilongarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 2, 1, &arg2))
+		return NULL;
+	rpdr2i( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void rpmv2i long s long s */
+
+static PyObject *
+gl_rpmv2i(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	if (!getilongarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 2, 1, &arg2))
+		return NULL;
+	rpmv2i( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void xfpt2i long s long s */
+
+static PyObject *
+gl_xfpt2i(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	if (!getilongarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 2, 1, &arg2))
+		return NULL;
+	xfpt2i( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void objdelete long s long s */
+
+static PyObject *
+gl_objdelete(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	if (!getilongarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 2, 1, &arg2))
+		return NULL;
+	objdelete( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void patchcurves long s long s */
+
+static PyObject *
+gl_patchcurves(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	if (!getilongarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 2, 1, &arg2))
+		return NULL;
+	patchcurves( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void minsize long s long s */
+
+static PyObject *
+gl_minsize(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	if (!getilongarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 2, 1, &arg2))
+		return NULL;
+	minsize( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void maxsize long s long s */
+
+static PyObject *
+gl_maxsize(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	if (!getilongarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 2, 1, &arg2))
+		return NULL;
+	maxsize( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void keepaspect long s long s */
+
+static PyObject *
+gl_keepaspect(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	if (!getilongarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 2, 1, &arg2))
+		return NULL;
+	keepaspect( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void prefsize long s long s */
+
+static PyObject *
+gl_prefsize(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	if (!getilongarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 2, 1, &arg2))
+		return NULL;
+	prefsize( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void stepunit long s long s */
+
+static PyObject *
+gl_stepunit(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	if (!getilongarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 2, 1, &arg2))
+		return NULL;
+	stepunit( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void fudge long s long s */
+
+static PyObject *
+gl_fudge(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	if (!getilongarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 2, 1, &arg2))
+		return NULL;
+	fudge( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void winmove long s long s */
+
+static PyObject *
+gl_winmove(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	if (!getilongarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 2, 1, &arg2))
+		return NULL;
+	winmove( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void attachcursor short s short s */
+
+static PyObject *
+gl_attachcursor(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	if (!getishortarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 2, 1, &arg2))
+		return NULL;
+	attachcursor( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void deflinestyle short s short s */
+
+static PyObject *
+gl_deflinestyle(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	if (!getishortarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 2, 1, &arg2))
+		return NULL;
+	deflinestyle( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void noise short s short s */
+
+static PyObject *
+gl_noise(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	if (!getishortarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 2, 1, &arg2))
+		return NULL;
+	noise( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void picksize short s short s */
+
+static PyObject *
+gl_picksize(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	if (!getishortarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 2, 1, &arg2))
+		return NULL;
+	picksize( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void qenter short s short s */
+
+static PyObject *
+gl_qenter(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	if (!getishortarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 2, 1, &arg2))
+		return NULL;
+	qenter( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void setdepth short s short s */
+
+static PyObject *
+gl_setdepth(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	if (!getishortarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 2, 1, &arg2))
+		return NULL;
+	setdepth( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void cmov2s short s short s */
+
+static PyObject *
+gl_cmov2s(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	if (!getishortarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 2, 1, &arg2))
+		return NULL;
+	cmov2s( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void draw2s short s short s */
+
+static PyObject *
+gl_draw2s(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	if (!getishortarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 2, 1, &arg2))
+		return NULL;
+	draw2s( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void move2s short s short s */
+
+static PyObject *
+gl_move2s(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	if (!getishortarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 2, 1, &arg2))
+		return NULL;
+	move2s( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void pdr2s short s short s */
+
+static PyObject *
+gl_pdr2s(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	if (!getishortarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 2, 1, &arg2))
+		return NULL;
+	pdr2s( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void pmv2s short s short s */
+
+static PyObject *
+gl_pmv2s(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	if (!getishortarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 2, 1, &arg2))
+		return NULL;
+	pmv2s( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void pnt2s short s short s */
+
+static PyObject *
+gl_pnt2s(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	if (!getishortarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 2, 1, &arg2))
+		return NULL;
+	pnt2s( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void rdr2s short s short s */
+
+static PyObject *
+gl_rdr2s(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	if (!getishortarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 2, 1, &arg2))
+		return NULL;
+	rdr2s( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void rmv2s short s short s */
+
+static PyObject *
+gl_rmv2s(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	if (!getishortarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 2, 1, &arg2))
+		return NULL;
+	rmv2s( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void rpdr2s short s short s */
+
+static PyObject *
+gl_rpdr2s(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	if (!getishortarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 2, 1, &arg2))
+		return NULL;
+	rpdr2s( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void rpmv2s short s short s */
+
+static PyObject *
+gl_rpmv2s(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	if (!getishortarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 2, 1, &arg2))
+		return NULL;
+	rpmv2s( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void xfpt2s short s short s */
+
+static PyObject *
+gl_xfpt2s(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	if (!getishortarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 2, 1, &arg2))
+		return NULL;
+	xfpt2s( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void cmov2 float s float s */
+
+static PyObject *
+gl_cmov2(PyObject *self, PyObject *args)
+{
+	float arg1 ;
+	float arg2 ;
+	if (!getifloatarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getifloatarg(args, 2, 1, &arg2))
+		return NULL;
+	cmov2( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void draw2 float s float s */
+
+static PyObject *
+gl_draw2(PyObject *self, PyObject *args)
+{
+	float arg1 ;
+	float arg2 ;
+	if (!getifloatarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getifloatarg(args, 2, 1, &arg2))
+		return NULL;
+	draw2( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void move2 float s float s */
+
+static PyObject *
+gl_move2(PyObject *self, PyObject *args)
+{
+	float arg1 ;
+	float arg2 ;
+	if (!getifloatarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getifloatarg(args, 2, 1, &arg2))
+		return NULL;
+	move2( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void pnt2 float s float s */
+
+static PyObject *
+gl_pnt2(PyObject *self, PyObject *args)
+{
+	float arg1 ;
+	float arg2 ;
+	if (!getifloatarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getifloatarg(args, 2, 1, &arg2))
+		return NULL;
+	pnt2( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void pdr2 float s float s */
+
+static PyObject *
+gl_pdr2(PyObject *self, PyObject *args)
+{
+	float arg1 ;
+	float arg2 ;
+	if (!getifloatarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getifloatarg(args, 2, 1, &arg2))
+		return NULL;
+	pdr2( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void pmv2 float s float s */
+
+static PyObject *
+gl_pmv2(PyObject *self, PyObject *args)
+{
+	float arg1 ;
+	float arg2 ;
+	if (!getifloatarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getifloatarg(args, 2, 1, &arg2))
+		return NULL;
+	pmv2( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void rdr2 float s float s */
+
+static PyObject *
+gl_rdr2(PyObject *self, PyObject *args)
+{
+	float arg1 ;
+	float arg2 ;
+	if (!getifloatarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getifloatarg(args, 2, 1, &arg2))
+		return NULL;
+	rdr2( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void rmv2 float s float s */
+
+static PyObject *
+gl_rmv2(PyObject *self, PyObject *args)
+{
+	float arg1 ;
+	float arg2 ;
+	if (!getifloatarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getifloatarg(args, 2, 1, &arg2))
+		return NULL;
+	rmv2( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void rpdr2 float s float s */
+
+static PyObject *
+gl_rpdr2(PyObject *self, PyObject *args)
+{
+	float arg1 ;
+	float arg2 ;
+	if (!getifloatarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getifloatarg(args, 2, 1, &arg2))
+		return NULL;
+	rpdr2( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void rpmv2 float s float s */
+
+static PyObject *
+gl_rpmv2(PyObject *self, PyObject *args)
+{
+	float arg1 ;
+	float arg2 ;
+	if (!getifloatarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getifloatarg(args, 2, 1, &arg2))
+		return NULL;
+	rpmv2( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void xfpt2 float s float s */
+
+static PyObject *
+gl_xfpt2(PyObject *self, PyObject *args)
+{
+	float arg1 ;
+	float arg2 ;
+	if (!getifloatarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getifloatarg(args, 2, 1, &arg2))
+		return NULL;
+	xfpt2( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void loadmatrix float s[4*4] */
+
+static PyObject *
+gl_loadmatrix(PyObject *self, PyObject *args)
+{
+	float arg1 [ 4 ] [ 4 ] ;
+	if (!getifloatarray(args, 1, 0, 4 * 4 , (float *) arg1))
+		return NULL;
+	loadmatrix( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void multmatrix float s[4*4] */
+
+static PyObject *
+gl_multmatrix(PyObject *self, PyObject *args)
+{
+	float arg1 [ 4 ] [ 4 ] ;
+	if (!getifloatarray(args, 1, 0, 4 * 4 , (float *) arg1))
+		return NULL;
+	multmatrix( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void crv float s[3*4] */
+
+static PyObject *
+gl_crv(PyObject *self, PyObject *args)
+{
+	float arg1 [ 4 ] [ 3 ] ;
+	if (!getifloatarray(args, 1, 0, 3 * 4 , (float *) arg1))
+		return NULL;
+	crv( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void rcrv float s[4*4] */
+
+static PyObject *
+gl_rcrv(PyObject *self, PyObject *args)
+{
+	float arg1 [ 4 ] [ 4 ] ;
+	if (!getifloatarray(args, 1, 0, 4 * 4 , (float *) arg1))
+		return NULL;
+	rcrv( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void addtopup long s char *s long s */
+
+static PyObject *
+gl_addtopup(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	string arg2 ;
+	long arg3 ;
+	if (!getilongarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getistringarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getilongarg(args, 3, 2, &arg3))
+		return NULL;
+	addtopup( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void charstr char *s */
+
+static PyObject *
+gl_charstr(PyObject *self, PyObject *args)
+{
+	string arg1 ;
+	if (!getistringarg(args, 1, 0, &arg1))
+		return NULL;
+	charstr( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void getport char *s */
+
+static PyObject *
+gl_getport(PyObject *self, PyObject *args)
+{
+	string arg1 ;
+	if (!getistringarg(args, 1, 0, &arg1))
+		return NULL;
+	getport( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* long strwidth char *s */
+
+static PyObject *
+gl_strwidth(PyObject *self, PyObject *args)
+{
+	long retval;
+	string arg1 ;
+	if (!getistringarg(args, 1, 0, &arg1))
+		return NULL;
+	retval = strwidth( arg1 );
+	return mknewlongobject(retval);
+}
+
+/* long winopen char *s */
+
+static PyObject *
+gl_winopen(PyObject *self, PyObject *args)
+{
+	long retval;
+	string arg1 ;
+	if (!getistringarg(args, 1, 0, &arg1))
+		return NULL;
+	retval = winopen( arg1 );
+	return mknewlongobject(retval);
+}
+
+/* void wintitle char *s */
+
+static PyObject *
+gl_wintitle(PyObject *self, PyObject *args)
+{
+	string arg1 ;
+	if (!getistringarg(args, 1, 0, &arg1))
+		return NULL;
+	wintitle( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void polf long s float s[3*arg1] */
+
+static PyObject *
+gl_polf(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	float (* arg2) [ 3 ] ;
+	if (!getilongarraysize(args, 1, 0, &arg1))
+		return NULL;
+	arg1 = arg1 / 3;
+	if ((arg2 = (float(*)[3]) PyMem_NEW(float , 3 * arg1 )) == NULL)
+		return PyErr_NoMemory();
+	if (!getifloatarray(args, 1, 0, 3 * arg1 , (float *) arg2))
+		return NULL;
+	polf( arg1 , arg2 );
+	PyMem_DEL(arg2);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void polf2 long s float s[2*arg1] */
+
+static PyObject *
+gl_polf2(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	float (* arg2) [ 2 ] ;
+	if (!getilongarraysize(args, 1, 0, &arg1))
+		return NULL;
+	arg1 = arg1 / 2;
+	if ((arg2 = (float(*)[2]) PyMem_NEW(float , 2 * arg1 )) == NULL)
+		return PyErr_NoMemory();
+	if (!getifloatarray(args, 1, 0, 2 * arg1 , (float *) arg2))
+		return NULL;
+	polf2( arg1 , arg2 );
+	PyMem_DEL(arg2);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void poly long s float s[3*arg1] */
+
+static PyObject *
+gl_poly(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	float (* arg2) [ 3 ] ;
+	if (!getilongarraysize(args, 1, 0, &arg1))
+		return NULL;
+	arg1 = arg1 / 3;
+	if ((arg2 = (float(*)[3]) PyMem_NEW(float , 3 * arg1 )) == NULL)
+		return PyErr_NoMemory();
+	if (!getifloatarray(args, 1, 0, 3 * arg1 , (float *) arg2))
+		return NULL;
+	poly( arg1 , arg2 );
+	PyMem_DEL(arg2);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void poly2 long s float s[2*arg1] */
+
+static PyObject *
+gl_poly2(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	float (* arg2) [ 2 ] ;
+	if (!getilongarraysize(args, 1, 0, &arg1))
+		return NULL;
+	arg1 = arg1 / 2;
+	if ((arg2 = (float(*)[2]) PyMem_NEW(float , 2 * arg1 )) == NULL)
+		return PyErr_NoMemory();
+	if (!getifloatarray(args, 1, 0, 2 * arg1 , (float *) arg2))
+		return NULL;
+	poly2( arg1 , arg2 );
+	PyMem_DEL(arg2);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void crvn long s float s[3*arg1] */
+
+static PyObject *
+gl_crvn(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	float (* arg2) [ 3 ] ;
+	if (!getilongarraysize(args, 1, 0, &arg1))
+		return NULL;
+	arg1 = arg1 / 3;
+	if ((arg2 = (float(*)[3]) PyMem_NEW(float , 3 * arg1 )) == NULL)
+		return PyErr_NoMemory();
+	if (!getifloatarray(args, 1, 0, 3 * arg1 , (float *) arg2))
+		return NULL;
+	crvn( arg1 , arg2 );
+	PyMem_DEL(arg2);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void rcrvn long s float s[4*arg1] */
+
+static PyObject *
+gl_rcrvn(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	float (* arg2) [ 4 ] ;
+	if (!getilongarraysize(args, 1, 0, &arg1))
+		return NULL;
+	arg1 = arg1 / 4;
+	if ((arg2 = (float(*)[4]) PyMem_NEW(float , 4 * arg1 )) == NULL)
+		return PyErr_NoMemory();
+	if (!getifloatarray(args, 1, 0, 4 * arg1 , (float *) arg2))
+		return NULL;
+	rcrvn( arg1 , arg2 );
+	PyMem_DEL(arg2);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void polf2i long s long s[2*arg1] */
+
+static PyObject *
+gl_polf2i(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long (* arg2) [ 2 ] ;
+	if (!getilongarraysize(args, 1, 0, &arg1))
+		return NULL;
+	arg1 = arg1 / 2;
+	if ((arg2 = (long(*)[2]) PyMem_NEW(long , 2 * arg1 )) == NULL)
+		return PyErr_NoMemory();
+	if (!getilongarray(args, 1, 0, 2 * arg1 , (long *) arg2))
+		return NULL;
+	polf2i( arg1 , arg2 );
+	PyMem_DEL(arg2);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void polfi long s long s[3*arg1] */
+
+static PyObject *
+gl_polfi(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long (* arg2) [ 3 ] ;
+	if (!getilongarraysize(args, 1, 0, &arg1))
+		return NULL;
+	arg1 = arg1 / 3;
+	if ((arg2 = (long(*)[3]) PyMem_NEW(long , 3 * arg1 )) == NULL)
+		return PyErr_NoMemory();
+	if (!getilongarray(args, 1, 0, 3 * arg1 , (long *) arg2))
+		return NULL;
+	polfi( arg1 , arg2 );
+	PyMem_DEL(arg2);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void poly2i long s long s[2*arg1] */
+
+static PyObject *
+gl_poly2i(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long (* arg2) [ 2 ] ;
+	if (!getilongarraysize(args, 1, 0, &arg1))
+		return NULL;
+	arg1 = arg1 / 2;
+	if ((arg2 = (long(*)[2]) PyMem_NEW(long , 2 * arg1 )) == NULL)
+		return PyErr_NoMemory();
+	if (!getilongarray(args, 1, 0, 2 * arg1 , (long *) arg2))
+		return NULL;
+	poly2i( arg1 , arg2 );
+	PyMem_DEL(arg2);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void polyi long s long s[3*arg1] */
+
+static PyObject *
+gl_polyi(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long (* arg2) [ 3 ] ;
+	if (!getilongarraysize(args, 1, 0, &arg1))
+		return NULL;
+	arg1 = arg1 / 3;
+	if ((arg2 = (long(*)[3]) PyMem_NEW(long , 3 * arg1 )) == NULL)
+		return PyErr_NoMemory();
+	if (!getilongarray(args, 1, 0, 3 * arg1 , (long *) arg2))
+		return NULL;
+	polyi( arg1 , arg2 );
+	PyMem_DEL(arg2);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void polf2s long s short s[2*arg1] */
+
+static PyObject *
+gl_polf2s(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	short (* arg2) [ 2 ] ;
+	if (!getilongarraysize(args, 1, 0, &arg1))
+		return NULL;
+	arg1 = arg1 / 2;
+	if ((arg2 = (short(*)[2]) PyMem_NEW(short , 2 * arg1 )) == NULL)
+		return PyErr_NoMemory();
+	if (!getishortarray(args, 1, 0, 2 * arg1 , (short *) arg2))
+		return NULL;
+	polf2s( arg1 , arg2 );
+	PyMem_DEL(arg2);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void polfs long s short s[3*arg1] */
+
+static PyObject *
+gl_polfs(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	short (* arg2) [ 3 ] ;
+	if (!getilongarraysize(args, 1, 0, &arg1))
+		return NULL;
+	arg1 = arg1 / 3;
+	if ((arg2 = (short(*)[3]) PyMem_NEW(short , 3 * arg1 )) == NULL)
+		return PyErr_NoMemory();
+	if (!getishortarray(args, 1, 0, 3 * arg1 , (short *) arg2))
+		return NULL;
+	polfs( arg1 , arg2 );
+	PyMem_DEL(arg2);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void polys long s short s[3*arg1] */
+
+static PyObject *
+gl_polys(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	short (* arg2) [ 3 ] ;
+	if (!getilongarraysize(args, 1, 0, &arg1))
+		return NULL;
+	arg1 = arg1 / 3;
+	if ((arg2 = (short(*)[3]) PyMem_NEW(short , 3 * arg1 )) == NULL)
+		return PyErr_NoMemory();
+	if (!getishortarray(args, 1, 0, 3 * arg1 , (short *) arg2))
+		return NULL;
+	polys( arg1 , arg2 );
+	PyMem_DEL(arg2);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void poly2s long s short s[2*arg1] */
+
+static PyObject *
+gl_poly2s(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	short (* arg2) [ 2 ] ;
+	if (!getilongarraysize(args, 1, 0, &arg1))
+		return NULL;
+	arg1 = arg1 / 2;
+	if ((arg2 = (short(*)[2]) PyMem_NEW(short , 2 * arg1 )) == NULL)
+		return PyErr_NoMemory();
+	if (!getishortarray(args, 1, 0, 2 * arg1 , (short *) arg2))
+		return NULL;
+	poly2s( arg1 , arg2 );
+	PyMem_DEL(arg2);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void defcursor short s u_short s[128] */
+
+static PyObject *
+gl_defcursor(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	unsigned short arg2 [ 128 ] ;
+	if (!getishortarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getishortarray(args, 2, 1, 128 , (short *) arg2))
+		return NULL;
+	defcursor( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void writepixels short s u_short s[arg1] */
+
+static PyObject *
+gl_writepixels(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	unsigned short * arg2 ;
+	if (!getishortarraysize(args, 1, 0, &arg1))
+		return NULL;
+	if ((arg2 = PyMem_NEW(unsigned short , arg1 )) == NULL)
+		return PyErr_NoMemory();
+	if (!getishortarray(args, 1, 0, arg1 , (short *) arg2))
+		return NULL;
+	writepixels( arg1 , arg2 );
+	PyMem_DEL(arg2);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void defbasis long s float s[4*4] */
+
+static PyObject *
+gl_defbasis(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	float arg2 [ 4 ] [ 4 ] ;
+	if (!getilongarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getifloatarray(args, 2, 1, 4 * 4 , (float *) arg2))
+		return NULL;
+	defbasis( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void gewrite short s short s[arg1] */
+
+static PyObject *
+gl_gewrite(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short * arg2 ;
+	if (!getishortarraysize(args, 1, 0, &arg1))
+		return NULL;
+	if ((arg2 = PyMem_NEW(short , arg1 )) == NULL)
+		return PyErr_NoMemory();
+	if (!getishortarray(args, 1, 0, arg1 , arg2))
+		return NULL;
+	gewrite( arg1 , arg2 );
+	PyMem_DEL(arg2);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void rotate short s char s */
+
+static PyObject *
+gl_rotate(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	char arg2 ;
+	if (!getishortarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getichararg(args, 2, 1, &arg2))
+		return NULL;
+	rotate( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void rot float s char s */
+
+static PyObject *
+gl_rot(PyObject *self, PyObject *args)
+{
+	float arg1 ;
+	char arg2 ;
+	if (!getifloatarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getichararg(args, 2, 1, &arg2))
+		return NULL;
+	rot( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void circfi long s long s long s */
+
+static PyObject *
+gl_circfi(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	long arg3 ;
+	if (!getilongarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getilongarg(args, 3, 2, &arg3))
+		return NULL;
+	circfi( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void circi long s long s long s */
+
+static PyObject *
+gl_circi(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	long arg3 ;
+	if (!getilongarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getilongarg(args, 3, 2, &arg3))
+		return NULL;
+	circi( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void cmovi long s long s long s */
+
+static PyObject *
+gl_cmovi(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	long arg3 ;
+	if (!getilongarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getilongarg(args, 3, 2, &arg3))
+		return NULL;
+	cmovi( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void drawi long s long s long s */
+
+static PyObject *
+gl_drawi(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	long arg3 ;
+	if (!getilongarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getilongarg(args, 3, 2, &arg3))
+		return NULL;
+	drawi( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void movei long s long s long s */
+
+static PyObject *
+gl_movei(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	long arg3 ;
+	if (!getilongarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getilongarg(args, 3, 2, &arg3))
+		return NULL;
+	movei( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void pnti long s long s long s */
+
+static PyObject *
+gl_pnti(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	long arg3 ;
+	if (!getilongarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getilongarg(args, 3, 2, &arg3))
+		return NULL;
+	pnti( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void newtag long s long s long s */
+
+static PyObject *
+gl_newtag(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	long arg3 ;
+	if (!getilongarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getilongarg(args, 3, 2, &arg3))
+		return NULL;
+	newtag( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void pdri long s long s long s */
+
+static PyObject *
+gl_pdri(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	long arg3 ;
+	if (!getilongarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getilongarg(args, 3, 2, &arg3))
+		return NULL;
+	pdri( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void pmvi long s long s long s */
+
+static PyObject *
+gl_pmvi(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	long arg3 ;
+	if (!getilongarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getilongarg(args, 3, 2, &arg3))
+		return NULL;
+	pmvi( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void rdri long s long s long s */
+
+static PyObject *
+gl_rdri(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	long arg3 ;
+	if (!getilongarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getilongarg(args, 3, 2, &arg3))
+		return NULL;
+	rdri( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void rmvi long s long s long s */
+
+static PyObject *
+gl_rmvi(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	long arg3 ;
+	if (!getilongarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getilongarg(args, 3, 2, &arg3))
+		return NULL;
+	rmvi( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void rpdri long s long s long s */
+
+static PyObject *
+gl_rpdri(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	long arg3 ;
+	if (!getilongarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getilongarg(args, 3, 2, &arg3))
+		return NULL;
+	rpdri( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void rpmvi long s long s long s */
+
+static PyObject *
+gl_rpmvi(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	long arg3 ;
+	if (!getilongarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getilongarg(args, 3, 2, &arg3))
+		return NULL;
+	rpmvi( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void xfpti long s long s long s */
+
+static PyObject *
+gl_xfpti(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	long arg3 ;
+	if (!getilongarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getilongarg(args, 3, 2, &arg3))
+		return NULL;
+	xfpti( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void circ float s float s float s */
+
+static PyObject *
+gl_circ(PyObject *self, PyObject *args)
+{
+	float arg1 ;
+	float arg2 ;
+	float arg3 ;
+	if (!getifloatarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getifloatarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getifloatarg(args, 3, 2, &arg3))
+		return NULL;
+	circ( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void circf float s float s float s */
+
+static PyObject *
+gl_circf(PyObject *self, PyObject *args)
+{
+	float arg1 ;
+	float arg2 ;
+	float arg3 ;
+	if (!getifloatarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getifloatarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getifloatarg(args, 3, 2, &arg3))
+		return NULL;
+	circf( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void cmov float s float s float s */
+
+static PyObject *
+gl_cmov(PyObject *self, PyObject *args)
+{
+	float arg1 ;
+	float arg2 ;
+	float arg3 ;
+	if (!getifloatarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getifloatarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getifloatarg(args, 3, 2, &arg3))
+		return NULL;
+	cmov( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void draw float s float s float s */
+
+static PyObject *
+gl_draw(PyObject *self, PyObject *args)
+{
+	float arg1 ;
+	float arg2 ;
+	float arg3 ;
+	if (!getifloatarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getifloatarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getifloatarg(args, 3, 2, &arg3))
+		return NULL;
+	draw( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void move float s float s float s */
+
+static PyObject *
+gl_move(PyObject *self, PyObject *args)
+{
+	float arg1 ;
+	float arg2 ;
+	float arg3 ;
+	if (!getifloatarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getifloatarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getifloatarg(args, 3, 2, &arg3))
+		return NULL;
+	move( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void pnt float s float s float s */
+
+static PyObject *
+gl_pnt(PyObject *self, PyObject *args)
+{
+	float arg1 ;
+	float arg2 ;
+	float arg3 ;
+	if (!getifloatarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getifloatarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getifloatarg(args, 3, 2, &arg3))
+		return NULL;
+	pnt( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void scale float s float s float s */
+
+static PyObject *
+gl_scale(PyObject *self, PyObject *args)
+{
+	float arg1 ;
+	float arg2 ;
+	float arg3 ;
+	if (!getifloatarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getifloatarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getifloatarg(args, 3, 2, &arg3))
+		return NULL;
+	scale( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void translate float s float s float s */
+
+static PyObject *
+gl_translate(PyObject *self, PyObject *args)
+{
+	float arg1 ;
+	float arg2 ;
+	float arg3 ;
+	if (!getifloatarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getifloatarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getifloatarg(args, 3, 2, &arg3))
+		return NULL;
+	translate( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void pdr float s float s float s */
+
+static PyObject *
+gl_pdr(PyObject *self, PyObject *args)
+{
+	float arg1 ;
+	float arg2 ;
+	float arg3 ;
+	if (!getifloatarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getifloatarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getifloatarg(args, 3, 2, &arg3))
+		return NULL;
+	pdr( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void pmv float s float s float s */
+
+static PyObject *
+gl_pmv(PyObject *self, PyObject *args)
+{
+	float arg1 ;
+	float arg2 ;
+	float arg3 ;
+	if (!getifloatarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getifloatarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getifloatarg(args, 3, 2, &arg3))
+		return NULL;
+	pmv( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void rdr float s float s float s */
+
+static PyObject *
+gl_rdr(PyObject *self, PyObject *args)
+{
+	float arg1 ;
+	float arg2 ;
+	float arg3 ;
+	if (!getifloatarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getifloatarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getifloatarg(args, 3, 2, &arg3))
+		return NULL;
+	rdr( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void rmv float s float s float s */
+
+static PyObject *
+gl_rmv(PyObject *self, PyObject *args)
+{
+	float arg1 ;
+	float arg2 ;
+	float arg3 ;
+	if (!getifloatarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getifloatarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getifloatarg(args, 3, 2, &arg3))
+		return NULL;
+	rmv( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void rpdr float s float s float s */
+
+static PyObject *
+gl_rpdr(PyObject *self, PyObject *args)
+{
+	float arg1 ;
+	float arg2 ;
+	float arg3 ;
+	if (!getifloatarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getifloatarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getifloatarg(args, 3, 2, &arg3))
+		return NULL;
+	rpdr( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void rpmv float s float s float s */
+
+static PyObject *
+gl_rpmv(PyObject *self, PyObject *args)
+{
+	float arg1 ;
+	float arg2 ;
+	float arg3 ;
+	if (!getifloatarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getifloatarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getifloatarg(args, 3, 2, &arg3))
+		return NULL;
+	rpmv( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void xfpt float s float s float s */
+
+static PyObject *
+gl_xfpt(PyObject *self, PyObject *args)
+{
+	float arg1 ;
+	float arg2 ;
+	float arg3 ;
+	if (!getifloatarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getifloatarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getifloatarg(args, 3, 2, &arg3))
+		return NULL;
+	xfpt( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void RGBcolor short s short s short s */
+
+static PyObject *
+gl_RGBcolor(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	short arg3 ;
+	if (!getishortarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getishortarg(args, 3, 2, &arg3))
+		return NULL;
+	RGBcolor( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void RGBwritemask short s short s short s */
+
+static PyObject *
+gl_RGBwritemask(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	short arg3 ;
+	if (!getishortarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getishortarg(args, 3, 2, &arg3))
+		return NULL;
+	RGBwritemask( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void setcursor short s short s short s */
+
+static PyObject *
+gl_setcursor(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	short arg3 ;
+	if (!getishortarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getishortarg(args, 3, 2, &arg3))
+		return NULL;
+	setcursor( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void tie short s short s short s */
+
+static PyObject *
+gl_tie(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	short arg3 ;
+	if (!getishortarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getishortarg(args, 3, 2, &arg3))
+		return NULL;
+	tie( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void circfs short s short s short s */
+
+static PyObject *
+gl_circfs(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	short arg3 ;
+	if (!getishortarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getishortarg(args, 3, 2, &arg3))
+		return NULL;
+	circfs( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void circs short s short s short s */
+
+static PyObject *
+gl_circs(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	short arg3 ;
+	if (!getishortarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getishortarg(args, 3, 2, &arg3))
+		return NULL;
+	circs( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void cmovs short s short s short s */
+
+static PyObject *
+gl_cmovs(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	short arg3 ;
+	if (!getishortarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getishortarg(args, 3, 2, &arg3))
+		return NULL;
+	cmovs( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void draws short s short s short s */
+
+static PyObject *
+gl_draws(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	short arg3 ;
+	if (!getishortarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getishortarg(args, 3, 2, &arg3))
+		return NULL;
+	draws( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void moves short s short s short s */
+
+static PyObject *
+gl_moves(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	short arg3 ;
+	if (!getishortarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getishortarg(args, 3, 2, &arg3))
+		return NULL;
+	moves( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void pdrs short s short s short s */
+
+static PyObject *
+gl_pdrs(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	short arg3 ;
+	if (!getishortarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getishortarg(args, 3, 2, &arg3))
+		return NULL;
+	pdrs( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void pmvs short s short s short s */
+
+static PyObject *
+gl_pmvs(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	short arg3 ;
+	if (!getishortarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getishortarg(args, 3, 2, &arg3))
+		return NULL;
+	pmvs( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void pnts short s short s short s */
+
+static PyObject *
+gl_pnts(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	short arg3 ;
+	if (!getishortarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getishortarg(args, 3, 2, &arg3))
+		return NULL;
+	pnts( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void rdrs short s short s short s */
+
+static PyObject *
+gl_rdrs(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	short arg3 ;
+	if (!getishortarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getishortarg(args, 3, 2, &arg3))
+		return NULL;
+	rdrs( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void rmvs short s short s short s */
+
+static PyObject *
+gl_rmvs(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	short arg3 ;
+	if (!getishortarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getishortarg(args, 3, 2, &arg3))
+		return NULL;
+	rmvs( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void rpdrs short s short s short s */
+
+static PyObject *
+gl_rpdrs(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	short arg3 ;
+	if (!getishortarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getishortarg(args, 3, 2, &arg3))
+		return NULL;
+	rpdrs( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void rpmvs short s short s short s */
+
+static PyObject *
+gl_rpmvs(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	short arg3 ;
+	if (!getishortarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getishortarg(args, 3, 2, &arg3))
+		return NULL;
+	rpmvs( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void xfpts short s short s short s */
+
+static PyObject *
+gl_xfpts(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	short arg3 ;
+	if (!getishortarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getishortarg(args, 3, 2, &arg3))
+		return NULL;
+	xfpts( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void curorigin short s short s short s */
+
+static PyObject *
+gl_curorigin(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	short arg3 ;
+	if (!getishortarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getishortarg(args, 3, 2, &arg3))
+		return NULL;
+	curorigin( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void cyclemap short s short s short s */
+
+static PyObject *
+gl_cyclemap(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	short arg3 ;
+	if (!getishortarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getishortarg(args, 3, 2, &arg3))
+		return NULL;
+	cyclemap( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void patch float s[4*4] float s[4*4] float s[4*4] */
+
+static PyObject *
+gl_patch(PyObject *self, PyObject *args)
+{
+	float arg1 [ 4 ] [ 4 ] ;
+	float arg2 [ 4 ] [ 4 ] ;
+	float arg3 [ 4 ] [ 4 ] ;
+	if (!getifloatarray(args, 3, 0, 4 * 4 , (float *) arg1))
+		return NULL;
+	if (!getifloatarray(args, 3, 1, 4 * 4 , (float *) arg2))
+		return NULL;
+	if (!getifloatarray(args, 3, 2, 4 * 4 , (float *) arg3))
+		return NULL;
+	patch( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void splf long s float s[3*arg1] u_short s[arg1] */
+
+static PyObject *
+gl_splf(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	float (* arg2) [ 3 ] ;
+	unsigned short * arg3 ;
+	if (!getilongarraysize(args, 2, 0, &arg1))
+		return NULL;
+	arg1 = arg1 / 3;
+	if ((arg2 = (float(*)[3]) PyMem_NEW(float , 3 * arg1 )) == NULL)
+		return PyErr_NoMemory();
+	if (!getifloatarray(args, 2, 0, 3 * arg1 , (float *) arg2))
+		return NULL;
+	if ((arg3 = PyMem_NEW(unsigned short , arg1 )) == NULL)
+		return PyErr_NoMemory();
+	if (!getishortarray(args, 2, 1, arg1 , (short *) arg3))
+		return NULL;
+	splf( arg1 , arg2 , arg3 );
+	PyMem_DEL(arg2);
+	PyMem_DEL(arg3);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void splf2 long s float s[2*arg1] u_short s[arg1] */
+
+static PyObject *
+gl_splf2(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	float (* arg2) [ 2 ] ;
+	unsigned short * arg3 ;
+	if (!getilongarraysize(args, 2, 0, &arg1))
+		return NULL;
+	arg1 = arg1 / 2;
+	if ((arg2 = (float(*)[2]) PyMem_NEW(float , 2 * arg1 )) == NULL)
+		return PyErr_NoMemory();
+	if (!getifloatarray(args, 2, 0, 2 * arg1 , (float *) arg2))
+		return NULL;
+	if ((arg3 = PyMem_NEW(unsigned short , arg1 )) == NULL)
+		return PyErr_NoMemory();
+	if (!getishortarray(args, 2, 1, arg1 , (short *) arg3))
+		return NULL;
+	splf2( arg1 , arg2 , arg3 );
+	PyMem_DEL(arg2);
+	PyMem_DEL(arg3);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void splfi long s long s[3*arg1] u_short s[arg1] */
+
+static PyObject *
+gl_splfi(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long (* arg2) [ 3 ] ;
+	unsigned short * arg3 ;
+	if (!getilongarraysize(args, 2, 0, &arg1))
+		return NULL;
+	arg1 = arg1 / 3;
+	if ((arg2 = (long(*)[3]) PyMem_NEW(long , 3 * arg1 )) == NULL)
+		return PyErr_NoMemory();
+	if (!getilongarray(args, 2, 0, 3 * arg1 , (long *) arg2))
+		return NULL;
+	if ((arg3 = PyMem_NEW(unsigned short , arg1 )) == NULL)
+		return PyErr_NoMemory();
+	if (!getishortarray(args, 2, 1, arg1 , (short *) arg3))
+		return NULL;
+	splfi( arg1 , arg2 , arg3 );
+	PyMem_DEL(arg2);
+	PyMem_DEL(arg3);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void splf2i long s long s[2*arg1] u_short s[arg1] */
+
+static PyObject *
+gl_splf2i(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long (* arg2) [ 2 ] ;
+	unsigned short * arg3 ;
+	if (!getilongarraysize(args, 2, 0, &arg1))
+		return NULL;
+	arg1 = arg1 / 2;
+	if ((arg2 = (long(*)[2]) PyMem_NEW(long , 2 * arg1 )) == NULL)
+		return PyErr_NoMemory();
+	if (!getilongarray(args, 2, 0, 2 * arg1 , (long *) arg2))
+		return NULL;
+	if ((arg3 = PyMem_NEW(unsigned short , arg1 )) == NULL)
+		return PyErr_NoMemory();
+	if (!getishortarray(args, 2, 1, arg1 , (short *) arg3))
+		return NULL;
+	splf2i( arg1 , arg2 , arg3 );
+	PyMem_DEL(arg2);
+	PyMem_DEL(arg3);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void splfs long s short s[3*arg1] u_short s[arg1] */
+
+static PyObject *
+gl_splfs(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	short (* arg2) [ 3 ] ;
+	unsigned short * arg3 ;
+	if (!getilongarraysize(args, 2, 0, &arg1))
+		return NULL;
+	arg1 = arg1 / 3;
+	if ((arg2 = (short(*)[3]) PyMem_NEW(short , 3 * arg1 )) == NULL)
+		return PyErr_NoMemory();
+	if (!getishortarray(args, 2, 0, 3 * arg1 , (short *) arg2))
+		return NULL;
+	if ((arg3 = PyMem_NEW(unsigned short , arg1 )) == NULL)
+		return PyErr_NoMemory();
+	if (!getishortarray(args, 2, 1, arg1 , (short *) arg3))
+		return NULL;
+	splfs( arg1 , arg2 , arg3 );
+	PyMem_DEL(arg2);
+	PyMem_DEL(arg3);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void splf2s long s short s[2*arg1] u_short s[arg1] */
+
+static PyObject *
+gl_splf2s(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	short (* arg2) [ 2 ] ;
+	unsigned short * arg3 ;
+	if (!getilongarraysize(args, 2, 0, &arg1))
+		return NULL;
+	arg1 = arg1 / 2;
+	if ((arg2 = (short(*)[2]) PyMem_NEW(short , 2 * arg1 )) == NULL)
+		return PyErr_NoMemory();
+	if (!getishortarray(args, 2, 0, 2 * arg1 , (short *) arg2))
+		return NULL;
+	if ((arg3 = PyMem_NEW(unsigned short , arg1 )) == NULL)
+		return PyErr_NoMemory();
+	if (!getishortarray(args, 2, 1, arg1 , (short *) arg3))
+		return NULL;
+	splf2s( arg1 , arg2 , arg3 );
+	PyMem_DEL(arg2);
+	PyMem_DEL(arg3);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void rpatch float s[4*4] float s[4*4] float s[4*4] float s[4*4] */
+
+static PyObject *
+gl_rpatch(PyObject *self, PyObject *args)
+{
+	float arg1 [ 4 ] [ 4 ] ;
+	float arg2 [ 4 ] [ 4 ] ;
+	float arg3 [ 4 ] [ 4 ] ;
+	float arg4 [ 4 ] [ 4 ] ;
+	if (!getifloatarray(args, 4, 0, 4 * 4 , (float *) arg1))
+		return NULL;
+	if (!getifloatarray(args, 4, 1, 4 * 4 , (float *) arg2))
+		return NULL;
+	if (!getifloatarray(args, 4, 2, 4 * 4 , (float *) arg3))
+		return NULL;
+	if (!getifloatarray(args, 4, 3, 4 * 4 , (float *) arg4))
+		return NULL;
+	rpatch( arg1 , arg2 , arg3 , arg4 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void ortho2 float s float s float s float s */
+
+static PyObject *
+gl_ortho2(PyObject *self, PyObject *args)
+{
+	float arg1 ;
+	float arg2 ;
+	float arg3 ;
+	float arg4 ;
+	if (!getifloatarg(args, 4, 0, &arg1))
+		return NULL;
+	if (!getifloatarg(args, 4, 1, &arg2))
+		return NULL;
+	if (!getifloatarg(args, 4, 2, &arg3))
+		return NULL;
+	if (!getifloatarg(args, 4, 3, &arg4))
+		return NULL;
+	ortho2( arg1 , arg2 , arg3 , arg4 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void rect float s float s float s float s */
+
+static PyObject *
+gl_rect(PyObject *self, PyObject *args)
+{
+	float arg1 ;
+	float arg2 ;
+	float arg3 ;
+	float arg4 ;
+	if (!getifloatarg(args, 4, 0, &arg1))
+		return NULL;
+	if (!getifloatarg(args, 4, 1, &arg2))
+		return NULL;
+	if (!getifloatarg(args, 4, 2, &arg3))
+		return NULL;
+	if (!getifloatarg(args, 4, 3, &arg4))
+		return NULL;
+	rect( arg1 , arg2 , arg3 , arg4 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void rectf float s float s float s float s */
+
+static PyObject *
+gl_rectf(PyObject *self, PyObject *args)
+{
+	float arg1 ;
+	float arg2 ;
+	float arg3 ;
+	float arg4 ;
+	if (!getifloatarg(args, 4, 0, &arg1))
+		return NULL;
+	if (!getifloatarg(args, 4, 1, &arg2))
+		return NULL;
+	if (!getifloatarg(args, 4, 2, &arg3))
+		return NULL;
+	if (!getifloatarg(args, 4, 3, &arg4))
+		return NULL;
+	rectf( arg1 , arg2 , arg3 , arg4 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void xfpt4 float s float s float s float s */
+
+static PyObject *
+gl_xfpt4(PyObject *self, PyObject *args)
+{
+	float arg1 ;
+	float arg2 ;
+	float arg3 ;
+	float arg4 ;
+	if (!getifloatarg(args, 4, 0, &arg1))
+		return NULL;
+	if (!getifloatarg(args, 4, 1, &arg2))
+		return NULL;
+	if (!getifloatarg(args, 4, 2, &arg3))
+		return NULL;
+	if (!getifloatarg(args, 4, 3, &arg4))
+		return NULL;
+	xfpt4( arg1 , arg2 , arg3 , arg4 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void textport short s short s short s short s */
+
+static PyObject *
+gl_textport(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	short arg3 ;
+	short arg4 ;
+	if (!getishortarg(args, 4, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 4, 1, &arg2))
+		return NULL;
+	if (!getishortarg(args, 4, 2, &arg3))
+		return NULL;
+	if (!getishortarg(args, 4, 3, &arg4))
+		return NULL;
+	textport( arg1 , arg2 , arg3 , arg4 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void mapcolor short s short s short s short s */
+
+static PyObject *
+gl_mapcolor(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	short arg3 ;
+	short arg4 ;
+	if (!getishortarg(args, 4, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 4, 1, &arg2))
+		return NULL;
+	if (!getishortarg(args, 4, 2, &arg3))
+		return NULL;
+	if (!getishortarg(args, 4, 3, &arg4))
+		return NULL;
+	mapcolor( arg1 , arg2 , arg3 , arg4 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void scrmask short s short s short s short s */
+
+static PyObject *
+gl_scrmask(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	short arg3 ;
+	short arg4 ;
+	if (!getishortarg(args, 4, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 4, 1, &arg2))
+		return NULL;
+	if (!getishortarg(args, 4, 2, &arg3))
+		return NULL;
+	if (!getishortarg(args, 4, 3, &arg4))
+		return NULL;
+	scrmask( arg1 , arg2 , arg3 , arg4 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void setvaluator short s short s short s short s */
+
+static PyObject *
+gl_setvaluator(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	short arg3 ;
+	short arg4 ;
+	if (!getishortarg(args, 4, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 4, 1, &arg2))
+		return NULL;
+	if (!getishortarg(args, 4, 2, &arg3))
+		return NULL;
+	if (!getishortarg(args, 4, 3, &arg4))
+		return NULL;
+	setvaluator( arg1 , arg2 , arg3 , arg4 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void viewport short s short s short s short s */
+
+static PyObject *
+gl_viewport(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	short arg3 ;
+	short arg4 ;
+	if (!getishortarg(args, 4, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 4, 1, &arg2))
+		return NULL;
+	if (!getishortarg(args, 4, 2, &arg3))
+		return NULL;
+	if (!getishortarg(args, 4, 3, &arg4))
+		return NULL;
+	viewport( arg1 , arg2 , arg3 , arg4 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void shaderange short s short s short s short s */
+
+static PyObject *
+gl_shaderange(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	short arg3 ;
+	short arg4 ;
+	if (!getishortarg(args, 4, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 4, 1, &arg2))
+		return NULL;
+	if (!getishortarg(args, 4, 2, &arg3))
+		return NULL;
+	if (!getishortarg(args, 4, 3, &arg4))
+		return NULL;
+	shaderange( arg1 , arg2 , arg3 , arg4 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void xfpt4s short s short s short s short s */
+
+static PyObject *
+gl_xfpt4s(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	short arg3 ;
+	short arg4 ;
+	if (!getishortarg(args, 4, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 4, 1, &arg2))
+		return NULL;
+	if (!getishortarg(args, 4, 2, &arg3))
+		return NULL;
+	if (!getishortarg(args, 4, 3, &arg4))
+		return NULL;
+	xfpt4s( arg1 , arg2 , arg3 , arg4 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void rectfi long s long s long s long s */
+
+static PyObject *
+gl_rectfi(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	long arg3 ;
+	long arg4 ;
+	if (!getilongarg(args, 4, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 4, 1, &arg2))
+		return NULL;
+	if (!getilongarg(args, 4, 2, &arg3))
+		return NULL;
+	if (!getilongarg(args, 4, 3, &arg4))
+		return NULL;
+	rectfi( arg1 , arg2 , arg3 , arg4 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void recti long s long s long s long s */
+
+static PyObject *
+gl_recti(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	long arg3 ;
+	long arg4 ;
+	if (!getilongarg(args, 4, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 4, 1, &arg2))
+		return NULL;
+	if (!getilongarg(args, 4, 2, &arg3))
+		return NULL;
+	if (!getilongarg(args, 4, 3, &arg4))
+		return NULL;
+	recti( arg1 , arg2 , arg3 , arg4 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void xfpt4i long s long s long s long s */
+
+static PyObject *
+gl_xfpt4i(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	long arg3 ;
+	long arg4 ;
+	if (!getilongarg(args, 4, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 4, 1, &arg2))
+		return NULL;
+	if (!getilongarg(args, 4, 2, &arg3))
+		return NULL;
+	if (!getilongarg(args, 4, 3, &arg4))
+		return NULL;
+	xfpt4i( arg1 , arg2 , arg3 , arg4 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void prefposition long s long s long s long s */
+
+static PyObject *
+gl_prefposition(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	long arg3 ;
+	long arg4 ;
+	if (!getilongarg(args, 4, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 4, 1, &arg2))
+		return NULL;
+	if (!getilongarg(args, 4, 2, &arg3))
+		return NULL;
+	if (!getilongarg(args, 4, 3, &arg4))
+		return NULL;
+	prefposition( arg1 , arg2 , arg3 , arg4 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void arc float s float s float s short s short s */
+
+static PyObject *
+gl_arc(PyObject *self, PyObject *args)
+{
+	float arg1 ;
+	float arg2 ;
+	float arg3 ;
+	short arg4 ;
+	short arg5 ;
+	if (!getifloatarg(args, 5, 0, &arg1))
+		return NULL;
+	if (!getifloatarg(args, 5, 1, &arg2))
+		return NULL;
+	if (!getifloatarg(args, 5, 2, &arg3))
+		return NULL;
+	if (!getishortarg(args, 5, 3, &arg4))
+		return NULL;
+	if (!getishortarg(args, 5, 4, &arg5))
+		return NULL;
+	arc( arg1 , arg2 , arg3 , arg4 , arg5 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void arcf float s float s float s short s short s */
+
+static PyObject *
+gl_arcf(PyObject *self, PyObject *args)
+{
+	float arg1 ;
+	float arg2 ;
+	float arg3 ;
+	short arg4 ;
+	short arg5 ;
+	if (!getifloatarg(args, 5, 0, &arg1))
+		return NULL;
+	if (!getifloatarg(args, 5, 1, &arg2))
+		return NULL;
+	if (!getifloatarg(args, 5, 2, &arg3))
+		return NULL;
+	if (!getishortarg(args, 5, 3, &arg4))
+		return NULL;
+	if (!getishortarg(args, 5, 4, &arg5))
+		return NULL;
+	arcf( arg1 , arg2 , arg3 , arg4 , arg5 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void arcfi long s long s long s short s short s */
+
+static PyObject *
+gl_arcfi(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	long arg3 ;
+	short arg4 ;
+	short arg5 ;
+	if (!getilongarg(args, 5, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 5, 1, &arg2))
+		return NULL;
+	if (!getilongarg(args, 5, 2, &arg3))
+		return NULL;
+	if (!getishortarg(args, 5, 3, &arg4))
+		return NULL;
+	if (!getishortarg(args, 5, 4, &arg5))
+		return NULL;
+	arcfi( arg1 , arg2 , arg3 , arg4 , arg5 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void arci long s long s long s short s short s */
+
+static PyObject *
+gl_arci(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	long arg3 ;
+	short arg4 ;
+	short arg5 ;
+	if (!getilongarg(args, 5, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 5, 1, &arg2))
+		return NULL;
+	if (!getilongarg(args, 5, 2, &arg3))
+		return NULL;
+	if (!getishortarg(args, 5, 3, &arg4))
+		return NULL;
+	if (!getishortarg(args, 5, 4, &arg5))
+		return NULL;
+	arci( arg1 , arg2 , arg3 , arg4 , arg5 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void bbox2 short s short s float s float s float s float s */
+
+static PyObject *
+gl_bbox2(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	float arg3 ;
+	float arg4 ;
+	float arg5 ;
+	float arg6 ;
+	if (!getishortarg(args, 6, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 6, 1, &arg2))
+		return NULL;
+	if (!getifloatarg(args, 6, 2, &arg3))
+		return NULL;
+	if (!getifloatarg(args, 6, 3, &arg4))
+		return NULL;
+	if (!getifloatarg(args, 6, 4, &arg5))
+		return NULL;
+	if (!getifloatarg(args, 6, 5, &arg6))
+		return NULL;
+	bbox2( arg1 , arg2 , arg3 , arg4 , arg5 , arg6 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void bbox2i short s short s long s long s long s long s */
+
+static PyObject *
+gl_bbox2i(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	long arg3 ;
+	long arg4 ;
+	long arg5 ;
+	long arg6 ;
+	if (!getishortarg(args, 6, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 6, 1, &arg2))
+		return NULL;
+	if (!getilongarg(args, 6, 2, &arg3))
+		return NULL;
+	if (!getilongarg(args, 6, 3, &arg4))
+		return NULL;
+	if (!getilongarg(args, 6, 4, &arg5))
+		return NULL;
+	if (!getilongarg(args, 6, 5, &arg6))
+		return NULL;
+	bbox2i( arg1 , arg2 , arg3 , arg4 , arg5 , arg6 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void bbox2s short s short s short s short s short s short s */
+
+static PyObject *
+gl_bbox2s(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	short arg3 ;
+	short arg4 ;
+	short arg5 ;
+	short arg6 ;
+	if (!getishortarg(args, 6, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 6, 1, &arg2))
+		return NULL;
+	if (!getishortarg(args, 6, 2, &arg3))
+		return NULL;
+	if (!getishortarg(args, 6, 3, &arg4))
+		return NULL;
+	if (!getishortarg(args, 6, 4, &arg5))
+		return NULL;
+	if (!getishortarg(args, 6, 5, &arg6))
+		return NULL;
+	bbox2s( arg1 , arg2 , arg3 , arg4 , arg5 , arg6 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void blink short s short s short s short s short s */
+
+static PyObject *
+gl_blink(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	short arg3 ;
+	short arg4 ;
+	short arg5 ;
+	if (!getishortarg(args, 5, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 5, 1, &arg2))
+		return NULL;
+	if (!getishortarg(args, 5, 2, &arg3))
+		return NULL;
+	if (!getishortarg(args, 5, 3, &arg4))
+		return NULL;
+	if (!getishortarg(args, 5, 4, &arg5))
+		return NULL;
+	blink( arg1 , arg2 , arg3 , arg4 , arg5 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void ortho float s float s float s float s float s float s */
+
+static PyObject *
+gl_ortho(PyObject *self, PyObject *args)
+{
+	float arg1 ;
+	float arg2 ;
+	float arg3 ;
+	float arg4 ;
+	float arg5 ;
+	float arg6 ;
+	if (!getifloatarg(args, 6, 0, &arg1))
+		return NULL;
+	if (!getifloatarg(args, 6, 1, &arg2))
+		return NULL;
+	if (!getifloatarg(args, 6, 2, &arg3))
+		return NULL;
+	if (!getifloatarg(args, 6, 3, &arg4))
+		return NULL;
+	if (!getifloatarg(args, 6, 4, &arg5))
+		return NULL;
+	if (!getifloatarg(args, 6, 5, &arg6))
+		return NULL;
+	ortho( arg1 , arg2 , arg3 , arg4 , arg5 , arg6 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void window float s float s float s float s float s float s */
+
+static PyObject *
+gl_window(PyObject *self, PyObject *args)
+{
+	float arg1 ;
+	float arg2 ;
+	float arg3 ;
+	float arg4 ;
+	float arg5 ;
+	float arg6 ;
+	if (!getifloatarg(args, 6, 0, &arg1))
+		return NULL;
+	if (!getifloatarg(args, 6, 1, &arg2))
+		return NULL;
+	if (!getifloatarg(args, 6, 2, &arg3))
+		return NULL;
+	if (!getifloatarg(args, 6, 3, &arg4))
+		return NULL;
+	if (!getifloatarg(args, 6, 4, &arg5))
+		return NULL;
+	if (!getifloatarg(args, 6, 5, &arg6))
+		return NULL;
+	window( arg1 , arg2 , arg3 , arg4 , arg5 , arg6 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void lookat float s float s float s float s float s float s short s */
+
+static PyObject *
+gl_lookat(PyObject *self, PyObject *args)
+{
+	float arg1 ;
+	float arg2 ;
+	float arg3 ;
+	float arg4 ;
+	float arg5 ;
+	float arg6 ;
+	short arg7 ;
+	if (!getifloatarg(args, 7, 0, &arg1))
+		return NULL;
+	if (!getifloatarg(args, 7, 1, &arg2))
+		return NULL;
+	if (!getifloatarg(args, 7, 2, &arg3))
+		return NULL;
+	if (!getifloatarg(args, 7, 3, &arg4))
+		return NULL;
+	if (!getifloatarg(args, 7, 4, &arg5))
+		return NULL;
+	if (!getifloatarg(args, 7, 5, &arg6))
+		return NULL;
+	if (!getishortarg(args, 7, 6, &arg7))
+		return NULL;
+	lookat( arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void perspective short s float s float s float s */
+
+static PyObject *
+gl_perspective(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	float arg2 ;
+	float arg3 ;
+	float arg4 ;
+	if (!getishortarg(args, 4, 0, &arg1))
+		return NULL;
+	if (!getifloatarg(args, 4, 1, &arg2))
+		return NULL;
+	if (!getifloatarg(args, 4, 2, &arg3))
+		return NULL;
+	if (!getifloatarg(args, 4, 3, &arg4))
+		return NULL;
+	perspective( arg1 , arg2 , arg3 , arg4 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void polarview float s short s short s short s */
+
+static PyObject *
+gl_polarview(PyObject *self, PyObject *args)
+{
+	float arg1 ;
+	short arg2 ;
+	short arg3 ;
+	short arg4 ;
+	if (!getifloatarg(args, 4, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 4, 1, &arg2))
+		return NULL;
+	if (!getishortarg(args, 4, 2, &arg3))
+		return NULL;
+	if (!getishortarg(args, 4, 3, &arg4))
+		return NULL;
+	polarview( arg1 , arg2 , arg3 , arg4 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void arcfs short s short s short s short s short s */
+
+static PyObject *
+gl_arcfs(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	short arg3 ;
+	short arg4 ;
+	short arg5 ;
+	if (!getishortarg(args, 5, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 5, 1, &arg2))
+		return NULL;
+	if (!getishortarg(args, 5, 2, &arg3))
+		return NULL;
+	if (!getishortarg(args, 5, 3, &arg4))
+		return NULL;
+	if (!getishortarg(args, 5, 4, &arg5))
+		return NULL;
+	arcfs( arg1 , arg2 , arg3 , arg4 , arg5 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void arcs short s short s short s short s short s */
+
+static PyObject *
+gl_arcs(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	short arg3 ;
+	short arg4 ;
+	short arg5 ;
+	if (!getishortarg(args, 5, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 5, 1, &arg2))
+		return NULL;
+	if (!getishortarg(args, 5, 2, &arg3))
+		return NULL;
+	if (!getishortarg(args, 5, 3, &arg4))
+		return NULL;
+	if (!getishortarg(args, 5, 4, &arg5))
+		return NULL;
+	arcs( arg1 , arg2 , arg3 , arg4 , arg5 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void rectcopy short s short s short s short s short s short s */
+
+static PyObject *
+gl_rectcopy(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	short arg3 ;
+	short arg4 ;
+	short arg5 ;
+	short arg6 ;
+	if (!getishortarg(args, 6, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 6, 1, &arg2))
+		return NULL;
+	if (!getishortarg(args, 6, 2, &arg3))
+		return NULL;
+	if (!getishortarg(args, 6, 3, &arg4))
+		return NULL;
+	if (!getishortarg(args, 6, 4, &arg5))
+		return NULL;
+	if (!getishortarg(args, 6, 5, &arg6))
+		return NULL;
+	rectcopy( arg1 , arg2 , arg3 , arg4 , arg5 , arg6 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void RGBcursor short s short s short s short s short s short s short s */
+
+static PyObject *
+gl_RGBcursor(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	short arg3 ;
+	short arg4 ;
+	short arg5 ;
+	short arg6 ;
+	short arg7 ;
+	if (!getishortarg(args, 7, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 7, 1, &arg2))
+		return NULL;
+	if (!getishortarg(args, 7, 2, &arg3))
+		return NULL;
+	if (!getishortarg(args, 7, 3, &arg4))
+		return NULL;
+	if (!getishortarg(args, 7, 4, &arg5))
+		return NULL;
+	if (!getishortarg(args, 7, 5, &arg6))
+		return NULL;
+	if (!getishortarg(args, 7, 6, &arg7))
+		return NULL;
+	RGBcursor( arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* long getbutton short s */
+
+static PyObject *
+gl_getbutton(PyObject *self, PyObject *args)
+{
+	long retval;
+	short arg1 ;
+	if (!getishortarg(args, 1, 0, &arg1))
+		return NULL;
+	retval = getbutton( arg1 );
+	return mknewlongobject(retval);
+}
+
+/* long getcmmode */
+
+static PyObject *
+gl_getcmmode(PyObject *self, PyObject *args)
+{
+	long retval;
+	retval = getcmmode( );
+	return mknewlongobject(retval);
+}
+
+/* long getlsbackup */
+
+static PyObject *
+gl_getlsbackup(PyObject *self, PyObject *args)
+{
+	long retval;
+	retval = getlsbackup( );
+	return mknewlongobject(retval);
+}
+
+/* long getresetls */
+
+static PyObject *
+gl_getresetls(PyObject *self, PyObject *args)
+{
+	long retval;
+	retval = getresetls( );
+	return mknewlongobject(retval);
+}
+
+/* long getdcm */
+
+static PyObject *
+gl_getdcm(PyObject *self, PyObject *args)
+{
+	long retval;
+	retval = getdcm( );
+	return mknewlongobject(retval);
+}
+
+/* long getzbuffer */
+
+static PyObject *
+gl_getzbuffer(PyObject *self, PyObject *args)
+{
+	long retval;
+	retval = getzbuffer( );
+	return mknewlongobject(retval);
+}
+
+/* long ismex */
+
+static PyObject *
+gl_ismex(PyObject *self, PyObject *args)
+{
+	long retval;
+	retval = ismex( );
+	return mknewlongobject(retval);
+}
+
+/* long isobj long s */
+
+static PyObject *
+gl_isobj(PyObject *self, PyObject *args)
+{
+	long retval;
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	retval = isobj( arg1 );
+	return mknewlongobject(retval);
+}
+
+/* long isqueued short s */
+
+static PyObject *
+gl_isqueued(PyObject *self, PyObject *args)
+{
+	long retval;
+	short arg1 ;
+	if (!getishortarg(args, 1, 0, &arg1))
+		return NULL;
+	retval = isqueued( arg1 );
+	return mknewlongobject(retval);
+}
+
+/* long istag long s */
+
+static PyObject *
+gl_istag(PyObject *self, PyObject *args)
+{
+	long retval;
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	retval = istag( arg1 );
+	return mknewlongobject(retval);
+}
+
+/* long genobj */
+
+static PyObject *
+gl_genobj(PyObject *self, PyObject *args)
+{
+	long retval;
+	retval = genobj( );
+	return mknewlongobject(retval);
+}
+
+/* long gentag */
+
+static PyObject *
+gl_gentag(PyObject *self, PyObject *args)
+{
+	long retval;
+	retval = gentag( );
+	return mknewlongobject(retval);
+}
+
+/* long getbuffer */
+
+static PyObject *
+gl_getbuffer(PyObject *self, PyObject *args)
+{
+	long retval;
+	retval = getbuffer( );
+	return mknewlongobject(retval);
+}
+
+/* long getcolor */
+
+static PyObject *
+gl_getcolor(PyObject *self, PyObject *args)
+{
+	long retval;
+	retval = getcolor( );
+	return mknewlongobject(retval);
+}
+
+/* long getdisplaymode */
+
+static PyObject *
+gl_getdisplaymode(PyObject *self, PyObject *args)
+{
+	long retval;
+	retval = getdisplaymode( );
+	return mknewlongobject(retval);
+}
+
+/* long getfont */
+
+static PyObject *
+gl_getfont(PyObject *self, PyObject *args)
+{
+	long retval;
+	retval = getfont( );
+	return mknewlongobject(retval);
+}
+
+/* long getheight */
+
+static PyObject *
+gl_getheight(PyObject *self, PyObject *args)
+{
+	long retval;
+	retval = getheight( );
+	return mknewlongobject(retval);
+}
+
+/* long gethitcode */
+
+static PyObject *
+gl_gethitcode(PyObject *self, PyObject *args)
+{
+	long retval;
+	retval = gethitcode( );
+	return mknewlongobject(retval);
+}
+
+/* long getlstyle */
+
+static PyObject *
+gl_getlstyle(PyObject *self, PyObject *args)
+{
+	long retval;
+	retval = getlstyle( );
+	return mknewlongobject(retval);
+}
+
+/* long getlwidth */
+
+static PyObject *
+gl_getlwidth(PyObject *self, PyObject *args)
+{
+	long retval;
+	retval = getlwidth( );
+	return mknewlongobject(retval);
+}
+
+/* long getmap */
+
+static PyObject *
+gl_getmap(PyObject *self, PyObject *args)
+{
+	long retval;
+	retval = getmap( );
+	return mknewlongobject(retval);
+}
+
+/* long getplanes */
+
+static PyObject *
+gl_getplanes(PyObject *self, PyObject *args)
+{
+	long retval;
+	retval = getplanes( );
+	return mknewlongobject(retval);
+}
+
+/* long getwritemask */
+
+static PyObject *
+gl_getwritemask(PyObject *self, PyObject *args)
+{
+	long retval;
+	retval = getwritemask( );
+	return mknewlongobject(retval);
+}
+
+/* long qtest */
+
+static PyObject *
+gl_qtest(PyObject *self, PyObject *args)
+{
+	long retval;
+	retval = qtest( );
+	return mknewlongobject(retval);
+}
+
+/* long getlsrepeat */
+
+static PyObject *
+gl_getlsrepeat(PyObject *self, PyObject *args)
+{
+	long retval;
+	retval = getlsrepeat( );
+	return mknewlongobject(retval);
+}
+
+/* long getmonitor */
+
+static PyObject *
+gl_getmonitor(PyObject *self, PyObject *args)
+{
+	long retval;
+	retval = getmonitor( );
+	return mknewlongobject(retval);
+}
+
+/* long getopenobj */
+
+static PyObject *
+gl_getopenobj(PyObject *self, PyObject *args)
+{
+	long retval;
+	retval = getopenobj( );
+	return mknewlongobject(retval);
+}
+
+/* long getpattern */
+
+static PyObject *
+gl_getpattern(PyObject *self, PyObject *args)
+{
+	long retval;
+	retval = getpattern( );
+	return mknewlongobject(retval);
+}
+
+/* long winget */
+
+static PyObject *
+gl_winget(PyObject *self, PyObject *args)
+{
+	long retval;
+	retval = winget( );
+	return mknewlongobject(retval);
+}
+
+/* long winattach */
+
+static PyObject *
+gl_winattach(PyObject *self, PyObject *args)
+{
+	long retval;
+	retval = winattach( );
+	return mknewlongobject(retval);
+}
+
+/* long getothermonitor */
+
+static PyObject *
+gl_getothermonitor(PyObject *self, PyObject *args)
+{
+	long retval;
+	retval = getothermonitor( );
+	return mknewlongobject(retval);
+}
+
+/* long newpup */
+
+static PyObject *
+gl_newpup(PyObject *self, PyObject *args)
+{
+	long retval;
+	retval = newpup( );
+	return mknewlongobject(retval);
+}
+
+/* long getvaluator short s */
+
+static PyObject *
+gl_getvaluator(PyObject *self, PyObject *args)
+{
+	long retval;
+	short arg1 ;
+	if (!getishortarg(args, 1, 0, &arg1))
+		return NULL;
+	retval = getvaluator( arg1 );
+	return mknewlongobject(retval);
+}
+
+/* void winset long s */
+
+static PyObject *
+gl_winset(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	winset( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* long dopup long s */
+
+static PyObject *
+gl_dopup(PyObject *self, PyObject *args)
+{
+	long retval;
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	retval = dopup( arg1 );
+	return mknewlongobject(retval);
+}
+
+/* void getdepth short r short r */
+
+static PyObject *
+gl_getdepth(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	getdepth( & arg1 , & arg2 );
+	{ PyObject *v = PyTuple_New( 2 );
+	  if (v == NULL) return NULL;
+	  PyTuple_SetItem(v, 0, mknewshortobject(arg1));
+	  PyTuple_SetItem(v, 1, mknewshortobject(arg2));
+	  return v;
+	}
+}
+
+/* void getcpos short r short r */
+
+static PyObject *
+gl_getcpos(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	getcpos( & arg1 , & arg2 );
+	{ PyObject *v = PyTuple_New( 2 );
+	  if (v == NULL) return NULL;
+	  PyTuple_SetItem(v, 0, mknewshortobject(arg1));
+	  PyTuple_SetItem(v, 1, mknewshortobject(arg2));
+	  return v;
+	}
+}
+
+/* void getsize long r long r */
+
+static PyObject *
+gl_getsize(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	getsize( & arg1 , & arg2 );
+	{ PyObject *v = PyTuple_New( 2 );
+	  if (v == NULL) return NULL;
+	  PyTuple_SetItem(v, 0, mknewlongobject(arg1));
+	  PyTuple_SetItem(v, 1, mknewlongobject(arg2));
+	  return v;
+	}
+}
+
+/* void getorigin long r long r */
+
+static PyObject *
+gl_getorigin(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	getorigin( & arg1 , & arg2 );
+	{ PyObject *v = PyTuple_New( 2 );
+	  if (v == NULL) return NULL;
+	  PyTuple_SetItem(v, 0, mknewlongobject(arg1));
+	  PyTuple_SetItem(v, 1, mknewlongobject(arg2));
+	  return v;
+	}
+}
+
+/* void getviewport short r short r short r short r */
+
+static PyObject *
+gl_getviewport(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	short arg3 ;
+	short arg4 ;
+	getviewport( & arg1 , & arg2 , & arg3 , & arg4 );
+	{ PyObject *v = PyTuple_New( 4 );
+	  if (v == NULL) return NULL;
+	  PyTuple_SetItem(v, 0, mknewshortobject(arg1));
+	  PyTuple_SetItem(v, 1, mknewshortobject(arg2));
+	  PyTuple_SetItem(v, 2, mknewshortobject(arg3));
+	  PyTuple_SetItem(v, 3, mknewshortobject(arg4));
+	  return v;
+	}
+}
+
+/* void gettp short r short r short r short r */
+
+static PyObject *
+gl_gettp(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	short arg3 ;
+	short arg4 ;
+	gettp( & arg1 , & arg2 , & arg3 , & arg4 );
+	{ PyObject *v = PyTuple_New( 4 );
+	  if (v == NULL) return NULL;
+	  PyTuple_SetItem(v, 0, mknewshortobject(arg1));
+	  PyTuple_SetItem(v, 1, mknewshortobject(arg2));
+	  PyTuple_SetItem(v, 2, mknewshortobject(arg3));
+	  PyTuple_SetItem(v, 3, mknewshortobject(arg4));
+	  return v;
+	}
+}
+
+/* void getgpos float r float r float r float r */
+
+static PyObject *
+gl_getgpos(PyObject *self, PyObject *args)
+{
+	float arg1 ;
+	float arg2 ;
+	float arg3 ;
+	float arg4 ;
+	getgpos( & arg1 , & arg2 , & arg3 , & arg4 );
+	{ PyObject *v = PyTuple_New( 4 );
+	  if (v == NULL) return NULL;
+	  PyTuple_SetItem(v, 0, mknewfloatobject(arg1));
+	  PyTuple_SetItem(v, 1, mknewfloatobject(arg2));
+	  PyTuple_SetItem(v, 2, mknewfloatobject(arg3));
+	  PyTuple_SetItem(v, 3, mknewfloatobject(arg4));
+	  return v;
+	}
+}
+
+/* void winposition long s long s long s long s */
+
+static PyObject *
+gl_winposition(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	long arg3 ;
+	long arg4 ;
+	if (!getilongarg(args, 4, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 4, 1, &arg2))
+		return NULL;
+	if (!getilongarg(args, 4, 2, &arg3))
+		return NULL;
+	if (!getilongarg(args, 4, 3, &arg4))
+		return NULL;
+	winposition( arg1 , arg2 , arg3 , arg4 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void gRGBcolor short r short r short r */
+
+static PyObject *
+gl_gRGBcolor(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	short arg3 ;
+	gRGBcolor( & arg1 , & arg2 , & arg3 );
+	{ PyObject *v = PyTuple_New( 3 );
+	  if (v == NULL) return NULL;
+	  PyTuple_SetItem(v, 0, mknewshortobject(arg1));
+	  PyTuple_SetItem(v, 1, mknewshortobject(arg2));
+	  PyTuple_SetItem(v, 2, mknewshortobject(arg3));
+	  return v;
+	}
+}
+
+/* void gRGBmask short r short r short r */
+
+static PyObject *
+gl_gRGBmask(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	short arg3 ;
+	gRGBmask( & arg1 , & arg2 , & arg3 );
+	{ PyObject *v = PyTuple_New( 3 );
+	  if (v == NULL) return NULL;
+	  PyTuple_SetItem(v, 0, mknewshortobject(arg1));
+	  PyTuple_SetItem(v, 1, mknewshortobject(arg2));
+	  PyTuple_SetItem(v, 2, mknewshortobject(arg3));
+	  return v;
+	}
+}
+
+/* void getscrmask short r short r short r short r */
+
+static PyObject *
+gl_getscrmask(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	short arg3 ;
+	short arg4 ;
+	getscrmask( & arg1 , & arg2 , & arg3 , & arg4 );
+	{ PyObject *v = PyTuple_New( 4 );
+	  if (v == NULL) return NULL;
+	  PyTuple_SetItem(v, 0, mknewshortobject(arg1));
+	  PyTuple_SetItem(v, 1, mknewshortobject(arg2));
+	  PyTuple_SetItem(v, 2, mknewshortobject(arg3));
+	  PyTuple_SetItem(v, 3, mknewshortobject(arg4));
+	  return v;
+	}
+}
+
+/* void getmcolor short s short r short r short r */
+
+static PyObject *
+gl_getmcolor(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	short arg3 ;
+	short arg4 ;
+	if (!getishortarg(args, 1, 0, &arg1))
+		return NULL;
+	getmcolor( arg1 , & arg2 , & arg3 , & arg4 );
+	{ PyObject *v = PyTuple_New( 3 );
+	  if (v == NULL) return NULL;
+	  PyTuple_SetItem(v, 0, mknewshortobject(arg2));
+	  PyTuple_SetItem(v, 1, mknewshortobject(arg3));
+	  PyTuple_SetItem(v, 2, mknewshortobject(arg4));
+	  return v;
+	}
+}
+
+/* void mapw long s short s short s float r float r float r float r float r float r */
+
+static PyObject *
+gl_mapw(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	short arg2 ;
+	short arg3 ;
+	float arg4 ;
+	float arg5 ;
+	float arg6 ;
+	float arg7 ;
+	float arg8 ;
+	float arg9 ;
+	if (!getilongarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getishortarg(args, 3, 2, &arg3))
+		return NULL;
+	mapw( arg1 , arg2 , arg3 , & arg4 , & arg5 , & arg6 , & arg7 , & arg8 , & arg9 );
+	{ PyObject *v = PyTuple_New( 6 );
+	  if (v == NULL) return NULL;
+	  PyTuple_SetItem(v, 0, mknewfloatobject(arg4));
+	  PyTuple_SetItem(v, 1, mknewfloatobject(arg5));
+	  PyTuple_SetItem(v, 2, mknewfloatobject(arg6));
+	  PyTuple_SetItem(v, 3, mknewfloatobject(arg7));
+	  PyTuple_SetItem(v, 4, mknewfloatobject(arg8));
+	  PyTuple_SetItem(v, 5, mknewfloatobject(arg9));
+	  return v;
+	}
+}
+
+/* void mapw2 long s short s short s float r float r */
+
+static PyObject *
+gl_mapw2(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	short arg2 ;
+	short arg3 ;
+	float arg4 ;
+	float arg5 ;
+	if (!getilongarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getishortarg(args, 3, 2, &arg3))
+		return NULL;
+	mapw2( arg1 , arg2 , arg3 , & arg4 , & arg5 );
+	{ PyObject *v = PyTuple_New( 2 );
+	  if (v == NULL) return NULL;
+	  PyTuple_SetItem(v, 0, mknewfloatobject(arg4));
+	  PyTuple_SetItem(v, 1, mknewfloatobject(arg5));
+	  return v;
+	}
+}
+
+/* void getcursor short r u_short r u_short r long r */
+
+static PyObject *
+gl_getcursor(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	unsigned short arg2 ;
+	unsigned short arg3 ;
+	long arg4 ;
+	getcursor( & arg1 , & arg2 , & arg3 , & arg4 );
+	{ PyObject *v = PyTuple_New( 4 );
+	  if (v == NULL) return NULL;
+	  PyTuple_SetItem(v, 0, mknewshortobject(arg1));
+	  PyTuple_SetItem(v, 1, mknewshortobject((short) arg2));
+	  PyTuple_SetItem(v, 2, mknewshortobject((short) arg3));
+	  PyTuple_SetItem(v, 3, mknewlongobject(arg4));
+	  return v;
+	}
+}
+
+/* void cmode */
+
+static PyObject *
+gl_cmode(PyObject *self, PyObject *args)
+{
+	cmode( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void concave long s */
+
+static PyObject *
+gl_concave(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	concave( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void curstype long s */
+
+static PyObject *
+gl_curstype(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	curstype( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void drawmode long s */
+
+static PyObject *
+gl_drawmode(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	drawmode( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void gammaramp short s[256] short s[256] short s[256] */
+
+static PyObject *
+gl_gammaramp(PyObject *self, PyObject *args)
+{
+	short arg1 [ 256 ] ;
+	short arg2 [ 256 ] ;
+	short arg3 [ 256 ] ;
+	if (!getishortarray(args, 3, 0, 256 , arg1))
+		return NULL;
+	if (!getishortarray(args, 3, 1, 256 , arg2))
+		return NULL;
+	if (!getishortarray(args, 3, 2, 256 , arg3))
+		return NULL;
+	gammaramp( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* long getbackface */
+
+static PyObject *
+gl_getbackface(PyObject *self, PyObject *args)
+{
+	long retval;
+	retval = getbackface( );
+	return mknewlongobject(retval);
+}
+
+/* long getdescender */
+
+static PyObject *
+gl_getdescender(PyObject *self, PyObject *args)
+{
+	long retval;
+	retval = getdescender( );
+	return mknewlongobject(retval);
+}
+
+/* long getdrawmode */
+
+static PyObject *
+gl_getdrawmode(PyObject *self, PyObject *args)
+{
+	long retval;
+	retval = getdrawmode( );
+	return mknewlongobject(retval);
+}
+
+/* long getmmode */
+
+static PyObject *
+gl_getmmode(PyObject *self, PyObject *args)
+{
+	long retval;
+	retval = getmmode( );
+	return mknewlongobject(retval);
+}
+
+/* long getsm */
+
+static PyObject *
+gl_getsm(PyObject *self, PyObject *args)
+{
+	long retval;
+	retval = getsm( );
+	return mknewlongobject(retval);
+}
+
+/* long getvideo long s */
+
+static PyObject *
+gl_getvideo(PyObject *self, PyObject *args)
+{
+	long retval;
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	retval = getvideo( arg1 );
+	return mknewlongobject(retval);
+}
+
+/* void imakebackground */
+
+static PyObject *
+gl_imakebackground(PyObject *self, PyObject *args)
+{
+	imakebackground( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void lmbind short s short s */
+
+static PyObject *
+gl_lmbind(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	if (!getishortarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 2, 1, &arg2))
+		return NULL;
+	lmbind( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void lmdef long s long s long s float s[arg3] */
+
+static PyObject *
+gl_lmdef(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	long arg3 ;
+	float * arg4 ;
+	if (!getilongarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getilongarraysize(args, 3, 2, &arg3))
+		return NULL;
+	if ((arg4 = PyMem_NEW(float , arg3 )) == NULL)
+		return PyErr_NoMemory();
+	if (!getifloatarray(args, 3, 2, arg3 , arg4))
+		return NULL;
+	lmdef( arg1 , arg2 , arg3 , arg4 );
+	PyMem_DEL(arg4);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void mmode long s */
+
+static PyObject *
+gl_mmode(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	mmode( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void normal float s[3] */
+
+static PyObject *
+gl_normal(PyObject *self, PyObject *args)
+{
+	float arg1 [ 3 ] ;
+	if (!getifloatarray(args, 1, 0, 3 , arg1))
+		return NULL;
+	normal( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void overlay long s */
+
+static PyObject *
+gl_overlay(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	overlay( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void RGBrange short s short s short s short s short s short s short s short s */
+
+static PyObject *
+gl_RGBrange(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	short arg3 ;
+	short arg4 ;
+	short arg5 ;
+	short arg6 ;
+	short arg7 ;
+	short arg8 ;
+	if (!getishortarg(args, 8, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 8, 1, &arg2))
+		return NULL;
+	if (!getishortarg(args, 8, 2, &arg3))
+		return NULL;
+	if (!getishortarg(args, 8, 3, &arg4))
+		return NULL;
+	if (!getishortarg(args, 8, 4, &arg5))
+		return NULL;
+	if (!getishortarg(args, 8, 5, &arg6))
+		return NULL;
+	if (!getishortarg(args, 8, 6, &arg7))
+		return NULL;
+	if (!getishortarg(args, 8, 7, &arg8))
+		return NULL;
+	RGBrange( arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void setvideo long s long s */
+
+static PyObject *
+gl_setvideo(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	if (!getilongarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 2, 1, &arg2))
+		return NULL;
+	setvideo( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void shademodel long s */
+
+static PyObject *
+gl_shademodel(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	shademodel( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void underlay long s */
+
+static PyObject *
+gl_underlay(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	underlay( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void bgnclosedline */
+
+static PyObject *
+gl_bgnclosedline(PyObject *self, PyObject *args)
+{
+	bgnclosedline( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void bgnline */
+
+static PyObject *
+gl_bgnline(PyObject *self, PyObject *args)
+{
+	bgnline( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void bgnpoint */
+
+static PyObject *
+gl_bgnpoint(PyObject *self, PyObject *args)
+{
+	bgnpoint( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void bgnpolygon */
+
+static PyObject *
+gl_bgnpolygon(PyObject *self, PyObject *args)
+{
+	bgnpolygon( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void bgnsurface */
+
+static PyObject *
+gl_bgnsurface(PyObject *self, PyObject *args)
+{
+	bgnsurface( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void bgntmesh */
+
+static PyObject *
+gl_bgntmesh(PyObject *self, PyObject *args)
+{
+	bgntmesh( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void bgntrim */
+
+static PyObject *
+gl_bgntrim(PyObject *self, PyObject *args)
+{
+	bgntrim( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void endclosedline */
+
+static PyObject *
+gl_endclosedline(PyObject *self, PyObject *args)
+{
+	endclosedline( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void endline */
+
+static PyObject *
+gl_endline(PyObject *self, PyObject *args)
+{
+	endline( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void endpoint */
+
+static PyObject *
+gl_endpoint(PyObject *self, PyObject *args)
+{
+	endpoint( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void endpolygon */
+
+static PyObject *
+gl_endpolygon(PyObject *self, PyObject *args)
+{
+	endpolygon( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void endsurface */
+
+static PyObject *
+gl_endsurface(PyObject *self, PyObject *args)
+{
+	endsurface( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void endtmesh */
+
+static PyObject *
+gl_endtmesh(PyObject *self, PyObject *args)
+{
+	endtmesh( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void endtrim */
+
+static PyObject *
+gl_endtrim(PyObject *self, PyObject *args)
+{
+	endtrim( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void blendfunction long s long s */
+
+static PyObject *
+gl_blendfunction(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	if (!getilongarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 2, 1, &arg2))
+		return NULL;
+	blendfunction( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void c3f float s[3] */
+
+static PyObject *
+gl_c3f(PyObject *self, PyObject *args)
+{
+	float arg1 [ 3 ] ;
+	if (!getifloatarray(args, 1, 0, 3 , arg1))
+		return NULL;
+	c3f( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void c3i long s[3] */
+
+static PyObject *
+gl_c3i(PyObject *self, PyObject *args)
+{
+	long arg1 [ 3 ] ;
+	if (!getilongarray(args, 1, 0, 3 , arg1))
+		return NULL;
+	c3i( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void c3s short s[3] */
+
+static PyObject *
+gl_c3s(PyObject *self, PyObject *args)
+{
+	short arg1 [ 3 ] ;
+	if (!getishortarray(args, 1, 0, 3 , arg1))
+		return NULL;
+	c3s( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void c4f float s[4] */
+
+static PyObject *
+gl_c4f(PyObject *self, PyObject *args)
+{
+	float arg1 [ 4 ] ;
+	if (!getifloatarray(args, 1, 0, 4 , arg1))
+		return NULL;
+	c4f( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void c4i long s[4] */
+
+static PyObject *
+gl_c4i(PyObject *self, PyObject *args)
+{
+	long arg1 [ 4 ] ;
+	if (!getilongarray(args, 1, 0, 4 , arg1))
+		return NULL;
+	c4i( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void c4s short s[4] */
+
+static PyObject *
+gl_c4s(PyObject *self, PyObject *args)
+{
+	short arg1 [ 4 ] ;
+	if (!getishortarray(args, 1, 0, 4 , arg1))
+		return NULL;
+	c4s( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void colorf float s */
+
+static PyObject *
+gl_colorf(PyObject *self, PyObject *args)
+{
+	float arg1 ;
+	if (!getifloatarg(args, 1, 0, &arg1))
+		return NULL;
+	colorf( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void cpack long s */
+
+static PyObject *
+gl_cpack(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	cpack( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void czclear long s long s */
+
+static PyObject *
+gl_czclear(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	if (!getilongarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 2, 1, &arg2))
+		return NULL;
+	czclear( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void dglclose long s */
+
+static PyObject *
+gl_dglclose(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	dglclose( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* long dglopen char *s long s */
+
+static PyObject *
+gl_dglopen(PyObject *self, PyObject *args)
+{
+	long retval;
+	string arg1 ;
+	long arg2 ;
+	if (!getistringarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 2, 1, &arg2))
+		return NULL;
+	retval = dglopen( arg1 , arg2 );
+	return mknewlongobject(retval);
+}
+
+/* long getgdesc long s */
+
+static PyObject *
+gl_getgdesc(PyObject *self, PyObject *args)
+{
+	long retval;
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	retval = getgdesc( arg1 );
+	return mknewlongobject(retval);
+}
+
+/* void getnurbsproperty long s float r */
+
+static PyObject *
+gl_getnurbsproperty(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	float arg2 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	getnurbsproperty( arg1 , & arg2 );
+	return mknewfloatobject(arg2);
+}
+
+/* void glcompat long s long s */
+
+static PyObject *
+gl_glcompat(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	if (!getilongarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 2, 1, &arg2))
+		return NULL;
+	glcompat( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void iconsize long s long s */
+
+static PyObject *
+gl_iconsize(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	if (!getilongarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 2, 1, &arg2))
+		return NULL;
+	iconsize( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void icontitle char *s */
+
+static PyObject *
+gl_icontitle(PyObject *self, PyObject *args)
+{
+	string arg1 ;
+	if (!getistringarg(args, 1, 0, &arg1))
+		return NULL;
+	icontitle( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void lRGBrange short s short s short s short s short s short s long s long s */
+
+static PyObject *
+gl_lRGBrange(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	short arg3 ;
+	short arg4 ;
+	short arg5 ;
+	short arg6 ;
+	long arg7 ;
+	long arg8 ;
+	if (!getishortarg(args, 8, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 8, 1, &arg2))
+		return NULL;
+	if (!getishortarg(args, 8, 2, &arg3))
+		return NULL;
+	if (!getishortarg(args, 8, 3, &arg4))
+		return NULL;
+	if (!getishortarg(args, 8, 4, &arg5))
+		return NULL;
+	if (!getishortarg(args, 8, 5, &arg6))
+		return NULL;
+	if (!getilongarg(args, 8, 6, &arg7))
+		return NULL;
+	if (!getilongarg(args, 8, 7, &arg8))
+		return NULL;
+	lRGBrange( arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void linesmooth long s */
+
+static PyObject *
+gl_linesmooth(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	linesmooth( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void lmcolor long s */
+
+static PyObject *
+gl_lmcolor(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	lmcolor( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void logicop long s */
+
+static PyObject *
+gl_logicop(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	logicop( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void lsetdepth long s long s */
+
+static PyObject *
+gl_lsetdepth(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	if (!getilongarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 2, 1, &arg2))
+		return NULL;
+	lsetdepth( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void lshaderange short s short s long s long s */
+
+static PyObject *
+gl_lshaderange(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	long arg3 ;
+	long arg4 ;
+	if (!getishortarg(args, 4, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 4, 1, &arg2))
+		return NULL;
+	if (!getilongarg(args, 4, 2, &arg3))
+		return NULL;
+	if (!getilongarg(args, 4, 3, &arg4))
+		return NULL;
+	lshaderange( arg1 , arg2 , arg3 , arg4 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void n3f float s[3] */
+
+static PyObject *
+gl_n3f(PyObject *self, PyObject *args)
+{
+	float arg1 [ 3 ] ;
+	if (!getifloatarray(args, 1, 0, 3 , arg1))
+		return NULL;
+	n3f( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void noborder */
+
+static PyObject *
+gl_noborder(PyObject *self, PyObject *args)
+{
+	noborder( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void pntsmooth long s */
+
+static PyObject *
+gl_pntsmooth(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	pntsmooth( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void readsource long s */
+
+static PyObject *
+gl_readsource(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	readsource( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void rectzoom float s float s */
+
+static PyObject *
+gl_rectzoom(PyObject *self, PyObject *args)
+{
+	float arg1 ;
+	float arg2 ;
+	if (!getifloatarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getifloatarg(args, 2, 1, &arg2))
+		return NULL;
+	rectzoom( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void sbox float s float s float s float s */
+
+static PyObject *
+gl_sbox(PyObject *self, PyObject *args)
+{
+	float arg1 ;
+	float arg2 ;
+	float arg3 ;
+	float arg4 ;
+	if (!getifloatarg(args, 4, 0, &arg1))
+		return NULL;
+	if (!getifloatarg(args, 4, 1, &arg2))
+		return NULL;
+	if (!getifloatarg(args, 4, 2, &arg3))
+		return NULL;
+	if (!getifloatarg(args, 4, 3, &arg4))
+		return NULL;
+	sbox( arg1 , arg2 , arg3 , arg4 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void sboxi long s long s long s long s */
+
+static PyObject *
+gl_sboxi(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	long arg3 ;
+	long arg4 ;
+	if (!getilongarg(args, 4, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 4, 1, &arg2))
+		return NULL;
+	if (!getilongarg(args, 4, 2, &arg3))
+		return NULL;
+	if (!getilongarg(args, 4, 3, &arg4))
+		return NULL;
+	sboxi( arg1 , arg2 , arg3 , arg4 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void sboxs short s short s short s short s */
+
+static PyObject *
+gl_sboxs(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	short arg3 ;
+	short arg4 ;
+	if (!getishortarg(args, 4, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 4, 1, &arg2))
+		return NULL;
+	if (!getishortarg(args, 4, 2, &arg3))
+		return NULL;
+	if (!getishortarg(args, 4, 3, &arg4))
+		return NULL;
+	sboxs( arg1 , arg2 , arg3 , arg4 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void sboxf float s float s float s float s */
+
+static PyObject *
+gl_sboxf(PyObject *self, PyObject *args)
+{
+	float arg1 ;
+	float arg2 ;
+	float arg3 ;
+	float arg4 ;
+	if (!getifloatarg(args, 4, 0, &arg1))
+		return NULL;
+	if (!getifloatarg(args, 4, 1, &arg2))
+		return NULL;
+	if (!getifloatarg(args, 4, 2, &arg3))
+		return NULL;
+	if (!getifloatarg(args, 4, 3, &arg4))
+		return NULL;
+	sboxf( arg1 , arg2 , arg3 , arg4 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void sboxfi long s long s long s long s */
+
+static PyObject *
+gl_sboxfi(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	long arg3 ;
+	long arg4 ;
+	if (!getilongarg(args, 4, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 4, 1, &arg2))
+		return NULL;
+	if (!getilongarg(args, 4, 2, &arg3))
+		return NULL;
+	if (!getilongarg(args, 4, 3, &arg4))
+		return NULL;
+	sboxfi( arg1 , arg2 , arg3 , arg4 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void sboxfs short s short s short s short s */
+
+static PyObject *
+gl_sboxfs(PyObject *self, PyObject *args)
+{
+	short arg1 ;
+	short arg2 ;
+	short arg3 ;
+	short arg4 ;
+	if (!getishortarg(args, 4, 0, &arg1))
+		return NULL;
+	if (!getishortarg(args, 4, 1, &arg2))
+		return NULL;
+	if (!getishortarg(args, 4, 2, &arg3))
+		return NULL;
+	if (!getishortarg(args, 4, 3, &arg4))
+		return NULL;
+	sboxfs( arg1 , arg2 , arg3 , arg4 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void setnurbsproperty long s float s */
+
+static PyObject *
+gl_setnurbsproperty(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	float arg2 ;
+	if (!getilongarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getifloatarg(args, 2, 1, &arg2))
+		return NULL;
+	setnurbsproperty( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void setpup long s long s long s */
+
+static PyObject *
+gl_setpup(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	long arg3 ;
+	if (!getilongarg(args, 3, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 3, 1, &arg2))
+		return NULL;
+	if (!getilongarg(args, 3, 2, &arg3))
+		return NULL;
+	setpup( arg1 , arg2 , arg3 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void smoothline long s */
+
+static PyObject *
+gl_smoothline(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	smoothline( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void subpixel long s */
+
+static PyObject *
+gl_subpixel(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	subpixel( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void swaptmesh */
+
+static PyObject *
+gl_swaptmesh(PyObject *self, PyObject *args)
+{
+	swaptmesh( );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* long swinopen long s */
+
+static PyObject *
+gl_swinopen(PyObject *self, PyObject *args)
+{
+	long retval;
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	retval = swinopen( arg1 );
+	return mknewlongobject(retval);
+}
+
+/* void v2f float s[2] */
+
+static PyObject *
+gl_v2f(PyObject *self, PyObject *args)
+{
+	float arg1 [ 2 ] ;
+	if (!getifloatarray(args, 1, 0, 2 , arg1))
+		return NULL;
+	v2f( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void v2i long s[2] */
+
+static PyObject *
+gl_v2i(PyObject *self, PyObject *args)
+{
+	long arg1 [ 2 ] ;
+	if (!getilongarray(args, 1, 0, 2 , arg1))
+		return NULL;
+	v2i( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void v2s short s[2] */
+
+static PyObject *
+gl_v2s(PyObject *self, PyObject *args)
+{
+	short arg1 [ 2 ] ;
+	if (!getishortarray(args, 1, 0, 2 , arg1))
+		return NULL;
+	v2s( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void v3f float s[3] */
+
+static PyObject *
+gl_v3f(PyObject *self, PyObject *args)
+{
+	float arg1 [ 3 ] ;
+	if (!getifloatarray(args, 1, 0, 3 , arg1))
+		return NULL;
+	v3f( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void v3i long s[3] */
+
+static PyObject *
+gl_v3i(PyObject *self, PyObject *args)
+{
+	long arg1 [ 3 ] ;
+	if (!getilongarray(args, 1, 0, 3 , arg1))
+		return NULL;
+	v3i( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void v3s short s[3] */
+
+static PyObject *
+gl_v3s(PyObject *self, PyObject *args)
+{
+	short arg1 [ 3 ] ;
+	if (!getishortarray(args, 1, 0, 3 , arg1))
+		return NULL;
+	v3s( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void v4f float s[4] */
+
+static PyObject *
+gl_v4f(PyObject *self, PyObject *args)
+{
+	float arg1 [ 4 ] ;
+	if (!getifloatarray(args, 1, 0, 4 , arg1))
+		return NULL;
+	v4f( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void v4i long s[4] */
+
+static PyObject *
+gl_v4i(PyObject *self, PyObject *args)
+{
+	long arg1 [ 4 ] ;
+	if (!getilongarray(args, 1, 0, 4 , arg1))
+		return NULL;
+	v4i( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void v4s short s[4] */
+
+static PyObject *
+gl_v4s(PyObject *self, PyObject *args)
+{
+	short arg1 [ 4 ] ;
+	if (!getishortarray(args, 1, 0, 4 , arg1))
+		return NULL;
+	v4s( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void videocmd long s */
+
+static PyObject *
+gl_videocmd(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	videocmd( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* long windepth long s */
+
+static PyObject *
+gl_windepth(PyObject *self, PyObject *args)
+{
+	long retval;
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	retval = windepth( arg1 );
+	return mknewlongobject(retval);
+}
+
+/* void wmpack long s */
+
+static PyObject *
+gl_wmpack(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	wmpack( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void zdraw long s */
+
+static PyObject *
+gl_zdraw(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	zdraw( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void zfunction long s */
+
+static PyObject *
+gl_zfunction(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	zfunction( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void zsource long s */
+
+static PyObject *
+gl_zsource(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	zsource( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void zwritemask long s */
+
+static PyObject *
+gl_zwritemask(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	zwritemask( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void v2d double s[2] */
+
+static PyObject *
+gl_v2d(PyObject *self, PyObject *args)
+{
+	double arg1 [ 2 ] ;
+	if (!getidoublearray(args, 1, 0, 2 , arg1))
+		return NULL;
+	v2d( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void v3d double s[3] */
+
+static PyObject *
+gl_v3d(PyObject *self, PyObject *args)
+{
+	double arg1 [ 3 ] ;
+	if (!getidoublearray(args, 1, 0, 3 , arg1))
+		return NULL;
+	v3d( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void v4d double s[4] */
+
+static PyObject *
+gl_v4d(PyObject *self, PyObject *args)
+{
+	double arg1 [ 4 ] ;
+	if (!getidoublearray(args, 1, 0, 4 , arg1))
+		return NULL;
+	v4d( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* void pixmode long s long s */
+
+static PyObject *
+gl_pixmode(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	long arg2 ;
+	if (!getilongarg(args, 2, 0, &arg1))
+		return NULL;
+	if (!getilongarg(args, 2, 1, &arg2))
+		return NULL;
+	pixmode( arg1 , arg2 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* long qgetfd */
+
+static PyObject *
+gl_qgetfd(PyObject *self, PyObject *args)
+{
+	long retval;
+	retval = qgetfd( );
+	return mknewlongobject(retval);
+}
+
+/* void dither long s */
+
+static PyObject *
+gl_dither(PyObject *self, PyObject *args)
+{
+	long arg1 ;
+	if (!getilongarg(args, 1, 0, &arg1))
+		return NULL;
+	dither( arg1 );
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static struct PyMethodDef gl_methods[] = {
+	{"qread", gl_qread,                  METH_OLDARGS},
+	{"varray", gl_varray,                METH_OLDARGS},
+	{"nvarray", gl_nvarray,              METH_OLDARGS},
+	{"vnarray", gl_vnarray,              METH_OLDARGS},
+	{"nurbssurface", gl_nurbssurface,    METH_OLDARGS},
+	{"nurbscurve", gl_nurbscurve,        METH_OLDARGS},
+	{"pwlcurve", gl_pwlcurve,            METH_OLDARGS},
+	{"pick", gl_pick,                    METH_OLDARGS},
+	{"endpick", gl_endpick,              METH_NOARGS},
+	{"gselect", gl_gselect,              METH_OLDARGS},
+	{"endselect", gl_endselect,          METH_NOARGS},
+	{"getmatrix", gl_getmatrix,          METH_OLDARGS},
+	{"altgetmatrix", gl_altgetmatrix,    METH_OLDARGS},
+	{"lrectwrite", gl_lrectwrite,        METH_OLDARGS},
+	{"lrectread", gl_lrectread,          METH_OLDARGS},
+	{"readdisplay", gl_readdisplay,      METH_OLDARGS},
+	{"packrect", gl_packrect,            METH_OLDARGS},
+	{"unpackrect", gl_unpackrect,        METH_OLDARGS},
+	{"gversion", gl_gversion,            METH_OLDARGS},
+	{"clear", gl_clear,                  METH_OLDARGS},
+	{"getshade", gl_getshade,            METH_OLDARGS},
+	{"devport", gl_devport,              METH_OLDARGS},
+	{"rdr2i", gl_rdr2i,                  METH_OLDARGS},
+	{"rectfs", gl_rectfs,                METH_OLDARGS},
+	{"rects", gl_rects,                  METH_OLDARGS},
+	{"rmv2i", gl_rmv2i,                  METH_OLDARGS},
+	{"noport", gl_noport,                METH_OLDARGS},
+	{"popviewport", gl_popviewport,      METH_OLDARGS},
+	{"clearhitcode", gl_clearhitcode,    METH_OLDARGS},
+	{"closeobj", gl_closeobj,            METH_OLDARGS},
+	{"cursoff", gl_cursoff,              METH_OLDARGS},
+	{"curson", gl_curson,                METH_OLDARGS},
+	{"doublebuffer", gl_doublebuffer,    METH_OLDARGS},
+	{"finish", gl_finish,                METH_OLDARGS},
+	{"gconfig", gl_gconfig,              METH_OLDARGS},
+	{"ginit", gl_ginit,                  METH_OLDARGS},
+	{"greset", gl_greset,                METH_OLDARGS},
+	{"multimap", gl_multimap,            METH_OLDARGS},
+	{"onemap", gl_onemap,                METH_OLDARGS},
+	{"popattributes", gl_popattributes,  METH_OLDARGS},
+	{"popmatrix", gl_popmatrix,          METH_OLDARGS},
+	{"pushattributes", gl_pushattributes,METH_OLDARGS},
+	{"pushmatrix", gl_pushmatrix,        METH_OLDARGS},
+	{"pushviewport", gl_pushviewport,    METH_OLDARGS},
+	{"qreset", gl_qreset,                METH_OLDARGS},
+	{"RGBmode", gl_RGBmode,              METH_OLDARGS},
+	{"singlebuffer", gl_singlebuffer,    METH_OLDARGS},
+	{"swapbuffers", gl_swapbuffers,      METH_OLDARGS},
+	{"gsync", gl_gsync,                  METH_OLDARGS},
+	{"gflush", gl_gflush,                METH_OLDARGS},
+	{"tpon", gl_tpon,                    METH_OLDARGS},
+	{"tpoff", gl_tpoff,                  METH_OLDARGS},
+	{"clkon", gl_clkon,                  METH_OLDARGS},
+	{"clkoff", gl_clkoff,                METH_OLDARGS},
+	{"ringbell", gl_ringbell,            METH_OLDARGS},
+	{"gbegin", gl_gbegin,                METH_OLDARGS},
+	{"textinit", gl_textinit,            METH_OLDARGS},
+	{"initnames", gl_initnames,          METH_OLDARGS},
+	{"pclos", gl_pclos,                  METH_OLDARGS},
+	{"popname", gl_popname,              METH_OLDARGS},
+	{"spclos", gl_spclos,                METH_OLDARGS},
+	{"zclear", gl_zclear,                METH_OLDARGS},
+	{"screenspace", gl_screenspace,      METH_OLDARGS},
+	{"reshapeviewport", gl_reshapeviewport, METH_OLDARGS},
+	{"winpush", gl_winpush,              METH_OLDARGS},
+	{"winpop", gl_winpop,                METH_OLDARGS},
+	{"foreground", gl_foreground,        METH_OLDARGS},
+	{"endfullscrn", gl_endfullscrn,      METH_OLDARGS},
+	{"endpupmode", gl_endpupmode,        METH_OLDARGS},
+	{"fullscrn", gl_fullscrn,            METH_OLDARGS},
+	{"pupmode", gl_pupmode,              METH_OLDARGS},
+	{"winconstraints", gl_winconstraints, METH_OLDARGS},
+	{"pagecolor", gl_pagecolor,          METH_OLDARGS},
+	{"textcolor", gl_textcolor,          METH_OLDARGS},
+	{"color", gl_color,                  METH_OLDARGS},
+	{"curveit", gl_curveit,              METH_OLDARGS},
+	{"font", gl_font,                    METH_OLDARGS},
+	{"linewidth", gl_linewidth,          METH_OLDARGS},
+	{"setlinestyle", gl_setlinestyle,    METH_OLDARGS},
+	{"setmap", gl_setmap,                METH_OLDARGS},
+	{"swapinterval", gl_swapinterval,    METH_OLDARGS},
+	{"writemask", gl_writemask,          METH_OLDARGS},
+	{"textwritemask", gl_textwritemask,  METH_OLDARGS},
+	{"qdevice", gl_qdevice,              METH_OLDARGS},
+	{"unqdevice", gl_unqdevice,          METH_OLDARGS},
+	{"curvebasis", gl_curvebasis,        METH_OLDARGS},
+	{"curveprecision", gl_curveprecision,METH_OLDARGS},
+	{"loadname", gl_loadname,            METH_OLDARGS},
+	{"passthrough", gl_passthrough,      METH_OLDARGS},
+	{"pushname", gl_pushname,            METH_OLDARGS},
+	{"setmonitor", gl_setmonitor,        METH_OLDARGS},
+	{"setshade", gl_setshade,            METH_OLDARGS},
+	{"setpattern", gl_setpattern,        METH_OLDARGS},
+	{"pagewritemask", gl_pagewritemask,  METH_OLDARGS},
+	{"callobj", gl_callobj,              METH_OLDARGS},
+	{"delobj", gl_delobj,                METH_OLDARGS},
+	{"editobj", gl_editobj,              METH_OLDARGS},
+	{"makeobj", gl_makeobj,              METH_OLDARGS},
+	{"maketag", gl_maketag,              METH_OLDARGS},
+	{"chunksize", gl_chunksize,          METH_OLDARGS},
+	{"compactify", gl_compactify,        METH_OLDARGS},
+	{"deltag", gl_deltag,                METH_OLDARGS},
+	{"lsrepeat", gl_lsrepeat,            METH_OLDARGS},
+	{"objinsert", gl_objinsert,          METH_OLDARGS},
+	{"objreplace", gl_objreplace,        METH_OLDARGS},
+	{"winclose", gl_winclose,            METH_OLDARGS},
+	{"blanktime", gl_blanktime,          METH_OLDARGS},
+	{"freepup", gl_freepup,              METH_OLDARGS},
+	{"backbuffer", gl_backbuffer,        METH_OLDARGS},
+	{"frontbuffer", gl_frontbuffer,      METH_OLDARGS},
+	{"lsbackup", gl_lsbackup,            METH_OLDARGS},
+	{"resetls", gl_resetls,              METH_OLDARGS},
+	{"lampon", gl_lampon,                METH_OLDARGS},
+	{"lampoff", gl_lampoff,              METH_OLDARGS},
+	{"setbell", gl_setbell,              METH_OLDARGS},
+	{"blankscreen", gl_blankscreen,      METH_OLDARGS},
+	{"depthcue", gl_depthcue,            METH_OLDARGS},
+	{"zbuffer", gl_zbuffer,              METH_OLDARGS},
+	{"backface", gl_backface,            METH_OLDARGS},
+	{"cmov2i", gl_cmov2i,                METH_OLDARGS},
+	{"draw2i", gl_draw2i,                METH_OLDARGS},
+	{"move2i", gl_move2i,                METH_OLDARGS},
+	{"pnt2i", gl_pnt2i,                  METH_OLDARGS},
+	{"patchbasis", gl_patchbasis,        METH_OLDARGS},
+	{"patchprecision", gl_patchprecision, METH_OLDARGS},
+	{"pdr2i", gl_pdr2i,                  METH_OLDARGS},
+	{"pmv2i", gl_pmv2i,                  METH_OLDARGS},
+	{"rpdr2i", gl_rpdr2i,                METH_OLDARGS},
+	{"rpmv2i", gl_rpmv2i,                METH_OLDARGS},
+	{"xfpt2i", gl_xfpt2i,                METH_OLDARGS},
+	{"objdelete", gl_objdelete,          METH_OLDARGS},
+	{"patchcurves", gl_patchcurves,      METH_OLDARGS},
+	{"minsize", gl_minsize,              METH_OLDARGS},
+	{"maxsize", gl_maxsize,              METH_OLDARGS},
+	{"keepaspect", gl_keepaspect,        METH_OLDARGS},
+	{"prefsize", gl_prefsize,            METH_OLDARGS},
+	{"stepunit", gl_stepunit,            METH_OLDARGS},
+	{"fudge", gl_fudge,                  METH_OLDARGS},
+	{"winmove", gl_winmove,              METH_OLDARGS},
+	{"attachcursor", gl_attachcursor,    METH_OLDARGS},
+	{"deflinestyle", gl_deflinestyle,    METH_OLDARGS},
+	{"noise", gl_noise,                  METH_OLDARGS},
+	{"picksize", gl_picksize,            METH_OLDARGS},
+	{"qenter", gl_qenter,                METH_OLDARGS},
+	{"setdepth", gl_setdepth,            METH_OLDARGS},
+	{"cmov2s", gl_cmov2s,                METH_OLDARGS},
+	{"draw2s", gl_draw2s,                METH_OLDARGS},
+	{"move2s", gl_move2s,                METH_OLDARGS},
+	{"pdr2s", gl_pdr2s,                  METH_OLDARGS},
+	{"pmv2s", gl_pmv2s,                  METH_OLDARGS},
+	{"pnt2s", gl_pnt2s,                  METH_OLDARGS},
+	{"rdr2s", gl_rdr2s,                  METH_OLDARGS},
+	{"rmv2s", gl_rmv2s,                  METH_OLDARGS},
+	{"rpdr2s", gl_rpdr2s,                METH_OLDARGS},
+	{"rpmv2s", gl_rpmv2s,                METH_OLDARGS},
+	{"xfpt2s", gl_xfpt2s,                METH_OLDARGS},
+	{"cmov2", gl_cmov2,                  METH_OLDARGS},
+	{"draw2", gl_draw2,                  METH_OLDARGS},
+	{"move2", gl_move2,                  METH_OLDARGS},
+	{"pnt2", gl_pnt2,                    METH_OLDARGS},
+	{"pdr2", gl_pdr2,                    METH_OLDARGS},
+	{"pmv2", gl_pmv2,                    METH_OLDARGS},
+	{"rdr2", gl_rdr2,                    METH_OLDARGS},
+	{"rmv2", gl_rmv2,                    METH_OLDARGS},
+	{"rpdr2", gl_rpdr2,                  METH_OLDARGS},
+	{"rpmv2", gl_rpmv2,                  METH_OLDARGS},
+	{"xfpt2", gl_xfpt2,                  METH_OLDARGS},
+	{"loadmatrix", gl_loadmatrix,        METH_OLDARGS},
+	{"multmatrix", gl_multmatrix,        METH_OLDARGS},
+	{"crv", gl_crv,                      METH_OLDARGS},
+	{"rcrv", gl_rcrv,                    METH_OLDARGS},
+	{"addtopup", gl_addtopup,            METH_OLDARGS},
+	{"charstr", gl_charstr,              METH_OLDARGS},
+	{"getport", gl_getport,              METH_OLDARGS},
+	{"strwidth", gl_strwidth,            METH_OLDARGS},
+	{"winopen", gl_winopen,              METH_OLDARGS},
+	{"wintitle", gl_wintitle,            METH_OLDARGS},
+	{"polf", gl_polf,                    METH_OLDARGS},
+	{"polf2", gl_polf2,                  METH_OLDARGS},
+	{"poly", gl_poly,                    METH_OLDARGS},
+	{"poly2", gl_poly2,                  METH_OLDARGS},
+	{"crvn", gl_crvn,                    METH_OLDARGS},
+	{"rcrvn", gl_rcrvn,                  METH_OLDARGS},
+	{"polf2i", gl_polf2i,                METH_OLDARGS},
+	{"polfi", gl_polfi,                  METH_OLDARGS},
+	{"poly2i", gl_poly2i,                METH_OLDARGS},
+	{"polyi", gl_polyi,                  METH_OLDARGS},
+	{"polf2s", gl_polf2s,                METH_OLDARGS},
+	{"polfs", gl_polfs,                  METH_OLDARGS},
+	{"polys", gl_polys,                  METH_OLDARGS},
+	{"poly2s", gl_poly2s,                METH_OLDARGS},
+	{"defcursor", gl_defcursor,          METH_OLDARGS},
+	{"writepixels", gl_writepixels,      METH_OLDARGS},
+	{"defbasis", gl_defbasis,            METH_OLDARGS},
+	{"gewrite", gl_gewrite,              METH_OLDARGS},
+	{"rotate", gl_rotate,                METH_OLDARGS},
+	{"rot", gl_rot,                      METH_OLDARGS},
+	{"circfi", gl_circfi,                METH_OLDARGS},
+	{"circi", gl_circi,                  METH_OLDARGS},
+	{"cmovi", gl_cmovi,                  METH_OLDARGS},
+	{"drawi", gl_drawi,                  METH_OLDARGS},
+	{"movei", gl_movei,                  METH_OLDARGS},
+	{"pnti", gl_pnti,                    METH_OLDARGS},
+	{"newtag", gl_newtag,                METH_OLDARGS},
+	{"pdri", gl_pdri,                    METH_OLDARGS},
+	{"pmvi", gl_pmvi,                    METH_OLDARGS},
+	{"rdri", gl_rdri,                    METH_OLDARGS},
+	{"rmvi", gl_rmvi,                    METH_OLDARGS},
+	{"rpdri", gl_rpdri,                  METH_OLDARGS},
+	{"rpmvi", gl_rpmvi,                  METH_OLDARGS},
+	{"xfpti", gl_xfpti,                  METH_OLDARGS},
+	{"circ", gl_circ,                    METH_OLDARGS},
+	{"circf", gl_circf,                  METH_OLDARGS},
+	{"cmov", gl_cmov,                    METH_OLDARGS},
+	{"draw", gl_draw,                    METH_OLDARGS},
+	{"move", gl_move,                    METH_OLDARGS},
+	{"pnt", gl_pnt,                      METH_OLDARGS},
+	{"scale", gl_scale,                  METH_OLDARGS},
+	{"translate", gl_translate,          METH_OLDARGS},
+	{"pdr", gl_pdr,                      METH_OLDARGS},
+	{"pmv", gl_pmv,                      METH_OLDARGS},
+	{"rdr", gl_rdr,                      METH_OLDARGS},
+	{"rmv", gl_rmv,                      METH_OLDARGS},
+	{"rpdr", gl_rpdr,                    METH_OLDARGS},
+	{"rpmv", gl_rpmv,                    METH_OLDARGS},
+	{"xfpt", gl_xfpt,                    METH_OLDARGS},
+	{"RGBcolor", gl_RGBcolor,            METH_OLDARGS},
+	{"RGBwritemask", gl_RGBwritemask,    METH_OLDARGS},
+	{"setcursor", gl_setcursor,          METH_OLDARGS},
+	{"tie", gl_tie,                      METH_OLDARGS},
+	{"circfs", gl_circfs,                METH_OLDARGS},
+	{"circs", gl_circs,                  METH_OLDARGS},
+	{"cmovs", gl_cmovs,                  METH_OLDARGS},
+	{"draws", gl_draws,                  METH_OLDARGS},
+	{"moves", gl_moves,                  METH_OLDARGS},
+	{"pdrs", gl_pdrs,                    METH_OLDARGS},
+	{"pmvs", gl_pmvs,                    METH_OLDARGS},
+	{"pnts", gl_pnts,                    METH_OLDARGS},
+	{"rdrs", gl_rdrs,                    METH_OLDARGS},
+	{"rmvs", gl_rmvs,                    METH_OLDARGS},
+	{"rpdrs", gl_rpdrs,                  METH_OLDARGS},
+	{"rpmvs", gl_rpmvs,                  METH_OLDARGS},
+	{"xfpts", gl_xfpts,                  METH_OLDARGS},
+	{"curorigin", gl_curorigin,          METH_OLDARGS},
+	{"cyclemap", gl_cyclemap,            METH_OLDARGS},
+	{"patch", gl_patch,                  METH_OLDARGS},
+	{"splf", gl_splf,                    METH_OLDARGS},
+	{"splf2", gl_splf2,                  METH_OLDARGS},
+	{"splfi", gl_splfi,                  METH_OLDARGS},
+	{"splf2i", gl_splf2i,                METH_OLDARGS},
+	{"splfs", gl_splfs,                  METH_OLDARGS},
+	{"splf2s", gl_splf2s,                METH_OLDARGS},
+	{"rpatch", gl_rpatch,                METH_OLDARGS},
+	{"ortho2", gl_ortho2,                METH_OLDARGS},
+	{"rect", gl_rect,                    METH_OLDARGS},
+	{"rectf", gl_rectf,                  METH_OLDARGS},
+	{"xfpt4", gl_xfpt4,                  METH_OLDARGS},
+	{"textport", gl_textport,            METH_OLDARGS},
+	{"mapcolor", gl_mapcolor,            METH_OLDARGS},
+	{"scrmask", gl_scrmask,              METH_OLDARGS},
+	{"setvaluator", gl_setvaluator,      METH_OLDARGS},
+	{"viewport", gl_viewport,            METH_OLDARGS},
+	{"shaderange", gl_shaderange,        METH_OLDARGS},
+	{"xfpt4s", gl_xfpt4s,                METH_OLDARGS},
+	{"rectfi", gl_rectfi,                METH_OLDARGS},
+	{"recti", gl_recti,                  METH_OLDARGS},
+	{"xfpt4i", gl_xfpt4i,                METH_OLDARGS},
+	{"prefposition", gl_prefposition,    METH_OLDARGS},
+	{"arc", gl_arc,                      METH_OLDARGS},
+	{"arcf", gl_arcf,                    METH_OLDARGS},
+	{"arcfi", gl_arcfi,                  METH_OLDARGS},
+	{"arci", gl_arci,                    METH_OLDARGS},
+	{"bbox2", gl_bbox2,                  METH_OLDARGS},
+	{"bbox2i", gl_bbox2i,                METH_OLDARGS},
+	{"bbox2s", gl_bbox2s,                METH_OLDARGS},
+	{"blink", gl_blink,                  METH_OLDARGS},
+	{"ortho", gl_ortho,                  METH_OLDARGS},
+	{"window", gl_window,                METH_OLDARGS},
+	{"lookat", gl_lookat,                METH_OLDARGS},
+	{"perspective", gl_perspective,      METH_OLDARGS},
+	{"polarview", gl_polarview,          METH_OLDARGS},
+	{"arcfs", gl_arcfs,                  METH_OLDARGS},
+	{"arcs", gl_arcs,                    METH_OLDARGS},
+	{"rectcopy", gl_rectcopy,            METH_OLDARGS},
+	{"RGBcursor", gl_RGBcursor,          METH_OLDARGS},
+	{"getbutton", gl_getbutton,          METH_OLDARGS},
+	{"getcmmode", gl_getcmmode,          METH_OLDARGS},
+	{"getlsbackup", gl_getlsbackup,      METH_OLDARGS},
+	{"getresetls", gl_getresetls,        METH_OLDARGS},
+	{"getdcm", gl_getdcm,                METH_OLDARGS},
+	{"getzbuffer", gl_getzbuffer,        METH_OLDARGS},
+	{"ismex", gl_ismex,                  METH_OLDARGS},
+	{"isobj", gl_isobj,                  METH_OLDARGS},
+	{"isqueued", gl_isqueued,            METH_OLDARGS},
+	{"istag", gl_istag,                  METH_OLDARGS},
+	{"genobj", gl_genobj,                METH_OLDARGS},
+	{"gentag", gl_gentag,                METH_OLDARGS},
+	{"getbuffer", gl_getbuffer,          METH_OLDARGS},
+	{"getcolor", gl_getcolor,            METH_OLDARGS},
+	{"getdisplaymode", gl_getdisplaymode, METH_OLDARGS},
+	{"getfont", gl_getfont,              METH_OLDARGS},
+	{"getheight", gl_getheight,          METH_OLDARGS},
+	{"gethitcode", gl_gethitcode,        METH_OLDARGS},
+	{"getlstyle", gl_getlstyle,          METH_OLDARGS},
+	{"getlwidth", gl_getlwidth,          METH_OLDARGS},
+	{"getmap", gl_getmap,                METH_OLDARGS},
+	{"getplanes", gl_getplanes,          METH_OLDARGS},
+	{"getwritemask", gl_getwritemask,    METH_OLDARGS},
+	{"qtest", gl_qtest,                  METH_OLDARGS},
+	{"getlsrepeat", gl_getlsrepeat,      METH_OLDARGS},
+	{"getmonitor", gl_getmonitor,        METH_OLDARGS},
+	{"getopenobj", gl_getopenobj,        METH_OLDARGS},
+	{"getpattern", gl_getpattern,        METH_OLDARGS},
+	{"winget", gl_winget,                METH_OLDARGS},
+	{"winattach", gl_winattach,          METH_OLDARGS},
+	{"getothermonitor", gl_getothermonitor, METH_OLDARGS},
+	{"newpup", gl_newpup,                METH_OLDARGS},
+	{"getvaluator", gl_getvaluator,      METH_OLDARGS},
+	{"winset", gl_winset,                METH_OLDARGS},
+	{"dopup", gl_dopup,                  METH_OLDARGS},
+	{"getdepth", gl_getdepth,            METH_OLDARGS},
+	{"getcpos", gl_getcpos,              METH_OLDARGS},
+	{"getsize", gl_getsize,              METH_OLDARGS},
+	{"getorigin", gl_getorigin,          METH_OLDARGS},
+	{"getviewport", gl_getviewport,      METH_OLDARGS},
+	{"gettp", gl_gettp,                  METH_OLDARGS},
+	{"getgpos", gl_getgpos,              METH_OLDARGS},
+	{"winposition", gl_winposition,      METH_OLDARGS},
+	{"gRGBcolor", gl_gRGBcolor,          METH_OLDARGS},
+	{"gRGBmask", gl_gRGBmask,            METH_OLDARGS},
+	{"getscrmask", gl_getscrmask,        METH_OLDARGS},
+	{"getmcolor", gl_getmcolor,          METH_OLDARGS},
+	{"mapw", gl_mapw,                    METH_OLDARGS},
+	{"mapw2", gl_mapw2,                  METH_OLDARGS},
+	{"getcursor", gl_getcursor,          METH_OLDARGS},
+	{"cmode", gl_cmode,                  METH_OLDARGS},
+	{"concave", gl_concave,              METH_OLDARGS},
+	{"curstype", gl_curstype,            METH_OLDARGS},
+	{"drawmode", gl_drawmode,            METH_OLDARGS},
+	{"gammaramp", gl_gammaramp,          METH_OLDARGS},
+	{"getbackface", gl_getbackface,      METH_OLDARGS},
+	{"getdescender", gl_getdescender,    METH_OLDARGS},
+	{"getdrawmode", gl_getdrawmode,      METH_OLDARGS},
+	{"getmmode", gl_getmmode,            METH_OLDARGS},
+	{"getsm", gl_getsm,                  METH_OLDARGS},
+	{"getvideo", gl_getvideo,            METH_OLDARGS},
+	{"imakebackground", gl_imakebackground, METH_OLDARGS},
+	{"lmbind", gl_lmbind,                METH_OLDARGS},
+	{"lmdef", gl_lmdef,                  METH_OLDARGS},
+	{"mmode", gl_mmode,                  METH_OLDARGS},
+	{"normal", gl_normal,                METH_OLDARGS},
+	{"overlay", gl_overlay,              METH_OLDARGS},
+	{"RGBrange", gl_RGBrange,            METH_OLDARGS},
+	{"setvideo", gl_setvideo,            METH_OLDARGS},
+	{"shademodel", gl_shademodel,        METH_OLDARGS},
+	{"underlay", gl_underlay,            METH_OLDARGS},
+	{"bgnclosedline", gl_bgnclosedline,  METH_OLDARGS},
+	{"bgnline", gl_bgnline,              METH_OLDARGS},
+	{"bgnpoint", gl_bgnpoint,            METH_OLDARGS},
+	{"bgnpolygon", gl_bgnpolygon,        METH_OLDARGS},
+	{"bgnsurface", gl_bgnsurface,        METH_OLDARGS},
+	{"bgntmesh", gl_bgntmesh,            METH_OLDARGS},
+	{"bgntrim", gl_bgntrim,              METH_OLDARGS},
+	{"endclosedline", gl_endclosedline,  METH_OLDARGS},
+	{"endline", gl_endline,              METH_OLDARGS},
+	{"endpoint", gl_endpoint,            METH_OLDARGS},
+	{"endpolygon", gl_endpolygon,        METH_OLDARGS},
+	{"endsurface", gl_endsurface,        METH_OLDARGS},
+	{"endtmesh", gl_endtmesh,            METH_OLDARGS},
+	{"endtrim", gl_endtrim,              METH_OLDARGS},
+	{"blendfunction", gl_blendfunction,  METH_OLDARGS},
+	{"c3f", gl_c3f,                      METH_OLDARGS},
+	{"c3i", gl_c3i,                      METH_OLDARGS},
+	{"c3s", gl_c3s,                      METH_OLDARGS},
+	{"c4f", gl_c4f,                      METH_OLDARGS},
+	{"c4i", gl_c4i,                      METH_OLDARGS},
+	{"c4s", gl_c4s,                      METH_OLDARGS},
+	{"colorf", gl_colorf,                METH_OLDARGS},
+	{"cpack", gl_cpack,                  METH_OLDARGS},
+	{"czclear", gl_czclear,              METH_OLDARGS},
+	{"dglclose", gl_dglclose,            METH_OLDARGS},
+	{"dglopen", gl_dglopen,              METH_OLDARGS},
+	{"getgdesc", gl_getgdesc,            METH_OLDARGS},
+	{"getnurbsproperty", gl_getnurbsproperty, METH_OLDARGS},
+	{"glcompat", gl_glcompat,            METH_OLDARGS},
+	{"iconsize", gl_iconsize,            METH_OLDARGS},
+	{"icontitle", gl_icontitle,          METH_OLDARGS},
+	{"lRGBrange", gl_lRGBrange,          METH_OLDARGS},
+	{"linesmooth", gl_linesmooth,        METH_OLDARGS},
+	{"lmcolor", gl_lmcolor,              METH_OLDARGS},
+	{"logicop", gl_logicop,              METH_OLDARGS},
+	{"lsetdepth", gl_lsetdepth,          METH_OLDARGS},
+	{"lshaderange", gl_lshaderange,      METH_OLDARGS},
+	{"n3f", gl_n3f,                      METH_OLDARGS},
+	{"noborder", gl_noborder,            METH_OLDARGS},
+	{"pntsmooth", gl_pntsmooth,          METH_OLDARGS},
+	{"readsource", gl_readsource,        METH_OLDARGS},
+	{"rectzoom", gl_rectzoom,            METH_OLDARGS},
+	{"sbox", gl_sbox,                    METH_OLDARGS},
+	{"sboxi", gl_sboxi,                  METH_OLDARGS},
+	{"sboxs", gl_sboxs,                  METH_OLDARGS},
+	{"sboxf", gl_sboxf,                  METH_OLDARGS},
+	{"sboxfi", gl_sboxfi,                METH_OLDARGS},
+	{"sboxfs", gl_sboxfs,                METH_OLDARGS},
+	{"setnurbsproperty", gl_setnurbsproperty, METH_OLDARGS},
+	{"setpup", gl_setpup,                METH_OLDARGS},
+	{"smoothline", gl_smoothline,        METH_OLDARGS},
+	{"subpixel", gl_subpixel,            METH_OLDARGS},
+	{"swaptmesh", gl_swaptmesh,          METH_OLDARGS},
+	{"swinopen", gl_swinopen,            METH_OLDARGS},
+	{"v2f", gl_v2f,                      METH_OLDARGS},
+	{"v2i", gl_v2i,                      METH_OLDARGS},
+	{"v2s", gl_v2s,                      METH_OLDARGS},
+	{"v3f", gl_v3f,                      METH_OLDARGS},
+	{"v3i", gl_v3i,                      METH_OLDARGS},
+	{"v3s", gl_v3s,                      METH_OLDARGS},
+	{"v4f", gl_v4f,                      METH_OLDARGS},
+	{"v4i", gl_v4i,                      METH_OLDARGS},
+	{"v4s", gl_v4s,                      METH_OLDARGS},
+	{"videocmd", gl_videocmd,            METH_OLDARGS},
+	{"windepth", gl_windepth,            METH_OLDARGS},
+	{"wmpack", gl_wmpack,                METH_OLDARGS},
+	{"zdraw", gl_zdraw,                  METH_OLDARGS},
+	{"zfunction", gl_zfunction,          METH_OLDARGS},
+	{"zsource", gl_zsource,              METH_OLDARGS},
+	{"zwritemask", gl_zwritemask,        METH_OLDARGS},
+	{"v2d", gl_v2d,                      METH_OLDARGS},
+	{"v3d", gl_v3d,                      METH_OLDARGS},
+	{"v4d", gl_v4d,                      METH_OLDARGS},
+	{"pixmode", gl_pixmode,              METH_OLDARGS},
+	{"qgetfd", gl_qgetfd,                METH_OLDARGS},
+	{"dither", gl_dither,                METH_OLDARGS},
+	{NULL, NULL} /* Sentinel */
+};
+
+void
+initgl(void)
+{
+	(void) Py_InitModule("gl", gl_methods);
+}

Added: vendor/Python/current/Modules/grpmodule.c
===================================================================
--- vendor/Python/current/Modules/grpmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/grpmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,194 @@
+
+/* UNIX group file access module */
+
+#include "Python.h"
+#include "structseq.h"
+
+#include <sys/types.h>
+#include <grp.h>
+
+static PyStructSequence_Field struct_group_type_fields[] = {
+   {"gr_name", "group name"},
+   {"gr_passwd", "password"},
+   {"gr_gid", "group id"}, 
+   {"gr_mem", "group memebers"}, 
+   {0}
+};
+
+PyDoc_STRVAR(struct_group__doc__,
+"grp.struct_group: Results from getgr*() routines.\n\n\
+This object may be accessed either as a tuple of\n\
+  (gr_name,gr_passwd,gr_gid,gr_mem)\n\
+or via the object attributes as named in the above tuple.\n");
+
+static PyStructSequence_Desc struct_group_type_desc = {
+   "grp.struct_group",
+   struct_group__doc__,
+   struct_group_type_fields,
+   4,
+};
+
+
+static int initialized;
+static PyTypeObject StructGrpType;
+
+static PyObject *
+mkgrent(struct group *p)
+{
+    int setIndex = 0;
+    PyObject *v = PyStructSequence_New(&StructGrpType), *w;
+    char **member;
+
+    if (v == NULL)
+        return NULL;
+
+    if ((w = PyList_New(0)) == NULL) {
+        Py_DECREF(v);
+        return NULL;
+    }
+    for (member = p->gr_mem; *member != NULL; member++) {
+        PyObject *x = PyString_FromString(*member);
+        if (x == NULL || PyList_Append(w, x) != 0) {
+            Py_XDECREF(x);
+            Py_DECREF(w);
+            Py_DECREF(v);
+            return NULL;
+        }
+        Py_DECREF(x);
+    }
+
+#define SET(i,val) PyStructSequence_SET_ITEM(v, i, val)
+    SET(setIndex++, PyString_FromString(p->gr_name));
+#ifdef __VMS
+    SET(setIndex++, Py_None);
+    Py_INCREF(Py_None);
+#else
+    if (p->gr_passwd)
+	    SET(setIndex++, PyString_FromString(p->gr_passwd));
+    else {
+	    SET(setIndex++, Py_None);
+	    Py_INCREF(Py_None);
+    }
+#endif
+    SET(setIndex++, PyInt_FromLong((long) p->gr_gid));
+    SET(setIndex++, w);
+#undef SET
+
+    if (PyErr_Occurred()) {
+        Py_DECREF(v);
+        Py_DECREF(w);
+        return NULL;
+    }
+
+    return v;
+}
+
+static PyObject *
+grp_getgrgid(PyObject *self, PyObject *pyo_id)
+{
+    PyObject *py_int_id;
+    unsigned int gid;
+    struct group *p;
+
+    py_int_id = PyNumber_Int(pyo_id);
+    if (!py_int_id)
+	    return NULL;
+    gid = PyInt_AS_LONG(py_int_id);
+    Py_DECREF(py_int_id);
+
+    if ((p = getgrgid(gid)) == NULL) {
+	PyErr_Format(PyExc_KeyError, "getgrgid(): gid not found: %d", gid);
+        return NULL;
+    }
+    return mkgrent(p);
+}
+
+static PyObject *
+grp_getgrnam(PyObject *self, PyObject *pyo_name)
+{
+    PyObject *py_str_name;
+    char *name;
+    struct group *p;
+
+    py_str_name = PyObject_Str(pyo_name);
+    if (!py_str_name)
+	    return NULL;
+    name = PyString_AS_STRING(py_str_name);
+    
+    if ((p = getgrnam(name)) == NULL) {
+	PyErr_Format(PyExc_KeyError, "getgrnam(): name not found: %s", name);
+	Py_DECREF(py_str_name);
+        return NULL;
+    }
+
+    Py_DECREF(py_str_name);
+    return mkgrent(p);
+}
+
+static PyObject *
+grp_getgrall(PyObject *self, PyObject *ignore)
+{
+    PyObject *d;
+    struct group *p;
+
+    if ((d = PyList_New(0)) == NULL)
+        return NULL;
+    setgrent();
+    while ((p = getgrent()) != NULL) {
+        PyObject *v = mkgrent(p);
+        if (v == NULL || PyList_Append(d, v) != 0) {
+            Py_XDECREF(v);
+            Py_DECREF(d);
+            return NULL;
+        }
+        Py_DECREF(v);
+    }
+    endgrent();
+    return d;
+}
+
+static PyMethodDef grp_methods[] = {
+    {"getgrgid",	grp_getgrgid,	METH_O,
+     "getgrgid(id) -> tuple\n\
+Return the group database entry for the given numeric group ID.  If\n\
+id is not valid, raise KeyError."},
+    {"getgrnam",	grp_getgrnam,	METH_O,
+     "getgrnam(name) -> tuple\n\
+Return the group database entry for the given group name.  If\n\
+name is not valid, raise KeyError."},
+    {"getgrall",	grp_getgrall,	METH_NOARGS,
+     "getgrall() -> list of tuples\n\
+Return a list of all available group entries, in arbitrary order."},
+    {NULL,		NULL}		/* sentinel */
+};
+
+PyDoc_STRVAR(grp__doc__,
+"Access to the Unix group database.\n\
+\n\
+Group entries are reported as 4-tuples containing the following fields\n\
+from the group database, in order:\n\
+\n\
+  name   - name of the group\n\
+  passwd - group password (encrypted); often empty\n\
+  gid    - numeric ID of the group\n\
+  mem    - list of members\n\
+\n\
+The gid is an integer, name and password are strings.  (Note that most\n\
+users are not explicitly listed as members of the groups they are in\n\
+according to the password database.  Check both databases to get\n\
+complete membership information.)");
+
+
+PyMODINIT_FUNC
+initgrp(void)
+{
+    PyObject *m, *d;
+    m = Py_InitModule3("grp", grp_methods, grp__doc__);
+    if (m == NULL)
+        return;
+    d = PyModule_GetDict(m);
+    if (!initialized)
+	    PyStructSequence_InitType(&StructGrpType, &struct_group_type_desc);
+    PyDict_SetItemString(d, "struct_group", (PyObject *) &StructGrpType);
+    initialized = 1;
+}

Added: vendor/Python/current/Modules/imageop.c
===================================================================
--- vendor/Python/current/Modules/imageop.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/imageop.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,785 @@
+
+/* imageopmodule - Various operations on pictures */
+
+#ifdef sun
+#define signed
+#endif
+
+#include "Python.h"
+
+#if SIZEOF_INT == 4
+typedef int Py_Int32;
+typedef unsigned int Py_UInt32;
+#else
+#if SIZEOF_LONG == 4
+typedef long Py_Int32;
+typedef unsigned long Py_UInt32;
+#else
+#error "No 4-byte integral type"
+#endif
+#endif
+
+#define CHARP(cp, xmax, x, y) ((char *)(cp+y*xmax+x))
+#define SHORTP(cp, xmax, x, y) ((short *)(cp+2*(y*xmax+x)))
+#define LONGP(cp, xmax, x, y) ((Py_Int32 *)(cp+4*(y*xmax+x)))
+
+static PyObject *ImageopError;
+static PyObject *ImageopDict;
+
+/* If this function returns true (the default if anything goes wrong), we're
+   behaving in a backward-compatible way with respect to how multi-byte pixels
+   are stored in the strings.  The code in this module was originally written
+   for an SGI which is a big-endian system, and so the old code assumed that
+   4-byte integers hold the R, G, and B values in a particular order.
+   However, on little-endian systems the order is reversed, and so not
+   actually compatible with what gl.lrectwrite and imgfile expect.
+   (gl.lrectwrite and imgfile are also SGI-specific, however, it is
+   conceivable that the data handled here comes from or goes to an SGI or that
+   it is otherwise used in the expectation that the byte order in the strings
+   is as specified.)
+
+   The function returns the value of the module variable
+   "backward_compatible", or 1 if the variable does not exist or is not an
+   int.
+ */
+
+static int
+imageop_backward_compatible(void)
+{
+	static PyObject *bcos;
+	PyObject *bco;
+	long rc;
+
+	if (ImageopDict == NULL) /* "cannot happen" */
+		return 1;
+	if (bcos == NULL) {
+		/* cache string object for future use */
+		bcos = PyString_FromString("backward_compatible");
+		if (bcos == NULL)
+			return 1;
+	}
+	bco = PyDict_GetItem(ImageopDict, bcos);
+	if (bco == NULL)
+		return 1;
+	if (!PyInt_Check(bco))
+		return 1;
+	rc = PyInt_AsLong(bco);
+	if (PyErr_Occurred()) {
+		/* not an integer, or too large, or something */
+		PyErr_Clear();
+		rc = 1;
+	}
+	return rc != 0;		/* convert to values 0, 1 */
+}
+
+static PyObject *
+imageop_crop(PyObject *self, PyObject *args)
+{
+	char *cp, *ncp;
+	short *nsp;
+	Py_Int32 *nlp;
+	int len, size, x, y, newx1, newx2, newy1, newy2;
+	int ix, iy, xstep, ystep;
+	PyObject *rv;
+
+	if ( !PyArg_ParseTuple(args, "s#iiiiiii", &cp, &len, &size, &x, &y,
+			  &newx1, &newy1, &newx2, &newy2) )
+		return 0;
+    
+	if ( size != 1 && size != 2 && size != 4 ) {
+		PyErr_SetString(ImageopError, "Size should be 1, 2 or 4");
+		return 0;
+	}
+	if ( len != size*x*y ) {
+		PyErr_SetString(ImageopError, "String has incorrect length");
+		return 0;
+	}
+	xstep = (newx1 < newx2)? 1 : -1;
+	ystep = (newy1 < newy2)? 1 : -1;
+    
+	rv = PyString_FromStringAndSize(NULL,
+			     (abs(newx2-newx1)+1)*(abs(newy2-newy1)+1)*size);
+	if ( rv == 0 )
+		return 0;
+	ncp = (char *)PyString_AsString(rv);
+	nsp = (short *)ncp;
+	nlp = (Py_Int32 *)ncp;
+	newy2 += ystep;
+	newx2 += xstep;
+	for( iy = newy1; iy != newy2; iy+=ystep ) {
+		for ( ix = newx1; ix != newx2; ix+=xstep ) {
+			if ( iy < 0 || iy >= y || ix < 0 || ix >= x ) {
+				if ( size == 1 )
+					*ncp++ = 0;
+				else
+					*nlp++ = 0;
+			} else {
+				if ( size == 1 )
+					*ncp++ = *CHARP(cp, x, ix, iy);
+				else if ( size == 2 )
+					*nsp++ = *SHORTP(cp, x, ix, iy);
+				else
+					*nlp++ = *LONGP(cp, x, ix, iy);
+			}
+		}
+	}
+	return rv;
+}
+ 
+static PyObject *
+imageop_scale(PyObject *self, PyObject *args)
+{
+	char *cp, *ncp;
+	short *nsp;
+	Py_Int32 *nlp;
+	int len, size, x, y, newx, newy;
+	int ix, iy;
+	int oix, oiy;
+	PyObject *rv;
+
+	if ( !PyArg_ParseTuple(args, "s#iiiii",
+			  &cp, &len, &size, &x, &y, &newx, &newy) )
+		return 0;
+    
+	if ( size != 1 && size != 2 && size != 4 ) {
+		PyErr_SetString(ImageopError, "Size should be 1, 2 or 4");
+		return 0;
+	}
+	if ( len != size*x*y ) {
+		PyErr_SetString(ImageopError, "String has incorrect length");
+		return 0;
+	}
+    
+	rv = PyString_FromStringAndSize(NULL, newx*newy*size);
+	if ( rv == 0 )
+		return 0;
+	ncp = (char *)PyString_AsString(rv);
+	nsp = (short *)ncp;
+	nlp = (Py_Int32 *)ncp;
+	for( iy = 0; iy < newy; iy++ ) {
+		for ( ix = 0; ix < newx; ix++ ) {
+			oix = ix * x / newx;
+			oiy = iy * y / newy;
+			if ( size == 1 )
+				*ncp++ = *CHARP(cp, x, oix, oiy);
+			else if ( size == 2 )
+				*nsp++ = *SHORTP(cp, x, oix, oiy);
+			else
+				*nlp++ = *LONGP(cp, x, oix, oiy);
+		}
+	}
+	return rv;
+}
+
+/* Note: this routine can use a bit of optimizing */
+
+static PyObject *
+imageop_tovideo(PyObject *self, PyObject *args)
+{
+	int maxx, maxy, x, y, len;
+	int i;
+	unsigned char *cp, *ncp;
+	int width;
+	PyObject *rv;
+   
+    
+	if ( !PyArg_ParseTuple(args, "s#iii", &cp, &len, &width, &maxx, &maxy) )
+		return 0;
+
+	if ( width != 1 && width != 4 ) {
+		PyErr_SetString(ImageopError, "Size should be 1 or 4");
+		return 0;
+	}
+	if ( maxx*maxy*width != len ) {
+		PyErr_SetString(ImageopError, "String has incorrect length");
+		return 0;
+	}
+    
+	rv = PyString_FromStringAndSize(NULL, len);
+	if ( rv == 0 )
+		return 0;
+	ncp = (unsigned char *)PyString_AsString(rv);
+
+	if ( width == 1 ) {
+		memcpy(ncp, cp, maxx);		/* Copy first line */
+		ncp += maxx;
+		for (y=1; y<maxy; y++) {	/* Interpolate other lines */
+			for(x=0; x<maxx; x++) {
+				i = y*maxx + x;
+				*ncp++ = ((int)cp[i] + (int)cp[i-maxx]) >> 1;
+			}
+		}
+	} else {
+		memcpy(ncp, cp, maxx*4);		/* Copy first line */
+		ncp += maxx*4;
+		for (y=1; y<maxy; y++) {	/* Interpolate other lines */
+			for(x=0; x<maxx; x++) {
+				i = (y*maxx + x)*4 + 1;
+				*ncp++ = 0;	/* Skip alfa comp */
+				*ncp++ = ((int)cp[i] + (int)cp[i-4*maxx]) >> 1;
+				i++;
+				*ncp++ = ((int)cp[i] + (int)cp[i-4*maxx]) >> 1;
+				i++;
+				*ncp++ = ((int)cp[i] + (int)cp[i-4*maxx]) >> 1;
+			}
+		}
+	}
+	return rv;
+}
+
+static PyObject *
+imageop_grey2mono(PyObject *self, PyObject *args)
+{
+	int tres, x, y, len;
+	unsigned char *cp, *ncp;
+	unsigned char ovalue;
+	PyObject *rv;
+	int i, bit;
+   
+    
+	if ( !PyArg_ParseTuple(args, "s#iii", &cp, &len, &x, &y, &tres) )
+		return 0;
+
+	if ( x*y != len ) {
+		PyErr_SetString(ImageopError, "String has incorrect length");
+		return 0;
+	}
+    
+	rv = PyString_FromStringAndSize(NULL, (len+7)/8);
+	if ( rv == 0 )
+		return 0;
+	ncp = (unsigned char *)PyString_AsString(rv);
+
+	bit = 0x80;
+	ovalue = 0;
+	for ( i=0; i < len; i++ ) {
+		if ( (int)cp[i] > tres )
+			ovalue |= bit;
+		bit >>= 1;
+		if ( bit == 0 ) {
+			*ncp++ = ovalue;
+			bit = 0x80;
+			ovalue = 0;
+		}
+	}
+	if ( bit != 0x80 )
+		*ncp++ = ovalue;
+	return rv;
+}
+
+static PyObject *
+imageop_grey2grey4(PyObject *self, PyObject *args)
+{
+	int x, y, len;
+	unsigned char *cp, *ncp;
+	unsigned char ovalue;
+	PyObject *rv;
+	int i;
+	int pos;
+   
+    
+	if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) )
+		return 0;
+
+	if ( x*y != len ) {
+		PyErr_SetString(ImageopError, "String has incorrect length");
+		return 0;
+	}
+    
+	rv = PyString_FromStringAndSize(NULL, (len+1)/2);
+	if ( rv == 0 )
+		return 0;
+	ncp = (unsigned char *)PyString_AsString(rv);
+	pos = 0;
+	ovalue = 0;
+	for ( i=0; i < len; i++ ) {
+		ovalue |= ((int)cp[i] & 0xf0) >> pos;
+		pos += 4;
+		if ( pos == 8 ) {
+			*ncp++ = ovalue;
+			ovalue = 0;
+			pos = 0;
+		}
+	}
+	if ( pos != 0 )
+		*ncp++ = ovalue;
+	return rv;
+}
+
+static PyObject *
+imageop_grey2grey2(PyObject *self, PyObject *args)
+{
+	int x, y, len;
+	unsigned char *cp, *ncp;
+	unsigned char ovalue;
+	PyObject *rv;
+	int i;
+	int pos;
+   
+    
+	if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) )
+		return 0;
+
+	if ( x*y != len ) {
+		PyErr_SetString(ImageopError, "String has incorrect length");
+		return 0;
+	}
+    
+	rv = PyString_FromStringAndSize(NULL, (len+3)/4);
+	if ( rv == 0 )
+		return 0;
+	ncp = (unsigned char *)PyString_AsString(rv);
+	pos = 0;
+	ovalue = 0;
+	for ( i=0; i < len; i++ ) {
+		ovalue |= ((int)cp[i] & 0xc0) >> pos;
+		pos += 2;
+		if ( pos == 8 ) {
+			*ncp++ = ovalue;
+			ovalue = 0;
+			pos = 0;
+		}
+	}
+	if ( pos != 0 )
+		*ncp++ = ovalue;
+	return rv;
+}
+
+static PyObject *
+imageop_dither2mono(PyObject *self, PyObject *args)
+{
+	int sum, x, y, len;
+	unsigned char *cp, *ncp;
+	unsigned char ovalue;
+	PyObject *rv;
+	int i, bit;
+   
+    
+	if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) )
+		return 0;
+
+	if ( x*y != len ) {
+		PyErr_SetString(ImageopError, "String has incorrect length");
+		return 0;
+	}
+    
+	rv = PyString_FromStringAndSize(NULL, (len+7)/8);
+	if ( rv == 0 )
+		return 0;
+	ncp = (unsigned char *)PyString_AsString(rv);
+
+	bit = 0x80;
+	ovalue = 0;
+	sum = 0;
+	for ( i=0; i < len; i++ ) {
+		sum += cp[i];
+		if ( sum >= 256 ) {
+			sum -= 256;
+			ovalue |= bit;
+		}
+		bit >>= 1;
+		if ( bit == 0 ) {
+			*ncp++ = ovalue;
+			bit = 0x80;
+			ovalue = 0;
+		}
+	}
+	if ( bit != 0x80 )
+		*ncp++ = ovalue;
+	return rv;
+}
+
+static PyObject *
+imageop_dither2grey2(PyObject *self, PyObject *args)
+{
+	int x, y, len;
+	unsigned char *cp, *ncp;
+	unsigned char ovalue;
+	PyObject *rv;
+	int i;
+	int pos;
+	int sum = 0, nvalue;
+   
+    
+	if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) )
+		return 0;
+
+	if ( x*y != len ) {
+		PyErr_SetString(ImageopError, "String has incorrect length");
+		return 0;
+	}
+    
+	rv = PyString_FromStringAndSize(NULL, (len+3)/4);
+	if ( rv == 0 )
+		return 0;
+	ncp = (unsigned char *)PyString_AsString(rv);
+	pos = 1;
+	ovalue = 0;
+	for ( i=0; i < len; i++ ) {
+		sum += cp[i];
+		nvalue = sum & 0x180;
+		sum -= nvalue;
+		ovalue |= nvalue >> pos;
+		pos += 2;
+		if ( pos == 9 ) {
+			*ncp++ = ovalue;
+			ovalue = 0;
+			pos = 1;
+		}
+	}
+	if ( pos != 0 )
+		*ncp++ = ovalue;
+	return rv;
+}
+
+static PyObject *
+imageop_mono2grey(PyObject *self, PyObject *args)
+{
+	int v0, v1, x, y, len, nlen;
+	unsigned char *cp, *ncp;
+	PyObject *rv;
+	int i, bit;
+    
+	if ( !PyArg_ParseTuple(args, "s#iiii", &cp, &len, &x, &y, &v0, &v1) )
+		return 0;
+
+	nlen = x*y;
+	if ( (nlen+7)/8 != len ) {
+		PyErr_SetString(ImageopError, "String has incorrect length");
+		return 0;
+	}
+    
+	rv = PyString_FromStringAndSize(NULL, nlen);
+	if ( rv == 0 )
+		return 0;
+	ncp = (unsigned char *)PyString_AsString(rv);
+
+	bit = 0x80;
+	for ( i=0; i < nlen; i++ ) {
+		if ( *cp & bit )
+			*ncp++ = v1;
+		else
+			*ncp++ = v0;
+		bit >>= 1;
+		if ( bit == 0 ) {
+			bit = 0x80;
+			cp++;
+		}
+	}
+	return rv;
+}
+
+static PyObject *
+imageop_grey22grey(PyObject *self, PyObject *args)
+{
+	int x, y, len, nlen;
+	unsigned char *cp, *ncp;
+	PyObject *rv;
+	int i, pos, value = 0, nvalue;
+    
+	if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) )
+		return 0;
+
+	nlen = x*y;
+	if ( (nlen+3)/4 != len ) {
+		PyErr_SetString(ImageopError, "String has incorrect length");
+		return 0;
+	}
+    
+	rv = PyString_FromStringAndSize(NULL, nlen);
+	if ( rv == 0 )
+		return 0;
+	ncp = (unsigned char *)PyString_AsString(rv);
+
+	pos = 0;
+	for ( i=0; i < nlen; i++ ) {
+		if ( pos == 0 ) {
+			value = *cp++;
+			pos = 8;
+		}
+		pos -= 2;
+		nvalue = (value >> pos) & 0x03;
+		*ncp++ = nvalue | (nvalue << 2) |
+			 (nvalue << 4) | (nvalue << 6);
+	}
+	return rv;
+}
+
+static PyObject *
+imageop_grey42grey(PyObject *self, PyObject *args)
+{
+	int x, y, len, nlen;
+	unsigned char *cp, *ncp;
+	PyObject *rv;
+	int i, pos, value = 0, nvalue;
+    
+	if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) )
+		return 0;
+
+	nlen = x*y;
+	if ( (nlen+1)/2 != len ) {
+		PyErr_SetString(ImageopError, "String has incorrect length");
+		return 0;
+	}
+    
+	rv = PyString_FromStringAndSize(NULL, nlen);
+	if ( rv == 0 )
+		return 0;
+	ncp = (unsigned char *)PyString_AsString(rv);
+
+	pos = 0;
+	for ( i=0; i < nlen; i++ ) {
+		if ( pos == 0 ) {
+			value = *cp++;
+			pos = 8;
+		}
+		pos -= 4;
+		nvalue = (value >> pos) & 0x0f;
+		*ncp++ = nvalue | (nvalue << 4);
+	}
+	return rv;
+}
+
+static PyObject *
+imageop_rgb2rgb8(PyObject *self, PyObject *args)
+{
+	int x, y, len, nlen;
+	unsigned char *cp;
+	unsigned char *ncp;
+	PyObject *rv;
+	int i, r, g, b;
+	int backward_compatible = imageop_backward_compatible();
+    
+	if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) )
+		return 0;
+
+	nlen = x*y;
+	if ( nlen*4 != len ) {
+		PyErr_SetString(ImageopError, "String has incorrect length");
+		return 0;
+	}
+    
+	rv = PyString_FromStringAndSize(NULL, nlen);
+	if ( rv == 0 )
+		return 0;
+	ncp = (unsigned char *)PyString_AsString(rv);
+
+	for ( i=0; i < nlen; i++ ) {
+		/* Bits in source: aaaaaaaa BBbbbbbb GGGggggg RRRrrrrr */
+		if (backward_compatible) {
+			Py_UInt32 value = * (Py_UInt32 *) cp;
+			cp += 4;
+			r = (int) ((value & 0xff) / 255. * 7. + .5);
+			g = (int) (((value >> 8) & 0xff) / 255. * 7. + .5);
+			b = (int) (((value >> 16) & 0xff) / 255. * 3. + .5);
+		} else {
+			cp++;		/* skip alpha channel */
+			b = (int) (*cp++ / 255. * 3. + .5);
+			g = (int) (*cp++ / 255. * 7. + .5);
+			r = (int) (*cp++ / 255. * 7. + .5);
+		}
+		*ncp++ = (unsigned char)((r<<5) | (b<<3) | g);
+	}
+	return rv;
+}
+
+static PyObject *
+imageop_rgb82rgb(PyObject *self, PyObject *args)
+{
+	int x, y, len, nlen;
+	unsigned char *cp;
+	unsigned char *ncp;
+	PyObject *rv;
+	int i, r, g, b;
+	unsigned char value;
+	int backward_compatible = imageop_backward_compatible();
+    
+	if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) )
+		return 0;
+
+	nlen = x*y;
+	if ( nlen != len ) {
+		PyErr_SetString(ImageopError, "String has incorrect length");
+		return 0;
+	}
+    
+	rv = PyString_FromStringAndSize(NULL, nlen*4);
+	if ( rv == 0 )
+		return 0;
+	ncp = (unsigned char *)PyString_AsString(rv);
+
+	for ( i=0; i < nlen; i++ ) {
+		/* Bits in source: RRRBBGGG
+		** Red and Green are multiplied by 36.5, Blue by 85
+		*/
+		value = *cp++;
+		r = (value >> 5) & 7;
+		g = (value     ) & 7;
+		b = (value >> 3) & 3;
+		r = (r<<5) | (r<<3) | (r>>1);
+		g = (g<<5) | (g<<3) | (g>>1);
+		b = (b<<6) | (b<<4) | (b<<2) | b;
+		if (backward_compatible) {
+			Py_UInt32 nvalue = r | (g<<8) | (b<<16);
+			* (Py_UInt32 *) ncp = nvalue;
+			ncp += 4;
+		} else {
+			*ncp++ = 0;
+			*ncp++ = b;
+			*ncp++ = g;
+			*ncp++ = r;
+		}
+	}
+	return rv;
+}
+
+static PyObject *
+imageop_rgb2grey(PyObject *self, PyObject *args)
+{
+	int x, y, len, nlen;
+	unsigned char *cp;
+	unsigned char *ncp;
+	PyObject *rv;
+	int i, r, g, b;
+	int nvalue;
+	int backward_compatible = imageop_backward_compatible();
+    
+	if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) )
+		return 0;
+
+	nlen = x*y;
+	if ( nlen*4 != len ) {
+		PyErr_SetString(ImageopError, "String has incorrect length");
+		return 0;
+	}
+    
+	rv = PyString_FromStringAndSize(NULL, nlen);
+	if ( rv == 0 )
+		return 0;
+	ncp = (unsigned char *)PyString_AsString(rv);
+
+	for ( i=0; i < nlen; i++ ) {
+		if (backward_compatible) {
+			Py_UInt32 value = * (Py_UInt32 *) cp;
+			cp += 4;
+			r = (int) ((value & 0xff) / 255. * 7. + .5);
+			g = (int) (((value >> 8) & 0xff) / 255. * 7. + .5);
+			b = (int) (((value >> 16) & 0xff) / 255. * 3. + .5);
+		} else {
+			cp++;		/* skip alpha channel */
+			b = *cp++;
+			g = *cp++;
+			r = *cp++;
+		}
+		nvalue = (int)(0.30*r + 0.59*g + 0.11*b);
+		if ( nvalue > 255 ) nvalue = 255;
+		*ncp++ = (unsigned char)nvalue;
+	}
+	return rv;
+}
+
+static PyObject *
+imageop_grey2rgb(PyObject *self, PyObject *args)
+{
+	int x, y, len, nlen;
+	unsigned char *cp;
+	unsigned char *ncp;
+	PyObject *rv;
+	int i;
+	unsigned char value;
+	int backward_compatible = imageop_backward_compatible();
+    
+	if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) )
+		return 0;
+
+	nlen = x*y;
+	if ( nlen != len ) {
+		PyErr_SetString(ImageopError, "String has incorrect length");
+		return 0;
+	}
+    
+	rv = PyString_FromStringAndSize(NULL, nlen*4);
+	if ( rv == 0 )
+		return 0;
+	ncp = (unsigned char *)PyString_AsString(rv);
+
+	for ( i=0; i < nlen; i++ ) {
+		value = *cp++;
+		if (backward_compatible) {
+			* (Py_UInt32 *) ncp = (Py_UInt32) value | ((Py_UInt32) value << 8 ) | ((Py_UInt32) value << 16);
+			ncp += 4;
+		} else {
+			*ncp++ = 0;
+			*ncp++ = value;
+			*ncp++ = value;
+			*ncp++ = value;
+		}
+	}
+	return rv;
+}
+
+/*
+static object *
+imageop_mul(object *self, object *args)
+{
+	char *cp, *ncp;
+	int len, size, x, y;
+	object *rv;
+	int i;
+
+	if ( !getargs(args, "(s#iii)", &cp, &len, &size, &x, &y) )
+		return 0;
+    
+	if ( size != 1 && size != 4 ) {
+		err_setstr(ImageopError, "Size should be 1 or 4");
+		return 0;
+	}
+	if ( len != size*x*y ) {
+		err_setstr(ImageopError, "String has incorrect length");
+		return 0;
+	}
+    
+	rv = newsizedstringobject(NULL, XXXX);
+	if ( rv == 0 )
+		return 0;
+	ncp = (char *)getstringvalue(rv);
+    
+    
+	for ( i=0; i < len; i += size ) {
+	}
+	return rv;
+}
+*/
+
+static PyMethodDef imageop_methods[] = {
+	{ "crop",		imageop_crop, METH_VARARGS },
+	{ "scale",		imageop_scale, METH_VARARGS },
+	{ "grey2mono",	        imageop_grey2mono, METH_VARARGS },
+	{ "grey2grey2",	        imageop_grey2grey2, METH_VARARGS },
+	{ "grey2grey4",	        imageop_grey2grey4, METH_VARARGS },
+	{ "dither2mono",	imageop_dither2mono, METH_VARARGS },
+	{ "dither2grey2",	imageop_dither2grey2, METH_VARARGS },
+	{ "mono2grey",	        imageop_mono2grey, METH_VARARGS },
+	{ "grey22grey",	        imageop_grey22grey, METH_VARARGS },
+	{ "grey42grey",	        imageop_grey42grey, METH_VARARGS },
+	{ "tovideo",	        imageop_tovideo, METH_VARARGS },
+	{ "rgb2rgb8",	        imageop_rgb2rgb8, METH_VARARGS },
+	{ "rgb82rgb",	        imageop_rgb82rgb, METH_VARARGS },
+	{ "rgb2grey",	        imageop_rgb2grey, METH_VARARGS },
+	{ "grey2rgb",	        imageop_grey2rgb, METH_VARARGS },
+	{ 0,                    0 }
+};
+
+
+PyMODINIT_FUNC
+initimageop(void)
+{
+	PyObject *m;
+	m = Py_InitModule("imageop", imageop_methods);
+	if (m == NULL)
+		return;
+	ImageopDict = PyModule_GetDict(m);
+	ImageopError = PyErr_NewException("imageop.error", NULL, NULL);
+	if (ImageopError != NULL)
+		PyDict_SetItemString(ImageopDict, "error", ImageopError);
+}

Added: vendor/Python/current/Modules/imgfile.c
===================================================================
--- vendor/Python/current/Modules/imgfile.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/imgfile.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,504 @@
+
+/* IMGFILE module - Interface to sgi libimage */
+
+/* XXX This module should be done better at some point. It should return
+** an object of image file class, and have routines to manipulate these
+** image files in a neater way (so you can get rgb images off a greyscale
+** file, for instance, or do a straight display without having to get the
+** image bits into python, etc).
+**
+** Warning: this module is very non-reentrant (esp. the readscaled stuff)
+*/
+
+#include "Python.h"
+
+#include <gl/image.h>
+
+#include "/usr/people/4Dgifts/iristools/include/izoom.h"
+
+/* Bunch of missing extern decls; keep gcc -Wall happy... */
+extern void i_seterror();
+extern void iclose();
+extern void filterzoom();
+extern void putrow();
+extern void getrow();
+
+static PyObject * ImgfileError; /* Exception we raise for various trouble */
+
+static int top_to_bottom;	/* True if we want top-to-bottom images */
+
+/* The image library does not always call the error hander :-(,
+   therefore we have a global variable indicating that it was called.
+   It is cleared by imgfile_open(). */
+
+static int error_called;
+
+
+/* The error handler */
+
+static void
+imgfile_error(char *str)
+{
+	PyErr_SetString(ImgfileError, str);
+	error_called = 1;
+	return;	/* To imglib, which will return a failure indicator */
+}
+
+
+/* Open an image file and return a pointer to it.
+   Make sure we raise an exception if we fail. */
+
+static IMAGE *
+imgfile_open(char *fname)
+{
+	IMAGE *image;
+	i_seterror(imgfile_error);
+	error_called = 0;
+	errno = 0;
+	if ( (image = iopen(fname, "r")) == NULL ) {
+		/* Error may already be set by imgfile_error */
+		if ( !error_called ) {
+			if (errno)
+				PyErr_SetFromErrno(ImgfileError);
+			else
+				PyErr_SetString(ImgfileError,
+						"Can't open image file");
+		}
+		return NULL;
+	}
+	return image;
+}
+
+static PyObject *
+imgfile_ttob(PyObject *self, PyObject *args)
+{
+	int newval;
+	PyObject *rv;
+    
+	if (!PyArg_ParseTuple(args, "i:ttob", &newval))
+		return NULL;
+	rv = PyInt_FromLong(top_to_bottom);
+	top_to_bottom = newval;
+	return rv;
+}
+
+static PyObject *
+imgfile_read(PyObject *self, PyObject *args)
+{
+	char *fname;
+	PyObject *rv;
+	int xsize, ysize, zsize;
+	char *cdatap;
+	long *idatap;
+	static short rs[8192], gs[8192], bs[8192];
+	int x, y;
+	IMAGE *image;
+	int yfirst, ylast, ystep;
+
+	if ( !PyArg_ParseTuple(args, "s:read", &fname) )
+		return NULL;
+    
+	if ( (image = imgfile_open(fname)) == NULL )
+		return NULL;
+    
+	if ( image->colormap != CM_NORMAL ) {
+		iclose(image);
+		PyErr_SetString(ImgfileError,
+				"Can only handle CM_NORMAL images");
+		return NULL;
+	}
+	if ( BPP(image->type) != 1 ) {
+		iclose(image);
+		PyErr_SetString(ImgfileError,
+				"Can't handle imgfiles with bpp!=1");
+		return NULL;
+	}
+	xsize = image->xsize;
+	ysize = image->ysize;
+	zsize = image->zsize;
+	if ( zsize != 1 && zsize != 3) {
+		iclose(image);
+		PyErr_SetString(ImgfileError,
+				"Can only handle 1 or 3 byte pixels");
+		return NULL;
+	}
+	if ( xsize > 8192 ) {
+		iclose(image);
+		PyErr_SetString(ImgfileError,
+				"Can't handle image with > 8192 columns");
+		return NULL;
+	}
+
+	if ( zsize == 3 ) zsize = 4;
+	rv = PyString_FromStringAndSize((char *)NULL, xsize*ysize*zsize);
+	if ( rv == NULL ) {
+		iclose(image);
+		return NULL;
+	}
+	cdatap = PyString_AsString(rv);
+	idatap = (long *)cdatap;
+
+	if (top_to_bottom) {
+		yfirst = ysize-1;
+		ylast = -1;
+		ystep = -1;
+	} else {
+		yfirst = 0;
+		ylast = ysize;
+		ystep = 1;
+	}
+	for ( y=yfirst; y != ylast && !error_called; y += ystep ) {
+		if ( zsize == 1 ) {
+			getrow(image, rs, y, 0);
+			for(x=0; x<xsize; x++ )
+				*cdatap++ = rs[x];
+		} else {
+			getrow(image, rs, y, 0);
+			getrow(image, gs, y, 1);
+			getrow(image, bs, y, 2);
+			for(x=0; x<xsize; x++ )
+				*idatap++ = (rs[x] & 0xff)  |
+					((gs[x] & 0xff)<<8) |
+					((bs[x] & 0xff)<<16);
+		}
+	}
+	iclose(image);
+	if ( error_called ) {
+		Py_DECREF(rv);
+		return NULL;
+	}
+	return rv;
+}
+
+static IMAGE *glob_image;
+static long *glob_datap;
+static int glob_width, glob_z, glob_ysize;
+
+static void
+xs_get(short *buf, int y)
+{
+	if (top_to_bottom)
+		getrow(glob_image, buf, (glob_ysize-1-y), glob_z);
+	else
+		getrow(glob_image, buf, y, glob_z);
+}
+
+static void
+xs_put_c(short *buf, int y)
+{
+	char *datap = (char *)glob_datap + y*glob_width;
+	int width = glob_width;
+
+	while ( width-- )
+		*datap++ = (*buf++) & 0xff;
+}
+
+static void
+xs_put_0(short *buf, int y)
+{
+	long *datap = glob_datap + y*glob_width;
+	int width = glob_width;
+
+	while ( width-- )
+		*datap++ = (*buf++) & 0xff;
+}
+static void
+xs_put_12(short *buf, int y)
+{
+	long *datap = glob_datap + y*glob_width;
+	int width = glob_width;
+
+	while ( width-- )
+		*datap++ |= ((*buf++) & 0xff) << (glob_z*8);
+}
+
+static void
+xscale(IMAGE *image, int xsize, int ysize, int zsize,
+       long *datap, int xnew, int ynew, int fmode, double blur)
+{
+	glob_image = image;
+	glob_datap = datap;
+	glob_width = xnew;
+	glob_ysize = ysize;
+	if ( zsize == 1 ) {
+		glob_z = 0;
+		filterzoom(xs_get, xs_put_c, xsize, ysize,
+			   xnew, ynew, fmode, blur);
+	} else {
+		glob_z = 0;
+		filterzoom(xs_get, xs_put_0, xsize, ysize,
+			   xnew, ynew, fmode, blur);
+		glob_z = 1;
+		filterzoom(xs_get, xs_put_12, xsize, ysize,
+			   xnew, ynew, fmode, blur);
+		glob_z = 2;
+		filterzoom(xs_get, xs_put_12, xsize, ysize,
+			   xnew, ynew, fmode, blur);
+	}
+}
+
+
+static PyObject *
+imgfile_readscaled(PyObject *self, PyObject *args)
+{
+	char *fname;
+	PyObject *rv;
+	int xsize, ysize, zsize;
+	char *cdatap;
+	long *idatap;
+	static short rs[8192], gs[8192], bs[8192];
+	int x, y;
+	int xwtd, ywtd, xorig, yorig;
+	float xfac, yfac;
+	IMAGE *image;
+	char *filter;
+	double blur = 1.0;
+	int extended;
+	int fmode = 0;
+	int yfirst, ylast, ystep;
+
+	/*
+	** Parse args. Funny, since arg 4 and 5 are optional
+	** (filter name and blur factor). Also, 4 or 5 arguments indicates
+	** extended scale algorithm in stead of simple-minded pixel drop/dup.
+	*/
+	extended = PyTuple_Size(args) >= 4;
+	if ( !PyArg_ParseTuple(args, "sii|sd",
+			       &fname, &xwtd, &ywtd, &filter, &blur) )
+		return NULL;
+
+	/*
+	** Check parameters, open file and check type, rows, etc.
+	*/
+	if ( extended ) {
+		if ( strcmp(filter, "impulse") == 0 )
+			fmode = IMPULSE;
+		else if ( strcmp( filter, "box") == 0 )
+			fmode = BOX;
+		else if ( strcmp( filter, "triangle") == 0 )
+			fmode = TRIANGLE;
+		else if ( strcmp( filter, "quadratic") == 0 )
+			fmode = QUADRATIC;
+		else if ( strcmp( filter, "gaussian") == 0 )
+			fmode = GAUSSIAN;
+		else {
+			PyErr_SetString(ImgfileError, "Unknown filter type");
+			return NULL;
+		}
+	}
+    
+	if ( (image = imgfile_open(fname)) == NULL )
+		return NULL;
+    
+	if ( image->colormap != CM_NORMAL ) {
+		iclose(image);
+		PyErr_SetString(ImgfileError,
+				"Can only handle CM_NORMAL images");
+		return NULL;
+	}
+	if ( BPP(image->type) != 1 ) {
+		iclose(image);
+		PyErr_SetString(ImgfileError,
+				"Can't handle imgfiles with bpp!=1");
+		return NULL;
+	}
+	xsize = image->xsize;
+	ysize = image->ysize;
+	zsize = image->zsize;
+	if ( zsize != 1 && zsize != 3) {
+		iclose(image);
+		PyErr_SetString(ImgfileError,
+				"Can only handle 1 or 3 byte pixels");
+		return NULL;
+	}
+	if ( xsize > 8192 ) {
+		iclose(image);
+		PyErr_SetString(ImgfileError,
+				"Can't handle image with > 8192 columns");
+		return NULL;
+	}
+
+	if ( zsize == 3 ) zsize = 4;
+	rv = PyString_FromStringAndSize(NULL, xwtd*ywtd*zsize);
+	if ( rv == NULL ) {
+		iclose(image);
+		return NULL;
+	}
+	PyFPE_START_PROTECT("readscaled", return 0)
+	xfac = (float)xsize/(float)xwtd;
+	yfac = (float)ysize/(float)ywtd;
+	PyFPE_END_PROTECT(yfac)
+	cdatap = PyString_AsString(rv);
+	idatap = (long *)cdatap;
+
+	if ( extended ) {
+		xscale(image, xsize, ysize, zsize,
+		       idatap, xwtd, ywtd, fmode, blur);
+	} else {
+		if (top_to_bottom) {
+			yfirst = ywtd-1;
+			ylast = -1;
+			ystep = -1;
+		} else {
+			yfirst = 0;
+			ylast = ywtd;
+			ystep = 1;
+		}
+		for ( y=yfirst; y != ylast && !error_called; y += ystep ) {
+			yorig = (int)(y*yfac);
+			if ( zsize == 1 ) {
+				getrow(image, rs, yorig, 0);
+				for(x=0; x<xwtd; x++ ) {
+					*cdatap++ = rs[(int)(x*xfac)];	
+				}
+			} else {
+				getrow(image, rs, yorig, 0);
+				getrow(image, gs, yorig, 1);
+				getrow(image, bs, yorig, 2);
+				for(x=0; x<xwtd; x++ ) {
+					xorig = (int)(x*xfac);
+					*idatap++ = (rs[xorig] & 0xff)  |
+						((gs[xorig] & 0xff)<<8) |
+						((bs[xorig] & 0xff)<<16);
+				}
+			}
+		}
+	}
+	iclose(image);
+	if ( error_called ) {
+		Py_DECREF(rv);
+		return NULL;
+	}
+	return rv;
+}
+
+static PyObject *
+imgfile_getsizes(PyObject *self, PyObject *args)
+{
+	char *fname;
+	PyObject *rv;
+	IMAGE *image;
+    
+	if ( !PyArg_ParseTuple(args, "s:getsizes", &fname) )
+		return NULL;
+    
+	if ( (image = imgfile_open(fname)) == NULL )
+		return NULL;
+	rv = Py_BuildValue("(iii)", image->xsize, image->ysize, image->zsize);
+	iclose(image);
+	return rv;
+}
+
+static PyObject *
+imgfile_write(PyObject *self, PyObject *args)
+{
+	IMAGE *image;
+	char *fname;
+	int xsize, ysize, zsize, len;
+	char *cdatap;
+	long *idatap;
+	short rs[8192], gs[8192], bs[8192];
+	short r, g, b;
+	long rgb;
+	int x, y;
+	int yfirst, ylast, ystep;
+
+
+	if ( !PyArg_ParseTuple(args, "ss#iii:write",
+			  &fname, &cdatap, &len, &xsize, &ysize, &zsize) )
+		return NULL;
+    
+	if ( zsize != 1 && zsize != 3 ) {
+		PyErr_SetString(ImgfileError,
+				"Can only handle 1 or 3 byte pixels");
+		return NULL;
+	}
+	if ( len != xsize * ysize * (zsize == 1 ? 1 : 4) ) {
+		PyErr_SetString(ImgfileError, "Data does not match sizes");
+		return NULL;
+	}
+	if ( xsize > 8192 ) {
+		PyErr_SetString(ImgfileError,
+				"Can't handle image with > 8192 columns");
+		return NULL;
+	}
+
+	error_called = 0;
+	errno = 0;
+	image =iopen(fname, "w", RLE(1), 3, xsize, ysize, zsize);
+	if ( image == 0 ) {
+		if ( ! error_called ) {
+			if (errno)
+				PyErr_SetFromErrno(ImgfileError);
+			else
+				PyErr_SetString(ImgfileError,
+						"Can't create image file");
+		}
+		return NULL;
+	}
+
+	idatap = (long *)cdatap;
+    
+	if (top_to_bottom) {
+		yfirst = ysize-1;
+		ylast = -1;
+		ystep = -1;
+	} else {
+		yfirst = 0;
+		ylast = ysize;
+		ystep = 1;
+	}
+	for ( y=yfirst; y != ylast && !error_called; y += ystep ) {
+		if ( zsize == 1 ) {
+			for( x=0; x<xsize; x++ )
+				rs[x] = *cdatap++;
+			putrow(image, rs, y, 0);
+		} else {
+			for( x=0; x<xsize; x++ ) {
+				rgb = *idatap++;
+				r = rgb & 0xff;
+				g = (rgb >> 8 ) & 0xff;
+				b = (rgb >> 16 ) & 0xff;
+				rs[x] = r;
+				gs[x] = g;
+				bs[x] = b;
+			}
+			putrow(image, rs, y, 0);
+			putrow(image, gs, y, 1);
+			putrow(image, bs, y, 2);
+		}
+	}
+	iclose(image);
+	if ( error_called )
+		return NULL;
+	Py_INCREF(Py_None);
+	return Py_None;
+    
+}
+
+
+static PyMethodDef imgfile_methods[] = {
+	{ "getsizes",	imgfile_getsizes, METH_VARARGS },
+	{ "read",	imgfile_read, METH_VARARGS },
+	{ "readscaled",	imgfile_readscaled, METH_VARARGS},
+	{ "write",	imgfile_write, METH_VARARGS },
+	{ "ttob",	imgfile_ttob, METH_VARARGS },
+	{ NULL,		NULL } /* Sentinel */
+};
+
+
+void
+initimgfile(void)
+{
+	PyObject *m, *d;
+	m = Py_InitModule("imgfile", imgfile_methods);
+	if (m == NULL)
+		return;
+	d = PyModule_GetDict(m);
+	ImgfileError = PyErr_NewException("imgfile.error", NULL, NULL);
+	if (ImgfileError != NULL)
+		PyDict_SetItemString(d, "error", ImgfileError);
+}
+
+
+

Added: vendor/Python/current/Modules/itertoolsmodule.c
===================================================================
--- vendor/Python/current/Modules/itertoolsmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/itertoolsmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2550 @@
+
+#include "Python.h"
+#include "structmember.h"
+
+/* Itertools module written and maintained 
+   by Raymond D. Hettinger <python at rcn.com>
+   Copyright (c) 2003 Python Software Foundation.
+   All rights reserved.
+*/
+
+
+/* groupby object ***********************************************************/
+
+typedef struct {
+	PyObject_HEAD
+	PyObject *it;
+	PyObject *keyfunc;
+	PyObject *tgtkey;
+	PyObject *currkey;
+	PyObject *currvalue;
+} groupbyobject;
+
+static PyTypeObject groupby_type;
+static PyObject *_grouper_create(groupbyobject *, PyObject *);
+
+static PyObject *
+groupby_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	static char *kwargs[] = {"iterable", "key", NULL};
+	groupbyobject *gbo;
+ 	PyObject *it, *keyfunc = Py_None;
+ 
+ 	if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:groupby", kwargs,
+					 &it, &keyfunc))
+		return NULL;
+
+	gbo = (groupbyobject *)type->tp_alloc(type, 0);
+	if (gbo == NULL)
+		return NULL;
+	gbo->tgtkey = NULL;
+	gbo->currkey = NULL;
+	gbo->currvalue = NULL;
+	gbo->keyfunc = keyfunc;
+	Py_INCREF(keyfunc);
+	gbo->it = PyObject_GetIter(it);
+	if (gbo->it == NULL) {
+		Py_DECREF(gbo);
+		return NULL;
+	}
+	return (PyObject *)gbo;
+}
+
+static void
+groupby_dealloc(groupbyobject *gbo)
+{
+	PyObject_GC_UnTrack(gbo);
+	Py_XDECREF(gbo->it);
+	Py_XDECREF(gbo->keyfunc);
+	Py_XDECREF(gbo->tgtkey);
+	Py_XDECREF(gbo->currkey);
+	Py_XDECREF(gbo->currvalue);
+	gbo->ob_type->tp_free(gbo);
+}
+
+static int
+groupby_traverse(groupbyobject *gbo, visitproc visit, void *arg)
+{
+	Py_VISIT(gbo->it);
+	Py_VISIT(gbo->keyfunc);
+	Py_VISIT(gbo->tgtkey);
+	Py_VISIT(gbo->currkey);
+	Py_VISIT(gbo->currvalue);
+	return 0;
+}
+
+static PyObject *
+groupby_next(groupbyobject *gbo)
+{
+	PyObject *newvalue, *newkey, *r, *grouper, *tmp;
+
+	/* skip to next iteration group */
+	for (;;) {
+		if (gbo->currkey == NULL)
+			/* pass */;
+		else if (gbo->tgtkey == NULL)
+			break;
+		else {
+			int rcmp;
+
+			rcmp = PyObject_RichCompareBool(gbo->tgtkey,
+							gbo->currkey, Py_EQ);
+			if (rcmp == -1)
+				return NULL;
+			else if (rcmp == 0)
+				break;
+		}
+
+		newvalue = PyIter_Next(gbo->it);
+		if (newvalue == NULL)
+			return NULL;
+
+		if (gbo->keyfunc == Py_None) {
+			newkey = newvalue;
+			Py_INCREF(newvalue);
+		} else {
+			newkey = PyObject_CallFunctionObjArgs(gbo->keyfunc,
+							      newvalue, NULL);
+			if (newkey == NULL) {
+				Py_DECREF(newvalue);
+				return NULL;
+			}
+		}
+
+		tmp = gbo->currkey;
+		gbo->currkey = newkey;
+		Py_XDECREF(tmp);
+
+		tmp = gbo->currvalue;
+		gbo->currvalue = newvalue;
+		Py_XDECREF(tmp);
+	}
+
+	Py_INCREF(gbo->currkey);
+	tmp = gbo->tgtkey;
+	gbo->tgtkey = gbo->currkey;
+	Py_XDECREF(tmp);
+
+	grouper = _grouper_create(gbo, gbo->tgtkey);
+	if (grouper == NULL)
+		return NULL;
+
+	r = PyTuple_Pack(2, gbo->currkey, grouper);
+	Py_DECREF(grouper);
+	return r;
+}
+
+PyDoc_STRVAR(groupby_doc,
+"groupby(iterable[, keyfunc]) -> create an iterator which returns\n\
+(key, sub-iterator) grouped by each value of key(value).\n");
+
+static PyTypeObject groupby_type = {
+	PyObject_HEAD_INIT(NULL)
+	0,				/* ob_size */
+	"itertools.groupby",		/* tp_name */
+	sizeof(groupbyobject),		/* tp_basicsize */
+	0,				/* tp_itemsize */
+	/* methods */
+	(destructor)groupby_dealloc,	/* tp_dealloc */
+	0,				/* tp_print */
+	0,				/* tp_getattr */
+	0,				/* tp_setattr */
+	0,				/* tp_compare */
+	0,				/* tp_repr */
+	0,				/* tp_as_number */
+	0,				/* tp_as_sequence */
+	0,				/* tp_as_mapping */
+	0,				/* tp_hash */
+	0,				/* tp_call */
+	0,				/* tp_str */
+	PyObject_GenericGetAttr,	/* tp_getattro */
+	0,				/* tp_setattro */
+	0,				/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+		Py_TPFLAGS_BASETYPE,	/* tp_flags */
+	groupby_doc,			/* tp_doc */
+	(traverseproc)groupby_traverse,	/* tp_traverse */
+	0,				/* tp_clear */
+	0,				/* tp_richcompare */
+	0,				/* tp_weaklistoffset */
+	PyObject_SelfIter,		/* tp_iter */
+	(iternextfunc)groupby_next,	/* tp_iternext */
+	0,				/* tp_methods */
+	0,				/* tp_members */
+	0,				/* tp_getset */
+	0,				/* tp_base */
+	0,				/* tp_dict */
+	0,				/* tp_descr_get */
+	0,				/* tp_descr_set */
+	0,				/* tp_dictoffset */
+	0,				/* tp_init */
+	0,				/* tp_alloc */
+	groupby_new,			/* tp_new */
+	PyObject_GC_Del,		/* tp_free */
+};
+
+
+/* _grouper object (internal) ************************************************/
+
+typedef struct {
+	PyObject_HEAD
+	PyObject *parent;
+	PyObject *tgtkey;
+} _grouperobject;
+
+static PyTypeObject _grouper_type;
+
+static PyObject *
+_grouper_create(groupbyobject *parent, PyObject *tgtkey)
+{
+	_grouperobject *igo;
+
+	igo = PyObject_New(_grouperobject, &_grouper_type);
+	if (igo == NULL)
+		return NULL;
+	igo->parent = (PyObject *)parent;
+	Py_INCREF(parent);
+	igo->tgtkey = tgtkey;
+	Py_INCREF(tgtkey);
+
+	return (PyObject *)igo;
+}
+
+static void
+_grouper_dealloc(_grouperobject *igo)
+{
+	Py_DECREF(igo->parent);
+	Py_DECREF(igo->tgtkey);
+	PyObject_Del(igo);
+}
+
+static PyObject *
+_grouper_next(_grouperobject *igo)
+{
+	groupbyobject *gbo = (groupbyobject *)igo->parent;
+	PyObject *newvalue, *newkey, *r;
+	int rcmp;
+
+	if (gbo->currvalue == NULL) {
+		newvalue = PyIter_Next(gbo->it);
+		if (newvalue == NULL)
+			return NULL;
+
+		if (gbo->keyfunc == Py_None) {
+			newkey = newvalue;
+			Py_INCREF(newvalue);
+		} else {
+			newkey = PyObject_CallFunctionObjArgs(gbo->keyfunc,
+							      newvalue, NULL);
+			if (newkey == NULL) {
+				Py_DECREF(newvalue);
+				return NULL;
+			}
+		}
+
+		assert(gbo->currkey == NULL);
+		gbo->currkey = newkey;
+		gbo->currvalue = newvalue;
+	}
+
+	assert(gbo->currkey != NULL);
+	rcmp = PyObject_RichCompareBool(igo->tgtkey, gbo->currkey, Py_EQ);
+	if (rcmp <= 0)
+		/* got any error or current group is end */
+		return NULL;
+
+	r = gbo->currvalue;
+	gbo->currvalue = NULL;
+	Py_CLEAR(gbo->currkey);
+
+	return r;
+}
+
+static PyTypeObject _grouper_type = {
+	PyObject_HEAD_INIT(NULL)
+	0,				/* ob_size */
+	"itertools._grouper",		/* tp_name */
+	sizeof(_grouperobject),		/* tp_basicsize */
+	0,				/* tp_itemsize */
+	/* methods */
+	(destructor)_grouper_dealloc,	/* tp_dealloc */
+	0,				/* tp_print */
+	0,				/* tp_getattr */
+	0,				/* tp_setattr */
+	0,				/* tp_compare */
+	0,				/* tp_repr */
+	0,				/* tp_as_number */
+	0,				/* tp_as_sequence */
+	0,				/* tp_as_mapping */
+	0,				/* tp_hash */
+	0,				/* tp_call */
+	0,				/* tp_str */
+	PyObject_GenericGetAttr,	/* tp_getattro */
+	0,				/* tp_setattro */
+	0,				/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT,		/* tp_flags */
+	0,				/* tp_doc */
+	0, 				/* tp_traverse */
+	0,				/* tp_clear */
+	0,				/* tp_richcompare */
+	0,				/* tp_weaklistoffset */
+	PyObject_SelfIter,		/* tp_iter */
+	(iternextfunc)_grouper_next,	/* tp_iternext */
+	0,				/* tp_methods */
+	0,				/* tp_members */
+	0,				/* tp_getset */
+	0,				/* tp_base */
+	0,				/* tp_dict */
+	0,				/* tp_descr_get */
+	0,				/* tp_descr_set */
+	0,				/* tp_dictoffset */
+	0,				/* tp_init */
+	0,				/* tp_alloc */
+	0,				/* tp_new */
+	PyObject_Del,			/* tp_free */
+};
+
+ 
+
+/* tee object and with supporting function and objects ***************/
+
+/* The teedataobject pre-allocates space for LINKCELLS number of objects.
+   To help the object fit neatly inside cache lines (space for 16 to 32
+   pointers), the value should be a multiple of 16 minus  space for 
+   the other structure members including PyHEAD overhead.  The larger the
+   value, the less memory overhead per object and the less time spent
+   allocating/deallocating new links.  The smaller the number, the less
+   wasted space and the more rapid freeing of older data.
+*/
+#define LINKCELLS 57
+
+typedef struct {
+	PyObject_HEAD
+	PyObject *it;
+	int numread;
+	PyObject *nextlink;
+	PyObject *(values[LINKCELLS]);
+} teedataobject;
+
+typedef struct {
+	PyObject_HEAD
+	teedataobject *dataobj;
+	int index;
+	PyObject *weakreflist;
+} teeobject;
+
+static PyTypeObject teedataobject_type;
+
+static PyObject *
+teedataobject_new(PyObject *it)
+{
+	teedataobject *tdo;
+
+	tdo = PyObject_GC_New(teedataobject, &teedataobject_type);
+	if (tdo == NULL)
+		return NULL;
+
+	tdo->numread = 0;
+	tdo->nextlink = NULL;
+	Py_INCREF(it);
+	tdo->it = it;
+	PyObject_GC_Track(tdo);
+	return (PyObject *)tdo;
+}
+
+static PyObject *
+teedataobject_jumplink(teedataobject *tdo)
+{
+	if (tdo->nextlink == NULL)
+		tdo->nextlink = teedataobject_new(tdo->it);
+	Py_XINCREF(tdo->nextlink);
+	return tdo->nextlink;
+}
+
+static PyObject *
+teedataobject_getitem(teedataobject *tdo, int i)
+{
+	PyObject *value;
+
+	assert(i < LINKCELLS);
+	if (i < tdo->numread)
+		value = tdo->values[i];
+	else {
+		/* this is the lead iterator, so fetch more data */
+		assert(i == tdo->numread);
+		value = PyIter_Next(tdo->it);
+		if (value == NULL)
+			return NULL;
+		tdo->numread++;
+		tdo->values[i] = value;
+	}
+	Py_INCREF(value);
+	return value;
+}
+
+static int
+teedataobject_traverse(teedataobject *tdo, visitproc visit, void * arg)
+{
+	int i;
+	Py_VISIT(tdo->it);
+	for (i = 0; i < tdo->numread; i++)
+		Py_VISIT(tdo->values[i]);
+	Py_VISIT(tdo->nextlink);
+	return 0;
+}
+
+static int
+teedataobject_clear(teedataobject *tdo)
+{
+	int i;
+	Py_CLEAR(tdo->it);
+	for (i=0 ; i<tdo->numread ; i++)
+		Py_CLEAR(tdo->values[i]);
+	Py_CLEAR(tdo->nextlink);
+	return 0;
+}
+
+static void
+teedataobject_dealloc(teedataobject *tdo)
+{
+	PyObject_GC_UnTrack(tdo);
+	teedataobject_clear(tdo);
+	PyObject_GC_Del(tdo);
+}
+
+PyDoc_STRVAR(teedataobject_doc, "Data container common to multiple tee objects.");
+
+static PyTypeObject teedataobject_type = {
+	PyObject_HEAD_INIT(0)	/* Must fill in type value later */
+	0,					/* ob_size */
+	"itertools.tee_dataobject",		/* tp_name */
+	sizeof(teedataobject),			/* tp_basicsize */
+	0,					/* tp_itemsize */
+	/* methods */
+	(destructor)teedataobject_dealloc,	/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	0,					/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,	/* tp_flags */
+	teedataobject_doc,			/* tp_doc */
+	(traverseproc)teedataobject_traverse,	/* tp_traverse */
+	(inquiry)teedataobject_clear,		/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	0,					/* tp_methods */
+	0,					/* tp_members */
+	0,					/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	0,					/* tp_init */
+	0,					/* tp_alloc */
+	0,					/* tp_new */
+	PyObject_GC_Del,			/* tp_free */
+};
+
+
+static PyTypeObject tee_type;
+
+static PyObject *
+tee_next(teeobject *to)
+{
+	PyObject *value, *link;
+
+	if (to->index >= LINKCELLS) {
+		link = teedataobject_jumplink(to->dataobj);
+		Py_DECREF(to->dataobj);
+		to->dataobj = (teedataobject *)link;
+		to->index = 0;
+	}
+	value = teedataobject_getitem(to->dataobj, to->index);
+	if (value == NULL)
+		return NULL;
+	to->index++;
+	return value;
+}
+
+static int
+tee_traverse(teeobject *to, visitproc visit, void *arg)
+{
+	Py_VISIT((PyObject *)to->dataobj);
+	return 0;
+}
+
+static PyObject *
+tee_copy(teeobject *to)
+{
+	teeobject *newto;
+
+	newto = PyObject_GC_New(teeobject, &tee_type);
+	if (newto == NULL)
+		return NULL;
+	Py_INCREF(to->dataobj);
+	newto->dataobj = to->dataobj;
+	newto->index = to->index;
+	newto->weakreflist = NULL;
+	PyObject_GC_Track(newto);
+	return (PyObject *)newto;
+}
+
+PyDoc_STRVAR(teecopy_doc, "Returns an independent iterator.");
+
+static PyObject *
+tee_fromiterable(PyObject *iterable)
+{
+	teeobject *to;
+	PyObject *it = NULL;
+
+	it = PyObject_GetIter(iterable);
+	if (it == NULL)
+		return NULL;
+	if (PyObject_TypeCheck(it, &tee_type)) {
+		to = (teeobject *)tee_copy((teeobject *)it);
+		goto done;
+	}
+
+	to = PyObject_GC_New(teeobject, &tee_type);
+	if (to == NULL) 
+		goto done;
+	to->dataobj = (teedataobject *)teedataobject_new(it);
+	if (!to->dataobj) {
+		PyObject_GC_Del(to);
+		to = NULL;
+		goto done;
+	}
+
+	to->index = 0;
+	to->weakreflist = NULL;
+	PyObject_GC_Track(to);
+done:
+	Py_XDECREF(it);
+	return (PyObject *)to;
+}
+
+static PyObject *
+tee_new(PyTypeObject *type, PyObject *args, PyObject *kw)
+{
+	PyObject *iterable;
+
+	if (!PyArg_UnpackTuple(args, "tee", 1, 1, &iterable))
+		return NULL;
+	return tee_fromiterable(iterable);
+}
+
+static int
+tee_clear(teeobject *to)
+{
+	if (to->weakreflist != NULL)
+		PyObject_ClearWeakRefs((PyObject *) to);
+	Py_CLEAR(to->dataobj);
+	return 0;
+}
+
+static void
+tee_dealloc(teeobject *to)
+{
+	PyObject_GC_UnTrack(to);
+	tee_clear(to);
+	PyObject_GC_Del(to);
+}
+
+PyDoc_STRVAR(teeobject_doc,
+"Iterator wrapped to make it copyable");
+
+static PyMethodDef tee_methods[] = {
+	{"__copy__",	(PyCFunction)tee_copy,	METH_NOARGS, teecopy_doc},
+ 	{NULL,		NULL}		/* sentinel */
+};
+
+static PyTypeObject tee_type = {
+	PyObject_HEAD_INIT(NULL)
+	0,				/* ob_size */
+	"itertools.tee",		/* tp_name */
+	sizeof(teeobject),		/* tp_basicsize */
+	0,				/* tp_itemsize */
+	/* methods */
+	(destructor)tee_dealloc,	/* tp_dealloc */
+	0,				/* tp_print */
+	0,				/* tp_getattr */
+	0,				/* tp_setattr */
+	0,				/* tp_compare */
+	0,				/* tp_repr */
+	0,				/* tp_as_number */
+	0,				/* tp_as_sequence */
+	0,				/* tp_as_mapping */
+	0,				/* tp_hash */
+	0,				/* tp_call */
+	0,				/* tp_str */
+	0,				/* tp_getattro */
+	0,				/* tp_setattro */
+	0,				/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,	/* tp_flags */
+	teeobject_doc,			/* tp_doc */
+	(traverseproc)tee_traverse,	/* tp_traverse */
+	(inquiry)tee_clear,		/* tp_clear */
+	0,				/* tp_richcompare */
+	offsetof(teeobject, weakreflist),	/* tp_weaklistoffset */
+	PyObject_SelfIter,		/* tp_iter */
+	(iternextfunc)tee_next,		/* tp_iternext */
+	tee_methods,			/* tp_methods */
+	0,				/* tp_members */
+	0,				/* tp_getset */
+	0,				/* tp_base */
+	0,				/* tp_dict */
+	0,				/* tp_descr_get */
+	0,				/* tp_descr_set */
+	0,				/* tp_dictoffset */
+	0,				/* tp_init */
+	0,				/* tp_alloc */
+	tee_new,			/* tp_new */
+	PyObject_GC_Del,		/* tp_free */
+};
+
+static PyObject *
+tee(PyObject *self, PyObject *args)
+{
+	Py_ssize_t i, n=2;
+	PyObject *it, *iterable, *copyable, *result;
+
+	if (!PyArg_ParseTuple(args, "O|n", &iterable, &n))
+		return NULL;
+	if (n < 0) {
+		PyErr_SetString(PyExc_ValueError, "n must be >= 0");
+		return NULL;
+	}
+	result = PyTuple_New(n);
+	if (result == NULL)
+		return NULL;
+	if (n == 0)
+		return result;
+	it = PyObject_GetIter(iterable);
+	if (it == NULL) {
+		Py_DECREF(result);
+		return NULL;
+	}
+	if (!PyObject_HasAttrString(it, "__copy__")) {
+		copyable = tee_fromiterable(it);
+		Py_DECREF(it);
+		if (copyable == NULL) {
+			Py_DECREF(result);
+			return NULL;
+		}
+	} else
+		copyable = it;
+	PyTuple_SET_ITEM(result, 0, copyable);
+	for (i=1 ; i<n ; i++) {
+		copyable = PyObject_CallMethod(copyable, "__copy__", NULL);
+		if (copyable == NULL) {
+			Py_DECREF(result);
+			return NULL;
+		}
+		PyTuple_SET_ITEM(result, i, copyable);
+	}
+	return result;
+}
+
+PyDoc_STRVAR(tee_doc,
+"tee(iterable, n=2) --> tuple of n independent iterators.");
+
+
+/* cycle object **********************************************************/
+
+typedef struct {
+	PyObject_HEAD
+	PyObject *it;
+	PyObject *saved;
+	int firstpass;
+} cycleobject;
+
+static PyTypeObject cycle_type;
+
+static PyObject *
+cycle_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	PyObject *it;
+	PyObject *iterable;
+	PyObject *saved;
+	cycleobject *lz;
+
+	if (type == &cycle_type && !_PyArg_NoKeywords("cycle()", kwds))
+		return NULL;
+
+	if (!PyArg_UnpackTuple(args, "cycle", 1, 1, &iterable))
+		return NULL;
+
+	/* Get iterator. */
+	it = PyObject_GetIter(iterable);
+	if (it == NULL)
+		return NULL;
+
+	saved = PyList_New(0);
+	if (saved == NULL) {
+		Py_DECREF(it);
+		return NULL;
+	}
+
+	/* create cycleobject structure */
+	lz = (cycleobject *)type->tp_alloc(type, 0);
+	if (lz == NULL) {
+		Py_DECREF(it);
+		Py_DECREF(saved);
+		return NULL;
+	}
+	lz->it = it;
+	lz->saved = saved;
+	lz->firstpass = 0;
+
+	return (PyObject *)lz;
+}
+
+static void
+cycle_dealloc(cycleobject *lz)
+{
+	PyObject_GC_UnTrack(lz);
+	Py_XDECREF(lz->saved);
+	Py_XDECREF(lz->it);
+	lz->ob_type->tp_free(lz);
+}
+
+static int
+cycle_traverse(cycleobject *lz, visitproc visit, void *arg)
+{
+	Py_VISIT(lz->it);
+	Py_VISIT(lz->saved);
+	return 0;
+}
+
+static PyObject *
+cycle_next(cycleobject *lz)
+{
+	PyObject *item;
+	PyObject *it;
+	PyObject *tmp;
+
+	while (1) {
+		item = PyIter_Next(lz->it);
+		if (item != NULL) {
+			if (!lz->firstpass)
+				PyList_Append(lz->saved, item);
+			return item;
+		}
+		if (PyErr_Occurred()) {
+			if (PyErr_ExceptionMatches(PyExc_StopIteration))
+				PyErr_Clear();
+			else
+				return NULL;
+		}
+		if (PyList_Size(lz->saved) == 0) 
+			return NULL;
+		it = PyObject_GetIter(lz->saved);
+		if (it == NULL)
+			return NULL;
+		tmp = lz->it;
+		lz->it = it;
+		lz->firstpass = 1;
+		Py_DECREF(tmp);
+	}
+}
+
+PyDoc_STRVAR(cycle_doc,
+"cycle(iterable) --> cycle object\n\
+\n\
+Return elements from the iterable until it is exhausted.\n\
+Then repeat the sequence indefinitely.");
+
+static PyTypeObject cycle_type = {
+	PyObject_HEAD_INIT(NULL)
+	0,				/* ob_size */
+	"itertools.cycle",		/* tp_name */
+	sizeof(cycleobject),		/* tp_basicsize */
+	0,				/* tp_itemsize */
+	/* methods */
+	(destructor)cycle_dealloc,	/* tp_dealloc */
+	0,				/* tp_print */
+	0,				/* tp_getattr */
+	0,				/* tp_setattr */
+	0,				/* tp_compare */
+	0,				/* tp_repr */
+	0,				/* tp_as_number */
+	0,				/* tp_as_sequence */
+	0,				/* tp_as_mapping */
+	0,				/* tp_hash */
+	0,				/* tp_call */
+	0,				/* tp_str */
+	PyObject_GenericGetAttr,	/* tp_getattro */
+	0,				/* tp_setattro */
+	0,				/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+		Py_TPFLAGS_BASETYPE,	/* tp_flags */
+	cycle_doc,			/* tp_doc */
+	(traverseproc)cycle_traverse,	/* tp_traverse */
+	0,				/* tp_clear */
+	0,				/* tp_richcompare */
+	0,				/* tp_weaklistoffset */
+	PyObject_SelfIter,		/* tp_iter */
+	(iternextfunc)cycle_next,	/* tp_iternext */
+	0,				/* tp_methods */
+	0,				/* tp_members */
+	0,				/* tp_getset */
+	0,				/* tp_base */
+	0,				/* tp_dict */
+	0,				/* tp_descr_get */
+	0,				/* tp_descr_set */
+	0,				/* tp_dictoffset */
+	0,				/* tp_init */
+	0,				/* tp_alloc */
+	cycle_new,			/* tp_new */
+	PyObject_GC_Del,		/* tp_free */
+};
+
+
+/* dropwhile object **********************************************************/
+
+typedef struct {
+	PyObject_HEAD
+	PyObject *func;
+	PyObject *it;
+	long	 start;
+} dropwhileobject;
+
+static PyTypeObject dropwhile_type;
+
+static PyObject *
+dropwhile_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	PyObject *func, *seq;
+	PyObject *it;
+	dropwhileobject *lz;
+
+	if (type == &dropwhile_type && !_PyArg_NoKeywords("dropwhile()", kwds))
+		return NULL;
+
+	if (!PyArg_UnpackTuple(args, "dropwhile", 2, 2, &func, &seq))
+		return NULL;
+
+	/* Get iterator. */
+	it = PyObject_GetIter(seq);
+	if (it == NULL)
+		return NULL;
+
+	/* create dropwhileobject structure */
+	lz = (dropwhileobject *)type->tp_alloc(type, 0);
+	if (lz == NULL) {
+		Py_DECREF(it);
+		return NULL;
+	}
+	Py_INCREF(func);
+	lz->func = func;
+	lz->it = it;
+	lz->start = 0;
+
+	return (PyObject *)lz;
+}
+
+static void
+dropwhile_dealloc(dropwhileobject *lz)
+{
+	PyObject_GC_UnTrack(lz);
+	Py_XDECREF(lz->func);
+	Py_XDECREF(lz->it);
+	lz->ob_type->tp_free(lz);
+}
+
+static int
+dropwhile_traverse(dropwhileobject *lz, visitproc visit, void *arg)
+{
+	Py_VISIT(lz->it);
+	Py_VISIT(lz->func);
+	return 0;
+}
+
+static PyObject *
+dropwhile_next(dropwhileobject *lz)
+{
+	PyObject *item, *good;
+	PyObject *it = lz->it;
+	long ok;
+	PyObject *(*iternext)(PyObject *);
+
+	assert(PyIter_Check(it));
+	iternext = *it->ob_type->tp_iternext;
+	for (;;) {
+		item = iternext(it);
+		if (item == NULL)
+			return NULL;
+		if (lz->start == 1)
+			return item;
+
+		good = PyObject_CallFunctionObjArgs(lz->func, item, NULL);
+		if (good == NULL) {
+			Py_DECREF(item);
+			return NULL;
+		}
+		ok = PyObject_IsTrue(good);
+		Py_DECREF(good);
+		if (!ok) {
+			lz->start = 1;
+			return item;
+		}
+		Py_DECREF(item);
+	}
+}
+
+PyDoc_STRVAR(dropwhile_doc,
+"dropwhile(predicate, iterable) --> dropwhile object\n\
+\n\
+Drop items from the iterable while predicate(item) is true.\n\
+Afterwards, return every element until the iterable is exhausted.");
+
+static PyTypeObject dropwhile_type = {
+	PyObject_HEAD_INIT(NULL)
+	0,				/* ob_size */
+	"itertools.dropwhile",		/* tp_name */
+	sizeof(dropwhileobject),	/* tp_basicsize */
+	0,				/* tp_itemsize */
+	/* methods */
+	(destructor)dropwhile_dealloc,	/* tp_dealloc */
+	0,				/* tp_print */
+	0,				/* tp_getattr */
+	0,				/* tp_setattr */
+	0,				/* tp_compare */
+	0,				/* tp_repr */
+	0,				/* tp_as_number */
+	0,				/* tp_as_sequence */
+	0,				/* tp_as_mapping */
+	0,				/* tp_hash */
+	0,				/* tp_call */
+	0,				/* tp_str */
+	PyObject_GenericGetAttr,	/* tp_getattro */
+	0,				/* tp_setattro */
+	0,				/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+		Py_TPFLAGS_BASETYPE,	/* tp_flags */
+	dropwhile_doc,			/* tp_doc */
+	(traverseproc)dropwhile_traverse,    /* tp_traverse */
+	0,				/* tp_clear */
+	0,				/* tp_richcompare */
+	0,				/* tp_weaklistoffset */
+	PyObject_SelfIter,		/* tp_iter */
+	(iternextfunc)dropwhile_next,	/* tp_iternext */
+	0,				/* tp_methods */
+	0,				/* tp_members */
+	0,				/* tp_getset */
+	0,				/* tp_base */
+	0,				/* tp_dict */
+	0,				/* tp_descr_get */
+	0,				/* tp_descr_set */
+	0,				/* tp_dictoffset */
+	0,				/* tp_init */
+	0,				/* tp_alloc */
+	dropwhile_new,			/* tp_new */
+	PyObject_GC_Del,		/* tp_free */
+};
+
+
+/* takewhile object **********************************************************/
+
+typedef struct {
+	PyObject_HEAD
+	PyObject *func;
+	PyObject *it;
+	long	 stop;
+} takewhileobject;
+
+static PyTypeObject takewhile_type;
+
+static PyObject *
+takewhile_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	PyObject *func, *seq;
+	PyObject *it;
+	takewhileobject *lz;
+
+	if (type == &takewhile_type && !_PyArg_NoKeywords("takewhile()", kwds))
+		return NULL;
+
+	if (!PyArg_UnpackTuple(args, "takewhile", 2, 2, &func, &seq))
+		return NULL;
+
+	/* Get iterator. */
+	it = PyObject_GetIter(seq);
+	if (it == NULL)
+		return NULL;
+
+	/* create takewhileobject structure */
+	lz = (takewhileobject *)type->tp_alloc(type, 0);
+	if (lz == NULL) {
+		Py_DECREF(it);
+		return NULL;
+	}
+	Py_INCREF(func);
+	lz->func = func;
+	lz->it = it;
+	lz->stop = 0;
+
+	return (PyObject *)lz;
+}
+
+static void
+takewhile_dealloc(takewhileobject *lz)
+{
+	PyObject_GC_UnTrack(lz);
+	Py_XDECREF(lz->func);
+	Py_XDECREF(lz->it);
+	lz->ob_type->tp_free(lz);
+}
+
+static int
+takewhile_traverse(takewhileobject *lz, visitproc visit, void *arg)
+{
+	Py_VISIT(lz->it);
+	Py_VISIT(lz->func);
+	return 0;
+}
+
+static PyObject *
+takewhile_next(takewhileobject *lz)
+{
+	PyObject *item, *good;
+	PyObject *it = lz->it;
+	long ok;
+
+	if (lz->stop == 1)
+		return NULL;
+
+	assert(PyIter_Check(it));
+	item = (*it->ob_type->tp_iternext)(it);
+	if (item == NULL)
+		return NULL;
+
+	good = PyObject_CallFunctionObjArgs(lz->func, item, NULL);
+	if (good == NULL) {
+		Py_DECREF(item);
+		return NULL;
+	}
+	ok = PyObject_IsTrue(good);
+	Py_DECREF(good);
+	if (ok)
+		return item;
+	Py_DECREF(item);
+	lz->stop = 1;
+	return NULL;
+}
+
+PyDoc_STRVAR(takewhile_doc,
+"takewhile(predicate, iterable) --> takewhile object\n\
+\n\
+Return successive entries from an iterable as long as the \n\
+predicate evaluates to true for each entry.");
+
+static PyTypeObject takewhile_type = {
+	PyObject_HEAD_INIT(NULL)
+	0,				/* ob_size */
+	"itertools.takewhile",		/* tp_name */
+	sizeof(takewhileobject),	/* tp_basicsize */
+	0,				/* tp_itemsize */
+	/* methods */
+	(destructor)takewhile_dealloc,	/* tp_dealloc */
+	0,				/* tp_print */
+	0,				/* tp_getattr */
+	0,				/* tp_setattr */
+	0,				/* tp_compare */
+	0,				/* tp_repr */
+	0,				/* tp_as_number */
+	0,				/* tp_as_sequence */
+	0,				/* tp_as_mapping */
+	0,				/* tp_hash */
+	0,				/* tp_call */
+	0,				/* tp_str */
+	PyObject_GenericGetAttr,	/* tp_getattro */
+	0,				/* tp_setattro */
+	0,				/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+		Py_TPFLAGS_BASETYPE,	/* tp_flags */
+	takewhile_doc,			/* tp_doc */
+	(traverseproc)takewhile_traverse,    /* tp_traverse */
+	0,				/* tp_clear */
+	0,				/* tp_richcompare */
+	0,				/* tp_weaklistoffset */
+	PyObject_SelfIter,		/* tp_iter */
+	(iternextfunc)takewhile_next,	/* tp_iternext */
+	0,				/* tp_methods */
+	0,				/* tp_members */
+	0,				/* tp_getset */
+	0,				/* tp_base */
+	0,				/* tp_dict */
+	0,				/* tp_descr_get */
+	0,				/* tp_descr_set */
+	0,				/* tp_dictoffset */
+	0,				/* tp_init */
+	0,				/* tp_alloc */
+	takewhile_new,			/* tp_new */
+	PyObject_GC_Del,		/* tp_free */
+};
+
+
+/* islice object ************************************************************/
+
+typedef struct {
+	PyObject_HEAD
+	PyObject *it;
+	Py_ssize_t next;
+	Py_ssize_t stop;
+	Py_ssize_t step;
+	Py_ssize_t cnt;
+} isliceobject;
+
+static PyTypeObject islice_type;
+
+static PyObject *
+islice_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	PyObject *seq;
+	Py_ssize_t start=0, stop=-1, step=1;
+	PyObject *it, *a1=NULL, *a2=NULL, *a3=NULL;
+	Py_ssize_t numargs;
+	isliceobject *lz;
+
+	if (type == &islice_type && !_PyArg_NoKeywords("islice()", kwds))
+		return NULL;
+
+	if (!PyArg_UnpackTuple(args, "islice", 2, 4, &seq, &a1, &a2, &a3))
+		return NULL;
+
+	numargs = PyTuple_Size(args);
+	if (numargs == 2) {
+		if (a1 != Py_None) {
+			stop = PyInt_AsSsize_t(a1);
+			if (stop == -1) {
+				if (PyErr_Occurred())
+					PyErr_Clear();
+				PyErr_SetString(PyExc_ValueError,
+				   "Stop argument for islice() must be a non-negative integer or None.");
+				return NULL;
+			}
+		}
+	} else {
+		if (a1 != Py_None)
+			start = PyInt_AsSsize_t(a1);
+		if (start == -1 && PyErr_Occurred())
+			PyErr_Clear();
+		if (a2 != Py_None) {
+			stop = PyInt_AsSsize_t(a2);
+			if (stop == -1) {
+				if (PyErr_Occurred())
+					PyErr_Clear();
+				PyErr_SetString(PyExc_ValueError,
+				   "Stop argument for islice() must be a non-negative integer or None.");
+				return NULL;
+			}
+		}
+	}
+	if (start<0 || stop<-1) {
+		PyErr_SetString(PyExc_ValueError,
+		   "Indices for islice() must be non-negative integers or None.");
+		return NULL;
+	}
+
+	if (a3 != NULL) {
+		if (a3 != Py_None)
+			step = PyInt_AsSsize_t(a3);
+		if (step == -1 && PyErr_Occurred())
+			PyErr_Clear();
+	}
+	if (step<1) {
+		PyErr_SetString(PyExc_ValueError,
+		   "Step for islice() must be a positive integer or None.");
+		return NULL;
+	}
+
+	/* Get iterator. */
+	it = PyObject_GetIter(seq);
+	if (it == NULL)
+		return NULL;
+
+	/* create isliceobject structure */
+	lz = (isliceobject *)type->tp_alloc(type, 0);
+	if (lz == NULL) {
+		Py_DECREF(it);
+		return NULL;
+	}
+	lz->it = it;
+	lz->next = start;
+	lz->stop = stop;
+	lz->step = step;
+	lz->cnt = 0L;
+
+	return (PyObject *)lz;
+}
+
+static void
+islice_dealloc(isliceobject *lz)
+{
+	PyObject_GC_UnTrack(lz);
+	Py_XDECREF(lz->it);
+	lz->ob_type->tp_free(lz);
+}
+
+static int
+islice_traverse(isliceobject *lz, visitproc visit, void *arg)
+{
+	Py_VISIT(lz->it);
+	return 0;
+}
+
+static PyObject *
+islice_next(isliceobject *lz)
+{
+	PyObject *item;
+	PyObject *it = lz->it;
+	Py_ssize_t oldnext;
+	PyObject *(*iternext)(PyObject *);
+
+	assert(PyIter_Check(it));
+	iternext = *it->ob_type->tp_iternext;
+	while (lz->cnt < lz->next) {
+		item = iternext(it);
+		if (item == NULL)
+			return NULL;
+		Py_DECREF(item);
+		lz->cnt++;
+	}
+	if (lz->stop != -1 && lz->cnt >= lz->stop)
+		return NULL;
+	assert(PyIter_Check(it));
+	item = iternext(it);
+	if (item == NULL)
+		return NULL;
+	lz->cnt++;
+	oldnext = lz->next;
+	lz->next += lz->step;
+	if (lz->next < oldnext)	/* Check for overflow */
+		lz->next = lz->stop;
+	return item;
+}
+
+PyDoc_STRVAR(islice_doc,
+"islice(iterable, [start,] stop [, step]) --> islice object\n\
+\n\
+Return an iterator whose next() method returns selected values from an\n\
+iterable.  If start is specified, will skip all preceding elements;\n\
+otherwise, start defaults to zero.  Step defaults to one.  If\n\
+specified as another value, step determines how many values are \n\
+skipped between successive calls.  Works like a slice() on a list\n\
+but returns an iterator.");
+
+static PyTypeObject islice_type = {
+	PyObject_HEAD_INIT(NULL)
+	0,				/* ob_size */
+	"itertools.islice",		/* tp_name */
+	sizeof(isliceobject),		/* tp_basicsize */
+	0,				/* tp_itemsize */
+	/* methods */
+	(destructor)islice_dealloc,	/* tp_dealloc */
+	0,				/* tp_print */
+	0,				/* tp_getattr */
+	0,				/* tp_setattr */
+	0,				/* tp_compare */
+	0,				/* tp_repr */
+	0,				/* tp_as_number */
+	0,				/* tp_as_sequence */
+	0,				/* tp_as_mapping */
+	0,				/* tp_hash */
+	0,				/* tp_call */
+	0,				/* tp_str */
+	PyObject_GenericGetAttr,	/* tp_getattro */
+	0,				/* tp_setattro */
+	0,				/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+		Py_TPFLAGS_BASETYPE,	/* tp_flags */
+	islice_doc,			/* tp_doc */
+	(traverseproc)islice_traverse,	/* tp_traverse */
+	0,				/* tp_clear */
+	0,				/* tp_richcompare */
+	0,				/* tp_weaklistoffset */
+	PyObject_SelfIter,		/* tp_iter */
+	(iternextfunc)islice_next,	/* tp_iternext */
+	0,				/* tp_methods */
+	0,				/* tp_members */
+	0,				/* tp_getset */
+	0,				/* tp_base */
+	0,				/* tp_dict */
+	0,				/* tp_descr_get */
+	0,				/* tp_descr_set */
+	0,				/* tp_dictoffset */
+	0,				/* tp_init */
+	0,				/* tp_alloc */
+	islice_new,			/* tp_new */
+	PyObject_GC_Del,		/* tp_free */
+};
+
+
+/* starmap object ************************************************************/
+
+typedef struct {
+	PyObject_HEAD
+	PyObject *func;
+	PyObject *it;
+} starmapobject;
+
+static PyTypeObject starmap_type;
+
+static PyObject *
+starmap_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	PyObject *func, *seq;
+	PyObject *it;
+	starmapobject *lz;
+
+	if (type == &starmap_type && !_PyArg_NoKeywords("starmap()", kwds))
+		return NULL;
+
+	if (!PyArg_UnpackTuple(args, "starmap", 2, 2, &func, &seq))
+		return NULL;
+
+	/* Get iterator. */
+	it = PyObject_GetIter(seq);
+	if (it == NULL)
+		return NULL;
+
+	/* create starmapobject structure */
+	lz = (starmapobject *)type->tp_alloc(type, 0);
+	if (lz == NULL) {
+		Py_DECREF(it);
+		return NULL;
+	}
+	Py_INCREF(func);
+	lz->func = func;
+	lz->it = it;
+
+	return (PyObject *)lz;
+}
+
+static void
+starmap_dealloc(starmapobject *lz)
+{
+	PyObject_GC_UnTrack(lz);
+	Py_XDECREF(lz->func);
+	Py_XDECREF(lz->it);
+	lz->ob_type->tp_free(lz);
+}
+
+static int
+starmap_traverse(starmapobject *lz, visitproc visit, void *arg)
+{
+	Py_VISIT(lz->it);
+	Py_VISIT(lz->func);
+	return 0;
+}
+
+static PyObject *
+starmap_next(starmapobject *lz)
+{
+	PyObject *args;
+	PyObject *result;
+	PyObject *it = lz->it;
+
+	assert(PyIter_Check(it));
+	args = (*it->ob_type->tp_iternext)(it);
+	if (args == NULL)
+		return NULL;
+	if (!PyTuple_CheckExact(args)) {
+		Py_DECREF(args);
+		PyErr_SetString(PyExc_TypeError,
+				"iterator must return a tuple");
+		return NULL;
+	}
+	result = PyObject_Call(lz->func, args, NULL);
+	Py_DECREF(args);
+	return result;
+}
+
+PyDoc_STRVAR(starmap_doc,
+"starmap(function, sequence) --> starmap object\n\
+\n\
+Return an iterator whose values are returned from the function evaluated\n\
+with a argument tuple taken from the given sequence.");
+
+static PyTypeObject starmap_type = {
+	PyObject_HEAD_INIT(NULL)
+	0,				/* ob_size */
+	"itertools.starmap",		/* tp_name */
+	sizeof(starmapobject),		/* tp_basicsize */
+	0,				/* tp_itemsize */
+	/* methods */
+	(destructor)starmap_dealloc,	/* tp_dealloc */
+	0,				/* tp_print */
+	0,				/* tp_getattr */
+	0,				/* tp_setattr */
+	0,				/* tp_compare */
+	0,				/* tp_repr */
+	0,				/* tp_as_number */
+	0,				/* tp_as_sequence */
+	0,				/* tp_as_mapping */
+	0,				/* tp_hash */
+	0,				/* tp_call */
+	0,				/* tp_str */
+	PyObject_GenericGetAttr,	/* tp_getattro */
+	0,				/* tp_setattro */
+	0,				/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+		Py_TPFLAGS_BASETYPE,	/* tp_flags */
+	starmap_doc,			/* tp_doc */
+	(traverseproc)starmap_traverse,	/* tp_traverse */
+	0,				/* tp_clear */
+	0,				/* tp_richcompare */
+	0,				/* tp_weaklistoffset */
+	PyObject_SelfIter,		/* tp_iter */
+	(iternextfunc)starmap_next,	/* tp_iternext */
+	0,				/* tp_methods */
+	0,				/* tp_members */
+	0,				/* tp_getset */
+	0,				/* tp_base */
+	0,				/* tp_dict */
+	0,				/* tp_descr_get */
+	0,				/* tp_descr_set */
+	0,				/* tp_dictoffset */
+	0,				/* tp_init */
+	0,				/* tp_alloc */
+	starmap_new,			/* tp_new */
+	PyObject_GC_Del,		/* tp_free */
+};
+
+
+/* imap object ************************************************************/
+
+typedef struct {
+	PyObject_HEAD
+	PyObject *iters;
+	PyObject *func;
+} imapobject;
+
+static PyTypeObject imap_type;
+
+static PyObject *
+imap_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	PyObject *it, *iters, *func;
+	imapobject *lz;
+	Py_ssize_t numargs, i;
+
+	if (type == &imap_type && !_PyArg_NoKeywords("imap()", kwds))
+		return NULL;
+
+	numargs = PyTuple_Size(args);
+	if (numargs < 2) {
+		PyErr_SetString(PyExc_TypeError,
+		   "imap() must have at least two arguments.");
+		return NULL;
+	}
+
+	iters = PyTuple_New(numargs-1);
+	if (iters == NULL)
+		return NULL;
+
+	for (i=1 ; i<numargs ; i++) {
+		/* Get iterator. */
+		it = PyObject_GetIter(PyTuple_GET_ITEM(args, i));
+		if (it == NULL) {
+			Py_DECREF(iters);
+			return NULL;
+		}
+		PyTuple_SET_ITEM(iters, i-1, it);
+	}
+
+	/* create imapobject structure */
+	lz = (imapobject *)type->tp_alloc(type, 0);
+	if (lz == NULL) {
+		Py_DECREF(iters);
+		return NULL;
+	}
+	lz->iters = iters;
+	func = PyTuple_GET_ITEM(args, 0);
+	Py_INCREF(func);
+	lz->func = func;
+
+	return (PyObject *)lz;
+}
+
+static void
+imap_dealloc(imapobject *lz)
+{
+	PyObject_GC_UnTrack(lz);
+	Py_XDECREF(lz->iters);
+	Py_XDECREF(lz->func);
+	lz->ob_type->tp_free(lz);
+}
+
+static int
+imap_traverse(imapobject *lz, visitproc visit, void *arg)
+{
+	Py_VISIT(lz->iters);
+	Py_VISIT(lz->func);
+	return 0;
+}
+
+/*	
+imap() is an iterator version of __builtins__.map() except that it does
+not have the None fill-in feature.  That was intentionally left out for
+the following reasons:
+
+  1) Itertools are designed to be easily combined and chained together.
+     Having all tools stop with the shortest input is a unifying principle
+     that makes it easier to combine finite iterators (supplying data) with
+     infinite iterators like count() and repeat() (for supplying sequential
+     or constant arguments to a function).
+
+  2) In typical use cases for combining itertools, having one finite data 
+     supplier run out before another is likely to be an error condition which
+     should not pass silently by automatically supplying None.
+
+  3) The use cases for automatic None fill-in are rare -- not many functions
+     do something useful when a parameter suddenly switches type and becomes
+     None.  
+
+  4) If a need does arise, it can be met by __builtins__.map() or by 
+     writing:  chain(iterable, repeat(None)).
+
+  5) Similar toolsets in Haskell and SML do not have automatic None fill-in.
+*/
+
+static PyObject *
+imap_next(imapobject *lz)
+{
+	PyObject *val;
+	PyObject *argtuple;
+	PyObject *result;
+	Py_ssize_t numargs, i;
+
+	numargs = PyTuple_Size(lz->iters);
+	argtuple = PyTuple_New(numargs);
+	if (argtuple == NULL)
+		return NULL;
+
+	for (i=0 ; i<numargs ; i++) {
+		val = PyIter_Next(PyTuple_GET_ITEM(lz->iters, i));
+		if (val == NULL) {
+			Py_DECREF(argtuple);
+			return NULL;
+		}
+		PyTuple_SET_ITEM(argtuple, i, val);
+	}
+	if (lz->func == Py_None) 
+		return argtuple;
+	result = PyObject_Call(lz->func, argtuple, NULL);
+	Py_DECREF(argtuple);
+	return result;
+}
+
+PyDoc_STRVAR(imap_doc,
+"imap(func, *iterables) --> imap object\n\
+\n\
+Make an iterator that computes the function using arguments from\n\
+each of the iterables.	Like map() except that it returns\n\
+an iterator instead of a list and that it stops when the shortest\n\
+iterable is exhausted instead of filling in None for shorter\n\
+iterables.");
+
+static PyTypeObject imap_type = {
+	PyObject_HEAD_INIT(NULL)
+	0,				/* ob_size */
+	"itertools.imap",		/* tp_name */
+	sizeof(imapobject),		/* tp_basicsize */
+	0,				/* tp_itemsize */
+	/* methods */
+	(destructor)imap_dealloc,	/* tp_dealloc */
+	0,				/* tp_print */
+	0,				/* tp_getattr */
+	0,				/* tp_setattr */
+	0,				/* tp_compare */
+	0,				/* tp_repr */
+	0,				/* tp_as_number */
+	0,				/* tp_as_sequence */
+	0,				/* tp_as_mapping */
+	0,				/* tp_hash */
+	0,				/* tp_call */
+	0,				/* tp_str */
+	PyObject_GenericGetAttr,	/* tp_getattro */
+	0,				/* tp_setattro */
+	0,				/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+		Py_TPFLAGS_BASETYPE,	/* tp_flags */
+	imap_doc,			/* tp_doc */
+	(traverseproc)imap_traverse,	/* tp_traverse */
+	0,				/* tp_clear */
+	0,				/* tp_richcompare */
+	0,				/* tp_weaklistoffset */
+	PyObject_SelfIter,		/* tp_iter */
+	(iternextfunc)imap_next,	/* tp_iternext */
+	0,				/* tp_methods */
+	0,				/* tp_members */
+	0,				/* tp_getset */
+	0,				/* tp_base */
+	0,				/* tp_dict */
+	0,				/* tp_descr_get */
+	0,				/* tp_descr_set */
+	0,				/* tp_dictoffset */
+	0,				/* tp_init */
+	0,				/* tp_alloc */
+	imap_new,			/* tp_new */
+	PyObject_GC_Del,		/* tp_free */
+};
+
+
+/* chain object ************************************************************/
+
+typedef struct {
+	PyObject_HEAD
+	Py_ssize_t tuplesize;
+	Py_ssize_t iternum;		/* which iterator is active */
+	PyObject *ittuple;		/* tuple of iterators */
+} chainobject;
+
+static PyTypeObject chain_type;
+
+static PyObject *
+chain_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	chainobject *lz;
+	Py_ssize_t tuplesize = PySequence_Length(args);
+	Py_ssize_t i;
+	PyObject *ittuple;
+
+	if (type == &chain_type && !_PyArg_NoKeywords("chain()", kwds))
+		return NULL;
+
+	/* obtain iterators */
+	assert(PyTuple_Check(args));
+	ittuple = PyTuple_New(tuplesize);
+	if (ittuple == NULL)
+		return NULL;
+	for (i=0; i < tuplesize; ++i) {
+		PyObject *item = PyTuple_GET_ITEM(args, i);
+		PyObject *it = PyObject_GetIter(item);
+		if (it == NULL) {
+			if (PyErr_ExceptionMatches(PyExc_TypeError))
+				PyErr_Format(PyExc_TypeError,
+				    "chain argument #%zd must support iteration",
+				    i+1);
+			Py_DECREF(ittuple);
+			return NULL;
+		}
+		PyTuple_SET_ITEM(ittuple, i, it);
+	}
+
+	/* create chainobject structure */
+	lz = (chainobject *)type->tp_alloc(type, 0);
+	if (lz == NULL) {
+		Py_DECREF(ittuple);
+		return NULL;
+	}
+
+	lz->ittuple = ittuple;
+	lz->iternum = 0;
+	lz->tuplesize = tuplesize;
+
+	return (PyObject *)lz;
+}
+
+static void
+chain_dealloc(chainobject *lz)
+{
+	PyObject_GC_UnTrack(lz);
+	Py_XDECREF(lz->ittuple);
+	lz->ob_type->tp_free(lz);
+}
+
+static int
+chain_traverse(chainobject *lz, visitproc visit, void *arg)
+{
+	Py_VISIT(lz->ittuple);
+	return 0;
+}
+
+static PyObject *
+chain_next(chainobject *lz)
+{
+	PyObject *it;
+	PyObject *item;
+
+	while (lz->iternum < lz->tuplesize) {
+		it = PyTuple_GET_ITEM(lz->ittuple, lz->iternum);
+		item = PyIter_Next(it);
+		if (item != NULL)
+			return item;
+		if (PyErr_Occurred()) {
+			if (PyErr_ExceptionMatches(PyExc_StopIteration))
+				PyErr_Clear();
+			else
+				return NULL;
+		}
+		lz->iternum++;
+	}
+	return NULL;
+}
+
+PyDoc_STRVAR(chain_doc,
+"chain(*iterables) --> chain object\n\
+\n\
+Return a chain object whose .next() method returns elements from the\n\
+first iterable until it is exhausted, then elements from the next\n\
+iterable, until all of the iterables are exhausted.");
+
+static PyTypeObject chain_type = {
+	PyObject_HEAD_INIT(NULL)
+	0,				/* ob_size */
+	"itertools.chain",		/* tp_name */
+	sizeof(chainobject),		/* tp_basicsize */
+	0,				/* tp_itemsize */
+	/* methods */
+	(destructor)chain_dealloc,	/* tp_dealloc */
+	0,				/* tp_print */
+	0,				/* tp_getattr */
+	0,				/* tp_setattr */
+	0,				/* tp_compare */
+	0,				/* tp_repr */
+	0,				/* tp_as_number */
+	0,				/* tp_as_sequence */
+	0,				/* tp_as_mapping */
+	0,				/* tp_hash */
+	0,				/* tp_call */
+	0,				/* tp_str */
+	PyObject_GenericGetAttr,	/* tp_getattro */
+	0,				/* tp_setattro */
+	0,				/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+		Py_TPFLAGS_BASETYPE,	/* tp_flags */
+	chain_doc,			/* tp_doc */
+	(traverseproc)chain_traverse,	/* tp_traverse */
+	0,				/* tp_clear */
+	0,				/* tp_richcompare */
+	0,				/* tp_weaklistoffset */
+	PyObject_SelfIter,		/* tp_iter */
+	(iternextfunc)chain_next,	/* tp_iternext */
+	0,				/* tp_methods */
+	0,				/* tp_members */
+	0,				/* tp_getset */
+	0,				/* tp_base */
+	0,				/* tp_dict */
+	0,				/* tp_descr_get */
+	0,				/* tp_descr_set */
+	0,				/* tp_dictoffset */
+	0,				/* tp_init */
+	0,				/* tp_alloc */
+	chain_new,			/* tp_new */
+	PyObject_GC_Del,		/* tp_free */
+};
+
+
+/* ifilter object ************************************************************/
+
+typedef struct {
+	PyObject_HEAD
+	PyObject *func;
+	PyObject *it;
+} ifilterobject;
+
+static PyTypeObject ifilter_type;
+
+static PyObject *
+ifilter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	PyObject *func, *seq;
+	PyObject *it;
+	ifilterobject *lz;
+
+	if (type == &ifilter_type && !_PyArg_NoKeywords("ifilter()", kwds))
+		return NULL;
+
+	if (!PyArg_UnpackTuple(args, "ifilter", 2, 2, &func, &seq))
+		return NULL;
+
+	/* Get iterator. */
+	it = PyObject_GetIter(seq);
+	if (it == NULL)
+		return NULL;
+
+	/* create ifilterobject structure */
+	lz = (ifilterobject *)type->tp_alloc(type, 0);
+	if (lz == NULL) {
+		Py_DECREF(it);
+		return NULL;
+	}
+	Py_INCREF(func);
+	lz->func = func;
+	lz->it = it;
+
+	return (PyObject *)lz;
+}
+
+static void
+ifilter_dealloc(ifilterobject *lz)
+{
+	PyObject_GC_UnTrack(lz);
+	Py_XDECREF(lz->func);
+	Py_XDECREF(lz->it);
+	lz->ob_type->tp_free(lz);
+}
+
+static int
+ifilter_traverse(ifilterobject *lz, visitproc visit, void *arg)
+{
+	Py_VISIT(lz->it);
+	Py_VISIT(lz->func);
+	return 0;
+}
+
+static PyObject *
+ifilter_next(ifilterobject *lz)
+{
+	PyObject *item;
+	PyObject *it = lz->it;
+	long ok;
+	PyObject *(*iternext)(PyObject *);
+
+	assert(PyIter_Check(it));
+	iternext = *it->ob_type->tp_iternext;
+	for (;;) {
+		item = iternext(it);
+		if (item == NULL)
+			return NULL;
+
+		if (lz->func == Py_None) {
+			ok = PyObject_IsTrue(item);
+		} else {
+			PyObject *good;
+			good = PyObject_CallFunctionObjArgs(lz->func,
+							    item, NULL);
+			if (good == NULL) {
+				Py_DECREF(item);
+				return NULL;
+			}
+			ok = PyObject_IsTrue(good);
+			Py_DECREF(good);
+		}
+		if (ok)
+			return item;
+		Py_DECREF(item);
+	}
+}
+
+PyDoc_STRVAR(ifilter_doc,
+"ifilter(function or None, sequence) --> ifilter object\n\
+\n\
+Return those items of sequence for which function(item) is true.\n\
+If function is None, return the items that are true.");
+
+static PyTypeObject ifilter_type = {
+	PyObject_HEAD_INIT(NULL)
+	0,				/* ob_size */
+	"itertools.ifilter",		/* tp_name */
+	sizeof(ifilterobject),		/* tp_basicsize */
+	0,				/* tp_itemsize */
+	/* methods */
+	(destructor)ifilter_dealloc,	/* tp_dealloc */
+	0,				/* tp_print */
+	0,				/* tp_getattr */
+	0,				/* tp_setattr */
+	0,				/* tp_compare */
+	0,				/* tp_repr */
+	0,				/* tp_as_number */
+	0,				/* tp_as_sequence */
+	0,				/* tp_as_mapping */
+	0,				/* tp_hash */
+	0,				/* tp_call */
+	0,				/* tp_str */
+	PyObject_GenericGetAttr,	/* tp_getattro */
+	0,				/* tp_setattro */
+	0,				/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+		Py_TPFLAGS_BASETYPE,	/* tp_flags */
+	ifilter_doc,			/* tp_doc */
+	(traverseproc)ifilter_traverse,	/* tp_traverse */
+	0,				/* tp_clear */
+	0,				/* tp_richcompare */
+	0,				/* tp_weaklistoffset */
+	PyObject_SelfIter,		/* tp_iter */
+	(iternextfunc)ifilter_next,	/* tp_iternext */
+	0,				/* tp_methods */
+	0,				/* tp_members */
+	0,				/* tp_getset */
+	0,				/* tp_base */
+	0,				/* tp_dict */
+	0,				/* tp_descr_get */
+	0,				/* tp_descr_set */
+	0,				/* tp_dictoffset */
+	0,				/* tp_init */
+	0,				/* tp_alloc */
+	ifilter_new,			/* tp_new */
+	PyObject_GC_Del,		/* tp_free */
+};
+
+
+/* ifilterfalse object ************************************************************/
+
+typedef struct {
+	PyObject_HEAD
+	PyObject *func;
+	PyObject *it;
+} ifilterfalseobject;
+
+static PyTypeObject ifilterfalse_type;
+
+static PyObject *
+ifilterfalse_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	PyObject *func, *seq;
+	PyObject *it;
+	ifilterfalseobject *lz;
+
+	if (type == &ifilterfalse_type &&
+	    !_PyArg_NoKeywords("ifilterfalse()", kwds))
+		return NULL;
+
+	if (!PyArg_UnpackTuple(args, "ifilterfalse", 2, 2, &func, &seq))
+		return NULL;
+
+	/* Get iterator. */
+	it = PyObject_GetIter(seq);
+	if (it == NULL)
+		return NULL;
+
+	/* create ifilterfalseobject structure */
+	lz = (ifilterfalseobject *)type->tp_alloc(type, 0);
+	if (lz == NULL) {
+		Py_DECREF(it);
+		return NULL;
+	}
+	Py_INCREF(func);
+	lz->func = func;
+	lz->it = it;
+
+	return (PyObject *)lz;
+}
+
+static void
+ifilterfalse_dealloc(ifilterfalseobject *lz)
+{
+	PyObject_GC_UnTrack(lz);
+	Py_XDECREF(lz->func);
+	Py_XDECREF(lz->it);
+	lz->ob_type->tp_free(lz);
+}
+
+static int
+ifilterfalse_traverse(ifilterfalseobject *lz, visitproc visit, void *arg)
+{
+	Py_VISIT(lz->it);
+	Py_VISIT(lz->func);
+	return 0;
+}
+
+static PyObject *
+ifilterfalse_next(ifilterfalseobject *lz)
+{
+	PyObject *item;
+	PyObject *it = lz->it;
+	long ok;
+	PyObject *(*iternext)(PyObject *);
+
+	assert(PyIter_Check(it));
+	iternext = *it->ob_type->tp_iternext;
+	for (;;) {
+		item = iternext(it);
+		if (item == NULL)
+			return NULL;
+
+		if (lz->func == Py_None) {
+			ok = PyObject_IsTrue(item);
+		} else {
+			PyObject *good;
+			good = PyObject_CallFunctionObjArgs(lz->func,
+							    item, NULL);
+			if (good == NULL) {
+				Py_DECREF(item);
+				return NULL;
+			}
+			ok = PyObject_IsTrue(good);
+			Py_DECREF(good);
+		}
+		if (!ok)
+			return item;
+		Py_DECREF(item);
+	}
+}
+
+PyDoc_STRVAR(ifilterfalse_doc,
+"ifilterfalse(function or None, sequence) --> ifilterfalse object\n\
+\n\
+Return those items of sequence for which function(item) is false.\n\
+If function is None, return the items that are false.");
+
+static PyTypeObject ifilterfalse_type = {
+	PyObject_HEAD_INIT(NULL)
+	0,				/* ob_size */
+	"itertools.ifilterfalse",	/* tp_name */
+	sizeof(ifilterfalseobject),	/* tp_basicsize */
+	0,				/* tp_itemsize */
+	/* methods */
+	(destructor)ifilterfalse_dealloc,	/* tp_dealloc */
+	0,				/* tp_print */
+	0,				/* tp_getattr */
+	0,				/* tp_setattr */
+	0,				/* tp_compare */
+	0,				/* tp_repr */
+	0,				/* tp_as_number */
+	0,				/* tp_as_sequence */
+	0,				/* tp_as_mapping */
+	0,				/* tp_hash */
+	0,				/* tp_call */
+	0,				/* tp_str */
+	PyObject_GenericGetAttr,	/* tp_getattro */
+	0,				/* tp_setattro */
+	0,				/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+		Py_TPFLAGS_BASETYPE,	/* tp_flags */
+	ifilterfalse_doc,		/* tp_doc */
+	(traverseproc)ifilterfalse_traverse,	/* tp_traverse */
+	0,				/* tp_clear */
+	0,				/* tp_richcompare */
+	0,				/* tp_weaklistoffset */
+	PyObject_SelfIter,		/* tp_iter */
+	(iternextfunc)ifilterfalse_next,	/* tp_iternext */
+	0,				/* tp_methods */
+	0,				/* tp_members */
+	0,				/* tp_getset */
+	0,				/* tp_base */
+	0,				/* tp_dict */
+	0,				/* tp_descr_get */
+	0,				/* tp_descr_set */
+	0,				/* tp_dictoffset */
+	0,				/* tp_init */
+	0,				/* tp_alloc */
+	ifilterfalse_new,		/* tp_new */
+	PyObject_GC_Del,		/* tp_free */
+};
+
+
+/* count object ************************************************************/
+
+typedef struct {
+	PyObject_HEAD
+	Py_ssize_t cnt;
+} countobject;
+
+static PyTypeObject count_type;
+
+static PyObject *
+count_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	countobject *lz;
+	Py_ssize_t cnt = 0;
+
+	if (type == &count_type && !_PyArg_NoKeywords("count()", kwds))
+		return NULL;
+
+	if (!PyArg_ParseTuple(args, "|n:count", &cnt))
+		return NULL;
+
+	/* create countobject structure */
+	lz = (countobject *)PyObject_New(countobject, &count_type);
+	if (lz == NULL)
+		return NULL;
+	lz->cnt = cnt;
+
+	return (PyObject *)lz;
+}
+
+static PyObject *
+count_next(countobject *lz)
+{
+        if (lz->cnt == LONG_MAX) {
+                PyErr_SetString(PyExc_OverflowError,
+                        "cannot count beyond LONG_MAX");                
+                return NULL;         
+        }
+	return PyInt_FromSsize_t(lz->cnt++);
+}
+
+static PyObject *
+count_repr(countobject *lz)
+{
+	return PyString_FromFormat("count(%zd)", lz->cnt);
+}
+
+PyDoc_STRVAR(count_doc,
+"count([firstval]) --> count object\n\
+\n\
+Return a count object whose .next() method returns consecutive\n\
+integers starting from zero or, if specified, from firstval.");
+
+static PyTypeObject count_type = {
+	PyObject_HEAD_INIT(NULL)
+	0,				/* ob_size */
+	"itertools.count",		/* tp_name */
+	sizeof(countobject),		/* tp_basicsize */
+	0,				/* tp_itemsize */
+	/* methods */
+	(destructor)PyObject_Del,	/* tp_dealloc */
+	0,				/* tp_print */
+	0,				/* tp_getattr */
+	0,				/* tp_setattr */
+	0,				/* tp_compare */
+	(reprfunc)count_repr,		/* tp_repr */
+	0,				/* tp_as_number */
+	0,				/* tp_as_sequence */
+	0,				/* tp_as_mapping */
+	0,				/* tp_hash */
+	0,				/* tp_call */
+	0,				/* tp_str */
+	PyObject_GenericGetAttr,	/* tp_getattro */
+	0,				/* tp_setattro */
+	0,				/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT,		/* tp_flags */
+	count_doc,			/* tp_doc */
+	0,				/* tp_traverse */
+	0,				/* tp_clear */
+	0,				/* tp_richcompare */
+	0,				/* tp_weaklistoffset */
+	PyObject_SelfIter,		/* tp_iter */
+	(iternextfunc)count_next,	/* tp_iternext */
+	0,				/* tp_methods */
+	0,				/* tp_members */
+	0,				/* tp_getset */
+	0,				/* tp_base */
+	0,				/* tp_dict */
+	0,				/* tp_descr_get */
+	0,				/* tp_descr_set */
+	0,				/* tp_dictoffset */
+	0,				/* tp_init */
+	0,				/* tp_alloc */
+	count_new,			/* tp_new */
+};
+
+
+/* izip object ************************************************************/
+
+#include "Python.h"
+
+typedef struct {
+	PyObject_HEAD
+	Py_ssize_t	tuplesize;
+	PyObject *ittuple;		/* tuple of iterators */
+	PyObject *result;
+} izipobject;
+
+static PyTypeObject izip_type;
+
+static PyObject *
+izip_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	izipobject *lz;
+	Py_ssize_t i;
+	PyObject *ittuple;  /* tuple of iterators */
+	PyObject *result;
+	Py_ssize_t tuplesize = PySequence_Length(args);
+
+	if (type == &izip_type && !_PyArg_NoKeywords("izip()", kwds))
+		return NULL;
+
+	/* args must be a tuple */
+	assert(PyTuple_Check(args));
+
+	/* obtain iterators */
+	ittuple = PyTuple_New(tuplesize);
+	if (ittuple == NULL)
+		return NULL;
+	for (i=0; i < tuplesize; ++i) {
+		PyObject *item = PyTuple_GET_ITEM(args, i);
+		PyObject *it = PyObject_GetIter(item);
+		if (it == NULL) {
+			if (PyErr_ExceptionMatches(PyExc_TypeError))
+				PyErr_Format(PyExc_TypeError,
+				    "izip argument #%zd must support iteration",
+				    i+1);
+			Py_DECREF(ittuple);
+			return NULL;
+		}
+		PyTuple_SET_ITEM(ittuple, i, it);
+	}
+
+	/* create a result holder */
+	result = PyTuple_New(tuplesize);
+	if (result == NULL) {
+		Py_DECREF(ittuple);
+		return NULL;
+	}
+	for (i=0 ; i < tuplesize ; i++) {
+		Py_INCREF(Py_None);
+		PyTuple_SET_ITEM(result, i, Py_None);
+	}
+
+	/* create izipobject structure */
+	lz = (izipobject *)type->tp_alloc(type, 0);
+	if (lz == NULL) {
+		Py_DECREF(ittuple);
+		Py_DECREF(result);
+		return NULL;
+	}
+	lz->ittuple = ittuple;
+	lz->tuplesize = tuplesize;
+	lz->result = result;
+
+	return (PyObject *)lz;
+}
+
+static void
+izip_dealloc(izipobject *lz)
+{
+	PyObject_GC_UnTrack(lz);
+	Py_XDECREF(lz->ittuple);
+	Py_XDECREF(lz->result);
+	lz->ob_type->tp_free(lz);
+}
+
+static int
+izip_traverse(izipobject *lz, visitproc visit, void *arg)
+{
+	Py_VISIT(lz->ittuple);
+	Py_VISIT(lz->result);
+	return 0;
+}
+
+static PyObject *
+izip_next(izipobject *lz)
+{
+	Py_ssize_t i;
+	Py_ssize_t tuplesize = lz->tuplesize;
+	PyObject *result = lz->result;
+	PyObject *it;
+	PyObject *item;
+	PyObject *olditem;
+
+	if (tuplesize == 0)
+		return NULL;
+	if (result->ob_refcnt == 1) {
+		Py_INCREF(result);
+		for (i=0 ; i < tuplesize ; i++) {
+			it = PyTuple_GET_ITEM(lz->ittuple, i);
+			assert(PyIter_Check(it));
+			item = (*it->ob_type->tp_iternext)(it);
+			if (item == NULL) {
+				Py_DECREF(result);
+				return NULL;
+			}
+			olditem = PyTuple_GET_ITEM(result, i);
+			PyTuple_SET_ITEM(result, i, item);
+			Py_DECREF(olditem);
+		}
+	} else {
+		result = PyTuple_New(tuplesize);
+		if (result == NULL)
+			return NULL;
+		for (i=0 ; i < tuplesize ; i++) {
+			it = PyTuple_GET_ITEM(lz->ittuple, i);
+			assert(PyIter_Check(it));
+			item = (*it->ob_type->tp_iternext)(it);
+			if (item == NULL) {
+				Py_DECREF(result);
+				return NULL;
+			}
+			PyTuple_SET_ITEM(result, i, item);
+		}
+	}
+	return result;
+}
+
+PyDoc_STRVAR(izip_doc,
+"izip(iter1 [,iter2 [...]]) --> izip object\n\
+\n\
+Return a izip object whose .next() method returns a tuple where\n\
+the i-th element comes from the i-th iterable argument.  The .next()\n\
+method continues until the shortest iterable in the argument sequence\n\
+is exhausted and then it raises StopIteration.  Works like the zip()\n\
+function but consumes less memory by returning an iterator instead of\n\
+a list.");
+
+static PyTypeObject izip_type = {
+	PyObject_HEAD_INIT(NULL)
+	0,				/* ob_size */
+	"itertools.izip",		/* tp_name */
+	sizeof(izipobject),		/* tp_basicsize */
+	0,				/* tp_itemsize */
+	/* methods */
+	(destructor)izip_dealloc,	/* tp_dealloc */
+	0,				/* tp_print */
+	0,				/* tp_getattr */
+	0,				/* tp_setattr */
+	0,				/* tp_compare */
+	0,				/* tp_repr */
+	0,				/* tp_as_number */
+	0,				/* tp_as_sequence */
+	0,				/* tp_as_mapping */
+	0,				/* tp_hash */
+	0,				/* tp_call */
+	0,				/* tp_str */
+	PyObject_GenericGetAttr,	/* tp_getattro */
+	0,				/* tp_setattro */
+	0,				/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+		Py_TPFLAGS_BASETYPE,	/* tp_flags */
+	izip_doc,			/* tp_doc */
+	(traverseproc)izip_traverse,    /* tp_traverse */
+	0,				/* tp_clear */
+	0,				/* tp_richcompare */
+	0,				/* tp_weaklistoffset */
+	PyObject_SelfIter,		/* tp_iter */
+	(iternextfunc)izip_next,	/* tp_iternext */
+	0,				/* tp_methods */
+	0,				/* tp_members */
+	0,				/* tp_getset */
+	0,				/* tp_base */
+	0,				/* tp_dict */
+	0,				/* tp_descr_get */
+	0,				/* tp_descr_set */
+	0,				/* tp_dictoffset */
+	0,				/* tp_init */
+	0,				/* tp_alloc */
+	izip_new,			/* tp_new */
+	PyObject_GC_Del,		/* tp_free */
+};
+
+
+/* repeat object ************************************************************/
+
+typedef struct {
+	PyObject_HEAD
+	PyObject *element;
+	Py_ssize_t cnt;
+} repeatobject;
+
+static PyTypeObject repeat_type;
+
+static PyObject *
+repeat_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	repeatobject *ro;
+	PyObject *element;
+	Py_ssize_t cnt = -1;
+
+	if (type == &repeat_type && !_PyArg_NoKeywords("repeat()", kwds))
+		return NULL;
+
+	if (!PyArg_ParseTuple(args, "O|n:repeat", &element, &cnt))
+		return NULL;
+
+	if (PyTuple_Size(args) == 2 && cnt < 0)
+		cnt = 0;
+
+	ro = (repeatobject *)type->tp_alloc(type, 0);
+	if (ro == NULL)
+		return NULL;
+	Py_INCREF(element);
+	ro->element = element;
+	ro->cnt = cnt;
+	return (PyObject *)ro;
+}
+
+static void
+repeat_dealloc(repeatobject *ro)
+{
+	PyObject_GC_UnTrack(ro);
+	Py_XDECREF(ro->element);
+	ro->ob_type->tp_free(ro);
+}
+
+static int
+repeat_traverse(repeatobject *ro, visitproc visit, void *arg)
+{
+	Py_VISIT(ro->element);
+	return 0;
+}
+
+static PyObject *
+repeat_next(repeatobject *ro)
+{
+	if (ro->cnt == 0)
+		return NULL;
+	if (ro->cnt > 0)
+		ro->cnt--;
+	Py_INCREF(ro->element);
+	return ro->element;
+}
+
+static PyObject *
+repeat_repr(repeatobject *ro)
+{
+	PyObject *result, *objrepr;
+
+	objrepr = PyObject_Repr(ro->element);
+	if (objrepr == NULL)
+		return NULL;
+
+	if (ro->cnt == -1)
+		result = PyString_FromFormat("repeat(%s)",
+			PyString_AS_STRING(objrepr));
+	else
+		result = PyString_FromFormat("repeat(%s, %zd)",
+			PyString_AS_STRING(objrepr), ro->cnt);
+	Py_DECREF(objrepr);
+	return result;
+}	
+
+static PyObject *
+repeat_len(repeatobject *ro)
+{
+        if (ro->cnt == -1) {
+                PyErr_SetString(PyExc_TypeError, "len() of unsized object");
+		return NULL;
+	}
+        return PyInt_FromSize_t(ro->cnt);
+}
+
+PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
+
+static PyMethodDef repeat_methods[] = {
+	{"__length_hint__", (PyCFunction)repeat_len, METH_NOARGS, length_hint_doc},
+ 	{NULL,		NULL}		/* sentinel */
+};
+
+PyDoc_STRVAR(repeat_doc,
+"repeat(element [,times]) -> create an iterator which returns the element\n\
+for the specified number of times.  If not specified, returns the element\n\
+endlessly.");
+
+static PyTypeObject repeat_type = {
+	PyObject_HEAD_INIT(NULL)
+	0,				/* ob_size */
+	"itertools.repeat",		/* tp_name */
+	sizeof(repeatobject),		/* tp_basicsize */
+	0,				/* tp_itemsize */
+	/* methods */
+	(destructor)repeat_dealloc,	/* tp_dealloc */
+	0,				/* tp_print */
+	0,				/* tp_getattr */
+	0,				/* tp_setattr */
+	0,				/* tp_compare */
+	(reprfunc)repeat_repr,		/* tp_repr */
+	0,				/* tp_as_number */
+	0,				/* tp_as_sequence */
+	0,				/* tp_as_mapping */
+	0,				/* tp_hash */
+	0,				/* tp_call */
+	0,				/* tp_str */
+	PyObject_GenericGetAttr,	/* tp_getattro */
+	0,				/* tp_setattro */
+	0,				/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+		Py_TPFLAGS_BASETYPE,	/* tp_flags */
+	repeat_doc,			/* tp_doc */
+	(traverseproc)repeat_traverse,	/* tp_traverse */
+	0,				/* tp_clear */
+	0,				/* tp_richcompare */
+	0,				/* tp_weaklistoffset */
+	PyObject_SelfIter,		/* tp_iter */
+	(iternextfunc)repeat_next,	/* tp_iternext */
+	repeat_methods,			/* tp_methods */
+	0,				/* tp_members */
+	0,				/* tp_getset */
+	0,				/* tp_base */
+	0,				/* tp_dict */
+	0,				/* tp_descr_get */
+	0,				/* tp_descr_set */
+	0,				/* tp_dictoffset */
+	0,				/* tp_init */
+	0,				/* tp_alloc */
+	repeat_new,			/* tp_new */
+	PyObject_GC_Del,		/* tp_free */
+};
+
+
+/* module level code ********************************************************/
+
+PyDoc_STRVAR(module_doc,
+"Functional tools for creating and using iterators.\n\
+\n\
+Infinite iterators:\n\
+count([n]) --> n, n+1, n+2, ...\n\
+cycle(p) --> p0, p1, ... plast, p0, p1, ...\n\
+repeat(elem [,n]) --> elem, elem, elem, ... endlessly or up to n times\n\
+\n\
+Iterators terminating on the shortest input sequence:\n\
+izip(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ... \n\
+ifilter(pred, seq) --> elements of seq where pred(elem) is True\n\
+ifilterfalse(pred, seq) --> elements of seq where pred(elem) is False\n\
+islice(seq, [start,] stop [, step]) --> elements from\n\
+       seq[start:stop:step]\n\
+imap(fun, p, q, ...) --> fun(p0, q0), fun(p1, q1), ...\n\
+starmap(fun, seq) --> fun(*seq[0]), fun(*seq[1]), ...\n\
+tee(it, n=2) --> (it1, it2 , ... itn) splits one iterator into n\n\
+chain(p, q, ...) --> p0, p1, ... plast, q0, q1, ... \n\
+takewhile(pred, seq) --> seq[0], seq[1], until pred fails\n\
+dropwhile(pred, seq) --> seq[n], seq[n+1], starting when pred fails\n\
+groupby(iterable[, keyfunc]) --> sub-iterators grouped by value of keyfunc(v)\n\
+");
+
+
+static PyMethodDef module_methods[] = {
+	{"tee",	(PyCFunction)tee,	METH_VARARGS, tee_doc},
+ 	{NULL,		NULL}		/* sentinel */
+};
+
+PyMODINIT_FUNC
+inititertools(void)
+{
+	int i;
+	PyObject *m;
+	char *name;
+	PyTypeObject *typelist[] = {
+		&cycle_type,
+		&dropwhile_type,
+		&takewhile_type,
+		&islice_type,
+		&starmap_type,
+		&imap_type,
+		&chain_type,
+		&ifilter_type,
+		&ifilterfalse_type,
+		&count_type,
+		&izip_type,
+		&repeat_type,
+		&groupby_type,
+		NULL
+	};
+
+	teedataobject_type.ob_type = &PyType_Type;
+	m = Py_InitModule3("itertools", module_methods, module_doc);
+	if (m == NULL)
+		return;
+
+	for (i=0 ; typelist[i] != NULL ; i++) {
+		if (PyType_Ready(typelist[i]) < 0)
+			return;
+		name = strchr(typelist[i]->tp_name, '.');
+		assert (name != NULL);
+		Py_INCREF(typelist[i]);
+		PyModule_AddObject(m, name+1, (PyObject *)typelist[i]);
+	}
+
+	if (PyType_Ready(&teedataobject_type) < 0)
+		return;
+	if (PyType_Ready(&tee_type) < 0)
+		return;
+	if (PyType_Ready(&_grouper_type) < 0)
+		return;
+}

Added: vendor/Python/current/Modules/ld_so_aix
===================================================================
--- vendor/Python/current/Modules/ld_so_aix	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/ld_so_aix	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,187 @@
+#!/bin/sh
+#
+#   ========================================================================
+#   FILE:           ld_so_aix
+#   TYPE:           executable, uses makexp_aix
+#   SYSTEM:         AIX
+#
+#   DESCRIPTION:    Creates a shareable .o from a set of pre-compiled 
+#                   (unshared) .o files
+#
+#   USAGE:          ld_so_aix [CC] [arguments]
+#
+#   ARGUMENTS:      Same as for "ld". The following arguments are processed
+#                   or supplied by this script (those marked with an asterisk
+#                   can be overriden from command line):
+#
+#                       Argument                     Default value
+#                   (*) -o [OutputFileName]          -o shr.o
+#                   (*) -e [EntryPointLabel]         -e init[OutputBaseName]
+#                   (*) -bE:[ExportFile]             -bE:[OutputBaseName].exp
+#                   (*) -bI:[ImportFile]             -bI:./python.exp
+#                       -bM:[ModuleType]             -bM:SRE
+#                       -bhalt:[Number]              -bhalt:4
+#                       -T[Number]                   -T512
+#                       -H[Number]                   -H512
+#                       -lm
+#
+#                   The compiler specific ("-lc" or "-lc_r", "-lpthreads",...)
+#                   arguments will be automatically passed to "ld" according
+#                   to the CC command provided as a first argument to this
+#                   script. Usually, the same CC command was used to produce
+#                   the pre-compiled .o file(s).
+#
+#   NOTES:          1.  Since "ld_so_aix" was originally written for building
+#                       shared modules for the Python interpreter, the -e and
+#                       -bI default values match Python's conventions. In
+#                       Python, the entry point for a shared module is based
+#                       on the module's name (e.g., the "mathmodule" will
+#                       expect an  entry point of "initmath").
+#                   2.  The script accepts multiple .o or .a input files and
+#                       creates a single (shared) output file. The export list
+#                       that is created is based on the output file's basename
+#                       with the suffix ".exp".
+#                   3.  The resulting shared object file is left in the
+#                       current directory.
+#                   4.  Uncommenting the "echo" lines gives detailed output
+#                       about the commands executed in the script.
+#
+#                       
+#   HISTORY:        Oct-1996    -- Support added for multiple .o files --
+#                               -- and optional arguments processing.  --
+#                   Chris Myers (myers at tc.cornell.edu), Keith Kwok
+#                   (kkwok at tc.cornell.edu) and Vladimir Marangozov
+#
+#                   Aug-6-1996  -- Take care of the compiler specific  --
+#                               -- args by leaving CC to invoke "ld".  --
+#                   Vladimir Marangozov
+#
+#                   Jul-1-1996  -- Make sure to use /usr/ccs/bin/ld    --
+#                               -- Use makexp_aix for the export list. --
+#                   Vladimir Marangozov     (Vladimir.Marangozov at imag.fr)
+#
+#                   Manus Hand (mhand at csn.net) -- Initial code -- 6/24/96
+#   ========================================================================
+#
+
+usage="Usage: ld_so_aix [CC command] [ld arguments]"
+if test ! -n "$*"; then
+  echo $usage; exit 2
+fi
+
+makexp=`dirname $0`/makexp_aix
+
+# Check for existence of compiler.
+CC=$1; shift
+whichcc=`which $CC`
+
+if test ! -x "$whichcc"; then
+  echo "ld_so_aix: Compiler '$CC' not found; exiting."
+  exit 2
+fi
+
+if test ! -n "$*"; then
+  echo $usage; exit 2
+fi
+
+# Default import file for Python
+# Can be overriden by providing a -bI: argument.
+impfile="./python.exp"
+
+# Parse arguments
+while test -n "$1"
+do
+  case "$1" in
+    -e | -Wl,-e)
+        if test -z "$2"; then
+	  echo "ld_so_aix: The -e flag needs a parameter; exiting."; exit 2
+	else
+	  shift; entry=$1
+	fi
+	;;
+    -e* | -Wl,-e*)
+	entry=`echo $1 | sed -e "s/-Wl,//" -e "s/-e//"`
+	;;
+    -o)
+	if test -z "$2"; then
+	  echo "ld_so_aix: The -o flag needs a parameter; exiting."; exit 2
+	else
+	  shift; objfile=$1
+	fi
+	;;
+    -o*)
+	objfile=`echo $1 | sed "s/-o//"`
+	;;
+    -bI:* | -Wl,-bI:*)
+	impfile=`echo $1 | sed -e "s/-Wl,//" -e "s/-bI://"`
+	;;
+    -bE:* | -Wl,-bE:*)
+	expfile=`echo $1 | sed -e "s/-Wl,//" -e "s/-bE://"`
+	;;
+    *.o | *.a)
+	objs="$objs $1"
+	args="$args $1"
+	;;
+    -bM:* | -Wl,-bM:* | -H* | -Wl,-H* | -T* | -Wl,-T* | -lm)
+	;;
+    *)
+        args="$args $1"
+	;;
+  esac
+  shift
+done
+
+
+if test -z "$objs"; then
+  echo "ld_so_aix: No input files; exiting."
+  exit 2
+elif test ! -r "$impfile"; then
+  echo "ld_so_aix: Import file '$impfile' not found or not readable; exiting."
+  exit 2
+fi
+
+# If -o wasn't specified, assume "-o shr.o"
+if test -z "$objfile"; then
+  objfile=shr.o
+fi
+
+filename=`basename $objfile | sed "s/\.[^.]*$//"`
+
+# If -bE: wasn't specified, assume "-bE:$filename.exp"
+if test -z "$expfile"; then
+  expfile="$filename.exp"
+fi
+
+# Default entry symbol for Python modules = init[modulename]
+# Can be overriden by providing a -e argument.
+if test -z "$entry"; then
+  entry=init`echo $filename | sed "s/module.*//"`
+fi
+
+#echo "ld_so_aix: Debug info section"
+#echo "  -> output file : $objfile"
+#echo "  -> import file : $impfile"
+#echo "  -> export file : $expfile"
+#echo "  -> entry point : $entry"
+#echo "  -> object files: $objs"
+#echo "  -> CC arguments: $args"
+
+CCOPT="-Wl,-e$entry -Wl,-bE:$expfile -Wl,-bI:$impfile -Wl,-bhalt:4"
+CCOPT="$CCOPT -Wl,-bM:SRE -Wl,-T512 -Wl,-H512 -lm -o $objfile"
+# Note: to use dynamic libraries like libtcl8.4.so and libtk8.4.so 
+# you may need to replace the second CCOPT line above with the following:
+# CCOPT="$CCOPT -Wl,-bM:SRE -Wl,-T512 -Wl,-H512 -brtl -bnortllib -lm -o $objfile"
+
+CCARGS="$args"
+
+# Export list generation.
+#echo $makexp $expfile "$objfile" $objs
+$makexp $expfile "$objfile" $objs
+
+# Perform the link.
+#echo $CC $CCOPT $CCARGS
+$CC $CCOPT $CCARGS
+
+# Delete the module's export list file.
+# Comment this line if you need it.
+rm -f $expfile


Property changes on: vendor/Python/current/Modules/ld_so_aix
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Modules/ld_so_beos
===================================================================
--- vendor/Python/current/Modules/ld_so_beos	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/ld_so_beos	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,78 @@
+#! /bin/sh
+#
+# linkmodule for Python
+# Chris Herborth (chrish at qnx.com)
+#
+# This is covered by the same copyright/licensing terms as the rest of
+# Python.
+#
+# Shell script to build shared library versions of the modules; since
+# the change to the *ahem* "proper" import/export mechanism, this script
+# is much simpler.  It handles PowerPC and x86, too.
+#
+# This is called by the Modules/Makefile as $(LDSHARED):
+#
+# $(LDSHARED) foomodule.o -o foomodule$(SO)
+#
+# Could also be called as:
+#
+# $(LDSHARED)  readline.o  -L/boot/home/config/lib -lreadline -ltermcap \
+# -o readline$(SO)
+#
+# so we need to preserve the arguments, sort of.
+
+# Make sure we got reasonable arguments.
+TARGET=""
+ARGS=""
+
+while [ "$#" != "0" ]; do
+	case "$1" in
+		-o)	TARGET="$2"; shift; shift;;
+		*)	ARGS="$ARGS $1"; shift;;
+	esac
+done
+
+if [ "$TARGET" = "" ] ; then
+	echo "Usage:"
+	echo
+	echo "	$0 [args] -o foomodule.so [args] foomodule.o [args]"
+	echo
+	echo "Where:"
+	echo
+	echo "	[args]	normal compiler arguments"
+	exit 1
+fi
+
+# The shared libraries and glue objects we need to link against; these
+# libs are overkill for most of the standard modules, but it makes life
+# in this shell script easier.
+LIBS="-lbe -lnet -lroot"
+
+case $BE_HOST_CPU in
+	ppc)
+		# Boy, do we need a lot of crap...
+		GLUE_LOC=/boot/develop/lib/ppc
+		GLUE="${GLUE_LOC}/glue-noinit.a ${GLUE_LOC}/init_term_dyn.o"
+		case $(uname -r) in
+			4.0*) CC="mwcc -xms -export pragma -nodup" ;;
+			*) CC="mwcc -shared -export pragma -nodup" ;;
+		esac
+		;;
+
+	x86)
+		# We don't need as much crap here...
+		GLUE=""
+		CC="gcc -nostart -Wl,-soname=${TARGET}"
+		;;
+
+	*)
+		# What the?!?
+		echo "$0 doesn't support $BE_HOST_CPU systems..."
+		echo "You're on your own... I'd be surprised if this works."
+		GLUE=""
+		CC="cc"
+		;;
+esac
+
+# Now link that shared lib...
+$CC -o $TARGET $ARGS $GLUE $LIBS


Property changes on: vendor/Python/current/Modules/ld_so_beos
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Modules/linuxaudiodev.c
===================================================================
--- vendor/Python/current/Modules/linuxaudiodev.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/linuxaudiodev.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,502 @@
+/* Hey Emacs, this is -*-C-*- 
+ ******************************************************************************
+ * linuxaudiodev.c -- Linux audio device for python.
+ * 
+ * Author          : Peter Bosch
+ * Created On      : Thu Mar  2 21:10:33 2000
+ * Status          : Unknown, Use with caution!
+ * 
+ * Unless other notices are present in any part of this file
+ * explicitly claiming copyrights for other people and/or 
+ * organizations, the contents of this file is fully copyright 
+ * (C) 2000 Peter Bosch, all rights reserved.
+ ******************************************************************************
+ */
+
+#include "Python.h"
+#include "structmember.h"
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#else
+#define O_RDONLY 00
+#define O_WRONLY 01
+#endif
+
+
+#include <sys/ioctl.h>
+#if defined(linux)
+#include <linux/soundcard.h>
+
+#ifndef HAVE_STDINT_H
+typedef unsigned long uint32_t;
+#endif
+
+#elif defined(__FreeBSD__)
+#include <machine/soundcard.h>
+
+#ifndef SNDCTL_DSP_CHANNELS
+#define SNDCTL_DSP_CHANNELS SOUND_PCM_WRITE_CHANNELS
+#endif
+
+#endif
+
+typedef struct {
+    PyObject_HEAD
+    int		x_fd;		/* The open file */
+    int         x_mode;           /* file mode */
+    int		x_icount;	/* Input count */
+    int		x_ocount;	/* Output count */
+    uint32_t	x_afmts;	/* Audio formats supported by hardware*/
+} lad_t;
+
+/* XXX several format defined in soundcard.h are not supported,
+   including _NE (native endian) options and S32 options
+*/
+
+static struct {
+    int		a_bps;
+    uint32_t	a_fmt;
+    char       *a_name;
+} audio_types[] = {
+    {  8, 	AFMT_MU_LAW, "logarithmic mu-law 8-bit audio" },
+    {  8, 	AFMT_A_LAW,  "logarithmic A-law 8-bit audio" },
+    {  8,	AFMT_U8,     "linear unsigned 8-bit audio" },
+    {  8, 	AFMT_S8,     "linear signed 8-bit audio" },
+    { 16, 	AFMT_U16_BE, "linear unsigned 16-bit big-endian audio" },
+    { 16, 	AFMT_U16_LE, "linear unsigned 16-bit little-endian audio" },
+    { 16, 	AFMT_S16_BE, "linear signed 16-bit big-endian audio" },
+    { 16, 	AFMT_S16_LE, "linear signed 16-bit little-endian audio" },
+    { 16, 	AFMT_S16_NE, "linear signed 16-bit native-endian audio" },
+};
+
+static int n_audio_types = sizeof(audio_types) / sizeof(audio_types[0]);
+
+static PyTypeObject Ladtype;
+
+static PyObject *LinuxAudioError;
+
+static lad_t *
+newladobject(PyObject *arg)
+{
+    lad_t *xp;
+    int fd, afmts, imode;
+    char *basedev = NULL;
+    char *mode = NULL;
+
+    /* Two ways to call linuxaudiodev.open():
+         open(device, mode) (for consistency with builtin open())
+         open(mode)         (for backwards compatibility)
+       because the *first* argument is optional, parsing args is
+       a wee bit tricky. */
+    if (!PyArg_ParseTuple(arg, "s|s:open", &basedev, &mode))
+       return NULL;
+    if (mode == NULL) {                 /* only one arg supplied */
+       mode = basedev;
+       basedev = NULL;
+    }
+
+    if (strcmp(mode, "r") == 0)
+        imode = O_RDONLY;
+    else if (strcmp(mode, "w") == 0)
+        imode = O_WRONLY;
+    else {
+        PyErr_SetString(LinuxAudioError, "mode should be 'r' or 'w'");
+        return NULL;
+    }
+
+    /* Open the correct device.  The base device name comes from the
+     * AUDIODEV environment variable first, then /dev/dsp.  The
+     * control device tacks "ctl" onto the base device name.
+     * 
+     * Note that the only difference between /dev/audio and /dev/dsp
+     * is that the former uses logarithmic mu-law encoding and the
+     * latter uses 8-bit unsigned encoding.
+     */
+
+    if (basedev == NULL) {              /* called with one arg */
+       basedev = getenv("AUDIODEV");
+       if (basedev == NULL)             /* $AUDIODEV not set */
+          basedev = "/dev/dsp";
+    }
+
+    if ((fd = open(basedev, imode)) == -1) {
+        PyErr_SetFromErrnoWithFilename(LinuxAudioError, basedev);
+        return NULL;
+    }
+    if (imode == O_WRONLY && ioctl(fd, SNDCTL_DSP_NONBLOCK, NULL) == -1) {
+        PyErr_SetFromErrnoWithFilename(LinuxAudioError, basedev);
+        return NULL;
+    }
+    if (ioctl(fd, SNDCTL_DSP_GETFMTS, &afmts) == -1) {
+        PyErr_SetFromErrnoWithFilename(LinuxAudioError, basedev);
+        return NULL;
+    }
+    /* Create and initialize the object */
+    if ((xp = PyObject_New(lad_t, &Ladtype)) == NULL) {
+        close(fd);
+        return NULL;
+    }
+    xp->x_fd = fd;
+    xp->x_mode = imode;
+    xp->x_icount = xp->x_ocount = 0;
+    xp->x_afmts  = afmts;
+    return xp;
+}
+
+static void
+lad_dealloc(lad_t *xp)
+{
+    /* if already closed, don't reclose it */
+    if (xp->x_fd != -1)
+	close(xp->x_fd);
+    PyObject_Del(xp);
+}
+
+static PyObject *
+lad_read(lad_t *self, PyObject *args)
+{
+    int size, count;
+    char *cp;
+    PyObject *rv;
+	
+    if (!PyArg_ParseTuple(args, "i:read", &size))
+        return NULL;
+    rv = PyString_FromStringAndSize(NULL, size);
+    if (rv == NULL)
+        return NULL;
+    cp = PyString_AS_STRING(rv);
+    if ((count = read(self->x_fd, cp, size)) < 0) {
+        PyErr_SetFromErrno(LinuxAudioError);
+        Py_DECREF(rv);
+        return NULL;
+    }
+    self->x_icount += count;
+    _PyString_Resize(&rv, count);
+    return rv;
+}
+
+static PyObject *
+lad_write(lad_t *self, PyObject *args)
+{
+    char *cp;
+    int rv, size;
+    fd_set write_set_fds;
+    struct timeval tv;
+    int select_retval;
+    
+    if (!PyArg_ParseTuple(args, "s#:write", &cp, &size)) 
+	return NULL;
+
+    /* use select to wait for audio device to be available */
+    FD_ZERO(&write_set_fds);
+    FD_SET(self->x_fd, &write_set_fds);
+    tv.tv_sec = 4; /* timeout values */
+    tv.tv_usec = 0; 
+
+    while (size > 0) {
+      select_retval = select(self->x_fd+1, NULL, &write_set_fds, NULL, &tv);
+      tv.tv_sec = 1; tv.tv_usec = 0; /* willing to wait this long next time*/
+      if (select_retval) {
+        if ((rv = write(self->x_fd, cp, size)) == -1) {
+	  if (errno != EAGAIN) {
+	    PyErr_SetFromErrno(LinuxAudioError);
+	    return NULL;
+	  } else {
+	    errno = 0; /* EAGAIN: buffer is full, try again */
+	  }
+        } else {
+	  self->x_ocount += rv;
+	  size -= rv;
+	  cp += rv;
+	}
+      } else {
+	/* printf("Not able to write to linux audio device within %ld seconds\n", tv.tv_sec); */
+	PyErr_SetFromErrno(LinuxAudioError);
+	return NULL;
+      }
+    }
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject *
+lad_close(lad_t *self, PyObject *unused)
+{
+    if (self->x_fd >= 0) {
+        close(self->x_fd);
+        self->x_fd = -1;
+    }
+    Py_RETURN_NONE;
+}
+
+static PyObject *
+lad_fileno(lad_t *self, PyObject *unused)
+{
+    return PyInt_FromLong(self->x_fd);
+}
+
+static PyObject *
+lad_setparameters(lad_t *self, PyObject *args)
+{
+    int rate, ssize, nchannels, n, fmt, emulate=0;
+
+    if (!PyArg_ParseTuple(args, "iiii|i:setparameters",
+                          &rate, &ssize, &nchannels, &fmt, &emulate))
+        return NULL;
+  
+    if (rate < 0) {
+	PyErr_Format(PyExc_ValueError, "expected rate >= 0, not %d",
+		     rate); 
+	return NULL;
+    }
+    if (ssize < 0) {
+	PyErr_Format(PyExc_ValueError, "expected sample size >= 0, not %d",
+		     ssize);
+	return NULL;
+    }
+    if (nchannels != 1 && nchannels != 2) {
+	PyErr_Format(PyExc_ValueError, "nchannels must be 1 or 2, not %d",
+		     nchannels);
+	return NULL;
+    }
+
+    for (n = 0; n < n_audio_types; n++)
+        if (fmt == audio_types[n].a_fmt)
+            break;
+    if (n == n_audio_types) {
+	PyErr_Format(PyExc_ValueError, "unknown audio encoding: %d", fmt);
+	return NULL;
+    }
+    if (audio_types[n].a_bps != ssize) {
+	PyErr_Format(PyExc_ValueError, 
+		     "for %s, expected sample size %d, not %d",
+		     audio_types[n].a_name, audio_types[n].a_bps, ssize);
+	return NULL;
+    }
+
+    if (emulate == 0) {
+	if ((self->x_afmts & audio_types[n].a_fmt) == 0) {
+	    PyErr_Format(PyExc_ValueError, 
+			 "%s format not supported by device",
+			 audio_types[n].a_name);
+	    return NULL;
+	}
+    }
+    if (ioctl(self->x_fd, SNDCTL_DSP_SETFMT, 
+	      &audio_types[n].a_fmt) == -1) {
+        PyErr_SetFromErrno(LinuxAudioError);
+        return NULL;
+    }
+    if (ioctl(self->x_fd, SNDCTL_DSP_CHANNELS, &nchannels) == -1) {
+        PyErr_SetFromErrno(LinuxAudioError);
+        return NULL;
+    }
+    if (ioctl(self->x_fd, SNDCTL_DSP_SPEED, &rate) == -1) {
+        PyErr_SetFromErrno(LinuxAudioError);
+        return NULL;
+    }
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static int
+_ssize(lad_t *self, int *nchannels, int *ssize)
+{
+    int fmt;
+
+    fmt = 0;
+    if (ioctl(self->x_fd, SNDCTL_DSP_SETFMT, &fmt) < 0) 
+        return -errno;
+
+    switch (fmt) {
+    case AFMT_MU_LAW:
+    case AFMT_A_LAW:
+    case AFMT_U8:
+    case AFMT_S8:
+        *ssize = sizeof(char);
+        break;
+    case AFMT_S16_LE:
+    case AFMT_S16_BE:
+    case AFMT_U16_LE:
+    case AFMT_U16_BE:
+        *ssize = sizeof(short);
+        break;
+    case AFMT_MPEG:
+    case AFMT_IMA_ADPCM:
+    default:
+        return -EOPNOTSUPP;
+    }
+    if (ioctl(self->x_fd, SNDCTL_DSP_CHANNELS, nchannels) < 0)
+        return -errno;
+    return 0;
+}
+
+
+/* bufsize returns the size of the hardware audio buffer in number 
+   of samples */
+static PyObject *
+lad_bufsize(lad_t *self, PyObject *unused)
+{
+    audio_buf_info ai;
+    int nchannels=0, ssize=0;
+
+    if (_ssize(self, &nchannels, &ssize) < 0 || !ssize || !nchannels) {
+        PyErr_SetFromErrno(LinuxAudioError);
+        return NULL;
+    }
+    if (ioctl(self->x_fd, SNDCTL_DSP_GETOSPACE, &ai) < 0) {
+        PyErr_SetFromErrno(LinuxAudioError);
+        return NULL;
+    }
+    return PyInt_FromLong((ai.fragstotal * ai.fragsize) / (nchannels * ssize));
+}
+
+/* obufcount returns the number of samples that are available in the 
+   hardware for playing */
+static PyObject *
+lad_obufcount(lad_t *self, PyObject *unused)
+{
+    audio_buf_info ai;
+    int nchannels=0, ssize=0;
+
+    if (_ssize(self, &nchannels, &ssize) < 0 || !ssize || !nchannels) {
+        PyErr_SetFromErrno(LinuxAudioError);
+        return NULL;
+    }
+    if (ioctl(self->x_fd, SNDCTL_DSP_GETOSPACE, &ai) < 0) {
+        PyErr_SetFromErrno(LinuxAudioError);
+        return NULL;
+    }
+    return PyInt_FromLong((ai.fragstotal * ai.fragsize - ai.bytes) / 
+                          (ssize * nchannels));
+}
+
+/* obufcount returns the number of samples that can be played without
+   blocking */
+static PyObject *
+lad_obuffree(lad_t *self, PyObject *unused)
+{
+    audio_buf_info ai;
+    int nchannels=0, ssize=0;
+
+    if (_ssize(self, &nchannels, &ssize) < 0 || !ssize || !nchannels) {
+        PyErr_SetFromErrno(LinuxAudioError);
+        return NULL;
+    }
+    if (ioctl(self->x_fd, SNDCTL_DSP_GETOSPACE, &ai) < 0) {
+        PyErr_SetFromErrno(LinuxAudioError);
+        return NULL;
+    }
+    return PyInt_FromLong(ai.bytes / (ssize * nchannels));
+}
+
+/* Flush the device */
+static PyObject *
+lad_flush(lad_t *self, PyObject *unused)
+{
+    if (ioctl(self->x_fd, SNDCTL_DSP_SYNC, NULL) == -1) {
+        PyErr_SetFromErrno(LinuxAudioError);
+        return NULL;
+    }
+    Py_RETURN_NONE;
+}
+
+static PyObject *
+lad_getptr(lad_t *self, PyObject *unused)
+{
+    count_info info;
+    int req;
+
+    if (self->x_mode == O_RDONLY)
+	req = SNDCTL_DSP_GETIPTR;
+    else
+	req = SNDCTL_DSP_GETOPTR;
+    if (ioctl(self->x_fd, req, &info) == -1) {
+        PyErr_SetFromErrno(LinuxAudioError);
+        return NULL;
+    }
+    return Py_BuildValue("iii", info.bytes, info.blocks, info.ptr);
+}
+
+static PyMethodDef lad_methods[] = {
+    { "read",		(PyCFunction)lad_read, METH_VARARGS },
+    { "write",		(PyCFunction)lad_write, METH_VARARGS },
+    { "setparameters",	(PyCFunction)lad_setparameters, METH_VARARGS },
+    { "bufsize",	(PyCFunction)lad_bufsize, METH_VARARGS },
+    { "obufcount",	(PyCFunction)lad_obufcount, METH_NOARGS },
+    { "obuffree",	(PyCFunction)lad_obuffree, METH_NOARGS },
+    { "flush",		(PyCFunction)lad_flush, METH_NOARGS },
+    { "close",		(PyCFunction)lad_close, METH_NOARGS },
+    { "fileno",     	(PyCFunction)lad_fileno, METH_NOARGS },
+    { "getptr",         (PyCFunction)lad_getptr, METH_NOARGS },
+    { NULL,		NULL}		/* sentinel */
+};
+
+static PyObject *
+lad_getattr(lad_t *xp, char *name)
+{
+    return Py_FindMethod(lad_methods, (PyObject *)xp, name);
+}
+
+static PyTypeObject Ladtype = {
+    PyObject_HEAD_INIT(&PyType_Type)
+    0,				/*ob_size*/
+    "linuxaudiodev.linux_audio_device", /*tp_name*/
+    sizeof(lad_t),		/*tp_size*/
+    0,				/*tp_itemsize*/
+    /* methods */
+    (destructor)lad_dealloc,	/*tp_dealloc*/
+    0,				/*tp_print*/
+    (getattrfunc)lad_getattr,	/*tp_getattr*/
+    0,				/*tp_setattr*/
+    0,				/*tp_compare*/
+    0,				/*tp_repr*/
+};
+
+static PyObject *
+ladopen(PyObject *self, PyObject *args)
+{
+    return (PyObject *)newladobject(args);
+}
+
+static PyMethodDef linuxaudiodev_methods[] = {
+    { "open", ladopen, METH_VARARGS },
+    { 0, 0 },
+};
+
+void
+initlinuxaudiodev(void)
+{
+    PyObject *m;
+  
+    m = Py_InitModule("linuxaudiodev", linuxaudiodev_methods);
+    if (m == NULL)
+	return;
+
+    LinuxAudioError = PyErr_NewException("linuxaudiodev.error", NULL, NULL);
+    if (LinuxAudioError)
+	PyModule_AddObject(m, "error", LinuxAudioError);
+
+    if (PyModule_AddIntConstant(m, "AFMT_MU_LAW", (long)AFMT_MU_LAW) == -1)
+	return;
+    if (PyModule_AddIntConstant(m, "AFMT_A_LAW", (long)AFMT_A_LAW) == -1)
+	return;
+    if (PyModule_AddIntConstant(m, "AFMT_U8", (long)AFMT_U8) == -1)
+	return;
+    if (PyModule_AddIntConstant(m, "AFMT_S8", (long)AFMT_S8) == -1)
+	return;
+    if (PyModule_AddIntConstant(m, "AFMT_U16_BE", (long)AFMT_U16_BE) == -1)
+	return;
+    if (PyModule_AddIntConstant(m, "AFMT_U16_LE", (long)AFMT_U16_LE) == -1)
+	return;
+    if (PyModule_AddIntConstant(m, "AFMT_S16_BE", (long)AFMT_S16_BE) == -1)
+	return;
+    if (PyModule_AddIntConstant(m, "AFMT_S16_LE", (long)AFMT_S16_LE) == -1)
+	return;
+    if (PyModule_AddIntConstant(m, "AFMT_S16_NE", (long)AFMT_S16_NE) == -1)
+	return;
+
+    return;
+}

Added: vendor/Python/current/Modules/main.c
===================================================================
--- vendor/Python/current/Modules/main.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/main.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,584 @@
+/* Python interpreter main program */
+
+#include "Python.h"
+#include "osdefs.h"
+#include "code.h" /* For CO_FUTURE_DIVISION */
+#include "import.h"
+
+#ifdef __VMS
+#include <unixlib.h>
+#endif
+
+#if defined(MS_WINDOWS) || defined(__CYGWIN__)
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#endif
+
+#if (defined(PYOS_OS2) && !defined(PYCC_GCC)) || defined(MS_WINDOWS)
+#define PYTHONHOMEHELP "<prefix>\\lib"
+#else
+#if defined(PYOS_OS2) && defined(PYCC_GCC)
+#define PYTHONHOMEHELP "<prefix>/Lib"
+#else
+#define PYTHONHOMEHELP "<prefix>/pythonX.X"
+#endif
+#endif
+
+#include "pygetopt.h"
+
+#define COPYRIGHT \
+    "Type \"help\", \"copyright\", \"credits\" or \"license\" " \
+    "for more information."
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* For Py_GetArgcArgv(); set by main() */
+static char **orig_argv;
+static int  orig_argc;
+
+/* command line options */
+#define BASE_OPTS "c:dEhim:OQ:StuUvVW:xX?"
+
+#ifndef RISCOS
+#define PROGRAM_OPTS BASE_OPTS
+#else /*RISCOS*/
+/* extra option saying that we are running under a special task window
+   frontend; especially my_readline will behave different */
+#define PROGRAM_OPTS BASE_OPTS "w"
+/* corresponding flag */
+extern int Py_RISCOSWimpFlag;
+#endif /*RISCOS*/
+
+/* Short usage message (with %s for argv0) */
+static char *usage_line =
+"usage: %s [option] ... [-c cmd | -m mod | file | -] [arg] ...\n";
+
+/* Long usage message, split into parts < 512 bytes */
+static char *usage_1 = "\
+Options and arguments (and corresponding environment variables):\n\
+-c cmd : program passed in as string (terminates option list)\n\
+-d     : debug output from parser (also PYTHONDEBUG=x)\n\
+-E     : ignore environment variables (such as PYTHONPATH)\n\
+-h     : print this help message and exit (also --help)\n\
+-i     : inspect interactively after running script, (also PYTHONINSPECT=x)\n\
+         and force prompts, even if stdin does not appear to be a terminal\n\
+";
+static char *usage_2 = "\
+-m mod : run library module as a script (terminates option list)\n\
+-O     : optimize generated bytecode (a tad; also PYTHONOPTIMIZE=x)\n\
+-OO    : remove doc-strings in addition to the -O optimizations\n\
+-Q arg : division options: -Qold (default), -Qwarn, -Qwarnall, -Qnew\n\
+-S     : don't imply 'import site' on initialization\n\
+-t     : issue warnings about inconsistent tab usage (-tt: issue errors)\n\
+-u     : unbuffered binary stdout and stderr (also PYTHONUNBUFFERED=x)\n\
+";
+static char *usage_3 = "\
+         see man page for details on internal buffering relating to '-u'\n\
+-v     : verbose (trace import statements) (also PYTHONVERBOSE=x)\n\
+-V     : print the Python version number and exit (also --version)\n\
+-W arg : warning control (arg is action:message:category:module:lineno)\n\
+-x     : skip first line of source, allowing use of non-Unix forms of #!cmd\n\
+file   : program read from script file\n\
+-      : program read from stdin (default; interactive mode if a tty)\n\
+";
+static char *usage_4 = "\
+arg ...: arguments passed to program in sys.argv[1:]\n\
+Other environment variables:\n\
+PYTHONSTARTUP: file executed on interactive startup (no default)\n\
+PYTHONPATH   : '%c'-separated list of directories prefixed to the\n\
+               default module search path.  The result is sys.path.\n\
+PYTHONHOME   : alternate <prefix> directory (or <prefix>%c<exec_prefix>).\n\
+               The default module search path uses %s.\n\
+PYTHONCASEOK : ignore case in 'import' statements (Windows).\n\
+";
+
+
+static int
+usage(int exitcode, char* program)
+{
+	FILE *f = exitcode ? stderr : stdout;
+
+	fprintf(f, usage_line, program);
+	if (exitcode)
+		fprintf(f, "Try `python -h' for more information.\n");
+	else {
+		fprintf(f, usage_1);
+		fprintf(f, usage_2);
+		fprintf(f, usage_3);
+		fprintf(f, usage_4, DELIM, DELIM, PYTHONHOMEHELP);
+	}
+#if defined(__VMS)
+	if (exitcode == 0) {
+		/* suppress 'error' message */
+		return 1;
+	}
+	else {
+		/* STS$M_INHIB_MSG + SS$_ABORT */
+		return 0x1000002c;
+	}
+#else
+	return exitcode;
+#endif
+	/*NOTREACHED*/
+}
+
+static void RunStartupFile(PyCompilerFlags *cf)
+{
+	char *startup = Py_GETENV("PYTHONSTARTUP");
+	if (startup != NULL && startup[0] != '\0') {
+		FILE *fp = fopen(startup, "r");
+		if (fp != NULL) {
+			(void) PyRun_SimpleFileExFlags(fp, startup, 0, cf);
+			PyErr_Clear();
+			fclose(fp);
+		}
+	}
+}
+
+
+static int RunModule(char *module)
+{
+	PyObject *runpy, *runmodule, *runargs, *result;
+	runpy = PyImport_ImportModule("runpy");
+	if (runpy == NULL) {
+		fprintf(stderr, "Could not import runpy module\n");
+		return -1;
+	}
+	runmodule = PyObject_GetAttrString(runpy, "run_module");
+	if (runmodule == NULL) {
+		fprintf(stderr, "Could not access runpy.run_module\n");
+		Py_DECREF(runpy);
+		return -1;
+	}
+	runargs = Py_BuildValue("sOsO", module,
+							Py_None, "__main__", Py_True);
+	if (runargs == NULL) {
+		fprintf(stderr,
+				"Could not create arguments for runpy.run_module\n");
+		Py_DECREF(runpy);
+		Py_DECREF(runmodule);
+		return -1;
+	}
+	result = PyObject_Call(runmodule, runargs, NULL);
+	if (result == NULL) {
+		PyErr_Print();
+	}
+	Py_DECREF(runpy);
+	Py_DECREF(runmodule);
+	Py_DECREF(runargs);
+	if (result == NULL) {
+		return -1;
+	}
+	Py_DECREF(result);
+	return 0;
+}
+
+/* Wait until threading._shutdown completes, provided
+   the threading module was imported in the first place.
+   The shutdown routine will wait until all non-daemon
+   "threading" threads have completed. */
+#include "abstract.h"
+static void
+WaitForThreadShutdown()
+{
+#ifdef WITH_THREAD
+	PyObject *result;
+	PyThreadState *tstate = PyThreadState_GET();
+	PyObject *threading = PyMapping_GetItemString(tstate->interp->modules,
+						      "threading");
+	if (threading == NULL) {
+		/* threading not imported */
+		PyErr_Clear();
+		return;
+	}
+	result = PyObject_CallMethod(threading, "_shutdown", "");
+	if (result == NULL)
+		PyErr_WriteUnraisable(threading);
+	else
+		Py_DECREF(result);
+	Py_DECREF(threading);
+#endif
+}
+
+/* Main program */
+
+int
+Py_Main(int argc, char **argv)
+{
+	int c;
+	int sts;
+	char *command = NULL;
+	char *filename = NULL;
+	char *module = NULL;
+	FILE *fp = stdin;
+	char *p;
+	int inspect = 0;
+	int unbuffered = 0;
+	int skipfirstline = 0;
+	int stdin_is_interactive = 0;
+	int help = 0;
+	int version = 0;
+	int saw_inspect_flag = 0;
+	int saw_unbuffered_flag = 0;
+	PyCompilerFlags cf;
+
+	cf.cf_flags = 0;
+
+	orig_argc = argc;	/* For Py_GetArgcArgv() */
+	orig_argv = argv;
+
+#ifdef RISCOS
+	Py_RISCOSWimpFlag = 0;
+#endif
+
+	PySys_ResetWarnOptions();
+
+	while ((c = _PyOS_GetOpt(argc, argv, PROGRAM_OPTS)) != EOF) {
+		if (c == 'c') {
+			/* -c is the last option; following arguments
+			   that look like options are left for the
+			   command to interpret. */
+			command = (char *)malloc(strlen(_PyOS_optarg) + 2);
+			if (command == NULL)
+				Py_FatalError(
+				   "not enough memory to copy -c argument");
+			strcpy(command, _PyOS_optarg);
+			strcat(command, "\n");
+			break;
+		}
+
+		if (c == 'm') {
+			/* -m is the last option; following arguments
+			   that look like options are left for the
+			   module to interpret. */
+			module = (char *)malloc(strlen(_PyOS_optarg) + 2);
+			if (module == NULL)
+				Py_FatalError(
+				   "not enough memory to copy -m argument");
+			strcpy(module, _PyOS_optarg);
+			break;
+		}
+
+		switch (c) {
+
+		case 'd':
+			Py_DebugFlag++;
+			break;
+
+		case 'Q':
+			if (strcmp(_PyOS_optarg, "old") == 0) {
+				Py_DivisionWarningFlag = 0;
+				break;
+			}
+			if (strcmp(_PyOS_optarg, "warn") == 0) {
+				Py_DivisionWarningFlag = 1;
+				break;
+			}
+			if (strcmp(_PyOS_optarg, "warnall") == 0) {
+				Py_DivisionWarningFlag = 2;
+				break;
+			}
+			if (strcmp(_PyOS_optarg, "new") == 0) {
+				/* This only affects __main__ */
+				cf.cf_flags |= CO_FUTURE_DIVISION;
+				/* And this tells the eval loop to treat
+				   BINARY_DIVIDE as BINARY_TRUE_DIVIDE */
+				_Py_QnewFlag = 1;
+				break;
+			}
+			fprintf(stderr,
+				"-Q option should be `-Qold', "
+				"`-Qwarn', `-Qwarnall', or `-Qnew' only\n");
+			return usage(2, argv[0]);
+			/* NOTREACHED */
+
+		case 'i':
+			inspect++;
+			saw_inspect_flag = 1;
+			Py_InteractiveFlag++;
+			break;
+
+		case 'O':
+			Py_OptimizeFlag++;
+			break;
+
+		case 'S':
+			Py_NoSiteFlag++;
+			break;
+
+		case 'E':
+			Py_IgnoreEnvironmentFlag++;
+			break;
+
+		case 't':
+			Py_TabcheckFlag++;
+			break;
+
+		case 'u':
+			unbuffered++;
+			saw_unbuffered_flag = 1;
+			break;
+
+		case 'v':
+			Py_VerboseFlag++;
+			break;
+
+#ifdef RISCOS
+		case 'w':
+			Py_RISCOSWimpFlag = 1;
+			break;
+#endif
+
+		case 'x':
+			skipfirstline = 1;
+			break;
+
+		case 'U':
+			Py_UnicodeFlag++;
+			break;
+		case 'h':
+		case '?':
+			help++;
+			break;
+		case 'V':
+			version++;
+			break;
+
+		case 'W':
+			PySys_AddWarnOption(_PyOS_optarg);
+			break;
+
+		/* This space reserved for other options */
+
+		default:
+			return usage(2, argv[0]);
+			/*NOTREACHED*/
+
+		}
+	}
+
+	if (help)
+		return usage(0, argv[0]);
+
+	if (version) {
+		fprintf(stderr, "Python %s\n", PY_VERSION);
+		return 0;
+	}
+
+	if (!saw_inspect_flag &&
+	    (p = Py_GETENV("PYTHONINSPECT")) && *p != '\0')
+		inspect = 1;
+	if (!saw_unbuffered_flag &&
+	    (p = Py_GETENV("PYTHONUNBUFFERED")) && *p != '\0')
+		unbuffered = 1;
+
+	if (command == NULL && module == NULL && _PyOS_optind < argc &&
+	    strcmp(argv[_PyOS_optind], "-") != 0)
+	{
+#ifdef __VMS
+		filename = decc$translate_vms(argv[_PyOS_optind]);
+		if (filename == (char *)0 || filename == (char *)-1)
+			filename = argv[_PyOS_optind];
+
+#else
+		filename = argv[_PyOS_optind];
+#endif
+		if (filename != NULL) {
+			if ((fp = fopen(filename, "r")) == NULL) {
+#ifdef HAVE_STRERROR
+				fprintf(stderr, "%s: can't open file '%s': [Errno %d] %s\n",
+					argv[0], filename, errno, strerror(errno));
+#else
+				fprintf(stderr, "%s: can't open file '%s': Errno %d\n",
+					argv[0], filename, errno);
+#endif
+				return 2;
+			}
+			else if (skipfirstline) {
+				int ch;
+				/* Push back first newline so line numbers
+				   remain the same */
+				while ((ch = getc(fp)) != EOF) {
+					if (ch == '\n') {
+						(void)ungetc(ch, fp);
+						break;
+					}
+				}
+			}
+			{
+				/* XXX: does this work on Win/Win64? (see posix_fstat) */
+				struct stat sb;
+				if (fstat(fileno(fp), &sb) == 0 &&
+				    S_ISDIR(sb.st_mode)) {
+					fprintf(stderr, "%s: '%s' is a directory, cannot continue\n", argv[0], filename);
+					return 1;
+				}
+			}
+		}
+	}
+
+	stdin_is_interactive = Py_FdIsInteractive(stdin, (char *)0);
+
+	if (unbuffered) {
+#if defined(MS_WINDOWS) || defined(__CYGWIN__)
+		_setmode(fileno(stdin), O_BINARY);
+		_setmode(fileno(stdout), O_BINARY);
+#endif
+#ifdef HAVE_SETVBUF
+		setvbuf(stdin,  (char *)NULL, _IONBF, BUFSIZ);
+		setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
+		setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ);
+#else /* !HAVE_SETVBUF */
+		setbuf(stdin,  (char *)NULL);
+		setbuf(stdout, (char *)NULL);
+		setbuf(stderr, (char *)NULL);
+#endif /* !HAVE_SETVBUF */
+	}
+	else if (Py_InteractiveFlag) {
+#ifdef MS_WINDOWS
+		/* Doesn't have to have line-buffered -- use unbuffered */
+		/* Any set[v]buf(stdin, ...) screws up Tkinter :-( */
+		setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
+#else /* !MS_WINDOWS */
+#ifdef HAVE_SETVBUF
+		setvbuf(stdin,  (char *)NULL, _IOLBF, BUFSIZ);
+		setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
+#endif /* HAVE_SETVBUF */
+#endif /* !MS_WINDOWS */
+		/* Leave stderr alone - it should be unbuffered anyway. */
+  	}
+#ifdef __VMS
+	else {
+		setvbuf (stdout, (char *)NULL, _IOLBF, BUFSIZ);
+	}
+#endif /* __VMS */
+
+#ifdef __APPLE__
+	/* On MacOS X, when the Python interpreter is embedded in an
+	   application bundle, it gets executed by a bootstrapping script
+	   that does os.execve() with an argv[0] that's different from the
+	   actual Python executable. This is needed to keep the Finder happy,
+	   or rather, to work around Apple's overly strict requirements of
+	   the process name. However, we still need a usable sys.executable,
+	   so the actual executable path is passed in an environment variable.
+	   See Lib/plat-mac/bundlebuiler.py for details about the bootstrap
+	   script. */
+	if ((p = Py_GETENV("PYTHONEXECUTABLE")) && *p != '\0')
+		Py_SetProgramName(p);
+	else
+		Py_SetProgramName(argv[0]);
+#else
+	Py_SetProgramName(argv[0]);
+#endif
+	Py_Initialize();
+
+	if (Py_VerboseFlag ||
+	    (command == NULL && filename == NULL && module == NULL && stdin_is_interactive)) {
+		fprintf(stderr, "Python %s on %s\n",
+			Py_GetVersion(), Py_GetPlatform());
+ 		if (!Py_NoSiteFlag)
+ 			fprintf(stderr, "%s\n", COPYRIGHT);
+	}
+
+	if (command != NULL) {
+		/* Backup _PyOS_optind and force sys.argv[0] = '-c' */
+		_PyOS_optind--;
+		argv[_PyOS_optind] = "-c";
+	}
+
+	if (module != NULL) {
+		/* Backup _PyOS_optind and force sys.argv[0] = '-c'
+		   so that PySys_SetArgv correctly sets sys.path[0] to ''*/
+		_PyOS_optind--;
+		argv[_PyOS_optind] = "-c";
+	}
+
+	PySys_SetArgv(argc-_PyOS_optind, argv+_PyOS_optind);
+
+	if ((inspect || (command == NULL && filename == NULL && module == NULL)) &&
+	    isatty(fileno(stdin))) {
+		PyObject *v;
+		v = PyImport_ImportModule("readline");
+		if (v == NULL)
+			PyErr_Clear();
+		else
+			Py_DECREF(v);
+	}
+
+	if (command) {
+		sts = PyRun_SimpleStringFlags(command, &cf) != 0;
+		free(command);
+	} else if (module) {
+		sts = RunModule(module);
+		free(module);
+	}
+	else {
+		if (filename == NULL && stdin_is_interactive) {
+			RunStartupFile(&cf);
+		}
+		/* XXX */
+		sts = PyRun_AnyFileExFlags(
+			fp,
+			filename == NULL ? "<stdin>" : filename,
+			filename != NULL, &cf) != 0;
+	}
+
+	/* Check this environment variable at the end, to give programs the
+	 * opportunity to set it from Python.
+	 */
+	if (!saw_inspect_flag &&
+	    (p = Py_GETENV("PYTHONINSPECT")) && *p != '\0')
+	{
+		inspect = 1;
+	}
+
+	if (inspect && stdin_is_interactive &&
+	    (filename != NULL || command != NULL || module != NULL))
+		/* XXX */
+		sts = PyRun_AnyFileFlags(stdin, "<stdin>", &cf) != 0;
+
+	WaitForThreadShutdown();
+
+	Py_Finalize();
+#ifdef RISCOS
+	if (Py_RISCOSWimpFlag)
+                fprintf(stderr, "\x0cq\x0c"); /* make frontend quit */
+#endif
+
+#ifdef __INSURE__
+	/* Insure++ is a memory analysis tool that aids in discovering
+	 * memory leaks and other memory problems.  On Python exit, the
+	 * interned string dictionary is flagged as being in use at exit
+	 * (which it is).  Under normal circumstances, this is fine because
+	 * the memory will be automatically reclaimed by the system.  Under
+	 * memory debugging, it's a huge source of useless noise, so we
+	 * trade off slower shutdown for less distraction in the memory
+	 * reports.  -baw
+	 */
+	_Py_ReleaseInternedStrings();
+#endif /* __INSURE__ */
+
+	return sts;
+}
+
+/* this is gonna seem *real weird*, but if you put some other code between
+   Py_Main() and Py_GetArgcArgv() you will need to adjust the test in the
+   while statement in Misc/gdbinit:ppystack */
+
+/* Make the *original* argc/argv available to other modules.
+   This is rare, but it is needed by the secureware extension. */
+
+void
+Py_GetArgcArgv(int *argc, char ***argv)
+{
+	*argc = orig_argc;
+	*argv = orig_argv;
+}
+
+#ifdef __cplusplus
+}
+#endif
+

Added: vendor/Python/current/Modules/makesetup
===================================================================
--- vendor/Python/current/Modules/makesetup	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/makesetup	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,297 @@
+#! /bin/sh
+
+# Convert templates into Makefile and config.c, based on the module
+# definitions found in the file Setup.
+#
+# Usage: makesetup [-s dir] [-c file] [-m file] [Setup] ... [-n [Setup] ...]
+#
+# Options:
+# -s directory: alternative source directory (default .)
+# -l directory: library source directory (default derived from $0)
+# -c file:      alternative config.c template (default $libdir/config.c.in)
+# -c -:         don't write config.c
+# -m file:      alternative Makefile template (default ./Makefile.pre)
+# -m -:         don't write Makefile
+#
+# Remaining arguments are one or more Setup files (default ./Setup).
+# Setup files after a -n option are used for their variables, modules
+# and libraries but not for their .o files.
+#
+# See Setup.dist for a description of the format of the Setup file.
+#
+# The following edits are made:
+#
+# Copying config.c.in to config.c:
+# - insert an identifying comment at the start
+# - for each <module> mentioned in Setup before *noconfig*:
+#   + insert 'extern void init<module>(void);' before MARKER 1
+#   + insert '{"<module>", initmodule},' before MARKER 2
+#
+# Copying Makefile.pre to Makefile:
+# - insert an identifying comment at the start
+# - replace _MODOBJS_ by the list of objects from Setup (except for
+#   Setup files after a -n option)
+# - replace _MODLIBS_ by the list of libraries from Setup
+# - for each object file mentioned in Setup, append a rule
+#   '<file>.o: <file>.c; <build commands>' to the end of the Makefile
+# - for each module mentioned in Setup, append a rule
+#   which creates a shared library version to the end of the Makefile
+# - for each variable definition found in Setup, insert the definition
+#   before the comment 'Definitions added by makesetup'
+
+# Loop over command line options
+usage='
+usage: makesetup [-s srcdir] [-l libdir] [-c config.c.in] [-m Makefile.pre]
+                 [Setup] ... [-n [Setup] ...]'
+srcdir='.'
+libdir=''
+config=''
+makepre=''
+noobjects=''
+doconfig=yes
+while :
+do
+	case $1 in
+	-s)	shift; srcdir=$1; shift;;
+	-l)	shift; libdir=$1; shift;;
+	-c)	shift; config=$1; shift;;
+	-m)	shift; makepre=$1; shift;;
+	--)	shift; break;;
+	-n)	noobjects=yes;;
+	-*)	echo "$usage" 1>&2; exit 2;;
+	*)	break;;
+	esac
+done
+
+# Set default libdir and config if not set by command line
+# (Not all systems have dirname)
+case $libdir in
+'')	case $0 in
+	*/*)	libdir=`echo $0 | sed 's,/[^/]*$,,'`;;
+	*)	libdir=.;;
+	esac;;
+esac
+case $config in
+'')	config=$libdir/config.c.in;;
+esac
+case $makepre in
+'')	makepre=Makefile.pre;;
+esac
+
+# Newline for sed i and a commands
+NL='\
+'
+
+# Setup to link with extra libraries when makeing shared extensions.
+# Currently, only Cygwin needs this baggage.
+case `uname -s` in
+CYGWIN*) if test $libdir = .
+	 then
+	 	ExtraLibDir=.
+	 else
+	 	ExtraLibDir='$(LIBPL)'
+	 fi
+	 ExtraLibs="-L$ExtraLibDir -lpython\$(VERSION)";;
+esac
+
+# Main loop
+for i in ${*-Setup}
+do
+	case $i in
+	-n)	echo '*noobjects*';;
+	*)	echo '*doconfig*'; cat "$i";;
+	esac
+done |
+sed -e 's/[ 	]*#.*//' -e '/^[ 	]*$/d' |
+(
+	rulesf="@rules.$$"
+	trap 'rm -f $rulesf' 0 1 2 3
+	echo "
+# Rules appended by makedepend
+" >$rulesf
+	DEFS=
+	MODS=
+	SHAREDMODS=
+	OBJS=
+	LIBS=
+	LOCALLIBS=
+	BASELIBS=
+	while read line
+	do
+		# to handle backslashes for sh's that don't automatically
+		# continue a read when the last char is a backslash
+		while echo $line | grep '\\$' > /dev/null
+		do
+			read extraline
+			line=`echo $line| sed s/.$//`$extraline
+		done
+
+		# Output DEFS in reverse order so first definition overrides
+		case $line in
+		*=*)	DEFS="$line$NL$DEFS"; continue;;
+		'include '*)	DEFS="$line$NL$DEFS"; continue;;
+		'*noobjects*')
+			case $noobjects in
+			yes)	;;
+			*)	LOCALLIBS=$LIBS; LIBS=;;
+			esac
+			noobjects=yes;
+			continue;;
+		'*doconfig*')	doconfig=yes; continue;;
+		'*static*')	doconfig=yes; continue;;
+		'*noconfig*')	doconfig=no; continue;;
+		'*shared*')	doconfig=no; continue;;
+		esac
+		srcs=
+		cpps=
+		libs=
+		mods=
+		skip=
+		for arg in $line
+		do
+			case $skip in
+			libs)	libs="$libs $arg"; skip=; continue;;
+			cpps)	cpps="$cpps $arg"; skip=; continue;;
+			srcs)	srcs="$srcs $arg"; skip=; continue;;
+			esac
+			case $arg in
+			-framework)	libs="$libs $arg"; skip=libs;
+				        # OSX/OSXS/Darwin framework link cmd
+					;;
+			-[IDUCfF]*)	cpps="$cpps $arg";;
+			-Xcompiler)	skip=cpps;;
+			-Xlinker)	libs="$libs $arg"; skip=libs;;
+			-rpath)		libs="$libs $arg"; skip=libs;;
+			--rpath)	libs="$libs $arg"; skip=libs;;
+			-[A-Zl]*)	libs="$libs $arg";;
+			*.a)		libs="$libs $arg";;
+			*.so)		libs="$libs $arg";;
+			*.sl)		libs="$libs $arg";;
+			/*.o)		libs="$libs $arg";;
+			*.def)		libs="$libs $arg";;
+			*.o)		srcs="$srcs `basename $arg .o`.c";;
+			*.[cC])		srcs="$srcs $arg";;
+			*.m)		srcs="$srcs $arg";; # Objective-C src
+			*.cc)		srcs="$srcs $arg";;
+			*.c++)		srcs="$srcs $arg";;
+			*.cxx)		srcs="$srcs $arg";;
+			*.cpp)		srcs="$srcs $arg";;
+			\$*)		libs="$libs $arg"
+					cpps="$cpps $arg";;
+			*.*)		echo 1>&2 "bad word $arg in $line"
+					exit 1;;
+			-u)		skip=libs; libs="$libs -u";;
+			[a-zA-Z_]*)	mods="$mods $arg";;
+			*)		echo 1>&2 "bad word $arg in $line"
+					exit 1;;
+			esac
+		done
+		case $doconfig in
+		yes)
+			LIBS="$LIBS $libs"
+			MODS="$MODS $mods"
+			;;
+		esac
+		case $noobjects in
+		yes)	continue;;
+		esac
+		objs=''
+		for src in $srcs
+		do
+			case $src in
+			*.c)   obj=`basename $src .c`.o; cc='$(CC)';;
+			*.cc)  obj=`basename $src .cc`.o; cc='$(CXX)';;
+			*.c++) obj=`basename $src .c++`.o; cc='$(CXX)';;
+			*.C)   obj=`basename $src .C`.o; cc='$(CXX)';;
+			*.cxx) obj=`basename $src .cxx`.o; cc='$(CXX)';;
+			*.cpp) obj=`basename $src .cpp`.o; cc='$(CXX)';;
+			*.m)   obj=`basename $src .m`.o; cc='$(CC)';; # Obj-C
+			*)     continue;;
+			esac
+			obj="$srcdir/$obj"
+			objs="$objs $obj"
+			case $src in
+			glmodule.c) ;;
+			/*) ;;
+			\$*) ;;
+			*) src='$(srcdir)/'"$srcdir/$src";;
+			esac
+			case $doconfig in
+			no)	cc="$cc \$(CCSHARED) \$(CFLAGS) \$(CPPFLAGS)";;
+			*)
+				cc="$cc \$(PY_CFLAGS)";;
+			esac
+			rule="$obj: $src; $cc $cpps -c $src -o $obj"
+			echo "$rule" >>$rulesf
+		done
+		case $doconfig in
+		yes)	OBJS="$OBJS $objs";;
+		esac
+		for mod in $mods
+		do
+			case $objs in
+			*$mod.o*)	base=$mod;;
+			*)		base=${mod}module;;
+			esac
+			file="$srcdir/$base\$(SO)"
+			case $doconfig in
+			no)	SHAREDMODS="$SHAREDMODS $file";;
+			esac
+			rule="$file: $objs"
+			rule="$rule; \$(LDSHARED) $objs $libs $ExtraLibs -o $file"
+			echo "$rule" >>$rulesf
+		done
+	done
+
+	case $SHAREDMODS in
+	'')	;;
+	*)	DEFS="SHAREDMODS=$SHAREDMODS$NL$DEFS";;
+	esac
+
+	case $noobjects in
+	yes)	BASELIBS=$LIBS;;
+	*)	LOCALLIBS=$LIBS;;
+	esac
+	LIBS='$(LOCALMODLIBS) $(BASEMODLIBS)'
+	DEFS="BASEMODLIBS=$BASELIBS$NL$DEFS"
+	DEFS="LOCALMODLIBS=$LOCALLIBS$NL$DEFS"
+
+	EXTDECLS=
+	INITBITS=
+	for mod in $MODS
+	do
+		EXTDECLS="${EXTDECLS}extern void init$mod(void);$NL"
+		INITBITS="${INITBITS}	{\"$mod\", init$mod},$NL"
+	done
+
+
+	case $config in
+	-)  ;;
+	*)  sed -e "
+		1i$NL/* Generated automatically from $config by makesetup. */
+		/MARKER 1/i$NL$EXTDECLS
+ 
+		/MARKER 2/i$NL$INITBITS
+
+		" $config >config.c
+	    ;;
+	esac
+
+	case $makepre in
+	-)	;;
+	*)	sedf="@sed.in.$$"
+		trap 'rm -f $sedf' 0 1 2 3
+		echo "1i\\" >$sedf
+		str="# Generated automatically from $makepre by makesetup."
+		echo "$str" >>$sedf
+		echo "s%_MODOBJS_%$OBJS%" >>$sedf
+		echo "s%_MODLIBS_%$LIBS%" >>$sedf
+		echo "/Definitions added by makesetup/a$NL$NL$DEFS" >>$sedf
+		sed -f $sedf $makepre >Makefile
+		cat $rulesf >>Makefile
+		rm -f $sedf
+	    ;;
+	esac
+
+	rm -f $rulesf
+)


Property changes on: vendor/Python/current/Modules/makesetup
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Modules/makexp_aix
===================================================================
--- vendor/Python/current/Modules/makexp_aix	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/makexp_aix	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,81 @@
+#!/bin/sh
+#
+# ===========================================================================
+# FILE:         makexp_aix
+# TYPE:         standalone executable
+# SYSTEM:	AIX 3.2.5 and AIX 4
+#
+# DESCRIPTION:  This script creates an export list of ALL global symbols
+#               from a list of object or archive files.
+#
+# USAGE:        makexp_aix <OutputFile> "<FirstLine>" <InputFile> ...
+#
+#               where:
+#                      <OutputFile> is the target export list filename.
+#                      <FirstLine> is the path/file string to be appended
+#                         after the "#!" symbols in the first line of the
+#                         export file. Passing "" means deferred resolution.
+#                      <InputFile> is an object (.o) or an archive file (.a).
+#
+# HISTORY:
+#		3-Apr-1998  -- remove C++ entries of the form Class::method
+#		Vladimir Marangozov
+#
+#               1-Jul-1996  -- added header information
+#               Vladimir Marangozov
+#
+#               28-Jun-1996 -- initial code
+#               Vladimir Marangozov           (Vladimir.Marangozov at imag.fr)
+# ==========================================================================
+
+# Variables
+expFileName=$1
+toAppendStr=$2
+shift; shift;
+inputFiles=$*
+automsg="Generated automatically by makexp_aix"
+notemsg="NOTE: lists _all_ global symbols defined in the above file(s)."
+curwdir=`pwd`
+
+# Create the export file and setup the header info
+echo "#!"$toAppendStr > $expFileName
+echo "*" >> $expFileName
+echo "* $automsg  (`date -u`)" >> $expFileName
+echo "*" >> $expFileName
+echo "* Base Directory: $curwdir" >> $expFileName
+echo "* Input File(s) : $inputFiles" >> $expFileName
+echo "*" >> $expFileName
+echo "* $notemsg" >> $expFileName
+echo "*" >> $expFileName
+
+# Extract the symbol list using 'nm' which produces quite
+# different output under AIX 4 than under AIX 3.2.5.
+# The following handles both versions by using a common flagset.
+# Here are some hidden tricks:
+# 1. Use /usr/ccs/bin/nm. Relevant to AIX 3.2.5 which has
+#    another version under /usr/ucb/bin/nm.
+# 2. Use the -B flag to have a standard BSD representation
+#    of the symbol list on both AIX 3.2.5 and AIX 4. The "-B"
+#    flag is missing in the AIX 3.2.5 online usage help of 'nm'.
+# 3. Use the -x flag to have a hex representation of the symbol
+#    values. This fills the leading whitespaces on AIX 4,
+#    thus simplifying the sed statement.
+# 4. Eliminate all entries except those with either "B", "D"
+#    or "T" key letters. We are interested only in the global
+#    (extern) BSS, DATA and TEXT symbols. With the same statement
+#    we eliminate object member lines relevant to AIX 4.
+# 5. Eliminate entries containing a dot. We can have a dot only
+#    as a symbol prefix, but such symbols are undefined externs.
+# 6. Eliminate everything including the key letter, so that we're
+#    left with just the symbol name.
+# 7. Eliminate all entries containing two colons, like Class::method
+#
+
+# Use -X32_64 if it appears to be implemented in this version of 'nm'.
+NM=/usr/ccs/bin/nm
+xopt=-X32_64
+$NM -e $xopt $1 >/dev/null 2>&1 || xopt=""
+
+$NM -Bex $xopt $inputFiles					\
+| sed -e '/ [^BDT] /d' -e '/\./d' -e 's/.* [BDT] //' -e '/::/d'	\
+| sort | uniq >> $expFileName


Property changes on: vendor/Python/current/Modules/makexp_aix
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Modules/mathmodule.c
===================================================================
--- vendor/Python/current/Modules/mathmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/mathmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,376 @@
+/* Math module -- standard C math library functions, pi and e */
+
+#include "Python.h"
+#include "longintrepr.h" /* just for SHIFT */
+
+#ifndef _MSC_VER
+#ifndef __STDC__
+extern double fmod (double, double);
+extern double frexp (double, int *);
+extern double ldexp (double, int);
+extern double modf (double, double *);
+#endif /* __STDC__ */
+#endif /* _MSC_VER */
+
+/* Call is_error when errno != 0, and where x is the result libm
+ * returned.  is_error will usually set up an exception and return
+ * true (1), but may return false (0) without setting up an exception.
+ */
+static int
+is_error(double x)
+{
+	int result = 1;	/* presumption of guilt */
+	assert(errno);	/* non-zero errno is a precondition for calling */
+	if (errno == EDOM)
+		PyErr_SetString(PyExc_ValueError, "math domain error");
+
+	else if (errno == ERANGE) {
+		/* ANSI C generally requires libm functions to set ERANGE
+		 * on overflow, but also generally *allows* them to set
+		 * ERANGE on underflow too.  There's no consistency about
+		 * the latter across platforms.
+		 * Alas, C99 never requires that errno be set.
+		 * Here we suppress the underflow errors (libm functions
+		 * should return a zero on underflow, and +- HUGE_VAL on
+		 * overflow, so testing the result for zero suffices to
+		 * distinguish the cases).
+		 */
+		if (x)
+			PyErr_SetString(PyExc_OverflowError,
+					"math range error");
+		else
+			result = 0;
+	}
+	else
+                /* Unexpected math error */
+		PyErr_SetFromErrno(PyExc_ValueError);
+	return result;
+}
+
+static PyObject *
+math_1(PyObject *args, double (*func) (double), char *argsfmt)
+{
+	double x;
+	if (!  PyArg_ParseTuple(args, argsfmt, &x))
+		return NULL;
+	errno = 0;
+	PyFPE_START_PROTECT("in math_1", return 0)
+	x = (*func)(x);
+	PyFPE_END_PROTECT(x)
+	Py_SET_ERRNO_ON_MATH_ERROR(x);
+	if (errno && is_error(x))
+		return NULL;
+	else
+		return PyFloat_FromDouble(x);
+}
+
+static PyObject *
+math_2(PyObject *args, double (*func) (double, double), char *argsfmt)
+{
+	double x, y;
+	if (! PyArg_ParseTuple(args, argsfmt, &x, &y))
+		return NULL;
+	errno = 0;
+	PyFPE_START_PROTECT("in math_2", return 0)
+	x = (*func)(x, y);
+	PyFPE_END_PROTECT(x)
+	Py_SET_ERRNO_ON_MATH_ERROR(x);
+	if (errno && is_error(x))
+		return NULL;
+	else
+		return PyFloat_FromDouble(x);
+}
+
+#define FUNC1(funcname, func, docstring) \
+	static PyObject * math_##funcname(PyObject *self, PyObject *args) { \
+		return math_1(args, func, "d:" #funcname); \
+	}\
+        PyDoc_STRVAR(math_##funcname##_doc, docstring);
+
+#define FUNC2(funcname, func, docstring) \
+	static PyObject * math_##funcname(PyObject *self, PyObject *args) { \
+		return math_2(args, func, "dd:" #funcname); \
+	}\
+        PyDoc_STRVAR(math_##funcname##_doc, docstring);
+
+FUNC1(acos, acos,
+      "acos(x)\n\nReturn the arc cosine (measured in radians) of x.")
+FUNC1(asin, asin,
+      "asin(x)\n\nReturn the arc sine (measured in radians) of x.")
+FUNC1(atan, atan,
+      "atan(x)\n\nReturn the arc tangent (measured in radians) of x.")
+FUNC2(atan2, atan2,
+      "atan2(y, x)\n\nReturn the arc tangent (measured in radians) of y/x.\n"
+      "Unlike atan(y/x), the signs of both x and y are considered.")
+FUNC1(ceil, ceil,
+      "ceil(x)\n\nReturn the ceiling of x as a float.\n"
+      "This is the smallest integral value >= x.")
+FUNC1(cos, cos,
+      "cos(x)\n\nReturn the cosine of x (measured in radians).")
+FUNC1(cosh, cosh,
+      "cosh(x)\n\nReturn the hyperbolic cosine of x.")
+FUNC1(exp, exp,
+      "exp(x)\n\nReturn e raised to the power of x.")
+FUNC1(fabs, fabs,
+      "fabs(x)\n\nReturn the absolute value of the float x.")
+FUNC1(floor, floor,
+      "floor(x)\n\nReturn the floor of x as a float.\n"
+      "This is the largest integral value <= x.")
+FUNC2(fmod, fmod,
+      "fmod(x,y)\n\nReturn fmod(x, y), according to platform C."
+      "  x % y may differ.")
+FUNC2(hypot, hypot,
+      "hypot(x,y)\n\nReturn the Euclidean distance, sqrt(x*x + y*y).")
+FUNC2(pow, pow,
+      "pow(x,y)\n\nReturn x**y (x to the power of y).")
+FUNC1(sin, sin,
+      "sin(x)\n\nReturn the sine of x (measured in radians).")
+FUNC1(sinh, sinh,
+      "sinh(x)\n\nReturn the hyperbolic sine of x.")
+FUNC1(sqrt, sqrt,
+      "sqrt(x)\n\nReturn the square root of x.")
+FUNC1(tan, tan,
+      "tan(x)\n\nReturn the tangent of x (measured in radians).")
+FUNC1(tanh, tanh,
+      "tanh(x)\n\nReturn the hyperbolic tangent of x.")
+
+static PyObject *
+math_frexp(PyObject *self, PyObject *args)
+{
+	double x;
+	int i;
+	if (! PyArg_ParseTuple(args, "d:frexp", &x))
+		return NULL;
+	errno = 0;
+	x = frexp(x, &i);
+	Py_SET_ERRNO_ON_MATH_ERROR(x);
+	if (errno && is_error(x))
+		return NULL;
+	else
+		return Py_BuildValue("(di)", x, i);
+}
+
+PyDoc_STRVAR(math_frexp_doc,
+"frexp(x)\n"
+"\n"
+"Return the mantissa and exponent of x, as pair (m, e).\n"
+"m is a float and e is an int, such that x = m * 2.**e.\n"
+"If x is 0, m and e are both 0.  Else 0.5 <= abs(m) < 1.0.");
+
+static PyObject *
+math_ldexp(PyObject *self, PyObject *args)
+{
+	double x;
+	int exp;
+	if (! PyArg_ParseTuple(args, "di:ldexp", &x, &exp))
+		return NULL;
+	errno = 0;
+	PyFPE_START_PROTECT("ldexp", return 0)
+	x = ldexp(x, exp);
+	PyFPE_END_PROTECT(x)
+	Py_SET_ERRNO_ON_MATH_ERROR(x);
+	if (errno && is_error(x))
+		return NULL;
+	else
+		return PyFloat_FromDouble(x);
+}
+
+PyDoc_STRVAR(math_ldexp_doc,
+"ldexp(x, i) -> x * (2**i)");
+
+static PyObject *
+math_modf(PyObject *self, PyObject *args)
+{
+	double x, y;
+	if (! PyArg_ParseTuple(args, "d:modf", &x))
+		return NULL;
+	errno = 0;
+	x = modf(x, &y);
+	Py_SET_ERRNO_ON_MATH_ERROR(x);
+	if (errno && is_error(x))
+		return NULL;
+	else
+		return Py_BuildValue("(dd)", x, y);
+}
+
+PyDoc_STRVAR(math_modf_doc,
+"modf(x)\n"
+"\n"
+"Return the fractional and integer parts of x.  Both results carry the sign\n"
+"of x.  The integer part is returned as a real.");
+
+/* A decent logarithm is easy to compute even for huge longs, but libm can't
+   do that by itself -- loghelper can.  func is log or log10, and name is
+   "log" or "log10".  Note that overflow isn't possible:  a long can contain
+   no more than INT_MAX * SHIFT bits, so has value certainly less than
+   2**(2**64 * 2**16) == 2**2**80, and log2 of that is 2**80, which is
+   small enough to fit in an IEEE single.  log and log10 are even smaller.
+*/
+
+static PyObject*
+loghelper(PyObject* args, double (*func)(double), char *format, PyObject *arg)
+{
+	/* If it is long, do it ourselves. */
+	if (PyLong_Check(arg)) {
+		double x;
+		int e;
+		x = _PyLong_AsScaledDouble(arg, &e);
+		if (x <= 0.0) {
+			PyErr_SetString(PyExc_ValueError,
+					"math domain error");
+			return NULL;
+		}
+		/* Value is ~= x * 2**(e*SHIFT), so the log ~=
+		   log(x) + log(2) * e * SHIFT.
+		   CAUTION:  e*SHIFT may overflow using int arithmetic,
+		   so force use of double. */
+		x = func(x) + (e * (double)SHIFT) * func(2.0);
+		return PyFloat_FromDouble(x);
+	}
+
+	/* Else let libm handle it by itself. */
+	return math_1(args, func, format);
+}
+
+static PyObject *
+math_log(PyObject *self, PyObject *args)
+{
+	PyObject *arg;
+	PyObject *base = NULL;
+	PyObject *num, *den;
+	PyObject *ans;
+	PyObject *newargs;
+
+	if (!PyArg_UnpackTuple(args, "log", 1, 2, &arg, &base))
+		return NULL;
+	if (base == NULL)
+		return loghelper(args, log, "d:log", arg);
+
+	newargs = PyTuple_Pack(1, arg);
+	if (newargs == NULL)
+		return NULL;
+	num = loghelper(newargs, log, "d:log", arg);
+	Py_DECREF(newargs);
+	if (num == NULL)
+		return NULL;
+
+	newargs = PyTuple_Pack(1, base);
+	if (newargs == NULL) {
+		Py_DECREF(num);
+		return NULL;
+	}
+	den = loghelper(newargs, log, "d:log", base);
+	Py_DECREF(newargs);
+	if (den == NULL) {
+		Py_DECREF(num);
+		return NULL;
+	}
+
+	ans = PyNumber_Divide(num, den);
+	Py_DECREF(num);
+	Py_DECREF(den);
+	return ans;
+}
+
+PyDoc_STRVAR(math_log_doc,
+"log(x[, base]) -> the logarithm of x to the given base.\n\
+If the base not specified, returns the natural logarithm (base e) of x.");
+
+static PyObject *
+math_log10(PyObject *self, PyObject *args)
+{
+	PyObject *arg;
+
+	if (!PyArg_UnpackTuple(args, "log10", 1, 1, &arg))
+		return NULL;
+	return loghelper(args, log10, "d:log10", arg);
+}
+
+PyDoc_STRVAR(math_log10_doc,
+"log10(x) -> the base 10 logarithm of x.");
+
+static const double degToRad = 3.141592653589793238462643383 / 180.0;
+
+static PyObject *
+math_degrees(PyObject *self, PyObject *args)
+{
+	double x;
+	if (! PyArg_ParseTuple(args, "d:degrees", &x))
+		return NULL;
+	return PyFloat_FromDouble(x / degToRad);
+}
+
+PyDoc_STRVAR(math_degrees_doc,
+"degrees(x) -> converts angle x from radians to degrees");
+
+static PyObject *
+math_radians(PyObject *self, PyObject *args)
+{
+	double x;
+	if (! PyArg_ParseTuple(args, "d:radians", &x))
+		return NULL;
+	return PyFloat_FromDouble(x * degToRad);
+}
+
+PyDoc_STRVAR(math_radians_doc,
+"radians(x) -> converts angle x from degrees to radians");
+
+static PyMethodDef math_methods[] = {
+	{"acos",	math_acos,	METH_VARARGS,	math_acos_doc},
+	{"asin",	math_asin,	METH_VARARGS,	math_asin_doc},
+	{"atan",	math_atan,	METH_VARARGS,	math_atan_doc},
+	{"atan2",	math_atan2,	METH_VARARGS,	math_atan2_doc},
+	{"ceil",	math_ceil,	METH_VARARGS,	math_ceil_doc},
+	{"cos",		math_cos,	METH_VARARGS,	math_cos_doc},
+	{"cosh",	math_cosh,	METH_VARARGS,	math_cosh_doc},
+	{"degrees",	math_degrees,	METH_VARARGS,	math_degrees_doc},
+	{"exp",		math_exp,	METH_VARARGS,	math_exp_doc},
+	{"fabs",	math_fabs,	METH_VARARGS,	math_fabs_doc},
+	{"floor",	math_floor,	METH_VARARGS,	math_floor_doc},
+	{"fmod",	math_fmod,	METH_VARARGS,	math_fmod_doc},
+	{"frexp",	math_frexp,	METH_VARARGS,	math_frexp_doc},
+	{"hypot",	math_hypot,	METH_VARARGS,	math_hypot_doc},
+	{"ldexp",	math_ldexp,	METH_VARARGS,	math_ldexp_doc},
+	{"log",		math_log,	METH_VARARGS,	math_log_doc},
+	{"log10",	math_log10,	METH_VARARGS,	math_log10_doc},
+	{"modf",	math_modf,	METH_VARARGS,	math_modf_doc},
+	{"pow",		math_pow,	METH_VARARGS,	math_pow_doc},
+	{"radians",	math_radians,	METH_VARARGS,	math_radians_doc},
+	{"sin",		math_sin,	METH_VARARGS,	math_sin_doc},
+	{"sinh",	math_sinh,	METH_VARARGS,	math_sinh_doc},
+	{"sqrt",	math_sqrt,	METH_VARARGS,	math_sqrt_doc},
+	{"tan",		math_tan,	METH_VARARGS,	math_tan_doc},
+	{"tanh",	math_tanh,	METH_VARARGS,	math_tanh_doc},
+	{NULL,		NULL}		/* sentinel */
+};
+
+
+PyDoc_STRVAR(module_doc,
+"This module is always available.  It provides access to the\n"
+"mathematical functions defined by the C standard.");
+
+PyMODINIT_FUNC
+initmath(void)
+{
+	PyObject *m, *d, *v;
+
+	m = Py_InitModule3("math", math_methods, module_doc);
+	if (m == NULL)
+		goto finally;
+	d = PyModule_GetDict(m);
+
+        if (!(v = PyFloat_FromDouble(atan(1.0) * 4.0)))
+                goto finally;
+	if (PyDict_SetItemString(d, "pi", v) < 0)
+                goto finally;
+	Py_DECREF(v);
+
+        if (!(v = PyFloat_FromDouble(exp(1.0))))
+                goto finally;
+	if (PyDict_SetItemString(d, "e", v) < 0)
+                goto finally;
+	Py_DECREF(v);
+
+  finally:
+	return;
+}

Added: vendor/Python/current/Modules/md5.c
===================================================================
--- vendor/Python/current/Modules/md5.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/md5.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,381 @@
+/*
+  Copyright (C) 1999, 2000, 2002 Aladdin Enterprises.  All rights reserved.
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  L. Peter Deutsch
+  ghost at aladdin.com
+
+ */
+/* $Id: md5.c,v 1.6 2002/04/13 19:20:28 lpd Exp $ */
+/*
+  Independent implementation of MD5 (RFC 1321).
+
+  This code implements the MD5 Algorithm defined in RFC 1321, whose
+  text is available at
+	http://www.ietf.org/rfc/rfc1321.txt
+  The code is derived from the text of the RFC, including the test suite
+  (section A.5) but excluding the rest of Appendix A.  It does not include
+  any code or documentation that is identified in the RFC as being
+  copyrighted.
+
+  The original and principal author of md5.c is L. Peter Deutsch
+  <ghost at aladdin.com>.  Other authors are noted in the change history
+  that follows (in reverse chronological order):
+
+  2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order
+	either statically or dynamically; added missing #include <string.h>
+	in library.
+  2002-03-11 lpd Corrected argument list for main(), and added int return
+	type, in test program and T value program.
+  2002-02-21 lpd Added missing #include <stdio.h> in test program.
+  2000-07-03 lpd Patched to eliminate warnings about "constant is
+	unsigned in ANSI C, signed in traditional"; made test program
+	self-checking.
+  1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
+  1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).
+  1999-05-03 lpd Original version.
+ */
+
+#include "md5.h"
+#include <string.h>
+
+#undef BYTE_ORDER	/* 1 = big-endian, -1 = little-endian, 0 = unknown */
+#ifdef ARCH_IS_BIG_ENDIAN
+#  define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)
+#else
+#  define BYTE_ORDER 0
+#endif
+
+#define T_MASK ((md5_word_t)~0)
+#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
+#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
+#define T3    0x242070db
+#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
+#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
+#define T6    0x4787c62a
+#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
+#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
+#define T9    0x698098d8
+#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
+#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
+#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
+#define T13    0x6b901122
+#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
+#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
+#define T16    0x49b40821
+#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
+#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
+#define T19    0x265e5a51
+#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
+#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
+#define T22    0x02441453
+#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
+#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
+#define T25    0x21e1cde6
+#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
+#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
+#define T28    0x455a14ed
+#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
+#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
+#define T31    0x676f02d9
+#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
+#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
+#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
+#define T35    0x6d9d6122
+#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
+#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
+#define T38    0x4bdecfa9
+#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
+#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
+#define T41    0x289b7ec6
+#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
+#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
+#define T44    0x04881d05
+#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
+#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
+#define T47    0x1fa27cf8
+#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
+#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
+#define T50    0x432aff97
+#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
+#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
+#define T53    0x655b59c3
+#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
+#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
+#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
+#define T57    0x6fa87e4f
+#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
+#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
+#define T60    0x4e0811a1
+#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
+#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
+#define T63    0x2ad7d2bb
+#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)
+
+
+static void
+md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
+{
+    md5_word_t
+	a = pms->abcd[0], b = pms->abcd[1],
+	c = pms->abcd[2], d = pms->abcd[3];
+    md5_word_t t;
+#if BYTE_ORDER > 0
+    /* Define storage only for big-endian CPUs. */
+    md5_word_t X[16];
+#else
+    /* Define storage for little-endian or both types of CPUs. */
+    md5_word_t xbuf[16];
+    const md5_word_t *X;
+#endif
+
+    {
+#if BYTE_ORDER == 0
+	/*
+	 * Determine dynamically whether this is a big-endian or
+	 * little-endian machine, since we can use a more efficient
+	 * algorithm on the latter.
+	 */
+	static const int w = 1;
+
+	if (*((const md5_byte_t *)&w)) /* dynamic little-endian */
+#endif
+#if BYTE_ORDER <= 0		/* little-endian */
+	{
+	    /*
+	     * On little-endian machines, we can process properly aligned
+	     * data without copying it.
+	     */
+	    if (!((data - (const md5_byte_t *)0) & 3)) {
+		/* data are properly aligned */
+		X = (const md5_word_t *)data;
+	    } else {
+		/* not aligned */
+		memcpy(xbuf, data, 64);
+		X = xbuf;
+	    }
+	}
+#endif
+#if BYTE_ORDER == 0
+	else			/* dynamic big-endian */
+#endif
+#if BYTE_ORDER >= 0		/* big-endian */
+	{
+	    /*
+	     * On big-endian machines, we must arrange the bytes in the
+	     * right order.
+	     */
+	    const md5_byte_t *xp = data;
+	    int i;
+
+#  if BYTE_ORDER == 0
+	    X = xbuf;		/* (dynamic only) */
+#  else
+#    define xbuf X		/* (static only) */
+#  endif
+	    for (i = 0; i < 16; ++i, xp += 4)
+		xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
+	}
+#endif
+    }
+
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
+
+    /* Round 1. */
+    /* Let [abcd k s i] denote the operation
+       a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
+#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
+#define SET(a, b, c, d, k, s, Ti)\
+  t = a + F(b,c,d) + X[k] + Ti;\
+  a = ROTATE_LEFT(t, s) + b
+    /* Do the following 16 operations. */
+    SET(a, b, c, d,  0,  7,  T1);
+    SET(d, a, b, c,  1, 12,  T2);
+    SET(c, d, a, b,  2, 17,  T3);
+    SET(b, c, d, a,  3, 22,  T4);
+    SET(a, b, c, d,  4,  7,  T5);
+    SET(d, a, b, c,  5, 12,  T6);
+    SET(c, d, a, b,  6, 17,  T7);
+    SET(b, c, d, a,  7, 22,  T8);
+    SET(a, b, c, d,  8,  7,  T9);
+    SET(d, a, b, c,  9, 12, T10);
+    SET(c, d, a, b, 10, 17, T11);
+    SET(b, c, d, a, 11, 22, T12);
+    SET(a, b, c, d, 12,  7, T13);
+    SET(d, a, b, c, 13, 12, T14);
+    SET(c, d, a, b, 14, 17, T15);
+    SET(b, c, d, a, 15, 22, T16);
+#undef SET
+
+     /* Round 2. */
+     /* Let [abcd k s i] denote the operation
+          a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
+#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
+#define SET(a, b, c, d, k, s, Ti)\
+  t = a + G(b,c,d) + X[k] + Ti;\
+  a = ROTATE_LEFT(t, s) + b
+     /* Do the following 16 operations. */
+    SET(a, b, c, d,  1,  5, T17);
+    SET(d, a, b, c,  6,  9, T18);
+    SET(c, d, a, b, 11, 14, T19);
+    SET(b, c, d, a,  0, 20, T20);
+    SET(a, b, c, d,  5,  5, T21);
+    SET(d, a, b, c, 10,  9, T22);
+    SET(c, d, a, b, 15, 14, T23);
+    SET(b, c, d, a,  4, 20, T24);
+    SET(a, b, c, d,  9,  5, T25);
+    SET(d, a, b, c, 14,  9, T26);
+    SET(c, d, a, b,  3, 14, T27);
+    SET(b, c, d, a,  8, 20, T28);
+    SET(a, b, c, d, 13,  5, T29);
+    SET(d, a, b, c,  2,  9, T30);
+    SET(c, d, a, b,  7, 14, T31);
+    SET(b, c, d, a, 12, 20, T32);
+#undef SET
+
+     /* Round 3. */
+     /* Let [abcd k s t] denote the operation
+          a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define SET(a, b, c, d, k, s, Ti)\
+  t = a + H(b,c,d) + X[k] + Ti;\
+  a = ROTATE_LEFT(t, s) + b
+     /* Do the following 16 operations. */
+    SET(a, b, c, d,  5,  4, T33);
+    SET(d, a, b, c,  8, 11, T34);
+    SET(c, d, a, b, 11, 16, T35);
+    SET(b, c, d, a, 14, 23, T36);
+    SET(a, b, c, d,  1,  4, T37);
+    SET(d, a, b, c,  4, 11, T38);
+    SET(c, d, a, b,  7, 16, T39);
+    SET(b, c, d, a, 10, 23, T40);
+    SET(a, b, c, d, 13,  4, T41);
+    SET(d, a, b, c,  0, 11, T42);
+    SET(c, d, a, b,  3, 16, T43);
+    SET(b, c, d, a,  6, 23, T44);
+    SET(a, b, c, d,  9,  4, T45);
+    SET(d, a, b, c, 12, 11, T46);
+    SET(c, d, a, b, 15, 16, T47);
+    SET(b, c, d, a,  2, 23, T48);
+#undef SET
+
+     /* Round 4. */
+     /* Let [abcd k s t] denote the operation
+          a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
+#define I(x, y, z) ((y) ^ ((x) | ~(z)))
+#define SET(a, b, c, d, k, s, Ti)\
+  t = a + I(b,c,d) + X[k] + Ti;\
+  a = ROTATE_LEFT(t, s) + b
+     /* Do the following 16 operations. */
+    SET(a, b, c, d,  0,  6, T49);
+    SET(d, a, b, c,  7, 10, T50);
+    SET(c, d, a, b, 14, 15, T51);
+    SET(b, c, d, a,  5, 21, T52);
+    SET(a, b, c, d, 12,  6, T53);
+    SET(d, a, b, c,  3, 10, T54);
+    SET(c, d, a, b, 10, 15, T55);
+    SET(b, c, d, a,  1, 21, T56);
+    SET(a, b, c, d,  8,  6, T57);
+    SET(d, a, b, c, 15, 10, T58);
+    SET(c, d, a, b,  6, 15, T59);
+    SET(b, c, d, a, 13, 21, T60);
+    SET(a, b, c, d,  4,  6, T61);
+    SET(d, a, b, c, 11, 10, T62);
+    SET(c, d, a, b,  2, 15, T63);
+    SET(b, c, d, a,  9, 21, T64);
+#undef SET
+
+     /* Then perform the following additions. (That is increment each
+        of the four registers by the value it had before this block
+        was started.) */
+    pms->abcd[0] += a;
+    pms->abcd[1] += b;
+    pms->abcd[2] += c;
+    pms->abcd[3] += d;
+}
+
+void
+md5_init(md5_state_t *pms)
+{
+    pms->count[0] = pms->count[1] = 0;
+    pms->abcd[0] = 0x67452301;
+    pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
+    pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
+    pms->abcd[3] = 0x10325476;
+}
+
+void
+md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes)
+{
+    const md5_byte_t *p = data;
+    int left = nbytes;
+    int offset = (pms->count[0] >> 3) & 63;
+    md5_word_t nbits = (md5_word_t)(nbytes << 3);
+
+    if (nbytes <= 0)
+	return;
+
+    /* Update the message length. */
+    pms->count[1] += nbytes >> 29;
+    pms->count[0] += nbits;
+    if (pms->count[0] < nbits)
+	pms->count[1]++;
+
+    /* Process an initial partial block. */
+    if (offset) {
+	int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
+
+	memcpy(pms->buf + offset, p, copy);
+	if (offset + copy < 64)
+	    return;
+	p += copy;
+	left -= copy;
+	md5_process(pms, pms->buf);
+    }
+
+    /* Process full blocks. */
+    for (; left >= 64; p += 64, left -= 64)
+	md5_process(pms, p);
+
+    /* Process a final partial block. */
+    if (left)
+	memcpy(pms->buf, p, left);
+}
+
+void
+md5_finish(md5_state_t *pms, md5_byte_t digest[16])
+{
+    static const md5_byte_t pad[64] = {
+	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+    };
+    md5_byte_t data[8];
+    int i;
+
+    /* Save the length before padding. */
+    for (i = 0; i < 8; ++i)
+	data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
+    /* Pad to 56 bytes mod 64. */
+    md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
+    /* Append the length. */
+    md5_append(pms, data, 8);
+    for (i = 0; i < 16; ++i)
+	digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
+}

Added: vendor/Python/current/Modules/md5.h
===================================================================
--- vendor/Python/current/Modules/md5.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/md5.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,91 @@
+/*
+  Copyright (C) 1999, 2002 Aladdin Enterprises.  All rights reserved.
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  L. Peter Deutsch
+  ghost at aladdin.com
+
+ */
+/* $Id: md5.h 43594 2006-04-03 16:27:50Z matthias.klose $ */
+/*
+  Independent implementation of MD5 (RFC 1321).
+
+  This code implements the MD5 Algorithm defined in RFC 1321, whose
+  text is available at
+	http://www.ietf.org/rfc/rfc1321.txt
+  The code is derived from the text of the RFC, including the test suite
+  (section A.5) but excluding the rest of Appendix A.  It does not include
+  any code or documentation that is identified in the RFC as being
+  copyrighted.
+
+  The original and principal author of md5.h is L. Peter Deutsch
+  <ghost at aladdin.com>.  Other authors are noted in the change history
+  that follows (in reverse chronological order):
+
+  2002-04-13 lpd Removed support for non-ANSI compilers; removed
+	references to Ghostscript; clarified derivation from RFC 1321;
+	now handles byte order either statically or dynamically.
+  1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
+  1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
+	added conditionalization for C++ compilation from Martin
+	Purschke <purschke at bnl.gov>.
+  1999-05-03 lpd Original version.
+ */
+
+#ifndef md5_INCLUDED
+#  define md5_INCLUDED
+
+/*
+ * This package supports both compile-time and run-time determination of CPU
+ * byte order.  If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be
+ * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is
+ * defined as non-zero, the code will be compiled to run only on big-endian
+ * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to
+ * run on either big- or little-endian CPUs, but will run slightly less
+ * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined.
+ */
+
+typedef unsigned char md5_byte_t; /* 8-bit byte */
+typedef unsigned int md5_word_t; /* 32-bit word */
+
+/* Define the state of the MD5 Algorithm. */
+typedef struct md5_state_s {
+    md5_word_t count[2];	/* message length in bits, lsw first */
+    md5_word_t abcd[4];		/* digest buffer */
+    md5_byte_t buf[64];		/* accumulate block */
+} md5_state_t;
+
+#ifdef __cplusplus
+extern "C" 
+{
+#endif
+
+/* Initialize the algorithm. */
+void md5_init(md5_state_t *pms);
+
+/* Append a string to the message. */
+void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes);
+
+/* Finish the message and return the digest. */
+void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
+
+#ifdef __cplusplus
+}  /* end extern "C" */
+#endif
+
+#endif /* md5_INCLUDED */

Added: vendor/Python/current/Modules/md5module.c
===================================================================
--- vendor/Python/current/Modules/md5module.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/md5module.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,312 @@
+
+/* MD5 module */
+
+/* This module provides an interface to the RSA Data Security,
+   Inc. MD5 Message-Digest Algorithm, described in RFC 1321.
+   It requires the files md5c.c and md5.h (which are slightly changed
+   from the versions in the RFC to avoid the "global.h" file.) */
+
+
+/* MD5 objects */
+
+#include "Python.h"
+#include "structmember.h"
+#include "md5.h"
+
+typedef struct {
+	PyObject_HEAD
+        md5_state_t	md5;		/* the context holder */
+} md5object;
+
+static PyTypeObject MD5type;
+
+#define is_md5object(v)		((v)->ob_type == &MD5type)
+
+static md5object *
+newmd5object(void)
+{
+	md5object *md5p;
+
+	md5p = PyObject_New(md5object, &MD5type);
+	if (md5p == NULL)
+		return NULL;
+
+	md5_init(&md5p->md5);	/* actual initialisation */
+	return md5p;
+}
+
+
+/* MD5 methods */
+
+static void
+md5_dealloc(md5object *md5p)
+{
+	PyObject_Del(md5p);
+}
+
+
+/* MD5 methods-as-attributes */
+
+static PyObject *
+md5_update(md5object *self, PyObject *args)
+{
+	unsigned char *cp;
+	int len;
+
+	if (!PyArg_ParseTuple(args, "s#:update", &cp, &len))
+		return NULL;
+
+	md5_append(&self->md5, cp, len);
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(update_doc,
+"update (arg)\n\
+\n\
+Update the md5 object with the string arg. Repeated calls are\n\
+equivalent to a single call with the concatenation of all the\n\
+arguments.");
+
+
+static PyObject *
+md5_digest(md5object *self)
+{
+ 	md5_state_t mdContext;
+	unsigned char aDigest[16];
+
+	/* make a temporary copy, and perform the final */
+	mdContext = self->md5;
+	md5_finish(&mdContext, aDigest);
+
+	return PyString_FromStringAndSize((char *)aDigest, 16);
+}
+
+PyDoc_STRVAR(digest_doc,
+"digest() -> string\n\
+\n\
+Return the digest of the strings passed to the update() method so\n\
+far. This is a 16-byte string which may contain non-ASCII characters,\n\
+including null bytes.");
+
+
+static PyObject *
+md5_hexdigest(md5object *self)
+{
+ 	md5_state_t mdContext;
+	unsigned char digest[16];
+	unsigned char hexdigest[32];
+	int i, j;
+
+	/* make a temporary copy, and perform the final */
+	mdContext = self->md5;
+	md5_finish(&mdContext, digest);
+
+	/* Make hex version of the digest */
+	for(i=j=0; i<16; i++) {
+		char c;
+		c = (digest[i] >> 4) & 0xf;
+		c = (c>9) ? c+'a'-10 : c + '0';
+		hexdigest[j++] = c;
+		c = (digest[i] & 0xf);
+		c = (c>9) ? c+'a'-10 : c + '0';
+		hexdigest[j++] = c;
+	}
+	return PyString_FromStringAndSize((char*)hexdigest, 32);
+}
+
+
+PyDoc_STRVAR(hexdigest_doc,
+"hexdigest() -> string\n\
+\n\
+Like digest(), but returns the digest as a string of hexadecimal digits.");
+
+
+static PyObject *
+md5_copy(md5object *self)
+{
+	md5object *md5p;
+
+	if ((md5p = newmd5object()) == NULL)
+		return NULL;
+
+	md5p->md5 = self->md5;
+
+	return (PyObject *)md5p;
+}
+
+PyDoc_STRVAR(copy_doc,
+"copy() -> md5 object\n\
+\n\
+Return a copy (``clone'') of the md5 object.");
+
+
+static PyMethodDef md5_methods[] = {
+	{"update",    (PyCFunction)md5_update,    METH_VARARGS, update_doc},
+	{"digest",    (PyCFunction)md5_digest,    METH_NOARGS,  digest_doc},
+	{"hexdigest", (PyCFunction)md5_hexdigest, METH_NOARGS,  hexdigest_doc},
+	{"copy",      (PyCFunction)md5_copy,      METH_NOARGS,  copy_doc},
+	{NULL, NULL}			     /* sentinel */
+};
+
+static PyObject *
+md5_get_block_size(PyObject *self, void *closure)
+{
+    return PyInt_FromLong(64);
+}
+
+static PyObject *
+md5_get_digest_size(PyObject *self, void *closure)
+{
+    return PyInt_FromLong(16);
+}
+
+static PyObject *
+md5_get_name(PyObject *self, void *closure)
+{
+    return PyString_FromStringAndSize("MD5", 3);
+}
+
+static PyGetSetDef md5_getseters[] = {
+    {"digest_size",
+     (getter)md5_get_digest_size, NULL,
+     NULL,
+     NULL},
+    {"block_size",
+     (getter)md5_get_block_size, NULL,
+     NULL,
+     NULL},
+    {"name",
+     (getter)md5_get_name, NULL,
+     NULL,
+     NULL},
+    /* the old md5 and sha modules support 'digest_size' as in PEP 247.
+     * the old sha module also supported 'digestsize'.  ugh. */
+    {"digestsize",
+     (getter)md5_get_digest_size, NULL,
+     NULL,
+     NULL},
+    {NULL}  /* Sentinel */
+};
+
+
+PyDoc_STRVAR(module_doc,
+"This module implements the interface to RSA's MD5 message digest\n\
+algorithm (see also Internet RFC 1321). Its use is quite\n\
+straightforward: use the new() to create an md5 object. You can now\n\
+feed this object with arbitrary strings using the update() method, and\n\
+at any point you can ask it for the digest (a strong kind of 128-bit\n\
+checksum, a.k.a. ``fingerprint'') of the concatenation of the strings\n\
+fed to it so far using the digest() method.\n\
+\n\
+Functions:\n\
+\n\
+new([arg]) -- return a new md5 object, initialized with arg if provided\n\
+md5([arg]) -- DEPRECATED, same as new, but for compatibility\n\
+\n\
+Special Objects:\n\
+\n\
+MD5Type -- type object for md5 objects");
+
+PyDoc_STRVAR(md5type_doc,
+"An md5 represents the object used to calculate the MD5 checksum of a\n\
+string of information.\n\
+\n\
+Methods:\n\
+\n\
+update() -- updates the current digest with an additional string\n\
+digest() -- return the current digest value\n\
+hexdigest() -- return the current digest as a string of hexadecimal digits\n\
+copy() -- return a copy of the current md5 object");
+
+static PyTypeObject MD5type = {
+	PyObject_HEAD_INIT(NULL)
+	0,			  /*ob_size*/
+	"_md5.md5",		  /*tp_name*/
+	sizeof(md5object),	  /*tp_size*/
+	0,			  /*tp_itemsize*/
+	/* methods */
+	(destructor)md5_dealloc,  /*tp_dealloc*/
+	0,			  /*tp_print*/
+	0,                        /*tp_getattr*/
+	0,			  /*tp_setattr*/
+	0,			  /*tp_compare*/
+	0,			  /*tp_repr*/
+        0,			  /*tp_as_number*/
+	0,                        /*tp_as_sequence*/
+	0,			  /*tp_as_mapping*/
+	0, 			  /*tp_hash*/
+	0,			  /*tp_call*/
+	0,			  /*tp_str*/
+	0,			  /*tp_getattro*/
+	0,			  /*tp_setattro*/
+	0,	                  /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT,	  /*tp_flags*/
+	md5type_doc,		  /*tp_doc*/
+        0,                        /*tp_traverse*/
+        0,			  /*tp_clear*/
+        0,			  /*tp_richcompare*/
+        0,			  /*tp_weaklistoffset*/
+        0,			  /*tp_iter*/
+        0,			  /*tp_iternext*/
+        md5_methods,	          /*tp_methods*/
+        0,      	          /*tp_members*/
+        md5_getseters,            /*tp_getset*/
+};
+
+
+/* MD5 functions */
+
+static PyObject *
+MD5_new(PyObject *self, PyObject *args)
+{
+	md5object *md5p;
+	unsigned char *cp = NULL;
+	int len = 0;
+
+	if (!PyArg_ParseTuple(args, "|s#:new", &cp, &len))
+		return NULL;
+
+	if ((md5p = newmd5object()) == NULL)
+		return NULL;
+
+	if (cp)
+		md5_append(&md5p->md5, cp, len);
+
+	return (PyObject *)md5p;
+}
+
+PyDoc_STRVAR(new_doc,
+"new([arg]) -> md5 object\n\
+\n\
+Return a new md5 object. If arg is present, the method call update(arg)\n\
+is made.");
+
+
+/* List of functions exported by this module */
+
+static PyMethodDef md5_functions[] = {
+	{"new",		(PyCFunction)MD5_new, METH_VARARGS, new_doc},
+	{NULL,		NULL}	/* Sentinel */
+};
+
+
+/* Initialize this module. */
+
+PyMODINIT_FUNC
+init_md5(void)
+{
+	PyObject *m, *d;
+
+        MD5type.ob_type = &PyType_Type;
+        if (PyType_Ready(&MD5type) < 0)
+            return;
+	m = Py_InitModule3("_md5", md5_functions, module_doc);
+	if (m == NULL)
+	    return;
+	d = PyModule_GetDict(m);
+	PyDict_SetItemString(d, "MD5Type", (PyObject *)&MD5type);
+	PyModule_AddIntConstant(m, "digest_size", 16);
+	/* No need to check the error here, the caller will do that */
+}

Added: vendor/Python/current/Modules/mmapmodule.c
===================================================================
--- vendor/Python/current/Modules/mmapmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/mmapmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1186 @@
+/*
+ /  Author: Sam Rushing <rushing at nightmare.com>
+ /  Hacked for Unix by AMK
+ /  $Id: mmapmodule.c 51474 2006-08-22 13:57:07Z neal.norwitz $
+
+ / mmapmodule.cpp -- map a view of a file into memory
+ /
+ / todo: need permission flags, perhaps a 'chsize' analog
+ /   not all functions check range yet!!!
+ /
+ /
+ / This version of mmapmodule.c has been changed significantly
+ / from the original mmapfile.c on which it was based.
+ / The original version of mmapfile is maintained by Sam at
+ / ftp://squirl.nightmare.com/pub/python/python-ext.
+*/
+
+#define PY_SSIZE_T_CLEAN
+#include <Python.h>
+
+#ifndef MS_WINDOWS
+#define UNIX
+#endif
+
+#ifdef MS_WINDOWS
+#include <windows.h>
+static int
+my_getpagesize(void)
+{
+	SYSTEM_INFO si;
+	GetSystemInfo(&si);
+	return si.dwPageSize;
+}
+#endif
+
+#ifdef UNIX
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+#if defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE)
+static int
+my_getpagesize(void)
+{
+	return sysconf(_SC_PAGESIZE);
+}
+#else
+#define my_getpagesize getpagesize
+#endif
+
+#endif /* UNIX */
+
+#include <string.h>
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif /* HAVE_SYS_TYPES_H */
+
+/* Prefer MAP_ANONYMOUS since MAP_ANON is deprecated according to man page. */
+#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
+#  define MAP_ANONYMOUS MAP_ANON
+#endif
+
+static PyObject *mmap_module_error;
+
+typedef enum
+{
+	ACCESS_DEFAULT,
+	ACCESS_READ,
+	ACCESS_WRITE,
+	ACCESS_COPY
+} access_mode;
+
+typedef struct {
+	PyObject_HEAD
+	char *	data;
+	size_t	size;
+	size_t	pos;
+
+#ifdef MS_WINDOWS
+	HANDLE	map_handle;
+	HANDLE	file_handle;
+	char *	tagname;
+#endif
+
+#ifdef UNIX
+        int fd;
+#endif
+
+        access_mode access;
+} mmap_object;
+
+
+static void
+mmap_object_dealloc(mmap_object *m_obj)
+{
+#ifdef MS_WINDOWS
+	if (m_obj->data != NULL)
+		UnmapViewOfFile (m_obj->data);
+	if (m_obj->map_handle != INVALID_HANDLE_VALUE)
+		CloseHandle (m_obj->map_handle);
+	if (m_obj->file_handle != INVALID_HANDLE_VALUE)
+		CloseHandle (m_obj->file_handle);
+	if (m_obj->tagname)
+		PyMem_Free(m_obj->tagname);
+#endif /* MS_WINDOWS */
+
+#ifdef UNIX
+	if (m_obj->fd >= 0)
+		(void) close(m_obj->fd);
+	if (m_obj->data!=NULL) {
+		msync(m_obj->data, m_obj->size, MS_SYNC);
+		munmap(m_obj->data, m_obj->size);
+	}
+#endif /* UNIX */
+
+	PyObject_Del(m_obj);
+}
+
+static PyObject *
+mmap_close_method(mmap_object *self, PyObject *unused)
+{
+#ifdef MS_WINDOWS
+	/* For each resource we maintain, we need to check
+	   the value is valid, and if so, free the resource
+	   and set the member value to an invalid value so
+	   the dealloc does not attempt to resource clearing
+	   again.
+	   TODO - should we check for errors in the close operations???
+	*/
+	if (self->data != NULL) {
+		UnmapViewOfFile(self->data);
+		self->data = NULL;
+	}
+	if (self->map_handle != INVALID_HANDLE_VALUE) {
+		CloseHandle(self->map_handle);
+		self->map_handle = INVALID_HANDLE_VALUE;
+	}
+	if (self->file_handle != INVALID_HANDLE_VALUE) {
+		CloseHandle(self->file_handle);
+		self->file_handle = INVALID_HANDLE_VALUE;
+	}
+#endif /* MS_WINDOWS */
+
+#ifdef UNIX
+	(void) close(self->fd);
+	self->fd = -1;
+	if (self->data != NULL) {
+		munmap(self->data, self->size);
+		self->data = NULL;
+	}
+#endif
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+#ifdef MS_WINDOWS
+#define CHECK_VALID(err)						\
+do {									\
+    if (self->map_handle == INVALID_HANDLE_VALUE) {						\
+	PyErr_SetString(PyExc_ValueError, "mmap closed or invalid");	\
+	return err;							\
+    }									\
+} while (0)
+#endif /* MS_WINDOWS */
+
+#ifdef UNIX
+#define CHECK_VALID(err)						\
+do {									\
+    if (self->data == NULL) {						\
+	PyErr_SetString(PyExc_ValueError, "mmap closed or invalid");	\
+	return err;							\
+	}								\
+} while (0)
+#endif /* UNIX */
+
+static PyObject *
+mmap_read_byte_method(mmap_object *self,
+		      PyObject *unused)
+{
+	CHECK_VALID(NULL);
+	if (self->pos < self->size) {
+	        char value = self->data[self->pos];
+		self->pos += 1;
+		return Py_BuildValue("c", value);
+	} else {
+		PyErr_SetString(PyExc_ValueError, "read byte out of range");
+		return NULL;
+	}
+}
+
+static PyObject *
+mmap_read_line_method(mmap_object *self,
+		      PyObject *unused)
+{
+	char *start = self->data+self->pos;
+	char *eof = self->data+self->size;
+	char *eol;
+	PyObject *result;
+
+	CHECK_VALID(NULL);
+
+	eol = memchr(start, '\n', self->size - self->pos);
+	if (!eol)
+		eol = eof;
+	else
+		++eol;		/* we're interested in the position after the
+				   newline. */
+	result = PyString_FromStringAndSize(start, (eol - start));
+	self->pos += (eol - start);
+	return result;
+}
+
+static PyObject *
+mmap_read_method(mmap_object *self,
+		 PyObject *args)
+{
+	Py_ssize_t num_bytes;
+	PyObject *result;
+
+	CHECK_VALID(NULL);
+	if (!PyArg_ParseTuple(args, "n:read", &num_bytes))
+		return(NULL);
+
+	/* silently 'adjust' out-of-range requests */
+	if ((self->pos + num_bytes) > self->size) {
+		num_bytes -= (self->pos+num_bytes) - self->size;
+	}
+	result = Py_BuildValue("s#", self->data+self->pos, num_bytes);
+	self->pos += num_bytes;
+	return result;
+}
+
+static PyObject *
+mmap_find_method(mmap_object *self,
+		 PyObject *args)
+{
+	Py_ssize_t start = self->pos;
+	char *needle;
+	Py_ssize_t len;
+
+	CHECK_VALID(NULL);
+	if (!PyArg_ParseTuple(args, "s#|n:find", &needle, &len, &start)) {
+		return NULL;
+	} else {
+		char *p;
+		char *e = self->data + self->size;
+
+                if (start < 0)
+			start += self->size;
+                if (start < 0)
+			start = 0;
+                else if ((size_t)start > self->size)
+			start = self->size;
+
+		for (p = self->data + start; p + len <= e; ++p) {
+			Py_ssize_t i;
+			for (i = 0; i < len && needle[i] == p[i]; ++i)
+				/* nothing */;
+			if (i == len) {
+				return PyInt_FromSsize_t(p - self->data);
+			}
+		}
+		return PyInt_FromLong(-1);
+	}
+}
+
+static int
+is_writeable(mmap_object *self)
+{
+	if (self->access != ACCESS_READ)
+		return 1;
+	PyErr_Format(PyExc_TypeError, "mmap can't modify a readonly memory map.");
+	return 0;
+}
+
+static int
+is_resizeable(mmap_object *self)
+{
+	if ((self->access == ACCESS_WRITE) || (self->access == ACCESS_DEFAULT))
+		return 1;
+	PyErr_Format(PyExc_TypeError,
+		     "mmap can't resize a readonly or copy-on-write memory map.");
+	return 0;
+}
+
+
+static PyObject *
+mmap_write_method(mmap_object *self,
+		  PyObject *args)
+{
+	Py_ssize_t length;
+	char *data;
+
+	CHECK_VALID(NULL);
+	if (!PyArg_ParseTuple(args, "s#:write", &data, &length))
+		return(NULL);
+
+	if (!is_writeable(self))
+		return NULL;
+
+	if ((self->pos + length) > self->size) {
+		PyErr_SetString(PyExc_ValueError, "data out of range");
+		return NULL;
+	}
+	memcpy(self->data+self->pos, data, length);
+	self->pos = self->pos+length;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+mmap_write_byte_method(mmap_object *self,
+		       PyObject *args)
+{
+	char value;
+
+	CHECK_VALID(NULL);
+	if (!PyArg_ParseTuple(args, "c:write_byte", &value))
+		return(NULL);
+
+	if (!is_writeable(self))
+		return NULL;
+	*(self->data+self->pos) = value;
+	self->pos += 1;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+mmap_size_method(mmap_object *self,
+		 PyObject *unused)
+{
+	CHECK_VALID(NULL);
+
+#ifdef MS_WINDOWS
+	if (self->file_handle != INVALID_HANDLE_VALUE) {
+		DWORD low,high;
+		PY_LONG_LONG size;
+		low = GetFileSize(self->file_handle, &high);
+		if (low == INVALID_FILE_SIZE) {
+			/* It might be that the function appears to have failed,
+			   when indeed its size equals INVALID_FILE_SIZE */
+			DWORD error = GetLastError();
+			if (error != NO_ERROR)
+				return PyErr_SetFromWindowsErr(error);
+		}
+		if (!high && low < LONG_MAX)
+			return PyInt_FromLong((long)low);
+		size = (((PY_LONG_LONG)high)<<32) + low;
+		return PyLong_FromLongLong(size);
+	} else {
+		return PyInt_FromSsize_t(self->size);
+	}
+#endif /* MS_WINDOWS */
+
+#ifdef UNIX
+	{
+		struct stat buf;
+		if (-1 == fstat(self->fd, &buf)) {
+			PyErr_SetFromErrno(mmap_module_error);
+			return NULL;
+		}
+		return PyInt_FromSsize_t(buf.st_size);
+	}
+#endif /* UNIX */
+}
+
+/* This assumes that you want the entire file mapped,
+ / and when recreating the map will make the new file
+ / have the new size
+ /
+ / Is this really necessary?  This could easily be done
+ / from python by just closing and re-opening with the
+ / new size?
+ */
+
+static PyObject *
+mmap_resize_method(mmap_object *self,
+		   PyObject *args)
+{
+	Py_ssize_t new_size;
+	CHECK_VALID(NULL);
+	if (!PyArg_ParseTuple(args, "n:resize", &new_size) ||
+	    !is_resizeable(self)) {
+		return NULL;
+#ifdef MS_WINDOWS
+	} else {
+		DWORD dwErrCode = 0;
+		DWORD newSizeLow, newSizeHigh;
+		/* First, unmap the file view */
+		UnmapViewOfFile(self->data);
+		/* Close the mapping object */
+		CloseHandle(self->map_handle);
+		/* Move to the desired EOF position */
+#if SIZEOF_SIZE_T > 4
+		newSizeHigh = (DWORD)(new_size >> 32);
+		newSizeLow = (DWORD)(new_size & 0xFFFFFFFF);
+#else
+		newSizeHigh = 0;
+		newSizeLow = (DWORD)new_size;
+#endif
+		SetFilePointer(self->file_handle,
+			       newSizeLow, &newSizeHigh, FILE_BEGIN);
+		/* Change the size of the file */
+		SetEndOfFile(self->file_handle);
+		/* Create another mapping object and remap the file view */
+		self->map_handle = CreateFileMapping(
+			self->file_handle,
+			NULL,
+			PAGE_READWRITE,
+			newSizeHigh,
+			newSizeLow,
+			self->tagname);
+		if (self->map_handle != NULL) {
+			self->data = (char *) MapViewOfFile(self->map_handle,
+							    FILE_MAP_WRITE,
+							    0,
+							    0,
+							    0);
+			if (self->data != NULL) {
+				self->size = new_size;
+				Py_INCREF(Py_None);
+				return Py_None;
+			} else {
+				dwErrCode = GetLastError();
+			}
+		} else {
+			dwErrCode = GetLastError();
+		}
+		PyErr_SetFromWindowsErr(dwErrCode);
+		return NULL;
+#endif /* MS_WINDOWS */
+
+#ifdef UNIX
+#ifndef HAVE_MREMAP
+	} else {
+		PyErr_SetString(PyExc_SystemError,
+				"mmap: resizing not available--no mremap()");
+		return NULL;
+#else
+	} else {
+		void *newmap;
+
+		if (ftruncate(self->fd, new_size) == -1) {
+			PyErr_SetFromErrno(mmap_module_error);
+			return NULL;
+		}
+
+#ifdef MREMAP_MAYMOVE
+		newmap = mremap(self->data, self->size, new_size, MREMAP_MAYMOVE);
+#else
+		newmap = mremap(self->data, self->size, new_size, 0);
+#endif
+		if (newmap == (void *)-1)
+		{
+			PyErr_SetFromErrno(mmap_module_error);
+			return NULL;
+		}
+		self->data = newmap;
+		self->size = new_size;
+		Py_INCREF(Py_None);
+		return Py_None;
+#endif /* HAVE_MREMAP */
+#endif /* UNIX */
+	}
+}
+
+static PyObject *
+mmap_tell_method(mmap_object *self, PyObject *unused)
+{
+	CHECK_VALID(NULL);
+	return PyInt_FromSize_t(self->pos);
+}
+
+static PyObject *
+mmap_flush_method(mmap_object *self, PyObject *args)
+{
+	Py_ssize_t offset = 0;
+	Py_ssize_t size = self->size;
+	CHECK_VALID(NULL);
+	if (!PyArg_ParseTuple(args, "|nn:flush", &offset, &size))
+		return NULL;
+	if ((size_t)(offset + size) > self->size) {
+		PyErr_SetString(PyExc_ValueError, "flush values out of range");
+		return NULL;
+	} else {
+#ifdef MS_WINDOWS
+		return PyInt_FromLong((long)
+                                      FlushViewOfFile(self->data+offset, size));
+#endif /* MS_WINDOWS */
+#ifdef UNIX
+		/* XXX semantics of return value? */
+		/* XXX flags for msync? */
+		if (-1 == msync(self->data + offset, size,
+				MS_SYNC))
+		{
+			PyErr_SetFromErrno(mmap_module_error);
+			return NULL;
+		}
+		return PyInt_FromLong(0);
+#endif /* UNIX */
+	}
+}
+
+static PyObject *
+mmap_seek_method(mmap_object *self, PyObject *args)
+{
+	Py_ssize_t dist;
+	int how=0;
+	CHECK_VALID(NULL);
+	if (!PyArg_ParseTuple(args, "n|i:seek", &dist, &how))
+		return NULL;
+	else {
+		size_t where;
+		switch (how) {
+		case 0: /* relative to start */
+			if (dist < 0)
+				goto onoutofrange;
+			where = dist;
+			break;
+		case 1: /* relative to current position */
+			if ((Py_ssize_t)self->pos + dist < 0)
+				goto onoutofrange;
+			where = self->pos + dist;
+			break;
+		case 2: /* relative to end */
+			if ((Py_ssize_t)self->size + dist < 0)
+				goto onoutofrange;
+			where = self->size + dist;
+			break;
+		default:
+			PyErr_SetString(PyExc_ValueError, "unknown seek type");
+			return NULL;
+		}
+		if (where > self->size)
+			goto onoutofrange;
+		self->pos = where;
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+
+  onoutofrange:
+	PyErr_SetString(PyExc_ValueError, "seek out of range");
+	return NULL;
+}
+
+static PyObject *
+mmap_move_method(mmap_object *self, PyObject *args)
+{
+	unsigned long dest, src, count;
+	CHECK_VALID(NULL);
+	if (!PyArg_ParseTuple(args, "kkk:move", &dest, &src, &count) ||
+	    !is_writeable(self)) {
+		return NULL;
+	} else {
+		/* bounds check the values */
+		if (/* end of source after end of data?? */
+			((src+count) > self->size)
+			/* dest will fit? */
+			|| (dest+count > self->size)) {
+			PyErr_SetString(PyExc_ValueError,
+					"source or destination out of range");
+			return NULL;
+		} else {
+			memmove(self->data+dest, self->data+src, count);
+			Py_INCREF(Py_None);
+			return Py_None;
+		}
+	}
+}
+
+static struct PyMethodDef mmap_object_methods[] = {
+	{"close",	(PyCFunction) mmap_close_method,	METH_NOARGS},
+	{"find",	(PyCFunction) mmap_find_method,		METH_VARARGS},
+	{"flush",	(PyCFunction) mmap_flush_method,	METH_VARARGS},
+	{"move",	(PyCFunction) mmap_move_method,		METH_VARARGS},
+	{"read",	(PyCFunction) mmap_read_method,		METH_VARARGS},
+	{"read_byte",	(PyCFunction) mmap_read_byte_method,  	METH_NOARGS},
+	{"readline",	(PyCFunction) mmap_read_line_method,	METH_NOARGS},
+	{"resize",	(PyCFunction) mmap_resize_method,	METH_VARARGS},
+	{"seek",	(PyCFunction) mmap_seek_method,		METH_VARARGS},
+	{"size",	(PyCFunction) mmap_size_method,		METH_NOARGS},
+	{"tell",	(PyCFunction) mmap_tell_method,		METH_NOARGS},
+	{"write",	(PyCFunction) mmap_write_method,	METH_VARARGS},
+	{"write_byte",	(PyCFunction) mmap_write_byte_method,	METH_VARARGS},
+	{NULL,	   NULL}       /* sentinel */
+};
+
+/* Functions for treating an mmap'ed file as a buffer */
+
+static Py_ssize_t
+mmap_buffer_getreadbuf(mmap_object *self, Py_ssize_t index, const void **ptr)
+{
+	CHECK_VALID(-1);
+	if (index != 0) {
+		PyErr_SetString(PyExc_SystemError,
+				"Accessing non-existent mmap segment");
+		return -1;
+	}
+	*ptr = self->data;
+	return self->size;
+}
+
+static Py_ssize_t
+mmap_buffer_getwritebuf(mmap_object *self, Py_ssize_t index, const void **ptr)
+{
+	CHECK_VALID(-1);
+	if (index != 0) {
+		PyErr_SetString(PyExc_SystemError,
+				"Accessing non-existent mmap segment");
+		return -1;
+	}
+	if (!is_writeable(self))
+		return -1;
+	*ptr = self->data;
+	return self->size;
+}
+
+static Py_ssize_t
+mmap_buffer_getsegcount(mmap_object *self, Py_ssize_t *lenp)
+{
+	CHECK_VALID(-1);
+	if (lenp)
+		*lenp = self->size;
+	return 1;
+}
+
+static Py_ssize_t
+mmap_buffer_getcharbuffer(mmap_object *self, Py_ssize_t index, const void **ptr)
+{
+	if (index != 0) {
+		PyErr_SetString(PyExc_SystemError,
+				"accessing non-existent buffer segment");
+		return -1;
+	}
+	*ptr = (const char *)self->data;
+	return self->size;
+}
+
+static PyObject *
+mmap_object_getattr(mmap_object *self, char *name)
+{
+	return Py_FindMethod(mmap_object_methods, (PyObject *)self, name);
+}
+
+static Py_ssize_t
+mmap_length(mmap_object *self)
+{
+	CHECK_VALID(-1);
+	return self->size;
+}
+
+static PyObject *
+mmap_item(mmap_object *self, Py_ssize_t i)
+{
+	CHECK_VALID(NULL);
+	if (i < 0 || (size_t)i >= self->size) {
+		PyErr_SetString(PyExc_IndexError, "mmap index out of range");
+		return NULL;
+	}
+	return PyString_FromStringAndSize(self->data + i, 1);
+}
+
+static PyObject *
+mmap_slice(mmap_object *self, Py_ssize_t ilow, Py_ssize_t ihigh)
+{
+	CHECK_VALID(NULL);
+	if (ilow < 0)
+		ilow = 0;
+	else if ((size_t)ilow > self->size)
+		ilow = self->size;
+	if (ihigh < 0)
+		ihigh = 0;
+	if (ihigh < ilow)
+		ihigh = ilow;
+	else if ((size_t)ihigh > self->size)
+		ihigh = self->size;
+
+	return PyString_FromStringAndSize(self->data + ilow, ihigh-ilow);
+}
+
+static PyObject *
+mmap_concat(mmap_object *self, PyObject *bb)
+{
+	CHECK_VALID(NULL);
+	PyErr_SetString(PyExc_SystemError,
+			"mmaps don't support concatenation");
+	return NULL;
+}
+
+static PyObject *
+mmap_repeat(mmap_object *self, Py_ssize_t n)
+{
+	CHECK_VALID(NULL);
+	PyErr_SetString(PyExc_SystemError,
+			"mmaps don't support repeat operation");
+	return NULL;
+}
+
+static int
+mmap_ass_slice(mmap_object *self, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v)
+{
+	const char *buf;
+
+	CHECK_VALID(-1);
+	if (ilow < 0)
+		ilow = 0;
+	else if ((size_t)ilow > self->size)
+		ilow = self->size;
+	if (ihigh < 0)
+		ihigh = 0;
+	if (ihigh < ilow)
+		ihigh = ilow;
+	else if ((size_t)ihigh > self->size)
+		ihigh = self->size;
+
+	if (v == NULL) {
+		PyErr_SetString(PyExc_TypeError,
+				"mmap object doesn't support slice deletion");
+		return -1;
+	}
+	if (! (PyString_Check(v)) ) {
+		PyErr_SetString(PyExc_IndexError,
+				"mmap slice assignment must be a string");
+		return -1;
+	}
+	if (PyString_Size(v) != (ihigh - ilow)) {
+		PyErr_SetString(PyExc_IndexError,
+				"mmap slice assignment is wrong size");
+		return -1;
+	}
+	if (!is_writeable(self))
+		return -1;
+	buf = PyString_AsString(v);
+	memcpy(self->data + ilow, buf, ihigh-ilow);
+	return 0;
+}
+
+static int
+mmap_ass_item(mmap_object *self, Py_ssize_t i, PyObject *v)
+{
+	const char *buf;
+
+	CHECK_VALID(-1);
+	if (i < 0 || (size_t)i >= self->size) {
+		PyErr_SetString(PyExc_IndexError, "mmap index out of range");
+		return -1;
+	}
+	if (v == NULL) {
+		PyErr_SetString(PyExc_TypeError,
+				"mmap object doesn't support item deletion");
+		return -1;
+	}
+	if (! (PyString_Check(v) && PyString_Size(v)==1) ) {
+		PyErr_SetString(PyExc_IndexError,
+				"mmap assignment must be single-character string");
+		return -1;
+	}
+	if (!is_writeable(self))
+		return -1;
+	buf = PyString_AsString(v);
+	self->data[i] = buf[0];
+	return 0;
+}
+
+static PySequenceMethods mmap_as_sequence = {
+	(lenfunc)mmap_length,		       /*sq_length*/
+	(binaryfunc)mmap_concat,	       /*sq_concat*/
+	(ssizeargfunc)mmap_repeat,	       /*sq_repeat*/
+	(ssizeargfunc)mmap_item,		       /*sq_item*/
+	(ssizessizeargfunc)mmap_slice,	       /*sq_slice*/
+	(ssizeobjargproc)mmap_ass_item,	       /*sq_ass_item*/
+	(ssizessizeobjargproc)mmap_ass_slice,      /*sq_ass_slice*/
+};
+
+static PyBufferProcs mmap_as_buffer = {
+	(readbufferproc)mmap_buffer_getreadbuf,
+	(writebufferproc)mmap_buffer_getwritebuf,
+	(segcountproc)mmap_buffer_getsegcount,
+	(charbufferproc)mmap_buffer_getcharbuffer,
+};
+
+static PyTypeObject mmap_object_type = {
+	PyObject_HEAD_INIT(0) /* patched in module init */
+	0,					/* ob_size */
+	"mmap.mmap",				/* tp_name */
+	sizeof(mmap_object),			/* tp_size */
+	0,					/* tp_itemsize */
+	/* methods */
+	(destructor) mmap_object_dealloc,	/* tp_dealloc */
+	0,					/* tp_print */
+	(getattrfunc) mmap_object_getattr,	/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	0,					/* tp_repr */
+	0,					/* tp_as_number */
+	&mmap_as_sequence,			/*tp_as_sequence*/
+	0,					/*tp_as_mapping*/
+	0,					/*tp_hash*/
+	0,					/*tp_call*/
+	0,					/*tp_str*/
+	0,					/*tp_getattro*/
+	0,					/*tp_setattro*/
+	&mmap_as_buffer,			/*tp_as_buffer*/
+	Py_TPFLAGS_HAVE_GETCHARBUFFER,		/*tp_flags*/
+	0,					/*tp_doc*/
+};
+
+
+/* extract the map size from the given PyObject
+
+   Returns -1 on error, with an appropriate Python exception raised. On
+   success, the map size is returned. */
+static Py_ssize_t
+_GetMapSize(PyObject *o)
+{
+	if (PyIndex_Check(o)) {
+		Py_ssize_t i = PyNumber_AsSsize_t(o, PyExc_OverflowError);
+		if (i==-1 && PyErr_Occurred()) 
+			return -1;
+		if (i < 0) {	 
+			PyErr_SetString(PyExc_OverflowError,
+					"memory mapped size must be positive");
+			return -1;
+		}
+		return i;
+	}
+
+	PyErr_SetString(PyExc_TypeError, "map size must be an integral value");
+	return -1;
+}
+
+#ifdef UNIX
+static PyObject *
+new_mmap_object(PyObject *self, PyObject *args, PyObject *kwdict)
+{
+#ifdef HAVE_FSTAT
+	struct stat st;
+#endif
+	mmap_object *m_obj;
+	PyObject *map_size_obj = NULL;
+	Py_ssize_t map_size;
+	int fd, flags = MAP_SHARED, prot = PROT_WRITE | PROT_READ;
+	int devzero = -1;
+	int access = (int)ACCESS_DEFAULT;
+	static char *keywords[] = {"fileno", "length",
+                                         "flags", "prot",
+                                         "access", NULL};
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iO|iii", keywords,
+					 &fd, &map_size_obj, &flags, &prot,
+                                         &access))
+		return NULL;
+	map_size = _GetMapSize(map_size_obj);
+	if (map_size < 0)
+		return NULL;
+
+	if ((access != (int)ACCESS_DEFAULT) &&
+	    ((flags != MAP_SHARED) || (prot != (PROT_WRITE | PROT_READ))))
+		return PyErr_Format(PyExc_ValueError,
+				    "mmap can't specify both access and flags, prot.");
+	switch ((access_mode)access) {
+	case ACCESS_READ:
+		flags = MAP_SHARED;
+		prot = PROT_READ;
+		break;
+	case ACCESS_WRITE:
+		flags = MAP_SHARED;
+		prot = PROT_READ | PROT_WRITE;
+		break;
+	case ACCESS_COPY:
+		flags = MAP_PRIVATE;
+		prot = PROT_READ | PROT_WRITE;
+		break;
+	case ACCESS_DEFAULT:
+		/* use the specified or default values of flags and prot */
+		break;
+	default:
+		return PyErr_Format(PyExc_ValueError,
+				    "mmap invalid access parameter.");
+	}
+
+#ifdef HAVE_FSTAT
+#  ifdef __VMS
+	/* on OpenVMS we must ensure that all bytes are written to the file */
+	fsync(fd);
+#  endif
+	if (fstat(fd, &st) == 0 && S_ISREG(st.st_mode)) {
+		if (map_size == 0) {
+			map_size = st.st_size;
+		} else if ((size_t)map_size > st.st_size) {
+			PyErr_SetString(PyExc_ValueError,
+					"mmap length is greater than file size");
+			return NULL;
+		}
+	}
+#endif
+	m_obj = PyObject_New(mmap_object, &mmap_object_type);
+	if (m_obj == NULL) {return NULL;}
+	m_obj->data = NULL;
+	m_obj->size = (size_t) map_size;
+	m_obj->pos = (size_t) 0;
+	if (fd == -1) {
+		m_obj->fd = -1;
+		/* Assume the caller wants to map anonymous memory.
+		   This is the same behaviour as Windows.  mmap.mmap(-1, size)
+		   on both Windows and Unix map anonymous memory.
+		*/
+#ifdef MAP_ANONYMOUS
+		/* BSD way to map anonymous memory */
+		flags |= MAP_ANONYMOUS;
+#else
+		/* SVR4 method to map anonymous memory is to open /dev/zero */
+		fd = devzero = open("/dev/zero", O_RDWR);
+		if (devzero == -1) {
+			Py_DECREF(m_obj);
+			PyErr_SetFromErrno(mmap_module_error);
+			return NULL;
+		}
+#endif
+	} else {
+		m_obj->fd = dup(fd);
+		if (m_obj->fd == -1) {
+			Py_DECREF(m_obj);
+			PyErr_SetFromErrno(mmap_module_error);
+			return NULL;
+		}
+	}
+
+	m_obj->data = mmap(NULL, map_size,
+			   prot, flags,
+			   fd, 0);
+
+	if (devzero != -1) {
+		close(devzero);
+	}
+
+	if (m_obj->data == (char *)-1) {
+	        m_obj->data = NULL;
+		Py_DECREF(m_obj);
+		PyErr_SetFromErrno(mmap_module_error);
+		return NULL;
+	}
+	m_obj->access = (access_mode)access;
+	return (PyObject *)m_obj;
+}
+#endif /* UNIX */
+
+#ifdef MS_WINDOWS
+static PyObject *
+new_mmap_object(PyObject *self, PyObject *args, PyObject *kwdict)
+{
+	mmap_object *m_obj;
+	PyObject *map_size_obj = NULL;
+	Py_ssize_t map_size;
+	DWORD size_hi;	/* upper 32 bits of m_obj->size */
+	DWORD size_lo;	/* lower 32 bits of m_obj->size */
+	char *tagname = "";
+	DWORD dwErr = 0;
+	int fileno;
+	HANDLE fh = 0;
+	int access = (access_mode)ACCESS_DEFAULT;
+	DWORD flProtect, dwDesiredAccess;
+	static char *keywords[] = { "fileno", "length",
+                                          "tagname",
+                                          "access", NULL };
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iO|zi", keywords,
+					 &fileno, &map_size_obj,
+					 &tagname, &access)) {
+		return NULL;
+	}
+
+	switch((access_mode)access) {
+	case ACCESS_READ:
+		flProtect = PAGE_READONLY;
+		dwDesiredAccess = FILE_MAP_READ;
+		break;
+	case ACCESS_DEFAULT:  case ACCESS_WRITE:
+		flProtect = PAGE_READWRITE;
+		dwDesiredAccess = FILE_MAP_WRITE;
+		break;
+	case ACCESS_COPY:
+		flProtect = PAGE_WRITECOPY;
+		dwDesiredAccess = FILE_MAP_COPY;
+		break;
+	default:
+		return PyErr_Format(PyExc_ValueError,
+				    "mmap invalid access parameter.");
+	}
+
+	map_size = _GetMapSize(map_size_obj);
+	if (map_size < 0)
+		return NULL;
+
+	/* assume -1 and 0 both mean invalid filedescriptor
+	   to 'anonymously' map memory.
+	   XXX: fileno == 0 is a valid fd, but was accepted prior to 2.5.
+	   XXX: Should this code be added?
+	   if (fileno == 0)
+	   	PyErr_Warn(PyExc_DeprecationWarning,
+			   "don't use 0 for anonymous memory");
+	 */
+	if (fileno != -1 && fileno != 0) {
+		fh = (HANDLE)_get_osfhandle(fileno);
+		if (fh==(HANDLE)-1) {
+			PyErr_SetFromErrno(mmap_module_error);
+			return NULL;
+		}
+		/* Win9x appears to need us seeked to zero */
+		lseek(fileno, 0, SEEK_SET);
+	}
+
+	m_obj = PyObject_New(mmap_object, &mmap_object_type);
+	if (m_obj == NULL)
+		return NULL;
+	/* Set every field to an invalid marker, so we can safely
+	   destruct the object in the face of failure */
+	m_obj->data = NULL;
+	m_obj->file_handle = INVALID_HANDLE_VALUE;
+	m_obj->map_handle = INVALID_HANDLE_VALUE;
+	m_obj->tagname = NULL;
+
+	if (fh) {
+		/* It is necessary to duplicate the handle, so the
+		   Python code can close it on us */
+		if (!DuplicateHandle(
+			GetCurrentProcess(), /* source process handle */
+			fh, /* handle to be duplicated */
+			GetCurrentProcess(), /* target proc handle */
+			(LPHANDLE)&m_obj->file_handle, /* result */
+			0, /* access - ignored due to options value */
+			FALSE, /* inherited by child processes? */
+			DUPLICATE_SAME_ACCESS)) { /* options */
+			dwErr = GetLastError();
+			Py_DECREF(m_obj);
+			PyErr_SetFromWindowsErr(dwErr);
+			return NULL;
+		}
+		if (!map_size) {
+			DWORD low,high;
+			low = GetFileSize(fh, &high);
+			/* low might just happen to have the value INVALID_FILE_SIZE;
+    			   so we need to check the last error also. */
+			if (low == INVALID_FILE_SIZE &&
+			    (dwErr = GetLastError()) != NO_ERROR) {
+				Py_DECREF(m_obj);
+				return PyErr_SetFromWindowsErr(dwErr);
+			}	
+				    
+#if SIZEOF_SIZE_T > 4
+			m_obj->size = (((size_t)high)<<32) + low;
+#else
+			if (high)
+				/* File is too large to map completely */
+				m_obj->size = (size_t)-1;
+			else
+				m_obj->size = low;
+#endif
+		} else {
+			m_obj->size = map_size;
+		}
+	}
+	else {
+		m_obj->size = map_size;
+	}
+
+	/* set the initial position */
+	m_obj->pos = (size_t) 0;
+
+	/* set the tag name */
+	if (tagname != NULL && *tagname != '\0') {
+		m_obj->tagname = PyMem_Malloc(strlen(tagname)+1);
+		if (m_obj->tagname == NULL) {
+			PyErr_NoMemory();
+			Py_DECREF(m_obj);
+			return NULL;
+		}
+		strcpy(m_obj->tagname, tagname);
+	}
+	else
+		m_obj->tagname = NULL;
+
+	m_obj->access = (access_mode)access;
+	/* DWORD is a 4-byte int.  If we're on a box where size_t consumes
+	 * more than 4 bytes, we need to break it apart.  Else (size_t
+	 * consumes 4 bytes), C doesn't define what happens if we shift
+	 * right by 32, so we need different code.
+	 */
+#if SIZEOF_SIZE_T > 4
+	size_hi = (DWORD)(m_obj->size >> 32);
+	size_lo = (DWORD)(m_obj->size & 0xFFFFFFFF);
+#else
+	size_hi = 0;
+	size_lo = (DWORD)m_obj->size;
+#endif
+	m_obj->map_handle = CreateFileMapping(m_obj->file_handle,
+					      NULL,
+					      flProtect,
+					      size_hi,
+					      size_lo,
+					      m_obj->tagname);
+	if (m_obj->map_handle != NULL) {
+		m_obj->data = (char *) MapViewOfFile(m_obj->map_handle,
+						     dwDesiredAccess,
+						     0,
+						     0,
+						     0);
+		if (m_obj->data != NULL)
+			return (PyObject *)m_obj;
+		else
+			dwErr = GetLastError();
+	} else
+		dwErr = GetLastError();
+	Py_DECREF(m_obj);
+	PyErr_SetFromWindowsErr(dwErr);
+	return NULL;
+}
+#endif /* MS_WINDOWS */
+
+/* List of functions exported by this module */
+static struct PyMethodDef mmap_functions[] = {
+	{"mmap",	(PyCFunction) new_mmap_object,
+	 METH_VARARGS|METH_KEYWORDS},
+	{NULL,		NULL}	     /* Sentinel */
+};
+
+static void
+setint(PyObject *d, const char *name, long value)
+{
+	PyObject *o = PyInt_FromLong(value);
+	if (o && PyDict_SetItemString(d, name, o) == 0) {
+		Py_DECREF(o);
+	}
+}
+
+PyMODINIT_FUNC
+	initmmap(void)
+{
+	PyObject *dict, *module;
+
+	/* Patch the object type */
+	mmap_object_type.ob_type = &PyType_Type;
+
+	module = Py_InitModule("mmap", mmap_functions);
+	if (module == NULL)
+		return;
+	dict = PyModule_GetDict(module);
+	if (!dict)
+		return;
+	mmap_module_error = PyExc_EnvironmentError;
+	PyDict_SetItemString(dict, "error", mmap_module_error);
+#ifdef PROT_EXEC
+	setint(dict, "PROT_EXEC", PROT_EXEC);
+#endif
+#ifdef PROT_READ
+	setint(dict, "PROT_READ", PROT_READ);
+#endif
+#ifdef PROT_WRITE
+	setint(dict, "PROT_WRITE", PROT_WRITE);
+#endif
+
+#ifdef MAP_SHARED
+	setint(dict, "MAP_SHARED", MAP_SHARED);
+#endif
+#ifdef MAP_PRIVATE
+	setint(dict, "MAP_PRIVATE", MAP_PRIVATE);
+#endif
+#ifdef MAP_DENYWRITE
+	setint(dict, "MAP_DENYWRITE", MAP_DENYWRITE);
+#endif
+#ifdef MAP_EXECUTABLE
+	setint(dict, "MAP_EXECUTABLE", MAP_EXECUTABLE);
+#endif
+#ifdef MAP_ANONYMOUS
+	setint(dict, "MAP_ANON", MAP_ANONYMOUS);
+	setint(dict, "MAP_ANONYMOUS", MAP_ANONYMOUS);
+#endif
+
+	setint(dict, "PAGESIZE", (long)my_getpagesize());
+
+	setint(dict, "ACCESS_READ", ACCESS_READ);
+	setint(dict, "ACCESS_WRITE", ACCESS_WRITE);
+	setint(dict, "ACCESS_COPY", ACCESS_COPY);
+}

Added: vendor/Python/current/Modules/nismodule.c
===================================================================
--- vendor/Python/current/Modules/nismodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/nismodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,444 @@
+/***********************************************************
+    Written by:
+	Fred Gansevles <Fred.Gansevles at cs.utwente.nl>
+	B&O group,
+	Faculteit der Informatica,
+	Universiteit Twente,
+	Enschede,
+	the Netherlands.
+******************************************************************/
+
+/* NIS module implementation */
+
+#include "Python.h"
+
+#include <sys/time.h>
+#include <sys/types.h>
+#include <rpc/rpc.h>
+#include <rpcsvc/yp_prot.h>
+#include <rpcsvc/ypclnt.h>
+
+#ifdef __sgi
+/* This is missing from rpcsvc/ypclnt.h */
+extern int yp_get_default_domain(char **);
+#endif
+
+PyDoc_STRVAR(get_default_domain__doc__, 
+"get_default_domain() -> str\n\
+Corresponds to the C library yp_get_default_domain() call, returning\n\
+the default NIS domain.\n");
+
+PyDoc_STRVAR(match__doc__,
+"match(key, map, domain = defaultdomain)\n\
+Corresponds to the C library yp_match() call, returning the value of\n\
+key in the given map. Optionally domain can be specified but it\n\
+defaults to the system default domain.\n");
+
+PyDoc_STRVAR(cat__doc__,
+"cat(map, domain = defaultdomain)\n\
+Returns the entire map as a dictionary. Optionally domain can be\n\
+specified but it defaults to the system default domain.\n");
+
+PyDoc_STRVAR(maps__doc__,
+"maps(domain = defaultdomain)\n\
+Returns an array of all available NIS maps within a domain. If domain\n\
+is not specified it defaults to the system default domain.\n");
+
+static PyObject *NisError;
+
+static PyObject *
+nis_error (int err)
+{
+	PyErr_SetString(NisError, yperr_string(err));
+	return NULL;
+}
+
+static struct nis_map {
+	char *alias;
+	char *map;
+	int  fix;
+} aliases [] = {
+	{"passwd",	"passwd.byname",	0},
+	{"group",	"group.byname",		0},
+	{"networks",	"networks.byaddr",	0},
+	{"hosts",	"hosts.byname",		0},
+	{"protocols",	"protocols.bynumber",	0},
+	{"services",	"services.byname",	0},
+	{"aliases",	"mail.aliases",		1}, /* created with 'makedbm -a' */
+	{"ethers",	"ethers.byname",	0},
+	{0L,		0L,			0}
+};
+
+static char *
+nis_mapname (char *map, int *pfix)
+{
+	int i;
+
+	*pfix = 0;
+	for (i=0; aliases[i].alias != 0L; i++) {
+		if (!strcmp (aliases[i].alias, map)) {
+			*pfix = aliases[i].fix;
+			return aliases[i].map;
+		}
+		if (!strcmp (aliases[i].map, map)) {
+			*pfix = aliases[i].fix;
+			return aliases[i].map;
+		}
+	}
+
+	return map;
+}
+
+#ifdef __APPLE__
+typedef int (*foreachfunc)(unsigned long, char *, int, char *, int, void *);
+#else
+typedef int (*foreachfunc)(int, char *, int, char *, int, char *);
+#endif
+
+struct ypcallback_data {
+	PyObject	*dict;
+	int			fix;
+};
+
+static int
+nis_foreach (int instatus, char *inkey, int inkeylen, char *inval,
+             int invallen, struct ypcallback_data *indata)
+{
+	if (instatus == YP_TRUE) {
+		PyObject *key;
+		PyObject *val;
+		int err;
+
+		if (indata->fix) {
+		    if (inkeylen > 0 && inkey[inkeylen-1] == '\0')
+			inkeylen--;
+		    if (invallen > 0 && inval[invallen-1] == '\0')
+			invallen--;
+		}
+		key = PyString_FromStringAndSize(inkey, inkeylen);
+		val = PyString_FromStringAndSize(inval, invallen);
+		if (key == NULL || val == NULL) {
+			/* XXX error -- don't know how to handle */
+			PyErr_Clear();
+			Py_XDECREF(key);
+			Py_XDECREF(val);
+			return 1;
+		}
+		err = PyDict_SetItem(indata->dict, key, val);
+		Py_DECREF(key);
+		Py_DECREF(val);
+		if (err != 0) {
+			PyErr_Clear();
+			return 1;
+		}
+		return 0;
+	}
+	return 1;
+}
+
+static PyObject *
+nis_get_default_domain (PyObject *self)
+{
+	char *domain;
+	int err;
+	PyObject *res;
+
+	if ((err = yp_get_default_domain(&domain)) != 0)
+		return nis_error(err);
+
+	res = PyString_FromStringAndSize (domain, strlen(domain));
+	return res;
+}
+
+static PyObject *
+nis_match (PyObject *self, PyObject *args, PyObject *kwdict)
+{
+	char *match;
+	char *domain = NULL;
+	int keylen, len;
+	char *key, *map;
+	int err;
+	PyObject *res;
+	int fix;
+	static char *kwlist[] = {"key", "map", "domain", NULL};
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwdict,
+					 "t#s|s:match", kwlist,
+					 &key, &keylen, &map, &domain))
+		return NULL;
+	if (!domain && ((err = yp_get_default_domain(&domain)) != 0))
+		return nis_error(err);
+	map = nis_mapname (map, &fix);
+	if (fix)
+	    keylen++;
+	Py_BEGIN_ALLOW_THREADS
+	err = yp_match (domain, map, key, keylen, &match, &len);
+	Py_END_ALLOW_THREADS
+	if (fix)
+	    len--;
+	if (err != 0)
+		return nis_error(err);
+	res = PyString_FromStringAndSize (match, len);
+	free (match);
+	return res;
+}
+
+static PyObject *
+nis_cat (PyObject *self, PyObject *args, PyObject *kwdict)
+{
+	char *domain = NULL;
+	char *map;
+	struct ypall_callback cb;
+	struct ypcallback_data data;
+	PyObject *dict;
+	int err;
+	static char *kwlist[] = {"map", "domain", NULL};
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwdict, "s|s:cat",
+				         kwlist, &map, &domain))
+		return NULL;
+	if (!domain && ((err = yp_get_default_domain(&domain)) != 0))
+		return nis_error(err);
+	dict = PyDict_New ();
+	if (dict == NULL)
+		return NULL;
+	cb.foreach = (foreachfunc)nis_foreach;
+	data.dict = dict;
+	map = nis_mapname (map, &data.fix);
+	cb.data = (char *)&data;
+	Py_BEGIN_ALLOW_THREADS
+	err = yp_all (domain, map, &cb);
+	Py_END_ALLOW_THREADS
+	if (err != 0) {
+		Py_DECREF(dict);
+		return nis_error(err);
+	}
+	return dict;
+}
+
+/* These should be u_long on Sun h/w but not on 64-bit h/w.
+   This is not portable to machines with 16-bit ints and no prototypes */
+#ifndef YPPROC_MAPLIST
+#define YPPROC_MAPLIST	11
+#endif
+#ifndef YPPROG
+#define YPPROG		100004
+#endif
+#ifndef YPVERS
+#define YPVERS		2
+#endif
+
+typedef char *domainname;
+typedef char *mapname;
+
+enum nisstat {
+	NIS_TRUE = 1,
+	NIS_NOMORE = 2,
+	NIS_FALSE = 0,
+	NIS_NOMAP = -1,
+	NIS_NODOM = -2,
+	NIS_NOKEY = -3,
+	NIS_BADOP = -4,
+	NIS_BADDB = -5,
+	NIS_YPERR = -6,
+	NIS_BADARGS = -7,
+	NIS_VERS = -8
+};
+typedef enum nisstat nisstat;
+
+struct nismaplist {
+	mapname map;
+	struct nismaplist *next;
+};
+typedef struct nismaplist nismaplist;
+
+struct nisresp_maplist {
+	nisstat stat;
+	nismaplist *maps;
+};
+typedef struct nisresp_maplist nisresp_maplist;
+
+static struct timeval TIMEOUT = { 25, 0 };
+
+static
+bool_t
+nis_xdr_domainname(XDR *xdrs, domainname *objp)
+{
+	if (!xdr_string(xdrs, objp, YPMAXDOMAIN)) {
+		return (FALSE);
+	}
+	return (TRUE);
+}
+
+static
+bool_t
+nis_xdr_mapname(XDR *xdrs, mapname *objp)
+{
+	if (!xdr_string(xdrs, objp, YPMAXMAP)) {
+		return (FALSE);
+	}
+	return (TRUE);
+}
+
+static
+bool_t
+nis_xdr_ypmaplist(XDR *xdrs, nismaplist *objp)
+{
+	if (!nis_xdr_mapname(xdrs, &objp->map)) {
+		return (FALSE);
+	}
+	if (!xdr_pointer(xdrs, (char **)&objp->next,
+			 sizeof(nismaplist), (xdrproc_t)nis_xdr_ypmaplist))
+	{
+		return (FALSE);
+	}
+	return (TRUE);
+}
+
+static
+bool_t
+nis_xdr_ypstat(XDR *xdrs, nisstat *objp)
+{
+	if (!xdr_enum(xdrs, (enum_t *)objp)) {
+		return (FALSE);
+	}
+	return (TRUE);
+}
+
+
+static
+bool_t
+nis_xdr_ypresp_maplist(XDR *xdrs, nisresp_maplist *objp)
+{
+	if (!nis_xdr_ypstat(xdrs, &objp->stat)) {
+		return (FALSE);
+	}
+	if (!xdr_pointer(xdrs, (char **)&objp->maps,
+			 sizeof(nismaplist), (xdrproc_t)nis_xdr_ypmaplist))
+	{
+		return (FALSE);
+	}
+	return (TRUE);
+}
+
+
+static
+nisresp_maplist *
+nisproc_maplist_2(domainname *argp, CLIENT *clnt)
+{
+	static nisresp_maplist res;
+
+	memset(&res, 0, sizeof(res));
+	if (clnt_call(clnt, YPPROC_MAPLIST,
+		      (xdrproc_t)nis_xdr_domainname, (caddr_t)argp,
+		      (xdrproc_t)nis_xdr_ypresp_maplist, (caddr_t)&res,
+		      TIMEOUT) != RPC_SUCCESS)
+	{
+		return (NULL);
+	}
+	return (&res);
+}
+
+static
+nismaplist *
+nis_maplist (char *dom)
+{
+	nisresp_maplist *list;
+	CLIENT *cl;
+	char *server = NULL;
+	int mapi = 0;
+
+	while (!server && aliases[mapi].map != 0L) {
+		yp_master (dom, aliases[mapi].map, &server);
+		mapi++;
+	}
+        if (!server) {
+            PyErr_SetString(NisError, "No NIS master found for any map");
+            return NULL;
+        }
+	cl = clnt_create(server, YPPROG, YPVERS, "tcp");
+	if (cl == NULL) {
+		PyErr_SetString(NisError, clnt_spcreateerror(server));
+		goto finally;
+	}
+	list = nisproc_maplist_2 (&dom, cl);
+	clnt_destroy(cl);
+	if (list == NULL)
+		goto finally;
+	if (list->stat != NIS_TRUE)
+		goto finally;
+
+	free(server);
+	return list->maps;
+
+  finally:
+	free(server);
+	return NULL;
+}
+
+static PyObject *
+nis_maps (PyObject *self, PyObject *args, PyObject *kwdict)
+{
+	char *domain = NULL;
+	nismaplist *maps;
+	PyObject *list;
+        int err;
+	static char *kwlist[] = {"domain", NULL};
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwdict,
+					 "|s:maps", kwlist, &domain))
+		return NULL;
+	if (!domain && ((err = yp_get_default_domain (&domain)) != 0)) {
+		nis_error(err);
+		return NULL;
+	}
+
+	if ((maps = nis_maplist (domain)) == NULL)
+		return NULL;
+	if ((list = PyList_New(0)) == NULL)
+		return NULL;
+	for (maps = maps; maps; maps = maps->next) {
+		PyObject *str = PyString_FromString(maps->map);
+		if (!str || PyList_Append(list, str) < 0)
+		{
+			Py_DECREF(list);
+			list = NULL;
+			break;
+		}
+		Py_DECREF(str);
+	}
+	/* XXX Shouldn't we free the list of maps now? */
+	return list;
+}
+
+static PyMethodDef nis_methods[] = {
+	{"match",		(PyCFunction)nis_match,
+					METH_VARARGS | METH_KEYWORDS,
+					match__doc__},
+	{"cat",			(PyCFunction)nis_cat,
+					METH_VARARGS | METH_KEYWORDS,
+					cat__doc__},
+	{"maps",		(PyCFunction)nis_maps,
+					METH_VARARGS | METH_KEYWORDS,
+					maps__doc__},
+	{"get_default_domain",	(PyCFunction)nis_get_default_domain,
+ 					METH_NOARGS,
+					get_default_domain__doc__},
+	{NULL,			NULL}		 /* Sentinel */
+};
+
+PyDoc_STRVAR(nis__doc__,
+"This module contains functions for accessing NIS maps.\n");
+
+void
+initnis (void)
+{
+	PyObject *m, *d;
+	m = Py_InitModule3("nis", nis_methods, nis__doc__);
+	if (m == NULL)
+		return;
+	d = PyModule_GetDict(m);
+	NisError = PyErr_NewException("nis.error", NULL, NULL);
+	if (NisError != NULL)
+		PyDict_SetItemString(d, "error", NisError);
+}

Added: vendor/Python/current/Modules/operator.c
===================================================================
--- vendor/Python/current/Modules/operator.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/operator.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,602 @@
+
+#include "Python.h"
+
+PyDoc_STRVAR(operator_doc,
+"Operator interface.\n\
+\n\
+This module exports a set of functions implemented in C corresponding\n\
+to the intrinsic operators of Python.  For example, operator.add(x, y)\n\
+is equivalent to the expression x+y.  The function names are those\n\
+used for special class methods; variants without leading and trailing\n\
+'__' are also provided for convenience.");
+
+#define spam1(OP,AOP) static PyObject *OP(PyObject *s, PyObject *a1) { \
+  return AOP(a1); }
+
+#define spam2(OP,AOP) static PyObject *OP(PyObject *s, PyObject *a) { \
+  PyObject *a1, *a2; \
+  if(! PyArg_UnpackTuple(a,#OP,2,2,&a1,&a2)) return NULL; \
+  return AOP(a1,a2); }
+
+#define spamoi(OP,AOP) static PyObject *OP(PyObject *s, PyObject *a) { \
+  PyObject *a1; int a2; \
+  if(! PyArg_ParseTuple(a,"Oi:" #OP,&a1,&a2)) return NULL; \
+  return AOP(a1,a2); }
+
+#define spam2n(OP,AOP) static PyObject *OP(PyObject *s, PyObject *a) { \
+  PyObject *a1, *a2; \
+  if(! PyArg_UnpackTuple(a,#OP,2,2,&a1,&a2)) return NULL; \
+  if(-1 == AOP(a1,a2)) return NULL; \
+  Py_INCREF(Py_None); \
+  return Py_None; }
+
+#define spam3n(OP,AOP) static PyObject *OP(PyObject *s, PyObject *a) { \
+  PyObject *a1, *a2, *a3; \
+  if(! PyArg_UnpackTuple(a,#OP,3,3,&a1,&a2,&a3)) return NULL; \
+  if(-1 == AOP(a1,a2,a3)) return NULL; \
+  Py_INCREF(Py_None); \
+  return Py_None; }
+
+#define spami(OP,AOP) static PyObject *OP(PyObject *s, PyObject *a1) { \
+  long r; \
+  if(-1 == (r=AOP(a1))) return NULL; \
+  return PyBool_FromLong(r); }
+
+#define spami2(OP,AOP) static PyObject *OP(PyObject *s, PyObject *a) { \
+  PyObject *a1, *a2; long r; \
+  if(! PyArg_UnpackTuple(a,#OP,2,2,&a1,&a2)) return NULL; \
+  if(-1 == (r=AOP(a1,a2))) return NULL; \
+  return PyInt_FromLong(r); }
+
+#define spamn2(OP,AOP) static PyObject *OP(PyObject *s, PyObject *a) { \
+  PyObject *a1, *a2; Py_ssize_t r; \
+  if(! PyArg_UnpackTuple(a,#OP,2,2,&a1,&a2)) return NULL; \
+  if(-1 == (r=AOP(a1,a2))) return NULL; \
+  return PyInt_FromSsize_t(r); }
+
+#define spami2b(OP,AOP) static PyObject *OP(PyObject *s, PyObject *a) { \
+  PyObject *a1, *a2; long r; \
+  if(! PyArg_UnpackTuple(a,#OP,2,2,&a1,&a2)) return NULL; \
+  if(-1 == (r=AOP(a1,a2))) return NULL; \
+  return PyBool_FromLong(r); }
+
+#define spamrc(OP,A) static PyObject *OP(PyObject *s, PyObject *a) { \
+  PyObject *a1, *a2; \
+  if(! PyArg_UnpackTuple(a,#OP,2,2,&a1,&a2)) return NULL; \
+  return PyObject_RichCompare(a1,a2,A); }
+
+spami(isCallable       , PyCallable_Check)
+spami(isNumberType     , PyNumber_Check)
+spami(truth            , PyObject_IsTrue)
+spam2(op_add           , PyNumber_Add)
+spam2(op_sub           , PyNumber_Subtract)
+spam2(op_mul           , PyNumber_Multiply)
+spam2(op_div           , PyNumber_Divide)
+spam2(op_floordiv      , PyNumber_FloorDivide)
+spam2(op_truediv       , PyNumber_TrueDivide)
+spam2(op_mod           , PyNumber_Remainder)
+spam1(op_neg           , PyNumber_Negative)
+spam1(op_pos           , PyNumber_Positive)
+spam1(op_abs           , PyNumber_Absolute)
+spam1(op_inv           , PyNumber_Invert)
+spam1(op_invert        , PyNumber_Invert)
+spam2(op_lshift        , PyNumber_Lshift)
+spam2(op_rshift        , PyNumber_Rshift)
+spami(op_not_          , PyObject_Not)
+spam2(op_and_          , PyNumber_And)
+spam2(op_xor           , PyNumber_Xor)
+spam2(op_or_           , PyNumber_Or)
+spam2(op_iadd          , PyNumber_InPlaceAdd)
+spam2(op_isub          , PyNumber_InPlaceSubtract)
+spam2(op_imul          , PyNumber_InPlaceMultiply)
+spam2(op_idiv          , PyNumber_InPlaceDivide)
+spam2(op_ifloordiv     , PyNumber_InPlaceFloorDivide)
+spam2(op_itruediv      , PyNumber_InPlaceTrueDivide)
+spam2(op_imod          , PyNumber_InPlaceRemainder)
+spam2(op_ilshift       , PyNumber_InPlaceLshift)
+spam2(op_irshift       , PyNumber_InPlaceRshift)
+spam2(op_iand          , PyNumber_InPlaceAnd)
+spam2(op_ixor          , PyNumber_InPlaceXor)
+spam2(op_ior           , PyNumber_InPlaceOr)
+spami(isSequenceType   , PySequence_Check)
+spam2(op_concat        , PySequence_Concat)
+spamoi(op_repeat       , PySequence_Repeat)
+spam2(op_iconcat       , PySequence_InPlaceConcat)
+spamoi(op_irepeat      , PySequence_InPlaceRepeat)
+spami2b(op_contains     , PySequence_Contains)
+spami2b(sequenceIncludes, PySequence_Contains)
+spamn2(indexOf         , PySequence_Index)
+spamn2(countOf         , PySequence_Count)
+spami(isMappingType    , PyMapping_Check)
+spam2(op_getitem       , PyObject_GetItem)
+spam2n(op_delitem       , PyObject_DelItem)
+spam3n(op_setitem      , PyObject_SetItem)
+spamrc(op_lt           , Py_LT)
+spamrc(op_le           , Py_LE)
+spamrc(op_eq           , Py_EQ)
+spamrc(op_ne           , Py_NE)
+spamrc(op_gt           , Py_GT)
+spamrc(op_ge           , Py_GE)
+
+static PyObject*
+op_pow(PyObject *s, PyObject *a)
+{
+	PyObject *a1, *a2;
+	if (PyArg_UnpackTuple(a,"pow", 2, 2, &a1, &a2))
+		return PyNumber_Power(a1, a2, Py_None);
+	return NULL;
+}
+
+static PyObject*
+op_ipow(PyObject *s, PyObject *a)
+{
+	PyObject *a1, *a2;
+	if (PyArg_UnpackTuple(a,"ipow", 2, 2, &a1, &a2))
+		return PyNumber_InPlacePower(a1, a2, Py_None);
+	return NULL;
+}
+
+static PyObject *
+op_index(PyObject *s, PyObject *a)
+{
+	return PyNumber_Index(a);
+}
+
+static PyObject*
+is_(PyObject *s, PyObject *a)
+{
+	PyObject *a1, *a2, *result = NULL;
+	if (PyArg_UnpackTuple(a,"is_", 2, 2, &a1, &a2)) {
+		result = (a1 == a2) ? Py_True : Py_False;
+		Py_INCREF(result);
+	}
+	return result;
+}
+
+static PyObject*
+is_not(PyObject *s, PyObject *a)
+{
+	PyObject *a1, *a2, *result = NULL;
+	if (PyArg_UnpackTuple(a,"is_not", 2, 2, &a1, &a2)) {
+		result = (a1 != a2) ? Py_True : Py_False;
+		Py_INCREF(result);
+	}
+	return result;
+}
+
+static PyObject*
+op_getslice(PyObject *s, PyObject *a)
+{
+        PyObject *a1;
+        Py_ssize_t a2, a3;
+
+        if (!PyArg_ParseTuple(a, "Onn:getslice", &a1, &a2, &a3))
+                return NULL;
+        return PySequence_GetSlice(a1, a2, a3);
+}
+
+static PyObject*
+op_setslice(PyObject *s, PyObject *a)
+{
+        PyObject *a1, *a4;
+        Py_ssize_t a2, a3;
+
+        if (!PyArg_ParseTuple(a, "OnnO:setslice", &a1, &a2, &a3, &a4))
+                return NULL;
+
+        if (-1 == PySequence_SetSlice(a1, a2, a3, a4))
+                return NULL;
+
+	Py_RETURN_NONE;
+}
+
+static PyObject*
+op_delslice(PyObject *s, PyObject *a)
+{
+        PyObject *a1;
+        Py_ssize_t a2, a3;
+
+        if (!PyArg_ParseTuple(a, "Onn:delslice", &a1, &a2, &a3))
+                return NULL;
+
+        if (-1 == PySequence_DelSlice(a1, a2, a3))
+                return NULL;
+
+	Py_RETURN_NONE;
+}
+
+#undef spam1
+#undef spam2
+#undef spam1o
+#undef spam1o
+#define spam1(OP,DOC) {#OP, OP, METH_VARARGS, PyDoc_STR(DOC)},
+#define spam2(OP,ALTOP,DOC) {#OP, op_##OP, METH_VARARGS, PyDoc_STR(DOC)}, \
+			   {#ALTOP, op_##OP, METH_VARARGS, PyDoc_STR(DOC)}, 
+#define spam1o(OP,DOC) {#OP, OP, METH_O, PyDoc_STR(DOC)},
+#define spam2o(OP,ALTOP,DOC) {#OP, op_##OP, METH_O, PyDoc_STR(DOC)}, \
+			   {#ALTOP, op_##OP, METH_O, PyDoc_STR(DOC)}, 
+
+static struct PyMethodDef operator_methods[] = {
+
+spam1o(isCallable,
+ "isCallable(a) -- Same as callable(a).")
+spam1o(isNumberType,
+ "isNumberType(a) -- Return True if a has a numeric type, False otherwise.")
+spam1o(isSequenceType,
+ "isSequenceType(a) -- Return True if a has a sequence type, False otherwise.")
+spam1o(truth,
+ "truth(a) -- Return True if a is true, False otherwise.")
+spam2(contains,__contains__,
+ "contains(a, b) -- Same as b in a (note reversed operands).")
+spam1(sequenceIncludes,
+ "sequenceIncludes(a, b) -- Same as b in a (note reversed operands; deprecated).")
+spam1(indexOf,
+ "indexOf(a, b) -- Return the first index of b in a.")
+spam1(countOf,
+ "countOf(a, b) -- Return the number of times b occurs in a.")
+spam1o(isMappingType,
+ "isMappingType(a) -- Return True if a has a mapping type, False otherwise.")
+
+spam1(is_, "is_(a, b) -- Same as a is b.")
+spam1(is_not, "is_not(a, b) -- Same as a is not b.")
+spam2o(index, __index__, "index(a) -- Same as a.__index__()")
+spam2(add,__add__, "add(a, b) -- Same as a + b.")
+spam2(sub,__sub__, "sub(a, b) -- Same as a - b.")
+spam2(mul,__mul__, "mul(a, b) -- Same as a * b.")
+spam2(div,__div__, "div(a, b) -- Same as a / b when __future__.division is not in effect.")
+spam2(floordiv,__floordiv__, "floordiv(a, b) -- Same as a // b.")
+spam2(truediv,__truediv__, "truediv(a, b) -- Same as a / b when __future__.division is in effect.")
+spam2(mod,__mod__, "mod(a, b) -- Same as a % b.")
+spam2o(neg,__neg__, "neg(a) -- Same as -a.")
+spam2o(pos,__pos__, "pos(a) -- Same as +a.")
+spam2o(abs,__abs__, "abs(a) -- Same as abs(a).")
+spam2o(inv,__inv__, "inv(a) -- Same as ~a.")
+spam2o(invert,__invert__, "invert(a) -- Same as ~a.")
+spam2(lshift,__lshift__, "lshift(a, b) -- Same as a << b.")
+spam2(rshift,__rshift__, "rshift(a, b) -- Same as a >> b.")
+spam2o(not_,__not__, "not_(a) -- Same as not a.")
+spam2(and_,__and__, "and_(a, b) -- Same as a & b.")
+spam2(xor,__xor__, "xor(a, b) -- Same as a ^ b.")
+spam2(or_,__or__, "or_(a, b) -- Same as a | b.")
+spam2(iadd,__iadd__, "iadd(a, b) -- Same as a += b.")
+spam2(isub,__isub__, "isub(a, b) -- Same as a -= b.")
+spam2(imul,__imul__, "imul(a, b) -- Same as a *= b.")
+spam2(idiv,__idiv__, "idiv(a, b) -- Same as a /= b when __future__.division is not in effect.")
+spam2(ifloordiv,__ifloordiv__, "ifloordiv(a, b) -- Same as a //= b.")
+spam2(itruediv,__itruediv__, "itruediv(a, b) -- Same as a /= b when __future__.division is in effect.")
+spam2(imod,__imod__, "imod(a, b) -- Same as a %= b.")
+spam2(ilshift,__ilshift__, "ilshift(a, b) -- Same as a <<= b.")
+spam2(irshift,__irshift__, "irshift(a, b) -- Same as a >>= b.")
+spam2(iand,__iand__, "iand(a, b) -- Same as a &= b.")
+spam2(ixor,__ixor__, "ixor(a, b) -- Same as a ^= b.")
+spam2(ior,__ior__, "ior(a, b) -- Same as a |= b.")
+spam2(concat,__concat__,
+ "concat(a, b) -- Same as a + b, for a and b sequences.")
+spam2(repeat,__repeat__,
+ "repeat(a, b) -- Return a * b, where a is a sequence, and b is an integer.")
+spam2(iconcat,__iconcat__,
+ "iconcat(a, b) -- Same as a += b, for a and b sequences.")
+spam2(irepeat,__irepeat__,
+ "irepeat(a, b) -- Same as a *= b, where a is a sequence, and b is an integer.")
+spam2(getitem,__getitem__,
+ "getitem(a, b) -- Same as a[b].")
+spam2(setitem,__setitem__,
+ "setitem(a, b, c) -- Same as a[b] = c.")
+spam2(delitem,__delitem__,
+ "delitem(a, b) -- Same as del a[b].")
+spam2(pow,__pow__, "pow(a, b) -- Same as a ** b.")
+spam2(ipow,__ipow__, "ipow(a, b) -- Same as a **= b.")
+spam2(getslice,__getslice__,
+ "getslice(a, b, c) -- Same as a[b:c].")
+spam2(setslice,__setslice__,
+"setslice(a, b, c, d) -- Same as a[b:c] = d.")
+spam2(delslice,__delslice__,
+"delslice(a, b, c) -- Same as del a[b:c].")
+spam2(lt,__lt__, "lt(a, b) -- Same as a<b.")
+spam2(le,__le__, "le(a, b) -- Same as a<=b.")
+spam2(eq,__eq__, "eq(a, b) -- Same as a==b.")
+spam2(ne,__ne__, "ne(a, b) -- Same as a!=b.")
+spam2(gt,__gt__, "gt(a, b) -- Same as a>b.")
+spam2(ge,__ge__, "ge(a, b) -- Same as a>=b.")
+
+	{NULL,		NULL}		/* sentinel */
+
+};
+
+/* itemgetter object **********************************************************/
+
+typedef struct {
+	PyObject_HEAD
+	Py_ssize_t nitems;
+	PyObject *item;
+} itemgetterobject;
+
+static PyTypeObject itemgetter_type;
+
+static PyObject *
+itemgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	itemgetterobject *ig;
+	PyObject *item;
+	Py_ssize_t nitems;
+
+	if (!_PyArg_NoKeywords("itemgetter()", kwds))
+		return NULL;
+
+	nitems = PyTuple_GET_SIZE(args);
+	if (nitems <= 1) {
+		if (!PyArg_UnpackTuple(args, "itemgetter", 1, 1, &item))
+			return NULL;
+	} else 
+		item = args;
+
+	/* create itemgetterobject structure */
+	ig = PyObject_GC_New(itemgetterobject, &itemgetter_type);
+	if (ig == NULL) 
+		return NULL;	
+	
+	Py_INCREF(item);
+	ig->item = item;
+	ig->nitems = nitems;
+
+	PyObject_GC_Track(ig);
+	return (PyObject *)ig;
+}
+
+static void
+itemgetter_dealloc(itemgetterobject *ig)
+{
+	PyObject_GC_UnTrack(ig);
+	Py_XDECREF(ig->item);
+	PyObject_GC_Del(ig);
+}
+
+static int
+itemgetter_traverse(itemgetterobject *ig, visitproc visit, void *arg)
+{
+	Py_VISIT(ig->item);
+	return 0;
+}
+
+static PyObject *
+itemgetter_call(itemgetterobject *ig, PyObject *args, PyObject *kw)
+{
+	PyObject *obj, *result;
+	Py_ssize_t i, nitems=ig->nitems;
+
+	if (!PyArg_UnpackTuple(args, "itemgetter", 1, 1, &obj))
+		return NULL;
+	if (nitems == 1)
+		return PyObject_GetItem(obj, ig->item);
+
+	assert(PyTuple_Check(ig->item));
+	assert(PyTuple_GET_SIZE(ig->item) == nitems);
+
+	result = PyTuple_New(nitems);
+	if (result == NULL)
+		return NULL;
+
+	for (i=0 ; i < nitems ; i++) {
+		PyObject *item, *val;
+		item = PyTuple_GET_ITEM(ig->item, i);
+		val = PyObject_GetItem(obj, item);
+		if (val == NULL) {
+			Py_DECREF(result);
+			return NULL;
+		}
+		PyTuple_SET_ITEM(result, i, val);
+	}
+	return result;
+}
+
+PyDoc_STRVAR(itemgetter_doc,
+"itemgetter(item, ...) --> itemgetter object\n\
+\n\
+Return a callable object that fetches the given item(s) from its operand.\n\
+After, f=itemgetter(2), the call f(r) returns r[2].\n\
+After, g=itemgetter(2,5,3), the call g(r) returns (r[2], r[5], r[3])");
+
+static PyTypeObject itemgetter_type = {
+	PyObject_HEAD_INIT(NULL)
+	0,				/* ob_size */
+	"operator.itemgetter",		/* tp_name */
+	sizeof(itemgetterobject),	/* tp_basicsize */
+	0,				/* tp_itemsize */
+	/* methods */
+	(destructor)itemgetter_dealloc,	/* tp_dealloc */
+	0,				/* tp_print */
+	0,				/* tp_getattr */
+	0,				/* tp_setattr */
+	0,				/* tp_compare */
+	0,				/* tp_repr */
+	0,				/* tp_as_number */
+	0,				/* tp_as_sequence */
+	0,				/* tp_as_mapping */
+	0,				/* tp_hash */
+	(ternaryfunc)itemgetter_call,	/* tp_call */
+	0,				/* tp_str */
+	PyObject_GenericGetAttr,	/* tp_getattro */
+	0,				/* tp_setattro */
+	0,				/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,	/* tp_flags */
+	itemgetter_doc,			/* tp_doc */
+	(traverseproc)itemgetter_traverse,	/* tp_traverse */
+	0,				/* tp_clear */
+	0,				/* tp_richcompare */
+	0,				/* tp_weaklistoffset */
+	0,				/* tp_iter */
+	0,				/* tp_iternext */
+	0,				/* tp_methods */
+	0,				/* tp_members */
+	0,				/* tp_getset */
+	0,				/* tp_base */
+	0,				/* tp_dict */
+	0,				/* tp_descr_get */
+	0,				/* tp_descr_set */
+	0,				/* tp_dictoffset */
+	0,				/* tp_init */
+	0,				/* tp_alloc */
+	itemgetter_new,			/* tp_new */
+	0,				/* tp_free */
+};
+
+
+/* attrgetter object **********************************************************/
+
+typedef struct {
+	PyObject_HEAD
+	Py_ssize_t nattrs;
+	PyObject *attr;
+} attrgetterobject;
+
+static PyTypeObject attrgetter_type;
+
+static PyObject *
+attrgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	attrgetterobject *ag;
+	PyObject *attr;
+	Py_ssize_t nattrs;
+
+	if (!_PyArg_NoKeywords("attrgetter()", kwds))
+		return NULL;
+
+	nattrs = PyTuple_GET_SIZE(args);
+	if (nattrs <= 1) {
+		if (!PyArg_UnpackTuple(args, "attrgetter", 1, 1, &attr))
+			return NULL;
+	} else 
+		attr = args;
+
+	/* create attrgetterobject structure */
+	ag = PyObject_GC_New(attrgetterobject, &attrgetter_type);
+	if (ag == NULL) 
+		return NULL;	
+	
+	Py_INCREF(attr);
+	ag->attr = attr;
+	ag->nattrs = nattrs;
+
+	PyObject_GC_Track(ag);
+	return (PyObject *)ag;
+}
+
+static void
+attrgetter_dealloc(attrgetterobject *ag)
+{
+	PyObject_GC_UnTrack(ag);
+	Py_XDECREF(ag->attr);
+	PyObject_GC_Del(ag);
+}
+
+static int
+attrgetter_traverse(attrgetterobject *ag, visitproc visit, void *arg)
+{
+	Py_VISIT(ag->attr);
+	return 0;
+}
+
+static PyObject *
+attrgetter_call(attrgetterobject *ag, PyObject *args, PyObject *kw)
+{
+	PyObject *obj, *result;
+	Py_ssize_t i, nattrs=ag->nattrs;
+
+	if (!PyArg_UnpackTuple(args, "attrgetter", 1, 1, &obj))
+		return NULL;
+	if (ag->nattrs == 1)
+		return PyObject_GetAttr(obj, ag->attr);
+
+	assert(PyTuple_Check(ag->attr));
+	assert(PyTuple_GET_SIZE(ag->attr) == nattrs);
+
+	result = PyTuple_New(nattrs);
+	if (result == NULL)
+		return NULL;
+
+	for (i=0 ; i < nattrs ; i++) {
+		PyObject *attr, *val;
+		attr = PyTuple_GET_ITEM(ag->attr, i);
+		val = PyObject_GetAttr(obj, attr);
+		if (val == NULL) {
+			Py_DECREF(result);
+			return NULL;
+		}
+		PyTuple_SET_ITEM(result, i, val);
+	}
+	return result;
+}
+
+PyDoc_STRVAR(attrgetter_doc,
+"attrgetter(attr, ...) --> attrgetter object\n\
+\n\
+Return a callable object that fetches the given attribute(s) from its operand.\n\
+After, f=attrgetter('name'), the call f(r) returns r.name.\n\
+After, g=attrgetter('name', 'date'), the call g(r) returns (r.name, r.date).");
+
+static PyTypeObject attrgetter_type = {
+	PyObject_HEAD_INIT(NULL)
+	0,				/* ob_size */
+	"operator.attrgetter",		/* tp_name */
+	sizeof(attrgetterobject),	/* tp_basicsize */
+	0,				/* tp_itemsize */
+	/* methods */
+	(destructor)attrgetter_dealloc,	/* tp_dealloc */
+	0,				/* tp_print */
+	0,				/* tp_getattr */
+	0,				/* tp_setattr */
+	0,				/* tp_compare */
+	0,				/* tp_repr */
+	0,				/* tp_as_number */
+	0,				/* tp_as_sequence */
+	0,				/* tp_as_mapping */
+	0,				/* tp_hash */
+	(ternaryfunc)attrgetter_call,	/* tp_call */
+	0,				/* tp_str */
+	PyObject_GenericGetAttr,	/* tp_getattro */
+	0,				/* tp_setattro */
+	0,				/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,	/* tp_flags */
+	attrgetter_doc,			/* tp_doc */
+	(traverseproc)attrgetter_traverse,	/* tp_traverse */
+	0,				/* tp_clear */
+	0,				/* tp_richcompare */
+	0,				/* tp_weaklistoffset */
+	0,				/* tp_iter */
+	0,				/* tp_iternext */
+	0,				/* tp_methods */
+	0,				/* tp_members */
+	0,				/* tp_getset */
+	0,				/* tp_base */
+	0,				/* tp_dict */
+	0,				/* tp_descr_get */
+	0,				/* tp_descr_set */
+	0,				/* tp_dictoffset */
+	0,				/* tp_init */
+	0,				/* tp_alloc */
+	attrgetter_new,			/* tp_new */
+	0,				/* tp_free */
+};
+/* Initialization function for the module (*must* be called initoperator) */
+
+PyMODINIT_FUNC
+initoperator(void)
+{
+	PyObject *m;
+        
+	/* Create the module and add the functions */
+        m = Py_InitModule4("operator", operator_methods, operator_doc,
+		       (PyObject*)NULL, PYTHON_API_VERSION);
+	if (m == NULL)
+		return;
+
+	if (PyType_Ready(&itemgetter_type) < 0)
+		return;
+	Py_INCREF(&itemgetter_type);
+	PyModule_AddObject(m, "itemgetter", (PyObject *)&itemgetter_type);
+
+	if (PyType_Ready(&attrgetter_type) < 0)
+		return;
+	Py_INCREF(&attrgetter_type);
+	PyModule_AddObject(m, "attrgetter", (PyObject *)&attrgetter_type);
+}

Added: vendor/Python/current/Modules/ossaudiodev.c
===================================================================
--- vendor/Python/current/Modules/ossaudiodev.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/ossaudiodev.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1138 @@
+/*
+ * ossaudiodev -- Python interface to the OSS (Open Sound System) API.
+ *                This is the standard audio API for Linux and some
+ *                flavours of BSD [XXX which ones?]; it is also available
+ *                for a wide range of commercial Unices.
+ *
+ * Originally written by Peter Bosch, March 2000, as linuxaudiodev.
+ *
+ * Renamed to ossaudiodev and rearranged/revised/hacked up
+ * by Greg Ward <gward at python.net>, November 2002.
+ * Mixer interface by Nicholas FitzRoy-Dale <wzdd at lardcave.net>, Dec 2002.
+ *
+ * (c) 2000 Peter Bosch.  All Rights Reserved.
+ * (c) 2002 Gregory P. Ward.  All Rights Reserved.
+ * (c) 2002 Python Software Foundation.  All Rights Reserved.
+ *
+ * XXX need a license statement
+ *
+ * $Id: ossaudiodev.c 52137 2006-10-04 10:23:57Z armin.rigo $
+ */
+
+#include "Python.h"
+#include "structmember.h"
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#else
+#define O_RDONLY 00
+#define O_WRONLY 01
+#endif
+
+#include <sys/ioctl.h>
+#include <sys/soundcard.h>
+
+#if defined(linux)
+
+#ifndef HAVE_STDINT_H
+typedef unsigned long uint32_t;
+#endif
+
+#elif defined(__FreeBSD__)
+
+# ifndef SNDCTL_DSP_CHANNELS
+#  define SNDCTL_DSP_CHANNELS SOUND_PCM_WRITE_CHANNELS
+# endif
+
+#endif
+
+typedef struct {
+    PyObject_HEAD
+    char    *devicename;              /* name of the device file */
+    int      fd;                      /* file descriptor */
+    int      mode;                    /* file mode (O_RDONLY, etc.) */
+    int      icount;                  /* input count */
+    int      ocount;                  /* output count */
+    uint32_t afmts;                   /* audio formats supported by hardware */
+} oss_audio_t;
+
+typedef struct {
+    PyObject_HEAD
+    int      fd;                      /* The open mixer device */
+} oss_mixer_t;
+
+
+static PyTypeObject OSSAudioType;
+static PyTypeObject OSSMixerType;
+
+static PyObject *OSSAudioError;
+
+
+/* ----------------------------------------------------------------------
+ * DSP object initialization/deallocation
+ */
+
+static oss_audio_t *
+newossobject(PyObject *arg)
+{
+    oss_audio_t *self;
+    int fd, afmts, imode;
+    char *devicename = NULL;
+    char *mode = NULL;
+
+    /* Two ways to call open():
+         open(device, mode) (for consistency with builtin open())
+         open(mode)         (for backwards compatibility)
+       because the *first* argument is optional, parsing args is
+       a wee bit tricky. */
+    if (!PyArg_ParseTuple(arg, "s|s:open", &devicename, &mode))
+       return NULL;
+    if (mode == NULL) {                 /* only one arg supplied */
+       mode = devicename;
+       devicename = NULL;
+    }
+
+    if (strcmp(mode, "r") == 0)
+        imode = O_RDONLY;
+    else if (strcmp(mode, "w") == 0)
+        imode = O_WRONLY;
+    else if (strcmp(mode, "rw") == 0)
+        imode = O_RDWR;
+    else {
+        PyErr_SetString(OSSAudioError, "mode must be 'r', 'w', or 'rw'");
+        return NULL;
+    }
+
+    /* Open the correct device: either the 'device' argument,
+       or the AUDIODEV environment variable, or "/dev/dsp". */
+    if (devicename == NULL) {              /* called with one arg */
+       devicename = getenv("AUDIODEV");
+       if (devicename == NULL)             /* $AUDIODEV not set */
+          devicename = "/dev/dsp";
+    }
+
+    /* Open with O_NONBLOCK to avoid hanging on devices that only allow
+       one open at a time.  This does *not* affect later I/O; OSS
+       provides a special ioctl() for non-blocking read/write, which is
+       exposed via oss_nonblock() below. */
+    if ((fd = open(devicename, imode|O_NONBLOCK)) == -1) {
+        PyErr_SetFromErrnoWithFilename(PyExc_IOError, devicename);
+        return NULL;
+    }
+
+    /* And (try to) put it back in blocking mode so we get the
+       expected write() semantics. */
+    if (fcntl(fd, F_SETFL, 0) == -1) {
+        close(fd);
+        PyErr_SetFromErrnoWithFilename(PyExc_IOError, devicename);
+        return NULL;
+    }
+
+    if (ioctl(fd, SNDCTL_DSP_GETFMTS, &afmts) == -1) {
+        PyErr_SetFromErrnoWithFilename(PyExc_IOError, devicename);
+        return NULL;
+    }
+    /* Create and initialize the object */
+    if ((self = PyObject_New(oss_audio_t, &OSSAudioType)) == NULL) {
+        close(fd);
+        return NULL;
+    }
+    self->devicename = devicename;
+    self->fd = fd;
+    self->mode = imode;
+    self->icount = self->ocount = 0;
+    self->afmts  = afmts;
+    return self;
+}
+
+static void
+oss_dealloc(oss_audio_t *self)
+{
+    /* if already closed, don't reclose it */
+    if (self->fd != -1)
+        close(self->fd);
+    PyObject_Del(self);
+}
+
+
+/* ----------------------------------------------------------------------
+ * Mixer object initialization/deallocation
+ */
+
+static oss_mixer_t *
+newossmixerobject(PyObject *arg)
+{
+    char *devicename = NULL;
+    int fd;
+    oss_mixer_t *self;
+
+    if (!PyArg_ParseTuple(arg, "|s", &devicename)) {
+        return NULL;
+    }
+
+    if (devicename == NULL) {
+        devicename = getenv("MIXERDEV");
+        if (devicename == NULL)            /* MIXERDEV not set */
+            devicename = "/dev/mixer";
+    }
+
+    if ((fd = open(devicename, O_RDWR)) == -1) {
+        PyErr_SetFromErrnoWithFilename(PyExc_IOError, devicename);
+        return NULL;
+    }
+
+    if ((self = PyObject_New(oss_mixer_t, &OSSMixerType)) == NULL) {
+        close(fd);
+        return NULL;
+    }
+
+    self->fd = fd;
+
+    return self;
+}
+
+static void
+oss_mixer_dealloc(oss_mixer_t *self)
+{
+    /* if already closed, don't reclose it */
+    if (self->fd != -1)
+        close(self->fd);
+    PyObject_Del(self);
+}
+
+
+/* Methods to wrap the OSS ioctls.  The calling convention is pretty
+   simple:
+     nonblock()        -> ioctl(fd, SNDCTL_DSP_NONBLOCK)
+     fmt = setfmt(fmt) -> ioctl(fd, SNDCTL_DSP_SETFMT, &fmt)
+     etc.
+*/
+
+
+/* ----------------------------------------------------------------------
+ * Helper functions
+ */
+
+/* _do_ioctl_1() is a private helper function used for the OSS ioctls --
+   SNDCTL_DSP_{SETFMT,CHANNELS,SPEED} -- that that are called from C
+   like this:
+     ioctl(fd, SNDCTL_DSP_cmd, &arg)
+
+   where arg is the value to set, and on return the driver sets arg to
+   the value that was actually set.  Mapping this to Python is obvious:
+     arg = dsp.xxx(arg)
+*/
+static PyObject *
+_do_ioctl_1(int fd, PyObject *args, char *fname, int cmd)
+{
+    char argfmt[33] = "i:";
+    int arg;
+
+    assert(strlen(fname) <= 30);
+    strcat(argfmt, fname);
+    if (!PyArg_ParseTuple(args, argfmt, &arg))
+        return NULL;
+
+    if (ioctl(fd, cmd, &arg) == -1)
+        return PyErr_SetFromErrno(PyExc_IOError);
+    return PyInt_FromLong(arg);
+}
+
+
+/* _do_ioctl_1_internal() is a wrapper for ioctls that take no inputs
+   but return an output -- ie. we need to pass a pointer to a local C
+   variable so the driver can write its output there, but from Python
+   all we see is the return value.  For example,
+   SOUND_MIXER_READ_DEVMASK returns a bitmask of available mixer
+   devices, but does not use the value of the parameter passed-in in any
+   way.
+*/
+static PyObject *
+_do_ioctl_1_internal(int fd, PyObject *args, char *fname, int cmd)
+{
+    char argfmt[32] = ":";
+    int arg = 0;
+
+    assert(strlen(fname) <= 30);
+    strcat(argfmt, fname);
+    if (!PyArg_ParseTuple(args, argfmt, &arg))
+        return NULL;
+
+    if (ioctl(fd, cmd, &arg) == -1)
+        return PyErr_SetFromErrno(PyExc_IOError);
+    return PyInt_FromLong(arg);
+}
+
+
+
+/* _do_ioctl_0() is a private helper for the no-argument ioctls:
+   SNDCTL_DSP_{SYNC,RESET,POST}. */
+static PyObject *
+_do_ioctl_0(int fd, PyObject *args, char *fname, int cmd)
+{
+    char argfmt[32] = ":";
+    int rv;
+
+    assert(strlen(fname) <= 30);
+    strcat(argfmt, fname);
+    if (!PyArg_ParseTuple(args, argfmt))
+        return NULL;
+
+    /* According to hannu at opensound.com, all three of the ioctls that
+       use this function can block, so release the GIL.  This is
+       especially important for SYNC, which can block for several
+       seconds. */
+    Py_BEGIN_ALLOW_THREADS
+    rv = ioctl(fd, cmd, 0);
+    Py_END_ALLOW_THREADS
+
+    if (rv == -1)
+        return PyErr_SetFromErrno(PyExc_IOError);
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+
+/* ----------------------------------------------------------------------
+ * Methods of DSP objects (OSSAudioType)
+ */
+
+static PyObject *
+oss_nonblock(oss_audio_t *self, PyObject *unused)
+{
+    /* Hmmm: it doesn't appear to be possible to return to blocking
+       mode once we're in non-blocking mode! */
+    if (ioctl(self->fd, SNDCTL_DSP_NONBLOCK, NULL) == -1)
+        return PyErr_SetFromErrno(PyExc_IOError);
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject *
+oss_setfmt(oss_audio_t *self, PyObject *args)
+{
+    return _do_ioctl_1(self->fd, args, "setfmt", SNDCTL_DSP_SETFMT);
+}
+
+static PyObject *
+oss_getfmts(oss_audio_t *self, PyObject *unused)
+{
+    int mask;
+    if (ioctl(self->fd, SNDCTL_DSP_GETFMTS, &mask) == -1)
+        return PyErr_SetFromErrno(PyExc_IOError);
+    return PyInt_FromLong(mask);
+}
+
+static PyObject *
+oss_channels(oss_audio_t *self, PyObject *args)
+{
+    return _do_ioctl_1(self->fd, args, "channels", SNDCTL_DSP_CHANNELS);
+}
+
+static PyObject *
+oss_speed(oss_audio_t *self, PyObject *args)
+{
+    return _do_ioctl_1(self->fd, args, "speed", SNDCTL_DSP_SPEED);
+}
+
+static PyObject *
+oss_sync(oss_audio_t *self, PyObject *args)
+{
+    return _do_ioctl_0(self->fd, args, "sync", SNDCTL_DSP_SYNC);
+}
+
+static PyObject *
+oss_reset(oss_audio_t *self, PyObject *args)
+{
+    return _do_ioctl_0(self->fd, args, "reset", SNDCTL_DSP_RESET);
+}
+
+static PyObject *
+oss_post(oss_audio_t *self, PyObject *args)
+{
+    return _do_ioctl_0(self->fd, args, "post", SNDCTL_DSP_POST);
+}
+
+
+/* Regular file methods: read(), write(), close(), etc. as well
+   as one convenience method, writeall(). */
+
+static PyObject *
+oss_read(oss_audio_t *self, PyObject *args)
+{
+    int size, count;
+    char *cp;
+    PyObject *rv;
+
+    if (!PyArg_ParseTuple(args, "i:read", &size))
+        return NULL;
+    rv = PyString_FromStringAndSize(NULL, size);
+    if (rv == NULL)
+        return NULL;
+    cp = PyString_AS_STRING(rv);
+
+    Py_BEGIN_ALLOW_THREADS
+    count = read(self->fd, cp, size);
+    Py_END_ALLOW_THREADS
+
+    if (count < 0) {
+        PyErr_SetFromErrno(PyExc_IOError);
+        Py_DECREF(rv);
+        return NULL;
+    }
+    self->icount += count;
+    _PyString_Resize(&rv, count);
+    return rv;
+}
+
+static PyObject *
+oss_write(oss_audio_t *self, PyObject *args)
+{
+    char *cp;
+    int rv, size;
+
+    if (!PyArg_ParseTuple(args, "s#:write", &cp, &size)) {
+        return NULL;
+    }
+
+    Py_BEGIN_ALLOW_THREADS
+    rv = write(self->fd, cp, size);
+    Py_END_ALLOW_THREADS
+
+    if (rv == -1) {
+        return PyErr_SetFromErrno(PyExc_IOError);
+    } else {
+        self->ocount += rv;
+    }
+    return PyInt_FromLong(rv);
+}
+
+static PyObject *
+oss_writeall(oss_audio_t *self, PyObject *args)
+{
+    char *cp;
+    int rv, size;
+    fd_set write_set_fds;
+    int select_rv;
+
+    /* NB. writeall() is only useful in non-blocking mode: according to
+       Guenter Geiger <geiger at xdv.org> on the linux-audio-dev list
+       (http://eca.cx/lad/2002/11/0380.html), OSS guarantees that
+       write() in blocking mode consumes the whole buffer.  In blocking
+       mode, the behaviour of write() and writeall() from Python is
+       indistinguishable. */
+
+    if (!PyArg_ParseTuple(args, "s#:write", &cp, &size))
+        return NULL;
+
+    /* use select to wait for audio device to be available */
+    FD_ZERO(&write_set_fds);
+    FD_SET(self->fd, &write_set_fds);
+
+    while (size > 0) {
+        Py_BEGIN_ALLOW_THREADS
+        select_rv = select(self->fd+1, NULL, &write_set_fds, NULL, NULL);
+        Py_END_ALLOW_THREADS
+        assert(select_rv != 0);         /* no timeout, can't expire */
+        if (select_rv == -1)
+            return PyErr_SetFromErrno(PyExc_IOError);
+
+        Py_BEGIN_ALLOW_THREADS
+        rv = write(self->fd, cp, size);
+        Py_END_ALLOW_THREADS
+        if (rv == -1) {
+            if (errno == EAGAIN) {      /* buffer is full, try again */
+                errno = 0;
+                continue;
+            } else                      /* it's a real error */
+                return PyErr_SetFromErrno(PyExc_IOError);
+        } else {                        /* wrote rv bytes */
+            self->ocount += rv;
+            size -= rv;
+            cp += rv;
+        }
+    }
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject *
+oss_close(oss_audio_t *self, PyObject *unused)
+{
+    if (self->fd >= 0) {
+        Py_BEGIN_ALLOW_THREADS
+        close(self->fd);
+        Py_END_ALLOW_THREADS
+        self->fd = -1;
+    }
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject *
+oss_fileno(oss_audio_t *self, PyObject *unused)
+{
+    return PyInt_FromLong(self->fd);
+}
+
+
+/* Convenience methods: these generally wrap a couple of ioctls into one
+   common task. */
+
+static PyObject *
+oss_setparameters(oss_audio_t *self, PyObject *args)
+{
+    int wanted_fmt, wanted_channels, wanted_rate, strict=0;
+    int fmt, channels, rate;
+    PyObject * rv;                    /* return tuple (fmt, channels, rate) */
+
+    if (!PyArg_ParseTuple(args, "iii|i:setparameters",
+                          &wanted_fmt, &wanted_channels, &wanted_rate,
+                          &strict))
+        return NULL;
+
+    fmt = wanted_fmt;
+    if (ioctl(self->fd, SNDCTL_DSP_SETFMT, &fmt) == -1) {
+        return PyErr_SetFromErrno(PyExc_IOError);
+    }
+    if (strict && fmt != wanted_fmt) {
+        return PyErr_Format
+            (OSSAudioError,
+             "unable to set requested format (wanted %d, got %d)",
+             wanted_fmt, fmt);
+    }
+
+    channels = wanted_channels;
+    if (ioctl(self->fd, SNDCTL_DSP_CHANNELS, &channels) == -1) {
+        return PyErr_SetFromErrno(PyExc_IOError);
+    }
+    if (strict && channels != wanted_channels) {
+        return PyErr_Format
+            (OSSAudioError,
+             "unable to set requested channels (wanted %d, got %d)",
+             wanted_channels, channels);
+    }
+
+    rate = wanted_rate;
+    if (ioctl(self->fd, SNDCTL_DSP_SPEED, &rate) == -1) {
+        return PyErr_SetFromErrno(PyExc_IOError);
+    }
+    if (strict && rate != wanted_rate) {
+        return PyErr_Format
+            (OSSAudioError,
+             "unable to set requested rate (wanted %d, got %d)",
+             wanted_rate, rate);
+    }
+
+    /* Construct the return value: a (fmt, channels, rate) tuple that
+       tells what the audio hardware was actually set to. */
+    rv = PyTuple_New(3);
+    if (rv == NULL)
+        return NULL;
+    PyTuple_SET_ITEM(rv, 0, PyInt_FromLong(fmt));
+    PyTuple_SET_ITEM(rv, 1, PyInt_FromLong(channels));
+    PyTuple_SET_ITEM(rv, 2, PyInt_FromLong(rate));
+    return rv;
+}
+
+static int
+_ssize(oss_audio_t *self, int *nchannels, int *ssize)
+{
+    int fmt;
+
+    fmt = 0;
+    if (ioctl(self->fd, SNDCTL_DSP_SETFMT, &fmt) < 0)
+        return -errno;
+
+    switch (fmt) {
+    case AFMT_MU_LAW:
+    case AFMT_A_LAW:
+    case AFMT_U8:
+    case AFMT_S8:
+        *ssize = 1;                     /* 8 bit formats: 1 byte */
+        break;
+    case AFMT_S16_LE:
+    case AFMT_S16_BE:
+    case AFMT_U16_LE:
+    case AFMT_U16_BE:
+        *ssize = 2;                     /* 16 bit formats: 2 byte */
+        break;
+    case AFMT_MPEG:
+    case AFMT_IMA_ADPCM:
+    default:
+        return -EOPNOTSUPP;
+    }
+    if (ioctl(self->fd, SNDCTL_DSP_CHANNELS, nchannels) < 0)
+        return -errno;
+    return 0;
+}
+
+
+/* bufsize returns the size of the hardware audio buffer in number
+   of samples */
+static PyObject *
+oss_bufsize(oss_audio_t *self, PyObject *unused)
+{
+    audio_buf_info ai;
+    int nchannels=0, ssize=0;
+
+    if (_ssize(self, &nchannels, &ssize) < 0 || !nchannels || !ssize) {
+        PyErr_SetFromErrno(PyExc_IOError);
+        return NULL;
+    }
+    if (ioctl(self->fd, SNDCTL_DSP_GETOSPACE, &ai) < 0) {
+        PyErr_SetFromErrno(PyExc_IOError);
+        return NULL;
+    }
+    return PyInt_FromLong((ai.fragstotal * ai.fragsize) / (nchannels * ssize));
+}
+
+/* obufcount returns the number of samples that are available in the
+   hardware for playing */
+static PyObject *
+oss_obufcount(oss_audio_t *self, PyObject *unused)
+{
+    audio_buf_info ai;
+    int nchannels=0, ssize=0;
+
+    if (_ssize(self, &nchannels, &ssize) < 0 || !nchannels || !ssize) {
+        PyErr_SetFromErrno(PyExc_IOError);
+        return NULL;
+    }
+    if (ioctl(self->fd, SNDCTL_DSP_GETOSPACE, &ai) < 0) {
+        PyErr_SetFromErrno(PyExc_IOError);
+        return NULL;
+    }
+    return PyInt_FromLong((ai.fragstotal * ai.fragsize - ai.bytes) /
+                          (ssize * nchannels));
+}
+
+/* obufcount returns the number of samples that can be played without
+   blocking */
+static PyObject *
+oss_obuffree(oss_audio_t *self, PyObject *unused)
+{
+    audio_buf_info ai;
+    int nchannels=0, ssize=0;
+
+    if (_ssize(self, &nchannels, &ssize) < 0 || !nchannels || !ssize) {
+        PyErr_SetFromErrno(PyExc_IOError);
+        return NULL;
+    }
+    if (ioctl(self->fd, SNDCTL_DSP_GETOSPACE, &ai) < 0) {
+        PyErr_SetFromErrno(PyExc_IOError);
+        return NULL;
+    }
+    return PyInt_FromLong(ai.bytes / (ssize * nchannels));
+}
+
+static PyObject *
+oss_getptr(oss_audio_t *self, PyObject *unused)
+{
+    count_info info;
+    int req;
+
+    if (self->mode == O_RDONLY)
+        req = SNDCTL_DSP_GETIPTR;
+    else
+        req = SNDCTL_DSP_GETOPTR;
+    if (ioctl(self->fd, req, &info) == -1) {
+        PyErr_SetFromErrno(PyExc_IOError);
+        return NULL;
+    }
+    return Py_BuildValue("iii", info.bytes, info.blocks, info.ptr);
+}
+
+
+/* ----------------------------------------------------------------------
+ * Methods of mixer objects (OSSMixerType)
+ */
+
+static PyObject *
+oss_mixer_close(oss_mixer_t *self, PyObject *unused)
+{
+    if (self->fd >= 0) {
+        close(self->fd);
+        self->fd = -1;
+    }
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject *
+oss_mixer_fileno(oss_mixer_t *self, PyObject *unused)
+{
+    return PyInt_FromLong(self->fd);
+}
+
+/* Simple mixer interface methods */
+
+static PyObject *
+oss_mixer_controls(oss_mixer_t *self, PyObject *args)
+{
+    return _do_ioctl_1_internal(self->fd, args, "controls",
+        SOUND_MIXER_READ_DEVMASK);
+}
+
+static PyObject *
+oss_mixer_stereocontrols(oss_mixer_t *self, PyObject *args)
+{
+    return _do_ioctl_1_internal(self->fd, args, "stereocontrols",
+        SOUND_MIXER_READ_STEREODEVS);
+}
+
+static PyObject *
+oss_mixer_reccontrols(oss_mixer_t *self, PyObject *args)
+{
+    return _do_ioctl_1_internal(self->fd, args, "reccontrols",
+        SOUND_MIXER_READ_RECMASK);
+}
+
+static PyObject *
+oss_mixer_get(oss_mixer_t *self, PyObject *args)
+{
+    int channel, volume;
+
+    /* Can't use _do_ioctl_1 because of encoded arg thingy. */
+    if (!PyArg_ParseTuple(args, "i:get", &channel))
+        return NULL;
+
+    if (channel < 0 || channel > SOUND_MIXER_NRDEVICES) {
+        PyErr_SetString(OSSAudioError, "Invalid mixer channel specified.");
+        return NULL;
+    }
+
+    if (ioctl(self->fd, MIXER_READ(channel), &volume) == -1)
+        return PyErr_SetFromErrno(PyExc_IOError);
+
+    return Py_BuildValue("(ii)", volume & 0xff, (volume & 0xff00) >> 8);
+}
+
+static PyObject *
+oss_mixer_set(oss_mixer_t *self, PyObject *args)
+{
+    int channel, volume, leftVol, rightVol;
+
+    /* Can't use _do_ioctl_1 because of encoded arg thingy. */
+    if (!PyArg_ParseTuple(args, "i(ii):set", &channel, &leftVol, &rightVol))
+        return NULL;
+
+    if (channel < 0 || channel > SOUND_MIXER_NRDEVICES) {
+        PyErr_SetString(OSSAudioError, "Invalid mixer channel specified.");
+        return NULL;
+    }
+
+    if (leftVol < 0 || rightVol < 0 || leftVol > 100 || rightVol > 100) {
+        PyErr_SetString(OSSAudioError, "Volumes must be between 0 and 100.");
+        return NULL;
+    }
+
+    volume = (rightVol << 8) | leftVol;
+
+    if (ioctl(self->fd, MIXER_WRITE(channel), &volume) == -1)
+        return PyErr_SetFromErrno(PyExc_IOError);
+
+    return Py_BuildValue("(ii)", volume & 0xff, (volume & 0xff00) >> 8);
+}
+
+static PyObject *
+oss_mixer_get_recsrc(oss_mixer_t *self, PyObject *args)
+{
+    return _do_ioctl_1_internal(self->fd, args, "get_recsrc",
+        SOUND_MIXER_READ_RECSRC);
+}
+
+static PyObject *
+oss_mixer_set_recsrc(oss_mixer_t *self, PyObject *args)
+{
+    return _do_ioctl_1(self->fd, args, "set_recsrc",
+        SOUND_MIXER_WRITE_RECSRC);
+}
+
+
+/* ----------------------------------------------------------------------
+ * Method tables and other bureaucracy
+ */
+
+static PyMethodDef oss_methods[] = {
+    /* Regular file methods */
+    { "read",           (PyCFunction)oss_read, METH_VARARGS },
+    { "write",          (PyCFunction)oss_write, METH_VARARGS },
+    { "writeall",       (PyCFunction)oss_writeall, METH_VARARGS },
+    { "close",          (PyCFunction)oss_close, METH_NOARGS },
+    { "fileno",         (PyCFunction)oss_fileno, METH_NOARGS },
+
+    /* Simple ioctl wrappers */
+    { "nonblock",       (PyCFunction)oss_nonblock, METH_NOARGS },
+    { "setfmt",         (PyCFunction)oss_setfmt, METH_VARARGS },
+    { "getfmts",        (PyCFunction)oss_getfmts, METH_NOARGS },
+    { "channels",       (PyCFunction)oss_channels, METH_VARARGS },
+    { "speed",          (PyCFunction)oss_speed, METH_VARARGS },
+    { "sync",           (PyCFunction)oss_sync, METH_VARARGS },
+    { "reset",          (PyCFunction)oss_reset, METH_VARARGS },
+    { "post",           (PyCFunction)oss_post, METH_VARARGS },
+
+    /* Convenience methods -- wrap a couple of ioctls together */
+    { "setparameters",  (PyCFunction)oss_setparameters, METH_VARARGS },
+    { "bufsize",        (PyCFunction)oss_bufsize, METH_NOARGS },
+    { "obufcount",      (PyCFunction)oss_obufcount, METH_NOARGS },
+    { "obuffree",       (PyCFunction)oss_obuffree, METH_NOARGS },
+    { "getptr",         (PyCFunction)oss_getptr, METH_NOARGS },
+
+    /* Aliases for backwards compatibility */
+    { "flush",          (PyCFunction)oss_sync, METH_VARARGS },
+
+    { NULL,             NULL}           /* sentinel */
+};
+
+static PyMethodDef oss_mixer_methods[] = {
+    /* Regular file method - OSS mixers are ioctl-only interface */
+    { "close",          (PyCFunction)oss_mixer_close, METH_NOARGS },
+    { "fileno",         (PyCFunction)oss_mixer_fileno, METH_NOARGS },
+
+    /* Simple ioctl wrappers */
+    { "controls",       (PyCFunction)oss_mixer_controls, METH_VARARGS },
+    { "stereocontrols", (PyCFunction)oss_mixer_stereocontrols, METH_VARARGS},
+    { "reccontrols",    (PyCFunction)oss_mixer_reccontrols, METH_VARARGS},
+    { "get",            (PyCFunction)oss_mixer_get, METH_VARARGS },
+    { "set",            (PyCFunction)oss_mixer_set, METH_VARARGS },
+    { "get_recsrc",     (PyCFunction)oss_mixer_get_recsrc, METH_VARARGS },
+    { "set_recsrc",     (PyCFunction)oss_mixer_set_recsrc, METH_VARARGS },
+
+    { NULL,             NULL}
+};
+
+static PyObject *
+oss_getattr(oss_audio_t *self, char *name)
+{
+    PyObject * rval = NULL;
+    if (strcmp(name, "closed") == 0) {
+        rval = (self->fd == -1) ? Py_True : Py_False;
+        Py_INCREF(rval);
+    }
+    else if (strcmp(name, "name") == 0) {
+        rval = PyString_FromString(self->devicename);
+    }
+    else if (strcmp(name, "mode") == 0) {
+        /* No need for a "default" in this switch: from newossobject(),
+           self->mode can only be one of these three values. */
+        switch(self->mode) {
+            case O_RDONLY:
+                rval = PyString_FromString("r");
+                break;
+            case O_RDWR:
+                rval = PyString_FromString("rw");
+                break;
+            case O_WRONLY:
+                rval = PyString_FromString("w");
+                break;
+        }
+    }
+    else {
+        rval = Py_FindMethod(oss_methods, (PyObject *)self, name);
+    }
+    return rval;
+}
+
+static PyObject *
+oss_mixer_getattr(oss_mixer_t *self, char *name)
+{
+    return Py_FindMethod(oss_mixer_methods, (PyObject *)self, name);
+}
+
+static PyTypeObject OSSAudioType = {
+    PyObject_HEAD_INIT(&PyType_Type)
+    0,                          /*ob_size*/
+    "ossaudiodev.oss_audio_device", /*tp_name*/
+    sizeof(oss_audio_t),        /*tp_size*/
+    0,                          /*tp_itemsize*/
+    /* methods */
+    (destructor)oss_dealloc,    /*tp_dealloc*/
+    0,                          /*tp_print*/
+    (getattrfunc)oss_getattr,   /*tp_getattr*/
+    0,                          /*tp_setattr*/
+    0,                          /*tp_compare*/
+    0,                          /*tp_repr*/
+};
+
+static PyTypeObject OSSMixerType = {
+    PyObject_HEAD_INIT(&PyType_Type)
+    0,                              /*ob_size*/
+    "ossaudiodev.oss_mixer_device", /*tp_name*/
+    sizeof(oss_mixer_t),            /*tp_size*/
+    0,                              /*tp_itemsize*/
+    /* methods */
+    (destructor)oss_mixer_dealloc,  /*tp_dealloc*/
+    0,                              /*tp_print*/
+    (getattrfunc)oss_mixer_getattr, /*tp_getattr*/
+    0,                              /*tp_setattr*/
+    0,                              /*tp_compare*/
+    0,                              /*tp_repr*/
+};
+
+
+static PyObject *
+ossopen(PyObject *self, PyObject *args)
+{
+    return (PyObject *)newossobject(args);
+}
+
+static PyObject *
+ossopenmixer(PyObject *self, PyObject *args)
+{
+    return (PyObject *)newossmixerobject(args);
+}
+
+static PyMethodDef ossaudiodev_methods[] = {
+    { "open", ossopen, METH_VARARGS },
+    { "openmixer", ossopenmixer, METH_VARARGS },
+    { 0, 0 },
+};
+
+
+#define _EXPORT_INT(mod, name) \
+  if (PyModule_AddIntConstant(mod, #name, (long) (name)) == -1) return;
+
+
+static char *control_labels[] = SOUND_DEVICE_LABELS;
+static char *control_names[] = SOUND_DEVICE_NAMES;
+
+
+static int
+build_namelists (PyObject *module)
+{
+    PyObject *labels;
+    PyObject *names;
+    PyObject *s;
+    int num_controls;
+    int i;
+
+    num_controls = sizeof(control_labels) / sizeof(control_labels[0]);
+    assert(num_controls == sizeof(control_names) / sizeof(control_names[0]));
+
+    labels = PyList_New(num_controls);
+    names = PyList_New(num_controls);
+    if (labels == NULL || names == NULL)
+        goto error2;
+    for (i = 0; i < num_controls; i++) {
+        s = PyString_FromString(control_labels[i]);
+        if (s == NULL)
+            goto error2;
+        PyList_SET_ITEM(labels, i, s);
+
+        s = PyString_FromString(control_names[i]);
+        if (s == NULL)
+            goto error2;
+        PyList_SET_ITEM(names, i, s);
+    }
+
+    if (PyModule_AddObject(module, "control_labels", labels) == -1)
+        goto error2;
+    if (PyModule_AddObject(module, "control_names", names) == -1)
+        goto error1;
+
+    return 0;
+
+error2:
+    Py_XDECREF(labels);
+error1:
+    Py_XDECREF(names);
+    return -1;
+}
+
+
+void
+initossaudiodev(void)
+{
+    PyObject *m;
+
+    m = Py_InitModule("ossaudiodev", ossaudiodev_methods);
+    if (m == NULL)
+	return;
+
+    OSSAudioError = PyErr_NewException("ossaudiodev.OSSAudioError",
+				       NULL, NULL);
+    if (OSSAudioError) {
+        /* Each call to PyModule_AddObject decrefs it; compensate: */
+        Py_INCREF(OSSAudioError);
+        Py_INCREF(OSSAudioError);
+        PyModule_AddObject(m, "error", OSSAudioError);
+        PyModule_AddObject(m, "OSSAudioError", OSSAudioError);
+    }
+
+    /* Build 'control_labels' and 'control_names' lists and add them
+       to the module. */
+    if (build_namelists(m) == -1)       /* XXX what to do here? */
+        return;
+
+    /* Expose the audio format numbers -- essential! */
+    _EXPORT_INT(m, AFMT_QUERY);
+    _EXPORT_INT(m, AFMT_MU_LAW);
+    _EXPORT_INT(m, AFMT_A_LAW);
+    _EXPORT_INT(m, AFMT_IMA_ADPCM);
+    _EXPORT_INT(m, AFMT_U8);
+    _EXPORT_INT(m, AFMT_S16_LE);
+    _EXPORT_INT(m, AFMT_S16_BE);
+    _EXPORT_INT(m, AFMT_S8);
+    _EXPORT_INT(m, AFMT_U16_LE);
+    _EXPORT_INT(m, AFMT_U16_BE);
+    _EXPORT_INT(m, AFMT_MPEG);
+#ifdef AFMT_AC3
+    _EXPORT_INT(m, AFMT_AC3);
+#endif
+#ifdef AFMT_S16_NE
+    _EXPORT_INT(m, AFMT_S16_NE);
+#endif
+#ifdef AFMT_U16_NE
+    _EXPORT_INT(m, AFMT_U16_NE);
+#endif
+#ifdef AFMT_S32_LE
+    _EXPORT_INT(m, AFMT_S32_LE);
+#endif
+#ifdef AFMT_S32_BE
+    _EXPORT_INT(m, AFMT_S32_BE);
+#endif
+#ifdef AFMT_MPEG
+    _EXPORT_INT(m, AFMT_MPEG);
+#endif
+
+    /* Expose the sound mixer device numbers. */
+    _EXPORT_INT(m, SOUND_MIXER_NRDEVICES);
+    _EXPORT_INT(m, SOUND_MIXER_VOLUME);
+    _EXPORT_INT(m, SOUND_MIXER_BASS);
+    _EXPORT_INT(m, SOUND_MIXER_TREBLE);
+    _EXPORT_INT(m, SOUND_MIXER_SYNTH);
+    _EXPORT_INT(m, SOUND_MIXER_PCM);
+    _EXPORT_INT(m, SOUND_MIXER_SPEAKER);
+    _EXPORT_INT(m, SOUND_MIXER_LINE);
+    _EXPORT_INT(m, SOUND_MIXER_MIC);
+    _EXPORT_INT(m, SOUND_MIXER_CD);
+    _EXPORT_INT(m, SOUND_MIXER_IMIX);
+    _EXPORT_INT(m, SOUND_MIXER_ALTPCM);
+    _EXPORT_INT(m, SOUND_MIXER_RECLEV);
+    _EXPORT_INT(m, SOUND_MIXER_IGAIN);
+    _EXPORT_INT(m, SOUND_MIXER_OGAIN);
+    _EXPORT_INT(m, SOUND_MIXER_LINE1);
+    _EXPORT_INT(m, SOUND_MIXER_LINE2);
+    _EXPORT_INT(m, SOUND_MIXER_LINE3);
+#ifdef SOUND_MIXER_DIGITAL1
+    _EXPORT_INT(m, SOUND_MIXER_DIGITAL1);
+#endif
+#ifdef SOUND_MIXER_DIGITAL2
+    _EXPORT_INT(m, SOUND_MIXER_DIGITAL2);
+#endif
+#ifdef SOUND_MIXER_DIGITAL3
+    _EXPORT_INT(m, SOUND_MIXER_DIGITAL3);
+#endif
+#ifdef SOUND_MIXER_PHONEIN
+    _EXPORT_INT(m, SOUND_MIXER_PHONEIN);
+#endif
+#ifdef SOUND_MIXER_PHONEOUT
+    _EXPORT_INT(m, SOUND_MIXER_PHONEOUT);
+#endif
+#ifdef SOUND_MIXER_VIDEO
+    _EXPORT_INT(m, SOUND_MIXER_VIDEO);
+#endif
+#ifdef SOUND_MIXER_RADIO
+    _EXPORT_INT(m, SOUND_MIXER_RADIO);
+#endif
+#ifdef SOUND_MIXER_MONITOR
+    _EXPORT_INT(m, SOUND_MIXER_MONITOR);
+#endif
+
+    /* Expose all the ioctl numbers for masochists who like to do this
+       stuff directly. */
+    _EXPORT_INT(m, SNDCTL_COPR_HALT);
+    _EXPORT_INT(m, SNDCTL_COPR_LOAD);
+    _EXPORT_INT(m, SNDCTL_COPR_RCODE);
+    _EXPORT_INT(m, SNDCTL_COPR_RCVMSG);
+    _EXPORT_INT(m, SNDCTL_COPR_RDATA);
+    _EXPORT_INT(m, SNDCTL_COPR_RESET);
+    _EXPORT_INT(m, SNDCTL_COPR_RUN);
+    _EXPORT_INT(m, SNDCTL_COPR_SENDMSG);
+    _EXPORT_INT(m, SNDCTL_COPR_WCODE);
+    _EXPORT_INT(m, SNDCTL_COPR_WDATA);
+#ifdef SNDCTL_DSP_BIND_CHANNEL
+    _EXPORT_INT(m, SNDCTL_DSP_BIND_CHANNEL);
+#endif
+    _EXPORT_INT(m, SNDCTL_DSP_CHANNELS);
+    _EXPORT_INT(m, SNDCTL_DSP_GETBLKSIZE);
+    _EXPORT_INT(m, SNDCTL_DSP_GETCAPS);
+#ifdef SNDCTL_DSP_GETCHANNELMASK
+    _EXPORT_INT(m, SNDCTL_DSP_GETCHANNELMASK);
+#endif
+    _EXPORT_INT(m, SNDCTL_DSP_GETFMTS);
+    _EXPORT_INT(m, SNDCTL_DSP_GETIPTR);
+    _EXPORT_INT(m, SNDCTL_DSP_GETISPACE);
+#ifdef SNDCTL_DSP_GETODELAY
+    _EXPORT_INT(m, SNDCTL_DSP_GETODELAY);
+#endif
+    _EXPORT_INT(m, SNDCTL_DSP_GETOPTR);
+    _EXPORT_INT(m, SNDCTL_DSP_GETOSPACE);
+#ifdef SNDCTL_DSP_GETSPDIF
+    _EXPORT_INT(m, SNDCTL_DSP_GETSPDIF);
+#endif
+    _EXPORT_INT(m, SNDCTL_DSP_GETTRIGGER);
+    _EXPORT_INT(m, SNDCTL_DSP_MAPINBUF);
+    _EXPORT_INT(m, SNDCTL_DSP_MAPOUTBUF);
+    _EXPORT_INT(m, SNDCTL_DSP_NONBLOCK);
+    _EXPORT_INT(m, SNDCTL_DSP_POST);
+#ifdef SNDCTL_DSP_PROFILE
+    _EXPORT_INT(m, SNDCTL_DSP_PROFILE);
+#endif
+    _EXPORT_INT(m, SNDCTL_DSP_RESET);
+    _EXPORT_INT(m, SNDCTL_DSP_SAMPLESIZE);
+    _EXPORT_INT(m, SNDCTL_DSP_SETDUPLEX);
+    _EXPORT_INT(m, SNDCTL_DSP_SETFMT);
+    _EXPORT_INT(m, SNDCTL_DSP_SETFRAGMENT);
+#ifdef SNDCTL_DSP_SETSPDIF
+    _EXPORT_INT(m, SNDCTL_DSP_SETSPDIF);
+#endif
+    _EXPORT_INT(m, SNDCTL_DSP_SETSYNCRO);
+    _EXPORT_INT(m, SNDCTL_DSP_SETTRIGGER);
+    _EXPORT_INT(m, SNDCTL_DSP_SPEED);
+    _EXPORT_INT(m, SNDCTL_DSP_STEREO);
+    _EXPORT_INT(m, SNDCTL_DSP_SUBDIVIDE);
+    _EXPORT_INT(m, SNDCTL_DSP_SYNC);
+    _EXPORT_INT(m, SNDCTL_FM_4OP_ENABLE);
+    _EXPORT_INT(m, SNDCTL_FM_LOAD_INSTR);
+    _EXPORT_INT(m, SNDCTL_MIDI_INFO);
+    _EXPORT_INT(m, SNDCTL_MIDI_MPUCMD);
+    _EXPORT_INT(m, SNDCTL_MIDI_MPUMODE);
+    _EXPORT_INT(m, SNDCTL_MIDI_PRETIME);
+    _EXPORT_INT(m, SNDCTL_SEQ_CTRLRATE);
+    _EXPORT_INT(m, SNDCTL_SEQ_GETINCOUNT);
+    _EXPORT_INT(m, SNDCTL_SEQ_GETOUTCOUNT);
+#ifdef SNDCTL_SEQ_GETTIME
+    _EXPORT_INT(m, SNDCTL_SEQ_GETTIME);
+#endif
+    _EXPORT_INT(m, SNDCTL_SEQ_NRMIDIS);
+    _EXPORT_INT(m, SNDCTL_SEQ_NRSYNTHS);
+    _EXPORT_INT(m, SNDCTL_SEQ_OUTOFBAND);
+    _EXPORT_INT(m, SNDCTL_SEQ_PANIC);
+    _EXPORT_INT(m, SNDCTL_SEQ_PERCMODE);
+    _EXPORT_INT(m, SNDCTL_SEQ_RESET);
+    _EXPORT_INT(m, SNDCTL_SEQ_RESETSAMPLES);
+    _EXPORT_INT(m, SNDCTL_SEQ_SYNC);
+    _EXPORT_INT(m, SNDCTL_SEQ_TESTMIDI);
+    _EXPORT_INT(m, SNDCTL_SEQ_THRESHOLD);
+#ifdef SNDCTL_SYNTH_CONTROL
+    _EXPORT_INT(m, SNDCTL_SYNTH_CONTROL);
+#endif
+#ifdef SNDCTL_SYNTH_ID
+    _EXPORT_INT(m, SNDCTL_SYNTH_ID);
+#endif
+    _EXPORT_INT(m, SNDCTL_SYNTH_INFO);
+    _EXPORT_INT(m, SNDCTL_SYNTH_MEMAVL);
+#ifdef SNDCTL_SYNTH_REMOVESAMPLE
+    _EXPORT_INT(m, SNDCTL_SYNTH_REMOVESAMPLE);
+#endif
+    _EXPORT_INT(m, SNDCTL_TMR_CONTINUE);
+    _EXPORT_INT(m, SNDCTL_TMR_METRONOME);
+    _EXPORT_INT(m, SNDCTL_TMR_SELECT);
+    _EXPORT_INT(m, SNDCTL_TMR_SOURCE);
+    _EXPORT_INT(m, SNDCTL_TMR_START);
+    _EXPORT_INT(m, SNDCTL_TMR_STOP);
+    _EXPORT_INT(m, SNDCTL_TMR_TEMPO);
+    _EXPORT_INT(m, SNDCTL_TMR_TIMEBASE);
+}

Added: vendor/Python/current/Modules/parsermodule.c
===================================================================
--- vendor/Python/current/Modules/parsermodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/parsermodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,3279 @@
+/*  parsermodule.c
+ *
+ *  Copyright 1995-1996 by Fred L. Drake, Jr. and Virginia Polytechnic
+ *  Institute and State University, Blacksburg, Virginia, USA.
+ *  Portions copyright 1991-1995 by Stichting Mathematisch Centrum,
+ *  Amsterdam, The Netherlands.  Copying is permitted under the terms
+ *  associated with the main Python distribution, with the additional
+ *  restriction that this additional notice be included and maintained
+ *  on all distributed copies.
+ *
+ *  This module serves to replace the original parser module written
+ *  by Guido.  The functionality is not matched precisely, but the
+ *  original may be implemented on top of this.  This is desirable
+ *  since the source of the text to be parsed is now divorced from
+ *  this interface.
+ *
+ *  Unlike the prior interface, the ability to give a parse tree
+ *  produced by Python code as a tuple to the compiler is enabled by
+ *  this module.  See the documentation for more details.
+ *
+ *  I've added some annotations that help with the lint code-checking
+ *  program, but they're not complete by a long shot.  The real errors
+ *  that lint detects are gone, but there are still warnings with
+ *  Py_[X]DECREF() and Py_[X]INCREF() macros.  The lint annotations
+ *  look like "NOTE(...)".
+ */
+
+#include "Python.h"                     /* general Python API             */
+#include "graminit.h"                   /* symbols defined in the grammar */
+#include "node.h"                       /* internal parser structure      */
+#include "errcode.h"                    /* error codes for PyNode_*()     */
+#include "token.h"                      /* token definitions              */
+                                        /* ISTERMINAL() / ISNONTERMINAL() */
+#include "compile.h"                    /* PyNode_Compile()               */
+
+#ifdef lint
+#include <note.h>
+#else
+#define NOTE(x)
+#endif
+
+/*  String constants used to initialize module attributes.
+ *
+ */
+static char parser_copyright_string[] =
+"Copyright 1995-1996 by Virginia Polytechnic Institute & State\n\
+University, Blacksburg, Virginia, USA, and Fred L. Drake, Jr., Reston,\n\
+Virginia, USA.  Portions copyright 1991-1995 by Stichting Mathematisch\n\
+Centrum, Amsterdam, The Netherlands.";
+
+
+PyDoc_STRVAR(parser_doc_string,
+"This is an interface to Python's internal parser.");
+
+static char parser_version_string[] = "0.5";
+
+
+typedef PyObject* (*SeqMaker) (Py_ssize_t length);
+typedef int (*SeqInserter) (PyObject* sequence,
+                            Py_ssize_t index,
+                            PyObject* element);
+
+/*  The function below is copyrighted by Stichting Mathematisch Centrum.  The
+ *  original copyright statement is included below, and continues to apply
+ *  in full to the function immediately following.  All other material is
+ *  original, copyrighted by Fred L. Drake, Jr. and Virginia Polytechnic
+ *  Institute and State University.  Changes were made to comply with the
+ *  new naming conventions.  Added arguments to provide support for creating
+ *  lists as well as tuples, and optionally including the line numbers.
+ */
+
+
+static PyObject*
+node2tuple(node *n,                     /* node to convert               */
+           SeqMaker mkseq,              /* create sequence               */
+           SeqInserter addelem,         /* func. to add elem. in seq.    */
+           int lineno)                  /* include line numbers?         */
+{
+    if (n == NULL) {
+        Py_INCREF(Py_None);
+        return (Py_None);
+    }
+    if (ISNONTERMINAL(TYPE(n))) {
+        int i;
+        PyObject *v;
+        PyObject *w;
+
+        v = mkseq(1 + NCH(n) + (TYPE(n) == encoding_decl));
+        if (v == NULL)
+            return (v);
+        w = PyInt_FromLong(TYPE(n));
+        if (w == NULL) {
+            Py_DECREF(v);
+            return ((PyObject*) NULL);
+        }
+        (void) addelem(v, 0, w);
+        for (i = 0; i < NCH(n); i++) {
+            w = node2tuple(CHILD(n, i), mkseq, addelem, lineno);
+            if (w == NULL) {
+                Py_DECREF(v);
+                return ((PyObject*) NULL);
+            }
+            (void) addelem(v, i+1, w);
+        }
+
+        if (TYPE(n) == encoding_decl)
+            (void) addelem(v, i+1, PyString_FromString(STR(n)));
+        return (v);
+    }
+    else if (ISTERMINAL(TYPE(n))) {
+        PyObject *result = mkseq(2 + lineno);
+        if (result != NULL) {
+            (void) addelem(result, 0, PyInt_FromLong(TYPE(n)));
+            (void) addelem(result, 1, PyString_FromString(STR(n)));
+            if (lineno == 1)
+                (void) addelem(result, 2, PyInt_FromLong(n->n_lineno));
+        }
+        return (result);
+    }
+    else {
+        PyErr_SetString(PyExc_SystemError,
+                        "unrecognized parse tree node type");
+        return ((PyObject*) NULL);
+    }
+}
+/*
+ *  End of material copyrighted by Stichting Mathematisch Centrum.
+ */
+
+
+
+/*  There are two types of intermediate objects we're interested in:
+ *  'eval' and 'exec' types.  These constants can be used in the st_type
+ *  field of the object type to identify which any given object represents.
+ *  These should probably go in an external header to allow other extensions
+ *  to use them, but then, we really should be using C++ too.  ;-)
+ */
+
+#define PyST_EXPR  1
+#define PyST_SUITE 2
+
+
+/*  These are the internal objects and definitions required to implement the
+ *  ST type.  Most of the internal names are more reminiscent of the 'old'
+ *  naming style, but the code uses the new naming convention.
+ */
+
+static PyObject*
+parser_error = 0;
+
+
+typedef struct {
+    PyObject_HEAD                       /* standard object header           */
+    node* st_node;                      /* the node* returned by the parser */
+    int   st_type;                      /* EXPR or SUITE ?                  */
+} PyST_Object;
+
+
+static void parser_free(PyST_Object *st);
+static int parser_compare(PyST_Object *left, PyST_Object *right);
+static PyObject *parser_getattr(PyObject *self, char *name);
+
+
+static
+PyTypeObject PyST_Type = {
+    PyObject_HEAD_INIT(NULL)
+    0,
+    "parser.st",                        /* tp_name              */
+    (int) sizeof(PyST_Object),          /* tp_basicsize         */
+    0,                                  /* tp_itemsize          */
+    (destructor)parser_free,            /* tp_dealloc           */
+    0,                                  /* tp_print             */
+    parser_getattr,                     /* tp_getattr           */
+    0,                                  /* tp_setattr           */
+    (cmpfunc)parser_compare,            /* tp_compare           */
+    0,                                  /* tp_repr              */
+    0,                                  /* tp_as_number         */
+    0,                                  /* tp_as_sequence       */
+    0,                                  /* tp_as_mapping        */
+    0,                                  /* tp_hash              */
+    0,                                  /* tp_call              */
+    0,                                  /* tp_str               */
+    0,                                  /* tp_getattro          */
+    0,                                  /* tp_setattro          */
+
+    /* Functions to access object as input/output buffer */
+    0,                                  /* tp_as_buffer         */
+
+    Py_TPFLAGS_DEFAULT,                 /* tp_flags             */
+
+    /* __doc__ */
+    "Intermediate representation of a Python parse tree."
+};  /* PyST_Type */
+
+
+static int
+parser_compare_nodes(node *left, node *right)
+{
+    int j;
+
+    if (TYPE(left) < TYPE(right))
+        return (-1);
+
+    if (TYPE(right) < TYPE(left))
+        return (1);
+
+    if (ISTERMINAL(TYPE(left)))
+        return (strcmp(STR(left), STR(right)));
+
+    if (NCH(left) < NCH(right))
+        return (-1);
+
+    if (NCH(right) < NCH(left))
+        return (1);
+
+    for (j = 0; j < NCH(left); ++j) {
+        int v = parser_compare_nodes(CHILD(left, j), CHILD(right, j));
+
+        if (v != 0)
+            return (v);
+    }
+    return (0);
+}
+
+
+/*  int parser_compare(PyST_Object* left, PyST_Object* right)
+ *
+ *  Comparison function used by the Python operators ==, !=, <, >, <=, >=
+ *  This really just wraps a call to parser_compare_nodes() with some easy
+ *  checks and protection code.
+ *
+ */
+static int
+parser_compare(PyST_Object *left, PyST_Object *right)
+{
+    if (left == right)
+        return (0);
+
+    if ((left == 0) || (right == 0))
+        return (-1);
+
+    return (parser_compare_nodes(left->st_node, right->st_node));
+}
+
+
+/*  parser_newstobject(node* st)
+ *
+ *  Allocates a new Python object representing an ST.  This is simply the
+ *  'wrapper' object that holds a node* and allows it to be passed around in
+ *  Python code.
+ *
+ */
+static PyObject*
+parser_newstobject(node *st, int type)
+{
+    PyST_Object* o = PyObject_New(PyST_Object, &PyST_Type);
+
+    if (o != 0) {
+        o->st_node = st;
+        o->st_type = type;
+    }
+    else {
+        PyNode_Free(st);
+    }
+    return ((PyObject*)o);
+}
+
+
+/*  void parser_free(PyST_Object* st)
+ *
+ *  This is called by a del statement that reduces the reference count to 0.
+ *
+ */
+static void
+parser_free(PyST_Object *st)
+{
+    PyNode_Free(st->st_node);
+    PyObject_Del(st);
+}
+
+
+/*  parser_st2tuple(PyObject* self, PyObject* args, PyObject* kw)
+ *
+ *  This provides conversion from a node* to a tuple object that can be
+ *  returned to the Python-level caller.  The ST object is not modified.
+ *
+ */
+static PyObject*
+parser_st2tuple(PyST_Object *self, PyObject *args, PyObject *kw)
+{
+    PyObject *line_option = 0;
+    PyObject *res = 0;
+    int ok;
+
+    static char *keywords[] = {"ast", "line_info", NULL};
+
+    if (self == NULL) {
+        ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|O:st2tuple", keywords,
+                                         &PyST_Type, &self, &line_option);
+    }
+    else
+        ok = PyArg_ParseTupleAndKeywords(args, kw, "|O:totuple", &keywords[1],
+                                         &line_option);
+    if (ok != 0) {
+        int lineno = 0;
+        if (line_option != NULL) {
+            lineno = (PyObject_IsTrue(line_option) != 0) ? 1 : 0;
+        }
+        /*
+         *  Convert ST into a tuple representation.  Use Guido's function,
+         *  since it's known to work already.
+         */
+        res = node2tuple(((PyST_Object*)self)->st_node,
+                         PyTuple_New, PyTuple_SetItem, lineno);
+    }
+    return (res);
+}
+
+
+/*  parser_st2list(PyObject* self, PyObject* args, PyObject* kw)
+ *
+ *  This provides conversion from a node* to a list object that can be
+ *  returned to the Python-level caller.  The ST object is not modified.
+ *
+ */
+static PyObject*
+parser_st2list(PyST_Object *self, PyObject *args, PyObject *kw)
+{
+    PyObject *line_option = 0;
+    PyObject *res = 0;
+    int ok;
+
+    static char *keywords[] = {"ast", "line_info", NULL};
+
+    if (self == NULL)
+        ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|O:st2list", keywords,
+                                         &PyST_Type, &self, &line_option);
+    else
+        ok = PyArg_ParseTupleAndKeywords(args, kw, "|O:tolist", &keywords[1],
+                                         &line_option);
+    if (ok) {
+        int lineno = 0;
+        if (line_option != 0) {
+            lineno = PyObject_IsTrue(line_option) ? 1 : 0;
+        }
+        /*
+         *  Convert ST into a tuple representation.  Use Guido's function,
+         *  since it's known to work already.
+         */
+        res = node2tuple(self->st_node,
+                         PyList_New, PyList_SetItem, lineno);
+    }
+    return (res);
+}
+
+
+/*  parser_compilest(PyObject* self, PyObject* args)
+ *
+ *  This function creates code objects from the parse tree represented by
+ *  the passed-in data object.  An optional file name is passed in as well.
+ *
+ */
+static PyObject*
+parser_compilest(PyST_Object *self, PyObject *args, PyObject *kw)
+{
+    PyObject*     res = 0;
+    char*         str = "<syntax-tree>";
+    int ok;
+
+    static char *keywords[] = {"ast", "filename", NULL};
+
+    if (self == NULL)
+        ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|s:compilest", keywords,
+                                         &PyST_Type, &self, &str);
+    else
+        ok = PyArg_ParseTupleAndKeywords(args, kw, "|s:compile", &keywords[1],
+                                         &str);
+
+    if (ok)
+        res = (PyObject *)PyNode_Compile(self->st_node, str);
+
+    return (res);
+}
+
+
+/*  PyObject* parser_isexpr(PyObject* self, PyObject* args)
+ *  PyObject* parser_issuite(PyObject* self, PyObject* args)
+ *
+ *  Checks the passed-in ST object to determine if it is an expression or
+ *  a statement suite, respectively.  The return is a Python truth value.
+ *
+ */
+static PyObject*
+parser_isexpr(PyST_Object *self, PyObject *args, PyObject *kw)
+{
+    PyObject* res = 0;
+    int ok;
+
+    static char *keywords[] = {"ast", NULL};
+
+    if (self == NULL)
+        ok = PyArg_ParseTupleAndKeywords(args, kw, "O!:isexpr", keywords,
+                                         &PyST_Type, &self);
+    else
+        ok = PyArg_ParseTupleAndKeywords(args, kw, ":isexpr", &keywords[1]);
+
+    if (ok) {
+        /* Check to see if the ST represents an expression or not. */
+        res = (self->st_type == PyST_EXPR) ? Py_True : Py_False;
+        Py_INCREF(res);
+    }
+    return (res);
+}
+
+
+static PyObject*
+parser_issuite(PyST_Object *self, PyObject *args, PyObject *kw)
+{
+    PyObject* res = 0;
+    int ok;
+
+    static char *keywords[] = {"ast", NULL};
+
+    if (self == NULL)
+        ok = PyArg_ParseTupleAndKeywords(args, kw, "O!:issuite", keywords,
+                                         &PyST_Type, &self);
+    else
+        ok = PyArg_ParseTupleAndKeywords(args, kw, ":issuite", &keywords[1]);
+
+    if (ok) {
+        /* Check to see if the ST represents an expression or not. */
+        res = (self->st_type == PyST_EXPR) ? Py_False : Py_True;
+        Py_INCREF(res);
+    }
+    return (res);
+}
+
+
+#define PUBLIC_METHOD_TYPE (METH_VARARGS|METH_KEYWORDS)
+
+static PyMethodDef
+parser_methods[] = {
+    {"compile",         (PyCFunction)parser_compilest,  PUBLIC_METHOD_TYPE,
+        PyDoc_STR("Compile this ST object into a code object.")},
+    {"isexpr",          (PyCFunction)parser_isexpr,     PUBLIC_METHOD_TYPE,
+        PyDoc_STR("Determines if this ST object was created from an expression.")},
+    {"issuite",         (PyCFunction)parser_issuite,    PUBLIC_METHOD_TYPE,
+        PyDoc_STR("Determines if this ST object was created from a suite.")},
+    {"tolist",          (PyCFunction)parser_st2list,    PUBLIC_METHOD_TYPE,
+        PyDoc_STR("Creates a list-tree representation of this ST.")},
+    {"totuple",         (PyCFunction)parser_st2tuple,   PUBLIC_METHOD_TYPE,
+        PyDoc_STR("Creates a tuple-tree representation of this ST.")},
+
+    {NULL, NULL, 0, NULL}
+};
+
+
+static PyObject*
+parser_getattr(PyObject *self, char *name)
+{
+    return (Py_FindMethod(parser_methods, self, name));
+}
+
+
+/*  err_string(char* message)
+ *
+ *  Sets the error string for an exception of type ParserError.
+ *
+ */
+static void
+err_string(char *message)
+{
+    PyErr_SetString(parser_error, message);
+}
+
+
+/*  PyObject* parser_do_parse(PyObject* args, int type)
+ *
+ *  Internal function to actually execute the parse and return the result if
+ *  successful or set an exception if not.
+ *
+ */
+static PyObject*
+parser_do_parse(PyObject *args, PyObject *kw, char *argspec, int type)
+{
+    char*     string = 0;
+    PyObject* res    = 0;
+
+    static char *keywords[] = {"source", NULL};
+
+    if (PyArg_ParseTupleAndKeywords(args, kw, argspec, keywords, &string)) {
+        node* n = PyParser_SimpleParseString(string,
+                                             (type == PyST_EXPR)
+                                             ? eval_input : file_input);
+
+	if (n)
+	    res = parser_newstobject(n, type);
+    }
+    return (res);
+}
+
+
+/*  PyObject* parser_expr(PyObject* self, PyObject* args)
+ *  PyObject* parser_suite(PyObject* self, PyObject* args)
+ *
+ *  External interfaces to the parser itself.  Which is called determines if
+ *  the parser attempts to recognize an expression ('eval' form) or statement
+ *  suite ('exec' form).  The real work is done by parser_do_parse() above.
+ *
+ */
+static PyObject*
+parser_expr(PyST_Object *self, PyObject *args, PyObject *kw)
+{
+    NOTE(ARGUNUSED(self))
+    return (parser_do_parse(args, kw, "s:expr", PyST_EXPR));
+}
+
+
+static PyObject*
+parser_suite(PyST_Object *self, PyObject *args, PyObject *kw)
+{
+    NOTE(ARGUNUSED(self))
+    return (parser_do_parse(args, kw, "s:suite", PyST_SUITE));
+}
+
+
+
+/*  This is the messy part of the code.  Conversion from a tuple to an ST
+ *  object requires that the input tuple be valid without having to rely on
+ *  catching an exception from the compiler.  This is done to allow the
+ *  compiler itself to remain fast, since most of its input will come from
+ *  the parser directly, and therefore be known to be syntactically correct.
+ *  This validation is done to ensure that we don't core dump the compile
+ *  phase, returning an exception instead.
+ *
+ *  Two aspects can be broken out in this code:  creating a node tree from
+ *  the tuple passed in, and verifying that it is indeed valid.  It may be
+ *  advantageous to expand the number of ST types to include funcdefs and
+ *  lambdadefs to take advantage of the optimizer, recognizing those STs
+ *  here.  They are not necessary, and not quite as useful in a raw form.
+ *  For now, let's get expressions and suites working reliably.
+ */
+
+
+static node* build_node_tree(PyObject *tuple);
+static int   validate_expr_tree(node *tree);
+static int   validate_file_input(node *tree);
+static int   validate_encoding_decl(node *tree);
+
+/*  PyObject* parser_tuple2st(PyObject* self, PyObject* args)
+ *
+ *  This is the public function, called from the Python code.  It receives a
+ *  single tuple object from the caller, and creates an ST object if the
+ *  tuple can be validated.  It does this by checking the first code of the
+ *  tuple, and, if acceptable, builds the internal representation.  If this
+ *  step succeeds, the internal representation is validated as fully as
+ *  possible with the various validate_*() routines defined below.
+ *
+ *  This function must be changed if support is to be added for PyST_FRAGMENT
+ *  ST objects.
+ *
+ */
+static PyObject*
+parser_tuple2st(PyST_Object *self, PyObject *args, PyObject *kw)
+{
+    NOTE(ARGUNUSED(self))
+    PyObject *st = 0;
+    PyObject *tuple;
+    node *tree;
+
+    static char *keywords[] = {"sequence", NULL};
+
+    if (!PyArg_ParseTupleAndKeywords(args, kw, "O:sequence2st", keywords,
+                                     &tuple))
+        return (0);
+    if (!PySequence_Check(tuple)) {
+        PyErr_SetString(PyExc_ValueError,
+                        "sequence2st() requires a single sequence argument");
+        return (0);
+    }
+    /*
+     *  Convert the tree to the internal form before checking it.
+     */
+    tree = build_node_tree(tuple);
+    if (tree != 0) {
+        int start_sym = TYPE(tree);
+        if (start_sym == eval_input) {
+            /*  Might be an eval form.  */
+            if (validate_expr_tree(tree))
+                st = parser_newstobject(tree, PyST_EXPR);
+            else
+                PyNode_Free(tree);
+        }
+        else if (start_sym == file_input) {
+            /*  This looks like an exec form so far.  */
+            if (validate_file_input(tree))
+                st = parser_newstobject(tree, PyST_SUITE);
+            else
+                PyNode_Free(tree);
+        }
+        else if (start_sym == encoding_decl) {
+            /* This looks like an encoding_decl so far. */
+            if (validate_encoding_decl(tree))
+                st = parser_newstobject(tree, PyST_SUITE);
+            else
+                PyNode_Free(tree);
+        }
+        else {
+            /*  This is a fragment, at best. */
+            PyNode_Free(tree);
+            err_string("parse tree does not use a valid start symbol");
+        }
+    }
+    /*  Make sure we throw an exception on all errors.  We should never
+     *  get this, but we'd do well to be sure something is done.
+     */
+    if (st == NULL && !PyErr_Occurred())
+        err_string("unspecified ST error occurred");
+
+    return st;
+}
+
+
+/*  node* build_node_children()
+ *
+ *  Iterate across the children of the current non-terminal node and build
+ *  their structures.  If successful, return the root of this portion of
+ *  the tree, otherwise, 0.  Any required exception will be specified already,
+ *  and no memory will have been deallocated.
+ *
+ */
+static node*
+build_node_children(PyObject *tuple, node *root, int *line_num)
+{
+    Py_ssize_t len = PyObject_Size(tuple);
+    Py_ssize_t i;
+    int  err;
+
+    for (i = 1; i < len; ++i) {
+        /* elem must always be a sequence, however simple */
+        PyObject* elem = PySequence_GetItem(tuple, i);
+        int ok = elem != NULL;
+        long  type = 0;
+        char *strn = 0;
+
+        if (ok)
+            ok = PySequence_Check(elem);
+        if (ok) {
+            PyObject *temp = PySequence_GetItem(elem, 0);
+            if (temp == NULL)
+                ok = 0;
+            else {
+                ok = PyInt_Check(temp);
+                if (ok)
+                    type = PyInt_AS_LONG(temp);
+                Py_DECREF(temp);
+            }
+        }
+        if (!ok) {
+            PyObject *err = Py_BuildValue("os", elem,
+                                          "Illegal node construct.");
+            PyErr_SetObject(parser_error, err);
+            Py_XDECREF(err);
+            Py_XDECREF(elem);
+            return (0);
+        }
+        if (ISTERMINAL(type)) {
+            Py_ssize_t len = PyObject_Size(elem);
+            PyObject *temp;
+
+            if ((len != 2) && (len != 3)) {
+                err_string("terminal nodes must have 2 or 3 entries");
+                return 0;
+            }
+            temp = PySequence_GetItem(elem, 1);
+            if (temp == NULL)
+                return 0;
+            if (!PyString_Check(temp)) {
+                PyErr_Format(parser_error,
+                             "second item in terminal node must be a string,"
+                             " found %s",
+                             temp->ob_type->tp_name);
+                Py_DECREF(temp);
+                return 0;
+            }
+            if (len == 3) {
+                PyObject *o = PySequence_GetItem(elem, 2);
+                if (o != NULL) {
+                    if (PyInt_Check(o))
+                        *line_num = PyInt_AS_LONG(o);
+                    else {
+                        PyErr_Format(parser_error,
+                                     "third item in terminal node must be an"
+                                     " integer, found %s",
+				     temp->ob_type->tp_name);
+                        Py_DECREF(o);
+                        Py_DECREF(temp);
+                        return 0;
+                    }
+                    Py_DECREF(o);
+                }
+            }
+            len = PyString_GET_SIZE(temp) + 1;
+            strn = (char *)PyObject_MALLOC(len);
+            if (strn != NULL)
+                (void) memcpy(strn, PyString_AS_STRING(temp), len);
+            Py_DECREF(temp);
+        }
+        else if (!ISNONTERMINAL(type)) {
+            /*
+             *  It has to be one or the other; this is an error.
+             *  Throw an exception.
+             */
+            PyObject *err = Py_BuildValue("os", elem, "unknown node type.");
+            PyErr_SetObject(parser_error, err);
+            Py_XDECREF(err);
+            Py_XDECREF(elem);
+            return (0);
+        }
+        err = PyNode_AddChild(root, type, strn, *line_num, 0);
+        if (err == E_NOMEM) {
+            PyObject_FREE(strn);
+            return (node *) PyErr_NoMemory();
+        }
+        if (err == E_OVERFLOW) {
+            PyObject_FREE(strn);
+            PyErr_SetString(PyExc_ValueError,
+                            "unsupported number of child nodes");
+            return NULL;
+        }
+
+        if (ISNONTERMINAL(type)) {
+            node* new_child = CHILD(root, i - 1);
+
+            if (new_child != build_node_children(elem, new_child, line_num)) {
+                Py_XDECREF(elem);
+                return (0);
+            }
+        }
+        else if (type == NEWLINE) {     /* It's true:  we increment the     */
+            ++(*line_num);              /* line number *after* the newline! */
+        }
+        Py_XDECREF(elem);
+    }
+    return root;
+}
+
+
+static node*
+build_node_tree(PyObject *tuple)
+{
+    node* res = 0;
+    PyObject *temp = PySequence_GetItem(tuple, 0);
+    long num = -1;
+
+    if (temp != NULL)
+        num = PyInt_AsLong(temp);
+    Py_XDECREF(temp);
+    if (ISTERMINAL(num)) {
+        /*
+         *  The tuple is simple, but it doesn't start with a start symbol.
+         *  Throw an exception now and be done with it.
+         */
+        tuple = Py_BuildValue("os", tuple,
+                    "Illegal syntax-tree; cannot start with terminal symbol.");
+        PyErr_SetObject(parser_error, tuple);
+        Py_XDECREF(tuple);
+    }
+    else if (ISNONTERMINAL(num)) {
+        /*
+         *  Not efficient, but that can be handled later.
+         */
+        int line_num = 0;
+        PyObject *encoding = NULL;
+
+        if (num == encoding_decl) {
+            encoding = PySequence_GetItem(tuple, 2);
+            /* tuple isn't borrowed anymore here, need to DECREF */
+            tuple = PySequence_GetSlice(tuple, 0, 2);
+        }
+        res = PyNode_New(num);
+        if (res != NULL) {
+            if (res != build_node_children(tuple, res, &line_num)) {
+                PyNode_Free(res);
+                res = NULL;
+            }
+            if (res && encoding) {
+                Py_ssize_t len;
+                len = PyString_GET_SIZE(encoding) + 1;
+                res->n_str = (char *)PyObject_MALLOC(len);
+                if (res->n_str != NULL)
+                    (void) memcpy(res->n_str, PyString_AS_STRING(encoding), len);
+                Py_DECREF(encoding);
+                Py_DECREF(tuple);
+            }
+        }
+    }
+    else {
+        /*  The tuple is illegal -- if the number is neither TERMINAL nor
+         *  NONTERMINAL, we can't use it.  Not sure the implementation
+         *  allows this condition, but the API doesn't preclude it.
+         */
+        PyObject *err = Py_BuildValue("os", tuple,
+                                      "Illegal component tuple.");
+        PyErr_SetObject(parser_error, err);
+        Py_XDECREF(err);
+    }
+
+    return (res);
+}
+
+
+/*
+ *  Validation routines used within the validation section:
+ */
+static int validate_terminal(node *terminal, int type, char *string);
+
+#define validate_ampersand(ch)  validate_terminal(ch,      AMPER, "&")
+#define validate_circumflex(ch) validate_terminal(ch, CIRCUMFLEX, "^")
+#define validate_colon(ch)      validate_terminal(ch,      COLON, ":")
+#define validate_comma(ch)      validate_terminal(ch,      COMMA, ",")
+#define validate_dedent(ch)     validate_terminal(ch,     DEDENT, "")
+#define validate_equal(ch)      validate_terminal(ch,      EQUAL, "=")
+#define validate_indent(ch)     validate_terminal(ch,     INDENT, (char*)NULL)
+#define validate_lparen(ch)     validate_terminal(ch,       LPAR, "(")
+#define validate_newline(ch)    validate_terminal(ch,    NEWLINE, (char*)NULL)
+#define validate_rparen(ch)     validate_terminal(ch,       RPAR, ")")
+#define validate_semi(ch)       validate_terminal(ch,       SEMI, ";")
+#define validate_star(ch)       validate_terminal(ch,       STAR, "*")
+#define validate_vbar(ch)       validate_terminal(ch,       VBAR, "|")
+#define validate_doublestar(ch) validate_terminal(ch, DOUBLESTAR, "**")
+#define validate_dot(ch)        validate_terminal(ch,        DOT, ".")
+#define validate_at(ch)         validate_terminal(ch,         AT, "@")
+#define validate_name(ch, str)  validate_terminal(ch,       NAME, str)
+
+#define VALIDATER(n)    static int validate_##n(node *tree)
+
+VALIDATER(node);                VALIDATER(small_stmt);
+VALIDATER(class);               VALIDATER(node);
+VALIDATER(parameters);          VALIDATER(suite);
+VALIDATER(testlist);            VALIDATER(varargslist);
+VALIDATER(fpdef);               VALIDATER(fplist);
+VALIDATER(stmt);                VALIDATER(simple_stmt);
+VALIDATER(expr_stmt);           VALIDATER(power);
+VALIDATER(print_stmt);          VALIDATER(del_stmt);
+VALIDATER(return_stmt);         VALIDATER(list_iter);
+VALIDATER(raise_stmt);          VALIDATER(import_stmt);
+VALIDATER(import_name);         VALIDATER(import_from);
+VALIDATER(global_stmt);         VALIDATER(list_if);
+VALIDATER(assert_stmt);         VALIDATER(list_for);
+VALIDATER(exec_stmt);           VALIDATER(compound_stmt);
+VALIDATER(while);               VALIDATER(for);
+VALIDATER(try);                 VALIDATER(except_clause);
+VALIDATER(test);                VALIDATER(and_test);
+VALIDATER(not_test);            VALIDATER(comparison);
+VALIDATER(comp_op);             VALIDATER(expr);
+VALIDATER(xor_expr);            VALIDATER(and_expr);
+VALIDATER(shift_expr);          VALIDATER(arith_expr);
+VALIDATER(term);                VALIDATER(factor);
+VALIDATER(atom);                VALIDATER(lambdef);
+VALIDATER(trailer);             VALIDATER(subscript);
+VALIDATER(subscriptlist);       VALIDATER(sliceop);
+VALIDATER(exprlist);            VALIDATER(dictmaker);
+VALIDATER(arglist);             VALIDATER(argument);
+VALIDATER(listmaker);           VALIDATER(yield_stmt);
+VALIDATER(testlist1);           VALIDATER(gen_for);
+VALIDATER(gen_iter);            VALIDATER(gen_if);
+VALIDATER(testlist_gexp);	VALIDATER(yield_expr);
+VALIDATER(yield_or_testlist);	VALIDATER(or_test);
+VALIDATER(old_test); 		VALIDATER(old_lambdef);
+
+#undef VALIDATER
+
+#define is_even(n)      (((n) & 1) == 0)
+#define is_odd(n)       (((n) & 1) == 1)
+
+
+static int
+validate_ntype(node *n, int t)
+{
+    if (TYPE(n) != t) {
+        PyErr_Format(parser_error, "Expected node type %d, got %d.",
+                     t, TYPE(n));
+        return 0;
+    }
+    return 1;
+}
+
+
+/*  Verifies that the number of child nodes is exactly 'num', raising
+ *  an exception if it isn't.  The exception message does not indicate
+ *  the exact number of nodes, allowing this to be used to raise the
+ *  "right" exception when the wrong number of nodes is present in a
+ *  specific variant of a statement's syntax.  This is commonly used
+ *  in that fashion.
+ */
+static int
+validate_numnodes(node *n, int num, const char *const name)
+{
+    if (NCH(n) != num) {
+        PyErr_Format(parser_error,
+                     "Illegal number of children for %s node.", name);
+        return 0;
+    }
+    return 1;
+}
+
+
+static int
+validate_terminal(node *terminal, int type, char *string)
+{
+    int res = (validate_ntype(terminal, type)
+               && ((string == 0) || (strcmp(string, STR(terminal)) == 0)));
+
+    if (!res && !PyErr_Occurred()) {
+        PyErr_Format(parser_error,
+                     "Illegal terminal: expected \"%s\"", string);
+    }
+    return (res);
+}
+
+
+/*  X (',' X) [',']
+ */
+static int
+validate_repeating_list(node *tree, int ntype, int (*vfunc)(node *),
+                        const char *const name)
+{
+    int nch = NCH(tree);
+    int res = (nch && validate_ntype(tree, ntype)
+               && vfunc(CHILD(tree, 0)));
+
+    if (!res && !PyErr_Occurred())
+        (void) validate_numnodes(tree, 1, name);
+    else {
+        if (is_even(nch))
+            res = validate_comma(CHILD(tree, --nch));
+        if (res && nch > 1) {
+            int pos = 1;
+            for ( ; res && pos < nch; pos += 2)
+                res = (validate_comma(CHILD(tree, pos))
+                       && vfunc(CHILD(tree, pos + 1)));
+        }
+    }
+    return (res);
+}
+
+
+/*  validate_class()
+ *
+ *  classdef:
+ *      'class' NAME ['(' testlist ')'] ':' suite
+ */
+static int
+validate_class(node *tree)
+{
+    int nch = NCH(tree);
+    int res = (validate_ntype(tree, classdef) &&
+	       	((nch == 4) || (nch == 6) || (nch == 7)));
+
+    if (res) {
+        res = (validate_name(CHILD(tree, 0), "class")
+               && validate_ntype(CHILD(tree, 1), NAME)
+               && validate_colon(CHILD(tree, nch - 2))
+               && validate_suite(CHILD(tree, nch - 1)));
+    }
+    else {
+        (void) validate_numnodes(tree, 4, "class");
+    }
+	
+    if (res) {
+	if (nch == 7) {
+		res = ((validate_lparen(CHILD(tree, 2)) &&
+			validate_testlist(CHILD(tree, 3)) &&
+			validate_rparen(CHILD(tree, 4))));
+	}
+	else if (nch == 6) {
+		res = (validate_lparen(CHILD(tree,2)) &&
+			validate_rparen(CHILD(tree,3)));
+	}
+    }
+    return (res);
+}
+
+
+/*  if_stmt:
+ *      'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
+ */
+static int
+validate_if(node *tree)
+{
+    int nch = NCH(tree);
+    int res = (validate_ntype(tree, if_stmt)
+               && (nch >= 4)
+               && validate_name(CHILD(tree, 0), "if")
+               && validate_test(CHILD(tree, 1))
+               && validate_colon(CHILD(tree, 2))
+               && validate_suite(CHILD(tree, 3)));
+
+    if (res && ((nch % 4) == 3)) {
+        /*  ... 'else' ':' suite  */
+        res = (validate_name(CHILD(tree, nch - 3), "else")
+               && validate_colon(CHILD(tree, nch - 2))
+               && validate_suite(CHILD(tree, nch - 1)));
+        nch -= 3;
+    }
+    else if (!res && !PyErr_Occurred())
+        (void) validate_numnodes(tree, 4, "if");
+    if ((nch % 4) != 0)
+        /* Will catch the case for nch < 4 */
+        res = validate_numnodes(tree, 0, "if");
+    else if (res && (nch > 4)) {
+        /*  ... ('elif' test ':' suite)+ ...  */
+        int j = 4;
+        while ((j < nch) && res) {
+            res = (validate_name(CHILD(tree, j), "elif")
+                   && validate_colon(CHILD(tree, j + 2))
+                   && validate_test(CHILD(tree, j + 1))
+                   && validate_suite(CHILD(tree, j + 3)));
+            j += 4;
+        }
+    }
+    return (res);
+}
+
+
+/*  parameters:
+ *      '(' [varargslist] ')'
+ *
+ */
+static int
+validate_parameters(node *tree)
+{
+    int nch = NCH(tree);
+    int res = validate_ntype(tree, parameters) && ((nch == 2) || (nch == 3));
+
+    if (res) {
+        res = (validate_lparen(CHILD(tree, 0))
+               && validate_rparen(CHILD(tree, nch - 1)));
+        if (res && (nch == 3))
+            res = validate_varargslist(CHILD(tree, 1));
+    }
+    else {
+        (void) validate_numnodes(tree, 2, "parameters");
+    }
+    return (res);
+}
+
+
+/*  validate_suite()
+ *
+ *  suite:
+ *      simple_stmt
+ *    | NEWLINE INDENT stmt+ DEDENT
+ */
+static int
+validate_suite(node *tree)
+{
+    int nch = NCH(tree);
+    int res = (validate_ntype(tree, suite) && ((nch == 1) || (nch >= 4)));
+
+    if (res && (nch == 1))
+        res = validate_simple_stmt(CHILD(tree, 0));
+    else if (res) {
+        /*  NEWLINE INDENT stmt+ DEDENT  */
+        res = (validate_newline(CHILD(tree, 0))
+               && validate_indent(CHILD(tree, 1))
+               && validate_stmt(CHILD(tree, 2))
+               && validate_dedent(CHILD(tree, nch - 1)));
+
+        if (res && (nch > 4)) {
+            int i = 3;
+            --nch;                      /* forget the DEDENT     */
+            for ( ; res && (i < nch); ++i)
+                res = validate_stmt(CHILD(tree, i));
+        }
+        else if (nch < 4)
+            res = validate_numnodes(tree, 4, "suite");
+    }
+    return (res);
+}
+
+
+static int
+validate_testlist(node *tree)
+{
+    return (validate_repeating_list(tree, testlist,
+                                    validate_test, "testlist"));
+}
+
+
+static int
+validate_testlist1(node *tree)
+{
+    return (validate_repeating_list(tree, testlist1,
+                                    validate_test, "testlist1"));
+}
+
+
+static int
+validate_testlist_safe(node *tree)
+{
+    return (validate_repeating_list(tree, testlist_safe,
+                                    validate_old_test, "testlist_safe"));
+}
+
+
+/* '*' NAME [',' '**' NAME] | '**' NAME
+ */
+static int
+validate_varargslist_trailer(node *tree, int start)
+{
+    int nch = NCH(tree);
+    int res = 0;
+    int sym;
+
+    if (nch <= start) {
+        err_string("expected variable argument trailer for varargslist");
+        return 0;
+    }
+    sym = TYPE(CHILD(tree, start));
+    if (sym == STAR) {
+        /*
+         *  ('*' NAME [',' '**' NAME]
+         */
+        if (nch-start == 2)
+            res = validate_name(CHILD(tree, start+1), NULL);
+        else if (nch-start == 5)
+            res = (validate_name(CHILD(tree, start+1), NULL)
+                   && validate_comma(CHILD(tree, start+2))
+                   && validate_doublestar(CHILD(tree, start+3))
+                   && validate_name(CHILD(tree, start+4), NULL));
+    }
+    else if (sym == DOUBLESTAR) {
+        /*
+         *  '**' NAME
+         */
+        if (nch-start == 2)
+            res = validate_name(CHILD(tree, start+1), NULL);
+    }
+    if (!res)
+        err_string("illegal variable argument trailer for varargslist");
+    return res;
+}
+
+
+/*  validate_varargslist()
+ *
+ *  varargslist:
+ *      (fpdef ['=' test] ',')*
+ *           ('*' NAME [',' '**' NAME]
+ *         | '**' NAME)
+ *    | fpdef ['=' test] (',' fpdef ['=' test])* [',']
+ *
+ */
+static int
+validate_varargslist(node *tree)
+{
+    int nch = NCH(tree);
+    int res = validate_ntype(tree, varargslist) && (nch != 0);
+    int sym;
+
+    if (!res)
+        return 0;
+    if (nch < 1) {
+        err_string("varargslist missing child nodes");
+        return 0;
+    }
+    sym = TYPE(CHILD(tree, 0));
+    if (sym == STAR || sym == DOUBLESTAR)
+        /* whole thing matches:
+         *      '*' NAME [',' '**' NAME] | '**' NAME
+         */
+        res = validate_varargslist_trailer(tree, 0);
+    else if (sym == fpdef) {
+        int i = 0;
+
+        sym = TYPE(CHILD(tree, nch-1));
+        if (sym == NAME) {
+            /*
+             *   (fpdef ['=' test] ',')+
+             *       ('*' NAME [',' '**' NAME]
+             *     | '**' NAME)
+             */
+            /* skip over (fpdef ['=' test] ',')+ */
+            while (res && (i+2 <= nch)) {
+                res = validate_fpdef(CHILD(tree, i));
+                ++i;
+                if (res && TYPE(CHILD(tree, i)) == EQUAL && (i+2 <= nch)) {
+                    res = (validate_equal(CHILD(tree, i))
+                           && validate_test(CHILD(tree, i+1)));
+                    if (res)
+                        i += 2;
+                }
+                if (res && i < nch) {
+                    res = validate_comma(CHILD(tree, i));
+                    ++i;
+                    if (res && i < nch
+                        && (TYPE(CHILD(tree, i)) == DOUBLESTAR
+                            || TYPE(CHILD(tree, i)) == STAR))
+                        break;
+                }
+            }
+            /* ... '*' NAME [',' '**' NAME] | '**' NAME
+             * i --^^^
+             */
+            if (res)
+                res = validate_varargslist_trailer(tree, i);
+        }
+        else {
+            /*
+             *  fpdef ['=' test] (',' fpdef ['=' test])* [',']
+             */
+            /* strip trailing comma node */
+            if (sym == COMMA) {
+                res = validate_comma(CHILD(tree, nch-1));
+                if (!res)
+                    return 0;
+                --nch;
+            }
+            /*
+             *  fpdef ['=' test] (',' fpdef ['=' test])*
+             */
+            res = validate_fpdef(CHILD(tree, 0));
+            ++i;
+            if (res && (i+2 <= nch) && TYPE(CHILD(tree, i)) == EQUAL) {
+                res = (validate_equal(CHILD(tree, i))
+                       && validate_test(CHILD(tree, i+1)));
+                i += 2;
+            }
+            /*
+             *  ... (',' fpdef ['=' test])*
+             *  i ---^^^
+             */
+            while (res && (nch - i) >= 2) {
+                res = (validate_comma(CHILD(tree, i))
+                       && validate_fpdef(CHILD(tree, i+1)));
+                i += 2;
+                if (res && (nch - i) >= 2 && TYPE(CHILD(tree, i)) == EQUAL) {
+                    res = (validate_equal(CHILD(tree, i))
+                           && validate_test(CHILD(tree, i+1)));
+                    i += 2;
+                }
+            }
+            if (res && nch - i != 0) {
+                res = 0;
+                err_string("illegal formation for varargslist");
+            }
+        }
+    }
+    return res;
+}
+
+
+/*  list_iter:  list_for | list_if
+ */
+static int
+validate_list_iter(node *tree)
+{
+    int res = (validate_ntype(tree, list_iter)
+               && validate_numnodes(tree, 1, "list_iter"));
+    if (res && TYPE(CHILD(tree, 0)) == list_for)
+        res = validate_list_for(CHILD(tree, 0));
+    else
+        res = validate_list_if(CHILD(tree, 0));
+
+    return res;
+}
+
+/*  gen_iter:  gen_for | gen_if
+ */
+static int
+validate_gen_iter(node *tree)
+{
+    int res = (validate_ntype(tree, gen_iter)
+               && validate_numnodes(tree, 1, "gen_iter"));
+    if (res && TYPE(CHILD(tree, 0)) == gen_for)
+        res = validate_gen_for(CHILD(tree, 0));
+    else
+        res = validate_gen_if(CHILD(tree, 0));
+
+    return res;
+}
+
+/*  list_for:  'for' exprlist 'in' testlist [list_iter]
+ */
+static int
+validate_list_for(node *tree)
+{
+    int nch = NCH(tree);
+    int res;
+
+    if (nch == 5)
+        res = validate_list_iter(CHILD(tree, 4));
+    else
+        res = validate_numnodes(tree, 4, "list_for");
+
+    if (res)
+        res = (validate_name(CHILD(tree, 0), "for")
+               && validate_exprlist(CHILD(tree, 1))
+               && validate_name(CHILD(tree, 2), "in")
+               && validate_testlist_safe(CHILD(tree, 3)));
+
+    return res;
+}
+
+/*  gen_for:  'for' exprlist 'in' test [gen_iter]
+ */
+static int
+validate_gen_for(node *tree)
+{
+    int nch = NCH(tree);
+    int res;
+
+    if (nch == 5)
+        res = validate_gen_iter(CHILD(tree, 4));
+    else
+        res = validate_numnodes(tree, 4, "gen_for");
+
+    if (res)
+        res = (validate_name(CHILD(tree, 0), "for")
+               && validate_exprlist(CHILD(tree, 1))
+               && validate_name(CHILD(tree, 2), "in")
+               && validate_or_test(CHILD(tree, 3)));
+
+    return res;
+}
+
+/*  list_if:  'if' old_test [list_iter]
+ */
+static int
+validate_list_if(node *tree)
+{
+    int nch = NCH(tree);
+    int res;
+
+    if (nch == 3)
+        res = validate_list_iter(CHILD(tree, 2));
+    else
+        res = validate_numnodes(tree, 2, "list_if");
+
+    if (res)
+        res = (validate_name(CHILD(tree, 0), "if")
+               && validate_old_test(CHILD(tree, 1)));
+
+    return res;
+}
+
+/*  gen_if:  'if' old_test [gen_iter]
+ */
+static int
+validate_gen_if(node *tree)
+{
+    int nch = NCH(tree);
+    int res;
+
+    if (nch == 3)
+        res = validate_gen_iter(CHILD(tree, 2));
+    else
+        res = validate_numnodes(tree, 2, "gen_if");
+    
+    if (res)
+        res = (validate_name(CHILD(tree, 0), "if")
+               && validate_old_test(CHILD(tree, 1)));
+
+    return res;
+}
+
+/*  validate_fpdef()
+ *
+ *  fpdef:
+ *      NAME
+ *    | '(' fplist ')'
+ */
+static int
+validate_fpdef(node *tree)
+{
+    int nch = NCH(tree);
+    int res = validate_ntype(tree, fpdef);
+
+    if (res) {
+        if (nch == 1)
+            res = validate_ntype(CHILD(tree, 0), NAME);
+        else if (nch == 3)
+            res = (validate_lparen(CHILD(tree, 0))
+                   && validate_fplist(CHILD(tree, 1))
+                   && validate_rparen(CHILD(tree, 2)));
+        else
+            res = validate_numnodes(tree, 1, "fpdef");
+    }
+    return (res);
+}
+
+
+static int
+validate_fplist(node *tree)
+{
+    return (validate_repeating_list(tree, fplist,
+                                    validate_fpdef, "fplist"));
+}
+
+
+/*  simple_stmt | compound_stmt
+ *
+ */
+static int
+validate_stmt(node *tree)
+{
+    int res = (validate_ntype(tree, stmt)
+               && validate_numnodes(tree, 1, "stmt"));
+
+    if (res) {
+        tree = CHILD(tree, 0);
+
+        if (TYPE(tree) == simple_stmt)
+            res = validate_simple_stmt(tree);
+        else
+            res = validate_compound_stmt(tree);
+    }
+    return (res);
+}
+
+
+/*  small_stmt (';' small_stmt)* [';'] NEWLINE
+ *
+ */
+static int
+validate_simple_stmt(node *tree)
+{
+    int nch = NCH(tree);
+    int res = (validate_ntype(tree, simple_stmt)
+               && (nch >= 2)
+               && validate_small_stmt(CHILD(tree, 0))
+               && validate_newline(CHILD(tree, nch - 1)));
+
+    if (nch < 2)
+        res = validate_numnodes(tree, 2, "simple_stmt");
+    --nch;                              /* forget the NEWLINE    */
+    if (res && is_even(nch))
+        res = validate_semi(CHILD(tree, --nch));
+    if (res && (nch > 2)) {
+        int i;
+
+        for (i = 1; res && (i < nch); i += 2)
+            res = (validate_semi(CHILD(tree, i))
+                   && validate_small_stmt(CHILD(tree, i + 1)));
+    }
+    return (res);
+}
+
+
+static int
+validate_small_stmt(node *tree)
+{
+    int nch = NCH(tree);
+    int res = validate_numnodes(tree, 1, "small_stmt");
+
+    if (res) {
+        int ntype = TYPE(CHILD(tree, 0));
+
+        if (  (ntype == expr_stmt)
+              || (ntype == print_stmt)
+              || (ntype == del_stmt)
+              || (ntype == pass_stmt)
+              || (ntype == flow_stmt)
+              || (ntype == import_stmt)
+              || (ntype == global_stmt)
+              || (ntype == assert_stmt)
+              || (ntype == exec_stmt))
+            res = validate_node(CHILD(tree, 0));
+        else {
+            res = 0;
+            err_string("illegal small_stmt child type");
+        }
+    }
+    else if (nch == 1) {
+        res = 0;
+        PyErr_Format(parser_error,
+                     "Unrecognized child node of small_stmt: %d.",
+                     TYPE(CHILD(tree, 0)));
+    }
+    return (res);
+}
+
+
+/*  compound_stmt:
+ *      if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef
+ */
+static int
+validate_compound_stmt(node *tree)
+{
+    int res = (validate_ntype(tree, compound_stmt)
+               && validate_numnodes(tree, 1, "compound_stmt"));
+    int ntype;
+
+    if (!res)
+        return (0);
+
+    tree = CHILD(tree, 0);
+    ntype = TYPE(tree);
+    if (  (ntype == if_stmt)
+          || (ntype == while_stmt)
+          || (ntype == for_stmt)
+          || (ntype == try_stmt)
+          || (ntype == funcdef)
+          || (ntype == classdef))
+        res = validate_node(tree);
+    else {
+        res = 0;
+        PyErr_Format(parser_error,
+                     "Illegal compound statement type: %d.", TYPE(tree));
+    }
+    return (res);
+}
+
+
+static int
+validate_yield_or_testlist(node *tree)
+{
+	if (TYPE(tree) == yield_expr) 
+		return validate_yield_expr(tree);
+	else
+		return validate_testlist(tree);
+}
+
+static int
+validate_expr_stmt(node *tree)
+{
+    int j;
+    int nch = NCH(tree);
+    int res = (validate_ntype(tree, expr_stmt)
+               && is_odd(nch)
+               && validate_testlist(CHILD(tree, 0)));
+
+    if (res && nch == 3
+        && TYPE(CHILD(tree, 1)) == augassign) {
+        res = validate_numnodes(CHILD(tree, 1), 1, "augassign")
+		&& validate_yield_or_testlist(CHILD(tree, 2));
+
+        if (res) {
+            char *s = STR(CHILD(CHILD(tree, 1), 0));
+
+            res = (strcmp(s, "+=") == 0
+                   || strcmp(s, "-=") == 0
+                   || strcmp(s, "*=") == 0
+                   || strcmp(s, "/=") == 0
+                   || strcmp(s, "//=") == 0
+                   || strcmp(s, "%=") == 0
+                   || strcmp(s, "&=") == 0
+                   || strcmp(s, "|=") == 0
+                   || strcmp(s, "^=") == 0
+                   || strcmp(s, "<<=") == 0
+                   || strcmp(s, ">>=") == 0
+                   || strcmp(s, "**=") == 0);
+            if (!res)
+                err_string("illegal augmmented assignment operator");
+        }
+    }
+    else {
+        for (j = 1; res && (j < nch); j += 2)
+            res = validate_equal(CHILD(tree, j))
+                   && validate_yield_or_testlist(CHILD(tree, j + 1));
+    }
+    return (res);
+}
+
+
+/*  print_stmt:
+ *
+ *      'print' ( [ test (',' test)* [','] ]
+ *              | '>>' test [ (',' test)+ [','] ] )
+ */
+static int
+validate_print_stmt(node *tree)
+{
+    int nch = NCH(tree);
+    int res = (validate_ntype(tree, print_stmt)
+               && (nch > 0)
+               && validate_name(CHILD(tree, 0), "print"));
+
+    if (res && nch > 1) {
+        int sym = TYPE(CHILD(tree, 1));
+        int i = 1;
+        int allow_trailing_comma = 1;
+
+        if (sym == test)
+            res = validate_test(CHILD(tree, i++));
+        else {
+            if (nch < 3)
+                res = validate_numnodes(tree, 3, "print_stmt");
+            else {
+                res = (validate_ntype(CHILD(tree, i), RIGHTSHIFT)
+                       && validate_test(CHILD(tree, i+1)));
+                i += 2;
+                allow_trailing_comma = 0;
+            }
+        }
+        if (res) {
+            /*  ... (',' test)* [',']  */
+            while (res && i+2 <= nch) {
+                res = (validate_comma(CHILD(tree, i))
+                       && validate_test(CHILD(tree, i+1)));
+                allow_trailing_comma = 1;
+                i += 2;
+            }
+            if (res && !allow_trailing_comma)
+                res = validate_numnodes(tree, i, "print_stmt");
+            else if (res && i < nch)
+                res = validate_comma(CHILD(tree, i));
+        }
+    }
+    return (res);
+}
+
+
+static int
+validate_del_stmt(node *tree)
+{
+    return (validate_numnodes(tree, 2, "del_stmt")
+            && validate_name(CHILD(tree, 0), "del")
+            && validate_exprlist(CHILD(tree, 1)));
+}
+
+
+static int
+validate_return_stmt(node *tree)
+{
+    int nch = NCH(tree);
+    int res = (validate_ntype(tree, return_stmt)
+               && ((nch == 1) || (nch == 2))
+               && validate_name(CHILD(tree, 0), "return"));
+
+    if (res && (nch == 2))
+        res = validate_testlist(CHILD(tree, 1));
+
+    return (res);
+}
+
+
+static int
+validate_raise_stmt(node *tree)
+{
+    int nch = NCH(tree);
+    int res = (validate_ntype(tree, raise_stmt)
+               && ((nch == 1) || (nch == 2) || (nch == 4) || (nch == 6)));
+
+    if (res) {
+        res = validate_name(CHILD(tree, 0), "raise");
+        if (res && (nch >= 2))
+            res = validate_test(CHILD(tree, 1));
+        if (res && nch > 2) {
+            res = (validate_comma(CHILD(tree, 2))
+                   && validate_test(CHILD(tree, 3)));
+            if (res && (nch > 4))
+                res = (validate_comma(CHILD(tree, 4))
+                       && validate_test(CHILD(tree, 5)));
+        }
+    }
+    else
+        (void) validate_numnodes(tree, 2, "raise");
+    if (res && (nch == 4))
+        res = (validate_comma(CHILD(tree, 2))
+               && validate_test(CHILD(tree, 3)));
+
+    return (res);
+}
+
+
+/* yield_expr: 'yield' [testlist]
+ */
+static int
+validate_yield_expr(node *tree)
+{
+    int nch = NCH(tree);
+    int res = (validate_ntype(tree, yield_expr)
+               && ((nch == 1) || (nch == 2))
+               && validate_name(CHILD(tree, 0), "yield"));
+
+    if (res && (nch == 2))
+        res = validate_testlist(CHILD(tree, 1));
+
+    return (res);
+}
+
+
+/* yield_stmt: yield_expr
+ */
+static int
+validate_yield_stmt(node *tree)
+{
+    return (validate_ntype(tree, yield_stmt)
+            && validate_numnodes(tree, 1, "yield_stmt")
+            && validate_yield_expr(CHILD(tree, 0)));
+}
+
+
+static int
+validate_import_as_name(node *tree)
+{
+    int nch = NCH(tree);
+    int ok = validate_ntype(tree, import_as_name);
+
+    if (ok) {
+        if (nch == 1)
+            ok = validate_name(CHILD(tree, 0), NULL);
+        else if (nch == 3)
+            ok = (validate_name(CHILD(tree, 0), NULL)
+                  && validate_name(CHILD(tree, 1), "as")
+                  && validate_name(CHILD(tree, 2), NULL));
+        else
+            ok = validate_numnodes(tree, 3, "import_as_name");
+    }
+    return ok;
+}
+
+
+/* dotted_name:  NAME ("." NAME)*
+ */
+static int
+validate_dotted_name(node *tree)
+{
+    int nch = NCH(tree);
+    int res = (validate_ntype(tree, dotted_name)
+               && is_odd(nch)
+               && validate_name(CHILD(tree, 0), NULL));
+    int i;
+
+    for (i = 1; res && (i < nch); i += 2) {
+        res = (validate_dot(CHILD(tree, i))
+               && validate_name(CHILD(tree, i+1), NULL));
+    }
+    return res;
+}
+
+
+/* dotted_as_name:  dotted_name [NAME NAME]
+ */
+static int
+validate_dotted_as_name(node *tree)
+{
+    int nch = NCH(tree);
+    int res = validate_ntype(tree, dotted_as_name);
+
+    if (res) {
+        if (nch == 1)
+            res = validate_dotted_name(CHILD(tree, 0));
+        else if (nch == 3)
+            res = (validate_dotted_name(CHILD(tree, 0))
+                   && validate_name(CHILD(tree, 1), "as")
+                   && validate_name(CHILD(tree, 2), NULL));
+        else {
+            res = 0;
+            err_string("illegal number of children for dotted_as_name");
+        }
+    }
+    return res;
+}
+
+
+/* dotted_as_name (',' dotted_as_name)* */
+static int
+validate_dotted_as_names(node *tree)
+{
+	int nch = NCH(tree);
+	int res = is_odd(nch) && validate_dotted_as_name(CHILD(tree, 0));
+	int i;
+
+	for (i = 1; res && (i < nch); i += 2)
+	    res = (validate_comma(CHILD(tree, i))
+		   && validate_dotted_as_name(CHILD(tree, i + 1)));
+	return (res);
+}
+
+
+/* import_as_name (',' import_as_name)* [','] */
+static int
+validate_import_as_names(node *tree)
+{
+    int nch = NCH(tree);
+    int res = validate_import_as_name(CHILD(tree, 0));
+    int i;
+
+    for (i = 1; res && (i + 1 < nch); i += 2)
+	res = (validate_comma(CHILD(tree, i))
+	       && validate_import_as_name(CHILD(tree, i + 1)));
+    return (res);
+}
+
+
+/* 'import' dotted_as_names */
+static int
+validate_import_name(node *tree)
+{
+	return (validate_ntype(tree, import_name)
+		&& validate_numnodes(tree, 2, "import_name")
+		&& validate_name(CHILD(tree, 0), "import")
+		&& validate_dotted_as_names(CHILD(tree, 1)));
+}
+
+/* Helper function to count the number of leading dots in 
+ * 'from ...module import name'
+ */
+static int
+count_from_dots(node *tree)
+{
+        int i;
+        for (i = 0; i < NCH(tree); i++)
+		if (TYPE(CHILD(tree, i)) != DOT)
+			break;
+        return i;
+}
+
+/* 'from' ('.'* dotted_name | '.') 'import' ('*' | '(' import_as_names ')' |
+ *     import_as_names
+ */
+static int
+validate_import_from(node *tree)
+{
+	int nch = NCH(tree);
+	int ndots = count_from_dots(tree);
+	int havename = (TYPE(CHILD(tree, ndots + 1)) == dotted_name);
+	int offset = ndots + havename;
+	int res = validate_ntype(tree, import_from)
+		&& (nch >= 4 + ndots)
+		&& validate_name(CHILD(tree, 0), "from")
+		&& (!havename || validate_dotted_name(CHILD(tree, ndots + 1)))
+		&& validate_name(CHILD(tree, offset + 1), "import");
+
+	if (res && TYPE(CHILD(tree, offset + 2)) == LPAR)
+	    res = ((nch == offset + 5)
+		   && validate_lparen(CHILD(tree, offset + 2))
+		   && validate_import_as_names(CHILD(tree, offset + 3))
+		   && validate_rparen(CHILD(tree, offset + 4)));
+	else if (res && TYPE(CHILD(tree, offset + 2)) != STAR)
+	    res = validate_import_as_names(CHILD(tree, offset + 2));
+	return (res);
+}
+
+
+/* import_stmt: import_name | import_from */
+static int
+validate_import_stmt(node *tree)
+{
+    int nch = NCH(tree);
+    int res = validate_numnodes(tree, 1, "import_stmt");
+
+    if (res) {
+	int ntype = TYPE(CHILD(tree, 0));
+
+	if (ntype == import_name || ntype == import_from)
+            res = validate_node(CHILD(tree, 0));
+        else {
+            res = 0;
+            err_string("illegal import_stmt child type");
+        }
+    }
+    else if (nch == 1) {
+        res = 0;
+        PyErr_Format(parser_error,
+                     "Unrecognized child node of import_stmt: %d.",
+                     TYPE(CHILD(tree, 0)));
+    }
+    return (res);
+}
+
+
+
+
+static int
+validate_global_stmt(node *tree)
+{
+    int j;
+    int nch = NCH(tree);
+    int res = (validate_ntype(tree, global_stmt)
+               && is_even(nch) && (nch >= 2));
+
+    if (!res && !PyErr_Occurred())
+        err_string("illegal global statement");
+
+    if (res)
+        res = (validate_name(CHILD(tree, 0), "global")
+               && validate_ntype(CHILD(tree, 1), NAME));
+    for (j = 2; res && (j < nch); j += 2)
+        res = (validate_comma(CHILD(tree, j))
+               && validate_ntype(CHILD(tree, j + 1), NAME));
+
+    return (res);
+}
+
+
+/*  exec_stmt:
+ *
+ *  'exec' expr ['in' test [',' test]]
+ */
+static int
+validate_exec_stmt(node *tree)
+{
+    int nch = NCH(tree);
+    int res = (validate_ntype(tree, exec_stmt)
+               && ((nch == 2) || (nch == 4) || (nch == 6))
+               && validate_name(CHILD(tree, 0), "exec")
+               && validate_expr(CHILD(tree, 1)));
+
+    if (!res && !PyErr_Occurred())
+        err_string("illegal exec statement");
+    if (res && (nch > 2))
+        res = (validate_name(CHILD(tree, 2), "in")
+               && validate_test(CHILD(tree, 3)));
+    if (res && (nch == 6))
+        res = (validate_comma(CHILD(tree, 4))
+               && validate_test(CHILD(tree, 5)));
+
+    return (res);
+}
+
+
+/*  assert_stmt:
+ *
+ *  'assert' test [',' test]
+ */
+static int
+validate_assert_stmt(node *tree)
+{
+    int nch = NCH(tree);
+    int res = (validate_ntype(tree, assert_stmt)
+               && ((nch == 2) || (nch == 4))
+               && (validate_name(CHILD(tree, 0), "assert"))
+               && validate_test(CHILD(tree, 1)));
+
+    if (!res && !PyErr_Occurred())
+        err_string("illegal assert statement");
+    if (res && (nch > 2))
+        res = (validate_comma(CHILD(tree, 2))
+               && validate_test(CHILD(tree, 3)));
+
+    return (res);
+}
+
+
+static int
+validate_while(node *tree)
+{
+    int nch = NCH(tree);
+    int res = (validate_ntype(tree, while_stmt)
+               && ((nch == 4) || (nch == 7))
+               && validate_name(CHILD(tree, 0), "while")
+               && validate_test(CHILD(tree, 1))
+               && validate_colon(CHILD(tree, 2))
+               && validate_suite(CHILD(tree, 3)));
+
+    if (res && (nch == 7))
+        res = (validate_name(CHILD(tree, 4), "else")
+               && validate_colon(CHILD(tree, 5))
+               && validate_suite(CHILD(tree, 6)));
+
+    return (res);
+}
+
+
+static int
+validate_for(node *tree)
+{
+    int nch = NCH(tree);
+    int res = (validate_ntype(tree, for_stmt)
+               && ((nch == 6) || (nch == 9))
+               && validate_name(CHILD(tree, 0), "for")
+               && validate_exprlist(CHILD(tree, 1))
+               && validate_name(CHILD(tree, 2), "in")
+               && validate_testlist(CHILD(tree, 3))
+               && validate_colon(CHILD(tree, 4))
+               && validate_suite(CHILD(tree, 5)));
+
+    if (res && (nch == 9))
+        res = (validate_name(CHILD(tree, 6), "else")
+               && validate_colon(CHILD(tree, 7))
+               && validate_suite(CHILD(tree, 8)));
+
+    return (res);
+}
+
+
+/*  try_stmt:
+ *      'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite]
+ *    | 'try' ':' suite 'finally' ':' suite
+ *
+ */
+static int
+validate_try(node *tree)
+{
+    int nch = NCH(tree);
+    int pos = 3;
+    int res = (validate_ntype(tree, try_stmt)
+               && (nch >= 6) && ((nch % 3) == 0));
+
+    if (res)
+        res = (validate_name(CHILD(tree, 0), "try")
+               && validate_colon(CHILD(tree, 1))
+               && validate_suite(CHILD(tree, 2))
+               && validate_colon(CHILD(tree, nch - 2))
+               && validate_suite(CHILD(tree, nch - 1)));
+    else if (!PyErr_Occurred()) {
+        const char* name = "except";
+        if (TYPE(CHILD(tree, nch - 3)) != except_clause)
+            name = STR(CHILD(tree, nch - 3));
+
+        PyErr_Format(parser_error,
+                     "Illegal number of children for try/%s node.", name);
+    }
+    /*  Skip past except_clause sections:  */
+    while (res && (TYPE(CHILD(tree, pos)) == except_clause)) {
+        res = (validate_except_clause(CHILD(tree, pos))
+               && validate_colon(CHILD(tree, pos + 1))
+               && validate_suite(CHILD(tree, pos + 2)));
+        pos += 3;
+    }
+    if (res && (pos < nch)) {
+        res = validate_ntype(CHILD(tree, pos), NAME);
+        if (res && (strcmp(STR(CHILD(tree, pos)), "finally") == 0))
+            res = (validate_numnodes(tree, 6, "try/finally")
+                   && validate_colon(CHILD(tree, 4))
+                   && validate_suite(CHILD(tree, 5)));
+        else if (res) {
+            if (nch == (pos + 3)) {
+                res = ((strcmp(STR(CHILD(tree, pos)), "except") == 0)
+                       || (strcmp(STR(CHILD(tree, pos)), "else") == 0));
+                if (!res)
+                    err_string("illegal trailing triple in try statement");
+            }
+            else if (nch == (pos + 6)) {
+                res = (validate_name(CHILD(tree, pos), "except")
+                       && validate_colon(CHILD(tree, pos + 1))
+                       && validate_suite(CHILD(tree, pos + 2))
+                       && validate_name(CHILD(tree, pos + 3), "else"));
+            }
+            else
+                res = validate_numnodes(tree, pos + 3, "try/except");
+        }
+    }
+    return (res);
+}
+
+
+static int
+validate_except_clause(node *tree)
+{
+    int nch = NCH(tree);
+    int res = (validate_ntype(tree, except_clause)
+               && ((nch == 1) || (nch == 2) || (nch == 4))
+               && validate_name(CHILD(tree, 0), "except"));
+
+    if (res && (nch > 1))
+        res = validate_test(CHILD(tree, 1));
+    if (res && (nch == 4))
+        res = (validate_comma(CHILD(tree, 2))
+               && validate_test(CHILD(tree, 3)));
+
+    return (res);
+}
+
+
+static int
+validate_test(node *tree)
+{
+    int nch = NCH(tree);
+    int res = validate_ntype(tree, test) && is_odd(nch);
+
+    if (res && (TYPE(CHILD(tree, 0)) == lambdef))
+        res = ((nch == 1)
+               && validate_lambdef(CHILD(tree, 0)));
+    else if (res) {
+        res = validate_or_test(CHILD(tree, 0));
+        res = (res && (nch == 1 || (nch == 5 &&
+            validate_name(CHILD(tree, 1), "if") &&
+            validate_or_test(CHILD(tree, 2)) &&
+            validate_name(CHILD(tree, 3), "else") &&
+            validate_test(CHILD(tree, 4)))));
+    }
+    return (res);
+}
+
+static int
+validate_old_test(node *tree)
+{
+    int nch = NCH(tree);
+    int res = validate_ntype(tree, old_test) && (nch == 1);
+
+    if (res && (TYPE(CHILD(tree, 0)) == old_lambdef))
+        res = (validate_old_lambdef(CHILD(tree, 0)));
+    else if (res) {
+        res = (validate_or_test(CHILD(tree, 0)));
+    }
+    return (res);
+}
+
+static int
+validate_or_test(node *tree)
+{
+    int nch = NCH(tree);
+    int res = validate_ntype(tree, or_test) && is_odd(nch);
+
+    if (res) {
+        int pos;
+        res = validate_and_test(CHILD(tree, 0));
+        for (pos = 1; res && (pos < nch); pos += 2)
+            res = (validate_name(CHILD(tree, pos), "or")
+                   && validate_and_test(CHILD(tree, pos + 1)));
+    }
+    return (res);
+}
+
+
+static int
+validate_and_test(node *tree)
+{
+    int pos;
+    int nch = NCH(tree);
+    int res = (validate_ntype(tree, and_test)
+               && is_odd(nch)
+               && validate_not_test(CHILD(tree, 0)));
+
+    for (pos = 1; res && (pos < nch); pos += 2)
+        res = (validate_name(CHILD(tree, pos), "and")
+               && validate_not_test(CHILD(tree, 0)));
+
+    return (res);
+}
+
+
+static int
+validate_not_test(node *tree)
+{
+    int nch = NCH(tree);
+    int res = validate_ntype(tree, not_test) && ((nch == 1) || (nch == 2));
+
+    if (res) {
+        if (nch == 2)
+            res = (validate_name(CHILD(tree, 0), "not")
+                   && validate_not_test(CHILD(tree, 1)));
+        else if (nch == 1)
+            res = validate_comparison(CHILD(tree, 0));
+    }
+    return (res);
+}
+
+
+static int
+validate_comparison(node *tree)
+{
+    int pos;
+    int nch = NCH(tree);
+    int res = (validate_ntype(tree, comparison)
+               && is_odd(nch)
+               && validate_expr(CHILD(tree, 0)));
+
+    for (pos = 1; res && (pos < nch); pos += 2)
+        res = (validate_comp_op(CHILD(tree, pos))
+               && validate_expr(CHILD(tree, pos + 1)));
+
+    return (res);
+}
+
+
+static int
+validate_comp_op(node *tree)
+{
+    int res = 0;
+    int nch = NCH(tree);
+
+    if (!validate_ntype(tree, comp_op))
+        return (0);
+    if (nch == 1) {
+        /*
+         *  Only child will be a terminal with a well-defined symbolic name
+         *  or a NAME with a string of either 'is' or 'in'
+         */
+        tree = CHILD(tree, 0);
+        switch (TYPE(tree)) {
+            case LESS:
+            case GREATER:
+            case EQEQUAL:
+            case EQUAL:
+            case LESSEQUAL:
+            case GREATEREQUAL:
+            case NOTEQUAL:
+              res = 1;
+              break;
+            case NAME:
+              res = ((strcmp(STR(tree), "in") == 0)
+                     || (strcmp(STR(tree), "is") == 0));
+              if (!res) {
+                  PyErr_Format(parser_error,
+                               "illegal operator '%s'", STR(tree));
+              }
+              break;
+          default:
+              err_string("illegal comparison operator type");
+              break;
+        }
+    }
+    else if ((res = validate_numnodes(tree, 2, "comp_op")) != 0) {
+        res = (validate_ntype(CHILD(tree, 0), NAME)
+               && validate_ntype(CHILD(tree, 1), NAME)
+               && (((strcmp(STR(CHILD(tree, 0)), "is") == 0)
+                    && (strcmp(STR(CHILD(tree, 1)), "not") == 0))
+                   || ((strcmp(STR(CHILD(tree, 0)), "not") == 0)
+                       && (strcmp(STR(CHILD(tree, 1)), "in") == 0))));
+        if (!res && !PyErr_Occurred())
+            err_string("unknown comparison operator");
+    }
+    return (res);
+}
+
+
+static int
+validate_expr(node *tree)
+{
+    int j;
+    int nch = NCH(tree);
+    int res = (validate_ntype(tree, expr)
+               && is_odd(nch)
+               && validate_xor_expr(CHILD(tree, 0)));
+
+    for (j = 2; res && (j < nch); j += 2)
+        res = (validate_xor_expr(CHILD(tree, j))
+               && validate_vbar(CHILD(tree, j - 1)));
+
+    return (res);
+}
+
+
+static int
+validate_xor_expr(node *tree)
+{
+    int j;
+    int nch = NCH(tree);
+    int res = (validate_ntype(tree, xor_expr)
+               && is_odd(nch)
+               && validate_and_expr(CHILD(tree, 0)));
+
+    for (j = 2; res && (j < nch); j += 2)
+        res = (validate_circumflex(CHILD(tree, j - 1))
+               && validate_and_expr(CHILD(tree, j)));
+
+    return (res);
+}
+
+
+static int
+validate_and_expr(node *tree)
+{
+    int pos;
+    int nch = NCH(tree);
+    int res = (validate_ntype(tree, and_expr)
+               && is_odd(nch)
+               && validate_shift_expr(CHILD(tree, 0)));
+
+    for (pos = 1; res && (pos < nch); pos += 2)
+        res = (validate_ampersand(CHILD(tree, pos))
+               && validate_shift_expr(CHILD(tree, pos + 1)));
+
+    return (res);
+}
+
+
+static int
+validate_chain_two_ops(node *tree, int (*termvalid)(node *), int op1, int op2)
+ {
+    int pos = 1;
+    int nch = NCH(tree);
+    int res = (is_odd(nch)
+               && (*termvalid)(CHILD(tree, 0)));
+
+    for ( ; res && (pos < nch); pos += 2) {
+        if (TYPE(CHILD(tree, pos)) != op1)
+            res = validate_ntype(CHILD(tree, pos), op2);
+        if (res)
+            res = (*termvalid)(CHILD(tree, pos + 1));
+    }
+    return (res);
+}
+
+
+static int
+validate_shift_expr(node *tree)
+{
+    return (validate_ntype(tree, shift_expr)
+            && validate_chain_two_ops(tree, validate_arith_expr,
+                                      LEFTSHIFT, RIGHTSHIFT));
+}
+
+
+static int
+validate_arith_expr(node *tree)
+{
+    return (validate_ntype(tree, arith_expr)
+            && validate_chain_two_ops(tree, validate_term, PLUS, MINUS));
+}
+
+
+static int
+validate_term(node *tree)
+{
+    int pos = 1;
+    int nch = NCH(tree);
+    int res = (validate_ntype(tree, term)
+               && is_odd(nch)
+               && validate_factor(CHILD(tree, 0)));
+
+    for ( ; res && (pos < nch); pos += 2)
+        res = (((TYPE(CHILD(tree, pos)) == STAR)
+               || (TYPE(CHILD(tree, pos)) == SLASH)
+               || (TYPE(CHILD(tree, pos)) == DOUBLESLASH)
+               || (TYPE(CHILD(tree, pos)) == PERCENT))
+               && validate_factor(CHILD(tree, pos + 1)));
+
+    return (res);
+}
+
+
+/*  factor:
+ *
+ *  factor: ('+'|'-'|'~') factor | power
+ */
+static int
+validate_factor(node *tree)
+{
+    int nch = NCH(tree);
+    int res = (validate_ntype(tree, factor)
+               && (((nch == 2)
+                    && ((TYPE(CHILD(tree, 0)) == PLUS)
+                        || (TYPE(CHILD(tree, 0)) == MINUS)
+                        || (TYPE(CHILD(tree, 0)) == TILDE))
+                    && validate_factor(CHILD(tree, 1)))
+                   || ((nch == 1)
+                       && validate_power(CHILD(tree, 0)))));
+    return (res);
+}
+
+
+/*  power:
+ *
+ *  power: atom trailer* ('**' factor)*
+ */
+static int
+validate_power(node *tree)
+{
+    int pos = 1;
+    int nch = NCH(tree);
+    int res = (validate_ntype(tree, power) && (nch >= 1)
+               && validate_atom(CHILD(tree, 0)));
+
+    while (res && (pos < nch) && (TYPE(CHILD(tree, pos)) == trailer))
+        res = validate_trailer(CHILD(tree, pos++));
+    if (res && (pos < nch)) {
+        if (!is_even(nch - pos)) {
+            err_string("illegal number of nodes for 'power'");
+            return (0);
+        }
+        for ( ; res && (pos < (nch - 1)); pos += 2)
+            res = (validate_doublestar(CHILD(tree, pos))
+                   && validate_factor(CHILD(tree, pos + 1)));
+    }
+    return (res);
+}
+
+
+static int
+validate_atom(node *tree)
+{
+    int pos;
+    int nch = NCH(tree);
+    int res = validate_ntype(tree, atom);
+
+    if (res && nch < 1)
+        res = validate_numnodes(tree, nch+1, "atom");
+    if (res) {
+        switch (TYPE(CHILD(tree, 0))) {
+          case LPAR:
+            res = ((nch <= 3)
+                   && (validate_rparen(CHILD(tree, nch - 1))));
+
+            if (res && (nch == 3)) {
+		if (TYPE(CHILD(tree, 1))==yield_expr)
+			res = validate_yield_expr(CHILD(tree, 1));
+		else
+                	res = validate_testlist_gexp(CHILD(tree, 1));
+	    }
+            break;
+          case LSQB:
+            if (nch == 2)
+                res = validate_ntype(CHILD(tree, 1), RSQB);
+            else if (nch == 3)
+                res = (validate_listmaker(CHILD(tree, 1))
+                       && validate_ntype(CHILD(tree, 2), RSQB));
+            else {
+                res = 0;
+                err_string("illegal list display atom");
+            }
+            break;
+          case LBRACE:
+            res = ((nch <= 3)
+                   && validate_ntype(CHILD(tree, nch - 1), RBRACE));
+
+            if (res && (nch == 3))
+                res = validate_dictmaker(CHILD(tree, 1));
+            break;
+          case BACKQUOTE:
+            res = ((nch == 3)
+                   && validate_testlist1(CHILD(tree, 1))
+                   && validate_ntype(CHILD(tree, 2), BACKQUOTE));
+            break;
+          case NAME:
+          case NUMBER:
+            res = (nch == 1);
+            break;
+          case STRING:
+            for (pos = 1; res && (pos < nch); ++pos)
+                res = validate_ntype(CHILD(tree, pos), STRING);
+            break;
+          default:
+            res = 0;
+            break;
+        }
+    }
+    return (res);
+}
+
+
+/*  listmaker:
+ *    test ( list_for | (',' test)* [','] )
+ */
+static int
+validate_listmaker(node *tree)
+{
+    int nch = NCH(tree);
+    int ok = nch;
+
+    if (nch == 0)
+        err_string("missing child nodes of listmaker");
+    else
+        ok = validate_test(CHILD(tree, 0));
+
+    /*
+     *  list_for | (',' test)* [',']
+     */
+    if (nch == 2 && TYPE(CHILD(tree, 1)) == list_for)
+        ok = validate_list_for(CHILD(tree, 1));
+    else {
+        /*  (',' test)* [',']  */
+        int i = 1;
+        while (ok && nch - i >= 2) {
+            ok = (validate_comma(CHILD(tree, i))
+                  && validate_test(CHILD(tree, i+1)));
+            i += 2;
+        }
+        if (ok && i == nch-1)
+            ok = validate_comma(CHILD(tree, i));
+        else if (i != nch) {
+            ok = 0;
+            err_string("illegal trailing nodes for listmaker");
+        }
+    }
+    return ok;
+}
+
+/*  testlist_gexp:
+ *    test ( gen_for | (',' test)* [','] )
+ */
+static int
+validate_testlist_gexp(node *tree)
+{
+    int nch = NCH(tree);
+    int ok = nch;
+
+    if (nch == 0)
+        err_string("missing child nodes of testlist_gexp");
+    else {
+        ok = validate_test(CHILD(tree, 0));
+    }
+
+    /*
+     *  gen_for | (',' test)* [',']
+     */
+    if (nch == 2 && TYPE(CHILD(tree, 1)) == gen_for)
+        ok = validate_gen_for(CHILD(tree, 1));
+    else {
+        /*  (',' test)* [',']  */
+        int i = 1;
+        while (ok && nch - i >= 2) {
+            ok = (validate_comma(CHILD(tree, i))
+                  && validate_test(CHILD(tree, i+1)));
+            i += 2;
+        }
+        if (ok && i == nch-1)
+            ok = validate_comma(CHILD(tree, i));
+        else if (i != nch) {
+            ok = 0;
+            err_string("illegal trailing nodes for testlist_gexp");
+        }
+    }
+    return ok;
+}
+
+/*  decorator:
+ *    '@' dotted_name [ '(' [arglist] ')' ] NEWLINE
+ */
+static int
+validate_decorator(node *tree)
+{
+    int ok;
+    int nch = NCH(tree);
+    ok = (validate_ntype(tree, decorator) &&
+	  (nch == 3 || nch == 5 || nch == 6) &&
+	  validate_at(CHILD(tree, 0)) &&
+	  validate_dotted_name(CHILD(tree, 1)) &&
+	  validate_newline(RCHILD(tree, -1)));
+
+    if (ok && nch != 3) {
+	ok = (validate_lparen(CHILD(tree, 2)) &&
+	      validate_rparen(RCHILD(tree, -2)));
+
+	if (ok && nch == 6)
+	    ok = validate_arglist(CHILD(tree, 3));
+    }
+
+    return ok;
+}
+
+/*  decorators:
+ *    decorator+
+ */
+static int
+validate_decorators(node *tree)
+{
+    int i, nch, ok; 
+    nch = NCH(tree);
+    ok = validate_ntype(tree, decorators) && nch >= 1;
+
+    for (i = 0; ok && i < nch; ++i)
+	ok = validate_decorator(CHILD(tree, i));
+
+    return ok;
+}
+
+/*  funcdef:
+ *      
+ *            -6   -5    -4         -3  -2 -1
+ *  [decorators] 'def' NAME parameters ':' suite
+ */
+static int
+validate_funcdef(node *tree)
+{
+    int nch = NCH(tree);
+    int ok = (validate_ntype(tree, funcdef)
+	       && ((nch == 5) || (nch == 6))
+	       && validate_name(RCHILD(tree, -5), "def")
+	       && validate_ntype(RCHILD(tree, -4), NAME)
+	       && validate_colon(RCHILD(tree, -2))
+	       && validate_parameters(RCHILD(tree, -3))
+	       && validate_suite(RCHILD(tree, -1)));
+
+    if (ok && (nch == 6))
+	ok = validate_decorators(CHILD(tree, 0));
+
+    return ok;
+}
+
+
+static int
+validate_lambdef(node *tree)
+{
+    int nch = NCH(tree);
+    int res = (validate_ntype(tree, lambdef)
+               && ((nch == 3) || (nch == 4))
+               && validate_name(CHILD(tree, 0), "lambda")
+               && validate_colon(CHILD(tree, nch - 2))
+               && validate_test(CHILD(tree, nch - 1)));
+
+    if (res && (nch == 4))
+        res = validate_varargslist(CHILD(tree, 1));
+    else if (!res && !PyErr_Occurred())
+        (void) validate_numnodes(tree, 3, "lambdef");
+
+    return (res);
+}
+
+
+static int
+validate_old_lambdef(node *tree)
+{
+    int nch = NCH(tree);
+    int res = (validate_ntype(tree, old_lambdef)
+               && ((nch == 3) || (nch == 4))
+               && validate_name(CHILD(tree, 0), "lambda")
+               && validate_colon(CHILD(tree, nch - 2))
+               && validate_test(CHILD(tree, nch - 1)));
+
+    if (res && (nch == 4))
+        res = validate_varargslist(CHILD(tree, 1));
+    else if (!res && !PyErr_Occurred())
+        (void) validate_numnodes(tree, 3, "old_lambdef");
+
+    return (res);
+}
+
+
+/*  arglist:
+ *
+ *  (argument ',')* (argument [','] | '*' test [',' '**' test] | '**' test)
+ */
+static int
+validate_arglist(node *tree)
+{
+    int nch = NCH(tree);
+    int i = 0;
+    int ok = 1;
+
+    if (nch <= 0)
+        /* raise the right error from having an invalid number of children */
+        return validate_numnodes(tree, nch + 1, "arglist");
+
+    if (nch > 1) {
+        for (i=0; i<nch; i++) {
+            if (TYPE(CHILD(tree, i)) == argument) {
+                node *ch = CHILD(tree, i);
+                if (NCH(ch) == 2 && TYPE(CHILD(ch, 1)) == gen_for) {
+                    err_string("need '(', ')' for generator expression");
+                    return 0;
+                }
+            }
+        }
+    }
+
+    while (ok && nch-i >= 2) {
+        /* skip leading (argument ',') */
+        ok = (validate_argument(CHILD(tree, i))
+              && validate_comma(CHILD(tree, i+1)));
+        if (ok)
+            i += 2;
+        else
+            PyErr_Clear();
+    }
+    ok = 1;
+    if (nch-i > 0) {
+        /*
+         * argument | '*' test [',' '**' test] | '**' test
+         */
+        int sym = TYPE(CHILD(tree, i));
+
+        if (sym == argument) {
+            ok = validate_argument(CHILD(tree, i));
+            if (ok && i+1 != nch) {
+                err_string("illegal arglist specification"
+                           " (extra stuff on end)");
+                ok = 0;
+            }
+        }
+        else if (sym == STAR) {
+            ok = validate_star(CHILD(tree, i));
+            if (ok && (nch-i == 2))
+                ok = validate_test(CHILD(tree, i+1));
+            else if (ok && (nch-i == 5))
+                ok = (validate_test(CHILD(tree, i+1))
+                      && validate_comma(CHILD(tree, i+2))
+                      && validate_doublestar(CHILD(tree, i+3))
+                      && validate_test(CHILD(tree, i+4)));
+            else {
+                err_string("illegal use of '*' in arglist");
+                ok = 0;
+            }
+        }
+        else if (sym == DOUBLESTAR) {
+            if (nch-i == 2)
+                ok = (validate_doublestar(CHILD(tree, i))
+                      && validate_test(CHILD(tree, i+1)));
+            else {
+                err_string("illegal use of '**' in arglist");
+                ok = 0;
+            }
+        }
+        else {
+            err_string("illegal arglist specification");
+            ok = 0;
+        }
+    }
+    return (ok);
+}
+
+
+
+/*  argument:
+ *
+ *  [test '='] test [gen_for]
+ */
+static int
+validate_argument(node *tree)
+{
+    int nch = NCH(tree);
+    int res = (validate_ntype(tree, argument)
+               && ((nch == 1) || (nch == 2) || (nch == 3))
+               && validate_test(CHILD(tree, 0)));
+
+    if (res && (nch == 2))
+        res = validate_gen_for(CHILD(tree, 1));
+    else if (res && (nch == 3))
+        res = (validate_equal(CHILD(tree, 1))
+               && validate_test(CHILD(tree, 2)));
+
+    return (res);
+}
+
+
+
+/*  trailer:
+ *
+ *  '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
+ */
+static int
+validate_trailer(node *tree)
+{
+    int nch = NCH(tree);
+    int res = validate_ntype(tree, trailer) && ((nch == 2) || (nch == 3));
+
+    if (res) {
+        switch (TYPE(CHILD(tree, 0))) {
+          case LPAR:
+            res = validate_rparen(CHILD(tree, nch - 1));
+            if (res && (nch == 3))
+                res = validate_arglist(CHILD(tree, 1));
+            break;
+          case LSQB:
+            res = (validate_numnodes(tree, 3, "trailer")
+                   && validate_subscriptlist(CHILD(tree, 1))
+                   && validate_ntype(CHILD(tree, 2), RSQB));
+            break;
+          case DOT:
+            res = (validate_numnodes(tree, 2, "trailer")
+                   && validate_ntype(CHILD(tree, 1), NAME));
+            break;
+          default:
+            res = 0;
+            break;
+        }
+    }
+    else {
+        (void) validate_numnodes(tree, 2, "trailer");
+    }
+    return (res);
+}
+
+
+/*  subscriptlist:
+ *
+ *  subscript (',' subscript)* [',']
+ */
+static int
+validate_subscriptlist(node *tree)
+{
+    return (validate_repeating_list(tree, subscriptlist,
+                                    validate_subscript, "subscriptlist"));
+}
+
+
+/*  subscript:
+ *
+ *  '.' '.' '.' | test | [test] ':' [test] [sliceop]
+ */
+static int
+validate_subscript(node *tree)
+{
+    int offset = 0;
+    int nch = NCH(tree);
+    int res = validate_ntype(tree, subscript) && (nch >= 1) && (nch <= 4);
+
+    if (!res) {
+        if (!PyErr_Occurred())
+            err_string("invalid number of arguments for subscript node");
+        return (0);
+    }
+    if (TYPE(CHILD(tree, 0)) == DOT)
+        /* take care of ('.' '.' '.') possibility */
+        return (validate_numnodes(tree, 3, "subscript")
+                && validate_dot(CHILD(tree, 0))
+                && validate_dot(CHILD(tree, 1))
+                && validate_dot(CHILD(tree, 2)));
+    if (nch == 1) {
+        if (TYPE(CHILD(tree, 0)) == test)
+            res = validate_test(CHILD(tree, 0));
+        else
+            res = validate_colon(CHILD(tree, 0));
+        return (res);
+    }
+    /*  Must be [test] ':' [test] [sliceop],
+     *  but at least one of the optional components will
+     *  be present, but we don't know which yet.
+     */
+    if ((TYPE(CHILD(tree, 0)) != COLON) || (nch == 4)) {
+        res = validate_test(CHILD(tree, 0));
+        offset = 1;
+    }
+    if (res)
+        res = validate_colon(CHILD(tree, offset));
+    if (res) {
+        int rem = nch - ++offset;
+        if (rem) {
+            if (TYPE(CHILD(tree, offset)) == test) {
+                res = validate_test(CHILD(tree, offset));
+                ++offset;
+                --rem;
+            }
+            if (res && rem)
+                res = validate_sliceop(CHILD(tree, offset));
+        }
+    }
+    return (res);
+}
+
+
+static int
+validate_sliceop(node *tree)
+{
+    int nch = NCH(tree);
+    int res = ((nch == 1) || validate_numnodes(tree, 2, "sliceop"))
+              && validate_ntype(tree, sliceop);
+    if (!res && !PyErr_Occurred()) {
+        res = validate_numnodes(tree, 1, "sliceop");
+    }
+    if (res)
+        res = validate_colon(CHILD(tree, 0));
+    if (res && (nch == 2))
+        res = validate_test(CHILD(tree, 1));
+
+    return (res);
+}
+
+
+static int
+validate_exprlist(node *tree)
+{
+    return (validate_repeating_list(tree, exprlist,
+                                    validate_expr, "exprlist"));
+}
+
+
+static int
+validate_dictmaker(node *tree)
+{
+    int nch = NCH(tree);
+    int res = (validate_ntype(tree, dictmaker)
+               && (nch >= 3)
+               && validate_test(CHILD(tree, 0))
+               && validate_colon(CHILD(tree, 1))
+               && validate_test(CHILD(tree, 2)));
+
+    if (res && ((nch % 4) == 0))
+        res = validate_comma(CHILD(tree, --nch));
+    else if (res)
+        res = ((nch % 4) == 3);
+
+    if (res && (nch > 3)) {
+        int pos = 3;
+        /*  ( ',' test ':' test )*  */
+        while (res && (pos < nch)) {
+            res = (validate_comma(CHILD(tree, pos))
+                   && validate_test(CHILD(tree, pos + 1))
+                   && validate_colon(CHILD(tree, pos + 2))
+                   && validate_test(CHILD(tree, pos + 3)));
+            pos += 4;
+        }
+    }
+    return (res);
+}
+
+
+static int
+validate_eval_input(node *tree)
+{
+    int pos;
+    int nch = NCH(tree);
+    int res = (validate_ntype(tree, eval_input)
+               && (nch >= 2)
+               && validate_testlist(CHILD(tree, 0))
+               && validate_ntype(CHILD(tree, nch - 1), ENDMARKER));
+
+    for (pos = 1; res && (pos < (nch - 1)); ++pos)
+        res = validate_ntype(CHILD(tree, pos), NEWLINE);
+
+    return (res);
+}
+
+
+static int
+validate_node(node *tree)
+{
+    int   nch  = 0;                     /* num. children on current node  */
+    int   res  = 1;                     /* result value                   */
+    node* next = 0;                     /* node to process after this one */
+
+    while (res && (tree != 0)) {
+        nch  = NCH(tree);
+        next = 0;
+        switch (TYPE(tree)) {
+            /*
+             *  Definition nodes.
+             */
+          case funcdef:
+            res = validate_funcdef(tree);
+            break;
+          case classdef:
+            res = validate_class(tree);
+            break;
+            /*
+             *  "Trivial" parse tree nodes.
+             *  (Why did I call these trivial?)
+             */
+          case stmt:
+            res = validate_stmt(tree);
+            break;
+          case small_stmt:
+            /*
+             *  expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt
+             *  | import_stmt | global_stmt | exec_stmt | assert_stmt
+             */
+            res = validate_small_stmt(tree);
+            break;
+          case flow_stmt:
+            res  = (validate_numnodes(tree, 1, "flow_stmt")
+                    && ((TYPE(CHILD(tree, 0)) == break_stmt)
+                        || (TYPE(CHILD(tree, 0)) == continue_stmt)
+                        || (TYPE(CHILD(tree, 0)) == yield_stmt)
+                        || (TYPE(CHILD(tree, 0)) == return_stmt)
+                        || (TYPE(CHILD(tree, 0)) == raise_stmt)));
+            if (res)
+                next = CHILD(tree, 0);
+            else if (nch == 1)
+                err_string("illegal flow_stmt type");
+            break;
+          case yield_stmt:
+            res = validate_yield_stmt(tree);
+            break;
+            /*
+             *  Compound statements.
+             */
+          case simple_stmt:
+            res = validate_simple_stmt(tree);
+            break;
+          case compound_stmt:
+            res = validate_compound_stmt(tree);
+            break;
+            /*
+             *  Fundamental statements.
+             */
+          case expr_stmt:
+            res = validate_expr_stmt(tree);
+            break;
+          case print_stmt:
+            res = validate_print_stmt(tree);
+            break;
+          case del_stmt:
+            res = validate_del_stmt(tree);
+            break;
+          case pass_stmt:
+            res = (validate_numnodes(tree, 1, "pass")
+                   && validate_name(CHILD(tree, 0), "pass"));
+            break;
+          case break_stmt:
+            res = (validate_numnodes(tree, 1, "break")
+                   && validate_name(CHILD(tree, 0), "break"));
+            break;
+          case continue_stmt:
+            res = (validate_numnodes(tree, 1, "continue")
+                   && validate_name(CHILD(tree, 0), "continue"));
+            break;
+          case return_stmt:
+            res = validate_return_stmt(tree);
+            break;
+          case raise_stmt:
+            res = validate_raise_stmt(tree);
+            break;
+          case import_stmt:
+            res = validate_import_stmt(tree);
+            break;
+	  case import_name:
+	    res = validate_import_name(tree);
+	    break;
+	  case import_from:
+	    res = validate_import_from(tree);
+	    break;
+          case global_stmt:
+            res = validate_global_stmt(tree);
+            break;
+          case exec_stmt:
+            res = validate_exec_stmt(tree);
+            break;
+          case assert_stmt:
+            res = validate_assert_stmt(tree);
+            break;
+          case if_stmt:
+            res = validate_if(tree);
+            break;
+          case while_stmt:
+            res = validate_while(tree);
+            break;
+          case for_stmt:
+            res = validate_for(tree);
+            break;
+          case try_stmt:
+            res = validate_try(tree);
+            break;
+          case suite:
+            res = validate_suite(tree);
+            break;
+            /*
+             *  Expression nodes.
+             */
+          case testlist:
+            res = validate_testlist(tree);
+            break;
+          case yield_expr:
+            res = validate_yield_expr(tree);
+            break;
+          case testlist1:
+            res = validate_testlist1(tree);
+            break;
+          case test:
+            res = validate_test(tree);
+            break;
+          case and_test:
+            res = validate_and_test(tree);
+            break;
+          case not_test:
+            res = validate_not_test(tree);
+            break;
+          case comparison:
+            res = validate_comparison(tree);
+            break;
+          case exprlist:
+            res = validate_exprlist(tree);
+            break;
+          case comp_op:
+            res = validate_comp_op(tree);
+            break;
+          case expr:
+            res = validate_expr(tree);
+            break;
+          case xor_expr:
+            res = validate_xor_expr(tree);
+            break;
+          case and_expr:
+            res = validate_and_expr(tree);
+            break;
+          case shift_expr:
+            res = validate_shift_expr(tree);
+            break;
+          case arith_expr:
+            res = validate_arith_expr(tree);
+            break;
+          case term:
+            res = validate_term(tree);
+            break;
+          case factor:
+            res = validate_factor(tree);
+            break;
+          case power:
+            res = validate_power(tree);
+            break;
+          case atom:
+            res = validate_atom(tree);
+            break;
+
+          default:
+            /* Hopefully never reached! */
+            err_string("unrecognized node type");
+            res = 0;
+            break;
+        }
+        tree = next;
+    }
+    return (res);
+}
+
+
+static int
+validate_expr_tree(node *tree)
+{
+    int res = validate_eval_input(tree);
+
+    if (!res && !PyErr_Occurred())
+        err_string("could not validate expression tuple");
+
+    return (res);
+}
+
+
+/*  file_input:
+ *      (NEWLINE | stmt)* ENDMARKER
+ */
+static int
+validate_file_input(node *tree)
+{
+    int j;
+    int nch = NCH(tree) - 1;
+    int res = ((nch >= 0)
+               && validate_ntype(CHILD(tree, nch), ENDMARKER));
+
+    for (j = 0; res && (j < nch); ++j) {
+        if (TYPE(CHILD(tree, j)) == stmt)
+            res = validate_stmt(CHILD(tree, j));
+        else
+            res = validate_newline(CHILD(tree, j));
+    }
+    /*  This stays in to prevent any internal failures from getting to the
+     *  user.  Hopefully, this won't be needed.  If a user reports getting
+     *  this, we have some debugging to do.
+     */
+    if (!res && !PyErr_Occurred())
+        err_string("VALIDATION FAILURE: report this to the maintainer!");
+
+    return (res);
+}
+
+static int
+validate_encoding_decl(node *tree)
+{
+    int nch = NCH(tree);
+    int res = ((nch == 1)
+        && validate_file_input(CHILD(tree, 0)));
+
+    if (!res && !PyErr_Occurred())
+        err_string("Error Parsing encoding_decl");
+
+    return res;
+}
+
+static PyObject*
+pickle_constructor = NULL;
+
+
+static PyObject*
+parser__pickler(PyObject *self, PyObject *args)
+{
+    NOTE(ARGUNUSED(self))
+    PyObject *result = NULL;
+    PyObject *st = NULL;
+    PyObject *empty_dict = NULL;
+
+    if (PyArg_ParseTuple(args, "O!:_pickler", &PyST_Type, &st)) {
+        PyObject *newargs;
+        PyObject *tuple;
+
+        if ((empty_dict = PyDict_New()) == NULL)
+            goto finally;
+        if ((newargs = Py_BuildValue("Oi", st, 1)) == NULL)
+            goto finally;
+        tuple = parser_st2tuple((PyST_Object*)NULL, newargs, empty_dict);
+        if (tuple != NULL) {
+            result = Py_BuildValue("O(O)", pickle_constructor, tuple);
+            Py_DECREF(tuple);
+        }
+        Py_DECREF(empty_dict);
+        Py_DECREF(newargs);
+    }
+  finally:
+    Py_XDECREF(empty_dict);
+
+    return (result);
+}
+
+
+/*  Functions exported by this module.  Most of this should probably
+ *  be converted into an ST object with methods, but that is better
+ *  done directly in Python, allowing subclasses to be created directly.
+ *  We'd really have to write a wrapper around it all anyway to allow
+ *  inheritance.
+ */
+static PyMethodDef parser_functions[] =  {
+    {"ast2tuple",       (PyCFunction)parser_st2tuple,  PUBLIC_METHOD_TYPE,
+        PyDoc_STR("Creates a tuple-tree representation of an ST.")},
+    {"ast2list",        (PyCFunction)parser_st2list,   PUBLIC_METHOD_TYPE,
+        PyDoc_STR("Creates a list-tree representation of an ST.")},
+    {"compileast",      (PyCFunction)parser_compilest, PUBLIC_METHOD_TYPE,
+        PyDoc_STR("Compiles an ST object into a code object.")},
+    {"compilest",      (PyCFunction)parser_compilest,  PUBLIC_METHOD_TYPE,
+        PyDoc_STR("Compiles an ST object into a code object.")},
+    {"expr",            (PyCFunction)parser_expr,      PUBLIC_METHOD_TYPE,
+        PyDoc_STR("Creates an ST object from an expression.")},
+    {"isexpr",          (PyCFunction)parser_isexpr,    PUBLIC_METHOD_TYPE,
+        PyDoc_STR("Determines if an ST object was created from an expression.")},
+    {"issuite",         (PyCFunction)parser_issuite,   PUBLIC_METHOD_TYPE,
+        PyDoc_STR("Determines if an ST object was created from a suite.")},
+    {"suite",           (PyCFunction)parser_suite,     PUBLIC_METHOD_TYPE,
+        PyDoc_STR("Creates an ST object from a suite.")},
+    {"sequence2ast",    (PyCFunction)parser_tuple2st,  PUBLIC_METHOD_TYPE,
+        PyDoc_STR("Creates an ST object from a tree representation.")},
+    {"sequence2st",     (PyCFunction)parser_tuple2st,  PUBLIC_METHOD_TYPE,
+        PyDoc_STR("Creates an ST object from a tree representation.")},
+    {"st2tuple",        (PyCFunction)parser_st2tuple,  PUBLIC_METHOD_TYPE,
+        PyDoc_STR("Creates a tuple-tree representation of an ST.")},
+    {"st2list",         (PyCFunction)parser_st2list,   PUBLIC_METHOD_TYPE,
+        PyDoc_STR("Creates a list-tree representation of an ST.")},
+    {"tuple2ast",       (PyCFunction)parser_tuple2st,  PUBLIC_METHOD_TYPE,
+        PyDoc_STR("Creates an ST object from a tree representation.")},
+    {"tuple2st",        (PyCFunction)parser_tuple2st,  PUBLIC_METHOD_TYPE,
+        PyDoc_STR("Creates an ST object from a tree representation.")},
+
+    /* private stuff: support pickle module */
+    {"_pickler",        (PyCFunction)parser__pickler,  METH_VARARGS,
+        PyDoc_STR("Returns the pickle magic to allow ST objects to be pickled.")},
+
+    {NULL, NULL, 0, NULL}
+    };
+
+
+PyMODINIT_FUNC initparser(void);  /* supply a prototype */
+
+PyMODINIT_FUNC
+initparser(void)
+{
+    PyObject *module, *copyreg;
+
+    PyST_Type.ob_type = &PyType_Type;
+    module = Py_InitModule("parser", parser_functions);
+    if (module == NULL)
+    	return;
+
+    if (parser_error == 0)
+        parser_error = PyErr_NewException("parser.ParserError", NULL, NULL);
+
+    if (parser_error == 0)
+        /* caller will check PyErr_Occurred() */
+        return;
+    /* CAUTION:  The code next used to skip bumping the refcount on
+     * parser_error.  That's a disaster if initparser() gets called more
+     * than once.  By incref'ing, we ensure that each module dict that
+     * gets created owns its reference to the shared parser_error object,
+     * and the file static parser_error vrbl owns a reference too.
+     */
+    Py_INCREF(parser_error);
+    if (PyModule_AddObject(module, "ParserError", parser_error) != 0)
+        return;
+
+    Py_INCREF(&PyST_Type);
+    PyModule_AddObject(module, "ASTType", (PyObject*)&PyST_Type);
+    Py_INCREF(&PyST_Type);
+    PyModule_AddObject(module, "STType", (PyObject*)&PyST_Type);
+
+    PyModule_AddStringConstant(module, "__copyright__",
+                               parser_copyright_string);
+    PyModule_AddStringConstant(module, "__doc__",
+                               parser_doc_string);
+    PyModule_AddStringConstant(module, "__version__",
+                               parser_version_string);
+
+    /* Register to support pickling.
+     * If this fails, the import of this module will fail because an
+     * exception will be raised here; should we clear the exception?
+     */
+    copyreg = PyImport_ImportModule("copy_reg");
+    if (copyreg != NULL) {
+        PyObject *func, *pickler;
+
+        func = PyObject_GetAttrString(copyreg, "pickle");
+        pickle_constructor = PyObject_GetAttrString(module, "sequence2st");
+        pickler = PyObject_GetAttrString(module, "_pickler");
+        Py_XINCREF(pickle_constructor);
+        if ((func != NULL) && (pickle_constructor != NULL)
+            && (pickler != NULL)) {
+            PyObject *res;
+
+            res = PyObject_CallFunctionObjArgs(func, &PyST_Type, pickler,
+                                               pickle_constructor, NULL);
+            Py_XDECREF(res);
+        }
+        Py_XDECREF(func);
+        Py_XDECREF(pickle_constructor);
+        Py_XDECREF(pickler);
+        Py_DECREF(copyreg);
+    }
+}

Added: vendor/Python/current/Modules/posixmodule.c
===================================================================
--- vendor/Python/current/Modules/posixmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/posixmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,8752 @@
+
+/* POSIX module implementation */
+
+/* This file is also used for Windows NT/MS-Win and OS/2.  In that case the
+   module actually calls itself 'nt' or 'os2', not 'posix', and a few
+   functions are either unimplemented or implemented differently.  The source
+   assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent
+   of the compiler used.  Different compilers define their own feature
+   test macro, e.g. '__BORLANDC__' or '_MSC_VER'.  For OS/2, the compiler
+   independent macro PYOS_OS2 should be defined.  On OS/2 the default
+   compiler is assumed to be IBM's VisualAge C++ (VACPP).  PYCC_GCC is used
+   as the compiler specific macro for the EMX port of gcc to OS/2. */
+
+/* See also ../Dos/dosmodule.c */
+
+#ifdef __APPLE__
+   /*
+    * Step 1 of support for weak-linking a number of symbols existing on 
+    * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
+    * at the end of this file for more information.
+    */
+#  pragma weak lchown
+#  pragma weak statvfs
+#  pragma weak fstatvfs
+
+#endif /* __APPLE__ */
+
+#define PY_SSIZE_T_CLEAN
+
+#include "Python.h"
+#include "structseq.h"
+
+#if defined(__VMS)
+#    include <unixio.h>
+#endif /* defined(__VMS) */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+PyDoc_STRVAR(posix__doc__,
+"This module provides access to operating system functionality that is\n\
+standardized by the C Standard and the POSIX standard (a thinly\n\
+disguised Unix interface).  Refer to the library manual and\n\
+corresponding Unix manual entries for more information on calls.");
+
+#ifndef Py_USING_UNICODE
+/* This is used in signatures of functions. */
+#define Py_UNICODE void
+#endif
+
+#if defined(PYOS_OS2)
+#define  INCL_DOS
+#define  INCL_DOSERRORS
+#define  INCL_DOSPROCESS
+#define  INCL_NOPMAPI
+#include <os2.h>
+#if defined(PYCC_GCC)
+#include <ctype.h>
+#include <io.h>
+#include <stdio.h>
+#include <process.h>
+#endif
+#include "osdefs.h"
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif /* HAVE_SYS_TYPES_H */
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif /* HAVE_SYS_STAT_H */
+
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>		/* For WNOHANG */
+#endif
+
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif /* HAVE_FCNTL_H */
+
+#ifdef HAVE_GRP_H
+#include <grp.h>
+#endif
+
+#ifdef HAVE_SYSEXITS_H
+#include <sysexits.h>
+#endif /* HAVE_SYSEXITS_H */
+
+#ifdef HAVE_SYS_LOADAVG_H
+#include <sys/loadavg.h>
+#endif
+
+/* Various compilers have only certain posix functions */
+/* XXX Gosh I wish these were all moved into pyconfig.h */
+#if defined(PYCC_VACPP) && defined(PYOS_OS2)
+#include <process.h>
+#else
+#if defined(__WATCOMC__) && !defined(__QNX__)		/* Watcom compiler */
+#define HAVE_GETCWD     1
+#define HAVE_OPENDIR    1
+#define HAVE_SYSTEM	1
+#if defined(__OS2__)
+#define HAVE_EXECV      1
+#define HAVE_WAIT       1
+#endif
+#include <process.h>
+#else
+#ifdef __BORLANDC__		/* Borland compiler */
+#define HAVE_EXECV      1
+#define HAVE_GETCWD     1
+#define HAVE_OPENDIR    1
+#define HAVE_PIPE       1
+#define HAVE_POPEN      1
+#define HAVE_SYSTEM	1
+#define HAVE_WAIT       1
+#else
+#ifdef _MSC_VER		/* Microsoft compiler */
+#define HAVE_GETCWD     1
+#define HAVE_SPAWNV	1
+#define HAVE_EXECV      1
+#define HAVE_PIPE       1
+#define HAVE_POPEN      1
+#define HAVE_SYSTEM	1
+#define HAVE_CWAIT	1
+#define HAVE_FSYNC	1
+#define fsync _commit
+#else
+#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
+/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
+#else			/* all other compilers */
+/* Unix functions that the configure script doesn't check for */
+#define HAVE_EXECV      1
+#define HAVE_FORK       1
+#if defined(__USLC__) && defined(__SCO_VERSION__)	/* SCO UDK Compiler */
+#define HAVE_FORK1      1
+#endif
+#define HAVE_GETCWD     1
+#define HAVE_GETEGID    1
+#define HAVE_GETEUID    1
+#define HAVE_GETGID     1
+#define HAVE_GETPPID    1
+#define HAVE_GETUID     1
+#define HAVE_KILL       1
+#define HAVE_OPENDIR    1
+#define HAVE_PIPE       1
+#ifndef __rtems__
+#define HAVE_POPEN      1
+#endif
+#define HAVE_SYSTEM	1
+#define HAVE_WAIT       1
+#define HAVE_TTYNAME	1
+#endif  /* PYOS_OS2 && PYCC_GCC && __VMS */
+#endif  /* _MSC_VER */
+#endif  /* __BORLANDC__ */
+#endif  /* ! __WATCOMC__ || __QNX__ */
+#endif /* ! __IBMC__ */
+
+#ifndef _MSC_VER
+
+#if defined(__sgi)&&_COMPILER_VERSION>=700
+/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
+   (default) */
+extern char        *ctermid_r(char *);
+#endif
+
+#ifndef HAVE_UNISTD_H
+#if defined(PYCC_VACPP)
+extern int mkdir(char *);
+#else
+#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
+extern int mkdir(const char *);
+#else
+extern int mkdir(const char *, mode_t);
+#endif
+#endif
+#if defined(__IBMC__) || defined(__IBMCPP__)
+extern int chdir(char *);
+extern int rmdir(char *);
+#else
+extern int chdir(const char *);
+extern int rmdir(const char *);
+#endif
+#ifdef __BORLANDC__
+extern int chmod(const char *, int);
+#else
+extern int chmod(const char *, mode_t);
+#endif
+extern int chown(const char *, uid_t, gid_t);
+extern char *getcwd(char *, int);
+extern char *strerror(int);
+extern int link(const char *, const char *);
+extern int rename(const char *, const char *);
+extern int stat(const char *, struct stat *);
+extern int unlink(const char *);
+extern int pclose(FILE *);
+#ifdef HAVE_SYMLINK
+extern int symlink(const char *, const char *);
+#endif /* HAVE_SYMLINK */
+#ifdef HAVE_LSTAT
+extern int lstat(const char *, struct stat *);
+#endif /* HAVE_LSTAT */
+#endif /* !HAVE_UNISTD_H */
+
+#endif /* !_MSC_VER */
+
+#ifdef HAVE_UTIME_H
+#include <utime.h>
+#endif /* HAVE_UTIME_H */
+
+#ifdef HAVE_SYS_UTIME_H
+#include <sys/utime.h>
+#define HAVE_UTIME_H /* pretend we do for the rest of this file */
+#endif /* HAVE_SYS_UTIME_H */
+
+#ifdef HAVE_SYS_TIMES_H
+#include <sys/times.h>
+#endif /* HAVE_SYS_TIMES_H */
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif /* HAVE_SYS_PARAM_H */
+
+#ifdef HAVE_SYS_UTSNAME_H
+#include <sys/utsname.h>
+#endif /* HAVE_SYS_UTSNAME_H */
+
+#ifdef HAVE_DIRENT_H
+#include <dirent.h>
+#define NAMLEN(dirent) strlen((dirent)->d_name)
+#else
+#if defined(__WATCOMC__) && !defined(__QNX__)
+#include <direct.h>
+#define NAMLEN(dirent) strlen((dirent)->d_name)
+#else
+#define dirent direct
+#define NAMLEN(dirent) (dirent)->d_namlen
+#endif
+#ifdef HAVE_SYS_NDIR_H
+#include <sys/ndir.h>
+#endif
+#ifdef HAVE_SYS_DIR_H
+#include <sys/dir.h>
+#endif
+#ifdef HAVE_NDIR_H
+#include <ndir.h>
+#endif
+#endif
+
+#ifdef _MSC_VER
+#ifdef HAVE_DIRECT_H
+#include <direct.h>
+#endif
+#ifdef HAVE_IO_H
+#include <io.h>
+#endif
+#ifdef HAVE_PROCESS_H
+#include <process.h>
+#endif
+#include "osdefs.h"
+#define _WIN32_WINNT 0x0400	  /* Needed for CryptoAPI on some systems */
+#include <windows.h>
+#include <shellapi.h>	/* for ShellExecute() */
+#define popen	_popen
+#define pclose	_pclose
+#endif /* _MSC_VER */
+
+#if defined(PYCC_VACPP) && defined(PYOS_OS2)
+#include <io.h>
+#endif /* OS2 */
+
+#ifndef MAXPATHLEN
+#if defined(PATH_MAX) && PATH_MAX > 1024
+#define MAXPATHLEN PATH_MAX
+#else
+#define MAXPATHLEN 1024
+#endif
+#endif /* MAXPATHLEN */
+
+#ifdef UNION_WAIT
+/* Emulate some macros on systems that have a union instead of macros */
+
+#ifndef WIFEXITED
+#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
+#endif
+
+#ifndef WEXITSTATUS
+#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
+#endif
+
+#ifndef WTERMSIG
+#define WTERMSIG(u_wait) ((u_wait).w_termsig)
+#endif
+
+#define WAIT_TYPE union wait
+#define WAIT_STATUS_INT(s) (s.w_status)
+
+#else /* !UNION_WAIT */
+#define WAIT_TYPE int
+#define WAIT_STATUS_INT(s) (s)
+#endif /* UNION_WAIT */
+
+/* Don't use the "_r" form if we don't need it (also, won't have a
+   prototype for it, at least on Solaris -- maybe others as well?). */
+#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
+#define USE_CTERMID_R
+#endif
+
+#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
+#define USE_TMPNAM_R
+#endif
+
+/* choose the appropriate stat and fstat functions and return structs */
+#undef STAT
+#if defined(MS_WIN64) || defined(MS_WINDOWS)
+#	define STAT win32_stat
+#	define FSTAT win32_fstat
+#	define STRUCT_STAT struct win32_stat
+#else
+#	define STAT stat
+#	define FSTAT fstat
+#	define STRUCT_STAT struct stat
+#endif
+
+#if defined(MAJOR_IN_MKDEV)
+#include <sys/mkdev.h>
+#else
+#if defined(MAJOR_IN_SYSMACROS)
+#include <sys/sysmacros.h>
+#endif
+#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
+#include <sys/mkdev.h>
+#endif
+#endif
+
+/* Return a dictionary corresponding to the POSIX environment table */
+#ifdef WITH_NEXT_FRAMEWORK
+/* On Darwin/MacOSX a shared library or framework has no access to
+** environ directly, we must obtain it with _NSGetEnviron().
+*/
+#include <crt_externs.h>
+static char **environ;
+#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
+extern char **environ;
+#endif /* !_MSC_VER */
+
+static PyObject *
+convertenviron(void)
+{
+	PyObject *d;
+	char **e;
+	d = PyDict_New();
+	if (d == NULL)
+		return NULL;
+#ifdef WITH_NEXT_FRAMEWORK
+	if (environ == NULL)
+		environ = *_NSGetEnviron();
+#endif
+	if (environ == NULL)
+		return d;
+	/* This part ignores errors */
+	for (e = environ; *e != NULL; e++) {
+		PyObject *k;
+		PyObject *v;
+		char *p = strchr(*e, '=');
+		if (p == NULL)
+			continue;
+		k = PyString_FromStringAndSize(*e, (int)(p-*e));
+		if (k == NULL) {
+			PyErr_Clear();
+			continue;
+		}
+		v = PyString_FromString(p+1);
+		if (v == NULL) {
+			PyErr_Clear();
+			Py_DECREF(k);
+			continue;
+		}
+		if (PyDict_GetItem(d, k) == NULL) {
+			if (PyDict_SetItem(d, k, v) != 0)
+				PyErr_Clear();
+		}
+		Py_DECREF(k);
+		Py_DECREF(v);
+	}
+#if defined(PYOS_OS2)
+    {
+        APIRET rc;
+        char   buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
+
+        rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
+	if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
+            PyObject *v = PyString_FromString(buffer);
+		    PyDict_SetItemString(d, "BEGINLIBPATH", v);
+            Py_DECREF(v);
+        }
+        rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
+        if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
+            PyObject *v = PyString_FromString(buffer);
+		    PyDict_SetItemString(d, "ENDLIBPATH", v);
+            Py_DECREF(v);
+        }
+    }
+#endif
+	return d;
+}
+
+
+/* Set a POSIX-specific error from errno, and return NULL */
+
+static PyObject *
+posix_error(void)
+{
+	return PyErr_SetFromErrno(PyExc_OSError);
+}
+static PyObject *
+posix_error_with_filename(char* name)
+{
+	return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
+}
+
+#ifdef Py_WIN_WIDE_FILENAMES
+static PyObject *
+posix_error_with_unicode_filename(Py_UNICODE* name)
+{
+	return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
+}
+#endif /* Py_WIN_WIDE_FILENAMES */
+
+
+static PyObject *
+posix_error_with_allocated_filename(char* name)
+{
+	PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
+	PyMem_Free(name);
+	return rc;
+}
+
+#ifdef MS_WINDOWS
+static PyObject *
+win32_error(char* function, char* filename)
+{
+	/* XXX We should pass the function name along in the future.
+	   (_winreg.c also wants to pass the function name.)
+	   This would however require an additional param to the
+	   Windows error object, which is non-trivial.
+	*/
+	errno = GetLastError();
+	if (filename)
+		return PyErr_SetFromWindowsErrWithFilename(errno, filename);
+	else
+		return PyErr_SetFromWindowsErr(errno);
+}
+
+#ifdef Py_WIN_WIDE_FILENAMES
+static PyObject *
+win32_error_unicode(char* function, Py_UNICODE* filename)
+{
+	/* XXX - see win32_error for comments on 'function' */
+	errno = GetLastError();
+	if (filename)
+		return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
+	else
+		return PyErr_SetFromWindowsErr(errno);
+}
+
+static PyObject *_PyUnicode_FromFileSystemEncodedObject(register PyObject *obj)
+{
+}
+
+/* Function suitable for O& conversion */
+static int
+convert_to_unicode(PyObject *arg, void* _param)
+{
+	PyObject **param = (PyObject**)_param;
+	if (PyUnicode_CheckExact(arg)) {
+		Py_INCREF(arg);
+		*param = arg;
+	} 
+	else if (PyUnicode_Check(arg)) {
+		/* For a Unicode subtype that's not a Unicode object,
+		   return a true Unicode object with the same data. */
+		*param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(arg),
+					       PyUnicode_GET_SIZE(arg));
+		return *param != NULL;
+	}
+	else
+		*param = PyUnicode_FromEncodedObject(arg,
+				                     Py_FileSystemDefaultEncoding,
+					             "strict");
+	return (*param) != NULL;
+}
+
+#endif /* Py_WIN_WIDE_FILENAMES */
+
+#endif
+
+#if defined(PYOS_OS2)
+/**********************************************************************
+ *         Helper Function to Trim and Format OS/2 Messages
+ **********************************************************************/
+    static void
+os2_formatmsg(char *msgbuf, int msglen, char *reason)
+{
+    msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
+
+    if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
+        char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
+
+        while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
+            *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
+    }
+
+    /* Add Optional Reason Text */
+    if (reason) {
+        strcat(msgbuf, " : ");
+        strcat(msgbuf, reason);
+    }
+}
+
+/**********************************************************************
+ *             Decode an OS/2 Operating System Error Code
+ *
+ * A convenience function to lookup an OS/2 error code and return a
+ * text message we can use to raise a Python exception.
+ *
+ * Notes:
+ *   The messages for errors returned from the OS/2 kernel reside in
+ *   the file OSO001.MSG in the \OS2 directory hierarchy.
+ *
+ **********************************************************************/
+    static char *
+os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
+{
+    APIRET rc;
+    ULONG  msglen;
+
+    /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
+    Py_BEGIN_ALLOW_THREADS
+    rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
+                       errorcode, "oso001.msg", &msglen);
+    Py_END_ALLOW_THREADS
+
+    if (rc == NO_ERROR)
+        os2_formatmsg(msgbuf, msglen, reason);
+    else
+        PyOS_snprintf(msgbuf, msgbuflen,
+        	      "unknown OS error #%d", errorcode);
+
+    return msgbuf;
+}
+
+/* Set an OS/2-specific error and return NULL.  OS/2 kernel
+   errors are not in a global variable e.g. 'errno' nor are
+   they congruent with posix error numbers. */
+
+static PyObject * os2_error(int code)
+{
+    char text[1024];
+    PyObject *v;
+
+    os2_strerror(text, sizeof(text), code, "");
+
+    v = Py_BuildValue("(is)", code, text);
+    if (v != NULL) {
+        PyErr_SetObject(PyExc_OSError, v);
+        Py_DECREF(v);
+    }
+    return NULL; /* Signal to Python that an Exception is Pending */
+}
+
+#endif /* OS2 */
+
+/* POSIX generic methods */
+
+static PyObject *
+posix_fildes(PyObject *fdobj, int (*func)(int))
+{
+	int fd;
+	int res;
+	fd = PyObject_AsFileDescriptor(fdobj);
+	if (fd < 0)
+		return NULL;
+	Py_BEGIN_ALLOW_THREADS
+	res = (*func)(fd);
+	Py_END_ALLOW_THREADS
+	if (res < 0)
+		return posix_error();
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+#ifdef Py_WIN_WIDE_FILENAMES
+static int
+unicode_file_names(void)
+{
+	static int canusewide = -1;
+	if (canusewide == -1) {
+		/* As per doc for ::GetVersion(), this is the correct test for
+		   the Windows NT family. */
+		canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
+	}
+	return canusewide;
+}
+#endif
+
+static PyObject *
+posix_1str(PyObject *args, char *format, int (*func)(const char*))
+{
+	char *path1 = NULL;
+	int res;
+	if (!PyArg_ParseTuple(args, format,
+	                      Py_FileSystemDefaultEncoding, &path1))
+		return NULL;
+	Py_BEGIN_ALLOW_THREADS
+	res = (*func)(path1);
+	Py_END_ALLOW_THREADS
+	if (res < 0)
+		return posix_error_with_allocated_filename(path1);
+	PyMem_Free(path1);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+posix_2str(PyObject *args,
+	   char *format,
+	   int (*func)(const char *, const char *))
+{
+	char *path1 = NULL, *path2 = NULL;
+	int res;
+	if (!PyArg_ParseTuple(args, format,
+	                      Py_FileSystemDefaultEncoding, &path1,
+	                      Py_FileSystemDefaultEncoding, &path2))
+		return NULL;
+	Py_BEGIN_ALLOW_THREADS
+	res = (*func)(path1, path2);
+	Py_END_ALLOW_THREADS
+	PyMem_Free(path1);
+	PyMem_Free(path2);
+	if (res != 0)
+		/* XXX how to report both path1 and path2??? */
+		return posix_error();
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+#ifdef Py_WIN_WIDE_FILENAMES
+static PyObject*
+win32_1str(PyObject* args, char* func, 
+	   char* format, BOOL (__stdcall *funcA)(LPCSTR), 
+	   char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
+{
+	PyObject *uni;
+	char *ansi;
+	BOOL result;
+	if (unicode_file_names()) {
+		if (!PyArg_ParseTuple(args, wformat, &uni))
+			PyErr_Clear();
+		else {
+			Py_BEGIN_ALLOW_THREADS
+			result = funcW(PyUnicode_AsUnicode(uni));
+			Py_END_ALLOW_THREADS
+			if (!result)
+				return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
+			Py_INCREF(Py_None);
+			return Py_None;
+		}
+	}
+	if (!PyArg_ParseTuple(args, format, &ansi))
+		return NULL;
+	Py_BEGIN_ALLOW_THREADS
+	result = funcA(ansi);
+	Py_END_ALLOW_THREADS
+	if (!result)
+		return win32_error(func, ansi);
+	Py_INCREF(Py_None);
+	return Py_None;
+
+}
+
+/* This is a reimplementation of the C library's chdir function,
+   but one that produces Win32 errors instead of DOS error codes.
+   chdir is essentially a wrapper around SetCurrentDirectory; however,
+   it also needs to set "magic" environment variables indicating
+   the per-drive current directory, which are of the form =<drive>: */
+BOOL __stdcall
+win32_chdir(LPCSTR path)
+{
+	char new_path[MAX_PATH+1];
+	int result;
+	char env[4] = "=x:";
+
+	if(!SetCurrentDirectoryA(path))
+		return FALSE;
+	result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
+	if (!result)
+		return FALSE;
+	/* In the ANSI API, there should not be any paths longer
+	   than MAX_PATH. */
+	assert(result <= MAX_PATH+1);
+	if (strncmp(new_path, "\\\\", 2) == 0 ||
+	    strncmp(new_path, "//", 2) == 0)
+	    /* UNC path, nothing to do. */
+	    return TRUE;
+	env[1] = new_path[0];
+	return SetEnvironmentVariableA(env, new_path);
+}
+
+/* The Unicode version differs from the ANSI version
+   since the current directory might exceed MAX_PATH characters */
+BOOL __stdcall
+win32_wchdir(LPCWSTR path)
+{
+	wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
+	int result;
+	wchar_t env[4] = L"=x:";
+
+	if(!SetCurrentDirectoryW(path))
+		return FALSE;
+	result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
+	if (!result)
+		return FALSE;
+	if (result > MAX_PATH+1) {
+		new_path = malloc(result);
+		if (!new_path) {
+			SetLastError(ERROR_OUTOFMEMORY);
+			return FALSE;
+		}
+	}
+	if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
+	    wcsncmp(new_path, L"//", 2) == 0)
+	    /* UNC path, nothing to do. */
+	    return TRUE;
+	env[1] = new_path[0];
+	result = SetEnvironmentVariableW(env, new_path);
+	if (new_path != _new_path)
+		free(new_path);
+	return result;
+}
+#endif
+
+#ifdef MS_WINDOWS
+/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
+   - time stamps are restricted to second resolution
+   - file modification times suffer from forth-and-back conversions between
+     UTC and local time
+   Therefore, we implement our own stat, based on the Win32 API directly.
+*/
+#define HAVE_STAT_NSEC 1 
+
+struct win32_stat{
+    int st_dev;
+    __int64 st_ino;
+    unsigned short st_mode;
+    int st_nlink;
+    int st_uid;
+    int st_gid;
+    int st_rdev;
+    __int64 st_size;
+    int st_atime;
+    int st_atime_nsec;
+    int st_mtime;
+    int st_mtime_nsec;
+    int st_ctime;
+    int st_ctime_nsec;
+};
+
+static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
+
+static void
+FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
+{
+	/* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
+	/* Cannot simply cast and dereference in_ptr, 
+	   since it might not be aligned properly */
+	__int64 in;
+	memcpy(&in, in_ptr, sizeof(in));
+	*nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
+	/* XXX Win32 supports time stamps past 2038; we currently don't */
+	*time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
+}
+
+static void
+time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr)
+{
+	/* XXX endianness */
+	__int64 out;
+	out = time_in + secs_between_epochs;
+	out = out * 10000000 + nsec_in / 100;
+	memcpy(out_ptr, &out, sizeof(out));
+}
+
+/* Below, we *know* that ugo+r is 0444 */
+#if _S_IREAD != 0400
+#error Unsupported C library
+#endif
+static int
+attributes_to_mode(DWORD attr)
+{
+	int m = 0;
+	if (attr & FILE_ATTRIBUTE_DIRECTORY)
+		m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
+	else
+		m |= _S_IFREG;
+	if (attr & FILE_ATTRIBUTE_READONLY)
+		m |= 0444;
+	else
+		m |= 0666;
+	return m;
+}
+
+static int
+attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
+{
+	memset(result, 0, sizeof(*result));
+	result->st_mode = attributes_to_mode(info->dwFileAttributes);
+	result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
+	FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
+	FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
+	FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
+
+	return 0;
+}
+
+/* Emulate GetFileAttributesEx[AW] on Windows 95 */
+static int checked = 0;
+static BOOL (CALLBACK *gfaxa)(LPCSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
+static BOOL (CALLBACK *gfaxw)(LPCWSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
+static void
+check_gfax()
+{
+	HINSTANCE hKernel32;
+	if (checked)
+	    return;
+	checked = 1;
+	hKernel32 = GetModuleHandle("KERNEL32");
+	*(FARPROC*)&gfaxa = GetProcAddress(hKernel32, "GetFileAttributesExA");
+	*(FARPROC*)&gfaxw = GetProcAddress(hKernel32, "GetFileAttributesExW");
+}
+
+static BOOL
+attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
+{
+	HANDLE hFindFile;
+	WIN32_FIND_DATAA FileData;
+	hFindFile = FindFirstFileA(pszFile, &FileData);
+	if (hFindFile == INVALID_HANDLE_VALUE)
+		return FALSE;
+	FindClose(hFindFile);
+	pfad->dwFileAttributes = FileData.dwFileAttributes;
+	pfad->ftCreationTime   = FileData.ftCreationTime;
+	pfad->ftLastAccessTime = FileData.ftLastAccessTime;
+	pfad->ftLastWriteTime  = FileData.ftLastWriteTime;
+	pfad->nFileSizeHigh    = FileData.nFileSizeHigh;
+	pfad->nFileSizeLow     = FileData.nFileSizeLow;
+	return TRUE;
+}
+
+static BOOL
+attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
+{
+	HANDLE hFindFile;
+	WIN32_FIND_DATAW FileData;
+	hFindFile = FindFirstFileW(pszFile, &FileData);
+	if (hFindFile == INVALID_HANDLE_VALUE)
+		return FALSE;
+	FindClose(hFindFile);
+	pfad->dwFileAttributes = FileData.dwFileAttributes;
+	pfad->ftCreationTime   = FileData.ftCreationTime;
+	pfad->ftLastAccessTime = FileData.ftLastAccessTime;
+	pfad->ftLastWriteTime  = FileData.ftLastWriteTime;
+	pfad->nFileSizeHigh    = FileData.nFileSizeHigh;
+	pfad->nFileSizeLow     = FileData.nFileSizeLow;
+	return TRUE;
+}
+
+static BOOL WINAPI
+Py_GetFileAttributesExA(LPCSTR pszFile, 
+		       GET_FILEEX_INFO_LEVELS level,
+                       LPVOID pv)
+{
+	BOOL result;
+	LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
+	/* First try to use the system's implementation, if that is
+	   available and either succeeds to gives an error other than
+	   that it isn't implemented. */
+	check_gfax();
+	if (gfaxa) {
+		result = gfaxa(pszFile, level, pv);
+		if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+			return result;
+	}
+	/* It's either not present, or not implemented.
+	   Emulate using FindFirstFile. */
+	if (level != GetFileExInfoStandard) {
+		SetLastError(ERROR_INVALID_PARAMETER);
+		return FALSE;
+	}
+	/* Use GetFileAttributes to validate that the file name
+	   does not contain wildcards (which FindFirstFile would
+	   accept). */
+	if (GetFileAttributesA(pszFile) == 0xFFFFFFFF)
+		return FALSE;
+	return attributes_from_dir(pszFile, pfad);
+}
+
+static BOOL WINAPI
+Py_GetFileAttributesExW(LPCWSTR pszFile, 
+		       GET_FILEEX_INFO_LEVELS level,
+                       LPVOID pv)
+{
+	BOOL result;
+	LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
+	/* First try to use the system's implementation, if that is
+	   available and either succeeds to gives an error other than
+	   that it isn't implemented. */
+	check_gfax();
+	if (gfaxa) {
+		result = gfaxw(pszFile, level, pv);
+		if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+			return result;
+	}
+	/* It's either not present, or not implemented.
+	   Emulate using FindFirstFile. */
+	if (level != GetFileExInfoStandard) {
+		SetLastError(ERROR_INVALID_PARAMETER);
+		return FALSE;
+	}
+	/* Use GetFileAttributes to validate that the file name
+	   does not contain wildcards (which FindFirstFile would
+	   accept). */
+	if (GetFileAttributesW(pszFile) == 0xFFFFFFFF)
+		return FALSE;
+	return attributes_from_dir_w(pszFile, pfad);
+}
+
+static int 
+win32_stat(const char* path, struct win32_stat *result)
+{
+	WIN32_FILE_ATTRIBUTE_DATA info;
+	int code;
+	char *dot;
+	/* XXX not supported on Win95 and NT 3.x */
+	if (!Py_GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
+		if (GetLastError() != ERROR_SHARING_VIOLATION) {
+			/* Protocol violation: we explicitly clear errno, instead of
+			   setting it to a POSIX error. Callers should use GetLastError. */
+			errno = 0;
+			return -1;
+		} else {
+			/* Could not get attributes on open file. Fall back to
+			   reading the directory. */
+			if (!attributes_from_dir(path, &info)) {
+				/* Very strange. This should not fail now */
+				errno = 0;
+				return -1;
+			}
+		}
+	}
+	code = attribute_data_to_stat(&info, result);
+	if (code != 0)
+		return code;
+	/* Set S_IFEXEC if it is an .exe, .bat, ... */
+	dot = strrchr(path, '.');
+	if (dot) {
+		if (stricmp(dot, ".bat") == 0 ||
+		stricmp(dot, ".cmd") == 0 ||
+		stricmp(dot, ".exe") == 0 ||
+		stricmp(dot, ".com") == 0)
+		result->st_mode |= 0111;
+	}
+	return code;
+}
+
+static int 
+win32_wstat(const wchar_t* path, struct win32_stat *result)
+{
+	int code;
+	const wchar_t *dot;
+	WIN32_FILE_ATTRIBUTE_DATA info;
+	/* XXX not supported on Win95 and NT 3.x */
+	if (!Py_GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
+		if (GetLastError() != ERROR_SHARING_VIOLATION) {
+			/* Protocol violation: we explicitly clear errno, instead of
+			   setting it to a POSIX error. Callers should use GetLastError. */
+			errno = 0;
+			return -1;
+		} else {
+			/* Could not get attributes on open file. Fall back to
+			   reading the directory. */
+			if (!attributes_from_dir_w(path, &info)) {
+				/* Very strange. This should not fail now */
+				errno = 0;
+				return -1;
+			}
+		}
+	}
+	code = attribute_data_to_stat(&info, result);
+	if (code < 0)
+		return code;
+	/* Set IFEXEC if it is an .exe, .bat, ... */
+	dot = wcsrchr(path, '.');
+	if (dot) {
+		if (_wcsicmp(dot, L".bat") == 0 ||
+		    _wcsicmp(dot, L".cmd") == 0 ||
+		    _wcsicmp(dot, L".exe") == 0 ||
+		    _wcsicmp(dot, L".com") == 0)
+			result->st_mode |= 0111;
+	}
+	return code;
+}
+
+static int
+win32_fstat(int file_number, struct win32_stat *result)
+{
+	BY_HANDLE_FILE_INFORMATION info;
+	HANDLE h;
+	int type;
+    
+	h = (HANDLE)_get_osfhandle(file_number);
+    
+	/* Protocol violation: we explicitly clear errno, instead of
+	   setting it to a POSIX error. Callers should use GetLastError. */
+	errno = 0;
+
+	if (h == INVALID_HANDLE_VALUE) {
+    		/* This is really a C library error (invalid file handle).
+		   We set the Win32 error to the closes one matching. */
+		SetLastError(ERROR_INVALID_HANDLE);
+		return -1;
+	}
+	memset(result, 0, sizeof(*result));
+
+	type = GetFileType(h);
+	if (type == FILE_TYPE_UNKNOWN) {
+	    DWORD error = GetLastError();
+	    if (error != 0) {
+		return -1;
+	    }
+	    /* else: valid but unknown file */
+	}
+
+	if (type != FILE_TYPE_DISK) {
+		if (type == FILE_TYPE_CHAR)
+			result->st_mode = _S_IFCHR;
+		else if (type == FILE_TYPE_PIPE)
+			result->st_mode = _S_IFIFO;
+		return 0;
+	}
+
+	if (!GetFileInformationByHandle(h, &info)) {
+		return -1;
+	}
+
+	/* similar to stat() */
+	result->st_mode = attributes_to_mode(info.dwFileAttributes);
+	result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
+	FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
+	FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
+	FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
+	/* specific to fstat() */
+	result->st_nlink = info.nNumberOfLinks;
+	result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
+	return 0;
+}
+
+#endif /* MS_WINDOWS */
+
+PyDoc_STRVAR(stat_result__doc__,
+"stat_result: Result from stat or lstat.\n\n\
+This object may be accessed either as a tuple of\n\
+  (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
+or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
+\n\
+Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
+or st_flags, they are available as attributes only.\n\
+\n\
+See os.stat for more information.");
+
+static PyStructSequence_Field stat_result_fields[] = {
+	{"st_mode",    "protection bits"},
+	{"st_ino",     "inode"},
+	{"st_dev",     "device"},
+	{"st_nlink",   "number of hard links"},
+	{"st_uid",     "user ID of owner"},
+	{"st_gid",     "group ID of owner"},
+	{"st_size",    "total size, in bytes"},
+	/* The NULL is replaced with PyStructSequence_UnnamedField later. */
+	{NULL,   "integer time of last access"},
+	{NULL,   "integer time of last modification"},
+	{NULL,   "integer time of last change"},
+	{"st_atime",   "time of last access"},
+	{"st_mtime",   "time of last modification"},
+	{"st_ctime",   "time of last change"},
+#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
+	{"st_blksize", "blocksize for filesystem I/O"},
+#endif
+#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
+	{"st_blocks",  "number of blocks allocated"},
+#endif
+#ifdef HAVE_STRUCT_STAT_ST_RDEV
+	{"st_rdev",    "device type (if inode device)"},
+#endif
+#ifdef HAVE_STRUCT_STAT_ST_FLAGS
+	{"st_flags",   "user defined flags for file"},
+#endif
+#ifdef HAVE_STRUCT_STAT_ST_GEN
+	{"st_gen",    "generation number"},
+#endif
+#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
+	{"st_birthtime",   "time of creation"},
+#endif
+	{0}
+};
+
+#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
+#define ST_BLKSIZE_IDX 13
+#else
+#define ST_BLKSIZE_IDX 12
+#endif
+
+#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
+#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
+#else
+#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
+#endif
+
+#ifdef HAVE_STRUCT_STAT_ST_RDEV
+#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
+#else
+#define ST_RDEV_IDX ST_BLOCKS_IDX
+#endif
+
+#ifdef HAVE_STRUCT_STAT_ST_FLAGS
+#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
+#else
+#define ST_FLAGS_IDX ST_RDEV_IDX
+#endif
+
+#ifdef HAVE_STRUCT_STAT_ST_GEN
+#define ST_GEN_IDX (ST_FLAGS_IDX+1)
+#else
+#define ST_GEN_IDX ST_FLAGS_IDX
+#endif
+
+#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
+#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
+#else
+#define ST_BIRTHTIME_IDX ST_GEN_IDX
+#endif
+
+static PyStructSequence_Desc stat_result_desc = {
+	"stat_result", /* name */
+	stat_result__doc__, /* doc */
+	stat_result_fields,
+	10
+};
+
+PyDoc_STRVAR(statvfs_result__doc__,
+"statvfs_result: Result from statvfs or fstatvfs.\n\n\
+This object may be accessed either as a tuple of\n\
+  (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
+or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
+\n\
+See os.statvfs for more information.");
+
+static PyStructSequence_Field statvfs_result_fields[] = {
+        {"f_bsize",  },
+        {"f_frsize", },
+        {"f_blocks", },
+        {"f_bfree",  },
+        {"f_bavail", },
+        {"f_files",  },
+        {"f_ffree",  },
+        {"f_favail", },
+        {"f_flag",   },
+        {"f_namemax",},
+        {0}
+};
+
+static PyStructSequence_Desc statvfs_result_desc = {
+	"statvfs_result", /* name */
+	statvfs_result__doc__, /* doc */
+	statvfs_result_fields,
+	10
+};
+
+static int initialized;
+static PyTypeObject StatResultType;
+static PyTypeObject StatVFSResultType;
+static newfunc structseq_new;
+
+static PyObject *
+statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	PyStructSequence *result;
+	int i;
+
+	result = (PyStructSequence*)structseq_new(type, args, kwds);
+	if (!result)
+		return NULL;
+	/* If we have been initialized from a tuple,
+	   st_?time might be set to None. Initialize it
+	   from the int slots.  */
+	for (i = 7; i <= 9; i++) {
+		if (result->ob_item[i+3] == Py_None) {
+			Py_DECREF(Py_None);
+			Py_INCREF(result->ob_item[i]);
+			result->ob_item[i+3] = result->ob_item[i];
+		}
+	}
+	return (PyObject*)result;
+}
+
+
+
+/* If true, st_?time is float. */
+static int _stat_float_times = 1;
+
+PyDoc_STRVAR(stat_float_times__doc__,
+"stat_float_times([newval]) -> oldval\n\n\
+Determine whether os.[lf]stat represents time stamps as float objects.\n\
+If newval is True, future calls to stat() return floats, if it is False,\n\
+future calls return ints. \n\
+If newval is omitted, return the current setting.\n");
+
+static PyObject*
+stat_float_times(PyObject* self, PyObject *args)
+{
+	int newval = -1;
+	if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
+		return NULL;
+	if (newval == -1)
+		/* Return old value */
+		return PyBool_FromLong(_stat_float_times);
+	_stat_float_times = newval;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static void
+fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
+{
+	PyObject *fval,*ival;
+#if SIZEOF_TIME_T > SIZEOF_LONG
+	ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
+#else
+	ival = PyInt_FromLong((long)sec);
+#endif
+	if (!ival)
+		return;
+	if (_stat_float_times) {
+		fval = PyFloat_FromDouble(sec + 1e-9*nsec);
+	} else {
+		fval = ival;
+		Py_INCREF(fval);
+	}
+	PyStructSequence_SET_ITEM(v, index, ival);
+	PyStructSequence_SET_ITEM(v, index+3, fval);
+}
+
+/* pack a system stat C structure into the Python stat tuple
+   (used by posix_stat() and posix_fstat()) */
+static PyObject*
+_pystat_fromstructstat(STRUCT_STAT *st)
+{
+	unsigned long ansec, mnsec, cnsec;
+	PyObject *v = PyStructSequence_New(&StatResultType);
+	if (v == NULL)
+		return NULL;
+
+        PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
+#ifdef HAVE_LARGEFILE_SUPPORT
+        PyStructSequence_SET_ITEM(v, 1,
+				  PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
+#else
+        PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st->st_ino));
+#endif
+#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
+        PyStructSequence_SET_ITEM(v, 2,
+				  PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
+#else
+        PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st->st_dev));
+#endif
+        PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink));
+        PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st->st_uid));
+        PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st->st_gid));
+#ifdef HAVE_LARGEFILE_SUPPORT
+        PyStructSequence_SET_ITEM(v, 6,
+				  PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
+#else
+        PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st->st_size));
+#endif
+
+#if defined(HAVE_STAT_TV_NSEC)
+	ansec = st->st_atim.tv_nsec;
+	mnsec = st->st_mtim.tv_nsec;
+	cnsec = st->st_ctim.tv_nsec;
+#elif defined(HAVE_STAT_TV_NSEC2)
+	ansec = st->st_atimespec.tv_nsec;
+	mnsec = st->st_mtimespec.tv_nsec;
+	cnsec = st->st_ctimespec.tv_nsec;
+#elif defined(HAVE_STAT_NSEC)
+	ansec = st->st_atime_nsec;
+	mnsec = st->st_mtime_nsec;
+	cnsec = st->st_ctime_nsec;
+#else
+	ansec = mnsec = cnsec = 0;
+#endif
+	fill_time(v, 7, st->st_atime, ansec);
+	fill_time(v, 8, st->st_mtime, mnsec);
+	fill_time(v, 9, st->st_ctime, cnsec);
+
+#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
+	PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
+			 PyInt_FromLong((long)st->st_blksize));
+#endif
+#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
+	PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
+			 PyInt_FromLong((long)st->st_blocks));
+#endif
+#ifdef HAVE_STRUCT_STAT_ST_RDEV
+	PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
+			 PyInt_FromLong((long)st->st_rdev));
+#endif
+#ifdef HAVE_STRUCT_STAT_ST_GEN
+	PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
+			 PyInt_FromLong((long)st->st_gen));
+#endif
+#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
+	{
+	  PyObject *val;
+	  unsigned long bsec,bnsec;
+	  bsec = (long)st->st_birthtime;
+#ifdef HAVE_STAT_TV_NSEC2
+	  bnsec = st->st_birthtimespec.tv_nsec;
+#else
+	  bnsec = 0;
+#endif
+	  if (_stat_float_times) {
+	    val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
+	  } else {
+	    val = PyInt_FromLong((long)bsec);
+	  }
+	  PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
+				    val);
+	}
+#endif
+#ifdef HAVE_STRUCT_STAT_ST_FLAGS
+	PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
+			 PyInt_FromLong((long)st->st_flags));
+#endif
+
+	if (PyErr_Occurred()) {
+		Py_DECREF(v);
+		return NULL;
+	}
+
+	return v;
+}
+
+#ifdef MS_WINDOWS
+
+/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
+   where / can be used in place of \ and the trailing slash is optional.
+   Both SERVER and SHARE must have at least one character.
+*/
+
+#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
+#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
+#ifndef ARRAYSIZE
+#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
+#endif
+
+static BOOL
+IsUNCRootA(char *path, int pathlen)
+{
+	#define ISSLASH ISSLASHA
+
+	int i, share;
+
+	if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
+		/* minimum UNCRoot is \\x\y */
+		return FALSE;
+	for (i = 2; i < pathlen ; i++)
+		if (ISSLASH(path[i])) break;
+	if (i == 2 || i == pathlen)
+		/* do not allow \\\SHARE or \\SERVER */
+		return FALSE;
+	share = i+1;
+	for (i = share; i < pathlen; i++)
+		if (ISSLASH(path[i])) break;
+	return (i != share && (i == pathlen || i == pathlen-1));
+
+	#undef ISSLASH
+}
+
+#ifdef Py_WIN_WIDE_FILENAMES
+static BOOL
+IsUNCRootW(Py_UNICODE *path, int pathlen)
+{
+	#define ISSLASH ISSLASHW
+
+	int i, share;
+
+	if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
+		/* minimum UNCRoot is \\x\y */
+		return FALSE;
+	for (i = 2; i < pathlen ; i++)
+		if (ISSLASH(path[i])) break;
+	if (i == 2 || i == pathlen)
+		/* do not allow \\\SHARE or \\SERVER */
+		return FALSE;
+	share = i+1;
+	for (i = share; i < pathlen; i++)
+		if (ISSLASH(path[i])) break;
+	return (i != share && (i == pathlen || i == pathlen-1));
+
+	#undef ISSLASH
+}
+#endif /* Py_WIN_WIDE_FILENAMES */
+#endif /* MS_WINDOWS */
+
+static PyObject *
+posix_do_stat(PyObject *self, PyObject *args,
+	      char *format,
+#ifdef __VMS
+	      int (*statfunc)(const char *, STRUCT_STAT *, ...),
+#else
+	      int (*statfunc)(const char *, STRUCT_STAT *),
+#endif
+	      char *wformat,
+	      int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
+{
+	STRUCT_STAT st;
+	char *path = NULL;	/* pass this to stat; do not free() it */
+	char *pathfree = NULL;  /* this memory must be free'd */
+	int res;
+	PyObject *result;
+
+#ifdef Py_WIN_WIDE_FILENAMES
+	/* If on wide-character-capable OS see if argument
+	   is Unicode and if so use wide API.  */
+	if (unicode_file_names()) {
+		PyUnicodeObject *po;
+		if (PyArg_ParseTuple(args, wformat, &po)) {
+			Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
+
+			Py_BEGIN_ALLOW_THREADS
+				/* PyUnicode_AS_UNICODE result OK without
+				   thread lock as it is a simple dereference. */
+			res = wstatfunc(wpath, &st);
+			Py_END_ALLOW_THREADS
+
+			if (res != 0)
+				return win32_error_unicode("stat", wpath);
+			return _pystat_fromstructstat(&st);
+		}
+		/* Drop the argument parsing error as narrow strings
+		   are also valid. */
+		PyErr_Clear();
+	}
+#endif
+
+	if (!PyArg_ParseTuple(args, format,
+	                      Py_FileSystemDefaultEncoding, &path))
+		return NULL;
+	pathfree = path;
+
+	Py_BEGIN_ALLOW_THREADS
+	res = (*statfunc)(path, &st);
+	Py_END_ALLOW_THREADS
+
+	if (res != 0) {
+#ifdef MS_WINDOWS
+		result = win32_error("stat", pathfree);
+#else
+		result = posix_error_with_filename(pathfree);
+#endif
+	} 
+	else
+		result = _pystat_fromstructstat(&st);
+
+	PyMem_Free(pathfree);
+	return result;
+}
+
+/* POSIX methods */
+
+PyDoc_STRVAR(posix_access__doc__,
+"access(path, mode) -> True if granted, False otherwise\n\n\
+Use the real uid/gid to test for access to a path.  Note that most\n\
+operations will use the effective uid/gid, therefore this routine can\n\
+be used in a suid/sgid environment to test if the invoking user has the\n\
+specified access to the path.  The mode argument can be F_OK to test\n\
+existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
+
+static PyObject *
+posix_access(PyObject *self, PyObject *args)
+{
+	char *path;
+	int mode;
+	
+#ifdef Py_WIN_WIDE_FILENAMES
+	DWORD attr;
+	if (unicode_file_names()) {
+		PyUnicodeObject *po;
+		if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
+			Py_BEGIN_ALLOW_THREADS
+			/* PyUnicode_AS_UNICODE OK without thread lock as
+			   it is a simple dereference. */
+			attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
+			Py_END_ALLOW_THREADS
+			goto finish;
+		}
+		/* Drop the argument parsing error as narrow strings
+		   are also valid. */
+		PyErr_Clear();
+	}
+	if (!PyArg_ParseTuple(args, "eti:access",
+			      Py_FileSystemDefaultEncoding, &path, &mode))
+		return 0;
+	Py_BEGIN_ALLOW_THREADS
+	attr = GetFileAttributesA(path);
+	Py_END_ALLOW_THREADS
+	PyMem_Free(path);
+finish:
+	if (attr == 0xFFFFFFFF)
+		/* File does not exist, or cannot read attributes */
+		return PyBool_FromLong(0);
+	/* Access is possible if either write access wasn't requested, or
+	   the file isn't read-only. */
+	return PyBool_FromLong(!(mode & 2) || !(attr & FILE_ATTRIBUTE_READONLY));
+#else
+	int res;
+	if (!PyArg_ParseTuple(args, "eti:access", 
+			      Py_FileSystemDefaultEncoding, &path, &mode))
+		return NULL;
+	Py_BEGIN_ALLOW_THREADS
+	res = access(path, mode);
+	Py_END_ALLOW_THREADS
+	PyMem_Free(path);
+	return PyBool_FromLong(res == 0);
+#endif
+}
+
+#ifndef F_OK
+#define F_OK 0
+#endif
+#ifndef R_OK
+#define R_OK 4
+#endif
+#ifndef W_OK
+#define W_OK 2
+#endif
+#ifndef X_OK
+#define X_OK 1
+#endif
+
+#ifdef HAVE_TTYNAME
+PyDoc_STRVAR(posix_ttyname__doc__,
+"ttyname(fd) -> string\n\n\
+Return the name of the terminal device connected to 'fd'.");
+
+static PyObject *
+posix_ttyname(PyObject *self, PyObject *args)
+{
+	int id;
+	char *ret;
+
+	if (!PyArg_ParseTuple(args, "i:ttyname", &id))
+		return NULL;
+
+#if defined(__VMS)
+        /* file descriptor 0 only, the default input device (stdin) */
+	if (id == 0) {
+		ret = ttyname();
+	}
+	else {
+		ret = NULL;
+	}
+#else
+	ret = ttyname(id);
+#endif
+	if (ret == NULL)
+		return posix_error();
+	return PyString_FromString(ret);
+}
+#endif
+
+#ifdef HAVE_CTERMID
+PyDoc_STRVAR(posix_ctermid__doc__,
+"ctermid() -> string\n\n\
+Return the name of the controlling terminal for this process.");
+
+static PyObject *
+posix_ctermid(PyObject *self, PyObject *noargs)
+{
+        char *ret;
+        char buffer[L_ctermid];
+
+#ifdef USE_CTERMID_R
+	ret = ctermid_r(buffer);
+#else
+        ret = ctermid(buffer);
+#endif
+	if (ret == NULL)
+		return posix_error();
+	return PyString_FromString(buffer);
+}
+#endif
+
+PyDoc_STRVAR(posix_chdir__doc__,
+"chdir(path)\n\n\
+Change the current working directory to the specified path.");
+
+static PyObject *
+posix_chdir(PyObject *self, PyObject *args)
+{
+#ifdef MS_WINDOWS
+	return win32_1str(args, "chdir", "s:chdir", win32_chdir, "U:chdir", win32_wchdir);
+#elif defined(PYOS_OS2) && defined(PYCC_GCC)
+	return posix_1str(args, "et:chdir", _chdir2);
+#elif defined(__VMS)
+	return posix_1str(args, "et:chdir", (int (*)(const char *))chdir);
+#else
+	return posix_1str(args, "et:chdir", chdir);
+#endif
+}
+
+#ifdef HAVE_FCHDIR
+PyDoc_STRVAR(posix_fchdir__doc__,
+"fchdir(fildes)\n\n\
+Change to the directory of the given file descriptor.  fildes must be\n\
+opened on a directory, not a file.");
+
+static PyObject *
+posix_fchdir(PyObject *self, PyObject *fdobj)
+{
+	return posix_fildes(fdobj, fchdir);
+}
+#endif /* HAVE_FCHDIR */
+
+
+PyDoc_STRVAR(posix_chmod__doc__,
+"chmod(path, mode)\n\n\
+Change the access permissions of a file.");
+
+static PyObject *
+posix_chmod(PyObject *self, PyObject *args)
+{
+	char *path = NULL;
+	int i;
+	int res;
+#ifdef Py_WIN_WIDE_FILENAMES
+	DWORD attr;
+	if (unicode_file_names()) {
+		PyUnicodeObject *po;
+		if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
+			Py_BEGIN_ALLOW_THREADS
+			attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
+			if (attr != 0xFFFFFFFF) {
+				if (i & _S_IWRITE)
+					attr &= ~FILE_ATTRIBUTE_READONLY;
+				else
+					attr |= FILE_ATTRIBUTE_READONLY;
+				res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
+			}
+			else
+				res = 0;
+			Py_END_ALLOW_THREADS
+			if (!res)
+				return win32_error_unicode("chmod",
+						PyUnicode_AS_UNICODE(po));
+			Py_INCREF(Py_None);
+			return Py_None;
+		}
+		/* Drop the argument parsing error as narrow strings
+		   are also valid. */
+		PyErr_Clear();
+	}
+	if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
+	                      &path, &i))
+		return NULL;
+	Py_BEGIN_ALLOW_THREADS
+	attr = GetFileAttributesA(path);
+	if (attr != 0xFFFFFFFF) {
+		if (i & _S_IWRITE)
+			attr &= ~FILE_ATTRIBUTE_READONLY;
+		else
+			attr |= FILE_ATTRIBUTE_READONLY;
+		res = SetFileAttributesA(path, attr);
+	}
+	else
+		res = 0;
+	Py_END_ALLOW_THREADS
+	if (!res) {
+		win32_error("chmod", path);
+		PyMem_Free(path);
+		return NULL;
+	}
+	PyMem_Free(path);
+	Py_INCREF(Py_None);
+	return Py_None;
+#else /* Py_WIN_WIDE_FILENAMES */
+	if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
+	                      &path, &i))
+		return NULL;
+	Py_BEGIN_ALLOW_THREADS
+	res = chmod(path, i);
+	Py_END_ALLOW_THREADS
+	if (res < 0)
+		return posix_error_with_allocated_filename(path);
+	PyMem_Free(path);
+	Py_INCREF(Py_None);
+	return Py_None;
+#endif
+}
+
+
+#ifdef HAVE_CHROOT
+PyDoc_STRVAR(posix_chroot__doc__,
+"chroot(path)\n\n\
+Change root directory to path.");
+
+static PyObject *
+posix_chroot(PyObject *self, PyObject *args)
+{
+	return posix_1str(args, "et:chroot", chroot);
+}
+#endif
+
+#ifdef HAVE_FSYNC
+PyDoc_STRVAR(posix_fsync__doc__,
+"fsync(fildes)\n\n\
+force write of file with filedescriptor to disk.");
+
+static PyObject *
+posix_fsync(PyObject *self, PyObject *fdobj)
+{
+       return posix_fildes(fdobj, fsync);
+}
+#endif /* HAVE_FSYNC */
+
+#ifdef HAVE_FDATASYNC
+
+#ifdef __hpux
+extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
+#endif
+
+PyDoc_STRVAR(posix_fdatasync__doc__,
+"fdatasync(fildes)\n\n\
+force write of file with filedescriptor to disk.\n\
+ does not force update of metadata.");
+
+static PyObject *
+posix_fdatasync(PyObject *self, PyObject *fdobj)
+{
+       return posix_fildes(fdobj, fdatasync);
+}
+#endif /* HAVE_FDATASYNC */
+
+
+#ifdef HAVE_CHOWN
+PyDoc_STRVAR(posix_chown__doc__,
+"chown(path, uid, gid)\n\n\
+Change the owner and group id of path to the numeric uid and gid.");
+
+static PyObject *
+posix_chown(PyObject *self, PyObject *args)
+{
+	char *path = NULL;
+	int uid, gid;
+	int res;
+	if (!PyArg_ParseTuple(args, "etii:chown",
+	                      Py_FileSystemDefaultEncoding, &path,
+	                      &uid, &gid))
+		return NULL;
+	Py_BEGIN_ALLOW_THREADS
+	res = chown(path, (uid_t) uid, (gid_t) gid);
+	Py_END_ALLOW_THREADS
+	if (res < 0)
+		return posix_error_with_allocated_filename(path);
+	PyMem_Free(path);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+#endif /* HAVE_CHOWN */
+
+#ifdef HAVE_LCHOWN
+PyDoc_STRVAR(posix_lchown__doc__,
+"lchown(path, uid, gid)\n\n\
+Change the owner and group id of path to the numeric uid and gid.\n\
+This function will not follow symbolic links.");
+
+static PyObject *
+posix_lchown(PyObject *self, PyObject *args)
+{
+	char *path = NULL;
+	int uid, gid;
+	int res;
+	if (!PyArg_ParseTuple(args, "etii:lchown",
+	                      Py_FileSystemDefaultEncoding, &path,
+	                      &uid, &gid))
+		return NULL;
+	Py_BEGIN_ALLOW_THREADS
+	res = lchown(path, (uid_t) uid, (gid_t) gid);
+	Py_END_ALLOW_THREADS
+	if (res < 0)
+		return posix_error_with_allocated_filename(path);
+	PyMem_Free(path);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+#endif /* HAVE_LCHOWN */
+
+
+#ifdef HAVE_GETCWD
+PyDoc_STRVAR(posix_getcwd__doc__,
+"getcwd() -> path\n\n\
+Return a string representing the current working directory.");
+
+static PyObject *
+posix_getcwd(PyObject *self, PyObject *noargs)
+{
+	char buf[1026];
+	char *res;
+
+	Py_BEGIN_ALLOW_THREADS
+#if defined(PYOS_OS2) && defined(PYCC_GCC)
+	res = _getcwd2(buf, sizeof buf);
+#else
+	res = getcwd(buf, sizeof buf);
+#endif
+	Py_END_ALLOW_THREADS
+	if (res == NULL)
+		return posix_error();
+	return PyString_FromString(buf);
+}
+
+#ifdef Py_USING_UNICODE
+PyDoc_STRVAR(posix_getcwdu__doc__,
+"getcwdu() -> path\n\n\
+Return a unicode string representing the current working directory.");
+
+static PyObject *
+posix_getcwdu(PyObject *self, PyObject *noargs)
+{
+	char buf[1026];
+	char *res;
+
+#ifdef Py_WIN_WIDE_FILENAMES
+	DWORD len;
+	if (unicode_file_names()) {
+		wchar_t wbuf[1026];
+		wchar_t *wbuf2 = wbuf;
+		PyObject *resobj;
+		Py_BEGIN_ALLOW_THREADS
+		len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
+		/* If the buffer is large enough, len does not include the
+		   terminating \0. If the buffer is too small, len includes
+		   the space needed for the terminator. */
+		if (len >= sizeof wbuf/ sizeof wbuf[0]) {
+			wbuf2 = malloc(len * sizeof(wchar_t));
+			if (wbuf2)
+				len = GetCurrentDirectoryW(len, wbuf2);
+		}
+		Py_END_ALLOW_THREADS
+		if (!wbuf2) {
+			PyErr_NoMemory();
+			return NULL;
+		}
+		if (!len) {
+			if (wbuf2 != wbuf) free(wbuf2);
+			return win32_error("getcwdu", NULL);
+		}
+		resobj = PyUnicode_FromWideChar(wbuf2, len);
+		if (wbuf2 != wbuf) free(wbuf2);
+		return resobj;
+	}
+#endif
+
+	Py_BEGIN_ALLOW_THREADS
+#if defined(PYOS_OS2) && defined(PYCC_GCC)
+	res = _getcwd2(buf, sizeof buf);
+#else
+	res = getcwd(buf, sizeof buf);
+#endif
+	Py_END_ALLOW_THREADS
+	if (res == NULL)
+		return posix_error();
+	return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
+}
+#endif
+#endif
+
+
+#ifdef HAVE_LINK
+PyDoc_STRVAR(posix_link__doc__,
+"link(src, dst)\n\n\
+Create a hard link to a file.");
+
+static PyObject *
+posix_link(PyObject *self, PyObject *args)
+{
+	return posix_2str(args, "etet:link", link);
+}
+#endif /* HAVE_LINK */
+
+
+PyDoc_STRVAR(posix_listdir__doc__,
+"listdir(path) -> list_of_strings\n\n\
+Return a list containing the names of the entries in the directory.\n\
+\n\
+	path: path of directory to list\n\
+\n\
+The list is in arbitrary order.  It does not include the special\n\
+entries '.' and '..' even if they are present in the directory.");
+
+static PyObject *
+posix_listdir(PyObject *self, PyObject *args)
+{
+	/* XXX Should redo this putting the (now four) versions of opendir
+	   in separate files instead of having them all here... */
+#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
+
+	PyObject *d, *v;
+	HANDLE hFindFile;
+	BOOL result;
+	WIN32_FIND_DATA FileData;
+	char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
+	char *bufptr = namebuf;
+	Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
+
+#ifdef Py_WIN_WIDE_FILENAMES
+	/* If on wide-character-capable OS see if argument
+	   is Unicode and if so use wide API.  */
+	if (unicode_file_names()) {
+		PyObject *po;
+		if (PyArg_ParseTuple(args, "U:listdir", &po)) {
+			WIN32_FIND_DATAW wFileData;
+			Py_UNICODE *wnamebuf;
+			Py_UNICODE wch;
+			/* Overallocate for \\*.*\0 */
+			len = PyUnicode_GET_SIZE(po);
+			wnamebuf = malloc((len + 5) * sizeof(wchar_t));
+			if (!wnamebuf) {
+				PyErr_NoMemory();
+				return NULL;
+			}
+			wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
+			wch = len > 0 ? wnamebuf[len-1] : '\0';
+			if (wch != L'/' && wch != L'\\' && wch != L':')
+				wnamebuf[len++] = L'\\';
+			wcscpy(wnamebuf + len, L"*.*");
+			if ((d = PyList_New(0)) == NULL) {
+				free(wnamebuf);
+				return NULL;
+			}
+			hFindFile = FindFirstFileW(wnamebuf, &wFileData);
+			if (hFindFile == INVALID_HANDLE_VALUE) {
+				int error = GetLastError();
+				if (error == ERROR_FILE_NOT_FOUND) {
+					free(wnamebuf);
+					return d;
+				}
+				Py_DECREF(d);
+				win32_error_unicode("FindFirstFileW", wnamebuf);
+				free(wnamebuf);
+				return NULL;
+			}
+			do {
+				/* Skip over . and .. */
+				if (wcscmp(wFileData.cFileName, L".") != 0 &&
+				    wcscmp(wFileData.cFileName, L"..") != 0) {
+					v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
+					if (v == NULL) {
+						Py_DECREF(d);
+						d = NULL;
+						break;
+					}
+					if (PyList_Append(d, v) != 0) {
+						Py_DECREF(v);
+						Py_DECREF(d);
+						d = NULL;
+						break;
+					}
+					Py_DECREF(v);
+				}
+				Py_BEGIN_ALLOW_THREADS
+				result = FindNextFileW(hFindFile, &wFileData);
+				Py_END_ALLOW_THREADS
+				/* FindNextFile sets error to ERROR_NO_MORE_FILES if
+				   it got to the end of the directory. */
+				if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
+				    Py_DECREF(d);
+				    win32_error_unicode("FindNextFileW", wnamebuf);
+				    FindClose(hFindFile);
+				    free(wnamebuf);
+				    return NULL;
+				}
+			} while (result == TRUE);
+
+			if (FindClose(hFindFile) == FALSE) {
+				Py_DECREF(d);
+				win32_error_unicode("FindClose", wnamebuf);
+				free(wnamebuf);
+				return NULL;
+			}
+			free(wnamebuf);
+			return d;
+		}
+		/* Drop the argument parsing error as narrow strings
+		   are also valid. */
+		PyErr_Clear();
+	}
+#endif
+
+	if (!PyArg_ParseTuple(args, "et#:listdir",
+	                      Py_FileSystemDefaultEncoding, &bufptr, &len))
+		return NULL;
+	if (len > 0) {
+		char ch = namebuf[len-1];
+		if (ch != SEP && ch != ALTSEP && ch != ':')
+			namebuf[len++] = '/';
+	}
+	strcpy(namebuf + len, "*.*");
+
+	if ((d = PyList_New(0)) == NULL)
+		return NULL;
+
+	hFindFile = FindFirstFile(namebuf, &FileData);
+	if (hFindFile == INVALID_HANDLE_VALUE) {
+		int error = GetLastError();
+		if (error == ERROR_FILE_NOT_FOUND)
+			return d;
+		Py_DECREF(d);
+		return win32_error("FindFirstFile", namebuf);
+	}
+	do {
+		/* Skip over . and .. */
+		if (strcmp(FileData.cFileName, ".") != 0 &&
+		    strcmp(FileData.cFileName, "..") != 0) {
+			v = PyString_FromString(FileData.cFileName);
+			if (v == NULL) {
+				Py_DECREF(d);
+				d = NULL;
+				break;
+			}
+			if (PyList_Append(d, v) != 0) {
+				Py_DECREF(v);
+				Py_DECREF(d);
+				d = NULL;
+				break;
+			}
+			Py_DECREF(v);
+		}
+		Py_BEGIN_ALLOW_THREADS
+		result = FindNextFile(hFindFile, &FileData);
+		Py_END_ALLOW_THREADS
+		/* FindNextFile sets error to ERROR_NO_MORE_FILES if
+		   it got to the end of the directory. */
+		if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
+		    Py_DECREF(d);
+		    win32_error("FindNextFile", namebuf);
+		    FindClose(hFindFile);
+		    return NULL;
+		}
+	} while (result == TRUE);
+
+	if (FindClose(hFindFile) == FALSE) {
+		Py_DECREF(d);
+		return win32_error("FindClose", namebuf);
+	}
+
+	return d;
+
+#elif defined(PYOS_OS2)
+
+#ifndef MAX_PATH
+#define MAX_PATH    CCHMAXPATH
+#endif
+    char *name, *pt;
+    Py_ssize_t len;
+    PyObject *d, *v;
+    char namebuf[MAX_PATH+5];
+    HDIR  hdir = 1;
+    ULONG srchcnt = 1;
+    FILEFINDBUF3   ep;
+    APIRET rc;
+
+    if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
+        return NULL;
+    if (len >= MAX_PATH) {
+		PyErr_SetString(PyExc_ValueError, "path too long");
+        return NULL;
+    }
+    strcpy(namebuf, name);
+    for (pt = namebuf; *pt; pt++)
+        if (*pt == ALTSEP)
+            *pt = SEP;
+    if (namebuf[len-1] != SEP)
+        namebuf[len++] = SEP;
+    strcpy(namebuf + len, "*.*");
+
+	if ((d = PyList_New(0)) == NULL)
+        return NULL;
+
+    rc = DosFindFirst(namebuf,         /* Wildcard Pattern to Match */
+                      &hdir,           /* Handle to Use While Search Directory */
+                      FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
+                      &ep, sizeof(ep), /* Structure to Receive Directory Entry */
+                      &srchcnt,        /* Max and Actual Count of Entries Per Iteration */
+                      FIL_STANDARD);   /* Format of Entry (EAs or Not) */
+
+    if (rc != NO_ERROR) {
+        errno = ENOENT;
+        return posix_error_with_filename(name);
+    }
+
+    if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
+        do {
+            if (ep.achName[0] == '.'
+            && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
+                continue; /* Skip Over "." and ".." Names */
+
+            strcpy(namebuf, ep.achName);
+
+            /* Leave Case of Name Alone -- In Native Form */
+            /* (Removed Forced Lowercasing Code) */
+
+            v = PyString_FromString(namebuf);
+            if (v == NULL) {
+                Py_DECREF(d);
+                d = NULL;
+                break;
+            }
+            if (PyList_Append(d, v) != 0) {
+                Py_DECREF(v);
+                Py_DECREF(d);
+                d = NULL;
+                break;
+            }
+            Py_DECREF(v);
+        } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
+    }
+
+    return d;
+#else
+
+	char *name = NULL;
+	PyObject *d, *v;
+	DIR *dirp;
+	struct dirent *ep;
+	int arg_is_unicode = 1;
+
+	errno = 0;
+	if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
+		arg_is_unicode = 0;
+		PyErr_Clear();
+	}
+	if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
+		return NULL;
+	if ((dirp = opendir(name)) == NULL) {
+		return posix_error_with_allocated_filename(name);
+	}
+	if ((d = PyList_New(0)) == NULL) {
+		closedir(dirp);
+		PyMem_Free(name);
+		return NULL;
+	}
+	for (;;) {
+		Py_BEGIN_ALLOW_THREADS
+		ep = readdir(dirp);
+		Py_END_ALLOW_THREADS
+		if (ep == NULL)
+			break;
+		if (ep->d_name[0] == '.' &&
+		    (NAMLEN(ep) == 1 ||
+		     (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
+			continue;
+		v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
+		if (v == NULL) {
+			Py_DECREF(d);
+			d = NULL;
+			break;
+		}
+#ifdef Py_USING_UNICODE
+		if (arg_is_unicode) {
+			PyObject *w;
+
+			w = PyUnicode_FromEncodedObject(v,
+					Py_FileSystemDefaultEncoding,
+					"strict");
+			if (w != NULL) {
+				Py_DECREF(v);
+				v = w;
+			}
+			else {
+				/* fall back to the original byte string, as
+				   discussed in patch #683592 */
+				PyErr_Clear();
+			}
+		}
+#endif
+		if (PyList_Append(d, v) != 0) {
+			Py_DECREF(v);
+			Py_DECREF(d);
+			d = NULL;
+			break;
+		}
+		Py_DECREF(v);
+	}
+	if (errno != 0 && d != NULL) {
+		/* readdir() returned NULL and set errno */
+		closedir(dirp);
+		Py_DECREF(d);
+		return posix_error_with_allocated_filename(name); 
+	}
+	closedir(dirp);
+	PyMem_Free(name);
+
+	return d;
+
+#endif /* which OS */
+}  /* end of posix_listdir */
+
+#ifdef MS_WINDOWS
+/* A helper function for abspath on win32 */
+static PyObject *
+posix__getfullpathname(PyObject *self, PyObject *args)
+{
+	/* assume encoded strings wont more than double no of chars */
+	char inbuf[MAX_PATH*2];
+	char *inbufp = inbuf;
+	Py_ssize_t insize = sizeof(inbuf);
+	char outbuf[MAX_PATH*2];
+	char *temp;
+#ifdef Py_WIN_WIDE_FILENAMES
+	if (unicode_file_names()) {
+		PyUnicodeObject *po;
+		if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
+			Py_UNICODE woutbuf[MAX_PATH*2];
+			Py_UNICODE *wtemp;
+			if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
+						sizeof(woutbuf)/sizeof(woutbuf[0]),
+						 woutbuf, &wtemp))
+				return win32_error("GetFullPathName", "");
+			return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
+		}
+		/* Drop the argument parsing error as narrow strings
+		   are also valid. */
+		PyErr_Clear();
+	}
+#endif
+	if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
+	                       Py_FileSystemDefaultEncoding, &inbufp,
+	                       &insize))
+		return NULL;
+	if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
+	                     outbuf, &temp))
+		return win32_error("GetFullPathName", inbuf);
+	if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
+		return PyUnicode_Decode(outbuf, strlen(outbuf),
+			Py_FileSystemDefaultEncoding, NULL);
+	}
+	return PyString_FromString(outbuf);
+} /* end of posix__getfullpathname */
+#endif /* MS_WINDOWS */
+
+PyDoc_STRVAR(posix_mkdir__doc__,
+"mkdir(path [, mode=0777])\n\n\
+Create a directory.");
+
+static PyObject *
+posix_mkdir(PyObject *self, PyObject *args)
+{
+	int res;
+	char *path = NULL;
+	int mode = 0777;
+
+#ifdef Py_WIN_WIDE_FILENAMES
+	if (unicode_file_names()) {
+		PyUnicodeObject *po;
+		if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
+			Py_BEGIN_ALLOW_THREADS
+			/* PyUnicode_AS_UNICODE OK without thread lock as
+			   it is a simple dereference. */
+			res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
+			Py_END_ALLOW_THREADS
+			if (!res)
+				return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
+			Py_INCREF(Py_None);
+			return Py_None;
+		}
+		/* Drop the argument parsing error as narrow strings
+		   are also valid. */
+		PyErr_Clear();
+	}
+	if (!PyArg_ParseTuple(args, "et|i:mkdir",
+	                      Py_FileSystemDefaultEncoding, &path, &mode))
+		return NULL;
+	Py_BEGIN_ALLOW_THREADS
+	/* PyUnicode_AS_UNICODE OK without thread lock as
+	   it is a simple dereference. */
+	res = CreateDirectoryA(path, NULL);
+	Py_END_ALLOW_THREADS
+	if (!res) {
+		win32_error("mkdir", path);
+		PyMem_Free(path);
+		return NULL;
+	}
+	PyMem_Free(path);
+	Py_INCREF(Py_None);
+	return Py_None;
+#else
+
+	if (!PyArg_ParseTuple(args, "et|i:mkdir",
+	                      Py_FileSystemDefaultEncoding, &path, &mode))
+		return NULL;
+	Py_BEGIN_ALLOW_THREADS
+#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
+	res = mkdir(path);
+#else
+	res = mkdir(path, mode);
+#endif
+	Py_END_ALLOW_THREADS
+	if (res < 0)
+		return posix_error_with_allocated_filename(path);
+	PyMem_Free(path);
+	Py_INCREF(Py_None);
+	return Py_None;
+#endif
+}
+
+
+/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
+#if defined(HAVE_SYS_RESOURCE_H)
+#include <sys/resource.h>
+#endif
+
+
+#ifdef HAVE_NICE
+PyDoc_STRVAR(posix_nice__doc__,
+"nice(inc) -> new_priority\n\n\
+Decrease the priority of process by inc and return the new priority.");
+
+static PyObject *
+posix_nice(PyObject *self, PyObject *args)
+{
+	int increment, value;
+
+	if (!PyArg_ParseTuple(args, "i:nice", &increment))
+		return NULL;
+
+	/* There are two flavours of 'nice': one that returns the new
+	   priority (as required by almost all standards out there) and the
+	   Linux/FreeBSD/BSDI one, which returns '0' on success and advices
+	   the use of getpriority() to get the new priority.
+
+	   If we are of the nice family that returns the new priority, we
+	   need to clear errno before the call, and check if errno is filled
+	   before calling posix_error() on a returnvalue of -1, because the
+	   -1 may be the actual new priority! */
+
+	errno = 0;
+	value = nice(increment);
+#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
+	if (value == 0)
+		value = getpriority(PRIO_PROCESS, 0);
+#endif
+	if (value == -1 && errno != 0)
+		/* either nice() or getpriority() returned an error */
+		return posix_error();
+	return PyInt_FromLong((long) value);
+}
+#endif /* HAVE_NICE */
+
+PyDoc_STRVAR(posix_rename__doc__,
+"rename(old, new)\n\n\
+Rename a file or directory.");
+
+static PyObject *
+posix_rename(PyObject *self, PyObject *args)
+{
+#ifdef MS_WINDOWS
+	PyObject *o1, *o2;
+	char *p1, *p2;
+	BOOL result;
+	if (unicode_file_names()) {
+	    if (!PyArg_ParseTuple(args, "O&O&:rename", 
+		convert_to_unicode, &o1,
+		convert_to_unicode, &o2))
+		    PyErr_Clear();
+	    else {
+		    Py_BEGIN_ALLOW_THREADS
+		    result = MoveFileW(PyUnicode_AsUnicode(o1),
+				       PyUnicode_AsUnicode(o2));
+		    Py_END_ALLOW_THREADS
+		    Py_DECREF(o1);
+		    Py_DECREF(o2);
+		    if (!result)
+			    return win32_error("rename", NULL);
+		    Py_INCREF(Py_None);
+		    return Py_None;
+	    }
+	}
+	if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
+		return NULL;
+	Py_BEGIN_ALLOW_THREADS
+	result = MoveFileA(p1, p2);
+	Py_END_ALLOW_THREADS
+	if (!result)
+		return win32_error("rename", NULL);
+	Py_INCREF(Py_None);
+	return Py_None;
+#else
+	return posix_2str(args, "etet:rename", rename);
+#endif
+}
+
+
+PyDoc_STRVAR(posix_rmdir__doc__,
+"rmdir(path)\n\n\
+Remove a directory.");
+
+static PyObject *
+posix_rmdir(PyObject *self, PyObject *args)
+{
+#ifdef MS_WINDOWS
+	return win32_1str(args, "rmdir", "s:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
+#else
+	return posix_1str(args, "et:rmdir", rmdir);
+#endif
+}
+
+
+PyDoc_STRVAR(posix_stat__doc__,
+"stat(path) -> stat result\n\n\
+Perform a stat system call on the given path.");
+
+static PyObject *
+posix_stat(PyObject *self, PyObject *args)
+{
+#ifdef MS_WINDOWS
+	return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
+#else
+	return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
+#endif
+}
+
+
+#ifdef HAVE_SYSTEM
+PyDoc_STRVAR(posix_system__doc__,
+"system(command) -> exit_status\n\n\
+Execute the command (a string) in a subshell.");
+
+static PyObject *
+posix_system(PyObject *self, PyObject *args)
+{
+	char *command;
+	long sts;
+	if (!PyArg_ParseTuple(args, "s:system", &command))
+		return NULL;
+	Py_BEGIN_ALLOW_THREADS
+	sts = system(command);
+	Py_END_ALLOW_THREADS
+	return PyInt_FromLong(sts);
+}
+#endif
+
+
+PyDoc_STRVAR(posix_umask__doc__,
+"umask(new_mask) -> old_mask\n\n\
+Set the current numeric umask and return the previous umask.");
+
+static PyObject *
+posix_umask(PyObject *self, PyObject *args)
+{
+	int i;
+	if (!PyArg_ParseTuple(args, "i:umask", &i))
+		return NULL;
+	i = (int)umask(i);
+	if (i < 0)
+		return posix_error();
+	return PyInt_FromLong((long)i);
+}
+
+
+PyDoc_STRVAR(posix_unlink__doc__,
+"unlink(path)\n\n\
+Remove a file (same as remove(path)).");
+
+PyDoc_STRVAR(posix_remove__doc__,
+"remove(path)\n\n\
+Remove a file (same as unlink(path)).");
+
+static PyObject *
+posix_unlink(PyObject *self, PyObject *args)
+{
+#ifdef MS_WINDOWS
+	return win32_1str(args, "remove", "s:remove", DeleteFileA, "U:remove", DeleteFileW);
+#else
+	return posix_1str(args, "et:remove", unlink);
+#endif
+}
+
+
+#ifdef HAVE_UNAME
+PyDoc_STRVAR(posix_uname__doc__,
+"uname() -> (sysname, nodename, release, version, machine)\n\n\
+Return a tuple identifying the current operating system.");
+
+static PyObject *
+posix_uname(PyObject *self, PyObject *noargs)
+{
+	struct utsname u;
+	int res;
+
+	Py_BEGIN_ALLOW_THREADS
+	res = uname(&u);
+	Py_END_ALLOW_THREADS
+	if (res < 0)
+		return posix_error();
+	return Py_BuildValue("(sssss)",
+			     u.sysname,
+			     u.nodename,
+			     u.release,
+			     u.version,
+			     u.machine);
+}
+#endif /* HAVE_UNAME */
+
+static int
+extract_time(PyObject *t, long* sec, long* usec)
+{
+	long intval;
+	if (PyFloat_Check(t)) {
+		double tval = PyFloat_AsDouble(t);
+		PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
+		if (!intobj)
+			return -1;
+		intval = PyInt_AsLong(intobj);
+		Py_DECREF(intobj);
+		if (intval == -1 && PyErr_Occurred())
+			return -1;
+		*sec = intval;
+		*usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
+		if (*usec < 0)
+			/* If rounding gave us a negative number,
+			   truncate.  */
+			*usec = 0;
+		return 0;
+	}
+	intval = PyInt_AsLong(t);
+	if (intval == -1 && PyErr_Occurred())
+		return -1;
+	*sec = intval;
+	*usec = 0;
+        return 0;
+}
+
+PyDoc_STRVAR(posix_utime__doc__,
+"utime(path, (atime, mtime))\n\
+utime(path, None)\n\n\
+Set the access and modified time of the file to the given values.  If the\n\
+second form is used, set the access and modified times to the current time.");
+
+static PyObject *
+posix_utime(PyObject *self, PyObject *args)
+{
+#ifdef Py_WIN_WIDE_FILENAMES
+	PyObject *arg;
+	PyUnicodeObject *obwpath;
+	wchar_t *wpath = NULL;
+	char *apath = NULL;
+	HANDLE hFile;
+	long atimesec, mtimesec, ausec, musec;
+	FILETIME atime, mtime;
+	PyObject *result = NULL;
+
+	if (unicode_file_names()) {
+		if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
+			wpath = PyUnicode_AS_UNICODE(obwpath);
+			Py_BEGIN_ALLOW_THREADS
+			hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
+					    NULL, OPEN_EXISTING, 0, NULL);
+			Py_END_ALLOW_THREADS
+			if (hFile == INVALID_HANDLE_VALUE)
+				return win32_error_unicode("utime", wpath);
+		} else
+			/* Drop the argument parsing error as narrow strings
+			   are also valid. */
+			PyErr_Clear();
+	}
+	if (!wpath) {
+		if (!PyArg_ParseTuple(args, "etO:utime",
+				Py_FileSystemDefaultEncoding, &apath, &arg))
+			return NULL;
+		Py_BEGIN_ALLOW_THREADS
+		hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
+				    NULL, OPEN_EXISTING, 0, NULL);
+		Py_END_ALLOW_THREADS
+		if (hFile == INVALID_HANDLE_VALUE) {
+			win32_error("utime", apath);
+			PyMem_Free(apath);
+			return NULL;
+		}
+		PyMem_Free(apath);
+	}
+	
+	if (arg == Py_None) {
+		SYSTEMTIME now;
+		GetSystemTime(&now);
+		if (!SystemTimeToFileTime(&now, &mtime) ||
+		    !SystemTimeToFileTime(&now, &atime)) {
+			win32_error("utime", NULL);
+			goto done;
+		    }
+	}
+	else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
+		PyErr_SetString(PyExc_TypeError,
+				"utime() arg 2 must be a tuple (atime, mtime)");
+		goto done;
+	}
+	else {
+		if (extract_time(PyTuple_GET_ITEM(arg, 0),
+				 &atimesec, &ausec) == -1)
+			goto done;
+		time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
+		if (extract_time(PyTuple_GET_ITEM(arg, 1),
+				 &mtimesec, &musec) == -1)
+			goto done;
+		time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
+	}
+	if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
+		/* Avoid putting the file name into the error here,
+		   as that may confuse the user into believing that
+		   something is wrong with the file, when it also
+		   could be the time stamp that gives a problem. */
+		win32_error("utime", NULL);
+	}
+	Py_INCREF(Py_None);
+	result = Py_None;
+done:
+	CloseHandle(hFile);
+	return result;
+#else /* Py_WIN_WIDE_FILENAMES */
+
+	char *path = NULL;
+	long atime, mtime, ausec, musec;
+	int res;
+	PyObject* arg;
+
+#if defined(HAVE_UTIMES)
+	struct timeval buf[2];
+#define ATIME buf[0].tv_sec
+#define MTIME buf[1].tv_sec
+#elif defined(HAVE_UTIME_H)
+/* XXX should define struct utimbuf instead, above */
+	struct utimbuf buf;
+#define ATIME buf.actime
+#define MTIME buf.modtime
+#define UTIME_ARG &buf
+#else /* HAVE_UTIMES */
+	time_t buf[2];
+#define ATIME buf[0]
+#define MTIME buf[1]
+#define UTIME_ARG buf
+#endif /* HAVE_UTIMES */
+
+
+	if (!PyArg_ParseTuple(args, "etO:utime",
+				  Py_FileSystemDefaultEncoding, &path, &arg))
+		return NULL;
+	if (arg == Py_None) {
+		/* optional time values not given */
+		Py_BEGIN_ALLOW_THREADS
+		res = utime(path, NULL);
+		Py_END_ALLOW_THREADS
+	}
+	else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
+		PyErr_SetString(PyExc_TypeError,
+				"utime() arg 2 must be a tuple (atime, mtime)");
+		PyMem_Free(path);
+		return NULL;
+	}
+	else {
+		if (extract_time(PyTuple_GET_ITEM(arg, 0),
+				 &atime, &ausec) == -1) {
+			PyMem_Free(path);
+			return NULL;
+		}
+		if (extract_time(PyTuple_GET_ITEM(arg, 1),
+				 &mtime, &musec) == -1) {
+			PyMem_Free(path);
+			return NULL;
+		}
+		ATIME = atime;
+		MTIME = mtime;
+#ifdef HAVE_UTIMES
+		buf[0].tv_usec = ausec;
+		buf[1].tv_usec = musec;
+		Py_BEGIN_ALLOW_THREADS
+		res = utimes(path, buf);
+		Py_END_ALLOW_THREADS
+#else
+		Py_BEGIN_ALLOW_THREADS
+		res = utime(path, UTIME_ARG);
+		Py_END_ALLOW_THREADS
+#endif /* HAVE_UTIMES */
+	}
+	if (res < 0) {
+		return posix_error_with_allocated_filename(path);
+	}
+	PyMem_Free(path);
+	Py_INCREF(Py_None);
+	return Py_None;
+#undef UTIME_ARG
+#undef ATIME
+#undef MTIME
+#endif /* Py_WIN_WIDE_FILENAMES */
+}
+
+
+/* Process operations */
+
+PyDoc_STRVAR(posix__exit__doc__,
+"_exit(status)\n\n\
+Exit to the system with specified status, without normal exit processing.");
+
+static PyObject *
+posix__exit(PyObject *self, PyObject *args)
+{
+	int sts;
+	if (!PyArg_ParseTuple(args, "i:_exit", &sts))
+		return NULL;
+	_exit(sts);
+	return NULL; /* Make gcc -Wall happy */
+}
+
+#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
+static void
+free_string_array(char **array, Py_ssize_t count)
+{
+	Py_ssize_t i;
+	for (i = 0; i < count; i++)
+		PyMem_Free(array[i]);
+	PyMem_DEL(array);
+}
+#endif
+
+
+#ifdef HAVE_EXECV
+PyDoc_STRVAR(posix_execv__doc__,
+"execv(path, args)\n\n\
+Execute an executable path with arguments, replacing current process.\n\
+\n\
+	path: path of executable file\n\
+	args: tuple or list of strings");
+
+static PyObject *
+posix_execv(PyObject *self, PyObject *args)
+{
+	char *path;
+	PyObject *argv;
+	char **argvlist;
+	Py_ssize_t i, argc;
+	PyObject *(*getitem)(PyObject *, Py_ssize_t);
+
+	/* execv has two arguments: (path, argv), where
+	   argv is a list or tuple of strings. */
+
+	if (!PyArg_ParseTuple(args, "etO:execv",
+                              Py_FileSystemDefaultEncoding,
+                              &path, &argv))
+		return NULL;
+	if (PyList_Check(argv)) {
+		argc = PyList_Size(argv);
+		getitem = PyList_GetItem;
+	}
+	else if (PyTuple_Check(argv)) {
+		argc = PyTuple_Size(argv);
+		getitem = PyTuple_GetItem;
+	}
+	else {
+		PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
+                PyMem_Free(path);
+		return NULL;
+	}
+
+	argvlist = PyMem_NEW(char *, argc+1);
+	if (argvlist == NULL) {
+		PyMem_Free(path);
+		return PyErr_NoMemory();
+	}
+	for (i = 0; i < argc; i++) {
+		if (!PyArg_Parse((*getitem)(argv, i), "et",
+				 Py_FileSystemDefaultEncoding,
+				 &argvlist[i])) {
+			free_string_array(argvlist, i);
+			PyErr_SetString(PyExc_TypeError,
+					"execv() arg 2 must contain only strings");
+			PyMem_Free(path);
+			return NULL;
+
+		}
+	}
+	argvlist[argc] = NULL;
+
+	execv(path, argvlist);
+
+	/* If we get here it's definitely an error */
+
+	free_string_array(argvlist, argc);
+	PyMem_Free(path);
+	return posix_error();
+}
+
+
+PyDoc_STRVAR(posix_execve__doc__,
+"execve(path, args, env)\n\n\
+Execute a path with arguments and environment, replacing current process.\n\
+\n\
+	path: path of executable file\n\
+	args: tuple or list of arguments\n\
+	env: dictionary of strings mapping to strings");
+
+static PyObject *
+posix_execve(PyObject *self, PyObject *args)
+{
+	char *path;
+	PyObject *argv, *env;
+	char **argvlist;
+	char **envlist;
+	PyObject *key, *val, *keys=NULL, *vals=NULL;
+	Py_ssize_t i, pos, argc, envc;
+	PyObject *(*getitem)(PyObject *, Py_ssize_t);
+	Py_ssize_t lastarg = 0;
+
+	/* execve has three arguments: (path, argv, env), where
+	   argv is a list or tuple of strings and env is a dictionary
+	   like posix.environ. */
+
+	if (!PyArg_ParseTuple(args, "etOO:execve",
+			      Py_FileSystemDefaultEncoding,
+			      &path, &argv, &env))
+		return NULL;
+	if (PyList_Check(argv)) {
+		argc = PyList_Size(argv);
+		getitem = PyList_GetItem;
+	}
+	else if (PyTuple_Check(argv)) {
+		argc = PyTuple_Size(argv);
+		getitem = PyTuple_GetItem;
+	}
+	else {
+		PyErr_SetString(PyExc_TypeError,
+				"execve() arg 2 must be a tuple or list");
+		goto fail_0;
+	}
+	if (!PyMapping_Check(env)) {
+		PyErr_SetString(PyExc_TypeError,
+				"execve() arg 3 must be a mapping object");
+		goto fail_0;
+	}
+
+	argvlist = PyMem_NEW(char *, argc+1);
+	if (argvlist == NULL) {
+		PyErr_NoMemory();
+		goto fail_0;
+	}
+	for (i = 0; i < argc; i++) {
+		if (!PyArg_Parse((*getitem)(argv, i),
+				 "et;execve() arg 2 must contain only strings",
+				 Py_FileSystemDefaultEncoding,
+				 &argvlist[i]))
+		{
+			lastarg = i;
+			goto fail_1;
+		}
+	}
+	lastarg = argc;
+	argvlist[argc] = NULL;
+
+	i = PyMapping_Size(env);
+	if (i < 0)
+		goto fail_1;
+	envlist = PyMem_NEW(char *, i + 1);
+	if (envlist == NULL) {
+		PyErr_NoMemory();
+		goto fail_1;
+	}
+	envc = 0;
+	keys = PyMapping_Keys(env);
+	vals = PyMapping_Values(env);
+	if (!keys || !vals)
+		goto fail_2;
+	if (!PyList_Check(keys) || !PyList_Check(vals)) {
+		PyErr_SetString(PyExc_TypeError,
+			"execve(): env.keys() or env.values() is not a list");
+		goto fail_2;
+	}
+
+	for (pos = 0; pos < i; pos++) {
+		char *p, *k, *v;
+		size_t len;
+
+		key = PyList_GetItem(keys, pos);
+		val = PyList_GetItem(vals, pos);
+		if (!key || !val)
+			goto fail_2;
+
+		if (!PyArg_Parse(
+			    key,
+			    "s;execve() arg 3 contains a non-string key",
+			    &k) ||
+		    !PyArg_Parse(
+			    val,
+			    "s;execve() arg 3 contains a non-string value",
+			    &v))
+		{
+			goto fail_2;
+		}
+
+#if defined(PYOS_OS2)
+        /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
+        if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
+#endif
+		len = PyString_Size(key) + PyString_Size(val) + 2;
+		p = PyMem_NEW(char, len);
+		if (p == NULL) {
+			PyErr_NoMemory();
+			goto fail_2;
+		}
+		PyOS_snprintf(p, len, "%s=%s", k, v);
+		envlist[envc++] = p;
+#if defined(PYOS_OS2)
+    }
+#endif
+	}
+	envlist[envc] = 0;
+
+	execve(path, argvlist, envlist);
+
+	/* If we get here it's definitely an error */
+
+	(void) posix_error();
+
+  fail_2:
+	while (--envc >= 0)
+		PyMem_DEL(envlist[envc]);
+	PyMem_DEL(envlist);
+  fail_1:
+	free_string_array(argvlist, lastarg);
+	Py_XDECREF(vals);
+	Py_XDECREF(keys);
+  fail_0:
+	PyMem_Free(path);
+	return NULL;
+}
+#endif /* HAVE_EXECV */
+
+
+#ifdef HAVE_SPAWNV
+PyDoc_STRVAR(posix_spawnv__doc__,
+"spawnv(mode, path, args)\n\n\
+Execute the program 'path' in a new process.\n\
+\n\
+	mode: mode of process creation\n\
+	path: path of executable file\n\
+	args: tuple or list of strings");
+
+static PyObject *
+posix_spawnv(PyObject *self, PyObject *args)
+{
+	char *path;
+	PyObject *argv;
+	char **argvlist;
+	int mode, i;
+	Py_ssize_t argc;
+	Py_intptr_t spawnval;
+	PyObject *(*getitem)(PyObject *, Py_ssize_t);
+
+	/* spawnv has three arguments: (mode, path, argv), where
+	   argv is a list or tuple of strings. */
+
+	if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
+			      Py_FileSystemDefaultEncoding,
+			      &path, &argv))
+		return NULL;
+	if (PyList_Check(argv)) {
+		argc = PyList_Size(argv);
+		getitem = PyList_GetItem;
+	}
+	else if (PyTuple_Check(argv)) {
+		argc = PyTuple_Size(argv);
+		getitem = PyTuple_GetItem;
+	}
+	else {
+		PyErr_SetString(PyExc_TypeError,
+				"spawnv() arg 2 must be a tuple or list");
+		PyMem_Free(path);
+		return NULL;
+	}
+
+	argvlist = PyMem_NEW(char *, argc+1);
+	if (argvlist == NULL) {
+		PyMem_Free(path);
+		return PyErr_NoMemory();
+	}
+	for (i = 0; i < argc; i++) {
+		if (!PyArg_Parse((*getitem)(argv, i), "et",
+				 Py_FileSystemDefaultEncoding,
+				 &argvlist[i])) {
+			free_string_array(argvlist, i);
+			PyErr_SetString(
+				PyExc_TypeError,
+				"spawnv() arg 2 must contain only strings");
+			PyMem_Free(path);
+			return NULL;
+		}
+	}
+	argvlist[argc] = NULL;
+
+#if defined(PYOS_OS2) && defined(PYCC_GCC)
+	Py_BEGIN_ALLOW_THREADS
+	spawnval = spawnv(mode, path, argvlist);
+	Py_END_ALLOW_THREADS
+#else
+	if (mode == _OLD_P_OVERLAY)
+		mode = _P_OVERLAY;
+
+	Py_BEGIN_ALLOW_THREADS
+	spawnval = _spawnv(mode, path, argvlist);
+	Py_END_ALLOW_THREADS
+#endif
+
+	free_string_array(argvlist, argc);
+	PyMem_Free(path);
+
+	if (spawnval == -1)
+		return posix_error();
+	else
+#if SIZEOF_LONG == SIZEOF_VOID_P
+		return Py_BuildValue("l", (long) spawnval);
+#else
+		return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
+#endif
+}
+
+
+PyDoc_STRVAR(posix_spawnve__doc__,
+"spawnve(mode, path, args, env)\n\n\
+Execute the program 'path' in a new process.\n\
+\n\
+	mode: mode of process creation\n\
+	path: path of executable file\n\
+	args: tuple or list of arguments\n\
+	env: dictionary of strings mapping to strings");
+
+static PyObject *
+posix_spawnve(PyObject *self, PyObject *args)
+{
+	char *path;
+	PyObject *argv, *env;
+	char **argvlist;
+	char **envlist;
+	PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
+	int mode, pos, envc;
+	Py_ssize_t argc, i;
+	Py_intptr_t spawnval;
+	PyObject *(*getitem)(PyObject *, Py_ssize_t);
+	Py_ssize_t lastarg = 0;
+
+	/* spawnve has four arguments: (mode, path, argv, env), where
+	   argv is a list or tuple of strings and env is a dictionary
+	   like posix.environ. */
+
+	if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
+			      Py_FileSystemDefaultEncoding,
+			      &path, &argv, &env))
+		return NULL;
+	if (PyList_Check(argv)) {
+		argc = PyList_Size(argv);
+		getitem = PyList_GetItem;
+	}
+	else if (PyTuple_Check(argv)) {
+		argc = PyTuple_Size(argv);
+		getitem = PyTuple_GetItem;
+	}
+	else {
+		PyErr_SetString(PyExc_TypeError,
+				"spawnve() arg 2 must be a tuple or list");
+		goto fail_0;
+	}
+	if (!PyMapping_Check(env)) {
+		PyErr_SetString(PyExc_TypeError,
+				"spawnve() arg 3 must be a mapping object");
+		goto fail_0;
+	}
+
+	argvlist = PyMem_NEW(char *, argc+1);
+	if (argvlist == NULL) {
+		PyErr_NoMemory();
+		goto fail_0;
+	}
+	for (i = 0; i < argc; i++) {
+		if (!PyArg_Parse((*getitem)(argv, i),
+			     "et;spawnve() arg 2 must contain only strings",
+				 Py_FileSystemDefaultEncoding,
+				 &argvlist[i]))
+		{
+			lastarg = i;
+			goto fail_1;
+		}
+	}
+	lastarg = argc;
+	argvlist[argc] = NULL;
+
+	i = PyMapping_Size(env);
+	if (i < 0)
+		goto fail_1;
+	envlist = PyMem_NEW(char *, i + 1);
+	if (envlist == NULL) {
+		PyErr_NoMemory();
+		goto fail_1;
+	}
+	envc = 0;
+	keys = PyMapping_Keys(env);
+	vals = PyMapping_Values(env);
+	if (!keys || !vals)
+		goto fail_2;
+	if (!PyList_Check(keys) || !PyList_Check(vals)) {
+		PyErr_SetString(PyExc_TypeError,
+			"spawnve(): env.keys() or env.values() is not a list");
+		goto fail_2;
+	}
+
+	for (pos = 0; pos < i; pos++) {
+		char *p, *k, *v;
+		size_t len;
+
+		key = PyList_GetItem(keys, pos);
+		val = PyList_GetItem(vals, pos);
+		if (!key || !val)
+			goto fail_2;
+
+		if (!PyArg_Parse(
+			    key,
+			    "s;spawnve() arg 3 contains a non-string key",
+			    &k) ||
+		    !PyArg_Parse(
+			    val,
+			    "s;spawnve() arg 3 contains a non-string value",
+			    &v))
+		{
+			goto fail_2;
+		}
+		len = PyString_Size(key) + PyString_Size(val) + 2;
+		p = PyMem_NEW(char, len);
+		if (p == NULL) {
+			PyErr_NoMemory();
+			goto fail_2;
+		}
+		PyOS_snprintf(p, len, "%s=%s", k, v);
+		envlist[envc++] = p;
+	}
+	envlist[envc] = 0;
+
+#if defined(PYOS_OS2) && defined(PYCC_GCC)
+	Py_BEGIN_ALLOW_THREADS
+	spawnval = spawnve(mode, path, argvlist, envlist);
+	Py_END_ALLOW_THREADS
+#else
+	if (mode == _OLD_P_OVERLAY)
+		mode = _P_OVERLAY;
+
+	Py_BEGIN_ALLOW_THREADS
+	spawnval = _spawnve(mode, path, argvlist, envlist);
+	Py_END_ALLOW_THREADS
+#endif
+
+	if (spawnval == -1)
+		(void) posix_error();
+	else
+#if SIZEOF_LONG == SIZEOF_VOID_P
+		res = Py_BuildValue("l", (long) spawnval);
+#else
+		res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
+#endif
+
+  fail_2:
+	while (--envc >= 0)
+		PyMem_DEL(envlist[envc]);
+	PyMem_DEL(envlist);
+  fail_1:
+	free_string_array(argvlist, lastarg);
+	Py_XDECREF(vals);
+	Py_XDECREF(keys);
+  fail_0:
+	PyMem_Free(path);
+	return res;
+}
+
+/* OS/2 supports spawnvp & spawnvpe natively */
+#if defined(PYOS_OS2)
+PyDoc_STRVAR(posix_spawnvp__doc__,
+"spawnvp(mode, file, args)\n\n\
+Execute the program 'file' in a new process, using the environment\n\
+search path to find the file.\n\
+\n\
+	mode: mode of process creation\n\
+	file: executable file name\n\
+	args: tuple or list of strings");
+
+static PyObject *
+posix_spawnvp(PyObject *self, PyObject *args)
+{
+	char *path;
+	PyObject *argv;
+	char **argvlist;
+	int mode, i, argc;
+	Py_intptr_t spawnval;
+	PyObject *(*getitem)(PyObject *, Py_ssize_t);
+
+	/* spawnvp has three arguments: (mode, path, argv), where
+	   argv is a list or tuple of strings. */
+
+	if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
+			      Py_FileSystemDefaultEncoding,
+			      &path, &argv))
+		return NULL;
+	if (PyList_Check(argv)) {
+		argc = PyList_Size(argv);
+		getitem = PyList_GetItem;
+	}
+	else if (PyTuple_Check(argv)) {
+		argc = PyTuple_Size(argv);
+		getitem = PyTuple_GetItem;
+	}
+	else {
+		PyErr_SetString(PyExc_TypeError,
+				"spawnvp() arg 2 must be a tuple or list");
+		PyMem_Free(path);
+		return NULL;
+	}
+
+	argvlist = PyMem_NEW(char *, argc+1);
+	if (argvlist == NULL) {
+		PyMem_Free(path);
+		return PyErr_NoMemory();
+	}
+	for (i = 0; i < argc; i++) {
+		if (!PyArg_Parse((*getitem)(argv, i), "et",
+				 Py_FileSystemDefaultEncoding,
+				 &argvlist[i])) {
+			free_string_array(argvlist, i);
+			PyErr_SetString(
+				PyExc_TypeError,
+				"spawnvp() arg 2 must contain only strings");
+			PyMem_Free(path);
+			return NULL;
+		}
+	}
+	argvlist[argc] = NULL;
+
+	Py_BEGIN_ALLOW_THREADS
+#if defined(PYCC_GCC)
+	spawnval = spawnvp(mode, path, argvlist);
+#else
+	spawnval = _spawnvp(mode, path, argvlist);
+#endif
+	Py_END_ALLOW_THREADS
+
+	free_string_array(argvlist, argc);
+	PyMem_Free(path);
+
+	if (spawnval == -1)
+		return posix_error();
+	else
+		return Py_BuildValue("l", (long) spawnval);
+}
+
+
+PyDoc_STRVAR(posix_spawnvpe__doc__,
+"spawnvpe(mode, file, args, env)\n\n\
+Execute the program 'file' in a new process, using the environment\n\
+search path to find the file.\n\
+\n\
+	mode: mode of process creation\n\
+	file: executable file name\n\
+	args: tuple or list of arguments\n\
+	env: dictionary of strings mapping to strings");
+
+static PyObject *
+posix_spawnvpe(PyObject *self, PyObject *args)
+{
+	char *path;
+	PyObject *argv, *env;
+	char **argvlist;
+	char **envlist;
+	PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
+	int mode, i, pos, argc, envc;
+	Py_intptr_t spawnval;
+	PyObject *(*getitem)(PyObject *, Py_ssize_t);
+	int lastarg = 0;
+
+	/* spawnvpe has four arguments: (mode, path, argv, env), where
+	   argv is a list or tuple of strings and env is a dictionary
+	   like posix.environ. */
+
+	if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
+			      Py_FileSystemDefaultEncoding,
+			      &path, &argv, &env))
+		return NULL;
+	if (PyList_Check(argv)) {
+		argc = PyList_Size(argv);
+		getitem = PyList_GetItem;
+	}
+	else if (PyTuple_Check(argv)) {
+		argc = PyTuple_Size(argv);
+		getitem = PyTuple_GetItem;
+	}
+	else {
+		PyErr_SetString(PyExc_TypeError,
+				"spawnvpe() arg 2 must be a tuple or list");
+		goto fail_0;
+	}
+	if (!PyMapping_Check(env)) {
+		PyErr_SetString(PyExc_TypeError,
+				"spawnvpe() arg 3 must be a mapping object");
+		goto fail_0;
+	}
+
+	argvlist = PyMem_NEW(char *, argc+1);
+	if (argvlist == NULL) {
+		PyErr_NoMemory();
+		goto fail_0;
+	}
+	for (i = 0; i < argc; i++) {
+		if (!PyArg_Parse((*getitem)(argv, i),
+			     "et;spawnvpe() arg 2 must contain only strings",
+				 Py_FileSystemDefaultEncoding,
+				 &argvlist[i]))
+		{
+			lastarg = i;
+			goto fail_1;
+		}
+	}
+	lastarg = argc;
+	argvlist[argc] = NULL;
+
+	i = PyMapping_Size(env);
+	if (i < 0)
+		goto fail_1;
+	envlist = PyMem_NEW(char *, i + 1);
+	if (envlist == NULL) {
+		PyErr_NoMemory();
+		goto fail_1;
+	}
+	envc = 0;
+	keys = PyMapping_Keys(env);
+	vals = PyMapping_Values(env);
+	if (!keys || !vals)
+		goto fail_2;
+	if (!PyList_Check(keys) || !PyList_Check(vals)) {
+		PyErr_SetString(PyExc_TypeError,
+			"spawnvpe(): env.keys() or env.values() is not a list");
+		goto fail_2;
+	}
+
+	for (pos = 0; pos < i; pos++) {
+		char *p, *k, *v;
+		size_t len;
+
+		key = PyList_GetItem(keys, pos);
+		val = PyList_GetItem(vals, pos);
+		if (!key || !val)
+			goto fail_2;
+
+		if (!PyArg_Parse(
+			    key,
+			    "s;spawnvpe() arg 3 contains a non-string key",
+			    &k) ||
+		    !PyArg_Parse(
+			    val,
+			    "s;spawnvpe() arg 3 contains a non-string value",
+			    &v))
+		{
+			goto fail_2;
+		}
+		len = PyString_Size(key) + PyString_Size(val) + 2;
+		p = PyMem_NEW(char, len);
+		if (p == NULL) {
+			PyErr_NoMemory();
+			goto fail_2;
+		}
+		PyOS_snprintf(p, len, "%s=%s", k, v);
+		envlist[envc++] = p;
+	}
+	envlist[envc] = 0;
+
+	Py_BEGIN_ALLOW_THREADS
+#if defined(PYCC_GCC)
+	spawnval = spawnve(mode, path, argvlist, envlist);
+#else
+	spawnval = _spawnve(mode, path, argvlist, envlist);
+#endif
+	Py_END_ALLOW_THREADS
+
+	if (spawnval == -1)
+		(void) posix_error();
+	else
+		res = Py_BuildValue("l", (long) spawnval);
+
+  fail_2:
+	while (--envc >= 0)
+		PyMem_DEL(envlist[envc]);
+	PyMem_DEL(envlist);
+  fail_1:
+	free_string_array(argvlist, lastarg);
+	Py_XDECREF(vals);
+	Py_XDECREF(keys);
+  fail_0:
+	PyMem_Free(path);
+	return res;
+}
+#endif /* PYOS_OS2 */
+#endif /* HAVE_SPAWNV */
+
+
+#ifdef HAVE_FORK1
+PyDoc_STRVAR(posix_fork1__doc__,
+"fork1() -> pid\n\n\
+Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
+\n\
+Return 0 to child process and PID of child to parent process.");
+
+static PyObject *
+posix_fork1(PyObject *self, PyObject *noargs)
+{
+	int pid = fork1();
+	if (pid == -1)
+		return posix_error();
+	PyOS_AfterFork();
+	return PyInt_FromLong((long)pid);
+}
+#endif
+
+
+#ifdef HAVE_FORK
+PyDoc_STRVAR(posix_fork__doc__,
+"fork() -> pid\n\n\
+Fork a child process.\n\
+Return 0 to child process and PID of child to parent process.");
+
+static PyObject *
+posix_fork(PyObject *self, PyObject *noargs)
+{
+	int pid = fork();
+	if (pid == -1)
+		return posix_error();
+	if (pid == 0)
+		PyOS_AfterFork();
+	return PyInt_FromLong((long)pid);
+}
+#endif
+
+/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
+/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
+#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
+#define DEV_PTY_FILE "/dev/ptc"
+#define HAVE_DEV_PTMX
+#else
+#define DEV_PTY_FILE "/dev/ptmx"
+#endif
+
+#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
+#ifdef HAVE_PTY_H
+#include <pty.h>
+#else
+#ifdef HAVE_LIBUTIL_H
+#include <libutil.h>
+#endif /* HAVE_LIBUTIL_H */
+#endif /* HAVE_PTY_H */
+#ifdef HAVE_STROPTS_H
+#include <stropts.h>
+#endif
+#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
+
+#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
+PyDoc_STRVAR(posix_openpty__doc__,
+"openpty() -> (master_fd, slave_fd)\n\n\
+Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
+
+static PyObject *
+posix_openpty(PyObject *self, PyObject *noargs)
+{
+	int master_fd, slave_fd;
+#ifndef HAVE_OPENPTY
+	char * slave_name;
+#endif
+#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
+	PyOS_sighandler_t sig_saved;
+#ifdef sun
+	extern char *ptsname(int fildes);
+#endif
+#endif
+
+#ifdef HAVE_OPENPTY
+	if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
+		return posix_error();
+#elif defined(HAVE__GETPTY)
+	slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
+	if (slave_name == NULL)
+		return posix_error();
+
+	slave_fd = open(slave_name, O_RDWR);
+	if (slave_fd < 0)
+		return posix_error();
+#else
+	master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
+	if (master_fd < 0)
+		return posix_error();
+	sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
+	/* change permission of slave */
+	if (grantpt(master_fd) < 0) {
+		PyOS_setsig(SIGCHLD, sig_saved);
+		return posix_error();
+	}
+	/* unlock slave */
+	if (unlockpt(master_fd) < 0) {
+		PyOS_setsig(SIGCHLD, sig_saved);
+		return posix_error();
+	}
+	PyOS_setsig(SIGCHLD, sig_saved);
+	slave_name = ptsname(master_fd); /* get name of slave */
+	if (slave_name == NULL)
+		return posix_error();
+	slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
+	if (slave_fd < 0)
+		return posix_error();
+#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
+	ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
+	ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
+#ifndef __hpux
+	ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
+#endif /* __hpux */
+#endif /* HAVE_CYGWIN */
+#endif /* HAVE_OPENPTY */
+
+	return Py_BuildValue("(ii)", master_fd, slave_fd);
+
+}
+#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
+
+#ifdef HAVE_FORKPTY
+PyDoc_STRVAR(posix_forkpty__doc__,
+"forkpty() -> (pid, master_fd)\n\n\
+Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
+Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
+To both, return fd of newly opened pseudo-terminal.\n");
+
+static PyObject *
+posix_forkpty(PyObject *self, PyObject *noargs)
+{
+	int master_fd = -1, pid;
+
+	pid = forkpty(&master_fd, NULL, NULL, NULL);
+	if (pid == -1)
+		return posix_error();
+	if (pid == 0)
+		PyOS_AfterFork();
+	return Py_BuildValue("(ii)", pid, master_fd);
+}
+#endif
+
+#ifdef HAVE_GETEGID
+PyDoc_STRVAR(posix_getegid__doc__,
+"getegid() -> egid\n\n\
+Return the current process's effective group id.");
+
+static PyObject *
+posix_getegid(PyObject *self, PyObject *noargs)
+{
+	return PyInt_FromLong((long)getegid());
+}
+#endif
+
+
+#ifdef HAVE_GETEUID
+PyDoc_STRVAR(posix_geteuid__doc__,
+"geteuid() -> euid\n\n\
+Return the current process's effective user id.");
+
+static PyObject *
+posix_geteuid(PyObject *self, PyObject *noargs)
+{
+	return PyInt_FromLong((long)geteuid());
+}
+#endif
+
+
+#ifdef HAVE_GETGID
+PyDoc_STRVAR(posix_getgid__doc__,
+"getgid() -> gid\n\n\
+Return the current process's group id.");
+
+static PyObject *
+posix_getgid(PyObject *self, PyObject *noargs)
+{
+	return PyInt_FromLong((long)getgid());
+}
+#endif
+
+
+PyDoc_STRVAR(posix_getpid__doc__,
+"getpid() -> pid\n\n\
+Return the current process id");
+
+static PyObject *
+posix_getpid(PyObject *self, PyObject *noargs)
+{
+	return PyInt_FromLong((long)getpid());
+}
+
+
+#ifdef HAVE_GETGROUPS
+PyDoc_STRVAR(posix_getgroups__doc__,
+"getgroups() -> list of group IDs\n\n\
+Return list of supplemental group IDs for the process.");
+
+static PyObject *
+posix_getgroups(PyObject *self, PyObject *noargs)
+{
+    PyObject *result = NULL;
+
+#ifdef NGROUPS_MAX
+#define MAX_GROUPS NGROUPS_MAX
+#else
+        /* defined to be 16 on Solaris7, so this should be a small number */
+#define MAX_GROUPS 64
+#endif
+        gid_t grouplist[MAX_GROUPS];
+        int n;
+
+        n = getgroups(MAX_GROUPS, grouplist);
+        if (n < 0)
+            posix_error();
+        else {
+            result = PyList_New(n);
+            if (result != NULL) {
+                int i;
+                for (i = 0; i < n; ++i) {
+                    PyObject *o = PyInt_FromLong((long)grouplist[i]);
+                    if (o == NULL) {
+                        Py_DECREF(result);
+                        result = NULL;
+                        break;
+                    }
+                    PyList_SET_ITEM(result, i, o);
+                }
+            }
+        }
+
+    return result;
+}
+#endif
+
+#ifdef HAVE_GETPGID
+PyDoc_STRVAR(posix_getpgid__doc__,
+"getpgid(pid) -> pgid\n\n\
+Call the system call getpgid().");
+
+static PyObject *
+posix_getpgid(PyObject *self, PyObject *args)
+{
+	int pid, pgid;
+	if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
+		return NULL;
+	pgid = getpgid(pid);
+	if (pgid < 0)
+		return posix_error();
+	return PyInt_FromLong((long)pgid);
+}
+#endif /* HAVE_GETPGID */
+
+
+#ifdef HAVE_GETPGRP
+PyDoc_STRVAR(posix_getpgrp__doc__,
+"getpgrp() -> pgrp\n\n\
+Return the current process group id.");
+
+static PyObject *
+posix_getpgrp(PyObject *self, PyObject *noargs)
+{
+#ifdef GETPGRP_HAVE_ARG
+	return PyInt_FromLong((long)getpgrp(0));
+#else /* GETPGRP_HAVE_ARG */
+	return PyInt_FromLong((long)getpgrp());
+#endif /* GETPGRP_HAVE_ARG */
+}
+#endif /* HAVE_GETPGRP */
+
+
+#ifdef HAVE_SETPGRP
+PyDoc_STRVAR(posix_setpgrp__doc__,
+"setpgrp()\n\n\
+Make this process a session leader.");
+
+static PyObject *
+posix_setpgrp(PyObject *self, PyObject *noargs)
+{
+#ifdef SETPGRP_HAVE_ARG
+	if (setpgrp(0, 0) < 0)
+#else /* SETPGRP_HAVE_ARG */
+	if (setpgrp() < 0)
+#endif /* SETPGRP_HAVE_ARG */
+		return posix_error();
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+#endif /* HAVE_SETPGRP */
+
+#ifdef HAVE_GETPPID
+PyDoc_STRVAR(posix_getppid__doc__,
+"getppid() -> ppid\n\n\
+Return the parent's process id.");
+
+static PyObject *
+posix_getppid(PyObject *self, PyObject *noargs)
+{
+	return PyInt_FromLong((long)getppid());
+}
+#endif
+
+
+#ifdef HAVE_GETLOGIN
+PyDoc_STRVAR(posix_getlogin__doc__,
+"getlogin() -> string\n\n\
+Return the actual login name.");
+
+static PyObject *
+posix_getlogin(PyObject *self, PyObject *noargs)
+{
+        PyObject *result = NULL;
+        char *name;
+        int old_errno = errno;
+
+        errno = 0;
+        name = getlogin();
+        if (name == NULL) {
+            if (errno)
+                posix_error();
+            else
+                PyErr_SetString(PyExc_OSError,
+                                "unable to determine login name");
+        }
+        else
+            result = PyString_FromString(name);
+        errno = old_errno;
+
+    return result;
+}
+#endif
+
+#ifdef HAVE_GETUID
+PyDoc_STRVAR(posix_getuid__doc__,
+"getuid() -> uid\n\n\
+Return the current process's user id.");
+
+static PyObject *
+posix_getuid(PyObject *self, PyObject *noargs)
+{
+	return PyInt_FromLong((long)getuid());
+}
+#endif
+
+
+#ifdef HAVE_KILL
+PyDoc_STRVAR(posix_kill__doc__,
+"kill(pid, sig)\n\n\
+Kill a process with a signal.");
+
+static PyObject *
+posix_kill(PyObject *self, PyObject *args)
+{
+	int pid, sig;
+	if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
+		return NULL;
+#if defined(PYOS_OS2) && !defined(PYCC_GCC)
+    if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
+        APIRET rc;
+        if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
+            return os2_error(rc);
+
+    } else if (sig == XCPT_SIGNAL_KILLPROC) {
+        APIRET rc;
+        if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
+            return os2_error(rc);
+
+    } else
+        return NULL; /* Unrecognized Signal Requested */
+#else
+	if (kill(pid, sig) == -1)
+		return posix_error();
+#endif
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+#endif
+
+#ifdef HAVE_KILLPG
+PyDoc_STRVAR(posix_killpg__doc__,
+"killpg(pgid, sig)\n\n\
+Kill a process group with a signal.");
+
+static PyObject *
+posix_killpg(PyObject *self, PyObject *args)
+{
+	int pgid, sig;
+	if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
+		return NULL;
+	if (killpg(pgid, sig) == -1)
+		return posix_error();
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+#endif
+
+#ifdef HAVE_PLOCK
+
+#ifdef HAVE_SYS_LOCK_H
+#include <sys/lock.h>
+#endif
+
+PyDoc_STRVAR(posix_plock__doc__,
+"plock(op)\n\n\
+Lock program segments into memory.");
+
+static PyObject *
+posix_plock(PyObject *self, PyObject *args)
+{
+	int op;
+	if (!PyArg_ParseTuple(args, "i:plock", &op))
+		return NULL;
+	if (plock(op) == -1)
+		return posix_error();
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+#endif
+
+
+#ifdef HAVE_POPEN
+PyDoc_STRVAR(posix_popen__doc__,
+"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
+Open a pipe to/from a command returning a file object.");
+
+#if defined(PYOS_OS2)
+#if defined(PYCC_VACPP)
+static int
+async_system(const char *command)
+{
+	char errormsg[256], args[1024];
+	RESULTCODES rcodes;
+	APIRET rc;
+
+	char *shell = getenv("COMSPEC");
+	if (!shell)
+		shell = "cmd";
+
+	/* avoid overflowing the argument buffer */
+	if (strlen(shell) + 3 + strlen(command) >= 1024)
+		return ERROR_NOT_ENOUGH_MEMORY
+
+	args[0] = '\0';
+	strcat(args, shell);
+	strcat(args, "/c ");
+	strcat(args, command);
+
+	/* execute asynchronously, inheriting the environment */
+	rc = DosExecPgm(errormsg,
+			sizeof(errormsg),
+			EXEC_ASYNC,
+			args,
+			NULL,
+			&rcodes,
+			shell);
+	return rc;
+}
+
+static FILE *
+popen(const char *command, const char *mode, int pipesize, int *err)
+{
+	int oldfd, tgtfd;
+	HFILE pipeh[2];
+	APIRET rc;
+
+	/* mode determines which of stdin or stdout is reconnected to
+	 * the pipe to the child
+	 */
+	if (strchr(mode, 'r') != NULL) {
+		tgt_fd = 1;	/* stdout */
+	} else if (strchr(mode, 'w')) {
+		tgt_fd = 0;	/* stdin */
+	} else {
+		*err = ERROR_INVALID_ACCESS;
+		return NULL;
+	}
+
+	/* setup the pipe */
+	if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
+		*err = rc;
+		return NULL;
+	}
+
+	/* prevent other threads accessing stdio */
+	DosEnterCritSec();
+
+	/* reconnect stdio and execute child */
+	oldfd = dup(tgtfd);
+	close(tgtfd);
+	if (dup2(pipeh[tgtfd], tgtfd) == 0) {
+		DosClose(pipeh[tgtfd]);
+		rc = async_system(command);
+	}
+
+	/* restore stdio */
+	dup2(oldfd, tgtfd);
+	close(oldfd);
+
+	/* allow other threads access to stdio */
+	DosExitCritSec();
+
+	/* if execution of child was successful return file stream */
+	if (rc == NO_ERROR)
+		return fdopen(pipeh[1 - tgtfd], mode);
+	else {
+		DosClose(pipeh[1 - tgtfd]);
+		*err = rc;
+		return NULL;
+	}
+}
+
+static PyObject *
+posix_popen(PyObject *self, PyObject *args)
+{
+	char *name;
+	char *mode = "r";
+	int   err, bufsize = -1;
+	FILE *fp;
+	PyObject *f;
+	if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
+		return NULL;
+	Py_BEGIN_ALLOW_THREADS
+	fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
+	Py_END_ALLOW_THREADS
+	if (fp == NULL)
+		return os2_error(err);
+
+	f = PyFile_FromFile(fp, name, mode, fclose);
+	if (f != NULL)
+		PyFile_SetBufSize(f, bufsize);
+	return f;
+}
+
+#elif defined(PYCC_GCC)
+
+/* standard posix version of popen() support */
+static PyObject *
+posix_popen(PyObject *self, PyObject *args)
+{
+	char *name;
+	char *mode = "r";
+	int bufsize = -1;
+	FILE *fp;
+	PyObject *f;
+	if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
+		return NULL;
+	Py_BEGIN_ALLOW_THREADS
+	fp = popen(name, mode);
+	Py_END_ALLOW_THREADS
+	if (fp == NULL)
+		return posix_error();
+	f = PyFile_FromFile(fp, name, mode, pclose);
+	if (f != NULL)
+		PyFile_SetBufSize(f, bufsize);
+	return f;
+}
+
+/* fork() under OS/2 has lots'o'warts
+ * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
+ * most of this code is a ripoff of the win32 code, but using the
+ * capabilities of EMX's C library routines
+ */
+
+/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
+#define POPEN_1 1
+#define POPEN_2 2
+#define POPEN_3 3
+#define POPEN_4 4
+
+static PyObject *_PyPopen(char *, int, int, int);
+static int _PyPclose(FILE *file);
+
+/*
+ * Internal dictionary mapping popen* file pointers to process handles,
+ * for use when retrieving the process exit code.  See _PyPclose() below
+ * for more information on this dictionary's use.
+ */
+static PyObject *_PyPopenProcs = NULL;
+
+/* os2emx version of popen2()
+ *
+ * The result of this function is a pipe (file) connected to the
+ * process's stdin, and a pipe connected to the process's stdout.
+ */
+
+static PyObject *
+os2emx_popen2(PyObject *self, PyObject  *args)
+{
+	PyObject *f;
+	int tm=0;
+
+	char *cmdstring;
+	char *mode = "t";
+	int bufsize = -1;
+	if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
+		return NULL;
+
+	if (*mode == 't')
+		tm = O_TEXT;
+	else if (*mode != 'b') {
+		PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
+		return NULL;
+	} else
+		tm = O_BINARY;
+
+	f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
+
+	return f;
+}
+
+/*
+ * Variation on os2emx.popen2
+ *
+ * The result of this function is 3 pipes - the process's stdin,
+ * stdout and stderr
+ */
+
+static PyObject *
+os2emx_popen3(PyObject *self, PyObject *args)
+{
+	PyObject *f;
+	int tm = 0;
+
+	char *cmdstring;
+	char *mode = "t";
+	int bufsize = -1;
+	if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
+		return NULL;
+
+	if (*mode == 't')
+		tm = O_TEXT;
+	else if (*mode != 'b') {
+		PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
+		return NULL;
+	} else
+		tm = O_BINARY;
+
+	f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
+
+	return f;
+}
+
+/*
+ * Variation on os2emx.popen2
+ *
+ * The result of this function is 2 pipes - the processes stdin,
+ * and stdout+stderr combined as a single pipe.
+ */
+
+static PyObject *
+os2emx_popen4(PyObject *self, PyObject  *args)
+{
+	PyObject *f;
+	int tm = 0;
+
+	char *cmdstring;
+	char *mode = "t";
+	int bufsize = -1;
+	if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
+		return NULL;
+
+	if (*mode == 't')
+		tm = O_TEXT;
+	else if (*mode != 'b') {
+		PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
+		return NULL;
+	} else
+		tm = O_BINARY;
+
+	f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
+
+	return f;
+}
+
+/* a couple of structures for convenient handling of multiple
+ * file handles and pipes
+ */
+struct file_ref
+{
+	int handle;
+	int flags;
+};
+
+struct pipe_ref
+{
+	int rd;
+	int wr;
+};
+
+/* The following code is derived from the win32 code */
+
+static PyObject *
+_PyPopen(char *cmdstring, int mode, int n, int bufsize)
+{
+	struct file_ref stdio[3];
+	struct pipe_ref p_fd[3];
+	FILE *p_s[3];
+	int file_count, i, pipe_err, pipe_pid;
+	char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
+	PyObject *f, *p_f[3];
+
+	/* file modes for subsequent fdopen's on pipe handles */
+	if (mode == O_TEXT)
+	{
+		rd_mode = "rt";
+		wr_mode = "wt";
+	}
+	else
+	{
+		rd_mode = "rb";
+		wr_mode = "wb";
+	}
+
+	/* prepare shell references */
+	if ((shell = getenv("EMXSHELL")) == NULL)
+		if ((shell = getenv("COMSPEC")) == NULL)
+		{
+			errno = ENOENT;
+			return posix_error();
+		}
+
+	sh_name = _getname(shell);
+	if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
+		opt = "/c";
+	else
+		opt = "-c";
+
+	/* save current stdio fds + their flags, and set not inheritable */
+	i = pipe_err = 0;
+	while (pipe_err >= 0 && i < 3)
+	{
+		pipe_err = stdio[i].handle = dup(i);
+		stdio[i].flags = fcntl(i, F_GETFD, 0);
+		fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
+		i++;
+	}
+	if (pipe_err < 0)
+	{
+		/* didn't get them all saved - clean up and bail out */
+		int saved_err = errno;
+		while (i-- > 0)
+		{
+			close(stdio[i].handle);
+		}
+		errno = saved_err;
+		return posix_error();
+	}
+
+	/* create pipe ends */
+	file_count = 2;
+	if (n == POPEN_3)
+		file_count = 3;
+	i = pipe_err = 0;
+	while ((pipe_err == 0) && (i < file_count))
+		pipe_err = pipe((int *)&p_fd[i++]);
+	if (pipe_err < 0)
+	{
+		/* didn't get them all made - clean up and bail out */
+		while (i-- > 0)
+		{
+			close(p_fd[i].wr);
+			close(p_fd[i].rd);
+		}
+		errno = EPIPE;
+		return posix_error();
+	}
+
+	/* change the actual standard IO streams over temporarily,
+	 * making the retained pipe ends non-inheritable
+	 */
+	pipe_err = 0;
+
+	/* - stdin */
+	if (dup2(p_fd[0].rd, 0) == 0)
+	{
+		close(p_fd[0].rd);
+		i = fcntl(p_fd[0].wr, F_GETFD, 0);
+		fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
+		if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
+		{
+			close(p_fd[0].wr);
+			pipe_err = -1;
+		}
+	}
+	else
+	{
+		pipe_err = -1;
+	}
+
+	/* - stdout */
+	if (pipe_err == 0)
+	{
+		if (dup2(p_fd[1].wr, 1) == 1)
+		{
+			close(p_fd[1].wr);
+			i = fcntl(p_fd[1].rd, F_GETFD, 0);
+			fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
+			if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
+			{
+				close(p_fd[1].rd);
+				pipe_err = -1;
+			}
+		}
+		else
+		{
+			pipe_err = -1;
+		}
+	}
+
+	/* - stderr, as required */
+	if (pipe_err == 0)
+		switch (n)
+		{
+			case POPEN_3:
+			{
+				if (dup2(p_fd[2].wr, 2) == 2)
+				{
+					close(p_fd[2].wr);
+					i = fcntl(p_fd[2].rd, F_GETFD, 0);
+					fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
+					if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
+					{
+						close(p_fd[2].rd);
+						pipe_err = -1;
+					}
+				}
+				else
+				{
+					pipe_err = -1;
+				}
+				break;
+			}
+
+			case POPEN_4:
+			{
+				if (dup2(1, 2) != 2)
+				{
+					pipe_err = -1;
+				}
+				break;
+			}
+		}
+
+	/* spawn the child process */
+	if (pipe_err == 0)
+	{
+		pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
+		if (pipe_pid == -1)
+		{
+			pipe_err = -1;
+		}
+		else
+		{
+			/* save the PID into the FILE structure
+			 * NOTE: this implementation doesn't actually
+			 * take advantage of this, but do it for
+			 * completeness - AIM Apr01
+			 */
+			for (i = 0; i < file_count; i++)
+				p_s[i]->_pid = pipe_pid;
+		}
+	}
+
+	/* reset standard IO to normal */
+	for (i = 0; i < 3; i++)
+	{
+		dup2(stdio[i].handle, i);
+		fcntl(i, F_SETFD, stdio[i].flags);
+		close(stdio[i].handle);
+	}
+
+	/* if any remnant problems, clean up and bail out */
+	if (pipe_err < 0)
+	{
+		for (i = 0; i < 3; i++)
+		{
+			close(p_fd[i].rd);
+			close(p_fd[i].wr);
+		}
+		errno = EPIPE;
+		return posix_error_with_filename(cmdstring);
+	}
+
+	/* build tuple of file objects to return */
+	if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
+		PyFile_SetBufSize(p_f[0], bufsize);
+	if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
+		PyFile_SetBufSize(p_f[1], bufsize);
+	if (n == POPEN_3)
+	{
+		if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
+			PyFile_SetBufSize(p_f[0], bufsize);
+		f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
+	}
+	else
+		f = PyTuple_Pack(2, p_f[0], p_f[1]);
+
+	/*
+	 * Insert the files we've created into the process dictionary
+	 * all referencing the list with the process handle and the
+	 * initial number of files (see description below in _PyPclose).
+	 * Since if _PyPclose later tried to wait on a process when all
+	 * handles weren't closed, it could create a deadlock with the
+	 * child, we spend some energy here to try to ensure that we
+	 * either insert all file handles into the dictionary or none
+	 * at all.  It's a little clumsy with the various popen modes
+	 * and variable number of files involved.
+	 */
+	if (!_PyPopenProcs)
+	{
+		_PyPopenProcs = PyDict_New();
+	}
+
+	if (_PyPopenProcs)
+	{
+		PyObject *procObj, *pidObj, *intObj, *fileObj[3];
+		int ins_rc[3];
+
+		fileObj[0] = fileObj[1] = fileObj[2] = NULL;
+		ins_rc[0]  = ins_rc[1]  = ins_rc[2]  = 0;
+
+		procObj = PyList_New(2);
+		pidObj = PyInt_FromLong((long) pipe_pid);
+		intObj = PyInt_FromLong((long) file_count);
+
+		if (procObj && pidObj && intObj)
+		{
+			PyList_SetItem(procObj, 0, pidObj);
+			PyList_SetItem(procObj, 1, intObj);
+
+			fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
+			if (fileObj[0])
+			{
+			    ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
+						       fileObj[0],
+						       procObj);
+			}
+			fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
+			if (fileObj[1])
+			{
+			    ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
+						       fileObj[1],
+						       procObj);
+			}
+			if (file_count >= 3)
+			{
+				fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
+				if (fileObj[2])
+				{
+				    ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
+							       fileObj[2],
+							       procObj);
+				}
+			}
+
+			if (ins_rc[0] < 0 || !fileObj[0] ||
+			    ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
+			    ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
+			{
+				/* Something failed - remove any dictionary
+				 * entries that did make it.
+				 */
+				if (!ins_rc[0] && fileObj[0])
+				{
+					PyDict_DelItem(_PyPopenProcs,
+							fileObj[0]);
+				}
+				if (!ins_rc[1] && fileObj[1])
+				{
+					PyDict_DelItem(_PyPopenProcs,
+							fileObj[1]);
+				}
+				if (!ins_rc[2] && fileObj[2])
+				{
+					PyDict_DelItem(_PyPopenProcs,
+							fileObj[2]);
+				}
+			}
+		}
+
+		/*
+		 * Clean up our localized references for the dictionary keys
+		 * and value since PyDict_SetItem will Py_INCREF any copies
+		 * that got placed in the dictionary.
+		 */
+		Py_XDECREF(procObj);
+		Py_XDECREF(fileObj[0]);
+		Py_XDECREF(fileObj[1]);
+		Py_XDECREF(fileObj[2]);
+	}
+
+	/* Child is launched. */
+	return f;
+}
+
+/*
+ * Wrapper for fclose() to use for popen* files, so we can retrieve the
+ * exit code for the child process and return as a result of the close.
+ *
+ * This function uses the _PyPopenProcs dictionary in order to map the
+ * input file pointer to information about the process that was
+ * originally created by the popen* call that created the file pointer.
+ * The dictionary uses the file pointer as a key (with one entry
+ * inserted for each file returned by the original popen* call) and a
+ * single list object as the value for all files from a single call.
+ * The list object contains the Win32 process handle at [0], and a file
+ * count at [1], which is initialized to the total number of file
+ * handles using that list.
+ *
+ * This function closes whichever handle it is passed, and decrements
+ * the file count in the dictionary for the process handle pointed to
+ * by this file.  On the last close (when the file count reaches zero),
+ * this function will wait for the child process and then return its
+ * exit code as the result of the close() operation.  This permits the
+ * files to be closed in any order - it is always the close() of the
+ * final handle that will return the exit code.
+ *
+ * NOTE: This function is currently called with the GIL released.
+ * hence we use the GILState API to manage our state.
+ */
+
+static int _PyPclose(FILE *file)
+{
+	int result;
+	int exit_code;
+	int pipe_pid;
+	PyObject *procObj, *pidObj, *intObj, *fileObj;
+	int file_count;
+#ifdef WITH_THREAD
+	PyGILState_STATE state;
+#endif
+
+	/* Close the file handle first, to ensure it can't block the
+	 * child from exiting if it's the last handle.
+	 */
+	result = fclose(file);
+
+#ifdef WITH_THREAD
+	state = PyGILState_Ensure();
+#endif
+	if (_PyPopenProcs)
+	{
+		if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
+		    (procObj = PyDict_GetItem(_PyPopenProcs,
+					      fileObj)) != NULL &&
+		    (pidObj = PyList_GetItem(procObj,0)) != NULL &&
+		    (intObj = PyList_GetItem(procObj,1)) != NULL)
+		{
+			pipe_pid = (int) PyInt_AsLong(pidObj);
+			file_count = (int) PyInt_AsLong(intObj);
+
+			if (file_count > 1)
+			{
+				/* Still other files referencing process */
+				file_count--;
+				PyList_SetItem(procObj,1,
+					       PyInt_FromLong((long) file_count));
+			}
+			else
+			{
+				/* Last file for this process */
+				if (result != EOF &&
+				    waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
+				{
+					/* extract exit status */
+					if (WIFEXITED(exit_code))
+					{
+						result = WEXITSTATUS(exit_code);
+					}
+					else
+					{
+						errno = EPIPE;
+						result = -1;
+					}
+				}
+				else
+				{
+					/* Indicate failure - this will cause the file object
+					 * to raise an I/O error and translate the last
+					 * error code from errno.  We do have a problem with
+					 * last errors that overlap the normal errno table,
+					 * but that's a consistent problem with the file object.
+					 */
+					result = -1;
+				}
+			}
+
+			/* Remove this file pointer from dictionary */
+			PyDict_DelItem(_PyPopenProcs, fileObj);
+
+			if (PyDict_Size(_PyPopenProcs) == 0)
+			{
+				Py_DECREF(_PyPopenProcs);
+				_PyPopenProcs = NULL;
+			}
+
+		} /* if object retrieval ok */
+
+		Py_XDECREF(fileObj);
+	} /* if _PyPopenProcs */
+
+#ifdef WITH_THREAD
+	PyGILState_Release(state);
+#endif
+	return result;
+}
+
+#endif /* PYCC_??? */
+
+#elif defined(MS_WINDOWS)
+
+/*
+ * Portable 'popen' replacement for Win32.
+ *
+ * Written by Bill Tutt <billtut at microsoft.com>.  Minor tweaks
+ * and 2.0 integration by Fredrik Lundh <fredrik at pythonware.com>
+ * Return code handling by David Bolen <db3l at fitlinxx.com>.
+ */
+
+#include <malloc.h>
+#include <io.h>
+#include <fcntl.h>
+
+/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
+#define POPEN_1 1
+#define POPEN_2 2
+#define POPEN_3 3
+#define POPEN_4 4
+
+static PyObject *_PyPopen(char *, int, int);
+static int _PyPclose(FILE *file);
+
+/*
+ * Internal dictionary mapping popen* file pointers to process handles,
+ * for use when retrieving the process exit code.  See _PyPclose() below
+ * for more information on this dictionary's use.
+ */
+static PyObject *_PyPopenProcs = NULL;
+
+
+/* popen that works from a GUI.
+ *
+ * The result of this function is a pipe (file) connected to the
+ * processes stdin or stdout, depending on the requested mode.
+ */
+
+static PyObject *
+posix_popen(PyObject *self, PyObject *args)
+{
+	PyObject *f;
+	int tm = 0;
+
+	char *cmdstring;
+	char *mode = "r";
+	int bufsize = -1;
+	if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
+		return NULL;
+
+	if (*mode == 'r')
+		tm = _O_RDONLY;
+	else if (*mode != 'w') {
+		PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
+		return NULL;
+	} else
+		tm = _O_WRONLY;
+
+	if (bufsize != -1) {
+		PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
+		return NULL;
+	}
+
+	if (*(mode+1) == 't')
+		f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
+	else if (*(mode+1) == 'b')
+		f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
+	else
+		f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
+
+	return f;
+}
+
+/* Variation on win32pipe.popen
+ *
+ * The result of this function is a pipe (file) connected to the
+ * process's stdin, and a pipe connected to the process's stdout.
+ */
+
+static PyObject *
+win32_popen2(PyObject *self, PyObject  *args)
+{
+	PyObject *f;
+	int tm=0;
+
+	char *cmdstring;
+	char *mode = "t";
+	int bufsize = -1;
+	if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
+		return NULL;
+
+	if (*mode == 't')
+		tm = _O_TEXT;
+	else if (*mode != 'b') {
+		PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
+		return NULL;
+	} else
+		tm = _O_BINARY;
+
+	if (bufsize != -1) {
+		PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
+		return NULL;
+	}
+
+	f = _PyPopen(cmdstring, tm, POPEN_2);
+
+	return f;
+}
+
+/*
+ * Variation on <om win32pipe.popen>
+ *
+ * The result of this function is 3 pipes - the process's stdin,
+ * stdout and stderr
+ */
+
+static PyObject *
+win32_popen3(PyObject *self, PyObject *args)
+{
+	PyObject *f;
+	int tm = 0;
+
+	char *cmdstring;
+	char *mode = "t";
+	int bufsize = -1;
+	if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
+		return NULL;
+
+	if (*mode == 't')
+		tm = _O_TEXT;
+	else if (*mode != 'b') {
+		PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
+		return NULL;
+	} else
+		tm = _O_BINARY;
+
+	if (bufsize != -1) {
+		PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
+		return NULL;
+	}
+
+	f = _PyPopen(cmdstring, tm, POPEN_3);
+
+	return f;
+}
+
+/*
+ * Variation on win32pipe.popen
+ *
+ * The result of this function is 2 pipes - the processes stdin,
+ * and stdout+stderr combined as a single pipe.
+ */
+
+static PyObject *
+win32_popen4(PyObject *self, PyObject  *args)
+{
+	PyObject *f;
+	int tm = 0;
+
+	char *cmdstring;
+	char *mode = "t";
+	int bufsize = -1;
+	if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
+		return NULL;
+
+	if (*mode == 't')
+		tm = _O_TEXT;
+	else if (*mode != 'b') {
+		PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
+		return NULL;
+	} else
+		tm = _O_BINARY;
+
+	if (bufsize != -1) {
+		PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
+		return NULL;
+	}
+
+	f = _PyPopen(cmdstring, tm, POPEN_4);
+
+	return f;
+}
+
+static BOOL
+_PyPopenCreateProcess(char *cmdstring,
+		      HANDLE hStdin,
+		      HANDLE hStdout,
+		      HANDLE hStderr,
+		      HANDLE *hProcess)
+{
+	PROCESS_INFORMATION piProcInfo;
+	STARTUPINFO siStartInfo;
+	DWORD dwProcessFlags = 0;  /* no NEW_CONSOLE by default for Ctrl+C handling */
+	char *s1,*s2, *s3 = " /c ";
+	const char *szConsoleSpawn = "w9xpopen.exe";
+	int i;
+	Py_ssize_t x;
+
+	if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
+		char *comshell;
+
+		s1 = (char *)alloca(i);
+		if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
+			/* x < i, so x fits into an integer */
+			return (int)x;
+
+		/* Explicitly check if we are using COMMAND.COM.  If we are
+		 * then use the w9xpopen hack.
+		 */
+		comshell = s1 + x;
+		while (comshell >= s1 && *comshell != '\\')
+			--comshell;
+		++comshell;
+
+		if (GetVersion() < 0x80000000 &&
+		    _stricmp(comshell, "command.com") != 0) {
+			/* NT/2000 and not using command.com. */
+			x = i + strlen(s3) + strlen(cmdstring) + 1;
+			s2 = (char *)alloca(x);
+			ZeroMemory(s2, x);
+			PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
+		}
+		else {
+			/*
+			 * Oh gag, we're on Win9x or using COMMAND.COM. Use
+			 * the workaround listed in KB: Q150956
+			 */
+			char modulepath[_MAX_PATH];
+			struct stat statinfo;
+			GetModuleFileName(NULL, modulepath, sizeof(modulepath));
+			for (x = i = 0; modulepath[i]; i++)
+				if (modulepath[i] == SEP)
+					x = i+1;
+			modulepath[x] = '\0';
+			/* Create the full-name to w9xpopen, so we can test it exists */
+			strncat(modulepath,
+			        szConsoleSpawn,
+			        (sizeof(modulepath)/sizeof(modulepath[0]))
+			               -strlen(modulepath));
+			if (stat(modulepath, &statinfo) != 0) {
+				/* Eeek - file-not-found - possibly an embedding
+				   situation - see if we can locate it in sys.prefix
+				*/
+				strncpy(modulepath,
+				        Py_GetExecPrefix(),
+				        sizeof(modulepath)/sizeof(modulepath[0]));
+				if (modulepath[strlen(modulepath)-1] != '\\')
+					strcat(modulepath, "\\");
+				strncat(modulepath,
+				        szConsoleSpawn,
+				        (sizeof(modulepath)/sizeof(modulepath[0]))
+				               -strlen(modulepath));
+				/* No where else to look - raise an easily identifiable
+				   error, rather than leaving Windows to report
+				   "file not found" - as the user is probably blissfully
+				   unaware this shim EXE is used, and it will confuse them.
+				   (well, it confused me for a while ;-)
+				*/
+				if (stat(modulepath, &statinfo) != 0) {
+					PyErr_Format(PyExc_RuntimeError,
+					    "Can not locate '%s' which is needed "
+					    "for popen to work with your shell "
+					    "or platform.",
+					    szConsoleSpawn);
+					return FALSE;
+				}
+			}
+			x = i + strlen(s3) + strlen(cmdstring) + 1 +
+				strlen(modulepath) +
+				strlen(szConsoleSpawn) + 1;
+
+			s2 = (char *)alloca(x);
+			ZeroMemory(s2, x);
+			/* To maintain correct argument passing semantics,
+			   we pass the command-line as it stands, and allow
+			   quoting to be applied.  w9xpopen.exe will then
+			   use its argv vector, and re-quote the necessary
+			   args for the ultimate child process.
+			*/
+			PyOS_snprintf(
+				s2, x,
+				"\"%s\" %s%s%s",
+				modulepath,
+				s1,
+				s3,
+				cmdstring);
+			/* Not passing CREATE_NEW_CONSOLE has been known to
+			   cause random failures on win9x.  Specifically a
+			   dialog:
+			   "Your program accessed mem currently in use at xxx"
+			   and a hopeful warning about the stability of your
+			   system.
+			   Cost is Ctrl+C wont kill children, but anyone
+			   who cares can have a go!
+			*/
+			dwProcessFlags |= CREATE_NEW_CONSOLE;
+		}
+	}
+
+	/* Could be an else here to try cmd.exe / command.com in the path
+	   Now we'll just error out.. */
+	else {
+		PyErr_SetString(PyExc_RuntimeError,
+			"Cannot locate a COMSPEC environment variable to "
+			"use as the shell");
+		return FALSE;
+	}
+
+	ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
+	siStartInfo.cb = sizeof(STARTUPINFO);
+	siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
+	siStartInfo.hStdInput = hStdin;
+	siStartInfo.hStdOutput = hStdout;
+	siStartInfo.hStdError = hStderr;
+	siStartInfo.wShowWindow = SW_HIDE;
+
+	if (CreateProcess(NULL,
+			  s2,
+			  NULL,
+			  NULL,
+			  TRUE,
+			  dwProcessFlags,
+			  NULL,
+			  NULL,
+			  &siStartInfo,
+			  &piProcInfo) ) {
+		/* Close the handles now so anyone waiting is woken. */
+		CloseHandle(piProcInfo.hThread);
+
+		/* Return process handle */
+		*hProcess = piProcInfo.hProcess;
+		return TRUE;
+	}
+	win32_error("CreateProcess", s2);
+	return FALSE;
+}
+
+/* The following code is based off of KB: Q190351 */
+
+static PyObject *
+_PyPopen(char *cmdstring, int mode, int n)
+{
+	HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
+		hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
+		hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
+
+	SECURITY_ATTRIBUTES saAttr;
+	BOOL fSuccess;
+	int fd1, fd2, fd3;
+	FILE *f1, *f2, *f3;
+	long file_count;
+	PyObject *f;
+
+	saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
+	saAttr.bInheritHandle = TRUE;
+	saAttr.lpSecurityDescriptor = NULL;
+
+	if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
+		return win32_error("CreatePipe", NULL);
+
+	/* Create new output read handle and the input write handle. Set
+	 * the inheritance properties to FALSE. Otherwise, the child inherits
+	 * these handles; resulting in non-closeable handles to the pipes
+	 * being created. */
+	 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
+				    GetCurrentProcess(), &hChildStdinWrDup, 0,
+				    FALSE,
+				    DUPLICATE_SAME_ACCESS);
+	 if (!fSuccess)
+		 return win32_error("DuplicateHandle", NULL);
+
+	 /* Close the inheritable version of ChildStdin
+	that we're using. */
+	 CloseHandle(hChildStdinWr);
+
+	 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
+		 return win32_error("CreatePipe", NULL);
+
+	 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
+				    GetCurrentProcess(), &hChildStdoutRdDup, 0,
+				    FALSE, DUPLICATE_SAME_ACCESS);
+	 if (!fSuccess)
+		 return win32_error("DuplicateHandle", NULL);
+
+	 /* Close the inheritable version of ChildStdout
+		that we're using. */
+	 CloseHandle(hChildStdoutRd);
+
+	 if (n != POPEN_4) {
+		 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
+			 return win32_error("CreatePipe", NULL);
+		 fSuccess = DuplicateHandle(GetCurrentProcess(),
+					    hChildStderrRd,
+					    GetCurrentProcess(),
+					    &hChildStderrRdDup, 0,
+					    FALSE, DUPLICATE_SAME_ACCESS);
+		 if (!fSuccess)
+			 return win32_error("DuplicateHandle", NULL);
+		 /* Close the inheritable version of ChildStdErr that we're using. */
+		 CloseHandle(hChildStderrRd);
+	 }
+
+	 switch (n) {
+	 case POPEN_1:
+		 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
+		 case _O_WRONLY | _O_TEXT:
+			 /* Case for writing to child Stdin in text mode. */
+			 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
+			 f1 = _fdopen(fd1, "w");
+			 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
+			 PyFile_SetBufSize(f, 0);
+			 /* We don't care about these pipes anymore, so close them. */
+			 CloseHandle(hChildStdoutRdDup);
+			 CloseHandle(hChildStderrRdDup);
+			 break;
+
+		 case _O_RDONLY | _O_TEXT:
+			 /* Case for reading from child Stdout in text mode. */
+			 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
+			 f1 = _fdopen(fd1, "r");
+			 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
+			 PyFile_SetBufSize(f, 0);
+			 /* We don't care about these pipes anymore, so close them. */
+			 CloseHandle(hChildStdinWrDup);
+			 CloseHandle(hChildStderrRdDup);
+			 break;
+
+		 case _O_RDONLY | _O_BINARY:
+			 /* Case for readinig from child Stdout in binary mode. */
+			 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
+			 f1 = _fdopen(fd1, "rb");
+			 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
+			 PyFile_SetBufSize(f, 0);
+			 /* We don't care about these pipes anymore, so close them. */
+			 CloseHandle(hChildStdinWrDup);
+			 CloseHandle(hChildStderrRdDup);
+			 break;
+
+		 case _O_WRONLY | _O_BINARY:
+			 /* Case for writing to child Stdin in binary mode. */
+			 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
+			 f1 = _fdopen(fd1, "wb");
+			 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
+			 PyFile_SetBufSize(f, 0);
+			 /* We don't care about these pipes anymore, so close them. */
+			 CloseHandle(hChildStdoutRdDup);
+			 CloseHandle(hChildStderrRdDup);
+			 break;
+		 }
+		 file_count = 1;
+		 break;
+
+	 case POPEN_2:
+	 case POPEN_4:
+	 {
+		 char *m1, *m2;
+		 PyObject *p1, *p2;
+
+		 if (mode & _O_TEXT) {
+			 m1 = "r";
+			 m2 = "w";
+		 } else {
+			 m1 = "rb";
+			 m2 = "wb";
+		 }
+
+		 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
+		 f1 = _fdopen(fd1, m2);
+		 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
+		 f2 = _fdopen(fd2, m1);
+		 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
+		 PyFile_SetBufSize(p1, 0);
+		 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
+		 PyFile_SetBufSize(p2, 0);
+
+		 if (n != 4)
+			 CloseHandle(hChildStderrRdDup);
+
+		 f = PyTuple_Pack(2,p1,p2);
+		 Py_XDECREF(p1);
+		 Py_XDECREF(p2);
+		 file_count = 2;
+		 break;
+	 }
+
+	 case POPEN_3:
+	 {
+		 char *m1, *m2;
+		 PyObject *p1, *p2, *p3;
+
+		 if (mode & _O_TEXT) {
+			 m1 = "r";
+			 m2 = "w";
+		 } else {
+			 m1 = "rb";
+			 m2 = "wb";
+		 }
+
+		 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
+		 f1 = _fdopen(fd1, m2);
+		 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
+		 f2 = _fdopen(fd2, m1);
+		 fd3 = _open_osfhandle((Py_intptr_t)hChildStderrRdDup, mode);
+		 f3 = _fdopen(fd3, m1);
+		 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
+		 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
+		 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
+		 PyFile_SetBufSize(p1, 0);
+		 PyFile_SetBufSize(p2, 0);
+		 PyFile_SetBufSize(p3, 0);
+		 f = PyTuple_Pack(3,p1,p2,p3);
+		 Py_XDECREF(p1);
+		 Py_XDECREF(p2);
+		 Py_XDECREF(p3);
+		 file_count = 3;
+		 break;
+	 }
+	 }
+
+	 if (n == POPEN_4) {
+		 if (!_PyPopenCreateProcess(cmdstring,
+					    hChildStdinRd,
+					    hChildStdoutWr,
+					    hChildStdoutWr,
+					    &hProcess))
+			 return NULL;
+	 }
+	 else {
+		 if (!_PyPopenCreateProcess(cmdstring,
+					    hChildStdinRd,
+					    hChildStdoutWr,
+					    hChildStderrWr,
+					    &hProcess))
+			 return NULL;
+	 }
+
+	 /*
+	  * Insert the files we've created into the process dictionary
+	  * all referencing the list with the process handle and the
+	  * initial number of files (see description below in _PyPclose).
+	  * Since if _PyPclose later tried to wait on a process when all
+	  * handles weren't closed, it could create a deadlock with the
+	  * child, we spend some energy here to try to ensure that we
+	  * either insert all file handles into the dictionary or none
+	  * at all.  It's a little clumsy with the various popen modes
+	  * and variable number of files involved.
+	  */
+	 if (!_PyPopenProcs) {
+		 _PyPopenProcs = PyDict_New();
+	 }
+
+	 if (_PyPopenProcs) {
+		 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
+		 int ins_rc[3];
+
+		 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
+		 ins_rc[0]  = ins_rc[1]  = ins_rc[2]  = 0;
+
+		 procObj = PyList_New(2);
+		 hProcessObj = PyLong_FromVoidPtr(hProcess);
+		 intObj = PyInt_FromLong(file_count);
+
+		 if (procObj && hProcessObj && intObj) {
+			 PyList_SetItem(procObj,0,hProcessObj);
+			 PyList_SetItem(procObj,1,intObj);
+
+			 fileObj[0] = PyLong_FromVoidPtr(f1);
+			 if (fileObj[0]) {
+			    ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
+						       fileObj[0],
+						       procObj);
+			 }
+			 if (file_count >= 2) {
+				 fileObj[1] = PyLong_FromVoidPtr(f2);
+				 if (fileObj[1]) {
+				    ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
+							       fileObj[1],
+							       procObj);
+				 }
+			 }
+			 if (file_count >= 3) {
+				 fileObj[2] = PyLong_FromVoidPtr(f3);
+				 if (fileObj[2]) {
+				    ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
+							       fileObj[2],
+							       procObj);
+				 }
+			 }
+
+			 if (ins_rc[0] < 0 || !fileObj[0] ||
+			     ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
+			     ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
+				 /* Something failed - remove any dictionary
+				  * entries that did make it.
+				  */
+				 if (!ins_rc[0] && fileObj[0]) {
+					 PyDict_DelItem(_PyPopenProcs,
+							fileObj[0]);
+				 }
+				 if (!ins_rc[1] && fileObj[1]) {
+					 PyDict_DelItem(_PyPopenProcs,
+							fileObj[1]);
+				 }
+				 if (!ins_rc[2] && fileObj[2]) {
+					 PyDict_DelItem(_PyPopenProcs,
+							fileObj[2]);
+				 }
+			 }
+		 }
+
+		 /*
+		  * Clean up our localized references for the dictionary keys
+		  * and value since PyDict_SetItem will Py_INCREF any copies
+		  * that got placed in the dictionary.
+		  */
+		 Py_XDECREF(procObj);
+		 Py_XDECREF(fileObj[0]);
+		 Py_XDECREF(fileObj[1]);
+		 Py_XDECREF(fileObj[2]);
+	 }
+
+	 /* Child is launched. Close the parents copy of those pipe
+	  * handles that only the child should have open.  You need to
+	  * make sure that no handles to the write end of the output pipe
+	  * are maintained in this process or else the pipe will not close
+	  * when the child process exits and the ReadFile will hang. */
+
+	 if (!CloseHandle(hChildStdinRd))
+		 return win32_error("CloseHandle", NULL);
+
+	 if (!CloseHandle(hChildStdoutWr))
+		 return win32_error("CloseHandle", NULL);
+
+	 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
+		 return win32_error("CloseHandle", NULL);
+
+	 return f;
+}
+
+/*
+ * Wrapper for fclose() to use for popen* files, so we can retrieve the
+ * exit code for the child process and return as a result of the close.
+ *
+ * This function uses the _PyPopenProcs dictionary in order to map the
+ * input file pointer to information about the process that was
+ * originally created by the popen* call that created the file pointer.
+ * The dictionary uses the file pointer as a key (with one entry
+ * inserted for each file returned by the original popen* call) and a
+ * single list object as the value for all files from a single call.
+ * The list object contains the Win32 process handle at [0], and a file
+ * count at [1], which is initialized to the total number of file
+ * handles using that list.
+ *
+ * This function closes whichever handle it is passed, and decrements
+ * the file count in the dictionary for the process handle pointed to
+ * by this file.  On the last close (when the file count reaches zero),
+ * this function will wait for the child process and then return its
+ * exit code as the result of the close() operation.  This permits the
+ * files to be closed in any order - it is always the close() of the
+ * final handle that will return the exit code.
+ *
+ * NOTE: This function is currently called with the GIL released.
+ * hence we use the GILState API to manage our state.
+ */
+
+static int _PyPclose(FILE *file)
+{
+	int result;
+	DWORD exit_code;
+	HANDLE hProcess;
+	PyObject *procObj, *hProcessObj, *intObj, *fileObj;
+	long file_count;
+#ifdef WITH_THREAD
+	PyGILState_STATE state;
+#endif
+
+	/* Close the file handle first, to ensure it can't block the
+	 * child from exiting if it's the last handle.
+	 */
+	result = fclose(file);
+#ifdef WITH_THREAD
+	state = PyGILState_Ensure();
+#endif
+	if (_PyPopenProcs) {
+		if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
+		    (procObj = PyDict_GetItem(_PyPopenProcs,
+					      fileObj)) != NULL &&
+		    (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
+		    (intObj = PyList_GetItem(procObj,1)) != NULL) {
+
+			hProcess = PyLong_AsVoidPtr(hProcessObj);
+			file_count = PyInt_AsLong(intObj);
+
+			if (file_count > 1) {
+				/* Still other files referencing process */
+				file_count--;
+				PyList_SetItem(procObj,1,
+					       PyInt_FromLong(file_count));
+			} else {
+				/* Last file for this process */
+				if (result != EOF &&
+				    WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
+				    GetExitCodeProcess(hProcess, &exit_code)) {
+					/* Possible truncation here in 16-bit environments, but
+					 * real exit codes are just the lower byte in any event.
+					 */
+					result = exit_code;
+				} else {
+					/* Indicate failure - this will cause the file object
+					 * to raise an I/O error and translate the last Win32
+					 * error code from errno.  We do have a problem with
+					 * last errors that overlap the normal errno table,
+					 * but that's a consistent problem with the file object.
+					 */
+					if (result != EOF) {
+						/* If the error wasn't from the fclose(), then
+						 * set errno for the file object error handling.
+						 */
+						errno = GetLastError();
+					}
+					result = -1;
+				}
+
+				/* Free up the native handle at this point */
+				CloseHandle(hProcess);
+			}
+
+			/* Remove this file pointer from dictionary */
+			PyDict_DelItem(_PyPopenProcs, fileObj);
+
+			if (PyDict_Size(_PyPopenProcs) == 0) {
+				Py_DECREF(_PyPopenProcs);
+				_PyPopenProcs = NULL;
+			}
+
+		} /* if object retrieval ok */
+
+		Py_XDECREF(fileObj);
+	} /* if _PyPopenProcs */
+
+#ifdef WITH_THREAD
+	PyGILState_Release(state);
+#endif
+	return result;
+}
+
+#else /* which OS? */
+static PyObject *
+posix_popen(PyObject *self, PyObject *args)
+{
+	char *name;
+	char *mode = "r";
+	int bufsize = -1;
+	FILE *fp;
+	PyObject *f;
+	if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
+		return NULL;
+	/* Strip mode of binary or text modifiers */
+	if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
+		mode = "r";
+	else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
+		mode = "w";
+	Py_BEGIN_ALLOW_THREADS
+	fp = popen(name, mode);
+	Py_END_ALLOW_THREADS
+	if (fp == NULL)
+		return posix_error();
+	f = PyFile_FromFile(fp, name, mode, pclose);
+	if (f != NULL)
+		PyFile_SetBufSize(f, bufsize);
+	return f;
+}
+
+#endif /* PYOS_??? */
+#endif /* HAVE_POPEN */
+
+
+#ifdef HAVE_SETUID
+PyDoc_STRVAR(posix_setuid__doc__,
+"setuid(uid)\n\n\
+Set the current process's user id.");
+
+static PyObject *
+posix_setuid(PyObject *self, PyObject *args)
+{
+	int uid;
+	if (!PyArg_ParseTuple(args, "i:setuid", &uid))
+		return NULL;
+	if (setuid(uid) < 0)
+		return posix_error();
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+#endif /* HAVE_SETUID */
+
+
+#ifdef HAVE_SETEUID
+PyDoc_STRVAR(posix_seteuid__doc__,
+"seteuid(uid)\n\n\
+Set the current process's effective user id.");
+
+static PyObject *
+posix_seteuid (PyObject *self, PyObject *args)
+{
+	int euid;
+	if (!PyArg_ParseTuple(args, "i", &euid)) {
+		return NULL;
+	} else if (seteuid(euid) < 0) {
+		return posix_error();
+	} else {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+}
+#endif /* HAVE_SETEUID */
+
+#ifdef HAVE_SETEGID
+PyDoc_STRVAR(posix_setegid__doc__,
+"setegid(gid)\n\n\
+Set the current process's effective group id.");
+
+static PyObject *
+posix_setegid (PyObject *self, PyObject *args)
+{
+	int egid;
+	if (!PyArg_ParseTuple(args, "i", &egid)) {
+		return NULL;
+	} else if (setegid(egid) < 0) {
+		return posix_error();
+	} else {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+}
+#endif /* HAVE_SETEGID */
+
+#ifdef HAVE_SETREUID
+PyDoc_STRVAR(posix_setreuid__doc__,
+"setreuid(ruid, euid)\n\n\
+Set the current process's real and effective user ids.");
+
+static PyObject *
+posix_setreuid (PyObject *self, PyObject *args)
+{
+	int ruid, euid;
+	if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
+		return NULL;
+	} else if (setreuid(ruid, euid) < 0) {
+		return posix_error();
+	} else {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+}
+#endif /* HAVE_SETREUID */
+
+#ifdef HAVE_SETREGID
+PyDoc_STRVAR(posix_setregid__doc__,
+"setregid(rgid, egid)\n\n\
+Set the current process's real and effective group ids.");
+
+static PyObject *
+posix_setregid (PyObject *self, PyObject *args)
+{
+	int rgid, egid;
+	if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
+		return NULL;
+	} else if (setregid(rgid, egid) < 0) {
+		return posix_error();
+	} else {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+}
+#endif /* HAVE_SETREGID */
+
+#ifdef HAVE_SETGID
+PyDoc_STRVAR(posix_setgid__doc__,
+"setgid(gid)\n\n\
+Set the current process's group id.");
+
+static PyObject *
+posix_setgid(PyObject *self, PyObject *args)
+{
+	int gid;
+	if (!PyArg_ParseTuple(args, "i:setgid", &gid))
+		return NULL;
+	if (setgid(gid) < 0)
+		return posix_error();
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+#endif /* HAVE_SETGID */
+
+#ifdef HAVE_SETGROUPS
+PyDoc_STRVAR(posix_setgroups__doc__,
+"setgroups(list)\n\n\
+Set the groups of the current process to list.");
+
+static PyObject *
+posix_setgroups(PyObject *self, PyObject *groups)
+{
+	int i, len;
+        gid_t grouplist[MAX_GROUPS];
+
+	if (!PySequence_Check(groups)) {
+		PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
+		return NULL;
+	}
+	len = PySequence_Size(groups);
+	if (len > MAX_GROUPS) {
+		PyErr_SetString(PyExc_ValueError, "too many groups");
+		return NULL;
+	}
+	for(i = 0; i < len; i++) {
+		PyObject *elem;
+		elem = PySequence_GetItem(groups, i);
+		if (!elem)
+			return NULL;
+		if (!PyInt_Check(elem)) {
+			if (!PyLong_Check(elem)) {
+				PyErr_SetString(PyExc_TypeError,
+						"groups must be integers");
+				Py_DECREF(elem);
+				return NULL;
+			} else {
+				unsigned long x = PyLong_AsUnsignedLong(elem);
+				if (PyErr_Occurred()) {
+					PyErr_SetString(PyExc_TypeError, 
+							"group id too big");
+					Py_DECREF(elem);
+					return NULL;
+				}
+				grouplist[i] = x;
+				/* read back the value to see if it fitted in gid_t */
+				if (grouplist[i] != x) {
+					PyErr_SetString(PyExc_TypeError,
+							"group id too big");
+					Py_DECREF(elem);
+					return NULL;
+				}
+			}
+		} else {
+			long x  = PyInt_AsLong(elem);
+			grouplist[i] = x;
+			if (grouplist[i] != x) {
+				PyErr_SetString(PyExc_TypeError,
+						"group id too big");
+				Py_DECREF(elem);
+				return NULL;
+			}
+		}
+		Py_DECREF(elem);
+	}
+
+	if (setgroups(len, grouplist) < 0)
+		return posix_error();
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+#endif /* HAVE_SETGROUPS */
+
+#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
+static PyObject *
+wait_helper(int pid, int status, struct rusage *ru)
+{
+	PyObject *result;
+   	static PyObject *struct_rusage;
+
+	if (pid == -1)
+		return posix_error();
+
+	if (struct_rusage == NULL) {
+		PyObject *m = PyImport_ImportModule("resource");
+		if (m == NULL)
+			return NULL;
+		struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
+		Py_DECREF(m);
+		if (struct_rusage == NULL)
+			return NULL;
+	}
+
+	/* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
+	result = PyStructSequence_New((PyTypeObject*) struct_rusage);
+	if (!result)
+		return NULL;
+
+#ifndef doubletime
+#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
+#endif
+
+	PyStructSequence_SET_ITEM(result, 0,
+			PyFloat_FromDouble(doubletime(ru->ru_utime)));
+	PyStructSequence_SET_ITEM(result, 1,
+			PyFloat_FromDouble(doubletime(ru->ru_stime)));
+#define SET_INT(result, index, value)\
+		PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
+	SET_INT(result, 2, ru->ru_maxrss);
+	SET_INT(result, 3, ru->ru_ixrss);
+	SET_INT(result, 4, ru->ru_idrss);
+	SET_INT(result, 5, ru->ru_isrss);
+	SET_INT(result, 6, ru->ru_minflt);
+	SET_INT(result, 7, ru->ru_majflt);
+	SET_INT(result, 8, ru->ru_nswap);
+	SET_INT(result, 9, ru->ru_inblock);
+	SET_INT(result, 10, ru->ru_oublock);
+	SET_INT(result, 11, ru->ru_msgsnd);
+	SET_INT(result, 12, ru->ru_msgrcv);
+	SET_INT(result, 13, ru->ru_nsignals);
+	SET_INT(result, 14, ru->ru_nvcsw);
+	SET_INT(result, 15, ru->ru_nivcsw);
+#undef SET_INT
+
+	if (PyErr_Occurred()) {
+		Py_DECREF(result);
+		return NULL;
+	}
+
+	return Py_BuildValue("iiN", pid, status, result);
+}
+#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
+
+#ifdef HAVE_WAIT3
+PyDoc_STRVAR(posix_wait3__doc__,
+"wait3(options) -> (pid, status, rusage)\n\n\
+Wait for completion of a child process.");
+
+static PyObject *
+posix_wait3(PyObject *self, PyObject *args)
+{
+	int pid, options;
+	struct rusage ru;
+	WAIT_TYPE status;
+	WAIT_STATUS_INT(status) = 0;
+
+	if (!PyArg_ParseTuple(args, "i:wait3", &options))
+		return NULL;
+
+	Py_BEGIN_ALLOW_THREADS
+	pid = wait3(&status, options, &ru);
+	Py_END_ALLOW_THREADS
+
+	return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
+}
+#endif /* HAVE_WAIT3 */
+
+#ifdef HAVE_WAIT4
+PyDoc_STRVAR(posix_wait4__doc__,
+"wait4(pid, options) -> (pid, status, rusage)\n\n\
+Wait for completion of a given child process.");
+
+static PyObject *
+posix_wait4(PyObject *self, PyObject *args)
+{
+	int pid, options;
+	struct rusage ru;
+	WAIT_TYPE status;
+	WAIT_STATUS_INT(status) = 0;
+
+	if (!PyArg_ParseTuple(args, "ii:wait4", &pid, &options))
+		return NULL;
+
+	Py_BEGIN_ALLOW_THREADS
+	pid = wait4(pid, &status, options, &ru);
+	Py_END_ALLOW_THREADS
+
+	return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
+}
+#endif /* HAVE_WAIT4 */
+
+#ifdef HAVE_WAITPID
+PyDoc_STRVAR(posix_waitpid__doc__,
+"waitpid(pid, options) -> (pid, status)\n\n\
+Wait for completion of a given child process.");
+
+static PyObject *
+posix_waitpid(PyObject *self, PyObject *args)
+{
+	int pid, options;
+	WAIT_TYPE status;
+	WAIT_STATUS_INT(status) = 0;
+
+	if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
+		return NULL;
+	Py_BEGIN_ALLOW_THREADS
+	pid = waitpid(pid, &status, options);
+	Py_END_ALLOW_THREADS
+	if (pid == -1)
+		return posix_error();
+
+	return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
+}
+
+#elif defined(HAVE_CWAIT)
+
+/* MS C has a variant of waitpid() that's usable for most purposes. */
+PyDoc_STRVAR(posix_waitpid__doc__,
+"waitpid(pid, options) -> (pid, status << 8)\n\n"
+"Wait for completion of a given process.  options is ignored on Windows.");
+
+static PyObject *
+posix_waitpid(PyObject *self, PyObject *args)
+{
+	Py_intptr_t pid;
+	int status, options;
+
+	if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
+		return NULL;
+	Py_BEGIN_ALLOW_THREADS
+	pid = _cwait(&status, pid, options);
+	Py_END_ALLOW_THREADS
+	if (pid == -1)
+		return posix_error();
+
+	/* shift the status left a byte so this is more like the POSIX waitpid */
+	return Py_BuildValue("ii", pid, status << 8);
+}
+#endif /* HAVE_WAITPID || HAVE_CWAIT */
+
+#ifdef HAVE_WAIT
+PyDoc_STRVAR(posix_wait__doc__,
+"wait() -> (pid, status)\n\n\
+Wait for completion of a child process.");
+
+static PyObject *
+posix_wait(PyObject *self, PyObject *noargs)
+{
+	int pid;
+	WAIT_TYPE status;
+	WAIT_STATUS_INT(status) = 0;
+
+	Py_BEGIN_ALLOW_THREADS
+	pid = wait(&status);
+	Py_END_ALLOW_THREADS
+	if (pid == -1)
+		return posix_error();
+
+	return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
+}
+#endif
+
+
+PyDoc_STRVAR(posix_lstat__doc__,
+"lstat(path) -> stat result\n\n\
+Like stat(path), but do not follow symbolic links.");
+
+static PyObject *
+posix_lstat(PyObject *self, PyObject *args)
+{
+#ifdef HAVE_LSTAT
+	return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
+#else /* !HAVE_LSTAT */
+#ifdef MS_WINDOWS
+	return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
+#else
+	return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
+#endif
+#endif /* !HAVE_LSTAT */
+}
+
+
+#ifdef HAVE_READLINK
+PyDoc_STRVAR(posix_readlink__doc__,
+"readlink(path) -> path\n\n\
+Return a string representing the path to which the symbolic link points.");
+
+static PyObject *
+posix_readlink(PyObject *self, PyObject *args)
+{
+	char buf[MAXPATHLEN];
+	char *path;
+	int n;
+	if (!PyArg_ParseTuple(args, "s:readlink", &path))
+		return NULL;
+	Py_BEGIN_ALLOW_THREADS
+	n = readlink(path, buf, (int) sizeof buf);
+	Py_END_ALLOW_THREADS
+	if (n < 0)
+		return posix_error_with_filename(path);
+	return PyString_FromStringAndSize(buf, n);
+}
+#endif /* HAVE_READLINK */
+
+
+#ifdef HAVE_SYMLINK
+PyDoc_STRVAR(posix_symlink__doc__,
+"symlink(src, dst)\n\n\
+Create a symbolic link pointing to src named dst.");
+
+static PyObject *
+posix_symlink(PyObject *self, PyObject *args)
+{
+	return posix_2str(args, "etet:symlink", symlink);
+}
+#endif /* HAVE_SYMLINK */
+
+
+#ifdef HAVE_TIMES
+#ifndef HZ
+#define HZ 60 /* Universal constant :-) */
+#endif /* HZ */
+
+#if defined(PYCC_VACPP) && defined(PYOS_OS2)
+static long
+system_uptime(void)
+{
+    ULONG     value = 0;
+
+    Py_BEGIN_ALLOW_THREADS
+    DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
+    Py_END_ALLOW_THREADS
+
+    return value;
+}
+
+static PyObject *
+posix_times(PyObject *self, PyObject *noargs)
+{
+    /* Currently Only Uptime is Provided -- Others Later */
+	return Py_BuildValue("ddddd",
+			     (double)0 /* t.tms_utime / HZ */,
+			     (double)0 /* t.tms_stime / HZ */,
+			     (double)0 /* t.tms_cutime / HZ */,
+			     (double)0 /* t.tms_cstime / HZ */,
+			     (double)system_uptime() / 1000);
+}
+#else /* not OS2 */
+static PyObject *
+posix_times(PyObject *self, PyObject *noargs)
+{
+	struct tms t;
+	clock_t c;
+	errno = 0;
+	c = times(&t);
+	if (c == (clock_t) -1)
+		return posix_error();
+	return Py_BuildValue("ddddd",
+			     (double)t.tms_utime / HZ,
+			     (double)t.tms_stime / HZ,
+			     (double)t.tms_cutime / HZ,
+			     (double)t.tms_cstime / HZ,
+			     (double)c / HZ);
+}
+#endif /* not OS2 */
+#endif /* HAVE_TIMES */
+
+
+#ifdef MS_WINDOWS
+#define HAVE_TIMES	/* so the method table will pick it up */
+static PyObject *
+posix_times(PyObject *self, PyObject *noargs)
+{
+	FILETIME create, exit, kernel, user;
+	HANDLE hProc;
+	hProc = GetCurrentProcess();
+	GetProcessTimes(hProc, &create, &exit, &kernel, &user);
+	/* The fields of a FILETIME structure are the hi and lo part
+	   of a 64-bit value expressed in 100 nanosecond units.
+	   1e7 is one second in such units; 1e-7 the inverse.
+	   429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
+	*/
+	return Py_BuildValue(
+		"ddddd",
+		(double)(kernel.dwHighDateTime*429.4967296 +
+		         kernel.dwLowDateTime*1e-7),
+		(double)(user.dwHighDateTime*429.4967296 +
+		         user.dwLowDateTime*1e-7),
+		(double)0,
+		(double)0,
+		(double)0);
+}
+#endif /* MS_WINDOWS */
+
+#ifdef HAVE_TIMES
+PyDoc_STRVAR(posix_times__doc__,
+"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
+Return a tuple of floating point numbers indicating process times.");
+#endif
+
+
+#ifdef HAVE_GETSID
+PyDoc_STRVAR(posix_getsid__doc__,
+"getsid(pid) -> sid\n\n\
+Call the system call getsid().");
+
+static PyObject *
+posix_getsid(PyObject *self, PyObject *args)
+{
+	int pid, sid;
+	if (!PyArg_ParseTuple(args, "i:getsid", &pid))
+		return NULL;
+	sid = getsid(pid);
+	if (sid < 0)
+		return posix_error();
+	return PyInt_FromLong((long)sid);
+}
+#endif /* HAVE_GETSID */
+
+
+#ifdef HAVE_SETSID
+PyDoc_STRVAR(posix_setsid__doc__,
+"setsid()\n\n\
+Call the system call setsid().");
+
+static PyObject *
+posix_setsid(PyObject *self, PyObject *noargs)
+{
+	if (setsid() < 0)
+		return posix_error();
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+#endif /* HAVE_SETSID */
+
+#ifdef HAVE_SETPGID
+PyDoc_STRVAR(posix_setpgid__doc__,
+"setpgid(pid, pgrp)\n\n\
+Call the system call setpgid().");
+
+static PyObject *
+posix_setpgid(PyObject *self, PyObject *args)
+{
+	int pid, pgrp;
+	if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
+		return NULL;
+	if (setpgid(pid, pgrp) < 0)
+		return posix_error();
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+#endif /* HAVE_SETPGID */
+
+
+#ifdef HAVE_TCGETPGRP
+PyDoc_STRVAR(posix_tcgetpgrp__doc__,
+"tcgetpgrp(fd) -> pgid\n\n\
+Return the process group associated with the terminal given by a fd.");
+
+static PyObject *
+posix_tcgetpgrp(PyObject *self, PyObject *args)
+{
+	int fd, pgid;
+	if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
+		return NULL;
+	pgid = tcgetpgrp(fd);
+	if (pgid < 0)
+		return posix_error();
+	return PyInt_FromLong((long)pgid);
+}
+#endif /* HAVE_TCGETPGRP */
+
+
+#ifdef HAVE_TCSETPGRP
+PyDoc_STRVAR(posix_tcsetpgrp__doc__,
+"tcsetpgrp(fd, pgid)\n\n\
+Set the process group associated with the terminal given by a fd.");
+
+static PyObject *
+posix_tcsetpgrp(PyObject *self, PyObject *args)
+{
+	int fd, pgid;
+	if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
+		return NULL;
+	if (tcsetpgrp(fd, pgid) < 0)
+		return posix_error();
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+#endif /* HAVE_TCSETPGRP */
+
+/* Functions acting on file descriptors */
+
+PyDoc_STRVAR(posix_open__doc__,
+"open(filename, flag [, mode=0777]) -> fd\n\n\
+Open a file (for low level IO).");
+
+static PyObject *
+posix_open(PyObject *self, PyObject *args)
+{
+	char *file = NULL;
+	int flag;
+	int mode = 0777;
+	int fd;
+
+#ifdef MS_WINDOWS
+	if (unicode_file_names()) {
+		PyUnicodeObject *po;
+		if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
+			Py_BEGIN_ALLOW_THREADS
+			/* PyUnicode_AS_UNICODE OK without thread
+			   lock as it is a simple dereference. */
+			fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
+			Py_END_ALLOW_THREADS
+			if (fd < 0)
+				return posix_error();
+			return PyInt_FromLong((long)fd);
+		}
+		/* Drop the argument parsing error as narrow strings
+		   are also valid. */
+		PyErr_Clear();
+	}
+#endif
+
+	if (!PyArg_ParseTuple(args, "eti|i",
+	                      Py_FileSystemDefaultEncoding, &file,
+	                      &flag, &mode))
+		return NULL;
+
+	Py_BEGIN_ALLOW_THREADS
+	fd = open(file, flag, mode);
+	Py_END_ALLOW_THREADS
+	if (fd < 0)
+		return posix_error_with_allocated_filename(file);
+	PyMem_Free(file);
+	return PyInt_FromLong((long)fd);
+}
+
+
+PyDoc_STRVAR(posix_close__doc__,
+"close(fd)\n\n\
+Close a file descriptor (for low level IO).");
+
+static PyObject *
+posix_close(PyObject *self, PyObject *args)
+{
+	int fd, res;
+	if (!PyArg_ParseTuple(args, "i:close", &fd))
+		return NULL;
+	Py_BEGIN_ALLOW_THREADS
+	res = close(fd);
+	Py_END_ALLOW_THREADS
+	if (res < 0)
+		return posix_error();
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+
+PyDoc_STRVAR(posix_dup__doc__,
+"dup(fd) -> fd2\n\n\
+Return a duplicate of a file descriptor.");
+
+static PyObject *
+posix_dup(PyObject *self, PyObject *args)
+{
+	int fd;
+	if (!PyArg_ParseTuple(args, "i:dup", &fd))
+		return NULL;
+	Py_BEGIN_ALLOW_THREADS
+	fd = dup(fd);
+	Py_END_ALLOW_THREADS
+	if (fd < 0)
+		return posix_error();
+	return PyInt_FromLong((long)fd);
+}
+
+
+PyDoc_STRVAR(posix_dup2__doc__,
+"dup2(old_fd, new_fd)\n\n\
+Duplicate file descriptor.");
+
+static PyObject *
+posix_dup2(PyObject *self, PyObject *args)
+{
+	int fd, fd2, res;
+	if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
+		return NULL;
+	Py_BEGIN_ALLOW_THREADS
+	res = dup2(fd, fd2);
+	Py_END_ALLOW_THREADS
+	if (res < 0)
+		return posix_error();
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+
+PyDoc_STRVAR(posix_lseek__doc__,
+"lseek(fd, pos, how) -> newpos\n\n\
+Set the current position of a file descriptor.");
+
+static PyObject *
+posix_lseek(PyObject *self, PyObject *args)
+{
+	int fd, how;
+#if defined(MS_WIN64) || defined(MS_WINDOWS)
+	PY_LONG_LONG pos, res;
+#else
+	off_t pos, res;
+#endif
+	PyObject *posobj;
+	if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
+		return NULL;
+#ifdef SEEK_SET
+	/* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
+	switch (how) {
+	case 0: how = SEEK_SET; break;
+	case 1: how = SEEK_CUR; break;
+	case 2: how = SEEK_END; break;
+	}
+#endif /* SEEK_END */
+
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+	pos = PyInt_AsLong(posobj);
+#else
+	pos = PyLong_Check(posobj) ?
+		PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
+#endif
+	if (PyErr_Occurred())
+		return NULL;
+
+	Py_BEGIN_ALLOW_THREADS
+#if defined(MS_WIN64) || defined(MS_WINDOWS)
+	res = _lseeki64(fd, pos, how);
+#else
+	res = lseek(fd, pos, how);
+#endif
+	Py_END_ALLOW_THREADS
+	if (res < 0)
+		return posix_error();
+
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+	return PyInt_FromLong(res);
+#else
+	return PyLong_FromLongLong(res);
+#endif
+}
+
+
+PyDoc_STRVAR(posix_read__doc__,
+"read(fd, buffersize) -> string\n\n\
+Read a file descriptor.");
+
+static PyObject *
+posix_read(PyObject *self, PyObject *args)
+{
+	int fd, size, n;
+	PyObject *buffer;
+	if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
+		return NULL;
+	if (size < 0) {
+		errno = EINVAL;
+		return posix_error();
+	}
+	buffer = PyString_FromStringAndSize((char *)NULL, size);
+	if (buffer == NULL)
+		return NULL;
+	Py_BEGIN_ALLOW_THREADS
+	n = read(fd, PyString_AsString(buffer), size);
+	Py_END_ALLOW_THREADS
+	if (n < 0) {
+		Py_DECREF(buffer);
+		return posix_error();
+	}
+	if (n != size)
+		_PyString_Resize(&buffer, n);
+	return buffer;
+}
+
+
+PyDoc_STRVAR(posix_write__doc__,
+"write(fd, string) -> byteswritten\n\n\
+Write a string to a file descriptor.");
+
+static PyObject *
+posix_write(PyObject *self, PyObject *args)
+{
+	int fd;
+	Py_ssize_t size;
+	char *buffer;
+
+	if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
+		return NULL;
+	Py_BEGIN_ALLOW_THREADS
+	size = write(fd, buffer, (size_t)size);
+	Py_END_ALLOW_THREADS
+	if (size < 0)
+		return posix_error();
+	return PyInt_FromSsize_t(size);
+}
+
+
+PyDoc_STRVAR(posix_fstat__doc__,
+"fstat(fd) -> stat result\n\n\
+Like stat(), but for an open file descriptor.");
+
+static PyObject *
+posix_fstat(PyObject *self, PyObject *args)
+{
+	int fd;
+	STRUCT_STAT st;
+	int res;
+	if (!PyArg_ParseTuple(args, "i:fstat", &fd))
+		return NULL;
+#ifdef __VMS
+        /* on OpenVMS we must ensure that all bytes are written to the file */
+        fsync(fd);
+#endif
+	Py_BEGIN_ALLOW_THREADS
+	res = FSTAT(fd, &st);
+	Py_END_ALLOW_THREADS
+	if (res != 0) {
+#ifdef MS_WINDOWS
+		return win32_error("fstat", NULL);
+#else
+		return posix_error();
+#endif
+	}
+
+	return _pystat_fromstructstat(&st);
+}
+
+
+PyDoc_STRVAR(posix_fdopen__doc__,
+"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
+Return an open file object connected to a file descriptor.");
+
+static PyObject *
+posix_fdopen(PyObject *self, PyObject *args)
+{
+	int fd;
+	char *mode = "r";
+	int bufsize = -1;
+	FILE *fp;
+	PyObject *f;
+	if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
+		return NULL;
+
+	if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
+		PyErr_Format(PyExc_ValueError,
+			     "invalid file mode '%s'", mode);
+		return NULL;
+	}
+	Py_BEGIN_ALLOW_THREADS
+#if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
+	if (mode[0] == 'a') {
+		/* try to make sure the O_APPEND flag is set */
+		int flags;
+		flags = fcntl(fd, F_GETFL);
+		if (flags != -1)
+			fcntl(fd, F_SETFL, flags | O_APPEND);
+		fp = fdopen(fd, mode);
+		if (fp == NULL && flags != -1)
+			/* restore old mode if fdopen failed */
+			fcntl(fd, F_SETFL, flags);
+	} else {
+		fp = fdopen(fd, mode);
+	}
+#else
+	fp = fdopen(fd, mode);
+#endif
+	Py_END_ALLOW_THREADS
+	if (fp == NULL)
+		return posix_error();
+	f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
+	if (f != NULL)
+		PyFile_SetBufSize(f, bufsize);
+	return f;
+}
+
+PyDoc_STRVAR(posix_isatty__doc__,
+"isatty(fd) -> bool\n\n\
+Return True if the file descriptor 'fd' is an open file descriptor\n\
+connected to the slave end of a terminal.");
+
+static PyObject *
+posix_isatty(PyObject *self, PyObject *args)
+{
+	int fd;
+	if (!PyArg_ParseTuple(args, "i:isatty", &fd))
+		return NULL;
+	return PyBool_FromLong(isatty(fd));
+}
+
+#ifdef HAVE_PIPE
+PyDoc_STRVAR(posix_pipe__doc__,
+"pipe() -> (read_end, write_end)\n\n\
+Create a pipe.");
+
+static PyObject *
+posix_pipe(PyObject *self, PyObject *noargs)
+{
+#if defined(PYOS_OS2)
+    HFILE read, write;
+    APIRET rc;
+
+	Py_BEGIN_ALLOW_THREADS
+    rc = DosCreatePipe( &read, &write, 4096);
+	Py_END_ALLOW_THREADS
+    if (rc != NO_ERROR)
+        return os2_error(rc);
+
+    return Py_BuildValue("(ii)", read, write);
+#else
+#if !defined(MS_WINDOWS)
+	int fds[2];
+	int res;
+	Py_BEGIN_ALLOW_THREADS
+	res = pipe(fds);
+	Py_END_ALLOW_THREADS
+	if (res != 0)
+		return posix_error();
+	return Py_BuildValue("(ii)", fds[0], fds[1]);
+#else /* MS_WINDOWS */
+	HANDLE read, write;
+	int read_fd, write_fd;
+	BOOL ok;
+	Py_BEGIN_ALLOW_THREADS
+	ok = CreatePipe(&read, &write, NULL, 0);
+	Py_END_ALLOW_THREADS
+	if (!ok)
+		return win32_error("CreatePipe", NULL);
+	read_fd = _open_osfhandle((Py_intptr_t)read, 0);
+	write_fd = _open_osfhandle((Py_intptr_t)write, 1);
+	return Py_BuildValue("(ii)", read_fd, write_fd);
+#endif /* MS_WINDOWS */
+#endif
+}
+#endif  /* HAVE_PIPE */
+
+
+#ifdef HAVE_MKFIFO
+PyDoc_STRVAR(posix_mkfifo__doc__,
+"mkfifo(filename [, mode=0666])\n\n\
+Create a FIFO (a POSIX named pipe).");
+
+static PyObject *
+posix_mkfifo(PyObject *self, PyObject *args)
+{
+	char *filename;
+	int mode = 0666;
+	int res;
+	if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
+		return NULL;
+	Py_BEGIN_ALLOW_THREADS
+	res = mkfifo(filename, mode);
+	Py_END_ALLOW_THREADS
+	if (res < 0)
+		return posix_error();
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+#endif
+
+
+#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
+PyDoc_STRVAR(posix_mknod__doc__,
+"mknod(filename [, mode=0600, device])\n\n\
+Create a filesystem node (file, device special file or named pipe)\n\
+named filename. mode specifies both the permissions to use and the\n\
+type of node to be created, being combined (bitwise OR) with one of\n\
+S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
+device defines the newly created device special file (probably using\n\
+os.makedev()), otherwise it is ignored.");
+
+
+static PyObject *
+posix_mknod(PyObject *self, PyObject *args)
+{
+	char *filename;
+	int mode = 0600;
+	int device = 0;
+	int res;
+	if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
+		return NULL;
+	Py_BEGIN_ALLOW_THREADS
+	res = mknod(filename, mode, device);
+	Py_END_ALLOW_THREADS
+	if (res < 0)
+		return posix_error();
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+#endif
+
+#ifdef HAVE_DEVICE_MACROS
+PyDoc_STRVAR(posix_major__doc__,
+"major(device) -> major number\n\
+Extracts a device major number from a raw device number.");
+
+static PyObject *
+posix_major(PyObject *self, PyObject *args)
+{
+	int device;
+	if (!PyArg_ParseTuple(args, "i:major", &device))
+		return NULL;
+	return PyInt_FromLong((long)major(device));
+}
+
+PyDoc_STRVAR(posix_minor__doc__,
+"minor(device) -> minor number\n\
+Extracts a device minor number from a raw device number.");
+
+static PyObject *
+posix_minor(PyObject *self, PyObject *args)
+{
+	int device;
+	if (!PyArg_ParseTuple(args, "i:minor", &device))
+		return NULL;
+	return PyInt_FromLong((long)minor(device));
+}
+
+PyDoc_STRVAR(posix_makedev__doc__,
+"makedev(major, minor) -> device number\n\
+Composes a raw device number from the major and minor device numbers.");
+
+static PyObject *
+posix_makedev(PyObject *self, PyObject *args)
+{
+	int major, minor;
+	if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
+		return NULL;
+	return PyInt_FromLong((long)makedev(major, minor));
+}
+#endif /* device macros */
+
+
+#ifdef HAVE_FTRUNCATE
+PyDoc_STRVAR(posix_ftruncate__doc__,
+"ftruncate(fd, length)\n\n\
+Truncate a file to a specified length.");
+
+static PyObject *
+posix_ftruncate(PyObject *self, PyObject *args)
+{
+	int fd;
+	off_t length;
+	int res;
+	PyObject *lenobj;
+
+	if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
+		return NULL;
+
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+	length = PyInt_AsLong(lenobj);
+#else
+	length = PyLong_Check(lenobj) ?
+		PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
+#endif
+	if (PyErr_Occurred())
+		return NULL;
+
+	Py_BEGIN_ALLOW_THREADS
+	res = ftruncate(fd, length);
+	Py_END_ALLOW_THREADS
+	if (res < 0) {
+		PyErr_SetFromErrno(PyExc_IOError);
+		return NULL;
+	}
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+#endif
+
+#ifdef HAVE_PUTENV
+PyDoc_STRVAR(posix_putenv__doc__,
+"putenv(key, value)\n\n\
+Change or add an environment variable.");
+
+/* Save putenv() parameters as values here, so we can collect them when they
+ * get re-set with another call for the same key. */
+static PyObject *posix_putenv_garbage;
+
+static PyObject *
+posix_putenv(PyObject *self, PyObject *args)
+{
+        char *s1, *s2;
+        char *newenv;
+	PyObject *newstr;
+	size_t len;
+
+	if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
+		return NULL;
+
+#if defined(PYOS_OS2)
+    if (stricmp(s1, "BEGINLIBPATH") == 0) {
+        APIRET rc;
+
+        rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
+        if (rc != NO_ERROR)
+            return os2_error(rc);
+
+    } else if (stricmp(s1, "ENDLIBPATH") == 0) {
+        APIRET rc;
+
+        rc = DosSetExtLIBPATH(s2, END_LIBPATH);
+        if (rc != NO_ERROR)
+            return os2_error(rc);
+    } else {
+#endif
+
+	/* XXX This can leak memory -- not easy to fix :-( */
+	len = strlen(s1) + strlen(s2) + 2;
+	/* len includes space for a trailing \0; the size arg to
+	   PyString_FromStringAndSize does not count that */
+	newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
+	if (newstr == NULL)
+		return PyErr_NoMemory();
+	newenv = PyString_AS_STRING(newstr);
+	PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
+	if (putenv(newenv)) {
+                Py_DECREF(newstr);
+                posix_error();
+                return NULL;
+	}
+	/* Install the first arg and newstr in posix_putenv_garbage;
+	 * this will cause previous value to be collected.  This has to
+	 * happen after the real putenv() call because the old value
+	 * was still accessible until then. */
+	if (PyDict_SetItem(posix_putenv_garbage,
+			   PyTuple_GET_ITEM(args, 0), newstr)) {
+		/* really not much we can do; just leak */
+		PyErr_Clear();
+	}
+	else {
+		Py_DECREF(newstr);
+	}
+
+#if defined(PYOS_OS2)
+    }
+#endif
+	Py_INCREF(Py_None);
+        return Py_None;
+}
+#endif /* putenv */
+
+#ifdef HAVE_UNSETENV
+PyDoc_STRVAR(posix_unsetenv__doc__,
+"unsetenv(key)\n\n\
+Delete an environment variable.");
+
+static PyObject *
+posix_unsetenv(PyObject *self, PyObject *args)
+{
+        char *s1;
+
+	if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
+		return NULL;
+
+	unsetenv(s1);
+
+	/* Remove the key from posix_putenv_garbage;
+	 * this will cause it to be collected.  This has to
+	 * happen after the real unsetenv() call because the
+	 * old value was still accessible until then.
+	 */
+	if (PyDict_DelItem(posix_putenv_garbage,
+		PyTuple_GET_ITEM(args, 0))) {
+		/* really not much we can do; just leak */
+		PyErr_Clear();
+	}
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+#endif /* unsetenv */
+
+#ifdef HAVE_STRERROR
+PyDoc_STRVAR(posix_strerror__doc__,
+"strerror(code) -> string\n\n\
+Translate an error code to a message string.");
+
+static PyObject *
+posix_strerror(PyObject *self, PyObject *args)
+{
+	int code;
+	char *message;
+	if (!PyArg_ParseTuple(args, "i:strerror", &code))
+		return NULL;
+	message = strerror(code);
+	if (message == NULL) {
+		PyErr_SetString(PyExc_ValueError,
+				"strerror() argument out of range");
+		return NULL;
+	}
+	return PyString_FromString(message);
+}
+#endif /* strerror */
+
+
+#ifdef HAVE_SYS_WAIT_H
+
+#ifdef WCOREDUMP
+PyDoc_STRVAR(posix_WCOREDUMP__doc__,
+"WCOREDUMP(status) -> bool\n\n\
+Return True if the process returning 'status' was dumped to a core file.");
+
+static PyObject *
+posix_WCOREDUMP(PyObject *self, PyObject *args)
+{
+	WAIT_TYPE status;
+	WAIT_STATUS_INT(status) = 0;
+
+	if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
+		return NULL;
+
+	return PyBool_FromLong(WCOREDUMP(status));
+}
+#endif /* WCOREDUMP */
+
+#ifdef WIFCONTINUED
+PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
+"WIFCONTINUED(status) -> bool\n\n\
+Return True if the process returning 'status' was continued from a\n\
+job control stop.");
+
+static PyObject *
+posix_WIFCONTINUED(PyObject *self, PyObject *args)
+{
+	WAIT_TYPE status;
+	WAIT_STATUS_INT(status) = 0;
+
+	if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
+		return NULL;
+
+	return PyBool_FromLong(WIFCONTINUED(status));
+}
+#endif /* WIFCONTINUED */
+
+#ifdef WIFSTOPPED
+PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
+"WIFSTOPPED(status) -> bool\n\n\
+Return True if the process returning 'status' was stopped.");
+
+static PyObject *
+posix_WIFSTOPPED(PyObject *self, PyObject *args)
+{
+	WAIT_TYPE status;
+	WAIT_STATUS_INT(status) = 0;
+
+	if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
+		return NULL;
+
+	return PyBool_FromLong(WIFSTOPPED(status));
+}
+#endif /* WIFSTOPPED */
+
+#ifdef WIFSIGNALED
+PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
+"WIFSIGNALED(status) -> bool\n\n\
+Return True if the process returning 'status' was terminated by a signal.");
+
+static PyObject *
+posix_WIFSIGNALED(PyObject *self, PyObject *args)
+{
+	WAIT_TYPE status;
+	WAIT_STATUS_INT(status) = 0;
+
+	if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
+		return NULL;
+
+	return PyBool_FromLong(WIFSIGNALED(status));
+}
+#endif /* WIFSIGNALED */
+
+#ifdef WIFEXITED
+PyDoc_STRVAR(posix_WIFEXITED__doc__,
+"WIFEXITED(status) -> bool\n\n\
+Return true if the process returning 'status' exited using the exit()\n\
+system call.");
+
+static PyObject *
+posix_WIFEXITED(PyObject *self, PyObject *args)
+{
+	WAIT_TYPE status;
+	WAIT_STATUS_INT(status) = 0;
+
+	if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
+		return NULL;
+
+	return PyBool_FromLong(WIFEXITED(status));
+}
+#endif /* WIFEXITED */
+
+#ifdef WEXITSTATUS
+PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
+"WEXITSTATUS(status) -> integer\n\n\
+Return the process return code from 'status'.");
+
+static PyObject *
+posix_WEXITSTATUS(PyObject *self, PyObject *args)
+{
+	WAIT_TYPE status;
+	WAIT_STATUS_INT(status) = 0;
+
+	if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
+		return NULL;
+
+	return Py_BuildValue("i", WEXITSTATUS(status));
+}
+#endif /* WEXITSTATUS */
+
+#ifdef WTERMSIG
+PyDoc_STRVAR(posix_WTERMSIG__doc__,
+"WTERMSIG(status) -> integer\n\n\
+Return the signal that terminated the process that provided the 'status'\n\
+value.");
+
+static PyObject *
+posix_WTERMSIG(PyObject *self, PyObject *args)
+{
+	WAIT_TYPE status;
+	WAIT_STATUS_INT(status) = 0;
+
+	if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
+		return NULL;
+
+	return Py_BuildValue("i", WTERMSIG(status));
+}
+#endif /* WTERMSIG */
+
+#ifdef WSTOPSIG
+PyDoc_STRVAR(posix_WSTOPSIG__doc__,
+"WSTOPSIG(status) -> integer\n\n\
+Return the signal that stopped the process that provided\n\
+the 'status' value.");
+
+static PyObject *
+posix_WSTOPSIG(PyObject *self, PyObject *args)
+{
+	WAIT_TYPE status;
+	WAIT_STATUS_INT(status) = 0;
+
+	if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
+		return NULL;
+
+	return Py_BuildValue("i", WSTOPSIG(status));
+}
+#endif /* WSTOPSIG */
+
+#endif /* HAVE_SYS_WAIT_H */
+
+
+#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
+#ifdef _SCO_DS
+/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
+   needed definitions in sys/statvfs.h */
+#define _SVID3
+#endif
+#include <sys/statvfs.h>
+
+static PyObject*
+_pystatvfs_fromstructstatvfs(struct statvfs st) {
+        PyObject *v = PyStructSequence_New(&StatVFSResultType);
+	if (v == NULL)
+		return NULL;
+
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+        PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
+        PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
+        PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
+        PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
+        PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
+        PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
+        PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
+        PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
+        PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
+        PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
+#else
+        PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
+        PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
+        PyStructSequence_SET_ITEM(v, 2,
+			       PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
+        PyStructSequence_SET_ITEM(v, 3,
+			       PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
+        PyStructSequence_SET_ITEM(v, 4,
+			       PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
+        PyStructSequence_SET_ITEM(v, 5,
+			       PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
+        PyStructSequence_SET_ITEM(v, 6,
+			       PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
+        PyStructSequence_SET_ITEM(v, 7,
+			       PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
+        PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
+        PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
+#endif
+
+        return v;
+}
+
+PyDoc_STRVAR(posix_fstatvfs__doc__,
+"fstatvfs(fd) -> statvfs result\n\n\
+Perform an fstatvfs system call on the given fd.");
+
+static PyObject *
+posix_fstatvfs(PyObject *self, PyObject *args)
+{
+	int fd, res;
+	struct statvfs st;
+
+	if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
+		return NULL;
+	Py_BEGIN_ALLOW_THREADS
+	res = fstatvfs(fd, &st);
+	Py_END_ALLOW_THREADS
+	if (res != 0)
+		return posix_error();
+
+        return _pystatvfs_fromstructstatvfs(st);
+}
+#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
+
+
+#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
+#include <sys/statvfs.h>
+
+PyDoc_STRVAR(posix_statvfs__doc__,
+"statvfs(path) -> statvfs result\n\n\
+Perform a statvfs system call on the given path.");
+
+static PyObject *
+posix_statvfs(PyObject *self, PyObject *args)
+{
+	char *path;
+	int res;
+	struct statvfs st;
+	if (!PyArg_ParseTuple(args, "s:statvfs", &path))
+		return NULL;
+	Py_BEGIN_ALLOW_THREADS
+	res = statvfs(path, &st);
+	Py_END_ALLOW_THREADS
+	if (res != 0)
+		return posix_error_with_filename(path);
+
+        return _pystatvfs_fromstructstatvfs(st);
+}
+#endif /* HAVE_STATVFS */
+
+
+#ifdef HAVE_TEMPNAM
+PyDoc_STRVAR(posix_tempnam__doc__,
+"tempnam([dir[, prefix]]) -> string\n\n\
+Return a unique name for a temporary file.\n\
+The directory and a prefix may be specified as strings; they may be omitted\n\
+or None if not needed.");
+
+static PyObject *
+posix_tempnam(PyObject *self, PyObject *args)
+{
+    PyObject *result = NULL;
+    char *dir = NULL;
+    char *pfx = NULL;
+    char *name;
+
+    if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
+        return NULL;
+
+    if (PyErr_Warn(PyExc_RuntimeWarning,
+		  "tempnam is a potential security risk to your program") < 0)
+	    return NULL;
+
+#ifdef MS_WINDOWS
+    name = _tempnam(dir, pfx);
+#else
+    name = tempnam(dir, pfx);
+#endif
+    if (name == NULL)
+        return PyErr_NoMemory();
+    result = PyString_FromString(name);
+    free(name);
+    return result;
+}
+#endif
+
+
+#ifdef HAVE_TMPFILE
+PyDoc_STRVAR(posix_tmpfile__doc__,
+"tmpfile() -> file object\n\n\
+Create a temporary file with no directory entries.");
+
+static PyObject *
+posix_tmpfile(PyObject *self, PyObject *noargs)
+{
+    FILE *fp;
+
+    fp = tmpfile();
+    if (fp == NULL)
+        return posix_error();
+    return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
+}
+#endif
+
+
+#ifdef HAVE_TMPNAM
+PyDoc_STRVAR(posix_tmpnam__doc__,
+"tmpnam() -> string\n\n\
+Return a unique name for a temporary file.");
+
+static PyObject *
+posix_tmpnam(PyObject *self, PyObject *noargs)
+{
+    char buffer[L_tmpnam];
+    char *name;
+
+    if (PyErr_Warn(PyExc_RuntimeWarning,
+		  "tmpnam is a potential security risk to your program") < 0)
+	    return NULL;
+
+#ifdef USE_TMPNAM_R
+    name = tmpnam_r(buffer);
+#else
+    name = tmpnam(buffer);
+#endif
+    if (name == NULL) {
+	PyObject *err = Py_BuildValue("is", 0,
+#ifdef USE_TMPNAM_R
+                                      "unexpected NULL from tmpnam_r"
+#else
+                                      "unexpected NULL from tmpnam"
+#endif
+                                      );
+	PyErr_SetObject(PyExc_OSError, err);
+	Py_XDECREF(err);
+	return NULL;
+    }
+    return PyString_FromString(buffer);
+}
+#endif
+
+
+/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
+ * It maps strings representing configuration variable names to
+ * integer values, allowing those functions to be called with the
+ * magic names instead of polluting the module's namespace with tons of
+ * rarely-used constants.  There are three separate tables that use
+ * these definitions.
+ *
+ * This code is always included, even if none of the interfaces that
+ * need it are included.  The #if hackery needed to avoid it would be
+ * sufficiently pervasive that it's not worth the loss of readability.
+ */
+struct constdef {
+    char *name;
+    long value;
+};
+
+static int
+conv_confname(PyObject *arg, int *valuep, struct constdef *table,
+	      size_t tablesize)
+{
+    if (PyInt_Check(arg)) {
+        *valuep = PyInt_AS_LONG(arg);
+        return 1;
+    }
+    if (PyString_Check(arg)) {
+        /* look up the value in the table using a binary search */
+        size_t lo = 0;
+		size_t mid;
+        size_t hi = tablesize;
+        int cmp;
+        char *confname = PyString_AS_STRING(arg);
+        while (lo < hi) {
+            mid = (lo + hi) / 2;
+            cmp = strcmp(confname, table[mid].name);
+            if (cmp < 0)
+                hi = mid;
+            else if (cmp > 0)
+                lo = mid + 1;
+            else {
+                *valuep = table[mid].value;
+                return 1;
+            }
+        }
+        PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
+    }
+    else
+        PyErr_SetString(PyExc_TypeError,
+                        "configuration names must be strings or integers");
+    return 0;
+}
+
+
+#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
+static struct constdef  posix_constants_pathconf[] = {
+#ifdef _PC_ABI_AIO_XFER_MAX
+    {"PC_ABI_AIO_XFER_MAX",	_PC_ABI_AIO_XFER_MAX},
+#endif
+#ifdef _PC_ABI_ASYNC_IO
+    {"PC_ABI_ASYNC_IO",	_PC_ABI_ASYNC_IO},
+#endif
+#ifdef _PC_ASYNC_IO
+    {"PC_ASYNC_IO",	_PC_ASYNC_IO},
+#endif
+#ifdef _PC_CHOWN_RESTRICTED
+    {"PC_CHOWN_RESTRICTED",	_PC_CHOWN_RESTRICTED},
+#endif
+#ifdef _PC_FILESIZEBITS
+    {"PC_FILESIZEBITS",	_PC_FILESIZEBITS},
+#endif
+#ifdef _PC_LAST
+    {"PC_LAST",	_PC_LAST},
+#endif
+#ifdef _PC_LINK_MAX
+    {"PC_LINK_MAX",	_PC_LINK_MAX},
+#endif
+#ifdef _PC_MAX_CANON
+    {"PC_MAX_CANON",	_PC_MAX_CANON},
+#endif
+#ifdef _PC_MAX_INPUT
+    {"PC_MAX_INPUT",	_PC_MAX_INPUT},
+#endif
+#ifdef _PC_NAME_MAX
+    {"PC_NAME_MAX",	_PC_NAME_MAX},
+#endif
+#ifdef _PC_NO_TRUNC
+    {"PC_NO_TRUNC",	_PC_NO_TRUNC},
+#endif
+#ifdef _PC_PATH_MAX
+    {"PC_PATH_MAX",	_PC_PATH_MAX},
+#endif
+#ifdef _PC_PIPE_BUF
+    {"PC_PIPE_BUF",	_PC_PIPE_BUF},
+#endif
+#ifdef _PC_PRIO_IO
+    {"PC_PRIO_IO",	_PC_PRIO_IO},
+#endif
+#ifdef _PC_SOCK_MAXBUF
+    {"PC_SOCK_MAXBUF",	_PC_SOCK_MAXBUF},
+#endif
+#ifdef _PC_SYNC_IO
+    {"PC_SYNC_IO",	_PC_SYNC_IO},
+#endif
+#ifdef _PC_VDISABLE
+    {"PC_VDISABLE",	_PC_VDISABLE},
+#endif
+};
+
+static int
+conv_path_confname(PyObject *arg, int *valuep)
+{
+    return conv_confname(arg, valuep, posix_constants_pathconf,
+                         sizeof(posix_constants_pathconf)
+                           / sizeof(struct constdef));
+}
+#endif
+
+#ifdef HAVE_FPATHCONF
+PyDoc_STRVAR(posix_fpathconf__doc__,
+"fpathconf(fd, name) -> integer\n\n\
+Return the configuration limit name for the file descriptor fd.\n\
+If there is no limit, return -1.");
+
+static PyObject *
+posix_fpathconf(PyObject *self, PyObject *args)
+{
+    PyObject *result = NULL;
+    int name, fd;
+
+    if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
+                         conv_path_confname, &name)) {
+        long limit;
+
+        errno = 0;
+        limit = fpathconf(fd, name);
+        if (limit == -1 && errno != 0)
+            posix_error();
+        else
+            result = PyInt_FromLong(limit);
+    }
+    return result;
+}
+#endif
+
+
+#ifdef HAVE_PATHCONF
+PyDoc_STRVAR(posix_pathconf__doc__,
+"pathconf(path, name) -> integer\n\n\
+Return the configuration limit name for the file or directory path.\n\
+If there is no limit, return -1.");
+
+static PyObject *
+posix_pathconf(PyObject *self, PyObject *args)
+{
+    PyObject *result = NULL;
+    int name;
+    char *path;
+
+    if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
+                         conv_path_confname, &name)) {
+        long limit;
+
+        errno = 0;
+        limit = pathconf(path, name);
+        if (limit == -1 && errno != 0) {
+            if (errno == EINVAL)
+                /* could be a path or name problem */
+                posix_error();
+            else
+                posix_error_with_filename(path);
+        }
+        else
+            result = PyInt_FromLong(limit);
+    }
+    return result;
+}
+#endif
+
+#ifdef HAVE_CONFSTR
+static struct constdef posix_constants_confstr[] = {
+#ifdef _CS_ARCHITECTURE
+    {"CS_ARCHITECTURE",	_CS_ARCHITECTURE},
+#endif
+#ifdef _CS_HOSTNAME
+    {"CS_HOSTNAME",	_CS_HOSTNAME},
+#endif
+#ifdef _CS_HW_PROVIDER
+    {"CS_HW_PROVIDER",	_CS_HW_PROVIDER},
+#endif
+#ifdef _CS_HW_SERIAL
+    {"CS_HW_SERIAL",	_CS_HW_SERIAL},
+#endif
+#ifdef _CS_INITTAB_NAME
+    {"CS_INITTAB_NAME",	_CS_INITTAB_NAME},
+#endif
+#ifdef _CS_LFS64_CFLAGS
+    {"CS_LFS64_CFLAGS",	_CS_LFS64_CFLAGS},
+#endif
+#ifdef _CS_LFS64_LDFLAGS
+    {"CS_LFS64_LDFLAGS",	_CS_LFS64_LDFLAGS},
+#endif
+#ifdef _CS_LFS64_LIBS
+    {"CS_LFS64_LIBS",	_CS_LFS64_LIBS},
+#endif
+#ifdef _CS_LFS64_LINTFLAGS
+    {"CS_LFS64_LINTFLAGS",	_CS_LFS64_LINTFLAGS},
+#endif
+#ifdef _CS_LFS_CFLAGS
+    {"CS_LFS_CFLAGS",	_CS_LFS_CFLAGS},
+#endif
+#ifdef _CS_LFS_LDFLAGS
+    {"CS_LFS_LDFLAGS",	_CS_LFS_LDFLAGS},
+#endif
+#ifdef _CS_LFS_LIBS
+    {"CS_LFS_LIBS",	_CS_LFS_LIBS},
+#endif
+#ifdef _CS_LFS_LINTFLAGS
+    {"CS_LFS_LINTFLAGS",	_CS_LFS_LINTFLAGS},
+#endif
+#ifdef _CS_MACHINE
+    {"CS_MACHINE",	_CS_MACHINE},
+#endif
+#ifdef _CS_PATH
+    {"CS_PATH",	_CS_PATH},
+#endif
+#ifdef _CS_RELEASE
+    {"CS_RELEASE",	_CS_RELEASE},
+#endif
+#ifdef _CS_SRPC_DOMAIN
+    {"CS_SRPC_DOMAIN",	_CS_SRPC_DOMAIN},
+#endif
+#ifdef _CS_SYSNAME
+    {"CS_SYSNAME",	_CS_SYSNAME},
+#endif
+#ifdef _CS_VERSION
+    {"CS_VERSION",	_CS_VERSION},
+#endif
+#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
+    {"CS_XBS5_ILP32_OFF32_CFLAGS",	_CS_XBS5_ILP32_OFF32_CFLAGS},
+#endif
+#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
+    {"CS_XBS5_ILP32_OFF32_LDFLAGS",	_CS_XBS5_ILP32_OFF32_LDFLAGS},
+#endif
+#ifdef _CS_XBS5_ILP32_OFF32_LIBS
+    {"CS_XBS5_ILP32_OFF32_LIBS",	_CS_XBS5_ILP32_OFF32_LIBS},
+#endif
+#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
+    {"CS_XBS5_ILP32_OFF32_LINTFLAGS",	_CS_XBS5_ILP32_OFF32_LINTFLAGS},
+#endif
+#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
+    {"CS_XBS5_ILP32_OFFBIG_CFLAGS",	_CS_XBS5_ILP32_OFFBIG_CFLAGS},
+#endif
+#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
+    {"CS_XBS5_ILP32_OFFBIG_LDFLAGS",	_CS_XBS5_ILP32_OFFBIG_LDFLAGS},
+#endif
+#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
+    {"CS_XBS5_ILP32_OFFBIG_LIBS",	_CS_XBS5_ILP32_OFFBIG_LIBS},
+#endif
+#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
+    {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS",	_CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
+#endif
+#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
+    {"CS_XBS5_LP64_OFF64_CFLAGS",	_CS_XBS5_LP64_OFF64_CFLAGS},
+#endif
+#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
+    {"CS_XBS5_LP64_OFF64_LDFLAGS",	_CS_XBS5_LP64_OFF64_LDFLAGS},
+#endif
+#ifdef _CS_XBS5_LP64_OFF64_LIBS
+    {"CS_XBS5_LP64_OFF64_LIBS",	_CS_XBS5_LP64_OFF64_LIBS},
+#endif
+#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
+    {"CS_XBS5_LP64_OFF64_LINTFLAGS",	_CS_XBS5_LP64_OFF64_LINTFLAGS},
+#endif
+#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
+    {"CS_XBS5_LPBIG_OFFBIG_CFLAGS",	_CS_XBS5_LPBIG_OFFBIG_CFLAGS},
+#endif
+#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
+    {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS",	_CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
+#endif
+#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
+    {"CS_XBS5_LPBIG_OFFBIG_LIBS",	_CS_XBS5_LPBIG_OFFBIG_LIBS},
+#endif
+#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
+    {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS",	_CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
+#endif
+#ifdef _MIPS_CS_AVAIL_PROCESSORS
+    {"MIPS_CS_AVAIL_PROCESSORS",	_MIPS_CS_AVAIL_PROCESSORS},
+#endif
+#ifdef _MIPS_CS_BASE
+    {"MIPS_CS_BASE",	_MIPS_CS_BASE},
+#endif
+#ifdef _MIPS_CS_HOSTID
+    {"MIPS_CS_HOSTID",	_MIPS_CS_HOSTID},
+#endif
+#ifdef _MIPS_CS_HW_NAME
+    {"MIPS_CS_HW_NAME",	_MIPS_CS_HW_NAME},
+#endif
+#ifdef _MIPS_CS_NUM_PROCESSORS
+    {"MIPS_CS_NUM_PROCESSORS",	_MIPS_CS_NUM_PROCESSORS},
+#endif
+#ifdef _MIPS_CS_OSREL_MAJ
+    {"MIPS_CS_OSREL_MAJ",	_MIPS_CS_OSREL_MAJ},
+#endif
+#ifdef _MIPS_CS_OSREL_MIN
+    {"MIPS_CS_OSREL_MIN",	_MIPS_CS_OSREL_MIN},
+#endif
+#ifdef _MIPS_CS_OSREL_PATCH
+    {"MIPS_CS_OSREL_PATCH",	_MIPS_CS_OSREL_PATCH},
+#endif
+#ifdef _MIPS_CS_OS_NAME
+    {"MIPS_CS_OS_NAME",	_MIPS_CS_OS_NAME},
+#endif
+#ifdef _MIPS_CS_OS_PROVIDER
+    {"MIPS_CS_OS_PROVIDER",	_MIPS_CS_OS_PROVIDER},
+#endif
+#ifdef _MIPS_CS_PROCESSORS
+    {"MIPS_CS_PROCESSORS",	_MIPS_CS_PROCESSORS},
+#endif
+#ifdef _MIPS_CS_SERIAL
+    {"MIPS_CS_SERIAL",	_MIPS_CS_SERIAL},
+#endif
+#ifdef _MIPS_CS_VENDOR
+    {"MIPS_CS_VENDOR",	_MIPS_CS_VENDOR},
+#endif
+};
+
+static int
+conv_confstr_confname(PyObject *arg, int *valuep)
+{
+    return conv_confname(arg, valuep, posix_constants_confstr,
+                         sizeof(posix_constants_confstr)
+                           / sizeof(struct constdef));
+}
+
+PyDoc_STRVAR(posix_confstr__doc__,
+"confstr(name) -> string\n\n\
+Return a string-valued system configuration variable.");
+
+static PyObject *
+posix_confstr(PyObject *self, PyObject *args)
+{
+    PyObject *result = NULL;
+    int name;
+    char buffer[256];
+
+    if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
+	int len;
+
+        errno = 0;
+	len = confstr(name, buffer, sizeof(buffer));
+	if (len == 0) {
+	    if (errno) {
+		posix_error();
+	    }
+	    else {
+		result = Py_None;
+		Py_INCREF(Py_None);
+	    }
+        }
+        else {
+	    if ((unsigned int)len >= sizeof(buffer)) {
+                result = PyString_FromStringAndSize(NULL, len-1);
+                if (result != NULL)
+                    confstr(name, PyString_AS_STRING(result), len);
+            }
+            else
+                result = PyString_FromStringAndSize(buffer, len-1);
+        }
+    }
+    return result;
+}
+#endif
+
+
+#ifdef HAVE_SYSCONF
+static struct constdef posix_constants_sysconf[] = {
+#ifdef _SC_2_CHAR_TERM
+    {"SC_2_CHAR_TERM",	_SC_2_CHAR_TERM},
+#endif
+#ifdef _SC_2_C_BIND
+    {"SC_2_C_BIND",	_SC_2_C_BIND},
+#endif
+#ifdef _SC_2_C_DEV
+    {"SC_2_C_DEV",	_SC_2_C_DEV},
+#endif
+#ifdef _SC_2_C_VERSION
+    {"SC_2_C_VERSION",	_SC_2_C_VERSION},
+#endif
+#ifdef _SC_2_FORT_DEV
+    {"SC_2_FORT_DEV",	_SC_2_FORT_DEV},
+#endif
+#ifdef _SC_2_FORT_RUN
+    {"SC_2_FORT_RUN",	_SC_2_FORT_RUN},
+#endif
+#ifdef _SC_2_LOCALEDEF
+    {"SC_2_LOCALEDEF",	_SC_2_LOCALEDEF},
+#endif
+#ifdef _SC_2_SW_DEV
+    {"SC_2_SW_DEV",	_SC_2_SW_DEV},
+#endif
+#ifdef _SC_2_UPE
+    {"SC_2_UPE",	_SC_2_UPE},
+#endif
+#ifdef _SC_2_VERSION
+    {"SC_2_VERSION",	_SC_2_VERSION},
+#endif
+#ifdef _SC_ABI_ASYNCHRONOUS_IO
+    {"SC_ABI_ASYNCHRONOUS_IO",	_SC_ABI_ASYNCHRONOUS_IO},
+#endif
+#ifdef _SC_ACL
+    {"SC_ACL",	_SC_ACL},
+#endif
+#ifdef _SC_AIO_LISTIO_MAX
+    {"SC_AIO_LISTIO_MAX",	_SC_AIO_LISTIO_MAX},
+#endif
+#ifdef _SC_AIO_MAX
+    {"SC_AIO_MAX",	_SC_AIO_MAX},
+#endif
+#ifdef _SC_AIO_PRIO_DELTA_MAX
+    {"SC_AIO_PRIO_DELTA_MAX",	_SC_AIO_PRIO_DELTA_MAX},
+#endif
+#ifdef _SC_ARG_MAX
+    {"SC_ARG_MAX",	_SC_ARG_MAX},
+#endif
+#ifdef _SC_ASYNCHRONOUS_IO
+    {"SC_ASYNCHRONOUS_IO",	_SC_ASYNCHRONOUS_IO},
+#endif
+#ifdef _SC_ATEXIT_MAX
+    {"SC_ATEXIT_MAX",	_SC_ATEXIT_MAX},
+#endif
+#ifdef _SC_AUDIT
+    {"SC_AUDIT",	_SC_AUDIT},
+#endif
+#ifdef _SC_AVPHYS_PAGES
+    {"SC_AVPHYS_PAGES",	_SC_AVPHYS_PAGES},
+#endif
+#ifdef _SC_BC_BASE_MAX
+    {"SC_BC_BASE_MAX",	_SC_BC_BASE_MAX},
+#endif
+#ifdef _SC_BC_DIM_MAX
+    {"SC_BC_DIM_MAX",	_SC_BC_DIM_MAX},
+#endif
+#ifdef _SC_BC_SCALE_MAX
+    {"SC_BC_SCALE_MAX",	_SC_BC_SCALE_MAX},
+#endif
+#ifdef _SC_BC_STRING_MAX
+    {"SC_BC_STRING_MAX",	_SC_BC_STRING_MAX},
+#endif
+#ifdef _SC_CAP
+    {"SC_CAP",	_SC_CAP},
+#endif
+#ifdef _SC_CHARCLASS_NAME_MAX
+    {"SC_CHARCLASS_NAME_MAX",	_SC_CHARCLASS_NAME_MAX},
+#endif
+#ifdef _SC_CHAR_BIT
+    {"SC_CHAR_BIT",	_SC_CHAR_BIT},
+#endif
+#ifdef _SC_CHAR_MAX
+    {"SC_CHAR_MAX",	_SC_CHAR_MAX},
+#endif
+#ifdef _SC_CHAR_MIN
+    {"SC_CHAR_MIN",	_SC_CHAR_MIN},
+#endif
+#ifdef _SC_CHILD_MAX
+    {"SC_CHILD_MAX",	_SC_CHILD_MAX},
+#endif
+#ifdef _SC_CLK_TCK
+    {"SC_CLK_TCK",	_SC_CLK_TCK},
+#endif
+#ifdef _SC_COHER_BLKSZ
+    {"SC_COHER_BLKSZ",	_SC_COHER_BLKSZ},
+#endif
+#ifdef _SC_COLL_WEIGHTS_MAX
+    {"SC_COLL_WEIGHTS_MAX",	_SC_COLL_WEIGHTS_MAX},
+#endif
+#ifdef _SC_DCACHE_ASSOC
+    {"SC_DCACHE_ASSOC",	_SC_DCACHE_ASSOC},
+#endif
+#ifdef _SC_DCACHE_BLKSZ
+    {"SC_DCACHE_BLKSZ",	_SC_DCACHE_BLKSZ},
+#endif
+#ifdef _SC_DCACHE_LINESZ
+    {"SC_DCACHE_LINESZ",	_SC_DCACHE_LINESZ},
+#endif
+#ifdef _SC_DCACHE_SZ
+    {"SC_DCACHE_SZ",	_SC_DCACHE_SZ},
+#endif
+#ifdef _SC_DCACHE_TBLKSZ
+    {"SC_DCACHE_TBLKSZ",	_SC_DCACHE_TBLKSZ},
+#endif
+#ifdef _SC_DELAYTIMER_MAX
+    {"SC_DELAYTIMER_MAX",	_SC_DELAYTIMER_MAX},
+#endif
+#ifdef _SC_EQUIV_CLASS_MAX
+    {"SC_EQUIV_CLASS_MAX",	_SC_EQUIV_CLASS_MAX},
+#endif
+#ifdef _SC_EXPR_NEST_MAX
+    {"SC_EXPR_NEST_MAX",	_SC_EXPR_NEST_MAX},
+#endif
+#ifdef _SC_FSYNC
+    {"SC_FSYNC",	_SC_FSYNC},
+#endif
+#ifdef _SC_GETGR_R_SIZE_MAX
+    {"SC_GETGR_R_SIZE_MAX",	_SC_GETGR_R_SIZE_MAX},
+#endif
+#ifdef _SC_GETPW_R_SIZE_MAX
+    {"SC_GETPW_R_SIZE_MAX",	_SC_GETPW_R_SIZE_MAX},
+#endif
+#ifdef _SC_ICACHE_ASSOC
+    {"SC_ICACHE_ASSOC",	_SC_ICACHE_ASSOC},
+#endif
+#ifdef _SC_ICACHE_BLKSZ
+    {"SC_ICACHE_BLKSZ",	_SC_ICACHE_BLKSZ},
+#endif
+#ifdef _SC_ICACHE_LINESZ
+    {"SC_ICACHE_LINESZ",	_SC_ICACHE_LINESZ},
+#endif
+#ifdef _SC_ICACHE_SZ
+    {"SC_ICACHE_SZ",	_SC_ICACHE_SZ},
+#endif
+#ifdef _SC_INF
+    {"SC_INF",	_SC_INF},
+#endif
+#ifdef _SC_INT_MAX
+    {"SC_INT_MAX",	_SC_INT_MAX},
+#endif
+#ifdef _SC_INT_MIN
+    {"SC_INT_MIN",	_SC_INT_MIN},
+#endif
+#ifdef _SC_IOV_MAX
+    {"SC_IOV_MAX",	_SC_IOV_MAX},
+#endif
+#ifdef _SC_IP_SECOPTS
+    {"SC_IP_SECOPTS",	_SC_IP_SECOPTS},
+#endif
+#ifdef _SC_JOB_CONTROL
+    {"SC_JOB_CONTROL",	_SC_JOB_CONTROL},
+#endif
+#ifdef _SC_KERN_POINTERS
+    {"SC_KERN_POINTERS",	_SC_KERN_POINTERS},
+#endif
+#ifdef _SC_KERN_SIM
+    {"SC_KERN_SIM",	_SC_KERN_SIM},
+#endif
+#ifdef _SC_LINE_MAX
+    {"SC_LINE_MAX",	_SC_LINE_MAX},
+#endif
+#ifdef _SC_LOGIN_NAME_MAX
+    {"SC_LOGIN_NAME_MAX",	_SC_LOGIN_NAME_MAX},
+#endif
+#ifdef _SC_LOGNAME_MAX
+    {"SC_LOGNAME_MAX",	_SC_LOGNAME_MAX},
+#endif
+#ifdef _SC_LONG_BIT
+    {"SC_LONG_BIT",	_SC_LONG_BIT},
+#endif
+#ifdef _SC_MAC
+    {"SC_MAC",	_SC_MAC},
+#endif
+#ifdef _SC_MAPPED_FILES
+    {"SC_MAPPED_FILES",	_SC_MAPPED_FILES},
+#endif
+#ifdef _SC_MAXPID
+    {"SC_MAXPID",	_SC_MAXPID},
+#endif
+#ifdef _SC_MB_LEN_MAX
+    {"SC_MB_LEN_MAX",	_SC_MB_LEN_MAX},
+#endif
+#ifdef _SC_MEMLOCK
+    {"SC_MEMLOCK",	_SC_MEMLOCK},
+#endif
+#ifdef _SC_MEMLOCK_RANGE
+    {"SC_MEMLOCK_RANGE",	_SC_MEMLOCK_RANGE},
+#endif
+#ifdef _SC_MEMORY_PROTECTION
+    {"SC_MEMORY_PROTECTION",	_SC_MEMORY_PROTECTION},
+#endif
+#ifdef _SC_MESSAGE_PASSING
+    {"SC_MESSAGE_PASSING",	_SC_MESSAGE_PASSING},
+#endif
+#ifdef _SC_MMAP_FIXED_ALIGNMENT
+    {"SC_MMAP_FIXED_ALIGNMENT",	_SC_MMAP_FIXED_ALIGNMENT},
+#endif
+#ifdef _SC_MQ_OPEN_MAX
+    {"SC_MQ_OPEN_MAX",	_SC_MQ_OPEN_MAX},
+#endif
+#ifdef _SC_MQ_PRIO_MAX
+    {"SC_MQ_PRIO_MAX",	_SC_MQ_PRIO_MAX},
+#endif
+#ifdef _SC_NACLS_MAX
+    {"SC_NACLS_MAX",	_SC_NACLS_MAX},
+#endif
+#ifdef _SC_NGROUPS_MAX
+    {"SC_NGROUPS_MAX",	_SC_NGROUPS_MAX},
+#endif
+#ifdef _SC_NL_ARGMAX
+    {"SC_NL_ARGMAX",	_SC_NL_ARGMAX},
+#endif
+#ifdef _SC_NL_LANGMAX
+    {"SC_NL_LANGMAX",	_SC_NL_LANGMAX},
+#endif
+#ifdef _SC_NL_MSGMAX
+    {"SC_NL_MSGMAX",	_SC_NL_MSGMAX},
+#endif
+#ifdef _SC_NL_NMAX
+    {"SC_NL_NMAX",	_SC_NL_NMAX},
+#endif
+#ifdef _SC_NL_SETMAX
+    {"SC_NL_SETMAX",	_SC_NL_SETMAX},
+#endif
+#ifdef _SC_NL_TEXTMAX
+    {"SC_NL_TEXTMAX",	_SC_NL_TEXTMAX},
+#endif
+#ifdef _SC_NPROCESSORS_CONF
+    {"SC_NPROCESSORS_CONF",	_SC_NPROCESSORS_CONF},
+#endif
+#ifdef _SC_NPROCESSORS_ONLN
+    {"SC_NPROCESSORS_ONLN",	_SC_NPROCESSORS_ONLN},
+#endif
+#ifdef _SC_NPROC_CONF
+    {"SC_NPROC_CONF",	_SC_NPROC_CONF},
+#endif
+#ifdef _SC_NPROC_ONLN
+    {"SC_NPROC_ONLN",	_SC_NPROC_ONLN},
+#endif
+#ifdef _SC_NZERO
+    {"SC_NZERO",	_SC_NZERO},
+#endif
+#ifdef _SC_OPEN_MAX
+    {"SC_OPEN_MAX",	_SC_OPEN_MAX},
+#endif
+#ifdef _SC_PAGESIZE
+    {"SC_PAGESIZE",	_SC_PAGESIZE},
+#endif
+#ifdef _SC_PAGE_SIZE
+    {"SC_PAGE_SIZE",	_SC_PAGE_SIZE},
+#endif
+#ifdef _SC_PASS_MAX
+    {"SC_PASS_MAX",	_SC_PASS_MAX},
+#endif
+#ifdef _SC_PHYS_PAGES
+    {"SC_PHYS_PAGES",	_SC_PHYS_PAGES},
+#endif
+#ifdef _SC_PII
+    {"SC_PII",	_SC_PII},
+#endif
+#ifdef _SC_PII_INTERNET
+    {"SC_PII_INTERNET",	_SC_PII_INTERNET},
+#endif
+#ifdef _SC_PII_INTERNET_DGRAM
+    {"SC_PII_INTERNET_DGRAM",	_SC_PII_INTERNET_DGRAM},
+#endif
+#ifdef _SC_PII_INTERNET_STREAM
+    {"SC_PII_INTERNET_STREAM",	_SC_PII_INTERNET_STREAM},
+#endif
+#ifdef _SC_PII_OSI
+    {"SC_PII_OSI",	_SC_PII_OSI},
+#endif
+#ifdef _SC_PII_OSI_CLTS
+    {"SC_PII_OSI_CLTS",	_SC_PII_OSI_CLTS},
+#endif
+#ifdef _SC_PII_OSI_COTS
+    {"SC_PII_OSI_COTS",	_SC_PII_OSI_COTS},
+#endif
+#ifdef _SC_PII_OSI_M
+    {"SC_PII_OSI_M",	_SC_PII_OSI_M},
+#endif
+#ifdef _SC_PII_SOCKET
+    {"SC_PII_SOCKET",	_SC_PII_SOCKET},
+#endif
+#ifdef _SC_PII_XTI
+    {"SC_PII_XTI",	_SC_PII_XTI},
+#endif
+#ifdef _SC_POLL
+    {"SC_POLL",	_SC_POLL},
+#endif
+#ifdef _SC_PRIORITIZED_IO
+    {"SC_PRIORITIZED_IO",	_SC_PRIORITIZED_IO},
+#endif
+#ifdef _SC_PRIORITY_SCHEDULING
+    {"SC_PRIORITY_SCHEDULING",	_SC_PRIORITY_SCHEDULING},
+#endif
+#ifdef _SC_REALTIME_SIGNALS
+    {"SC_REALTIME_SIGNALS",	_SC_REALTIME_SIGNALS},
+#endif
+#ifdef _SC_RE_DUP_MAX
+    {"SC_RE_DUP_MAX",	_SC_RE_DUP_MAX},
+#endif
+#ifdef _SC_RTSIG_MAX
+    {"SC_RTSIG_MAX",	_SC_RTSIG_MAX},
+#endif
+#ifdef _SC_SAVED_IDS
+    {"SC_SAVED_IDS",	_SC_SAVED_IDS},
+#endif
+#ifdef _SC_SCHAR_MAX
+    {"SC_SCHAR_MAX",	_SC_SCHAR_MAX},
+#endif
+#ifdef _SC_SCHAR_MIN
+    {"SC_SCHAR_MIN",	_SC_SCHAR_MIN},
+#endif
+#ifdef _SC_SELECT
+    {"SC_SELECT",	_SC_SELECT},
+#endif
+#ifdef _SC_SEMAPHORES
+    {"SC_SEMAPHORES",	_SC_SEMAPHORES},
+#endif
+#ifdef _SC_SEM_NSEMS_MAX
+    {"SC_SEM_NSEMS_MAX",	_SC_SEM_NSEMS_MAX},
+#endif
+#ifdef _SC_SEM_VALUE_MAX
+    {"SC_SEM_VALUE_MAX",	_SC_SEM_VALUE_MAX},
+#endif
+#ifdef _SC_SHARED_MEMORY_OBJECTS
+    {"SC_SHARED_MEMORY_OBJECTS",	_SC_SHARED_MEMORY_OBJECTS},
+#endif
+#ifdef _SC_SHRT_MAX
+    {"SC_SHRT_MAX",	_SC_SHRT_MAX},
+#endif
+#ifdef _SC_SHRT_MIN
+    {"SC_SHRT_MIN",	_SC_SHRT_MIN},
+#endif
+#ifdef _SC_SIGQUEUE_MAX
+    {"SC_SIGQUEUE_MAX",	_SC_SIGQUEUE_MAX},
+#endif
+#ifdef _SC_SIGRT_MAX
+    {"SC_SIGRT_MAX",	_SC_SIGRT_MAX},
+#endif
+#ifdef _SC_SIGRT_MIN
+    {"SC_SIGRT_MIN",	_SC_SIGRT_MIN},
+#endif
+#ifdef _SC_SOFTPOWER
+    {"SC_SOFTPOWER",	_SC_SOFTPOWER},
+#endif
+#ifdef _SC_SPLIT_CACHE
+    {"SC_SPLIT_CACHE",	_SC_SPLIT_CACHE},
+#endif
+#ifdef _SC_SSIZE_MAX
+    {"SC_SSIZE_MAX",	_SC_SSIZE_MAX},
+#endif
+#ifdef _SC_STACK_PROT
+    {"SC_STACK_PROT",	_SC_STACK_PROT},
+#endif
+#ifdef _SC_STREAM_MAX
+    {"SC_STREAM_MAX",	_SC_STREAM_MAX},
+#endif
+#ifdef _SC_SYNCHRONIZED_IO
+    {"SC_SYNCHRONIZED_IO",	_SC_SYNCHRONIZED_IO},
+#endif
+#ifdef _SC_THREADS
+    {"SC_THREADS",	_SC_THREADS},
+#endif
+#ifdef _SC_THREAD_ATTR_STACKADDR
+    {"SC_THREAD_ATTR_STACKADDR",	_SC_THREAD_ATTR_STACKADDR},
+#endif
+#ifdef _SC_THREAD_ATTR_STACKSIZE
+    {"SC_THREAD_ATTR_STACKSIZE",	_SC_THREAD_ATTR_STACKSIZE},
+#endif
+#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
+    {"SC_THREAD_DESTRUCTOR_ITERATIONS",	_SC_THREAD_DESTRUCTOR_ITERATIONS},
+#endif
+#ifdef _SC_THREAD_KEYS_MAX
+    {"SC_THREAD_KEYS_MAX",	_SC_THREAD_KEYS_MAX},
+#endif
+#ifdef _SC_THREAD_PRIORITY_SCHEDULING
+    {"SC_THREAD_PRIORITY_SCHEDULING",	_SC_THREAD_PRIORITY_SCHEDULING},
+#endif
+#ifdef _SC_THREAD_PRIO_INHERIT
+    {"SC_THREAD_PRIO_INHERIT",	_SC_THREAD_PRIO_INHERIT},
+#endif
+#ifdef _SC_THREAD_PRIO_PROTECT
+    {"SC_THREAD_PRIO_PROTECT",	_SC_THREAD_PRIO_PROTECT},
+#endif
+#ifdef _SC_THREAD_PROCESS_SHARED
+    {"SC_THREAD_PROCESS_SHARED",	_SC_THREAD_PROCESS_SHARED},
+#endif
+#ifdef _SC_THREAD_SAFE_FUNCTIONS
+    {"SC_THREAD_SAFE_FUNCTIONS",	_SC_THREAD_SAFE_FUNCTIONS},
+#endif
+#ifdef _SC_THREAD_STACK_MIN
+    {"SC_THREAD_STACK_MIN",	_SC_THREAD_STACK_MIN},
+#endif
+#ifdef _SC_THREAD_THREADS_MAX
+    {"SC_THREAD_THREADS_MAX",	_SC_THREAD_THREADS_MAX},
+#endif
+#ifdef _SC_TIMERS
+    {"SC_TIMERS",	_SC_TIMERS},
+#endif
+#ifdef _SC_TIMER_MAX
+    {"SC_TIMER_MAX",	_SC_TIMER_MAX},
+#endif
+#ifdef _SC_TTY_NAME_MAX
+    {"SC_TTY_NAME_MAX",	_SC_TTY_NAME_MAX},
+#endif
+#ifdef _SC_TZNAME_MAX
+    {"SC_TZNAME_MAX",	_SC_TZNAME_MAX},
+#endif
+#ifdef _SC_T_IOV_MAX
+    {"SC_T_IOV_MAX",	_SC_T_IOV_MAX},
+#endif
+#ifdef _SC_UCHAR_MAX
+    {"SC_UCHAR_MAX",	_SC_UCHAR_MAX},
+#endif
+#ifdef _SC_UINT_MAX
+    {"SC_UINT_MAX",	_SC_UINT_MAX},
+#endif
+#ifdef _SC_UIO_MAXIOV
+    {"SC_UIO_MAXIOV",	_SC_UIO_MAXIOV},
+#endif
+#ifdef _SC_ULONG_MAX
+    {"SC_ULONG_MAX",	_SC_ULONG_MAX},
+#endif
+#ifdef _SC_USHRT_MAX
+    {"SC_USHRT_MAX",	_SC_USHRT_MAX},
+#endif
+#ifdef _SC_VERSION
+    {"SC_VERSION",	_SC_VERSION},
+#endif
+#ifdef _SC_WORD_BIT
+    {"SC_WORD_BIT",	_SC_WORD_BIT},
+#endif
+#ifdef _SC_XBS5_ILP32_OFF32
+    {"SC_XBS5_ILP32_OFF32",	_SC_XBS5_ILP32_OFF32},
+#endif
+#ifdef _SC_XBS5_ILP32_OFFBIG
+    {"SC_XBS5_ILP32_OFFBIG",	_SC_XBS5_ILP32_OFFBIG},
+#endif
+#ifdef _SC_XBS5_LP64_OFF64
+    {"SC_XBS5_LP64_OFF64",	_SC_XBS5_LP64_OFF64},
+#endif
+#ifdef _SC_XBS5_LPBIG_OFFBIG
+    {"SC_XBS5_LPBIG_OFFBIG",	_SC_XBS5_LPBIG_OFFBIG},
+#endif
+#ifdef _SC_XOPEN_CRYPT
+    {"SC_XOPEN_CRYPT",	_SC_XOPEN_CRYPT},
+#endif
+#ifdef _SC_XOPEN_ENH_I18N
+    {"SC_XOPEN_ENH_I18N",	_SC_XOPEN_ENH_I18N},
+#endif
+#ifdef _SC_XOPEN_LEGACY
+    {"SC_XOPEN_LEGACY",	_SC_XOPEN_LEGACY},
+#endif
+#ifdef _SC_XOPEN_REALTIME
+    {"SC_XOPEN_REALTIME",	_SC_XOPEN_REALTIME},
+#endif
+#ifdef _SC_XOPEN_REALTIME_THREADS
+    {"SC_XOPEN_REALTIME_THREADS",	_SC_XOPEN_REALTIME_THREADS},
+#endif
+#ifdef _SC_XOPEN_SHM
+    {"SC_XOPEN_SHM",	_SC_XOPEN_SHM},
+#endif
+#ifdef _SC_XOPEN_UNIX
+    {"SC_XOPEN_UNIX",	_SC_XOPEN_UNIX},
+#endif
+#ifdef _SC_XOPEN_VERSION
+    {"SC_XOPEN_VERSION",	_SC_XOPEN_VERSION},
+#endif
+#ifdef _SC_XOPEN_XCU_VERSION
+    {"SC_XOPEN_XCU_VERSION",	_SC_XOPEN_XCU_VERSION},
+#endif
+#ifdef _SC_XOPEN_XPG2
+    {"SC_XOPEN_XPG2",	_SC_XOPEN_XPG2},
+#endif
+#ifdef _SC_XOPEN_XPG3
+    {"SC_XOPEN_XPG3",	_SC_XOPEN_XPG3},
+#endif
+#ifdef _SC_XOPEN_XPG4
+    {"SC_XOPEN_XPG4",	_SC_XOPEN_XPG4},
+#endif
+};
+
+static int
+conv_sysconf_confname(PyObject *arg, int *valuep)
+{
+    return conv_confname(arg, valuep, posix_constants_sysconf,
+                         sizeof(posix_constants_sysconf)
+                           / sizeof(struct constdef));
+}
+
+PyDoc_STRVAR(posix_sysconf__doc__,
+"sysconf(name) -> integer\n\n\
+Return an integer-valued system configuration variable.");
+
+static PyObject *
+posix_sysconf(PyObject *self, PyObject *args)
+{
+    PyObject *result = NULL;
+    int name;
+
+    if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
+        int value;
+
+        errno = 0;
+        value = sysconf(name);
+        if (value == -1 && errno != 0)
+            posix_error();
+        else
+            result = PyInt_FromLong(value);
+    }
+    return result;
+}
+#endif
+
+
+/* This code is used to ensure that the tables of configuration value names
+ * are in sorted order as required by conv_confname(), and also to build the
+ * the exported dictionaries that are used to publish information about the
+ * names available on the host platform.
+ *
+ * Sorting the table at runtime ensures that the table is properly ordered
+ * when used, even for platforms we're not able to test on.  It also makes
+ * it easier to add additional entries to the tables.
+ */
+
+static int
+cmp_constdefs(const void *v1,  const void *v2)
+{
+    const struct constdef *c1 =
+        (const struct constdef *) v1;
+    const struct constdef *c2 =
+        (const struct constdef *) v2;
+
+    return strcmp(c1->name, c2->name);
+}
+
+static int
+setup_confname_table(struct constdef *table, size_t tablesize,
+		     char *tablename, PyObject *module)
+{
+    PyObject *d = NULL;
+    size_t i;
+
+    qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
+    d = PyDict_New();
+    if (d == NULL)
+	    return -1;
+
+    for (i=0; i < tablesize; ++i) {
+            PyObject *o = PyInt_FromLong(table[i].value);
+            if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
+		    Py_XDECREF(o);
+		    Py_DECREF(d);
+		    return -1;
+            }
+	    Py_DECREF(o);
+    }
+    return PyModule_AddObject(module, tablename, d);
+}
+
+/* Return -1 on failure, 0 on success. */
+static int
+setup_confname_tables(PyObject *module)
+{
+#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
+    if (setup_confname_table(posix_constants_pathconf,
+                             sizeof(posix_constants_pathconf)
+                               / sizeof(struct constdef),
+                             "pathconf_names", module))
+        return -1;
+#endif
+#ifdef HAVE_CONFSTR
+    if (setup_confname_table(posix_constants_confstr,
+                             sizeof(posix_constants_confstr)
+                               / sizeof(struct constdef),
+                             "confstr_names", module))
+        return -1;
+#endif
+#ifdef HAVE_SYSCONF
+    if (setup_confname_table(posix_constants_sysconf,
+                             sizeof(posix_constants_sysconf)
+                               / sizeof(struct constdef),
+                             "sysconf_names", module))
+        return -1;
+#endif
+    return 0;
+}
+
+
+PyDoc_STRVAR(posix_abort__doc__,
+"abort() -> does not return!\n\n\
+Abort the interpreter immediately.  This 'dumps core' or otherwise fails\n\
+in the hardest way possible on the hosting operating system.");
+
+static PyObject *
+posix_abort(PyObject *self, PyObject *noargs)
+{
+    abort();
+    /*NOTREACHED*/
+    Py_FatalError("abort() called from Python code didn't abort!");
+    return NULL;
+}
+
+#ifdef MS_WINDOWS
+PyDoc_STRVAR(win32_startfile__doc__,
+"startfile(filepath [, operation]) - Start a file with its associated\n\
+application.\n\
+\n\
+When \"operation\" is not specified or \"open\", this acts like\n\
+double-clicking the file in Explorer, or giving the file name as an\n\
+argument to the DOS \"start\" command: the file is opened with whatever\n\
+application (if any) its extension is associated.\n\
+When another \"operation\" is given, it specifies what should be done with\n\
+the file.  A typical operation is \"print\".\n\
+\n\
+startfile returns as soon as the associated application is launched.\n\
+There is no option to wait for the application to close, and no way\n\
+to retrieve the application's exit status.\n\
+\n\
+The filepath is relative to the current directory.  If you want to use\n\
+an absolute path, make sure the first character is not a slash (\"/\");\n\
+the underlying Win32 ShellExecute function doesn't work if it is.");
+
+static PyObject *
+win32_startfile(PyObject *self, PyObject *args)
+{
+	char *filepath;
+	char *operation = NULL;
+	HINSTANCE rc;
+#ifdef Py_WIN_WIDE_FILENAMES
+	if (unicode_file_names()) {
+		PyObject *unipath, *woperation = NULL;
+		if (!PyArg_ParseTuple(args, "U|s:startfile",
+				      &unipath, &operation)) {
+			PyErr_Clear();
+			goto normal;
+		}
+		
+
+		if (operation) {
+		    woperation = PyUnicode_DecodeASCII(operation, 
+						       strlen(operation), NULL);
+		    if (!woperation) {
+			    PyErr_Clear();
+			    operation = NULL;
+			    goto normal;
+		    }
+		}
+			
+		Py_BEGIN_ALLOW_THREADS
+		rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
+			PyUnicode_AS_UNICODE(unipath),
+			NULL, NULL, SW_SHOWNORMAL);
+		Py_END_ALLOW_THREADS
+
+		Py_XDECREF(woperation);
+		if (rc <= (HINSTANCE)32) {
+			PyObject *errval = win32_error_unicode("startfile",
+						PyUnicode_AS_UNICODE(unipath));
+			return errval;
+		}
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+#endif
+
+normal:
+	if (!PyArg_ParseTuple(args, "et|s:startfile", 
+			      Py_FileSystemDefaultEncoding, &filepath, 
+			      &operation))
+		return NULL;
+	Py_BEGIN_ALLOW_THREADS
+	rc = ShellExecute((HWND)0, operation, filepath, 
+			  NULL, NULL, SW_SHOWNORMAL);
+	Py_END_ALLOW_THREADS
+	if (rc <= (HINSTANCE)32) {
+		PyObject *errval = win32_error("startfile", filepath);
+		PyMem_Free(filepath);
+		return errval;
+	}
+	PyMem_Free(filepath);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+#endif
+
+#ifdef HAVE_GETLOADAVG
+PyDoc_STRVAR(posix_getloadavg__doc__,
+"getloadavg() -> (float, float, float)\n\n\
+Return the number of processes in the system run queue averaged over\n\
+the last 1, 5, and 15 minutes or raises OSError if the load average\n\
+was unobtainable");
+
+static PyObject *
+posix_getloadavg(PyObject *self, PyObject *noargs)
+{
+    double loadavg[3];
+    if (getloadavg(loadavg, 3)!=3) {
+        PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
+        return NULL;
+    } else
+        return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
+}
+#endif
+
+#ifdef MS_WINDOWS
+
+PyDoc_STRVAR(win32_urandom__doc__,
+"urandom(n) -> str\n\n\
+Return a string of n random bytes suitable for cryptographic use.");
+
+typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
+              LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
+              DWORD dwFlags );
+typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
+              BYTE *pbBuffer );
+
+static CRYPTGENRANDOM pCryptGenRandom = NULL;
+static HCRYPTPROV hCryptProv = 0;
+
+static PyObject*
+win32_urandom(PyObject *self, PyObject *args)
+{
+	int howMany;
+	PyObject* result;
+
+	/* Read arguments */
+	if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
+		return NULL;
+	if (howMany < 0)
+		return PyErr_Format(PyExc_ValueError,
+				    "negative argument not allowed");
+
+	if (hCryptProv == 0) {
+		HINSTANCE hAdvAPI32 = NULL;
+		CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
+
+		/* Obtain handle to the DLL containing CryptoAPI
+		   This should not fail	*/
+		hAdvAPI32 = GetModuleHandle("advapi32.dll");
+		if(hAdvAPI32 == NULL)
+			return win32_error("GetModuleHandle", NULL);
+
+		/* Obtain pointers to the CryptoAPI functions
+		   This will fail on some early versions of Win95 */
+		pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
+						hAdvAPI32,
+						"CryptAcquireContextA");
+		if (pCryptAcquireContext == NULL)
+			return PyErr_Format(PyExc_NotImplementedError,
+					    "CryptAcquireContextA not found");
+
+		pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
+						hAdvAPI32, "CryptGenRandom");
+		if (pCryptGenRandom == NULL)
+			return PyErr_Format(PyExc_NotImplementedError,
+					    "CryptGenRandom not found");
+
+		/* Acquire context */
+		if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
+					   PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
+			return win32_error("CryptAcquireContext", NULL);
+	}
+
+	/* Allocate bytes */
+	result = PyString_FromStringAndSize(NULL, howMany);
+	if (result != NULL) {
+		/* Get random data */
+		if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
+				      PyString_AS_STRING(result))) {
+			Py_DECREF(result);
+			return win32_error("CryptGenRandom", NULL);
+		}
+	}
+	return result;
+}
+#endif
+
+#ifdef __VMS
+/* Use openssl random routine */
+#include <openssl/rand.h>
+PyDoc_STRVAR(vms_urandom__doc__,
+"urandom(n) -> str\n\n\
+Return a string of n random bytes suitable for cryptographic use.");
+
+static PyObject*
+vms_urandom(PyObject *self, PyObject *args)
+{
+	int howMany;
+	PyObject* result;
+
+	/* Read arguments */
+	if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
+		return NULL;
+	if (howMany < 0)
+		return PyErr_Format(PyExc_ValueError,
+				    "negative argument not allowed");
+
+	/* Allocate bytes */
+	result = PyString_FromStringAndSize(NULL, howMany);
+	if (result != NULL) {
+		/* Get random data */
+		if (RAND_pseudo_bytes((unsigned char*)
+				      PyString_AS_STRING(result),
+				      howMany) < 0) {
+			Py_DECREF(result);
+			return PyErr_Format(PyExc_ValueError,
+					    "RAND_pseudo_bytes");
+		}
+	}
+	return result;
+}
+#endif
+
+static PyMethodDef posix_methods[] = {
+	{"access",	posix_access, METH_VARARGS, posix_access__doc__},
+#ifdef HAVE_TTYNAME
+	{"ttyname",	posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
+#endif
+	{"chdir",	posix_chdir, METH_VARARGS, posix_chdir__doc__},
+	{"chmod",	posix_chmod, METH_VARARGS, posix_chmod__doc__},
+#ifdef HAVE_CHOWN
+	{"chown",	posix_chown, METH_VARARGS, posix_chown__doc__},
+#endif /* HAVE_CHOWN */
+#ifdef HAVE_LCHOWN
+	{"lchown",	posix_lchown, METH_VARARGS, posix_lchown__doc__},
+#endif /* HAVE_LCHOWN */
+#ifdef HAVE_CHROOT
+	{"chroot",	posix_chroot, METH_VARARGS, posix_chroot__doc__},
+#endif
+#ifdef HAVE_CTERMID
+	{"ctermid",	posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
+#endif
+#ifdef HAVE_GETCWD
+	{"getcwd",	posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
+#ifdef Py_USING_UNICODE
+	{"getcwdu",	posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
+#endif
+#endif
+#ifdef HAVE_LINK
+	{"link",	posix_link, METH_VARARGS, posix_link__doc__},
+#endif /* HAVE_LINK */
+	{"listdir",	posix_listdir, METH_VARARGS, posix_listdir__doc__},
+	{"lstat",	posix_lstat, METH_VARARGS, posix_lstat__doc__},
+	{"mkdir",	posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
+#ifdef HAVE_NICE
+	{"nice",	posix_nice, METH_VARARGS, posix_nice__doc__},
+#endif /* HAVE_NICE */
+#ifdef HAVE_READLINK
+	{"readlink",	posix_readlink, METH_VARARGS, posix_readlink__doc__},
+#endif /* HAVE_READLINK */
+	{"rename",	posix_rename, METH_VARARGS, posix_rename__doc__},
+	{"rmdir",	posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
+	{"stat",	posix_stat, METH_VARARGS, posix_stat__doc__},
+	{"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
+#ifdef HAVE_SYMLINK
+	{"symlink",	posix_symlink, METH_VARARGS, posix_symlink__doc__},
+#endif /* HAVE_SYMLINK */
+#ifdef HAVE_SYSTEM
+	{"system",	posix_system, METH_VARARGS, posix_system__doc__},
+#endif
+	{"umask",	posix_umask, METH_VARARGS, posix_umask__doc__},
+#ifdef HAVE_UNAME
+	{"uname",	posix_uname, METH_NOARGS, posix_uname__doc__},
+#endif /* HAVE_UNAME */
+	{"unlink",	posix_unlink, METH_VARARGS, posix_unlink__doc__},
+	{"remove",	posix_unlink, METH_VARARGS, posix_remove__doc__},
+	{"utime",	posix_utime, METH_VARARGS, posix_utime__doc__},
+#ifdef HAVE_TIMES
+	{"times",	posix_times, METH_NOARGS, posix_times__doc__},
+#endif /* HAVE_TIMES */
+	{"_exit",	posix__exit, METH_VARARGS, posix__exit__doc__},
+#ifdef HAVE_EXECV
+	{"execv",	posix_execv, METH_VARARGS, posix_execv__doc__},
+	{"execve",	posix_execve, METH_VARARGS, posix_execve__doc__},
+#endif /* HAVE_EXECV */
+#ifdef HAVE_SPAWNV
+	{"spawnv",	posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
+	{"spawnve",	posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
+#if defined(PYOS_OS2)
+	{"spawnvp",	posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
+	{"spawnvpe",	posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
+#endif /* PYOS_OS2 */
+#endif /* HAVE_SPAWNV */
+#ifdef HAVE_FORK1
+	{"fork1",       posix_fork1, METH_NOARGS, posix_fork1__doc__},
+#endif /* HAVE_FORK1 */
+#ifdef HAVE_FORK
+	{"fork",	posix_fork, METH_NOARGS, posix_fork__doc__},
+#endif /* HAVE_FORK */
+#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
+	{"openpty",	posix_openpty, METH_NOARGS, posix_openpty__doc__},
+#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
+#ifdef HAVE_FORKPTY
+	{"forkpty",	posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
+#endif /* HAVE_FORKPTY */
+#ifdef HAVE_GETEGID
+	{"getegid",	posix_getegid, METH_NOARGS, posix_getegid__doc__},
+#endif /* HAVE_GETEGID */
+#ifdef HAVE_GETEUID
+	{"geteuid",	posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
+#endif /* HAVE_GETEUID */
+#ifdef HAVE_GETGID
+	{"getgid",	posix_getgid, METH_NOARGS, posix_getgid__doc__},
+#endif /* HAVE_GETGID */
+#ifdef HAVE_GETGROUPS
+	{"getgroups",	posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
+#endif
+	{"getpid",	posix_getpid, METH_NOARGS, posix_getpid__doc__},
+#ifdef HAVE_GETPGRP
+	{"getpgrp",	posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
+#endif /* HAVE_GETPGRP */
+#ifdef HAVE_GETPPID
+	{"getppid",	posix_getppid, METH_NOARGS, posix_getppid__doc__},
+#endif /* HAVE_GETPPID */
+#ifdef HAVE_GETUID
+	{"getuid",	posix_getuid, METH_NOARGS, posix_getuid__doc__},
+#endif /* HAVE_GETUID */
+#ifdef HAVE_GETLOGIN
+	{"getlogin",	posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
+#endif
+#ifdef HAVE_KILL
+	{"kill",	posix_kill, METH_VARARGS, posix_kill__doc__},
+#endif /* HAVE_KILL */
+#ifdef HAVE_KILLPG
+	{"killpg",	posix_killpg, METH_VARARGS, posix_killpg__doc__},
+#endif /* HAVE_KILLPG */
+#ifdef HAVE_PLOCK
+	{"plock",	posix_plock, METH_VARARGS, posix_plock__doc__},
+#endif /* HAVE_PLOCK */
+#ifdef HAVE_POPEN
+	{"popen",	posix_popen, METH_VARARGS, posix_popen__doc__},
+#ifdef MS_WINDOWS
+	{"popen2",	win32_popen2, METH_VARARGS},
+	{"popen3",	win32_popen3, METH_VARARGS},
+	{"popen4",	win32_popen4, METH_VARARGS},
+	{"startfile",	win32_startfile, METH_VARARGS, win32_startfile__doc__},
+#else
+#if defined(PYOS_OS2) && defined(PYCC_GCC)
+	{"popen2",	os2emx_popen2, METH_VARARGS},
+	{"popen3",	os2emx_popen3, METH_VARARGS},
+	{"popen4",	os2emx_popen4, METH_VARARGS},
+#endif
+#endif
+#endif /* HAVE_POPEN */
+#ifdef HAVE_SETUID
+	{"setuid",	posix_setuid, METH_VARARGS, posix_setuid__doc__},
+#endif /* HAVE_SETUID */
+#ifdef HAVE_SETEUID
+	{"seteuid",	posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
+#endif /* HAVE_SETEUID */
+#ifdef HAVE_SETEGID
+	{"setegid",	posix_setegid, METH_VARARGS, posix_setegid__doc__},
+#endif /* HAVE_SETEGID */
+#ifdef HAVE_SETREUID
+	{"setreuid",	posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
+#endif /* HAVE_SETREUID */
+#ifdef HAVE_SETREGID
+	{"setregid",	posix_setregid,	METH_VARARGS, posix_setregid__doc__},
+#endif /* HAVE_SETREGID */
+#ifdef HAVE_SETGID
+	{"setgid",	posix_setgid, METH_VARARGS, posix_setgid__doc__},
+#endif /* HAVE_SETGID */
+#ifdef HAVE_SETGROUPS
+	{"setgroups",	posix_setgroups, METH_O, posix_setgroups__doc__},
+#endif /* HAVE_SETGROUPS */
+#ifdef HAVE_GETPGID
+	{"getpgid",	posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
+#endif /* HAVE_GETPGID */
+#ifdef HAVE_SETPGRP
+	{"setpgrp",	posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
+#endif /* HAVE_SETPGRP */
+#ifdef HAVE_WAIT
+	{"wait",	posix_wait, METH_NOARGS, posix_wait__doc__},
+#endif /* HAVE_WAIT */
+#ifdef HAVE_WAIT3
+        {"wait3",	posix_wait3, METH_VARARGS, posix_wait3__doc__},
+#endif /* HAVE_WAIT3 */
+#ifdef HAVE_WAIT4
+        {"wait4",	posix_wait4, METH_VARARGS, posix_wait4__doc__},
+#endif /* HAVE_WAIT4 */
+#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
+	{"waitpid",	posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
+#endif /* HAVE_WAITPID */
+#ifdef HAVE_GETSID
+	{"getsid",	posix_getsid, METH_VARARGS, posix_getsid__doc__},
+#endif /* HAVE_GETSID */
+#ifdef HAVE_SETSID
+	{"setsid",	posix_setsid, METH_NOARGS, posix_setsid__doc__},
+#endif /* HAVE_SETSID */
+#ifdef HAVE_SETPGID
+	{"setpgid",	posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
+#endif /* HAVE_SETPGID */
+#ifdef HAVE_TCGETPGRP
+	{"tcgetpgrp",	posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
+#endif /* HAVE_TCGETPGRP */
+#ifdef HAVE_TCSETPGRP
+	{"tcsetpgrp",	posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
+#endif /* HAVE_TCSETPGRP */
+	{"open",	posix_open, METH_VARARGS, posix_open__doc__},
+	{"close",	posix_close, METH_VARARGS, posix_close__doc__},
+	{"dup",		posix_dup, METH_VARARGS, posix_dup__doc__},
+	{"dup2",	posix_dup2, METH_VARARGS, posix_dup2__doc__},
+	{"lseek",	posix_lseek, METH_VARARGS, posix_lseek__doc__},
+	{"read",	posix_read, METH_VARARGS, posix_read__doc__},
+	{"write",	posix_write, METH_VARARGS, posix_write__doc__},
+	{"fstat",	posix_fstat, METH_VARARGS, posix_fstat__doc__},
+	{"fdopen",	posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
+	{"isatty",	posix_isatty, METH_VARARGS, posix_isatty__doc__},
+#ifdef HAVE_PIPE
+	{"pipe",	posix_pipe, METH_NOARGS, posix_pipe__doc__},
+#endif
+#ifdef HAVE_MKFIFO
+	{"mkfifo",	posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
+#endif
+#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
+	{"mknod",	posix_mknod, METH_VARARGS, posix_mknod__doc__},
+#endif
+#ifdef HAVE_DEVICE_MACROS
+	{"major",	posix_major, METH_VARARGS, posix_major__doc__},
+	{"minor",	posix_minor, METH_VARARGS, posix_minor__doc__},
+	{"makedev",	posix_makedev, METH_VARARGS, posix_makedev__doc__},
+#endif
+#ifdef HAVE_FTRUNCATE
+	{"ftruncate",	posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
+#endif
+#ifdef HAVE_PUTENV
+	{"putenv",	posix_putenv, METH_VARARGS, posix_putenv__doc__},
+#endif
+#ifdef HAVE_UNSETENV
+	{"unsetenv",	posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
+#endif
+#ifdef HAVE_STRERROR
+	{"strerror",	posix_strerror, METH_VARARGS, posix_strerror__doc__},
+#endif
+#ifdef HAVE_FCHDIR
+	{"fchdir",	posix_fchdir, METH_O, posix_fchdir__doc__},
+#endif
+#ifdef HAVE_FSYNC
+	{"fsync",       posix_fsync, METH_O, posix_fsync__doc__},
+#endif
+#ifdef HAVE_FDATASYNC
+	{"fdatasync",   posix_fdatasync,  METH_O, posix_fdatasync__doc__},
+#endif
+#ifdef HAVE_SYS_WAIT_H
+#ifdef WCOREDUMP
+        {"WCOREDUMP",	posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
+#endif /* WCOREDUMP */
+#ifdef WIFCONTINUED
+        {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
+#endif /* WIFCONTINUED */
+#ifdef WIFSTOPPED
+        {"WIFSTOPPED",	posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
+#endif /* WIFSTOPPED */
+#ifdef WIFSIGNALED
+        {"WIFSIGNALED",	posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
+#endif /* WIFSIGNALED */
+#ifdef WIFEXITED
+        {"WIFEXITED",	posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
+#endif /* WIFEXITED */
+#ifdef WEXITSTATUS
+        {"WEXITSTATUS",	posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
+#endif /* WEXITSTATUS */
+#ifdef WTERMSIG
+        {"WTERMSIG",	posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
+#endif /* WTERMSIG */
+#ifdef WSTOPSIG
+        {"WSTOPSIG",	posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
+#endif /* WSTOPSIG */
+#endif /* HAVE_SYS_WAIT_H */
+#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
+	{"fstatvfs",	posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
+#endif
+#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
+	{"statvfs",	posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
+#endif
+#ifdef HAVE_TMPFILE
+	{"tmpfile",	posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
+#endif
+#ifdef HAVE_TEMPNAM
+	{"tempnam",	posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
+#endif
+#ifdef HAVE_TMPNAM
+	{"tmpnam",	posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
+#endif
+#ifdef HAVE_CONFSTR
+	{"confstr",	posix_confstr, METH_VARARGS, posix_confstr__doc__},
+#endif
+#ifdef HAVE_SYSCONF
+	{"sysconf",	posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
+#endif
+#ifdef HAVE_FPATHCONF
+	{"fpathconf",	posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
+#endif
+#ifdef HAVE_PATHCONF
+	{"pathconf",	posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
+#endif
+	{"abort",	posix_abort, METH_NOARGS, posix_abort__doc__},
+#ifdef MS_WINDOWS
+	{"_getfullpathname",	posix__getfullpathname, METH_VARARGS, NULL},
+#endif
+#ifdef HAVE_GETLOADAVG
+	{"getloadavg",	posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
+#endif
+ #ifdef MS_WINDOWS
+ 	{"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
+ #endif
+ #ifdef __VMS
+ 	{"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
+ #endif
+	{NULL,		NULL}		 /* Sentinel */
+};
+
+
+static int
+ins(PyObject *module, char *symbol, long value)
+{
+        return PyModule_AddIntConstant(module, symbol, value);
+}
+
+#if defined(PYOS_OS2)
+/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
+static int insertvalues(PyObject *module)
+{
+    APIRET    rc;
+    ULONG     values[QSV_MAX+1];
+    PyObject *v;
+    char     *ver, tmp[50];
+
+    Py_BEGIN_ALLOW_THREADS
+    rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
+    Py_END_ALLOW_THREADS
+
+    if (rc != NO_ERROR) {
+        os2_error(rc);
+        return -1;
+    }
+
+    if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
+    if (ins(module, "memkernel",    values[QSV_TOTRESMEM])) return -1;
+    if (ins(module, "memvirtual",   values[QSV_TOTAVAILMEM])) return -1;
+    if (ins(module, "maxpathlen",   values[QSV_MAX_PATH_LENGTH])) return -1;
+    if (ins(module, "maxnamelen",   values[QSV_MAX_COMP_LENGTH])) return -1;
+    if (ins(module, "revision",     values[QSV_VERSION_REVISION])) return -1;
+    if (ins(module, "timeslice",    values[QSV_MIN_SLICE])) return -1;
+
+    switch (values[QSV_VERSION_MINOR]) {
+    case 0:  ver = "2.00"; break;
+    case 10: ver = "2.10"; break;
+    case 11: ver = "2.11"; break;
+    case 30: ver = "3.00"; break;
+    case 40: ver = "4.00"; break;
+    case 50: ver = "5.00"; break;
+    default:
+        PyOS_snprintf(tmp, sizeof(tmp),
+        	      "%d-%d", values[QSV_VERSION_MAJOR],
+                      values[QSV_VERSION_MINOR]);
+        ver = &tmp[0];
+    }
+
+    /* Add Indicator of the Version of the Operating System */
+    if (PyModule_AddStringConstant(module, "version", tmp) < 0)
+        return -1;
+
+    /* Add Indicator of Which Drive was Used to Boot the System */
+    tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
+    tmp[1] = ':';
+    tmp[2] = '\0';
+
+    return PyModule_AddStringConstant(module, "bootdrive", tmp);
+}
+#endif
+
+static int
+all_ins(PyObject *d)
+{
+#ifdef F_OK
+        if (ins(d, "F_OK", (long)F_OK)) return -1;
+#endif
+#ifdef R_OK
+        if (ins(d, "R_OK", (long)R_OK)) return -1;
+#endif
+#ifdef W_OK
+        if (ins(d, "W_OK", (long)W_OK)) return -1;
+#endif
+#ifdef X_OK
+        if (ins(d, "X_OK", (long)X_OK)) return -1;
+#endif
+#ifdef NGROUPS_MAX
+        if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
+#endif
+#ifdef TMP_MAX
+        if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
+#endif
+#ifdef WCONTINUED
+        if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
+#endif
+#ifdef WNOHANG
+        if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
+#endif
+#ifdef WUNTRACED
+        if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
+#endif
+#ifdef O_RDONLY
+        if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
+#endif
+#ifdef O_WRONLY
+        if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
+#endif
+#ifdef O_RDWR
+        if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
+#endif
+#ifdef O_NDELAY
+        if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
+#endif
+#ifdef O_NONBLOCK
+        if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
+#endif
+#ifdef O_APPEND
+        if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
+#endif
+#ifdef O_DSYNC
+        if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
+#endif
+#ifdef O_RSYNC
+        if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
+#endif
+#ifdef O_SYNC
+        if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
+#endif
+#ifdef O_NOCTTY
+        if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
+#endif
+#ifdef O_CREAT
+        if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
+#endif
+#ifdef O_EXCL
+        if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
+#endif
+#ifdef O_TRUNC
+        if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
+#endif
+#ifdef O_BINARY
+        if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
+#endif
+#ifdef O_TEXT
+        if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
+#endif
+#ifdef O_LARGEFILE
+        if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
+#endif
+#ifdef O_SHLOCK
+        if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
+#endif
+#ifdef O_EXLOCK
+        if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
+#endif
+
+/* MS Windows */
+#ifdef O_NOINHERIT
+	/* Don't inherit in child processes. */
+        if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
+#endif
+#ifdef _O_SHORT_LIVED
+	/* Optimize for short life (keep in memory). */
+	/* MS forgot to define this one with a non-underscore form too. */
+        if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
+#endif
+#ifdef O_TEMPORARY
+	/* Automatically delete when last handle is closed. */
+        if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
+#endif
+#ifdef O_RANDOM
+	/* Optimize for random access. */
+        if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
+#endif
+#ifdef O_SEQUENTIAL
+	/* Optimize for sequential access. */
+        if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
+#endif
+
+/* GNU extensions. */
+#ifdef O_DIRECT
+        /* Direct disk access. */
+        if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
+#endif
+#ifdef O_DIRECTORY
+        /* Must be a directory.	 */
+        if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
+#endif
+#ifdef O_NOFOLLOW
+        /* Do not follow links.	 */
+        if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
+#endif
+
+	/* These come from sysexits.h */
+#ifdef EX_OK
+	if (ins(d, "EX_OK", (long)EX_OK)) return -1;
+#endif /* EX_OK */
+#ifdef EX_USAGE
+	if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
+#endif /* EX_USAGE */
+#ifdef EX_DATAERR
+	if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
+#endif /* EX_DATAERR */
+#ifdef EX_NOINPUT
+	if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
+#endif /* EX_NOINPUT */
+#ifdef EX_NOUSER
+	if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
+#endif /* EX_NOUSER */
+#ifdef EX_NOHOST
+	if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
+#endif /* EX_NOHOST */
+#ifdef EX_UNAVAILABLE
+	if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
+#endif /* EX_UNAVAILABLE */
+#ifdef EX_SOFTWARE
+	if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
+#endif /* EX_SOFTWARE */
+#ifdef EX_OSERR
+	if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
+#endif /* EX_OSERR */
+#ifdef EX_OSFILE
+	if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
+#endif /* EX_OSFILE */
+#ifdef EX_CANTCREAT
+	if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
+#endif /* EX_CANTCREAT */
+#ifdef EX_IOERR
+	if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
+#endif /* EX_IOERR */
+#ifdef EX_TEMPFAIL
+	if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
+#endif /* EX_TEMPFAIL */
+#ifdef EX_PROTOCOL
+	if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
+#endif /* EX_PROTOCOL */
+#ifdef EX_NOPERM
+	if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
+#endif /* EX_NOPERM */
+#ifdef EX_CONFIG
+	if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
+#endif /* EX_CONFIG */
+#ifdef EX_NOTFOUND
+	if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
+#endif /* EX_NOTFOUND */
+
+#ifdef HAVE_SPAWNV
+#if defined(PYOS_OS2) && defined(PYCC_GCC)
+	if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
+	if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
+	if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
+	if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
+	if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
+	if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
+	if (ins(d, "P_PM", (long)P_PM)) return -1;
+	if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
+	if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
+	if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
+	if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
+	if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
+	if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
+	if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
+	if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
+	if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
+	if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
+	if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
+	if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
+	if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
+#else
+        if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
+        if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
+        if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
+        if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
+        if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
+#endif
+#endif
+
+#if defined(PYOS_OS2)
+        if (insertvalues(d)) return -1;
+#endif
+        return 0;
+}
+
+
+#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
+#define INITFUNC initnt
+#define MODNAME "nt"
+
+#elif defined(PYOS_OS2)
+#define INITFUNC initos2
+#define MODNAME "os2"
+
+#else
+#define INITFUNC initposix
+#define MODNAME "posix"
+#endif
+
+PyMODINIT_FUNC
+INITFUNC(void)
+{
+	PyObject *m, *v;
+
+	m = Py_InitModule3(MODNAME,
+			   posix_methods,
+			   posix__doc__);
+	if (m == NULL)
+    		return;
+
+	/* Initialize environ dictionary */
+	v = convertenviron();
+	Py_XINCREF(v);
+	if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
+		return;
+	Py_DECREF(v);
+
+        if (all_ins(m))
+                return;
+
+        if (setup_confname_tables(m))
+                return;
+
+	Py_INCREF(PyExc_OSError);
+	PyModule_AddObject(m, "error", PyExc_OSError);
+
+#ifdef HAVE_PUTENV
+	if (posix_putenv_garbage == NULL)
+		posix_putenv_garbage = PyDict_New();
+#endif
+
+	if (!initialized) {
+		stat_result_desc.name = MODNAME ".stat_result";
+		stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
+		stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
+		stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
+		PyStructSequence_InitType(&StatResultType, &stat_result_desc);
+		structseq_new = StatResultType.tp_new;
+		StatResultType.tp_new = statresult_new;
+
+		statvfs_result_desc.name = MODNAME ".statvfs_result";
+		PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
+	}
+	Py_INCREF((PyObject*) &StatResultType);
+	PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
+	Py_INCREF((PyObject*) &StatVFSResultType);
+	PyModule_AddObject(m, "statvfs_result",
+			   (PyObject*) &StatVFSResultType);
+	initialized = 1;
+
+#ifdef __APPLE__
+	/*
+	 * Step 2 of weak-linking support on Mac OS X.
+	 *
+	 * The code below removes functions that are not available on the
+	 * currently active platform. 
+	 *
+	 * This block allow one to use a python binary that was build on
+	 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on 
+	 * OSX 10.4.
+	 */
+#ifdef HAVE_FSTATVFS
+	if (fstatvfs == NULL) {
+		if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
+			return;
+		}
+	}
+#endif /* HAVE_FSTATVFS */
+
+#ifdef HAVE_STATVFS
+	if (statvfs == NULL) {
+		if (PyObject_DelAttrString(m, "statvfs") == -1) {
+			return;
+		}
+	}
+#endif /* HAVE_STATVFS */
+
+# ifdef HAVE_LCHOWN
+	if (lchown == NULL) {
+		if (PyObject_DelAttrString(m, "lchown") == -1) {
+			return;
+		}
+	}
+#endif /* HAVE_LCHOWN */
+
+
+#endif /* __APPLE__ */
+
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+

Added: vendor/Python/current/Modules/puremodule.c
===================================================================
--- vendor/Python/current/Modules/puremodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/puremodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,988 @@
+/* This module exports the C API to such Pure Software Inc. (tm) (now
+ * called Pure Atria Corporation) products as Purify (tm) and Quantify
+ * (tm).  Other packages could be added, but I didn't have those products
+ * and thus lack the API documentation.
+ *
+ * Currently supported: Quantify 2.x, Purify 3.x
+ *
+ * You need to decide which products you want to incorporate into the
+ * module when you compile this file.  The way to do this is to edit
+ * <Python>/Modules/Setup to pass the appropriate flags to the compiler.
+ * -DWITH_PURIFY compiles in the Purify support, and -DWITH_QUANTIFY
+ * compiles in the Quantify support.  -DWITH_ALL_PURE compiles in both.
+ * You can also build a Purify'd or Quantify'd interpreter by passing in
+ * the LINKCC variable to make.  E.g. if you want to build a Purify'd
+ * interpreter and are using gcc, build Python with this command:
+ *
+ * make LINKCC='purify gcc'
+ *
+ * It would be nice (and probably easy) to provide this file as a shared
+ * library, however since it doesn't appear that Pure gives us shared
+ * libraries of the stubs, it doesn't really matter.  For now, you have to
+ * link this file in statically.
+ *
+ * Major bogosity.  The purify.h header file exports purify_exit(), but
+ * guess what?  It is not defined in the libpurify_stubs.a file!  I tried
+ * to fake one here, hoping the Pure linker would Do The Right Thing when
+ * instrumented for Purify, but it doesn't seem to, so I don't export
+ * purify_exit() to the Python layer.  In Python you should raise a
+ * SystemExit exception anyway.
+ *
+ * The actual purify.h and quantify.h files which embody the APIs are
+ * copyrighted by Pure Software, Inc. and are only attainable through them.
+ * This module assumes you have legally installed licenses of their
+ * software.  Contact them on the Web via <http://www.pureatria.com/>
+ *
+ * Author: Barry Warsaw <bwarsaw at python.org>
+ *                      <bwarsaw at cnri.reston.va.us>
+ */
+
+#include "Python.h"
+
+#if defined(WITH_PURIFY) || defined(WITH_ALL_PURE)
+#    include <purify.h>
+#    define HAS_PURIFY_EXIT 0                /* See note at top of file */
+#    define PURE_PURIFY_VERSION 3            /* not provided by purify.h */
+#endif
+#if defined(WITH_QUANTIFY) || defined(WITH_ALL_PURE)
+#    include <quantify.h>
+#    define PURE_QUANTIFY_VERSION 2          /* not provided by quantify.h */
+#endif
+#if defined(PURIFY_H) || defined(QUANTIFY_H)
+#    define COMMON_PURE_FUNCTIONS
+#endif /* PURIFY_H || QUANTIFY_H */
+
+typedef int (*VoidArgFunc)(void);
+typedef int (*StringArgFunc)(char*);
+typedef int (*PrintfishFunc)(const char*, ...);
+typedef int (*StringIntArgFunc)(const char*, int);
+
+
+
+static PyObject*
+call_voidarg_function(VoidArgFunc func, PyObject *self, PyObject *args)
+{
+	int status;
+
+	if (!PyArg_ParseTuple(args, ""))
+		return NULL;
+
+	status = func();
+	return Py_BuildValue("i", status);
+}
+
+static PyObject*
+call_stringarg_function(StringArgFunc func, PyObject *self, PyObject *args)
+{
+	int status;
+	char* stringarg;
+
+	if (!PyArg_ParseTuple(args, "s", &stringarg))
+		return NULL;
+
+	status = func(stringarg);
+	return Py_BuildValue("i", status);
+}
+
+static PyObject*
+call_stringorint_function(StringArgFunc func, PyObject *self, PyObject *args)
+{
+	int status;
+	int intarg;
+	char* stringarg;
+
+        /* according to the quantify.h file, the argument to
+         * quantify_*_recording_system_call can be an integer or a string,
+	 * but the functions are prototyped as taking a single char*
+	 * argument. Yikes!
+         */
+	if (PyArg_ParseTuple(args, "i", &intarg))
+		/* func is prototyped as int(*)(char*)
+		 * better shut up the compiler
+		 */
+		status = func((char*)intarg);
+
+	else {
+		PyErr_Clear();
+		if (!PyArg_ParseTuple(args, "s", &stringarg))
+			return NULL;
+		else
+			status = func(stringarg);
+	}
+	return Py_BuildValue("i", status);
+}
+
+static PyObject*
+call_printfish_function(PrintfishFunc func, PyObject *self, PyObject *args)
+{
+	/* we support the printf() style vararg functions by requiring the
+         * formatting be done in Python.  At the C level we pass just a string
+         * to the printf() style function.
+         */
+	int status;
+	char* argstring;
+
+	if (!PyArg_ParseTuple(args, "s", &argstring))
+		return NULL;
+
+	status = func("%s", argstring);
+	return Py_BuildValue("i", status);
+}
+
+static PyObject*
+call_intasaddr_function(StringArgFunc func, PyObject *self, PyObject *args)
+{
+	long memrep;
+	int id;
+
+	if (!PyArg_ParseTuple(args, "l", &memrep))
+		return NULL;
+
+	id = func((char*)memrep);
+	return Py_BuildValue("i", id);
+}
+
+static PyObject*
+call_stringandint_function(StringIntArgFunc func, PyObject *self,
+			   PyObject *args)
+{
+	long srcrep;
+	int size;
+	int status;
+
+	if (!PyArg_ParseTuple(args, "li", &srcrep, &size))
+		return NULL;
+
+	status = func((char*)srcrep, size);
+	return Py_BuildValue("i", status);
+}
+
+
+
+/* functions common to all products
+ *
+ * N.B. These printf() style functions are a bit of a kludge.  Since the
+ * API doesn't provide vprintf versions of them, we can't call them
+ * directly.  They don't support all the standard printf % modifiers
+ * anyway.  The way to use these is to use Python's % string operator to do
+ * the formatting.  By the time these functions get the thing to print,
+ * it's already a string, and they just use "%s" as the format string.
+ */
+
+#ifdef COMMON_PURE_FUNCTIONS
+
+static PyObject*
+pure_pure_logfile_printf(PyObject* self, PyObject* args)
+{
+	return call_printfish_function(pure_logfile_printf, self, args);
+}
+
+static PyObject*
+pure_pure_printf(PyObject* self, PyObject* args)
+{
+	return call_printfish_function(pure_printf, self, args);
+}
+
+static PyObject*
+pure_pure_printf_with_banner(PyObject* self, PyObject* args)
+{
+	return call_printfish_function(pure_printf_with_banner, self, args);
+}
+
+
+#endif /* COMMON_PURE_FUNCTIONS */
+
+
+
+/* Purify functions
+ *
+ * N.B. There are some interfaces described in the purify.h file that are
+ * not described in the manual.
+ *
+ * Unsigned longs purify_report_{address,number,type,result} are not
+ * accessible from the Python layer since they seem mostly useful when
+ * purify_stop_here() is called by the (C) debugger.  The same is true of
+ * the purify_stop_here_internal() function so it isn't exported either.
+ * And purify_stop_here() should never be called directly.
+ *
+ * The header file says purify_{new,all,clear_new}_reports() are obsolete
+ * so they aren't exported.
+ *
+ * None of the custom dynamic loader functions are exported.
+ *
+ * purify_unsafe_memcpy() isn't exported.
+ *
+ * purify_{start,size}_of_block() aren't exported.
+ *
+ * The manual that I have says that the prototype for the second argument
+ * to purify_map_pool is:
+ *
+ *    void (*fn)(char*)
+ *
+ * but the purify.h file declares it as:
+ *
+ *    void (*fn)(char*, int, void*)
+ *
+ * and does not explain what the other arguments are for.  I support the
+ * latter but I don't know if I do it right or usefully.
+ *
+ * The header file says that purify_describe() returns a char* which is the
+ * pointer passed to it.  The manual says it returns an int, but I believe
+ * that is a typo.
+ */
+#ifdef PURIFY_H
+
+static PyObject*
+pure_purify_all_inuse(PyObject *self, PyObject *args)
+{
+	return call_voidarg_function(purify_all_inuse, self, args);
+}
+static PyObject*
+pure_purify_all_leaks(PyObject *self, PyObject *args)
+{
+	return call_voidarg_function(purify_all_leaks, self, args);
+}
+static PyObject*
+pure_purify_new_inuse(PyObject *self, PyObject *args)
+{
+	return call_voidarg_function(purify_new_inuse, self, args);
+}
+static PyObject*
+pure_purify_new_leaks(PyObject *self, PyObject *args)
+{
+	return call_voidarg_function(purify_new_leaks, self, args);
+}
+static PyObject*
+pure_purify_clear_inuse(PyObject *self, PyObject *args)
+{
+	return call_voidarg_function(purify_clear_inuse, self, args);
+}
+static PyObject*
+pure_purify_clear_leaks(PyObject *self, PyObject *args)
+{
+	return call_voidarg_function(purify_clear_leaks, self, args);
+}
+static PyObject*
+pure_purify_all_fds_inuse(PyObject *self, PyObject *args)
+{
+	return call_voidarg_function(purify_all_fds_inuse, self, args);
+}
+static PyObject*
+pure_purify_new_fds_inuse(PyObject *self, PyObject *args)
+{
+	return call_voidarg_function(purify_new_fds_inuse, self, args);
+}
+static PyObject*
+pure_purify_printf_with_call_chain(PyObject *self, PyObject *args)
+{
+	return call_printfish_function(purify_printf_with_call_chain,
+				       self, args);
+}
+static PyObject*
+pure_purify_set_pool_id(PyObject *self, PyObject *args)
+{
+	long memrep;
+	int id;
+
+	if (!PyArg_ParseTuple(args, "li:purify_set_pool_id", &memrep, &id))
+		return NULL;
+
+	purify_set_pool_id((char*)memrep, id);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+static PyObject*
+pure_purify_get_pool_id(PyObject *self, PyObject *args)
+{
+	return call_intasaddr_function(purify_get_pool_id, self, args);
+}
+static PyObject*
+pure_purify_set_user_data(PyObject *self, PyObject *args)
+{
+	long memrep;
+	long datarep;
+
+	if (!PyArg_ParseTuple(args, "ll:purify_set_user_data", &memrep, &datarep))
+		return NULL;
+
+	purify_set_user_data((char*)memrep, (void*)datarep);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+static PyObject*
+pure_purify_get_user_data(PyObject *self, PyObject *args)
+{
+        /* can't use call_intasaddr_function() since purify_get_user_data()
+         * returns a void*
+         */
+	long memrep;
+	void* data;
+
+	if (!PyArg_ParseTuple(args, "l:purify_get_user_data", &memrep))
+		return NULL;
+
+	data = purify_get_user_data((char*)memrep);
+	return Py_BuildValue("l", (long)data);
+}
+
+
+/* this global variable is shared by both mapping functions:
+ * pure_purify_map_pool() and pure_purify_map_pool_id().  Since they cache
+ * this variable it should be safe in the face of recursion or cross
+ * calling.
+ *
+ * Further note that the prototype for the callback function is wrong in
+ * the Purify manual.  The manual says the function takes a single char*,
+ * but the header file says it takes an additional int and void*.  I have
+ * no idea what these are for!
+ */
+static PyObject* MapCallable = NULL;
+
+static void
+map_pool_callback(char* mem, int user_size, void *user_aux_data)
+{
+	long memrep = (long)mem;
+	long user_aux_data_rep = (long)user_aux_data;
+	PyObject* result;
+	PyObject* memobj = Py_BuildValue("lil", memrep, user_size,
+					 user_aux_data_rep);
+
+	if (memobj == NULL)
+		return;
+
+	result = PyEval_CallObject(MapCallable, memobj);
+	Py_DECREF(result);
+	Py_DECREF(memobj);
+}
+
+static PyObject*
+pure_purify_map_pool(PyObject *self, PyObject *args)
+{
+        /* cache global variable in case of recursion */
+	PyObject* saved_callable = MapCallable;
+	PyObject* arg_callable;
+	int id;
+
+	if (!PyArg_ParseTuple(args, "iO:purify_map_pool", &id, &arg_callable))
+		return NULL;
+
+	if (!PyCallable_Check(arg_callable)) {
+		PyErr_SetString(PyExc_TypeError,
+				"Second argument must be callable");
+		return NULL;
+	}
+	MapCallable = arg_callable;
+	purify_map_pool(id, map_pool_callback);
+	MapCallable = saved_callable;
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static void
+PurifyMapPoolIdCallback(int id)
+{
+	PyObject* result;
+	PyObject* intobj = Py_BuildValue("i", id);
+
+	if (intobj == NULL)
+		return;
+
+	result = PyEval_CallObject(MapCallable, intobj);
+	Py_DECREF(result);
+	Py_DECREF(intobj);
+}
+
+static PyObject*
+pure_purify_map_pool_id(PyObject *self, PyObject *args)
+{
+        /* cache global variable in case of recursion */
+	PyObject* saved_callable = MapCallable;
+	PyObject* arg_callable;
+
+	if (!PyArg_ParseTuple(args, "O:purify_map_pool_id", &arg_callable))
+		return NULL;
+
+	if (!PyCallable_Check(arg_callable)) {
+		PyErr_SetString(PyExc_TypeError, "Argument must be callable.");
+		return NULL;
+	}
+
+	MapCallable = arg_callable;
+	purify_map_pool_id(PurifyMapPoolIdCallback);
+	MapCallable = saved_callable;
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+
+
+static PyObject*
+pure_purify_new_messages(PyObject *self, PyObject *args)
+{
+	return call_voidarg_function(purify_new_messages, self, args);
+}
+static PyObject*
+pure_purify_all_messages(PyObject *self, PyObject *args)
+{
+	return call_voidarg_function(purify_all_messages, self, args);
+}
+static PyObject*
+pure_purify_clear_messages(PyObject *self, PyObject *args)
+{
+	return call_voidarg_function(purify_clear_messages, self, args);
+}
+static PyObject*
+pure_purify_clear_new_messages(PyObject *self, PyObject *args)
+{
+	return call_voidarg_function(purify_clear_new_messages, self, args);
+}
+static PyObject*
+pure_purify_start_batch(PyObject *self, PyObject *args)
+{
+	return call_voidarg_function(purify_start_batch, self, args);
+}
+static PyObject*
+pure_purify_start_batch_show_first(PyObject *self, PyObject *args)
+{
+	return call_voidarg_function(purify_start_batch_show_first,
+				     self, args);
+}
+static PyObject*
+pure_purify_stop_batch(PyObject *self, PyObject *args)
+{
+	return call_voidarg_function(purify_stop_batch, self, args);
+}
+static PyObject*
+pure_purify_name_thread(PyObject *self, PyObject *args)
+{
+        /* can't strictly use call_stringarg_function since
+         * purify_name_thread takes a const char*, not a char*
+         */
+	int status;
+	char* stringarg;
+
+	if (!PyArg_ParseTuple(args, "s:purify_name_thread", &stringarg))
+		return NULL;
+
+	status = purify_name_thread(stringarg);
+	return Py_BuildValue("i", status);
+}
+static PyObject*
+pure_purify_watch(PyObject *self, PyObject *args)
+{
+	return call_intasaddr_function(purify_watch, self, args);
+}
+static PyObject*
+pure_purify_watch_1(PyObject *self, PyObject *args)
+{
+	return call_intasaddr_function(purify_watch_1, self, args);
+}
+static PyObject*
+pure_purify_watch_2(PyObject *self, PyObject *args)
+{
+	return call_intasaddr_function(purify_watch_2, self, args);
+}
+static PyObject*
+pure_purify_watch_4(PyObject *self, PyObject *args)
+{
+	return call_intasaddr_function(purify_watch_4, self, args);
+}
+static PyObject*
+pure_purify_watch_8(PyObject *self, PyObject *args)
+{
+	return call_intasaddr_function(purify_watch_8, self, args);
+}
+static PyObject*
+pure_purify_watch_w_1(PyObject *self, PyObject *args)
+{
+	return call_intasaddr_function(purify_watch_w_1, self, args);
+}
+static PyObject*
+pure_purify_watch_w_2(PyObject *self, PyObject *args)
+{
+	return call_intasaddr_function(purify_watch_w_2, self, args);
+}
+static PyObject*
+pure_purify_watch_w_4(PyObject *self, PyObject *args)
+{
+	return call_intasaddr_function(purify_watch_w_4, self, args);
+}
+static PyObject*
+pure_purify_watch_w_8(PyObject *self, PyObject *args)
+{
+	return call_intasaddr_function(purify_watch_w_8, self, args);
+}
+static PyObject*
+pure_purify_watch_r_1(PyObject *self, PyObject *args)
+{
+	return call_intasaddr_function(purify_watch_r_1, self, args);
+}
+static PyObject*
+pure_purify_watch_r_2(PyObject *self, PyObject *args)
+{
+	return call_intasaddr_function(purify_watch_r_2, self, args);
+}
+static PyObject*
+pure_purify_watch_r_4(PyObject *self, PyObject *args)
+{
+	return call_intasaddr_function(purify_watch_r_4, self, args);
+}
+static PyObject*
+pure_purify_watch_r_8(PyObject *self, PyObject *args)
+{
+	return call_intasaddr_function(purify_watch_r_8, self, args);
+}
+static PyObject*
+pure_purify_watch_rw_1(PyObject *self, PyObject *args)
+{
+	return call_intasaddr_function(purify_watch_rw_1, self, args);
+}
+static PyObject*
+pure_purify_watch_rw_2(PyObject *self, PyObject *args)
+{
+	return call_intasaddr_function(purify_watch_rw_2, self, args);
+}
+static PyObject*
+pure_purify_watch_rw_4(PyObject *self, PyObject *args)
+{
+	return call_intasaddr_function(purify_watch_rw_4, self, args);
+}
+static PyObject*
+pure_purify_watch_rw_8(PyObject *self, PyObject *args)
+{
+	return call_intasaddr_function(purify_watch_rw_8, self, args);
+}
+
+static PyObject*
+pure_purify_watch_n(PyObject *self, PyObject *args)
+{
+	long addrrep;
+	unsigned int size;
+	char* type;
+	int status;
+
+	if (!PyArg_ParseTuple(args, "lis:purify_watch_n", &addrrep, &size, &type))
+		return NULL;
+
+	status = purify_watch_n((char*)addrrep, size, type);
+	return Py_BuildValue("i", status);
+}
+
+static PyObject*
+pure_purify_watch_info(PyObject *self, PyObject *args)
+{
+	return call_voidarg_function(purify_watch_info, self, args);
+}
+
+static PyObject*
+pure_purify_watch_remove(PyObject *self, PyObject *args)
+{
+	int watchno;
+	int status;
+
+	if (!PyArg_ParseTuple(args, "i:purify_watch_remove", &watchno))
+		return NULL;
+
+	status = purify_watch_remove(watchno);
+	return Py_BuildValue("i", status);
+}
+
+static PyObject*
+pure_purify_watch_remove_all(PyObject *self, PyObject *args)
+{
+	return call_voidarg_function(purify_watch_remove_all, self, args);
+}
+static PyObject*
+pure_purify_describe(PyObject *self, PyObject *args)
+{
+	long addrrep;
+	char* rtn;
+
+	if (!PyArg_ParseTuple(args, "l:purify_describe", &addrrep))
+		return NULL;
+
+	rtn = purify_describe((char*)addrrep);
+	return Py_BuildValue("l", (long)rtn);
+}
+
+static PyObject*
+pure_purify_what_colors(PyObject *self, PyObject *args)
+{
+	long addrrep;
+	unsigned int size;
+	int status;
+    
+	if (!PyArg_ParseTuple(args, "li:purify_what_colors", &addrrep, &size))
+		return NULL;
+
+	status = purify_what_colors((char*)addrrep, size);
+	return Py_BuildValue("i", status);
+}
+
+static PyObject*
+pure_purify_is_running(PyObject *self, PyObject *args)
+{
+	return call_voidarg_function(purify_is_running, self, args);
+}
+
+static PyObject*
+pure_purify_assert_is_readable(PyObject *self, PyObject *args)
+{
+	return call_stringandint_function(purify_assert_is_readable,
+					  self, args);
+}
+static PyObject*
+pure_purify_assert_is_writable(PyObject *self, PyObject *args)
+{
+	return call_stringandint_function(purify_assert_is_writable,
+					  self, args);
+}
+
+#if HAS_PURIFY_EXIT
+
+/* I wish I could include this, but I can't.  See the notes at the top of
+ * the file.
+ */
+
+static PyObject*
+pure_purify_exit(PyObject *self, PyObject *args)
+{
+	int status;
+
+	if (!PyArg_ParseTuple(args, "i:purify_exit", &status))
+		return NULL;
+
+        /* purify_exit doesn't always act like exit(). See the manual */
+	purify_exit(status);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+#endif /* HAS_PURIFY_EXIT */
+
+#endif /* PURIFY_H */
+
+
+
+/* Quantify functions
+ *
+ * N.B. Some of these functions are only described in the quantify.h file,
+ * not in the version of the hardcopy manual that I had.  If you're not
+ * sure what some of these do, check the header file, it is documented
+ * fairly well.
+ *
+ * None of the custom dynamic loader functions are exported.
+ *
+ */
+#ifdef QUANTIFY_H
+
+static PyObject*
+pure_quantify_is_running(PyObject *self, PyObject *args)
+{
+	return call_voidarg_function(quantify_is_running, self, args);
+}
+static PyObject*
+pure_quantify_help(PyObject *self, PyObject *args)
+{
+	return call_voidarg_function(quantify_help, self, args);
+}
+static PyObject*
+pure_quantify_print_recording_state(PyObject *self, PyObject *args)
+{
+	return call_voidarg_function(quantify_print_recording_state,
+				     self, args);
+}
+static PyObject*
+pure_quantify_start_recording_data(PyObject *self, PyObject *args)
+{
+	return call_voidarg_function(quantify_start_recording_data,
+				     self, args);
+}
+static PyObject*
+pure_quantify_stop_recording_data(PyObject *self, PyObject *args)
+{
+	return call_voidarg_function(quantify_stop_recording_data, self, args);
+}
+static PyObject*
+pure_quantify_is_recording_data(PyObject *self, PyObject *args)
+{
+	return call_voidarg_function(quantify_is_recording_data, self, args);
+}
+static PyObject*
+pure_quantify_start_recording_system_calls(PyObject *self, PyObject *args)
+{
+	return call_voidarg_function(quantify_start_recording_system_calls,
+				     self, args);
+}
+static PyObject*
+pure_quantify_stop_recording_system_calls(PyObject *self, PyObject *args)
+{
+	return call_voidarg_function(quantify_stop_recording_system_calls,
+				     self, args);
+}
+static PyObject*
+pure_quantify_is_recording_system_calls(PyObject *self, PyObject *args)
+{
+	return call_voidarg_function(quantify_is_recording_system_calls,
+				     self, args);
+}
+static PyObject*
+pure_quantify_start_recording_system_call(PyObject *self, PyObject *args)
+{
+	return call_stringorint_function(quantify_start_recording_system_call,
+					   self, args);
+}
+static PyObject*
+pure_quantify_stop_recording_system_call(PyObject *self, PyObject *args)
+{
+	return call_stringorint_function(quantify_stop_recording_system_call,
+					 self, args);
+}
+static PyObject*
+pure_quantify_is_recording_system_call(PyObject *self, PyObject *args)
+{
+	return call_stringorint_function(quantify_is_recording_system_call,
+					 self, args);
+}
+static PyObject*
+pure_quantify_start_recording_dynamic_library_data(PyObject *self, PyObject *args)
+{
+	return call_voidarg_function(
+		quantify_start_recording_dynamic_library_data,
+		self, args);
+}
+static PyObject*
+pure_quantify_stop_recording_dynamic_library_data(PyObject *self, PyObject *args)
+{
+	return call_voidarg_function(
+		quantify_stop_recording_dynamic_library_data,
+		self, args);
+}
+static PyObject*
+pure_quantify_is_recording_dynamic_library_data(PyObject *self, PyObject *args)
+{
+	return call_voidarg_function(
+		quantify_is_recording_dynamic_library_data,
+		self, args);
+}
+static PyObject*
+pure_quantify_start_recording_register_window_traps(PyObject *self, PyObject *args)
+{
+	return call_voidarg_function(
+		quantify_start_recording_register_window_traps,
+		self, args);
+}
+static PyObject*
+pure_quantify_stop_recording_register_window_traps(PyObject *self, PyObject *args)
+{
+	return call_voidarg_function(
+		quantify_stop_recording_register_window_traps,
+		self, args);
+}
+static PyObject*
+pure_quantify_is_recording_register_window_traps(PyObject *self, PyObject *args)
+{
+	return call_voidarg_function(
+		quantify_is_recording_register_window_traps,
+		self, args);
+}
+static PyObject*
+pure_quantify_disable_recording_data(PyObject *self, PyObject *args)
+{
+	return call_voidarg_function(quantify_disable_recording_data,
+				     self, args);
+}
+static PyObject*
+pure_quantify_clear_data(PyObject *self, PyObject *args)
+{
+	return call_voidarg_function(quantify_clear_data, self, args);
+}
+static PyObject*
+pure_quantify_save_data(PyObject *self, PyObject *args)
+{
+	return call_voidarg_function(quantify_save_data, self, args);
+}
+static PyObject*
+pure_quantify_save_data_to_file(PyObject *self, PyObject *args)
+{
+	return call_stringarg_function(quantify_save_data_to_file, self, args);
+}
+static PyObject*
+pure_quantify_add_annotation(PyObject *self, PyObject *args)
+{
+	return call_stringarg_function(quantify_add_annotation, self, args);
+}
+
+#endif /* QUANTIFY_H */
+
+
+
+/* external interface
+ */
+static struct PyMethodDef
+pure_methods[] = {
+#ifdef COMMON_PURE_FUNCTIONS
+    {"pure_logfile_printf",            pure_pure_logfile_printf,            METH_VARARGS},
+    {"pure_printf",                    pure_pure_printf,                    METH_VARARGS},
+    {"pure_printf_with_banner",        pure_pure_printf_with_banner,        METH_VARARGS},
+#endif /* COMMON_PURE_FUNCTIONS */
+#ifdef PURIFY_H
+    {"purify_all_inuse",               pure_purify_all_inuse,               METH_VARARGS},
+    {"purify_all_leaks",               pure_purify_all_leaks,               METH_VARARGS},
+    {"purify_new_inuse",               pure_purify_new_inuse,               METH_VARARGS},
+    {"purify_new_leaks",               pure_purify_new_leaks,               METH_VARARGS},
+    {"purify_clear_inuse",             pure_purify_clear_inuse,             METH_VARARGS},
+    {"purify_clear_leaks",             pure_purify_clear_leaks,             METH_VARARGS},
+    {"purify_all_fds_inuse",           pure_purify_all_fds_inuse,           METH_VARARGS},
+    {"purify_new_fds_inuse",           pure_purify_new_fds_inuse,           METH_VARARGS},
+    /* see purify.h */
+    {"purify_logfile_printf",          pure_pure_logfile_printf,            METH_VARARGS},
+    {"purify_printf",                  pure_pure_printf,                    METH_VARARGS},
+    {"purify_printf_with_banner",      pure_pure_printf_with_banner,        METH_VARARGS},
+    /**/
+    {"purify_printf_with_call_chain",  pure_purify_printf_with_call_chain,  METH_VARARGS},
+    {"purify_set_pool_id",             pure_purify_set_pool_id,             METH_VARARGS},
+    {"purify_get_pool_id",             pure_purify_get_pool_id,             METH_VARARGS},
+    {"purify_set_user_data",           pure_purify_set_user_data,           METH_VARARGS},
+    {"purify_get_user_data",           pure_purify_get_user_data,           METH_VARARGS},
+    {"purify_map_pool",                pure_purify_map_pool,                METH_VARARGS},
+    {"purify_map_pool_id",             pure_purify_map_pool_id,             METH_VARARGS},
+    {"purify_new_messages",            pure_purify_new_messages,            METH_VARARGS},
+    {"purify_all_messages",            pure_purify_all_messages,            METH_VARARGS},
+    {"purify_clear_messages",          pure_purify_clear_messages,          METH_VARARGS},
+    {"purify_clear_new_messages",      pure_purify_clear_new_messages,      METH_VARARGS},
+    {"purify_start_batch",             pure_purify_start_batch,             METH_VARARGS},
+    {"purify_start_batch_show_first",  pure_purify_start_batch_show_first,  METH_VARARGS},
+    {"purify_stop_batch",              pure_purify_stop_batch,              METH_VARARGS},
+    {"purify_name_thread",             pure_purify_name_thread,             METH_VARARGS},
+    {"purify_watch",                   pure_purify_watch,                   METH_VARARGS},
+    {"purify_watch_1",                 pure_purify_watch_1,                 METH_VARARGS},
+    {"purify_watch_2",                 pure_purify_watch_2,                 METH_VARARGS},
+    {"purify_watch_4",                 pure_purify_watch_4,                 METH_VARARGS},
+    {"purify_watch_8",                 pure_purify_watch_8,                 METH_VARARGS},
+    {"purify_watch_w_1",               pure_purify_watch_w_1,               METH_VARARGS},
+    {"purify_watch_w_2",               pure_purify_watch_w_2,               METH_VARARGS},
+    {"purify_watch_w_4",               pure_purify_watch_w_4,               METH_VARARGS},
+    {"purify_watch_w_8",               pure_purify_watch_w_8,               METH_VARARGS},
+    {"purify_watch_r_1",               pure_purify_watch_r_1,               METH_VARARGS},
+    {"purify_watch_r_2",               pure_purify_watch_r_2,               METH_VARARGS},
+    {"purify_watch_r_4",               pure_purify_watch_r_4,               METH_VARARGS},
+    {"purify_watch_r_8",               pure_purify_watch_r_8,               METH_VARARGS},
+    {"purify_watch_rw_1",              pure_purify_watch_rw_1,              METH_VARARGS},
+    {"purify_watch_rw_2",              pure_purify_watch_rw_2,              METH_VARARGS},
+    {"purify_watch_rw_4",              pure_purify_watch_rw_4,              METH_VARARGS},
+    {"purify_watch_rw_8",              pure_purify_watch_rw_8,              METH_VARARGS},
+    {"purify_watch_n",                 pure_purify_watch_n,                 METH_VARARGS},
+    {"purify_watch_info",              pure_purify_watch_info,              METH_VARARGS},
+    {"purify_watch_remove",            pure_purify_watch_remove,            METH_VARARGS},
+    {"purify_watch_remove_all",        pure_purify_watch_remove_all,        METH_VARARGS},
+    {"purify_describe",                pure_purify_describe,                METH_VARARGS},
+    {"purify_what_colors",             pure_purify_what_colors,             METH_VARARGS},
+    {"purify_is_running",              pure_purify_is_running,              METH_VARARGS},
+    {"purify_assert_is_readable",      pure_purify_assert_is_readable,      METH_VARARGS},
+    {"purify_assert_is_writable",      pure_purify_assert_is_writable,      METH_VARARGS},
+#if HAS_PURIFY_EXIT
+    /* I wish I could include this, but I can't.  See the notes at the
+     * top of the file.
+     */
+    {"purify_exit",                    pure_purify_exit,                    METH_VARARGS},
+#endif /* HAS_PURIFY_EXIT */
+#endif /* PURIFY_H */
+#ifdef QUANTIFY_H
+    {"quantify_is_running",            pure_quantify_is_running,            METH_VARARGS},
+    {"quantify_help",                  pure_quantify_help,                  METH_VARARGS},
+    {"quantify_print_recording_state", pure_quantify_print_recording_state, METH_VARARGS},
+    {"quantify_start_recording_data",  pure_quantify_start_recording_data,  METH_VARARGS},
+    {"quantify_stop_recording_data",   pure_quantify_stop_recording_data,   METH_VARARGS},
+    {"quantify_is_recording_data",     pure_quantify_is_recording_data,  METH_VARARGS},
+    {"quantify_start_recording_system_calls",
+     pure_quantify_start_recording_system_calls, METH_VARARGS},
+    {"quantify_stop_recording_system_calls",
+     pure_quantify_stop_recording_system_calls, METH_VARARGS},
+    {"quantify_is_recording_system_calls",
+     pure_quantify_is_recording_system_calls, METH_VARARGS},
+    {"quantify_start_recording_system_call",
+     pure_quantify_start_recording_system_call, METH_VARARGS},
+    {"quantify_stop_recording_system_call",
+     pure_quantify_stop_recording_system_call, METH_VARARGS},
+    {"quantify_is_recording_system_call",
+     pure_quantify_is_recording_system_call, METH_VARARGS},
+    {"quantify_start_recording_dynamic_library_data",
+     pure_quantify_start_recording_dynamic_library_data, METH_VARARGS},
+    {"quantify_stop_recording_dynamic_library_data",
+     pure_quantify_stop_recording_dynamic_library_data, METH_VARARGS},
+    {"quantify_is_recording_dynamic_library_data",
+     pure_quantify_is_recording_dynamic_library_data, METH_VARARGS},
+    {"quantify_start_recording_register_window_traps",
+     pure_quantify_start_recording_register_window_traps, METH_VARARGS},
+    {"quantify_stop_recording_register_window_traps",
+     pure_quantify_stop_recording_register_window_traps, METH_VARARGS},
+    {"quantify_is_recording_register_window_traps",
+     pure_quantify_is_recording_register_window_traps, METH_VARARGS},
+    {"quantify_disable_recording_data",
+     pure_quantify_disable_recording_data, METH_VARARGS},
+    {"quantify_clear_data",        pure_quantify_clear_data,        METH_VARARGS},
+    {"quantify_save_data",         pure_quantify_save_data,         METH_VARARGS},
+    {"quantify_save_data_to_file", pure_quantify_save_data_to_file, METH_VARARGS},
+    {"quantify_add_annotation",    pure_quantify_add_annotation,    METH_VARARGS},
+#endif /* QUANTIFY_H */
+    {NULL,  NULL}			     /* sentinel */
+};
+
+
+
+static void
+ins(d, name, val)
+	PyObject *d;
+	char* name;
+	long val;
+{
+	PyObject *v = PyInt_FromLong(val);
+	if (v) {
+		(void)PyDict_SetItemString(d, name, v);
+		Py_DECREF(v);
+	}
+}
+
+
+void
+initpure()
+{
+	PyObject *m, *d;
+
+	m = Py_InitModule("pure", pure_methods);
+	if (m == NULL)
+    		return;
+	d = PyModule_GetDict(m);
+
+        /* this is bogus because we should be able to find this information
+         * out from the header files.  Pure's current versions don't
+         * include this information!
+         */
+#ifdef PURE_PURIFY_VERSION
+	ins(d, "PURIFY_VERSION", PURE_PURIFY_VERSION);
+#else
+	PyDict_SetItemString(d, "PURIFY_VERSION", Py_None);
+#endif
+
+        /* these aren't terribly useful because purify_exit() isn't
+         * exported correctly.  See the note at the top of the file.
+         */
+#ifdef PURIFY_EXIT_ERRORS
+	ins(d, "PURIFY_EXIT_ERRORS", PURIFY_EXIT_ERRORS);
+#endif
+#ifdef PURIFY_EXIT_LEAKS
+	ins(d, "PURIFY_EXIT_LEAKS",  PURIFY_EXIT_LEAKS);
+#endif
+#ifdef PURIFY_EXIT_PLEAKS
+	ins(d, "PURIFY_EXIT_PLEAKS", PURIFY_EXIT_PLEAKS);
+#endif
+
+
+#ifdef PURE_QUANTIFY_VERSION
+	ins(d, "QUANTIFY_VERSION", PURE_QUANTIFY_VERSION);
+#else
+	PyDict_SetItemString(d, "QUANTIFY_VERSION", Py_None);
+#endif
+}

Added: vendor/Python/current/Modules/pwdmodule.c
===================================================================
--- vendor/Python/current/Modules/pwdmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/pwdmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,198 @@
+
+/* UNIX password file access module */
+
+#include "Python.h"
+#include "structseq.h"
+
+#include <sys/types.h>
+#include <pwd.h>
+
+static PyStructSequence_Field struct_pwd_type_fields[] = {
+	{"pw_name", "user name"},
+	{"pw_passwd", "password"},
+	{"pw_uid", "user id"},
+	{"pw_gid", "group id"}, 
+	{"pw_gecos", "real name"}, 
+	{"pw_dir", "home directory"},
+	{"pw_shell", "shell program"},
+	{0}
+};
+
+PyDoc_STRVAR(struct_passwd__doc__,
+"pwd.struct_passwd: Results from getpw*() routines.\n\n\
+This object may be accessed either as a tuple of\n\
+  (pw_name,pw_passwd,pw_uid,pw_gid,pw_gecos,pw_dir,pw_shell)\n\
+or via the object attributes as named in the above tuple.");
+
+static PyStructSequence_Desc struct_pwd_type_desc = {
+	"pwd.struct_passwd",
+	struct_passwd__doc__,
+	struct_pwd_type_fields,
+	7,
+};
+
+PyDoc_STRVAR(pwd__doc__,
+"This module provides access to the Unix password database.\n\
+It is available on all Unix versions.\n\
+\n\
+Password database entries are reported as 7-tuples containing the following\n\
+items from the password database (see `<pwd.h>'), in order:\n\
+pw_name, pw_passwd, pw_uid, pw_gid, pw_gecos, pw_dir, pw_shell.\n\
+The uid and gid items are integers, all others are strings. An\n\
+exception is raised if the entry asked for cannot be found.");
+
+      
+static int initialized;
+static PyTypeObject StructPwdType;
+
+static void
+sets(PyObject *v, int i, char* val)
+{
+  if (val)
+	  PyStructSequence_SET_ITEM(v, i, PyString_FromString(val));
+  else {
+	  PyStructSequence_SET_ITEM(v, i, Py_None);
+	  Py_INCREF(Py_None);
+  }
+}
+
+static PyObject *
+mkpwent(struct passwd *p)
+{
+	int setIndex = 0;
+	PyObject *v = PyStructSequence_New(&StructPwdType);
+	if (v == NULL)
+		return NULL;
+
+#define SETI(i,val) PyStructSequence_SET_ITEM(v, i, PyInt_FromLong((long) val))
+#define SETS(i,val) sets(v, i, val)
+
+	SETS(setIndex++, p->pw_name);
+#ifdef __VMS
+	SETS(setIndex++, "");
+#else
+	SETS(setIndex++, p->pw_passwd);
+#endif
+	SETI(setIndex++, p->pw_uid);
+	SETI(setIndex++, p->pw_gid);
+#ifdef __VMS
+	SETS(setIndex++, "");
+#else
+	SETS(setIndex++, p->pw_gecos);
+#endif
+	SETS(setIndex++, p->pw_dir);
+	SETS(setIndex++, p->pw_shell);
+
+#undef SETS
+#undef SETI
+
+	if (PyErr_Occurred()) {
+		Py_XDECREF(v);
+		return NULL;
+	}
+
+	return v;
+}
+
+PyDoc_STRVAR(pwd_getpwuid__doc__,
+"getpwuid(uid) -> (pw_name,pw_passwd,pw_uid,\n\
+                  pw_gid,pw_gecos,pw_dir,pw_shell)\n\
+Return the password database entry for the given numeric user ID.\n\
+See pwd.__doc__ for more on password database entries.");
+
+static PyObject *
+pwd_getpwuid(PyObject *self, PyObject *args)
+{
+	unsigned int uid;
+	struct passwd *p;
+	if (!PyArg_ParseTuple(args, "I:getpwuid", &uid))
+		return NULL;
+	if ((p = getpwuid(uid)) == NULL) {
+		PyErr_Format(PyExc_KeyError,
+			     "getpwuid(): uid not found: %d", uid);
+		return NULL;
+	}
+	return mkpwent(p);
+}
+
+PyDoc_STRVAR(pwd_getpwnam__doc__,
+"getpwnam(name) -> (pw_name,pw_passwd,pw_uid,\n\
+                    pw_gid,pw_gecos,pw_dir,pw_shell)\n\
+Return the password database entry for the given user name.\n\
+See pwd.__doc__ for more on password database entries.");
+
+static PyObject *
+pwd_getpwnam(PyObject *self, PyObject *args)
+{
+	char *name;
+	struct passwd *p;
+	if (!PyArg_ParseTuple(args, "s:getpwnam", &name))
+		return NULL;
+	if ((p = getpwnam(name)) == NULL) {
+		PyErr_Format(PyExc_KeyError,
+			     "getpwnam(): name not found: %s", name);
+		return NULL;
+	}
+	return mkpwent(p);
+}
+
+#ifdef HAVE_GETPWENT
+PyDoc_STRVAR(pwd_getpwall__doc__,
+"getpwall() -> list_of_entries\n\
+Return a list of all available password database entries, \
+in arbitrary order.\n\
+See pwd.__doc__ for more on password database entries.");
+
+static PyObject *
+pwd_getpwall(PyObject *self)
+{
+	PyObject *d;
+	struct passwd *p;
+	if ((d = PyList_New(0)) == NULL)
+		return NULL;
+#if defined(PYOS_OS2) && defined(PYCC_GCC)
+	if ((p = getpwuid(0)) != NULL) {
+#else
+	setpwent();
+	while ((p = getpwent()) != NULL) {
+#endif
+		PyObject *v = mkpwent(p);
+		if (v == NULL || PyList_Append(d, v) != 0) {
+			Py_XDECREF(v);
+			Py_DECREF(d);
+			return NULL;
+		}
+		Py_DECREF(v);
+	}
+	endpwent();
+	return d;
+}
+#endif
+
+static PyMethodDef pwd_methods[] = {
+	{"getpwuid",	pwd_getpwuid, METH_VARARGS, pwd_getpwuid__doc__},
+	{"getpwnam",	pwd_getpwnam, METH_VARARGS, pwd_getpwnam__doc__},
+#ifdef HAVE_GETPWENT
+	{"getpwall",	(PyCFunction)pwd_getpwall,
+		METH_NOARGS,  pwd_getpwall__doc__},
+#endif
+	{NULL,		NULL}		/* sentinel */
+};
+
+PyMODINIT_FUNC
+initpwd(void)
+{
+	PyObject *m;
+	m = Py_InitModule3("pwd", pwd_methods, pwd__doc__);
+	if (m == NULL)
+    		return;
+
+	if (!initialized)
+		PyStructSequence_InitType(&StructPwdType, 
+					  &struct_pwd_type_desc);
+	Py_INCREF((PyObject *) &StructPwdType);
+	PyModule_AddObject(m, "struct_passwd", (PyObject *) &StructPwdType);
+	/* And for b/w compatibility (this was defined by mistake): */
+	PyModule_AddObject(m, "struct_pwent", (PyObject *) &StructPwdType);
+	initialized = 1;
+}

Added: vendor/Python/current/Modules/pyexpat.c
===================================================================
--- vendor/Python/current/Modules/pyexpat.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/pyexpat.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2149 @@
+#include "Python.h"
+#include <ctype.h>
+
+#include "frameobject.h"
+#include "expat.h"
+
+#include "pyexpat.h"
+
+#define XML_COMBINED_VERSION (10000*XML_MAJOR_VERSION+100*XML_MINOR_VERSION+XML_MICRO_VERSION)
+
+#ifndef PyDoc_STRVAR
+
+/*
+ * fdrake says:
+ * Don't change the PyDoc_STR macro definition to (str), because
+ * '''the parentheses cause compile failures
+ * ("non-constant static initializer" or something like that)
+ * on some platforms (Irix?)'''
+ */
+#define PyDoc_STR(str)         str
+#define PyDoc_VAR(name)        static char name[]
+#define PyDoc_STRVAR(name,str) PyDoc_VAR(name) = PyDoc_STR(str)
+#endif
+
+#if (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 2)
+/* In Python 2.0 and  2.1, disabling Unicode was not possible. */
+#define Py_USING_UNICODE
+#else
+#define FIX_TRACE
+#endif
+
+enum HandlerTypes {
+    StartElement,
+    EndElement,
+    ProcessingInstruction,
+    CharacterData,
+    UnparsedEntityDecl,
+    NotationDecl,
+    StartNamespaceDecl,
+    EndNamespaceDecl,
+    Comment,
+    StartCdataSection,
+    EndCdataSection,
+    Default,
+    DefaultHandlerExpand,
+    NotStandalone,
+    ExternalEntityRef,
+    StartDoctypeDecl,
+    EndDoctypeDecl,
+    EntityDecl,
+    XmlDecl,
+    ElementDecl,
+    AttlistDecl,
+#if XML_COMBINED_VERSION >= 19504
+    SkippedEntity,
+#endif
+    _DummyDecl
+};
+
+static PyObject *ErrorObject;
+
+/* ----------------------------------------------------- */
+
+/* Declarations for objects of type xmlparser */
+
+typedef struct {
+    PyObject_HEAD
+
+    XML_Parser itself;
+    int returns_unicode;        /* True if Unicode strings are returned;
+                                   if false, UTF-8 strings are returned */
+    int ordered_attributes;     /* Return attributes as a list. */
+    int specified_attributes;   /* Report only specified attributes. */
+    int in_callback;            /* Is a callback active? */
+    int ns_prefixes;            /* Namespace-triplets mode? */
+    XML_Char *buffer;           /* Buffer used when accumulating characters */
+                                /* NULL if not enabled */
+    int buffer_size;            /* Size of buffer, in XML_Char units */
+    int buffer_used;            /* Buffer units in use */
+    PyObject *intern;           /* Dictionary to intern strings */
+    PyObject **handlers;
+} xmlparseobject;
+
+#define CHARACTER_DATA_BUFFER_SIZE 8192
+
+static PyTypeObject Xmlparsetype;
+
+typedef void (*xmlhandlersetter)(XML_Parser self, void *meth);
+typedef void* xmlhandler;
+
+struct HandlerInfo {
+    const char *name;
+    xmlhandlersetter setter;
+    xmlhandler handler;
+    PyCodeObject *tb_code;
+    PyObject *nameobj;
+};
+
+static struct HandlerInfo handler_info[64];
+
+/* Set an integer attribute on the error object; return true on success,
+ * false on an exception.
+ */
+static int
+set_error_attr(PyObject *err, char *name, int value)
+{
+    PyObject *v = PyInt_FromLong(value);
+
+    if (v == NULL || PyObject_SetAttrString(err, name, v) == -1) {
+        Py_XDECREF(v);
+        return 0;
+    }
+    Py_DECREF(v);
+    return 1;
+}
+
+/* Build and set an Expat exception, including positioning
+ * information.  Always returns NULL.
+ */
+static PyObject *
+set_error(xmlparseobject *self, enum XML_Error code)
+{
+    PyObject *err;
+    char buffer[256];
+    XML_Parser parser = self->itself;
+    int lineno = XML_GetErrorLineNumber(parser);
+    int column = XML_GetErrorColumnNumber(parser);
+
+    /* There is no risk of overflowing this buffer, since
+       even for 64-bit integers, there is sufficient space. */
+    sprintf(buffer, "%.200s: line %i, column %i",
+            XML_ErrorString(code), lineno, column);
+    err = PyObject_CallFunction(ErrorObject, "s", buffer);
+    if (  err != NULL
+          && set_error_attr(err, "code", code)
+          && set_error_attr(err, "offset", column)
+          && set_error_attr(err, "lineno", lineno)) {
+        PyErr_SetObject(ErrorObject, err);
+    }
+    Py_XDECREF(err);
+    return NULL;
+}
+
+static int
+have_handler(xmlparseobject *self, int type)
+{
+    PyObject *handler = self->handlers[type];
+    return handler != NULL;
+}
+
+static PyObject *
+get_handler_name(struct HandlerInfo *hinfo)
+{
+    PyObject *name = hinfo->nameobj;
+    if (name == NULL) {
+        name = PyString_FromString(hinfo->name);
+        hinfo->nameobj = name;
+    }
+    Py_XINCREF(name);
+    return name;
+}
+
+
+#ifdef Py_USING_UNICODE
+/* Convert a string of XML_Chars into a Unicode string.
+   Returns None if str is a null pointer. */
+
+static PyObject *
+conv_string_to_unicode(const XML_Char *str)
+{
+    /* XXX currently this code assumes that XML_Char is 8-bit,
+       and hence in UTF-8.  */
+    /* UTF-8 from Expat, Unicode desired */
+    if (str == NULL) {
+        Py_INCREF(Py_None);
+        return Py_None;
+    }
+    return PyUnicode_DecodeUTF8(str, strlen(str), "strict");
+}
+
+static PyObject *
+conv_string_len_to_unicode(const XML_Char *str, int len)
+{
+    /* XXX currently this code assumes that XML_Char is 8-bit,
+       and hence in UTF-8.  */
+    /* UTF-8 from Expat, Unicode desired */
+    if (str == NULL) {
+        Py_INCREF(Py_None);
+        return Py_None;
+    }
+    return PyUnicode_DecodeUTF8((const char *)str, len, "strict");
+}
+#endif
+
+/* Convert a string of XML_Chars into an 8-bit Python string.
+   Returns None if str is a null pointer. */
+
+static PyObject *
+conv_string_to_utf8(const XML_Char *str)
+{
+    /* XXX currently this code assumes that XML_Char is 8-bit,
+       and hence in UTF-8.  */
+    /* UTF-8 from Expat, UTF-8 desired */
+    if (str == NULL) {
+        Py_INCREF(Py_None);
+        return Py_None;
+    }
+    return PyString_FromString(str);
+}
+
+static PyObject *
+conv_string_len_to_utf8(const XML_Char *str, int len)
+{
+    /* XXX currently this code assumes that XML_Char is 8-bit,
+       and hence in UTF-8.  */
+    /* UTF-8 from Expat, UTF-8 desired */
+    if (str == NULL) {
+        Py_INCREF(Py_None);
+        return Py_None;
+    }
+    return PyString_FromStringAndSize((const char *)str, len);
+}
+
+/* Callback routines */
+
+static void clear_handlers(xmlparseobject *self, int initial);
+
+/* This handler is used when an error has been detected, in the hope
+   that actual parsing can be terminated early.  This will only help
+   if an external entity reference is encountered. */
+static int
+error_external_entity_ref_handler(XML_Parser parser,
+                                  const XML_Char *context,
+                                  const XML_Char *base,
+                                  const XML_Char *systemId,
+                                  const XML_Char *publicId)
+{
+    return 0;
+}
+
+/* Dummy character data handler used when an error (exception) has
+   been detected, and the actual parsing can be terminated early.
+   This is needed since character data handler can't be safely removed
+   from within the character data handler, but can be replaced.  It is
+   used only from the character data handler trampoline, and must be
+   used right after `flag_error()` is called. */
+static void
+noop_character_data_handler(void *userData, const XML_Char *data, int len) 
+{
+    /* Do nothing. */
+}
+
+static void
+flag_error(xmlparseobject *self)
+{
+    clear_handlers(self, 0);
+    XML_SetExternalEntityRefHandler(self->itself,
+                                    error_external_entity_ref_handler);
+}
+
+static PyCodeObject*
+getcode(enum HandlerTypes slot, char* func_name, int lineno)
+{
+    PyObject *code = NULL;
+    PyObject *name = NULL;
+    PyObject *nulltuple = NULL;
+    PyObject *filename = NULL;
+
+    if (handler_info[slot].tb_code == NULL) {
+        code = PyString_FromString("");
+        if (code == NULL)
+            goto failed;
+        name = PyString_FromString(func_name);
+        if (name == NULL)
+            goto failed;
+        nulltuple = PyTuple_New(0);
+        if (nulltuple == NULL)
+            goto failed;
+        filename = PyString_FromString(__FILE__);
+        handler_info[slot].tb_code =
+            PyCode_New(0,		/* argcount */
+                       0,		/* nlocals */
+                       0,		/* stacksize */
+                       0,		/* flags */
+                       code,		/* code */
+                       nulltuple,	/* consts */
+                       nulltuple,	/* names */
+                       nulltuple,	/* varnames */
+#if PYTHON_API_VERSION >= 1010
+                       nulltuple,	/* freevars */
+                       nulltuple,	/* cellvars */
+#endif
+                       filename,	/* filename */
+                       name,		/* name */
+                       lineno,		/* firstlineno */
+                       code		/* lnotab */
+                       );
+        if (handler_info[slot].tb_code == NULL)
+            goto failed;
+        Py_DECREF(code);
+        Py_DECREF(nulltuple);
+        Py_DECREF(filename);
+        Py_DECREF(name);
+    }
+    return handler_info[slot].tb_code;
+ failed:
+    Py_XDECREF(code);
+    Py_XDECREF(name);
+    return NULL;
+}
+
+#ifdef FIX_TRACE
+static int
+trace_frame(PyThreadState *tstate, PyFrameObject *f, int code, PyObject *val)
+{
+    int result = 0;
+    if (!tstate->use_tracing || tstate->tracing)
+	return 0;
+    if (tstate->c_profilefunc != NULL) {
+	tstate->tracing++;
+	result = tstate->c_profilefunc(tstate->c_profileobj,
+				       f, code , val);
+	tstate->use_tracing = ((tstate->c_tracefunc != NULL)
+			       || (tstate->c_profilefunc != NULL));
+	tstate->tracing--;
+	if (result)
+	    return result;
+    }
+    if (tstate->c_tracefunc != NULL) {
+	tstate->tracing++;
+	result = tstate->c_tracefunc(tstate->c_traceobj,
+				     f, code , val);
+	tstate->use_tracing = ((tstate->c_tracefunc != NULL)
+			       || (tstate->c_profilefunc != NULL));
+	tstate->tracing--;
+    }	
+    return result;
+}
+
+static int
+trace_frame_exc(PyThreadState *tstate, PyFrameObject *f)
+{
+    PyObject *type, *value, *traceback, *arg;
+    int err;
+
+    if (tstate->c_tracefunc == NULL)
+	return 0;
+
+    PyErr_Fetch(&type, &value, &traceback);
+    if (value == NULL) {
+	value = Py_None;
+	Py_INCREF(value);
+    }
+#if PY_VERSION_HEX < 0x02040000
+    arg = Py_BuildValue("(OOO)", type, value, traceback);
+#else
+    arg = PyTuple_Pack(3, type, value, traceback);
+#endif
+    if (arg == NULL) {
+	PyErr_Restore(type, value, traceback);
+	return 0;
+    }
+    err = trace_frame(tstate, f, PyTrace_EXCEPTION, arg);
+    Py_DECREF(arg);
+    if (err == 0)
+	PyErr_Restore(type, value, traceback);
+    else {
+	Py_XDECREF(type);
+	Py_XDECREF(value);
+	Py_XDECREF(traceback);
+    }
+    return err;
+}
+#endif
+
+static PyObject*
+call_with_frame(PyCodeObject *c, PyObject* func, PyObject* args,
+                xmlparseobject *self)
+{
+    PyThreadState *tstate = PyThreadState_GET();
+    PyFrameObject *f;
+    PyObject *res;
+
+    if (c == NULL)
+        return NULL;
+    
+    f = PyFrame_New(tstate, c, PyEval_GetGlobals(), NULL);
+    if (f == NULL)
+        return NULL;
+    tstate->frame = f;
+#ifdef FIX_TRACE
+    if (trace_frame(tstate, f, PyTrace_CALL, Py_None) < 0) {
+	return NULL;
+    }
+#endif
+    res = PyEval_CallObject(func, args);
+    if (res == NULL) {
+	if (tstate->curexc_traceback == NULL)
+	    PyTraceBack_Here(f);
+        XML_StopParser(self->itself, XML_FALSE);
+#ifdef FIX_TRACE
+	if (trace_frame_exc(tstate, f) < 0) {
+	    return NULL;
+	}
+    }
+    else {
+	if (trace_frame(tstate, f, PyTrace_RETURN, res) < 0) {
+	    Py_XDECREF(res);
+	    res = NULL;
+	}
+    }
+#else
+    }
+#endif
+    tstate->frame = f->f_back;
+    Py_DECREF(f);
+    return res;
+}
+
+#ifndef Py_USING_UNICODE
+#define STRING_CONV_FUNC conv_string_to_utf8
+#else
+/* Python 2.0 and later versions, when built with Unicode support */
+#define STRING_CONV_FUNC (self->returns_unicode \
+                          ? conv_string_to_unicode : conv_string_to_utf8)
+#endif
+
+static PyObject*
+string_intern(xmlparseobject *self, const char* str)
+{
+    PyObject *result = STRING_CONV_FUNC(str);
+    PyObject *value;
+    /* result can be NULL if the unicode conversion failed. */
+    if (!result)
+	return result;
+    if (!self->intern)
+	return result;
+    value = PyDict_GetItem(self->intern, result);
+    if (!value) {
+	if (PyDict_SetItem(self->intern, result, result) == 0)
+            return result;
+        else
+            return NULL;
+    }
+    Py_INCREF(value);
+    Py_DECREF(result);
+    return value;
+}
+
+/* Return 0 on success, -1 on exception.
+ * flag_error() will be called before return if needed.
+ */
+static int
+call_character_handler(xmlparseobject *self, const XML_Char *buffer, int len)
+{
+    PyObject *args;
+    PyObject *temp;
+
+    args = PyTuple_New(1);
+    if (args == NULL)
+        return -1;
+#ifdef Py_USING_UNICODE
+    temp = (self->returns_unicode 
+            ? conv_string_len_to_unicode(buffer, len) 
+            : conv_string_len_to_utf8(buffer, len));
+#else
+    temp = conv_string_len_to_utf8(buffer, len);
+#endif
+    if (temp == NULL) {
+        Py_DECREF(args);
+        flag_error(self);
+        XML_SetCharacterDataHandler(self->itself,
+                                    noop_character_data_handler);
+        return -1;
+    }
+    PyTuple_SET_ITEM(args, 0, temp);
+    /* temp is now a borrowed reference; consider it unused. */
+    self->in_callback = 1;
+    temp = call_with_frame(getcode(CharacterData, "CharacterData", __LINE__),
+                           self->handlers[CharacterData], args, self);
+    /* temp is an owned reference again, or NULL */
+    self->in_callback = 0;
+    Py_DECREF(args);
+    if (temp == NULL) {
+        flag_error(self);
+        XML_SetCharacterDataHandler(self->itself,
+                                    noop_character_data_handler);
+        return -1;
+    }
+    Py_DECREF(temp);
+    return 0;
+}
+
+static int
+flush_character_buffer(xmlparseobject *self)
+{
+    int rc;
+    if (self->buffer == NULL || self->buffer_used == 0)
+        return 0;
+    rc = call_character_handler(self, self->buffer, self->buffer_used);
+    self->buffer_used = 0;
+    return rc;
+}
+
+static void
+my_CharacterDataHandler(void *userData, const XML_Char *data, int len) 
+{
+    xmlparseobject *self = (xmlparseobject *) userData;
+    if (self->buffer == NULL)
+        call_character_handler(self, data, len);
+    else {
+        if ((self->buffer_used + len) > self->buffer_size) {
+            if (flush_character_buffer(self) < 0)
+                return;
+            /* handler might have changed; drop the rest on the floor
+             * if there isn't a handler anymore
+             */
+            if (!have_handler(self, CharacterData))
+                return;
+        }
+        if (len > self->buffer_size) {
+            call_character_handler(self, data, len);
+            self->buffer_used = 0;
+        }
+        else {
+            memcpy(self->buffer + self->buffer_used,
+                   data, len * sizeof(XML_Char));
+            self->buffer_used += len;
+        }
+    }
+}
+
+static void
+my_StartElementHandler(void *userData,
+                       const XML_Char *name, const XML_Char *atts[])
+{
+    xmlparseobject *self = (xmlparseobject *)userData;
+
+    if (have_handler(self, StartElement)) {
+        PyObject *container, *rv, *args;
+        int i, max;
+
+        if (flush_character_buffer(self) < 0)
+            return;
+        /* Set max to the number of slots filled in atts[]; max/2 is
+         * the number of attributes we need to process.
+         */
+        if (self->specified_attributes) {
+            max = XML_GetSpecifiedAttributeCount(self->itself);
+        }
+        else {
+            max = 0;
+            while (atts[max] != NULL)
+                max += 2;
+        }
+        /* Build the container. */
+        if (self->ordered_attributes)
+            container = PyList_New(max);
+        else
+            container = PyDict_New();
+        if (container == NULL) {
+            flag_error(self);
+            return;
+        }
+        for (i = 0; i < max; i += 2) {
+            PyObject *n = string_intern(self, (XML_Char *) atts[i]);
+            PyObject *v;
+            if (n == NULL) {
+                flag_error(self);
+                Py_DECREF(container);
+                return;
+            }
+            v = STRING_CONV_FUNC((XML_Char *) atts[i+1]);
+            if (v == NULL) {
+                flag_error(self);
+                Py_DECREF(container);
+                Py_DECREF(n);
+                return;
+            }
+            if (self->ordered_attributes) {
+                PyList_SET_ITEM(container, i, n);
+                PyList_SET_ITEM(container, i+1, v);
+            }
+            else if (PyDict_SetItem(container, n, v)) {
+                flag_error(self);
+                Py_DECREF(n);
+                Py_DECREF(v);
+                return;
+            }
+            else {
+                Py_DECREF(n);
+                Py_DECREF(v);
+            }
+        }
+        args = string_intern(self, name);
+        if (args != NULL)
+            args = Py_BuildValue("(NN)", args, container);
+        if (args == NULL) {
+            Py_DECREF(container);
+            return;
+        }
+        /* Container is now a borrowed reference; ignore it. */
+        self->in_callback = 1;
+        rv = call_with_frame(getcode(StartElement, "StartElement", __LINE__),
+                             self->handlers[StartElement], args, self);
+        self->in_callback = 0;
+        Py_DECREF(args);
+        if (rv == NULL) {
+            flag_error(self);
+            return;
+        }
+        Py_DECREF(rv);
+    }
+}
+
+#define RC_HANDLER(RC, NAME, PARAMS, INIT, PARAM_FORMAT, CONVERSION, \
+                RETURN, GETUSERDATA) \
+static RC \
+my_##NAME##Handler PARAMS {\
+    xmlparseobject *self = GETUSERDATA ; \
+    PyObject *args = NULL; \
+    PyObject *rv = NULL; \
+    INIT \
+\
+    if (have_handler(self, NAME)) { \
+        if (flush_character_buffer(self) < 0) \
+            return RETURN; \
+        args = Py_BuildValue PARAM_FORMAT ;\
+        if (!args) { flag_error(self); return RETURN;} \
+        self->in_callback = 1; \
+        rv = call_with_frame(getcode(NAME,#NAME,__LINE__), \
+                             self->handlers[NAME], args, self); \
+        self->in_callback = 0; \
+        Py_DECREF(args); \
+        if (rv == NULL) { \
+            flag_error(self); \
+            return RETURN; \
+        } \
+        CONVERSION \
+        Py_DECREF(rv); \
+    } \
+    return RETURN; \
+}
+
+#define VOID_HANDLER(NAME, PARAMS, PARAM_FORMAT) \
+	RC_HANDLER(void, NAME, PARAMS, ;, PARAM_FORMAT, ;, ;,\
+	(xmlparseobject *)userData)
+
+#define INT_HANDLER(NAME, PARAMS, PARAM_FORMAT)\
+	RC_HANDLER(int, NAME, PARAMS, int rc=0;, PARAM_FORMAT, \
+			rc = PyInt_AsLong(rv);, rc, \
+	(xmlparseobject *)userData)
+
+VOID_HANDLER(EndElement,
+             (void *userData, const XML_Char *name),
+             ("(N)", string_intern(self, name)))
+
+VOID_HANDLER(ProcessingInstruction,
+             (void *userData,
+              const XML_Char *target,
+              const XML_Char *data),
+             ("(NO&)", string_intern(self, target), STRING_CONV_FUNC,data))
+
+VOID_HANDLER(UnparsedEntityDecl,
+             (void *userData,
+              const XML_Char *entityName,
+              const XML_Char *base,
+              const XML_Char *systemId,
+              const XML_Char *publicId,
+              const XML_Char *notationName),
+             ("(NNNNN)",
+              string_intern(self, entityName), string_intern(self, base),
+              string_intern(self, systemId), string_intern(self, publicId),
+              string_intern(self, notationName)))
+
+#ifndef Py_USING_UNICODE
+VOID_HANDLER(EntityDecl,
+             (void *userData,
+              const XML_Char *entityName,
+              int is_parameter_entity,
+              const XML_Char *value,
+              int value_length,
+              const XML_Char *base,
+              const XML_Char *systemId,
+              const XML_Char *publicId,
+              const XML_Char *notationName),
+             ("NiNNNNN",
+              string_intern(self, entityName), is_parameter_entity,
+              conv_string_len_to_utf8(value, value_length),
+              string_intern(self, base), string_intern(self, systemId),
+              string_intern(self, publicId),
+              string_intern(self, notationName)))
+#else
+VOID_HANDLER(EntityDecl,
+             (void *userData,
+              const XML_Char *entityName,
+              int is_parameter_entity,
+              const XML_Char *value,
+              int value_length,
+              const XML_Char *base,
+              const XML_Char *systemId,
+              const XML_Char *publicId,
+              const XML_Char *notationName),
+             ("NiNNNNN",
+              string_intern(self, entityName), is_parameter_entity,
+              (self->returns_unicode
+               ? conv_string_len_to_unicode(value, value_length)
+               : conv_string_len_to_utf8(value, value_length)),
+              string_intern(self, base), string_intern(self, systemId),
+              string_intern(self, publicId),
+              string_intern(self, notationName)))
+#endif
+
+VOID_HANDLER(XmlDecl,
+             (void *userData,
+              const XML_Char *version,
+              const XML_Char *encoding,
+              int standalone),
+             ("(O&O&i)",
+              STRING_CONV_FUNC,version, STRING_CONV_FUNC,encoding,
+              standalone))
+
+static PyObject *
+conv_content_model(XML_Content * const model,
+                   PyObject *(*conv_string)(const XML_Char *))
+{
+    PyObject *result = NULL;
+    PyObject *children = PyTuple_New(model->numchildren);
+    int i;
+
+    if (children != NULL) {
+        assert(model->numchildren < INT_MAX);
+        for (i = 0; i < (int)model->numchildren; ++i) {
+            PyObject *child = conv_content_model(&model->children[i],
+                                                 conv_string);
+            if (child == NULL) {
+                Py_XDECREF(children);
+                return NULL;
+            }
+            PyTuple_SET_ITEM(children, i, child);
+        }
+        result = Py_BuildValue("(iiO&N)",
+                               model->type, model->quant,
+                               conv_string,model->name, children);
+    }
+    return result;
+}
+
+static void
+my_ElementDeclHandler(void *userData,
+                      const XML_Char *name,
+                      XML_Content *model)
+{
+    xmlparseobject *self = (xmlparseobject *)userData;
+    PyObject *args = NULL;
+
+    if (have_handler(self, ElementDecl)) {
+        PyObject *rv = NULL;
+        PyObject *modelobj, *nameobj;
+
+        if (flush_character_buffer(self) < 0)
+            goto finally;
+#ifdef Py_USING_UNICODE
+        modelobj = conv_content_model(model,
+                                      (self->returns_unicode
+                                       ? conv_string_to_unicode
+                                       : conv_string_to_utf8));
+#else
+        modelobj = conv_content_model(model, conv_string_to_utf8);
+#endif
+        if (modelobj == NULL) {
+            flag_error(self);
+            goto finally;
+        }
+        nameobj = string_intern(self, name);
+        if (nameobj == NULL) {
+            Py_DECREF(modelobj);
+            flag_error(self);
+            goto finally;
+        }
+        args = Py_BuildValue("NN", nameobj, modelobj);
+        if (args == NULL) {
+            Py_DECREF(modelobj);
+            flag_error(self);
+            goto finally;
+        }
+        self->in_callback = 1;
+        rv = call_with_frame(getcode(ElementDecl, "ElementDecl", __LINE__),
+                             self->handlers[ElementDecl], args, self);
+        self->in_callback = 0;
+        if (rv == NULL) {
+            flag_error(self);
+            goto finally;
+        }
+        Py_DECREF(rv);
+    }
+ finally:
+    Py_XDECREF(args);
+    XML_FreeContentModel(self->itself, model);
+    return;
+}
+
+VOID_HANDLER(AttlistDecl,
+             (void *userData,
+              const XML_Char *elname,
+              const XML_Char *attname,
+              const XML_Char *att_type,
+              const XML_Char *dflt,
+              int isrequired),
+             ("(NNO&O&i)",
+              string_intern(self, elname), string_intern(self, attname),
+              STRING_CONV_FUNC,att_type, STRING_CONV_FUNC,dflt,
+              isrequired))
+
+#if XML_COMBINED_VERSION >= 19504
+VOID_HANDLER(SkippedEntity,
+             (void *userData,
+              const XML_Char *entityName,
+              int is_parameter_entity),
+             ("Ni",
+              string_intern(self, entityName), is_parameter_entity))
+#endif
+
+VOID_HANDLER(NotationDecl,
+		(void *userData,
+			const XML_Char *notationName,
+			const XML_Char *base,
+			const XML_Char *systemId,
+			const XML_Char *publicId),
+                ("(NNNN)",
+		 string_intern(self, notationName), string_intern(self, base),
+		 string_intern(self, systemId), string_intern(self, publicId)))
+
+VOID_HANDLER(StartNamespaceDecl,
+		(void *userData,
+		      const XML_Char *prefix,
+		      const XML_Char *uri),
+                ("(NN)",
+                 string_intern(self, prefix), string_intern(self, uri)))
+
+VOID_HANDLER(EndNamespaceDecl,
+		(void *userData,
+		    const XML_Char *prefix),
+                ("(N)", string_intern(self, prefix)))
+
+VOID_HANDLER(Comment,
+               (void *userData, const XML_Char *data),
+                ("(O&)", STRING_CONV_FUNC,data))
+
+VOID_HANDLER(StartCdataSection,
+               (void *userData),
+		("()"))
+
+VOID_HANDLER(EndCdataSection,
+               (void *userData),
+		("()"))
+
+#ifndef Py_USING_UNICODE
+VOID_HANDLER(Default,
+	      (void *userData, const XML_Char *s, int len),
+	      ("(N)", conv_string_len_to_utf8(s,len)))
+
+VOID_HANDLER(DefaultHandlerExpand,
+	      (void *userData, const XML_Char *s, int len),
+	      ("(N)", conv_string_len_to_utf8(s,len)))
+#else
+VOID_HANDLER(Default,
+	      (void *userData, const XML_Char *s, int len),
+	      ("(N)", (self->returns_unicode
+		       ? conv_string_len_to_unicode(s,len)
+		       : conv_string_len_to_utf8(s,len))))
+
+VOID_HANDLER(DefaultHandlerExpand,
+	      (void *userData, const XML_Char *s, int len),
+	      ("(N)", (self->returns_unicode
+		       ? conv_string_len_to_unicode(s,len)
+		       : conv_string_len_to_utf8(s,len))))
+#endif
+
+INT_HANDLER(NotStandalone,
+		(void *userData),
+		("()"))
+
+RC_HANDLER(int, ExternalEntityRef,
+		(XML_Parser parser,
+		    const XML_Char *context,
+		    const XML_Char *base,
+		    const XML_Char *systemId,
+		    const XML_Char *publicId),
+		int rc=0;,
+                ("(O&NNN)",
+		 STRING_CONV_FUNC,context, string_intern(self, base),
+		 string_intern(self, systemId), string_intern(self, publicId)),
+		rc = PyInt_AsLong(rv);, rc,
+		XML_GetUserData(parser))
+
+/* XXX UnknownEncodingHandler */
+
+VOID_HANDLER(StartDoctypeDecl,
+             (void *userData, const XML_Char *doctypeName,
+              const XML_Char *sysid, const XML_Char *pubid,
+              int has_internal_subset),
+             ("(NNNi)", string_intern(self, doctypeName),
+              string_intern(self, sysid), string_intern(self, pubid),
+              has_internal_subset))
+
+VOID_HANDLER(EndDoctypeDecl, (void *userData), ("()"))
+
+/* ---------------------------------------------------------------- */
+
+static PyObject *
+get_parse_result(xmlparseobject *self, int rv)
+{
+    if (PyErr_Occurred()) {
+        return NULL;
+    }
+    if (rv == 0) {
+        return set_error(self, XML_GetErrorCode(self->itself));
+    }
+    if (flush_character_buffer(self) < 0) {
+        return NULL;
+    }
+    return PyInt_FromLong(rv);
+}
+
+PyDoc_STRVAR(xmlparse_Parse__doc__,
+"Parse(data[, isfinal])\n\
+Parse XML data.  `isfinal' should be true at end of input.");
+
+static PyObject *
+xmlparse_Parse(xmlparseobject *self, PyObject *args)
+{
+    char *s;
+    int slen;
+    int isFinal = 0;
+
+    if (!PyArg_ParseTuple(args, "s#|i:Parse", &s, &slen, &isFinal))
+        return NULL;
+
+    return get_parse_result(self, XML_Parse(self->itself, s, slen, isFinal));
+}
+
+/* File reading copied from cPickle */
+
+#define BUF_SIZE 2048
+
+static int
+readinst(char *buf, int buf_size, PyObject *meth)
+{
+    PyObject *arg = NULL;
+    PyObject *bytes = NULL;
+    PyObject *str = NULL;
+    int len = -1;
+
+    if ((bytes = PyInt_FromLong(buf_size)) == NULL)
+        goto finally;
+
+    if ((arg = PyTuple_New(1)) == NULL) {
+        Py_DECREF(bytes);
+        goto finally;
+    }
+
+    PyTuple_SET_ITEM(arg, 0, bytes);
+
+#if PY_VERSION_HEX < 0x02020000
+    str = PyObject_CallObject(meth, arg);
+#else
+    str = PyObject_Call(meth, arg, NULL);
+#endif
+    if (str == NULL)
+        goto finally;
+
+    /* XXX what to do if it returns a Unicode string? */
+    if (!PyString_Check(str)) {
+        PyErr_Format(PyExc_TypeError,
+                     "read() did not return a string object (type=%.400s)",
+                     str->ob_type->tp_name);
+        goto finally;
+    }
+    len = PyString_GET_SIZE(str);
+    if (len > buf_size) {
+        PyErr_Format(PyExc_ValueError,
+                     "read() returned too much data: "
+                     "%i bytes requested, %i returned",
+                     buf_size, len);
+        goto finally;
+    }
+    memcpy(buf, PyString_AsString(str), len);
+finally:
+    Py_XDECREF(arg);
+    Py_XDECREF(str);
+    return len;
+}
+
+PyDoc_STRVAR(xmlparse_ParseFile__doc__,
+"ParseFile(file)\n\
+Parse XML data from file-like object.");
+
+static PyObject *
+xmlparse_ParseFile(xmlparseobject *self, PyObject *f)
+{
+    int rv = 1;
+    FILE *fp;
+    PyObject *readmethod = NULL;
+
+    if (PyFile_Check(f)) {
+        fp = PyFile_AsFile(f);
+    }
+    else {
+        fp = NULL;
+        readmethod = PyObject_GetAttrString(f, "read");
+        if (readmethod == NULL) {
+            PyErr_Clear();
+            PyErr_SetString(PyExc_TypeError,
+                            "argument must have 'read' attribute");
+            return NULL;
+        }
+    }
+    for (;;) {
+        int bytes_read;
+        void *buf = XML_GetBuffer(self->itself, BUF_SIZE);
+        if (buf == NULL) {
+            Py_XDECREF(readmethod);
+            return PyErr_NoMemory();
+        }
+
+        if (fp) {
+            bytes_read = fread(buf, sizeof(char), BUF_SIZE, fp);
+            if (bytes_read < 0) {
+                PyErr_SetFromErrno(PyExc_IOError);
+                return NULL;
+            }
+        }
+        else {
+            bytes_read = readinst(buf, BUF_SIZE, readmethod);
+            if (bytes_read < 0) {
+                Py_DECREF(readmethod);
+                return NULL;
+            }
+        }
+        rv = XML_ParseBuffer(self->itself, bytes_read, bytes_read == 0);
+        if (PyErr_Occurred()) {
+            Py_XDECREF(readmethod);
+            return NULL;
+        }
+
+        if (!rv || bytes_read == 0)
+            break;
+    }
+    Py_XDECREF(readmethod);
+    return get_parse_result(self, rv);
+}
+
+PyDoc_STRVAR(xmlparse_SetBase__doc__,
+"SetBase(base_url)\n\
+Set the base URL for the parser.");
+
+static PyObject *
+xmlparse_SetBase(xmlparseobject *self, PyObject *args)
+{
+    char *base;
+
+    if (!PyArg_ParseTuple(args, "s:SetBase", &base))
+        return NULL;
+    if (!XML_SetBase(self->itself, base)) {
+	return PyErr_NoMemory();
+    }
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+PyDoc_STRVAR(xmlparse_GetBase__doc__,
+"GetBase() -> url\n\
+Return base URL string for the parser.");
+
+static PyObject *
+xmlparse_GetBase(xmlparseobject *self, PyObject *unused)
+{
+    return Py_BuildValue("z", XML_GetBase(self->itself));
+}
+
+PyDoc_STRVAR(xmlparse_GetInputContext__doc__,
+"GetInputContext() -> string\n\
+Return the untranslated text of the input that caused the current event.\n\
+If the event was generated by a large amount of text (such as a start tag\n\
+for an element with many attributes), not all of the text may be available.");
+
+static PyObject *
+xmlparse_GetInputContext(xmlparseobject *self, PyObject *unused)
+{
+    if (self->in_callback) {
+        int offset, size;
+        const char *buffer
+            = XML_GetInputContext(self->itself, &offset, &size);
+
+        if (buffer != NULL)
+            return PyString_FromStringAndSize(buffer + offset,
+                                              size - offset);
+        else
+            Py_RETURN_NONE;
+    }
+    else
+        Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(xmlparse_ExternalEntityParserCreate__doc__,
+"ExternalEntityParserCreate(context[, encoding])\n\
+Create a parser for parsing an external entity based on the\n\
+information passed to the ExternalEntityRefHandler.");
+
+static PyObject *
+xmlparse_ExternalEntityParserCreate(xmlparseobject *self, PyObject *args)
+{
+    char *context;
+    char *encoding = NULL;
+    xmlparseobject *new_parser;
+    int i;
+
+    if (!PyArg_ParseTuple(args, "z|s:ExternalEntityParserCreate",
+                          &context, &encoding)) {
+        return NULL;
+    }
+
+#ifndef Py_TPFLAGS_HAVE_GC
+    /* Python versions 2.0 and 2.1 */
+    new_parser = PyObject_New(xmlparseobject, &Xmlparsetype);
+#else
+    /* Python versions 2.2 and later */
+    new_parser = PyObject_GC_New(xmlparseobject, &Xmlparsetype);
+#endif
+
+    if (new_parser == NULL)
+        return NULL;
+    new_parser->buffer_size = self->buffer_size;
+    new_parser->buffer_used = 0;
+    if (self->buffer != NULL) {
+        new_parser->buffer = malloc(new_parser->buffer_size);
+        if (new_parser->buffer == NULL) {
+#ifndef Py_TPFLAGS_HAVE_GC
+            /* Code for versions 2.0 and 2.1 */
+            PyObject_Del(new_parser);
+#else
+            /* Code for versions 2.2 and later. */
+            PyObject_GC_Del(new_parser);
+#endif
+            return PyErr_NoMemory();
+        }
+    }
+    else
+        new_parser->buffer = NULL;
+    new_parser->returns_unicode = self->returns_unicode;
+    new_parser->ordered_attributes = self->ordered_attributes;
+    new_parser->specified_attributes = self->specified_attributes;
+    new_parser->in_callback = 0;
+    new_parser->ns_prefixes = self->ns_prefixes;
+    new_parser->itself = XML_ExternalEntityParserCreate(self->itself, context,
+							encoding);
+    new_parser->handlers = 0;
+    new_parser->intern = self->intern;
+    Py_XINCREF(new_parser->intern);
+#ifdef Py_TPFLAGS_HAVE_GC
+    PyObject_GC_Track(new_parser);
+#else
+    PyObject_GC_Init(new_parser);
+#endif
+
+    if (!new_parser->itself) {
+        Py_DECREF(new_parser);
+        return PyErr_NoMemory();
+    }
+
+    XML_SetUserData(new_parser->itself, (void *)new_parser);
+
+    /* allocate and clear handlers first */
+    for (i = 0; handler_info[i].name != NULL; i++)
+        /* do nothing */;
+
+    new_parser->handlers = malloc(sizeof(PyObject *) * i);
+    if (!new_parser->handlers) {
+        Py_DECREF(new_parser);
+        return PyErr_NoMemory();
+    }
+    clear_handlers(new_parser, 1);
+
+    /* then copy handlers from self */
+    for (i = 0; handler_info[i].name != NULL; i++) {
+        PyObject *handler = self->handlers[i];
+        if (handler != NULL) {
+            Py_INCREF(handler);
+            new_parser->handlers[i] = handler;
+            handler_info[i].setter(new_parser->itself,
+                                   handler_info[i].handler);
+        }
+    }
+    return (PyObject *)new_parser;
+}
+
+PyDoc_STRVAR(xmlparse_SetParamEntityParsing__doc__,
+"SetParamEntityParsing(flag) -> success\n\
+Controls parsing of parameter entities (including the external DTD\n\
+subset). Possible flag values are XML_PARAM_ENTITY_PARSING_NEVER,\n\
+XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE and\n\
+XML_PARAM_ENTITY_PARSING_ALWAYS. Returns true if setting the flag\n\
+was successful.");
+
+static PyObject*
+xmlparse_SetParamEntityParsing(xmlparseobject *p, PyObject* args)
+{
+    int flag;
+    if (!PyArg_ParseTuple(args, "i", &flag))
+        return NULL;
+    flag = XML_SetParamEntityParsing(p->itself, flag);
+    return PyInt_FromLong(flag);
+}
+
+
+#if XML_COMBINED_VERSION >= 19505
+PyDoc_STRVAR(xmlparse_UseForeignDTD__doc__,
+"UseForeignDTD([flag])\n\
+Allows the application to provide an artificial external subset if one is\n\
+not specified as part of the document instance.  This readily allows the\n\
+use of a 'default' document type controlled by the application, while still\n\
+getting the advantage of providing document type information to the parser.\n\
+'flag' defaults to True if not provided.");
+
+static PyObject *
+xmlparse_UseForeignDTD(xmlparseobject *self, PyObject *args)
+{
+    PyObject *flagobj = NULL;
+    XML_Bool flag = XML_TRUE;
+    enum XML_Error rc;
+    if (!PyArg_UnpackTuple(args, "UseForeignDTD", 0, 1, &flagobj))
+        return NULL;
+    if (flagobj != NULL)
+        flag = PyObject_IsTrue(flagobj) ? XML_TRUE : XML_FALSE;
+    rc = XML_UseForeignDTD(self->itself, flag);
+    if (rc != XML_ERROR_NONE) {
+        return set_error(self, rc);
+    }
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+#endif
+
+static struct PyMethodDef xmlparse_methods[] = {
+    {"Parse",	  (PyCFunction)xmlparse_Parse,
+		  METH_VARARGS,	xmlparse_Parse__doc__},
+    {"ParseFile", (PyCFunction)xmlparse_ParseFile,
+		  METH_O,	xmlparse_ParseFile__doc__},
+    {"SetBase",   (PyCFunction)xmlparse_SetBase,
+		  METH_VARARGS, xmlparse_SetBase__doc__},
+    {"GetBase",   (PyCFunction)xmlparse_GetBase,
+		  METH_NOARGS, xmlparse_GetBase__doc__},
+    {"ExternalEntityParserCreate", (PyCFunction)xmlparse_ExternalEntityParserCreate,
+	 	  METH_VARARGS, xmlparse_ExternalEntityParserCreate__doc__},
+    {"SetParamEntityParsing", (PyCFunction)xmlparse_SetParamEntityParsing,
+		  METH_VARARGS, xmlparse_SetParamEntityParsing__doc__},
+    {"GetInputContext", (PyCFunction)xmlparse_GetInputContext,
+		  METH_NOARGS, xmlparse_GetInputContext__doc__},
+#if XML_COMBINED_VERSION >= 19505
+    {"UseForeignDTD", (PyCFunction)xmlparse_UseForeignDTD,
+		  METH_VARARGS, xmlparse_UseForeignDTD__doc__},
+#endif
+    {NULL,	  NULL}		/* sentinel */
+};
+
+/* ---------- */
+
+
+#ifdef Py_USING_UNICODE
+
+/* pyexpat international encoding support.
+   Make it as simple as possible.
+*/
+
+static char template_buffer[257];
+PyObject *template_string = NULL;
+
+static void
+init_template_buffer(void)
+{
+    int i;
+    for (i = 0; i < 256; i++) {
+	template_buffer[i] = i;
+    }
+    template_buffer[256] = 0;
+}
+
+static int
+PyUnknownEncodingHandler(void *encodingHandlerData,
+                         const XML_Char *name,
+                         XML_Encoding *info)
+{
+    PyUnicodeObject *_u_string = NULL;
+    int result = 0;
+    int i;
+
+    /* Yes, supports only 8bit encodings */
+    _u_string = (PyUnicodeObject *)
+        PyUnicode_Decode(template_buffer, 256, name, "replace");
+
+    if (_u_string == NULL)
+	return result;
+
+    for (i = 0; i < 256; i++) {
+	/* Stupid to access directly, but fast */
+	Py_UNICODE c = _u_string->str[i];
+	if (c == Py_UNICODE_REPLACEMENT_CHARACTER)
+	    info->map[i] = -1;
+	else
+	    info->map[i] = c;
+    }
+    info->data = NULL;
+    info->convert = NULL;
+    info->release = NULL;
+    result = 1;
+    Py_DECREF(_u_string);
+    return result;
+}
+
+#endif
+
+static PyObject *
+newxmlparseobject(char *encoding, char *namespace_separator, PyObject *intern)
+{
+    int i;
+    xmlparseobject *self;
+
+#ifdef Py_TPFLAGS_HAVE_GC
+    /* Code for versions 2.2 and later */
+    self = PyObject_GC_New(xmlparseobject, &Xmlparsetype);
+#else
+    self = PyObject_New(xmlparseobject, &Xmlparsetype);
+#endif
+    if (self == NULL)
+        return NULL;
+
+#ifdef Py_USING_UNICODE
+    self->returns_unicode = 1;
+#else
+    self->returns_unicode = 0;
+#endif
+
+    self->buffer = NULL;
+    self->buffer_size = CHARACTER_DATA_BUFFER_SIZE;
+    self->buffer_used = 0;
+    self->ordered_attributes = 0;
+    self->specified_attributes = 0;
+    self->in_callback = 0;
+    self->ns_prefixes = 0;
+    self->handlers = NULL;
+    if (namespace_separator != NULL) {
+        self->itself = XML_ParserCreateNS(encoding, *namespace_separator);
+    }
+    else {
+        self->itself = XML_ParserCreate(encoding);
+    }
+    self->intern = intern;
+    Py_XINCREF(self->intern);
+#ifdef Py_TPFLAGS_HAVE_GC
+    PyObject_GC_Track(self);
+#else
+    PyObject_GC_Init(self);
+#endif
+    if (self->itself == NULL) {
+        PyErr_SetString(PyExc_RuntimeError,
+                        "XML_ParserCreate failed");
+        Py_DECREF(self);
+        return NULL;
+    }
+    XML_SetUserData(self->itself, (void *)self);
+#ifdef Py_USING_UNICODE
+    XML_SetUnknownEncodingHandler(self->itself,
+                  (XML_UnknownEncodingHandler) PyUnknownEncodingHandler, NULL);
+#endif
+
+    for (i = 0; handler_info[i].name != NULL; i++)
+        /* do nothing */;
+
+    self->handlers = malloc(sizeof(PyObject *) * i);
+    if (!self->handlers) {
+        Py_DECREF(self);
+        return PyErr_NoMemory();
+    }
+    clear_handlers(self, 1);
+
+    return (PyObject*)self;
+}
+
+
+static void
+xmlparse_dealloc(xmlparseobject *self)
+{
+    int i;
+#ifdef Py_TPFLAGS_HAVE_GC
+    PyObject_GC_UnTrack(self);
+#else
+    PyObject_GC_Fini(self);
+#endif
+    if (self->itself != NULL)
+        XML_ParserFree(self->itself);
+    self->itself = NULL;
+
+    if (self->handlers != NULL) {
+        PyObject *temp;
+        for (i = 0; handler_info[i].name != NULL; i++) {
+            temp = self->handlers[i];
+            self->handlers[i] = NULL;
+            Py_XDECREF(temp);
+        }
+        free(self->handlers);
+        self->handlers = NULL;
+    }
+    if (self->buffer != NULL) {
+        free(self->buffer);
+        self->buffer = NULL;
+    }
+    Py_XDECREF(self->intern);
+#ifndef Py_TPFLAGS_HAVE_GC
+    /* Code for versions 2.0 and 2.1 */
+    PyObject_Del(self);
+#else
+    /* Code for versions 2.2 and later. */
+    PyObject_GC_Del(self);
+#endif
+}
+
+static int
+handlername2int(const char *name)
+{
+    int i;
+    for (i = 0; handler_info[i].name != NULL; i++) {
+        if (strcmp(name, handler_info[i].name) == 0) {
+            return i;
+        }
+    }
+    return -1;
+}
+
+static PyObject *
+get_pybool(int istrue)
+{
+    PyObject *result = istrue ? Py_True : Py_False;
+    Py_INCREF(result);
+    return result;
+}
+
+static PyObject *
+xmlparse_getattr(xmlparseobject *self, char *name)
+{
+    int handlernum = handlername2int(name);
+
+    if (handlernum != -1) {
+        PyObject *result = self->handlers[handlernum];
+        if (result == NULL)
+            result = Py_None;
+        Py_INCREF(result);
+        return result;
+    }
+    if (name[0] == 'E') {
+        if (strcmp(name, "ErrorCode") == 0)
+            return PyInt_FromLong((long)
+                                  XML_GetErrorCode(self->itself));
+        if (strcmp(name, "ErrorLineNumber") == 0)
+            return PyInt_FromLong((long)
+                                  XML_GetErrorLineNumber(self->itself));
+        if (strcmp(name, "ErrorColumnNumber") == 0)
+            return PyInt_FromLong((long)
+                                  XML_GetErrorColumnNumber(self->itself));
+        if (strcmp(name, "ErrorByteIndex") == 0)
+            return PyInt_FromLong((long)
+                                  XML_GetErrorByteIndex(self->itself));
+    }
+    if (name[0] == 'C') {
+        if (strcmp(name, "CurrentLineNumber") == 0)
+            return PyInt_FromLong((long)
+                                  XML_GetCurrentLineNumber(self->itself));
+        if (strcmp(name, "CurrentColumnNumber") == 0)
+            return PyInt_FromLong((long)
+                                  XML_GetCurrentColumnNumber(self->itself));
+        if (strcmp(name, "CurrentByteIndex") == 0)
+            return PyInt_FromLong((long)
+                                  XML_GetCurrentByteIndex(self->itself));
+    }
+    if (name[0] == 'b') {
+        if (strcmp(name, "buffer_size") == 0)
+            return PyInt_FromLong((long) self->buffer_size);
+        if (strcmp(name, "buffer_text") == 0)
+            return get_pybool(self->buffer != NULL);
+        if (strcmp(name, "buffer_used") == 0)
+            return PyInt_FromLong((long) self->buffer_used);
+    }
+    if (strcmp(name, "namespace_prefixes") == 0)
+        return get_pybool(self->ns_prefixes);
+    if (strcmp(name, "ordered_attributes") == 0)
+        return get_pybool(self->ordered_attributes);
+    if (strcmp(name, "returns_unicode") == 0)
+        return get_pybool((long) self->returns_unicode);
+    if (strcmp(name, "specified_attributes") == 0)
+        return get_pybool((long) self->specified_attributes);
+    if (strcmp(name, "intern") == 0) {
+        if (self->intern == NULL) {
+            Py_INCREF(Py_None);
+            return Py_None;
+        }
+        else {
+            Py_INCREF(self->intern);
+            return self->intern;
+        }
+    }
+
+#define APPEND(list, str)				\
+        do {						\
+                PyObject *o = PyString_FromString(str);	\
+                if (o != NULL)				\
+        	        PyList_Append(list, o);		\
+                Py_XDECREF(o);				\
+        } while (0)
+
+    if (strcmp(name, "__members__") == 0) {
+        int i;
+        PyObject *rc = PyList_New(0);
+	if (!rc)
+		return NULL;
+        for (i = 0; handler_info[i].name != NULL; i++) {
+            PyObject *o = get_handler_name(&handler_info[i]);
+            if (o != NULL)
+                PyList_Append(rc, o);
+            Py_XDECREF(o);
+        }
+        APPEND(rc, "ErrorCode");
+        APPEND(rc, "ErrorLineNumber");
+        APPEND(rc, "ErrorColumnNumber");
+        APPEND(rc, "ErrorByteIndex");
+        APPEND(rc, "CurrentLineNumber");
+        APPEND(rc, "CurrentColumnNumber");
+        APPEND(rc, "CurrentByteIndex");
+        APPEND(rc, "buffer_size");
+        APPEND(rc, "buffer_text");
+        APPEND(rc, "buffer_used");
+        APPEND(rc, "namespace_prefixes");
+        APPEND(rc, "ordered_attributes");
+        APPEND(rc, "returns_unicode");
+        APPEND(rc, "specified_attributes");
+        APPEND(rc, "intern");
+
+#undef APPEND
+        return rc;
+    }
+    return Py_FindMethod(xmlparse_methods, (PyObject *)self, name);
+}
+
+static int
+sethandler(xmlparseobject *self, const char *name, PyObject* v)
+{
+    int handlernum = handlername2int(name);
+    if (handlernum >= 0) {
+        xmlhandler c_handler = NULL;
+        PyObject *temp = self->handlers[handlernum];
+
+        if (v == Py_None) {
+            /* If this is the character data handler, and a character
+               data handler is already active, we need to be more
+               careful.  What we can safely do is replace the existing
+               character data handler callback function with a no-op
+               function that will refuse to call Python.  The downside
+               is that this doesn't completely remove the character
+               data handler from the C layer if there's any callback
+               active, so Expat does a little more work than it
+               otherwise would, but that's really an odd case.  A more
+               elaborate system of handlers and state could remove the
+               C handler more effectively. */
+            if (handlernum == CharacterData && self->in_callback)
+                c_handler = noop_character_data_handler;
+            v = NULL;
+        }
+        else if (v != NULL) {
+            Py_INCREF(v);
+            c_handler = handler_info[handlernum].handler;
+        }
+        self->handlers[handlernum] = v;
+        Py_XDECREF(temp);
+        handler_info[handlernum].setter(self->itself, c_handler);
+        return 1;
+    }
+    return 0;
+}
+
+static int
+xmlparse_setattr(xmlparseobject *self, char *name, PyObject *v)
+{
+    /* Set attribute 'name' to value 'v'. v==NULL means delete */
+    if (v == NULL) {
+        PyErr_SetString(PyExc_RuntimeError, "Cannot delete attribute");
+        return -1;
+    }
+    if (strcmp(name, "buffer_text") == 0) {
+        if (PyObject_IsTrue(v)) {
+            if (self->buffer == NULL) {
+                self->buffer = malloc(self->buffer_size);
+                if (self->buffer == NULL) {
+                    PyErr_NoMemory();
+                    return -1;
+                }
+                self->buffer_used = 0;
+            }
+        }
+        else if (self->buffer != NULL) {
+            if (flush_character_buffer(self) < 0)
+                return -1;
+            free(self->buffer);
+            self->buffer = NULL;
+        }
+        return 0;
+    }
+    if (strcmp(name, "namespace_prefixes") == 0) {
+        if (PyObject_IsTrue(v))
+            self->ns_prefixes = 1;
+        else
+            self->ns_prefixes = 0;
+        XML_SetReturnNSTriplet(self->itself, self->ns_prefixes);
+        return 0;
+    }
+    if (strcmp(name, "ordered_attributes") == 0) {
+        if (PyObject_IsTrue(v))
+            self->ordered_attributes = 1;
+        else
+            self->ordered_attributes = 0;
+        return 0;
+    }
+    if (strcmp(name, "returns_unicode") == 0) {
+        if (PyObject_IsTrue(v)) {
+#ifndef Py_USING_UNICODE
+            PyErr_SetString(PyExc_ValueError,
+                            "Unicode support not available");
+            return -1;
+#else
+            self->returns_unicode = 1;
+#endif
+        }
+        else
+            self->returns_unicode = 0;
+        return 0;
+    }
+    if (strcmp(name, "specified_attributes") == 0) {
+        if (PyObject_IsTrue(v))
+            self->specified_attributes = 1;
+        else
+            self->specified_attributes = 0;
+        return 0;
+    }
+    if (strcmp(name, "CharacterDataHandler") == 0) {
+        /* If we're changing the character data handler, flush all
+         * cached data with the old handler.  Not sure there's a
+         * "right" thing to do, though, but this probably won't
+         * happen.
+         */
+        if (flush_character_buffer(self) < 0)
+            return -1;
+    }
+    if (sethandler(self, name, v)) {
+        return 0;
+    }
+    PyErr_SetString(PyExc_AttributeError, name);
+    return -1;
+}
+
+#ifdef WITH_CYCLE_GC
+static int
+xmlparse_traverse(xmlparseobject *op, visitproc visit, void *arg)
+{
+    int i;
+    for (i = 0; handler_info[i].name != NULL; i++)
+        Py_VISIT(op->handlers[i]);
+    return 0;
+}
+
+static int
+xmlparse_clear(xmlparseobject *op)
+{
+    clear_handlers(op, 0);
+    Py_CLEAR(op->intern);
+    return 0;
+}
+#endif
+
+PyDoc_STRVAR(Xmlparsetype__doc__, "XML parser");
+
+static PyTypeObject Xmlparsetype = {
+	PyObject_HEAD_INIT(NULL)
+	0,				/*ob_size*/
+	"pyexpat.xmlparser",		/*tp_name*/
+	sizeof(xmlparseobject) + PyGC_HEAD_SIZE,/*tp_basicsize*/
+	0,				/*tp_itemsize*/
+	/* methods */
+	(destructor)xmlparse_dealloc,	/*tp_dealloc*/
+	(printfunc)0,		/*tp_print*/
+	(getattrfunc)xmlparse_getattr,	/*tp_getattr*/
+	(setattrfunc)xmlparse_setattr,	/*tp_setattr*/
+	(cmpfunc)0,		/*tp_compare*/
+	(reprfunc)0,		/*tp_repr*/
+	0,			/*tp_as_number*/
+	0,		/*tp_as_sequence*/
+	0,		/*tp_as_mapping*/
+	(hashfunc)0,		/*tp_hash*/
+	(ternaryfunc)0,		/*tp_call*/
+	(reprfunc)0,		/*tp_str*/
+	0,		/* tp_getattro */
+	0,		/* tp_setattro */
+	0,		/* tp_as_buffer */
+#ifdef Py_TPFLAGS_HAVE_GC
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+#else
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /*tp_flags*/
+#endif
+	Xmlparsetype__doc__, /* tp_doc - Documentation string */
+#ifdef WITH_CYCLE_GC
+	(traverseproc)xmlparse_traverse,	/* tp_traverse */
+	(inquiry)xmlparse_clear		/* tp_clear */
+#else
+	0, 0
+#endif
+};
+
+/* End of code for xmlparser objects */
+/* -------------------------------------------------------- */
+
+PyDoc_STRVAR(pyexpat_ParserCreate__doc__,
+"ParserCreate([encoding[, namespace_separator]]) -> parser\n\
+Return a new XML parser object.");
+
+static PyObject *
+pyexpat_ParserCreate(PyObject *notused, PyObject *args, PyObject *kw)
+{
+    char *encoding = NULL;
+    char *namespace_separator = NULL;
+    PyObject *intern = NULL;
+    PyObject *result;
+    int intern_decref = 0;
+    static char *kwlist[] = {"encoding", "namespace_separator",
+                                   "intern", NULL};
+
+    if (!PyArg_ParseTupleAndKeywords(args, kw, "|zzO:ParserCreate", kwlist,
+                                     &encoding, &namespace_separator, &intern))
+        return NULL;
+    if (namespace_separator != NULL
+        && strlen(namespace_separator) > 1) {
+        PyErr_SetString(PyExc_ValueError,
+                        "namespace_separator must be at most one"
+                        " character, omitted, or None");
+        return NULL;
+    }
+    /* Explicitly passing None means no interning is desired.
+       Not passing anything means that a new dictionary is used. */
+    if (intern == Py_None)
+	intern = NULL;
+    else if (intern == NULL) {
+	intern = PyDict_New();
+	if (!intern)
+	    return NULL;
+	intern_decref = 1;
+    }
+    else if (!PyDict_Check(intern)) {
+	PyErr_SetString(PyExc_TypeError, "intern must be a dictionary");
+	return NULL;
+    }
+
+    result = newxmlparseobject(encoding, namespace_separator, intern);
+    if (intern_decref) {
+	Py_DECREF(intern);
+    }
+    return result;
+}
+
+PyDoc_STRVAR(pyexpat_ErrorString__doc__,
+"ErrorString(errno) -> string\n\
+Returns string error for given number.");
+
+static PyObject *
+pyexpat_ErrorString(PyObject *self, PyObject *args)
+{
+    long code = 0;
+
+    if (!PyArg_ParseTuple(args, "l:ErrorString", &code))
+        return NULL;
+    return Py_BuildValue("z", XML_ErrorString((int)code));
+}
+
+/* List of methods defined in the module */
+
+static struct PyMethodDef pyexpat_methods[] = {
+    {"ParserCreate",	(PyCFunction)pyexpat_ParserCreate,
+     METH_VARARGS|METH_KEYWORDS, pyexpat_ParserCreate__doc__},
+    {"ErrorString",	(PyCFunction)pyexpat_ErrorString,
+     METH_VARARGS,	pyexpat_ErrorString__doc__},
+
+    {NULL,	 (PyCFunction)NULL, 0, NULL}		/* sentinel */
+};
+
+/* Module docstring */
+
+PyDoc_STRVAR(pyexpat_module_documentation,
+"Python wrapper for Expat parser.");
+
+/* Return a Python string that represents the version number without the
+ * extra cruft added by revision control, even if the right options were
+ * given to the "cvs export" command to make it not include the extra
+ * cruft.
+ */
+static PyObject *
+get_version_string(void)
+{
+    static char *rcsid = "$Revision: 47253 $";
+    char *rev = rcsid;
+    int i = 0;
+
+    while (!isdigit(Py_CHARMASK(*rev)))
+        ++rev;
+    while (rev[i] != ' ' && rev[i] != '\0')
+        ++i;
+
+    return PyString_FromStringAndSize(rev, i);
+}
+
+/* Initialization function for the module */
+
+#ifndef MODULE_NAME
+#define MODULE_NAME "pyexpat"
+#endif
+
+#ifndef MODULE_INITFUNC
+#define MODULE_INITFUNC initpyexpat
+#endif
+
+#ifndef PyMODINIT_FUNC
+#   ifdef MS_WINDOWS
+#       define PyMODINIT_FUNC __declspec(dllexport) void
+#   else
+#       define PyMODINIT_FUNC void
+#   endif
+#endif
+
+PyMODINIT_FUNC MODULE_INITFUNC(void);  /* avoid compiler warnings */
+
+PyMODINIT_FUNC
+MODULE_INITFUNC(void)
+{
+    PyObject *m, *d;
+    PyObject *errmod_name = PyString_FromString(MODULE_NAME ".errors");
+    PyObject *errors_module;
+    PyObject *modelmod_name;
+    PyObject *model_module;
+    PyObject *sys_modules;
+    static struct PyExpat_CAPI capi;
+    PyObject* capi_object;
+
+    if (errmod_name == NULL)
+        return;
+    modelmod_name = PyString_FromString(MODULE_NAME ".model");
+    if (modelmod_name == NULL)
+        return;
+
+    Xmlparsetype.ob_type = &PyType_Type;
+
+    /* Create the module and add the functions */
+    m = Py_InitModule3(MODULE_NAME, pyexpat_methods,
+                       pyexpat_module_documentation);
+    if (m == NULL)
+	return;
+
+    /* Add some symbolic constants to the module */
+    if (ErrorObject == NULL) {
+        ErrorObject = PyErr_NewException("xml.parsers.expat.ExpatError",
+                                         NULL, NULL);
+        if (ErrorObject == NULL)
+            return;
+    }
+    Py_INCREF(ErrorObject);
+    PyModule_AddObject(m, "error", ErrorObject);
+    Py_INCREF(ErrorObject);
+    PyModule_AddObject(m, "ExpatError", ErrorObject);
+    Py_INCREF(&Xmlparsetype);
+    PyModule_AddObject(m, "XMLParserType", (PyObject *) &Xmlparsetype);
+
+    PyModule_AddObject(m, "__version__", get_version_string());
+    PyModule_AddStringConstant(m, "EXPAT_VERSION",
+                               (char *) XML_ExpatVersion());
+    {
+        XML_Expat_Version info = XML_ExpatVersionInfo();
+        PyModule_AddObject(m, "version_info",
+                           Py_BuildValue("(iii)", info.major,
+                                         info.minor, info.micro));
+    }
+#ifdef Py_USING_UNICODE
+    init_template_buffer();
+#endif
+    /* XXX When Expat supports some way of figuring out how it was
+       compiled, this should check and set native_encoding
+       appropriately.
+    */
+    PyModule_AddStringConstant(m, "native_encoding", "UTF-8");
+
+    sys_modules = PySys_GetObject("modules");
+    d = PyModule_GetDict(m);
+    errors_module = PyDict_GetItem(d, errmod_name);
+    if (errors_module == NULL) {
+        errors_module = PyModule_New(MODULE_NAME ".errors");
+        if (errors_module != NULL) {
+            PyDict_SetItem(sys_modules, errmod_name, errors_module);
+            /* gives away the reference to errors_module */
+            PyModule_AddObject(m, "errors", errors_module);
+        }
+    }
+    Py_DECREF(errmod_name);
+    model_module = PyDict_GetItem(d, modelmod_name);
+    if (model_module == NULL) {
+        model_module = PyModule_New(MODULE_NAME ".model");
+        if (model_module != NULL) {
+            PyDict_SetItem(sys_modules, modelmod_name, model_module);
+            /* gives away the reference to model_module */
+            PyModule_AddObject(m, "model", model_module);
+        }
+    }
+    Py_DECREF(modelmod_name);
+    if (errors_module == NULL || model_module == NULL)
+        /* Don't core dump later! */
+        return;
+    
+#if XML_COMBINED_VERSION > 19505
+    {
+        const XML_Feature *features = XML_GetFeatureList();
+        PyObject *list = PyList_New(0);
+        if (list == NULL)
+            /* just ignore it */
+            PyErr_Clear();
+        else {
+            int i = 0;
+            for (; features[i].feature != XML_FEATURE_END; ++i) {
+                int ok;
+                PyObject *item = Py_BuildValue("si", features[i].name,
+                                               features[i].value);
+                if (item == NULL) {
+                    Py_DECREF(list);
+                    list = NULL;
+                    break;
+                }
+                ok = PyList_Append(list, item);
+                Py_DECREF(item);
+                if (ok < 0) {
+                    PyErr_Clear();
+                    break;
+                }
+            }
+            if (list != NULL)
+                PyModule_AddObject(m, "features", list);
+        }
+    }
+#endif
+
+#define MYCONST(name) \
+    PyModule_AddStringConstant(errors_module, #name, \
+                               (char*)XML_ErrorString(name))
+
+    MYCONST(XML_ERROR_NO_MEMORY);
+    MYCONST(XML_ERROR_SYNTAX);
+    MYCONST(XML_ERROR_NO_ELEMENTS);
+    MYCONST(XML_ERROR_INVALID_TOKEN);
+    MYCONST(XML_ERROR_UNCLOSED_TOKEN);
+    MYCONST(XML_ERROR_PARTIAL_CHAR);
+    MYCONST(XML_ERROR_TAG_MISMATCH);
+    MYCONST(XML_ERROR_DUPLICATE_ATTRIBUTE);
+    MYCONST(XML_ERROR_JUNK_AFTER_DOC_ELEMENT);
+    MYCONST(XML_ERROR_PARAM_ENTITY_REF);
+    MYCONST(XML_ERROR_UNDEFINED_ENTITY);
+    MYCONST(XML_ERROR_RECURSIVE_ENTITY_REF);
+    MYCONST(XML_ERROR_ASYNC_ENTITY);
+    MYCONST(XML_ERROR_BAD_CHAR_REF);
+    MYCONST(XML_ERROR_BINARY_ENTITY_REF);
+    MYCONST(XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF);
+    MYCONST(XML_ERROR_MISPLACED_XML_PI);
+    MYCONST(XML_ERROR_UNKNOWN_ENCODING);
+    MYCONST(XML_ERROR_INCORRECT_ENCODING);
+    MYCONST(XML_ERROR_UNCLOSED_CDATA_SECTION);
+    MYCONST(XML_ERROR_EXTERNAL_ENTITY_HANDLING);
+    MYCONST(XML_ERROR_NOT_STANDALONE);
+    MYCONST(XML_ERROR_UNEXPECTED_STATE);
+    MYCONST(XML_ERROR_ENTITY_DECLARED_IN_PE);
+    MYCONST(XML_ERROR_FEATURE_REQUIRES_XML_DTD);
+    MYCONST(XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING);
+    /* Added in Expat 1.95.7. */
+    MYCONST(XML_ERROR_UNBOUND_PREFIX);
+    /* Added in Expat 1.95.8. */
+    MYCONST(XML_ERROR_UNDECLARING_PREFIX);
+    MYCONST(XML_ERROR_INCOMPLETE_PE);
+    MYCONST(XML_ERROR_XML_DECL);
+    MYCONST(XML_ERROR_TEXT_DECL);
+    MYCONST(XML_ERROR_PUBLICID);
+    MYCONST(XML_ERROR_SUSPENDED);
+    MYCONST(XML_ERROR_NOT_SUSPENDED);
+    MYCONST(XML_ERROR_ABORTED);
+    MYCONST(XML_ERROR_FINISHED);
+    MYCONST(XML_ERROR_SUSPEND_PE);
+
+    PyModule_AddStringConstant(errors_module, "__doc__",
+                               "Constants used to describe error conditions.");
+
+#undef MYCONST
+
+#define MYCONST(c) PyModule_AddIntConstant(m, #c, c)
+    MYCONST(XML_PARAM_ENTITY_PARSING_NEVER);
+    MYCONST(XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE);
+    MYCONST(XML_PARAM_ENTITY_PARSING_ALWAYS);
+#undef MYCONST
+
+#define MYCONST(c) PyModule_AddIntConstant(model_module, #c, c)
+    PyModule_AddStringConstant(model_module, "__doc__",
+                     "Constants used to interpret content model information.");
+
+    MYCONST(XML_CTYPE_EMPTY);
+    MYCONST(XML_CTYPE_ANY);
+    MYCONST(XML_CTYPE_MIXED);
+    MYCONST(XML_CTYPE_NAME);
+    MYCONST(XML_CTYPE_CHOICE);
+    MYCONST(XML_CTYPE_SEQ);
+
+    MYCONST(XML_CQUANT_NONE);
+    MYCONST(XML_CQUANT_OPT);
+    MYCONST(XML_CQUANT_REP);
+    MYCONST(XML_CQUANT_PLUS);
+#undef MYCONST
+
+    /* initialize pyexpat dispatch table */
+    capi.size = sizeof(capi);
+    capi.magic = PyExpat_CAPI_MAGIC;
+    capi.MAJOR_VERSION = XML_MAJOR_VERSION;
+    capi.MINOR_VERSION = XML_MINOR_VERSION;
+    capi.MICRO_VERSION = XML_MICRO_VERSION;
+    capi.ErrorString = XML_ErrorString;
+    capi.GetErrorCode = XML_GetErrorCode;
+    capi.GetErrorColumnNumber = XML_GetErrorColumnNumber;
+    capi.GetErrorLineNumber = XML_GetErrorLineNumber;
+    capi.Parse = XML_Parse;
+    capi.ParserCreate_MM = XML_ParserCreate_MM;
+    capi.ParserFree = XML_ParserFree;
+    capi.SetCharacterDataHandler = XML_SetCharacterDataHandler;
+    capi.SetCommentHandler = XML_SetCommentHandler;
+    capi.SetDefaultHandlerExpand = XML_SetDefaultHandlerExpand;
+    capi.SetElementHandler = XML_SetElementHandler;
+    capi.SetNamespaceDeclHandler = XML_SetNamespaceDeclHandler;
+    capi.SetProcessingInstructionHandler = XML_SetProcessingInstructionHandler;
+    capi.SetUnknownEncodingHandler = XML_SetUnknownEncodingHandler;
+    capi.SetUserData = XML_SetUserData;
+    
+    /* export as cobject */
+    capi_object = PyCObject_FromVoidPtr(&capi, NULL);
+    if (capi_object)
+        PyModule_AddObject(m, "expat_CAPI", capi_object);
+}
+
+static void
+clear_handlers(xmlparseobject *self, int initial)
+{
+    int i = 0;
+    PyObject *temp;
+
+    for (; handler_info[i].name != NULL; i++) {
+        if (initial)
+	    self->handlers[i] = NULL;
+	else {
+            temp = self->handlers[i];
+            self->handlers[i] = NULL;
+            Py_XDECREF(temp);
+	    handler_info[i].setter(self->itself, NULL);
+        }
+    }
+}
+
+static struct HandlerInfo handler_info[] = {
+    {"StartElementHandler",
+     (xmlhandlersetter)XML_SetStartElementHandler,
+     (xmlhandler)my_StartElementHandler},
+    {"EndElementHandler",
+     (xmlhandlersetter)XML_SetEndElementHandler,
+     (xmlhandler)my_EndElementHandler},
+    {"ProcessingInstructionHandler",
+     (xmlhandlersetter)XML_SetProcessingInstructionHandler,
+     (xmlhandler)my_ProcessingInstructionHandler},
+    {"CharacterDataHandler",
+     (xmlhandlersetter)XML_SetCharacterDataHandler,
+     (xmlhandler)my_CharacterDataHandler},
+    {"UnparsedEntityDeclHandler",
+     (xmlhandlersetter)XML_SetUnparsedEntityDeclHandler,
+     (xmlhandler)my_UnparsedEntityDeclHandler},
+    {"NotationDeclHandler",
+     (xmlhandlersetter)XML_SetNotationDeclHandler,
+     (xmlhandler)my_NotationDeclHandler},
+    {"StartNamespaceDeclHandler",
+     (xmlhandlersetter)XML_SetStartNamespaceDeclHandler,
+     (xmlhandler)my_StartNamespaceDeclHandler},
+    {"EndNamespaceDeclHandler",
+     (xmlhandlersetter)XML_SetEndNamespaceDeclHandler,
+     (xmlhandler)my_EndNamespaceDeclHandler},
+    {"CommentHandler",
+     (xmlhandlersetter)XML_SetCommentHandler,
+     (xmlhandler)my_CommentHandler},
+    {"StartCdataSectionHandler",
+     (xmlhandlersetter)XML_SetStartCdataSectionHandler,
+     (xmlhandler)my_StartCdataSectionHandler},
+    {"EndCdataSectionHandler",
+     (xmlhandlersetter)XML_SetEndCdataSectionHandler,
+     (xmlhandler)my_EndCdataSectionHandler},
+    {"DefaultHandler",
+     (xmlhandlersetter)XML_SetDefaultHandler,
+     (xmlhandler)my_DefaultHandler},
+    {"DefaultHandlerExpand",
+     (xmlhandlersetter)XML_SetDefaultHandlerExpand,
+     (xmlhandler)my_DefaultHandlerExpandHandler},
+    {"NotStandaloneHandler",
+     (xmlhandlersetter)XML_SetNotStandaloneHandler,
+     (xmlhandler)my_NotStandaloneHandler},
+    {"ExternalEntityRefHandler",
+     (xmlhandlersetter)XML_SetExternalEntityRefHandler,
+     (xmlhandler)my_ExternalEntityRefHandler},
+    {"StartDoctypeDeclHandler",
+     (xmlhandlersetter)XML_SetStartDoctypeDeclHandler,
+     (xmlhandler)my_StartDoctypeDeclHandler},
+    {"EndDoctypeDeclHandler",
+     (xmlhandlersetter)XML_SetEndDoctypeDeclHandler,
+     (xmlhandler)my_EndDoctypeDeclHandler},
+    {"EntityDeclHandler",
+     (xmlhandlersetter)XML_SetEntityDeclHandler,
+     (xmlhandler)my_EntityDeclHandler},
+    {"XmlDeclHandler",
+     (xmlhandlersetter)XML_SetXmlDeclHandler,
+     (xmlhandler)my_XmlDeclHandler},
+    {"ElementDeclHandler",
+     (xmlhandlersetter)XML_SetElementDeclHandler,
+     (xmlhandler)my_ElementDeclHandler},
+    {"AttlistDeclHandler",
+     (xmlhandlersetter)XML_SetAttlistDeclHandler,
+     (xmlhandler)my_AttlistDeclHandler},
+#if XML_COMBINED_VERSION >= 19504
+    {"SkippedEntityHandler",
+     (xmlhandlersetter)XML_SetSkippedEntityHandler,
+     (xmlhandler)my_SkippedEntityHandler},
+#endif
+
+    {NULL, NULL, NULL} /* sentinel */
+};

Added: vendor/Python/current/Modules/python.c
===================================================================
--- vendor/Python/current/Modules/python.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/python.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,24 @@
+/* Minimal main program -- everything is loaded from the library */
+
+#include "Python.h"
+
+#ifdef __FreeBSD__
+#include <floatingpoint.h>
+#endif
+
+int
+main(int argc, char **argv)
+{
+	/* 754 requires that FP exceptions run in "no stop" mode by default,
+	 * and until C vendors implement C99's ways to control FP exceptions,
+	 * Python requires non-stop mode.  Alas, some platforms enable FP
+	 * exceptions by default.  Here we disable them.
+	 */
+#ifdef __FreeBSD__
+	fp_except_t m;
+
+	m = fpgetmask();
+	fpsetmask(m & ~FP_X_OFL);
+#endif
+	return Py_Main(argc, argv);
+}

Added: vendor/Python/current/Modules/readline.c
===================================================================
--- vendor/Python/current/Modules/readline.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/readline.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,941 @@
+/* This module makes GNU readline available to Python.  It has ideas
+ * contributed by Lee Busby, LLNL, and William Magro, Cornell Theory
+ * Center.  The completer interface was inspired by Lele Gaifax.  More
+ * recently, it was largely rewritten by Guido van Rossum.
+ */
+
+/* Standard definitions */
+#include "Python.h"
+#include <setjmp.h>
+#include <signal.h>
+#include <errno.h>
+#include <sys/time.h>
+
+#if defined(HAVE_SETLOCALE)
+/* GNU readline() mistakenly sets the LC_CTYPE locale.
+ * This is evil.  Only the user or the app's main() should do this!
+ * We must save and restore the locale around the rl_initialize() call.
+ */
+#define SAVE_LOCALE
+#include <locale.h>
+#endif
+
+#ifdef SAVE_LOCALE
+#  define RESTORE_LOCALE(sl) { setlocale(LC_CTYPE, sl); free(sl); }
+#else
+#  define RESTORE_LOCALE(sl) 
+#endif
+
+/* GNU readline definitions */
+#undef HAVE_CONFIG_H /* Else readline/chardefs.h includes strings.h */
+#include <readline/readline.h>
+#include <readline/history.h>
+
+#ifdef HAVE_RL_COMPLETION_MATCHES
+#define completion_matches(x, y) \
+	rl_completion_matches((x), ((rl_compentry_func_t *)(y)))
+#endif
+
+
+/* Exported function to send one line to readline's init file parser */
+
+static PyObject *
+parse_and_bind(PyObject *self, PyObject *args)
+{
+	char *s, *copy;
+	if (!PyArg_ParseTuple(args, "s:parse_and_bind", &s))
+		return NULL;
+	/* Make a copy -- rl_parse_and_bind() modifies its argument */
+	/* Bernard Herzog */
+	copy = malloc(1 + strlen(s));
+	if (copy == NULL)
+		return PyErr_NoMemory();
+	strcpy(copy, s);
+	rl_parse_and_bind(copy);
+	free(copy); /* Free the copy */
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(doc_parse_and_bind,
+"parse_and_bind(string) -> None\n\
+Parse and execute single line of a readline init file.");
+
+
+/* Exported function to parse a readline init file */
+
+static PyObject *
+read_init_file(PyObject *self, PyObject *args)
+{
+	char *s = NULL;
+	if (!PyArg_ParseTuple(args, "|z:read_init_file", &s))
+		return NULL;
+	errno = rl_read_init_file(s);
+	if (errno)
+		return PyErr_SetFromErrno(PyExc_IOError);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(doc_read_init_file,
+"read_init_file([filename]) -> None\n\
+Parse a readline initialization file.\n\
+The default filename is the last filename used.");
+
+
+/* Exported function to load a readline history file */
+
+static PyObject *
+read_history_file(PyObject *self, PyObject *args)
+{
+	char *s = NULL;
+	if (!PyArg_ParseTuple(args, "|z:read_history_file", &s))
+		return NULL;
+	errno = read_history(s);
+	if (errno)
+		return PyErr_SetFromErrno(PyExc_IOError);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static int _history_length = -1; /* do not truncate history by default */
+PyDoc_STRVAR(doc_read_history_file,
+"read_history_file([filename]) -> None\n\
+Load a readline history file.\n\
+The default filename is ~/.history.");
+
+
+/* Exported function to save a readline history file */
+
+static PyObject *
+write_history_file(PyObject *self, PyObject *args)
+{
+	char *s = NULL;
+	if (!PyArg_ParseTuple(args, "|z:write_history_file", &s))
+		return NULL;
+	errno = write_history(s);
+	if (!errno && _history_length >= 0)
+		history_truncate_file(s, _history_length);
+	if (errno)
+		return PyErr_SetFromErrno(PyExc_IOError);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(doc_write_history_file,
+"write_history_file([filename]) -> None\n\
+Save a readline history file.\n\
+The default filename is ~/.history.");
+
+
+/* Set history length */
+
+static PyObject*
+set_history_length(PyObject *self, PyObject *args)
+{
+	int length = _history_length;
+	if (!PyArg_ParseTuple(args, "i:set_history_length", &length))
+		return NULL;
+	_history_length = length;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(set_history_length_doc,
+"set_history_length(length) -> None\n\
+set the maximal number of items which will be written to\n\
+the history file. A negative length is used to inhibit\n\
+history truncation.");
+
+
+/* Get history length */
+
+static PyObject*
+get_history_length(PyObject *self, PyObject *noarg)
+{
+	return PyInt_FromLong(_history_length);
+}
+
+PyDoc_STRVAR(get_history_length_doc,
+"get_history_length() -> int\n\
+return the maximum number of items that will be written to\n\
+the history file.");
+
+
+/* Generic hook function setter */
+
+static PyObject *
+set_hook(const char *funcname, PyObject **hook_var, PyObject *args)
+{
+	PyObject *function = Py_None;
+	char buf[80];
+	PyOS_snprintf(buf, sizeof(buf), "|O:set_%.50s", funcname);
+	if (!PyArg_ParseTuple(args, buf, &function))
+		return NULL;
+	if (function == Py_None) {
+		Py_XDECREF(*hook_var);
+		*hook_var = NULL;
+	}
+	else if (PyCallable_Check(function)) {
+		PyObject *tmp = *hook_var;
+		Py_INCREF(function);
+		*hook_var = function;
+		Py_XDECREF(tmp);
+	}
+	else {
+		PyOS_snprintf(buf, sizeof(buf),
+			      "set_%.50s(func): argument not callable",
+			      funcname);
+		PyErr_SetString(PyExc_TypeError, buf);
+		return NULL;
+	}
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+
+/* Exported functions to specify hook functions in Python */
+
+static PyObject *startup_hook = NULL;
+
+#ifdef HAVE_RL_PRE_INPUT_HOOK
+static PyObject *pre_input_hook = NULL;
+#endif
+
+static PyObject *
+set_startup_hook(PyObject *self, PyObject *args)
+{
+	return set_hook("startup_hook", &startup_hook, args);
+}
+
+PyDoc_STRVAR(doc_set_startup_hook,
+"set_startup_hook([function]) -> None\n\
+Set or remove the startup_hook function.\n\
+The function is called with no arguments just\n\
+before readline prints the first prompt.");
+
+
+#ifdef HAVE_RL_PRE_INPUT_HOOK
+
+/* Set pre-input hook */
+
+static PyObject *
+set_pre_input_hook(PyObject *self, PyObject *args)
+{
+	return set_hook("pre_input_hook", &pre_input_hook, args);
+}
+
+PyDoc_STRVAR(doc_set_pre_input_hook,
+"set_pre_input_hook([function]) -> None\n\
+Set or remove the pre_input_hook function.\n\
+The function is called with no arguments after the first prompt\n\
+has been printed and just before readline starts reading input\n\
+characters.");
+
+#endif
+
+
+/* Exported function to specify a word completer in Python */
+
+static PyObject *completer = NULL;
+
+static PyObject *begidx = NULL;
+static PyObject *endidx = NULL;
+
+
+/* Get the beginning index for the scope of the tab-completion */
+
+static PyObject *
+get_begidx(PyObject *self, PyObject *noarg)
+{
+	Py_INCREF(begidx);
+	return begidx;
+}
+
+PyDoc_STRVAR(doc_get_begidx,
+"get_begidx() -> int\n\
+get the beginning index of the readline tab-completion scope");
+
+
+/* Get the ending index for the scope of the tab-completion */
+
+static PyObject *
+get_endidx(PyObject *self, PyObject *noarg)
+{
+	Py_INCREF(endidx);
+	return endidx;
+}
+
+PyDoc_STRVAR(doc_get_endidx,
+"get_endidx() -> int\n\
+get the ending index of the readline tab-completion scope");
+
+
+/* Set the tab-completion word-delimiters that readline uses */
+
+static PyObject *
+set_completer_delims(PyObject *self, PyObject *args)
+{
+	char *break_chars;
+
+	if(!PyArg_ParseTuple(args, "s:set_completer_delims", &break_chars)) {
+		return NULL;
+	}
+	free((void*)rl_completer_word_break_characters);
+	rl_completer_word_break_characters = strdup(break_chars);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(doc_set_completer_delims,
+"set_completer_delims(string) -> None\n\
+set the readline word delimiters for tab-completion");
+
+static PyObject *
+py_remove_history(PyObject *self, PyObject *args)
+{
+        int entry_number;
+        HIST_ENTRY *entry;
+
+        if (!PyArg_ParseTuple(args, "i:remove_history", &entry_number))
+                return NULL;
+        if (entry_number < 0) {
+                PyErr_SetString(PyExc_ValueError,
+                                "History index cannot be negative");
+                return NULL;
+        }
+        entry = remove_history(entry_number);
+        if (!entry) {
+                PyErr_Format(PyExc_ValueError,
+                             "No history item at position %d",
+                             entry_number);
+                return NULL;
+        }
+        /* free memory allocated for the history entry */
+        if (entry->line)
+                free(entry->line);
+        if (entry->data)
+                free(entry->data);
+        free(entry);
+
+        Py_INCREF(Py_None);
+        return Py_None;
+}
+
+PyDoc_STRVAR(doc_remove_history,
+"remove_history_item(pos) -> None\n\
+remove history item given by its position");
+
+static PyObject *
+py_replace_history(PyObject *self, PyObject *args)
+{
+        int entry_number;
+        char *line;
+        HIST_ENTRY *old_entry;
+
+        if (!PyArg_ParseTuple(args, "is:replace_history", &entry_number, &line)) {
+                return NULL;
+        }
+        if (entry_number < 0) {
+                PyErr_SetString(PyExc_ValueError,
+                                "History index cannot be negative");
+                return NULL;
+        }
+        old_entry = replace_history_entry(entry_number, line, (void *)NULL);
+        if (!old_entry) {
+                PyErr_Format(PyExc_ValueError,
+                             "No history item at position %d",
+                             entry_number);
+                return NULL;
+        }
+        /* free memory allocated for the old history entry */
+        if (old_entry->line)
+            free(old_entry->line);
+        if (old_entry->data)
+            free(old_entry->data);
+        free(old_entry);
+
+        Py_INCREF(Py_None);
+        return Py_None;
+}
+
+PyDoc_STRVAR(doc_replace_history,
+"replace_history_item(pos, line) -> None\n\
+replaces history item given by its position with contents of line");
+
+/* Add a line to the history buffer */
+
+static PyObject *
+py_add_history(PyObject *self, PyObject *args)
+{
+	char *line;
+
+	if(!PyArg_ParseTuple(args, "s:add_history", &line)) {
+		return NULL;
+	}
+	add_history(line);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(doc_add_history,
+"add_history(string) -> None\n\
+add a line to the history buffer");
+
+
+/* Get the tab-completion word-delimiters that readline uses */
+
+static PyObject *
+get_completer_delims(PyObject *self, PyObject *noarg)
+{
+	return PyString_FromString(rl_completer_word_break_characters);
+}
+
+PyDoc_STRVAR(doc_get_completer_delims,
+"get_completer_delims() -> string\n\
+get the readline word delimiters for tab-completion");
+
+
+/* Set the completer function */
+
+static PyObject *
+set_completer(PyObject *self, PyObject *args)
+{
+	return set_hook("completer", &completer, args);
+}
+
+PyDoc_STRVAR(doc_set_completer,
+"set_completer([function]) -> None\n\
+Set or remove the completer function.\n\
+The function is called as function(text, state),\n\
+for state in 0, 1, 2, ..., until it returns a non-string.\n\
+It should return the next possible completion starting with 'text'.");
+
+
+static PyObject *
+get_completer(PyObject *self, PyObject *noargs)
+{
+	if (completer == NULL) {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+	Py_INCREF(completer);
+	return completer;
+}
+
+PyDoc_STRVAR(doc_get_completer,
+"get_completer() -> function\n\
+\n\
+Returns current completer function.");
+
+/* Exported function to get any element of history */
+
+static PyObject *
+get_history_item(PyObject *self, PyObject *args)
+{
+	int idx = 0;
+	HIST_ENTRY *hist_ent;
+
+	if (!PyArg_ParseTuple(args, "i:index", &idx))
+		return NULL;
+	if ((hist_ent = history_get(idx)))
+		return PyString_FromString(hist_ent->line);
+	else {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+}
+
+PyDoc_STRVAR(doc_get_history_item,
+"get_history_item() -> string\n\
+return the current contents of history item at index.");
+
+
+/* Exported function to get current length of history */
+
+static PyObject *
+get_current_history_length(PyObject *self, PyObject *noarg)
+{
+	HISTORY_STATE *hist_st;
+
+	hist_st = history_get_history_state();
+	return PyInt_FromLong(hist_st ? (long) hist_st->length : (long) 0);
+}
+
+PyDoc_STRVAR(doc_get_current_history_length,
+"get_current_history_length() -> integer\n\
+return the current (not the maximum) length of history.");
+
+
+/* Exported function to read the current line buffer */
+
+static PyObject *
+get_line_buffer(PyObject *self, PyObject *noarg)
+{
+	return PyString_FromString(rl_line_buffer);
+}
+
+PyDoc_STRVAR(doc_get_line_buffer,
+"get_line_buffer() -> string\n\
+return the current contents of the line buffer.");
+
+
+#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
+
+/* Exported function to clear the current history */
+
+static PyObject *
+py_clear_history(PyObject *self, PyObject *noarg)
+{
+	clear_history();
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(doc_clear_history,
+"clear_history() -> None\n\
+Clear the current readline history.");
+#endif
+
+
+/* Exported function to insert text into the line buffer */
+
+static PyObject *
+insert_text(PyObject *self, PyObject *args)
+{
+	char *s;
+	if (!PyArg_ParseTuple(args, "s:insert_text", &s))
+		return NULL;
+	rl_insert_text(s);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(doc_insert_text,
+"insert_text(string) -> None\n\
+Insert text into the command line.");
+
+
+/* Redisplay the line buffer */
+
+static PyObject *
+redisplay(PyObject *self, PyObject *noarg)
+{
+	rl_redisplay();
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(doc_redisplay,
+"redisplay() -> None\n\
+Change what's displayed on the screen to reflect the current\n\
+contents of the line buffer.");
+
+
+/* Table of functions exported by the module */
+
+static struct PyMethodDef readline_methods[] =
+{
+	{"parse_and_bind", parse_and_bind, METH_VARARGS, doc_parse_and_bind},
+	{"get_line_buffer", get_line_buffer, METH_NOARGS, doc_get_line_buffer},
+	{"insert_text", insert_text, METH_VARARGS, doc_insert_text},
+	{"redisplay", redisplay, METH_NOARGS, doc_redisplay},
+	{"read_init_file", read_init_file, METH_VARARGS, doc_read_init_file},
+	{"read_history_file", read_history_file,
+	 METH_VARARGS, doc_read_history_file},
+	{"write_history_file", write_history_file,
+	 METH_VARARGS, doc_write_history_file},
+	{"get_history_item", get_history_item,
+	 METH_VARARGS, doc_get_history_item},
+	{"get_current_history_length", (PyCFunction)get_current_history_length,
+	 METH_NOARGS, doc_get_current_history_length},
+ 	{"set_history_length", set_history_length,
+	 METH_VARARGS, set_history_length_doc},
+ 	{"get_history_length", get_history_length,
+	 METH_NOARGS, get_history_length_doc},
+	{"set_completer", set_completer, METH_VARARGS, doc_set_completer},
+	{"get_completer", get_completer, METH_NOARGS, doc_get_completer},
+	{"get_begidx", get_begidx, METH_NOARGS, doc_get_begidx},
+	{"get_endidx", get_endidx, METH_NOARGS, doc_get_endidx},
+
+	{"set_completer_delims", set_completer_delims,
+	 METH_VARARGS, doc_set_completer_delims},
+	{"add_history", py_add_history, METH_VARARGS, doc_add_history},
+        {"remove_history_item", py_remove_history, METH_VARARGS, doc_remove_history},
+        {"replace_history_item", py_replace_history, METH_VARARGS, doc_replace_history},
+	{"get_completer_delims", get_completer_delims,
+	 METH_NOARGS, doc_get_completer_delims},
+
+	{"set_startup_hook", set_startup_hook,
+	 METH_VARARGS, doc_set_startup_hook},
+#ifdef HAVE_RL_PRE_INPUT_HOOK
+	{"set_pre_input_hook", set_pre_input_hook,
+	 METH_VARARGS, doc_set_pre_input_hook},
+#endif
+#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
+	{"clear_history", py_clear_history, METH_NOARGS, doc_clear_history},
+#endif
+	{0, 0}
+};
+
+
+/* C function to call the Python hooks. */
+
+static int
+on_hook(PyObject *func)
+{
+	int result = 0;
+	if (func != NULL) {
+		PyObject *r;
+#ifdef WITH_THREAD	      
+		PyGILState_STATE gilstate = PyGILState_Ensure();
+#endif
+		r = PyObject_CallFunction(func, NULL);
+		if (r == NULL)
+			goto error;
+		if (r == Py_None)
+			result = 0;
+		else {
+			result = PyInt_AsLong(r);
+			if (result == -1 && PyErr_Occurred()) 
+				goto error;
+		}
+		Py_DECREF(r);
+		goto done;
+	  error:
+		PyErr_Clear();
+		Py_XDECREF(r);
+	  done:
+#ifdef WITH_THREAD	      
+		PyGILState_Release(gilstate);
+#endif
+		return result;
+	}
+	return result;
+}
+
+static int
+on_startup_hook(void)
+{
+	return on_hook(startup_hook);
+}
+
+#ifdef HAVE_RL_PRE_INPUT_HOOK
+static int
+on_pre_input_hook(void)
+{
+	return on_hook(pre_input_hook);
+}
+#endif
+
+
+/* C function to call the Python completer. */
+
+static char *
+on_completion(char *text, int state)
+{
+	char *result = NULL;
+	if (completer != NULL) {
+		PyObject *r;
+#ifdef WITH_THREAD	      
+		PyGILState_STATE gilstate = PyGILState_Ensure();
+#endif
+		rl_attempted_completion_over = 1;
+		r = PyObject_CallFunction(completer, "si", text, state);
+		if (r == NULL)
+			goto error;
+		if (r == Py_None) {
+			result = NULL;
+		}
+		else {
+			char *s = PyString_AsString(r);
+			if (s == NULL)
+				goto error;
+			result = strdup(s);
+		}
+		Py_DECREF(r);
+		goto done;
+	  error:
+		PyErr_Clear();
+		Py_XDECREF(r);
+	  done:
+#ifdef WITH_THREAD	      
+		PyGILState_Release(gilstate);
+#endif
+		return result;
+	}
+	return result;
+}
+
+
+/* A more flexible constructor that saves the "begidx" and "endidx"
+ * before calling the normal completer */
+
+static char **
+flex_complete(char *text, int start, int end)
+{
+	Py_XDECREF(begidx);
+	Py_XDECREF(endidx);
+	begidx = PyInt_FromLong((long) start);
+	endidx = PyInt_FromLong((long) end);
+	return completion_matches(text, *on_completion);
+}
+
+
+/* Helper to initialize GNU readline properly. */
+
+static void
+setup_readline(void)
+{
+#ifdef SAVE_LOCALE
+	char *saved_locale = strdup(setlocale(LC_CTYPE, NULL));
+	if (!saved_locale)
+		Py_FatalError("not enough memory to save locale");
+#endif
+
+	using_history();
+
+	rl_readline_name = "python";
+#if defined(PYOS_OS2) && defined(PYCC_GCC)
+	/* Allow $if term= in .inputrc to work */
+	rl_terminal_name = getenv("TERM");
+#endif
+	/* Force rebind of TAB to insert-tab */
+	rl_bind_key('\t', rl_insert);
+	/* Bind both ESC-TAB and ESC-ESC to the completion function */
+	rl_bind_key_in_map ('\t', rl_complete, emacs_meta_keymap);
+	rl_bind_key_in_map ('\033', rl_complete, emacs_meta_keymap);
+	/* Set our hook functions */
+	rl_startup_hook = (Function *)on_startup_hook;
+#ifdef HAVE_RL_PRE_INPUT_HOOK
+	rl_pre_input_hook = (Function *)on_pre_input_hook;
+#endif
+	/* Set our completion function */
+	rl_attempted_completion_function = (CPPFunction *)flex_complete;
+	/* Set Python word break characters */
+	rl_completer_word_break_characters =
+		strdup(" \t\n`~!@#$%^&*()-=+[{]}\\|;:'\",<>/?");
+		/* All nonalphanums except '.' */
+#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
+	rl_completion_append_character ='\0';
+#endif
+
+	begidx = PyInt_FromLong(0L);
+	endidx = PyInt_FromLong(0L);
+	/* Initialize (allows .inputrc to override)
+	 *
+	 * XXX: A bug in the readline-2.2 library causes a memory leak
+	 * inside this function.  Nothing we can do about it.
+	 */
+	rl_initialize();
+
+	RESTORE_LOCALE(saved_locale)
+}
+
+/* Wrapper around GNU readline that handles signals differently. */
+
+
+#if defined(HAVE_RL_CALLBACK) && defined(HAVE_SELECT)
+
+static	char *completed_input_string;
+static void
+rlhandler(char *text)
+{
+	completed_input_string = text;
+	rl_callback_handler_remove();
+}
+
+extern PyThreadState* _PyOS_ReadlineTState;
+
+static char *
+readline_until_enter_or_signal(char *prompt, int *signal)
+{
+	char * not_done_reading = "";
+	fd_set selectset;
+
+	*signal = 0;
+#ifdef HAVE_RL_CATCH_SIGNAL
+	rl_catch_signals = 0;
+#endif
+
+	rl_callback_handler_install (prompt, rlhandler);
+	FD_ZERO(&selectset);
+	
+	completed_input_string = not_done_reading;
+
+	while (completed_input_string == not_done_reading) {
+		int has_input = 0;
+
+		while (!has_input)
+		{	struct timeval timeout = {0, 100000}; /* 0.1 seconds */
+
+			/* [Bug #1552726] Only limit the pause if an input hook has been 
+			   defined.  */
+		 	struct timeval *timeoutp = NULL;
+			if (PyOS_InputHook) 
+				timeoutp = &timeout;
+			FD_SET(fileno(rl_instream), &selectset);
+			/* select resets selectset if no input was available */
+			has_input = select(fileno(rl_instream) + 1, &selectset,
+					   NULL, NULL, timeoutp);
+			if(PyOS_InputHook) PyOS_InputHook();
+		}
+
+		if(has_input > 0) {
+			rl_callback_read_char();
+		}
+		else if (errno == EINTR) {
+			int s;
+#ifdef WITH_THREAD
+			PyEval_RestoreThread(_PyOS_ReadlineTState);
+#endif
+			s = PyErr_CheckSignals();
+#ifdef WITH_THREAD
+			PyEval_SaveThread();	
+#endif
+			if (s < 0) {
+				rl_free_line_state();
+				rl_cleanup_after_signal();
+				rl_callback_handler_remove();
+				*signal = 1;
+				completed_input_string = NULL;
+			}
+		}
+	}
+
+	return completed_input_string;
+}
+
+
+#else
+
+/* Interrupt handler */
+
+static jmp_buf jbuf;
+
+/* ARGSUSED */
+static void
+onintr(int sig)
+{
+	longjmp(jbuf, 1);
+}
+
+
+static char *
+readline_until_enter_or_signal(char *prompt, int *signal)
+{
+	PyOS_sighandler_t old_inthandler;
+	char *p;
+    
+	*signal = 0;
+
+	old_inthandler = PyOS_setsig(SIGINT, onintr);
+	if (setjmp(jbuf)) {
+#ifdef HAVE_SIGRELSE
+		/* This seems necessary on SunOS 4.1 (Rasmus Hahn) */
+		sigrelse(SIGINT);
+#endif
+		PyOS_setsig(SIGINT, old_inthandler);
+		*signal = 1;
+		return NULL;
+	}
+	rl_event_hook = PyOS_InputHook;
+	p = readline(prompt);
+	PyOS_setsig(SIGINT, old_inthandler);
+
+    return p;
+}
+#endif /*defined(HAVE_RL_CALLBACK) && defined(HAVE_SELECT) */
+
+
+static char *
+call_readline(FILE *sys_stdin, FILE *sys_stdout, char *prompt)
+{
+	size_t n;
+	char *p, *q;
+	int signal;
+
+#ifdef SAVE_LOCALE
+	char *saved_locale = strdup(setlocale(LC_CTYPE, NULL));
+	if (!saved_locale)
+		Py_FatalError("not enough memory to save locale");
+	setlocale(LC_CTYPE, "");
+#endif
+
+	if (sys_stdin != rl_instream || sys_stdout != rl_outstream) {
+		rl_instream = sys_stdin;
+		rl_outstream = sys_stdout;
+#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
+		rl_prep_terminal (1);
+#endif
+	}
+
+	p = readline_until_enter_or_signal(prompt, &signal);
+	
+	/* we got an interrupt signal */
+	if (signal) {
+		RESTORE_LOCALE(saved_locale)
+		return NULL;
+	}
+
+	/* We got an EOF, return a empty string. */
+	if (p == NULL) {
+		p = PyMem_Malloc(1);
+		if (p != NULL)
+			*p = '\0';
+		RESTORE_LOCALE(saved_locale)
+		return p;
+	}
+
+	/* we have a valid line */
+	n = strlen(p);
+	if (n > 0) {
+		char *line;
+		HISTORY_STATE *state = history_get_history_state();
+		if (state->length > 0)
+			line = history_get(state->length)->line;
+		else
+			line = "";
+		if (strcmp(p, line))
+			add_history(p);
+		/* the history docs don't say so, but the address of state
+		   changes each time history_get_history_state is called
+		   which makes me think it's freshly malloc'd memory...
+		   on the other hand, the address of the last line stays the
+		   same as long as history isn't extended, so it appears to
+		   be malloc'd but managed by the history package... */
+		free(state);
+	}
+	/* Copy the malloc'ed buffer into a PyMem_Malloc'ed one and
+	   release the original. */
+	q = p;
+	p = PyMem_Malloc(n+2);
+	if (p != NULL) {
+		strncpy(p, q, n);
+		p[n] = '\n';
+		p[n+1] = '\0';
+	}
+	free(q);
+	RESTORE_LOCALE(saved_locale)
+	return p;
+}
+
+
+/* Initialize the module */
+
+PyDoc_STRVAR(doc_module,
+"Importing this module enables command line editing using GNU readline.");
+
+PyMODINIT_FUNC
+initreadline(void)
+{
+	PyObject *m;
+
+	m = Py_InitModule4("readline", readline_methods, doc_module,
+			   (PyObject *)NULL, PYTHON_API_VERSION);
+	if (m == NULL)
+		return;
+
+	PyOS_ReadlineFunctionPointer = call_readline;
+	setup_readline();
+}

Added: vendor/Python/current/Modules/resource.c
===================================================================
--- vendor/Python/current/Modules/resource.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/resource.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,325 @@
+
+#include "Python.h"
+#include "structseq.h"
+#include <sys/resource.h>
+#include <sys/time.h>
+#include <string.h>
+#include <errno.h>
+/* for sysconf */
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
+
+/* On some systems, these aren't in any header file.
+   On others they are, with inconsistent prototypes.
+   We declare the (default) return type, to shut up gcc -Wall;
+   but we can't declare the prototype, to avoid errors
+   when the header files declare it different.
+   Worse, on some Linuxes, getpagesize() returns a size_t... */
+
+#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
+
+static PyObject *ResourceError;
+
+PyDoc_STRVAR(struct_rusage__doc__,
+"struct_rusage: Result from getrusage.\n\n"
+"This object may be accessed either as a tuple of\n"
+"    (utime,stime,maxrss,ixrss,idrss,isrss,minflt,majflt,\n"
+"    nswap,inblock,oublock,msgsnd,msgrcv,nsignals,nvcsw,nivcsw)\n"
+"or via the attributes ru_utime, ru_stime, ru_maxrss, and so on.");
+
+static PyStructSequence_Field struct_rusage_fields[] = {
+	{"ru_utime",	"user time used"},
+	{"ru_stime",	"system time used"},
+	{"ru_maxrss",	"max. resident set size"},
+	{"ru_ixrss",	"shared memory size"},
+	{"ru_idrss",	"unshared data size"},
+	{"ru_isrss",	"unshared stack size"},
+	{"ru_minflt",	"page faults not requiring I/O"},
+	{"ru_majflt",	"page faults requiring I/O"},
+	{"ru_nswap",	"number of swap outs"},
+	{"ru_inblock",	"block input operations"},
+	{"ru_oublock",	"block output operations"},
+	{"ru_msgsnd",	"IPC messages sent"},
+	{"ru_msgrcv",	"IPC messages received"},
+	{"ru_nsignals",	"signals received"},
+	{"ru_nvcsw",	"voluntary context switches"},
+	{"ru_nivcsw",	"involuntary context switches"},
+	{0}
+};
+
+static PyStructSequence_Desc struct_rusage_desc = {
+	"resource.struct_rusage",	/* name */
+	struct_rusage__doc__,	/* doc */
+	struct_rusage_fields,	/* fields */
+	16	/* n_in_sequence */
+};
+
+static int initialized;
+static PyTypeObject StructRUsageType;
+
+static PyObject *
+resource_getrusage(PyObject *self, PyObject *args)
+{
+	int who;
+	struct rusage ru;
+	PyObject *result;
+
+	if (!PyArg_ParseTuple(args, "i:getrusage", &who))
+		return NULL;
+
+	if (getrusage(who, &ru) == -1) {
+		if (errno == EINVAL) {
+			PyErr_SetString(PyExc_ValueError,
+					"invalid who parameter");
+			return NULL;
+		} 
+		PyErr_SetFromErrno(ResourceError);
+		return NULL;
+	}
+
+	result = PyStructSequence_New(&StructRUsageType);
+	if (!result)
+		return NULL;
+
+	PyStructSequence_SET_ITEM(result, 0,
+			PyFloat_FromDouble(doubletime(ru.ru_utime)));
+	PyStructSequence_SET_ITEM(result, 1,
+			PyFloat_FromDouble(doubletime(ru.ru_stime)));
+	PyStructSequence_SET_ITEM(result, 2, PyInt_FromLong(ru.ru_maxrss));
+	PyStructSequence_SET_ITEM(result, 3, PyInt_FromLong(ru.ru_ixrss));
+	PyStructSequence_SET_ITEM(result, 4, PyInt_FromLong(ru.ru_idrss));
+	PyStructSequence_SET_ITEM(result, 5, PyInt_FromLong(ru.ru_isrss));
+	PyStructSequence_SET_ITEM(result, 6, PyInt_FromLong(ru.ru_minflt));
+	PyStructSequence_SET_ITEM(result, 7, PyInt_FromLong(ru.ru_majflt));
+	PyStructSequence_SET_ITEM(result, 8, PyInt_FromLong(ru.ru_nswap));
+	PyStructSequence_SET_ITEM(result, 9, PyInt_FromLong(ru.ru_inblock));
+	PyStructSequence_SET_ITEM(result, 10, PyInt_FromLong(ru.ru_oublock));
+	PyStructSequence_SET_ITEM(result, 11, PyInt_FromLong(ru.ru_msgsnd));
+	PyStructSequence_SET_ITEM(result, 12, PyInt_FromLong(ru.ru_msgrcv));
+	PyStructSequence_SET_ITEM(result, 13, PyInt_FromLong(ru.ru_nsignals));
+	PyStructSequence_SET_ITEM(result, 14, PyInt_FromLong(ru.ru_nvcsw));
+	PyStructSequence_SET_ITEM(result, 15, PyInt_FromLong(ru.ru_nivcsw));
+
+	if (PyErr_Occurred()) {
+		Py_DECREF(result);
+		return NULL;
+	}
+
+	return result;
+}
+
+
+static PyObject *
+resource_getrlimit(PyObject *self, PyObject *args)
+{
+	struct rlimit rl;
+	int resource;
+
+	if (!PyArg_ParseTuple(args, "i:getrlimit", &resource)) 
+		return NULL;
+
+	if (resource < 0 || resource >= RLIM_NLIMITS) {
+		PyErr_SetString(PyExc_ValueError,
+				"invalid resource specified");
+		return NULL;
+	}
+
+	if (getrlimit(resource, &rl) == -1) {
+		PyErr_SetFromErrno(ResourceError);
+		return NULL;
+	}
+
+#if defined(HAVE_LONG_LONG)
+	if (sizeof(rl.rlim_cur) > sizeof(long)) {
+		return Py_BuildValue("LL",
+				     (PY_LONG_LONG) rl.rlim_cur,
+				     (PY_LONG_LONG) rl.rlim_max);
+	}
+#endif
+	return Py_BuildValue("ll", (long) rl.rlim_cur, (long) rl.rlim_max);
+}
+
+static PyObject *
+resource_setrlimit(PyObject *self, PyObject *args)
+{
+	struct rlimit rl;
+	int resource;
+	PyObject *curobj, *maxobj;
+
+	if (!PyArg_ParseTuple(args, "i(OO):setrlimit", 
+			      &resource, &curobj, &maxobj))
+		return NULL;
+
+	if (resource < 0 || resource >= RLIM_NLIMITS) {
+		PyErr_SetString(PyExc_ValueError,
+				"invalid resource specified");
+		return NULL;
+	}
+
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+	rl.rlim_cur = PyInt_AsLong(curobj);
+	if (rl.rlim_cur == -1 && PyErr_Occurred())
+	    return NULL;
+	rl.rlim_max = PyInt_AsLong(maxobj);
+	if (rl.rlim_max == -1 && PyErr_Occurred())
+	    return NULL;
+#else
+	/* The limits are probably bigger than a long */
+	rl.rlim_cur = PyLong_Check(curobj) ?
+		PyLong_AsLongLong(curobj) : PyInt_AsLong(curobj);
+	if (rl.rlim_cur == -1 && PyErr_Occurred())
+	    return NULL;
+	rl.rlim_max = PyLong_Check(maxobj) ?
+		PyLong_AsLongLong(maxobj) : PyInt_AsLong(maxobj);
+	if (rl.rlim_max == -1 && PyErr_Occurred())
+	    return NULL;
+#endif
+
+	rl.rlim_cur = rl.rlim_cur & RLIM_INFINITY;
+	rl.rlim_max = rl.rlim_max & RLIM_INFINITY;
+	if (setrlimit(resource, &rl) == -1) {
+		if (errno == EINVAL) 
+			PyErr_SetString(PyExc_ValueError,
+					"current limit exceeds maximum limit");
+		else if (errno == EPERM)
+			PyErr_SetString(PyExc_ValueError,
+					"not allowed to raise maximum limit");
+		else
+			PyErr_SetFromErrno(ResourceError);
+		return NULL;
+	}
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+resource_getpagesize(PyObject *self, PyObject *unused)
+{
+	long pagesize = 0;
+#if defined(HAVE_GETPAGESIZE)
+	pagesize = getpagesize();
+#elif defined(HAVE_SYSCONF)
+#if defined(_SC_PAGE_SIZE)
+	pagesize = sysconf(_SC_PAGE_SIZE);
+#else
+	/* Irix 5.3 has _SC_PAGESIZE, but not _SC_PAGE_SIZE */
+	pagesize = sysconf(_SC_PAGESIZE);
+#endif
+#endif
+	return Py_BuildValue("i", pagesize);
+
+}
+
+/* List of functions */
+
+static struct PyMethodDef
+resource_methods[] = {
+	{"getrusage",    resource_getrusage,   METH_VARARGS},
+	{"getrlimit",    resource_getrlimit,   METH_VARARGS},
+	{"setrlimit",    resource_setrlimit,   METH_VARARGS},
+	{"getpagesize",  resource_getpagesize, METH_NOARGS},
+	{NULL, NULL}			     /* sentinel */
+};
+
+
+/* Module initialization */
+
+PyMODINIT_FUNC
+initresource(void)
+{
+	PyObject *m, *v;
+
+	/* Create the module and add the functions */
+	m = Py_InitModule("resource", resource_methods);
+	if (m == NULL)
+		return;
+
+	/* Add some symbolic constants to the module */
+	if (ResourceError == NULL) {
+		ResourceError = PyErr_NewException("resource.error",
+						   NULL, NULL);
+	}
+	Py_INCREF(ResourceError);
+	PyModule_AddObject(m, "error", ResourceError);
+	if (!initialized)
+		PyStructSequence_InitType(&StructRUsageType, 
+					  &struct_rusage_desc);
+	Py_INCREF(&StructRUsageType);
+ 	PyModule_AddObject(m, "struct_rusage", 
+			   (PyObject*) &StructRUsageType);
+
+	/* insert constants */
+#ifdef RLIMIT_CPU
+	PyModule_AddIntConstant(m, "RLIMIT_CPU", RLIMIT_CPU);
+#endif
+
+#ifdef RLIMIT_FSIZE
+	PyModule_AddIntConstant(m, "RLIMIT_FSIZE", RLIMIT_FSIZE);
+#endif
+
+#ifdef RLIMIT_DATA
+	PyModule_AddIntConstant(m, "RLIMIT_DATA", RLIMIT_DATA);
+#endif
+
+#ifdef RLIMIT_STACK
+	PyModule_AddIntConstant(m, "RLIMIT_STACK", RLIMIT_STACK);
+#endif
+
+#ifdef RLIMIT_CORE
+	PyModule_AddIntConstant(m, "RLIMIT_CORE", RLIMIT_CORE);
+#endif
+
+#ifdef RLIMIT_NOFILE
+	PyModule_AddIntConstant(m, "RLIMIT_NOFILE", RLIMIT_NOFILE);
+#endif
+
+#ifdef RLIMIT_OFILE
+	PyModule_AddIntConstant(m, "RLIMIT_OFILE", RLIMIT_OFILE);
+#endif
+
+#ifdef RLIMIT_VMEM
+	PyModule_AddIntConstant(m, "RLIMIT_VMEM", RLIMIT_VMEM);
+#endif
+
+#ifdef RLIMIT_AS
+	PyModule_AddIntConstant(m, "RLIMIT_AS", RLIMIT_AS);
+#endif
+
+#ifdef RLIMIT_RSS
+	PyModule_AddIntConstant(m, "RLIMIT_RSS", RLIMIT_RSS);
+#endif
+
+#ifdef RLIMIT_NPROC
+	PyModule_AddIntConstant(m, "RLIMIT_NPROC", RLIMIT_NPROC);
+#endif
+
+#ifdef RLIMIT_MEMLOCK
+	PyModule_AddIntConstant(m, "RLIMIT_MEMLOCK", RLIMIT_MEMLOCK);
+#endif
+
+#ifdef RUSAGE_SELF
+	PyModule_AddIntConstant(m, "RUSAGE_SELF", RUSAGE_SELF);
+#endif
+
+#ifdef RUSAGE_CHILDREN
+	PyModule_AddIntConstant(m, "RUSAGE_CHILDREN", RUSAGE_CHILDREN);
+#endif
+
+#ifdef RUSAGE_BOTH
+	PyModule_AddIntConstant(m, "RUSAGE_BOTH", RUSAGE_BOTH);
+#endif
+
+#if defined(HAVE_LONG_LONG)
+	if (sizeof(RLIM_INFINITY) > sizeof(long)) {
+		v = PyLong_FromLongLong((PY_LONG_LONG) RLIM_INFINITY);
+	} else 
+#endif
+	{
+		v = PyInt_FromLong((long) RLIM_INFINITY);
+	}
+	if (v) {
+		PyModule_AddObject(m, "RLIM_INFINITY", v);
+	}
+	initialized = 1;
+}

Added: vendor/Python/current/Modules/rgbimgmodule.c
===================================================================
--- vendor/Python/current/Modules/rgbimgmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/rgbimgmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,780 @@
+/*
+ *   	fastimg -
+ *		Faster reading and writing of image files.
+ *
+ *      This code should work on machines with any byte order.
+ *
+ *	Could someone make this run real fast using multiple processors 
+ *	or how about using memory mapped files to speed it up?
+ *
+ *				Paul Haeberli - 1991
+ *
+ *	Changed to return sizes.
+ *				Sjoerd Mullender - 1993
+ *	Changed to incorporate into Python.
+ *				Sjoerd Mullender - 1993
+ */
+#include "Python.h"
+
+#if SIZEOF_INT == 4
+typedef int Py_Int32;
+typedef unsigned int Py_UInt32;
+#else
+#if SIZEOF_LONG == 4
+typedef long Py_Int32;
+typedef unsigned long Py_UInt32;
+#else
+#error "No 4-byte integral type"
+#endif
+#endif
+
+#include <string.h>
+
+/*
+ *	from image.h
+ *
+ */
+typedef struct {
+	unsigned short	imagic;		/* stuff saved on disk . . */
+	unsigned short 	type;
+	unsigned short 	dim;
+	unsigned short 	xsize;
+	unsigned short 	ysize;
+	unsigned short 	zsize;
+	Py_UInt32 	min;
+	Py_UInt32 	max;
+	Py_UInt32	wastebytes;	
+	char 		name[80];
+	Py_UInt32	colormap;
+
+	Py_Int32	file;		/* stuff used in core only */
+	unsigned short 	flags;
+	short		dorev;
+	short		x;
+	short		y;
+	short		z;
+	short		cnt;
+	unsigned short	*ptr;
+	unsigned short	*base;
+	unsigned short	*tmpbuf;
+	Py_UInt32	offset;
+	Py_UInt32	rleend;		/* for rle images */
+	Py_UInt32	*rowstart;	/* for rle images */
+	Py_Int32	*rowsize;	/* for rle images */
+} IMAGE;
+
+#define IMAGIC 	0732
+
+#define TYPEMASK		0xff00
+#define BPPMASK			0x00ff
+#define ITYPE_VERBATIM		0x0000
+#define ITYPE_RLE		0x0100
+#define ISRLE(type)		(((type) & 0xff00) == ITYPE_RLE)
+#define ISVERBATIM(type)	(((type) & 0xff00) == ITYPE_VERBATIM)
+#define BPP(type)		((type) & BPPMASK)
+#define RLE(bpp)		(ITYPE_RLE | (bpp))
+#define VERBATIM(bpp)		(ITYPE_VERBATIM | (bpp))
+/*
+ *	end of image.h stuff
+ *
+ */
+
+#define RINTLUM (79)
+#define GINTLUM (156)
+#define BINTLUM (21)
+
+#define ILUM(r,g,b)     ((int)(RINTLUM*(r)+GINTLUM*(g)+BINTLUM*(b))>>8)
+
+#define OFFSET_R	3	/* this is byte order dependent */
+#define OFFSET_G	2
+#define OFFSET_B	1
+#define OFFSET_A	0
+
+#define CHANOFFSET(z)	(3-(z))	/* this is byte order dependent */
+
+static void expandrow(unsigned char *, unsigned char *, int);
+static void setalpha(unsigned char *, int);
+static void copybw(Py_Int32 *, int);
+static void interleaverow(unsigned char*, unsigned char*, int, int);
+static int compressrow(unsigned char *, unsigned char *, int, int);
+static void lumrow(unsigned char *, unsigned char *, int);
+
+#ifdef ADD_TAGS
+#define TAGLEN	(5)
+#else
+#define TAGLEN	(0)
+#endif
+
+static PyObject *ImgfileError;
+
+static int reverse_order;
+
+#ifdef ADD_TAGS
+/*
+ *	addlongimgtag - 
+ *		this is used to extract image data from core dumps.
+ *
+ */
+static void 
+addlongimgtag(Py_UInt32 *dptr, int xsize, int ysize)
+{
+	dptr = dptr + (xsize * ysize);
+	dptr[0] = 0x12345678;
+	dptr[1] = 0x59493333;
+	dptr[2] = 0x69434222;
+	dptr[3] = xsize;
+	dptr[4] = ysize;
+}
+#endif
+
+/*
+ *	byte order independent read/write of shorts and longs.
+ *
+ */
+static unsigned short
+getshort(FILE *inf)
+{
+	unsigned char buf[2];
+
+	fread(buf, 2, 1, inf);
+	return (buf[0] << 8) + (buf[1] << 0);
+}
+
+static Py_UInt32
+getlong(FILE *inf)
+{
+	unsigned char buf[4];
+
+	fread(buf, 4, 1, inf);
+	return (buf[0] << 24) + (buf[1] << 16) + (buf[2] << 8) + (buf[3] << 0);
+}
+
+static void
+putshort(FILE *outf, unsigned short val)
+{
+	unsigned char buf[2];
+
+	buf[0] = (val >> 8);
+	buf[1] = (val >> 0);
+	fwrite(buf, 2, 1, outf);
+}
+
+static int
+putlong(FILE *outf, Py_UInt32 val)
+{
+	unsigned char buf[4];
+
+	buf[0] = (unsigned char) (val >> 24);
+	buf[1] = (unsigned char) (val >> 16);
+	buf[2] = (unsigned char) (val >> 8);
+	buf[3] = (unsigned char) (val >> 0);
+	return (int)fwrite(buf, 4, 1, outf);
+}
+
+static void
+readheader(FILE *inf, IMAGE *image)
+{
+	memset(image ,0, sizeof(IMAGE));
+	image->imagic = getshort(inf);
+	image->type   = getshort(inf);
+	image->dim    = getshort(inf);
+	image->xsize  = getshort(inf);
+	image->ysize  = getshort(inf);
+	image->zsize  = getshort(inf);
+}
+
+static int
+writeheader(FILE *outf, IMAGE *image)
+{
+	IMAGE t;
+
+	memset(&t, 0, sizeof(IMAGE));
+	fwrite(&t, sizeof(IMAGE), 1, outf);
+	fseek(outf, 0, SEEK_SET);
+	putshort(outf, image->imagic);
+	putshort(outf, image->type);
+	putshort(outf, image->dim);
+	putshort(outf, image->xsize);
+	putshort(outf, image->ysize);
+	putshort(outf, image->zsize);
+	putlong(outf, image->min);
+	putlong(outf, image->max);
+	putlong(outf, 0);
+	return (int)fwrite("no name", 8, 1, outf);
+}
+
+static int
+writetab(FILE *outf, /*unsigned*/ Py_Int32 *tab, int len)
+{
+	int r = 0;
+
+	while(len) {
+		r = putlong(outf, *tab++);
+		len--;
+	}
+	return r;
+}
+
+static void
+readtab(FILE *inf, /*unsigned*/ Py_Int32 *tab, int len)
+{
+	while(len) {
+		*tab++ = getlong(inf);
+		len--;
+	}
+}
+
+/*
+ *	sizeofimage - 
+ *		return the xsize and ysize of an iris image file.
+ *
+ */
+static PyObject *
+sizeofimage(PyObject *self, PyObject *args)
+{
+	char *name;
+	IMAGE image;
+	FILE *inf;
+
+	if (!PyArg_ParseTuple(args, "s:sizeofimage", &name))
+		return NULL;
+
+	inf = fopen(name, "rb");
+	if (!inf) {
+		PyErr_SetString(ImgfileError, "can't open image file");
+		return NULL;
+	}
+	readheader(inf, &image);
+	fclose(inf);
+	if (image.imagic != IMAGIC) {
+		PyErr_SetString(ImgfileError,
+				"bad magic number in image file");
+		return NULL;
+	}
+	return Py_BuildValue("(ii)", image.xsize, image.ysize);
+}
+
+/*
+ *	longimagedata - 
+ *		read in a B/W RGB or RGBA iris image file and return a 
+ *	pointer to an array of longs.
+ *
+ */
+static PyObject *
+longimagedata(PyObject *self, PyObject *args)
+{
+	char *name;
+	unsigned char *base, *lptr;
+	unsigned char *rledat = NULL, *verdat = NULL;
+	Py_Int32 *starttab = NULL, *lengthtab = NULL;
+	FILE *inf = NULL;
+	IMAGE image;
+	int y, z, tablen;
+	int xsize, ysize, zsize;
+	int bpp, rle, cur, badorder;
+	int rlebuflen;
+	PyObject *rv = NULL;
+
+	if (!PyArg_ParseTuple(args, "s:longimagedata", &name))
+		return NULL;
+
+	inf = fopen(name,"rb");
+	if (!inf) {
+		PyErr_SetString(ImgfileError, "can't open image file");
+		return NULL;
+	}
+	readheader(inf,&image);
+	if (image.imagic != IMAGIC) {
+		PyErr_SetString(ImgfileError,
+				"bad magic number in image file");
+		goto finally;
+	}
+	rle = ISRLE(image.type);
+	bpp = BPP(image.type);
+	if (bpp != 1) {
+		PyErr_SetString(ImgfileError,
+				"image must have 1 byte per pix chan");
+		goto finally;
+	}
+	xsize = image.xsize;
+	ysize = image.ysize;
+	zsize = image.zsize;
+	if (rle) {
+		tablen = ysize * zsize * sizeof(Py_Int32);
+		starttab = (Py_Int32 *)malloc(tablen);
+		lengthtab = (Py_Int32 *)malloc(tablen);
+		rlebuflen = (int) (1.05 * xsize +10);
+		rledat = (unsigned char *)malloc(rlebuflen);
+		if (!starttab || !lengthtab || !rledat) {
+			PyErr_NoMemory();
+			goto finally;
+		}
+		
+		fseek(inf, 512, SEEK_SET);
+		readtab(inf, starttab, ysize*zsize);
+		readtab(inf, lengthtab, ysize*zsize);
+
+		/* check data order */
+		cur = 0;
+		badorder = 0;
+		for(y = 0; y < ysize; y++) {
+			for(z = 0; z < zsize; z++) {
+				if (starttab[y + z * ysize] < cur) {
+					badorder = 1;
+					break;
+				}
+				cur = starttab[y +z * ysize];
+			}
+			if (badorder)
+				break;
+		}
+
+		fseek(inf, 512 + 2 * tablen, SEEK_SET);
+		cur = 512 + 2 * tablen;
+		rv = PyString_FromStringAndSize((char *)NULL,
+				      (xsize * ysize + TAGLEN) * sizeof(Py_Int32));
+		if (rv == NULL)
+			goto finally;
+
+		base = (unsigned char *) PyString_AsString(rv);
+#ifdef ADD_TAGS
+		addlongimgtag(base,xsize,ysize);
+#endif
+		if (badorder) {
+			for (z = 0; z < zsize; z++) {
+				lptr = base;
+				if (reverse_order)
+					lptr += (ysize - 1) * xsize
+						* sizeof(Py_UInt32);
+				for (y = 0; y < ysize; y++) {
+					int idx = y + z * ysize;
+					if (cur != starttab[idx]) {
+						fseek(inf,starttab[idx],
+						      SEEK_SET);
+						cur = starttab[idx];
+					}
+					if (lengthtab[idx] > rlebuflen) {
+						PyErr_SetString(ImgfileError,
+							"rlebuf is too small");
+						Py_DECREF(rv);
+						rv = NULL;
+						goto finally;
+					}
+					fread(rledat, lengthtab[idx], 1, inf);
+					cur += lengthtab[idx];
+					expandrow(lptr, rledat, 3-z);
+					if (reverse_order)
+						lptr -= xsize
+						      * sizeof(Py_UInt32);
+					else
+						lptr += xsize
+						      * sizeof(Py_UInt32);
+				}
+			}
+		} else {
+			lptr = base;
+			if (reverse_order)
+				lptr += (ysize - 1) * xsize
+					* sizeof(Py_UInt32);
+			for (y = 0; y < ysize; y++) {
+				for(z = 0; z < zsize; z++) {
+					int idx = y + z * ysize;
+					if (cur != starttab[idx]) {
+						fseek(inf, starttab[idx],
+						      SEEK_SET);
+						cur = starttab[idx];
+					}
+					fread(rledat, lengthtab[idx], 1, inf);
+					cur += lengthtab[idx];
+					expandrow(lptr, rledat, 3-z);
+				}
+				if (reverse_order)
+					lptr -= xsize * sizeof(Py_UInt32);
+				else
+					lptr += xsize * sizeof(Py_UInt32);
+			}
+		}
+		if (zsize == 3) 
+			setalpha(base, xsize * ysize);
+		else if (zsize < 3) 
+			copybw((Py_Int32 *) base, xsize * ysize);
+	}
+	else {
+		rv = PyString_FromStringAndSize((char *) 0,
+					   (xsize*ysize+TAGLEN)*sizeof(Py_Int32));
+		if (rv == NULL)
+			goto finally;
+
+		base = (unsigned char *) PyString_AsString(rv);
+#ifdef ADD_TAGS
+		addlongimgtag(base, xsize, ysize);
+#endif
+		verdat = (unsigned char *)malloc(xsize);
+		if (!verdat) {
+			Py_CLEAR(rv);
+			goto finally;
+		}
+
+		fseek(inf, 512, SEEK_SET);
+		for (z = 0; z < zsize; z++) {
+			lptr = base;
+			if (reverse_order)
+				lptr += (ysize - 1) * xsize
+				        * sizeof(Py_UInt32);
+			for (y = 0; y < ysize; y++) {
+				fread(verdat, xsize, 1, inf);
+				interleaverow(lptr, verdat, 3-z, xsize);
+				if (reverse_order)
+					lptr -= xsize * sizeof(Py_UInt32);
+				else
+					lptr += xsize * sizeof(Py_UInt32);
+			}
+		}
+		if (zsize == 3)
+			setalpha(base, xsize * ysize);
+		else if (zsize < 3) 
+			copybw((Py_Int32 *) base, xsize * ysize);
+	}
+  finally:
+	if (starttab)
+		free(starttab);
+	if (lengthtab)
+		free(lengthtab);
+	if (rledat)
+		free(rledat);
+	if (verdat)
+		free(verdat);
+	fclose(inf);
+	return rv;
+}
+
+/* static utility functions for longimagedata */
+
+static void
+interleaverow(unsigned char *lptr, unsigned char *cptr, int z, int n)
+{
+	lptr += z;
+	while (n--) {
+		*lptr = *cptr++;
+		lptr += 4;
+	}
+}
+
+static void
+copybw(Py_Int32 *lptr, int n)
+{
+	while (n >= 8) {
+		lptr[0] = 0xff000000 + (0x010101 * (lptr[0] & 0xff));
+		lptr[1] = 0xff000000 + (0x010101 * (lptr[1] & 0xff));
+		lptr[2] = 0xff000000 + (0x010101 * (lptr[2] & 0xff));
+		lptr[3] = 0xff000000 + (0x010101 * (lptr[3] & 0xff));
+		lptr[4] = 0xff000000 + (0x010101 * (lptr[4] & 0xff));
+		lptr[5] = 0xff000000 + (0x010101 * (lptr[5] & 0xff));
+		lptr[6] = 0xff000000 + (0x010101 * (lptr[6] & 0xff));
+		lptr[7] = 0xff000000 + (0x010101 * (lptr[7] & 0xff));
+		lptr += 8;
+		n -= 8;
+	}
+	while (n--) {
+		*lptr = 0xff000000 + (0x010101 * (*lptr&0xff));
+		lptr++;
+	}
+}
+
+static void
+setalpha(unsigned char *lptr, int n)
+{
+	while (n >= 8) {
+		lptr[0 * 4] = 0xff;
+		lptr[1 * 4] = 0xff;
+		lptr[2 * 4] = 0xff;
+		lptr[3 * 4] = 0xff;
+		lptr[4 * 4] = 0xff;
+		lptr[5 * 4] = 0xff;
+		lptr[6 * 4] = 0xff;
+		lptr[7 * 4] = 0xff;
+		lptr += 4 * 8;
+		n -= 8;
+	}
+	while (n--) {
+		*lptr = 0xff;
+		lptr += 4;
+	}
+}
+
+static void
+expandrow(unsigned char *optr, unsigned char *iptr, int z)
+{
+	unsigned char pixel, count;
+
+	optr += z;
+	while (1) {
+		pixel = *iptr++;
+		if (!(count = (pixel & 0x7f)))
+			return;
+		if (pixel & 0x80) {
+			while (count >= 8) {
+				optr[0 * 4] = iptr[0];
+				optr[1 * 4] = iptr[1];
+				optr[2 * 4] = iptr[2];
+				optr[3 * 4] = iptr[3];
+				optr[4 * 4] = iptr[4];
+				optr[5 * 4] = iptr[5];
+				optr[6 * 4] = iptr[6];
+				optr[7 * 4] = iptr[7];
+				optr += 8 * 4;
+				iptr += 8;
+				count -= 8;
+			}
+			while (count--) {
+				*optr = *iptr++;
+				optr += 4;
+			}
+		}
+		else {
+			pixel = *iptr++;
+			while (count >= 8) {
+				optr[0 * 4] = pixel;
+				optr[1 * 4] = pixel;
+				optr[2 * 4] = pixel;
+				optr[3 * 4] = pixel;
+				optr[4 * 4] = pixel;
+				optr[5 * 4] = pixel;
+				optr[6 * 4] = pixel;
+				optr[7 * 4] = pixel;
+				optr += 8 * 4;
+				count -= 8;
+			}
+			while (count--) {
+				*optr = pixel;
+				optr += 4;
+			}
+		}
+	}
+}
+
+/*
+ *	longstoimage -
+ *		copy an array of longs to an iris image file.  Each long
+ *	represents one pixel.  xsize and ysize specify the dimensions of
+ *	the pixel array.  zsize specifies what kind of image file to
+ *	write out.  if zsize is 1, the luminance of the pixels are
+ *	calculated, and a single channel black and white image is saved.
+ *	If zsize is 3, an RGB image file is saved.  If zsize is 4, an
+ *	RGBA image file is saved.
+ *
+ */
+static PyObject *
+longstoimage(PyObject *self, PyObject *args)
+{
+	unsigned char *lptr;
+	char *name;
+	int xsize, ysize, zsize;
+	FILE *outf = NULL;
+	IMAGE image;
+	int tablen, y, z, pos, len;
+	Py_Int32 *starttab = NULL, *lengthtab = NULL;
+	unsigned char *rlebuf = NULL;
+	unsigned char *lumbuf = NULL;
+	int rlebuflen;
+	Py_ssize_t goodwrite;
+	PyObject *retval = NULL;
+
+	if (!PyArg_ParseTuple(args, "s#iiis:longstoimage", &lptr, &len,
+			      &xsize, &ysize, &zsize, &name))
+		return NULL;
+
+	goodwrite = 1;
+	outf = fopen(name, "wb");
+	if (!outf) {
+		PyErr_SetString(ImgfileError, "can't open output file");
+		return NULL;
+	}
+	tablen = ysize * zsize * sizeof(Py_Int32);
+
+	starttab = (Py_Int32 *)malloc(tablen);
+	lengthtab = (Py_Int32 *)malloc(tablen);
+	rlebuflen = (int) (1.05 * xsize + 10);
+	rlebuf = (unsigned char *)malloc(rlebuflen);
+	lumbuf = (unsigned char *)malloc(xsize * sizeof(Py_Int32));
+	if (!starttab || !lengthtab || !rlebuf || !lumbuf) {
+		PyErr_NoMemory();
+		goto finally;
+	}
+	
+	memset(&image, 0, sizeof(IMAGE));
+	image.imagic = IMAGIC; 
+	image.type = RLE(1);
+	if (zsize>1)
+		image.dim = 3;
+	else
+		image.dim = 2;
+	image.xsize = xsize;
+	image.ysize = ysize;
+	image.zsize = zsize;
+	image.min = 0;
+	image.max = 255;
+	goodwrite *= writeheader(outf, &image);
+	pos = 512 + 2 * tablen;
+	fseek(outf, pos, SEEK_SET);
+	if (reverse_order)
+		lptr += (ysize - 1) * xsize * sizeof(Py_UInt32);
+	for (y = 0; y < ysize; y++) {
+		for (z = 0; z < zsize; z++) {
+			if (zsize == 1) {
+				lumrow(lptr, lumbuf, xsize);
+				len = compressrow(lumbuf, rlebuf,
+						  CHANOFFSET(z), xsize);
+			} else {
+				len = compressrow(lptr, rlebuf,
+						  CHANOFFSET(z), xsize);
+			}
+			if(len > rlebuflen) {
+				PyErr_SetString(ImgfileError,
+						"rlebuf is too small");
+				goto finally;
+			}
+			goodwrite *= fwrite(rlebuf, len, 1, outf);
+			starttab[y + z * ysize] = pos;
+			lengthtab[y + z * ysize] = len;
+			pos += len;
+		}
+		if (reverse_order)
+			lptr -= xsize * sizeof(Py_UInt32);
+		else
+			lptr += xsize * sizeof(Py_UInt32);
+	}
+
+	fseek(outf, 512, SEEK_SET);
+	goodwrite *= writetab(outf, starttab, ysize*zsize);
+	goodwrite *= writetab(outf, lengthtab, ysize*zsize);
+	if (goodwrite) {
+		Py_INCREF(Py_None);
+		retval = Py_None;
+	} else
+		PyErr_SetString(ImgfileError, "not enough space for image");
+
+  finally:
+	fclose(outf);
+	free(starttab);
+	free(lengthtab);
+	free(rlebuf);
+	free(lumbuf);
+	return retval;
+}
+
+/* static utility functions for longstoimage */
+
+static void
+lumrow(unsigned char *rgbptr, unsigned char *lumptr, int n)
+{
+	lumptr += CHANOFFSET(0);
+	while (n--) {
+		*lumptr = ILUM(rgbptr[OFFSET_R],
+			       rgbptr[OFFSET_G],
+			       rgbptr[OFFSET_B]);
+		lumptr += 4;
+		rgbptr += 4;
+	}
+}
+
+static int
+compressrow(unsigned char *lbuf, unsigned char *rlebuf, int z, int cnt)
+{
+	unsigned char *iptr, *ibufend, *sptr, *optr;
+	short todo, cc;							
+	Py_Int32 count;
+
+	lbuf += z;
+	iptr = lbuf;
+	ibufend = iptr + cnt * 4;
+	optr = rlebuf;
+
+	while(iptr < ibufend) {
+		sptr = iptr;
+		iptr += 8;
+		while ((iptr<ibufend) &&
+		       ((iptr[-8]!=iptr[-4]) ||(iptr[-4]!=iptr[0])))
+		{
+			iptr += 4;
+		}
+		iptr -= 8;
+		count = (iptr - sptr) / 4;
+		while (count) {
+			todo = count > 126 ? 126 : (short)count;
+			count -= todo;
+			*optr++ = 0x80 | todo;
+			while (todo > 8) {
+				optr[0] = sptr[0 * 4];
+				optr[1] = sptr[1 * 4];
+				optr[2] = sptr[2 * 4];
+				optr[3] = sptr[3 * 4];
+				optr[4] = sptr[4 * 4];
+				optr[5] = sptr[5 * 4];
+				optr[6] = sptr[6 * 4];
+				optr[7] = sptr[7 * 4];
+				optr += 8;
+				sptr += 8 * 4;
+				todo -= 8;
+			}
+			while (todo--) {
+				*optr++ = *sptr;
+				sptr += 4;
+			}
+		}
+		sptr = iptr;
+		cc = *iptr;
+		iptr += 4;
+		while ((iptr < ibufend) && (*iptr == cc))
+			iptr += 4;
+		count = (iptr - sptr) / 4;
+		while (count) {
+			todo = count > 126 ? 126 : (short)count;
+			count -= todo;
+			*optr++ = (unsigned char) todo;
+			*optr++ = (unsigned char) cc;
+		}
+	}
+	*optr++ = 0;
+	return optr - (unsigned char *)rlebuf;
+}
+
+static PyObject *
+ttob(PyObject *self, PyObject *args)
+{
+	int order, oldorder;
+
+	if (!PyArg_ParseTuple(args, "i:ttob", &order))
+		return NULL;
+	oldorder = reverse_order;
+	reverse_order = order;
+	return PyInt_FromLong(oldorder);
+}
+
+static PyMethodDef
+rgbimg_methods[] = {
+	{"sizeofimage",	   sizeofimage, METH_VARARGS},
+	{"longimagedata",  longimagedata, METH_VARARGS},
+	{"longstoimage",   longstoimage, METH_VARARGS},
+	{"ttob",	   ttob, METH_VARARGS},
+	{NULL,             NULL}	     /* sentinel */
+};
+
+
+PyMODINIT_FUNC
+initrgbimg(void)
+{
+	PyObject *m, *d;
+	m = Py_InitModule("rgbimg", rgbimg_methods);
+	if (m == NULL)
+		return;
+
+	if (PyErr_Warn(PyExc_DeprecationWarning, 
+				"the rgbimg module is deprecated"))
+		return;
+	
+	d = PyModule_GetDict(m);
+	ImgfileError = PyErr_NewException("rgbimg.error", NULL, NULL);
+	if (ImgfileError != NULL)
+		PyDict_SetItemString(d, "error", ImgfileError);
+}

Added: vendor/Python/current/Modules/rotatingtree.c
===================================================================
--- vendor/Python/current/Modules/rotatingtree.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/rotatingtree.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,121 @@
+#include "rotatingtree.h"
+
+#define KEY_LOWER_THAN(key1, key2)  ((char*)(key1) < (char*)(key2))
+
+/* The randombits() function below is a fast-and-dirty generator that
+ * is probably irregular enough for our purposes.  Note that it's biased:
+ * I think that ones are slightly more probable than zeroes.  It's not
+ * important here, though.
+ */
+
+static unsigned int random_value = 1;
+static unsigned int random_stream = 0;
+
+static int
+randombits(int bits)
+{
+	int result;
+	if (random_stream < (1U << bits)) {
+		random_value *= 1082527;
+		random_stream = random_value;
+	}
+	result = random_stream & ((1<<bits)-1);
+	random_stream >>= bits;
+	return result;
+}
+
+
+/* Insert a new node into the tree.
+   (*root) is modified to point to the new root. */
+void
+RotatingTree_Add(rotating_node_t **root, rotating_node_t *node)
+{
+	while (*root != NULL) {
+		if (KEY_LOWER_THAN(node->key, (*root)->key))
+			root = &((*root)->left);
+		else
+			root = &((*root)->right);
+	}
+	node->left = NULL;
+	node->right = NULL;
+	*root = node;
+}
+
+/* Locate the node with the given key.  This is the most complicated
+   function because it occasionally rebalances the tree to move the
+   resulting node closer to the root. */
+rotating_node_t *
+RotatingTree_Get(rotating_node_t **root, void *key)
+{
+	if (randombits(3) != 4) {
+		/* Fast path, no rebalancing */
+		rotating_node_t *node = *root;
+		while (node != NULL) {
+			if (node->key == key)
+				return node;
+			if (KEY_LOWER_THAN(key, node->key))
+				node = node->left;
+			else
+				node = node->right;
+		}
+		return NULL;
+	}
+	else {
+		rotating_node_t **pnode = root;
+		rotating_node_t *node = *pnode;
+		rotating_node_t *next;
+		int rotate;
+		if (node == NULL)
+			return NULL;
+		while (1) {
+			if (node->key == key)
+				return node;
+			rotate = !randombits(1);
+			if (KEY_LOWER_THAN(key, node->key)) {
+				next = node->left;
+				if (next == NULL)
+					return NULL;
+				if (rotate) {
+					node->left = next->right;
+					next->right = node;
+					*pnode = next;
+				}
+				else
+					pnode = &(node->left);
+			}
+			else {
+				next = node->right;
+				if (next == NULL)
+					return NULL;
+				if (rotate) {
+					node->right = next->left;
+					next->left = node;
+					*pnode = next;
+				}
+				else
+					pnode = &(node->right);
+			}
+			node = next;
+		}
+	}
+}
+
+/* Enumerate all nodes in the tree.  The callback enumfn() should return
+   zero to continue the enumeration, or non-zero to interrupt it.
+   A non-zero value is directly returned by RotatingTree_Enum(). */
+int
+RotatingTree_Enum(rotating_node_t *root, rotating_tree_enum_fn enumfn,
+		  void *arg)
+{
+	int result;
+	rotating_node_t *node;
+	while (root != NULL) {
+		result = RotatingTree_Enum(root->left, enumfn, arg);
+		if (result != 0) return result;
+		node = root->right;
+		result = enumfn(root, arg);
+		if (result != 0) return result;
+		root = node;
+	}
+	return 0;
+}

Added: vendor/Python/current/Modules/rotatingtree.h
===================================================================
--- vendor/Python/current/Modules/rotatingtree.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/rotatingtree.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,27 @@
+/* "Rotating trees" (Armin Rigo)
+ *
+ * Google "splay trees" for the general idea.
+ *
+ * It's a dict-like data structure that works best when accesses are not
+ * random, but follow a strong pattern.  The one implemented here is for
+ * access patterns where the same small set of keys is looked up over
+ * and over again, and this set of keys evolves slowly over time.
+ */
+
+#include <stdlib.h>
+
+#define EMPTY_ROTATING_TREE       ((rotating_node_t *)NULL)
+
+typedef struct rotating_node_s rotating_node_t;
+typedef int (*rotating_tree_enum_fn) (rotating_node_t *node, void *arg);
+
+struct rotating_node_s {
+	void *key;
+	rotating_node_t *left;
+	rotating_node_t *right;
+};
+
+void RotatingTree_Add(rotating_node_t **root, rotating_node_t *node);
+rotating_node_t* RotatingTree_Get(rotating_node_t **root, void *key);
+int RotatingTree_Enum(rotating_node_t *root, rotating_tree_enum_fn enumfn,
+		      void *arg);

Added: vendor/Python/current/Modules/selectmodule.c
===================================================================
--- vendor/Python/current/Modules/selectmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/selectmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,734 @@
+/* select - Module containing unix select(2) call.
+   Under Unix, the file descriptors are small integers.
+   Under Win32, select only exists for sockets, and sockets may
+   have any value except INVALID_SOCKET.
+   Under BeOS, we suffer the same dichotomy as Win32; sockets can be anything
+   >= 0.
+*/
+
+#include "Python.h"
+
+#ifdef __APPLE__
+    /* Perform runtime testing for a broken poll on OSX to make it easier
+     * to use the same binary on multiple releases of the OS.
+     */
+#undef HAVE_BROKEN_POLL
+#endif
+
+/* Windows #defines FD_SETSIZE to 64 if FD_SETSIZE isn't already defined.
+   64 is too small (too many people have bumped into that limit).
+   Here we boost it.
+   Users who want even more than the boosted limit should #define
+   FD_SETSIZE higher before this; e.g., via compiler /D switch.
+*/
+#if defined(MS_WINDOWS) && !defined(FD_SETSIZE)
+#define FD_SETSIZE 512
+#endif 
+
+#if defined(HAVE_POLL_H)
+#include <poll.h>
+#elif defined(HAVE_SYS_POLL_H)
+#include <sys/poll.h>
+#endif
+
+#ifdef __sgi
+/* This is missing from unistd.h */
+extern void bzero(void *, int);
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#if defined(PYOS_OS2) && !defined(PYCC_GCC)
+#include <sys/time.h>
+#include <utils.h>
+#endif
+
+#ifdef MS_WINDOWS
+#  include <winsock.h>
+#else
+#  define SOCKET int
+#  ifdef __BEOS__
+#    include <net/socket.h>
+#  elif defined(__VMS)
+#    include <socket.h>
+#  endif
+#endif
+
+
+static PyObject *SelectError;
+
+/* list of Python objects and their file descriptor */
+typedef struct {
+	PyObject *obj;			     /* owned reference */
+	SOCKET fd;
+	int sentinel;			     /* -1 == sentinel */
+} pylist;
+
+static void
+reap_obj(pylist fd2obj[FD_SETSIZE + 1])
+{
+	int i;
+	for (i = 0; i < FD_SETSIZE + 1 && fd2obj[i].sentinel >= 0; i++) {
+		Py_XDECREF(fd2obj[i].obj);
+		fd2obj[i].obj = NULL;
+	}
+	fd2obj[0].sentinel = -1;
+}
+
+
+/* returns -1 and sets the Python exception if an error occurred, otherwise
+   returns a number >= 0
+*/
+static int
+seq2set(PyObject *seq, fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
+{
+	int i;
+	int max = -1;
+	int index = 0;
+        int len = -1;
+        PyObject* fast_seq = NULL;
+	PyObject* o = NULL;
+
+	fd2obj[0].obj = (PyObject*)0;	     /* set list to zero size */
+	FD_ZERO(set);
+
+        fast_seq=PySequence_Fast(seq, "arguments 1-3 must be sequences");
+        if (!fast_seq)
+            return -1;
+
+        len = PySequence_Fast_GET_SIZE(fast_seq);
+
+	for (i = 0; i < len; i++)  {
+		SOCKET v;
+
+		/* any intervening fileno() calls could decr this refcnt */
+		if (!(o = PySequence_Fast_GET_ITEM(fast_seq, i)))
+                    return -1;
+
+		Py_INCREF(o);
+		v = PyObject_AsFileDescriptor( o );
+		if (v == -1) goto finally;
+
+#if defined(_MSC_VER)
+		max = 0;		     /* not used for Win32 */
+#else  /* !_MSC_VER */
+		if (v < 0 || v >= FD_SETSIZE) {
+			PyErr_SetString(PyExc_ValueError,
+				    "filedescriptor out of range in select()");
+			goto finally;
+		}
+		if (v > max)
+			max = v;
+#endif /* _MSC_VER */
+		FD_SET(v, set);
+
+		/* add object and its file descriptor to the list */
+		if (index >= FD_SETSIZE) {
+			PyErr_SetString(PyExc_ValueError,
+				      "too many file descriptors in select()");
+			goto finally;
+		}
+		fd2obj[index].obj = o;
+		fd2obj[index].fd = v;
+		fd2obj[index].sentinel = 0;
+		fd2obj[++index].sentinel = -1;
+	}
+        Py_DECREF(fast_seq);
+	return max+1;
+
+  finally:
+	Py_XDECREF(o);
+        Py_DECREF(fast_seq);
+	return -1;
+}
+
+/* returns NULL and sets the Python exception if an error occurred */
+static PyObject *
+set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
+{
+	int i, j, count=0;
+	PyObject *list, *o;
+	SOCKET fd;
+
+	for (j = 0; fd2obj[j].sentinel >= 0; j++) {
+		if (FD_ISSET(fd2obj[j].fd, set))
+			count++;
+	}
+	list = PyList_New(count);
+	if (!list)
+		return NULL;
+
+	i = 0;
+	for (j = 0; fd2obj[j].sentinel >= 0; j++) {
+		fd = fd2obj[j].fd;
+		if (FD_ISSET(fd, set)) {
+#ifndef _MSC_VER
+			if (fd > FD_SETSIZE) {
+				PyErr_SetString(PyExc_SystemError,
+			   "filedescriptor out of range returned in select()");
+				goto finally;
+			}
+#endif
+			o = fd2obj[j].obj;
+			fd2obj[j].obj = NULL;
+			/* transfer ownership */
+			if (PyList_SetItem(list, i, o) < 0)
+				goto finally;
+
+			i++;
+		}
+	}
+	return list;
+  finally:
+	Py_DECREF(list);
+	return NULL;
+}
+
+#undef SELECT_USES_HEAP
+#if FD_SETSIZE > 1024
+#define SELECT_USES_HEAP
+#endif /* FD_SETSIZE > 1024 */
+
+static PyObject *
+select_select(PyObject *self, PyObject *args)
+{
+#ifdef SELECT_USES_HEAP
+	pylist *rfd2obj, *wfd2obj, *efd2obj;
+#else  /* !SELECT_USES_HEAP */
+	/* XXX: All this should probably be implemented as follows:
+	 * - find the highest descriptor we're interested in
+	 * - add one
+	 * - that's the size
+	 * See: Stevens, APitUE, $12.5.1
+	 */
+	pylist rfd2obj[FD_SETSIZE + 1];
+	pylist wfd2obj[FD_SETSIZE + 1];
+	pylist efd2obj[FD_SETSIZE + 1];
+#endif /* SELECT_USES_HEAP */
+	PyObject *ifdlist, *ofdlist, *efdlist;
+	PyObject *ret = NULL;
+	PyObject *tout = Py_None;
+	fd_set ifdset, ofdset, efdset;
+	double timeout;
+	struct timeval tv, *tvp;
+	long seconds;
+	int imax, omax, emax, max;
+	int n;
+
+	/* convert arguments */
+	if (!PyArg_UnpackTuple(args, "select", 3, 4,
+			      &ifdlist, &ofdlist, &efdlist, &tout))
+		return NULL;
+
+	if (tout == Py_None)
+		tvp = (struct timeval *)0;
+	else if (!PyNumber_Check(tout)) {
+		PyErr_SetString(PyExc_TypeError,
+				"timeout must be a float or None");
+		return NULL;
+	}
+	else {
+		timeout = PyFloat_AsDouble(tout);
+		if (timeout == -1 && PyErr_Occurred())
+			return NULL;
+		if (timeout > (double)LONG_MAX) {
+			PyErr_SetString(PyExc_OverflowError,
+					"timeout period too long");
+			return NULL;
+		}
+		seconds = (long)timeout;
+		timeout = timeout - (double)seconds;
+		tv.tv_sec = seconds;
+		tv.tv_usec = (long)(timeout*1000000.0);
+		tvp = &tv;
+	}
+
+
+#ifdef SELECT_USES_HEAP
+	/* Allocate memory for the lists */
+	rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
+	wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
+	efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
+	if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
+		if (rfd2obj) PyMem_DEL(rfd2obj);
+		if (wfd2obj) PyMem_DEL(wfd2obj);
+		if (efd2obj) PyMem_DEL(efd2obj);
+		return PyErr_NoMemory();
+	}
+#endif /* SELECT_USES_HEAP */
+	/* Convert sequences to fd_sets, and get maximum fd number
+	 * propagates the Python exception set in seq2set()
+	 */
+	rfd2obj[0].sentinel = -1;
+	wfd2obj[0].sentinel = -1;
+	efd2obj[0].sentinel = -1;
+	if ((imax=seq2set(ifdlist, &ifdset, rfd2obj)) < 0) 
+		goto finally;
+	if ((omax=seq2set(ofdlist, &ofdset, wfd2obj)) < 0) 
+		goto finally;
+	if ((emax=seq2set(efdlist, &efdset, efd2obj)) < 0) 
+		goto finally;
+	max = imax;
+	if (omax > max) max = omax;
+	if (emax > max) max = emax;
+
+	Py_BEGIN_ALLOW_THREADS
+	n = select(max, &ifdset, &ofdset, &efdset, tvp);
+	Py_END_ALLOW_THREADS
+
+#ifdef MS_WINDOWS
+	if (n == SOCKET_ERROR) {
+		PyErr_SetExcFromWindowsErr(SelectError, WSAGetLastError());
+	}
+#else
+	if (n < 0) {
+		PyErr_SetFromErrno(SelectError);
+	}
+#endif
+	else if (n == 0) {
+                /* optimization */
+		ifdlist = PyList_New(0);
+		if (ifdlist) {
+			ret = PyTuple_Pack(3, ifdlist, ifdlist, ifdlist);
+			Py_DECREF(ifdlist);
+		}
+	}
+	else {
+		/* any of these three calls can raise an exception.  it's more
+		   convenient to test for this after all three calls... but
+		   is that acceptable?
+		*/
+		ifdlist = set2list(&ifdset, rfd2obj);
+		ofdlist = set2list(&ofdset, wfd2obj);
+		efdlist = set2list(&efdset, efd2obj);
+		if (PyErr_Occurred())
+			ret = NULL;
+		else
+			ret = PyTuple_Pack(3, ifdlist, ofdlist, efdlist);
+
+		Py_DECREF(ifdlist);
+		Py_DECREF(ofdlist);
+		Py_DECREF(efdlist);
+	}
+	
+  finally:
+	reap_obj(rfd2obj);
+	reap_obj(wfd2obj);
+	reap_obj(efd2obj);
+#ifdef SELECT_USES_HEAP
+	PyMem_DEL(rfd2obj);
+	PyMem_DEL(wfd2obj);
+	PyMem_DEL(efd2obj);
+#endif /* SELECT_USES_HEAP */
+	return ret;
+}
+
+#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
+/* 
+ * poll() support
+ */
+
+typedef struct {
+	PyObject_HEAD
+	PyObject *dict;
+	int ufd_uptodate; 
+	int ufd_len;
+        struct pollfd *ufds;
+} pollObject;
+
+static PyTypeObject poll_Type;
+
+/* Update the malloc'ed array of pollfds to match the dictionary 
+   contained within a pollObject.  Return 1 on success, 0 on an error.
+*/
+
+static int
+update_ufd_array(pollObject *self)
+{
+	Py_ssize_t i, pos;
+	PyObject *key, *value;
+
+	self->ufd_len = PyDict_Size(self->dict);
+	PyMem_Resize(self->ufds, struct pollfd, self->ufd_len);
+	if (self->ufds == NULL) {
+		PyErr_NoMemory();
+		return 0;
+	}
+
+	i = pos = 0;
+	while (PyDict_Next(self->dict, &pos, &key, &value)) {
+		self->ufds[i].fd = PyInt_AsLong(key);
+		self->ufds[i].events = (short)PyInt_AsLong(value);
+		i++;
+	}
+	self->ufd_uptodate = 1;
+	return 1;
+}
+
+PyDoc_STRVAR(poll_register_doc,
+"register(fd [, eventmask] ) -> None\n\n\
+Register a file descriptor with the polling object.\n\
+fd -- either an integer, or an object with a fileno() method returning an\n\
+      int.\n\
+events -- an optional bitmask describing the type of events to check for");
+
+static PyObject *
+poll_register(pollObject *self, PyObject *args) 
+{
+	PyObject *o, *key, *value;
+	int fd, events = POLLIN | POLLPRI | POLLOUT;
+	int err;
+
+	if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
+		return NULL;
+	}
+  
+	fd = PyObject_AsFileDescriptor(o);
+	if (fd == -1) return NULL;
+
+	/* Add entry to the internal dictionary: the key is the 
+	   file descriptor, and the value is the event mask. */
+	key = PyInt_FromLong(fd);
+	if (key == NULL)
+		return NULL;
+	value = PyInt_FromLong(events);
+	if (value == NULL) {
+		Py_DECREF(key);
+		return NULL;
+	}
+	err = PyDict_SetItem(self->dict, key, value);
+	Py_DECREF(key);
+	Py_DECREF(value);
+	if (err < 0)
+		return NULL;
+
+	self->ufd_uptodate = 0;
+		       
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(poll_unregister_doc,
+"unregister(fd) -> None\n\n\
+Remove a file descriptor being tracked by the polling object.");
+
+static PyObject *
+poll_unregister(pollObject *self, PyObject *o) 
+{
+	PyObject *key;
+	int fd;
+
+	fd = PyObject_AsFileDescriptor( o );
+	if (fd == -1) 
+		return NULL;
+
+	/* Check whether the fd is already in the array */
+	key = PyInt_FromLong(fd);
+	if (key == NULL) 
+		return NULL;
+
+	if (PyDict_DelItem(self->dict, key) == -1) {
+		Py_DECREF(key);
+		/* This will simply raise the KeyError set by PyDict_DelItem
+		   if the file descriptor isn't registered. */
+		return NULL;
+	}
+
+	Py_DECREF(key);
+	self->ufd_uptodate = 0;
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(poll_poll_doc,
+"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
+Polls the set of registered file descriptors, returning a list containing \n\
+any descriptors that have events or errors to report.");
+
+static PyObject *
+poll_poll(pollObject *self, PyObject *args) 
+{
+	PyObject *result_list = NULL, *tout = NULL;
+	int timeout = 0, poll_result, i, j;
+	PyObject *value = NULL, *num = NULL;
+
+	if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) {
+		return NULL;
+	}
+
+	/* Check values for timeout */
+	if (tout == NULL || tout == Py_None)
+		timeout = -1;
+	else if (!PyNumber_Check(tout)) {
+		PyErr_SetString(PyExc_TypeError,
+				"timeout must be an integer or None");
+		return NULL;
+	}
+	else {
+		tout = PyNumber_Int(tout);
+		if (!tout)
+			return NULL;
+		timeout = PyInt_AsLong(tout);
+		Py_DECREF(tout);
+		if (timeout == -1 && PyErr_Occurred())
+			return NULL;
+	}
+
+	/* Ensure the ufd array is up to date */
+	if (!self->ufd_uptodate) 
+		if (update_ufd_array(self) == 0)
+			return NULL;
+
+	/* call poll() */
+	Py_BEGIN_ALLOW_THREADS;
+	poll_result = poll(self->ufds, self->ufd_len, timeout);
+	Py_END_ALLOW_THREADS;
+ 
+	if (poll_result < 0) {
+		PyErr_SetFromErrno(SelectError);
+		return NULL;
+	} 
+       
+	/* build the result list */
+  
+	result_list = PyList_New(poll_result);
+	if (!result_list) 
+		return NULL;
+	else {
+		for (i = 0, j = 0; j < poll_result; j++) {
+ 			/* skip to the next fired descriptor */
+ 			while (!self->ufds[i].revents) {
+ 				i++;
+ 			}
+			/* if we hit a NULL return, set value to NULL
+			   and break out of loop; code at end will
+			   clean up result_list */
+			value = PyTuple_New(2);
+			if (value == NULL)
+				goto error;
+			num = PyInt_FromLong(self->ufds[i].fd);
+			if (num == NULL) {
+				Py_DECREF(value);
+				goto error;
+			}
+			PyTuple_SET_ITEM(value, 0, num);
+
+			/* The &0xffff is a workaround for AIX.  'revents'
+			   is a 16-bit short, and IBM assigned POLLNVAL
+			   to be 0x8000, so the conversion to int results
+			   in a negative number. See SF bug #923315. */
+			num = PyInt_FromLong(self->ufds[i].revents & 0xffff);
+			if (num == NULL) {
+				Py_DECREF(value);
+				goto error;
+			}
+			PyTuple_SET_ITEM(value, 1, num);
+ 			if ((PyList_SetItem(result_list, j, value)) == -1) {
+				Py_DECREF(value);
+				goto error;
+ 			}
+ 			i++;
+ 		}
+ 	}
+ 	return result_list;
+
+  error:
+	Py_DECREF(result_list);
+	return NULL;
+}
+
+static PyMethodDef poll_methods[] = {
+	{"register",	(PyCFunction)poll_register,	
+	 METH_VARARGS,  poll_register_doc},
+	{"unregister",	(PyCFunction)poll_unregister,	
+	 METH_O,        poll_unregister_doc},
+	{"poll",	(PyCFunction)poll_poll,	
+	 METH_VARARGS,  poll_poll_doc},
+	{NULL,		NULL}		/* sentinel */
+};
+
+static pollObject *
+newPollObject(void)
+{
+        pollObject *self;
+	self = PyObject_New(pollObject, &poll_Type);
+	if (self == NULL)
+		return NULL;
+	/* ufd_uptodate is a Boolean, denoting whether the 
+	   array pointed to by ufds matches the contents of the dictionary. */
+	self->ufd_uptodate = 0;
+	self->ufds = NULL;
+	self->dict = PyDict_New();
+	if (self->dict == NULL) {
+		Py_DECREF(self);
+		return NULL;
+	}
+	return self;
+}
+
+static void
+poll_dealloc(pollObject *self)
+{
+	if (self->ufds != NULL)
+		PyMem_DEL(self->ufds);
+	Py_XDECREF(self->dict);
+  	PyObject_Del(self);
+}
+
+static PyObject *
+poll_getattr(pollObject *self, char *name)
+{
+	return Py_FindMethod(poll_methods, (PyObject *)self, name);
+}
+
+static PyTypeObject poll_Type = {
+	/* The ob_type field must be initialized in the module init function
+	 * to be portable to Windows without using C++. */
+	PyObject_HEAD_INIT(NULL)
+	0,			/*ob_size*/
+	"select.poll",		/*tp_name*/
+	sizeof(pollObject),	/*tp_basicsize*/
+	0,			/*tp_itemsize*/
+	/* methods */
+	(destructor)poll_dealloc, /*tp_dealloc*/
+	0,			/*tp_print*/
+	(getattrfunc)poll_getattr, /*tp_getattr*/
+	0,                      /*tp_setattr*/
+	0,			/*tp_compare*/
+	0,			/*tp_repr*/
+	0,			/*tp_as_number*/
+	0,			/*tp_as_sequence*/
+	0,			/*tp_as_mapping*/
+	0,			/*tp_hash*/
+};
+
+PyDoc_STRVAR(poll_doc,
+"Returns a polling object, which supports registering and\n\
+unregistering file descriptors, and then polling them for I/O events.");
+
+static PyObject *
+select_poll(PyObject *self, PyObject *unused)
+{
+	return (PyObject *)newPollObject();
+}
+
+#ifdef __APPLE__
+/* 
+ * On some systems poll() sets errno on invalid file descriptors. We test
+ * for this at runtime because this bug may be fixed or introduced between
+ * OS releases.
+ */
+static int select_have_broken_poll(void)
+{
+	int poll_test;
+	int filedes[2];
+
+	struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
+
+	/* Create a file descriptor to make invalid */
+	if (pipe(filedes) < 0) {
+		return 1;
+	}
+	poll_struct.fd = filedes[0];
+	close(filedes[0]);
+	close(filedes[1]);
+	poll_test = poll(&poll_struct, 1, 0);
+	if (poll_test < 0) {
+		return 1;
+	} else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
+		return 1;
+	}
+	return 0;
+}
+#endif /* __APPLE__ */
+
+#endif /* HAVE_POLL */
+
+PyDoc_STRVAR(select_doc,
+"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
+\n\
+Wait until one or more file descriptors are ready for some kind of I/O.\n\
+The first three arguments are sequences of file descriptors to be waited for:\n\
+rlist -- wait until ready for reading\n\
+wlist -- wait until ready for writing\n\
+xlist -- wait for an ``exceptional condition''\n\
+If only one kind of condition is required, pass [] for the other lists.\n\
+A file descriptor is either a socket or file object, or a small integer\n\
+gotten from a fileno() method call on one of those.\n\
+\n\
+The optional 4th argument specifies a timeout in seconds; it may be\n\
+a floating point number to specify fractions of seconds.  If it is absent\n\
+or None, the call will never time out.\n\
+\n\
+The return value is a tuple of three lists corresponding to the first three\n\
+arguments; each contains the subset of the corresponding file descriptors\n\
+that are ready.\n\
+\n\
+*** IMPORTANT NOTICE ***\n\
+On Windows and OpenVMS, only sockets are supported; on Unix, all file descriptors.");
+
+static PyMethodDef select_methods[] = {
+    {"select",	select_select, METH_VARARGS, select_doc},
+#if defined(HAVE_POLL) 
+    {"poll",    select_poll,   METH_NOARGS, poll_doc},
+#endif /* HAVE_POLL */
+    {0,  	0},			     /* sentinel */
+};
+
+PyDoc_STRVAR(module_doc,
+"This module supports asynchronous I/O on multiple file descriptors.\n\
+\n\
+*** IMPORTANT NOTICE ***\n\
+On Windows and OpenVMS, only sockets are supported; on Unix, all file descriptors.");
+
+PyMODINIT_FUNC
+initselect(void)
+{
+	PyObject *m;
+	m = Py_InitModule3("select", select_methods, module_doc);
+	if (m == NULL)
+		return;
+
+	SelectError = PyErr_NewException("select.error", NULL, NULL);
+	Py_INCREF(SelectError);
+	PyModule_AddObject(m, "error", SelectError);
+#if defined(HAVE_POLL) 
+
+#ifdef __APPLE__
+	if (select_have_broken_poll()) {
+		if (PyObject_DelAttrString(m, "poll") == -1) {
+			PyErr_Clear();
+		}
+	} else {
+#else
+	{
+#endif
+		poll_Type.ob_type = &PyType_Type;
+		PyModule_AddIntConstant(m, "POLLIN", POLLIN);
+		PyModule_AddIntConstant(m, "POLLPRI", POLLPRI);
+		PyModule_AddIntConstant(m, "POLLOUT", POLLOUT);
+		PyModule_AddIntConstant(m, "POLLERR", POLLERR);
+		PyModule_AddIntConstant(m, "POLLHUP", POLLHUP);
+		PyModule_AddIntConstant(m, "POLLNVAL", POLLNVAL);
+
+#ifdef POLLRDNORM
+		PyModule_AddIntConstant(m, "POLLRDNORM", POLLRDNORM);
+#endif
+#ifdef POLLRDBAND
+		PyModule_AddIntConstant(m, "POLLRDBAND", POLLRDBAND);
+#endif
+#ifdef POLLWRNORM
+		PyModule_AddIntConstant(m, "POLLWRNORM", POLLWRNORM);
+#endif
+#ifdef POLLWRBAND
+		PyModule_AddIntConstant(m, "POLLWRBAND", POLLWRBAND);
+#endif
+#ifdef POLLMSG
+		PyModule_AddIntConstant(m, "POLLMSG", POLLMSG);
+#endif
+	}
+#endif /* HAVE_POLL */
+}

Added: vendor/Python/current/Modules/sgimodule.c
===================================================================
--- vendor/Python/current/Modules/sgimodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/sgimodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,55 @@
+
+/* SGI module -- random SGI-specific things */
+
+#include "Python.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+static PyObject *
+sgi_nap(PyObject *self, PyObject *args)
+{
+	long ticks;
+	if (!PyArg_ParseTuple(args, "l:nap", &ticks))
+		return NULL;
+	Py_BEGIN_ALLOW_THREADS
+	sginap(ticks);
+	Py_END_ALLOW_THREADS
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+extern char *_getpty(int *, int, mode_t, int);
+
+static PyObject *
+sgi__getpty(PyObject *self, PyObject *args)
+{
+	int oflag;
+	int mode;
+	int nofork;
+	char *name;
+	int fildes;
+	if (!PyArg_ParseTuple(args, "iii:_getpty", &oflag, &mode, &nofork))
+		return NULL;
+	errno = 0;
+	name = _getpty(&fildes, oflag, (mode_t)mode, nofork);
+	if (name == NULL) {
+		PyErr_SetFromErrno(PyExc_IOError);
+		return NULL;
+	}
+	return Py_BuildValue("(si)", name, fildes);
+}
+
+static PyMethodDef sgi_methods[] = {
+	{"nap",		sgi_nap,	METH_VARARGS},
+	{"_getpty",	sgi__getpty,	METH_VARARGS},
+	{NULL,		NULL}		/* sentinel */
+};
+
+
+void
+initsgi(void)
+{
+	Py_InitModule("sgi", sgi_methods);
+}

Added: vendor/Python/current/Modules/sha256module.c
===================================================================
--- vendor/Python/current/Modules/sha256module.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/sha256module.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,701 @@
+/* SHA256 module */
+
+/* This module provides an interface to NIST's SHA-256 and SHA-224 Algorithms */
+
+/* See below for information about the original code this module was
+   based upon. Additional work performed by:
+
+   Andrew Kuchling (amk at amk.ca)
+   Greg Stein (gstein at lyra.org)
+   Trevor Perrin (trevp at trevp.net)
+
+   Copyright (C) 2005   Gregory P. Smith (greg at electricrain.com)
+   Licensed to PSF under a Contributor Agreement.
+
+*/
+
+/* SHA objects */
+
+#include "Python.h"
+#include "structmember.h"
+
+
+/* Endianness testing and definitions */
+#define TestEndianness(variable) {int i=1; variable=PCT_BIG_ENDIAN;\
+	if (*((char*)&i)==1) variable=PCT_LITTLE_ENDIAN;}
+
+#define PCT_LITTLE_ENDIAN 1
+#define PCT_BIG_ENDIAN 0
+
+/* Some useful types */
+
+typedef unsigned char SHA_BYTE;
+
+#if SIZEOF_INT == 4
+typedef unsigned int SHA_INT32;	/* 32-bit integer */
+#else
+/* not defined. compilation will die. */
+#endif
+
+/* The SHA block size and message digest sizes, in bytes */
+
+#define SHA_BLOCKSIZE    64
+#define SHA_DIGESTSIZE  32
+
+/* The structure for storing SHA info */
+
+typedef struct {
+    PyObject_HEAD
+    SHA_INT32 digest[8];		/* Message digest */
+    SHA_INT32 count_lo, count_hi;	/* 64-bit bit count */
+    SHA_BYTE data[SHA_BLOCKSIZE];	/* SHA data buffer */
+    int Endianness;
+    int local;				/* unprocessed amount in data */
+    int digestsize;
+} SHAobject;
+
+/* When run on a little-endian CPU we need to perform byte reversal on an
+   array of longwords. */
+
+static void longReverse(SHA_INT32 *buffer, int byteCount, int Endianness)
+{
+    SHA_INT32 value;
+
+    if ( Endianness == PCT_BIG_ENDIAN )
+	return;
+
+    byteCount /= sizeof(*buffer);
+    while (byteCount--) {
+        value = *buffer;
+        value = ( ( value & 0xFF00FF00L ) >> 8  ) | \
+                ( ( value & 0x00FF00FFL ) << 8 );
+        *buffer++ = ( value << 16 ) | ( value >> 16 );
+    }
+}
+
+static void SHAcopy(SHAobject *src, SHAobject *dest)
+{
+    dest->Endianness = src->Endianness;
+    dest->local = src->local;
+    dest->digestsize = src->digestsize;
+    dest->count_lo = src->count_lo;
+    dest->count_hi = src->count_hi;
+    memcpy(dest->digest, src->digest, sizeof(src->digest));
+    memcpy(dest->data, src->data, sizeof(src->data));
+}
+
+
+/* ------------------------------------------------------------------------
+ *
+ * This code for the SHA-256 algorithm was noted as public domain. The
+ * original headers are pasted below.
+ *
+ * Several changes have been made to make it more compatible with the
+ * Python environment and desired interface.
+ *
+ */
+
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * gurantee it works.
+ *
+ * Tom St Denis, tomstdenis at iahu.ca, http://libtomcrypt.org
+ */
+
+
+/* SHA256 by Tom St Denis */
+
+/* Various logical functions */
+#define ROR(x, y)\
+( ((((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)((y)&31)) | \
+((unsigned long)(x)<<(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)
+#define Ch(x,y,z)       (z ^ (x & (y ^ z)))
+#define Maj(x,y,z)      (((x | y) & z) | (x & y)) 
+#define S(x, n)         ROR((x),(n))
+#define R(x, n)         (((x)&0xFFFFFFFFUL)>>(n))
+#define Sigma0(x)       (S(x, 2) ^ S(x, 13) ^ S(x, 22))
+#define Sigma1(x)       (S(x, 6) ^ S(x, 11) ^ S(x, 25))
+#define Gamma0(x)       (S(x, 7) ^ S(x, 18) ^ R(x, 3))
+#define Gamma1(x)       (S(x, 17) ^ S(x, 19) ^ R(x, 10))
+
+
+static void
+sha_transform(SHAobject *sha_info)
+{
+    int i;
+	SHA_INT32 S[8], W[64], t0, t1;
+
+    memcpy(W, sha_info->data, sizeof(sha_info->data));
+    longReverse(W, (int)sizeof(sha_info->data), sha_info->Endianness);
+
+    for (i = 16; i < 64; ++i) {
+		W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
+    }
+    for (i = 0; i < 8; ++i) {
+        S[i] = sha_info->digest[i];
+    }
+
+    /* Compress */
+#define RND(a,b,c,d,e,f,g,h,i,ki)                    \
+     t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i];   \
+     t1 = Sigma0(a) + Maj(a, b, c);                  \
+     d += t0;                                        \
+     h  = t0 + t1;
+
+    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],0,0x428a2f98);
+    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],1,0x71374491);
+    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],2,0xb5c0fbcf);
+    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],3,0xe9b5dba5);
+    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],4,0x3956c25b);
+    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],5,0x59f111f1);
+    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],6,0x923f82a4);
+    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],7,0xab1c5ed5);
+    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],8,0xd807aa98);
+    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],9,0x12835b01);
+    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],10,0x243185be);
+    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],11,0x550c7dc3);
+    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],12,0x72be5d74);
+    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],13,0x80deb1fe);
+    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],14,0x9bdc06a7);
+    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],15,0xc19bf174);
+    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,0xe49b69c1);
+    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,0xefbe4786);
+    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,0x0fc19dc6);
+    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,0x240ca1cc);
+    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,0x2de92c6f);
+    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,0x4a7484aa);
+    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,0x5cb0a9dc);
+    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,0x76f988da);
+    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,0x983e5152);
+    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,0xa831c66d);
+    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,0xb00327c8);
+    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,0xbf597fc7);
+    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,0xc6e00bf3);
+    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,0xd5a79147);
+    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,0x06ca6351);
+    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,0x14292967);
+    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,0x27b70a85);
+    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,0x2e1b2138);
+    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,0x4d2c6dfc);
+    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,0x53380d13);
+    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,0x650a7354);
+    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,0x766a0abb);
+    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,0x81c2c92e);
+    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,0x92722c85);
+    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,0xa2bfe8a1);
+    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,0xa81a664b);
+    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,0xc24b8b70);
+    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,0xc76c51a3);
+    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,0xd192e819);
+    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,0xd6990624);
+    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,0xf40e3585);
+    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,0x106aa070);
+    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,0x19a4c116);
+    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,0x1e376c08);
+    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,0x2748774c);
+    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,0x34b0bcb5);
+    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,0x391c0cb3);
+    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,0x4ed8aa4a);
+    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,0x5b9cca4f);
+    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,0x682e6ff3);
+    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,0x748f82ee);
+    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,0x78a5636f);
+    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,0x84c87814);
+    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,0x8cc70208);
+    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,0x90befffa);
+    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,0xa4506ceb);
+    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,0xbef9a3f7);
+    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,0xc67178f2);
+
+#undef RND     
+    
+    /* feedback */
+    for (i = 0; i < 8; i++) {
+        sha_info->digest[i] = sha_info->digest[i] + S[i];
+    }
+
+}
+
+
+
+/* initialize the SHA digest */
+
+static void
+sha_init(SHAobject *sha_info)
+{
+    TestEndianness(sha_info->Endianness)
+    sha_info->digest[0] = 0x6A09E667L;
+    sha_info->digest[1] = 0xBB67AE85L;
+    sha_info->digest[2] = 0x3C6EF372L;
+    sha_info->digest[3] = 0xA54FF53AL;
+    sha_info->digest[4] = 0x510E527FL;
+    sha_info->digest[5] = 0x9B05688CL;
+    sha_info->digest[6] = 0x1F83D9ABL;
+    sha_info->digest[7] = 0x5BE0CD19L;
+    sha_info->count_lo = 0L;
+    sha_info->count_hi = 0L;
+    sha_info->local = 0;
+    sha_info->digestsize = 32;
+}
+
+static void
+sha224_init(SHAobject *sha_info)
+{
+    TestEndianness(sha_info->Endianness)
+    sha_info->digest[0] = 0xc1059ed8L;
+    sha_info->digest[1] = 0x367cd507L;
+    sha_info->digest[2] = 0x3070dd17L;
+    sha_info->digest[3] = 0xf70e5939L;
+    sha_info->digest[4] = 0xffc00b31L;
+    sha_info->digest[5] = 0x68581511L;
+    sha_info->digest[6] = 0x64f98fa7L;
+    sha_info->digest[7] = 0xbefa4fa4L;
+    sha_info->count_lo = 0L;
+    sha_info->count_hi = 0L;
+    sha_info->local = 0;
+    sha_info->digestsize = 28;
+}
+
+
+/* update the SHA digest */
+
+static void
+sha_update(SHAobject *sha_info, SHA_BYTE *buffer, int count)
+{
+    int i;
+    SHA_INT32 clo;
+
+    clo = sha_info->count_lo + ((SHA_INT32) count << 3);
+    if (clo < sha_info->count_lo) {
+        ++sha_info->count_hi;
+    }
+    sha_info->count_lo = clo;
+    sha_info->count_hi += (SHA_INT32) count >> 29;
+    if (sha_info->local) {
+        i = SHA_BLOCKSIZE - sha_info->local;
+        if (i > count) {
+            i = count;
+        }
+        memcpy(((SHA_BYTE *) sha_info->data) + sha_info->local, buffer, i);
+        count -= i;
+        buffer += i;
+        sha_info->local += i;
+        if (sha_info->local == SHA_BLOCKSIZE) {
+            sha_transform(sha_info);
+        }
+        else {
+            return;
+        }
+    }
+    while (count >= SHA_BLOCKSIZE) {
+        memcpy(sha_info->data, buffer, SHA_BLOCKSIZE);
+        buffer += SHA_BLOCKSIZE;
+        count -= SHA_BLOCKSIZE;
+        sha_transform(sha_info);
+    }
+    memcpy(sha_info->data, buffer, count);
+    sha_info->local = count;
+}
+
+/* finish computing the SHA digest */
+
+static void
+sha_final(unsigned char digest[SHA_DIGESTSIZE], SHAobject *sha_info)
+{
+    int count;
+    SHA_INT32 lo_bit_count, hi_bit_count;
+
+    lo_bit_count = sha_info->count_lo;
+    hi_bit_count = sha_info->count_hi;
+    count = (int) ((lo_bit_count >> 3) & 0x3f);
+    ((SHA_BYTE *) sha_info->data)[count++] = 0x80;
+    if (count > SHA_BLOCKSIZE - 8) {
+	memset(((SHA_BYTE *) sha_info->data) + count, 0,
+	       SHA_BLOCKSIZE - count);
+	sha_transform(sha_info);
+	memset((SHA_BYTE *) sha_info->data, 0, SHA_BLOCKSIZE - 8);
+    }
+    else {
+	memset(((SHA_BYTE *) sha_info->data) + count, 0,
+	       SHA_BLOCKSIZE - 8 - count);
+    }
+
+    /* GJS: note that we add the hi/lo in big-endian. sha_transform will
+       swap these values into host-order. */
+    sha_info->data[56] = (hi_bit_count >> 24) & 0xff;
+    sha_info->data[57] = (hi_bit_count >> 16) & 0xff;
+    sha_info->data[58] = (hi_bit_count >>  8) & 0xff;
+    sha_info->data[59] = (hi_bit_count >>  0) & 0xff;
+    sha_info->data[60] = (lo_bit_count >> 24) & 0xff;
+    sha_info->data[61] = (lo_bit_count >> 16) & 0xff;
+    sha_info->data[62] = (lo_bit_count >>  8) & 0xff;
+    sha_info->data[63] = (lo_bit_count >>  0) & 0xff;
+    sha_transform(sha_info);
+    digest[ 0] = (unsigned char) ((sha_info->digest[0] >> 24) & 0xff);
+    digest[ 1] = (unsigned char) ((sha_info->digest[0] >> 16) & 0xff);
+    digest[ 2] = (unsigned char) ((sha_info->digest[0] >>  8) & 0xff);
+    digest[ 3] = (unsigned char) ((sha_info->digest[0]      ) & 0xff);
+    digest[ 4] = (unsigned char) ((sha_info->digest[1] >> 24) & 0xff);
+    digest[ 5] = (unsigned char) ((sha_info->digest[1] >> 16) & 0xff);
+    digest[ 6] = (unsigned char) ((sha_info->digest[1] >>  8) & 0xff);
+    digest[ 7] = (unsigned char) ((sha_info->digest[1]      ) & 0xff);
+    digest[ 8] = (unsigned char) ((sha_info->digest[2] >> 24) & 0xff);
+    digest[ 9] = (unsigned char) ((sha_info->digest[2] >> 16) & 0xff);
+    digest[10] = (unsigned char) ((sha_info->digest[2] >>  8) & 0xff);
+    digest[11] = (unsigned char) ((sha_info->digest[2]      ) & 0xff);
+    digest[12] = (unsigned char) ((sha_info->digest[3] >> 24) & 0xff);
+    digest[13] = (unsigned char) ((sha_info->digest[3] >> 16) & 0xff);
+    digest[14] = (unsigned char) ((sha_info->digest[3] >>  8) & 0xff);
+    digest[15] = (unsigned char) ((sha_info->digest[3]      ) & 0xff);
+    digest[16] = (unsigned char) ((sha_info->digest[4] >> 24) & 0xff);
+    digest[17] = (unsigned char) ((sha_info->digest[4] >> 16) & 0xff);
+    digest[18] = (unsigned char) ((sha_info->digest[4] >>  8) & 0xff);
+    digest[19] = (unsigned char) ((sha_info->digest[4]      ) & 0xff);
+    digest[20] = (unsigned char) ((sha_info->digest[5] >> 24) & 0xff);
+    digest[21] = (unsigned char) ((sha_info->digest[5] >> 16) & 0xff);
+    digest[22] = (unsigned char) ((sha_info->digest[5] >>  8) & 0xff);
+    digest[23] = (unsigned char) ((sha_info->digest[5]      ) & 0xff);
+    digest[24] = (unsigned char) ((sha_info->digest[6] >> 24) & 0xff);
+    digest[25] = (unsigned char) ((sha_info->digest[6] >> 16) & 0xff);
+    digest[26] = (unsigned char) ((sha_info->digest[6] >>  8) & 0xff);
+    digest[27] = (unsigned char) ((sha_info->digest[6]      ) & 0xff);
+    digest[28] = (unsigned char) ((sha_info->digest[7] >> 24) & 0xff);
+    digest[29] = (unsigned char) ((sha_info->digest[7] >> 16) & 0xff);
+    digest[30] = (unsigned char) ((sha_info->digest[7] >>  8) & 0xff);
+    digest[31] = (unsigned char) ((sha_info->digest[7]      ) & 0xff);
+}
+
+/*
+ * End of copied SHA code.
+ *
+ * ------------------------------------------------------------------------
+ */
+
+static PyTypeObject SHA224type;
+static PyTypeObject SHA256type;
+
+
+static SHAobject *
+newSHA224object(void)
+{
+    return (SHAobject *)PyObject_New(SHAobject, &SHA224type);
+}
+
+static SHAobject *
+newSHA256object(void)
+{
+    return (SHAobject *)PyObject_New(SHAobject, &SHA256type);
+}
+
+/* Internal methods for a hash object */
+
+static void
+SHA_dealloc(PyObject *ptr)
+{
+    PyObject_Del(ptr);
+}
+
+
+/* External methods for a hash object */
+
+PyDoc_STRVAR(SHA256_copy__doc__, "Return a copy of the hash object.");
+
+static PyObject *
+SHA256_copy(SHAobject *self, PyObject *unused)
+{
+    SHAobject *newobj;
+
+    if (((PyObject*)self)->ob_type == &SHA256type) {
+        if ( (newobj = newSHA256object())==NULL)
+            return NULL;
+    } else {
+        if ( (newobj = newSHA224object())==NULL)
+            return NULL;
+    }
+
+    SHAcopy(self, newobj);
+    return (PyObject *)newobj;
+}
+
+PyDoc_STRVAR(SHA256_digest__doc__,
+"Return the digest value as a string of binary data.");
+
+static PyObject *
+SHA256_digest(SHAobject *self, PyObject *unused)
+{
+    unsigned char digest[SHA_DIGESTSIZE];
+    SHAobject temp;
+
+    SHAcopy(self, &temp);
+    sha_final(digest, &temp);
+    return PyString_FromStringAndSize((const char *)digest, self->digestsize);
+}
+
+PyDoc_STRVAR(SHA256_hexdigest__doc__,
+"Return the digest value as a string of hexadecimal digits.");
+
+static PyObject *
+SHA256_hexdigest(SHAobject *self, PyObject *unused)
+{
+    unsigned char digest[SHA_DIGESTSIZE];
+    SHAobject temp;
+    PyObject *retval;
+    char *hex_digest;
+    int i, j;
+
+    /* Get the raw (binary) digest value */
+    SHAcopy(self, &temp);
+    sha_final(digest, &temp);
+
+    /* Create a new string */
+    retval = PyString_FromStringAndSize(NULL, self->digestsize * 2);
+    if (!retval)
+	    return NULL;
+    hex_digest = PyString_AsString(retval);
+    if (!hex_digest) {
+	    Py_DECREF(retval);
+	    return NULL;
+    }
+
+    /* Make hex version of the digest */
+    for(i=j=0; i<self->digestsize; i++) {
+        char c;
+        c = (digest[i] >> 4) & 0xf;
+	c = (c>9) ? c+'a'-10 : c + '0';
+        hex_digest[j++] = c;
+        c = (digest[i] & 0xf);
+	c = (c>9) ? c+'a'-10 : c + '0';
+        hex_digest[j++] = c;
+    }
+    return retval;
+}
+
+PyDoc_STRVAR(SHA256_update__doc__,
+"Update this hash object's state with the provided string.");
+
+static PyObject *
+SHA256_update(SHAobject *self, PyObject *args)
+{
+    unsigned char *cp;
+    int len;
+
+    if (!PyArg_ParseTuple(args, "s#:update", &cp, &len))
+        return NULL;
+
+    sha_update(self, cp, len);
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyMethodDef SHA_methods[] = {
+    {"copy",	  (PyCFunction)SHA256_copy,      METH_NOARGS,  SHA256_copy__doc__},
+    {"digest",	  (PyCFunction)SHA256_digest,    METH_NOARGS,  SHA256_digest__doc__},
+    {"hexdigest", (PyCFunction)SHA256_hexdigest, METH_NOARGS,  SHA256_hexdigest__doc__},
+    {"update",	  (PyCFunction)SHA256_update,    METH_VARARGS, SHA256_update__doc__},
+    {NULL,	  NULL}		/* sentinel */
+};
+
+static PyObject *
+SHA256_get_block_size(PyObject *self, void *closure)
+{
+    return PyInt_FromLong(SHA_BLOCKSIZE);
+}
+
+static PyObject *
+SHA256_get_name(PyObject *self, void *closure)
+{
+    if (((SHAobject *)self)->digestsize == 32)
+        return PyString_FromStringAndSize("SHA256", 6);
+    else
+        return PyString_FromStringAndSize("SHA224", 6);
+}
+
+static PyGetSetDef SHA_getseters[] = {
+    {"block_size",
+     (getter)SHA256_get_block_size, NULL,
+     NULL,
+     NULL},
+    {"name",
+     (getter)SHA256_get_name, NULL,
+     NULL,
+     NULL},
+    {NULL}  /* Sentinel */
+};
+
+static PyMemberDef SHA_members[] = {
+    {"digest_size", T_INT, offsetof(SHAobject, digestsize), READONLY, NULL},
+    /* the old md5 and sha modules support 'digest_size' as in PEP 247.
+     * the old sha module also supported 'digestsize'.  ugh. */
+    {"digestsize", T_INT, offsetof(SHAobject, digestsize), READONLY, NULL},
+    {NULL}  /* Sentinel */
+};
+
+static PyTypeObject SHA224type = {
+    PyObject_HEAD_INIT(NULL)
+    0,			/*ob_size*/
+    "_sha256.sha224",	/*tp_name*/
+    sizeof(SHAobject),	/*tp_size*/
+    0,			/*tp_itemsize*/
+    /* methods */
+    SHA_dealloc,	/*tp_dealloc*/
+    0,			/*tp_print*/
+    0,          	/*tp_getattr*/
+    0,                  /*tp_setattr*/
+    0,                  /*tp_compare*/
+    0,                  /*tp_repr*/
+    0,                  /*tp_as_number*/
+    0,                  /*tp_as_sequence*/
+    0,                  /*tp_as_mapping*/
+    0,                  /*tp_hash*/
+    0,                  /*tp_call*/
+    0,                  /*tp_str*/
+    0,                  /*tp_getattro*/
+    0,                  /*tp_setattro*/
+    0,                  /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT, /*tp_flags*/
+    0,                  /*tp_doc*/
+    0,                  /*tp_traverse*/
+    0,			/*tp_clear*/
+    0,			/*tp_richcompare*/
+    0,			/*tp_weaklistoffset*/
+    0,			/*tp_iter*/
+    0,			/*tp_iternext*/
+    SHA_methods,	/* tp_methods */
+    SHA_members,	/* tp_members */
+    SHA_getseters,      /* tp_getset */
+};
+
+static PyTypeObject SHA256type = {
+    PyObject_HEAD_INIT(NULL)
+    0,			/*ob_size*/
+    "_sha256.sha256",	/*tp_name*/
+    sizeof(SHAobject),	/*tp_size*/
+    0,			/*tp_itemsize*/
+    /* methods */
+    SHA_dealloc,	/*tp_dealloc*/
+    0,			/*tp_print*/
+    0,          	/*tp_getattr*/
+    0,                  /*tp_setattr*/
+    0,                  /*tp_compare*/
+    0,                  /*tp_repr*/
+    0,                  /*tp_as_number*/
+    0,                  /*tp_as_sequence*/
+    0,                  /*tp_as_mapping*/
+    0,                  /*tp_hash*/
+    0,                  /*tp_call*/
+    0,                  /*tp_str*/
+    0,                  /*tp_getattro*/
+    0,                  /*tp_setattro*/
+    0,                  /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT, /*tp_flags*/
+    0,                  /*tp_doc*/
+    0,                  /*tp_traverse*/
+    0,			/*tp_clear*/
+    0,			/*tp_richcompare*/
+    0,			/*tp_weaklistoffset*/
+    0,			/*tp_iter*/
+    0,			/*tp_iternext*/
+    SHA_methods,	/* tp_methods */
+    SHA_members,	/* tp_members */
+    SHA_getseters,      /* tp_getset */
+};
+
+
+/* The single module-level function: new() */
+
+PyDoc_STRVAR(SHA256_new__doc__,
+"Return a new SHA-256 hash object; optionally initialized with a string.");
+
+static PyObject *
+SHA256_new(PyObject *self, PyObject *args, PyObject *kwdict)
+{
+    static char *kwlist[] = {"string", NULL};
+    SHAobject *new;
+    unsigned char *cp = NULL;
+    int len;
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwdict, "|s#:new", kwlist,
+                                     &cp, &len)) {
+        return NULL;
+    }
+
+    if ((new = newSHA256object()) == NULL)
+        return NULL;
+
+    sha_init(new);
+
+    if (PyErr_Occurred()) {
+        Py_DECREF(new);
+        return NULL;
+    }
+    if (cp)
+        sha_update(new, cp, len);
+
+    return (PyObject *)new;
+}
+
+PyDoc_STRVAR(SHA224_new__doc__,
+"Return a new SHA-224 hash object; optionally initialized with a string.");
+
+static PyObject *
+SHA224_new(PyObject *self, PyObject *args, PyObject *kwdict)
+{
+    static char *kwlist[] = {"string", NULL};
+    SHAobject *new;
+    unsigned char *cp = NULL;
+    int len;
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwdict, "|s#:new", kwlist,
+                                     &cp, &len)) {
+        return NULL;
+    }
+
+    if ((new = newSHA224object()) == NULL)
+        return NULL;
+
+    sha224_init(new);
+
+    if (PyErr_Occurred()) {
+        Py_DECREF(new);
+        return NULL;
+    }
+    if (cp)
+        sha_update(new, cp, len);
+
+    return (PyObject *)new;
+}
+
+
+/* List of functions exported by this module */
+
+static struct PyMethodDef SHA_functions[] = {
+    {"sha256", (PyCFunction)SHA256_new, METH_VARARGS|METH_KEYWORDS, SHA256_new__doc__},
+    {"sha224", (PyCFunction)SHA224_new, METH_VARARGS|METH_KEYWORDS, SHA224_new__doc__},
+    {NULL,	NULL}		 /* Sentinel */
+};
+
+
+/* Initialize this module. */
+
+#define insint(n,v) { PyModule_AddIntConstant(m,n,v); }
+
+PyMODINIT_FUNC
+init_sha256(void)
+{
+    PyObject *m;
+
+    SHA224type.ob_type = &PyType_Type;
+    if (PyType_Ready(&SHA224type) < 0)
+        return;
+    SHA256type.ob_type = &PyType_Type;
+    if (PyType_Ready(&SHA256type) < 0)
+        return;
+    m = Py_InitModule("_sha256", SHA_functions);
+    if (m == NULL)
+	return;
+}

Added: vendor/Python/current/Modules/sha512module.c
===================================================================
--- vendor/Python/current/Modules/sha512module.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/sha512module.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,769 @@
+/* SHA512 module */
+
+/* This module provides an interface to NIST's SHA-512 and SHA-384 Algorithms */
+
+/* See below for information about the original code this module was
+   based upon. Additional work performed by:
+
+   Andrew Kuchling (amk at amk.ca)
+   Greg Stein (gstein at lyra.org)
+   Trevor Perrin (trevp at trevp.net)
+
+   Copyright (C) 2005   Gregory P. Smith (greg at electricrain.com)
+   Licensed to PSF under a Contributor Agreement.
+
+*/
+
+/* SHA objects */
+
+#include "Python.h"
+#include "structmember.h"
+
+#ifdef PY_LONG_LONG /* If no PY_LONG_LONG, don't compile anything! */
+
+/* Endianness testing and definitions */
+#define TestEndianness(variable) {int i=1; variable=PCT_BIG_ENDIAN;\
+	if (*((char*)&i)==1) variable=PCT_LITTLE_ENDIAN;}
+
+#define PCT_LITTLE_ENDIAN 1
+#define PCT_BIG_ENDIAN 0
+
+/* Some useful types */
+
+typedef unsigned char SHA_BYTE;
+
+#if SIZEOF_INT == 4
+typedef unsigned int SHA_INT32;	/* 32-bit integer */
+typedef unsigned PY_LONG_LONG SHA_INT64;	/* 64-bit integer */
+#else
+/* not defined. compilation will die. */
+#endif
+
+/* The SHA block size and message digest sizes, in bytes */
+
+#define SHA_BLOCKSIZE   128
+#define SHA_DIGESTSIZE  64
+
+/* The structure for storing SHA info */
+
+typedef struct {
+    PyObject_HEAD
+    SHA_INT64 digest[8];		/* Message digest */
+    SHA_INT32 count_lo, count_hi;	/* 64-bit bit count */
+    SHA_BYTE data[SHA_BLOCKSIZE];	/* SHA data buffer */
+    int Endianness;
+    int local;				/* unprocessed amount in data */
+    int digestsize;
+} SHAobject;
+
+/* When run on a little-endian CPU we need to perform byte reversal on an
+   array of longwords. */
+
+static void longReverse(SHA_INT64 *buffer, int byteCount, int Endianness)
+{
+    SHA_INT64 value;
+
+    if ( Endianness == PCT_BIG_ENDIAN )
+	return;
+
+    byteCount /= sizeof(*buffer);
+    while (byteCount--) {
+        value = *buffer;
+
+		((unsigned char*)buffer)[0] = (unsigned char)(value >> 56) & 0xff;
+		((unsigned char*)buffer)[1] = (unsigned char)(value >> 48) & 0xff;
+		((unsigned char*)buffer)[2] = (unsigned char)(value >> 40) & 0xff;
+		((unsigned char*)buffer)[3] = (unsigned char)(value >> 32) & 0xff;
+		((unsigned char*)buffer)[4] = (unsigned char)(value >> 24) & 0xff;
+		((unsigned char*)buffer)[5] = (unsigned char)(value >> 16) & 0xff;
+		((unsigned char*)buffer)[6] = (unsigned char)(value >>  8) & 0xff;
+		((unsigned char*)buffer)[7] = (unsigned char)(value      ) & 0xff;
+        
+		buffer++;
+    }
+}
+
+static void SHAcopy(SHAobject *src, SHAobject *dest)
+{
+    dest->Endianness = src->Endianness;
+    dest->local = src->local;
+    dest->digestsize = src->digestsize;
+    dest->count_lo = src->count_lo;
+    dest->count_hi = src->count_hi;
+    memcpy(dest->digest, src->digest, sizeof(src->digest));
+    memcpy(dest->data, src->data, sizeof(src->data));
+}
+
+
+/* ------------------------------------------------------------------------
+ *
+ * This code for the SHA-512 algorithm was noted as public domain. The
+ * original headers are pasted below.
+ *
+ * Several changes have been made to make it more compatible with the
+ * Python environment and desired interface.
+ *
+ */
+
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * gurantee it works.
+ *
+ * Tom St Denis, tomstdenis at iahu.ca, http://libtomcrypt.org
+ */
+
+
+/* SHA512 by Tom St Denis */
+
+/* Various logical functions */
+#define ROR64(x, y) \
+    ( ((((x) & Py_ULL(0xFFFFFFFFFFFFFFFF))>>((unsigned PY_LONG_LONG)(y) & 63)) | \
+      ((x)<<((unsigned PY_LONG_LONG)(64-((y) & 63))))) & Py_ULL(0xFFFFFFFFFFFFFFFF))
+#define Ch(x,y,z)       (z ^ (x & (y ^ z)))
+#define Maj(x,y,z)      (((x | y) & z) | (x & y)) 
+#define S(x, n)         ROR64((x),(n))
+#define R(x, n)         (((x) & Py_ULL(0xFFFFFFFFFFFFFFFF)) >> ((unsigned PY_LONG_LONG)n))
+#define Sigma0(x)       (S(x, 28) ^ S(x, 34) ^ S(x, 39))
+#define Sigma1(x)       (S(x, 14) ^ S(x, 18) ^ S(x, 41))
+#define Gamma0(x)       (S(x, 1) ^ S(x, 8) ^ R(x, 7))
+#define Gamma1(x)       (S(x, 19) ^ S(x, 61) ^ R(x, 6))
+
+
+static void
+sha512_transform(SHAobject *sha_info)
+{
+    int i;
+    SHA_INT64 S[8], W[80], t0, t1;
+
+    memcpy(W, sha_info->data, sizeof(sha_info->data));
+    longReverse(W, (int)sizeof(sha_info->data), sha_info->Endianness);
+
+    for (i = 16; i < 80; ++i) {
+		W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
+    }
+    for (i = 0; i < 8; ++i) {
+        S[i] = sha_info->digest[i];
+    }
+
+    /* Compress */
+#define RND(a,b,c,d,e,f,g,h,i,ki)                    \
+     t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i];   \
+     t1 = Sigma0(a) + Maj(a, b, c);                  \
+     d += t0;                                        \
+     h  = t0 + t1;
+
+    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],0,Py_ULL(0x428a2f98d728ae22));
+    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],1,Py_ULL(0x7137449123ef65cd));
+    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],2,Py_ULL(0xb5c0fbcfec4d3b2f));
+    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],3,Py_ULL(0xe9b5dba58189dbbc));
+    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],4,Py_ULL(0x3956c25bf348b538));
+    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],5,Py_ULL(0x59f111f1b605d019));
+    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],6,Py_ULL(0x923f82a4af194f9b));
+    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],7,Py_ULL(0xab1c5ed5da6d8118));
+    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],8,Py_ULL(0xd807aa98a3030242));
+    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],9,Py_ULL(0x12835b0145706fbe));
+    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],10,Py_ULL(0x243185be4ee4b28c));
+    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],11,Py_ULL(0x550c7dc3d5ffb4e2));
+    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],12,Py_ULL(0x72be5d74f27b896f));
+    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],13,Py_ULL(0x80deb1fe3b1696b1));
+    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],14,Py_ULL(0x9bdc06a725c71235));
+    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],15,Py_ULL(0xc19bf174cf692694));
+    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,Py_ULL(0xe49b69c19ef14ad2));
+    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,Py_ULL(0xefbe4786384f25e3));
+    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,Py_ULL(0x0fc19dc68b8cd5b5));
+    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,Py_ULL(0x240ca1cc77ac9c65));
+    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,Py_ULL(0x2de92c6f592b0275));
+    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,Py_ULL(0x4a7484aa6ea6e483));
+    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,Py_ULL(0x5cb0a9dcbd41fbd4));
+    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,Py_ULL(0x76f988da831153b5));
+    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,Py_ULL(0x983e5152ee66dfab));
+    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,Py_ULL(0xa831c66d2db43210));
+    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,Py_ULL(0xb00327c898fb213f));
+    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,Py_ULL(0xbf597fc7beef0ee4));
+    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,Py_ULL(0xc6e00bf33da88fc2));
+    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,Py_ULL(0xd5a79147930aa725));
+    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,Py_ULL(0x06ca6351e003826f));
+    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,Py_ULL(0x142929670a0e6e70));
+    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,Py_ULL(0x27b70a8546d22ffc));
+    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,Py_ULL(0x2e1b21385c26c926));
+    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,Py_ULL(0x4d2c6dfc5ac42aed));
+    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,Py_ULL(0x53380d139d95b3df));
+    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,Py_ULL(0x650a73548baf63de));
+    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,Py_ULL(0x766a0abb3c77b2a8));
+    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,Py_ULL(0x81c2c92e47edaee6));
+    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,Py_ULL(0x92722c851482353b));
+    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,Py_ULL(0xa2bfe8a14cf10364));
+    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,Py_ULL(0xa81a664bbc423001));
+    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,Py_ULL(0xc24b8b70d0f89791));
+    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,Py_ULL(0xc76c51a30654be30));
+    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,Py_ULL(0xd192e819d6ef5218));
+    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,Py_ULL(0xd69906245565a910));
+    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,Py_ULL(0xf40e35855771202a));
+    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,Py_ULL(0x106aa07032bbd1b8));
+    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,Py_ULL(0x19a4c116b8d2d0c8));
+    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,Py_ULL(0x1e376c085141ab53));
+    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,Py_ULL(0x2748774cdf8eeb99));
+    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,Py_ULL(0x34b0bcb5e19b48a8));
+    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,Py_ULL(0x391c0cb3c5c95a63));
+    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,Py_ULL(0x4ed8aa4ae3418acb));
+    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,Py_ULL(0x5b9cca4f7763e373));
+    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,Py_ULL(0x682e6ff3d6b2b8a3));
+    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,Py_ULL(0x748f82ee5defb2fc));
+    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,Py_ULL(0x78a5636f43172f60));
+    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,Py_ULL(0x84c87814a1f0ab72));
+    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,Py_ULL(0x8cc702081a6439ec));
+    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,Py_ULL(0x90befffa23631e28));
+    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,Py_ULL(0xa4506cebde82bde9));
+    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,Py_ULL(0xbef9a3f7b2c67915));
+    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,Py_ULL(0xc67178f2e372532b));
+    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],64,Py_ULL(0xca273eceea26619c));
+    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],65,Py_ULL(0xd186b8c721c0c207));
+    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],66,Py_ULL(0xeada7dd6cde0eb1e));
+    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],67,Py_ULL(0xf57d4f7fee6ed178));
+    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],68,Py_ULL(0x06f067aa72176fba));
+    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],69,Py_ULL(0x0a637dc5a2c898a6));
+    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],70,Py_ULL(0x113f9804bef90dae));
+    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],71,Py_ULL(0x1b710b35131c471b));
+    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],72,Py_ULL(0x28db77f523047d84));
+    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],73,Py_ULL(0x32caab7b40c72493));
+    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],74,Py_ULL(0x3c9ebe0a15c9bebc));
+    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],75,Py_ULL(0x431d67c49c100d4c));
+    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],76,Py_ULL(0x4cc5d4becb3e42b6));
+    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],77,Py_ULL(0x597f299cfc657e2a));
+    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],78,Py_ULL(0x5fcb6fab3ad6faec));
+    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],79,Py_ULL(0x6c44198c4a475817));
+
+#undef RND     
+    
+    /* feedback */
+    for (i = 0; i < 8; i++) {
+        sha_info->digest[i] = sha_info->digest[i] + S[i];
+    }
+
+}
+
+
+
+/* initialize the SHA digest */
+
+static void
+sha512_init(SHAobject *sha_info)
+{
+    TestEndianness(sha_info->Endianness)
+    sha_info->digest[0] = Py_ULL(0x6a09e667f3bcc908);
+    sha_info->digest[1] = Py_ULL(0xbb67ae8584caa73b);
+    sha_info->digest[2] = Py_ULL(0x3c6ef372fe94f82b);
+    sha_info->digest[3] = Py_ULL(0xa54ff53a5f1d36f1);
+    sha_info->digest[4] = Py_ULL(0x510e527fade682d1);
+    sha_info->digest[5] = Py_ULL(0x9b05688c2b3e6c1f);
+    sha_info->digest[6] = Py_ULL(0x1f83d9abfb41bd6b);
+    sha_info->digest[7] = Py_ULL(0x5be0cd19137e2179);
+    sha_info->count_lo = 0L;
+    sha_info->count_hi = 0L;
+    sha_info->local = 0;
+    sha_info->digestsize = 64;
+}
+
+static void
+sha384_init(SHAobject *sha_info)
+{
+    TestEndianness(sha_info->Endianness)
+    sha_info->digest[0] = Py_ULL(0xcbbb9d5dc1059ed8);
+    sha_info->digest[1] = Py_ULL(0x629a292a367cd507);
+    sha_info->digest[2] = Py_ULL(0x9159015a3070dd17);
+    sha_info->digest[3] = Py_ULL(0x152fecd8f70e5939);
+    sha_info->digest[4] = Py_ULL(0x67332667ffc00b31);
+    sha_info->digest[5] = Py_ULL(0x8eb44a8768581511);
+    sha_info->digest[6] = Py_ULL(0xdb0c2e0d64f98fa7);
+    sha_info->digest[7] = Py_ULL(0x47b5481dbefa4fa4);
+    sha_info->count_lo = 0L;
+    sha_info->count_hi = 0L;
+    sha_info->local = 0;
+    sha_info->digestsize = 48;
+}
+
+
+/* update the SHA digest */
+
+static void
+sha512_update(SHAobject *sha_info, SHA_BYTE *buffer, int count)
+{
+    int i;
+    SHA_INT32 clo;
+
+    clo = sha_info->count_lo + ((SHA_INT32) count << 3);
+    if (clo < sha_info->count_lo) {
+        ++sha_info->count_hi;
+    }
+    sha_info->count_lo = clo;
+    sha_info->count_hi += (SHA_INT32) count >> 29;
+    if (sha_info->local) {
+        i = SHA_BLOCKSIZE - sha_info->local;
+        if (i > count) {
+            i = count;
+        }
+        memcpy(((SHA_BYTE *) sha_info->data) + sha_info->local, buffer, i);
+        count -= i;
+        buffer += i;
+        sha_info->local += i;
+        if (sha_info->local == SHA_BLOCKSIZE) {
+            sha512_transform(sha_info);
+        }
+        else {
+            return;
+        }
+    }
+    while (count >= SHA_BLOCKSIZE) {
+        memcpy(sha_info->data, buffer, SHA_BLOCKSIZE);
+        buffer += SHA_BLOCKSIZE;
+        count -= SHA_BLOCKSIZE;
+        sha512_transform(sha_info);
+    }
+    memcpy(sha_info->data, buffer, count);
+    sha_info->local = count;
+}
+
+/* finish computing the SHA digest */
+
+static void
+sha512_final(unsigned char digest[SHA_DIGESTSIZE], SHAobject *sha_info)
+{
+    int count;
+    SHA_INT32 lo_bit_count, hi_bit_count;
+
+    lo_bit_count = sha_info->count_lo;
+    hi_bit_count = sha_info->count_hi;
+    count = (int) ((lo_bit_count >> 3) & 0x7f);
+    ((SHA_BYTE *) sha_info->data)[count++] = 0x80;
+    if (count > SHA_BLOCKSIZE - 16) {
+	memset(((SHA_BYTE *) sha_info->data) + count, 0,
+	       SHA_BLOCKSIZE - count);
+	sha512_transform(sha_info);
+	memset((SHA_BYTE *) sha_info->data, 0, SHA_BLOCKSIZE - 16);
+    }
+    else {
+	memset(((SHA_BYTE *) sha_info->data) + count, 0,
+	       SHA_BLOCKSIZE - 16 - count);
+    }
+
+    /* GJS: note that we add the hi/lo in big-endian. sha512_transform will
+       swap these values into host-order. */
+    sha_info->data[112] = 0;
+    sha_info->data[113] = 0;
+    sha_info->data[114] = 0;
+    sha_info->data[115] = 0;
+    sha_info->data[116] = 0;
+    sha_info->data[117] = 0;
+    sha_info->data[118] = 0;
+    sha_info->data[119] = 0;
+    sha_info->data[120] = (hi_bit_count >> 24) & 0xff;
+    sha_info->data[121] = (hi_bit_count >> 16) & 0xff;
+    sha_info->data[122] = (hi_bit_count >>  8) & 0xff;
+    sha_info->data[123] = (hi_bit_count >>  0) & 0xff;
+    sha_info->data[124] = (lo_bit_count >> 24) & 0xff;
+    sha_info->data[125] = (lo_bit_count >> 16) & 0xff;
+    sha_info->data[126] = (lo_bit_count >>  8) & 0xff;
+    sha_info->data[127] = (lo_bit_count >>  0) & 0xff;
+    sha512_transform(sha_info);
+    digest[ 0] = (unsigned char) ((sha_info->digest[0] >> 56) & 0xff);
+    digest[ 1] = (unsigned char) ((sha_info->digest[0] >> 48) & 0xff);
+    digest[ 2] = (unsigned char) ((sha_info->digest[0] >> 40) & 0xff);
+    digest[ 3] = (unsigned char) ((sha_info->digest[0] >> 32) & 0xff);
+    digest[ 4] = (unsigned char) ((sha_info->digest[0] >> 24) & 0xff);
+    digest[ 5] = (unsigned char) ((sha_info->digest[0] >> 16) & 0xff);
+    digest[ 6] = (unsigned char) ((sha_info->digest[0] >>  8) & 0xff);
+    digest[ 7] = (unsigned char) ((sha_info->digest[0]      ) & 0xff);
+    digest[ 8] = (unsigned char) ((sha_info->digest[1] >> 56) & 0xff);
+    digest[ 9] = (unsigned char) ((sha_info->digest[1] >> 48) & 0xff);
+    digest[10] = (unsigned char) ((sha_info->digest[1] >> 40) & 0xff);
+    digest[11] = (unsigned char) ((sha_info->digest[1] >> 32) & 0xff);
+    digest[12] = (unsigned char) ((sha_info->digest[1] >> 24) & 0xff);
+    digest[13] = (unsigned char) ((sha_info->digest[1] >> 16) & 0xff);
+    digest[14] = (unsigned char) ((sha_info->digest[1] >>  8) & 0xff);
+    digest[15] = (unsigned char) ((sha_info->digest[1]      ) & 0xff);
+    digest[16] = (unsigned char) ((sha_info->digest[2] >> 56) & 0xff);
+    digest[17] = (unsigned char) ((sha_info->digest[2] >> 48) & 0xff);
+    digest[18] = (unsigned char) ((sha_info->digest[2] >> 40) & 0xff);
+    digest[19] = (unsigned char) ((sha_info->digest[2] >> 32) & 0xff);
+    digest[20] = (unsigned char) ((sha_info->digest[2] >> 24) & 0xff);
+    digest[21] = (unsigned char) ((sha_info->digest[2] >> 16) & 0xff);
+    digest[22] = (unsigned char) ((sha_info->digest[2] >>  8) & 0xff);
+    digest[23] = (unsigned char) ((sha_info->digest[2]      ) & 0xff);
+    digest[24] = (unsigned char) ((sha_info->digest[3] >> 56) & 0xff);
+    digest[25] = (unsigned char) ((sha_info->digest[3] >> 48) & 0xff);
+    digest[26] = (unsigned char) ((sha_info->digest[3] >> 40) & 0xff);
+    digest[27] = (unsigned char) ((sha_info->digest[3] >> 32) & 0xff);
+    digest[28] = (unsigned char) ((sha_info->digest[3] >> 24) & 0xff);
+    digest[29] = (unsigned char) ((sha_info->digest[3] >> 16) & 0xff);
+    digest[30] = (unsigned char) ((sha_info->digest[3] >>  8) & 0xff);
+    digest[31] = (unsigned char) ((sha_info->digest[3]      ) & 0xff);
+    digest[32] = (unsigned char) ((sha_info->digest[4] >> 56) & 0xff);
+    digest[33] = (unsigned char) ((sha_info->digest[4] >> 48) & 0xff);
+    digest[34] = (unsigned char) ((sha_info->digest[4] >> 40) & 0xff);
+    digest[35] = (unsigned char) ((sha_info->digest[4] >> 32) & 0xff);
+    digest[36] = (unsigned char) ((sha_info->digest[4] >> 24) & 0xff);
+    digest[37] = (unsigned char) ((sha_info->digest[4] >> 16) & 0xff);
+    digest[38] = (unsigned char) ((sha_info->digest[4] >>  8) & 0xff);
+    digest[39] = (unsigned char) ((sha_info->digest[4]      ) & 0xff);
+    digest[40] = (unsigned char) ((sha_info->digest[5] >> 56) & 0xff);
+    digest[41] = (unsigned char) ((sha_info->digest[5] >> 48) & 0xff);
+    digest[42] = (unsigned char) ((sha_info->digest[5] >> 40) & 0xff);
+    digest[43] = (unsigned char) ((sha_info->digest[5] >> 32) & 0xff);
+    digest[44] = (unsigned char) ((sha_info->digest[5] >> 24) & 0xff);
+    digest[45] = (unsigned char) ((sha_info->digest[5] >> 16) & 0xff);
+    digest[46] = (unsigned char) ((sha_info->digest[5] >>  8) & 0xff);
+    digest[47] = (unsigned char) ((sha_info->digest[5]      ) & 0xff);
+    digest[48] = (unsigned char) ((sha_info->digest[6] >> 56) & 0xff);
+    digest[49] = (unsigned char) ((sha_info->digest[6] >> 48) & 0xff);
+    digest[50] = (unsigned char) ((sha_info->digest[6] >> 40) & 0xff);
+    digest[51] = (unsigned char) ((sha_info->digest[6] >> 32) & 0xff);
+    digest[52] = (unsigned char) ((sha_info->digest[6] >> 24) & 0xff);
+    digest[53] = (unsigned char) ((sha_info->digest[6] >> 16) & 0xff);
+    digest[54] = (unsigned char) ((sha_info->digest[6] >>  8) & 0xff);
+    digest[55] = (unsigned char) ((sha_info->digest[6]      ) & 0xff);
+    digest[56] = (unsigned char) ((sha_info->digest[7] >> 56) & 0xff);
+    digest[57] = (unsigned char) ((sha_info->digest[7] >> 48) & 0xff);
+    digest[58] = (unsigned char) ((sha_info->digest[7] >> 40) & 0xff);
+    digest[59] = (unsigned char) ((sha_info->digest[7] >> 32) & 0xff);
+    digest[60] = (unsigned char) ((sha_info->digest[7] >> 24) & 0xff);
+    digest[61] = (unsigned char) ((sha_info->digest[7] >> 16) & 0xff);
+    digest[62] = (unsigned char) ((sha_info->digest[7] >>  8) & 0xff);
+    digest[63] = (unsigned char) ((sha_info->digest[7]      ) & 0xff);
+}
+
+/*
+ * End of copied SHA code.
+ *
+ * ------------------------------------------------------------------------
+ */
+
+static PyTypeObject SHA384type;
+static PyTypeObject SHA512type;
+
+
+static SHAobject *
+newSHA384object(void)
+{
+    return (SHAobject *)PyObject_New(SHAobject, &SHA384type);
+}
+
+static SHAobject *
+newSHA512object(void)
+{
+    return (SHAobject *)PyObject_New(SHAobject, &SHA512type);
+}
+
+/* Internal methods for a hash object */
+
+static void
+SHA512_dealloc(PyObject *ptr)
+{
+    PyObject_Del(ptr);
+}
+
+
+/* External methods for a hash object */
+
+PyDoc_STRVAR(SHA512_copy__doc__, "Return a copy of the hash object.");
+
+static PyObject *
+SHA512_copy(SHAobject *self, PyObject *unused)
+{
+    SHAobject *newobj;
+
+    if (((PyObject*)self)->ob_type == &SHA512type) {
+        if ( (newobj = newSHA512object())==NULL)
+            return NULL;
+    } else {
+        if ( (newobj = newSHA384object())==NULL)
+            return NULL;
+    }
+
+    SHAcopy(self, newobj);
+    return (PyObject *)newobj;
+}
+
+PyDoc_STRVAR(SHA512_digest__doc__,
+"Return the digest value as a string of binary data.");
+
+static PyObject *
+SHA512_digest(SHAobject *self, PyObject *unused)
+{
+    unsigned char digest[SHA_DIGESTSIZE];
+    SHAobject temp;
+
+    SHAcopy(self, &temp);
+    sha512_final(digest, &temp);
+    return PyString_FromStringAndSize((const char *)digest, self->digestsize);
+}
+
+PyDoc_STRVAR(SHA512_hexdigest__doc__,
+"Return the digest value as a string of hexadecimal digits.");
+
+static PyObject *
+SHA512_hexdigest(SHAobject *self, PyObject *unused)
+{
+    unsigned char digest[SHA_DIGESTSIZE];
+    SHAobject temp;
+    PyObject *retval;
+    char *hex_digest;
+    int i, j;
+
+    /* Get the raw (binary) digest value */
+    SHAcopy(self, &temp);
+    sha512_final(digest, &temp);
+
+    /* Create a new string */
+    retval = PyString_FromStringAndSize(NULL, self->digestsize * 2);
+    if (!retval)
+	    return NULL;
+    hex_digest = PyString_AsString(retval);
+    if (!hex_digest) {
+	    Py_DECREF(retval);
+	    return NULL;
+    }
+
+    /* Make hex version of the digest */
+    for (i=j=0; i<self->digestsize; i++) {
+        char c;
+        c = (digest[i] >> 4) & 0xf;
+	c = (c>9) ? c+'a'-10 : c + '0';
+        hex_digest[j++] = c;
+        c = (digest[i] & 0xf);
+	c = (c>9) ? c+'a'-10 : c + '0';
+        hex_digest[j++] = c;
+    }
+    return retval;
+}
+
+PyDoc_STRVAR(SHA512_update__doc__,
+"Update this hash object's state with the provided string.");
+
+static PyObject *
+SHA512_update(SHAobject *self, PyObject *args)
+{
+    unsigned char *cp;
+    int len;
+
+    if (!PyArg_ParseTuple(args, "s#:update", &cp, &len))
+        return NULL;
+
+    sha512_update(self, cp, len);
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyMethodDef SHA_methods[] = {
+    {"copy",	  (PyCFunction)SHA512_copy,      METH_NOARGS, SHA512_copy__doc__},
+    {"digest",	  (PyCFunction)SHA512_digest,    METH_NOARGS, SHA512_digest__doc__},
+    {"hexdigest", (PyCFunction)SHA512_hexdigest, METH_NOARGS, SHA512_hexdigest__doc__},
+    {"update",	  (PyCFunction)SHA512_update,    METH_VARARGS, SHA512_update__doc__},
+    {NULL,	  NULL}		/* sentinel */
+};
+
+static PyObject *
+SHA512_get_block_size(PyObject *self, void *closure)
+{
+    return PyInt_FromLong(SHA_BLOCKSIZE);
+}
+
+static PyObject *
+SHA512_get_name(PyObject *self, void *closure)
+{
+    if (((SHAobject *)self)->digestsize == 64)
+        return PyString_FromStringAndSize("SHA512", 6);
+    else
+        return PyString_FromStringAndSize("SHA384", 6);
+}
+
+static PyGetSetDef SHA_getseters[] = {
+    {"block_size",
+     (getter)SHA512_get_block_size, NULL,
+     NULL,
+     NULL},
+    {"name",
+     (getter)SHA512_get_name, NULL,
+     NULL,
+     NULL},
+    {NULL}  /* Sentinel */
+};
+
+static PyMemberDef SHA_members[] = {
+    {"digest_size", T_INT, offsetof(SHAobject, digestsize), READONLY, NULL},
+    /* the old md5 and sha modules support 'digest_size' as in PEP 247.
+     * the old sha module also supported 'digestsize'.  ugh. */
+    {"digestsize", T_INT, offsetof(SHAobject, digestsize), READONLY, NULL},
+    {NULL}  /* Sentinel */
+};
+
+static PyTypeObject SHA384type = {
+    PyObject_HEAD_INIT(NULL)
+    0,			/*ob_size*/
+    "_sha512.sha384",	/*tp_name*/
+    sizeof(SHAobject),	/*tp_size*/
+    0,			/*tp_itemsize*/
+    /* methods */
+    SHA512_dealloc,	/*tp_dealloc*/
+    0,			/*tp_print*/
+    0,          	/*tp_getattr*/
+    0,                  /*tp_setattr*/
+    0,                  /*tp_compare*/
+    0,                  /*tp_repr*/
+    0,                  /*tp_as_number*/
+    0,                  /*tp_as_sequence*/
+    0,                  /*tp_as_mapping*/
+    0,                  /*tp_hash*/
+    0,                  /*tp_call*/
+    0,                  /*tp_str*/
+    0,                  /*tp_getattro*/
+    0,                  /*tp_setattro*/
+    0,                  /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT, /*tp_flags*/
+    0,                  /*tp_doc*/
+    0,                  /*tp_traverse*/
+    0,			/*tp_clear*/
+    0,			/*tp_richcompare*/
+    0,			/*tp_weaklistoffset*/
+    0,			/*tp_iter*/
+    0,			/*tp_iternext*/
+    SHA_methods,	/* tp_methods */
+    SHA_members,	/* tp_members */
+    SHA_getseters,      /* tp_getset */
+};
+
+static PyTypeObject SHA512type = {
+    PyObject_HEAD_INIT(NULL)
+    0,			/*ob_size*/
+    "_sha512.sha512",	/*tp_name*/
+    sizeof(SHAobject),	/*tp_size*/
+    0,			/*tp_itemsize*/
+    /* methods */
+    SHA512_dealloc,	/*tp_dealloc*/
+    0,			/*tp_print*/
+    0,          	/*tp_getattr*/
+    0,                  /*tp_setattr*/
+    0,                  /*tp_compare*/
+    0,                  /*tp_repr*/
+    0,                  /*tp_as_number*/
+    0,                  /*tp_as_sequence*/
+    0,                  /*tp_as_mapping*/
+    0,                  /*tp_hash*/
+    0,                  /*tp_call*/
+    0,                  /*tp_str*/
+    0,                  /*tp_getattro*/
+    0,                  /*tp_setattro*/
+    0,                  /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT, /*tp_flags*/
+    0,                  /*tp_doc*/
+    0,                  /*tp_traverse*/
+    0,			/*tp_clear*/
+    0,			/*tp_richcompare*/
+    0,			/*tp_weaklistoffset*/
+    0,			/*tp_iter*/
+    0,			/*tp_iternext*/
+    SHA_methods,	/* tp_methods */
+    SHA_members,	/* tp_members */
+    SHA_getseters,      /* tp_getset */
+};
+
+
+/* The single module-level function: new() */
+
+PyDoc_STRVAR(SHA512_new__doc__,
+"Return a new SHA-512 hash object; optionally initialized with a string.");
+
+static PyObject *
+SHA512_new(PyObject *self, PyObject *args, PyObject *kwdict)
+{
+    static char *kwlist[] = {"string", NULL};
+    SHAobject *new;
+    unsigned char *cp = NULL;
+    int len;
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwdict, "|s#:new", kwlist,
+                                     &cp, &len)) {
+        return NULL;
+    }
+
+    if ((new = newSHA512object()) == NULL)
+        return NULL;
+
+    sha512_init(new);
+
+    if (PyErr_Occurred()) {
+        Py_DECREF(new);
+        return NULL;
+    }
+    if (cp)
+        sha512_update(new, cp, len);
+
+    return (PyObject *)new;
+}
+
+PyDoc_STRVAR(SHA384_new__doc__,
+"Return a new SHA-384 hash object; optionally initialized with a string.");
+
+static PyObject *
+SHA384_new(PyObject *self, PyObject *args, PyObject *kwdict)
+{
+    static char *kwlist[] = {"string", NULL};
+    SHAobject *new;
+    unsigned char *cp = NULL;
+    int len;
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwdict, "|s#:new", kwlist,
+                                     &cp, &len)) {
+        return NULL;
+    }
+
+    if ((new = newSHA384object()) == NULL)
+        return NULL;
+
+    sha384_init(new);
+
+    if (PyErr_Occurred()) {
+        Py_DECREF(new);
+        return NULL;
+    }
+    if (cp)
+        sha512_update(new, cp, len);
+
+    return (PyObject *)new;
+}
+
+
+/* List of functions exported by this module */
+
+static struct PyMethodDef SHA_functions[] = {
+    {"sha512", (PyCFunction)SHA512_new, METH_VARARGS|METH_KEYWORDS, SHA512_new__doc__},
+    {"sha384", (PyCFunction)SHA384_new, METH_VARARGS|METH_KEYWORDS, SHA384_new__doc__},
+    {NULL,	NULL}		 /* Sentinel */
+};
+
+
+/* Initialize this module. */
+
+#define insint(n,v) { PyModule_AddIntConstant(m,n,v); }
+
+PyMODINIT_FUNC
+init_sha512(void)
+{
+    PyObject *m;
+
+    SHA384type.ob_type = &PyType_Type;
+    if (PyType_Ready(&SHA384type) < 0)
+        return;
+    SHA512type.ob_type = &PyType_Type;
+    if (PyType_Ready(&SHA512type) < 0)
+        return;
+    m = Py_InitModule("_sha512", SHA_functions);
+    if (m == NULL)
+	return;
+}
+
+#endif

Added: vendor/Python/current/Modules/shamodule.c
===================================================================
--- vendor/Python/current/Modules/shamodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/shamodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,593 @@
+/* SHA module */
+
+/* This module provides an interface to NIST's Secure Hash Algorithm */
+
+/* See below for information about the original code this module was
+   based upon. Additional work performed by:
+
+   Andrew Kuchling (amk at amk.ca)
+   Greg Stein (gstein at lyra.org)
+
+   Copyright (C) 2005   Gregory P. Smith (greg at electricrain.com)
+   Licensed to PSF under a Contributor Agreement.
+
+*/
+
+/* SHA objects */
+
+#include "Python.h"
+#include "structmember.h"
+
+
+/* Endianness testing and definitions */
+#define TestEndianness(variable) {int i=1; variable=PCT_BIG_ENDIAN;\
+	if (*((char*)&i)==1) variable=PCT_LITTLE_ENDIAN;}
+
+#define PCT_LITTLE_ENDIAN 1
+#define PCT_BIG_ENDIAN 0
+
+/* Some useful types */
+
+typedef unsigned char SHA_BYTE;
+
+#if SIZEOF_INT == 4
+typedef unsigned int SHA_INT32;	/* 32-bit integer */
+#else
+/* not defined. compilation will die. */
+#endif
+
+/* The SHA block size and message digest sizes, in bytes */
+
+#define SHA_BLOCKSIZE    64
+#define SHA_DIGESTSIZE  20
+
+/* The structure for storing SHS info */
+
+typedef struct {
+    PyObject_HEAD
+    SHA_INT32 digest[5];		/* Message digest */
+    SHA_INT32 count_lo, count_hi;	/* 64-bit bit count */
+    SHA_BYTE data[SHA_BLOCKSIZE];	/* SHA data buffer */
+    int Endianness;
+    int local;				/* unprocessed amount in data */
+} SHAobject;
+
+/* When run on a little-endian CPU we need to perform byte reversal on an
+   array of longwords. */
+
+static void longReverse(SHA_INT32 *buffer, int byteCount, int Endianness)
+{
+    SHA_INT32 value;
+
+    if ( Endianness == PCT_BIG_ENDIAN )
+	return;
+
+    byteCount /= sizeof(*buffer);
+    while (byteCount--) {
+        value = *buffer;
+        value = ( ( value & 0xFF00FF00L ) >> 8  ) | \
+                ( ( value & 0x00FF00FFL ) << 8 );
+        *buffer++ = ( value << 16 ) | ( value >> 16 );
+    }
+}
+
+static void SHAcopy(SHAobject *src, SHAobject *dest)
+{
+    dest->Endianness = src->Endianness;
+    dest->local = src->local;
+    dest->count_lo = src->count_lo;
+    dest->count_hi = src->count_hi;
+    memcpy(dest->digest, src->digest, sizeof(src->digest));
+    memcpy(dest->data, src->data, sizeof(src->data));
+}
+
+
+/* ------------------------------------------------------------------------
+ *
+ * This code for the SHA algorithm was noted as public domain. The original
+ * headers are pasted below.
+ *
+ * Several changes have been made to make it more compatible with the
+ * Python environment and desired interface.
+ *
+ */
+
+/* NIST Secure Hash Algorithm */
+/* heavily modified by Uwe Hollerbach <uh at alumni.caltech edu> */
+/* from Peter C. Gutmann's implementation as found in */
+/* Applied Cryptography by Bruce Schneier */
+/* Further modifications to include the "UNRAVEL" stuff, below */
+
+/* This code is in the public domain */
+
+/* UNRAVEL should be fastest & biggest */
+/* UNROLL_LOOPS should be just as big, but slightly slower */
+/* both undefined should be smallest and slowest */
+
+#define UNRAVEL
+/* #define UNROLL_LOOPS */
+
+/* The SHA f()-functions.  The f1 and f3 functions can be optimized to
+   save one boolean operation each - thanks to Rich Schroeppel,
+   rcs at cs.arizona.edu for discovering this */
+
+/*#define f1(x,y,z)	((x & y) | (~x & z))		// Rounds  0-19 */
+#define f1(x,y,z)	(z ^ (x & (y ^ z)))		/* Rounds  0-19 */
+#define f2(x,y,z)	(x ^ y ^ z)			/* Rounds 20-39 */
+/*#define f3(x,y,z)	((x & y) | (x & z) | (y & z))	// Rounds 40-59 */
+#define f3(x,y,z)	((x & y) | (z & (x | y)))	/* Rounds 40-59 */
+#define f4(x,y,z)	(x ^ y ^ z)			/* Rounds 60-79 */
+
+/* SHA constants */
+
+#define CONST1		0x5a827999L			/* Rounds  0-19 */
+#define CONST2		0x6ed9eba1L			/* Rounds 20-39 */
+#define CONST3		0x8f1bbcdcL			/* Rounds 40-59 */
+#define CONST4		0xca62c1d6L			/* Rounds 60-79 */
+
+/* 32-bit rotate */
+
+#define R32(x,n)	((x << n) | (x >> (32 - n)))
+
+/* the generic case, for when the overall rotation is not unraveled */
+
+#define FG(n)	\
+    T = R32(A,5) + f##n(B,C,D) + E + *WP++ + CONST##n;	\
+    E = D; D = C; C = R32(B,30); B = A; A = T
+
+/* specific cases, for when the overall rotation is unraveled */
+
+#define FA(n)	\
+    T = R32(A,5) + f##n(B,C,D) + E + *WP++ + CONST##n; B = R32(B,30)
+
+#define FB(n)	\
+    E = R32(T,5) + f##n(A,B,C) + D + *WP++ + CONST##n; A = R32(A,30)
+
+#define FC(n)	\
+    D = R32(E,5) + f##n(T,A,B) + C + *WP++ + CONST##n; T = R32(T,30)
+
+#define FD(n)	\
+    C = R32(D,5) + f##n(E,T,A) + B + *WP++ + CONST##n; E = R32(E,30)
+
+#define FE(n)	\
+    B = R32(C,5) + f##n(D,E,T) + A + *WP++ + CONST##n; D = R32(D,30)
+
+#define FT(n)	\
+    A = R32(B,5) + f##n(C,D,E) + T + *WP++ + CONST##n; C = R32(C,30)
+
+/* do SHA transformation */
+
+static void
+sha_transform(SHAobject *sha_info)
+{
+    int i;
+    SHA_INT32 T, A, B, C, D, E, W[80], *WP;
+
+    memcpy(W, sha_info->data, sizeof(sha_info->data));
+    longReverse(W, (int)sizeof(sha_info->data), sha_info->Endianness);
+
+    for (i = 16; i < 80; ++i) {
+	W[i] = W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16];
+
+	/* extra rotation fix */
+	W[i] = R32(W[i], 1);
+    }
+    A = sha_info->digest[0];
+    B = sha_info->digest[1];
+    C = sha_info->digest[2];
+    D = sha_info->digest[3];
+    E = sha_info->digest[4];
+    WP = W;
+#ifdef UNRAVEL
+    FA(1); FB(1); FC(1); FD(1); FE(1); FT(1); FA(1); FB(1); FC(1); FD(1);
+    FE(1); FT(1); FA(1); FB(1); FC(1); FD(1); FE(1); FT(1); FA(1); FB(1);
+    FC(2); FD(2); FE(2); FT(2); FA(2); FB(2); FC(2); FD(2); FE(2); FT(2);
+    FA(2); FB(2); FC(2); FD(2); FE(2); FT(2); FA(2); FB(2); FC(2); FD(2);
+    FE(3); FT(3); FA(3); FB(3); FC(3); FD(3); FE(3); FT(3); FA(3); FB(3);
+    FC(3); FD(3); FE(3); FT(3); FA(3); FB(3); FC(3); FD(3); FE(3); FT(3);
+    FA(4); FB(4); FC(4); FD(4); FE(4); FT(4); FA(4); FB(4); FC(4); FD(4);
+    FE(4); FT(4); FA(4); FB(4); FC(4); FD(4); FE(4); FT(4); FA(4); FB(4);
+    sha_info->digest[0] += E;
+    sha_info->digest[1] += T;
+    sha_info->digest[2] += A;
+    sha_info->digest[3] += B;
+    sha_info->digest[4] += C;
+#else /* !UNRAVEL */
+#ifdef UNROLL_LOOPS
+    FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1);
+    FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1);
+    FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2);
+    FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2);
+    FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3);
+    FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3);
+    FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4);
+    FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4);
+#else /* !UNROLL_LOOPS */
+    for (i =  0; i < 20; ++i) { FG(1); }
+    for (i = 20; i < 40; ++i) { FG(2); }
+    for (i = 40; i < 60; ++i) { FG(3); }
+    for (i = 60; i < 80; ++i) { FG(4); }
+#endif /* !UNROLL_LOOPS */
+    sha_info->digest[0] += A;
+    sha_info->digest[1] += B;
+    sha_info->digest[2] += C;
+    sha_info->digest[3] += D;
+    sha_info->digest[4] += E;
+#endif /* !UNRAVEL */
+}
+
+/* initialize the SHA digest */
+
+static void
+sha_init(SHAobject *sha_info)
+{
+    TestEndianness(sha_info->Endianness)
+
+    sha_info->digest[0] = 0x67452301L;
+    sha_info->digest[1] = 0xefcdab89L;
+    sha_info->digest[2] = 0x98badcfeL;
+    sha_info->digest[3] = 0x10325476L;
+    sha_info->digest[4] = 0xc3d2e1f0L;
+    sha_info->count_lo = 0L;
+    sha_info->count_hi = 0L;
+    sha_info->local = 0;
+}
+
+/* update the SHA digest */
+
+static void
+sha_update(SHAobject *sha_info, SHA_BYTE *buffer, int count)
+{
+    int i;
+    SHA_INT32 clo;
+
+    clo = sha_info->count_lo + ((SHA_INT32) count << 3);
+    if (clo < sha_info->count_lo) {
+        ++sha_info->count_hi;
+    }
+    sha_info->count_lo = clo;
+    sha_info->count_hi += (SHA_INT32) count >> 29;
+    if (sha_info->local) {
+        i = SHA_BLOCKSIZE - sha_info->local;
+        if (i > count) {
+            i = count;
+        }
+        memcpy(((SHA_BYTE *) sha_info->data) + sha_info->local, buffer, i);
+        count -= i;
+        buffer += i;
+        sha_info->local += i;
+        if (sha_info->local == SHA_BLOCKSIZE) {
+            sha_transform(sha_info);
+        }
+        else {
+            return;
+        }
+    }
+    while (count >= SHA_BLOCKSIZE) {
+        memcpy(sha_info->data, buffer, SHA_BLOCKSIZE);
+        buffer += SHA_BLOCKSIZE;
+        count -= SHA_BLOCKSIZE;
+        sha_transform(sha_info);
+    }
+    memcpy(sha_info->data, buffer, count);
+    sha_info->local = count;
+}
+
+/* finish computing the SHA digest */
+
+static void
+sha_final(unsigned char digest[20], SHAobject *sha_info)
+{
+    int count;
+    SHA_INT32 lo_bit_count, hi_bit_count;
+
+    lo_bit_count = sha_info->count_lo;
+    hi_bit_count = sha_info->count_hi;
+    count = (int) ((lo_bit_count >> 3) & 0x3f);
+    ((SHA_BYTE *) sha_info->data)[count++] = 0x80;
+    if (count > SHA_BLOCKSIZE - 8) {
+	memset(((SHA_BYTE *) sha_info->data) + count, 0,
+	       SHA_BLOCKSIZE - count);
+	sha_transform(sha_info);
+	memset((SHA_BYTE *) sha_info->data, 0, SHA_BLOCKSIZE - 8);
+    }
+    else {
+	memset(((SHA_BYTE *) sha_info->data) + count, 0,
+	       SHA_BLOCKSIZE - 8 - count);
+    }
+
+    /* GJS: note that we add the hi/lo in big-endian. sha_transform will
+       swap these values into host-order. */
+    sha_info->data[56] = (hi_bit_count >> 24) & 0xff;
+    sha_info->data[57] = (hi_bit_count >> 16) & 0xff;
+    sha_info->data[58] = (hi_bit_count >>  8) & 0xff;
+    sha_info->data[59] = (hi_bit_count >>  0) & 0xff;
+    sha_info->data[60] = (lo_bit_count >> 24) & 0xff;
+    sha_info->data[61] = (lo_bit_count >> 16) & 0xff;
+    sha_info->data[62] = (lo_bit_count >>  8) & 0xff;
+    sha_info->data[63] = (lo_bit_count >>  0) & 0xff;
+    sha_transform(sha_info);
+    digest[ 0] = (unsigned char) ((sha_info->digest[0] >> 24) & 0xff);
+    digest[ 1] = (unsigned char) ((sha_info->digest[0] >> 16) & 0xff);
+    digest[ 2] = (unsigned char) ((sha_info->digest[0] >>  8) & 0xff);
+    digest[ 3] = (unsigned char) ((sha_info->digest[0]      ) & 0xff);
+    digest[ 4] = (unsigned char) ((sha_info->digest[1] >> 24) & 0xff);
+    digest[ 5] = (unsigned char) ((sha_info->digest[1] >> 16) & 0xff);
+    digest[ 6] = (unsigned char) ((sha_info->digest[1] >>  8) & 0xff);
+    digest[ 7] = (unsigned char) ((sha_info->digest[1]      ) & 0xff);
+    digest[ 8] = (unsigned char) ((sha_info->digest[2] >> 24) & 0xff);
+    digest[ 9] = (unsigned char) ((sha_info->digest[2] >> 16) & 0xff);
+    digest[10] = (unsigned char) ((sha_info->digest[2] >>  8) & 0xff);
+    digest[11] = (unsigned char) ((sha_info->digest[2]      ) & 0xff);
+    digest[12] = (unsigned char) ((sha_info->digest[3] >> 24) & 0xff);
+    digest[13] = (unsigned char) ((sha_info->digest[3] >> 16) & 0xff);
+    digest[14] = (unsigned char) ((sha_info->digest[3] >>  8) & 0xff);
+    digest[15] = (unsigned char) ((sha_info->digest[3]      ) & 0xff);
+    digest[16] = (unsigned char) ((sha_info->digest[4] >> 24) & 0xff);
+    digest[17] = (unsigned char) ((sha_info->digest[4] >> 16) & 0xff);
+    digest[18] = (unsigned char) ((sha_info->digest[4] >>  8) & 0xff);
+    digest[19] = (unsigned char) ((sha_info->digest[4]      ) & 0xff);
+}
+
+/*
+ * End of copied SHA code.
+ *
+ * ------------------------------------------------------------------------
+ */
+
+static PyTypeObject SHAtype;
+
+
+static SHAobject *
+newSHAobject(void)
+{
+    return (SHAobject *)PyObject_New(SHAobject, &SHAtype);
+}
+
+/* Internal methods for a hashing object */
+
+static void
+SHA_dealloc(PyObject *ptr)
+{
+    PyObject_Del(ptr);
+}
+
+
+/* External methods for a hashing object */
+
+PyDoc_STRVAR(SHA_copy__doc__, "Return a copy of the hashing object.");
+
+static PyObject *
+SHA_copy(SHAobject *self, PyObject *unused)
+{
+    SHAobject *newobj;
+
+    if ( (newobj = newSHAobject())==NULL)
+        return NULL;
+
+    SHAcopy(self, newobj);
+    return (PyObject *)newobj;
+}
+
+PyDoc_STRVAR(SHA_digest__doc__,
+"Return the digest value as a string of binary data.");
+
+static PyObject *
+SHA_digest(SHAobject *self, PyObject *unused)
+{
+    unsigned char digest[SHA_DIGESTSIZE];
+    SHAobject temp;
+
+    SHAcopy(self, &temp);
+    sha_final(digest, &temp);
+    return PyString_FromStringAndSize((const char *)digest, sizeof(digest));
+}
+
+PyDoc_STRVAR(SHA_hexdigest__doc__,
+"Return the digest value as a string of hexadecimal digits.");
+
+static PyObject *
+SHA_hexdigest(SHAobject *self, PyObject *unused)
+{
+    unsigned char digest[SHA_DIGESTSIZE];
+    SHAobject temp;
+    PyObject *retval;
+    char *hex_digest;
+    int i, j;
+
+    /* Get the raw (binary) digest value */
+    SHAcopy(self, &temp);
+    sha_final(digest, &temp);
+
+    /* Create a new string */
+    retval = PyString_FromStringAndSize(NULL, sizeof(digest) * 2);
+    if (!retval)
+	    return NULL;
+    hex_digest = PyString_AsString(retval);
+    if (!hex_digest) {
+	    Py_DECREF(retval);
+	    return NULL;
+    }
+
+    /* Make hex version of the digest */
+    for(i=j=0; i<sizeof(digest); i++) {
+        char c;
+        c = (digest[i] >> 4) & 0xf;
+	c = (c>9) ? c+'a'-10 : c + '0';
+        hex_digest[j++] = c;
+        c = (digest[i] & 0xf);
+	c = (c>9) ? c+'a'-10 : c + '0';
+        hex_digest[j++] = c;
+    }
+    return retval;
+}
+
+PyDoc_STRVAR(SHA_update__doc__,
+"Update this hashing object's state with the provided string.");
+
+static PyObject *
+SHA_update(SHAobject *self, PyObject *args)
+{
+    unsigned char *cp;
+    int len;
+
+    if (!PyArg_ParseTuple(args, "s#:update", &cp, &len))
+        return NULL;
+
+    sha_update(self, cp, len);
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyMethodDef SHA_methods[] = {
+    {"copy",	  (PyCFunction)SHA_copy,      METH_NOARGS,  SHA_copy__doc__},
+    {"digest",	  (PyCFunction)SHA_digest,    METH_NOARGS,  SHA_digest__doc__},
+    {"hexdigest", (PyCFunction)SHA_hexdigest, METH_NOARGS,  SHA_hexdigest__doc__},
+    {"update",	  (PyCFunction)SHA_update,    METH_VARARGS, SHA_update__doc__},
+    {NULL,	  NULL}		/* sentinel */
+};
+
+static PyObject *
+SHA_get_block_size(PyObject *self, void *closure)
+{
+    return PyInt_FromLong(SHA_BLOCKSIZE);
+}
+
+static PyObject *
+SHA_get_digest_size(PyObject *self, void *closure)
+{
+    return PyInt_FromLong(SHA_DIGESTSIZE);
+}
+
+static PyObject *
+SHA_get_name(PyObject *self, void *closure)
+{
+    return PyString_FromStringAndSize("SHA1", 4);
+}
+
+static PyGetSetDef SHA_getseters[] = {
+    {"digest_size",
+     (getter)SHA_get_digest_size, NULL,
+     NULL,
+     NULL},
+    {"block_size",
+     (getter)SHA_get_block_size, NULL,
+     NULL,
+     NULL},
+    {"name",
+     (getter)SHA_get_name, NULL,
+     NULL,
+     NULL},
+    /* the old md5 and sha modules support 'digest_size' as in PEP 247.
+     * the old sha module also supported 'digestsize'.  ugh. */
+    {"digestsize",
+     (getter)SHA_get_digest_size, NULL,
+     NULL,
+     NULL},
+    {NULL}  /* Sentinel */
+};
+
+static PyTypeObject SHAtype = {
+    PyObject_HEAD_INIT(NULL)
+    0,			/*ob_size*/
+    "_sha.sha",		/*tp_name*/
+    sizeof(SHAobject),	/*tp_size*/
+    0,			/*tp_itemsize*/
+    /* methods */
+    SHA_dealloc,	/*tp_dealloc*/
+    0,			/*tp_print*/
+    0,                  /*tp_getattr*/
+    0,                  /*tp_setattr*/
+    0,                  /*tp_compare*/
+    0,                  /*tp_repr*/
+    0,                  /*tp_as_number*/
+    0,                  /*tp_as_sequence*/
+    0,                  /*tp_as_mapping*/
+    0,                  /*tp_hash*/
+    0,                  /*tp_call*/
+    0,                  /*tp_str*/
+    0,                  /*tp_getattro*/
+    0,                  /*tp_setattro*/
+    0,                  /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT, /*tp_flags*/
+    0,                  /*tp_doc*/
+    0,                  /*tp_traverse*/
+    0,			/*tp_clear*/
+    0,			/*tp_richcompare*/
+    0,			/*tp_weaklistoffset*/
+    0,			/*tp_iter*/
+    0,			/*tp_iternext*/
+    SHA_methods,	/* tp_methods */
+    0,                  /* tp_members */
+    SHA_getseters,      /* tp_getset */
+};
+
+
+/* The single module-level function: new() */
+
+PyDoc_STRVAR(SHA_new__doc__,
+"Return a new SHA hashing object.  An optional string argument\n\
+may be provided; if present, this string will be automatically\n\
+hashed.");
+
+static PyObject *
+SHA_new(PyObject *self, PyObject *args, PyObject *kwdict)
+{
+    static char *kwlist[] = {"string", NULL};
+    SHAobject *new;
+    unsigned char *cp = NULL;
+    int len;
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwdict, "|s#:new", kwlist,
+                                     &cp, &len)) {
+        return NULL;
+    }
+
+    if ((new = newSHAobject()) == NULL)
+        return NULL;
+
+    sha_init(new);
+
+    if (PyErr_Occurred()) {
+        Py_DECREF(new);
+        return NULL;
+    }
+    if (cp)
+        sha_update(new, cp, len);
+
+    return (PyObject *)new;
+}
+
+
+/* List of functions exported by this module */
+
+static struct PyMethodDef SHA_functions[] = {
+    {"new", (PyCFunction)SHA_new, METH_VARARGS|METH_KEYWORDS, SHA_new__doc__},
+    {NULL,	NULL}		 /* Sentinel */
+};
+
+
+/* Initialize this module. */
+
+#define insint(n,v) { PyModule_AddIntConstant(m,n,v); }
+
+PyMODINIT_FUNC
+init_sha(void)
+{
+    PyObject *m;
+
+    SHAtype.ob_type = &PyType_Type;
+    if (PyType_Ready(&SHAtype) < 0)
+        return;
+    m = Py_InitModule("_sha", SHA_functions);
+    if (m == NULL)
+	return;
+
+    /* Add some symbolic constants to the module */
+    insint("blocksize", 1);  /* For future use, in case some hash
+                                functions require an integral number of
+                                blocks */ 
+    insint("digestsize", 20);
+    insint("digest_size", 20);
+}

Added: vendor/Python/current/Modules/signalmodule.c
===================================================================
--- vendor/Python/current/Modules/signalmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/signalmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,676 @@
+
+/* Signal module -- many thanks to Lance Ellinghaus */
+
+/* XXX Signals should be recorded per thread, now we have thread state. */
+
+#include "Python.h"
+#include "intrcheck.h"
+
+#ifdef MS_WINDOWS
+#include <process.h>
+#endif
+
+#include <signal.h>
+
+#ifndef SIG_ERR
+#define SIG_ERR ((PyOS_sighandler_t)(-1))
+#endif
+
+#if defined(PYOS_OS2) && !defined(PYCC_GCC)
+#define NSIG 12
+#include <process.h>
+#endif
+
+#ifndef NSIG
+# if defined(_NSIG)
+#  define NSIG _NSIG		/* For BSD/SysV */
+# elif defined(_SIGMAX)
+#  define NSIG (_SIGMAX + 1)	/* For QNX */
+# elif defined(SIGMAX)
+#  define NSIG (SIGMAX + 1)	/* For djgpp */
+# else
+#  define NSIG 64		/* Use a reasonable default value */
+# endif
+#endif
+
+
+/*
+   NOTES ON THE INTERACTION BETWEEN SIGNALS AND THREADS
+
+   When threads are supported, we want the following semantics:
+
+   - only the main thread can set a signal handler
+   - any thread can get a signal handler
+   - signals are only delivered to the main thread
+
+   I.e. we don't support "synchronous signals" like SIGFPE (catching
+   this doesn't make much sense in Python anyway) nor do we support
+   signals as a means of inter-thread communication, since not all
+   thread implementations support that (at least our thread library
+   doesn't).
+
+   We still have the problem that in some implementations signals
+   generated by the keyboard (e.g. SIGINT) are delivered to all
+   threads (e.g. SGI), while in others (e.g. Solaris) such signals are
+   delivered to one random thread (an intermediate possibility would
+   be to deliver it to the main thread -- POSIX?).  For now, we have
+   a working implementation that works in all three cases -- the
+   handler ignores signals if getpid() isn't the same as in the main
+   thread.  XXX This is a hack.
+
+   GNU pth is a user-space threading library, and as such, all threads
+   run within the same process. In this case, if the currently running
+   thread is not the main_thread, send the signal to the main_thread.
+*/
+
+#ifdef WITH_THREAD
+#include <sys/types.h> /* For pid_t */
+#include "pythread.h"
+static long main_thread;
+static pid_t main_pid;
+#endif
+
+static struct {
+        int tripped;
+        PyObject *func;
+} Handlers[NSIG];
+
+static int is_tripped = 0; /* Speed up sigcheck() when none tripped */
+
+static PyObject *DefaultHandler;
+static PyObject *IgnoreHandler;
+static PyObject *IntHandler;
+
+/* On Solaris 8, gcc will produce a warning that the function
+   declaration is not a prototype. This is caused by the definition of
+   SIG_DFL as (void (*)())0; the correct declaration would have been
+   (void (*)(int))0. */
+
+static PyOS_sighandler_t old_siginthandler = SIG_DFL;
+
+
+static PyObject *
+signal_default_int_handler(PyObject *self, PyObject *args)
+{
+	PyErr_SetNone(PyExc_KeyboardInterrupt);
+	return NULL;
+}
+
+PyDoc_STRVAR(default_int_handler_doc,
+"default_int_handler(...)\n\
+\n\
+The default handler for SIGINT installed by Python.\n\
+It raises KeyboardInterrupt.");
+
+
+static int
+checksignals_witharg(void * unused)
+{
+	return PyErr_CheckSignals();
+}
+
+static void
+signal_handler(int sig_num)
+{
+#ifdef WITH_THREAD
+#ifdef WITH_PTH
+	if (PyThread_get_thread_ident() != main_thread) {
+		pth_raise(*(pth_t *) main_thread, sig_num);
+		return;
+	}
+#endif
+	/* See NOTES section above */
+	if (getpid() == main_pid) {
+#endif
+		is_tripped++;
+		Handlers[sig_num].tripped = 1;
+		Py_AddPendingCall(checksignals_witharg, NULL);
+#ifdef WITH_THREAD
+	}
+#endif
+#ifdef SIGCHLD
+	if (sig_num == SIGCHLD) {
+		/* To avoid infinite recursion, this signal remains
+		   reset until explicit re-instated.
+		   Don't clear the 'func' field as it is our pointer
+		   to the Python handler... */
+		return;
+	}
+#endif
+	PyOS_setsig(sig_num, signal_handler);
+}
+
+
+#ifdef HAVE_ALARM
+static PyObject *
+signal_alarm(PyObject *self, PyObject *args)
+{
+	int t;
+	if (!PyArg_ParseTuple(args, "i:alarm", &t))
+		return NULL;
+	/* alarm() returns the number of seconds remaining */
+	return PyInt_FromLong((long)alarm(t));
+}
+
+PyDoc_STRVAR(alarm_doc,
+"alarm(seconds)\n\
+\n\
+Arrange for SIGALRM to arrive after the given number of seconds.");
+#endif
+
+#ifdef HAVE_PAUSE
+static PyObject *
+signal_pause(PyObject *self)
+{
+	Py_BEGIN_ALLOW_THREADS
+	(void)pause();
+	Py_END_ALLOW_THREADS
+	/* make sure that any exceptions that got raised are propagated
+	 * back into Python
+	 */
+	if (PyErr_CheckSignals())
+		return NULL;
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+PyDoc_STRVAR(pause_doc,
+"pause()\n\
+\n\
+Wait until a signal arrives.");
+
+#endif
+
+
+static PyObject *
+signal_signal(PyObject *self, PyObject *args)
+{
+	PyObject *obj;
+	int sig_num;
+	PyObject *old_handler;
+	void (*func)(int);
+	if (!PyArg_ParseTuple(args, "iO:signal", &sig_num, &obj))
+		return NULL;
+#ifdef WITH_THREAD
+	if (PyThread_get_thread_ident() != main_thread) {
+		PyErr_SetString(PyExc_ValueError,
+				"signal only works in main thread");
+		return NULL;
+	}
+#endif
+	if (sig_num < 1 || sig_num >= NSIG) {
+		PyErr_SetString(PyExc_ValueError,
+				"signal number out of range");
+		return NULL;
+	}
+	if (obj == IgnoreHandler)
+		func = SIG_IGN;
+	else if (obj == DefaultHandler)
+		func = SIG_DFL;
+	else if (!PyCallable_Check(obj)) {
+		PyErr_SetString(PyExc_TypeError,
+"signal handler must be signal.SIG_IGN, signal.SIG_DFL, or a callable object");
+		return NULL;
+	}
+	else
+		func = signal_handler;
+	if (PyOS_setsig(sig_num, func) == SIG_ERR) {
+		PyErr_SetFromErrno(PyExc_RuntimeError);
+		return NULL;
+	}
+	old_handler = Handlers[sig_num].func;
+	Handlers[sig_num].tripped = 0;
+	Py_INCREF(obj);
+	Handlers[sig_num].func = obj;
+	return old_handler;
+}
+
+PyDoc_STRVAR(signal_doc,
+"signal(sig, action) -> action\n\
+\n\
+Set the action for the given signal.  The action can be SIG_DFL,\n\
+SIG_IGN, or a callable Python object.  The previous action is\n\
+returned.  See getsignal() for possible return values.\n\
+\n\
+*** IMPORTANT NOTICE ***\n\
+A signal handler function is called with two arguments:\n\
+the first is the signal number, the second is the interrupted stack frame.");
+
+
+static PyObject *
+signal_getsignal(PyObject *self, PyObject *args)
+{
+	int sig_num;
+	PyObject *old_handler;
+	if (!PyArg_ParseTuple(args, "i:getsignal", &sig_num))
+		return NULL;
+	if (sig_num < 1 || sig_num >= NSIG) {
+		PyErr_SetString(PyExc_ValueError,
+				"signal number out of range");
+		return NULL;
+	}
+	old_handler = Handlers[sig_num].func;
+	Py_INCREF(old_handler);
+	return old_handler;
+}
+
+PyDoc_STRVAR(getsignal_doc,
+"getsignal(sig) -> action\n\
+\n\
+Return the current action for the given signal.  The return value can be:\n\
+SIG_IGN -- if the signal is being ignored\n\
+SIG_DFL -- if the default action for the signal is in effect\n\
+None -- if an unknown handler is in effect\n\
+anything else -- the callable Python object used as a handler");
+
+
+/* List of functions defined in the module */
+static PyMethodDef signal_methods[] = {
+#ifdef HAVE_ALARM
+	{"alarm",	        signal_alarm, METH_VARARGS, alarm_doc},
+#endif
+	{"signal",	        signal_signal, METH_VARARGS, signal_doc},
+	{"getsignal",	        signal_getsignal, METH_VARARGS, getsignal_doc},
+#ifdef HAVE_PAUSE
+	{"pause",	        (PyCFunction)signal_pause,
+	 METH_NOARGS,pause_doc},
+#endif
+	{"default_int_handler", signal_default_int_handler, 
+	 METH_VARARGS, default_int_handler_doc},
+	{NULL,			NULL}		/* sentinel */
+};
+
+
+PyDoc_STRVAR(module_doc,
+"This module provides mechanisms to use signal handlers in Python.\n\
+\n\
+Functions:\n\
+\n\
+alarm() -- cause SIGALRM after a specified time [Unix only]\n\
+signal() -- set the action for a given signal\n\
+getsignal() -- get the signal action for a given signal\n\
+pause() -- wait until a signal arrives [Unix only]\n\
+default_int_handler() -- default SIGINT handler\n\
+\n\
+Constants:\n\
+\n\
+SIG_DFL -- used to refer to the system default handler\n\
+SIG_IGN -- used to ignore the signal\n\
+NSIG -- number of defined signals\n\
+\n\
+SIGINT, SIGTERM, etc. -- signal numbers\n\
+\n\
+*** IMPORTANT NOTICE ***\n\
+A signal handler function is called with two arguments:\n\
+the first is the signal number, the second is the interrupted stack frame.");
+
+PyMODINIT_FUNC
+initsignal(void)
+{
+	PyObject *m, *d, *x;
+	int i;
+
+#ifdef WITH_THREAD
+	main_thread = PyThread_get_thread_ident();
+	main_pid = getpid();
+#endif
+
+	/* Create the module and add the functions */
+	m = Py_InitModule3("signal", signal_methods, module_doc);
+	if (m == NULL)
+		return;
+
+	/* Add some symbolic constants to the module */
+	d = PyModule_GetDict(m);
+
+	x = DefaultHandler = PyLong_FromVoidPtr((void *)SIG_DFL);
+        if (!x || PyDict_SetItemString(d, "SIG_DFL", x) < 0)
+                goto finally;
+
+	x = IgnoreHandler = PyLong_FromVoidPtr((void *)SIG_IGN);
+        if (!x || PyDict_SetItemString(d, "SIG_IGN", x) < 0)
+                goto finally;
+
+        x = PyInt_FromLong((long)NSIG);
+        if (!x || PyDict_SetItemString(d, "NSIG", x) < 0)
+                goto finally;
+        Py_DECREF(x);
+
+	x = IntHandler = PyDict_GetItemString(d, "default_int_handler");
+        if (!x)
+                goto finally;
+	Py_INCREF(IntHandler);
+
+	Handlers[0].tripped = 0;
+	for (i = 1; i < NSIG; i++) {
+		void (*t)(int);
+		t = PyOS_getsig(i);
+		Handlers[i].tripped = 0;
+		if (t == SIG_DFL)
+			Handlers[i].func = DefaultHandler;
+		else if (t == SIG_IGN)
+			Handlers[i].func = IgnoreHandler;
+		else
+			Handlers[i].func = Py_None; /* None of our business */
+		Py_INCREF(Handlers[i].func);
+	}
+	if (Handlers[SIGINT].func == DefaultHandler) {
+		/* Install default int handler */
+		Py_INCREF(IntHandler);
+		Py_DECREF(Handlers[SIGINT].func);
+		Handlers[SIGINT].func = IntHandler;
+		old_siginthandler = PyOS_setsig(SIGINT, signal_handler);
+	}
+
+#ifdef SIGHUP
+	x = PyInt_FromLong(SIGHUP);
+	PyDict_SetItemString(d, "SIGHUP", x);
+        Py_XDECREF(x);
+#endif
+#ifdef SIGINT
+	x = PyInt_FromLong(SIGINT);
+	PyDict_SetItemString(d, "SIGINT", x);
+        Py_XDECREF(x);
+#endif
+#ifdef SIGBREAK
+	x = PyInt_FromLong(SIGBREAK);
+	PyDict_SetItemString(d, "SIGBREAK", x);
+        Py_XDECREF(x);
+#endif
+#ifdef SIGQUIT
+	x = PyInt_FromLong(SIGQUIT);
+	PyDict_SetItemString(d, "SIGQUIT", x);
+        Py_XDECREF(x);
+#endif
+#ifdef SIGILL
+	x = PyInt_FromLong(SIGILL);
+	PyDict_SetItemString(d, "SIGILL", x);
+        Py_XDECREF(x);
+#endif
+#ifdef SIGTRAP
+	x = PyInt_FromLong(SIGTRAP);
+	PyDict_SetItemString(d, "SIGTRAP", x);
+        Py_XDECREF(x);
+#endif
+#ifdef SIGIOT
+	x = PyInt_FromLong(SIGIOT);
+	PyDict_SetItemString(d, "SIGIOT", x);
+        Py_XDECREF(x);
+#endif
+#ifdef SIGABRT
+	x = PyInt_FromLong(SIGABRT);
+	PyDict_SetItemString(d, "SIGABRT", x);
+        Py_XDECREF(x);
+#endif
+#ifdef SIGEMT
+	x = PyInt_FromLong(SIGEMT);
+	PyDict_SetItemString(d, "SIGEMT", x);
+        Py_XDECREF(x);
+#endif
+#ifdef SIGFPE
+	x = PyInt_FromLong(SIGFPE);
+	PyDict_SetItemString(d, "SIGFPE", x);
+        Py_XDECREF(x);
+#endif
+#ifdef SIGKILL
+	x = PyInt_FromLong(SIGKILL);
+	PyDict_SetItemString(d, "SIGKILL", x);
+        Py_XDECREF(x);
+#endif
+#ifdef SIGBUS
+	x = PyInt_FromLong(SIGBUS);
+	PyDict_SetItemString(d, "SIGBUS", x);
+        Py_XDECREF(x);
+#endif
+#ifdef SIGSEGV
+	x = PyInt_FromLong(SIGSEGV);
+	PyDict_SetItemString(d, "SIGSEGV", x);
+        Py_XDECREF(x);
+#endif
+#ifdef SIGSYS
+	x = PyInt_FromLong(SIGSYS);
+	PyDict_SetItemString(d, "SIGSYS", x);
+        Py_XDECREF(x);
+#endif
+#ifdef SIGPIPE
+	x = PyInt_FromLong(SIGPIPE);
+	PyDict_SetItemString(d, "SIGPIPE", x);
+        Py_XDECREF(x);
+#endif
+#ifdef SIGALRM
+	x = PyInt_FromLong(SIGALRM);
+	PyDict_SetItemString(d, "SIGALRM", x);
+        Py_XDECREF(x);
+#endif
+#ifdef SIGTERM
+	x = PyInt_FromLong(SIGTERM);
+	PyDict_SetItemString(d, "SIGTERM", x);
+        Py_XDECREF(x);
+#endif
+#ifdef SIGUSR1
+	x = PyInt_FromLong(SIGUSR1);
+	PyDict_SetItemString(d, "SIGUSR1", x);
+        Py_XDECREF(x);
+#endif
+#ifdef SIGUSR2
+	x = PyInt_FromLong(SIGUSR2);
+	PyDict_SetItemString(d, "SIGUSR2", x);
+        Py_XDECREF(x);
+#endif
+#ifdef SIGCLD
+	x = PyInt_FromLong(SIGCLD);
+	PyDict_SetItemString(d, "SIGCLD", x);
+        Py_XDECREF(x);
+#endif
+#ifdef SIGCHLD
+	x = PyInt_FromLong(SIGCHLD);
+	PyDict_SetItemString(d, "SIGCHLD", x);
+        Py_XDECREF(x);
+#endif
+#ifdef SIGPWR
+	x = PyInt_FromLong(SIGPWR);
+	PyDict_SetItemString(d, "SIGPWR", x);
+        Py_XDECREF(x);
+#endif
+#ifdef SIGIO
+	x = PyInt_FromLong(SIGIO);
+	PyDict_SetItemString(d, "SIGIO", x);
+        Py_XDECREF(x);
+#endif
+#ifdef SIGURG
+	x = PyInt_FromLong(SIGURG);
+	PyDict_SetItemString(d, "SIGURG", x);
+        Py_XDECREF(x);
+#endif
+#ifdef SIGWINCH
+	x = PyInt_FromLong(SIGWINCH);
+	PyDict_SetItemString(d, "SIGWINCH", x);
+        Py_XDECREF(x);
+#endif
+#ifdef SIGPOLL
+	x = PyInt_FromLong(SIGPOLL);
+	PyDict_SetItemString(d, "SIGPOLL", x);
+        Py_XDECREF(x);
+#endif
+#ifdef SIGSTOP
+	x = PyInt_FromLong(SIGSTOP);
+	PyDict_SetItemString(d, "SIGSTOP", x);
+        Py_XDECREF(x);
+#endif
+#ifdef SIGTSTP
+	x = PyInt_FromLong(SIGTSTP);
+	PyDict_SetItemString(d, "SIGTSTP", x);
+        Py_XDECREF(x);
+#endif
+#ifdef SIGCONT
+	x = PyInt_FromLong(SIGCONT);
+	PyDict_SetItemString(d, "SIGCONT", x);
+        Py_XDECREF(x);
+#endif
+#ifdef SIGTTIN
+	x = PyInt_FromLong(SIGTTIN);
+	PyDict_SetItemString(d, "SIGTTIN", x);
+        Py_XDECREF(x);
+#endif
+#ifdef SIGTTOU
+	x = PyInt_FromLong(SIGTTOU);
+	PyDict_SetItemString(d, "SIGTTOU", x);
+        Py_XDECREF(x);
+#endif
+#ifdef SIGVTALRM
+	x = PyInt_FromLong(SIGVTALRM);
+	PyDict_SetItemString(d, "SIGVTALRM", x);
+        Py_XDECREF(x);
+#endif
+#ifdef SIGPROF
+	x = PyInt_FromLong(SIGPROF);
+	PyDict_SetItemString(d, "SIGPROF", x);
+        Py_XDECREF(x);
+#endif
+#ifdef SIGXCPU
+	x = PyInt_FromLong(SIGXCPU);
+	PyDict_SetItemString(d, "SIGXCPU", x);
+        Py_XDECREF(x);
+#endif
+#ifdef SIGXFSZ
+	x = PyInt_FromLong(SIGXFSZ);
+	PyDict_SetItemString(d, "SIGXFSZ", x);
+        Py_XDECREF(x);
+#endif
+#ifdef SIGRTMIN
+        x = PyInt_FromLong(SIGRTMIN);
+        PyDict_SetItemString(d, "SIGRTMIN", x);
+        Py_XDECREF(x);
+#endif
+#ifdef SIGRTMAX
+        x = PyInt_FromLong(SIGRTMAX);
+        PyDict_SetItemString(d, "SIGRTMAX", x);
+        Py_XDECREF(x);
+#endif
+#ifdef SIGINFO
+	x = PyInt_FromLong(SIGINFO);
+	PyDict_SetItemString(d, "SIGINFO", x);
+        Py_XDECREF(x);
+#endif
+        if (!PyErr_Occurred())
+                return;
+
+	/* Check for errors */
+  finally:
+        return;
+}
+
+static void
+finisignal(void)
+{
+	int i;
+	PyObject *func;
+
+	PyOS_setsig(SIGINT, old_siginthandler);
+	old_siginthandler = SIG_DFL;
+
+	for (i = 1; i < NSIG; i++) {
+		func = Handlers[i].func;
+		Handlers[i].tripped = 0;
+		Handlers[i].func = NULL;
+		if (i != SIGINT && func != NULL && func != Py_None &&
+		    func != DefaultHandler && func != IgnoreHandler)
+			PyOS_setsig(i, SIG_DFL);
+		Py_XDECREF(func);
+	}
+
+	Py_XDECREF(IntHandler);
+	IntHandler = NULL;
+	Py_XDECREF(DefaultHandler);
+	DefaultHandler = NULL;
+	Py_XDECREF(IgnoreHandler);
+	IgnoreHandler = NULL;
+}
+
+
+/* Declared in pyerrors.h */
+int
+PyErr_CheckSignals(void)
+{
+	int i;
+	PyObject *f;
+
+	if (!is_tripped)
+		return 0;
+#ifdef WITH_THREAD
+	if (PyThread_get_thread_ident() != main_thread)
+		return 0;
+#endif
+	if (!(f = (PyObject *)PyEval_GetFrame()))
+		f = Py_None;
+	
+	for (i = 1; i < NSIG; i++) {
+		if (Handlers[i].tripped) {
+			PyObject *result = NULL;
+			PyObject *arglist = Py_BuildValue("(iO)", i, f);
+			Handlers[i].tripped = 0;
+
+			if (arglist) {
+				result = PyEval_CallObject(Handlers[i].func,
+							   arglist);
+				Py_DECREF(arglist);
+			}
+			if (!result)
+				return -1;
+
+			Py_DECREF(result);
+		}
+	}
+	is_tripped = 0;
+	return 0;
+}
+
+
+/* Replacements for intrcheck.c functionality
+ * Declared in pyerrors.h
+ */
+void
+PyErr_SetInterrupt(void)
+{
+	is_tripped++;
+	Handlers[SIGINT].tripped = 1;
+	Py_AddPendingCall((int (*)(void *))PyErr_CheckSignals, NULL);
+}
+
+void
+PyOS_InitInterrupts(void)
+{
+	initsignal();
+	_PyImport_FixupExtension("signal", "signal");
+}
+
+void
+PyOS_FiniInterrupts(void)
+{
+	finisignal();
+}
+
+int
+PyOS_InterruptOccurred(void)
+{
+	if (Handlers[SIGINT].tripped) {
+#ifdef WITH_THREAD
+		if (PyThread_get_thread_ident() != main_thread)
+			return 0;
+#endif
+		Handlers[SIGINT].tripped = 0;
+		return 1;
+	}
+	return 0;
+}
+
+void
+PyOS_AfterFork(void)
+{
+#ifdef WITH_THREAD
+	PyEval_ReInitThreads();
+	main_thread = PyThread_get_thread_ident();
+	main_pid = getpid();
+	_PyImport_ReInitLock();
+#endif
+}

Added: vendor/Python/current/Modules/socketmodule.c
===================================================================
--- vendor/Python/current/Modules/socketmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/socketmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,5096 @@
+/* Socket module */
+
+/*
+
+This module provides an interface to Berkeley socket IPC.
+
+Limitations:
+
+- Only AF_INET, AF_INET6 and AF_UNIX address families are supported in a
+  portable manner, though AF_PACKET and AF_NETLINK are supported under Linux.
+- No read/write operations (use sendall/recv or makefile instead).
+- Additional restrictions apply on some non-Unix platforms (compensated
+  for by socket.py).
+
+Module interface:
+
+- socket.error: exception raised for socket specific errors
+- socket.gaierror: exception raised for getaddrinfo/getnameinfo errors,
+	a subclass of socket.error
+- socket.herror: exception raised for gethostby* errors,
+	a subclass of socket.error
+- socket.fromfd(fd, family, type[, proto]) --> new socket object (created
+        from an existing file descriptor)
+- socket.gethostbyname(hostname) --> host IP address (string: 'dd.dd.dd.dd')
+- socket.gethostbyaddr(IP address) --> (hostname, [alias, ...], [IP addr, ...])
+- socket.gethostname() --> host name (string: 'spam' or 'spam.domain.com')
+- socket.getprotobyname(protocolname) --> protocol number
+- socket.getservbyname(servicename[, protocolname]) --> port number
+- socket.getservbyport(portnumber[, protocolname]) --> service name
+- socket.socket([family[, type [, proto]]]) --> new socket object
+- socket.socketpair([family[, type [, proto]]]) --> (socket, socket)
+- socket.ntohs(16 bit value) --> new int object
+- socket.ntohl(32 bit value) --> new int object
+- socket.htons(16 bit value) --> new int object
+- socket.htonl(32 bit value) --> new int object
+- socket.getaddrinfo(host, port [, family, socktype, proto, flags])
+	--> List of (family, socktype, proto, canonname, sockaddr)
+- socket.getnameinfo(sockaddr, flags) --> (host, port)
+- socket.AF_INET, socket.SOCK_STREAM, etc.: constants from <socket.h>
+- socket.has_ipv6: boolean value indicating if IPv6 is supported
+- socket.inet_aton(IP address) -> 32-bit packed IP representation
+- socket.inet_ntoa(packed IP) -> IP address string
+- socket.getdefaulttimeout() -> None | float
+- socket.setdefaulttimeout(None | float)
+- an Internet socket address is a pair (hostname, port)
+  where hostname can be anything recognized by gethostbyname()
+  (including the dd.dd.dd.dd notation) and port is in host byte order
+- where a hostname is returned, the dd.dd.dd.dd notation is used
+- a UNIX domain socket address is a string specifying the pathname
+- an AF_PACKET socket address is a tuple containing a string
+  specifying the ethernet interface and an integer specifying
+  the Ethernet protocol number to be received. For example:
+  ("eth0",0x1234).  Optional 3rd,4th,5th elements in the tuple
+  specify packet-type and ha-type/addr.
+
+Local naming conventions:
+
+- names starting with sock_ are socket object methods
+- names starting with socket_ are module-level functions
+- names starting with PySocket are exported through socketmodule.h
+
+*/
+
+#ifdef __APPLE__
+  /*
+   * inet_aton is not available on OSX 10.3, yet we want to use a binary
+   * that was build on 10.4 or later to work on that release, weak linking
+   * comes to the rescue.
+   */
+# pragma weak inet_aton
+#endif
+
+#include "Python.h"
+#include "structmember.h"
+
+#undef MAX
+#define MAX(x, y) ((x) < (y) ? (y) : (x))
+
+/* Socket object documentation */
+PyDoc_STRVAR(sock_doc,
+"socket([family[, type[, proto]]]) -> socket object\n\
+\n\
+Open a socket of the given type.  The family argument specifies the\n\
+address family; it defaults to AF_INET.  The type argument specifies\n\
+whether this is a stream (SOCK_STREAM, this is the default)\n\
+or datagram (SOCK_DGRAM) socket.  The protocol argument defaults to 0,\n\
+specifying the default protocol.  Keyword arguments are accepted.\n\
+\n\
+A socket object represents one endpoint of a network connection.\n\
+\n\
+Methods of socket objects (keyword arguments not allowed):\n\
+\n\
+accept() -- accept a connection, returning new socket and client address\n\
+bind(addr) -- bind the socket to a local address\n\
+close() -- close the socket\n\
+connect(addr) -- connect the socket to a remote address\n\
+connect_ex(addr) -- connect, return an error code instead of an exception\n\
+dup() -- return a new socket object identical to the current one [*]\n\
+fileno() -- return underlying file descriptor\n\
+getpeername() -- return remote address [*]\n\
+getsockname() -- return local address\n\
+getsockopt(level, optname[, buflen]) -- get socket options\n\
+gettimeout() -- return timeout or None\n\
+listen(n) -- start listening for incoming connections\n\
+makefile([mode, [bufsize]]) -- return a file object for the socket [*]\n\
+recv(buflen[, flags]) -- receive data\n\
+recv_into(buffer[, nbytes[, flags]]) -- receive data (into a buffer)\n\
+recvfrom(buflen[, flags]) -- receive data and sender\'s address\n\
+recvfrom_into(buffer[, nbytes, [, flags])\n\
+  -- receive data and sender\'s address (into a buffer)\n\
+sendall(data[, flags]) -- send all data\n\
+send(data[, flags]) -- send data, may not send all of it\n\
+sendto(data[, flags], addr) -- send data to a given address\n\
+setblocking(0 | 1) -- set or clear the blocking I/O flag\n\
+setsockopt(level, optname, value) -- set socket options\n\
+settimeout(None | float) -- set or clear the timeout\n\
+shutdown(how) -- shut down traffic in one or both directions\n\
+\n\
+ [*] not available on all platforms!");
+
+/* XXX This is a terrible mess of platform-dependent preprocessor hacks.
+   I hope some day someone can clean this up please... */
+
+/* Hacks for gethostbyname_r().  On some non-Linux platforms, the configure
+   script doesn't get this right, so we hardcode some platform checks below.
+   On the other hand, not all Linux versions agree, so there the settings
+   computed by the configure script are needed! */
+
+#ifndef linux
+# undef HAVE_GETHOSTBYNAME_R_3_ARG
+# undef HAVE_GETHOSTBYNAME_R_5_ARG
+# undef HAVE_GETHOSTBYNAME_R_6_ARG
+#endif
+
+#ifndef WITH_THREAD
+# undef HAVE_GETHOSTBYNAME_R
+#endif
+
+#ifdef HAVE_GETHOSTBYNAME_R
+# if defined(_AIX) || defined(__osf__)
+#  define HAVE_GETHOSTBYNAME_R_3_ARG
+# elif defined(__sun) || defined(__sgi)
+#  define HAVE_GETHOSTBYNAME_R_5_ARG
+# elif defined(linux)
+/* Rely on the configure script */
+# else
+#  undef HAVE_GETHOSTBYNAME_R
+# endif
+#endif
+
+#if !defined(HAVE_GETHOSTBYNAME_R) && defined(WITH_THREAD) && \
+    !defined(MS_WINDOWS)
+# define USE_GETHOSTBYNAME_LOCK
+#endif
+
+/* To use __FreeBSD_version */
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+/* On systems on which getaddrinfo() is believed to not be thread-safe,
+   (this includes the getaddrinfo emulation) protect access with a lock. */
+#if defined(WITH_THREAD) && (defined(__APPLE__) || \
+    (defined(__FreeBSD__) && __FreeBSD_version+0 < 503000) || \
+    defined(__OpenBSD__) || defined(__NetBSD__) || \
+    defined(__VMS) || !defined(HAVE_GETADDRINFO))
+#define USE_GETADDRINFO_LOCK
+#endif
+
+#ifdef USE_GETADDRINFO_LOCK
+#define ACQUIRE_GETADDRINFO_LOCK PyThread_acquire_lock(netdb_lock, 1);
+#define RELEASE_GETADDRINFO_LOCK PyThread_release_lock(netdb_lock);
+#else
+#define ACQUIRE_GETADDRINFO_LOCK
+#define RELEASE_GETADDRINFO_LOCK
+#endif
+
+#if defined(USE_GETHOSTBYNAME_LOCK) || defined(USE_GETADDRINFO_LOCK)
+# include "pythread.h"
+#endif
+
+#if defined(PYCC_VACPP)
+# include <types.h>
+# include <io.h>
+# include <sys/ioctl.h>
+# include <utils.h>
+# include <ctype.h>
+#endif
+
+#if defined(__VMS)
+#  include <ioctl.h>
+#endif
+
+#if defined(PYOS_OS2)
+# define  INCL_DOS
+# define  INCL_DOSERRORS
+# define  INCL_NOPMAPI
+# include <os2.h>
+#endif
+
+#if defined(__sgi) && _COMPILER_VERSION>700 && !_SGIAPI
+/* make sure that the reentrant (gethostbyaddr_r etc)
+   functions are declared correctly if compiling with
+   MIPSPro 7.x in ANSI C mode (default) */
+
+/* XXX Using _SGIAPI is the wrong thing,
+   but I don't know what the right thing is. */
+#undef _SGIAPI /* to avoid warning */
+#define _SGIAPI 1
+
+#undef _XOPEN_SOURCE
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#ifdef _SS_ALIGNSIZE
+#define HAVE_GETADDRINFO 1
+#define HAVE_GETNAMEINFO 1
+#endif
+
+#define HAVE_INET_PTON
+#include <netdb.h>
+#endif
+
+/* Irix 6.5 fails to define this variable at all. This is needed
+   for both GCC and SGI's compiler. I'd say that the SGI headers
+   are just busted. Same thing for Solaris. */
+#if (defined(__sgi) || defined(sun)) && !defined(INET_ADDRSTRLEN)
+#define INET_ADDRSTRLEN 16
+#endif
+
+/* Generic includes */
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+/* Generic socket object definitions and includes */
+#define PySocket_BUILDING_SOCKET
+#include "socketmodule.h"
+
+/* Addressing includes */
+
+#ifndef MS_WINDOWS
+
+/* Non-MS WINDOWS includes */
+# include <netdb.h>
+
+/* Headers needed for inet_ntoa() and inet_addr() */
+# ifdef __BEOS__
+#  include <net/netdb.h>
+# elif defined(PYOS_OS2) && defined(PYCC_VACPP)
+#  include <netdb.h>
+typedef size_t socklen_t;
+# else
+#   include <arpa/inet.h>
+# endif
+
+# ifndef RISCOS
+#  include <fcntl.h>
+# else
+#  include <sys/ioctl.h>
+#  include <socklib.h>
+#  define NO_DUP
+int h_errno; /* not used */
+#  define INET_ADDRSTRLEN 16
+# endif
+
+#else
+
+/* MS_WINDOWS includes */
+# ifdef HAVE_FCNTL_H
+#  include <fcntl.h>
+# endif
+
+#endif
+
+#include <stddef.h>
+
+#ifndef offsetof
+# define offsetof(type, member)	((size_t)(&((type *)0)->member))
+#endif
+
+#ifndef O_NONBLOCK
+# define O_NONBLOCK O_NDELAY
+#endif
+
+/* include Python's addrinfo.h unless it causes trouble */
+#if defined(__sgi) && _COMPILER_VERSION>700 && defined(_SS_ALIGNSIZE)
+  /* Do not include addinfo.h on some newer IRIX versions.
+   * _SS_ALIGNSIZE is defined in sys/socket.h by 6.5.21,
+   * for example, but not by 6.5.10.
+   */
+#elif defined(_MSC_VER) && _MSC_VER>1201
+  /* Do not include addrinfo.h for MSVC7 or greater. 'addrinfo' and
+   * EAI_* constants are defined in (the already included) ws2tcpip.h.
+   */
+#else
+#  include "addrinfo.h"
+#endif
+
+#ifndef HAVE_INET_PTON
+int inet_pton(int af, const char *src, void *dst);
+const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
+#endif
+
+#ifdef __APPLE__
+/* On OS X, getaddrinfo returns no error indication of lookup
+   failure, so we must use the emulation instead of the libinfo
+   implementation. Unfortunately, performing an autoconf test
+   for this bug would require DNS access for the machine performing
+   the configuration, which is not acceptable. Therefore, we
+   determine the bug just by checking for __APPLE__. If this bug
+   gets ever fixed, perhaps checking for sys/version.h would be
+   appropriate, which is 10/0 on the system with the bug. */
+#ifndef HAVE_GETNAMEINFO
+/* This bug seems to be fixed in Jaguar. Ths easiest way I could
+   Find to check for Jaguar is that it has getnameinfo(), which
+   older releases don't have */
+#undef HAVE_GETADDRINFO
+#endif
+
+#ifdef HAVE_INET_ATON
+#define USE_INET_ATON_WEAKLINK
+#endif
+
+#endif
+
+/* I know this is a bad practice, but it is the easiest... */
+#if !defined(HAVE_GETADDRINFO)
+/* avoid clashes with the C library definition of the symbol. */
+#define getaddrinfo fake_getaddrinfo
+#define gai_strerror fake_gai_strerror
+#define freeaddrinfo fake_freeaddrinfo
+#include "getaddrinfo.c"
+#endif
+#if !defined(HAVE_GETNAMEINFO)
+#define getnameinfo fake_getnameinfo
+#include "getnameinfo.c"
+#endif
+
+#if defined(MS_WINDOWS) || defined(__BEOS__)
+/* BeOS suffers from the same socket dichotomy as Win32... - [cjh] */
+/* seem to be a few differences in the API */
+#define SOCKETCLOSE closesocket
+#define NO_DUP /* Actually it exists on NT 3.5, but what the heck... */
+#endif
+
+#ifdef MS_WIN32
+#define EAFNOSUPPORT WSAEAFNOSUPPORT
+#define snprintf _snprintf
+#endif
+
+#if defined(PYOS_OS2) && !defined(PYCC_GCC)
+#define SOCKETCLOSE soclose
+#define NO_DUP /* Sockets are Not Actual File Handles under OS/2 */
+#endif
+
+#ifndef SOCKETCLOSE
+#define SOCKETCLOSE close
+#endif
+
+#if defined(HAVE_BLUETOOTH_H) || defined(HAVE_BLUETOOTH_BLUETOOTH_H)
+#define USE_BLUETOOTH 1
+#if defined(__FreeBSD__)
+#define BTPROTO_L2CAP BLUETOOTH_PROTO_L2CAP
+#define BTPROTO_RFCOMM BLUETOOTH_PROTO_RFCOMM
+#define sockaddr_l2 sockaddr_l2cap
+#define sockaddr_rc sockaddr_rfcomm
+#define _BT_L2_MEMB(sa, memb) ((sa)->l2cap_##memb)
+#define _BT_RC_MEMB(sa, memb) ((sa)->rfcomm_##memb)
+#elif defined(__NetBSD__)
+#define sockaddr_l2 sockaddr_bt
+#define sockaddr_rc sockaddr_bt
+#define sockaddr_sco sockaddr_bt
+#define _BT_L2_MEMB(sa, memb) ((sa)->bt_##memb)
+#define _BT_RC_MEMB(sa, memb) ((sa)->bt_##memb)
+#define _BT_SCO_MEMB(sa, memb) ((sa)->bt_##memb)
+#else
+#define _BT_L2_MEMB(sa, memb) ((sa)->l2_##memb)
+#define _BT_RC_MEMB(sa, memb) ((sa)->rc_##memb)
+#define _BT_SCO_MEMB(sa, memb) ((sa)->sco_##memb)
+#endif
+#endif
+
+#ifdef __VMS
+/* TCP/IP Services for VMS uses a maximum send/recv buffer length */
+#define SEGMENT_SIZE (32 * 1024 -1)
+#endif
+
+#define	SAS2SA(x)	((struct sockaddr *)(x))
+
+/*
+ * Constants for getnameinfo()
+ */
+#if !defined(NI_MAXHOST)
+#define NI_MAXHOST 1025
+#endif
+#if !defined(NI_MAXSERV)
+#define NI_MAXSERV 32
+#endif
+
+/* XXX There's a problem here: *static* functions are not supposed to have
+   a Py prefix (or use CapitalizedWords).  Later... */
+
+/* Global variable holding the exception type for errors detected
+   by this module (but not argument type or memory errors, etc.). */
+static PyObject *socket_error;
+static PyObject *socket_herror;
+static PyObject *socket_gaierror;
+static PyObject *socket_timeout;
+
+#ifdef RISCOS
+/* Global variable which is !=0 if Python is running in a RISC OS taskwindow */
+static int taskwindow;
+#endif
+
+/* A forward reference to the socket type object.
+   The sock_type variable contains pointers to various functions,
+   some of which call new_sockobject(), which uses sock_type, so
+   there has to be a circular reference. */
+static PyTypeObject sock_type;
+
+#if defined(HAVE_POLL_H)
+#include <poll.h>
+#elif defined(HAVE_SYS_POLL_H)
+#include <sys/poll.h>
+#endif
+
+#ifdef Py_SOCKET_FD_CAN_BE_GE_FD_SETSIZE
+/* Platform can select file descriptors beyond FD_SETSIZE */
+#define IS_SELECTABLE(s) 1
+#elif defined(HAVE_POLL)
+/* Instead of select(), we'll use poll() since poll() works on any fd. */
+#define IS_SELECTABLE(s) 1
+/* Can we call select() with this socket without a buffer overrun? */
+#else
+/* POSIX says selecting file descriptors beyond FD_SETSIZE
+   has undefined behaviour.  If there's no timeout left, we don't have to
+   call select, so it's a safe, little white lie. */
+#define IS_SELECTABLE(s) ((s)->sock_fd < FD_SETSIZE || s->sock_timeout <= 0.0)
+#endif
+
+static PyObject*
+select_error(void)
+{
+	PyErr_SetString(socket_error, "unable to select on socket");
+	return NULL;
+}
+
+/* Convenience function to raise an error according to errno
+   and return a NULL pointer from a function. */
+
+static PyObject *
+set_error(void)
+{
+#ifdef MS_WINDOWS
+	int err_no = WSAGetLastError();
+	static struct {
+		int no;
+		const char *msg;
+	} *msgp, msgs[] = {
+		{WSAEINTR, "Interrupted system call"},
+		{WSAEBADF, "Bad file descriptor"},
+		{WSAEACCES, "Permission denied"},
+		{WSAEFAULT, "Bad address"},
+		{WSAEINVAL, "Invalid argument"},
+		{WSAEMFILE, "Too many open files"},
+		{WSAEWOULDBLOCK,
+		  "The socket operation could not complete "
+		  "without blocking"},
+		{WSAEINPROGRESS, "Operation now in progress"},
+		{WSAEALREADY, "Operation already in progress"},
+		{WSAENOTSOCK, "Socket operation on non-socket"},
+		{WSAEDESTADDRREQ, "Destination address required"},
+		{WSAEMSGSIZE, "Message too long"},
+		{WSAEPROTOTYPE, "Protocol wrong type for socket"},
+		{WSAENOPROTOOPT, "Protocol not available"},
+		{WSAEPROTONOSUPPORT, "Protocol not supported"},
+		{WSAESOCKTNOSUPPORT, "Socket type not supported"},
+		{WSAEOPNOTSUPP, "Operation not supported"},
+		{WSAEPFNOSUPPORT, "Protocol family not supported"},
+		{WSAEAFNOSUPPORT, "Address family not supported"},
+		{WSAEADDRINUSE, "Address already in use"},
+		{WSAEADDRNOTAVAIL, "Can't assign requested address"},
+		{WSAENETDOWN, "Network is down"},
+		{WSAENETUNREACH, "Network is unreachable"},
+		{WSAENETRESET, "Network dropped connection on reset"},
+		{WSAECONNABORTED, "Software caused connection abort"},
+		{WSAECONNRESET, "Connection reset by peer"},
+		{WSAENOBUFS, "No buffer space available"},
+		{WSAEISCONN, "Socket is already connected"},
+		{WSAENOTCONN, "Socket is not connected"},
+		{WSAESHUTDOWN, "Can't send after socket shutdown"},
+		{WSAETOOMANYREFS, "Too many references: can't splice"},
+		{WSAETIMEDOUT, "Operation timed out"},
+		{WSAECONNREFUSED, "Connection refused"},
+		{WSAELOOP, "Too many levels of symbolic links"},
+		{WSAENAMETOOLONG, "File name too long"},
+		{WSAEHOSTDOWN, "Host is down"},
+		{WSAEHOSTUNREACH, "No route to host"},
+		{WSAENOTEMPTY, "Directory not empty"},
+		{WSAEPROCLIM, "Too many processes"},
+		{WSAEUSERS, "Too many users"},
+		{WSAEDQUOT, "Disc quota exceeded"},
+		{WSAESTALE, "Stale NFS file handle"},
+		{WSAEREMOTE, "Too many levels of remote in path"},
+		{WSASYSNOTREADY, "Network subsystem is unvailable"},
+		{WSAVERNOTSUPPORTED, "WinSock version is not supported"},
+		{WSANOTINITIALISED,
+		  "Successful WSAStartup() not yet performed"},
+		{WSAEDISCON, "Graceful shutdown in progress"},
+		/* Resolver errors */
+		{WSAHOST_NOT_FOUND, "No such host is known"},
+		{WSATRY_AGAIN, "Host not found, or server failed"},
+		{WSANO_RECOVERY, "Unexpected server error encountered"},
+		{WSANO_DATA, "Valid name without requested data"},
+		{WSANO_ADDRESS, "No address, look for MX record"},
+		{0, NULL}
+	};
+	if (err_no) {
+		PyObject *v;
+		const char *msg = "winsock error";
+
+		for (msgp = msgs; msgp->msg; msgp++) {
+			if (err_no == msgp->no) {
+				msg = msgp->msg;
+				break;
+			}
+		}
+
+		v = Py_BuildValue("(is)", err_no, msg);
+		if (v != NULL) {
+			PyErr_SetObject(socket_error, v);
+			Py_DECREF(v);
+		}
+		return NULL;
+	}
+	else
+#endif
+
+#if defined(PYOS_OS2) && !defined(PYCC_GCC)
+	if (sock_errno() != NO_ERROR) {
+		APIRET rc;
+		ULONG  msglen;
+		char outbuf[100];
+		int myerrorcode = sock_errno();
+
+		/* Retrieve socket-related error message from MPTN.MSG file */
+		rc = DosGetMessage(NULL, 0, outbuf, sizeof(outbuf),
+				   myerrorcode - SOCBASEERR + 26,
+				   "mptn.msg",
+				   &msglen);
+		if (rc == NO_ERROR) {
+			PyObject *v;
+
+			/* OS/2 doesn't guarantee a terminator */
+			outbuf[msglen] = '\0';
+			if (strlen(outbuf) > 0) {
+				/* If non-empty msg, trim CRLF */
+				char *lastc = &outbuf[ strlen(outbuf)-1 ];
+				while (lastc > outbuf &&
+				       isspace(Py_CHARMASK(*lastc))) {
+					/* Trim trailing whitespace (CRLF) */
+					*lastc-- = '\0';
+				}
+			}
+			v = Py_BuildValue("(is)", myerrorcode, outbuf);
+			if (v != NULL) {
+				PyErr_SetObject(socket_error, v);
+				Py_DECREF(v);
+			}
+			return NULL;
+		}
+	}
+#endif
+
+#if defined(RISCOS)
+	if (_inet_error.errnum != NULL) {
+		PyObject *v;
+		v = Py_BuildValue("(is)", errno, _inet_err());
+		if (v != NULL) {
+			PyErr_SetObject(socket_error, v);
+			Py_DECREF(v);
+		}
+		return NULL;
+	}
+#endif
+
+	return PyErr_SetFromErrno(socket_error);
+}
+
+
+static PyObject *
+set_herror(int h_error)
+{
+	PyObject *v;
+
+#ifdef HAVE_HSTRERROR
+	v = Py_BuildValue("(is)", h_error, (char *)hstrerror(h_error));
+#else
+	v = Py_BuildValue("(is)", h_error, "host not found");
+#endif
+	if (v != NULL) {
+		PyErr_SetObject(socket_herror, v);
+		Py_DECREF(v);
+	}
+
+	return NULL;
+}
+
+
+static PyObject *
+set_gaierror(int error)
+{
+	PyObject *v;
+
+#ifdef EAI_SYSTEM
+	/* EAI_SYSTEM is not available on Windows XP. */
+	if (error == EAI_SYSTEM)
+		return set_error();
+#endif
+
+#ifdef HAVE_GAI_STRERROR
+	v = Py_BuildValue("(is)", error, gai_strerror(error));
+#else
+	v = Py_BuildValue("(is)", error, "getaddrinfo failed");
+#endif
+	if (v != NULL) {
+		PyErr_SetObject(socket_gaierror, v);
+		Py_DECREF(v);
+	}
+
+	return NULL;
+}
+
+#ifdef __VMS
+/* Function to send in segments */
+static int
+sendsegmented(int sock_fd, char *buf, int len, int flags)
+{
+	int n = 0;
+	int remaining = len;
+
+	while (remaining > 0) {
+		unsigned int segment;
+
+		segment = (remaining >= SEGMENT_SIZE ? SEGMENT_SIZE : remaining);
+		n = send(sock_fd, buf, segment, flags);
+		if (n < 0) {
+			return n;
+		}
+		remaining -= segment;
+		buf += segment;
+	} /* end while */
+
+	return len;
+}
+#endif
+
+/* Function to perform the setting of socket blocking mode
+   internally. block = (1 | 0). */
+static int
+internal_setblocking(PySocketSockObject *s, int block)
+{
+#ifndef RISCOS
+#ifndef MS_WINDOWS
+	int delay_flag;
+#endif
+#endif
+
+	Py_BEGIN_ALLOW_THREADS
+#ifdef __BEOS__
+	block = !block;
+	setsockopt(s->sock_fd, SOL_SOCKET, SO_NONBLOCK,
+		   (void *)(&block), sizeof(int));
+#else
+#ifndef RISCOS
+#ifndef MS_WINDOWS
+#if defined(PYOS_OS2) && !defined(PYCC_GCC)
+	block = !block;
+	ioctl(s->sock_fd, FIONBIO, (caddr_t)&block, sizeof(block));
+#elif defined(__VMS)
+	block = !block;
+	ioctl(s->sock_fd, FIONBIO, (unsigned int *)&block);
+#else  /* !PYOS_OS2 && !__VMS */
+	delay_flag = fcntl(s->sock_fd, F_GETFL, 0);
+	if (block)
+		delay_flag &= (~O_NONBLOCK);
+	else
+		delay_flag |= O_NONBLOCK;
+	fcntl(s->sock_fd, F_SETFL, delay_flag);
+#endif /* !PYOS_OS2 */
+#else /* MS_WINDOWS */
+	block = !block;
+	ioctlsocket(s->sock_fd, FIONBIO, (u_long*)&block);
+#endif /* MS_WINDOWS */
+#else /* RISCOS */
+	block = !block;
+	socketioctl(s->sock_fd, FIONBIO, (u_long*)&block);
+#endif /* RISCOS */
+#endif /* __BEOS__ */
+	Py_END_ALLOW_THREADS
+
+	/* Since these don't return anything */
+	return 1;
+}
+
+/* Do a select()/poll() on the socket, if necessary (sock_timeout > 0).
+   The argument writing indicates the direction.
+   This does not raise an exception; we'll let our caller do that
+   after they've reacquired the interpreter lock.
+   Returns 1 on timeout, -1 on error, 0 otherwise. */
+static int
+internal_select(PySocketSockObject *s, int writing)
+{
+	int n;
+
+	/* Nothing to do unless we're in timeout mode (not non-blocking) */
+	if (s->sock_timeout <= 0.0)
+		return 0;
+
+	/* Guard against closed socket */
+	if (s->sock_fd < 0)
+		return 0;
+
+	/* Prefer poll, if available, since you can poll() any fd
+	 * which can't be done with select(). */
+#ifdef HAVE_POLL
+	{
+		struct pollfd pollfd;
+		int timeout;
+
+		pollfd.fd = s->sock_fd;
+		pollfd.events = writing ? POLLOUT : POLLIN;
+
+		/* s->sock_timeout is in seconds, timeout in ms */
+		timeout = (int)(s->sock_timeout * 1000 + 0.5); 
+		n = poll(&pollfd, 1, timeout);
+	}
+#else
+	{
+		/* Construct the arguments to select */
+		fd_set fds;
+		struct timeval tv;
+		tv.tv_sec = (int)s->sock_timeout;
+		tv.tv_usec = (int)((s->sock_timeout - tv.tv_sec) * 1e6);
+		FD_ZERO(&fds);
+		FD_SET(s->sock_fd, &fds);
+
+		/* See if the socket is ready */
+		if (writing)
+			n = select(s->sock_fd+1, NULL, &fds, NULL, &tv);
+		else
+			n = select(s->sock_fd+1, &fds, NULL, NULL, &tv);
+	}
+#endif
+	
+	if (n < 0)
+		return -1;
+	if (n == 0)
+		return 1;
+	return 0;
+}
+
+/* Initialize a new socket object. */
+
+static double defaulttimeout = -1.0; /* Default timeout for new sockets */
+
+PyMODINIT_FUNC
+init_sockobject(PySocketSockObject *s,
+		SOCKET_T fd, int family, int type, int proto)
+{
+#ifdef RISCOS
+	int block = 1;
+#endif
+	s->sock_fd = fd;
+	s->sock_family = family;
+	s->sock_type = type;
+	s->sock_proto = proto;
+	s->sock_timeout = defaulttimeout;
+
+	s->errorhandler = &set_error;
+
+	if (defaulttimeout >= 0.0)
+		internal_setblocking(s, 0);
+
+#ifdef RISCOS
+	if (taskwindow)
+		socketioctl(s->sock_fd, 0x80046679, (u_long*)&block);
+#endif
+}
+
+
+/* Create a new socket object.
+   This just creates the object and initializes it.
+   If the creation fails, return NULL and set an exception (implicit
+   in NEWOBJ()). */
+
+static PySocketSockObject *
+new_sockobject(SOCKET_T fd, int family, int type, int proto)
+{
+	PySocketSockObject *s;
+	s = (PySocketSockObject *)
+		PyType_GenericNew(&sock_type, NULL, NULL);
+	if (s != NULL)
+		init_sockobject(s, fd, family, type, proto);
+	return s;
+}
+
+
+/* Lock to allow python interpreter to continue, but only allow one
+   thread to be in gethostbyname or getaddrinfo */
+#if defined(USE_GETHOSTBYNAME_LOCK) || defined(USE_GETADDRINFO_LOCK)
+PyThread_type_lock netdb_lock;
+#endif
+
+
+/* Convert a string specifying a host name or one of a few symbolic
+   names to a numeric IP address.  This usually calls gethostbyname()
+   to do the work; the names "" and "<broadcast>" are special.
+   Return the length (IPv4 should be 4 bytes), or negative if
+   an error occurred; then an exception is raised. */
+
+static int
+setipaddr(char *name, struct sockaddr *addr_ret, size_t addr_ret_size, int af)
+{
+	struct addrinfo hints, *res;
+	int error;
+	int d1, d2, d3, d4;
+	char ch;
+
+	memset((void *) addr_ret, '\0', sizeof(*addr_ret));
+	if (name[0] == '\0') {
+		int siz;
+		memset(&hints, 0, sizeof(hints));
+		hints.ai_family = af;
+		hints.ai_socktype = SOCK_DGRAM;	/*dummy*/
+		hints.ai_flags = AI_PASSIVE;
+		Py_BEGIN_ALLOW_THREADS
+		ACQUIRE_GETADDRINFO_LOCK
+		error = getaddrinfo(NULL, "0", &hints, &res);
+		Py_END_ALLOW_THREADS
+		/* We assume that those thread-unsafe getaddrinfo() versions
+		   *are* safe regarding their return value, ie. that a
+		   subsequent call to getaddrinfo() does not destroy the
+		   outcome of the first call. */
+		RELEASE_GETADDRINFO_LOCK
+		if (error) {
+			set_gaierror(error);
+			return -1;
+		}
+		switch (res->ai_family) {
+		case AF_INET:
+			siz = 4;
+			break;
+#ifdef ENABLE_IPV6
+		case AF_INET6:
+			siz = 16;
+			break;
+#endif
+		default:
+			freeaddrinfo(res);
+			PyErr_SetString(socket_error,
+				"unsupported address family");
+			return -1;
+		}
+		if (res->ai_next) {
+			freeaddrinfo(res);
+			PyErr_SetString(socket_error,
+				"wildcard resolved to multiple address");
+			return -1;
+		}
+		if (res->ai_addrlen < addr_ret_size)
+			addr_ret_size = res->ai_addrlen;
+		memcpy(addr_ret, res->ai_addr, addr_ret_size);
+		freeaddrinfo(res);
+		return siz;
+	}
+	if (name[0] == '<' && strcmp(name, "<broadcast>") == 0) {
+		struct sockaddr_in *sin;
+		if (af != AF_INET && af != AF_UNSPEC) {
+			PyErr_SetString(socket_error,
+				"address family mismatched");
+			return -1;
+		}
+		sin = (struct sockaddr_in *)addr_ret;
+		memset((void *) sin, '\0', sizeof(*sin));
+		sin->sin_family = AF_INET;
+#ifdef HAVE_SOCKADDR_SA_LEN
+		sin->sin_len = sizeof(*sin);
+#endif
+		sin->sin_addr.s_addr = INADDR_BROADCAST;
+		return sizeof(sin->sin_addr);
+	}
+	if (sscanf(name, "%d.%d.%d.%d%c", &d1, &d2, &d3, &d4, &ch) == 4 &&
+	    0 <= d1 && d1 <= 255 && 0 <= d2 && d2 <= 255 &&
+	    0 <= d3 && d3 <= 255 && 0 <= d4 && d4 <= 255) {
+		struct sockaddr_in *sin;
+		sin = (struct sockaddr_in *)addr_ret;
+		sin->sin_addr.s_addr = htonl(
+			((long) d1 << 24) | ((long) d2 << 16) |
+			((long) d3 << 8) | ((long) d4 << 0));
+		sin->sin_family = AF_INET;
+#ifdef HAVE_SOCKADDR_SA_LEN
+		sin->sin_len = sizeof(*sin);
+#endif
+		return 4;
+	}
+	memset(&hints, 0, sizeof(hints));
+	hints.ai_family = af;
+	Py_BEGIN_ALLOW_THREADS
+	ACQUIRE_GETADDRINFO_LOCK
+	error = getaddrinfo(name, NULL, &hints, &res);
+#if defined(__digital__) && defined(__unix__)
+	if (error == EAI_NONAME && af == AF_UNSPEC) {
+		/* On Tru64 V5.1, numeric-to-addr conversion fails
+		   if no address family is given. Assume IPv4 for now.*/
+		hints.ai_family = AF_INET;
+		error = getaddrinfo(name, NULL, &hints, &res);
+	}
+#endif
+	Py_END_ALLOW_THREADS
+	RELEASE_GETADDRINFO_LOCK  /* see comment in setipaddr() */
+	if (error) {
+		set_gaierror(error);
+		return -1;
+	}
+	if (res->ai_addrlen < addr_ret_size)
+		addr_ret_size = res->ai_addrlen;
+	memcpy((char *) addr_ret, res->ai_addr, addr_ret_size);
+	freeaddrinfo(res);
+	switch (addr_ret->sa_family) {
+	case AF_INET:
+		return 4;
+#ifdef ENABLE_IPV6
+	case AF_INET6:
+		return 16;
+#endif
+	default:
+		PyErr_SetString(socket_error, "unknown address family");
+		return -1;
+	}
+}
+
+
+/* Create a string object representing an IP address.
+   This is always a string of the form 'dd.dd.dd.dd' (with variable
+   size numbers). */
+
+static PyObject *
+makeipaddr(struct sockaddr *addr, int addrlen)
+{
+	char buf[NI_MAXHOST];
+	int error;
+
+	error = getnameinfo(addr, addrlen, buf, sizeof(buf), NULL, 0,
+		NI_NUMERICHOST);
+	if (error) {
+		set_gaierror(error);
+		return NULL;
+	}
+	return PyString_FromString(buf);
+}
+
+
+#ifdef USE_BLUETOOTH
+/* Convert a string representation of a Bluetooth address into a numeric
+   address.  Returns the length (6), or raises an exception and returns -1 if
+   an error occurred. */
+
+static int
+setbdaddr(char *name, bdaddr_t *bdaddr)
+{
+	unsigned int b0, b1, b2, b3, b4, b5;
+	char ch;
+	int n;
+
+	n = sscanf(name, "%X:%X:%X:%X:%X:%X%c",
+		   &b5, &b4, &b3, &b2, &b1, &b0, &ch);
+	if (n == 6 && (b0 | b1 | b2 | b3 | b4 | b5) < 256) {
+		bdaddr->b[0] = b0;
+		bdaddr->b[1] = b1;
+		bdaddr->b[2] = b2;
+		bdaddr->b[3] = b3;
+		bdaddr->b[4] = b4;
+		bdaddr->b[5] = b5;
+		return 6;
+	} else {
+		PyErr_SetString(socket_error, "bad bluetooth address");
+		return -1;
+	}
+}
+
+/* Create a string representation of the Bluetooth address.  This is always a
+   string of the form 'XX:XX:XX:XX:XX:XX' where XX is a two digit hexadecimal
+   value (zero padded if necessary). */
+
+static PyObject *
+makebdaddr(bdaddr_t *bdaddr)
+{
+	char buf[(6 * 2) + 5 + 1];
+
+	sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X",
+		bdaddr->b[5], bdaddr->b[4], bdaddr->b[3],
+		bdaddr->b[2], bdaddr->b[1], bdaddr->b[0]);
+	return PyString_FromString(buf);
+}
+#endif
+
+
+/* Create an object representing the given socket address,
+   suitable for passing it back to bind(), connect() etc.
+   The family field of the sockaddr structure is inspected
+   to determine what kind of address it really is. */
+
+/*ARGSUSED*/
+static PyObject *
+makesockaddr(int sockfd, struct sockaddr *addr, int addrlen, int proto)
+{
+	if (addrlen == 0) {
+		/* No address -- may be recvfrom() from known socket */
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+
+#ifdef __BEOS__
+	/* XXX: BeOS version of accept() doesn't set family correctly */
+	addr->sa_family = AF_INET;
+#endif
+
+	switch (addr->sa_family) {
+
+	case AF_INET:
+	{
+		struct sockaddr_in *a;
+		PyObject *addrobj = makeipaddr(addr, sizeof(*a));
+		PyObject *ret = NULL;
+		if (addrobj) {
+			a = (struct sockaddr_in *)addr;
+			ret = Py_BuildValue("Oi", addrobj, ntohs(a->sin_port));
+			Py_DECREF(addrobj);
+		}
+		return ret;
+	}
+
+#if defined(AF_UNIX)
+	case AF_UNIX:
+	{
+		struct sockaddr_un *a = (struct sockaddr_un *) addr;
+#ifdef linux
+		if (a->sun_path[0] == 0) {  /* Linux abstract namespace */
+			addrlen -= (sizeof(*a) - sizeof(a->sun_path));
+			return PyString_FromStringAndSize(a->sun_path,
+							  addrlen);
+		}
+		else
+#endif /* linux */
+		{
+			/* regular NULL-terminated string */
+			return PyString_FromString(a->sun_path);
+		}
+	}
+#endif /* AF_UNIX */
+
+#if defined(AF_NETLINK)
+       case AF_NETLINK:
+       {
+               struct sockaddr_nl *a = (struct sockaddr_nl *) addr;
+               return Py_BuildValue("II", a->nl_pid, a->nl_groups);
+       }
+#endif /* AF_NETLINK */
+
+#ifdef ENABLE_IPV6
+	case AF_INET6:
+	{
+		struct sockaddr_in6 *a;
+		PyObject *addrobj = makeipaddr(addr, sizeof(*a));
+		PyObject *ret = NULL;
+		if (addrobj) {
+			a = (struct sockaddr_in6 *)addr;
+			ret = Py_BuildValue("Oiii",
+					    addrobj,
+					    ntohs(a->sin6_port),
+					    a->sin6_flowinfo,
+					    a->sin6_scope_id);
+			Py_DECREF(addrobj);
+		}
+		return ret;
+	}
+#endif
+
+#ifdef USE_BLUETOOTH
+	case AF_BLUETOOTH:
+		switch (proto) {
+
+		case BTPROTO_L2CAP:
+		{
+			struct sockaddr_l2 *a = (struct sockaddr_l2 *) addr;
+			PyObject *addrobj = makebdaddr(&_BT_L2_MEMB(a, bdaddr));
+			PyObject *ret = NULL;
+			if (addrobj) {
+				ret = Py_BuildValue("Oi",
+						    addrobj,
+						    _BT_L2_MEMB(a, psm));
+				Py_DECREF(addrobj);
+			}
+			return ret;
+		}
+
+		case BTPROTO_RFCOMM:
+		{
+			struct sockaddr_rc *a = (struct sockaddr_rc *) addr;
+			PyObject *addrobj = makebdaddr(&_BT_RC_MEMB(a, bdaddr));
+			PyObject *ret = NULL;
+			if (addrobj) {
+				ret = Py_BuildValue("Oi",
+						    addrobj,
+						    _BT_RC_MEMB(a, channel));
+				Py_DECREF(addrobj);
+			}
+			return ret;
+		}
+
+#if !defined(__FreeBSD__)
+		case BTPROTO_SCO:
+		{
+			struct sockaddr_sco *a = (struct sockaddr_sco *) addr;
+			return makebdaddr(&_BT_SCO_MEMB(a, bdaddr));
+		}
+#endif
+
+		}
+#endif
+
+#ifdef HAVE_NETPACKET_PACKET_H
+	case AF_PACKET:
+	{
+		struct sockaddr_ll *a = (struct sockaddr_ll *)addr;
+		char *ifname = "";
+		struct ifreq ifr;
+		/* need to look up interface name give index */
+		if (a->sll_ifindex) {
+			ifr.ifr_ifindex = a->sll_ifindex;
+			if (ioctl(sockfd, SIOCGIFNAME, &ifr) == 0)
+				ifname = ifr.ifr_name;
+		}
+		return Py_BuildValue("shbhs#",
+				     ifname,
+				     ntohs(a->sll_protocol),
+				     a->sll_pkttype,
+				     a->sll_hatype,
+				     a->sll_addr,
+				     a->sll_halen);
+	}
+#endif
+
+	/* More cases here... */
+
+	default:
+		/* If we don't know the address family, don't raise an
+		   exception -- return it as a tuple. */
+		return Py_BuildValue("is#",
+				     addr->sa_family,
+				     addr->sa_data,
+				     sizeof(addr->sa_data));
+
+	}
+}
+
+
+/* Parse a socket address argument according to the socket object's
+   address family.  Return 1 if the address was in the proper format,
+   0 of not.  The address is returned through addr_ret, its length
+   through len_ret. */
+
+static int
+getsockaddrarg(PySocketSockObject *s, PyObject *args,
+	       struct sockaddr *addr_ret, int *len_ret)
+{
+	switch (s->sock_family) {
+
+#if defined(AF_UNIX)
+	case AF_UNIX:
+	{
+		struct sockaddr_un* addr;
+		char *path;
+		int len;
+		if (!PyArg_Parse(args, "t#", &path, &len))
+			return 0;
+
+		addr = (struct sockaddr_un*)addr_ret;
+#ifdef linux
+		if (len > 0 && path[0] == 0) {
+			/* Linux abstract namespace extension */
+			if (len > sizeof addr->sun_path) {
+				PyErr_SetString(socket_error,
+						"AF_UNIX path too long");
+				return 0;
+			}
+		}
+		else
+#endif /* linux */
+                {
+			/* regular NULL-terminated string */
+			if (len >= sizeof addr->sun_path) {
+				PyErr_SetString(socket_error,
+						"AF_UNIX path too long");
+				return 0;
+			}
+			addr->sun_path[len] = 0;
+		}
+		addr->sun_family = s->sock_family;
+		memcpy(addr->sun_path, path, len);
+#if defined(PYOS_OS2)
+		*len_ret = sizeof(*addr);
+#else
+		*len_ret = len + sizeof(*addr) - sizeof(addr->sun_path);
+#endif
+		return 1;
+	}
+#endif /* AF_UNIX */
+
+#if defined(AF_NETLINK)
+	case AF_NETLINK:
+	{
+		struct sockaddr_nl* addr;
+		int pid, groups;
+		addr = (struct sockaddr_nl *)addr_ret;
+		if (!PyTuple_Check(args)) {
+			PyErr_Format(
+				PyExc_TypeError,
+				"getsockaddrarg: "
+				"AF_NETLINK address must be tuple, not %.500s",
+				args->ob_type->tp_name);
+			return 0;
+		}
+		if (!PyArg_ParseTuple(args, "II:getsockaddrarg", &pid, &groups))
+			return 0;
+		addr->nl_family = AF_NETLINK;
+		addr->nl_pid = pid;
+		addr->nl_groups = groups;
+		*len_ret = sizeof(*addr);
+		return 1;
+	}
+#endif
+
+	case AF_INET:
+	{
+		struct sockaddr_in* addr;
+		char *host;
+		int port, result;
+		if (!PyTuple_Check(args)) {
+			PyErr_Format(
+				PyExc_TypeError,
+				"getsockaddrarg: "
+				"AF_INET address must be tuple, not %.500s",
+				args->ob_type->tp_name);
+			return 0;
+		}
+		if (!PyArg_ParseTuple(args, "eti:getsockaddrarg",
+				      "idna", &host, &port))
+			return 0;
+		addr=(struct sockaddr_in*)addr_ret;
+                result = setipaddr(host, (struct sockaddr *)addr,
+                                   sizeof(*addr),  AF_INET);
+                PyMem_Free(host);
+                if (result < 0)
+			return 0;
+		addr->sin_family = AF_INET;
+		addr->sin_port = htons((short)port);
+		*len_ret = sizeof *addr;
+		return 1;
+	}
+
+#ifdef ENABLE_IPV6
+	case AF_INET6:
+	{
+		struct sockaddr_in6* addr;
+		char *host;
+		int port, flowinfo, scope_id, result;
+		flowinfo = scope_id = 0;
+		if (!PyTuple_Check(args)) {
+			PyErr_Format(
+				PyExc_TypeError,
+				"getsockaddrarg: "
+				"AF_INET6 address must be tuple, not %.500s",
+				args->ob_type->tp_name);
+			return 0;
+		}
+		if (!PyArg_ParseTuple(args, "eti|ii",
+				      "idna", &host, &port, &flowinfo,
+				      &scope_id)) {
+			return 0;
+		}
+		addr = (struct sockaddr_in6*)addr_ret;
+                result = setipaddr(host, (struct sockaddr *)addr,
+                                   sizeof(*addr), AF_INET6);
+                PyMem_Free(host);
+                if (result < 0)
+			return 0;
+		addr->sin6_family = s->sock_family;
+		addr->sin6_port = htons((short)port);
+		addr->sin6_flowinfo = flowinfo;
+		addr->sin6_scope_id = scope_id;
+		*len_ret = sizeof *addr;
+		return 1;
+	}
+#endif
+
+#ifdef USE_BLUETOOTH
+	case AF_BLUETOOTH:
+	{
+		switch (s->sock_proto) {
+		case BTPROTO_L2CAP:
+		{
+			struct sockaddr_l2 *addr;
+			char *straddr;
+
+			addr = (struct sockaddr_l2 *)addr_ret;
+			_BT_L2_MEMB(addr, family) = AF_BLUETOOTH;
+			if (!PyArg_ParseTuple(args, "si", &straddr,
+					      &_BT_L2_MEMB(addr, psm))) {
+				PyErr_SetString(socket_error, "getsockaddrarg: "
+						"wrong format");
+				return 0;
+			}
+			if (setbdaddr(straddr, &_BT_L2_MEMB(addr, bdaddr)) < 0)
+				return 0;
+
+			*len_ret = sizeof *addr;
+			return 1;
+		}
+		case BTPROTO_RFCOMM:
+		{
+			struct sockaddr_rc *addr;
+			char *straddr;
+
+			addr = (struct sockaddr_rc *)addr_ret;
+			_BT_RC_MEMB(addr, family) = AF_BLUETOOTH;
+			if (!PyArg_ParseTuple(args, "si", &straddr,
+					      &_BT_RC_MEMB(addr, channel))) {
+				PyErr_SetString(socket_error, "getsockaddrarg: "
+						"wrong format");
+				return 0;
+			}
+			if (setbdaddr(straddr, &_BT_RC_MEMB(addr, bdaddr)) < 0)
+				return 0;
+
+			*len_ret = sizeof *addr;
+			return 1;
+		}
+#if !defined(__FreeBSD__)
+		case BTPROTO_SCO:
+		{
+			struct sockaddr_sco *addr;
+			char *straddr;
+
+			addr = (struct sockaddr_sco *)addr_ret;
+			_BT_SCO_MEMB(addr, family) = AF_BLUETOOTH;
+			straddr = PyString_AsString(args);
+			if (straddr == NULL) {
+				PyErr_SetString(socket_error, "getsockaddrarg: "
+						"wrong format");
+				return 0;
+			}
+			if (setbdaddr(straddr, &_BT_SCO_MEMB(addr, bdaddr)) < 0)
+				return 0;
+
+			*len_ret = sizeof *addr;
+			return 1;
+		}
+#endif
+		default:
+			PyErr_SetString(socket_error, "getsockaddrarg: unknown Bluetooth protocol");
+			return 0;
+		}
+	}
+#endif
+
+#ifdef HAVE_NETPACKET_PACKET_H
+	case AF_PACKET:
+	{
+		struct sockaddr_ll* addr;
+		struct ifreq ifr;
+		char *interfaceName;
+		int protoNumber;
+		int hatype = 0;
+		int pkttype = 0;
+		char *haddr = NULL;
+		unsigned int halen = 0;
+
+		if (!PyTuple_Check(args)) {
+			PyErr_Format(
+				PyExc_TypeError,
+				"getsockaddrarg: "
+				"AF_PACKET address must be tuple, not %.500s",
+				args->ob_type->tp_name);
+			return 0;
+		}
+		if (!PyArg_ParseTuple(args, "si|iis#", &interfaceName,
+				      &protoNumber, &pkttype, &hatype,
+				      &haddr, &halen))
+			return 0;
+		strncpy(ifr.ifr_name, interfaceName, sizeof(ifr.ifr_name));
+		ifr.ifr_name[(sizeof(ifr.ifr_name))-1] = '\0';
+		if (ioctl(s->sock_fd, SIOCGIFINDEX, &ifr) < 0) {
+		        s->errorhandler();
+			return 0;
+		}
+		if (halen > 8) {
+		  PyErr_SetString(PyExc_ValueError,
+				  "Hardware address must be 8 bytes or less");
+		  return 0;
+		}
+		addr = (struct sockaddr_ll*)addr_ret;
+		addr->sll_family = AF_PACKET;
+		addr->sll_protocol = htons((short)protoNumber);
+		addr->sll_ifindex = ifr.ifr_ifindex;
+		addr->sll_pkttype = pkttype;
+		addr->sll_hatype = hatype;
+		if (halen != 0) {
+		  memcpy(&addr->sll_addr, haddr, halen);
+		}
+		addr->sll_halen = halen;
+		*len_ret = sizeof *addr;
+		return 1;
+	}
+#endif
+
+	/* More cases here... */
+
+	default:
+		PyErr_SetString(socket_error, "getsockaddrarg: bad family");
+		return 0;
+
+	}
+}
+
+
+/* Get the address length according to the socket object's address family.
+   Return 1 if the family is known, 0 otherwise.  The length is returned
+   through len_ret. */
+
+static int
+getsockaddrlen(PySocketSockObject *s, socklen_t *len_ret)
+{
+	switch (s->sock_family) {
+
+#if defined(AF_UNIX)
+	case AF_UNIX:
+	{
+		*len_ret = sizeof (struct sockaddr_un);
+		return 1;
+	}
+#endif /* AF_UNIX */
+#if defined(AF_NETLINK)
+       case AF_NETLINK:
+       {
+               *len_ret = sizeof (struct sockaddr_nl);
+               return 1;
+       }
+#endif
+
+	case AF_INET:
+	{
+		*len_ret = sizeof (struct sockaddr_in);
+		return 1;
+	}
+
+#ifdef ENABLE_IPV6
+	case AF_INET6:
+	{
+		*len_ret = sizeof (struct sockaddr_in6);
+		return 1;
+	}
+#endif
+
+#ifdef USE_BLUETOOTH
+	case AF_BLUETOOTH:
+	{
+		switch(s->sock_proto)
+		{
+
+		case BTPROTO_L2CAP:
+			*len_ret = sizeof (struct sockaddr_l2);
+			return 1;
+		case BTPROTO_RFCOMM:
+			*len_ret = sizeof (struct sockaddr_rc);
+			return 1;
+#if !defined(__FreeBSD__)
+		case BTPROTO_SCO:
+			*len_ret = sizeof (struct sockaddr_sco);
+			return 1;
+#endif
+		default:
+			PyErr_SetString(socket_error, "getsockaddrlen: "
+					"unknown BT protocol");
+			return 0;
+
+		}
+	}
+#endif
+
+#ifdef HAVE_NETPACKET_PACKET_H
+	case AF_PACKET:
+	{
+		*len_ret = sizeof (struct sockaddr_ll);
+		return 1;
+	}
+#endif
+
+	/* More cases here... */
+
+	default:
+		PyErr_SetString(socket_error, "getsockaddrlen: bad family");
+		return 0;
+
+	}
+}
+
+
+/* s.accept() method */
+
+static PyObject *
+sock_accept(PySocketSockObject *s)
+{
+	sock_addr_t addrbuf;
+	SOCKET_T newfd;
+	socklen_t addrlen;
+	PyObject *sock = NULL;
+	PyObject *addr = NULL;
+	PyObject *res = NULL;
+	int timeout;
+
+	if (!getsockaddrlen(s, &addrlen))
+		return NULL;
+	memset(&addrbuf, 0, addrlen);
+
+#ifdef MS_WINDOWS
+	newfd = INVALID_SOCKET;
+#else
+	newfd = -1;
+#endif
+
+	if (!IS_SELECTABLE(s))
+		return select_error();
+
+	Py_BEGIN_ALLOW_THREADS
+	timeout = internal_select(s, 0);
+	if (!timeout)
+		newfd = accept(s->sock_fd, SAS2SA(&addrbuf), &addrlen);
+	Py_END_ALLOW_THREADS
+
+	if (timeout == 1) {
+		PyErr_SetString(socket_timeout, "timed out");
+		return NULL;
+	}
+
+#ifdef MS_WINDOWS
+	if (newfd == INVALID_SOCKET)
+#else
+	if (newfd < 0)
+#endif
+		return s->errorhandler();
+
+	/* Create the new object with unspecified family,
+	   to avoid calls to bind() etc. on it. */
+	sock = (PyObject *) new_sockobject(newfd,
+					   s->sock_family,
+					   s->sock_type,
+					   s->sock_proto);
+
+	if (sock == NULL) {
+		SOCKETCLOSE(newfd);
+		goto finally;
+	}
+	addr = makesockaddr(s->sock_fd, SAS2SA(&addrbuf),
+			    addrlen, s->sock_proto);
+	if (addr == NULL)
+		goto finally;
+
+	res = PyTuple_Pack(2, sock, addr);
+
+finally:
+	Py_XDECREF(sock);
+	Py_XDECREF(addr);
+	return res;
+}
+
+PyDoc_STRVAR(accept_doc,
+"accept() -> (socket object, address info)\n\
+\n\
+Wait for an incoming connection.  Return a new socket representing the\n\
+connection, and the address of the client.  For IP sockets, the address\n\
+info is a pair (hostaddr, port).");
+
+/* s.setblocking(flag) method.  Argument:
+   False -- non-blocking mode; same as settimeout(0)
+   True -- blocking mode; same as settimeout(None)
+*/
+
+static PyObject *
+sock_setblocking(PySocketSockObject *s, PyObject *arg)
+{
+	int block;
+
+	block = PyInt_AsLong(arg);
+	if (block == -1 && PyErr_Occurred())
+		return NULL;
+
+	s->sock_timeout = block ? -1.0 : 0.0;
+	internal_setblocking(s, block);
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(setblocking_doc,
+"setblocking(flag)\n\
+\n\
+Set the socket to blocking (flag is true) or non-blocking (false).\n\
+setblocking(True) is equivalent to settimeout(None);\n\
+setblocking(False) is equivalent to settimeout(0.0).");
+
+/* s.settimeout(timeout) method.  Argument:
+   None -- no timeout, blocking mode; same as setblocking(True)
+   0.0  -- non-blocking mode; same as setblocking(False)
+   > 0  -- timeout mode; operations time out after timeout seconds
+   < 0  -- illegal; raises an exception
+*/
+static PyObject *
+sock_settimeout(PySocketSockObject *s, PyObject *arg)
+{
+	double timeout;
+
+	if (arg == Py_None)
+		timeout = -1.0;
+	else {
+		timeout = PyFloat_AsDouble(arg);
+		if (timeout < 0.0) {
+			if (!PyErr_Occurred())
+				PyErr_SetString(PyExc_ValueError,
+						"Timeout value out of range");
+			return NULL;
+		}
+	}
+
+	s->sock_timeout = timeout;
+	internal_setblocking(s, timeout < 0.0);
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(settimeout_doc,
+"settimeout(timeout)\n\
+\n\
+Set a timeout on socket operations.  'timeout' can be a float,\n\
+giving in seconds, or None.  Setting a timeout of None disables\n\
+the timeout feature and is equivalent to setblocking(1).\n\
+Setting a timeout of zero is the same as setblocking(0).");
+
+/* s.gettimeout() method.
+   Returns the timeout associated with a socket. */
+static PyObject *
+sock_gettimeout(PySocketSockObject *s)
+{
+	if (s->sock_timeout < 0.0) {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+	else
+		return PyFloat_FromDouble(s->sock_timeout);
+}
+
+PyDoc_STRVAR(gettimeout_doc,
+"gettimeout() -> timeout\n\
+\n\
+Returns the timeout in floating seconds associated with socket \n\
+operations. A timeout of None indicates that timeouts on socket \n\
+operations are disabled.");
+
+#ifdef RISCOS
+/* s.sleeptaskw(1 | 0) method */
+
+static PyObject *
+sock_sleeptaskw(PySocketSockObject *s,PyObject *arg)
+{
+	int block;
+	block = PyInt_AsLong(arg);
+	if (block == -1 && PyErr_Occurred())
+		return NULL;
+	Py_BEGIN_ALLOW_THREADS
+	socketioctl(s->sock_fd, 0x80046679, (u_long*)&block);
+	Py_END_ALLOW_THREADS
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+PyDoc_STRVAR(sleeptaskw_doc,
+"sleeptaskw(flag)\n\
+\n\
+Allow sleeps in taskwindows.");
+#endif
+
+
+/* s.setsockopt() method.
+   With an integer third argument, sets an integer option.
+   With a string third argument, sets an option from a buffer;
+   use optional built-in module 'struct' to encode the string. */
+
+static PyObject *
+sock_setsockopt(PySocketSockObject *s, PyObject *args)
+{
+	int level;
+	int optname;
+	int res;
+	char *buf;
+	int buflen;
+	int flag;
+
+	if (PyArg_ParseTuple(args, "iii:setsockopt",
+			     &level, &optname, &flag)) {
+		buf = (char *) &flag;
+		buflen = sizeof flag;
+	}
+	else {
+		PyErr_Clear();
+		if (!PyArg_ParseTuple(args, "iis#:setsockopt",
+				      &level, &optname, &buf, &buflen))
+			return NULL;
+	}
+	res = setsockopt(s->sock_fd, level, optname, (void *)buf, buflen);
+	if (res < 0)
+		return s->errorhandler();
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(setsockopt_doc,
+"setsockopt(level, option, value)\n\
+\n\
+Set a socket option.  See the Unix manual for level and option.\n\
+The value argument can either be an integer or a string.");
+
+
+/* s.getsockopt() method.
+   With two arguments, retrieves an integer option.
+   With a third integer argument, retrieves a string buffer of that size;
+   use optional built-in module 'struct' to decode the string. */
+
+static PyObject *
+sock_getsockopt(PySocketSockObject *s, PyObject *args)
+{
+	int level;
+	int optname;
+	int res;
+	PyObject *buf;
+	socklen_t buflen = 0;
+
+#ifdef __BEOS__
+	/* We have incomplete socket support. */
+	PyErr_SetString(socket_error, "getsockopt not supported");
+	return NULL;
+#else
+
+	if (!PyArg_ParseTuple(args, "ii|i:getsockopt",
+			      &level, &optname, &buflen))
+		return NULL;
+
+	if (buflen == 0) {
+		int flag = 0;
+		socklen_t flagsize = sizeof flag;
+		res = getsockopt(s->sock_fd, level, optname,
+				 (void *)&flag, &flagsize);
+		if (res < 0)
+			return s->errorhandler();
+		return PyInt_FromLong(flag);
+	}
+#ifdef __VMS
+	/* socklen_t is unsigned so no negative test is needed,
+	   test buflen == 0 is previously done */
+	if (buflen > 1024) {
+#else
+	if (buflen <= 0 || buflen > 1024) {
+#endif
+		PyErr_SetString(socket_error,
+				"getsockopt buflen out of range");
+		return NULL;
+	}
+	buf = PyString_FromStringAndSize((char *)NULL, buflen);
+	if (buf == NULL)
+		return NULL;
+	res = getsockopt(s->sock_fd, level, optname,
+			 (void *)PyString_AS_STRING(buf), &buflen);
+	if (res < 0) {
+		Py_DECREF(buf);
+		return s->errorhandler();
+	}
+	_PyString_Resize(&buf, buflen);
+	return buf;
+#endif /* __BEOS__ */
+}
+
+PyDoc_STRVAR(getsockopt_doc,
+"getsockopt(level, option[, buffersize]) -> value\n\
+\n\
+Get a socket option.  See the Unix manual for level and option.\n\
+If a nonzero buffersize argument is given, the return value is a\n\
+string of that length; otherwise it is an integer.");
+
+
+/* s.bind(sockaddr) method */
+
+static PyObject *
+sock_bind(PySocketSockObject *s, PyObject *addro)
+{
+	sock_addr_t addrbuf;
+	int addrlen;
+	int res;
+
+	if (!getsockaddrarg(s, addro, SAS2SA(&addrbuf), &addrlen))
+		return NULL;
+	Py_BEGIN_ALLOW_THREADS
+	res = bind(s->sock_fd, SAS2SA(&addrbuf), addrlen);
+	Py_END_ALLOW_THREADS
+	if (res < 0)
+		return s->errorhandler();
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(bind_doc,
+"bind(address)\n\
+\n\
+Bind the socket to a local address.  For IP sockets, the address is a\n\
+pair (host, port); the host must refer to the local host. For raw packet\n\
+sockets the address is a tuple (ifname, proto [,pkttype [,hatype]])");
+
+
+/* s.close() method.
+   Set the file descriptor to -1 so operations tried subsequently
+   will surely fail. */
+
+static PyObject *
+sock_close(PySocketSockObject *s)
+{
+	SOCKET_T fd;
+
+	if ((fd = s->sock_fd) != -1) {
+		s->sock_fd = -1;
+		Py_BEGIN_ALLOW_THREADS
+		(void) SOCKETCLOSE(fd);
+		Py_END_ALLOW_THREADS
+	}
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(close_doc,
+"close()\n\
+\n\
+Close the socket.  It cannot be used after this call.");
+
+static int
+internal_connect(PySocketSockObject *s, struct sockaddr *addr, int addrlen,
+		 int *timeoutp)
+{
+	int res, timeout;
+
+	timeout = 0;
+	res = connect(s->sock_fd, addr, addrlen);
+
+#ifdef MS_WINDOWS
+
+	if (s->sock_timeout > 0.0) {
+		if (res < 0 && WSAGetLastError() == WSAEWOULDBLOCK &&
+		    IS_SELECTABLE(s)) {
+			/* This is a mess.  Best solution: trust select */
+			fd_set fds;
+			fd_set fds_exc;
+			struct timeval tv;
+			tv.tv_sec = (int)s->sock_timeout;
+			tv.tv_usec = (int)((s->sock_timeout - tv.tv_sec) * 1e6);
+			FD_ZERO(&fds);
+			FD_SET(s->sock_fd, &fds);
+			FD_ZERO(&fds_exc);
+			FD_SET(s->sock_fd, &fds_exc);
+			res = select(s->sock_fd+1, NULL, &fds, &fds_exc, &tv);
+			if (res == 0) {
+				res = WSAEWOULDBLOCK;
+				timeout = 1;
+			} else if (res > 0) {
+				if (FD_ISSET(s->sock_fd, &fds))
+					/* The socket is in the writeable set - this
+					   means connected */
+					res = 0;
+				else {
+					/* As per MS docs, we need to call getsockopt()
+					   to get the underlying error */
+					int res_size = sizeof res;
+					/* It must be in the exception set */
+					assert(FD_ISSET(s->sock_fd, &fds_exc));
+					if (0 == getsockopt(s->sock_fd, SOL_SOCKET, SO_ERROR,
+					                    (char *)&res, &res_size))
+						/* getsockopt also clears WSAGetLastError,
+						   so reset it back. */
+						WSASetLastError(res);
+					else
+						res = WSAGetLastError();
+				}
+			}
+			/* else if (res < 0) an error occurred */
+		}
+	}
+
+	if (res < 0)
+		res = WSAGetLastError();
+
+#else
+
+	if (s->sock_timeout > 0.0) {
+		if (res < 0 && errno == EINPROGRESS && IS_SELECTABLE(s)) {
+			timeout = internal_select(s, 1);
+			if (timeout == 0) {
+				res = connect(s->sock_fd, addr, addrlen);
+				if (res < 0 && errno == EISCONN)
+					res = 0;
+			}
+			else if (timeout == -1)
+				res = errno;		/* had error */
+			else
+				res = EWOULDBLOCK;	/* timed out */
+		}
+	}
+
+	if (res < 0)
+		res = errno;
+
+#endif
+	*timeoutp = timeout;
+
+	return res;
+}
+
+/* s.connect(sockaddr) method */
+
+static PyObject *
+sock_connect(PySocketSockObject *s, PyObject *addro)
+{
+	sock_addr_t addrbuf;
+	int addrlen;
+	int res;
+	int timeout;
+
+	if (!getsockaddrarg(s, addro, SAS2SA(&addrbuf), &addrlen))
+		return NULL;
+
+	Py_BEGIN_ALLOW_THREADS
+	res = internal_connect(s, SAS2SA(&addrbuf), addrlen, &timeout);
+	Py_END_ALLOW_THREADS
+
+	if (timeout == 1) {
+		PyErr_SetString(socket_timeout, "timed out");
+		return NULL;
+	}
+	if (res != 0)
+		return s->errorhandler();
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(connect_doc,
+"connect(address)\n\
+\n\
+Connect the socket to a remote address.  For IP sockets, the address\n\
+is a pair (host, port).");
+
+
+/* s.connect_ex(sockaddr) method */
+
+static PyObject *
+sock_connect_ex(PySocketSockObject *s, PyObject *addro)
+{
+	sock_addr_t addrbuf;
+	int addrlen;
+	int res;
+	int timeout;
+
+	if (!getsockaddrarg(s, addro, SAS2SA(&addrbuf), &addrlen))
+		return NULL;
+
+	Py_BEGIN_ALLOW_THREADS
+	res = internal_connect(s, SAS2SA(&addrbuf), addrlen, &timeout);
+	Py_END_ALLOW_THREADS
+
+	/* Signals are not errors (though they may raise exceptions).  Adapted
+	   from PyErr_SetFromErrnoWithFilenameObject(). */
+#ifdef EINTR
+	if (res == EINTR && PyErr_CheckSignals())
+		return NULL;
+#endif
+
+	return PyInt_FromLong((long) res);
+}
+
+PyDoc_STRVAR(connect_ex_doc,
+"connect_ex(address) -> errno\n\
+\n\
+This is like connect(address), but returns an error code (the errno value)\n\
+instead of raising an exception when an error occurs.");
+
+
+/* s.fileno() method */
+
+static PyObject *
+sock_fileno(PySocketSockObject *s)
+{
+#if SIZEOF_SOCKET_T <= SIZEOF_LONG
+	return PyInt_FromLong((long) s->sock_fd);
+#else
+	return PyLong_FromLongLong((PY_LONG_LONG)s->sock_fd);
+#endif
+}
+
+PyDoc_STRVAR(fileno_doc,
+"fileno() -> integer\n\
+\n\
+Return the integer file descriptor of the socket.");
+
+
+#ifndef NO_DUP
+/* s.dup() method */
+
+static PyObject *
+sock_dup(PySocketSockObject *s)
+{
+	SOCKET_T newfd;
+	PyObject *sock;
+
+	newfd = dup(s->sock_fd);
+	if (newfd < 0)
+		return s->errorhandler();
+	sock = (PyObject *) new_sockobject(newfd,
+					   s->sock_family,
+					   s->sock_type,
+					   s->sock_proto);
+	if (sock == NULL)
+		SOCKETCLOSE(newfd);
+	return sock;
+}
+
+PyDoc_STRVAR(dup_doc,
+"dup() -> socket object\n\
+\n\
+Return a new socket object connected to the same system resource.");
+
+#endif
+
+
+/* s.getsockname() method */
+
+static PyObject *
+sock_getsockname(PySocketSockObject *s)
+{
+	sock_addr_t addrbuf;
+	int res;
+	socklen_t addrlen;
+
+	if (!getsockaddrlen(s, &addrlen))
+		return NULL;
+	memset(&addrbuf, 0, addrlen);
+	Py_BEGIN_ALLOW_THREADS
+	res = getsockname(s->sock_fd, SAS2SA(&addrbuf), &addrlen);
+	Py_END_ALLOW_THREADS
+	if (res < 0)
+		return s->errorhandler();
+	return makesockaddr(s->sock_fd, SAS2SA(&addrbuf), addrlen,
+			    s->sock_proto);
+}
+
+PyDoc_STRVAR(getsockname_doc,
+"getsockname() -> address info\n\
+\n\
+Return the address of the local endpoint.  For IP sockets, the address\n\
+info is a pair (hostaddr, port).");
+
+
+#ifdef HAVE_GETPEERNAME		/* Cray APP doesn't have this :-( */
+/* s.getpeername() method */
+
+static PyObject *
+sock_getpeername(PySocketSockObject *s)
+{
+	sock_addr_t addrbuf;
+	int res;
+	socklen_t addrlen;
+
+	if (!getsockaddrlen(s, &addrlen))
+		return NULL;
+	memset(&addrbuf, 0, addrlen);
+	Py_BEGIN_ALLOW_THREADS
+	res = getpeername(s->sock_fd, SAS2SA(&addrbuf), &addrlen);
+	Py_END_ALLOW_THREADS
+	if (res < 0)
+		return s->errorhandler();
+	return makesockaddr(s->sock_fd, SAS2SA(&addrbuf), addrlen,
+			    s->sock_proto);
+}
+
+PyDoc_STRVAR(getpeername_doc,
+"getpeername() -> address info\n\
+\n\
+Return the address of the remote endpoint.  For IP sockets, the address\n\
+info is a pair (hostaddr, port).");
+
+#endif /* HAVE_GETPEERNAME */
+
+
+/* s.listen(n) method */
+
+static PyObject *
+sock_listen(PySocketSockObject *s, PyObject *arg)
+{
+	int backlog;
+	int res;
+
+	backlog = PyInt_AsLong(arg);
+	if (backlog == -1 && PyErr_Occurred())
+		return NULL;
+	Py_BEGIN_ALLOW_THREADS
+	if (backlog < 1)
+		backlog = 1;
+	res = listen(s->sock_fd, backlog);
+	Py_END_ALLOW_THREADS
+	if (res < 0)
+		return s->errorhandler();
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(listen_doc,
+"listen(backlog)\n\
+\n\
+Enable a server to accept connections.  The backlog argument must be at\n\
+least 1; it specifies the number of unaccepted connection that the system\n\
+will allow before refusing new connections.");
+
+
+#ifndef NO_DUP
+/* s.makefile(mode) method.
+   Create a new open file object referring to a dupped version of
+   the socket's file descriptor.  (The dup() call is necessary so
+   that the open file and socket objects may be closed independent
+   of each other.)
+   The mode argument specifies 'r' or 'w' passed to fdopen(). */
+
+static PyObject *
+sock_makefile(PySocketSockObject *s, PyObject *args)
+{
+	extern int fclose(FILE *);
+	char *mode = "r";
+	int bufsize = -1;
+#ifdef MS_WIN32
+	Py_intptr_t fd;
+#else
+	int fd;
+#endif
+	FILE *fp;
+	PyObject *f;
+#ifdef __VMS
+	char *mode_r = "r";
+	char *mode_w = "w";
+#endif
+
+	if (!PyArg_ParseTuple(args, "|si:makefile", &mode, &bufsize))
+		return NULL;
+#ifdef __VMS
+	if (strcmp(mode,"rb") == 0) {
+	    mode = mode_r;
+	}
+	else {
+		if (strcmp(mode,"wb") == 0) {
+			mode = mode_w;
+		}
+	}
+#endif
+#ifdef MS_WIN32
+	if (((fd = _open_osfhandle(s->sock_fd, _O_BINARY)) < 0) ||
+	    ((fd = dup(fd)) < 0) || ((fp = fdopen(fd, mode)) == NULL))
+#else
+	if ((fd = dup(s->sock_fd)) < 0 || (fp = fdopen(fd, mode)) == NULL)
+#endif
+	{
+		if (fd >= 0)
+			SOCKETCLOSE(fd);
+		return s->errorhandler();
+	}
+	f = PyFile_FromFile(fp, "<socket>", mode, fclose);
+	if (f != NULL)
+		PyFile_SetBufSize(f, bufsize);
+	return f;
+}
+
+PyDoc_STRVAR(makefile_doc,
+"makefile([mode[, buffersize]]) -> file object\n\
+\n\
+Return a regular file object corresponding to the socket.\n\
+The mode and buffersize arguments are as for the built-in open() function.");
+
+#endif /* NO_DUP */
+
+/*
+ * This is the guts of the recv() and recv_into() methods, which reads into a
+ * char buffer.  If you have any inc/def ref to do to the objects that contain
+ * the buffer, do it in the caller.  This function returns the number of bytes
+ * succesfully read.  If there was an error, it returns -1.  Note that it is
+ * also possible that we return a number of bytes smaller than the request
+ * bytes.
+ */
+static ssize_t
+sock_recv_guts(PySocketSockObject *s, char* cbuf, int len, int flags)
+{
+        ssize_t outlen = -1;
+        int timeout;
+#ifdef __VMS
+	int remaining;
+	char *read_buf;
+#endif
+
+	if (!IS_SELECTABLE(s)) {
+		select_error();
+		return -1;
+	}
+
+#ifndef __VMS
+	Py_BEGIN_ALLOW_THREADS
+	timeout = internal_select(s, 0);
+	if (!timeout)
+		outlen = recv(s->sock_fd, cbuf, len, flags);
+	Py_END_ALLOW_THREADS
+
+	if (timeout == 1) {
+		PyErr_SetString(socket_timeout, "timed out");
+		return -1;
+	}
+	if (outlen < 0) {
+		/* Note: the call to errorhandler() ALWAYS indirectly returned
+		   NULL, so ignore its return value */
+		s->errorhandler();
+		return -1;
+	}
+#else
+	read_buf = cbuf;
+	remaining = len;
+	while (remaining != 0) {
+		unsigned int segment;
+		int nread = -1;
+
+		segment = remaining /SEGMENT_SIZE;
+		if (segment != 0) {
+			segment = SEGMENT_SIZE;
+		}
+		else {
+			segment = remaining;
+		}
+
+		Py_BEGIN_ALLOW_THREADS
+		timeout = internal_select(s, 0);
+		if (!timeout)
+			nread = recv(s->sock_fd, read_buf, segment, flags);
+		Py_END_ALLOW_THREADS
+
+		if (timeout == 1) {
+			PyErr_SetString(socket_timeout, "timed out");
+			return -1;
+		}
+		if (nread < 0) {
+			s->errorhandler();
+			return -1;
+		}
+		if (nread != remaining) {
+			read_buf += nread;
+			break;
+		}
+
+		remaining -= segment;
+		read_buf += segment;
+	}
+	outlen = read_buf - cbuf;
+#endif /* !__VMS */
+
+	return outlen;
+}
+
+
+/* s.recv(nbytes [,flags]) method */
+
+static PyObject *
+sock_recv(PySocketSockObject *s, PyObject *args)
+{
+	int recvlen, flags = 0;
+        ssize_t outlen;
+	PyObject *buf;
+
+	if (!PyArg_ParseTuple(args, "i|i:recv", &recvlen, &flags))
+		return NULL;
+
+	if (recvlen < 0) {
+		PyErr_SetString(PyExc_ValueError,
+				"negative buffersize in recv");
+		return NULL;
+	}
+
+	/* Allocate a new string. */
+	buf = PyString_FromStringAndSize((char *) 0, recvlen);
+	if (buf == NULL)
+		return NULL;
+
+	/* Call the guts */
+	outlen = sock_recv_guts(s, PyString_AS_STRING(buf), recvlen, flags);
+	if (outlen < 0) {
+		/* An error occurred, release the string and return an
+		   error. */
+		Py_DECREF(buf);
+		return NULL;
+	}
+	if (outlen != recvlen) {
+		/* We did not read as many bytes as we anticipated, resize the
+		   string if possible and be succesful. */
+		if (_PyString_Resize(&buf, outlen) < 0)
+			/* Oopsy, not so succesful after all. */
+			return NULL;
+	}
+
+	return buf;
+}
+
+PyDoc_STRVAR(recv_doc,
+"recv(buffersize[, flags]) -> data\n\
+\n\
+Receive up to buffersize bytes from the socket.  For the optional flags\n\
+argument, see the Unix manual.  When no data is available, block until\n\
+at least one byte is available or until the remote end is closed.  When\n\
+the remote end is closed and all data is read, return the empty string.");
+
+
+/* s.recv_into(buffer, [nbytes [,flags]]) method */
+
+static PyObject*
+sock_recv_into(PySocketSockObject *s, PyObject *args, PyObject *kwds)
+{
+	static char *kwlist[] = {"buffer", "nbytes", "flags", 0};
+
+	int recvlen = 0, flags = 0;
+        ssize_t readlen;
+	char *buf;
+	int buflen;
+
+	/* Get the buffer's memory */
+	if (!PyArg_ParseTupleAndKeywords(args, kwds, "w#|ii:recv_into", kwlist,
+					 &buf, &buflen, &recvlen, &flags))
+		return NULL;
+	assert(buf != 0 && buflen > 0);
+
+	if (recvlen < 0) {
+		PyErr_SetString(PyExc_ValueError,
+				"negative buffersize in recv_into");
+		return NULL;
+	}
+	if (recvlen == 0) {
+            /* If nbytes was not specified, use the buffer's length */
+            recvlen = buflen;
+	}
+
+	/* Check if the buffer is large enough */
+	if (buflen < recvlen) {
+		PyErr_SetString(PyExc_ValueError,
+				"buffer too small for requested bytes");
+		return NULL;
+	}
+
+	/* Call the guts */
+	readlen = sock_recv_guts(s, buf, recvlen, flags);
+	if (readlen < 0) {
+		/* Return an error. */
+		return NULL;
+	}
+
+	/* Return the number of bytes read.  Note that we do not do anything
+	   special here in the case that readlen < recvlen. */
+	return PyInt_FromSsize_t(readlen);
+}
+
+PyDoc_STRVAR(recv_into_doc,
+"recv_into(buffer, [nbytes[, flags]]) -> nbytes_read\n\
+\n\
+A version of recv() that stores its data into a buffer rather than creating \n\
+a new string.  Receive up to buffersize bytes from the socket.  If buffersize \n\
+is not specified (or 0), receive up to the size available in the given buffer.\n\
+\n\
+See recv() for documentation about the flags.");
+
+
+/*
+ * This is the guts of the recv() and recv_into() methods, which reads into a
+ * char buffer.  If you have any inc/def ref to do to the objects that contain
+ * the buffer, do it in the caller.  This function returns the number of bytes
+ * succesfully read.  If there was an error, it returns -1.  Note that it is
+ * also possible that we return a number of bytes smaller than the request
+ * bytes.
+ *
+ * 'addr' is a return value for the address object.  Note that you must decref
+ * it yourself.
+ */
+static ssize_t
+sock_recvfrom_guts(PySocketSockObject *s, char* cbuf, int len, int flags,
+		   PyObject** addr)
+{
+	sock_addr_t addrbuf;
+	int timeout;
+	ssize_t n = -1;
+	socklen_t addrlen;
+
+	*addr = NULL;
+
+	if (!getsockaddrlen(s, &addrlen))
+		return -1;
+
+	if (!IS_SELECTABLE(s)) {
+		select_error();
+		return -1;
+	}
+
+	Py_BEGIN_ALLOW_THREADS
+	memset(&addrbuf, 0, addrlen);
+	timeout = internal_select(s, 0);
+	if (!timeout) {
+#ifndef MS_WINDOWS
+#if defined(PYOS_OS2) && !defined(PYCC_GCC)
+		n = recvfrom(s->sock_fd, cbuf, len, flags,
+			     SAS2SA(&addrbuf), &addrlen);
+#else
+		n = recvfrom(s->sock_fd, cbuf, len, flags,
+			     (void *) &addrbuf, &addrlen);
+#endif
+#else
+		n = recvfrom(s->sock_fd, cbuf, len, flags,
+			     SAS2SA(&addrbuf), &addrlen);
+#endif
+	}
+	Py_END_ALLOW_THREADS
+
+	if (timeout == 1) {
+		PyErr_SetString(socket_timeout, "timed out");
+		return -1;
+	}
+	if (n < 0) {
+		s->errorhandler();
+                return -1;
+	}
+
+	if (!(*addr = makesockaddr(s->sock_fd, SAS2SA(&addrbuf),
+				   addrlen, s->sock_proto)))
+		return -1;
+
+	return n;
+}
+
+/* s.recvfrom(nbytes [,flags]) method */
+
+static PyObject *
+sock_recvfrom(PySocketSockObject *s, PyObject *args)
+{
+	PyObject *buf = NULL;
+	PyObject *addr = NULL;
+	PyObject *ret = NULL;
+	int recvlen, flags = 0;
+        ssize_t outlen;
+
+	if (!PyArg_ParseTuple(args, "i|i:recvfrom", &recvlen, &flags))
+		return NULL;
+
+	if (recvlen < 0) {
+		PyErr_SetString(PyExc_ValueError,
+				"negative buffersize in recvfrom");
+		return NULL;
+	}
+
+	buf = PyString_FromStringAndSize((char *) 0, recvlen);
+	if (buf == NULL)
+		return NULL;
+
+	outlen = sock_recvfrom_guts(s, PyString_AS_STRING(buf),
+				    recvlen, flags, &addr);
+	if (outlen < 0) {
+		goto finally;
+	}
+
+	if (outlen != recvlen) {
+		/* We did not read as many bytes as we anticipated, resize the
+		   string if possible and be succesful. */
+		if (_PyString_Resize(&buf, outlen) < 0)
+			/* Oopsy, not so succesful after all. */
+			goto finally;
+	}
+
+	ret = PyTuple_Pack(2, buf, addr);
+
+finally:
+	Py_XDECREF(buf);
+	Py_XDECREF(addr);
+	return ret;
+}
+
+PyDoc_STRVAR(recvfrom_doc,
+"recvfrom(buffersize[, flags]) -> (data, address info)\n\
+\n\
+Like recv(buffersize, flags) but also return the sender's address info.");
+
+
+/* s.recvfrom_into(buffer[, nbytes [,flags]]) method */
+
+static PyObject *
+sock_recvfrom_into(PySocketSockObject *s, PyObject *args, PyObject* kwds)
+{
+	static char *kwlist[] = {"buffer", "nbytes", "flags", 0};
+
+	int recvlen = 0, flags = 0;
+        ssize_t readlen;
+	char *buf;
+	int buflen;
+
+	PyObject *addr = NULL;
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwds, "w#|ii:recvfrom_into",
+					 kwlist, &buf, &buflen,
+					 &recvlen, &flags))
+		return NULL;
+	assert(buf != 0 && buflen > 0);
+
+	if (recvlen < 0) {
+		PyErr_SetString(PyExc_ValueError,
+				"negative buffersize in recvfrom_into");
+		return NULL;
+	}
+	if (recvlen == 0) {
+            /* If nbytes was not specified, use the buffer's length */
+            recvlen = buflen;
+	}
+
+	readlen = sock_recvfrom_guts(s, buf, recvlen, flags, &addr);
+	if (readlen < 0) {
+		/* Return an error */
+		Py_XDECREF(addr);
+		return NULL;
+	}
+
+	/* Return the number of bytes read and the address.  Note that we do
+	   not do anything special here in the case that readlen < recvlen. */
+ 	return Py_BuildValue("lN", readlen, addr);
+}
+
+PyDoc_STRVAR(recvfrom_into_doc,
+"recvfrom_into(buffer[, nbytes[, flags]]) -> (nbytes, address info)\n\
+\n\
+Like recv_into(buffer[, nbytes[, flags]]) but also return the sender's address info.");
+
+
+/* s.send(data [,flags]) method */
+
+static PyObject *
+sock_send(PySocketSockObject *s, PyObject *args)
+{
+	char *buf;
+	int len, n = -1, flags = 0, timeout;
+
+	if (!PyArg_ParseTuple(args, "s#|i:send", &buf, &len, &flags))
+		return NULL;
+
+	if (!IS_SELECTABLE(s))
+		return select_error();
+
+	Py_BEGIN_ALLOW_THREADS
+	timeout = internal_select(s, 1);
+	if (!timeout)
+#ifdef __VMS
+		n = sendsegmented(s->sock_fd, buf, len, flags);
+#else
+		n = send(s->sock_fd, buf, len, flags);
+#endif
+	Py_END_ALLOW_THREADS
+
+	if (timeout == 1) {
+		PyErr_SetString(socket_timeout, "timed out");
+		return NULL;
+	}
+	if (n < 0)
+		return s->errorhandler();
+	return PyInt_FromLong((long)n);
+}
+
+PyDoc_STRVAR(send_doc,
+"send(data[, flags]) -> count\n\
+\n\
+Send a data string to the socket.  For the optional flags\n\
+argument, see the Unix manual.  Return the number of bytes\n\
+sent; this may be less than len(data) if the network is busy.");
+
+
+/* s.sendall(data [,flags]) method */
+
+static PyObject *
+sock_sendall(PySocketSockObject *s, PyObject *args)
+{
+	char *buf;
+	int len, n = -1, flags = 0, timeout;
+
+	if (!PyArg_ParseTuple(args, "s#|i:sendall", &buf, &len, &flags))
+		return NULL;
+
+	if (!IS_SELECTABLE(s))
+		return select_error();
+
+	Py_BEGIN_ALLOW_THREADS
+	do {
+		timeout = internal_select(s, 1);
+		n = -1;
+		if (timeout)
+			break;
+#ifdef __VMS
+		n = sendsegmented(s->sock_fd, buf, len, flags);
+#else
+		n = send(s->sock_fd, buf, len, flags);
+#endif
+		if (n < 0)
+			break;
+		buf += n;
+		len -= n;
+	} while (len > 0);
+	Py_END_ALLOW_THREADS
+
+	if (timeout == 1) {
+		PyErr_SetString(socket_timeout, "timed out");
+		return NULL;
+	}
+	if (n < 0)
+		return s->errorhandler();
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(sendall_doc,
+"sendall(data[, flags])\n\
+\n\
+Send a data string to the socket.  For the optional flags\n\
+argument, see the Unix manual.  This calls send() repeatedly\n\
+until all data is sent.  If an error occurs, it's impossible\n\
+to tell how much data has been sent.");
+
+
+/* s.sendto(data, [flags,] sockaddr) method */
+
+static PyObject *
+sock_sendto(PySocketSockObject *s, PyObject *args)
+{
+	PyObject *addro;
+	char *buf;
+	sock_addr_t addrbuf;
+	int addrlen, len, n = -1, flags, timeout;
+
+	flags = 0;
+	if (!PyArg_ParseTuple(args, "s#O:sendto", &buf, &len, &addro)) {
+		PyErr_Clear();
+		if (!PyArg_ParseTuple(args, "s#iO:sendto",
+				      &buf, &len, &flags, &addro))
+			return NULL;
+	}
+
+	if (!IS_SELECTABLE(s))
+		return select_error();
+
+	if (!getsockaddrarg(s, addro, SAS2SA(&addrbuf), &addrlen))
+		return NULL;
+
+	Py_BEGIN_ALLOW_THREADS
+	timeout = internal_select(s, 1);
+	if (!timeout)
+		n = sendto(s->sock_fd, buf, len, flags, SAS2SA(&addrbuf), addrlen);
+	Py_END_ALLOW_THREADS
+
+	if (timeout == 1) {
+		PyErr_SetString(socket_timeout, "timed out");
+		return NULL;
+	}
+	if (n < 0)
+		return s->errorhandler();
+	return PyInt_FromLong((long)n);
+}
+
+PyDoc_STRVAR(sendto_doc,
+"sendto(data[, flags], address) -> count\n\
+\n\
+Like send(data, flags) but allows specifying the destination address.\n\
+For IP sockets, the address is a pair (hostaddr, port).");
+
+
+/* s.shutdown(how) method */
+
+static PyObject *
+sock_shutdown(PySocketSockObject *s, PyObject *arg)
+{
+	int how;
+	int res;
+
+	how = PyInt_AsLong(arg);
+	if (how == -1 && PyErr_Occurred())
+		return NULL;
+	Py_BEGIN_ALLOW_THREADS
+	res = shutdown(s->sock_fd, how);
+	Py_END_ALLOW_THREADS
+	if (res < 0)
+		return s->errorhandler();
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(shutdown_doc,
+"shutdown(flag)\n\
+\n\
+Shut down the reading side of the socket (flag == SHUT_RD), the writing side\n\
+of the socket (flag == SHUT_WR), or both ends (flag == SHUT_RDWR).");
+
+
+/* List of methods for socket objects */
+
+static PyMethodDef sock_methods[] = {
+	{"accept",	  (PyCFunction)sock_accept, METH_NOARGS,
+			  accept_doc},
+	{"bind",	  (PyCFunction)sock_bind, METH_O,
+			  bind_doc},
+	{"close",	  (PyCFunction)sock_close, METH_NOARGS,
+			  close_doc},
+	{"connect",	  (PyCFunction)sock_connect, METH_O,
+			  connect_doc},
+	{"connect_ex",	  (PyCFunction)sock_connect_ex, METH_O,
+			  connect_ex_doc},
+#ifndef NO_DUP
+	{"dup",		  (PyCFunction)sock_dup, METH_NOARGS,
+			  dup_doc},
+#endif
+	{"fileno",	  (PyCFunction)sock_fileno, METH_NOARGS,
+			  fileno_doc},
+#ifdef HAVE_GETPEERNAME
+	{"getpeername",	  (PyCFunction)sock_getpeername,
+			  METH_NOARGS, getpeername_doc},
+#endif
+	{"getsockname",	  (PyCFunction)sock_getsockname,
+			  METH_NOARGS, getsockname_doc},
+	{"getsockopt",	  (PyCFunction)sock_getsockopt, METH_VARARGS,
+			  getsockopt_doc},
+	{"listen",	  (PyCFunction)sock_listen, METH_O,
+			  listen_doc},
+#ifndef NO_DUP
+	{"makefile",	  (PyCFunction)sock_makefile, METH_VARARGS,
+			  makefile_doc},
+#endif
+	{"recv",	  (PyCFunction)sock_recv, METH_VARARGS,
+			  recv_doc},
+	{"recv_into",	  (PyCFunction)sock_recv_into, METH_VARARGS | METH_KEYWORDS,
+			  recv_into_doc},
+	{"recvfrom",	  (PyCFunction)sock_recvfrom, METH_VARARGS,
+			  recvfrom_doc},
+	{"recvfrom_into",  (PyCFunction)sock_recvfrom_into, METH_VARARGS | METH_KEYWORDS,
+			  recvfrom_into_doc},
+	{"send",	  (PyCFunction)sock_send, METH_VARARGS,
+			  send_doc},
+	{"sendall",	  (PyCFunction)sock_sendall, METH_VARARGS,
+			  sendall_doc},
+	{"sendto",	  (PyCFunction)sock_sendto, METH_VARARGS,
+			  sendto_doc},
+	{"setblocking",	  (PyCFunction)sock_setblocking, METH_O,
+			  setblocking_doc},
+	{"settimeout",    (PyCFunction)sock_settimeout, METH_O,
+			  settimeout_doc},
+	{"gettimeout",    (PyCFunction)sock_gettimeout, METH_NOARGS,
+			  gettimeout_doc},
+	{"setsockopt",	  (PyCFunction)sock_setsockopt, METH_VARARGS,
+			  setsockopt_doc},
+	{"shutdown",	  (PyCFunction)sock_shutdown, METH_O,
+			  shutdown_doc},
+#ifdef RISCOS
+	{"sleeptaskw",	  (PyCFunction)sock_sleeptaskw, METH_O,
+	 		  sleeptaskw_doc},
+#endif
+	{NULL,			NULL}		/* sentinel */
+};
+
+/* SockObject members */
+static PyMemberDef sock_memberlist[] = {
+       {"family", T_INT, offsetof(PySocketSockObject, sock_family), READONLY, "the socket family"},
+       {"type", T_INT, offsetof(PySocketSockObject, sock_type), READONLY, "the socket type"},
+       {"proto", T_INT, offsetof(PySocketSockObject, sock_proto), READONLY, "the socket protocol"},
+       {"timeout", T_DOUBLE, offsetof(PySocketSockObject, sock_timeout), READONLY, "the socket timeout"},
+       {0},
+};
+
+/* Deallocate a socket object in response to the last Py_DECREF().
+   First close the file description. */
+
+static void
+sock_dealloc(PySocketSockObject *s)
+{
+	if (s->sock_fd != -1)
+		(void) SOCKETCLOSE(s->sock_fd);
+	s->ob_type->tp_free((PyObject *)s);
+}
+
+
+static PyObject *
+sock_repr(PySocketSockObject *s)
+{
+	char buf[512];
+#if SIZEOF_SOCKET_T > SIZEOF_LONG
+	if (s->sock_fd > LONG_MAX) {
+		/* this can occur on Win64, and actually there is a special
+		   ugly printf formatter for decimal pointer length integer
+		   printing, only bother if necessary*/
+		PyErr_SetString(PyExc_OverflowError,
+				"no printf formatter to display "
+				"the socket descriptor in decimal");
+		return NULL;
+	}
+#endif
+	PyOS_snprintf(
+		buf, sizeof(buf),
+		"<socket object, fd=%ld, family=%d, type=%d, protocol=%d>",
+		(long)s->sock_fd, s->sock_family,
+		s->sock_type,
+		s->sock_proto);
+	return PyString_FromString(buf);
+}
+
+
+/* Create a new, uninitialized socket object. */
+
+static PyObject *
+sock_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	PyObject *new;
+
+	new = type->tp_alloc(type, 0);
+	if (new != NULL) {
+		((PySocketSockObject *)new)->sock_fd = -1;
+		((PySocketSockObject *)new)->sock_timeout = -1.0;
+		((PySocketSockObject *)new)->errorhandler = &set_error;
+	}
+	return new;
+}
+
+
+/* Initialize a new socket object. */
+
+/*ARGSUSED*/
+static int
+sock_initobj(PyObject *self, PyObject *args, PyObject *kwds)
+{
+	PySocketSockObject *s = (PySocketSockObject *)self;
+	SOCKET_T fd;
+	int family = AF_INET, type = SOCK_STREAM, proto = 0;
+	static char *keywords[] = {"family", "type", "proto", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwds,
+					 "|iii:socket", keywords,
+					 &family, &type, &proto))
+		return -1;
+
+	Py_BEGIN_ALLOW_THREADS
+	fd = socket(family, type, proto);
+	Py_END_ALLOW_THREADS
+
+#ifdef MS_WINDOWS
+	if (fd == INVALID_SOCKET)
+#else
+	if (fd < 0)
+#endif
+	{
+		set_error();
+		return -1;
+	}
+	init_sockobject(s, fd, family, type, proto);
+
+	return 0;
+
+}
+
+
+/* Type object for socket objects. */
+
+static PyTypeObject sock_type = {
+	PyObject_HEAD_INIT(0)	/* Must fill in type value later */
+	0,					/* ob_size */
+	"_socket.socket",			/* tp_name */
+	sizeof(PySocketSockObject),		/* tp_basicsize */
+	0,					/* tp_itemsize */
+	(destructor)sock_dealloc,		/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	(reprfunc)sock_repr,			/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+	sock_doc,				/* tp_doc */
+	0,					/* tp_traverse */
+	0,					/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	sock_methods,				/* tp_methods */
+	sock_memberlist,			/* tp_members */
+	0,					/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	sock_initobj,				/* tp_init */
+	PyType_GenericAlloc,			/* tp_alloc */
+	sock_new,				/* tp_new */
+	PyObject_Del,				/* tp_free */
+};
+
+
+/* Python interface to gethostname(). */
+
+/*ARGSUSED*/
+static PyObject *
+socket_gethostname(PyObject *self, PyObject *unused)
+{
+	char buf[1024];
+	int res;
+	Py_BEGIN_ALLOW_THREADS
+	res = gethostname(buf, (int) sizeof buf - 1);
+	Py_END_ALLOW_THREADS
+	if (res < 0)
+		return set_error();
+	buf[sizeof buf - 1] = '\0';
+	return PyString_FromString(buf);
+}
+
+PyDoc_STRVAR(gethostname_doc,
+"gethostname() -> string\n\
+\n\
+Return the current host name.");
+
+
+/* Python interface to gethostbyname(name). */
+
+/*ARGSUSED*/
+static PyObject *
+socket_gethostbyname(PyObject *self, PyObject *args)
+{
+	char *name;
+	sock_addr_t addrbuf;
+
+	if (!PyArg_ParseTuple(args, "s:gethostbyname", &name))
+		return NULL;
+	if (setipaddr(name, SAS2SA(&addrbuf),  sizeof(addrbuf), AF_INET) < 0)
+		return NULL;
+	return makeipaddr(SAS2SA(&addrbuf), sizeof(struct sockaddr_in));
+}
+
+PyDoc_STRVAR(gethostbyname_doc,
+"gethostbyname(host) -> address\n\
+\n\
+Return the IP address (a string of the form '255.255.255.255') for a host.");
+
+
+/* Convenience function common to gethostbyname_ex and gethostbyaddr */
+
+static PyObject *
+gethost_common(struct hostent *h, struct sockaddr *addr, int alen, int af)
+{
+	char **pch;
+	PyObject *rtn_tuple = (PyObject *)NULL;
+	PyObject *name_list = (PyObject *)NULL;
+	PyObject *addr_list = (PyObject *)NULL;
+	PyObject *tmp;
+
+	if (h == NULL) {
+		/* Let's get real error message to return */
+#ifndef RISCOS
+		set_herror(h_errno);
+#else
+		PyErr_SetString(socket_error, "host not found");
+#endif
+		return NULL;
+	}
+
+	if (h->h_addrtype != af) {
+#ifdef HAVE_STRERROR
+		/* Let's get real error message to return */
+		PyErr_SetString(socket_error,
+				(char *)strerror(EAFNOSUPPORT));
+#else
+		PyErr_SetString(
+			socket_error,
+			"Address family not supported by protocol family");
+#endif
+		return NULL;
+	}
+
+	switch (af) {
+
+	case AF_INET:
+		if (alen < sizeof(struct sockaddr_in))
+			return NULL;
+		break;
+
+#ifdef ENABLE_IPV6
+	case AF_INET6:
+		if (alen < sizeof(struct sockaddr_in6))
+			return NULL;
+		break;
+#endif
+
+	}
+
+	if ((name_list = PyList_New(0)) == NULL)
+		goto err;
+
+	if ((addr_list = PyList_New(0)) == NULL)
+		goto err;
+
+	/* SF #1511317: h_aliases can be NULL */
+	if (h->h_aliases) {
+		for (pch = h->h_aliases; *pch != NULL; pch++) {
+			int status;
+			tmp = PyString_FromString(*pch);
+			if (tmp == NULL)
+				goto err;
+
+			status = PyList_Append(name_list, tmp);
+			Py_DECREF(tmp);
+
+			if (status)
+				goto err;
+		}
+	}
+
+	for (pch = h->h_addr_list; *pch != NULL; pch++) {
+		int status;
+
+		switch (af) {
+
+		case AF_INET:
+		    {
+			struct sockaddr_in sin;
+			memset(&sin, 0, sizeof(sin));
+			sin.sin_family = af;
+#ifdef HAVE_SOCKADDR_SA_LEN
+			sin.sin_len = sizeof(sin);
+#endif
+			memcpy(&sin.sin_addr, *pch, sizeof(sin.sin_addr));
+			tmp = makeipaddr((struct sockaddr *)&sin, sizeof(sin));
+
+			if (pch == h->h_addr_list && alen >= sizeof(sin))
+				memcpy((char *) addr, &sin, sizeof(sin));
+			break;
+		    }
+
+#ifdef ENABLE_IPV6
+		case AF_INET6:
+		    {
+			struct sockaddr_in6 sin6;
+			memset(&sin6, 0, sizeof(sin6));
+			sin6.sin6_family = af;
+#ifdef HAVE_SOCKADDR_SA_LEN
+			sin6.sin6_len = sizeof(sin6);
+#endif
+			memcpy(&sin6.sin6_addr, *pch, sizeof(sin6.sin6_addr));
+			tmp = makeipaddr((struct sockaddr *)&sin6,
+				sizeof(sin6));
+
+			if (pch == h->h_addr_list && alen >= sizeof(sin6))
+				memcpy((char *) addr, &sin6, sizeof(sin6));
+			break;
+		    }
+#endif
+
+		default:	/* can't happen */
+			PyErr_SetString(socket_error,
+					"unsupported address family");
+			return NULL;
+		}
+
+		if (tmp == NULL)
+			goto err;
+
+		status = PyList_Append(addr_list, tmp);
+		Py_DECREF(tmp);
+
+		if (status)
+			goto err;
+	}
+
+	rtn_tuple = Py_BuildValue("sOO", h->h_name, name_list, addr_list);
+
+ err:
+	Py_XDECREF(name_list);
+	Py_XDECREF(addr_list);
+	return rtn_tuple;
+}
+
+
+/* Python interface to gethostbyname_ex(name). */
+
+/*ARGSUSED*/
+static PyObject *
+socket_gethostbyname_ex(PyObject *self, PyObject *args)
+{
+	char *name;
+	struct hostent *h;
+#ifdef ENABLE_IPV6
+        struct sockaddr_storage addr;
+#else
+        struct sockaddr_in addr;
+#endif
+	struct sockaddr *sa;
+	PyObject *ret;
+#ifdef HAVE_GETHOSTBYNAME_R
+	struct hostent hp_allocated;
+#ifdef HAVE_GETHOSTBYNAME_R_3_ARG
+	struct hostent_data data;
+#else
+	char buf[16384];
+	int buf_len = (sizeof buf) - 1;
+	int errnop;
+#endif
+#if defined(HAVE_GETHOSTBYNAME_R_3_ARG) || defined(HAVE_GETHOSTBYNAME_R_6_ARG)
+	int result;
+#endif
+#endif /* HAVE_GETHOSTBYNAME_R */
+
+	if (!PyArg_ParseTuple(args, "s:gethostbyname_ex", &name))
+		return NULL;
+	if (setipaddr(name, (struct sockaddr *)&addr, sizeof(addr), AF_INET) < 0)
+		return NULL;
+	Py_BEGIN_ALLOW_THREADS
+#ifdef HAVE_GETHOSTBYNAME_R
+#if   defined(HAVE_GETHOSTBYNAME_R_6_ARG)
+	result = gethostbyname_r(name, &hp_allocated, buf, buf_len,
+				 &h, &errnop);
+#elif defined(HAVE_GETHOSTBYNAME_R_5_ARG)
+	h = gethostbyname_r(name, &hp_allocated, buf, buf_len, &errnop);
+#else /* HAVE_GETHOSTBYNAME_R_3_ARG */
+	memset((void *) &data, '\0', sizeof(data));
+	result = gethostbyname_r(name, &hp_allocated, &data);
+	h = (result != 0) ? NULL : &hp_allocated;
+#endif
+#else /* not HAVE_GETHOSTBYNAME_R */
+#ifdef USE_GETHOSTBYNAME_LOCK
+	PyThread_acquire_lock(netdb_lock, 1);
+#endif
+	h = gethostbyname(name);
+#endif /* HAVE_GETHOSTBYNAME_R */
+	Py_END_ALLOW_THREADS
+	/* Some C libraries would require addr.__ss_family instead of
+	   addr.ss_family.
+	   Therefore, we cast the sockaddr_storage into sockaddr to
+	   access sa_family. */
+	sa = (struct sockaddr*)&addr;
+	ret = gethost_common(h, (struct sockaddr *)&addr, sizeof(addr),
+			     sa->sa_family);
+#ifdef USE_GETHOSTBYNAME_LOCK
+	PyThread_release_lock(netdb_lock);
+#endif
+	return ret;
+}
+
+PyDoc_STRVAR(ghbn_ex_doc,
+"gethostbyname_ex(host) -> (name, aliaslist, addresslist)\n\
+\n\
+Return the true host name, a list of aliases, and a list of IP addresses,\n\
+for a host.  The host argument is a string giving a host name or IP number.");
+
+
+/* Python interface to gethostbyaddr(IP). */
+
+/*ARGSUSED*/
+static PyObject *
+socket_gethostbyaddr(PyObject *self, PyObject *args)
+{
+#ifdef ENABLE_IPV6
+	struct sockaddr_storage addr;
+#else
+	struct sockaddr_in addr;
+#endif
+	struct sockaddr *sa = (struct sockaddr *)&addr;
+	char *ip_num;
+	struct hostent *h;
+	PyObject *ret;
+#ifdef HAVE_GETHOSTBYNAME_R
+	struct hostent hp_allocated;
+#ifdef HAVE_GETHOSTBYNAME_R_3_ARG
+	struct hostent_data data;
+#else
+	char buf[16384];
+	int buf_len = (sizeof buf) - 1;
+	int errnop;
+#endif
+#if defined(HAVE_GETHOSTBYNAME_R_3_ARG) || defined(HAVE_GETHOSTBYNAME_R_6_ARG)
+	int result;
+#endif
+#endif /* HAVE_GETHOSTBYNAME_R */
+	char *ap;
+	int al;
+	int af;
+
+	if (!PyArg_ParseTuple(args, "s:gethostbyaddr", &ip_num))
+		return NULL;
+	af = AF_UNSPEC;
+	if (setipaddr(ip_num, sa, sizeof(addr), af) < 0)
+		return NULL;
+	af = sa->sa_family;
+	ap = NULL;
+	al = 0;
+	switch (af) {
+	case AF_INET:
+		ap = (char *)&((struct sockaddr_in *)sa)->sin_addr;
+		al = sizeof(((struct sockaddr_in *)sa)->sin_addr);
+		break;
+#ifdef ENABLE_IPV6
+	case AF_INET6:
+		ap = (char *)&((struct sockaddr_in6 *)sa)->sin6_addr;
+		al = sizeof(((struct sockaddr_in6 *)sa)->sin6_addr);
+		break;
+#endif
+	default:
+		PyErr_SetString(socket_error, "unsupported address family");
+		return NULL;
+	}
+	Py_BEGIN_ALLOW_THREADS
+#ifdef HAVE_GETHOSTBYNAME_R
+#if   defined(HAVE_GETHOSTBYNAME_R_6_ARG)
+	result = gethostbyaddr_r(ap, al, af,
+		&hp_allocated, buf, buf_len,
+		&h, &errnop);
+#elif defined(HAVE_GETHOSTBYNAME_R_5_ARG)
+	h = gethostbyaddr_r(ap, al, af,
+			    &hp_allocated, buf, buf_len, &errnop);
+#else /* HAVE_GETHOSTBYNAME_R_3_ARG */
+	memset((void *) &data, '\0', sizeof(data));
+	result = gethostbyaddr_r(ap, al, af, &hp_allocated, &data);
+	h = (result != 0) ? NULL : &hp_allocated;
+#endif
+#else /* not HAVE_GETHOSTBYNAME_R */
+#ifdef USE_GETHOSTBYNAME_LOCK
+	PyThread_acquire_lock(netdb_lock, 1);
+#endif
+	h = gethostbyaddr(ap, al, af);
+#endif /* HAVE_GETHOSTBYNAME_R */
+	Py_END_ALLOW_THREADS
+	ret = gethost_common(h, (struct sockaddr *)&addr, sizeof(addr), af);
+#ifdef USE_GETHOSTBYNAME_LOCK
+	PyThread_release_lock(netdb_lock);
+#endif
+	return ret;
+}
+
+PyDoc_STRVAR(gethostbyaddr_doc,
+"gethostbyaddr(host) -> (name, aliaslist, addresslist)\n\
+\n\
+Return the true host name, a list of aliases, and a list of IP addresses,\n\
+for a host.  The host argument is a string giving a host name or IP number.");
+
+
+/* Python interface to getservbyname(name).
+   This only returns the port number, since the other info is already
+   known or not useful (like the list of aliases). */
+
+/*ARGSUSED*/
+static PyObject *
+socket_getservbyname(PyObject *self, PyObject *args)
+{
+	char *name, *proto=NULL;
+	struct servent *sp;
+	if (!PyArg_ParseTuple(args, "s|s:getservbyname", &name, &proto))
+		return NULL;
+	Py_BEGIN_ALLOW_THREADS
+	sp = getservbyname(name, proto);
+	Py_END_ALLOW_THREADS
+	if (sp == NULL) {
+		PyErr_SetString(socket_error, "service/proto not found");
+		return NULL;
+	}
+	return PyInt_FromLong((long) ntohs(sp->s_port));
+}
+
+PyDoc_STRVAR(getservbyname_doc,
+"getservbyname(servicename[, protocolname]) -> integer\n\
+\n\
+Return a port number from a service name and protocol name.\n\
+The optional protocol name, if given, should be 'tcp' or 'udp',\n\
+otherwise any protocol will match.");
+
+
+/* Python interface to getservbyport(port).
+   This only returns the service name, since the other info is already
+   known or not useful (like the list of aliases). */
+
+/*ARGSUSED*/
+static PyObject *
+socket_getservbyport(PyObject *self, PyObject *args)
+{
+	unsigned short port;
+	char *proto=NULL;
+	struct servent *sp;
+	if (!PyArg_ParseTuple(args, "H|s:getservbyport", &port, &proto))
+		return NULL;
+	Py_BEGIN_ALLOW_THREADS
+	sp = getservbyport(htons(port), proto);
+	Py_END_ALLOW_THREADS
+	if (sp == NULL) {
+		PyErr_SetString(socket_error, "port/proto not found");
+		return NULL;
+	}
+	return PyString_FromString(sp->s_name);
+}
+
+PyDoc_STRVAR(getservbyport_doc,
+"getservbyport(port[, protocolname]) -> string\n\
+\n\
+Return the service name from a port number and protocol name.\n\
+The optional protocol name, if given, should be 'tcp' or 'udp',\n\
+otherwise any protocol will match.");
+
+/* Python interface to getprotobyname(name).
+   This only returns the protocol number, since the other info is
+   already known or not useful (like the list of aliases). */
+
+/*ARGSUSED*/
+static PyObject *
+socket_getprotobyname(PyObject *self, PyObject *args)
+{
+	char *name;
+	struct protoent *sp;
+#ifdef __BEOS__
+/* Not available in BeOS yet. - [cjh] */
+	PyErr_SetString(socket_error, "getprotobyname not supported");
+	return NULL;
+#else
+	if (!PyArg_ParseTuple(args, "s:getprotobyname", &name))
+		return NULL;
+	Py_BEGIN_ALLOW_THREADS
+	sp = getprotobyname(name);
+	Py_END_ALLOW_THREADS
+	if (sp == NULL) {
+		PyErr_SetString(socket_error, "protocol not found");
+		return NULL;
+	}
+	return PyInt_FromLong((long) sp->p_proto);
+#endif
+}
+
+PyDoc_STRVAR(getprotobyname_doc,
+"getprotobyname(name) -> integer\n\
+\n\
+Return the protocol number for the named protocol.  (Rarely used.)");
+
+
+#ifdef HAVE_SOCKETPAIR
+/* Create a pair of sockets using the socketpair() function.
+   Arguments as for socket() except the default family is AF_UNIX if
+   defined on the platform; otherwise, the default is AF_INET. */
+
+/*ARGSUSED*/
+static PyObject *
+socket_socketpair(PyObject *self, PyObject *args)
+{
+	PySocketSockObject *s0 = NULL, *s1 = NULL;
+	SOCKET_T sv[2];
+	int family, type = SOCK_STREAM, proto = 0;
+	PyObject *res = NULL;
+
+#if defined(AF_UNIX)
+	family = AF_UNIX;
+#else
+	family = AF_INET;
+#endif
+	if (!PyArg_ParseTuple(args, "|iii:socketpair",
+			      &family, &type, &proto))
+		return NULL;
+	/* Create a pair of socket fds */
+	if (socketpair(family, type, proto, sv) < 0)
+		return set_error();
+	s0 = new_sockobject(sv[0], family, type, proto);
+	if (s0 == NULL)
+		goto finally;
+	s1 = new_sockobject(sv[1], family, type, proto);
+	if (s1 == NULL)
+		goto finally;
+	res = PyTuple_Pack(2, s0, s1);
+
+finally:
+	if (res == NULL) {
+		if (s0 == NULL)
+			SOCKETCLOSE(sv[0]);
+		if (s1 == NULL)
+			SOCKETCLOSE(sv[1]);
+	}
+	Py_XDECREF(s0);
+	Py_XDECREF(s1);
+	return res;
+}
+
+PyDoc_STRVAR(socketpair_doc,
+"socketpair([family[, type[, proto]]]) -> (socket object, socket object)\n\
+\n\
+Create a pair of socket objects from the sockets returned by the platform\n\
+socketpair() function.\n\
+The arguments are the same as for socket() except the default family is\n\
+AF_UNIX if defined on the platform; otherwise, the default is AF_INET.");
+
+#endif /* HAVE_SOCKETPAIR */
+
+
+#ifndef NO_DUP
+/* Create a socket object from a numeric file description.
+   Useful e.g. if stdin is a socket.
+   Additional arguments as for socket(). */
+
+/*ARGSUSED*/
+static PyObject *
+socket_fromfd(PyObject *self, PyObject *args)
+{
+	PySocketSockObject *s;
+	SOCKET_T fd;
+	int family, type, proto = 0;
+	if (!PyArg_ParseTuple(args, "iii|i:fromfd",
+			      &fd, &family, &type, &proto))
+		return NULL;
+	/* Dup the fd so it and the socket can be closed independently */
+	fd = dup(fd);
+	if (fd < 0)
+		return set_error();
+	s = new_sockobject(fd, family, type, proto);
+	return (PyObject *) s;
+}
+
+PyDoc_STRVAR(fromfd_doc,
+"fromfd(fd, family, type[, proto]) -> socket object\n\
+\n\
+Create a socket object from a duplicate of the given\n\
+file descriptor.\n\
+The remaining arguments are the same as for socket().");
+
+#endif /* NO_DUP */
+
+
+static PyObject *
+socket_ntohs(PyObject *self, PyObject *args)
+{
+	int x1, x2;
+
+	if (!PyArg_ParseTuple(args, "i:ntohs", &x1)) {
+		return NULL;
+	}
+	x2 = (int)ntohs((short)x1);
+	return PyInt_FromLong(x2);
+}
+
+PyDoc_STRVAR(ntohs_doc,
+"ntohs(integer) -> integer\n\
+\n\
+Convert a 16-bit integer from network to host byte order.");
+
+
+static PyObject *
+socket_ntohl(PyObject *self, PyObject *arg)
+{
+	unsigned long x;
+
+	if (PyInt_Check(arg)) {
+		x = PyInt_AS_LONG(arg);
+		if (x == (unsigned long) -1 && PyErr_Occurred())
+			return NULL;
+	}
+	else if (PyLong_Check(arg)) {
+		x = PyLong_AsUnsignedLong(arg);
+		if (x == (unsigned long) -1 && PyErr_Occurred())
+			return NULL;
+#if SIZEOF_LONG > 4
+		{
+			unsigned long y;
+			/* only want the trailing 32 bits */
+			y = x & 0xFFFFFFFFUL;
+			if (y ^ x)
+				return PyErr_Format(PyExc_OverflowError,
+					    "long int larger than 32 bits");
+			x = y;
+		}
+#endif
+	}
+	else
+		return PyErr_Format(PyExc_TypeError,
+				    "expected int/long, %s found",
+				    arg->ob_type->tp_name);
+	if (x == (unsigned long) -1 && PyErr_Occurred())
+		return NULL;
+	return PyInt_FromLong(ntohl(x));
+}
+
+PyDoc_STRVAR(ntohl_doc,
+"ntohl(integer) -> integer\n\
+\n\
+Convert a 32-bit integer from network to host byte order.");
+
+
+static PyObject *
+socket_htons(PyObject *self, PyObject *args)
+{
+	int x1, x2;
+
+	if (!PyArg_ParseTuple(args, "i:htons", &x1)) {
+		return NULL;
+	}
+	x2 = (int)htons((short)x1);
+	return PyInt_FromLong(x2);
+}
+
+PyDoc_STRVAR(htons_doc,
+"htons(integer) -> integer\n\
+\n\
+Convert a 16-bit integer from host to network byte order.");
+
+
+static PyObject *
+socket_htonl(PyObject *self, PyObject *arg)
+{
+	unsigned long x;
+
+	if (PyInt_Check(arg)) {
+		x = PyInt_AS_LONG(arg);
+		if (x == (unsigned long) -1 && PyErr_Occurred())
+			return NULL;
+	}
+	else if (PyLong_Check(arg)) {
+		x = PyLong_AsUnsignedLong(arg);
+		if (x == (unsigned long) -1 && PyErr_Occurred())
+			return NULL;
+#if SIZEOF_LONG > 4
+		{
+			unsigned long y;
+			/* only want the trailing 32 bits */
+			y = x & 0xFFFFFFFFUL;
+			if (y ^ x)
+				return PyErr_Format(PyExc_OverflowError,
+					    "long int larger than 32 bits");
+			x = y;
+		}
+#endif
+	}
+	else
+		return PyErr_Format(PyExc_TypeError,
+				    "expected int/long, %s found",
+				    arg->ob_type->tp_name);
+	return PyInt_FromLong(htonl(x));
+}
+
+PyDoc_STRVAR(htonl_doc,
+"htonl(integer) -> integer\n\
+\n\
+Convert a 32-bit integer from host to network byte order.");
+
+/* socket.inet_aton() and socket.inet_ntoa() functions. */
+
+PyDoc_STRVAR(inet_aton_doc,
+"inet_aton(string) -> packed 32-bit IP representation\n\
+\n\
+Convert an IP address in string format (123.45.67.89) to the 32-bit packed\n\
+binary format used in low-level network functions.");
+
+static PyObject*
+socket_inet_aton(PyObject *self, PyObject *args)
+{
+#ifndef INADDR_NONE
+#define INADDR_NONE (-1)
+#endif
+#ifdef HAVE_INET_ATON
+	struct in_addr buf;
+#endif
+
+#if !defined(HAVE_INET_ATON) || defined(USE_INET_ATON_WEAKLINK)
+	/* Have to use inet_addr() instead */
+	unsigned long packed_addr;
+#endif
+	char *ip_addr;
+
+	if (!PyArg_ParseTuple(args, "s:inet_aton", &ip_addr))
+		return NULL;
+
+
+#ifdef HAVE_INET_ATON
+
+#ifdef USE_INET_ATON_WEAKLINK
+    if (inet_aton != NULL) {
+#endif
+	if (inet_aton(ip_addr, &buf))
+		return PyString_FromStringAndSize((char *)(&buf),
+						  sizeof(buf));
+
+	PyErr_SetString(socket_error,
+			"illegal IP address string passed to inet_aton");
+	return NULL;
+
+#ifdef USE_INET_ATON_WEAKLINK
+   } else {
+#endif
+
+#endif
+
+#if !defined(HAVE_INET_ATON) || defined(USE_INET_ATON_WEAKLINK)
+
+	/* special-case this address as inet_addr might return INADDR_NONE
+	 * for this */
+	if (strcmp(ip_addr, "255.255.255.255") == 0) {
+		packed_addr = 0xFFFFFFFF;
+	} else {
+
+		packed_addr = inet_addr(ip_addr);
+
+		if (packed_addr == INADDR_NONE) {	/* invalid address */
+			PyErr_SetString(socket_error,
+				"illegal IP address string passed to inet_aton");
+			return NULL;
+		}
+	}
+	return PyString_FromStringAndSize((char *) &packed_addr,
+					  sizeof(packed_addr));
+
+#ifdef USE_INET_ATON_WEAKLINK
+   }
+#endif
+
+#endif
+}
+
+PyDoc_STRVAR(inet_ntoa_doc,
+"inet_ntoa(packed_ip) -> ip_address_string\n\
+\n\
+Convert an IP address from 32-bit packed binary format to string format");
+
+static PyObject*
+socket_inet_ntoa(PyObject *self, PyObject *args)
+{
+	char *packed_str;
+	int addr_len;
+	struct in_addr packed_addr;
+
+	if (!PyArg_ParseTuple(args, "s#:inet_ntoa", &packed_str, &addr_len)) {
+		return NULL;
+	}
+
+	if (addr_len != sizeof(packed_addr)) {
+		PyErr_SetString(socket_error,
+			"packed IP wrong length for inet_ntoa");
+		return NULL;
+	}
+
+	memcpy(&packed_addr, packed_str, addr_len);
+
+	return PyString_FromString(inet_ntoa(packed_addr));
+}
+
+#ifdef HAVE_INET_PTON
+
+PyDoc_STRVAR(inet_pton_doc,
+"inet_pton(af, ip) -> packed IP address string\n\
+\n\
+Convert an IP address from string format to a packed string suitable\n\
+for use with low-level network functions.");
+
+static PyObject *
+socket_inet_pton(PyObject *self, PyObject *args)
+{
+	int af;
+	char* ip;
+	int retval;
+#ifdef ENABLE_IPV6
+	char packed[MAX(sizeof(struct in_addr), sizeof(struct in6_addr))];
+#else
+	char packed[sizeof(struct in_addr)];
+#endif
+	if (!PyArg_ParseTuple(args, "is:inet_pton", &af, &ip)) {
+		return NULL;
+	}
+
+#if !defined(ENABLE_IPV6) && defined(AF_INET6)
+	if(af == AF_INET6) {
+		PyErr_SetString(socket_error,
+				"can't use AF_INET6, IPv6 is disabled");
+		return NULL;
+	}
+#endif
+
+	retval = inet_pton(af, ip, packed);
+	if (retval < 0) {
+		PyErr_SetFromErrno(socket_error);
+		return NULL;
+	} else if (retval == 0) {
+		PyErr_SetString(socket_error,
+			"illegal IP address string passed to inet_pton");
+		return NULL;
+	} else if (af == AF_INET) {
+		return PyString_FromStringAndSize(packed,
+			sizeof(struct in_addr));
+#ifdef ENABLE_IPV6
+	} else if (af == AF_INET6) {
+		return PyString_FromStringAndSize(packed,
+			sizeof(struct in6_addr));
+#endif
+	} else {
+		PyErr_SetString(socket_error, "unknown address family");
+		return NULL;
+	}
+}
+
+PyDoc_STRVAR(inet_ntop_doc,
+"inet_ntop(af, packed_ip) -> string formatted IP address\n\
+\n\
+Convert a packed IP address of the given family to string format.");
+
+static PyObject *
+socket_inet_ntop(PyObject *self, PyObject *args)
+{
+	int af;
+	char* packed;
+	int len;
+	const char* retval;
+#ifdef ENABLE_IPV6
+	char ip[MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN) + 1];
+#else
+	char ip[INET_ADDRSTRLEN + 1];
+#endif
+
+	/* Guarantee NUL-termination for PyString_FromString() below */
+	memset((void *) &ip[0], '\0', sizeof(ip));
+
+	if (!PyArg_ParseTuple(args, "is#:inet_ntop", &af, &packed, &len)) {
+		return NULL;
+	}
+
+	if (af == AF_INET) {
+		if (len != sizeof(struct in_addr)) {
+			PyErr_SetString(PyExc_ValueError,
+				"invalid length of packed IP address string");
+			return NULL;
+		}
+#ifdef ENABLE_IPV6
+	} else if (af == AF_INET6) {
+		if (len != sizeof(struct in6_addr)) {
+			PyErr_SetString(PyExc_ValueError,
+				"invalid length of packed IP address string");
+			return NULL;
+		}
+#endif
+	} else {
+		PyErr_Format(PyExc_ValueError,
+			"unknown address family %d", af);
+		return NULL;
+	}
+
+	retval = inet_ntop(af, packed, ip, sizeof(ip));
+	if (!retval) {
+		PyErr_SetFromErrno(socket_error);
+		return NULL;
+	} else {
+		return PyString_FromString(retval);
+	}
+
+	/* NOTREACHED */
+	PyErr_SetString(PyExc_RuntimeError, "invalid handling of inet_ntop");
+	return NULL;
+}
+
+#endif /* HAVE_INET_PTON */
+
+/* Python interface to getaddrinfo(host, port). */
+
+/*ARGSUSED*/
+static PyObject *
+socket_getaddrinfo(PyObject *self, PyObject *args)
+{
+	struct addrinfo hints, *res;
+	struct addrinfo *res0 = NULL;
+	PyObject *hobj = NULL;
+	PyObject *pobj = (PyObject *)NULL;
+	char pbuf[30];
+	char *hptr, *pptr;
+	int family, socktype, protocol, flags;
+	int error;
+	PyObject *all = (PyObject *)NULL;
+	PyObject *single = (PyObject *)NULL;
+	PyObject *idna = NULL;
+
+	family = socktype = protocol = flags = 0;
+	family = AF_UNSPEC;
+	if (!PyArg_ParseTuple(args, "OO|iiii:getaddrinfo",
+			      &hobj, &pobj, &family, &socktype,
+			      &protocol, &flags)) {
+		return NULL;
+	}
+	if (hobj == Py_None) {
+		hptr = NULL;
+	} else if (PyUnicode_Check(hobj)) {
+		idna = PyObject_CallMethod(hobj, "encode", "s", "idna");
+		if (!idna)
+			return NULL;
+		hptr = PyString_AsString(idna);
+	} else if (PyString_Check(hobj)) {
+		hptr = PyString_AsString(hobj);
+	} else {
+		PyErr_SetString(PyExc_TypeError,
+				"getaddrinfo() argument 1 must be string or None");
+		return NULL;
+	}
+	if (PyInt_Check(pobj)) {
+		PyOS_snprintf(pbuf, sizeof(pbuf), "%ld", PyInt_AsLong(pobj));
+		pptr = pbuf;
+	} else if (PyString_Check(pobj)) {
+		pptr = PyString_AsString(pobj);
+	} else if (pobj == Py_None) {
+		pptr = (char *)NULL;
+	} else {
+		PyErr_SetString(socket_error, "Int or String expected");
+                goto err;
+	}
+	memset(&hints, 0, sizeof(hints));
+	hints.ai_family = family;
+	hints.ai_socktype = socktype;
+	hints.ai_protocol = protocol;
+	hints.ai_flags = flags;
+	Py_BEGIN_ALLOW_THREADS
+	ACQUIRE_GETADDRINFO_LOCK
+	error = getaddrinfo(hptr, pptr, &hints, &res0);
+	Py_END_ALLOW_THREADS
+	RELEASE_GETADDRINFO_LOCK  /* see comment in setipaddr() */
+	if (error) {
+		set_gaierror(error);
+		goto err;
+	}
+
+	if ((all = PyList_New(0)) == NULL)
+		goto err;
+	for (res = res0; res; res = res->ai_next) {
+		PyObject *addr =
+			makesockaddr(-1, res->ai_addr, res->ai_addrlen, protocol);
+		if (addr == NULL)
+			goto err;
+		single = Py_BuildValue("iiisO", res->ai_family,
+			res->ai_socktype, res->ai_protocol,
+			res->ai_canonname ? res->ai_canonname : "",
+			addr);
+		Py_DECREF(addr);
+		if (single == NULL)
+			goto err;
+
+		if (PyList_Append(all, single))
+			goto err;
+		Py_XDECREF(single);
+	}
+	Py_XDECREF(idna);
+	if (res0)
+		freeaddrinfo(res0);
+	return all;
+ err:
+	Py_XDECREF(single);
+	Py_XDECREF(all);
+	Py_XDECREF(idna);
+	if (res0)
+		freeaddrinfo(res0);
+	return (PyObject *)NULL;
+}
+
+PyDoc_STRVAR(getaddrinfo_doc,
+"getaddrinfo(host, port [, family, socktype, proto, flags])\n\
+    -> list of (family, socktype, proto, canonname, sockaddr)\n\
+\n\
+Resolve host and port into addrinfo struct.");
+
+/* Python interface to getnameinfo(sa, flags). */
+
+/*ARGSUSED*/
+static PyObject *
+socket_getnameinfo(PyObject *self, PyObject *args)
+{
+	PyObject *sa = (PyObject *)NULL;
+	int flags;
+	char *hostp;
+	int port, flowinfo, scope_id;
+	char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];
+	struct addrinfo hints, *res = NULL;
+	int error;
+	PyObject *ret = (PyObject *)NULL;
+
+	flags = flowinfo = scope_id = 0;
+	if (!PyArg_ParseTuple(args, "Oi:getnameinfo", &sa, &flags))
+		return NULL;
+	if  (!PyArg_ParseTuple(sa, "si|ii",
+			       &hostp, &port, &flowinfo, &scope_id))
+		return NULL;
+	PyOS_snprintf(pbuf, sizeof(pbuf), "%d", port);
+	memset(&hints, 0, sizeof(hints));
+	hints.ai_family = AF_UNSPEC;
+	hints.ai_socktype = SOCK_DGRAM;	/* make numeric port happy */
+	Py_BEGIN_ALLOW_THREADS
+	ACQUIRE_GETADDRINFO_LOCK
+	error = getaddrinfo(hostp, pbuf, &hints, &res);
+	Py_END_ALLOW_THREADS
+	RELEASE_GETADDRINFO_LOCK  /* see comment in setipaddr() */
+	if (error) {
+		set_gaierror(error);
+		goto fail;
+	}
+	if (res->ai_next) {
+		PyErr_SetString(socket_error,
+			"sockaddr resolved to multiple addresses");
+		goto fail;
+	}
+	switch (res->ai_family) {
+	case AF_INET:
+	    {
+		char *t1;
+		int t2;
+		if (PyArg_ParseTuple(sa, "si", &t1, &t2) == 0) {
+			PyErr_SetString(socket_error,
+				"IPv4 sockaddr must be 2 tuple");
+			goto fail;
+		}
+		break;
+	    }
+#ifdef ENABLE_IPV6
+	case AF_INET6:
+	    {
+		struct sockaddr_in6 *sin6;
+		sin6 = (struct sockaddr_in6 *)res->ai_addr;
+		sin6->sin6_flowinfo = flowinfo;
+		sin6->sin6_scope_id = scope_id;
+		break;
+	    }
+#endif
+	}
+	error = getnameinfo(res->ai_addr, res->ai_addrlen,
+			hbuf, sizeof(hbuf), pbuf, sizeof(pbuf), flags);
+	if (error) {
+		set_gaierror(error);
+		goto fail;
+	}
+	ret = Py_BuildValue("ss", hbuf, pbuf);
+
+fail:
+	if (res)
+		freeaddrinfo(res);
+	return ret;
+}
+
+PyDoc_STRVAR(getnameinfo_doc,
+"getnameinfo(sockaddr, flags) --> (host, port)\n\
+\n\
+Get host and port for a sockaddr.");
+
+
+/* Python API to getting and setting the default timeout value. */
+
+static PyObject *
+socket_getdefaulttimeout(PyObject *self)
+{
+	if (defaulttimeout < 0.0) {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+	else
+		return PyFloat_FromDouble(defaulttimeout);
+}
+
+PyDoc_STRVAR(getdefaulttimeout_doc,
+"getdefaulttimeout() -> timeout\n\
+\n\
+Returns the default timeout in floating seconds for new socket objects.\n\
+A value of None indicates that new socket objects have no timeout.\n\
+When the socket module is first imported, the default is None.");
+
+static PyObject *
+socket_setdefaulttimeout(PyObject *self, PyObject *arg)
+{
+	double timeout;
+
+	if (arg == Py_None)
+		timeout = -1.0;
+	else {
+		timeout = PyFloat_AsDouble(arg);
+		if (timeout < 0.0) {
+			if (!PyErr_Occurred())
+				PyErr_SetString(PyExc_ValueError,
+						"Timeout value out of range");
+			return NULL;
+		}
+	}
+
+	defaulttimeout = timeout;
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(setdefaulttimeout_doc,
+"setdefaulttimeout(timeout)\n\
+\n\
+Set the default timeout in floating seconds for new socket objects.\n\
+A value of None indicates that new socket objects have no timeout.\n\
+When the socket module is first imported, the default is None.");
+
+
+/* List of functions exported by this module. */
+
+static PyMethodDef socket_methods[] = {
+	{"gethostbyname",	socket_gethostbyname,
+	 METH_VARARGS, gethostbyname_doc},
+	{"gethostbyname_ex",	socket_gethostbyname_ex,
+	 METH_VARARGS, ghbn_ex_doc},
+	{"gethostbyaddr",	socket_gethostbyaddr,
+	 METH_VARARGS, gethostbyaddr_doc},
+	{"gethostname",		socket_gethostname,
+	 METH_NOARGS,  gethostname_doc},
+	{"getservbyname",	socket_getservbyname,
+	 METH_VARARGS, getservbyname_doc},
+	{"getservbyport",	socket_getservbyport,
+	 METH_VARARGS, getservbyport_doc},
+	{"getprotobyname",	socket_getprotobyname,
+	 METH_VARARGS, getprotobyname_doc},
+#ifndef NO_DUP
+	{"fromfd",		socket_fromfd,
+	 METH_VARARGS, fromfd_doc},
+#endif
+#ifdef HAVE_SOCKETPAIR
+	{"socketpair",		socket_socketpair,
+	 METH_VARARGS, socketpair_doc},
+#endif
+	{"ntohs",		socket_ntohs,
+	 METH_VARARGS, ntohs_doc},
+	{"ntohl",		socket_ntohl,
+	 METH_O, ntohl_doc},
+	{"htons",		socket_htons,
+	 METH_VARARGS, htons_doc},
+	{"htonl",		socket_htonl,
+	 METH_O, htonl_doc},
+	{"inet_aton",		socket_inet_aton,
+	 METH_VARARGS, inet_aton_doc},
+	{"inet_ntoa",		socket_inet_ntoa,
+	 METH_VARARGS, inet_ntoa_doc},
+#ifdef HAVE_INET_PTON
+	{"inet_pton",		socket_inet_pton,
+	 METH_VARARGS, inet_pton_doc},
+	{"inet_ntop",		socket_inet_ntop,
+	 METH_VARARGS, inet_ntop_doc},
+#endif
+	{"getaddrinfo",		socket_getaddrinfo,
+	 METH_VARARGS, getaddrinfo_doc},
+	{"getnameinfo",		socket_getnameinfo,
+	 METH_VARARGS, getnameinfo_doc},
+	{"getdefaulttimeout",	(PyCFunction)socket_getdefaulttimeout,
+	 METH_NOARGS, getdefaulttimeout_doc},
+	{"setdefaulttimeout",	socket_setdefaulttimeout,
+	 METH_O, setdefaulttimeout_doc},
+	{NULL,			NULL}		 /* Sentinel */
+};
+
+
+#ifdef RISCOS
+#define OS_INIT_DEFINED
+
+static int
+os_init(void)
+{
+	_kernel_swi_regs r;
+
+	r.r[0] = 0;
+	_kernel_swi(0x43380, &r, &r);
+	taskwindow = r.r[0];
+
+	return 1;
+}
+
+#endif /* RISCOS */
+
+
+#ifdef MS_WINDOWS
+#define OS_INIT_DEFINED
+
+/* Additional initialization and cleanup for Windows */
+
+static void
+os_cleanup(void)
+{
+	WSACleanup();
+}
+
+static int
+os_init(void)
+{
+	WSADATA WSAData;
+	int ret;
+	char buf[100];
+	ret = WSAStartup(0x0101, &WSAData);
+	switch (ret) {
+	case 0:	/* No error */
+		Py_AtExit(os_cleanup);
+		return 1; /* Success */
+	case WSASYSNOTREADY:
+		PyErr_SetString(PyExc_ImportError,
+				"WSAStartup failed: network not ready");
+		break;
+	case WSAVERNOTSUPPORTED:
+	case WSAEINVAL:
+		PyErr_SetString(
+			PyExc_ImportError,
+			"WSAStartup failed: requested version not supported");
+		break;
+	default:
+		PyOS_snprintf(buf, sizeof(buf),
+			      "WSAStartup failed: error code %d", ret);
+		PyErr_SetString(PyExc_ImportError, buf);
+		break;
+	}
+	return 0; /* Failure */
+}
+
+#endif /* MS_WINDOWS */
+
+
+#ifdef PYOS_OS2
+#define OS_INIT_DEFINED
+
+/* Additional initialization for OS/2 */
+
+static int
+os_init(void)
+{
+#ifndef PYCC_GCC
+	char reason[64];
+	int rc = sock_init();
+
+	if (rc == 0) {
+		return 1; /* Success */
+	}
+
+	PyOS_snprintf(reason, sizeof(reason),
+		      "OS/2 TCP/IP Error# %d", sock_errno());
+	PyErr_SetString(PyExc_ImportError, reason);
+
+	return 0;  /* Failure */
+#else
+	/* No need to initialise sockets with GCC/EMX */
+	return 1; /* Success */
+#endif
+}
+
+#endif /* PYOS_OS2 */
+
+
+#ifndef OS_INIT_DEFINED
+static int
+os_init(void)
+{
+	return 1; /* Success */
+}
+#endif
+
+
+/* C API table - always add new things to the end for binary
+   compatibility. */
+static
+PySocketModule_APIObject PySocketModuleAPI =
+{
+	&sock_type,
+        NULL
+};
+
+
+/* Initialize the _socket module.
+
+   This module is actually called "_socket", and there's a wrapper
+   "socket.py" which implements some additional functionality.  On some
+   platforms (e.g. Windows and OS/2), socket.py also implements a
+   wrapper for the socket type that provides missing functionality such
+   as makefile(), dup() and fromfd().  The import of "_socket" may fail
+   with an ImportError exception if os-specific initialization fails.
+   On Windows, this does WINSOCK initialization.  When WINSOCK is
+   initialized succesfully, a call to WSACleanup() is scheduled to be
+   made at exit time.
+*/
+
+PyDoc_STRVAR(socket_doc,
+"Implementation module for socket operations.\n\
+\n\
+See the socket module for documentation.");
+
+PyMODINIT_FUNC
+init_socket(void)
+{
+	PyObject *m, *has_ipv6;
+
+	if (!os_init())
+		return;
+
+	sock_type.ob_type = &PyType_Type;
+	m = Py_InitModule3(PySocket_MODULE_NAME,
+			   socket_methods,
+			   socket_doc);
+	if (m == NULL)
+		return;
+
+	socket_error = PyErr_NewException("socket.error", NULL, NULL);
+	if (socket_error == NULL)
+		return;
+        PySocketModuleAPI.error = socket_error;
+	Py_INCREF(socket_error);
+	PyModule_AddObject(m, "error", socket_error);
+	socket_herror = PyErr_NewException("socket.herror",
+					   socket_error, NULL);
+	if (socket_herror == NULL)
+		return;
+	Py_INCREF(socket_herror);
+	PyModule_AddObject(m, "herror", socket_herror);
+	socket_gaierror = PyErr_NewException("socket.gaierror", socket_error,
+	    NULL);
+	if (socket_gaierror == NULL)
+		return;
+	Py_INCREF(socket_gaierror);
+	PyModule_AddObject(m, "gaierror", socket_gaierror);
+	socket_timeout = PyErr_NewException("socket.timeout",
+					    socket_error, NULL);
+	if (socket_timeout == NULL)
+		return;
+	Py_INCREF(socket_timeout);
+	PyModule_AddObject(m, "timeout", socket_timeout);
+	Py_INCREF((PyObject *)&sock_type);
+	if (PyModule_AddObject(m, "SocketType",
+			       (PyObject *)&sock_type) != 0)
+		return;
+	Py_INCREF((PyObject *)&sock_type);
+	if (PyModule_AddObject(m, "socket",
+			       (PyObject *)&sock_type) != 0)
+		return;
+
+#ifdef ENABLE_IPV6
+	has_ipv6 = Py_True;
+#else
+	has_ipv6 = Py_False;
+#endif
+	Py_INCREF(has_ipv6);
+	PyModule_AddObject(m, "has_ipv6", has_ipv6);
+
+	/* Export C API */
+	if (PyModule_AddObject(m, PySocket_CAPI_NAME,
+	       PyCObject_FromVoidPtr((void *)&PySocketModuleAPI, NULL)
+				 ) != 0)
+		return;
+
+	/* Address families (we only support AF_INET and AF_UNIX) */
+#ifdef AF_UNSPEC
+	PyModule_AddIntConstant(m, "AF_UNSPEC", AF_UNSPEC);
+#endif
+	PyModule_AddIntConstant(m, "AF_INET", AF_INET);
+#ifdef AF_INET6
+	PyModule_AddIntConstant(m, "AF_INET6", AF_INET6);
+#endif /* AF_INET6 */
+#if defined(AF_UNIX)
+	PyModule_AddIntConstant(m, "AF_UNIX", AF_UNIX);
+#endif /* AF_UNIX */
+#ifdef AF_AX25
+	/* Amateur Radio AX.25 */
+	PyModule_AddIntConstant(m, "AF_AX25", AF_AX25);
+#endif
+#ifdef AF_IPX
+	PyModule_AddIntConstant(m, "AF_IPX", AF_IPX); /* Novell IPX */
+#endif
+#ifdef AF_APPLETALK
+	/* Appletalk DDP */
+	PyModule_AddIntConstant(m, "AF_APPLETALK", AF_APPLETALK);
+#endif
+#ifdef AF_NETROM
+	/* Amateur radio NetROM */
+	PyModule_AddIntConstant(m, "AF_NETROM", AF_NETROM);
+#endif
+#ifdef AF_BRIDGE
+	/* Multiprotocol bridge */
+	PyModule_AddIntConstant(m, "AF_BRIDGE", AF_BRIDGE);
+#endif
+#ifdef AF_ATMPVC
+	/* ATM PVCs */
+	PyModule_AddIntConstant(m, "AF_ATMPVC", AF_ATMPVC);
+#endif
+#ifdef AF_AAL5
+	/* Reserved for Werner's ATM */
+	PyModule_AddIntConstant(m, "AF_AAL5", AF_AAL5);
+#endif
+#ifdef AF_X25
+	/* Reserved for X.25 project */
+	PyModule_AddIntConstant(m, "AF_X25", AF_X25);
+#endif
+#ifdef AF_INET6
+	PyModule_AddIntConstant(m, "AF_INET6", AF_INET6); /* IP version 6 */
+#endif
+#ifdef AF_ROSE
+	/* Amateur Radio X.25 PLP */
+	PyModule_AddIntConstant(m, "AF_ROSE", AF_ROSE);
+#endif
+#ifdef AF_DECnet
+	/* Reserved for DECnet project */
+	PyModule_AddIntConstant(m, "AF_DECnet", AF_DECnet);
+#endif
+#ifdef AF_NETBEUI
+	/* Reserved for 802.2LLC project */
+	PyModule_AddIntConstant(m, "AF_NETBEUI", AF_NETBEUI);
+#endif
+#ifdef AF_SECURITY
+	/* Security callback pseudo AF */
+	PyModule_AddIntConstant(m, "AF_SECURITY", AF_SECURITY);
+#endif
+#ifdef AF_KEY
+	/* PF_KEY key management API */
+	PyModule_AddIntConstant(m, "AF_KEY", AF_KEY);
+#endif
+#ifdef AF_NETLINK
+	/*  */
+	PyModule_AddIntConstant(m, "AF_NETLINK", AF_NETLINK);
+	PyModule_AddIntConstant(m, "NETLINK_ROUTE", NETLINK_ROUTE);
+#ifdef NETLINK_SKIP
+	PyModule_AddIntConstant(m, "NETLINK_SKIP", NETLINK_SKIP);
+#endif
+#ifdef NETLINK_W1
+	PyModule_AddIntConstant(m, "NETLINK_W1", NETLINK_W1);
+#endif
+	PyModule_AddIntConstant(m, "NETLINK_USERSOCK", NETLINK_USERSOCK);
+	PyModule_AddIntConstant(m, "NETLINK_FIREWALL", NETLINK_FIREWALL);
+#ifdef NETLINK_TCPDIAG
+	PyModule_AddIntConstant(m, "NETLINK_TCPDIAG", NETLINK_TCPDIAG);
+#endif
+#ifdef NETLINK_NFLOG
+	PyModule_AddIntConstant(m, "NETLINK_NFLOG", NETLINK_NFLOG);
+#endif
+#ifdef NETLINK_XFRM
+	PyModule_AddIntConstant(m, "NETLINK_XFRM", NETLINK_XFRM);
+#endif
+#ifdef NETLINK_ARPD
+	PyModule_AddIntConstant(m, "NETLINK_ARPD", NETLINK_ARPD);
+#endif
+#ifdef NETLINK_ROUTE6
+	PyModule_AddIntConstant(m, "NETLINK_ROUTE6", NETLINK_ROUTE6);
+#endif
+	PyModule_AddIntConstant(m, "NETLINK_IP6_FW", NETLINK_IP6_FW);
+#ifdef NETLINK_DNRTMSG
+	PyModule_AddIntConstant(m, "NETLINK_DNRTMSG", NETLINK_DNRTMSG);
+#endif 
+#ifdef NETLINK_TAPBASE
+	PyModule_AddIntConstant(m, "NETLINK_TAPBASE", NETLINK_TAPBASE);
+#endif
+#endif /* AF_NETLINK */
+#ifdef AF_ROUTE
+	/* Alias to emulate 4.4BSD */
+	PyModule_AddIntConstant(m, "AF_ROUTE", AF_ROUTE);
+#endif
+#ifdef AF_ASH
+	/* Ash */
+	PyModule_AddIntConstant(m, "AF_ASH", AF_ASH);
+#endif
+#ifdef AF_ECONET
+	/* Acorn Econet */
+	PyModule_AddIntConstant(m, "AF_ECONET", AF_ECONET);
+#endif
+#ifdef AF_ATMSVC
+	/* ATM SVCs */
+	PyModule_AddIntConstant(m, "AF_ATMSVC", AF_ATMSVC);
+#endif
+#ifdef AF_SNA
+	/* Linux SNA Project (nutters!) */
+	PyModule_AddIntConstant(m, "AF_SNA", AF_SNA);
+#endif
+#ifdef AF_IRDA
+	/* IRDA sockets */
+	PyModule_AddIntConstant(m, "AF_IRDA", AF_IRDA);
+#endif
+#ifdef AF_PPPOX
+	/* PPPoX sockets */
+	PyModule_AddIntConstant(m, "AF_PPPOX", AF_PPPOX);
+#endif
+#ifdef AF_WANPIPE
+	/* Wanpipe API Sockets */
+	PyModule_AddIntConstant(m, "AF_WANPIPE", AF_WANPIPE);
+#endif
+#ifdef AF_LLC
+	/* Linux LLC */
+	PyModule_AddIntConstant(m, "AF_LLC", AF_LLC);
+#endif
+
+#ifdef USE_BLUETOOTH
+	PyModule_AddIntConstant(m, "AF_BLUETOOTH", AF_BLUETOOTH);
+	PyModule_AddIntConstant(m, "BTPROTO_L2CAP", BTPROTO_L2CAP);
+#if !defined(__FreeBSD__)
+	PyModule_AddIntConstant(m, "BTPROTO_SCO", BTPROTO_SCO);
+#endif
+	PyModule_AddIntConstant(m, "BTPROTO_RFCOMM", BTPROTO_RFCOMM);
+	PyModule_AddStringConstant(m, "BDADDR_ANY", "00:00:00:00:00:00");
+	PyModule_AddStringConstant(m, "BDADDR_LOCAL", "00:00:00:FF:FF:FF");
+#endif
+
+#ifdef HAVE_NETPACKET_PACKET_H
+	PyModule_AddIntConstant(m, "AF_PACKET", AF_PACKET);
+	PyModule_AddIntConstant(m, "PF_PACKET", PF_PACKET);
+	PyModule_AddIntConstant(m, "PACKET_HOST", PACKET_HOST);
+	PyModule_AddIntConstant(m, "PACKET_BROADCAST", PACKET_BROADCAST);
+	PyModule_AddIntConstant(m, "PACKET_MULTICAST", PACKET_MULTICAST);
+	PyModule_AddIntConstant(m, "PACKET_OTHERHOST", PACKET_OTHERHOST);
+	PyModule_AddIntConstant(m, "PACKET_OUTGOING", PACKET_OUTGOING);
+	PyModule_AddIntConstant(m, "PACKET_LOOPBACK", PACKET_LOOPBACK);
+	PyModule_AddIntConstant(m, "PACKET_FASTROUTE", PACKET_FASTROUTE);
+#endif
+
+	/* Socket types */
+	PyModule_AddIntConstant(m, "SOCK_STREAM", SOCK_STREAM);
+	PyModule_AddIntConstant(m, "SOCK_DGRAM", SOCK_DGRAM);
+#ifndef __BEOS__
+/* We have incomplete socket support. */
+	PyModule_AddIntConstant(m, "SOCK_RAW", SOCK_RAW);
+	PyModule_AddIntConstant(m, "SOCK_SEQPACKET", SOCK_SEQPACKET);
+#if defined(SOCK_RDM)
+	PyModule_AddIntConstant(m, "SOCK_RDM", SOCK_RDM);
+#endif
+#endif
+
+#ifdef	SO_DEBUG
+	PyModule_AddIntConstant(m, "SO_DEBUG", SO_DEBUG);
+#endif
+#ifdef	SO_ACCEPTCONN
+	PyModule_AddIntConstant(m, "SO_ACCEPTCONN", SO_ACCEPTCONN);
+#endif
+#ifdef	SO_REUSEADDR
+	PyModule_AddIntConstant(m, "SO_REUSEADDR", SO_REUSEADDR);
+#endif
+#ifdef SO_EXCLUSIVEADDRUSE
+	PyModule_AddIntConstant(m, "SO_EXCLUSIVEADDRUSE", SO_EXCLUSIVEADDRUSE);
+#endif
+
+#ifdef	SO_KEEPALIVE
+	PyModule_AddIntConstant(m, "SO_KEEPALIVE", SO_KEEPALIVE);
+#endif
+#ifdef	SO_DONTROUTE
+	PyModule_AddIntConstant(m, "SO_DONTROUTE", SO_DONTROUTE);
+#endif
+#ifdef	SO_BROADCAST
+	PyModule_AddIntConstant(m, "SO_BROADCAST", SO_BROADCAST);
+#endif
+#ifdef	SO_USELOOPBACK
+	PyModule_AddIntConstant(m, "SO_USELOOPBACK", SO_USELOOPBACK);
+#endif
+#ifdef	SO_LINGER
+	PyModule_AddIntConstant(m, "SO_LINGER", SO_LINGER);
+#endif
+#ifdef	SO_OOBINLINE
+	PyModule_AddIntConstant(m, "SO_OOBINLINE", SO_OOBINLINE);
+#endif
+#ifdef	SO_REUSEPORT
+	PyModule_AddIntConstant(m, "SO_REUSEPORT", SO_REUSEPORT);
+#endif
+#ifdef	SO_SNDBUF
+	PyModule_AddIntConstant(m, "SO_SNDBUF", SO_SNDBUF);
+#endif
+#ifdef	SO_RCVBUF
+	PyModule_AddIntConstant(m, "SO_RCVBUF", SO_RCVBUF);
+#endif
+#ifdef	SO_SNDLOWAT
+	PyModule_AddIntConstant(m, "SO_SNDLOWAT", SO_SNDLOWAT);
+#endif
+#ifdef	SO_RCVLOWAT
+	PyModule_AddIntConstant(m, "SO_RCVLOWAT", SO_RCVLOWAT);
+#endif
+#ifdef	SO_SNDTIMEO
+	PyModule_AddIntConstant(m, "SO_SNDTIMEO", SO_SNDTIMEO);
+#endif
+#ifdef	SO_RCVTIMEO
+	PyModule_AddIntConstant(m, "SO_RCVTIMEO", SO_RCVTIMEO);
+#endif
+#ifdef	SO_ERROR
+	PyModule_AddIntConstant(m, "SO_ERROR", SO_ERROR);
+#endif
+#ifdef	SO_TYPE
+	PyModule_AddIntConstant(m, "SO_TYPE", SO_TYPE);
+#endif
+
+	/* Maximum number of connections for "listen" */
+#ifdef	SOMAXCONN
+	PyModule_AddIntConstant(m, "SOMAXCONN", SOMAXCONN);
+#else
+	PyModule_AddIntConstant(m, "SOMAXCONN", 5); /* Common value */
+#endif
+
+	/* Flags for send, recv */
+#ifdef	MSG_OOB
+	PyModule_AddIntConstant(m, "MSG_OOB", MSG_OOB);
+#endif
+#ifdef	MSG_PEEK
+	PyModule_AddIntConstant(m, "MSG_PEEK", MSG_PEEK);
+#endif
+#ifdef	MSG_DONTROUTE
+	PyModule_AddIntConstant(m, "MSG_DONTROUTE", MSG_DONTROUTE);
+#endif
+#ifdef	MSG_DONTWAIT
+	PyModule_AddIntConstant(m, "MSG_DONTWAIT", MSG_DONTWAIT);
+#endif
+#ifdef	MSG_EOR
+	PyModule_AddIntConstant(m, "MSG_EOR", MSG_EOR);
+#endif
+#ifdef	MSG_TRUNC
+	PyModule_AddIntConstant(m, "MSG_TRUNC", MSG_TRUNC);
+#endif
+#ifdef	MSG_CTRUNC
+	PyModule_AddIntConstant(m, "MSG_CTRUNC", MSG_CTRUNC);
+#endif
+#ifdef	MSG_WAITALL
+	PyModule_AddIntConstant(m, "MSG_WAITALL", MSG_WAITALL);
+#endif
+#ifdef	MSG_BTAG
+	PyModule_AddIntConstant(m, "MSG_BTAG", MSG_BTAG);
+#endif
+#ifdef	MSG_ETAG
+	PyModule_AddIntConstant(m, "MSG_ETAG", MSG_ETAG);
+#endif
+
+	/* Protocol level and numbers, usable for [gs]etsockopt */
+#ifdef	SOL_SOCKET
+	PyModule_AddIntConstant(m, "SOL_SOCKET", SOL_SOCKET);
+#endif
+#ifdef	SOL_IP
+	PyModule_AddIntConstant(m, "SOL_IP", SOL_IP);
+#else
+	PyModule_AddIntConstant(m, "SOL_IP", 0);
+#endif
+#ifdef	SOL_IPX
+	PyModule_AddIntConstant(m, "SOL_IPX", SOL_IPX);
+#endif
+#ifdef	SOL_AX25
+	PyModule_AddIntConstant(m, "SOL_AX25", SOL_AX25);
+#endif
+#ifdef	SOL_ATALK
+	PyModule_AddIntConstant(m, "SOL_ATALK", SOL_ATALK);
+#endif
+#ifdef	SOL_NETROM
+	PyModule_AddIntConstant(m, "SOL_NETROM", SOL_NETROM);
+#endif
+#ifdef	SOL_ROSE
+	PyModule_AddIntConstant(m, "SOL_ROSE", SOL_ROSE);
+#endif
+#ifdef	SOL_TCP
+	PyModule_AddIntConstant(m, "SOL_TCP", SOL_TCP);
+#else
+	PyModule_AddIntConstant(m, "SOL_TCP", 6);
+#endif
+#ifdef	SOL_UDP
+	PyModule_AddIntConstant(m, "SOL_UDP", SOL_UDP);
+#else
+	PyModule_AddIntConstant(m, "SOL_UDP", 17);
+#endif
+#ifdef	IPPROTO_IP
+	PyModule_AddIntConstant(m, "IPPROTO_IP", IPPROTO_IP);
+#else
+	PyModule_AddIntConstant(m, "IPPROTO_IP", 0);
+#endif
+#ifdef	IPPROTO_HOPOPTS
+	PyModule_AddIntConstant(m, "IPPROTO_HOPOPTS", IPPROTO_HOPOPTS);
+#endif
+#ifdef	IPPROTO_ICMP
+	PyModule_AddIntConstant(m, "IPPROTO_ICMP", IPPROTO_ICMP);
+#else
+	PyModule_AddIntConstant(m, "IPPROTO_ICMP", 1);
+#endif
+#ifdef	IPPROTO_IGMP
+	PyModule_AddIntConstant(m, "IPPROTO_IGMP", IPPROTO_IGMP);
+#endif
+#ifdef	IPPROTO_GGP
+	PyModule_AddIntConstant(m, "IPPROTO_GGP", IPPROTO_GGP);
+#endif
+#ifdef	IPPROTO_IPV4
+	PyModule_AddIntConstant(m, "IPPROTO_IPV4", IPPROTO_IPV4);
+#endif
+#ifdef	IPPROTO_IPV6
+	PyModule_AddIntConstant(m, "IPPROTO_IPV6", IPPROTO_IPV6);
+#endif
+#ifdef	IPPROTO_IPIP
+	PyModule_AddIntConstant(m, "IPPROTO_IPIP", IPPROTO_IPIP);
+#endif
+#ifdef	IPPROTO_TCP
+	PyModule_AddIntConstant(m, "IPPROTO_TCP", IPPROTO_TCP);
+#else
+	PyModule_AddIntConstant(m, "IPPROTO_TCP", 6);
+#endif
+#ifdef	IPPROTO_EGP
+	PyModule_AddIntConstant(m, "IPPROTO_EGP", IPPROTO_EGP);
+#endif
+#ifdef	IPPROTO_PUP
+	PyModule_AddIntConstant(m, "IPPROTO_PUP", IPPROTO_PUP);
+#endif
+#ifdef	IPPROTO_UDP
+	PyModule_AddIntConstant(m, "IPPROTO_UDP", IPPROTO_UDP);
+#else
+	PyModule_AddIntConstant(m, "IPPROTO_UDP", 17);
+#endif
+#ifdef	IPPROTO_IDP
+	PyModule_AddIntConstant(m, "IPPROTO_IDP", IPPROTO_IDP);
+#endif
+#ifdef	IPPROTO_HELLO
+	PyModule_AddIntConstant(m, "IPPROTO_HELLO", IPPROTO_HELLO);
+#endif
+#ifdef	IPPROTO_ND
+	PyModule_AddIntConstant(m, "IPPROTO_ND", IPPROTO_ND);
+#endif
+#ifdef	IPPROTO_TP
+	PyModule_AddIntConstant(m, "IPPROTO_TP", IPPROTO_TP);
+#endif
+#ifdef	IPPROTO_IPV6
+	PyModule_AddIntConstant(m, "IPPROTO_IPV6", IPPROTO_IPV6);
+#endif
+#ifdef	IPPROTO_ROUTING
+	PyModule_AddIntConstant(m, "IPPROTO_ROUTING", IPPROTO_ROUTING);
+#endif
+#ifdef	IPPROTO_FRAGMENT
+	PyModule_AddIntConstant(m, "IPPROTO_FRAGMENT", IPPROTO_FRAGMENT);
+#endif
+#ifdef	IPPROTO_RSVP
+	PyModule_AddIntConstant(m, "IPPROTO_RSVP", IPPROTO_RSVP);
+#endif
+#ifdef	IPPROTO_GRE
+	PyModule_AddIntConstant(m, "IPPROTO_GRE", IPPROTO_GRE);
+#endif
+#ifdef	IPPROTO_ESP
+	PyModule_AddIntConstant(m, "IPPROTO_ESP", IPPROTO_ESP);
+#endif
+#ifdef	IPPROTO_AH
+	PyModule_AddIntConstant(m, "IPPROTO_AH", IPPROTO_AH);
+#endif
+#ifdef	IPPROTO_MOBILE
+	PyModule_AddIntConstant(m, "IPPROTO_MOBILE", IPPROTO_MOBILE);
+#endif
+#ifdef	IPPROTO_ICMPV6
+	PyModule_AddIntConstant(m, "IPPROTO_ICMPV6", IPPROTO_ICMPV6);
+#endif
+#ifdef	IPPROTO_NONE
+	PyModule_AddIntConstant(m, "IPPROTO_NONE", IPPROTO_NONE);
+#endif
+#ifdef	IPPROTO_DSTOPTS
+	PyModule_AddIntConstant(m, "IPPROTO_DSTOPTS", IPPROTO_DSTOPTS);
+#endif
+#ifdef	IPPROTO_XTP
+	PyModule_AddIntConstant(m, "IPPROTO_XTP", IPPROTO_XTP);
+#endif
+#ifdef	IPPROTO_EON
+	PyModule_AddIntConstant(m, "IPPROTO_EON", IPPROTO_EON);
+#endif
+#ifdef	IPPROTO_PIM
+	PyModule_AddIntConstant(m, "IPPROTO_PIM", IPPROTO_PIM);
+#endif
+#ifdef	IPPROTO_IPCOMP
+	PyModule_AddIntConstant(m, "IPPROTO_IPCOMP", IPPROTO_IPCOMP);
+#endif
+#ifdef	IPPROTO_VRRP
+	PyModule_AddIntConstant(m, "IPPROTO_VRRP", IPPROTO_VRRP);
+#endif
+#ifdef	IPPROTO_BIP
+	PyModule_AddIntConstant(m, "IPPROTO_BIP", IPPROTO_BIP);
+#endif
+/**/
+#ifdef	IPPROTO_RAW
+	PyModule_AddIntConstant(m, "IPPROTO_RAW", IPPROTO_RAW);
+#else
+	PyModule_AddIntConstant(m, "IPPROTO_RAW", 255);
+#endif
+#ifdef	IPPROTO_MAX
+	PyModule_AddIntConstant(m, "IPPROTO_MAX", IPPROTO_MAX);
+#endif
+
+	/* Some port configuration */
+#ifdef	IPPORT_RESERVED
+	PyModule_AddIntConstant(m, "IPPORT_RESERVED", IPPORT_RESERVED);
+#else
+	PyModule_AddIntConstant(m, "IPPORT_RESERVED", 1024);
+#endif
+#ifdef	IPPORT_USERRESERVED
+	PyModule_AddIntConstant(m, "IPPORT_USERRESERVED", IPPORT_USERRESERVED);
+#else
+	PyModule_AddIntConstant(m, "IPPORT_USERRESERVED", 5000);
+#endif
+
+	/* Some reserved IP v.4 addresses */
+#ifdef	INADDR_ANY
+	PyModule_AddIntConstant(m, "INADDR_ANY", INADDR_ANY);
+#else
+	PyModule_AddIntConstant(m, "INADDR_ANY", 0x00000000);
+#endif
+#ifdef	INADDR_BROADCAST
+	PyModule_AddIntConstant(m, "INADDR_BROADCAST", INADDR_BROADCAST);
+#else
+	PyModule_AddIntConstant(m, "INADDR_BROADCAST", 0xffffffff);
+#endif
+#ifdef	INADDR_LOOPBACK
+	PyModule_AddIntConstant(m, "INADDR_LOOPBACK", INADDR_LOOPBACK);
+#else
+	PyModule_AddIntConstant(m, "INADDR_LOOPBACK", 0x7F000001);
+#endif
+#ifdef	INADDR_UNSPEC_GROUP
+	PyModule_AddIntConstant(m, "INADDR_UNSPEC_GROUP", INADDR_UNSPEC_GROUP);
+#else
+	PyModule_AddIntConstant(m, "INADDR_UNSPEC_GROUP", 0xe0000000);
+#endif
+#ifdef	INADDR_ALLHOSTS_GROUP
+	PyModule_AddIntConstant(m, "INADDR_ALLHOSTS_GROUP",
+				INADDR_ALLHOSTS_GROUP);
+#else
+	PyModule_AddIntConstant(m, "INADDR_ALLHOSTS_GROUP", 0xe0000001);
+#endif
+#ifdef	INADDR_MAX_LOCAL_GROUP
+	PyModule_AddIntConstant(m, "INADDR_MAX_LOCAL_GROUP",
+				INADDR_MAX_LOCAL_GROUP);
+#else
+	PyModule_AddIntConstant(m, "INADDR_MAX_LOCAL_GROUP", 0xe00000ff);
+#endif
+#ifdef	INADDR_NONE
+	PyModule_AddIntConstant(m, "INADDR_NONE", INADDR_NONE);
+#else
+	PyModule_AddIntConstant(m, "INADDR_NONE", 0xffffffff);
+#endif
+
+	/* IPv4 [gs]etsockopt options */
+#ifdef	IP_OPTIONS
+	PyModule_AddIntConstant(m, "IP_OPTIONS", IP_OPTIONS);
+#endif
+#ifdef	IP_HDRINCL
+	PyModule_AddIntConstant(m, "IP_HDRINCL", IP_HDRINCL);
+#endif
+#ifdef	IP_TOS
+	PyModule_AddIntConstant(m, "IP_TOS", IP_TOS);
+#endif
+#ifdef	IP_TTL
+	PyModule_AddIntConstant(m, "IP_TTL", IP_TTL);
+#endif
+#ifdef	IP_RECVOPTS
+	PyModule_AddIntConstant(m, "IP_RECVOPTS", IP_RECVOPTS);
+#endif
+#ifdef	IP_RECVRETOPTS
+	PyModule_AddIntConstant(m, "IP_RECVRETOPTS", IP_RECVRETOPTS);
+#endif
+#ifdef	IP_RECVDSTADDR
+	PyModule_AddIntConstant(m, "IP_RECVDSTADDR", IP_RECVDSTADDR);
+#endif
+#ifdef	IP_RETOPTS
+	PyModule_AddIntConstant(m, "IP_RETOPTS", IP_RETOPTS);
+#endif
+#ifdef	IP_MULTICAST_IF
+	PyModule_AddIntConstant(m, "IP_MULTICAST_IF", IP_MULTICAST_IF);
+#endif
+#ifdef	IP_MULTICAST_TTL
+	PyModule_AddIntConstant(m, "IP_MULTICAST_TTL", IP_MULTICAST_TTL);
+#endif
+#ifdef	IP_MULTICAST_LOOP
+	PyModule_AddIntConstant(m, "IP_MULTICAST_LOOP", IP_MULTICAST_LOOP);
+#endif
+#ifdef	IP_ADD_MEMBERSHIP
+	PyModule_AddIntConstant(m, "IP_ADD_MEMBERSHIP", IP_ADD_MEMBERSHIP);
+#endif
+#ifdef	IP_DROP_MEMBERSHIP
+	PyModule_AddIntConstant(m, "IP_DROP_MEMBERSHIP", IP_DROP_MEMBERSHIP);
+#endif
+#ifdef	IP_DEFAULT_MULTICAST_TTL
+	PyModule_AddIntConstant(m, "IP_DEFAULT_MULTICAST_TTL",
+				IP_DEFAULT_MULTICAST_TTL);
+#endif
+#ifdef	IP_DEFAULT_MULTICAST_LOOP
+	PyModule_AddIntConstant(m, "IP_DEFAULT_MULTICAST_LOOP",
+				IP_DEFAULT_MULTICAST_LOOP);
+#endif
+#ifdef	IP_MAX_MEMBERSHIPS
+	PyModule_AddIntConstant(m, "IP_MAX_MEMBERSHIPS", IP_MAX_MEMBERSHIPS);
+#endif
+
+	/* IPv6 [gs]etsockopt options, defined in RFC2553 */
+#ifdef	IPV6_JOIN_GROUP
+	PyModule_AddIntConstant(m, "IPV6_JOIN_GROUP", IPV6_JOIN_GROUP);
+#endif
+#ifdef	IPV6_LEAVE_GROUP
+	PyModule_AddIntConstant(m, "IPV6_LEAVE_GROUP", IPV6_LEAVE_GROUP);
+#endif
+#ifdef	IPV6_MULTICAST_HOPS
+	PyModule_AddIntConstant(m, "IPV6_MULTICAST_HOPS", IPV6_MULTICAST_HOPS);
+#endif
+#ifdef	IPV6_MULTICAST_IF
+	PyModule_AddIntConstant(m, "IPV6_MULTICAST_IF", IPV6_MULTICAST_IF);
+#endif
+#ifdef	IPV6_MULTICAST_LOOP
+	PyModule_AddIntConstant(m, "IPV6_MULTICAST_LOOP", IPV6_MULTICAST_LOOP);
+#endif
+#ifdef	IPV6_UNICAST_HOPS
+	PyModule_AddIntConstant(m, "IPV6_UNICAST_HOPS", IPV6_UNICAST_HOPS);
+#endif
+        /* Additional IPV6 socket options, defined in RFC 3493 */
+#ifdef IPV6_V6ONLY
+	PyModule_AddIntConstant(m, "IPV6_V6ONLY", IPV6_V6ONLY);
+#endif
+	/* Advanced IPV6 socket options, from RFC 3542 */
+#ifdef IPV6_CHECKSUM
+	PyModule_AddIntConstant(m, "IPV6_CHECKSUM", IPV6_CHECKSUM);
+#endif
+#ifdef IPV6_DONTFRAG
+	PyModule_AddIntConstant(m, "IPV6_DONTFRAG", IPV6_DONTFRAG);
+#endif
+#ifdef IPV6_DSTOPTS
+	PyModule_AddIntConstant(m, "IPV6_DSTOPTS", IPV6_DSTOPTS);
+#endif
+#ifdef IPV6_HOPLIMIT
+	PyModule_AddIntConstant(m, "IPV6_HOPLIMIT", IPV6_HOPLIMIT);
+#endif
+#ifdef IPV6_HOPOPTS
+	PyModule_AddIntConstant(m, "IPV6_HOPOPTS", IPV6_HOPOPTS);
+#endif
+#ifdef IPV6_NEXTHOP
+	PyModule_AddIntConstant(m, "IPV6_NEXTHOP", IPV6_NEXTHOP);
+#endif
+#ifdef IPV6_PATHMTU
+	PyModule_AddIntConstant(m, "IPV6_PATHMTU", IPV6_PATHMTU);
+#endif
+#ifdef IPV6_PKTINFO
+	PyModule_AddIntConstant(m, "IPV6_PKTINFO", IPV6_PKTINFO);
+#endif
+#ifdef IPV6_RECVDSTOPTS
+	PyModule_AddIntConstant(m, "IPV6_RECVDSTOPTS", IPV6_RECVDSTOPTS);
+#endif
+#ifdef IPV6_RECVHOPLIMIT
+	PyModule_AddIntConstant(m, "IPV6_RECVHOPLIMIT", IPV6_RECVHOPLIMIT);
+#endif
+#ifdef IPV6_RECVHOPOPTS
+	PyModule_AddIntConstant(m, "IPV6_RECVHOPOPTS", IPV6_RECVHOPOPTS);
+#endif
+#ifdef IPV6_RECVPKTINFO
+	PyModule_AddIntConstant(m, "IPV6_RECVPKTINFO", IPV6_RECVPKTINFO);
+#endif
+#ifdef IPV6_RECVRTHDR
+	PyModule_AddIntConstant(m, "IPV6_RECVRTHDR", IPV6_RECVRTHDR);
+#endif
+#ifdef IPV6_RECVTCLASS
+	PyModule_AddIntConstant(m, "IPV6_RECVTCLASS", IPV6_RECVTCLASS);
+#endif
+#ifdef IPV6_RTHDR
+	PyModule_AddIntConstant(m, "IPV6_RTHDR", IPV6_RTHDR);
+#endif
+#ifdef IPV6_RTHDRDSTOPTS
+	PyModule_AddIntConstant(m, "IPV6_RTHDRDSTOPTS", IPV6_RTHDRDSTOPTS);
+#endif
+#ifdef IPV6_RTHDR_TYPE_0
+	PyModule_AddIntConstant(m, "IPV6_RTHDR_TYPE_0", IPV6_RTHDR_TYPE_0);
+#endif
+#ifdef IPV6_RECVPATHMTU
+	PyModule_AddIntConstant(m, "IPV6_RECVPATHMTU", IPV6_RECVPATHMTU);
+#endif
+#ifdef IPV6_TCLASS
+	PyModule_AddIntConstant(m, "IPV6_TCLASS", IPV6_TCLASS);
+#endif
+#ifdef IPV6_USE_MIN_MTU
+	PyModule_AddIntConstant(m, "IPV6_USE_MIN_MTU", IPV6_USE_MIN_MTU);
+#endif
+
+	/* TCP options */
+#ifdef	TCP_NODELAY
+	PyModule_AddIntConstant(m, "TCP_NODELAY", TCP_NODELAY);
+#endif
+#ifdef	TCP_MAXSEG
+	PyModule_AddIntConstant(m, "TCP_MAXSEG", TCP_MAXSEG);
+#endif
+#ifdef	TCP_CORK
+	PyModule_AddIntConstant(m, "TCP_CORK", TCP_CORK);
+#endif
+#ifdef	TCP_KEEPIDLE
+	PyModule_AddIntConstant(m, "TCP_KEEPIDLE", TCP_KEEPIDLE);
+#endif
+#ifdef	TCP_KEEPINTVL
+	PyModule_AddIntConstant(m, "TCP_KEEPINTVL", TCP_KEEPINTVL);
+#endif
+#ifdef	TCP_KEEPCNT
+	PyModule_AddIntConstant(m, "TCP_KEEPCNT", TCP_KEEPCNT);
+#endif
+#ifdef	TCP_SYNCNT
+	PyModule_AddIntConstant(m, "TCP_SYNCNT", TCP_SYNCNT);
+#endif
+#ifdef	TCP_LINGER2
+	PyModule_AddIntConstant(m, "TCP_LINGER2", TCP_LINGER2);
+#endif
+#ifdef	TCP_DEFER_ACCEPT
+	PyModule_AddIntConstant(m, "TCP_DEFER_ACCEPT", TCP_DEFER_ACCEPT);
+#endif
+#ifdef	TCP_WINDOW_CLAMP
+	PyModule_AddIntConstant(m, "TCP_WINDOW_CLAMP", TCP_WINDOW_CLAMP);
+#endif
+#ifdef	TCP_INFO
+	PyModule_AddIntConstant(m, "TCP_INFO", TCP_INFO);
+#endif
+#ifdef	TCP_QUICKACK
+	PyModule_AddIntConstant(m, "TCP_QUICKACK", TCP_QUICKACK);
+#endif
+
+
+	/* IPX options */
+#ifdef	IPX_TYPE
+	PyModule_AddIntConstant(m, "IPX_TYPE", IPX_TYPE);
+#endif
+
+	/* get{addr,name}info parameters */
+#ifdef EAI_ADDRFAMILY
+	PyModule_AddIntConstant(m, "EAI_ADDRFAMILY", EAI_ADDRFAMILY);
+#endif
+#ifdef EAI_AGAIN
+	PyModule_AddIntConstant(m, "EAI_AGAIN", EAI_AGAIN);
+#endif
+#ifdef EAI_BADFLAGS
+	PyModule_AddIntConstant(m, "EAI_BADFLAGS", EAI_BADFLAGS);
+#endif
+#ifdef EAI_FAIL
+	PyModule_AddIntConstant(m, "EAI_FAIL", EAI_FAIL);
+#endif
+#ifdef EAI_FAMILY
+	PyModule_AddIntConstant(m, "EAI_FAMILY", EAI_FAMILY);
+#endif
+#ifdef EAI_MEMORY
+	PyModule_AddIntConstant(m, "EAI_MEMORY", EAI_MEMORY);
+#endif
+#ifdef EAI_NODATA
+	PyModule_AddIntConstant(m, "EAI_NODATA", EAI_NODATA);
+#endif
+#ifdef EAI_NONAME
+	PyModule_AddIntConstant(m, "EAI_NONAME", EAI_NONAME);
+#endif
+#ifdef EAI_OVERFLOW
+	PyModule_AddIntConstant(m, "EAI_OVERFLOW", EAI_OVERFLOW);
+#endif
+#ifdef EAI_SERVICE
+	PyModule_AddIntConstant(m, "EAI_SERVICE", EAI_SERVICE);
+#endif
+#ifdef EAI_SOCKTYPE
+	PyModule_AddIntConstant(m, "EAI_SOCKTYPE", EAI_SOCKTYPE);
+#endif
+#ifdef EAI_SYSTEM
+	PyModule_AddIntConstant(m, "EAI_SYSTEM", EAI_SYSTEM);
+#endif
+#ifdef EAI_BADHINTS
+	PyModule_AddIntConstant(m, "EAI_BADHINTS", EAI_BADHINTS);
+#endif
+#ifdef EAI_PROTOCOL
+	PyModule_AddIntConstant(m, "EAI_PROTOCOL", EAI_PROTOCOL);
+#endif
+#ifdef EAI_MAX
+	PyModule_AddIntConstant(m, "EAI_MAX", EAI_MAX);
+#endif
+#ifdef AI_PASSIVE
+	PyModule_AddIntConstant(m, "AI_PASSIVE", AI_PASSIVE);
+#endif
+#ifdef AI_CANONNAME
+	PyModule_AddIntConstant(m, "AI_CANONNAME", AI_CANONNAME);
+#endif
+#ifdef AI_NUMERICHOST
+	PyModule_AddIntConstant(m, "AI_NUMERICHOST", AI_NUMERICHOST);
+#endif
+#ifdef AI_NUMERICSERV
+	PyModule_AddIntConstant(m, "AI_NUMERICSERV", AI_NUMERICSERV);
+#endif
+#ifdef AI_MASK
+	PyModule_AddIntConstant(m, "AI_MASK", AI_MASK);
+#endif
+#ifdef AI_ALL
+	PyModule_AddIntConstant(m, "AI_ALL", AI_ALL);
+#endif
+#ifdef AI_V4MAPPED_CFG
+	PyModule_AddIntConstant(m, "AI_V4MAPPED_CFG", AI_V4MAPPED_CFG);
+#endif
+#ifdef AI_ADDRCONFIG
+	PyModule_AddIntConstant(m, "AI_ADDRCONFIG", AI_ADDRCONFIG);
+#endif
+#ifdef AI_V4MAPPED
+	PyModule_AddIntConstant(m, "AI_V4MAPPED", AI_V4MAPPED);
+#endif
+#ifdef AI_DEFAULT
+	PyModule_AddIntConstant(m, "AI_DEFAULT", AI_DEFAULT);
+#endif
+#ifdef NI_MAXHOST
+	PyModule_AddIntConstant(m, "NI_MAXHOST", NI_MAXHOST);
+#endif
+#ifdef NI_MAXSERV
+	PyModule_AddIntConstant(m, "NI_MAXSERV", NI_MAXSERV);
+#endif
+#ifdef NI_NOFQDN
+	PyModule_AddIntConstant(m, "NI_NOFQDN", NI_NOFQDN);
+#endif
+#ifdef NI_NUMERICHOST
+	PyModule_AddIntConstant(m, "NI_NUMERICHOST", NI_NUMERICHOST);
+#endif
+#ifdef NI_NAMEREQD
+	PyModule_AddIntConstant(m, "NI_NAMEREQD", NI_NAMEREQD);
+#endif
+#ifdef NI_NUMERICSERV
+	PyModule_AddIntConstant(m, "NI_NUMERICSERV", NI_NUMERICSERV);
+#endif
+#ifdef NI_DGRAM
+	PyModule_AddIntConstant(m, "NI_DGRAM", NI_DGRAM);
+#endif
+
+	/* shutdown() parameters */
+#ifdef SHUT_RD
+	PyModule_AddIntConstant(m, "SHUT_RD", SHUT_RD);
+#elif defined(SD_RECEIVE)
+	PyModule_AddIntConstant(m, "SHUT_RD", SD_RECEIVE);
+#else
+	PyModule_AddIntConstant(m, "SHUT_RD", 0);
+#endif
+#ifdef SHUT_WR
+	PyModule_AddIntConstant(m, "SHUT_WR", SHUT_WR);
+#elif defined(SD_SEND)
+	PyModule_AddIntConstant(m, "SHUT_WR", SD_SEND);
+#else
+	PyModule_AddIntConstant(m, "SHUT_WR", 1);
+#endif
+#ifdef SHUT_RDWR
+	PyModule_AddIntConstant(m, "SHUT_RDWR", SHUT_RDWR);
+#elif defined(SD_BOTH)
+	PyModule_AddIntConstant(m, "SHUT_RDWR", SD_BOTH);
+#else
+	PyModule_AddIntConstant(m, "SHUT_RDWR", 2);
+#endif
+
+	/* Initialize gethostbyname lock */
+#if defined(USE_GETHOSTBYNAME_LOCK) || defined(USE_GETADDRINFO_LOCK)
+	netdb_lock = PyThread_allocate_lock();
+#endif
+}
+
+
+#ifndef HAVE_INET_PTON
+
+/* Simplistic emulation code for inet_pton that only works for IPv4 */
+/* These are not exposed because they do not set errno properly */
+
+int
+inet_pton(int af, const char *src, void *dst)
+{
+	if (af == AF_INET) {
+		long packed_addr;
+		packed_addr = inet_addr(src);
+		if (packed_addr == INADDR_NONE)
+			return 0;
+		memcpy(dst, &packed_addr, 4);
+		return 1;
+	}
+	/* Should set errno to EAFNOSUPPORT */
+	return -1;
+}
+
+const char *
+inet_ntop(int af, const void *src, char *dst, socklen_t size)
+{
+	if (af == AF_INET) {
+		struct in_addr packed_addr;
+		if (size < 16)
+			/* Should set errno to ENOSPC. */
+			return NULL;
+		memcpy(&packed_addr, src, sizeof(packed_addr));
+		return strncpy(dst, inet_ntoa(packed_addr), size);
+	}
+	/* Should set errno to EAFNOSUPPORT */
+	return NULL;
+}
+
+#endif

Added: vendor/Python/current/Modules/socketmodule.h
===================================================================
--- vendor/Python/current/Modules/socketmodule.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/socketmodule.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,252 @@
+/* Socket module header file */
+
+/* Includes needed for the sockaddr_* symbols below */
+#ifndef MS_WINDOWS
+#ifdef __VMS
+#   include <socket.h>
+# else
+#   include <sys/socket.h>
+# endif
+# include <netinet/in.h>
+# if !(defined(__BEOS__) || defined(__CYGWIN__) || (defined(PYOS_OS2) && defined(PYCC_VACPP)))
+#  include <netinet/tcp.h>
+# endif
+
+#else /* MS_WINDOWS */
+#if _MSC_VER >= 1300
+# include <winsock2.h>
+# include <ws2tcpip.h>
+# define HAVE_ADDRINFO
+# define HAVE_SOCKADDR_STORAGE
+# define HAVE_GETADDRINFO
+# define HAVE_GETNAMEINFO
+# define ENABLE_IPV6
+#else
+# include <winsock.h>
+#endif
+#endif
+
+#ifdef HAVE_SYS_UN_H
+# include <sys/un.h>
+#else
+# undef AF_UNIX
+#endif
+
+#ifdef HAVE_LINUX_NETLINK_H
+# ifdef HAVE_ASM_TYPES_H
+#  include <asm/types.h>
+# endif
+# include <linux/netlink.h>
+#else
+#  undef AF_NETLINK
+#endif
+
+#ifdef HAVE_BLUETOOTH_BLUETOOTH_H
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/rfcomm.h>
+#include <bluetooth/l2cap.h>
+#include <bluetooth/sco.h>
+#endif
+
+#ifdef HAVE_BLUETOOTH_H
+#include <bluetooth.h>
+#endif
+
+#ifdef HAVE_NETPACKET_PACKET_H
+# include <sys/ioctl.h>
+# include <net/if.h>
+# include <netpacket/packet.h>
+#endif
+
+#ifndef Py__SOCKET_H
+#define Py__SOCKET_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Python module and C API name */
+#define PySocket_MODULE_NAME	"_socket"
+#define PySocket_CAPI_NAME	"CAPI"
+
+/* Abstract the socket file descriptor type */
+#ifdef MS_WINDOWS
+typedef SOCKET SOCKET_T;
+#	ifdef MS_WIN64
+#		define SIZEOF_SOCKET_T 8
+#	else
+#		define SIZEOF_SOCKET_T 4
+#	endif
+#else
+typedef int SOCKET_T;
+#	define SIZEOF_SOCKET_T SIZEOF_INT
+#endif
+
+/* Socket address */
+typedef union sock_addr {
+	struct sockaddr_in in;
+#ifdef AF_UNIX
+	struct sockaddr_un un;
+#endif
+#ifdef AF_NETLINK
+	struct sockaddr_nl nl;
+#endif
+#ifdef ENABLE_IPV6
+	struct sockaddr_in6 in6;
+	struct sockaddr_storage storage;
+#endif
+#ifdef HAVE_BLUETOOTH_BLUETOOTH_H
+	struct sockaddr_l2 bt_l2;
+	struct sockaddr_rc bt_rc;
+	struct sockaddr_sco bt_sco;
+#endif
+#ifdef HAVE_NETPACKET_PACKET_H
+	struct sockaddr_ll ll;
+#endif
+} sock_addr_t;
+
+/* The object holding a socket.  It holds some extra information,
+   like the address family, which is used to decode socket address
+   arguments properly. */
+
+typedef struct {
+	PyObject_HEAD
+	SOCKET_T sock_fd;	/* Socket file descriptor */
+	int sock_family;	/* Address family, e.g., AF_INET */
+	int sock_type;		/* Socket type, e.g., SOCK_STREAM */
+	int sock_proto;		/* Protocol type, usually 0 */
+	PyObject *(*errorhandler)(void); /* Error handler; checks
+					    errno, returns NULL and
+					    sets a Python exception */
+	double sock_timeout;		 /* Operation timeout in seconds;
+					    0.0 means non-blocking */
+} PySocketSockObject;
+
+/* --- C API ----------------------------------------------------*/
+
+/* Short explanation of what this C API export mechanism does
+   and how it works:
+
+    The _ssl module needs access to the type object defined in 
+    the _socket module. Since cross-DLL linking introduces a lot of
+    problems on many platforms, the "trick" is to wrap the
+    C API of a module in a struct which then gets exported to
+    other modules via a PyCObject.
+
+    The code in socketmodule.c defines this struct (which currently
+    only contains the type object reference, but could very
+    well also include other C APIs needed by other modules)
+    and exports it as PyCObject via the module dictionary
+    under the name "CAPI".
+
+    Other modules can now include the socketmodule.h file
+    which defines the needed C APIs to import and set up
+    a static copy of this struct in the importing module.
+
+    After initialization, the importing module can then
+    access the C APIs from the _socket module by simply
+    referring to the static struct, e.g.
+
+    Load _socket module and its C API; this sets up the global
+    PySocketModule:
+    
+	if (PySocketModule_ImportModuleAndAPI())
+	    return;
+
+
+    Now use the C API as if it were defined in the using
+    module:
+
+        if (!PyArg_ParseTuple(args, "O!|zz:ssl",
+
+			      PySocketModule.Sock_Type,
+
+			      (PyObject*)&Sock,
+			      &key_file, &cert_file))
+	    return NULL;
+
+    Support could easily be extended to export more C APIs/symbols
+    this way. Currently, only the type object is exported, 
+    other candidates would be socket constructors and socket
+    access functions.
+
+*/
+
+/* C API for usage by other Python modules */
+typedef struct {
+	PyTypeObject *Sock_Type;
+        PyObject *error;
+} PySocketModule_APIObject;
+
+/* XXX The net effect of the following appears to be to define a function
+   XXX named PySocketModule_APIObject in _ssl.c.  It's unclear why it isn't
+   XXX defined there directly. 
+
+   >>> It's defined here because other modules might also want to use
+   >>> the C API.
+
+*/
+#ifndef PySocket_BUILDING_SOCKET
+
+/* --- C API ----------------------------------------------------*/
+
+/* Interfacestructure to C API for other modules.
+   Call PySocketModule_ImportModuleAndAPI() to initialize this
+   structure. After that usage is simple:
+
+   if (!PyArg_ParseTuple(args, "O!|zz:ssl",
+                         &PySocketModule.Sock_Type, (PyObject*)&Sock,
+	 		 &key_file, &cert_file))
+ 	 return NULL;
+   ...
+*/
+
+static
+PySocketModule_APIObject PySocketModule;
+
+/* You *must* call this before using any of the functions in
+   PySocketModule and check its outcome; otherwise all accesses will
+   result in a segfault. Returns 0 on success. */
+
+#ifndef DPRINTF
+# define DPRINTF if (0) printf
+#endif
+
+static
+int PySocketModule_ImportModuleAndAPI(void)
+{
+	PyObject *mod = 0, *v = 0;
+	char *apimodule = PySocket_MODULE_NAME;
+	char *apiname = PySocket_CAPI_NAME;
+	void *api;
+
+	DPRINTF("Importing the %s C API...\n", apimodule);
+	mod = PyImport_ImportModule(apimodule);
+	if (mod == NULL)
+		goto onError;
+	DPRINTF(" %s package found\n", apimodule);
+	v = PyObject_GetAttrString(mod, apiname);
+	if (v == NULL)
+		goto onError;
+	Py_DECREF(mod);
+	DPRINTF(" API object %s found\n", apiname);
+	api = PyCObject_AsVoidPtr(v);
+	if (api == NULL)
+		goto onError;
+	Py_DECREF(v);
+	memcpy(&PySocketModule, api, sizeof(PySocketModule));
+	DPRINTF(" API object loaded and initialized.\n");
+	return 0;
+
+ onError:
+	DPRINTF(" not found.\n");
+	Py_XDECREF(mod);
+	Py_XDECREF(v);
+	return -1;
+}
+
+#endif /* !PySocket_BUILDING_SOCKET */
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py__SOCKET_H */

Added: vendor/Python/current/Modules/spwdmodule.c
===================================================================
--- vendor/Python/current/Modules/spwdmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/spwdmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,183 @@
+
+/* UNIX shadow password file access module */
+/* A lot of code has been taken from pwdmodule.c */
+/* For info also see http://www.unixpapa.com/incnote/passwd.html */
+
+#include "Python.h"
+#include "structseq.h"
+
+#include <sys/types.h>
+#ifdef HAVE_SHADOW_H
+#include <shadow.h>
+#endif
+
+
+PyDoc_STRVAR(spwd__doc__,
+"This module provides access to the Unix shadow password database.\n\
+It is available on various Unix versions.\n\
+\n\
+Shadow password database entries are reported as 9-tuples of type struct_spwd,\n\
+containing the following items from the password database (see `<shadow.h>'):\n\
+sp_namp, sp_pwdp, sp_lstchg, sp_min, sp_max, sp_warn, sp_inact, sp_expire, sp_flag.\n\
+The sp_namp and sp_pwdp are strings, the rest are integers.\n\
+An exception is raised if the entry asked for cannot be found.\n\
+You have to be root to be able to use this module.");
+
+
+#if defined(HAVE_GETSPNAM) || defined(HAVE_GETSPENT)
+
+static PyStructSequence_Field struct_spwd_type_fields[] = {
+	{"sp_nam", "login name"},
+	{"sp_pwd", "encrypted password"},
+	{"sp_lstchg", "date of last change"},
+	{"sp_min", "min #days between changes"}, 
+	{"sp_max", "max #days between changes"}, 
+	{"sp_warn", "#days before pw expires to warn user about it"}, 
+	{"sp_inact", "#days after pw expires until account is blocked"},
+	{"sp_expire", "#days since 1970-01-01 until account is disabled"},
+	{"sp_flag", "reserved"},
+	{0}
+};
+
+PyDoc_STRVAR(struct_spwd__doc__,
+"spwd.struct_spwd: Results from getsp*() routines.\n\n\
+This object may be accessed either as a 9-tuple of\n\
+  (sp_nam,sp_pwd,sp_lstchg,sp_min,sp_max,sp_warn,sp_inact,sp_expire,sp_flag)\n\
+or via the object attributes as named in the above tuple.");
+
+static PyStructSequence_Desc struct_spwd_type_desc = {
+	"spwd.struct_spwd",
+	struct_spwd__doc__,
+	struct_spwd_type_fields,
+	9,
+};
+
+static int initialized;
+static PyTypeObject StructSpwdType;
+
+
+static void
+sets(PyObject *v, int i, char* val)
+{
+  if (val)
+	  PyStructSequence_SET_ITEM(v, i, PyString_FromString(val));
+  else {
+	  PyStructSequence_SET_ITEM(v, i, Py_None);
+	  Py_INCREF(Py_None);
+  }
+}
+
+static PyObject *mkspent(struct spwd *p)
+{
+	int setIndex = 0;
+	PyObject *v = PyStructSequence_New(&StructSpwdType);
+	if (v == NULL)
+		return NULL;
+
+#define SETI(i,val) PyStructSequence_SET_ITEM(v, i, PyInt_FromLong((long) val))
+#define SETS(i,val) sets(v, i, val)
+
+	SETS(setIndex++, p->sp_namp);
+	SETS(setIndex++, p->sp_pwdp);
+	SETI(setIndex++, p->sp_lstchg);
+	SETI(setIndex++, p->sp_min);
+	SETI(setIndex++, p->sp_max);
+	SETI(setIndex++, p->sp_warn);
+	SETI(setIndex++, p->sp_inact);
+	SETI(setIndex++, p->sp_expire);
+	SETI(setIndex++, p->sp_flag);
+
+#undef SETS
+#undef SETI
+
+	if (PyErr_Occurred()) {
+		Py_DECREF(v);
+		return NULL;
+	}
+
+	return v;
+}
+
+#endif  /* HAVE_GETSPNAM || HAVE_GETSPENT */
+
+
+#ifdef HAVE_GETSPNAM
+
+PyDoc_STRVAR(spwd_getspnam__doc__,
+"getspnam(name) -> (sp_namp, sp_pwdp, sp_lstchg, sp_min, sp_max,\n\
+                    sp_warn, sp_inact, sp_expire, sp_flag)\n\
+Return the shadow password database entry for the given user name.\n\
+See spwd.__doc__ for more on shadow password database entries.");
+
+static PyObject* spwd_getspnam(PyObject *self, PyObject *args)
+{
+	char *name;
+	struct spwd *p;
+	if (!PyArg_ParseTuple(args, "s:getspnam", &name))
+		return NULL;
+	if ((p = getspnam(name)) == NULL) {
+		PyErr_SetString(PyExc_KeyError, "getspnam(): name not found");
+		return NULL;
+	}
+	return mkspent(p);
+}
+
+#endif /* HAVE_GETSPNAM */
+
+#ifdef HAVE_GETSPENT
+
+PyDoc_STRVAR(spwd_getspall__doc__,
+"getspall() -> list_of_entries\n\
+Return a list of all available shadow password database entries, \
+in arbitrary order.\n\
+See spwd.__doc__ for more on shadow password database entries.");
+
+static PyObject *
+spwd_getspall(PyObject *self, PyObject *args)
+{
+	PyObject *d;
+	struct spwd *p;
+	if ((d = PyList_New(0)) == NULL)
+		return NULL;
+	setspent();
+	while ((p = getspent()) != NULL) {
+		PyObject *v = mkspent(p);
+		if (v == NULL || PyList_Append(d, v) != 0) {
+			Py_XDECREF(v);
+			Py_DECREF(d);
+			endspent();
+			return NULL;
+		}
+		Py_DECREF(v);
+	}
+	endspent();
+	return d;
+}
+
+#endif /* HAVE_GETSPENT */
+
+static PyMethodDef spwd_methods[] = {
+#ifdef HAVE_GETSPNAM	
+	{"getspnam",	spwd_getspnam, METH_VARARGS, spwd_getspnam__doc__},
+#endif
+#ifdef HAVE_GETSPENT
+	{"getspall",	spwd_getspall, METH_NOARGS, spwd_getspall__doc__},
+#endif
+	{NULL,		NULL}		/* sentinel */
+};
+
+
+PyMODINIT_FUNC
+initspwd(void)
+{
+	PyObject *m;
+	m=Py_InitModule3("spwd", spwd_methods, spwd__doc__);
+	if (m == NULL)
+		return;
+	if (!initialized)
+		PyStructSequence_InitType(&StructSpwdType, 
+					  &struct_spwd_type_desc);
+	Py_INCREF((PyObject *) &StructSpwdType);
+	PyModule_AddObject(m, "struct_spwd", (PyObject *) &StructSpwdType);
+	initialized = 1;
+}

Added: vendor/Python/current/Modules/sre.h
===================================================================
--- vendor/Python/current/Modules/sre.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/sre.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,94 @@
+/*
+ * Secret Labs' Regular Expression Engine
+ *
+ * regular expression matching engine
+ *
+ * Copyright (c) 1997-2001 by Secret Labs AB.  All rights reserved.
+ *
+ * See the _sre.c file for information on usage and redistribution.
+ */
+
+#ifndef SRE_INCLUDED
+#define SRE_INCLUDED
+
+#include "sre_constants.h"
+
+/* size of a code word (must be unsigned short or larger, and
+   large enough to hold a Py_UNICODE character) */
+#ifdef Py_UNICODE_WIDE
+#define SRE_CODE Py_UCS4
+#else
+#define SRE_CODE unsigned short
+#endif
+
+typedef struct {
+    PyObject_VAR_HEAD
+    Py_ssize_t groups; /* must be first! */
+    PyObject* groupindex;
+    PyObject* indexgroup;
+    /* compatibility */
+    PyObject* pattern; /* pattern source (or None) */
+    int flags; /* flags used when compiling pattern source */
+    PyObject *weakreflist; /* List of weak references */
+    /* pattern code */
+    Py_ssize_t codesize;
+    SRE_CODE code[1];
+} PatternObject;
+
+#define PatternObject_GetCode(o) (((PatternObject*)(o))->code)
+
+typedef struct {
+    PyObject_VAR_HEAD
+    PyObject* string; /* link to the target string (must be first) */
+    PyObject* regs; /* cached list of matching spans */
+    PatternObject* pattern; /* link to the regex (pattern) object */
+    Py_ssize_t pos, endpos; /* current target slice */
+    Py_ssize_t lastindex; /* last index marker seen by the engine (-1 if none) */
+    Py_ssize_t groups; /* number of groups (start/end marks) */
+    Py_ssize_t mark[1];
+} MatchObject;
+
+typedef unsigned int (*SRE_TOLOWER_HOOK)(unsigned int ch);
+
+/* FIXME: <fl> shouldn't be a constant, really... */
+#define SRE_MARK_SIZE 200
+
+typedef struct SRE_REPEAT_T {
+    Py_ssize_t count;
+    SRE_CODE* pattern; /* points to REPEAT operator arguments */
+    void* last_ptr; /* helper to check for infinite loops */
+    struct SRE_REPEAT_T *prev; /* points to previous repeat context */
+} SRE_REPEAT;
+
+typedef struct {
+    /* string pointers */
+    void* ptr; /* current position (also end of current slice) */
+    void* beginning; /* start of original string */
+    void* start; /* start of current slice */
+    void* end; /* end of original string */
+    /* attributes for the match object */
+    PyObject* string;
+    Py_ssize_t pos, endpos;
+    /* character size */
+    int charsize;
+    /* registers */
+    Py_ssize_t lastindex;
+    Py_ssize_t lastmark;
+    void* mark[SRE_MARK_SIZE];
+    /* dynamically allocated stuff */
+    char* data_stack;
+    size_t data_stack_size;
+    size_t data_stack_base;
+    /* current repeat context */
+    SRE_REPEAT *repeat;
+    /* hooks */
+    SRE_TOLOWER_HOOK lower;
+} SRE_STATE;
+
+typedef struct {
+    PyObject_HEAD
+    PyObject* pattern;
+    SRE_STATE state;
+} ScannerObject;
+
+#endif

Added: vendor/Python/current/Modules/sre_constants.h
===================================================================
--- vendor/Python/current/Modules/sre_constants.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/sre_constants.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,86 @@
+/*
+ * Secret Labs' Regular Expression Engine
+ *
+ * regular expression matching engine
+ *
+ * NOTE: This file is generated by sre_constants.py.  If you need
+ * to change anything in here, edit sre_constants.py and run it.
+ *
+ * Copyright (c) 1997-2001 by Secret Labs AB.  All rights reserved.
+ *
+ * See the _sre.c file for information on usage and redistribution.
+ */
+
+#define SRE_MAGIC 20031017
+#define SRE_OP_FAILURE 0
+#define SRE_OP_SUCCESS 1
+#define SRE_OP_ANY 2
+#define SRE_OP_ANY_ALL 3
+#define SRE_OP_ASSERT 4
+#define SRE_OP_ASSERT_NOT 5
+#define SRE_OP_AT 6
+#define SRE_OP_BRANCH 7
+#define SRE_OP_CALL 8
+#define SRE_OP_CATEGORY 9
+#define SRE_OP_CHARSET 10
+#define SRE_OP_BIGCHARSET 11
+#define SRE_OP_GROUPREF 12
+#define SRE_OP_GROUPREF_EXISTS 13
+#define SRE_OP_GROUPREF_IGNORE 14
+#define SRE_OP_IN 15
+#define SRE_OP_IN_IGNORE 16
+#define SRE_OP_INFO 17
+#define SRE_OP_JUMP 18
+#define SRE_OP_LITERAL 19
+#define SRE_OP_LITERAL_IGNORE 20
+#define SRE_OP_MARK 21
+#define SRE_OP_MAX_UNTIL 22
+#define SRE_OP_MIN_UNTIL 23
+#define SRE_OP_NOT_LITERAL 24
+#define SRE_OP_NOT_LITERAL_IGNORE 25
+#define SRE_OP_NEGATE 26
+#define SRE_OP_RANGE 27
+#define SRE_OP_REPEAT 28
+#define SRE_OP_REPEAT_ONE 29
+#define SRE_OP_SUBPATTERN 30
+#define SRE_OP_MIN_REPEAT_ONE 31
+#define SRE_AT_BEGINNING 0
+#define SRE_AT_BEGINNING_LINE 1
+#define SRE_AT_BEGINNING_STRING 2
+#define SRE_AT_BOUNDARY 3
+#define SRE_AT_NON_BOUNDARY 4
+#define SRE_AT_END 5
+#define SRE_AT_END_LINE 6
+#define SRE_AT_END_STRING 7
+#define SRE_AT_LOC_BOUNDARY 8
+#define SRE_AT_LOC_NON_BOUNDARY 9
+#define SRE_AT_UNI_BOUNDARY 10
+#define SRE_AT_UNI_NON_BOUNDARY 11
+#define SRE_CATEGORY_DIGIT 0
+#define SRE_CATEGORY_NOT_DIGIT 1
+#define SRE_CATEGORY_SPACE 2
+#define SRE_CATEGORY_NOT_SPACE 3
+#define SRE_CATEGORY_WORD 4
+#define SRE_CATEGORY_NOT_WORD 5
+#define SRE_CATEGORY_LINEBREAK 6
+#define SRE_CATEGORY_NOT_LINEBREAK 7
+#define SRE_CATEGORY_LOC_WORD 8
+#define SRE_CATEGORY_LOC_NOT_WORD 9
+#define SRE_CATEGORY_UNI_DIGIT 10
+#define SRE_CATEGORY_UNI_NOT_DIGIT 11
+#define SRE_CATEGORY_UNI_SPACE 12
+#define SRE_CATEGORY_UNI_NOT_SPACE 13
+#define SRE_CATEGORY_UNI_WORD 14
+#define SRE_CATEGORY_UNI_NOT_WORD 15
+#define SRE_CATEGORY_UNI_LINEBREAK 16
+#define SRE_CATEGORY_UNI_NOT_LINEBREAK 17
+#define SRE_FLAG_TEMPLATE 1
+#define SRE_FLAG_IGNORECASE 2
+#define SRE_FLAG_LOCALE 4
+#define SRE_FLAG_MULTILINE 8
+#define SRE_FLAG_DOTALL 16
+#define SRE_FLAG_UNICODE 32
+#define SRE_FLAG_VERBOSE 64
+#define SRE_INFO_PREFIX 1
+#define SRE_INFO_LITERAL 2
+#define SRE_INFO_CHARSET 4

Added: vendor/Python/current/Modules/stropmodule.c
===================================================================
--- vendor/Python/current/Modules/stropmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/stropmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1248 @@
+/* strop module */
+
+#define PY_SSIZE_T_CLEAN
+#include "Python.h"
+#include <ctype.h>
+
+PyDoc_STRVAR(strop_module__doc__,
+"Common string manipulations, optimized for speed.\n"
+"\n"
+"Always use \"import string\" rather than referencing\n"
+"this module directly.");
+
+/* XXX This file assumes that the <ctype.h> is*() functions
+   XXX are defined for all 8-bit characters! */
+
+#define WARN if (PyErr_Warn(PyExc_DeprecationWarning, \
+		       "strop functions are obsolete; use string methods")) \
+	     return NULL
+
+/* The lstrip(), rstrip() and strip() functions are implemented
+   in do_strip(), which uses an additional parameter to indicate what
+   type of strip should occur. */
+
+#define LEFTSTRIP 0
+#define RIGHTSTRIP 1
+#define BOTHSTRIP 2
+
+
+static PyObject *
+split_whitespace(char *s, Py_ssize_t len, Py_ssize_t maxsplit)
+{
+	Py_ssize_t i = 0, j;
+	int err;
+	Py_ssize_t countsplit = 0;
+	PyObject* item;
+	PyObject *list = PyList_New(0);
+
+	if (list == NULL)
+		return NULL;
+
+	while (i < len) {
+		while (i < len && isspace(Py_CHARMASK(s[i]))) {
+			i = i+1;
+		}
+		j = i;
+		while (i < len && !isspace(Py_CHARMASK(s[i]))) {
+			i = i+1;
+		}
+		if (j < i) {
+			item = PyString_FromStringAndSize(s+j, i-j);
+			if (item == NULL)
+				goto finally;
+
+			err = PyList_Append(list, item);
+			Py_DECREF(item);
+			if (err < 0)
+				goto finally;
+
+			countsplit++;
+			while (i < len && isspace(Py_CHARMASK(s[i]))) {
+				i = i+1;
+			}
+			if (maxsplit && (countsplit >= maxsplit) && i < len) {
+				item = PyString_FromStringAndSize(
+                                        s+i, len - i);
+				if (item == NULL)
+					goto finally;
+
+				err = PyList_Append(list, item);
+				Py_DECREF(item);
+				if (err < 0)
+					goto finally;
+
+				i = len;
+			}
+		}
+	}
+	return list;
+  finally:
+	Py_DECREF(list);
+	return NULL;
+}
+
+
+PyDoc_STRVAR(splitfields__doc__,
+"split(s [,sep [,maxsplit]]) -> list of strings\n"
+"splitfields(s [,sep [,maxsplit]]) -> list of strings\n"
+"\n"
+"Return a list of the words in the string s, using sep as the\n"
+"delimiter string.  If maxsplit is nonzero, splits into at most\n"
+"maxsplit words.  If sep is not specified, any whitespace string\n"
+"is a separator.  Maxsplit defaults to 0.\n"
+"\n"
+"(split and splitfields are synonymous)");
+
+static PyObject *
+strop_splitfields(PyObject *self, PyObject *args)
+{
+	Py_ssize_t len, n, i, j, err;
+	Py_ssize_t splitcount, maxsplit;
+	char *s, *sub;
+	PyObject *list, *item;
+
+	WARN;
+	sub = NULL;
+	n = 0;
+	splitcount = 0;
+	maxsplit = 0;
+	if (!PyArg_ParseTuple(args, "t#|z#n:split", &s, &len, &sub, &n, &maxsplit))
+		return NULL;
+	if (sub == NULL)
+		return split_whitespace(s, len, maxsplit);
+	if (n == 0) {
+		PyErr_SetString(PyExc_ValueError, "empty separator");
+		return NULL;
+	}
+
+	list = PyList_New(0);
+	if (list == NULL)
+		return NULL;
+
+	i = j = 0;
+	while (i+n <= len) {
+		if (s[i] == sub[0] && (n == 1 || memcmp(s+i, sub, n) == 0)) {
+			item = PyString_FromStringAndSize(s+j, i-j);
+			if (item == NULL)
+				goto fail;
+			err = PyList_Append(list, item);
+			Py_DECREF(item);
+			if (err < 0)
+				goto fail;
+			i = j = i + n;
+			splitcount++;
+			if (maxsplit && (splitcount >= maxsplit))
+				break;
+		}
+		else
+			i++;
+	}
+	item = PyString_FromStringAndSize(s+j, len-j);
+	if (item == NULL)
+		goto fail;
+	err = PyList_Append(list, item);
+	Py_DECREF(item);
+	if (err < 0)
+		goto fail;
+
+	return list;
+
+ fail:
+	Py_DECREF(list);
+	return NULL;
+}
+
+
+PyDoc_STRVAR(joinfields__doc__,
+"join(list [,sep]) -> string\n"
+"joinfields(list [,sep]) -> string\n"
+"\n"
+"Return a string composed of the words in list, with\n"
+"intervening occurrences of sep.  Sep defaults to a single\n"
+"space.\n"
+"\n"
+"(join and joinfields are synonymous)");
+
+static PyObject *
+strop_joinfields(PyObject *self, PyObject *args)
+{
+	PyObject *seq;
+	char *sep = NULL;
+	Py_ssize_t seqlen, seplen = 0;
+	Py_ssize_t i, reslen = 0, slen = 0, sz = 100;
+	PyObject *res = NULL;
+	char* p = NULL;
+	ssizeargfunc getitemfunc;
+
+	WARN;
+	if (!PyArg_ParseTuple(args, "O|t#:join", &seq, &sep, &seplen))
+		return NULL;
+	if (sep == NULL) {
+		sep = " ";
+		seplen = 1;
+	}
+
+	seqlen = PySequence_Size(seq);
+	if (seqlen < 0 && PyErr_Occurred())
+		return NULL;
+
+	if (seqlen == 1) {
+		/* Optimization if there's only one item */
+		PyObject *item = PySequence_GetItem(seq, 0);
+		if (item && !PyString_Check(item)) {
+			PyErr_SetString(PyExc_TypeError,
+				 "first argument must be sequence of strings");
+			Py_DECREF(item);
+			return NULL;
+		}
+		return item;
+	}
+
+	if (!(res = PyString_FromStringAndSize((char*)NULL, sz)))
+		return NULL;
+	p = PyString_AsString(res);
+
+	/* optimize for lists, since it's the most common case.  all others
+	 * (tuples and arbitrary sequences) just use the sequence abstract
+	 * interface.
+	 */
+	if (PyList_Check(seq)) {
+		for (i = 0; i < seqlen; i++) {
+			PyObject *item = PyList_GET_ITEM(seq, i);
+			if (!PyString_Check(item)) {
+				PyErr_SetString(PyExc_TypeError,
+				"first argument must be sequence of strings");
+				Py_DECREF(res);
+				return NULL;
+			}
+			slen = PyString_GET_SIZE(item);
+			while (reslen + slen + seplen >= sz) {
+				if (_PyString_Resize(&res, sz * 2) < 0)
+					return NULL;
+				sz *= 2;
+				p = PyString_AsString(res) + reslen;
+			}
+			if (i > 0) {
+				memcpy(p, sep, seplen);
+				p += seplen;
+				reslen += seplen;
+			}
+			memcpy(p, PyString_AS_STRING(item), slen);
+			p += slen;
+			reslen += slen;
+		}
+		_PyString_Resize(&res, reslen);
+		return res;
+	}
+
+	if (seq->ob_type->tp_as_sequence == NULL ||
+		 (getitemfunc = seq->ob_type->tp_as_sequence->sq_item) == NULL)
+	{
+		PyErr_SetString(PyExc_TypeError,
+				"first argument must be a sequence");
+		return NULL;
+	}
+	/* This is now type safe */
+	for (i = 0; i < seqlen; i++) {
+		PyObject *item = getitemfunc(seq, i);
+		if (!item || !PyString_Check(item)) {
+			PyErr_SetString(PyExc_TypeError,
+				 "first argument must be sequence of strings");
+			Py_DECREF(res);
+			Py_XDECREF(item);
+			return NULL;
+		}
+		slen = PyString_GET_SIZE(item);
+		while (reslen + slen + seplen >= sz) {
+			if (_PyString_Resize(&res, sz * 2) < 0) {
+				Py_DECREF(item);
+				return NULL;
+			}
+			sz *= 2;
+			p = PyString_AsString(res) + reslen;
+		}
+		if (i > 0) {
+			memcpy(p, sep, seplen);
+			p += seplen;
+			reslen += seplen;
+		}
+		memcpy(p, PyString_AS_STRING(item), slen);
+		p += slen;
+		reslen += slen;
+		Py_DECREF(item);
+	}
+	_PyString_Resize(&res, reslen);
+	return res;
+}
+
+
+PyDoc_STRVAR(find__doc__,
+"find(s, sub [,start [,end]]) -> in\n"
+"\n"
+"Return the lowest index in s where substring sub is found,\n"
+"such that sub is contained within s[start,end].  Optional\n"
+"arguments start and end are interpreted as in slice notation.\n"
+"\n"
+"Return -1 on failure.");
+
+static PyObject *
+strop_find(PyObject *self, PyObject *args)
+{
+	char *s, *sub;
+	Py_ssize_t len, n, i = 0, last = PY_SSIZE_T_MAX;
+
+	WARN;
+	if (!PyArg_ParseTuple(args, "t#t#|nn:find", &s, &len, &sub, &n, &i, &last))
+		return NULL;
+
+	if (last > len)
+		last = len;
+	if (last < 0)
+		last += len;
+	if (last < 0)
+		last = 0;
+	if (i < 0)
+		i += len;
+	if (i < 0)
+		i = 0;
+
+	if (n == 0 && i <= last)
+		return PyInt_FromLong((long)i);
+
+	last -= n;
+	for (; i <= last; ++i)
+		if (s[i] == sub[0] &&
+		    (n == 1 || memcmp(&s[i+1], &sub[1], n-1) == 0))
+			return PyInt_FromLong((long)i);
+
+	return PyInt_FromLong(-1L);
+}
+
+
+PyDoc_STRVAR(rfind__doc__,
+"rfind(s, sub [,start [,end]]) -> int\n"
+"\n"
+"Return the highest index in s where substring sub is found,\n"
+"such that sub is contained within s[start,end].  Optional\n"
+"arguments start and end are interpreted as in slice notation.\n"
+"\n"
+"Return -1 on failure.");
+
+static PyObject *
+strop_rfind(PyObject *self, PyObject *args)
+{
+	char *s, *sub;
+	Py_ssize_t len, n, j;
+	Py_ssize_t i = 0, last = PY_SSIZE_T_MAX;
+
+	WARN;
+	if (!PyArg_ParseTuple(args, "t#t#|nn:rfind", &s, &len, &sub, &n, &i, &last))
+		return NULL;
+
+	if (last > len)
+		last = len;
+	if (last < 0)
+		last += len;
+	if (last < 0)
+		last = 0;
+	if (i < 0)
+		i += len;
+	if (i < 0)
+		i = 0;
+
+	if (n == 0 && i <= last)
+		return PyInt_FromLong((long)last);
+
+	for (j = last-n; j >= i; --j)
+		if (s[j] == sub[0] &&
+		    (n == 1 || memcmp(&s[j+1], &sub[1], n-1) == 0))
+			return PyInt_FromLong((long)j);
+
+	return PyInt_FromLong(-1L);
+}
+
+
+static PyObject *
+do_strip(PyObject *args, int striptype)
+{
+	char *s;
+	Py_ssize_t len, i, j;
+
+
+	if (PyString_AsStringAndSize(args, &s, &len))
+		return NULL;
+
+	i = 0;
+	if (striptype != RIGHTSTRIP) {
+		while (i < len && isspace(Py_CHARMASK(s[i]))) {
+			i++;
+		}
+	}
+
+	j = len;
+	if (striptype != LEFTSTRIP) {
+		do {
+			j--;
+		} while (j >= i && isspace(Py_CHARMASK(s[j])));
+		j++;
+	}
+
+	if (i == 0 && j == len) {
+		Py_INCREF(args);
+		return args;
+	}
+	else
+		return PyString_FromStringAndSize(s+i, j-i);
+}
+
+
+PyDoc_STRVAR(strip__doc__,
+"strip(s) -> string\n"
+"\n"
+"Return a copy of the string s with leading and trailing\n"
+"whitespace removed.");
+
+static PyObject *
+strop_strip(PyObject *self, PyObject *args)
+{
+	WARN;
+	return do_strip(args, BOTHSTRIP);
+}
+
+
+PyDoc_STRVAR(lstrip__doc__,
+"lstrip(s) -> string\n"
+"\n"
+"Return a copy of the string s with leading whitespace removed.");
+
+static PyObject *
+strop_lstrip(PyObject *self, PyObject *args)
+{
+	WARN;
+	return do_strip(args, LEFTSTRIP);
+}
+
+
+PyDoc_STRVAR(rstrip__doc__,
+"rstrip(s) -> string\n"
+"\n"
+"Return a copy of the string s with trailing whitespace removed.");
+
+static PyObject *
+strop_rstrip(PyObject *self, PyObject *args)
+{
+	WARN;
+	return do_strip(args, RIGHTSTRIP);
+}
+
+
+PyDoc_STRVAR(lower__doc__,
+"lower(s) -> string\n"
+"\n"
+"Return a copy of the string s converted to lowercase.");
+
+static PyObject *
+strop_lower(PyObject *self, PyObject *args)
+{
+	char *s, *s_new;
+	Py_ssize_t i, n;
+	PyObject *newstr;
+	int changed;
+
+	WARN;
+	if (PyString_AsStringAndSize(args, &s, &n))
+		return NULL;
+	newstr = PyString_FromStringAndSize(NULL, n);
+	if (newstr == NULL)
+		return NULL;
+	s_new = PyString_AsString(newstr);
+	changed = 0;
+	for (i = 0; i < n; i++) {
+		int c = Py_CHARMASK(*s++);
+		if (isupper(c)) {
+			changed = 1;
+			*s_new = tolower(c);
+		} else
+			*s_new = c;
+		s_new++;
+	}
+	if (!changed) {
+		Py_DECREF(newstr);
+		Py_INCREF(args);
+		return args;
+	}
+	return newstr;
+}
+
+
+PyDoc_STRVAR(upper__doc__,
+"upper(s) -> string\n"
+"\n"
+"Return a copy of the string s converted to uppercase.");
+
+static PyObject *
+strop_upper(PyObject *self, PyObject *args)
+{
+	char *s, *s_new;
+	Py_ssize_t i, n;
+	PyObject *newstr;
+	int changed;
+
+	WARN;
+	if (PyString_AsStringAndSize(args, &s, &n))
+		return NULL;
+	newstr = PyString_FromStringAndSize(NULL, n);
+	if (newstr == NULL)
+		return NULL;
+	s_new = PyString_AsString(newstr);
+	changed = 0;
+	for (i = 0; i < n; i++) {
+		int c = Py_CHARMASK(*s++);
+		if (islower(c)) {
+			changed = 1;
+			*s_new = toupper(c);
+		} else
+			*s_new = c;
+		s_new++;
+	}
+	if (!changed) {
+		Py_DECREF(newstr);
+		Py_INCREF(args);
+		return args;
+	}
+	return newstr;
+}
+
+
+PyDoc_STRVAR(capitalize__doc__,
+"capitalize(s) -> string\n"
+"\n"
+"Return a copy of the string s with only its first character\n"
+"capitalized.");
+
+static PyObject *
+strop_capitalize(PyObject *self, PyObject *args)
+{
+	char *s, *s_new;
+	Py_ssize_t i, n;
+	PyObject *newstr;
+	int changed;
+
+	WARN;
+	if (PyString_AsStringAndSize(args, &s, &n))
+		return NULL;
+	newstr = PyString_FromStringAndSize(NULL, n);
+	if (newstr == NULL)
+		return NULL;
+	s_new = PyString_AsString(newstr);
+	changed = 0;
+	if (0 < n) {
+		int c = Py_CHARMASK(*s++);
+		if (islower(c)) {
+			changed = 1;
+			*s_new = toupper(c);
+		} else
+			*s_new = c;
+		s_new++;
+	}
+	for (i = 1; i < n; i++) {
+		int c = Py_CHARMASK(*s++);
+		if (isupper(c)) {
+			changed = 1;
+			*s_new = tolower(c);
+		} else
+			*s_new = c;
+		s_new++;
+	}
+	if (!changed) {
+		Py_DECREF(newstr);
+		Py_INCREF(args);
+		return args;
+	}
+	return newstr;
+}
+
+
+PyDoc_STRVAR(expandtabs__doc__,
+"expandtabs(string, [tabsize]) -> string\n"
+"\n"
+"Expand tabs in a string, i.e. replace them by one or more spaces,\n"
+"depending on the current column and the given tab size (default 8).\n"
+"The column number is reset to zero after each newline occurring in the\n"
+"string.  This doesn't understand other non-printing characters.");
+
+static PyObject *
+strop_expandtabs(PyObject *self, PyObject *args)
+{
+	/* Original by Fredrik Lundh */
+	char* e;
+	char* p;
+	char* q;
+	Py_ssize_t i, j;
+	PyObject* out;
+	char* string;
+	Py_ssize_t stringlen;
+	int tabsize = 8;
+
+	WARN;
+	/* Get arguments */
+	if (!PyArg_ParseTuple(args, "s#|i:expandtabs", &string, &stringlen, &tabsize))
+		return NULL;
+	if (tabsize < 1) {
+		PyErr_SetString(PyExc_ValueError,
+				"tabsize must be at least 1");
+		return NULL;
+	}
+
+	/* First pass: determine size of output string */
+	i = j = 0; /* j: current column; i: total of previous lines */
+	e = string + stringlen;
+	for (p = string; p < e; p++) {
+		if (*p == '\t')
+			j += tabsize - (j%tabsize);
+		else {
+			j++;
+			if (*p == '\n') {
+				i += j;
+				j = 0;
+			}
+		}
+	}
+
+	/* Second pass: create output string and fill it */
+	out = PyString_FromStringAndSize(NULL, i+j);
+	if (out == NULL)
+		return NULL;
+
+	i = 0;
+	q = PyString_AS_STRING(out);
+
+	for (p = string; p < e; p++) {
+		if (*p == '\t') {
+			j = tabsize - (i%tabsize);
+			i += j;
+			while (j-- > 0)
+				*q++ = ' ';
+		} else {
+			*q++ = *p;
+			i++;
+			if (*p == '\n')
+				i = 0;
+		}
+	}
+
+	return out;
+}
+
+
+PyDoc_STRVAR(count__doc__,
+"count(s, sub[, start[, end]]) -> int\n"
+"\n"
+"Return the number of occurrences of substring sub in string\n"
+"s[start:end].  Optional arguments start and end are\n"
+"interpreted as in slice notation.");
+
+static PyObject *
+strop_count(PyObject *self, PyObject *args)
+{
+	char *s, *sub;
+	Py_ssize_t len, n;
+	Py_ssize_t i = 0, last = PY_SSIZE_T_MAX;
+	Py_ssize_t m, r;
+
+	WARN;
+	if (!PyArg_ParseTuple(args, "t#t#|nn:count", &s, &len, &sub, &n, &i, &last))
+		return NULL;
+	if (last > len)
+		last = len;
+	if (last < 0)
+		last += len;
+	if (last < 0)
+		last = 0;
+	if (i < 0)
+		i += len;
+	if (i < 0)
+		i = 0;
+	m = last + 1 - n;
+	if (n == 0)
+		return PyInt_FromLong((long) (m-i));
+
+	r = 0;
+	while (i < m) {
+		if (!memcmp(s+i, sub, n)) {
+			r++;
+			i += n;
+		} else {
+			i++;
+		}
+	}
+	return PyInt_FromLong((long) r);
+}
+
+
+PyDoc_STRVAR(swapcase__doc__,
+"swapcase(s) -> string\n"
+"\n"
+"Return a copy of the string s with upper case characters\n"
+"converted to lowercase and vice versa.");
+
+static PyObject *
+strop_swapcase(PyObject *self, PyObject *args)
+{
+	char *s, *s_new;
+	Py_ssize_t i, n;
+	PyObject *newstr;
+	int changed;
+
+	WARN;
+	if (PyString_AsStringAndSize(args, &s, &n))
+		return NULL;
+	newstr = PyString_FromStringAndSize(NULL, n);
+	if (newstr == NULL)
+		return NULL;
+	s_new = PyString_AsString(newstr);
+	changed = 0;
+	for (i = 0; i < n; i++) {
+		int c = Py_CHARMASK(*s++);
+		if (islower(c)) {
+			changed = 1;
+			*s_new = toupper(c);
+		}
+		else if (isupper(c)) {
+			changed = 1;
+			*s_new = tolower(c);
+		}
+		else
+			*s_new = c;
+		s_new++;
+	}
+	if (!changed) {
+		Py_DECREF(newstr);
+		Py_INCREF(args);
+		return args;
+	}
+	return newstr;
+}
+
+
+PyDoc_STRVAR(atoi__doc__,
+"atoi(s [,base]) -> int\n"
+"\n"
+"Return the integer represented by the string s in the given\n"
+"base, which defaults to 10.  The string s must consist of one\n"
+"or more digits, possibly preceded by a sign.  If base is 0, it\n"
+"is chosen from the leading characters of s, 0 for octal, 0x or\n"
+"0X for hexadecimal.  If base is 16, a preceding 0x or 0X is\n"
+"accepted.");
+
+static PyObject *
+strop_atoi(PyObject *self, PyObject *args)
+{
+	char *s, *end;
+	int base = 10;
+	long x;
+	char buffer[256]; /* For errors */
+
+	WARN;
+	if (!PyArg_ParseTuple(args, "s|i:atoi", &s, &base))
+		return NULL;
+
+	if ((base != 0 && base < 2) || base > 36) {
+		PyErr_SetString(PyExc_ValueError, "invalid base for atoi()");
+		return NULL;
+	}
+
+	while (*s && isspace(Py_CHARMASK(*s)))
+		s++;
+	errno = 0;
+	if (base == 0 && s[0] == '0')
+		x = (long) PyOS_strtoul(s, &end, base);
+	else
+		x = PyOS_strtol(s, &end, base);
+	if (end == s || !isalnum(Py_CHARMASK(end[-1])))
+		goto bad;
+	while (*end && isspace(Py_CHARMASK(*end)))
+		end++;
+	if (*end != '\0') {
+  bad:
+		PyOS_snprintf(buffer, sizeof(buffer),
+			      "invalid literal for atoi(): %.200s", s);
+		PyErr_SetString(PyExc_ValueError, buffer);
+		return NULL;
+	}
+	else if (errno != 0) {
+		PyOS_snprintf(buffer, sizeof(buffer), 
+			      "atoi() literal too large: %.200s", s);
+		PyErr_SetString(PyExc_ValueError, buffer);
+		return NULL;
+	}
+	return PyInt_FromLong(x);
+}
+
+
+PyDoc_STRVAR(atol__doc__,
+"atol(s [,base]) -> long\n"
+"\n"
+"Return the long integer represented by the string s in the\n"
+"given base, which defaults to 10.  The string s must consist\n"
+"of one or more digits, possibly preceded by a sign.  If base\n"
+"is 0, it is chosen from the leading characters of s, 0 for\n"
+"octal, 0x or 0X for hexadecimal.  If base is 16, a preceding\n"
+"0x or 0X is accepted.  A trailing L or l is not accepted,\n"
+"unless base is 0.");
+
+static PyObject *
+strop_atol(PyObject *self, PyObject *args)
+{
+	char *s, *end;
+	int base = 10;
+	PyObject *x;
+	char buffer[256]; /* For errors */
+
+	WARN;
+	if (!PyArg_ParseTuple(args, "s|i:atol", &s, &base))
+		return NULL;
+
+	if ((base != 0 && base < 2) || base > 36) {
+		PyErr_SetString(PyExc_ValueError, "invalid base for atol()");
+		return NULL;
+	}
+
+	while (*s && isspace(Py_CHARMASK(*s)))
+		s++;
+	if (s[0] == '\0') {
+		PyErr_SetString(PyExc_ValueError, "empty string for atol()");
+		return NULL;
+	}
+	x = PyLong_FromString(s, &end, base);
+	if (x == NULL)
+		return NULL;
+	if (base == 0 && (*end == 'l' || *end == 'L'))
+		end++;
+	while (*end && isspace(Py_CHARMASK(*end)))
+		end++;
+	if (*end != '\0') {
+		PyOS_snprintf(buffer, sizeof(buffer),
+			      "invalid literal for atol(): %.200s", s);
+		PyErr_SetString(PyExc_ValueError, buffer);
+		Py_DECREF(x);
+		return NULL;
+	}
+	return x;
+}
+
+
+PyDoc_STRVAR(atof__doc__,
+"atof(s) -> float\n"
+"\n"
+"Return the floating point number represented by the string s.");
+
+static PyObject *
+strop_atof(PyObject *self, PyObject *args)
+{
+	char *s, *end;
+	double x;
+	char buffer[256]; /* For errors */
+
+	WARN;
+	if (!PyArg_ParseTuple(args, "s:atof", &s))
+		return NULL;
+	while (*s && isspace(Py_CHARMASK(*s)))
+		s++;
+	if (s[0] == '\0') {
+		PyErr_SetString(PyExc_ValueError, "empty string for atof()");
+		return NULL;
+	}
+	errno = 0;
+	PyFPE_START_PROTECT("strop_atof", return 0)
+	x = PyOS_ascii_strtod(s, &end);
+	PyFPE_END_PROTECT(x)
+	while (*end && isspace(Py_CHARMASK(*end)))
+		end++;
+	if (*end != '\0') {
+		PyOS_snprintf(buffer, sizeof(buffer),
+			      "invalid literal for atof(): %.200s", s);
+		PyErr_SetString(PyExc_ValueError, buffer);
+		return NULL;
+	}
+	else if (errno != 0) {
+		PyOS_snprintf(buffer, sizeof(buffer), 
+			      "atof() literal too large: %.200s", s);
+		PyErr_SetString(PyExc_ValueError, buffer);
+		return NULL;
+	}
+	return PyFloat_FromDouble(x);
+}
+
+
+PyDoc_STRVAR(maketrans__doc__,
+"maketrans(frm, to) -> string\n"
+"\n"
+"Return a translation table (a string of 256 bytes long)\n"
+"suitable for use in string.translate.  The strings frm and to\n"
+"must be of the same length.");
+
+static PyObject *
+strop_maketrans(PyObject *self, PyObject *args)
+{
+	unsigned char *c, *from=NULL, *to=NULL;
+	Py_ssize_t i, fromlen=0, tolen=0;
+	PyObject *result;
+
+	if (!PyArg_ParseTuple(args, "t#t#:maketrans", &from, &fromlen, &to, &tolen))
+		return NULL;
+
+	if (fromlen != tolen) {
+		PyErr_SetString(PyExc_ValueError,
+				"maketrans arguments must have same length");
+		return NULL;
+	}
+
+	result = PyString_FromStringAndSize((char *)NULL, 256);
+	if (result == NULL)
+		return NULL;
+	c = (unsigned char *) PyString_AS_STRING((PyStringObject *)result);
+	for (i = 0; i < 256; i++)
+		c[i]=(unsigned char)i;
+	for (i = 0; i < fromlen; i++)
+		c[from[i]]=to[i];
+
+	return result;
+}
+
+
+PyDoc_STRVAR(translate__doc__,
+"translate(s,table [,deletechars]) -> string\n"
+"\n"
+"Return a copy of the string s, where all characters occurring\n"
+"in the optional argument deletechars are removed, and the\n"
+"remaining characters have been mapped through the given\n"
+"translation table, which must be a string of length 256.");
+
+static PyObject *
+strop_translate(PyObject *self, PyObject *args)
+{
+	register char *input, *table, *output;
+	Py_ssize_t i; 
+	int c, changed = 0;
+	PyObject *input_obj;
+	char *table1, *output_start, *del_table=NULL;
+	Py_ssize_t inlen, tablen, dellen = 0;
+	PyObject *result;
+	int trans_table[256];
+
+	WARN;
+	if (!PyArg_ParseTuple(args, "St#|t#:translate", &input_obj,
+			      &table1, &tablen, &del_table, &dellen))
+		return NULL;
+	if (tablen != 256) {
+		PyErr_SetString(PyExc_ValueError,
+			      "translation table must be 256 characters long");
+		return NULL;
+	}
+
+	table = table1;
+	inlen = PyString_GET_SIZE(input_obj);
+	result = PyString_FromStringAndSize((char *)NULL, inlen);
+	if (result == NULL)
+		return NULL;
+	output_start = output = PyString_AsString(result);
+	input = PyString_AsString(input_obj);
+
+	if (dellen == 0) {
+		/* If no deletions are required, use faster code */
+		for (i = inlen; --i >= 0; ) {
+			c = Py_CHARMASK(*input++);
+			if (Py_CHARMASK((*output++ = table[c])) != c)
+				changed = 1;
+		}
+		if (changed)
+			return result;
+		Py_DECREF(result);
+		Py_INCREF(input_obj);
+		return input_obj;
+	}
+
+	for (i = 0; i < 256; i++)
+		trans_table[i] = Py_CHARMASK(table[i]);
+
+	for (i = 0; i < dellen; i++)
+		trans_table[(int) Py_CHARMASK(del_table[i])] = -1;
+
+	for (i = inlen; --i >= 0; ) {
+		c = Py_CHARMASK(*input++);
+		if (trans_table[c] != -1)
+			if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c)
+				continue;
+		changed = 1;
+	}
+	if (!changed) {
+		Py_DECREF(result);
+		Py_INCREF(input_obj);
+		return input_obj;
+	}
+	/* Fix the size of the resulting string */
+	if (inlen > 0)
+		_PyString_Resize(&result, output - output_start);
+	return result;
+}
+
+
+/* What follows is used for implementing replace().  Perry Stoll. */
+
+/*
+  mymemfind
+
+  strstr replacement for arbitrary blocks of memory.
+
+  Locates the first occurrence in the memory pointed to by MEM of the
+  contents of memory pointed to by PAT.  Returns the index into MEM if
+  found, or -1 if not found.  If len of PAT is greater than length of
+  MEM, the function returns -1.
+*/
+static Py_ssize_t 
+mymemfind(const char *mem, Py_ssize_t len, const char *pat, Py_ssize_t pat_len)
+{
+	register Py_ssize_t ii;
+
+	/* pattern can not occur in the last pat_len-1 chars */
+	len -= pat_len;
+
+	for (ii = 0; ii <= len; ii++) {
+		if (mem[ii] == pat[0] &&
+		    (pat_len == 1 ||
+		     memcmp(&mem[ii+1], &pat[1], pat_len-1) == 0)) {
+			return ii;
+		}
+	}
+	return -1;
+}
+
+/*
+  mymemcnt
+
+   Return the number of distinct times PAT is found in MEM.
+   meaning mem=1111 and pat==11 returns 2.
+           mem=11111 and pat==11 also return 2.
+ */
+static Py_ssize_t 
+mymemcnt(const char *mem, Py_ssize_t len, const char *pat, Py_ssize_t pat_len)
+{
+	register Py_ssize_t offset = 0;
+	Py_ssize_t nfound = 0;
+
+	while (len >= 0) {
+		offset = mymemfind(mem, len, pat, pat_len);
+		if (offset == -1)
+			break;
+		mem += offset + pat_len;
+		len -= offset + pat_len;
+		nfound++;
+	}
+	return nfound;
+}
+
+/*
+   mymemreplace
+
+   Return a string in which all occurrences of PAT in memory STR are
+   replaced with SUB.
+
+   If length of PAT is less than length of STR or there are no occurrences
+   of PAT in STR, then the original string is returned. Otherwise, a new
+   string is allocated here and returned.
+
+   on return, out_len is:
+       the length of output string, or
+       -1 if the input string is returned, or
+       unchanged if an error occurs (no memory).
+
+   return value is:
+       the new string allocated locally, or
+       NULL if an error occurred.
+*/
+static char *
+mymemreplace(const char *str, Py_ssize_t len,		/* input string */
+             const char *pat, Py_ssize_t pat_len,	/* pattern string to find */
+             const char *sub, Py_ssize_t sub_len,	/* substitution string */
+             Py_ssize_t count,				/* number of replacements */
+	     Py_ssize_t *out_len)
+{
+	char *out_s;
+	char *new_s;
+	Py_ssize_t nfound, offset, new_len;
+
+	if (len == 0 || pat_len > len)
+		goto return_same;
+
+	/* find length of output string */
+	nfound = mymemcnt(str, len, pat, pat_len);
+	if (count < 0)
+		count = PY_SSIZE_T_MAX;
+	else if (nfound > count)
+		nfound = count;
+	if (nfound == 0)
+		goto return_same;
+
+	new_len = len + nfound*(sub_len - pat_len);
+	if (new_len == 0) {
+		/* Have to allocate something for the caller to free(). */
+		out_s = (char *)PyMem_MALLOC(1);
+		if (out_s == NULL)
+			return NULL;
+		out_s[0] = '\0';
+	}
+	else {
+		assert(new_len > 0);
+		new_s = (char *)PyMem_MALLOC(new_len);
+		if (new_s == NULL)
+			return NULL;
+		out_s = new_s;
+
+		for (; count > 0 && len > 0; --count) {
+			/* find index of next instance of pattern */
+			offset = mymemfind(str, len, pat, pat_len);
+			if (offset == -1)
+				break;
+
+			/* copy non matching part of input string */
+			memcpy(new_s, str, offset);
+			str += offset + pat_len;
+			len -= offset + pat_len;
+
+			/* copy substitute into the output string */
+			new_s += offset;
+			memcpy(new_s, sub, sub_len);
+			new_s += sub_len;
+		}
+		/* copy any remaining values into output string */
+		if (len > 0)
+			memcpy(new_s, str, len);
+	}
+	*out_len = new_len;
+	return out_s;
+
+  return_same:
+	*out_len = -1;
+	return (char *)str; /* cast away const */
+}
+
+
+PyDoc_STRVAR(replace__doc__,
+"replace (str, old, new[, maxsplit]) -> string\n"
+"\n"
+"Return a copy of string str with all occurrences of substring\n"
+"old replaced by new. If the optional argument maxsplit is\n"
+"given, only the first maxsplit occurrences are replaced.");
+
+static PyObject *
+strop_replace(PyObject *self, PyObject *args)
+{
+	char *str, *pat,*sub,*new_s;
+	Py_ssize_t len,pat_len,sub_len,out_len;
+	Py_ssize_t count = -1;
+	PyObject *newstr;
+
+	WARN;
+	if (!PyArg_ParseTuple(args, "t#t#t#|n:replace",
+			      &str, &len, &pat, &pat_len, &sub, &sub_len,
+			      &count))
+		return NULL;
+	if (pat_len <= 0) {
+		PyErr_SetString(PyExc_ValueError, "empty pattern string");
+		return NULL;
+	}
+	/* CAUTION:  strop treats a replace count of 0 as infinity, unlke
+	 * current (2.1) string.py and string methods.  Preserve this for
+	 * ... well, hard to say for what <wink>.
+	 */
+	if (count == 0)
+		count = -1;
+	new_s = mymemreplace(str,len,pat,pat_len,sub,sub_len,count,&out_len);
+	if (new_s == NULL) {
+		PyErr_NoMemory();
+		return NULL;
+	}
+	if (out_len == -1) {
+		/* we're returning another reference to the input string */
+		newstr = PyTuple_GetItem(args, 0);
+		Py_XINCREF(newstr);
+	}
+	else {
+		newstr = PyString_FromStringAndSize(new_s, out_len);
+		PyMem_FREE(new_s);
+	}
+	return newstr;
+}
+
+
+/* List of functions defined in the module */
+
+static PyMethodDef
+strop_methods[] = {
+	{"atof",	strop_atof,	   METH_VARARGS, atof__doc__},
+	{"atoi",	strop_atoi,	   METH_VARARGS, atoi__doc__},
+	{"atol",	strop_atol,	   METH_VARARGS, atol__doc__},
+	{"capitalize",	strop_capitalize,  METH_O,       capitalize__doc__},
+	{"count",	strop_count,	   METH_VARARGS, count__doc__},
+	{"expandtabs",	strop_expandtabs,  METH_VARARGS, expandtabs__doc__},
+	{"find",	strop_find,	   METH_VARARGS, find__doc__},
+	{"join",	strop_joinfields,  METH_VARARGS, joinfields__doc__},
+	{"joinfields",	strop_joinfields,  METH_VARARGS, joinfields__doc__},
+	{"lstrip",	strop_lstrip,	   METH_O,       lstrip__doc__},
+	{"lower",	strop_lower,	   METH_O,       lower__doc__},
+	{"maketrans",	strop_maketrans,   METH_VARARGS, maketrans__doc__},
+	{"replace",	strop_replace,	   METH_VARARGS, replace__doc__},
+	{"rfind",	strop_rfind,	   METH_VARARGS, rfind__doc__},
+	{"rstrip",	strop_rstrip,	   METH_O,       rstrip__doc__},
+	{"split",	strop_splitfields, METH_VARARGS, splitfields__doc__},
+	{"splitfields",	strop_splitfields, METH_VARARGS, splitfields__doc__},
+	{"strip",	strop_strip,	   METH_O,       strip__doc__},
+	{"swapcase",	strop_swapcase,    METH_O,       swapcase__doc__},
+	{"translate",	strop_translate,   METH_VARARGS, translate__doc__},
+	{"upper",	strop_upper,	   METH_O,       upper__doc__},
+	{NULL,		NULL}	/* sentinel */
+};
+
+
+PyMODINIT_FUNC
+initstrop(void)
+{
+	PyObject *m, *s;
+	char buf[256];
+	int c, n;
+	m = Py_InitModule4("strop", strop_methods, strop_module__doc__,
+			   (PyObject*)NULL, PYTHON_API_VERSION);
+	if (m == NULL)
+		return;
+
+	/* Create 'whitespace' object */
+	n = 0;
+	for (c = 0; c < 256; c++) {
+		if (isspace(c))
+			buf[n++] = c;
+	}
+	s = PyString_FromStringAndSize(buf, n);
+	if (s)
+		PyModule_AddObject(m, "whitespace", s);
+
+	/* Create 'lowercase' object */
+	n = 0;
+	for (c = 0; c < 256; c++) {
+		if (islower(c))
+			buf[n++] = c;
+	}
+	s = PyString_FromStringAndSize(buf, n);
+	if (s)
+		PyModule_AddObject(m, "lowercase", s);
+
+	/* Create 'uppercase' object */
+	n = 0;
+	for (c = 0; c < 256; c++) {
+		if (isupper(c))
+			buf[n++] = c;
+	}
+	s = PyString_FromStringAndSize(buf, n);
+	if (s)
+		PyModule_AddObject(m, "uppercase", s);
+}

Added: vendor/Python/current/Modules/sunaudiodev.c
===================================================================
--- vendor/Python/current/Modules/sunaudiodev.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/sunaudiodev.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,465 @@
+
+/* Sad objects */
+
+#include "Python.h"
+#include "structmember.h"
+
+#ifdef HAVE_SYS_AUDIOIO_H
+#define SOLARIS
+#endif
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#include <stropts.h>
+#include <sys/ioctl.h>
+#ifdef SOLARIS
+#include <sys/audioio.h>
+#else
+#include <sun/audioio.h>
+#endif
+
+/* #define offsetof(str,mem) ((int)(((str *)0)->mem)) */
+
+typedef struct {
+	PyObject_HEAD
+	int	x_fd;		/* The open file */
+	int	x_icount;	/* # samples read */
+	int	x_ocount;	/* # samples written */
+	int	x_isctl;	/* True if control device */
+	
+} sadobject;
+
+typedef struct {
+	PyObject_HEAD
+	audio_info_t ai;
+} sadstatusobject;
+
+static PyTypeObject Sadtype;
+static PyTypeObject Sadstatustype;
+static sadstatusobject *sads_alloc(void);	/* Forward */
+
+static PyObject *SunAudioError;
+
+#define is_sadobject(v)		((v)->ob_type == &Sadtype)
+#define is_sadstatusobject(v)	((v)->ob_type == &Sadstatustype)
+
+
+static sadobject *
+newsadobject(PyObject *args)
+{
+	sadobject *xp;
+	int fd;
+	char *mode;
+	int imode;
+	char* basedev;
+	char* ctldev;
+	char* opendev;
+
+	/* Check arg for r/w/rw */
+	if (!PyArg_ParseTuple(args, "s", &mode))
+		return NULL;
+	if (strcmp(mode, "r") == 0)
+		imode = 0;
+	else if (strcmp(mode, "w") == 0)
+		imode = 1;
+	else if (strcmp(mode, "rw") == 0)
+		imode = 2;
+	else if (strcmp(mode, "control") == 0)
+		imode = -1;
+	else {
+		PyErr_SetString(SunAudioError,
+			  "Mode should be one of 'r', 'w', 'rw' or 'control'");
+		return NULL;
+	}
+	
+	/* Open the correct device.  The base device name comes from the
+	 * AUDIODEV environment variable first, then /dev/audio.  The
+	 * control device tacks "ctl" onto the base device name.
+	 */
+	basedev = getenv("AUDIODEV");
+	if (!basedev)
+		basedev = "/dev/audio";
+	ctldev = PyMem_NEW(char, strlen(basedev) + 4);
+	if (!ctldev) {
+		PyErr_NoMemory();
+		return NULL;
+	}
+	strcpy(ctldev, basedev);
+	strcat(ctldev, "ctl");
+
+	if (imode < 0) {
+		opendev = ctldev;
+		fd = open(ctldev, 2);
+	}
+	else {
+		opendev = basedev;
+		fd = open(basedev, imode);
+	}
+	if (fd < 0) {
+		PyErr_SetFromErrnoWithFilename(SunAudioError, opendev);
+		PyMem_DEL(ctldev);
+		return NULL;
+	}
+	PyMem_DEL(ctldev);
+
+	/* Create and initialize the object */
+	xp = PyObject_New(sadobject, &Sadtype);
+	if (xp == NULL) {
+		close(fd);
+		return NULL;
+	}
+	xp->x_fd = fd;
+	xp->x_icount = xp->x_ocount = 0;
+	xp->x_isctl = (imode < 0);
+	
+	return xp;
+}
+
+/* Sad methods */
+
+static void
+sad_dealloc(sadobject *xp)
+{
+        close(xp->x_fd);
+	PyObject_Del(xp);
+}
+
+static PyObject *
+sad_read(sadobject *self, PyObject *args)
+{
+        int size, count;
+	char *cp;
+	PyObject *rv;
+	
+        if (!PyArg_ParseTuple(args, "i:read", &size))
+		return NULL;
+	rv = PyString_FromStringAndSize(NULL, size);
+	if (rv == NULL)
+		return NULL;
+
+	if (!(cp = PyString_AsString(rv)))
+		goto finally;
+
+	count = read(self->x_fd, cp, size);
+	if (count < 0) {
+		PyErr_SetFromErrno(SunAudioError);
+		goto finally;
+	}
+#if 0
+	/* TBD: why print this message if you can handle the condition?
+	 * assume it's debugging info which we can just as well get rid
+	 * of.  in any case this message should *not* be using printf!
+	 */
+	if (count != size)
+		printf("sunaudio: funny read rv %d wtd %d\n", count, size);
+#endif
+	self->x_icount += count;
+	return rv;
+
+  finally:
+	Py_DECREF(rv);
+	return NULL;
+}
+
+static PyObject *
+sad_write(sadobject *self, PyObject *args)
+{
+        char *cp;
+	int count, size;
+	
+        if (!PyArg_ParseTuple(args, "s#:write", &cp, &size))
+		return NULL;
+
+	count = write(self->x_fd, cp, size);
+	if (count < 0) {
+		PyErr_SetFromErrno(SunAudioError);
+		return NULL;
+	}
+#if 0
+	if (count != size)
+		printf("sunaudio: funny write rv %d wanted %d\n", count, size);
+#endif
+	self->x_ocount += count;
+	
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+sad_getinfo(sadobject *self)
+{
+	sadstatusobject *rv;
+
+	if (!(rv = sads_alloc()))
+		return NULL;
+
+	if (ioctl(self->x_fd, AUDIO_GETINFO, &rv->ai) < 0) {
+		PyErr_SetFromErrno(SunAudioError);
+		Py_DECREF(rv);
+		return NULL;
+	}
+	return (PyObject *)rv;
+}
+
+static PyObject *
+sad_setinfo(sadobject *self, sadstatusobject *arg)
+{
+	if (!is_sadstatusobject(arg)) {
+		PyErr_SetString(PyExc_TypeError,
+				"Must be sun audio status object");
+		return NULL;
+	}
+	if (ioctl(self->x_fd, AUDIO_SETINFO, &arg->ai) < 0) {
+		PyErr_SetFromErrno(SunAudioError);
+		return NULL;
+	}
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+sad_ibufcount(sadobject *self)
+{
+	audio_info_t ai;
+    
+	if (ioctl(self->x_fd, AUDIO_GETINFO, &ai) < 0) {
+		PyErr_SetFromErrno(SunAudioError);
+		return NULL;
+	}
+	return PyInt_FromLong(ai.record.samples - self->x_icount);
+}
+
+static PyObject *
+sad_obufcount(sadobject *self)
+{
+	audio_info_t ai;
+    
+	if (ioctl(self->x_fd, AUDIO_GETINFO, &ai) < 0) {
+		PyErr_SetFromErrno(SunAudioError);
+		return NULL;
+	}
+	/* x_ocount is in bytes, whereas play.samples is in frames */
+	/* we want frames */
+	return PyInt_FromLong(self->x_ocount / (ai.play.channels *
+						ai.play.precision / 8) -
+			      ai.play.samples);
+}
+
+static PyObject *
+sad_drain(sadobject *self)
+{
+	if (ioctl(self->x_fd, AUDIO_DRAIN, 0) < 0) {
+		PyErr_SetFromErrno(SunAudioError);
+		return NULL;
+	}
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+#ifdef SOLARIS
+static PyObject *
+sad_getdev(sadobject *self)
+{
+	struct audio_device ad;
+
+	if (ioctl(self->x_fd, AUDIO_GETDEV, &ad) < 0) {
+		PyErr_SetFromErrno(SunAudioError);
+		return NULL;
+	}
+	return Py_BuildValue("(sss)", ad.name, ad.version, ad.config);
+}
+#endif
+
+static PyObject *
+sad_flush(sadobject *self)
+{
+	if (ioctl(self->x_fd, I_FLUSH, FLUSHW) < 0) {
+		PyErr_SetFromErrno(SunAudioError);
+		return NULL;
+	}
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+sad_close(sadobject *self)
+{
+    
+	if (self->x_fd >= 0) {
+		close(self->x_fd);
+		self->x_fd = -1;
+	}
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+sad_fileno(sadobject *self)
+{
+	return PyInt_FromLong(self->x_fd);
+}
+
+
+static PyMethodDef sad_methods[] = {
+        { "read",	(PyCFunction)sad_read, METH_VARARGS },
+        { "write",	(PyCFunction)sad_write, METH_VARARGS },
+        { "ibufcount",	(PyCFunction)sad_ibufcount, METH_NOARGS },
+        { "obufcount",	(PyCFunction)sad_obufcount, METH_NOARGS },
+#define CTL_METHODS 4
+        { "getinfo",	(PyCFunction)sad_getinfo, METH_NOARGS },
+        { "setinfo",	(PyCFunction)sad_setinfo, METH_O},
+        { "drain",	(PyCFunction)sad_drain, METH_NOARGS },
+        { "flush",	(PyCFunction)sad_flush, METH_NOARGS },
+#ifdef SOLARIS
+	{ "getdev",	(PyCFunction)sad_getdev, METH_NOARGS },
+#endif
+        { "close",	(PyCFunction)sad_close, METH_NOARGS },
+	{ "fileno",     (PyCFunction)sad_fileno, METH_NOARGS },
+	{NULL,		NULL}		/* sentinel */
+};
+
+static PyObject *
+sad_getattr(sadobject *xp, char *name)
+{
+	if (xp->x_isctl)
+		return Py_FindMethod(sad_methods+CTL_METHODS,
+				     (PyObject *)xp, name);
+	else
+		return Py_FindMethod(sad_methods, (PyObject *)xp, name);
+}
+
+/* ----------------------------------------------------------------- */
+
+static sadstatusobject *
+sads_alloc(void) {
+	return PyObject_New(sadstatusobject, &Sadstatustype);
+}
+
+static void
+sads_dealloc(sadstatusobject *xp)
+{
+	PyMem_DEL(xp);
+}
+
+#define OFF(x) offsetof(audio_info_t,x)
+static struct memberlist sads_ml[] = {
+	{ "i_sample_rate",	T_UINT,		OFF(record.sample_rate) },
+	{ "i_channels",		T_UINT,		OFF(record.channels) },
+	{ "i_precision",	T_UINT,		OFF(record.precision) },
+	{ "i_encoding",		T_UINT,		OFF(record.encoding) },
+	{ "i_gain",		T_UINT,		OFF(record.gain) },
+	{ "i_port",		T_UINT,		OFF(record.port) },
+	{ "i_samples",		T_UINT,		OFF(record.samples) },
+	{ "i_eof",		T_UINT,		OFF(record.eof) },
+	{ "i_pause",		T_UBYTE,	OFF(record.pause) },
+	{ "i_error",		T_UBYTE,	OFF(record.error) },
+	{ "i_waiting",		T_UBYTE,	OFF(record.waiting) },
+	{ "i_open",		T_UBYTE,	OFF(record.open) ,	 RO},
+	{ "i_active",		T_UBYTE,	OFF(record.active) ,	 RO},
+#ifdef SOLARIS
+	{ "i_buffer_size",	T_UINT,		OFF(record.buffer_size) },
+	{ "i_balance",		T_UBYTE,	OFF(record.balance) },
+	{ "i_avail_ports",	T_UINT,		OFF(record.avail_ports) },
+#endif
+
+	{ "o_sample_rate",	T_UINT,		OFF(play.sample_rate) },
+	{ "o_channels",		T_UINT,		OFF(play.channels) },
+	{ "o_precision",	T_UINT,		OFF(play.precision) },
+	{ "o_encoding",		T_UINT,		OFF(play.encoding) },
+	{ "o_gain",		T_UINT,		OFF(play.gain) },
+	{ "o_port",		T_UINT,		OFF(play.port) },
+	{ "o_samples",		T_UINT,		OFF(play.samples) },
+	{ "o_eof",		T_UINT,		OFF(play.eof) },
+	{ "o_pause",		T_UBYTE,	OFF(play.pause) },
+	{ "o_error",		T_UBYTE,	OFF(play.error) },
+	{ "o_waiting",		T_UBYTE,	OFF(play.waiting) },
+	{ "o_open",		T_UBYTE,	OFF(play.open) ,	 RO},
+	{ "o_active",		T_UBYTE,	OFF(play.active) ,	 RO},
+#ifdef SOLARIS
+	{ "o_buffer_size",	T_UINT,		OFF(play.buffer_size) },
+	{ "o_balance",		T_UBYTE,	OFF(play.balance) },
+	{ "o_avail_ports",	T_UINT,		OFF(play.avail_ports) },
+#endif
+
+	{ "monitor_gain",	T_UINT,		OFF(monitor_gain) },
+        { NULL,                 0,              0},
+};
+
+static PyObject *
+sads_getattr(sadstatusobject *xp, char *name)
+{
+	return PyMember_Get((char *)&xp->ai, sads_ml, name);
+}
+
+static int
+sads_setattr(sadstatusobject *xp, char *name, PyObject *v)
+{
+
+	if (v == NULL) {
+		PyErr_SetString(PyExc_TypeError,
+				"can't delete sun audio status attributes");
+		return -1;
+	}
+	return PyMember_Set((char *)&xp->ai, sads_ml, name, v);
+}
+
+/* ------------------------------------------------------------------- */
+
+
+static PyTypeObject Sadtype = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,				/*ob_size*/
+	"sunaudiodev.sun_audio_device",	/*tp_name*/
+	sizeof(sadobject),		/*tp_size*/
+	0,				/*tp_itemsize*/
+	/* methods */
+	(destructor)sad_dealloc,	/*tp_dealloc*/
+	0,				/*tp_print*/
+	(getattrfunc)sad_getattr,	/*tp_getattr*/
+	0,				/*tp_setattr*/
+	0,				/*tp_compare*/
+	0,				/*tp_repr*/
+};
+
+static PyTypeObject Sadstatustype = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,				/*ob_size*/
+	"sunaudiodev.sun_audio_device_status", /*tp_name*/
+	sizeof(sadstatusobject),	/*tp_size*/
+	0,				/*tp_itemsize*/
+	/* methods */
+	(destructor)sads_dealloc,	/*tp_dealloc*/
+	0,				/*tp_print*/
+	(getattrfunc)sads_getattr,	/*tp_getattr*/
+	(setattrfunc)sads_setattr,	/*tp_setattr*/
+	0,				/*tp_compare*/
+	0,				/*tp_repr*/
+};
+/* ------------------------------------------------------------------- */
+
+static PyObject *
+sadopen(PyObject *self, PyObject *args)
+{
+	return (PyObject *)newsadobject(args);
+}
+    
+static PyMethodDef sunaudiodev_methods[] = {
+    { "open", sadopen, METH_VARARGS },
+    { 0, 0 },
+};
+
+void
+initsunaudiodev(void)
+{
+	PyObject *m, *d;
+
+	m = Py_InitModule("sunaudiodev", sunaudiodev_methods);
+	if (m == NULL)
+		return;
+	d = PyModule_GetDict(m);
+	SunAudioError = PyErr_NewException("sunaudiodev.error", NULL, NULL);
+	if (SunAudioError)
+		PyDict_SetItemString(d, "error", SunAudioError);
+}

Added: vendor/Python/current/Modules/svmodule.c
===================================================================
--- vendor/Python/current/Modules/svmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/svmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,966 @@
+/* SV module -- interface to the Indigo video board */
+
+/* WARNING! This module is for hardware that we don't have any more,
+   so it hasn't been tested.  It has been converted to the new coding
+   style, and it is possible that this conversion has broken something
+   -- user beware! */
+
+#include <sys/time.h>
+#include <svideo.h>
+#include "Python.h"
+#include "compile.h"
+#include "yuv.h"		/* for YUV conversion functions */
+
+typedef struct {
+	PyObject_HEAD
+	SV_nodeP ob_svideo;
+	svCaptureInfo ob_info;
+} svobject;
+
+typedef struct {
+	PyObject_HEAD
+	void *ob_capture;
+	int ob_mustunlock;
+	svCaptureInfo ob_info;
+	svobject *ob_svideo;
+} captureobject;
+
+static PyObject *SvError;		/* exception sv.error */
+
+static PyObject *newcaptureobject(svobject *, void *, int);
+
+/* Set a SV-specific error from svideo_errno and return NULL */
+static PyObject *
+sv_error(void)
+{
+	PyErr_SetString(SvError, svStrerror(svideo_errno));
+	return NULL;
+}
+
+static PyObject *
+svc_conversion(captureobject *self, PyObject *args, void (*function)(),	float factor)
+{
+	PyObject *output;
+	int invert;
+	char* outstr;
+
+	if (!PyArg_Parse(args, "i", &invert))
+		return NULL;
+
+	if (!(output = PyString_FromStringAndSize(
+		NULL,
+		(int)(self->ob_info.width * self->ob_info.height * factor))))
+	{
+		return NULL;
+	}
+	if (!(outstr = PyString_AsString(output))) {
+		Py_DECREF(output);
+		return NULL;
+	}
+
+	(*function)((boolean)invert, self->ob_capture,
+		    outstr,
+		    self->ob_info.width, self->ob_info.height);
+
+	return output;
+}
+
+/*
+ * 3 functions to convert from Starter Video YUV 4:1:1 format to
+ * Compression Library 4:2:2 Duplicate Chroma format.
+ */
+static PyObject *
+svc_YUVtoYUV422DC(captureobject *self, PyObject *args)
+{
+	if (self->ob_info.format != SV_YUV411_FRAMES) {
+		PyErr_SetString(SvError, "data has bad format");
+		return NULL;
+	}
+	return svc_conversion(self, args, yuv_sv411_to_cl422dc, 2.0);
+}
+
+static PyObject *
+svc_YUVtoYUV422DC_quarter(captureobject *self, PyObject *args)
+{
+	if (self->ob_info.format != SV_YUV411_FRAMES) {
+		PyErr_SetString(SvError, "data has bad format");
+		return NULL;
+	}
+	return svc_conversion(self, args,
+			      yuv_sv411_to_cl422dc_quartersize, 0.5);
+}
+
+static PyObject *
+svc_YUVtoYUV422DC_sixteenth(captureobject *self, PyObject *args)
+{
+	if (self->ob_info.format != SV_YUV411_FRAMES) {
+		PyErr_SetString(SvError, "data has bad format");
+		return NULL;
+	}
+	return svc_conversion(self, args,
+			      yuv_sv411_to_cl422dc_sixteenthsize, 0.125);
+}
+
+static PyObject *
+svc_YUVtoRGB(captureobject *self, PyObject *args)
+{
+	switch (self->ob_info.format) {
+	case SV_YUV411_FRAMES:
+	case SV_YUV411_FRAMES_AND_BLANKING_BUFFER:
+		break;
+	default:
+		PyErr_SetString(SvError, "data had bad format");
+		return NULL;
+	}
+	return svc_conversion(self, args, svYUVtoRGB, (float) sizeof(long));
+}
+
+static PyObject *
+svc_RGB8toRGB32(captureobject *self, PyObject *args)
+{
+	if (self->ob_info.format != SV_RGB8_FRAMES) {
+		PyErr_SetString(SvError, "data has bad format");
+		return NULL;
+	}
+	return svc_conversion(self, args, svRGB8toRGB32, (float) sizeof(long));
+}
+
+static PyObject *
+svc_InterleaveFields(captureobject *self, PyObject *args)
+{
+	if (self->ob_info.format != SV_RGB8_FRAMES) {
+		PyErr_SetString(SvError, "data has bad format");
+		return NULL;
+	}
+	return svc_conversion(self, args, svInterleaveFields, 1.0);
+}
+
+static PyObject *
+svc_GetFields(captureobject *self, PyObject *args)
+{
+	PyObject *f1 = NULL;
+	PyObject *f2 = NULL;
+	PyObject *ret = NULL;
+	int fieldsize;
+	char* obcapture;
+
+	if (self->ob_info.format != SV_RGB8_FRAMES) {
+		PyErr_SetString(SvError, "data has bad format");
+		return NULL;
+	}
+
+	fieldsize = self->ob_info.width * self->ob_info.height / 2;
+	obcapture = (char*)self->ob_capture;
+	
+	if (!(f1 = PyString_FromStringAndSize(obcapture, fieldsize)))
+		goto finally;
+	if (!(f2 = PyString_FromStringAndSize(obcapture + fieldsize,
+					      fieldsize)))
+		goto finally;
+	ret = PyTuple_Pack(2, f1, f2);
+
+  finally:
+	Py_XDECREF(f1);
+	Py_XDECREF(f2);
+	return ret;
+}
+	
+static PyObject *
+svc_UnlockCaptureData(captureobject *self, PyObject *args)
+{
+	if (!PyArg_Parse(args, ""))
+		return NULL;
+
+	if (!self->ob_mustunlock) {
+		PyErr_SetString(SvError, "buffer should not be unlocked");
+		return NULL;
+	}
+
+	if (svUnlockCaptureData(self->ob_svideo->ob_svideo, self->ob_capture))
+		return sv_error();
+
+	self->ob_mustunlock = 0;
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+#ifdef USE_GL
+#include <gl.h>
+
+static PyObject *
+svc_lrectwrite(captureobject *self, PyObject *args)
+{
+	Screencoord x1, x2, y1, y2;
+
+	if (!PyArg_Parse(args, "(hhhh)", &x1, &x2, &y1, &y2))
+		return NULL;
+
+	lrectwrite(x1, x2, y1, y2, (unsigned long *) self->ob_capture);
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+#endif
+
+static PyObject *
+svc_writefile(captureobject *self, PyObject *args)
+{
+	PyObject *file;
+	int size;
+	FILE* fp;
+
+	if (!PyArg_Parse(args, "O", &file))
+		return NULL;
+
+	if (!PyFile_Check(file)) {
+		PyErr_SetString(SvError, "not a file object");
+		return NULL;
+	}
+
+	if (!(fp = PyFile_AsFile(file)))
+		return NULL;
+
+	size = self->ob_info.width * self->ob_info.height;
+
+	if (fwrite(self->ob_capture, sizeof(long), size, fp) != size) {
+		PyErr_SetString(SvError, "writing failed");
+		return NULL;
+	}
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+svc_FindVisibleRegion(captureobject *self, PyObject *args)
+{
+	void *visible;
+	int width;
+
+	if (!PyArg_Parse(args, ""))
+		return NULL;
+
+	if (svFindVisibleRegion(self->ob_svideo->ob_svideo,
+				self->ob_capture, &visible,
+				self->ob_info.width))
+		return sv_error();
+
+	if (visible == NULL) {
+		PyErr_SetString(SvError, "data in wrong format");
+		return NULL;
+	}
+
+	return newcaptureobject(self->ob_svideo, visible, 0);
+}
+
+static PyMethodDef capture_methods[] = {
+	{"YUVtoRGB",		(PyCFunction)svc_YUVtoRGB, METH_OLDARGS},
+	{"RGB8toRGB32",		(PyCFunction)svc_RGB8toRGB32, METH_OLDARGS},
+	{"InterleaveFields",	(PyCFunction)svc_InterleaveFields, METH_OLDARGS},
+	{"UnlockCaptureData",	(PyCFunction)svc_UnlockCaptureData, METH_OLDARGS},
+	{"FindVisibleRegion",	(PyCFunction)svc_FindVisibleRegion, METH_OLDARGS},
+	{"GetFields",		(PyCFunction)svc_GetFields, METH_OLDARGS},
+	{"YUVtoYUV422DC",	(PyCFunction)svc_YUVtoYUV422DC, METH_OLDARGS},
+	{"YUVtoYUV422DC_quarter",(PyCFunction)svc_YUVtoYUV422DC_quarter, METH_OLDARGS},
+	{"YUVtoYUV422DC_sixteenth",(PyCFunction)svc_YUVtoYUV422DC_sixteenth, METH_OLDARGS},
+#ifdef USE_GL
+	{"lrectwrite",		(PyCFunction)svc_lrectwrite, METH_OLDARGS},
+#endif
+	{"writefile",		(PyCFunction)svc_writefile, METH_OLDARGS},
+	{NULL,			NULL} 		/* sentinel */
+};
+
+static void
+capture_dealloc(captureobject *self)
+{
+	if (self->ob_capture != NULL) {
+		if (self->ob_mustunlock)
+			(void)svUnlockCaptureData(self->ob_svideo->ob_svideo,
+						  self->ob_capture);
+		self->ob_capture = NULL;
+		Py_DECREF(self->ob_svideo);
+		self->ob_svideo = NULL;
+	}
+	PyObject_Del(self);
+}
+
+static PyObject *
+capture_getattr(svobject *self, char *name)
+{
+	return Py_FindMethod(capture_methods, (PyObject *)self, name);
+}
+
+PyTypeObject Capturetype = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,				/*ob_size*/
+	"sv.capture",			/*tp_name*/
+	sizeof(captureobject),		/*tp_size*/
+	0,				/*tp_itemsize*/
+	/* methods */
+	(destructor)capture_dealloc,	/*tp_dealloc*/
+	0,				/*tp_print*/
+	(getattrfunc)capture_getattr,	/*tp_getattr*/
+	0,				/*tp_setattr*/
+	0,				/*tp_compare*/
+	0,				/*tp_repr*/
+};
+
+static PyObject *
+newcaptureobject(svobject *self, void *ptr, int mustunlock)
+{
+	captureobject *p;
+
+	p = PyObject_New(captureobject, &Capturetype);
+	if (p == NULL)
+		return NULL;
+	p->ob_svideo = self;
+	Py_INCREF(self);
+	p->ob_capture = ptr;
+	p->ob_mustunlock = mustunlock;
+	p->ob_info = self->ob_info;
+	return (PyObject *) p;
+}
+
+static PyObject *
+sv_GetCaptureData(svobject *self, PyObject *args)
+{
+	void *ptr;
+	long fieldID;
+	PyObject *res, *c;
+
+	if (!PyArg_Parse(args, ""))
+		return NULL;
+
+	if (svGetCaptureData(self->ob_svideo, &ptr, &fieldID))
+		return sv_error();
+
+	if (ptr == NULL) {
+		PyErr_SetString(SvError, "no data available");
+		return NULL;
+	}
+
+	c = newcaptureobject(self, ptr, 1);
+	if (c == NULL)
+		return NULL;
+	res = Py_BuildValue("(Oi)", c, fieldID);
+	Py_DECREF(c);
+	return res;
+}
+
+static PyObject *
+sv_BindGLWindow(svobject *self, PyObject *args)
+{
+	long wid;
+	int mode;
+
+	if (!PyArg_Parse(args, "(ii)", &wid, &mode))
+		return NULL;
+
+	if (svBindGLWindow(self->ob_svideo, wid, mode))
+		return sv_error();
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+sv_EndContinuousCapture(svobject *self, PyObject *args)
+{
+
+	if (!PyArg_Parse(args, ""))
+		return NULL;
+
+	if (svEndContinuousCapture(self->ob_svideo))
+		return sv_error();
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+sv_IsVideoDisplayed(svobject *self, PyObject *args)
+{
+	int v;
+
+	if (!PyArg_Parse(args, ""))
+		return NULL;
+
+	v = svIsVideoDisplayed(self->ob_svideo);
+	if (v == -1)
+		return sv_error();
+
+	return PyInt_FromLong((long) v);
+}
+
+static PyObject *
+sv_OutputOffset(svobject *self, PyObject *args)
+{
+	int x_offset;
+	int y_offset;
+
+	if (!PyArg_Parse(args, "(ii)", &x_offset, &y_offset))
+		return NULL;
+
+	if (svOutputOffset(self->ob_svideo, x_offset, y_offset))
+		return sv_error();
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+sv_PutFrame(svobject *self, PyObject *args)
+{
+	char *buffer;
+
+	if (!PyArg_Parse(args, "s", &buffer))
+		return NULL;
+
+	if (svPutFrame(self->ob_svideo, buffer))
+		return sv_error();
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+sv_QuerySize(svobject *self, PyObject *args)
+{
+	int w;
+	int h;
+	int rw;
+	int rh;
+
+	if (!PyArg_Parse(args, "(ii)", &w, &h))
+		return NULL;
+
+	if (svQuerySize(self->ob_svideo, w, h, &rw, &rh))
+		return sv_error();
+
+	return Py_BuildValue("(ii)", (long) rw, (long) rh);
+}
+
+static PyObject *
+sv_SetSize(svobject *self, PyObject *args)
+{
+	int w;
+	int h;
+
+	if (!PyArg_Parse(args, "(ii)", &w, &h))
+		return NULL;
+
+	if (svSetSize(self->ob_svideo, w, h))
+		return sv_error();
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+sv_SetStdDefaults(svobject *self, PyObject *args)
+{
+
+	if (!PyArg_Parse(args, ""))
+		return NULL;
+
+	if (svSetStdDefaults(self->ob_svideo))
+		return sv_error();
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+sv_UseExclusive(svobject *self, PyObject *args)
+{
+	boolean onoff;
+	int mode;
+
+	if (!PyArg_Parse(args, "(ii)", &onoff, &mode))
+		return NULL;
+
+	if (svUseExclusive(self->ob_svideo, onoff, mode))
+		return sv_error();
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+sv_WindowOffset(svobject *self, PyObject *args)
+{
+	int x_offset;
+	int y_offset;
+
+	if (!PyArg_Parse(args, "(ii)", &x_offset, &y_offset))
+		return NULL;
+
+	if (svWindowOffset(self->ob_svideo, x_offset, y_offset))
+		return sv_error();
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+sv_CaptureBurst(svobject *self, PyObject *args)
+{
+	int bytes, i;
+	svCaptureInfo info;
+	void *bitvector = NULL;
+	PyObject *videodata = NULL;
+	PyObject *bitvecobj = NULL;
+	PyObject *res = NULL;
+	static PyObject *evenitem, *odditem;
+
+	if (!PyArg_Parse(args, "(iiiii)", &info.format,
+			 &info.width, &info.height,
+			 &info.size, &info.samplingrate))
+		return NULL;
+
+	switch (info.format) {
+	case SV_RGB8_FRAMES:
+		bitvector = malloc(SV_BITVEC_SIZE(info.size));
+		break;
+	case SV_YUV411_FRAMES_AND_BLANKING_BUFFER:
+		break;
+	default:
+		PyErr_SetString(SvError, "illegal format specified");
+		return NULL;
+	}
+
+	if (svQueryCaptureBufferSize(self->ob_svideo, &info, &bytes)) {
+		res = sv_error();
+		goto finally;
+	}
+
+	if (!(videodata = PyString_FromStringAndSize(NULL, bytes)))
+		goto finally;
+
+	/* XXX -- need to do something about the bitvector */
+	{
+		char* str = PyString_AsString(videodata);
+		if (!str)
+			goto finally;
+		
+		if (svCaptureBurst(self->ob_svideo, &info, str, bitvector)) {
+			res = sv_error();
+			goto finally;
+		}
+	}
+
+	if (bitvector) {
+		if (evenitem == NULL) {
+			if (!(evenitem = PyInt_FromLong(0)))
+				goto finally;
+		}
+		if (odditem == NULL) {
+			if (!(odditem = PyInt_FromLong(1)))
+				goto finally;
+		}
+		if (!(bitvecobj = PyTuple_New(2 * info.size)))
+			goto finally;
+
+		for (i = 0; i < 2 * info.size; i++) {
+			int sts;
+
+			if (SV_GET_FIELD(bitvector, i) == SV_EVEN_FIELD) {
+				Py_INCREF(evenitem);
+				sts = PyTuple_SetItem(bitvecobj, i, evenitem);
+			} else {
+				Py_INCREF(odditem);
+				sts = PyTuple_SetItem(bitvecobj, i, odditem);
+			}
+			if (sts < 0)
+				goto finally;
+		}
+	} else {
+		bitvecobj = Py_None;
+		Py_INCREF(Py_None);
+	}
+
+	res = Py_BuildValue("((iiiii)OO)", info.format,
+			    info.width, info.height,
+			    info.size, info.samplingrate,
+			    videodata, bitvecobj);
+
+  finally:
+	if (bitvector)
+		free(bitvector);
+
+	Py_XDECREF(videodata);
+	Py_XDECREF(bitvecobj);
+	return res;
+}
+
+static PyObject *
+sv_CaptureOneFrame(svobject *self, PyObject *args)
+{
+	svCaptureInfo info;
+	int format, width, height;
+	int bytes;
+	PyObject *videodata = NULL;
+	PyObject *res = NULL;
+	char *str;
+	
+	if (!PyArg_Parse(args, "(iii)", &format, &width, &height))
+		return NULL;
+
+	info.format = format;
+	info.width = width;
+	info.height = height;
+	info.size = 0;
+	info.samplingrate = 0;
+	if (svQueryCaptureBufferSize(self->ob_svideo, &info, &bytes))
+		return sv_error();
+
+	if (!(videodata = PyString_FromStringAndSize(NULL, bytes)))
+		return NULL;
+	
+	str = PyString_AsString(videodata);
+	if (!str)
+		goto finally;
+
+	if (svCaptureOneFrame(self->ob_svideo, format, &width, &height, str)) {
+		res = sv_error();
+		goto finally;
+	}
+
+	res = Py_BuildValue("(iiO)", width, height, videodata);
+
+  finally:
+	Py_XDECREF(videodata);
+	return res;
+}
+
+static PyObject *
+sv_InitContinuousCapture(svobject *self, PyObject *args)
+{
+	svCaptureInfo info;
+
+	if (!PyArg_Parse(args, "(iiiii)", &info.format,
+			 &info.width, &info.height,
+			 &info.size, &info.samplingrate))
+		return NULL;
+
+	if (svInitContinuousCapture(self->ob_svideo, &info))
+		return sv_error();
+
+	self->ob_info = info;
+
+	return Py_BuildValue("(iiiii)", info.format, info.width, info.height,
+			     info.size, info.samplingrate);
+}
+
+static PyObject *
+sv_LoadMap(svobject *self, PyObject *args)
+{
+	PyObject *rgb;
+	PyObject *res = NULL;
+	rgb_tuple *mapp = NULL;
+	int maptype;
+	int i, j;			     /* indices */
+
+	if (!PyArg_Parse(args, "(iO)", &maptype, &rgb))
+		return NULL;
+
+	if (!PyList_Check(rgb) || PyList_Size(rgb) != 256) {
+		PyErr_BadArgument();
+		return NULL;
+	}
+
+	if (!(mapp = PyMem_NEW(rgb_tuple, 256)))
+		return PyErr_NoMemory();
+
+	for (i = 0; i < 256; i++) {
+		PyObject* v = PyList_GetItem(rgb, i);
+		if (!v)
+			goto finally;
+
+		if (!PyTuple_Check(v) || PyTuple_Size(v) != 3) {
+			PyErr_BadArgument();
+			goto finally;
+		}
+		for (j = 0; j < 3; j++) {
+			PyObject* cell = PyTuple_GetItem(v, j);
+			if (!cell)
+				goto finally;
+
+			if (!PyInt_Check(cell)) {
+				PyErr_BadArgument();
+				goto finally;
+			}
+			switch (j) {
+			case 0: mapp[i].red = PyInt_AsLong(cell); break;
+			case 1: mapp[i].blue = PyInt_AsLong(cell); break;
+			case 2: mapp[i].green = PyInt_AsLong(cell); break;
+			}
+			if (PyErr_Occurred())
+				goto finally;
+		}
+	}
+
+	if (svLoadMap(self->ob_svideo, maptype, mapp)) {
+		res = sv_error();
+		goto finally;
+	}
+
+	Py_INCREF(Py_None);
+	res = Py_None;
+
+  finally:
+	PyMem_DEL(mapp);
+	return res;
+}
+		
+static PyObject *
+sv_CloseVideo(svobject *self, PyObject *args)
+{
+	if (!PyArg_Parse(args, ""))
+		return NULL;
+
+	if (svCloseVideo(self->ob_svideo))
+		return sv_error();
+
+	self->ob_svideo = NULL;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+doParams(svobject *self, PyObject *args,
+         int (*func)(SV_nodeP, long *, int), int modified)
+{
+	PyObject *list;
+	PyObject *res = NULL;
+	long *PVbuffer = NULL;
+	long length;
+	int i;
+	
+	if (!PyArg_Parse(args, "O", &list))
+		return NULL;
+
+	if (!PyList_Check(list)) {
+		PyErr_BadArgument();
+		return NULL;
+	}
+
+	if ((length = PyList_Size(list)) < 0)
+		return NULL;
+
+	PVbuffer = PyMem_NEW(long, length);
+	if (PVbuffer == NULL)
+		return PyErr_NoMemory();
+
+	for (i = 0; i < length; i++) {
+		PyObject *v = PyList_GetItem(list, i);
+		if (!v)
+			goto finally;
+
+		if (!PyInt_Check(v)) {
+			PyErr_BadArgument();
+			goto finally;
+		}
+		PVbuffer[i] = PyInt_AsLong(v);
+		/* can't just test the return value, because what if the
+		   value was -1?!
+		*/
+		if (PVbuffer[i] == -1 && PyErr_Occurred())
+			goto finally;
+	}
+
+	if ((*func)(self->ob_svideo, PVbuffer, length)) {
+		res = sv_error();
+		goto finally;
+	}
+
+	if (modified) {
+		for (i = 0; i < length; i++) {
+			PyObject* v = PyInt_FromLong(PVbuffer[i]);
+			if (!v || PyList_SetItem(list, i, v) < 0)
+				goto finally;
+		}
+	}
+
+	Py_INCREF(Py_None);
+	res = Py_None;
+
+  finally:
+	PyMem_DEL(PVbuffer);
+	return res;
+}
+
+static PyObject *
+sv_GetParam(PyObject *self, PyObject *args)
+{
+	return doParams(self, args, svGetParam, 1);
+}
+
+static PyObject *
+sv_GetParamRange(PyObject *self, PyObject *args)
+{
+	return doParams(self, args, svGetParamRange, 1);
+}
+
+static PyObject *
+sv_SetParam(PyObject *self, PyObject *args)
+{
+	return doParams(self, args, svSetParam, 0);
+}
+
+static PyMethodDef svideo_methods[] = {
+	{"BindGLWindow",	(PyCFunction)sv_BindGLWindow, METH_OLDARGS},
+	{"EndContinuousCapture",(PyCFunction)sv_EndContinuousCapture, METH_OLDARGS},
+	{"IsVideoDisplayed",	(PyCFunction)sv_IsVideoDisplayed, METH_OLDARGS},
+	{"OutputOffset",	(PyCFunction)sv_OutputOffset, METH_OLDARGS},
+	{"PutFrame",		(PyCFunction)sv_PutFrame, METH_OLDARGS},
+	{"QuerySize",		(PyCFunction)sv_QuerySize, METH_OLDARGS},
+	{"SetSize",		(PyCFunction)sv_SetSize, METH_OLDARGS},
+	{"SetStdDefaults",	(PyCFunction)sv_SetStdDefaults, METH_OLDARGS},
+	{"UseExclusive",	(PyCFunction)sv_UseExclusive, METH_OLDARGS},
+	{"WindowOffset",	(PyCFunction)sv_WindowOffset, METH_OLDARGS},
+	{"InitContinuousCapture",(PyCFunction)sv_InitContinuousCapture, METH_OLDARGS},
+	{"CaptureBurst",	(PyCFunction)sv_CaptureBurst, METH_OLDARGS},
+	{"CaptureOneFrame",	(PyCFunction)sv_CaptureOneFrame, METH_OLDARGS},
+	{"GetCaptureData",	(PyCFunction)sv_GetCaptureData, METH_OLDARGS},
+	{"CloseVideo",		(PyCFunction)sv_CloseVideo, METH_OLDARGS},
+	{"LoadMap",		(PyCFunction)sv_LoadMap, METH_OLDARGS},
+	{"GetParam",		(PyCFunction)sv_GetParam, METH_OLDARGS},
+	{"GetParamRange",	(PyCFunction)sv_GetParamRange, METH_OLDARGS},
+	{"SetParam",		(PyCFunction)sv_SetParam, METH_OLDARGS},
+	{NULL,			NULL} 		/* sentinel */
+};
+
+static PyObject *
+sv_conversion(PyObject *self, PyObject *args, void (*function)(),
+              int inputfactor, float factor)
+{
+	int invert, width, height, inputlength;
+	char *input, *str;
+	PyObject *output;
+
+	if (!PyArg_Parse(args, "(is#ii)", &invert,
+			 &input, &inputlength, &width, &height))
+		return NULL;
+
+	if (width * height * inputfactor > inputlength) {
+		PyErr_SetString(SvError, "input buffer not long enough");
+		return NULL;
+	}
+
+	if (!(output = PyString_FromStringAndSize(NULL,
+					      (int)(width * height * factor))))
+		return NULL;
+
+	str = PyString_AsString(output);
+	if (!str) {
+		Py_DECREF(output);
+		return NULL;
+	}
+	(*function)(invert, input, str, width, height);
+
+	return output;
+}
+
+static PyObject *
+sv_InterleaveFields(PyObject *self, PyObject *args)
+{
+	return sv_conversion(self, args, svInterleaveFields, 1, 1.0);
+}
+
+static PyObject *
+sv_RGB8toRGB32(PyObject *self, PyObject *args)
+{
+	return sv_conversion(self, args, svRGB8toRGB32, 1, (float) sizeof(long));
+}
+
+static PyObject *
+sv_YUVtoRGB(PyObject *self, PyObject *args)
+{
+	return sv_conversion(self, args, svYUVtoRGB, 2, (float) sizeof(long));
+}
+
+static void
+svideo_dealloc(svobject *self)
+{
+	if (self->ob_svideo != NULL)
+		(void) svCloseVideo(self->ob_svideo);
+	PyObject_Del(self);
+}
+
+static PyObject *
+svideo_getattr(svobject *self, char *name)
+{
+	return Py_FindMethod(svideo_methods, (PyObject *)self, name);
+}
+
+PyTypeObject Svtype = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,			/*ob_size*/
+	"sv.sv",		/*tp_name*/
+	sizeof(svobject),	/*tp_size*/
+	0,			/*tp_itemsize*/
+	/* methods */
+	(destructor)svideo_dealloc, /*tp_dealloc*/
+	0,			/*tp_print*/
+	(getattrfunc)svideo_getattr, /*tp_getattr*/
+	0,			/*tp_setattr*/
+	0,			/*tp_compare*/
+	0,			/*tp_repr*/
+};
+
+static PyObject *
+newsvobject(SV_nodeP svp)
+{
+	svobject *p;
+
+	p = PyObject_New(svobject, &Svtype);
+	if (p == NULL)
+		return NULL;
+	p->ob_svideo = svp;
+	p->ob_info.format = 0;
+	p->ob_info.size = 0;
+	p->ob_info.width = 0;
+	p->ob_info.height = 0;
+	p->ob_info.samplingrate = 0;
+	return (PyObject *) p;
+}
+
+static PyObject *
+sv_OpenVideo(PyObject *self, PyObject *args)
+{
+	SV_nodeP svp;
+
+	if (!PyArg_Parse(args, ""))
+		return NULL;
+
+	svp = svOpenVideo();
+	if (svp == NULL)
+		return sv_error();
+
+	return newsvobject(svp);
+}
+
+static PyMethodDef sv_methods[] = {
+	{"InterleaveFields",	(PyCFunction)sv_InterleaveFields, METH_OLDARGS},
+	{"RGB8toRGB32",		(PyCFunction)sv_RGB8toRGB32, METH_OLDARGS},
+	{"YUVtoRGB",		(PyCFunction)sv_YUVtoRGB, METH_OLDARGS},
+	{"OpenVideo",		(PyCFunction)sv_OpenVideo, METH_OLDARGS},
+	{NULL,			NULL}	/* Sentinel */
+};
+
+void
+initsv(void)
+{
+	PyObject *m, *d;
+
+	m = Py_InitModule("sv", sv_methods);
+	if (m == NULL)
+		return;
+	d = PyModule_GetDict(m);
+
+	SvError = PyErr_NewException("sv.error", NULL, NULL);
+	if (SvError == NULL || PyDict_SetItemString(d, "error", SvError) != 0)
+		return;
+}

Added: vendor/Python/current/Modules/symtablemodule.c
===================================================================
--- vendor/Python/current/Modules/symtablemodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/symtablemodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,84 @@
+#include "Python.h"
+
+#include "code.h"
+#include "compile.h"
+#include "Python-ast.h"
+#include "symtable.h"
+
+static PyObject *
+symtable_symtable(PyObject *self, PyObject *args)
+{
+	struct symtable *st;
+	PyObject *t;
+
+	char *str;
+	char *filename;
+	char *startstr;
+	int start;
+
+	if (!PyArg_ParseTuple(args, "sss:symtable", &str, &filename, 
+			      &startstr))
+		return NULL;
+	if (strcmp(startstr, "exec") == 0)
+		start = Py_file_input;
+	else if (strcmp(startstr, "eval") == 0)
+		start = Py_eval_input;
+	else if (strcmp(startstr, "single") == 0)
+		start = Py_single_input;
+	else {
+		PyErr_SetString(PyExc_ValueError,
+		   "symtable() arg 3 must be 'exec' or 'eval' or 'single'");
+		return NULL;
+	}
+	st = Py_SymtableString(str, filename, start);
+	if (st == NULL)
+		return NULL;
+	t = st->st_symbols;
+	Py_INCREF(t);
+	PyMem_Free((void *)st->st_future);
+	PySymtable_Free(st);
+	return t;
+}
+
+static PyMethodDef symtable_methods[] = {
+	{"symtable",	symtable_symtable,	METH_VARARGS,
+	 PyDoc_STR("Return symbol and scope dictionaries"
+	 	   " used internally by compiler.")},
+	{NULL,		NULL}		/* sentinel */
+};
+
+PyMODINIT_FUNC
+init_symtable(void)
+{
+	PyObject *m;
+
+	m = Py_InitModule("_symtable", symtable_methods);
+	if (m == NULL)
+		return;
+	PyModule_AddIntConstant(m, "USE", USE);
+	PyModule_AddIntConstant(m, "DEF_GLOBAL", DEF_GLOBAL);
+	PyModule_AddIntConstant(m, "DEF_LOCAL", DEF_LOCAL);
+	PyModule_AddIntConstant(m, "DEF_PARAM", DEF_PARAM);
+	PyModule_AddIntConstant(m, "DEF_STAR", DEF_STAR);
+	PyModule_AddIntConstant(m, "DEF_DOUBLESTAR", DEF_DOUBLESTAR);
+	PyModule_AddIntConstant(m, "DEF_INTUPLE", DEF_INTUPLE);
+	PyModule_AddIntConstant(m, "DEF_FREE", DEF_FREE);
+	PyModule_AddIntConstant(m, "DEF_FREE_GLOBAL", DEF_FREE_GLOBAL);
+	PyModule_AddIntConstant(m, "DEF_FREE_CLASS", DEF_FREE_CLASS);
+	PyModule_AddIntConstant(m, "DEF_IMPORT", DEF_IMPORT);
+	PyModule_AddIntConstant(m, "DEF_BOUND", DEF_BOUND);
+
+	PyModule_AddIntConstant(m, "TYPE_FUNCTION", FunctionBlock);
+	PyModule_AddIntConstant(m, "TYPE_CLASS", ClassBlock);
+	PyModule_AddIntConstant(m, "TYPE_MODULE", ModuleBlock);
+
+	PyModule_AddIntConstant(m, "OPT_IMPORT_STAR", OPT_IMPORT_STAR);
+	PyModule_AddIntConstant(m, "OPT_EXEC", OPT_EXEC);
+	PyModule_AddIntConstant(m, "OPT_BARE_EXEC", OPT_BARE_EXEC);
+
+	PyModule_AddIntConstant(m, "LOCAL", LOCAL);
+	PyModule_AddIntConstant(m, "GLOBAL_EXPLICIT", GLOBAL_EXPLICIT);
+	PyModule_AddIntConstant(m, "GLOBAL_IMPLICIT", GLOBAL_IMPLICIT);
+	PyModule_AddIntConstant(m, "FREE", FREE);
+	PyModule_AddIntConstant(m, "CELL", CELL);
+}

Added: vendor/Python/current/Modules/syslogmodule.c
===================================================================
--- vendor/Python/current/Modules/syslogmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/syslogmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,223 @@
+/***********************************************************
+Copyright 1994 by Lance Ellinghouse,
+Cathedral City, California Republic, United States of America.
+
+                        All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its 
+documentation for any purpose and without fee is hereby granted, 
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in 
+supporting documentation, and that the name of Lance Ellinghouse
+not be used in advertising or publicity pertaining to distribution 
+of the software without specific, written prior permission.
+
+LANCE ELLINGHOUSE DISCLAIMS ALL WARRANTIES WITH REGARD TO
+THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL LANCE ELLINGHOUSE BE LIABLE FOR ANY SPECIAL, 
+INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING 
+FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, 
+NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 
+WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+******************************************************************/
+
+/******************************************************************
+
+Revision history:
+
+1998/04/28 (Sean Reifschneider)
+  - When facility not specified to syslog() method, use default from openlog()
+    (This is how it was claimed to work in the documentation)
+  - Potential resource leak of o_ident, now cleaned up in closelog()
+  - Minor comment accuracy fix.
+
+95/06/29 (Steve Clift)
+  - Changed arg parsing to use PyArg_ParseTuple.
+  - Added PyErr_Clear() call(s) where needed.
+  - Fix core dumps if user message contains format specifiers.
+  - Change openlog arg defaults to match normal syslog behavior.
+  - Plug memory leak in openlog().
+  - Fix setlogmask() to return previous mask value.
+
+******************************************************************/
+
+/* syslog module */
+
+#include "Python.h"
+
+#include <syslog.h>
+
+/*  only one instance, only one syslog, so globals should be ok  */
+static PyObject *S_ident_o = NULL;			/*  identifier, held by openlog()  */
+
+
+static PyObject * 
+syslog_openlog(PyObject * self, PyObject * args)
+{
+	long logopt = 0;
+	long facility = LOG_USER;
+	PyObject *new_S_ident_o;
+
+	if (!PyArg_ParseTuple(args,
+			      "S|ll;ident string [, logoption [, facility]]",
+			      &new_S_ident_o, &logopt, &facility))
+		return NULL;
+
+	/* This is needed because openlog() does NOT make a copy
+	 * and syslog() later uses it.. cannot trash it.
+	 */
+	Py_XDECREF(S_ident_o);
+	S_ident_o = new_S_ident_o;
+	Py_INCREF(S_ident_o);
+
+	openlog(PyString_AsString(S_ident_o), logopt, facility);
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+
+static PyObject * 
+syslog_syslog(PyObject * self, PyObject * args)
+{
+	char *message;
+	int   priority = LOG_INFO;
+
+	if (!PyArg_ParseTuple(args, "is;[priority,] message string",
+			      &priority, &message)) {
+		PyErr_Clear();
+		if (!PyArg_ParseTuple(args, "s;[priority,] message string",
+				      &message))
+			return NULL;
+	}
+
+	syslog(priority, "%s", message);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject * 
+syslog_closelog(PyObject *self, PyObject *unused)
+{
+	closelog();
+	Py_XDECREF(S_ident_o);
+	S_ident_o = NULL;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject * 
+syslog_setlogmask(PyObject *self, PyObject *args)
+{
+	long maskpri, omaskpri;
+
+	if (!PyArg_ParseTuple(args, "l;mask for priority", &maskpri))
+		return NULL;
+	omaskpri = setlogmask(maskpri);
+	return PyInt_FromLong(omaskpri);
+}
+
+static PyObject * 
+syslog_log_mask(PyObject *self, PyObject *args)
+{
+	long mask;
+	long pri;
+	if (!PyArg_ParseTuple(args, "l:LOG_MASK", &pri))
+		return NULL;
+	mask = LOG_MASK(pri);
+	return PyInt_FromLong(mask);
+}
+
+static PyObject * 
+syslog_log_upto(PyObject *self, PyObject *args)
+{
+	long mask;
+	long pri;
+	if (!PyArg_ParseTuple(args, "l:LOG_UPTO", &pri))
+		return NULL;
+	mask = LOG_UPTO(pri);
+	return PyInt_FromLong(mask);
+}
+
+/* List of functions defined in the module */
+
+static PyMethodDef syslog_methods[] = {
+	{"openlog",	syslog_openlog,		METH_VARARGS},
+	{"closelog",	syslog_closelog,	METH_NOARGS},
+	{"syslog",	syslog_syslog,		METH_VARARGS},
+	{"setlogmask",	syslog_setlogmask,	METH_VARARGS},
+	{"LOG_MASK",	syslog_log_mask,	METH_VARARGS},
+	{"LOG_UPTO",	syslog_log_upto,	METH_VARARGS},
+	{NULL,		NULL,			0}
+};
+
+/* Initialization function for the module */
+
+PyMODINIT_FUNC
+initsyslog(void)
+{
+	PyObject *m;
+
+	/* Create the module and add the functions */
+	m = Py_InitModule("syslog", syslog_methods);
+	if (m == NULL)
+		return;
+
+	/* Add some symbolic constants to the module */
+
+	/* Priorities */
+	PyModule_AddIntConstant(m, "LOG_EMERG",	  LOG_EMERG);
+	PyModule_AddIntConstant(m, "LOG_ALERT",	  LOG_ALERT);
+	PyModule_AddIntConstant(m, "LOG_CRIT",	  LOG_CRIT);
+	PyModule_AddIntConstant(m, "LOG_ERR",	  LOG_ERR);
+	PyModule_AddIntConstant(m, "LOG_WARNING", LOG_WARNING);
+	PyModule_AddIntConstant(m, "LOG_NOTICE",  LOG_NOTICE);
+	PyModule_AddIntConstant(m, "LOG_INFO",	  LOG_INFO);
+	PyModule_AddIntConstant(m, "LOG_DEBUG",	  LOG_DEBUG);
+
+	/* openlog() option flags */
+	PyModule_AddIntConstant(m, "LOG_PID",	  LOG_PID);
+	PyModule_AddIntConstant(m, "LOG_CONS",	  LOG_CONS);
+	PyModule_AddIntConstant(m, "LOG_NDELAY",  LOG_NDELAY);
+#ifdef LOG_NOWAIT
+	PyModule_AddIntConstant(m, "LOG_NOWAIT",  LOG_NOWAIT);
+#endif
+#ifdef LOG_PERROR
+	PyModule_AddIntConstant(m, "LOG_PERROR",  LOG_PERROR);
+#endif
+
+	/* Facilities */
+	PyModule_AddIntConstant(m, "LOG_KERN",	  LOG_KERN);
+	PyModule_AddIntConstant(m, "LOG_USER",	  LOG_USER);
+	PyModule_AddIntConstant(m, "LOG_MAIL",	  LOG_MAIL);
+	PyModule_AddIntConstant(m, "LOG_DAEMON",  LOG_DAEMON);
+	PyModule_AddIntConstant(m, "LOG_AUTH",	  LOG_AUTH);
+	PyModule_AddIntConstant(m, "LOG_LPR",	  LOG_LPR);
+	PyModule_AddIntConstant(m, "LOG_LOCAL0",  LOG_LOCAL0);
+	PyModule_AddIntConstant(m, "LOG_LOCAL1",  LOG_LOCAL1);
+	PyModule_AddIntConstant(m, "LOG_LOCAL2",  LOG_LOCAL2);
+	PyModule_AddIntConstant(m, "LOG_LOCAL3",  LOG_LOCAL3);
+	PyModule_AddIntConstant(m, "LOG_LOCAL4",  LOG_LOCAL4);
+	PyModule_AddIntConstant(m, "LOG_LOCAL5",  LOG_LOCAL5);
+	PyModule_AddIntConstant(m, "LOG_LOCAL6",  LOG_LOCAL6);
+	PyModule_AddIntConstant(m, "LOG_LOCAL7",  LOG_LOCAL7);
+
+#ifndef LOG_SYSLOG
+#define LOG_SYSLOG		LOG_DAEMON
+#endif
+#ifndef LOG_NEWS
+#define LOG_NEWS		LOG_MAIL
+#endif
+#ifndef LOG_UUCP
+#define LOG_UUCP		LOG_MAIL
+#endif
+#ifndef LOG_CRON
+#define LOG_CRON		LOG_DAEMON
+#endif
+
+	PyModule_AddIntConstant(m, "LOG_SYSLOG",  LOG_SYSLOG);
+	PyModule_AddIntConstant(m, "LOG_CRON",	  LOG_CRON);
+	PyModule_AddIntConstant(m, "LOG_UUCP",	  LOG_UUCP);
+	PyModule_AddIntConstant(m, "LOG_NEWS",	  LOG_NEWS);
+}

Added: vendor/Python/current/Modules/termios.c
===================================================================
--- vendor/Python/current/Modules/termios.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/termios.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,926 @@
+/* termiosmodule.c -- POSIX terminal I/O module implementation.  */
+
+#include "Python.h"
+
+#define PyInit_termios inittermios
+
+/* Apparently, on SGI, termios.h won't define CTRL if _XOPEN_SOURCE
+   is defined, so we define it here. */
+#if defined(__sgi)
+#define CTRL(c) ((c)&037)
+#endif
+
+#include <termios.h>
+#ifdef __osf__
+/* On OSF, sys/ioctl.h requires that struct termio already be defined,
+ * so this needs to be included first on that platform. */
+#include <termio.h>
+#endif
+#include <sys/ioctl.h>
+
+/* HP-UX requires that this be included to pick up MDCD, MCTS, MDSR,
+ * MDTR, MRI, and MRTS (appearantly used internally by some things
+ * defined as macros; these are not used here directly).
+ */
+#ifdef HAVE_SYS_MODEM_H
+#include <sys/modem.h>
+#endif
+/* HP-UX requires that this be included to pick up TIOCGPGRP and friends */
+#ifdef HAVE_SYS_BSDTTY_H
+#include <sys/bsdtty.h>
+#endif
+
+PyDoc_STRVAR(termios__doc__,
+"This module provides an interface to the Posix calls for tty I/O control.\n\
+For a complete description of these calls, see the Posix or Unix manual\n\
+pages. It is only available for those Unix versions that support Posix\n\
+termios style tty I/O control.\n\
+\n\
+All functions in this module take a file descriptor fd as their first\n\
+argument. This can be an integer file descriptor, such as returned by\n\
+sys.stdin.fileno(), or a file object, such as sys.stdin itself.");
+
+static PyObject *TermiosError;
+
+static int fdconv(PyObject* obj, void* p)
+{
+	int fd;
+
+	fd = PyObject_AsFileDescriptor(obj);
+	if (fd >= 0) {
+		*(int*)p = fd;
+		return 1;
+	}
+	return 0;
+}
+
+PyDoc_STRVAR(termios_tcgetattr__doc__,
+"tcgetattr(fd) -> list_of_attrs\n\
+\n\
+Get the tty attributes for file descriptor fd, as follows:\n\
+[iflag, oflag, cflag, lflag, ispeed, ospeed, cc] where cc is a list\n\
+of the tty special characters (each a string of length 1, except the items\n\
+with indices VMIN and VTIME, which are integers when these fields are\n\
+defined).  The interpretation of the flags and the speeds as well as the\n\
+indexing in the cc array must be done using the symbolic constants defined\n\
+in this module.");
+
+static PyObject *
+termios_tcgetattr(PyObject *self, PyObject *args)
+{
+	int fd;
+	struct termios mode;
+	PyObject *cc;
+	speed_t ispeed, ospeed;
+	PyObject *v;
+	int i;
+	char ch;
+
+	if (!PyArg_ParseTuple(args, "O&:tcgetattr", 
+			      fdconv, (void*)&fd))
+		return NULL;
+
+	if (tcgetattr(fd, &mode) == -1)
+		return PyErr_SetFromErrno(TermiosError);
+
+	ispeed = cfgetispeed(&mode);
+	ospeed = cfgetospeed(&mode);
+
+	cc = PyList_New(NCCS);
+	if (cc == NULL)
+		return NULL;
+	for (i = 0; i < NCCS; i++) {
+		ch = (char)mode.c_cc[i];
+		v = PyString_FromStringAndSize(&ch, 1);
+		if (v == NULL)
+			goto err;
+		PyList_SetItem(cc, i, v);
+	}
+
+	/* Convert the MIN and TIME slots to integer.  On some systems, the
+	   MIN and TIME slots are the same as the EOF and EOL slots.  So we
+	   only do this in noncanonical input mode.  */
+	if ((mode.c_lflag & ICANON) == 0) {
+		v = PyInt_FromLong((long)mode.c_cc[VMIN]);
+		if (v == NULL)
+			goto err;
+		PyList_SetItem(cc, VMIN, v);
+		v = PyInt_FromLong((long)mode.c_cc[VTIME]);
+		if (v == NULL)
+			goto err;
+		PyList_SetItem(cc, VTIME, v);
+	}
+
+	if (!(v = PyList_New(7)))
+		goto err;
+
+	PyList_SetItem(v, 0, PyInt_FromLong((long)mode.c_iflag));
+	PyList_SetItem(v, 1, PyInt_FromLong((long)mode.c_oflag));
+	PyList_SetItem(v, 2, PyInt_FromLong((long)mode.c_cflag));
+	PyList_SetItem(v, 3, PyInt_FromLong((long)mode.c_lflag));
+	PyList_SetItem(v, 4, PyInt_FromLong((long)ispeed));
+	PyList_SetItem(v, 5, PyInt_FromLong((long)ospeed));
+	PyList_SetItem(v, 6, cc);
+	if (PyErr_Occurred()){
+		Py_DECREF(v);
+		goto err;
+	}
+	return v;
+  err:
+	Py_DECREF(cc);
+	return NULL;
+}
+
+PyDoc_STRVAR(termios_tcsetattr__doc__,
+"tcsetattr(fd, when, attributes) -> None\n\
+\n\
+Set the tty attributes for file descriptor fd.\n\
+The attributes to be set are taken from the attributes argument, which\n\
+is a list like the one returned by tcgetattr(). The when argument\n\
+determines when the attributes are changed: termios.TCSANOW to\n\
+change immediately, termios.TCSADRAIN to change after transmitting all\n\
+queued output, or termios.TCSAFLUSH to change after transmitting all\n\
+queued output and discarding all queued input. ");
+
+static PyObject *
+termios_tcsetattr(PyObject *self, PyObject *args)
+{
+	int fd, when;
+	struct termios mode;
+	speed_t ispeed, ospeed;
+	PyObject *term, *cc, *v;
+	int i;
+
+	if (!PyArg_ParseTuple(args, "O&iO:tcsetattr", 
+			      fdconv, &fd, &when, &term))
+		return NULL;
+	if (!PyList_Check(term) || PyList_Size(term) != 7) {
+		PyErr_SetString(PyExc_TypeError, 
+			     "tcsetattr, arg 3: must be 7 element list");
+		return NULL;
+	}
+
+	/* Get the old mode, in case there are any hidden fields... */
+	if (tcgetattr(fd, &mode) == -1)
+		return PyErr_SetFromErrno(TermiosError);
+	mode.c_iflag = (tcflag_t) PyInt_AsLong(PyList_GetItem(term, 0));
+	mode.c_oflag = (tcflag_t) PyInt_AsLong(PyList_GetItem(term, 1));
+	mode.c_cflag = (tcflag_t) PyInt_AsLong(PyList_GetItem(term, 2));
+	mode.c_lflag = (tcflag_t) PyInt_AsLong(PyList_GetItem(term, 3));
+	ispeed = (speed_t) PyInt_AsLong(PyList_GetItem(term, 4));
+	ospeed = (speed_t) PyInt_AsLong(PyList_GetItem(term, 5));
+	cc = PyList_GetItem(term, 6);
+	if (PyErr_Occurred())
+		return NULL;
+
+	if (!PyList_Check(cc) || PyList_Size(cc) != NCCS) {
+		PyErr_Format(PyExc_TypeError, 
+			"tcsetattr: attributes[6] must be %d element list",
+			     NCCS);
+		return NULL;
+	}
+
+	for (i = 0; i < NCCS; i++) {
+		v = PyList_GetItem(cc, i);
+
+		if (PyString_Check(v) && PyString_Size(v) == 1)
+			mode.c_cc[i] = (cc_t) * PyString_AsString(v);
+		else if (PyInt_Check(v))
+			mode.c_cc[i] = (cc_t) PyInt_AsLong(v);
+		else {
+			PyErr_SetString(PyExc_TypeError, 
+     "tcsetattr: elements of attributes must be characters or integers");
+			return NULL;
+		}
+	}
+
+	if (cfsetispeed(&mode, (speed_t) ispeed) == -1)
+		return PyErr_SetFromErrno(TermiosError);
+	if (cfsetospeed(&mode, (speed_t) ospeed) == -1)
+		return PyErr_SetFromErrno(TermiosError);
+	if (tcsetattr(fd, when, &mode) == -1)
+		return PyErr_SetFromErrno(TermiosError);
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(termios_tcsendbreak__doc__,
+"tcsendbreak(fd, duration) -> None\n\
+\n\
+Send a break on file descriptor fd.\n\
+A zero duration sends a break for 0.25-0.5 seconds; a nonzero duration\n\
+has a system dependent meaning.");
+
+static PyObject *
+termios_tcsendbreak(PyObject *self, PyObject *args)
+{
+	int fd, duration;
+
+	if (!PyArg_ParseTuple(args, "O&i:tcsendbreak", 
+			      fdconv, &fd, &duration))
+		return NULL;
+	if (tcsendbreak(fd, duration) == -1)
+		return PyErr_SetFromErrno(TermiosError);
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(termios_tcdrain__doc__,
+"tcdrain(fd) -> None\n\
+\n\
+Wait until all output written to file descriptor fd has been transmitted.");
+
+static PyObject *
+termios_tcdrain(PyObject *self, PyObject *args)
+{
+	int fd;
+
+	if (!PyArg_ParseTuple(args, "O&:tcdrain", 
+			      fdconv, &fd))
+		return NULL;
+	if (tcdrain(fd) == -1)
+		return PyErr_SetFromErrno(TermiosError);
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(termios_tcflush__doc__,
+"tcflush(fd, queue) -> None\n\
+\n\
+Discard queued data on file descriptor fd.\n\
+The queue selector specifies which queue: termios.TCIFLUSH for the input\n\
+queue, termios.TCOFLUSH for the output queue, or termios.TCIOFLUSH for\n\
+both queues. ");
+
+static PyObject *
+termios_tcflush(PyObject *self, PyObject *args)
+{
+	int fd, queue;
+
+	if (!PyArg_ParseTuple(args, "O&i:tcflush", 
+			      fdconv, &fd, &queue))
+		return NULL;
+	if (tcflush(fd, queue) == -1)
+		return PyErr_SetFromErrno(TermiosError);
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(termios_tcflow__doc__,
+"tcflow(fd, action) -> None\n\
+\n\
+Suspend or resume input or output on file descriptor fd.\n\
+The action argument can be termios.TCOOFF to suspend output,\n\
+termios.TCOON to restart output, termios.TCIOFF to suspend input,\n\
+or termios.TCION to restart input.");
+
+static PyObject *
+termios_tcflow(PyObject *self, PyObject *args)
+{
+	int fd, action;
+
+	if (!PyArg_ParseTuple(args, "O&i:tcflow", 
+			      fdconv, &fd, &action))
+		return NULL;
+	if (tcflow(fd, action) == -1)
+		return PyErr_SetFromErrno(TermiosError);
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyMethodDef termios_methods[] =
+{
+	{"tcgetattr", termios_tcgetattr, 
+	 METH_VARARGS, termios_tcgetattr__doc__},
+	{"tcsetattr", termios_tcsetattr, 
+	 METH_VARARGS, termios_tcsetattr__doc__},
+	{"tcsendbreak", termios_tcsendbreak, 
+	 METH_VARARGS, termios_tcsendbreak__doc__},
+	{"tcdrain", termios_tcdrain, 
+	 METH_VARARGS, termios_tcdrain__doc__},
+	{"tcflush", termios_tcflush, 
+	 METH_VARARGS, termios_tcflush__doc__},
+	{"tcflow", termios_tcflow, 
+	 METH_VARARGS, termios_tcflow__doc__},
+	{NULL, NULL}
+};
+
+
+#if defined(VSWTCH) && !defined(VSWTC)
+#define VSWTC VSWTCH
+#endif
+
+#if defined(VSWTC) && !defined(VSWTCH)
+#define VSWTCH VSWTC
+#endif
+
+static struct constant {
+	char *name;
+	long value;
+} termios_constants[] = {
+	/* cfgetospeed(), cfsetospeed() constants */
+	{"B0", B0},
+	{"B50", B50},
+	{"B75", B75},
+	{"B110", B110},
+	{"B134", B134},
+	{"B150", B150},
+	{"B200", B200},
+	{"B300", B300},
+	{"B600", B600},
+	{"B1200", B1200},
+	{"B1800", B1800},
+	{"B2400", B2400},
+	{"B4800", B4800},
+	{"B9600", B9600},
+	{"B19200", B19200},
+	{"B38400", B38400},
+#ifdef B57600
+	{"B57600", B57600},
+#endif
+#ifdef B115200
+	{"B115200", B115200},
+#endif
+#ifdef B230400
+	{"B230400", B230400},
+#endif
+#ifdef CBAUDEX
+	{"CBAUDEX", CBAUDEX},
+#endif
+
+	/* tcsetattr() constants */
+	{"TCSANOW", TCSANOW},
+	{"TCSADRAIN", TCSADRAIN},
+	{"TCSAFLUSH", TCSAFLUSH},
+
+	/* tcflush() constants */
+	{"TCIFLUSH", TCIFLUSH},
+	{"TCOFLUSH", TCOFLUSH},
+	{"TCIOFLUSH", TCIOFLUSH},
+
+	/* tcflow() constants */
+	{"TCOOFF", TCOOFF},
+	{"TCOON", TCOON},
+	{"TCIOFF", TCIOFF},
+	{"TCION", TCION},
+
+	/* struct termios.c_iflag constants */
+	{"IGNBRK", IGNBRK},
+	{"BRKINT", BRKINT},
+	{"IGNPAR", IGNPAR},
+	{"PARMRK", PARMRK},
+	{"INPCK", INPCK},
+	{"ISTRIP", ISTRIP},
+	{"INLCR", INLCR},
+	{"IGNCR", IGNCR},
+	{"ICRNL", ICRNL},
+#ifdef IUCLC
+	{"IUCLC", IUCLC},
+#endif
+	{"IXON", IXON},
+	{"IXANY", IXANY},
+	{"IXOFF", IXOFF},
+#ifdef IMAXBEL
+	{"IMAXBEL", IMAXBEL},
+#endif
+
+	/* struct termios.c_oflag constants */
+	{"OPOST", OPOST},
+#ifdef OLCUC
+	{"OLCUC", OLCUC},
+#endif
+#ifdef ONLCR
+	{"ONLCR", ONLCR},
+#endif
+#ifdef OCRNL
+	{"OCRNL", OCRNL},
+#endif
+#ifdef ONOCR
+	{"ONOCR", ONOCR},
+#endif
+#ifdef ONLRET
+	{"ONLRET", ONLRET},
+#endif
+#ifdef OFILL
+	{"OFILL", OFILL},
+#endif
+#ifdef OFDEL
+	{"OFDEL", OFDEL},
+#endif
+#ifdef NLDLY
+	{"NLDLY", NLDLY},
+#endif
+#ifdef CRDLY
+	{"CRDLY", CRDLY},
+#endif
+#ifdef TABDLY
+	{"TABDLY", TABDLY},
+#endif
+#ifdef BSDLY
+	{"BSDLY", BSDLY},
+#endif
+#ifdef VTDLY
+	{"VTDLY", VTDLY},
+#endif
+#ifdef FFDLY
+	{"FFDLY", FFDLY},
+#endif
+
+	/* struct termios.c_oflag-related values (delay mask) */
+#ifdef NL0
+	{"NL0", NL0},
+#endif
+#ifdef NL1
+	{"NL1", NL1},
+#endif
+#ifdef CR0
+	{"CR0", CR0},
+#endif
+#ifdef CR1
+	{"CR1", CR1},
+#endif
+#ifdef CR2
+	{"CR2", CR2},
+#endif
+#ifdef CR3
+	{"CR3", CR3},
+#endif
+#ifdef TAB0
+	{"TAB0", TAB0},
+#endif
+#ifdef TAB1
+	{"TAB1", TAB1},
+#endif
+#ifdef TAB2
+	{"TAB2", TAB2},
+#endif
+#ifdef TAB3
+	{"TAB3", TAB3},
+#endif
+#ifdef XTABS
+	{"XTABS", XTABS},
+#endif
+#ifdef BS0
+	{"BS0", BS0},
+#endif
+#ifdef BS1
+	{"BS1", BS1},
+#endif
+#ifdef VT0
+	{"VT0", VT0},
+#endif
+#ifdef VT1
+	{"VT1", VT1},
+#endif
+#ifdef FF0
+	{"FF0", FF0},
+#endif
+#ifdef FF1
+	{"FF1", FF1},
+#endif
+
+	/* struct termios.c_cflag constants */
+	{"CSIZE", CSIZE},
+	{"CSTOPB", CSTOPB},
+	{"CREAD", CREAD},
+	{"PARENB", PARENB},
+	{"PARODD", PARODD},
+	{"HUPCL", HUPCL},
+	{"CLOCAL", CLOCAL},
+#ifdef CIBAUD
+	{"CIBAUD", CIBAUD},
+#endif
+#ifdef CRTSCTS
+	{"CRTSCTS", (long)CRTSCTS},
+#endif
+
+	/* struct termios.c_cflag-related values (character size) */
+	{"CS5", CS5},
+	{"CS6", CS6},
+	{"CS7", CS7},
+	{"CS8", CS8},
+
+	/* struct termios.c_lflag constants */
+	{"ISIG", ISIG},
+	{"ICANON", ICANON},
+#ifdef XCASE
+	{"XCASE", XCASE},
+#endif
+	{"ECHO", ECHO},
+	{"ECHOE", ECHOE},
+	{"ECHOK", ECHOK},
+	{"ECHONL", ECHONL},
+#ifdef ECHOCTL
+	{"ECHOCTL", ECHOCTL},
+#endif
+#ifdef ECHOPRT
+	{"ECHOPRT", ECHOPRT},
+#endif
+#ifdef ECHOKE
+	{"ECHOKE", ECHOKE},
+#endif
+#ifdef FLUSHO
+	{"FLUSHO", FLUSHO},
+#endif
+	{"NOFLSH", NOFLSH},
+	{"TOSTOP", TOSTOP},
+#ifdef PENDIN
+	{"PENDIN", PENDIN},
+#endif
+	{"IEXTEN", IEXTEN},
+
+	/* indexes into the control chars array returned by tcgetattr() */
+	{"VINTR", VINTR},
+	{"VQUIT", VQUIT},
+	{"VERASE", VERASE},
+	{"VKILL", VKILL},
+	{"VEOF", VEOF},
+	{"VTIME", VTIME},
+	{"VMIN", VMIN},
+#ifdef VSWTC
+	/* The #defines above ensure that if either is defined, both are,
+         * but both may be omitted by the system headers.  ;-(  */
+	{"VSWTC", VSWTC},
+	{"VSWTCH", VSWTCH},
+#endif
+	{"VSTART", VSTART},
+	{"VSTOP", VSTOP},
+	{"VSUSP", VSUSP},
+	{"VEOL", VEOL},
+#ifdef VREPRINT
+	{"VREPRINT", VREPRINT},
+#endif
+#ifdef VDISCARD
+	{"VDISCARD", VDISCARD},
+#endif
+#ifdef VWERASE
+	{"VWERASE", VWERASE},
+#endif
+#ifdef VLNEXT
+	{"VLNEXT", VLNEXT},
+#endif
+#ifdef VEOL2
+	{"VEOL2", VEOL2},
+#endif
+
+
+#ifdef B460800
+	{"B460800", B460800},
+#endif
+#ifdef CBAUD
+	{"CBAUD", CBAUD},
+#endif
+#ifdef CDEL
+	{"CDEL", CDEL},
+#endif
+#ifdef CDSUSP
+	{"CDSUSP", CDSUSP},
+#endif
+#ifdef CEOF
+	{"CEOF", CEOF},
+#endif
+#ifdef CEOL
+	{"CEOL", CEOL},
+#endif
+#ifdef CEOL2
+	{"CEOL2", CEOL2},
+#endif
+#ifdef CEOT
+	{"CEOT", CEOT},
+#endif
+#ifdef CERASE
+	{"CERASE", CERASE},
+#endif
+#ifdef CESC
+	{"CESC", CESC},
+#endif
+#ifdef CFLUSH
+	{"CFLUSH", CFLUSH},
+#endif
+#ifdef CINTR
+	{"CINTR", CINTR},
+#endif
+#ifdef CKILL
+	{"CKILL", CKILL},
+#endif
+#ifdef CLNEXT
+	{"CLNEXT", CLNEXT},
+#endif
+#ifdef CNUL
+	{"CNUL", CNUL},
+#endif
+#ifdef COMMON
+	{"COMMON", COMMON},
+#endif
+#ifdef CQUIT
+	{"CQUIT", CQUIT},
+#endif
+#ifdef CRPRNT
+	{"CRPRNT", CRPRNT},
+#endif
+#ifdef CSTART
+	{"CSTART", CSTART},
+#endif
+#ifdef CSTOP
+	{"CSTOP", CSTOP},
+#endif
+#ifdef CSUSP
+	{"CSUSP", CSUSP},
+#endif
+#ifdef CSWTCH
+	{"CSWTCH", CSWTCH},
+#endif
+#ifdef CWERASE
+	{"CWERASE", CWERASE},
+#endif
+#ifdef EXTA
+	{"EXTA", EXTA},
+#endif
+#ifdef EXTB
+	{"EXTB", EXTB},
+#endif
+#ifdef FIOASYNC
+	{"FIOASYNC", FIOASYNC},
+#endif
+#ifdef FIOCLEX
+	{"FIOCLEX", FIOCLEX},
+#endif
+#ifdef FIONBIO
+	{"FIONBIO", FIONBIO},
+#endif
+#ifdef FIONCLEX
+	{"FIONCLEX", FIONCLEX},
+#endif
+#ifdef FIONREAD
+	{"FIONREAD", FIONREAD},
+#endif
+#ifdef IBSHIFT
+	{"IBSHIFT", IBSHIFT},
+#endif
+#ifdef INIT_C_CC
+	{"INIT_C_CC", INIT_C_CC},
+#endif
+#ifdef IOCSIZE_MASK
+	{"IOCSIZE_MASK", IOCSIZE_MASK},
+#endif
+#ifdef IOCSIZE_SHIFT
+	{"IOCSIZE_SHIFT", IOCSIZE_SHIFT},
+#endif
+#ifdef NCC
+	{"NCC", NCC},
+#endif
+#ifdef NCCS
+	{"NCCS", NCCS},
+#endif
+#ifdef NSWTCH
+	{"NSWTCH", NSWTCH},
+#endif
+#ifdef N_MOUSE
+	{"N_MOUSE", N_MOUSE},
+#endif
+#ifdef N_PPP
+	{"N_PPP", N_PPP},
+#endif
+#ifdef N_SLIP
+	{"N_SLIP", N_SLIP},
+#endif
+#ifdef N_STRIP
+	{"N_STRIP", N_STRIP},
+#endif
+#ifdef N_TTY
+	{"N_TTY", N_TTY},
+#endif
+#ifdef TCFLSH
+	{"TCFLSH", TCFLSH},
+#endif
+#ifdef TCGETA
+	{"TCGETA", TCGETA},
+#endif
+#ifdef TCGETS
+	{"TCGETS", TCGETS},
+#endif
+#ifdef TCSBRK
+	{"TCSBRK", TCSBRK},
+#endif
+#ifdef TCSBRKP
+	{"TCSBRKP", TCSBRKP},
+#endif
+#ifdef TCSETA
+	{"TCSETA", TCSETA},
+#endif
+#ifdef TCSETAF
+	{"TCSETAF", TCSETAF},
+#endif
+#ifdef TCSETAW
+	{"TCSETAW", TCSETAW},
+#endif
+#ifdef TCSETS
+	{"TCSETS", TCSETS},
+#endif
+#ifdef TCSETSF
+	{"TCSETSF", TCSETSF},
+#endif
+#ifdef TCSETSW
+	{"TCSETSW", TCSETSW},
+#endif
+#ifdef TCXONC
+	{"TCXONC", TCXONC},
+#endif
+#ifdef TIOCCONS
+	{"TIOCCONS", TIOCCONS},
+#endif
+#ifdef TIOCEXCL
+	{"TIOCEXCL", TIOCEXCL},
+#endif
+#ifdef TIOCGETD
+	{"TIOCGETD", TIOCGETD},
+#endif
+#ifdef TIOCGICOUNT
+	{"TIOCGICOUNT", TIOCGICOUNT},
+#endif
+#ifdef TIOCGLCKTRMIOS
+	{"TIOCGLCKTRMIOS", TIOCGLCKTRMIOS},
+#endif
+#ifdef TIOCGPGRP
+	{"TIOCGPGRP", TIOCGPGRP},
+#endif
+#ifdef TIOCGSERIAL
+	{"TIOCGSERIAL", TIOCGSERIAL},
+#endif
+#ifdef TIOCGSOFTCAR
+	{"TIOCGSOFTCAR", TIOCGSOFTCAR},
+#endif
+#ifdef TIOCGWINSZ
+	{"TIOCGWINSZ", TIOCGWINSZ},
+#endif
+#ifdef TIOCINQ
+	{"TIOCINQ", TIOCINQ},
+#endif
+#ifdef TIOCLINUX
+	{"TIOCLINUX", TIOCLINUX},
+#endif
+#ifdef TIOCMBIC
+	{"TIOCMBIC", TIOCMBIC},
+#endif
+#ifdef TIOCMBIS
+	{"TIOCMBIS", TIOCMBIS},
+#endif
+#ifdef TIOCMGET
+	{"TIOCMGET", TIOCMGET},
+#endif
+#ifdef TIOCMIWAIT
+	{"TIOCMIWAIT", TIOCMIWAIT},
+#endif
+#ifdef TIOCMSET
+	{"TIOCMSET", TIOCMSET},
+#endif
+#ifdef TIOCM_CAR
+	{"TIOCM_CAR", TIOCM_CAR},
+#endif
+#ifdef TIOCM_CD
+	{"TIOCM_CD", TIOCM_CD},
+#endif
+#ifdef TIOCM_CTS
+	{"TIOCM_CTS", TIOCM_CTS},
+#endif
+#ifdef TIOCM_DSR
+	{"TIOCM_DSR", TIOCM_DSR},
+#endif
+#ifdef TIOCM_DTR
+	{"TIOCM_DTR", TIOCM_DTR},
+#endif
+#ifdef TIOCM_LE
+	{"TIOCM_LE", TIOCM_LE},
+#endif
+#ifdef TIOCM_RI
+	{"TIOCM_RI", TIOCM_RI},
+#endif
+#ifdef TIOCM_RNG
+	{"TIOCM_RNG", TIOCM_RNG},
+#endif
+#ifdef TIOCM_RTS
+	{"TIOCM_RTS", TIOCM_RTS},
+#endif
+#ifdef TIOCM_SR
+	{"TIOCM_SR", TIOCM_SR},
+#endif
+#ifdef TIOCM_ST
+	{"TIOCM_ST", TIOCM_ST},
+#endif
+#ifdef TIOCNOTTY
+	{"TIOCNOTTY", TIOCNOTTY},
+#endif
+#ifdef TIOCNXCL
+	{"TIOCNXCL", TIOCNXCL},
+#endif
+#ifdef TIOCOUTQ
+	{"TIOCOUTQ", TIOCOUTQ},
+#endif
+#ifdef TIOCPKT
+	{"TIOCPKT", TIOCPKT},
+#endif
+#ifdef TIOCPKT_DATA
+	{"TIOCPKT_DATA", TIOCPKT_DATA},
+#endif
+#ifdef TIOCPKT_DOSTOP
+	{"TIOCPKT_DOSTOP", TIOCPKT_DOSTOP},
+#endif
+#ifdef TIOCPKT_FLUSHREAD
+	{"TIOCPKT_FLUSHREAD", TIOCPKT_FLUSHREAD},
+#endif
+#ifdef TIOCPKT_FLUSHWRITE
+	{"TIOCPKT_FLUSHWRITE", TIOCPKT_FLUSHWRITE},
+#endif
+#ifdef TIOCPKT_NOSTOP
+	{"TIOCPKT_NOSTOP", TIOCPKT_NOSTOP},
+#endif
+#ifdef TIOCPKT_START
+	{"TIOCPKT_START", TIOCPKT_START},
+#endif
+#ifdef TIOCPKT_STOP
+	{"TIOCPKT_STOP", TIOCPKT_STOP},
+#endif
+#ifdef TIOCSCTTY
+	{"TIOCSCTTY", TIOCSCTTY},
+#endif
+#ifdef TIOCSERCONFIG
+	{"TIOCSERCONFIG", TIOCSERCONFIG},
+#endif
+#ifdef TIOCSERGETLSR
+	{"TIOCSERGETLSR", TIOCSERGETLSR},
+#endif
+#ifdef TIOCSERGETMULTI
+	{"TIOCSERGETMULTI", TIOCSERGETMULTI},
+#endif
+#ifdef TIOCSERGSTRUCT
+	{"TIOCSERGSTRUCT", TIOCSERGSTRUCT},
+#endif
+#ifdef TIOCSERGWILD
+	{"TIOCSERGWILD", TIOCSERGWILD},
+#endif
+#ifdef TIOCSERSETMULTI
+	{"TIOCSERSETMULTI", TIOCSERSETMULTI},
+#endif
+#ifdef TIOCSERSWILD
+	{"TIOCSERSWILD", TIOCSERSWILD},
+#endif
+#ifdef TIOCSER_TEMT
+	{"TIOCSER_TEMT", TIOCSER_TEMT},
+#endif
+#ifdef TIOCSETD
+	{"TIOCSETD", TIOCSETD},
+#endif
+#ifdef TIOCSLCKTRMIOS
+	{"TIOCSLCKTRMIOS", TIOCSLCKTRMIOS},
+#endif
+#ifdef TIOCSPGRP
+	{"TIOCSPGRP", TIOCSPGRP},
+#endif
+#ifdef TIOCSSERIAL
+	{"TIOCSSERIAL", TIOCSSERIAL},
+#endif
+#ifdef TIOCSSOFTCAR
+	{"TIOCSSOFTCAR", TIOCSSOFTCAR},
+#endif
+#ifdef TIOCSTI
+	{"TIOCSTI", TIOCSTI},
+#endif
+#ifdef TIOCSWINSZ
+	{"TIOCSWINSZ", TIOCSWINSZ},
+#endif
+#ifdef TIOCTTYGSTRUCT
+	{"TIOCTTYGSTRUCT", TIOCTTYGSTRUCT},
+#endif
+
+	/* sentinel */
+	{NULL, 0}
+};
+
+
+PyMODINIT_FUNC
+PyInit_termios(void)
+{
+	PyObject *m;
+	struct constant *constant = termios_constants;
+
+	m = Py_InitModule4("termios", termios_methods, termios__doc__,
+                           (PyObject *)NULL, PYTHON_API_VERSION);
+	if (m == NULL)
+		return;
+
+	if (TermiosError == NULL) {
+		TermiosError = PyErr_NewException("termios.error", NULL, NULL);
+	}
+	Py_INCREF(TermiosError);
+	PyModule_AddObject(m, "error", TermiosError);
+
+	while (constant->name != NULL) {
+		PyModule_AddIntConstant(m, constant->name, constant->value);
+		++constant;
+	}
+}

Added: vendor/Python/current/Modules/testcapi_long.h
===================================================================
--- vendor/Python/current/Modules/testcapi_long.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/testcapi_long.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,166 @@
+/* Poor-man's template.  Macros used:
+   TESTNAME	name of the test (like test_long_api_inner)
+   TYPENAME	the signed type (like long)
+   F_S_TO_PY	convert signed to pylong; TYPENAME -> PyObject*
+   F_PY_TO_S	convert pylong to signed; PyObject* -> TYPENAME
+   F_U_TO_PY	convert unsigned to pylong; unsigned TYPENAME -> PyObject*
+   F_PY_TO_U    convert pylong to unsigned; PyObject* -> unsigned TYPENAME
+*/
+
+static PyObject *
+TESTNAME(PyObject *error(const char*))
+{
+	const int NBITS = sizeof(TYPENAME) * 8;
+	unsigned TYPENAME base;
+	PyObject *pyresult;
+	int i;
+
+	/* Note:  This test lets PyObjects leak if an error is raised.  Since
+	   an error should never be raised, leaks are impossible <wink>. */
+
+	/* Test native -> PyLong -> native roundtrip identity.
+	 * Generate all powers of 2, and test them and their negations,
+	 * plus the numbers +-1 off from them.
+	 */
+	base = 1;
+	for (i = 0;
+	     i < NBITS + 1;  /* on last, base overflows to 0 */
+	     ++i, base <<= 1)
+	{
+		int j;
+		for (j = 0; j < 6; ++j) {
+			TYPENAME in, out;
+			unsigned TYPENAME uin, uout;
+
+			/* For 0, 1, 2 use base; for 3, 4, 5 use -base */
+			uin = j < 3 ? base
+				    : (unsigned TYPENAME)(-(TYPENAME)base);
+
+			/* For 0 & 3, subtract 1.
+			 * For 1 & 4, leave alone.
+			 * For 2 & 5, add 1.
+			 */
+			uin += (unsigned TYPENAME)(TYPENAME)(j % 3 - 1);
+
+			pyresult = F_U_TO_PY(uin);
+			if (pyresult == NULL)
+				return error(
+				 "unsigned unexpected null result");
+
+			uout = F_PY_TO_U(pyresult);
+			if (uout == (unsigned TYPENAME)-1 && PyErr_Occurred())
+				return error(
+					"unsigned unexpected -1 result");
+			if (uout != uin)
+				return error(
+					"unsigned output != input");
+			UNBIND(pyresult);
+
+			in = (TYPENAME)uin;
+			pyresult = F_S_TO_PY(in);
+			if (pyresult == NULL)
+				return error(
+					"signed unexpected null result");
+
+			out = F_PY_TO_S(pyresult);
+			if (out == (TYPENAME)-1 && PyErr_Occurred())
+				return error(
+					"signed unexpected -1 result");
+			if (out != in)
+				return error(
+					"signed output != input");
+			UNBIND(pyresult);
+		}
+	}
+
+	/* Overflow tests.  The loop above ensured that all limit cases that
+	 * should not overflow don't overflow, so all we need to do here is
+	 * provoke one-over-the-limit cases (not exhaustive, but sharp).
+	 */
+	{
+		PyObject *one, *x, *y;
+		TYPENAME out;
+		unsigned TYPENAME uout;
+
+		one = PyLong_FromLong(1);
+		if (one == NULL)
+			return error(
+				"unexpected NULL from PyLong_FromLong");
+
+		/* Unsigned complains about -1? */
+		x = PyNumber_Negative(one);
+		if (x == NULL)
+			return error(
+				"unexpected NULL from PyNumber_Negative");
+
+		uout = F_PY_TO_U(x);
+		if (uout != (unsigned TYPENAME)-1 || !PyErr_Occurred())
+			return error(
+				"PyLong_AsUnsignedXXX(-1) didn't complain");
+		PyErr_Clear();
+		UNBIND(x);
+
+		/* Unsigned complains about 2**NBITS? */
+		y = PyLong_FromLong((long)NBITS);
+		if (y == NULL)
+			return error(
+				"unexpected NULL from PyLong_FromLong");
+
+		x = PyNumber_Lshift(one, y); /* 1L << NBITS, == 2**NBITS */
+		UNBIND(y);
+		if (x == NULL)
+			return error(
+				"unexpected NULL from PyNumber_Lshift");
+
+  		uout = F_PY_TO_U(x);
+		if (uout != (unsigned TYPENAME)-1 || !PyErr_Occurred())
+			return error(
+				"PyLong_AsUnsignedXXX(2**NBITS) didn't "
+				"complain");
+		PyErr_Clear();
+
+		/* Signed complains about 2**(NBITS-1)?
+		   x still has 2**NBITS. */
+		y = PyNumber_Rshift(x, one); /* 2**(NBITS-1) */
+		UNBIND(x);
+		if (y == NULL)
+			return error(
+				"unexpected NULL from PyNumber_Rshift");
+
+		out = F_PY_TO_S(y);
+		if (out != (TYPENAME)-1 || !PyErr_Occurred())
+			return error(
+				"PyLong_AsXXX(2**(NBITS-1)) didn't "
+				"complain");
+		PyErr_Clear();
+
+		/* Signed complains about -2**(NBITS-1)-1?;
+		   y still has 2**(NBITS-1). */
+		x = PyNumber_Negative(y);  /* -(2**(NBITS-1)) */
+		UNBIND(y);
+		if (x == NULL)
+			return error(
+				"unexpected NULL from PyNumber_Negative");
+
+		y = PyNumber_Subtract(x, one); /* -(2**(NBITS-1))-1 */
+		UNBIND(x);
+		if (y == NULL)
+			return error(
+				"unexpected NULL from PyNumber_Subtract");
+
+		out = F_PY_TO_S(y);
+		if (out != (TYPENAME)-1 || !PyErr_Occurred())
+			return error(
+				"PyLong_AsXXX(-2**(NBITS-1)-1) didn't "
+				"complain");
+		PyErr_Clear();
+		UNBIND(y);
+
+		Py_XDECREF(x);
+		Py_XDECREF(y);
+		Py_DECREF(one);
+	}
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}

Added: vendor/Python/current/Modules/threadmodule.c
===================================================================
--- vendor/Python/current/Modules/threadmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/threadmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,720 @@
+
+/* Thread module */
+/* Interface to Sjoerd's portable C thread library */
+
+#include "Python.h"
+
+#ifndef WITH_THREAD
+#error "Error!  The rest of Python is not compiled with thread support."
+#error "Rerun configure, adding a --with-threads option."
+#error "Then run `make clean' followed by `make'."
+#endif
+
+#include "pythread.h"
+
+static PyObject *ThreadError;
+
+
+/* Lock objects */
+
+typedef struct {
+	PyObject_HEAD
+	PyThread_type_lock lock_lock;
+} lockobject;
+
+static void
+lock_dealloc(lockobject *self)
+{
+	assert(self->lock_lock);
+	/* Unlock the lock so it's safe to free it */
+	PyThread_acquire_lock(self->lock_lock, 0);
+	PyThread_release_lock(self->lock_lock);
+	
+	PyThread_free_lock(self->lock_lock);
+	PyObject_Del(self);
+}
+
+static PyObject *
+lock_PyThread_acquire_lock(lockobject *self, PyObject *args)
+{
+	int i = 1;
+
+	if (!PyArg_ParseTuple(args, "|i:acquire", &i))
+		return NULL;
+
+	Py_BEGIN_ALLOW_THREADS
+	i = PyThread_acquire_lock(self->lock_lock, i);
+	Py_END_ALLOW_THREADS
+
+	return PyBool_FromLong((long)i);
+}
+
+PyDoc_STRVAR(acquire_doc,
+"acquire([wait]) -> None or bool\n\
+(acquire_lock() is an obsolete synonym)\n\
+\n\
+Lock the lock.  Without argument, this blocks if the lock is already\n\
+locked (even by the same thread), waiting for another thread to release\n\
+the lock, and return None once the lock is acquired.\n\
+With an argument, this will only block if the argument is true,\n\
+and the return value reflects whether the lock is acquired.\n\
+The blocking operation is not interruptible.");
+
+static PyObject *
+lock_PyThread_release_lock(lockobject *self)
+{
+	/* Sanity check: the lock must be locked */
+	if (PyThread_acquire_lock(self->lock_lock, 0)) {
+		PyThread_release_lock(self->lock_lock);
+		PyErr_SetString(ThreadError, "release unlocked lock");
+		return NULL;
+	}
+
+	PyThread_release_lock(self->lock_lock);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(release_doc,
+"release()\n\
+(release_lock() is an obsolete synonym)\n\
+\n\
+Release the lock, allowing another thread that is blocked waiting for\n\
+the lock to acquire the lock.  The lock must be in the locked state,\n\
+but it needn't be locked by the same thread that unlocks it.");
+
+static PyObject *
+lock_locked_lock(lockobject *self)
+{
+	if (PyThread_acquire_lock(self->lock_lock, 0)) {
+		PyThread_release_lock(self->lock_lock);
+		return PyBool_FromLong(0L);
+	}
+	return PyBool_FromLong(1L);
+}
+
+PyDoc_STRVAR(locked_doc,
+"locked() -> bool\n\
+(locked_lock() is an obsolete synonym)\n\
+\n\
+Return whether the lock is in the locked state.");
+
+static PyMethodDef lock_methods[] = {
+	{"acquire_lock", (PyCFunction)lock_PyThread_acquire_lock, 
+	 METH_VARARGS, acquire_doc},
+	{"acquire",      (PyCFunction)lock_PyThread_acquire_lock, 
+	 METH_VARARGS, acquire_doc},
+	{"release_lock", (PyCFunction)lock_PyThread_release_lock, 
+	 METH_NOARGS, release_doc},
+	{"release",      (PyCFunction)lock_PyThread_release_lock, 
+	 METH_NOARGS, release_doc},
+	{"locked_lock",  (PyCFunction)lock_locked_lock,  
+	 METH_NOARGS, locked_doc},
+	{"locked",       (PyCFunction)lock_locked_lock,  
+	 METH_NOARGS, locked_doc},
+	{"__enter__",    (PyCFunction)lock_PyThread_acquire_lock,
+	 METH_VARARGS, acquire_doc},
+	{"__exit__",    (PyCFunction)lock_PyThread_release_lock,
+	 METH_VARARGS, release_doc},
+	{NULL,           NULL}		/* sentinel */
+};
+
+static PyObject *
+lock_getattr(lockobject *self, char *name)
+{
+	return Py_FindMethod(lock_methods, (PyObject *)self, name);
+}
+
+static PyTypeObject Locktype = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,				/*ob_size*/
+	"thread.lock",			/*tp_name*/
+	sizeof(lockobject),		/*tp_size*/
+	0,				/*tp_itemsize*/
+	/* methods */
+	(destructor)lock_dealloc,	/*tp_dealloc*/
+	0,				/*tp_print*/
+	(getattrfunc)lock_getattr,	/*tp_getattr*/
+	0,				/*tp_setattr*/
+	0,				/*tp_compare*/
+	0,				/*tp_repr*/
+};
+
+static lockobject *
+newlockobject(void)
+{
+	lockobject *self;
+	self = PyObject_New(lockobject, &Locktype);
+	if (self == NULL)
+		return NULL;
+	self->lock_lock = PyThread_allocate_lock();
+	if (self->lock_lock == NULL) {
+		PyObject_Del(self);
+		self = NULL;
+		PyErr_SetString(ThreadError, "can't allocate lock");
+	}
+	return self;
+}
+
+/* Thread-local objects */
+
+#include "structmember.h"
+
+typedef struct {
+	PyObject_HEAD
+	PyObject *key;
+	PyObject *args;
+	PyObject *kw;
+	PyObject *dict;
+} localobject;
+
+static PyObject *
+local_new(PyTypeObject *type, PyObject *args, PyObject *kw)
+{
+	localobject *self;
+	PyObject *tdict;
+
+	if (type->tp_init == PyBaseObject_Type.tp_init
+	    && ((args && PyObject_IsTrue(args))
+		|| (kw && PyObject_IsTrue(kw)))) {
+		PyErr_SetString(PyExc_TypeError,
+			  "Initialization arguments are not supported");
+		return NULL;
+	}
+
+	self = (localobject *)type->tp_alloc(type, 0);
+	if (self == NULL)
+		return NULL;
+
+	Py_XINCREF(args);
+	self->args = args;
+	Py_XINCREF(kw);
+	self->kw = kw;
+	self->dict = NULL;	/* making sure */
+	self->key = PyString_FromFormat("thread.local.%p", self);
+	if (self->key == NULL) 
+		goto err;
+
+	self->dict = PyDict_New();
+	if (self->dict == NULL)
+		goto err;
+
+	tdict = PyThreadState_GetDict();
+	if (tdict == NULL) {
+		PyErr_SetString(PyExc_SystemError,
+				"Couldn't get thread-state dictionary");
+		goto err;
+	}
+
+	if (PyDict_SetItem(tdict, self->key, self->dict) < 0)
+		goto err;
+
+	return (PyObject *)self;
+
+  err:
+	Py_DECREF(self);
+	return NULL;
+}
+
+static int
+local_traverse(localobject *self, visitproc visit, void *arg)
+{
+	Py_VISIT(self->args);
+	Py_VISIT(self->kw);
+	Py_VISIT(self->dict);
+	return 0;
+}
+
+static int
+local_clear(localobject *self)
+{
+	Py_CLEAR(self->key);
+	Py_CLEAR(self->args);
+	Py_CLEAR(self->kw);
+	Py_CLEAR(self->dict);
+	return 0;
+}
+
+static void
+local_dealloc(localobject *self)
+{
+	PyThreadState *tstate;
+	if (self->key
+	    && (tstate = PyThreadState_Get())
+	    && tstate->interp) {
+		for(tstate = PyInterpreterState_ThreadHead(tstate->interp);
+		    tstate;
+		    tstate = PyThreadState_Next(tstate)) 
+			if (tstate->dict &&
+			    PyDict_GetItem(tstate->dict, self->key))
+				PyDict_DelItem(tstate->dict, self->key);
+	}
+
+	local_clear(self);
+	self->ob_type->tp_free((PyObject*)self);
+}
+
+static PyObject *
+_ldict(localobject *self)
+{
+	PyObject *tdict, *ldict;
+
+	tdict = PyThreadState_GetDict();
+	if (tdict == NULL) {
+		PyErr_SetString(PyExc_SystemError,
+				"Couldn't get thread-state dictionary");
+		return NULL;
+	}
+
+	ldict = PyDict_GetItem(tdict, self->key);
+	if (ldict == NULL) {
+		ldict = PyDict_New(); /* we own ldict */
+
+		if (ldict == NULL)
+			return NULL;
+		else {
+			int i = PyDict_SetItem(tdict, self->key, ldict);
+			Py_DECREF(ldict); /* now ldict is borrowed */
+			if (i < 0) 
+				return NULL;
+		}
+
+		Py_CLEAR(self->dict);
+		Py_INCREF(ldict);
+		self->dict = ldict; /* still borrowed */
+
+		if (self->ob_type->tp_init != PyBaseObject_Type.tp_init &&
+		    self->ob_type->tp_init((PyObject*)self, 
+					   self->args, self->kw) < 0) {
+			/* we need to get rid of ldict from thread so
+			   we create a new one the next time we do an attr
+			   acces */
+			PyDict_DelItem(tdict, self->key);
+			return NULL;
+		}
+		
+	}
+	else if (self->dict != ldict) {
+		Py_CLEAR(self->dict);
+		Py_INCREF(ldict);
+		self->dict = ldict;
+	}
+
+	return ldict;
+}
+
+static int
+local_setattro(localobject *self, PyObject *name, PyObject *v)
+{
+	PyObject *ldict;
+	
+	ldict = _ldict(self);
+	if (ldict == NULL) 
+		return -1;
+
+	return PyObject_GenericSetAttr((PyObject *)self, name, v);
+}
+
+static PyObject *
+local_getdict(localobject *self, void *closure)
+{
+	if (self->dict == NULL) {
+		PyErr_SetString(PyExc_AttributeError, "__dict__");
+		return NULL;
+	}
+
+	Py_INCREF(self->dict);
+	return self->dict;
+}
+
+static PyGetSetDef local_getset[] = {
+	{"__dict__", (getter)local_getdict, (setter)NULL,
+	 "Local-data dictionary", NULL},
+	{NULL}  /* Sentinel */
+};
+
+static PyObject *local_getattro(localobject *, PyObject *);
+
+static PyTypeObject localtype = {
+	PyObject_HEAD_INIT(NULL)
+	/* ob_size           */ 0,
+	/* tp_name           */ "thread._local",
+	/* tp_basicsize      */ sizeof(localobject),
+	/* tp_itemsize       */ 0,
+	/* tp_dealloc        */ (destructor)local_dealloc,
+	/* tp_print          */ 0,
+	/* tp_getattr        */ 0,
+	/* tp_setattr        */ 0,
+	/* tp_compare        */ 0,
+	/* tp_repr           */ 0,
+	/* tp_as_number      */ 0,
+	/* tp_as_sequence    */ 0,
+	/* tp_as_mapping     */ 0,
+	/* tp_hash           */ 0,
+	/* tp_call           */ 0,
+	/* tp_str            */ 0,
+	/* tp_getattro       */ (getattrofunc)local_getattro,
+	/* tp_setattro       */ (setattrofunc)local_setattro,
+	/* tp_as_buffer      */ 0,
+	/* tp_flags          */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+	/* tp_doc            */ "Thread-local data",
+	/* tp_traverse       */ (traverseproc)local_traverse,
+	/* tp_clear          */ (inquiry)local_clear,
+	/* tp_richcompare    */ 0,
+	/* tp_weaklistoffset */ 0,
+	/* tp_iter           */ 0,
+	/* tp_iternext       */ 0,
+	/* tp_methods        */ 0,
+	/* tp_members        */ 0,
+	/* tp_getset         */ local_getset,
+	/* tp_base           */ 0,
+	/* tp_dict           */ 0, /* internal use */
+	/* tp_descr_get      */ 0,
+	/* tp_descr_set      */ 0,
+	/* tp_dictoffset     */ offsetof(localobject, dict),
+	/* tp_init           */ 0,
+	/* tp_alloc          */ 0,
+	/* tp_new            */ local_new,
+	/* tp_free           */ 0, /* Low-level free-mem routine */
+	/* tp_is_gc          */ 0, /* For PyObject_IS_GC */
+};
+
+static PyObject *
+local_getattro(localobject *self, PyObject *name)
+{
+	PyObject *ldict, *value;
+
+	ldict = _ldict(self);
+	if (ldict == NULL) 
+		return NULL;
+
+	if (self->ob_type != &localtype)
+		/* use generic lookup for subtypes */
+		return PyObject_GenericGetAttr((PyObject *)self, name);
+
+	/* Optimization: just look in dict ourselves */
+	value = PyDict_GetItem(ldict, name);
+	if (value == NULL) 
+		/* Fall back on generic to get __class__ and __dict__ */
+		return PyObject_GenericGetAttr((PyObject *)self, name);
+
+	Py_INCREF(value);
+	return value;
+}
+
+/* Module functions */
+
+struct bootstate {
+	PyInterpreterState *interp;
+	PyObject *func;
+	PyObject *args;
+	PyObject *keyw;
+};
+
+static void
+t_bootstrap(void *boot_raw)
+{
+	struct bootstate *boot = (struct bootstate *) boot_raw;
+	PyThreadState *tstate;
+	PyObject *res;
+
+	tstate = PyThreadState_New(boot->interp);
+
+	PyEval_AcquireThread(tstate);
+	res = PyEval_CallObjectWithKeywords(
+		boot->func, boot->args, boot->keyw);
+	if (res == NULL) {
+		if (PyErr_ExceptionMatches(PyExc_SystemExit))
+			PyErr_Clear();
+		else {
+			PyObject *file;
+			PySys_WriteStderr(
+				"Unhandled exception in thread started by ");
+			file = PySys_GetObject("stderr");
+			if (file)
+				PyFile_WriteObject(boot->func, file, 0);
+			else
+				PyObject_Print(boot->func, stderr, 0);
+			PySys_WriteStderr("\n");
+			PyErr_PrintEx(0);
+		}
+	}
+	else
+		Py_DECREF(res);
+	Py_DECREF(boot->func);
+	Py_DECREF(boot->args);
+	Py_XDECREF(boot->keyw);
+	PyMem_DEL(boot_raw);
+	PyThreadState_Clear(tstate);
+	PyThreadState_DeleteCurrent();
+	PyThread_exit_thread();
+}
+
+static PyObject *
+thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
+{
+	PyObject *func, *args, *keyw = NULL;
+	struct bootstate *boot;
+	long ident;
+
+	if (!PyArg_UnpackTuple(fargs, "start_new_thread", 2, 3,
+		               &func, &args, &keyw))
+		return NULL;
+	if (!PyCallable_Check(func)) {
+		PyErr_SetString(PyExc_TypeError,
+				"first arg must be callable");
+		return NULL;
+	}
+	if (!PyTuple_Check(args)) {
+		PyErr_SetString(PyExc_TypeError,
+				"2nd arg must be a tuple");
+		return NULL;
+	}
+	if (keyw != NULL && !PyDict_Check(keyw)) {
+		PyErr_SetString(PyExc_TypeError,
+				"optional 3rd arg must be a dictionary");
+		return NULL;
+	}
+	boot = PyMem_NEW(struct bootstate, 1);
+	if (boot == NULL)
+		return PyErr_NoMemory();
+	boot->interp = PyThreadState_GET()->interp;
+	boot->func = func;
+	boot->args = args;
+	boot->keyw = keyw;
+	Py_INCREF(func);
+	Py_INCREF(args);
+	Py_XINCREF(keyw);
+	PyEval_InitThreads(); /* Start the interpreter's thread-awareness */
+	ident = PyThread_start_new_thread(t_bootstrap, (void*) boot);
+	if (ident == -1) {
+		PyErr_SetString(ThreadError, "can't start new thread");
+		Py_DECREF(func);
+		Py_DECREF(args);
+		Py_XDECREF(keyw);
+		PyMem_DEL(boot);
+		return NULL;
+	}
+	return PyInt_FromLong(ident);
+}
+
+PyDoc_STRVAR(start_new_doc,
+"start_new_thread(function, args[, kwargs])\n\
+(start_new() is an obsolete synonym)\n\
+\n\
+Start a new thread and return its identifier.  The thread will call the\n\
+function with positional arguments from the tuple args and keyword arguments\n\
+taken from the optional dictionary kwargs.  The thread exits when the\n\
+function returns; the return value is ignored.  The thread will also exit\n\
+when the function raises an unhandled exception; a stack trace will be\n\
+printed unless the exception is SystemExit.\n");
+
+static PyObject *
+thread_PyThread_exit_thread(PyObject *self)
+{
+	PyErr_SetNone(PyExc_SystemExit);
+	return NULL;
+}
+
+PyDoc_STRVAR(exit_doc,
+"exit()\n\
+(PyThread_exit_thread() is an obsolete synonym)\n\
+\n\
+This is synonymous to ``raise SystemExit''.  It will cause the current\n\
+thread to exit silently unless the exception is caught.");
+
+static PyObject *
+thread_PyThread_interrupt_main(PyObject * self)
+{
+	PyErr_SetInterrupt();
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(interrupt_doc,
+"interrupt_main()\n\
+\n\
+Raise a KeyboardInterrupt in the main thread.\n\
+A subthread can use this function to interrupt the main thread."
+);
+
+#ifndef NO_EXIT_PROG
+static PyObject *
+thread_PyThread_exit_prog(PyObject *self, PyObject *args)
+{
+	int sts;
+	if (!PyArg_ParseTuple(args, "i:exit_prog", &sts))
+		return NULL;
+	Py_Exit(sts); /* Calls PyThread_exit_prog(sts) or _PyThread_exit_prog(sts) */
+	for (;;) { } /* Should not be reached */
+}
+#endif
+
+static lockobject *newlockobject(void);
+
+static PyObject *
+thread_PyThread_allocate_lock(PyObject *self)
+{
+	return (PyObject *) newlockobject();
+}
+
+PyDoc_STRVAR(allocate_doc,
+"allocate_lock() -> lock object\n\
+(allocate() is an obsolete synonym)\n\
+\n\
+Create a new lock object.  See LockType.__doc__ for information about locks.");
+
+static PyObject *
+thread_get_ident(PyObject *self)
+{
+	long ident;
+	ident = PyThread_get_thread_ident();
+	if (ident == -1) {
+		PyErr_SetString(ThreadError, "no current thread ident");
+		return NULL;
+	}
+	return PyInt_FromLong(ident);
+}
+
+PyDoc_STRVAR(get_ident_doc,
+"get_ident() -> integer\n\
+\n\
+Return a non-zero integer that uniquely identifies the current thread\n\
+amongst other threads that exist simultaneously.\n\
+This may be used to identify per-thread resources.\n\
+Even though on some platforms threads identities may appear to be\n\
+allocated consecutive numbers starting at 1, this behavior should not\n\
+be relied upon, and the number should be seen purely as a magic cookie.\n\
+A thread's identity may be reused for another thread after it exits.");
+
+static PyObject *
+thread_stack_size(PyObject *self, PyObject *args)
+{
+	size_t old_size;
+	Py_ssize_t new_size = 0;
+	int rc;
+
+	if (!PyArg_ParseTuple(args, "|n:stack_size", &new_size))
+		return NULL;
+
+	if (new_size < 0) {
+		PyErr_SetString(PyExc_ValueError,
+				"size must be 0 or a positive value");
+		return NULL;
+	}
+
+	old_size = PyThread_get_stacksize();
+
+	rc = PyThread_set_stacksize((size_t) new_size);
+	if (rc == -1) {
+		PyErr_Format(PyExc_ValueError,
+			     "size not valid: %zd bytes",
+			     new_size);
+		return NULL;
+	}
+	if (rc == -2) {
+		PyErr_SetString(ThreadError,
+				"setting stack size not supported");
+		return NULL;
+	}
+
+	return PyInt_FromSsize_t((Py_ssize_t) old_size);
+}
+
+PyDoc_STRVAR(stack_size_doc,
+"stack_size([size]) -> size\n\
+\n\
+Return the thread stack size used when creating new threads.  The\n\
+optional size argument specifies the stack size (in bytes) to be used\n\
+for subsequently created threads, and must be 0 (use platform or\n\
+configured default) or a positive integer value of at least 32,768 (32k).\n\
+If changing the thread stack size is unsupported, a ThreadError\n\
+exception is raised.  If the specified size is invalid, a ValueError\n\
+exception is raised, and the stack size is unmodified.  32k bytes\n\
+ currently the minimum supported stack size value to guarantee\n\
+sufficient stack space for the interpreter itself.\n\
+\n\
+Note that some platforms may have particular restrictions on values for\n\
+the stack size, such as requiring a minimum stack size larger than 32kB or\n\
+requiring allocation in multiples of the system memory page size\n\
+- platform documentation should be referred to for more information\n\
+(4kB pages are common; using multiples of 4096 for the stack size is\n\
+the suggested approach in the absence of more specific information).");
+
+static PyMethodDef thread_methods[] = {
+	{"start_new_thread",	(PyCFunction)thread_PyThread_start_new_thread,
+	                        METH_VARARGS,
+				start_new_doc},
+	{"start_new",		(PyCFunction)thread_PyThread_start_new_thread, 
+	                        METH_VARARGS,
+				start_new_doc},
+	{"allocate_lock",	(PyCFunction)thread_PyThread_allocate_lock, 
+	 METH_NOARGS, allocate_doc},
+	{"allocate",		(PyCFunction)thread_PyThread_allocate_lock, 
+	 METH_NOARGS, allocate_doc},
+	{"exit_thread",		(PyCFunction)thread_PyThread_exit_thread, 
+	 METH_NOARGS, exit_doc},
+	{"exit",		(PyCFunction)thread_PyThread_exit_thread, 
+	 METH_NOARGS, exit_doc},
+	{"interrupt_main",	(PyCFunction)thread_PyThread_interrupt_main,
+	 METH_NOARGS, interrupt_doc},
+	{"get_ident",		(PyCFunction)thread_get_ident, 
+	 METH_NOARGS, get_ident_doc},
+	{"stack_size",		(PyCFunction)thread_stack_size,
+				METH_VARARGS,
+				stack_size_doc},
+#ifndef NO_EXIT_PROG
+	{"exit_prog",		(PyCFunction)thread_PyThread_exit_prog,
+	 METH_VARARGS},
+#endif
+	{NULL,			NULL}		/* sentinel */
+};
+
+
+/* Initialization function */
+
+PyDoc_STRVAR(thread_doc,
+"This module provides primitive operations to write multi-threaded programs.\n\
+The 'threading' module provides a more convenient interface.");
+
+PyDoc_STRVAR(lock_doc,
+"A lock object is a synchronization primitive.  To create a lock,\n\
+call the PyThread_allocate_lock() function.  Methods are:\n\
+\n\
+acquire() -- lock the lock, possibly blocking until it can be obtained\n\
+release() -- unlock of the lock\n\
+locked() -- test whether the lock is currently locked\n\
+\n\
+A lock is not owned by the thread that locked it; another thread may\n\
+unlock it.  A thread attempting to lock a lock that it has already locked\n\
+will block until another thread unlocks it.  Deadlocks may ensue.");
+
+PyMODINIT_FUNC
+initthread(void)
+{
+	PyObject *m, *d;
+	
+	/* Initialize types: */
+	if (PyType_Ready(&localtype) < 0)
+		return;
+
+	/* Create the module and add the functions */
+	m = Py_InitModule3("thread", thread_methods, thread_doc);
+	if (m == NULL)
+		return;
+
+	/* Add a symbolic constant */
+	d = PyModule_GetDict(m);
+	ThreadError = PyErr_NewException("thread.error", NULL, NULL);
+	PyDict_SetItemString(d, "error", ThreadError);
+	Locktype.tp_doc = lock_doc;
+	Py_INCREF(&Locktype);
+	PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype);
+
+	Py_INCREF(&localtype);
+	if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0)
+		return;
+
+	/* Initialize the C thread library */
+	PyThread_init_thread();
+}

Added: vendor/Python/current/Modules/timemodule.c
===================================================================
--- vendor/Python/current/Modules/timemodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/timemodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1021 @@
+
+/* Time module */
+
+#include "Python.h"
+#include "structseq.h"
+#include "timefuncs.h"
+
+#ifdef __APPLE__
+#if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_FTIME)
+  /*
+   * floattime falls back to ftime when getttimeofday fails because the latter
+   * might fail on some platforms. This fallback is unwanted on MacOSX because
+   * that makes it impossible to use a binary build on OSX 10.4 on earlier
+   * releases of the OS. Therefore claim we don't support ftime.
+   */
+# undef HAVE_FTIME
+#endif
+#endif
+
+#include <ctype.h>
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif /* HAVE_SYS_TYPES_H */
+
+#ifdef QUICKWIN
+#include <io.h>
+#endif
+
+#ifdef HAVE_FTIME
+#include <sys/timeb.h>
+#if !defined(MS_WINDOWS) && !defined(PYOS_OS2)
+extern int ftime(struct timeb *);
+#endif /* MS_WINDOWS */
+#endif /* HAVE_FTIME */
+
+#if defined(__WATCOMC__) && !defined(__QNX__)
+#include <i86.h>
+#else
+#ifdef MS_WINDOWS
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include "pythread.h"
+
+/* helper to allow us to interrupt sleep() on Windows*/
+static HANDLE hInterruptEvent = NULL;
+static BOOL WINAPI PyCtrlHandler(DWORD dwCtrlType)
+{
+	SetEvent(hInterruptEvent);
+	/* allow other default handlers to be called.
+	   Default Python handler will setup the
+	   KeyboardInterrupt exception.
+	*/
+	return FALSE;
+}
+static long main_thread;
+
+
+#if defined(__BORLANDC__)
+/* These overrides not needed for Win32 */
+#define timezone _timezone
+#define tzname _tzname
+#define daylight _daylight
+#endif /* __BORLANDC__ */
+#endif /* MS_WINDOWS */
+#endif /* !__WATCOMC__ || __QNX__ */
+
+#if defined(MS_WINDOWS) && !defined(__BORLANDC__)
+/* Win32 has better clock replacement; we have our own version below. */
+#undef HAVE_CLOCK
+#endif /* MS_WINDOWS && !defined(__BORLANDC__) */
+
+#if defined(PYOS_OS2)
+#define INCL_DOS
+#define INCL_ERRORS
+#include <os2.h>
+#endif
+
+#if defined(PYCC_VACPP)
+#include <sys/time.h>
+#endif
+
+#ifdef __BEOS__
+#include <time.h>
+/* For bigtime_t, snooze(). - [cjh] */
+#include <support/SupportDefs.h>
+#include <kernel/OS.h>
+#endif
+
+#ifdef RISCOS
+extern int riscos_sleep(double);
+#endif
+
+/* Forward declarations */
+static int floatsleep(double);
+static double floattime(void);
+
+/* For Y2K check */
+static PyObject *moddict;
+
+/* Exposed in timefuncs.h. */
+time_t
+_PyTime_DoubleToTimet(double x)
+{
+	time_t result;
+	double diff;
+
+	result = (time_t)x;
+	/* How much info did we lose?  time_t may be an integral or
+	 * floating type, and we don't know which.  If it's integral,
+	 * we don't know whether C truncates, rounds, returns the floor,
+	 * etc.  If we lost a second or more, the C rounding is
+	 * unreasonable, or the input just doesn't fit in a time_t;
+	 * call it an error regardless.  Note that the original cast to
+	 * time_t can cause a C error too, but nothing we can do to
+	 * worm around that.
+	 */
+	diff = x - (double)result;
+	if (diff <= -1.0 || diff >= 1.0) {
+		PyErr_SetString(PyExc_ValueError,
+		                "timestamp out of range for platform time_t");
+		result = (time_t)-1;
+	}
+	return result;
+}
+
+static PyObject *
+time_time(PyObject *self, PyObject *unused)
+{
+	double secs;
+	secs = floattime();
+	if (secs == 0.0) {
+		PyErr_SetFromErrno(PyExc_IOError);
+		return NULL;
+	}
+	return PyFloat_FromDouble(secs);
+}
+
+PyDoc_STRVAR(time_doc,
+"time() -> floating point number\n\
+\n\
+Return the current time in seconds since the Epoch.\n\
+Fractions of a second may be present if the system clock provides them.");
+
+#ifdef HAVE_CLOCK
+
+#ifndef CLOCKS_PER_SEC
+#ifdef CLK_TCK
+#define CLOCKS_PER_SEC CLK_TCK
+#else
+#define CLOCKS_PER_SEC 1000000
+#endif
+#endif
+
+static PyObject *
+time_clock(PyObject *self, PyObject *unused)
+{
+	return PyFloat_FromDouble(((double)clock()) / CLOCKS_PER_SEC);
+}
+#endif /* HAVE_CLOCK */
+
+#if defined(MS_WINDOWS) && !defined(__BORLANDC__)
+/* Due to Mark Hammond and Tim Peters */
+static PyObject *
+time_clock(PyObject *self, PyObject *unused)
+{
+	static LARGE_INTEGER ctrStart;
+	static double divisor = 0.0;
+	LARGE_INTEGER now;
+	double diff;
+
+	if (divisor == 0.0) {
+		LARGE_INTEGER freq;
+		QueryPerformanceCounter(&ctrStart);
+		if (!QueryPerformanceFrequency(&freq) || freq.QuadPart == 0) {
+			/* Unlikely to happen - this works on all intel
+			   machines at least!  Revert to clock() */
+			return PyFloat_FromDouble(((double)clock()) /
+						  CLOCKS_PER_SEC);
+		}
+		divisor = (double)freq.QuadPart;
+	}
+	QueryPerformanceCounter(&now);
+	diff = (double)(now.QuadPart - ctrStart.QuadPart);
+	return PyFloat_FromDouble(diff / divisor);
+}
+
+#define HAVE_CLOCK /* So it gets included in the methods */
+#endif /* MS_WINDOWS && !defined(__BORLANDC__) */
+
+#ifdef HAVE_CLOCK
+PyDoc_STRVAR(clock_doc,
+"clock() -> floating point number\n\
+\n\
+Return the CPU time or real time since the start of the process or since\n\
+the first call to clock().  This has as much precision as the system\n\
+records.");
+#endif
+
+static PyObject *
+time_sleep(PyObject *self, PyObject *args)
+{
+	double secs;
+	if (!PyArg_ParseTuple(args, "d:sleep", &secs))
+		return NULL;
+	if (floatsleep(secs) != 0)
+		return NULL;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(sleep_doc,
+"sleep(seconds)\n\
+\n\
+Delay execution for a given number of seconds.  The argument may be\n\
+a floating point number for subsecond precision.");
+
+static PyStructSequence_Field struct_time_type_fields[] = {
+	{"tm_year", NULL},
+	{"tm_mon", NULL},
+	{"tm_mday", NULL},
+	{"tm_hour", NULL},
+	{"tm_min", NULL},
+	{"tm_sec", NULL},
+	{"tm_wday", NULL},
+	{"tm_yday", NULL},
+	{"tm_isdst", NULL},
+	{0}
+};
+
+static PyStructSequence_Desc struct_time_type_desc = {
+	"time.struct_time",
+	NULL,
+	struct_time_type_fields,
+	9,
+};
+
+static int initialized;
+static PyTypeObject StructTimeType;
+
+static PyObject *
+tmtotuple(struct tm *p)
+{
+	PyObject *v = PyStructSequence_New(&StructTimeType);
+	if (v == NULL)
+		return NULL;
+
+#define SET(i,val) PyStructSequence_SET_ITEM(v, i, PyInt_FromLong((long) val))
+
+	SET(0, p->tm_year + 1900);
+	SET(1, p->tm_mon + 1);	   /* Want January == 1 */
+	SET(2, p->tm_mday);
+	SET(3, p->tm_hour);
+	SET(4, p->tm_min);
+	SET(5, p->tm_sec);
+	SET(6, (p->tm_wday + 6) % 7); /* Want Monday == 0 */
+	SET(7, p->tm_yday + 1);	   /* Want January, 1 == 1 */
+	SET(8, p->tm_isdst);
+#undef SET
+	if (PyErr_Occurred()) {
+		Py_XDECREF(v);
+		return NULL;
+	}
+
+	return v;
+}
+
+static PyObject *
+time_convert(double when, struct tm * (*function)(const time_t *))
+{
+	struct tm *p;
+	time_t whent = _PyTime_DoubleToTimet(when);
+
+	if (whent == (time_t)-1 && PyErr_Occurred())
+		return NULL;
+	errno = 0;
+	p = function(&whent);
+	if (p == NULL) {
+#ifdef EINVAL
+		if (errno == 0)
+			errno = EINVAL;
+#endif
+		return PyErr_SetFromErrno(PyExc_ValueError);
+	}
+	return tmtotuple(p);
+}
+
+/* Parse arg tuple that can contain an optional float-or-None value;
+   format needs to be "|O:name".
+   Returns non-zero on success (parallels PyArg_ParseTuple).
+*/
+static int
+parse_time_double_args(PyObject *args, char *format, double *pwhen)
+{
+	PyObject *ot = NULL;
+
+	if (!PyArg_ParseTuple(args, format, &ot))
+		return 0;
+	if (ot == NULL || ot == Py_None)
+		*pwhen = floattime();
+	else {
+		double when = PyFloat_AsDouble(ot);
+		if (PyErr_Occurred())
+			return 0;
+		*pwhen = when;
+	}
+	return 1;
+}
+
+static PyObject *
+time_gmtime(PyObject *self, PyObject *args)
+{
+	double when;
+	if (!parse_time_double_args(args, "|O:gmtime", &when))
+		return NULL;
+	return time_convert(when, gmtime);
+}
+
+PyDoc_STRVAR(gmtime_doc,
+"gmtime([seconds]) -> (tm_year, tm_mon, tm_day, tm_hour, tm_min,\n\
+                       tm_sec, tm_wday, tm_yday, tm_isdst)\n\
+\n\
+Convert seconds since the Epoch to a time tuple expressing UTC (a.k.a.\n\
+GMT).  When 'seconds' is not passed in, convert the current time instead.");
+
+static PyObject *
+time_localtime(PyObject *self, PyObject *args)
+{
+	double when;
+	if (!parse_time_double_args(args, "|O:localtime", &when))
+		return NULL;
+	return time_convert(when, localtime);
+}
+
+PyDoc_STRVAR(localtime_doc,
+"localtime([seconds]) -> (tm_year,tm_mon,tm_day,tm_hour,tm_min,tm_sec,tm_wday,tm_yday,tm_isdst)\n\
+\n\
+Convert seconds since the Epoch to a time tuple expressing local time.\n\
+When 'seconds' is not passed in, convert the current time instead.");
+
+static int
+gettmarg(PyObject *args, struct tm *p)
+{
+	int y;
+	memset((void *) p, '\0', sizeof(struct tm));
+
+	if (!PyArg_Parse(args, "(iiiiiiiii)",
+			 &y,
+			 &p->tm_mon,
+			 &p->tm_mday,
+			 &p->tm_hour,
+			 &p->tm_min,
+			 &p->tm_sec,
+			 &p->tm_wday,
+			 &p->tm_yday,
+			 &p->tm_isdst))
+		return 0;
+	if (y < 1900) {
+		PyObject *accept = PyDict_GetItemString(moddict,
+							"accept2dyear");
+		if (accept == NULL || !PyInt_Check(accept) ||
+		    PyInt_AsLong(accept) == 0) {
+			PyErr_SetString(PyExc_ValueError,
+					"year >= 1900 required");
+			return 0;
+		}
+		if (69 <= y && y <= 99)
+			y += 1900;
+		else if (0 <= y && y <= 68)
+			y += 2000;
+		else {
+			PyErr_SetString(PyExc_ValueError,
+					"year out of range");
+			return 0;
+		}
+	}
+	p->tm_year = y - 1900;
+	p->tm_mon--;
+	p->tm_wday = (p->tm_wday + 1) % 7;
+	p->tm_yday--;
+	return 1;
+}
+
+#ifdef HAVE_STRFTIME
+static PyObject *
+time_strftime(PyObject *self, PyObject *args)
+{
+	PyObject *tup = NULL;
+	struct tm buf;
+	const char *fmt;
+	size_t fmtlen, buflen;
+	char *outbuf = 0;
+	size_t i;
+
+	memset((void *) &buf, '\0', sizeof(buf));
+
+	if (!PyArg_ParseTuple(args, "s|O:strftime", &fmt, &tup))
+		return NULL;
+
+	if (tup == NULL) {
+		time_t tt = time(NULL);
+		buf = *localtime(&tt);
+	} else if (!gettmarg(tup, &buf))
+		return NULL;
+
+        /* Checks added to make sure strftime() does not crash Python by
+            indexing blindly into some array for a textual representation
+            by some bad index (fixes bug #897625).
+
+	    Also support values of zero from Python code for arguments in which
+	    that is out of range by forcing that value to the lowest value that
+	    is valid (fixed bug #1520914).
+
+	    Valid ranges based on what is allowed in struct tm:
+
+	    - tm_year: [0, max(int)] (1)
+	    - tm_mon: [0, 11] (2)
+	    - tm_mday: [1, 31]
+	    - tm_hour: [0, 23]
+	    - tm_min: [0, 59]
+	    - tm_sec: [0, 60]
+	    - tm_wday: [0, 6] (1)
+	    - tm_yday: [0, 365] (2)
+	    - tm_isdst: [-max(int), max(int)]
+
+	    (1) gettmarg() handles bounds-checking.
+	    (2) Python's acceptable range is one greater than the range in C,
+	        thus need to check against automatic decrement by gettmarg().
+        */
+	if (buf.tm_mon == -1)
+	    buf.tm_mon = 0;
+	else if (buf.tm_mon < 0 || buf.tm_mon > 11) {
+            PyErr_SetString(PyExc_ValueError, "month out of range");
+                        return NULL;
+        }
+	if (buf.tm_mday == 0)
+	    buf.tm_mday = 1;
+	else if (buf.tm_mday < 0 || buf.tm_mday > 31) {
+            PyErr_SetString(PyExc_ValueError, "day of month out of range");
+                        return NULL;
+        }
+        if (buf.tm_hour < 0 || buf.tm_hour > 23) {
+            PyErr_SetString(PyExc_ValueError, "hour out of range");
+            return NULL;
+        }
+        if (buf.tm_min < 0 || buf.tm_min > 59) {
+            PyErr_SetString(PyExc_ValueError, "minute out of range");
+            return NULL;
+        }
+        if (buf.tm_sec < 0 || buf.tm_sec > 61) {
+            PyErr_SetString(PyExc_ValueError, "seconds out of range");
+            return NULL;
+        }
+        /* tm_wday does not need checking of its upper-bound since taking
+        ``% 7`` in gettmarg() automatically restricts the range. */
+        if (buf.tm_wday < 0) {
+            PyErr_SetString(PyExc_ValueError, "day of week out of range");
+            return NULL;
+        }
+	if (buf.tm_yday == -1)
+	    buf.tm_yday = 0;
+	else if (buf.tm_yday < 0 || buf.tm_yday > 365) {
+            PyErr_SetString(PyExc_ValueError, "day of year out of range");
+            return NULL;
+        }
+        if (buf.tm_isdst < -1 || buf.tm_isdst > 1) {
+            PyErr_SetString(PyExc_ValueError,
+                            "daylight savings flag out of range");
+            return NULL;
+        }
+
+	fmtlen = strlen(fmt);
+
+	/* I hate these functions that presume you know how big the output
+	 * will be ahead of time...
+	 */
+	for (i = 1024; ; i += i) {
+		outbuf = (char *)malloc(i);
+		if (outbuf == NULL) {
+			return PyErr_NoMemory();
+		}
+		buflen = strftime(outbuf, i, fmt, &buf);
+		if (buflen > 0 || i >= 256 * fmtlen) {
+			/* If the buffer is 256 times as long as the format,
+			   it's probably not failing for lack of room!
+			   More likely, the format yields an empty result,
+			   e.g. an empty format, or %Z when the timezone
+			   is unknown. */
+			PyObject *ret;
+			ret = PyString_FromStringAndSize(outbuf, buflen);
+			free(outbuf);
+			return ret;
+		}
+		free(outbuf);
+#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
+		/* VisualStudio .NET 2005 does this properly */
+		if (buflen == 0 && errno == EINVAL) {
+			PyErr_SetString(PyExc_ValueError, "Invalid format string");
+			return 0;
+		}
+#endif
+		
+	}
+}
+
+PyDoc_STRVAR(strftime_doc,
+"strftime(format[, tuple]) -> string\n\
+\n\
+Convert a time tuple to a string according to a format specification.\n\
+See the library reference manual for formatting codes. When the time tuple\n\
+is not present, current time as returned by localtime() is used.");
+#endif /* HAVE_STRFTIME */
+
+static PyObject *
+time_strptime(PyObject *self, PyObject *args)
+{
+    PyObject *strptime_module = PyImport_ImportModule("_strptime");
+    PyObject *strptime_result;
+
+    if (!strptime_module)
+        return NULL;
+    strptime_result = PyObject_CallMethod(strptime_module, "strptime", "O", args);
+    Py_DECREF(strptime_module);
+    return strptime_result;
+}
+
+PyDoc_STRVAR(strptime_doc,
+"strptime(string, format) -> struct_time\n\
+\n\
+Parse a string to a time tuple according to a format specification.\n\
+See the library reference manual for formatting codes (same as strftime()).");
+
+
+static PyObject *
+time_asctime(PyObject *self, PyObject *args)
+{
+	PyObject *tup = NULL;
+	struct tm buf;
+	char *p;
+	if (!PyArg_UnpackTuple(args, "asctime", 0, 1, &tup))
+		return NULL;
+	if (tup == NULL) {
+		time_t tt = time(NULL);
+		buf = *localtime(&tt);
+	} else if (!gettmarg(tup, &buf))
+		return NULL;
+	p = asctime(&buf);
+	if (p[24] == '\n')
+		p[24] = '\0';
+	return PyString_FromString(p);
+}
+
+PyDoc_STRVAR(asctime_doc,
+"asctime([tuple]) -> string\n\
+\n\
+Convert a time tuple to a string, e.g. 'Sat Jun 06 16:26:11 1998'.\n\
+When the time tuple is not present, current time as returned by localtime()\n\
+is used.");
+
+static PyObject *
+time_ctime(PyObject *self, PyObject *args)
+{
+	PyObject *ot = NULL;
+	time_t tt;
+	char *p;
+
+	if (!PyArg_UnpackTuple(args, "ctime", 0, 1, &ot))
+		return NULL;
+	if (ot == NULL || ot == Py_None)
+		tt = time(NULL);
+	else {
+		double dt = PyFloat_AsDouble(ot);
+		if (PyErr_Occurred())
+			return NULL;
+		tt = _PyTime_DoubleToTimet(dt);
+		if (tt == (time_t)-1 && PyErr_Occurred())
+			return NULL;
+	}
+	p = ctime(&tt);
+	if (p == NULL) {
+		PyErr_SetString(PyExc_ValueError, "unconvertible time");
+		return NULL;
+	}
+	if (p[24] == '\n')
+		p[24] = '\0';
+	return PyString_FromString(p);
+}
+
+PyDoc_STRVAR(ctime_doc,
+"ctime(seconds) -> string\n\
+\n\
+Convert a time in seconds since the Epoch to a string in local time.\n\
+This is equivalent to asctime(localtime(seconds)). When the time tuple is\n\
+not present, current time as returned by localtime() is used.");
+
+#ifdef HAVE_MKTIME
+static PyObject *
+time_mktime(PyObject *self, PyObject *tup)
+{
+	struct tm buf;
+	time_t tt;
+	tt = time(&tt);
+	buf = *localtime(&tt);
+	if (!gettmarg(tup, &buf))
+		return NULL;
+	tt = mktime(&buf);
+	if (tt == (time_t)(-1)) {
+		PyErr_SetString(PyExc_OverflowError,
+				"mktime argument out of range");
+		return NULL;
+	}
+	return PyFloat_FromDouble((double)tt);
+}
+
+PyDoc_STRVAR(mktime_doc,
+"mktime(tuple) -> floating point number\n\
+\n\
+Convert a time tuple in local time to seconds since the Epoch.");
+#endif /* HAVE_MKTIME */
+
+#ifdef HAVE_WORKING_TZSET
+void inittimezone(PyObject *module);
+
+static PyObject *
+time_tzset(PyObject *self, PyObject *unused)
+{
+	PyObject* m;
+
+	m = PyImport_ImportModule("time");
+	if (m == NULL) {
+	    return NULL;
+	}
+
+	tzset();
+
+	/* Reset timezone, altzone, daylight and tzname */
+	inittimezone(m);
+	Py_DECREF(m);
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(tzset_doc,
+"tzset(zone)\n\
+\n\
+Initialize, or reinitialize, the local timezone to the value stored in\n\
+os.environ['TZ']. The TZ environment variable should be specified in\n\
+standard Unix timezone format as documented in the tzset man page\n\
+(eg. 'US/Eastern', 'Europe/Amsterdam'). Unknown timezones will silently\n\
+fall back to UTC. If the TZ environment variable is not set, the local\n\
+timezone is set to the systems best guess of wallclock time.\n\
+Changing the TZ environment variable without calling tzset *may* change\n\
+the local timezone used by methods such as localtime, but this behaviour\n\
+should not be relied on.");
+#endif /* HAVE_WORKING_TZSET */
+
+void inittimezone(PyObject *m) {
+    /* This code moved from inittime wholesale to allow calling it from
+	time_tzset. In the future, some parts of it can be moved back
+	(for platforms that don't HAVE_WORKING_TZSET, when we know what they
+	are), and the extranious calls to tzset(3) should be removed.
+	I havn't done this yet, as I don't want to change this code as
+	little as possible when introducing the time.tzset and time.tzsetwall
+	methods. This should simply be a method of doing the following once,
+	at the top of this function and removing the call to tzset() from
+	time_tzset():
+
+	    #ifdef HAVE_TZSET
+	    tzset()
+	    #endif
+
+	And I'm lazy and hate C so nyer.
+     */
+#if defined(HAVE_TZNAME) && !defined(__GLIBC__) && !defined(__CYGWIN__)
+	tzset();
+#ifdef PYOS_OS2
+	PyModule_AddIntConstant(m, "timezone", _timezone);
+#else /* !PYOS_OS2 */
+	PyModule_AddIntConstant(m, "timezone", timezone);
+#endif /* PYOS_OS2 */
+#ifdef HAVE_ALTZONE
+	PyModule_AddIntConstant(m, "altzone", altzone);
+#else
+#ifdef PYOS_OS2
+	PyModule_AddIntConstant(m, "altzone", _timezone-3600);
+#else /* !PYOS_OS2 */
+	PyModule_AddIntConstant(m, "altzone", timezone-3600);
+#endif /* PYOS_OS2 */
+#endif
+	PyModule_AddIntConstant(m, "daylight", daylight);
+	PyModule_AddObject(m, "tzname",
+			   Py_BuildValue("(zz)", tzname[0], tzname[1]));
+#else /* !HAVE_TZNAME || __GLIBC__ || __CYGWIN__*/
+#ifdef HAVE_STRUCT_TM_TM_ZONE
+	{
+#define YEAR ((time_t)((365 * 24 + 6) * 3600))
+		time_t t;
+		struct tm *p;
+		long janzone, julyzone;
+		char janname[10], julyname[10];
+		t = (time((time_t *)0) / YEAR) * YEAR;
+		p = localtime(&t);
+		janzone = -p->tm_gmtoff;
+		strncpy(janname, p->tm_zone ? p->tm_zone : "   ", 9);
+		janname[9] = '\0';
+		t += YEAR/2;
+		p = localtime(&t);
+		julyzone = -p->tm_gmtoff;
+		strncpy(julyname, p->tm_zone ? p->tm_zone : "   ", 9);
+		julyname[9] = '\0';
+
+		if( janzone < julyzone ) {
+			/* DST is reversed in the southern hemisphere */
+			PyModule_AddIntConstant(m, "timezone", julyzone);
+			PyModule_AddIntConstant(m, "altzone", janzone);
+			PyModule_AddIntConstant(m, "daylight",
+						janzone != julyzone);
+			PyModule_AddObject(m, "tzname",
+					   Py_BuildValue("(zz)",
+							 julyname, janname));
+		} else {
+			PyModule_AddIntConstant(m, "timezone", janzone);
+			PyModule_AddIntConstant(m, "altzone", julyzone);
+			PyModule_AddIntConstant(m, "daylight",
+						janzone != julyzone);
+			PyModule_AddObject(m, "tzname",
+					   Py_BuildValue("(zz)",
+							 janname, julyname));
+		}
+	}
+#else
+#endif /* HAVE_STRUCT_TM_TM_ZONE */
+#ifdef __CYGWIN__
+	tzset();
+	PyModule_AddIntConstant(m, "timezone", _timezone);
+	PyModule_AddIntConstant(m, "altzone", _timezone-3600);
+	PyModule_AddIntConstant(m, "daylight", _daylight);
+	PyModule_AddObject(m, "tzname",
+			   Py_BuildValue("(zz)", _tzname[0], _tzname[1]));
+#endif /* __CYGWIN__ */
+#endif /* !HAVE_TZNAME || __GLIBC__ || __CYGWIN__*/
+}
+
+
+static PyMethodDef time_methods[] = {
+	{"time",	time_time, METH_NOARGS, time_doc},
+#ifdef HAVE_CLOCK
+	{"clock",	time_clock, METH_NOARGS, clock_doc},
+#endif
+	{"sleep",	time_sleep, METH_VARARGS, sleep_doc},
+	{"gmtime",	time_gmtime, METH_VARARGS, gmtime_doc},
+	{"localtime",	time_localtime, METH_VARARGS, localtime_doc},
+	{"asctime",	time_asctime, METH_VARARGS, asctime_doc},
+	{"ctime",	time_ctime, METH_VARARGS, ctime_doc},
+#ifdef HAVE_MKTIME
+	{"mktime",	time_mktime, METH_O, mktime_doc},
+#endif
+#ifdef HAVE_STRFTIME
+	{"strftime",	time_strftime, METH_VARARGS, strftime_doc},
+#endif
+	{"strptime",	time_strptime, METH_VARARGS, strptime_doc},
+#ifdef HAVE_WORKING_TZSET
+	{"tzset",	time_tzset, METH_NOARGS, tzset_doc},
+#endif
+	{NULL,		NULL}		/* sentinel */
+};
+
+
+PyDoc_STRVAR(module_doc,
+"This module provides various functions to manipulate time values.\n\
+\n\
+There are two standard representations of time.  One is the number\n\
+of seconds since the Epoch, in UTC (a.k.a. GMT).  It may be an integer\n\
+or a floating point number (to represent fractions of seconds).\n\
+The Epoch is system-defined; on Unix, it is generally January 1st, 1970.\n\
+The actual value can be retrieved by calling gmtime(0).\n\
+\n\
+The other representation is a tuple of 9 integers giving local time.\n\
+The tuple items are:\n\
+  year (four digits, e.g. 1998)\n\
+  month (1-12)\n\
+  day (1-31)\n\
+  hours (0-23)\n\
+  minutes (0-59)\n\
+  seconds (0-59)\n\
+  weekday (0-6, Monday is 0)\n\
+  Julian day (day in the year, 1-366)\n\
+  DST (Daylight Savings Time) flag (-1, 0 or 1)\n\
+If the DST flag is 0, the time is given in the regular time zone;\n\
+if it is 1, the time is given in the DST time zone;\n\
+if it is -1, mktime() should guess based on the date and time.\n\
+\n\
+Variables:\n\
+\n\
+timezone -- difference in seconds between UTC and local standard time\n\
+altzone -- difference in  seconds between UTC and local DST time\n\
+daylight -- whether local time should reflect DST\n\
+tzname -- tuple of (standard time zone name, DST time zone name)\n\
+\n\
+Functions:\n\
+\n\
+time() -- return current time in seconds since the Epoch as a float\n\
+clock() -- return CPU time since process start as a float\n\
+sleep() -- delay for a number of seconds given as a float\n\
+gmtime() -- convert seconds since Epoch to UTC tuple\n\
+localtime() -- convert seconds since Epoch to local time tuple\n\
+asctime() -- convert time tuple to string\n\
+ctime() -- convert time in seconds to string\n\
+mktime() -- convert local time tuple to seconds since Epoch\n\
+strftime() -- convert time tuple to string according to format specification\n\
+strptime() -- parse string to time tuple according to format specification\n\
+tzset() -- change the local timezone");
+
+
+PyMODINIT_FUNC
+inittime(void)
+{
+	PyObject *m;
+	char *p;
+	m = Py_InitModule3("time", time_methods, module_doc);
+	if (m == NULL)
+		return;
+
+	/* Accept 2-digit dates unless PYTHONY2K is set and non-empty */
+	p = Py_GETENV("PYTHONY2K");
+	PyModule_AddIntConstant(m, "accept2dyear", (long) (!p || !*p));
+	/* Squirrel away the module's dictionary for the y2k check */
+	moddict = PyModule_GetDict(m);
+	Py_INCREF(moddict);
+
+	/* Set, or reset, module variables like time.timezone */
+	inittimezone(m);
+
+#ifdef MS_WINDOWS
+	/* Helper to allow interrupts for Windows.
+	   If Ctrl+C event delivered while not sleeping
+	   it will be ignored.
+	*/
+	main_thread = PyThread_get_thread_ident();
+	hInterruptEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+	SetConsoleCtrlHandler( PyCtrlHandler, TRUE);
+#endif /* MS_WINDOWS */
+	if (!initialized) {
+		PyStructSequence_InitType(&StructTimeType,
+					  &struct_time_type_desc);
+	}
+	Py_INCREF(&StructTimeType);
+	PyModule_AddObject(m, "struct_time", (PyObject*) &StructTimeType);
+	initialized = 1;
+}
+
+
+/* Implement floattime() for various platforms */
+
+static double
+floattime(void)
+{
+	/* There are three ways to get the time:
+	  (1) gettimeofday() -- resolution in microseconds
+	  (2) ftime() -- resolution in milliseconds
+	  (3) time() -- resolution in seconds
+	  In all cases the return value is a float in seconds.
+	  Since on some systems (e.g. SCO ODT 3.0) gettimeofday() may
+	  fail, so we fall back on ftime() or time().
+	  Note: clock resolution does not imply clock accuracy! */
+#ifdef HAVE_GETTIMEOFDAY
+	{
+		struct timeval t;
+#ifdef GETTIMEOFDAY_NO_TZ
+		if (gettimeofday(&t) == 0)
+			return (double)t.tv_sec + t.tv_usec*0.000001;
+#else /* !GETTIMEOFDAY_NO_TZ */
+		if (gettimeofday(&t, (struct timezone *)NULL) == 0)
+			return (double)t.tv_sec + t.tv_usec*0.000001;
+#endif /* !GETTIMEOFDAY_NO_TZ */
+	}
+
+#endif /* !HAVE_GETTIMEOFDAY */
+	{
+#if defined(HAVE_FTIME)
+		struct timeb t;
+		ftime(&t);
+		return (double)t.time + (double)t.millitm * (double)0.001;
+#else /* !HAVE_FTIME */
+		time_t secs;
+		time(&secs);
+		return (double)secs;
+#endif /* !HAVE_FTIME */
+	}
+}
+
+
+/* Implement floatsleep() for various platforms.
+   When interrupted (or when another error occurs), return -1 and
+   set an exception; else return 0. */
+
+static int
+floatsleep(double secs)
+{
+/* XXX Should test for MS_WINDOWS first! */
+#if defined(HAVE_SELECT) && !defined(__BEOS__) && !defined(__EMX__)
+	struct timeval t;
+	double frac;
+	frac = fmod(secs, 1.0);
+	secs = floor(secs);
+	t.tv_sec = (long)secs;
+	t.tv_usec = (long)(frac*1000000.0);
+	Py_BEGIN_ALLOW_THREADS
+	if (select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t) != 0) {
+#ifdef EINTR
+		if (errno != EINTR) {
+#else
+		if (1) {
+#endif
+			Py_BLOCK_THREADS
+			PyErr_SetFromErrno(PyExc_IOError);
+			return -1;
+		}
+	}
+	Py_END_ALLOW_THREADS
+#elif defined(__WATCOMC__) && !defined(__QNX__)
+	/* XXX Can't interrupt this sleep */
+	Py_BEGIN_ALLOW_THREADS
+	delay((int)(secs * 1000 + 0.5));  /* delay() uses milliseconds */
+	Py_END_ALLOW_THREADS
+#elif defined(MS_WINDOWS)
+	{
+		double millisecs = secs * 1000.0;
+		unsigned long ul_millis;
+
+		if (millisecs > (double)ULONG_MAX) {
+			PyErr_SetString(PyExc_OverflowError,
+					"sleep length is too large");
+			return -1;
+		}
+		Py_BEGIN_ALLOW_THREADS
+		/* Allow sleep(0) to maintain win32 semantics, and as decreed
+		 * by Guido, only the main thread can be interrupted.
+		 */
+		ul_millis = (unsigned long)millisecs;
+		if (ul_millis == 0 ||
+		    main_thread != PyThread_get_thread_ident())
+			Sleep(ul_millis);
+		else {
+			DWORD rc;
+			ResetEvent(hInterruptEvent);
+			rc = WaitForSingleObject(hInterruptEvent, ul_millis);
+			if (rc == WAIT_OBJECT_0) {
+				/* Yield to make sure real Python signal
+				 * handler called.
+				 */
+				Sleep(1);
+				Py_BLOCK_THREADS
+				errno = EINTR;
+				PyErr_SetFromErrno(PyExc_IOError);
+				return -1;
+			}
+		}
+		Py_END_ALLOW_THREADS
+	}
+#elif defined(PYOS_OS2)
+	/* This Sleep *IS* Interruptable by Exceptions */
+	Py_BEGIN_ALLOW_THREADS
+	if (DosSleep(secs * 1000) != NO_ERROR) {
+		Py_BLOCK_THREADS
+		PyErr_SetFromErrno(PyExc_IOError);
+		return -1;
+	}
+	Py_END_ALLOW_THREADS
+#elif defined(__BEOS__)
+	/* This sleep *CAN BE* interrupted. */
+	{
+		if( secs <= 0.0 ) {
+			return;
+		}
+
+		Py_BEGIN_ALLOW_THREADS
+		/* BeOS snooze() is in microseconds... */
+		if( snooze( (bigtime_t)( secs * 1000.0 * 1000.0 ) ) == B_INTERRUPTED ) {
+			Py_BLOCK_THREADS
+			PyErr_SetFromErrno( PyExc_IOError );
+			return -1;
+		}
+		Py_END_ALLOW_THREADS
+	}
+#elif defined(RISCOS)
+	if (secs <= 0.0)
+		return 0;
+	Py_BEGIN_ALLOW_THREADS
+	/* This sleep *CAN BE* interrupted. */
+	if ( riscos_sleep(secs) )
+		return -1;
+	Py_END_ALLOW_THREADS
+#elif defined(PLAN9)
+	{
+		double millisecs = secs * 1000.0;
+		if (millisecs > (double)LONG_MAX) {
+			PyErr_SetString(PyExc_OverflowError, "sleep length is too large");
+			return -1;
+		}
+		/* This sleep *CAN BE* interrupted. */
+		Py_BEGIN_ALLOW_THREADS
+		if(sleep((long)millisecs) < 0){
+			Py_BLOCK_THREADS
+			PyErr_SetFromErrno(PyExc_IOError);
+			return -1;
+		}
+		Py_END_ALLOW_THREADS
+	}
+#else
+	/* XXX Can't interrupt this sleep */
+	Py_BEGIN_ALLOW_THREADS
+	sleep((int)secs);
+	Py_END_ALLOW_THREADS
+#endif
+
+	return 0;
+}
+
+

Added: vendor/Python/current/Modules/timing.h
===================================================================
--- vendor/Python/current/Modules/timing.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/timing.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 1993 George V. Neville-Neil
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by George V. Neville-Neil
+ * 4. The name, George Neville-Neil may not be used to endorse or promote 
+ *    products derived from this software without specific prior 
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _TIMING_H_
+#define _TIMING_H_
+
+#ifdef TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#else /* !TIME_WITH_SYS_TIME */
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#else /* !HAVE_SYS_TIME_H */
+#include <time.h>
+#endif /* !HAVE_SYS_TIME_H */
+#endif /* !TIME_WITH_SYS_TIME */
+
+static struct timeval aftertp, beforetp;
+
+#define BEGINTIMING gettimeofday(&beforetp, NULL)
+
+#define ENDTIMING gettimeofday(&aftertp, NULL); \
+    if(beforetp.tv_usec > aftertp.tv_usec) \
+    {  \
+         aftertp.tv_usec += 1000000;  \
+         aftertp.tv_sec--; \
+    }
+
+#define TIMINGUS (((aftertp.tv_sec - beforetp.tv_sec) * 1000000) + \
+		  (aftertp.tv_usec - beforetp.tv_usec))
+
+#define TIMINGMS (((aftertp.tv_sec - beforetp.tv_sec) * 1000) + \
+		  ((aftertp.tv_usec - beforetp.tv_usec) / 1000))
+
+#define TIMINGS  ((aftertp.tv_sec - beforetp.tv_sec) + \
+		  (aftertp.tv_usec - beforetp.tv_usec) / 1000000)
+
+#endif /* _TIMING_H_ */

Added: vendor/Python/current/Modules/timingmodule.c
===================================================================
--- vendor/Python/current/Modules/timingmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/timingmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,58 @@
+/*
+ * Author: George V. Neville-Neil
+ */
+
+#include "Python.h"
+
+/* Our stuff... */
+#include "timing.h"
+
+static PyObject *
+start_timing(PyObject *self)
+{
+	Py_INCREF(Py_None);
+	BEGINTIMING;
+	return Py_None;
+}
+
+static PyObject *
+finish_timing(PyObject *self)
+{
+	ENDTIMING    
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+seconds(PyObject *self)
+{
+	return PyInt_FromLong(TIMINGS);
+}
+
+static PyObject *
+milli(PyObject *self)
+{
+	return PyInt_FromLong(TIMINGMS);
+}
+
+static PyObject *
+micro(PyObject *self)
+{
+	return PyInt_FromLong(TIMINGUS);
+}
+
+
+static PyMethodDef timing_methods[] = {
+	{"start",   (PyCFunction)start_timing, METH_NOARGS},
+	{"finish",  (PyCFunction)finish_timing, METH_NOARGS},
+	{"seconds", (PyCFunction)seconds, METH_NOARGS},
+	{"milli",   (PyCFunction)milli, METH_NOARGS},
+	{"micro",   (PyCFunction)micro, METH_NOARGS},
+	{NULL,      NULL}
+};
+
+
+PyMODINIT_FUNC inittiming(void)
+{
+	(void)Py_InitModule("timing", timing_methods);
+}

Added: vendor/Python/current/Modules/tkappinit.c
===================================================================
--- vendor/Python/current/Modules/tkappinit.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/tkappinit.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,149 @@
+/* appinit.c -- Tcl and Tk application initialization.
+
+   The function Tcl_AppInit() below initializes various Tcl packages.
+   It is called for each Tcl interpreter created by _tkinter.create().
+   It needs to be compiled with -DWITH_<package> flags for each package
+   that you are statically linking with.  You may have to add sections
+   for packages not yet listed below.
+
+   Note that those packages for which Tcl_StaticPackage() is called with
+   a NULL first argument are known as "static loadable" packages to
+   Tcl but not actually initialized.  To use these, you have to load
+   it explicitly, e.g. tkapp.eval("load {} Blt").
+ */
+
+#include <string.h>
+#include <tcl.h>
+#include <tk.h>
+
+int
+Tcl_AppInit(Tcl_Interp *interp)
+{
+	Tk_Window main_window;
+	const char * _tkinter_skip_tk_init;
+
+#ifdef TK_AQUA
+#ifndef MAX_PATH_LEN
+#define MAX_PATH_LEN 1024
+#endif
+	char tclLibPath[MAX_PATH_LEN], tkLibPath[MAX_PATH_LEN];
+	Tcl_Obj*	pathPtr;
+
+        /* pre- Tcl_Init code copied from tkMacOSXAppInit.c */
+	Tk_MacOSXOpenBundleResources (interp, "com.tcltk.tcllibrary",
+       	tclLibPath, MAX_PATH_LEN, 0);
+
+	if (tclLibPath[0] != '\0') {
+       	Tcl_SetVar(interp, "tcl_library", tclLibPath, TCL_GLOBAL_ONLY);
+		Tcl_SetVar(interp, "tclDefaultLibrary", tclLibPath, TCL_GLOBAL_ONLY);
+		Tcl_SetVar(interp, "tcl_pkgPath", tclLibPath, TCL_GLOBAL_ONLY);
+	}
+	
+   	if (tclLibPath[0] != '\0') {
+		Tcl_SetVar(interp, "tcl_library", tclLibPath, TCL_GLOBAL_ONLY);
+		Tcl_SetVar(interp, "tclDefaultLibrary", tclLibPath, TCL_GLOBAL_ONLY);
+		Tcl_SetVar(interp, "tcl_pkgPath", tclLibPath, TCL_GLOBAL_ONLY);
+	}
+#endif
+	if (Tcl_Init (interp) == TCL_ERROR)
+		return TCL_ERROR;
+
+#ifdef TK_AQUA
+        /* pre- Tk_Init code copied from tkMacOSXAppInit.c */
+	Tk_MacOSXOpenBundleResources (interp, "com.tcltk.tklibrary",
+            tkLibPath, MAX_PATH_LEN, 1);
+
+	if (tclLibPath[0] != '\0') {
+		pathPtr = Tcl_NewStringObj(tclLibPath, -1);
+	} else {
+		Tcl_Obj *pathPtr = TclGetLibraryPath();
+	}
+
+	if (tkLibPath[0] != '\0') {
+		Tcl_Obj *objPtr;
+
+		Tcl_SetVar(interp, "tk_library", tkLibPath, TCL_GLOBAL_ONLY);
+		objPtr = Tcl_NewStringObj(tkLibPath, -1);
+		Tcl_ListObjAppendElement(NULL, pathPtr, objPtr);
+	}
+
+	TclSetLibraryPath(pathPtr);
+#endif
+
+#ifdef WITH_XXX
+		// Initialize modules that don't require Tk
+#endif
+
+	_tkinter_skip_tk_init =	Tcl_GetVar(interp, "_tkinter_skip_tk_init", TCL_GLOBAL_ONLY);
+	if (_tkinter_skip_tk_init != NULL && strcmp(_tkinter_skip_tk_init, "1")	== 0) {
+		return TCL_OK;
+	}
+	if (Tk_Init(interp) == TCL_ERROR)
+		return TCL_ERROR;
+
+	main_window = Tk_MainWindow(interp);
+
+#ifdef TK_AQUA
+	TkMacOSXInitAppleEvents(interp);
+	TkMacOSXInitMenus(interp);
+#endif
+    
+#ifdef WITH_MOREBUTTONS
+	{
+		extern Tcl_CmdProc studButtonCmd;
+		extern Tcl_CmdProc triButtonCmd;
+
+		Tcl_CreateCommand(interp, "studbutton", studButtonCmd,
+				  (ClientData) main_window, NULL);
+		Tcl_CreateCommand(interp, "tributton", triButtonCmd,
+				  (ClientData) main_window, NULL);
+	}
+#endif
+
+#ifdef WITH_PIL /* 0.2b5 and later -- not yet released as of May 14 */
+	{
+		extern void TkImaging_Init(Tcl_Interp *);
+		TkImaging_Init(interp);
+		/* XXX TkImaging_Init() doesn't have the right return type */
+		/*Tcl_StaticPackage(interp, "Imaging", TkImaging_Init, NULL);*/
+	}
+#endif
+
+#ifdef WITH_PIL_OLD /* 0.2b4 and earlier */
+	{
+		extern void TkImaging_Init(void);
+		/* XXX TkImaging_Init() doesn't have the right prototype */
+		/*Tcl_StaticPackage(interp, "Imaging", TkImaging_Init, NULL);*/
+	}
+#endif
+
+#ifdef WITH_TIX
+        {
+                extern int Tix_Init(Tcl_Interp *interp);
+                extern int Tix_SafeInit(Tcl_Interp *interp);
+                Tcl_StaticPackage(NULL, "Tix", Tix_Init, Tix_SafeInit);
+        }
+#endif
+
+#ifdef WITH_BLT
+	{
+		extern int Blt_Init(Tcl_Interp *);
+		extern int Blt_SafeInit(Tcl_Interp *);
+		Tcl_StaticPackage(NULL, "Blt", Blt_Init, Blt_SafeInit);
+	}
+#endif
+
+#ifdef WITH_TOGL
+	{
+		/* XXX I've heard rumors that this doesn't work */
+		extern int Togl_Init(Tcl_Interp *);
+		/* XXX Is there no Togl_SafeInit? */
+		Tcl_StaticPackage(NULL, "Togl", Togl_Init, NULL);
+	}
+#endif
+
+#ifdef WITH_XXX
+
+#endif
+	return TCL_OK;
+}

Added: vendor/Python/current/Modules/unicodedata.c
===================================================================
--- vendor/Python/current/Modules/unicodedata.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/unicodedata.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1223 @@
+/* ------------------------------------------------------------------------
+
+   unicodedata -- Provides access to the Unicode 4.1 data base.
+
+   Data was extracted from the Unicode 4.1 UnicodeData.txt file.
+
+   Written by Marc-Andre Lemburg (mal at lemburg.com).
+   Modified for Python 2.0 by Fredrik Lundh (fredrik at pythonware.com)
+   Modified by Martin v. Löwis (martin at v.loewis.de)
+
+   Copyright (c) Corporation for National Research Initiatives.
+
+   ------------------------------------------------------------------------ */
+
+#include "Python.h"
+#include "ucnhash.h"
+#include "structmember.h"
+
+/* character properties */
+
+typedef struct {
+    const unsigned char category;	/* index into
+					   _PyUnicode_CategoryNames */
+    const unsigned char	combining; 	/* combining class value 0 - 255 */
+    const unsigned char	bidirectional; 	/* index into
+					   _PyUnicode_BidirectionalNames */
+    const unsigned char mirrored;	/* true if mirrored in bidir mode */
+    const unsigned char east_asian_width;	/* index into
+						   _PyUnicode_EastAsianWidth */
+} _PyUnicode_DatabaseRecord;
+
+typedef struct change_record {
+    /* sequence of fields should be the same as in merge_old_version */
+    const unsigned char bidir_changed;
+    const unsigned char category_changed;
+    const unsigned char decimal_changed;
+    const int numeric_changed;
+} change_record;
+
+/* data file generated by Tools/unicode/makeunicodedata.py */
+#include "unicodedata_db.h"
+
+static const _PyUnicode_DatabaseRecord*
+_getrecord_ex(Py_UCS4 code)
+{
+    int index;
+    if (code >= 0x110000)
+        index = 0;
+    else {
+        index = index1[(code>>SHIFT)];
+        index = index2[(index<<SHIFT)+(code&((1<<SHIFT)-1))];
+    }
+
+    return &_PyUnicode_Database_Records[index];
+}
+
+static const _PyUnicode_DatabaseRecord*
+_getrecord(PyUnicodeObject* v)
+{
+    return _getrecord_ex(*PyUnicode_AS_UNICODE(v));
+}
+
+/* ------------- Previous-version API ------------------------------------- */
+typedef struct previous_version {
+    PyObject_HEAD
+    const char *name;
+    const change_record* (*getrecord)(Py_UCS4);
+    Py_UCS4 (*normalization)(Py_UCS4);
+} PreviousDBVersion;
+
+#define get_old_record(self, v)    ((((PreviousDBVersion*)self)->getrecord)(v))
+
+static PyMemberDef DB_members[] = {
+	{"unidata_version", T_STRING, offsetof(PreviousDBVersion, name), READONLY},
+        {NULL}
+};
+
+/* forward declaration */
+static PyTypeObject UCD_Type;
+
+static PyObject*
+new_previous_version(const char*name, const change_record* (*getrecord)(Py_UCS4),
+                     Py_UCS4 (*normalization)(Py_UCS4))
+{
+	PreviousDBVersion *self;
+	self = PyObject_New(PreviousDBVersion, &UCD_Type);
+	if (self == NULL)
+		return NULL;
+	self->name = name;
+	self->getrecord = getrecord;
+        self->normalization = normalization;
+	return (PyObject*)self;
+}
+
+/* --- Module API --------------------------------------------------------- */
+
+PyDoc_STRVAR(unicodedata_decimal__doc__,
+"decimal(unichr[, default])\n\
+\n\
+Returns the decimal value assigned to the Unicode character unichr\n\
+as integer. If no such value is defined, default is returned, or, if\n\
+not given, ValueError is raised.");
+
+static PyObject *
+unicodedata_decimal(PyObject *self, PyObject *args)
+{
+    PyUnicodeObject *v;
+    PyObject *defobj = NULL;
+    int have_old = 0;
+    long rc;
+
+    if (!PyArg_ParseTuple(args, "O!|O:decimal", &PyUnicode_Type, &v, &defobj))
+        return NULL;
+    if (PyUnicode_GET_SIZE(v) != 1) {
+	PyErr_SetString(PyExc_TypeError,
+			"need a single Unicode character as parameter");
+        return NULL;
+    }
+
+    if (self) {
+        const change_record *old = get_old_record(self, *PyUnicode_AS_UNICODE(v));
+        if (old->category_changed == 0) {
+            /* unassigned */
+            have_old = 1;
+            rc = -1;
+        } 
+        else if (old->decimal_changed != 0xFF) {
+            have_old = 1;
+            rc = old->decimal_changed;
+        }
+    }
+
+    if (!have_old)
+        rc = Py_UNICODE_TODECIMAL(*PyUnicode_AS_UNICODE(v));
+    if (rc < 0) {
+	if (defobj == NULL) {
+	    PyErr_SetString(PyExc_ValueError,
+			    "not a decimal");
+            return NULL;
+	}
+	else {
+	    Py_INCREF(defobj);
+	    return defobj;
+	}
+    }
+    return PyInt_FromLong(rc);
+}
+
+PyDoc_STRVAR(unicodedata_digit__doc__,
+"digit(unichr[, default])\n\
+\n\
+Returns the digit value assigned to the Unicode character unichr as\n\
+integer. If no such value is defined, default is returned, or, if\n\
+not given, ValueError is raised.");
+
+static PyObject *
+unicodedata_digit(PyObject *self, PyObject *args)
+{
+    PyUnicodeObject *v;
+    PyObject *defobj = NULL;
+    long rc;
+
+    if (!PyArg_ParseTuple(args, "O!|O:digit", &PyUnicode_Type, &v, &defobj))
+        return NULL;
+    if (PyUnicode_GET_SIZE(v) != 1) {
+	PyErr_SetString(PyExc_TypeError,
+			"need a single Unicode character as parameter");
+        return NULL;
+    }
+    rc = Py_UNICODE_TODIGIT(*PyUnicode_AS_UNICODE(v));
+    if (rc < 0) {
+	if (defobj == NULL) {
+	    PyErr_SetString(PyExc_ValueError, "not a digit");
+            return NULL;
+	}
+	else {
+	    Py_INCREF(defobj);
+	    return defobj;
+	}
+    }
+    return PyInt_FromLong(rc);
+}
+
+PyDoc_STRVAR(unicodedata_numeric__doc__,
+"numeric(unichr[, default])\n\
+\n\
+Returns the numeric value assigned to the Unicode character unichr\n\
+as float. If no such value is defined, default is returned, or, if\n\
+not given, ValueError is raised.");
+
+static PyObject *
+unicodedata_numeric(PyObject *self, PyObject *args)
+{
+    PyUnicodeObject *v;
+    PyObject *defobj = NULL;
+    int have_old = 0;
+    double rc;
+
+    if (!PyArg_ParseTuple(args, "O!|O:numeric", &PyUnicode_Type, &v, &defobj))
+        return NULL;
+    if (PyUnicode_GET_SIZE(v) != 1) {
+	PyErr_SetString(PyExc_TypeError,
+			"need a single Unicode character as parameter");
+	return NULL;
+    }
+
+    if (self) {
+        const change_record *old = get_old_record(self, *PyUnicode_AS_UNICODE(v));
+        if (old->category_changed == 0) {
+            /* unassigned */
+            have_old = 1;
+            rc = -1.0;
+        } 
+        else if (old->decimal_changed != 0xFF) {
+            have_old = 1;
+            rc = old->decimal_changed;
+        }
+    }
+
+    if (!have_old)
+        rc = Py_UNICODE_TONUMERIC(*PyUnicode_AS_UNICODE(v));
+    if (rc == -1.0) {
+	if (defobj == NULL) {
+	    PyErr_SetString(PyExc_ValueError, "not a numeric character");
+	    return NULL;
+	}
+	else {
+	    Py_INCREF(defobj);
+	    return defobj;
+	}
+    }
+    return PyFloat_FromDouble(rc);
+}
+
+PyDoc_STRVAR(unicodedata_category__doc__,
+"category(unichr)\n\
+\n\
+Returns the general category assigned to the Unicode character\n\
+unichr as string.");
+
+static PyObject *
+unicodedata_category(PyObject *self, PyObject *args)
+{
+    PyUnicodeObject *v;
+    int index;
+
+    if (!PyArg_ParseTuple(args, "O!:category",
+			  &PyUnicode_Type, &v))
+	return NULL;
+    if (PyUnicode_GET_SIZE(v) != 1) {
+	PyErr_SetString(PyExc_TypeError,
+			"need a single Unicode character as parameter");
+	return NULL;
+    }
+    index = (int) _getrecord(v)->category;
+    if (self) {
+        const change_record *old = get_old_record(self, *PyUnicode_AS_UNICODE(v));
+        if (old->category_changed != 0xFF)
+            index = old->category_changed;
+    }
+    return PyString_FromString(_PyUnicode_CategoryNames[index]);
+}
+
+PyDoc_STRVAR(unicodedata_bidirectional__doc__,
+"bidirectional(unichr)\n\
+\n\
+Returns the bidirectional category assigned to the Unicode character\n\
+unichr as string. If no such value is defined, an empty string is\n\
+returned.");
+
+static PyObject *
+unicodedata_bidirectional(PyObject *self, PyObject *args)
+{
+    PyUnicodeObject *v;
+    int index;
+
+    if (!PyArg_ParseTuple(args, "O!:bidirectional",
+			  &PyUnicode_Type, &v))
+	return NULL;
+    if (PyUnicode_GET_SIZE(v) != 1) {
+	PyErr_SetString(PyExc_TypeError,
+			"need a single Unicode character as parameter");
+	return NULL;
+    }
+    index = (int) _getrecord(v)->bidirectional;
+    if (self) {
+        const change_record *old = get_old_record(self, *PyUnicode_AS_UNICODE(v));
+        if (old->category_changed == 0)
+            index = 0; /* unassigned */
+        else if (old->bidir_changed != 0xFF)
+            index = old->bidir_changed;
+    }
+    return PyString_FromString(_PyUnicode_BidirectionalNames[index]);
+}
+
+PyDoc_STRVAR(unicodedata_combining__doc__,
+"combining(unichr)\n\
+\n\
+Returns the canonical combining class assigned to the Unicode\n\
+character unichr as integer. Returns 0 if no combining class is\n\
+defined.");
+
+static PyObject *
+unicodedata_combining(PyObject *self, PyObject *args)
+{
+    PyUnicodeObject *v;
+    int index;
+
+    if (!PyArg_ParseTuple(args, "O!:combining",
+			  &PyUnicode_Type, &v))
+	return NULL;
+    if (PyUnicode_GET_SIZE(v) != 1) {
+	PyErr_SetString(PyExc_TypeError,
+			"need a single Unicode character as parameter");
+	return NULL;
+    }
+    index = (int) _getrecord(v)->combining;
+    if (self) {
+        const change_record *old = get_old_record(self, *PyUnicode_AS_UNICODE(v));
+        if (old->category_changed == 0)
+            index = 0; /* unassigned */
+    }
+    return PyInt_FromLong(index);
+}
+
+PyDoc_STRVAR(unicodedata_mirrored__doc__,
+"mirrored(unichr)\n\
+\n\
+Returns the mirrored property assigned to the Unicode character\n\
+unichr as integer. Returns 1 if the character has been identified as\n\
+a \"mirrored\" character in bidirectional text, 0 otherwise.");
+
+static PyObject *
+unicodedata_mirrored(PyObject *self, PyObject *args)
+{
+    PyUnicodeObject *v;
+    int index;
+
+    if (!PyArg_ParseTuple(args, "O!:mirrored",
+			  &PyUnicode_Type, &v))
+	return NULL;
+    if (PyUnicode_GET_SIZE(v) != 1) {
+	PyErr_SetString(PyExc_TypeError,
+			"need a single Unicode character as parameter");
+	return NULL;
+    }
+    index = (int) _getrecord(v)->mirrored;
+    if (self) {
+        const change_record *old = get_old_record(self, *PyUnicode_AS_UNICODE(v));
+        if (old->category_changed == 0)
+            index = 0; /* unassigned */
+    }
+    return PyInt_FromLong(index);
+}
+
+PyDoc_STRVAR(unicodedata_east_asian_width__doc__,
+"east_asian_width(unichr)\n\
+\n\
+Returns the east asian width assigned to the Unicode character\n\
+unichr as string.");
+
+static PyObject *
+unicodedata_east_asian_width(PyObject *self, PyObject *args)
+{
+    PyUnicodeObject *v;
+    int index;
+
+    if (!PyArg_ParseTuple(args, "O!:east_asian_width",
+			  &PyUnicode_Type, &v))
+	return NULL;
+    if (PyUnicode_GET_SIZE(v) != 1) {
+	PyErr_SetString(PyExc_TypeError,
+			"need a single Unicode character as parameter");
+	return NULL;
+    }
+    index = (int) _getrecord(v)->east_asian_width;
+    if (self) {
+        const change_record *old = get_old_record(self, *PyUnicode_AS_UNICODE(v));
+        if (old->category_changed == 0)
+            index = 0; /* unassigned */
+    }
+    return PyString_FromString(_PyUnicode_EastAsianWidthNames[index]);
+}
+
+PyDoc_STRVAR(unicodedata_decomposition__doc__,
+"decomposition(unichr)\n\
+\n\
+Returns the character decomposition mapping assigned to the Unicode\n\
+character unichr as string. An empty string is returned in case no\n\
+such mapping is defined.");
+
+static PyObject *
+unicodedata_decomposition(PyObject *self, PyObject *args)
+{
+    PyUnicodeObject *v;
+    char decomp[256];
+    int code, index, count, i;
+    unsigned int prefix_index;
+
+    if (!PyArg_ParseTuple(args, "O!:decomposition",
+			  &PyUnicode_Type, &v))
+	return NULL;
+    if (PyUnicode_GET_SIZE(v) != 1) {
+	PyErr_SetString(PyExc_TypeError,
+			"need a single Unicode character as parameter");
+	return NULL;
+    }
+
+    code = (int) *PyUnicode_AS_UNICODE(v);
+
+    if (self) {
+        const change_record *old = get_old_record(self, *PyUnicode_AS_UNICODE(v));
+        if (old->category_changed == 0)
+            return PyString_FromString(""); /* unassigned */
+    }
+
+    if (code < 0 || code >= 0x110000)
+        index = 0;
+    else {
+        index = decomp_index1[(code>>DECOMP_SHIFT)];
+        index = decomp_index2[(index<<DECOMP_SHIFT)+
+                             (code&((1<<DECOMP_SHIFT)-1))];
+    }
+
+    /* high byte is number of hex bytes (usually one or two), low byte
+       is prefix code (from*/
+    count = decomp_data[index] >> 8;
+
+    /* XXX: could allocate the PyString up front instead
+       (strlen(prefix) + 5 * count + 1 bytes) */
+
+    /* Based on how index is calculated above and decomp_data is generated
+       from Tools/unicode/makeunicodedata.py, it should not be possible
+       to overflow decomp_prefix. */
+    prefix_index = decomp_data[index] & 255;
+    assert(prefix_index < (sizeof(decomp_prefix)/sizeof(*decomp_prefix)));
+
+    /* copy prefix */
+    i = strlen(decomp_prefix[prefix_index]);
+    memcpy(decomp, decomp_prefix[prefix_index], i);
+
+    while (count-- > 0) {
+        if (i)
+            decomp[i++] = ' ';
+        assert((size_t)i < sizeof(decomp));
+        PyOS_snprintf(decomp + i, sizeof(decomp) - i, "%04X",
+                      decomp_data[++index]);
+        i += strlen(decomp + i);
+    }
+    
+    decomp[i] = '\0';
+
+    return PyString_FromString(decomp);
+}
+
+static void
+get_decomp_record(PyObject *self, Py_UCS4 code, int *index, int *prefix, int *count)
+{
+    if (code >= 0x110000) {
+        *index = 0;
+    } else if (self && get_old_record(self, code)->category_changed==0) {
+        /* unassigned in old version */
+        *index = 0;
+    }
+    else {
+        *index = decomp_index1[(code>>DECOMP_SHIFT)];
+        *index = decomp_index2[(*index<<DECOMP_SHIFT)+
+                               (code&((1<<DECOMP_SHIFT)-1))];
+    }
+	
+    /* high byte is number of hex bytes (usually one or two), low byte
+       is prefix code (from*/
+    *count = decomp_data[*index] >> 8;
+    *prefix = decomp_data[*index] & 255;
+
+    (*index)++;
+}
+
+#define SBase   0xAC00
+#define LBase   0x1100
+#define VBase   0x1161
+#define TBase   0x11A7
+#define LCount  19
+#define VCount  21
+#define TCount  28
+#define NCount  (VCount*TCount)
+#define SCount  (LCount*NCount)
+
+static PyObject*
+nfd_nfkd(PyObject *self, PyObject *input, int k)
+{
+    PyObject *result;
+    Py_UNICODE *i, *end, *o;
+    /* Longest decomposition in Unicode 3.2: U+FDFA */
+    Py_UNICODE stack[20]; 
+    Py_ssize_t space, isize;
+    int index, prefix, count, stackptr;
+    unsigned char prev, cur;
+	
+    stackptr = 0;
+    isize = PyUnicode_GET_SIZE(input);
+    /* Overallocate atmost 10 characters. */
+    space = (isize > 10 ? 10 : isize) + isize;
+    result = PyUnicode_FromUnicode(NULL, space);
+    if (!result)
+        return NULL;
+    i = PyUnicode_AS_UNICODE(input);
+    end = i + isize;
+    o = PyUnicode_AS_UNICODE(result);
+
+    while (i < end) {
+        stack[stackptr++] = *i++;
+        while(stackptr) {
+            Py_UNICODE code = stack[--stackptr];
+            /* Hangul Decomposition adds three characters in
+               a single step, so we need atleast that much room. */
+            if (space < 3) {
+                Py_ssize_t newsize = PyString_GET_SIZE(result) + 10;
+                space += 10;
+                if (PyUnicode_Resize(&result, newsize) == -1)
+                    return NULL;
+                o = PyUnicode_AS_UNICODE(result) + newsize - space;
+            }
+            /* Hangul Decomposition. */
+            if (SBase <= code && code < (SBase+SCount)) {
+                int SIndex = code - SBase;
+                int L = LBase + SIndex / NCount;
+                int V = VBase + (SIndex % NCount) / TCount;
+                int T = TBase + SIndex % TCount;
+                *o++ = L;
+                *o++ = V;
+                space -= 2;
+                if (T != TBase) {
+                    *o++ = T;
+                    space --;
+                }
+                continue;
+            }
+            /* normalization changes */
+            if (self) {
+                Py_UCS4 value = ((PreviousDBVersion*)self)->normalization(code);
+                if (value != 0) {
+                    stack[stackptr++] = value;
+                    continue;
+                }
+            }
+
+            /* Other decompositions. */
+            get_decomp_record(self, code, &index, &prefix, &count);
+
+            /* Copy character if it is not decomposable, or has a
+               compatibility decomposition, but we do NFD. */
+            if (!count || (prefix && !k)) {
+                *o++ = code;
+                space--;
+                continue;
+            }
+            /* Copy decomposition onto the stack, in reverse
+               order.  */
+            while(count) {
+                code = decomp_data[index + (--count)];
+                stack[stackptr++] = code;
+            }
+        }
+    }
+
+    /* Drop overallocation. Cannot fail. */
+    PyUnicode_Resize(&result, PyUnicode_GET_SIZE(result) - space);
+
+    /* Sort canonically. */
+    i = PyUnicode_AS_UNICODE(result);
+    prev = _getrecord_ex(*i)->combining;
+    end = i + PyUnicode_GET_SIZE(result);
+    for (i++; i < end; i++) {
+        cur = _getrecord_ex(*i)->combining;
+        if (prev == 0 || cur == 0 || prev <= cur) {
+            prev = cur;
+            continue;
+        }
+        /* Non-canonical order. Need to switch *i with previous. */
+        o = i - 1;
+        while (1) {
+            Py_UNICODE tmp = o[1];
+            o[1] = o[0];
+            o[0] = tmp;
+            o--;
+            if (o < PyUnicode_AS_UNICODE(result))
+                break;
+            prev = _getrecord_ex(*o)->combining;
+            if (prev == 0 || prev <= cur)
+                break;
+        }
+        prev = _getrecord_ex(*i)->combining;
+    }
+    return result;
+}
+
+static int
+find_nfc_index(PyObject *self, struct reindex* nfc, Py_UNICODE code)
+{
+    int index;
+    for (index = 0; nfc[index].start; index++) {
+        int start = nfc[index].start;
+        if (code < start)
+            return -1;
+        if (code <= start + nfc[index].count) {
+            int delta = code - start;
+            return nfc[index].index + delta;
+        }
+    }
+    return -1;
+}
+
+static PyObject*
+nfc_nfkc(PyObject *self, PyObject *input, int k)
+{
+    PyObject *result;
+    Py_UNICODE *i, *i1, *o, *end;
+    int f,l,index,index1,comb;
+    Py_UNICODE code;
+    Py_UNICODE *skipped[20];
+    int cskipped = 0;
+
+    result = nfd_nfkd(self, input, k);
+    if (!result)
+        return NULL;
+
+    /* We are going to modify result in-place.
+       If nfd_nfkd is changed to sometimes return the input,
+       this code needs to be reviewed. */
+    assert(result != input);
+
+    i = PyUnicode_AS_UNICODE(result);
+    end = i + PyUnicode_GET_SIZE(result);
+    o = PyUnicode_AS_UNICODE(result);
+	
+  again:
+    while (i < end) {
+      for (index = 0; index < cskipped; index++) {
+          if (skipped[index] == i) {
+              /* *i character is skipped. 
+                 Remove from list. */
+              skipped[index] = skipped[cskipped-1];
+              cskipped--;
+              i++;
+              goto again; /* continue while */
+          }
+      }
+      /* Hangul Composition. We don't need to check for <LV,T>
+         pairs, since we always have decomposed data. */
+      if (LBase <= *i && *i < (LBase+LCount) &&
+          i + 1 < end && 
+          VBase <= i[1] && i[1] <= (VBase+VCount)) {
+          int LIndex, VIndex;
+          LIndex = i[0] - LBase;
+          VIndex = i[1] - VBase;
+          code = SBase + (LIndex*VCount+VIndex)*TCount;
+          i+=2;
+          if (i < end &&
+              TBase <= *i && *i <= (TBase+TCount)) {
+              code += *i-TBase;
+              i++;
+          }
+          *o++ = code;
+          continue;
+      }
+
+      f = find_nfc_index(self, nfc_first, *i);
+      if (f == -1) {
+          *o++ = *i++;
+          continue;
+      }
+      /* Find next unblocked character. */
+      i1 = i+1;
+      comb = 0;
+      while (i1 < end) {
+          int comb1 = _getrecord_ex(*i1)->combining;
+          if (comb1 && comb == comb1) {
+              /* Character is blocked. */
+              i1++;
+              continue;
+          }
+          l = find_nfc_index(self, nfc_last, *i1);
+          /* *i1 cannot be combined with *i. If *i1
+             is a starter, we don't need to look further.
+             Otherwise, record the combining class. */
+          if (l == -1) {
+            not_combinable:
+              if (comb1 == 0)
+                  break;
+              comb = comb1;
+              i1++;
+              continue;
+          }
+          index = f*TOTAL_LAST + l;
+          index1 = comp_index[index >> COMP_SHIFT];
+          code = comp_data[(index1<<COMP_SHIFT)+
+                           (index&((1<<COMP_SHIFT)-1))];
+          if (code == 0)
+              goto not_combinable;
+			
+          /* Replace the original character. */
+          *i = code;
+          /* Mark the second character unused. */
+          skipped[cskipped++] = i1;
+          i1++;
+          f = find_nfc_index(self, nfc_first, *i);
+          if (f == -1)
+              break;
+      }
+      *o++ = *i++;
+    }
+    if (o != end)
+        PyUnicode_Resize(&result, o - PyUnicode_AS_UNICODE(result));
+    return result;
+}
+		
+PyDoc_STRVAR(unicodedata_normalize__doc__,
+"normalize(form, unistr)\n\
+\n\
+Return the normal form 'form' for the Unicode string unistr.  Valid\n\
+values for form are 'NFC', 'NFKC', 'NFD', and 'NFKD'.");
+
+static PyObject*
+unicodedata_normalize(PyObject *self, PyObject *args)
+{
+    char *form;
+    PyObject *input;
+
+    if(!PyArg_ParseTuple(args, "sO!:normalize",
+                         &form, &PyUnicode_Type, &input))
+        return NULL;
+
+    if (PyUnicode_GetSize(input) == 0) {
+        /* Special case empty input strings, since resizing
+           them  later would cause internal errors. */
+        Py_INCREF(input);
+        return input;
+    }
+
+    if (strcmp(form, "NFC") == 0)
+        return nfc_nfkc(self, input, 0);
+    if (strcmp(form, "NFKC") == 0)
+        return nfc_nfkc(self, input, 1);
+    if (strcmp(form, "NFD") == 0)
+        return nfd_nfkd(self, input, 0);
+    if (strcmp(form, "NFKD") == 0)
+        return nfd_nfkd(self, input, 1);
+    PyErr_SetString(PyExc_ValueError, "invalid normalization form");
+    return NULL;
+}
+
+/* -------------------------------------------------------------------- */
+/* unicode character name tables */
+
+/* data file generated by Tools/unicode/makeunicodedata.py */
+#include "unicodename_db.h"
+
+/* -------------------------------------------------------------------- */
+/* database code (cut and pasted from the unidb package) */
+
+static unsigned long
+_gethash(const char *s, int len, int scale)
+{
+    int i;
+    unsigned long h = 0;
+    unsigned long ix;
+    for (i = 0; i < len; i++) {
+        h = (h * scale) + (unsigned char) toupper(Py_CHARMASK(s[i]));
+        ix = h & 0xff000000;
+        if (ix)
+            h = (h ^ ((ix>>24) & 0xff)) & 0x00ffffff;
+    }
+    return h;
+}
+
+static char *hangul_syllables[][3] = {
+    { "G",  "A",   ""   },
+    { "GG", "AE",  "G"  },
+    { "N",  "YA",  "GG" },
+    { "D",  "YAE", "GS" },
+    { "DD", "EO",  "N", },
+    { "R",  "E",   "NJ" },
+    { "M",  "YEO", "NH" },
+    { "B",  "YE",  "D"  },
+    { "BB", "O",   "L"  },
+    { "S",  "WA",  "LG" },
+    { "SS", "WAE", "LM" },
+    { "",   "OE",  "LB" },
+    { "J",  "YO",  "LS" },
+    { "JJ", "U",   "LT" },
+    { "C",  "WEO", "LP" },
+    { "K",  "WE",  "LH" },
+    { "T",  "WI",  "M"  },
+    { "P",  "YU",  "B"  },
+    { "H",  "EU",  "BS" },
+    { 0,    "YI",  "S"  },
+    { 0,    "I",   "SS" },
+    { 0,    0,     "NG" },
+    { 0,    0,     "J"  },
+    { 0,    0,     "C"  },
+    { 0,    0,     "K"  },
+    { 0,    0,     "T"  },
+    { 0,    0,     "P"  },
+    { 0,    0,     "H"  }
+};
+
+static int
+is_unified_ideograph(Py_UCS4 code)
+{
+    return (
+        (0x3400 <= code && code <= 0x4DB5) || /* CJK Ideograph Extension A */
+        (0x4E00 <= code && code <= 0x9FBB) || /* CJK Ideograph */
+        (0x20000 <= code && code <= 0x2A6D6));/* CJK Ideograph Extension B */
+}
+
+static int
+_getucname(PyObject *self, Py_UCS4 code, char* buffer, int buflen)
+{
+    int offset;
+    int i;
+    int word;
+    unsigned char* w;
+
+    if (code >= 0x110000)
+        return 0;
+
+    if (self) {
+        const change_record *old = get_old_record(self, code);
+        if (old->category_changed == 0) {
+            /* unassigned */
+            return 0;
+        } 
+    }
+
+    if (SBase <= code && code < SBase+SCount) {
+	/* Hangul syllable. */
+	int SIndex = code - SBase;
+	int L = SIndex / NCount;
+	int V = (SIndex % NCount) / TCount;
+	int T = SIndex % TCount;
+
+	if (buflen < 27)
+	    /* Worst case: HANGUL SYLLABLE <10chars>. */
+	    return 0;
+	strcpy(buffer, "HANGUL SYLLABLE ");
+	buffer += 16;
+	strcpy(buffer, hangul_syllables[L][0]);
+	buffer += strlen(hangul_syllables[L][0]);
+	strcpy(buffer, hangul_syllables[V][1]);
+	buffer += strlen(hangul_syllables[V][1]);
+	strcpy(buffer, hangul_syllables[T][2]);
+	buffer += strlen(hangul_syllables[T][2]);
+	*buffer = '\0';
+	return 1;
+    }
+
+    if (is_unified_ideograph(code)) {
+        if (buflen < 28)
+            /* Worst case: CJK UNIFIED IDEOGRAPH-20000 */
+            return 0;
+        sprintf(buffer, "CJK UNIFIED IDEOGRAPH-%X", code);
+        return 1;
+    }
+
+    /* get offset into phrasebook */
+    offset = phrasebook_offset1[(code>>phrasebook_shift)];
+    offset = phrasebook_offset2[(offset<<phrasebook_shift) +
+                               (code&((1<<phrasebook_shift)-1))];
+    if (!offset)
+        return 0;
+
+    i = 0;
+
+    for (;;) {
+        /* get word index */
+        word = phrasebook[offset] - phrasebook_short;
+        if (word >= 0) {
+            word = (word << 8) + phrasebook[offset+1];
+            offset += 2;
+        } else
+            word = phrasebook[offset++];
+        if (i) {
+            if (i > buflen)
+                return 0; /* buffer overflow */
+            buffer[i++] = ' ';
+        }
+        /* copy word string from lexicon.  the last character in the
+           word has bit 7 set.  the last word in a string ends with
+           0x80 */
+        w = lexicon + lexicon_offset[word];
+        while (*w < 128) {
+            if (i >= buflen)
+                return 0; /* buffer overflow */
+            buffer[i++] = *w++;
+        }
+        if (i >= buflen)
+            return 0; /* buffer overflow */
+        buffer[i++] = *w & 127;
+        if (*w == 128)
+            break; /* end of word */
+    }
+
+    return 1;
+}
+
+static int
+_cmpname(PyObject *self, int code, const char* name, int namelen)
+{
+    /* check if code corresponds to the given name */
+    int i;
+    char buffer[NAME_MAXLEN];
+    if (!_getucname(self, code, buffer, sizeof(buffer)))
+        return 0;
+    for (i = 0; i < namelen; i++) {
+        if (toupper(Py_CHARMASK(name[i])) != buffer[i])
+            return 0;
+    }
+    return buffer[namelen] == '\0';
+}
+
+static void 
+find_syllable(const char *str, int *len, int *pos, int count, int column)
+{
+    int i, len1;
+    *len = -1;
+    for (i = 0; i < count; i++) {
+	char *s = hangul_syllables[i][column];
+	len1 = strlen(s);
+	if (len1 <= *len)
+	    continue;
+	if (strncmp(str, s, len1) == 0) {
+	    *len = len1;
+	    *pos = i;
+	}
+    }
+    if (*len == -1) {
+	*len = 0;
+    }
+}
+
+static int
+_getcode(PyObject* self, const char* name, int namelen, Py_UCS4* code)
+{
+    unsigned int h, v;
+    unsigned int mask = code_size-1;
+    unsigned int i, incr;
+
+    /* Check for hangul syllables. */
+    if (strncmp(name, "HANGUL SYLLABLE ", 16) == 0) {
+	int len, L = -1, V = -1, T = -1;
+	const char *pos = name + 16;
+	find_syllable(pos, &len, &L, LCount, 0);
+	pos += len;
+	find_syllable(pos, &len, &V, VCount, 1);
+	pos += len;
+	find_syllable(pos, &len, &T, TCount, 2);
+	pos += len;
+	if (L != -1 && V != -1 && T != -1 && pos-name == namelen) {
+	    *code = SBase + (L*VCount+V)*TCount + T;
+	    return 1;
+	}
+        /* Otherwise, it's an illegal syllable name. */
+        return 0;
+    }
+
+    /* Check for unified ideographs. */
+    if (strncmp(name, "CJK UNIFIED IDEOGRAPH-", 22) == 0) {
+        /* Four or five hexdigits must follow. */
+        v = 0;
+        name += 22;
+        namelen -= 22;
+        if (namelen != 4 && namelen != 5)
+            return 0;
+        while (namelen--) {
+            v *= 16;
+            if (*name >= '0' && *name <= '9')
+                v += *name - '0';
+            else if (*name >= 'A' && *name <= 'F')
+                v += *name - 'A' + 10;
+            else
+                return 0;
+            name++;
+        }
+        if (!is_unified_ideograph(v))
+            return 0;
+        *code = v;
+        return 1;
+    }
+
+    /* the following is the same as python's dictionary lookup, with
+       only minor changes.  see the makeunicodedata script for more
+       details */
+
+    h = (unsigned int) _gethash(name, namelen, code_magic);
+    i = (~h) & mask;
+    v = code_hash[i];
+    if (!v)
+        return 0;
+    if (_cmpname(self, v, name, namelen)) {
+        *code = v;
+        return 1;
+    }
+    incr = (h ^ (h >> 3)) & mask;
+    if (!incr)
+        incr = mask;
+    for (;;) {
+        i = (i + incr) & mask;
+        v = code_hash[i];
+        if (!v)
+            return 0;
+        if (_cmpname(self, v, name, namelen)) {
+            *code = v;
+            return 1;
+        }
+        incr = incr << 1;
+        if (incr > mask)
+            incr = incr ^ code_poly;
+    }
+}
+
+static const _PyUnicode_Name_CAPI hashAPI = 
+{
+    sizeof(_PyUnicode_Name_CAPI),
+    _getucname,
+    _getcode
+};
+
+/* -------------------------------------------------------------------- */
+/* Python bindings */
+
+PyDoc_STRVAR(unicodedata_name__doc__,
+"name(unichr[, default])\n\
+Returns the name assigned to the Unicode character unichr as a\n\
+string. If no name is defined, default is returned, or, if not\n\
+given, ValueError is raised.");
+
+static PyObject *
+unicodedata_name(PyObject* self, PyObject* args)
+{
+    char name[NAME_MAXLEN];
+
+    PyUnicodeObject* v;
+    PyObject* defobj = NULL;
+    if (!PyArg_ParseTuple(args, "O!|O:name", &PyUnicode_Type, &v, &defobj))
+        return NULL;
+
+    if (PyUnicode_GET_SIZE(v) != 1) {
+	PyErr_SetString(PyExc_TypeError,
+			"need a single Unicode character as parameter");
+	return NULL;
+    }
+
+    if (!_getucname(self, (Py_UCS4) *PyUnicode_AS_UNICODE(v),
+                    name, sizeof(name))) {
+	if (defobj == NULL) {
+	    PyErr_SetString(PyExc_ValueError, "no such name");
+            return NULL;
+	}
+	else {
+	    Py_INCREF(defobj);
+	    return defobj;
+	}
+    }
+
+    return Py_BuildValue("s", name);
+}
+
+PyDoc_STRVAR(unicodedata_lookup__doc__,
+"lookup(name)\n\
+\n\
+Look up character by name.  If a character with the\n\
+given name is found, return the corresponding Unicode\n\
+character.  If not found, KeyError is raised.");
+
+static PyObject *
+unicodedata_lookup(PyObject* self, PyObject* args)
+{
+    Py_UCS4 code;
+    Py_UNICODE str[1];
+    char errbuf[256];
+
+    char* name;
+    int namelen;
+    if (!PyArg_ParseTuple(args, "s#:lookup", &name, &namelen))
+        return NULL;
+
+    if (!_getcode(self, name, namelen, &code)) {
+	/* XXX(nnorwitz): why are we allocating for the error msg?
+		Why not always use snprintf? */
+        char fmt[] = "undefined character name '%s'";
+        char *buf = PyMem_MALLOC(sizeof(fmt) + namelen);
+        if (buf)
+            sprintf(buf, fmt, name);
+        else {
+            buf = errbuf;
+            PyOS_snprintf(buf, sizeof(errbuf), fmt, name);
+        }
+        PyErr_SetString(PyExc_KeyError, buf);
+        if (buf != errbuf)
+        	PyMem_FREE(buf);
+        return NULL;
+    }
+
+    str[0] = (Py_UNICODE) code;
+    return PyUnicode_FromUnicode(str, 1);
+}
+
+/* XXX Add doc strings. */
+
+static PyMethodDef unicodedata_functions[] = {
+    {"decimal", unicodedata_decimal, METH_VARARGS, unicodedata_decimal__doc__},
+    {"digit", unicodedata_digit, METH_VARARGS, unicodedata_digit__doc__},
+    {"numeric", unicodedata_numeric, METH_VARARGS, unicodedata_numeric__doc__},
+    {"category", unicodedata_category, METH_VARARGS,
+                 unicodedata_category__doc__},
+    {"bidirectional", unicodedata_bidirectional, METH_VARARGS,
+                      unicodedata_bidirectional__doc__},
+    {"combining", unicodedata_combining, METH_VARARGS,
+                  unicodedata_combining__doc__},
+    {"mirrored", unicodedata_mirrored, METH_VARARGS,
+                 unicodedata_mirrored__doc__},
+    {"east_asian_width", unicodedata_east_asian_width, METH_VARARGS,
+                         unicodedata_east_asian_width__doc__},
+    {"decomposition", unicodedata_decomposition, METH_VARARGS,
+                      unicodedata_decomposition__doc__},
+    {"name", unicodedata_name, METH_VARARGS, unicodedata_name__doc__},
+    {"lookup", unicodedata_lookup, METH_VARARGS, unicodedata_lookup__doc__},
+    {"normalize", unicodedata_normalize, METH_VARARGS,
+                  unicodedata_normalize__doc__},
+    {NULL, NULL}		/* sentinel */
+};
+
+static PyTypeObject UCD_Type = {
+	/* The ob_type field must be initialized in the module init function
+	 * to be portable to Windows without using C++. */
+	PyObject_HEAD_INIT(NULL)
+	0,			/*ob_size*/
+	"unicodedata.UCD",		/*tp_name*/
+	sizeof(PreviousDBVersion),	/*tp_basicsize*/
+	0,			/*tp_itemsize*/
+	/* methods */
+	(destructor)PyObject_Del, /*tp_dealloc*/
+	0,			/*tp_print*/
+	0,                      /*tp_getattr*/
+	0,			/*tp_setattr*/
+	0,			/*tp_compare*/
+	0,			/*tp_repr*/
+	0,			/*tp_as_number*/
+	0,			/*tp_as_sequence*/
+	0,			/*tp_as_mapping*/
+	0,			/*tp_hash*/
+        0,                      /*tp_call*/
+        0,                      /*tp_str*/
+        PyObject_GenericGetAttr,/*tp_getattro*/
+        0,                      /*tp_setattro*/
+        0,                      /*tp_as_buffer*/
+        Py_TPFLAGS_DEFAULT,     /*tp_flags*/
+        0,                      /*tp_doc*/
+        0,                      /*tp_traverse*/
+        0,                      /*tp_clear*/
+        0,                      /*tp_richcompare*/
+        0,                      /*tp_weaklistoffset*/
+        0,                      /*tp_iter*/
+        0,                      /*tp_iternext*/
+        unicodedata_functions,  /*tp_methods*/
+        DB_members,             /*tp_members*/
+        0,                      /*tp_getset*/
+        0,                      /*tp_base*/
+        0,                      /*tp_dict*/
+        0,                      /*tp_descr_get*/
+        0,                      /*tp_descr_set*/
+        0,                      /*tp_dictoffset*/
+        0,                      /*tp_init*/
+        0,                      /*tp_alloc*/
+        0,                      /*tp_new*/
+        0,                      /*tp_free*/
+        0,                      /*tp_is_gc*/
+};
+
+PyDoc_STRVAR(unicodedata_docstring,
+"This module provides access to the Unicode Character Database which\n\
+defines character properties for all Unicode characters. The data in\n\
+this database is based on the UnicodeData.txt file version\n\
+4.1.0 which is publically available from ftp://ftp.unicode.org/.\n\
+\n\
+The module uses the same names and symbols as defined by the\n\
+UnicodeData File Format 4.1.0 (see\n\
+http://www.unicode.org/Public/4.1.0/ucd/UCD.html).");
+
+PyMODINIT_FUNC
+initunicodedata(void)
+{
+    PyObject *m, *v;
+
+    UCD_Type.ob_type = &PyType_Type;
+
+    m = Py_InitModule3(
+        "unicodedata", unicodedata_functions, unicodedata_docstring);
+    if (!m)
+        return;
+
+    PyModule_AddStringConstant(m, "unidata_version", UNIDATA_VERSION);
+    Py_INCREF(&UCD_Type);
+    PyModule_AddObject(m, "UCD", (PyObject*)&UCD_Type);
+
+    /* Previous versions */
+    v = new_previous_version("3.2.0", get_change_3_2_0, normalization_3_2_0);
+    if (v != NULL)
+        PyModule_AddObject(m, "ucd_3_2_0", v);
+
+    /* Export C API */
+    v = PyCObject_FromVoidPtr((void *) &hashAPI, NULL);
+    if (v != NULL)
+        PyModule_AddObject(m, "ucnhash_CAPI", v);
+}
+
+/* 
+Local variables:
+c-basic-offset: 4
+indent-tabs-mode: nil
+End:
+*/

Added: vendor/Python/current/Modules/unicodedata_db.h
===================================================================
--- vendor/Python/current/Modules/unicodedata_db.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/unicodedata_db.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,5135 @@
+/* this file was generated by Tools/unicode/makeunicodedata.py 2.5 */
+
+#define UNIDATA_VERSION "4.1.0"
+/* a list of unique database records */
+const _PyUnicode_DatabaseRecord _PyUnicode_Database_Records[] = {
+    {0, 0, 0, 0, 0},
+    {13, 0, 15, 0, 5},
+    {13, 0, 17, 0, 5},
+    {13, 0, 16, 0, 5},
+    {13, 0, 18, 0, 5},
+    {10, 0, 18, 0, 3},
+    {26, 0, 19, 0, 3},
+    {26, 0, 11, 0, 3},
+    {28, 0, 11, 0, 3},
+    {22, 0, 19, 1, 3},
+    {23, 0, 19, 1, 3},
+    {27, 0, 10, 0, 3},
+    {26, 0, 13, 0, 3},
+    {21, 0, 10, 0, 3},
+    {7, 0, 9, 0, 3},
+    {27, 0, 19, 1, 3},
+    {27, 0, 19, 0, 3},
+    {1, 0, 1, 0, 3},
+    {29, 0, 19, 0, 3},
+    {20, 0, 19, 0, 3},
+    {2, 0, 1, 0, 3},
+    {10, 0, 13, 0, 5},
+    {26, 0, 19, 0, 4},
+    {28, 0, 11, 0, 4},
+    {30, 0, 19, 0, 3},
+    {30, 0, 19, 0, 4},
+    {29, 0, 19, 0, 4},
+    {30, 0, 19, 0, 5},
+    {2, 0, 1, 0, 4},
+    {24, 0, 19, 1, 5},
+    {14, 0, 15, 0, 4},
+    {30, 0, 11, 0, 4},
+    {27, 0, 11, 0, 4},
+    {9, 0, 9, 0, 4},
+    {2, 0, 1, 0, 5},
+    {25, 0, 19, 1, 5},
+    {9, 0, 19, 0, 4},
+    {1, 0, 1, 0, 5},
+    {1, 0, 1, 0, 4},
+    {27, 0, 19, 0, 4},
+    {19, 0, 1, 0, 5},
+    {3, 0, 1, 0, 5},
+    {18, 0, 1, 0, 5},
+    {18, 0, 19, 0, 5},
+    {29, 0, 19, 0, 5},
+    {18, 0, 19, 0, 4},
+    {18, 0, 1, 0, 4},
+    {4, 230, 14, 0, 4},
+    {4, 232, 14, 0, 4},
+    {4, 220, 14, 0, 4},
+    {4, 216, 14, 0, 4},
+    {4, 202, 14, 0, 4},
+    {4, 1, 14, 0, 4},
+    {4, 240, 14, 0, 4},
+    {4, 0, 14, 0, 4},
+    {4, 233, 14, 0, 4},
+    {4, 234, 14, 0, 4},
+    {26, 0, 19, 0, 5},
+    {27, 0, 19, 0, 5},
+    {30, 0, 1, 0, 5},
+    {4, 230, 14, 0, 5},
+    {6, 0, 14, 0, 5},
+    {26, 0, 1, 0, 5},
+    {21, 0, 19, 0, 5},
+    {4, 220, 14, 0, 5},
+    {4, 222, 14, 0, 5},
+    {4, 228, 14, 0, 5},
+    {4, 10, 14, 0, 5},
+    {4, 11, 14, 0, 5},
+    {4, 12, 14, 0, 5},
+    {4, 13, 14, 0, 5},
+    {4, 14, 14, 0, 5},
+    {4, 15, 14, 0, 5},
+    {4, 16, 14, 0, 5},
+    {4, 17, 14, 0, 5},
+    {4, 18, 14, 0, 5},
+    {4, 19, 14, 0, 5},
+    {4, 20, 14, 0, 5},
+    {4, 21, 14, 0, 5},
+    {4, 22, 14, 0, 5},
+    {26, 0, 4, 0, 5},
+    {4, 23, 14, 0, 5},
+    {4, 24, 14, 0, 5},
+    {4, 25, 14, 0, 5},
+    {19, 0, 4, 0, 5},
+    {14, 0, 5, 0, 5},
+    {28, 0, 5, 0, 5},
+    {26, 0, 13, 0, 5},
+    {26, 0, 5, 0, 5},
+    {19, 0, 5, 0, 5},
+    {18, 0, 5, 0, 5},
+    {4, 27, 14, 0, 5},
+    {4, 28, 14, 0, 5},
+    {4, 29, 14, 0, 5},
+    {4, 30, 14, 0, 5},
+    {4, 31, 14, 0, 5},
+    {4, 32, 14, 0, 5},
+    {4, 33, 14, 0, 5},
+    {4, 34, 14, 0, 5},
+    {7, 0, 12, 0, 5},
+    {26, 0, 11, 0, 5},
+    {26, 0, 12, 0, 5},
+    {4, 35, 14, 0, 5},
+    {7, 0, 9, 0, 5},
+    {30, 0, 5, 0, 5},
+    {14, 0, 15, 0, 5},
+    {4, 36, 14, 0, 5},
+    {4, 0, 14, 0, 5},
+    {5, 0, 1, 0, 5},
+    {4, 7, 14, 0, 5},
+    {4, 9, 14, 0, 5},
+    {7, 0, 1, 0, 5},
+    {28, 0, 11, 0, 5},
+    {9, 0, 1, 0, 5},
+    {4, 84, 14, 0, 5},
+    {4, 91, 14, 0, 5},
+    {4, 0, 1, 0, 5},
+    {4, 103, 14, 0, 5},
+    {4, 107, 14, 0, 5},
+    {4, 118, 14, 0, 5},
+    {4, 122, 14, 0, 5},
+    {4, 216, 14, 0, 5},
+    {22, 0, 19, 0, 5},
+    {23, 0, 19, 0, 5},
+    {4, 129, 14, 0, 5},
+    {4, 130, 14, 0, 5},
+    {4, 132, 14, 0, 5},
+    {19, 0, 1, 0, 2},
+    {10, 0, 18, 0, 5},
+    {8, 0, 1, 0, 5},
+    {14, 0, 1, 0, 5},
+    {9, 0, 19, 0, 5},
+    {5, 0, 14, 0, 5},
+    {14, 0, 4, 0, 5},
+    {21, 0, 19, 0, 4},
+    {24, 0, 19, 0, 4},
+    {25, 0, 19, 0, 4},
+    {24, 0, 19, 0, 5},
+    {11, 0, 18, 0, 5},
+    {12, 0, 16, 0, 5},
+    {14, 0, 2, 0, 5},
+    {14, 0, 6, 0, 5},
+    {14, 0, 8, 0, 5},
+    {14, 0, 3, 0, 5},
+    {14, 0, 7, 0, 5},
+    {26, 0, 11, 0, 4},
+    {20, 0, 19, 0, 5},
+    {27, 0, 13, 0, 5},
+    {22, 0, 19, 1, 5},
+    {23, 0, 19, 1, 5},
+    {9, 0, 9, 0, 5},
+    {27, 0, 10, 0, 5},
+    {28, 0, 11, 0, 1},
+    {4, 1, 14, 0, 5},
+    {30, 0, 11, 0, 5},
+    {27, 0, 19, 1, 5},
+    {8, 0, 1, 0, 4},
+    {27, 0, 19, 1, 4},
+    {27, 0, 11, 0, 5},
+    {22, 0, 19, 1, 2},
+    {23, 0, 19, 1, 2},
+    {30, 0, 1, 0, 4},
+    {30, 0, 19, 0, 2},
+    {10, 0, 18, 0, 0},
+    {26, 0, 19, 0, 2},
+    {18, 0, 1, 0, 2},
+    {8, 0, 1, 0, 2},
+    {21, 0, 19, 0, 2},
+    {22, 0, 19, 0, 2},
+    {23, 0, 19, 0, 2},
+    {4, 218, 14, 0, 2},
+    {4, 228, 14, 0, 2},
+    {4, 232, 14, 0, 2},
+    {4, 222, 14, 0, 2},
+    {4, 224, 14, 0, 2},
+    {4, 8, 14, 0, 2},
+    {29, 0, 19, 0, 2},
+    {30, 0, 1, 0, 2},
+    {9, 0, 1, 0, 2},
+    {9, 0, 19, 0, 2},
+    {15, 0, 1, 0, 5},
+    {16, 0, 1, 0, 4},
+    {4, 26, 14, 0, 5},
+    {20, 0, 19, 0, 2},
+    {26, 0, 13, 0, 2},
+    {26, 0, 11, 0, 2},
+    {27, 0, 10, 0, 2},
+    {21, 0, 10, 0, 2},
+    {27, 0, 19, 0, 2},
+    {28, 0, 11, 0, 2},
+    {26, 0, 19, 0, 0},
+    {26, 0, 11, 0, 0},
+    {28, 0, 11, 0, 0},
+    {22, 0, 19, 1, 0},
+    {23, 0, 19, 1, 0},
+    {27, 0, 10, 0, 0},
+    {26, 0, 13, 0, 0},
+    {21, 0, 10, 0, 0},
+    {7, 0, 9, 0, 0},
+    {27, 0, 19, 1, 0},
+    {27, 0, 19, 0, 0},
+    {1, 0, 1, 0, 0},
+    {29, 0, 19, 0, 0},
+    {20, 0, 19, 0, 0},
+    {2, 0, 1, 0, 0},
+    {26, 0, 19, 0, 1},
+    {22, 0, 19, 1, 1},
+    {23, 0, 19, 1, 1},
+    {19, 0, 1, 0, 1},
+    {18, 0, 1, 0, 1},
+    {30, 0, 19, 0, 0},
+    {30, 0, 19, 0, 1},
+    {27, 0, 19, 0, 1},
+    {14, 0, 19, 0, 5},
+    {8, 0, 19, 0, 5},
+    {9, 0, 4, 0, 5},
+    {5, 216, 1, 0, 5},
+    {5, 226, 1, 0, 5},
+    {27, 0, 1, 0, 5},
+};
+
+/* Reindexing of NFC first characters. */
+#define TOTAL_FIRST 356
+#define TOTAL_LAST 53
+struct reindex{int start;short count,index;};
+struct reindex nfc_first[] = {
+  { 60, 2, 0},
+  { 65, 15, 3},
+  { 82, 8, 19},
+  { 97, 15, 28},
+  { 114, 8, 44},
+  { 168, 0, 53},
+  { 194, 0, 54},
+  { 196, 3, 55},
+  { 202, 0, 59},
+  { 207, 0, 60},
+  { 212, 2, 61},
+  { 216, 0, 64},
+  { 220, 0, 65},
+  { 226, 0, 66},
+  { 228, 3, 67},
+  { 234, 0, 71},
+  { 239, 0, 72},
+  { 244, 2, 73},
+  { 248, 0, 76},
+  { 252, 0, 77},
+  { 258, 1, 78},
+  { 274, 1, 80},
+  { 332, 1, 82},
+  { 346, 1, 84},
+  { 352, 1, 86},
+  { 360, 3, 88},
+  { 383, 0, 92},
+  { 416, 1, 93},
+  { 431, 1, 95},
+  { 439, 0, 97},
+  { 490, 1, 98},
+  { 550, 3, 100},
+  { 558, 1, 104},
+  { 658, 0, 106},
+  { 913, 0, 107},
+  { 917, 0, 108},
+  { 919, 0, 109},
+  { 921, 0, 110},
+  { 927, 0, 111},
+  { 929, 0, 112},
+  { 933, 0, 113},
+  { 937, 0, 114},
+  { 940, 0, 115},
+  { 942, 0, 116},
+  { 945, 0, 117},
+  { 949, 0, 118},
+  { 951, 0, 119},
+  { 953, 0, 120},
+  { 959, 0, 121},
+  { 961, 0, 122},
+  { 965, 0, 123},
+  { 969, 2, 124},
+  { 974, 0, 127},
+  { 978, 0, 128},
+  { 1030, 0, 129},
+  { 1040, 0, 130},
+  { 1043, 0, 131},
+  { 1045, 3, 132},
+  { 1050, 0, 136},
+  { 1054, 0, 137},
+  { 1059, 0, 138},
+  { 1063, 0, 139},
+  { 1067, 0, 140},
+  { 1069, 0, 141},
+  { 1072, 0, 142},
+  { 1075, 0, 143},
+  { 1077, 3, 144},
+  { 1082, 0, 148},
+  { 1086, 0, 149},
+  { 1091, 0, 150},
+  { 1095, 0, 151},
+  { 1099, 0, 152},
+  { 1101, 0, 153},
+  { 1110, 0, 154},
+  { 1140, 1, 155},
+  { 1240, 1, 157},
+  { 1256, 1, 159},
+  { 1575, 0, 161},
+  { 1608, 0, 162},
+  { 1610, 0, 163},
+  { 1729, 0, 164},
+  { 1746, 0, 165},
+  { 1749, 0, 166},
+  { 2344, 0, 167},
+  { 2352, 0, 168},
+  { 2355, 0, 169},
+  { 2503, 0, 170},
+  { 2887, 0, 171},
+  { 2962, 0, 172},
+  { 3014, 1, 173},
+  { 3142, 0, 175},
+  { 3263, 0, 176},
+  { 3270, 0, 177},
+  { 3274, 0, 178},
+  { 3398, 1, 179},
+  { 3545, 0, 181},
+  { 3548, 0, 182},
+  { 4133, 0, 183},
+  { 7734, 1, 184},
+  { 7770, 1, 186},
+  { 7778, 1, 188},
+  { 7840, 1, 190},
+  { 7864, 1, 192},
+  { 7884, 1, 194},
+  { 7936, 17, 196},
+  { 7960, 1, 214},
+  { 7968, 17, 216},
+  { 7992, 1, 234},
+  { 8000, 1, 236},
+  { 8008, 1, 238},
+  { 8016, 1, 240},
+  { 8025, 0, 242},
+  { 8032, 16, 243},
+  { 8052, 0, 260},
+  { 8060, 0, 261},
+  { 8118, 0, 262},
+  { 8127, 0, 263},
+  { 8134, 0, 264},
+  { 8182, 0, 265},
+  { 8190, 0, 266},
+  { 8592, 0, 267},
+  { 8594, 0, 268},
+  { 8596, 0, 269},
+  { 8656, 0, 270},
+  { 8658, 0, 271},
+  { 8660, 0, 272},
+  { 8707, 0, 273},
+  { 8712, 0, 274},
+  { 8715, 0, 275},
+  { 8739, 0, 276},
+  { 8741, 0, 277},
+  { 8764, 0, 278},
+  { 8771, 0, 279},
+  { 8773, 0, 280},
+  { 8776, 0, 281},
+  { 8781, 0, 282},
+  { 8801, 0, 283},
+  { 8804, 1, 284},
+  { 8818, 1, 286},
+  { 8822, 1, 288},
+  { 8826, 3, 290},
+  { 8834, 1, 294},
+  { 8838, 1, 296},
+  { 8849, 1, 298},
+  { 8866, 0, 300},
+  { 8872, 1, 301},
+  { 8875, 0, 303},
+  { 8882, 3, 304},
+  { 12358, 0, 308},
+  { 12363, 0, 309},
+  { 12365, 0, 310},
+  { 12367, 0, 311},
+  { 12369, 0, 312},
+  { 12371, 0, 313},
+  { 12373, 0, 314},
+  { 12375, 0, 315},
+  { 12377, 0, 316},
+  { 12379, 0, 317},
+  { 12381, 0, 318},
+  { 12383, 0, 319},
+  { 12385, 0, 320},
+  { 12388, 0, 321},
+  { 12390, 0, 322},
+  { 12392, 0, 323},
+  { 12399, 0, 324},
+  { 12402, 0, 325},
+  { 12405, 0, 326},
+  { 12408, 0, 327},
+  { 12411, 0, 328},
+  { 12445, 0, 329},
+  { 12454, 0, 330},
+  { 12459, 0, 331},
+  { 12461, 0, 332},
+  { 12463, 0, 333},
+  { 12465, 0, 334},
+  { 12467, 0, 335},
+  { 12469, 0, 336},
+  { 12471, 0, 337},
+  { 12473, 0, 338},
+  { 12475, 0, 339},
+  { 12477, 0, 340},
+  { 12479, 0, 341},
+  { 12481, 0, 342},
+  { 12484, 0, 343},
+  { 12486, 0, 344},
+  { 12488, 0, 345},
+  { 12495, 0, 346},
+  { 12498, 0, 347},
+  { 12501, 0, 348},
+  { 12504, 0, 349},
+  { 12507, 0, 350},
+  { 12527, 3, 351},
+  { 12541, 0, 355},
+  {0,0,0}
+};
+
+struct reindex nfc_last[] = {
+  { 768, 4, 0},
+  { 774, 6, 5},
+  { 783, 0, 12},
+  { 785, 0, 13},
+  { 787, 1, 14},
+  { 795, 0, 16},
+  { 803, 5, 17},
+  { 813, 1, 23},
+  { 816, 1, 25},
+  { 824, 0, 27},
+  { 834, 0, 28},
+  { 837, 0, 29},
+  { 1619, 2, 30},
+  { 2364, 0, 33},
+  { 2494, 0, 34},
+  { 2519, 0, 35},
+  { 2878, 0, 36},
+  { 2902, 1, 37},
+  { 3006, 0, 39},
+  { 3031, 0, 40},
+  { 3158, 0, 41},
+  { 3266, 0, 42},
+  { 3285, 1, 43},
+  { 3390, 0, 45},
+  { 3415, 0, 46},
+  { 3530, 0, 47},
+  { 3535, 0, 48},
+  { 3551, 0, 49},
+  { 4142, 0, 50},
+  { 12441, 1, 51},
+  {0,0,0}
+};
+
+/* string literals */
+const char *_PyUnicode_CategoryNames[] = {
+    "Cn",
+    "Lu",
+    "Ll",
+    "Lt",
+    "Mn",
+    "Mc",
+    "Me",
+    "Nd",
+    "Nl",
+    "No",
+    "Zs",
+    "Zl",
+    "Zp",
+    "Cc",
+    "Cf",
+    "Cs",
+    "Co",
+    "Cn",
+    "Lm",
+    "Lo",
+    "Pc",
+    "Pd",
+    "Ps",
+    "Pe",
+    "Pi",
+    "Pf",
+    "Po",
+    "Sm",
+    "Sc",
+    "Sk",
+    "So",
+    NULL
+};
+const char *_PyUnicode_BidirectionalNames[] = {
+    "",
+    "L",
+    "LRE",
+    "LRO",
+    "R",
+    "AL",
+    "RLE",
+    "RLO",
+    "PDF",
+    "EN",
+    "ES",
+    "ET",
+    "AN",
+    "CS",
+    "NSM",
+    "BN",
+    "B",
+    "S",
+    "WS",
+    "ON",
+    NULL
+};
+const char *_PyUnicode_EastAsianWidthNames[] = {
+    "F",
+    "H",
+    "W",
+    "Na",
+    "A",
+    "N",
+    NULL
+};
+static const char *decomp_prefix[] = {
+    "",
+    "<noBreak>",
+    "<compat>",
+    "<super>",
+    "<fraction>",
+    "<sub>",
+    "<font>",
+    "<circle>",
+    "<wide>",
+    "<vertical>",
+    "<square>",
+    "<isolated>",
+    "<final>",
+    "<initial>",
+    "<medial>",
+    "<small>",
+    "<narrow>",
+    NULL
+};
+/* index tables for the database records */
+#define SHIFT 8
+static unsigned char index1[] = {
+    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 
+    21, 22, 23, 24, 25, 26, 8, 8, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 
+    38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50, 50, 50, 50, 50, 
+    50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 
+    50, 51, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 
+    50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 
+    50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 
+    50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 
+    50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 52, 53, 50, 50, 50, 54, 8, 8, 
+    55, 56, 8, 8, 8, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 
+    50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 
+    50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 57, 58, 58, 58, 58, 58, 58, 
+    58, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 50, 60, 61, 62, 63, 64, 65, 66, 67, 
+    8, 68, 69, 8, 8, 8, 70, 8, 71, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 72, 73, 74, 75, 76, 77, 78, 
+    79, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 50, 50, 50, 50, 50, 
+    50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 
+    50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 
+    50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 
+    50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 
+    50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 
+    50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 
+    50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 
+    50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 
+    50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 80, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 50, 50, 81, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 82, 83, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 84, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 84, 
+};
+
+static unsigned char index2[] = {
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 2, 4, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 3, 3, 3, 2, 5, 6, 6, 7, 8, 7, 6, 6, 9, 10, 6, 11, 12, 13, 12, 
+    12, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 12, 6, 15, 16, 15, 6, 6, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 9, 6, 10, 18, 19, 18, 20, 20, 20, 20, 20, 20, 
+    20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 
+    20, 20, 9, 16, 10, 16, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 21, 22, 8, 8, 23, 8, 24, 
+    25, 26, 27, 28, 29, 16, 30, 25, 18, 31, 32, 33, 33, 26, 34, 25, 22, 26, 
+    33, 28, 35, 36, 36, 36, 22, 37, 37, 37, 37, 37, 37, 38, 37, 37, 37, 37, 
+    37, 37, 37, 37, 37, 38, 37, 37, 37, 37, 37, 37, 39, 38, 37, 37, 37, 37, 
+    37, 38, 28, 28, 28, 34, 34, 34, 34, 28, 34, 28, 28, 28, 34, 28, 28, 34, 
+    34, 28, 34, 28, 28, 34, 34, 34, 39, 28, 28, 28, 34, 28, 34, 28, 34, 37, 
+    28, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 28, 37, 
+    28, 37, 34, 37, 34, 37, 34, 37, 28, 37, 34, 37, 34, 37, 34, 37, 34, 37, 
+    34, 38, 28, 37, 34, 37, 28, 37, 34, 37, 34, 37, 28, 38, 28, 37, 34, 37, 
+    34, 28, 37, 34, 37, 34, 37, 34, 38, 28, 38, 28, 37, 28, 37, 34, 37, 28, 
+    28, 38, 28, 37, 28, 37, 34, 37, 34, 38, 28, 37, 34, 37, 34, 37, 34, 37, 
+    34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 38, 28, 37, 34, 37, 28, 37, 
+    34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 37, 34, 37, 34, 37, 34, 
+    34, 34, 37, 37, 34, 37, 34, 37, 37, 34, 37, 37, 37, 34, 34, 37, 37, 37, 
+    37, 34, 37, 37, 34, 37, 37, 37, 34, 34, 34, 37, 37, 34, 37, 37, 34, 37, 
+    34, 37, 34, 37, 37, 34, 37, 34, 34, 37, 34, 37, 37, 34, 37, 37, 37, 34, 
+    37, 34, 37, 37, 34, 34, 40, 37, 34, 34, 34, 40, 40, 40, 40, 37, 41, 34, 
+    37, 41, 34, 37, 41, 34, 37, 28, 37, 28, 37, 28, 37, 28, 37, 28, 37, 28, 
+    37, 28, 37, 28, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 
+    34, 37, 34, 37, 34, 34, 37, 41, 34, 37, 34, 37, 37, 37, 34, 37, 34, 37, 
+    34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 
+    34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 
+    34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 
+    34, 34, 34, 34, 34, 34, 34, 37, 37, 34, 37, 37, 34, 34, 37, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 28, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 28, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 42, 42, 
+    42, 42, 42, 42, 43, 43, 42, 42, 42, 42, 42, 42, 42, 44, 44, 26, 44, 43, 
+    45, 43, 45, 45, 45, 43, 45, 43, 43, 46, 42, 44, 44, 44, 44, 44, 44, 26, 
+    26, 26, 26, 44, 26, 44, 26, 42, 42, 42, 42, 42, 44, 44, 44, 44, 44, 44, 
+    44, 44, 44, 42, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 
+    44, 44, 44, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 48, 49, 49, 49, 49, 48, 50, 49, 49, 49, 49, 49, 
+    51, 51, 49, 49, 49, 49, 51, 51, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 
+    49, 52, 52, 52, 52, 52, 49, 49, 49, 49, 47, 47, 47, 47, 47, 47, 47, 47, 
+    53, 47, 49, 49, 49, 47, 47, 47, 49, 49, 54, 47, 47, 47, 49, 49, 49, 49, 
+    47, 48, 49, 49, 47, 55, 56, 56, 55, 56, 56, 55, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 44, 44, 0, 0, 0, 0, 42, 0, 0, 0, 
+    57, 0, 0, 0, 0, 0, 44, 44, 37, 57, 37, 37, 37, 0, 37, 0, 37, 37, 34, 38, 
+    38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 0, 38, 
+    38, 38, 38, 38, 38, 38, 37, 37, 34, 34, 34, 34, 34, 28, 28, 28, 28, 28, 
+    28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 34, 28, 28, 28, 28, 28, 
+    28, 28, 34, 34, 34, 34, 34, 0, 34, 34, 37, 37, 37, 34, 34, 34, 37, 34, 
+    37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 
+    37, 34, 37, 34, 34, 34, 34, 34, 37, 34, 58, 37, 34, 37, 37, 34, 34, 37, 
+    37, 37, 37, 38, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 
+    38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 
+    38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 28, 28, 28, 28, 
+    28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 
+    28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 34, 28, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 
+    37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 
+    37, 34, 37, 34, 37, 34, 59, 60, 60, 60, 60, 0, 61, 61, 37, 34, 37, 34, 
+    37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 
+    37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 
+    37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 37, 34, 37, 
+    34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 0, 37, 34, 37, 34, 37, 34, 
+    37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 
+    37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 
+    0, 0, 0, 0, 0, 0, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 
+    37, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 
+    37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 
+    37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 0, 0, 42, 62, 62, 62, 62, 62, 62, 
+    0, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 0, 62, 63, 0, 0, 0, 0, 0, 0, 64, 60, 60, 60, 60, 64, 60, 
+    60, 60, 65, 64, 60, 60, 60, 60, 60, 60, 64, 64, 64, 64, 64, 64, 60, 60, 
+    64, 60, 60, 65, 66, 60, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 0, 77, 
+    78, 79, 80, 81, 80, 82, 83, 80, 60, 64, 80, 75, 0, 0, 0, 0, 0, 0, 0, 0, 
+    84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 
+    84, 84, 84, 84, 84, 84, 84, 84, 84, 0, 0, 0, 0, 0, 84, 84, 84, 80, 80, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 85, 85, 85, 0, 0, 0, 0, 0, 0, 0, 86, 
+    87, 88, 27, 27, 60, 60, 60, 60, 60, 60, 0, 0, 0, 0, 0, 88, 0, 0, 88, 88, 
+    0, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 89, 89, 89, 89, 0, 0, 0, 0, 0, 90, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 89, 91, 92, 93, 94, 95, 96, 97, 98, 60, 60, 64, 64, 
+    60, 60, 60, 60, 60, 64, 60, 60, 0, 99, 99, 99, 99, 99, 99, 99, 99, 99, 
+    99, 100, 101, 101, 88, 89, 89, 102, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    88, 89, 60, 60, 60, 60, 60, 60, 60, 85, 61, 60, 60, 60, 60, 64, 60, 90, 
+    90, 60, 60, 27, 64, 60, 60, 64, 89, 89, 103, 103, 103, 103, 103, 103, 
+    103, 103, 103, 103, 89, 89, 89, 104, 104, 89, 88, 88, 88, 88, 88, 88, 88, 
+    88, 88, 88, 88, 88, 88, 88, 0, 105, 89, 106, 89, 89, 89, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 60, 64, 60, 60, 64, 60, 60, 64, 64, 64, 60, 64, 64, 
+    60, 64, 60, 60, 60, 64, 60, 64, 60, 64, 60, 64, 60, 60, 0, 0, 89, 89, 89, 
+    89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 89, 89, 89, 89, 107, 107, 107, 107, 107, 107, 107, 
+    107, 107, 107, 107, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 107, 107, 108, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 109, 40, 108, 108, 108, 107, 
+    107, 107, 107, 107, 107, 107, 107, 108, 108, 108, 108, 110, 0, 0, 40, 60, 
+    64, 60, 60, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 107, 107, 
+    62, 62, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 62, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 107, 108, 108, 0, 40, 40, 40, 40, 
+    40, 40, 40, 40, 0, 0, 40, 40, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 
+    40, 40, 40, 0, 40, 0, 0, 0, 40, 40, 40, 40, 0, 0, 109, 40, 108, 108, 108, 
+    107, 107, 107, 107, 0, 0, 108, 108, 0, 0, 108, 108, 110, 40, 0, 0, 0, 0, 
+    0, 0, 0, 0, 108, 0, 0, 0, 0, 40, 40, 0, 40, 40, 40, 107, 107, 0, 0, 111, 
+    111, 111, 111, 111, 111, 111, 111, 111, 111, 40, 40, 112, 112, 113, 113, 
+    113, 113, 113, 113, 59, 0, 0, 0, 0, 0, 0, 107, 107, 108, 0, 40, 40, 40, 
+    40, 40, 40, 0, 0, 0, 0, 40, 40, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 
+    40, 40, 40, 0, 40, 40, 0, 40, 40, 0, 40, 40, 0, 0, 109, 0, 108, 108, 108, 
+    107, 107, 0, 0, 0, 0, 107, 107, 0, 0, 107, 107, 110, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 40, 40, 40, 40, 0, 40, 0, 0, 0, 0, 0, 0, 0, 111, 111, 111, 
+    111, 111, 111, 111, 111, 111, 111, 107, 107, 40, 40, 40, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 107, 107, 108, 0, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 0, 40, 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 0, 40, 
+    40, 0, 40, 40, 40, 40, 40, 0, 0, 109, 40, 108, 108, 108, 107, 107, 107, 
+    107, 107, 0, 107, 107, 108, 0, 108, 108, 110, 0, 0, 40, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 107, 107, 0, 0, 111, 111, 111, 111, 
+    111, 111, 111, 111, 111, 111, 0, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 107, 108, 108, 0, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 40, 40, 
+    0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 0, 40, 40, 
+    40, 40, 40, 0, 0, 109, 40, 108, 107, 108, 107, 107, 107, 0, 0, 0, 108, 
+    108, 0, 0, 108, 108, 110, 0, 0, 0, 0, 0, 0, 0, 0, 107, 108, 0, 0, 0, 0, 
+    40, 40, 0, 40, 40, 40, 0, 0, 0, 0, 111, 111, 111, 111, 111, 111, 111, 
+    111, 111, 111, 59, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    107, 40, 0, 40, 40, 40, 40, 40, 40, 0, 0, 0, 40, 40, 40, 0, 40, 40, 40, 
+    40, 0, 0, 0, 40, 40, 0, 40, 0, 40, 40, 0, 0, 0, 40, 40, 0, 0, 0, 40, 40, 
+    40, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 
+    108, 108, 107, 108, 108, 0, 0, 0, 108, 108, 108, 0, 108, 108, 108, 110, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 113, 113, 113, 27, 27, 
+    27, 27, 27, 27, 112, 27, 0, 0, 0, 0, 0, 0, 108, 108, 108, 0, 40, 40, 40, 
+    40, 40, 40, 40, 40, 0, 40, 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 40, 0, 0, 0, 0, 107, 107, 
+    107, 108, 108, 108, 108, 0, 107, 107, 107, 0, 107, 107, 107, 110, 0, 0, 
+    0, 0, 0, 0, 0, 114, 115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 0, 0, 0, 0, 
+    111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 108, 0, 40, 40, 40, 40, 40, 40, 40, 
+    40, 0, 40, 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 0, 40, 40, 40, 40, 40, 0, 0, 109, 40, 108, 116, 108, 108, 
+    108, 108, 108, 0, 116, 108, 108, 0, 108, 108, 107, 110, 0, 0, 0, 0, 0, 0, 
+    0, 108, 108, 0, 0, 0, 0, 0, 0, 0, 40, 0, 40, 40, 0, 0, 0, 0, 111, 111, 
+    111, 111, 111, 111, 111, 111, 111, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 108, 108, 0, 40, 40, 40, 40, 40, 40, 40, 40, 0, 40, 
+    40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 108, 108, 108, 107, 107, 107, 0, 
+    0, 108, 108, 108, 0, 108, 108, 108, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 
+    0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 0, 0, 0, 0, 111, 111, 111, 111, 111, 111, 
+    111, 111, 111, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    108, 108, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 0, 40, 0, 0, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 110, 0, 0, 
+    0, 0, 108, 108, 108, 107, 107, 107, 0, 107, 0, 108, 108, 108, 108, 108, 
+    108, 108, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 
+    108, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 107, 40, 40, 107, 107, 107, 107, 117, 117, 110, 0, 0, 
+    0, 0, 112, 40, 40, 40, 40, 40, 40, 42, 107, 118, 118, 118, 118, 107, 107, 
+    107, 62, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 62, 62, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 0, 40, 0, 0, 40, 40, 0, 40, 0, 
+    0, 40, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 
+    0, 40, 40, 40, 0, 40, 0, 40, 0, 0, 40, 40, 0, 40, 40, 40, 40, 107, 40, 
+    40, 107, 107, 107, 107, 119, 119, 0, 107, 107, 40, 0, 0, 40, 40, 40, 40, 
+    40, 0, 42, 0, 120, 120, 120, 120, 107, 107, 0, 0, 111, 111, 111, 111, 
+    111, 111, 111, 111, 111, 111, 0, 0, 40, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    40, 59, 59, 59, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 
+    62, 59, 59, 59, 59, 59, 64, 64, 59, 59, 59, 59, 59, 59, 111, 111, 111, 
+    111, 111, 111, 111, 111, 111, 111, 113, 113, 113, 113, 113, 113, 113, 
+    113, 113, 113, 59, 64, 59, 64, 59, 121, 122, 123, 122, 123, 108, 108, 40, 
+    40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 0, 0, 124, 125, 107, 126, 107, 107, 
+    107, 107, 107, 125, 125, 125, 125, 107, 108, 125, 107, 60, 60, 110, 62, 
+    60, 60, 40, 40, 40, 40, 0, 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, 
+    107, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 
+    107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 
+    107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 59, 59, 59, 59, 59, 59, 
+    59, 59, 64, 59, 59, 59, 59, 59, 59, 0, 0, 59, 62, 62, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 40, 0, 40, 40, 
+    0, 108, 107, 107, 107, 107, 108, 107, 0, 0, 0, 107, 109, 108, 110, 0, 0, 
+    0, 0, 0, 0, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 62, 62, 62, 
+    62, 62, 62, 40, 40, 40, 40, 40, 40, 108, 108, 107, 107, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 37, 37, 37, 37, 37, 
+    37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 
+    37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 62, 42, 0, 0, 0, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 0, 0, 0, 0, 0, 127, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 0, 0, 40, 40, 40, 40, 40, 40, 40, 
+    0, 40, 0, 40, 40, 40, 40, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 0, 
+    0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 40, 
+    40, 40, 40, 0, 0, 40, 40, 40, 40, 40, 40, 40, 0, 40, 0, 40, 40, 40, 40, 
+    0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 0, 40, 40, 40, 40, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 0, 0, 0, 0, 60, 59, 62, 62, 62, 62, 62, 62, 62, 62, 113, 113, 
+    113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 
+    113, 113, 113, 113, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 
+    0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 62, 62, 40, 40, 40, 40, 
+    40, 40, 40, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 122, 123, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 62, 62, 62, 129, 129, 129, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 107, 107, 110, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 107, 107, 110, 62, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 107, 107, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 0, 40, 40, 40, 0, 107, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 130, 
+    130, 108, 107, 107, 107, 107, 107, 107, 107, 108, 108, 108, 108, 108, 
+    108, 108, 108, 107, 108, 108, 107, 107, 107, 107, 107, 107, 107, 107, 
+    107, 110, 107, 62, 62, 62, 42, 62, 62, 62, 112, 40, 60, 0, 0, 111, 111, 
+    111, 111, 111, 111, 111, 111, 111, 111, 0, 0, 0, 0, 0, 0, 131, 131, 131, 
+    131, 131, 131, 131, 131, 131, 131, 0, 0, 0, 0, 0, 0, 57, 57, 57, 57, 57, 
+    57, 63, 57, 57, 57, 57, 107, 107, 107, 128, 0, 111, 111, 111, 111, 111, 
+    111, 111, 111, 111, 111, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 42, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 0, 0, 0, 107, 107, 107, 108, 108, 108, 108, 107, 
+    107, 132, 132, 132, 0, 0, 0, 0, 108, 108, 107, 108, 108, 108, 108, 108, 
+    108, 65, 60, 64, 0, 0, 0, 0, 27, 0, 0, 0, 57, 57, 111, 111, 111, 111, 
+    111, 111, 111, 111, 111, 111, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 0, 0, 40, 40, 40, 40, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 0, 0, 0, 0, 0, 0, 108, 108, 108, 108, 108, 108, 108, 108, 
+    108, 108, 108, 108, 108, 108, 108, 108, 108, 40, 40, 40, 40, 40, 40, 40, 
+    108, 108, 0, 0, 0, 0, 0, 0, 111, 111, 111, 111, 111, 111, 111, 111, 111, 
+    111, 0, 0, 0, 0, 57, 57, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 
+    27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 
+    27, 27, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 60, 64, 108, 108, 108, 0, 0, 62, 62, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 42, 42, 42, 
+    42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 
+    42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 
+    42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 42, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 
+    42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 
+    42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 60, 60, 
+    64, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 34, 37, 34, 37, 34, 37, 34, 
+    37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 
+    37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 
+    37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 
+    37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 
+    37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 
+    37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 
+    37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 
+    37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 34, 34, 
+    34, 34, 34, 34, 0, 0, 0, 0, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 
+    34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 
+    34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 
+    34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 
+    34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 
+    34, 37, 34, 37, 34, 37, 34, 0, 0, 0, 0, 0, 0, 34, 34, 34, 34, 34, 34, 34, 
+    34, 37, 37, 37, 37, 37, 37, 37, 37, 34, 34, 34, 34, 34, 34, 0, 0, 37, 37, 
+    37, 37, 37, 37, 0, 0, 34, 34, 34, 34, 34, 34, 34, 34, 37, 37, 37, 37, 37, 
+    37, 37, 37, 34, 34, 34, 34, 34, 34, 34, 34, 37, 37, 37, 37, 37, 37, 37, 
+    37, 34, 34, 34, 34, 34, 34, 0, 0, 37, 37, 37, 37, 37, 37, 0, 0, 34, 34, 
+    34, 34, 34, 34, 34, 34, 0, 37, 0, 37, 0, 37, 0, 37, 34, 34, 34, 34, 34, 
+    34, 34, 34, 37, 37, 37, 37, 37, 37, 37, 37, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 0, 0, 34, 34, 34, 34, 34, 34, 34, 34, 41, 41, 
+    41, 41, 41, 41, 41, 41, 34, 34, 34, 34, 34, 34, 34, 34, 41, 41, 41, 41, 
+    41, 41, 41, 41, 34, 34, 34, 34, 34, 34, 34, 34, 41, 41, 41, 41, 41, 41, 
+    41, 41, 34, 34, 34, 34, 34, 0, 34, 34, 37, 37, 37, 37, 41, 44, 34, 44, 
+    44, 44, 34, 34, 34, 0, 34, 34, 37, 37, 37, 37, 41, 44, 44, 44, 34, 34, 
+    34, 34, 0, 0, 34, 34, 37, 37, 37, 37, 0, 44, 44, 44, 34, 34, 34, 34, 34, 
+    34, 34, 34, 37, 37, 37, 37, 37, 44, 44, 44, 0, 0, 34, 34, 34, 0, 34, 34, 
+    37, 37, 37, 37, 41, 44, 44, 0, 128, 128, 128, 128, 128, 128, 128, 128, 
+    128, 128, 128, 105, 105, 105, 130, 133, 134, 63, 63, 134, 134, 134, 22, 
+    57, 135, 136, 122, 137, 135, 136, 122, 137, 22, 22, 22, 57, 22, 22, 22, 
+    22, 138, 139, 140, 141, 142, 143, 144, 21, 145, 100, 145, 145, 100, 22, 
+    57, 57, 57, 29, 35, 22, 57, 57, 22, 146, 146, 57, 57, 57, 147, 148, 149, 
+    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 58, 57, 146, 57, 57, 57, 57, 
+    57, 57, 57, 57, 57, 57, 128, 105, 105, 105, 105, 0, 0, 0, 0, 0, 0, 105, 
+    105, 105, 105, 105, 105, 150, 34, 0, 0, 33, 150, 150, 150, 150, 150, 151, 
+    151, 58, 148, 149, 28, 150, 33, 33, 33, 33, 150, 150, 150, 150, 150, 151, 
+    151, 58, 148, 149, 0, 42, 42, 42, 42, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 112, 112, 112, 112, 112, 112, 112, 112, 112, 152, 112, 112, 23, 112, 
+    112, 112, 112, 112, 112, 112, 112, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 60, 153, 153, 60, 60, 
+    60, 60, 153, 153, 153, 60, 60, 61, 61, 61, 61, 60, 61, 61, 61, 153, 153, 
+    60, 64, 60, 153, 153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 27, 27, 37, 25, 27, 25, 27, 37, 27, 25, 34, 37, 37, 37, 34, 34, 
+    37, 37, 37, 28, 27, 37, 25, 27, 27, 37, 37, 37, 37, 37, 27, 27, 27, 25, 
+    25, 27, 37, 27, 38, 27, 37, 27, 37, 38, 37, 37, 154, 34, 37, 37, 27, 37, 
+    34, 40, 40, 40, 40, 34, 27, 27, 34, 34, 37, 37, 155, 58, 58, 58, 58, 37, 
+    34, 34, 34, 34, 27, 58, 27, 0, 0, 0, 0, 0, 0, 36, 36, 131, 131, 131, 131, 
+    131, 131, 36, 36, 36, 36, 131, 156, 156, 156, 156, 156, 156, 156, 156, 
+    156, 156, 156, 156, 129, 129, 129, 129, 156, 156, 156, 156, 156, 156, 
+    156, 156, 156, 156, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 39, 39, 39, 39, 25, 25, 25, 25, 25, 
+    58, 58, 27, 27, 27, 27, 58, 27, 27, 58, 27, 27, 58, 27, 27, 27, 27, 27, 
+    27, 27, 58, 27, 27, 27, 27, 27, 27, 27, 27, 27, 25, 25, 27, 27, 27, 27, 
+    27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 58, 58, 
+    27, 27, 39, 27, 39, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 
+    27, 27, 27, 27, 27, 25, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 
+    58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 39, 155, 157, 157, 155, 
+    58, 58, 39, 157, 155, 155, 157, 155, 155, 58, 39, 58, 157, 151, 158, 58, 
+    157, 155, 58, 58, 58, 157, 155, 155, 157, 39, 157, 157, 155, 155, 39, 
+    155, 39, 155, 39, 39, 39, 39, 157, 157, 155, 157, 155, 155, 155, 155, 
+    155, 39, 39, 39, 39, 58, 155, 58, 155, 157, 157, 155, 155, 155, 155, 155, 
+    155, 155, 155, 155, 155, 157, 155, 155, 155, 157, 58, 58, 58, 58, 58, 
+    157, 155, 155, 155, 58, 58, 58, 58, 58, 58, 58, 58, 58, 155, 157, 39, 
+    155, 58, 157, 157, 157, 157, 155, 155, 157, 157, 58, 58, 157, 157, 155, 
+    155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 
+    155, 155, 155, 157, 157, 155, 155, 157, 157, 155, 155, 155, 155, 155, 58, 
+    58, 155, 155, 155, 155, 58, 58, 39, 58, 58, 155, 39, 58, 58, 58, 58, 58, 
+    58, 58, 58, 155, 155, 58, 39, 155, 155, 155, 155, 155, 155, 155, 155, 
+    155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 58, 58, 58, 58, 
+    58, 155, 157, 58, 58, 58, 58, 58, 58, 58, 58, 58, 155, 155, 155, 155, 
+    155, 58, 58, 155, 155, 58, 58, 58, 58, 155, 155, 155, 155, 155, 155, 155, 
+    155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 
+    155, 155, 155, 58, 58, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 
+    155, 155, 155, 155, 155, 155, 27, 27, 27, 27, 27, 27, 27, 27, 155, 155, 
+    155, 155, 27, 27, 27, 27, 27, 27, 25, 27, 27, 27, 27, 27, 27, 27, 27, 27, 
+    27, 27, 27, 27, 155, 155, 27, 27, 27, 27, 27, 27, 27, 159, 160, 27, 27, 
+    27, 27, 27, 27, 27, 27, 27, 27, 27, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 27, 58, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 
+    27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 59, 27, 27, 27, 
+    27, 27, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 
+    58, 58, 58, 58, 58, 58, 58, 58, 58, 122, 123, 57, 27, 27, 27, 27, 27, 27, 
+    27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 
+    27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 
+    27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 
+    27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 36, 
+    36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 
+    36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 
+    36, 36, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 
+    33, 33, 33, 33, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 
+    161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 
+    161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 
+    161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 
+    161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 
+    161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 131, 36, 36, 36, 
+    36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 
+    25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 
+    25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 
+    25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 
+    25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 
+    25, 25, 25, 25, 27, 27, 27, 27, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 
+    25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 
+    25, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 
+    27, 27, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 
+    27, 27, 25, 25, 25, 25, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 25, 25, 
+    27, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 27, 27, 27, 27, 25, 25, 
+    27, 27, 25, 39, 27, 27, 27, 27, 25, 25, 27, 27, 25, 39, 27, 27, 27, 27, 
+    25, 25, 25, 27, 27, 25, 27, 27, 25, 25, 25, 25, 27, 27, 27, 27, 27, 27, 
+    27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 25, 25, 25, 25, 27, 27, 27, 27, 
+    27, 27, 27, 27, 27, 25, 27, 27, 27, 27, 27, 27, 27, 27, 58, 58, 58, 58, 
+    58, 58, 58, 58, 27, 27, 27, 27, 27, 25, 25, 27, 27, 25, 27, 27, 27, 27, 
+    25, 25, 27, 27, 27, 27, 25, 25, 27, 27, 27, 27, 27, 27, 25, 27, 25, 27, 
+    27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 
+    27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 25, 27, 25, 27, 
+    27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 
+    27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 25, 25, 27, 25, 25, 25, 27, 25, 
+    25, 25, 25, 27, 25, 25, 27, 39, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 
+    27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 
+    27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 
+    0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 59, 27, 27, 27, 27, 
+    27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 27, 27, 27, 27, 0, 27, 27, 27, 27, 0, 0, 27, 27, 
+    27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 
+    27, 27, 27, 27, 27, 27, 27, 27, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 
+    27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 25, 27, 27, 27, 27, 27, 27, 
+    27, 27, 27, 27, 27, 27, 27, 27, 0, 27, 0, 27, 27, 27, 27, 0, 0, 0, 27, 0, 
+    27, 27, 27, 27, 27, 27, 27, 0, 0, 27, 27, 27, 27, 27, 27, 27, 148, 149, 
+    148, 149, 148, 149, 148, 149, 148, 149, 148, 149, 148, 149, 36, 36, 36, 
+    36, 36, 36, 36, 36, 36, 36, 131, 131, 131, 131, 131, 131, 131, 131, 131, 
+    131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 27, 0, 0, 0, 27, 
+    27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 
+    27, 27, 27, 27, 27, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 
+    27, 27, 0, 155, 58, 58, 155, 155, 148, 149, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    58, 58, 58, 155, 155, 155, 155, 58, 58, 58, 58, 58, 155, 155, 155, 58, 
+    58, 58, 155, 155, 155, 155, 9, 10, 9, 10, 9, 10, 0, 0, 0, 0, 58, 58, 58, 
+    58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 58, 
+    58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 
+    58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 
+    58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 
+    58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 
+    58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 
+    58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 
+    58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 
+    58, 58, 58, 58, 148, 149, 9, 10, 148, 149, 148, 149, 148, 149, 148, 149, 
+    148, 149, 148, 149, 148, 149, 148, 149, 148, 149, 58, 58, 155, 155, 155, 
+    155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 
+    155, 155, 155, 155, 58, 58, 58, 58, 58, 58, 58, 58, 155, 58, 58, 58, 58, 
+    58, 58, 58, 155, 155, 155, 155, 155, 155, 58, 58, 58, 155, 58, 58, 58, 
+    58, 155, 155, 155, 155, 155, 58, 155, 155, 58, 58, 148, 149, 148, 149, 
+    155, 58, 58, 58, 58, 155, 58, 155, 155, 155, 58, 58, 155, 155, 58, 58, 
+    58, 58, 58, 58, 58, 58, 58, 58, 155, 155, 155, 155, 155, 155, 58, 58, 
+    148, 149, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 155, 155, 155, 
+    155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 
+    155, 155, 58, 155, 155, 155, 155, 58, 58, 155, 58, 155, 58, 58, 155, 58, 
+    155, 155, 155, 155, 58, 58, 58, 58, 58, 155, 155, 58, 58, 58, 58, 58, 58, 
+    155, 155, 155, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 
+    58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 155, 155, 58, 58, 58, 58, 58, 58, 
+    58, 58, 58, 58, 58, 155, 155, 58, 58, 58, 58, 155, 155, 155, 155, 58, 
+    155, 155, 58, 58, 155, 155, 58, 58, 58, 58, 155, 155, 155, 155, 155, 155, 
+    155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 
+    155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 
+    155, 155, 155, 155, 155, 155, 155, 155, 155, 58, 58, 155, 155, 155, 155, 
+    155, 155, 155, 155, 58, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 
+    155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 
+    155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 
+    155, 155, 58, 58, 58, 58, 58, 155, 58, 155, 58, 58, 58, 155, 155, 155, 
+    155, 155, 58, 58, 58, 58, 58, 155, 155, 155, 58, 58, 58, 58, 155, 58, 58, 
+    58, 155, 155, 155, 155, 155, 58, 155, 58, 58, 27, 27, 27, 27, 27, 27, 27, 
+    27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 37, 37, 37, 37, 37, 37, 37, 
+    37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 
+    37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 
+    37, 37, 37, 0, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 
+    37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 
+    37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 
+    37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 
+    37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 
+    37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 34, 27, 27, 27, 
+    27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, 57, 57, 57, 
+    131, 57, 57, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 
+    40, 40, 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 40, 40, 
+    40, 0, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 0, 40, 
+    40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 57, 57, 29, 35, 29, 35, 57, 57, 57, 29, 35, 57, 29, 35, 57, 57, 
+    57, 57, 57, 57, 57, 57, 57, 63, 0, 0, 0, 0, 29, 35, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 162, 162, 162, 
+    162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 
+    162, 162, 162, 162, 162, 162, 162, 162, 162, 0, 162, 162, 162, 162, 162, 
+    162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 
+    162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 
+    162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 
+    162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 
+    162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 
+    162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 162, 162, 162, 162, 162, 162, 162, 162, 
+    162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 
+    162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 
+    162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 
+    162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 
+    162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 
+    162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 
+    162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 
+    162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 
+    162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 
+    162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 
+    162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 
+    162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 
+    162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 
+    162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 
+    162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 162, 162, 162, 162, 
+    162, 162, 162, 162, 162, 162, 162, 162, 0, 0, 0, 0, 163, 164, 164, 164, 
+    162, 165, 127, 166, 159, 160, 159, 160, 159, 160, 159, 160, 159, 160, 
+    162, 162, 159, 160, 159, 160, 159, 160, 159, 160, 167, 168, 169, 169, 
+    162, 166, 166, 166, 166, 166, 166, 166, 166, 166, 170, 171, 172, 173, 
+    174, 174, 167, 165, 165, 165, 165, 165, 162, 162, 166, 166, 166, 165, 
+    127, 164, 162, 27, 0, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 0, 0, 175, 175, 176, 176, 165, 165, 127, 
+    167, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 164, 165, 165, 165, 127, 0, 0, 0, 0, 
+    0, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 0, 0, 0, 0, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 0, 177, 177, 178, 178, 
+    178, 178, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 0, 0, 0, 0, 0, 0, 0, 0, 162, 162, 
+    162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 177, 177, 177, 177, 177, 177, 177, 177, 
+    177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 
+    177, 177, 177, 177, 177, 177, 177, 162, 162, 0, 178, 178, 178, 178, 178, 
+    178, 178, 178, 178, 178, 177, 177, 177, 177, 177, 177, 177, 177, 177, 
+    177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 
+    177, 177, 177, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 162, 179, 179, 179, 
+    179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 177, 177, 
+    177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 
+    177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 162, 162, 
+    162, 177, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 177, 177, 
+    177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 
+    177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 
+    177, 177, 177, 177, 177, 177, 177, 177, 177, 179, 179, 179, 179, 179, 
+    179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 177, 177, 177, 177, 
+    177, 177, 177, 177, 177, 177, 177, 177, 162, 162, 162, 162, 177, 177, 
+    177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 
+    177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 
+    177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 
+    177, 177, 177, 0, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 
+    177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 
+    177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 
+    177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 
+    177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 
+    177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 
+    177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 
+    177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 
+    177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 162, 162, 162, 162, 
+    177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 
+    177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 
+    177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 
+    177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 
+    177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 
+    177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 
+    177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 
+    177, 162, 162, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 
+    177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 
+    177, 177, 177, 177, 177, 177, 162, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 
+    27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 
+    27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 
+    27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 165, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 0, 0, 0, 162, 162, 162, 162, 162, 162, 162, 162, 162, 
+    162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 
+    162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 
+    162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 
+    162, 162, 162, 162, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 44, 44, 44, 44, 44, 44, 
+    44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 132, 40, 40, 40, 110, 
+    40, 40, 40, 40, 107, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 108, 108, 107, 107, 108, 27, 27, 
+    27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, 180, 180, 180, 180, 180, 180, 180, 
+    180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 
+    180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 
+    180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 
+    180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 
+    180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 
+    180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 
+    180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 
+    180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 
+    180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 
+    180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 
+    180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 
+    180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 
+    180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 
+    180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 
+    180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 
+    180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 
+    180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 
+    180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 181, 181, 181, 181, 
+    181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 
+    181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 
+    181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 
+    181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 
+    181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 
+    181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 
+    181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 
+    181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 
+    181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 
+    181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 
+    181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 
+    181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 
+    181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 
+    181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 
+    181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 
+    181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 
+    181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 
+    181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 0, 0, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 0, 0, 0, 0, 0, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 34, 
+    34, 34, 34, 34, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 34, 34, 34, 
+    34, 0, 0, 0, 0, 0, 84, 182, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 151, 
+    84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 0, 84, 84, 84, 84, 
+    84, 0, 84, 0, 84, 84, 0, 84, 84, 0, 84, 84, 84, 84, 84, 84, 84, 84, 84, 
+    84, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 89, 89, 89, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 89, 89, 
+    89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    89, 122, 123, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 89, 89, 89, 
+    89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 89, 89, 0, 0, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 89, 89, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 86, 27, 0, 0, 54, 
+    54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 164, 164, 
+    164, 164, 164, 164, 164, 168, 169, 164, 0, 0, 0, 0, 0, 0, 60, 60, 60, 60, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 164, 167, 167, 183, 183, 168, 169, 
+    168, 169, 168, 169, 168, 169, 168, 169, 168, 169, 168, 169, 168, 169, 
+    164, 164, 168, 169, 164, 164, 164, 164, 183, 183, 183, 184, 164, 184, 0, 
+    164, 184, 164, 164, 167, 168, 169, 168, 169, 168, 169, 185, 164, 164, 
+    186, 187, 188, 188, 188, 0, 164, 189, 185, 164, 0, 0, 0, 0, 89, 89, 89, 
+    89, 89, 0, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 0, 0, 105, 0, 190, 190, 
+    191, 192, 191, 190, 190, 193, 194, 190, 195, 196, 197, 196, 196, 198, 
+    198, 198, 198, 198, 198, 198, 198, 198, 198, 196, 190, 199, 200, 199, 
+    190, 190, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 
+    201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 
+    193, 190, 194, 202, 203, 202, 204, 204, 204, 204, 204, 204, 204, 204, 
+    204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 
+    204, 204, 204, 204, 193, 200, 194, 200, 193, 194, 205, 206, 207, 205, 
+    205, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 209, 208, 208, 
+    208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 
+    208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 
+    208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 
+    208, 209, 209, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 
+    208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 
+    208, 208, 208, 208, 208, 208, 0, 0, 0, 208, 208, 208, 208, 208, 208, 0, 
+    0, 208, 208, 208, 208, 208, 208, 0, 0, 208, 208, 208, 208, 208, 208, 0, 
+    0, 208, 208, 208, 0, 0, 0, 192, 192, 200, 202, 210, 192, 192, 0, 211, 
+    212, 212, 212, 212, 211, 211, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 213, 213, 
+    213, 27, 25, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 0, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 0, 62, 57, 59, 0, 0, 
+    0, 0, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 
+    113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 
+    113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 
+    113, 113, 113, 113, 0, 0, 0, 59, 59, 59, 59, 59, 59, 59, 59, 59, 214, 
+    214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 
+    214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 
+    214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 
+    214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 131, 131, 131, 131, 27, 
+    27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 131, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 113, 113, 113, 113, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 129, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 62, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 
+    40, 40, 40, 40, 40, 40, 40, 40, 59, 214, 214, 214, 214, 214, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 37, 37, 37, 37, 37, 37, 37, 
+    37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 
+    37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 0, 0, 111, 111, 111, 111, 111, 111, 111, 111, 
+    111, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 84, 84, 84, 84, 
+    84, 0, 0, 84, 0, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 
+    84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 
+    84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 0, 84, 84, 0, 0, 0, 84, 
+    0, 0, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 84, 107, 107, 107, 0, 107, 107, 0, 0, 0, 0, 0, 107, 64, 107, 60, 
+    84, 84, 84, 84, 0, 84, 84, 84, 0, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 
+    84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 0, 0, 
+    0, 0, 60, 153, 64, 0, 0, 0, 0, 110, 215, 215, 215, 215, 215, 215, 215, 
+    215, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 80, 80, 80, 80, 80, 80, 80, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 0, 0, 0, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 216, 216, 153, 153, 153, 59, 59, 59, 217, 
+    216, 216, 216, 216, 216, 105, 105, 105, 105, 105, 105, 105, 105, 64, 64, 
+    64, 64, 64, 64, 64, 64, 59, 59, 60, 60, 60, 60, 60, 64, 64, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 60, 60, 60, 60, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
+    59, 59, 59, 59, 59, 59, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 27, 27, 27, 
+    27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 
+    27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 
+    27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 
+    27, 27, 27, 27, 27, 27, 27, 27, 60, 60, 60, 27, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 
+    27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 
+    27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 
+    27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 
+    27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 
+    27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 
+    37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 
+    37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 34, 34, 34, 34, 34, 34, 34, 0, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 
+    37, 37, 37, 37, 37, 37, 37, 37, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 37, 0, 
+    37, 37, 0, 0, 37, 0, 0, 37, 37, 0, 0, 37, 37, 37, 37, 0, 37, 37, 37, 37, 
+    37, 37, 37, 37, 34, 34, 34, 34, 0, 34, 0, 34, 34, 34, 34, 34, 34, 34, 0, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 37, 37, 37, 37, 37, 37, 37, 
+    37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 
+    37, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 37, 37, 0, 37, 37, 37, 37, 0, 0, 37, 
+    37, 37, 37, 37, 37, 37, 37, 0, 37, 37, 37, 37, 37, 37, 37, 0, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 37, 37, 0, 37, 37, 37, 37, 0, 37, 37, 37, 37, 37, 0, 
+    37, 0, 0, 0, 37, 37, 37, 37, 37, 37, 37, 0, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 
+    37, 37, 37, 37, 37, 37, 37, 37, 37, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 37, 
+    37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 
+    37, 37, 37, 37, 37, 37, 37, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 37, 37, 37, 
+    37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 
+    37, 37, 37, 37, 37, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 37, 37, 37, 37, 37, 
+    37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 
+    37, 37, 37, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 37, 37, 37, 37, 37, 37, 37, 
+    37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 
+    37, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 37, 37, 37, 37, 37, 37, 37, 37, 37, 
+    37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 0, 0, 37, 37, 37, 37, 37, 37, 37, 37, 
+    37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 218, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 218, 34, 34, 34, 34, 34, 34, 37, 37, 37, 37, 
+    37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 
+    37, 37, 37, 218, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 218, 34, 34, 34, 34, 34, 34, 
+    37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 
+    37, 37, 37, 37, 37, 37, 37, 218, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 218, 34, 34, 
+    34, 34, 34, 34, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 
+    37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 218, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 218, 34, 34, 34, 34, 34, 34, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 
+    37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 218, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 218, 34, 34, 34, 34, 34, 34, 0, 0, 0, 0, 103, 103, 
+    103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 
+    103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 
+    103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 
+    103, 103, 103, 103, 103, 103, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 
+    105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 
+    105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 
+    105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 
+    105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 
+    105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 
+    105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 
+    105, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 
+    54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 
+    54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 
+    54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 
+    54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 
+    54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 
+    54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 
+    54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 
+    54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 
+    54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 
+    54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 
+    54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 
+    54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 
+    54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 181, 181, 181, 181, 181, 181, 181, 181, 
+    181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 
+    181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 
+    181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 
+    181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 
+    181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 
+    181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 
+    181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 
+    181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 
+    181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 
+    181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 
+    181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 
+    181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 
+    181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 
+    181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 
+    181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 
+    181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 
+    181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 
+    181, 181, 181, 181, 181, 181, 181, 181, 0, 0, 
+};
+
+/* decomposition data */
+static unsigned int decomp_data[] = {
+    0, 257, 32, 514, 32, 776, 259, 97, 514, 32, 772, 259, 50, 259, 51, 514, 
+    32, 769, 258, 956, 514, 32, 807, 259, 49, 259, 111, 772, 49, 8260, 52, 
+    772, 49, 8260, 50, 772, 51, 8260, 52, 512, 65, 768, 512, 65, 769, 512, 
+    65, 770, 512, 65, 771, 512, 65, 776, 512, 65, 778, 512, 67, 807, 512, 69, 
+    768, 512, 69, 769, 512, 69, 770, 512, 69, 776, 512, 73, 768, 512, 73, 
+    769, 512, 73, 770, 512, 73, 776, 512, 78, 771, 512, 79, 768, 512, 79, 
+    769, 512, 79, 770, 512, 79, 771, 512, 79, 776, 512, 85, 768, 512, 85, 
+    769, 512, 85, 770, 512, 85, 776, 512, 89, 769, 512, 97, 768, 512, 97, 
+    769, 512, 97, 770, 512, 97, 771, 512, 97, 776, 512, 97, 778, 512, 99, 
+    807, 512, 101, 768, 512, 101, 769, 512, 101, 770, 512, 101, 776, 512, 
+    105, 768, 512, 105, 769, 512, 105, 770, 512, 105, 776, 512, 110, 771, 
+    512, 111, 768, 512, 111, 769, 512, 111, 770, 512, 111, 771, 512, 111, 
+    776, 512, 117, 768, 512, 117, 769, 512, 117, 770, 512, 117, 776, 512, 
+    121, 769, 512, 121, 776, 512, 65, 772, 512, 97, 772, 512, 65, 774, 512, 
+    97, 774, 512, 65, 808, 512, 97, 808, 512, 67, 769, 512, 99, 769, 512, 67, 
+    770, 512, 99, 770, 512, 67, 775, 512, 99, 775, 512, 67, 780, 512, 99, 
+    780, 512, 68, 780, 512, 100, 780, 512, 69, 772, 512, 101, 772, 512, 69, 
+    774, 512, 101, 774, 512, 69, 775, 512, 101, 775, 512, 69, 808, 512, 101, 
+    808, 512, 69, 780, 512, 101, 780, 512, 71, 770, 512, 103, 770, 512, 71, 
+    774, 512, 103, 774, 512, 71, 775, 512, 103, 775, 512, 71, 807, 512, 103, 
+    807, 512, 72, 770, 512, 104, 770, 512, 73, 771, 512, 105, 771, 512, 73, 
+    772, 512, 105, 772, 512, 73, 774, 512, 105, 774, 512, 73, 808, 512, 105, 
+    808, 512, 73, 775, 514, 73, 74, 514, 105, 106, 512, 74, 770, 512, 106, 
+    770, 512, 75, 807, 512, 107, 807, 512, 76, 769, 512, 108, 769, 512, 76, 
+    807, 512, 108, 807, 512, 76, 780, 512, 108, 780, 514, 76, 183, 514, 108, 
+    183, 512, 78, 769, 512, 110, 769, 512, 78, 807, 512, 110, 807, 512, 78, 
+    780, 512, 110, 780, 514, 700, 110, 512, 79, 772, 512, 111, 772, 512, 79, 
+    774, 512, 111, 774, 512, 79, 779, 512, 111, 779, 512, 82, 769, 512, 114, 
+    769, 512, 82, 807, 512, 114, 807, 512, 82, 780, 512, 114, 780, 512, 83, 
+    769, 512, 115, 769, 512, 83, 770, 512, 115, 770, 512, 83, 807, 512, 115, 
+    807, 512, 83, 780, 512, 115, 780, 512, 84, 807, 512, 116, 807, 512, 84, 
+    780, 512, 116, 780, 512, 85, 771, 512, 117, 771, 512, 85, 772, 512, 117, 
+    772, 512, 85, 774, 512, 117, 774, 512, 85, 778, 512, 117, 778, 512, 85, 
+    779, 512, 117, 779, 512, 85, 808, 512, 117, 808, 512, 87, 770, 512, 119, 
+    770, 512, 89, 770, 512, 121, 770, 512, 89, 776, 512, 90, 769, 512, 122, 
+    769, 512, 90, 775, 512, 122, 775, 512, 90, 780, 512, 122, 780, 258, 115, 
+    512, 79, 795, 512, 111, 795, 512, 85, 795, 512, 117, 795, 514, 68, 381, 
+    514, 68, 382, 514, 100, 382, 514, 76, 74, 514, 76, 106, 514, 108, 106, 
+    514, 78, 74, 514, 78, 106, 514, 110, 106, 512, 65, 780, 512, 97, 780, 
+    512, 73, 780, 512, 105, 780, 512, 79, 780, 512, 111, 780, 512, 85, 780, 
+    512, 117, 780, 512, 220, 772, 512, 252, 772, 512, 220, 769, 512, 252, 
+    769, 512, 220, 780, 512, 252, 780, 512, 220, 768, 512, 252, 768, 512, 
+    196, 772, 512, 228, 772, 512, 550, 772, 512, 551, 772, 512, 198, 772, 
+    512, 230, 772, 512, 71, 780, 512, 103, 780, 512, 75, 780, 512, 107, 780, 
+    512, 79, 808, 512, 111, 808, 512, 490, 772, 512, 491, 772, 512, 439, 780, 
+    512, 658, 780, 512, 106, 780, 514, 68, 90, 514, 68, 122, 514, 100, 122, 
+    512, 71, 769, 512, 103, 769, 512, 78, 768, 512, 110, 768, 512, 197, 769, 
+    512, 229, 769, 512, 198, 769, 512, 230, 769, 512, 216, 769, 512, 248, 
+    769, 512, 65, 783, 512, 97, 783, 512, 65, 785, 512, 97, 785, 512, 69, 
+    783, 512, 101, 783, 512, 69, 785, 512, 101, 785, 512, 73, 783, 512, 105, 
+    783, 512, 73, 785, 512, 105, 785, 512, 79, 783, 512, 111, 783, 512, 79, 
+    785, 512, 111, 785, 512, 82, 783, 512, 114, 783, 512, 82, 785, 512, 114, 
+    785, 512, 85, 783, 512, 117, 783, 512, 85, 785, 512, 117, 785, 512, 83, 
+    806, 512, 115, 806, 512, 84, 806, 512, 116, 806, 512, 72, 780, 512, 104, 
+    780, 512, 65, 775, 512, 97, 775, 512, 69, 807, 512, 101, 807, 512, 214, 
+    772, 512, 246, 772, 512, 213, 772, 512, 245, 772, 512, 79, 775, 512, 111, 
+    775, 512, 558, 772, 512, 559, 772, 512, 89, 772, 512, 121, 772, 259, 104, 
+    259, 614, 259, 106, 259, 114, 259, 633, 259, 635, 259, 641, 259, 119, 
+    259, 121, 514, 32, 774, 514, 32, 775, 514, 32, 778, 514, 32, 808, 514, 
+    32, 771, 514, 32, 779, 259, 611, 259, 108, 259, 115, 259, 120, 259, 661, 
+    256, 768, 256, 769, 256, 787, 512, 776, 769, 256, 697, 514, 32, 837, 256, 
+    59, 514, 32, 769, 512, 168, 769, 512, 913, 769, 256, 183, 512, 917, 769, 
+    512, 919, 769, 512, 921, 769, 512, 927, 769, 512, 933, 769, 512, 937, 
+    769, 512, 970, 769, 512, 921, 776, 512, 933, 776, 512, 945, 769, 512, 
+    949, 769, 512, 951, 769, 512, 953, 769, 512, 971, 769, 512, 953, 776, 
+    512, 965, 776, 512, 959, 769, 512, 965, 769, 512, 969, 769, 258, 946, 
+    258, 952, 258, 933, 512, 978, 769, 512, 978, 776, 258, 966, 258, 960, 
+    258, 954, 258, 961, 258, 962, 258, 920, 258, 949, 258, 931, 512, 1045, 
+    768, 512, 1045, 776, 512, 1043, 769, 512, 1030, 776, 512, 1050, 769, 512, 
+    1048, 768, 512, 1059, 774, 512, 1048, 774, 512, 1080, 774, 512, 1077, 
+    768, 512, 1077, 776, 512, 1075, 769, 512, 1110, 776, 512, 1082, 769, 512, 
+    1080, 768, 512, 1091, 774, 512, 1140, 783, 512, 1141, 783, 512, 1046, 
+    774, 512, 1078, 774, 512, 1040, 774, 512, 1072, 774, 512, 1040, 776, 512, 
+    1072, 776, 512, 1045, 774, 512, 1077, 774, 512, 1240, 776, 512, 1241, 
+    776, 512, 1046, 776, 512, 1078, 776, 512, 1047, 776, 512, 1079, 776, 512, 
+    1048, 772, 512, 1080, 772, 512, 1048, 776, 512, 1080, 776, 512, 1054, 
+    776, 512, 1086, 776, 512, 1256, 776, 512, 1257, 776, 512, 1069, 776, 512, 
+    1101, 776, 512, 1059, 772, 512, 1091, 772, 512, 1059, 776, 512, 1091, 
+    776, 512, 1059, 779, 512, 1091, 779, 512, 1063, 776, 512, 1095, 776, 512, 
+    1067, 776, 512, 1099, 776, 514, 1381, 1410, 512, 1575, 1619, 512, 1575, 
+    1620, 512, 1608, 1620, 512, 1575, 1621, 512, 1610, 1620, 514, 1575, 1652, 
+    514, 1608, 1652, 514, 1735, 1652, 514, 1610, 1652, 512, 1749, 1620, 512, 
+    1729, 1620, 512, 1746, 1620, 512, 2344, 2364, 512, 2352, 2364, 512, 2355, 
+    2364, 512, 2325, 2364, 512, 2326, 2364, 512, 2327, 2364, 512, 2332, 2364, 
+    512, 2337, 2364, 512, 2338, 2364, 512, 2347, 2364, 512, 2351, 2364, 512, 
+    2503, 2494, 512, 2503, 2519, 512, 2465, 2492, 512, 2466, 2492, 512, 2479, 
+    2492, 512, 2610, 2620, 512, 2616, 2620, 512, 2582, 2620, 512, 2583, 2620, 
+    512, 2588, 2620, 512, 2603, 2620, 512, 2887, 2902, 512, 2887, 2878, 512, 
+    2887, 2903, 512, 2849, 2876, 512, 2850, 2876, 512, 2962, 3031, 512, 3014, 
+    3006, 512, 3015, 3006, 512, 3014, 3031, 512, 3142, 3158, 512, 3263, 3285, 
+    512, 3270, 3285, 512, 3270, 3286, 512, 3270, 3266, 512, 3274, 3285, 512, 
+    3398, 3390, 512, 3399, 3390, 512, 3398, 3415, 512, 3545, 3530, 512, 3545, 
+    3535, 512, 3548, 3530, 512, 3545, 3551, 514, 3661, 3634, 514, 3789, 3762, 
+    514, 3755, 3737, 514, 3755, 3745, 257, 3851, 512, 3906, 4023, 512, 3916, 
+    4023, 512, 3921, 4023, 512, 3926, 4023, 512, 3931, 4023, 512, 3904, 4021, 
+    512, 3953, 3954, 512, 3953, 3956, 512, 4018, 3968, 514, 4018, 3969, 512, 
+    4019, 3968, 514, 4019, 3969, 512, 3953, 3968, 512, 3986, 4023, 512, 3996, 
+    4023, 512, 4001, 4023, 512, 4006, 4023, 512, 4011, 4023, 512, 3984, 4021, 
+    512, 4133, 4142, 259, 4316, 259, 65, 259, 198, 259, 66, 259, 68, 259, 69, 
+    259, 398, 259, 71, 259, 72, 259, 73, 259, 74, 259, 75, 259, 76, 259, 77, 
+    259, 78, 259, 79, 259, 546, 259, 80, 259, 82, 259, 84, 259, 85, 259, 87, 
+    259, 97, 259, 592, 259, 593, 259, 7426, 259, 98, 259, 100, 259, 101, 259, 
+    601, 259, 603, 259, 604, 259, 103, 259, 107, 259, 109, 259, 331, 259, 
+    111, 259, 596, 259, 7446, 259, 7447, 259, 112, 259, 116, 259, 117, 259, 
+    7453, 259, 623, 259, 118, 259, 7461, 259, 946, 259, 947, 259, 948, 259, 
+    966, 259, 967, 261, 105, 261, 114, 261, 117, 261, 118, 261, 946, 261, 
+    947, 261, 961, 261, 966, 261, 967, 259, 1085, 259, 594, 259, 99, 259, 
+    597, 259, 240, 259, 604, 259, 102, 259, 607, 259, 609, 259, 613, 259, 
+    616, 259, 617, 259, 618, 259, 7547, 259, 669, 259, 621, 259, 7557, 259, 
+    671, 259, 625, 259, 624, 259, 626, 259, 627, 259, 628, 259, 629, 259, 
+    632, 259, 642, 259, 643, 259, 427, 259, 649, 259, 650, 259, 7452, 259, 
+    651, 259, 652, 259, 122, 259, 656, 259, 657, 259, 658, 259, 952, 512, 65, 
+    805, 512, 97, 805, 512, 66, 775, 512, 98, 775, 512, 66, 803, 512, 98, 
+    803, 512, 66, 817, 512, 98, 817, 512, 199, 769, 512, 231, 769, 512, 68, 
+    775, 512, 100, 775, 512, 68, 803, 512, 100, 803, 512, 68, 817, 512, 100, 
+    817, 512, 68, 807, 512, 100, 807, 512, 68, 813, 512, 100, 813, 512, 274, 
+    768, 512, 275, 768, 512, 274, 769, 512, 275, 769, 512, 69, 813, 512, 101, 
+    813, 512, 69, 816, 512, 101, 816, 512, 552, 774, 512, 553, 774, 512, 70, 
+    775, 512, 102, 775, 512, 71, 772, 512, 103, 772, 512, 72, 775, 512, 104, 
+    775, 512, 72, 803, 512, 104, 803, 512, 72, 776, 512, 104, 776, 512, 72, 
+    807, 512, 104, 807, 512, 72, 814, 512, 104, 814, 512, 73, 816, 512, 105, 
+    816, 512, 207, 769, 512, 239, 769, 512, 75, 769, 512, 107, 769, 512, 75, 
+    803, 512, 107, 803, 512, 75, 817, 512, 107, 817, 512, 76, 803, 512, 108, 
+    803, 512, 7734, 772, 512, 7735, 772, 512, 76, 817, 512, 108, 817, 512, 
+    76, 813, 512, 108, 813, 512, 77, 769, 512, 109, 769, 512, 77, 775, 512, 
+    109, 775, 512, 77, 803, 512, 109, 803, 512, 78, 775, 512, 110, 775, 512, 
+    78, 803, 512, 110, 803, 512, 78, 817, 512, 110, 817, 512, 78, 813, 512, 
+    110, 813, 512, 213, 769, 512, 245, 769, 512, 213, 776, 512, 245, 776, 
+    512, 332, 768, 512, 333, 768, 512, 332, 769, 512, 333, 769, 512, 80, 769, 
+    512, 112, 769, 512, 80, 775, 512, 112, 775, 512, 82, 775, 512, 114, 775, 
+    512, 82, 803, 512, 114, 803, 512, 7770, 772, 512, 7771, 772, 512, 82, 
+    817, 512, 114, 817, 512, 83, 775, 512, 115, 775, 512, 83, 803, 512, 115, 
+    803, 512, 346, 775, 512, 347, 775, 512, 352, 775, 512, 353, 775, 512, 
+    7778, 775, 512, 7779, 775, 512, 84, 775, 512, 116, 775, 512, 84, 803, 
+    512, 116, 803, 512, 84, 817, 512, 116, 817, 512, 84, 813, 512, 116, 813, 
+    512, 85, 804, 512, 117, 804, 512, 85, 816, 512, 117, 816, 512, 85, 813, 
+    512, 117, 813, 512, 360, 769, 512, 361, 769, 512, 362, 776, 512, 363, 
+    776, 512, 86, 771, 512, 118, 771, 512, 86, 803, 512, 118, 803, 512, 87, 
+    768, 512, 119, 768, 512, 87, 769, 512, 119, 769, 512, 87, 776, 512, 119, 
+    776, 512, 87, 775, 512, 119, 775, 512, 87, 803, 512, 119, 803, 512, 88, 
+    775, 512, 120, 775, 512, 88, 776, 512, 120, 776, 512, 89, 775, 512, 121, 
+    775, 512, 90, 770, 512, 122, 770, 512, 90, 803, 512, 122, 803, 512, 90, 
+    817, 512, 122, 817, 512, 104, 817, 512, 116, 776, 512, 119, 778, 512, 
+    121, 778, 514, 97, 702, 512, 383, 775, 512, 65, 803, 512, 97, 803, 512, 
+    65, 777, 512, 97, 777, 512, 194, 769, 512, 226, 769, 512, 194, 768, 512, 
+    226, 768, 512, 194, 777, 512, 226, 777, 512, 194, 771, 512, 226, 771, 
+    512, 7840, 770, 512, 7841, 770, 512, 258, 769, 512, 259, 769, 512, 258, 
+    768, 512, 259, 768, 512, 258, 777, 512, 259, 777, 512, 258, 771, 512, 
+    259, 771, 512, 7840, 774, 512, 7841, 774, 512, 69, 803, 512, 101, 803, 
+    512, 69, 777, 512, 101, 777, 512, 69, 771, 512, 101, 771, 512, 202, 769, 
+    512, 234, 769, 512, 202, 768, 512, 234, 768, 512, 202, 777, 512, 234, 
+    777, 512, 202, 771, 512, 234, 771, 512, 7864, 770, 512, 7865, 770, 512, 
+    73, 777, 512, 105, 777, 512, 73, 803, 512, 105, 803, 512, 79, 803, 512, 
+    111, 803, 512, 79, 777, 512, 111, 777, 512, 212, 769, 512, 244, 769, 512, 
+    212, 768, 512, 244, 768, 512, 212, 777, 512, 244, 777, 512, 212, 771, 
+    512, 244, 771, 512, 7884, 770, 512, 7885, 770, 512, 416, 769, 512, 417, 
+    769, 512, 416, 768, 512, 417, 768, 512, 416, 777, 512, 417, 777, 512, 
+    416, 771, 512, 417, 771, 512, 416, 803, 512, 417, 803, 512, 85, 803, 512, 
+    117, 803, 512, 85, 777, 512, 117, 777, 512, 431, 769, 512, 432, 769, 512, 
+    431, 768, 512, 432, 768, 512, 431, 777, 512, 432, 777, 512, 431, 771, 
+    512, 432, 771, 512, 431, 803, 512, 432, 803, 512, 89, 768, 512, 121, 768, 
+    512, 89, 803, 512, 121, 803, 512, 89, 777, 512, 121, 777, 512, 89, 771, 
+    512, 121, 771, 512, 945, 787, 512, 945, 788, 512, 7936, 768, 512, 7937, 
+    768, 512, 7936, 769, 512, 7937, 769, 512, 7936, 834, 512, 7937, 834, 512, 
+    913, 787, 512, 913, 788, 512, 7944, 768, 512, 7945, 768, 512, 7944, 769, 
+    512, 7945, 769, 512, 7944, 834, 512, 7945, 834, 512, 949, 787, 512, 949, 
+    788, 512, 7952, 768, 512, 7953, 768, 512, 7952, 769, 512, 7953, 769, 512, 
+    917, 787, 512, 917, 788, 512, 7960, 768, 512, 7961, 768, 512, 7960, 769, 
+    512, 7961, 769, 512, 951, 787, 512, 951, 788, 512, 7968, 768, 512, 7969, 
+    768, 512, 7968, 769, 512, 7969, 769, 512, 7968, 834, 512, 7969, 834, 512, 
+    919, 787, 512, 919, 788, 512, 7976, 768, 512, 7977, 768, 512, 7976, 769, 
+    512, 7977, 769, 512, 7976, 834, 512, 7977, 834, 512, 953, 787, 512, 953, 
+    788, 512, 7984, 768, 512, 7985, 768, 512, 7984, 769, 512, 7985, 769, 512, 
+    7984, 834, 512, 7985, 834, 512, 921, 787, 512, 921, 788, 512, 7992, 768, 
+    512, 7993, 768, 512, 7992, 769, 512, 7993, 769, 512, 7992, 834, 512, 
+    7993, 834, 512, 959, 787, 512, 959, 788, 512, 8000, 768, 512, 8001, 768, 
+    512, 8000, 769, 512, 8001, 769, 512, 927, 787, 512, 927, 788, 512, 8008, 
+    768, 512, 8009, 768, 512, 8008, 769, 512, 8009, 769, 512, 965, 787, 512, 
+    965, 788, 512, 8016, 768, 512, 8017, 768, 512, 8016, 769, 512, 8017, 769, 
+    512, 8016, 834, 512, 8017, 834, 512, 933, 788, 512, 8025, 768, 512, 8025, 
+    769, 512, 8025, 834, 512, 969, 787, 512, 969, 788, 512, 8032, 768, 512, 
+    8033, 768, 512, 8032, 769, 512, 8033, 769, 512, 8032, 834, 512, 8033, 
+    834, 512, 937, 787, 512, 937, 788, 512, 8040, 768, 512, 8041, 768, 512, 
+    8040, 769, 512, 8041, 769, 512, 8040, 834, 512, 8041, 834, 512, 945, 768, 
+    256, 940, 512, 949, 768, 256, 941, 512, 951, 768, 256, 942, 512, 953, 
+    768, 256, 943, 512, 959, 768, 256, 972, 512, 965, 768, 256, 973, 512, 
+    969, 768, 256, 974, 512, 7936, 837, 512, 7937, 837, 512, 7938, 837, 512, 
+    7939, 837, 512, 7940, 837, 512, 7941, 837, 512, 7942, 837, 512, 7943, 
+    837, 512, 7944, 837, 512, 7945, 837, 512, 7946, 837, 512, 7947, 837, 512, 
+    7948, 837, 512, 7949, 837, 512, 7950, 837, 512, 7951, 837, 512, 7968, 
+    837, 512, 7969, 837, 512, 7970, 837, 512, 7971, 837, 512, 7972, 837, 512, 
+    7973, 837, 512, 7974, 837, 512, 7975, 837, 512, 7976, 837, 512, 7977, 
+    837, 512, 7978, 837, 512, 7979, 837, 512, 7980, 837, 512, 7981, 837, 512, 
+    7982, 837, 512, 7983, 837, 512, 8032, 837, 512, 8033, 837, 512, 8034, 
+    837, 512, 8035, 837, 512, 8036, 837, 512, 8037, 837, 512, 8038, 837, 512, 
+    8039, 837, 512, 8040, 837, 512, 8041, 837, 512, 8042, 837, 512, 8043, 
+    837, 512, 8044, 837, 512, 8045, 837, 512, 8046, 837, 512, 8047, 837, 512, 
+    945, 774, 512, 945, 772, 512, 8048, 837, 512, 945, 837, 512, 940, 837, 
+    512, 945, 834, 512, 8118, 837, 512, 913, 774, 512, 913, 772, 512, 913, 
+    768, 256, 902, 512, 913, 837, 514, 32, 787, 256, 953, 514, 32, 787, 514, 
+    32, 834, 512, 168, 834, 512, 8052, 837, 512, 951, 837, 512, 942, 837, 
+    512, 951, 834, 512, 8134, 837, 512, 917, 768, 256, 904, 512, 919, 768, 
+    256, 905, 512, 919, 837, 512, 8127, 768, 512, 8127, 769, 512, 8127, 834, 
+    512, 953, 774, 512, 953, 772, 512, 970, 768, 256, 912, 512, 953, 834, 
+    512, 970, 834, 512, 921, 774, 512, 921, 772, 512, 921, 768, 256, 906, 
+    512, 8190, 768, 512, 8190, 769, 512, 8190, 834, 512, 965, 774, 512, 965, 
+    772, 512, 971, 768, 256, 944, 512, 961, 787, 512, 961, 788, 512, 965, 
+    834, 512, 971, 834, 512, 933, 774, 512, 933, 772, 512, 933, 768, 256, 
+    910, 512, 929, 788, 512, 168, 768, 256, 901, 256, 96, 512, 8060, 837, 
+    512, 969, 837, 512, 974, 837, 512, 969, 834, 512, 8182, 837, 512, 927, 
+    768, 256, 908, 512, 937, 768, 256, 911, 512, 937, 837, 256, 180, 514, 32, 
+    788, 256, 8194, 256, 8195, 258, 32, 258, 32, 258, 32, 258, 32, 258, 32, 
+    257, 32, 258, 32, 258, 32, 258, 32, 257, 8208, 514, 32, 819, 258, 46, 
+    514, 46, 46, 770, 46, 46, 46, 257, 32, 514, 8242, 8242, 770, 8242, 8242, 
+    8242, 514, 8245, 8245, 770, 8245, 8245, 8245, 514, 33, 33, 514, 32, 773, 
+    514, 63, 63, 514, 63, 33, 514, 33, 63, 1026, 8242, 8242, 8242, 8242, 258, 
+    32, 259, 48, 259, 105, 259, 52, 259, 53, 259, 54, 259, 55, 259, 56, 259, 
+    57, 259, 43, 259, 8722, 259, 61, 259, 40, 259, 41, 259, 110, 261, 48, 
+    261, 49, 261, 50, 261, 51, 261, 52, 261, 53, 261, 54, 261, 55, 261, 56, 
+    261, 57, 261, 43, 261, 8722, 261, 61, 261, 40, 261, 41, 261, 97, 261, 
+    101, 261, 111, 261, 120, 261, 601, 514, 82, 115, 770, 97, 47, 99, 770, 
+    97, 47, 115, 262, 67, 514, 176, 67, 770, 99, 47, 111, 770, 99, 47, 117, 
+    258, 400, 514, 176, 70, 262, 103, 262, 72, 262, 72, 262, 72, 262, 104, 
+    262, 295, 262, 73, 262, 73, 262, 76, 262, 108, 262, 78, 514, 78, 111, 
+    262, 80, 262, 81, 262, 82, 262, 82, 262, 82, 515, 83, 77, 770, 84, 69, 
+    76, 515, 84, 77, 262, 90, 256, 937, 262, 90, 256, 75, 256, 197, 262, 66, 
+    262, 67, 262, 101, 262, 69, 262, 70, 262, 77, 262, 111, 258, 1488, 258, 
+    1489, 258, 1490, 258, 1491, 262, 105, 770, 70, 65, 88, 262, 960, 262, 
+    947, 262, 915, 262, 928, 262, 8721, 262, 68, 262, 100, 262, 101, 262, 
+    105, 262, 106, 772, 49, 8260, 51, 772, 50, 8260, 51, 772, 49, 8260, 53, 
+    772, 50, 8260, 53, 772, 51, 8260, 53, 772, 52, 8260, 53, 772, 49, 8260, 
+    54, 772, 53, 8260, 54, 772, 49, 8260, 56, 772, 51, 8260, 56, 772, 53, 
+    8260, 56, 772, 55, 8260, 56, 516, 49, 8260, 258, 73, 514, 73, 73, 770, 
+    73, 73, 73, 514, 73, 86, 258, 86, 514, 86, 73, 770, 86, 73, 73, 1026, 86, 
+    73, 73, 73, 514, 73, 88, 258, 88, 514, 88, 73, 770, 88, 73, 73, 258, 76, 
+    258, 67, 258, 68, 258, 77, 258, 105, 514, 105, 105, 770, 105, 105, 105, 
+    514, 105, 118, 258, 118, 514, 118, 105, 770, 118, 105, 105, 1026, 118, 
+    105, 105, 105, 514, 105, 120, 258, 120, 514, 120, 105, 770, 120, 105, 
+    105, 258, 108, 258, 99, 258, 100, 258, 109, 512, 8592, 824, 512, 8594, 
+    824, 512, 8596, 824, 512, 8656, 824, 512, 8660, 824, 512, 8658, 824, 512, 
+    8707, 824, 512, 8712, 824, 512, 8715, 824, 512, 8739, 824, 512, 8741, 
+    824, 514, 8747, 8747, 770, 8747, 8747, 8747, 514, 8750, 8750, 770, 8750, 
+    8750, 8750, 512, 8764, 824, 512, 8771, 824, 512, 8773, 824, 512, 8776, 
+    824, 512, 61, 824, 512, 8801, 824, 512, 8781, 824, 512, 60, 824, 512, 62, 
+    824, 512, 8804, 824, 512, 8805, 824, 512, 8818, 824, 512, 8819, 824, 512, 
+    8822, 824, 512, 8823, 824, 512, 8826, 824, 512, 8827, 824, 512, 8834, 
+    824, 512, 8835, 824, 512, 8838, 824, 512, 8839, 824, 512, 8866, 824, 512, 
+    8872, 824, 512, 8873, 824, 512, 8875, 824, 512, 8828, 824, 512, 8829, 
+    824, 512, 8849, 824, 512, 8850, 824, 512, 8882, 824, 512, 8883, 824, 512, 
+    8884, 824, 512, 8885, 824, 256, 12296, 256, 12297, 263, 49, 263, 50, 263, 
+    51, 263, 52, 263, 53, 263, 54, 263, 55, 263, 56, 263, 57, 519, 49, 48, 
+    519, 49, 49, 519, 49, 50, 519, 49, 51, 519, 49, 52, 519, 49, 53, 519, 49, 
+    54, 519, 49, 55, 519, 49, 56, 519, 49, 57, 519, 50, 48, 770, 40, 49, 41, 
+    770, 40, 50, 41, 770, 40, 51, 41, 770, 40, 52, 41, 770, 40, 53, 41, 770, 
+    40, 54, 41, 770, 40, 55, 41, 770, 40, 56, 41, 770, 40, 57, 41, 1026, 40, 
+    49, 48, 41, 1026, 40, 49, 49, 41, 1026, 40, 49, 50, 41, 1026, 40, 49, 51, 
+    41, 1026, 40, 49, 52, 41, 1026, 40, 49, 53, 41, 1026, 40, 49, 54, 41, 
+    1026, 40, 49, 55, 41, 1026, 40, 49, 56, 41, 1026, 40, 49, 57, 41, 1026, 
+    40, 50, 48, 41, 514, 49, 46, 514, 50, 46, 514, 51, 46, 514, 52, 46, 514, 
+    53, 46, 514, 54, 46, 514, 55, 46, 514, 56, 46, 514, 57, 46, 770, 49, 48, 
+    46, 770, 49, 49, 46, 770, 49, 50, 46, 770, 49, 51, 46, 770, 49, 52, 46, 
+    770, 49, 53, 46, 770, 49, 54, 46, 770, 49, 55, 46, 770, 49, 56, 46, 770, 
+    49, 57, 46, 770, 50, 48, 46, 770, 40, 97, 41, 770, 40, 98, 41, 770, 40, 
+    99, 41, 770, 40, 100, 41, 770, 40, 101, 41, 770, 40, 102, 41, 770, 40, 
+    103, 41, 770, 40, 104, 41, 770, 40, 105, 41, 770, 40, 106, 41, 770, 40, 
+    107, 41, 770, 40, 108, 41, 770, 40, 109, 41, 770, 40, 110, 41, 770, 40, 
+    111, 41, 770, 40, 112, 41, 770, 40, 113, 41, 770, 40, 114, 41, 770, 40, 
+    115, 41, 770, 40, 116, 41, 770, 40, 117, 41, 770, 40, 118, 41, 770, 40, 
+    119, 41, 770, 40, 120, 41, 770, 40, 121, 41, 770, 40, 122, 41, 263, 65, 
+    263, 66, 263, 67, 263, 68, 263, 69, 263, 70, 263, 71, 263, 72, 263, 73, 
+    263, 74, 263, 75, 263, 76, 263, 77, 263, 78, 263, 79, 263, 80, 263, 81, 
+    263, 82, 263, 83, 263, 84, 263, 85, 263, 86, 263, 87, 263, 88, 263, 89, 
+    263, 90, 263, 97, 263, 98, 263, 99, 263, 100, 263, 101, 263, 102, 263, 
+    103, 263, 104, 263, 105, 263, 106, 263, 107, 263, 108, 263, 109, 263, 
+    110, 263, 111, 263, 112, 263, 113, 263, 114, 263, 115, 263, 116, 263, 
+    117, 263, 118, 263, 119, 263, 120, 263, 121, 263, 122, 263, 48, 1026, 
+    8747, 8747, 8747, 8747, 770, 58, 58, 61, 514, 61, 61, 770, 61, 61, 61, 
+    512, 10973, 824, 259, 11617, 258, 27597, 258, 40863, 258, 19968, 258, 
+    20008, 258, 20022, 258, 20031, 258, 20057, 258, 20101, 258, 20108, 258, 
+    20128, 258, 20154, 258, 20799, 258, 20837, 258, 20843, 258, 20866, 258, 
+    20886, 258, 20907, 258, 20960, 258, 20981, 258, 20992, 258, 21147, 258, 
+    21241, 258, 21269, 258, 21274, 258, 21304, 258, 21313, 258, 21340, 258, 
+    21353, 258, 21378, 258, 21430, 258, 21448, 258, 21475, 258, 22231, 258, 
+    22303, 258, 22763, 258, 22786, 258, 22794, 258, 22805, 258, 22823, 258, 
+    22899, 258, 23376, 258, 23424, 258, 23544, 258, 23567, 258, 23586, 258, 
+    23608, 258, 23662, 258, 23665, 258, 24027, 258, 24037, 258, 24049, 258, 
+    24062, 258, 24178, 258, 24186, 258, 24191, 258, 24308, 258, 24318, 258, 
+    24331, 258, 24339, 258, 24400, 258, 24417, 258, 24435, 258, 24515, 258, 
+    25096, 258, 25142, 258, 25163, 258, 25903, 258, 25908, 258, 25991, 258, 
+    26007, 258, 26020, 258, 26041, 258, 26080, 258, 26085, 258, 26352, 258, 
+    26376, 258, 26408, 258, 27424, 258, 27490, 258, 27513, 258, 27571, 258, 
+    27595, 258, 27604, 258, 27611, 258, 27663, 258, 27668, 258, 27700, 258, 
+    28779, 258, 29226, 258, 29238, 258, 29243, 258, 29247, 258, 29255, 258, 
+    29273, 258, 29275, 258, 29356, 258, 29572, 258, 29577, 258, 29916, 258, 
+    29926, 258, 29976, 258, 29983, 258, 29992, 258, 30000, 258, 30091, 258, 
+    30098, 258, 30326, 258, 30333, 258, 30382, 258, 30399, 258, 30446, 258, 
+    30683, 258, 30690, 258, 30707, 258, 31034, 258, 31160, 258, 31166, 258, 
+    31348, 258, 31435, 258, 31481, 258, 31859, 258, 31992, 258, 32566, 258, 
+    32593, 258, 32650, 258, 32701, 258, 32769, 258, 32780, 258, 32786, 258, 
+    32819, 258, 32895, 258, 32905, 258, 33251, 258, 33258, 258, 33267, 258, 
+    33276, 258, 33292, 258, 33307, 258, 33311, 258, 33390, 258, 33394, 258, 
+    33400, 258, 34381, 258, 34411, 258, 34880, 258, 34892, 258, 34915, 258, 
+    35198, 258, 35211, 258, 35282, 258, 35328, 258, 35895, 258, 35910, 258, 
+    35925, 258, 35960, 258, 35997, 258, 36196, 258, 36208, 258, 36275, 258, 
+    36523, 258, 36554, 258, 36763, 258, 36784, 258, 36789, 258, 37009, 258, 
+    37193, 258, 37318, 258, 37324, 258, 37329, 258, 38263, 258, 38272, 258, 
+    38428, 258, 38582, 258, 38585, 258, 38632, 258, 38737, 258, 38750, 258, 
+    38754, 258, 38761, 258, 38859, 258, 38893, 258, 38899, 258, 38913, 258, 
+    39080, 258, 39131, 258, 39135, 258, 39318, 258, 39321, 258, 39340, 258, 
+    39592, 258, 39640, 258, 39647, 258, 39717, 258, 39727, 258, 39730, 258, 
+    39740, 258, 39770, 258, 40165, 258, 40565, 258, 40575, 258, 40613, 258, 
+    40635, 258, 40643, 258, 40653, 258, 40657, 258, 40697, 258, 40701, 258, 
+    40718, 258, 40723, 258, 40736, 258, 40763, 258, 40778, 258, 40786, 258, 
+    40845, 258, 40860, 258, 40864, 264, 32, 258, 12306, 258, 21313, 258, 
+    21316, 258, 21317, 512, 12363, 12441, 512, 12365, 12441, 512, 12367, 
+    12441, 512, 12369, 12441, 512, 12371, 12441, 512, 12373, 12441, 512, 
+    12375, 12441, 512, 12377, 12441, 512, 12379, 12441, 512, 12381, 12441, 
+    512, 12383, 12441, 512, 12385, 12441, 512, 12388, 12441, 512, 12390, 
+    12441, 512, 12392, 12441, 512, 12399, 12441, 512, 12399, 12442, 512, 
+    12402, 12441, 512, 12402, 12442, 512, 12405, 12441, 512, 12405, 12442, 
+    512, 12408, 12441, 512, 12408, 12442, 512, 12411, 12441, 512, 12411, 
+    12442, 512, 12358, 12441, 514, 32, 12441, 514, 32, 12442, 512, 12445, 
+    12441, 521, 12424, 12426, 512, 12459, 12441, 512, 12461, 12441, 512, 
+    12463, 12441, 512, 12465, 12441, 512, 12467, 12441, 512, 12469, 12441, 
+    512, 12471, 12441, 512, 12473, 12441, 512, 12475, 12441, 512, 12477, 
+    12441, 512, 12479, 12441, 512, 12481, 12441, 512, 12484, 12441, 512, 
+    12486, 12441, 512, 12488, 12441, 512, 12495, 12441, 512, 12495, 12442, 
+    512, 12498, 12441, 512, 12498, 12442, 512, 12501, 12441, 512, 12501, 
+    12442, 512, 12504, 12441, 512, 12504, 12442, 512, 12507, 12441, 512, 
+    12507, 12442, 512, 12454, 12441, 512, 12527, 12441, 512, 12528, 12441, 
+    512, 12529, 12441, 512, 12530, 12441, 512, 12541, 12441, 521, 12467, 
+    12488, 258, 4352, 258, 4353, 258, 4522, 258, 4354, 258, 4524, 258, 4525, 
+    258, 4355, 258, 4356, 258, 4357, 258, 4528, 258, 4529, 258, 4530, 258, 
+    4531, 258, 4532, 258, 4533, 258, 4378, 258, 4358, 258, 4359, 258, 4360, 
+    258, 4385, 258, 4361, 258, 4362, 258, 4363, 258, 4364, 258, 4365, 258, 
+    4366, 258, 4367, 258, 4368, 258, 4369, 258, 4370, 258, 4449, 258, 4450, 
+    258, 4451, 258, 4452, 258, 4453, 258, 4454, 258, 4455, 258, 4456, 258, 
+    4457, 258, 4458, 258, 4459, 258, 4460, 258, 4461, 258, 4462, 258, 4463, 
+    258, 4464, 258, 4465, 258, 4466, 258, 4467, 258, 4468, 258, 4469, 258, 
+    4448, 258, 4372, 258, 4373, 258, 4551, 258, 4552, 258, 4556, 258, 4558, 
+    258, 4563, 258, 4567, 258, 4569, 258, 4380, 258, 4573, 258, 4575, 258, 
+    4381, 258, 4382, 258, 4384, 258, 4386, 258, 4387, 258, 4391, 258, 4393, 
+    258, 4395, 258, 4396, 258, 4397, 258, 4398, 258, 4399, 258, 4402, 258, 
+    4406, 258, 4416, 258, 4423, 258, 4428, 258, 4593, 258, 4594, 258, 4439, 
+    258, 4440, 258, 4441, 258, 4484, 258, 4485, 258, 4488, 258, 4497, 258, 
+    4498, 258, 4500, 258, 4510, 258, 4513, 259, 19968, 259, 20108, 259, 
+    19977, 259, 22235, 259, 19978, 259, 20013, 259, 19979, 259, 30002, 259, 
+    20057, 259, 19993, 259, 19969, 259, 22825, 259, 22320, 259, 20154, 770, 
+    40, 4352, 41, 770, 40, 4354, 41, 770, 40, 4355, 41, 770, 40, 4357, 41, 
+    770, 40, 4358, 41, 770, 40, 4359, 41, 770, 40, 4361, 41, 770, 40, 4363, 
+    41, 770, 40, 4364, 41, 770, 40, 4366, 41, 770, 40, 4367, 41, 770, 40, 
+    4368, 41, 770, 40, 4369, 41, 770, 40, 4370, 41, 1026, 40, 4352, 4449, 41, 
+    1026, 40, 4354, 4449, 41, 1026, 40, 4355, 4449, 41, 1026, 40, 4357, 4449, 
+    41, 1026, 40, 4358, 4449, 41, 1026, 40, 4359, 4449, 41, 1026, 40, 4361, 
+    4449, 41, 1026, 40, 4363, 4449, 41, 1026, 40, 4364, 4449, 41, 1026, 40, 
+    4366, 4449, 41, 1026, 40, 4367, 4449, 41, 1026, 40, 4368, 4449, 41, 1026, 
+    40, 4369, 4449, 41, 1026, 40, 4370, 4449, 41, 1026, 40, 4364, 4462, 41, 
+    1794, 40, 4363, 4457, 4364, 4453, 4523, 41, 1538, 40, 4363, 4457, 4370, 
+    4462, 41, 770, 40, 19968, 41, 770, 40, 20108, 41, 770, 40, 19977, 41, 
+    770, 40, 22235, 41, 770, 40, 20116, 41, 770, 40, 20845, 41, 770, 40, 
+    19971, 41, 770, 40, 20843, 41, 770, 40, 20061, 41, 770, 40, 21313, 41, 
+    770, 40, 26376, 41, 770, 40, 28779, 41, 770, 40, 27700, 41, 770, 40, 
+    26408, 41, 770, 40, 37329, 41, 770, 40, 22303, 41, 770, 40, 26085, 41, 
+    770, 40, 26666, 41, 770, 40, 26377, 41, 770, 40, 31038, 41, 770, 40, 
+    21517, 41, 770, 40, 29305, 41, 770, 40, 36001, 41, 770, 40, 31069, 41, 
+    770, 40, 21172, 41, 770, 40, 20195, 41, 770, 40, 21628, 41, 770, 40, 
+    23398, 41, 770, 40, 30435, 41, 770, 40, 20225, 41, 770, 40, 36039, 41, 
+    770, 40, 21332, 41, 770, 40, 31085, 41, 770, 40, 20241, 41, 770, 40, 
+    33258, 41, 770, 40, 33267, 41, 778, 80, 84, 69, 519, 50, 49, 519, 50, 50, 
+    519, 50, 51, 519, 50, 52, 519, 50, 53, 519, 50, 54, 519, 50, 55, 519, 50, 
+    56, 519, 50, 57, 519, 51, 48, 519, 51, 49, 519, 51, 50, 519, 51, 51, 519, 
+    51, 52, 519, 51, 53, 263, 4352, 263, 4354, 263, 4355, 263, 4357, 263, 
+    4358, 263, 4359, 263, 4361, 263, 4363, 263, 4364, 263, 4366, 263, 4367, 
+    263, 4368, 263, 4369, 263, 4370, 519, 4352, 4449, 519, 4354, 4449, 519, 
+    4355, 4449, 519, 4357, 4449, 519, 4358, 4449, 519, 4359, 4449, 519, 4361, 
+    4449, 519, 4363, 4449, 519, 4364, 4449, 519, 4366, 4449, 519, 4367, 4449, 
+    519, 4368, 4449, 519, 4369, 4449, 519, 4370, 4449, 1287, 4366, 4449, 
+    4535, 4352, 4457, 1031, 4364, 4462, 4363, 4468, 519, 4363, 4462, 263, 
+    19968, 263, 20108, 263, 19977, 263, 22235, 263, 20116, 263, 20845, 263, 
+    19971, 263, 20843, 263, 20061, 263, 21313, 263, 26376, 263, 28779, 263, 
+    27700, 263, 26408, 263, 37329, 263, 22303, 263, 26085, 263, 26666, 263, 
+    26377, 263, 31038, 263, 21517, 263, 29305, 263, 36001, 263, 31069, 263, 
+    21172, 263, 31192, 263, 30007, 263, 22899, 263, 36969, 263, 20778, 263, 
+    21360, 263, 27880, 263, 38917, 263, 20241, 263, 20889, 263, 27491, 263, 
+    19978, 263, 20013, 263, 19979, 263, 24038, 263, 21491, 263, 21307, 263, 
+    23447, 263, 23398, 263, 30435, 263, 20225, 263, 36039, 263, 21332, 263, 
+    22812, 519, 51, 54, 519, 51, 55, 519, 51, 56, 519, 51, 57, 519, 52, 48, 
+    519, 52, 49, 519, 52, 50, 519, 52, 51, 519, 52, 52, 519, 52, 53, 519, 52, 
+    54, 519, 52, 55, 519, 52, 56, 519, 52, 57, 519, 53, 48, 514, 49, 26376, 
+    514, 50, 26376, 514, 51, 26376, 514, 52, 26376, 514, 53, 26376, 514, 54, 
+    26376, 514, 55, 26376, 514, 56, 26376, 514, 57, 26376, 770, 49, 48, 
+    26376, 770, 49, 49, 26376, 770, 49, 50, 26376, 522, 72, 103, 778, 101, 
+    114, 103, 522, 101, 86, 778, 76, 84, 68, 263, 12450, 263, 12452, 263, 
+    12454, 263, 12456, 263, 12458, 263, 12459, 263, 12461, 263, 12463, 263, 
+    12465, 263, 12467, 263, 12469, 263, 12471, 263, 12473, 263, 12475, 263, 
+    12477, 263, 12479, 263, 12481, 263, 12484, 263, 12486, 263, 12488, 263, 
+    12490, 263, 12491, 263, 12492, 263, 12493, 263, 12494, 263, 12495, 263, 
+    12498, 263, 12501, 263, 12504, 263, 12507, 263, 12510, 263, 12511, 263, 
+    12512, 263, 12513, 263, 12514, 263, 12516, 263, 12518, 263, 12520, 263, 
+    12521, 263, 12522, 263, 12523, 263, 12524, 263, 12525, 263, 12527, 263, 
+    12528, 263, 12529, 263, 12530, 1034, 12450, 12497, 12540, 12488, 1034, 
+    12450, 12523, 12501, 12449, 1034, 12450, 12531, 12506, 12450, 778, 12450, 
+    12540, 12523, 1034, 12452, 12491, 12531, 12464, 778, 12452, 12531, 12481, 
+    778, 12454, 12457, 12531, 1290, 12456, 12473, 12463, 12540, 12489, 1034, 
+    12456, 12540, 12459, 12540, 778, 12458, 12531, 12473, 778, 12458, 12540, 
+    12512, 778, 12459, 12452, 12522, 1034, 12459, 12521, 12483, 12488, 1034, 
+    12459, 12525, 12522, 12540, 778, 12460, 12525, 12531, 778, 12460, 12531, 
+    12510, 522, 12462, 12460, 778, 12462, 12491, 12540, 1034, 12461, 12517, 
+    12522, 12540, 1034, 12462, 12523, 12480, 12540, 522, 12461, 12525, 1290, 
+    12461, 12525, 12464, 12521, 12512, 1546, 12461, 12525, 12513, 12540, 
+    12488, 12523, 1290, 12461, 12525, 12527, 12483, 12488, 778, 12464, 12521, 
+    12512, 1290, 12464, 12521, 12512, 12488, 12531, 1290, 12463, 12523, 
+    12476, 12452, 12525, 1034, 12463, 12525, 12540, 12493, 778, 12465, 12540, 
+    12473, 778, 12467, 12523, 12490, 778, 12467, 12540, 12509, 1034, 12469, 
+    12452, 12463, 12523, 1290, 12469, 12531, 12481, 12540, 12512, 1034, 
+    12471, 12522, 12531, 12464, 778, 12475, 12531, 12481, 778, 12475, 12531, 
+    12488, 778, 12480, 12540, 12473, 522, 12487, 12471, 522, 12489, 12523, 
+    522, 12488, 12531, 522, 12490, 12494, 778, 12494, 12483, 12488, 778, 
+    12495, 12452, 12484, 1290, 12497, 12540, 12475, 12531, 12488, 778, 12497, 
+    12540, 12484, 1034, 12496, 12540, 12524, 12523, 1290, 12500, 12450, 
+    12473, 12488, 12523, 778, 12500, 12463, 12523, 522, 12500, 12467, 522, 
+    12499, 12523, 1290, 12501, 12449, 12521, 12483, 12489, 1034, 12501, 
+    12451, 12540, 12488, 1290, 12502, 12483, 12471, 12455, 12523, 778, 12501, 
+    12521, 12531, 1290, 12504, 12463, 12479, 12540, 12523, 522, 12506, 12477, 
+    778, 12506, 12491, 12498, 778, 12504, 12523, 12484, 778, 12506, 12531, 
+    12473, 778, 12506, 12540, 12472, 778, 12505, 12540, 12479, 1034, 12509, 
+    12452, 12531, 12488, 778, 12508, 12523, 12488, 522, 12507, 12531, 778, 
+    12509, 12531, 12489, 778, 12507, 12540, 12523, 778, 12507, 12540, 12531, 
+    1034, 12510, 12452, 12463, 12525, 778, 12510, 12452, 12523, 778, 12510, 
+    12483, 12495, 778, 12510, 12523, 12463, 1290, 12510, 12531, 12471, 12519, 
+    12531, 1034, 12511, 12463, 12525, 12531, 522, 12511, 12522, 1290, 12511, 
+    12522, 12496, 12540, 12523, 522, 12513, 12460, 1034, 12513, 12460, 12488, 
+    12531, 1034, 12513, 12540, 12488, 12523, 778, 12516, 12540, 12489, 778, 
+    12516, 12540, 12523, 778, 12518, 12450, 12531, 1034, 12522, 12483, 12488, 
+    12523, 522, 12522, 12521, 778, 12523, 12500, 12540, 1034, 12523, 12540, 
+    12502, 12523, 522, 12524, 12512, 1290, 12524, 12531, 12488, 12466, 12531, 
+    778, 12527, 12483, 12488, 514, 48, 28857, 514, 49, 28857, 514, 50, 28857, 
+    514, 51, 28857, 514, 52, 28857, 514, 53, 28857, 514, 54, 28857, 514, 55, 
+    28857, 514, 56, 28857, 514, 57, 28857, 770, 49, 48, 28857, 770, 49, 49, 
+    28857, 770, 49, 50, 28857, 770, 49, 51, 28857, 770, 49, 52, 28857, 770, 
+    49, 53, 28857, 770, 49, 54, 28857, 770, 49, 55, 28857, 770, 49, 56, 
+    28857, 770, 49, 57, 28857, 770, 50, 48, 28857, 770, 50, 49, 28857, 770, 
+    50, 50, 28857, 770, 50, 51, 28857, 770, 50, 52, 28857, 778, 104, 80, 97, 
+    522, 100, 97, 522, 65, 85, 778, 98, 97, 114, 522, 111, 86, 522, 112, 99, 
+    522, 100, 109, 778, 100, 109, 178, 778, 100, 109, 179, 522, 73, 85, 522, 
+    24179, 25104, 522, 26157, 21644, 522, 22823, 27491, 522, 26126, 27835, 
+    1034, 26666, 24335, 20250, 31038, 522, 112, 65, 522, 110, 65, 522, 956, 
+    65, 522, 109, 65, 522, 107, 65, 522, 75, 66, 522, 77, 66, 522, 71, 66, 
+    778, 99, 97, 108, 1034, 107, 99, 97, 108, 522, 112, 70, 522, 110, 70, 
+    522, 956, 70, 522, 956, 103, 522, 109, 103, 522, 107, 103, 522, 72, 122, 
+    778, 107, 72, 122, 778, 77, 72, 122, 778, 71, 72, 122, 778, 84, 72, 122, 
+    522, 956, 8467, 522, 109, 8467, 522, 100, 8467, 522, 107, 8467, 522, 102, 
+    109, 522, 110, 109, 522, 956, 109, 522, 109, 109, 522, 99, 109, 522, 107, 
+    109, 778, 109, 109, 178, 778, 99, 109, 178, 522, 109, 178, 778, 107, 109, 
+    178, 778, 109, 109, 179, 778, 99, 109, 179, 522, 109, 179, 778, 107, 109, 
+    179, 778, 109, 8725, 115, 1034, 109, 8725, 115, 178, 522, 80, 97, 778, 
+    107, 80, 97, 778, 77, 80, 97, 778, 71, 80, 97, 778, 114, 97, 100, 1290, 
+    114, 97, 100, 8725, 115, 1546, 114, 97, 100, 8725, 115, 178, 522, 112, 
+    115, 522, 110, 115, 522, 956, 115, 522, 109, 115, 522, 112, 86, 522, 110, 
+    86, 522, 956, 86, 522, 109, 86, 522, 107, 86, 522, 77, 86, 522, 112, 87, 
+    522, 110, 87, 522, 956, 87, 522, 109, 87, 522, 107, 87, 522, 77, 87, 522, 
+    107, 937, 522, 77, 937, 1034, 97, 46, 109, 46, 522, 66, 113, 522, 99, 99, 
+    522, 99, 100, 1034, 67, 8725, 107, 103, 778, 67, 111, 46, 522, 100, 66, 
+    522, 71, 121, 522, 104, 97, 522, 72, 80, 522, 105, 110, 522, 75, 75, 522, 
+    75, 77, 522, 107, 116, 522, 108, 109, 522, 108, 110, 778, 108, 111, 103, 
+    522, 108, 120, 522, 109, 98, 778, 109, 105, 108, 778, 109, 111, 108, 522, 
+    80, 72, 1034, 112, 46, 109, 46, 778, 80, 80, 77, 522, 80, 82, 522, 115, 
+    114, 522, 83, 118, 522, 87, 98, 778, 86, 8725, 109, 778, 65, 8725, 109, 
+    514, 49, 26085, 514, 50, 26085, 514, 51, 26085, 514, 52, 26085, 514, 53, 
+    26085, 514, 54, 26085, 514, 55, 26085, 514, 56, 26085, 514, 57, 26085, 
+    770, 49, 48, 26085, 770, 49, 49, 26085, 770, 49, 50, 26085, 770, 49, 51, 
+    26085, 770, 49, 52, 26085, 770, 49, 53, 26085, 770, 49, 54, 26085, 770, 
+    49, 55, 26085, 770, 49, 56, 26085, 770, 49, 57, 26085, 770, 50, 48, 
+    26085, 770, 50, 49, 26085, 770, 50, 50, 26085, 770, 50, 51, 26085, 770, 
+    50, 52, 26085, 770, 50, 53, 26085, 770, 50, 54, 26085, 770, 50, 55, 
+    26085, 770, 50, 56, 26085, 770, 50, 57, 26085, 770, 51, 48, 26085, 770, 
+    51, 49, 26085, 778, 103, 97, 108, 256, 35912, 256, 26356, 256, 36554, 
+    256, 36040, 256, 28369, 256, 20018, 256, 21477, 256, 40860, 256, 40860, 
+    256, 22865, 256, 37329, 256, 21895, 256, 22856, 256, 25078, 256, 30313, 
+    256, 32645, 256, 34367, 256, 34746, 256, 35064, 256, 37007, 256, 27138, 
+    256, 27931, 256, 28889, 256, 29662, 256, 33853, 256, 37226, 256, 39409, 
+    256, 20098, 256, 21365, 256, 27396, 256, 29211, 256, 34349, 256, 40478, 
+    256, 23888, 256, 28651, 256, 34253, 256, 35172, 256, 25289, 256, 33240, 
+    256, 34847, 256, 24266, 256, 26391, 256, 28010, 256, 29436, 256, 37070, 
+    256, 20358, 256, 20919, 256, 21214, 256, 25796, 256, 27347, 256, 29200, 
+    256, 30439, 256, 32769, 256, 34310, 256, 34396, 256, 36335, 256, 38706, 
+    256, 39791, 256, 40442, 256, 30860, 256, 31103, 256, 32160, 256, 33737, 
+    256, 37636, 256, 40575, 256, 35542, 256, 22751, 256, 24324, 256, 31840, 
+    256, 32894, 256, 29282, 256, 30922, 256, 36034, 256, 38647, 256, 22744, 
+    256, 23650, 256, 27155, 256, 28122, 256, 28431, 256, 32047, 256, 32311, 
+    256, 38475, 256, 21202, 256, 32907, 256, 20956, 256, 20940, 256, 31260, 
+    256, 32190, 256, 33777, 256, 38517, 256, 35712, 256, 25295, 256, 27138, 
+    256, 35582, 256, 20025, 256, 23527, 256, 24594, 256, 29575, 256, 30064, 
+    256, 21271, 256, 30971, 256, 20415, 256, 24489, 256, 19981, 256, 27852, 
+    256, 25976, 256, 32034, 256, 21443, 256, 22622, 256, 30465, 256, 33865, 
+    256, 35498, 256, 27578, 256, 36784, 256, 27784, 256, 25342, 256, 33509, 
+    256, 25504, 256, 30053, 256, 20142, 256, 20841, 256, 20937, 256, 26753, 
+    256, 31975, 256, 33391, 256, 35538, 256, 37327, 256, 21237, 256, 21570, 
+    256, 22899, 256, 24300, 256, 26053, 256, 28670, 256, 31018, 256, 38317, 
+    256, 39530, 256, 40599, 256, 40654, 256, 21147, 256, 26310, 256, 27511, 
+    256, 36706, 256, 24180, 256, 24976, 256, 25088, 256, 25754, 256, 28451, 
+    256, 29001, 256, 29833, 256, 31178, 256, 32244, 256, 32879, 256, 36646, 
+    256, 34030, 256, 36899, 256, 37706, 256, 21015, 256, 21155, 256, 21693, 
+    256, 28872, 256, 35010, 256, 35498, 256, 24265, 256, 24565, 256, 25467, 
+    256, 27566, 256, 31806, 256, 29557, 256, 20196, 256, 22265, 256, 23527, 
+    256, 23994, 256, 24604, 256, 29618, 256, 29801, 256, 32666, 256, 32838, 
+    256, 37428, 256, 38646, 256, 38728, 256, 38936, 256, 20363, 256, 31150, 
+    256, 37300, 256, 38584, 256, 24801, 256, 20102, 256, 20698, 256, 23534, 
+    256, 23615, 256, 26009, 256, 27138, 256, 29134, 256, 30274, 256, 34044, 
+    256, 36988, 256, 40845, 256, 26248, 256, 38446, 256, 21129, 256, 26491, 
+    256, 26611, 256, 27969, 256, 28316, 256, 29705, 256, 30041, 256, 30827, 
+    256, 32016, 256, 39006, 256, 20845, 256, 25134, 256, 38520, 256, 20523, 
+    256, 23833, 256, 28138, 256, 36650, 256, 24459, 256, 24900, 256, 26647, 
+    256, 29575, 256, 38534, 256, 21033, 256, 21519, 256, 23653, 256, 26131, 
+    256, 26446, 256, 26792, 256, 27877, 256, 29702, 256, 30178, 256, 32633, 
+    256, 35023, 256, 35041, 256, 37324, 256, 38626, 256, 21311, 256, 28346, 
+    256, 21533, 256, 29136, 256, 29848, 256, 34298, 256, 38563, 256, 40023, 
+    256, 40607, 256, 26519, 256, 28107, 256, 33256, 256, 31435, 256, 31520, 
+    256, 31890, 256, 29376, 256, 28825, 256, 35672, 256, 20160, 256, 33590, 
+    256, 21050, 256, 20999, 256, 24230, 256, 25299, 256, 31958, 256, 23429, 
+    256, 27934, 256, 26292, 256, 36667, 256, 34892, 256, 38477, 256, 35211, 
+    256, 24275, 256, 20800, 256, 21952, 256, 22618, 256, 26228, 256, 20958, 
+    256, 29482, 256, 30410, 256, 31036, 256, 31070, 256, 31077, 256, 31119, 
+    256, 38742, 256, 31934, 256, 32701, 256, 34322, 256, 35576, 256, 36920, 
+    256, 37117, 256, 39151, 256, 39164, 256, 39208, 256, 40372, 256, 20398, 
+    256, 20711, 256, 20813, 256, 21193, 256, 21220, 256, 21329, 256, 21917, 
+    256, 22022, 256, 22120, 256, 22592, 256, 22696, 256, 23652, 256, 23662, 
+    256, 24724, 256, 24936, 256, 24974, 256, 25074, 256, 25935, 256, 26082, 
+    256, 26257, 256, 26757, 256, 28023, 256, 28186, 256, 28450, 256, 29038, 
+    256, 29227, 256, 29730, 256, 30865, 256, 31038, 256, 31049, 256, 31048, 
+    256, 31056, 256, 31062, 256, 31069, 256, 31117, 256, 31118, 256, 31296, 
+    256, 31361, 256, 31680, 256, 32244, 256, 32265, 256, 32321, 256, 32626, 
+    256, 32773, 256, 33261, 256, 33401, 256, 33401, 256, 33879, 256, 35088, 
+    256, 35222, 256, 35585, 256, 35641, 256, 36051, 256, 36104, 256, 36790, 
+    256, 36920, 256, 38627, 256, 38911, 256, 38971, 256, 20006, 256, 20917, 
+    256, 20840, 256, 20352, 256, 20805, 256, 20864, 256, 21191, 256, 21242, 
+    256, 21917, 256, 21845, 256, 21913, 256, 21986, 256, 22618, 256, 22707, 
+    256, 22852, 256, 22868, 256, 23138, 256, 23336, 256, 24274, 256, 24281, 
+    256, 24425, 256, 24493, 256, 24792, 256, 24910, 256, 24840, 256, 24974, 
+    256, 24928, 256, 25074, 256, 25140, 256, 25540, 256, 25628, 256, 25682, 
+    256, 25942, 256, 26228, 256, 26391, 256, 26395, 256, 26454, 256, 27513, 
+    256, 27578, 256, 27969, 256, 28379, 256, 28363, 256, 28450, 256, 28702, 
+    256, 29038, 256, 30631, 256, 29237, 256, 29359, 256, 29482, 256, 29809, 
+    256, 29958, 256, 30011, 256, 30237, 256, 30239, 256, 30410, 256, 30427, 
+    256, 30452, 256, 30538, 256, 30528, 256, 30924, 256, 31409, 256, 31680, 
+    256, 31867, 256, 32091, 256, 32244, 256, 32574, 256, 32773, 256, 33618, 
+    256, 33775, 256, 34681, 256, 35137, 256, 35206, 256, 35222, 256, 35519, 
+    256, 35576, 256, 35531, 256, 35585, 256, 35582, 256, 35565, 256, 35641, 
+    256, 35722, 256, 36104, 256, 36664, 256, 36978, 256, 37273, 256, 37494, 
+    256, 38524, 256, 38627, 256, 38742, 256, 38875, 256, 38911, 256, 38923, 
+    256, 38971, 256, 39698, 256, 40860, 256, 141386, 256, 141380, 256, 
+    144341, 256, 15261, 256, 16408, 256, 16441, 256, 152137, 256, 154832, 
+    256, 163539, 256, 40771, 256, 40846, 514, 102, 102, 514, 102, 105, 514, 
+    102, 108, 770, 102, 102, 105, 770, 102, 102, 108, 514, 383, 116, 514, 
+    115, 116, 514, 1396, 1398, 514, 1396, 1381, 514, 1396, 1387, 514, 1406, 
+    1398, 514, 1396, 1389, 512, 1497, 1460, 512, 1522, 1463, 262, 1506, 262, 
+    1488, 262, 1491, 262, 1492, 262, 1499, 262, 1500, 262, 1501, 262, 1512, 
+    262, 1514, 262, 43, 512, 1513, 1473, 512, 1513, 1474, 512, 64329, 1473, 
+    512, 64329, 1474, 512, 1488, 1463, 512, 1488, 1464, 512, 1488, 1468, 512, 
+    1489, 1468, 512, 1490, 1468, 512, 1491, 1468, 512, 1492, 1468, 512, 1493, 
+    1468, 512, 1494, 1468, 512, 1496, 1468, 512, 1497, 1468, 512, 1498, 1468, 
+    512, 1499, 1468, 512, 1500, 1468, 512, 1502, 1468, 512, 1504, 1468, 512, 
+    1505, 1468, 512, 1507, 1468, 512, 1508, 1468, 512, 1510, 1468, 512, 1511, 
+    1468, 512, 1512, 1468, 512, 1513, 1468, 512, 1514, 1468, 512, 1493, 1465, 
+    512, 1489, 1471, 512, 1499, 1471, 512, 1508, 1471, 514, 1488, 1500, 267, 
+    1649, 268, 1649, 267, 1659, 268, 1659, 269, 1659, 270, 1659, 267, 1662, 
+    268, 1662, 269, 1662, 270, 1662, 267, 1664, 268, 1664, 269, 1664, 270, 
+    1664, 267, 1658, 268, 1658, 269, 1658, 270, 1658, 267, 1663, 268, 1663, 
+    269, 1663, 270, 1663, 267, 1657, 268, 1657, 269, 1657, 270, 1657, 267, 
+    1700, 268, 1700, 269, 1700, 270, 1700, 267, 1702, 268, 1702, 269, 1702, 
+    270, 1702, 267, 1668, 268, 1668, 269, 1668, 270, 1668, 267, 1667, 268, 
+    1667, 269, 1667, 270, 1667, 267, 1670, 268, 1670, 269, 1670, 270, 1670, 
+    267, 1671, 268, 1671, 269, 1671, 270, 1671, 267, 1677, 268, 1677, 267, 
+    1676, 268, 1676, 267, 1678, 268, 1678, 267, 1672, 268, 1672, 267, 1688, 
+    268, 1688, 267, 1681, 268, 1681, 267, 1705, 268, 1705, 269, 1705, 270, 
+    1705, 267, 1711, 268, 1711, 269, 1711, 270, 1711, 267, 1715, 268, 1715, 
+    269, 1715, 270, 1715, 267, 1713, 268, 1713, 269, 1713, 270, 1713, 267, 
+    1722, 268, 1722, 267, 1723, 268, 1723, 269, 1723, 270, 1723, 267, 1728, 
+    268, 1728, 267, 1729, 268, 1729, 269, 1729, 270, 1729, 267, 1726, 268, 
+    1726, 269, 1726, 270, 1726, 267, 1746, 268, 1746, 267, 1747, 268, 1747, 
+    267, 1709, 268, 1709, 269, 1709, 270, 1709, 267, 1735, 268, 1735, 267, 
+    1734, 268, 1734, 267, 1736, 268, 1736, 267, 1655, 267, 1739, 268, 1739, 
+    267, 1733, 268, 1733, 267, 1737, 268, 1737, 267, 1744, 268, 1744, 269, 
+    1744, 270, 1744, 269, 1609, 270, 1609, 523, 1574, 1575, 524, 1574, 1575, 
+    523, 1574, 1749, 524, 1574, 1749, 523, 1574, 1608, 524, 1574, 1608, 523, 
+    1574, 1735, 524, 1574, 1735, 523, 1574, 1734, 524, 1574, 1734, 523, 1574, 
+    1736, 524, 1574, 1736, 523, 1574, 1744, 524, 1574, 1744, 525, 1574, 1744, 
+    523, 1574, 1609, 524, 1574, 1609, 525, 1574, 1609, 267, 1740, 268, 1740, 
+    269, 1740, 270, 1740, 523, 1574, 1580, 523, 1574, 1581, 523, 1574, 1605, 
+    523, 1574, 1609, 523, 1574, 1610, 523, 1576, 1580, 523, 1576, 1581, 523, 
+    1576, 1582, 523, 1576, 1605, 523, 1576, 1609, 523, 1576, 1610, 523, 1578, 
+    1580, 523, 1578, 1581, 523, 1578, 1582, 523, 1578, 1605, 523, 1578, 1609, 
+    523, 1578, 1610, 523, 1579, 1580, 523, 1579, 1605, 523, 1579, 1609, 523, 
+    1579, 1610, 523, 1580, 1581, 523, 1580, 1605, 523, 1581, 1580, 523, 1581, 
+    1605, 523, 1582, 1580, 523, 1582, 1581, 523, 1582, 1605, 523, 1587, 1580, 
+    523, 1587, 1581, 523, 1587, 1582, 523, 1587, 1605, 523, 1589, 1581, 523, 
+    1589, 1605, 523, 1590, 1580, 523, 1590, 1581, 523, 1590, 1582, 523, 1590, 
+    1605, 523, 1591, 1581, 523, 1591, 1605, 523, 1592, 1605, 523, 1593, 1580, 
+    523, 1593, 1605, 523, 1594, 1580, 523, 1594, 1605, 523, 1601, 1580, 523, 
+    1601, 1581, 523, 1601, 1582, 523, 1601, 1605, 523, 1601, 1609, 523, 1601, 
+    1610, 523, 1602, 1581, 523, 1602, 1605, 523, 1602, 1609, 523, 1602, 1610, 
+    523, 1603, 1575, 523, 1603, 1580, 523, 1603, 1581, 523, 1603, 1582, 523, 
+    1603, 1604, 523, 1603, 1605, 523, 1603, 1609, 523, 1603, 1610, 523, 1604, 
+    1580, 523, 1604, 1581, 523, 1604, 1582, 523, 1604, 1605, 523, 1604, 1609, 
+    523, 1604, 1610, 523, 1605, 1580, 523, 1605, 1581, 523, 1605, 1582, 523, 
+    1605, 1605, 523, 1605, 1609, 523, 1605, 1610, 523, 1606, 1580, 523, 1606, 
+    1581, 523, 1606, 1582, 523, 1606, 1605, 523, 1606, 1609, 523, 1606, 1610, 
+    523, 1607, 1580, 523, 1607, 1605, 523, 1607, 1609, 523, 1607, 1610, 523, 
+    1610, 1580, 523, 1610, 1581, 523, 1610, 1582, 523, 1610, 1605, 523, 1610, 
+    1609, 523, 1610, 1610, 523, 1584, 1648, 523, 1585, 1648, 523, 1609, 1648, 
+    779, 32, 1612, 1617, 779, 32, 1613, 1617, 779, 32, 1614, 1617, 779, 32, 
+    1615, 1617, 779, 32, 1616, 1617, 779, 32, 1617, 1648, 524, 1574, 1585, 
+    524, 1574, 1586, 524, 1574, 1605, 524, 1574, 1606, 524, 1574, 1609, 524, 
+    1574, 1610, 524, 1576, 1585, 524, 1576, 1586, 524, 1576, 1605, 524, 1576, 
+    1606, 524, 1576, 1609, 524, 1576, 1610, 524, 1578, 1585, 524, 1578, 1586, 
+    524, 1578, 1605, 524, 1578, 1606, 524, 1578, 1609, 524, 1578, 1610, 524, 
+    1579, 1585, 524, 1579, 1586, 524, 1579, 1605, 524, 1579, 1606, 524, 1579, 
+    1609, 524, 1579, 1610, 524, 1601, 1609, 524, 1601, 1610, 524, 1602, 1609, 
+    524, 1602, 1610, 524, 1603, 1575, 524, 1603, 1604, 524, 1603, 1605, 524, 
+    1603, 1609, 524, 1603, 1610, 524, 1604, 1605, 524, 1604, 1609, 524, 1604, 
+    1610, 524, 1605, 1575, 524, 1605, 1605, 524, 1606, 1585, 524, 1606, 1586, 
+    524, 1606, 1605, 524, 1606, 1606, 524, 1606, 1609, 524, 1606, 1610, 524, 
+    1609, 1648, 524, 1610, 1585, 524, 1610, 1586, 524, 1610, 1605, 524, 1610, 
+    1606, 524, 1610, 1609, 524, 1610, 1610, 525, 1574, 1580, 525, 1574, 1581, 
+    525, 1574, 1582, 525, 1574, 1605, 525, 1574, 1607, 525, 1576, 1580, 525, 
+    1576, 1581, 525, 1576, 1582, 525, 1576, 1605, 525, 1576, 1607, 525, 1578, 
+    1580, 525, 1578, 1581, 525, 1578, 1582, 525, 1578, 1605, 525, 1578, 1607, 
+    525, 1579, 1605, 525, 1580, 1581, 525, 1580, 1605, 525, 1581, 1580, 525, 
+    1581, 1605, 525, 1582, 1580, 525, 1582, 1605, 525, 1587, 1580, 525, 1587, 
+    1581, 525, 1587, 1582, 525, 1587, 1605, 525, 1589, 1581, 525, 1589, 1582, 
+    525, 1589, 1605, 525, 1590, 1580, 525, 1590, 1581, 525, 1590, 1582, 525, 
+    1590, 1605, 525, 1591, 1581, 525, 1592, 1605, 525, 1593, 1580, 525, 1593, 
+    1605, 525, 1594, 1580, 525, 1594, 1605, 525, 1601, 1580, 525, 1601, 1581, 
+    525, 1601, 1582, 525, 1601, 1605, 525, 1602, 1581, 525, 1602, 1605, 525, 
+    1603, 1580, 525, 1603, 1581, 525, 1603, 1582, 525, 1603, 1604, 525, 1603, 
+    1605, 525, 1604, 1580, 525, 1604, 1581, 525, 1604, 1582, 525, 1604, 1605, 
+    525, 1604, 1607, 525, 1605, 1580, 525, 1605, 1581, 525, 1605, 1582, 525, 
+    1605, 1605, 525, 1606, 1580, 525, 1606, 1581, 525, 1606, 1582, 525, 1606, 
+    1605, 525, 1606, 1607, 525, 1607, 1580, 525, 1607, 1605, 525, 1607, 1648, 
+    525, 1610, 1580, 525, 1610, 1581, 525, 1610, 1582, 525, 1610, 1605, 525, 
+    1610, 1607, 526, 1574, 1605, 526, 1574, 1607, 526, 1576, 1605, 526, 1576, 
+    1607, 526, 1578, 1605, 526, 1578, 1607, 526, 1579, 1605, 526, 1579, 1607, 
+    526, 1587, 1605, 526, 1587, 1607, 526, 1588, 1605, 526, 1588, 1607, 526, 
+    1603, 1604, 526, 1603, 1605, 526, 1604, 1605, 526, 1606, 1605, 526, 1606, 
+    1607, 526, 1610, 1605, 526, 1610, 1607, 782, 1600, 1614, 1617, 782, 1600, 
+    1615, 1617, 782, 1600, 1616, 1617, 523, 1591, 1609, 523, 1591, 1610, 523, 
+    1593, 1609, 523, 1593, 1610, 523, 1594, 1609, 523, 1594, 1610, 523, 1587, 
+    1609, 523, 1587, 1610, 523, 1588, 1609, 523, 1588, 1610, 523, 1581, 1609, 
+    523, 1581, 1610, 523, 1580, 1609, 523, 1580, 1610, 523, 1582, 1609, 523, 
+    1582, 1610, 523, 1589, 1609, 523, 1589, 1610, 523, 1590, 1609, 523, 1590, 
+    1610, 523, 1588, 1580, 523, 1588, 1581, 523, 1588, 1582, 523, 1588, 1605, 
+    523, 1588, 1585, 523, 1587, 1585, 523, 1589, 1585, 523, 1590, 1585, 524, 
+    1591, 1609, 524, 1591, 1610, 524, 1593, 1609, 524, 1593, 1610, 524, 1594, 
+    1609, 524, 1594, 1610, 524, 1587, 1609, 524, 1587, 1610, 524, 1588, 1609, 
+    524, 1588, 1610, 524, 1581, 1609, 524, 1581, 1610, 524, 1580, 1609, 524, 
+    1580, 1610, 524, 1582, 1609, 524, 1582, 1610, 524, 1589, 1609, 524, 1589, 
+    1610, 524, 1590, 1609, 524, 1590, 1610, 524, 1588, 1580, 524, 1588, 1581, 
+    524, 1588, 1582, 524, 1588, 1605, 524, 1588, 1585, 524, 1587, 1585, 524, 
+    1589, 1585, 524, 1590, 1585, 525, 1588, 1580, 525, 1588, 1581, 525, 1588, 
+    1582, 525, 1588, 1605, 525, 1587, 1607, 525, 1588, 1607, 525, 1591, 1605, 
+    526, 1587, 1580, 526, 1587, 1581, 526, 1587, 1582, 526, 1588, 1580, 526, 
+    1588, 1581, 526, 1588, 1582, 526, 1591, 1605, 526, 1592, 1605, 524, 1575, 
+    1611, 523, 1575, 1611, 781, 1578, 1580, 1605, 780, 1578, 1581, 1580, 781, 
+    1578, 1581, 1580, 781, 1578, 1581, 1605, 781, 1578, 1582, 1605, 781, 
+    1578, 1605, 1580, 781, 1578, 1605, 1581, 781, 1578, 1605, 1582, 780, 
+    1580, 1605, 1581, 781, 1580, 1605, 1581, 780, 1581, 1605, 1610, 780, 
+    1581, 1605, 1609, 781, 1587, 1581, 1580, 781, 1587, 1580, 1581, 780, 
+    1587, 1580, 1609, 780, 1587, 1605, 1581, 781, 1587, 1605, 1581, 781, 
+    1587, 1605, 1580, 780, 1587, 1605, 1605, 781, 1587, 1605, 1605, 780, 
+    1589, 1581, 1581, 781, 1589, 1581, 1581, 780, 1589, 1605, 1605, 780, 
+    1588, 1581, 1605, 781, 1588, 1581, 1605, 780, 1588, 1580, 1610, 780, 
+    1588, 1605, 1582, 781, 1588, 1605, 1582, 780, 1588, 1605, 1605, 781, 
+    1588, 1605, 1605, 780, 1590, 1581, 1609, 780, 1590, 1582, 1605, 781, 
+    1590, 1582, 1605, 780, 1591, 1605, 1581, 781, 1591, 1605, 1581, 781, 
+    1591, 1605, 1605, 780, 1591, 1605, 1610, 780, 1593, 1580, 1605, 780, 
+    1593, 1605, 1605, 781, 1593, 1605, 1605, 780, 1593, 1605, 1609, 780, 
+    1594, 1605, 1605, 780, 1594, 1605, 1610, 780, 1594, 1605, 1609, 780, 
+    1601, 1582, 1605, 781, 1601, 1582, 1605, 780, 1602, 1605, 1581, 780, 
+    1602, 1605, 1605, 780, 1604, 1581, 1605, 780, 1604, 1581, 1610, 780, 
+    1604, 1581, 1609, 781, 1604, 1580, 1580, 780, 1604, 1580, 1580, 780, 
+    1604, 1582, 1605, 781, 1604, 1582, 1605, 780, 1604, 1605, 1581, 781, 
+    1604, 1605, 1581, 781, 1605, 1581, 1580, 781, 1605, 1581, 1605, 780, 
+    1605, 1581, 1610, 781, 1605, 1580, 1581, 781, 1605, 1580, 1605, 781, 
+    1605, 1582, 1580, 781, 1605, 1582, 1605, 781, 1605, 1580, 1582, 781, 
+    1607, 1605, 1580, 781, 1607, 1605, 1605, 781, 1606, 1581, 1605, 780, 
+    1606, 1581, 1609, 780, 1606, 1580, 1605, 781, 1606, 1580, 1605, 780, 
+    1606, 1580, 1609, 780, 1606, 1605, 1610, 780, 1606, 1605, 1609, 780, 
+    1610, 1605, 1605, 781, 1610, 1605, 1605, 780, 1576, 1582, 1610, 780, 
+    1578, 1580, 1610, 780, 1578, 1580, 1609, 780, 1578, 1582, 1610, 780, 
+    1578, 1582, 1609, 780, 1578, 1605, 1610, 780, 1578, 1605, 1609, 780, 
+    1580, 1605, 1610, 780, 1580, 1581, 1609, 780, 1580, 1605, 1609, 780, 
+    1587, 1582, 1609, 780, 1589, 1581, 1610, 780, 1588, 1581, 1610, 780, 
+    1590, 1581, 1610, 780, 1604, 1580, 1610, 780, 1604, 1605, 1610, 780, 
+    1610, 1581, 1610, 780, 1610, 1580, 1610, 780, 1610, 1605, 1610, 780, 
+    1605, 1605, 1610, 780, 1602, 1605, 1610, 780, 1606, 1581, 1610, 781, 
+    1602, 1605, 1581, 781, 1604, 1581, 1605, 780, 1593, 1605, 1610, 780, 
+    1603, 1605, 1610, 781, 1606, 1580, 1581, 780, 1605, 1582, 1610, 781, 
+    1604, 1580, 1605, 780, 1603, 1605, 1605, 780, 1604, 1580, 1605, 780, 
+    1606, 1580, 1581, 780, 1580, 1581, 1610, 780, 1581, 1580, 1610, 780, 
+    1605, 1580, 1610, 780, 1601, 1605, 1610, 780, 1576, 1581, 1610, 781, 
+    1603, 1605, 1605, 781, 1593, 1580, 1605, 781, 1589, 1605, 1605, 780, 
+    1587, 1582, 1610, 780, 1606, 1580, 1610, 779, 1589, 1604, 1746, 779, 
+    1602, 1604, 1746, 1035, 1575, 1604, 1604, 1607, 1035, 1575, 1603, 1576, 
+    1585, 1035, 1605, 1581, 1605, 1583, 1035, 1589, 1604, 1593, 1605, 1035, 
+    1585, 1587, 1608, 1604, 1035, 1593, 1604, 1610, 1607, 1035, 1608, 1587, 
+    1604, 1605, 779, 1589, 1604, 1609, 4619, 1589, 1604, 1609, 32, 1575, 
+    1604, 1604, 1607, 32, 1593, 1604, 1610, 1607, 32, 1608, 1587, 1604, 1605, 
+    2059, 1580, 1604, 32, 1580, 1604, 1575, 1604, 1607, 1035, 1585, 1740, 
+    1575, 1604, 265, 44, 265, 12289, 265, 12290, 265, 58, 265, 59, 265, 33, 
+    265, 63, 265, 12310, 265, 12311, 265, 8230, 265, 8229, 265, 8212, 265, 
+    8211, 265, 95, 265, 95, 265, 40, 265, 41, 265, 123, 265, 125, 265, 12308, 
+    265, 12309, 265, 12304, 265, 12305, 265, 12298, 265, 12299, 265, 12296, 
+    265, 12297, 265, 12300, 265, 12301, 265, 12302, 265, 12303, 265, 91, 265, 
+    93, 258, 8254, 258, 8254, 258, 8254, 258, 8254, 258, 95, 258, 95, 258, 
+    95, 271, 44, 271, 12289, 271, 46, 271, 59, 271, 58, 271, 63, 271, 33, 
+    271, 8212, 271, 40, 271, 41, 271, 123, 271, 125, 271, 12308, 271, 12309, 
+    271, 35, 271, 38, 271, 42, 271, 43, 271, 45, 271, 60, 271, 62, 271, 61, 
+    271, 92, 271, 36, 271, 37, 271, 64, 523, 32, 1611, 526, 1600, 1611, 523, 
+    32, 1612, 523, 32, 1613, 523, 32, 1614, 526, 1600, 1614, 523, 32, 1615, 
+    526, 1600, 1615, 523, 32, 1616, 526, 1600, 1616, 523, 32, 1617, 526, 
+    1600, 1617, 523, 32, 1618, 526, 1600, 1618, 267, 1569, 267, 1570, 268, 
+    1570, 267, 1571, 268, 1571, 267, 1572, 268, 1572, 267, 1573, 268, 1573, 
+    267, 1574, 268, 1574, 269, 1574, 270, 1574, 267, 1575, 268, 1575, 267, 
+    1576, 268, 1576, 269, 1576, 270, 1576, 267, 1577, 268, 1577, 267, 1578, 
+    268, 1578, 269, 1578, 270, 1578, 267, 1579, 268, 1579, 269, 1579, 270, 
+    1579, 267, 1580, 268, 1580, 269, 1580, 270, 1580, 267, 1581, 268, 1581, 
+    269, 1581, 270, 1581, 267, 1582, 268, 1582, 269, 1582, 270, 1582, 267, 
+    1583, 268, 1583, 267, 1584, 268, 1584, 267, 1585, 268, 1585, 267, 1586, 
+    268, 1586, 267, 1587, 268, 1587, 269, 1587, 270, 1587, 267, 1588, 268, 
+    1588, 269, 1588, 270, 1588, 267, 1589, 268, 1589, 269, 1589, 270, 1589, 
+    267, 1590, 268, 1590, 269, 1590, 270, 1590, 267, 1591, 268, 1591, 269, 
+    1591, 270, 1591, 267, 1592, 268, 1592, 269, 1592, 270, 1592, 267, 1593, 
+    268, 1593, 269, 1593, 270, 1593, 267, 1594, 268, 1594, 269, 1594, 270, 
+    1594, 267, 1601, 268, 1601, 269, 1601, 270, 1601, 267, 1602, 268, 1602, 
+    269, 1602, 270, 1602, 267, 1603, 268, 1603, 269, 1603, 270, 1603, 267, 
+    1604, 268, 1604, 269, 1604, 270, 1604, 267, 1605, 268, 1605, 269, 1605, 
+    270, 1605, 267, 1606, 268, 1606, 269, 1606, 270, 1606, 267, 1607, 268, 
+    1607, 269, 1607, 270, 1607, 267, 1608, 268, 1608, 267, 1609, 268, 1609, 
+    267, 1610, 268, 1610, 269, 1610, 270, 1610, 523, 1604, 1570, 524, 1604, 
+    1570, 523, 1604, 1571, 524, 1604, 1571, 523, 1604, 1573, 524, 1604, 1573, 
+    523, 1604, 1575, 524, 1604, 1575, 264, 33, 264, 34, 264, 35, 264, 36, 
+    264, 37, 264, 38, 264, 39, 264, 40, 264, 41, 264, 42, 264, 43, 264, 44, 
+    264, 45, 264, 46, 264, 47, 264, 48, 264, 49, 264, 50, 264, 51, 264, 52, 
+    264, 53, 264, 54, 264, 55, 264, 56, 264, 57, 264, 58, 264, 59, 264, 60, 
+    264, 61, 264, 62, 264, 63, 264, 64, 264, 65, 264, 66, 264, 67, 264, 68, 
+    264, 69, 264, 70, 264, 71, 264, 72, 264, 73, 264, 74, 264, 75, 264, 76, 
+    264, 77, 264, 78, 264, 79, 264, 80, 264, 81, 264, 82, 264, 83, 264, 84, 
+    264, 85, 264, 86, 264, 87, 264, 88, 264, 89, 264, 90, 264, 91, 264, 92, 
+    264, 93, 264, 94, 264, 95, 264, 96, 264, 97, 264, 98, 264, 99, 264, 100, 
+    264, 101, 264, 102, 264, 103, 264, 104, 264, 105, 264, 106, 264, 107, 
+    264, 108, 264, 109, 264, 110, 264, 111, 264, 112, 264, 113, 264, 114, 
+    264, 115, 264, 116, 264, 117, 264, 118, 264, 119, 264, 120, 264, 121, 
+    264, 122, 264, 123, 264, 124, 264, 125, 264, 126, 264, 10629, 264, 10630, 
+    272, 12290, 272, 12300, 272, 12301, 272, 12289, 272, 12539, 272, 12530, 
+    272, 12449, 272, 12451, 272, 12453, 272, 12455, 272, 12457, 272, 12515, 
+    272, 12517, 272, 12519, 272, 12483, 272, 12540, 272, 12450, 272, 12452, 
+    272, 12454, 272, 12456, 272, 12458, 272, 12459, 272, 12461, 272, 12463, 
+    272, 12465, 272, 12467, 272, 12469, 272, 12471, 272, 12473, 272, 12475, 
+    272, 12477, 272, 12479, 272, 12481, 272, 12484, 272, 12486, 272, 12488, 
+    272, 12490, 272, 12491, 272, 12492, 272, 12493, 272, 12494, 272, 12495, 
+    272, 12498, 272, 12501, 272, 12504, 272, 12507, 272, 12510, 272, 12511, 
+    272, 12512, 272, 12513, 272, 12514, 272, 12516, 272, 12518, 272, 12520, 
+    272, 12521, 272, 12522, 272, 12523, 272, 12524, 272, 12525, 272, 12527, 
+    272, 12531, 272, 12441, 272, 12442, 272, 12644, 272, 12593, 272, 12594, 
+    272, 12595, 272, 12596, 272, 12597, 272, 12598, 272, 12599, 272, 12600, 
+    272, 12601, 272, 12602, 272, 12603, 272, 12604, 272, 12605, 272, 12606, 
+    272, 12607, 272, 12608, 272, 12609, 272, 12610, 272, 12611, 272, 12612, 
+    272, 12613, 272, 12614, 272, 12615, 272, 12616, 272, 12617, 272, 12618, 
+    272, 12619, 272, 12620, 272, 12621, 272, 12622, 272, 12623, 272, 12624, 
+    272, 12625, 272, 12626, 272, 12627, 272, 12628, 272, 12629, 272, 12630, 
+    272, 12631, 272, 12632, 272, 12633, 272, 12634, 272, 12635, 272, 12636, 
+    272, 12637, 272, 12638, 272, 12639, 272, 12640, 272, 12641, 272, 12642, 
+    272, 12643, 264, 162, 264, 163, 264, 172, 264, 175, 264, 166, 264, 165, 
+    264, 8361, 272, 9474, 272, 8592, 272, 8593, 272, 8594, 272, 8595, 272, 
+    9632, 272, 9675, 512, 119127, 119141, 512, 119128, 119141, 512, 119135, 
+    119150, 512, 119135, 119151, 512, 119135, 119152, 512, 119135, 119153, 
+    512, 119135, 119154, 512, 119225, 119141, 512, 119226, 119141, 512, 
+    119227, 119150, 512, 119228, 119150, 512, 119227, 119151, 512, 119228, 
+    119151, 262, 65, 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, 262, 71, 
+    262, 72, 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, 
+    262, 80, 262, 81, 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 
+    262, 88, 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 
+    262, 102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, 262, 108, 
+    262, 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115, 
+    262, 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 122, 
+    262, 65, 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, 262, 71, 262, 72, 
+    262, 73, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, 262, 80, 
+    262, 81, 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, 
+    262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 262, 
+    102, 262, 103, 262, 105, 262, 106, 262, 107, 262, 108, 262, 109, 262, 
+    110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115, 262, 116, 262, 
+    117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 122, 262, 65, 262, 66, 
+    262, 67, 262, 68, 262, 69, 262, 70, 262, 71, 262, 72, 262, 73, 262, 74, 
+    262, 75, 262, 76, 262, 77, 262, 78, 262, 79, 262, 80, 262, 81, 262, 82, 
+    262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, 262, 90, 
+    262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 262, 102, 262, 103, 262, 
+    104, 262, 105, 262, 106, 262, 107, 262, 108, 262, 109, 262, 110, 262, 
+    111, 262, 112, 262, 113, 262, 114, 262, 115, 262, 116, 262, 117, 262, 
+    118, 262, 119, 262, 120, 262, 121, 262, 122, 262, 65, 262, 67, 262, 68, 
+    262, 71, 262, 74, 262, 75, 262, 78, 262, 79, 262, 80, 262, 81, 262, 83, 
+    262, 84, 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, 262, 90, 262, 97, 
+    262, 98, 262, 99, 262, 100, 262, 102, 262, 104, 262, 105, 262, 106, 262, 
+    107, 262, 108, 262, 109, 262, 110, 262, 112, 262, 113, 262, 114, 262, 
+    115, 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 
+    122, 262, 65, 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, 262, 71, 262, 
+    72, 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, 262, 
+    80, 262, 81, 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 
+    88, 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 262, 
+    102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, 262, 108, 262, 
+    109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115, 262, 
+    116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 122, 262, 65, 
+    262, 66, 262, 68, 262, 69, 262, 70, 262, 71, 262, 74, 262, 75, 262, 76, 
+    262, 77, 262, 78, 262, 79, 262, 80, 262, 81, 262, 83, 262, 84, 262, 85, 
+    262, 86, 262, 87, 262, 88, 262, 89, 262, 97, 262, 98, 262, 99, 262, 100, 
+    262, 101, 262, 102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, 
+    262, 108, 262, 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, 
+    262, 115, 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, 
+    262, 122, 262, 65, 262, 66, 262, 68, 262, 69, 262, 70, 262, 71, 262, 73, 
+    262, 74, 262, 75, 262, 76, 262, 77, 262, 79, 262, 83, 262, 84, 262, 85, 
+    262, 86, 262, 87, 262, 88, 262, 89, 262, 97, 262, 98, 262, 99, 262, 100, 
+    262, 101, 262, 102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, 
+    262, 108, 262, 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, 
+    262, 115, 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, 
+    262, 122, 262, 65, 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, 262, 71, 
+    262, 72, 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, 
+    262, 80, 262, 81, 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 
+    262, 88, 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 
+    262, 102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, 262, 108, 
+    262, 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115, 
+    262, 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 122, 
+    262, 65, 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, 262, 71, 262, 72, 
+    262, 73, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, 262, 80, 
+    262, 81, 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, 
+    262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 262, 
+    102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, 262, 108, 262, 
+    109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115, 262, 
+    116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 122, 262, 65, 
+    262, 66, 262, 67, 262, 68, 262, 69, 262, 70, 262, 71, 262, 72, 262, 73, 
+    262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, 262, 80, 262, 81, 
+    262, 82, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, 
+    262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 262, 102, 262, 
+    103, 262, 104, 262, 105, 262, 106, 262, 107, 262, 108, 262, 109, 262, 
+    110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115, 262, 116, 262, 
+    117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 122, 262, 65, 262, 66, 
+    262, 67, 262, 68, 262, 69, 262, 70, 262, 71, 262, 72, 262, 73, 262, 74, 
+    262, 75, 262, 76, 262, 77, 262, 78, 262, 79, 262, 80, 262, 81, 262, 82, 
+    262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, 262, 90, 
+    262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 262, 102, 262, 103, 262, 
+    104, 262, 105, 262, 106, 262, 107, 262, 108, 262, 109, 262, 110, 262, 
+    111, 262, 112, 262, 113, 262, 114, 262, 115, 262, 116, 262, 117, 262, 
+    118, 262, 119, 262, 120, 262, 121, 262, 122, 262, 65, 262, 66, 262, 67, 
+    262, 68, 262, 69, 262, 70, 262, 71, 262, 72, 262, 73, 262, 74, 262, 75, 
+    262, 76, 262, 77, 262, 78, 262, 79, 262, 80, 262, 81, 262, 82, 262, 83, 
+    262, 84, 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, 262, 90, 262, 97, 
+    262, 98, 262, 99, 262, 100, 262, 101, 262, 102, 262, 103, 262, 104, 262, 
+    105, 262, 106, 262, 107, 262, 108, 262, 109, 262, 110, 262, 111, 262, 
+    112, 262, 113, 262, 114, 262, 115, 262, 116, 262, 117, 262, 118, 262, 
+    119, 262, 120, 262, 121, 262, 122, 262, 65, 262, 66, 262, 67, 262, 68, 
+    262, 69, 262, 70, 262, 71, 262, 72, 262, 73, 262, 74, 262, 75, 262, 76, 
+    262, 77, 262, 78, 262, 79, 262, 80, 262, 81, 262, 82, 262, 83, 262, 84, 
+    262, 85, 262, 86, 262, 87, 262, 88, 262, 89, 262, 90, 262, 97, 262, 98, 
+    262, 99, 262, 100, 262, 101, 262, 102, 262, 103, 262, 104, 262, 105, 262, 
+    106, 262, 107, 262, 108, 262, 109, 262, 110, 262, 111, 262, 112, 262, 
+    113, 262, 114, 262, 115, 262, 116, 262, 117, 262, 118, 262, 119, 262, 
+    120, 262, 121, 262, 122, 262, 305, 262, 567, 262, 913, 262, 914, 262, 
+    915, 262, 916, 262, 917, 262, 918, 262, 919, 262, 920, 262, 921, 262, 
+    922, 262, 923, 262, 924, 262, 925, 262, 926, 262, 927, 262, 928, 262, 
+    929, 262, 1012, 262, 931, 262, 932, 262, 933, 262, 934, 262, 935, 262, 
+    936, 262, 937, 262, 8711, 262, 945, 262, 946, 262, 947, 262, 948, 262, 
+    949, 262, 950, 262, 951, 262, 952, 262, 953, 262, 954, 262, 955, 262, 
+    956, 262, 957, 262, 958, 262, 959, 262, 960, 262, 961, 262, 962, 262, 
+    963, 262, 964, 262, 965, 262, 966, 262, 967, 262, 968, 262, 969, 262, 
+    8706, 262, 1013, 262, 977, 262, 1008, 262, 981, 262, 1009, 262, 982, 262, 
+    913, 262, 914, 262, 915, 262, 916, 262, 917, 262, 918, 262, 919, 262, 
+    920, 262, 921, 262, 922, 262, 923, 262, 924, 262, 925, 262, 926, 262, 
+    927, 262, 928, 262, 929, 262, 1012, 262, 931, 262, 932, 262, 933, 262, 
+    934, 262, 935, 262, 936, 262, 937, 262, 8711, 262, 945, 262, 946, 262, 
+    947, 262, 948, 262, 949, 262, 950, 262, 951, 262, 952, 262, 953, 262, 
+    954, 262, 955, 262, 956, 262, 957, 262, 958, 262, 959, 262, 960, 262, 
+    961, 262, 962, 262, 963, 262, 964, 262, 965, 262, 966, 262, 967, 262, 
+    968, 262, 969, 262, 8706, 262, 1013, 262, 977, 262, 1008, 262, 981, 262, 
+    1009, 262, 982, 262, 913, 262, 914, 262, 915, 262, 916, 262, 917, 262, 
+    918, 262, 919, 262, 920, 262, 921, 262, 922, 262, 923, 262, 924, 262, 
+    925, 262, 926, 262, 927, 262, 928, 262, 929, 262, 1012, 262, 931, 262, 
+    932, 262, 933, 262, 934, 262, 935, 262, 936, 262, 937, 262, 8711, 262, 
+    945, 262, 946, 262, 947, 262, 948, 262, 949, 262, 950, 262, 951, 262, 
+    952, 262, 953, 262, 954, 262, 955, 262, 956, 262, 957, 262, 958, 262, 
+    959, 262, 960, 262, 961, 262, 962, 262, 963, 262, 964, 262, 965, 262, 
+    966, 262, 967, 262, 968, 262, 969, 262, 8706, 262, 1013, 262, 977, 262, 
+    1008, 262, 981, 262, 1009, 262, 982, 262, 913, 262, 914, 262, 915, 262, 
+    916, 262, 917, 262, 918, 262, 919, 262, 920, 262, 921, 262, 922, 262, 
+    923, 262, 924, 262, 925, 262, 926, 262, 927, 262, 928, 262, 929, 262, 
+    1012, 262, 931, 262, 932, 262, 933, 262, 934, 262, 935, 262, 936, 262, 
+    937, 262, 8711, 262, 945, 262, 946, 262, 947, 262, 948, 262, 949, 262, 
+    950, 262, 951, 262, 952, 262, 953, 262, 954, 262, 955, 262, 956, 262, 
+    957, 262, 958, 262, 959, 262, 960, 262, 961, 262, 962, 262, 963, 262, 
+    964, 262, 965, 262, 966, 262, 967, 262, 968, 262, 969, 262, 8706, 262, 
+    1013, 262, 977, 262, 1008, 262, 981, 262, 1009, 262, 982, 262, 913, 262, 
+    914, 262, 915, 262, 916, 262, 917, 262, 918, 262, 919, 262, 920, 262, 
+    921, 262, 922, 262, 923, 262, 924, 262, 925, 262, 926, 262, 927, 262, 
+    928, 262, 929, 262, 1012, 262, 931, 262, 932, 262, 933, 262, 934, 262, 
+    935, 262, 936, 262, 937, 262, 8711, 262, 945, 262, 946, 262, 947, 262, 
+    948, 262, 949, 262, 950, 262, 951, 262, 952, 262, 953, 262, 954, 262, 
+    955, 262, 956, 262, 957, 262, 958, 262, 959, 262, 960, 262, 961, 262, 
+    962, 262, 963, 262, 964, 262, 965, 262, 966, 262, 967, 262, 968, 262, 
+    969, 262, 8706, 262, 1013, 262, 977, 262, 1008, 262, 981, 262, 1009, 262, 
+    982, 262, 48, 262, 49, 262, 50, 262, 51, 262, 52, 262, 53, 262, 54, 262, 
+    55, 262, 56, 262, 57, 262, 48, 262, 49, 262, 50, 262, 51, 262, 52, 262, 
+    53, 262, 54, 262, 55, 262, 56, 262, 57, 262, 48, 262, 49, 262, 50, 262, 
+    51, 262, 52, 262, 53, 262, 54, 262, 55, 262, 56, 262, 57, 262, 48, 262, 
+    49, 262, 50, 262, 51, 262, 52, 262, 53, 262, 54, 262, 55, 262, 56, 262, 
+    57, 262, 48, 262, 49, 262, 50, 262, 51, 262, 52, 262, 53, 262, 54, 262, 
+    55, 262, 56, 262, 57, 256, 20029, 256, 20024, 256, 20033, 256, 131362, 
+    256, 20320, 256, 20398, 256, 20411, 256, 20482, 256, 20602, 256, 20633, 
+    256, 20711, 256, 20687, 256, 13470, 256, 132666, 256, 20813, 256, 20820, 
+    256, 20836, 256, 20855, 256, 132380, 256, 13497, 256, 20839, 256, 20877, 
+    256, 132427, 256, 20887, 256, 20900, 256, 20172, 256, 20908, 256, 20917, 
+    256, 168415, 256, 20981, 256, 20995, 256, 13535, 256, 21051, 256, 21062, 
+    256, 21106, 256, 21111, 256, 13589, 256, 21191, 256, 21193, 256, 21220, 
+    256, 21242, 256, 21253, 256, 21254, 256, 21271, 256, 21321, 256, 21329, 
+    256, 21338, 256, 21363, 256, 21373, 256, 21375, 256, 21375, 256, 21375, 
+    256, 133676, 256, 28784, 256, 21450, 256, 21471, 256, 133987, 256, 21483, 
+    256, 21489, 256, 21510, 256, 21662, 256, 21560, 256, 21576, 256, 21608, 
+    256, 21666, 256, 21750, 256, 21776, 256, 21843, 256, 21859, 256, 21892, 
+    256, 21892, 256, 21913, 256, 21931, 256, 21939, 256, 21954, 256, 22294, 
+    256, 22022, 256, 22295, 256, 22097, 256, 22132, 256, 20999, 256, 22766, 
+    256, 22478, 256, 22516, 256, 22541, 256, 22411, 256, 22578, 256, 22577, 
+    256, 22700, 256, 136420, 256, 22770, 256, 22775, 256, 22790, 256, 22810, 
+    256, 22818, 256, 22882, 256, 136872, 256, 136938, 256, 23020, 256, 23067, 
+    256, 23079, 256, 23000, 256, 23142, 256, 14062, 256, 14076, 256, 23304, 
+    256, 23358, 256, 23358, 256, 137672, 256, 23491, 256, 23512, 256, 23527, 
+    256, 23539, 256, 138008, 256, 23551, 256, 23558, 256, 24403, 256, 23586, 
+    256, 14209, 256, 23648, 256, 23662, 256, 23744, 256, 23693, 256, 138724, 
+    256, 23875, 256, 138726, 256, 23918, 256, 23915, 256, 23932, 256, 24033, 
+    256, 24034, 256, 14383, 256, 24061, 256, 24104, 256, 24125, 256, 24169, 
+    256, 14434, 256, 139651, 256, 14460, 256, 24240, 256, 24243, 256, 24246, 
+    256, 24266, 256, 172946, 256, 24318, 256, 140081, 256, 140081, 256, 
+    33281, 256, 24354, 256, 24354, 256, 14535, 256, 144056, 256, 156122, 256, 
+    24418, 256, 24427, 256, 14563, 256, 24474, 256, 24525, 256, 24535, 256, 
+    24569, 256, 24705, 256, 14650, 256, 14620, 256, 24724, 256, 141012, 256, 
+    24775, 256, 24904, 256, 24908, 256, 24910, 256, 24908, 256, 24954, 256, 
+    24974, 256, 25010, 256, 24996, 256, 25007, 256, 25054, 256, 25074, 256, 
+    25078, 256, 25104, 256, 25115, 256, 25181, 256, 25265, 256, 25300, 256, 
+    25424, 256, 142092, 256, 25405, 256, 25340, 256, 25448, 256, 25475, 256, 
+    25572, 256, 142321, 256, 25634, 256, 25541, 256, 25513, 256, 14894, 256, 
+    25705, 256, 25726, 256, 25757, 256, 25719, 256, 14956, 256, 25935, 256, 
+    25964, 256, 143370, 256, 26083, 256, 26360, 256, 26185, 256, 15129, 256, 
+    26257, 256, 15112, 256, 15076, 256, 20882, 256, 20885, 256, 26368, 256, 
+    26268, 256, 32941, 256, 17369, 256, 26391, 256, 26395, 256, 26401, 256, 
+    26462, 256, 26451, 256, 144323, 256, 15177, 256, 26618, 256, 26501, 256, 
+    26706, 256, 26757, 256, 144493, 256, 26766, 256, 26655, 256, 26900, 256, 
+    15261, 256, 26946, 256, 27043, 256, 27114, 256, 27304, 256, 145059, 256, 
+    27355, 256, 15384, 256, 27425, 256, 145575, 256, 27476, 256, 15438, 256, 
+    27506, 256, 27551, 256, 27578, 256, 27579, 256, 146061, 256, 138507, 256, 
+    146170, 256, 27726, 256, 146620, 256, 27839, 256, 27853, 256, 27751, 256, 
+    27926, 256, 27966, 256, 28023, 256, 27969, 256, 28009, 256, 28024, 256, 
+    28037, 256, 146718, 256, 27956, 256, 28207, 256, 28270, 256, 15667, 256, 
+    28363, 256, 28359, 256, 147153, 256, 28153, 256, 28526, 256, 147294, 256, 
+    147342, 256, 28614, 256, 28729, 256, 28702, 256, 28699, 256, 15766, 256, 
+    28746, 256, 28797, 256, 28791, 256, 28845, 256, 132389, 256, 28997, 256, 
+    148067, 256, 29084, 256, 148395, 256, 29224, 256, 29237, 256, 29264, 256, 
+    149000, 256, 29312, 256, 29333, 256, 149301, 256, 149524, 256, 29562, 
+    256, 29579, 256, 16044, 256, 29605, 256, 16056, 256, 16056, 256, 29767, 
+    256, 29788, 256, 29809, 256, 29829, 256, 29898, 256, 16155, 256, 29988, 
+    256, 150582, 256, 30014, 256, 150674, 256, 30064, 256, 139679, 256, 
+    30224, 256, 151457, 256, 151480, 256, 151620, 256, 16380, 256, 16392, 
+    256, 30452, 256, 151795, 256, 151794, 256, 151833, 256, 151859, 256, 
+    30494, 256, 30495, 256, 30495, 256, 30538, 256, 16441, 256, 30603, 256, 
+    16454, 256, 16534, 256, 152605, 256, 30798, 256, 30860, 256, 30924, 256, 
+    16611, 256, 153126, 256, 31062, 256, 153242, 256, 153285, 256, 31119, 
+    256, 31211, 256, 16687, 256, 31296, 256, 31306, 256, 31311, 256, 153980, 
+    256, 154279, 256, 154279, 256, 31470, 256, 16898, 256, 154539, 256, 
+    31686, 256, 31689, 256, 16935, 256, 154752, 256, 31954, 256, 17056, 256, 
+    31976, 256, 31971, 256, 32000, 256, 155526, 256, 32099, 256, 17153, 256, 
+    32199, 256, 32258, 256, 32325, 256, 17204, 256, 156200, 256, 156231, 256, 
+    17241, 256, 156377, 256, 32634, 256, 156478, 256, 32661, 256, 32762, 256, 
+    32773, 256, 156890, 256, 156963, 256, 32864, 256, 157096, 256, 32880, 
+    256, 144223, 256, 17365, 256, 32946, 256, 33027, 256, 17419, 256, 33086, 
+    256, 23221, 256, 157607, 256, 157621, 256, 144275, 256, 144284, 256, 
+    33281, 256, 33284, 256, 36766, 256, 17515, 256, 33425, 256, 33419, 256, 
+    33437, 256, 21171, 256, 33457, 256, 33459, 256, 33469, 256, 33510, 256, 
+    158524, 256, 33509, 256, 33565, 256, 33635, 256, 33709, 256, 33571, 256, 
+    33725, 256, 33767, 256, 33879, 256, 33619, 256, 33738, 256, 33740, 256, 
+    33756, 256, 158774, 256, 159083, 256, 158933, 256, 17707, 256, 34033, 
+    256, 34035, 256, 34070, 256, 160714, 256, 34148, 256, 159532, 256, 17757, 
+    256, 17761, 256, 159665, 256, 159954, 256, 17771, 256, 34384, 256, 34396, 
+    256, 34407, 256, 34409, 256, 34473, 256, 34440, 256, 34574, 256, 34530, 
+    256, 34681, 256, 34600, 256, 34667, 256, 34694, 256, 17879, 256, 34785, 
+    256, 34817, 256, 17913, 256, 34912, 256, 34915, 256, 161383, 256, 35031, 
+    256, 35038, 256, 17973, 256, 35066, 256, 13499, 256, 161966, 256, 162150, 
+    256, 18110, 256, 18119, 256, 35488, 256, 35565, 256, 35722, 256, 35925, 
+    256, 162984, 256, 36011, 256, 36033, 256, 36123, 256, 36215, 256, 163631, 
+    256, 133124, 256, 36299, 256, 36284, 256, 36336, 256, 133342, 256, 36564, 
+    256, 36664, 256, 165330, 256, 165357, 256, 37012, 256, 37105, 256, 37137, 
+    256, 165678, 256, 37147, 256, 37432, 256, 37591, 256, 37592, 256, 37500, 
+    256, 37881, 256, 37909, 256, 166906, 256, 38283, 256, 18837, 256, 38327, 
+    256, 167287, 256, 18918, 256, 38595, 256, 23986, 256, 38691, 256, 168261, 
+    256, 168474, 256, 19054, 256, 19062, 256, 38880, 256, 168970, 256, 19122, 
+    256, 169110, 256, 38923, 256, 38923, 256, 38953, 256, 169398, 256, 39138, 
+    256, 19251, 256, 39209, 256, 39335, 256, 39362, 256, 39422, 256, 19406, 
+    256, 170800, 256, 39698, 256, 40000, 256, 40189, 256, 19662, 256, 19693, 
+    256, 40295, 256, 172238, 256, 19704, 256, 172293, 256, 172558, 256, 
+    172689, 256, 40635, 256, 19798, 256, 40697, 256, 40702, 256, 40709, 256, 
+    40719, 256, 40726, 256, 40763, 256, 173568, 
+};
+
+/* index tables for the decomposition data */
+#define DECOMP_SHIFT 8
+static unsigned char decomp_index1[] = {
+    0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 9, 10, 11, 12, 13, 14, 15, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 16, 17, 18, 19, 20, 21, 22, 23, 7, 7, 7, 7, 7, 24, 
+    7, 7, 25, 26, 27, 28, 29, 30, 31, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 32, 33, 34, 35, 36, 37, 
+    38, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 39, 7, 7, 40, 41, 
+    42, 43, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 44, 45, 46, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+};
+
+static unsigned short decomp_index2[] = {
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 
+    3, 0, 6, 0, 0, 0, 0, 8, 0, 0, 11, 13, 15, 18, 0, 0, 20, 23, 25, 0, 27, 
+    31, 35, 0, 39, 42, 45, 48, 51, 54, 0, 57, 60, 63, 66, 69, 72, 75, 78, 81, 
+    0, 84, 87, 90, 93, 96, 99, 0, 0, 102, 105, 108, 111, 114, 0, 0, 117, 120, 
+    123, 126, 129, 132, 0, 135, 138, 141, 144, 147, 150, 153, 156, 159, 0, 
+    162, 165, 168, 171, 174, 177, 0, 0, 180, 183, 186, 189, 192, 0, 195, 198, 
+    201, 204, 207, 210, 213, 216, 219, 222, 225, 228, 231, 234, 237, 240, 
+    243, 0, 0, 246, 249, 252, 255, 258, 261, 264, 267, 270, 273, 276, 279, 
+    282, 285, 288, 291, 294, 297, 300, 303, 0, 0, 306, 309, 312, 315, 318, 
+    321, 324, 327, 330, 0, 333, 336, 339, 342, 345, 348, 0, 351, 354, 357, 
+    360, 363, 366, 369, 372, 0, 0, 375, 378, 381, 384, 387, 390, 393, 0, 0, 
+    396, 399, 402, 405, 408, 411, 0, 0, 414, 417, 420, 423, 426, 429, 432, 
+    435, 438, 441, 444, 447, 450, 453, 456, 459, 462, 465, 0, 0, 468, 471, 
+    474, 477, 480, 483, 486, 489, 492, 495, 498, 501, 504, 507, 510, 513, 
+    516, 519, 522, 525, 528, 531, 534, 537, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 539, 542, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 545, 548, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 551, 554, 557, 560, 563, 566, 569, 572, 
+    575, 578, 581, 584, 587, 590, 593, 596, 599, 602, 605, 608, 611, 614, 
+    617, 620, 623, 0, 626, 629, 632, 635, 638, 641, 0, 0, 644, 647, 650, 653, 
+    656, 659, 662, 665, 668, 671, 674, 677, 680, 683, 686, 689, 0, 0, 692, 
+    695, 698, 701, 704, 707, 710, 713, 716, 719, 722, 725, 728, 731, 734, 
+    737, 740, 743, 746, 749, 752, 755, 758, 761, 764, 767, 770, 773, 776, 
+    779, 782, 785, 788, 791, 794, 797, 0, 0, 800, 803, 0, 0, 0, 0, 0, 0, 806, 
+    809, 812, 815, 818, 821, 824, 827, 830, 833, 836, 839, 842, 845, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 848, 850, 852, 854, 856, 858, 860, 862, 864, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 866, 
+    869, 872, 875, 878, 881, 0, 0, 884, 886, 888, 890, 892, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 894, 896, 0, 898, 900, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 903, 0, 0, 0, 0, 
+    0, 905, 0, 0, 0, 908, 0, 0, 0, 0, 0, 910, 913, 916, 919, 921, 924, 927, 
+    0, 930, 0, 933, 936, 939, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 942, 945, 948, 951, 954, 957, 960, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 963, 966, 
+    969, 972, 975, 0, 978, 980, 982, 984, 987, 990, 992, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 994, 996, 998, 0, 
+    1000, 1002, 0, 0, 0, 1004, 0, 0, 0, 0, 0, 0, 1006, 1009, 0, 1012, 0, 0, 
+    0, 1015, 0, 0, 0, 0, 1018, 1021, 1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    1027, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 1030, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 1033, 1036, 0, 1039, 0, 0, 0, 1042, 0, 0, 0, 
+    0, 1045, 1048, 1051, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 1054, 1057, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1060, 1063, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 1066, 1069, 1072, 1075, 0, 0, 1078, 1081, 0, 0, 1084, 1087, 
+    1090, 1093, 1096, 1099, 0, 0, 1102, 1105, 1108, 1111, 1114, 1117, 0, 0, 
+    1120, 1123, 1126, 1129, 1132, 1135, 1138, 1141, 1144, 1147, 1150, 1153, 
+    0, 0, 1156, 1159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 1162, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1165, 1168, 1171, 1174, 
+    1177, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 1180, 1183, 1186, 1189, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1192, 0, 1195, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1198, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1201, 0, 0, 0, 
+    0, 0, 0, 0, 1204, 0, 0, 1207, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1210, 
+    1213, 1216, 1219, 1222, 1225, 1228, 1231, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 1234, 1237, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1240, 1243, 
+    0, 1246, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1249, 0, 0, 1252, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 1255, 1258, 1261, 0, 0, 1264, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 1267, 0, 0, 1270, 1273, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 1276, 1279, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1282, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 1285, 1288, 1291, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1294, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1297, 0, 0, 0, 0, 0, 0, 1300, 1303, 0, 
+    1306, 1309, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1312, 1315, 1318, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1321, 0, 1324, 1327, 1330, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1333, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1336, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1339, 1342, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1345, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    1347, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1350, 0, 0, 0, 0, 1353, 0, 0, 0, 0, 
+    1356, 0, 0, 0, 0, 1359, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1362, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 1365, 0, 1368, 1371, 1374, 1377, 1380, 0, 0, 0, 0, 
+    0, 0, 0, 1383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1386, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 1389, 0, 0, 0, 0, 1392, 0, 0, 0, 0, 1395, 0, 
+    0, 0, 0, 1398, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1401, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 1404, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 1407, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 1409, 1411, 1413, 0, 1415, 1417, 1419, 1421, 1423, 
+    1425, 1427, 1429, 1431, 1433, 1435, 0, 1437, 1439, 1441, 1443, 1445, 
+    1447, 1449, 1451, 1453, 1455, 1457, 1459, 1461, 1463, 1465, 1467, 1469, 
+    1471, 0, 1473, 1475, 1477, 1479, 1481, 1483, 1485, 1487, 1489, 1491, 
+    1493, 1495, 1497, 1499, 1501, 1503, 1505, 1507, 1509, 1511, 1513, 1515, 
+    1517, 1519, 1521, 1523, 1525, 1527, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 1529, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1531, 1533, 1535, 1537, 1539, 
+    1541, 1543, 1545, 1547, 1549, 1551, 1553, 1555, 1557, 1559, 1561, 1563, 
+    1565, 1567, 1569, 1571, 1573, 1575, 1577, 1579, 1581, 1583, 1585, 1587, 
+    1589, 1591, 1593, 1595, 1597, 1599, 1601, 1603, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 1605, 1608, 1611, 1614, 1617, 1620, 1623, 1626, 
+    1629, 1632, 1635, 1638, 1641, 1644, 1647, 1650, 1653, 1656, 1659, 1662, 
+    1665, 1668, 1671, 1674, 1677, 1680, 1683, 1686, 1689, 1692, 1695, 1698, 
+    1701, 1704, 1707, 1710, 1713, 1716, 1719, 1722, 1725, 1728, 1731, 1734, 
+    1737, 1740, 1743, 1746, 1749, 1752, 1755, 1758, 1761, 1764, 1767, 1770, 
+    1773, 1776, 1779, 1782, 1785, 1788, 1791, 1794, 1797, 1800, 1803, 1806, 
+    1809, 1812, 1815, 1818, 1821, 1824, 1827, 1830, 1833, 1836, 1839, 1842, 
+    1845, 1848, 1851, 1854, 1857, 1860, 1863, 1866, 1869, 1872, 1875, 1878, 
+    1881, 1884, 1887, 1890, 1893, 1896, 1899, 1902, 1905, 1908, 1911, 1914, 
+    1917, 1920, 1923, 1926, 1929, 1932, 1935, 1938, 1941, 1944, 1947, 1950, 
+    1953, 1956, 1959, 1962, 1965, 1968, 1971, 1974, 1977, 1980, 1983, 1986, 
+    1989, 1992, 1995, 1998, 2001, 2004, 2007, 2010, 2013, 2016, 2019, 2022, 
+    2025, 2028, 2031, 2034, 2037, 2040, 2043, 2046, 2049, 2052, 2055, 2058, 
+    2061, 2064, 2067, 2070, 0, 0, 0, 0, 2073, 2076, 2079, 2082, 2085, 2088, 
+    2091, 2094, 2097, 2100, 2103, 2106, 2109, 2112, 2115, 2118, 2121, 2124, 
+    2127, 2130, 2133, 2136, 2139, 2142, 2145, 2148, 2151, 2154, 2157, 2160, 
+    2163, 2166, 2169, 2172, 2175, 2178, 2181, 2184, 2187, 2190, 2193, 2196, 
+    2199, 2202, 2205, 2208, 2211, 2214, 2217, 2220, 2223, 2226, 2229, 2232, 
+    2235, 2238, 2241, 2244, 2247, 2250, 2253, 2256, 2259, 2262, 2265, 2268, 
+    2271, 2274, 2277, 2280, 2283, 2286, 2289, 2292, 2295, 2298, 2301, 2304, 
+    2307, 2310, 2313, 2316, 2319, 2322, 2325, 2328, 2331, 2334, 2337, 2340, 
+    0, 0, 0, 0, 0, 0, 2343, 2346, 2349, 2352, 2355, 2358, 2361, 2364, 2367, 
+    2370, 2373, 2376, 2379, 2382, 2385, 2388, 2391, 2394, 2397, 2400, 2403, 
+    2406, 0, 0, 2409, 2412, 2415, 2418, 2421, 2424, 0, 0, 2427, 2430, 2433, 
+    2436, 2439, 2442, 2445, 2448, 2451, 2454, 2457, 2460, 2463, 2466, 2469, 
+    2472, 2475, 2478, 2481, 2484, 2487, 2490, 2493, 2496, 2499, 2502, 2505, 
+    2508, 2511, 2514, 2517, 2520, 2523, 2526, 2529, 2532, 2535, 2538, 0, 0, 
+    2541, 2544, 2547, 2550, 2553, 2556, 0, 0, 2559, 2562, 2565, 2568, 2571, 
+    2574, 2577, 2580, 0, 2583, 0, 2586, 0, 2589, 0, 2592, 2595, 2598, 2601, 
+    2604, 2607, 2610, 2613, 2616, 2619, 2622, 2625, 2628, 2631, 2634, 2637, 
+    2640, 2643, 2646, 2648, 2651, 2653, 2656, 2658, 2661, 2663, 2666, 2668, 
+    2671, 2673, 2676, 0, 0, 2678, 2681, 2684, 2687, 2690, 2693, 2696, 2699, 
+    2702, 2705, 2708, 2711, 2714, 2717, 2720, 2723, 2726, 2729, 2732, 2735, 
+    2738, 2741, 2744, 2747, 2750, 2753, 2756, 2759, 2762, 2765, 2768, 2771, 
+    2774, 2777, 2780, 2783, 2786, 2789, 2792, 2795, 2798, 2801, 2804, 2807, 
+    2810, 2813, 2816, 2819, 2822, 2825, 2828, 2831, 2834, 0, 2837, 2840, 
+    2843, 2846, 2849, 2852, 2854, 2857, 2860, 2862, 2865, 2868, 2871, 2874, 
+    2877, 0, 2880, 2883, 2886, 2889, 2891, 2894, 2896, 2899, 2902, 2905, 
+    2908, 2911, 2914, 2917, 0, 0, 2919, 2922, 2925, 2928, 2931, 2934, 0, 
+    2936, 2939, 2942, 2945, 2948, 2951, 2954, 2956, 2959, 2962, 2965, 2968, 
+    2971, 2974, 2977, 2979, 2982, 2985, 2987, 0, 0, 2989, 2992, 2995, 0, 
+    2998, 3001, 3004, 3007, 3009, 3012, 3014, 3017, 3019, 0, 3022, 3024, 
+    3026, 3028, 3030, 3032, 3034, 3036, 3038, 3040, 3042, 0, 0, 0, 0, 0, 0, 
+    3044, 0, 0, 0, 0, 0, 3046, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3049, 
+    3051, 3054, 0, 0, 0, 0, 0, 0, 0, 0, 3058, 0, 0, 0, 3060, 3063, 0, 3067, 
+    3070, 0, 0, 0, 0, 3074, 0, 3077, 0, 0, 0, 0, 0, 0, 0, 0, 3080, 3083, 
+    3086, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3089, 0, 0, 0, 0, 0, 0, 0, 
+    3094, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3096, 3098, 0, 0, 
+    3100, 3102, 3104, 3106, 3108, 3110, 3112, 3114, 3116, 3118, 3120, 3122, 
+    3124, 3126, 3128, 3130, 3132, 3134, 3136, 3138, 3140, 3142, 3144, 3146, 
+    3148, 3150, 3152, 0, 3154, 3156, 3158, 3160, 3162, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3164, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 3167, 3171, 3175, 3177, 0, 3180, 3184, 3188, 0, 3190, 
+    3193, 3195, 3197, 3199, 3201, 3203, 3205, 3207, 3209, 3211, 0, 3213, 
+    3215, 0, 0, 3218, 3220, 3222, 3224, 3226, 0, 0, 3228, 3231, 3235, 0, 
+    3238, 0, 3240, 0, 3242, 0, 3244, 3246, 3248, 3250, 0, 3252, 3254, 3256, 
+    0, 3258, 3260, 3262, 3264, 3266, 3268, 3270, 0, 3272, 3276, 3278, 3280, 
+    3282, 3284, 0, 0, 0, 0, 3286, 3288, 3290, 3292, 3294, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 3296, 3300, 3304, 3308, 3312, 3316, 3320, 3324, 3328, 3332, 
+    3336, 3340, 3344, 3347, 3349, 3352, 3356, 3359, 3361, 3364, 3368, 3373, 
+    3376, 3378, 3381, 3385, 3387, 3389, 3391, 3393, 3395, 3398, 3402, 3405, 
+    3407, 3410, 3414, 3419, 3422, 3424, 3427, 3431, 3433, 3435, 3437, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    3439, 3442, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3445, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 3448, 3451, 3454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3457, 0, 0, 0, 0, 3460, 
+    0, 0, 3463, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 3466, 0, 3469, 0, 0, 0, 0, 0, 3472, 3475, 0, 3479, 3482, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3486, 0, 0, 3489, 0, 0, 3492, 
+    0, 3495, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 3498, 0, 3501, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3504, 3507, 3510, 3513, 
+    3516, 0, 0, 3519, 3522, 0, 0, 3525, 3528, 0, 0, 0, 0, 0, 0, 3531, 3534, 
+    0, 0, 3537, 3540, 0, 0, 3543, 3546, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3549, 
+    3552, 3555, 3558, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 3561, 3564, 3567, 3570, 0, 0, 0, 0, 0, 0, 3573, 3576, 
+    3579, 3582, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3585, 3587, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3589, 3591, 3593, 3595, 
+    3597, 3599, 3601, 3603, 3605, 3607, 3610, 3613, 3616, 3619, 3622, 3625, 
+    3628, 3631, 3634, 3637, 3640, 3644, 3648, 3652, 3656, 3660, 3664, 3668, 
+    3672, 3676, 3681, 3686, 3691, 3696, 3701, 3706, 3711, 3716, 3721, 3726, 
+    3731, 3734, 3737, 3740, 3743, 3746, 3749, 3752, 3755, 3758, 3762, 3766, 
+    3770, 3774, 3778, 3782, 3786, 3790, 3794, 3798, 3802, 3806, 3810, 3814, 
+    3818, 3822, 3826, 3830, 3834, 3838, 3842, 3846, 3850, 3854, 3858, 3862, 
+    3866, 3870, 3874, 3878, 3882, 3886, 3890, 3894, 3898, 3902, 3906, 3908, 
+    3910, 3912, 3914, 3916, 3918, 3920, 3922, 3924, 3926, 3928, 3930, 3932, 
+    3934, 3936, 3938, 3940, 3942, 3944, 3946, 3948, 3950, 3952, 3954, 3956, 
+    3958, 3960, 3962, 3964, 3966, 3968, 3970, 3972, 3974, 3976, 3978, 3980, 
+    3982, 3984, 3986, 3988, 3990, 3992, 3994, 3996, 3998, 4000, 4002, 4004, 
+    4006, 4008, 4010, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4012, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    4017, 4021, 4024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4028, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4031, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 4033, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4035, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4037, 4039, 4041, 4043, 4045, 4047, 
+    4049, 4051, 4053, 4055, 4057, 4059, 4061, 4063, 4065, 4067, 4069, 4071, 
+    4073, 4075, 4077, 4079, 4081, 4083, 4085, 4087, 4089, 4091, 4093, 4095, 
+    4097, 4099, 4101, 4103, 4105, 4107, 4109, 4111, 4113, 4115, 4117, 4119, 
+    4121, 4123, 4125, 4127, 4129, 4131, 4133, 4135, 4137, 4139, 4141, 4143, 
+    4145, 4147, 4149, 4151, 4153, 4155, 4157, 4159, 4161, 4163, 4165, 4167, 
+    4169, 4171, 4173, 4175, 4177, 4179, 4181, 4183, 4185, 4187, 4189, 4191, 
+    4193, 4195, 4197, 4199, 4201, 4203, 4205, 4207, 4209, 4211, 4213, 4215, 
+    4217, 4219, 4221, 4223, 4225, 4227, 4229, 4231, 4233, 4235, 4237, 4239, 
+    4241, 4243, 4245, 4247, 4249, 4251, 4253, 4255, 4257, 4259, 4261, 4263, 
+    4265, 4267, 4269, 4271, 4273, 4275, 4277, 4279, 4281, 4283, 4285, 4287, 
+    4289, 4291, 4293, 4295, 4297, 4299, 4301, 4303, 4305, 4307, 4309, 4311, 
+    4313, 4315, 4317, 4319, 4321, 4323, 4325, 4327, 4329, 4331, 4333, 4335, 
+    4337, 4339, 4341, 4343, 4345, 4347, 4349, 4351, 4353, 4355, 4357, 4359, 
+    4361, 4363, 4365, 4367, 4369, 4371, 4373, 4375, 4377, 4379, 4381, 4383, 
+    4385, 4387, 4389, 4391, 4393, 4395, 4397, 4399, 4401, 4403, 4405, 4407, 
+    4409, 4411, 4413, 4415, 4417, 4419, 4421, 4423, 4425, 4427, 4429, 4431, 
+    4433, 4435, 4437, 4439, 4441, 4443, 4445, 4447, 4449, 4451, 4453, 4455, 
+    4457, 4459, 4461, 4463, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 4465, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 4467, 0, 4469, 4471, 4473, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4475, 0, 4478, 0, 4481, 0, 4484, 0, 
+    4487, 0, 4490, 0, 4493, 0, 4496, 0, 4499, 0, 4502, 0, 4505, 0, 4508, 0, 
+    0, 4511, 0, 4514, 0, 4517, 0, 0, 0, 0, 0, 0, 4520, 4523, 0, 4526, 4529, 
+    0, 4532, 4535, 0, 4538, 4541, 0, 4544, 4547, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4550, 0, 0, 0, 0, 0, 0, 4553, 
+    4556, 0, 4559, 4562, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4565, 0, 4568, 
+    0, 4571, 0, 4574, 0, 4577, 0, 4580, 0, 4583, 0, 4586, 0, 4589, 0, 4592, 
+    0, 4595, 0, 4598, 0, 0, 4601, 0, 4604, 0, 4607, 0, 0, 0, 0, 0, 0, 4610, 
+    4613, 0, 4616, 4619, 0, 4622, 4625, 0, 4628, 4631, 0, 4634, 4637, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4640, 0, 0, 
+    4643, 4646, 4649, 4652, 0, 0, 0, 4655, 4658, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4661, 4663, 4665, 4667, 
+    4669, 4671, 4673, 4675, 4677, 4679, 4681, 4683, 4685, 4687, 4689, 4691, 
+    4693, 4695, 4697, 4699, 4701, 4703, 4705, 4707, 4709, 4711, 4713, 4715, 
+    4717, 4719, 4721, 4723, 4725, 4727, 4729, 4731, 4733, 4735, 4737, 4739, 
+    4741, 4743, 4745, 4747, 4749, 4751, 4753, 4755, 4757, 4759, 4761, 4763, 
+    4765, 4767, 4769, 4771, 4773, 4775, 4777, 4779, 4781, 4783, 4785, 4787, 
+    4789, 4791, 4793, 4795, 4797, 4799, 4801, 4803, 4805, 4807, 4809, 4811, 
+    4813, 4815, 4817, 4819, 4821, 4823, 4825, 4827, 4829, 4831, 4833, 4835, 
+    4837, 4839, 4841, 4843, 4845, 4847, 0, 0, 0, 4849, 4851, 4853, 4855, 
+    4857, 4859, 4861, 4863, 4865, 4867, 4869, 4871, 4873, 4875, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4877, 4881, 
+    4885, 4889, 4893, 4897, 4901, 4905, 4909, 4913, 4917, 4921, 4925, 4929, 
+    4933, 4938, 4943, 4948, 4953, 4958, 4963, 4968, 4973, 4978, 4983, 4988, 
+    4993, 4998, 5003, 5008, 5016, 0, 5023, 5027, 5031, 5035, 5039, 5043, 
+    5047, 5051, 5055, 5059, 5063, 5067, 5071, 5075, 5079, 5083, 5087, 5091, 
+    5095, 5099, 5103, 5107, 5111, 5115, 5119, 5123, 5127, 5131, 5135, 5139, 
+    5143, 5147, 5151, 5155, 5159, 5163, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    5167, 5171, 5174, 5177, 5180, 5183, 5186, 5189, 5192, 5195, 5198, 5201, 
+    5204, 5207, 5210, 5213, 5216, 5218, 5220, 5222, 5224, 5226, 5228, 5230, 
+    5232, 5234, 5236, 5238, 5240, 5242, 5244, 5247, 5250, 5253, 5256, 5259, 
+    5262, 5265, 5268, 5271, 5274, 5277, 5280, 5283, 5286, 5292, 5297, 0, 
+    5300, 5302, 5304, 5306, 5308, 5310, 5312, 5314, 5316, 5318, 5320, 5322, 
+    5324, 5326, 5328, 5330, 5332, 5334, 5336, 5338, 5340, 5342, 5344, 5346, 
+    5348, 5350, 5352, 5354, 5356, 5358, 5360, 5362, 5364, 5366, 5368, 5370, 
+    5372, 5374, 5376, 5378, 5380, 5382, 5384, 5386, 5388, 5390, 5392, 5394, 
+    5396, 5398, 5401, 5404, 5407, 5410, 5413, 5416, 5419, 5422, 5425, 5428, 
+    5431, 5434, 5437, 5440, 5443, 5446, 5449, 5452, 5455, 5458, 5461, 5464, 
+    5467, 5470, 5474, 5478, 5482, 5485, 5489, 5492, 5496, 5498, 5500, 5502, 
+    5504, 5506, 5508, 5510, 5512, 5514, 5516, 5518, 5520, 5522, 5524, 5526, 
+    5528, 5530, 5532, 5534, 5536, 5538, 5540, 5542, 5544, 5546, 5548, 5550, 
+    5552, 5554, 5556, 5558, 5560, 5562, 5564, 5566, 5568, 5570, 5572, 5574, 
+    5576, 5578, 5580, 5582, 5584, 5586, 5588, 0, 5590, 5595, 5600, 5605, 
+    5609, 5614, 5618, 5622, 5628, 5633, 5637, 5641, 5645, 5650, 5655, 5659, 
+    5663, 5666, 5670, 5675, 5680, 5683, 5689, 5696, 5702, 5706, 5712, 5718, 
+    5723, 5727, 5731, 5735, 5740, 5746, 5751, 5755, 5759, 5763, 5766, 5769, 
+    5772, 5775, 5779, 5783, 5789, 5793, 5798, 5804, 5808, 5811, 5814, 5820, 
+    5825, 5831, 5835, 5841, 5844, 5848, 5852, 5856, 5860, 5864, 5869, 5873, 
+    5876, 5880, 5884, 5888, 5893, 5897, 5901, 5905, 5911, 5916, 5919, 5925, 
+    5928, 5933, 5938, 5942, 5946, 5950, 5955, 5958, 5962, 5967, 5970, 5976, 
+    5980, 5983, 5986, 5989, 5992, 5995, 5998, 6001, 6004, 6007, 6010, 6014, 
+    6018, 6022, 6026, 6030, 6034, 6038, 6042, 6046, 6050, 6054, 6058, 6062, 
+    6066, 6070, 6074, 6077, 6080, 6084, 6087, 6090, 6093, 6097, 6101, 6104, 
+    6107, 6110, 6113, 6116, 6121, 6124, 6127, 6130, 6133, 6136, 6139, 6142, 
+    6145, 6149, 6154, 6157, 6160, 6163, 6166, 6169, 6172, 6175, 6179, 6183, 
+    6187, 6191, 6194, 6197, 6200, 6203, 6206, 6209, 6212, 6215, 6218, 6221, 
+    6225, 6229, 6232, 6236, 6240, 6244, 6247, 6251, 6255, 6260, 6263, 6267, 
+    6271, 6275, 6279, 6285, 6292, 6295, 6298, 6301, 6304, 6307, 6310, 6313, 
+    6316, 6319, 6322, 6325, 6328, 6331, 6334, 6337, 6340, 6343, 6346, 6351, 
+    6354, 6357, 6360, 6365, 6369, 6372, 6375, 6378, 6381, 6384, 6387, 6390, 
+    6393, 6396, 6399, 6403, 6406, 6409, 6413, 6417, 6420, 6425, 6429, 6432, 
+    6435, 6438, 6441, 6445, 6449, 6452, 6455, 6458, 6461, 6464, 6467, 6470, 
+    6473, 6476, 6480, 6484, 6488, 6492, 6496, 6500, 6504, 6508, 6512, 6516, 
+    6520, 6524, 6528, 6532, 6536, 6540, 6544, 6548, 6552, 6556, 6560, 6564, 
+    6568, 6570, 6572, 6574, 6576, 6578, 6580, 6582, 6584, 6586, 6588, 6590, 
+    6592, 6594, 6596, 6598, 6600, 6602, 6604, 6606, 6608, 6610, 6612, 6614, 
+    6616, 6618, 6620, 6622, 6624, 6626, 6628, 6630, 6632, 6634, 6636, 6638, 
+    6640, 6642, 6644, 6646, 6648, 6650, 6652, 6654, 6656, 6658, 6660, 6662, 
+    6664, 6666, 6668, 6670, 6672, 6674, 6676, 6678, 6680, 6682, 6684, 6686, 
+    6688, 6690, 6692, 6694, 6696, 6698, 6700, 6702, 6704, 6706, 6708, 6710, 
+    6712, 6714, 6716, 6718, 6720, 6722, 6724, 6726, 6728, 6730, 6732, 6734, 
+    6736, 6738, 6740, 6742, 6744, 6746, 6748, 6750, 6752, 6754, 6756, 6758, 
+    6760, 6762, 6764, 6766, 6768, 6770, 6772, 6774, 6776, 6778, 6780, 6782, 
+    6784, 6786, 6788, 6790, 6792, 6794, 6796, 6798, 6800, 6802, 6804, 6806, 
+    6808, 6810, 6812, 6814, 6816, 6818, 6820, 6822, 6824, 6826, 6828, 6830, 
+    6832, 6834, 6836, 6838, 6840, 6842, 6844, 6846, 6848, 6850, 6852, 6854, 
+    6856, 6858, 6860, 6862, 6864, 6866, 6868, 6870, 6872, 6874, 6876, 6878, 
+    6880, 6882, 6884, 6886, 6888, 6890, 6892, 6894, 6896, 6898, 6900, 6902, 
+    6904, 6906, 6908, 6910, 6912, 6914, 6916, 6918, 6920, 6922, 6924, 6926, 
+    6928, 6930, 6932, 6934, 6936, 6938, 6940, 6942, 6944, 6946, 6948, 6950, 
+    6952, 6954, 6956, 6958, 6960, 6962, 6964, 6966, 6968, 6970, 6972, 6974, 
+    6976, 6978, 6980, 6982, 6984, 6986, 6988, 6990, 6992, 6994, 6996, 6998, 
+    7000, 7002, 7004, 7006, 7008, 7010, 7012, 7014, 7016, 7018, 7020, 7022, 
+    7024, 7026, 7028, 7030, 7032, 7034, 7036, 7038, 7040, 7042, 7044, 7046, 
+    7048, 7050, 7052, 7054, 7056, 7058, 7060, 7062, 7064, 7066, 7068, 7070, 
+    7072, 7074, 7076, 7078, 7080, 7082, 7084, 7086, 7088, 7090, 7092, 7094, 
+    7096, 7098, 7100, 7102, 7104, 7106, 0, 0, 7108, 0, 7110, 0, 0, 7112, 
+    7114, 7116, 7118, 7120, 7122, 7124, 7126, 7128, 7130, 0, 7132, 0, 7134, 
+    0, 0, 7136, 7138, 0, 0, 0, 7140, 7142, 7144, 7146, 0, 0, 7148, 7150, 
+    7152, 7154, 7156, 7158, 7160, 7162, 7164, 7166, 7168, 7170, 7172, 7174, 
+    7176, 7178, 7180, 7182, 7184, 7186, 7188, 7190, 7192, 7194, 7196, 7198, 
+    7200, 7202, 7204, 7206, 7208, 7210, 7212, 7214, 7216, 7218, 7220, 7222, 
+    7224, 7226, 7228, 7230, 7232, 7234, 7236, 7238, 7240, 7242, 7244, 7246, 
+    7248, 7250, 7252, 7254, 7256, 7258, 7260, 7262, 7264, 0, 0, 0, 0, 0, 
+    7266, 7268, 7270, 7272, 7274, 7276, 7278, 7280, 7282, 7284, 7286, 7288, 
+    7290, 7292, 7294, 7296, 7298, 7300, 7302, 7304, 7306, 7308, 7310, 7312, 
+    7314, 7316, 7318, 7320, 7322, 7324, 7326, 7328, 7330, 7332, 7334, 7336, 
+    7338, 7340, 7342, 7344, 7346, 7348, 7350, 7352, 7354, 7356, 7358, 7360, 
+    7362, 7364, 7366, 7368, 7370, 7372, 7374, 7376, 7378, 7380, 7382, 7384, 
+    7386, 7388, 7390, 7392, 7394, 7396, 7398, 7400, 7402, 7404, 7406, 7408, 
+    7410, 7412, 7414, 7416, 7418, 7420, 7422, 7424, 7426, 7428, 7430, 7432, 
+    7434, 7436, 7438, 7440, 7442, 7444, 7446, 7448, 7450, 7452, 7454, 7456, 
+    7458, 7460, 7462, 7464, 7466, 7468, 7470, 7472, 7474, 7476, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7478, 7481, 7484, 7487, 7491, 7495, 7498, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7501, 7504, 7507, 7510, 7513, 0, 0, 
+    0, 0, 0, 7516, 0, 7519, 7522, 7524, 7526, 7528, 7530, 7532, 7534, 7536, 
+    7538, 7540, 7542, 7545, 7548, 7551, 7554, 7557, 7560, 7563, 7566, 7569, 
+    7572, 7575, 7578, 0, 7581, 7584, 7587, 7590, 7593, 0, 7596, 0, 7599, 
+    7602, 0, 7605, 7608, 0, 7611, 7614, 7617, 7620, 7623, 7626, 7629, 7632, 
+    7635, 7638, 7641, 7643, 7645, 7647, 7649, 7651, 7653, 7655, 7657, 7659, 
+    7661, 7663, 7665, 7667, 7669, 7671, 7673, 7675, 7677, 7679, 7681, 7683, 
+    7685, 7687, 7689, 7691, 7693, 7695, 7697, 7699, 7701, 7703, 7705, 7707, 
+    7709, 7711, 7713, 7715, 7717, 7719, 7721, 7723, 7725, 7727, 7729, 7731, 
+    7733, 7735, 7737, 7739, 7741, 7743, 7745, 7747, 7749, 7751, 7753, 7755, 
+    7757, 7759, 7761, 7763, 7765, 7767, 7769, 7771, 7773, 7775, 7777, 7779, 
+    7781, 7783, 7785, 7787, 7789, 7791, 7793, 7795, 7797, 7799, 7801, 7803, 
+    7805, 7807, 7809, 7811, 7813, 7815, 7817, 7819, 7821, 7823, 7825, 7827, 
+    7829, 7831, 7833, 7835, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7837, 7839, 7841, 
+    7843, 7845, 7847, 7849, 7851, 7853, 7855, 7857, 7859, 7861, 7863, 7865, 
+    7867, 7869, 7871, 7873, 7875, 7877, 7879, 7881, 7883, 7886, 7889, 7892, 
+    7895, 7898, 7901, 7904, 7907, 7910, 7913, 7916, 7919, 7922, 7925, 7928, 
+    7931, 7934, 7937, 7939, 7941, 7943, 7945, 7948, 7951, 7954, 7957, 7960, 
+    7963, 7966, 7969, 7972, 7975, 7978, 7981, 7984, 7987, 7990, 7993, 7996, 
+    7999, 8002, 8005, 8008, 8011, 8014, 8017, 8020, 8023, 8026, 8029, 8032, 
+    8035, 8038, 8041, 8044, 8047, 8050, 8053, 8056, 8059, 8062, 8065, 8068, 
+    8071, 8074, 8077, 8080, 8083, 8086, 8089, 8092, 8095, 8098, 8101, 8104, 
+    8107, 8110, 8113, 8116, 8119, 8122, 8125, 8128, 8131, 8134, 8137, 8140, 
+    8143, 8146, 8149, 8152, 8155, 8158, 8161, 8164, 8167, 8170, 8173, 8176, 
+    8179, 8182, 8185, 8188, 8191, 8194, 8197, 8200, 8203, 8206, 8209, 8212, 
+    8215, 8218, 8221, 8224, 8227, 8231, 8235, 8239, 8243, 8247, 8251, 8254, 
+    8257, 8260, 8263, 8266, 8269, 8272, 8275, 8278, 8281, 8284, 8287, 8290, 
+    8293, 8296, 8299, 8302, 8305, 8308, 8311, 8314, 8317, 8320, 8323, 8326, 
+    8329, 8332, 8335, 8338, 8341, 8344, 8347, 8350, 8353, 8356, 8359, 8362, 
+    8365, 8368, 8371, 8374, 8377, 8380, 8383, 8386, 8389, 8392, 8395, 8398, 
+    8401, 8404, 8407, 8410, 8413, 8416, 8419, 8422, 8425, 8428, 8431, 8434, 
+    8437, 8440, 8443, 8446, 8449, 8452, 8455, 8458, 8461, 8464, 8467, 8470, 
+    8473, 8476, 8479, 8482, 8485, 8488, 8491, 8494, 8497, 8500, 8503, 8506, 
+    8509, 8512, 8515, 8518, 8521, 8524, 8527, 8530, 8533, 8536, 8539, 8542, 
+    8545, 8548, 8551, 8554, 8557, 8560, 8563, 8566, 8569, 8572, 8575, 8578, 
+    8581, 8584, 8587, 8590, 8593, 8596, 8599, 8602, 8605, 8608, 8611, 8614, 
+    8617, 8620, 8623, 8626, 8629, 8632, 8635, 8638, 8641, 8644, 8647, 8650, 
+    8653, 8656, 8659, 8662, 8665, 8668, 8671, 8674, 8677, 8681, 8685, 8689, 
+    8692, 8695, 8698, 8701, 8704, 8707, 8710, 8713, 8716, 8719, 8722, 8725, 
+    8728, 8731, 8734, 8737, 8740, 8743, 8746, 8749, 8752, 8755, 8758, 8761, 
+    8764, 8767, 8770, 8773, 8776, 8779, 8782, 8785, 8788, 8791, 8794, 8797, 
+    8800, 8803, 8806, 8809, 8812, 8815, 8818, 8821, 8824, 8827, 8830, 8833, 
+    8836, 8839, 8842, 8845, 8848, 8851, 8854, 8857, 8860, 8863, 8866, 8869, 
+    8872, 8875, 8878, 8881, 8884, 8887, 8890, 8893, 8896, 8899, 8902, 8905, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8908, 8912, 8916, 
+    8920, 8924, 8928, 8932, 8936, 8940, 8944, 8948, 8952, 8956, 8960, 8964, 
+    8968, 8972, 8976, 8980, 8984, 8988, 8992, 8996, 9000, 9004, 9008, 9012, 
+    9016, 9020, 9024, 9028, 9032, 9036, 9040, 9044, 9048, 9052, 9056, 9060, 
+    9064, 9068, 9072, 9076, 9080, 9084, 9088, 9092, 9096, 9100, 9104, 9108, 
+    9112, 9116, 9120, 9124, 9128, 9132, 9136, 9140, 9144, 9148, 9152, 9156, 
+    9160, 0, 0, 9164, 9168, 9172, 9176, 9180, 9184, 9188, 9192, 9196, 9200, 
+    9204, 9208, 9212, 9216, 9220, 9224, 9228, 9232, 9236, 9240, 9244, 9248, 
+    9252, 9256, 9260, 9264, 9268, 9272, 9276, 9280, 9284, 9288, 9292, 9296, 
+    9300, 9304, 9308, 9312, 9316, 9320, 9324, 9328, 9332, 9336, 9340, 9344, 
+    9348, 9352, 9356, 9360, 9364, 9368, 9372, 9376, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 9380, 9384, 9388, 9393, 9398, 9403, 9408, 9413, 
+    9418, 9423, 9427, 9446, 9455, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 9460, 9462, 9464, 9466, 9468, 9470, 9472, 9474, 9476, 
+    9478, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    9480, 9482, 9484, 9486, 9488, 9490, 9492, 9494, 9496, 9498, 9500, 9502, 
+    9504, 9506, 9508, 9510, 9512, 9514, 9516, 9518, 9520, 0, 0, 9522, 9524, 
+    9526, 9528, 9530, 9532, 9534, 9536, 9538, 9540, 9542, 9544, 0, 9546, 
+    9548, 9550, 9552, 9554, 9556, 9558, 9560, 9562, 9564, 9566, 9568, 9570, 
+    9572, 9574, 9576, 9578, 9580, 9582, 0, 9584, 9586, 9588, 9590, 0, 0, 0, 
+    0, 9592, 9595, 9598, 0, 9601, 0, 9604, 9607, 9610, 9613, 9616, 9619, 
+    9622, 9625, 9628, 9631, 9634, 9636, 9638, 9640, 9642, 9644, 9646, 9648, 
+    9650, 9652, 9654, 9656, 9658, 9660, 9662, 9664, 9666, 9668, 9670, 9672, 
+    9674, 9676, 9678, 9680, 9682, 9684, 9686, 9688, 9690, 9692, 9694, 9696, 
+    9698, 9700, 9702, 9704, 9706, 9708, 9710, 9712, 9714, 9716, 9718, 9720, 
+    9722, 9724, 9726, 9728, 9730, 9732, 9734, 9736, 9738, 9740, 9742, 9744, 
+    9746, 9748, 9750, 9752, 9754, 9756, 9758, 9760, 9762, 9764, 9766, 9768, 
+    9770, 9772, 9774, 9776, 9778, 9780, 9782, 9784, 9786, 9788, 9790, 9792, 
+    9794, 9796, 9798, 9800, 9802, 9804, 9806, 9808, 9810, 9812, 9814, 9816, 
+    9818, 9820, 9822, 9824, 9826, 9828, 9830, 9832, 9834, 9836, 9838, 9840, 
+    9842, 9844, 9846, 9848, 9850, 9852, 9854, 9856, 9858, 9860, 9862, 9864, 
+    9866, 9868, 9871, 9874, 9877, 9880, 9883, 9886, 9889, 0, 0, 0, 0, 9892, 
+    9894, 9896, 9898, 9900, 9902, 9904, 9906, 9908, 9910, 9912, 9914, 9916, 
+    9918, 9920, 9922, 9924, 9926, 9928, 9930, 9932, 9934, 9936, 9938, 9940, 
+    9942, 9944, 9946, 9948, 9950, 9952, 9954, 9956, 9958, 9960, 9962, 9964, 
+    9966, 9968, 9970, 9972, 9974, 9976, 9978, 9980, 9982, 9984, 9986, 9988, 
+    9990, 9992, 9994, 9996, 9998, 10000, 10002, 10004, 10006, 10008, 10010, 
+    10012, 10014, 10016, 10018, 10020, 10022, 10024, 10026, 10028, 10030, 
+    10032, 10034, 10036, 10038, 10040, 10042, 10044, 10046, 10048, 10050, 
+    10052, 10054, 10056, 10058, 10060, 10062, 10064, 10066, 10068, 10070, 
+    10072, 10074, 10076, 10078, 10080, 10082, 10084, 10086, 10088, 10090, 
+    10092, 10094, 10096, 10098, 10100, 10102, 10104, 10106, 10108, 10110, 
+    10112, 10114, 10116, 10118, 10120, 10122, 10124, 10126, 10128, 10130, 
+    10132, 10134, 10136, 10138, 10140, 10142, 10144, 10146, 10148, 10150, 
+    10152, 10154, 10156, 10158, 10160, 10162, 10164, 10166, 10168, 10170, 
+    10172, 10174, 10176, 10178, 10180, 10182, 10184, 10186, 10188, 10190, 
+    10192, 10194, 10196, 10198, 10200, 10202, 10204, 10206, 10208, 10210, 
+    10212, 10214, 10216, 10218, 10220, 10222, 10224, 10226, 10228, 10230, 
+    10232, 10234, 10236, 10238, 10240, 10242, 10244, 10246, 10248, 10250, 
+    10252, 10254, 10256, 10258, 10260, 10262, 10264, 10266, 10268, 10270, 0, 
+    0, 0, 10272, 10274, 10276, 10278, 10280, 10282, 0, 0, 10284, 10286, 
+    10288, 10290, 10292, 10294, 0, 0, 10296, 10298, 10300, 10302, 10304, 
+    10306, 0, 0, 10308, 10310, 10312, 0, 0, 0, 10314, 10316, 10318, 10320, 
+    10322, 10324, 10326, 0, 10328, 10330, 10332, 10334, 10336, 10338, 10340, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10342, 10345, 10348, 10351, 
+    10354, 10357, 10360, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10363, 
+    10366, 10369, 10372, 10375, 10378, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 10381, 10383, 10385, 10387, 10389, 10391, 10393, 10395, 10397, 
+    10399, 10401, 10403, 10405, 10407, 10409, 10411, 10413, 10415, 10417, 
+    10419, 10421, 10423, 10425, 10427, 10429, 10431, 10433, 10435, 10437, 
+    10439, 10441, 10443, 10445, 10447, 10449, 10451, 10453, 10455, 10457, 
+    10459, 10461, 10463, 10465, 10467, 10469, 10471, 10473, 10475, 10477, 
+    10479, 10481, 10483, 10485, 10487, 10489, 10491, 10493, 10495, 10497, 
+    10499, 10501, 10503, 10505, 10507, 10509, 10511, 10513, 10515, 10517, 
+    10519, 10521, 10523, 10525, 10527, 10529, 10531, 10533, 10535, 10537, 
+    10539, 10541, 10543, 10545, 10547, 10549, 0, 10551, 10553, 10555, 10557, 
+    10559, 10561, 10563, 10565, 10567, 10569, 10571, 10573, 10575, 10577, 
+    10579, 10581, 10583, 10585, 10587, 10589, 10591, 10593, 10595, 10597, 
+    10599, 10601, 10603, 10605, 10607, 10609, 10611, 10613, 10615, 10617, 
+    10619, 10621, 10623, 10625, 10627, 10629, 10631, 10633, 10635, 10637, 
+    10639, 10641, 10643, 10645, 10647, 10649, 10651, 10653, 10655, 10657, 
+    10659, 10661, 10663, 10665, 10667, 10669, 10671, 10673, 10675, 10677, 
+    10679, 10681, 10683, 10685, 10687, 10689, 10691, 0, 10693, 10695, 0, 0, 
+    10697, 0, 0, 10699, 10701, 0, 0, 10703, 10705, 10707, 10709, 0, 10711, 
+    10713, 10715, 10717, 10719, 10721, 10723, 10725, 10727, 10729, 10731, 
+    10733, 0, 10735, 0, 10737, 10739, 10741, 10743, 10745, 10747, 10749, 0, 
+    10751, 10753, 10755, 10757, 10759, 10761, 10763, 10765, 10767, 10769, 
+    10771, 10773, 10775, 10777, 10779, 10781, 10783, 10785, 10787, 10789, 
+    10791, 10793, 10795, 10797, 10799, 10801, 10803, 10805, 10807, 10809, 
+    10811, 10813, 10815, 10817, 10819, 10821, 10823, 10825, 10827, 10829, 
+    10831, 10833, 10835, 10837, 10839, 10841, 10843, 10845, 10847, 10849, 
+    10851, 10853, 10855, 10857, 10859, 10861, 10863, 10865, 10867, 10869, 
+    10871, 10873, 10875, 10877, 10879, 0, 10881, 10883, 10885, 10887, 0, 0, 
+    10889, 10891, 10893, 10895, 10897, 10899, 10901, 10903, 0, 10905, 10907, 
+    10909, 10911, 10913, 10915, 10917, 0, 10919, 10921, 10923, 10925, 10927, 
+    10929, 10931, 10933, 10935, 10937, 10939, 10941, 10943, 10945, 10947, 
+    10949, 10951, 10953, 10955, 10957, 10959, 10961, 10963, 10965, 10967, 
+    10969, 10971, 10973, 0, 10975, 10977, 10979, 10981, 0, 10983, 10985, 
+    10987, 10989, 10991, 0, 10993, 0, 0, 0, 10995, 10997, 10999, 11001, 
+    11003, 11005, 11007, 0, 11009, 11011, 11013, 11015, 11017, 11019, 11021, 
+    11023, 11025, 11027, 11029, 11031, 11033, 11035, 11037, 11039, 11041, 
+    11043, 11045, 11047, 11049, 11051, 11053, 11055, 11057, 11059, 11061, 
+    11063, 11065, 11067, 11069, 11071, 11073, 11075, 11077, 11079, 11081, 
+    11083, 11085, 11087, 11089, 11091, 11093, 11095, 11097, 11099, 11101, 
+    11103, 11105, 11107, 11109, 11111, 11113, 11115, 11117, 11119, 11121, 
+    11123, 11125, 11127, 11129, 11131, 11133, 11135, 11137, 11139, 11141, 
+    11143, 11145, 11147, 11149, 11151, 11153, 11155, 11157, 11159, 11161, 
+    11163, 11165, 11167, 11169, 11171, 11173, 11175, 11177, 11179, 11181, 
+    11183, 11185, 11187, 11189, 11191, 11193, 11195, 11197, 11199, 11201, 
+    11203, 11205, 11207, 11209, 11211, 11213, 11215, 11217, 11219, 11221, 
+    11223, 11225, 11227, 11229, 11231, 11233, 11235, 11237, 11239, 11241, 
+    11243, 11245, 11247, 11249, 11251, 11253, 11255, 11257, 11259, 11261, 
+    11263, 11265, 11267, 11269, 11271, 11273, 11275, 11277, 11279, 11281, 
+    11283, 11285, 11287, 11289, 11291, 11293, 11295, 11297, 11299, 11301, 
+    11303, 11305, 11307, 11309, 11311, 11313, 11315, 11317, 11319, 11321, 
+    11323, 11325, 11327, 11329, 11331, 11333, 11335, 11337, 11339, 11341, 
+    11343, 11345, 11347, 11349, 11351, 11353, 11355, 11357, 11359, 11361, 
+    11363, 11365, 11367, 11369, 11371, 11373, 11375, 11377, 11379, 11381, 
+    11383, 11385, 11387, 11389, 11391, 11393, 11395, 11397, 11399, 11401, 
+    11403, 11405, 11407, 11409, 11411, 11413, 11415, 11417, 11419, 11421, 
+    11423, 11425, 11427, 11429, 11431, 11433, 11435, 11437, 11439, 11441, 
+    11443, 11445, 11447, 11449, 11451, 11453, 11455, 11457, 11459, 11461, 
+    11463, 11465, 11467, 11469, 11471, 11473, 11475, 11477, 11479, 11481, 
+    11483, 11485, 11487, 11489, 11491, 11493, 11495, 11497, 11499, 11501, 
+    11503, 11505, 11507, 11509, 11511, 11513, 11515, 11517, 11519, 11521, 
+    11523, 11525, 11527, 11529, 11531, 11533, 11535, 11537, 11539, 11541, 
+    11543, 11545, 11547, 11549, 11551, 11553, 11555, 11557, 11559, 11561, 
+    11563, 11565, 11567, 11569, 11571, 11573, 11575, 11577, 11579, 11581, 
+    11583, 11585, 11587, 11589, 11591, 11593, 11595, 11597, 11599, 11601, 
+    11603, 11605, 11607, 11609, 11611, 11613, 11615, 11617, 11619, 11621, 
+    11623, 11625, 11627, 11629, 11631, 11633, 11635, 11637, 11639, 11641, 
+    11643, 11645, 11647, 11649, 11651, 11653, 11655, 11657, 11659, 11661, 
+    11663, 11665, 11667, 11669, 11671, 11673, 11675, 11677, 11679, 11681, 
+    11683, 11685, 11687, 0, 0, 11689, 11691, 11693, 11695, 11697, 11699, 
+    11701, 11703, 11705, 11707, 11709, 11711, 11713, 11715, 11717, 11719, 
+    11721, 11723, 11725, 11727, 11729, 11731, 11733, 11735, 11737, 11739, 
+    11741, 11743, 11745, 11747, 11749, 11751, 11753, 11755, 11757, 11759, 
+    11761, 11763, 11765, 11767, 11769, 11771, 11773, 11775, 11777, 11779, 
+    11781, 11783, 11785, 11787, 11789, 11791, 11793, 11795, 11797, 11799, 
+    11801, 11803, 11805, 11807, 11809, 11811, 11813, 11815, 11817, 11819, 
+    11821, 11823, 11825, 11827, 11829, 11831, 11833, 11835, 11837, 11839, 
+    11841, 11843, 11845, 11847, 11849, 11851, 11853, 11855, 11857, 11859, 
+    11861, 11863, 11865, 11867, 11869, 11871, 11873, 11875, 11877, 11879, 
+    11881, 11883, 11885, 11887, 11889, 11891, 11893, 11895, 11897, 11899, 
+    11901, 11903, 11905, 11907, 11909, 11911, 11913, 11915, 11917, 11919, 
+    11921, 11923, 11925, 11927, 11929, 11931, 11933, 11935, 11937, 11939, 
+    11941, 11943, 11945, 11947, 11949, 11951, 11953, 11955, 11957, 11959, 
+    11961, 11963, 11965, 11967, 11969, 11971, 11973, 11975, 11977, 11979, 
+    11981, 11983, 11985, 11987, 11989, 11991, 11993, 11995, 11997, 11999, 
+    12001, 12003, 12005, 12007, 12009, 12011, 12013, 12015, 12017, 12019, 
+    12021, 12023, 12025, 12027, 12029, 12031, 12033, 12035, 12037, 12039, 
+    12041, 12043, 12045, 12047, 12049, 12051, 12053, 12055, 12057, 12059, 
+    12061, 12063, 12065, 12067, 12069, 12071, 12073, 12075, 12077, 12079, 
+    12081, 12083, 12085, 12087, 12089, 12091, 12093, 12095, 12097, 12099, 
+    12101, 12103, 12105, 12107, 12109, 12111, 12113, 12115, 12117, 12119, 
+    12121, 12123, 12125, 12127, 12129, 12131, 12133, 12135, 12137, 12139, 
+    12141, 12143, 12145, 12147, 12149, 12151, 12153, 12155, 12157, 12159, 
+    12161, 12163, 12165, 12167, 12169, 12171, 12173, 12175, 12177, 12179, 
+    12181, 12183, 12185, 12187, 12189, 12191, 12193, 12195, 12197, 12199, 
+    12201, 12203, 12205, 12207, 12209, 12211, 12213, 12215, 12217, 12219, 
+    12221, 12223, 12225, 12227, 12229, 12231, 12233, 12235, 12237, 12239, 
+    12241, 12243, 12245, 12247, 12249, 12251, 12253, 12255, 12257, 12259, 
+    12261, 12263, 12265, 12267, 0, 0, 0, 0, 12269, 12271, 12273, 12275, 
+    12277, 12279, 12281, 12283, 12285, 12287, 12289, 12291, 12293, 12295, 
+    12297, 12299, 12301, 12303, 12305, 12307, 12309, 12311, 12313, 12315, 
+    12317, 12319, 12321, 12323, 12325, 12327, 12329, 12331, 12333, 12335, 
+    12337, 12339, 12341, 12343, 12345, 12347, 12349, 12351, 12353, 12355, 
+    12357, 12359, 12361, 12363, 12365, 12367, 12369, 12371, 12373, 12375, 
+    12377, 12379, 12381, 12383, 12385, 12387, 12389, 12391, 12393, 12395, 
+    12397, 12399, 12401, 12403, 12405, 12407, 12409, 12411, 12413, 12415, 
+    12417, 12419, 12421, 12423, 12425, 12427, 12429, 12431, 12433, 12435, 
+    12437, 12439, 12441, 12443, 12445, 12447, 12449, 12451, 12453, 12455, 
+    12457, 12459, 12461, 12463, 12465, 12467, 12469, 12471, 12473, 12475, 
+    12477, 12479, 12481, 12483, 12485, 12487, 12489, 12491, 12493, 12495, 
+    12497, 12499, 12501, 12503, 12505, 12507, 12509, 12511, 12513, 12515, 
+    12517, 12519, 12521, 12523, 12525, 12527, 12529, 12531, 12533, 12535, 
+    12537, 12539, 12541, 12543, 12545, 12547, 12549, 12551, 12553, 12555, 
+    12557, 12559, 12561, 12563, 12565, 12567, 12569, 12571, 12573, 12575, 
+    12577, 12579, 12581, 12583, 12585, 12587, 12589, 12591, 12593, 12595, 
+    12597, 12599, 12601, 12603, 12605, 12607, 12609, 12611, 12613, 12615, 
+    12617, 12619, 12621, 12623, 12625, 12627, 12629, 12631, 12633, 12635, 
+    12637, 12639, 12641, 12643, 12645, 12647, 12649, 12651, 12653, 12655, 
+    12657, 12659, 12661, 12663, 12665, 12667, 12669, 12671, 12673, 12675, 
+    12677, 12679, 12681, 12683, 12685, 12687, 12689, 12691, 12693, 12695, 
+    12697, 12699, 12701, 12703, 12705, 12707, 12709, 12711, 12713, 12715, 
+    12717, 12719, 12721, 12723, 12725, 12727, 12729, 12731, 12733, 12735, 
+    12737, 12739, 12741, 12743, 12745, 12747, 12749, 12751, 12753, 12755, 
+    12757, 12759, 12761, 12763, 12765, 12767, 12769, 12771, 12773, 12775, 
+    12777, 12779, 12781, 12783, 12785, 12787, 12789, 12791, 12793, 12795, 
+    12797, 12799, 12801, 12803, 12805, 12807, 12809, 12811, 12813, 12815, 
+    12817, 12819, 12821, 12823, 12825, 12827, 12829, 12831, 12833, 12835, 
+    12837, 12839, 12841, 12843, 12845, 12847, 12849, 12851, 12853, 12855, 
+    12857, 12859, 12861, 12863, 12865, 12867, 12869, 12871, 12873, 12875, 
+    12877, 12879, 12881, 12883, 12885, 12887, 12889, 12891, 12893, 12895, 
+    12897, 12899, 12901, 12903, 12905, 12907, 12909, 12911, 12913, 12915, 
+    12917, 12919, 12921, 12923, 12925, 12927, 12929, 12931, 12933, 12935, 
+    12937, 12939, 12941, 12943, 12945, 12947, 12949, 12951, 12953, 12955, 
+    12957, 12959, 12961, 12963, 12965, 12967, 12969, 12971, 12973, 12975, 
+    12977, 12979, 12981, 12983, 12985, 12987, 12989, 12991, 12993, 12995, 
+    12997, 12999, 13001, 13003, 13005, 13007, 13009, 13011, 13013, 13015, 
+    13017, 13019, 13021, 13023, 13025, 13027, 13029, 13031, 13033, 13035, 
+    13037, 13039, 13041, 13043, 13045, 13047, 13049, 13051, 13053, 13055, 
+    13057, 13059, 13061, 13063, 13065, 13067, 13069, 13071, 13073, 13075, 
+    13077, 13079, 13081, 13083, 13085, 13087, 13089, 13091, 13093, 13095, 
+    13097, 13099, 13101, 13103, 13105, 13107, 13109, 13111, 13113, 13115, 
+    13117, 13119, 13121, 13123, 13125, 13127, 13129, 13131, 13133, 13135, 
+    13137, 13139, 13141, 13143, 13145, 13147, 13149, 13151, 13153, 13155, 
+    13157, 13159, 13161, 13163, 13165, 13167, 13169, 13171, 13173, 13175, 
+    13177, 13179, 13181, 13183, 13185, 13187, 13189, 13191, 13193, 13195, 
+    13197, 13199, 13201, 13203, 13205, 13207, 13209, 13211, 13213, 13215, 
+    13217, 13219, 13221, 13223, 13225, 13227, 13229, 13231, 13233, 13235, 
+    13237, 13239, 13241, 13243, 13245, 13247, 13249, 13251, 13253, 13255, 
+    13257, 13259, 13261, 13263, 13265, 13267, 13269, 13271, 13273, 13275, 
+    13277, 13279, 13281, 13283, 13285, 13287, 13289, 13291, 13293, 13295, 
+    13297, 13299, 13301, 13303, 13305, 13307, 13309, 13311, 13313, 13315, 
+    13317, 13319, 13321, 13323, 13325, 13327, 13329, 13331, 13333, 13335, 
+    13337, 13339, 13341, 13343, 13345, 13347, 13349, 13351, 13353, 13355, 
+    13357, 13359, 13361, 13363, 13365, 13367, 13369, 13371, 13373, 13375, 
+    13377, 13379, 13381, 13383, 13385, 13387, 13389, 13391, 13393, 13395, 
+    13397, 13399, 13401, 13403, 13405, 13407, 13409, 13411, 13413, 13415, 
+    13417, 13419, 13421, 13423, 13425, 13427, 13429, 13431, 13433, 13435, 
+    13437, 13439, 13441, 13443, 13445, 13447, 13449, 13451, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 
+};
+
+/* NFC pairs */
+#define COMP_SHIFT 3
+static unsigned short comp_index[] = {
+    0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 3, 0, 0, 4, 5, 6, 7, 0, 
+    0, 0, 0, 8, 9, 10, 0, 0, 0, 11, 12, 13, 0, 0, 0, 0, 14, 15, 16, 17, 0, 0, 
+    18, 19, 20, 21, 0, 0, 0, 22, 0, 0, 0, 0, 0, 23, 24, 25, 26, 0, 0, 0, 27, 
+    28, 29, 30, 0, 0, 31, 32, 33, 34, 35, 0, 0, 36, 0, 0, 0, 0, 0, 0, 37, 38, 
+    39, 40, 0, 0, 41, 0, 42, 43, 44, 0, 0, 45, 46, 47, 0, 0, 0, 0, 48, 49, 
+    50, 51, 0, 0, 52, 53, 54, 55, 0, 0, 0, 56, 57, 0, 0, 0, 0, 0, 58, 59, 60, 
+    61, 0, 0, 62, 63, 64, 65, 0, 0, 0, 66, 67, 68, 69, 0, 0, 70, 71, 72, 73, 
+    0, 0, 0, 74, 0, 75, 0, 0, 0, 0, 76, 0, 77, 0, 0, 0, 0, 78, 0, 0, 0, 0, 0, 
+    79, 80, 81, 0, 0, 0, 0, 82, 83, 84, 85, 0, 0, 86, 87, 88, 89, 0, 0, 0, 
+    90, 0, 91, 92, 0, 0, 93, 94, 95, 96, 0, 0, 0, 0, 97, 98, 99, 0, 0, 0, 
+    100, 101, 102, 103, 0, 0, 0, 104, 0, 0, 0, 0, 0, 105, 106, 107, 0, 0, 0, 
+    0, 108, 109, 110, 111, 0, 0, 112, 113, 114, 115, 0, 0, 0, 116, 117, 0, 0, 
+    0, 0, 118, 0, 119, 120, 121, 0, 0, 122, 123, 124, 125, 0, 0, 0, 126, 0, 
+    127, 0, 0, 0, 128, 129, 130, 131, 0, 0, 0, 132, 133, 134, 135, 0, 0, 0, 
+    136, 0, 0, 0, 0, 0, 137, 138, 139, 140, 0, 0, 0, 141, 142, 143, 0, 0, 0, 
+    0, 144, 145, 146, 147, 0, 0, 148, 149, 150, 151, 0, 0, 0, 152, 0, 153, 0, 
+    0, 0, 154, 155, 156, 0, 0, 0, 0, 0, 157, 0, 0, 0, 0, 158, 159, 160, 161, 
+    0, 0, 0, 162, 163, 164, 165, 0, 0, 0, 166, 0, 0, 167, 0, 0, 168, 169, 0, 
+    0, 0, 0, 0, 170, 0, 0, 0, 0, 0, 0, 171, 0, 0, 0, 0, 0, 172, 173, 0, 0, 0, 
+    0, 0, 174, 0, 0, 0, 0, 0, 175, 176, 0, 0, 0, 0, 0, 177, 0, 0, 0, 0, 0, 0, 
+    178, 179, 0, 0, 0, 0, 180, 181, 0, 0, 0, 0, 0, 182, 0, 0, 0, 0, 0, 0, 
+    183, 0, 0, 0, 0, 0, 184, 185, 186, 0, 0, 0, 0, 187, 188, 0, 0, 0, 0, 0, 
+    189, 0, 0, 0, 0, 0, 190, 0, 0, 0, 0, 0, 0, 191, 0, 0, 0, 0, 0, 192, 0, 0, 
+    0, 0, 0, 0, 193, 194, 0, 0, 0, 0, 0, 195, 0, 0, 0, 0, 0, 196, 197, 0, 0, 
+    0, 0, 0, 198, 199, 0, 0, 0, 0, 0, 200, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 
+    0, 202, 203, 0, 0, 0, 0, 204, 205, 0, 0, 0, 0, 0, 206, 207, 0, 0, 0, 0, 
+    0, 208, 0, 0, 0, 0, 0, 209, 0, 0, 0, 0, 0, 0, 210, 0, 0, 0, 0, 0, 211, 
+    212, 0, 0, 0, 0, 0, 0, 213, 0, 0, 0, 0, 0, 214, 0, 0, 0, 0, 0, 0, 215, 0, 
+    0, 0, 0, 0, 0, 216, 0, 0, 0, 0, 0, 217, 0, 0, 0, 0, 0, 218, 0, 0, 0, 0, 
+    0, 0, 0, 219, 0, 0, 0, 0, 0, 220, 0, 0, 0, 0, 0, 0, 221, 0, 0, 0, 0, 0, 
+    222, 223, 224, 0, 0, 0, 225, 226, 227, 0, 0, 0, 0, 228, 229, 230, 0, 0, 
+    0, 0, 231, 232, 233, 0, 0, 0, 0, 0, 234, 0, 0, 0, 0, 235, 0, 0, 0, 0, 0, 
+    0, 236, 0, 0, 0, 0, 0, 0, 237, 0, 0, 0, 0, 0, 238, 0, 0, 0, 0, 0, 0, 239, 
+    0, 0, 0, 0, 0, 0, 240, 0, 0, 0, 0, 0, 241, 0, 0, 0, 0, 0, 0, 242, 0, 0, 
+    0, 0, 0, 0, 243, 0, 0, 0, 0, 244, 245, 246, 0, 247, 0, 0, 248, 0, 249, 0, 
+    0, 0, 0, 250, 251, 252, 253, 0, 0, 254, 255, 256, 0, 0, 0, 0, 257, 0, 
+    258, 0, 0, 0, 0, 0, 259, 0, 0, 0, 0, 260, 261, 262, 0, 0, 0, 0, 263, 0, 
+    264, 265, 0, 0, 0, 0, 0, 0, 266, 0, 0, 0, 0, 0, 0, 267, 0, 0, 268, 269, 
+    270, 271, 0, 0, 272, 0, 273, 0, 0, 0, 0, 274, 0, 275, 276, 277, 0, 0, 
+    278, 279, 0, 280, 0, 0, 281, 0, 282, 0, 0, 0, 0, 0, 0, 283, 0, 0, 0, 284, 
+    285, 286, 0, 287, 0, 0, 288, 0, 289, 0, 290, 0, 0, 291, 0, 0, 292, 0, 0, 
+    293, 0, 0, 0, 294, 0, 0, 0, 0, 0, 0, 295, 0, 0, 296, 0, 0, 0, 0, 0, 0, 
+    297, 0, 0, 0, 0, 0, 298, 299, 0, 0, 0, 0, 0, 300, 0, 0, 0, 0, 0, 301, 
+    302, 0, 0, 0, 0, 0, 303, 304, 0, 0, 0, 0, 0, 305, 0, 0, 0, 0, 0, 306, 
+    307, 0, 0, 0, 0, 0, 308, 0, 0, 0, 0, 0, 0, 309, 0, 0, 0, 0, 0, 310, 311, 
+    0, 0, 0, 0, 0, 312, 0, 0, 0, 0, 0, 0, 313, 0, 0, 0, 0, 0, 0, 314, 0, 0, 
+    0, 0, 0, 315, 0, 0, 0, 0, 0, 316, 0, 0, 0, 0, 0, 0, 317, 0, 0, 0, 0, 0, 
+    0, 318, 0, 0, 0, 0, 0, 0, 319, 0, 0, 0, 0, 320, 321, 0, 0, 0, 0, 0, 322, 
+    0, 0, 0, 0, 0, 0, 0, 323, 0, 0, 0, 0, 0, 324, 325, 0, 0, 0, 0, 0, 326, 0, 
+    0, 0, 0, 0, 327, 0, 0, 0, 0, 0, 0, 328, 0, 0, 0, 0, 0, 0, 329, 0, 0, 0, 
+    0, 0, 0, 330, 0, 0, 0, 0, 0, 0, 331, 0, 0, 0, 0, 0, 332, 0, 0, 0, 0, 0, 
+    333, 0, 0, 0, 0, 0, 0, 334, 0, 0, 0, 0, 0, 335, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 336, 0, 0, 0, 0, 0, 0, 337, 0, 0, 0, 0, 0, 338, 0, 0, 0, 0, 0, 0, 339, 
+    0, 0, 0, 0, 0, 0, 340, 0, 0, 0, 0, 0, 341, 0, 0, 0, 0, 0, 0, 342, 0, 0, 
+    0, 0, 0, 0, 343, 0, 0, 0, 0, 0, 344, 0, 0, 0, 0, 0, 0, 345, 0, 0, 0, 0, 
+    0, 0, 346, 0, 0, 0, 0, 0, 0, 347, 0, 0, 0, 0, 0, 0, 348, 0, 0, 0, 0, 0, 
+    349, 0, 0, 0, 0, 0, 0, 350, 0, 0, 0, 0, 0, 0, 351, 0, 0, 0, 0, 0, 352, 
+    353, 0, 0, 0, 0, 0, 354, 0, 0, 0, 0, 0, 0, 355, 0, 0, 0, 0, 0, 0, 356, 0, 
+    0, 0, 0, 0, 0, 357, 0, 0, 0, 0, 0, 358, 0, 0, 0, 0, 0, 0, 359, 360, 0, 0, 
+    0, 0, 0, 0, 361, 0, 0, 0, 0, 0, 362, 0, 0, 0, 0, 0, 0, 363, 0, 0, 0, 0, 
+    0, 0, 364, 0, 0, 0, 0, 0, 365, 0, 0, 0, 0, 0, 0, 366, 0, 0, 0, 0, 0, 367, 
+    368, 0, 0, 0, 0, 0, 369, 0, 0, 0, 0, 0, 370, 0, 0, 0, 0, 0, 0, 371, 0, 0, 
+    0, 0, 0, 0, 372, 0, 0, 0, 0, 0, 373, 0, 0, 0, 374, 0, 0, 375, 0, 0, 376, 
+    0, 0, 0, 0, 0, 0, 377, 0, 0, 0, 0, 0, 0, 378, 0, 0, 0, 0, 0, 379, 0, 0, 
+    0, 0, 0, 0, 380, 0, 0, 0, 0, 0, 381, 0, 0, 0, 0, 0, 0, 382, 0, 0, 383, 0, 
+    0, 0, 384, 0, 0, 385, 0, 0, 386, 0, 0, 0, 0, 0, 0, 387, 0, 0, 0, 0, 0, 0, 
+    388, 0, 0, 0, 0, 0, 389, 0, 0, 0, 0, 0, 0, 390, 0, 0, 0, 0, 0, 391, 0, 0, 
+    0, 0, 0, 0, 392, 0, 0, 393, 0, 0, 0, 0, 0, 0, 394, 0, 0, 0, 0, 0, 395, 0, 
+    0, 0, 0, 0, 0, 396, 0, 0, 0, 0, 0, 0, 397, 0, 0, 398, 0, 0, 399, 0, 0, 0, 
+    400, 0, 0, 0, 0, 0, 401, 0, 0, 0, 0, 0, 0, 402, 0, 0, 0, 0, 0, 0, 403, 0, 
+    0, 0, 0, 0, 404, 0, 0, 0, 0, 0, 0, 405, 0, 0, 0, 0, 0, 0, 406, 0, 0, 407, 
+    0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 411, 0, 0, 0, 0, 0, 0, 
+    412, 0, 0, 0, 0, 0, 0, 413, 0, 0, 0, 0, 0, 414, 0, 0, 0, 0, 0, 0, 415, 0, 
+    0, 0, 0, 0, 0, 416, 0, 0, 417, 0, 0, 418, 0, 0, 419, 0, 0, 0, 420, 0, 0, 
+    421, 0, 0, 422, 0, 0, 423, 424, 0, 0, 425, 0, 0, 426, 0, 0, 0, 0, 0, 0, 
+    427, 0, 0, 0, 0, 0, 428, 0, 0, 0, 0, 0, 0, 429, 0, 0, 0, 0, 0, 0, 430, 0, 
+    0, 431, 0, 0, 432, 0, 0, 0, 433, 0, 0, 434, 0, 0, 435, 0, 0, 436, 437, 0, 
+    0, 438, 0, 0, 439, 0, 0, 0, 440, 0, 0, 0, 0, 0, 441, 0, 0, 0, 0, 0, 0, 
+    442, 0, 0, 0, 0, 0, 0, 443, 0, 0, 0, 0, 0, 444, 0, 0, 0, 0, 0, 0, 445, 0, 
+    0, 0, 0, 0, 446, 0, 0, 447, 448, 0, 0, 449, 0, 0, 450, 0, 0, 0, 451, 0, 
+    0, 0, 0, 0, 452, 0, 0, 0, 0, 0, 0, 453, 0, 0, 0, 0, 0, 0, 454, 0, 0, 0, 
+    0, 0, 455, 0, 0, 0, 0, 0, 0, 456, 0, 0, 0, 0, 0, 457, 0, 0, 0, 0, 0, 0, 
+    458, 0, 0, 0, 0, 0, 0, 459, 0, 0, 0, 0, 0, 460, 0, 0, 0, 0, 0, 0, 461, 0, 
+    0, 462, 0, 0, 463, 0, 0, 0, 0, 0, 0, 464, 0, 0, 0, 0, 0, 0, 465, 0, 0, 
+    466, 0, 0, 467, 0, 0, 0, 0, 0, 0, 468, 0, 0, 0, 0, 0, 469, 0, 0, 0, 0, 0, 
+    0, 470, 0, 0, 0, 0, 0, 0, 471, 0, 0, 0, 0, 0, 472, 0, 0, 0, 0, 0, 0, 473, 
+    0, 0, 0, 0, 0, 0, 474, 0, 0, 0, 0, 0, 475, 0, 0, 0, 0, 0, 0, 476, 0, 0, 
+    0, 0, 0, 477, 0, 0, 0, 0, 0, 0, 478, 0, 0, 0, 0, 0, 0, 479, 0, 0, 0, 0, 
+    0, 480, 0, 0, 0, 0, 0, 0, 481, 0, 0, 0, 0, 0, 0, 482, 0, 0, 0, 0, 0, 483, 
+    0, 0, 0, 0, 0, 0, 484, 0, 0, 0, 0, 0, 485, 0, 0, 0, 0, 0, 0, 486, 0, 0, 
+    0, 0, 0, 0, 487, 0, 0, 0, 0, 0, 488, 0, 0, 0, 0, 0, 0, 489, 0, 0, 0, 0, 
+    0, 0, 490, 0, 0, 0, 0, 0, 491, 0, 0, 0, 0, 0, 0, 492, 0, 0, 0, 0, 0, 493, 
+    0, 0, 0, 0, 0, 0, 494, 0, 0, 0, 0, 0, 0, 495, 0, 0, 0, 0, 0, 496, 0, 0, 
+    0, 0, 0, 0, 497, 0, 0, 0, 0, 0, 0, 498, 0, 0, 0, 0, 0, 499, 0, 0, 0, 0, 
+    0, 0, 500, 0, 0, 0, 0, 0, 501, 0, 0, 0, 0, 0, 0, 502, 0, 0, 0, 0, 0, 0, 
+    503, 0, 0, 0, 0, 0, 504, 0, 0, 0, 0, 0, 0, 505, 0, 0, 0, 0, 0, 0, 506, 0, 
+    0, 0, 0, 0, 507, 0, 0, 0, 0, 0, 0, 508, 0, 0, 0, 0, 0, 0, 0, 0, 509, 0, 
+    0, 0, 0, 0, 0, 510, 0, 0, 0, 0, 0, 0, 511, 0, 0, 0, 0, 0, 512, 0, 0, 0, 
+    0, 0, 0, 513, 0, 0, 0, 0, 0, 0, 514, 0, 0, 0, 0, 0, 515, 0, 0, 0, 0, 0, 
+    0, 516, 0, 0, 0, 0, 0, 517, 0, 0, 0, 0, 0, 0, 518, 0, 0, 0, 0, 0, 0, 519, 
+    0, 0, 0, 0, 0, 520, 0, 0, 0, 0, 0, 0, 521, 0, 0, 0, 0, 0, 0, 522, 0, 0, 
+    0, 0, 0, 523, 0, 0, 0, 0, 0, 0, 524, 0, 0, 0, 0, 0, 525, 526, 0, 0, 0, 0, 
+    0, 527, 0, 0, 0, 0, 0, 0, 528, 0, 0, 0, 0, 0, 529, 0, 0, 0, 0, 0, 0, 530, 
+    0, 0, 0, 0, 0, 0, 531, 0, 0, 0, 0, 0, 532, 0, 0, 0, 0, 0, 0, 533, 0, 0, 
+    0, 0, 0, 534, 0, 0, 0, 0, 0, 0, 535, 0, 0, 0, 0, 0, 0, 536, 0, 0, 0, 0, 
+    0, 537, 0, 0, 0, 0, 0, 0, 538, 0, 0, 0, 0, 0, 0, 539, 0, 0, 0, 0, 0, 540, 
+    0, 0, 0, 0, 0, 0, 541, 0, 0, 0, 0, 0, 542, 0, 0, 0, 0, 0, 0, 543, 0, 0, 
+    0, 0, 0, 0, 544, 0, 0, 0, 0, 0, 545, 0, 0, 0, 0, 0, 0, 546, 0, 0, 0, 0, 
+    0, 0, 547, 0, 0, 0, 0, 0, 548, 0, 0, 0, 0, 0, 0, 549, 0, 0, 0, 0, 0, 550, 
+    551, 0, 0, 0, 0, 0, 552, 0, 0, 0, 0, 0, 0, 553, 0, 0, 0, 0, 0, 554, 0, 0, 
+    0, 0, 0, 0, 555, 0, 0, 0, 0, 0, 0, 556, 0, 0, 0, 0, 0, 557, 0, 0, 0, 0, 
+    0, 0, 558, 
+};
+
+static unsigned short comp_data[] = {
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8814, 0, 0, 0, 0, 8800, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 8815, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 193, 194, 195, 
+    256, 258, 550, 196, 7842, 197, 0, 461, 512, 514, 0, 0, 0, 7840, 0, 7680, 
+    0, 0, 260, 0, 0, 0, 0, 7682, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7684, 0, 0, 0, 
+    0, 0, 0, 0, 0, 7686, 0, 0, 0, 262, 264, 0, 0, 0, 266, 0, 0, 0, 0, 268, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 199, 0, 0, 0, 0, 0, 7690, 0, 0, 0, 0, 270, 0, 0, 
+    0, 0, 0, 7692, 0, 0, 0, 7696, 0, 7698, 0, 0, 7694, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 200, 201, 202, 7868, 274, 276, 278, 203, 7866, 0, 0, 282, 516, 
+    518, 0, 0, 0, 7864, 0, 0, 0, 552, 280, 7704, 0, 7706, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 7710, 0, 0, 0, 0, 0, 0, 0, 500, 284, 0, 7712, 286, 288, 0, 0, 0, 
+    0, 486, 0, 0, 0, 0, 0, 0, 0, 0, 0, 290, 0, 0, 0, 0, 0, 0, 0, 0, 0, 292, 
+    0, 0, 0, 7714, 7718, 0, 0, 0, 542, 0, 0, 0, 0, 0, 7716, 0, 0, 0, 7720, 0, 
+    0, 7722, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 204, 205, 206, 296, 298, 
+    300, 304, 207, 7880, 0, 0, 463, 520, 522, 0, 0, 0, 7882, 0, 0, 0, 0, 302, 
+    0, 0, 7724, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 308, 0, 0, 0, 7728, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 488, 0, 0, 0, 0, 0, 7730, 0, 0, 0, 310, 0, 0, 0, 
+    0, 7732, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 313, 0, 317, 0, 0, 0, 0, 0, 
+    7734, 0, 0, 0, 315, 0, 7740, 0, 0, 7738, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    7742, 0, 0, 0, 0, 7744, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7746, 0, 0, 0, 504, 
+    323, 0, 209, 0, 0, 7748, 0, 0, 0, 0, 327, 0, 0, 0, 0, 0, 7750, 0, 0, 0, 
+    325, 0, 7754, 0, 0, 7752, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 211, 212, 
+    213, 332, 334, 558, 214, 7886, 0, 336, 465, 524, 526, 0, 0, 416, 7884, 0, 
+    0, 0, 0, 490, 0, 0, 0, 0, 0, 0, 0, 7764, 0, 0, 0, 0, 7766, 0, 0, 0, 0, 0, 
+    0, 0, 340, 0, 0, 0, 0, 7768, 0, 0, 0, 0, 344, 528, 530, 0, 0, 0, 7770, 0, 
+    0, 0, 342, 0, 0, 0, 0, 7774, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 346, 348, 
+    0, 0, 0, 7776, 0, 0, 0, 0, 352, 0, 0, 0, 0, 0, 7778, 0, 0, 536, 350, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7786, 0, 0, 0, 0, 356, 0, 0, 0, 0, 0, 
+    7788, 0, 0, 538, 354, 0, 7792, 0, 0, 7790, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    217, 218, 219, 360, 362, 364, 0, 220, 7910, 366, 368, 467, 532, 534, 0, 
+    0, 431, 7908, 7794, 0, 0, 0, 370, 7798, 0, 7796, 0, 0, 0, 0, 0, 0, 7804, 
+    0, 0, 0, 0, 0, 7806, 0, 0, 0, 7808, 7810, 372, 0, 0, 0, 7814, 7812, 0, 
+    7816, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7818, 7820, 0, 0, 0, 0, 0, 7922, 221, 
+    374, 7928, 562, 0, 7822, 376, 7926, 0, 0, 0, 0, 0, 0, 0, 0, 7924, 0, 0, 
+    0, 0, 377, 7824, 0, 0, 0, 379, 0, 0, 0, 0, 381, 0, 0, 0, 0, 0, 7826, 0, 
+    0, 0, 0, 0, 0, 0, 0, 7828, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 225, 226, 
+    227, 257, 259, 551, 228, 7843, 229, 0, 462, 513, 515, 0, 0, 0, 7841, 0, 
+    7681, 0, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7683, 0, 0, 7685, 0, 
+    0, 0, 0, 0, 0, 0, 0, 7687, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 263, 265, 0, 
+    0, 0, 267, 0, 0, 0, 0, 269, 0, 0, 0, 0, 0, 0, 0, 0, 0, 231, 0, 0, 0, 0, 
+    0, 7691, 0, 0, 0, 0, 271, 0, 0, 0, 0, 0, 7693, 0, 0, 0, 7697, 0, 7699, 0, 
+    0, 7695, 0, 0, 232, 233, 234, 7869, 275, 277, 279, 235, 7867, 0, 0, 283, 
+    517, 519, 0, 0, 0, 7865, 0, 0, 0, 553, 281, 7705, 0, 7707, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 7711, 0, 0, 0, 0, 0, 0, 0, 501, 285, 0, 7713, 287, 289, 0, 0, 
+    0, 0, 487, 0, 0, 0, 0, 0, 0, 0, 0, 0, 291, 0, 293, 0, 0, 0, 7715, 7719, 
+    0, 0, 0, 543, 0, 0, 0, 0, 0, 7717, 0, 0, 0, 7721, 0, 0, 7723, 0, 7830, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 236, 237, 238, 297, 299, 301, 0, 239, 7881, 0, 
+    0, 464, 521, 523, 0, 0, 0, 7883, 0, 0, 0, 0, 303, 0, 0, 7725, 0, 0, 0, 0, 
+    0, 309, 0, 0, 0, 0, 0, 0, 0, 0, 496, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7729, 
+    0, 489, 0, 0, 0, 0, 0, 7731, 0, 0, 0, 311, 0, 0, 0, 0, 7733, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 314, 0, 0, 0, 0, 0, 0, 0, 0, 0, 318, 0, 0, 0, 0, 0, 
+    7735, 0, 0, 0, 316, 0, 7741, 0, 0, 7739, 0, 0, 0, 7743, 0, 0, 0, 0, 7745, 
+    0, 0, 7747, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 505, 324, 0, 241, 0, 0, 
+    7749, 0, 0, 0, 0, 328, 0, 0, 0, 0, 0, 7751, 0, 0, 0, 326, 0, 7755, 0, 0, 
+    7753, 0, 0, 242, 243, 244, 245, 333, 335, 559, 246, 7887, 0, 337, 466, 
+    525, 527, 0, 0, 417, 7885, 0, 0, 0, 0, 491, 0, 0, 0, 0, 0, 0, 0, 7765, 0, 
+    0, 0, 0, 7767, 0, 0, 0, 0, 0, 0, 0, 341, 0, 0, 0, 0, 7769, 0, 0, 0, 0, 
+    345, 529, 531, 0, 0, 0, 7771, 0, 0, 0, 343, 0, 0, 0, 0, 7775, 0, 0, 0, 
+    347, 349, 0, 0, 0, 7777, 0, 0, 0, 0, 353, 0, 0, 0, 0, 0, 7779, 0, 0, 537, 
+    351, 0, 0, 0, 0, 0, 7787, 7831, 0, 0, 0, 357, 0, 0, 0, 0, 0, 7789, 0, 0, 
+    539, 355, 0, 7793, 0, 0, 7791, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 249, 250, 
+    251, 361, 363, 365, 0, 252, 7911, 367, 369, 468, 533, 535, 0, 0, 432, 
+    7909, 7795, 0, 0, 0, 371, 7799, 0, 7797, 0, 0, 0, 0, 0, 0, 7805, 0, 0, 0, 
+    0, 0, 7807, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7809, 7811, 373, 0, 0, 0, 
+    7815, 7813, 0, 7832, 0, 0, 0, 0, 0, 0, 0, 7817, 0, 7819, 7821, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7923, 253, 375, 7929, 563, 0, 7823, 255, 
+    7927, 7833, 0, 0, 0, 0, 0, 0, 0, 7925, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 378, 7825, 0, 0, 0, 380, 0, 0, 0, 0, 382, 0, 0, 0, 0, 0, 7827, 0, 0, 
+    0, 0, 0, 0, 0, 0, 7829, 0, 0, 8173, 901, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    8129, 0, 0, 0, 0, 0, 0, 0, 0, 7846, 7844, 0, 7850, 0, 0, 0, 0, 7848, 0, 
+    0, 0, 0, 0, 0, 0, 0, 478, 0, 506, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    508, 0, 0, 482, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7688, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 7872, 7870, 0, 7876, 0, 0, 0, 0, 7874, 0, 0, 0, 0, 0, 7726, 0, 
+    0, 0, 7890, 7888, 0, 7894, 0, 0, 0, 0, 7892, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 7756, 0, 0, 556, 0, 0, 7758, 0, 0, 0, 0, 0, 0, 0, 0, 0, 554, 
+    0, 510, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 475, 471, 0, 0, 469, 0, 0, 0, 0, 
+    0, 0, 473, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7847, 7845, 0, 7851, 0, 0, 0, 0, 
+    7849, 0, 0, 0, 0, 0, 0, 0, 0, 479, 0, 0, 0, 0, 0, 0, 0, 0, 0, 507, 0, 0, 
+    0, 0, 509, 0, 0, 483, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7689, 0, 0, 0, 7873, 
+    7871, 0, 7877, 0, 0, 0, 0, 7875, 0, 0, 0, 0, 0, 7727, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 7891, 7889, 0, 7895, 0, 0, 0, 0, 7893, 0, 0, 0, 0, 0, 
+    7757, 0, 0, 557, 0, 0, 7759, 0, 0, 0, 0, 0, 0, 0, 0, 0, 555, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 511, 0, 0, 0, 476, 472, 0, 0, 470, 0, 0, 0, 0, 0, 0, 474, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 7856, 7854, 0, 7860, 0, 0, 0, 0, 7858, 0, 0, 
+    0, 0, 7857, 7855, 0, 7861, 0, 0, 0, 0, 7859, 0, 0, 0, 0, 7700, 7702, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7701, 7703, 0, 0, 0, 7760, 7762, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 7761, 7763, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7780, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7781, 0, 0, 0, 0, 7782, 0, 0, 0, 0, 
+    7783, 0, 0, 0, 0, 0, 0, 0, 7800, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    7801, 0, 0, 7802, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7803, 0, 0, 0, 
+    7835, 0, 0, 0, 0, 0, 0, 7900, 7898, 0, 7904, 0, 0, 0, 0, 7902, 0, 0, 0, 
+    0, 0, 0, 0, 0, 7906, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7901, 7899, 0, 
+    7905, 0, 0, 0, 0, 7903, 0, 0, 0, 0, 0, 0, 0, 0, 7907, 0, 0, 0, 7914, 
+    7912, 0, 7918, 0, 0, 0, 0, 7916, 0, 0, 0, 0, 0, 0, 0, 0, 7920, 0, 0, 0, 
+    7915, 7913, 0, 7919, 0, 0, 0, 0, 7917, 0, 0, 0, 0, 0, 0, 0, 0, 7921, 0, 
+    0, 0, 0, 0, 0, 494, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 492, 0, 0, 0, 
+    0, 493, 0, 0, 0, 0, 480, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 481, 0, 0, 
+    0, 0, 0, 7708, 0, 0, 0, 0, 7709, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 560, 0, 
+    0, 0, 0, 561, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 495, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 8122, 902, 0, 0, 8121, 8120, 0, 0, 0, 0, 0, 0, 0, 0, 7944, 7945, 0, 
+    0, 0, 0, 0, 8124, 0, 0, 0, 0, 0, 0, 0, 8136, 904, 0, 0, 0, 0, 7960, 7961, 
+    0, 0, 0, 0, 0, 8138, 905, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7976, 7977, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8140, 0, 0, 0, 0, 0, 0, 0, 8154, 
+    906, 0, 0, 8153, 8152, 0, 938, 0, 0, 0, 0, 0, 0, 7992, 7993, 0, 0, 0, 0, 
+    0, 8184, 908, 0, 0, 0, 0, 8008, 8009, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    8172, 0, 0, 0, 0, 0, 8170, 910, 0, 0, 8169, 8168, 0, 939, 0, 0, 0, 0, 0, 
+    0, 0, 8025, 0, 0, 0, 0, 0, 8186, 911, 0, 0, 0, 0, 8040, 8041, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 8188, 0, 0, 0, 0, 8116, 0, 0, 0, 0, 8132, 0, 
+    0, 0, 0, 0, 0, 0, 8048, 940, 0, 0, 8113, 8112, 0, 0, 0, 0, 0, 0, 0, 0, 
+    7936, 7937, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8118, 8115, 0, 0, 0, 0, 
+    0, 0, 0, 8050, 941, 0, 0, 0, 0, 7952, 7953, 0, 0, 0, 0, 0, 8052, 942, 0, 
+    0, 0, 0, 7968, 7969, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8134, 8131, 0, 
+    0, 0, 0, 0, 0, 0, 8054, 943, 0, 0, 8145, 8144, 0, 970, 0, 0, 0, 0, 0, 0, 
+    7984, 7985, 0, 0, 0, 0, 8150, 0, 0, 0, 0, 0, 0, 0, 0, 8056, 972, 0, 0, 0, 
+    0, 8000, 8001, 0, 0, 0, 8164, 8165, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 8058, 973, 0, 0, 8161, 8160, 0, 971, 0, 0, 0, 0, 0, 0, 8016, 8017, 0, 
+    0, 0, 0, 8166, 0, 0, 0, 0, 0, 0, 0, 0, 8060, 974, 0, 0, 0, 0, 8032, 8033, 
+    0, 0, 0, 0, 8182, 8179, 0, 0, 0, 0, 0, 0, 0, 8146, 912, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 8151, 0, 0, 0, 0, 0, 0, 0, 0, 8162, 944, 0, 0, 8167, 0, 0, 0, 
+    0, 0, 8180, 0, 0, 0, 0, 0, 0, 0, 0, 979, 0, 0, 0, 0, 0, 980, 0, 0, 0, 0, 
+    1031, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1232, 0, 1234, 0, 0, 0, 0, 0, 0, 
+    1027, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1024, 0, 0, 0, 0, 1238, 0, 1025, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1217, 0, 1244, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 1246, 0, 0, 0, 0, 0, 1037, 0, 0, 0, 1250, 1049, 0, 1252, 0, 0, 
+    0, 0, 0, 0, 1036, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1254, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 1262, 1038, 0, 1264, 0, 0, 1266, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    1268, 0, 0, 0, 0, 1272, 0, 0, 0, 0, 1260, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    1233, 0, 1235, 0, 0, 0, 0, 0, 0, 1107, 0, 0, 0, 1104, 0, 0, 0, 0, 1239, 
+    0, 1105, 0, 0, 1218, 0, 1245, 0, 0, 0, 0, 1247, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 1117, 0, 0, 0, 1251, 1081, 0, 1253, 0, 0, 0, 0, 0, 0, 
+    1116, 0, 0, 1255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1263, 1118, 0, 1265, 0, 0, 
+    1267, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1269, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 1273, 0, 0, 0, 0, 1261, 0, 0, 0, 0, 1111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    1142, 0, 0, 0, 0, 1143, 0, 0, 0, 0, 0, 0, 0, 1242, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 1243, 0, 0, 0, 0, 1258, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 1259, 0, 0, 0, 1570, 1571, 1573, 0, 0, 0, 1572, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 1574, 0, 0, 0, 0, 1730, 0, 0, 0, 0, 1747, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 1728, 0, 0, 0, 0, 0, 0, 2345, 0, 0, 0, 0, 2353, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2356, 0, 0, 0, 0, 0, 2507, 2508, 0, 0, 
+    0, 0, 0, 2891, 2888, 2892, 0, 0, 0, 0, 0, 0, 2964, 0, 0, 0, 3018, 3020, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3019, 0, 0, 0, 0, 0, 0, 3144, 0, 0, 0, 
+    0, 0, 0, 3264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3274, 3271, 3272, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 3275, 0, 0, 0, 0, 0, 0, 3402, 3404, 0, 0, 0, 
+    3403, 0, 0, 0, 0, 0, 0, 3546, 3548, 3550, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    3549, 0, 0, 0, 0, 0, 0, 0, 4134, 0, 0, 0, 0, 0, 0, 7736, 0, 0, 0, 0, 
+    7737, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7772, 0, 0, 0, 0, 7773, 0, 0, 
+    0, 0, 0, 0, 7784, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7785, 7852, 0, 0, 
+    7862, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7853, 0, 0, 7863, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 7878, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7879, 0, 0, 0, 0, 7896, 
+    0, 0, 0, 0, 7897, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7938, 7940, 0, 0, 7942, 
+    8064, 0, 0, 0, 0, 0, 0, 0, 7939, 7941, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    7943, 8065, 0, 0, 0, 0, 8066, 0, 0, 0, 0, 8067, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 8068, 0, 0, 0, 0, 8069, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    8070, 0, 0, 0, 0, 8071, 0, 0, 0, 0, 0, 0, 0, 7946, 7948, 0, 0, 7950, 
+    8072, 0, 0, 0, 0, 0, 0, 0, 7947, 7949, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    7951, 8073, 0, 0, 0, 0, 8074, 0, 0, 0, 0, 8075, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 8076, 0, 0, 0, 0, 8077, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    8078, 0, 0, 0, 0, 8079, 0, 0, 0, 0, 0, 0, 0, 7954, 7956, 0, 0, 0, 7955, 
+    7957, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7962, 7964, 0, 0, 0, 7963, 7965, 
+    0, 0, 0, 7970, 7972, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7974, 8080, 0, 0, 0, 
+    0, 0, 0, 0, 7971, 7973, 0, 0, 7975, 8081, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 8082, 0, 0, 0, 0, 8083, 0, 0, 0, 0, 8084, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 8085, 0, 0, 0, 0, 8086, 0, 0, 0, 0, 8087, 0, 0, 0, 0, 0, 0, 
+    0, 7978, 7980, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7982, 8088, 0, 0, 0, 0, 0, 
+    0, 0, 7979, 7981, 0, 0, 7983, 8089, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    8090, 0, 0, 0, 0, 8091, 0, 0, 0, 0, 8092, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 8093, 0, 0, 0, 0, 8094, 0, 0, 0, 0, 8095, 0, 0, 0, 0, 0, 0, 0, 
+    7986, 7988, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7990, 0, 0, 0, 0, 0, 0, 0, 0, 
+    7987, 7989, 0, 0, 7991, 0, 0, 0, 0, 0, 0, 0, 0, 7994, 7996, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 7998, 0, 0, 0, 0, 0, 0, 0, 0, 7995, 7997, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 7999, 0, 0, 0, 0, 0, 0, 0, 0, 8002, 8004, 0, 0, 0, 
+    8003, 8005, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8010, 8012, 0, 0, 0, 8011, 
+    8013, 0, 0, 0, 8018, 8020, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8022, 0, 0, 0, 
+    0, 0, 0, 0, 0, 8019, 8021, 0, 0, 8023, 0, 0, 0, 0, 0, 0, 0, 0, 8027, 
+    8029, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8031, 0, 0, 0, 0, 0, 0, 0, 0, 8034, 
+    8036, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8038, 8096, 0, 0, 0, 0, 0, 0, 0, 
+    8035, 8037, 0, 0, 8039, 8097, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8098, 
+    0, 0, 0, 0, 8099, 0, 0, 0, 0, 8100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    8101, 0, 0, 0, 0, 8102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8103, 0, 0, 
+    0, 0, 0, 0, 0, 8042, 8044, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8046, 8104, 0, 
+    0, 0, 0, 0, 0, 0, 8043, 8045, 0, 0, 8047, 8105, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 8106, 0, 0, 0, 0, 8107, 0, 0, 0, 0, 8108, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 8109, 0, 0, 0, 0, 8110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 8111, 0, 0, 0, 0, 8114, 0, 0, 0, 0, 8130, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 8178, 0, 0, 0, 0, 8119, 0, 0, 0, 0, 0, 0, 0, 8141, 8142, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 8143, 0, 0, 0, 0, 0, 8135, 0, 0, 0, 0, 8183, 
+    0, 0, 0, 0, 0, 0, 0, 8157, 8158, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8159, 0, 
+    0, 0, 8602, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8603, 0, 0, 0, 0, 8622, 
+    0, 0, 0, 0, 8653, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8655, 0, 0, 0, 0, 
+    8654, 0, 0, 0, 0, 8708, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8713, 0, 0, 
+    0, 0, 8716, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8740, 0, 0, 0, 0, 8742, 
+    0, 0, 0, 0, 8769, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8772, 0, 0, 0, 0, 
+    8775, 0, 0, 0, 0, 8777, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8813, 0, 0, 
+    0, 0, 8802, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8816, 0, 0, 0, 0, 8817, 
+    0, 0, 0, 0, 8820, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8821, 0, 0, 0, 0, 
+    8824, 0, 0, 0, 0, 8825, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8832, 0, 0, 
+    0, 0, 8833, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8928, 0, 0, 0, 0, 8929, 
+    0, 0, 0, 0, 8836, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8837, 0, 0, 0, 0, 
+    8840, 0, 0, 0, 0, 8841, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8930, 0, 0, 
+    0, 0, 8931, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8876, 0, 0, 0, 0, 8877, 
+    0, 0, 0, 0, 8878, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8879, 0, 0, 0, 0, 
+    8938, 0, 0, 0, 0, 8939, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8940, 0, 0, 
+    0, 0, 8941, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12436, 0, 0, 0, 0, 12364, 
+    0, 0, 0, 0, 12366, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12368, 0, 0, 0, 0, 
+    12370, 0, 0, 0, 0, 12372, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12374, 0, 
+    0, 0, 0, 12376, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12378, 0, 0, 0, 0, 
+    12380, 0, 0, 0, 0, 12382, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12384, 0, 
+    0, 0, 0, 12386, 0, 0, 0, 0, 12389, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    12391, 0, 0, 0, 0, 12393, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12400, 
+    12401, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12403, 12404, 0, 0, 0, 12406, 
+    12407, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12409, 12410, 0, 0, 0, 12412, 
+    12413, 0, 0, 0, 12446, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12532, 0, 0, 
+    0, 0, 12460, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12462, 0, 0, 0, 0, 
+    12464, 0, 0, 0, 0, 12466, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12468, 0, 
+    0, 0, 0, 12470, 0, 0, 0, 0, 12472, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    12474, 0, 0, 0, 0, 12476, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12478, 0, 
+    0, 0, 0, 12480, 0, 0, 0, 0, 12482, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    12485, 0, 0, 0, 0, 12487, 0, 0, 0, 0, 12489, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 12496, 12497, 0, 0, 0, 12499, 12500, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 12502, 12503, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12505, 12506, 0, 0, 
+    0, 12508, 12509, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12535, 0, 0, 0, 0, 
+    12536, 0, 0, 0, 0, 12537, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12538, 0, 
+    0, 0, 0, 12542, 0, 
+};
+
+static const change_record change_records_3_2_0[] = {
+	{ 255, 255, 255, 0 },
+	{ 11, 255, 255, 0 },
+	{ 10, 255, 255, 0 },
+	{ 19, 21, 255, 0 },
+	{ 255, 255, 2, 0 },
+	{ 255, 255, 3, 0 },
+	{ 255, 255, 1, 0 },
+	{ 255, 0, 255, 0 },
+	{ 255, 29, 255, 0 },
+	{ 14, 255, 255, 0 },
+	{ 255, 7, 1, 0 },
+	{ 255, 7, 2, 0 },
+	{ 255, 7, 3, 0 },
+	{ 255, 7, 4, 0 },
+	{ 255, 7, 5, 0 },
+	{ 255, 7, 6, 0 },
+	{ 255, 7, 7, 0 },
+	{ 255, 7, 8, 0 },
+	{ 255, 7, 9, 0 },
+	{ 255, 5, 255, 0 },
+	{ 15, 14, 255, 0 },
+	{ 255, 10, 255, 0 },
+	{ 18, 255, 255, 0 },
+	{ 19, 255, 255, 0 },
+	{ 255, 255, 0, 0 },
+	{ 255, 255, 4, 0 },
+	{ 255, 255, 5, 0 },
+	{ 255, 255, 6, 0 },
+	{ 255, 255, 7, 0 },
+	{ 255, 255, 8, 0 },
+	{ 255, 255, 9, 0 },
+	{ 9, 255, 255, 0 },
+	{ 255, 20, 255, 0 },
+	{ 255, 19, 255, 0 },
+	{ 15, 255, 255, 0 },
+	{ 255, 255, 255, -1 },
+};
+static unsigned char changes_3_2_0_index[] = {
+    0, 1, 2, 2, 3, 4, 5, 6, 2, 7, 2, 8, 9, 10, 11, 2, 2, 2, 12, 13, 14, 15, 
+    16, 17, 2, 18, 2, 2, 2, 2, 2, 19, 2, 20, 2, 2, 21, 22, 23, 24, 2, 2, 2, 
+    2, 2, 2, 2, 25, 26, 2, 27, 28, 29, 2, 2, 2, 2, 2, 30, 31, 2, 2, 2, 2, 32, 
+    33, 34, 2, 35, 2, 2, 36, 37, 38, 2, 2, 39, 40, 2, 41, 42, 42, 2, 2, 2, 2, 
+    43, 2, 44, 45, 46, 47, 48, 2, 2, 2, 2, 49, 2, 50, 51, 52, 53, 54, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 55, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 56, 57, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 58, 2, 59, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 60, 61, 62, 2, 2, 2, 2, 63, 64, 2, 65, 66, 
+    67, 68, 69, 70, 2, 2, 71, 72, 73, 74, 2, 2, 2, 2, 2, 2, 75, 2, 2, 2, 76, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 77, 2, 78, 2, 2, 79, 2, 2, 
+    2, 80, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 30, 81, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+};
+
+static unsigned char changes_3_2_0_data[] = {
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 2, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 4, 5, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 
+    0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 9, 0, 0, 0, 0, 0, 0, 9, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 7, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0, 
+    0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 19, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 
+    0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 7, 0, 0, 0, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 7, 7, 7, 7, 7, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 
+    0, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 25, 26, 27, 28, 29, 30, 1, 
+    1, 0, 0, 0, 0, 24, 6, 4, 5, 25, 26, 27, 28, 29, 30, 1, 1, 0, 0, 0, 0, 7, 
+    7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 31, 31, 31, 31, 31, 31, 
+    31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 
+    31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 7, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 23, 23, 
+    23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
+    23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
+    23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
+    23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
+    23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
+    23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
+    23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 0, 7, 7, 
+    7, 7, 7, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 0, 7, 7, 
+    7, 7, 7, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 0, 7, 7, 
+    7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 2, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 34, 34, 0, 0, 0, 0, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 7, 7, 7, 0, 0, 0, 0, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 0, 0, 7, 
+    0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 7, 7, 
+    0, 0, 0, 7, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 
+    7, 7, 7, 0, 7, 7, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 0, 7, 7, 7, 0, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 0, 0, 0, 0, 7, 7, 7, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 
+    0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+    7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+};
+
+static const change_record* get_change_3_2_0(Py_UCS4 n)
+{
+	int index;
+	if (n >= 0x110000) index = 0;
+	else {
+		index = changes_3_2_0_index[n>>7];
+		index = changes_3_2_0_data[(index<<7)+(n & 127)];
+	}
+	return change_records_3_2_0+index;
+}
+
+static Py_UCS4 normalization_3_2_0(Py_UCS4 n)
+{
+	switch(n) {
+	case 0x2f868: return 0x2136A;
+	case 0x2f874: return 0x5F33;
+	case 0x2f91f: return 0x43AB;
+	case 0x2f95f: return 0x7AAE;
+	case 0x2f9bf: return 0x4D57;
+	default: return 0;
+	}
+}
+

Added: vendor/Python/current/Modules/unicodename_db.h
===================================================================
--- vendor/Python/current/Modules/unicodename_db.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/unicodename_db.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,12543 @@
+/* this file was generated by Tools/unicode/makeunicodedata.py 2.5 */
+
+#define NAME_MAXLEN 256
+
+/* lexicon */
+static unsigned char lexicon[] = {
+    76, 69, 84, 84, 69, 210, 87, 73, 84, 200, 83, 77, 65, 76, 204, 83, 89, 
+    76, 76, 65, 66, 76, 197, 67, 65, 80, 73, 84, 65, 204, 89, 201, 67, 74, 
+    203, 76, 65, 84, 73, 206, 67, 79, 77, 80, 65, 84, 73, 66, 73, 76, 73, 84, 
+    217, 77, 65, 84, 72, 69, 77, 65, 84, 73, 67, 65, 204, 65, 82, 65, 66, 73, 
+    195, 83, 89, 77, 66, 79, 204, 70, 79, 82, 77, 128, 67, 65, 78, 65, 68, 
+    73, 65, 206, 83, 89, 76, 76, 65, 66, 73, 67, 211, 66, 79, 76, 196, 71, 
+    82, 69, 69, 203, 76, 73, 71, 65, 84, 85, 82, 197, 65, 78, 196, 77, 85, 
+    83, 73, 67, 65, 204, 83, 73, 71, 206, 69, 84, 72, 73, 79, 80, 73, 195, 
+    72, 65, 78, 71, 85, 204, 73, 84, 65, 76, 73, 195, 82, 65, 68, 73, 67, 65, 
+    204, 68, 73, 71, 73, 212, 83, 65, 78, 83, 45, 83, 69, 82, 73, 198, 70, 
+    79, 210, 67, 73, 82, 67, 76, 69, 196, 70, 73, 78, 65, 204, 83, 81, 85, 
+    65, 82, 197, 67, 89, 82, 73, 76, 76, 73, 195, 86, 79, 87, 69, 204, 86, 
+    65, 82, 73, 65, 84, 73, 79, 206, 66, 82, 65, 73, 76, 76, 197, 80, 65, 84, 
+    84, 69, 82, 206, 66, 89, 90, 65, 78, 84, 73, 78, 197, 82, 73, 71, 72, 
+    212, 73, 83, 79, 76, 65, 84, 69, 196, 76, 69, 70, 212, 194, 75, 65, 84, 
+    65, 75, 65, 78, 193, 75, 65, 78, 71, 88, 201, 76, 73, 78, 69, 65, 210, 
+    68, 79, 85, 66, 76, 197, 66, 69, 76, 79, 87, 128, 84, 73, 66, 69, 84, 65, 
+    206, 65, 66, 79, 86, 69, 128, 77, 79, 68, 73, 70, 73, 69, 210, 67, 79, 
+    77, 66, 73, 78, 73, 78, 199, 77, 69, 69, 205, 83, 73, 71, 78, 128, 68, 
+    79, 212, 73, 78, 73, 84, 73, 65, 204, 67, 65, 82, 82, 73, 69, 210, 65, 
+    82, 82, 79, 87, 128, 89, 69, 200, 77, 79, 78, 71, 79, 76, 73, 65, 206, 
+    86, 69, 82, 84, 73, 67, 65, 204, 65, 66, 79, 86, 197, 78, 85, 77, 66, 69, 
+    210, 67, 79, 80, 84, 73, 195, 75, 72, 77, 69, 210, 87, 72, 73, 84, 197, 
+    65, 82, 82, 79, 215, 66, 79, 216, 65, 128, 72, 69, 66, 82, 69, 215, 77, 
+    65, 82, 75, 128, 68, 82, 65, 87, 73, 78, 71, 211, 73, 128, 79, 128, 72, 
+    65, 76, 70, 87, 73, 68, 84, 200, 71, 69, 79, 82, 71, 73, 65, 206, 82, 73, 
+    71, 72, 84, 87, 65, 82, 68, 211, 73, 68, 69, 79, 71, 82, 65, 205, 85, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 73, 195, 84, 65, 201, 80, 65, 
+    82, 69, 78, 84, 72, 69, 83, 73, 90, 69, 196, 65, 76, 69, 198, 83, 67, 82, 
+    73, 80, 212, 68, 69, 86, 65, 78, 65, 71, 65, 82, 201, 66, 76, 65, 67, 
+    203, 84, 79, 128, 85, 208, 70, 85, 76, 76, 87, 73, 68, 84, 200, 72, 79, 
+    79, 75, 128, 83, 89, 77, 66, 79, 76, 128, 68, 79, 87, 206, 70, 82, 65, 
+    75, 84, 85, 210, 72, 65, 200, 69, 81, 85, 65, 204, 72, 69, 65, 86, 217, 
+    84, 65, 199, 71, 76, 65, 71, 79, 76, 73, 84, 73, 195, 67, 72, 65, 82, 65, 
+    67, 84, 69, 210, 65, 82, 77, 69, 78, 73, 65, 206, 66, 69, 78, 71, 65, 76, 
+    201, 67, 72, 79, 83, 69, 79, 78, 199, 74, 69, 69, 205, 66, 82, 65, 67, 
+    75, 69, 84, 128, 72, 73, 82, 65, 71, 65, 78, 193, 87, 69, 83, 84, 45, 67, 
+    82, 69, 197, 84, 72, 65, 201, 83, 84, 82, 79, 75, 69, 128, 67, 72, 69, 
+    82, 79, 75, 69, 197, 73, 68, 69, 79, 71, 82, 65, 80, 200, 84, 87, 79, 
+    128, 71, 85, 74, 65, 82, 65, 84, 201, 77, 69, 68, 73, 65, 204, 74, 79, 
+    78, 71, 83, 69, 79, 78, 199, 75, 65, 78, 78, 65, 68, 193, 78, 69, 215, 
+    207, 79, 82, 73, 89, 193, 82, 85, 78, 73, 195, 84, 69, 84, 82, 65, 71, 
+    82, 65, 205, 68, 69, 83, 69, 82, 69, 212, 76, 85, 197, 83, 73, 78, 72, 
+    65, 76, 193, 84, 69, 76, 85, 71, 213, 66, 65, 82, 128, 78, 79, 84, 65, 
+    84, 73, 79, 206, 79, 78, 69, 128, 83, 89, 82, 73, 65, 195, 77, 65, 76, 
+    65, 89, 65, 76, 65, 205, 77, 89, 65, 78, 77, 65, 210, 71, 85, 82, 77, 85, 
+    75, 72, 201, 65, 67, 85, 84, 69, 128, 76, 73, 71, 72, 212, 72, 65, 76, 
+    198, 68, 79, 85, 66, 76, 69, 45, 83, 84, 82, 85, 67, 203, 76, 69, 70, 84, 
+    87, 65, 82, 68, 211, 84, 65, 77, 73, 204, 65, 80, 204, 70, 85, 78, 67, 
+    84, 73, 79, 78, 65, 204, 72, 65, 77, 90, 193, 84, 69, 76, 69, 71, 82, 65, 
+    80, 200, 74, 85, 78, 71, 83, 69, 79, 78, 199, 79, 198, 68, 65, 83, 73, 
+    193, 76, 73, 77, 66, 213, 77, 65, 75, 83, 85, 82, 193, 75, 72, 65, 82, 
+    79, 83, 72, 84, 72, 201, 76, 65, 207, 84, 207, 66, 65, 82, 194, 66, 79, 
+    80, 79, 77, 79, 70, 207, 72, 69, 88, 65, 71, 82, 65, 205, 77, 65, 82, 
+    203, 80, 83, 73, 76, 201, 77, 79, 78, 79, 83, 80, 65, 67, 197, 78, 79, 
+    212, 72, 79, 82, 73, 90, 79, 78, 84, 65, 204, 75, 72, 65, 200, 86, 79, 
+    67, 65, 76, 73, 195, 84, 72, 82, 69, 69, 128, 65, 69, 71, 69, 65, 206, 
+    76, 79, 87, 69, 210, 84, 73, 76, 68, 69, 128, 76, 79, 215, 84, 87, 207, 
+    67, 89, 80, 82, 73, 79, 212, 84, 73, 70, 73, 78, 65, 71, 200, 68, 73, 65, 
+    69, 82, 69, 83, 73, 83, 128, 70, 73, 86, 69, 128, 70, 79, 85, 82, 128, 
+    78, 85, 77, 69, 82, 65, 204, 86, 128, 65, 67, 82, 79, 80, 72, 79, 78, 73, 
+    195, 68, 79, 84, 211, 76, 79, 78, 199, 80, 69, 82, 83, 73, 65, 206, 65, 
+    78, 71, 76, 197, 72, 65, 82, 80, 79, 79, 206, 83, 73, 88, 128, 84, 79, 
+    78, 197, 85, 80, 80, 69, 210, 67, 73, 82, 67, 85, 77, 70, 76, 69, 216, 
+    71, 82, 65, 86, 69, 128, 72, 128, 65, 76, 80, 72, 193, 69, 73, 71, 72, 
+    84, 128, 77, 65, 67, 82, 79, 78, 128, 78, 79, 79, 206, 84, 72, 65, 65, 
+    78, 193, 72, 73, 71, 200, 75, 65, 128, 78, 73, 78, 69, 128, 83, 69, 86, 
+    69, 78, 128, 84, 72, 82, 69, 197, 84, 85, 82, 78, 69, 196, 83, 72, 65, 
+    86, 73, 65, 206, 83, 84, 79, 80, 128, 68, 128, 71, 128, 79, 77, 69, 71, 
+    193, 79, 88, 73, 65, 128, 83, 85, 66, 74, 79, 73, 78, 69, 196, 86, 65, 
+    82, 73, 65, 128, 89, 65, 128, 66, 128, 67, 73, 82, 67, 76, 197, 72, 65, 
+    128, 74, 128, 77, 65, 128, 82, 69, 86, 69, 82, 83, 69, 196, 82, 73, 71, 
+    72, 84, 128, 85, 80, 87, 65, 82, 68, 211, 80, 65, 83, 83, 73, 86, 69, 45, 
+    80, 85, 76, 76, 45, 68, 79, 87, 78, 45, 79, 85, 84, 80, 85, 212, 66, 89, 
+    69, 76, 79, 82, 85, 83, 83, 73, 65, 78, 45, 85, 75, 82, 65, 73, 78, 73, 
+    65, 206, 67, 69, 79, 78, 71, 67, 72, 73, 69, 85, 77, 83, 83, 65, 78, 71, 
+    67, 73, 69, 85, 67, 128, 80, 65, 83, 83, 73, 86, 69, 45, 80, 85, 76, 76, 
+    45, 85, 80, 45, 79, 85, 84, 80, 85, 212, 65, 78, 84, 73, 67, 76, 79, 67, 
+    75, 87, 73, 83, 69, 45, 82, 79, 84, 65, 84, 69, 196, 67, 69, 79, 78, 71, 
+    67, 72, 73, 69, 85, 77, 83, 83, 65, 78, 71, 83, 73, 79, 83, 128, 80, 83, 
+    73, 70, 73, 83, 84, 79, 80, 65, 82, 65, 75, 65, 76, 69, 83, 77, 65, 128, 
+    82, 73, 69, 85, 76, 45, 75, 65, 80, 89, 69, 79, 85, 78, 80, 73, 69, 85, 
+    80, 128, 75, 65, 80, 89, 69, 79, 85, 78, 83, 83, 65, 78, 71, 80, 73, 69, 
+    85, 80, 128, 79, 80, 69, 78, 45, 67, 73, 82, 67, 85, 73, 84, 45, 79, 85, 
+    84, 80, 85, 212, 67, 69, 79, 78, 71, 67, 72, 73, 69, 85, 77, 67, 72, 73, 
+    69, 85, 67, 72, 128, 67, 72, 73, 84, 85, 69, 85, 77, 83, 83, 65, 78, 71, 
+    67, 73, 69, 85, 67, 128, 75, 73, 89, 69, 79, 75, 45, 83, 73, 79, 83, 45, 
+    75, 73, 89, 69, 79, 75, 128, 82, 73, 69, 85, 76, 45, 77, 73, 69, 85, 77, 
+    45, 75, 73, 89, 69, 79, 75, 128, 82, 73, 69, 85, 76, 45, 84, 73, 75, 69, 
+    85, 84, 45, 72, 73, 69, 85, 72, 128, 84, 82, 79, 77, 73, 75, 79, 80, 65, 
+    82, 65, 75, 65, 76, 69, 83, 77, 65, 128, 80, 73, 69, 85, 80, 45, 83, 73, 
+    79, 83, 45, 75, 73, 89, 69, 79, 75, 128, 80, 73, 69, 85, 80, 45, 83, 73, 
+    79, 83, 45, 84, 73, 75, 69, 85, 84, 128, 82, 73, 69, 85, 76, 45, 75, 73, 
+    89, 69, 79, 75, 45, 83, 73, 79, 83, 128, 82, 73, 69, 85, 76, 45, 89, 69, 
+    79, 82, 73, 78, 72, 73, 69, 85, 72, 128, 67, 72, 73, 84, 85, 69, 85, 77, 
+    83, 83, 65, 78, 71, 83, 73, 79, 83, 128, 73, 69, 85, 78, 71, 45, 83, 83, 
+    65, 78, 71, 75, 73, 89, 69, 79, 75, 128, 76, 79, 78, 71, 45, 66, 82, 65, 
+    78, 67, 72, 45, 72, 65, 71, 65, 76, 204, 80, 65, 82, 84, 73, 65, 76, 76, 
+    89, 45, 82, 69, 67, 89, 67, 76, 69, 196, 82, 73, 69, 85, 76, 45, 80, 73, 
+    69, 85, 80, 45, 72, 73, 69, 85, 72, 128, 83, 72, 79, 82, 84, 45, 84, 87, 
+    73, 71, 45, 66, 74, 65, 82, 75, 65, 206, 83, 73, 79, 83, 45, 80, 73, 69, 
+    85, 80, 45, 75, 73, 89, 69, 79, 75, 128, 75, 65, 84, 65, 75, 65, 78, 65, 
+    45, 72, 73, 82, 65, 71, 65, 78, 193, 82, 73, 69, 85, 76, 45, 80, 73, 69, 
+    85, 80, 45, 83, 73, 79, 83, 128, 89, 69, 83, 73, 69, 85, 78, 71, 45, 80, 
+    65, 78, 83, 73, 79, 83, 128, 67, 69, 79, 78, 71, 67, 72, 73, 69, 85, 77, 
+    67, 73, 69, 85, 67, 128, 77, 65, 82, 67, 65, 84, 79, 45, 83, 84, 65, 67, 
+    67, 65, 84, 79, 128, 80, 73, 69, 85, 80, 45, 83, 73, 79, 83, 45, 67, 73, 
+    69, 85, 67, 128, 80, 73, 69, 85, 80, 45, 83, 73, 79, 83, 45, 80, 73, 69, 
+    85, 80, 128, 82, 73, 69, 85, 76, 45, 77, 73, 69, 85, 77, 45, 83, 73, 79, 
+    83, 128, 83, 72, 79, 82, 84, 45, 84, 87, 73, 71, 45, 72, 65, 71, 65, 76, 
+    204, 83, 79, 70, 84, 87, 65, 82, 69, 45, 70, 85, 78, 67, 84, 73, 79, 206, 
+    84, 82, 79, 77, 73, 75, 79, 80, 83, 73, 70, 73, 83, 84, 79, 78, 128, 75, 
+    65, 80, 89, 69, 79, 85, 78, 80, 72, 73, 69, 85, 80, 72, 128, 65, 78, 84, 
+    73, 82, 69, 83, 84, 82, 73, 67, 84, 73, 79, 78, 128, 65, 67, 67, 69, 78, 
+    84, 45, 83, 84, 65, 67, 67, 65, 84, 79, 128, 65, 78, 84, 73, 75, 69, 78, 
+    79, 75, 89, 76, 73, 83, 77, 65, 128, 67, 69, 79, 78, 71, 67, 72, 73, 69, 
+    85, 77, 83, 73, 79, 83, 128, 67, 72, 73, 69, 85, 67, 72, 45, 75, 72, 73, 
+    69, 85, 75, 72, 128, 67, 72, 73, 84, 85, 69, 85, 77, 67, 72, 73, 69, 85, 
+    67, 72, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 48, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 49, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 50, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 51, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 56, 48, 52, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 56, 48, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 56, 48, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 56, 48, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 
+    48, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 57, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 65, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 66, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 67, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 56, 48, 68, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 56, 48, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 56, 48, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 56, 49, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 
+    49, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 50, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 51, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 52, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 53, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 56, 49, 54, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 56, 49, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 56, 49, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 56, 49, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 
+    49, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 66, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 67, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 68, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 69, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 56, 49, 70, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 56, 50, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 56, 50, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 56, 50, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 
+    50, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 52, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 53, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 54, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 55, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 56, 50, 56, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 56, 50, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 56, 50, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 56, 50, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 
+    50, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 68, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 69, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 70, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 48, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 56, 51, 49, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 56, 51, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 56, 51, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 56, 51, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 
+    51, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 54, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 55, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 56, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 57, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 56, 51, 65, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 56, 51, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 56, 51, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 56, 51, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 
+    51, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 70, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 48, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 49, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 50, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 56, 52, 51, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 56, 52, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 56, 52, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 56, 52, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 
+    52, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 56, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 57, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 65, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 66, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 56, 52, 67, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 56, 52, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 56, 52, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 56, 52, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 
+    53, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 49, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 50, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 51, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 52, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 56, 53, 53, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 56, 53, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 56, 53, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 56, 53, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 
+    53, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 65, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 66, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 67, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 68, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 56, 53, 69, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 56, 53, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 56, 54, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 56, 54, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 
+    54, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 51, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 52, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 53, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 54, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 56, 54, 55, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 56, 54, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 56, 54, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 56, 54, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 
+    54, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 67, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 68, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 69, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 70, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 56, 55, 48, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 56, 55, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 56, 55, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 56, 55, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 
+    55, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 53, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 54, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 55, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 56, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 56, 55, 57, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 56, 55, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 56, 55, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 56, 55, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 
+    55, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 69, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 70, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 48, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 49, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 56, 56, 50, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 56, 56, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 56, 56, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 56, 56, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 
+    56, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 55, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 56, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 57, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 65, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 56, 56, 66, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 56, 56, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 56, 56, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 56, 56, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 
+    56, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 48, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 49, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 50, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 51, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 56, 57, 52, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 56, 57, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 56, 57, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 56, 57, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 
+    57, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 57, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 65, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 66, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 67, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 56, 57, 68, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 56, 57, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 56, 57, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 56, 65, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 
+    65, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 50, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 51, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 52, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 53, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 56, 65, 54, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 56, 65, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 56, 65, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 56, 65, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 
+    65, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 66, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 67, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 68, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 69, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 56, 65, 70, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 56, 66, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 56, 66, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 56, 66, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 
+    66, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 52, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 53, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 54, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 55, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 56, 66, 56, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 56, 66, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 56, 66, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 56, 66, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 
+    66, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 68, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 69, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 70, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 48, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 56, 67, 49, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 56, 67, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 56, 67, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 56, 67, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 
+    67, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 54, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 55, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 56, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 57, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 56, 67, 65, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 56, 67, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 56, 67, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 56, 67, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 
+    67, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 70, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 48, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 49, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 50, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 56, 68, 51, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 56, 68, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 56, 68, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 56, 68, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 
+    68, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 56, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 57, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 65, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 66, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 56, 68, 67, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 56, 68, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 56, 68, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 56, 68, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 
+    69, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 49, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 50, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 51, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 52, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 56, 69, 53, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 56, 69, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 56, 69, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 56, 69, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 
+    69, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 65, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 66, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 67, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 68, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 56, 69, 69, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 56, 69, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 56, 70, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 56, 70, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 
+    70, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 51, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 52, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 53, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 54, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 56, 70, 55, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 56, 70, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 56, 70, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 56, 70, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 
+    70, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 67, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 68, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 69, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 70, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 57, 48, 48, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 57, 48, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 57, 48, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 57, 48, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 
+    48, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 53, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 54, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 55, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 56, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 57, 48, 57, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 57, 48, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 57, 48, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 57, 48, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 
+    48, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 69, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 70, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 48, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 49, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 57, 49, 50, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 57, 49, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 57, 49, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 57, 49, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 
+    49, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 55, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 56, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 57, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 65, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 57, 49, 66, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 57, 49, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 57, 49, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 57, 49, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 
+    49, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 48, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 49, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 50, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 51, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 57, 50, 52, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 57, 50, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 57, 50, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 57, 50, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 
+    50, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 57, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 65, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 66, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 67, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 57, 50, 68, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 57, 50, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 57, 50, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 57, 51, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 
+    51, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 50, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 51, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 52, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 53, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 57, 51, 54, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 57, 51, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 57, 51, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 57, 51, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 
+    51, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 66, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 67, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 68, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 69, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 57, 51, 70, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 57, 52, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 57, 52, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 57, 52, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 
+    52, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 52, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 53, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 54, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 55, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 57, 52, 56, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 57, 52, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 57, 52, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 57, 52, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 
+    52, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 68, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 69, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 70, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 48, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 57, 53, 49, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 57, 53, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 57, 53, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 57, 53, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 
+    53, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 54, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 55, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 56, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 57, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 57, 53, 65, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 57, 53, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 57, 53, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 57, 53, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 
+    53, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 70, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 48, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 49, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 50, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 57, 54, 51, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 57, 54, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 57, 54, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 57, 54, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 
+    54, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 56, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 57, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 65, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 66, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 57, 54, 67, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 57, 54, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 57, 54, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 57, 54, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 
+    55, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 49, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 50, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 51, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 52, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 57, 55, 53, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 57, 55, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 57, 55, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 57, 55, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 
+    55, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 65, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 66, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 67, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 68, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 57, 55, 69, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 57, 55, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 57, 56, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 57, 56, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 
+    56, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 51, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 52, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 53, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 54, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 57, 56, 55, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 57, 56, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 57, 56, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 57, 56, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 
+    56, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 67, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 68, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 69, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 70, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 57, 57, 48, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 57, 57, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 57, 57, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 57, 57, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 
+    57, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 53, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 54, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 55, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 56, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 57, 57, 57, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 57, 57, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 57, 57, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 57, 57, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 
+    57, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 69, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 70, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 48, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 49, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 57, 65, 50, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 57, 65, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 57, 65, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 57, 65, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 
+    65, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 55, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 56, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 57, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 65, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 57, 65, 66, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 57, 65, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 57, 65, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 57, 65, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 
+    65, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 48, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 49, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 50, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 51, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 57, 66, 52, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 57, 66, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 57, 66, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 57, 66, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 
+    66, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 57, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 65, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 66, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 67, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 57, 66, 68, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 57, 66, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 57, 66, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 57, 67, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 
+    67, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 50, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 51, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 52, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 53, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 57, 67, 54, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 57, 67, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 57, 67, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 57, 67, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 
+    67, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 66, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 67, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 68, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 69, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 57, 67, 70, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 57, 68, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 57, 68, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 57, 68, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 
+    68, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 52, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 53, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 54, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 55, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 57, 68, 56, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 57, 68, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 57, 68, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 57, 68, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 
+    68, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 68, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 69, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 70, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 48, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 57, 69, 49, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 57, 69, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 57, 69, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 57, 69, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 
+    69, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 54, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 55, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 56, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 57, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 57, 69, 65, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 57, 69, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 57, 69, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 57, 69, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 
+    69, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 70, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 48, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 49, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 50, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 57, 70, 51, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 57, 70, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 57, 70, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 57, 70, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 
+    70, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 56, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 57, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 65, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 66, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 57, 70, 67, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 57, 70, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 57, 70, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 57, 70, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 
+    48, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 49, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 50, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 51, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 52, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 65, 48, 53, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 65, 48, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 65, 48, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 65, 48, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 
+    48, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 65, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 66, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 67, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 68, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 65, 48, 69, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 65, 48, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 65, 49, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 65, 49, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 
+    49, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 51, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 52, 128, 73, 
+    68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 53, 128, 73, 68, 69, 
+    79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 54, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 50, 70, 65, 49, 55, 128, 73, 68, 69, 79, 71, 82, 65, 
+    80, 72, 45, 50, 70, 65, 49, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 
+    45, 50, 70, 65, 49, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 
+    70, 65, 49, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 
+    49, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 67, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 68, 128, 74, 
+    65, 76, 76, 65, 74, 65, 76, 65, 76, 79, 85, 72, 79, 85, 128, 75, 82, 65, 
+    84, 73, 77, 79, 75, 79, 85, 70, 73, 83, 77, 65, 128, 75, 82, 65, 84, 73, 
+    77, 79, 89, 80, 79, 82, 82, 79, 79, 78, 128, 76, 79, 78, 71, 45, 66, 82, 
+    65, 78, 67, 72, 45, 77, 65, 68, 210, 77, 73, 69, 85, 77, 45, 83, 83, 65, 
+    78, 71, 83, 73, 79, 83, 128, 80, 69, 84, 65, 83, 84, 79, 75, 79, 85, 70, 
+    73, 83, 77, 65, 128, 80, 73, 69, 85, 80, 45, 83, 83, 65, 78, 71, 83, 73, 
+    79, 83, 128, 80, 83, 73, 70, 73, 83, 84, 79, 76, 89, 71, 73, 83, 77, 65, 
+    128, 80, 83, 73, 70, 73, 83, 84, 79, 83, 89, 78, 65, 71, 77, 65, 128, 82, 
+    73, 69, 85, 76, 45, 83, 83, 65, 78, 71, 83, 73, 79, 83, 128, 84, 69, 65, 
+    82, 68, 82, 79, 80, 45, 83, 72, 65, 78, 75, 69, 196, 80, 82, 79, 83, 71, 
+    69, 71, 82, 65, 77, 77, 69, 78, 73, 128, 84, 69, 65, 82, 68, 82, 79, 80, 
+    45, 83, 80, 79, 75, 69, 196, 66, 76, 65, 67, 75, 45, 70, 69, 65, 84, 72, 
+    69, 82, 69, 196, 84, 82, 73, 65, 78, 71, 76, 69, 45, 72, 69, 65, 68, 69, 
+    196, 67, 79, 78, 71, 82, 65, 84, 85, 76, 65, 84, 73, 79, 78, 128, 72, 73, 
+    71, 72, 45, 82, 69, 86, 69, 82, 83, 69, 68, 45, 185, 65, 70, 79, 82, 69, 
+    77, 69, 78, 84, 73, 79, 78, 69, 68, 128, 65, 82, 79, 85, 78, 68, 45, 80, 
+    82, 79, 70, 73, 76, 69, 128, 67, 79, 78, 67, 65, 86, 69, 45, 80, 79, 73, 
+    78, 84, 69, 196, 71, 79, 82, 71, 79, 83, 89, 78, 84, 72, 69, 84, 79, 78, 
+    128, 73, 68, 69, 78, 84, 73, 70, 73, 67, 65, 84, 73, 79, 78, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 48, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 57, 48, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 57, 48, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    57, 48, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 52, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 53, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 54, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 57, 48, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 57, 48, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    57, 48, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 65, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 66, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 67, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 57, 48, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 57, 48, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    57, 48, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 48, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 49, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 50, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 57, 49, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 57, 49, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    57, 49, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 54, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 55, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 56, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 57, 49, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 57, 49, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    57, 49, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 67, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 68, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 69, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 57, 49, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 57, 50, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    57, 50, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 50, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 51, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 52, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 57, 50, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 57, 50, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    57, 50, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 56, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 57, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 65, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 57, 50, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 57, 50, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    57, 50, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 69, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 70, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 48, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 57, 51, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 57, 51, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    57, 51, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 52, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 53, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 54, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 57, 51, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 57, 51, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    57, 51, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 65, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 66, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 67, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 57, 51, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 57, 51, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    57, 51, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 48, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 49, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 50, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 57, 52, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 57, 52, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    57, 52, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 54, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 55, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 56, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 57, 52, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 57, 52, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    57, 52, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 67, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 68, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 69, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 57, 52, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 57, 53, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    57, 53, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 50, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 51, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 52, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 57, 53, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 57, 53, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    57, 53, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 56, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 57, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 65, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 57, 53, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 57, 53, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    57, 53, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 69, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 70, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 48, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 57, 54, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 57, 54, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    57, 54, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 52, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 53, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 54, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 57, 54, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 57, 54, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    57, 54, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 65, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 66, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 67, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 57, 54, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 57, 54, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    57, 54, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 48, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 49, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 50, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 57, 55, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 57, 55, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    57, 55, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 54, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 55, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 56, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 57, 55, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 57, 55, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    57, 55, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 67, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 68, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 69, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 57, 55, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 57, 56, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    57, 56, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 50, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 51, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 52, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 57, 56, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 57, 56, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    57, 56, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 56, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 57, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 65, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 57, 56, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 57, 56, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    57, 56, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 69, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 70, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 48, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 57, 57, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 57, 57, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    57, 57, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 52, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 53, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 54, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 57, 57, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 57, 57, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    57, 57, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 65, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 66, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 67, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 57, 57, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 57, 57, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    57, 57, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 48, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 49, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 50, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 57, 65, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 57, 65, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    57, 65, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 54, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 55, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 56, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 57, 65, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 57, 65, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    57, 65, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 67, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 68, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 69, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 57, 65, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 57, 66, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    57, 66, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 50, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 51, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 52, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 57, 66, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 57, 66, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    57, 66, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 56, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 57, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 65, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 57, 66, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 57, 66, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    57, 66, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 69, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 70, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 48, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 57, 67, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 57, 67, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    57, 67, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 52, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 53, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 54, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 57, 67, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 57, 67, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    57, 67, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 65, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 66, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 67, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 57, 67, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 57, 67, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    57, 67, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 48, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 49, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 50, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 57, 68, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 57, 68, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    57, 68, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 54, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 55, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 56, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 57, 68, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 57, 68, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    57, 68, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 67, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 68, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 69, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 57, 68, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 57, 69, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    57, 69, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 50, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 51, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 52, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 57, 69, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 57, 69, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    57, 69, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 56, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 57, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 65, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 57, 69, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 57, 69, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    57, 69, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 69, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 70, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 48, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 57, 70, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 57, 70, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    57, 70, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 52, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 53, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 54, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 57, 70, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 57, 70, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    57, 70, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 65, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 66, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 67, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 57, 70, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 57, 70, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    57, 70, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 48, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 49, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 50, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 65, 48, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 65, 48, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    65, 48, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 54, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 55, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 56, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 65, 48, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 65, 48, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    65, 48, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 67, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 68, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 69, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 65, 48, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 65, 49, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    65, 49, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 50, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 51, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 52, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 65, 49, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 65, 49, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    65, 49, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 56, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 57, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 65, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 65, 49, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 65, 49, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    65, 49, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 69, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 70, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 48, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 65, 50, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 65, 50, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    65, 50, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 52, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 53, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 54, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 65, 50, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 65, 50, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    65, 50, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 65, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 66, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 67, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 65, 50, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 65, 51, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    65, 51, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 50, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 51, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 52, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 65, 51, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 65, 51, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    65, 51, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 56, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 57, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 65, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 65, 51, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 65, 51, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    65, 51, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 69, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 70, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 48, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 65, 52, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 65, 52, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    65, 52, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 52, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 53, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 54, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 65, 52, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 65, 52, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    65, 52, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 65, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 66, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 67, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 65, 52, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 65, 52, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    65, 52, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 48, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 49, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 50, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 65, 53, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 65, 53, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    65, 53, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 54, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 55, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 56, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 65, 53, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 65, 53, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    65, 53, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 67, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 68, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 69, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 65, 53, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 65, 54, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    65, 54, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 50, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 51, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 52, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 65, 54, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 65, 54, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    65, 54, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 56, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 57, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 65, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 65, 55, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 65, 55, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    65, 55, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 51, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 52, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 53, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 65, 55, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 65, 55, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    65, 55, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 57, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 65, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 66, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 65, 55, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 65, 55, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    65, 55, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 70, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 48, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 49, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 65, 56, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 65, 56, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    65, 56, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 53, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 54, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 55, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 65, 56, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 65, 56, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    65, 56, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 66, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 67, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 68, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 65, 56, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 65, 56, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    65, 57, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 49, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 50, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 51, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 65, 57, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 65, 57, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    65, 57, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 55, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 56, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 57, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 65, 57, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 65, 57, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    65, 57, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 68, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 69, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 70, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 65, 65, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 65, 65, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    65, 65, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 51, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 52, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 53, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 65, 65, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 65, 65, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    65, 65, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 57, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 65, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 66, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 65, 65, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 65, 65, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    65, 65, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 70, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 48, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 49, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 65, 66, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 65, 66, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    65, 66, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 53, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 54, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 55, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 65, 66, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 65, 66, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    65, 66, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 66, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 67, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 68, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 65, 66, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 65, 66, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    65, 67, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 49, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 50, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 51, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 65, 67, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 65, 67, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    65, 67, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 55, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 56, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 57, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 65, 67, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 65, 67, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    65, 67, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 68, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 69, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 70, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 65, 68, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 65, 68, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    65, 68, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, 51, 
+    128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, 52, 128, 73, 68, 
+    69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, 53, 128, 73, 68, 69, 79, 71, 
+    82, 65, 80, 72, 45, 70, 65, 68, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 
+    72, 45, 70, 65, 68, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 
+    65, 68, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, 57, 
+    128, 76, 79, 78, 71, 45, 66, 82, 65, 78, 67, 72, 45, 79, 83, 211, 76, 79, 
+    78, 71, 45, 66, 82, 65, 78, 67, 72, 45, 83, 79, 204, 76, 79, 78, 71, 45, 
+    66, 82, 65, 78, 67, 72, 45, 89, 82, 128, 77, 85, 76, 84, 73, 80, 76, 73, 
+    67, 65, 84, 73, 79, 78, 128, 80, 65, 76, 65, 84, 65, 76, 73, 90, 65, 84, 
+    73, 79, 78, 128, 83, 72, 79, 82, 84, 45, 84, 87, 73, 71, 45, 77, 65, 68, 
+    210, 83, 72, 79, 82, 84, 45, 84, 87, 73, 71, 45, 78, 65, 85, 196, 83, 73, 
+    79, 83, 45, 83, 83, 65, 78, 71, 83, 73, 79, 83, 128, 84, 69, 65, 82, 68, 
+    82, 79, 80, 45, 66, 65, 82, 66, 69, 196, 84, 82, 79, 77, 73, 75, 79, 76, 
+    89, 71, 73, 83, 77, 65, 128, 84, 82, 79, 77, 73, 75, 79, 83, 89, 78, 65, 
+    71, 77, 65, 128, 87, 72, 73, 84, 69, 45, 70, 69, 65, 84, 72, 69, 82, 69, 
+    196, 89, 80, 79, 71, 69, 71, 82, 65, 77, 77, 69, 78, 73, 128, 82, 73, 71, 
+    72, 84, 45, 80, 79, 73, 78, 84, 73, 78, 199, 77, 85, 76, 84, 73, 80, 76, 
+    73, 67, 65, 84, 73, 79, 206, 82, 73, 71, 72, 84, 45, 83, 72, 65, 68, 79, 
+    87, 69, 196, 66, 65, 76, 76, 79, 79, 78, 45, 83, 80, 79, 75, 69, 196, 75, 
+    65, 80, 89, 69, 79, 85, 78, 77, 73, 69, 85, 77, 128, 82, 73, 69, 85, 76, 
+    45, 80, 72, 73, 69, 85, 80, 72, 128, 82, 73, 69, 85, 76, 45, 84, 72, 73, 
+    69, 85, 84, 72, 128, 65, 82, 71, 79, 83, 89, 78, 84, 72, 69, 84, 79, 78, 
+    128, 65, 83, 89, 77, 80, 84, 79, 84, 73, 67, 65, 76, 76, 217, 77, 73, 69, 
+    85, 77, 45, 80, 65, 78, 83, 73, 79, 83, 128, 78, 73, 69, 85, 78, 45, 80, 
+    65, 78, 83, 73, 79, 83, 128, 80, 65, 82, 65, 76, 76, 69, 76, 79, 71, 82, 
+    65, 77, 128, 80, 69, 82, 80, 69, 78, 68, 73, 67, 85, 76, 65, 82, 128, 80, 
+    72, 73, 69, 85, 80, 72, 45, 80, 73, 69, 85, 80, 128, 80, 73, 69, 85, 80, 
+    45, 80, 72, 73, 69, 85, 80, 72, 128, 80, 73, 69, 85, 80, 45, 84, 72, 73, 
+    69, 85, 84, 72, 128, 80, 82, 69, 80, 79, 78, 68, 69, 82, 65, 78, 67, 69, 
+    128, 82, 73, 69, 85, 76, 45, 80, 65, 78, 83, 73, 79, 83, 128, 84, 69, 84, 
+    65, 82, 84, 73, 77, 79, 82, 73, 79, 78, 128, 84, 73, 75, 69, 85, 84, 45, 
+    75, 73, 89, 69, 79, 75, 128, 84, 82, 73, 65, 78, 71, 76, 69, 45, 82, 79, 
+    85, 78, 196, 89, 69, 83, 73, 69, 85, 78, 71, 45, 83, 73, 79, 83, 128, 65, 
+    86, 65, 75, 82, 65, 72, 65, 83, 65, 78, 89, 65, 128, 66, 79, 84, 84, 79, 
+    77, 45, 76, 73, 71, 72, 84, 69, 196, 67, 72, 73, 69, 85, 67, 72, 45, 72, 
+    73, 69, 85, 72, 128, 67, 72, 73, 84, 85, 69, 85, 77, 67, 73, 69, 85, 67, 
+    128, 67, 79, 78, 84, 69, 77, 80, 76, 65, 84, 73, 79, 78, 128, 68, 79, 84, 
+    83, 45, 49, 50, 51, 52, 53, 54, 55, 56, 128, 69, 77, 66, 69, 76, 76, 73, 
+    83, 72, 77, 69, 78, 84, 128, 73, 69, 85, 78, 71, 45, 67, 72, 73, 69, 85, 
+    67, 72, 128, 73, 69, 85, 78, 71, 45, 75, 72, 73, 69, 85, 75, 72, 128, 73, 
+    69, 85, 78, 71, 45, 80, 72, 73, 69, 85, 80, 72, 128, 73, 69, 85, 78, 71, 
+    45, 84, 72, 73, 69, 85, 84, 72, 128, 75, 65, 80, 89, 69, 79, 85, 78, 82, 
+    73, 69, 85, 76, 128, 76, 79, 78, 71, 45, 66, 82, 65, 78, 67, 72, 45, 65, 
+    210, 77, 73, 69, 85, 77, 45, 67, 72, 73, 69, 85, 67, 72, 128, 78, 73, 69, 
+    85, 78, 45, 84, 72, 73, 69, 85, 84, 72, 128, 80, 73, 69, 85, 80, 45, 67, 
+    72, 73, 69, 85, 67, 72, 128, 82, 73, 69, 85, 76, 45, 75, 72, 73, 69, 85, 
+    75, 72, 128, 83, 72, 79, 82, 84, 45, 84, 87, 73, 71, 45, 79, 83, 211, 83, 
+    72, 79, 82, 84, 45, 84, 87, 73, 71, 45, 83, 79, 204, 83, 72, 79, 82, 84, 
+    45, 84, 87, 73, 71, 45, 84, 89, 210, 83, 72, 79, 82, 84, 45, 84, 87, 73, 
+    71, 45, 89, 82, 128, 83, 84, 65, 67, 67, 65, 84, 73, 83, 83, 73, 77, 79, 
+    128, 83, 84, 82, 73, 75, 69, 84, 72, 82, 79, 85, 71, 72, 128, 84, 72, 69, 
+    82, 77, 79, 68, 89, 78, 65, 77, 73, 67, 128, 89, 85, 85, 75, 65, 76, 69, 
+    65, 80, 73, 78, 84, 85, 128, 71, 82, 69, 65, 84, 69, 82, 45, 84, 72, 65, 
+    78, 128, 65, 78, 84, 73, 67, 76, 79, 67, 75, 87, 73, 83, 197, 76, 69, 70, 
+    84, 45, 80, 79, 73, 78, 84, 73, 78, 199, 73, 78, 84, 69, 82, 83, 69, 67, 
+    84, 73, 79, 78, 128, 65, 80, 80, 82, 79, 88, 73, 77, 65, 84, 69, 76, 217, 
+    68, 73, 70, 70, 69, 82, 69, 78, 84, 73, 65, 76, 128, 68, 79, 87, 78, 45, 
+    80, 79, 73, 78, 84, 73, 78, 199, 80, 65, 82, 69, 83, 84, 73, 71, 77, 69, 
+    78, 79, 206, 67, 82, 89, 80, 84, 79, 71, 82, 65, 77, 77, 73, 195, 72, 89, 
+    80, 72, 69, 78, 45, 77, 73, 78, 85, 83, 128, 67, 79, 78, 67, 65, 86, 69, 
+    45, 83, 73, 68, 69, 196, 76, 69, 70, 84, 45, 84, 79, 45, 82, 73, 71, 72, 
+    212, 78, 73, 69, 85, 78, 45, 84, 73, 75, 69, 85, 84, 128, 82, 73, 69, 85, 
+    76, 45, 75, 73, 89, 69, 79, 75, 128, 82, 73, 71, 72, 84, 45, 84, 79, 45, 
+    76, 69, 70, 212, 84, 82, 65, 78, 83, 80, 79, 83, 73, 84, 73, 79, 206, 67, 
+    82, 79, 83, 83, 69, 68, 45, 84, 65, 73, 76, 128, 68, 73, 77, 73, 78, 85, 
+    84, 73, 79, 78, 45, 49, 128, 68, 82, 79, 80, 45, 83, 72, 65, 68, 79, 87, 
+    69, 196, 71, 65, 69, 84, 84, 65, 45, 80, 73, 76, 76, 65, 128, 71, 69, 79, 
+    77, 69, 84, 82, 73, 67, 65, 76, 76, 217, 73, 69, 85, 78, 71, 45, 75, 73, 
+    89, 69, 79, 75, 128, 73, 78, 84, 69, 82, 80, 79, 76, 65, 84, 73, 79, 206, 
+    78, 73, 69, 85, 78, 45, 75, 73, 89, 69, 79, 75, 128, 80, 73, 69, 85, 80, 
+    45, 84, 73, 75, 69, 85, 84, 128, 82, 73, 69, 85, 76, 45, 84, 73, 75, 69, 
+    85, 84, 128, 84, 72, 73, 82, 84, 89, 45, 83, 69, 67, 79, 78, 196, 84, 87, 
+    69, 78, 84, 89, 45, 69, 73, 71, 72, 84, 200, 84, 87, 69, 78, 84, 89, 45, 
+    84, 72, 82, 69, 69, 128, 65, 67, 67, 85, 77, 85, 76, 65, 84, 73, 79, 78, 
+    128, 65, 78, 65, 84, 82, 73, 67, 72, 73, 83, 77, 65, 128, 65, 85, 82, 65, 
+    77, 65, 90, 68, 65, 65, 45, 50, 128, 65, 85, 82, 65, 77, 65, 90, 68, 65, 
+    65, 72, 65, 128, 66, 82, 69, 65, 75, 84, 72, 82, 79, 85, 71, 72, 128, 67, 
+    72, 73, 84, 85, 69, 85, 77, 83, 73, 79, 83, 128, 67, 89, 76, 73, 78, 68, 
+    82, 73, 67, 73, 84, 89, 128, 68, 69, 67, 73, 83, 73, 86, 69, 78, 69, 83, 
+    83, 128, 68, 69, 70, 69, 67, 84, 73, 86, 69, 78, 69, 83, 211, 68, 73, 70, 
+    70, 73, 67, 85, 76, 84, 73, 69, 83, 128, 68, 73, 77, 73, 78, 73, 83, 72, 
+    77, 69, 78, 84, 128, 68, 73, 77, 73, 78, 85, 84, 73, 79, 78, 45, 50, 128, 
+    68, 73, 77, 73, 78, 85, 84, 73, 79, 78, 45, 51, 128, 68, 73, 83, 67, 79, 
+    78, 84, 73, 78, 85, 79, 85, 211, 68, 79, 84, 83, 45, 49, 50, 51, 52, 53, 
+    54, 55, 128, 68, 79, 84, 83, 45, 49, 50, 51, 52, 53, 54, 56, 128, 68, 79, 
+    84, 83, 45, 49, 50, 51, 52, 53, 55, 56, 128, 68, 79, 84, 83, 45, 49, 50, 
+    51, 52, 54, 55, 56, 128, 68, 79, 84, 83, 45, 49, 50, 51, 53, 54, 55, 56, 
+    128, 68, 79, 84, 83, 45, 49, 50, 52, 53, 54, 55, 56, 128, 68, 79, 84, 83, 
+    45, 49, 51, 52, 53, 54, 55, 56, 128, 68, 79, 84, 83, 45, 50, 51, 52, 53, 
+    54, 55, 56, 128, 69, 85, 82, 79, 45, 67, 85, 82, 82, 69, 78, 67, 217, 70, 
+    76, 69, 85, 82, 45, 68, 69, 45, 76, 73, 83, 128, 71, 82, 79, 78, 84, 72, 
+    73, 83, 77, 65, 84, 65, 128, 72, 89, 80, 79, 68, 73, 65, 83, 84, 79, 76, 
+    69, 128, 73, 67, 69, 76, 65, 78, 68, 73, 67, 45, 89, 82, 128, 73, 69, 85, 
+    78, 71, 45, 84, 73, 75, 69, 85, 84, 128, 73, 78, 84, 69, 82, 83, 89, 76, 
+    76, 65, 66, 73, 195, 74, 85, 68, 69, 79, 45, 83, 80, 65, 78, 73, 83, 200, 
+    75, 73, 89, 69, 79, 75, 45, 82, 73, 69, 85, 76, 128, 76, 65, 66, 73, 65, 
+    76, 73, 90, 65, 84, 73, 79, 206, 77, 73, 78, 85, 83, 45, 79, 82, 45, 80, 
+    76, 85, 211, 77, 79, 82, 80, 72, 79, 76, 79, 71, 73, 67, 65, 204, 79, 80, 
+    69, 78, 45, 79, 85, 84, 76, 73, 78, 69, 196, 80, 69, 82, 80, 69, 78, 68, 
+    73, 67, 85, 76, 65, 210, 82, 85, 76, 69, 45, 68, 69, 76, 65, 89, 69, 68, 
+    128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 48, 48, 128, 83, 69, 76, 69, 
+    67, 84, 79, 82, 45, 49, 48, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 
+    49, 48, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 48, 51, 128, 83, 
+    69, 76, 69, 67, 84, 79, 82, 45, 49, 48, 52, 128, 83, 69, 76, 69, 67, 84, 
+    79, 82, 45, 49, 48, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 48, 
+    54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 48, 55, 128, 83, 69, 76, 
+    69, 67, 84, 79, 82, 45, 49, 48, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 
+    45, 49, 48, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 49, 48, 128, 
+    83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 49, 49, 128, 83, 69, 76, 69, 67, 
+    84, 79, 82, 45, 49, 49, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 
+    49, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 49, 52, 128, 83, 69, 
+    76, 69, 67, 84, 79, 82, 45, 49, 49, 53, 128, 83, 69, 76, 69, 67, 84, 79, 
+    82, 45, 49, 49, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 49, 55, 
+    128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 49, 56, 128, 83, 69, 76, 69, 
+    67, 84, 79, 82, 45, 49, 49, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 
+    49, 50, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 50, 49, 128, 83, 
+    69, 76, 69, 67, 84, 79, 82, 45, 49, 50, 50, 128, 83, 69, 76, 69, 67, 84, 
+    79, 82, 45, 49, 50, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 50, 
+    52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 50, 53, 128, 83, 69, 76, 
+    69, 67, 84, 79, 82, 45, 49, 50, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 
+    45, 49, 50, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 50, 56, 128, 
+    83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 50, 57, 128, 83, 69, 76, 69, 67, 
+    84, 79, 82, 45, 49, 51, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 
+    51, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 51, 50, 128, 83, 69, 
+    76, 69, 67, 84, 79, 82, 45, 49, 51, 51, 128, 83, 69, 76, 69, 67, 84, 79, 
+    82, 45, 49, 51, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 51, 53, 
+    128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 51, 54, 128, 83, 69, 76, 69, 
+    67, 84, 79, 82, 45, 49, 51, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 
+    49, 51, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 51, 57, 128, 83, 
+    69, 76, 69, 67, 84, 79, 82, 45, 49, 52, 48, 128, 83, 69, 76, 69, 67, 84, 
+    79, 82, 45, 49, 52, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 52, 
+    50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 52, 51, 128, 83, 69, 76, 
+    69, 67, 84, 79, 82, 45, 49, 52, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 
+    45, 49, 52, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 52, 54, 128, 
+    83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 52, 55, 128, 83, 69, 76, 69, 67, 
+    84, 79, 82, 45, 49, 52, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 
+    52, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 53, 48, 128, 83, 69, 
+    76, 69, 67, 84, 79, 82, 45, 49, 53, 49, 128, 83, 69, 76, 69, 67, 84, 79, 
+    82, 45, 49, 53, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 53, 51, 
+    128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 53, 52, 128, 83, 69, 76, 69, 
+    67, 84, 79, 82, 45, 49, 53, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 
+    49, 53, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 53, 55, 128, 83, 
+    69, 76, 69, 67, 84, 79, 82, 45, 49, 53, 56, 128, 83, 69, 76, 69, 67, 84, 
+    79, 82, 45, 49, 53, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 54, 
+    48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 54, 49, 128, 83, 69, 76, 
+    69, 67, 84, 79, 82, 45, 49, 54, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 
+    45, 49, 54, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 54, 52, 128, 
+    83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 54, 53, 128, 83, 69, 76, 69, 67, 
+    84, 79, 82, 45, 49, 54, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 
+    54, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 54, 56, 128, 83, 69, 
+    76, 69, 67, 84, 79, 82, 45, 49, 54, 57, 128, 83, 69, 76, 69, 67, 84, 79, 
+    82, 45, 49, 55, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 55, 49, 
+    128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 55, 50, 128, 83, 69, 76, 69, 
+    67, 84, 79, 82, 45, 49, 55, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 
+    49, 55, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 55, 53, 128, 83, 
+    69, 76, 69, 67, 84, 79, 82, 45, 49, 55, 54, 128, 83, 69, 76, 69, 67, 84, 
+    79, 82, 45, 49, 55, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 55, 
+    56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 55, 57, 128, 83, 69, 76, 
+    69, 67, 84, 79, 82, 45, 49, 56, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 
+    45, 49, 56, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 56, 50, 128, 
+    83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 56, 51, 128, 83, 69, 76, 69, 67, 
+    84, 79, 82, 45, 49, 56, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 
+    56, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 56, 54, 128, 83, 69, 
+    76, 69, 67, 84, 79, 82, 45, 49, 56, 55, 128, 83, 69, 76, 69, 67, 84, 79, 
+    82, 45, 49, 56, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 56, 57, 
+    128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 57, 48, 128, 83, 69, 76, 69, 
+    67, 84, 79, 82, 45, 49, 57, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 
+    49, 57, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 57, 51, 128, 83, 
+    69, 76, 69, 67, 84, 79, 82, 45, 49, 57, 52, 128, 83, 69, 76, 69, 67, 84, 
+    79, 82, 45, 49, 57, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 57, 
+    54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 57, 55, 128, 83, 69, 76, 
+    69, 67, 84, 79, 82, 45, 49, 57, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 
+    45, 49, 57, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 48, 48, 128, 
+    83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 48, 49, 128, 83, 69, 76, 69, 67, 
+    84, 79, 82, 45, 50, 48, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 
+    48, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 48, 52, 128, 83, 69, 
+    76, 69, 67, 84, 79, 82, 45, 50, 48, 53, 128, 83, 69, 76, 69, 67, 84, 79, 
+    82, 45, 50, 48, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 48, 55, 
+    128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 48, 56, 128, 83, 69, 76, 69, 
+    67, 84, 79, 82, 45, 50, 48, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 
+    50, 49, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 49, 49, 128, 83, 
+    69, 76, 69, 67, 84, 79, 82, 45, 50, 49, 50, 128, 83, 69, 76, 69, 67, 84, 
+    79, 82, 45, 50, 49, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 49, 
+    52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 49, 53, 128, 83, 69, 76, 
+    69, 67, 84, 79, 82, 45, 50, 49, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 
+    45, 50, 49, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 49, 56, 128, 
+    83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 49, 57, 128, 83, 69, 76, 69, 67, 
+    84, 79, 82, 45, 50, 50, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 
+    50, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 50, 50, 128, 83, 69, 
+    76, 69, 67, 84, 79, 82, 45, 50, 50, 51, 128, 83, 69, 76, 69, 67, 84, 79, 
+    82, 45, 50, 50, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 50, 53, 
+    128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 50, 54, 128, 83, 69, 76, 69, 
+    67, 84, 79, 82, 45, 50, 50, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 
+    50, 50, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 50, 57, 128, 83, 
+    69, 76, 69, 67, 84, 79, 82, 45, 50, 51, 48, 128, 83, 69, 76, 69, 67, 84, 
+    79, 82, 45, 50, 51, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 51, 
+    50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 51, 51, 128, 83, 69, 76, 
+    69, 67, 84, 79, 82, 45, 50, 51, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 
+    45, 50, 51, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 51, 54, 128, 
+    83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 51, 55, 128, 83, 69, 76, 69, 67, 
+    84, 79, 82, 45, 50, 51, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 
+    51, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 52, 48, 128, 83, 69, 
+    76, 69, 67, 84, 79, 82, 45, 50, 52, 49, 128, 83, 69, 76, 69, 67, 84, 79, 
+    82, 45, 50, 52, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 52, 51, 
+    128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 52, 52, 128, 83, 69, 76, 69, 
+    67, 84, 79, 82, 45, 50, 52, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 
+    50, 52, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 52, 55, 128, 83, 
+    69, 76, 69, 67, 84, 79, 82, 45, 50, 52, 56, 128, 83, 69, 76, 69, 67, 84, 
+    79, 82, 45, 50, 52, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 53, 
+    48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 53, 49, 128, 83, 69, 76, 
+    69, 67, 84, 79, 82, 45, 50, 53, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 
+    45, 50, 53, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 53, 52, 128, 
+    83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 53, 53, 128, 83, 69, 76, 69, 67, 
+    84, 79, 82, 45, 50, 53, 54, 128, 83, 72, 79, 82, 84, 45, 84, 87, 73, 71, 
+    45, 65, 210, 83, 73, 79, 83, 45, 67, 72, 73, 69, 85, 67, 72, 128, 83, 73, 
+    79, 83, 45, 75, 72, 73, 69, 85, 75, 72, 128, 83, 73, 79, 83, 45, 80, 72, 
+    73, 69, 85, 80, 72, 128, 83, 73, 79, 83, 45, 84, 72, 73, 69, 85, 84, 72, 
+    128, 83, 84, 82, 65, 71, 71, 73, 83, 77, 65, 84, 65, 128, 84, 72, 85, 78, 
+    68, 69, 82, 83, 84, 79, 82, 77, 128, 84, 73, 75, 69, 85, 84, 45, 82, 73, 
+    69, 85, 76, 128, 84, 82, 65, 78, 83, 77, 73, 83, 83, 73, 79, 78, 128, 84, 
+    87, 69, 78, 84, 89, 45, 69, 73, 71, 72, 84, 128, 84, 87, 69, 78, 84, 89, 
+    45, 83, 69, 86, 69, 78, 128, 86, 79, 87, 69, 76, 45, 67, 65, 82, 82, 73, 
+    69, 210, 88, 83, 72, 65, 65, 89, 65, 84, 72, 73, 89, 65, 128, 89, 79, 85, 
+    84, 72, 70, 85, 76, 78, 69, 83, 83, 128, 71, 82, 69, 65, 84, 69, 82, 45, 
+    84, 72, 65, 206, 73, 78, 83, 84, 82, 85, 77, 69, 78, 84, 65, 204, 80, 82, 
+    69, 83, 69, 78, 84, 65, 84, 73, 79, 206, 80, 69, 82, 73, 83, 80, 79, 77, 
+    69, 78, 73, 128, 67, 45, 83, 73, 77, 80, 76, 73, 70, 73, 69, 196, 65, 82, 
+    65, 66, 73, 67, 45, 73, 78, 68, 73, 195, 80, 65, 82, 69, 78, 84, 72, 69, 
+    83, 73, 83, 128, 80, 85, 78, 67, 84, 85, 65, 84, 73, 79, 78, 128, 73, 78, 
+    84, 69, 82, 83, 69, 67, 84, 73, 79, 206, 67, 65, 78, 68, 82, 65, 66, 73, 
+    78, 68, 85, 128, 69, 82, 82, 79, 82, 45, 66, 65, 82, 82, 69, 196, 83, 85, 
+    66, 83, 84, 73, 84, 85, 84, 73, 79, 206, 66, 76, 65, 67, 75, 45, 76, 69, 
+    84, 84, 69, 210, 65, 80, 80, 82, 79, 88, 73, 77, 65, 84, 69, 128, 67, 65, 
+    78, 84, 73, 76, 76, 65, 84, 73, 79, 206, 69, 75, 70, 79, 78, 73, 84, 73, 
+    75, 79, 78, 128, 74, 45, 83, 73, 77, 80, 76, 73, 70, 73, 69, 196, 82, 73, 
+    69, 85, 76, 45, 72, 73, 69, 85, 72, 128, 83, 79, 85, 84, 72, 45, 83, 76, 
+    65, 86, 69, 217, 65, 66, 66, 82, 69, 86, 73, 65, 84, 73, 79, 206, 65, 83, 
+    84, 82, 79, 76, 79, 71, 73, 67, 65, 204, 71, 65, 89, 65, 78, 85, 75, 73, 
+    84, 84, 65, 128, 77, 73, 69, 85, 77, 45, 80, 73, 69, 85, 80, 128, 78, 73, 
+    69, 85, 78, 45, 67, 73, 69, 85, 67, 128, 78, 73, 69, 85, 78, 45, 72, 73, 
+    69, 85, 72, 128, 80, 65, 82, 65, 71, 82, 65, 80, 72, 79, 83, 128, 82, 73, 
+    69, 85, 76, 45, 77, 73, 69, 85, 77, 128, 82, 73, 69, 85, 76, 45, 80, 73, 
+    69, 85, 80, 128, 83, 69, 77, 73, 67, 73, 82, 67, 85, 76, 65, 210, 83, 83, 
+    65, 78, 71, 84, 73, 75, 69, 85, 84, 128, 65, 67, 75, 78, 79, 87, 76, 69, 
+    68, 71, 69, 128, 67, 79, 77, 80, 79, 83, 73, 84, 73, 79, 78, 128, 73, 78, 
+    84, 69, 82, 83, 69, 67, 84, 73, 78, 199, 80, 73, 69, 85, 80, 45, 67, 73, 
+    69, 85, 67, 128, 81, 85, 73, 78, 68, 73, 67, 69, 83, 73, 77, 193, 82, 73, 
+    69, 85, 76, 45, 78, 73, 69, 85, 78, 128, 83, 73, 88, 84, 89, 45, 70, 79, 
+    85, 82, 84, 200, 84, 82, 73, 84, 73, 77, 79, 82, 73, 79, 78, 128, 84, 87, 
+    69, 78, 84, 89, 45, 70, 79, 85, 82, 128, 87, 69, 68, 71, 69, 45, 84, 65, 
+    73, 76, 69, 196, 65, 69, 83, 67, 85, 76, 65, 80, 73, 85, 83, 128, 65, 71, 
+    71, 82, 65, 86, 65, 84, 73, 79, 78, 128, 65, 77, 65, 76, 71, 65, 77, 65, 
+    84, 73, 79, 206, 65, 80, 80, 76, 73, 67, 65, 84, 73, 79, 78, 128, 65, 85, 
+    71, 77, 69, 78, 84, 65, 84, 73, 79, 206, 67, 65, 78, 67, 69, 76, 76, 65, 
+    84, 73, 79, 206, 67, 73, 69, 85, 67, 45, 73, 69, 85, 78, 71, 128, 67, 79, 
+    78, 74, 85, 78, 67, 84, 73, 79, 78, 128, 67, 79, 78, 84, 82, 65, 67, 84, 
+    73, 79, 78, 128, 67, 79, 78, 84, 82, 65, 82, 73, 69, 84, 89, 128, 67, 79, 
+    82, 80, 79, 82, 65, 84, 73, 79, 78, 128, 67, 79, 85, 78, 84, 69, 82, 66, 
+    79, 82, 69, 128, 67, 79, 85, 78, 84, 69, 82, 83, 73, 78, 75, 128, 68, 65, 
+    72, 89, 65, 65, 85, 83, 72, 45, 50, 128, 68, 69, 67, 82, 69, 83, 67, 69, 
+    78, 68, 79, 128, 68, 69, 76, 73, 86, 69, 82, 65, 78, 67, 69, 128, 68, 69, 
+    78, 79, 77, 73, 78, 65, 84, 79, 82, 128, 68, 69, 82, 69, 84, 45, 72, 73, 
+    68, 69, 84, 128, 68, 69, 86, 69, 76, 79, 80, 77, 69, 78, 84, 128, 68, 73, 
+    83, 84, 73, 78, 71, 85, 73, 83, 72, 128, 68, 79, 65, 67, 72, 65, 83, 72, 
+    77, 69, 69, 128, 68, 79, 84, 83, 45, 49, 50, 51, 52, 53, 54, 128, 68, 79, 
+    84, 83, 45, 49, 50, 51, 52, 53, 55, 128, 68, 79, 84, 83, 45, 49, 50, 51, 
+    52, 53, 56, 128, 68, 79, 84, 83, 45, 49, 50, 51, 52, 54, 55, 128, 68, 79, 
+    84, 83, 45, 49, 50, 51, 52, 54, 56, 128, 68, 79, 84, 83, 45, 49, 50, 51, 
+    52, 55, 56, 128, 68, 79, 84, 83, 45, 49, 50, 51, 53, 54, 55, 128, 68, 79, 
+    84, 83, 45, 49, 50, 51, 53, 54, 56, 128, 68, 79, 84, 83, 45, 49, 50, 51, 
+    53, 55, 56, 128, 68, 79, 84, 83, 45, 49, 50, 51, 54, 55, 56, 128, 68, 79, 
+    84, 83, 45, 49, 50, 52, 53, 54, 55, 128, 68, 79, 84, 83, 45, 49, 50, 52, 
+    53, 54, 56, 128, 68, 79, 84, 83, 45, 49, 50, 52, 53, 55, 56, 128, 68, 79, 
+    84, 83, 45, 49, 50, 52, 54, 55, 56, 128, 68, 79, 84, 83, 45, 49, 50, 53, 
+    54, 55, 56, 128, 68, 79, 84, 83, 45, 49, 51, 52, 53, 54, 55, 128, 68, 79, 
+    84, 83, 45, 49, 51, 52, 53, 54, 56, 128, 68, 79, 84, 83, 45, 49, 51, 52, 
+    53, 55, 56, 128, 68, 79, 84, 83, 45, 49, 51, 52, 54, 55, 56, 128, 68, 79, 
+    84, 83, 45, 49, 51, 53, 54, 55, 56, 128, 68, 79, 84, 83, 45, 49, 52, 53, 
+    54, 55, 56, 128, 68, 79, 84, 83, 45, 50, 51, 52, 53, 54, 55, 128, 68, 79, 
+    84, 83, 45, 50, 51, 52, 53, 54, 56, 128, 68, 79, 84, 83, 45, 50, 51, 52, 
+    53, 55, 56, 128, 68, 79, 84, 83, 45, 50, 51, 52, 54, 55, 56, 128, 68, 79, 
+    84, 83, 45, 50, 51, 53, 54, 55, 56, 128, 68, 79, 84, 83, 45, 50, 52, 53, 
+    54, 55, 56, 128, 68, 79, 84, 83, 45, 51, 52, 53, 54, 55, 56, 128, 68, 79, 
+    85, 66, 76, 69, 45, 69, 78, 68, 69, 196, 69, 65, 77, 72, 65, 78, 67, 72, 
+    79, 76, 76, 128, 69, 78, 76, 65, 82, 71, 69, 77, 69, 78, 84, 128, 70, 73, 
+    78, 71, 69, 82, 78, 65, 73, 76, 83, 128, 70, 82, 79, 78, 84, 45, 84, 73, 
+    76, 84, 69, 196, 71, 85, 65, 82, 68, 69, 68, 78, 69, 83, 83, 128, 72, 65, 
+    85, 80, 84, 83, 84, 73, 77, 77, 69, 128, 72, 73, 69, 85, 72, 45, 77, 73, 
+    69, 85, 77, 128, 72, 73, 69, 85, 72, 45, 78, 73, 69, 85, 78, 128, 72, 73, 
+    69, 85, 72, 45, 80, 73, 69, 85, 80, 128, 72, 73, 69, 85, 72, 45, 82, 73, 
+    69, 85, 76, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 76, 217, 73, 69, 
+    85, 78, 71, 45, 67, 73, 69, 85, 67, 128, 73, 69, 85, 78, 71, 45, 77, 73, 
+    69, 85, 77, 128, 73, 69, 85, 78, 71, 45, 80, 73, 69, 85, 80, 128, 73, 78, 
+    84, 69, 71, 82, 65, 84, 73, 79, 78, 128, 73, 78, 84, 69, 82, 67, 65, 76, 
+    65, 84, 69, 128, 73, 78, 84, 69, 82, 82, 79, 66, 65, 78, 71, 128, 75, 73, 
+    82, 79, 77, 69, 69, 84, 79, 82, 85, 128, 76, 65, 75, 75, 72, 65, 78, 71, 
+    89, 65, 79, 128, 77, 73, 69, 85, 77, 45, 72, 73, 69, 85, 72, 128, 77, 73, 
+    69, 85, 77, 45, 82, 73, 69, 85, 76, 128, 77, 85, 85, 83, 73, 75, 65, 84, 
+    79, 65, 78, 128, 78, 65, 65, 75, 83, 73, 75, 89, 65, 89, 65, 128, 78, 69, 
+    66, 69, 78, 83, 84, 73, 77, 77, 69, 128, 78, 73, 69, 85, 78, 45, 80, 73, 
+    69, 85, 80, 128, 78, 79, 78, 45, 66, 82, 69, 65, 75, 73, 78, 199, 79, 66, 
+    83, 84, 82, 85, 67, 84, 73, 79, 78, 128, 80, 65, 82, 65, 75, 76, 73, 84, 
+    73, 75, 73, 128, 80, 69, 78, 69, 84, 82, 65, 84, 73, 79, 78, 128, 80, 69, 
+    82, 83, 80, 69, 67, 84, 73, 86, 69, 128, 80, 73, 69, 85, 80, 45, 78, 73, 
+    69, 85, 78, 128, 80, 73, 69, 85, 80, 45, 82, 73, 69, 85, 76, 128, 80, 79, 
+    83, 84, 80, 79, 83, 73, 84, 73, 79, 206, 80, 82, 69, 83, 67, 82, 73, 80, 
+    84, 73, 79, 206, 80, 82, 79, 80, 79, 82, 84, 73, 79, 78, 65, 204, 82, 73, 
+    71, 72, 84, 45, 83, 72, 65, 68, 69, 196, 82, 73, 78, 70, 79, 82, 90, 65, 
+    78, 68, 79, 128, 82, 79, 85, 78, 68, 45, 84, 73, 80, 80, 69, 196, 83, 65, 
+    71, 73, 84, 84, 65, 82, 73, 85, 83, 128, 83, 69, 76, 69, 67, 84, 79, 82, 
+    45, 49, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 49, 128, 83, 69, 
+    76, 69, 67, 84, 79, 82, 45, 49, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 
+    45, 49, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 52, 128, 83, 69, 
+    76, 69, 67, 84, 79, 82, 45, 49, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 
+    45, 49, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 55, 128, 83, 69, 
+    76, 69, 67, 84, 79, 82, 45, 49, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 
+    45, 49, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 48, 128, 83, 69, 
+    76, 69, 67, 84, 79, 82, 45, 50, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 
+    45, 50, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 51, 128, 83, 69, 
+    76, 69, 67, 84, 79, 82, 45, 50, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 
+    45, 50, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 54, 128, 83, 69, 
+    76, 69, 67, 84, 79, 82, 45, 50, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 
+    45, 50, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 57, 128, 83, 69, 
+    76, 69, 67, 84, 79, 82, 45, 51, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 
+    45, 51, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 51, 50, 128, 83, 69, 
+    76, 69, 67, 84, 79, 82, 45, 51, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 
+    45, 51, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 51, 53, 128, 83, 69, 
+    76, 69, 67, 84, 79, 82, 45, 51, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 
+    45, 51, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 51, 56, 128, 83, 69, 
+    76, 69, 67, 84, 79, 82, 45, 51, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 
+    45, 52, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 52, 49, 128, 83, 69, 
+    76, 69, 67, 84, 79, 82, 45, 52, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 
+    45, 52, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 52, 52, 128, 83, 69, 
+    76, 69, 67, 84, 79, 82, 45, 52, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 
+    45, 52, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 52, 55, 128, 83, 69, 
+    76, 69, 67, 84, 79, 82, 45, 52, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 
+    45, 52, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 53, 48, 128, 83, 69, 
+    76, 69, 67, 84, 79, 82, 45, 53, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 
+    45, 53, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 53, 51, 128, 83, 69, 
+    76, 69, 67, 84, 79, 82, 45, 53, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 
+    45, 53, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 53, 54, 128, 83, 69, 
+    76, 69, 67, 84, 79, 82, 45, 53, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 
+    45, 53, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 53, 57, 128, 83, 69, 
+    76, 69, 67, 84, 79, 82, 45, 54, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 
+    45, 54, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 54, 50, 128, 83, 69, 
+    76, 69, 67, 84, 79, 82, 45, 54, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 
+    45, 54, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 54, 53, 128, 83, 69, 
+    76, 69, 67, 84, 79, 82, 45, 54, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 
+    45, 54, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 54, 56, 128, 83, 69, 
+    76, 69, 67, 84, 79, 82, 45, 54, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 
+    45, 55, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 55, 49, 128, 83, 69, 
+    76, 69, 67, 84, 79, 82, 45, 55, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 
+    45, 55, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 55, 52, 128, 83, 69, 
+    76, 69, 67, 84, 79, 82, 45, 55, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 
+    45, 55, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 55, 55, 128, 83, 69, 
+    76, 69, 67, 84, 79, 82, 45, 55, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 
+    45, 55, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 56, 48, 128, 83, 69, 
+    76, 69, 67, 84, 79, 82, 45, 56, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 
+    45, 56, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 56, 51, 128, 83, 69, 
+    76, 69, 67, 84, 79, 82, 45, 56, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 
+    45, 56, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 56, 54, 128, 83, 69, 
+    76, 69, 67, 84, 79, 82, 45, 56, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 
+    45, 56, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 56, 57, 128, 83, 69, 
+    76, 69, 67, 84, 79, 82, 45, 57, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 
+    45, 57, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 57, 50, 128, 83, 69, 
+    76, 69, 67, 84, 79, 82, 45, 57, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 
+    45, 57, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 57, 53, 128, 83, 69, 
+    76, 69, 67, 84, 79, 82, 45, 57, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 
+    45, 57, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 57, 56, 128, 83, 69, 
+    76, 69, 67, 84, 79, 82, 45, 57, 57, 128, 83, 80, 82, 69, 67, 72, 71, 69, 
+    83, 65, 78, 199, 83, 85, 80, 69, 82, 73, 77, 80, 79, 83, 69, 196, 84, 69, 
+    84, 82, 65, 70, 79, 78, 73, 65, 83, 128, 84, 72, 65, 78, 84, 72, 65, 75, 
+    72, 65, 84, 128, 84, 72, 82, 69, 69, 45, 80, 69, 82, 45, 69, 205, 84, 79, 
+    65, 78, 68, 65, 75, 72, 73, 65, 84, 128, 84, 82, 65, 78, 83, 77, 73, 83, 
+    83, 73, 79, 206, 84, 87, 69, 78, 84, 89, 45, 70, 73, 86, 69, 128, 84, 87, 
+    69, 78, 84, 89, 45, 78, 73, 78, 69, 128, 85, 78, 65, 83, 80, 73, 82, 65, 
+    84, 69, 68, 128, 67, 73, 82, 67, 85, 77, 70, 76, 69, 88, 128, 83, 85, 80, 
+    69, 82, 83, 67, 82, 73, 80, 212, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 
+    128, 80, 85, 78, 67, 84, 85, 65, 84, 73, 79, 206, 73, 78, 68, 69, 80, 69, 
+    78, 68, 69, 78, 212, 80, 69, 82, 73, 83, 80, 79, 77, 69, 78, 201, 69, 88, 
+    67, 76, 65, 77, 65, 84, 73, 79, 206, 68, 69, 83, 67, 82, 73, 80, 84, 73, 
+    79, 206, 80, 65, 82, 69, 78, 84, 72, 69, 83, 73, 211, 68, 79, 85, 66, 76, 
+    69, 45, 76, 73, 78, 197, 77, 65, 72, 65, 65, 80, 82, 65, 65, 78, 193, 65, 
+    80, 79, 83, 84, 82, 79, 80, 72, 69, 128, 85, 80, 45, 80, 79, 73, 78, 84, 
+    73, 78, 199, 83, 73, 78, 71, 76, 69, 45, 76, 73, 78, 197, 73, 77, 80, 69, 
+    82, 70, 69, 67, 84, 85, 205, 82, 73, 71, 72, 84, 87, 65, 82, 68, 83, 128, 
+    65, 82, 82, 79, 87, 45, 84, 65, 73, 76, 128, 68, 79, 65, 67, 72, 65, 83, 
+    72, 77, 69, 197, 65, 69, 76, 65, 45, 80, 73, 76, 76, 65, 128, 65, 76, 84, 
+    69, 82, 78, 65, 84, 73, 86, 197, 67, 79, 77, 80, 76, 69, 84, 73, 79, 78, 
+    128, 73, 78, 84, 69, 71, 82, 65, 84, 73, 79, 206, 73, 78, 84, 69, 82, 76, 
+    73, 78, 69, 65, 210, 79, 80, 69, 78, 45, 72, 69, 65, 68, 69, 196, 79, 80, 
+    80, 79, 83, 73, 84, 73, 79, 78, 128, 82, 73, 69, 85, 76, 45, 83, 73, 79, 
+    83, 128, 83, 69, 77, 73, 45, 86, 79, 73, 67, 69, 196, 83, 83, 65, 78, 71, 
+    73, 69, 85, 78, 71, 128, 83, 85, 80, 82, 65, 76, 73, 78, 69, 65, 210, 65, 
+    69, 68, 65, 45, 80, 73, 76, 76, 65, 128, 67, 79, 78, 83, 69, 67, 85, 84, 
+    73, 86, 197, 68, 73, 86, 73, 78, 65, 84, 73, 79, 78, 128, 69, 78, 84, 69, 
+    82, 80, 82, 73, 83, 69, 128, 73, 77, 80, 69, 82, 70, 69, 67, 84, 65, 128, 
+    77, 79, 78, 79, 70, 79, 78, 73, 65, 83, 128, 77, 79, 78, 79, 71, 82, 65, 
+    77, 77, 79, 211, 78, 65, 65, 83, 73, 75, 89, 65, 89, 65, 128, 78, 73, 69, 
+    85, 78, 45, 83, 73, 79, 83, 128, 79, 86, 69, 82, 76, 65, 80, 80, 73, 78, 
+    199, 80, 65, 82, 65, 75, 65, 76, 69, 83, 77, 193, 80, 65, 82, 65, 75, 76, 
+    73, 84, 73, 75, 201, 80, 65, 82, 84, 78, 69, 82, 83, 72, 73, 208, 80, 69, 
+    82, 67, 85, 83, 83, 73, 86, 69, 128, 80, 82, 79, 80, 79, 82, 84, 73, 79, 
+    78, 128, 82, 69, 67, 84, 65, 78, 71, 85, 76, 65, 210, 82, 69, 67, 84, 73, 
+    76, 73, 78, 69, 65, 210, 82, 69, 80, 76, 65, 67, 69, 77, 69, 78, 212, 83, 
+    65, 76, 76, 65, 76, 76, 65, 72, 79, 213, 83, 73, 79, 83, 45, 78, 73, 69, 
+    85, 78, 128, 83, 73, 79, 83, 45, 82, 73, 69, 85, 76, 128, 83, 83, 65, 78, 
+    71, 72, 73, 69, 85, 72, 128, 83, 83, 65, 78, 71, 78, 73, 69, 85, 78, 128, 
+    83, 83, 65, 78, 71, 82, 73, 69, 85, 76, 128, 84, 65, 66, 85, 76, 65, 84, 
+    73, 79, 78, 128, 84, 69, 84, 82, 65, 83, 73, 77, 79, 85, 128, 84, 72, 69, 
+    77, 65, 84, 73, 83, 77, 79, 211, 84, 87, 69, 78, 84, 89, 45, 79, 78, 69, 
+    128, 84, 87, 69, 78, 84, 89, 45, 84, 87, 79, 128, 65, 76, 84, 69, 82, 78, 
+    65, 84, 73, 79, 206, 65, 78, 71, 75, 72, 65, 78, 75, 72, 85, 128, 65, 78, 
+    84, 73, 75, 69, 78, 79, 77, 65, 128, 65, 78, 85, 83, 86, 65, 82, 65, 89, 
+    65, 128, 65, 80, 79, 83, 84, 82, 79, 70, 79, 83, 128, 65, 83, 84, 69, 82, 
+    73, 83, 67, 85, 83, 128, 65, 85, 82, 65, 77, 65, 90, 68, 65, 65, 128, 66, 
+    65, 67, 75, 45, 84, 73, 76, 84, 69, 196, 66, 65, 82, 73, 89, 79, 79, 83, 
+    65, 78, 128, 66, 65, 84, 72, 65, 77, 65, 83, 65, 84, 128, 67, 73, 82, 67, 
+    85, 76, 65, 84, 73, 79, 206, 67, 76, 85, 66, 45, 83, 80, 79, 75, 69, 196, 
+    67, 79, 77, 80, 76, 69, 77, 69, 78, 84, 128, 67, 79, 77, 80, 76, 73, 65, 
+    78, 67, 69, 128, 67, 79, 77, 80, 79, 83, 73, 84, 73, 79, 206, 67, 79, 78, 
+    84, 69, 78, 84, 73, 79, 78, 128, 67, 79, 82, 82, 69, 83, 80, 79, 78, 68, 
+    211, 67, 82, 79, 83, 83, 66, 79, 78, 69, 83, 128, 68, 69, 70, 73, 78, 73, 
+    84, 73, 79, 78, 128, 68, 69, 78, 79, 77, 73, 78, 65, 84, 79, 210, 68, 73, 
+    65, 69, 82, 69, 83, 73, 90, 69, 196, 68, 73, 77, 69, 78, 83, 73, 79, 78, 
+    65, 204, 68, 73, 82, 69, 67, 84, 73, 79, 78, 65, 204, 68, 73, 83, 80, 69, 
+    82, 83, 73, 79, 78, 128, 68, 73, 83, 84, 79, 82, 84, 73, 79, 78, 128, 68, 
+    73, 86, 69, 82, 71, 69, 78, 67, 69, 128, 68, 79, 84, 83, 45, 49, 50, 51, 
+    52, 53, 128, 68, 79, 84, 83, 45, 49, 50, 51, 52, 54, 128, 68, 79, 84, 83, 
+    45, 49, 50, 51, 52, 55, 128, 68, 79, 84, 83, 45, 49, 50, 51, 52, 56, 128, 
+    68, 79, 84, 83, 45, 49, 50, 51, 53, 54, 128, 68, 79, 84, 83, 45, 49, 50, 
+    51, 53, 55, 128, 68, 79, 84, 83, 45, 49, 50, 51, 53, 56, 128, 68, 79, 84, 
+    83, 45, 49, 50, 51, 54, 55, 128, 68, 79, 84, 83, 45, 49, 50, 51, 54, 56, 
+    128, 68, 79, 84, 83, 45, 49, 50, 51, 55, 56, 128, 68, 79, 84, 83, 45, 49, 
+    50, 52, 53, 54, 128, 68, 79, 84, 83, 45, 49, 50, 52, 53, 55, 128, 68, 79, 
+    84, 83, 45, 49, 50, 52, 53, 56, 128, 68, 79, 84, 83, 45, 49, 50, 52, 54, 
+    55, 128, 68, 79, 84, 83, 45, 49, 50, 52, 54, 56, 128, 68, 79, 84, 83, 45, 
+    49, 50, 52, 55, 56, 128, 68, 79, 84, 83, 45, 49, 50, 53, 54, 55, 128, 68, 
+    79, 84, 83, 45, 49, 50, 53, 54, 56, 128, 68, 79, 84, 83, 45, 49, 50, 53, 
+    55, 56, 128, 68, 79, 84, 83, 45, 49, 50, 54, 55, 56, 128, 68, 79, 84, 83, 
+    45, 49, 51, 52, 53, 54, 128, 68, 79, 84, 83, 45, 49, 51, 52, 53, 55, 128, 
+    68, 79, 84, 83, 45, 49, 51, 52, 53, 56, 128, 68, 79, 84, 83, 45, 49, 51, 
+    52, 54, 55, 128, 68, 79, 84, 83, 45, 49, 51, 52, 54, 56, 128, 68, 79, 84, 
+    83, 45, 49, 51, 52, 55, 56, 128, 68, 79, 84, 83, 45, 49, 51, 53, 54, 55, 
+    128, 68, 79, 84, 83, 45, 49, 51, 53, 54, 56, 128, 68, 79, 84, 83, 45, 49, 
+    51, 53, 55, 56, 128, 68, 79, 84, 83, 45, 49, 51, 54, 55, 56, 128, 68, 79, 
+    84, 83, 45, 49, 52, 53, 54, 55, 128, 68, 79, 84, 83, 45, 49, 52, 53, 54, 
+    56, 128, 68, 79, 84, 83, 45, 49, 52, 53, 55, 56, 128, 68, 79, 84, 83, 45, 
+    49, 52, 54, 55, 56, 128, 68, 79, 84, 83, 45, 49, 53, 54, 55, 56, 128, 68, 
+    79, 84, 83, 45, 50, 51, 52, 53, 54, 128, 68, 79, 84, 83, 45, 50, 51, 52, 
+    53, 55, 128, 68, 79, 84, 83, 45, 50, 51, 52, 53, 56, 128, 68, 79, 84, 83, 
+    45, 50, 51, 52, 54, 55, 128, 68, 79, 84, 83, 45, 50, 51, 52, 54, 56, 128, 
+    68, 79, 84, 83, 45, 50, 51, 52, 55, 56, 128, 68, 79, 84, 83, 45, 50, 51, 
+    53, 54, 55, 128, 68, 79, 84, 83, 45, 50, 51, 53, 54, 56, 128, 68, 79, 84, 
+    83, 45, 50, 51, 53, 55, 56, 128, 68, 79, 84, 83, 45, 50, 51, 54, 55, 56, 
+    128, 68, 79, 84, 83, 45, 50, 52, 53, 54, 55, 128, 68, 79, 84, 83, 45, 50, 
+    52, 53, 54, 56, 128, 68, 79, 84, 83, 45, 50, 52, 53, 55, 56, 128, 68, 79, 
+    84, 83, 45, 50, 52, 54, 55, 56, 128, 68, 79, 84, 83, 45, 50, 53, 54, 55, 
+    56, 128, 68, 79, 84, 83, 45, 51, 52, 53, 54, 55, 128, 68, 79, 84, 83, 45, 
+    51, 52, 53, 54, 56, 128, 68, 79, 84, 83, 45, 51, 52, 53, 55, 56, 128, 68, 
+    79, 84, 83, 45, 51, 52, 54, 55, 56, 128, 68, 79, 84, 83, 45, 51, 53, 54, 
+    55, 56, 128, 68, 79, 84, 83, 45, 52, 53, 54, 55, 56, 128, 69, 75, 83, 84, 
+    82, 69, 80, 84, 79, 78, 128, 69, 77, 66, 82, 79, 73, 68, 69, 82, 89, 128, 
+    69, 78, 67, 79, 85, 78, 84, 69, 82, 83, 128, 69, 78, 84, 72, 85, 83, 73, 
+    65, 83, 77, 128, 69, 81, 85, 73, 65, 78, 71, 85, 76, 65, 210, 69, 88, 72, 
+    65, 85, 83, 84, 73, 79, 78, 128, 70, 65, 72, 82, 69, 78, 72, 69, 73, 84, 
+    128, 70, 69, 76, 76, 79, 87, 83, 72, 73, 80, 128, 70, 79, 82, 77, 65, 84, 
+    84, 73, 78, 71, 128, 70, 79, 85, 82, 45, 80, 69, 82, 45, 69, 205, 70, 79, 
+    85, 82, 45, 83, 84, 82, 73, 78, 199, 72, 66, 65, 83, 65, 45, 69, 83, 65, 
+    83, 193, 72, 79, 77, 79, 84, 72, 69, 84, 73, 67, 128, 72, 89, 80, 72, 69, 
+    78, 65, 84, 73, 79, 206, 73, 77, 73, 68, 73, 65, 82, 71, 79, 78, 128, 73, 
+    77, 73, 70, 84, 72, 79, 82, 79, 78, 128, 73, 78, 70, 79, 82, 77, 65, 84, 
+    73, 79, 206, 73, 78, 84, 69, 82, 76, 79, 67, 75, 69, 196, 75, 73, 82, 79, 
+    71, 85, 82, 65, 77, 85, 128, 75, 85, 78, 68, 68, 65, 76, 73, 89, 65, 128, 
+    76, 69, 70, 84, 45, 83, 72, 65, 68, 69, 196, 76, 73, 77, 73, 84, 65, 84, 
+    73, 79, 78, 128, 77, 69, 77, 66, 69, 82, 83, 72, 73, 80, 128, 78, 65, 78, 
+    71, 77, 79, 78, 84, 72, 79, 128, 78, 79, 78, 45, 74, 79, 73, 78, 69, 82, 
+    128, 78, 79, 78, 70, 79, 82, 75, 73, 78, 71, 128, 79, 80, 80, 82, 69, 83, 
+    83, 73, 79, 78, 128, 80, 65, 76, 65, 84, 65, 76, 73, 90, 69, 196, 80, 65, 
+    84, 72, 65, 77, 65, 83, 65, 84, 128, 80, 79, 83, 83, 69, 83, 83, 73, 79, 
+    78, 128, 80, 82, 79, 74, 69, 67, 84, 73, 79, 78, 128, 80, 82, 79, 74, 69, 
+    67, 84, 73, 86, 69, 128, 82, 65, 68, 73, 79, 65, 67, 84, 73, 86, 197, 82, 
+    65, 72, 77, 65, 84, 85, 76, 76, 65, 200, 82, 69, 83, 73, 83, 84, 65, 78, 
+    67, 69, 128, 82, 69, 83, 79, 76, 85, 84, 73, 79, 78, 128, 82, 69, 86, 79, 
+    76, 85, 84, 73, 79, 78, 128, 83, 65, 67, 82, 73, 70, 73, 67, 73, 65, 204, 
+    83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 128, 83, 69, 76, 69, 67, 84, 79, 
+    82, 45, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 51, 128, 83, 69, 76, 
+    69, 67, 84, 79, 82, 45, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 53, 
+    128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 54, 128, 83, 69, 76, 69, 67, 84, 
+    79, 82, 45, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 56, 128, 83, 69, 
+    76, 69, 67, 84, 79, 82, 45, 57, 128, 83, 72, 65, 76, 83, 72, 69, 76, 69, 
+    84, 128, 83, 73, 79, 83, 45, 72, 73, 69, 85, 72, 128, 83, 73, 79, 83, 45, 
+    73, 69, 85, 78, 71, 128, 83, 73, 79, 83, 45, 77, 73, 69, 85, 77, 128, 83, 
+    83, 65, 78, 71, 65, 82, 65, 69, 65, 128, 83, 84, 65, 78, 68, 83, 84, 73, 
+    76, 76, 128, 83, 85, 66, 80, 85, 78, 67, 84, 73, 83, 128, 83, 85, 66, 83, 
+    84, 73, 84, 85, 84, 69, 128, 83, 89, 78, 67, 72, 82, 79, 78, 79, 85, 211, 
+    84, 69, 82, 77, 73, 78, 65, 84, 79, 82, 128, 84, 72, 73, 82, 84, 89, 45, 
+    79, 78, 69, 128, 84, 79, 80, 45, 76, 73, 71, 72, 84, 69, 196, 84, 82, 65, 
+    78, 83, 86, 69, 82, 83, 65, 204, 84, 87, 69, 78, 84, 89, 45, 83, 73, 88, 
+    128, 86, 69, 82, 84, 73, 67, 65, 76, 76, 89, 128, 87, 73, 68, 69, 45, 72, 
+    69, 65, 68, 69, 196, 68, 69, 83, 67, 69, 78, 68, 69, 82, 128, 76, 69, 83, 
+    83, 45, 84, 72, 65, 78, 128, 65, 78, 78, 79, 84, 65, 84, 73, 79, 206, 69, 
+    81, 85, 73, 86, 65, 76, 69, 78, 212, 83, 69, 80, 65, 82, 65, 84, 79, 82, 
+    128, 65, 82, 82, 79, 87, 72, 69, 65, 68, 128, 65, 76, 80, 65, 80, 82, 65, 
+    65, 78, 193, 68, 79, 87, 78, 87, 65, 82, 68, 83, 128, 69, 88, 84, 69, 78, 
+    83, 73, 79, 78, 128, 76, 69, 78, 84, 73, 67, 85, 76, 65, 210, 80, 72, 65, 
+    82, 89, 78, 71, 69, 65, 204, 80, 82, 79, 76, 65, 84, 73, 79, 78, 197, 83, 
+    69, 77, 73, 67, 79, 76, 79, 78, 128, 84, 85, 82, 78, 83, 84, 73, 76, 69, 
+    128, 84, 87, 79, 45, 72, 69, 65, 68, 69, 196, 65, 77, 80, 69, 82, 83, 65, 
+    78, 68, 128, 76, 69, 70, 84, 87, 65, 82, 68, 83, 128, 84, 82, 79, 69, 90, 
+    69, 78, 73, 65, 206, 67, 79, 77, 77, 69, 82, 67, 73, 65, 204, 83, 69, 77, 
+    73, 68, 73, 82, 69, 67, 212, 83, 69, 86, 69, 78, 84, 69, 69, 78, 128, 87, 
+    79, 79, 68, 83, 45, 67, 82, 69, 197, 66, 65, 67, 75, 83, 76, 65, 83, 72, 
+    128, 68, 73, 65, 76, 89, 84, 73, 75, 65, 128, 69, 88, 84, 82, 65, 45, 72, 
+    73, 71, 200, 70, 73, 88, 69, 68, 45, 70, 79, 82, 205, 73, 77, 80, 69, 82, 
+    70, 69, 67, 84, 193, 73, 78, 68, 73, 67, 65, 84, 79, 82, 128, 82, 69, 67, 
+    84, 65, 78, 71, 76, 69, 128, 86, 69, 82, 84, 73, 67, 65, 76, 76, 217, 67, 
+    79, 78, 84, 65, 73, 78, 73, 78, 199, 68, 69, 76, 73, 77, 73, 84, 69, 82, 
+    128, 69, 78, 67, 76, 79, 83, 85, 82, 69, 128, 69, 80, 73, 68, 65, 85, 82, 
+    69, 65, 206, 72, 69, 82, 77, 73, 79, 78, 73, 65, 206, 72, 79, 85, 82, 71, 
+    76, 65, 83, 83, 128, 83, 69, 77, 73, 66, 82, 69, 86, 73, 211, 83, 69, 77, 
+    73, 77, 73, 78, 73, 77, 193, 83, 78, 79, 87, 70, 76, 65, 75, 69, 128, 84, 
+    82, 73, 65, 78, 71, 85, 76, 65, 210, 65, 80, 79, 83, 84, 82, 79, 70, 79, 
+    201, 65, 80, 79, 83, 84, 82, 79, 70, 79, 211, 65, 82, 80, 69, 71, 71, 73, 
+    65, 84, 207, 65, 84, 72, 65, 80, 65, 83, 67, 65, 206, 67, 69, 78, 84, 82, 
+    69, 76, 73, 78, 197, 67, 72, 65, 82, 65, 67, 84, 69, 82, 128, 67, 79, 80, 
+    82, 79, 68, 85, 67, 84, 128, 67, 82, 79, 83, 83, 72, 65, 84, 67, 200, 69, 
+    77, 66, 69, 68, 68, 73, 78, 71, 128, 70, 73, 78, 65, 78, 67, 73, 65, 76, 
+    128, 70, 79, 76, 76, 79, 87, 73, 78, 71, 128, 70, 82, 69, 84, 66, 79, 65, 
+    82, 68, 128, 71, 69, 82, 83, 72, 65, 89, 73, 77, 128, 71, 79, 82, 84, 72, 
+    77, 73, 75, 79, 206, 73, 67, 72, 73, 77, 65, 84, 79, 83, 128, 75, 72, 65, 
+    75, 65, 83, 83, 73, 65, 206, 80, 65, 65, 45, 80, 73, 76, 76, 65, 128, 80, 
+    65, 82, 65, 80, 72, 82, 65, 83, 197, 80, 69, 78, 84, 65, 83, 69, 77, 69, 
+    128, 80, 72, 73, 76, 73, 80, 80, 73, 78, 197, 83, 69, 77, 73, 67, 73, 82, 
+    67, 76, 197, 83, 85, 77, 77, 65, 84, 73, 79, 78, 128, 83, 85, 80, 69, 82, 
+    86, 73, 83, 69, 128, 83, 89, 77, 66, 79, 76, 45, 49, 49, 128, 83, 89, 77, 
+    66, 79, 76, 45, 49, 50, 128, 83, 89, 77, 66, 79, 76, 45, 49, 51, 128, 83, 
+    89, 77, 66, 79, 76, 45, 49, 52, 128, 83, 89, 77, 66, 79, 76, 45, 49, 55, 
+    128, 83, 89, 77, 66, 79, 76, 45, 49, 56, 128, 83, 89, 77, 66, 79, 76, 45, 
+    49, 57, 128, 83, 89, 77, 66, 79, 76, 45, 50, 51, 128, 83, 89, 77, 66, 79, 
+    76, 45, 50, 52, 128, 83, 89, 77, 66, 79, 76, 45, 53, 48, 128, 83, 89, 77, 
+    66, 79, 76, 45, 53, 49, 128, 83, 89, 77, 66, 79, 76, 45, 53, 50, 128, 83, 
+    89, 77, 66, 79, 76, 45, 53, 51, 128, 83, 89, 77, 66, 79, 76, 45, 53, 52, 
+    128, 84, 69, 76, 69, 80, 72, 79, 78, 69, 128, 84, 69, 84, 82, 65, 83, 69, 
+    77, 69, 128, 84, 82, 69, 77, 79, 76, 79, 45, 49, 128, 84, 82, 69, 77, 79, 
+    76, 79, 45, 50, 128, 84, 82, 69, 77, 79, 76, 79, 45, 51, 128, 84, 82, 73, 
+    71, 82, 65, 77, 77, 79, 211, 84, 82, 79, 75, 85, 84, 65, 83, 84, 201, 65, 
+    65, 66, 65, 65, 70, 73, 76, 73, 128, 65, 66, 85, 78, 68, 65, 78, 67, 69, 
+    128, 65, 76, 45, 76, 65, 75, 85, 78, 65, 128, 65, 78, 84, 73, 70, 79, 78, 
+    73, 65, 128, 65, 80, 80, 82, 79, 65, 67, 72, 69, 211, 65, 82, 45, 82, 65, 
+    72, 69, 69, 77, 128, 65, 83, 83, 69, 82, 84, 73, 79, 78, 128, 65, 84, 84, 
+    69, 78, 84, 73, 79, 78, 128, 66, 65, 67, 75, 83, 80, 65, 67, 69, 128, 66, 
+    69, 71, 73, 78, 78, 73, 78, 71, 128, 66, 73, 66, 76, 69, 45, 67, 82, 69, 
+    197, 67, 65, 80, 82, 73, 67, 79, 82, 78, 128, 67, 72, 65, 86, 73, 89, 65, 
+    78, 73, 128, 67, 76, 79, 83, 69, 78, 69, 83, 83, 128, 67, 79, 77, 80, 76, 
+    69, 84, 69, 68, 128, 67, 79, 78, 83, 84, 65, 78, 67, 89, 128, 67, 79, 80, 
+    89, 82, 73, 71, 72, 84, 128, 68, 65, 72, 89, 65, 65, 85, 83, 72, 128, 68, 
+    65, 82, 75, 69, 78, 73, 78, 71, 128, 68, 69, 80, 65, 82, 84, 85, 82, 69, 
+    128, 68, 69, 83, 67, 69, 78, 68, 73, 78, 199, 68, 73, 70, 70, 69, 82, 69, 
+    78, 67, 197, 68, 73, 70, 70, 73, 67, 85, 76, 84, 217, 68, 79, 84, 83, 45, 
+    49, 50, 51, 52, 128, 68, 79, 84, 83, 45, 49, 50, 51, 53, 128, 68, 79, 84, 
+    83, 45, 49, 50, 51, 54, 128, 68, 79, 84, 83, 45, 49, 50, 51, 55, 128, 68, 
+    79, 84, 83, 45, 49, 50, 51, 56, 128, 68, 79, 84, 83, 45, 49, 50, 52, 53, 
+    128, 68, 79, 84, 83, 45, 49, 50, 52, 54, 128, 68, 79, 84, 83, 45, 49, 50, 
+    52, 55, 128, 68, 79, 84, 83, 45, 49, 50, 52, 56, 128, 68, 79, 84, 83, 45, 
+    49, 50, 53, 54, 128, 68, 79, 84, 83, 45, 49, 50, 53, 55, 128, 68, 79, 84, 
+    83, 45, 49, 50, 53, 56, 128, 68, 79, 84, 83, 45, 49, 50, 54, 55, 128, 68, 
+    79, 84, 83, 45, 49, 50, 54, 56, 128, 68, 79, 84, 83, 45, 49, 50, 55, 56, 
+    128, 68, 79, 84, 83, 45, 49, 51, 52, 53, 128, 68, 79, 84, 83, 45, 49, 51, 
+    52, 54, 128, 68, 79, 84, 83, 45, 49, 51, 52, 55, 128, 68, 79, 84, 83, 45, 
+    49, 51, 52, 56, 128, 68, 79, 84, 83, 45, 49, 51, 53, 54, 128, 68, 79, 84, 
+    83, 45, 49, 51, 53, 55, 128, 68, 79, 84, 83, 45, 49, 51, 53, 56, 128, 68, 
+    79, 84, 83, 45, 49, 51, 54, 55, 128, 68, 79, 84, 83, 45, 49, 51, 54, 56, 
+    128, 68, 79, 84, 83, 45, 49, 51, 55, 56, 128, 68, 79, 84, 83, 45, 49, 52, 
+    53, 54, 128, 68, 79, 84, 83, 45, 49, 52, 53, 55, 128, 68, 79, 84, 83, 45, 
+    49, 52, 53, 56, 128, 68, 79, 84, 83, 45, 49, 52, 54, 55, 128, 68, 79, 84, 
+    83, 45, 49, 52, 54, 56, 128, 68, 79, 84, 83, 45, 49, 52, 55, 56, 128, 68, 
+    79, 84, 83, 45, 49, 53, 54, 55, 128, 68, 79, 84, 83, 45, 49, 53, 54, 56, 
+    128, 68, 79, 84, 83, 45, 49, 53, 55, 56, 128, 68, 79, 84, 83, 45, 49, 54, 
+    55, 56, 128, 68, 79, 84, 83, 45, 50, 51, 52, 53, 128, 68, 79, 84, 83, 45, 
+    50, 51, 52, 54, 128, 68, 79, 84, 83, 45, 50, 51, 52, 55, 128, 68, 79, 84, 
+    83, 45, 50, 51, 52, 56, 128, 68, 79, 84, 83, 45, 50, 51, 53, 54, 128, 68, 
+    79, 84, 83, 45, 50, 51, 53, 55, 128, 68, 79, 84, 83, 45, 50, 51, 53, 56, 
+    128, 68, 79, 84, 83, 45, 50, 51, 54, 55, 128, 68, 79, 84, 83, 45, 50, 51, 
+    54, 56, 128, 68, 79, 84, 83, 45, 50, 51, 55, 56, 128, 68, 79, 84, 83, 45, 
+    50, 52, 53, 54, 128, 68, 79, 84, 83, 45, 50, 52, 53, 55, 128, 68, 79, 84, 
+    83, 45, 50, 52, 53, 56, 128, 68, 79, 84, 83, 45, 50, 52, 54, 55, 128, 68, 
+    79, 84, 83, 45, 50, 52, 54, 56, 128, 68, 79, 84, 83, 45, 50, 52, 55, 56, 
+    128, 68, 79, 84, 83, 45, 50, 53, 54, 55, 128, 68, 79, 84, 83, 45, 50, 53, 
+    54, 56, 128, 68, 79, 84, 83, 45, 50, 53, 55, 56, 128, 68, 79, 84, 83, 45, 
+    50, 54, 55, 56, 128, 68, 79, 84, 83, 45, 51, 52, 53, 54, 128, 68, 79, 84, 
+    83, 45, 51, 52, 53, 55, 128, 68, 79, 84, 83, 45, 51, 52, 53, 56, 128, 68, 
+    79, 84, 83, 45, 51, 52, 54, 55, 128, 68, 79, 84, 83, 45, 51, 52, 54, 56, 
+    128, 68, 79, 84, 83, 45, 51, 52, 55, 56, 128, 68, 79, 84, 83, 45, 51, 53, 
+    54, 55, 128, 68, 79, 84, 83, 45, 51, 53, 54, 56, 128, 68, 79, 84, 83, 45, 
+    51, 53, 55, 56, 128, 68, 79, 84, 83, 45, 51, 54, 55, 56, 128, 68, 79, 84, 
+    83, 45, 52, 53, 54, 55, 128, 68, 79, 84, 83, 45, 52, 53, 54, 56, 128, 68, 
+    79, 84, 83, 45, 52, 53, 55, 56, 128, 68, 79, 84, 83, 45, 52, 54, 55, 56, 
+    128, 68, 79, 84, 83, 45, 53, 54, 55, 56, 128, 69, 69, 66, 69, 69, 70, 73, 
+    76, 73, 128, 69, 78, 65, 82, 77, 79, 78, 73, 79, 211, 69, 78, 68, 69, 65, 
+    86, 79, 85, 82, 128, 69, 78, 68, 79, 70, 79, 78, 79, 78, 128, 69, 83, 84, 
+    73, 77, 65, 84, 69, 83, 128, 69, 88, 67, 69, 76, 76, 69, 78, 84, 128, 69, 
+    89, 66, 69, 89, 70, 73, 76, 73, 128, 70, 79, 79, 84, 83, 84, 79, 79, 76, 
+    128, 70, 79, 83, 84, 69, 82, 73, 78, 71, 128, 70, 82, 73, 67, 65, 84, 73, 
+    86, 69, 128, 71, 65, 84, 72, 69, 82, 73, 78, 71, 128, 71, 69, 77, 73, 78, 
+    65, 84, 73, 79, 206, 71, 78, 65, 86, 73, 89, 65, 78, 73, 128, 71, 79, 82, 
+    71, 79, 84, 69, 82, 73, 128, 71, 82, 69, 65, 84, 78, 69, 83, 83, 128, 71, 
+    85, 82, 65, 77, 85, 84, 79, 78, 128, 72, 69, 75, 85, 84, 65, 65, 82, 85, 
+    128, 72, 79, 77, 79, 84, 72, 69, 84, 73, 195, 72, 89, 83, 84, 69, 82, 69, 
+    83, 73, 211, 73, 76, 85, 85, 89, 65, 78, 78, 65, 128, 73, 77, 73, 70, 84, 
+    72, 79, 82, 65, 128, 73, 78, 67, 79, 77, 80, 76, 69, 84, 197, 73, 78, 67, 
+    82, 69, 77, 69, 78, 84, 128, 73, 78, 68, 85, 83, 84, 82, 73, 65, 204, 73, 
+    78, 70, 76, 85, 69, 78, 67, 69, 128, 73, 78, 78, 79, 67, 69, 78, 67, 69, 
+    128, 73, 82, 85, 85, 89, 65, 78, 78, 65, 128, 74, 69, 82, 85, 83, 65, 76, 
+    69, 77, 128, 75, 65, 84, 65, 86, 65, 83, 77, 65, 128, 75, 69, 77, 80, 72, 
+    82, 69, 78, 71, 128, 75, 69, 78, 84, 73, 77, 65, 84, 65, 128, 75, 73, 82, 
+    79, 87, 65, 84, 84, 79, 128, 75, 82, 65, 84, 73, 77, 65, 84, 65, 128, 75, 
+    85, 82, 85, 90, 69, 73, 82, 79, 128, 76, 65, 66, 79, 85, 82, 73, 78, 71, 
+    128, 76, 72, 65, 86, 73, 89, 65, 78, 73, 128, 76, 73, 71, 72, 84, 78, 73, 
+    78, 71, 128, 77, 65, 73, 84, 65, 73, 75, 72, 85, 128, 77, 65, 84, 69, 82, 
+    73, 65, 76, 83, 128, 77, 69, 84, 79, 66, 69, 76, 85, 83, 128, 77, 73, 82, 
+    73, 66, 65, 65, 82, 85, 128, 77, 79, 78, 79, 83, 84, 65, 66, 76, 197, 77, 
+    79, 79, 83, 69, 45, 67, 82, 69, 197, 77, 85, 75, 80, 72, 82, 69, 78, 71, 
+    128, 78, 73, 71, 71, 65, 72, 73, 84, 65, 128, 79, 65, 66, 79, 65, 70, 73, 
+    76, 73, 128, 79, 79, 66, 79, 79, 70, 73, 76, 73, 128, 79, 82, 84, 72, 79, 
+    71, 79, 78, 65, 204, 80, 65, 73, 89, 65, 78, 78, 79, 73, 128, 80, 65, 82, 
+    65, 71, 82, 65, 80, 72, 128, 80, 73, 65, 83, 85, 84, 79, 82, 85, 128, 80, 
+    73, 84, 67, 72, 70, 79, 82, 75, 128, 80, 73, 90, 90, 73, 67, 65, 84, 79, 
+    128, 80, 76, 85, 83, 45, 77, 73, 78, 85, 211, 80, 79, 82, 82, 69, 67, 84, 
+    85, 83, 128, 80, 82, 65, 77, 45, 66, 85, 79, 78, 128, 80, 82, 65, 77, 45, 
+    77, 85, 79, 89, 128, 80, 82, 79, 84, 79, 86, 65, 82, 89, 211, 81, 85, 65, 
+    84, 69, 82, 78, 73, 79, 206, 81, 85, 69, 83, 84, 73, 79, 78, 69, 196, 81, 
+    85, 83, 72, 83, 72, 65, 89, 65, 128, 82, 69, 71, 73, 83, 84, 69, 82, 69, 
+    196, 82, 69, 76, 65, 84, 73, 79, 78, 65, 204, 82, 69, 80, 82, 69, 83, 69, 
+    78, 84, 128, 82, 69, 83, 73, 68, 69, 78, 67, 69, 128, 82, 69, 83, 85, 80, 
+    73, 78, 85, 83, 128, 82, 73, 71, 72, 84, 45, 83, 73, 68, 197, 83, 67, 65, 
+    78, 68, 73, 67, 85, 83, 128, 83, 69, 80, 84, 69, 77, 66, 69, 82, 128, 83, 
+    69, 86, 69, 82, 65, 78, 67, 69, 128, 83, 72, 65, 86, 73, 89, 65, 78, 73, 
+    128, 83, 72, 79, 82, 84, 69, 78, 69, 82, 128, 83, 72, 79, 85, 76, 68, 69, 
+    82, 69, 196, 83, 73, 88, 45, 80, 69, 82, 45, 69, 205, 83, 73, 88, 45, 83, 
+    84, 82, 73, 78, 199, 83, 84, 82, 79, 75, 69, 45, 49, 48, 128, 83, 84, 82, 
+    79, 75, 69, 45, 49, 49, 128, 83, 85, 66, 83, 84, 73, 84, 85, 84, 197, 83, 
+    85, 83, 80, 69, 78, 83, 73, 79, 206, 83, 89, 77, 66, 79, 76, 45, 49, 48, 
+    128, 83, 89, 77, 66, 79, 76, 45, 49, 53, 128, 83, 89, 77, 66, 79, 76, 45, 
+    49, 54, 128, 83, 89, 77, 66, 79, 76, 45, 50, 48, 128, 83, 89, 77, 66, 79, 
+    76, 45, 50, 49, 128, 83, 89, 77, 66, 79, 76, 45, 50, 50, 128, 83, 89, 77, 
+    66, 79, 76, 45, 50, 53, 128, 83, 89, 77, 66, 79, 76, 45, 50, 54, 128, 83, 
+    89, 77, 66, 79, 76, 45, 50, 55, 128, 83, 89, 77, 66, 79, 76, 45, 50, 57, 
+    128, 83, 89, 77, 66, 79, 76, 45, 51, 48, 128, 83, 89, 77, 66, 79, 76, 45, 
+    51, 50, 128, 83, 89, 77, 66, 79, 76, 45, 51, 54, 128, 83, 89, 77, 66, 79, 
+    76, 45, 51, 55, 128, 83, 89, 77, 66, 79, 76, 45, 51, 56, 128, 83, 89, 77, 
+    66, 79, 76, 45, 51, 57, 128, 83, 89, 77, 66, 79, 76, 45, 52, 48, 128, 83, 
+    89, 77, 66, 79, 76, 45, 52, 50, 128, 83, 89, 77, 66, 79, 76, 45, 52, 51, 
+    128, 83, 89, 77, 66, 79, 76, 45, 52, 53, 128, 83, 89, 77, 66, 79, 76, 45, 
+    52, 55, 128, 83, 89, 77, 66, 79, 76, 45, 52, 56, 128, 83, 89, 77, 66, 79, 
+    76, 45, 52, 57, 128, 83, 89, 82, 77, 65, 84, 73, 75, 73, 128, 84, 65, 75, 
+    72, 65, 76, 76, 85, 83, 128, 84, 65, 87, 69, 76, 76, 69, 77, 69, 212, 84, 
+    72, 69, 82, 69, 70, 79, 82, 69, 128, 84, 72, 82, 69, 69, 45, 76, 73, 78, 
+    197, 84, 82, 73, 70, 79, 76, 73, 65, 84, 197, 84, 82, 73, 70, 79, 78, 73, 
+    65, 83, 128, 84, 82, 73, 71, 79, 82, 71, 79, 78, 128, 84, 85, 84, 69, 89, 
+    65, 83, 65, 84, 128, 86, 73, 83, 65, 82, 71, 65, 89, 65, 128, 87, 65, 83, 
+    83, 65, 76, 76, 65, 77, 128, 87, 72, 69, 69, 76, 67, 72, 65, 73, 210, 87, 
+    79, 82, 68, 83, 80, 65, 67, 69, 128, 89, 80, 79, 75, 82, 73, 83, 73, 83, 
+    128, 76, 69, 83, 83, 45, 84, 72, 65, 206, 68, 79, 87, 78, 87, 65, 82, 68, 
+    211, 84, 82, 73, 65, 78, 71, 76, 69, 128, 79, 80, 69, 82, 65, 84, 79, 82, 
+    128, 83, 85, 66, 83, 67, 82, 73, 80, 212, 84, 72, 79, 85, 83, 65, 78, 68, 
+    128, 85, 78, 68, 69, 82, 66, 65, 82, 128, 81, 85, 79, 84, 65, 84, 73, 79, 
+    206, 65, 83, 84, 69, 82, 73, 83, 75, 128, 79, 82, 78, 65, 77, 69, 78, 84, 
+    128, 82, 69, 84, 82, 79, 70, 76, 69, 216, 65, 82, 67, 72, 65, 73, 79, 78, 
+    128, 68, 73, 65, 69, 82, 69, 83, 73, 211, 66, 76, 65, 67, 75, 70, 79, 79, 
+    212, 68, 69, 78, 84, 73, 83, 84, 82, 217, 68, 73, 65, 76, 89, 84, 73, 75, 
+    193, 73, 78, 84, 69, 71, 82, 65, 76, 128, 65, 78, 85, 83, 86, 65, 82, 65, 
+    128, 86, 69, 82, 84, 73, 67, 65, 76, 128, 76, 69, 70, 84, 45, 83, 84, 69, 
+    205, 82, 69, 67, 89, 67, 76, 73, 78, 199, 65, 66, 75, 72, 65, 83, 73, 65, 
+    206, 68, 73, 65, 76, 69, 67, 84, 45, 208, 68, 79, 68, 69, 75, 65, 84, 65, 
+    128, 69, 76, 76, 73, 80, 83, 73, 83, 128, 81, 85, 65, 68, 82, 65, 78, 84, 
+    128, 81, 85, 65, 68, 82, 85, 80, 76, 197, 68, 73, 65, 84, 79, 78, 73, 75, 
+    201, 69, 78, 67, 76, 79, 83, 73, 78, 199, 79, 86, 69, 82, 76, 73, 78, 69, 
+    128, 80, 76, 65, 83, 84, 73, 67, 83, 128, 65, 82, 82, 79, 87, 72, 69, 65, 
+    196, 73, 84, 69, 82, 65, 84, 73, 79, 206, 78, 79, 84, 69, 72, 69, 65, 68, 
+    128, 78, 85, 77, 69, 82, 65, 84, 79, 210, 65, 86, 65, 71, 82, 65, 72, 65, 
+    128, 69, 73, 71, 72, 84, 69, 69, 78, 128, 70, 79, 85, 82, 84, 69, 69, 78, 
+    128, 78, 73, 78, 69, 84, 69, 69, 78, 128, 83, 85, 80, 69, 82, 83, 69, 84, 
+    128, 84, 72, 73, 82, 84, 69, 69, 78, 128, 68, 73, 65, 71, 79, 78, 65, 76, 
+    128, 69, 88, 84, 82, 65, 45, 76, 79, 215, 70, 76, 79, 82, 69, 84, 84, 69, 
+    128, 73, 68, 69, 78, 84, 73, 67, 65, 204, 75, 69, 78, 84, 73, 77, 65, 84, 
+    193, 80, 65, 82, 65, 71, 82, 65, 80, 200, 82, 69, 76, 65, 84, 73, 79, 78, 
+    128, 83, 67, 73, 83, 83, 79, 82, 83, 128, 83, 69, 66, 65, 84, 66, 69, 73, 
+    212, 83, 69, 80, 65, 82, 65, 84, 79, 210, 65, 76, 84, 69, 82, 78, 65, 84, 
+    197, 68, 68, 65, 89, 65, 78, 78, 65, 128, 68, 69, 80, 65, 82, 84, 73, 78, 
+    199, 70, 65, 78, 69, 82, 79, 83, 73, 211, 70, 73, 83, 72, 72, 79, 79, 75, 
+    128, 73, 78, 70, 73, 78, 73, 84, 89, 128, 77, 79, 85, 78, 84, 65, 73, 78, 
+    128, 77, 85, 76, 84, 73, 77, 65, 80, 128, 77, 85, 85, 82, 68, 72, 65, 74, 
+    193, 80, 65, 82, 65, 76, 76, 69, 76, 128, 80, 82, 69, 67, 69, 68, 69, 83, 
+    128, 83, 73, 88, 84, 69, 69, 78, 84, 200, 83, 80, 72, 69, 82, 73, 67, 65, 
+    204, 83, 85, 66, 76, 73, 78, 69, 65, 210, 83, 85, 67, 67, 69, 69, 68, 83, 
+    128, 83, 85, 77, 77, 65, 84, 73, 79, 206, 84, 69, 76, 69, 80, 72, 79, 78, 
+    197, 84, 72, 79, 85, 83, 65, 78, 68, 211, 89, 69, 83, 73, 69, 85, 78, 71, 
+    128, 65, 76, 76, 73, 65, 78, 67, 69, 128, 67, 65, 85, 76, 68, 82, 79, 78, 
+    128, 67, 79, 78, 83, 84, 65, 78, 84, 128, 68, 73, 70, 79, 78, 73, 65, 83, 
+    128, 68, 73, 71, 82, 65, 77, 77, 79, 211, 68, 82, 65, 67, 72, 77, 65, 83, 
+    128, 70, 76, 65, 84, 84, 69, 78, 69, 196, 71, 65, 82, 83, 72, 85, 78, 73, 
+    128, 71, 65, 84, 72, 69, 82, 73, 78, 199, 71, 76, 73, 83, 83, 65, 78, 68, 
+    207, 71, 82, 69, 71, 79, 82, 73, 65, 206, 73, 78, 67, 82, 69, 65, 83, 69, 
+    128, 73, 78, 83, 69, 82, 84, 73, 79, 206, 73, 78, 86, 73, 83, 73, 66, 76, 
+    197, 73, 83, 45, 80, 73, 76, 76, 65, 128, 79, 86, 69, 82, 82, 73, 68, 69, 
+    128, 79, 89, 82, 65, 78, 73, 83, 77, 193, 80, 69, 68, 69, 83, 84, 65, 76, 
+    128, 80, 78, 69, 85, 77, 65, 84, 65, 128, 80, 82, 65, 77, 45, 66, 85, 79, 
+    206, 80, 82, 65, 77, 45, 77, 85, 79, 217, 80, 82, 79, 76, 79, 78, 71, 69, 
+    196, 80, 82, 79, 80, 69, 76, 76, 69, 210, 82, 69, 83, 79, 85, 82, 67, 69, 
+    128, 82, 69, 83, 80, 79, 78, 83, 69, 128, 82, 69, 86, 69, 82, 83, 69, 68, 
+    128, 83, 69, 77, 73, 86, 79, 87, 69, 204, 83, 85, 66, 71, 82, 79, 85, 80, 
+    128, 83, 87, 65, 80, 80, 73, 78, 71, 128, 83, 89, 77, 66, 79, 76, 45, 49, 
+    128, 83, 89, 77, 66, 79, 76, 45, 50, 128, 83, 89, 77, 66, 79, 76, 45, 52, 
+    128, 83, 89, 77, 66, 79, 76, 45, 53, 128, 83, 89, 77, 66, 79, 76, 45, 55, 
+    128, 83, 89, 77, 66, 79, 76, 45, 56, 128, 83, 89, 77, 77, 69, 84, 82, 73, 
+    195, 84, 79, 71, 69, 84, 72, 69, 82, 128, 84, 82, 73, 83, 73, 77, 79, 85, 
+    128, 84, 84, 65, 89, 65, 78, 78, 65, 128, 85, 78, 68, 69, 82, 76, 73, 78, 
+    197, 85, 78, 68, 69, 82, 84, 73, 69, 128, 85, 78, 73, 86, 69, 82, 83, 65, 
+    204, 65, 68, 68, 82, 69, 83, 83, 69, 196, 65, 69, 69, 89, 65, 78, 78, 65, 
+    128, 65, 73, 82, 80, 76, 65, 78, 69, 128, 65, 78, 85, 68, 65, 84, 84, 65, 
+    128, 65, 80, 79, 68, 69, 88, 73, 65, 128, 65, 80, 79, 84, 72, 69, 77, 65, 
+    128, 65, 80, 80, 82, 79, 65, 67, 72, 128, 65, 81, 85, 65, 82, 73, 85, 83, 
+    128, 65, 82, 45, 82, 65, 72, 77, 65, 206, 65, 82, 65, 69, 65, 45, 69, 79, 
+    128, 65, 82, 71, 79, 84, 69, 82, 73, 128, 65, 82, 73, 83, 84, 69, 82, 65, 
+    128, 65, 83, 67, 69, 78, 68, 73, 78, 199, 65, 83, 84, 69, 82, 73, 83, 75, 
+    211, 65, 83, 84, 69, 82, 73, 83, 77, 128, 65, 84, 84, 72, 65, 67, 65, 78, 
+    128, 66, 65, 67, 75, 83, 76, 65, 83, 200, 66, 69, 86, 69, 82, 65, 71, 69, 
+    128, 66, 73, 79, 72, 65, 90, 65, 82, 196, 66, 73, 83, 69, 67, 84, 73, 78, 
+    199, 66, 73, 83, 77, 73, 76, 76, 65, 200, 66, 82, 65, 78, 67, 72, 73, 78, 
+    199, 66, 85, 76, 76, 83, 69, 89, 69, 128, 66, 85, 83, 83, 89, 69, 82, 85, 
+    128, 67, 65, 68, 85, 67, 69, 85, 83, 128, 67, 65, 82, 89, 83, 84, 73, 65, 
+    206, 67, 72, 65, 77, 73, 76, 79, 78, 128, 67, 72, 65, 84, 84, 65, 87, 65, 
+    128, 67, 73, 86, 73, 76, 73, 65, 78, 128, 67, 76, 73, 77, 65, 67, 85, 83, 
+    128, 67, 79, 78, 70, 76, 73, 67, 84, 128, 67, 79, 78, 71, 82, 85, 69, 78, 
+    212, 67, 79, 78, 74, 85, 71, 65, 84, 197, 67, 79, 78, 84, 79, 85, 82, 69, 
+    196, 67, 79, 80, 89, 82, 73, 71, 72, 212, 67, 82, 69, 83, 67, 69, 78, 84, 
+    128, 68, 65, 77, 77, 65, 84, 65, 78, 128, 68, 65, 82, 75, 69, 78, 73, 78, 
+    199, 68, 65, 86, 73, 89, 65, 78, 73, 128, 68, 69, 67, 69, 77, 66, 69, 82, 
+    128, 68, 69, 67, 82, 69, 65, 83, 69, 128, 68, 69, 76, 73, 77, 73, 84, 69, 
+    210, 68, 73, 70, 84, 79, 71, 71, 79, 211, 68, 73, 71, 79, 82, 71, 79, 78, 
+    128, 68, 73, 77, 69, 78, 83, 73, 79, 206, 68, 79, 84, 83, 45, 49, 50, 51, 
+    128, 68, 79, 84, 83, 45, 49, 50, 52, 128, 68, 79, 84, 83, 45, 49, 50, 53, 
+    128, 68, 79, 84, 83, 45, 49, 50, 54, 128, 68, 79, 84, 83, 45, 49, 50, 55, 
+    128, 68, 79, 84, 83, 45, 49, 50, 56, 128, 68, 79, 84, 83, 45, 49, 51, 52, 
+    128, 68, 79, 84, 83, 45, 49, 51, 53, 128, 68, 79, 84, 83, 45, 49, 51, 54, 
+    128, 68, 79, 84, 83, 45, 49, 51, 55, 128, 68, 79, 84, 83, 45, 49, 51, 56, 
+    128, 68, 79, 84, 83, 45, 49, 52, 53, 128, 68, 79, 84, 83, 45, 49, 52, 54, 
+    128, 68, 79, 84, 83, 45, 49, 52, 55, 128, 68, 79, 84, 83, 45, 49, 52, 56, 
+    128, 68, 79, 84, 83, 45, 49, 53, 54, 128, 68, 79, 84, 83, 45, 49, 53, 55, 
+    128, 68, 79, 84, 83, 45, 49, 53, 56, 128, 68, 79, 84, 83, 45, 49, 54, 55, 
+    128, 68, 79, 84, 83, 45, 49, 54, 56, 128, 68, 79, 84, 83, 45, 49, 55, 56, 
+    128, 68, 79, 84, 83, 45, 50, 51, 52, 128, 68, 79, 84, 83, 45, 50, 51, 53, 
+    128, 68, 79, 84, 83, 45, 50, 51, 54, 128, 68, 79, 84, 83, 45, 50, 51, 55, 
+    128, 68, 79, 84, 83, 45, 50, 51, 56, 128, 68, 79, 84, 83, 45, 50, 52, 53, 
+    128, 68, 79, 84, 83, 45, 50, 52, 54, 128, 68, 79, 84, 83, 45, 50, 52, 55, 
+    128, 68, 79, 84, 83, 45, 50, 52, 56, 128, 68, 79, 84, 83, 45, 50, 53, 54, 
+    128, 68, 79, 84, 83, 45, 50, 53, 55, 128, 68, 79, 84, 83, 45, 50, 53, 56, 
+    128, 68, 79, 84, 83, 45, 50, 54, 55, 128, 68, 79, 84, 83, 45, 50, 54, 56, 
+    128, 68, 79, 84, 83, 45, 50, 55, 56, 128, 68, 79, 84, 83, 45, 51, 52, 53, 
+    128, 68, 79, 84, 83, 45, 51, 52, 54, 128, 68, 79, 84, 83, 45, 51, 52, 55, 
+    128, 68, 79, 84, 83, 45, 51, 52, 56, 128, 68, 79, 84, 83, 45, 51, 53, 54, 
+    128, 68, 79, 84, 83, 45, 51, 53, 55, 128, 68, 79, 84, 83, 45, 51, 53, 56, 
+    128, 68, 79, 84, 83, 45, 51, 54, 55, 128, 68, 79, 84, 83, 45, 51, 54, 56, 
+    128, 68, 79, 84, 83, 45, 51, 55, 56, 128, 68, 79, 84, 83, 45, 52, 53, 54, 
+    128, 68, 79, 84, 83, 45, 52, 53, 55, 128, 68, 79, 84, 83, 45, 52, 53, 56, 
+    128, 68, 79, 84, 83, 45, 52, 54, 55, 128, 68, 79, 84, 83, 45, 52, 54, 56, 
+    128, 68, 79, 84, 83, 45, 52, 55, 56, 128, 68, 79, 84, 83, 45, 53, 54, 55, 
+    128, 68, 79, 84, 83, 45, 53, 54, 56, 128, 68, 79, 84, 83, 45, 53, 55, 56, 
+    128, 68, 79, 84, 83, 45, 54, 55, 56, 128, 68, 79, 84, 84, 69, 68, 45, 76, 
+    128, 68, 79, 84, 84, 69, 68, 45, 78, 128, 68, 79, 84, 84, 69, 68, 45, 80, 
+    128, 68, 85, 82, 65, 84, 73, 79, 78, 128, 68, 86, 73, 83, 86, 65, 82, 65, 
+    128, 69, 68, 73, 84, 79, 82, 73, 65, 204, 69, 78, 86, 69, 76, 79, 80, 69, 
+    128, 69, 80, 69, 71, 69, 82, 77, 65, 128, 69, 83, 84, 73, 77, 65, 84, 69, 
+    196, 69, 83, 85, 75, 85, 85, 68, 79, 128, 69, 84, 69, 82, 78, 73, 84, 89, 
+    128, 70, 65, 67, 83, 73, 77, 73, 76, 197, 70, 65, 84, 72, 65, 84, 65, 78, 
+    128, 70, 69, 66, 82, 85, 65, 82, 89, 128, 70, 69, 83, 84, 73, 86, 65, 76, 
+    128, 70, 73, 71, 85, 82, 69, 45, 49, 128, 70, 73, 71, 85, 82, 69, 45, 50, 
+    128, 70, 73, 71, 85, 82, 69, 45, 51, 128, 70, 73, 86, 69, 45, 76, 73, 78, 
+    197, 70, 79, 85, 82, 45, 76, 73, 78, 197, 70, 82, 65, 71, 77, 69, 78, 84, 
+    128, 70, 82, 65, 71, 82, 65, 78, 84, 128, 70, 85, 76, 76, 78, 69, 83, 83, 
+    128, 70, 85, 78, 67, 84, 73, 79, 78, 128, 71, 69, 78, 73, 84, 73, 86, 69, 
+    128, 71, 69, 79, 77, 69, 84, 82, 73, 195, 72, 65, 78, 45, 65, 75, 65, 84, 
+    128, 72, 65, 82, 68, 78, 69, 83, 83, 128, 72, 65, 82, 77, 79, 78, 73, 67, 
+    128, 72, 69, 82, 77, 73, 84, 73, 65, 206, 72, 85, 65, 82, 65, 68, 68, 79, 
+    128, 73, 76, 85, 89, 65, 78, 78, 65, 128, 73, 77, 73, 70, 79, 78, 79, 78, 
+    128, 73, 78, 67, 76, 85, 68, 73, 78, 199, 73, 78, 67, 82, 69, 65, 83, 69, 
+    211, 73, 82, 85, 89, 65, 78, 78, 65, 128, 74, 65, 86, 73, 89, 65, 78, 73, 
+    128, 75, 65, 83, 82, 65, 84, 65, 78, 128, 75, 65, 84, 72, 73, 83, 84, 73, 
+    128, 75, 69, 89, 66, 79, 65, 82, 68, 128, 75, 79, 78, 84, 69, 86, 77, 65, 
+    128, 75, 82, 69, 77, 65, 83, 84, 73, 128, 76, 65, 82, 89, 78, 71, 69, 65, 
+    204, 76, 69, 70, 84, 45, 83, 73, 68, 197, 76, 73, 65, 66, 73, 76, 73, 84, 
+    217, 76, 79, 67, 65, 84, 73, 86, 69, 128, 76, 79, 82, 82, 65, 73, 78, 69, 
+    128, 77, 65, 72, 65, 80, 65, 75, 72, 128, 77, 65, 73, 77, 65, 76, 65, 73, 
+    128, 77, 65, 73, 89, 65, 77, 79, 75, 128, 77, 65, 78, 71, 65, 76, 65, 77, 
+    128, 77, 65, 83, 67, 85, 76, 73, 78, 197, 77, 69, 68, 73, 67, 73, 78, 69, 
+    128, 77, 69, 83, 83, 69, 78, 73, 65, 206, 77, 73, 78, 73, 83, 84, 69, 82, 
+    128, 77, 85, 76, 84, 73, 83, 69, 84, 128, 78, 73, 75, 72, 65, 72, 73, 84, 
+    128, 78, 79, 82, 84, 72, 87, 69, 83, 212, 78, 79, 86, 69, 77, 66, 69, 82, 
+    128, 79, 86, 69, 82, 76, 65, 73, 68, 128, 80, 65, 65, 83, 69, 78, 84, 79, 
+    128, 80, 65, 73, 82, 84, 72, 82, 65, 128, 80, 65, 76, 79, 67, 72, 75, 65, 
+    128, 80, 65, 77, 85, 68, 80, 79, 68, 128, 80, 65, 82, 73, 67, 72, 79, 78, 
+    128, 80, 65, 86, 73, 89, 65, 78, 73, 128, 80, 69, 76, 65, 83, 84, 79, 78, 
+    128, 80, 69, 82, 77, 65, 78, 69, 78, 212, 80, 73, 84, 67, 72, 70, 79, 82, 
+    203, 80, 76, 69, 84, 72, 82, 79, 78, 128, 80, 79, 82, 82, 69, 67, 84, 85, 
+    211, 80, 82, 65, 77, 45, 66, 69, 73, 128, 80, 82, 65, 77, 45, 80, 73, 73, 
+    128, 80, 82, 79, 70, 79, 85, 78, 68, 128, 80, 82, 79, 71, 82, 69, 83, 83, 
+    128, 80, 83, 73, 70, 73, 83, 84, 79, 206, 81, 65, 73, 82, 84, 72, 82, 65, 
+    128, 81, 85, 65, 82, 84, 69, 82, 83, 128, 81, 85, 69, 83, 84, 73, 79, 78, 
+    128, 82, 69, 67, 69, 80, 84, 73, 86, 197, 82, 69, 67, 79, 82, 68, 69, 82, 
+    128, 82, 69, 67, 79, 82, 68, 73, 78, 199, 82, 69, 67, 84, 65, 78, 71, 76, 
+    197, 82, 69, 70, 69, 82, 69, 78, 67, 197, 82, 69, 76, 73, 71, 73, 79, 78, 
+    128, 82, 69, 78, 84, 79, 71, 69, 78, 128, 82, 73, 71, 72, 84, 72, 65, 78, 
+    196, 82, 85, 75, 75, 65, 75, 72, 65, 128, 83, 65, 78, 84, 73, 73, 77, 85, 
+    128, 83, 65, 88, 73, 77, 65, 84, 65, 128, 83, 67, 65, 78, 68, 73, 67, 85, 
+    211, 83, 67, 79, 82, 80, 73, 85, 83, 128, 83, 69, 77, 73, 67, 79, 76, 79, 
+    206, 83, 69, 86, 69, 78, 84, 69, 69, 206, 83, 72, 65, 77, 82, 79, 67, 75, 
+    128, 83, 72, 69, 45, 71, 79, 65, 84, 128, 83, 73, 67, 75, 78, 69, 83, 83, 
+    128, 83, 80, 76, 73, 84, 84, 73, 78, 199, 83, 84, 65, 76, 76, 73, 79, 78, 
+    128, 83, 84, 79, 80, 80, 65, 71, 69, 128, 83, 84, 79, 80, 80, 73, 78, 71, 
+    128, 83, 84, 82, 69, 78, 71, 84, 72, 128, 83, 84, 82, 69, 84, 67, 72, 69, 
+    196, 83, 84, 82, 79, 75, 69, 45, 49, 128, 83, 84, 82, 79, 75, 69, 45, 50, 
+    128, 83, 84, 82, 79, 75, 69, 45, 51, 128, 83, 84, 82, 79, 75, 69, 45, 52, 
+    128, 83, 84, 82, 79, 75, 69, 45, 53, 128, 83, 84, 82, 79, 75, 69, 45, 54, 
+    128, 83, 84, 82, 79, 75, 69, 45, 55, 128, 83, 84, 82, 79, 75, 69, 45, 56, 
+    128, 83, 84, 82, 79, 75, 69, 45, 57, 128, 83, 85, 73, 84, 65, 66, 76, 69, 
+    128, 83, 85, 82, 82, 79, 85, 78, 68, 128, 83, 89, 77, 66, 79, 76, 45, 51, 
+    128, 83, 89, 77, 66, 79, 76, 45, 54, 128, 83, 89, 77, 66, 79, 76, 45, 57, 
+    128, 83, 89, 77, 77, 69, 84, 82, 89, 128, 83, 89, 78, 68, 69, 83, 77, 79, 
+    211, 84, 65, 86, 73, 89, 65, 78, 73, 128, 84, 69, 84, 82, 65, 80, 76, 73, 
+    128, 84, 79, 82, 67, 85, 76, 85, 83, 128, 84, 82, 69, 65, 68, 73, 78, 71, 
+    128, 84, 82, 73, 67, 79, 76, 79, 78, 128, 84, 82, 79, 77, 73, 75, 79, 78, 
+    128, 84, 82, 85, 78, 67, 65, 84, 69, 196, 85, 73, 76, 76, 69, 65, 78, 78, 
+    128, 85, 77, 66, 82, 69, 76, 76, 65, 128, 85, 78, 68, 69, 82, 68, 79, 84, 
+    128, 85, 78, 77, 65, 82, 82, 73, 69, 196, 86, 69, 82, 83, 73, 67, 76, 69, 
+    128, 87, 65, 78, 68, 69, 82, 69, 82, 128, 87, 65, 83, 65, 76, 76, 65, 77, 
+    128, 89, 65, 77, 65, 75, 75, 65, 78, 128, 89, 80, 79, 75, 82, 73, 83, 73, 
+    211, 90, 65, 86, 73, 89, 65, 78, 73, 128, 90, 87, 65, 82, 65, 75, 65, 89, 
+    128, 73, 78, 86, 69, 82, 84, 69, 196, 78, 69, 71, 65, 84, 73, 86, 197, 
+    85, 71, 65, 82, 73, 84, 73, 195, 66, 85, 71, 73, 78, 69, 83, 197, 72, 85, 
+    78, 68, 82, 69, 68, 128, 67, 69, 68, 73, 76, 76, 65, 128, 84, 82, 73, 65, 
+    78, 71, 76, 197, 78, 79, 84, 69, 72, 69, 65, 196, 83, 85, 80, 69, 82, 83, 
+    69, 212, 70, 82, 65, 67, 84, 73, 79, 206, 81, 85, 69, 83, 84, 73, 79, 
+    206, 84, 65, 71, 66, 65, 78, 87, 193, 81, 85, 65, 68, 82, 65, 78, 212, 
+    68, 73, 65, 71, 79, 78, 65, 204, 85, 80, 83, 73, 76, 79, 78, 128, 79, 86, 
+    69, 82, 76, 65, 89, 128, 77, 65, 82, 84, 89, 82, 73, 193, 79, 86, 69, 82, 
+    66, 65, 82, 128, 68, 73, 65, 77, 79, 78, 68, 128, 69, 80, 83, 73, 76, 79, 
+    78, 128, 72, 65, 78, 71, 90, 72, 79, 213, 73, 78, 84, 69, 71, 82, 65, 
+    204, 77, 69, 65, 83, 85, 82, 69, 196, 79, 77, 73, 67, 82, 79, 78, 128, 
+    84, 79, 82, 84, 79, 73, 83, 197, 79, 82, 78, 65, 77, 69, 78, 212, 86, 73, 
+    83, 65, 82, 71, 65, 128, 69, 88, 84, 69, 78, 68, 69, 196, 72, 65, 82, 80, 
+    79, 79, 78, 128, 80, 82, 69, 67, 69, 68, 69, 211, 83, 79, 76, 73, 68, 85, 
+    83, 128, 83, 85, 67, 67, 69, 69, 68, 211, 84, 72, 69, 83, 80, 73, 65, 
+    206, 67, 79, 78, 84, 65, 73, 78, 211, 68, 73, 71, 82, 65, 80, 72, 128, 
+    77, 69, 84, 82, 73, 67, 65, 204, 77, 79, 78, 79, 71, 82, 65, 205, 67, 82, 
+    79, 83, 83, 73, 78, 199, 83, 73, 77, 65, 78, 83, 73, 211, 83, 84, 65, 84, 
+    69, 82, 83, 128, 83, 85, 66, 85, 78, 73, 84, 128, 83, 73, 68, 69, 87, 65, 
+    89, 211, 83, 81, 85, 65, 82, 69, 68, 128, 84, 65, 76, 69, 78, 84, 83, 
+    128, 84, 72, 79, 85, 83, 65, 78, 196, 66, 65, 82, 76, 73, 78, 69, 128, 
+    68, 73, 86, 73, 83, 73, 79, 206, 73, 79, 84, 73, 70, 73, 69, 196, 80, 65, 
+    82, 65, 76, 76, 69, 204, 83, 73, 88, 84, 69, 69, 78, 128, 83, 85, 66, 71, 
+    82, 79, 85, 208, 83, 85, 82, 82, 79, 85, 78, 196, 85, 80, 87, 65, 82, 68, 
+    83, 128, 70, 73, 70, 84, 69, 69, 78, 128, 79, 80, 69, 82, 65, 84, 79, 
+    210, 79, 82, 73, 71, 73, 78, 65, 204, 68, 73, 65, 83, 84, 79, 76, 201, 
+    68, 73, 86, 73, 68, 69, 82, 128, 70, 65, 84, 72, 65, 84, 65, 206, 73, 90, 
+    72, 73, 84, 83, 65, 128, 77, 89, 83, 76, 73, 84, 69, 128, 80, 79, 73, 78, 
+    84, 69, 82, 128, 83, 84, 82, 65, 73, 71, 72, 212, 65, 83, 84, 69, 82, 73, 
+    83, 203, 66, 65, 89, 65, 78, 78, 65, 128, 67, 72, 82, 79, 78, 79, 78, 
+    128, 68, 73, 71, 79, 82, 71, 79, 206, 69, 73, 71, 72, 84, 72, 83, 128, 
+    70, 73, 78, 71, 69, 82, 69, 196, 71, 65, 89, 65, 78, 78, 65, 128, 72, 65, 
+    82, 75, 76, 69, 65, 206, 74, 65, 89, 65, 78, 78, 65, 128, 75, 79, 82, 79, 
+    78, 73, 83, 128, 76, 69, 65, 84, 72, 69, 82, 128, 76, 79, 90, 69, 78, 71, 
+    69, 128, 77, 65, 75, 83, 85, 82, 65, 128, 78, 79, 45, 66, 82, 69, 65, 
+    203, 80, 73, 78, 87, 72, 69, 69, 204, 81, 85, 65, 82, 84, 69, 82, 211, 
+    82, 69, 80, 69, 65, 84, 69, 196, 83, 65, 89, 65, 78, 78, 65, 128, 83, 69, 
+    76, 69, 67, 84, 79, 210, 83, 81, 85, 73, 71, 71, 76, 197, 84, 69, 84, 65, 
+    82, 84, 79, 211, 84, 82, 79, 77, 73, 75, 79, 206, 65, 67, 84, 73, 86, 65, 
+    84, 197, 65, 67, 84, 85, 65, 76, 76, 217, 65, 75, 72, 77, 73, 77, 73, 
+    195, 65, 80, 79, 68, 69, 82, 77, 193, 65, 82, 73, 83, 84, 69, 82, 193, 
+    66, 69, 84, 87, 69, 69, 78, 128, 66, 73, 76, 65, 66, 73, 65, 204, 67, 65, 
+    89, 65, 78, 78, 65, 128, 67, 69, 73, 76, 73, 78, 71, 128, 67, 72, 65, 82, 
+    73, 79, 84, 128, 67, 72, 79, 82, 69, 86, 77, 193, 67, 72, 82, 79, 78, 79, 
+    85, 128, 67, 76, 79, 84, 72, 69, 83, 128, 67, 79, 82, 78, 69, 82, 83, 
+    128, 68, 65, 77, 77, 65, 84, 65, 206, 68, 65, 80, 45, 66, 85, 79, 206, 
+    68, 65, 80, 45, 77, 85, 79, 217, 68, 65, 80, 45, 80, 82, 65, 205, 68, 69, 
+    89, 84, 69, 82, 79, 211, 68, 73, 71, 65, 77, 77, 65, 128, 68, 73, 83, 73, 
+    77, 79, 85, 128, 69, 77, 80, 72, 65, 83, 73, 211, 70, 69, 77, 73, 78, 73, 
+    78, 197, 70, 69, 82, 77, 65, 84, 65, 128, 70, 73, 83, 72, 72, 79, 79, 
+    203, 71, 76, 65, 71, 79, 76, 73, 128, 73, 78, 72, 69, 82, 69, 78, 212, 
+    73, 78, 84, 69, 82, 73, 79, 210, 75, 65, 83, 82, 65, 84, 65, 206, 75, 65, 
+    89, 65, 78, 78, 65, 128, 75, 79, 77, 66, 85, 86, 65, 128, 76, 45, 83, 72, 
+    65, 80, 69, 196, 76, 65, 84, 73, 78, 65, 84, 197, 76, 65, 89, 65, 78, 78, 
+    65, 128, 76, 74, 85, 68, 73, 74, 69, 128, 76, 79, 71, 79, 84, 89, 80, 
+    197, 77, 69, 65, 83, 85, 82, 69, 128, 77, 85, 76, 84, 73, 83, 69, 212, 
+    78, 65, 89, 65, 78, 78, 65, 128, 79, 77, 73, 83, 83, 73, 79, 206, 80, 65, 
+    89, 65, 78, 78, 65, 128, 80, 69, 68, 69, 83, 84, 65, 204, 80, 69, 84, 65, 
+    76, 76, 69, 196, 80, 82, 65, 77, 45, 66, 69, 201, 80, 82, 65, 77, 45, 80, 
+    73, 201, 81, 85, 65, 82, 84, 69, 82, 128, 82, 71, 89, 73, 78, 71, 83, 
+    128, 83, 45, 83, 72, 65, 80, 69, 196, 83, 69, 77, 73, 83, 79, 70, 212, 
+    83, 69, 77, 75, 65, 84, 72, 128, 83, 69, 86, 69, 78, 84, 89, 128, 83, 72, 
+    65, 80, 73, 78, 71, 128, 83, 72, 84, 65, 80, 73, 67, 128, 83, 79, 67, 73, 
+    69, 84, 89, 128, 83, 80, 65, 82, 75, 76, 69, 128, 83, 80, 69, 67, 73, 65, 
+    76, 128, 83, 84, 65, 78, 68, 65, 82, 196, 83, 84, 82, 79, 75, 69, 83, 
+    128, 84, 72, 69, 83, 69, 79, 83, 128, 84, 72, 85, 78, 68, 69, 82, 128, 
+    84, 82, 73, 83, 69, 77, 69, 128, 85, 66, 65, 68, 65, 77, 65, 128, 87, 65, 
+    73, 84, 73, 78, 71, 128, 90, 72, 73, 86, 69, 84, 69, 128, 65, 65, 89, 65, 
+    78, 78, 65, 128, 65, 66, 65, 70, 73, 76, 73, 128, 65, 68, 86, 65, 78, 67, 
+    69, 128, 65, 69, 89, 65, 78, 78, 65, 128, 65, 73, 89, 65, 78, 78, 65, 
+    128, 65, 76, 69, 77, 66, 73, 67, 128, 65, 76, 86, 69, 79, 76, 65, 210, 
+    65, 78, 71, 83, 84, 82, 79, 205, 65, 78, 71, 85, 76, 65, 82, 128, 65, 78, 
+    85, 83, 86, 65, 82, 193, 65, 80, 79, 84, 72, 69, 83, 128, 65, 82, 65, 69, 
+    65, 45, 73, 128, 65, 82, 65, 69, 65, 45, 85, 128, 65, 82, 67, 72, 65, 73, 
+    79, 206, 65, 82, 79, 85, 83, 73, 78, 199, 65, 85, 89, 65, 78, 78, 65, 
+    128, 66, 65, 65, 82, 69, 82, 85, 128, 66, 65, 73, 82, 75, 65, 78, 128, 
+    66, 65, 82, 82, 69, 75, 72, 128, 66, 65, 82, 82, 73, 69, 82, 128, 66, 65, 
+    84, 72, 84, 85, 66, 128, 66, 69, 67, 65, 85, 83, 69, 128, 66, 69, 76, 71, 
+    84, 72, 79, 210, 66, 69, 82, 75, 65, 78, 65, 206, 66, 73, 68, 69, 78, 84, 
+    65, 204, 66, 79, 85, 78, 68, 65, 82, 217, 66, 82, 65, 75, 67, 69, 84, 
+    128, 66, 82, 73, 83, 84, 76, 69, 128, 66, 85, 85, 77, 73, 83, 72, 128, 
+    67, 65, 69, 83, 85, 82, 65, 128, 67, 65, 80, 73, 84, 65, 76, 128, 67, 65, 
+    82, 82, 73, 65, 71, 197, 67, 69, 76, 83, 73, 85, 83, 128, 67, 72, 65, 77, 
+    73, 76, 73, 128, 67, 76, 73, 78, 71, 73, 78, 199, 67, 79, 77, 80, 65, 82, 
+    69, 128, 67, 79, 78, 83, 84, 65, 78, 212, 67, 79, 78, 84, 65, 67, 84, 
+    128, 67, 79, 82, 79, 78, 73, 83, 128, 67, 79, 82, 82, 69, 67, 84, 128, 
+    67, 82, 69, 65, 84, 73, 86, 197, 67, 82, 69, 83, 67, 69, 78, 212, 67, 82, 
+    85, 90, 69, 73, 82, 207, 67, 85, 83, 84, 79, 77, 69, 210, 67, 87, 69, 79, 
+    82, 84, 72, 128, 67, 89, 80, 69, 82, 85, 83, 128, 67, 89, 82, 69, 78, 65, 
+    73, 195, 68, 65, 71, 65, 76, 71, 65, 128, 68, 69, 67, 65, 89, 69, 68, 
+    128, 68, 69, 89, 84, 69, 82, 79, 213, 68, 72, 65, 76, 65, 84, 72, 128, 
+    68, 73, 65, 77, 69, 84, 69, 210, 68, 73, 65, 84, 79, 78, 79, 206, 68, 73, 
+    71, 82, 65, 77, 77, 193, 68, 73, 77, 77, 73, 78, 71, 128, 68, 73, 80, 76, 
+    79, 85, 78, 128, 68, 73, 82, 69, 67, 84, 76, 217, 68, 73, 86, 73, 68, 69, 
+    83, 128, 68, 79, 84, 83, 45, 49, 50, 128, 68, 79, 84, 83, 45, 49, 51, 
+    128, 68, 79, 84, 83, 45, 49, 52, 128, 68, 79, 84, 83, 45, 49, 53, 128, 
+    68, 79, 84, 83, 45, 49, 54, 128, 68, 79, 84, 83, 45, 49, 55, 128, 68, 79, 
+    84, 83, 45, 49, 56, 128, 68, 79, 84, 83, 45, 50, 51, 128, 68, 79, 84, 83, 
+    45, 50, 52, 128, 68, 79, 84, 83, 45, 50, 53, 128, 68, 79, 84, 83, 45, 50, 
+    54, 128, 68, 79, 84, 83, 45, 50, 55, 128, 68, 79, 84, 83, 45, 50, 56, 
+    128, 68, 79, 84, 83, 45, 51, 52, 128, 68, 79, 84, 83, 45, 51, 53, 128, 
+    68, 79, 84, 83, 45, 51, 54, 128, 68, 79, 84, 83, 45, 51, 55, 128, 68, 79, 
+    84, 83, 45, 51, 56, 128, 68, 79, 84, 83, 45, 52, 53, 128, 68, 79, 84, 83, 
+    45, 52, 54, 128, 68, 79, 84, 83, 45, 52, 55, 128, 68, 79, 84, 83, 45, 52, 
+    56, 128, 68, 79, 84, 83, 45, 53, 54, 128, 68, 79, 84, 83, 45, 53, 55, 
+    128, 68, 79, 84, 83, 45, 53, 56, 128, 68, 79, 84, 83, 45, 54, 55, 128, 
+    68, 79, 84, 83, 45, 54, 56, 128, 68, 79, 84, 83, 45, 55, 56, 128, 68, 82, 
+    65, 67, 72, 77, 65, 128, 68, 82, 65, 70, 84, 73, 78, 199, 69, 65, 66, 72, 
+    65, 68, 72, 128, 69, 65, 68, 72, 65, 68, 72, 128, 69, 66, 69, 70, 73, 76, 
+    73, 128, 69, 73, 71, 72, 84, 69, 69, 206, 69, 76, 65, 70, 82, 79, 78, 
+    128, 69, 76, 69, 67, 84, 82, 73, 195, 69, 78, 81, 85, 73, 82, 89, 128, 
+    69, 78, 84, 69, 82, 73, 78, 199, 69, 84, 78, 65, 72, 84, 65, 128, 69, 86, 
+    69, 78, 73, 78, 71, 128, 70, 65, 73, 76, 85, 82, 69, 128, 70, 65, 89, 65, 
+    78, 78, 65, 128, 70, 69, 65, 84, 72, 69, 82, 128, 70, 73, 83, 72, 69, 89, 
+    69, 128, 70, 79, 78, 71, 77, 65, 78, 128, 70, 79, 79, 84, 78, 79, 84, 
+    197, 70, 79, 85, 82, 84, 69, 69, 206, 70, 82, 79, 87, 78, 73, 78, 199, 
+    71, 65, 82, 77, 69, 78, 84, 128, 71, 73, 82, 85, 68, 65, 65, 128, 71, 82, 
+    65, 80, 72, 69, 77, 197, 72, 65, 70, 85, 75, 72, 65, 128, 72, 65, 76, 65, 
+    78, 84, 65, 128, 72, 65, 76, 66, 69, 82, 68, 128, 72, 65, 83, 65, 78, 84, 
+    65, 128, 72, 65, 89, 65, 78, 78, 65, 128, 72, 69, 65, 68, 73, 78, 71, 
+    128, 72, 69, 65, 86, 69, 78, 76, 217, 73, 45, 65, 82, 65, 69, 65, 128, 
+    73, 66, 73, 70, 73, 76, 73, 128, 73, 67, 72, 65, 68, 73, 78, 128, 73, 73, 
+    89, 65, 78, 78, 65, 128, 73, 78, 68, 73, 82, 69, 67, 212, 73, 78, 70, 73, 
+    78, 73, 84, 217, 73, 78, 84, 69, 82, 69, 83, 212, 73, 79, 68, 72, 65, 68, 
+    72, 128, 74, 65, 78, 85, 65, 82, 89, 128, 74, 65, 80, 65, 78, 69, 83, 
+    197, 74, 85, 80, 73, 84, 69, 82, 128, 75, 65, 75, 65, 66, 65, 84, 128, 
+    75, 65, 82, 65, 84, 84, 79, 128, 75, 65, 82, 79, 82, 73, 73, 128, 75, 73, 
+    78, 83, 72, 73, 80, 128, 75, 79, 78, 84, 69, 86, 77, 193, 75, 79, 79, 77, 
+    85, 85, 84, 128, 75, 85, 82, 79, 79, 78, 69, 128, 76, 65, 78, 71, 85, 65, 
+    71, 197, 76, 79, 67, 65, 84, 73, 79, 206, 77, 65, 73, 75, 85, 82, 79, 
+    128, 77, 65, 73, 77, 85, 65, 78, 128, 77, 65, 78, 83, 89, 79, 78, 128, 
+    77, 65, 82, 66, 85, 84, 65, 128, 77, 65, 82, 67, 65, 84, 79, 128, 77, 65, 
+    82, 82, 73, 65, 71, 197, 77, 65, 82, 82, 89, 73, 78, 199, 77, 65, 83, 83, 
+    73, 78, 71, 128, 77, 65, 89, 65, 78, 78, 65, 128, 77, 69, 71, 65, 84, 79, 
+    78, 128, 77, 69, 82, 67, 85, 82, 89, 128, 77, 69, 84, 82, 69, 84, 69, 
+    211, 77, 73, 75, 85, 82, 79, 78, 128, 77, 73, 76, 76, 73, 79, 78, 211, 
+    77, 79, 68, 69, 83, 84, 89, 128, 77, 79, 72, 65, 77, 77, 65, 196, 77, 79, 
+    82, 78, 73, 78, 71, 128, 77, 85, 76, 84, 73, 80, 76, 197, 78, 65, 84, 73, 
+    79, 78, 65, 204, 78, 69, 71, 65, 84, 73, 79, 206, 78, 69, 80, 84, 85, 78, 
+    69, 128, 78, 69, 87, 76, 73, 78, 69, 128, 78, 71, 69, 65, 68, 65, 76, 
+    128, 78, 73, 75, 65, 72, 73, 84, 128, 78, 73, 78, 69, 84, 69, 69, 206, 
+    79, 66, 79, 70, 73, 76, 73, 128, 79, 67, 84, 79, 66, 69, 82, 128, 79, 78, 
+    69, 45, 76, 73, 78, 197, 79, 78, 69, 83, 69, 76, 70, 128, 79, 79, 89, 65, 
+    78, 78, 65, 128, 79, 82, 84, 72, 79, 68, 79, 216, 79, 85, 84, 76, 73, 78, 
+    69, 128, 80, 65, 67, 75, 73, 78, 71, 128, 80, 65, 76, 76, 65, 87, 65, 
+    128, 80, 65, 84, 84, 69, 82, 78, 128, 80, 69, 76, 65, 83, 84, 79, 206, 
+    80, 69, 84, 65, 83, 77, 65, 128, 80, 69, 84, 65, 83, 84, 73, 128, 80, 72, 
+    73, 78, 84, 72, 85, 128, 80, 72, 85, 84, 72, 65, 79, 128, 80, 79, 68, 65, 
+    84, 85, 83, 128, 80, 82, 69, 67, 69, 68, 69, 128, 80, 82, 69, 67, 69, 68, 
+    69, 196, 80, 82, 69, 86, 73, 79, 85, 211, 80, 82, 73, 86, 65, 84, 69, 
+    128, 80, 82, 79, 80, 69, 82, 84, 217, 82, 65, 75, 72, 65, 78, 71, 128, 
+    82, 65, 80, 73, 83, 77, 65, 128, 82, 65, 89, 65, 78, 78, 65, 128, 82, 69, 
+    65, 72, 77, 85, 75, 128, 82, 69, 76, 69, 65, 83, 69, 128, 82, 69, 84, 82, 
+    69, 65, 84, 128, 82, 73, 84, 84, 79, 82, 85, 128, 82, 85, 85, 66, 85, 82, 
+    85, 128, 83, 65, 73, 75, 85, 82, 85, 128, 83, 65, 76, 84, 73, 82, 69, 
+    128, 83, 65, 77, 80, 72, 65, 79, 128, 83, 65, 78, 89, 79, 79, 71, 193, 
+    83, 67, 72, 79, 76, 65, 82, 128, 83, 67, 82, 85, 80, 76, 69, 128, 83, 69, 
+    71, 77, 69, 78, 84, 128, 83, 73, 77, 73, 76, 65, 82, 128, 83, 73, 78, 75, 
+    73, 78, 71, 128, 83, 73, 82, 73, 78, 71, 85, 128, 83, 73, 88, 45, 76, 73, 
+    78, 197, 83, 78, 79, 87, 77, 65, 78, 128, 83, 80, 73, 82, 65, 78, 84, 
+    128, 83, 80, 82, 73, 78, 71, 83, 128, 83, 81, 85, 65, 82, 69, 83, 128, 
+    83, 84, 65, 85, 82, 79, 83, 128, 83, 84, 65, 86, 82, 79, 83, 128, 83, 84, 
+    65, 86, 82, 79, 85, 128, 83, 84, 82, 65, 84, 73, 65, 206, 83, 84, 82, 73, 
+    67, 84, 76, 217, 83, 85, 66, 74, 69, 67, 84, 128, 83, 85, 67, 67, 69, 69, 
+    68, 128, 83, 89, 78, 69, 86, 77, 65, 128, 84, 65, 73, 83, 89, 79, 85, 
+    128, 84, 65, 84, 87, 69, 69, 76, 128, 84, 67, 72, 69, 72, 69, 72, 128, 
+    84, 69, 83, 83, 65, 82, 79, 206, 84, 69, 83, 83, 69, 82, 65, 128, 84, 72, 
+    73, 82, 84, 69, 69, 206, 84, 72, 85, 82, 73, 83, 65, 218, 84, 73, 78, 65, 
+    71, 77, 65, 128, 84, 73, 82, 79, 78, 73, 65, 206, 84, 79, 82, 67, 85, 76, 
+    85, 211, 84, 82, 73, 73, 83, 65, 80, 128, 84, 82, 89, 66, 76, 73, 79, 
+    206, 84, 86, 73, 77, 65, 68, 85, 210, 84, 87, 79, 45, 76, 73, 78, 197, 
+    85, 45, 69, 79, 45, 69, 85, 128, 85, 66, 85, 70, 73, 76, 73, 128, 85, 77, 
+    66, 82, 69, 76, 76, 193, 86, 65, 83, 84, 78, 69, 83, 211, 86, 65, 89, 65, 
+    78, 78, 65, 128, 86, 73, 69, 87, 68, 65, 84, 193, 86, 73, 76, 76, 65, 71, 
+    69, 128, 86, 79, 73, 67, 73, 78, 71, 128, 87, 65, 83, 65, 76, 76, 65, 
+    205, 87, 65, 83, 84, 73, 78, 71, 128, 89, 65, 89, 65, 78, 78, 65, 128, 
+    89, 79, 85, 84, 72, 70, 85, 204, 89, 80, 79, 82, 82, 79, 73, 128, 79, 83, 
+    77, 65, 78, 89, 193, 67, 73, 82, 67, 76, 69, 128, 66, 82, 65, 67, 75, 69, 
+    212, 85, 80, 83, 73, 76, 79, 206, 65, 67, 67, 69, 78, 84, 128, 68, 73, 
+    78, 71, 66, 65, 212, 69, 80, 83, 73, 76, 79, 206, 83, 76, 65, 78, 84, 69, 
+    196, 83, 81, 85, 65, 82, 69, 128, 72, 65, 78, 85, 78, 79, 207, 68, 65, 
+    71, 69, 83, 72, 128, 71, 76, 79, 84, 84, 65, 204, 84, 65, 71, 65, 76, 79, 
+    199, 79, 77, 73, 67, 82, 79, 206, 80, 65, 76, 65, 84, 65, 204, 78, 65, 
+    83, 75, 65, 80, 201, 67, 79, 82, 78, 69, 82, 128, 69, 76, 69, 77, 69, 78, 
+    212, 66, 85, 76, 76, 69, 84, 128, 68, 79, 84, 76, 69, 83, 211, 79, 71, 
+    79, 78, 69, 75, 128, 86, 73, 82, 65, 77, 65, 128, 75, 73, 82, 71, 72, 73, 
+    218, 82, 69, 86, 69, 82, 83, 197, 68, 73, 65, 77, 79, 78, 196, 84, 87, 
+    69, 78, 84, 89, 128, 68, 79, 85, 66, 76, 69, 128, 78, 69, 73, 84, 72, 69, 
+    210, 81, 85, 65, 82, 84, 69, 210, 83, 73, 77, 73, 76, 65, 210, 83, 73, 
+    78, 71, 76, 69, 128, 83, 79, 76, 73, 68, 85, 211, 83, 81, 85, 65, 82, 69, 
+    196, 67, 72, 73, 78, 69, 83, 197, 78, 85, 78, 65, 86, 73, 203, 83, 85, 
+    66, 83, 69, 84, 128, 84, 72, 45, 67, 82, 69, 197, 84, 82, 73, 71, 82, 65, 
+    205, 65, 82, 75, 84, 73, 75, 207, 69, 76, 69, 86, 69, 78, 128, 72, 85, 
+    78, 68, 82, 69, 196, 72, 89, 80, 72, 69, 78, 128, 73, 78, 83, 73, 68, 69, 
+    128, 77, 65, 82, 75, 69, 82, 128, 79, 80, 69, 78, 73, 78, 199, 84, 87, 
+    69, 76, 86, 69, 128, 69, 73, 71, 72, 84, 72, 211, 80, 65, 82, 84, 73, 65, 
+    204, 84, 72, 73, 82, 84, 89, 128, 86, 82, 65, 67, 72, 89, 128, 65, 82, 
+    82, 79, 87, 83, 128, 70, 65, 76, 76, 73, 78, 199, 79, 66, 76, 73, 81, 85, 
+    197, 80, 69, 82, 67, 69, 78, 212, 84, 72, 82, 79, 85, 71, 200, 67, 69, 
+    68, 73, 76, 76, 193, 67, 79, 78, 84, 82, 79, 204, 67, 85, 82, 86, 73, 78, 
+    199, 68, 73, 71, 82, 65, 80, 200, 69, 81, 85, 65, 76, 83, 128, 70, 73, 
+    76, 76, 69, 82, 128, 71, 65, 78, 71, 73, 65, 128, 73, 78, 86, 69, 82, 83, 
+    197, 73, 79, 84, 65, 84, 69, 196, 75, 69, 78, 84, 73, 77, 193, 77, 69, 
+    65, 83, 85, 82, 197, 82, 79, 85, 78, 68, 69, 196, 83, 65, 78, 89, 65, 75, 
+    193, 84, 67, 72, 69, 72, 69, 200, 84, 79, 80, 66, 65, 82, 128, 84, 85, 
+    82, 84, 76, 69, 128, 89, 73, 68, 68, 73, 83, 200, 45, 75, 72, 89, 73, 76, 
+    128, 66, 79, 84, 84, 79, 77, 128, 67, 69, 78, 84, 82, 69, 128, 67, 69, 
+    78, 84, 82, 69, 196, 67, 79, 78, 84, 65, 73, 206, 67, 79, 78, 84, 79, 85, 
+    210, 67, 82, 79, 83, 83, 69, 196, 68, 65, 78, 84, 65, 74, 193, 68, 73, 
+    86, 73, 68, 69, 196, 68, 79, 84, 84, 69, 68, 128, 68, 82, 65, 71, 79, 78, 
+    128, 70, 73, 70, 84, 72, 83, 128, 72, 69, 65, 86, 69, 78, 128, 75, 79, 
+    77, 66, 85, 86, 193, 75, 82, 65, 84, 73, 77, 193, 76, 69, 65, 68, 69, 82, 
+    128, 77, 65, 82, 66, 85, 84, 193, 77, 69, 77, 66, 69, 82, 128, 78, 65, 
+    84, 85, 82, 65, 204, 78, 73, 78, 69, 84, 89, 128, 80, 69, 78, 67, 73, 76, 
+    128, 81, 65, 77, 65, 84, 83, 128, 83, 75, 76, 73, 82, 79, 206, 83, 79, 
+    71, 68, 73, 65, 206, 83, 84, 73, 71, 77, 65, 128, 83, 89, 78, 65, 71, 77, 
+    193, 84, 65, 65, 76, 85, 74, 193, 84, 72, 69, 83, 69, 79, 211, 84, 79, 
+    78, 71, 85, 69, 128, 65, 67, 65, 68, 69, 77, 217, 65, 67, 67, 79, 85, 78, 
+    212, 65, 78, 67, 72, 79, 82, 128, 65, 78, 67, 79, 82, 65, 128, 65, 80, 
+    76, 79, 85, 78, 128, 65, 82, 67, 72, 65, 73, 195, 66, 65, 76, 85, 68, 65, 
+    128, 66, 65, 77, 66, 79, 79, 128, 66, 65, 83, 72, 75, 73, 210, 66, 73, 
+    78, 68, 73, 78, 199, 66, 73, 83, 72, 79, 80, 128, 66, 79, 87, 84, 73, 69, 
+    128, 67, 72, 73, 69, 85, 67, 200, 67, 72, 82, 73, 86, 73, 128, 67, 76, 
+    85, 83, 84, 69, 210, 68, 65, 71, 71, 69, 82, 128, 68, 65, 80, 45, 66, 69, 
+    201, 68, 65, 80, 45, 80, 73, 201, 68, 69, 67, 73, 77, 65, 204, 68, 73, 
+    86, 73, 68, 69, 128, 68, 74, 69, 82, 86, 73, 128, 68, 79, 85, 66, 76, 69, 
+    196, 68, 82, 65, 67, 72, 77, 193, 69, 65, 82, 84, 72, 76, 217, 69, 73, 
+    71, 72, 84, 89, 128, 69, 83, 67, 65, 80, 69, 128, 70, 69, 65, 84, 72, 69, 
+    210, 70, 76, 69, 88, 85, 83, 128, 71, 69, 82, 69, 83, 72, 128, 71, 72, 
+    85, 78, 78, 65, 128, 71, 82, 69, 65, 84, 69, 210, 72, 79, 76, 68, 73, 78, 
+    199, 73, 78, 72, 73, 66, 73, 212, 73, 83, 83, 72, 65, 82, 128, 73, 90, 
+    72, 73, 84, 83, 193, 75, 69, 69, 80, 73, 78, 199, 75, 72, 73, 69, 85, 75, 
+    200, 75, 76, 65, 83, 77, 65, 128, 75, 78, 73, 71, 72, 84, 128, 75, 79, 
+    82, 65, 78, 73, 195, 76, 69, 71, 69, 84, 79, 211, 77, 65, 76, 65, 75, 79, 
+    206, 77, 65, 82, 75, 45, 49, 128, 77, 65, 82, 75, 45, 50, 128, 77, 79, 
+    82, 84, 65, 82, 128, 78, 69, 71, 65, 84, 69, 196, 78, 79, 84, 67, 72, 69, 
+    196, 79, 82, 68, 73, 78, 65, 204, 80, 72, 73, 69, 85, 80, 200, 80, 72, 
+    82, 65, 83, 69, 128, 80, 73, 76, 67, 82, 79, 215, 80, 76, 65, 71, 73, 79, 
+    211, 80, 79, 75, 79, 74, 73, 128, 82, 69, 84, 85, 82, 78, 128, 82, 73, 
+    75, 82, 73, 75, 128, 83, 69, 82, 73, 70, 83, 128, 83, 72, 65, 80, 69, 83, 
+    128, 83, 73, 88, 84, 69, 69, 206, 83, 76, 79, 80, 73, 78, 199, 83, 77, 
+    65, 76, 76, 69, 210, 83, 77, 73, 76, 73, 78, 199, 83, 80, 69, 69, 67, 72, 
+    128, 83, 80, 73, 68, 69, 82, 217, 84, 65, 77, 73, 78, 71, 128, 84, 69, 
+    76, 69, 73, 65, 128, 84, 69, 76, 73, 83, 72, 193, 84, 69, 83, 83, 69, 82, 
+    193, 84, 72, 69, 84, 72, 69, 128, 84, 72, 73, 69, 85, 84, 200, 84, 72, 
+    82, 69, 65, 68, 128, 84, 72, 82, 69, 69, 45, 196, 84, 86, 82, 73, 68, 79, 
+    128, 85, 80, 84, 85, 82, 78, 128, 89, 69, 76, 76, 79, 87, 128, 89, 79, 
+    45, 89, 65, 69, 128, 89, 85, 45, 89, 69, 79, 128, 90, 69, 77, 76, 74, 65, 
+    128, 65, 66, 89, 83, 77, 65, 204, 65, 70, 71, 72, 65, 78, 201, 65, 70, 
+    82, 73, 67, 65, 206, 65, 72, 65, 71, 71, 65, 210, 65, 73, 72, 86, 85, 83, 
+    128, 65, 73, 86, 73, 76, 73, 203, 65, 76, 65, 89, 72, 69, 128, 65, 76, 
+    73, 71, 78, 69, 196, 65, 78, 78, 85, 73, 84, 217, 65, 80, 65, 65, 84, 79, 
+    128, 65, 82, 65, 69, 65, 69, 128, 65, 82, 77, 79, 85, 82, 128, 65, 82, 
+    82, 73, 86, 69, 128, 65, 82, 83, 69, 79, 83, 128, 65, 82, 85, 72, 85, 65, 
+    128, 65, 83, 67, 69, 78, 84, 128, 65, 85, 71, 85, 83, 84, 128, 65, 85, 
+    83, 84, 82, 65, 204, 65, 86, 69, 82, 65, 71, 197, 66, 65, 68, 71, 69, 82, 
+    128, 66, 65, 73, 77, 65, 73, 128, 66, 65, 78, 84, 79, 67, 128, 66, 65, 
+    82, 76, 69, 89, 128, 66, 65, 82, 82, 69, 69, 128, 66, 69, 78, 90, 69, 78, 
+    197, 66, 69, 84, 87, 69, 69, 206, 66, 69, 89, 89, 65, 76, 128, 66, 73, 
+    84, 84, 69, 82, 128, 66, 79, 82, 85, 84, 79, 128, 66, 82, 65, 78, 67, 72, 
+    128, 66, 82, 69, 86, 73, 83, 128, 66, 82, 79, 78, 90, 69, 128, 66, 85, 
+    67, 75, 76, 69, 128, 67, 65, 78, 67, 69, 76, 128, 67, 65, 78, 67, 69, 82, 
+    128, 67, 65, 84, 65, 87, 65, 128, 67, 65, 85, 84, 73, 79, 206, 67, 72, 
+    65, 77, 75, 79, 128, 67, 72, 65, 78, 71, 69, 128, 67, 72, 65, 82, 73, 79, 
+    212, 67, 72, 69, 86, 82, 79, 206, 67, 72, 73, 82, 69, 84, 128, 67, 72, 
+    85, 82, 67, 72, 128, 67, 76, 69, 70, 45, 49, 128, 67, 76, 69, 70, 45, 50, 
+    128, 67, 76, 73, 86, 73, 83, 128, 67, 76, 79, 83, 69, 68, 128, 67, 79, 
+    70, 70, 73, 78, 128, 67, 79, 78, 73, 67, 65, 204, 67, 79, 82, 80, 83, 69, 
+    128, 67, 85, 82, 82, 69, 78, 212, 68, 65, 65, 68, 72, 85, 128, 68, 65, 
+    76, 65, 84, 72, 128, 68, 65, 77, 65, 82, 85, 128, 68, 65, 83, 69, 73, 65, 
+    128, 68, 68, 65, 72, 65, 76, 128, 68, 69, 76, 69, 84, 69, 128, 68, 69, 
+    76, 80, 72, 73, 195, 68, 72, 65, 65, 76, 85, 128, 68, 72, 65, 82, 77, 65, 
+    128, 68, 73, 69, 83, 73, 83, 128, 68, 73, 80, 80, 69, 82, 128, 68, 73, 
+    86, 79, 82, 67, 197, 68, 79, 84, 83, 45, 49, 128, 68, 79, 84, 83, 45, 50, 
+    128, 68, 79, 84, 83, 45, 51, 128, 68, 79, 84, 83, 45, 52, 128, 68, 79, 
+    84, 83, 45, 53, 128, 68, 79, 84, 83, 45, 54, 128, 68, 79, 84, 83, 45, 55, 
+    128, 68, 79, 84, 83, 45, 56, 128, 68, 85, 84, 73, 69, 83, 128, 69, 73, 
+    71, 72, 84, 72, 128, 69, 78, 65, 82, 88, 73, 211, 69, 88, 67, 69, 83, 83, 
+    128, 69, 88, 73, 83, 84, 83, 128, 70, 65, 67, 69, 45, 49, 128, 70, 65, 
+    67, 69, 45, 50, 128, 70, 65, 67, 69, 45, 51, 128, 70, 65, 67, 69, 45, 52, 
+    128, 70, 65, 67, 69, 45, 53, 128, 70, 65, 67, 69, 45, 54, 128, 70, 65, 
+    77, 73, 76, 89, 128, 70, 65, 84, 72, 69, 82, 128, 70, 69, 77, 65, 76, 69, 
+    128, 70, 69, 82, 77, 65, 84, 193, 70, 73, 70, 84, 69, 69, 206, 70, 76, 
+    65, 71, 45, 49, 128, 70, 76, 65, 71, 45, 50, 128, 70, 76, 65, 71, 45, 51, 
+    128, 70, 76, 65, 71, 45, 52, 128, 70, 76, 65, 71, 45, 53, 128, 70, 76, 
+    73, 71, 72, 84, 128, 70, 76, 79, 87, 69, 82, 128, 70, 79, 82, 67, 69, 83, 
+    128, 70, 85, 78, 69, 82, 65, 204, 71, 69, 68, 79, 76, 65, 128, 71, 69, 
+    77, 73, 78, 73, 128, 71, 69, 78, 69, 82, 73, 195, 71, 72, 65, 73, 78, 85, 
+    128, 71, 72, 65, 77, 65, 76, 128, 71, 82, 79, 85, 78, 68, 128, 71, 85, 
+    65, 82, 65, 78, 201, 72, 65, 70, 85, 75, 72, 128, 72, 69, 73, 83, 69, 73, 
+    128, 72, 69, 76, 77, 69, 84, 128, 72, 69, 82, 65, 69, 85, 205, 72, 69, 
+    82, 77, 69, 83, 128, 72, 69, 82, 85, 84, 85, 128, 72, 82, 89, 86, 78, 73, 
+    193, 72, 85, 73, 73, 84, 79, 128, 73, 45, 66, 69, 65, 77, 128, 73, 77, 
+    73, 83, 69, 79, 211, 73, 78, 71, 87, 65, 90, 128, 73, 78, 73, 78, 71, 85, 
+    128, 73, 78, 83, 69, 67, 84, 128, 73, 78, 83, 85, 76, 65, 210, 74, 79, 
+    73, 78, 69, 68, 128, 75, 65, 78, 65, 75, 79, 128, 75, 65, 78, 84, 65, 74, 
+    193, 75, 69, 70, 85, 76, 65, 128, 75, 69, 89, 67, 65, 80, 128, 75, 72, 
+    79, 77, 85, 84, 128, 75, 76, 73, 84, 79, 78, 128, 75, 79, 82, 85, 78, 65, 
+    128, 75, 89, 65, 84, 72, 79, 211, 75, 89, 85, 82, 73, 73, 128, 76, 65, 
+    77, 65, 68, 72, 128, 76, 65, 84, 69, 82, 65, 204, 76, 69, 71, 73, 79, 78, 
+    128, 76, 69, 73, 77, 77, 65, 128, 76, 69, 84, 84, 69, 82, 128, 76, 73, 
+    77, 73, 84, 69, 196, 76, 73, 78, 69, 45, 49, 128, 76, 73, 78, 69, 45, 51, 
+    128, 76, 73, 78, 69, 45, 55, 128, 76, 73, 78, 69, 45, 57, 128, 76, 73, 
+    78, 75, 73, 78, 199, 76, 79, 90, 69, 78, 71, 197, 77, 65, 73, 68, 69, 78, 
+    128, 77, 65, 76, 84, 69, 83, 197, 77, 65, 82, 75, 45, 51, 128, 77, 65, 
+    82, 75, 45, 52, 128, 77, 65, 82, 85, 75, 85, 128, 77, 65, 84, 82, 73, 88, 
+    128, 77, 65, 88, 73, 77, 65, 128, 77, 69, 68, 73, 85, 77, 128, 77, 69, 
+    71, 65, 76, 73, 128, 77, 69, 82, 75, 72, 65, 128, 77, 69, 84, 82, 73, 65, 
+    128, 77, 73, 68, 76, 73, 78, 197, 77, 73, 76, 76, 69, 84, 128, 77, 73, 
+    78, 73, 77, 65, 128, 77, 79, 68, 69, 76, 83, 128, 77, 79, 84, 72, 69, 82, 
+    128, 77, 85, 81, 68, 65, 77, 128, 78, 65, 85, 84, 72, 83, 128, 78, 69, 
+    78, 65, 78, 79, 128, 78, 73, 82, 85, 71, 85, 128, 78, 79, 75, 72, 85, 75, 
+    128, 78, 79, 77, 73, 78, 65, 204, 78, 85, 77, 66, 69, 82, 128, 78, 85, 
+    78, 65, 86, 85, 212, 79, 66, 69, 76, 79, 83, 128, 79, 77, 65, 76, 79, 78, 
+    128, 79, 80, 69, 78, 45, 80, 128, 79, 80, 80, 79, 83, 69, 128, 79, 82, 
+    73, 71, 73, 78, 128, 79, 84, 72, 65, 76, 65, 206, 80, 65, 76, 85, 84, 65, 
+    128, 80, 65, 83, 72, 84, 65, 128, 80, 69, 78, 73, 72, 73, 128, 80, 69, 
+    82, 83, 79, 78, 128, 80, 73, 75, 85, 82, 85, 128, 80, 73, 80, 73, 78, 71, 
+    128, 80, 73, 83, 67, 69, 83, 128, 80, 79, 73, 78, 84, 79, 128, 80, 82, 
+    69, 67, 69, 68, 197, 80, 82, 69, 70, 65, 67, 197, 80, 82, 79, 68, 85, 67, 
+    212, 80, 85, 82, 73, 84, 89, 128, 80, 85, 83, 72, 73, 78, 199, 81, 69, 
+    84, 65, 78, 65, 128, 81, 85, 66, 85, 84, 83, 128, 82, 69, 80, 69, 65, 84, 
+    128, 82, 73, 84, 85, 65, 76, 128, 82, 85, 78, 79, 85, 84, 128, 83, 65, 
+    65, 68, 72, 85, 128, 83, 65, 74, 68, 65, 72, 128, 83, 65, 77, 69, 75, 72, 
+    128, 83, 65, 78, 78, 89, 65, 128, 83, 65, 84, 85, 82, 78, 128, 83, 67, 
+    65, 76, 69, 83, 128, 83, 67, 82, 69, 69, 78, 128, 83, 67, 82, 73, 80, 84, 
+    128, 83, 69, 65, 71, 85, 76, 204, 83, 69, 67, 79, 78, 68, 128, 83, 69, 
+    67, 82, 69, 84, 128, 83, 69, 67, 84, 79, 82, 128, 83, 69, 73, 83, 77, 65, 
+    128, 83, 69, 82, 86, 73, 67, 197, 83, 69, 86, 69, 78, 84, 217, 83, 72, 
+    65, 68, 68, 65, 128, 83, 72, 65, 75, 84, 73, 128, 83, 72, 69, 69, 78, 85, 
+    128, 83, 72, 79, 82, 84, 83, 128, 83, 72, 85, 70, 70, 76, 197, 83, 73, 
+    67, 75, 76, 69, 128, 83, 73, 88, 84, 72, 83, 128, 83, 76, 79, 87, 76, 89, 
+    128, 83, 80, 65, 84, 72, 73, 128, 83, 80, 73, 82, 73, 84, 128, 83, 80, 
+    82, 79, 85, 84, 128, 83, 84, 65, 86, 82, 79, 211, 83, 84, 82, 65, 73, 70, 
+    128, 83, 84, 82, 73, 68, 69, 128, 83, 84, 82, 79, 75, 69, 211, 83, 85, 
+    66, 73, 84, 79, 128, 83, 85, 67, 67, 69, 69, 196, 83, 85, 82, 70, 65, 67, 
+    197, 83, 87, 79, 82, 68, 83, 128, 83, 89, 78, 65, 70, 73, 128, 83, 89, 
+    79, 85, 87, 65, 128, 84, 65, 84, 87, 69, 69, 204, 84, 65, 85, 82, 85, 83, 
+    128, 84, 69, 78, 85, 84, 79, 128, 84, 72, 65, 65, 76, 85, 128, 84, 72, 
+    65, 72, 65, 78, 128, 84, 72, 65, 78, 78, 65, 128, 84, 72, 73, 82, 68, 83, 
+    128, 84, 72, 73, 85, 84, 72, 128, 84, 73, 80, 69, 72, 65, 128, 84, 79, 
+    78, 69, 45, 50, 128, 84, 79, 78, 69, 45, 51, 128, 84, 79, 78, 69, 45, 52, 
+    128, 84, 79, 78, 69, 45, 53, 128, 84, 79, 78, 69, 45, 54, 128, 84, 82, 
+    73, 80, 76, 73, 128, 84, 82, 73, 80, 79, 68, 128, 84, 83, 72, 85, 71, 83, 
+    128, 84, 84, 69, 72, 69, 72, 128, 84, 85, 82, 66, 65, 78, 128, 85, 80, 
+    82, 73, 71, 72, 212, 85, 80, 87, 65, 82, 68, 128, 85, 82, 65, 78, 85, 83, 
+    128, 86, 65, 76, 76, 69, 89, 128, 86, 65, 82, 69, 73, 65, 201, 86, 65, 
+    82, 73, 65, 78, 212, 86, 65, 82, 73, 75, 65, 128, 86, 73, 67, 84, 79, 82, 
+    217, 86, 73, 82, 73, 65, 77, 128, 86, 73, 83, 65, 82, 71, 193, 86, 79, 
+    76, 84, 65, 71, 197, 87, 65, 82, 78, 73, 78, 199, 87, 69, 65, 80, 79, 78, 
+    128, 87, 72, 69, 69, 76, 69, 196, 87, 82, 73, 84, 73, 78, 199, 89, 70, 
+    69, 83, 73, 83, 128, 89, 79, 45, 89, 69, 79, 128, 89, 80, 83, 73, 76, 73, 
+    128, 83, 89, 76, 79, 84, 201, 67, 65, 82, 79, 78, 128, 66, 82, 69, 86, 
+    69, 128, 66, 76, 65, 67, 75, 128, 77, 73, 68, 68, 76, 197, 65, 67, 67, 
+    69, 78, 212, 84, 82, 73, 80, 76, 197, 68, 79, 84, 84, 69, 196, 83, 84, 
+    82, 79, 75, 197, 86, 69, 83, 83, 69, 204, 69, 81, 85, 65, 76, 211, 71, 
+    79, 84, 72, 73, 195, 72, 69, 65, 86, 89, 128, 83, 73, 78, 71, 76, 197, 
+    66, 76, 79, 67, 75, 128, 77, 65, 78, 67, 72, 213, 84, 79, 78, 79, 83, 
+    128, 66, 79, 84, 84, 79, 205, 70, 84, 72, 79, 82, 193, 77, 69, 68, 73, 
+    85, 205, 79, 77, 69, 71, 65, 128, 83, 73, 71, 77, 65, 128, 65, 76, 80, 
+    72, 65, 128, 67, 76, 79, 83, 69, 196, 68, 65, 83, 73, 65, 128, 83, 85, 
+    66, 83, 69, 212, 67, 79, 77, 77, 65, 128, 68, 69, 76, 84, 65, 128, 86, 
+    85, 76, 71, 65, 210, 67, 79, 82, 78, 69, 210, 69, 81, 85, 65, 76, 128, 
+    76, 65, 77, 68, 65, 128, 67, 82, 79, 83, 83, 128, 73, 67, 72, 79, 83, 
+    128, 83, 65, 89, 73, 83, 201, 84, 72, 69, 84, 65, 128, 87, 72, 73, 84, 
+    69, 128, 65, 76, 77, 79, 83, 212, 75, 65, 80, 80, 65, 128, 77, 65, 67, 
+    82, 79, 206, 78, 85, 66, 73, 65, 206, 89, 45, 67, 82, 69, 197, 66, 69, 
+    83, 73, 68, 197, 67, 69, 78, 84, 82, 197, 83, 72, 65, 68, 68, 193, 84, 
+    87, 69, 78, 84, 217, 69, 65, 82, 84, 72, 128, 70, 73, 70, 84, 89, 128, 
+    76, 69, 78, 71, 84, 200, 78, 79, 82, 77, 65, 204, 84, 72, 73, 82, 84, 
+    217, 68, 65, 83, 72, 69, 196, 68, 73, 71, 82, 65, 205, 80, 82, 73, 77, 
+    69, 128, 85, 78, 73, 79, 78, 128, 67, 65, 78, 68, 82, 193, 82, 69, 80, 
+    69, 65, 212, 84, 69, 77, 80, 85, 211, 84, 85, 65, 82, 69, 199, 76, 85, 
+    78, 65, 84, 197, 82, 73, 83, 73, 78, 199, 82, 84, 65, 71, 83, 128, 68, 
+    73, 69, 83, 73, 211, 68, 73, 80, 76, 73, 128, 73, 78, 68, 69, 88, 128, 
+    75, 79, 80, 80, 65, 128, 78, 65, 66, 76, 65, 128, 78, 85, 75, 84, 65, 
+    128, 79, 84, 84, 65, 86, 193, 82, 65, 73, 83, 69, 196, 83, 67, 72, 87, 
+    65, 128, 83, 72, 73, 77, 65, 128, 83, 84, 65, 70, 70, 128, 89, 70, 69, 
+    83, 73, 211, 66, 65, 76, 76, 79, 212, 66, 65, 82, 82, 69, 197, 67, 76, 
+    73, 67, 75, 128, 67, 85, 66, 69, 68, 128, 67, 85, 82, 86, 69, 196, 70, 
+    69, 77, 65, 76, 197, 70, 69, 78, 67, 69, 128, 75, 79, 82, 69, 65, 206, 
+    76, 69, 73, 77, 77, 193, 76, 73, 84, 84, 76, 197, 78, 69, 83, 84, 69, 
+    196, 85, 73, 71, 72, 85, 210, 87, 65, 84, 69, 82, 128, 87, 69, 73, 71, 
+    72, 212, 65, 76, 65, 89, 72, 197, 66, 65, 83, 83, 65, 128, 66, 82, 73, 
+    68, 71, 197, 67, 72, 82, 79, 77, 193, 68, 65, 78, 68, 65, 128, 68, 69, 
+    71, 82, 69, 197, 68, 69, 86, 73, 67, 197, 68, 79, 76, 76, 65, 210, 80, 
+    65, 73, 82, 69, 196, 80, 65, 84, 65, 72, 128, 80, 73, 69, 67, 69, 128, 
+    80, 79, 69, 84, 82, 217, 83, 65, 77, 80, 73, 128, 83, 75, 69, 87, 69, 
+    196, 84, 73, 77, 69, 83, 128, 84, 84, 69, 72, 69, 200, 87, 73, 71, 71, 
+    76, 217, 90, 73, 71, 90, 65, 199, 65, 82, 79, 85, 78, 196, 65, 82, 83, 
+    69, 79, 211, 66, 82, 79, 75, 69, 206, 67, 65, 82, 69, 84, 128, 67, 76, 
+    73, 70, 70, 128, 67, 76, 79, 84, 72, 128, 68, 65, 71, 69, 83, 200, 68, 
+    65, 77, 77, 65, 128, 70, 76, 79, 82, 65, 204, 70, 79, 82, 84, 89, 128, 
+    72, 69, 65, 82, 84, 128, 76, 65, 77, 69, 68, 128, 77, 65, 80, 73, 81, 
+    128, 78, 45, 67, 82, 69, 197, 80, 79, 83, 84, 65, 204, 80, 84, 72, 65, 
+    72, 193, 83, 67, 72, 69, 77, 193, 83, 69, 71, 79, 76, 128, 83, 72, 65, 
+    68, 69, 128, 83, 77, 65, 76, 76, 128, 83, 84, 82, 69, 83, 211, 84, 72, 
+    79, 82, 78, 128, 84, 73, 84, 76, 79, 128, 84, 79, 79, 84, 72, 128, 86, 
+    65, 82, 69, 73, 193, 87, 72, 69, 65, 84, 128, 90, 81, 65, 80, 72, 193, 
+    65, 76, 65, 80, 72, 128, 66, 69, 65, 77, 69, 196, 66, 69, 82, 66, 69, 
+    210, 66, 73, 78, 65, 82, 217, 66, 73, 78, 68, 73, 128, 66, 79, 87, 84, 
+    73, 197, 67, 72, 69, 67, 75, 128, 67, 85, 82, 86, 69, 128, 68, 65, 76, 
+    68, 65, 128, 68, 65, 76, 69, 84, 128, 68, 68, 65, 72, 65, 204, 68, 69, 
+    65, 84, 72, 128, 68, 79, 66, 82, 79, 128, 68, 90, 69, 76, 79, 128, 69, 
+    84, 69, 82, 79, 206, 70, 65, 67, 84, 79, 210, 70, 73, 71, 85, 82, 197, 
+    70, 76, 79, 79, 82, 128, 70, 79, 82, 75, 69, 196, 70, 82, 73, 84, 85, 
+    128, 71, 65, 80, 80, 69, 196, 71, 69, 78, 73, 75, 201, 71, 72, 65, 73, 
+    78, 128, 71, 72, 79, 83, 84, 128, 71, 72, 85, 78, 78, 193, 71, 78, 89, 
+    73, 83, 128, 71, 79, 82, 71, 73, 128, 72, 65, 77, 77, 69, 210, 72, 65, 
+    77, 90, 65, 128, 72, 73, 82, 73, 81, 128, 72, 79, 76, 65, 77, 128, 72, 
+    79, 82, 83, 69, 128, 72, 87, 65, 73, 82, 128, 73, 65, 85, 68, 65, 128, 
+    75, 65, 90, 65, 75, 200, 75, 73, 89, 69, 79, 203, 75, 76, 65, 83, 77, 
+    193, 76, 65, 66, 79, 82, 128, 76, 65, 82, 71, 69, 210, 76, 65, 85, 76, 
+    65, 128, 76, 69, 83, 83, 69, 210, 77, 69, 84, 65, 76, 128, 77, 79, 85, 
+    84, 72, 128, 78, 65, 83, 72, 73, 128, 78, 79, 84, 69, 83, 128, 79, 71, 
+    79, 78, 69, 203, 79, 76, 73, 71, 79, 206, 79, 82, 78, 65, 84, 197, 80, 
+    73, 65, 83, 77, 193, 80, 76, 65, 78, 67, 203, 80, 79, 73, 78, 84, 128, 
+    80, 79, 87, 69, 82, 128, 80, 82, 79, 84, 79, 211, 81, 65, 84, 65, 78, 
+    128, 81, 85, 69, 69, 78, 128, 81, 85, 73, 76, 76, 128, 82, 69, 65, 67, 
+    72, 128, 82, 71, 89, 65, 78, 128, 82, 73, 84, 83, 73, 128, 83, 67, 82, 
+    69, 69, 206, 83, 69, 71, 78, 79, 128, 83, 69, 82, 73, 70, 211, 83, 69, 
+    83, 65, 77, 197, 83, 72, 65, 78, 71, 128, 83, 72, 65, 82, 80, 128, 83, 
+    72, 67, 72, 65, 128, 83, 72, 69, 69, 80, 128, 83, 72, 69, 76, 70, 128, 
+    83, 72, 69, 76, 76, 128, 83, 72, 79, 82, 84, 211, 83, 72, 87, 65, 65, 
+    128, 83, 72, 87, 73, 73, 128, 83, 72, 87, 79, 79, 128, 83, 73, 71, 78, 
+    83, 128, 83, 73, 78, 68, 72, 201, 83, 73, 88, 84, 89, 128, 83, 76, 79, 
+    86, 79, 128, 83, 80, 69, 65, 82, 128, 83, 80, 73, 82, 73, 212, 83, 84, 
+    79, 67, 75, 128, 83, 84, 85, 68, 89, 128, 83, 85, 75, 85, 78, 128, 84, 
+    65, 78, 78, 69, 196, 84, 69, 76, 79, 85, 211, 84, 72, 87, 65, 65, 128, 
+    84, 73, 71, 69, 82, 128, 84, 73, 75, 69, 85, 212, 84, 82, 85, 78, 75, 
+    128, 84, 83, 65, 68, 73, 128, 84, 83, 72, 69, 71, 128, 84, 83, 72, 69, 
+    83, 128, 84, 87, 69, 76, 86, 197, 87, 65, 84, 67, 72, 128, 87, 79, 77, 
+    65, 78, 128, 89, 69, 83, 84, 85, 128, 89, 79, 45, 89, 65, 128, 89, 85, 
+    45, 89, 69, 128, 90, 90, 73, 69, 84, 128, 45, 67, 72, 65, 76, 128, 45, 
+    75, 72, 89, 85, 196, 45, 80, 72, 82, 85, 128, 65, 68, 68, 65, 75, 128, 
+    65, 71, 65, 73, 78, 128, 65, 72, 83, 68, 65, 128, 65, 76, 73, 70, 85, 
+    128, 65, 77, 79, 85, 78, 212, 65, 78, 80, 69, 65, 128, 65, 80, 65, 82, 
+    84, 128, 65, 80, 82, 73, 76, 128, 65, 82, 69, 80, 65, 128, 65, 82, 73, 
+    69, 83, 128, 65, 82, 76, 65, 85, 199, 65, 82, 79, 85, 82, 193, 65, 82, 
+    82, 65, 89, 128, 65, 82, 84, 65, 66, 197, 66, 66, 73, 69, 80, 128, 66, 
+    66, 73, 69, 84, 128, 66, 66, 73, 69, 88, 128, 66, 66, 85, 79, 80, 128, 
+    66, 66, 85, 79, 88, 128, 66, 66, 85, 82, 88, 128, 66, 69, 69, 84, 65, 
+    128, 66, 69, 70, 79, 82, 197, 66, 69, 72, 69, 72, 128, 66, 69, 73, 84, 
+    72, 128, 66, 72, 69, 84, 72, 128, 66, 73, 82, 71, 65, 128, 66, 73, 84, 
+    73, 78, 199, 66, 76, 65, 78, 75, 128, 66, 76, 79, 79, 68, 128, 66, 82, 
+    65, 67, 69, 128, 66, 82, 65, 78, 67, 200, 66, 82, 69, 65, 84, 200, 66, 
+    82, 85, 83, 72, 128, 66, 83, 84, 65, 82, 128, 66, 85, 76, 76, 69, 212, 
+    67, 65, 77, 78, 85, 195, 67, 65, 78, 67, 69, 204, 67, 65, 85, 68, 65, 
+    128, 67, 67, 72, 65, 65, 128, 67, 67, 72, 69, 69, 128, 67, 69, 65, 76, 
+    67, 128, 67, 69, 73, 82, 84, 128, 67, 72, 65, 68, 65, 128, 67, 72, 65, 
+    73, 82, 128, 67, 72, 65, 78, 71, 128, 67, 72, 73, 76, 68, 128, 67, 72, 
+    73, 78, 71, 128, 67, 72, 79, 75, 69, 128, 67, 72, 85, 76, 65, 128, 67, 
+    72, 85, 79, 80, 128, 67, 72, 85, 79, 84, 128, 67, 72, 85, 79, 88, 128, 
+    67, 72, 85, 82, 88, 128, 67, 72, 89, 82, 88, 128, 67, 76, 79, 85, 68, 
+    128, 67, 79, 69, 78, 71, 128, 67, 79, 76, 79, 82, 128, 67, 79, 77, 69, 
+    84, 128, 67, 79, 77, 73, 78, 199, 67, 79, 77, 77, 79, 206, 67, 79, 86, 
+    69, 82, 128, 67, 82, 69, 68, 73, 212, 67, 82, 79, 73, 88, 128, 68, 65, 
+    65, 83, 85, 128, 68, 65, 76, 65, 84, 200, 68, 65, 82, 71, 65, 128, 68, 
+    65, 86, 73, 68, 128, 68, 68, 68, 72, 65, 128, 68, 68, 73, 69, 80, 128, 
+    68, 68, 73, 69, 88, 128, 68, 68, 85, 79, 80, 128, 68, 68, 85, 79, 88, 
+    128, 68, 68, 85, 82, 88, 128, 68, 69, 76, 69, 84, 197, 68, 69, 82, 69, 
+    84, 128, 68, 73, 70, 65, 84, 128, 68, 73, 80, 84, 69, 128, 68, 73, 86, 
+    73, 68, 197, 68, 79, 77, 65, 73, 206, 68, 79, 85, 66, 84, 128, 68, 82, 
+    73, 86, 69, 128, 68, 82, 79, 80, 83, 128, 69, 69, 75, 65, 65, 128, 69, 
+    73, 71, 72, 84, 217, 69, 76, 69, 86, 69, 206, 69, 76, 73, 70, 73, 128, 
+    69, 78, 84, 69, 82, 128, 69, 79, 76, 72, 88, 128, 69, 81, 85, 73, 68, 
+    128, 69, 85, 45, 69, 85, 128, 69, 88, 73, 83, 84, 128, 70, 65, 65, 70, 
+    85, 128, 70, 65, 73, 72, 85, 128, 70, 65, 84, 72, 65, 128, 70, 69, 65, 
+    82, 78, 128, 70, 72, 84, 79, 82, 193, 70, 73, 69, 76, 68, 128, 70, 73, 
+    70, 84, 72, 128, 70, 73, 71, 72, 84, 128, 70, 73, 76, 76, 69, 196, 70, 
+    73, 78, 73, 84, 197, 70, 76, 79, 87, 69, 210, 70, 76, 85, 84, 69, 128, 
+    70, 79, 76, 76, 89, 128, 70, 79, 82, 67, 69, 128, 70, 79, 82, 84, 69, 
+    128, 70, 82, 65, 77, 69, 128, 70, 82, 69, 78, 67, 200, 70, 82, 79, 87, 
+    78, 128, 71, 65, 65, 70, 85, 128, 71, 65, 68, 79, 76, 128, 71, 65, 77, 
+    65, 76, 128, 71, 65, 77, 76, 65, 128, 71, 65, 78, 77, 65, 128, 71, 65, 
+    82, 79, 78, 128, 71, 69, 78, 84, 76, 197, 71, 69, 82, 69, 83, 200, 71, 
+    69, 82, 77, 65, 206, 71, 71, 73, 69, 80, 128, 71, 71, 73, 69, 88, 128, 
+    71, 71, 85, 79, 80, 128, 71, 71, 85, 79, 84, 128, 71, 71, 85, 79, 88, 
+    128, 71, 71, 85, 82, 88, 128, 71, 71, 87, 65, 65, 128, 71, 71, 87, 69, 
+    69, 128, 71, 73, 77, 69, 76, 128, 71, 73, 78, 73, 73, 128, 71, 76, 69, 
+    73, 67, 200, 71, 82, 65, 67, 69, 128, 71, 82, 65, 73, 78, 128, 71, 82, 
+    65, 83, 83, 128, 72, 45, 84, 89, 80, 197, 72, 65, 45, 72, 65, 128, 72, 
+    65, 71, 76, 65, 218, 72, 65, 73, 84, 85, 128, 72, 65, 78, 68, 83, 128, 
+    72, 69, 65, 86, 69, 206, 72, 73, 68, 73, 78, 199, 72, 76, 73, 69, 80, 
+    128, 72, 76, 73, 69, 88, 128, 72, 76, 85, 79, 80, 128, 72, 76, 85, 79, 
+    88, 128, 72, 76, 85, 82, 88, 128, 72, 76, 89, 82, 88, 128, 72, 77, 73, 
+    69, 80, 128, 72, 77, 73, 69, 88, 128, 72, 77, 85, 79, 80, 128, 72, 77, 
+    85, 79, 88, 128, 72, 77, 85, 82, 88, 128, 72, 77, 89, 82, 88, 128, 72, 
+    78, 73, 69, 80, 128, 72, 78, 73, 69, 84, 128, 72, 78, 73, 69, 88, 128, 
+    72, 78, 85, 79, 88, 128, 72, 79, 79, 82, 85, 128, 72, 79, 85, 83, 69, 
+    128, 72, 85, 77, 65, 78, 128, 72, 85, 82, 65, 78, 128, 72, 88, 73, 69, 
+    80, 128, 72, 88, 73, 69, 84, 128, 72, 88, 73, 69, 88, 128, 72, 88, 85, 
+    79, 80, 128, 72, 88, 85, 79, 84, 128, 72, 88, 85, 79, 88, 128, 72, 89, 
+    80, 72, 69, 206, 73, 67, 72, 79, 85, 128, 73, 71, 71, 87, 83, 128, 73, 
+    78, 78, 69, 82, 128, 73, 83, 65, 75, 73, 193, 74, 74, 73, 69, 80, 128, 
+    74, 74, 73, 69, 84, 128, 74, 74, 73, 69, 88, 128, 74, 74, 85, 79, 80, 
+    128, 74, 74, 85, 79, 88, 128, 74, 74, 85, 82, 88, 128, 74, 79, 89, 79, 
+    85, 211, 74, 85, 68, 71, 69, 128, 74, 85, 69, 85, 73, 128, 75, 65, 65, 
+    70, 85, 128, 75, 65, 73, 82, 73, 128, 75, 65, 83, 82, 65, 128, 75, 65, 
+    84, 65, 86, 193, 75, 65, 85, 78, 65, 128, 75, 69, 69, 83, 85, 128, 75, 
+    69, 72, 69, 72, 128, 75, 69, 76, 86, 73, 206, 75, 69, 78, 65, 84, 128, 
+    75, 72, 65, 78, 68, 193, 75, 72, 65, 80, 72, 128, 75, 72, 85, 65, 84, 
+    128, 75, 72, 87, 65, 73, 128, 75, 78, 73, 70, 69, 128, 75, 79, 79, 80, 
+    79, 128, 75, 85, 83, 77, 65, 128, 75, 88, 87, 65, 65, 128, 75, 88, 87, 
+    69, 69, 128, 76, 45, 84, 89, 80, 197, 76, 65, 65, 77, 85, 128, 76, 65, 
+    71, 85, 83, 128, 76, 65, 77, 66, 68, 193, 76, 65, 85, 75, 65, 218, 76, 
+    69, 77, 79, 73, 128, 76, 73, 66, 82, 65, 128, 76, 73, 77, 73, 84, 128, 
+    76, 73, 78, 69, 83, 128, 76, 73, 81, 85, 73, 196, 76, 79, 78, 71, 65, 
+    128, 76, 79, 84, 85, 83, 128, 76, 79, 85, 82, 69, 128, 77, 65, 68, 68, 
+    65, 128, 77, 65, 68, 68, 65, 200, 77, 65, 72, 72, 65, 128, 77, 65, 73, 
+    82, 85, 128, 77, 65, 78, 78, 65, 128, 77, 65, 78, 78, 65, 218, 77, 65, 
+    81, 65, 70, 128, 77, 65, 82, 67, 72, 128, 77, 65, 83, 79, 82, 193, 77, 
+    69, 69, 77, 85, 128, 77, 69, 73, 90, 73, 128, 77, 69, 76, 79, 78, 128, 
+    77, 69, 77, 66, 69, 210, 77, 69, 82, 75, 72, 193, 77, 69, 84, 69, 71, 
+    128, 77, 69, 90, 90, 79, 128, 77, 71, 73, 69, 88, 128, 77, 71, 85, 79, 
+    80, 128, 77, 71, 85, 79, 88, 128, 77, 71, 85, 82, 88, 128, 77, 73, 75, 
+    82, 73, 128, 77, 73, 75, 82, 79, 206, 77, 73, 82, 69, 68, 128, 77, 73, 
+    83, 82, 65, 128, 77, 79, 68, 69, 76, 128, 77, 79, 68, 85, 76, 207, 77, 
+    79, 78, 84, 72, 128, 77, 79, 85, 78, 68, 128, 77, 85, 78, 65, 72, 128, 
+    77, 85, 83, 73, 67, 128, 78, 65, 82, 82, 79, 215, 78, 65, 85, 68, 73, 
+    218, 78, 65, 88, 73, 65, 206, 78, 66, 73, 69, 80, 128, 78, 66, 73, 69, 
+    88, 128, 78, 66, 85, 82, 88, 128, 78, 66, 89, 82, 88, 128, 78, 68, 73, 
+    69, 88, 128, 78, 68, 85, 82, 88, 128, 78, 71, 65, 65, 73, 128, 78, 71, 
+    73, 69, 80, 128, 78, 71, 73, 69, 88, 128, 78, 71, 79, 69, 72, 128, 78, 
+    71, 85, 79, 84, 128, 78, 71, 85, 79, 88, 128, 78, 73, 78, 69, 84, 217, 
+    78, 74, 73, 69, 80, 128, 78, 74, 73, 69, 84, 128, 78, 74, 73, 69, 88, 
+    128, 78, 74, 85, 79, 88, 128, 78, 74, 85, 82, 88, 128, 78, 74, 89, 82, 
+    88, 128, 78, 78, 71, 65, 65, 128, 78, 78, 71, 73, 73, 128, 78, 78, 71, 
+    79, 79, 128, 78, 79, 79, 78, 85, 128, 78, 79, 84, 67, 72, 128, 78, 79, 
+    84, 84, 79, 128, 78, 82, 85, 82, 88, 128, 78, 82, 89, 82, 88, 128, 78, 
+    85, 77, 69, 82, 207, 78, 89, 73, 69, 80, 128, 78, 89, 73, 69, 84, 128, 
+    78, 89, 73, 69, 88, 128, 78, 89, 85, 79, 80, 128, 78, 89, 85, 79, 88, 
+    128, 78, 90, 73, 69, 80, 128, 78, 90, 73, 69, 88, 128, 78, 90, 85, 79, 
+    88, 128, 78, 90, 85, 82, 88, 128, 78, 90, 89, 82, 88, 128, 79, 66, 74, 
+    69, 67, 212, 79, 74, 69, 79, 78, 128, 79, 76, 73, 86, 69, 128, 79, 78, 
+    75, 65, 82, 128, 79, 80, 84, 73, 79, 206, 79, 84, 72, 65, 76, 128, 79, 
+    85, 78, 75, 73, 193, 79, 88, 69, 73, 65, 201, 80, 65, 65, 84, 85, 128, 
+    80, 65, 83, 69, 81, 128, 80, 65, 83, 85, 81, 128, 80, 65, 84, 65, 75, 
+    128, 80, 65, 90, 69, 82, 128, 80, 69, 65, 67, 69, 128, 80, 69, 69, 90, 
+    73, 128, 80, 69, 72, 69, 72, 128, 80, 69, 73, 84, 72, 128, 80, 69, 78, 
+    83, 85, 128, 80, 69, 79, 82, 84, 200, 80, 69, 82, 84, 72, 207, 80, 69, 
+    83, 69, 84, 193, 80, 72, 78, 65, 69, 203, 80, 72, 85, 78, 71, 128, 80, 
+    73, 65, 78, 79, 128, 80, 76, 85, 84, 79, 128, 80, 79, 69, 84, 73, 195, 
+    80, 79, 78, 68, 79, 128, 80, 82, 73, 78, 84, 128, 80, 82, 79, 79, 70, 
+    128, 80, 82, 79, 86, 69, 128, 81, 65, 65, 70, 85, 128, 81, 65, 68, 77, 
+    65, 128, 81, 65, 77, 65, 84, 211, 81, 65, 82, 78, 69, 217, 81, 72, 87, 
+    65, 65, 128, 81, 72, 87, 69, 69, 128, 82, 45, 67, 82, 69, 197, 82, 65, 
+    73, 68, 65, 128, 82, 65, 83, 72, 65, 128, 82, 65, 83, 79, 85, 204, 82, 
+    65, 84, 73, 79, 128, 82, 69, 67, 79, 82, 196, 82, 69, 84, 85, 82, 206, 
+    82, 69, 86, 73, 65, 128, 82, 69, 86, 77, 65, 128, 82, 72, 79, 84, 73, 
+    195, 82, 73, 86, 69, 82, 128, 82, 78, 79, 79, 78, 128, 82, 79, 66, 65, 
+    84, 128, 82, 82, 85, 79, 88, 128, 82, 82, 85, 82, 88, 128, 82, 82, 89, 
+    82, 88, 128, 82, 85, 80, 73, 73, 128, 82, 87, 65, 72, 65, 128, 83, 65, 
+    68, 72, 69, 128, 83, 65, 70, 72, 65, 128, 83, 65, 77, 69, 75, 200, 83, 
+    65, 77, 75, 65, 128, 83, 65, 77, 89, 79, 203, 83, 65, 78, 65, 72, 128, 
+    83, 65, 85, 73, 76, 128, 83, 69, 69, 78, 85, 128, 83, 69, 73, 83, 77, 
+    193, 83, 69, 78, 84, 73, 128, 83, 72, 69, 69, 78, 128, 83, 72, 69, 81, 
+    69, 204, 83, 72, 69, 86, 65, 128, 83, 72, 73, 73, 78, 128, 83, 72, 79, 
+    79, 84, 128, 83, 72, 79, 82, 84, 128, 83, 72, 85, 79, 80, 128, 83, 72, 
+    85, 79, 88, 128, 83, 72, 85, 82, 88, 128, 83, 72, 89, 82, 88, 128, 83, 
+    73, 88, 84, 72, 128, 83, 76, 65, 86, 69, 128, 83, 76, 73, 67, 69, 128, 
+    83, 76, 79, 80, 69, 128, 83, 77, 69, 65, 82, 128, 83, 77, 73, 76, 69, 
+    128, 83, 78, 65, 75, 69, 128, 83, 78, 79, 85, 84, 128, 83, 79, 85, 78, 
+    68, 128, 83, 79, 87, 73, 76, 207, 83, 80, 73, 67, 69, 128, 83, 80, 79, 
+    79, 78, 128, 83, 80, 85, 78, 71, 211, 83, 81, 85, 73, 83, 200, 83, 83, 
+    73, 69, 80, 128, 83, 83, 73, 69, 88, 128, 83, 83, 89, 82, 88, 128, 83, 
+    84, 65, 78, 68, 128, 83, 84, 65, 82, 75, 128, 83, 84, 69, 65, 77, 128, 
+    83, 84, 79, 78, 69, 128, 83, 84, 79, 86, 69, 128, 83, 87, 69, 69, 84, 
+    128, 83, 87, 79, 82, 68, 128, 83, 89, 82, 77, 65, 128, 84, 65, 76, 69, 
+    78, 212, 84, 65, 80, 69, 82, 128, 84, 67, 72, 69, 72, 128, 84, 69, 73, 
+    87, 83, 128, 84, 69, 86, 73, 82, 128, 84, 72, 73, 71, 72, 128, 84, 72, 
+    73, 82, 68, 128, 84, 72, 73, 82, 68, 211, 84, 72, 73, 84, 65, 128, 84, 
+    72, 79, 78, 71, 128, 84, 72, 85, 78, 71, 128, 84, 73, 78, 78, 69, 128, 
+    84, 73, 80, 80, 73, 128, 84, 76, 72, 69, 69, 128, 84, 82, 65, 67, 75, 
+    128, 84, 82, 73, 84, 79, 211, 84, 82, 85, 84, 72, 128, 84, 83, 69, 82, 
+    69, 128, 84, 84, 83, 69, 69, 128, 84, 84, 84, 72, 65, 128, 84, 85, 71, 
+    82, 73, 203, 84, 85, 82, 79, 50, 128, 84, 89, 80, 69, 45, 177, 84, 89, 
+    80, 69, 45, 178, 84, 89, 80, 69, 45, 179, 84, 89, 80, 69, 45, 180, 84, 
+    89, 80, 69, 45, 181, 84, 89, 80, 69, 45, 182, 84, 89, 80, 69, 45, 183, 
+    85, 78, 73, 84, 89, 128, 85, 80, 87, 65, 82, 196, 86, 65, 65, 86, 85, 
+    128, 86, 65, 83, 73, 83, 128, 86, 65, 84, 72, 89, 128, 86, 69, 67, 84, 
+    79, 210, 86, 69, 82, 71, 69, 128, 86, 73, 82, 71, 65, 128, 86, 73, 82, 
+    71, 79, 128, 86, 79, 76, 85, 77, 197, 87, 65, 65, 86, 85, 128, 87, 65, 
+    83, 76, 65, 128, 87, 72, 69, 69, 76, 128, 87, 73, 78, 74, 65, 128, 87, 
+    82, 69, 65, 84, 200, 87, 82, 79, 78, 71, 128, 88, 69, 83, 84, 69, 211, 
+    89, 65, 45, 89, 79, 128, 89, 65, 65, 68, 79, 128, 89, 65, 65, 82, 85, 
+    128, 89, 65, 68, 68, 72, 128, 89, 65, 71, 72, 72, 128, 89, 65, 75, 72, 
+    72, 128, 89, 69, 79, 45, 79, 128, 89, 69, 79, 45, 85, 128, 89, 69, 84, 
+    73, 86, 128, 89, 73, 90, 69, 84, 128, 89, 85, 45, 69, 79, 128, 90, 65, 
+    82, 81, 65, 128, 90, 65, 89, 73, 78, 128, 90, 72, 65, 73, 78, 128, 90, 
+    72, 85, 79, 80, 128, 90, 72, 85, 79, 88, 128, 90, 72, 85, 82, 88, 128, 
+    90, 72, 89, 82, 88, 128, 90, 73, 76, 68, 69, 128, 90, 73, 78, 79, 82, 
+    128, 90, 89, 71, 79, 83, 128, 90, 90, 73, 69, 80, 128, 90, 90, 73, 69, 
+    88, 128, 90, 90, 85, 82, 88, 128, 90, 90, 89, 82, 88, 128, 78, 65, 71, 
+    82, 201, 83, 72, 79, 82, 212, 83, 72, 69, 69, 206, 90, 69, 82, 79, 128, 
+    82, 79, 77, 65, 206, 84, 73, 76, 68, 197, 76, 69, 70, 84, 128, 79, 71, 
+    72, 65, 205, 86, 79, 67, 65, 204, 78, 79, 82, 84, 200, 67, 85, 82, 76, 
+    217, 65, 84, 84, 73, 195, 83, 79, 85, 84, 200, 66, 69, 76, 79, 215, 66, 
+    85, 72, 73, 196, 80, 79, 73, 78, 212, 84, 65, 67, 75, 128, 68, 65, 83, 
+    72, 128, 68, 79, 87, 78, 128, 73, 79, 84, 65, 128, 78, 45, 65, 82, 217, 
+    82, 69, 83, 84, 128, 71, 72, 65, 73, 206, 65, 67, 85, 84, 197, 66, 69, 
+    84, 65, 128, 66, 82, 69, 86, 197, 67, 79, 77, 77, 193, 71, 82, 65, 86, 
+    197, 75, 79, 69, 84, 128, 86, 65, 82, 73, 193, 90, 69, 84, 65, 128, 67, 
+    72, 69, 83, 211, 67, 85, 82, 76, 128, 83, 72, 69, 76, 204, 84, 72, 69, 
+    84, 193, 83, 79, 85, 78, 196, 85, 78, 73, 79, 206, 65, 76, 69, 70, 128, 
+    65, 84, 84, 65, 203, 68, 79, 84, 83, 128, 70, 79, 82, 84, 217, 72, 65, 
+    76, 70, 128, 78, 79, 84, 69, 128, 84, 79, 78, 65, 204, 73, 77, 65, 71, 
+    197, 80, 76, 85, 83, 128, 65, 71, 79, 71, 201, 69, 77, 80, 84, 217, 72, 
+    69, 65, 82, 212, 83, 85, 73, 84, 128, 70, 73, 70, 84, 217, 70, 73, 76, 
+    76, 128, 75, 65, 84, 79, 128, 75, 69, 72, 69, 200, 76, 65, 82, 71, 197, 
+    83, 72, 65, 68, 128, 66, 69, 71, 73, 206, 67, 65, 82, 69, 212, 70, 65, 
+    82, 83, 201, 70, 73, 82, 69, 128, 72, 79, 82, 73, 128, 75, 65, 80, 80, 
+    193, 77, 79, 79, 78, 128, 83, 69, 86, 69, 206, 83, 72, 69, 73, 128, 83, 
+    72, 73, 78, 128, 83, 85, 78, 71, 128, 84, 73, 67, 75, 128, 67, 76, 69, 
+    70, 128, 67, 82, 79, 83, 211, 70, 65, 84, 72, 193, 70, 73, 82, 83, 212, 
+    77, 65, 68, 68, 193, 81, 85, 65, 68, 128, 82, 85, 80, 69, 197, 83, 73, 
+    71, 77, 193, 83, 84, 69, 77, 128, 84, 67, 72, 69, 200, 84, 73, 77, 69, 
+    211, 84, 83, 72, 69, 199, 89, 65, 78, 71, 128, 65, 76, 84, 65, 128, 66, 
+    69, 72, 69, 200, 67, 72, 69, 67, 203, 67, 82, 79, 80, 128, 68, 65, 77, 
+    77, 193, 70, 73, 84, 65, 128, 71, 82, 69, 65, 212, 72, 65, 78, 68, 128, 
+    73, 90, 72, 69, 128, 74, 79, 73, 78, 128, 75, 65, 80, 65, 128, 75, 65, 
+    83, 82, 193, 75, 72, 69, 73, 128, 75, 87, 65, 65, 128, 76, 79, 78, 71, 
+    128, 78, 71, 79, 69, 200, 79, 66, 79, 76, 211, 80, 69, 72, 69, 200, 82, 
+    65, 70, 69, 128, 82, 78, 79, 79, 206, 82, 84, 65, 71, 211, 83, 67, 72, 
+    87, 193, 83, 72, 65, 82, 208, 84, 72, 65, 65, 128, 84, 72, 69, 69, 128, 
+    86, 65, 78, 69, 128, 87, 65, 86, 69, 128, 87, 73, 78, 68, 128, 65, 76, 
+    76, 79, 128, 66, 73, 82, 68, 128, 67, 65, 82, 79, 206, 67, 72, 65, 82, 
+    128, 67, 72, 73, 78, 128, 67, 72, 82, 79, 193, 67, 73, 69, 85, 195, 67, 
+    87, 65, 65, 128, 68, 69, 76, 84, 193, 70, 79, 79, 84, 128, 71, 72, 65, 
+    78, 128, 71, 79, 76, 68, 128, 71, 82, 65, 83, 211, 72, 65, 84, 65, 198, 
+    73, 69, 85, 78, 199, 74, 72, 65, 78, 128, 75, 69, 84, 84, 201, 75, 72, 
+    65, 82, 128, 76, 76, 76, 65, 128, 76, 79, 79, 80, 128, 77, 78, 65, 83, 
+    128, 77, 85, 83, 73, 195, 77, 87, 65, 65, 128, 78, 87, 65, 65, 128, 79, 
+    85, 84, 69, 210, 79, 88, 69, 73, 193, 80, 65, 80, 69, 210, 80, 69, 68, 
+    65, 204, 80, 72, 65, 82, 128, 80, 79, 76, 69, 128, 80, 82, 73, 77, 197, 
+    80, 87, 65, 65, 128, 82, 79, 79, 84, 128, 83, 69, 69, 78, 128, 83, 72, 
+    87, 65, 128, 83, 73, 76, 75, 128, 83, 73, 77, 65, 128, 83, 84, 65, 82, 
+    212, 83, 87, 65, 65, 128, 83, 87, 65, 83, 200, 84, 72, 73, 73, 128, 84, 
+    72, 73, 82, 196, 84, 83, 72, 65, 128, 84, 84, 72, 79, 128, 84, 87, 65, 
+    65, 128, 87, 73, 78, 69, 128, 89, 65, 71, 72, 128, 89, 65, 90, 72, 128, 
+    89, 73, 87, 78, 128, 89, 87, 65, 65, 128, 90, 72, 65, 82, 128, 90, 72, 
+    69, 69, 128, 45, 68, 90, 85, 196, 65, 76, 70, 65, 128, 65, 80, 69, 83, 
+    207, 65, 82, 71, 73, 128, 66, 66, 85, 84, 128, 66, 69, 65, 84, 128, 66, 
+    76, 65, 68, 197, 66, 76, 85, 69, 128, 66, 79, 78, 69, 128, 66, 82, 85, 
+    83, 200, 66, 85, 75, 89, 128, 66, 90, 85, 78, 199, 67, 65, 82, 84, 128, 
+    67, 85, 79, 80, 128, 67, 85, 82, 86, 197, 67, 87, 73, 73, 128, 67, 87, 
+    79, 79, 128, 68, 65, 76, 69, 212, 68, 68, 85, 82, 128, 68, 69, 69, 82, 
+    128, 68, 90, 72, 65, 128, 68, 90, 72, 69, 128, 68, 90, 74, 69, 128, 69, 
+    65, 82, 84, 200, 69, 82, 65, 83, 197, 70, 69, 69, 68, 128, 70, 73, 83, 
+    72, 128, 70, 76, 65, 71, 128, 70, 76, 65, 84, 128, 70, 82, 79, 71, 128, 
+    70, 87, 65, 65, 128, 71, 65, 84, 69, 128, 71, 67, 73, 71, 128, 71, 71, 
+    79, 80, 128, 71, 71, 85, 79, 128, 71, 72, 65, 68, 128, 71, 72, 72, 65, 
+    128, 71, 73, 77, 69, 204, 71, 79, 65, 76, 128, 71, 82, 65, 67, 197, 71, 
+    83, 85, 77, 128, 71, 89, 65, 83, 128, 71, 89, 79, 78, 128, 72, 65, 84, 
+    69, 128, 72, 65, 86, 69, 128, 72, 66, 65, 83, 193, 72, 69, 82, 85, 128, 
+    72, 72, 65, 65, 128, 72, 73, 69, 85, 200, 72, 88, 73, 84, 128, 72, 88, 
+    79, 80, 128, 72, 88, 85, 79, 128, 74, 65, 68, 69, 128, 74, 69, 69, 77, 
+    128, 74, 72, 69, 72, 128, 74, 74, 73, 69, 128, 74, 74, 85, 84, 128, 75, 
+    65, 75, 79, 128, 75, 72, 65, 72, 128, 75, 72, 65, 78, 199, 75, 72, 72, 
+    65, 128, 75, 78, 73, 70, 197, 75, 83, 83, 65, 128, 75, 87, 73, 73, 128, 
+    75, 87, 79, 79, 128, 76, 69, 65, 70, 128, 76, 73, 87, 78, 128, 76, 79, 
+    78, 71, 193, 76, 79, 87, 45, 185, 76, 87, 65, 65, 128, 76, 87, 73, 73, 
+    128, 76, 87, 79, 79, 128, 77, 69, 65, 84, 128, 77, 69, 69, 77, 128, 77, 
+    69, 69, 84, 128, 77, 69, 83, 79, 128, 77, 73, 69, 85, 205, 77, 79, 85, 
+    78, 196, 77, 87, 73, 73, 128, 77, 87, 79, 79, 128, 78, 65, 77, 69, 128, 
+    78, 65, 78, 65, 128, 78, 66, 73, 69, 128, 78, 73, 69, 85, 206, 78, 78, 
+    78, 65, 128, 78, 79, 68, 69, 128, 78, 89, 73, 80, 128, 78, 89, 79, 80, 
+    128, 78, 90, 85, 80, 128, 80, 65, 87, 78, 128, 80, 73, 69, 85, 208, 80, 
+    73, 87, 82, 128, 80, 76, 65, 67, 197, 80, 79, 85, 78, 196, 80, 87, 73, 
+    73, 128, 80, 87, 79, 79, 128, 81, 85, 79, 84, 197, 82, 65, 89, 83, 128, 
+    82, 66, 65, 83, 193, 82, 73, 69, 85, 204, 82, 73, 83, 72, 128, 82, 79, 
+    79, 75, 128, 82, 87, 65, 65, 128, 83, 65, 76, 76, 193, 83, 65, 76, 84, 
+    128, 83, 69, 65, 76, 128, 83, 72, 65, 65, 128, 83, 72, 65, 84, 128, 83, 
+    72, 69, 69, 128, 83, 72, 72, 65, 128, 83, 72, 73, 70, 212, 83, 72, 79, 
+    71, 201, 83, 72, 85, 82, 128, 83, 72, 87, 69, 128, 83, 72, 87, 73, 128, 
+    83, 72, 87, 79, 128, 83, 76, 85, 82, 128, 83, 77, 65, 83, 200, 83, 78, 
+    79, 85, 212, 83, 80, 65, 68, 197, 83, 81, 85, 65, 212, 83, 84, 65, 70, 
+    198, 83, 85, 75, 85, 206, 83, 87, 73, 73, 128, 83, 87, 79, 79, 128, 84, 
+    69, 88, 84, 128, 84, 72, 69, 82, 197, 84, 72, 79, 79, 128, 84, 73, 77, 
+    69, 128, 84, 73, 87, 78, 128, 84, 76, 72, 65, 128, 84, 76, 72, 69, 128, 
+    84, 76, 72, 73, 128, 84, 76, 72, 79, 128, 84, 82, 69, 69, 128, 84, 82, 
+    85, 69, 128, 84, 83, 72, 69, 128, 84, 87, 73, 73, 128, 84, 87, 79, 79, 
+    128, 85, 78, 68, 69, 210, 86, 69, 68, 69, 128, 86, 73, 68, 65, 128, 87, 
+    65, 76, 75, 128, 87, 65, 83, 76, 193, 87, 65, 84, 69, 210, 87, 72, 79, 
+    76, 197, 87, 79, 79, 68, 128, 87, 79, 79, 76, 128, 87, 89, 78, 78, 128, 
+    89, 65, 75, 72, 128, 89, 65, 84, 73, 128, 89, 69, 82, 73, 128, 89, 79, 
+    45, 73, 128, 89, 79, 71, 72, 128, 89, 85, 45, 73, 128, 89, 87, 73, 73, 
+    128, 89, 87, 79, 79, 128, 90, 65, 73, 78, 128, 90, 65, 81, 69, 198, 90, 
+    65, 84, 65, 128, 90, 76, 65, 77, 193, 45, 67, 72, 65, 210, 65, 69, 83, 
+    67, 128, 65, 70, 84, 69, 210, 65, 72, 83, 65, 128, 65, 73, 76, 77, 128, 
+    65, 73, 78, 78, 128, 65, 75, 66, 65, 210, 65, 76, 71, 73, 218, 65, 76, 
+    76, 65, 200, 65, 76, 80, 65, 128, 65, 77, 80, 83, 128, 65, 78, 72, 85, 
+    128, 65, 78, 75, 72, 128, 65, 78, 83, 85, 218, 65, 82, 77, 89, 128, 65, 
+    84, 78, 65, 200, 65, 85, 78, 78, 128, 65, 89, 65, 72, 128, 66, 48, 49, 
+    56, 128, 66, 48, 49, 57, 128, 66, 48, 50, 50, 128, 66, 48, 51, 52, 128, 
+    66, 48, 52, 55, 128, 66, 48, 52, 57, 128, 66, 48, 53, 54, 128, 66, 48, 
+    54, 51, 128, 66, 48, 54, 52, 128, 66, 48, 55, 57, 128, 66, 48, 56, 50, 
+    128, 66, 48, 56, 51, 128, 66, 48, 56, 54, 128, 66, 48, 56, 57, 128, 66, 
+    49, 48, 53, 198, 66, 49, 48, 53, 205, 66, 49, 48, 54, 198, 66, 49, 48, 
+    54, 205, 66, 49, 48, 55, 198, 66, 49, 48, 55, 205, 66, 49, 48, 56, 198, 
+    66, 49, 48, 56, 205, 66, 49, 48, 57, 198, 66, 49, 48, 57, 205, 66, 49, 
+    51, 50, 128, 66, 49, 52, 50, 128, 66, 49, 52, 54, 128, 66, 49, 53, 48, 
+    128, 66, 49, 53, 50, 128, 66, 49, 53, 51, 128, 66, 49, 53, 52, 128, 66, 
+    49, 53, 53, 128, 66, 49, 53, 55, 128, 66, 49, 53, 56, 128, 66, 49, 54, 
+    48, 128, 66, 49, 54, 49, 128, 66, 49, 54, 52, 128, 66, 49, 54, 53, 128, 
+    66, 49, 54, 54, 128, 66, 49, 54, 55, 128, 66, 49, 54, 56, 128, 66, 49, 
+    54, 57, 128, 66, 49, 55, 48, 128, 66, 49, 55, 49, 128, 66, 49, 55, 50, 
+    128, 66, 49, 55, 52, 128, 66, 49, 55, 55, 128, 66, 49, 55, 56, 128, 66, 
+    49, 55, 57, 128, 66, 49, 56, 48, 128, 66, 49, 56, 49, 128, 66, 49, 56, 
+    50, 128, 66, 49, 56, 51, 128, 66, 49, 56, 52, 128, 66, 49, 56, 53, 128, 
+    66, 49, 56, 57, 128, 66, 49, 57, 48, 128, 66, 50, 48, 48, 128, 66, 50, 
+    48, 49, 128, 66, 50, 48, 50, 128, 66, 50, 48, 51, 128, 66, 50, 48, 52, 
+    128, 66, 50, 48, 53, 128, 66, 50, 48, 54, 128, 66, 50, 48, 55, 128, 66, 
+    50, 48, 56, 128, 66, 50, 48, 57, 128, 66, 50, 49, 48, 128, 66, 50, 49, 
+    49, 128, 66, 50, 49, 50, 128, 66, 50, 49, 51, 128, 66, 50, 49, 52, 128, 
+    66, 50, 49, 53, 128, 66, 50, 49, 54, 128, 66, 50, 49, 55, 128, 66, 50, 
+    49, 56, 128, 66, 50, 49, 57, 128, 66, 50, 50, 49, 128, 66, 50, 50, 50, 
+    128, 66, 50, 50, 54, 128, 66, 50, 50, 55, 128, 66, 50, 50, 56, 128, 66, 
+    50, 50, 57, 128, 66, 50, 51, 50, 128, 66, 50, 51, 52, 128, 66, 50, 51, 
+    54, 128, 66, 50, 52, 53, 128, 66, 50, 52, 54, 128, 66, 50, 52, 56, 128, 
+    66, 50, 52, 57, 128, 66, 50, 53, 48, 128, 66, 50, 53, 49, 128, 66, 50, 
+    53, 50, 128, 66, 50, 53, 51, 128, 66, 50, 53, 53, 128, 66, 50, 53, 54, 
+    128, 66, 50, 53, 55, 128, 66, 50, 53, 56, 128, 66, 50, 53, 57, 128, 66, 
+    51, 48, 53, 128, 66, 65, 67, 75, 128, 66, 65, 71, 65, 128, 66, 65, 72, 
+    84, 128, 66, 65, 82, 83, 128, 66, 65, 83, 69, 128, 66, 66, 65, 80, 128, 
+    66, 66, 65, 84, 128, 66, 66, 65, 88, 128, 66, 66, 69, 80, 128, 66, 66, 
+    69, 88, 128, 66, 66, 73, 69, 128, 66, 66, 73, 80, 128, 66, 66, 73, 84, 
+    128, 66, 66, 73, 88, 128, 66, 66, 79, 80, 128, 66, 66, 79, 84, 128, 66, 
+    66, 79, 88, 128, 66, 66, 85, 79, 128, 66, 66, 85, 80, 128, 66, 66, 85, 
+    82, 128, 66, 66, 85, 88, 128, 66, 66, 89, 80, 128, 66, 66, 89, 84, 128, 
+    66, 66, 89, 88, 128, 66, 67, 65, 68, 128, 66, 69, 65, 78, 128, 66, 69, 
+    69, 72, 128, 66, 69, 76, 76, 128, 66, 69, 76, 84, 128, 66, 69, 78, 68, 
+    128, 66, 69, 79, 82, 195, 66, 69, 84, 72, 128, 66, 73, 82, 85, 128, 66, 
+    76, 65, 78, 203, 66, 79, 65, 82, 128, 66, 79, 65, 84, 128, 66, 79, 68, 
+    89, 128, 66, 83, 68, 85, 211, 66, 83, 75, 65, 173, 66, 83, 75, 85, 210, 
+    66, 85, 76, 76, 128, 66, 85, 77, 80, 217, 66, 87, 69, 69, 128, 67, 65, 
+    65, 73, 128, 67, 65, 76, 67, 128, 67, 65, 76, 76, 128, 67, 65, 80, 79, 
+    128, 67, 65, 86, 69, 128, 67, 65, 89, 78, 128, 67, 67, 65, 65, 128, 67, 
+    67, 69, 69, 128, 67, 67, 72, 65, 128, 67, 67, 72, 69, 128, 67, 67, 72, 
+    73, 128, 67, 67, 72, 79, 128, 67, 67, 72, 85, 128, 67, 72, 65, 78, 128, 
+    67, 72, 65, 80, 128, 67, 72, 65, 84, 128, 67, 72, 65, 88, 128, 67, 72, 
+    69, 80, 128, 67, 72, 69, 84, 128, 67, 72, 69, 88, 128, 67, 72, 79, 65, 
+    128, 67, 72, 79, 69, 128, 67, 72, 79, 80, 128, 67, 72, 79, 84, 128, 67, 
+    72, 79, 88, 128, 67, 72, 85, 79, 128, 67, 72, 85, 80, 128, 67, 72, 85, 
+    82, 128, 67, 72, 85, 88, 128, 67, 72, 89, 80, 128, 67, 72, 89, 82, 128, 
+    67, 72, 89, 84, 128, 67, 72, 89, 88, 128, 67, 73, 69, 80, 128, 67, 73, 
+    69, 84, 128, 67, 73, 69, 88, 128, 67, 76, 65, 78, 128, 67, 76, 65, 87, 
+    128, 67, 76, 69, 65, 210, 67, 76, 79, 83, 197, 67, 79, 68, 65, 128, 67, 
+    79, 76, 76, 128, 67, 79, 80, 89, 128, 67, 85, 79, 88, 128, 67, 85, 82, 
+    88, 128, 67, 89, 82, 88, 128, 68, 65, 71, 65, 218, 68, 65, 71, 83, 128, 
+    68, 65, 73, 82, 128, 68, 65, 77, 80, 128, 68, 65, 82, 84, 128, 68, 68, 
+    65, 65, 128, 68, 68, 65, 76, 128, 68, 68, 65, 80, 128, 68, 68, 65, 84, 
+    128, 68, 68, 65, 88, 128, 68, 68, 69, 69, 128, 68, 68, 69, 80, 128, 68, 
+    68, 69, 88, 128, 68, 68, 72, 79, 128, 68, 68, 73, 69, 128, 68, 68, 73, 
+    80, 128, 68, 68, 73, 84, 128, 68, 68, 73, 88, 128, 68, 68, 79, 65, 128, 
+    68, 68, 79, 80, 128, 68, 68, 79, 84, 128, 68, 68, 79, 88, 128, 68, 68, 
+    85, 79, 128, 68, 68, 85, 80, 128, 68, 68, 85, 84, 128, 68, 68, 85, 88, 
+    128, 68, 68, 87, 65, 128, 68, 69, 65, 68, 128, 68, 69, 66, 73, 212, 68, 
+    69, 69, 76, 128, 68, 69, 72, 73, 128, 68, 69, 75, 65, 128, 68, 69, 83, 
+    73, 128, 68, 72, 65, 76, 128, 68, 73, 80, 76, 201, 68, 73, 83, 72, 128, 
+    68, 73, 84, 84, 207, 68, 76, 69, 69, 128, 68, 79, 73, 84, 128, 68, 79, 
+    79, 82, 128, 68, 79, 82, 85, 128, 68, 82, 85, 77, 128, 68, 89, 69, 72, 
+    128, 68, 90, 69, 69, 128, 69, 72, 87, 65, 218, 69, 74, 69, 67, 212, 69, 
+    78, 84, 69, 210, 69, 84, 72, 69, 204, 69, 85, 45, 85, 128, 69, 85, 76, 
+    69, 210, 70, 65, 65, 73, 128, 70, 65, 78, 71, 128, 70, 76, 73, 80, 128, 
+    70, 79, 82, 77, 211, 70, 82, 65, 78, 195, 70, 85, 82, 88, 128, 70, 85, 
+    83, 69, 128, 70, 87, 69, 69, 128, 71, 65, 77, 65, 204, 71, 68, 65, 78, 
+    128, 71, 69, 65, 82, 128, 71, 71, 65, 65, 128, 71, 71, 65, 80, 128, 71, 
+    71, 65, 84, 128, 71, 71, 65, 88, 128, 71, 71, 69, 69, 128, 71, 71, 69, 
+    80, 128, 71, 71, 69, 84, 128, 71, 71, 69, 88, 128, 71, 71, 73, 69, 128, 
+    71, 71, 73, 84, 128, 71, 71, 73, 88, 128, 71, 71, 79, 84, 128, 71, 71, 
+    79, 88, 128, 71, 71, 85, 80, 128, 71, 71, 85, 82, 128, 71, 71, 85, 84, 
+    128, 71, 71, 85, 88, 128, 71, 71, 87, 65, 128, 71, 71, 87, 69, 128, 71, 
+    71, 87, 73, 128, 71, 72, 69, 69, 128, 71, 73, 66, 65, 128, 71, 73, 69, 
+    84, 128, 71, 73, 71, 65, 128, 71, 79, 73, 78, 199, 71, 79, 82, 84, 128, 
+    71, 85, 69, 72, 128, 71, 89, 65, 65, 128, 71, 89, 69, 69, 128, 72, 65, 
+    69, 71, 204, 72, 65, 71, 76, 128, 72, 69, 77, 80, 128, 72, 72, 69, 69, 
+    128, 72, 72, 87, 65, 128, 72, 73, 69, 88, 128, 72, 73, 90, 66, 128, 72, 
+    76, 65, 80, 128, 72, 76, 65, 84, 128, 72, 76, 65, 88, 128, 72, 76, 69, 
+    80, 128, 72, 76, 69, 88, 128, 72, 76, 73, 69, 128, 72, 76, 73, 80, 128, 
+    72, 76, 73, 84, 128, 72, 76, 73, 88, 128, 72, 76, 79, 80, 128, 72, 76, 
+    79, 88, 128, 72, 76, 85, 79, 128, 72, 76, 85, 80, 128, 72, 76, 85, 82, 
+    128, 72, 76, 85, 84, 128, 72, 76, 85, 88, 128, 72, 76, 89, 80, 128, 72, 
+    76, 89, 82, 128, 72, 76, 89, 84, 128, 72, 76, 89, 88, 128, 72, 77, 65, 
+    80, 128, 72, 77, 65, 84, 128, 72, 77, 65, 88, 128, 72, 77, 73, 69, 128, 
+    72, 77, 73, 80, 128, 72, 77, 73, 84, 128, 72, 77, 73, 88, 128, 72, 77, 
+    79, 80, 128, 72, 77, 79, 84, 128, 72, 77, 79, 88, 128, 72, 77, 85, 79, 
+    128, 72, 77, 85, 80, 128, 72, 77, 85, 82, 128, 72, 77, 85, 84, 128, 72, 
+    77, 85, 88, 128, 72, 77, 89, 80, 128, 72, 77, 89, 82, 128, 72, 77, 89, 
+    88, 128, 72, 78, 65, 80, 128, 72, 78, 65, 84, 128, 72, 78, 65, 88, 128, 
+    72, 78, 69, 80, 128, 72, 78, 69, 88, 128, 72, 78, 73, 69, 128, 72, 78, 
+    73, 80, 128, 72, 78, 73, 84, 128, 72, 78, 73, 88, 128, 72, 78, 79, 80, 
+    128, 72, 78, 79, 84, 128, 72, 78, 79, 88, 128, 72, 78, 85, 79, 128, 72, 
+    78, 85, 84, 128, 72, 79, 79, 78, 128, 72, 79, 84, 65, 128, 72, 80, 87, 
+    71, 128, 72, 85, 77, 65, 206, 72, 88, 65, 80, 128, 72, 88, 65, 84, 128, 
+    72, 88, 65, 88, 128, 72, 88, 69, 80, 128, 72, 88, 69, 88, 128, 72, 88, 
+    73, 69, 128, 72, 88, 73, 80, 128, 72, 88, 73, 88, 128, 72, 88, 79, 84, 
+    128, 72, 88, 79, 88, 128, 72, 90, 87, 71, 128, 72, 90, 90, 80, 128, 72, 
+    90, 90, 90, 128, 73, 45, 69, 85, 128, 73, 45, 89, 65, 128, 73, 68, 76, 
+    69, 128, 73, 70, 73, 78, 128, 73, 76, 85, 89, 128, 73, 78, 67, 72, 128, 
+    73, 78, 78, 69, 210, 73, 78, 78, 78, 128, 73, 78, 84, 73, 128, 73, 83, 
+    79, 78, 128, 73, 84, 69, 77, 128, 73, 85, 74, 65, 128, 74, 69, 82, 65, 
+    206, 74, 74, 69, 69, 128, 74, 74, 73, 80, 128, 74, 74, 73, 84, 128, 74, 
+    74, 73, 88, 128, 74, 74, 79, 80, 128, 74, 74, 79, 84, 128, 74, 74, 79, 
+    88, 128, 74, 74, 85, 79, 128, 74, 74, 85, 80, 128, 74, 74, 85, 82, 128, 
+    74, 74, 85, 88, 128, 74, 74, 89, 80, 128, 74, 74, 89, 84, 128, 74, 74, 
+    89, 88, 128, 74, 85, 76, 89, 128, 74, 85, 78, 69, 128, 74, 85, 79, 84, 
+    128, 75, 65, 65, 70, 128, 75, 65, 65, 73, 128, 75, 65, 80, 72, 128, 75, 
+    65, 80, 79, 128, 75, 67, 65, 76, 128, 75, 72, 65, 65, 128, 75, 72, 65, 
+    73, 128, 75, 72, 65, 78, 128, 75, 72, 69, 69, 128, 75, 72, 79, 78, 128, 
+    75, 73, 67, 75, 128, 75, 73, 69, 80, 128, 75, 73, 69, 88, 128, 75, 73, 
+    82, 79, 128, 75, 75, 69, 69, 128, 75, 79, 77, 66, 213, 75, 79, 84, 79, 
+    128, 75, 85, 79, 80, 128, 75, 85, 79, 88, 128, 75, 85, 82, 84, 128, 75, 
+    85, 82, 88, 128, 75, 85, 85, 72, 128, 75, 87, 69, 69, 128, 75, 88, 65, 
+    65, 128, 75, 88, 69, 69, 128, 75, 88, 87, 65, 128, 75, 88, 87, 69, 128, 
+    75, 88, 87, 73, 128, 75, 89, 65, 65, 128, 75, 89, 69, 69, 128, 76, 65, 
+    65, 73, 128, 76, 65, 65, 78, 128, 76, 65, 69, 86, 128, 76, 65, 77, 69, 
+    128, 76, 65, 77, 69, 196, 76, 68, 65, 78, 128, 76, 69, 69, 75, 128, 76, 
+    69, 71, 83, 128, 76, 69, 86, 69, 204, 76, 69, 90, 72, 128, 76, 72, 65, 
+    65, 128, 76, 72, 73, 73, 128, 76, 72, 79, 79, 128, 76, 73, 69, 84, 128, 
+    76, 73, 70, 69, 128, 76, 73, 84, 82, 193, 76, 79, 76, 76, 128, 76, 79, 
+    79, 84, 128, 76, 85, 73, 83, 128, 76, 85, 79, 84, 128, 77, 65, 65, 73, 
+    128, 77, 65, 82, 69, 128, 77, 69, 82, 73, 128, 77, 69, 83, 72, 128, 77, 
+    69, 83, 73, 128, 77, 71, 65, 80, 128, 77, 71, 65, 84, 128, 77, 71, 65, 
+    88, 128, 77, 71, 69, 80, 128, 77, 71, 69, 88, 128, 77, 71, 73, 69, 128, 
+    77, 71, 79, 80, 128, 77, 71, 79, 84, 128, 77, 71, 79, 88, 128, 77, 71, 
+    85, 79, 128, 77, 71, 85, 80, 128, 77, 71, 85, 82, 128, 77, 71, 85, 84, 
+    128, 77, 71, 85, 88, 128, 77, 73, 67, 82, 207, 77, 73, 73, 78, 128, 77, 
+    73, 76, 76, 197, 77, 73, 77, 69, 128, 77, 73, 78, 89, 128, 77, 73, 82, 
+    73, 128, 77, 78, 89, 65, 205, 77, 79, 78, 84, 200, 77, 79, 85, 84, 200, 
+    77, 79, 86, 69, 196, 77, 85, 73, 78, 128, 77, 85, 76, 84, 201, 77, 85, 
+    79, 84, 128, 77, 87, 69, 69, 128, 78, 65, 65, 73, 128, 78, 65, 73, 82, 
+    193, 78, 65, 78, 68, 128, 78, 66, 65, 80, 128, 78, 66, 65, 84, 128, 78, 
+    66, 65, 88, 128, 78, 66, 73, 80, 128, 78, 66, 73, 84, 128, 78, 66, 73, 
+    88, 128, 78, 66, 79, 80, 128, 78, 66, 79, 84, 128, 78, 66, 79, 88, 128, 
+    78, 66, 85, 80, 128, 78, 66, 85, 82, 128, 78, 66, 85, 84, 128, 78, 66, 
+    85, 88, 128, 78, 66, 89, 80, 128, 78, 66, 89, 82, 128, 78, 66, 89, 84, 
+    128, 78, 66, 89, 88, 128, 78, 68, 65, 80, 128, 78, 68, 65, 84, 128, 78, 
+    68, 65, 88, 128, 78, 68, 69, 80, 128, 78, 68, 73, 69, 128, 78, 68, 73, 
+    80, 128, 78, 68, 73, 84, 128, 78, 68, 73, 88, 128, 78, 68, 79, 80, 128, 
+    78, 68, 79, 84, 128, 78, 68, 79, 88, 128, 78, 68, 85, 80, 128, 78, 68, 
+    85, 82, 128, 78, 68, 85, 84, 128, 78, 68, 85, 88, 128, 78, 71, 65, 73, 
+    128, 78, 71, 65, 80, 128, 78, 71, 65, 84, 128, 78, 71, 65, 88, 128, 78, 
+    71, 69, 80, 128, 78, 71, 69, 88, 128, 78, 71, 73, 69, 128, 78, 71, 75, 
+    65, 128, 78, 71, 79, 80, 128, 78, 71, 79, 84, 128, 78, 71, 79, 88, 128, 
+    78, 71, 85, 79, 128, 78, 74, 73, 69, 128, 78, 74, 73, 80, 128, 78, 74, 
+    73, 84, 128, 78, 74, 73, 88, 128, 78, 74, 79, 80, 128, 78, 74, 79, 84, 
+    128, 78, 74, 79, 88, 128, 78, 74, 85, 79, 128, 78, 74, 85, 80, 128, 78, 
+    74, 85, 82, 128, 78, 74, 85, 88, 128, 78, 74, 89, 80, 128, 78, 74, 89, 
+    82, 128, 78, 74, 89, 84, 128, 78, 74, 89, 88, 128, 78, 78, 71, 65, 128, 
+    78, 78, 71, 73, 128, 78, 78, 71, 79, 128, 78, 79, 83, 69, 128, 78, 82, 
+    65, 80, 128, 78, 82, 65, 84, 128, 78, 82, 65, 88, 128, 78, 82, 69, 80, 
+    128, 78, 82, 69, 84, 128, 78, 82, 69, 88, 128, 78, 82, 79, 80, 128, 78, 
+    82, 79, 88, 128, 78, 82, 85, 80, 128, 78, 82, 85, 82, 128, 78, 82, 85, 
+    84, 128, 78, 82, 85, 88, 128, 78, 82, 89, 80, 128, 78, 82, 89, 82, 128, 
+    78, 82, 89, 84, 128, 78, 82, 89, 88, 128, 78, 85, 76, 76, 128, 78, 85, 
+    79, 80, 128, 78, 85, 82, 88, 128, 78, 85, 85, 78, 128, 78, 89, 65, 65, 
+    128, 78, 89, 67, 65, 128, 78, 89, 69, 69, 128, 78, 89, 69, 72, 128, 78, 
+    89, 73, 69, 128, 78, 89, 73, 84, 128, 78, 89, 73, 88, 128, 78, 89, 79, 
+    65, 128, 78, 89, 79, 84, 128, 78, 89, 79, 88, 128, 78, 89, 85, 79, 128, 
+    78, 89, 85, 80, 128, 78, 89, 85, 84, 128, 78, 89, 85, 88, 128, 78, 89, 
+    87, 65, 128, 78, 90, 65, 80, 128, 78, 90, 65, 84, 128, 78, 90, 65, 88, 
+    128, 78, 90, 69, 88, 128, 78, 90, 73, 69, 128, 78, 90, 73, 80, 128, 78, 
+    90, 73, 84, 128, 78, 90, 73, 88, 128, 78, 90, 79, 80, 128, 78, 90, 79, 
+    88, 128, 78, 90, 85, 79, 128, 78, 90, 85, 82, 128, 78, 90, 85, 88, 128, 
+    78, 90, 89, 80, 128, 78, 90, 89, 82, 128, 78, 90, 89, 84, 128, 78, 90, 
+    89, 88, 128, 79, 45, 69, 79, 128, 79, 45, 89, 69, 128, 79, 78, 83, 85, 
+    128, 79, 79, 77, 85, 128, 79, 79, 90, 69, 128, 79, 85, 78, 67, 197, 80, 
+    65, 65, 73, 128, 80, 65, 68, 77, 193, 80, 65, 82, 65, 128, 80, 69, 65, 
+    67, 197, 80, 69, 69, 80, 128, 80, 69, 78, 78, 217, 80, 69, 83, 79, 128, 
+    80, 72, 65, 65, 128, 80, 72, 65, 78, 128, 80, 72, 69, 69, 128, 80, 72, 
+    79, 65, 128, 80, 72, 87, 65, 128, 80, 73, 67, 75, 128, 80, 73, 69, 80, 
+    128, 80, 73, 69, 88, 128, 80, 73, 75, 79, 128, 80, 76, 79, 87, 128, 80, 
+    82, 65, 77, 128, 80, 82, 73, 78, 212, 80, 85, 79, 80, 128, 80, 85, 79, 
+    88, 128, 80, 85, 82, 88, 128, 80, 87, 69, 69, 128, 80, 89, 82, 88, 128, 
+    81, 65, 65, 70, 128, 81, 65, 65, 73, 128, 81, 65, 80, 72, 128, 81, 72, 
+    65, 65, 128, 81, 72, 69, 69, 128, 81, 72, 87, 65, 128, 81, 72, 87, 69, 
+    128, 81, 72, 87, 73, 128, 81, 73, 69, 80, 128, 81, 73, 69, 84, 128, 81, 
+    73, 69, 88, 128, 81, 79, 80, 65, 128, 81, 85, 79, 80, 128, 81, 85, 79, 
+    84, 128, 81, 85, 79, 88, 128, 81, 85, 82, 88, 128, 81, 85, 85, 86, 128, 
+    81, 87, 65, 65, 128, 81, 87, 69, 69, 128, 81, 89, 65, 65, 128, 81, 89, 
+    69, 69, 128, 81, 89, 82, 88, 128, 82, 65, 65, 73, 128, 82, 65, 73, 68, 
+    207, 82, 65, 78, 71, 197, 82, 69, 77, 85, 128, 82, 73, 67, 69, 128, 82, 
+    73, 69, 76, 128, 82, 73, 82, 65, 128, 82, 79, 65, 82, 128, 82, 82, 65, 
+    88, 128, 82, 82, 69, 72, 128, 82, 82, 69, 80, 128, 82, 82, 69, 84, 128, 
+    82, 82, 69, 88, 128, 82, 82, 79, 80, 128, 82, 82, 79, 84, 128, 82, 82, 
+    79, 88, 128, 82, 82, 85, 79, 128, 82, 82, 85, 80, 128, 82, 82, 85, 82, 
+    128, 82, 82, 85, 84, 128, 82, 82, 85, 88, 128, 82, 82, 89, 80, 128, 82, 
+    82, 89, 82, 128, 82, 82, 89, 84, 128, 82, 82, 89, 88, 128, 82, 85, 73, 
+    83, 128, 82, 85, 76, 69, 128, 82, 85, 79, 80, 128, 82, 85, 83, 73, 128, 
+    83, 65, 45, 73, 128, 83, 65, 65, 73, 128, 83, 65, 68, 69, 128, 83, 65, 
+    73, 76, 128, 83, 65, 76, 65, 128, 83, 65, 76, 65, 205, 83, 66, 82, 85, 
+    204, 83, 67, 87, 65, 128, 83, 68, 79, 78, 199, 83, 72, 65, 80, 128, 83, 
+    72, 65, 88, 128, 83, 72, 69, 80, 128, 83, 72, 69, 84, 128, 83, 72, 69, 
+    88, 128, 83, 72, 73, 73, 128, 83, 72, 73, 77, 193, 83, 72, 79, 65, 128, 
+    83, 72, 79, 79, 128, 83, 72, 79, 84, 128, 83, 72, 79, 88, 128, 83, 72, 
+    85, 79, 128, 83, 72, 85, 80, 128, 83, 72, 85, 84, 128, 83, 72, 85, 88, 
+    128, 83, 72, 89, 80, 128, 83, 72, 89, 82, 128, 83, 72, 89, 84, 128, 83, 
+    72, 89, 88, 128, 83, 73, 71, 69, 204, 83, 73, 88, 84, 217, 83, 75, 73, 
+    78, 128, 83, 75, 85, 76, 204, 83, 75, 87, 65, 128, 83, 78, 65, 75, 197, 
+    83, 80, 79, 84, 128, 83, 80, 87, 65, 128, 83, 83, 65, 65, 128, 83, 83, 
+    65, 80, 128, 83, 83, 65, 84, 128, 83, 83, 65, 88, 128, 83, 83, 69, 69, 
+    128, 83, 83, 69, 80, 128, 83, 83, 69, 88, 128, 83, 83, 73, 69, 128, 83, 
+    83, 73, 80, 128, 83, 83, 73, 84, 128, 83, 83, 73, 88, 128, 83, 83, 79, 
+    80, 128, 83, 83, 79, 84, 128, 83, 83, 79, 88, 128, 83, 83, 85, 80, 128, 
+    83, 83, 85, 84, 128, 83, 83, 85, 88, 128, 83, 83, 89, 80, 128, 83, 83, 
+    89, 82, 128, 83, 83, 89, 84, 128, 83, 83, 89, 88, 128, 83, 84, 65, 78, 
+    128, 83, 84, 69, 80, 128, 83, 84, 73, 76, 197, 83, 84, 73, 76, 204, 83, 
+    84, 87, 65, 128, 83, 85, 79, 80, 128, 83, 85, 79, 88, 128, 83, 85, 82, 
+    88, 128, 83, 87, 85, 78, 199, 83, 90, 65, 65, 128, 83, 90, 69, 69, 128, 
+    83, 90, 87, 65, 128, 83, 90, 87, 71, 128, 84, 65, 65, 73, 128, 84, 65, 
+    75, 69, 128, 84, 65, 76, 76, 128, 84, 69, 45, 85, 128, 84, 69, 78, 84, 
+    128, 84, 69, 84, 72, 128, 84, 72, 69, 72, 128, 84, 72, 69, 77, 193, 84, 
+    72, 69, 89, 128, 84, 72, 79, 65, 128, 84, 72, 85, 82, 211, 84, 72, 87, 
+    65, 128, 84, 73, 69, 80, 128, 84, 73, 69, 88, 128, 84, 73, 71, 72, 212, 
+    84, 73, 78, 89, 128, 84, 73, 87, 65, 218, 84, 76, 69, 69, 128, 84, 76, 
+    72, 85, 128, 84, 79, 84, 65, 204, 84, 82, 65, 68, 197, 84, 82, 73, 79, 
+    206, 84, 83, 65, 65, 128, 84, 83, 65, 68, 201, 84, 83, 87, 65, 128, 84, 
+    84, 65, 65, 128, 84, 84, 69, 69, 128, 84, 84, 69, 72, 128, 84, 84, 72, 
+    69, 128, 84, 84, 72, 73, 128, 84, 84, 83, 65, 128, 84, 84, 83, 69, 128, 
+    84, 84, 83, 73, 128, 84, 84, 83, 79, 128, 84, 84, 83, 85, 128, 84, 85, 
+    79, 80, 128, 84, 85, 79, 84, 128, 84, 85, 79, 88, 128, 84, 85, 82, 88, 
+    128, 84, 90, 65, 65, 128, 84, 90, 69, 69, 128, 84, 90, 79, 65, 128, 85, 
+    45, 65, 69, 128, 85, 65, 84, 72, 128, 86, 73, 69, 80, 128, 86, 73, 69, 
+    84, 128, 86, 73, 69, 88, 128, 86, 85, 82, 88, 128, 86, 89, 82, 88, 128, 
+    87, 65, 69, 78, 128, 87, 65, 76, 76, 128, 87, 69, 76, 76, 128, 87, 69, 
+    83, 84, 128, 87, 79, 82, 75, 128, 87, 82, 65, 80, 128, 87, 85, 78, 74, 
+    207, 87, 85, 79, 80, 128, 87, 85, 79, 88, 128, 88, 73, 82, 79, 206, 88, 
+    89, 65, 65, 128, 88, 89, 69, 69, 128, 88, 89, 82, 88, 128, 89, 65, 45, 
+    79, 128, 89, 65, 65, 73, 128, 89, 65, 66, 72, 128, 89, 65, 67, 72, 128, 
+    89, 65, 68, 68, 128, 89, 65, 68, 72, 128, 89, 65, 71, 78, 128, 89, 65, 
+    72, 72, 128, 89, 65, 82, 82, 128, 89, 65, 83, 72, 128, 89, 65, 83, 83, 
+    128, 89, 65, 84, 72, 128, 89, 65, 84, 84, 128, 89, 65, 90, 90, 128, 89, 
+    69, 82, 65, 200, 89, 73, 45, 85, 128, 89, 73, 78, 71, 128, 89, 79, 45, 
+    79, 128, 89, 79, 77, 79, 128, 89, 79, 82, 73, 128, 89, 85, 45, 65, 128, 
+    89, 85, 45, 69, 128, 89, 85, 45, 85, 128, 89, 85, 65, 78, 128, 89, 85, 
+    68, 72, 128, 89, 85, 79, 84, 128, 89, 85, 82, 88, 128, 89, 89, 82, 88, 
+    128, 90, 65, 89, 73, 206, 90, 72, 65, 65, 128, 90, 72, 65, 80, 128, 90, 
+    72, 65, 84, 128, 90, 72, 65, 88, 128, 90, 72, 69, 80, 128, 90, 72, 69, 
+    84, 128, 90, 72, 69, 88, 128, 90, 72, 79, 80, 128, 90, 72, 79, 84, 128, 
+    90, 72, 79, 88, 128, 90, 72, 85, 79, 128, 90, 72, 85, 80, 128, 90, 72, 
+    85, 82, 128, 90, 72, 85, 84, 128, 90, 72, 85, 88, 128, 90, 72, 87, 65, 
+    128, 90, 72, 89, 80, 128, 90, 72, 89, 82, 128, 90, 72, 89, 84, 128, 90, 
+    72, 89, 88, 128, 90, 85, 79, 80, 128, 90, 90, 65, 65, 128, 90, 90, 65, 
+    80, 128, 90, 90, 65, 84, 128, 90, 90, 65, 88, 128, 90, 90, 69, 69, 128, 
+    90, 90, 69, 80, 128, 90, 90, 69, 88, 128, 90, 90, 73, 69, 128, 90, 90, 
+    73, 80, 128, 90, 90, 73, 84, 128, 90, 90, 73, 88, 128, 90, 90, 79, 80, 
+    128, 90, 90, 79, 88, 128, 90, 90, 85, 80, 128, 90, 90, 85, 82, 128, 90, 
+    90, 85, 88, 128, 90, 90, 89, 80, 128, 90, 90, 89, 82, 128, 90, 90, 89, 
+    84, 128, 90, 90, 89, 88, 128, 79, 80, 69, 206, 70, 85, 76, 204, 83, 69, 
+    69, 206, 73, 79, 84, 193, 69, 65, 83, 212, 70, 82, 79, 205, 84, 79, 68, 
+    207, 70, 73, 86, 197, 72, 79, 85, 210, 84, 69, 78, 128, 83, 73, 66, 197, 
+    70, 79, 85, 210, 79, 86, 69, 210, 72, 79, 82, 206, 81, 85, 65, 196, 68, 
+    65, 83, 200, 78, 69, 79, 128, 80, 72, 73, 128, 80, 83, 73, 128, 84, 72, 
+    69, 200, 75, 79, 77, 201, 82, 72, 79, 128, 89, 85, 83, 128, 71, 72, 65, 
+    128, 79, 88, 73, 193, 82, 79, 67, 128, 66, 72, 65, 128, 83, 65, 82, 193, 
+    84, 65, 67, 203, 84, 65, 85, 128, 68, 79, 69, 211, 74, 72, 65, 128, 82, 
+    82, 65, 128, 87, 73, 68, 197, 82, 68, 69, 204, 83, 72, 73, 206, 87, 65, 
+    86, 217, 90, 65, 73, 206, 68, 73, 71, 193, 83, 72, 79, 128, 65, 82, 67, 
+    128, 75, 65, 70, 128, 76, 69, 71, 128, 83, 84, 79, 208, 84, 65, 77, 128, 
+    89, 65, 78, 199, 68, 90, 69, 128, 71, 72, 69, 128, 71, 79, 65, 204, 71, 
+    84, 69, 210, 78, 85, 78, 128, 78, 89, 79, 128, 83, 84, 65, 210, 83, 85, 
+    78, 128, 84, 65, 73, 204, 87, 65, 86, 197, 87, 65, 87, 128, 87, 79, 82, 
+    196, 90, 69, 82, 207, 65, 80, 76, 201, 66, 69, 69, 200, 67, 76, 69, 198, 
+    68, 74, 69, 128, 68, 75, 65, 210, 68, 89, 69, 200, 68, 90, 65, 128, 69, 
+    73, 69, 128, 70, 69, 72, 128, 70, 73, 83, 200, 71, 65, 78, 128, 71, 85, 
+    69, 200, 72, 73, 69, 128, 75, 83, 73, 128, 76, 65, 77, 197, 76, 74, 69, 
+    128, 77, 69, 77, 128, 77, 71, 79, 128, 77, 85, 67, 200, 77, 87, 65, 128, 
+    78, 65, 77, 197, 78, 65, 82, 128, 78, 74, 69, 128, 78, 79, 87, 128, 78, 
+    87, 65, 128, 78, 89, 69, 200, 78, 89, 73, 128, 79, 79, 85, 128, 80, 69, 
+    69, 128, 82, 65, 65, 128, 84, 72, 69, 206, 84, 73, 67, 203, 84, 84, 69, 
+    200, 89, 79, 68, 128, 66, 65, 83, 197, 66, 69, 69, 128, 66, 79, 87, 128, 
+    66, 90, 72, 201, 67, 79, 87, 128, 68, 79, 78, 128, 70, 76, 65, 212, 70, 
+    82, 69, 197, 72, 65, 69, 128, 74, 73, 76, 128, 75, 69, 72, 128, 75, 72, 
+    73, 128, 75, 72, 79, 128, 75, 87, 69, 128, 75, 87, 73, 128, 76, 65, 83, 
+    128, 76, 79, 79, 128, 76, 87, 65, 128, 77, 69, 78, 128, 77, 87, 69, 128, 
+    77, 87, 73, 128, 78, 65, 65, 128, 78, 89, 73, 211, 80, 65, 82, 128, 80, 
+    69, 72, 128, 80, 72, 79, 128, 80, 87, 69, 128, 80, 87, 73, 128, 81, 65, 
+    65, 128, 81, 65, 82, 128, 82, 65, 69, 128, 82, 72, 65, 128, 83, 72, 79, 
+    197, 83, 72, 85, 128, 83, 83, 73, 128, 83, 83, 79, 128, 83, 83, 85, 128, 
+    84, 72, 65, 204, 84, 79, 79, 128, 84, 87, 69, 128, 86, 69, 69, 128, 86, 
+    73, 78, 128, 87, 65, 69, 128, 87, 65, 76, 203, 87, 69, 79, 128, 88, 65, 
+    78, 128, 88, 69, 72, 128, 89, 65, 75, 128, 89, 65, 84, 128, 89, 89, 65, 
+    128, 90, 69, 78, 128, 65, 76, 76, 201, 65, 89, 66, 128, 65, 90, 85, 128, 
+    66, 65, 65, 128, 66, 69, 72, 128, 66, 69, 78, 128, 66, 79, 76, 212, 66, 
+    87, 65, 128, 67, 73, 80, 128, 67, 76, 85, 194, 67, 79, 79, 128, 67, 85, 
+    80, 128, 67, 87, 69, 128, 67, 87, 73, 128, 67, 87, 79, 128, 67, 89, 80, 
+    128, 67, 89, 84, 128, 68, 68, 65, 204, 68, 68, 69, 128, 68, 68, 73, 128, 
+    68, 68, 85, 128, 68, 69, 73, 128, 68, 74, 65, 128, 68, 76, 65, 128, 68, 
+    79, 71, 128, 68, 82, 85, 205, 69, 87, 69, 128, 70, 65, 65, 128, 70, 69, 
+    69, 128, 70, 69, 73, 128, 70, 76, 89, 128, 70, 85, 82, 128, 70, 85, 83, 
+    193, 70, 87, 65, 128, 71, 65, 89, 128, 71, 71, 65, 128, 71, 71, 69, 128, 
+    71, 71, 73, 128, 71, 71, 79, 128, 71, 71, 85, 128, 71, 72, 79, 128, 71, 
+    73, 77, 128, 71, 74, 69, 128, 72, 65, 82, 196, 72, 77, 79, 128, 72, 78, 
+    65, 128, 73, 83, 79, 206, 74, 74, 73, 128, 74, 74, 79, 128, 74, 74, 85, 
+    128, 74, 74, 89, 128, 75, 65, 73, 128, 75, 69, 78, 128, 75, 72, 69, 128, 
+    75, 73, 84, 128, 75, 74, 69, 128, 75, 75, 65, 128, 75, 79, 79, 128, 75, 
+    86, 65, 128, 75, 87, 79, 128, 76, 65, 65, 128, 76, 87, 69, 128, 76, 87, 
+    73, 128, 76, 87, 79, 128, 77, 65, 65, 128, 77, 79, 79, 128, 77, 79, 79, 
+    206, 77, 80, 65, 128, 77, 87, 79, 128, 78, 69, 69, 128, 78, 71, 65, 211, 
+    78, 73, 66, 128, 78, 79, 79, 128, 78, 82, 65, 128, 78, 87, 69, 128, 78, 
+    89, 85, 128, 79, 72, 77, 128, 79, 73, 76, 128, 79, 75, 84, 207, 79, 78, 
+    78, 128, 79, 84, 85, 128, 80, 65, 65, 128, 80, 65, 82, 212, 80, 65, 84, 
+    200, 80, 72, 85, 210, 80, 79, 76, 201, 80, 79, 79, 128, 80, 85, 84, 128, 
+    80, 87, 79, 128, 80, 89, 84, 128, 81, 65, 73, 128, 81, 73, 73, 128, 81, 
+    79, 84, 128, 81, 85, 79, 128, 81, 85, 85, 128, 82, 71, 89, 193, 82, 78, 
+    65, 205, 82, 82, 69, 200, 82, 82, 79, 128, 83, 69, 72, 128, 83, 72, 65, 
+    196, 83, 72, 79, 199, 83, 72, 89, 128, 83, 73, 79, 211, 83, 74, 69, 128, 
+    83, 79, 79, 128, 83, 79, 85, 128, 83, 83, 69, 128, 83, 87, 69, 128, 83, 
+    87, 73, 128, 83, 87, 79, 128, 84, 65, 71, 128, 84, 65, 84, 128, 84, 65, 
+    86, 128, 84, 69, 84, 128, 84, 74, 69, 128, 84, 76, 65, 128, 84, 76, 73, 
+    128, 84, 76, 85, 128, 84, 79, 84, 128, 84, 82, 69, 197, 84, 84, 73, 128, 
+    84, 87, 73, 128, 85, 83, 69, 196, 86, 65, 86, 128, 86, 69, 80, 128, 86, 
+    69, 82, 217, 86, 69, 87, 128, 86, 79, 85, 128, 86, 85, 82, 128, 87, 65, 
+    85, 128, 88, 86, 65, 128, 89, 65, 74, 128, 89, 65, 81, 128, 89, 65, 90, 
+    128, 89, 69, 65, 210, 89, 69, 82, 213, 89, 70, 69, 206, 89, 79, 79, 128, 
+    89, 87, 69, 128, 89, 87, 73, 128, 89, 87, 79, 128, 90, 72, 73, 128, 90, 
+    72, 79, 128, 90, 72, 85, 128, 90, 79, 84, 128, 90, 90, 65, 128, 90, 90, 
+    69, 128, 90, 90, 73, 128, 90, 90, 85, 128, 65, 65, 89, 128, 65, 68, 65, 
+    203, 65, 77, 66, 193, 65, 82, 67, 200, 65, 84, 79, 205, 65, 85, 69, 128, 
+    65, 87, 69, 128, 65, 88, 69, 128, 65, 89, 69, 210, 66, 48, 48, 177, 66, 
+    48, 48, 178, 66, 48, 48, 179, 66, 48, 48, 180, 66, 48, 48, 181, 66, 48, 
+    48, 182, 66, 48, 48, 183, 66, 48, 48, 184, 66, 48, 48, 185, 66, 48, 49, 
+    176, 66, 48, 49, 177, 66, 48, 49, 178, 66, 48, 49, 179, 66, 48, 49, 180, 
+    66, 48, 49, 181, 66, 48, 49, 182, 66, 48, 49, 183, 66, 48, 50, 176, 66, 
+    48, 50, 177, 66, 48, 50, 179, 66, 48, 50, 180, 66, 48, 50, 181, 66, 48, 
+    50, 182, 66, 48, 50, 183, 66, 48, 50, 184, 66, 48, 50, 185, 66, 48, 51, 
+    176, 66, 48, 51, 177, 66, 48, 51, 178, 66, 48, 51, 179, 66, 48, 51, 182, 
+    66, 48, 51, 183, 66, 48, 51, 184, 66, 48, 51, 185, 66, 48, 52, 176, 66, 
+    48, 52, 177, 66, 48, 52, 178, 66, 48, 52, 179, 66, 48, 52, 180, 66, 48, 
+    52, 181, 66, 48, 52, 182, 66, 48, 52, 184, 66, 48, 53, 176, 66, 48, 53, 
+    177, 66, 48, 53, 178, 66, 48, 53, 179, 66, 48, 53, 180, 66, 48, 53, 181, 
+    66, 48, 53, 183, 66, 48, 53, 184, 66, 48, 53, 185, 66, 48, 54, 176, 66, 
+    48, 54, 177, 66, 48, 54, 178, 66, 48, 54, 181, 66, 48, 54, 182, 66, 48, 
+    54, 183, 66, 48, 54, 184, 66, 48, 54, 185, 66, 48, 55, 176, 66, 48, 55, 
+    177, 66, 48, 55, 178, 66, 48, 55, 179, 66, 48, 55, 180, 66, 48, 55, 181, 
+    66, 48, 55, 182, 66, 48, 55, 183, 66, 48, 55, 184, 66, 48, 56, 176, 66, 
+    48, 56, 177, 66, 48, 56, 181, 66, 48, 56, 183, 66, 48, 57, 176, 66, 48, 
+    57, 177, 66, 49, 48, 176, 66, 49, 48, 178, 66, 49, 48, 180, 66, 49, 48, 
+    181, 66, 49, 50, 176, 66, 49, 50, 177, 66, 49, 50, 178, 66, 49, 50, 179, 
+    66, 49, 50, 181, 66, 49, 50, 183, 66, 49, 50, 184, 66, 49, 51, 176, 66, 
+    49, 51, 177, 66, 49, 51, 179, 66, 49, 51, 181, 66, 49, 52, 176, 66, 49, 
+    52, 177, 66, 49, 52, 181, 66, 49, 53, 177, 66, 49, 53, 182, 66, 49, 53, 
+    185, 66, 49, 54, 178, 66, 49, 54, 179, 66, 49, 55, 179, 66, 49, 55, 182, 
+    66, 49, 57, 177, 66, 50, 50, 176, 66, 50, 50, 181, 66, 50, 51, 176, 66, 
+    50, 51, 177, 66, 50, 51, 179, 66, 50, 52, 176, 66, 50, 52, 177, 66, 50, 
+    52, 178, 66, 50, 52, 179, 66, 50, 52, 183, 66, 50, 53, 180, 66, 65, 78, 
+    203, 66, 66, 65, 128, 66, 66, 69, 128, 66, 66, 73, 128, 66, 66, 79, 128, 
+    66, 66, 85, 128, 66, 66, 89, 128, 66, 67, 65, 196, 66, 69, 76, 204, 66, 
+    69, 76, 212, 66, 69, 84, 128, 66, 69, 84, 193, 66, 72, 79, 128, 66, 73, 
+    66, 128, 66, 73, 71, 128, 66, 75, 65, 173, 66, 79, 65, 128, 66, 87, 69, 
+    128, 66, 87, 73, 128, 66, 88, 71, 128, 67, 65, 68, 193, 67, 65, 78, 199, 
+    67, 65, 82, 197, 67, 65, 84, 128, 67, 65, 88, 128, 67, 67, 65, 128, 67, 
+    67, 69, 128, 67, 67, 73, 128, 67, 67, 79, 128, 67, 67, 85, 128, 67, 69, 
+    68, 201, 67, 69, 78, 128, 67, 69, 80, 128, 67, 69, 88, 128, 67, 72, 65, 
+    196, 67, 72, 69, 206, 67, 73, 69, 128, 67, 73, 73, 128, 67, 73, 84, 128, 
+    67, 73, 88, 128, 67, 79, 65, 128, 67, 79, 80, 128, 67, 79, 84, 128, 67, 
+    79, 88, 128, 67, 85, 66, 197, 67, 85, 79, 128, 67, 85, 82, 128, 67, 85, 
+    84, 128, 67, 85, 88, 128, 67, 89, 65, 128, 67, 89, 82, 128, 67, 89, 88, 
+    128, 68, 65, 68, 128, 68, 65, 69, 199, 68, 65, 77, 208, 68, 65, 82, 203, 
+    68, 65, 84, 197, 68, 69, 75, 128, 68, 69, 90, 200, 68, 76, 73, 128, 68, 
+    76, 79, 128, 68, 76, 85, 128, 68, 82, 73, 204, 68, 82, 89, 128, 68, 85, 
+    76, 128, 68, 87, 69, 128, 68, 87, 79, 128, 68, 89, 79, 128, 68, 90, 73, 
+    128, 68, 90, 79, 128, 68, 90, 85, 128, 69, 71, 71, 128, 69, 73, 83, 128, 
+    69, 75, 83, 128, 69, 78, 78, 128, 69, 78, 79, 211, 69, 79, 72, 128, 69, 
+    82, 71, 128, 69, 82, 82, 128, 69, 85, 82, 207, 69, 88, 79, 128, 70, 65, 
+    78, 128, 70, 65, 80, 128, 70, 65, 88, 128, 70, 69, 69, 196, 70, 69, 72, 
+    213, 70, 69, 78, 199, 70, 69, 79, 200, 70, 70, 73, 128, 70, 70, 76, 128, 
+    70, 73, 73, 128, 70, 73, 76, 197, 70, 73, 76, 204, 70, 73, 80, 128, 70, 
+    73, 84, 128, 70, 73, 88, 128, 70, 79, 79, 128, 70, 79, 80, 128, 70, 79, 
+    88, 128, 70, 85, 80, 128, 70, 85, 84, 128, 70, 85, 88, 128, 70, 87, 69, 
+    128, 70, 87, 73, 128, 70, 89, 65, 128, 70, 89, 80, 128, 70, 89, 84, 128, 
+    70, 89, 88, 128, 71, 65, 70, 128, 71, 65, 71, 128, 71, 65, 76, 128, 71, 
+    65, 82, 128, 71, 67, 65, 206, 71, 69, 66, 207, 71, 69, 84, 193, 71, 72, 
+    73, 128, 71, 72, 85, 128, 71, 72, 90, 128, 71, 73, 80, 128, 71, 79, 65, 
+    128, 71, 80, 65, 128, 71, 83, 85, 205, 71, 89, 65, 128, 71, 89, 69, 128, 
+    71, 89, 70, 213, 71, 89, 73, 128, 71, 89, 79, 128, 71, 89, 85, 128, 72, 
+    69, 76, 205, 72, 69, 78, 199, 72, 72, 69, 128, 72, 72, 73, 128, 72, 72, 
+    79, 128, 72, 72, 85, 128, 72, 76, 65, 128, 72, 76, 69, 128, 72, 76, 73, 
+    128, 72, 76, 79, 128, 72, 76, 85, 128, 72, 76, 89, 128, 72, 77, 73, 128, 
+    72, 77, 85, 128, 72, 77, 89, 128, 72, 78, 69, 128, 72, 78, 73, 128, 72, 
+    80, 65, 128, 72, 87, 85, 128, 72, 88, 65, 128, 72, 88, 69, 128, 72, 88, 
+    73, 128, 72, 88, 79, 128, 72, 90, 71, 128, 72, 90, 84, 128, 72, 90, 87, 
+    128, 72, 90, 90, 128, 73, 45, 65, 128, 73, 45, 79, 128, 73, 79, 82, 128, 
+    74, 65, 65, 128, 74, 65, 82, 128, 74, 69, 72, 128, 74, 69, 82, 128, 74, 
+    72, 79, 128, 74, 73, 65, 128, 74, 74, 65, 128, 74, 74, 69, 128, 74, 79, 
+    65, 128, 74, 79, 89, 128, 74, 87, 65, 128, 75, 65, 72, 128, 75, 65, 80, 
+    128, 75, 65, 85, 206, 75, 65, 88, 128, 75, 69, 80, 128, 75, 69, 88, 128, 
+    75, 69, 89, 128, 75, 72, 90, 128, 75, 73, 69, 128, 75, 73, 72, 128, 75, 
+    73, 73, 128, 75, 73, 80, 128, 75, 73, 88, 128, 75, 75, 69, 128, 75, 75, 
+    73, 128, 75, 75, 79, 128, 75, 75, 85, 128, 75, 79, 65, 128, 75, 79, 72, 
+    128, 75, 79, 80, 128, 75, 79, 84, 128, 75, 79, 88, 128, 75, 80, 65, 128, 
+    75, 82, 65, 128, 75, 85, 79, 128, 75, 85, 80, 128, 75, 85, 82, 128, 75, 
+    85, 84, 128, 75, 85, 88, 128, 75, 88, 65, 128, 75, 88, 69, 128, 75, 88, 
+    73, 128, 75, 88, 79, 128, 75, 88, 85, 128, 75, 89, 65, 128, 75, 89, 69, 
+    128, 75, 89, 73, 128, 75, 89, 79, 128, 75, 89, 85, 128, 76, 65, 69, 128, 
+    76, 65, 71, 213, 76, 65, 83, 212, 76, 65, 90, 217, 76, 69, 79, 128, 76, 
+    72, 65, 199, 76, 73, 68, 128, 76, 73, 73, 128, 76, 73, 78, 203, 76, 73, 
+    82, 193, 76, 79, 65, 128, 76, 79, 71, 128, 76, 79, 71, 210, 76, 79, 84, 
+    128, 76, 89, 89, 128, 77, 65, 83, 213, 77, 65, 89, 128, 77, 67, 72, 213, 
+    77, 68, 85, 206, 77, 69, 84, 193, 77, 69, 88, 128, 77, 71, 65, 128, 77, 
+    71, 69, 128, 77, 71, 85, 128, 77, 72, 90, 128, 77, 73, 73, 128, 77, 73, 
+    76, 128, 77, 73, 76, 204, 77, 73, 77, 128, 77, 79, 65, 128, 77, 79, 76, 
+    128, 77, 89, 65, 128, 77, 89, 84, 128, 78, 65, 71, 128, 78, 65, 79, 211, 
+    78, 66, 65, 128, 78, 66, 73, 128, 78, 66, 79, 128, 78, 66, 85, 128, 78, 
+    66, 89, 128, 78, 68, 69, 128, 78, 69, 78, 128, 78, 69, 84, 128, 78, 69, 
+    88, 212, 78, 71, 71, 128, 78, 74, 73, 128, 78, 74, 79, 128, 78, 74, 85, 
+    128, 78, 74, 89, 128, 78, 78, 71, 128, 78, 78, 79, 128, 78, 79, 65, 128, 
+    78, 82, 69, 128, 78, 82, 79, 128, 78, 82, 85, 128, 78, 82, 89, 128, 78, 
+    85, 76, 204, 78, 85, 80, 128, 78, 85, 82, 128, 78, 85, 88, 128, 78, 89, 
+    69, 128, 78, 90, 65, 128, 78, 90, 73, 128, 78, 90, 85, 128, 78, 90, 89, 
+    128, 79, 45, 69, 128, 79, 65, 75, 128, 79, 65, 89, 128, 79, 66, 79, 204, 
+    80, 65, 80, 128, 80, 65, 84, 128, 80, 65, 88, 128, 80, 72, 85, 128, 80, 
+    73, 69, 128, 80, 73, 71, 128, 80, 73, 80, 128, 80, 73, 84, 128, 80, 73, 
+    88, 128, 80, 76, 65, 128, 80, 79, 65, 128, 80, 79, 80, 128, 80, 79, 88, 
+    128, 80, 80, 77, 128, 80, 85, 50, 128, 80, 85, 79, 128, 80, 85, 80, 128, 
+    80, 85, 82, 128, 80, 85, 88, 128, 80, 89, 80, 128, 80, 89, 82, 128, 80, 
+    89, 88, 128, 81, 65, 76, 193, 81, 65, 81, 128, 81, 65, 85, 128, 81, 69, 
+    69, 128, 81, 72, 65, 128, 81, 72, 69, 128, 81, 72, 73, 128, 81, 72, 79, 
+    128, 81, 72, 85, 128, 81, 73, 69, 128, 81, 73, 80, 128, 81, 73, 84, 128, 
+    81, 73, 88, 128, 81, 79, 65, 128, 81, 79, 70, 128, 81, 79, 79, 128, 81, 
+    79, 80, 128, 81, 79, 88, 128, 81, 85, 65, 128, 81, 85, 69, 128, 81, 85, 
+    73, 128, 81, 85, 75, 128, 81, 85, 80, 128, 81, 85, 82, 128, 81, 85, 84, 
+    128, 81, 85, 86, 128, 81, 85, 88, 128, 81, 87, 65, 128, 81, 87, 69, 128, 
+    81, 87, 73, 128, 81, 89, 65, 128, 81, 89, 69, 128, 81, 89, 73, 128, 81, 
+    89, 79, 128, 81, 89, 80, 128, 81, 89, 82, 128, 81, 89, 84, 128, 81, 89, 
+    85, 128, 81, 89, 88, 128, 82, 65, 50, 128, 82, 65, 51, 128, 82, 65, 68, 
+    128, 82, 65, 68, 201, 82, 65, 73, 206, 82, 65, 77, 211, 82, 69, 73, 196, 
+    82, 73, 80, 128, 82, 74, 69, 128, 82, 74, 69, 211, 82, 79, 65, 128, 82, 
+    79, 79, 128, 82, 82, 69, 128, 82, 82, 85, 128, 82, 82, 89, 128, 82, 85, 
+    65, 128, 82, 85, 78, 128, 82, 87, 65, 128, 82, 89, 65, 128, 82, 89, 89, 
+    128, 83, 45, 87, 128, 83, 65, 68, 128, 83, 65, 89, 128, 83, 66, 85, 194, 
+    83, 71, 65, 194, 83, 71, 79, 210, 83, 71, 82, 193, 83, 73, 73, 128, 83, 
+    73, 78, 197, 83, 75, 87, 128, 83, 78, 65, 208, 83, 79, 65, 128, 83, 79, 
+    87, 128, 83, 83, 89, 128, 83, 85, 65, 128, 83, 85, 79, 128, 83, 85, 82, 
+    128, 83, 90, 65, 128, 83, 90, 69, 128, 83, 90, 73, 128, 83, 90, 79, 128, 
+    83, 90, 85, 128, 84, 65, 50, 128, 84, 65, 79, 128, 84, 65, 80, 128, 84, 
+    65, 80, 197, 84, 65, 87, 128, 84, 65, 88, 128, 84, 69, 83, 200, 84, 69, 
+    84, 200, 84, 69, 88, 128, 84, 72, 69, 211, 84, 72, 73, 206, 84, 72, 90, 
+    128, 84, 73, 73, 128, 84, 73, 80, 128, 84, 73, 84, 128, 84, 73, 88, 128, 
+    84, 76, 86, 128, 84, 79, 65, 128, 84, 79, 88, 128, 84, 82, 73, 128, 84, 
+    83, 86, 128, 84, 84, 72, 128, 84, 84, 85, 128, 84, 85, 79, 128, 84, 85, 
+    80, 128, 84, 85, 82, 128, 84, 85, 84, 128, 84, 85, 88, 128, 84, 89, 65, 
+    128, 84, 89, 69, 128, 84, 89, 73, 128, 84, 89, 79, 128, 84, 90, 65, 128, 
+    84, 90, 69, 128, 84, 90, 73, 128, 84, 90, 79, 128, 84, 90, 85, 128, 85, 
+    69, 69, 128, 85, 69, 89, 128, 85, 78, 68, 207, 85, 78, 73, 212, 85, 82, 
+    85, 218, 86, 65, 65, 128, 86, 65, 80, 128, 86, 65, 84, 128, 86, 65, 88, 
+    128, 86, 69, 72, 128, 86, 69, 88, 128, 86, 73, 69, 128, 86, 73, 80, 128, 
+    86, 73, 84, 128, 86, 73, 88, 128, 86, 79, 73, 196, 86, 79, 80, 128, 86, 
+    79, 84, 128, 86, 79, 87, 128, 86, 79, 88, 128, 86, 85, 80, 128, 86, 85, 
+    84, 128, 86, 85, 88, 128, 86, 87, 65, 128, 86, 89, 80, 128, 86, 89, 82, 
+    128, 86, 89, 84, 128, 86, 89, 88, 128, 87, 65, 80, 128, 87, 65, 84, 128, 
+    87, 65, 88, 128, 87, 69, 80, 128, 87, 69, 88, 128, 87, 79, 65, 128, 87, 
+    79, 69, 128, 87, 79, 80, 128, 87, 79, 82, 203, 87, 79, 88, 128, 87, 85, 
+    79, 128, 87, 89, 78, 206, 88, 79, 65, 128, 88, 79, 82, 128, 88, 89, 65, 
+    128, 88, 89, 69, 128, 88, 89, 73, 128, 88, 89, 79, 128, 88, 89, 80, 128, 
+    88, 89, 82, 128, 88, 89, 84, 128, 88, 89, 85, 128, 88, 89, 88, 128, 89, 
+    65, 66, 128, 89, 65, 68, 128, 89, 65, 70, 128, 89, 65, 71, 128, 89, 65, 
+    77, 128, 89, 65, 80, 128, 89, 65, 82, 128, 89, 65, 86, 128, 89, 65, 87, 
+    128, 89, 65, 89, 128, 89, 69, 65, 128, 89, 69, 87, 128, 89, 69, 89, 128, 
+    89, 73, 73, 128, 89, 85, 68, 200, 89, 85, 82, 128, 89, 89, 80, 128, 89, 
+    89, 82, 128, 89, 89, 84, 128, 89, 89, 88, 128, 90, 65, 72, 128, 90, 72, 
+    89, 128, 90, 76, 65, 128, 90, 79, 79, 128, 90, 82, 65, 128, 90, 85, 84, 
+    128, 90, 90, 89, 128, 75, 65, 198, 66, 69, 200, 68, 65, 217, 84, 72, 197, 
+    70, 69, 200, 68, 65, 196, 83, 65, 196, 69, 78, 196, 81, 65, 198, 84, 65, 
+    200, 65, 82, 195, 78, 79, 210, 76, 69, 203, 77, 65, 201, 79, 67, 210, 66, 
+    73, 199, 82, 72, 207, 84, 69, 206, 87, 65, 215, 89, 73, 199, 67, 72, 197, 
+    77, 71, 207, 65, 82, 205, 66, 85, 212, 67, 85, 205, 71, 72, 197, 78, 69, 
+    207, 80, 85, 128, 84, 73, 208, 71, 65, 198, 75, 72, 207, 90, 65, 200, 68, 
+    73, 197, 80, 72, 201, 90, 72, 197, 80, 72, 207, 81, 73, 128, 81, 85, 128, 
+    83, 73, 216, 67, 72, 207, 77, 69, 206, 77, 73, 196, 78, 69, 212, 80, 69, 
+    200, 81, 79, 128, 86, 69, 200, 89, 79, 196, 66, 65, 199, 66, 69, 212, 68, 
+    89, 207, 70, 79, 128, 72, 65, 193, 75, 65, 201, 78, 65, 199, 81, 69, 128, 
+    82, 65, 196, 83, 73, 206, 86, 65, 214, 45, 85, 205, 67, 72, 201, 68, 65, 
+    208, 68, 85, 204, 68, 90, 128, 69, 88, 207, 71, 82, 213, 71, 85, 199, 72, 
+    79, 212, 72, 80, 128, 72, 86, 128, 73, 74, 128, 73, 85, 128, 73, 89, 128, 
+    74, 69, 200, 74, 79, 212, 75, 69, 217, 75, 71, 128, 75, 75, 128, 76, 74, 
+    128, 77, 73, 199, 78, 74, 128, 78, 85, 206, 78, 86, 128, 78, 89, 201, 79, 
+    72, 205, 80, 65, 215, 81, 79, 207, 82, 68, 207, 83, 85, 206, 83, 87, 128, 
+    87, 79, 206, 89, 69, 206, 89, 85, 211, 65, 78, 207, 66, 69, 206, 66, 79, 
+    215, 66, 81, 128, 67, 77, 128, 67, 85, 212, 68, 76, 128, 68, 77, 128, 68, 
+    82, 217, 68, 86, 128, 69, 67, 200, 70, 77, 128, 70, 89, 128, 71, 66, 128, 
+    71, 86, 128, 71, 89, 128, 72, 71, 128, 72, 75, 128, 73, 83, 211, 75, 66, 
+    128, 75, 73, 208, 75, 76, 128, 75, 77, 128, 75, 84, 128, 75, 86, 128, 76, 
+    65, 215, 76, 67, 197, 76, 67, 201, 76, 72, 128, 76, 78, 128, 76, 88, 128, 
+    77, 66, 128, 77, 69, 205, 77, 71, 128, 77, 72, 128, 77, 76, 128, 77, 77, 
+    128, 77, 83, 128, 77, 86, 128, 77, 87, 128, 78, 65, 193, 78, 70, 128, 78, 
+    71, 207, 78, 72, 128, 78, 77, 128, 78, 87, 128, 78, 89, 196, 79, 86, 128, 
+    80, 67, 128, 80, 69, 211, 80, 70, 128, 80, 79, 208, 80, 82, 128, 80, 86, 
+    128, 80, 87, 128, 81, 79, 198, 81, 89, 128, 82, 73, 206, 82, 74, 197, 82, 
+    85, 194, 83, 78, 193, 83, 79, 198, 83, 82, 128, 84, 65, 213, 84, 65, 214, 
+    84, 69, 197, 84, 69, 212, 84, 73, 210, 84, 82, 128, 86, 69, 197, 86, 69, 
+    215, 87, 66, 128, 87, 86, 128, 88, 89, 128, 89, 65, 210, 89, 86, 128, 90, 
+    76, 193, 66, 217, 77, 213, 65, 197, 89, 213, 68, 218, 90, 197, 75, 205, 
+    67, 205, 68, 205, 75, 213, 77, 205, 68, 194, 76, 218, 77, 194, 77, 207, 
+    77, 214, 77, 215, 80, 207, 81, 208, 84, 195, 202, 209, 
+};
+
+static unsigned short lexicon_offset[] = {
+    0, 0, 6, 10, 15, 23, 30, 32, 35, 40, 53, 65, 71, 77, 82, 90, 99, 103, 
+    108, 116, 119, 126, 130, 138, 144, 150, 157, 162, 172, 175, 182, 187, 
+    193, 201, 206, 215, 222, 229, 238, 243, 251, 255, 256, 264, 270, 276, 
+    282, 288, 295, 301, 309, 318, 322, 327, 330, 337, 344, 350, 353, 362, 
+    370, 375, 381, 387, 392, 397, 402, 405, 407, 413, 418, 426, 299, 428, 
+    430, 439, 100, 447, 457, 465, 467, 478, 481, 494, 498, 504, 514, 519, 
+    522, 524, 533, 538, 545, 549, 556, 559, 564, 569, 572, 582, 591, 599, 
+    606, 614, 618, 626, 634, 643, 647, 654, 662, 671, 675, 683, 689, 698, 
+    705, 708, 709, 714, 719, 728, 735, 738, 745, 751, 755, 763, 173, 767, 
+    773, 782, 750, 789, 263, 797, 803, 808, 812, 825, 834, 839, 842, 852, 
+    753, 857, 866, 875, 877, 882, 887, 894, 904, 907, 909, 913, 921, 22, 929, 
+    933, 938, 947, 543, 950, 960, 964, 971, 977, 983, 988, 994, 997, 1000, 
+    80, 1007, 1015, 1025, 1030, 1035, 1042, 1044, 1054, 779, 1058, 1062, 
+    1069, 1074, 1081, 1085, 1089, 1094, 1104, 1110, 1023, 1112, 1117, 1123, 
+    325, 1130, 1134, 1140, 1144, 1147, 1152, 1158, 1163, 1083, 1169, 1176, 
+    1181, 1183, 1185, 1190, 1195, 624, 1204, 1210, 1213, 1215, 1221, 31, 
+    1224, 1226, 1179, 1229, 1237, 1243, 1250, 1274, 1296, 1318, 1340, 1361, 
+    1382, 1402, 1422, 1441, 1460, 1479, 1498, 1517, 1536, 1555, 1574, 1592, 
+    1610, 1628, 1646, 1664, 1682, 1700, 1718, 1736, 1754, 1772, 1789, 1806, 
+    1823, 1840, 1857, 1874, 1891, 1908, 1925, 1942, 1959, 1975, 1991, 2007, 
+    2023, 2039, 2055, 2071, 2087, 2103, 2119, 2135, 2151, 2167, 2183, 2199, 
+    2215, 2231, 2247, 2263, 2279, 2295, 2311, 2327, 2343, 2359, 2375, 2391, 
+    2407, 2423, 2439, 2455, 2471, 2487, 2503, 2519, 2535, 2551, 2567, 2583, 
+    2599, 2615, 2631, 2647, 2663, 2679, 2695, 2711, 2727, 2743, 2759, 2775, 
+    2791, 2807, 2823, 2839, 2855, 2871, 2887, 2903, 2919, 2935, 2951, 2967, 
+    2983, 2999, 3015, 3031, 3047, 3063, 3079, 3095, 3111, 3127, 3143, 3159, 
+    3175, 3191, 3207, 3223, 3239, 3255, 3271, 3287, 3303, 3319, 3335, 3351, 
+    3367, 3383, 3399, 3415, 3431, 3447, 3463, 3479, 3495, 3511, 3527, 3543, 
+    3559, 3575, 3591, 3607, 3623, 3639, 3655, 3671, 3687, 3703, 3719, 3735, 
+    3751, 3767, 3783, 3799, 3815, 3831, 3847, 3863, 3879, 3895, 3911, 3927, 
+    3943, 3959, 3975, 3991, 4007, 4023, 4039, 4055, 4071, 4087, 4103, 4119, 
+    4135, 4151, 4167, 4183, 4199, 4215, 4231, 4247, 4263, 4279, 4295, 4311, 
+    4327, 4343, 4359, 4375, 4391, 4407, 4423, 4439, 4455, 4471, 4487, 4503, 
+    4519, 4535, 4551, 4567, 4583, 4599, 4615, 4631, 4647, 4663, 4679, 4695, 
+    4711, 4727, 4743, 4759, 4775, 4791, 4807, 4823, 4839, 4855, 4871, 4887, 
+    4903, 4919, 4935, 4951, 4967, 4983, 4999, 5015, 5031, 5047, 5063, 5079, 
+    5095, 5111, 5127, 5143, 5159, 5175, 5191, 5207, 5223, 5239, 5255, 5271, 
+    5287, 5303, 5319, 5335, 5351, 5367, 5383, 5399, 5415, 5431, 5447, 5463, 
+    5479, 5495, 5511, 5527, 5543, 5559, 5575, 5591, 5607, 5623, 5639, 5655, 
+    5671, 5687, 5703, 5719, 5735, 5751, 5767, 5783, 5799, 5815, 5831, 5847, 
+    5863, 5879, 5895, 5911, 5927, 5943, 5959, 5975, 5991, 6007, 6023, 6039, 
+    6055, 6071, 6087, 6103, 6119, 6135, 6151, 6167, 6183, 6199, 6215, 6231, 
+    6247, 6263, 6279, 6295, 6311, 6327, 6343, 6359, 6375, 6391, 6407, 6423, 
+    6439, 6455, 6471, 6487, 6503, 6519, 6535, 6551, 6567, 6583, 6599, 6615, 
+    6631, 6647, 6663, 6679, 6695, 6711, 6727, 6743, 6759, 6775, 6791, 6807, 
+    6823, 6839, 6855, 6871, 6887, 6903, 6919, 6935, 6951, 6967, 6983, 6999, 
+    7015, 7031, 7047, 7063, 7079, 7095, 7111, 7127, 7143, 7159, 7175, 7191, 
+    7207, 7223, 7239, 7255, 7271, 7287, 7303, 7319, 7335, 7351, 7367, 7383, 
+    7399, 7415, 7431, 7447, 7463, 7479, 7495, 7511, 7527, 7543, 7559, 7575, 
+    7591, 7607, 7623, 7639, 7655, 7671, 7687, 7703, 7719, 7735, 7751, 7767, 
+    7783, 7799, 7815, 7831, 7847, 7863, 7879, 7895, 7911, 7927, 7943, 7959, 
+    7975, 7991, 8007, 8023, 8039, 8055, 8071, 8087, 8103, 8119, 8135, 8151, 
+    8167, 8183, 8199, 8215, 8231, 8247, 8263, 8279, 8295, 8311, 8327, 8343, 
+    8359, 8375, 8391, 8407, 8423, 8439, 8455, 8471, 8487, 8503, 8519, 8535, 
+    8551, 8567, 8583, 8599, 8615, 8631, 8647, 8663, 8679, 8695, 8711, 8727, 
+    8743, 8759, 8775, 8791, 8807, 8823, 8839, 8855, 8871, 8887, 8903, 8919, 
+    8935, 8951, 8967, 8983, 8999, 9015, 9031, 9047, 9063, 9079, 9095, 9111, 
+    9127, 9143, 9159, 9175, 9191, 9207, 9223, 9239, 9255, 9271, 9287, 9303, 
+    9319, 9335, 9351, 9367, 9383, 9399, 9415, 9431, 9447, 9463, 9479, 9495, 
+    9511, 9527, 9543, 9559, 9575, 9591, 9607, 9623, 9639, 9655, 9671, 9687, 
+    9703, 9719, 9735, 9751, 9767, 9783, 9799, 9815, 9831, 9847, 9863, 9879, 
+    9895, 9911, 9927, 9943, 9959, 9975, 9991, 10007, 10023, 10039, 10055, 
+    10071, 10087, 10103, 10119, 10135, 10151, 10167, 10183, 10199, 10215, 
+    10231, 10247, 10263, 10279, 10295, 10311, 10327, 10343, 10359, 10375, 
+    10391, 10407, 10423, 10439, 10455, 10471, 10487, 10503, 10519, 10535, 
+    10551, 10567, 10583, 10599, 10615, 10631, 10647, 10663, 10679, 10695, 
+    10711, 10727, 10743, 10759, 10775, 10791, 10807, 10823, 10839, 10855, 
+    10871, 10887, 10903, 10919, 10934, 10949, 10964, 10979, 10994, 11009, 
+    11024, 11039, 11054, 11069, 11084, 11099, 11114, 11129, 11144, 11159, 
+    11174, 11189, 11204, 11219, 11234, 11249, 11264, 11279, 11294, 11309, 
+    11324, 11339, 11354, 11369, 11384, 11399, 11414, 11429, 11444, 11459, 
+    11474, 11489, 11504, 11519, 11534, 11549, 11564, 11579, 11594, 11609, 
+    11624, 11639, 11654, 11669, 11684, 11699, 11714, 11729, 11744, 11759, 
+    11774, 11789, 11804, 11819, 11834, 11849, 11864, 11879, 11894, 11909, 
+    11924, 11939, 11954, 11969, 11984, 11999, 12014, 12029, 12044, 12059, 
+    12074, 12089, 12104, 12119, 12134, 12149, 12164, 12179, 12194, 12209, 
+    12224, 12239, 12254, 12269, 12284, 12299, 12314, 12329, 12344, 12359, 
+    12374, 12389, 12404, 12419, 12434, 12449, 12464, 12479, 12494, 12509, 
+    12524, 12539, 12554, 12569, 12584, 12599, 12614, 12629, 12644, 12659, 
+    12674, 12689, 12704, 12719, 12734, 12749, 12764, 12779, 12794, 12809, 
+    12824, 12839, 12854, 12869, 12884, 12899, 12914, 12929, 12944, 12959, 
+    12974, 12989, 13004, 13019, 13034, 13049, 13064, 13079, 13094, 13109, 
+    13124, 13139, 13154, 13169, 13184, 13199, 13214, 13229, 13244, 13259, 
+    13274, 13289, 13304, 13319, 13334, 13349, 13364, 13379, 13394, 13409, 
+    13424, 13439, 13454, 13469, 13484, 13499, 13514, 13529, 13544, 13559, 
+    13574, 13589, 13604, 13619, 13634, 13649, 13664, 13679, 13694, 13709, 
+    13724, 13739, 13754, 13769, 13784, 13799, 13814, 13829, 13844, 13859, 
+    13874, 13889, 13904, 13919, 13934, 13949, 13964, 13979, 13994, 14009, 
+    14024, 14039, 14054, 14069, 14084, 14099, 14114, 14129, 14144, 14159, 
+    14174, 14189, 14204, 14219, 14234, 14249, 14264, 14279, 14294, 14309, 
+    14324, 14339, 14354, 14369, 14384, 14399, 14414, 14429, 14444, 14459, 
+    14474, 14489, 14504, 14519, 14534, 14549, 14564, 14579, 14594, 14609, 
+    14624, 14639, 14654, 14669, 14684, 14699, 14714, 14729, 14744, 14759, 
+    14774, 14789, 14804, 14819, 14834, 14849, 14864, 14879, 14894, 14909, 
+    14924, 14939, 14954, 14969, 14984, 14999, 15014, 15029, 15044, 15059, 
+    15074, 15089, 15104, 15119, 15134, 15149, 15164, 15179, 15194, 15209, 
+    15224, 15239, 15254, 15269, 15284, 15299, 15314, 15329, 15344, 15359, 
+    15374, 15389, 15404, 15419, 15434, 15449, 15464, 15479, 15494, 15509, 
+    15524, 15539, 15554, 15569, 15584, 15599, 15614, 15629, 15644, 15659, 
+    15674, 15689, 15704, 15719, 15734, 15749, 15764, 15779, 15794, 15809, 
+    15824, 15839, 15854, 15869, 15884, 15899, 15914, 15929, 15944, 15959, 
+    15974, 15989, 16004, 16019, 16034, 16049, 16064, 16079, 16094, 16109, 
+    16124, 16139, 16154, 16169, 16184, 16199, 16214, 16229, 16244, 16259, 
+    16274, 16289, 16304, 16319, 16334, 16349, 16364, 16379, 16394, 16409, 
+    16424, 16439, 16454, 16469, 16484, 16499, 16514, 16529, 16544, 16559, 
+    16574, 16589, 16604, 16619, 16634, 16649, 16664, 16679, 16694, 16709, 
+    16724, 16739, 16754, 16769, 16784, 16799, 16814, 16829, 16844, 16859, 
+    16874, 16889, 16904, 16919, 16934, 16949, 16964, 16979, 16994, 17009, 
+    17024, 17039, 17054, 17069, 17084, 17099, 17114, 17129, 17144, 17159, 
+    17174, 17189, 17204, 17219, 17234, 17249, 17264, 17279, 17294, 17309, 
+    17324, 17339, 17354, 17369, 17384, 17399, 17414, 17429, 17444, 17459, 
+    17474, 17489, 17504, 17519, 17534, 17549, 17564, 17579, 17594, 17609, 
+    17624, 17639, 17654, 17669, 17684, 17699, 17714, 17729, 17744, 17759, 
+    17774, 17789, 17804, 17819, 17834, 17849, 17864, 17879, 17894, 17909, 
+    17924, 17939, 17954, 17969, 17984, 17999, 18014, 18029, 18044, 18059, 
+    18074, 18089, 18104, 18119, 18134, 18149, 18164, 18179, 18194, 18209, 
+    18224, 18239, 18254, 18269, 18283, 18297, 18311, 18325, 18339, 1408, 
+    18353, 18367, 18381, 18395, 18409, 18423, 18437, 18451, 18465, 18479, 
+    18493, 18507, 18521, 18535, 18549, 18563, 18577, 18591, 18605, 18619, 
+    18633, 18647, 18661, 18675, 18689, 18703, 1809, 18717, 18731, 18745, 
+    18759, 18773, 18787, 18801, 18815, 18829, 18843, 18857, 18871, 18885, 
+    18899, 18913, 18927, 18941, 18954, 18967, 18980, 18993, 19006, 19019, 
+    19032, 19045, 19058, 19071, 19084, 19097, 19110, 19123, 19136, 19149, 
+    19162, 19175, 19188, 19201, 19214, 19227, 19240, 1759, 19253, 19266, 
+    19279, 19292, 19305, 19318, 19331, 19344, 19357, 19370, 19383, 19396, 
+    19409, 19422, 19435, 19448, 19461, 19474, 19487, 19500, 19513, 19526, 
+    19539, 19552, 19565, 19578, 19591, 19604, 19617, 19630, 19643, 19656, 
+    19669, 19682, 19695, 19708, 19721, 1523, 19734, 19747, 19760, 19773, 
+    19786, 19799, 19812, 19825, 19838, 19851, 19864, 19877, 19890, 19903, 
+    19916, 19929, 19942, 19955, 19968, 19981, 19994, 20007, 20020, 20033, 
+    20046, 20059, 20072, 20085, 20098, 20111, 20124, 20137, 20150, 20163, 
+    20176, 20189, 20202, 20215, 20228, 20241, 20254, 20267, 20280, 20293, 
+    20306, 20319, 20332, 20345, 20358, 20371, 20384, 20397, 20410, 20423, 
+    20436, 20449, 20462, 20475, 20488, 20501, 20514, 20527, 20540, 20553, 
+    20566, 20579, 20592, 20605, 20618, 20631, 20644, 20657, 20670, 20683, 
+    20696, 20709, 20722, 20735, 20748, 20761, 20774, 20787, 20800, 20813, 
+    20826, 20839, 20852, 20865, 20878, 20891, 20904, 20917, 20930, 20943, 
+    20956, 20969, 20982, 20995, 21008, 21021, 21034, 21047, 21060, 21073, 
+    21086, 21099, 21112, 21125, 21138, 21151, 21164, 21177, 21190, 21203, 
+    21216, 21229, 21242, 21255, 21268, 21281, 21294, 21307, 21320, 21333, 
+    21346, 21359, 21372, 21385, 21398, 21411, 21424, 21437, 21450, 21463, 
+    21476, 21489, 21502, 21515, 21528, 21541, 21554, 21567, 21580, 21593, 
+    21606, 21619, 21632, 21645, 21658, 21671, 21684, 21697, 21710, 21723, 
+    21736, 21749, 21762, 21775, 21788, 21801, 21814, 21827, 21840, 21853, 
+    21866, 21879, 21892, 21905, 21918, 21931, 21944, 21957, 21970, 21983, 
+    21996, 22009, 22022, 22034, 22046, 22058, 22070, 22082, 22094, 22106, 
+    22118, 22130, 22142, 22154, 22166, 22178, 22190, 22202, 22214, 22226, 
+    22238, 1670, 22250, 22262, 22274, 1616, 22286, 22298, 22310, 22322, 
+    22334, 22346, 22358, 1505, 1598, 22370, 1634, 22382, 22394, 22406, 22418, 
+    22430, 22442, 22454, 22466, 22478, 22490, 22502, 22514, 22526, 22538, 
+    22550, 22562, 22574, 22586, 22598, 22610, 22622, 22634, 22646, 22658, 
+    22670, 22682, 22694, 22706, 22718, 22730, 22742, 22754, 22766, 22778, 
+    22790, 22802, 22814, 22826, 22838, 22850, 22862, 22874, 22886, 22898, 
+    22910, 22922, 22934, 22946, 22958, 22970, 22982, 22994, 23006, 23018, 
+    23030, 23042, 23054, 23066, 23078, 23090, 23102, 23114, 23126, 23138, 
+    23150, 23162, 23174, 23186, 23198, 23210, 23222, 23234, 23246, 23258, 
+    23270, 23282, 23294, 23306, 23318, 23330, 23342, 23354, 23366, 23378, 
+    23390, 23402, 23414, 1390, 23426, 23438, 23450, 1724, 23462, 23474, 
+    23486, 23498, 23510, 23522, 23534, 23546, 23558, 23570, 23582, 23594, 
+    23606, 23618, 23630, 23642, 23654, 23666, 23678, 23690, 23702, 23714, 
+    23726, 23738, 23750, 23762, 23774, 23786, 23798, 23810, 23822, 23834, 
+    23846, 23858, 23870, 23882, 23894, 23906, 23918, 23930, 23942, 23954, 
+    23966, 23978, 23990, 24002, 24014, 24026, 24038, 24050, 24062, 24074, 
+    24086, 24098, 24110, 24122, 24134, 24146, 24158, 24170, 24182, 24194, 
+    24206, 24218, 24230, 24242, 24254, 24266, 24278, 24290, 24302, 24314, 
+    24326, 24338, 24350, 24362, 24374, 24386, 24398, 24410, 24422, 24434, 
+    24446, 24458, 24470, 24482, 24494, 24506, 24518, 24530, 24542, 24554, 
+    24566, 24578, 24590, 24602, 24614, 24626, 24638, 24650, 24662, 24674, 
+    24686, 24698, 24710, 24722, 24734, 24746, 24758, 24770, 24781, 24792, 
+    24803, 24814, 24825, 24836, 24847, 24858, 24869, 24880, 24891, 24902, 
+    24913, 24924, 24935, 24946, 24957, 1795, 24968, 24979, 24990, 25001, 
+    25012, 25023, 25034, 25045, 25056, 1880, 1307, 25067, 1430, 25078, 25089, 
+    25100, 25111, 25122, 25133, 1897, 25144, 25155, 25166, 25177, 25188, 
+    25199, 25210, 25221, 25232, 25243, 25254, 25265, 25276, 25287, 1863, 
+    25298, 25309, 25320, 25331, 25342, 25353, 25364, 25375, 25386, 25397, 
+    25408, 25419, 25430, 25441, 25452, 25463, 25474, 25485, 25496, 25507, 
+    25518, 25529, 25540, 25551, 25562, 25573, 25584, 25595, 25606, 25617, 
+    25628, 25639, 25650, 25661, 25672, 25683, 25694, 25705, 25716, 25727, 
+    25738, 25749, 25760, 25771, 25782, 25793, 25804, 25815, 25826, 25837, 
+    25848, 25859, 25870, 25881, 25892, 25903, 25914, 25925, 25936, 25947, 
+    25958, 25969, 25980, 25991, 26002, 26013, 26024, 26035, 26046, 26057, 
+    26068, 26079, 26090, 26101, 26112, 26123, 26134, 26145, 26156, 26167, 
+    26178, 26189, 26200, 26211, 26222, 26233, 26244, 26255, 26266, 26277, 
+    26288, 26299, 26310, 26321, 26332, 26343, 26354, 26365, 26376, 26387, 
+    26398, 26409, 26420, 26431, 26442, 26453, 18580, 26464, 26475, 26486, 
+    26497, 26508, 26519, 26530, 26541, 26552, 26563, 26574, 26585, 26596, 
+    26607, 26618, 26629, 26640, 26651, 26662, 26673, 26684, 26695, 26706, 
+    26717, 26728, 26739, 26750, 26761, 26772, 26783, 26794, 26805, 26816, 
+    26827, 26838, 26849, 26860, 26871, 26882, 26893, 26904, 26915, 26926, 
+    26937, 26948, 26959, 26970, 26981, 26992, 27003, 27013, 27023, 27033, 
+    27043, 27053, 27063, 27073, 27083, 27093, 27103, 27113, 27123, 27133, 
+    27143, 27153, 27163, 27173, 27183, 27193, 27203, 22072, 27213, 27223, 
+    27233, 27243, 27253, 27263, 27273, 27283, 1372, 27293, 27303, 27313, 
+    27323, 27333, 27343, 27353, 27363, 27373, 27383, 27393, 27403, 27413, 
+    27423, 27433, 27443, 27453, 27463, 27473, 27483, 27493, 27503, 27513, 
+    27523, 27533, 27543, 27553, 27563, 27573, 27583, 27593, 27603, 27613, 
+    27623, 27633, 27643, 27653, 27663, 27673, 27683, 27693, 27703, 27713, 
+    27723, 27733, 27743, 27753, 27763, 27773, 27783, 27793, 27803, 27813, 
+    27823, 27833, 27843, 27853, 27863, 27873, 27883, 27893, 27903, 27913, 
+    27923, 27933, 27943, 27953, 27963, 27973, 27983, 27993, 19490, 28003, 
+    22672, 28013, 28023, 28033, 28043, 28053, 28063, 28073, 28083, 28093, 
+    28103, 28113, 28123, 28133, 28143, 28153, 28163, 28173, 28183, 28193, 
+    28203, 28213, 28223, 28233, 28243, 28253, 28263, 28273, 28283, 28293, 
+    28303, 28313, 28323, 28333, 28343, 28353, 28363, 28373, 28383, 28393, 
+    28403, 28413, 28423, 28433, 28443, 28453, 28463, 28473, 28483, 28493, 
+    28503, 28513, 28523, 28533, 28543, 28553, 28563, 28573, 28583, 28593, 
+    28603, 28613, 28623, 28633, 28643, 28653, 28663, 28673, 28683, 28693, 
+    28703, 28713, 28723, 28733, 28743, 28753, 28763, 28773, 28783, 28793, 
+    28803, 28813, 28823, 28833, 28843, 28853, 28863, 28873, 28883, 28893, 
+    28903, 28913, 28923, 28933, 28943, 28953, 28963, 28973, 28983, 28993, 
+    29003, 29013, 29023, 29033, 29043, 29053, 29063, 29073, 29083, 29093, 
+    29103, 29113, 29123, 29133, 29143, 29153, 29163, 29173, 29183, 29193, 
+    29203, 29213, 29223, 29233, 29243, 29253, 29263, 29273, 29283, 29293, 
+    29303, 29313, 29323, 29333, 29343, 1949, 29353, 29363, 29373, 29383, 
+    29393, 29403, 29413, 29423, 29433, 29443, 29453, 29463, 29473, 29483, 
+    29493, 29503, 29513, 29523, 29533, 29543, 29553, 29563, 29573, 29583, 
+    29593, 29603, 29613, 29623, 29633, 29643, 29653, 29663, 29673, 29683, 
+    29693, 29703, 29713, 29723, 29733, 29743, 29753, 29763, 29773, 29783, 
+    29793, 29803, 29813, 29823, 29833, 29843, 29853, 29863, 29873, 29883, 
+    29893, 29903, 29913, 29923, 29933, 29942, 29951, 29960, 29969, 29978, 
+    29987, 29996, 30005, 30014, 30023, 30032, 30041, 30050, 30059, 30068, 
+    30077, 30086, 18958, 30095, 30104, 30113, 30122, 30131, 30140, 30149, 
+    30158, 30167, 30176, 30185, 30194, 30203, 30212, 30221, 30230, 30239, 
+    30248, 30257, 30266, 30275, 30284, 30293, 30302, 30311, 30320, 30329, 
+    30338, 30347, 30356, 30365, 30374, 30383, 30392, 30401, 30410, 30419, 
+    30428, 30437, 30446, 30455, 30464, 30473, 24926, 30482, 30491, 30500, 
+    30509, 30518, 30527, 30536, 30545, 30554, 30563, 30572, 30581, 30590, 
+    30599, 30608, 30617, 30626, 30635, 30644, 30653, 30662, 30671, 30680, 
+    30689, 30698, 30707, 30716, 25135, 30725, 30734, 30743, 30752, 30761, 
+    30770, 30779, 30788, 30797, 30806, 30815, 30824, 30833, 30842, 30851, 
+    30860, 30869, 30878, 30887, 30896, 30905, 1287, 30914, 30923, 30932, 
+    30941, 30950, 30959, 30968, 30977, 30986, 30995, 31004, 31013, 31022, 
+    31031, 31040, 31049, 29894, 31058, 31067, 31076, 31085, 31094, 31103, 
+    31112, 31121, 31130, 31139, 31148, 31157, 31166, 31175, 31184, 31193, 
+    31202, 31211, 31220, 31229, 31238, 31247, 31256, 31265, 31274, 31283, 
+    31292, 31301, 31310, 31319, 31328, 31337, 31346, 31355, 31364, 31373, 
+    31382, 31391, 31400, 31409, 31418, 31427, 31436, 31445, 31454, 31463, 
+    31472, 31481, 31490, 31499, 31508, 31517, 31526, 31535, 31544, 31553, 
+    31562, 31571, 31580, 31589, 31598, 31607, 31616, 31625, 31634, 31643, 
+    31652, 31661, 31670, 31679, 31688, 31697, 31706, 31715, 31724, 31733, 
+    31742, 31751, 31760, 31769, 31778, 31787, 31796, 31805, 31814, 31823, 
+    31832, 31841, 31850, 31859, 31868, 31877, 31886, 31895, 31904, 31913, 
+    31922, 31931, 31940, 31949, 31958, 31967, 31976, 31985, 31994, 32003, 
+    32012, 32021, 32030, 32039, 32048, 32057, 32066, 32075, 32084, 32093, 
+    32102, 32111, 32120, 32129, 32138, 32147, 32156, 32165, 32174, 32183, 
+    32192, 32201, 32210, 10766, 32219, 32228, 32237, 32246, 32255, 32264, 
+    32273, 32282, 32291, 32300, 32309, 32318, 32327, 32336, 32345, 32354, 
+    32363, 32372, 32381, 32390, 32399, 32408, 32417, 32426, 32435, 32444, 
+    32453, 32462, 32471, 32480, 32489, 32498, 32507, 32516, 32525, 32534, 
+    32543, 32552, 32561, 32570, 32579, 32588, 32597, 32606, 32615, 32624, 
+    32633, 32642, 32651, 32660, 32669, 32678, 32687, 32696, 32705, 32714, 
+    32723, 1848, 32732, 32741, 32750, 32759, 32768, 32777, 32786, 32795, 
+    32804, 32813, 32822, 32831, 32840, 32849, 32858, 32867, 32876, 32885, 
+    32894, 32903, 32912, 32921, 32930, 32939, 32948, 32957, 32966, 32975, 
+    32984, 32993, 33002, 33011, 33020, 33029, 33038, 33047, 33056, 33065, 
+    33074, 33083, 33091, 33099, 33107, 33115, 18289, 33123, 33131, 33139, 
+    33147, 33155, 33163, 33171, 33179, 33187, 33195, 33203, 33211, 33219, 
+    33227, 33235, 33243, 33251, 33259, 33267, 27465, 33275, 33283, 33291, 
+    33299, 33307, 33315, 33323, 33331, 33339, 33347, 19609, 33355, 33363, 
+    33371, 33379, 33387, 33395, 33403, 18317, 33411, 33419, 33427, 33435, 
+    33443, 1471, 33451, 33459, 2047, 19765, 33467, 1967, 33475, 33483, 33491, 
+    18373, 33499, 33507, 33515, 33523, 18985, 22362, 33531, 33539, 33547, 
+    33555, 33563, 33571, 33579, 33587, 33595, 33603, 30402, 33611, 33619, 
+    33627, 33635, 33643, 33651, 33659, 33667, 33675, 33683, 33691, 1815, 
+    33699, 33707, 33715, 33723, 33731, 33739, 33747, 33755, 33763, 33771, 
+    33779, 33787, 33795, 33803, 33811, 33819, 33827, 33835, 33843, 33851, 
+    33859, 33867, 33875, 33883, 33891, 33899, 33907, 33915, 33923, 33931, 
+    33939, 33947, 33955, 33963, 33971, 33979, 33987, 33995, 34003, 34011, 
+    34019, 34027, 34035, 34043, 34051, 34059, 34067, 34075, 34083, 34091, 
+    27265, 34099, 34107, 34115, 34123, 34131, 34139, 34147, 34155, 34163, 
+    34171, 34179, 34187, 34195, 34203, 34211, 34219, 30906, 34227, 34235, 
+    34243, 34251, 34259, 34267, 34275, 34283, 34291, 34299, 34307, 34315, 
+    34323, 34331, 34339, 34347, 34355, 34363, 34371, 34379, 34387, 34395, 
+    34403, 34411, 34419, 34427, 34435, 34443, 34451, 34459, 34467, 34475, 
+    34483, 34491, 34499, 34507, 34515, 34523, 34531, 34539, 34547, 27325, 
+    34555, 34563, 34571, 34579, 34587, 34595, 34603, 34611, 34619, 34627, 
+    34635, 34643, 34651, 34659, 34667, 34675, 34683, 26467, 34691, 34699, 
+    34707, 34715, 34723, 34731, 34739, 34747, 34755, 34763, 34771, 34779, 
+    34787, 34795, 34803, 34811, 34819, 34827, 34835, 34843, 34851, 34859, 
+    34867, 34875, 34883, 34891, 34899, 34907, 34915, 34923, 34931, 34939, 
+    34947, 34955, 34963, 34971, 34979, 34987, 34995, 30951, 35003, 35011, 
+    35019, 35027, 35035, 35043, 35051, 35059, 35067, 35075, 35083, 35091, 
+    35099, 26588, 35107, 35115, 1934, 35123, 35131, 35139, 35147, 35155, 
+    35163, 35171, 35179, 32706, 35187, 35195, 35203, 35211, 35219, 35227, 
+    35235, 35243, 35251, 35259, 35267, 35275, 35283, 35291, 35299, 35307, 
+    35315, 35323, 35331, 35339, 2015, 35347, 35355, 10863, 35363, 35371, 
+    35379, 35387, 35395, 35403, 35411, 35419, 35427, 23310, 35435, 35443, 
+    35451, 35459, 35467, 35475, 35483, 35491, 35499, 35507, 35515, 35523, 
+    35531, 35539, 35547, 35555, 35563, 35571, 35579, 35587, 35595, 35603, 
+    35611, 35619, 35627, 35635, 35643, 35651, 35659, 35667, 35675, 35683, 
+    19141, 35691, 35699, 35707, 35715, 35723, 35731, 35739, 35747, 35755, 
+    1710, 35763, 35771, 35779, 35787, 35795, 35803, 35811, 35819, 35827, 
+    35835, 35843, 35851, 35859, 35867, 35875, 35883, 35891, 35899, 35907, 
+    35915, 35923, 35931, 35939, 35947, 35955, 35963, 35971, 35979, 35987, 
+    35995, 36003, 36011, 36019, 18905, 36027, 36035, 36043, 36051, 36059, 
+    36067, 36075, 36083, 36091, 36099, 36107, 28965, 36115, 36123, 36131, 
+    36139, 36147, 36155, 36163, 36171, 36179, 36187, 36195, 36202, 36209, 
+    36216, 36223, 36230, 19753, 36237, 36244, 36251, 36258, 36265, 36272, 
+    36279, 36286, 36293, 36300, 36307, 36314, 36321, 36328, 36335, 36342, 
+    36349, 11047, 36356, 36363, 36370, 36377, 36384, 36391, 36398, 36405, 
+    36412, 36419, 36426, 36433, 36440, 36447, 36454, 36461, 36468, 36475, 
+    36482, 36489, 36496, 36503, 36510, 36517, 1510, 36524, 36531, 1603, 
+    36538, 36545, 36552, 36559, 36566, 36573, 36580, 36587, 36594, 36601, 
+    36608, 36615, 36622, 36629, 36636, 36643, 36650, 1354, 36657, 36664, 
+    36671, 36678, 36685, 36692, 36699, 36706, 36713, 36720, 36727, 36734, 
+    36741, 36748, 36755, 36762, 36769, 36776, 36783, 26578, 36790, 36797, 
+    36804, 36811, 36818, 36825, 36832, 36839, 36846, 36853, 36860, 36867, 
+    36874, 36881, 36888, 36895, 36902, 36909, 36916, 36923, 36930, 36937, 
+    36944, 36951, 36958, 36965, 36972, 36979, 36986, 36993, 30187, 37000, 
+    37007, 37014, 37021, 37028, 37035, 37042, 37049, 37056, 37063, 37070, 
+    37077, 37084, 37091, 37098, 37105, 37112, 37119, 37126, 37133, 37140, 
+    37147, 37154, 37161, 37168, 37175, 37182, 37189, 37196, 37203, 37210, 
+    37217, 37224, 37231, 37238, 37245, 37252, 37259, 37266, 37273, 37280, 
+    22123, 37287, 37294, 37301, 37308, 37315, 37322, 37329, 37336, 37343, 
+    37350, 37357, 37364, 37371, 37378, 37385, 37392, 37399, 37406, 37413, 
+    37420, 37427, 37434, 37441, 37448, 37455, 37462, 37469, 37476, 37483, 
+    37490, 25291, 37497, 37504, 37511, 37518, 37525, 37532, 37539, 37546, 
+    37553, 37560, 37567, 30403, 37574, 37581, 37588, 37595, 37602, 37609, 
+    37616, 37623, 37630, 1747, 37637, 37644, 37651, 37658, 37665, 37672, 
+    37679, 37686, 37693, 37700, 37707, 37714, 37721, 37728, 37735, 37742, 
+    37749, 37756, 37763, 37770, 37777, 37784, 37791, 37798, 37805, 37812, 
+    37819, 37826, 37833, 37840, 37847, 37854, 37861, 37868, 37875, 37882, 
+    37889, 37896, 37903, 37910, 37917, 37924, 37931, 37938, 37945, 37952, 
+    37959, 37966, 30952, 37973, 37980, 37987, 37994, 38001, 38008, 38015, 
+    38022, 38029, 38036, 38043, 38050, 38057, 38064, 38071, 38078, 38085, 
+    38092, 38099, 38106, 38113, 38120, 38127, 38134, 38141, 38148, 38155, 
+    26512, 38162, 38169, 38176, 38183, 38190, 38197, 38204, 38211, 38218, 
+    38225, 38232, 38239, 38246, 38253, 34308, 38260, 38267, 38274, 38281, 
+    38288, 38295, 38302, 38309, 38316, 38323, 38330, 38337, 38344, 38351, 
+    38358, 38365, 38372, 38379, 38386, 38393, 38400, 38407, 38414, 38421, 
+    38428, 38435, 38442, 38449, 38456, 38463, 38470, 38477, 38484, 38491, 
+    38498, 38505, 38512, 38519, 38526, 38533, 38540, 38547, 38554, 38561, 
+    38568, 38575, 38582, 29166, 38589, 38596, 38603, 38610, 38617, 35596, 
+    38624, 38631, 38638, 38645, 38652, 38659, 38666, 38673, 38680, 38687, 
+    38694, 33196, 38701, 38708, 38715, 38722, 38729, 38736, 38743, 38750, 
+    38757, 38764, 38771, 38778, 38785, 38792, 38799, 38806, 38813, 38820, 
+    38827, 38834, 38841, 38848, 38855, 38862, 38869, 38876, 38883, 38890, 
+    38897, 38904, 30772, 38911, 38918, 38925, 38932, 23167, 38939, 38946, 
+    38953, 38960, 38967, 38974, 38981, 38988, 38995, 39002, 39009, 39016, 
+    39023, 39030, 39037, 39044, 39051, 39058, 39065, 39072, 39079, 39086, 
+    39093, 39100, 39107, 39114, 39121, 39128, 30970, 39135, 39142, 39149, 
+    28966, 39156, 39163, 39170, 39177, 39184, 39191, 39198, 39205, 39212, 
+    39219, 39226, 39233, 39240, 39247, 39254, 39261, 39267, 39273, 39279, 
+    39285, 39291, 39297, 39303, 39309, 39315, 39321, 39327, 38086, 33917, 
+    39333, 39339, 39345, 39351, 27927, 39357, 39363, 39369, 39375, 39381, 
+    39387, 39393, 39399, 27127, 39405, 39411, 39417, 39423, 39255, 39429, 
+    39435, 39441, 39447, 39453, 39459, 39465, 27227, 39471, 39477, 39483, 
+    39489, 39495, 39501, 39507, 39513, 39519, 39525, 39531, 39537, 39543, 
+    39549, 39555, 39561, 27287, 39567, 39573, 39579, 39585, 25061, 22148, 
+    39591, 19299, 28047, 39597, 39603, 39609, 39615, 19065, 39621, 39627, 
+    1312, 39633, 39639, 1549, 22580, 39645, 39651, 18347, 39657, 22448, 
+    39663, 39669, 1416, 39675, 18753, 39681, 19286, 39687, 39693, 39699, 
+    39705, 39711, 39717, 39723, 39729, 39735, 39741, 33613, 39747, 39753, 
+    39759, 39765, 27137, 39771, 39777, 39783, 39789, 39795, 39801, 39807, 
+    39813, 39819, 39825, 39831, 10973, 1198, 39837, 39843, 39849, 39855, 
+    39861, 39867, 39873, 39879, 39885, 39891, 39897, 39903, 39909, 39915, 
+    39921, 39927, 39933, 39939, 39945, 39951, 22460, 39957, 39963, 39969, 
+    39975, 39981, 39987, 39993, 39999, 40005, 40011, 40017, 40023, 40029, 
+    40035, 40041, 40047, 40053, 40059, 26876, 40065, 40071, 40077, 40083, 
+    40089, 40095, 40101, 40107, 40113, 40119, 40125, 30980, 27197, 40131, 
+    40137, 40143, 40149, 40155, 40161, 40167, 40173, 40179, 40185, 40191, 
+    40197, 40203, 40209, 40215, 40221, 40227, 40233, 40239, 40245, 40251, 
+    40257, 40263, 40269, 40275, 40281, 40287, 40293, 40299, 40305, 27377, 
+    40311, 40317, 40323, 40329, 40335, 40341, 40347, 40353, 40359, 40365, 
+    40371, 40377, 40383, 40389, 40395, 40401, 40407, 40413, 40419, 40425, 
+    40431, 40437, 40443, 40449, 40455, 40461, 40467, 40473, 40479, 40485, 
+    40491, 40497, 40503, 40509, 40515, 40521, 40527, 40533, 40539, 40545, 
+    32861, 40551, 40557, 40563, 40569, 40575, 40581, 40587, 40593, 40599, 
+    40605, 40611, 40617, 40623, 40629, 40635, 40641, 40647, 40653, 40659, 
+    40665, 40671, 40677, 40683, 40689, 40695, 40701, 40707, 40713, 26469, 
+    40719, 40725, 40731, 40737, 40743, 40749, 40755, 40761, 40767, 40773, 
+    40779, 40785, 40791, 40797, 40803, 40809, 40815, 40821, 40827, 40833, 
+    40839, 40845, 40851, 27367, 40857, 40863, 40869, 40875, 40881, 40887, 
+    40893, 40899, 40905, 40911, 40917, 40923, 40929, 40935, 40941, 40947, 
+    40953, 40959, 40965, 40971, 40977, 40983, 40989, 40995, 41001, 41007, 
+    41013, 41019, 41025, 41031, 41037, 41043, 37827, 41049, 41055, 41061, 
+    41067, 41073, 41079, 41085, 41091, 41097, 41103, 34469, 41109, 41115, 
+    41121, 41127, 41133, 41139, 41145, 41151, 41157, 41163, 41169, 41175, 
+    41181, 36093, 41187, 41193, 41199, 41205, 41211, 41217, 41223, 41229, 
+    41235, 41241, 41247, 41253, 41259, 41265, 41271, 41277, 41283, 41289, 
+    41295, 41301, 41307, 41313, 41319, 41325, 41331, 41337, 41343, 41349, 
+    41355, 41361, 41367, 41373, 41379, 41385, 41391, 41397, 41403, 41409, 
+    41415, 41421, 41427, 41433, 41439, 41445, 34701, 41451, 41457, 41463, 
+    41469, 41475, 41481, 41487, 22712, 41493, 41499, 41505, 41511, 41517, 
+    41523, 41529, 41535, 41541, 41547, 41553, 41559, 41565, 41571, 41577, 
+    41583, 41589, 41595, 41601, 41607, 41613, 41619, 41625, 41631, 41637, 
+    41643, 41649, 41655, 41661, 41667, 41673, 41679, 41685, 41691, 41697, 
+    41703, 41709, 41715, 41721, 41727, 41733, 41739, 41745, 41751, 41757, 
+    41763, 41769, 41775, 41781, 41787, 41793, 41799, 41805, 41811, 41817, 
+    41823, 41829, 41835, 41841, 41847, 41853, 41859, 41865, 41871, 41877, 
+    41883, 41889, 41895, 41901, 41907, 41913, 41919, 41925, 41931, 41937, 
+    41943, 41949, 41955, 41961, 41967, 41973, 41979, 41985, 41991, 41997, 
+    42003, 42009, 42015, 42021, 42027, 42033, 42039, 42045, 42051, 42057, 
+    42063, 42069, 42075, 42081, 42087, 42093, 42099, 42105, 42111, 42117, 
+    42123, 42129, 42135, 42141, 42147, 42153, 42159, 42165, 42171, 42177, 
+    42183, 42189, 37169, 42195, 42201, 42207, 42213, 42219, 42225, 42231, 
+    42237, 42243, 42249, 42255, 42261, 42267, 42273, 42279, 42285, 42291, 
+    42297, 42303, 42309, 42315, 42321, 42327, 42333, 42339, 42345, 42351, 
+    42357, 42363, 42369, 42375, 42381, 42387, 42393, 42399, 42405, 42411, 
+    42417, 42423, 42429, 42435, 42441, 42447, 42453, 42459, 42465, 42471, 
+    42477, 42483, 42489, 42495, 42501, 42507, 42513, 42519, 42525, 42531, 
+    42537, 42543, 42549, 42555, 42561, 42567, 42573, 42579, 42585, 42591, 
+    42597, 42603, 42609, 42615, 42621, 42627, 42633, 42639, 42645, 42651, 
+    42657, 42663, 42669, 42675, 42681, 42687, 42693, 42699, 42705, 42711, 
+    42717, 42723, 42729, 32393, 42735, 42741, 42747, 42753, 42759, 42765, 
+    42771, 42777, 42783, 42789, 42795, 42801, 42807, 42813, 42819, 42825, 
+    42831, 42837, 42843, 42849, 42855, 10943, 42861, 42867, 42873, 42879, 
+    42885, 42891, 42897, 42903, 42909, 42915, 42921, 42927, 42933, 42939, 
+    22496, 42945, 42951, 42957, 39122, 42963, 42969, 30989, 42975, 42981, 
+    42987, 42993, 42999, 43005, 43011, 43017, 43023, 43029, 43035, 43041, 
+    43047, 43053, 43059, 43065, 43071, 43077, 43083, 43089, 43095, 43101, 
+    43107, 43113, 43119, 43125, 43131, 43137, 43143, 43149, 43155, 43161, 
+    43167, 43173, 43179, 43185, 29087, 43191, 43197, 43203, 43209, 43215, 
+    43221, 43227, 43233, 43239, 43245, 43251, 43257, 43263, 43269, 43275, 
+    43281, 43287, 43293, 43299, 43305, 43311, 43317, 43323, 43329, 43335, 
+    43341, 43347, 43353, 43359, 43365, 43371, 43376, 43381, 43386, 43391, 
+    43396, 43401, 43406, 43411, 43416, 30198, 43421, 19157, 43426, 43431, 
+    40864, 43436, 43441, 43446, 28858, 43451, 43456, 43461, 43466, 43471, 
+    43476, 43481, 43486, 43491, 43496, 43501, 43506, 43511, 43060, 43516, 
+    41068, 29308, 43521, 43526, 43531, 39784, 43536, 43541, 43546, 43551, 
+    43556, 43561, 43566, 43571, 43576, 40024, 43581, 43586, 43591, 43596, 
+    43601, 32682, 43606, 43611, 43616, 43621, 43626, 43631, 43636, 43641, 
+    43646, 43651, 43656, 43661, 43666, 43671, 43676, 43681, 43686, 43691, 
+    43696, 1377, 43701, 43706, 43711, 43716, 17919, 43721, 43726, 43731, 
+    43736, 43741, 43746, 43751, 43756, 43761, 43766, 43771, 43776, 43781, 
+    43786, 40900, 43791, 43796, 43801, 43806, 43811, 43816, 43821, 43826, 
+    43831, 43836, 43841, 43846, 43851, 43856, 43861, 43866, 43871, 43876, 
+    43881, 43886, 39880, 43891, 43896, 42916, 43901, 43906, 434, 43911, 
+    31152, 43916, 43921, 43926, 43931, 43936, 43941, 43946, 43951, 43956, 
+    1153, 43961, 43966, 43971, 43976, 43981, 27058, 43986, 43991, 43996, 
+    44001, 44006, 44011, 39382, 44016, 44021, 44026, 44031, 44036, 44041, 
+    44046, 44051, 44056, 44061, 44066, 44071, 44076, 44081, 44086, 44091, 
+    44096, 44101, 44106, 44111, 18949, 44116, 44121, 44126, 44131, 44136, 
+    44141, 44146, 44151, 44156, 44161, 44166, 44171, 44176, 44181, 44186, 
+    44191, 43294, 44196, 38220, 44201, 44206, 44211, 44216, 44221, 44226, 
+    44231, 44236, 42958, 19404, 44241, 44246, 44251, 44256, 40120, 44261, 
+    44266, 44271, 44276, 44281, 44286, 44291, 44296, 26437, 44301, 44306, 
+    44311, 44316, 29288, 44321, 44326, 44331, 44336, 44341, 44346, 44351, 
+    44356, 44361, 44366, 44371, 44376, 44381, 44386, 44391, 44396, 44401, 
+    44406, 44411, 44416, 44421, 44426, 44431, 44436, 44441, 44446, 44451, 
+    44456, 44461, 44466, 44471, 44476, 26591, 44481, 44486, 44491, 44496, 
+    27388, 44501, 33830, 44506, 44511, 44516, 44521, 44526, 44531, 44536, 
+    44541, 44546, 44551, 44556, 44561, 44566, 44571, 44576, 44581, 44586, 
+    44591, 44596, 44601, 42634, 44606, 44611, 44616, 32745, 44621, 44626, 
+    30819, 44631, 44636, 44641, 44646, 44651, 44656, 41446, 44661, 44666, 
+    37100, 44671, 44676, 44681, 18572, 44686, 44691, 44696, 44701, 35590, 
+    44706, 44711, 44716, 44721, 44726, 44731, 36974, 38633, 44736, 44741, 
+    44746, 44751, 44756, 44761, 44766, 44771, 44776, 44781, 44786, 44791, 
+    44796, 44801, 44806, 44811, 44816, 44821, 44826, 44831, 44836, 44841, 
+    44846, 44851, 43054, 44856, 37275, 44861, 44866, 44871, 44876, 36358, 
+    44881, 44886, 44891, 44896, 44901, 44906, 44911, 44916, 44921, 44926, 
+    44931, 44936, 44941, 44946, 44951, 44956, 44961, 44966, 44971, 44976, 
+    44981, 28938, 44986, 44991, 44996, 45001, 45006, 38136, 45011, 45016, 
+    45021, 45026, 45031, 45036, 45041, 45046, 32934, 45051, 45056, 45061, 
+    45066, 45071, 45076, 45081, 45086, 45091, 45096, 45101, 45106, 45111, 
+    45116, 45121, 45126, 45131, 45136, 45141, 45146, 45151, 45156, 45161, 
+    45166, 45171, 45176, 45181, 45186, 45191, 45196, 45201, 45206, 45211, 
+    45216, 45221, 45226, 45231, 45236, 45241, 45246, 45251, 45256, 45261, 
+    45266, 45271, 45276, 45281, 45286, 45291, 45296, 45301, 45306, 45311, 
+    45316, 45321, 45326, 45331, 45336, 45341, 45346, 45351, 45356, 45361, 
+    45366, 45371, 45376, 45381, 45386, 45391, 45396, 45401, 45406, 45411, 
+    45416, 45421, 45426, 45431, 45436, 45441, 45446, 45451, 45456, 45461, 
+    45466, 45471, 45476, 45481, 45486, 45491, 45496, 45501, 45506, 45511, 
+    45516, 45521, 45526, 45531, 45536, 45541, 45546, 45551, 45556, 45561, 
+    45566, 45571, 45576, 45581, 45586, 45591, 45596, 45601, 45606, 45611, 
+    45616, 45621, 45626, 45631, 45636, 45641, 45646, 45651, 45656, 45661, 
+    45666, 45671, 45676, 45681, 45686, 45691, 45696, 45701, 45706, 45711, 
+    45716, 45721, 45726, 40750, 40756, 40762, 45731, 45736, 45741, 45746, 
+    45751, 45756, 45761, 45766, 45771, 45776, 29328, 40768, 40774, 40780, 
+    45781, 42142, 45786, 45791, 45796, 45801, 45806, 45811, 45816, 45821, 
+    45826, 45831, 45836, 45841, 45846, 40894, 45851, 45856, 45861, 45866, 
+    45871, 45876, 45881, 45886, 45891, 45896, 45901, 45906, 45911, 45916, 
+    45921, 45926, 39682, 45931, 45936, 45941, 45946, 45951, 45956, 45961, 
+    45966, 45971, 45976, 45981, 45986, 45991, 45996, 46001, 46006, 46011, 
+    46016, 46021, 46026, 46031, 46036, 46041, 46046, 46051, 46056, 46061, 
+    46066, 46071, 46076, 46081, 46086, 46091, 46096, 46101, 46106, 46111, 
+    46116, 46121, 46126, 46131, 46136, 46141, 46146, 46151, 46156, 46161, 
+    46166, 46171, 46176, 46181, 41074, 41080, 46186, 46191, 46196, 46201, 
+    46206, 46211, 46216, 46221, 41092, 41098, 46226, 46231, 30666, 46236, 
+    46241, 46246, 43258, 43264, 46251, 46256, 46261, 46266, 46271, 46276, 
+    46281, 46286, 46291, 46296, 46301, 46306, 46311, 46316, 46321, 46326, 
+    46331, 46336, 46341, 46346, 46351, 46356, 46361, 46366, 46371, 46376, 
+    46381, 46386, 46391, 46396, 46401, 46406, 46411, 46416, 46421, 46426, 
+    41374, 46431, 41380, 46436, 46441, 46446, 18446, 33486, 46451, 41386, 
+    41392, 41398, 41404, 41410, 41416, 46456, 46461, 46466, 46471, 40924, 
+    46476, 40810, 46481, 46486, 46491, 42976, 46496, 46501, 46506, 46511, 
+    46516, 46521, 46526, 46531, 46536, 46541, 46546, 46551, 46556, 46561, 
+    46566, 46571, 46576, 46581, 46586, 46591, 46596, 46601, 46606, 46611, 
+    46616, 46621, 46626, 46631, 46636, 46641, 46646, 46651, 46656, 46661, 
+    46666, 46671, 46676, 46681, 46686, 46691, 46696, 46701, 46706, 46711, 
+    46716, 46721, 46726, 46731, 46736, 46741, 46746, 46751, 46756, 46761, 
+    46766, 46771, 46776, 42484, 40960, 40966, 40972, 42562, 46781, 46786, 
+    46791, 46796, 46801, 46806, 46811, 46816, 46821, 46826, 46831, 46836, 
+    46841, 46846, 46851, 46856, 46861, 46866, 46871, 46876, 46881, 46886, 
+    46891, 46896, 46901, 46906, 41686, 41692, 41698, 46911, 46916, 46921, 
+    46926, 46931, 46936, 46941, 46946, 46951, 46956, 46961, 46966, 46971, 
+    46976, 46981, 46986, 41704, 46991, 41710, 41716, 42232, 46996, 47001, 
+    47006, 47011, 47016, 47021, 47026, 47031, 47036, 47041, 47046, 47051, 
+    47056, 47061, 47066, 47071, 47076, 47081, 47086, 47091, 47096, 47101, 
+    47106, 47111, 47116, 47121, 47126, 47131, 47136, 47141, 47146, 47151, 
+    39280, 47156, 47161, 47166, 47171, 47176, 47181, 47186, 47191, 47196, 
+    43024, 47201, 47206, 41500, 47211, 41506, 47216, 47221, 47226, 47231, 
+    47236, 41512, 47241, 41518, 41524, 41530, 47246, 38031, 47251, 47256, 
+    47261, 47266, 47271, 47276, 47281, 47286, 47291, 47296, 47301, 47306, 
+    47311, 47316, 47321, 47326, 47331, 47336, 47341, 41536, 41542, 47346, 
+    47351, 47356, 47361, 47366, 47371, 47376, 47381, 47386, 35374, 47391, 
+    47396, 41548, 47401, 41554, 29338, 41560, 47406, 47411, 47416, 47421, 
+    38542, 47426, 47431, 47436, 47441, 47446, 47451, 47456, 47461, 47466, 
+    47471, 47476, 47481, 47486, 47491, 47496, 47501, 47506, 47511, 47516, 
+    47521, 47526, 39646, 47531, 47536, 47541, 47546, 47551, 47556, 47561, 
+    47566, 47571, 47576, 47581, 42238, 47586, 47591, 47596, 47601, 47606, 
+    47611, 47616, 42244, 47621, 42250, 47626, 47631, 47636, 47641, 41572, 
+    41584, 39586, 47646, 47651, 47656, 47661, 47666, 47671, 47676, 47681, 
+    47686, 47691, 47696, 47701, 47706, 47711, 47716, 47721, 47726, 47731, 
+    38773, 47736, 47741, 47746, 47751, 47756, 47761, 47766, 47771, 47776, 
+    47781, 47786, 47791, 47796, 47801, 47806, 47811, 47816, 47821, 47826, 
+    41590, 47831, 47836, 47841, 47846, 47851, 47856, 47861, 47866, 47871, 
+    47876, 47881, 47886, 47891, 47896, 47901, 47906, 47911, 47916, 47921, 
+    47926, 47931, 47936, 47941, 47946, 47951, 47956, 47961, 47966, 47971, 
+    47976, 47981, 47986, 47991, 47996, 48001, 48006, 48011, 48016, 48021, 
+    48026, 48031, 48036, 48041, 48046, 48051, 48056, 48061, 48066, 48071, 
+    48076, 48081, 48086, 48091, 48096, 48101, 48106, 48111, 48116, 48121, 
+    48126, 48131, 48136, 48141, 48146, 48151, 48156, 48161, 48166, 48171, 
+    48176, 48181, 48186, 48191, 48196, 48201, 48206, 48211, 48216, 48221, 
+    48226, 48231, 48236, 48241, 48246, 48251, 48256, 48261, 48266, 48271, 
+    48276, 48281, 48286, 48291, 48296, 42520, 48301, 48306, 48311, 48316, 
+    48321, 48326, 48331, 48336, 48341, 48346, 48351, 48356, 48361, 48366, 
+    48371, 48376, 48381, 48386, 48391, 48396, 42646, 42274, 48401, 42280, 
+    48406, 48411, 48416, 48421, 48426, 48431, 48436, 48441, 48446, 48451, 
+    48456, 48461, 48466, 48471, 48476, 48481, 48486, 48491, 48496, 48501, 
+    48506, 48511, 48516, 48521, 48526, 48531, 48536, 48541, 42880, 42886, 
+    48546, 48551, 48556, 48561, 48566, 31089, 48571, 942, 48576, 48581, 
+    48586, 48591, 48596, 48601, 48606, 48611, 48616, 48621, 48626, 48631, 
+    48636, 48641, 48646, 48651, 48656, 48661, 48666, 48671, 48676, 48681, 
+    48686, 48691, 48696, 48701, 48706, 48711, 48716, 48721, 27328, 48726, 
+    48731, 42892, 48736, 48741, 48746, 48751, 48756, 48761, 48766, 48771, 
+    48776, 48781, 42382, 48786, 48791, 48796, 48801, 48806, 48811, 48816, 
+    48821, 48826, 27138, 48831, 48836, 48841, 48846, 48851, 48856, 38486, 
+    48861, 48866, 48871, 48876, 48881, 48886, 48891, 48896, 48901, 48906, 
+    48911, 48916, 48921, 48926, 48931, 48936, 48941, 48946, 48951, 48956, 
+    48961, 48966, 40636, 48971, 33406, 39011, 29348, 48976, 48981, 48986, 
+    48991, 48996, 49001, 49006, 49011, 49016, 33702, 49021, 49026, 49031, 
+    49036, 49041, 41620, 41626, 41632, 49046, 41650, 41836, 41842, 49051, 
+    49056, 49061, 49066, 49071, 49076, 49081, 49086, 49091, 49096, 49101, 
+    49106, 49111, 49116, 49121, 49126, 49131, 49136, 49141, 42292, 42298, 
+    42304, 49146, 49151, 49156, 49161, 49166, 49171, 49176, 49181, 49186, 
+    42310, 49191, 42316, 49196, 49201, 49206, 49211, 49216, 49221, 49226, 
+    49231, 49236, 49241, 49246, 49251, 49256, 49261, 49266, 49271, 49276, 
+    49281, 49286, 49291, 49296, 49301, 49306, 42322, 42328, 49311, 42334, 
+    42340, 42346, 49316, 49321, 49326, 49331, 49336, 49341, 49346, 49351, 
+    49356, 49361, 49366, 49371, 49376, 49381, 49386, 49391, 49396, 49401, 
+    49406, 49411, 49416, 602, 49420, 27259, 49424, 33007, 24876, 49428, 
+    49432, 49436, 33959, 42581, 49440, 49444, 19743, 41909, 26427, 49448, 
+    49452, 49456, 41225, 32368, 40451, 49460, 49464, 49468, 32638, 49472, 
+    49476, 49480, 39395, 39797, 45837, 49484, 49488, 49492, 22282, 49496, 
+    49500, 49504, 38858, 41069, 49508, 18601, 49512, 49516, 49520, 28969, 
+    49524, 49528, 49532, 49536, 39473, 45832, 49540, 33559, 27159, 45652, 
+    36268, 19197, 39737, 49544, 26570, 49548, 44277, 31081, 49552, 49556, 
+    49560, 49564, 30451, 38543, 49568, 29069, 40811, 49572, 37374, 48912, 
+    49576, 40895, 46937, 49580, 49584, 44857, 49588, 49592, 38914, 49596, 
+    43817, 23302, 45842, 49600, 49604, 49608, 49612, 260, 35095, 49616, 
+    49620, 25503, 49624, 49628, 39845, 49632, 30928, 40409, 49636, 49640, 
+    49644, 46227, 49648, 49652, 49656, 49660, 46067, 49664, 49668, 49672, 
+    49676, 49680, 47192, 49684, 49688, 49692, 49696, 49700, 46912, 33052, 
+    49704, 49708, 49712, 49716, 49720, 49724, 49728, 49732, 49736, 47732, 
+    33943, 49740, 49744, 49748, 49752, 49756, 49760, 49764, 48582, 49768, 
+    27439, 43055, 40319, 34151, 49772, 49776, 49780, 40481, 46457, 46462, 
+    49784, 46232, 39131, 49788, 49792, 49796, 49800, 45847, 36842, 49804, 
+    48442, 32125, 49808, 40523, 35775, 37332, 49812, 49816, 42239, 49820, 
+    37136, 24694, 45892, 38123, 49824, 49828, 49832, 49836, 48567, 49840, 
+    49844, 49848, 44827, 49852, 49856, 49860, 49864, 49868, 49872, 47727, 
+    46742, 49876, 38746, 49880, 49884, 49888, 49892, 49896, 49900, 49904, 
+    49908, 47742, 48307, 49912, 49916, 49920, 49924, 49928, 49932, 48877, 
+    31270, 37213, 48887, 49936, 22030, 49940, 1177, 48922, 48927, 29089, 
+    48712, 49944, 34047, 49948, 49952, 49956, 49960, 49964, 40493, 49968, 
+    49972, 37423, 45067, 49976, 49980, 37430, 43295, 49984, 49988, 40013, 
+    49992, 49996, 50000, 50004, 50008, 50012, 50016, 30739, 45667, 50020, 
+    45817, 38291, 34607, 50024, 50028, 50032, 50036, 50040, 50044, 50048, 
+    50052, 50056, 50060, 50064, 50068, 50072, 50076, 50080, 50084, 50088, 
+    50092, 50096, 31144, 50100, 50104, 50108, 50112, 50116, 50120, 50124, 
+    50128, 46342, 46347, 50132, 50136, 50140, 50144, 50148, 50152, 50156, 
+    50160, 46377, 50164, 40901, 43692, 50168, 50172, 42809, 50176, 50180, 
+    50184, 50188, 50192, 41159, 50196, 33079, 50200, 50204, 50208, 50212, 
+    50216, 50220, 50224, 50228, 50232, 46202, 44837, 44842, 46527, 50236, 
+    50240, 50244, 46587, 50248, 22750, 50252, 50256, 46637, 50260, 30748, 
+    50264, 50268, 50272, 50276, 50280, 35103, 50284, 50288, 50292, 50296, 
+    50300, 50304, 43972, 50308, 42257, 50312, 50316, 50320, 50324, 24898, 
+    50328, 32503, 50332, 50336, 33903, 50340, 50344, 50348, 41963, 50352, 
+    50356, 50360, 50364, 50368, 18447, 47747, 973, 50372, 50376, 50380, 
+    50384, 48587, 50388, 30289, 50392, 50396, 50400, 50404, 50408, 50412, 
+    50416, 50420, 50424, 50428, 50432, 48882, 50436, 50440, 50444, 50448, 
+    35671, 50452, 50456, 34495, 50460, 40031, 50464, 50468, 50472, 30325, 
+    50476, 42605, 50480, 38445, 50484, 50488, 50492, 50496, 50500, 50504, 
+    50508, 50512, 41417, 40487, 50516, 50520, 40403, 50524, 50528, 50532, 
+    50536, 50540, 47867, 50544, 47882, 47912, 50548, 50552, 50556, 48737, 
+    50560, 50564, 50568, 44287, 50572, 44617, 47972, 50576, 50580, 50584, 
+    42017, 50588, 49067, 34375, 42161, 50592, 50596, 43229, 31099, 40253, 
+    50600, 32989, 50604, 34559, 27229, 50608, 50612, 50616, 50620, 50624, 
+    50628, 50632, 50636, 50640, 50644, 50648, 50652, 50656, 50660, 50664, 
+    50668, 50672, 50676, 50680, 50684, 50688, 50692, 50696, 50700, 50704, 
+    50708, 50712, 50716, 50720, 50724, 50728, 50732, 50736, 50740, 50744, 
+    50748, 50752, 50756, 50760, 50764, 50768, 50772, 50776, 50780, 50784, 
+    50788, 50792, 50796, 50800, 50804, 50808, 50812, 50816, 50820, 50824, 
+    50828, 50832, 50836, 50840, 50844, 50848, 50852, 50856, 50860, 50864, 
+    50868, 50872, 50876, 50880, 50884, 50888, 50892, 50896, 50900, 50904, 
+    50908, 50912, 50916, 50920, 50924, 50928, 50932, 50936, 50940, 50944, 
+    50948, 50952, 50956, 50960, 50964, 50968, 50972, 50976, 50980, 50984, 
+    50988, 50992, 50996, 51000, 51004, 51008, 51012, 51016, 51020, 51024, 
+    51028, 51032, 51036, 51040, 51044, 51048, 51052, 51056, 51060, 51064, 
+    51068, 51072, 45597, 35295, 45607, 51076, 51080, 51084, 51088, 51092, 
+    51096, 51100, 32494, 51104, 51108, 45612, 51112, 51116, 45617, 51120, 
+    51124, 44587, 51128, 45627, 45632, 45637, 51132, 51136, 45642, 45647, 
+    45657, 45662, 44197, 45672, 51140, 51144, 51148, 45677, 47497, 45682, 
+    45687, 51152, 30100, 51156, 51160, 51164, 51168, 51172, 51176, 51180, 
+    51184, 51188, 51192, 45822, 51196, 51200, 51204, 51208, 51212, 36541, 
+    51216, 51220, 51224, 51228, 51232, 51236, 51240, 51244, 51248, 51252, 
+    51256, 51260, 51264, 51268, 51272, 51276, 25481, 51280, 51284, 35543, 
+    51288, 46052, 51292, 46057, 36135, 51296, 46062, 51300, 42071, 46072, 
+    39647, 51304, 46082, 46087, 46092, 46097, 46102, 46857, 51308, 51312, 
+    51316, 46107, 48447, 46112, 46122, 51320, 51324, 51328, 46127, 46132, 
+    44267, 46137, 46142, 46147, 51332, 51336, 51340, 51344, 51348, 51352, 
+    51356, 51360, 51364, 51368, 51372, 51376, 51380, 51384, 26339, 44552, 
+    51388, 51392, 51396, 51400, 41117, 51404, 51408, 51412, 51416, 51420, 
+    51424, 51428, 51432, 51436, 51440, 51444, 51448, 51452, 51456, 51460, 
+    51464, 51468, 51472, 51476, 51480, 51484, 51488, 51492, 51496, 51500, 
+    51504, 51508, 51512, 46327, 51516, 46332, 46337, 51520, 51524, 37010, 
+    46352, 51528, 46357, 51532, 51536, 51540, 46362, 51544, 46367, 46372, 
+    51548, 44342, 46382, 51552, 461, 51556, 44347, 46387, 46392, 46397, 
+    46402, 46407, 46412, 46417, 51560, 51564, 51568, 51572, 51576, 51580, 
+    44467, 29909, 45857, 45867, 30217, 35999, 51584, 51588, 45872, 45877, 
+    45882, 41939, 51592, 51596, 51600, 51604, 44117, 26394, 32359, 51608, 
+    51612, 51616, 51620, 51624, 51628, 34967, 51632, 51636, 51640, 51644, 
+    51648, 45887, 32431, 44812, 36975, 45902, 45907, 51652, 45912, 39683, 
+    44742, 44747, 44752, 51656, 51660, 51664, 51668, 51672, 51676, 51680, 
+    51684, 51688, 51692, 51696, 49142, 31198, 40751, 40643, 40763, 26405, 
+    45007, 51700, 41747, 36031, 48837, 51704, 51708, 51712, 51716, 51720, 
+    51724, 44452, 46917, 46922, 46927, 51728, 51732, 51736, 46932, 46942, 
+    51740, 46947, 46952, 46957, 44457, 46962, 51744, 46967, 47707, 46972, 
+    46977, 51748, 51752, 32089, 51756, 51760, 47067, 51764, 622, 51768, 
+    51772, 25426, 51776, 51780, 51784, 51788, 51792, 51796, 51800, 51804, 
+    51808, 51812, 51816, 51820, 22210, 51824, 51828, 51832, 51836, 51840, 
+    51844, 51848, 51852, 51856, 51860, 51864, 51868, 51872, 51876, 51880, 
+    51884, 51888, 51892, 51896, 51900, 51904, 51908, 29899, 46502, 51912, 
+    44317, 46512, 51916, 51920, 46517, 36331, 24777, 51924, 44832, 48847, 
+    51928, 51932, 51936, 46277, 51940, 46537, 46542, 51944, 51948, 51952, 
+    46547, 51956, 284, 46552, 46557, 46562, 44757, 46572, 46577, 46582, 
+    46592, 46597, 51960, 30460, 51964, 46607, 46612, 51968, 51972, 51976, 
+    51980, 51984, 51988, 51992, 51996, 52000, 46617, 52004, 52008, 52012, 
+    52016, 46622, 41891, 46632, 52020, 52024, 46642, 46647, 46652, 46657, 
+    46662, 38298, 46672, 52028, 46677, 52032, 46687, 52036, 42095, 52040, 
+    46692, 18190, 46702, 52044, 52048, 52052, 52056, 52060, 39815, 52064, 
+    40085, 22678, 22138, 52068, 46707, 52072, 46712, 52076, 33679, 52080, 
+    35871, 27879, 46717, 41429, 46722, 33407, 46732, 52084, 52088, 52092, 
+    52096, 52100, 52104, 52108, 46737, 43337, 46747, 52112, 52116, 52120, 
+    52124, 52128, 46752, 52132, 52136, 46757, 52140, 52144, 52148, 37661, 
+    52152, 52156, 52160, 52164, 43259, 43265, 52168, 52172, 52176, 19652, 
+    43001, 52180, 52184, 52188, 44187, 52192, 52196, 52200, 52204, 52208, 
+    52212, 52216, 52220, 52224, 48577, 52228, 52232, 41123, 52236, 52240, 
+    52244, 52248, 52252, 52256, 52260, 52264, 52268, 52272, 52276, 52280, 
+    52284, 52288, 52292, 52296, 52300, 52304, 52308, 52312, 52316, 52320, 
+    52324, 52328, 52332, 52336, 52340, 52344, 52348, 52352, 52356, 52360, 
+    52364, 52368, 52372, 52376, 52380, 52384, 52388, 52392, 52396, 52400, 
+    52404, 52408, 52412, 52416, 52420, 52424, 52428, 52432, 52436, 52440, 
+    52444, 47752, 33119, 52448, 47757, 41363, 47767, 29009, 35311, 52452, 
+    52456, 52460, 43073, 52464, 52468, 43792, 48332, 47777, 52472, 52476, 
+    52480, 52484, 52488, 48342, 47782, 47787, 47792, 47797, 52492, 52496, 
+    47802, 47807, 47812, 47817, 52500, 52504, 52508, 36063, 25514, 48602, 
+    52512, 52516, 48612, 48617, 52520, 52524, 52528, 48622, 52532, 52536, 
+    48627, 48632, 52540, 52544, 52548, 38648, 48642, 48647, 52552, 48652, 
+    52556, 30109, 52560, 44377, 52564, 48657, 52568, 48662, 48667, 48672, 
+    48677, 48682, 48687, 52572, 52576, 52580, 52584, 52588, 52592, 52596, 
+    52600, 52604, 52608, 52612, 48892, 48697, 52616, 52620, 52624, 52628, 
+    52632, 52636, 52640, 52644, 52648, 52652, 52656, 52660, 1955, 52664, 
+    52668, 52672, 52676, 52680, 52684, 52688, 52692, 52696, 52700, 52704, 
+    52708, 52712, 52716, 52720, 52724, 52728, 52732, 52736, 49167, 46257, 
+    52740, 52744, 27869, 52748, 52752, 45062, 29329, 40769, 40775, 33687, 
+    37276, 52756, 34447, 52760, 52764, 52768, 52772, 52776, 52780, 52784, 
+    52788, 52792, 52796, 52800, 52804, 52808, 52812, 52816, 52820, 52824, 
+    52828, 52832, 52836, 52840, 52844, 52848, 52852, 52856, 52860, 52864, 
+    52868, 52872, 52876, 52880, 52884, 52888, 52892, 52896, 47112, 47117, 
+    46807, 46812, 44422, 46817, 52900, 44427, 52904, 46822, 46827, 44432, 
+    47122, 47127, 47132, 52908, 52912, 52916, 52920, 52924, 52928, 52932, 
+    52936, 52940, 52944, 52948, 52952, 52956, 37626, 52960, 52964, 52968, 
+    44382, 52972, 52976, 52980, 52984, 52988, 52992, 47862, 52996, 44607, 
+    47872, 47877, 44612, 47887, 53000, 47892, 47897, 53004, 47902, 47907, 
+    53008, 53012, 53016, 53020, 53024, 47917, 47922, 47927, 49342, 47932, 
+    53028, 47937, 47942, 47947, 47952, 53032, 48962, 53036, 47957, 47962, 
+    53040, 47967, 53044, 47977, 48747, 47982, 47987, 47992, 47997, 53048, 
+    42474, 36675, 1086, 19640, 49781, 603, 39492, 28980, 27870, 33560, 5572, 
+    19198, 53052, 53055, 53058, 31190, 33296, 4804, 5060, 32504, 50381, 
+    45013, 53061, 37438, 39864, 50369, 32288, 38138, 49533, 5316, 53064, 
+    26516, 53067, 36955, 53070, 36731, 49589, 29110, 50293, 43224, 40230, 
+    974, 53073, 10931, 53076, 24899, 53079, 44743, 34008, 651, 38544, 42522, 
+    31910, 1419, 672, 4868, 6084, 51633, 18896, 49108, 53082, 26571, 23315, 
+    44553, 44748, 51669, 49757, 37704, 23111, 53085, 45893, 22643, 800, 
+    18938, 764, 40410, 44053, 991, 40086, 1155, 38446, 53088, 53091, 23171, 
+    53094, 41826, 28910, 25130, 41046, 32198, 53097, 38642, 23435, 40032, 
+    43290, 53100, 53103, 53106, 53109, 42018, 53112, 51185, 22679, 53115, 
+    22703, 37662, 53118, 53121, 53124, 22139, 53127, 43170, 35872, 25427, 
+    30929, 53130, 53133, 42468, 53136, 5124, 51093, 51305, 38992, 53139, 
+    30452, 50185, 53142, 11036, 27850, 36899, 51661, 31145, 53145, 38761, 
+    51089, 53148, 30479, 26582, 22391, 40218, 37270, 37851, 1127, 10756, 
+    53151, 298, 40518, 51657, 49208, 53154, 41988, 50001, 18951, 24695, 5908, 
+    27900, 19445, 34040, 50189, 22583, 53157, 53160, 53163, 33152, 53166, 
+    18448, 33080, 51085, 53169, 36000, 33800, 39936, 53172, 53175, 53178, 
+    29260, 36710, 53181, 53184, 18378, 53187, 36997, 43134, 53190, 12, 53193, 
+    53196, 5380, 51181, 49553, 53199, 39600, 31028, 623, 36096, 6148, 53202, 
+    53205, 53208, 53211, 33008, 1091, 34120, 53214, 53217, 22739, 53220, 
+    37543, 22451, 53223, 51961, 49168, 53226, 24659, 34112, 51097, 53229, 
+    51189, 28000, 53232, 53235, 53238, 32495, 36339, 50501, 53241, 40686, 
+    53244, 53247, 53250, 53253, 53256, 53259, 42594, 53262, 53265, 53268, 
+    53271, 53274, 53277, 53280, 52541, 53283, 26989, 31019, 53286, 53289, 
+    53292, 53295, 53298, 45888, 51377, 53301, 1178, 285, 53304, 53307, 53310, 
+    26329, 53313, 52673, 53316, 37144, 35760, 53319, 50621, 51393, 53322, 
+    18131, 53325, 4676, 4692, 48873, 53328, 30461, 50525, 24683, 45608, 
+    53331, 53334, 53337, 27440, 5348, 5364, 1476, 53340, 53343, 5588, 53346, 
+    53349, 53352, 53355, 53358, 47158, 24778, 6164, 51429, 53361, 53364, 
+    53367, 51357, 324, 53370, 53373, 53376, 53379, 51541, 38943, 27530, 
+    26395, 40254, 53382, 26384, 1082, 50193, 53385, 42006, 794, 53388, 53391, 
+    53394, 53397, 53400, 53403, 53406, 53409, 53412, 45003, 53415, 52657, 
+    53418, 786, 53421, 40068, 53424, 53427, 53430, 53433, 53436, 53439, 
+    53442, 53445, 45053, 53448, 53451, 44513, 53454, 53457, 53460, 40500, 
+    53463, 53466, 53469, 40776, 29340, 53472, 53475, 53478, 1972, 52233, 
+    53481, 53484, 41154, 53487, 53490, 45998, 53493, 53496, 53499, 53502, 
+    53505, 30011, 53508, 53511, 53514, 37557, 52557, 53517, 53520, 53523, 
+    53526, 40092, 53529, 53532, 18868, 44348, 1032, 46868, 53535, 53538, 
+    39336, 53541, 46773, 53544, 51149, 51881, 53547, 53550, 45813, 53553, 
+    44153, 53556, 52161, 19407, 416, 286, 38237, 1316, 2325, 39973, 21, 38, 
+    32694, 50274, 53559, 30075, 53561, 320, 36305, 53563, 36235, 42469, 
+    49918, 213, 44189, 53565, 479, 34049, 53518, 53567, 919, 40093, 42079, 
+    316, 395, 53569, 885, 30651, 204, 53571, 53329, 53573, 53575, 4, 27891, 
+    1102, 43604, 1115, 36466, 53577, 53579, 24834, 892, 50538, 373, 53200, 
+    771, 88, 51526, 703, 53581, 351, 106, 44484, 53116, 39793, 24867, 39325, 
+    53583, 53585, 35145, 49498, 53587, 53589, 53591, 25164, 43679, 53593, 
+    53595, 34617, 51966, 53597, 8, 1056, 554, 998, 36034, 39, 98, 14, 5, 161, 
+    102, 317, 70, 9, 52, 321, 34, 53225, 401, 171, 404, 523, 53599, 53600, 
+};
+
+/* code->name phrasebook */
+#define phrasebook_shift 7
+#define phrasebook_short 226
+static unsigned char phrasebook[] = {
+    0, 240, 15, 233, 54, 69, 235, 51, 69, 61, 52, 240, 114, 52, 238, 107, 52, 
+    234, 17, 233, 59, 40, 232, 74, 38, 232, 74, 235, 52, 248, 49, 52, 240, 
+    27, 231, 94, 248, 37, 208, 236, 177, 26, 242, 217, 26, 127, 26, 111, 26, 
+    166, 26, 177, 26, 176, 26, 187, 26, 203, 26, 195, 26, 202, 240, 24, 234, 
+    14, 235, 44, 52, 240, 7, 52, 232, 68, 52, 236, 156, 69, 234, 20, 254, 20, 
+    8, 5, 1, 67, 8, 5, 1, 217, 8, 5, 1, 255, 18, 8, 5, 1, 209, 8, 5, 1, 72, 
+    8, 5, 1, 255, 19, 8, 5, 1, 210, 8, 5, 1, 192, 8, 5, 1, 71, 8, 5, 1, 221, 
+    8, 5, 1, 255, 15, 8, 5, 1, 162, 8, 5, 1, 173, 8, 5, 1, 197, 8, 5, 1, 73, 
+    8, 5, 1, 223, 8, 5, 1, 255, 20, 8, 5, 1, 144, 8, 5, 1, 193, 8, 5, 1, 214, 
+    8, 5, 1, 79, 8, 5, 1, 179, 8, 5, 1, 255, 16, 8, 5, 1, 206, 8, 5, 1, 255, 
+    14, 8, 5, 1, 255, 17, 40, 31, 104, 238, 75, 236, 177, 38, 31, 104, 190, 
+    238, 54, 170, 242, 224, 242, 245, 238, 54, 8, 3, 1, 67, 8, 3, 1, 217, 8, 
+    3, 1, 255, 18, 8, 3, 1, 209, 8, 3, 1, 72, 8, 3, 1, 255, 19, 8, 3, 1, 210, 
+    8, 3, 1, 192, 8, 3, 1, 71, 8, 3, 1, 221, 8, 3, 1, 255, 15, 8, 3, 1, 162, 
+    8, 3, 1, 173, 8, 3, 1, 197, 8, 3, 1, 73, 8, 3, 1, 223, 8, 3, 1, 255, 20, 
+    8, 3, 1, 144, 8, 3, 1, 193, 8, 3, 1, 214, 8, 3, 1, 79, 8, 3, 1, 179, 8, 
+    3, 1, 255, 16, 8, 3, 1, 206, 8, 3, 1, 255, 14, 8, 3, 1, 255, 17, 40, 242, 
+    225, 104, 59, 242, 224, 38, 242, 225, 104, 169, 236, 233, 240, 15, 236, 
+    145, 233, 54, 69, 249, 39, 52, 243, 246, 52, 236, 181, 52, 254, 134, 52, 
+    240, 129, 125, 238, 213, 52, 175, 235, 195, 52, 237, 9, 238, 205, 234, 
+    30, 231, 87, 45, 185, 235, 51, 69, 161, 52, 248, 186, 238, 93, 234, 245, 
+    52, 196, 240, 112, 52, 234, 236, 52, 233, 49, 111, 233, 49, 166, 242, 
+    241, 238, 54, 246, 81, 52, 238, 208, 52, 240, 1, 248, 40, 236, 151, 233, 
+    49, 127, 236, 58, 238, 205, 234, 30, 231, 36, 45, 185, 235, 51, 69, 240, 
+    30, 236, 155, 253, 125, 237, 33, 240, 30, 236, 155, 253, 125, 243, 7, 
+    240, 30, 236, 155, 204, 236, 84, 236, 145, 236, 156, 69, 8, 5, 1, 134, 2, 
+    191, 8, 5, 1, 134, 2, 135, 8, 5, 1, 134, 2, 233, 48, 8, 5, 1, 134, 2, 
+    169, 8, 5, 1, 134, 2, 175, 8, 5, 1, 134, 2, 248, 51, 48, 8, 5, 1, 253, 
+    178, 8, 5, 1, 255, 105, 2, 236, 151, 8, 5, 1, 157, 2, 191, 8, 5, 1, 157, 
+    2, 135, 8, 5, 1, 157, 2, 233, 48, 8, 5, 1, 157, 2, 175, 8, 5, 1, 220, 2, 
+    191, 8, 5, 1, 220, 2, 135, 8, 5, 1, 220, 2, 233, 48, 8, 5, 1, 220, 2, 
+    175, 8, 5, 1, 248, 109, 8, 5, 1, 255, 98, 2, 169, 8, 5, 1, 117, 2, 191, 
+    8, 5, 1, 117, 2, 135, 8, 5, 1, 117, 2, 233, 48, 8, 5, 1, 117, 2, 169, 8, 
+    5, 1, 117, 2, 175, 231, 37, 52, 8, 5, 1, 117, 2, 108, 8, 5, 1, 132, 2, 
+    191, 8, 5, 1, 132, 2, 135, 8, 5, 1, 132, 2, 233, 48, 8, 5, 1, 132, 2, 
+    175, 8, 5, 1, 255, 107, 2, 135, 8, 5, 1, 240, 149, 8, 3, 1, 243, 74, 193, 
+    8, 3, 1, 134, 2, 191, 8, 3, 1, 134, 2, 135, 8, 3, 1, 134, 2, 233, 48, 8, 
+    3, 1, 134, 2, 169, 8, 3, 1, 134, 2, 175, 8, 3, 1, 134, 2, 248, 51, 48, 8, 
+    3, 1, 253, 178, 8, 3, 1, 255, 105, 2, 236, 151, 8, 3, 1, 157, 2, 191, 8, 
+    3, 1, 157, 2, 135, 8, 3, 1, 157, 2, 233, 48, 8, 3, 1, 157, 2, 175, 8, 3, 
+    1, 220, 2, 191, 8, 3, 1, 220, 2, 135, 8, 3, 1, 220, 2, 233, 48, 8, 3, 1, 
+    220, 2, 175, 8, 3, 1, 248, 109, 8, 3, 1, 255, 98, 2, 169, 8, 3, 1, 117, 
+    2, 191, 8, 3, 1, 117, 2, 135, 8, 3, 1, 117, 2, 233, 48, 8, 3, 1, 117, 2, 
+    169, 8, 3, 1, 117, 2, 175, 236, 196, 52, 8, 3, 1, 117, 2, 108, 8, 3, 1, 
+    132, 2, 191, 8, 3, 1, 132, 2, 135, 8, 3, 1, 132, 2, 233, 48, 8, 3, 1, 
+    132, 2, 175, 8, 3, 1, 255, 107, 2, 135, 8, 3, 1, 240, 149, 8, 3, 1, 255, 
+    107, 2, 175, 8, 5, 1, 134, 2, 196, 8, 3, 1, 134, 2, 196, 8, 5, 1, 134, 2, 
+    239, 255, 8, 3, 1, 134, 2, 239, 255, 8, 5, 1, 134, 2, 238, 71, 8, 3, 1, 
+    134, 2, 238, 71, 8, 5, 1, 255, 105, 2, 135, 8, 3, 1, 255, 105, 2, 135, 8, 
+    5, 1, 255, 105, 2, 233, 48, 8, 3, 1, 255, 105, 2, 233, 48, 8, 5, 1, 255, 
+    105, 2, 53, 48, 8, 3, 1, 255, 105, 2, 53, 48, 8, 5, 1, 255, 105, 2, 239, 
+    254, 8, 3, 1, 255, 105, 2, 239, 254, 8, 5, 1, 255, 103, 2, 239, 254, 8, 
+    3, 1, 255, 103, 2, 239, 254, 8, 5, 1, 255, 103, 2, 108, 8, 3, 1, 255, 
+    103, 2, 108, 8, 5, 1, 157, 2, 196, 8, 3, 1, 157, 2, 196, 8, 5, 1, 157, 2, 
+    239, 255, 8, 3, 1, 157, 2, 239, 255, 8, 5, 1, 157, 2, 53, 48, 8, 3, 1, 
+    157, 2, 53, 48, 8, 5, 1, 157, 2, 238, 71, 8, 3, 1, 157, 2, 238, 71, 8, 5, 
+    1, 157, 2, 239, 254, 8, 3, 1, 157, 2, 239, 254, 8, 5, 1, 255, 104, 2, 
+    233, 48, 8, 3, 1, 255, 104, 2, 233, 48, 8, 5, 1, 255, 104, 2, 239, 255, 
+    8, 3, 1, 255, 104, 2, 239, 255, 8, 5, 1, 255, 104, 2, 53, 48, 8, 3, 1, 
+    255, 104, 2, 53, 48, 8, 5, 1, 255, 104, 2, 236, 151, 8, 3, 1, 255, 104, 
+    2, 236, 151, 8, 5, 1, 255, 106, 2, 233, 48, 8, 3, 1, 255, 106, 2, 233, 
+    48, 8, 5, 1, 255, 106, 2, 108, 8, 3, 1, 255, 106, 2, 108, 8, 5, 1, 220, 
+    2, 169, 8, 3, 1, 220, 2, 169, 8, 5, 1, 220, 2, 196, 8, 3, 1, 220, 2, 196, 
+    8, 5, 1, 220, 2, 239, 255, 8, 3, 1, 220, 2, 239, 255, 8, 5, 1, 220, 2, 
+    238, 71, 8, 3, 1, 220, 2, 238, 71, 8, 5, 1, 220, 2, 53, 48, 8, 3, 1, 238, 
+    70, 71, 8, 5, 18, 254, 99, 8, 3, 18, 254, 99, 8, 5, 1, 255, 115, 2, 233, 
+    48, 8, 3, 1, 255, 115, 2, 233, 48, 8, 5, 1, 255, 109, 2, 236, 151, 8, 3, 
+    1, 255, 109, 2, 236, 151, 8, 3, 1, 251, 164, 8, 5, 1, 255, 100, 2, 135, 
+    8, 3, 1, 255, 100, 2, 135, 8, 5, 1, 255, 100, 2, 236, 151, 8, 3, 1, 255, 
+    100, 2, 236, 151, 8, 5, 1, 255, 100, 2, 239, 254, 8, 3, 1, 255, 100, 2, 
+    239, 254, 8, 5, 1, 255, 100, 2, 240, 1, 248, 40, 8, 3, 1, 255, 100, 2, 
+    240, 1, 248, 40, 8, 5, 1, 255, 100, 2, 108, 8, 3, 1, 255, 100, 2, 108, 8, 
+    5, 1, 255, 98, 2, 135, 8, 3, 1, 255, 98, 2, 135, 8, 5, 1, 255, 98, 2, 
+    236, 151, 8, 3, 1, 255, 98, 2, 236, 151, 8, 5, 1, 255, 98, 2, 239, 254, 
+    8, 3, 1, 255, 98, 2, 239, 254, 8, 3, 1, 255, 98, 237, 241, 255, 25, 233, 
+    59, 8, 5, 1, 248, 108, 8, 3, 1, 248, 108, 8, 5, 1, 117, 2, 196, 8, 3, 1, 
+    117, 2, 196, 8, 5, 1, 117, 2, 239, 255, 8, 3, 1, 117, 2, 239, 255, 8, 5, 
+    1, 117, 2, 45, 135, 8, 3, 1, 117, 2, 45, 135, 8, 5, 18, 253, 193, 8, 3, 
+    18, 253, 193, 8, 5, 1, 255, 101, 2, 135, 8, 3, 1, 255, 101, 2, 135, 8, 5, 
+    1, 255, 101, 2, 236, 151, 8, 3, 1, 255, 101, 2, 236, 151, 8, 5, 1, 255, 
+    101, 2, 239, 254, 8, 3, 1, 255, 101, 2, 239, 254, 8, 5, 1, 255, 99, 2, 
+    135, 8, 3, 1, 255, 99, 2, 135, 8, 5, 1, 255, 99, 2, 233, 48, 8, 3, 1, 
+    255, 99, 2, 233, 48, 8, 5, 1, 255, 99, 2, 236, 151, 8, 3, 1, 255, 99, 2, 
+    236, 151, 8, 5, 1, 255, 99, 2, 239, 254, 8, 3, 1, 255, 99, 2, 239, 254, 
+    8, 5, 1, 255, 102, 2, 236, 151, 8, 3, 1, 255, 102, 2, 236, 151, 8, 5, 1, 
+    255, 102, 2, 239, 254, 8, 3, 1, 255, 102, 2, 239, 254, 8, 5, 1, 255, 102, 
+    2, 108, 8, 3, 1, 255, 102, 2, 108, 8, 5, 1, 132, 2, 169, 8, 3, 1, 132, 2, 
+    169, 8, 5, 1, 132, 2, 196, 8, 3, 1, 132, 2, 196, 8, 5, 1, 132, 2, 239, 
+    255, 8, 3, 1, 132, 2, 239, 255, 8, 5, 1, 132, 2, 248, 51, 48, 8, 3, 1, 
+    132, 2, 248, 51, 48, 8, 5, 1, 132, 2, 45, 135, 8, 3, 1, 132, 2, 45, 135, 
+    8, 5, 1, 132, 2, 238, 71, 8, 3, 1, 132, 2, 238, 71, 8, 5, 1, 255, 111, 2, 
+    233, 48, 8, 3, 1, 255, 111, 2, 233, 48, 8, 5, 1, 255, 107, 2, 233, 48, 8, 
+    3, 1, 255, 107, 2, 233, 48, 8, 5, 1, 255, 107, 2, 175, 8, 5, 1, 255, 97, 
+    2, 135, 8, 3, 1, 255, 97, 2, 135, 8, 5, 1, 255, 97, 2, 53, 48, 8, 3, 1, 
+    255, 97, 2, 53, 48, 8, 5, 1, 255, 97, 2, 239, 254, 8, 3, 1, 255, 97, 2, 
+    239, 254, 8, 3, 1, 183, 193, 8, 3, 1, 41, 2, 108, 8, 5, 1, 41, 2, 90, 8, 
+    5, 1, 41, 2, 238, 124, 8, 3, 1, 41, 2, 238, 124, 8, 5, 1, 188, 187, 8, 3, 
+    1, 188, 187, 8, 5, 1, 248, 35, 73, 8, 5, 1, 255, 105, 2, 90, 8, 3, 1, 
+    255, 105, 2, 90, 8, 5, 1, 238, 238, 209, 8, 5, 1, 255, 103, 2, 90, 8, 5, 
+    1, 255, 103, 2, 238, 124, 8, 3, 1, 255, 103, 2, 238, 124, 8, 3, 1, 205, 
+    240, 28, 8, 5, 1, 224, 72, 8, 5, 1, 240, 86, 8, 5, 1, 248, 35, 72, 8, 5, 
+    1, 255, 112, 2, 90, 8, 3, 1, 255, 112, 2, 90, 8, 5, 1, 255, 104, 2, 90, 
+    8, 5, 1, 240, 10, 8, 3, 1, 254, 98, 8, 5, 1, 242, 237, 8, 5, 1, 220, 2, 
+    108, 8, 5, 1, 255, 109, 2, 90, 8, 3, 1, 255, 109, 2, 90, 8, 3, 1, 255, 
+    100, 2, 125, 8, 3, 1, 241, 212, 2, 108, 8, 5, 1, 205, 173, 8, 5, 1, 255, 
+    98, 2, 40, 90, 8, 3, 1, 255, 98, 2, 183, 38, 248, 117, 8, 5, 1, 117, 2, 
+    240, 1, 169, 8, 5, 1, 117, 2, 243, 8, 8, 3, 1, 117, 2, 243, 8, 8, 5, 1, 
+    254, 42, 8, 3, 1, 254, 42, 8, 5, 1, 255, 114, 2, 90, 8, 3, 1, 255, 114, 
+    2, 90, 8, 1, 254, 135, 8, 5, 1, 188, 111, 8, 3, 1, 188, 111, 8, 5, 1, 
+    248, 93, 8, 1, 224, 254, 38, 243, 105, 8, 3, 1, 255, 102, 2, 238, 65, 90, 
+    8, 5, 1, 255, 102, 2, 90, 8, 3, 1, 255, 102, 2, 90, 8, 5, 1, 255, 102, 2, 
+    235, 54, 90, 8, 5, 1, 132, 2, 243, 8, 8, 3, 1, 132, 2, 243, 8, 8, 5, 1, 
+    236, 160, 8, 5, 1, 255, 110, 2, 90, 8, 5, 1, 255, 107, 2, 90, 8, 3, 1, 
+    255, 107, 2, 90, 8, 5, 1, 255, 97, 2, 108, 8, 3, 1, 255, 97, 2, 108, 8, 
+    5, 1, 248, 155, 8, 5, 1, 253, 244, 235, 142, 8, 3, 1, 253, 244, 235, 142, 
+    8, 3, 1, 253, 244, 2, 242, 226, 8, 1, 171, 2, 108, 8, 5, 1, 188, 176, 8, 
+    3, 1, 188, 176, 8, 1, 236, 145, 238, 62, 248, 119, 2, 108, 8, 1, 244, 54, 
+    8, 1, 241, 82, 240, 93, 8, 1, 239, 114, 240, 93, 8, 1, 237, 59, 240, 93, 
+    8, 1, 235, 54, 240, 93, 8, 5, 1, 255, 40, 2, 239, 254, 8, 5, 1, 255, 103, 
+    2, 3, 1, 255, 97, 2, 239, 254, 8, 3, 1, 255, 40, 2, 239, 254, 8, 5, 1, 
+    254, 109, 8, 5, 1, 255, 100, 2, 3, 1, 221, 8, 3, 1, 254, 109, 8, 5, 1, 
+    254, 113, 8, 5, 1, 255, 98, 2, 3, 1, 221, 8, 3, 1, 254, 113, 8, 5, 1, 
+    134, 2, 239, 254, 8, 3, 1, 134, 2, 239, 254, 8, 5, 1, 220, 2, 239, 254, 
+    8, 3, 1, 220, 2, 239, 254, 8, 5, 1, 117, 2, 239, 254, 8, 3, 1, 117, 2, 
+    239, 254, 8, 5, 1, 132, 2, 239, 254, 8, 3, 1, 132, 2, 239, 254, 8, 5, 1, 
+    132, 2, 235, 56, 19, 196, 8, 3, 1, 132, 2, 235, 56, 19, 196, 8, 5, 1, 
+    132, 2, 235, 56, 19, 135, 8, 3, 1, 132, 2, 235, 56, 19, 135, 8, 5, 1, 
+    132, 2, 235, 56, 19, 239, 254, 8, 3, 1, 132, 2, 235, 56, 19, 239, 254, 8, 
+    5, 1, 132, 2, 235, 56, 19, 191, 8, 3, 1, 132, 2, 235, 56, 19, 191, 8, 3, 
+    1, 205, 72, 8, 5, 1, 134, 2, 235, 56, 19, 196, 8, 3, 1, 134, 2, 235, 56, 
+    19, 196, 8, 5, 1, 134, 2, 53, 60, 19, 196, 8, 3, 1, 134, 2, 53, 60, 19, 
+    196, 8, 5, 1, 255, 30, 2, 196, 8, 3, 1, 255, 30, 2, 196, 8, 5, 1, 255, 
+    104, 2, 108, 8, 3, 1, 255, 104, 2, 108, 8, 5, 1, 255, 104, 2, 239, 254, 
+    8, 3, 1, 255, 104, 2, 239, 254, 8, 5, 1, 255, 109, 2, 239, 254, 8, 3, 1, 
+    255, 109, 2, 239, 254, 8, 5, 1, 117, 2, 238, 71, 8, 3, 1, 117, 2, 238, 
+    71, 8, 5, 1, 117, 2, 240, 204, 19, 196, 8, 3, 1, 117, 2, 240, 204, 19, 
+    196, 8, 5, 1, 253, 244, 2, 239, 254, 8, 3, 1, 253, 244, 2, 239, 254, 8, 
+    3, 1, 255, 115, 2, 239, 254, 8, 5, 1, 254, 88, 8, 5, 1, 255, 103, 2, 3, 
+    1, 255, 17, 8, 3, 1, 254, 88, 8, 5, 1, 255, 104, 2, 135, 8, 3, 1, 255, 
+    104, 2, 135, 8, 5, 1, 240, 190, 8, 5, 1, 244, 54, 8, 5, 1, 255, 98, 2, 
+    191, 8, 3, 1, 255, 98, 2, 191, 8, 5, 1, 134, 2, 248, 51, 60, 19, 135, 8, 
+    3, 1, 134, 2, 248, 51, 60, 19, 135, 8, 5, 1, 255, 30, 2, 135, 8, 3, 1, 
+    255, 30, 2, 135, 8, 5, 1, 117, 2, 240, 5, 19, 135, 8, 3, 1, 117, 2, 240, 
+    5, 19, 135, 8, 5, 1, 134, 2, 45, 191, 8, 3, 1, 134, 2, 45, 191, 8, 5, 1, 
+    134, 2, 236, 145, 239, 255, 8, 3, 1, 134, 2, 236, 145, 239, 255, 8, 5, 1, 
+    157, 2, 45, 191, 8, 3, 1, 157, 2, 45, 191, 8, 5, 1, 157, 2, 236, 145, 
+    239, 255, 8, 3, 1, 157, 2, 236, 145, 239, 255, 8, 5, 1, 220, 2, 45, 191, 
+    8, 3, 1, 220, 2, 45, 191, 8, 5, 1, 220, 2, 236, 145, 239, 255, 8, 3, 1, 
+    220, 2, 236, 145, 239, 255, 8, 5, 1, 117, 2, 45, 191, 8, 3, 1, 117, 2, 
+    45, 191, 8, 5, 1, 117, 2, 236, 145, 239, 255, 8, 3, 1, 117, 2, 236, 145, 
+    239, 255, 8, 5, 1, 255, 101, 2, 45, 191, 8, 3, 1, 255, 101, 2, 45, 191, 
+    8, 5, 1, 255, 101, 2, 236, 145, 239, 255, 8, 3, 1, 255, 101, 2, 236, 145, 
+    239, 255, 8, 5, 1, 132, 2, 45, 191, 8, 3, 1, 132, 2, 45, 191, 8, 5, 1, 
+    132, 2, 236, 145, 239, 255, 8, 3, 1, 132, 2, 236, 145, 239, 255, 8, 5, 1, 
+    255, 99, 2, 242, 244, 46, 8, 3, 1, 255, 99, 2, 242, 244, 46, 8, 5, 1, 
+    255, 102, 2, 242, 244, 46, 8, 3, 1, 255, 102, 2, 242, 244, 46, 8, 5, 1, 
+    244, 59, 8, 3, 1, 244, 59, 8, 5, 1, 255, 106, 2, 239, 254, 8, 3, 1, 255, 
+    106, 2, 239, 254, 8, 5, 1, 255, 98, 2, 183, 38, 248, 117, 8, 3, 1, 255, 
+    103, 2, 242, 253, 8, 5, 1, 254, 10, 8, 3, 1, 254, 10, 8, 5, 1, 255, 97, 
+    2, 90, 8, 3, 1, 255, 97, 2, 90, 8, 5, 1, 134, 2, 53, 48, 8, 3, 1, 134, 2, 
+    53, 48, 8, 5, 1, 157, 2, 236, 151, 8, 3, 1, 157, 2, 236, 151, 8, 5, 1, 
+    117, 2, 235, 56, 19, 196, 8, 3, 1, 117, 2, 235, 56, 19, 196, 8, 5, 1, 
+    117, 2, 242, 219, 19, 196, 8, 3, 1, 117, 2, 242, 219, 19, 196, 8, 5, 1, 
+    117, 2, 53, 48, 8, 3, 1, 117, 2, 53, 48, 8, 5, 1, 117, 2, 53, 60, 19, 
+    196, 8, 3, 1, 117, 2, 53, 60, 19, 196, 8, 5, 1, 255, 107, 2, 196, 8, 3, 
+    1, 255, 107, 2, 196, 8, 3, 1, 255, 100, 2, 242, 253, 8, 3, 1, 255, 98, 2, 
+    242, 253, 8, 3, 1, 255, 102, 2, 242, 253, 8, 3, 1, 238, 70, 221, 8, 3, 1, 
+    255, 71, 236, 182, 8, 3, 1, 255, 89, 236, 182, 8, 5, 1, 134, 2, 108, 8, 
+    5, 1, 255, 105, 2, 108, 8, 3, 1, 255, 105, 2, 108, 8, 5, 1, 255, 100, 2, 
+    125, 8, 5, 1, 255, 102, 2, 236, 159, 108, 8, 3, 1, 255, 99, 2, 243, 126, 
+    242, 226, 8, 3, 1, 255, 97, 2, 243, 126, 242, 226, 8, 5, 1, 238, 62, 208, 
+    8, 3, 1, 205, 67, 8, 3, 1, 240, 22, 8, 3, 1, 205, 240, 22, 8, 3, 1, 41, 
+    2, 90, 8, 3, 1, 248, 35, 73, 8, 3, 1, 255, 105, 2, 242, 253, 8, 3, 1, 
+    255, 103, 2, 242, 226, 8, 3, 1, 255, 103, 2, 90, 8, 3, 1, 224, 72, 8, 3, 
+    1, 240, 86, 8, 3, 1, 243, 73, 2, 90, 8, 3, 1, 248, 35, 72, 8, 3, 1, 224, 
+    248, 35, 72, 8, 3, 1, 224, 248, 35, 157, 2, 90, 8, 3, 1, 240, 23, 224, 
+    248, 35, 72, 8, 3, 1, 238, 70, 255, 115, 2, 108, 8, 3, 1, 255, 104, 2, 
+    90, 8, 3, 1, 84, 210, 8, 1, 3, 5, 210, 8, 3, 1, 240, 10, 8, 3, 1, 252, 
+    129, 243, 8, 8, 3, 1, 205, 192, 8, 3, 1, 255, 106, 2, 90, 8, 3, 1, 251, 
+    52, 2, 90, 8, 3, 1, 220, 2, 108, 8, 3, 1, 242, 237, 8, 1, 3, 5, 71, 8, 3, 
+    1, 255, 100, 2, 240, 1, 169, 8, 3, 1, 255, 100, 2, 244, 216, 8, 3, 1, 
+    255, 100, 2, 235, 54, 90, 8, 3, 1, 246, 43, 8, 3, 1, 205, 173, 8, 3, 1, 
+    205, 255, 108, 2, 183, 248, 117, 8, 3, 1, 255, 108, 2, 90, 8, 3, 1, 255, 
+    98, 2, 40, 90, 8, 3, 1, 255, 98, 2, 235, 54, 90, 8, 1, 3, 5, 197, 8, 3, 
+    1, 240, 60, 73, 8, 1, 3, 5, 253, 193, 8, 3, 1, 240, 23, 240, 20, 8, 3, 1, 
+    248, 68, 8, 3, 1, 205, 144, 8, 3, 1, 205, 255, 101, 2, 183, 248, 117, 8, 
+    3, 1, 205, 255, 101, 2, 90, 8, 3, 1, 255, 101, 2, 183, 248, 117, 8, 3, 1, 
+    255, 101, 2, 242, 226, 8, 3, 1, 255, 101, 2, 235, 100, 8, 3, 1, 224, 255, 
+    101, 2, 235, 100, 8, 1, 3, 5, 144, 8, 1, 3, 5, 236, 145, 144, 8, 3, 1, 
+    255, 99, 2, 90, 8, 3, 1, 248, 93, 8, 3, 1, 238, 70, 255, 115, 2, 240, 5, 
+    19, 90, 8, 3, 1, 244, 23, 224, 248, 93, 8, 3, 1, 254, 38, 2, 242, 253, 8, 
+    3, 1, 205, 214, 8, 3, 1, 255, 102, 2, 235, 54, 90, 8, 3, 1, 132, 125, 8, 
+    3, 1, 236, 160, 8, 3, 1, 255, 110, 2, 90, 8, 3, 1, 205, 179, 8, 3, 1, 
+    205, 255, 16, 8, 3, 1, 205, 255, 14, 8, 1, 3, 5, 255, 14, 8, 3, 1, 255, 
+    97, 2, 235, 54, 90, 8, 3, 1, 255, 97, 2, 242, 253, 8, 3, 1, 248, 155, 8, 
+    3, 1, 253, 244, 2, 242, 253, 8, 1, 238, 62, 208, 8, 1, 234, 12, 240, 59, 
+    234, 192, 8, 1, 236, 145, 238, 62, 208, 8, 1, 236, 110, 255, 18, 8, 1, 
+    236, 249, 240, 93, 8, 1, 3, 5, 217, 8, 3, 1, 240, 23, 248, 35, 72, 8, 1, 
+    3, 5, 255, 104, 2, 90, 8, 1, 3, 5, 192, 8, 3, 1, 255, 115, 2, 231, 101, 
+    8, 3, 1, 205, 255, 15, 8, 1, 3, 5, 162, 8, 3, 1, 255, 116, 2, 90, 8, 1, 
+    238, 62, 248, 119, 2, 108, 8, 1, 224, 238, 62, 248, 119, 2, 108, 8, 3, 1, 
+    255, 40, 236, 182, 8, 3, 1, 250, 192, 236, 182, 8, 3, 1, 255, 40, 238, 
+    112, 2, 242, 253, 8, 3, 1, 255, 94, 236, 182, 8, 3, 1, 252, 215, 236, 
+    182, 8, 3, 1, 255, 92, 238, 112, 2, 242, 253, 8, 3, 1, 250, 239, 236, 
+    182, 8, 3, 1, 255, 78, 236, 182, 8, 3, 1, 255, 79, 236, 182, 8, 1, 236, 
+    249, 233, 95, 8, 1, 237, 77, 233, 95, 8, 3, 1, 205, 255, 106, 2, 235, 
+    100, 8, 3, 1, 205, 255, 106, 2, 237, 11, 19, 242, 226, 49, 1, 3, 192, 49, 
+    1, 3, 255, 106, 2, 90, 49, 1, 3, 221, 49, 1, 3, 144, 49, 1, 3, 205, 144, 
+    49, 1, 3, 205, 255, 101, 2, 90, 49, 1, 3, 5, 236, 145, 144, 49, 1, 3, 
+    255, 16, 49, 1, 3, 255, 14, 49, 1, 240, 57, 49, 1, 45, 240, 57, 49, 1, 
+    205, 240, 27, 49, 1, 233, 59, 49, 1, 224, 240, 27, 49, 1, 38, 137, 242, 
+    233, 49, 1, 40, 137, 242, 233, 49, 1, 238, 62, 208, 49, 1, 224, 238, 62, 
+    208, 49, 1, 40, 234, 7, 49, 1, 38, 234, 7, 49, 1, 88, 234, 7, 49, 1, 92, 
+    234, 7, 49, 1, 190, 238, 54, 239, 254, 49, 1, 59, 242, 224, 49, 1, 196, 
+    49, 1, 242, 241, 238, 54, 49, 1, 242, 245, 238, 54, 49, 1, 170, 59, 242, 
+    224, 49, 1, 170, 196, 49, 1, 170, 242, 245, 238, 54, 49, 1, 170, 242, 
+    241, 238, 54, 49, 1, 234, 43, 240, 24, 49, 1, 137, 234, 43, 240, 24, 49, 
+    1, 238, 130, 38, 137, 242, 233, 49, 1, 238, 130, 40, 137, 242, 233, 49, 
+    1, 88, 242, 234, 49, 1, 92, 242, 234, 49, 1, 248, 49, 52, 49, 1, 242, 
+    250, 52, 239, 255, 53, 48, 248, 51, 48, 238, 71, 3, 169, 45, 242, 241, 
+    238, 54, 49, 1, 242, 83, 90, 49, 1, 243, 38, 238, 54, 49, 1, 3, 240, 10, 
+    49, 1, 3, 162, 49, 1, 3, 193, 49, 1, 3, 206, 49, 1, 3, 224, 238, 62, 208, 
+    49, 1, 234, 27, 188, 125, 49, 1, 200, 188, 125, 49, 1, 254, 40, 188, 125, 
+    49, 1, 170, 188, 125, 49, 1, 235, 87, 188, 125, 49, 1, 254, 15, 235, 98, 
+    188, 69, 49, 1, 248, 122, 235, 98, 188, 69, 49, 1, 238, 44, 49, 1, 233, 
+    47, 49, 1, 45, 233, 59, 49, 1, 170, 92, 234, 7, 49, 1, 170, 88, 234, 7, 
+    49, 1, 170, 40, 234, 7, 49, 1, 170, 38, 234, 7, 49, 1, 170, 242, 233, 49, 
+    1, 240, 1, 242, 245, 238, 54, 49, 1, 240, 1, 45, 242, 245, 238, 54, 49, 
+    1, 240, 1, 45, 242, 241, 238, 54, 49, 1, 170, 169, 49, 1, 240, 84, 240, 
+    24, 49, 1, 243, 24, 200, 243, 78, 49, 1, 253, 165, 200, 243, 78, 49, 1, 
+    243, 24, 170, 243, 78, 49, 1, 253, 165, 170, 243, 78, 49, 1, 240, 226, 
+    49, 1, 248, 35, 240, 226, 49, 1, 170, 40, 56, 50, 242, 245, 238, 54, 50, 
+    242, 241, 238, 54, 50, 190, 238, 54, 50, 169, 50, 196, 50, 235, 74, 50, 
+    239, 255, 50, 53, 48, 50, 175, 50, 248, 45, 48, 50, 248, 51, 48, 50, 45, 
+    242, 241, 238, 54, 50, 239, 254, 50, 59, 248, 41, 48, 50, 45, 59, 248, 
+    41, 48, 50, 45, 242, 245, 238, 54, 50, 232, 77, 50, 236, 145, 239, 255, 
+    50, 205, 242, 244, 48, 50, 242, 244, 48, 50, 224, 242, 244, 48, 50, 242, 
+    244, 60, 225, 50, 242, 245, 240, 2, 46, 50, 242, 241, 240, 2, 46, 50, 40, 
+    248, 84, 46, 50, 38, 248, 84, 46, 50, 40, 185, 48, 50, 243, 8, 50, 40, 
+    137, 248, 51, 46, 50, 88, 248, 84, 46, 50, 92, 248, 84, 46, 50, 248, 49, 
+    21, 46, 50, 242, 250, 21, 46, 50, 233, 222, 248, 45, 46, 50, 235, 54, 
+    248, 45, 46, 50, 53, 46, 50, 235, 56, 46, 50, 248, 51, 46, 50, 242, 244, 
+    46, 50, 236, 151, 50, 238, 71, 50, 59, 248, 41, 46, 50, 240, 109, 46, 50, 
+    236, 145, 45, 249, 239, 46, 50, 243, 86, 46, 50, 190, 240, 2, 46, 50, 
+    242, 243, 46, 50, 236, 145, 242, 243, 46, 50, 242, 219, 46, 50, 240, 42, 
+    46, 50, 170, 242, 224, 50, 45, 170, 242, 224, 50, 242, 219, 236, 161, 50, 
+    242, 215, 240, 5, 236, 161, 50, 183, 240, 5, 236, 161, 50, 242, 215, 238, 
+    83, 236, 161, 50, 183, 238, 83, 236, 161, 50, 38, 137, 248, 51, 46, 50, 
+    236, 145, 240, 109, 46, 50, 31, 46, 50, 239, 184, 46, 50, 255, 113, 48, 
+    50, 59, 169, 50, 45, 235, 74, 50, 242, 245, 188, 69, 50, 242, 241, 188, 
+    69, 50, 17, 232, 71, 50, 17, 236, 229, 50, 17, 235, 59, 240, 16, 50, 17, 
+    231, 35, 50, 240, 109, 48, 50, 240, 7, 21, 46, 50, 45, 59, 248, 41, 46, 
+    50, 40, 185, 46, 50, 161, 242, 219, 48, 50, 234, 200, 48, 50, 240, 40, 
+    95, 153, 48, 50, 40, 38, 65, 46, 50, 226, 226, 65, 46, 50, 237, 166, 238, 
+    140, 50, 38, 235, 76, 48, 50, 40, 137, 248, 51, 48, 50, 237, 10, 50, 255, 
+    113, 46, 50, 40, 235, 76, 46, 50, 38, 235, 76, 46, 50, 38, 235, 76, 19, 
+    88, 235, 76, 46, 50, 38, 137, 248, 51, 48, 50, 53, 60, 225, 50, 236, 219, 
+    46, 50, 45, 248, 51, 46, 50, 240, 126, 48, 50, 45, 242, 243, 46, 50, 45, 
+    239, 255, 50, 45, 196, 50, 45, 240, 42, 46, 50, 45, 169, 50, 45, 236, 
+    145, 239, 255, 50, 45, 77, 65, 46, 50, 8, 3, 1, 67, 50, 8, 3, 1, 72, 50, 
+    8, 3, 1, 71, 50, 8, 3, 1, 73, 50, 8, 3, 1, 79, 50, 8, 3, 1, 255, 18, 50, 
+    8, 3, 1, 209, 50, 8, 3, 1, 192, 50, 8, 3, 1, 173, 50, 8, 3, 1, 144, 50, 
+    8, 3, 1, 214, 50, 8, 3, 1, 179, 50, 8, 3, 1, 206, 17, 178, 52, 17, 168, 
+    178, 52, 17, 231, 35, 17, 236, 156, 69, 17, 240, 16, 17, 235, 59, 240, 
+    16, 17, 5, 1, 194, 2, 240, 16, 17, 254, 140, 238, 223, 17, 5, 1, 238, 57, 
+    2, 240, 16, 17, 5, 1, 253, 123, 2, 240, 16, 17, 5, 1, 248, 42, 2, 240, 
+    16, 17, 5, 1, 238, 64, 2, 240, 16, 17, 5, 1, 238, 53, 2, 240, 16, 17, 5, 
+    1, 211, 2, 240, 16, 17, 3, 1, 248, 42, 2, 235, 59, 19, 240, 16, 17, 5, 1, 
+    240, 22, 17, 5, 1, 242, 242, 17, 5, 1, 240, 10, 17, 5, 1, 240, 28, 17, 5, 
+    1, 236, 165, 17, 5, 1, 242, 251, 17, 5, 1, 248, 87, 17, 5, 1, 240, 38, 
+    17, 5, 1, 242, 237, 17, 5, 1, 240, 41, 17, 5, 1, 240, 33, 17, 5, 1, 253, 
+    154, 17, 5, 1, 253, 150, 17, 5, 1, 253, 188, 17, 5, 1, 236, 169, 17, 5, 
+    1, 253, 147, 17, 5, 1, 248, 73, 17, 5, 1, 240, 21, 17, 5, 1, 248, 85, 17, 
+    5, 1, 236, 160, 17, 5, 1, 248, 68, 17, 5, 1, 248, 67, 17, 5, 1, 248, 69, 
+    17, 5, 1, 240, 20, 17, 5, 1, 248, 42, 2, 234, 26, 17, 5, 1, 238, 53, 2, 
+    234, 26, 17, 3, 1, 194, 2, 240, 16, 17, 3, 1, 238, 57, 2, 240, 16, 17, 3, 
+    1, 253, 123, 2, 240, 16, 17, 3, 1, 248, 42, 2, 240, 16, 17, 3, 1, 238, 
+    53, 2, 235, 59, 19, 240, 16, 17, 3, 1, 240, 22, 17, 3, 1, 242, 242, 17, 
+    3, 1, 240, 10, 17, 3, 1, 240, 28, 17, 3, 1, 236, 165, 17, 3, 1, 242, 251, 
+    17, 3, 1, 248, 87, 17, 3, 1, 240, 38, 17, 3, 1, 242, 237, 17, 3, 1, 240, 
+    41, 17, 3, 1, 240, 33, 17, 3, 1, 253, 154, 17, 3, 1, 253, 150, 17, 3, 1, 
+    253, 188, 17, 3, 1, 236, 169, 17, 3, 1, 253, 147, 17, 3, 1, 248, 73, 17, 
+    3, 1, 30, 240, 21, 17, 3, 1, 240, 21, 17, 3, 1, 248, 85, 17, 3, 1, 236, 
+    160, 17, 3, 1, 248, 68, 17, 3, 1, 248, 67, 17, 3, 1, 248, 69, 17, 3, 1, 
+    240, 20, 17, 3, 1, 248, 42, 2, 234, 26, 17, 3, 1, 238, 53, 2, 234, 26, 
+    17, 3, 1, 238, 64, 2, 240, 16, 17, 3, 1, 238, 53, 2, 240, 16, 17, 3, 1, 
+    211, 2, 240, 16, 17, 250, 118, 91, 17, 243, 0, 91, 17, 238, 53, 2, 248, 
+    45, 91, 17, 238, 53, 2, 242, 241, 19, 248, 45, 91, 17, 238, 53, 2, 235, 
+    56, 19, 248, 45, 91, 17, 254, 11, 91, 17, 255, 29, 91, 17, 254, 65, 91, 
+    17, 1, 238, 162, 240, 77, 17, 3, 1, 238, 162, 240, 77, 17, 1, 238, 152, 
+    17, 3, 1, 238, 152, 17, 1, 237, 6, 17, 3, 1, 237, 6, 17, 1, 240, 77, 17, 
+    3, 1, 240, 77, 17, 1, 240, 121, 17, 3, 1, 240, 121, 62, 5, 1, 243, 32, 
+    62, 3, 1, 243, 32, 62, 5, 1, 249, 62, 62, 3, 1, 249, 62, 62, 5, 1, 243, 
+    64, 62, 3, 1, 243, 64, 62, 5, 1, 243, 28, 62, 3, 1, 243, 28, 62, 5, 1, 
+    238, 115, 62, 3, 1, 238, 115, 62, 5, 1, 240, 88, 62, 3, 1, 240, 88, 62, 
+    5, 1, 249, 53, 62, 3, 1, 249, 53, 17, 243, 29, 91, 17, 253, 218, 91, 17, 
+    240, 67, 243, 45, 91, 17, 1, 249, 211, 17, 5, 243, 0, 91, 17, 240, 67, 
+    238, 57, 91, 17, 224, 240, 67, 238, 57, 91, 17, 5, 1, 248, 110, 17, 3, 1, 
+    248, 110, 17, 5, 240, 67, 243, 45, 91, 17, 5, 1, 248, 134, 17, 3, 1, 248, 
+    134, 17, 253, 218, 2, 240, 5, 91, 17, 5, 224, 240, 67, 243, 45, 91, 17, 
+    5, 240, 4, 240, 67, 243, 45, 91, 17, 5, 224, 240, 4, 240, 67, 243, 45, 
+    91, 32, 5, 1, 255, 42, 2, 191, 32, 5, 1, 254, 100, 32, 5, 1, 248, 150, 
+    32, 5, 1, 249, 77, 32, 5, 1, 235, 156, 253, 237, 32, 5, 1, 248, 126, 32, 
+    5, 1, 226, 228, 71, 32, 5, 1, 253, 189, 32, 5, 1, 254, 24, 32, 5, 1, 248, 
+    165, 32, 5, 1, 248, 174, 32, 5, 1, 244, 40, 32, 5, 1, 249, 96, 32, 5, 1, 
+    220, 2, 191, 32, 5, 1, 242, 215, 79, 32, 5, 1, 243, 166, 32, 5, 1, 67, 
+    32, 5, 1, 253, 242, 32, 5, 1, 254, 12, 32, 5, 1, 248, 127, 32, 5, 1, 253, 
+    200, 32, 5, 1, 253, 237, 32, 5, 1, 248, 123, 32, 5, 1, 253, 228, 32, 5, 
+    1, 71, 32, 5, 1, 242, 215, 71, 32, 5, 1, 201, 32, 5, 1, 254, 3, 32, 5, 1, 
+    254, 22, 32, 5, 1, 253, 202, 32, 5, 1, 73, 32, 5, 1, 253, 175, 32, 5, 1, 
+    254, 4, 32, 5, 1, 254, 23, 32, 5, 1, 253, 195, 32, 5, 1, 79, 32, 5, 1, 
+    254, 21, 32, 5, 1, 219, 32, 5, 1, 248, 112, 32, 5, 1, 248, 88, 32, 5, 1, 
+    248, 46, 32, 5, 1, 240, 224, 32, 5, 1, 249, 79, 52, 32, 5, 1, 243, 83, 
+    32, 5, 1, 248, 186, 52, 32, 5, 1, 72, 32, 5, 1, 253, 161, 32, 5, 1, 216, 
+    32, 3, 1, 67, 32, 3, 1, 253, 242, 32, 3, 1, 254, 12, 32, 3, 1, 248, 127, 
+    32, 3, 1, 253, 200, 32, 3, 1, 253, 237, 32, 3, 1, 248, 123, 32, 3, 1, 
+    253, 228, 32, 3, 1, 71, 32, 3, 1, 242, 215, 71, 32, 3, 1, 201, 32, 3, 1, 
+    254, 3, 32, 3, 1, 254, 22, 32, 3, 1, 253, 202, 32, 3, 1, 73, 32, 3, 1, 
+    253, 175, 32, 3, 1, 254, 4, 32, 3, 1, 254, 23, 32, 3, 1, 253, 195, 32, 3, 
+    1, 79, 32, 3, 1, 254, 21, 32, 3, 1, 219, 32, 3, 1, 248, 112, 32, 3, 1, 
+    248, 88, 32, 3, 1, 248, 46, 32, 3, 1, 240, 224, 32, 3, 1, 249, 79, 52, 
+    32, 3, 1, 243, 83, 32, 3, 1, 248, 186, 52, 32, 3, 1, 72, 32, 3, 1, 253, 
+    161, 32, 3, 1, 216, 32, 3, 1, 255, 42, 2, 191, 32, 3, 1, 254, 100, 32, 3, 
+    1, 248, 150, 32, 3, 1, 249, 77, 32, 3, 1, 235, 156, 253, 237, 32, 3, 1, 
+    248, 126, 32, 3, 1, 226, 228, 71, 32, 3, 1, 253, 189, 32, 3, 1, 254, 24, 
+    32, 3, 1, 248, 165, 32, 3, 1, 248, 174, 32, 3, 1, 244, 40, 32, 3, 1, 249, 
+    96, 32, 3, 1, 220, 2, 191, 32, 3, 1, 242, 215, 79, 32, 3, 1, 243, 166, 
+    32, 5, 1, 240, 20, 32, 3, 1, 240, 20, 32, 5, 1, 249, 21, 32, 3, 1, 249, 
+    21, 32, 5, 1, 236, 197, 72, 32, 3, 1, 236, 197, 72, 32, 5, 1, 240, 101, 
+    248, 74, 32, 3, 1, 240, 101, 248, 74, 32, 5, 1, 236, 197, 240, 101, 248, 
+    74, 32, 3, 1, 236, 197, 240, 101, 248, 74, 32, 5, 1, 253, 213, 248, 74, 
+    32, 3, 1, 253, 213, 248, 74, 32, 5, 1, 236, 197, 253, 213, 248, 74, 32, 
+    3, 1, 236, 197, 253, 213, 248, 74, 32, 5, 1, 248, 163, 32, 3, 1, 248, 
+    163, 32, 5, 1, 248, 69, 32, 3, 1, 248, 69, 32, 5, 1, 243, 57, 32, 3, 1, 
+    243, 57, 32, 5, 1, 236, 215, 32, 3, 1, 236, 215, 32, 5, 1, 238, 192, 2, 
+    45, 242, 245, 238, 54, 32, 3, 1, 238, 192, 2, 45, 242, 245, 238, 54, 32, 
+    5, 1, 254, 130, 32, 3, 1, 254, 130, 32, 5, 1, 244, 1, 240, 20, 32, 3, 1, 
+    244, 1, 240, 20, 32, 5, 1, 211, 2, 240, 150, 32, 3, 1, 211, 2, 240, 150, 
+    32, 5, 1, 254, 67, 32, 3, 1, 254, 67, 32, 5, 1, 240, 77, 32, 3, 1, 240, 
+    77, 32, 235, 114, 52, 50, 32, 240, 150, 50, 32, 231, 27, 50, 32, 148, 
+    235, 135, 50, 32, 159, 235, 135, 50, 32, 238, 92, 235, 114, 52, 50, 32, 
+    237, 211, 52, 32, 5, 1, 242, 215, 220, 2, 242, 226, 32, 3, 1, 242, 215, 
+    220, 2, 242, 226, 32, 5, 1, 237, 36, 52, 32, 3, 1, 237, 36, 52, 32, 5, 1, 
+    255, 54, 2, 243, 36, 32, 3, 1, 255, 54, 2, 243, 36, 32, 5, 1, 253, 233, 
+    2, 238, 231, 32, 3, 1, 253, 233, 2, 238, 231, 32, 5, 1, 253, 233, 2, 108, 
+    32, 3, 1, 253, 233, 2, 108, 32, 5, 1, 253, 233, 2, 240, 1, 90, 32, 3, 1, 
+    253, 233, 2, 240, 1, 90, 32, 5, 1, 254, 16, 2, 234, 2, 32, 3, 1, 254, 16, 
+    2, 234, 2, 32, 5, 1, 255, 46, 2, 234, 2, 32, 3, 1, 255, 46, 2, 234, 2, 
+    32, 5, 1, 255, 26, 2, 234, 2, 32, 3, 1, 255, 26, 2, 234, 2, 32, 5, 1, 
+    255, 26, 2, 59, 108, 32, 3, 1, 255, 26, 2, 59, 108, 32, 5, 1, 255, 26, 2, 
+    108, 32, 3, 1, 255, 26, 2, 108, 32, 5, 1, 238, 165, 201, 32, 3, 1, 238, 
+    165, 201, 32, 5, 1, 255, 23, 2, 234, 2, 32, 3, 1, 255, 23, 2, 234, 2, 32, 
+    5, 18, 255, 23, 248, 127, 32, 3, 18, 255, 23, 248, 127, 32, 5, 1, 255, 
+    38, 2, 240, 1, 90, 32, 3, 1, 255, 38, 2, 240, 1, 90, 32, 5, 1, 235, 66, 
+    219, 32, 3, 1, 235, 66, 219, 32, 5, 1, 255, 55, 2, 234, 2, 32, 3, 1, 255, 
+    55, 2, 234, 2, 32, 5, 1, 255, 45, 2, 234, 2, 32, 3, 1, 255, 45, 2, 234, 
+    2, 32, 5, 1, 236, 218, 79, 32, 3, 1, 236, 218, 79, 32, 5, 1, 236, 218, 
+    132, 2, 108, 32, 3, 1, 236, 218, 132, 2, 108, 32, 5, 1, 255, 58, 2, 234, 
+    2, 32, 3, 1, 255, 58, 2, 234, 2, 32, 5, 18, 255, 45, 248, 112, 32, 3, 18, 
+    255, 45, 248, 112, 32, 5, 1, 253, 223, 2, 234, 2, 32, 3, 1, 253, 223, 2, 
+    234, 2, 32, 5, 1, 253, 223, 2, 59, 108, 32, 3, 1, 253, 223, 2, 59, 108, 
+    32, 5, 1, 244, 10, 32, 3, 1, 244, 10, 32, 5, 1, 235, 66, 248, 88, 32, 3, 
+    1, 235, 66, 248, 88, 32, 5, 1, 235, 66, 253, 223, 2, 234, 2, 32, 3, 1, 
+    235, 66, 253, 223, 2, 234, 2, 32, 1, 236, 69, 32, 5, 1, 254, 16, 2, 239, 
+    255, 32, 3, 1, 254, 16, 2, 239, 255, 32, 5, 1, 255, 26, 2, 90, 32, 3, 1, 
+    255, 26, 2, 90, 32, 5, 1, 255, 49, 2, 242, 226, 32, 3, 1, 255, 49, 2, 
+    242, 226, 32, 5, 1, 255, 23, 2, 90, 32, 3, 1, 255, 23, 2, 90, 32, 5, 1, 
+    255, 23, 2, 242, 226, 32, 3, 1, 255, 23, 2, 242, 226, 32, 5, 1, 234, 59, 
+    248, 88, 32, 3, 1, 234, 59, 248, 88, 32, 5, 1, 255, 28, 2, 242, 226, 32, 
+    3, 1, 255, 28, 2, 242, 226, 32, 5, 1, 134, 2, 239, 255, 32, 3, 1, 134, 2, 
+    239, 255, 32, 5, 1, 134, 2, 175, 32, 3, 1, 134, 2, 175, 32, 5, 18, 134, 
+    253, 237, 32, 3, 18, 134, 253, 237, 32, 5, 1, 255, 42, 2, 239, 255, 32, 
+    3, 1, 255, 42, 2, 239, 255, 32, 5, 1, 240, 86, 32, 3, 1, 240, 86, 32, 5, 
+    1, 243, 73, 2, 175, 32, 3, 1, 243, 73, 2, 175, 32, 5, 1, 254, 16, 2, 175, 
+    32, 3, 1, 254, 16, 2, 175, 32, 5, 1, 255, 46, 2, 175, 32, 3, 1, 255, 46, 
+    2, 175, 32, 5, 1, 235, 66, 248, 126, 32, 3, 1, 235, 66, 248, 126, 32, 5, 
+    1, 220, 2, 196, 32, 3, 1, 220, 2, 196, 32, 5, 1, 220, 2, 175, 32, 3, 1, 
+    220, 2, 175, 32, 5, 1, 117, 2, 175, 32, 3, 1, 117, 2, 175, 32, 5, 1, 240, 
+    60, 73, 32, 3, 1, 240, 60, 73, 32, 5, 1, 240, 60, 117, 2, 175, 32, 3, 1, 
+    240, 60, 117, 2, 175, 32, 5, 1, 157, 2, 175, 32, 3, 1, 157, 2, 175, 32, 
+    5, 1, 132, 2, 196, 32, 3, 1, 132, 2, 196, 32, 5, 1, 132, 2, 175, 32, 3, 
+    1, 132, 2, 175, 32, 5, 1, 132, 2, 45, 135, 32, 3, 1, 132, 2, 45, 135, 32, 
+    5, 1, 253, 223, 2, 175, 32, 3, 1, 253, 223, 2, 175, 32, 5, 1, 253, 233, 
+    2, 234, 2, 32, 3, 1, 253, 233, 2, 234, 2, 32, 5, 1, 249, 207, 2, 175, 32, 
+    3, 1, 249, 207, 2, 175, 32, 5, 1, 248, 72, 253, 200, 32, 3, 1, 248, 72, 
+    253, 200, 32, 5, 1, 248, 72, 248, 150, 32, 3, 1, 248, 72, 248, 150, 32, 
+    5, 1, 248, 72, 249, 220, 32, 3, 1, 248, 72, 249, 220, 32, 5, 1, 248, 72, 
+    243, 167, 32, 3, 1, 248, 72, 243, 167, 32, 5, 1, 248, 72, 248, 165, 32, 
+    3, 1, 248, 72, 248, 165, 32, 5, 1, 248, 72, 248, 174, 32, 3, 1, 248, 72, 
+    248, 174, 32, 5, 1, 248, 72, 249, 165, 32, 3, 1, 248, 72, 249, 165, 32, 
+    5, 1, 248, 72, 249, 178, 32, 3, 1, 248, 72, 249, 178, 100, 5, 1, 249, 28, 
+    100, 5, 1, 249, 32, 100, 5, 1, 249, 76, 100, 5, 1, 253, 133, 100, 5, 1, 
+    248, 208, 100, 5, 1, 253, 163, 100, 5, 1, 254, 36, 100, 5, 1, 254, 60, 
+    100, 5, 1, 87, 100, 5, 1, 248, 123, 100, 5, 1, 248, 216, 100, 5, 1, 243, 
+    216, 100, 5, 1, 249, 17, 100, 5, 1, 253, 152, 100, 5, 1, 249, 93, 100, 5, 
+    1, 253, 184, 100, 5, 1, 253, 146, 100, 5, 1, 243, 182, 100, 5, 1, 243, 
+    155, 100, 5, 1, 248, 228, 100, 5, 1, 253, 189, 100, 5, 1, 248, 175, 100, 
+    5, 1, 248, 46, 100, 5, 1, 254, 13, 100, 5, 1, 248, 57, 100, 5, 1, 248, 
+    237, 100, 5, 1, 243, 201, 100, 5, 1, 253, 130, 100, 5, 1, 249, 159, 100, 
+    5, 1, 249, 195, 100, 5, 1, 244, 32, 100, 5, 1, 248, 245, 100, 5, 1, 253, 
+    224, 100, 5, 1, 243, 136, 100, 5, 1, 243, 244, 100, 5, 1, 248, 218, 100, 
+    5, 1, 254, 118, 100, 5, 1, 248, 156, 100, 49, 1, 40, 137, 242, 233, 100, 
+    233, 59, 100, 237, 8, 69, 100, 233, 54, 69, 100, 240, 27, 100, 236, 156, 
+    69, 100, 232, 88, 69, 100, 3, 1, 249, 28, 100, 3, 1, 249, 32, 100, 3, 1, 
+    249, 76, 100, 3, 1, 253, 133, 100, 3, 1, 248, 208, 100, 3, 1, 253, 163, 
+    100, 3, 1, 254, 36, 100, 3, 1, 254, 60, 100, 3, 1, 87, 100, 3, 1, 248, 
+    123, 100, 3, 1, 248, 216, 100, 3, 1, 243, 216, 100, 3, 1, 249, 17, 100, 
+    3, 1, 253, 152, 100, 3, 1, 249, 93, 100, 3, 1, 253, 184, 100, 3, 1, 253, 
+    146, 100, 3, 1, 243, 182, 100, 3, 1, 243, 155, 100, 3, 1, 248, 228, 100, 
+    3, 1, 253, 189, 100, 3, 1, 248, 175, 100, 3, 1, 248, 46, 100, 3, 1, 254, 
+    13, 100, 3, 1, 248, 57, 100, 3, 1, 248, 237, 100, 3, 1, 243, 201, 100, 3, 
+    1, 253, 130, 100, 3, 1, 249, 159, 100, 3, 1, 249, 195, 100, 3, 1, 244, 
+    32, 100, 3, 1, 248, 245, 100, 3, 1, 253, 224, 100, 3, 1, 243, 136, 100, 
+    3, 1, 243, 244, 100, 3, 1, 248, 218, 100, 3, 1, 254, 118, 100, 3, 1, 248, 
+    156, 100, 3, 18, 254, 159, 243, 136, 100, 248, 37, 208, 100, 238, 93, 68, 
+    240, 2, 237, 152, 68, 240, 2, 240, 145, 68, 240, 2, 233, 242, 68, 240, 2, 
+    244, 64, 240, 212, 68, 240, 2, 244, 64, 241, 120, 68, 240, 2, 239, 222, 
+    68, 240, 2, 242, 81, 68, 240, 2, 242, 200, 68, 240, 2, 239, 158, 68, 240, 
+    2, 242, 197, 68, 240, 2, 242, 145, 68, 240, 2, 238, 186, 68, 240, 2, 241, 
+    126, 239, 141, 68, 240, 2, 234, 56, 68, 240, 2, 242, 71, 246, 238, 68, 
+    240, 2, 238, 224, 239, 80, 68, 240, 2, 242, 50, 68, 240, 2, 244, 85, 239, 
+    88, 68, 240, 2, 241, 250, 68, 240, 2, 236, 54, 68, 240, 2, 239, 134, 68, 
+    240, 2, 241, 235, 239, 106, 68, 240, 2, 241, 73, 68, 240, 2, 242, 69, 68, 
+    240, 2, 238, 224, 239, 171, 68, 240, 2, 247, 225, 254, 145, 247, 232, 68, 
+    240, 2, 252, 58, 68, 240, 2, 245, 226, 68, 240, 2, 245, 61, 68, 240, 2, 
+    242, 208, 68, 158, 241, 230, 238, 51, 68, 242, 232, 242, 105, 68, 242, 
+    232, 243, 98, 240, 145, 68, 242, 232, 243, 98, 240, 118, 68, 242, 232, 
+    243, 98, 238, 149, 68, 242, 232, 240, 187, 68, 242, 232, 242, 159, 68, 
+    242, 232, 240, 145, 68, 242, 232, 240, 118, 68, 242, 232, 238, 149, 68, 
+    242, 232, 240, 188, 68, 242, 232, 239, 172, 68, 242, 232, 240, 133, 128, 
+    240, 140, 68, 242, 232, 241, 236, 68, 233, 51, 241, 228, 68, 242, 232, 
+    243, 70, 68, 233, 51, 242, 47, 68, 242, 232, 248, 102, 248, 40, 68, 242, 
+    232, 254, 73, 248, 40, 68, 233, 51, 254, 240, 242, 48, 68, 158, 189, 248, 
+    40, 68, 158, 168, 248, 40, 68, 233, 51, 254, 114, 237, 167, 68, 242, 232, 
+    242, 70, 240, 212, 68, 1, 243, 3, 68, 1, 250, 117, 68, 1, 241, 136, 68, 
+    1, 240, 165, 68, 1, 253, 168, 68, 1, 249, 192, 68, 1, 242, 201, 68, 1, 
+    251, 54, 68, 1, 249, 176, 68, 1, 248, 193, 68, 1, 30, 248, 116, 68, 1, 
+    248, 116, 68, 1, 240, 139, 68, 1, 30, 248, 166, 68, 1, 248, 166, 68, 1, 
+    30, 248, 132, 68, 1, 248, 132, 68, 1, 239, 178, 68, 1, 243, 144, 68, 1, 
+    30, 253, 175, 68, 1, 253, 175, 68, 1, 30, 240, 248, 68, 1, 240, 248, 68, 
+    1, 252, 99, 68, 1, 243, 253, 68, 1, 243, 33, 68, 1, 249, 175, 68, 18, 
+    238, 126, 45, 249, 192, 68, 18, 238, 126, 254, 76, 248, 193, 68, 18, 238, 
+    126, 45, 248, 193, 68, 233, 51, 238, 186, 68, 233, 51, 234, 56, 11, 61, 
+    52, 11, 21, 242, 97, 11, 237, 159, 238, 95, 11, 21, 242, 93, 238, 237, 
+    52, 11, 240, 27, 11, 250, 186, 234, 6, 11, 242, 63, 244, 46, 52, 11, 21, 
+    241, 245, 11, 21, 233, 100, 240, 107, 235, 40, 11, 21, 240, 107, 235, 
+    173, 11, 21, 233, 228, 238, 242, 11, 21, 252, 127, 238, 244, 244, 80, 11, 
+    21, 235, 31, 11, 3, 200, 248, 137, 11, 234, 14, 11, 240, 3, 53, 233, 51, 
+    69, 11, 236, 156, 69, 11, 1, 240, 186, 11, 1, 83, 2, 243, 42, 48, 11, 1, 
+    83, 2, 143, 48, 11, 1, 253, 220, 2, 143, 48, 11, 1, 83, 2, 143, 46, 11, 
+    1, 57, 2, 143, 48, 11, 1, 243, 3, 11, 1, 249, 31, 11, 1, 253, 127, 237, 
+    200, 11, 1, 252, 213, 11, 1, 247, 142, 11, 1, 243, 200, 11, 1, 251, 45, 
+    11, 1, 243, 205, 11, 1, 250, 180, 11, 1, 247, 141, 11, 1, 248, 245, 11, 
+    1, 244, 63, 11, 1, 243, 120, 11, 1, 242, 103, 11, 1, 252, 165, 11, 1, 
+    250, 178, 11, 1, 248, 137, 11, 1, 253, 97, 11, 1, 248, 105, 11, 1, 240, 
+    180, 11, 238, 22, 11, 1, 248, 156, 11, 1, 249, 145, 11, 1, 248, 116, 11, 
+    1, 251, 182, 11, 1, 243, 223, 11, 1, 243, 236, 11, 1, 251, 50, 11, 1, 
+    248, 142, 11, 1, 83, 236, 232, 11, 1, 248, 144, 11, 236, 18, 11, 235, 
+    197, 11, 236, 43, 11, 241, 103, 11, 240, 134, 11, 241, 193, 11, 239, 191, 
+    11, 240, 240, 11, 241, 223, 48, 11, 143, 48, 11, 143, 46, 11, 235, 48, 
+    243, 3, 11, 236, 145, 240, 134, 11, 158, 198, 238, 187, 11, 236, 144, 11, 
+    33, 21, 3, 255, 110, 48, 11, 33, 21, 236, 145, 3, 255, 110, 48, 11, 33, 
+    21, 53, 46, 11, 224, 240, 134, 11, 243, 40, 2, 171, 243, 5, 232, 73, 26, 
+    242, 217, 232, 73, 26, 127, 232, 73, 26, 111, 232, 73, 26, 166, 232, 73, 
+    26, 177, 232, 73, 26, 176, 232, 73, 26, 187, 232, 73, 26, 203, 232, 73, 
+    26, 195, 232, 73, 26, 202, 11, 238, 107, 52, 11, 238, 176, 234, 6, 11, 
+    235, 114, 234, 6, 11, 248, 48, 238, 74, 242, 229, 11, 1, 238, 70, 249, 
+    31, 11, 1, 238, 70, 249, 145, 11, 1, 233, 49, 243, 3, 11, 1, 83, 242, 
+    182, 11, 1, 83, 2, 248, 103, 143, 48, 11, 1, 83, 2, 248, 103, 143, 46, 
+    11, 1, 200, 240, 186, 11, 1, 200, 143, 243, 3, 11, 1, 200, 143, 248, 142, 
+    11, 1, 132, 2, 143, 48, 11, 1, 200, 143, 248, 144, 11, 1, 247, 165, 11, 
+    1, 239, 231, 11, 1, 244, 214, 11, 1, 253, 127, 2, 242, 233, 11, 1, 253, 
+    127, 2, 204, 181, 60, 234, 9, 11, 1, 248, 237, 11, 1, 242, 143, 11, 1, 
+    241, 28, 11, 1, 94, 2, 143, 48, 11, 1, 94, 2, 171, 181, 59, 48, 11, 1, 
+    246, 201, 11, 1, 245, 77, 11, 1, 94, 2, 204, 181, 48, 11, 1, 242, 142, 
+    11, 1, 238, 23, 11, 1, 245, 37, 11, 1, 253, 199, 2, 242, 233, 11, 1, 253, 
+    199, 2, 53, 46, 11, 1, 253, 199, 2, 53, 242, 230, 19, 3, 248, 137, 11, 1, 
+    241, 71, 11, 1, 239, 38, 11, 1, 250, 208, 11, 1, 253, 199, 2, 204, 181, 
+    60, 234, 9, 11, 1, 253, 199, 2, 248, 58, 181, 48, 11, 1, 247, 36, 11, 1, 
+    253, 143, 2, 3, 179, 11, 1, 253, 143, 2, 242, 233, 11, 1, 253, 143, 2, 
+    53, 46, 11, 1, 253, 143, 2, 3, 255, 110, 46, 11, 1, 253, 143, 2, 53, 242, 
+    230, 19, 53, 48, 11, 1, 253, 143, 2, 171, 181, 48, 11, 1, 251, 112, 11, 
+    1, 253, 143, 2, 248, 58, 181, 48, 11, 1, 248, 39, 2, 53, 242, 230, 19, 
+    53, 48, 11, 1, 248, 39, 2, 204, 181, 46, 11, 1, 248, 39, 2, 204, 181, 
+    242, 230, 19, 204, 181, 48, 11, 1, 253, 157, 2, 171, 181, 46, 11, 1, 253, 
+    157, 2, 204, 181, 48, 11, 1, 253, 169, 2, 204, 181, 48, 11, 1, 253, 158, 
+    2, 204, 181, 48, 11, 1, 238, 70, 248, 156, 11, 1, 253, 153, 2, 53, 246, 
+    92, 46, 11, 1, 253, 153, 2, 53, 46, 11, 1, 253, 10, 11, 1, 253, 153, 2, 
+    204, 181, 46, 11, 1, 242, 53, 11, 1, 253, 167, 2, 53, 48, 11, 1, 253, 
+    167, 2, 204, 181, 48, 11, 1, 241, 197, 11, 1, 243, 126, 248, 116, 11, 1, 
+    253, 135, 2, 242, 233, 11, 1, 253, 135, 2, 53, 48, 11, 1, 254, 26, 11, 1, 
+    253, 135, 2, 204, 181, 46, 11, 1, 251, 5, 11, 1, 253, 246, 2, 242, 233, 
+    11, 1, 242, 8, 11, 1, 253, 246, 2, 171, 181, 46, 11, 1, 245, 129, 11, 1, 
+    253, 246, 2, 204, 181, 48, 11, 1, 182, 2, 3, 179, 11, 1, 182, 2, 53, 48, 
+    11, 1, 182, 2, 204, 181, 48, 11, 1, 182, 2, 204, 181, 46, 11, 1, 198, 2, 
+    53, 46, 11, 1, 198, 238, 187, 11, 1, 242, 85, 11, 1, 198, 2, 242, 233, 
+    11, 1, 198, 2, 204, 181, 48, 11, 1, 253, 124, 232, 133, 11, 1, 243, 47, 
+    2, 53, 48, 11, 1, 253, 124, 2, 57, 48, 11, 1, 253, 124, 243, 185, 11, 1, 
+    253, 124, 248, 128, 2, 143, 48, 11, 1, 253, 127, 238, 144, 243, 185, 11, 
+    1, 253, 220, 2, 242, 233, 11, 1, 238, 73, 253, 193, 11, 1, 253, 193, 11, 
+    1, 79, 11, 1, 253, 161, 11, 1, 238, 73, 253, 161, 11, 1, 253, 220, 2, 
+    171, 181, 48, 11, 1, 254, 12, 11, 1, 243, 26, 248, 144, 11, 1, 57, 2, 
+    242, 226, 11, 1, 57, 2, 3, 179, 11, 1, 253, 220, 2, 53, 48, 11, 1, 72, 
+    11, 1, 57, 2, 204, 181, 46, 11, 1, 57, 239, 5, 11, 1, 57, 240, 92, 2, 
+    143, 48, 11, 248, 37, 208, 11, 1, 253, 178, 11, 3, 200, 18, 253, 157, 2, 
+    182, 2, 83, 236, 232, 11, 3, 200, 18, 253, 167, 2, 182, 2, 83, 236, 232, 
+    11, 3, 200, 51, 54, 13, 11, 3, 200, 182, 243, 3, 11, 3, 200, 243, 200, 
+    11, 3, 200, 204, 243, 5, 11, 3, 200, 243, 120, 11, 253, 165, 147, 244, 
+    87, 11, 243, 124, 147, 254, 237, 255, 49, 245, 147, 11, 3, 200, 238, 121, 
+    242, 217, 11, 3, 200, 239, 234, 233, 97, 242, 217, 11, 3, 200, 238, 70, 
+    251, 49, 147, 243, 205, 11, 3, 200, 51, 39, 13, 11, 3, 170, 243, 120, 11, 
+    3, 200, 241, 222, 11, 3, 248, 142, 11, 3, 248, 144, 11, 3, 200, 248, 144, 
+    11, 3, 200, 243, 236, 11, 243, 245, 147, 239, 177, 11, 243, 15, 240, 46, 
+    170, 208, 11, 243, 15, 240, 46, 200, 208, 11, 238, 121, 200, 248, 119, 2, 
+    241, 109, 238, 129, 11, 3, 170, 243, 223, 11, 1, 253, 199, 2, 236, 145, 
+    179, 11, 1, 253, 143, 2, 236, 145, 179, 236, 174, 232, 73, 26, 242, 217, 
+    236, 174, 232, 73, 26, 127, 236, 174, 232, 73, 26, 111, 236, 174, 232, 
+    73, 26, 166, 236, 174, 232, 73, 26, 177, 236, 174, 232, 73, 26, 176, 236, 
+    174, 232, 73, 26, 187, 236, 174, 232, 73, 26, 203, 236, 174, 232, 73, 26, 
+    195, 236, 174, 232, 73, 26, 202, 11, 1, 242, 216, 2, 53, 46, 11, 1, 253, 
+    155, 2, 53, 46, 11, 1, 242, 240, 2, 53, 46, 11, 21, 240, 233, 234, 17, 
+    11, 21, 240, 233, 232, 197, 248, 228, 11, 1, 253, 124, 2, 236, 145, 179, 
+    129, 253, 165, 147, 234, 232, 129, 233, 80, 248, 37, 208, 129, 235, 110, 
+    248, 37, 208, 129, 233, 80, 240, 24, 129, 235, 110, 240, 24, 129, 163, 
+    240, 24, 129, 243, 14, 240, 122, 242, 220, 129, 243, 14, 240, 122, 225, 
+    129, 233, 80, 243, 14, 240, 122, 242, 220, 129, 235, 110, 243, 14, 240, 
+    122, 225, 129, 232, 121, 129, 236, 227, 239, 150, 129, 236, 227, 234, 
+    222, 129, 236, 227, 233, 117, 129, 232, 88, 69, 129, 1, 240, 155, 129, 1, 
+    233, 49, 240, 155, 129, 1, 244, 219, 129, 1, 241, 121, 129, 1, 245, 96, 
+    235, 123, 129, 1, 239, 35, 129, 1, 238, 70, 241, 72, 243, 255, 129, 1, 
+    253, 168, 129, 1, 248, 142, 129, 1, 244, 63, 129, 1, 245, 142, 129, 1, 
+    247, 140, 129, 1, 252, 216, 235, 123, 129, 1, 247, 238, 129, 1, 253, 87, 
+    253, 168, 129, 1, 246, 5, 129, 1, 239, 113, 129, 1, 251, 235, 129, 1, 
+    248, 132, 129, 1, 237, 37, 129, 1, 30, 237, 37, 129, 1, 72, 129, 1, 253, 
+    175, 129, 1, 224, 253, 175, 129, 1, 242, 92, 129, 1, 247, 6, 129, 1, 243, 
+    255, 129, 1, 243, 33, 129, 1, 252, 211, 129, 1, 184, 241, 30, 129, 1, 
+    184, 239, 84, 129, 1, 184, 237, 104, 129, 240, 143, 48, 129, 240, 143, 
+    46, 129, 240, 143, 238, 136, 129, 240, 154, 48, 129, 240, 154, 46, 129, 
+    240, 154, 238, 136, 129, 243, 252, 48, 129, 243, 252, 46, 129, 240, 4, 
+    244, 66, 233, 50, 129, 240, 4, 244, 66, 237, 61, 129, 243, 192, 48, 129, 
+    243, 192, 46, 129, 233, 205, 238, 136, 129, 243, 170, 48, 129, 243, 170, 
+    46, 129, 242, 91, 129, 237, 9, 248, 40, 129, 234, 244, 129, 236, 94, 129, 
+    171, 59, 181, 48, 129, 171, 59, 181, 46, 129, 204, 181, 48, 129, 204, 
+    181, 46, 129, 238, 106, 248, 41, 48, 129, 238, 106, 248, 41, 46, 129, 
+    241, 251, 129, 237, 71, 129, 1, 238, 151, 242, 202, 129, 1, 238, 151, 
+    241, 201, 129, 1, 238, 151, 254, 62, 11, 1, 253, 136, 2, 204, 181, 232, 
+    173, 46, 11, 1, 253, 136, 2, 53, 242, 230, 19, 204, 181, 48, 11, 1, 253, 
+    136, 2, 204, 181, 236, 150, 226, 226, 46, 11, 1, 253, 136, 2, 204, 181, 
+    236, 150, 226, 226, 242, 230, 19, 171, 181, 48, 11, 1, 253, 136, 2, 171, 
+    181, 242, 230, 19, 53, 48, 11, 1, 253, 136, 2, 236, 145, 3, 255, 110, 46, 
+    11, 1, 253, 136, 2, 3, 179, 11, 1, 94, 2, 171, 181, 48, 11, 1, 94, 2, 
+    204, 181, 236, 150, 226, 226, 46, 11, 1, 253, 199, 2, 171, 181, 234, 33, 
+    242, 230, 19, 3, 248, 137, 11, 1, 253, 199, 2, 236, 145, 3, 255, 110, 46, 
+    11, 1, 253, 143, 2, 108, 11, 1, 248, 39, 2, 248, 58, 181, 48, 11, 1, 253, 
+    158, 2, 171, 181, 48, 11, 1, 253, 158, 2, 204, 181, 236, 150, 235, 45, 
+    48, 11, 1, 253, 158, 2, 171, 181, 234, 33, 48, 11, 1, 253, 153, 2, 171, 
+    181, 46, 11, 1, 253, 153, 2, 204, 181, 236, 150, 226, 226, 46, 11, 1, 
+    243, 21, 2, 53, 48, 11, 1, 243, 21, 2, 204, 181, 48, 11, 1, 243, 21, 2, 
+    204, 181, 236, 150, 226, 226, 46, 11, 1, 51, 2, 53, 48, 11, 1, 51, 2, 53, 
+    46, 11, 1, 198, 2, 171, 181, 46, 11, 1, 198, 2, 3, 248, 137, 11, 1, 198, 
+    2, 3, 179, 11, 1, 182, 2, 125, 11, 1, 253, 143, 2, 171, 181, 234, 33, 48, 
+    11, 1, 253, 143, 2, 143, 48, 11, 1, 248, 39, 2, 171, 181, 234, 33, 48, 
+    199, 1, 248, 114, 199, 1, 234, 254, 199, 1, 242, 22, 199, 1, 248, 182, 
+    199, 1, 249, 30, 199, 1, 234, 218, 199, 1, 241, 191, 199, 1, 241, 8, 199, 
+    1, 242, 173, 199, 1, 241, 231, 199, 1, 241, 101, 199, 1, 239, 41, 199, 1, 
+    243, 76, 199, 1, 241, 210, 199, 1, 241, 119, 199, 1, 234, 195, 199, 1, 
+    242, 99, 199, 1, 235, 199, 199, 1, 236, 143, 199, 1, 236, 127, 199, 1, 
+    248, 191, 199, 1, 236, 72, 199, 1, 236, 42, 199, 1, 234, 100, 199, 1, 
+    247, 163, 199, 1, 243, 194, 199, 1, 246, 8, 199, 1, 239, 217, 199, 1, 
+    249, 216, 199, 1, 239, 193, 199, 1, 239, 176, 199, 1, 239, 34, 199, 1, 
+    87, 199, 1, 253, 222, 199, 1, 244, 74, 199, 1, 239, 83, 199, 1, 242, 68, 
+    199, 1, 242, 181, 199, 237, 54, 199, 234, 88, 199, 237, 176, 199, 234, 
+    183, 199, 238, 37, 199, 234, 229, 199, 237, 145, 199, 234, 189, 199, 237, 
+    223, 199, 234, 228, 199, 240, 240, 199, 1, 248, 231, 85, 21, 232, 77, 85, 
+    21, 235, 61, 85, 21, 236, 173, 85, 1, 242, 215, 67, 85, 1, 67, 85, 1, 
+    253, 140, 85, 1, 71, 85, 1, 253, 142, 85, 1, 79, 85, 1, 253, 148, 85, 1, 
+    165, 144, 85, 1, 165, 162, 85, 1, 240, 61, 72, 85, 1, 242, 215, 72, 85, 
+    1, 72, 85, 1, 253, 149, 85, 1, 240, 61, 73, 85, 1, 242, 215, 73, 85, 1, 
+    73, 85, 1, 253, 151, 85, 1, 201, 85, 1, 248, 61, 85, 1, 253, 139, 85, 1, 
+    248, 77, 85, 1, 248, 50, 85, 1, 253, 152, 85, 1, 248, 57, 85, 1, 253, 
+    146, 85, 1, 248, 89, 85, 1, 248, 78, 85, 1, 248, 71, 85, 1, 242, 247, 85, 
+    1, 248, 75, 85, 1, 242, 249, 85, 1, 248, 82, 85, 1, 253, 126, 85, 1, 248, 
+    55, 85, 1, 253, 133, 85, 1, 248, 76, 85, 1, 253, 131, 85, 1, 243, 234, 
+    85, 1, 253, 129, 85, 1, 248, 65, 85, 1, 253, 141, 85, 1, 248, 81, 85, 1, 
+    222, 85, 1, 216, 85, 1, 253, 130, 85, 1, 248, 96, 85, 1, 253, 134, 85, 1, 
+    248, 94, 85, 1, 243, 104, 85, 1, 253, 171, 85, 1, 248, 46, 85, 1, 248, 
+    66, 85, 1, 253, 132, 85, 1, 219, 85, 21, 240, 81, 85, 21, 235, 80, 85, 
+    33, 21, 253, 140, 85, 33, 21, 71, 85, 33, 21, 253, 142, 85, 33, 21, 79, 
+    85, 33, 21, 253, 148, 85, 33, 21, 165, 144, 85, 33, 21, 165, 253, 182, 
+    85, 33, 21, 240, 61, 72, 85, 33, 21, 242, 215, 72, 85, 33, 21, 72, 85, 
+    33, 21, 253, 149, 85, 33, 21, 240, 61, 73, 85, 33, 21, 242, 215, 73, 85, 
+    33, 21, 73, 85, 33, 21, 253, 151, 85, 21, 238, 72, 85, 254, 43, 85, 240, 
+    148, 21, 239, 233, 85, 240, 148, 21, 235, 163, 85, 242, 245, 238, 54, 85, 
+    242, 241, 238, 54, 85, 1, 253, 217, 85, 1, 243, 207, 85, 1, 243, 183, 85, 
+    1, 253, 163, 85, 1, 241, 75, 85, 1, 248, 246, 85, 1, 253, 179, 85, 1, 
+    249, 24, 85, 1, 165, 253, 182, 85, 1, 165, 253, 191, 85, 33, 21, 165, 
+    162, 85, 33, 21, 165, 253, 191, 85, 240, 111, 85, 45, 240, 111, 85, 26, 
+    242, 217, 85, 26, 127, 85, 26, 111, 85, 26, 166, 85, 26, 177, 85, 26, 
+    176, 85, 26, 187, 85, 26, 203, 85, 26, 195, 85, 26, 202, 85, 232, 88, 52, 
+    85, 1, 238, 62, 208, 101, 21, 232, 77, 101, 21, 235, 61, 101, 21, 236, 
+    173, 101, 1, 67, 101, 1, 253, 140, 101, 1, 71, 101, 1, 253, 142, 101, 1, 
+    79, 101, 1, 253, 148, 101, 1, 165, 144, 101, 1, 165, 162, 101, 1, 72, 
+    101, 1, 253, 149, 101, 1, 73, 101, 1, 253, 151, 101, 1, 201, 101, 1, 248, 
+    61, 101, 1, 253, 139, 101, 1, 248, 77, 101, 1, 248, 50, 101, 1, 253, 152, 
+    101, 1, 248, 57, 101, 1, 253, 146, 101, 1, 248, 89, 101, 1, 248, 78, 101, 
+    1, 248, 71, 101, 1, 242, 247, 101, 1, 248, 75, 101, 1, 242, 249, 101, 1, 
+    248, 82, 101, 1, 253, 126, 101, 1, 248, 55, 101, 1, 253, 133, 101, 1, 
+    248, 76, 101, 1, 253, 131, 101, 1, 253, 129, 101, 1, 248, 65, 101, 1, 
+    253, 141, 101, 1, 248, 81, 101, 1, 222, 101, 1, 216, 101, 1, 253, 130, 
+    101, 1, 253, 134, 101, 1, 248, 46, 101, 1, 248, 66, 101, 1, 253, 132, 
+    101, 1, 219, 101, 21, 240, 81, 101, 21, 235, 80, 101, 33, 21, 253, 140, 
+    101, 33, 21, 71, 101, 33, 21, 253, 142, 101, 33, 21, 79, 101, 33, 21, 
+    253, 148, 101, 33, 21, 165, 144, 101, 33, 21, 165, 253, 182, 101, 33, 21, 
+    72, 101, 33, 21, 253, 149, 101, 33, 21, 73, 101, 33, 21, 253, 151, 101, 
+    21, 238, 72, 101, 1, 241, 200, 253, 126, 101, 255, 39, 240, 51, 69, 101, 
+    1, 248, 96, 101, 1, 248, 246, 101, 1, 249, 24, 101, 1, 165, 253, 182, 
+    101, 1, 165, 253, 191, 101, 33, 21, 165, 162, 101, 33, 21, 165, 253, 191, 
+    101, 26, 242, 217, 101, 26, 127, 101, 26, 111, 101, 26, 166, 101, 26, 
+    177, 101, 26, 176, 101, 26, 187, 101, 26, 203, 101, 26, 195, 101, 26, 
+    202, 101, 1, 255, 63, 2, 240, 1, 235, 86, 101, 1, 255, 63, 2, 168, 235, 
+    86, 101, 243, 44, 69, 101, 243, 44, 52, 101, 236, 181, 235, 79, 127, 101, 
+    236, 181, 235, 79, 111, 101, 236, 181, 235, 79, 166, 101, 236, 181, 235, 
+    79, 177, 101, 236, 181, 235, 79, 253, 125, 251, 190, 249, 1, 253, 145, 
+    232, 129, 101, 236, 181, 233, 131, 236, 202, 101, 238, 191, 133, 21, 249, 
+    233, 240, 160, 133, 21, 240, 160, 133, 21, 236, 173, 133, 1, 67, 133, 1, 
+    253, 140, 133, 1, 71, 133, 1, 253, 142, 133, 1, 79, 133, 1, 253, 148, 
+    133, 1, 253, 164, 133, 1, 253, 149, 133, 1, 253, 156, 133, 1, 253, 151, 
+    133, 1, 201, 133, 1, 248, 61, 133, 1, 253, 139, 133, 1, 248, 77, 133, 1, 
+    248, 50, 133, 1, 253, 152, 133, 1, 248, 57, 133, 1, 253, 146, 133, 1, 
+    248, 89, 133, 1, 248, 78, 133, 1, 248, 71, 133, 1, 242, 247, 133, 1, 248, 
+    75, 133, 1, 242, 249, 133, 1, 248, 82, 133, 1, 253, 126, 133, 1, 248, 55, 
+    133, 1, 253, 133, 133, 1, 248, 76, 133, 1, 253, 131, 133, 1, 253, 129, 
+    133, 1, 248, 65, 133, 1, 253, 141, 133, 1, 248, 81, 133, 1, 222, 133, 1, 
+    216, 133, 1, 253, 130, 133, 1, 253, 134, 133, 1, 248, 94, 133, 1, 253, 
+    171, 133, 1, 248, 46, 133, 1, 253, 132, 133, 1, 219, 133, 21, 240, 81, 
+    133, 33, 21, 253, 140, 133, 33, 21, 71, 133, 33, 21, 253, 142, 133, 33, 
+    21, 79, 133, 33, 21, 253, 148, 133, 33, 21, 253, 164, 133, 33, 21, 253, 
+    149, 133, 33, 21, 253, 156, 133, 33, 21, 253, 151, 133, 21, 238, 72, 133, 
+    1, 243, 207, 133, 1, 243, 183, 133, 1, 253, 163, 133, 1, 248, 96, 133, 1, 
+    253, 179, 133, 26, 242, 217, 133, 26, 127, 133, 26, 111, 133, 26, 166, 
+    133, 26, 177, 133, 26, 176, 133, 26, 187, 133, 26, 203, 133, 26, 195, 
+    133, 26, 202, 133, 242, 154, 133, 241, 5, 133, 251, 107, 133, 253, 2, 
+    133, 255, 73, 242, 41, 112, 21, 232, 77, 112, 21, 235, 61, 112, 21, 236, 
+    173, 112, 1, 67, 112, 1, 253, 140, 112, 1, 71, 112, 1, 253, 142, 112, 1, 
+    79, 112, 1, 253, 148, 112, 1, 165, 144, 112, 1, 165, 162, 112, 33, 240, 
+    61, 72, 112, 1, 72, 112, 1, 253, 149, 112, 33, 240, 61, 73, 112, 1, 73, 
+    112, 1, 253, 151, 112, 1, 201, 112, 1, 248, 61, 112, 1, 253, 139, 112, 1, 
+    248, 77, 112, 1, 248, 50, 112, 1, 253, 152, 112, 1, 248, 57, 112, 1, 253, 
+    146, 112, 1, 248, 89, 112, 1, 248, 78, 112, 1, 248, 71, 112, 1, 242, 247, 
+    112, 1, 248, 75, 112, 1, 242, 249, 112, 1, 248, 82, 112, 1, 253, 126, 
+    112, 1, 248, 55, 112, 1, 253, 133, 112, 1, 248, 76, 112, 1, 253, 131, 
+    112, 1, 253, 129, 112, 1, 248, 65, 112, 1, 253, 141, 112, 1, 248, 81, 
+    112, 1, 222, 112, 1, 216, 112, 1, 253, 130, 112, 1, 253, 134, 112, 1, 
+    248, 94, 112, 1, 253, 171, 112, 1, 248, 46, 112, 1, 248, 66, 112, 1, 253, 
+    132, 112, 1, 219, 112, 21, 240, 81, 112, 21, 235, 80, 112, 33, 21, 253, 
+    140, 112, 33, 21, 71, 112, 33, 21, 253, 142, 112, 33, 21, 79, 112, 33, 
+    21, 253, 148, 112, 33, 21, 165, 144, 112, 33, 21, 165, 253, 182, 112, 33, 
+    21, 240, 61, 72, 112, 33, 21, 72, 112, 33, 21, 253, 149, 112, 33, 21, 
+    240, 61, 73, 112, 33, 21, 73, 112, 33, 21, 253, 151, 112, 21, 238, 72, 
+    112, 254, 43, 112, 1, 165, 253, 182, 112, 1, 165, 253, 191, 112, 33, 21, 
+    165, 162, 112, 33, 21, 165, 253, 191, 112, 26, 242, 217, 112, 26, 127, 
+    112, 26, 111, 112, 26, 166, 112, 26, 177, 112, 26, 176, 112, 26, 187, 
+    112, 26, 203, 112, 26, 195, 112, 26, 202, 112, 243, 44, 52, 118, 21, 232, 
+    77, 118, 21, 235, 61, 118, 21, 236, 173, 118, 1, 67, 118, 1, 253, 140, 
+    118, 1, 71, 118, 1, 253, 142, 118, 1, 79, 118, 1, 253, 148, 118, 1, 165, 
+    144, 118, 1, 165, 162, 118, 1, 72, 118, 1, 253, 149, 118, 1, 73, 118, 1, 
+    253, 151, 118, 1, 201, 118, 1, 248, 61, 118, 1, 253, 139, 118, 1, 248, 
+    77, 118, 1, 248, 50, 118, 1, 253, 152, 118, 1, 248, 57, 118, 1, 253, 146, 
+    118, 1, 248, 89, 118, 1, 248, 78, 118, 1, 248, 71, 118, 1, 242, 247, 118, 
+    1, 248, 75, 118, 1, 242, 249, 118, 1, 248, 82, 118, 1, 253, 126, 118, 1, 
+    248, 55, 118, 1, 253, 133, 118, 1, 248, 76, 118, 1, 253, 131, 118, 1, 
+    253, 129, 118, 1, 248, 65, 118, 1, 253, 141, 118, 1, 248, 81, 118, 1, 
+    222, 118, 1, 216, 118, 1, 253, 130, 118, 1, 253, 134, 118, 1, 248, 94, 
+    118, 1, 253, 171, 118, 1, 248, 46, 118, 1, 248, 66, 118, 1, 253, 132, 
+    118, 1, 219, 118, 21, 240, 81, 118, 21, 235, 80, 118, 33, 21, 253, 140, 
+    118, 33, 21, 71, 118, 33, 21, 253, 142, 118, 33, 21, 79, 118, 33, 21, 
+    253, 148, 118, 33, 21, 165, 144, 118, 33, 21, 72, 118, 33, 21, 253, 149, 
+    118, 33, 21, 73, 118, 33, 21, 253, 151, 118, 21, 238, 72, 118, 255, 37, 
+    240, 51, 69, 118, 255, 39, 240, 51, 69, 118, 1, 248, 96, 118, 1, 248, 
+    246, 118, 1, 249, 24, 118, 1, 165, 253, 182, 118, 1, 165, 253, 191, 118, 
+    26, 242, 217, 118, 26, 127, 118, 26, 111, 118, 26, 166, 118, 26, 177, 
+    118, 26, 176, 118, 26, 187, 118, 26, 203, 118, 26, 195, 118, 26, 202, 
+    118, 238, 191, 118, 1, 253, 138, 140, 21, 235, 61, 140, 21, 236, 173, 
+    140, 1, 67, 140, 1, 253, 140, 140, 1, 71, 140, 1, 253, 142, 140, 1, 79, 
+    140, 1, 253, 148, 140, 1, 72, 140, 1, 253, 164, 140, 1, 253, 149, 140, 1, 
+    73, 140, 1, 253, 156, 140, 1, 253, 151, 140, 1, 201, 140, 1, 248, 50, 
+    140, 1, 253, 152, 140, 1, 253, 146, 140, 1, 248, 78, 140, 1, 248, 71, 
+    140, 1, 248, 82, 140, 1, 253, 126, 140, 1, 253, 131, 140, 1, 243, 234, 
+    140, 1, 253, 129, 140, 1, 222, 140, 1, 216, 140, 1, 253, 130, 140, 1, 
+    248, 96, 140, 1, 253, 134, 140, 1, 248, 94, 140, 1, 243, 104, 140, 1, 
+    253, 171, 140, 1, 248, 46, 140, 1, 248, 66, 140, 1, 253, 132, 140, 1, 
+    219, 140, 33, 21, 253, 140, 140, 33, 21, 71, 140, 33, 21, 253, 142, 140, 
+    33, 21, 79, 140, 33, 21, 253, 148, 140, 33, 21, 72, 140, 33, 21, 253, 
+    164, 140, 33, 21, 253, 149, 140, 33, 21, 73, 140, 33, 21, 253, 156, 140, 
+    33, 21, 253, 151, 140, 21, 238, 72, 140, 255, 39, 240, 51, 69, 140, 26, 
+    242, 217, 140, 26, 127, 140, 26, 111, 140, 26, 166, 140, 26, 177, 140, 
+    26, 176, 140, 26, 187, 140, 26, 203, 140, 26, 195, 140, 26, 202, 140, 61, 
+    248, 53, 140, 61, 253, 125, 236, 149, 140, 61, 253, 125, 235, 49, 140, 
+    253, 137, 52, 140, 246, 90, 52, 140, 249, 206, 52, 140, 245, 59, 52, 140, 
+    241, 68, 52, 140, 255, 24, 60, 52, 140, 243, 44, 52, 140, 61, 52, 124, 
+    21, 232, 77, 124, 21, 235, 61, 124, 21, 236, 173, 124, 1, 67, 124, 1, 
+    253, 140, 124, 1, 71, 124, 1, 253, 142, 124, 1, 79, 124, 1, 253, 148, 
+    124, 1, 165, 144, 124, 1, 165, 162, 124, 1, 72, 124, 1, 253, 164, 124, 1, 
+    253, 149, 124, 1, 73, 124, 1, 253, 156, 124, 1, 253, 151, 124, 1, 201, 
+    124, 1, 248, 61, 124, 1, 253, 139, 124, 1, 248, 77, 124, 1, 248, 50, 124, 
+    1, 253, 152, 124, 1, 248, 57, 124, 1, 253, 146, 124, 1, 248, 89, 124, 1, 
+    248, 78, 124, 1, 248, 71, 124, 1, 242, 247, 124, 1, 248, 75, 124, 1, 242, 
+    249, 124, 1, 248, 82, 124, 1, 253, 126, 124, 1, 248, 55, 124, 1, 253, 
+    133, 124, 1, 248, 76, 124, 1, 253, 131, 124, 1, 253, 129, 124, 1, 248, 
+    65, 124, 1, 253, 141, 124, 1, 248, 81, 124, 1, 222, 124, 1, 216, 124, 1, 
+    253, 130, 124, 1, 248, 96, 124, 1, 253, 134, 124, 1, 248, 94, 124, 1, 
+    253, 171, 124, 1, 248, 46, 124, 1, 248, 66, 124, 1, 253, 132, 124, 1, 
+    219, 124, 33, 21, 253, 140, 124, 33, 21, 71, 124, 33, 21, 253, 142, 124, 
+    33, 21, 79, 124, 33, 21, 253, 148, 124, 33, 21, 165, 144, 124, 33, 21, 
+    165, 253, 182, 124, 33, 21, 72, 124, 33, 21, 253, 164, 124, 33, 21, 253, 
+    149, 124, 33, 21, 73, 124, 33, 21, 253, 156, 124, 33, 21, 253, 151, 124, 
+    21, 238, 72, 124, 240, 51, 69, 124, 255, 37, 240, 51, 69, 124, 1, 165, 
+    253, 182, 124, 1, 165, 253, 191, 124, 26, 242, 217, 124, 26, 127, 124, 
+    26, 111, 124, 26, 166, 124, 26, 177, 124, 26, 176, 124, 26, 187, 124, 26, 
+    203, 124, 26, 195, 124, 26, 202, 115, 21, 235, 61, 115, 21, 236, 173, 
+    115, 1, 67, 115, 1, 253, 140, 115, 1, 71, 115, 1, 253, 142, 115, 1, 79, 
+    115, 1, 253, 148, 115, 1, 165, 144, 115, 1, 165, 162, 115, 1, 72, 115, 1, 
+    253, 164, 115, 1, 253, 149, 115, 1, 73, 115, 1, 253, 156, 115, 1, 253, 
+    151, 115, 1, 201, 115, 1, 248, 61, 115, 1, 253, 139, 115, 1, 248, 77, 
+    115, 1, 248, 50, 115, 1, 253, 152, 115, 1, 248, 57, 115, 1, 253, 146, 
+    115, 1, 248, 89, 115, 1, 248, 78, 115, 1, 248, 71, 115, 1, 242, 247, 115, 
+    1, 248, 75, 115, 1, 242, 249, 115, 1, 248, 82, 115, 1, 253, 126, 115, 1, 
+    248, 55, 115, 1, 253, 133, 115, 1, 248, 76, 115, 1, 253, 131, 115, 1, 
+    253, 129, 115, 1, 248, 65, 115, 1, 253, 141, 115, 1, 248, 81, 115, 1, 
+    222, 115, 1, 216, 115, 1, 253, 130, 115, 1, 248, 96, 115, 1, 253, 134, 
+    115, 1, 248, 94, 115, 1, 253, 171, 115, 1, 248, 46, 115, 1, 248, 66, 115, 
+    1, 253, 132, 115, 1, 219, 115, 21, 240, 81, 115, 21, 235, 80, 115, 33, 
+    21, 253, 140, 115, 33, 21, 71, 115, 33, 21, 253, 142, 115, 33, 21, 79, 
+    115, 33, 21, 253, 148, 115, 33, 21, 165, 144, 115, 33, 21, 165, 253, 182, 
+    115, 33, 21, 72, 115, 33, 21, 253, 164, 115, 33, 21, 253, 149, 115, 33, 
+    21, 73, 115, 33, 21, 253, 156, 115, 33, 21, 253, 151, 115, 21, 238, 72, 
+    115, 240, 51, 69, 115, 255, 37, 240, 51, 69, 115, 1, 253, 179, 115, 1, 
+    165, 253, 182, 115, 1, 165, 253, 191, 115, 26, 242, 217, 115, 26, 127, 
+    115, 26, 111, 115, 26, 166, 115, 26, 177, 115, 26, 176, 115, 26, 187, 
+    115, 26, 203, 115, 26, 195, 115, 26, 202, 130, 21, 235, 61, 130, 21, 236, 
+    173, 130, 1, 67, 130, 1, 253, 140, 130, 1, 71, 130, 1, 253, 142, 130, 1, 
+    79, 130, 1, 253, 148, 130, 1, 165, 144, 130, 1, 165, 162, 130, 1, 72, 
+    130, 1, 253, 164, 130, 1, 253, 149, 130, 1, 73, 130, 1, 253, 156, 130, 1, 
+    253, 151, 130, 1, 201, 130, 1, 248, 61, 130, 1, 253, 139, 130, 1, 248, 
+    77, 130, 1, 248, 50, 130, 1, 253, 152, 130, 1, 248, 57, 130, 1, 253, 146, 
+    130, 1, 248, 89, 130, 1, 248, 78, 130, 1, 248, 71, 130, 1, 242, 247, 130, 
+    1, 248, 75, 130, 1, 242, 249, 130, 1, 248, 82, 130, 1, 253, 126, 130, 1, 
+    248, 55, 130, 1, 253, 133, 130, 1, 248, 76, 130, 1, 253, 131, 130, 1, 
+    253, 129, 130, 1, 248, 65, 130, 1, 253, 141, 130, 1, 248, 81, 130, 1, 
+    222, 130, 1, 216, 130, 1, 253, 130, 130, 1, 248, 96, 130, 1, 253, 134, 
+    130, 1, 248, 94, 130, 1, 243, 104, 130, 1, 253, 171, 130, 1, 248, 46, 
+    130, 1, 248, 66, 130, 1, 253, 132, 130, 1, 219, 130, 33, 21, 253, 140, 
+    130, 33, 21, 71, 130, 33, 21, 253, 142, 130, 33, 21, 79, 130, 33, 21, 
+    253, 148, 130, 33, 21, 165, 144, 130, 33, 21, 72, 130, 33, 21, 253, 164, 
+    130, 33, 21, 253, 149, 130, 33, 21, 73, 130, 33, 21, 253, 156, 130, 33, 
+    21, 253, 151, 130, 21, 238, 72, 130, 255, 39, 240, 51, 69, 130, 1, 165, 
+    253, 182, 130, 1, 165, 253, 191, 130, 26, 242, 217, 130, 26, 127, 130, 
+    26, 111, 130, 26, 166, 130, 26, 177, 130, 26, 176, 130, 26, 187, 130, 26, 
+    203, 130, 26, 195, 130, 26, 202, 123, 21, 233, 115, 123, 21, 235, 39, 
+    123, 1, 239, 0, 123, 1, 237, 53, 123, 1, 237, 56, 123, 1, 235, 161, 123, 
+    1, 239, 102, 123, 1, 237, 178, 123, 1, 239, 237, 123, 1, 238, 39, 123, 1, 
+    236, 41, 123, 1, 234, 209, 123, 1, 236, 37, 123, 1, 234, 202, 123, 1, 
+    239, 59, 123, 1, 237, 146, 123, 1, 237, 57, 123, 1, 239, 156, 123, 1, 
+    237, 227, 123, 1, 237, 68, 123, 1, 234, 8, 237, 16, 123, 1, 233, 58, 237, 
+    16, 123, 1, 234, 8, 236, 226, 123, 1, 233, 58, 236, 226, 123, 1, 239, 
+    105, 233, 89, 123, 1, 238, 122, 236, 226, 123, 1, 234, 8, 236, 250, 123, 
+    1, 233, 58, 236, 250, 123, 1, 234, 8, 236, 228, 123, 1, 233, 58, 236, 
+    228, 123, 1, 238, 154, 233, 89, 123, 1, 238, 154, 238, 1, 232, 185, 123, 
+    1, 238, 122, 236, 228, 123, 1, 234, 8, 235, 155, 123, 1, 233, 58, 235, 
+    155, 123, 1, 234, 8, 235, 97, 123, 1, 233, 58, 235, 97, 123, 1, 235, 104, 
+    237, 25, 123, 1, 238, 122, 235, 97, 123, 1, 234, 8, 237, 46, 123, 1, 233, 
+    58, 237, 46, 123, 1, 234, 8, 236, 222, 123, 1, 233, 58, 236, 222, 123, 1, 
+    238, 134, 237, 25, 123, 1, 238, 122, 236, 222, 123, 1, 234, 8, 237, 27, 
+    123, 1, 233, 58, 237, 27, 123, 1, 234, 8, 236, 220, 123, 1, 233, 58, 236, 
+    220, 123, 1, 237, 205, 123, 1, 249, 237, 236, 220, 123, 1, 238, 47, 123, 
+    1, 237, 247, 123, 1, 238, 134, 237, 20, 123, 1, 238, 41, 123, 1, 238, 
+    154, 236, 238, 123, 1, 235, 104, 236, 238, 123, 1, 238, 134, 236, 238, 
+    123, 1, 237, 171, 123, 1, 235, 104, 237, 20, 123, 1, 237, 155, 123, 21, 
+    234, 90, 123, 33, 21, 233, 67, 123, 33, 21, 243, 102, 233, 81, 123, 33, 
+    21, 248, 107, 233, 81, 123, 33, 21, 243, 102, 235, 130, 123, 33, 21, 248, 
+    107, 235, 130, 123, 33, 21, 243, 102, 234, 60, 123, 33, 21, 248, 107, 
+    234, 60, 123, 33, 21, 231, 104, 123, 33, 21, 237, 17, 123, 33, 21, 248, 
+    107, 237, 17, 123, 33, 21, 246, 18, 245, 62, 123, 33, 21, 238, 141, 254, 
+    64, 233, 67, 123, 33, 21, 238, 141, 254, 64, 248, 107, 233, 67, 123, 33, 
+    21, 238, 141, 254, 64, 232, 90, 123, 33, 21, 232, 90, 123, 33, 21, 248, 
+    107, 231, 104, 123, 33, 21, 248, 107, 232, 90, 123, 233, 51, 233, 214, 
+    107, 99, 255, 59, 249, 91, 107, 99, 253, 249, 246, 9, 107, 99, 253, 249, 
+    241, 202, 107, 99, 253, 249, 241, 203, 107, 99, 253, 249, 246, 12, 107, 
+    99, 253, 249, 237, 245, 107, 99, 254, 213, 252, 19, 107, 99, 254, 35, 
+    244, 253, 107, 99, 254, 35, 241, 53, 107, 99, 254, 35, 241, 51, 107, 99, 
+    255, 35, 253, 186, 107, 99, 254, 35, 245, 5, 107, 99, 255, 66, 247, 230, 
+    107, 99, 255, 48, 241, 49, 107, 99, 153, 242, 49, 107, 99, 253, 240, 243, 
+    127, 107, 99, 253, 240, 233, 218, 107, 99, 253, 240, 237, 237, 107, 99, 
+    255, 51, 252, 12, 107, 99, 255, 48, 250, 188, 107, 99, 153, 252, 208, 
+    107, 99, 253, 240, 242, 152, 107, 99, 253, 240, 239, 218, 107, 99, 253, 
+    240, 242, 151, 107, 99, 255, 51, 253, 150, 107, 99, 255, 69, 239, 2, 107, 
+    99, 255, 88, 252, 70, 107, 99, 254, 27, 242, 60, 107, 99, 255, 41, 253, 
+    179, 107, 99, 254, 27, 246, 244, 107, 99, 255, 41, 250, 233, 107, 99, 
+    254, 27, 238, 0, 107, 99, 255, 83, 222, 107, 99, 255, 66, 249, 20, 107, 
+    99, 255, 90, 252, 150, 107, 99, 253, 185, 107, 99, 255, 43, 243, 215, 
+    107, 99, 254, 8, 107, 99, 255, 96, 247, 191, 107, 99, 255, 35, 247, 63, 
+    107, 99, 255, 35, 247, 57, 107, 99, 255, 35, 252, 191, 107, 99, 255, 32, 
+    251, 62, 107, 99, 255, 43, 241, 55, 107, 99, 117, 248, 124, 107, 99, 255, 
+    32, 239, 145, 107, 99, 234, 231, 107, 99, 248, 83, 67, 107, 99, 253, 205, 
+    236, 32, 107, 99, 248, 83, 253, 140, 107, 99, 248, 83, 254, 32, 107, 99, 
+    248, 83, 71, 107, 99, 248, 83, 253, 142, 107, 99, 248, 83, 253, 252, 107, 
+    99, 248, 83, 252, 249, 107, 99, 248, 83, 79, 107, 99, 248, 83, 253, 148, 
+    107, 99, 237, 236, 107, 236, 181, 12, 244, 190, 107, 99, 248, 83, 72, 
+    107, 99, 248, 83, 253, 178, 107, 99, 248, 83, 73, 107, 99, 248, 83, 255, 
+    37, 237, 198, 107, 99, 248, 83, 255, 37, 236, 55, 107, 99, 232, 181, 107, 
+    99, 236, 56, 107, 99, 234, 220, 107, 99, 253, 205, 254, 90, 107, 99, 253, 
+    205, 248, 97, 107, 99, 253, 205, 252, 229, 107, 99, 253, 205, 235, 188, 
+    107, 99, 233, 41, 107, 99, 236, 63, 107, 99, 236, 141, 107, 99, 237, 158, 
+    107, 26, 242, 217, 107, 26, 127, 107, 26, 111, 107, 26, 166, 107, 26, 
+    177, 107, 26, 176, 107, 26, 187, 107, 26, 203, 107, 26, 195, 107, 26, 
+    202, 107, 99, 233, 113, 107, 99, 239, 108, 152, 1, 253, 190, 152, 1, 253, 
+    249, 243, 35, 152, 1, 253, 249, 248, 120, 152, 1, 248, 172, 152, 1, 253, 
+    224, 152, 1, 255, 35, 248, 120, 152, 1, 248, 133, 152, 1, 253, 225, 152, 
+    1, 87, 152, 1, 253, 240, 243, 35, 152, 1, 253, 240, 248, 120, 152, 1, 
+    253, 173, 152, 1, 254, 1, 152, 1, 253, 208, 152, 1, 254, 27, 243, 35, 
+    152, 1, 255, 41, 248, 120, 152, 1, 254, 27, 248, 120, 152, 1, 255, 41, 
+    243, 35, 152, 1, 253, 181, 152, 1, 253, 162, 152, 1, 255, 43, 243, 215, 
+    152, 1, 255, 43, 246, 54, 152, 1, 253, 177, 152, 1, 255, 35, 243, 35, 
+    152, 1, 255, 32, 243, 35, 152, 1, 73, 152, 1, 255, 32, 248, 120, 152, 
+    235, 69, 152, 33, 21, 67, 152, 33, 21, 253, 205, 248, 162, 152, 33, 21, 
+    253, 140, 152, 33, 21, 254, 32, 152, 33, 21, 71, 152, 33, 21, 253, 142, 
+    152, 33, 21, 255, 14, 152, 33, 21, 254, 77, 152, 33, 21, 79, 152, 33, 21, 
+    253, 148, 152, 33, 21, 253, 205, 251, 159, 152, 235, 143, 21, 253, 216, 
+    152, 235, 143, 21, 248, 133, 152, 33, 21, 72, 152, 33, 21, 254, 89, 152, 
+    33, 21, 73, 152, 33, 21, 254, 33, 152, 33, 21, 253, 149, 152, 255, 59, 
+    253, 134, 152, 188, 253, 205, 254, 90, 152, 188, 253, 205, 248, 97, 152, 
+    188, 253, 205, 253, 212, 152, 188, 253, 205, 239, 18, 152, 232, 118, 69, 
+    152, 234, 227, 152, 26, 242, 217, 152, 26, 127, 152, 26, 111, 152, 26, 
+    166, 152, 26, 177, 152, 26, 176, 152, 26, 187, 152, 26, 203, 152, 26, 
+    195, 152, 26, 202, 152, 255, 32, 253, 173, 152, 255, 32, 253, 181, 47, 4, 
+    254, 43, 47, 158, 248, 129, 253, 221, 253, 226, 236, 133, 67, 47, 158, 
+    248, 129, 253, 221, 253, 226, 254, 79, 249, 155, 250, 112, 222, 47, 158, 
+    248, 129, 253, 221, 253, 226, 254, 79, 248, 129, 243, 49, 222, 47, 158, 
+    54, 253, 221, 253, 226, 251, 224, 222, 47, 158, 238, 171, 253, 221, 253, 
+    226, 252, 173, 222, 47, 158, 243, 25, 253, 221, 253, 226, 249, 137, 249, 
+    161, 222, 47, 158, 253, 221, 253, 226, 243, 49, 249, 161, 222, 47, 158, 
+    247, 65, 243, 23, 47, 158, 244, 230, 253, 221, 248, 167, 47, 158, 250, 
+    127, 249, 162, 253, 221, 248, 167, 47, 158, 231, 143, 240, 249, 47, 158, 
+    235, 202, 243, 49, 241, 40, 47, 158, 243, 23, 47, 158, 248, 234, 243, 23, 
+    47, 158, 243, 49, 243, 23, 47, 158, 248, 234, 243, 49, 243, 23, 47, 158, 
+    254, 235, 250, 159, 242, 126, 243, 23, 47, 158, 249, 154, 251, 29, 243, 
+    23, 47, 158, 243, 25, 243, 140, 243, 72, 255, 81, 183, 248, 100, 47, 158, 
+    248, 129, 240, 249, 47, 237, 22, 21, 250, 158, 240, 70, 47, 237, 22, 21, 
+    251, 192, 240, 70, 47, 232, 89, 21, 252, 175, 251, 12, 244, 67, 240, 70, 
+    47, 232, 89, 21, 241, 3, 253, 129, 47, 232, 89, 21, 247, 67, 239, 230, 
+    47, 21, 248, 101, 248, 151, 243, 179, 47, 21, 248, 101, 248, 151, 240, 
+    183, 47, 21, 248, 101, 248, 151, 243, 187, 47, 21, 248, 101, 254, 66, 
+    243, 179, 47, 21, 248, 101, 254, 66, 240, 183, 47, 21, 248, 101, 248, 
+    151, 248, 101, 251, 252, 47, 26, 242, 217, 47, 26, 127, 47, 26, 111, 47, 
+    26, 166, 47, 26, 177, 47, 26, 176, 47, 26, 187, 47, 26, 203, 47, 26, 195, 
+    47, 26, 202, 47, 26, 137, 127, 47, 26, 137, 111, 47, 26, 137, 166, 47, 
+    26, 137, 177, 47, 26, 137, 176, 47, 26, 137, 187, 47, 26, 137, 203, 47, 
+    26, 137, 195, 47, 26, 137, 202, 47, 26, 137, 242, 217, 47, 158, 244, 228, 
+    240, 70, 47, 158, 249, 119, 243, 153, 254, 116, 253, 108, 47, 158, 243, 
+    25, 243, 140, 243, 72, 248, 199, 254, 112, 248, 100, 47, 158, 249, 119, 
+    243, 153, 252, 174, 240, 70, 47, 158, 253, 223, 248, 167, 47, 158, 254, 
+    129, 241, 4, 47, 158, 254, 95, 243, 72, 243, 189, 47, 158, 254, 95, 243, 
+    72, 243, 188, 47, 158, 254, 80, 243, 206, 243, 189, 47, 158, 254, 80, 
+    243, 206, 243, 188, 47, 21, 255, 8, 240, 250, 47, 21, 254, 198, 240, 250, 
+    47, 1, 201, 47, 1, 248, 61, 47, 1, 253, 139, 47, 1, 248, 77, 47, 1, 248, 
+    50, 47, 1, 253, 152, 47, 1, 248, 57, 47, 1, 253, 146, 47, 1, 248, 78, 47, 
+    1, 248, 71, 47, 1, 242, 247, 47, 1, 248, 75, 47, 1, 242, 249, 47, 1, 248, 
+    82, 47, 1, 253, 126, 47, 1, 248, 55, 47, 1, 253, 133, 47, 1, 248, 76, 47, 
+    1, 253, 131, 47, 1, 253, 129, 47, 1, 248, 65, 47, 1, 253, 141, 47, 1, 
+    248, 81, 47, 1, 222, 47, 1, 248, 90, 47, 1, 243, 130, 47, 1, 248, 153, 
+    47, 1, 243, 165, 47, 1, 253, 138, 47, 1, 248, 99, 47, 1, 253, 163, 47, 1, 
+    254, 78, 47, 1, 216, 47, 1, 253, 130, 47, 1, 253, 134, 47, 1, 248, 46, 
+    47, 1, 248, 66, 47, 1, 253, 132, 47, 1, 219, 47, 1, 67, 47, 1, 243, 210, 
+    47, 1, 234, 28, 253, 130, 47, 33, 21, 253, 140, 47, 33, 21, 71, 47, 33, 
+    21, 253, 142, 47, 33, 21, 79, 47, 33, 21, 253, 148, 47, 33, 21, 165, 144, 
+    47, 33, 21, 165, 253, 182, 47, 33, 21, 165, 162, 47, 33, 21, 165, 253, 
+    191, 47, 33, 21, 72, 47, 33, 21, 253, 164, 47, 33, 21, 73, 47, 33, 21, 
+    253, 156, 47, 21, 252, 140, 255, 91, 254, 212, 253, 160, 47, 21, 249, 
+    155, 244, 212, 47, 33, 21, 224, 71, 47, 33, 21, 224, 253, 142, 47, 21, 
+    254, 116, 255, 12, 254, 210, 253, 133, 47, 21, 254, 239, 246, 39, 47, 
+    158, 237, 168, 47, 158, 239, 157, 47, 21, 254, 192, 240, 70, 47, 21, 248, 
+    122, 240, 70, 47, 21, 254, 191, 254, 129, 248, 100, 47, 21, 251, 223, 
+    248, 100, 47, 21, 254, 94, 254, 148, 237, 34, 47, 21, 254, 94, 254, 200, 
+    237, 34, 47, 213, 1, 201, 47, 213, 1, 248, 61, 47, 213, 1, 253, 139, 47, 
+    213, 1, 248, 77, 47, 213, 1, 248, 50, 47, 213, 1, 253, 152, 47, 213, 1, 
+    248, 57, 47, 213, 1, 253, 146, 47, 213, 1, 248, 78, 47, 213, 1, 248, 71, 
+    47, 213, 1, 242, 247, 47, 213, 1, 248, 75, 47, 213, 1, 242, 249, 47, 213, 
+    1, 248, 82, 47, 213, 1, 253, 126, 47, 213, 1, 248, 55, 47, 213, 1, 253, 
+    133, 47, 213, 1, 248, 76, 47, 213, 1, 253, 131, 47, 213, 1, 253, 129, 47, 
+    213, 1, 248, 65, 47, 213, 1, 253, 141, 47, 213, 1, 248, 81, 47, 213, 1, 
+    222, 47, 213, 1, 248, 90, 47, 213, 1, 243, 130, 47, 213, 1, 248, 153, 47, 
+    213, 1, 243, 165, 47, 213, 1, 253, 138, 47, 213, 1, 248, 99, 47, 213, 1, 
+    253, 163, 47, 213, 1, 254, 78, 47, 213, 1, 216, 47, 213, 1, 253, 130, 47, 
+    213, 1, 253, 134, 47, 213, 1, 248, 46, 47, 213, 1, 248, 66, 47, 213, 1, 
+    253, 132, 47, 213, 1, 219, 47, 213, 1, 67, 47, 213, 1, 243, 210, 47, 213, 
+    1, 234, 28, 253, 138, 47, 213, 1, 234, 28, 216, 47, 213, 1, 234, 28, 253, 
+    130, 47, 255, 60, 255, 64, 248, 61, 47, 255, 60, 255, 64, 254, 183, 248, 
+    199, 254, 112, 248, 100, 47, 232, 82, 21, 96, 243, 147, 47, 232, 82, 21, 
+    136, 243, 147, 47, 232, 82, 21, 250, 144, 247, 138, 47, 232, 82, 21, 252, 
+    170, 241, 2, 47, 12, 250, 206, 253, 243, 47, 12, 254, 124, 252, 139, 47, 
+    12, 246, 237, 245, 97, 47, 12, 254, 124, 254, 236, 249, 154, 245, 127, 
+    47, 12, 249, 137, 253, 129, 47, 12, 253, 192, 253, 243, 47, 12, 253, 192, 
+    255, 47, 248, 234, 238, 127, 47, 12, 253, 192, 255, 47, 251, 30, 238, 
+    127, 47, 12, 253, 192, 255, 47, 248, 199, 238, 127, 47, 21, 248, 101, 
+    254, 66, 243, 187, 47, 158, 244, 229, 249, 162, 255, 57, 253, 226, 240, 
+    216, 47, 158, 246, 89, 253, 221, 255, 57, 253, 226, 240, 216, 131, 1, 
+    201, 131, 1, 248, 61, 131, 1, 253, 139, 131, 1, 248, 77, 131, 1, 248, 50, 
+    131, 1, 253, 152, 131, 1, 248, 57, 131, 1, 253, 146, 131, 1, 248, 89, 
+    131, 1, 248, 78, 131, 1, 246, 175, 131, 1, 248, 71, 131, 1, 242, 247, 
+    131, 1, 248, 75, 131, 1, 242, 249, 131, 1, 248, 82, 131, 1, 253, 126, 
+    131, 1, 248, 55, 131, 1, 253, 133, 131, 1, 248, 76, 131, 1, 253, 131, 
+    131, 1, 253, 129, 131, 1, 248, 65, 131, 1, 253, 141, 131, 1, 248, 81, 
+    131, 1, 222, 131, 1, 216, 131, 1, 253, 130, 131, 1, 253, 134, 131, 1, 
+    253, 138, 131, 1, 253, 132, 131, 1, 219, 131, 1, 248, 94, 131, 1, 67, 
+    131, 1, 71, 131, 1, 253, 142, 131, 1, 79, 131, 1, 253, 148, 131, 1, 72, 
+    131, 1, 73, 131, 1, 253, 151, 131, 33, 21, 253, 140, 131, 33, 21, 71, 
+    131, 33, 21, 253, 142, 131, 33, 21, 79, 131, 33, 21, 253, 148, 131, 33, 
+    21, 72, 131, 33, 21, 253, 149, 131, 21, 235, 61, 131, 21, 53, 46, 131, 
+    21, 236, 173, 131, 21, 238, 72, 131, 26, 242, 217, 131, 26, 127, 131, 26, 
+    111, 131, 26, 166, 131, 26, 177, 131, 26, 176, 131, 26, 187, 131, 26, 
+    203, 131, 26, 195, 131, 26, 202, 131, 21, 240, 101, 236, 210, 131, 21, 
+    236, 210, 131, 12, 236, 52, 131, 12, 234, 102, 131, 12, 229, 63, 131, 12, 
+    236, 30, 131, 1, 248, 46, 131, 1, 248, 66, 131, 1, 165, 144, 131, 1, 165, 
+    253, 182, 131, 1, 165, 162, 131, 1, 165, 253, 191, 131, 33, 21, 165, 144, 
+    131, 33, 21, 165, 253, 182, 131, 33, 21, 165, 162, 131, 33, 21, 165, 253, 
+    191, 75, 5, 1, 254, 19, 75, 5, 1, 248, 195, 75, 5, 1, 248, 158, 75, 5, 1, 
+    248, 205, 75, 5, 1, 253, 202, 75, 5, 1, 249, 11, 75, 5, 1, 249, 25, 75, 
+    5, 1, 248, 253, 75, 5, 1, 253, 247, 75, 5, 1, 248, 162, 75, 5, 1, 248, 
+    224, 75, 5, 1, 248, 131, 75, 5, 1, 248, 171, 75, 5, 1, 254, 9, 75, 5, 1, 
+    248, 236, 75, 5, 1, 243, 138, 75, 5, 1, 248, 243, 75, 5, 1, 248, 134, 75, 
+    5, 1, 248, 254, 75, 5, 1, 254, 75, 75, 5, 1, 243, 115, 75, 5, 1, 243, 
+    103, 75, 5, 1, 243, 95, 75, 5, 1, 248, 242, 75, 5, 1, 243, 33, 75, 5, 1, 
+    243, 88, 75, 5, 1, 248, 100, 75, 5, 1, 248, 217, 75, 5, 1, 248, 201, 75, 
+    5, 1, 243, 87, 75, 5, 1, 249, 16, 75, 5, 1, 243, 101, 75, 5, 1, 248, 212, 
+    75, 5, 1, 253, 168, 75, 5, 1, 248, 160, 75, 5, 1, 253, 170, 75, 5, 1, 
+    248, 213, 75, 5, 1, 248, 215, 75, 1, 254, 19, 75, 1, 248, 195, 75, 1, 
+    248, 158, 75, 1, 248, 205, 75, 1, 253, 202, 75, 1, 249, 11, 75, 1, 249, 
+    25, 75, 1, 248, 253, 75, 1, 253, 247, 75, 1, 248, 162, 75, 1, 248, 224, 
+    75, 1, 248, 131, 75, 1, 248, 171, 75, 1, 254, 9, 75, 1, 248, 236, 75, 1, 
+    243, 138, 75, 1, 248, 243, 75, 1, 248, 134, 75, 1, 248, 254, 75, 1, 254, 
+    75, 75, 1, 243, 115, 75, 1, 243, 103, 75, 1, 243, 95, 75, 1, 248, 242, 
+    75, 1, 243, 33, 75, 1, 243, 88, 75, 1, 248, 100, 75, 1, 248, 217, 75, 1, 
+    248, 201, 75, 1, 243, 87, 75, 1, 249, 16, 75, 1, 243, 101, 75, 1, 248, 
+    212, 75, 1, 253, 168, 75, 1, 248, 160, 75, 1, 253, 170, 75, 1, 248, 213, 
+    75, 1, 248, 215, 75, 1, 253, 245, 75, 1, 255, 9, 75, 1, 241, 94, 75, 1, 
+    205, 248, 158, 75, 1, 248, 105, 75, 235, 91, 234, 6, 49, 1, 75, 248, 171, 
+    23, 102, 238, 99, 23, 102, 232, 87, 23, 102, 240, 80, 23, 102, 238, 102, 
+    23, 102, 232, 101, 23, 102, 240, 85, 23, 102, 240, 78, 23, 102, 240, 83, 
+    23, 102, 233, 79, 23, 102, 243, 34, 23, 102, 234, 32, 23, 102, 240, 75, 
+    23, 102, 240, 71, 23, 102, 233, 77, 23, 102, 236, 195, 23, 102, 236, 198, 
+    23, 102, 236, 205, 23, 102, 236, 201, 23, 102, 240, 74, 23, 102, 231, 
+    108, 23, 102, 233, 105, 23, 102, 231, 97, 23, 102, 232, 187, 23, 102, 
+    231, 56, 23, 102, 232, 108, 23, 102, 233, 106, 23, 102, 232, 85, 23, 102, 
+    231, 71, 23, 102, 232, 92, 23, 102, 231, 40, 23, 102, 231, 109, 23, 102, 
+    232, 195, 23, 102, 231, 110, 23, 102, 233, 66, 23, 102, 226, 243, 23, 
+    102, 226, 244, 23, 102, 227, 4, 23, 102, 229, 52, 23, 102, 227, 3, 23, 
+    102, 232, 106, 23, 102, 231, 75, 23, 102, 231, 52, 23, 102, 231, 51, 23, 
+    102, 231, 41, 23, 102, 226, 235, 23, 102, 232, 99, 23, 102, 233, 102, 23, 
+    102, 232, 100, 23, 102, 233, 103, 23, 102, 233, 245, 23, 102, 233, 76, 
+    23, 102, 226, 253, 23, 102, 231, 30, 23, 102, 233, 244, 23, 102, 233, 
+    101, 23, 102, 232, 55, 23, 102, 232, 56, 23, 102, 232, 58, 23, 102, 232, 
+    57, 23, 102, 233, 243, 23, 102, 231, 120, 23, 102, 226, 247, 23, 102, 
+    227, 13, 23, 102, 226, 232, 23, 102, 236, 234, 23, 102, 231, 106, 23, 
+    102, 231, 142, 23, 102, 232, 175, 23, 102, 232, 176, 23, 102, 233, 208, 
+    23, 102, 231, 68, 23, 102, 233, 78, 23, 102, 232, 174, 23, 102, 231, 66, 
+    23, 102, 231, 70, 23, 102, 231, 69, 23, 102, 235, 115, 23, 102, 232, 119, 
+    23, 102, 231, 62, 23, 102, 226, 238, 23, 102, 227, 1, 23, 102, 226, 229, 
+    23, 102, 227, 14, 23, 102, 231, 61, 23, 102, 227, 15, 23, 102, 226, 237, 
+    23, 102, 231, 50, 23, 102, 227, 9, 23, 102, 233, 104, 23, 102, 232, 102, 
+    23, 102, 238, 114, 23, 146, 238, 114, 23, 146, 67, 23, 146, 253, 178, 23, 
+    146, 216, 23, 146, 249, 18, 23, 146, 254, 59, 23, 146, 72, 23, 146, 249, 
+    22, 23, 146, 253, 254, 23, 146, 73, 23, 146, 253, 138, 23, 146, 249, 12, 
+    23, 146, 253, 193, 23, 146, 253, 162, 23, 146, 79, 23, 146, 249, 14, 23, 
+    146, 253, 170, 23, 146, 253, 187, 23, 146, 253, 161, 23, 146, 254, 61, 
+    23, 146, 253, 189, 23, 146, 71, 23, 146, 249, 229, 23, 146, 249, 230, 23, 
+    146, 247, 211, 23, 146, 242, 189, 23, 146, 245, 83, 23, 146, 245, 84, 23, 
+    146, 241, 96, 23, 146, 242, 195, 23, 146, 242, 196, 23, 146, 246, 230, 
+    23, 146, 252, 52, 23, 146, 246, 231, 23, 146, 252, 53, 23, 146, 252, 54, 
+    23, 146, 240, 255, 23, 146, 238, 233, 23, 146, 239, 251, 23, 146, 247, 
+    231, 23, 146, 244, 58, 23, 146, 252, 247, 23, 146, 247, 180, 23, 146, 
+    238, 36, 23, 146, 247, 181, 23, 146, 252, 248, 23, 146, 247, 234, 23, 
+    146, 242, 199, 23, 146, 247, 235, 23, 146, 238, 234, 23, 146, 241, 0, 23, 
+    146, 247, 236, 23, 146, 244, 60, 23, 146, 245, 86, 23, 146, 241, 99, 23, 
+    146, 247, 226, 23, 146, 251, 97, 23, 146, 245, 223, 23, 146, 251, 98, 23, 
+    146, 251, 99, 23, 146, 245, 222, 23, 146, 237, 175, 23, 146, 240, 156, 
+    23, 146, 235, 169, 23, 146, 237, 65, 23, 146, 237, 64, 23, 146, 233, 246, 
+    23, 114, 238, 99, 23, 114, 232, 87, 23, 114, 232, 91, 23, 114, 240, 80, 
+    23, 114, 232, 93, 23, 114, 232, 94, 23, 114, 238, 102, 23, 114, 240, 85, 
+    23, 114, 231, 98, 23, 114, 232, 96, 23, 114, 232, 97, 23, 114, 233, 74, 
+    23, 114, 231, 43, 23, 114, 231, 42, 23, 114, 232, 85, 23, 114, 240, 78, 
+    23, 114, 240, 83, 23, 114, 233, 66, 23, 114, 243, 34, 23, 114, 234, 32, 
+    23, 114, 240, 75, 23, 114, 240, 71, 23, 114, 236, 195, 23, 114, 236, 198, 
+    23, 114, 236, 205, 23, 114, 236, 201, 23, 114, 240, 74, 23, 114, 231, 
+    145, 23, 114, 226, 239, 23, 114, 231, 108, 23, 114, 231, 97, 23, 114, 
+    233, 90, 23, 114, 231, 47, 23, 114, 231, 74, 23, 114, 231, 56, 23, 114, 
+    232, 61, 23, 114, 226, 245, 23, 114, 232, 108, 23, 114, 231, 111, 23, 
+    114, 226, 241, 23, 114, 233, 106, 23, 114, 226, 240, 23, 114, 227, 5, 23, 
+    114, 226, 255, 23, 114, 226, 251, 23, 114, 226, 234, 23, 114, 229, 55, 
+    23, 114, 231, 54, 23, 114, 231, 76, 23, 114, 226, 246, 23, 114, 231, 147, 
+    23, 114, 232, 183, 23, 114, 232, 92, 23, 114, 233, 86, 23, 114, 229, 50, 
+    23, 114, 231, 46, 23, 114, 231, 73, 23, 114, 232, 182, 23, 114, 231, 40, 
+    23, 114, 232, 196, 23, 114, 231, 51, 23, 114, 232, 194, 23, 114, 231, 41, 
+    23, 114, 232, 99, 23, 114, 232, 100, 23, 114, 233, 103, 23, 114, 233, 76, 
+    23, 114, 236, 234, 23, 114, 231, 106, 23, 114, 226, 248, 23, 114, 233, 
+    78, 23, 114, 231, 67, 23, 114, 235, 115, 23, 114, 231, 58, 23, 114, 227, 
+    0, 23, 114, 231, 50, 23, 114, 227, 9, 23, 114, 232, 170, 23, 114, 232, 
+    172, 23, 114, 232, 169, 23, 114, 232, 171, 23, 114, 232, 102, 22, 4, 219, 
+    22, 4, 253, 236, 22, 4, 253, 214, 22, 4, 248, 114, 22, 4, 249, 80, 22, 4, 
+    253, 168, 22, 4, 253, 184, 22, 4, 251, 76, 22, 4, 253, 134, 22, 4, 254, 
+    8, 22, 4, 253, 251, 22, 4, 249, 101, 22, 4, 249, 102, 22, 4, 253, 250, 
+    22, 4, 253, 216, 22, 4, 248, 227, 22, 4, 251, 56, 22, 4, 251, 60, 22, 4, 
+    251, 58, 22, 4, 243, 194, 22, 4, 245, 143, 22, 4, 251, 57, 22, 4, 251, 
+    59, 22, 4, 245, 144, 22, 4, 222, 22, 4, 253, 154, 22, 4, 253, 180, 22, 4, 
+    249, 110, 22, 4, 249, 111, 22, 4, 253, 206, 22, 4, 253, 181, 22, 4, 248, 
+    169, 22, 4, 252, 202, 22, 4, 252, 206, 22, 4, 252, 204, 22, 4, 247, 131, 
+    22, 4, 247, 132, 22, 4, 252, 203, 22, 4, 252, 205, 22, 4, 247, 133, 22, 
+    4, 253, 130, 22, 4, 253, 185, 22, 4, 253, 209, 22, 4, 248, 182, 22, 4, 
+    249, 153, 22, 4, 253, 194, 22, 4, 253, 160, 22, 4, 252, 157, 22, 4, 253, 
+    132, 22, 4, 253, 211, 22, 4, 253, 198, 22, 4, 249, 158, 22, 4, 248, 184, 
+    22, 4, 253, 210, 22, 4, 253, 186, 22, 4, 248, 252, 22, 4, 248, 46, 22, 4, 
+    248, 248, 22, 4, 248, 185, 22, 4, 244, 7, 22, 4, 244, 9, 22, 4, 248, 118, 
+    22, 4, 248, 110, 22, 4, 243, 121, 22, 4, 253, 217, 22, 4, 254, 29, 22, 4, 
+    254, 28, 22, 4, 248, 241, 22, 4, 252, 88, 22, 4, 254, 70, 22, 4, 254, 45, 
+    22, 4, 252, 98, 22, 4, 252, 112, 22, 4, 252, 114, 22, 4, 247, 21, 22, 4, 
+    247, 22, 22, 4, 252, 113, 22, 4, 252, 89, 22, 4, 252, 93, 22, 4, 252, 91, 
+    22, 4, 247, 7, 22, 4, 247, 8, 22, 4, 252, 90, 22, 4, 252, 92, 22, 4, 247, 
+    9, 22, 4, 247, 11, 22, 4, 242, 72, 22, 4, 242, 73, 22, 4, 247, 10, 22, 4, 
+    253, 141, 22, 4, 253, 243, 22, 4, 254, 34, 22, 4, 249, 30, 22, 4, 248, 
+    197, 22, 4, 253, 242, 22, 4, 254, 1, 22, 4, 249, 36, 22, 4, 253, 171, 22, 
+    4, 254, 49, 22, 4, 254, 48, 22, 4, 253, 6, 22, 4, 249, 10, 22, 4, 254, 
+    12, 22, 4, 254, 13, 22, 4, 253, 24, 22, 4, 253, 126, 22, 4, 253, 196, 22, 
+    4, 253, 212, 22, 4, 249, 172, 22, 4, 248, 255, 22, 4, 253, 195, 22, 4, 
+    87, 22, 4, 249, 7, 22, 4, 253, 152, 22, 4, 254, 84, 22, 4, 254, 55, 22, 
+    4, 249, 37, 22, 4, 250, 154, 22, 4, 254, 54, 22, 4, 253, 224, 22, 4, 248, 
+    203, 22, 4, 253, 253, 22, 4, 255, 6, 22, 4, 253, 188, 22, 4, 253, 41, 22, 
+    4, 253, 42, 22, 4, 254, 132, 22, 4, 254, 133, 22, 4, 253, 47, 22, 4, 253, 
+    53, 22, 4, 253, 55, 22, 4, 247, 206, 22, 4, 247, 207, 22, 4, 253, 54, 22, 
+    4, 253, 131, 22, 4, 253, 150, 22, 4, 253, 166, 22, 4, 248, 231, 22, 4, 
+    249, 118, 22, 4, 253, 197, 22, 4, 253, 173, 22, 4, 248, 176, 22, 4, 248, 
+    78, 22, 4, 249, 125, 22, 4, 248, 178, 22, 4, 246, 198, 22, 4, 246, 200, 
+    22, 4, 252, 46, 22, 4, 248, 133, 22, 4, 246, 212, 22, 4, 238, 62, 67, 22, 
+    4, 238, 62, 79, 22, 4, 238, 62, 71, 22, 4, 238, 62, 253, 140, 22, 4, 238, 
+    62, 253, 164, 22, 4, 238, 62, 72, 22, 4, 238, 62, 73, 22, 4, 238, 62, 
+    253, 138, 22, 4, 201, 22, 4, 253, 203, 22, 4, 253, 215, 22, 4, 249, 90, 
+    22, 4, 251, 141, 22, 4, 253, 172, 22, 4, 253, 190, 22, 4, 251, 157, 22, 
+    4, 248, 221, 22, 4, 248, 223, 22, 4, 243, 65, 22, 4, 246, 25, 22, 4, 248, 
+    222, 22, 4, 251, 170, 22, 4, 251, 174, 22, 4, 251, 172, 22, 4, 246, 26, 
+    22, 4, 246, 27, 22, 4, 251, 171, 22, 4, 251, 173, 22, 4, 246, 28, 22, 4, 
+    246, 30, 22, 4, 241, 207, 22, 4, 241, 208, 22, 4, 246, 29, 22, 4, 253, 
+    138, 22, 4, 254, 14, 22, 4, 253, 187, 22, 4, 248, 190, 22, 4, 249, 199, 
+    22, 4, 253, 170, 22, 4, 253, 177, 22, 4, 253, 34, 22, 4, 234, 12, 67, 22, 
+    4, 234, 12, 79, 22, 4, 234, 12, 71, 22, 4, 234, 12, 253, 140, 22, 4, 234, 
+    12, 253, 164, 22, 4, 234, 12, 72, 22, 4, 234, 12, 73, 22, 4, 253, 163, 
+    22, 4, 254, 18, 22, 4, 254, 17, 22, 4, 249, 216, 22, 4, 248, 194, 22, 4, 
+    253, 228, 22, 4, 253, 222, 22, 4, 253, 117, 22, 4, 248, 99, 22, 4, 249, 
+    219, 22, 4, 249, 217, 22, 4, 247, 245, 22, 4, 243, 139, 22, 4, 248, 123, 
+    22, 4, 249, 218, 22, 4, 248, 4, 22, 4, 216, 22, 4, 253, 161, 22, 4, 253, 
+    189, 22, 4, 248, 191, 22, 4, 248, 192, 22, 4, 253, 254, 22, 4, 253, 162, 
+    22, 4, 253, 84, 22, 4, 253, 133, 22, 4, 253, 232, 22, 4, 253, 201, 22, 4, 
+    250, 177, 22, 4, 248, 149, 22, 4, 253, 200, 22, 4, 253, 225, 22, 4, 250, 
+    214, 22, 4, 248, 75, 22, 4, 249, 52, 22, 4, 249, 51, 22, 4, 245, 36, 22, 
+    4, 245, 41, 22, 4, 249, 50, 22, 4, 248, 204, 22, 4, 245, 57, 22, 4, 253, 
+    146, 22, 4, 254, 25, 22, 4, 254, 7, 22, 4, 251, 110, 22, 4, 248, 161, 22, 
+    4, 254, 24, 22, 4, 253, 248, 22, 4, 251, 131, 22, 4, 253, 139, 22, 4, 
+    253, 235, 22, 4, 254, 6, 22, 4, 248, 211, 22, 4, 249, 68, 22, 4, 254, 5, 
+    22, 4, 253, 234, 22, 4, 251, 25, 22, 4, 251, 36, 22, 4, 251, 38, 22, 4, 
+    245, 134, 22, 4, 245, 135, 22, 4, 251, 37, 22, 4, 249, 70, 22, 4, 249, 
+    74, 22, 4, 249, 72, 22, 4, 245, 99, 22, 4, 245, 103, 22, 4, 249, 71, 22, 
+    4, 249, 73, 22, 4, 241, 134, 22, 4, 248, 55, 22, 4, 249, 177, 22, 4, 248, 
+    121, 22, 4, 243, 76, 22, 4, 243, 77, 22, 4, 248, 111, 22, 4, 248, 97, 22, 
+    4, 247, 147, 22, 4, 248, 57, 22, 4, 248, 200, 22, 4, 248, 67, 22, 4, 244, 
+    252, 22, 4, 243, 54, 22, 4, 248, 88, 22, 4, 248, 125, 22, 4, 245, 13, 22, 
+    4, 248, 65, 22, 4, 252, 64, 22, 4, 248, 68, 22, 4, 246, 243, 22, 4, 246, 
+    245, 22, 4, 249, 136, 22, 4, 248, 238, 22, 4, 246, 247, 22, 4, 248, 90, 
+    22, 4, 249, 5, 22, 4, 248, 140, 22, 4, 247, 160, 22, 4, 244, 39, 22, 4, 
+    248, 112, 22, 4, 249, 4, 22, 4, 247, 162, 22, 4, 252, 242, 22, 4, 252, 
+    246, 22, 4, 252, 244, 22, 4, 247, 177, 22, 4, 247, 178, 22, 4, 252, 243, 
+    22, 4, 252, 245, 22, 4, 247, 179, 22, 4, 253, 179, 22, 4, 254, 93, 22, 4, 
+    253, 245, 22, 4, 249, 60, 22, 4, 249, 61, 22, 4, 254, 62, 22, 4, 254, 63, 
+    22, 4, 249, 66, 22, 4, 253, 129, 22, 4, 253, 239, 22, 4, 253, 147, 22, 4, 
+    249, 133, 22, 4, 248, 180, 22, 4, 253, 175, 22, 4, 253, 208, 22, 4, 248, 
+    181, 22, 4, 252, 158, 22, 4, 251, 248, 22, 4, 251, 1, 22, 50, 234, 194, 
+    69, 22, 238, 213, 69, 22, 235, 42, 22, 248, 37, 208, 22, 240, 27, 22, 
+    234, 14, 22, 240, 24, 22, 239, 166, 240, 24, 22, 236, 156, 69, 22, 235, 
+    91, 234, 6, 22, 26, 127, 22, 26, 111, 22, 26, 166, 22, 26, 177, 22, 26, 
+    176, 22, 26, 187, 22, 26, 203, 22, 26, 195, 22, 26, 202, 22, 61, 248, 53, 
+    22, 61, 238, 77, 22, 61, 238, 101, 22, 61, 240, 136, 22, 61, 240, 50, 22, 
+    61, 240, 234, 22, 61, 237, 38, 22, 61, 238, 182, 22, 61, 238, 147, 22, 
+    61, 236, 149, 22, 61, 253, 219, 235, 49, 22, 4, 235, 94, 248, 169, 22, 4, 
+    248, 230, 22, 4, 246, 101, 22, 4, 248, 229, 22, 4, 235, 94, 249, 36, 22, 
+    4, 250, 136, 22, 4, 244, 237, 22, 4, 250, 135, 22, 4, 235, 94, 249, 66, 
+    22, 4, 251, 0, 22, 4, 245, 95, 22, 4, 250, 255, 22, 4, 235, 94, 248, 181, 
+    22, 4, 248, 240, 22, 4, 247, 2, 22, 4, 248, 239, 22, 243, 10, 158, 242, 
+    198, 22, 243, 10, 158, 241, 83, 22, 243, 10, 158, 238, 212, 22, 243, 10, 
+    158, 242, 215, 238, 212, 22, 243, 10, 158, 241, 84, 22, 243, 10, 158, 
+    241, 199, 22, 243, 10, 158, 239, 24, 22, 243, 10, 158, 241, 149, 22, 243, 
+    10, 158, 232, 130, 22, 243, 10, 158, 246, 22, 109, 1, 67, 109, 1, 72, 
+    109, 1, 71, 109, 1, 73, 109, 1, 79, 109, 1, 179, 109, 1, 253, 139, 109, 
+    1, 201, 109, 1, 254, 5, 109, 1, 254, 6, 109, 1, 253, 234, 109, 1, 253, 
+    235, 109, 1, 254, 169, 109, 1, 219, 109, 1, 253, 168, 109, 1, 253, 214, 
+    109, 1, 253, 184, 109, 1, 253, 236, 109, 1, 254, 98, 109, 1, 253, 134, 
+    109, 1, 253, 250, 109, 1, 253, 251, 109, 1, 253, 216, 109, 1, 254, 8, 
+    109, 1, 254, 196, 109, 1, 222, 109, 1, 253, 206, 109, 1, 253, 180, 109, 
+    1, 253, 181, 109, 1, 253, 154, 109, 1, 253, 131, 109, 1, 249, 83, 109, 1, 
+    251, 253, 109, 1, 253, 197, 109, 1, 253, 166, 109, 1, 253, 173, 109, 1, 
+    253, 150, 109, 1, 254, 115, 109, 1, 252, 103, 109, 1, 252, 104, 109, 1, 
+    252, 105, 109, 1, 249, 149, 109, 1, 249, 150, 109, 1, 252, 110, 109, 1, 
+    253, 132, 109, 1, 193, 109, 1, 253, 210, 109, 1, 253, 198, 109, 1, 253, 
+    186, 109, 1, 253, 211, 109, 1, 254, 127, 109, 1, 253, 133, 109, 1, 253, 
+    126, 109, 1, 253, 200, 109, 1, 253, 195, 109, 1, 253, 201, 109, 1, 253, 
+    212, 109, 1, 253, 225, 109, 1, 253, 232, 109, 1, 254, 158, 109, 1, 249, 
+    55, 109, 1, 249, 179, 109, 1, 249, 180, 109, 1, 249, 181, 109, 1, 249, 
+    182, 109, 1, 249, 183, 109, 1, 252, 225, 109, 1, 248, 90, 109, 1, 248, 
+    112, 109, 1, 248, 140, 109, 1, 249, 4, 109, 1, 249, 5, 109, 1, 252, 230, 
+    109, 1, 253, 138, 109, 1, 253, 170, 109, 1, 253, 187, 109, 1, 253, 177, 
+    109, 1, 254, 14, 109, 1, 255, 4, 109, 1, 216, 109, 1, 253, 254, 109, 1, 
+    253, 189, 109, 1, 253, 162, 109, 1, 253, 161, 109, 1, 255, 10, 14, 15, 
+    72, 14, 15, 249, 231, 14, 15, 71, 14, 15, 253, 142, 14, 15, 73, 14, 15, 
+    253, 156, 14, 15, 240, 44, 253, 156, 14, 15, 55, 253, 164, 14, 15, 55, 
+    71, 14, 15, 67, 14, 15, 253, 140, 14, 15, 253, 170, 14, 15, 106, 253, 
+    170, 14, 15, 253, 187, 14, 15, 106, 253, 187, 14, 15, 249, 200, 14, 15, 
+    106, 249, 200, 14, 15, 253, 177, 14, 15, 106, 253, 177, 14, 15, 249, 15, 
+    14, 15, 106, 249, 15, 14, 15, 238, 66, 249, 15, 14, 15, 253, 138, 14, 15, 
+    106, 253, 138, 14, 15, 248, 190, 14, 15, 106, 248, 190, 14, 15, 238, 66, 
+    248, 190, 14, 15, 253, 149, 14, 15, 240, 44, 255, 16, 14, 15, 238, 62, 
+    208, 14, 15, 30, 135, 14, 15, 30, 191, 14, 15, 30, 240, 17, 137, 242, 
+    233, 14, 15, 30, 253, 159, 137, 242, 233, 14, 15, 30, 38, 137, 242, 233, 
+    14, 15, 30, 242, 233, 14, 15, 30, 45, 135, 14, 15, 30, 45, 242, 215, 59, 
+    237, 45, 14, 15, 30, 240, 1, 248, 40, 14, 15, 30, 242, 215, 163, 108, 14, 
+    15, 30, 243, 12, 14, 15, 30, 92, 242, 234, 14, 15, 253, 202, 14, 15, 253, 
+    247, 14, 15, 254, 9, 14, 15, 254, 19, 14, 15, 253, 175, 14, 15, 246, 236, 
+    14, 15, 253, 147, 14, 15, 249, 138, 14, 15, 253, 208, 14, 15, 249, 140, 
+    14, 15, 240, 44, 249, 140, 14, 15, 55, 249, 80, 14, 15, 55, 253, 214, 14, 
+    15, 253, 129, 14, 15, 249, 133, 14, 15, 248, 239, 14, 15, 106, 248, 239, 
+    14, 15, 248, 240, 14, 15, 106, 248, 240, 14, 15, 243, 247, 14, 15, 106, 
+    243, 247, 14, 15, 249, 143, 14, 15, 106, 249, 143, 14, 15, 243, 248, 14, 
+    15, 106, 243, 248, 14, 15, 248, 181, 14, 15, 106, 248, 181, 14, 15, 243, 
+    118, 14, 15, 106, 243, 118, 14, 15, 240, 44, 243, 118, 14, 15, 223, 14, 
+    15, 106, 223, 14, 15, 55, 192, 14, 15, 253, 195, 14, 15, 247, 135, 14, 
+    15, 253, 212, 14, 15, 252, 221, 14, 15, 87, 14, 15, 249, 2, 14, 15, 240, 
+    44, 249, 2, 14, 15, 55, 248, 149, 14, 15, 55, 253, 201, 14, 15, 253, 126, 
+    14, 15, 249, 172, 14, 15, 249, 8, 14, 15, 106, 249, 8, 14, 15, 249, 189, 
+    14, 15, 106, 249, 189, 14, 15, 244, 42, 14, 15, 106, 244, 42, 14, 15, 
+    111, 14, 15, 106, 111, 14, 15, 244, 43, 14, 15, 106, 244, 43, 14, 15, 
+    249, 7, 14, 15, 106, 249, 7, 14, 15, 243, 132, 14, 15, 106, 243, 132, 14, 
+    15, 238, 66, 243, 132, 14, 15, 214, 14, 15, 249, 186, 14, 15, 249, 187, 
+    14, 15, 249, 6, 14, 15, 248, 71, 14, 15, 253, 172, 14, 15, 246, 4, 14, 
+    15, 253, 215, 14, 15, 251, 150, 14, 15, 253, 190, 14, 15, 249, 98, 14, 
+    15, 240, 44, 249, 98, 14, 15, 201, 14, 15, 249, 90, 14, 15, 248, 222, 14, 
+    15, 106, 248, 222, 14, 15, 248, 223, 14, 15, 106, 248, 223, 14, 15, 243, 
+    211, 14, 15, 106, 243, 211, 14, 15, 249, 100, 14, 15, 106, 249, 100, 14, 
+    15, 243, 212, 14, 15, 106, 243, 212, 14, 15, 248, 221, 14, 15, 106, 248, 
+    221, 14, 15, 243, 65, 14, 15, 106, 243, 65, 14, 15, 238, 66, 243, 65, 14, 
+    15, 255, 15, 14, 15, 254, 108, 14, 15, 232, 86, 248, 218, 14, 15, 232, 
+    86, 251, 149, 14, 15, 232, 86, 251, 158, 14, 15, 232, 86, 251, 136, 14, 
+    15, 254, 54, 14, 15, 244, 239, 14, 15, 254, 55, 14, 15, 250, 162, 14, 15, 
+    253, 224, 14, 15, 249, 42, 14, 15, 240, 44, 249, 42, 14, 15, 253, 152, 
+    14, 15, 249, 37, 14, 15, 249, 44, 14, 15, 106, 249, 44, 14, 15, 249, 45, 
+    14, 15, 106, 249, 45, 14, 15, 243, 159, 14, 15, 106, 243, 159, 14, 15, 
+    249, 46, 14, 15, 106, 249, 46, 14, 15, 243, 160, 14, 15, 106, 243, 160, 
+    14, 15, 248, 203, 14, 15, 106, 248, 203, 14, 15, 243, 91, 14, 15, 106, 
+    243, 91, 14, 15, 238, 66, 243, 91, 14, 15, 255, 18, 14, 15, 240, 36, 254, 
+    46, 14, 15, 253, 206, 14, 15, 246, 61, 14, 15, 253, 180, 14, 15, 251, 
+    232, 14, 15, 253, 181, 14, 15, 249, 112, 14, 15, 240, 44, 249, 112, 14, 
+    15, 222, 14, 15, 249, 110, 14, 15, 248, 229, 14, 15, 106, 248, 229, 14, 
+    15, 248, 230, 14, 15, 106, 248, 230, 14, 15, 243, 228, 14, 15, 106, 243, 
+    228, 14, 15, 249, 117, 14, 15, 106, 249, 117, 14, 15, 243, 229, 14, 15, 
+    106, 243, 229, 14, 15, 248, 169, 14, 15, 106, 248, 169, 14, 15, 243, 109, 
+    14, 15, 106, 243, 109, 14, 15, 238, 66, 243, 109, 14, 15, 173, 14, 15, 
+    106, 173, 14, 15, 254, 203, 14, 15, 234, 47, 173, 14, 15, 240, 36, 173, 
+    14, 15, 253, 197, 14, 15, 246, 102, 14, 15, 253, 166, 14, 15, 252, 22, 
+    14, 15, 253, 173, 14, 15, 249, 121, 14, 15, 240, 44, 249, 121, 14, 15, 
+    253, 131, 14, 15, 248, 231, 14, 15, 249, 124, 14, 15, 106, 249, 124, 14, 
+    15, 248, 176, 14, 15, 106, 248, 176, 14, 15, 243, 110, 14, 15, 106, 243, 
+    110, 14, 15, 238, 66, 243, 110, 14, 15, 197, 14, 15, 55, 254, 26, 14, 15, 
+    254, 214, 14, 15, 253, 250, 14, 15, 246, 33, 14, 15, 253, 251, 14, 15, 
+    251, 196, 14, 15, 253, 216, 14, 15, 248, 226, 14, 15, 240, 44, 248, 226, 
+    14, 15, 253, 134, 14, 15, 249, 101, 14, 15, 249, 106, 14, 15, 106, 249, 
+    106, 14, 15, 249, 107, 14, 15, 106, 249, 107, 14, 15, 243, 220, 14, 15, 
+    106, 243, 220, 14, 15, 249, 108, 14, 15, 106, 249, 108, 14, 15, 243, 221, 
+    14, 15, 106, 243, 221, 14, 15, 248, 227, 14, 15, 106, 248, 227, 14, 15, 
+    243, 219, 14, 15, 106, 243, 219, 14, 15, 162, 14, 15, 106, 162, 14, 15, 
+    113, 162, 14, 15, 253, 210, 14, 15, 247, 60, 14, 15, 253, 198, 14, 15, 
+    252, 177, 14, 15, 253, 186, 14, 15, 249, 166, 14, 15, 240, 44, 249, 166, 
+    14, 15, 253, 132, 14, 15, 249, 158, 14, 15, 249, 169, 14, 15, 106, 249, 
+    169, 14, 15, 249, 170, 14, 15, 106, 249, 170, 14, 15, 244, 26, 14, 15, 
+    106, 244, 26, 14, 15, 249, 171, 14, 15, 106, 249, 171, 14, 15, 244, 27, 
+    14, 15, 106, 244, 27, 14, 15, 248, 252, 14, 15, 106, 248, 252, 14, 15, 
+    243, 125, 14, 15, 106, 243, 125, 14, 15, 238, 66, 243, 125, 14, 15, 193, 
+    14, 15, 234, 47, 193, 14, 15, 254, 128, 14, 15, 235, 57, 193, 14, 15, 
+    234, 225, 254, 238, 14, 15, 238, 66, 252, 181, 14, 15, 238, 66, 252, 164, 
+    14, 15, 238, 66, 247, 98, 14, 15, 238, 66, 247, 124, 14, 15, 238, 66, 
+    247, 93, 14, 15, 238, 66, 247, 66, 14, 15, 248, 118, 14, 15, 248, 185, 
+    14, 15, 247, 73, 14, 15, 248, 110, 14, 15, 247, 76, 14, 15, 248, 46, 14, 
+    15, 244, 7, 14, 15, 244, 16, 14, 15, 106, 244, 16, 14, 15, 244, 17, 14, 
+    15, 106, 244, 17, 14, 15, 240, 230, 14, 15, 106, 240, 230, 14, 15, 244, 
+    18, 14, 15, 106, 244, 18, 14, 15, 240, 231, 14, 15, 106, 240, 231, 14, 
+    15, 243, 121, 14, 15, 106, 243, 121, 14, 15, 240, 229, 14, 15, 106, 240, 
+    229, 14, 15, 254, 72, 14, 15, 253, 254, 14, 15, 247, 212, 14, 15, 253, 
+    189, 14, 15, 253, 81, 14, 15, 253, 162, 14, 15, 249, 210, 14, 15, 240, 
+    44, 249, 210, 14, 15, 216, 14, 15, 248, 191, 14, 15, 249, 213, 14, 15, 
+    106, 249, 213, 14, 15, 249, 214, 14, 15, 106, 249, 214, 14, 15, 244, 61, 
+    14, 15, 106, 244, 61, 14, 15, 249, 215, 14, 15, 106, 249, 215, 14, 15, 
+    244, 62, 14, 15, 106, 244, 62, 14, 15, 249, 212, 14, 15, 106, 249, 212, 
+    14, 15, 243, 137, 14, 15, 106, 243, 137, 14, 15, 238, 66, 243, 137, 14, 
+    15, 255, 14, 14, 15, 234, 98, 255, 14, 14, 15, 106, 255, 14, 14, 15, 240, 
+    36, 253, 189, 14, 15, 253, 194, 14, 15, 242, 74, 253, 194, 14, 15, 106, 
+    253, 250, 14, 15, 247, 26, 14, 15, 253, 209, 14, 15, 252, 137, 14, 15, 
+    253, 160, 14, 15, 252, 143, 14, 15, 106, 253, 216, 14, 15, 253, 130, 14, 
+    15, 248, 182, 14, 15, 106, 253, 134, 14, 15, 244, 2, 14, 15, 106, 244, 2, 
+    14, 15, 144, 14, 15, 106, 144, 14, 15, 113, 144, 14, 15, 254, 62, 14, 15, 
+    245, 88, 14, 15, 253, 245, 14, 15, 250, 243, 14, 15, 254, 63, 14, 15, 
+    250, 249, 14, 15, 253, 179, 14, 15, 249, 60, 14, 15, 243, 177, 14, 15, 
+    106, 243, 177, 14, 15, 255, 19, 14, 15, 248, 111, 14, 15, 240, 141, 248, 
+    111, 14, 15, 248, 121, 14, 15, 240, 141, 248, 121, 14, 15, 243, 128, 14, 
+    15, 240, 141, 243, 128, 14, 15, 248, 97, 14, 15, 244, 30, 14, 15, 248, 
+    55, 14, 15, 243, 76, 14, 15, 240, 244, 14, 15, 106, 240, 244, 14, 15, 
+    254, 46, 14, 15, 247, 166, 14, 15, 247, 167, 14, 15, 243, 131, 14, 15, 
+    242, 247, 14, 15, 252, 231, 14, 15, 252, 239, 14, 15, 252, 240, 14, 15, 
+    252, 241, 14, 15, 252, 238, 14, 15, 238, 86, 253, 168, 14, 15, 238, 86, 
+    253, 214, 14, 15, 238, 86, 251, 61, 14, 15, 238, 86, 253, 184, 14, 15, 
+    238, 86, 251, 78, 14, 15, 238, 86, 219, 14, 15, 238, 86, 248, 114, 14, 
+    15, 238, 86, 192, 14, 15, 239, 148, 192, 14, 15, 254, 172, 14, 15, 247, 
+    5, 14, 15, 254, 28, 14, 15, 249, 147, 14, 15, 254, 45, 14, 15, 252, 100, 
+    14, 15, 253, 217, 14, 15, 248, 241, 14, 15, 255, 20, 14, 15, 244, 34, 14, 
+    15, 244, 35, 14, 15, 244, 36, 14, 15, 244, 33, 14, 15, 106, 253, 194, 14, 
+    15, 106, 253, 209, 14, 15, 106, 253, 160, 14, 15, 106, 253, 130, 14, 15, 
+    242, 5, 14, 15, 248, 232, 14, 15, 246, 147, 14, 15, 248, 172, 14, 15, 
+    246, 149, 14, 15, 248, 50, 14, 15, 246, 139, 14, 15, 254, 26, 14, 15, 
+    252, 30, 14, 15, 240, 36, 248, 118, 14, 15, 240, 36, 248, 185, 14, 15, 
+    240, 36, 248, 110, 14, 15, 240, 36, 248, 46, 14, 15, 234, 24, 248, 111, 
+    14, 15, 234, 24, 248, 121, 14, 15, 234, 24, 248, 97, 14, 15, 234, 24, 
+    248, 55, 14, 15, 234, 24, 254, 46, 14, 15, 249, 103, 14, 15, 246, 46, 14, 
+    15, 249, 104, 14, 15, 246, 47, 14, 15, 248, 225, 14, 15, 246, 44, 14, 15, 
+    254, 193, 14, 15, 238, 88, 248, 111, 14, 15, 238, 88, 248, 121, 14, 15, 
+    238, 88, 243, 128, 14, 15, 238, 88, 248, 97, 14, 15, 238, 88, 244, 30, 
+    14, 15, 238, 88, 248, 55, 14, 15, 238, 88, 243, 76, 14, 15, 238, 88, 254, 
+    46, 14, 15, 238, 241, 217, 14, 15, 235, 57, 72, 14, 15, 235, 57, 71, 14, 
+    15, 235, 57, 73, 14, 15, 235, 57, 67, 14, 15, 235, 57, 253, 170, 14, 15, 
+    235, 57, 253, 187, 14, 15, 235, 57, 253, 177, 14, 15, 235, 57, 253, 138, 
+    14, 15, 235, 57, 253, 197, 14, 15, 235, 57, 253, 166, 14, 15, 235, 57, 
+    253, 173, 14, 15, 235, 57, 253, 131, 14, 15, 235, 57, 253, 172, 14, 15, 
+    235, 57, 253, 215, 14, 15, 235, 57, 253, 190, 14, 15, 235, 57, 201, 14, 
+    15, 240, 36, 253, 168, 14, 15, 240, 36, 253, 214, 14, 15, 240, 36, 253, 
+    184, 14, 15, 240, 36, 219, 14, 15, 55, 251, 19, 14, 15, 55, 249, 75, 14, 
+    15, 55, 248, 127, 14, 15, 55, 245, 119, 14, 15, 55, 251, 18, 14, 15, 55, 
+    248, 77, 14, 15, 55, 253, 185, 14, 15, 55, 253, 160, 14, 15, 55, 253, 
+    194, 14, 15, 55, 249, 153, 14, 15, 55, 253, 209, 14, 15, 55, 253, 130, 
+    14, 15, 55, 254, 14, 14, 15, 55, 253, 177, 14, 15, 55, 253, 170, 14, 15, 
+    55, 249, 199, 14, 15, 55, 253, 187, 14, 15, 55, 253, 138, 14, 15, 55, 
+    251, 88, 14, 15, 55, 251, 87, 14, 15, 55, 251, 85, 14, 15, 55, 245, 208, 
+    14, 15, 55, 251, 86, 14, 15, 55, 251, 84, 14, 15, 55, 249, 177, 14, 15, 
+    55, 248, 97, 14, 15, 55, 248, 111, 14, 15, 55, 243, 77, 14, 15, 55, 248, 
+    121, 14, 15, 55, 248, 55, 14, 15, 55, 252, 232, 14, 15, 55, 249, 6, 14, 
+    15, 55, 249, 186, 14, 15, 55, 247, 164, 14, 15, 55, 249, 187, 14, 15, 55, 
+    248, 71, 14, 15, 55, 253, 239, 14, 15, 55, 253, 208, 14, 15, 55, 253, 
+    175, 14, 15, 55, 248, 180, 14, 15, 55, 253, 147, 14, 15, 55, 253, 129, 
+    14, 15, 55, 223, 14, 15, 55, 253, 235, 14, 15, 55, 253, 234, 14, 15, 55, 
+    254, 5, 14, 15, 55, 249, 68, 14, 15, 55, 254, 6, 14, 15, 55, 253, 139, 
+    14, 15, 55, 251, 146, 14, 15, 55, 248, 220, 14, 15, 55, 249, 94, 14, 15, 
+    55, 246, 11, 14, 15, 55, 248, 219, 14, 15, 55, 248, 61, 14, 15, 55, 251, 
+    156, 14, 15, 55, 251, 155, 14, 15, 55, 251, 153, 14, 15, 55, 246, 17, 14, 
+    15, 55, 251, 154, 14, 15, 55, 249, 97, 14, 15, 55, 254, 107, 14, 15, 55, 
+    253, 150, 14, 15, 55, 253, 173, 14, 15, 55, 253, 197, 14, 15, 55, 249, 
+    118, 14, 15, 55, 253, 166, 14, 15, 55, 253, 131, 14, 15, 55, 253, 154, 
+    14, 15, 55, 253, 181, 14, 15, 55, 253, 206, 14, 15, 55, 249, 111, 14, 15, 
+    55, 253, 180, 14, 15, 55, 222, 14, 15, 55, 253, 161, 14, 15, 55, 253, 
+    162, 14, 15, 55, 253, 254, 14, 15, 55, 248, 192, 14, 15, 55, 253, 189, 
+    14, 15, 55, 216, 14, 15, 55, 254, 25, 14, 15, 240, 36, 254, 25, 14, 15, 
+    55, 253, 248, 14, 15, 55, 254, 24, 14, 15, 55, 248, 161, 14, 15, 55, 254, 
+    7, 14, 15, 240, 36, 254, 7, 14, 15, 55, 253, 146, 14, 15, 55, 249, 88, 
+    14, 15, 55, 249, 87, 14, 15, 55, 251, 121, 14, 15, 55, 245, 238, 14, 15, 
+    55, 249, 86, 14, 15, 55, 251, 120, 14, 15, 55, 254, 8, 14, 15, 55, 253, 
+    216, 14, 15, 55, 253, 250, 14, 15, 55, 249, 102, 14, 15, 55, 253, 251, 
+    14, 15, 55, 253, 134, 14, 15, 55, 250, 201, 14, 15, 55, 250, 200, 14, 15, 
+    55, 250, 198, 14, 15, 55, 245, 70, 14, 15, 55, 250, 199, 14, 15, 55, 249, 
+    55, 14, 15, 55, 251, 194, 14, 15, 55, 249, 104, 14, 15, 55, 251, 193, 14, 
+    15, 55, 246, 45, 14, 15, 55, 249, 103, 14, 15, 55, 248, 225, 14, 15, 55, 
+    247, 155, 14, 15, 55, 244, 36, 14, 15, 55, 244, 34, 14, 15, 55, 242, 155, 
+    14, 15, 55, 244, 35, 14, 15, 55, 244, 33, 14, 15, 55, 249, 183, 14, 15, 
+    55, 249, 182, 14, 15, 55, 249, 180, 14, 15, 55, 247, 154, 14, 15, 55, 
+    249, 181, 14, 15, 55, 249, 179, 14, 15, 55, 254, 18, 14, 15, 55, 253, 
+    222, 14, 15, 55, 253, 228, 14, 15, 55, 248, 194, 14, 15, 55, 254, 17, 14, 
+    15, 55, 253, 163, 14, 15, 55, 255, 17, 14, 15, 55, 54, 255, 17, 14, 15, 
+    55, 250, 220, 14, 15, 55, 250, 219, 14, 15, 55, 248, 126, 14, 15, 55, 
+    245, 78, 14, 15, 55, 250, 218, 14, 15, 55, 248, 153, 14, 15, 55, 253, 
+    211, 14, 15, 55, 253, 186, 14, 15, 55, 253, 210, 14, 15, 55, 248, 184, 
+    14, 15, 55, 253, 198, 14, 15, 55, 253, 132, 14, 15, 55, 248, 248, 14, 15, 
+    55, 248, 110, 14, 15, 55, 248, 118, 14, 15, 55, 244, 9, 14, 15, 55, 248, 
+    185, 14, 15, 55, 248, 46, 14, 15, 55, 254, 72, 14, 15, 55, 249, 5, 14, 
+    15, 55, 249, 4, 14, 15, 55, 248, 112, 14, 15, 55, 244, 39, 14, 15, 55, 
+    248, 140, 14, 15, 55, 248, 90, 14, 15, 55, 248, 200, 14, 15, 55, 248, 
+    125, 14, 15, 55, 248, 88, 14, 15, 55, 243, 54, 14, 15, 55, 248, 67, 14, 
+    15, 55, 248, 57, 14, 15, 55, 247, 172, 14, 15, 55, 247, 171, 14, 15, 55, 
+    247, 169, 14, 15, 55, 242, 160, 14, 15, 55, 247, 170, 14, 15, 55, 247, 
+    168, 14, 15, 254, 83, 52, 14, 15, 248, 37, 208, 14, 15, 249, 146, 14, 15, 
+    246, 140, 14, 15, 246, 173, 14, 15, 242, 20, 14, 15, 246, 174, 14, 15, 
+    242, 21, 14, 15, 246, 172, 14, 15, 242, 19, 242, 221, 247, 96, 69, 242, 
+    221, 1, 241, 29, 242, 221, 1, 246, 55, 242, 221, 1, 241, 104, 242, 221, 
+    1, 247, 62, 242, 221, 1, 246, 156, 242, 221, 1, 247, 182, 242, 221, 1, 
+    245, 33, 242, 221, 1, 242, 153, 242, 221, 1, 245, 26, 242, 221, 1, 241, 
+    48, 242, 221, 1, 246, 94, 242, 221, 1, 245, 126, 242, 221, 1, 237, 220, 
+    242, 221, 1, 239, 205, 242, 221, 1, 247, 52, 242, 221, 1, 244, 72, 242, 
+    221, 1, 249, 130, 242, 221, 1, 254, 253, 242, 221, 1, 237, 144, 242, 221, 
+    1, 237, 182, 242, 221, 1, 237, 143, 242, 221, 1, 253, 227, 242, 221, 1, 
+    236, 134, 242, 221, 1, 245, 225, 242, 221, 1, 232, 163, 242, 221, 1, 242, 
+    54, 242, 221, 238, 184, 69, 242, 221, 224, 238, 184, 69, 119, 1, 250, 
+    238, 250, 240, 255, 74, 255, 19, 119, 1, 179, 119, 1, 253, 4, 255, 95, 
+    79, 119, 1, 254, 135, 119, 1, 255, 14, 119, 1, 255, 16, 119, 1, 238, 28, 
+    247, 146, 240, 149, 119, 1, 248, 109, 119, 1, 244, 82, 67, 119, 1, 255, 
+    86, 73, 119, 1, 255, 67, 67, 119, 1, 244, 69, 119, 1, 231, 23, 73, 119, 
+    1, 231, 77, 73, 119, 1, 73, 119, 1, 253, 193, 119, 1, 254, 9, 119, 1, 
+    247, 27, 254, 71, 252, 132, 144, 119, 1, 241, 195, 119, 1, 250, 155, 119, 
+    1, 251, 139, 255, 15, 119, 1, 210, 119, 1, 248, 108, 119, 1, 251, 13, 
+    251, 41, 210, 119, 1, 251, 9, 119, 1, 247, 198, 253, 40, 255, 16, 119, 1, 
+    241, 145, 192, 119, 1, 245, 138, 192, 119, 1, 226, 249, 192, 119, 1, 227, 
+    6, 192, 119, 1, 241, 253, 254, 218, 252, 0, 197, 119, 1, 231, 29, 197, 
+    119, 1, 236, 7, 119, 1, 251, 108, 255, 77, 254, 178, 71, 119, 1, 72, 119, 
+    1, 245, 234, 221, 119, 1, 251, 14, 119, 1, 231, 72, 253, 178, 119, 1, 
+    232, 54, 67, 119, 1, 251, 109, 250, 226, 119, 1, 242, 57, 242, 56, 223, 
+    119, 1, 244, 76, 241, 97, 119, 1, 242, 122, 193, 119, 1, 247, 89, 231, 
+    24, 193, 119, 1, 231, 78, 193, 119, 1, 255, 18, 119, 1, 255, 17, 119, 1, 
+    247, 153, 254, 249, 254, 251, 214, 119, 1, 231, 79, 214, 119, 1, 209, 
+    119, 1, 237, 76, 244, 218, 239, 10, 217, 119, 1, 226, 252, 217, 119, 1, 
+    236, 8, 119, 1, 239, 152, 119, 1, 245, 80, 255, 72, 72, 119, 1, 241, 227, 
+    254, 111, 173, 119, 1, 229, 49, 173, 119, 1, 231, 28, 173, 119, 1, 241, 
+    213, 251, 181, 251, 204, 162, 119, 1, 236, 6, 119, 1, 239, 98, 119, 1, 
+    251, 104, 119, 1, 245, 31, 250, 179, 209, 119, 1, 239, 155, 245, 85, 73, 
+    119, 1, 248, 206, 119, 1, 251, 106, 119, 1, 237, 98, 119, 1, 244, 240, 
+    119, 1, 241, 47, 119, 1, 247, 120, 119, 1, 231, 25, 119, 1, 231, 80, 119, 
+    1, 231, 141, 119, 1, 255, 20, 119, 1, 206, 119, 240, 12, 232, 75, 119, 
+    237, 215, 232, 75, 119, 243, 38, 232, 75, 119, 241, 16, 91, 119, 238, 34, 
+    91, 119, 237, 75, 91, 238, 63, 1, 67, 238, 63, 1, 71, 238, 63, 1, 79, 
+    238, 63, 1, 201, 238, 63, 1, 253, 139, 238, 63, 1, 248, 50, 238, 63, 1, 
+    253, 126, 238, 63, 1, 253, 133, 238, 63, 1, 253, 131, 238, 63, 1, 253, 
+    129, 238, 63, 1, 253, 141, 238, 63, 1, 222, 238, 63, 1, 216, 238, 63, 1, 
+    253, 134, 238, 63, 1, 253, 138, 238, 63, 1, 253, 132, 238, 63, 1, 219, 
+    238, 63, 33, 21, 71, 238, 63, 33, 21, 79, 238, 63, 21, 238, 72, 238, 60, 
+    1, 67, 238, 60, 1, 71, 238, 60, 1, 79, 238, 60, 1, 201, 238, 60, 1, 253, 
+    139, 238, 60, 1, 248, 50, 238, 60, 1, 253, 126, 238, 60, 1, 253, 133, 
+    238, 60, 1, 253, 131, 238, 60, 1, 253, 129, 238, 60, 1, 253, 141, 238, 
+    60, 1, 222, 238, 60, 1, 216, 238, 60, 1, 253, 130, 238, 60, 1, 253, 134, 
+    238, 60, 1, 253, 138, 238, 60, 1, 253, 132, 238, 60, 1, 219, 238, 60, 33, 
+    21, 71, 238, 60, 33, 21, 79, 238, 60, 21, 236, 70, 234, 63, 240, 12, 232, 
+    75, 234, 63, 45, 232, 75, 242, 231, 1, 67, 242, 231, 1, 71, 242, 231, 1, 
+    79, 242, 231, 1, 201, 242, 231, 1, 253, 139, 242, 231, 1, 248, 50, 242, 
+    231, 1, 253, 126, 242, 231, 1, 253, 133, 242, 231, 1, 253, 131, 242, 231, 
+    1, 253, 129, 242, 231, 1, 253, 141, 242, 231, 1, 222, 242, 231, 1, 216, 
+    242, 231, 1, 253, 130, 242, 231, 1, 253, 134, 242, 231, 1, 253, 138, 242, 
+    231, 1, 253, 132, 242, 231, 1, 219, 242, 231, 33, 21, 71, 242, 231, 33, 
+    21, 79, 236, 157, 1, 67, 236, 157, 1, 71, 236, 157, 1, 79, 236, 157, 1, 
+    201, 236, 157, 1, 253, 139, 236, 157, 1, 248, 50, 236, 157, 1, 253, 126, 
+    236, 157, 1, 253, 133, 236, 157, 1, 253, 131, 236, 157, 1, 253, 129, 236, 
+    157, 1, 253, 141, 236, 157, 1, 222, 236, 157, 1, 216, 236, 157, 1, 253, 
+    134, 236, 157, 1, 253, 138, 236, 157, 1, 253, 132, 236, 157, 33, 21, 71, 
+    236, 157, 33, 21, 79, 63, 1, 201, 63, 1, 248, 61, 63, 1, 253, 190, 63, 1, 
+    248, 220, 63, 1, 248, 172, 63, 1, 253, 152, 63, 1, 248, 57, 63, 1, 253, 
+    224, 63, 1, 248, 125, 63, 1, 248, 133, 63, 1, 253, 133, 63, 1, 242, 247, 
+    63, 1, 253, 225, 63, 1, 243, 131, 63, 1, 252, 31, 63, 1, 253, 126, 63, 1, 
+    248, 55, 63, 1, 87, 63, 1, 248, 97, 63, 1, 253, 173, 63, 1, 253, 141, 63, 
+    1, 248, 65, 63, 1, 253, 208, 63, 1, 248, 238, 63, 1, 253, 181, 63, 1, 
+    253, 162, 63, 1, 253, 160, 63, 1, 253, 216, 63, 1, 254, 13, 63, 1, 248, 
+    46, 63, 1, 248, 250, 63, 1, 253, 132, 63, 1, 219, 63, 1, 253, 134, 63, 1, 
+    253, 217, 63, 233, 52, 33, 252, 86, 63, 233, 52, 33, 248, 241, 63, 233, 
+    52, 33, 254, 28, 63, 233, 52, 33, 249, 147, 63, 233, 52, 33, 254, 29, 63, 
+    233, 52, 33, 252, 106, 63, 233, 52, 33, 249, 150, 63, 233, 52, 33, 247, 
+    20, 63, 233, 52, 33, 254, 125, 63, 233, 52, 33, 252, 163, 63, 233, 52, 
+    33, 254, 110, 63, 233, 52, 33, 251, 217, 63, 233, 52, 33, 254, 70, 63, 
+    233, 52, 33, 249, 146, 63, 233, 52, 33, 254, 123, 249, 9, 127, 63, 233, 
+    52, 33, 254, 123, 249, 9, 111, 63, 233, 52, 33, 252, 87, 63, 33, 237, 13, 
+    254, 142, 63, 33, 237, 13, 253, 140, 63, 33, 21, 253, 140, 63, 33, 21, 
+    71, 63, 33, 21, 253, 142, 63, 33, 21, 255, 14, 63, 33, 21, 254, 77, 63, 
+    33, 21, 79, 63, 33, 21, 253, 148, 63, 33, 21, 254, 74, 63, 33, 21, 253, 
+    193, 63, 33, 21, 216, 63, 33, 21, 253, 237, 63, 33, 21, 72, 63, 33, 21, 
+    253, 178, 63, 33, 21, 253, 149, 63, 33, 21, 253, 156, 63, 33, 21, 253, 
+    151, 63, 21, 237, 221, 63, 21, 237, 248, 63, 21, 231, 84, 63, 21, 232, 
+    184, 63, 21, 238, 32, 63, 21, 239, 3, 63, 21, 242, 86, 63, 21, 233, 43, 
+    63, 21, 237, 186, 63, 21, 241, 7, 63, 21, 242, 96, 239, 179, 63, 21, 239, 
+    243, 63, 21, 241, 62, 63, 21, 233, 121, 63, 21, 246, 10, 63, 21, 233, 
+    120, 63, 21, 241, 42, 254, 69, 246, 24, 63, 21, 253, 204, 249, 2, 63, 21, 
+    239, 8, 63, 21, 242, 59, 246, 93, 63, 21, 237, 191, 63, 236, 181, 12, 
+    247, 31, 63, 21, 231, 59, 63, 21, 235, 176, 63, 26, 242, 217, 63, 26, 
+    127, 63, 26, 111, 63, 26, 166, 63, 26, 177, 63, 26, 176, 63, 26, 187, 63, 
+    26, 203, 63, 26, 195, 63, 26, 202, 63, 12, 253, 204, 243, 4, 252, 184, 
+    63, 12, 253, 204, 243, 4, 246, 99, 63, 12, 253, 204, 243, 4, 249, 138, 
+    63, 12, 253, 204, 243, 4, 250, 113, 63, 12, 253, 204, 243, 4, 244, 233, 
+    63, 12, 253, 204, 243, 4, 246, 253, 63, 12, 253, 204, 243, 4, 234, 239, 
+    63, 12, 253, 204, 243, 4, 236, 79, 63, 12, 253, 204, 243, 4, 236, 78, 63, 
+    12, 253, 204, 243, 4, 234, 238, 58, 241, 31, 58, 235, 69, 58, 240, 27, 
+    58, 248, 37, 208, 58, 240, 24, 58, 248, 58, 243, 5, 58, 248, 47, 248, 
+    186, 238, 93, 58, 248, 54, 4, 237, 78, 238, 95, 58, 240, 14, 240, 27, 58, 
+    240, 14, 248, 37, 208, 58, 239, 144, 58, 248, 210, 34, 236, 239, 127, 58, 
+    248, 210, 34, 236, 239, 111, 58, 248, 210, 34, 236, 239, 166, 58, 33, 
+    234, 6, 58, 26, 242, 217, 58, 26, 127, 58, 26, 111, 58, 26, 166, 58, 26, 
+    177, 58, 26, 176, 58, 26, 187, 58, 26, 203, 58, 26, 195, 58, 26, 202, 58, 
+    1, 67, 58, 1, 72, 58, 1, 71, 58, 1, 73, 58, 1, 79, 58, 1, 253, 193, 58, 
+    1, 253, 252, 58, 1, 253, 164, 58, 1, 253, 131, 58, 1, 248, 124, 58, 1, 
+    253, 141, 58, 1, 253, 129, 58, 1, 253, 217, 58, 1, 253, 139, 58, 1, 222, 
+    58, 1, 253, 134, 58, 1, 253, 132, 58, 1, 248, 46, 58, 1, 253, 126, 58, 1, 
+    253, 133, 58, 1, 248, 57, 58, 1, 253, 146, 58, 1, 216, 58, 1, 253, 130, 
+    58, 1, 253, 138, 58, 1, 253, 179, 58, 1, 201, 58, 1, 248, 61, 58, 1, 248, 
+    90, 58, 1, 253, 163, 58, 1, 248, 114, 58, 1, 253, 113, 58, 1, 248, 225, 
+    58, 1, 249, 217, 58, 1, 248, 67, 58, 1, 248, 47, 183, 33, 52, 58, 1, 248, 
+    47, 72, 58, 1, 248, 47, 71, 58, 1, 248, 47, 73, 58, 1, 248, 47, 79, 58, 
+    1, 248, 47, 253, 193, 58, 1, 248, 47, 253, 252, 58, 1, 248, 47, 248, 124, 
+    58, 1, 248, 47, 253, 141, 58, 1, 248, 47, 253, 129, 58, 1, 248, 47, 253, 
+    217, 58, 1, 248, 47, 253, 139, 58, 1, 248, 47, 222, 58, 1, 248, 47, 253, 
+    126, 58, 1, 248, 47, 253, 133, 58, 1, 248, 47, 248, 57, 58, 1, 248, 47, 
+    253, 146, 58, 1, 248, 47, 248, 90, 58, 1, 248, 47, 216, 58, 1, 248, 47, 
+    253, 138, 58, 1, 248, 47, 201, 58, 1, 248, 47, 248, 211, 58, 1, 248, 47, 
+    248, 114, 58, 1, 248, 47, 251, 115, 58, 1, 248, 47, 252, 20, 58, 1, 248, 
+    47, 248, 153, 58, 1, 248, 54, 72, 58, 1, 248, 54, 71, 58, 1, 248, 54, 
+    254, 102, 58, 1, 248, 54, 253, 252, 58, 1, 248, 54, 79, 58, 1, 248, 54, 
+    248, 124, 58, 1, 248, 54, 201, 58, 1, 248, 54, 253, 139, 58, 1, 248, 54, 
+    219, 58, 1, 248, 54, 253, 129, 58, 1, 248, 54, 248, 46, 58, 1, 248, 54, 
+    253, 126, 58, 1, 248, 54, 253, 133, 58, 1, 248, 54, 253, 146, 58, 1, 248, 
+    54, 253, 179, 58, 1, 248, 54, 248, 211, 58, 1, 248, 54, 248, 114, 58, 1, 
+    248, 54, 248, 90, 58, 1, 248, 54, 253, 163, 58, 1, 248, 54, 248, 182, 58, 
+    1, 248, 54, 248, 57, 58, 1, 248, 54, 248, 99, 58, 1, 240, 14, 71, 58, 1, 
+    240, 14, 201, 58, 1, 240, 14, 253, 130, 58, 1, 240, 14, 253, 179, 58, 1, 
+    240, 14, 248, 99, 58, 1, 253, 128, 248, 36, 237, 62, 127, 58, 1, 253, 
+    128, 248, 36, 239, 244, 127, 58, 1, 253, 128, 248, 36, 239, 36, 58, 1, 
+    253, 128, 248, 36, 237, 50, 58, 1, 253, 128, 248, 36, 236, 145, 237, 50, 
+    58, 1, 253, 128, 248, 36, 238, 163, 58, 1, 253, 128, 248, 36, 204, 238, 
+    163, 58, 1, 253, 128, 248, 36, 67, 58, 1, 253, 128, 248, 36, 71, 58, 1, 
+    253, 128, 248, 36, 201, 58, 1, 253, 128, 248, 36, 248, 50, 58, 1, 253, 
+    128, 248, 36, 253, 152, 58, 1, 253, 128, 248, 36, 248, 71, 58, 1, 253, 
+    128, 248, 36, 242, 247, 58, 1, 253, 128, 248, 36, 248, 75, 58, 1, 253, 
+    128, 248, 36, 248, 82, 58, 1, 253, 128, 248, 36, 253, 126, 58, 1, 253, 
+    128, 248, 36, 253, 133, 58, 1, 253, 128, 248, 36, 253, 129, 58, 1, 253, 
+    128, 248, 36, 248, 65, 58, 1, 253, 128, 248, 36, 248, 66, 58, 1, 253, 
+    128, 248, 36, 248, 99, 58, 1, 253, 128, 248, 36, 253, 163, 58, 1, 253, 
+    128, 248, 36, 254, 0, 58, 1, 248, 47, 253, 128, 248, 36, 253, 126, 58, 1, 
+    248, 47, 253, 128, 248, 36, 248, 99, 58, 1, 240, 14, 253, 128, 248, 36, 
+    248, 77, 58, 1, 240, 14, 253, 128, 248, 36, 248, 50, 58, 1, 240, 14, 253, 
+    128, 248, 36, 253, 152, 58, 1, 240, 14, 253, 128, 248, 36, 248, 89, 58, 
+    1, 240, 14, 253, 128, 248, 36, 248, 71, 58, 1, 240, 14, 253, 128, 248, 
+    36, 242, 249, 58, 1, 240, 14, 253, 128, 248, 36, 253, 126, 58, 1, 240, 
+    14, 253, 128, 248, 36, 248, 76, 58, 1, 240, 14, 253, 128, 248, 36, 248, 
+    66, 58, 1, 240, 14, 253, 128, 248, 36, 250, 174, 58, 1, 240, 14, 253, 
+    128, 248, 36, 248, 99, 58, 1, 240, 14, 253, 128, 248, 36, 253, 163, 58, 
+    1, 253, 128, 248, 36, 137, 79, 58, 1, 253, 128, 248, 36, 137, 216, 58, 1, 
+    240, 14, 253, 128, 248, 36, 248, 81, 58, 1, 253, 128, 248, 36, 237, 101, 
+    149, 232, 65, 239, 117, 149, 1, 201, 149, 1, 248, 61, 149, 1, 253, 139, 
+    149, 1, 248, 77, 149, 1, 248, 50, 149, 1, 253, 152, 149, 1, 248, 57, 149, 
+    1, 253, 146, 149, 1, 248, 89, 149, 1, 249, 203, 149, 1, 253, 126, 149, 1, 
+    248, 55, 149, 1, 253, 133, 149, 1, 248, 76, 149, 1, 253, 131, 149, 1, 
+    253, 129, 149, 1, 248, 65, 149, 1, 253, 141, 149, 1, 248, 81, 149, 1, 
+    222, 149, 1, 216, 149, 1, 253, 130, 149, 1, 253, 134, 149, 1, 253, 138, 
+    149, 1, 248, 46, 149, 1, 248, 66, 149, 1, 253, 132, 149, 1, 219, 149, 33, 
+    21, 67, 149, 33, 21, 71, 149, 33, 21, 79, 149, 33, 21, 253, 164, 149, 33, 
+    21, 253, 149, 149, 33, 21, 253, 156, 149, 33, 21, 253, 151, 149, 33, 21, 
+    72, 149, 33, 21, 73, 149, 213, 1, 216, 149, 213, 1, 253, 130, 149, 213, 
+    1, 253, 138, 149, 3, 1, 201, 149, 3, 1, 248, 50, 149, 3, 1, 235, 61, 149, 
+    3, 1, 253, 126, 149, 3, 1, 253, 131, 149, 3, 1, 253, 129, 149, 3, 1, 222, 
+    149, 3, 1, 253, 130, 149, 3, 1, 253, 134, 149, 21, 234, 226, 149, 21, 
+    234, 212, 149, 21, 247, 59, 149, 21, 248, 226, 149, 233, 54, 69, 149, 
+    236, 156, 69, 149, 26, 242, 217, 149, 26, 127, 149, 26, 111, 149, 26, 
+    166, 149, 26, 177, 149, 26, 176, 149, 26, 187, 149, 26, 203, 149, 26, 
+    195, 149, 26, 202, 81, 255, 21, 1, 201, 81, 255, 21, 1, 253, 253, 81, 
+    255, 21, 1, 248, 50, 81, 255, 21, 1, 248, 90, 81, 255, 21, 1, 253, 132, 
+    81, 255, 21, 1, 216, 81, 255, 21, 1, 253, 126, 81, 255, 21, 1, 248, 55, 
+    81, 255, 21, 1, 253, 134, 81, 255, 21, 1, 253, 129, 81, 255, 21, 1, 248, 
+    65, 81, 255, 21, 1, 222, 81, 255, 21, 1, 253, 179, 81, 255, 21, 1, 253, 
+    171, 81, 255, 21, 1, 219, 81, 255, 21, 1, 253, 217, 81, 255, 21, 1, 248, 
+    61, 81, 255, 21, 1, 243, 130, 81, 255, 21, 1, 253, 131, 81, 255, 21, 1, 
+    67, 81, 255, 21, 1, 71, 81, 255, 21, 1, 253, 164, 81, 255, 21, 1, 254, 
+    36, 81, 255, 21, 1, 79, 81, 255, 21, 1, 253, 156, 81, 255, 21, 1, 73, 81, 
+    255, 21, 1, 253, 252, 81, 255, 21, 1, 72, 81, 255, 21, 1, 249, 243, 81, 
+    255, 21, 1, 253, 149, 81, 255, 21, 1, 239, 223, 81, 255, 21, 1, 239, 224, 
+    81, 255, 21, 1, 239, 225, 81, 255, 21, 1, 239, 226, 81, 255, 21, 1, 239, 
+    227, 116, 81, 122, 1, 200, 253, 217, 116, 81, 122, 1, 170, 253, 217, 116, 
+    81, 122, 1, 200, 201, 116, 81, 122, 1, 200, 253, 253, 116, 81, 122, 1, 
+    200, 248, 50, 116, 81, 122, 1, 170, 201, 116, 81, 122, 1, 170, 253, 253, 
+    116, 81, 122, 1, 170, 248, 50, 116, 81, 122, 1, 200, 248, 90, 116, 81, 
+    122, 1, 200, 253, 132, 116, 81, 122, 1, 200, 216, 116, 81, 122, 1, 170, 
+    248, 90, 116, 81, 122, 1, 170, 253, 132, 116, 81, 122, 1, 170, 216, 116, 
+    81, 122, 1, 200, 253, 126, 116, 81, 122, 1, 200, 248, 55, 116, 81, 122, 
+    1, 200, 253, 131, 116, 81, 122, 1, 170, 253, 126, 116, 81, 122, 1, 170, 
+    248, 55, 116, 81, 122, 1, 170, 253, 131, 116, 81, 122, 1, 200, 253, 129, 
+    116, 81, 122, 1, 200, 248, 65, 116, 81, 122, 1, 200, 222, 116, 81, 122, 
+    1, 170, 253, 129, 116, 81, 122, 1, 170, 248, 65, 116, 81, 122, 1, 170, 
+    222, 116, 81, 122, 1, 200, 253, 179, 116, 81, 122, 1, 200, 253, 171, 116, 
+    81, 122, 1, 200, 253, 134, 116, 81, 122, 1, 170, 253, 179, 116, 81, 122, 
+    1, 170, 253, 171, 116, 81, 122, 1, 170, 253, 134, 116, 81, 122, 1, 200, 
+    219, 116, 81, 122, 1, 200, 253, 133, 116, 81, 122, 1, 200, 253, 141, 116, 
+    81, 122, 1, 170, 219, 116, 81, 122, 1, 170, 253, 133, 116, 81, 122, 1, 
+    170, 253, 141, 116, 81, 122, 1, 200, 249, 99, 116, 81, 122, 1, 200, 249, 
+    201, 116, 81, 122, 1, 170, 249, 99, 116, 81, 122, 1, 170, 249, 201, 116, 
+    81, 122, 33, 21, 33, 234, 255, 116, 81, 122, 33, 21, 253, 140, 116, 81, 
+    122, 33, 21, 253, 142, 116, 81, 122, 33, 21, 79, 116, 81, 122, 33, 21, 
+    253, 148, 116, 81, 122, 33, 21, 72, 116, 81, 122, 33, 21, 253, 178, 116, 
+    81, 122, 33, 21, 73, 116, 81, 122, 33, 21, 254, 117, 116, 81, 122, 33, 
+    21, 253, 252, 116, 81, 122, 33, 21, 254, 33, 116, 81, 122, 33, 21, 249, 
+    232, 116, 81, 122, 33, 21, 254, 254, 116, 81, 122, 33, 21, 254, 221, 116, 
+    81, 122, 33, 21, 252, 56, 116, 81, 122, 33, 21, 252, 250, 116, 81, 122, 
+    33, 21, 254, 102, 116, 81, 122, 1, 30, 179, 116, 81, 122, 1, 30, 254, 26, 
+    116, 81, 122, 1, 30, 197, 116, 81, 122, 1, 30, 173, 116, 81, 122, 1, 30, 
+    255, 15, 116, 81, 122, 1, 30, 209, 116, 81, 122, 1, 30, 217, 116, 81, 
+    122, 188, 238, 200, 116, 81, 122, 188, 238, 201, 116, 81, 122, 26, 242, 
+    217, 116, 81, 122, 26, 127, 116, 81, 122, 26, 111, 116, 81, 122, 26, 166, 
+    116, 81, 122, 26, 177, 116, 81, 122, 26, 176, 116, 81, 122, 26, 187, 116, 
+    81, 122, 26, 203, 116, 81, 122, 26, 195, 116, 81, 122, 26, 202, 116, 81, 
+    122, 21, 251, 180, 116, 81, 122, 21, 246, 36, 63, 12, 233, 223, 63, 12, 
+    249, 116, 242, 246, 63, 12, 254, 69, 242, 246, 63, 12, 254, 81, 242, 246, 
+    63, 12, 249, 34, 242, 246, 63, 12, 249, 141, 242, 246, 63, 12, 235, 137, 
+    242, 246, 63, 12, 237, 32, 242, 246, 63, 12, 237, 31, 242, 246, 63, 12, 
+    235, 136, 242, 246, 63, 12, 254, 86, 242, 246, 63, 12, 237, 3, 242, 246, 
+    63, 12, 238, 175, 242, 246, 63, 12, 238, 174, 242, 246, 63, 12, 237, 2, 
+    242, 246, 63, 12, 237, 4, 242, 246, 63, 12, 235, 38, 63, 12, 249, 116, 
+    248, 80, 63, 12, 254, 69, 248, 80, 63, 12, 254, 81, 248, 80, 63, 12, 249, 
+    34, 248, 80, 63, 12, 249, 141, 248, 80, 63, 12, 235, 137, 248, 80, 63, 
+    12, 237, 32, 248, 80, 63, 12, 237, 31, 248, 80, 63, 12, 235, 136, 248, 
+    80, 63, 12, 254, 86, 248, 80, 63, 12, 237, 3, 248, 80, 63, 12, 238, 175, 
+    248, 80, 63, 12, 238, 174, 248, 80, 63, 12, 237, 2, 248, 80, 63, 12, 237, 
+    4, 248, 80, 236, 148, 1, 201, 236, 148, 1, 253, 139, 236, 148, 1, 248, 
+    50, 236, 148, 1, 246, 148, 236, 148, 1, 253, 129, 236, 148, 1, 253, 141, 
+    236, 148, 1, 222, 236, 148, 1, 249, 115, 236, 148, 1, 253, 126, 236, 148, 
+    1, 253, 133, 236, 148, 1, 253, 131, 236, 148, 1, 249, 123, 236, 148, 1, 
+    253, 152, 236, 148, 1, 253, 146, 236, 148, 1, 248, 78, 236, 148, 1, 246, 
+    199, 236, 148, 1, 216, 236, 148, 1, 253, 130, 236, 148, 1, 253, 134, 236, 
+    148, 1, 253, 171, 236, 148, 1, 253, 132, 236, 148, 1, 67, 236, 148, 1, 
+    219, 236, 148, 33, 21, 71, 236, 148, 33, 21, 79, 236, 148, 33, 21, 72, 
+    236, 148, 33, 21, 73, 236, 148, 33, 21, 253, 178, 236, 148, 237, 231, 
+    236, 148, 253, 165, 147, 236, 210, 8, 1, 3, 5, 67, 8, 1, 3, 5, 253, 178, 
+    8, 3, 1, 205, 253, 178, 8, 1, 3, 5, 240, 60, 217, 8, 1, 3, 5, 255, 18, 8, 
+    1, 3, 5, 209, 8, 1, 3, 5, 248, 109, 8, 1, 3, 5, 72, 8, 3, 1, 205, 248, 
+    35, 72, 8, 3, 1, 205, 71, 8, 1, 3, 5, 221, 8, 1, 3, 5, 255, 15, 8, 1, 3, 
+    5, 255, 100, 2, 108, 8, 1, 3, 5, 173, 8, 1, 3, 5, 224, 197, 8, 1, 3, 5, 
+    73, 8, 1, 3, 5, 248, 35, 73, 8, 3, 1, 236, 190, 73, 8, 3, 1, 236, 190, 
+    248, 35, 73, 8, 3, 1, 236, 190, 117, 2, 108, 8, 3, 1, 205, 253, 193, 8, 
+    1, 3, 5, 254, 10, 8, 3, 1, 253, 159, 137, 73, 8, 3, 1, 240, 17, 137, 73, 
+    8, 1, 3, 5, 223, 8, 1, 3, 5, 224, 144, 8, 1, 3, 5, 205, 144, 8, 1, 3, 5, 
+    214, 8, 1, 3, 5, 79, 8, 3, 1, 236, 190, 79, 8, 3, 1, 236, 190, 233, 132, 
+    79, 8, 3, 1, 236, 190, 205, 173, 8, 1, 3, 5, 179, 8, 1, 3, 5, 255, 16, 8, 
+    1, 3, 5, 255, 17, 8, 1, 3, 5, 248, 155, 8, 1, 240, 59, 236, 49, 238, 10, 
+    8, 1, 248, 105, 17, 1, 3, 5, 240, 10, 17, 1, 3, 5, 240, 33, 17, 1, 3, 5, 
+    253, 147, 17, 1, 3, 5, 248, 73, 17, 1, 3, 5, 248, 69, 32, 1, 3, 5, 254, 
+    3, 49, 1, 5, 67, 49, 1, 5, 253, 178, 49, 1, 5, 217, 49, 1, 5, 240, 60, 
+    217, 49, 1, 5, 209, 49, 1, 5, 72, 49, 1, 5, 224, 72, 49, 1, 5, 210, 49, 
+    1, 5, 192, 49, 1, 5, 71, 49, 1, 5, 221, 49, 1, 5, 255, 15, 49, 1, 5, 162, 
+    49, 1, 5, 173, 49, 1, 5, 197, 49, 1, 5, 224, 197, 49, 1, 5, 73, 49, 1, 5, 
+    254, 10, 49, 1, 5, 223, 49, 1, 5, 144, 49, 1, 5, 214, 49, 1, 5, 79, 49, 
+    1, 5, 255, 16, 49, 1, 3, 67, 49, 1, 3, 205, 67, 49, 1, 3, 240, 22, 49, 1, 
+    3, 205, 253, 178, 49, 1, 3, 217, 49, 1, 3, 209, 49, 1, 3, 72, 49, 1, 3, 
+    240, 86, 49, 1, 3, 248, 35, 72, 49, 1, 3, 205, 248, 35, 72, 49, 1, 3, 
+    210, 49, 1, 3, 205, 71, 49, 1, 3, 255, 15, 49, 1, 3, 173, 49, 1, 3, 248, 
+    108, 49, 1, 3, 73, 49, 1, 3, 248, 35, 73, 49, 1, 3, 253, 159, 137, 73, 
+    49, 1, 3, 240, 17, 137, 73, 49, 1, 3, 223, 49, 1, 3, 214, 49, 1, 3, 79, 
+    49, 1, 3, 236, 190, 79, 49, 1, 3, 205, 173, 49, 1, 3, 179, 49, 1, 3, 248, 
+    105, 49, 1, 3, 242, 242, 49, 1, 3, 17, 240, 10, 49, 1, 3, 240, 28, 49, 1, 
+    3, 17, 248, 68, 49, 1, 3, 248, 67, 8, 235, 48, 3, 1, 71, 8, 235, 48, 3, 
+    1, 144, 8, 235, 48, 3, 1, 79, 8, 235, 48, 3, 1, 179, 17, 235, 48, 3, 1, 
+    242, 242, 17, 235, 48, 3, 1, 240, 10, 17, 235, 48, 3, 1, 248, 73, 17, 
+    235, 48, 3, 1, 248, 68, 17, 235, 48, 3, 1, 248, 67, 8, 3, 1, 253, 252, 8, 
+    3, 1, 41, 2, 240, 1, 169, 8, 3, 1, 255, 103, 2, 240, 1, 169, 8, 3, 1, 
+    255, 112, 2, 240, 1, 169, 8, 3, 1, 255, 108, 2, 240, 1, 169, 8, 3, 1, 
+    255, 98, 2, 240, 1, 169, 8, 3, 1, 255, 114, 2, 240, 1, 169, 8, 3, 1, 255, 
+    101, 2, 240, 1, 169, 8, 3, 1, 255, 101, 2, 237, 11, 19, 240, 1, 169, 8, 
+    3, 1, 255, 99, 2, 240, 1, 169, 8, 3, 1, 255, 102, 2, 240, 1, 169, 8, 3, 
+    1, 255, 97, 2, 240, 1, 169, 8, 3, 1, 205, 210, 49, 1, 32, 253, 202, 8, 3, 
+    1, 239, 101, 210, 8, 3, 1, 255, 93, 2, 231, 82, 8, 3, 5, 1, 220, 2, 108, 
+    8, 3, 1, 248, 42, 2, 108, 8, 3, 1, 255, 114, 2, 108, 8, 3, 5, 1, 132, 2, 
+    108, 8, 3, 1, 238, 53, 2, 108, 8, 3, 1, 41, 2, 238, 65, 90, 8, 3, 1, 255, 
+    103, 2, 238, 65, 90, 8, 3, 1, 255, 112, 2, 238, 65, 90, 8, 3, 1, 255, 
+    104, 2, 238, 65, 90, 8, 3, 1, 255, 109, 2, 238, 65, 90, 8, 3, 1, 255, 
+    100, 2, 238, 65, 90, 8, 3, 1, 255, 108, 2, 238, 65, 90, 8, 3, 1, 255, 98, 
+    2, 238, 65, 90, 8, 3, 1, 255, 114, 2, 238, 65, 90, 8, 3, 1, 255, 101, 2, 
+    238, 65, 90, 8, 3, 1, 255, 99, 2, 238, 65, 90, 8, 3, 1, 254, 38, 2, 238, 
+    65, 90, 8, 3, 1, 255, 110, 2, 238, 65, 90, 8, 3, 1, 255, 113, 2, 238, 65, 
+    90, 8, 3, 1, 255, 97, 2, 238, 65, 90, 8, 3, 1, 134, 2, 235, 54, 90, 8, 3, 
+    1, 194, 2, 235, 54, 90, 8, 3, 1, 255, 103, 2, 248, 45, 19, 242, 226, 8, 
+    3, 1, 157, 2, 235, 54, 90, 8, 3, 1, 248, 35, 157, 2, 235, 54, 90, 8, 3, 
+    1, 224, 248, 35, 157, 2, 235, 54, 90, 8, 3, 1, 243, 73, 2, 235, 54, 90, 
+    8, 3, 1, 220, 2, 235, 54, 90, 8, 3, 1, 248, 35, 117, 2, 235, 54, 90, 8, 
+    3, 1, 254, 38, 2, 235, 54, 90, 8, 3, 1, 132, 2, 235, 54, 90, 8, 3, 1, 
+    253, 244, 2, 235, 54, 90, 49, 1, 3, 205, 240, 22, 49, 1, 3, 255, 18, 49, 
+    1, 3, 255, 105, 2, 242, 253, 49, 1, 3, 248, 109, 49, 1, 3, 224, 248, 35, 
+    72, 49, 1, 3, 255, 19, 49, 1, 3, 238, 70, 255, 115, 2, 108, 49, 1, 3, 84, 
+    210, 49, 1, 3, 205, 192, 49, 1, 3, 220, 2, 108, 49, 1, 3, 242, 237, 49, 
+    1, 3, 5, 71, 49, 1, 3, 5, 220, 2, 108, 49, 1, 3, 255, 115, 2, 231, 101, 
+    49, 1, 3, 255, 100, 2, 235, 54, 90, 49, 1, 3, 255, 100, 2, 238, 65, 90, 
+    49, 1, 3, 5, 162, 49, 1, 3, 255, 108, 2, 90, 49, 1, 3, 205, 255, 108, 2, 
+    183, 248, 117, 49, 1, 3, 255, 98, 2, 40, 90, 49, 1, 3, 255, 98, 2, 235, 
+    54, 90, 49, 1, 3, 5, 197, 49, 1, 3, 240, 60, 73, 49, 1, 3, 248, 68, 49, 
+    1, 3, 255, 99, 2, 90, 49, 1, 3, 248, 93, 49, 1, 3, 255, 102, 2, 238, 65, 
+    90, 49, 1, 3, 132, 125, 49, 1, 3, 236, 160, 49, 1, 3, 5, 79, 49, 1, 3, 
+    255, 110, 2, 90, 49, 1, 3, 205, 179, 49, 1, 3, 255, 17, 49, 1, 3, 255, 
+    97, 2, 235, 54, 90, 49, 1, 3, 255, 97, 2, 242, 253, 49, 1, 3, 248, 155, 
+    49, 1, 3, 240, 38, 50, 240, 4, 242, 245, 238, 54, 50, 240, 4, 242, 241, 
+    238, 54, 50, 247, 95, 46, 50, 235, 6, 69, 8, 5, 1, 134, 2, 248, 51, 46, 
+    8, 3, 1, 134, 2, 248, 51, 46, 8, 5, 1, 41, 2, 53, 48, 8, 3, 1, 41, 2, 53, 
+    48, 8, 5, 1, 41, 2, 53, 46, 8, 3, 1, 41, 2, 53, 46, 8, 5, 1, 41, 2, 248, 
+    41, 46, 8, 3, 1, 41, 2, 248, 41, 46, 8, 5, 1, 255, 105, 2, 238, 109, 19, 
+    135, 8, 3, 1, 255, 105, 2, 238, 109, 19, 135, 8, 5, 1, 255, 103, 2, 53, 
+    48, 8, 3, 1, 255, 103, 2, 53, 48, 8, 5, 1, 255, 103, 2, 53, 46, 8, 3, 1, 
+    255, 103, 2, 53, 46, 8, 5, 1, 255, 103, 2, 248, 41, 46, 8, 3, 1, 255, 
+    103, 2, 248, 41, 46, 8, 5, 1, 255, 103, 2, 236, 151, 8, 3, 1, 255, 103, 
+    2, 236, 151, 8, 5, 1, 255, 103, 2, 190, 46, 8, 3, 1, 255, 103, 2, 190, 
+    46, 8, 5, 1, 157, 2, 240, 42, 19, 191, 8, 3, 1, 157, 2, 240, 42, 19, 191, 
+    8, 5, 1, 157, 2, 240, 42, 19, 135, 8, 3, 1, 157, 2, 240, 42, 19, 135, 8, 
+    5, 1, 157, 2, 190, 46, 8, 3, 1, 157, 2, 190, 46, 8, 5, 1, 157, 2, 242, 
+    219, 46, 8, 3, 1, 157, 2, 242, 219, 46, 8, 5, 1, 157, 2, 238, 109, 19, 
+    239, 255, 8, 3, 1, 157, 2, 238, 109, 19, 239, 255, 8, 5, 1, 255, 112, 2, 
+    53, 48, 8, 3, 1, 255, 112, 2, 53, 48, 8, 5, 1, 255, 104, 2, 196, 8, 3, 1, 
+    255, 104, 2, 196, 8, 5, 1, 255, 106, 2, 53, 48, 8, 3, 1, 255, 106, 2, 53, 
+    48, 8, 5, 1, 255, 106, 2, 53, 46, 8, 3, 1, 255, 106, 2, 53, 46, 8, 5, 1, 
+    255, 106, 2, 175, 8, 3, 1, 255, 106, 2, 175, 8, 5, 1, 255, 106, 2, 236, 
+    151, 8, 3, 1, 255, 106, 2, 236, 151, 8, 5, 1, 255, 106, 2, 242, 243, 46, 
+    8, 3, 1, 255, 106, 2, 242, 243, 46, 8, 5, 1, 220, 2, 242, 219, 46, 8, 3, 
+    1, 220, 2, 242, 219, 46, 8, 5, 1, 220, 2, 235, 56, 19, 135, 8, 3, 1, 220, 
+    2, 235, 56, 19, 135, 8, 5, 1, 255, 109, 2, 135, 8, 3, 1, 255, 109, 2, 
+    135, 8, 5, 1, 255, 109, 2, 53, 46, 8, 3, 1, 255, 109, 2, 53, 46, 8, 5, 1, 
+    255, 109, 2, 248, 41, 46, 8, 3, 1, 255, 109, 2, 248, 41, 46, 8, 5, 1, 
+    255, 100, 2, 53, 46, 8, 3, 1, 255, 100, 2, 53, 46, 8, 5, 1, 255, 100, 2, 
+    53, 242, 230, 19, 196, 8, 3, 1, 255, 100, 2, 53, 242, 230, 19, 196, 8, 5, 
+    1, 255, 100, 2, 248, 41, 46, 8, 3, 1, 255, 100, 2, 248, 41, 46, 8, 5, 1, 
+    255, 100, 2, 190, 46, 8, 3, 1, 255, 100, 2, 190, 46, 8, 5, 1, 255, 108, 
+    2, 135, 8, 3, 1, 255, 108, 2, 135, 8, 5, 1, 255, 108, 2, 53, 48, 8, 3, 1, 
+    255, 108, 2, 53, 48, 8, 5, 1, 255, 108, 2, 53, 46, 8, 3, 1, 255, 108, 2, 
+    53, 46, 8, 5, 1, 255, 98, 2, 53, 48, 8, 3, 1, 255, 98, 2, 53, 48, 8, 5, 
+    1, 255, 98, 2, 53, 46, 8, 3, 1, 255, 98, 2, 53, 46, 8, 5, 1, 255, 98, 2, 
+    248, 41, 46, 8, 3, 1, 255, 98, 2, 248, 41, 46, 8, 5, 1, 255, 98, 2, 190, 
+    46, 8, 3, 1, 255, 98, 2, 190, 46, 8, 5, 1, 117, 2, 242, 219, 19, 135, 8, 
+    3, 1, 117, 2, 242, 219, 19, 135, 8, 5, 1, 117, 2, 242, 219, 19, 175, 8, 
+    3, 1, 117, 2, 242, 219, 19, 175, 8, 5, 1, 117, 2, 240, 42, 19, 191, 8, 3, 
+    1, 117, 2, 240, 42, 19, 191, 8, 5, 1, 117, 2, 240, 42, 19, 135, 8, 3, 1, 
+    117, 2, 240, 42, 19, 135, 8, 5, 1, 255, 114, 2, 135, 8, 3, 1, 255, 114, 
+    2, 135, 8, 5, 1, 255, 114, 2, 53, 48, 8, 3, 1, 255, 114, 2, 53, 48, 8, 5, 
+    1, 255, 101, 2, 53, 48, 8, 3, 1, 255, 101, 2, 53, 48, 8, 5, 1, 255, 101, 
+    2, 53, 46, 8, 3, 1, 255, 101, 2, 53, 46, 8, 5, 1, 255, 101, 2, 53, 242, 
+    230, 19, 196, 8, 3, 1, 255, 101, 2, 53, 242, 230, 19, 196, 8, 5, 1, 255, 
+    101, 2, 248, 41, 46, 8, 3, 1, 255, 101, 2, 248, 41, 46, 8, 5, 1, 255, 99, 
+    2, 53, 48, 8, 3, 1, 255, 99, 2, 53, 48, 8, 5, 1, 255, 99, 2, 53, 46, 8, 
+    3, 1, 255, 99, 2, 53, 46, 8, 5, 1, 255, 99, 2, 242, 241, 19, 53, 48, 8, 
+    3, 1, 255, 99, 2, 242, 241, 19, 53, 48, 8, 5, 1, 255, 99, 2, 243, 86, 19, 
+    53, 48, 8, 3, 1, 255, 99, 2, 243, 86, 19, 53, 48, 8, 5, 1, 255, 99, 2, 
+    53, 242, 230, 19, 53, 48, 8, 3, 1, 255, 99, 2, 53, 242, 230, 19, 53, 48, 
+    8, 5, 1, 255, 102, 2, 53, 48, 8, 3, 1, 255, 102, 2, 53, 48, 8, 5, 1, 255, 
+    102, 2, 53, 46, 8, 3, 1, 255, 102, 2, 53, 46, 8, 5, 1, 255, 102, 2, 248, 
+    41, 46, 8, 3, 1, 255, 102, 2, 248, 41, 46, 8, 5, 1, 255, 102, 2, 190, 46, 
+    8, 3, 1, 255, 102, 2, 190, 46, 8, 5, 1, 132, 2, 235, 56, 46, 8, 3, 1, 
+    132, 2, 235, 56, 46, 8, 5, 1, 132, 2, 242, 219, 46, 8, 3, 1, 132, 2, 242, 
+    219, 46, 8, 5, 1, 132, 2, 190, 46, 8, 3, 1, 132, 2, 190, 46, 8, 5, 1, 
+    132, 2, 242, 219, 19, 135, 8, 3, 1, 132, 2, 242, 219, 19, 135, 8, 5, 1, 
+    132, 2, 240, 42, 19, 175, 8, 3, 1, 132, 2, 240, 42, 19, 175, 8, 5, 1, 
+    255, 110, 2, 169, 8, 3, 1, 255, 110, 2, 169, 8, 5, 1, 255, 110, 2, 53, 
+    46, 8, 3, 1, 255, 110, 2, 53, 46, 8, 5, 1, 255, 111, 2, 191, 8, 3, 1, 
+    255, 111, 2, 191, 8, 5, 1, 255, 111, 2, 135, 8, 3, 1, 255, 111, 2, 135, 
+    8, 5, 1, 255, 111, 2, 175, 8, 3, 1, 255, 111, 2, 175, 8, 5, 1, 255, 111, 
+    2, 53, 48, 8, 3, 1, 255, 111, 2, 53, 48, 8, 5, 1, 255, 111, 2, 53, 46, 8, 
+    3, 1, 255, 111, 2, 53, 46, 8, 5, 1, 255, 113, 2, 53, 48, 8, 3, 1, 255, 
+    113, 2, 53, 48, 8, 5, 1, 255, 113, 2, 175, 8, 3, 1, 255, 113, 2, 175, 8, 
+    5, 1, 255, 107, 2, 53, 48, 8, 3, 1, 255, 107, 2, 53, 48, 8, 5, 1, 255, 
+    97, 2, 233, 48, 8, 3, 1, 255, 97, 2, 233, 48, 8, 5, 1, 255, 97, 2, 53, 
+    46, 8, 3, 1, 255, 97, 2, 53, 46, 8, 5, 1, 255, 97, 2, 248, 41, 46, 8, 3, 
+    1, 255, 97, 2, 248, 41, 46, 8, 3, 1, 255, 106, 2, 248, 41, 46, 8, 3, 1, 
+    255, 102, 2, 175, 8, 3, 1, 255, 111, 2, 248, 51, 48, 8, 3, 1, 255, 107, 
+    2, 248, 51, 48, 8, 3, 1, 134, 2, 38, 137, 242, 233, 8, 3, 1, 183, 255, 
+    99, 2, 53, 48, 8, 5, 1, 134, 2, 53, 46, 8, 3, 1, 134, 2, 53, 46, 8, 5, 1, 
+    134, 2, 248, 45, 48, 8, 3, 1, 134, 2, 248, 45, 48, 8, 5, 1, 134, 2, 190, 
+    19, 135, 8, 3, 1, 134, 2, 190, 19, 135, 8, 5, 1, 134, 2, 190, 19, 191, 8, 
+    3, 1, 134, 2, 190, 19, 191, 8, 5, 1, 134, 2, 190, 19, 248, 45, 48, 8, 3, 
+    1, 134, 2, 190, 19, 248, 45, 48, 8, 5, 1, 134, 2, 190, 19, 169, 8, 3, 1, 
+    134, 2, 190, 19, 169, 8, 5, 1, 134, 2, 190, 19, 53, 46, 8, 3, 1, 134, 2, 
+    190, 19, 53, 46, 8, 5, 1, 134, 2, 242, 243, 19, 135, 8, 3, 1, 134, 2, 
+    242, 243, 19, 135, 8, 5, 1, 134, 2, 242, 243, 19, 191, 8, 3, 1, 134, 2, 
+    242, 243, 19, 191, 8, 5, 1, 134, 2, 242, 243, 19, 248, 45, 48, 8, 3, 1, 
+    134, 2, 242, 243, 19, 248, 45, 48, 8, 5, 1, 134, 2, 242, 243, 19, 169, 8, 
+    3, 1, 134, 2, 242, 243, 19, 169, 8, 5, 1, 134, 2, 242, 243, 19, 53, 46, 
+    8, 3, 1, 134, 2, 242, 243, 19, 53, 46, 8, 5, 1, 157, 2, 53, 46, 8, 3, 1, 
+    157, 2, 53, 46, 8, 5, 1, 157, 2, 248, 45, 48, 8, 3, 1, 157, 2, 248, 45, 
+    48, 8, 5, 1, 157, 2, 169, 8, 3, 1, 157, 2, 169, 8, 5, 1, 157, 2, 190, 19, 
+    135, 8, 3, 1, 157, 2, 190, 19, 135, 8, 5, 1, 157, 2, 190, 19, 191, 8, 3, 
+    1, 157, 2, 190, 19, 191, 8, 5, 1, 157, 2, 190, 19, 248, 45, 48, 8, 3, 1, 
+    157, 2, 190, 19, 248, 45, 48, 8, 5, 1, 157, 2, 190, 19, 169, 8, 3, 1, 
+    157, 2, 190, 19, 169, 8, 5, 1, 157, 2, 190, 19, 53, 46, 8, 3, 1, 157, 2, 
+    190, 19, 53, 46, 8, 5, 1, 220, 2, 248, 45, 48, 8, 3, 1, 220, 2, 248, 45, 
+    48, 8, 5, 1, 220, 2, 53, 46, 8, 3, 1, 220, 2, 53, 46, 8, 5, 1, 117, 2, 
+    53, 46, 8, 3, 1, 117, 2, 53, 46, 8, 5, 1, 117, 2, 248, 45, 48, 8, 3, 1, 
+    117, 2, 248, 45, 48, 8, 5, 1, 117, 2, 190, 19, 135, 8, 3, 1, 117, 2, 190, 
+    19, 135, 8, 5, 1, 117, 2, 190, 19, 191, 8, 3, 1, 117, 2, 190, 19, 191, 8, 
+    5, 1, 117, 2, 190, 19, 248, 45, 48, 8, 3, 1, 117, 2, 190, 19, 248, 45, 
+    48, 8, 5, 1, 117, 2, 190, 19, 169, 8, 3, 1, 117, 2, 190, 19, 169, 8, 5, 
+    1, 117, 2, 190, 19, 53, 46, 8, 3, 1, 117, 2, 190, 19, 53, 46, 8, 5, 1, 
+    117, 2, 248, 60, 19, 135, 8, 3, 1, 117, 2, 248, 60, 19, 135, 8, 5, 1, 
+    117, 2, 248, 60, 19, 191, 8, 3, 1, 117, 2, 248, 60, 19, 191, 8, 5, 1, 
+    117, 2, 248, 60, 19, 248, 45, 48, 8, 3, 1, 117, 2, 248, 60, 19, 248, 45, 
+    48, 8, 5, 1, 117, 2, 248, 60, 19, 169, 8, 3, 1, 117, 2, 248, 60, 19, 169, 
+    8, 5, 1, 117, 2, 248, 60, 19, 53, 46, 8, 3, 1, 117, 2, 248, 60, 19, 53, 
+    46, 8, 5, 1, 132, 2, 53, 46, 8, 3, 1, 132, 2, 53, 46, 8, 5, 1, 132, 2, 
+    248, 45, 48, 8, 3, 1, 132, 2, 248, 45, 48, 8, 5, 1, 132, 2, 248, 60, 19, 
+    135, 8, 3, 1, 132, 2, 248, 60, 19, 135, 8, 5, 1, 132, 2, 248, 60, 19, 
+    191, 8, 3, 1, 132, 2, 248, 60, 19, 191, 8, 5, 1, 132, 2, 248, 60, 19, 
+    248, 45, 48, 8, 3, 1, 132, 2, 248, 60, 19, 248, 45, 48, 8, 5, 1, 132, 2, 
+    248, 60, 19, 169, 8, 3, 1, 132, 2, 248, 60, 19, 169, 8, 5, 1, 132, 2, 
+    248, 60, 19, 53, 46, 8, 3, 1, 132, 2, 248, 60, 19, 53, 46, 8, 5, 1, 255, 
+    107, 2, 191, 8, 3, 1, 255, 107, 2, 191, 8, 5, 1, 255, 107, 2, 53, 46, 8, 
+    3, 1, 255, 107, 2, 53, 46, 8, 5, 1, 255, 107, 2, 248, 45, 48, 8, 3, 1, 
+    255, 107, 2, 248, 45, 48, 8, 5, 1, 255, 107, 2, 169, 8, 3, 1, 255, 107, 
+    2, 169, 17, 3, 1, 194, 2, 240, 29, 17, 3, 1, 194, 2, 240, 25, 17, 3, 1, 
+    194, 2, 159, 19, 215, 17, 3, 1, 194, 2, 148, 19, 215, 17, 3, 1, 194, 2, 
+    159, 19, 212, 17, 3, 1, 194, 2, 148, 19, 212, 17, 3, 1, 194, 2, 159, 19, 
+    232, 71, 17, 3, 1, 194, 2, 148, 19, 232, 71, 17, 5, 1, 194, 2, 240, 29, 
+    17, 5, 1, 194, 2, 240, 25, 17, 5, 1, 194, 2, 159, 19, 215, 17, 5, 1, 194, 
+    2, 148, 19, 215, 17, 5, 1, 194, 2, 159, 19, 212, 17, 5, 1, 194, 2, 148, 
+    19, 212, 17, 5, 1, 194, 2, 159, 19, 232, 71, 17, 5, 1, 194, 2, 148, 19, 
+    232, 71, 17, 3, 1, 238, 57, 2, 240, 29, 17, 3, 1, 238, 57, 2, 240, 25, 
+    17, 3, 1, 238, 57, 2, 159, 19, 215, 17, 3, 1, 238, 57, 2, 148, 19, 215, 
+    17, 3, 1, 238, 57, 2, 159, 19, 212, 17, 3, 1, 238, 57, 2, 148, 19, 212, 
+    17, 5, 1, 238, 57, 2, 240, 29, 17, 5, 1, 238, 57, 2, 240, 25, 17, 5, 1, 
+    238, 57, 2, 159, 19, 215, 17, 5, 1, 238, 57, 2, 148, 19, 215, 17, 5, 1, 
+    238, 57, 2, 159, 19, 212, 17, 5, 1, 238, 57, 2, 148, 19, 212, 17, 3, 1, 
+    253, 123, 2, 240, 29, 17, 3, 1, 253, 123, 2, 240, 25, 17, 3, 1, 253, 123, 
+    2, 159, 19, 215, 17, 3, 1, 253, 123, 2, 148, 19, 215, 17, 3, 1, 253, 123, 
+    2, 159, 19, 212, 17, 3, 1, 253, 123, 2, 148, 19, 212, 17, 3, 1, 253, 123, 
+    2, 159, 19, 232, 71, 17, 3, 1, 253, 123, 2, 148, 19, 232, 71, 17, 5, 1, 
+    253, 123, 2, 240, 29, 17, 5, 1, 253, 123, 2, 240, 25, 17, 5, 1, 253, 123, 
+    2, 159, 19, 215, 17, 5, 1, 253, 123, 2, 148, 19, 215, 17, 5, 1, 253, 123, 
+    2, 159, 19, 212, 17, 5, 1, 253, 123, 2, 148, 19, 212, 17, 5, 1, 253, 123, 
+    2, 159, 19, 232, 71, 17, 5, 1, 253, 123, 2, 148, 19, 232, 71, 17, 3, 1, 
+    248, 42, 2, 240, 29, 17, 3, 1, 248, 42, 2, 240, 25, 17, 3, 1, 248, 42, 2, 
+    159, 19, 215, 17, 3, 1, 248, 42, 2, 148, 19, 215, 17, 3, 1, 248, 42, 2, 
+    159, 19, 212, 17, 3, 1, 248, 42, 2, 148, 19, 212, 17, 3, 1, 248, 42, 2, 
+    159, 19, 232, 71, 17, 3, 1, 248, 42, 2, 148, 19, 232, 71, 17, 5, 1, 248, 
+    42, 2, 240, 29, 17, 5, 1, 248, 42, 2, 240, 25, 17, 5, 1, 248, 42, 2, 159, 
+    19, 215, 17, 5, 1, 248, 42, 2, 148, 19, 215, 17, 5, 1, 248, 42, 2, 159, 
+    19, 212, 17, 5, 1, 248, 42, 2, 148, 19, 212, 17, 5, 1, 248, 42, 2, 159, 
+    19, 232, 71, 17, 5, 1, 248, 42, 2, 148, 19, 232, 71, 17, 3, 1, 238, 64, 
+    2, 240, 29, 17, 3, 1, 238, 64, 2, 240, 25, 17, 3, 1, 238, 64, 2, 159, 19, 
+    215, 17, 3, 1, 238, 64, 2, 148, 19, 215, 17, 3, 1, 238, 64, 2, 159, 19, 
+    212, 17, 3, 1, 238, 64, 2, 148, 19, 212, 17, 5, 1, 238, 64, 2, 240, 29, 
+    17, 5, 1, 238, 64, 2, 240, 25, 17, 5, 1, 238, 64, 2, 159, 19, 215, 17, 5, 
+    1, 238, 64, 2, 148, 19, 215, 17, 5, 1, 238, 64, 2, 159, 19, 212, 17, 5, 
+    1, 238, 64, 2, 148, 19, 212, 17, 3, 1, 238, 53, 2, 240, 29, 17, 3, 1, 
+    238, 53, 2, 240, 25, 17, 3, 1, 238, 53, 2, 159, 19, 215, 17, 3, 1, 238, 
+    53, 2, 148, 19, 215, 17, 3, 1, 238, 53, 2, 159, 19, 212, 17, 3, 1, 238, 
+    53, 2, 148, 19, 212, 17, 3, 1, 238, 53, 2, 159, 19, 232, 71, 17, 3, 1, 
+    238, 53, 2, 148, 19, 232, 71, 17, 5, 1, 238, 53, 2, 240, 25, 17, 5, 1, 
+    238, 53, 2, 148, 19, 215, 17, 5, 1, 238, 53, 2, 148, 19, 212, 17, 5, 1, 
+    238, 53, 2, 148, 19, 232, 71, 17, 3, 1, 211, 2, 240, 29, 17, 3, 1, 211, 
+    2, 240, 25, 17, 3, 1, 211, 2, 159, 19, 215, 17, 3, 1, 211, 2, 148, 19, 
+    215, 17, 3, 1, 211, 2, 159, 19, 212, 17, 3, 1, 211, 2, 148, 19, 212, 17, 
+    3, 1, 211, 2, 159, 19, 232, 71, 17, 3, 1, 211, 2, 148, 19, 232, 71, 17, 
+    5, 1, 211, 2, 240, 29, 17, 5, 1, 211, 2, 240, 25, 17, 5, 1, 211, 2, 159, 
+    19, 215, 17, 5, 1, 211, 2, 148, 19, 215, 17, 5, 1, 211, 2, 159, 19, 212, 
+    17, 5, 1, 211, 2, 148, 19, 212, 17, 5, 1, 211, 2, 159, 19, 232, 71, 17, 
+    5, 1, 211, 2, 148, 19, 232, 71, 17, 3, 1, 194, 2, 215, 17, 3, 1, 194, 2, 
+    212, 17, 3, 1, 238, 57, 2, 215, 17, 3, 1, 238, 57, 2, 212, 17, 3, 1, 253, 
+    123, 2, 215, 17, 3, 1, 253, 123, 2, 212, 17, 3, 1, 248, 42, 2, 215, 17, 
+    3, 1, 248, 42, 2, 212, 17, 3, 1, 238, 64, 2, 215, 17, 3, 1, 238, 64, 2, 
+    212, 17, 3, 1, 238, 53, 2, 215, 17, 3, 1, 238, 53, 2, 212, 17, 3, 1, 211, 
+    2, 215, 17, 3, 1, 211, 2, 212, 17, 3, 1, 194, 2, 159, 19, 231, 35, 17, 3, 
+    1, 194, 2, 148, 19, 231, 35, 17, 3, 1, 194, 2, 159, 19, 242, 248, 19, 
+    231, 35, 17, 3, 1, 194, 2, 148, 19, 242, 248, 19, 231, 35, 17, 3, 1, 194, 
+    2, 159, 19, 248, 79, 19, 231, 35, 17, 3, 1, 194, 2, 148, 19, 248, 79, 19, 
+    231, 35, 17, 3, 1, 194, 2, 159, 19, 233, 53, 19, 231, 35, 17, 3, 1, 194, 
+    2, 148, 19, 233, 53, 19, 231, 35, 17, 5, 1, 194, 2, 159, 19, 229, 57, 17, 
+    5, 1, 194, 2, 148, 19, 229, 57, 17, 5, 1, 194, 2, 159, 19, 242, 248, 19, 
+    229, 57, 17, 5, 1, 194, 2, 148, 19, 242, 248, 19, 229, 57, 17, 5, 1, 194, 
+    2, 159, 19, 248, 79, 19, 229, 57, 17, 5, 1, 194, 2, 148, 19, 248, 79, 19, 
+    229, 57, 17, 5, 1, 194, 2, 159, 19, 233, 53, 19, 229, 57, 17, 5, 1, 194, 
+    2, 148, 19, 233, 53, 19, 229, 57, 17, 3, 1, 253, 123, 2, 159, 19, 231, 
+    35, 17, 3, 1, 253, 123, 2, 148, 19, 231, 35, 17, 3, 1, 253, 123, 2, 159, 
+    19, 242, 248, 19, 231, 35, 17, 3, 1, 253, 123, 2, 148, 19, 242, 248, 19, 
+    231, 35, 17, 3, 1, 253, 123, 2, 159, 19, 248, 79, 19, 231, 35, 17, 3, 1, 
+    253, 123, 2, 148, 19, 248, 79, 19, 231, 35, 17, 3, 1, 253, 123, 2, 159, 
+    19, 233, 53, 19, 231, 35, 17, 3, 1, 253, 123, 2, 148, 19, 233, 53, 19, 
+    231, 35, 17, 5, 1, 253, 123, 2, 159, 19, 229, 57, 17, 5, 1, 253, 123, 2, 
+    148, 19, 229, 57, 17, 5, 1, 253, 123, 2, 159, 19, 242, 248, 19, 229, 57, 
+    17, 5, 1, 253, 123, 2, 148, 19, 242, 248, 19, 229, 57, 17, 5, 1, 253, 
+    123, 2, 159, 19, 248, 79, 19, 229, 57, 17, 5, 1, 253, 123, 2, 148, 19, 
+    248, 79, 19, 229, 57, 17, 5, 1, 253, 123, 2, 159, 19, 233, 53, 19, 229, 
+    57, 17, 5, 1, 253, 123, 2, 148, 19, 233, 53, 19, 229, 57, 17, 3, 1, 211, 
+    2, 159, 19, 231, 35, 17, 3, 1, 211, 2, 148, 19, 231, 35, 17, 3, 1, 211, 
+    2, 159, 19, 242, 248, 19, 231, 35, 17, 3, 1, 211, 2, 148, 19, 242, 248, 
+    19, 231, 35, 17, 3, 1, 211, 2, 159, 19, 248, 79, 19, 231, 35, 17, 3, 1, 
+    211, 2, 148, 19, 248, 79, 19, 231, 35, 17, 3, 1, 211, 2, 159, 19, 233, 
+    53, 19, 231, 35, 17, 3, 1, 211, 2, 148, 19, 233, 53, 19, 231, 35, 17, 5, 
+    1, 211, 2, 159, 19, 229, 57, 17, 5, 1, 211, 2, 148, 19, 229, 57, 17, 5, 
+    1, 211, 2, 159, 19, 242, 248, 19, 229, 57, 17, 5, 1, 211, 2, 148, 19, 
+    242, 248, 19, 229, 57, 17, 5, 1, 211, 2, 159, 19, 248, 79, 19, 229, 57, 
+    17, 5, 1, 211, 2, 148, 19, 248, 79, 19, 229, 57, 17, 5, 1, 211, 2, 159, 
+    19, 233, 53, 19, 229, 57, 17, 5, 1, 211, 2, 148, 19, 233, 53, 19, 229, 
+    57, 17, 3, 1, 194, 2, 238, 103, 17, 3, 1, 194, 2, 196, 17, 3, 1, 194, 2, 
+    242, 248, 19, 231, 35, 17, 3, 1, 194, 2, 231, 35, 17, 3, 1, 194, 2, 248, 
+    79, 19, 231, 35, 17, 3, 1, 194, 2, 232, 71, 17, 3, 1, 194, 2, 233, 53, 
+    19, 231, 35, 17, 5, 1, 194, 2, 238, 103, 17, 5, 1, 194, 2, 196, 17, 5, 1, 
+    194, 2, 215, 17, 5, 1, 194, 2, 212, 17, 5, 1, 194, 2, 229, 57, 17, 236, 
+    229, 17, 229, 57, 17, 240, 29, 17, 232, 71, 17, 235, 59, 19, 232, 71, 17, 
+    3, 1, 253, 123, 2, 242, 248, 19, 231, 35, 17, 3, 1, 253, 123, 2, 231, 35, 
+    17, 3, 1, 253, 123, 2, 248, 79, 19, 231, 35, 17, 3, 1, 253, 123, 2, 232, 
+    71, 17, 3, 1, 253, 123, 2, 233, 53, 19, 231, 35, 17, 5, 1, 238, 57, 2, 
+    215, 17, 5, 1, 238, 57, 2, 212, 17, 5, 1, 253, 123, 2, 215, 17, 5, 1, 
+    253, 123, 2, 212, 17, 5, 1, 253, 123, 2, 229, 57, 17, 159, 19, 215, 17, 
+    159, 19, 212, 17, 159, 19, 232, 71, 17, 3, 1, 248, 42, 2, 238, 103, 17, 
+    3, 1, 248, 42, 2, 196, 17, 3, 1, 248, 42, 2, 235, 59, 19, 215, 17, 3, 1, 
+    248, 42, 2, 235, 59, 19, 212, 17, 3, 1, 248, 42, 2, 232, 71, 17, 3, 1, 
+    248, 42, 2, 235, 59, 19, 232, 71, 17, 5, 1, 248, 42, 2, 238, 103, 17, 5, 
+    1, 248, 42, 2, 196, 17, 5, 1, 248, 42, 2, 215, 17, 5, 1, 248, 42, 2, 212, 
+    17, 148, 19, 215, 17, 148, 19, 212, 17, 148, 19, 232, 71, 17, 3, 1, 238, 
+    53, 2, 238, 103, 17, 3, 1, 238, 53, 2, 196, 17, 3, 1, 238, 53, 2, 235, 
+    59, 19, 215, 17, 3, 1, 238, 53, 2, 235, 59, 19, 212, 17, 3, 1, 253, 218, 
+    2, 240, 29, 17, 3, 1, 253, 218, 2, 240, 25, 17, 3, 1, 238, 53, 2, 232, 
+    71, 17, 3, 1, 238, 53, 2, 235, 59, 19, 232, 71, 17, 5, 1, 238, 53, 2, 
+    238, 103, 17, 5, 1, 238, 53, 2, 196, 17, 5, 1, 238, 53, 2, 215, 17, 5, 1, 
+    238, 53, 2, 212, 17, 5, 1, 253, 218, 2, 240, 25, 17, 235, 59, 19, 215, 
+    17, 235, 59, 19, 212, 17, 215, 17, 3, 1, 211, 2, 242, 248, 19, 231, 35, 
+    17, 3, 1, 211, 2, 231, 35, 17, 3, 1, 211, 2, 248, 79, 19, 231, 35, 17, 3, 
+    1, 211, 2, 232, 71, 17, 3, 1, 211, 2, 233, 53, 19, 231, 35, 17, 5, 1, 
+    238, 64, 2, 215, 17, 5, 1, 238, 64, 2, 212, 17, 5, 1, 211, 2, 215, 17, 5, 
+    1, 211, 2, 212, 17, 5, 1, 211, 2, 229, 57, 17, 212, 17, 240, 25, 255, 23, 
+    243, 43, 255, 28, 243, 43, 255, 23, 240, 15, 255, 28, 240, 15, 233, 42, 
+    240, 15, 233, 203, 240, 15, 235, 1, 240, 15, 240, 174, 240, 15, 233, 51, 
+    240, 15, 252, 219, 240, 15, 251, 46, 240, 15, 248, 145, 243, 81, 240, 15, 
+    248, 145, 243, 81, 233, 219, 248, 145, 243, 81, 238, 140, 231, 96, 69, 
+    231, 99, 69, 238, 93, 232, 188, 238, 93, 240, 174, 242, 235, 255, 23, 
+    242, 235, 255, 28, 242, 235, 163, 125, 45, 59, 242, 224, 45, 170, 242, 
+    224, 40, 240, 12, 235, 51, 69, 38, 240, 12, 235, 51, 69, 240, 12, 243, 
+    218, 235, 51, 69, 240, 12, 229, 62, 235, 51, 69, 40, 45, 235, 51, 69, 38, 
+    45, 235, 51, 69, 45, 243, 218, 235, 51, 69, 45, 229, 62, 235, 51, 69, 
+    238, 173, 45, 238, 173, 238, 69, 234, 43, 238, 69, 253, 125, 53, 238, 
+    143, 171, 53, 238, 143, 163, 235, 69, 233, 207, 240, 209, 248, 41, 234, 
+    6, 235, 91, 234, 6, 231, 96, 234, 52, 231, 99, 234, 52, 254, 227, 233, 
+    134, 233, 202, 231, 96, 235, 131, 231, 99, 235, 131, 241, 252, 236, 233, 
+    240, 15, 254, 68, 246, 85, 52, 254, 68, 253, 219, 236, 193, 52, 240, 57, 
+    45, 240, 57, 240, 3, 240, 57, 224, 240, 57, 224, 45, 240, 57, 224, 240, 
+    3, 240, 57, 240, 130, 240, 12, 231, 87, 185, 235, 51, 69, 240, 12, 231, 
+    36, 185, 235, 51, 69, 236, 90, 69, 45, 233, 54, 69, 232, 179, 235, 74, 
+    235, 158, 99, 248, 139, 243, 25, 235, 128, 240, 209, 235, 175, 241, 177, 
+    238, 69, 236, 155, 240, 37, 40, 31, 238, 52, 2, 240, 214, 38, 31, 238, 
+    52, 2, 240, 214, 45, 236, 156, 69, 236, 156, 233, 54, 69, 233, 54, 236, 
+    156, 69, 238, 30, 21, 254, 60, 224, 238, 208, 52, 86, 139, 238, 69, 86, 
+    77, 238, 69, 170, 235, 52, 224, 234, 14, 245, 24, 253, 176, 171, 235, 
+    174, 238, 243, 234, 0, 234, 20, 242, 250, 52, 247, 129, 242, 235, 236, 
+    145, 235, 158, 241, 111, 233, 51, 69, 204, 53, 232, 75, 235, 71, 240, 57, 
+    248, 58, 53, 232, 75, 248, 48, 53, 232, 75, 171, 53, 232, 75, 248, 58, 
+    53, 69, 240, 4, 240, 34, 236, 131, 59, 248, 58, 243, 5, 240, 19, 10, 240, 
+    15, 248, 143, 238, 140, 237, 163, 232, 116, 235, 129, 240, 123, 235, 129, 
+    234, 6, 238, 190, 235, 152, 235, 145, 236, 243, 235, 152, 235, 145, 238, 
+    190, 11, 248, 38, 237, 39, 236, 243, 11, 248, 38, 237, 39, 237, 216, 26, 
+    238, 215, 239, 146, 26, 238, 215, 233, 49, 242, 217, 233, 49, 8, 3, 1, 
+    71, 233, 49, 177, 233, 49, 176, 233, 49, 187, 233, 49, 203, 233, 49, 195, 
+    233, 49, 202, 233, 49, 248, 49, 52, 233, 49, 240, 68, 233, 49, 240, 7, 
+    52, 233, 49, 40, 232, 74, 233, 49, 38, 232, 74, 233, 49, 8, 3, 1, 197, 
+    235, 48, 242, 217, 235, 48, 127, 235, 48, 111, 235, 48, 166, 235, 48, 
+    177, 235, 48, 176, 235, 48, 187, 235, 48, 203, 235, 48, 195, 235, 48, 
+    202, 235, 48, 248, 49, 52, 235, 48, 240, 68, 235, 48, 240, 7, 52, 235, 
+    48, 40, 232, 74, 235, 48, 38, 232, 74, 8, 235, 48, 3, 1, 67, 8, 235, 48, 
+    3, 1, 72, 8, 235, 48, 3, 1, 73, 8, 235, 48, 3, 1, 206, 8, 235, 48, 3, 1, 
+    240, 86, 231, 137, 52, 243, 14, 52, 237, 96, 52, 241, 117, 245, 92, 52, 
+    251, 199, 52, 251, 234, 52, 246, 103, 52, 242, 58, 52, 243, 44, 52, 254, 
+    131, 52, 116, 242, 104, 52, 250, 203, 52, 250, 231, 52, 254, 185, 52, 
+    242, 162, 52, 238, 180, 52, 241, 127, 246, 241, 52, 252, 63, 52, 239, 86, 
+    52, 238, 254, 52, 239, 94, 52, 250, 153, 52, 50, 40, 186, 48, 50, 38, 
+    186, 48, 50, 183, 59, 248, 41, 236, 161, 50, 242, 215, 59, 248, 41, 236, 
+    161, 50, 231, 86, 65, 48, 50, 235, 62, 65, 48, 50, 40, 65, 48, 50, 38, 
+    65, 48, 50, 248, 51, 236, 161, 50, 235, 62, 248, 51, 236, 161, 50, 231, 
+    86, 248, 51, 236, 161, 50, 204, 181, 48, 50, 248, 58, 181, 48, 50, 235, 
+    73, 238, 51, 50, 235, 73, 238, 59, 50, 235, 73, 236, 164, 50, 235, 73, 
+    218, 234, 25, 50, 40, 38, 65, 48, 50, 235, 73, 239, 182, 50, 235, 73, 
+    239, 107, 50, 235, 73, 242, 172, 236, 150, 235, 46, 50, 238, 75, 238, 83, 
+    236, 161, 50, 45, 59, 240, 5, 236, 161, 50, 238, 245, 91, 50, 240, 3, 
+    236, 136, 50, 248, 98, 240, 109, 48, 50, 139, 65, 236, 161, 50, 183, 45, 
+    238, 83, 236, 161, 238, 158, 253, 174, 235, 160, 153, 253, 145, 238, 18, 
+    138, 5, 255, 18, 240, 112, 237, 85, 240, 46, 248, 41, 91, 250, 145, 253, 
+    174, 250, 142, 252, 251, 245, 87, 235, 118, 238, 3, 240, 112, 233, 200, 
+    84, 3, 210, 84, 5, 192, 232, 80, 5, 192, 138, 5, 192, 240, 208, 235, 118, 
+    240, 208, 237, 90, 248, 59, 171, 253, 147, 84, 5, 71, 232, 80, 5, 71, 84, 
+    5, 162, 84, 3, 162, 255, 100, 41, 253, 144, 91, 138, 5, 197, 242, 27, 52, 
+    243, 1, 236, 88, 234, 105, 84, 5, 223, 138, 5, 223, 138, 5, 255, 20, 84, 
+    5, 144, 232, 80, 5, 144, 138, 5, 144, 232, 198, 247, 136, 235, 141, 239, 
+    189, 69, 235, 113, 52, 247, 157, 158, 52, 236, 138, 138, 5, 255, 17, 246, 
+    235, 52, 254, 119, 52, 236, 145, 254, 119, 52, 232, 80, 5, 255, 17, 205, 
+    17, 3, 1, 242, 237, 241, 198, 52, 237, 60, 52, 84, 5, 217, 232, 80, 5, 
+    255, 18, 236, 14, 91, 84, 3, 72, 84, 5, 72, 84, 5, 255, 19, 205, 5, 255, 
+    19, 84, 5, 173, 84, 3, 73, 83, 91, 254, 53, 91, 243, 184, 91, 243, 162, 
+    91, 233, 211, 239, 199, 238, 120, 5, 255, 20, 236, 17, 52, 138, 3, 253, 
+    147, 138, 3, 240, 10, 138, 5, 240, 10, 138, 5, 253, 147, 138, 242, 238, 
+    234, 65, 205, 27, 5, 210, 205, 27, 5, 162, 224, 27, 5, 162, 205, 27, 5, 
+    255, 14, 138, 24, 5, 209, 138, 24, 3, 209, 138, 24, 3, 72, 138, 24, 3, 
+    71, 138, 24, 3, 221, 237, 244, 242, 224, 205, 234, 17, 254, 68, 52, 240, 
+    30, 236, 155, 253, 125, 242, 148, 240, 30, 236, 155, 171, 239, 220, 240, 
+    30, 236, 155, 253, 125, 241, 107, 240, 30, 236, 155, 171, 238, 138, 240, 
+    30, 236, 155, 204, 238, 138, 240, 30, 236, 155, 248, 58, 238, 138, 240, 
+    30, 236, 155, 253, 125, 242, 113, 240, 30, 236, 155, 248, 48, 239, 197, 
+    240, 30, 236, 155, 253, 125, 239, 55, 240, 30, 236, 155, 204, 236, 224, 
+    240, 30, 236, 155, 248, 48, 236, 224, 240, 30, 236, 155, 243, 31, 236, 
+    224, 236, 155, 235, 79, 127, 242, 218, 178, 127, 242, 218, 178, 111, 242, 
+    218, 178, 166, 242, 218, 178, 177, 242, 218, 178, 176, 242, 218, 178, 
+    187, 242, 218, 178, 203, 242, 218, 178, 195, 242, 218, 178, 202, 242, 
+    218, 178, 248, 53, 242, 218, 178, 238, 91, 242, 218, 178, 238, 97, 242, 
+    218, 178, 240, 50, 242, 218, 178, 253, 125, 236, 149, 242, 218, 178, 248, 
+    48, 236, 149, 242, 218, 178, 253, 125, 235, 49, 3, 242, 218, 178, 127, 3, 
+    242, 218, 178, 111, 3, 242, 218, 178, 166, 3, 242, 218, 178, 177, 3, 242, 
+    218, 178, 176, 3, 242, 218, 178, 187, 3, 242, 218, 178, 203, 3, 242, 218, 
+    178, 195, 3, 242, 218, 178, 202, 3, 242, 218, 178, 248, 53, 3, 242, 218, 
+    178, 238, 91, 3, 242, 218, 178, 238, 97, 3, 242, 218, 178, 240, 50, 3, 
+    242, 218, 178, 253, 125, 236, 149, 3, 242, 218, 178, 248, 48, 236, 149, 
+    3, 242, 218, 178, 253, 125, 235, 49, 242, 218, 178, 253, 125, 236, 193, 
+    255, 105, 209, 242, 218, 178, 248, 48, 235, 49, 242, 218, 178, 253, 219, 
+    235, 49, 242, 218, 178, 224, 253, 125, 236, 149, 139, 56, 226, 226, 56, 
+    77, 56, 235, 45, 56, 40, 38, 56, 88, 92, 56, 242, 223, 248, 56, 56, 242, 
+    223, 248, 43, 56, 242, 228, 248, 43, 56, 242, 228, 248, 56, 56, 139, 65, 
+    2, 108, 77, 65, 2, 108, 139, 248, 141, 56, 77, 248, 141, 56, 139, 171, 
+    240, 115, 56, 226, 226, 171, 240, 115, 56, 77, 171, 240, 115, 56, 235, 
+    45, 171, 240, 115, 56, 139, 65, 2, 242, 226, 77, 65, 2, 242, 226, 139, 
+    65, 248, 44, 125, 226, 226, 65, 248, 44, 125, 77, 65, 248, 44, 125, 235, 
+    45, 65, 248, 44, 125, 88, 92, 65, 2, 244, 192, 139, 65, 2, 90, 77, 65, 2, 
+    90, 139, 65, 2, 243, 105, 77, 65, 2, 243, 105, 40, 38, 248, 141, 56, 40, 
+    38, 65, 2, 108, 235, 45, 240, 126, 56, 226, 226, 65, 2, 253, 241, 234, 
+    18, 226, 226, 65, 2, 253, 241, 233, 63, 235, 45, 65, 2, 253, 241, 234, 
+    18, 235, 45, 65, 2, 253, 241, 233, 63, 77, 65, 2, 240, 31, 234, 9, 235, 
+    45, 65, 2, 240, 31, 234, 18, 231, 86, 253, 159, 234, 64, 56, 235, 62, 
+    253, 159, 234, 64, 56, 242, 223, 248, 56, 65, 153, 183, 125, 139, 65, 
+    153, 253, 144, 248, 59, 77, 65, 153, 125, 231, 86, 248, 35, 218, 56, 235, 
+    62, 248, 35, 218, 56, 139, 186, 2, 154, 236, 206, 139, 186, 2, 154, 234, 
+    9, 226, 226, 186, 2, 154, 233, 63, 226, 226, 186, 2, 154, 234, 18, 77, 
+    186, 2, 154, 236, 206, 77, 186, 2, 154, 234, 9, 235, 45, 186, 2, 154, 
+    233, 63, 235, 45, 186, 2, 154, 234, 18, 77, 65, 248, 59, 139, 56, 226, 
+    226, 65, 139, 147, 235, 45, 56, 139, 65, 248, 59, 77, 56, 139, 240, 117, 
+    238, 104, 226, 226, 240, 117, 238, 104, 77, 240, 117, 238, 104, 235, 45, 
+    240, 117, 238, 104, 139, 186, 248, 59, 77, 236, 175, 77, 186, 248, 59, 
+    139, 236, 175, 139, 45, 65, 2, 108, 40, 38, 45, 65, 2, 108, 77, 45, 65, 
+    2, 108, 139, 45, 56, 226, 226, 45, 56, 77, 45, 56, 235, 45, 45, 56, 40, 
+    38, 45, 56, 88, 92, 45, 56, 242, 223, 248, 56, 45, 56, 242, 223, 248, 43, 
+    45, 56, 242, 228, 248, 43, 45, 56, 242, 228, 248, 56, 45, 56, 139, 240, 
+    3, 56, 77, 240, 3, 56, 139, 236, 240, 56, 77, 236, 240, 56, 226, 226, 65, 
+    2, 45, 108, 235, 45, 65, 2, 45, 108, 139, 240, 55, 56, 226, 226, 240, 55, 
+    56, 77, 240, 55, 56, 235, 45, 240, 55, 56, 139, 65, 153, 125, 77, 65, 
+    153, 125, 139, 64, 56, 226, 226, 64, 56, 77, 64, 56, 235, 45, 64, 56, 
+    226, 226, 64, 65, 248, 44, 125, 226, 226, 64, 65, 255, 34, 235, 133, 226, 
+    226, 64, 65, 255, 34, 237, 28, 2, 163, 125, 226, 226, 64, 65, 255, 34, 
+    237, 28, 2, 59, 125, 226, 226, 64, 45, 56, 226, 226, 64, 45, 65, 255, 34, 
+    235, 133, 77, 64, 65, 248, 44, 247, 192, 242, 223, 248, 56, 65, 153, 238, 
+    67, 242, 228, 248, 43, 65, 153, 238, 67, 88, 92, 64, 56, 38, 65, 2, 3, 
+    238, 51, 235, 45, 65, 139, 147, 226, 226, 56, 204, 77, 238, 104, 139, 65, 
+    2, 59, 108, 77, 65, 2, 59, 108, 40, 38, 65, 2, 59, 108, 139, 65, 2, 45, 
+    59, 108, 77, 65, 2, 45, 59, 108, 40, 38, 65, 2, 45, 59, 108, 139, 233, 
+    72, 56, 77, 233, 72, 56, 40, 38, 233, 72, 56, 28, 249, 26, 233, 124, 238, 
+    100, 231, 90, 244, 29, 239, 58, 244, 29, 248, 86, 161, 241, 100, 243, 15, 
+    249, 160, 234, 205, 240, 79, 238, 68, 253, 174, 161, 255, 68, 238, 68, 
+    253, 174, 3, 238, 68, 253, 174, 236, 180, 255, 24, 238, 145, 248, 86, 
+    161, 238, 131, 255, 24, 238, 145, 3, 236, 180, 255, 24, 238, 145, 253, 
+    165, 147, 242, 66, 242, 238, 236, 170, 242, 238, 234, 50, 242, 238, 234, 
+    65, 242, 250, 52, 231, 148, 52, 53, 243, 12, 236, 196, 240, 37, 254, 30, 
+    240, 68, 236, 219, 235, 47, 248, 51, 235, 47, 241, 41, 235, 47, 31, 243, 
+    119, 250, 169, 243, 119, 240, 137, 243, 119, 232, 199, 87, 235, 101, 38, 
+    240, 54, 240, 54, 236, 168, 240, 54, 235, 109, 240, 54, 237, 112, 248, 
+    86, 161, 238, 177, 236, 200, 87, 161, 236, 200, 87, 238, 56, 248, 91, 
+    238, 56, 253, 227, 231, 88, 240, 58, 235, 60, 45, 235, 60, 240, 3, 235, 
+    60, 238, 132, 235, 60, 239, 210, 235, 60, 242, 180, 235, 60, 235, 62, 
+    235, 60, 235, 62, 238, 132, 235, 60, 231, 86, 238, 132, 235, 60, 235, 33, 
+    237, 74, 242, 78, 233, 96, 53, 240, 68, 239, 57, 236, 31, 233, 96, 233, 
+    206, 242, 219, 235, 47, 224, 169, 236, 145, 251, 187, 193, 252, 178, 243, 
+    80, 242, 186, 236, 170, 161, 169, 242, 250, 169, 231, 45, 95, 87, 161, 
+    231, 45, 95, 87, 231, 89, 95, 87, 231, 89, 253, 230, 161, 236, 244, 95, 
+    87, 238, 79, 231, 89, 253, 192, 236, 244, 95, 87, 240, 40, 95, 87, 161, 
+    240, 40, 95, 87, 240, 40, 95, 128, 95, 87, 240, 3, 169, 254, 51, 95, 87, 
+    234, 5, 87, 231, 105, 234, 5, 87, 234, 111, 236, 248, 234, 92, 253, 145, 
+    241, 216, 231, 105, 95, 87, 231, 89, 95, 153, 128, 253, 145, 243, 11, 
+    253, 174, 243, 11, 147, 128, 231, 89, 95, 87, 243, 14, 238, 113, 240, 7, 
+    240, 24, 248, 51, 255, 22, 95, 87, 248, 51, 95, 87, 233, 128, 87, 234, 
+    187, 233, 198, 87, 248, 135, 238, 113, 243, 92, 95, 87, 95, 153, 255, 25, 
+    233, 130, 236, 168, 254, 82, 234, 243, 95, 87, 161, 95, 87, 235, 89, 87, 
+    161, 235, 89, 87, 238, 17, 234, 5, 87, 235, 44, 128, 95, 87, 232, 68, 
+    128, 95, 87, 235, 44, 248, 59, 95, 87, 232, 68, 248, 59, 95, 87, 235, 44, 
+    253, 230, 161, 95, 87, 232, 68, 253, 230, 161, 95, 87, 248, 168, 234, 3, 
+    248, 168, 231, 85, 236, 248, 161, 234, 5, 87, 161, 234, 3, 161, 231, 85, 
+    238, 79, 235, 44, 253, 192, 95, 87, 238, 79, 232, 68, 253, 192, 95, 87, 
+    235, 44, 128, 234, 5, 87, 232, 68, 128, 234, 5, 87, 238, 79, 235, 44, 
+    253, 192, 234, 5, 87, 238, 79, 232, 68, 253, 192, 234, 5, 87, 235, 44, 
+    128, 231, 85, 232, 68, 128, 234, 3, 238, 79, 235, 44, 253, 192, 231, 85, 
+    238, 79, 232, 68, 253, 192, 234, 3, 235, 107, 235, 111, 236, 176, 128, 
+    95, 87, 236, 178, 128, 95, 87, 236, 176, 128, 234, 5, 87, 236, 178, 128, 
+    234, 5, 87, 248, 86, 161, 237, 240, 248, 86, 161, 238, 19, 240, 26, 253, 
+    174, 236, 154, 253, 174, 161, 134, 240, 26, 253, 174, 161, 134, 236, 154, 
+    253, 174, 240, 26, 147, 128, 95, 87, 236, 154, 147, 128, 95, 87, 238, 79, 
+    134, 240, 26, 147, 253, 192, 95, 87, 238, 79, 134, 236, 154, 147, 253, 
+    192, 95, 87, 240, 26, 147, 2, 161, 95, 87, 236, 154, 147, 2, 161, 95, 87, 
+    236, 62, 237, 24, 231, 26, 237, 24, 240, 58, 31, 243, 11, 253, 174, 31, 
+    236, 209, 253, 174, 31, 243, 11, 147, 128, 95, 87, 31, 236, 209, 147, 
+    128, 95, 87, 31, 249, 38, 31, 249, 43, 29, 243, 12, 29, 240, 68, 29, 240, 
+    123, 29, 236, 196, 240, 37, 29, 53, 235, 47, 29, 248, 51, 235, 47, 29, 
+    236, 219, 235, 47, 29, 238, 113, 29, 242, 235, 238, 84, 243, 12, 238, 84, 
+    240, 68, 238, 84, 240, 123, 238, 84, 53, 235, 47, 38, 242, 234, 40, 242, 
+    234, 92, 242, 234, 88, 242, 234, 234, 94, 239, 139, 244, 38, 239, 78, 
+    240, 3, 59, 253, 144, 38, 234, 15, 45, 59, 253, 144, 45, 38, 234, 15, 
+    248, 86, 161, 242, 67, 161, 244, 38, 248, 86, 161, 241, 114, 238, 203, 
+    45, 59, 253, 144, 45, 38, 234, 15, 236, 176, 244, 44, 235, 92, 236, 178, 
+    244, 44, 235, 92, 240, 52, 236, 203, 253, 174, 236, 180, 255, 24, 240, 
+    52, 235, 144, 240, 52, 236, 203, 147, 128, 95, 87, 236, 180, 255, 24, 
+    240, 52, 236, 203, 128, 95, 87, 236, 209, 253, 174, 243, 11, 253, 174, 
+    235, 103, 236, 35, 235, 193, 239, 130, 232, 178, 253, 49, 246, 104, 252, 
+    34, 38, 185, 2, 248, 113, 38, 235, 46, 242, 238, 238, 56, 248, 91, 242, 
+    238, 238, 56, 253, 227, 242, 238, 231, 88, 242, 238, 240, 58, 238, 76, 
+    235, 47, 53, 235, 47, 248, 135, 235, 47, 236, 196, 240, 123, 238, 168, 
+    40, 240, 52, 240, 173, 234, 21, 236, 170, 38, 240, 52, 240, 173, 234, 21, 
+    236, 170, 40, 234, 21, 236, 170, 38, 234, 21, 236, 170, 224, 242, 219, 
+    238, 113, 242, 225, 238, 56, 253, 227, 242, 225, 238, 56, 248, 91, 45, 
+    238, 87, 45, 235, 84, 45, 231, 88, 45, 240, 58, 234, 234, 95, 19, 236, 
+    200, 87, 235, 44, 2, 248, 40, 232, 68, 2, 248, 40, 249, 194, 248, 168, 
+    234, 3, 249, 194, 248, 168, 231, 85, 235, 44, 95, 153, 128, 231, 85, 232, 
+    68, 95, 153, 128, 234, 3, 95, 153, 128, 234, 3, 95, 153, 128, 231, 85, 
+    95, 153, 128, 235, 107, 95, 153, 128, 235, 111, 248, 86, 161, 239, 165, 
+    128, 240, 32, 248, 86, 161, 239, 209, 128, 240, 32, 161, 31, 243, 11, 
+    147, 128, 95, 87, 161, 31, 236, 209, 147, 128, 95, 87, 31, 243, 11, 147, 
+    128, 161, 95, 87, 31, 236, 209, 147, 128, 161, 95, 87, 235, 44, 253, 230, 
+    161, 234, 5, 87, 232, 68, 253, 230, 161, 234, 5, 87, 236, 176, 253, 230, 
+    161, 234, 5, 87, 236, 178, 253, 230, 161, 234, 5, 87, 161, 240, 52, 236, 
+    203, 253, 174, 248, 86, 161, 238, 131, 255, 24, 240, 52, 235, 144, 161, 
+    240, 52, 236, 203, 147, 128, 95, 87, 248, 86, 161, 238, 131, 255, 24, 
+    240, 52, 236, 203, 128, 240, 32, 59, 235, 69, 239, 136, 163, 235, 69, 88, 
+    38, 236, 159, 235, 69, 92, 38, 236, 159, 235, 69, 238, 68, 147, 2, 183, 
+    163, 108, 238, 68, 147, 2, 59, 253, 144, 255, 31, 253, 165, 147, 163, 
+    108, 3, 238, 68, 147, 2, 59, 253, 144, 255, 31, 253, 165, 147, 163, 108, 
+    238, 68, 147, 2, 53, 48, 238, 68, 147, 2, 236, 163, 3, 238, 68, 147, 2, 
+    236, 163, 238, 68, 147, 2, 235, 50, 238, 68, 147, 2, 171, 163, 237, 45, 
+    236, 180, 2, 183, 163, 108, 236, 180, 2, 59, 253, 144, 255, 31, 253, 165, 
+    147, 163, 108, 3, 236, 180, 2, 59, 253, 144, 255, 31, 253, 165, 147, 163, 
+    108, 236, 180, 2, 236, 163, 3, 236, 180, 2, 236, 163, 255, 97, 126, 254, 
+    52, 233, 217, 237, 105, 52, 237, 149, 56, 241, 168, 88, 234, 7, 92, 234, 
+    7, 233, 226, 232, 193, 248, 103, 242, 224, 40, 236, 251, 38, 236, 251, 
+    40, 240, 175, 38, 240, 175, 240, 17, 38, 243, 55, 240, 17, 40, 243, 55, 
+    253, 159, 38, 243, 55, 253, 159, 40, 243, 55, 224, 161, 52, 31, 236, 231, 
+    248, 113, 238, 4, 239, 187, 235, 113, 236, 87, 237, 239, 234, 30, 238, 
+    42, 238, 59, 243, 245, 147, 237, 181, 52, 205, 161, 52, 240, 252, 234, 
+    39, 253, 159, 40, 238, 67, 253, 159, 38, 238, 67, 240, 17, 40, 238, 67, 
+    240, 17, 38, 238, 67, 253, 159, 137, 235, 60, 240, 17, 137, 235, 60, 241, 
+    118, 242, 118, 88, 235, 76, 239, 7, 171, 163, 244, 191, 242, 42, 251, 
+    145, 243, 169, 153, 253, 145, 225, 255, 113, 255, 22, 134, 236, 89, 248, 
+    92, 236, 45, 231, 87, 185, 104, 231, 36, 185, 104, 243, 169, 153, 253, 
+    145, 242, 220, 239, 6, 242, 233, 231, 121, 254, 51, 229, 64, 236, 125, 
+    247, 156, 239, 175, 235, 205, 239, 154, 239, 31, 242, 141, 242, 116, 232, 
+    124, 232, 125, 141, 142, 12, 239, 96, 141, 142, 12, 242, 127, 243, 43, 
+    141, 142, 12, 248, 62, 240, 32, 141, 142, 12, 248, 62, 238, 177, 141, 
+    142, 12, 248, 62, 236, 164, 141, 142, 12, 248, 62, 248, 115, 141, 142, 
+    12, 248, 62, 238, 51, 141, 142, 12, 218, 240, 103, 141, 142, 12, 218, 
+    248, 115, 141, 142, 12, 247, 94, 125, 141, 142, 12, 235, 177, 125, 141, 
+    142, 12, 248, 62, 240, 37, 141, 142, 12, 248, 62, 234, 25, 141, 142, 12, 
+    248, 62, 234, 3, 141, 142, 12, 248, 62, 231, 85, 141, 142, 12, 139, 243, 
+    79, 141, 142, 12, 77, 243, 79, 141, 142, 12, 248, 62, 139, 56, 141, 142, 
+    12, 248, 62, 77, 56, 141, 142, 12, 218, 234, 25, 141, 142, 12, 92, 248, 
+    84, 235, 50, 141, 142, 12, 243, 92, 240, 103, 141, 142, 12, 248, 62, 92, 
+    240, 130, 141, 142, 12, 248, 62, 240, 28, 141, 142, 12, 92, 248, 84, 248, 
+    115, 141, 142, 12, 226, 226, 243, 79, 141, 142, 12, 248, 62, 226, 226, 
+    56, 141, 142, 12, 88, 248, 84, 236, 163, 141, 142, 12, 254, 56, 240, 103, 
+    141, 142, 12, 248, 62, 88, 240, 130, 141, 142, 12, 248, 62, 250, 189, 
+    141, 142, 12, 88, 248, 84, 248, 115, 141, 142, 12, 235, 45, 243, 79, 141, 
+    142, 12, 248, 62, 235, 45, 56, 141, 142, 12, 243, 249, 235, 50, 141, 142, 
+    12, 243, 92, 235, 50, 141, 142, 12, 238, 76, 235, 50, 141, 142, 12, 254, 
+    104, 235, 50, 141, 142, 12, 218, 235, 50, 141, 142, 12, 88, 248, 247, 
+    248, 115, 141, 142, 12, 243, 249, 243, 43, 141, 142, 12, 218, 242, 229, 
+    141, 142, 12, 248, 62, 240, 24, 141, 142, 12, 88, 248, 84, 175, 141, 142, 
+    12, 254, 56, 175, 141, 142, 12, 248, 135, 175, 141, 142, 12, 254, 104, 
+    175, 141, 142, 12, 218, 175, 141, 142, 12, 92, 248, 247, 240, 103, 141, 
+    142, 12, 40, 248, 247, 240, 103, 141, 142, 12, 242, 219, 175, 141, 142, 
+    12, 232, 68, 175, 141, 142, 12, 242, 244, 125, 141, 142, 12, 254, 56, 
+    169, 141, 142, 12, 242, 207, 141, 142, 12, 247, 122, 169, 141, 142, 12, 
+    236, 99, 235, 50, 141, 142, 12, 248, 62, 161, 240, 32, 141, 142, 12, 248, 
+    62, 236, 85, 141, 142, 12, 92, 243, 25, 169, 141, 142, 12, 88, 243, 25, 
+    169, 141, 142, 12, 242, 237, 141, 142, 12, 248, 73, 141, 142, 12, 240, 
+    20, 141, 142, 12, 194, 235, 50, 141, 142, 12, 238, 57, 235, 50, 141, 142, 
+    12, 248, 42, 235, 50, 141, 142, 12, 211, 235, 50, 141, 142, 12, 240, 22, 
+    161, 243, 53, 69, 38, 185, 2, 235, 45, 240, 126, 56, 235, 0, 248, 35, 
+    248, 92, 250, 114, 91, 59, 248, 41, 2, 240, 1, 248, 40, 235, 128, 91, 
+    234, 104, 235, 157, 91, 231, 128, 235, 157, 91, 237, 8, 91, 233, 126, 91, 
+    64, 31, 2, 240, 46, 59, 242, 224, 245, 82, 91, 233, 68, 254, 105, 91, 
+    251, 51, 91, 29, 163, 253, 144, 2, 242, 23, 29, 236, 152, 242, 236, 240, 
+    129, 218, 2, 236, 64, 56, 252, 252, 91, 234, 224, 91, 234, 201, 91, 226, 
+    236, 241, 143, 91, 226, 236, 241, 209, 91, 226, 227, 91, 226, 230, 91, 
+    240, 169, 239, 33, 12, 248, 38, 111, 227, 7, 91, 141, 142, 12, 243, 43, 
+    238, 176, 235, 95, 254, 105, 91, 237, 242, 243, 240, 252, 16, 243, 240, 
+    246, 254, 240, 218, 91, 245, 23, 240, 218, 91, 40, 233, 56, 189, 90, 40, 
+    233, 56, 234, 10, 40, 233, 56, 168, 90, 38, 233, 56, 189, 90, 38, 233, 
+    56, 234, 10, 38, 233, 56, 168, 90, 40, 31, 238, 52, 189, 238, 67, 40, 31, 
+    238, 52, 234, 10, 40, 31, 238, 52, 168, 238, 67, 38, 31, 238, 52, 189, 
+    238, 67, 38, 31, 238, 52, 234, 10, 38, 31, 238, 52, 168, 238, 67, 40, 
+    242, 225, 238, 52, 189, 90, 40, 242, 225, 238, 52, 240, 1, 240, 119, 40, 
+    242, 225, 238, 52, 168, 90, 242, 225, 238, 52, 234, 10, 38, 242, 225, 
+    238, 52, 189, 90, 38, 242, 225, 238, 52, 240, 1, 240, 119, 38, 242, 225, 
+    238, 52, 168, 90, 236, 167, 234, 10, 163, 248, 41, 234, 10, 189, 40, 128, 
+    168, 38, 242, 225, 238, 52, 236, 210, 189, 38, 128, 168, 40, 242, 225, 
+    238, 52, 236, 210, 235, 112, 249, 3, 235, 112, 238, 128, 253, 159, 31, 
+    104, 240, 17, 31, 104, 240, 17, 31, 238, 52, 248, 59, 253, 159, 31, 104, 
+    25, 12, 238, 128, 40, 59, 66, 242, 224, 38, 59, 66, 242, 224, 163, 248, 
+    183, 239, 119, 163, 248, 183, 239, 120, 163, 248, 183, 239, 121, 163, 
+    248, 183, 239, 122, 235, 58, 12, 136, 59, 19, 253, 159, 225, 235, 58, 12, 
+    136, 59, 19, 240, 17, 225, 235, 58, 12, 136, 59, 2, 238, 51, 235, 58, 12, 
+    136, 92, 19, 163, 2, 238, 51, 235, 58, 12, 136, 88, 19, 163, 2, 238, 51, 
+    235, 58, 12, 136, 59, 2, 235, 46, 235, 58, 12, 136, 92, 19, 163, 2, 235, 
+    46, 235, 58, 12, 136, 88, 19, 163, 2, 235, 46, 235, 58, 12, 136, 59, 19, 
+    243, 80, 235, 58, 12, 136, 92, 19, 163, 2, 243, 80, 235, 58, 12, 136, 88, 
+    19, 163, 2, 243, 80, 235, 58, 12, 136, 92, 19, 233, 50, 235, 58, 12, 136, 
+    88, 19, 233, 50, 235, 58, 12, 136, 59, 19, 253, 159, 242, 220, 235, 58, 
+    12, 136, 59, 19, 240, 17, 242, 220, 31, 243, 94, 242, 80, 91, 245, 81, 
+    91, 59, 248, 41, 234, 10, 236, 183, 239, 255, 236, 183, 183, 248, 59, 
+    242, 108, 236, 183, 242, 215, 248, 59, 243, 66, 236, 183, 183, 248, 59, 
+    171, 239, 194, 236, 183, 171, 240, 228, 248, 59, 243, 66, 236, 183, 171, 
+    240, 228, 239, 103, 236, 183, 237, 49, 236, 183, 234, 82, 236, 183, 234, 
+    62, 243, 168, 239, 85, 245, 94, 12, 28, 246, 193, 12, 28, 243, 124, 147, 
+    237, 173, 12, 28, 243, 124, 147, 244, 28, 12, 28, 253, 165, 147, 244, 28, 
+    12, 28, 253, 165, 147, 232, 62, 12, 28, 237, 150, 12, 28, 232, 103, 12, 
+    28, 244, 215, 12, 28, 234, 96, 12, 28, 163, 233, 107, 12, 28, 248, 41, 
+    243, 171, 12, 28, 59, 233, 107, 12, 28, 248, 38, 243, 171, 12, 28, 237, 
+    84, 238, 211, 12, 28, 244, 11, 248, 235, 12, 28, 244, 11, 253, 247, 12, 
+    28, 250, 185, 251, 197, 238, 183, 12, 28, 240, 113, 238, 110, 127, 12, 
+    28, 240, 113, 238, 110, 111, 12, 28, 240, 113, 238, 110, 166, 12, 28, 
+    240, 113, 238, 110, 177, 12, 28, 236, 146, 232, 103, 12, 28, 233, 250, 
+    245, 224, 12, 28, 253, 165, 147, 233, 44, 240, 13, 12, 28, 239, 16, 12, 
+    28, 253, 165, 147, 239, 132, 12, 28, 233, 249, 12, 28, 238, 183, 12, 28, 
+    250, 244, 234, 6, 12, 28, 245, 128, 234, 6, 12, 28, 242, 79, 234, 6, 12, 
+    28, 252, 253, 234, 6, 12, 28, 240, 15, 12, 28, 239, 39, 244, 224, 91, 
+    248, 35, 248, 92, 12, 28, 237, 219, 12, 28, 241, 81, 248, 38, 111, 12, 
+    28, 235, 5, 248, 38, 111, 253, 207, 90, 253, 207, 241, 50, 253, 207, 243, 
+    175, 253, 207, 236, 145, 243, 175, 253, 207, 250, 115, 239, 15, 253, 207, 
+    254, 146, 248, 139, 253, 207, 241, 36, 250, 102, 229, 67, 253, 207, 241, 
+    9, 147, 240, 162, 253, 207, 242, 235, 253, 207, 237, 97, 238, 158, 239, 
+    147, 253, 207, 45, 234, 25, 29, 26, 127, 29, 26, 111, 29, 26, 166, 29, 
+    26, 177, 29, 26, 176, 29, 26, 187, 29, 26, 203, 29, 26, 195, 29, 26, 202, 
+    29, 61, 248, 53, 29, 61, 238, 91, 29, 61, 238, 97, 29, 61, 235, 85, 29, 
+    61, 235, 82, 29, 61, 236, 207, 29, 61, 236, 202, 29, 61, 234, 22, 29, 61, 
+    235, 81, 29, 61, 235, 83, 29, 61, 238, 77, 82, 26, 127, 82, 26, 111, 82, 
+    26, 166, 82, 26, 177, 82, 26, 176, 82, 26, 187, 82, 26, 203, 82, 26, 195, 
+    82, 26, 202, 82, 61, 248, 53, 82, 61, 238, 91, 82, 61, 238, 97, 82, 61, 
+    235, 85, 82, 61, 235, 82, 82, 61, 236, 207, 82, 61, 236, 202, 82, 61, 
+    234, 22, 82, 61, 235, 81, 82, 61, 235, 83, 82, 61, 238, 77, 26, 253, 125, 
+    248, 37, 208, 26, 171, 248, 37, 208, 26, 204, 248, 37, 208, 26, 248, 58, 
+    248, 37, 208, 26, 248, 48, 248, 37, 208, 26, 254, 31, 248, 37, 208, 26, 
+    243, 31, 248, 37, 208, 26, 242, 254, 248, 37, 208, 26, 248, 173, 248, 37, 
+    208, 61, 253, 219, 248, 37, 208, 61, 241, 93, 248, 37, 208, 61, 240, 251, 
+    248, 37, 208, 61, 238, 26, 248, 37, 208, 61, 237, 161, 248, 37, 208, 61, 
+    239, 70, 248, 37, 208, 61, 238, 216, 248, 37, 208, 61, 236, 100, 248, 37, 
+    208, 61, 237, 147, 248, 37, 208, 61, 237, 222, 248, 37, 208, 61, 240, 48, 
+    248, 37, 208, 82, 8, 3, 1, 67, 82, 8, 3, 1, 217, 82, 8, 3, 1, 255, 18, 
+    82, 8, 3, 1, 209, 82, 8, 3, 1, 72, 82, 8, 3, 1, 255, 19, 82, 8, 3, 1, 
+    210, 82, 8, 3, 1, 192, 82, 8, 3, 1, 71, 82, 8, 3, 1, 221, 82, 8, 3, 1, 
+    255, 15, 82, 8, 3, 1, 162, 82, 8, 3, 1, 173, 82, 8, 3, 1, 197, 82, 8, 3, 
+    1, 73, 82, 8, 3, 1, 223, 82, 8, 3, 1, 255, 20, 82, 8, 3, 1, 144, 82, 8, 
+    3, 1, 193, 82, 8, 3, 1, 214, 82, 8, 3, 1, 79, 82, 8, 3, 1, 179, 82, 8, 3, 
+    1, 255, 16, 82, 8, 3, 1, 206, 82, 8, 3, 1, 255, 14, 82, 8, 3, 1, 255, 17, 
+    29, 8, 5, 1, 67, 29, 8, 5, 1, 217, 29, 8, 5, 1, 255, 18, 29, 8, 5, 1, 
+    209, 29, 8, 5, 1, 72, 29, 8, 5, 1, 255, 19, 29, 8, 5, 1, 210, 29, 8, 5, 
+    1, 192, 29, 8, 5, 1, 71, 29, 8, 5, 1, 221, 29, 8, 5, 1, 255, 15, 29, 8, 
+    5, 1, 162, 29, 8, 5, 1, 173, 29, 8, 5, 1, 197, 29, 8, 5, 1, 73, 29, 8, 5, 
+    1, 223, 29, 8, 5, 1, 255, 20, 29, 8, 5, 1, 144, 29, 8, 5, 1, 193, 29, 8, 
+    5, 1, 214, 29, 8, 5, 1, 79, 29, 8, 5, 1, 179, 29, 8, 5, 1, 255, 16, 29, 
+    8, 5, 1, 206, 29, 8, 5, 1, 255, 14, 29, 8, 5, 1, 255, 17, 29, 8, 3, 1, 
+    67, 29, 8, 3, 1, 217, 29, 8, 3, 1, 255, 18, 29, 8, 3, 1, 209, 29, 8, 3, 
+    1, 72, 29, 8, 3, 1, 255, 19, 29, 8, 3, 1, 210, 29, 8, 3, 1, 192, 29, 8, 
+    3, 1, 71, 29, 8, 3, 1, 221, 29, 8, 3, 1, 255, 15, 29, 8, 3, 1, 162, 29, 
+    8, 3, 1, 173, 29, 8, 3, 1, 197, 29, 8, 3, 1, 73, 29, 8, 3, 1, 223, 29, 8, 
+    3, 1, 255, 20, 29, 8, 3, 1, 144, 29, 8, 3, 1, 193, 29, 8, 3, 1, 214, 29, 
+    8, 3, 1, 79, 29, 8, 3, 1, 179, 29, 8, 3, 1, 255, 16, 29, 8, 3, 1, 206, 
+    29, 8, 3, 1, 255, 14, 29, 8, 3, 1, 255, 17, 29, 26, 242, 217, 236, 146, 
+    29, 61, 238, 91, 236, 146, 29, 61, 238, 97, 236, 146, 29, 61, 235, 85, 
+    236, 146, 29, 61, 235, 82, 236, 146, 29, 61, 236, 207, 236, 146, 29, 61, 
+    236, 202, 236, 146, 29, 61, 234, 22, 236, 146, 29, 61, 235, 81, 236, 146, 
+    29, 61, 235, 83, 236, 146, 29, 61, 238, 77, 45, 29, 26, 127, 45, 29, 26, 
+    111, 45, 29, 26, 166, 45, 29, 26, 177, 45, 29, 26, 176, 45, 29, 26, 187, 
+    45, 29, 26, 203, 45, 29, 26, 195, 45, 29, 26, 202, 45, 29, 61, 248, 53, 
+    236, 146, 29, 26, 242, 217, 66, 70, 136, 233, 50, 66, 70, 96, 233, 50, 
+    66, 70, 136, 235, 63, 66, 70, 96, 235, 63, 66, 70, 136, 240, 3, 248, 63, 
+    233, 50, 66, 70, 96, 240, 3, 248, 63, 233, 50, 66, 70, 136, 240, 3, 248, 
+    63, 235, 63, 66, 70, 96, 240, 3, 248, 63, 235, 63, 66, 70, 136, 235, 71, 
+    248, 63, 233, 50, 66, 70, 96, 235, 71, 248, 63, 233, 50, 66, 70, 136, 
+    235, 71, 248, 63, 235, 63, 66, 70, 96, 235, 71, 248, 63, 235, 63, 66, 70, 
+    136, 92, 19, 225, 66, 70, 92, 136, 19, 38, 240, 11, 66, 70, 92, 96, 19, 
+    38, 240, 9, 66, 70, 96, 92, 19, 225, 66, 70, 136, 92, 19, 242, 220, 66, 
+    70, 92, 136, 19, 40, 240, 11, 66, 70, 92, 96, 19, 40, 240, 9, 66, 70, 96, 
+    92, 19, 242, 220, 66, 70, 136, 88, 19, 225, 66, 70, 88, 136, 19, 38, 240, 
+    11, 66, 70, 88, 96, 19, 38, 240, 9, 66, 70, 96, 88, 19, 225, 66, 70, 136, 
+    88, 19, 242, 220, 66, 70, 88, 136, 19, 40, 240, 11, 66, 70, 88, 96, 19, 
+    40, 240, 9, 66, 70, 96, 88, 19, 242, 220, 66, 70, 136, 59, 19, 225, 66, 
+    70, 59, 136, 19, 38, 240, 11, 66, 70, 88, 96, 19, 38, 92, 240, 9, 66, 70, 
+    92, 96, 19, 38, 88, 240, 9, 66, 70, 59, 96, 19, 38, 240, 9, 66, 70, 92, 
+    136, 19, 38, 88, 240, 11, 66, 70, 88, 136, 19, 38, 92, 240, 11, 66, 70, 
+    96, 59, 19, 225, 66, 70, 136, 59, 19, 242, 220, 66, 70, 59, 136, 19, 40, 
+    240, 11, 66, 70, 88, 96, 19, 40, 92, 240, 9, 66, 70, 92, 96, 19, 40, 88, 
+    240, 9, 66, 70, 59, 96, 19, 40, 240, 9, 66, 70, 92, 136, 19, 40, 88, 240, 
+    11, 66, 70, 88, 136, 19, 40, 92, 240, 11, 66, 70, 96, 59, 19, 242, 220, 
+    66, 70, 136, 92, 19, 233, 50, 66, 70, 40, 96, 19, 38, 92, 240, 9, 66, 70, 
+    38, 96, 19, 40, 92, 240, 9, 66, 70, 92, 136, 19, 163, 240, 11, 66, 70, 
+    92, 96, 19, 163, 240, 9, 66, 70, 38, 136, 19, 40, 92, 240, 11, 66, 70, 
+    40, 136, 19, 38, 92, 240, 11, 66, 70, 96, 92, 19, 233, 50, 66, 70, 136, 
+    88, 19, 233, 50, 66, 70, 40, 96, 19, 38, 88, 240, 9, 66, 70, 38, 96, 19, 
+    40, 88, 240, 9, 66, 70, 88, 136, 19, 163, 240, 11, 66, 70, 88, 96, 19, 
+    163, 240, 9, 66, 70, 38, 136, 19, 40, 88, 240, 11, 66, 70, 40, 136, 19, 
+    38, 88, 240, 11, 66, 70, 96, 88, 19, 233, 50, 66, 70, 136, 59, 19, 233, 
+    50, 66, 70, 40, 96, 19, 38, 59, 240, 9, 66, 70, 38, 96, 19, 40, 59, 240, 
+    9, 66, 70, 59, 136, 19, 163, 240, 11, 66, 70, 88, 96, 19, 92, 163, 240, 
+    9, 66, 70, 92, 96, 19, 88, 163, 240, 9, 66, 70, 59, 96, 19, 163, 240, 9, 
+    66, 70, 40, 88, 96, 19, 38, 92, 240, 9, 66, 70, 38, 88, 96, 19, 40, 92, 
+    240, 9, 66, 70, 40, 92, 96, 19, 38, 88, 240, 9, 66, 70, 38, 92, 96, 19, 
+    40, 88, 240, 9, 66, 70, 92, 136, 19, 88, 163, 240, 11, 66, 70, 88, 136, 
+    19, 92, 163, 240, 11, 66, 70, 38, 136, 19, 40, 59, 240, 11, 66, 70, 40, 
+    136, 19, 38, 59, 240, 11, 66, 70, 96, 59, 19, 233, 50, 66, 70, 136, 45, 
+    248, 63, 233, 50, 66, 70, 96, 45, 248, 63, 233, 50, 66, 70, 136, 45, 248, 
+    63, 235, 63, 66, 70, 96, 45, 248, 63, 235, 63, 66, 70, 45, 233, 50, 66, 
+    70, 45, 235, 63, 66, 70, 92, 240, 12, 19, 38, 238, 78, 66, 70, 92, 45, 
+    19, 38, 238, 82, 66, 70, 45, 92, 19, 225, 66, 70, 92, 240, 12, 19, 40, 
+    238, 78, 66, 70, 92, 45, 19, 40, 238, 82, 66, 70, 45, 92, 19, 242, 220, 
+    66, 70, 88, 240, 12, 19, 38, 238, 78, 66, 70, 88, 45, 19, 38, 238, 82, 
+    66, 70, 45, 88, 19, 225, 66, 70, 88, 240, 12, 19, 40, 238, 78, 66, 70, 
+    88, 45, 19, 40, 238, 82, 66, 70, 45, 88, 19, 242, 220, 66, 70, 59, 240, 
+    12, 19, 38, 238, 78, 66, 70, 59, 45, 19, 38, 238, 82, 66, 70, 45, 59, 19, 
+    225, 66, 70, 59, 240, 12, 19, 40, 238, 78, 66, 70, 59, 45, 19, 40, 238, 
+    82, 66, 70, 45, 59, 19, 242, 220, 66, 70, 92, 240, 12, 19, 163, 238, 78, 
+    66, 70, 92, 45, 19, 163, 238, 82, 66, 70, 45, 92, 19, 233, 50, 66, 70, 
+    88, 240, 12, 19, 163, 238, 78, 66, 70, 88, 45, 19, 163, 238, 82, 66, 70, 
+    45, 88, 19, 233, 50, 66, 70, 59, 240, 12, 19, 163, 238, 78, 66, 70, 59, 
+    45, 19, 163, 238, 82, 66, 70, 45, 59, 19, 233, 50, 66, 70, 136, 253, 183, 
+    92, 19, 225, 66, 70, 136, 253, 183, 92, 19, 242, 220, 66, 70, 136, 253, 
+    183, 88, 19, 242, 220, 66, 70, 136, 253, 183, 88, 19, 225, 66, 70, 136, 
+    236, 159, 189, 38, 153, 168, 242, 220, 66, 70, 136, 236, 159, 189, 40, 
+    153, 168, 225, 66, 70, 136, 236, 159, 240, 34, 66, 70, 136, 242, 220, 66, 
+    70, 136, 253, 176, 66, 70, 136, 225, 66, 70, 136, 242, 236, 66, 70, 96, 
+    242, 220, 66, 70, 96, 253, 176, 66, 70, 96, 225, 66, 70, 96, 242, 236, 
+    66, 70, 136, 40, 19, 96, 225, 66, 70, 136, 88, 19, 96, 242, 236, 66, 70, 
+    96, 40, 19, 136, 225, 66, 70, 96, 88, 19, 136, 242, 236, 189, 137, 240, 
+    13, 168, 253, 125, 240, 62, 240, 13, 168, 253, 125, 238, 80, 240, 13, 
+    168, 204, 238, 98, 240, 13, 168, 137, 240, 13, 168, 248, 48, 238, 98, 
+    240, 13, 168, 204, 236, 236, 240, 13, 168, 243, 31, 238, 98, 240, 13, 
+    248, 37, 240, 13, 40, 243, 31, 238, 98, 240, 13, 40, 204, 236, 236, 240, 
+    13, 40, 248, 48, 238, 98, 240, 13, 40, 137, 240, 13, 40, 204, 238, 98, 
+    240, 13, 40, 253, 125, 238, 80, 240, 13, 40, 253, 125, 240, 62, 240, 13, 
+    38, 137, 240, 13, 136, 240, 146, 240, 19, 240, 146, 250, 183, 240, 146, 
+    189, 253, 125, 240, 62, 240, 13, 38, 253, 125, 240, 62, 240, 13, 236, 
+    158, 168, 242, 220, 236, 158, 168, 225, 236, 158, 189, 242, 220, 236, 
+    158, 189, 40, 19, 168, 40, 19, 168, 225, 236, 158, 189, 40, 19, 168, 225, 
+    236, 158, 189, 40, 19, 189, 38, 19, 168, 242, 220, 236, 158, 189, 40, 19, 
+    189, 38, 19, 168, 225, 236, 158, 189, 225, 236, 158, 189, 38, 19, 168, 
+    242, 220, 236, 158, 189, 38, 19, 168, 40, 19, 168, 225, 86, 238, 59, 64, 
+    238, 59, 64, 31, 2, 238, 121, 237, 0, 64, 31, 234, 34, 86, 3, 238, 59, 
+    31, 2, 163, 243, 19, 31, 2, 59, 243, 19, 31, 2, 234, 230, 234, 51, 243, 
+    19, 31, 2, 189, 40, 153, 168, 38, 243, 19, 31, 2, 189, 38, 153, 168, 40, 
+    243, 19, 31, 2, 236, 159, 234, 51, 243, 19, 86, 3, 238, 59, 64, 3, 238, 
+    59, 86, 234, 31, 64, 234, 31, 86, 59, 234, 31, 64, 59, 234, 31, 86, 231, 
+    48, 64, 231, 48, 86, 233, 60, 235, 46, 64, 233, 60, 235, 46, 86, 233, 60, 
+    3, 235, 46, 64, 233, 60, 3, 235, 46, 86, 231, 36, 235, 46, 64, 231, 36, 
+    235, 46, 86, 231, 36, 3, 235, 46, 64, 231, 36, 3, 235, 46, 86, 231, 36, 
+    236, 217, 64, 231, 36, 236, 217, 86, 231, 91, 235, 46, 64, 231, 91, 235, 
+    46, 86, 231, 91, 3, 235, 46, 64, 231, 91, 3, 235, 46, 86, 231, 87, 235, 
+    46, 64, 231, 87, 235, 46, 86, 231, 87, 3, 235, 46, 64, 231, 87, 3, 235, 
+    46, 86, 231, 87, 236, 217, 64, 231, 87, 236, 217, 86, 236, 164, 64, 236, 
+    164, 64, 238, 76, 234, 34, 86, 3, 236, 164, 237, 157, 236, 231, 64, 238, 
+    51, 240, 4, 238, 51, 218, 2, 59, 243, 19, 235, 183, 86, 238, 51, 218, 2, 
+    40, 137, 240, 0, 218, 2, 38, 137, 240, 0, 218, 2, 168, 137, 240, 0, 218, 
+    2, 189, 137, 240, 0, 218, 2, 189, 38, 236, 158, 240, 0, 218, 2, 254, 51, 
+    253, 230, 189, 40, 236, 158, 240, 0, 40, 137, 86, 238, 51, 38, 137, 86, 
+    238, 51, 238, 116, 238, 69, 238, 116, 64, 238, 51, 189, 137, 238, 116, 
+    64, 238, 51, 168, 137, 238, 116, 64, 238, 51, 189, 40, 236, 158, 236, 
+    211, 248, 113, 189, 38, 236, 158, 236, 211, 248, 113, 168, 38, 236, 158, 
+    236, 211, 248, 113, 168, 40, 236, 158, 236, 211, 248, 113, 189, 137, 238, 
+    51, 168, 137, 238, 51, 86, 168, 38, 235, 46, 86, 168, 40, 235, 46, 86, 
+    189, 40, 235, 46, 86, 189, 38, 235, 46, 64, 238, 69, 31, 2, 40, 137, 240, 
+    0, 31, 2, 38, 137, 240, 0, 31, 2, 189, 40, 236, 159, 137, 240, 0, 31, 2, 
+    168, 38, 236, 159, 137, 240, 0, 64, 31, 2, 59, 235, 180, 242, 224, 64, 
+    233, 60, 236, 152, 2, 248, 40, 233, 60, 236, 152, 2, 40, 137, 240, 0, 
+    233, 60, 236, 152, 2, 38, 137, 240, 0, 243, 22, 238, 51, 64, 31, 2, 189, 
+    40, 235, 70, 64, 31, 2, 168, 40, 235, 70, 64, 31, 2, 168, 38, 235, 70, 
+    64, 31, 2, 189, 38, 235, 70, 64, 218, 2, 189, 40, 235, 70, 64, 218, 2, 
+    168, 40, 235, 70, 64, 218, 2, 168, 38, 235, 70, 64, 218, 2, 189, 38, 235, 
+    70, 189, 40, 235, 46, 189, 38, 235, 46, 168, 40, 235, 46, 64, 240, 19, 
+    238, 59, 86, 240, 19, 238, 59, 64, 240, 19, 3, 238, 59, 86, 240, 19, 3, 
+    238, 59, 168, 38, 235, 46, 86, 254, 126, 2, 243, 251, 241, 61, 236, 135, 
+    238, 9, 241, 64, 86, 242, 229, 64, 242, 229, 234, 219, 232, 60, 248, 136, 
+    235, 172, 243, 235, 234, 110, 243, 235, 232, 120, 233, 73, 86, 234, 81, 
+    64, 234, 81, 240, 91, 248, 92, 240, 91, 66, 2, 240, 162, 240, 91, 66, 2, 
+    206, 237, 255, 238, 38, 2, 252, 128, 241, 90, 254, 96, 235, 178, 64, 244, 
+    12, 240, 119, 86, 244, 12, 240, 119, 236, 101, 224, 238, 120, 240, 135, 
+    243, 16, 238, 69, 86, 40, 236, 150, 240, 76, 86, 38, 236, 150, 240, 76, 
+    64, 40, 236, 150, 240, 76, 64, 88, 236, 150, 240, 76, 64, 38, 236, 150, 
+    240, 76, 64, 92, 236, 150, 240, 76, 247, 92, 19, 233, 129, 239, 19, 52, 
+    233, 227, 52, 235, 179, 52, 235, 185, 244, 81, 237, 228, 240, 34, 254, 
+    83, 248, 73, 243, 38, 147, 236, 53, 243, 38, 147, 234, 210, 248, 135, 19, 
+    235, 196, 243, 26, 91, 254, 139, 239, 192, 240, 185, 19, 239, 196, 246, 
+    239, 91, 254, 15, 243, 50, 238, 89, 28, 238, 139, 238, 89, 28, 243, 213, 
+    238, 89, 28, 243, 27, 238, 89, 28, 237, 48, 238, 89, 28, 243, 82, 238, 
+    89, 28, 240, 105, 238, 89, 28, 235, 102, 238, 89, 28, 240, 49, 247, 195, 
+    147, 239, 42, 64, 237, 162, 243, 39, 64, 238, 219, 243, 39, 86, 238, 219, 
+    243, 39, 64, 254, 126, 2, 243, 251, 243, 41, 238, 80, 243, 30, 251, 184, 
+    238, 80, 243, 30, 237, 208, 240, 96, 52, 240, 49, 248, 95, 52, 237, 185, 
+    239, 180, 239, 236, 237, 218, 242, 62, 241, 15, 239, 215, 239, 81, 239, 
+    17, 251, 188, 242, 179, 241, 215, 236, 98, 232, 203, 234, 99, 235, 167, 
+    239, 163, 64, 242, 252, 243, 208, 64, 242, 252, 240, 213, 64, 242, 252, 
+    244, 0, 64, 242, 252, 238, 167, 64, 242, 252, 238, 196, 64, 242, 252, 
+    243, 241, 86, 242, 252, 243, 208, 86, 242, 252, 240, 213, 86, 242, 252, 
+    244, 0, 86, 242, 252, 238, 167, 86, 242, 252, 238, 196, 86, 242, 252, 
+    243, 241, 86, 244, 22, 243, 17, 64, 243, 16, 243, 17, 64, 238, 76, 243, 
+    17, 86, 249, 41, 243, 17, 64, 244, 22, 243, 17, 86, 243, 16, 243, 17, 86, 
+    238, 76, 243, 17, 64, 249, 41, 243, 17, 254, 96, 238, 11, 238, 80, 243, 
+    9, 240, 62, 243, 9, 240, 157, 240, 62, 240, 203, 240, 157, 235, 108, 240, 
+    203, 243, 108, 248, 209, 52, 243, 108, 238, 146, 52, 243, 108, 243, 74, 
+    52, 248, 56, 129, 240, 34, 248, 43, 129, 240, 34, 235, 159, 235, 65, 91, 
+    235, 65, 12, 28, 242, 164, 235, 75, 235, 65, 12, 28, 242, 165, 235, 75, 
+    235, 65, 12, 28, 242, 166, 235, 75, 235, 65, 12, 28, 242, 167, 235, 75, 
+    235, 65, 12, 28, 242, 168, 235, 75, 235, 65, 12, 28, 242, 169, 235, 75, 
+    235, 65, 12, 28, 242, 170, 235, 75, 235, 65, 12, 28, 239, 82, 234, 221, 
+    86, 235, 159, 235, 65, 91, 237, 249, 243, 113, 91, 226, 250, 243, 113, 
+    91, 236, 74, 243, 113, 52, 235, 41, 91, 254, 2, 239, 60, 254, 2, 239, 61, 
+    254, 2, 239, 62, 254, 2, 239, 63, 254, 2, 239, 64, 254, 2, 239, 65, 64, 
+    218, 2, 53, 225, 64, 218, 2, 171, 243, 5, 86, 218, 2, 64, 53, 225, 86, 
+    218, 2, 171, 64, 243, 5, 236, 184, 28, 243, 50, 236, 184, 28, 249, 23, 
+    240, 56, 28, 238, 188, 243, 50, 240, 56, 28, 240, 198, 249, 23, 240, 56, 
+    28, 240, 198, 243, 50, 240, 56, 28, 238, 188, 249, 23, 64, 243, 173, 86, 
+    243, 173, 240, 185, 19, 246, 248, 238, 159, 238, 133, 239, 211, 244, 24, 
+    147, 232, 113, 239, 181, 237, 58, 239, 77, 245, 98, 244, 24, 147, 239, 
+    92, 249, 242, 91, 231, 138, 239, 246, 52, 200, 239, 245, 52, 238, 179, 
+    240, 96, 52, 238, 179, 248, 95, 52, 233, 212, 240, 96, 19, 248, 95, 52, 
+    248, 95, 19, 240, 96, 52, 248, 95, 2, 240, 5, 52, 248, 95, 2, 240, 5, 19, 
+    248, 95, 19, 240, 96, 52, 59, 248, 95, 2, 240, 5, 52, 163, 248, 95, 2, 
+    240, 5, 52, 240, 19, 64, 238, 51, 240, 19, 86, 238, 51, 240, 19, 3, 64, 
+    238, 51, 237, 202, 91, 239, 45, 91, 236, 137, 233, 94, 91, 239, 30, 239, 
+    79, 253, 3, 189, 243, 148, 235, 93, 86, 235, 93, 168, 243, 148, 235, 93, 
+    64, 235, 93, 235, 113, 237, 195, 52, 252, 210, 241, 89, 235, 162, 236, 
+    12, 239, 242, 243, 59, 239, 249, 243, 59, 168, 38, 238, 148, 238, 148, 
+    189, 38, 238, 148, 64, 249, 120, 86, 249, 120, 243, 53, 69, 96, 243, 53, 
+    69, 231, 37, 206, 96, 231, 37, 206, 240, 91, 206, 96, 240, 91, 206, 236, 
+    199, 17, 240, 34, 96, 17, 240, 34, 248, 35, 240, 46, 240, 34, 96, 248, 
+    35, 240, 46, 240, 34, 8, 240, 34, 236, 189, 64, 8, 240, 34, 236, 199, 8, 
+    240, 34, 239, 126, 240, 34, 248, 135, 147, 241, 74, 248, 58, 229, 58, 
+    235, 52, 248, 58, 231, 39, 235, 52, 96, 248, 58, 231, 39, 235, 52, 248, 
+    58, 233, 123, 235, 52, 86, 248, 58, 238, 74, 242, 229, 64, 248, 58, 238, 
+    74, 242, 229, 240, 148, 236, 199, 64, 242, 229, 29, 64, 242, 229, 248, 
+    35, 240, 46, 86, 242, 229, 86, 240, 46, 64, 242, 229, 236, 199, 86, 242, 
+    229, 96, 236, 199, 86, 242, 229, 236, 235, 242, 229, 236, 189, 64, 242, 
+    229, 96, 235, 52, 248, 35, 240, 46, 235, 52, 242, 254, 242, 124, 235, 52, 
+    242, 254, 238, 74, 86, 242, 229, 242, 254, 238, 74, 236, 235, 242, 229, 
+    254, 31, 238, 74, 86, 242, 229, 242, 254, 238, 74, 233, 98, 86, 242, 229, 
+    96, 242, 254, 238, 74, 233, 98, 86, 242, 229, 240, 251, 238, 74, 86, 242, 
+    229, 238, 216, 238, 74, 235, 52, 229, 58, 235, 52, 248, 35, 240, 46, 229, 
+    58, 235, 52, 96, 229, 58, 235, 52, 254, 31, 237, 30, 86, 19, 64, 235, 88, 
+    86, 235, 88, 64, 235, 88, 242, 254, 237, 30, 236, 199, 86, 235, 88, 29, 
+    248, 35, 240, 46, 242, 254, 238, 74, 242, 229, 96, 229, 58, 236, 235, 
+    235, 52, 234, 42, 247, 150, 235, 35, 234, 42, 96, 239, 23, 234, 42, 237, 
+    42, 96, 237, 42, 231, 39, 235, 52, 242, 254, 229, 58, 235, 139, 235, 52, 
+    96, 242, 254, 229, 58, 235, 139, 235, 52, 236, 189, 64, 238, 51, 168, 38, 
+    231, 103, 64, 238, 59, 189, 38, 231, 103, 64, 238, 59, 168, 38, 236, 189, 
+    64, 238, 59, 189, 38, 236, 189, 64, 238, 59, 86, 238, 76, 242, 250, 64, 
+    206, 136, 59, 125, 240, 19, 59, 125, 96, 59, 125, 96, 240, 12, 205, 242, 
+    244, 235, 51, 158, 235, 53, 96, 240, 12, 242, 244, 235, 51, 158, 235, 53, 
+    96, 45, 205, 242, 244, 235, 51, 158, 235, 53, 96, 45, 242, 244, 235, 51, 
+    158, 235, 53, 240, 95, 252, 190, 235, 91, 21, 235, 53, 96, 233, 54, 158, 
+    235, 53, 96, 243, 16, 233, 54, 158, 235, 53, 96, 86, 240, 138, 238, 120, 
+    96, 86, 243, 16, 238, 69, 240, 135, 240, 138, 238, 120, 240, 135, 243, 
+    16, 238, 69, 240, 19, 40, 233, 56, 235, 53, 240, 19, 38, 233, 56, 235, 
+    53, 240, 19, 235, 122, 40, 233, 56, 235, 53, 240, 19, 235, 122, 38, 233, 
+    56, 235, 53, 240, 19, 231, 87, 185, 238, 52, 235, 53, 240, 19, 231, 36, 
+    185, 238, 52, 235, 53, 96, 231, 87, 185, 235, 51, 158, 235, 53, 96, 231, 
+    36, 185, 235, 51, 158, 235, 53, 96, 231, 87, 185, 238, 52, 235, 53, 96, 
+    231, 36, 185, 238, 52, 235, 53, 136, 40, 236, 171, 242, 255, 238, 52, 
+    235, 53, 136, 38, 236, 171, 242, 255, 238, 52, 235, 53, 240, 19, 40, 242, 
+    225, 238, 52, 235, 53, 240, 19, 38, 242, 225, 238, 52, 235, 53, 238, 55, 
+    236, 146, 29, 26, 127, 238, 55, 236, 146, 29, 26, 111, 238, 55, 236, 146, 
+    29, 26, 166, 238, 55, 236, 146, 29, 26, 177, 238, 55, 236, 146, 29, 26, 
+    176, 238, 55, 236, 146, 29, 26, 187, 238, 55, 236, 146, 29, 26, 203, 238, 
+    55, 236, 146, 29, 26, 195, 238, 55, 236, 146, 29, 26, 202, 238, 55, 236, 
+    146, 29, 61, 248, 53, 238, 55, 29, 27, 26, 127, 238, 55, 29, 27, 26, 111, 
+    238, 55, 29, 27, 26, 166, 238, 55, 29, 27, 26, 177, 238, 55, 29, 27, 26, 
+    176, 238, 55, 29, 27, 26, 187, 238, 55, 29, 27, 26, 203, 238, 55, 29, 27, 
+    26, 195, 238, 55, 29, 27, 26, 202, 238, 55, 29, 27, 61, 248, 53, 238, 55, 
+    236, 146, 29, 27, 26, 127, 238, 55, 236, 146, 29, 27, 26, 111, 238, 55, 
+    236, 146, 29, 27, 26, 166, 238, 55, 236, 146, 29, 27, 26, 177, 238, 55, 
+    236, 146, 29, 27, 26, 176, 238, 55, 236, 146, 29, 27, 26, 187, 238, 55, 
+    236, 146, 29, 27, 26, 203, 238, 55, 236, 146, 29, 27, 26, 195, 238, 55, 
+    236, 146, 29, 27, 26, 202, 238, 55, 236, 146, 29, 27, 61, 248, 53, 96, 
+    234, 1, 77, 56, 96, 242, 228, 248, 43, 56, 96, 77, 56, 96, 242, 223, 248, 
+    43, 56, 237, 142, 242, 232, 77, 56, 96, 232, 202, 77, 56, 229, 60, 77, 
+    56, 96, 229, 60, 77, 56, 240, 55, 229, 60, 77, 56, 96, 240, 55, 229, 60, 
+    77, 56, 86, 77, 56, 238, 229, 233, 253, 77, 234, 7, 238, 229, 231, 60, 
+    77, 234, 7, 86, 77, 234, 7, 96, 86, 240, 95, 235, 45, 19, 77, 56, 96, 86, 
+    240, 95, 226, 226, 19, 77, 56, 244, 23, 86, 77, 56, 96, 229, 65, 86, 77, 
+    56, 232, 200, 64, 77, 56, 233, 215, 64, 77, 56, 233, 119, 236, 189, 64, 
+    77, 56, 232, 166, 236, 189, 64, 77, 56, 96, 168, 231, 38, 64, 77, 56, 96, 
+    189, 231, 38, 64, 77, 56, 238, 204, 168, 231, 38, 64, 77, 56, 238, 204, 
+    189, 231, 38, 64, 77, 56, 29, 96, 64, 77, 56, 231, 34, 77, 56, 229, 59, 
+    242, 228, 248, 43, 56, 229, 59, 77, 56, 229, 59, 242, 223, 248, 43, 56, 
+    96, 229, 59, 242, 228, 248, 43, 56, 96, 229, 59, 77, 56, 96, 229, 59, 
+    242, 223, 248, 43, 56, 231, 31, 77, 56, 96, 229, 56, 77, 56, 232, 112, 
+    77, 56, 96, 232, 112, 77, 56, 231, 150, 77, 56, 204, 233, 133, 240, 54, 
+    64, 236, 152, 234, 34, 3, 64, 235, 46, 231, 49, 248, 35, 238, 87, 248, 
+    35, 235, 84, 40, 237, 35, 254, 52, 234, 35, 38, 237, 35, 254, 52, 234, 
+    35, 64, 238, 76, 2, 238, 130, 248, 40, 19, 2, 248, 40, 238, 68, 147, 238, 
+    96, 236, 206, 168, 38, 240, 31, 2, 248, 40, 189, 40, 240, 31, 2, 248, 40, 
+    40, 243, 111, 243, 61, 38, 243, 111, 243, 61, 248, 37, 243, 111, 243, 61, 
+    243, 22, 88, 242, 234, 243, 22, 92, 242, 234, 40, 19, 38, 45, 234, 15, 
+    40, 19, 38, 242, 234, 40, 235, 103, 183, 38, 242, 234, 183, 40, 242, 234, 
+    88, 248, 84, 2, 218, 48, 239, 124, 238, 135, 255, 25, 163, 247, 53, 64, 
+    231, 95, 236, 164, 64, 231, 95, 238, 76, 2, 139, 243, 36, 64, 231, 95, 
+    238, 76, 2, 77, 243, 36, 64, 31, 2, 139, 243, 36, 64, 31, 2, 77, 243, 36, 
+    10, 40, 64, 31, 104, 10, 38, 64, 31, 104, 10, 40, 185, 104, 10, 38, 185, 
+    104, 10, 40, 45, 185, 104, 10, 38, 45, 185, 104, 226, 226, 235, 71, 56, 
+    235, 45, 235, 71, 56, 231, 86, 240, 178, 218, 56, 235, 62, 240, 178, 218, 
+    56, 38, 65, 2, 29, 243, 12, 183, 139, 56, 183, 77, 56, 183, 40, 38, 56, 
+    183, 139, 45, 56, 183, 77, 45, 56, 183, 40, 38, 45, 56, 183, 139, 65, 
+    248, 44, 125, 183, 77, 65, 248, 44, 125, 183, 139, 45, 65, 248, 44, 125, 
+    183, 77, 45, 65, 248, 44, 125, 183, 77, 236, 240, 56, 35, 36, 241, 33, 
+    35, 36, 239, 46, 35, 36, 239, 47, 35, 36, 237, 113, 35, 36, 239, 48, 35, 
+    36, 237, 114, 35, 36, 237, 120, 35, 36, 235, 206, 35, 36, 239, 49, 35, 
+    36, 237, 115, 35, 36, 237, 121, 35, 36, 235, 207, 35, 36, 237, 126, 35, 
+    36, 235, 212, 35, 36, 235, 227, 35, 36, 234, 113, 35, 36, 239, 50, 35, 
+    36, 237, 116, 35, 36, 237, 122, 35, 36, 235, 208, 35, 36, 237, 127, 35, 
+    36, 235, 213, 35, 36, 235, 228, 35, 36, 234, 114, 35, 36, 237, 131, 35, 
+    36, 235, 217, 35, 36, 235, 232, 35, 36, 234, 118, 35, 36, 235, 242, 35, 
+    36, 234, 128, 35, 36, 234, 148, 35, 36, 233, 138, 35, 36, 239, 51, 35, 
+    36, 237, 117, 35, 36, 237, 123, 35, 36, 235, 209, 35, 36, 237, 128, 35, 
+    36, 235, 214, 35, 36, 235, 229, 35, 36, 234, 115, 35, 36, 237, 132, 35, 
+    36, 235, 218, 35, 36, 235, 233, 35, 36, 234, 119, 35, 36, 235, 243, 35, 
+    36, 234, 129, 35, 36, 234, 149, 35, 36, 233, 139, 35, 36, 237, 135, 35, 
+    36, 235, 221, 35, 36, 235, 236, 35, 36, 234, 122, 35, 36, 235, 246, 35, 
+    36, 234, 132, 35, 36, 234, 152, 35, 36, 233, 142, 35, 36, 235, 252, 35, 
+    36, 234, 138, 35, 36, 234, 158, 35, 36, 233, 148, 35, 36, 234, 168, 35, 
+    36, 233, 158, 35, 36, 233, 173, 35, 36, 232, 134, 35, 36, 239, 52, 35, 
+    36, 237, 118, 35, 36, 237, 124, 35, 36, 235, 210, 35, 36, 237, 129, 35, 
+    36, 235, 215, 35, 36, 235, 230, 35, 36, 234, 116, 35, 36, 237, 133, 35, 
+    36, 235, 219, 35, 36, 235, 234, 35, 36, 234, 120, 35, 36, 235, 244, 35, 
+    36, 234, 130, 35, 36, 234, 150, 35, 36, 233, 140, 35, 36, 237, 136, 35, 
+    36, 235, 222, 35, 36, 235, 237, 35, 36, 234, 123, 35, 36, 235, 247, 35, 
+    36, 234, 133, 35, 36, 234, 153, 35, 36, 233, 143, 35, 36, 235, 253, 35, 
+    36, 234, 139, 35, 36, 234, 159, 35, 36, 233, 149, 35, 36, 234, 169, 35, 
+    36, 233, 159, 35, 36, 233, 174, 35, 36, 232, 135, 35, 36, 237, 138, 35, 
+    36, 235, 224, 35, 36, 235, 239, 35, 36, 234, 125, 35, 36, 235, 249, 35, 
+    36, 234, 135, 35, 36, 234, 155, 35, 36, 233, 145, 35, 36, 235, 255, 35, 
+    36, 234, 141, 35, 36, 234, 161, 35, 36, 233, 151, 35, 36, 234, 171, 35, 
+    36, 233, 161, 35, 36, 233, 176, 35, 36, 232, 137, 35, 36, 236, 2, 35, 36, 
+    234, 144, 35, 36, 234, 164, 35, 36, 233, 154, 35, 36, 234, 174, 35, 36, 
+    233, 164, 35, 36, 233, 179, 35, 36, 232, 140, 35, 36, 234, 178, 35, 36, 
+    233, 168, 35, 36, 233, 183, 35, 36, 232, 144, 35, 36, 233, 188, 35, 36, 
+    232, 149, 35, 36, 232, 155, 35, 36, 231, 129, 35, 36, 239, 53, 35, 36, 
+    237, 119, 35, 36, 237, 125, 35, 36, 235, 211, 35, 36, 237, 130, 35, 36, 
+    235, 216, 35, 36, 235, 231, 35, 36, 234, 117, 35, 36, 237, 134, 35, 36, 
+    235, 220, 35, 36, 235, 235, 35, 36, 234, 121, 35, 36, 235, 245, 35, 36, 
+    234, 131, 35, 36, 234, 151, 35, 36, 233, 141, 35, 36, 237, 137, 35, 36, 
+    235, 223, 35, 36, 235, 238, 35, 36, 234, 124, 35, 36, 235, 248, 35, 36, 
+    234, 134, 35, 36, 234, 154, 35, 36, 233, 144, 35, 36, 235, 254, 35, 36, 
+    234, 140, 35, 36, 234, 160, 35, 36, 233, 150, 35, 36, 234, 170, 35, 36, 
+    233, 160, 35, 36, 233, 175, 35, 36, 232, 136, 35, 36, 237, 139, 35, 36, 
+    235, 225, 35, 36, 235, 240, 35, 36, 234, 126, 35, 36, 235, 250, 35, 36, 
+    234, 136, 35, 36, 234, 156, 35, 36, 233, 146, 35, 36, 236, 0, 35, 36, 
+    234, 142, 35, 36, 234, 162, 35, 36, 233, 152, 35, 36, 234, 172, 35, 36, 
+    233, 162, 35, 36, 233, 177, 35, 36, 232, 138, 35, 36, 236, 3, 35, 36, 
+    234, 145, 35, 36, 234, 165, 35, 36, 233, 155, 35, 36, 234, 175, 35, 36, 
+    233, 165, 35, 36, 233, 180, 35, 36, 232, 141, 35, 36, 234, 179, 35, 36, 
+    233, 169, 35, 36, 233, 184, 35, 36, 232, 145, 35, 36, 233, 189, 35, 36, 
+    232, 150, 35, 36, 232, 156, 35, 36, 231, 130, 35, 36, 237, 140, 35, 36, 
+    235, 226, 35, 36, 235, 241, 35, 36, 234, 127, 35, 36, 235, 251, 35, 36, 
+    234, 137, 35, 36, 234, 157, 35, 36, 233, 147, 35, 36, 236, 1, 35, 36, 
+    234, 143, 35, 36, 234, 163, 35, 36, 233, 153, 35, 36, 234, 173, 35, 36, 
+    233, 163, 35, 36, 233, 178, 35, 36, 232, 139, 35, 36, 236, 4, 35, 36, 
+    234, 146, 35, 36, 234, 166, 35, 36, 233, 156, 35, 36, 234, 176, 35, 36, 
+    233, 166, 35, 36, 233, 181, 35, 36, 232, 142, 35, 36, 234, 180, 35, 36, 
+    233, 170, 35, 36, 233, 185, 35, 36, 232, 146, 35, 36, 233, 190, 35, 36, 
+    232, 151, 35, 36, 232, 157, 35, 36, 231, 131, 35, 36, 236, 5, 35, 36, 
+    234, 147, 35, 36, 234, 167, 35, 36, 233, 157, 35, 36, 234, 177, 35, 36, 
+    233, 167, 35, 36, 233, 182, 35, 36, 232, 143, 35, 36, 234, 181, 35, 36, 
+    233, 171, 35, 36, 233, 186, 35, 36, 232, 147, 35, 36, 233, 191, 35, 36, 
+    232, 152, 35, 36, 232, 158, 35, 36, 231, 132, 35, 36, 234, 182, 35, 36, 
+    233, 172, 35, 36, 233, 187, 35, 36, 232, 148, 35, 36, 233, 192, 35, 36, 
+    232, 153, 35, 36, 232, 159, 35, 36, 231, 133, 35, 36, 233, 193, 35, 36, 
+    232, 154, 35, 36, 232, 160, 35, 36, 231, 134, 35, 36, 232, 161, 35, 36, 
+    231, 135, 35, 36, 231, 136, 35, 36, 231, 64, 77, 234, 16, 65, 2, 59, 108, 
+    77, 234, 16, 65, 2, 45, 59, 108, 139, 45, 65, 2, 59, 108, 77, 45, 65, 2, 
+    59, 108, 40, 38, 45, 65, 2, 59, 108, 77, 234, 16, 65, 248, 44, 125, 139, 
+    45, 65, 248, 44, 125, 77, 45, 65, 248, 44, 125, 235, 45, 65, 2, 163, 108, 
+    226, 226, 65, 2, 163, 108, 226, 226, 240, 3, 56, 235, 45, 240, 3, 56, 
+    139, 45, 248, 63, 56, 77, 45, 248, 63, 56, 139, 240, 3, 248, 63, 56, 77, 
+    240, 3, 248, 63, 56, 77, 234, 16, 240, 3, 248, 63, 56, 77, 65, 2, 240, 4, 
+    243, 46, 226, 226, 65, 153, 125, 235, 45, 65, 153, 125, 77, 65, 2, 248, 
+    138, 2, 59, 108, 77, 65, 2, 248, 138, 2, 45, 59, 108, 77, 234, 16, 65, 2, 
+    242, 226, 77, 234, 16, 65, 2, 248, 138, 2, 59, 108, 77, 234, 16, 65, 2, 
+    248, 138, 2, 45, 59, 108, 139, 233, 64, 77, 233, 64, 139, 45, 233, 64, 
+    77, 45, 233, 64, 139, 65, 153, 86, 236, 164, 77, 65, 153, 86, 236, 164, 
+    139, 65, 248, 44, 253, 144, 153, 86, 236, 164, 77, 65, 248, 44, 253, 144, 
+    153, 86, 236, 164, 242, 223, 248, 56, 19, 242, 228, 248, 43, 56, 242, 
+    223, 248, 43, 19, 242, 228, 248, 56, 56, 242, 223, 248, 56, 65, 2, 90, 
+    242, 223, 248, 43, 65, 2, 90, 242, 228, 248, 43, 65, 2, 90, 242, 228, 
+    248, 56, 65, 2, 90, 242, 223, 248, 56, 65, 19, 242, 223, 248, 43, 56, 
+    242, 223, 248, 43, 65, 19, 242, 228, 248, 43, 56, 242, 228, 248, 43, 65, 
+    19, 242, 228, 248, 56, 56, 242, 228, 248, 56, 65, 19, 242, 223, 248, 56, 
+    56, 240, 69, 236, 159, 236, 185, 238, 105, 235, 86, 238, 105, 236, 159, 
+    236, 185, 240, 69, 235, 86, 242, 228, 248, 43, 65, 236, 185, 242, 223, 
+    248, 43, 56, 242, 223, 248, 43, 65, 236, 185, 242, 228, 248, 43, 56, 238, 
+    105, 236, 159, 236, 185, 242, 223, 248, 43, 56, 240, 69, 236, 159, 236, 
+    185, 242, 228, 248, 43, 56, 242, 223, 248, 43, 65, 236, 185, 242, 223, 
+    248, 56, 56, 242, 223, 248, 56, 65, 236, 185, 242, 223, 248, 43, 56, 248, 
+    141, 65, 236, 150, 237, 111, 225, 65, 236, 150, 77, 248, 187, 238, 111, 
+    236, 206, 65, 236, 150, 77, 248, 187, 238, 111, 234, 9, 65, 236, 150, 
+    235, 45, 248, 187, 238, 111, 234, 18, 65, 236, 150, 235, 45, 248, 187, 
+    238, 111, 233, 63, 234, 250, 253, 183, 235, 62, 56, 236, 50, 253, 183, 
+    231, 86, 56, 253, 159, 253, 183, 231, 86, 56, 240, 17, 253, 183, 231, 86, 
+    56, 253, 159, 253, 183, 235, 62, 65, 2, 240, 68, 253, 159, 253, 183, 231, 
+    86, 65, 2, 243, 12, 168, 38, 232, 98, 235, 62, 56, 168, 40, 232, 98, 231, 
+    86, 56, 231, 86, 240, 23, 218, 56, 235, 62, 240, 23, 218, 56, 77, 65, 60, 
+    242, 215, 139, 56, 139, 65, 60, 242, 215, 77, 56, 242, 215, 77, 65, 60, 
+    139, 56, 77, 65, 2, 248, 49, 46, 139, 65, 2, 248, 49, 46, 77, 65, 238, 
+    108, 206, 40, 38, 65, 238, 108, 3, 238, 51, 226, 226, 234, 16, 65, 248, 
+    44, 3, 238, 51, 40, 154, 88, 38, 154, 92, 236, 175, 40, 154, 92, 38, 154, 
+    88, 236, 175, 88, 154, 38, 92, 154, 40, 236, 175, 88, 154, 40, 92, 154, 
+    38, 236, 175, 40, 154, 88, 38, 154, 88, 236, 175, 88, 154, 38, 92, 154, 
+    38, 236, 175, 40, 154, 92, 38, 154, 92, 236, 175, 88, 154, 40, 92, 154, 
+    40, 236, 175, 139, 186, 2, 154, 88, 153, 125, 77, 186, 2, 154, 88, 153, 
+    125, 226, 226, 186, 2, 154, 38, 153, 125, 235, 45, 186, 2, 154, 38, 153, 
+    125, 139, 186, 2, 154, 92, 153, 125, 77, 186, 2, 154, 92, 153, 125, 226, 
+    226, 186, 2, 154, 40, 153, 125, 235, 45, 186, 2, 154, 40, 153, 125, 139, 
+    186, 2, 154, 88, 248, 44, 125, 77, 186, 2, 154, 88, 248, 44, 125, 226, 
+    226, 186, 2, 154, 38, 248, 44, 125, 235, 45, 186, 2, 154, 38, 248, 44, 
+    125, 139, 186, 2, 154, 92, 248, 44, 125, 77, 186, 2, 154, 92, 248, 44, 
+    125, 226, 226, 186, 2, 154, 40, 248, 44, 125, 235, 45, 186, 2, 154, 40, 
+    248, 44, 125, 139, 186, 2, 154, 88, 60, 139, 186, 2, 154, 242, 236, 226, 
+    226, 186, 2, 154, 40, 240, 45, 226, 226, 186, 2, 154, 225, 77, 186, 2, 
+    154, 88, 60, 77, 186, 2, 154, 242, 236, 235, 45, 186, 2, 154, 40, 240, 
+    45, 235, 45, 186, 2, 154, 225, 139, 186, 2, 154, 88, 60, 77, 186, 2, 154, 
+    253, 176, 139, 186, 2, 154, 92, 60, 77, 186, 2, 154, 242, 236, 77, 186, 
+    2, 154, 88, 60, 139, 186, 2, 154, 253, 176, 77, 186, 2, 154, 92, 60, 139, 
+    186, 2, 154, 242, 236, 139, 186, 2, 154, 88, 60, 183, 242, 235, 139, 186, 
+    2, 154, 92, 242, 230, 183, 242, 235, 77, 186, 2, 154, 88, 60, 183, 242, 
+    235, 77, 186, 2, 154, 92, 242, 230, 183, 242, 235, 226, 226, 186, 2, 154, 
+    40, 240, 45, 235, 45, 186, 2, 154, 225, 235, 45, 186, 2, 154, 40, 240, 
+    45, 226, 226, 186, 2, 154, 225, 38, 45, 65, 2, 238, 121, 243, 99, 240, 7, 
+    21, 60, 77, 56, 242, 219, 236, 208, 60, 77, 56, 139, 65, 60, 242, 219, 
+    235, 47, 77, 65, 60, 242, 219, 235, 47, 77, 65, 60, 240, 40, 95, 87, 235, 
+    44, 60, 139, 56, 139, 65, 238, 108, 234, 3, 232, 68, 60, 77, 56, 240, 26, 
+    60, 77, 56, 139, 65, 238, 108, 238, 87, 236, 154, 60, 139, 56, 40, 248, 
+    157, 242, 226, 38, 248, 157, 242, 226, 88, 248, 157, 242, 226, 92, 248, 
+    157, 242, 226, 240, 3, 59, 253, 144, 234, 35, 255, 97, 126, 247, 97, 255, 
+    97, 126, 249, 9, 240, 24, 40, 64, 242, 225, 104, 38, 64, 242, 225, 104, 
+    40, 64, 232, 74, 38, 64, 232, 74, 255, 97, 126, 40, 243, 11, 104, 255, 
+    97, 126, 38, 243, 11, 104, 255, 97, 126, 40, 238, 166, 104, 255, 97, 126, 
+    38, 238, 166, 104, 40, 31, 238, 52, 2, 235, 50, 38, 31, 238, 52, 2, 235, 
+    50, 40, 31, 238, 52, 2, 248, 188, 255, 22, 253, 159, 238, 67, 38, 31, 
+    238, 52, 2, 248, 188, 255, 22, 240, 17, 238, 67, 40, 31, 238, 52, 2, 248, 
+    188, 255, 22, 240, 17, 238, 67, 38, 31, 238, 52, 2, 248, 188, 255, 22, 
+    253, 159, 238, 67, 40, 185, 238, 52, 2, 248, 40, 38, 185, 238, 52, 2, 
+    248, 40, 40, 253, 183, 235, 44, 104, 38, 253, 183, 232, 68, 104, 45, 40, 
+    253, 183, 232, 68, 104, 45, 38, 253, 183, 235, 44, 104, 40, 86, 236, 171, 
+    242, 255, 104, 38, 86, 236, 171, 242, 255, 104, 240, 4, 240, 97, 59, 240, 
+    126, 242, 224, 236, 168, 185, 238, 96, 242, 220, 38, 185, 239, 240, 2, 
+    238, 59, 236, 168, 38, 185, 2, 248, 40, 185, 2, 255, 99, 238, 94, 242, 
+    241, 240, 54, 235, 109, 185, 238, 96, 242, 220, 235, 109, 185, 238, 96, 
+    253, 176, 205, 240, 54, 224, 240, 54, 185, 2, 235, 50, 224, 185, 2, 235, 
+    50, 238, 106, 185, 238, 96, 253, 176, 238, 106, 185, 238, 96, 242, 236, 
+    236, 168, 185, 2, 248, 35, 253, 229, 240, 63, 255, 22, 65, 236, 150, 88, 
+    19, 225, 236, 168, 185, 2, 248, 35, 253, 229, 240, 63, 255, 22, 65, 236, 
+    150, 88, 19, 242, 220, 236, 168, 185, 2, 248, 35, 253, 229, 240, 63, 255, 
+    22, 65, 236, 150, 92, 19, 225, 236, 168, 185, 2, 248, 35, 253, 229, 240, 
+    63, 255, 22, 65, 236, 150, 92, 19, 242, 220, 236, 168, 185, 2, 248, 35, 
+    253, 229, 240, 63, 255, 22, 65, 236, 150, 38, 19, 253, 176, 236, 168, 
+    185, 2, 248, 35, 253, 229, 240, 63, 255, 22, 65, 236, 150, 40, 19, 253, 
+    176, 236, 168, 185, 2, 248, 35, 253, 229, 240, 63, 255, 22, 65, 236, 150, 
+    38, 19, 242, 236, 236, 168, 185, 2, 248, 35, 253, 229, 240, 63, 255, 22, 
+    65, 236, 150, 40, 19, 242, 236, 224, 243, 15, 249, 160, 243, 15, 254, 30, 
+    2, 236, 163, 243, 15, 254, 30, 2, 3, 218, 48, 243, 15, 254, 30, 2, 38, 
+    65, 48, 243, 15, 254, 30, 2, 40, 65, 48, 218, 2, 163, 125, 29, 59, 125, 
+    29, 235, 105, 29, 238, 75, 236, 177, 29, 231, 49, 218, 238, 135, 255, 25, 
+    163, 253, 144, 19, 253, 159, 137, 238, 135, 255, 25, 59, 125, 218, 2, 
+    233, 39, 206, 29, 226, 231, 236, 196, 52, 88, 65, 238, 108, 238, 51, 29, 
+    64, 238, 69, 29, 238, 69, 29, 234, 3, 29, 231, 85, 218, 2, 3, 218, 153, 
+    253, 145, 225, 218, 2, 171, 163, 239, 207, 153, 253, 145, 225, 238, 84, 
+    240, 69, 236, 159, 240, 37, 238, 84, 238, 105, 236, 159, 240, 37, 238, 
+    84, 235, 52, 238, 84, 3, 238, 51, 238, 84, 238, 59, 171, 240, 116, 238, 
+    12, 236, 152, 2, 53, 48, 236, 152, 2, 235, 50, 255, 99, 255, 22, 235, 46, 
+    236, 152, 2, 240, 220, 255, 31, 238, 128, 38, 236, 152, 60, 40, 235, 46, 
+    40, 236, 152, 240, 45, 59, 125, 59, 253, 144, 240, 45, 38, 235, 46, 240, 
+    161, 2, 40, 137, 240, 0, 240, 161, 2, 38, 137, 240, 0, 86, 238, 168, 243, 
+    48, 2, 40, 137, 240, 0, 243, 48, 2, 38, 137, 240, 0, 64, 234, 39, 86, 
+    234, 39, 40, 240, 125, 240, 97, 38, 240, 125, 240, 97, 40, 45, 240, 125, 
+    240, 97, 38, 45, 240, 125, 240, 97, 234, 204, 235, 101, 254, 248, 248, 
+    59, 235, 101, 237, 180, 238, 203, 2, 59, 125, 232, 162, 235, 103, 31, 2, 
+    235, 194, 237, 229, 236, 40, 254, 143, 239, 195, 236, 170, 240, 7, 21, 
+    19, 238, 58, 235, 105, 240, 7, 21, 19, 238, 58, 236, 200, 2, 242, 219, 
+    48, 235, 89, 153, 19, 238, 58, 235, 105, 241, 138, 242, 132, 231, 83, 
+    231, 91, 236, 152, 2, 40, 137, 240, 0, 231, 91, 236, 152, 2, 38, 137, 
+    240, 0, 86, 238, 76, 2, 92, 56, 86, 236, 231, 64, 218, 2, 92, 56, 86, 
+    218, 2, 92, 56, 232, 78, 64, 238, 59, 232, 78, 86, 238, 59, 232, 78, 64, 
+    236, 164, 232, 78, 86, 236, 164, 232, 78, 64, 238, 51, 232, 78, 86, 238, 
+    51, 231, 152, 238, 75, 238, 83, 235, 47, 238, 83, 2, 236, 163, 238, 75, 
+    238, 83, 2, 163, 108, 253, 213, 236, 177, 253, 213, 238, 75, 236, 177, 
+    45, 243, 12, 240, 3, 243, 12, 231, 87, 240, 95, 185, 104, 231, 36, 240, 
+    95, 185, 104, 247, 152, 246, 87, 242, 238, 29, 53, 235, 47, 242, 238, 29, 
+    248, 49, 235, 47, 242, 238, 29, 243, 48, 235, 47, 242, 238, 243, 2, 236, 
+    208, 2, 248, 40, 242, 238, 243, 2, 236, 208, 2, 243, 12, 242, 238, 31, 
+    232, 76, 235, 47, 242, 238, 31, 243, 2, 235, 47, 171, 238, 56, 19, 235, 
+    47, 171, 238, 56, 128, 235, 47, 242, 238, 243, 48, 235, 47, 241, 247, 
+    171, 252, 192, 235, 112, 2, 235, 60, 235, 71, 236, 167, 235, 47, 241, 
+    110, 249, 134, 235, 60, 236, 167, 2, 45, 108, 236, 167, 238, 255, 2, 240, 
+    37, 233, 122, 236, 29, 231, 86, 232, 177, 248, 41, 233, 70, 2, 233, 97, 
+    249, 135, 240, 127, 243, 116, 248, 41, 233, 70, 2, 232, 98, 249, 135, 
+    240, 127, 243, 116, 248, 41, 233, 70, 161, 236, 39, 253, 145, 243, 116, 
+    236, 167, 240, 127, 134, 242, 232, 235, 47, 234, 242, 236, 167, 235, 47, 
+    236, 167, 2, 139, 65, 2, 90, 236, 167, 2, 243, 48, 52, 236, 167, 2, 231, 
+    88, 236, 167, 2, 240, 58, 236, 167, 2, 236, 163, 236, 167, 2, 235, 50, 
+    243, 61, 243, 22, 40, 236, 152, 235, 47, 255, 97, 126, 240, 144, 232, 
+    104, 255, 97, 126, 240, 144, 239, 162, 255, 97, 126, 240, 144, 233, 225, 
+    248, 49, 21, 2, 3, 218, 48, 248, 49, 21, 2, 190, 240, 2, 48, 248, 49, 21, 
+    2, 242, 219, 48, 248, 49, 21, 2, 53, 46, 248, 49, 21, 2, 242, 219, 46, 
+    248, 49, 21, 2, 235, 48, 111, 248, 49, 21, 2, 86, 235, 46, 242, 250, 21, 
+    2, 242, 244, 48, 242, 250, 21, 2, 53, 46, 242, 250, 21, 2, 238, 105, 243, 
+    5, 242, 250, 21, 2, 240, 69, 243, 5, 248, 49, 21, 255, 22, 40, 137, 238, 
+    51, 248, 49, 21, 255, 22, 38, 137, 238, 51, 242, 176, 128, 243, 38, 236, 
+    170, 231, 37, 21, 2, 53, 48, 231, 37, 21, 2, 235, 50, 234, 21, 239, 167, 
+    2, 240, 17, 239, 29, 244, 20, 236, 170, 231, 37, 21, 255, 22, 40, 137, 
+    238, 51, 231, 37, 21, 255, 22, 38, 137, 238, 51, 29, 231, 37, 21, 2, 190, 
+    238, 54, 231, 37, 21, 255, 22, 45, 238, 51, 29, 236, 196, 52, 248, 49, 
+    21, 255, 22, 235, 46, 242, 250, 21, 255, 22, 235, 46, 231, 37, 21, 255, 
+    22, 235, 46, 237, 14, 236, 170, 236, 93, 237, 14, 236, 170, 255, 97, 126, 
+    234, 246, 232, 104, 232, 115, 128, 234, 50, 232, 76, 2, 248, 40, 243, 2, 
+    2, 242, 250, 52, 243, 2, 2, 236, 163, 232, 76, 2, 236, 163, 232, 76, 2, 
+    238, 56, 248, 91, 243, 2, 2, 238, 56, 253, 227, 243, 2, 60, 231, 88, 232, 
+    76, 60, 240, 58, 243, 2, 60, 253, 144, 60, 231, 88, 232, 76, 60, 253, 
+    144, 60, 240, 58, 243, 2, 240, 45, 19, 240, 116, 2, 240, 58, 232, 76, 
+    240, 45, 19, 240, 116, 2, 231, 88, 240, 23, 243, 2, 2, 238, 214, 240, 23, 
+    232, 76, 2, 238, 214, 45, 31, 231, 88, 45, 31, 240, 58, 240, 23, 243, 2, 
+    2, 240, 220, 19, 244, 20, 236, 170, 238, 56, 19, 2, 53, 48, 238, 56, 128, 
+    2, 53, 48, 45, 238, 56, 248, 91, 45, 238, 56, 253, 227, 171, 232, 105, 
+    238, 56, 248, 91, 171, 232, 105, 238, 56, 253, 227, 238, 217, 243, 22, 
+    253, 227, 238, 217, 243, 22, 248, 91, 238, 56, 128, 233, 91, 238, 56, 
+    248, 91, 238, 56, 19, 2, 240, 1, 243, 46, 238, 56, 128, 2, 240, 1, 243, 
+    46, 238, 56, 19, 2, 163, 242, 235, 238, 56, 128, 2, 163, 242, 235, 238, 
+    56, 19, 2, 45, 236, 163, 238, 56, 19, 2, 235, 50, 238, 56, 19, 2, 45, 
+    235, 50, 3, 254, 255, 2, 235, 50, 238, 56, 128, 2, 45, 236, 163, 238, 56, 
+    128, 2, 45, 235, 50, 255, 97, 126, 241, 87, 227, 10, 255, 97, 126, 247, 
+    28, 227, 10, 240, 7, 21, 2, 53, 46, 235, 89, 2, 53, 48, 240, 3, 163, 253, 
+    144, 2, 45, 59, 108, 240, 3, 163, 253, 144, 2, 240, 3, 59, 108, 242, 219, 
+    236, 208, 2, 53, 48, 242, 219, 236, 208, 2, 240, 69, 243, 5, 238, 81, 
+    242, 250, 238, 5, 235, 192, 2, 53, 48, 240, 7, 2, 235, 52, 240, 40, 95, 
+    153, 2, 190, 238, 54, 231, 89, 95, 128, 95, 87, 240, 7, 21, 60, 248, 49, 
+    52, 248, 49, 21, 60, 240, 7, 52, 240, 7, 21, 60, 242, 219, 235, 47, 45, 
+    243, 14, 240, 32, 171, 233, 82, 240, 7, 240, 232, 204, 233, 82, 240, 7, 
+    240, 232, 240, 7, 21, 2, 171, 181, 60, 19, 171, 181, 46, 234, 5, 2, 248, 
+    58, 181, 48, 235, 44, 2, 218, 238, 94, 232, 68, 2, 218, 238, 94, 235, 44, 
+    2, 236, 156, 158, 48, 232, 68, 2, 236, 156, 158, 48, 235, 44, 128, 238, 
+    58, 95, 87, 232, 68, 128, 238, 58, 95, 87, 235, 44, 128, 238, 58, 95, 
+    153, 2, 53, 238, 94, 232, 68, 128, 238, 58, 95, 153, 2, 53, 238, 94, 235, 
+    44, 128, 238, 58, 95, 153, 2, 53, 48, 232, 68, 128, 238, 58, 95, 153, 2, 
+    53, 48, 235, 44, 128, 238, 58, 95, 153, 2, 53, 60, 225, 232, 68, 128, 
+    238, 58, 95, 153, 2, 53, 60, 242, 220, 235, 44, 128, 232, 81, 232, 68, 
+    128, 232, 81, 235, 44, 19, 233, 61, 161, 95, 87, 232, 68, 19, 233, 61, 
+    161, 95, 87, 235, 44, 19, 161, 232, 81, 232, 68, 19, 161, 232, 81, 235, 
+    44, 60, 233, 57, 95, 60, 231, 85, 232, 68, 60, 233, 57, 95, 60, 234, 3, 
+    235, 44, 60, 238, 81, 128, 240, 32, 232, 68, 60, 238, 81, 128, 240, 32, 
+    235, 44, 60, 238, 81, 60, 231, 85, 232, 68, 60, 238, 81, 60, 234, 3, 235, 
+    44, 60, 232, 68, 60, 233, 57, 240, 32, 232, 68, 60, 235, 44, 60, 233, 57, 
+    240, 32, 235, 44, 60, 238, 58, 95, 60, 232, 68, 60, 238, 58, 240, 32, 
+    232, 68, 60, 238, 58, 95, 60, 235, 44, 60, 238, 58, 240, 32, 238, 58, 95, 
+    153, 128, 234, 3, 238, 58, 95, 153, 128, 231, 85, 238, 58, 95, 153, 128, 
+    235, 44, 2, 53, 238, 94, 238, 58, 95, 153, 128, 232, 68, 2, 53, 238, 94, 
+    233, 57, 95, 153, 128, 234, 3, 233, 57, 95, 153, 128, 231, 85, 233, 57, 
+    238, 58, 95, 153, 128, 234, 3, 233, 57, 238, 58, 95, 153, 128, 231, 85, 
+    238, 81, 128, 234, 3, 238, 81, 128, 231, 85, 238, 81, 60, 235, 44, 60, 
+    240, 7, 52, 238, 81, 60, 232, 68, 60, 240, 7, 52, 45, 240, 102, 234, 3, 
+    45, 240, 102, 231, 85, 45, 240, 102, 235, 44, 2, 235, 50, 232, 68, 233, 
+    91, 234, 3, 232, 68, 240, 45, 234, 3, 235, 44, 240, 23, 255, 25, 240, 
+    163, 232, 68, 240, 23, 255, 25, 240, 163, 235, 44, 240, 23, 255, 25, 243, 
+    158, 60, 238, 58, 240, 32, 232, 68, 240, 23, 255, 25, 243, 158, 60, 238, 
+    58, 240, 32, 238, 218, 243, 127, 240, 196, 243, 127, 238, 218, 249, 1, 
+    128, 95, 87, 240, 196, 249, 1, 128, 95, 87, 240, 7, 21, 2, 244, 232, 48, 
+    236, 176, 60, 233, 61, 240, 7, 52, 236, 178, 60, 233, 61, 240, 7, 52, 
+    236, 176, 60, 233, 61, 161, 95, 87, 236, 178, 60, 233, 61, 161, 95, 87, 
+    236, 176, 60, 240, 7, 52, 236, 178, 60, 240, 7, 52, 236, 176, 60, 161, 
+    95, 87, 236, 178, 60, 161, 95, 87, 236, 176, 60, 240, 40, 95, 87, 236, 
+    178, 60, 240, 40, 95, 87, 236, 176, 60, 161, 240, 40, 95, 87, 236, 178, 
+    60, 161, 240, 40, 95, 87, 45, 235, 107, 45, 235, 111, 240, 26, 2, 248, 
+    40, 236, 154, 2, 248, 40, 240, 26, 2, 248, 49, 21, 46, 236, 154, 2, 248, 
+    49, 21, 46, 240, 26, 2, 231, 37, 21, 46, 236, 154, 2, 231, 37, 21, 46, 
+    240, 26, 147, 128, 95, 153, 2, 53, 48, 236, 154, 147, 128, 95, 153, 2, 
+    53, 48, 240, 26, 147, 60, 240, 7, 52, 236, 154, 147, 60, 240, 7, 52, 240, 
+    26, 147, 60, 242, 219, 235, 47, 236, 154, 147, 60, 242, 219, 235, 47, 
+    240, 26, 147, 60, 240, 40, 95, 87, 236, 154, 147, 60, 240, 40, 95, 87, 
+    240, 26, 147, 60, 161, 95, 87, 236, 154, 147, 60, 161, 95, 87, 31, 40, 
+    248, 35, 66, 235, 47, 31, 38, 248, 35, 66, 235, 47, 240, 23, 238, 87, 
+    240, 23, 235, 84, 240, 23, 240, 26, 128, 95, 87, 240, 23, 236, 154, 128, 
+    95, 87, 240, 26, 60, 235, 84, 236, 154, 60, 238, 87, 240, 26, 60, 238, 
+    87, 236, 154, 60, 235, 84, 236, 154, 240, 45, 238, 87, 236, 154, 240, 45, 
+    19, 240, 116, 255, 25, 248, 63, 2, 238, 87, 238, 68, 147, 238, 96, 234, 
+    9, 236, 75, 2, 254, 246, 249, 3, 233, 254, 231, 88, 237, 160, 233, 220, 
+    242, 215, 40, 242, 234, 242, 215, 92, 242, 234, 242, 215, 88, 242, 234, 
+    231, 151, 2, 193, 59, 253, 144, 240, 3, 38, 234, 15, 45, 59, 253, 144, 
+    40, 234, 15, 59, 253, 144, 45, 40, 234, 15, 45, 59, 253, 144, 45, 40, 
+    234, 15, 183, 248, 63, 248, 44, 40, 241, 234, 147, 45, 235, 63, 242, 215, 
+    92, 248, 84, 2, 236, 163, 242, 215, 88, 248, 84, 2, 235, 50, 242, 215, 
+    88, 248, 84, 60, 242, 215, 92, 242, 234, 45, 92, 242, 234, 45, 88, 242, 
+    234, 45, 240, 5, 161, 52, 224, 45, 240, 5, 161, 52, 248, 86, 161, 241, 
+    86, 2, 224, 237, 217, 240, 37, 59, 248, 41, 2, 218, 48, 59, 248, 41, 2, 
+    218, 46, 92, 248, 84, 2, 218, 46, 236, 200, 2, 163, 108, 236, 200, 2, 
+    242, 219, 235, 47, 240, 3, 59, 253, 144, 240, 159, 235, 92, 240, 3, 59, 
+    253, 144, 2, 163, 108, 240, 3, 243, 14, 235, 47, 240, 3, 240, 102, 234, 
+    3, 240, 3, 240, 102, 231, 85, 233, 57, 238, 58, 235, 44, 128, 95, 87, 
+    233, 57, 238, 58, 232, 68, 128, 95, 87, 240, 3, 238, 83, 240, 159, 235, 
+    92, 243, 22, 240, 3, 59, 253, 144, 235, 47, 45, 238, 83, 235, 47, 64, 59, 
+    125, 242, 238, 64, 59, 125, 242, 223, 248, 43, 64, 56, 242, 223, 248, 56, 
+    64, 56, 242, 228, 248, 43, 64, 56, 242, 228, 248, 56, 64, 56, 40, 38, 64, 
+    56, 139, 86, 56, 226, 226, 86, 56, 235, 45, 86, 56, 242, 223, 248, 43, 
+    86, 56, 242, 223, 248, 56, 86, 56, 242, 228, 248, 43, 86, 56, 242, 228, 
+    248, 56, 86, 56, 40, 38, 86, 56, 88, 92, 86, 56, 77, 65, 2, 253, 241, 
+    234, 9, 77, 65, 2, 253, 241, 236, 206, 139, 65, 2, 253, 241, 234, 9, 139, 
+    65, 2, 253, 241, 236, 206, 31, 2, 253, 159, 137, 240, 0, 31, 2, 240, 17, 
+    137, 240, 0, 98, 5, 1, 249, 29, 98, 5, 1, 243, 152, 98, 5, 1, 244, 45, 
+    98, 5, 1, 237, 12, 98, 5, 1, 240, 170, 98, 5, 1, 240, 254, 98, 5, 1, 237, 
+    52, 98, 5, 1, 240, 171, 98, 5, 1, 238, 235, 98, 5, 1, 243, 60, 98, 5, 1, 
+    54, 243, 60, 98, 5, 1, 71, 98, 5, 1, 238, 178, 98, 5, 1, 243, 204, 98, 5, 
+    1, 237, 21, 98, 5, 1, 236, 216, 98, 5, 1, 240, 202, 98, 5, 1, 249, 131, 
+    98, 5, 1, 238, 210, 98, 5, 1, 240, 217, 98, 5, 1, 240, 235, 98, 5, 1, 
+    238, 230, 98, 5, 1, 249, 190, 98, 5, 1, 240, 177, 98, 5, 1, 243, 193, 98, 
+    5, 1, 249, 132, 98, 5, 1, 253, 175, 98, 5, 1, 244, 14, 98, 5, 1, 248, 
+    140, 98, 5, 1, 238, 170, 98, 5, 1, 248, 46, 98, 5, 1, 243, 83, 98, 5, 1, 
+    244, 57, 98, 5, 1, 244, 56, 98, 5, 1, 238, 221, 219, 98, 5, 1, 253, 161, 
+    98, 5, 1, 3, 248, 74, 98, 5, 1, 3, 254, 136, 2, 242, 226, 98, 5, 1, 253, 
+    162, 98, 5, 1, 238, 117, 3, 248, 74, 98, 5, 1, 253, 213, 248, 74, 98, 5, 
+    1, 238, 117, 253, 213, 248, 74, 98, 5, 1, 243, 57, 98, 5, 1, 236, 215, 
+    98, 5, 1, 237, 40, 98, 5, 1, 234, 87, 67, 98, 5, 1, 237, 19, 236, 216, 
+    98, 3, 1, 249, 29, 98, 3, 1, 243, 152, 98, 3, 1, 244, 45, 98, 3, 1, 237, 
+    12, 98, 3, 1, 240, 170, 98, 3, 1, 240, 254, 98, 3, 1, 237, 52, 98, 3, 1, 
+    240, 171, 98, 3, 1, 238, 235, 98, 3, 1, 243, 60, 98, 3, 1, 54, 243, 60, 
+    98, 3, 1, 71, 98, 3, 1, 238, 178, 98, 3, 1, 243, 204, 98, 3, 1, 237, 21, 
+    98, 3, 1, 236, 216, 98, 3, 1, 240, 202, 98, 3, 1, 249, 131, 98, 3, 1, 
+    238, 210, 98, 3, 1, 240, 217, 98, 3, 1, 240, 235, 98, 3, 1, 238, 230, 98, 
+    3, 1, 249, 190, 98, 3, 1, 240, 177, 98, 3, 1, 243, 193, 98, 3, 1, 249, 
+    132, 98, 3, 1, 253, 175, 98, 3, 1, 244, 14, 98, 3, 1, 248, 140, 98, 3, 1, 
+    238, 170, 98, 3, 1, 248, 46, 98, 3, 1, 243, 83, 98, 3, 1, 244, 57, 98, 3, 
+    1, 244, 56, 98, 3, 1, 238, 221, 219, 98, 3, 1, 253, 161, 98, 3, 1, 3, 
+    248, 74, 98, 3, 1, 3, 254, 136, 2, 242, 226, 98, 3, 1, 253, 162, 98, 3, 
+    1, 238, 117, 3, 248, 74, 98, 3, 1, 253, 213, 248, 74, 98, 3, 1, 238, 117, 
+    253, 213, 248, 74, 98, 3, 1, 243, 57, 98, 3, 1, 236, 215, 98, 3, 1, 237, 
+    40, 98, 3, 1, 234, 87, 67, 98, 3, 1, 237, 19, 236, 216, 62, 5, 1, 243, 
+    141, 62, 3, 1, 243, 141, 62, 5, 1, 244, 47, 62, 3, 1, 244, 47, 62, 5, 1, 
+    240, 10, 62, 3, 1, 240, 10, 62, 5, 1, 240, 164, 62, 3, 1, 240, 164, 62, 
+    5, 1, 248, 154, 62, 3, 1, 248, 154, 62, 5, 1, 249, 167, 62, 3, 1, 249, 
+    167, 62, 5, 1, 244, 65, 62, 3, 1, 244, 65, 62, 5, 1, 243, 190, 62, 3, 1, 
+    243, 190, 62, 5, 1, 238, 226, 62, 3, 1, 238, 226, 62, 5, 1, 240, 191, 62, 
+    3, 1, 240, 191, 62, 5, 1, 243, 62, 62, 3, 1, 243, 62, 62, 5, 1, 240, 197, 
+    62, 3, 1, 240, 197, 62, 5, 1, 253, 180, 62, 3, 1, 253, 180, 62, 5, 1, 
+    253, 166, 62, 3, 1, 253, 166, 62, 5, 1, 248, 163, 62, 3, 1, 248, 163, 62, 
+    5, 1, 73, 62, 3, 1, 73, 62, 5, 1, 253, 147, 62, 3, 1, 253, 147, 62, 5, 1, 
+    253, 160, 62, 3, 1, 253, 160, 62, 5, 1, 243, 123, 62, 3, 1, 243, 123, 62, 
+    5, 1, 248, 85, 62, 3, 1, 248, 85, 62, 5, 1, 254, 74, 62, 3, 1, 254, 74, 
+    62, 5, 1, 253, 245, 62, 3, 1, 253, 245, 62, 5, 1, 248, 219, 62, 3, 1, 
+    248, 219, 62, 5, 1, 248, 69, 62, 3, 1, 248, 69, 62, 5, 1, 248, 179, 62, 
+    3, 1, 248, 179, 62, 5, 1, 235, 67, 243, 3, 62, 3, 1, 235, 67, 243, 3, 62, 
+    5, 1, 76, 62, 248, 105, 62, 3, 1, 76, 62, 248, 105, 62, 5, 1, 231, 93, 
+    248, 154, 62, 3, 1, 231, 93, 248, 154, 62, 5, 1, 235, 67, 243, 62, 62, 3, 
+    1, 235, 67, 243, 62, 62, 5, 1, 235, 67, 253, 166, 62, 3, 1, 235, 67, 253, 
+    166, 62, 5, 1, 231, 93, 253, 166, 62, 3, 1, 231, 93, 253, 166, 62, 5, 1, 
+    76, 62, 248, 179, 62, 3, 1, 76, 62, 248, 179, 62, 5, 1, 240, 121, 62, 3, 
+    1, 240, 121, 62, 5, 1, 238, 133, 243, 32, 62, 3, 1, 238, 133, 243, 32, 
+    62, 5, 1, 76, 62, 243, 32, 62, 3, 1, 76, 62, 243, 32, 62, 5, 1, 76, 62, 
+    248, 93, 62, 3, 1, 76, 62, 248, 93, 62, 5, 1, 236, 245, 243, 64, 62, 3, 
+    1, 236, 245, 243, 64, 62, 5, 1, 235, 67, 243, 28, 62, 3, 1, 235, 67, 243, 
+    28, 62, 5, 1, 76, 62, 243, 28, 62, 3, 1, 76, 62, 243, 28, 62, 5, 1, 76, 
+    62, 219, 62, 3, 1, 76, 62, 219, 62, 5, 1, 237, 18, 219, 62, 3, 1, 237, 
+    18, 219, 62, 5, 1, 76, 62, 249, 81, 62, 3, 1, 76, 62, 249, 81, 62, 5, 1, 
+    76, 62, 248, 214, 62, 3, 1, 76, 62, 248, 214, 62, 5, 1, 76, 62, 238, 115, 
+    62, 3, 1, 76, 62, 238, 115, 62, 5, 1, 76, 62, 249, 54, 62, 3, 1, 76, 62, 
+    249, 54, 62, 5, 1, 76, 62, 240, 88, 62, 3, 1, 76, 62, 240, 88, 62, 5, 1, 
+    76, 240, 43, 240, 88, 62, 3, 1, 76, 240, 43, 240, 88, 62, 5, 1, 76, 240, 
+    43, 248, 232, 62, 3, 1, 76, 240, 43, 248, 232, 62, 5, 1, 76, 240, 43, 
+    248, 178, 62, 3, 1, 76, 240, 43, 248, 178, 62, 5, 1, 76, 240, 43, 249, 
+    198, 62, 3, 1, 76, 240, 43, 249, 198, 62, 12, 249, 91, 62, 12, 255, 82, 
+    253, 160, 62, 12, 255, 29, 253, 160, 62, 12, 238, 13, 62, 12, 254, 244, 
+    253, 160, 62, 12, 254, 184, 253, 160, 62, 12, 247, 74, 243, 123, 62, 76, 
+    240, 43, 248, 37, 208, 62, 76, 240, 43, 240, 169, 236, 156, 69, 62, 76, 
+    240, 43, 237, 179, 236, 156, 69, 62, 76, 240, 43, 244, 46, 236, 213, 62, 
+    236, 155, 253, 125, 243, 7, 62, 248, 37, 208, 62, 231, 149, 236, 213, 75, 
+    3, 1, 254, 19, 75, 3, 1, 248, 195, 75, 3, 1, 248, 158, 75, 3, 1, 248, 
+    205, 75, 3, 1, 253, 202, 75, 3, 1, 249, 11, 75, 3, 1, 249, 25, 75, 3, 1, 
+    248, 253, 75, 3, 1, 253, 247, 75, 3, 1, 248, 162, 75, 3, 1, 248, 224, 75, 
+    3, 1, 248, 131, 75, 3, 1, 248, 171, 75, 3, 1, 254, 9, 75, 3, 1, 248, 236, 
+    75, 3, 1, 243, 138, 75, 3, 1, 248, 243, 75, 3, 1, 248, 134, 75, 3, 1, 
+    248, 254, 75, 3, 1, 254, 75, 75, 3, 1, 243, 115, 75, 3, 1, 243, 103, 75, 
+    3, 1, 243, 95, 75, 3, 1, 248, 242, 75, 3, 1, 243, 33, 75, 3, 1, 243, 88, 
+    75, 3, 1, 248, 100, 75, 3, 1, 248, 217, 75, 3, 1, 248, 201, 75, 3, 1, 
+    243, 87, 75, 3, 1, 249, 16, 75, 3, 1, 243, 101, 75, 3, 1, 248, 212, 75, 
+    3, 1, 253, 168, 75, 3, 1, 248, 160, 75, 3, 1, 253, 170, 75, 3, 1, 248, 
+    213, 75, 3, 1, 248, 215, 174, 1, 216, 174, 1, 253, 65, 174, 1, 247, 213, 
+    174, 1, 253, 68, 174, 1, 242, 193, 174, 1, 240, 158, 238, 157, 249, 202, 
+    174, 1, 249, 202, 174, 1, 253, 66, 174, 1, 247, 216, 174, 1, 247, 215, 
+    174, 1, 242, 192, 174, 1, 253, 79, 174, 1, 253, 67, 174, 1, 249, 20, 174, 
+    1, 240, 66, 249, 20, 174, 1, 242, 194, 174, 1, 249, 19, 174, 1, 240, 158, 
+    238, 157, 249, 19, 174, 1, 240, 66, 249, 19, 174, 1, 247, 218, 174, 1, 
+    248, 191, 174, 1, 244, 55, 174, 1, 240, 66, 244, 55, 174, 1, 249, 204, 
+    174, 1, 240, 66, 249, 204, 174, 1, 253, 189, 174, 1, 243, 135, 174, 1, 
+    238, 239, 243, 135, 174, 1, 240, 66, 243, 135, 174, 1, 253, 69, 174, 1, 
+    253, 70, 174, 1, 249, 203, 174, 1, 240, 66, 247, 217, 174, 1, 240, 66, 
+    243, 50, 174, 1, 253, 71, 174, 1, 253, 161, 174, 1, 253, 72, 174, 1, 247, 
+    219, 174, 1, 243, 134, 174, 1, 240, 66, 243, 134, 174, 1, 249, 246, 243, 
+    134, 174, 1, 253, 73, 174, 1, 247, 221, 174, 1, 247, 220, 174, 1, 249, 
+    21, 174, 1, 247, 222, 174, 1, 247, 214, 174, 1, 247, 223, 174, 1, 253, 
+    74, 174, 1, 253, 75, 174, 1, 253, 76, 174, 1, 249, 205, 174, 1, 235, 32, 
+    249, 205, 174, 1, 247, 224, 174, 49, 1, 231, 146, 69, 22, 4, 251, 202, 
+    22, 4, 251, 239, 22, 4, 252, 142, 22, 4, 252, 183, 22, 4, 247, 75, 22, 4, 
+    250, 128, 22, 4, 252, 226, 22, 4, 250, 165, 22, 4, 252, 32, 22, 4, 246, 
+    205, 22, 4, 238, 62, 254, 117, 22, 4, 253, 109, 22, 4, 250, 202, 22, 4, 
+    245, 49, 22, 4, 251, 122, 22, 4, 247, 145, 22, 4, 245, 4, 22, 4, 246, 
+    246, 22, 4, 252, 71, 22, 4, 245, 116, 22, 4, 245, 118, 22, 4, 241, 135, 
+    22, 4, 245, 117, 22, 4, 248, 66, 22, 4, 248, 251, 22, 4, 248, 249, 22, 4, 
+    247, 99, 22, 4, 247, 103, 22, 4, 249, 168, 22, 4, 248, 250, 22, 4, 250, 
+    148, 22, 4, 250, 152, 22, 4, 250, 150, 22, 4, 244, 245, 22, 4, 244, 246, 
+    22, 4, 250, 149, 22, 4, 250, 151, 22, 4, 249, 224, 22, 4, 249, 228, 22, 
+    4, 249, 226, 22, 4, 248, 15, 22, 4, 248, 19, 22, 4, 249, 225, 22, 4, 249, 
+    227, 22, 4, 244, 247, 22, 4, 244, 251, 22, 4, 244, 249, 22, 4, 241, 45, 
+    22, 4, 241, 46, 22, 4, 244, 248, 22, 4, 244, 250, 22, 4, 252, 115, 22, 4, 
+    252, 122, 22, 4, 252, 117, 22, 4, 247, 23, 22, 4, 247, 24, 22, 4, 252, 
+    116, 22, 4, 252, 118, 22, 4, 251, 175, 22, 4, 251, 179, 22, 4, 251, 177, 
+    22, 4, 246, 31, 22, 4, 246, 32, 22, 4, 251, 176, 22, 4, 251, 178, 22, 4, 
+    253, 56, 22, 4, 253, 63, 22, 4, 253, 58, 22, 4, 247, 208, 22, 4, 247, 
+    209, 22, 4, 253, 57, 22, 4, 253, 59, 22, 4, 251, 39, 22, 4, 251, 44, 22, 
+    4, 251, 42, 22, 4, 245, 136, 22, 4, 245, 137, 22, 4, 251, 40, 22, 4, 251, 
+    43, 38, 185, 232, 79, 238, 95, 38, 185, 240, 4, 232, 79, 238, 95, 40, 
+    232, 79, 104, 38, 232, 79, 104, 40, 240, 4, 232, 79, 104, 38, 240, 4, 
+    232, 79, 104, 240, 84, 231, 107, 238, 95, 240, 84, 240, 4, 231, 107, 238, 
+    95, 240, 4, 231, 100, 238, 95, 40, 231, 100, 104, 38, 231, 100, 104, 240, 
+    84, 238, 59, 40, 240, 84, 237, 26, 104, 38, 240, 84, 237, 26, 104, 236, 
+    11, 237, 92, 232, 95, 240, 176, 232, 95, 224, 240, 176, 232, 95, 231, 
+    140, 240, 4, 239, 149, 235, 45, 238, 160, 226, 226, 238, 160, 240, 4, 
+    231, 36, 240, 54, 45, 238, 106, 238, 93, 40, 170, 234, 61, 104, 38, 170, 
+    234, 61, 104, 7, 25, 239, 173, 7, 25, 240, 131, 7, 25, 240, 87, 127, 7, 
+    25, 240, 87, 111, 7, 25, 240, 87, 166, 7, 25, 239, 160, 7, 25, 248, 92, 
+    7, 25, 240, 241, 7, 25, 243, 209, 127, 7, 25, 243, 209, 111, 7, 25, 233, 
+    83, 7, 25, 244, 5, 7, 25, 3, 127, 7, 25, 3, 111, 7, 25, 248, 164, 127, 7, 
+    25, 248, 164, 111, 7, 25, 248, 164, 166, 7, 25, 248, 164, 177, 7, 25, 
+    242, 119, 7, 25, 238, 228, 7, 25, 244, 21, 127, 7, 25, 244, 21, 111, 7, 
+    25, 243, 16, 127, 7, 25, 243, 16, 111, 7, 25, 243, 59, 7, 25, 248, 244, 
+    7, 25, 241, 54, 7, 25, 248, 136, 7, 25, 243, 30, 7, 25, 240, 167, 7, 25, 
+    239, 140, 7, 25, 235, 189, 7, 25, 244, 50, 127, 7, 25, 244, 50, 111, 7, 
+    25, 243, 27, 7, 25, 254, 122, 127, 7, 25, 254, 122, 111, 7, 25, 234, 23, 
+    137, 249, 185, 240, 247, 7, 25, 248, 202, 7, 25, 249, 56, 7, 25, 243, 
+    199, 7, 25, 249, 33, 147, 240, 132, 7, 25, 249, 59, 7, 25, 240, 237, 127, 
+    7, 25, 240, 237, 111, 7, 25, 238, 164, 7, 25, 243, 122, 7, 25, 232, 72, 
+    243, 122, 7, 25, 254, 41, 127, 7, 25, 254, 41, 111, 7, 25, 254, 41, 166, 
+    7, 25, 254, 41, 177, 7, 25, 246, 65, 7, 25, 240, 225, 7, 25, 249, 151, 7, 
+    25, 249, 58, 7, 25, 249, 129, 7, 25, 243, 151, 127, 7, 25, 243, 151, 111, 
+    7, 25, 243, 222, 7, 25, 238, 202, 7, 25, 243, 97, 127, 7, 25, 243, 97, 
+    111, 7, 25, 243, 97, 166, 7, 25, 240, 245, 7, 25, 236, 255, 7, 25, 248, 
+    56, 127, 7, 25, 248, 56, 111, 7, 25, 232, 72, 248, 184, 7, 25, 234, 23, 
+    243, 8, 7, 25, 243, 8, 7, 25, 232, 72, 238, 220, 7, 25, 232, 72, 240, 
+    227, 7, 25, 243, 94, 7, 25, 232, 72, 243, 154, 7, 25, 234, 23, 244, 48, 
+    7, 25, 249, 13, 127, 7, 25, 249, 13, 111, 7, 25, 243, 156, 7, 25, 232, 
+    72, 243, 96, 7, 25, 183, 127, 7, 25, 183, 111, 7, 25, 232, 72, 243, 66, 
+    7, 25, 232, 72, 243, 178, 7, 25, 243, 227, 127, 7, 25, 243, 227, 111, 7, 
+    25, 243, 250, 7, 25, 243, 149, 7, 25, 232, 72, 240, 242, 236, 230, 7, 25, 
+    232, 72, 243, 214, 7, 25, 232, 72, 243, 82, 7, 25, 232, 72, 249, 63, 7, 
+    25, 254, 58, 127, 7, 25, 254, 58, 111, 7, 25, 254, 58, 166, 7, 25, 232, 
+    72, 248, 207, 7, 25, 243, 99, 7, 25, 232, 72, 240, 189, 7, 25, 243, 150, 
+    7, 25, 240, 181, 7, 25, 232, 72, 243, 172, 7, 25, 232, 72, 243, 85, 7, 
+    25, 232, 72, 244, 4, 7, 25, 234, 23, 240, 153, 7, 25, 234, 23, 238, 232, 
+    7, 25, 232, 72, 243, 176, 7, 25, 232, 84, 243, 93, 7, 25, 232, 72, 243, 
+    93, 7, 25, 232, 84, 240, 151, 7, 25, 232, 72, 240, 151, 7, 25, 232, 84, 
+    238, 137, 7, 25, 232, 72, 238, 137, 7, 25, 238, 125, 7, 25, 232, 84, 238, 
+    125, 7, 25, 232, 72, 238, 125, 43, 25, 127, 43, 25, 242, 224, 43, 25, 
+    248, 40, 43, 25, 240, 37, 43, 25, 239, 185, 43, 25, 90, 43, 25, 111, 43, 
+    25, 251, 195, 43, 25, 248, 131, 43, 25, 246, 41, 43, 25, 241, 95, 43, 25, 
+    195, 43, 25, 92, 248, 92, 43, 25, 241, 67, 43, 25, 249, 84, 43, 25, 240, 
+    241, 43, 25, 248, 35, 248, 92, 43, 25, 241, 204, 43, 25, 240, 210, 43, 
+    25, 247, 197, 43, 25, 242, 125, 43, 25, 38, 248, 35, 248, 92, 43, 25, 
+    241, 150, 234, 36, 43, 25, 248, 53, 43, 25, 233, 83, 43, 25, 244, 5, 43, 
+    25, 240, 131, 43, 25, 237, 243, 43, 25, 241, 6, 43, 25, 240, 201, 43, 25, 
+    234, 36, 43, 25, 240, 49, 43, 25, 238, 2, 43, 25, 253, 234, 43, 25, 255, 
+    75, 239, 198, 43, 25, 237, 153, 43, 25, 250, 123, 43, 25, 240, 253, 43, 
+    25, 241, 52, 43, 25, 247, 34, 43, 25, 245, 227, 43, 25, 240, 147, 43, 25, 
+    246, 37, 43, 25, 239, 32, 43, 25, 239, 202, 43, 25, 235, 102, 43, 25, 
+    242, 84, 43, 25, 247, 196, 43, 25, 237, 226, 43, 25, 239, 232, 43, 25, 
+    250, 207, 43, 25, 242, 215, 238, 228, 43, 25, 240, 4, 240, 131, 43, 25, 
+    183, 239, 206, 43, 25, 171, 241, 147, 43, 25, 242, 107, 43, 25, 248, 198, 
+    43, 25, 242, 120, 43, 25, 237, 80, 43, 25, 247, 121, 43, 25, 240, 138, 
+    43, 25, 237, 169, 43, 25, 245, 72, 43, 25, 243, 59, 43, 25, 239, 12, 43, 
+    25, 248, 244, 43, 25, 239, 183, 43, 25, 239, 44, 43, 25, 249, 245, 43, 
+    25, 238, 59, 43, 25, 248, 233, 43, 25, 248, 136, 43, 25, 252, 169, 43, 
+    25, 243, 30, 43, 25, 244, 37, 43, 25, 246, 35, 43, 25, 208, 43, 25, 240, 
+    167, 43, 25, 239, 247, 43, 25, 255, 48, 248, 233, 43, 25, 237, 89, 43, 
+    25, 249, 64, 43, 25, 245, 21, 43, 25, 242, 133, 43, 25, 240, 105, 43, 25, 
+    243, 27, 43, 25, 245, 22, 43, 25, 239, 67, 43, 25, 45, 206, 43, 25, 137, 
+    249, 185, 240, 247, 43, 25, 242, 115, 43, 25, 245, 89, 43, 25, 248, 202, 
+    43, 25, 249, 56, 43, 25, 236, 80, 43, 25, 243, 199, 43, 25, 241, 233, 43, 
+    25, 247, 151, 43, 25, 242, 136, 43, 25, 246, 51, 43, 25, 253, 5, 43, 25, 
+    241, 106, 43, 25, 249, 33, 147, 240, 132, 43, 25, 236, 103, 43, 25, 240, 
+    4, 247, 139, 43, 25, 240, 39, 43, 25, 247, 91, 43, 25, 245, 68, 43, 25, 
+    249, 59, 43, 25, 240, 236, 43, 25, 56, 43, 25, 242, 134, 43, 25, 239, 
+    201, 43, 25, 242, 156, 43, 25, 241, 140, 43, 25, 244, 243, 43, 25, 242, 
+    131, 43, 25, 238, 164, 43, 25, 247, 30, 43, 25, 243, 122, 43, 25, 251, 
+    111, 43, 25, 252, 14, 43, 25, 240, 225, 43, 25, 237, 156, 43, 25, 249, 
+    129, 43, 25, 248, 91, 43, 25, 246, 252, 43, 25, 248, 206, 43, 25, 241, 
+    39, 43, 25, 243, 222, 43, 25, 236, 61, 43, 25, 244, 6, 43, 25, 238, 249, 
+    43, 25, 238, 202, 43, 25, 238, 156, 43, 25, 239, 153, 43, 25, 244, 226, 
+    43, 25, 236, 108, 43, 25, 241, 63, 43, 25, 241, 142, 43, 25, 240, 245, 
+    43, 25, 239, 100, 43, 25, 241, 34, 43, 25, 249, 13, 234, 36, 43, 25, 236, 
+    255, 43, 25, 247, 194, 43, 25, 248, 184, 43, 25, 243, 8, 43, 25, 238, 
+    220, 43, 25, 239, 238, 43, 25, 244, 213, 43, 25, 252, 66, 43, 25, 239, 1, 
+    43, 25, 240, 227, 43, 25, 252, 131, 43, 25, 252, 151, 43, 25, 243, 94, 
+    43, 25, 244, 227, 43, 25, 243, 154, 43, 25, 239, 9, 43, 25, 237, 214, 43, 
+    25, 244, 48, 43, 25, 243, 156, 43, 25, 243, 133, 43, 25, 232, 132, 43, 
+    25, 238, 43, 43, 25, 243, 96, 43, 25, 243, 66, 43, 25, 243, 178, 43, 25, 
+    241, 249, 43, 25, 242, 114, 43, 25, 242, 215, 242, 139, 243, 85, 43, 25, 
+    243, 250, 43, 25, 243, 149, 43, 25, 242, 187, 43, 25, 243, 39, 43, 25, 
+    236, 230, 43, 25, 240, 242, 236, 230, 43, 25, 246, 40, 43, 25, 242, 121, 
+    43, 25, 243, 214, 43, 25, 243, 82, 43, 25, 249, 63, 43, 25, 248, 207, 43, 
+    25, 243, 99, 43, 25, 236, 27, 43, 25, 240, 189, 43, 25, 243, 150, 43, 25, 
+    247, 137, 43, 25, 245, 140, 43, 25, 241, 108, 43, 25, 233, 232, 243, 133, 
+    43, 25, 235, 117, 43, 25, 240, 181, 43, 25, 243, 172, 43, 25, 243, 85, 
+    43, 25, 244, 4, 43, 25, 243, 164, 43, 25, 240, 153, 43, 25, 245, 141, 43, 
+    25, 238, 232, 43, 25, 239, 137, 43, 25, 240, 0, 43, 25, 233, 195, 43, 25, 
+    243, 176, 43, 25, 239, 229, 43, 25, 245, 74, 43, 25, 249, 152, 43, 25, 
+    246, 176, 43, 25, 243, 93, 43, 25, 240, 151, 43, 25, 238, 137, 43, 25, 
+    238, 125, 43, 25, 241, 112, 80, 233, 55, 99, 40, 153, 225, 80, 233, 55, 
+    99, 60, 153, 46, 80, 233, 55, 99, 40, 153, 240, 1, 19, 225, 80, 233, 55, 
+    99, 60, 153, 240, 1, 19, 46, 80, 233, 55, 99, 248, 37, 236, 121, 80, 233, 
+    55, 99, 236, 204, 248, 44, 48, 80, 233, 55, 99, 236, 204, 248, 44, 46, 
+    80, 233, 55, 99, 236, 204, 248, 44, 242, 220, 80, 233, 55, 99, 236, 204, 
+    248, 44, 189, 242, 220, 80, 233, 55, 99, 236, 204, 248, 44, 189, 225, 80, 
+    233, 55, 99, 236, 204, 248, 44, 168, 242, 220, 80, 233, 55, 99, 236, 66, 
+    80, 240, 15, 80, 240, 27, 80, 248, 37, 208, 245, 69, 69, 237, 184, 234, 
+    206, 237, 44, 91, 80, 235, 77, 69, 80, 238, 171, 69, 80, 61, 242, 217, 
+    40, 185, 104, 38, 185, 104, 40, 45, 185, 104, 38, 45, 185, 104, 40, 240, 
+    31, 104, 38, 240, 31, 104, 40, 64, 240, 31, 104, 38, 64, 240, 31, 104, 
+    40, 86, 234, 11, 104, 38, 86, 234, 11, 104, 240, 142, 69, 251, 16, 69, 
+    40, 236, 171, 242, 255, 104, 38, 236, 171, 242, 255, 104, 40, 64, 234, 
+    11, 104, 38, 64, 234, 11, 104, 40, 64, 236, 171, 242, 255, 104, 38, 64, 
+    236, 171, 242, 255, 104, 40, 64, 31, 104, 38, 64, 31, 104, 248, 141, 242, 
+    235, 224, 45, 243, 117, 235, 51, 69, 45, 243, 117, 235, 51, 69, 170, 45, 
+    243, 117, 235, 51, 69, 240, 142, 158, 243, 39, 236, 166, 178, 127, 236, 
+    166, 178, 111, 236, 166, 178, 166, 236, 166, 178, 177, 236, 166, 178, 
+    176, 236, 166, 178, 187, 236, 166, 178, 203, 236, 166, 178, 195, 236, 
+    166, 178, 202, 80, 246, 42, 188, 69, 80, 240, 69, 188, 69, 80, 235, 98, 
+    188, 69, 80, 237, 151, 188, 69, 23, 240, 12, 53, 188, 69, 23, 45, 53, 
+    188, 69, 248, 103, 242, 235, 59, 248, 130, 240, 64, 69, 59, 248, 130, 
+    240, 64, 2, 240, 59, 243, 1, 69, 59, 248, 130, 240, 64, 158, 189, 243, 7, 
+    59, 248, 130, 240, 64, 2, 240, 59, 243, 1, 158, 189, 243, 7, 59, 248, 
+    130, 240, 64, 158, 168, 243, 7, 29, 240, 142, 69, 80, 145, 248, 41, 250, 
+    237, 235, 95, 91, 236, 166, 178, 248, 53, 236, 166, 178, 238, 77, 236, 
+    166, 178, 238, 101, 59, 80, 235, 77, 69, 251, 219, 69, 249, 134, 233, 
+    112, 69, 80, 34, 234, 30, 80, 137, 250, 245, 240, 15, 105, 1, 3, 67, 105, 
+    1, 67, 105, 1, 3, 71, 105, 1, 71, 105, 1, 3, 79, 105, 1, 79, 105, 1, 3, 
+    72, 105, 1, 72, 105, 1, 3, 73, 105, 1, 73, 105, 1, 201, 105, 1, 253, 139, 
+    105, 1, 253, 215, 105, 1, 254, 6, 105, 1, 253, 203, 105, 1, 253, 235, 
+    105, 1, 253, 172, 105, 1, 254, 5, 105, 1, 253, 190, 105, 1, 253, 234, 
+    105, 1, 253, 132, 105, 1, 253, 163, 105, 1, 253, 198, 105, 1, 254, 17, 
+    105, 1, 253, 211, 105, 1, 254, 18, 105, 1, 253, 210, 105, 1, 253, 228, 
+    105, 1, 253, 186, 105, 1, 253, 222, 105, 1, 253, 126, 105, 1, 253, 133, 
+    105, 1, 253, 212, 105, 1, 253, 201, 105, 1, 3, 253, 196, 105, 1, 253, 
+    196, 105, 1, 253, 232, 105, 1, 253, 195, 105, 1, 253, 200, 105, 1, 87, 
+    105, 1, 253, 225, 105, 1, 253, 131, 105, 1, 253, 166, 105, 1, 253, 150, 
+    105, 1, 253, 197, 105, 1, 253, 173, 105, 1, 219, 105, 1, 253, 141, 105, 
+    1, 253, 129, 105, 1, 253, 214, 105, 1, 254, 34, 105, 1, 253, 147, 105, 1, 
+    253, 236, 105, 1, 253, 243, 105, 1, 253, 239, 105, 1, 253, 168, 105, 1, 
+    253, 242, 105, 1, 253, 175, 105, 1, 253, 184, 105, 1, 254, 1, 105, 1, 
+    253, 208, 105, 1, 222, 105, 1, 253, 180, 105, 1, 253, 154, 105, 1, 253, 
+    206, 105, 1, 253, 181, 105, 1, 3, 216, 105, 1, 216, 105, 1, 3, 253, 161, 
+    105, 1, 253, 161, 105, 1, 3, 253, 162, 105, 1, 253, 162, 105, 1, 253, 
+    130, 105, 1, 253, 209, 105, 1, 253, 185, 105, 1, 253, 194, 105, 1, 253, 
+    160, 105, 1, 3, 253, 138, 105, 1, 253, 138, 105, 1, 253, 187, 105, 1, 
+    253, 170, 105, 1, 253, 177, 105, 1, 197, 105, 1, 254, 49, 105, 1, 3, 201, 
+    105, 1, 3, 253, 172, 50, 226, 254, 240, 59, 243, 1, 69, 50, 226, 254, 
+    233, 75, 243, 1, 69, 226, 254, 240, 59, 243, 1, 69, 226, 254, 233, 75, 
+    243, 1, 69, 105, 235, 77, 69, 105, 240, 59, 235, 77, 69, 105, 238, 112, 
+    247, 233, 226, 254, 45, 238, 93, 42, 1, 3, 67, 42, 1, 67, 42, 1, 3, 71, 
+    42, 1, 71, 42, 1, 3, 79, 42, 1, 79, 42, 1, 3, 72, 42, 1, 72, 42, 1, 3, 
+    73, 42, 1, 73, 42, 1, 201, 42, 1, 253, 139, 42, 1, 253, 215, 42, 1, 254, 
+    6, 42, 1, 253, 203, 42, 1, 253, 235, 42, 1, 253, 172, 42, 1, 254, 5, 42, 
+    1, 253, 190, 42, 1, 253, 234, 42, 1, 253, 132, 42, 1, 253, 163, 42, 1, 
+    253, 198, 42, 1, 254, 17, 42, 1, 253, 211, 42, 1, 254, 18, 42, 1, 253, 
+    210, 42, 1, 253, 228, 42, 1, 253, 186, 42, 1, 253, 222, 42, 1, 253, 126, 
+    42, 1, 253, 133, 42, 1, 253, 212, 42, 1, 253, 201, 42, 1, 3, 253, 196, 
+    42, 1, 253, 196, 42, 1, 253, 232, 42, 1, 253, 195, 42, 1, 253, 200, 42, 
+    1, 87, 42, 1, 253, 225, 42, 1, 253, 131, 42, 1, 253, 166, 42, 1, 253, 
+    150, 42, 1, 253, 197, 42, 1, 253, 173, 42, 1, 219, 42, 1, 253, 141, 42, 
+    1, 253, 129, 42, 1, 253, 214, 42, 1, 254, 34, 42, 1, 253, 147, 42, 1, 
+    253, 236, 42, 1, 253, 243, 42, 1, 253, 239, 42, 1, 253, 168, 42, 1, 253, 
+    242, 42, 1, 253, 175, 42, 1, 253, 184, 42, 1, 254, 1, 42, 1, 253, 208, 
+    42, 1, 222, 42, 1, 253, 180, 42, 1, 253, 154, 42, 1, 253, 206, 42, 1, 
+    253, 181, 42, 1, 3, 216, 42, 1, 216, 42, 1, 3, 253, 161, 42, 1, 253, 161, 
+    42, 1, 3, 253, 162, 42, 1, 253, 162, 42, 1, 253, 130, 42, 1, 253, 209, 
+    42, 1, 253, 185, 42, 1, 253, 194, 42, 1, 253, 160, 42, 1, 3, 253, 138, 
+    42, 1, 253, 138, 42, 1, 253, 187, 42, 1, 253, 170, 42, 1, 253, 177, 42, 
+    1, 197, 42, 1, 254, 49, 42, 1, 3, 201, 42, 1, 3, 253, 172, 42, 1, 253, 
+    171, 42, 1, 254, 48, 42, 1, 254, 12, 42, 1, 254, 13, 42, 240, 1, 248, 40, 
+    226, 254, 235, 138, 243, 1, 69, 42, 235, 77, 69, 42, 240, 59, 235, 77, 
+    69, 42, 238, 112, 246, 19, 155, 1, 217, 155, 1, 223, 155, 1, 173, 155, 1, 
+    255, 19, 155, 1, 209, 155, 1, 214, 155, 1, 197, 155, 1, 162, 155, 1, 210, 
+    155, 1, 255, 15, 155, 1, 192, 155, 1, 221, 155, 1, 255, 20, 155, 1, 206, 
+    155, 1, 255, 11, 155, 1, 254, 151, 155, 1, 254, 72, 155, 1, 144, 155, 1, 
+    255, 17, 155, 1, 255, 18, 155, 1, 193, 155, 1, 67, 155, 1, 73, 155, 1, 
+    72, 155, 1, 254, 36, 155, 1, 253, 149, 155, 1, 254, 89, 155, 1, 253, 151, 
+    155, 1, 254, 10, 155, 1, 254, 19, 155, 1, 253, 202, 155, 1, 248, 124, 
+    155, 1, 248, 108, 155, 1, 254, 4, 155, 1, 71, 155, 1, 79, 155, 1, 254, 
+    101, 155, 1, 179, 155, 1, 254, 26, 155, 1, 254, 168, 23, 1, 238, 99, 23, 
+    1, 232, 87, 23, 1, 232, 91, 23, 1, 240, 80, 23, 1, 232, 93, 23, 1, 232, 
+    94, 23, 1, 238, 102, 23, 1, 232, 101, 23, 1, 240, 85, 23, 1, 231, 98, 23, 
+    1, 232, 96, 23, 1, 232, 97, 23, 1, 233, 74, 23, 1, 231, 43, 23, 1, 231, 
+    42, 23, 1, 232, 85, 23, 1, 240, 78, 23, 1, 240, 83, 23, 1, 233, 79, 23, 
+    1, 233, 66, 23, 1, 243, 34, 23, 1, 234, 32, 23, 1, 240, 75, 23, 1, 240, 
+    71, 23, 1, 233, 77, 23, 1, 236, 195, 23, 1, 236, 198, 23, 1, 236, 205, 
+    23, 1, 236, 201, 23, 1, 240, 74, 23, 1, 67, 23, 1, 253, 178, 23, 1, 216, 
+    23, 1, 249, 18, 23, 1, 254, 59, 23, 1, 72, 23, 1, 249, 22, 23, 1, 253, 
+    254, 23, 1, 73, 23, 1, 253, 138, 23, 1, 249, 12, 23, 1, 253, 193, 23, 1, 
+    253, 162, 23, 1, 79, 23, 1, 249, 14, 23, 1, 253, 170, 23, 1, 253, 187, 
+    23, 1, 253, 161, 23, 1, 254, 61, 23, 1, 253, 189, 23, 1, 71, 23, 238, 
+    114, 23, 1, 233, 105, 23, 1, 231, 97, 23, 1, 233, 90, 23, 1, 231, 47, 23, 
+    1, 226, 245, 23, 1, 231, 111, 23, 1, 226, 255, 23, 1, 231, 54, 23, 1, 
+    226, 246, 23, 1, 232, 92, 23, 1, 233, 86, 23, 1, 231, 46, 23, 1, 231, 40, 
+    23, 1, 231, 109, 23, 1, 231, 110, 23, 1, 226, 243, 23, 1, 226, 244, 23, 
+    1, 232, 106, 23, 1, 231, 52, 23, 1, 231, 41, 23, 1, 226, 235, 23, 1, 232, 
+    99, 23, 1, 233, 102, 23, 1, 232, 100, 23, 1, 233, 76, 23, 1, 233, 101, 
+    23, 1, 236, 234, 23, 1, 233, 78, 23, 1, 235, 115, 23, 1, 231, 58, 23, 1, 
+    227, 0, 23, 1, 227, 9, 23, 1, 233, 104, 23, 1, 232, 102, 23, 1, 240, 255, 
+    23, 1, 238, 233, 23, 1, 244, 58, 23, 1, 238, 234, 23, 1, 241, 0, 23, 1, 
+    244, 60, 23, 1, 240, 156, 23, 1, 238, 247, 80, 234, 4, 239, 123, 69, 80, 
+    234, 4, 238, 75, 69, 80, 234, 4, 253, 125, 69, 80, 234, 4, 171, 69, 80, 
+    234, 4, 204, 69, 80, 234, 4, 248, 58, 69, 80, 234, 4, 253, 159, 69, 80, 
+    234, 4, 240, 1, 69, 80, 234, 4, 240, 17, 69, 80, 234, 4, 243, 41, 69, 80, 
+    234, 4, 240, 87, 69, 80, 234, 4, 243, 129, 69, 80, 234, 4, 240, 137, 69, 
+    80, 234, 4, 241, 148, 69, 80, 234, 4, 243, 168, 69, 80, 234, 4, 254, 111, 
+    69, 155, 1, 253, 243, 155, 1, 254, 17, 155, 1, 254, 7, 155, 1, 253, 235, 
+    155, 1, 253, 164, 155, 1, 250, 224, 155, 1, 253, 156, 155, 1, 249, 130, 
+    155, 1, 254, 177, 155, 1, 249, 238, 155, 1, 251, 105, 155, 1, 252, 254, 
+    155, 1, 254, 175, 155, 1, 252, 18, 155, 1, 244, 73, 155, 1, 244, 86, 155, 
+    1, 254, 32, 155, 1, 254, 43, 155, 1, 252, 59, 155, 1, 245, 229, 155, 30, 
+    1, 223, 155, 30, 1, 214, 155, 30, 1, 255, 15, 155, 30, 1, 192, 7, 240, 5, 
+    214, 7, 240, 5, 255, 3, 7, 240, 5, 255, 5, 7, 240, 5, 250, 137, 7, 240, 
+    5, 254, 128, 7, 240, 5, 251, 96, 7, 240, 5, 251, 93, 7, 240, 5, 254, 97, 
+    7, 240, 5, 245, 219, 7, 240, 5, 247, 134, 7, 240, 5, 251, 94, 7, 240, 5, 
+    245, 220, 7, 240, 5, 245, 202, 7, 240, 5, 251, 95, 7, 240, 5, 245, 221, 
+    7, 240, 5, 197, 42, 1, 3, 253, 203, 42, 1, 3, 253, 198, 42, 1, 3, 253, 
+    211, 42, 1, 3, 87, 42, 1, 3, 253, 150, 42, 1, 3, 219, 42, 1, 3, 253, 214, 
+    42, 1, 3, 253, 236, 42, 1, 3, 253, 168, 42, 1, 3, 253, 184, 42, 1, 3, 
+    253, 154, 42, 1, 3, 253, 130, 42, 1, 3, 253, 209, 42, 1, 3, 253, 185, 42, 
+    1, 3, 253, 194, 42, 1, 3, 253, 160, 82, 23, 238, 99, 82, 23, 240, 80, 82, 
+    23, 238, 102, 82, 23, 240, 85, 82, 23, 240, 78, 82, 23, 240, 83, 82, 23, 
+    243, 34, 82, 23, 240, 75, 82, 23, 240, 71, 82, 23, 236, 195, 82, 23, 236, 
+    198, 82, 23, 236, 205, 82, 23, 236, 201, 82, 23, 240, 74, 82, 23, 240, 
+    193, 67, 82, 23, 243, 233, 67, 82, 23, 240, 246, 67, 82, 23, 243, 254, 
+    67, 82, 23, 243, 226, 67, 82, 23, 243, 242, 67, 82, 23, 249, 164, 67, 82, 
+    23, 243, 100, 67, 82, 23, 243, 90, 67, 82, 23, 238, 169, 67, 82, 23, 238, 
+    194, 67, 82, 23, 238, 227, 67, 82, 23, 238, 206, 67, 82, 23, 243, 195, 
+    67, 82, 23, 243, 90, 79, 82, 240, 99, 99, 242, 39, 82, 240, 99, 99, 117, 
+    253, 236, 82, 110, 127, 82, 110, 111, 82, 110, 166, 82, 110, 177, 82, 
+    110, 176, 82, 110, 187, 82, 110, 203, 82, 110, 195, 82, 110, 202, 82, 
+    110, 248, 53, 82, 110, 243, 30, 82, 110, 243, 27, 82, 110, 240, 105, 82, 
+    110, 244, 52, 82, 110, 240, 199, 82, 110, 240, 49, 82, 110, 248, 136, 82, 
+    110, 240, 238, 82, 110, 243, 191, 82, 110, 237, 41, 82, 110, 243, 230, 
+    82, 110, 237, 43, 82, 110, 234, 53, 82, 110, 229, 61, 82, 110, 240, 195, 
+    82, 110, 234, 247, 82, 110, 244, 241, 82, 110, 240, 239, 82, 110, 234, 
+    66, 82, 110, 233, 84, 82, 110, 235, 140, 82, 110, 235, 116, 82, 110, 236, 
+    20, 82, 110, 242, 239, 82, 110, 244, 6, 82, 110, 240, 215, 233, 94, 52, 
+    29, 61, 240, 48, 127, 29, 61, 240, 48, 111, 29, 61, 240, 48, 166, 29, 61, 
+    240, 48, 177, 29, 61, 240, 48, 176, 29, 61, 240, 48, 187, 29, 61, 240, 
+    48, 203, 29, 61, 240, 48, 195, 29, 61, 240, 48, 202, 29, 61, 238, 101, 
+    29, 61, 240, 53, 127, 29, 61, 240, 53, 111, 29, 61, 240, 53, 166, 29, 61, 
+    240, 53, 177, 29, 61, 240, 53, 176, 29, 23, 238, 99, 29, 23, 240, 80, 29, 
+    23, 238, 102, 29, 23, 240, 85, 29, 23, 240, 78, 29, 23, 240, 83, 29, 23, 
+    243, 34, 29, 23, 240, 75, 29, 23, 240, 71, 29, 23, 236, 195, 29, 23, 236, 
+    198, 29, 23, 236, 205, 29, 23, 236, 201, 29, 23, 240, 74, 29, 23, 240, 
+    193, 67, 29, 23, 243, 233, 67, 29, 23, 240, 246, 67, 29, 23, 243, 254, 
+    67, 29, 23, 243, 226, 67, 29, 23, 243, 242, 67, 29, 23, 249, 164, 67, 29, 
+    23, 243, 100, 67, 29, 23, 243, 90, 67, 29, 23, 238, 169, 67, 29, 23, 238, 
+    194, 67, 29, 23, 238, 227, 67, 29, 23, 238, 206, 67, 29, 23, 243, 195, 
+    67, 29, 240, 99, 99, 239, 20, 29, 240, 99, 99, 241, 190, 29, 23, 243, 
+    100, 79, 240, 99, 237, 44, 91, 29, 110, 127, 29, 110, 111, 29, 110, 166, 
+    29, 110, 177, 29, 110, 176, 29, 110, 187, 29, 110, 203, 29, 110, 195, 29, 
+    110, 202, 29, 110, 248, 53, 29, 110, 243, 30, 29, 110, 243, 27, 29, 110, 
+    240, 105, 29, 110, 244, 52, 29, 110, 240, 199, 29, 110, 240, 49, 29, 110, 
+    248, 136, 29, 110, 240, 238, 29, 110, 243, 191, 29, 110, 237, 41, 29, 
+    110, 243, 230, 29, 110, 237, 43, 29, 110, 234, 53, 29, 110, 229, 61, 29, 
+    110, 240, 195, 29, 110, 239, 186, 29, 110, 246, 62, 29, 110, 239, 68, 29, 
+    110, 236, 120, 29, 110, 234, 188, 29, 110, 242, 65, 29, 110, 234, 95, 29, 
+    110, 245, 232, 29, 110, 242, 239, 29, 110, 245, 27, 29, 110, 237, 93, 29, 
+    110, 245, 146, 29, 110, 238, 129, 29, 110, 251, 207, 29, 110, 242, 220, 
+    29, 110, 225, 29, 110, 236, 59, 29, 110, 236, 91, 29, 110, 240, 239, 29, 
+    110, 234, 66, 29, 110, 233, 84, 29, 110, 235, 140, 29, 110, 235, 116, 29, 
+    110, 242, 11, 29, 61, 240, 53, 187, 29, 61, 240, 53, 203, 29, 61, 240, 
+    53, 195, 29, 61, 240, 53, 202, 29, 61, 240, 136, 29, 61, 243, 6, 127, 29, 
+    61, 243, 6, 111, 29, 61, 243, 6, 166, 29, 61, 243, 6, 177, 29, 61, 243, 
+    6, 176, 29, 61, 243, 6, 187, 29, 61, 243, 6, 203, 29, 61, 243, 6, 195, 
+    29, 61, 243, 6, 202, 29, 61, 240, 50, 80, 145, 12, 28, 237, 183, 80, 145, 
+    12, 28, 236, 19, 80, 145, 12, 28, 241, 229, 80, 145, 12, 28, 241, 12, 80, 
+    145, 12, 28, 251, 222, 80, 145, 12, 28, 245, 253, 80, 145, 12, 28, 245, 
+    252, 80, 145, 12, 28, 238, 253, 80, 145, 12, 28, 234, 252, 80, 145, 12, 
+    28, 237, 224, 80, 145, 12, 28, 236, 65, 80, 145, 12, 28, 235, 200, 31, 
+    254, 171, 31, 250, 227, 31, 254, 160, 239, 118, 236, 51, 52, 29, 42, 67, 
+    29, 42, 71, 29, 42, 79, 29, 42, 72, 29, 42, 73, 29, 42, 201, 29, 42, 253, 
+    215, 29, 42, 253, 203, 29, 42, 253, 172, 29, 42, 253, 190, 29, 42, 253, 
+    132, 29, 42, 253, 198, 29, 42, 253, 211, 29, 42, 253, 210, 29, 42, 253, 
+    186, 29, 42, 253, 126, 29, 42, 253, 212, 29, 42, 253, 196, 29, 42, 253, 
+    195, 29, 42, 87, 29, 42, 253, 131, 29, 42, 253, 166, 29, 42, 253, 150, 
+    29, 42, 253, 197, 29, 42, 253, 173, 29, 42, 219, 29, 42, 253, 214, 29, 
+    42, 253, 236, 29, 42, 253, 168, 29, 42, 253, 184, 29, 42, 222, 29, 42, 
+    253, 180, 29, 42, 253, 154, 29, 42, 253, 206, 29, 42, 253, 181, 29, 42, 
+    216, 29, 42, 253, 161, 29, 42, 253, 162, 29, 42, 253, 130, 29, 42, 253, 
+    209, 29, 42, 253, 185, 29, 42, 253, 194, 29, 42, 253, 160, 29, 42, 253, 
+    138, 29, 42, 253, 187, 29, 42, 253, 170, 29, 42, 253, 177, 31, 238, 246, 
+    31, 238, 251, 31, 241, 10, 31, 244, 68, 31, 239, 99, 31, 245, 230, 31, 
+    252, 255, 31, 236, 15, 31, 241, 91, 31, 246, 232, 31, 246, 233, 31, 241, 
+    192, 31, 237, 187, 31, 237, 188, 31, 241, 124, 31, 241, 123, 31, 245, 
+    124, 31, 241, 137, 31, 239, 112, 31, 237, 165, 31, 246, 16, 31, 233, 213, 
+    31, 232, 180, 31, 234, 214, 31, 239, 87, 31, 234, 198, 31, 234, 216, 31, 
+    237, 192, 31, 241, 196, 31, 239, 110, 31, 241, 205, 31, 237, 254, 31, 
+    236, 95, 31, 238, 7, 31, 242, 101, 31, 242, 102, 31, 241, 70, 31, 245, 
+    63, 31, 245, 73, 31, 252, 227, 31, 246, 105, 31, 242, 24, 31, 241, 146, 
+    31, 236, 67, 31, 242, 46, 31, 237, 69, 31, 234, 233, 31, 239, 161, 31, 
+    246, 251, 31, 244, 223, 31, 236, 36, 31, 239, 95, 31, 235, 184, 31, 241, 
+    170, 31, 234, 199, 31, 246, 242, 31, 239, 159, 31, 239, 93, 31, 242, 55, 
+    31, 242, 52, 31, 241, 26, 31, 239, 164, 31, 239, 11, 31, 251, 77, 31, 
+    242, 64, 31, 241, 167, 31, 245, 200, 31, 237, 197, 31, 241, 225, 31, 241, 
+    224, 31, 239, 129, 31, 237, 199, 31, 237, 210, 31, 246, 88, 31, 234, 223, 
+    31, 243, 106, 31, 237, 207, 31, 237, 206, 31, 242, 190, 31, 242, 191, 31, 
+    247, 237, 31, 237, 252, 31, 247, 32, 31, 242, 90, 31, 237, 253, 31, 247, 
+    29, 31, 236, 92, 31, 242, 183, 80, 145, 12, 28, 248, 52, 242, 217, 80, 
+    145, 12, 28, 248, 52, 127, 80, 145, 12, 28, 248, 52, 111, 80, 145, 12, 
+    28, 248, 52, 166, 80, 145, 12, 28, 248, 52, 177, 80, 145, 12, 28, 248, 
+    52, 176, 80, 145, 12, 28, 248, 52, 187, 80, 145, 12, 28, 248, 52, 203, 
+    80, 145, 12, 28, 248, 52, 195, 80, 145, 12, 28, 248, 52, 202, 80, 145, 
+    12, 28, 248, 52, 248, 53, 80, 145, 12, 28, 248, 52, 238, 91, 80, 145, 12, 
+    28, 248, 52, 238, 97, 80, 145, 12, 28, 248, 52, 235, 85, 80, 145, 12, 28, 
+    248, 52, 235, 82, 80, 145, 12, 28, 248, 52, 236, 207, 80, 145, 12, 28, 
+    248, 52, 236, 202, 80, 145, 12, 28, 248, 52, 234, 22, 80, 145, 12, 28, 
+    248, 52, 235, 81, 80, 145, 12, 28, 248, 52, 235, 83, 80, 145, 12, 28, 
+    248, 52, 238, 77, 80, 145, 12, 28, 248, 52, 233, 110, 80, 145, 12, 28, 
+    248, 52, 233, 111, 80, 145, 12, 28, 248, 52, 231, 114, 80, 145, 12, 28, 
+    248, 52, 232, 111, 31, 251, 82, 31, 253, 133, 31, 253, 151, 31, 125, 31, 
+    254, 219, 31, 254, 222, 31, 254, 156, 31, 255, 53, 236, 191, 31, 255, 53, 
+    240, 94, 31, 254, 101, 31, 254, 37, 248, 170, 239, 89, 31, 254, 37, 248, 
+    170, 239, 213, 31, 254, 37, 248, 170, 238, 21, 31, 254, 37, 248, 170, 
+    241, 232, 31, 232, 123, 31, 255, 87, 244, 79, 31, 253, 131, 31, 255, 27, 
+    67, 31, 222, 31, 201, 31, 254, 182, 31, 254, 199, 31, 254, 166, 31, 250, 
+    143, 31, 246, 7, 31, 254, 224, 31, 254, 211, 31, 255, 27, 255, 19, 31, 
+    255, 27, 210, 31, 254, 202, 31, 254, 106, 31, 254, 173, 31, 251, 147, 31, 
+    251, 230, 31, 251, 20, 31, 252, 220, 31, 255, 27, 162, 31, 254, 204, 31, 
+    254, 155, 31, 254, 186, 31, 254, 164, 31, 254, 215, 31, 255, 27, 173, 31, 
+    254, 205, 31, 254, 152, 31, 254, 187, 31, 255, 61, 236, 191, 31, 255, 52, 
+    236, 191, 31, 255, 108, 236, 191, 31, 255, 50, 236, 191, 31, 255, 61, 
+    240, 94, 31, 255, 52, 240, 94, 31, 255, 108, 240, 94, 31, 255, 50, 240, 
+    94, 31, 255, 108, 248, 59, 193, 31, 255, 108, 248, 59, 255, 99, 236, 191, 
+    31, 253, 129, 31, 251, 163, 31, 249, 115, 31, 251, 28, 31, 252, 126, 31, 
+    254, 71, 248, 59, 193, 31, 254, 71, 248, 59, 255, 99, 236, 191, 31, 254, 
+    229, 31, 254, 216, 31, 255, 27, 193, 31, 254, 206, 31, 254, 230, 31, 254, 
+    115, 31, 255, 27, 179, 31, 254, 207, 31, 254, 189, 31, 255, 84, 243, 106, 
+    31, 254, 231, 31, 254, 217, 31, 255, 27, 255, 16, 31, 254, 208, 31, 254, 
+    108, 31, 255, 85, 243, 106, 31, 255, 109, 249, 126, 31, 255, 108, 249, 
+    126, 31, 254, 32, 31, 254, 147, 31, 254, 149, 31, 254, 150, 31, 255, 105, 
+    248, 59, 254, 106, 31, 253, 224, 31, 254, 154, 31, 254, 170, 31, 219, 31, 
+    254, 97, 31, 253, 247, 31, 254, 107, 31, 255, 50, 237, 83, 31, 254, 188, 
+    31, 254, 194, 31, 254, 195, 31, 251, 203, 31, 254, 197, 31, 255, 80, 240, 
+    147, 31, 251, 233, 31, 251, 240, 31, 254, 225, 31, 254, 226, 31, 252, 75, 
+    31, 254, 228, 31, 254, 241, 31, 254, 127, 31, 255, 2, 31, 255, 110, 248, 
+    59, 173, 31, 134, 248, 59, 173, 80, 145, 12, 28, 253, 137, 127, 80, 145, 
+    12, 28, 253, 137, 111, 80, 145, 12, 28, 253, 137, 166, 80, 145, 12, 28, 
+    253, 137, 177, 80, 145, 12, 28, 253, 137, 176, 80, 145, 12, 28, 253, 137, 
+    187, 80, 145, 12, 28, 253, 137, 203, 80, 145, 12, 28, 253, 137, 195, 80, 
+    145, 12, 28, 253, 137, 202, 80, 145, 12, 28, 253, 137, 248, 53, 80, 145, 
+    12, 28, 253, 137, 238, 91, 80, 145, 12, 28, 253, 137, 238, 97, 80, 145, 
+    12, 28, 253, 137, 235, 85, 80, 145, 12, 28, 253, 137, 235, 82, 80, 145, 
+    12, 28, 253, 137, 236, 207, 80, 145, 12, 28, 253, 137, 236, 202, 80, 145, 
+    12, 28, 253, 137, 234, 22, 80, 145, 12, 28, 253, 137, 235, 81, 80, 145, 
+    12, 28, 253, 137, 235, 83, 80, 145, 12, 28, 253, 137, 238, 77, 80, 145, 
+    12, 28, 253, 137, 233, 110, 80, 145, 12, 28, 253, 137, 233, 111, 80, 145, 
+    12, 28, 253, 137, 231, 114, 80, 145, 12, 28, 253, 137, 232, 111, 80, 145, 
+    12, 28, 253, 137, 233, 45, 80, 145, 12, 28, 253, 137, 233, 255, 80, 145, 
+    12, 28, 253, 137, 232, 64, 80, 145, 12, 28, 253, 137, 232, 63, 80, 145, 
+    12, 28, 253, 137, 233, 46, 80, 145, 12, 28, 253, 137, 238, 101, 80, 145, 
+    12, 28, 253, 137, 233, 252, 31, 251, 7, 156, 28, 253, 145, 237, 94, 238, 
+    139, 156, 28, 253, 145, 236, 86, 240, 49, 156, 28, 234, 112, 255, 31, 
+    253, 145, 234, 97, 156, 28, 238, 48, 241, 113, 156, 28, 237, 51, 156, 28, 
+    235, 191, 156, 28, 253, 145, 244, 84, 156, 28, 238, 189, 235, 153, 156, 
+    28, 3, 238, 222, 156, 28, 236, 130, 156, 28, 242, 51, 156, 28, 233, 247, 
+    156, 28, 233, 201, 156, 28, 243, 58, 233, 224, 156, 28, 237, 212, 156, 
+    28, 233, 197, 156, 28, 234, 54, 156, 28, 253, 37, 255, 34, 253, 145, 237, 
+    102, 156, 28, 235, 166, 156, 28, 231, 63, 156, 28, 241, 32, 238, 27, 156, 
+    28, 241, 139, 156, 28, 236, 104, 241, 11, 156, 28, 238, 211, 156, 28, 
+    234, 208, 156, 28, 243, 58, 238, 222, 156, 28, 246, 91, 237, 0, 156, 28, 
+    243, 58, 231, 53, 156, 28, 253, 145, 238, 236, 240, 105, 156, 28, 253, 
+    145, 237, 87, 243, 27, 156, 28, 234, 207, 156, 28, 236, 9, 156, 28, 237, 
+    251, 156, 28, 243, 58, 240, 210, 156, 28, 236, 81, 156, 28, 235, 198, 
+    147, 253, 145, 240, 9, 156, 28, 253, 145, 239, 66, 156, 28, 233, 73, 156, 
+    28, 232, 189, 156, 28, 232, 128, 156, 28, 235, 201, 156, 28, 235, 127, 
+    156, 28, 231, 119, 156, 28, 241, 65, 153, 243, 224, 156, 28, 235, 124, 
+    235, 153, 156, 28, 239, 170, 239, 235, 156, 28, 233, 221, 156, 28, 253, 
+    145, 247, 193, 156, 28, 233, 231, 156, 28, 253, 145, 235, 117, 156, 28, 
+    253, 145, 237, 67, 237, 48, 156, 28, 253, 145, 238, 193, 247, 123, 235, 
+    102, 156, 28, 232, 131, 156, 28, 253, 145, 237, 203, 239, 125, 156, 28, 
+    234, 89, 156, 28, 253, 145, 236, 139, 156, 28, 253, 145, 241, 125, 243, 
+    82, 156, 28, 253, 145, 241, 188, 243, 213, 156, 28, 233, 135, 156, 28, 
+    233, 216, 156, 28, 245, 228, 242, 158, 156, 28, 3, 231, 53, 156, 28, 244, 
+    70, 233, 69, 156, 28, 241, 27, 233, 69, 6, 4, 254, 179, 6, 4, 254, 180, 
+    6, 4, 71, 6, 4, 254, 176, 6, 4, 251, 102, 6, 4, 251, 103, 6, 4, 253, 237, 
+    6, 4, 251, 101, 6, 4, 254, 20, 6, 4, 254, 144, 6, 4, 67, 6, 4, 254, 141, 
+    6, 4, 253, 1, 6, 4, 254, 252, 6, 4, 253, 0, 6, 4, 254, 67, 6, 4, 254, 
+    220, 6, 4, 73, 6, 4, 254, 120, 6, 4, 254, 161, 6, 4, 72, 6, 4, 254, 14, 
+    6, 4, 250, 125, 6, 4, 250, 126, 6, 4, 254, 34, 6, 4, 250, 124, 6, 4, 244, 
+    221, 6, 4, 244, 222, 6, 4, 250, 122, 6, 4, 244, 220, 6, 4, 250, 104, 6, 
+    4, 250, 105, 6, 4, 253, 141, 6, 4, 250, 103, 6, 4, 244, 235, 6, 4, 250, 
+    131, 6, 4, 244, 234, 6, 4, 250, 130, 6, 4, 248, 92, 6, 4, 254, 1, 6, 4, 
+    250, 129, 6, 4, 250, 119, 6, 4, 253, 242, 6, 4, 250, 116, 6, 4, 250, 133, 
+    6, 4, 250, 134, 6, 4, 253, 243, 6, 4, 250, 132, 6, 4, 244, 236, 6, 4, 
+    249, 35, 6, 4, 250, 140, 6, 4, 250, 141, 6, 4, 254, 82, 6, 4, 250, 138, 
+    6, 4, 244, 238, 6, 4, 250, 139, 6, 4, 252, 68, 6, 4, 252, 69, 6, 4, 253, 
+    147, 6, 4, 252, 67, 6, 4, 246, 250, 6, 4, 252, 65, 6, 4, 246, 249, 6, 4, 
+    252, 61, 6, 4, 252, 62, 6, 4, 253, 129, 6, 4, 252, 60, 6, 4, 247, 0, 6, 
+    4, 252, 78, 6, 4, 246, 255, 6, 4, 252, 73, 6, 4, 252, 74, 6, 4, 253, 208, 
+    6, 4, 252, 72, 6, 4, 249, 142, 6, 4, 252, 81, 6, 4, 253, 239, 6, 4, 252, 
+    79, 6, 4, 247, 1, 6, 4, 252, 80, 6, 4, 249, 144, 6, 4, 252, 84, 6, 4, 
+    254, 232, 6, 4, 252, 82, 6, 4, 247, 3, 6, 4, 252, 83, 6, 4, 244, 200, 6, 
+    4, 244, 201, 6, 4, 250, 108, 6, 4, 244, 199, 6, 4, 241, 21, 6, 4, 241, 
+    22, 6, 4, 244, 198, 6, 4, 241, 20, 6, 4, 244, 194, 6, 4, 244, 195, 6, 4, 
+    250, 106, 6, 4, 244, 193, 6, 4, 241, 24, 6, 4, 244, 205, 6, 4, 241, 23, 
+    6, 4, 244, 203, 6, 4, 244, 204, 6, 4, 250, 109, 6, 4, 244, 202, 6, 4, 
+    244, 197, 6, 4, 250, 107, 6, 4, 244, 196, 6, 4, 243, 145, 6, 4, 244, 208, 
+    6, 4, 250, 110, 6, 4, 244, 206, 6, 4, 241, 25, 6, 4, 244, 207, 6, 4, 244, 
+    210, 6, 4, 244, 211, 6, 4, 250, 111, 6, 4, 244, 209, 6, 4, 246, 110, 6, 
+    4, 246, 111, 6, 4, 252, 3, 6, 4, 246, 109, 6, 4, 242, 0, 6, 4, 243, 232, 
+    6, 4, 241, 255, 6, 4, 246, 107, 6, 4, 246, 108, 6, 4, 252, 2, 6, 4, 246, 
+    106, 6, 4, 246, 113, 6, 4, 246, 114, 6, 4, 252, 4, 6, 4, 246, 112, 6, 4, 
+    246, 117, 6, 4, 246, 118, 6, 4, 252, 5, 6, 4, 246, 115, 6, 4, 242, 1, 6, 
+    4, 246, 116, 6, 4, 246, 121, 6, 4, 246, 122, 6, 4, 252, 6, 6, 4, 246, 
+    119, 6, 4, 242, 2, 6, 4, 246, 120, 6, 4, 245, 173, 6, 4, 245, 174, 6, 4, 
+    251, 71, 6, 4, 245, 172, 6, 4, 241, 158, 6, 4, 245, 171, 6, 4, 241, 157, 
+    6, 4, 245, 169, 6, 4, 245, 170, 6, 4, 251, 70, 6, 4, 245, 168, 6, 4, 241, 
+    160, 6, 4, 245, 178, 6, 4, 241, 159, 6, 4, 245, 176, 6, 4, 245, 177, 6, 
+    4, 249, 82, 6, 4, 245, 175, 6, 4, 245, 181, 6, 4, 245, 182, 6, 4, 251, 
+    72, 6, 4, 245, 179, 6, 4, 241, 161, 6, 4, 245, 180, 6, 4, 245, 185, 6, 4, 
+    251, 73, 6, 4, 245, 183, 6, 4, 241, 162, 6, 4, 245, 184, 6, 4, 251, 237, 
+    6, 4, 251, 238, 6, 4, 253, 180, 6, 4, 251, 236, 6, 4, 246, 83, 6, 4, 251, 
+    231, 6, 4, 246, 82, 6, 4, 251, 220, 6, 4, 251, 221, 6, 4, 222, 6, 4, 251, 
+    218, 6, 4, 246, 97, 6, 4, 246, 98, 6, 4, 251, 243, 6, 4, 246, 96, 6, 4, 
+    251, 241, 6, 4, 251, 242, 6, 4, 253, 181, 6, 4, 249, 114, 6, 4, 251, 226, 
+    6, 4, 253, 206, 6, 4, 251, 246, 6, 4, 251, 247, 6, 4, 253, 154, 6, 4, 
+    251, 244, 6, 4, 246, 100, 6, 4, 251, 245, 6, 4, 251, 250, 6, 4, 251, 251, 
+    6, 4, 254, 209, 6, 4, 251, 249, 6, 4, 250, 247, 6, 4, 250, 248, 6, 4, 
+    253, 245, 6, 4, 250, 246, 6, 4, 250, 235, 6, 4, 250, 236, 6, 4, 253, 179, 
+    6, 4, 250, 234, 6, 4, 250, 251, 6, 4, 254, 63, 6, 4, 250, 250, 6, 4, 250, 
+    253, 6, 4, 250, 254, 6, 4, 254, 93, 6, 4, 250, 252, 6, 4, 245, 93, 6, 4, 
+    249, 64, 6, 4, 251, 3, 6, 4, 251, 4, 6, 4, 254, 165, 6, 4, 251, 2, 6, 4, 
+    253, 14, 6, 4, 253, 15, 6, 4, 254, 48, 6, 4, 253, 13, 6, 4, 247, 187, 6, 
+    4, 247, 188, 6, 4, 253, 12, 6, 4, 247, 186, 6, 4, 253, 8, 6, 4, 253, 9, 
+    6, 4, 253, 171, 6, 4, 253, 7, 6, 4, 253, 18, 6, 4, 253, 20, 6, 4, 254, 
+    13, 6, 4, 253, 17, 6, 4, 253, 11, 6, 4, 249, 193, 6, 4, 253, 22, 6, 4, 
+    253, 23, 6, 4, 254, 49, 6, 4, 253, 21, 6, 4, 247, 189, 6, 4, 249, 197, 6, 
+    4, 253, 27, 6, 4, 253, 28, 6, 4, 255, 1, 6, 4, 253, 25, 6, 4, 247, 190, 
+    6, 4, 253, 26, 6, 4, 250, 196, 6, 4, 250, 197, 6, 4, 253, 201, 6, 4, 250, 
+    195, 6, 4, 245, 66, 6, 4, 250, 194, 6, 4, 245, 65, 6, 4, 250, 184, 6, 4, 
+    250, 187, 6, 4, 253, 133, 6, 4, 250, 182, 6, 4, 245, 75, 6, 4, 250, 209, 
+    6, 4, 248, 40, 6, 4, 250, 205, 6, 4, 253, 225, 6, 4, 250, 204, 6, 4, 250, 
+    191, 6, 4, 253, 200, 6, 4, 250, 190, 6, 4, 250, 212, 6, 4, 250, 213, 6, 
+    4, 253, 232, 6, 4, 250, 210, 6, 4, 245, 76, 6, 4, 250, 211, 6, 4, 252, 
+    223, 6, 4, 252, 224, 6, 4, 253, 212, 6, 4, 252, 222, 6, 4, 247, 149, 6, 
+    4, 248, 139, 6, 4, 247, 148, 6, 4, 249, 174, 6, 4, 252, 212, 6, 4, 253, 
+    126, 6, 4, 252, 209, 6, 4, 247, 174, 6, 4, 247, 175, 6, 4, 252, 233, 6, 
+    4, 247, 173, 6, 4, 249, 184, 6, 4, 252, 228, 6, 4, 87, 6, 4, 249, 3, 6, 
+    4, 252, 217, 6, 4, 253, 195, 6, 4, 252, 214, 6, 4, 252, 236, 6, 4, 252, 
+    237, 6, 4, 253, 196, 6, 4, 252, 234, 6, 4, 247, 176, 6, 4, 252, 235, 6, 
+    4, 245, 47, 6, 4, 245, 48, 6, 4, 249, 51, 6, 4, 245, 46, 6, 4, 241, 77, 
+    6, 4, 245, 45, 6, 4, 241, 76, 6, 4, 245, 39, 6, 4, 245, 40, 6, 4, 248, 
+    75, 6, 4, 245, 38, 6, 4, 241, 79, 6, 4, 245, 53, 6, 4, 241, 78, 6, 4, 
+    245, 51, 6, 4, 245, 52, 6, 4, 248, 204, 6, 4, 245, 50, 6, 4, 245, 43, 6, 
+    4, 249, 50, 6, 4, 245, 42, 6, 4, 245, 55, 6, 4, 245, 56, 6, 4, 249, 52, 
+    6, 4, 245, 54, 6, 4, 241, 80, 6, 4, 243, 163, 6, 4, 246, 130, 6, 4, 246, 
+    131, 6, 4, 252, 9, 6, 4, 246, 129, 6, 4, 242, 3, 6, 4, 246, 128, 6, 4, 
+    246, 124, 6, 4, 246, 125, 6, 4, 252, 7, 6, 4, 246, 123, 6, 4, 246, 133, 
+    6, 4, 246, 134, 6, 4, 252, 10, 6, 4, 246, 132, 6, 4, 246, 127, 6, 4, 252, 
+    8, 6, 4, 246, 126, 6, 4, 246, 137, 6, 4, 246, 138, 6, 4, 252, 11, 6, 4, 
+    246, 135, 6, 4, 242, 4, 6, 4, 246, 136, 6, 4, 245, 193, 6, 4, 245, 194, 
+    6, 4, 251, 75, 6, 4, 245, 192, 6, 4, 241, 164, 6, 4, 241, 165, 6, 4, 245, 
+    191, 6, 4, 241, 163, 6, 4, 245, 187, 6, 4, 245, 188, 6, 4, 249, 83, 6, 4, 
+    245, 186, 6, 4, 241, 166, 6, 4, 245, 198, 6, 4, 245, 196, 6, 4, 245, 197, 
+    6, 4, 245, 195, 6, 4, 245, 190, 6, 4, 251, 74, 6, 4, 245, 189, 6, 4, 245, 
+    199, 6, 4, 252, 24, 6, 4, 252, 25, 6, 4, 253, 166, 6, 4, 252, 23, 6, 4, 
+    246, 155, 6, 4, 252, 21, 6, 4, 246, 154, 6, 4, 252, 1, 6, 4, 253, 131, 6, 
+    4, 251, 255, 6, 4, 246, 195, 6, 4, 252, 41, 6, 4, 246, 194, 6, 4, 248, 
+    233, 6, 4, 252, 35, 6, 4, 253, 173, 6, 4, 252, 33, 6, 4, 252, 15, 6, 4, 
+    253, 197, 6, 4, 252, 13, 6, 4, 252, 44, 6, 4, 252, 45, 6, 4, 253, 150, 6, 
+    4, 252, 42, 6, 4, 246, 196, 6, 4, 252, 43, 6, 4, 245, 155, 6, 4, 245, 
+    156, 6, 4, 251, 66, 6, 4, 245, 154, 6, 4, 241, 152, 6, 4, 245, 153, 6, 4, 
+    241, 151, 6, 4, 245, 149, 6, 4, 245, 150, 6, 4, 251, 64, 6, 4, 245, 148, 
+    6, 4, 241, 154, 6, 4, 245, 159, 6, 4, 241, 153, 6, 4, 245, 158, 6, 4, 
+    251, 67, 6, 4, 245, 157, 6, 4, 245, 152, 6, 4, 251, 65, 6, 4, 245, 151, 
+    6, 4, 245, 162, 6, 4, 245, 163, 6, 4, 251, 68, 6, 4, 245, 160, 6, 4, 241, 
+    155, 6, 4, 245, 161, 6, 4, 245, 166, 6, 4, 245, 167, 6, 4, 251, 69, 6, 4, 
+    245, 164, 6, 4, 241, 156, 6, 4, 245, 165, 6, 4, 251, 200, 6, 4, 251, 201, 
+    6, 4, 253, 251, 6, 4, 251, 198, 6, 4, 246, 49, 6, 4, 246, 50, 6, 4, 249, 
+    105, 6, 4, 246, 48, 6, 4, 251, 185, 6, 4, 251, 186, 6, 4, 253, 134, 6, 4, 
+    251, 183, 6, 4, 246, 57, 6, 4, 246, 58, 6, 4, 251, 209, 6, 4, 246, 56, 6, 
+    4, 251, 206, 6, 4, 251, 208, 6, 4, 253, 216, 6, 4, 251, 205, 6, 4, 251, 
+    191, 6, 4, 253, 250, 6, 4, 251, 189, 6, 4, 251, 212, 6, 4, 251, 213, 6, 
+    4, 254, 8, 6, 4, 251, 210, 6, 4, 246, 59, 6, 4, 251, 211, 6, 4, 251, 215, 
+    6, 4, 251, 216, 6, 4, 254, 110, 6, 4, 251, 214, 6, 4, 246, 60, 6, 4, 249, 
+    109, 6, 4, 251, 23, 6, 4, 251, 24, 6, 4, 254, 6, 6, 4, 251, 22, 6, 4, 
+    245, 122, 6, 4, 245, 123, 6, 4, 251, 21, 6, 4, 245, 121, 6, 4, 251, 10, 
+    6, 4, 251, 11, 6, 4, 253, 139, 6, 4, 251, 8, 6, 4, 245, 131, 6, 4, 245, 
+    132, 6, 4, 251, 31, 6, 4, 245, 130, 6, 4, 249, 78, 6, 4, 251, 27, 6, 4, 
+    253, 234, 6, 4, 251, 26, 6, 4, 251, 15, 6, 4, 251, 17, 6, 4, 254, 5, 6, 
+    4, 249, 69, 6, 4, 251, 34, 6, 4, 251, 35, 6, 4, 253, 235, 6, 4, 251, 32, 
+    6, 4, 245, 133, 6, 4, 251, 33, 6, 4, 249, 95, 6, 4, 251, 152, 6, 4, 253, 
+    215, 6, 4, 251, 151, 6, 4, 246, 15, 6, 4, 251, 148, 6, 4, 246, 14, 6, 4, 
+    251, 138, 6, 4, 251, 140, 6, 4, 201, 6, 4, 251, 137, 6, 4, 246, 21, 6, 4, 
+    251, 165, 6, 4, 246, 20, 6, 4, 251, 161, 6, 4, 251, 162, 6, 4, 253, 190, 
+    6, 4, 251, 160, 6, 4, 251, 143, 6, 4, 251, 144, 6, 4, 253, 172, 6, 4, 
+    251, 142, 6, 4, 251, 168, 6, 4, 251, 169, 6, 4, 253, 203, 6, 4, 251, 166, 
+    6, 4, 246, 23, 6, 4, 251, 167, 6, 4, 245, 108, 6, 4, 245, 109, 6, 4, 249, 
+    72, 6, 4, 241, 129, 6, 4, 245, 107, 6, 4, 241, 128, 6, 4, 245, 101, 6, 4, 
+    245, 102, 6, 4, 249, 70, 6, 4, 245, 100, 6, 4, 241, 131, 6, 4, 241, 132, 
+    6, 4, 243, 181, 6, 4, 241, 130, 6, 4, 245, 110, 6, 4, 245, 111, 6, 4, 
+    249, 73, 6, 4, 243, 180, 6, 4, 245, 105, 6, 4, 245, 106, 6, 4, 249, 71, 
+    6, 4, 245, 104, 6, 4, 245, 114, 6, 4, 245, 115, 6, 4, 249, 74, 6, 4, 245, 
+    112, 6, 4, 241, 133, 6, 4, 245, 113, 6, 4, 241, 238, 6, 4, 246, 72, 6, 4, 
+    246, 68, 6, 4, 246, 69, 6, 4, 251, 227, 6, 4, 246, 67, 6, 4, 241, 240, 6, 
+    4, 246, 76, 6, 4, 241, 239, 6, 4, 246, 74, 6, 4, 246, 75, 6, 4, 248, 167, 
+    6, 4, 246, 73, 6, 4, 246, 71, 6, 4, 251, 228, 6, 4, 246, 70, 6, 4, 246, 
+    79, 6, 4, 246, 80, 6, 4, 251, 229, 6, 4, 246, 77, 6, 4, 241, 241, 6, 4, 
+    246, 78, 6, 4, 243, 196, 6, 4, 245, 216, 6, 4, 251, 91, 6, 4, 245, 215, 
+    6, 4, 241, 172, 6, 4, 241, 173, 6, 4, 245, 214, 6, 4, 241, 171, 6, 4, 
+    245, 210, 6, 4, 245, 211, 6, 4, 251, 89, 6, 4, 245, 209, 6, 4, 241, 175, 
+    6, 4, 241, 176, 6, 4, 243, 198, 6, 4, 241, 174, 6, 4, 245, 217, 6, 4, 
+    245, 218, 6, 4, 251, 92, 6, 4, 243, 197, 6, 4, 245, 213, 6, 4, 251, 90, 
+    6, 4, 245, 212, 6, 4, 242, 7, 6, 4, 246, 146, 6, 4, 242, 6, 6, 4, 246, 
+    142, 6, 4, 246, 143, 6, 4, 248, 50, 6, 4, 246, 141, 6, 4, 242, 9, 6, 4, 
+    242, 10, 6, 4, 246, 153, 6, 4, 246, 151, 6, 4, 246, 152, 6, 4, 248, 172, 
+    6, 4, 246, 150, 6, 4, 246, 145, 6, 4, 252, 17, 6, 4, 246, 144, 6, 4, 251, 
+    63, 6, 4, 245, 145, 6, 4, 248, 160, 6, 4, 248, 214, 6, 4, 251, 48, 6, 4, 
+    219, 6, 4, 251, 47, 6, 4, 245, 206, 6, 4, 245, 207, 6, 4, 251, 83, 6, 4, 
+    245, 205, 6, 4, 251, 80, 6, 4, 251, 81, 6, 4, 253, 184, 6, 4, 251, 79, 6, 
+    4, 251, 55, 6, 4, 253, 168, 6, 4, 251, 53, 6, 4, 253, 30, 6, 4, 253, 31, 
+    6, 4, 253, 138, 6, 4, 253, 29, 6, 4, 247, 200, 6, 4, 253, 39, 6, 4, 247, 
+    199, 6, 4, 253, 38, 6, 4, 253, 177, 6, 4, 253, 36, 6, 4, 253, 33, 6, 4, 
+    253, 170, 6, 4, 253, 32, 6, 4, 253, 106, 6, 4, 253, 107, 6, 4, 254, 17, 
+    6, 4, 253, 105, 6, 4, 248, 10, 6, 4, 253, 104, 6, 4, 248, 9, 6, 4, 253, 
+    99, 6, 4, 253, 100, 6, 4, 253, 163, 6, 4, 253, 98, 6, 4, 248, 12, 6, 4, 
+    253, 114, 6, 4, 248, 11, 6, 4, 249, 221, 6, 4, 253, 112, 6, 4, 253, 222, 
+    6, 4, 253, 111, 6, 4, 253, 102, 6, 4, 253, 228, 6, 4, 253, 101, 6, 4, 
+    253, 115, 6, 4, 253, 116, 6, 4, 254, 18, 6, 4, 249, 222, 6, 4, 248, 13, 
+    6, 4, 249, 223, 6, 4, 253, 120, 6, 4, 253, 121, 6, 4, 255, 13, 6, 4, 253, 
+    118, 6, 4, 248, 14, 6, 4, 253, 119, 6, 4, 250, 163, 6, 4, 250, 164, 6, 4, 
+    254, 55, 6, 4, 249, 40, 6, 4, 245, 19, 6, 4, 245, 20, 6, 4, 250, 161, 6, 
+    4, 245, 18, 6, 4, 250, 146, 6, 4, 250, 147, 6, 4, 253, 152, 6, 4, 249, 
+    38, 6, 4, 245, 28, 6, 4, 250, 170, 6, 4, 243, 157, 6, 4, 250, 167, 6, 4, 
+    250, 168, 6, 4, 253, 224, 6, 4, 250, 166, 6, 4, 250, 157, 6, 4, 254, 54, 
+    6, 4, 250, 156, 6, 4, 250, 172, 6, 4, 250, 173, 6, 4, 254, 84, 6, 4, 249, 
+    43, 6, 4, 245, 29, 6, 4, 250, 171, 6, 4, 249, 48, 6, 4, 250, 176, 6, 4, 
+    254, 85, 6, 4, 249, 47, 6, 4, 245, 30, 6, 4, 250, 175, 6, 4, 248, 24, 6, 
+    4, 248, 25, 6, 4, 249, 226, 6, 4, 248, 23, 6, 4, 241, 1, 6, 4, 242, 211, 
+    6, 4, 248, 22, 6, 4, 242, 210, 6, 4, 248, 17, 6, 4, 248, 18, 6, 4, 249, 
+    224, 6, 4, 248, 16, 6, 4, 248, 27, 6, 4, 249, 227, 6, 4, 248, 26, 6, 4, 
+    248, 21, 6, 4, 249, 225, 6, 4, 248, 20, 6, 4, 248, 30, 6, 4, 249, 228, 6, 
+    4, 248, 28, 6, 4, 242, 212, 6, 4, 248, 29, 6, 4, 248, 33, 6, 4, 248, 34, 
+    6, 4, 253, 122, 6, 4, 248, 31, 6, 4, 242, 213, 6, 4, 248, 32, 6, 4, 246, 
+    219, 6, 4, 246, 220, 6, 4, 252, 49, 6, 4, 246, 218, 6, 4, 242, 34, 6, 4, 
+    246, 217, 6, 4, 242, 33, 6, 4, 246, 214, 6, 4, 246, 215, 6, 4, 252, 47, 
+    6, 4, 246, 213, 6, 4, 242, 35, 6, 4, 246, 223, 6, 4, 246, 222, 6, 4, 246, 
+    221, 6, 4, 246, 216, 6, 4, 252, 48, 6, 4, 246, 225, 6, 4, 252, 50, 6, 4, 
+    243, 239, 6, 4, 242, 36, 6, 4, 246, 224, 6, 4, 246, 228, 6, 4, 246, 229, 
+    6, 4, 252, 51, 6, 4, 246, 226, 6, 4, 242, 37, 6, 4, 246, 227, 6, 4, 252, 
+    180, 6, 4, 187, 6, 4, 253, 198, 6, 4, 252, 179, 6, 4, 247, 88, 6, 4, 252, 
+    176, 6, 4, 247, 87, 6, 4, 252, 167, 6, 4, 252, 168, 6, 4, 253, 132, 6, 4, 
+    252, 166, 6, 4, 247, 126, 6, 4, 252, 193, 6, 4, 247, 125, 6, 4, 252, 186, 
+    6, 4, 252, 188, 6, 4, 253, 186, 6, 4, 252, 185, 6, 4, 252, 172, 6, 4, 
+    253, 210, 6, 4, 252, 171, 6, 4, 252, 196, 6, 4, 252, 197, 6, 4, 253, 211, 
+    6, 4, 252, 194, 6, 4, 247, 128, 6, 4, 252, 195, 6, 4, 252, 200, 6, 4, 
+    252, 201, 6, 4, 254, 243, 6, 4, 252, 198, 6, 4, 247, 130, 6, 4, 252, 199, 
+    6, 4, 247, 108, 6, 4, 247, 109, 6, 4, 248, 249, 6, 4, 247, 107, 6, 4, 
+    242, 129, 6, 4, 247, 106, 6, 4, 242, 128, 6, 4, 247, 101, 6, 4, 247, 102, 
+    6, 4, 248, 66, 6, 4, 247, 100, 6, 4, 247, 111, 6, 4, 247, 112, 6, 4, 248, 
+    250, 6, 4, 247, 110, 6, 4, 247, 105, 6, 4, 249, 168, 6, 4, 247, 104, 6, 
+    4, 247, 114, 6, 4, 247, 115, 6, 4, 248, 251, 6, 4, 247, 113, 6, 4, 247, 
+    118, 6, 4, 247, 119, 6, 4, 252, 189, 6, 4, 247, 116, 6, 4, 242, 130, 6, 
+    4, 247, 117, 6, 4, 247, 247, 6, 4, 247, 248, 6, 4, 248, 99, 6, 4, 247, 
+    246, 6, 4, 242, 204, 6, 4, 247, 255, 6, 4, 242, 203, 6, 4, 247, 253, 6, 
+    4, 247, 254, 6, 4, 249, 218, 6, 4, 247, 252, 6, 4, 247, 250, 6, 4, 247, 
+    251, 6, 4, 248, 123, 6, 4, 247, 249, 6, 4, 248, 2, 6, 4, 248, 3, 6, 4, 
+    249, 219, 6, 4, 248, 0, 6, 4, 242, 205, 6, 4, 248, 1, 6, 4, 248, 7, 6, 4, 
+    248, 8, 6, 4, 253, 103, 6, 4, 248, 5, 6, 4, 242, 206, 6, 4, 248, 6, 6, 4, 
+    244, 255, 6, 4, 245, 0, 6, 4, 248, 57, 6, 4, 244, 254, 6, 4, 241, 57, 6, 
+    4, 241, 58, 6, 4, 245, 9, 6, 4, 241, 56, 6, 4, 245, 7, 6, 4, 245, 8, 6, 
+    4, 248, 125, 6, 4, 245, 6, 6, 4, 245, 2, 6, 4, 245, 3, 6, 4, 248, 88, 6, 
+    4, 245, 1, 6, 4, 245, 12, 6, 4, 248, 200, 6, 4, 245, 10, 6, 4, 241, 59, 
+    6, 4, 245, 11, 6, 4, 245, 16, 6, 4, 245, 17, 6, 4, 250, 160, 6, 4, 245, 
+    14, 6, 4, 241, 60, 6, 4, 245, 15, 6, 4, 247, 35, 6, 4, 248, 96, 6, 4, 
+    242, 87, 6, 4, 247, 43, 6, 4, 247, 41, 6, 4, 247, 42, 6, 4, 249, 157, 6, 
+    4, 247, 40, 6, 4, 247, 38, 6, 4, 247, 39, 6, 4, 252, 147, 6, 4, 247, 37, 
+    6, 4, 247, 46, 6, 4, 247, 47, 6, 4, 252, 148, 6, 4, 247, 44, 6, 4, 242, 
+    88, 6, 4, 247, 45, 6, 4, 247, 50, 6, 4, 247, 51, 6, 4, 252, 149, 6, 4, 
+    247, 48, 6, 4, 242, 89, 6, 4, 247, 49, 6, 4, 246, 178, 6, 4, 246, 179, 6, 
+    4, 249, 123, 6, 4, 246, 177, 6, 4, 246, 184, 6, 4, 252, 37, 6, 4, 246, 
+    183, 6, 4, 246, 181, 6, 4, 246, 182, 6, 4, 252, 36, 6, 4, 246, 180, 6, 4, 
+    246, 187, 6, 4, 246, 188, 6, 4, 252, 38, 6, 4, 246, 185, 6, 4, 242, 25, 
+    6, 4, 246, 186, 6, 4, 246, 191, 6, 4, 246, 192, 6, 4, 252, 39, 6, 4, 246, 
+    189, 6, 4, 242, 26, 6, 4, 246, 190, 6, 4, 244, 8, 6, 4, 247, 69, 6, 4, 
+    248, 46, 6, 4, 247, 68, 6, 4, 242, 110, 6, 4, 247, 79, 6, 4, 242, 109, 6, 
+    4, 247, 77, 6, 4, 247, 78, 6, 4, 248, 110, 6, 4, 244, 13, 6, 4, 247, 71, 
+    6, 4, 247, 72, 6, 4, 248, 118, 6, 4, 247, 70, 6, 4, 247, 81, 6, 4, 247, 
+    82, 6, 4, 248, 248, 6, 4, 247, 80, 6, 4, 242, 111, 6, 4, 244, 15, 6, 4, 
+    247, 85, 6, 4, 247, 86, 6, 4, 249, 163, 6, 4, 247, 83, 6, 4, 242, 112, 6, 
+    4, 247, 84, 6, 4, 249, 152, 6, 4, 252, 130, 6, 4, 253, 130, 6, 4, 248, 
+    244, 6, 4, 247, 55, 6, 4, 252, 152, 6, 4, 247, 54, 6, 4, 252, 145, 6, 4, 
+    252, 146, 6, 4, 253, 160, 6, 4, 252, 144, 6, 4, 252, 135, 6, 4, 253, 194, 
+    6, 4, 252, 133, 6, 4, 252, 155, 6, 4, 252, 156, 6, 4, 253, 185, 6, 4, 
+    252, 153, 6, 4, 247, 56, 6, 4, 252, 154, 6, 4, 252, 161, 6, 4, 252, 162, 
+    6, 4, 254, 125, 6, 4, 252, 159, 6, 4, 247, 58, 6, 4, 252, 160, 6, 4, 251, 
+    118, 6, 4, 251, 119, 6, 4, 254, 7, 6, 4, 251, 117, 6, 4, 245, 236, 6, 4, 
+    245, 237, 6, 4, 251, 116, 6, 4, 245, 235, 6, 4, 245, 255, 6, 4, 246, 0, 
+    6, 4, 251, 126, 6, 4, 245, 254, 6, 4, 248, 115, 6, 4, 251, 124, 6, 4, 
+    253, 248, 6, 4, 251, 123, 6, 4, 251, 129, 6, 4, 251, 130, 6, 4, 254, 25, 
+    6, 4, 251, 127, 6, 4, 246, 1, 6, 4, 251, 128, 6, 4, 251, 134, 6, 4, 251, 
+    135, 6, 4, 254, 181, 6, 4, 251, 132, 6, 4, 246, 2, 6, 4, 251, 133, 6, 4, 
+    252, 96, 6, 4, 252, 97, 6, 4, 254, 28, 6, 4, 252, 95, 6, 4, 247, 13, 6, 
+    4, 247, 14, 6, 4, 252, 94, 6, 4, 247, 12, 6, 4, 247, 17, 6, 4, 247, 18, 
+    6, 4, 249, 149, 6, 4, 247, 16, 6, 4, 249, 148, 6, 4, 252, 102, 6, 4, 254, 
+    45, 6, 4, 252, 101, 6, 4, 252, 109, 6, 4, 252, 111, 6, 4, 254, 29, 6, 4, 
+    252, 107, 6, 4, 247, 19, 6, 4, 252, 108, 6, 4, 252, 121, 6, 4, 252, 123, 
+    6, 4, 254, 234, 6, 4, 252, 119, 6, 4, 247, 25, 6, 4, 252, 120, 6, 4, 245, 
+    240, 6, 4, 245, 241, 6, 4, 249, 86, 6, 4, 245, 239, 6, 4, 241, 183, 6, 4, 
+    241, 184, 6, 4, 243, 202, 6, 4, 241, 182, 6, 4, 241, 186, 6, 4, 245, 245, 
+    6, 4, 241, 185, 6, 4, 245, 243, 6, 4, 245, 244, 6, 4, 249, 87, 6, 4, 245, 
+    242, 6, 4, 243, 203, 6, 4, 245, 248, 6, 4, 249, 88, 6, 4, 245, 246, 6, 4, 
+    241, 187, 6, 4, 245, 247, 6, 4, 245, 250, 6, 4, 245, 251, 6, 4, 249, 89, 
+    6, 4, 245, 249, 6, 4, 246, 159, 6, 4, 246, 160, 6, 4, 252, 26, 6, 4, 246, 
+    158, 6, 4, 242, 14, 6, 4, 242, 15, 6, 4, 246, 157, 6, 4, 242, 13, 6, 4, 
+    242, 16, 6, 4, 246, 164, 6, 4, 246, 162, 6, 4, 246, 163, 6, 4, 252, 27, 
+    6, 4, 246, 161, 6, 4, 246, 167, 6, 4, 252, 28, 6, 4, 246, 165, 6, 4, 242, 
+    17, 6, 4, 246, 166, 6, 4, 246, 170, 6, 4, 246, 171, 6, 4, 252, 29, 6, 4, 
+    246, 168, 6, 4, 242, 18, 6, 4, 246, 169, 6, 4, 246, 203, 6, 4, 246, 204, 
+    6, 4, 248, 178, 6, 4, 243, 237, 6, 4, 242, 29, 6, 4, 242, 30, 6, 4, 246, 
+    202, 6, 4, 242, 28, 6, 4, 242, 32, 6, 4, 246, 208, 6, 4, 242, 31, 6, 4, 
+    246, 206, 6, 4, 246, 207, 6, 4, 248, 133, 6, 4, 243, 238, 6, 4, 246, 210, 
+    6, 4, 246, 211, 6, 4, 249, 125, 6, 4, 246, 209, 6, 4, 253, 45, 6, 4, 253, 
+    46, 6, 4, 253, 188, 6, 4, 253, 44, 6, 4, 247, 202, 6, 4, 247, 203, 6, 4, 
+    253, 43, 6, 4, 247, 201, 6, 4, 247, 205, 6, 4, 253, 52, 6, 4, 253, 50, 6, 
+    4, 253, 51, 6, 4, 254, 133, 6, 4, 253, 48, 6, 4, 253, 62, 6, 4, 253, 64, 
+    6, 4, 255, 7, 6, 4, 253, 60, 6, 4, 247, 210, 6, 4, 253, 61, 6, 4, 249, 
+    209, 6, 4, 253, 83, 6, 4, 253, 189, 6, 4, 253, 82, 6, 4, 247, 228, 6, 4, 
+    247, 229, 6, 4, 253, 80, 6, 4, 247, 227, 6, 4, 247, 240, 6, 4, 247, 241, 
+    6, 4, 253, 88, 6, 4, 247, 239, 6, 4, 249, 211, 6, 4, 253, 86, 6, 4, 253, 
+    162, 6, 4, 253, 85, 6, 4, 253, 91, 6, 4, 253, 92, 6, 4, 253, 161, 6, 4, 
+    253, 89, 6, 4, 247, 242, 6, 4, 253, 90, 6, 4, 253, 95, 6, 4, 253, 96, 6, 
+    4, 254, 77, 6, 4, 253, 93, 6, 4, 247, 243, 6, 4, 253, 94, 6, 25, 249, 
+    148, 6, 25, 253, 251, 6, 25, 249, 95, 6, 25, 243, 237, 6, 25, 249, 47, 6, 
+    25, 248, 249, 6, 25, 243, 180, 6, 25, 249, 69, 6, 25, 253, 180, 6, 25, 
+    243, 196, 6, 25, 249, 109, 6, 25, 243, 145, 6, 25, 249, 114, 6, 25, 253, 
+    162, 6, 25, 249, 142, 6, 25, 243, 198, 6, 25, 249, 174, 6, 25, 253, 139, 
+    6, 25, 249, 222, 6, 25, 249, 48, 6, 25, 243, 163, 6, 25, 249, 35, 6, 25, 
+    243, 181, 6, 25, 243, 238, 6, 25, 253, 196, 6, 25, 254, 120, 6, 25, 243, 
+    203, 6, 25, 249, 221, 6, 25, 249, 144, 6, 25, 249, 82, 6, 25, 249, 209, 
+    6, 25, 249, 197, 6, 25, 249, 163, 6, 25, 249, 193, 6, 25, 253, 163, 6, 
+    25, 253, 248, 6, 25, 243, 239, 6, 25, 249, 89, 6, 25, 249, 78, 6, 25, 
+    243, 202, 6, 25, 253, 177, 6, 25, 253, 232, 6, 25, 244, 15, 6, 25, 249, 
+    105, 6, 25, 254, 85, 6, 25, 243, 157, 6, 25, 249, 40, 6, 25, 243, 197, 6, 
+    25, 244, 8, 6, 25, 249, 223, 6, 25, 244, 13, 6, 25, 248, 88, 6, 25, 241, 
+    1, 6, 25, 243, 232, 6, 25, 253, 172, 49, 1, 238, 85, 188, 254, 15, 243, 
+    243, 49, 1, 238, 85, 188, 248, 122, 243, 243, 49, 1, 238, 85, 188, 254, 
+    15, 240, 222, 49, 1, 238, 85, 188, 248, 122, 240, 222, 49, 1, 238, 85, 
+    188, 254, 15, 254, 29, 49, 1, 238, 85, 188, 248, 122, 254, 29, 49, 1, 
+    238, 85, 188, 254, 15, 253, 185, 49, 1, 238, 85, 188, 248, 122, 253, 185, 
+    49, 1, 234, 27, 240, 4, 188, 125, 49, 1, 200, 240, 4, 188, 125, 49, 1, 
+    254, 40, 240, 4, 188, 125, 49, 1, 170, 240, 4, 188, 125, 49, 1, 235, 87, 
+    240, 4, 188, 125, 49, 1, 234, 27, 240, 4, 235, 64, 188, 125, 49, 1, 200, 
+    240, 4, 235, 64, 188, 125, 49, 1, 254, 40, 240, 4, 235, 64, 188, 125, 49, 
+    1, 170, 240, 4, 235, 64, 188, 125, 49, 1, 235, 87, 240, 4, 235, 64, 188, 
+    125, 49, 1, 234, 27, 235, 64, 188, 125, 49, 1, 200, 235, 64, 188, 125, 
+    49, 1, 254, 40, 235, 64, 188, 125, 49, 1, 170, 235, 64, 188, 125, 49, 1, 
+    235, 87, 235, 64, 188, 125, 239, 253, 242, 214, 1, 67, 239, 253, 242, 
+    214, 1, 71, 239, 253, 242, 214, 21, 236, 10, 239, 253, 242, 214, 1, 79, 
+    239, 253, 242, 214, 1, 72, 239, 253, 242, 214, 1, 73, 239, 253, 242, 214, 
+    21, 237, 170, 239, 253, 242, 214, 1, 253, 190, 239, 253, 242, 214, 1, 
+    248, 220, 239, 253, 242, 214, 1, 253, 234, 239, 253, 242, 214, 1, 249, 
+    75, 239, 253, 242, 214, 21, 235, 61, 239, 253, 242, 214, 1, 253, 224, 
+    239, 253, 242, 214, 1, 248, 125, 239, 253, 242, 214, 1, 253, 248, 239, 
+    253, 242, 214, 1, 251, 114, 239, 253, 242, 214, 1, 249, 6, 239, 253, 242, 
+    214, 1, 243, 131, 239, 253, 242, 214, 1, 248, 204, 239, 253, 242, 214, 1, 
+    245, 44, 239, 253, 242, 214, 1, 87, 239, 253, 242, 214, 1, 248, 97, 239, 
+    253, 242, 214, 1, 253, 225, 239, 253, 242, 214, 1, 250, 193, 239, 253, 
+    242, 214, 1, 253, 173, 239, 253, 242, 214, 1, 253, 208, 239, 253, 242, 
+    214, 1, 248, 238, 239, 253, 242, 214, 1, 254, 1, 239, 253, 242, 214, 1, 
+    250, 120, 239, 253, 242, 214, 1, 253, 181, 239, 253, 242, 214, 1, 253, 
+    160, 239, 253, 242, 214, 1, 253, 216, 239, 253, 242, 214, 1, 249, 157, 
+    239, 253, 242, 214, 1, 253, 186, 239, 253, 242, 214, 1, 253, 184, 239, 
+    253, 242, 214, 33, 21, 67, 239, 253, 242, 214, 33, 21, 71, 239, 253, 242, 
+    214, 33, 21, 79, 239, 253, 242, 214, 33, 21, 72, 239, 253, 242, 214, 33, 
+    21, 253, 156, 239, 253, 242, 214, 240, 120, 238, 200, 239, 253, 242, 214, 
+    240, 120, 238, 201, 239, 253, 242, 214, 240, 120, 239, 127, 239, 253, 
+    242, 214, 240, 120, 239, 128, 7, 9, 229, 68, 7, 9, 229, 69, 7, 9, 229, 
+    70, 7, 9, 229, 71, 7, 9, 229, 72, 7, 9, 229, 73, 7, 9, 229, 74, 7, 9, 
+    229, 75, 7, 9, 229, 76, 7, 9, 229, 77, 7, 9, 229, 78, 7, 9, 229, 79, 7, 
+    9, 229, 80, 7, 9, 229, 81, 7, 9, 229, 82, 7, 9, 229, 83, 7, 9, 229, 84, 
+    7, 9, 229, 85, 7, 9, 229, 86, 7, 9, 229, 87, 7, 9, 229, 88, 7, 9, 229, 
+    89, 7, 9, 229, 90, 7, 9, 229, 91, 7, 9, 229, 92, 7, 9, 229, 93, 7, 9, 
+    229, 94, 7, 9, 229, 95, 7, 9, 229, 96, 7, 9, 229, 97, 7, 9, 229, 98, 7, 
+    9, 229, 99, 7, 9, 229, 100, 7, 9, 229, 101, 7, 9, 229, 102, 7, 9, 229, 
+    103, 7, 9, 229, 104, 7, 9, 229, 105, 7, 9, 229, 106, 7, 9, 229, 107, 7, 
+    9, 229, 108, 7, 9, 229, 109, 7, 9, 229, 110, 7, 9, 229, 111, 7, 9, 229, 
+    112, 7, 9, 229, 113, 7, 9, 229, 114, 7, 9, 229, 115, 7, 9, 229, 116, 7, 
+    9, 229, 117, 7, 9, 229, 118, 7, 9, 229, 119, 7, 9, 229, 120, 7, 9, 229, 
+    121, 7, 9, 229, 122, 7, 9, 229, 123, 7, 9, 229, 124, 7, 9, 229, 125, 7, 
+    9, 229, 126, 7, 9, 229, 127, 7, 9, 229, 128, 7, 9, 229, 129, 7, 9, 229, 
+    130, 7, 9, 229, 131, 7, 9, 229, 132, 7, 9, 229, 133, 7, 9, 229, 134, 7, 
+    9, 229, 135, 7, 9, 229, 136, 7, 9, 229, 137, 7, 9, 229, 138, 7, 9, 229, 
+    139, 7, 9, 229, 140, 7, 9, 229, 141, 7, 9, 229, 142, 7, 9, 229, 143, 7, 
+    9, 229, 144, 7, 9, 229, 145, 7, 9, 229, 146, 7, 9, 229, 147, 7, 9, 229, 
+    148, 7, 9, 229, 149, 7, 9, 229, 150, 7, 9, 229, 151, 7, 9, 229, 152, 7, 
+    9, 229, 153, 7, 9, 229, 154, 7, 9, 229, 155, 7, 9, 229, 156, 7, 9, 229, 
+    157, 7, 9, 229, 158, 7, 9, 229, 159, 7, 9, 229, 160, 7, 9, 229, 161, 7, 
+    9, 229, 162, 7, 9, 229, 163, 7, 9, 229, 164, 7, 9, 229, 165, 7, 9, 229, 
+    166, 7, 9, 229, 167, 7, 9, 229, 168, 7, 9, 229, 169, 7, 9, 229, 170, 7, 
+    9, 229, 171, 7, 9, 229, 172, 7, 9, 229, 173, 7, 9, 229, 174, 7, 9, 229, 
+    175, 7, 9, 229, 176, 7, 9, 229, 177, 7, 9, 229, 178, 7, 9, 229, 179, 7, 
+    9, 229, 180, 7, 9, 229, 181, 7, 9, 229, 182, 7, 9, 229, 183, 7, 9, 229, 
+    184, 7, 9, 229, 185, 7, 9, 229, 186, 7, 9, 229, 187, 7, 9, 229, 188, 7, 
+    9, 229, 189, 7, 9, 229, 190, 7, 9, 229, 191, 7, 9, 229, 192, 7, 9, 229, 
+    193, 7, 9, 229, 194, 7, 9, 229, 195, 7, 9, 229, 196, 7, 9, 229, 197, 7, 
+    9, 229, 198, 7, 9, 229, 199, 7, 9, 229, 200, 7, 9, 229, 201, 7, 9, 229, 
+    202, 7, 9, 229, 203, 7, 9, 229, 204, 7, 9, 229, 205, 7, 9, 229, 206, 7, 
+    9, 229, 207, 7, 9, 229, 208, 7, 9, 229, 209, 7, 9, 229, 210, 7, 9, 229, 
+    211, 7, 9, 229, 212, 7, 9, 229, 213, 7, 9, 229, 214, 7, 9, 229, 215, 7, 
+    9, 229, 216, 7, 9, 229, 217, 7, 9, 229, 218, 7, 9, 229, 219, 7, 9, 229, 
+    220, 7, 9, 229, 221, 7, 9, 229, 222, 7, 9, 229, 223, 7, 9, 229, 224, 7, 
+    9, 229, 225, 7, 9, 229, 226, 7, 9, 229, 227, 7, 9, 229, 228, 7, 9, 229, 
+    229, 7, 9, 229, 230, 7, 9, 229, 231, 7, 9, 229, 232, 7, 9, 229, 233, 7, 
+    9, 229, 234, 7, 9, 229, 235, 7, 9, 229, 236, 7, 9, 229, 237, 7, 9, 229, 
+    238, 7, 9, 229, 239, 7, 9, 229, 240, 7, 9, 229, 241, 7, 9, 229, 242, 7, 
+    9, 229, 243, 7, 9, 229, 244, 7, 9, 229, 245, 7, 9, 229, 246, 7, 9, 229, 
+    247, 7, 9, 229, 248, 7, 9, 229, 249, 7, 9, 229, 250, 7, 9, 229, 251, 7, 
+    9, 229, 252, 7, 9, 229, 253, 7, 9, 229, 254, 7, 9, 229, 255, 7, 9, 230, 
+    0, 7, 9, 230, 1, 7, 9, 230, 2, 7, 9, 230, 3, 7, 9, 230, 4, 7, 9, 230, 5, 
+    7, 9, 230, 6, 7, 9, 230, 7, 7, 9, 230, 8, 7, 9, 230, 9, 7, 9, 230, 10, 7, 
+    9, 230, 11, 7, 9, 230, 12, 7, 9, 230, 13, 7, 9, 230, 14, 7, 9, 230, 15, 
+    7, 9, 230, 16, 7, 9, 230, 17, 7, 9, 230, 18, 7, 9, 230, 19, 7, 9, 230, 
+    20, 7, 9, 230, 21, 7, 9, 230, 22, 7, 9, 230, 23, 7, 9, 230, 24, 7, 9, 
+    230, 25, 7, 9, 230, 26, 7, 9, 230, 27, 7, 9, 230, 28, 7, 9, 230, 29, 7, 
+    9, 230, 30, 7, 9, 230, 31, 7, 9, 230, 32, 7, 9, 230, 33, 7, 9, 230, 34, 
+    7, 9, 230, 35, 7, 9, 230, 36, 7, 9, 230, 37, 7, 9, 230, 38, 7, 9, 230, 
+    39, 7, 9, 230, 40, 7, 9, 230, 41, 7, 9, 230, 42, 7, 9, 230, 43, 7, 9, 
+    230, 44, 7, 9, 230, 45, 7, 9, 230, 46, 7, 9, 230, 47, 7, 9, 230, 48, 7, 
+    9, 230, 49, 7, 9, 230, 50, 7, 9, 230, 51, 7, 9, 230, 52, 7, 9, 230, 53, 
+    7, 9, 230, 54, 7, 9, 230, 55, 7, 9, 230, 56, 7, 9, 230, 57, 7, 9, 230, 
+    58, 7, 9, 230, 59, 7, 9, 230, 60, 7, 9, 230, 61, 7, 9, 230, 62, 7, 9, 
+    230, 63, 7, 9, 230, 64, 7, 9, 230, 65, 7, 9, 230, 66, 7, 9, 230, 67, 7, 
+    9, 230, 68, 7, 9, 230, 69, 7, 9, 230, 70, 7, 9, 230, 71, 7, 9, 230, 72, 
+    7, 9, 230, 73, 7, 9, 230, 74, 7, 9, 230, 75, 7, 9, 230, 76, 7, 9, 230, 
+    77, 7, 9, 230, 78, 7, 9, 230, 79, 7, 9, 230, 80, 7, 9, 230, 81, 7, 9, 
+    230, 82, 7, 9, 230, 83, 7, 9, 230, 84, 7, 9, 230, 85, 7, 9, 230, 86, 7, 
+    9, 230, 87, 7, 9, 230, 88, 7, 9, 230, 89, 7, 9, 230, 90, 7, 9, 230, 91, 
+    7, 9, 230, 92, 7, 9, 230, 93, 7, 9, 230, 94, 7, 9, 230, 95, 7, 9, 230, 
+    96, 7, 9, 230, 97, 7, 9, 230, 98, 7, 9, 230, 99, 7, 9, 230, 100, 7, 9, 
+    230, 101, 7, 9, 230, 102, 7, 9, 230, 103, 7, 9, 230, 104, 7, 9, 230, 105, 
+    7, 9, 230, 106, 7, 9, 230, 107, 7, 9, 230, 108, 7, 9, 230, 109, 7, 9, 
+    230, 110, 7, 9, 230, 111, 7, 9, 230, 112, 7, 9, 230, 113, 7, 9, 230, 114, 
+    7, 9, 230, 115, 7, 9, 230, 116, 7, 9, 230, 117, 7, 9, 230, 118, 7, 9, 
+    230, 119, 7, 9, 230, 120, 7, 9, 230, 121, 7, 9, 230, 122, 7, 9, 230, 123, 
+    7, 9, 230, 124, 7, 9, 230, 125, 7, 9, 230, 126, 7, 9, 230, 127, 7, 9, 
+    230, 128, 7, 9, 230, 129, 7, 9, 230, 130, 7, 9, 230, 131, 7, 9, 230, 132, 
+    7, 9, 230, 133, 7, 9, 230, 134, 7, 9, 230, 135, 7, 9, 230, 136, 7, 9, 
+    230, 137, 7, 9, 230, 138, 7, 9, 230, 139, 7, 9, 230, 140, 7, 9, 230, 141, 
+    7, 9, 230, 142, 7, 9, 230, 143, 7, 9, 230, 144, 7, 9, 230, 145, 7, 9, 
+    230, 146, 7, 9, 230, 147, 7, 9, 230, 148, 7, 9, 230, 149, 7, 9, 230, 150, 
+    7, 9, 230, 151, 7, 9, 230, 152, 7, 9, 230, 153, 7, 9, 230, 154, 7, 9, 
+    230, 155, 7, 9, 230, 156, 7, 9, 230, 157, 7, 9, 230, 158, 7, 9, 230, 159, 
+    7, 9, 230, 160, 7, 9, 230, 161, 7, 9, 230, 162, 7, 9, 230, 163, 7, 9, 
+    230, 164, 7, 9, 230, 165, 7, 9, 230, 166, 7, 9, 230, 167, 7, 9, 230, 168, 
+    7, 9, 230, 169, 7, 9, 230, 170, 7, 9, 230, 171, 7, 9, 230, 172, 7, 9, 
+    230, 173, 7, 9, 230, 174, 7, 9, 230, 175, 7, 9, 230, 176, 7, 9, 230, 177, 
+    7, 9, 230, 178, 7, 9, 230, 179, 7, 9, 230, 180, 7, 9, 230, 181, 7, 9, 
+    230, 182, 7, 9, 230, 183, 7, 9, 230, 184, 7, 9, 230, 185, 7, 9, 230, 186, 
+    7, 9, 230, 187, 7, 9, 230, 188, 7, 9, 230, 189, 7, 9, 230, 190, 7, 9, 
+    230, 191, 7, 9, 230, 192, 7, 9, 230, 193, 7, 9, 230, 194, 7, 9, 230, 195, 
+    7, 9, 230, 196, 7, 9, 230, 197, 7, 9, 230, 198, 7, 9, 230, 199, 7, 9, 
+    230, 200, 7, 9, 230, 201, 7, 9, 230, 202, 7, 9, 230, 203, 7, 9, 230, 204, 
+    7, 9, 230, 205, 7, 9, 230, 206, 7, 9, 230, 207, 7, 9, 230, 208, 7, 9, 
+    230, 209, 7, 9, 230, 210, 7, 9, 230, 211, 7, 9, 230, 212, 7, 9, 230, 213, 
+    7, 9, 230, 214, 7, 9, 230, 215, 7, 9, 230, 216, 7, 9, 230, 217, 7, 9, 
+    230, 218, 7, 9, 230, 219, 7, 9, 230, 220, 7, 9, 230, 221, 7, 9, 230, 222, 
+    7, 9, 230, 223, 7, 9, 230, 224, 7, 9, 230, 225, 7, 9, 230, 226, 7, 9, 
+    230, 227, 7, 9, 230, 228, 7, 9, 230, 229, 7, 9, 230, 230, 7, 9, 230, 231, 
+    7, 9, 230, 232, 7, 9, 230, 233, 7, 9, 230, 234, 7, 9, 230, 235, 7, 9, 
+    230, 236, 7, 9, 230, 237, 7, 9, 230, 238, 7, 9, 230, 239, 7, 9, 230, 240, 
+    7, 9, 230, 241, 7, 9, 230, 242, 7, 9, 230, 243, 7, 9, 230, 244, 7, 9, 
+    230, 245, 7, 9, 230, 246, 7, 9, 230, 247, 7, 9, 230, 248, 7, 9, 230, 249, 
+    7, 9, 230, 250, 7, 9, 230, 251, 7, 9, 230, 252, 7, 9, 230, 253, 7, 9, 
+    230, 254, 7, 9, 230, 255, 7, 9, 231, 0, 7, 9, 231, 1, 7, 9, 231, 2, 7, 9, 
+    231, 3, 7, 9, 231, 4, 7, 9, 231, 5, 7, 9, 231, 6, 7, 9, 231, 7, 7, 9, 
+    231, 8, 7, 9, 231, 9, 7, 9, 231, 10, 7, 9, 231, 11, 7, 9, 231, 12, 7, 9, 
+    231, 13, 7, 9, 231, 14, 7, 9, 231, 15, 7, 9, 231, 16, 7, 9, 231, 17, 7, 
+    9, 231, 18, 7, 9, 231, 19, 7, 9, 231, 20, 7, 9, 231, 21, 7, 9, 231, 22, 
+    8, 3, 18, 254, 162, 8, 3, 18, 253, 245, 8, 3, 18, 254, 163, 8, 3, 18, 
+    250, 241, 8, 3, 18, 250, 242, 8, 3, 18, 183, 255, 99, 214, 8, 3, 18, 254, 
+    242, 100, 3, 18, 254, 39, 248, 175, 100, 3, 18, 254, 39, 248, 208, 100, 
+    3, 18, 254, 39, 248, 216, 100, 3, 18, 255, 0, 248, 175, 100, 3, 18, 254, 
+    39, 249, 17, 68, 1, 254, 50, 2, 240, 187, 68, 242, 232, 231, 144, 239, 
+    241, 68, 18, 238, 126, 254, 50, 254, 50, 240, 118, 68, 1, 233, 68, 243, 
+    144, 68, 1, 248, 98, 243, 3, 68, 1, 248, 98, 240, 165, 68, 1, 248, 98, 
+    253, 168, 68, 1, 248, 98, 248, 116, 68, 1, 248, 98, 240, 139, 68, 1, 248, 
+    98, 30, 248, 166, 68, 1, 248, 98, 243, 253, 68, 1, 248, 98, 249, 175, 68, 
+    1, 233, 68, 248, 49, 52, 68, 1, 248, 102, 2, 248, 102, 248, 40, 68, 1, 
+    248, 102, 2, 254, 73, 248, 40, 68, 1, 248, 102, 2, 240, 133, 19, 248, 
+    102, 248, 40, 68, 1, 248, 102, 2, 240, 133, 19, 254, 73, 248, 40, 68, 1, 
+    83, 2, 240, 118, 68, 1, 83, 2, 238, 149, 68, 1, 83, 2, 240, 140, 68, 1, 
+    254, 53, 2, 238, 61, 68, 1, 243, 184, 2, 238, 61, 68, 1, 243, 162, 2, 
+    238, 61, 68, 1, 255, 76, 2, 240, 140, 68, 1, 254, 76, 2, 238, 61, 68, 1, 
+    247, 244, 2, 238, 61, 68, 1, 254, 247, 2, 238, 61, 68, 1, 254, 50, 2, 
+    238, 61, 68, 1, 30, 253, 135, 2, 238, 61, 68, 1, 253, 135, 2, 238, 61, 
+    68, 1, 246, 38, 2, 238, 61, 68, 1, 254, 201, 2, 238, 61, 68, 1, 254, 114, 
+    2, 238, 61, 68, 1, 242, 94, 2, 238, 61, 68, 1, 30, 255, 38, 2, 238, 61, 
+    68, 1, 255, 38, 2, 238, 61, 68, 1, 247, 161, 2, 238, 61, 68, 1, 254, 233, 
+    2, 238, 61, 68, 1, 252, 134, 2, 238, 61, 68, 1, 248, 102, 2, 238, 61, 68, 
+    1, 254, 245, 2, 238, 61, 68, 1, 254, 76, 2, 240, 188, 68, 1, 254, 53, 2, 
+    243, 70, 68, 1, 253, 135, 2, 243, 70, 68, 1, 255, 38, 2, 243, 70, 68, 18, 
+    83, 240, 139, 11, 1, 83, 244, 49, 39, 13, 11, 1, 83, 244, 49, 30, 13, 11, 
+    1, 248, 147, 39, 13, 11, 1, 248, 147, 30, 13, 11, 1, 248, 147, 54, 13, 
+    11, 1, 248, 147, 113, 13, 11, 1, 254, 44, 39, 13, 11, 1, 254, 44, 30, 13, 
+    11, 1, 254, 44, 54, 13, 11, 1, 254, 44, 113, 13, 11, 1, 243, 52, 39, 13, 
+    11, 1, 243, 52, 30, 13, 11, 1, 243, 52, 54, 13, 11, 1, 243, 52, 113, 13, 
+    11, 1, 240, 124, 39, 13, 11, 1, 240, 124, 30, 13, 11, 1, 240, 124, 54, 
+    13, 11, 1, 240, 124, 113, 13, 11, 1, 243, 75, 39, 13, 11, 1, 243, 75, 30, 
+    13, 11, 1, 243, 75, 54, 13, 11, 1, 243, 75, 113, 13, 11, 1, 248, 189, 39, 
+    13, 11, 1, 248, 189, 30, 13, 11, 1, 248, 189, 54, 13, 11, 1, 248, 189, 
+    113, 13, 11, 1, 254, 47, 39, 13, 11, 1, 254, 47, 30, 13, 11, 1, 254, 47, 
+    54, 13, 11, 1, 254, 47, 113, 13, 11, 1, 243, 69, 39, 13, 11, 1, 243, 69, 
+    30, 13, 11, 1, 243, 69, 54, 13, 11, 1, 243, 69, 113, 13, 11, 1, 248, 152, 
+    39, 13, 11, 1, 248, 152, 30, 13, 11, 1, 248, 152, 54, 13, 11, 1, 248, 
+    152, 113, 13, 11, 1, 248, 177, 39, 13, 11, 1, 248, 177, 30, 13, 11, 1, 
+    248, 177, 54, 13, 11, 1, 248, 177, 113, 13, 11, 1, 243, 47, 39, 13, 11, 
+    1, 243, 47, 30, 13, 11, 1, 243, 47, 54, 13, 11, 1, 243, 47, 113, 13, 11, 
+    1, 238, 123, 39, 13, 11, 1, 238, 123, 30, 13, 11, 1, 238, 123, 54, 13, 
+    11, 1, 238, 123, 113, 13, 11, 1, 240, 166, 39, 13, 11, 1, 240, 166, 30, 
+    13, 11, 1, 243, 161, 39, 13, 11, 1, 243, 161, 30, 13, 11, 1, 254, 87, 39, 
+    13, 11, 1, 254, 87, 30, 13, 11, 1, 249, 49, 39, 13, 11, 1, 249, 49, 30, 
+    13, 11, 1, 254, 103, 39, 13, 11, 1, 254, 103, 30, 13, 11, 1, 249, 156, 
+    39, 13, 11, 1, 249, 156, 30, 13, 11, 1, 243, 21, 39, 13, 11, 1, 243, 21, 
+    30, 13, 11, 1, 243, 21, 54, 13, 11, 1, 243, 21, 113, 13, 11, 1, 253, 246, 
+    39, 13, 11, 1, 253, 246, 30, 13, 11, 1, 253, 246, 54, 13, 11, 1, 253, 
+    246, 113, 13, 11, 1, 248, 159, 39, 13, 11, 1, 248, 159, 30, 13, 11, 1, 
+    248, 159, 54, 13, 11, 1, 248, 159, 113, 13, 11, 1, 243, 67, 39, 13, 11, 
+    1, 243, 67, 30, 13, 11, 1, 243, 67, 54, 13, 11, 1, 243, 67, 113, 13, 11, 
+    1, 198, 240, 182, 39, 13, 11, 1, 198, 240, 182, 30, 13, 11, 1, 243, 71, 
+    39, 13, 11, 1, 243, 71, 30, 13, 11, 1, 243, 71, 54, 13, 11, 1, 243, 71, 
+    113, 13, 11, 1, 253, 124, 2, 57, 60, 39, 13, 11, 1, 253, 124, 2, 57, 60, 
+    30, 13, 11, 1, 253, 124, 248, 128, 39, 13, 11, 1, 253, 124, 248, 128, 30, 
+    13, 11, 1, 253, 124, 248, 128, 54, 13, 11, 1, 253, 124, 248, 128, 113, 
+    13, 11, 1, 253, 124, 233, 65, 39, 13, 11, 1, 253, 124, 233, 65, 30, 13, 
+    11, 1, 253, 124, 233, 65, 54, 13, 11, 1, 253, 124, 233, 65, 113, 13, 11, 
+    1, 57, 240, 92, 39, 13, 11, 1, 57, 240, 92, 30, 13, 11, 1, 57, 240, 92, 
+    2, 143, 60, 39, 13, 11, 1, 57, 240, 92, 2, 143, 60, 30, 13, 11, 1, 255, 
+    44, 39, 13, 11, 1, 255, 44, 30, 13, 11, 1, 255, 44, 54, 13, 11, 1, 255, 
+    44, 113, 13, 11, 1, 132, 39, 13, 11, 1, 132, 30, 13, 11, 1, 255, 33, 39, 
+    13, 11, 1, 255, 33, 30, 13, 11, 1, 255, 36, 39, 13, 11, 1, 255, 36, 30, 
+    13, 11, 1, 132, 2, 143, 60, 39, 13, 11, 1, 255, 65, 39, 13, 11, 1, 255, 
+    65, 30, 13, 11, 1, 238, 73, 255, 33, 39, 13, 11, 1, 238, 73, 255, 33, 30, 
+    13, 11, 1, 238, 73, 255, 36, 39, 13, 11, 1, 238, 73, 255, 36, 30, 13, 11, 
+    1, 157, 39, 13, 11, 1, 157, 30, 13, 11, 1, 157, 54, 13, 11, 1, 157, 113, 
+    13, 11, 1, 240, 104, 240, 192, 238, 73, 83, 150, 54, 13, 11, 1, 240, 104, 
+    240, 192, 238, 73, 83, 150, 113, 13, 11, 18, 57, 2, 143, 60, 2, 83, 39, 
+    13, 11, 18, 57, 2, 143, 60, 2, 83, 30, 13, 11, 18, 57, 2, 143, 60, 2, 
+    255, 30, 39, 13, 11, 18, 57, 2, 143, 60, 2, 255, 30, 30, 13, 11, 18, 57, 
+    2, 143, 60, 2, 253, 220, 39, 13, 11, 18, 57, 2, 143, 60, 2, 253, 220, 30, 
+    13, 11, 18, 57, 2, 143, 60, 2, 132, 39, 13, 11, 18, 57, 2, 143, 60, 2, 
+    132, 30, 13, 11, 18, 57, 2, 143, 60, 2, 255, 33, 39, 13, 11, 18, 57, 2, 
+    143, 60, 2, 255, 33, 30, 13, 11, 18, 57, 2, 143, 60, 2, 255, 36, 39, 13, 
+    11, 18, 57, 2, 143, 60, 2, 255, 36, 30, 13, 11, 18, 57, 2, 143, 60, 2, 
+    157, 39, 13, 11, 18, 57, 2, 143, 60, 2, 157, 30, 13, 11, 18, 57, 2, 143, 
+    60, 2, 157, 54, 13, 11, 18, 240, 104, 238, 73, 57, 2, 143, 60, 2, 83, 
+    150, 39, 13, 11, 18, 240, 104, 238, 73, 57, 2, 143, 60, 2, 83, 150, 30, 
+    13, 11, 18, 240, 104, 238, 73, 57, 2, 143, 60, 2, 83, 150, 54, 13, 11, 1, 
+    243, 26, 57, 39, 13, 11, 1, 243, 26, 57, 30, 13, 11, 1, 243, 26, 57, 54, 
+    13, 11, 1, 243, 26, 57, 113, 13, 11, 18, 57, 2, 143, 60, 2, 103, 39, 13, 
+    11, 18, 57, 2, 143, 60, 2, 94, 39, 13, 11, 18, 57, 2, 143, 60, 2, 51, 39, 
+    13, 11, 18, 57, 2, 143, 60, 2, 83, 150, 39, 13, 11, 18, 57, 2, 143, 60, 
+    2, 57, 39, 13, 11, 18, 253, 136, 2, 103, 39, 13, 11, 18, 253, 136, 2, 94, 
+    39, 13, 11, 18, 253, 136, 2, 164, 39, 13, 11, 18, 253, 136, 2, 51, 39, 
+    13, 11, 18, 253, 136, 2, 83, 150, 39, 13, 11, 18, 253, 136, 2, 57, 39, 
+    13, 11, 18, 253, 127, 2, 103, 39, 13, 11, 18, 253, 127, 2, 94, 39, 13, 
+    11, 18, 253, 127, 2, 164, 39, 13, 11, 18, 253, 127, 2, 51, 39, 13, 11, 
+    18, 253, 127, 2, 83, 150, 39, 13, 11, 18, 253, 127, 2, 57, 39, 13, 11, 
+    18, 248, 70, 2, 103, 39, 13, 11, 18, 248, 70, 2, 51, 39, 13, 11, 18, 248, 
+    70, 2, 83, 150, 39, 13, 11, 18, 248, 70, 2, 57, 39, 13, 11, 18, 103, 2, 
+    94, 39, 13, 11, 18, 103, 2, 51, 39, 13, 11, 18, 94, 2, 103, 39, 13, 11, 
+    18, 94, 2, 51, 39, 13, 11, 18, 164, 2, 103, 39, 13, 11, 18, 164, 2, 94, 
+    39, 13, 11, 18, 164, 2, 51, 39, 13, 11, 18, 248, 39, 2, 103, 39, 13, 11, 
+    18, 248, 39, 2, 94, 39, 13, 11, 18, 248, 39, 2, 164, 39, 13, 11, 18, 248, 
+    39, 2, 51, 39, 13, 11, 18, 253, 157, 2, 94, 39, 13, 11, 18, 253, 157, 2, 
+    51, 39, 13, 11, 18, 253, 155, 2, 103, 39, 13, 11, 18, 253, 155, 2, 94, 
+    39, 13, 11, 18, 253, 155, 2, 164, 39, 13, 11, 18, 253, 155, 2, 51, 39, 
+    13, 11, 18, 253, 169, 2, 94, 39, 13, 11, 18, 253, 169, 2, 51, 39, 13, 11, 
+    18, 253, 255, 2, 51, 39, 13, 11, 18, 253, 158, 2, 103, 39, 13, 11, 18, 
+    253, 158, 2, 51, 39, 13, 11, 18, 242, 240, 2, 103, 39, 13, 11, 18, 242, 
+    240, 2, 51, 39, 13, 11, 18, 253, 153, 2, 103, 39, 13, 11, 18, 253, 153, 
+    2, 94, 39, 13, 11, 18, 253, 153, 2, 164, 39, 13, 11, 18, 253, 153, 2, 51, 
+    39, 13, 11, 18, 253, 153, 2, 83, 150, 39, 13, 11, 18, 253, 153, 2, 57, 
+    39, 13, 11, 18, 253, 167, 2, 94, 39, 13, 11, 18, 253, 167, 2, 51, 39, 13, 
+    11, 18, 253, 167, 2, 83, 150, 39, 13, 11, 18, 253, 167, 2, 57, 39, 13, 
+    11, 18, 253, 135, 2, 83, 39, 13, 11, 18, 253, 135, 2, 103, 39, 13, 11, 
+    18, 253, 135, 2, 94, 39, 13, 11, 18, 253, 135, 2, 164, 39, 13, 11, 18, 
+    253, 135, 2, 182, 39, 13, 11, 18, 253, 135, 2, 51, 39, 13, 11, 18, 253, 
+    135, 2, 83, 150, 39, 13, 11, 18, 253, 135, 2, 57, 39, 13, 11, 18, 182, 2, 
+    103, 39, 13, 11, 18, 182, 2, 94, 39, 13, 11, 18, 182, 2, 164, 39, 13, 11, 
+    18, 182, 2, 51, 39, 13, 11, 18, 182, 2, 83, 150, 39, 13, 11, 18, 182, 2, 
+    57, 39, 13, 11, 18, 51, 2, 103, 39, 13, 11, 18, 51, 2, 94, 39, 13, 11, 
+    18, 51, 2, 164, 39, 13, 11, 18, 51, 2, 51, 39, 13, 11, 18, 51, 2, 83, 
+    150, 39, 13, 11, 18, 51, 2, 57, 39, 13, 11, 18, 198, 2, 103, 39, 13, 11, 
+    18, 198, 2, 94, 39, 13, 11, 18, 198, 2, 164, 39, 13, 11, 18, 198, 2, 51, 
+    39, 13, 11, 18, 198, 2, 83, 150, 39, 13, 11, 18, 198, 2, 57, 39, 13, 11, 
+    18, 253, 124, 2, 103, 39, 13, 11, 18, 253, 124, 2, 51, 39, 13, 11, 18, 
+    253, 124, 2, 83, 150, 39, 13, 11, 18, 253, 124, 2, 57, 39, 13, 11, 18, 
+    57, 2, 103, 39, 13, 11, 18, 57, 2, 94, 39, 13, 11, 18, 57, 2, 164, 39, 
+    13, 11, 18, 57, 2, 51, 39, 13, 11, 18, 57, 2, 83, 150, 39, 13, 11, 18, 
+    57, 2, 57, 39, 13, 11, 18, 249, 0, 2, 233, 49, 83, 39, 13, 11, 18, 253, 
+    143, 2, 233, 49, 83, 39, 13, 11, 18, 83, 150, 2, 233, 49, 83, 39, 13, 11, 
+    18, 240, 47, 2, 237, 1, 39, 13, 11, 18, 240, 47, 2, 237, 15, 39, 13, 11, 
+    18, 240, 47, 2, 243, 40, 39, 13, 11, 18, 240, 47, 2, 243, 56, 39, 13, 11, 
+    18, 240, 47, 2, 243, 63, 39, 13, 11, 18, 240, 47, 2, 233, 49, 83, 39, 13, 
+    11, 18, 57, 2, 143, 60, 2, 253, 143, 30, 13, 11, 18, 57, 2, 143, 60, 2, 
+    248, 104, 30, 13, 11, 18, 57, 2, 143, 60, 2, 51, 30, 13, 11, 18, 57, 2, 
+    143, 60, 2, 198, 30, 13, 11, 18, 57, 2, 143, 60, 2, 83, 150, 30, 13, 11, 
+    18, 57, 2, 143, 60, 2, 57, 30, 13, 11, 18, 253, 136, 2, 253, 143, 30, 13, 
+    11, 18, 253, 136, 2, 248, 104, 30, 13, 11, 18, 253, 136, 2, 51, 30, 13, 
+    11, 18, 253, 136, 2, 198, 30, 13, 11, 18, 253, 136, 2, 83, 150, 30, 13, 
+    11, 18, 253, 136, 2, 57, 30, 13, 11, 18, 253, 127, 2, 253, 143, 30, 13, 
+    11, 18, 253, 127, 2, 248, 104, 30, 13, 11, 18, 253, 127, 2, 51, 30, 13, 
+    11, 18, 253, 127, 2, 198, 30, 13, 11, 18, 253, 127, 2, 83, 150, 30, 13, 
+    11, 18, 253, 127, 2, 57, 30, 13, 11, 18, 248, 70, 2, 253, 143, 30, 13, 
+    11, 18, 248, 70, 2, 248, 104, 30, 13, 11, 18, 248, 70, 2, 51, 30, 13, 11, 
+    18, 248, 70, 2, 198, 30, 13, 11, 18, 248, 70, 2, 83, 150, 30, 13, 11, 18, 
+    248, 70, 2, 57, 30, 13, 11, 18, 253, 153, 2, 83, 150, 30, 13, 11, 18, 
+    253, 153, 2, 57, 30, 13, 11, 18, 253, 167, 2, 83, 150, 30, 13, 11, 18, 
+    253, 167, 2, 57, 30, 13, 11, 18, 253, 135, 2, 83, 30, 13, 11, 18, 253, 
+    135, 2, 182, 30, 13, 11, 18, 253, 135, 2, 51, 30, 13, 11, 18, 253, 135, 
+    2, 83, 150, 30, 13, 11, 18, 253, 135, 2, 57, 30, 13, 11, 18, 182, 2, 51, 
+    30, 13, 11, 18, 182, 2, 83, 150, 30, 13, 11, 18, 182, 2, 57, 30, 13, 11, 
+    18, 51, 2, 83, 30, 13, 11, 18, 51, 2, 51, 30, 13, 11, 18, 198, 2, 253, 
+    143, 30, 13, 11, 18, 198, 2, 248, 104, 30, 13, 11, 18, 198, 2, 51, 30, 
+    13, 11, 18, 198, 2, 198, 30, 13, 11, 18, 198, 2, 83, 150, 30, 13, 11, 18, 
+    198, 2, 57, 30, 13, 11, 18, 83, 150, 2, 233, 49, 83, 30, 13, 11, 18, 57, 
+    2, 253, 143, 30, 13, 11, 18, 57, 2, 248, 104, 30, 13, 11, 18, 57, 2, 51, 
+    30, 13, 11, 18, 57, 2, 198, 30, 13, 11, 18, 57, 2, 83, 150, 30, 13, 11, 
+    18, 57, 2, 57, 30, 13, 11, 18, 57, 2, 143, 60, 2, 103, 54, 13, 11, 18, 
+    57, 2, 143, 60, 2, 94, 54, 13, 11, 18, 57, 2, 143, 60, 2, 164, 54, 13, 
+    11, 18, 57, 2, 143, 60, 2, 51, 54, 13, 11, 18, 57, 2, 143, 60, 2, 253, 
+    124, 54, 13, 11, 18, 253, 136, 2, 103, 54, 13, 11, 18, 253, 136, 2, 94, 
+    54, 13, 11, 18, 253, 136, 2, 164, 54, 13, 11, 18, 253, 136, 2, 51, 54, 
+    13, 11, 18, 253, 136, 2, 253, 124, 54, 13, 11, 18, 253, 127, 2, 103, 54, 
+    13, 11, 18, 253, 127, 2, 94, 54, 13, 11, 18, 253, 127, 2, 164, 54, 13, 
+    11, 18, 253, 127, 2, 51, 54, 13, 11, 18, 253, 127, 2, 253, 124, 54, 13, 
+    11, 18, 248, 70, 2, 51, 54, 13, 11, 18, 103, 2, 94, 54, 13, 11, 18, 103, 
+    2, 51, 54, 13, 11, 18, 94, 2, 103, 54, 13, 11, 18, 94, 2, 51, 54, 13, 11, 
+    18, 164, 2, 103, 54, 13, 11, 18, 164, 2, 51, 54, 13, 11, 18, 248, 39, 2, 
+    103, 54, 13, 11, 18, 248, 39, 2, 94, 54, 13, 11, 18, 248, 39, 2, 164, 54, 
+    13, 11, 18, 248, 39, 2, 51, 54, 13, 11, 18, 253, 157, 2, 94, 54, 13, 11, 
+    18, 253, 157, 2, 164, 54, 13, 11, 18, 253, 157, 2, 51, 54, 13, 11, 18, 
+    253, 155, 2, 103, 54, 13, 11, 18, 253, 155, 2, 94, 54, 13, 11, 18, 253, 
+    155, 2, 164, 54, 13, 11, 18, 253, 155, 2, 51, 54, 13, 11, 18, 253, 169, 
+    2, 94, 54, 13, 11, 18, 253, 255, 2, 51, 54, 13, 11, 18, 253, 158, 2, 103, 
+    54, 13, 11, 18, 253, 158, 2, 51, 54, 13, 11, 18, 242, 240, 2, 103, 54, 
+    13, 11, 18, 242, 240, 2, 51, 54, 13, 11, 18, 253, 153, 2, 103, 54, 13, 
+    11, 18, 253, 153, 2, 94, 54, 13, 11, 18, 253, 153, 2, 164, 54, 13, 11, 
+    18, 253, 153, 2, 51, 54, 13, 11, 18, 253, 167, 2, 94, 54, 13, 11, 18, 
+    253, 167, 2, 51, 54, 13, 11, 18, 253, 135, 2, 103, 54, 13, 11, 18, 253, 
+    135, 2, 94, 54, 13, 11, 18, 253, 135, 2, 164, 54, 13, 11, 18, 253, 135, 
+    2, 182, 54, 13, 11, 18, 253, 135, 2, 51, 54, 13, 11, 18, 182, 2, 103, 54, 
+    13, 11, 18, 182, 2, 94, 54, 13, 11, 18, 182, 2, 164, 54, 13, 11, 18, 182, 
+    2, 51, 54, 13, 11, 18, 182, 2, 253, 124, 54, 13, 11, 18, 51, 2, 103, 54, 
+    13, 11, 18, 51, 2, 94, 54, 13, 11, 18, 51, 2, 164, 54, 13, 11, 18, 51, 2, 
+    51, 54, 13, 11, 18, 198, 2, 103, 54, 13, 11, 18, 198, 2, 94, 54, 13, 11, 
+    18, 198, 2, 164, 54, 13, 11, 18, 198, 2, 51, 54, 13, 11, 18, 198, 2, 253, 
+    124, 54, 13, 11, 18, 253, 124, 2, 103, 54, 13, 11, 18, 253, 124, 2, 51, 
+    54, 13, 11, 18, 253, 124, 2, 233, 49, 83, 54, 13, 11, 18, 57, 2, 103, 54, 
+    13, 11, 18, 57, 2, 94, 54, 13, 11, 18, 57, 2, 164, 54, 13, 11, 18, 57, 2, 
+    51, 54, 13, 11, 18, 57, 2, 253, 124, 54, 13, 11, 18, 57, 2, 143, 60, 2, 
+    51, 113, 13, 11, 18, 57, 2, 143, 60, 2, 253, 124, 113, 13, 11, 18, 253, 
+    136, 2, 51, 113, 13, 11, 18, 253, 136, 2, 253, 124, 113, 13, 11, 18, 253, 
+    127, 2, 51, 113, 13, 11, 18, 253, 127, 2, 253, 124, 113, 13, 11, 18, 248, 
+    70, 2, 51, 113, 13, 11, 18, 248, 70, 2, 253, 124, 113, 13, 11, 18, 248, 
+    39, 2, 51, 113, 13, 11, 18, 248, 39, 2, 253, 124, 113, 13, 11, 18, 242, 
+    216, 2, 51, 113, 13, 11, 18, 242, 216, 2, 253, 124, 113, 13, 11, 18, 253, 
+    135, 2, 182, 113, 13, 11, 18, 253, 135, 2, 51, 113, 13, 11, 18, 182, 2, 
+    51, 113, 13, 11, 18, 198, 2, 51, 113, 13, 11, 18, 198, 2, 253, 124, 113, 
+    13, 11, 18, 57, 2, 51, 113, 13, 11, 18, 57, 2, 253, 124, 113, 13, 11, 18, 
+    240, 47, 2, 243, 40, 113, 13, 11, 18, 240, 47, 2, 243, 56, 113, 13, 11, 
+    18, 240, 47, 2, 243, 63, 113, 13, 11, 18, 253, 169, 2, 83, 150, 39, 13, 
+    11, 18, 253, 169, 2, 57, 39, 13, 11, 18, 253, 158, 2, 83, 150, 39, 13, 
+    11, 18, 253, 158, 2, 57, 39, 13, 11, 18, 242, 240, 2, 83, 150, 39, 13, 
+    11, 18, 242, 240, 2, 57, 39, 13, 11, 18, 248, 39, 2, 83, 150, 39, 13, 11, 
+    18, 248, 39, 2, 57, 39, 13, 11, 18, 242, 216, 2, 83, 150, 39, 13, 11, 18, 
+    242, 216, 2, 57, 39, 13, 11, 18, 94, 2, 83, 150, 39, 13, 11, 18, 94, 2, 
+    57, 39, 13, 11, 18, 103, 2, 83, 150, 39, 13, 11, 18, 103, 2, 57, 39, 13, 
+    11, 18, 164, 2, 83, 150, 39, 13, 11, 18, 164, 2, 57, 39, 13, 11, 18, 253, 
+    157, 2, 83, 150, 39, 13, 11, 18, 253, 157, 2, 57, 39, 13, 11, 18, 253, 
+    155, 2, 83, 150, 39, 13, 11, 18, 253, 155, 2, 57, 39, 13, 11, 18, 242, 
+    216, 2, 103, 39, 13, 11, 18, 242, 216, 2, 94, 39, 13, 11, 18, 242, 216, 
+    2, 164, 39, 13, 11, 18, 242, 216, 2, 51, 39, 13, 11, 18, 242, 216, 2, 
+    253, 143, 39, 13, 11, 18, 248, 39, 2, 253, 143, 39, 13, 11, 18, 253, 157, 
+    2, 253, 143, 39, 13, 11, 18, 253, 155, 2, 253, 143, 39, 13, 11, 18, 253, 
+    169, 2, 83, 150, 30, 13, 11, 18, 253, 169, 2, 57, 30, 13, 11, 18, 253, 
+    158, 2, 83, 150, 30, 13, 11, 18, 253, 158, 2, 57, 30, 13, 11, 18, 242, 
+    240, 2, 83, 150, 30, 13, 11, 18, 242, 240, 2, 57, 30, 13, 11, 18, 248, 
+    39, 2, 83, 150, 30, 13, 11, 18, 248, 39, 2, 57, 30, 13, 11, 18, 242, 216, 
+    2, 83, 150, 30, 13, 11, 18, 242, 216, 2, 57, 30, 13, 11, 18, 94, 2, 83, 
+    150, 30, 13, 11, 18, 94, 2, 57, 30, 13, 11, 18, 103, 2, 83, 150, 30, 13, 
+    11, 18, 103, 2, 57, 30, 13, 11, 18, 164, 2, 83, 150, 30, 13, 11, 18, 164, 
+    2, 57, 30, 13, 11, 18, 253, 157, 2, 83, 150, 30, 13, 11, 18, 253, 157, 2, 
+    57, 30, 13, 11, 18, 253, 155, 2, 83, 150, 30, 13, 11, 18, 253, 155, 2, 
+    57, 30, 13, 11, 18, 242, 216, 2, 103, 30, 13, 11, 18, 242, 216, 2, 94, 
+    30, 13, 11, 18, 242, 216, 2, 164, 30, 13, 11, 18, 242, 216, 2, 51, 30, 
+    13, 11, 18, 242, 216, 2, 253, 143, 30, 13, 11, 18, 248, 39, 2, 253, 143, 
+    30, 13, 11, 18, 253, 157, 2, 253, 143, 30, 13, 11, 18, 253, 155, 2, 253, 
+    143, 30, 13, 11, 18, 242, 216, 2, 103, 54, 13, 11, 18, 242, 216, 2, 94, 
+    54, 13, 11, 18, 242, 216, 2, 164, 54, 13, 11, 18, 242, 216, 2, 51, 54, 
+    13, 11, 18, 248, 39, 2, 253, 124, 54, 13, 11, 18, 242, 216, 2, 253, 124, 
+    54, 13, 11, 18, 253, 169, 2, 51, 54, 13, 11, 18, 248, 39, 2, 103, 113, 
+    13, 11, 18, 248, 39, 2, 94, 113, 13, 11, 18, 248, 39, 2, 164, 113, 13, 
+    11, 18, 242, 216, 2, 103, 113, 13, 11, 18, 242, 216, 2, 94, 113, 13, 11, 
+    18, 242, 216, 2, 164, 113, 13, 11, 18, 253, 169, 2, 51, 113, 13, 11, 18, 
+    253, 255, 2, 51, 113, 13, 11, 18, 83, 2, 236, 214, 30, 13, 11, 18, 83, 2, 
+    236, 214, 39, 13, 240, 206, 40, 232, 74, 240, 206, 38, 232, 74, 11, 18, 
+    253, 127, 2, 103, 2, 51, 54, 13, 11, 18, 253, 127, 2, 94, 2, 103, 30, 13, 
+    11, 18, 253, 127, 2, 94, 2, 103, 54, 13, 11, 18, 253, 127, 2, 94, 2, 51, 
+    54, 13, 11, 18, 253, 127, 2, 164, 2, 51, 54, 13, 11, 18, 253, 127, 2, 51, 
+    2, 103, 54, 13, 11, 18, 253, 127, 2, 51, 2, 94, 54, 13, 11, 18, 253, 127, 
+    2, 51, 2, 164, 54, 13, 11, 18, 103, 2, 51, 2, 94, 30, 13, 11, 18, 103, 2, 
+    51, 2, 94, 54, 13, 11, 18, 94, 2, 51, 2, 57, 30, 13, 11, 18, 94, 2, 51, 
+    2, 83, 150, 30, 13, 11, 18, 248, 39, 2, 94, 2, 103, 54, 13, 11, 18, 248, 
+    39, 2, 103, 2, 94, 54, 13, 11, 18, 248, 39, 2, 103, 2, 83, 150, 30, 13, 
+    11, 18, 248, 39, 2, 51, 2, 94, 30, 13, 11, 18, 248, 39, 2, 51, 2, 94, 54, 
+    13, 11, 18, 248, 39, 2, 51, 2, 103, 54, 13, 11, 18, 248, 39, 2, 51, 2, 
+    51, 30, 13, 11, 18, 248, 39, 2, 51, 2, 51, 54, 13, 11, 18, 253, 157, 2, 
+    94, 2, 94, 30, 13, 11, 18, 253, 157, 2, 94, 2, 94, 54, 13, 11, 18, 253, 
+    157, 2, 51, 2, 51, 30, 13, 11, 18, 242, 216, 2, 94, 2, 51, 30, 13, 11, 
+    18, 242, 216, 2, 94, 2, 51, 54, 13, 11, 18, 242, 216, 2, 103, 2, 57, 30, 
+    13, 11, 18, 242, 216, 2, 51, 2, 164, 30, 13, 11, 18, 242, 216, 2, 51, 2, 
+    164, 54, 13, 11, 18, 242, 216, 2, 51, 2, 51, 30, 13, 11, 18, 242, 216, 2, 
+    51, 2, 51, 54, 13, 11, 18, 253, 155, 2, 94, 2, 83, 150, 30, 13, 11, 18, 
+    253, 155, 2, 164, 2, 51, 30, 13, 11, 18, 253, 155, 2, 164, 2, 51, 54, 13, 
+    11, 18, 253, 169, 2, 51, 2, 94, 30, 13, 11, 18, 253, 169, 2, 51, 2, 94, 
+    54, 13, 11, 18, 253, 169, 2, 51, 2, 51, 54, 13, 11, 18, 253, 169, 2, 51, 
+    2, 57, 30, 13, 11, 18, 253, 158, 2, 103, 2, 51, 30, 13, 11, 18, 253, 158, 
+    2, 51, 2, 51, 30, 13, 11, 18, 253, 158, 2, 51, 2, 51, 54, 13, 11, 18, 
+    253, 158, 2, 51, 2, 83, 150, 30, 13, 11, 18, 242, 240, 2, 51, 2, 51, 30, 
+    13, 11, 18, 242, 240, 2, 51, 2, 57, 30, 13, 11, 18, 242, 240, 2, 51, 2, 
+    83, 150, 30, 13, 11, 18, 253, 153, 2, 164, 2, 51, 30, 13, 11, 18, 253, 
+    153, 2, 164, 2, 51, 54, 13, 11, 18, 253, 167, 2, 51, 2, 94, 30, 13, 11, 
+    18, 253, 167, 2, 51, 2, 51, 30, 13, 11, 18, 182, 2, 94, 2, 51, 30, 13, 
+    11, 18, 182, 2, 94, 2, 57, 30, 13, 11, 18, 182, 2, 94, 2, 83, 150, 30, 
+    13, 11, 18, 182, 2, 103, 2, 103, 54, 13, 11, 18, 182, 2, 103, 2, 103, 30, 
+    13, 11, 18, 182, 2, 164, 2, 51, 30, 13, 11, 18, 182, 2, 164, 2, 51, 54, 
+    13, 11, 18, 182, 2, 51, 2, 94, 30, 13, 11, 18, 182, 2, 51, 2, 94, 54, 13, 
+    11, 18, 51, 2, 94, 2, 103, 54, 13, 11, 18, 51, 2, 94, 2, 51, 54, 13, 11, 
+    18, 51, 2, 94, 2, 57, 30, 13, 11, 18, 51, 2, 103, 2, 94, 54, 13, 11, 18, 
+    51, 2, 103, 2, 51, 54, 13, 11, 18, 51, 2, 164, 2, 103, 54, 13, 11, 18, 
+    51, 2, 164, 2, 51, 54, 13, 11, 18, 51, 2, 103, 2, 164, 54, 13, 11, 18, 
+    253, 124, 2, 51, 2, 103, 54, 13, 11, 18, 253, 124, 2, 51, 2, 51, 54, 13, 
+    11, 18, 198, 2, 94, 2, 51, 54, 13, 11, 18, 198, 2, 94, 2, 83, 150, 30, 
+    13, 11, 18, 198, 2, 103, 2, 51, 30, 13, 11, 18, 198, 2, 103, 2, 51, 54, 
+    13, 11, 18, 198, 2, 103, 2, 83, 150, 30, 13, 11, 18, 198, 2, 51, 2, 57, 
+    30, 13, 11, 18, 198, 2, 51, 2, 83, 150, 30, 13, 11, 18, 57, 2, 51, 2, 51, 
+    30, 13, 11, 18, 57, 2, 51, 2, 51, 54, 13, 11, 18, 253, 136, 2, 164, 2, 
+    57, 30, 13, 11, 18, 253, 127, 2, 103, 2, 57, 30, 13, 11, 18, 253, 127, 2, 
+    103, 2, 83, 150, 30, 13, 11, 18, 253, 127, 2, 164, 2, 57, 30, 13, 11, 18, 
+    253, 127, 2, 164, 2, 83, 150, 30, 13, 11, 18, 253, 127, 2, 51, 2, 57, 30, 
+    13, 11, 18, 253, 127, 2, 51, 2, 83, 150, 30, 13, 11, 18, 103, 2, 51, 2, 
+    57, 30, 13, 11, 18, 103, 2, 94, 2, 83, 150, 30, 13, 11, 18, 103, 2, 51, 
+    2, 83, 150, 30, 13, 11, 18, 248, 39, 2, 164, 2, 83, 150, 30, 13, 11, 18, 
+    253, 157, 2, 94, 2, 57, 30, 13, 11, 18, 242, 216, 2, 94, 2, 57, 30, 13, 
+    11, 18, 253, 155, 2, 94, 2, 57, 30, 13, 11, 18, 182, 2, 103, 2, 57, 30, 
+    13, 11, 18, 182, 2, 51, 2, 57, 30, 13, 11, 18, 57, 2, 94, 2, 57, 30, 13, 
+    11, 18, 57, 2, 103, 2, 57, 30, 13, 11, 18, 57, 2, 51, 2, 57, 30, 13, 11, 
+    18, 51, 2, 51, 2, 57, 30, 13, 11, 18, 253, 167, 2, 51, 2, 57, 30, 13, 11, 
+    18, 198, 2, 94, 2, 57, 30, 13, 11, 18, 253, 167, 2, 51, 2, 94, 54, 13, 
+    11, 18, 182, 2, 94, 2, 51, 54, 13, 11, 18, 253, 158, 2, 51, 2, 57, 30, 
+    13, 11, 18, 253, 135, 2, 51, 2, 57, 30, 13, 11, 18, 198, 2, 103, 2, 94, 
+    54, 13, 11, 18, 51, 2, 164, 2, 57, 30, 13, 11, 18, 182, 2, 103, 2, 51, 
+    54, 13, 11, 18, 253, 135, 2, 51, 2, 51, 30, 13, 11, 18, 182, 2, 103, 2, 
+    51, 30, 13, 11, 18, 198, 2, 103, 2, 94, 30, 13, 11, 18, 103, 2, 94, 2, 
+    57, 30, 13, 11, 18, 94, 2, 103, 2, 57, 30, 13, 11, 18, 51, 2, 103, 2, 57, 
+    30, 13, 11, 18, 253, 153, 2, 51, 2, 57, 30, 13, 11, 18, 253, 136, 2, 94, 
+    2, 57, 30, 13, 11, 18, 253, 135, 2, 51, 2, 51, 54, 13, 11, 18, 253, 158, 
+    2, 103, 2, 51, 54, 13, 11, 18, 253, 157, 2, 51, 2, 51, 54, 13, 11, 18, 
+    248, 39, 2, 164, 2, 57, 30, 13, 11, 18, 198, 2, 103, 2, 57, 30, 13, 11, 
+    18, 244, 3, 249, 191, 255, 24, 238, 197, 248, 119, 21, 39, 13, 11, 18, 
+    252, 85, 249, 191, 255, 24, 238, 197, 248, 119, 21, 39, 13, 11, 18, 244, 
+    77, 39, 13, 11, 18, 244, 75, 39, 13, 11, 18, 237, 213, 39, 13, 11, 18, 
+    247, 64, 39, 13, 11, 18, 242, 77, 39, 13, 11, 18, 240, 107, 39, 13, 11, 
+    18, 238, 45, 39, 13, 11, 18, 244, 3, 39, 13, 11, 18, 233, 100, 240, 107, 
+    236, 140, 11, 18, 229, 46, 252, 136, 52, 11, 18, 235, 181, 235, 168, 234, 
+    93, 34, 233, 233, 34, 233, 234, 34, 233, 235, 34, 233, 236, 34, 233, 237, 
+    34, 233, 238, 34, 233, 239, 34, 233, 240, 34, 233, 241, 34, 232, 204, 34, 
+    232, 205, 34, 232, 206, 34, 232, 207, 34, 232, 208, 34, 232, 209, 34, 
+    232, 210, 232, 70, 248, 38, 28, 59, 240, 27, 232, 70, 248, 38, 28, 59, 
+    80, 240, 27, 232, 70, 248, 38, 28, 59, 80, 248, 37, 208, 232, 70, 248, 
+    38, 28, 59, 240, 24, 232, 70, 248, 38, 28, 59, 234, 14, 232, 70, 248, 38, 
+    28, 59, 233, 54, 69, 232, 70, 248, 38, 28, 59, 236, 156, 69, 232, 70, 
+    248, 38, 28, 59, 40, 64, 234, 11, 104, 232, 70, 248, 38, 28, 59, 38, 64, 
+    234, 11, 237, 79, 232, 70, 248, 38, 28, 59, 163, 235, 69, 50, 18, 40, 
+    243, 7, 50, 18, 38, 243, 7, 50, 45, 242, 219, 40, 243, 7, 50, 45, 242, 
+    219, 38, 243, 7, 232, 70, 248, 38, 28, 59, 171, 53, 238, 143, 232, 70, 
+    248, 38, 28, 59, 255, 28, 242, 235, 232, 70, 248, 38, 28, 59, 255, 23, 
+    242, 235, 232, 70, 248, 38, 28, 59, 170, 242, 224, 232, 70, 248, 38, 28, 
+    59, 248, 103, 170, 242, 224, 232, 70, 248, 38, 28, 59, 40, 232, 74, 232, 
+    70, 248, 38, 28, 59, 38, 232, 74, 232, 70, 248, 38, 28, 59, 40, 242, 225, 
+    104, 232, 70, 248, 38, 28, 59, 38, 242, 225, 104, 232, 70, 248, 38, 28, 
+    59, 40, 236, 171, 242, 255, 104, 232, 70, 248, 38, 28, 59, 38, 236, 171, 
+    242, 255, 104, 232, 70, 248, 38, 28, 59, 40, 86, 234, 11, 104, 232, 70, 
+    248, 38, 28, 59, 38, 86, 234, 11, 104, 232, 70, 248, 38, 28, 59, 40, 45, 
+    185, 104, 232, 70, 248, 38, 28, 59, 38, 45, 185, 104, 232, 70, 248, 38, 
+    28, 59, 40, 185, 104, 232, 70, 248, 38, 28, 59, 38, 185, 104, 232, 70, 
+    248, 38, 28, 59, 40, 240, 31, 104, 232, 70, 248, 38, 28, 59, 38, 240, 31, 
+    104, 232, 70, 248, 38, 28, 59, 40, 64, 240, 31, 104, 232, 70, 248, 38, 
+    28, 59, 38, 64, 240, 31, 104, 240, 221, 248, 40, 64, 240, 221, 248, 40, 
+    232, 70, 248, 38, 28, 59, 40, 31, 104, 232, 70, 248, 38, 28, 59, 38, 31, 
+    104, 240, 55, 235, 74, 234, 48, 235, 74, 248, 103, 235, 74, 45, 248, 103, 
+    235, 74, 240, 55, 170, 242, 224, 234, 48, 170, 242, 224, 248, 103, 170, 
+    242, 224, 3, 240, 27, 3, 80, 240, 27, 3, 248, 37, 208, 3, 234, 14, 3, 
+    240, 24, 3, 236, 156, 69, 3, 233, 54, 69, 3, 255, 28, 242, 235, 3, 40, 
+    232, 74, 3, 38, 232, 74, 3, 40, 242, 225, 104, 3, 38, 242, 225, 104, 3, 
+    40, 236, 171, 242, 255, 104, 3, 38, 236, 171, 242, 255, 104, 3, 61, 52, 
+    3, 234, 17, 3, 235, 52, 3, 248, 49, 52, 3, 231, 94, 3, 235, 44, 52, 3, 
+    232, 68, 52, 3, 240, 7, 52, 3, 238, 75, 236, 177, 3, 240, 114, 52, 3, 
+    238, 107, 52, 3, 234, 20, 254, 20, 11, 236, 214, 39, 13, 11, 239, 214, 2, 
+    236, 214, 48, 11, 237, 1, 39, 13, 11, 248, 138, 236, 26, 11, 237, 15, 39, 
+    13, 11, 243, 40, 39, 13, 11, 243, 40, 113, 13, 11, 243, 56, 39, 13, 11, 
+    243, 56, 113, 13, 11, 243, 63, 39, 13, 11, 243, 63, 113, 13, 11, 240, 47, 
+    39, 13, 11, 240, 47, 113, 13, 11, 244, 25, 39, 13, 11, 244, 25, 113, 13, 
+    11, 1, 143, 39, 13, 11, 1, 83, 2, 243, 42, 60, 39, 13, 11, 1, 83, 2, 243, 
+    42, 60, 30, 13, 11, 1, 83, 2, 143, 60, 39, 13, 11, 1, 83, 2, 143, 60, 30, 
+    13, 11, 1, 253, 220, 2, 143, 60, 39, 13, 11, 1, 253, 220, 2, 143, 60, 30, 
+    13, 11, 1, 83, 2, 143, 242, 230, 39, 13, 11, 1, 83, 2, 143, 242, 230, 30, 
+    13, 11, 1, 57, 2, 143, 60, 39, 13, 11, 1, 57, 2, 143, 60, 30, 13, 11, 1, 
+    57, 2, 143, 60, 54, 13, 11, 1, 57, 2, 143, 60, 113, 13, 11, 1, 83, 39, 
+    13, 11, 1, 83, 30, 13, 11, 1, 253, 136, 39, 13, 11, 1, 253, 136, 30, 13, 
+    11, 1, 253, 136, 54, 13, 11, 1, 253, 136, 113, 13, 11, 1, 253, 127, 238, 
+    144, 39, 13, 11, 1, 253, 127, 238, 144, 30, 13, 11, 1, 253, 127, 39, 13, 
+    11, 1, 253, 127, 30, 13, 11, 1, 253, 127, 54, 13, 11, 1, 253, 127, 113, 
+    13, 11, 1, 248, 70, 39, 13, 11, 1, 248, 70, 30, 13, 11, 1, 248, 70, 54, 
+    13, 11, 1, 248, 70, 113, 13, 11, 1, 103, 39, 13, 11, 1, 103, 30, 13, 11, 
+    1, 103, 54, 13, 11, 1, 103, 113, 13, 11, 1, 94, 39, 13, 11, 1, 94, 30, 
+    13, 11, 1, 94, 54, 13, 11, 1, 94, 113, 13, 11, 1, 164, 39, 13, 11, 1, 
+    164, 30, 13, 11, 1, 164, 54, 13, 11, 1, 164, 113, 13, 11, 1, 253, 199, 
+    39, 13, 11, 1, 253, 199, 30, 13, 11, 1, 249, 0, 39, 13, 11, 1, 249, 0, 
+    30, 13, 11, 1, 253, 143, 39, 13, 11, 1, 253, 143, 30, 13, 11, 1, 248, 
+    104, 39, 13, 11, 1, 248, 104, 30, 13, 11, 1, 248, 39, 39, 13, 11, 1, 248, 
+    39, 30, 13, 11, 1, 248, 39, 54, 13, 11, 1, 248, 39, 113, 13, 11, 1, 242, 
+    216, 39, 13, 11, 1, 242, 216, 30, 13, 11, 1, 242, 216, 54, 13, 11, 1, 
+    242, 216, 113, 13, 11, 1, 253, 157, 39, 13, 11, 1, 253, 157, 30, 13, 11, 
+    1, 253, 157, 54, 13, 11, 1, 253, 157, 113, 13, 11, 1, 253, 155, 39, 13, 
+    11, 1, 253, 155, 30, 13, 11, 1, 253, 155, 54, 13, 11, 1, 253, 155, 113, 
+    13, 11, 1, 253, 169, 39, 13, 11, 1, 253, 169, 30, 13, 11, 1, 253, 169, 
+    54, 13, 11, 1, 253, 169, 113, 13, 11, 1, 253, 255, 39, 13, 11, 1, 253, 
+    255, 30, 13, 11, 1, 253, 255, 54, 13, 11, 1, 253, 255, 113, 13, 11, 1, 
+    253, 158, 39, 13, 11, 1, 253, 158, 30, 13, 11, 1, 253, 158, 54, 13, 11, 
+    1, 253, 158, 113, 13, 11, 1, 242, 240, 39, 13, 11, 1, 242, 240, 30, 13, 
+    11, 1, 242, 240, 54, 13, 11, 1, 242, 240, 113, 13, 11, 1, 253, 153, 39, 
+    13, 11, 1, 253, 153, 30, 13, 11, 1, 253, 153, 54, 13, 11, 1, 253, 153, 
+    113, 13, 11, 1, 253, 167, 39, 13, 11, 1, 253, 167, 30, 13, 11, 1, 253, 
+    167, 54, 13, 11, 1, 253, 167, 113, 13, 11, 1, 253, 135, 39, 13, 11, 1, 
+    253, 135, 30, 13, 11, 1, 253, 135, 54, 13, 11, 1, 253, 135, 113, 13, 11, 
+    1, 182, 39, 13, 11, 1, 182, 30, 13, 11, 1, 182, 54, 13, 11, 1, 182, 113, 
+    13, 11, 1, 51, 39, 13, 11, 1, 51, 30, 13, 11, 1, 51, 54, 13, 11, 1, 51, 
+    113, 13, 11, 1, 198, 39, 13, 11, 1, 198, 30, 13, 11, 1, 198, 54, 13, 11, 
+    1, 198, 113, 13, 11, 1, 253, 124, 39, 13, 11, 1, 253, 124, 30, 13, 11, 1, 
+    253, 124, 54, 13, 11, 1, 253, 124, 113, 13, 11, 1, 253, 220, 39, 13, 11, 
+    1, 253, 220, 30, 13, 11, 1, 83, 150, 39, 13, 11, 1, 83, 150, 30, 13, 11, 
+    1, 57, 39, 13, 11, 1, 57, 30, 13, 11, 1, 57, 54, 13, 11, 1, 57, 113, 13, 
+    11, 18, 182, 2, 83, 2, 243, 42, 60, 39, 13, 11, 18, 182, 2, 83, 2, 243, 
+    42, 60, 30, 13, 11, 18, 182, 2, 83, 2, 143, 60, 39, 13, 11, 18, 182, 2, 
+    83, 2, 143, 60, 30, 13, 11, 18, 182, 2, 83, 2, 143, 242, 230, 39, 13, 11, 
+    18, 182, 2, 83, 2, 143, 242, 230, 30, 13, 11, 18, 182, 2, 83, 39, 13, 11, 
+    18, 182, 2, 83, 30, 13, 248, 145, 243, 81, 236, 233, 240, 15, 89, 233, 
+    54, 69, 89, 235, 51, 69, 89, 61, 52, 89, 240, 114, 52, 89, 238, 107, 52, 
+    89, 234, 17, 89, 233, 59, 89, 40, 232, 74, 89, 38, 232, 74, 89, 235, 52, 
+    89, 248, 49, 52, 89, 240, 27, 89, 231, 94, 89, 248, 37, 208, 89, 236, 
+    177, 89, 26, 242, 217, 89, 26, 127, 89, 26, 111, 89, 26, 166, 89, 26, 
+    177, 89, 26, 176, 89, 26, 187, 89, 26, 203, 89, 26, 195, 89, 26, 202, 89, 
+    240, 24, 89, 234, 14, 89, 235, 44, 52, 89, 240, 7, 52, 89, 232, 68, 52, 
+    89, 236, 156, 69, 89, 234, 20, 254, 20, 89, 8, 5, 1, 67, 89, 8, 5, 1, 
+    217, 89, 8, 5, 1, 255, 18, 89, 8, 5, 1, 209, 89, 8, 5, 1, 72, 89, 8, 5, 
+    1, 255, 19, 89, 8, 5, 1, 210, 89, 8, 5, 1, 192, 89, 8, 5, 1, 71, 89, 8, 
+    5, 1, 221, 89, 8, 5, 1, 255, 15, 89, 8, 5, 1, 162, 89, 8, 5, 1, 173, 89, 
+    8, 5, 1, 197, 89, 8, 5, 1, 73, 89, 8, 5, 1, 223, 89, 8, 5, 1, 255, 20, 
+    89, 8, 5, 1, 144, 89, 8, 5, 1, 193, 89, 8, 5, 1, 214, 89, 8, 5, 1, 79, 
+    89, 8, 5, 1, 179, 89, 8, 5, 1, 255, 16, 89, 8, 5, 1, 206, 89, 8, 5, 1, 
+    255, 14, 89, 8, 5, 1, 255, 17, 89, 40, 31, 104, 89, 238, 75, 236, 177, 
+    89, 38, 31, 104, 89, 190, 238, 54, 89, 170, 242, 224, 89, 242, 245, 238, 
+    54, 89, 8, 3, 1, 67, 89, 8, 3, 1, 217, 89, 8, 3, 1, 255, 18, 89, 8, 3, 1, 
+    209, 89, 8, 3, 1, 72, 89, 8, 3, 1, 255, 19, 89, 8, 3, 1, 210, 89, 8, 3, 
+    1, 192, 89, 8, 3, 1, 71, 89, 8, 3, 1, 221, 89, 8, 3, 1, 255, 15, 89, 8, 
+    3, 1, 162, 89, 8, 3, 1, 173, 89, 8, 3, 1, 197, 89, 8, 3, 1, 73, 89, 8, 3, 
+    1, 223, 89, 8, 3, 1, 255, 20, 89, 8, 3, 1, 144, 89, 8, 3, 1, 193, 89, 8, 
+    3, 1, 214, 89, 8, 3, 1, 79, 89, 8, 3, 1, 179, 89, 8, 3, 1, 255, 16, 89, 
+    8, 3, 1, 206, 89, 8, 3, 1, 255, 14, 89, 8, 3, 1, 255, 17, 89, 40, 242, 
+    225, 104, 89, 59, 242, 224, 89, 38, 242, 225, 104, 89, 169, 89, 40, 64, 
+    232, 74, 89, 38, 64, 232, 74, 74, 80, 248, 37, 208, 74, 40, 240, 31, 104, 
+    74, 38, 240, 31, 104, 74, 80, 240, 27, 74, 42, 240, 1, 248, 40, 74, 42, 
+    1, 253, 177, 74, 42, 1, 3, 67, 74, 42, 1, 3, 71, 74, 42, 1, 3, 79, 74, 
+    42, 1, 3, 72, 74, 42, 1, 3, 73, 74, 42, 1, 3, 216, 74, 42, 1, 3, 253, 
+    161, 74, 42, 1, 3, 253, 162, 74, 42, 1, 3, 253, 196, 74, 226, 254, 235, 
+    138, 243, 1, 69, 74, 42, 1, 67, 74, 42, 1, 71, 74, 42, 1, 79, 74, 42, 1, 
+    72, 74, 42, 1, 73, 74, 42, 1, 201, 74, 42, 1, 253, 215, 74, 42, 1, 253, 
+    203, 74, 42, 1, 253, 172, 74, 42, 1, 253, 190, 74, 42, 1, 253, 132, 74, 
+    42, 1, 253, 198, 74, 42, 1, 253, 211, 74, 42, 1, 253, 210, 74, 42, 1, 
+    253, 186, 74, 42, 1, 253, 126, 74, 42, 1, 253, 212, 74, 42, 1, 253, 196, 
+    74, 42, 1, 253, 195, 74, 42, 1, 87, 74, 42, 1, 253, 131, 74, 42, 1, 253, 
+    166, 74, 42, 1, 253, 150, 74, 42, 1, 253, 197, 74, 42, 1, 253, 173, 74, 
+    42, 1, 219, 74, 42, 1, 253, 214, 74, 42, 1, 253, 236, 74, 42, 1, 253, 
+    168, 74, 42, 1, 253, 184, 74, 42, 1, 222, 74, 42, 1, 253, 180, 74, 42, 1, 
+    253, 154, 74, 42, 1, 253, 206, 74, 42, 1, 253, 181, 74, 42, 1, 216, 74, 
+    42, 1, 253, 161, 74, 42, 1, 253, 162, 74, 42, 1, 253, 130, 74, 42, 1, 
+    253, 209, 74, 42, 1, 253, 185, 74, 42, 1, 253, 194, 74, 42, 1, 253, 160, 
+    74, 42, 1, 253, 138, 74, 42, 1, 197, 74, 42, 240, 59, 243, 1, 69, 74, 42, 
+    233, 75, 243, 1, 69, 74, 23, 238, 114, 74, 23, 1, 238, 99, 74, 23, 1, 
+    232, 87, 74, 23, 1, 232, 91, 74, 23, 1, 240, 80, 74, 23, 1, 232, 93, 74, 
+    23, 1, 232, 94, 74, 23, 1, 238, 102, 74, 23, 1, 232, 101, 74, 23, 1, 240, 
+    85, 74, 23, 1, 231, 98, 74, 23, 1, 232, 96, 74, 23, 1, 232, 97, 74, 23, 
+    1, 233, 74, 74, 23, 1, 231, 43, 74, 23, 1, 231, 42, 74, 23, 1, 232, 85, 
+    74, 23, 1, 240, 78, 74, 23, 1, 240, 83, 74, 23, 1, 233, 79, 74, 23, 1, 
+    233, 66, 74, 23, 1, 243, 34, 74, 23, 1, 234, 32, 74, 23, 1, 240, 75, 74, 
+    23, 1, 240, 71, 74, 23, 1, 233, 77, 74, 23, 1, 236, 195, 74, 23, 1, 236, 
+    198, 74, 23, 1, 236, 205, 74, 23, 1, 236, 201, 74, 23, 1, 240, 74, 74, 
+    23, 1, 67, 74, 23, 1, 253, 178, 74, 23, 1, 216, 74, 23, 1, 249, 18, 74, 
+    23, 1, 254, 59, 74, 23, 1, 72, 74, 23, 1, 249, 22, 74, 23, 1, 253, 254, 
+    74, 23, 1, 73, 74, 23, 1, 253, 138, 74, 23, 1, 249, 12, 74, 23, 1, 253, 
+    193, 74, 23, 1, 253, 162, 74, 23, 1, 79, 74, 23, 1, 249, 14, 74, 23, 1, 
+    253, 170, 74, 23, 1, 253, 187, 74, 23, 1, 253, 161, 74, 23, 1, 254, 61, 
+    74, 23, 1, 253, 189, 74, 23, 1, 71, 89, 249, 39, 52, 89, 243, 246, 52, 
+    89, 161, 52, 89, 196, 89, 240, 129, 125, 89, 254, 134, 52, 89, 254, 131, 
+    52, 74, 245, 91, 136, 235, 63, 74, 139, 56, 74, 226, 226, 56, 74, 77, 56, 
+    74, 235, 45, 56, 74, 86, 238, 59, 74, 64, 238, 51, 233, 71, 234, 4, 238, 
+    159, 233, 71, 234, 4, 234, 6, 233, 71, 234, 4, 233, 251, 242, 38, 233, 
+    99, 234, 49, 233, 99, 234, 49, 44, 41, 4, 249, 254, 67, 44, 41, 4, 250, 
+    23, 72, 44, 41, 4, 250, 15, 71, 44, 41, 4, 250, 43, 73, 44, 41, 4, 250, 
+    0, 79, 44, 41, 4, 249, 247, 253, 133, 44, 41, 4, 250, 30, 253, 200, 44, 
+    41, 4, 249, 253, 253, 201, 44, 41, 4, 250, 4, 253, 225, 44, 41, 4, 250, 
+    34, 253, 232, 44, 41, 4, 250, 39, 253, 146, 44, 41, 4, 250, 31, 254, 24, 
+    44, 41, 4, 250, 21, 253, 248, 44, 41, 4, 250, 45, 254, 25, 44, 41, 4, 
+    250, 57, 201, 44, 41, 4, 250, 29, 253, 172, 44, 41, 4, 250, 47, 253, 215, 
+    44, 41, 4, 250, 50, 253, 190, 44, 41, 4, 250, 60, 253, 203, 44, 41, 4, 
+    250, 59, 222, 44, 41, 4, 250, 3, 253, 206, 44, 41, 4, 250, 53, 253, 180, 
+    44, 41, 4, 250, 5, 253, 181, 44, 41, 4, 250, 10, 253, 154, 44, 41, 4, 
+    249, 252, 253, 131, 44, 41, 4, 250, 11, 253, 197, 44, 41, 4, 250, 17, 
+    253, 166, 44, 41, 4, 250, 35, 253, 173, 44, 41, 4, 250, 38, 253, 150, 44, 
+    41, 4, 249, 249, 253, 129, 44, 41, 4, 250, 52, 253, 175, 44, 41, 4, 250, 
+    24, 253, 147, 44, 41, 4, 250, 1, 253, 208, 44, 41, 4, 250, 33, 253, 239, 
+    44, 41, 4, 250, 6, 253, 217, 44, 41, 4, 250, 58, 254, 70, 44, 41, 4, 250, 
+    9, 254, 28, 44, 41, 4, 250, 19, 254, 45, 44, 41, 4, 250, 42, 253, 130, 
+    44, 41, 4, 250, 14, 253, 194, 44, 41, 4, 250, 36, 253, 209, 44, 41, 4, 
+    249, 248, 253, 160, 44, 41, 4, 250, 13, 253, 185, 44, 41, 4, 250, 18, 
+    253, 132, 44, 41, 4, 249, 255, 253, 210, 44, 41, 4, 250, 26, 253, 198, 
+    44, 41, 4, 250, 2, 253, 186, 44, 41, 4, 250, 40, 253, 211, 44, 41, 4, 
+    250, 41, 253, 126, 44, 41, 4, 249, 250, 253, 195, 44, 41, 4, 250, 22, 
+    253, 212, 44, 41, 4, 249, 251, 87, 44, 41, 4, 250, 49, 253, 196, 44, 41, 
+    4, 250, 37, 253, 138, 44, 41, 4, 250, 55, 253, 170, 44, 41, 4, 250, 25, 
+    253, 187, 44, 41, 4, 250, 27, 253, 177, 44, 41, 4, 250, 7, 253, 163, 44, 
+    41, 4, 250, 54, 253, 228, 44, 41, 4, 250, 8, 253, 222, 44, 41, 4, 250, 
+    12, 254, 137, 44, 41, 4, 250, 28, 254, 138, 44, 41, 4, 250, 61, 253, 151, 
+    44, 41, 4, 250, 51, 250, 215, 44, 41, 4, 250, 63, 250, 216, 44, 41, 4, 
+    250, 32, 248, 176, 44, 41, 4, 250, 16, 252, 77, 44, 41, 4, 250, 44, 252, 
+    76, 44, 41, 4, 250, 56, 252, 124, 44, 41, 4, 250, 20, 252, 125, 44, 41, 
+    4, 250, 48, 252, 141, 44, 41, 4, 250, 46, 252, 207, 44, 41, 4, 250, 62, 
+    249, 8, 44, 41, 4, 250, 64, 111, 44, 41, 12, 244, 88, 44, 41, 12, 244, 
+    89, 44, 41, 12, 244, 90, 44, 41, 12, 244, 91, 44, 41, 12, 244, 92, 44, 
+    41, 12, 244, 93, 44, 41, 12, 244, 94, 44, 41, 12, 244, 95, 44, 41, 12, 
+    244, 96, 44, 41, 12, 244, 97, 44, 41, 12, 244, 98, 44, 41, 12, 244, 99, 
+    44, 41, 12, 244, 100, 44, 41, 12, 244, 101, 44, 41, 78, 250, 65, 248, 
+    131, 44, 41, 78, 250, 66, 240, 253, 44, 41, 78, 250, 67, 243, 164, 44, 
+    41, 78, 250, 68, 241, 98, 44, 41, 78, 244, 102, 246, 63, 44, 41, 78, 244, 
+    103, 236, 106, 44, 41, 78, 244, 104, 249, 58, 44, 41, 78, 244, 105, 249, 
+    151, 44, 41, 78, 244, 106, 236, 102, 44, 41, 78, 244, 107, 237, 172, 44, 
+    41, 78, 244, 108, 252, 187, 44, 41, 78, 244, 109, 244, 225, 44, 41, 78, 
+    244, 110, 248, 202, 44, 41, 78, 244, 111, 244, 231, 44, 41, 78, 250, 69, 
+    240, 153, 44, 41, 78, 250, 70, 239, 4, 44, 41, 78, 250, 71, 242, 40, 44, 
+    41, 78, 250, 72, 242, 123, 44, 41, 78, 250, 73, 237, 99, 44, 41, 236, 
+    184, 250, 74, 246, 6, 44, 41, 236, 184, 250, 75, 239, 104, 44, 41, 78, 
+    250, 76, 249, 127, 44, 41, 78, 250, 77, 243, 133, 44, 41, 78, 244, 112, 
+    44, 41, 236, 184, 250, 78, 241, 13, 44, 41, 236, 184, 250, 79, 246, 64, 
+    44, 41, 78, 250, 80, 239, 14, 44, 41, 78, 250, 81, 243, 96, 44, 41, 78, 
+    244, 113, 44, 41, 78, 250, 82, 244, 53, 44, 41, 78, 244, 114, 44, 41, 78, 
+    244, 115, 44, 41, 78, 250, 83, 243, 8, 44, 41, 78, 244, 116, 44, 41, 78, 
+    244, 117, 44, 41, 78, 244, 118, 44, 41, 236, 184, 250, 84, 242, 163, 44, 
+    41, 78, 244, 120, 44, 41, 78, 244, 121, 44, 41, 78, 250, 85, 240, 132, 
+    44, 41, 78, 244, 122, 44, 41, 78, 244, 123, 44, 41, 78, 250, 86, 237, 
+    164, 44, 41, 78, 250, 87, 238, 248, 44, 41, 78, 244, 124, 44, 41, 78, 
+    244, 125, 44, 41, 78, 244, 126, 44, 41, 78, 244, 127, 44, 41, 78, 244, 
+    128, 44, 41, 78, 244, 129, 44, 41, 78, 244, 130, 44, 41, 78, 244, 131, 
+    44, 41, 78, 244, 132, 44, 41, 78, 250, 88, 241, 248, 44, 41, 78, 244, 
+    133, 44, 41, 78, 250, 89, 244, 37, 44, 41, 78, 244, 134, 44, 41, 78, 244, 
+    135, 44, 41, 78, 244, 136, 44, 41, 78, 244, 137, 44, 41, 78, 244, 138, 
+    44, 41, 78, 244, 139, 44, 41, 78, 244, 140, 44, 41, 78, 244, 141, 44, 41, 
+    78, 244, 142, 44, 41, 78, 244, 143, 44, 41, 78, 244, 144, 44, 41, 78, 
+    250, 90, 239, 90, 44, 41, 78, 250, 91, 234, 190, 44, 41, 78, 250, 92, 
+    237, 73, 44, 41, 78, 250, 93, 240, 236, 44, 41, 78, 250, 94, 56, 44, 41, 
+    78, 244, 171, 44, 41, 78, 250, 95, 242, 137, 44, 41, 78, 244, 172, 44, 
+    41, 78, 244, 173, 44, 41, 78, 250, 96, 239, 248, 236, 252, 44, 41, 78, 
+    250, 97, 236, 252, 44, 41, 78, 250, 98, 239, 22, 241, 116, 44, 41, 78, 
+    250, 99, 242, 184, 44, 41, 78, 244, 174, 44, 41, 78, 244, 175, 44, 41, 
+    236, 184, 250, 100, 241, 85, 44, 41, 78, 244, 176, 44, 41, 78, 244, 177, 
+    44, 41, 78, 244, 179, 44, 41, 78, 244, 180, 44, 41, 78, 244, 181, 44, 41, 
+    78, 250, 101, 245, 35, 44, 41, 78, 244, 182, 44, 41, 78, 244, 183, 44, 
+    41, 78, 244, 184, 44, 41, 78, 244, 185, 44, 41, 78, 244, 186, 44, 41, 78, 
+    240, 6, 244, 119, 44, 41, 78, 240, 6, 244, 145, 44, 41, 78, 240, 6, 244, 
+    146, 44, 41, 78, 240, 6, 244, 147, 44, 41, 78, 240, 6, 244, 148, 44, 41, 
+    78, 240, 6, 244, 149, 44, 41, 78, 240, 6, 244, 150, 44, 41, 78, 240, 6, 
+    244, 151, 44, 41, 78, 240, 6, 244, 152, 44, 41, 78, 240, 6, 244, 153, 44, 
+    41, 78, 240, 6, 244, 154, 44, 41, 78, 240, 6, 244, 155, 44, 41, 78, 240, 
+    6, 244, 156, 44, 41, 78, 240, 6, 244, 157, 44, 41, 78, 240, 6, 244, 158, 
+    44, 41, 78, 240, 6, 244, 159, 44, 41, 78, 240, 6, 244, 160, 44, 41, 78, 
+    240, 6, 244, 161, 44, 41, 78, 240, 6, 244, 162, 44, 41, 78, 240, 6, 244, 
+    163, 44, 41, 78, 240, 6, 244, 164, 44, 41, 78, 240, 6, 244, 165, 44, 41, 
+    78, 240, 6, 244, 166, 44, 41, 78, 240, 6, 244, 167, 44, 41, 78, 240, 6, 
+    244, 168, 44, 41, 78, 240, 6, 244, 169, 44, 41, 78, 240, 6, 244, 170, 44, 
+    41, 78, 240, 6, 244, 178, 44, 41, 78, 240, 6, 244, 187, 167, 248, 143, 
+    235, 95, 242, 224, 167, 248, 143, 235, 95, 248, 40, 167, 243, 53, 69, 
+    167, 61, 127, 167, 61, 111, 167, 61, 166, 167, 61, 177, 167, 61, 176, 
+    167, 61, 187, 167, 61, 203, 167, 61, 195, 167, 61, 202, 167, 61, 248, 53, 
+    167, 61, 238, 77, 167, 61, 238, 101, 167, 61, 240, 136, 167, 61, 240, 50, 
+    167, 61, 240, 234, 167, 61, 237, 38, 167, 61, 238, 182, 167, 61, 238, 
+    147, 167, 61, 253, 125, 236, 149, 167, 61, 171, 236, 149, 167, 61, 204, 
+    236, 149, 167, 61, 248, 58, 236, 149, 167, 61, 248, 48, 236, 149, 167, 
+    61, 254, 31, 236, 149, 167, 61, 243, 31, 236, 149, 167, 61, 242, 254, 
+    236, 149, 167, 61, 248, 173, 236, 149, 167, 61, 253, 125, 235, 49, 167, 
+    61, 171, 235, 49, 167, 61, 204, 235, 49, 167, 61, 248, 58, 235, 49, 167, 
+    61, 248, 48, 235, 49, 167, 61, 254, 31, 235, 49, 167, 61, 243, 31, 235, 
+    49, 167, 61, 242, 254, 235, 49, 167, 61, 248, 173, 235, 49, 167, 61, 253, 
+    219, 235, 49, 167, 61, 240, 48, 235, 49, 167, 61, 240, 53, 235, 49, 167, 
+    61, 243, 6, 235, 49, 167, 61, 243, 18, 235, 49, 167, 61, 247, 90, 235, 
+    49, 167, 61, 239, 190, 235, 49, 167, 61, 241, 92, 235, 49, 167, 61, 242, 
+    12, 235, 49, 167, 240, 106, 248, 196, 247, 183, 167, 240, 106, 243, 41, 
+    236, 188, 167, 240, 106, 240, 87, 236, 188, 167, 240, 106, 243, 129, 236, 
+    188, 167, 240, 106, 240, 137, 236, 188, 167, 254, 157, 238, 119, 243, 41, 
+    236, 188, 167, 241, 218, 238, 119, 243, 41, 236, 188, 167, 238, 119, 240, 
+    87, 236, 188, 167, 238, 119, 243, 129, 236, 188, 17, 180, 242, 227, 253, 
+    125, 237, 33, 17, 180, 242, 227, 253, 125, 243, 7, 17, 180, 242, 227, 
+    253, 125, 237, 141, 17, 180, 242, 227, 176, 17, 180, 242, 227, 240, 50, 
+    17, 180, 242, 227, 248, 48, 236, 149, 17, 180, 242, 227, 248, 48, 235, 
+    49, 17, 180, 242, 227, 243, 18, 235, 49, 17, 180, 242, 227, 248, 48, 236, 
+    192, 17, 180, 242, 227, 253, 219, 236, 192, 17, 180, 242, 227, 243, 18, 
+    236, 192, 17, 180, 242, 227, 253, 125, 238, 92, 236, 192, 17, 180, 242, 
+    227, 248, 48, 238, 92, 236, 192, 17, 180, 242, 227, 253, 125, 236, 193, 
+    236, 192, 17, 180, 242, 227, 248, 48, 236, 193, 236, 192, 17, 180, 242, 
+    227, 248, 48, 236, 187, 17, 180, 242, 227, 253, 219, 236, 187, 17, 180, 
+    242, 227, 243, 18, 236, 187, 17, 180, 242, 227, 253, 125, 238, 92, 236, 
+    187, 17, 180, 242, 227, 248, 48, 238, 92, 236, 187, 17, 180, 242, 227, 
+    253, 125, 236, 193, 236, 187, 17, 180, 242, 227, 253, 219, 236, 193, 236, 
+    187, 17, 180, 242, 227, 243, 18, 236, 193, 236, 187, 17, 180, 242, 227, 
+    253, 219, 243, 107, 17, 180, 239, 91, 253, 125, 236, 76, 17, 180, 236, 
+    179, 127, 17, 180, 234, 38, 127, 17, 180, 234, 37, 111, 17, 180, 236, 
+    179, 111, 17, 180, 237, 100, 171, 235, 121, 17, 180, 234, 37, 171, 235, 
+    121, 17, 180, 234, 19, 176, 17, 180, 234, 19, 248, 53, 17, 180, 234, 19, 
+    253, 219, 235, 96, 13, 17, 180, 234, 38, 248, 53, 17, 180, 236, 60, 248, 
+    53, 17, 180, 236, 179, 248, 53, 17, 180, 236, 179, 238, 101, 17, 180, 
+    234, 19, 240, 50, 17, 180, 234, 19, 243, 18, 235, 96, 13, 17, 180, 234, 
+    38, 240, 50, 17, 180, 236, 179, 240, 50, 17, 180, 236, 179, 253, 125, 
+    236, 149, 17, 180, 236, 179, 204, 236, 149, 17, 180, 234, 37, 248, 48, 
+    236, 149, 17, 180, 234, 19, 248, 48, 236, 149, 17, 180, 236, 179, 248, 
+    48, 236, 149, 17, 180, 235, 186, 248, 48, 236, 149, 17, 180, 241, 254, 
+    248, 48, 236, 149, 17, 180, 236, 179, 253, 125, 235, 49, 17, 180, 236, 
+    179, 248, 48, 235, 49, 17, 180, 239, 40, 248, 48, 243, 107, 17, 180, 238, 
+    16, 243, 18, 243, 107, 17, 253, 125, 137, 52, 17, 253, 125, 137, 21, 235, 
+    96, 13, 17, 171, 242, 149, 52, 17, 204, 236, 236, 52, 17, 249, 206, 52, 
+    17, 242, 140, 52, 17, 238, 180, 52, 17, 252, 57, 52, 17, 171, 243, 68, 
+    52, 17, 204, 243, 68, 52, 17, 248, 58, 243, 68, 52, 17, 248, 48, 243, 68, 
+    52, 17, 237, 209, 52, 17, 239, 111, 248, 196, 52, 17, 246, 52, 52, 17, 
+    242, 44, 52, 17, 242, 188, 52, 17, 241, 19, 52, 17, 241, 17, 52, 17, 241, 
+    141, 52, 17, 238, 33, 248, 196, 52, 17, 248, 145, 52, 76, 24, 1, 67, 76, 
+    24, 1, 253, 242, 76, 24, 1, 253, 172, 76, 24, 1, 253, 200, 76, 24, 1, 72, 
+    76, 24, 1, 254, 12, 76, 24, 1, 253, 228, 76, 24, 1, 253, 168, 76, 24, 1, 
+    248, 111, 76, 24, 1, 71, 76, 24, 1, 201, 76, 24, 1, 254, 3, 76, 24, 1, 
+    254, 22, 76, 24, 1, 253, 202, 76, 24, 1, 248, 93, 76, 24, 1, 73, 76, 24, 
+    1, 253, 175, 76, 24, 1, 248, 118, 76, 24, 1, 253, 203, 76, 24, 1, 254, 4, 
+    76, 24, 1, 254, 23, 76, 24, 1, 253, 195, 76, 24, 1, 79, 76, 24, 1, 250, 
+    223, 76, 24, 1, 249, 136, 76, 24, 1, 249, 94, 76, 24, 1, 254, 21, 76, 24, 
+    1, 250, 229, 76, 24, 1, 248, 88, 76, 24, 1, 253, 142, 76, 24, 1, 253, 
+    148, 76, 24, 178, 127, 76, 24, 178, 176, 76, 24, 178, 248, 53, 76, 24, 
+    178, 240, 50, 240, 8, 1, 244, 71, 240, 8, 1, 237, 70, 240, 8, 1, 245, 
+    120, 240, 8, 1, 245, 32, 240, 8, 1, 238, 240, 240, 8, 1, 236, 83, 240, 8, 
+    1, 245, 233, 240, 8, 1, 245, 139, 240, 8, 1, 239, 221, 240, 8, 1, 250, 
+    222, 240, 8, 1, 241, 206, 240, 8, 1, 241, 211, 240, 8, 1, 241, 226, 240, 
+    8, 1, 239, 142, 240, 8, 1, 251, 113, 240, 8, 1, 247, 184, 240, 8, 1, 236, 
+    68, 240, 8, 1, 238, 147, 240, 8, 1, 242, 75, 240, 8, 1, 242, 98, 240, 8, 
+    1, 242, 144, 240, 8, 1, 242, 185, 240, 8, 1, 241, 102, 240, 8, 1, 241, 
+    179, 240, 8, 1, 240, 190, 240, 8, 1, 242, 43, 240, 8, 1, 248, 173, 236, 
+    149, 236, 147, 1, 244, 78, 236, 147, 1, 242, 242, 236, 147, 1, 241, 122, 
+    236, 147, 1, 248, 61, 236, 147, 1, 240, 28, 236, 147, 1, 253, 184, 236, 
+    147, 1, 253, 177, 236, 147, 1, 242, 251, 236, 147, 1, 245, 201, 236, 147, 
+    1, 249, 176, 236, 147, 1, 248, 193, 236, 147, 1, 248, 116, 236, 147, 1, 
+    243, 33, 236, 147, 1, 240, 33, 236, 147, 1, 248, 166, 236, 147, 1, 245, 
+    64, 236, 147, 1, 248, 132, 236, 147, 1, 254, 18, 236, 147, 1, 242, 95, 
+    236, 147, 1, 248, 105, 236, 147, 1, 253, 239, 236, 147, 1, 247, 61, 236, 
+    147, 1, 247, 15, 236, 147, 1, 242, 76, 236, 147, 1, 239, 219, 236, 147, 
+    1, 240, 180, 236, 147, 1, 87, 236, 147, 1, 71, 236, 147, 1, 79, 236, 147, 
+    1, 248, 251, 236, 147, 248, 143, 236, 213, 76, 184, 21, 67, 76, 184, 21, 
+    71, 76, 184, 21, 79, 76, 184, 21, 201, 76, 184, 21, 253, 203, 76, 184, 
+    21, 253, 139, 76, 184, 21, 253, 235, 76, 184, 21, 253, 253, 76, 184, 21, 
+    253, 152, 76, 184, 21, 253, 146, 76, 184, 21, 254, 7, 76, 184, 21, 253, 
+    126, 76, 184, 21, 253, 196, 76, 184, 21, 253, 133, 76, 184, 21, 253, 201, 
+    76, 184, 21, 253, 232, 76, 184, 21, 248, 55, 76, 184, 21, 253, 129, 76, 
+    184, 21, 253, 141, 76, 184, 21, 253, 179, 76, 184, 21, 253, 131, 76, 184, 
+    21, 253, 150, 76, 184, 21, 222, 76, 184, 21, 253, 180, 76, 184, 21, 253, 
+    154, 76, 184, 21, 216, 76, 184, 21, 253, 171, 76, 184, 21, 254, 48, 76, 
+    184, 21, 253, 130, 76, 184, 21, 253, 185, 76, 184, 21, 253, 134, 76, 184, 
+    21, 253, 132, 76, 184, 21, 253, 163, 76, 184, 21, 248, 46, 76, 184, 21, 
+    248, 66, 76, 184, 21, 219, 76, 184, 21, 233, 118, 76, 184, 21, 231, 117, 
+    76, 184, 21, 231, 118, 76, 184, 21, 232, 66, 76, 184, 21, 234, 107, 76, 
+    184, 21, 232, 126, 76, 184, 21, 244, 189, 76, 184, 21, 237, 81, 76, 184, 
+    248, 143, 236, 213, 76, 184, 61, 127, 76, 184, 61, 111, 76, 184, 61, 248, 
+    53, 76, 184, 61, 238, 77, 76, 184, 61, 236, 149, 121, 5, 1, 183, 71, 121, 
+    5, 1, 183, 72, 121, 5, 1, 183, 67, 121, 5, 1, 183, 254, 0, 121, 5, 1, 
+    183, 73, 121, 5, 1, 183, 253, 156, 121, 5, 1, 242, 215, 71, 121, 5, 1, 
+    242, 215, 72, 121, 5, 1, 242, 215, 67, 121, 5, 1, 242, 215, 254, 0, 121, 
+    5, 1, 242, 215, 73, 121, 5, 1, 242, 215, 253, 156, 121, 5, 1, 254, 33, 
+    121, 5, 1, 254, 121, 121, 5, 1, 254, 14, 121, 5, 1, 248, 192, 121, 5, 1, 
+    192, 121, 5, 1, 248, 180, 121, 5, 1, 248, 197, 121, 5, 1, 248, 255, 121, 
+    5, 1, 248, 149, 121, 5, 1, 243, 54, 121, 5, 1, 248, 161, 121, 5, 1, 249, 
+    92, 121, 5, 1, 249, 67, 121, 5, 1, 254, 21, 121, 5, 1, 249, 10, 121, 5, 
+    1, 248, 109, 121, 5, 1, 243, 77, 121, 5, 1, 254, 23, 121, 5, 1, 248, 194, 
+    121, 5, 1, 248, 93, 121, 5, 1, 243, 139, 121, 5, 1, 254, 4, 121, 5, 1, 
+    254, 3, 121, 5, 1, 254, 22, 121, 5, 1, 253, 202, 121, 5, 1, 248, 108, 
+    121, 5, 1, 254, 42, 121, 5, 1, 254, 91, 121, 3, 1, 183, 71, 121, 3, 1, 
+    183, 72, 121, 3, 1, 183, 67, 121, 3, 1, 183, 254, 0, 121, 3, 1, 183, 73, 
+    121, 3, 1, 183, 253, 156, 121, 3, 1, 242, 215, 71, 121, 3, 1, 242, 215, 
+    72, 121, 3, 1, 242, 215, 67, 121, 3, 1, 242, 215, 254, 0, 121, 3, 1, 242, 
+    215, 73, 121, 3, 1, 242, 215, 253, 156, 121, 3, 1, 254, 33, 121, 3, 1, 
+    254, 121, 121, 3, 1, 254, 14, 121, 3, 1, 248, 192, 121, 3, 1, 192, 121, 
+    3, 1, 248, 180, 121, 3, 1, 248, 197, 121, 3, 1, 248, 255, 121, 3, 1, 248, 
+    149, 121, 3, 1, 243, 54, 121, 3, 1, 248, 161, 121, 3, 1, 249, 92, 121, 3, 
+    1, 249, 67, 121, 3, 1, 254, 21, 121, 3, 1, 249, 10, 121, 3, 1, 248, 109, 
+    121, 3, 1, 243, 77, 121, 3, 1, 254, 23, 121, 3, 1, 248, 194, 121, 3, 1, 
+    248, 93, 121, 3, 1, 243, 139, 121, 3, 1, 254, 4, 121, 3, 1, 254, 3, 121, 
+    3, 1, 254, 22, 121, 3, 1, 253, 202, 121, 3, 1, 248, 108, 121, 3, 1, 254, 
+    42, 121, 3, 1, 254, 91, 207, 1, 246, 240, 207, 1, 249, 184, 207, 1, 246, 
+    13, 207, 1, 249, 61, 207, 1, 242, 147, 207, 1, 253, 186, 207, 1, 247, 
+    127, 207, 1, 239, 25, 207, 1, 253, 77, 207, 1, 245, 204, 207, 1, 250, 
+    121, 207, 1, 245, 58, 207, 1, 251, 6, 207, 1, 253, 19, 207, 1, 247, 144, 
+    207, 1, 253, 110, 207, 1, 237, 23, 207, 1, 241, 189, 207, 1, 253, 35, 
+    207, 1, 241, 144, 207, 1, 246, 53, 207, 1, 246, 86, 207, 1, 254, 174, 
+    207, 1, 250, 221, 207, 1, 249, 241, 207, 1, 249, 234, 207, 1, 254, 9, 
+    207, 1, 244, 53, 207, 1, 248, 235, 207, 1, 254, 0, 207, 1, 247, 33, 207, 
+    1, 248, 132, 207, 1, 248, 207, 207, 1, 249, 235, 207, 1, 249, 84, 207, 1, 
+    253, 176, 207, 1, 252, 55, 207, 1, 246, 234, 207, 1, 249, 127, 207, 1, 
+    249, 244, 207, 1, 249, 240, 207, 1, 253, 227, 207, 1, 249, 236, 207, 1, 
+    250, 228, 207, 1, 241, 18, 207, 1, 248, 206, 207, 1, 251, 100, 207, 1, 
+    253, 78, 238, 50, 1, 243, 3, 238, 50, 1, 253, 141, 238, 50, 1, 253, 126, 
+    238, 50, 1, 253, 146, 238, 50, 1, 253, 253, 238, 50, 1, 248, 61, 238, 50, 
+    1, 245, 60, 238, 50, 1, 253, 130, 238, 50, 1, 253, 132, 238, 50, 1, 242, 
+    106, 238, 50, 1, 248, 76, 238, 50, 1, 244, 244, 238, 50, 1, 253, 139, 
+    238, 50, 1, 253, 179, 238, 50, 1, 247, 4, 238, 50, 1, 246, 3, 238, 50, 1, 
+    246, 34, 238, 50, 1, 246, 84, 238, 50, 1, 246, 197, 238, 50, 1, 248, 142, 
+    238, 50, 1, 219, 238, 50, 1, 216, 238, 50, 1, 67, 238, 50, 1, 72, 238, 
+    50, 1, 71, 238, 50, 1, 73, 238, 50, 1, 79, 238, 50, 1, 253, 140, 238, 50, 
+    1, 253, 164, 238, 50, 1, 253, 156, 238, 50, 26, 242, 217, 238, 50, 26, 
+    127, 238, 50, 26, 111, 238, 50, 26, 166, 238, 50, 26, 177, 238, 50, 26, 
+    176, 238, 50, 26, 187, 238, 50, 26, 203, 238, 50, 26, 195, 238, 50, 26, 
+    202, 172, 4, 67, 172, 4, 72, 172, 4, 71, 172, 4, 73, 172, 4, 79, 172, 4, 
+    253, 146, 172, 4, 253, 248, 172, 4, 201, 172, 4, 253, 172, 172, 4, 253, 
+    215, 172, 4, 253, 190, 172, 4, 253, 203, 172, 4, 253, 134, 172, 4, 253, 
+    250, 172, 4, 253, 251, 172, 4, 253, 216, 172, 4, 254, 8, 172, 4, 222, 
+    172, 4, 253, 206, 172, 4, 253, 180, 172, 4, 253, 181, 172, 4, 253, 154, 
+    172, 4, 253, 131, 172, 4, 253, 197, 172, 4, 253, 166, 172, 4, 253, 173, 
+    172, 4, 253, 150, 172, 4, 253, 129, 172, 4, 253, 175, 172, 4, 253, 147, 
+    172, 4, 253, 208, 172, 4, 253, 239, 172, 4, 253, 130, 172, 4, 253, 194, 
+    172, 4, 253, 209, 172, 4, 253, 160, 172, 4, 253, 185, 172, 4, 253, 132, 
+    172, 4, 253, 210, 172, 4, 253, 198, 172, 4, 253, 186, 172, 4, 253, 211, 
+    172, 4, 253, 126, 172, 4, 253, 195, 172, 4, 253, 212, 172, 4, 87, 172, 4, 
+    253, 196, 172, 4, 253, 138, 172, 4, 253, 170, 172, 4, 253, 187, 172, 4, 
+    253, 177, 172, 4, 253, 253, 172, 4, 254, 132, 172, 4, 253, 163, 172, 4, 
+    253, 222, 151, 1, 67, 151, 33, 21, 71, 151, 33, 21, 79, 151, 33, 21, 165, 
+    144, 151, 33, 21, 72, 151, 33, 21, 73, 151, 33, 240, 51, 69, 151, 21, 45, 
+    248, 51, 46, 151, 21, 235, 61, 151, 21, 236, 173, 151, 1, 201, 151, 1, 
+    248, 61, 151, 1, 253, 139, 151, 1, 248, 77, 151, 1, 253, 152, 151, 1, 
+    248, 57, 151, 1, 253, 146, 151, 1, 248, 78, 151, 1, 248, 71, 151, 1, 242, 
+    247, 151, 1, 248, 75, 151, 1, 242, 249, 151, 1, 248, 82, 151, 1, 253, 
+    126, 151, 1, 248, 55, 151, 1, 253, 133, 151, 1, 248, 76, 151, 1, 253, 
+    131, 151, 1, 253, 129, 151, 1, 248, 65, 151, 1, 253, 141, 151, 1, 248, 
+    81, 151, 1, 222, 151, 1, 216, 151, 1, 253, 130, 151, 1, 253, 134, 151, 1, 
+    253, 171, 151, 1, 248, 46, 151, 1, 248, 66, 151, 1, 253, 132, 151, 1, 
+    253, 163, 151, 1, 219, 151, 1, 249, 97, 151, 1, 242, 161, 151, 21, 253, 
+    144, 48, 151, 21, 241, 44, 151, 21, 53, 46, 151, 238, 72, 151, 26, 127, 
+    151, 26, 111, 151, 26, 166, 151, 26, 177, 151, 61, 248, 53, 151, 61, 238, 
+    77, 151, 61, 253, 125, 236, 149, 151, 61, 253, 125, 235, 49, 151, 233, 
+    51, 248, 40, 151, 233, 51, 3, 238, 51, 151, 233, 51, 238, 51, 151, 233, 
+    51, 237, 95, 125, 151, 233, 51, 236, 57, 151, 233, 51, 241, 220, 151, 
+    233, 51, 240, 111, 151, 233, 51, 45, 240, 111, 151, 233, 51, 241, 217, 
+    37, 20, 12, 240, 29, 37, 20, 12, 239, 37, 37, 20, 12, 232, 71, 37, 20, 
+    12, 243, 112, 232, 83, 37, 20, 12, 243, 112, 240, 73, 37, 20, 12, 240, 
+    152, 232, 83, 37, 20, 12, 240, 152, 240, 73, 37, 20, 12, 236, 44, 37, 20, 
+    12, 235, 30, 37, 20, 12, 232, 191, 37, 20, 12, 235, 43, 37, 20, 12, 236, 
+    142, 240, 73, 37, 20, 12, 236, 48, 37, 20, 12, 243, 142, 232, 83, 37, 20, 
+    12, 254, 92, 232, 83, 37, 20, 12, 238, 223, 37, 20, 12, 234, 213, 37, 20, 
+    12, 233, 116, 37, 20, 12, 234, 45, 240, 73, 37, 20, 12, 238, 20, 37, 20, 
+    12, 242, 150, 37, 20, 12, 240, 205, 235, 55, 37, 20, 12, 240, 98, 235, 
+    55, 37, 20, 12, 239, 168, 37, 20, 12, 235, 187, 37, 20, 12, 242, 175, 37, 
+    20, 12, 249, 85, 235, 55, 37, 20, 12, 238, 118, 235, 55, 37, 20, 12, 235, 
+    90, 235, 55, 37, 20, 12, 236, 96, 37, 20, 12, 236, 71, 37, 20, 12, 239, 
+    203, 235, 164, 37, 20, 12, 242, 45, 235, 55, 37, 20, 12, 239, 239, 235, 
+    55, 37, 20, 12, 236, 246, 235, 55, 37, 20, 12, 235, 165, 37, 20, 12, 238, 
+    195, 37, 20, 12, 242, 82, 37, 20, 12, 240, 207, 235, 55, 37, 20, 12, 238, 
+    29, 37, 20, 12, 231, 116, 37, 20, 12, 239, 188, 37, 20, 12, 238, 153, 
+    235, 55, 37, 20, 12, 238, 153, 251, 225, 238, 15, 37, 20, 12, 235, 132, 
+    235, 55, 37, 20, 12, 242, 146, 37, 20, 12, 241, 214, 37, 20, 12, 250, 
+    217, 37, 20, 12, 247, 158, 37, 20, 12, 238, 25, 37, 20, 12, 234, 215, 37, 
+    20, 12, 243, 142, 254, 92, 248, 64, 37, 20, 12, 240, 18, 235, 55, 37, 20, 
+    12, 234, 203, 37, 20, 12, 236, 242, 235, 55, 37, 20, 12, 241, 194, 236, 
+    132, 37, 20, 12, 236, 73, 37, 20, 12, 234, 241, 37, 20, 12, 236, 46, 37, 
+    20, 12, 236, 253, 235, 55, 37, 20, 12, 237, 246, 37, 20, 12, 233, 92, 
+    235, 55, 37, 20, 12, 233, 93, 235, 55, 37, 20, 12, 237, 177, 37, 20, 12, 
+    243, 231, 37, 20, 12, 237, 234, 37, 20, 12, 237, 190, 243, 84, 37, 20, 
+    12, 236, 242, 243, 84, 37, 20, 12, 232, 59, 37, 20, 12, 231, 139, 37, 20, 
+    12, 249, 85, 248, 64, 37, 20, 12, 240, 205, 248, 64, 37, 20, 12, 243, 
+    112, 248, 64, 37, 20, 12, 237, 235, 37, 20, 12, 236, 47, 37, 20, 12, 229, 
+    51, 37, 20, 12, 229, 47, 37, 20, 12, 237, 233, 248, 64, 37, 20, 12, 235, 
+    90, 253, 238, 248, 106, 37, 20, 12, 238, 118, 253, 238, 248, 106, 37, 20, 
+    12, 239, 252, 37, 20, 12, 234, 45, 248, 64, 37, 20, 12, 234, 44, 236, 
+    126, 248, 64, 37, 20, 12, 238, 49, 37, 20, 12, 229, 48, 37, 20, 12, 237, 
+    148, 37, 20, 12, 237, 86, 37, 20, 12, 241, 243, 245, 231, 37, 20, 12, 
+    240, 152, 248, 64, 37, 20, 12, 240, 207, 248, 64, 37, 20, 12, 236, 82, 
+    248, 64, 37, 20, 12, 239, 151, 37, 20, 12, 233, 114, 37, 20, 12, 237, 
+    196, 37, 20, 12, 233, 93, 248, 64, 37, 20, 12, 233, 92, 248, 64, 37, 20, 
+    12, 240, 172, 232, 190, 37, 20, 12, 237, 193, 37, 20, 12, 227, 12, 37, 
+    20, 12, 236, 242, 248, 64, 37, 20, 12, 233, 194, 37, 20, 12, 238, 153, 
+    248, 64, 37, 20, 12, 242, 138, 37, 20, 12, 236, 253, 248, 64, 37, 20, 12, 
+    236, 13, 37, 20, 12, 242, 100, 248, 64, 37, 20, 12, 247, 204, 238, 195, 
+    37, 20, 12, 227, 8, 37, 20, 12, 229, 53, 37, 20, 12, 231, 32, 37, 20, 12, 
+    226, 242, 37, 20, 12, 226, 233, 37, 20, 12, 231, 33, 37, 20, 12, 229, 54, 
+    37, 20, 12, 229, 66, 37, 20, 12, 231, 44, 37, 20, 12, 240, 172, 231, 44, 
+    37, 20, 12, 235, 132, 248, 64, 37, 20, 12, 233, 109, 250, 230, 37, 20, 
+    12, 233, 109, 250, 232, 37, 20, 12, 247, 143, 238, 161, 37, 20, 12, 252, 
+    218, 254, 65, 237, 63, 37, 20, 12, 234, 211, 37, 20, 12, 234, 186, 37, 
+    20, 12, 249, 208, 243, 20, 37, 20, 12, 249, 208, 248, 106, 37, 20, 12, 
+    238, 14, 37, 20, 12, 240, 194, 248, 106, 37, 20, 12, 245, 67, 235, 55, 
+    37, 20, 12, 238, 142, 235, 55, 37, 20, 12, 238, 142, 243, 84, 37, 20, 12, 
+    238, 142, 248, 64, 37, 20, 12, 236, 246, 248, 64, 37, 20, 12, 244, 83, 
+    37, 20, 12, 240, 73, 37, 20, 12, 239, 228, 37, 20, 12, 236, 128, 37, 20, 
+    12, 236, 229, 37, 20, 12, 240, 100, 250, 225, 236, 254, 37, 20, 12, 240, 
+    100, 254, 57, 236, 221, 37, 20, 12, 240, 100, 247, 159, 236, 221, 37, 20, 
+    12, 240, 100, 238, 24, 236, 221, 37, 20, 12, 240, 100, 239, 97, 236, 254, 
+    37, 20, 12, 240, 98, 253, 238, 248, 106, 37, 20, 12, 240, 98, 231, 92, 
+    235, 171, 37, 20, 12, 240, 98, 231, 92, 240, 168, 37, 20, 12, 235, 204, 
+    37, 20, 12, 236, 223, 231, 92, 236, 247, 243, 20, 37, 20, 12, 236, 223, 
+    231, 92, 236, 247, 248, 106, 37, 20, 12, 236, 223, 231, 92, 240, 168, 37, 
+    20, 12, 235, 37, 37, 20, 12, 241, 14, 37, 20, 12, 233, 209, 37, 20, 12, 
+    237, 106, 37, 20, 12, 243, 13, 249, 139, 243, 143, 37, 20, 12, 243, 13, 
+    235, 170, 37, 20, 12, 243, 13, 243, 143, 37, 20, 12, 243, 13, 239, 135, 
+    37, 20, 12, 243, 13, 246, 66, 37, 20, 12, 243, 13, 240, 184, 37, 20, 12, 
+    243, 13, 234, 196, 37, 20, 12, 243, 13, 249, 139, 240, 184, 37, 20, 12, 
+    236, 162, 240, 211, 240, 35, 37, 20, 12, 236, 162, 249, 27, 240, 211, 
+    240, 35, 37, 20, 12, 236, 162, 237, 5, 240, 35, 37, 20, 12, 236, 162, 
+    249, 27, 237, 5, 240, 35, 37, 20, 12, 236, 162, 242, 157, 240, 35, 37, 
+    20, 12, 236, 162, 235, 36, 37, 20, 12, 236, 162, 236, 241, 240, 35, 37, 
+    20, 12, 236, 162, 236, 241, 238, 198, 240, 35, 37, 20, 12, 236, 162, 238, 
+    198, 240, 35, 37, 20, 12, 236, 162, 238, 209, 240, 35, 37, 20, 12, 241, 
+    181, 240, 243, 234, 58, 37, 20, 12, 234, 44, 240, 243, 234, 58, 37, 20, 
+    12, 235, 99, 233, 40, 37, 20, 12, 235, 99, 233, 87, 37, 20, 12, 235, 99, 
+    235, 119, 37, 20, 12, 236, 162, 247, 185, 240, 35, 37, 20, 12, 236, 162, 
+    234, 240, 240, 35, 37, 20, 12, 236, 162, 238, 209, 236, 241, 240, 35, 37, 
+    20, 12, 234, 57, 255, 98, 238, 161, 37, 20, 12, 234, 57, 255, 98, 237, 
+    110, 37, 20, 12, 239, 56, 254, 65, 240, 18, 249, 196, 37, 20, 12, 236, 
+    38, 37, 20, 12, 233, 210, 37, 20, 12, 240, 18, 237, 66, 237, 103, 241, 
+    178, 37, 20, 12, 240, 18, 235, 72, 253, 129, 37, 20, 12, 240, 18, 235, 
+    72, 243, 231, 37, 20, 12, 240, 18, 251, 254, 240, 35, 37, 20, 12, 240, 
+    18, 235, 72, 253, 201, 37, 20, 12, 240, 18, 238, 150, 237, 107, 253, 201, 
+    37, 20, 12, 240, 18, 235, 72, 253, 172, 37, 20, 12, 240, 18, 235, 72, 
+    253, 222, 37, 20, 12, 240, 18, 235, 72, 255, 62, 243, 20, 37, 20, 12, 
+    240, 18, 235, 72, 255, 62, 248, 106, 37, 20, 12, 240, 18, 238, 199, 240, 
+    110, 235, 119, 37, 20, 12, 240, 18, 238, 199, 240, 110, 233, 87, 37, 20, 
+    12, 241, 105, 238, 150, 240, 110, 242, 174, 37, 20, 12, 240, 18, 238, 
+    150, 240, 110, 239, 212, 37, 20, 12, 240, 18, 239, 143, 37, 20, 12, 243, 
+    89, 242, 209, 37, 20, 12, 243, 89, 239, 109, 37, 20, 12, 243, 89, 239, 
+    200, 37, 20, 12, 240, 18, 220, 240, 90, 231, 55, 37, 20, 12, 240, 18, 
+    234, 184, 234, 91, 37, 20, 12, 240, 90, 232, 110, 37, 20, 12, 240, 72, 
+    232, 110, 37, 20, 12, 240, 72, 231, 55, 37, 20, 12, 240, 72, 248, 146, 
+    254, 57, 235, 68, 37, 20, 12, 240, 72, 233, 88, 238, 225, 235, 68, 37, 
+    20, 12, 240, 72, 235, 120, 255, 56, 235, 68, 37, 20, 12, 240, 72, 234, 
+    86, 249, 128, 235, 68, 37, 20, 12, 240, 90, 248, 146, 254, 57, 235, 68, 
+    37, 20, 12, 240, 90, 233, 88, 238, 225, 235, 68, 37, 20, 12, 240, 90, 
+    235, 120, 255, 56, 235, 68, 37, 20, 12, 240, 90, 234, 86, 249, 128, 235, 
+    68, 37, 20, 12, 240, 179, 239, 43, 37, 20, 12, 240, 179, 239, 250, 37, 
+    20, 12, 236, 212, 248, 146, 241, 242, 37, 20, 12, 236, 212, 248, 146, 
+    239, 133, 37, 20, 12, 236, 212, 240, 73, 37, 20, 12, 236, 212, 237, 47, 
+    37, 20, 12, 236, 186, 237, 47, 37, 20, 12, 236, 186, 238, 155, 237, 7, 
+    37, 20, 12, 236, 186, 238, 155, 235, 154, 37, 20, 12, 236, 186, 238, 155, 
+    233, 108, 37, 20, 12, 236, 186, 238, 250, 37, 20, 12, 236, 186, 240, 128, 
+    237, 7, 37, 20, 12, 236, 186, 240, 128, 235, 154, 37, 20, 12, 236, 186, 
+    240, 128, 233, 108, 37, 20, 12, 237, 108, 254, 167, 37, 20, 12, 235, 203, 
+    254, 10, 37, 20, 12, 238, 152, 37, 20, 12, 238, 90, 253, 129, 37, 20, 12, 
+    238, 90, 249, 196, 37, 20, 12, 238, 90, 253, 139, 37, 20, 12, 238, 90, 
+    253, 201, 37, 20, 12, 238, 90, 253, 172, 37, 20, 12, 238, 90, 253, 222, 
+    37, 20, 12, 238, 90, 253, 166, 37, 20, 12, 235, 90, 253, 238, 243, 225, 
+    37, 20, 12, 238, 118, 253, 238, 243, 225, 37, 20, 12, 235, 90, 253, 238, 
+    243, 20, 37, 20, 12, 238, 118, 253, 238, 243, 20, 37, 20, 12, 240, 194, 
+    243, 20, 37, 20, 12, 240, 98, 253, 238, 243, 20, 20, 12, 240, 12, 236, 
+    194, 20, 12, 45, 236, 194, 20, 12, 30, 236, 194, 20, 12, 238, 75, 30, 
+    236, 194, 20, 12, 240, 55, 236, 194, 20, 12, 242, 215, 236, 194, 20, 12, 
+    40, 240, 64, 52, 20, 12, 38, 240, 64, 52, 20, 12, 240, 64, 243, 5, 20, 
+    12, 253, 199, 240, 219, 20, 12, 255, 70, 244, 242, 20, 12, 240, 219, 20, 
+    12, 245, 25, 20, 12, 236, 237, 236, 21, 20, 12, 236, 237, 236, 22, 20, 
+    12, 236, 237, 236, 23, 20, 12, 237, 10, 20, 12, 239, 69, 46, 20, 12, 241, 
+    37, 69, 20, 12, 237, 82, 20, 12, 241, 35, 20, 12, 104, 20, 12, 237, 225, 
+    240, 89, 20, 12, 238, 35, 240, 89, 20, 12, 235, 34, 240, 89, 20, 12, 236, 
+    25, 240, 89, 20, 12, 236, 24, 240, 89, 20, 12, 238, 8, 240, 89, 20, 12, 
+    235, 2, 234, 55, 20, 12, 233, 204, 234, 55, 20, 12, 255, 104, 243, 37, 
+    20, 12, 255, 104, 248, 148, 240, 82, 243, 51, 20, 12, 255, 104, 248, 148, 
+    240, 82, 240, 108, 20, 12, 255, 105, 243, 37, 20, 12, 255, 112, 243, 37, 
+    20, 12, 255, 112, 248, 148, 240, 82, 243, 51, 20, 12, 255, 112, 248, 148, 
+    240, 82, 240, 108, 20, 12, 249, 57, 239, 26, 20, 12, 249, 57, 239, 27, 
+    20, 12, 45, 240, 223, 20, 12, 45, 243, 174, 20, 12, 248, 209, 253, 176, 
+    20, 12, 248, 209, 242, 236, 20, 12, 238, 146, 253, 176, 20, 12, 238, 146, 
+    242, 236, 20, 12, 243, 74, 253, 176, 20, 12, 243, 74, 242, 236, 20, 12, 
+    238, 80, 188, 240, 223, 20, 12, 238, 80, 188, 243, 174, 20, 12, 241, 66, 
+    244, 31, 20, 12, 254, 153, 244, 31, 20, 12, 240, 82, 243, 51, 20, 12, 
+    240, 82, 240, 108, 20, 12, 232, 107, 243, 51, 20, 12, 232, 107, 240, 108, 
+    20, 12, 246, 95, 242, 239, 20, 12, 244, 51, 242, 239, 20, 12, 137, 242, 
+    239, 20, 12, 238, 80, 242, 239, 20, 12, 240, 62, 242, 239, 20, 12, 235, 
+    108, 242, 239, 20, 12, 231, 112, 242, 239, 20, 12, 232, 109, 242, 239, 
+    20, 12, 253, 125, 238, 92, 231, 113, 242, 239, 20, 12, 255, 113, 235, 78, 
+    20, 12, 248, 49, 235, 78, 20, 12, 218, 255, 113, 235, 78, 20, 12, 31, 
+    236, 153, 240, 39, 20, 12, 31, 236, 153, 240, 0, 20, 12, 236, 152, 236, 
+    153, 88, 240, 39, 20, 12, 236, 152, 236, 153, 88, 240, 0, 20, 12, 236, 
+    152, 236, 153, 40, 240, 39, 20, 12, 236, 152, 236, 153, 40, 240, 0, 20, 
+    12, 236, 152, 236, 153, 38, 240, 39, 20, 12, 236, 152, 236, 153, 38, 240, 
+    0, 20, 12, 236, 152, 236, 153, 92, 240, 39, 20, 12, 236, 152, 236, 153, 
+    92, 240, 0, 20, 12, 236, 152, 236, 153, 88, 38, 240, 39, 20, 12, 236, 
+    152, 236, 153, 88, 38, 240, 0, 20, 12, 249, 113, 236, 153, 240, 39, 20, 
+    12, 249, 113, 236, 153, 240, 0, 20, 12, 231, 57, 236, 153, 92, 240, 39, 
+    20, 12, 231, 57, 236, 153, 92, 240, 0, 20, 12, 233, 56, 235, 78, 20, 12, 
+    253, 16, 235, 78, 20, 12, 236, 153, 240, 0, 20, 12, 252, 40, 235, 78, 20, 
+    12, 238, 172, 236, 153, 240, 39, 20, 12, 238, 172, 236, 153, 240, 0, 20, 
+    12, 239, 255, 20, 12, 244, 51, 243, 9, 20, 12, 137, 243, 9, 20, 12, 238, 
+    80, 243, 9, 20, 12, 240, 62, 243, 9, 20, 12, 235, 108, 243, 9, 20, 12, 
+    231, 112, 243, 9, 20, 12, 232, 109, 243, 9, 20, 12, 253, 125, 238, 92, 
+    231, 113, 243, 9, 20, 12, 50, 243, 46, 20, 12, 50, 233, 38, 243, 46, 20, 
+    12, 50, 234, 83, 20, 12, 50, 234, 84, 20, 12, 50, 234, 85, 20, 12, 236, 
+    225, 234, 83, 20, 12, 236, 225, 234, 84, 20, 12, 236, 225, 234, 85, 20, 
+    12, 50, 232, 117, 248, 40, 20, 12, 50, 239, 71, 20, 12, 50, 239, 72, 20, 
+    12, 50, 239, 73, 20, 12, 50, 239, 74, 20, 12, 50, 239, 75, 20, 12, 243, 
+    24, 243, 146, 20, 12, 253, 165, 243, 146, 20, 12, 243, 24, 248, 139, 20, 
+    12, 253, 165, 248, 139, 20, 12, 243, 24, 244, 19, 20, 12, 253, 165, 244, 
+    19, 20, 12, 243, 24, 238, 207, 20, 12, 253, 165, 238, 207, 20, 12, 50, 
+    238, 54, 20, 12, 50, 236, 105, 20, 12, 50, 239, 216, 20, 12, 50, 231, 81, 
+    20, 12, 50, 237, 201, 20, 12, 50, 227, 2, 20, 12, 50, 227, 11, 20, 12, 
+    50, 241, 221, 20, 12, 234, 46, 253, 176, 20, 12, 234, 46, 242, 236, 20, 
+    12, 50, 245, 71, 20, 12, 50, 252, 138, 20, 12, 50, 245, 90, 20, 12, 50, 
+    242, 117, 20, 12, 50, 244, 217, 20, 12, 50, 45, 238, 156, 20, 12, 50, 
+    240, 3, 238, 156, 20, 12, 232, 201, 20, 12, 239, 208, 20, 12, 255, 17, 
+    20, 12, 242, 61, 20, 12, 241, 237, 20, 12, 241, 115, 20, 12, 234, 106, 
+    20, 12, 232, 127, 20, 12, 243, 186, 249, 122, 240, 37, 20, 12, 243, 186, 
+    249, 122, 255, 51, 240, 37, 20, 12, 254, 250, 20, 12, 244, 41, 20, 12, 
+    236, 145, 244, 41, 20, 12, 249, 188, 240, 37, 20, 12, 249, 188, 253, 176, 
+    20, 12, 236, 172, 236, 111, 20, 12, 236, 172, 236, 112, 20, 12, 236, 172, 
+    236, 113, 20, 12, 236, 172, 236, 114, 20, 12, 236, 172, 236, 115, 20, 12, 
+    236, 172, 236, 116, 20, 12, 236, 172, 236, 117, 20, 12, 236, 172, 236, 
+    118, 20, 12, 236, 172, 236, 119, 20, 12, 236, 172, 235, 3, 20, 12, 236, 
+    172, 235, 4, 20, 12, 232, 168, 20, 12, 232, 186, 20, 12, 253, 165, 147, 
+    239, 204, 20, 12, 240, 112, 240, 37, 20, 12, 50, 92, 248, 198, 20, 12, 
+    50, 88, 248, 198, 20, 12, 50, 236, 34, 20, 12, 50, 252, 182, 234, 235, 
+    20, 12, 243, 114, 69, 20, 12, 243, 114, 88, 69, 20, 12, 137, 243, 114, 
+    69, 20, 12, 235, 125, 253, 176, 20, 12, 235, 125, 242, 236, 20, 12, 2, 
+    232, 165, 20, 12, 245, 34, 20, 12, 250, 181, 249, 26, 20, 12, 239, 131, 
+    20, 12, 241, 219, 20, 12, 239, 13, 20, 12, 234, 40, 240, 39, 20, 12, 234, 
+    40, 240, 0, 20, 12, 239, 138, 20, 12, 240, 200, 240, 0, 20, 12, 234, 41, 
+    240, 39, 20, 12, 234, 41, 240, 0, 20, 12, 249, 65, 240, 39, 20, 12, 249, 
+    65, 240, 0, 20, 12, 243, 217, 237, 29, 242, 239, 20, 12, 243, 217, 234, 
+    29, 242, 239, 20, 12, 241, 38, 242, 239, 20, 12, 234, 40, 242, 239, 20, 
+    12, 240, 200, 242, 239, 20, 12, 234, 41, 242, 239, 20, 12, 240, 65, 235, 
+    106, 253, 231, 234, 13, 235, 134, 20, 12, 240, 65, 235, 106, 253, 231, 
+    234, 13, 233, 85, 20, 12, 240, 65, 235, 106, 253, 231, 234, 13, 237, 29, 
+    231, 102, 20, 12, 240, 65, 233, 62, 253, 231, 234, 13, 235, 134, 20, 12, 
+    240, 65, 233, 62, 253, 231, 234, 13, 233, 85, 20, 12, 240, 65, 233, 62, 
+    253, 231, 234, 13, 234, 29, 231, 102, 20, 12, 240, 65, 233, 62, 253, 231, 
+    234, 13, 234, 29, 231, 126, 20, 12, 240, 65, 233, 62, 253, 231, 234, 13, 
+    234, 29, 231, 127, 20, 12, 241, 69, 20, 12, 235, 126, 255, 105, 243, 37, 
+    20, 12, 235, 126, 255, 112, 243, 37, 20, 12, 31, 217, 20, 12, 242, 178, 
+    20, 12, 237, 238, 20, 12, 239, 28, 20, 12, 234, 251, 20, 12, 235, 190, 
+    20, 12, 236, 129, 20, 12, 234, 237, 20, 12, 236, 77, 238, 185, 20, 12, 
+    236, 97, 238, 185, 20, 12, 238, 31, 234, 249, 20, 12, 254, 223, 233, 248, 
+    17, 242, 222, 126, 235, 146, 17, 242, 222, 126, 235, 147, 17, 242, 222, 
+    126, 236, 122, 17, 242, 222, 126, 235, 148, 17, 242, 222, 126, 235, 149, 
+    17, 242, 222, 126, 236, 123, 17, 242, 222, 126, 235, 150, 17, 242, 222, 
+    126, 235, 151, 17, 242, 222, 126, 236, 124, 17, 242, 222, 126, 235, 7, 
+    17, 242, 222, 126, 234, 67, 17, 242, 222, 126, 234, 68, 17, 242, 222, 
+    126, 234, 69, 17, 242, 222, 126, 234, 70, 17, 242, 222, 126, 235, 8, 17, 
+    242, 222, 126, 235, 9, 17, 242, 222, 126, 234, 71, 17, 242, 222, 126, 
+    234, 72, 17, 242, 222, 126, 234, 73, 17, 242, 222, 126, 235, 10, 17, 242, 
+    222, 126, 235, 11, 17, 242, 222, 126, 235, 12, 17, 242, 222, 126, 234, 
+    74, 17, 242, 222, 126, 234, 75, 17, 242, 222, 126, 234, 76, 17, 242, 222, 
+    126, 234, 77, 17, 242, 222, 126, 234, 78, 17, 242, 222, 126, 234, 79, 17, 
+    242, 222, 126, 234, 80, 17, 232, 69, 126, 235, 146, 17, 232, 69, 126, 
+    235, 147, 17, 232, 69, 126, 235, 148, 17, 232, 69, 126, 235, 149, 17, 
+    232, 69, 126, 235, 150, 17, 232, 69, 126, 235, 151, 17, 232, 69, 126, 
+    234, 67, 17, 232, 69, 126, 234, 68, 17, 232, 69, 126, 234, 69, 17, 232, 
+    69, 126, 234, 70, 17, 232, 69, 126, 234, 71, 17, 232, 69, 126, 234, 72, 
+    17, 232, 69, 126, 234, 73, 17, 232, 69, 126, 234, 74, 17, 232, 69, 126, 
+    234, 75, 17, 232, 69, 126, 235, 13, 17, 232, 69, 126, 235, 14, 17, 232, 
+    69, 126, 235, 15, 17, 232, 69, 126, 235, 16, 17, 232, 69, 126, 235, 17, 
+    17, 232, 69, 126, 235, 18, 17, 232, 69, 126, 235, 19, 17, 232, 69, 126, 
+    235, 20, 17, 232, 69, 126, 235, 21, 17, 232, 69, 126, 235, 22, 17, 232, 
+    69, 126, 235, 23, 17, 232, 69, 126, 235, 24, 17, 232, 69, 126, 235, 25, 
+    17, 232, 69, 126, 235, 26, 17, 232, 69, 126, 235, 27, 17, 232, 69, 126, 
+    235, 28, 17, 232, 69, 126, 235, 29, 17, 232, 69, 126, 234, 76, 17, 232, 
+    69, 126, 234, 77, 17, 232, 69, 126, 234, 78, 17, 232, 69, 126, 234, 79, 
+    17, 232, 69, 126, 234, 80, 50, 17, 20, 237, 49, 50, 17, 20, 234, 82, 50, 
+    17, 20, 234, 62, 17, 20, 239, 116, 236, 184, 28, 240, 49, 240, 56, 28, 
+    237, 174, 240, 49, 240, 56, 28, 245, 203, 240, 49, 240, 56, 28, 238, 181, 
+    238, 139, 240, 56, 28, 238, 181, 241, 169, 240, 56, 28, 240, 49, 120, 28, 
+    238, 129, 120, 28, 248, 37, 238, 51, 120, 28, 241, 244, 120, 28, 237, 72, 
+    120, 28, 238, 193, 240, 147, 120, 28, 232, 122, 120, 28, 238, 252, 120, 
+    28, 233, 73, 120, 28, 235, 182, 248, 235, 120, 28, 231, 123, 128, 233, 
+    136, 120, 28, 233, 137, 120, 28, 232, 67, 120, 28, 235, 127, 120, 28, 
+    232, 192, 120, 28, 240, 215, 120, 28, 237, 91, 120, 28, 238, 189, 244, 
+    188, 120, 28, 237, 51, 120, 28, 234, 54, 120, 28, 237, 55, 120, 28, 237, 
+    250, 120, 28, 233, 229, 120, 28, 245, 79, 120, 28, 251, 125, 120, 28, 
+    233, 127, 120, 28, 234, 185, 120, 28, 239, 54, 120, 28, 239, 21, 120, 28, 
+    231, 122, 120, 28, 16, 233, 230, 120, 28, 237, 230, 120, 28, 239, 115, 
+    120, 28, 234, 101, 120, 28, 237, 189, 120, 28, 234, 193, 120, 28, 236, 
+    109, 120, 28, 239, 169, 120, 28, 236, 28, 120, 28, 234, 248, 120, 28, 
+    254, 190, 128, 241, 246, 120, 28, 235, 141, 120, 28, 245, 125, 153, 243, 
+    224, 120, 28, 233, 196, 120, 28, 242, 135, 120, 28, 234, 197, 120, 28, 
+    232, 164, 120, 28, 237, 232, 120, 28, 239, 174, 120, 28, 239, 76, 120, 
+    28, 238, 40, 128, 238, 46, 120, 28, 234, 103, 120, 28, 237, 23, 120, 28, 
+    236, 16, 120, 28, 242, 171, 120, 28, 231, 125, 120, 28, 240, 23, 240, 
+    201, 120, 28, 232, 167, 120, 28, 235, 124, 253, 247, 120, 28, 237, 204, 
+    120, 28, 231, 115, 120, 28, 231, 65, 120, 28, 241, 88, 120, 28, 240, 252, 
+    120, 28, 238, 6, 120, 28, 241, 180, 120, 28, 234, 109, 120, 28, 234, 108, 
+    120, 28, 237, 109, 120, 28, 233, 199, 120, 28, 234, 253, 120, 28, 236, 
+    107, 120, 28, 236, 33, 120, 28, 233, 69, 120, 28, 237, 88, 120, 28, 237, 
+    154, 120, 28, 232, 114, 120, 28, 233, 125, 120, 28, 255, 34, 253, 145, 
+    242, 177, 120, 28, 231, 124, 120, 28, 234, 217, 120, 28, 234, 191, 10, 
+    16, 5, 67, 10, 16, 5, 217, 10, 16, 5, 255, 18, 10, 16, 5, 209, 10, 16, 5, 
+    72, 10, 16, 5, 255, 19, 10, 16, 5, 210, 10, 16, 5, 192, 10, 16, 5, 71, 
+    10, 16, 5, 221, 10, 16, 5, 255, 15, 10, 16, 5, 162, 10, 16, 5, 173, 10, 
+    16, 5, 197, 10, 16, 5, 73, 10, 16, 5, 223, 10, 16, 5, 255, 20, 10, 16, 5, 
+    144, 10, 16, 5, 193, 10, 16, 5, 214, 10, 16, 5, 79, 10, 16, 5, 179, 10, 
+    16, 5, 255, 16, 10, 16, 5, 206, 10, 16, 5, 255, 14, 10, 16, 5, 255, 17, 
+    10, 16, 3, 67, 10, 16, 3, 217, 10, 16, 3, 255, 18, 10, 16, 3, 209, 10, 
+    16, 3, 72, 10, 16, 3, 255, 19, 10, 16, 3, 210, 10, 16, 3, 192, 10, 16, 3, 
+    71, 10, 16, 3, 221, 10, 16, 3, 255, 15, 10, 16, 3, 162, 10, 16, 3, 173, 
+    10, 16, 3, 197, 10, 16, 3, 73, 10, 16, 3, 223, 10, 16, 3, 255, 20, 10, 
+    16, 3, 144, 10, 16, 3, 193, 10, 16, 3, 214, 10, 16, 3, 79, 10, 16, 3, 
+    179, 10, 16, 3, 255, 16, 10, 16, 3, 206, 10, 16, 3, 255, 14, 10, 16, 3, 
+    255, 17, 10, 24, 5, 67, 10, 24, 5, 217, 10, 24, 5, 255, 18, 10, 24, 5, 
+    209, 10, 24, 5, 72, 10, 24, 5, 255, 19, 10, 24, 5, 210, 10, 24, 5, 192, 
+    10, 24, 5, 71, 10, 24, 5, 221, 10, 24, 5, 255, 15, 10, 24, 5, 162, 10, 
+    24, 5, 173, 10, 24, 5, 197, 10, 24, 5, 73, 10, 24, 5, 223, 10, 24, 5, 
+    255, 20, 10, 24, 5, 144, 10, 24, 5, 193, 10, 24, 5, 214, 10, 24, 5, 79, 
+    10, 24, 5, 179, 10, 24, 5, 255, 16, 10, 24, 5, 206, 10, 24, 5, 255, 14, 
+    10, 24, 5, 255, 17, 10, 24, 3, 67, 10, 24, 3, 217, 10, 24, 3, 255, 18, 
+    10, 24, 3, 209, 10, 24, 3, 72, 10, 24, 3, 255, 19, 10, 24, 3, 210, 10, 
+    24, 3, 71, 10, 24, 3, 221, 10, 24, 3, 255, 15, 10, 24, 3, 162, 10, 24, 3, 
+    173, 10, 24, 3, 197, 10, 24, 3, 73, 10, 24, 3, 223, 10, 24, 3, 255, 20, 
+    10, 24, 3, 144, 10, 24, 3, 193, 10, 24, 3, 214, 10, 24, 3, 79, 10, 24, 3, 
+    179, 10, 24, 3, 255, 16, 10, 24, 3, 206, 10, 24, 3, 255, 14, 10, 24, 3, 
+    255, 17, 10, 16, 24, 5, 67, 10, 16, 24, 5, 217, 10, 16, 24, 5, 255, 18, 
+    10, 16, 24, 5, 209, 10, 16, 24, 5, 72, 10, 16, 24, 5, 255, 19, 10, 16, 
+    24, 5, 210, 10, 16, 24, 5, 192, 10, 16, 24, 5, 71, 10, 16, 24, 5, 221, 
+    10, 16, 24, 5, 255, 15, 10, 16, 24, 5, 162, 10, 16, 24, 5, 173, 10, 16, 
+    24, 5, 197, 10, 16, 24, 5, 73, 10, 16, 24, 5, 223, 10, 16, 24, 5, 255, 
+    20, 10, 16, 24, 5, 144, 10, 16, 24, 5, 193, 10, 16, 24, 5, 214, 10, 16, 
+    24, 5, 79, 10, 16, 24, 5, 179, 10, 16, 24, 5, 255, 16, 10, 16, 24, 5, 
+    206, 10, 16, 24, 5, 255, 14, 10, 16, 24, 5, 255, 17, 10, 16, 24, 3, 67, 
+    10, 16, 24, 3, 217, 10, 16, 24, 3, 255, 18, 10, 16, 24, 3, 209, 10, 16, 
+    24, 3, 72, 10, 16, 24, 3, 255, 19, 10, 16, 24, 3, 210, 10, 16, 24, 3, 
+    192, 10, 16, 24, 3, 71, 10, 16, 24, 3, 221, 10, 16, 24, 3, 255, 15, 10, 
+    16, 24, 3, 162, 10, 16, 24, 3, 173, 10, 16, 24, 3, 197, 10, 16, 24, 3, 
+    73, 10, 16, 24, 3, 223, 10, 16, 24, 3, 255, 20, 10, 16, 24, 3, 144, 10, 
+    16, 24, 3, 193, 10, 16, 24, 3, 214, 10, 16, 24, 3, 79, 10, 16, 24, 3, 
+    179, 10, 16, 24, 3, 255, 16, 10, 16, 24, 3, 206, 10, 16, 24, 3, 255, 14, 
+    10, 16, 24, 3, 255, 17, 10, 84, 5, 67, 10, 84, 5, 255, 18, 10, 84, 5, 
+    209, 10, 84, 5, 210, 10, 84, 5, 221, 10, 84, 5, 255, 15, 10, 84, 5, 197, 
+    10, 84, 5, 73, 10, 84, 5, 223, 10, 84, 5, 255, 20, 10, 84, 5, 193, 10, 
+    84, 5, 214, 10, 84, 5, 79, 10, 84, 5, 179, 10, 84, 5, 255, 16, 10, 84, 5, 
+    206, 10, 84, 5, 255, 14, 10, 84, 5, 255, 17, 10, 84, 3, 67, 10, 84, 3, 
+    217, 10, 84, 3, 255, 18, 10, 84, 3, 209, 10, 84, 3, 255, 19, 10, 84, 3, 
+    192, 10, 84, 3, 71, 10, 84, 3, 221, 10, 84, 3, 255, 15, 10, 84, 3, 162, 
+    10, 84, 3, 173, 10, 84, 3, 197, 10, 84, 3, 223, 10, 84, 3, 255, 20, 10, 
+    84, 3, 144, 10, 84, 3, 193, 10, 84, 3, 214, 10, 84, 3, 79, 10, 84, 3, 
+    179, 10, 84, 3, 255, 16, 10, 84, 3, 206, 10, 84, 3, 255, 14, 10, 84, 3, 
+    255, 17, 10, 16, 84, 5, 67, 10, 16, 84, 5, 217, 10, 16, 84, 5, 255, 18, 
+    10, 16, 84, 5, 209, 10, 16, 84, 5, 72, 10, 16, 84, 5, 255, 19, 10, 16, 
+    84, 5, 210, 10, 16, 84, 5, 192, 10, 16, 84, 5, 71, 10, 16, 84, 5, 221, 
+    10, 16, 84, 5, 255, 15, 10, 16, 84, 5, 162, 10, 16, 84, 5, 173, 10, 16, 
+    84, 5, 197, 10, 16, 84, 5, 73, 10, 16, 84, 5, 223, 10, 16, 84, 5, 255, 
+    20, 10, 16, 84, 5, 144, 10, 16, 84, 5, 193, 10, 16, 84, 5, 214, 10, 16, 
+    84, 5, 79, 10, 16, 84, 5, 179, 10, 16, 84, 5, 255, 16, 10, 16, 84, 5, 
+    206, 10, 16, 84, 5, 255, 14, 10, 16, 84, 5, 255, 17, 10, 16, 84, 3, 67, 
+    10, 16, 84, 3, 217, 10, 16, 84, 3, 255, 18, 10, 16, 84, 3, 209, 10, 16, 
+    84, 3, 72, 10, 16, 84, 3, 255, 19, 10, 16, 84, 3, 210, 10, 16, 84, 3, 
+    192, 10, 16, 84, 3, 71, 10, 16, 84, 3, 221, 10, 16, 84, 3, 255, 15, 10, 
+    16, 84, 3, 162, 10, 16, 84, 3, 173, 10, 16, 84, 3, 197, 10, 16, 84, 3, 
+    73, 10, 16, 84, 3, 223, 10, 16, 84, 3, 255, 20, 10, 16, 84, 3, 144, 10, 
+    16, 84, 3, 193, 10, 16, 84, 3, 214, 10, 16, 84, 3, 79, 10, 16, 84, 3, 
+    179, 10, 16, 84, 3, 255, 16, 10, 16, 84, 3, 206, 10, 16, 84, 3, 255, 14, 
+    10, 16, 84, 3, 255, 17, 10, 93, 5, 67, 10, 93, 5, 217, 10, 93, 5, 209, 
+    10, 93, 5, 72, 10, 93, 5, 255, 19, 10, 93, 5, 210, 10, 93, 5, 221, 10, 
+    93, 5, 255, 15, 10, 93, 5, 162, 10, 93, 5, 173, 10, 93, 5, 197, 10, 93, 
+    5, 73, 10, 93, 5, 223, 10, 93, 5, 255, 20, 10, 93, 5, 193, 10, 93, 5, 
+    214, 10, 93, 5, 79, 10, 93, 5, 179, 10, 93, 5, 255, 16, 10, 93, 5, 206, 
+    10, 93, 5, 255, 14, 10, 93, 3, 67, 10, 93, 3, 217, 10, 93, 3, 255, 18, 
+    10, 93, 3, 209, 10, 93, 3, 72, 10, 93, 3, 255, 19, 10, 93, 3, 210, 10, 
+    93, 3, 192, 10, 93, 3, 71, 10, 93, 3, 221, 10, 93, 3, 255, 15, 10, 93, 3, 
+    162, 10, 93, 3, 173, 10, 93, 3, 197, 10, 93, 3, 73, 10, 93, 3, 223, 10, 
+    93, 3, 255, 20, 10, 93, 3, 144, 10, 93, 3, 193, 10, 93, 3, 214, 10, 93, 
+    3, 79, 10, 93, 3, 179, 10, 93, 3, 255, 16, 10, 93, 3, 206, 10, 93, 3, 
+    255, 14, 10, 93, 3, 255, 17, 10, 138, 5, 67, 10, 138, 5, 217, 10, 138, 5, 
+    209, 10, 138, 5, 72, 10, 138, 5, 255, 19, 10, 138, 5, 210, 10, 138, 5, 
+    71, 10, 138, 5, 221, 10, 138, 5, 255, 15, 10, 138, 5, 162, 10, 138, 5, 
+    173, 10, 138, 5, 73, 10, 138, 5, 193, 10, 138, 5, 214, 10, 138, 5, 79, 
+    10, 138, 5, 179, 10, 138, 5, 255, 16, 10, 138, 5, 206, 10, 138, 5, 255, 
+    14, 10, 138, 3, 67, 10, 138, 3, 217, 10, 138, 3, 255, 18, 10, 138, 3, 
+    209, 10, 138, 3, 72, 10, 138, 3, 255, 19, 10, 138, 3, 210, 10, 138, 3, 
+    192, 10, 138, 3, 71, 10, 138, 3, 221, 10, 138, 3, 255, 15, 10, 138, 3, 
+    162, 10, 138, 3, 173, 10, 138, 3, 197, 10, 138, 3, 73, 10, 138, 3, 223, 
+    10, 138, 3, 255, 20, 10, 138, 3, 144, 10, 138, 3, 193, 10, 138, 3, 214, 
+    10, 138, 3, 79, 10, 138, 3, 179, 10, 138, 3, 255, 16, 10, 138, 3, 206, 
+    10, 138, 3, 255, 14, 10, 138, 3, 255, 17, 10, 16, 93, 5, 67, 10, 16, 93, 
+    5, 217, 10, 16, 93, 5, 255, 18, 10, 16, 93, 5, 209, 10, 16, 93, 5, 72, 
+    10, 16, 93, 5, 255, 19, 10, 16, 93, 5, 210, 10, 16, 93, 5, 192, 10, 16, 
+    93, 5, 71, 10, 16, 93, 5, 221, 10, 16, 93, 5, 255, 15, 10, 16, 93, 5, 
+    162, 10, 16, 93, 5, 173, 10, 16, 93, 5, 197, 10, 16, 93, 5, 73, 10, 16, 
+    93, 5, 223, 10, 16, 93, 5, 255, 20, 10, 16, 93, 5, 144, 10, 16, 93, 5, 
+    193, 10, 16, 93, 5, 214, 10, 16, 93, 5, 79, 10, 16, 93, 5, 179, 10, 16, 
+    93, 5, 255, 16, 10, 16, 93, 5, 206, 10, 16, 93, 5, 255, 14, 10, 16, 93, 
+    5, 255, 17, 10, 16, 93, 3, 67, 10, 16, 93, 3, 217, 10, 16, 93, 3, 255, 
+    18, 10, 16, 93, 3, 209, 10, 16, 93, 3, 72, 10, 16, 93, 3, 255, 19, 10, 
+    16, 93, 3, 210, 10, 16, 93, 3, 192, 10, 16, 93, 3, 71, 10, 16, 93, 3, 
+    221, 10, 16, 93, 3, 255, 15, 10, 16, 93, 3, 162, 10, 16, 93, 3, 173, 10, 
+    16, 93, 3, 197, 10, 16, 93, 3, 73, 10, 16, 93, 3, 223, 10, 16, 93, 3, 
+    255, 20, 10, 16, 93, 3, 144, 10, 16, 93, 3, 193, 10, 16, 93, 3, 214, 10, 
+    16, 93, 3, 79, 10, 16, 93, 3, 179, 10, 16, 93, 3, 255, 16, 10, 16, 93, 3, 
+    206, 10, 16, 93, 3, 255, 14, 10, 16, 93, 3, 255, 17, 10, 27, 5, 67, 10, 
+    27, 5, 217, 10, 27, 5, 255, 18, 10, 27, 5, 209, 10, 27, 5, 72, 10, 27, 5, 
+    255, 19, 10, 27, 5, 210, 10, 27, 5, 192, 10, 27, 5, 71, 10, 27, 5, 221, 
+    10, 27, 5, 255, 15, 10, 27, 5, 162, 10, 27, 5, 173, 10, 27, 5, 197, 10, 
+    27, 5, 73, 10, 27, 5, 223, 10, 27, 5, 255, 20, 10, 27, 5, 144, 10, 27, 5, 
+    193, 10, 27, 5, 214, 10, 27, 5, 79, 10, 27, 5, 179, 10, 27, 5, 255, 16, 
+    10, 27, 5, 206, 10, 27, 5, 255, 14, 10, 27, 5, 255, 17, 10, 27, 3, 67, 
+    10, 27, 3, 217, 10, 27, 3, 255, 18, 10, 27, 3, 209, 10, 27, 3, 72, 10, 
+    27, 3, 255, 19, 10, 27, 3, 210, 10, 27, 3, 192, 10, 27, 3, 71, 10, 27, 3, 
+    221, 10, 27, 3, 255, 15, 10, 27, 3, 162, 10, 27, 3, 173, 10, 27, 3, 197, 
+    10, 27, 3, 73, 10, 27, 3, 223, 10, 27, 3, 255, 20, 10, 27, 3, 144, 10, 
+    27, 3, 193, 10, 27, 3, 214, 10, 27, 3, 79, 10, 27, 3, 179, 10, 27, 3, 
+    255, 16, 10, 27, 3, 206, 10, 27, 3, 255, 14, 10, 27, 3, 255, 17, 10, 27, 
+    16, 5, 67, 10, 27, 16, 5, 217, 10, 27, 16, 5, 255, 18, 10, 27, 16, 5, 
+    209, 10, 27, 16, 5, 72, 10, 27, 16, 5, 255, 19, 10, 27, 16, 5, 210, 10, 
+    27, 16, 5, 192, 10, 27, 16, 5, 71, 10, 27, 16, 5, 221, 10, 27, 16, 5, 
+    255, 15, 10, 27, 16, 5, 162, 10, 27, 16, 5, 173, 10, 27, 16, 5, 197, 10, 
+    27, 16, 5, 73, 10, 27, 16, 5, 223, 10, 27, 16, 5, 255, 20, 10, 27, 16, 5, 
+    144, 10, 27, 16, 5, 193, 10, 27, 16, 5, 214, 10, 27, 16, 5, 79, 10, 27, 
+    16, 5, 179, 10, 27, 16, 5, 255, 16, 10, 27, 16, 5, 206, 10, 27, 16, 5, 
+    255, 14, 10, 27, 16, 5, 255, 17, 10, 27, 16, 3, 67, 10, 27, 16, 3, 217, 
+    10, 27, 16, 3, 255, 18, 10, 27, 16, 3, 209, 10, 27, 16, 3, 72, 10, 27, 
+    16, 3, 255, 19, 10, 27, 16, 3, 210, 10, 27, 16, 3, 192, 10, 27, 16, 3, 
+    71, 10, 27, 16, 3, 221, 10, 27, 16, 3, 255, 15, 10, 27, 16, 3, 162, 10, 
+    27, 16, 3, 173, 10, 27, 16, 3, 197, 10, 27, 16, 3, 73, 10, 27, 16, 3, 
+    223, 10, 27, 16, 3, 255, 20, 10, 27, 16, 3, 144, 10, 27, 16, 3, 193, 10, 
+    27, 16, 3, 214, 10, 27, 16, 3, 79, 10, 27, 16, 3, 179, 10, 27, 16, 3, 
+    255, 16, 10, 27, 16, 3, 206, 10, 27, 16, 3, 255, 14, 10, 27, 16, 3, 255, 
+    17, 10, 27, 24, 5, 67, 10, 27, 24, 5, 217, 10, 27, 24, 5, 255, 18, 10, 
+    27, 24, 5, 209, 10, 27, 24, 5, 72, 10, 27, 24, 5, 255, 19, 10, 27, 24, 5, 
+    210, 10, 27, 24, 5, 192, 10, 27, 24, 5, 71, 10, 27, 24, 5, 221, 10, 27, 
+    24, 5, 255, 15, 10, 27, 24, 5, 162, 10, 27, 24, 5, 173, 10, 27, 24, 5, 
+    197, 10, 27, 24, 5, 73, 10, 27, 24, 5, 223, 10, 27, 24, 5, 255, 20, 10, 
+    27, 24, 5, 144, 10, 27, 24, 5, 193, 10, 27, 24, 5, 214, 10, 27, 24, 5, 
+    79, 10, 27, 24, 5, 179, 10, 27, 24, 5, 255, 16, 10, 27, 24, 5, 206, 10, 
+    27, 24, 5, 255, 14, 10, 27, 24, 5, 255, 17, 10, 27, 24, 3, 67, 10, 27, 
+    24, 3, 217, 10, 27, 24, 3, 255, 18, 10, 27, 24, 3, 209, 10, 27, 24, 3, 
+    72, 10, 27, 24, 3, 255, 19, 10, 27, 24, 3, 210, 10, 27, 24, 3, 192, 10, 
+    27, 24, 3, 71, 10, 27, 24, 3, 221, 10, 27, 24, 3, 255, 15, 10, 27, 24, 3, 
+    162, 10, 27, 24, 3, 173, 10, 27, 24, 3, 197, 10, 27, 24, 3, 73, 10, 27, 
+    24, 3, 223, 10, 27, 24, 3, 255, 20, 10, 27, 24, 3, 144, 10, 27, 24, 3, 
+    193, 10, 27, 24, 3, 214, 10, 27, 24, 3, 79, 10, 27, 24, 3, 179, 10, 27, 
+    24, 3, 255, 16, 10, 27, 24, 3, 206, 10, 27, 24, 3, 255, 14, 10, 27, 24, 
+    3, 255, 17, 10, 27, 16, 24, 5, 67, 10, 27, 16, 24, 5, 217, 10, 27, 16, 
+    24, 5, 255, 18, 10, 27, 16, 24, 5, 209, 10, 27, 16, 24, 5, 72, 10, 27, 
+    16, 24, 5, 255, 19, 10, 27, 16, 24, 5, 210, 10, 27, 16, 24, 5, 192, 10, 
+    27, 16, 24, 5, 71, 10, 27, 16, 24, 5, 221, 10, 27, 16, 24, 5, 255, 15, 
+    10, 27, 16, 24, 5, 162, 10, 27, 16, 24, 5, 173, 10, 27, 16, 24, 5, 197, 
+    10, 27, 16, 24, 5, 73, 10, 27, 16, 24, 5, 223, 10, 27, 16, 24, 5, 255, 
+    20, 10, 27, 16, 24, 5, 144, 10, 27, 16, 24, 5, 193, 10, 27, 16, 24, 5, 
+    214, 10, 27, 16, 24, 5, 79, 10, 27, 16, 24, 5, 179, 10, 27, 16, 24, 5, 
+    255, 16, 10, 27, 16, 24, 5, 206, 10, 27, 16, 24, 5, 255, 14, 10, 27, 16, 
+    24, 5, 255, 17, 10, 27, 16, 24, 3, 67, 10, 27, 16, 24, 3, 217, 10, 27, 
+    16, 24, 3, 255, 18, 10, 27, 16, 24, 3, 209, 10, 27, 16, 24, 3, 72, 10, 
+    27, 16, 24, 3, 255, 19, 10, 27, 16, 24, 3, 210, 10, 27, 16, 24, 3, 192, 
+    10, 27, 16, 24, 3, 71, 10, 27, 16, 24, 3, 221, 10, 27, 16, 24, 3, 255, 
+    15, 10, 27, 16, 24, 3, 162, 10, 27, 16, 24, 3, 173, 10, 27, 16, 24, 3, 
+    197, 10, 27, 16, 24, 3, 73, 10, 27, 16, 24, 3, 223, 10, 27, 16, 24, 3, 
+    255, 20, 10, 27, 16, 24, 3, 144, 10, 27, 16, 24, 3, 193, 10, 27, 16, 24, 
+    3, 214, 10, 27, 16, 24, 3, 79, 10, 27, 16, 24, 3, 179, 10, 27, 16, 24, 3, 
+    255, 16, 10, 27, 16, 24, 3, 206, 10, 27, 16, 24, 3, 255, 14, 10, 27, 16, 
+    24, 3, 255, 17, 10, 160, 5, 67, 10, 160, 5, 217, 10, 160, 5, 255, 18, 10, 
+    160, 5, 209, 10, 160, 5, 72, 10, 160, 5, 255, 19, 10, 160, 5, 210, 10, 
+    160, 5, 192, 10, 160, 5, 71, 10, 160, 5, 221, 10, 160, 5, 255, 15, 10, 
+    160, 5, 162, 10, 160, 5, 173, 10, 160, 5, 197, 10, 160, 5, 73, 10, 160, 
+    5, 223, 10, 160, 5, 255, 20, 10, 160, 5, 144, 10, 160, 5, 193, 10, 160, 
+    5, 214, 10, 160, 5, 79, 10, 160, 5, 179, 10, 160, 5, 255, 16, 10, 160, 5, 
+    206, 10, 160, 5, 255, 14, 10, 160, 5, 255, 17, 10, 160, 3, 67, 10, 160, 
+    3, 217, 10, 160, 3, 255, 18, 10, 160, 3, 209, 10, 160, 3, 72, 10, 160, 3, 
+    255, 19, 10, 160, 3, 210, 10, 160, 3, 192, 10, 160, 3, 71, 10, 160, 3, 
+    221, 10, 160, 3, 255, 15, 10, 160, 3, 162, 10, 160, 3, 173, 10, 160, 3, 
+    197, 10, 160, 3, 73, 10, 160, 3, 223, 10, 160, 3, 255, 20, 10, 160, 3, 
+    144, 10, 160, 3, 193, 10, 160, 3, 214, 10, 160, 3, 79, 10, 160, 3, 179, 
+    10, 160, 3, 255, 16, 10, 160, 3, 206, 10, 160, 3, 255, 14, 10, 160, 3, 
+    255, 17, 10, 24, 3, 238, 70, 71, 10, 24, 3, 238, 70, 221, 10, 16, 5, 240, 
+    22, 10, 16, 5, 242, 242, 10, 16, 5, 240, 10, 10, 16, 5, 240, 28, 10, 16, 
+    5, 236, 165, 10, 16, 5, 242, 251, 10, 16, 5, 248, 87, 10, 16, 5, 240, 38, 
+    10, 16, 5, 242, 237, 10, 16, 5, 240, 41, 10, 16, 5, 240, 33, 10, 16, 5, 
+    253, 154, 10, 16, 5, 253, 150, 10, 16, 5, 253, 188, 10, 16, 5, 236, 169, 
+    10, 16, 5, 253, 147, 10, 16, 5, 248, 73, 10, 16, 5, 243, 0, 91, 10, 16, 
+    5, 240, 21, 10, 16, 5, 248, 85, 10, 16, 5, 236, 160, 10, 16, 5, 248, 68, 
+    10, 16, 5, 248, 67, 10, 16, 5, 248, 69, 10, 16, 5, 240, 20, 10, 16, 240, 
+    79, 10, 16, 3, 240, 22, 10, 16, 3, 242, 242, 10, 16, 3, 240, 10, 10, 16, 
+    3, 240, 28, 10, 16, 3, 236, 165, 10, 16, 3, 242, 251, 10, 16, 3, 248, 87, 
+    10, 16, 3, 240, 38, 10, 16, 3, 242, 237, 10, 16, 3, 240, 41, 10, 16, 3, 
+    240, 33, 10, 16, 3, 253, 154, 10, 16, 3, 253, 150, 10, 16, 3, 253, 188, 
+    10, 16, 3, 236, 169, 10, 16, 3, 253, 147, 10, 16, 3, 248, 73, 10, 16, 3, 
+    30, 240, 21, 10, 16, 3, 240, 21, 10, 16, 3, 248, 85, 10, 16, 3, 236, 160, 
+    10, 16, 3, 248, 68, 10, 16, 3, 248, 67, 10, 16, 3, 248, 69, 10, 16, 3, 
+    240, 20, 10, 16, 238, 100, 231, 90, 10, 16, 238, 57, 91, 10, 16, 243, 0, 
+    91, 10, 16, 243, 29, 91, 10, 16, 254, 11, 91, 10, 16, 253, 218, 91, 10, 
+    16, 255, 29, 91, 10, 24, 5, 240, 22, 10, 24, 5, 242, 242, 10, 24, 5, 240, 
+    10, 10, 24, 5, 240, 28, 10, 24, 5, 236, 165, 10, 24, 5, 242, 251, 10, 24, 
+    5, 248, 87, 10, 24, 5, 240, 38, 10, 24, 5, 242, 237, 10, 24, 5, 240, 41, 
+    10, 24, 5, 240, 33, 10, 24, 5, 253, 154, 10, 24, 5, 253, 150, 10, 24, 5, 
+    253, 188, 10, 24, 5, 236, 169, 10, 24, 5, 253, 147, 10, 24, 5, 248, 73, 
+    10, 24, 5, 243, 0, 91, 10, 24, 5, 240, 21, 10, 24, 5, 248, 85, 10, 24, 5, 
+    236, 160, 10, 24, 5, 248, 68, 10, 24, 5, 248, 67, 10, 24, 5, 248, 69, 10, 
+    24, 5, 240, 20, 10, 24, 240, 79, 10, 24, 3, 240, 22, 10, 24, 3, 242, 242, 
+    10, 24, 3, 240, 10, 10, 24, 3, 240, 28, 10, 24, 3, 236, 165, 10, 24, 3, 
+    242, 251, 10, 24, 3, 248, 87, 10, 24, 3, 240, 38, 10, 24, 3, 242, 237, 
+    10, 24, 3, 240, 41, 10, 24, 3, 240, 33, 10, 24, 3, 253, 154, 10, 24, 3, 
+    253, 150, 10, 24, 3, 253, 188, 10, 24, 3, 236, 169, 10, 24, 3, 253, 147, 
+    10, 24, 3, 248, 73, 10, 24, 3, 30, 240, 21, 10, 24, 3, 240, 21, 10, 24, 
+    3, 248, 85, 10, 24, 3, 236, 160, 10, 24, 3, 248, 68, 10, 24, 3, 248, 67, 
+    10, 24, 3, 248, 69, 10, 24, 3, 240, 20, 10, 24, 238, 100, 231, 90, 10, 
+    24, 238, 57, 91, 10, 24, 243, 0, 91, 10, 24, 243, 29, 91, 10, 24, 254, 
+    11, 91, 10, 24, 253, 218, 91, 10, 24, 255, 29, 91, 10, 16, 24, 5, 240, 
+    22, 10, 16, 24, 5, 242, 242, 10, 16, 24, 5, 240, 10, 10, 16, 24, 5, 240, 
+    28, 10, 16, 24, 5, 236, 165, 10, 16, 24, 5, 242, 251, 10, 16, 24, 5, 248, 
+    87, 10, 16, 24, 5, 240, 38, 10, 16, 24, 5, 242, 237, 10, 16, 24, 5, 240, 
+    41, 10, 16, 24, 5, 240, 33, 10, 16, 24, 5, 253, 154, 10, 16, 24, 5, 253, 
+    150, 10, 16, 24, 5, 253, 188, 10, 16, 24, 5, 236, 169, 10, 16, 24, 5, 
+    253, 147, 10, 16, 24, 5, 248, 73, 10, 16, 24, 5, 243, 0, 91, 10, 16, 24, 
+    5, 240, 21, 10, 16, 24, 5, 248, 85, 10, 16, 24, 5, 236, 160, 10, 16, 24, 
+    5, 248, 68, 10, 16, 24, 5, 248, 67, 10, 16, 24, 5, 248, 69, 10, 16, 24, 
+    5, 240, 20, 10, 16, 24, 240, 79, 10, 16, 24, 3, 240, 22, 10, 16, 24, 3, 
+    242, 242, 10, 16, 24, 3, 240, 10, 10, 16, 24, 3, 240, 28, 10, 16, 24, 3, 
+    236, 165, 10, 16, 24, 3, 242, 251, 10, 16, 24, 3, 248, 87, 10, 16, 24, 3, 
+    240, 38, 10, 16, 24, 3, 242, 237, 10, 16, 24, 3, 240, 41, 10, 16, 24, 3, 
+    240, 33, 10, 16, 24, 3, 253, 154, 10, 16, 24, 3, 253, 150, 10, 16, 24, 3, 
+    253, 188, 10, 16, 24, 3, 236, 169, 10, 16, 24, 3, 253, 147, 10, 16, 24, 
+    3, 248, 73, 10, 16, 24, 3, 30, 240, 21, 10, 16, 24, 3, 240, 21, 10, 16, 
+    24, 3, 248, 85, 10, 16, 24, 3, 236, 160, 10, 16, 24, 3, 248, 68, 10, 16, 
+    24, 3, 248, 67, 10, 16, 24, 3, 248, 69, 10, 16, 24, 3, 240, 20, 10, 16, 
+    24, 238, 100, 231, 90, 10, 16, 24, 238, 57, 91, 10, 16, 24, 243, 0, 91, 
+    10, 16, 24, 243, 29, 91, 10, 16, 24, 254, 11, 91, 10, 16, 24, 253, 218, 
+    91, 10, 16, 24, 255, 29, 91, 10, 27, 16, 5, 240, 22, 10, 27, 16, 5, 242, 
+    242, 10, 27, 16, 5, 240, 10, 10, 27, 16, 5, 240, 28, 10, 27, 16, 5, 236, 
+    165, 10, 27, 16, 5, 242, 251, 10, 27, 16, 5, 248, 87, 10, 27, 16, 5, 240, 
+    38, 10, 27, 16, 5, 242, 237, 10, 27, 16, 5, 240, 41, 10, 27, 16, 5, 240, 
+    33, 10, 27, 16, 5, 253, 154, 10, 27, 16, 5, 253, 150, 10, 27, 16, 5, 253, 
+    188, 10, 27, 16, 5, 236, 169, 10, 27, 16, 5, 253, 147, 10, 27, 16, 5, 
+    248, 73, 10, 27, 16, 5, 243, 0, 91, 10, 27, 16, 5, 240, 21, 10, 27, 16, 
+    5, 248, 85, 10, 27, 16, 5, 236, 160, 10, 27, 16, 5, 248, 68, 10, 27, 16, 
+    5, 248, 67, 10, 27, 16, 5, 248, 69, 10, 27, 16, 5, 240, 20, 10, 27, 16, 
+    240, 79, 10, 27, 16, 3, 240, 22, 10, 27, 16, 3, 242, 242, 10, 27, 16, 3, 
+    240, 10, 10, 27, 16, 3, 240, 28, 10, 27, 16, 3, 236, 165, 10, 27, 16, 3, 
+    242, 251, 10, 27, 16, 3, 248, 87, 10, 27, 16, 3, 240, 38, 10, 27, 16, 3, 
+    242, 237, 10, 27, 16, 3, 240, 41, 10, 27, 16, 3, 240, 33, 10, 27, 16, 3, 
+    253, 154, 10, 27, 16, 3, 253, 150, 10, 27, 16, 3, 253, 188, 10, 27, 16, 
+    3, 236, 169, 10, 27, 16, 3, 253, 147, 10, 27, 16, 3, 248, 73, 10, 27, 16, 
+    3, 30, 240, 21, 10, 27, 16, 3, 240, 21, 10, 27, 16, 3, 248, 85, 10, 27, 
+    16, 3, 236, 160, 10, 27, 16, 3, 248, 68, 10, 27, 16, 3, 248, 67, 10, 27, 
+    16, 3, 248, 69, 10, 27, 16, 3, 240, 20, 10, 27, 16, 238, 100, 231, 90, 
+    10, 27, 16, 238, 57, 91, 10, 27, 16, 243, 0, 91, 10, 27, 16, 243, 29, 91, 
+    10, 27, 16, 254, 11, 91, 10, 27, 16, 253, 218, 91, 10, 27, 16, 255, 29, 
+    91, 10, 27, 16, 24, 5, 240, 22, 10, 27, 16, 24, 5, 242, 242, 10, 27, 16, 
+    24, 5, 240, 10, 10, 27, 16, 24, 5, 240, 28, 10, 27, 16, 24, 5, 236, 165, 
+    10, 27, 16, 24, 5, 242, 251, 10, 27, 16, 24, 5, 248, 87, 10, 27, 16, 24, 
+    5, 240, 38, 10, 27, 16, 24, 5, 242, 237, 10, 27, 16, 24, 5, 240, 41, 10, 
+    27, 16, 24, 5, 240, 33, 10, 27, 16, 24, 5, 253, 154, 10, 27, 16, 24, 5, 
+    253, 150, 10, 27, 16, 24, 5, 253, 188, 10, 27, 16, 24, 5, 236, 169, 10, 
+    27, 16, 24, 5, 253, 147, 10, 27, 16, 24, 5, 248, 73, 10, 27, 16, 24, 5, 
+    243, 0, 91, 10, 27, 16, 24, 5, 240, 21, 10, 27, 16, 24, 5, 248, 85, 10, 
+    27, 16, 24, 5, 236, 160, 10, 27, 16, 24, 5, 248, 68, 10, 27, 16, 24, 5, 
+    248, 67, 10, 27, 16, 24, 5, 248, 69, 10, 27, 16, 24, 5, 240, 20, 10, 27, 
+    16, 24, 240, 79, 10, 27, 16, 24, 3, 240, 22, 10, 27, 16, 24, 3, 242, 242, 
+    10, 27, 16, 24, 3, 240, 10, 10, 27, 16, 24, 3, 240, 28, 10, 27, 16, 24, 
+    3, 236, 165, 10, 27, 16, 24, 3, 242, 251, 10, 27, 16, 24, 3, 248, 87, 10, 
+    27, 16, 24, 3, 240, 38, 10, 27, 16, 24, 3, 242, 237, 10, 27, 16, 24, 3, 
+    240, 41, 10, 27, 16, 24, 3, 240, 33, 10, 27, 16, 24, 3, 253, 154, 10, 27, 
+    16, 24, 3, 253, 150, 10, 27, 16, 24, 3, 253, 188, 10, 27, 16, 24, 3, 236, 
+    169, 10, 27, 16, 24, 3, 253, 147, 10, 27, 16, 24, 3, 248, 73, 10, 27, 16, 
+    24, 3, 30, 240, 21, 10, 27, 16, 24, 3, 240, 21, 10, 27, 16, 24, 3, 248, 
+    85, 10, 27, 16, 24, 3, 236, 160, 10, 27, 16, 24, 3, 248, 68, 10, 27, 16, 
+    24, 3, 248, 67, 10, 27, 16, 24, 3, 248, 69, 10, 27, 16, 24, 3, 240, 20, 
+    10, 27, 16, 24, 238, 100, 231, 90, 10, 27, 16, 24, 238, 57, 91, 10, 27, 
+    16, 24, 243, 0, 91, 10, 27, 16, 24, 243, 29, 91, 10, 27, 16, 24, 254, 11, 
+    91, 10, 27, 16, 24, 253, 218, 91, 10, 27, 16, 24, 255, 29, 91, 10, 16, 
+    26, 242, 217, 10, 16, 26, 127, 10, 16, 26, 111, 10, 16, 26, 166, 10, 16, 
+    26, 177, 10, 16, 26, 176, 10, 16, 26, 187, 10, 16, 26, 203, 10, 16, 26, 
+    195, 10, 16, 26, 202, 10, 138, 26, 242, 217, 10, 138, 26, 127, 10, 138, 
+    26, 111, 10, 138, 26, 166, 10, 138, 26, 177, 10, 138, 26, 176, 10, 138, 
+    26, 187, 10, 138, 26, 203, 10, 138, 26, 195, 10, 138, 26, 202, 10, 27, 
+    26, 242, 217, 10, 27, 26, 127, 10, 27, 26, 111, 10, 27, 26, 166, 10, 27, 
+    26, 177, 10, 27, 26, 176, 10, 27, 26, 187, 10, 27, 26, 203, 10, 27, 26, 
+    195, 10, 27, 26, 202, 10, 27, 16, 26, 242, 217, 10, 27, 16, 26, 127, 10, 
+    27, 16, 26, 111, 10, 27, 16, 26, 166, 10, 27, 16, 26, 177, 10, 27, 16, 
+    26, 176, 10, 27, 16, 26, 187, 10, 27, 16, 26, 203, 10, 27, 16, 26, 195, 
+    10, 27, 16, 26, 202, 10, 160, 26, 242, 217, 10, 160, 26, 127, 10, 160, 
+    26, 111, 10, 160, 26, 166, 10, 160, 26, 177, 10, 160, 26, 176, 10, 160, 
+    26, 187, 10, 160, 26, 203, 10, 160, 26, 195, 10, 160, 26, 202, 7, 9, 227, 
+    16, 7, 9, 227, 17, 7, 9, 227, 18, 7, 9, 227, 19, 7, 9, 227, 20, 7, 9, 
+    227, 21, 7, 9, 227, 22, 7, 9, 227, 23, 7, 9, 227, 24, 7, 9, 227, 25, 7, 
+    9, 227, 26, 7, 9, 227, 27, 7, 9, 227, 28, 7, 9, 227, 29, 7, 9, 227, 30, 
+    7, 9, 227, 31, 7, 9, 227, 32, 7, 9, 227, 33, 7, 9, 227, 34, 7, 9, 227, 
+    35, 7, 9, 227, 36, 7, 9, 227, 37, 7, 9, 227, 38, 7, 9, 227, 39, 7, 9, 
+    227, 40, 7, 9, 227, 41, 7, 9, 227, 42, 7, 9, 227, 43, 7, 9, 227, 44, 7, 
+    9, 227, 45, 7, 9, 227, 46, 7, 9, 227, 47, 7, 9, 227, 48, 7, 9, 227, 49, 
+    7, 9, 227, 50, 7, 9, 227, 51, 7, 9, 227, 52, 7, 9, 227, 53, 7, 9, 227, 
+    54, 7, 9, 227, 55, 7, 9, 227, 56, 7, 9, 227, 57, 7, 9, 227, 58, 7, 9, 
+    227, 59, 7, 9, 227, 60, 7, 9, 227, 61, 7, 9, 227, 62, 7, 9, 227, 63, 7, 
+    9, 227, 64, 7, 9, 227, 65, 7, 9, 227, 66, 7, 9, 227, 67, 7, 9, 227, 68, 
+    7, 9, 227, 69, 7, 9, 227, 70, 7, 9, 227, 71, 7, 9, 227, 72, 7, 9, 227, 
+    73, 7, 9, 227, 74, 7, 9, 227, 75, 7, 9, 227, 76, 7, 9, 227, 77, 7, 9, 
+    227, 78, 7, 9, 227, 79, 7, 9, 227, 80, 7, 9, 227, 81, 7, 9, 227, 82, 7, 
+    9, 227, 83, 7, 9, 227, 84, 7, 9, 227, 85, 7, 9, 227, 86, 7, 9, 227, 87, 
+    7, 9, 227, 88, 7, 9, 227, 89, 7, 9, 227, 90, 7, 9, 227, 91, 7, 9, 227, 
+    92, 7, 9, 227, 93, 7, 9, 227, 94, 7, 9, 227, 95, 7, 9, 227, 96, 7, 9, 
+    227, 97, 7, 9, 227, 98, 7, 9, 227, 99, 7, 9, 227, 100, 7, 9, 227, 101, 7, 
+    9, 227, 102, 7, 9, 227, 103, 7, 9, 227, 104, 7, 9, 227, 105, 7, 9, 227, 
+    106, 7, 9, 227, 107, 7, 9, 227, 108, 7, 9, 227, 109, 7, 9, 227, 110, 7, 
+    9, 227, 111, 7, 9, 227, 112, 7, 9, 227, 113, 7, 9, 227, 114, 7, 9, 227, 
+    115, 7, 9, 227, 116, 7, 9, 227, 117, 7, 9, 227, 118, 7, 9, 227, 119, 7, 
+    9, 227, 120, 7, 9, 227, 121, 7, 9, 227, 122, 7, 9, 227, 123, 7, 9, 227, 
+    124, 7, 9, 227, 125, 7, 9, 227, 126, 7, 9, 227, 127, 7, 9, 227, 128, 7, 
+    9, 227, 129, 7, 9, 227, 130, 7, 9, 227, 131, 7, 9, 227, 132, 7, 9, 227, 
+    133, 7, 9, 227, 134, 7, 9, 227, 135, 7, 9, 227, 136, 7, 9, 227, 137, 7, 
+    9, 227, 138, 7, 9, 227, 139, 7, 9, 227, 140, 7, 9, 227, 141, 7, 9, 227, 
+    142, 7, 9, 227, 143, 7, 9, 227, 144, 7, 9, 227, 145, 7, 9, 227, 146, 7, 
+    9, 227, 147, 7, 9, 227, 148, 7, 9, 227, 149, 7, 9, 227, 150, 7, 9, 227, 
+    151, 7, 9, 227, 152, 7, 9, 227, 153, 7, 9, 227, 154, 7, 9, 227, 155, 7, 
+    9, 227, 156, 7, 9, 227, 157, 7, 9, 227, 158, 7, 9, 227, 159, 7, 9, 227, 
+    160, 7, 9, 227, 161, 7, 9, 227, 162, 7, 9, 227, 163, 7, 9, 227, 164, 7, 
+    9, 227, 165, 7, 9, 227, 166, 7, 9, 227, 167, 7, 9, 227, 168, 7, 9, 227, 
+    169, 7, 9, 227, 170, 7, 9, 227, 171, 7, 9, 227, 172, 7, 9, 227, 173, 7, 
+    9, 227, 174, 7, 9, 227, 175, 7, 9, 227, 176, 7, 9, 227, 177, 7, 9, 227, 
+    178, 7, 9, 227, 179, 7, 9, 227, 180, 7, 9, 227, 181, 7, 9, 227, 182, 7, 
+    9, 227, 183, 7, 9, 227, 184, 7, 9, 227, 185, 7, 9, 227, 186, 7, 9, 227, 
+    187, 7, 9, 227, 188, 7, 9, 227, 189, 7, 9, 227, 190, 7, 9, 227, 191, 7, 
+    9, 227, 192, 7, 9, 227, 193, 7, 9, 227, 194, 7, 9, 227, 195, 7, 9, 227, 
+    196, 7, 9, 227, 197, 7, 9, 227, 198, 7, 9, 227, 199, 7, 9, 227, 200, 7, 
+    9, 227, 201, 7, 9, 227, 202, 7, 9, 227, 203, 7, 9, 227, 204, 7, 9, 227, 
+    205, 7, 9, 227, 206, 7, 9, 227, 207, 7, 9, 227, 208, 7, 9, 227, 209, 7, 
+    9, 227, 210, 7, 9, 227, 211, 7, 9, 227, 212, 7, 9, 227, 213, 7, 9, 227, 
+    214, 7, 9, 227, 215, 7, 9, 227, 216, 7, 9, 227, 217, 7, 9, 227, 218, 7, 
+    9, 227, 219, 7, 9, 227, 220, 7, 9, 227, 221, 7, 9, 227, 222, 7, 9, 227, 
+    223, 7, 9, 227, 224, 7, 9, 227, 225, 7, 9, 227, 226, 7, 9, 227, 227, 7, 
+    9, 227, 228, 7, 9, 227, 229, 7, 9, 227, 230, 7, 9, 227, 231, 7, 9, 227, 
+    232, 7, 9, 227, 233, 7, 9, 227, 234, 7, 9, 227, 235, 7, 9, 227, 236, 7, 
+    9, 227, 237, 7, 9, 227, 238, 7, 9, 227, 239, 7, 9, 227, 240, 7, 9, 227, 
+    241, 7, 9, 227, 242, 7, 9, 227, 243, 7, 9, 227, 244, 7, 9, 227, 245, 7, 
+    9, 227, 246, 7, 9, 227, 247, 7, 9, 227, 248, 7, 9, 227, 249, 7, 9, 227, 
+    250, 7, 9, 227, 251, 7, 9, 227, 252, 7, 9, 227, 253, 7, 9, 227, 254, 7, 
+    9, 227, 255, 7, 9, 228, 0, 7, 9, 228, 1, 7, 9, 228, 2, 7, 9, 228, 3, 7, 
+    9, 228, 4, 7, 9, 228, 5, 7, 9, 228, 6, 7, 9, 228, 7, 7, 9, 228, 8, 7, 9, 
+    228, 9, 7, 9, 228, 10, 7, 9, 228, 11, 7, 9, 228, 12, 7, 9, 228, 13, 7, 9, 
+    228, 14, 7, 9, 228, 15, 7, 9, 228, 16, 7, 9, 228, 17, 7, 9, 228, 18, 7, 
+    9, 228, 19, 7, 9, 228, 20, 7, 9, 228, 21, 7, 9, 228, 22, 7, 9, 228, 23, 
+    7, 9, 228, 24, 7, 9, 228, 25, 7, 9, 228, 26, 7, 9, 228, 27, 7, 9, 228, 
+    28, 7, 9, 228, 29, 7, 9, 228, 30, 7, 9, 228, 31, 7, 9, 228, 32, 7, 9, 
+    228, 33, 7, 9, 228, 34, 7, 9, 228, 35, 7, 9, 228, 36, 7, 9, 228, 37, 7, 
+    9, 228, 38, 7, 9, 228, 39, 7, 9, 228, 40, 7, 9, 228, 41, 7, 9, 228, 42, 
+    7, 9, 228, 43, 7, 9, 228, 44, 7, 9, 228, 45, 7, 9, 228, 46, 7, 9, 228, 
+    47, 7, 9, 228, 48, 7, 9, 228, 49, 7, 9, 228, 50, 7, 9, 228, 51, 7, 9, 
+    228, 52, 7, 9, 228, 53, 7, 9, 228, 54, 7, 9, 228, 55, 7, 9, 228, 56, 7, 
+    9, 228, 57, 7, 9, 228, 58, 7, 9, 228, 59, 7, 9, 228, 60, 7, 9, 228, 61, 
+    7, 9, 228, 62, 7, 9, 228, 63, 7, 9, 228, 64, 7, 9, 228, 65, 7, 9, 228, 
+    66, 7, 9, 228, 67, 7, 9, 228, 68, 7, 9, 228, 69, 7, 9, 228, 70, 7, 9, 
+    228, 71, 7, 9, 228, 72, 7, 9, 228, 73, 7, 9, 228, 74, 7, 9, 228, 75, 7, 
+    9, 228, 76, 7, 9, 228, 77, 7, 9, 228, 78, 7, 9, 228, 79, 7, 9, 228, 80, 
+    7, 9, 228, 81, 7, 9, 228, 82, 7, 9, 228, 83, 7, 9, 228, 84, 7, 9, 228, 
+    85, 7, 9, 228, 86, 7, 9, 228, 87, 7, 9, 228, 88, 7, 9, 228, 89, 7, 9, 
+    228, 90, 7, 9, 228, 91, 7, 9, 228, 92, 7, 9, 228, 93, 7, 9, 228, 94, 7, 
+    9, 228, 95, 7, 9, 228, 96, 7, 9, 228, 97, 7, 9, 228, 98, 7, 9, 228, 99, 
+    7, 9, 228, 100, 7, 9, 228, 101, 7, 9, 228, 102, 7, 9, 228, 103, 7, 9, 
+    228, 104, 7, 9, 228, 105, 7, 9, 228, 106, 7, 9, 228, 107, 7, 9, 228, 108, 
+    7, 9, 228, 109, 7, 9, 228, 110, 7, 9, 228, 111, 7, 9, 228, 112, 7, 9, 
+    228, 113, 7, 9, 228, 114, 7, 9, 228, 115, 7, 9, 228, 116, 7, 9, 228, 117, 
+    7, 9, 228, 118, 7, 9, 228, 119, 7, 9, 228, 120, 7, 9, 228, 121, 7, 9, 
+    228, 122, 7, 9, 228, 123, 7, 9, 228, 124, 7, 9, 228, 125, 7, 9, 228, 126, 
+    7, 9, 228, 127, 7, 9, 228, 128, 7, 9, 228, 129, 7, 9, 228, 130, 7, 9, 
+    228, 131, 7, 9, 228, 132, 7, 9, 228, 133, 7, 9, 228, 134, 7, 9, 228, 135, 
+    7, 9, 228, 136, 7, 9, 228, 137, 7, 9, 228, 138, 7, 9, 228, 139, 7, 9, 
+    228, 140, 7, 9, 228, 141, 7, 9, 228, 142, 7, 9, 228, 143, 7, 9, 228, 144, 
+    7, 9, 228, 145, 7, 9, 228, 146, 7, 9, 228, 147, 7, 9, 228, 148, 7, 9, 
+    228, 149, 7, 9, 228, 150, 7, 9, 228, 151, 7, 9, 228, 152, 7, 9, 228, 153, 
+    7, 9, 228, 154, 7, 9, 228, 155, 7, 9, 228, 156, 7, 9, 228, 157, 7, 9, 
+    228, 158, 7, 9, 228, 159, 7, 9, 228, 160, 7, 9, 228, 161, 7, 9, 228, 162, 
+    7, 9, 228, 163, 7, 9, 228, 164, 7, 9, 228, 165, 7, 9, 228, 166, 7, 9, 
+    228, 167, 7, 9, 228, 168, 7, 9, 228, 169, 7, 9, 228, 170, 7, 9, 228, 171, 
+    7, 9, 228, 172, 7, 9, 228, 173, 7, 9, 228, 174, 7, 9, 228, 175, 7, 9, 
+    228, 176, 7, 9, 228, 177, 7, 9, 228, 178, 7, 9, 228, 179, 7, 9, 228, 180, 
+    7, 9, 228, 181, 7, 9, 228, 182, 7, 9, 228, 183, 7, 9, 228, 184, 7, 9, 
+    228, 185, 7, 9, 228, 186, 7, 9, 228, 187, 7, 9, 228, 188, 7, 9, 228, 189, 
+    7, 9, 228, 190, 7, 9, 228, 191, 7, 9, 228, 192, 7, 9, 228, 193, 7, 9, 
+    228, 194, 7, 9, 228, 195, 7, 9, 228, 196, 7, 9, 228, 197, 7, 9, 228, 198, 
+    7, 9, 228, 199, 7, 9, 228, 200, 7, 9, 228, 201, 7, 9, 228, 202, 7, 9, 
+    228, 203, 7, 9, 228, 204, 7, 9, 228, 205, 7, 9, 228, 206, 7, 9, 228, 207, 
+    7, 9, 228, 208, 7, 9, 228, 209, 7, 9, 228, 210, 7, 9, 228, 211, 7, 9, 
+    228, 212, 7, 9, 228, 213, 7, 9, 228, 214, 7, 9, 228, 215, 7, 9, 228, 216, 
+    7, 9, 228, 217, 7, 9, 228, 218, 7, 9, 228, 219, 7, 9, 228, 220, 7, 9, 
+    228, 221, 7, 9, 228, 222, 7, 9, 228, 223, 7, 9, 228, 224, 7, 9, 228, 225, 
+    7, 9, 228, 226, 7, 9, 228, 227, 7, 9, 228, 228, 7, 9, 228, 229, 7, 9, 
+    228, 230, 7, 9, 228, 231, 7, 9, 228, 232, 7, 9, 228, 233, 7, 9, 228, 234, 
+    7, 9, 228, 235, 7, 9, 228, 236, 7, 9, 228, 237, 7, 9, 228, 238, 7, 9, 
+    228, 239, 7, 9, 228, 240, 7, 9, 228, 241, 7, 9, 228, 242, 7, 9, 228, 243, 
+    7, 9, 228, 244, 7, 9, 228, 245, 7, 9, 228, 246, 7, 9, 228, 247, 7, 9, 
+    228, 248, 7, 9, 228, 249, 7, 9, 228, 250, 7, 9, 228, 251, 7, 9, 228, 252, 
+    7, 9, 228, 253, 7, 9, 228, 254, 7, 9, 228, 255, 7, 9, 229, 0, 7, 9, 229, 
+    1, 7, 9, 229, 2, 7, 9, 229, 3, 7, 9, 229, 4, 7, 9, 229, 5, 7, 9, 229, 6, 
+    7, 9, 229, 7, 7, 9, 229, 8, 7, 9, 229, 9, 7, 9, 229, 10, 7, 9, 229, 11, 
+    7, 9, 229, 12, 7, 9, 229, 13, 7, 9, 229, 14, 7, 9, 229, 15, 7, 9, 229, 
+    16, 7, 9, 229, 17, 7, 9, 229, 18, 7, 9, 229, 19, 7, 9, 229, 20, 7, 9, 
+    229, 21, 7, 9, 229, 22, 7, 9, 229, 23, 7, 9, 229, 24, 7, 9, 229, 25, 7, 
+    9, 229, 26, 7, 9, 229, 27, 7, 9, 229, 28, 7, 9, 229, 29, 7, 9, 229, 30, 
+    7, 9, 229, 31, 7, 9, 229, 32, 7, 9, 229, 33, 7, 9, 229, 34, 7, 9, 229, 
+    35, 7, 9, 229, 36, 7, 9, 229, 37, 7, 9, 229, 38, 7, 9, 229, 39, 7, 9, 
+    229, 40, 7, 9, 229, 41, 7, 9, 229, 42, 7, 9, 229, 43, 7, 9, 229, 44, 7, 
+    9, 229, 45, 237, 194, 249, 173, 97, 240, 15, 97, 233, 54, 69, 97, 235, 
+    51, 69, 97, 61, 52, 97, 240, 114, 52, 97, 238, 107, 52, 97, 234, 17, 97, 
+    233, 59, 97, 40, 232, 74, 97, 38, 232, 74, 97, 235, 52, 97, 248, 49, 52, 
+    97, 240, 27, 97, 231, 94, 97, 248, 37, 208, 97, 236, 177, 97, 26, 242, 
+    217, 97, 26, 127, 97, 26, 111, 97, 26, 166, 97, 26, 177, 97, 26, 176, 97, 
+    26, 187, 97, 26, 203, 97, 26, 195, 97, 26, 202, 97, 240, 24, 97, 234, 14, 
+    97, 235, 44, 52, 97, 240, 7, 52, 97, 232, 68, 52, 97, 236, 156, 69, 97, 
+    234, 20, 254, 20, 97, 8, 5, 1, 67, 97, 8, 5, 1, 217, 97, 8, 5, 1, 255, 
+    18, 97, 8, 5, 1, 209, 97, 8, 5, 1, 72, 97, 8, 5, 1, 255, 19, 97, 8, 5, 1, 
+    210, 97, 8, 5, 1, 192, 97, 8, 5, 1, 71, 97, 8, 5, 1, 221, 97, 8, 5, 1, 
+    255, 15, 97, 8, 5, 1, 162, 97, 8, 5, 1, 173, 97, 8, 5, 1, 197, 97, 8, 5, 
+    1, 73, 97, 8, 5, 1, 223, 97, 8, 5, 1, 255, 20, 97, 8, 5, 1, 144, 97, 8, 
+    5, 1, 193, 97, 8, 5, 1, 214, 97, 8, 5, 1, 79, 97, 8, 5, 1, 179, 97, 8, 5, 
+    1, 255, 16, 97, 8, 5, 1, 206, 97, 8, 5, 1, 255, 14, 97, 8, 5, 1, 255, 17, 
+    97, 40, 31, 104, 97, 238, 75, 236, 177, 97, 38, 31, 104, 97, 190, 238, 
+    54, 97, 170, 242, 224, 97, 242, 245, 238, 54, 97, 8, 3, 1, 67, 97, 8, 3, 
+    1, 217, 97, 8, 3, 1, 255, 18, 97, 8, 3, 1, 209, 97, 8, 3, 1, 72, 97, 8, 
+    3, 1, 255, 19, 97, 8, 3, 1, 210, 97, 8, 3, 1, 192, 97, 8, 3, 1, 71, 97, 
+    8, 3, 1, 221, 97, 8, 3, 1, 255, 15, 97, 8, 3, 1, 162, 97, 8, 3, 1, 173, 
+    97, 8, 3, 1, 197, 97, 8, 3, 1, 73, 97, 8, 3, 1, 223, 97, 8, 3, 1, 255, 
+    20, 97, 8, 3, 1, 144, 97, 8, 3, 1, 193, 97, 8, 3, 1, 214, 97, 8, 3, 1, 
+    79, 97, 8, 3, 1, 179, 97, 8, 3, 1, 255, 16, 97, 8, 3, 1, 206, 97, 8, 3, 
+    1, 255, 14, 97, 8, 3, 1, 255, 17, 97, 40, 242, 225, 104, 97, 59, 242, 
+    224, 97, 38, 242, 225, 104, 97, 169, 241, 43, 249, 173, 34, 232, 211, 34, 
+    232, 212, 34, 232, 213, 34, 232, 214, 34, 232, 215, 34, 232, 216, 34, 
+    232, 217, 34, 232, 218, 34, 232, 219, 34, 232, 220, 34, 232, 221, 34, 
+    232, 222, 34, 232, 223, 34, 232, 224, 34, 232, 225, 34, 232, 226, 34, 
+    232, 227, 34, 232, 228, 34, 232, 229, 34, 232, 230, 34, 232, 231, 34, 
+    232, 232, 34, 232, 233, 34, 232, 234, 34, 232, 235, 34, 232, 236, 34, 
+    232, 237, 34, 232, 238, 34, 232, 239, 34, 232, 240, 34, 232, 241, 34, 
+    232, 242, 34, 232, 243, 34, 232, 244, 34, 232, 245, 34, 232, 246, 34, 
+    232, 247, 34, 232, 248, 34, 232, 249, 34, 232, 250, 34, 232, 251, 34, 
+    232, 252, 34, 232, 253, 34, 232, 254, 34, 232, 255, 34, 233, 0, 34, 233, 
+    1, 34, 233, 2, 34, 233, 3, 34, 233, 4, 34, 233, 5, 34, 233, 6, 34, 233, 
+    7, 34, 233, 8, 34, 233, 9, 34, 233, 10, 34, 233, 11, 34, 233, 12, 34, 
+    233, 13, 34, 233, 14, 34, 233, 15, 34, 233, 16, 34, 233, 17, 34, 233, 18, 
+    34, 233, 19, 34, 233, 20, 34, 233, 21, 34, 233, 22, 34, 233, 23, 34, 233, 
+    24, 34, 233, 25, 34, 233, 26, 34, 233, 27, 34, 233, 28, 34, 233, 29, 34, 
+    233, 30, 34, 233, 31, 34, 233, 32, 34, 233, 33, 34, 233, 34, 34, 233, 35, 
+    34, 233, 36, 34, 233, 37, 34, 231, 153, 34, 231, 154, 34, 231, 155, 34, 
+    231, 156, 34, 231, 157, 34, 231, 158, 34, 231, 159, 34, 231, 160, 34, 
+    231, 161, 34, 231, 162, 34, 231, 163, 34, 231, 164, 34, 231, 165, 34, 
+    231, 166, 34, 231, 167, 34, 231, 168, 34, 231, 169, 34, 231, 170, 34, 
+    231, 171, 34, 231, 172, 34, 231, 173, 34, 231, 174, 34, 231, 175, 34, 
+    231, 176, 34, 231, 177, 34, 231, 178, 34, 231, 179, 34, 231, 180, 34, 
+    231, 181, 34, 231, 182, 34, 231, 183, 34, 231, 184, 34, 231, 185, 34, 
+    231, 186, 34, 231, 187, 34, 231, 188, 34, 231, 189, 34, 231, 190, 34, 
+    231, 191, 34, 231, 192, 34, 231, 193, 34, 231, 194, 34, 231, 195, 34, 
+    231, 196, 34, 231, 197, 34, 231, 198, 34, 231, 199, 34, 231, 200, 34, 
+    231, 201, 34, 231, 202, 34, 231, 203, 34, 231, 204, 34, 231, 205, 34, 
+    231, 206, 34, 231, 207, 34, 231, 208, 34, 231, 209, 34, 231, 210, 34, 
+    231, 211, 34, 231, 212, 34, 231, 213, 34, 231, 214, 34, 231, 215, 34, 
+    231, 216, 34, 231, 217, 34, 231, 218, 34, 231, 219, 34, 231, 220, 34, 
+    231, 221, 34, 231, 222, 34, 231, 223, 34, 231, 224, 34, 231, 225, 34, 
+    231, 226, 34, 231, 227, 34, 231, 228, 34, 231, 229, 34, 231, 230, 34, 
+    231, 231, 34, 231, 232, 34, 231, 233, 34, 231, 234, 34, 231, 235, 34, 
+    231, 236, 34, 231, 237, 34, 231, 238, 34, 231, 239, 34, 231, 240, 34, 
+    231, 241, 34, 231, 242, 34, 231, 243, 34, 231, 244, 34, 231, 245, 34, 
+    231, 246, 34, 231, 247, 34, 231, 248, 34, 231, 249, 34, 231, 250, 34, 
+    231, 251, 34, 231, 252, 34, 231, 253, 34, 231, 254, 34, 231, 255, 34, 
+    232, 0, 34, 232, 1, 34, 232, 2, 34, 232, 3, 34, 232, 4, 34, 232, 5, 34, 
+    232, 6, 34, 232, 7, 34, 232, 8, 34, 232, 9, 34, 232, 10, 34, 232, 11, 34, 
+    232, 12, 34, 232, 13, 34, 232, 14, 34, 232, 15, 34, 232, 16, 34, 232, 17, 
+    34, 232, 18, 34, 232, 19, 34, 232, 20, 34, 232, 21, 34, 232, 22, 34, 232, 
+    23, 34, 232, 24, 34, 232, 25, 34, 232, 26, 34, 232, 27, 34, 232, 28, 34, 
+    232, 29, 34, 232, 30, 34, 232, 31, 34, 232, 32, 34, 232, 33, 34, 232, 34, 
+    34, 232, 35, 34, 232, 36, 34, 232, 37, 34, 232, 38, 34, 232, 39, 34, 232, 
+    40, 34, 232, 41, 34, 232, 42, 34, 232, 43, 34, 232, 44, 34, 232, 45, 34, 
+    232, 46, 34, 232, 47, 34, 232, 48, 34, 232, 49, 34, 232, 50, 34, 232, 51, 
+    34, 232, 52, 34, 232, 53, 
+};
+
+static unsigned char phrasebook_offset1[] = {
+    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16, 17, 18, 19, 
+    20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 
+    38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 16, 16, 16, 16, 
+    16, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 
+    69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 16, 81, 82, 83, 84, 85, 
+    86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 97, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 98, 99, 100, 101, 102, 103, 
+    104, 105, 106, 107, 16, 16, 16, 16, 108, 16, 109, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 110, 111, 112, 113, 114, 115, 
+    116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 16, 16, 128, 
+    129, 130, 131, 16, 16, 16, 16, 16, 16, 132, 16, 16, 16, 133, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 134, 135, 136, 
+    137, 138, 16, 139, 16, 140, 141, 142, 143, 144, 145, 146, 147, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 148, 149, 
+    150, 151, 152, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 153, 16, 154, 155, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 
+};
+
+static unsigned int phrasebook_offset2[] = {
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 6, 9, 11, 14, 17, 19, 21, 24, 27, 29, 32, 
+    34, 36, 39, 41, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 69, 72, 
+    75, 78, 82, 86, 90, 95, 99, 103, 108, 112, 116, 120, 124, 129, 133, 137, 
+    141, 145, 149, 154, 158, 162, 166, 170, 174, 179, 183, 188, 193, 196, 
+    200, 203, 206, 209, 213, 217, 221, 226, 230, 234, 239, 243, 247, 251, 
+    255, 260, 264, 268, 272, 276, 280, 285, 289, 293, 297, 301, 305, 310, 
+    314, 319, 324, 328, 331, 335, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 336, 340, 345, 
+    348, 351, 354, 357, 360, 363, 364, 367, 373, 380, 382, 386, 389, 390, 
+    393, 396, 399, 402, 406, 409, 412, 416, 418, 421, 427, 434, 442, 450, 
+    457, 462, 468, 474, 481, 487, 493, 501, 506, 514, 520, 526, 533, 539, 
+    545, 551, 558, 564, 569, 576, 582, 588, 595, 601, 607, 610, 616, 622, 
+    628, 635, 641, 648, 653, 659, 665, 671, 678, 684, 690, 698, 703, 711, 
+    717, 723, 730, 736, 742, 748, 755, 761, 766, 773, 779, 785, 792, 798, 
+    804, 807, 813, 819, 825, 832, 838, 845, 850, 857, 863, 869, 876, 883, 
+    890, 897, 904, 911, 919, 927, 935, 943, 951, 959, 967, 975, 982, 989, 
+    995, 1001, 1008, 1015, 1022, 1029, 1036, 1043, 1050, 1057, 1065, 1073, 
+    1081, 1089, 1097, 1105, 1113, 1121, 1129, 1137, 1144, 1151, 1157, 1163, 
+    1169, 1175, 1182, 1189, 1196, 1203, 1210, 1216, 1221, 1226, 1234, 1242, 
+    1250, 1258, 1263, 1270, 1277, 1285, 1293, 1301, 1309, 1319, 1329, 1336, 
+    1343, 1350, 1357, 1365, 1373, 1381, 1389, 1400, 1405, 1410, 1416, 1422, 
+    1429, 1436, 1443, 1450, 1455, 1460, 1467, 1474, 1482, 1490, 1498, 1506, 
+    1513, 1520, 1528, 1536, 1544, 1552, 1560, 1568, 1576, 1584, 1592, 1600, 
+    1607, 1614, 1620, 1626, 1632, 1638, 1645, 1652, 1660, 1668, 1675, 1682, 
+    1689, 1696, 1704, 1712, 1720, 1728, 1735, 1742, 1749, 1757, 1765, 1773, 
+    1781, 1786, 1792, 1798, 1805, 1812, 1817, 1822, 1828, 1835, 1842, 1848, 
+    1855, 1863, 1871, 1877, 1882, 1887, 1893, 1900, 1907, 1914, 1919, 1924, 
+    1929, 1935, 1942, 1949, 1956, 1963, 1968, 1976, 1986, 1994, 2001, 2008, 
+    2013, 2018, 2025, 2032, 2036, 2041, 2046, 2051, 2058, 2067, 2074, 2081, 
+    2090, 2097, 2104, 2109, 2116, 2123, 2130, 2137, 2144, 2149, 2156, 2163, 
+    2171, 2176, 2181, 2186, 2196, 2200, 2206, 2212, 2218, 2224, 2232, 2245, 
+    2253, 2258, 2267, 2272, 2277, 2286, 2291, 2298, 2305, 2312, 2319, 2326, 
+    2333, 2340, 2347, 2356, 2365, 2374, 2383, 2393, 2403, 2412, 2421, 2426, 
+    2435, 2444, 2453, 2462, 2469, 2476, 2483, 2490, 2498, 2506, 2514, 2522, 
+    2529, 2536, 2545, 2554, 2562, 2570, 2578, 2583, 2593, 2598, 2605, 2612, 
+    2617, 2622, 2629, 2636, 2646, 2656, 2663, 2670, 2679, 2688, 2695, 2702, 
+    2711, 2720, 2727, 2734, 2743, 2752, 2759, 2766, 2775, 2784, 2791, 2798, 
+    2807, 2816, 2824, 2832, 2842, 2852, 2859, 2866, 2875, 2884, 2893, 2902, 
+    2911, 2920, 2925, 2930, 2938, 2946, 2956, 2964, 2969, 2974, 2981, 2988, 
+    2995, 3002, 3009, 3016, 3025, 3034, 3043, 3052, 3059, 3066, 3075, 3084, 
+    3091, 3098, 3106, 3114, 3122, 3128, 3135, 3142, 3148, 3155, 3162, 3169, 
+    3178, 3188, 3198, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3204, 3209, 
+    3214, 3220, 3226, 3232, 3240, 3248, 3255, 3260, 3265, 3272, 3278, 3285, 
+    3294, 3303, 3312, 3319, 3324, 3329, 3334, 3341, 3346, 3353, 3360, 3366, 
+    3371, 3376, 3385, 3393, 3402, 3407, 3412, 3422, 3429, 3437, 3446, 3451, 
+    3457, 3463, 3470, 3475, 3480, 3490, 3498, 3507, 3515, 3523, 3532, 3537, 
+    3544, 3551, 3556, 3568, 3576, 3584, 3589, 3598, 3603, 3608, 3615, 3620, 
+    3626, 3632, 3638, 3647, 3655, 3660, 3668, 3673, 3681, 3688, 3694, 3700, 
+    3705, 3713, 3721, 3726, 3734, 3740, 3745, 3752, 3760, 3769, 3776, 3783, 
+    3793, 3800, 3807, 3817, 3824, 3831, 3838, 3844, 3850, 3859, 3871, 3875, 
+    3882, 3886, 3890, 3895, 3903, 3910, 3915, 3920, 3924, 3929, 3934, 3938, 
+    3943, 3949, 3955, 3960, 3966, 3971, 3976, 3981, 3986, 3991, 3993, 3998, 
+    4001, 4007, 4013, 4019, 4023, 4030, 4037, 4043, 4050, 4058, 4066, 4071, 
+    4076, 4081, 4086, 4088, 4090, 4093, 4095, 4097, 4102, 4107, 4113, 4118, 
+    4122, 4126, 4130, 4137, 4143, 4148, 4154, 4159, 4165, 4173, 4181, 4185, 
+    4189, 4194, 4200, 4206, 4212, 4218, 4223, 4231, 4240, 4249, 4253, 4259, 
+    4266, 4273, 4280, 4287, 4291, 4297, 4302, 4307, 4312, 4316, 4318, 4320, 
+    4323, 4326, 4329, 4331, 4335, 4339, 4345, 4348, 4353, 4359, 4365, 4368, 
+    4373, 4378, 4382, 4387, 4392, 4398, 4404, 4409, 4414, 4418, 4421, 4427, 
+    4432, 4437, 4442, 4447, 4453, 4459, 4462, 4466, 4470, 4474, 4477, 4480, 
+    4485, 4489, 4496, 4500, 4505, 4509, 4515, 4519, 4523, 4527, 4532, 4537, 
+    4544, 4550, 4557, 4563, 4569, 4575, 4578, 4582, 4586, 4589, 4593, 4598, 
+    4603, 4607, 4611, 4617, 4621, 4625, 4630, 4636, 4640, 4645, 4649, 4655, 
+    4660, 4665, 4670, 4675, 4681, 4684, 4688, 4693, 4698, 4707, 4713, 4717, 
+    4721, 4726, 4730, 4735, 4739, 4742, 4747, 4750, 4756, 4761, 4766, 4771, 
+    4776, 4781, 4786, 4792, 4797, 4802, 4807, 4812, 4817, 4822, 0, 0, 0, 0, 
+    4827, 4830, 0, 0, 0, 0, 4834, 0, 0, 0, 4837, 0, 0, 0, 0, 0, 4841, 4844, 
+    4849, 4856, 4861, 4869, 4877, 0, 4885, 0, 4893, 4901, 4908, 4919, 4924, 
+    4929, 4934, 4939, 4944, 4949, 4954, 4959, 4964, 4969, 4974, 4979, 4984, 
+    4989, 4994, 4999, 0, 5004, 5009, 5014, 5019, 5024, 5029, 5034, 5039, 
+    5047, 5055, 5062, 5070, 5078, 5086, 5097, 5102, 5107, 5112, 5117, 5122, 
+    5127, 5132, 5137, 5142, 5147, 5152, 5157, 5162, 5167, 5172, 5177, 5182, 
+    5188, 5193, 5198, 5203, 5208, 5213, 5218, 5223, 5231, 5239, 5247, 5255, 
+    0, 5262, 5266, 5270, 5277, 5287, 5297, 5301, 5305, 5309, 5315, 5322, 
+    5326, 5331, 5335, 5340, 5344, 5349, 5353, 5358, 5363, 5368, 5373, 5378, 
+    5383, 5388, 5393, 5398, 5403, 5408, 5413, 5418, 5423, 5428, 5432, 5436, 
+    5442, 5446, 5451, 5457, 5464, 5469, 5474, 5481, 5486, 5491, 5498, 5506, 
+    5515, 5525, 5532, 5537, 5542, 5547, 5554, 5559, 5565, 5570, 5575, 5580, 
+    5585, 5590, 5595, 5601, 5607, 5612, 5616, 5621, 5626, 5631, 5636, 5641, 
+    5646, 5651, 5655, 5661, 5665, 5670, 5675, 5680, 5684, 5689, 5694, 5699, 
+    5704, 5708, 5713, 5717, 5722, 5727, 5732, 5737, 5743, 5748, 5754, 5758, 
+    5763, 5767, 5771, 5776, 5781, 5786, 5791, 5796, 5801, 5806, 5810, 5816, 
+    5820, 5825, 5830, 5835, 5839, 5844, 5849, 5854, 5859, 5863, 5868, 5872, 
+    5877, 5882, 5887, 5892, 5898, 5903, 5909, 5913, 5918, 5922, 5929, 5934, 
+    5939, 5944, 5951, 5956, 5962, 5967, 5972, 5977, 5982, 5987, 5992, 5998, 
+    6004, 6009, 6014, 6019, 6024, 6029, 6035, 6041, 6048, 6055, 6064, 6073, 
+    6080, 6087, 6096, 6105, 6110, 6115, 6120, 6125, 6130, 6135, 6140, 6145, 
+    6156, 6167, 6172, 6177, 6184, 6191, 6198, 6205, 6210, 6215, 6220, 6225, 
+    6229, 6233, 6237, 6242, 0, 6247, 6254, 6259, 6268, 6277, 6283, 6289, 
+    6297, 6305, 6313, 6321, 6328, 6335, 6344, 6353, 6361, 6369, 6377, 6385, 
+    6393, 6401, 6409, 6417, 6424, 6431, 6437, 6443, 6451, 6459, 6466, 6473, 
+    6482, 6491, 6497, 6503, 6511, 6519, 6527, 6535, 6541, 6547, 6555, 6563, 
+    6571, 6579, 6586, 6593, 6601, 6609, 6617, 6625, 6630, 6635, 6642, 6649, 
+    6659, 6669, 6673, 6681, 6689, 6696, 6703, 6711, 6719, 6726, 6733, 6741, 
+    6749, 6756, 6763, 6771, 0, 6779, 6786, 6793, 6799, 6805, 6811, 6817, 
+    6825, 6833, 6838, 6843, 6850, 6857, 6864, 6871, 6878, 6885, 6892, 6899, 
+    6905, 6911, 6917, 6923, 6929, 6935, 6941, 6947, 6955, 6963, 6969, 6975, 
+    6981, 6987, 6993, 6999, 7006, 7013, 7020, 7027, 7035, 7043, 7050, 0, 0, 
+    0, 0, 0, 0, 7057, 7064, 7071, 7078, 7085, 7092, 7099, 7106, 7113, 7120, 
+    7127, 7134, 7141, 7148, 7155, 7162, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7169, 
+    7174, 7179, 7184, 7189, 7194, 7199, 7204, 7209, 7213, 7218, 7223, 7228, 
+    7233, 7238, 7243, 7248, 7253, 7258, 7263, 7268, 7273, 7278, 7283, 7288, 
+    7293, 7298, 7303, 7308, 7313, 7318, 7323, 7328, 7333, 7338, 7343, 7348, 
+    7353, 0, 0, 7358, 7365, 7368, 7372, 7376, 7379, 7383, 0, 7387, 7392, 
+    7397, 7402, 7407, 7412, 7417, 7422, 7427, 7431, 7436, 7441, 7446, 7451, 
+    7456, 7461, 7466, 7471, 7476, 7481, 7486, 7491, 7496, 7501, 7506, 7511, 
+    7516, 7521, 7526, 7531, 7536, 7541, 7546, 7551, 7556, 7561, 7566, 7571, 
+    7576, 0, 7583, 7587, 0, 0, 0, 0, 0, 0, 7590, 7595, 7600, 7605, 7612, 
+    7619, 7624, 7629, 7634, 7639, 7644, 7649, 7654, 7661, 7666, 7673, 7680, 
+    7685, 7692, 7697, 7702, 7707, 7714, 7719, 7724, 7731, 7740, 7745, 7750, 
+    7755, 7760, 7766, 7771, 7778, 7785, 7792, 7797, 7802, 7807, 7812, 7817, 
+    0, 7822, 7827, 7835, 7840, 7845, 7850, 7855, 7862, 7869, 7876, 7881, 
+    7886, 7893, 0, 0, 0, 0, 0, 0, 0, 0, 7900, 7904, 7908, 7912, 7916, 7920, 
+    7924, 7928, 7932, 7936, 7940, 7945, 7949, 7953, 7958, 7962, 7967, 7971, 
+    7975, 7979, 7984, 7988, 7993, 7997, 8001, 8005, 8009, 0, 0, 0, 0, 0, 
+    8013, 8020, 8028, 8035, 8040, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8045, 
+    8048, 8052, 8057, 0, 0, 0, 0, 0, 0, 0, 8061, 8064, 8067, 8072, 8078, 
+    8082, 8090, 8096, 8102, 8110, 8114, 0, 0, 0, 0, 0, 8119, 0, 0, 8122, 
+    8129, 0, 8133, 8137, 8144, 8150, 8157, 8163, 8169, 8173, 8177, 8183, 
+    8187, 8191, 8195, 8199, 8203, 8207, 8211, 8215, 8219, 8223, 8227, 8231, 
+    8235, 8239, 8243, 8247, 0, 0, 0, 0, 0, 8251, 8254, 8258, 8262, 8266, 
+    8270, 8274, 8278, 8282, 8286, 8291, 8295, 8298, 8301, 8304, 8307, 8310, 
+    8313, 8316, 8319, 8323, 8326, 8329, 8334, 8339, 8344, 8347, 8354, 8363, 
+    8368, 8372, 0, 8379, 8384, 8388, 8392, 8396, 8400, 8404, 8408, 8412, 
+    8416, 8420, 8424, 8429, 8434, 8441, 8447, 8453, 8459, 8464, 8472, 8480, 
+    8485, 8491, 8497, 8503, 8509, 8513, 8517, 8521, 8528, 8538, 8542, 8546, 
+    8550, 8556, 8564, 8568, 8572, 8579, 8583, 8587, 8591, 8598, 8605, 8617, 
+    8621, 8625, 8629, 8639, 8648, 8652, 8659, 8666, 8673, 8682, 8693, 8701, 
+    8705, 8714, 8725, 8733, 8746, 8754, 8762, 8770, 8778, 8784, 8793, 8800, 
+    8804, 8812, 8816, 8823, 8831, 8835, 8841, 8848, 8855, 8859, 8867, 8871, 
+    8878, 8882, 8890, 8894, 8902, 8908, 8914, 8921, 8928, 8934, 8939, 8943, 
+    8949, 8956, 8962, 8969, 8976, 8982, 8991, 8999, 9006, 9012, 9016, 9019, 
+    9023, 9029, 9037, 9041, 9047, 9053, 9059, 9066, 9069, 9076, 9081, 9089, 
+    9093, 9097, 9109, 9121, 9127, 9133, 9138, 9144, 9149, 9155, 9165, 9172, 
+    9181, 9191, 9197, 9202, 9207, 9211, 9215, 9220, 9225, 9231, 9238, 9245, 
+    9256, 9261, 9269, 9277, 9284, 9290, 9296, 9302, 9308, 9314, 9320, 9326, 
+    9332, 9338, 9345, 9352, 9359, 9365, 9373, 9381, 9387, 9393, 9399, 9404, 
+    9409, 9413, 9420, 9426, 9435, 9443, 9446, 9451, 9456, 0, 9461, 9465, 
+    9469, 9475, 9479, 9483, 9489, 9493, 9501, 9505, 9509, 9513, 9517, 9521, 
+    9527, 9531, 9537, 9541, 9545, 9549, 9553, 9557, 9562, 9565, 9569, 9574, 
+    9578, 9582, 9586, 9590, 9594, 9599, 9604, 9609, 9613, 9617, 9622, 9626, 
+    9630, 9635, 9639, 9643, 9650, 9657, 9661, 9665, 9670, 9674, 9678, 9681, 
+    9686, 9689, 9692, 9697, 9702, 9706, 9710, 9716, 9722, 9725, 0, 0, 9728, 
+    9734, 9740, 9746, 9756, 9768, 9780, 9797, 9809, 9820, 9827, 9834, 9845, 
+    9860, 9871, 9877, 9886, 9894, 9906, 9916, 9924, 9936, 9943, 9951, 9963, 
+    9969, 9975, 9982, 9989, 9995, 10000, 10010, 10017, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10027, 10031, 10035, 10039, 10043, 
+    10047, 10051, 10055, 10059, 10063, 10067, 10071, 10075, 10079, 10083, 
+    10087, 10091, 10095, 10099, 10103, 10107, 10111, 10115, 10119, 10123, 
+    10127, 10131, 10135, 10139, 10143, 10147, 10151, 10155, 10158, 10162, 
+    10166, 10170, 10174, 10178, 10181, 10184, 10187, 10190, 10193, 10196, 
+    10199, 10202, 10205, 10208, 10211, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 10215, 10219, 10223, 10227, 10232, 10235, 10239, 10242, 10246, 
+    10249, 10253, 10257, 10261, 10266, 10271, 10274, 10278, 10283, 10288, 
+    10291, 10295, 10298, 10302, 10306, 10310, 10314, 10318, 10322, 10326, 
+    10330, 10334, 10338, 10342, 10346, 10350, 10354, 10358, 10362, 10366, 
+    10370, 10374, 10378, 10382, 10386, 10390, 10394, 10397, 10400, 10404, 
+    10408, 10412, 10416, 10420, 10424, 10428, 10432, 10436, 0, 0, 10439, 
+    10443, 10447, 10452, 10456, 10461, 10465, 10470, 10475, 10481, 10487, 
+    10493, 10497, 10502, 10508, 10514, 10518, 10523, 0, 0, 10527, 10530, 
+    10536, 10542, 10547, 0, 0, 0, 10552, 10556, 10560, 10564, 10568, 10572, 
+    10576, 10580, 10584, 10589, 10594, 10599, 10605, 10608, 10612, 10616, 
+    10619, 10622, 10625, 10628, 10631, 10634, 10637, 10640, 10643, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 10647, 0, 0, 0, 10652, 10656, 10660, 0, 10664, 
+    10667, 10671, 10674, 10678, 10681, 10685, 10689, 0, 0, 10693, 10696, 0, 
+    0, 10700, 10703, 10707, 10710, 10714, 10718, 10722, 10726, 10730, 10734, 
+    10738, 10742, 10746, 10750, 10754, 10758, 10762, 10766, 10770, 10774, 
+    10778, 10782, 0, 10786, 10790, 10794, 10798, 10802, 10805, 10808, 0, 
+    10812, 0, 0, 0, 10816, 10820, 10824, 10828, 0, 0, 10831, 10835, 10839, 
+    10844, 10848, 10853, 10857, 10862, 10867, 0, 0, 10873, 10877, 0, 0, 
+    10882, 10886, 10891, 10895, 0, 0, 0, 0, 0, 0, 0, 0, 10901, 0, 0, 0, 0, 
+    10907, 10911, 0, 10915, 10919, 10924, 10929, 10934, 0, 0, 10940, 10944, 
+    10947, 10950, 10953, 10956, 10959, 10962, 10965, 10968, 10971, 10980, 
+    10988, 10992, 10996, 11002, 11008, 11014, 11020, 11035, 11042, 0, 0, 0, 
+    0, 0, 0, 11045, 11051, 11055, 0, 11059, 11062, 11066, 11069, 11073, 
+    11076, 0, 0, 0, 0, 11080, 11084, 0, 0, 11088, 11092, 11096, 11099, 11103, 
+    11107, 11111, 11115, 11119, 11123, 11127, 11131, 11135, 11139, 11143, 
+    11147, 11151, 11155, 11159, 11163, 11167, 11171, 0, 11175, 11179, 11183, 
+    11187, 11191, 11194, 11197, 0, 11201, 11205, 0, 11209, 11213, 0, 11217, 
+    11221, 0, 0, 11224, 0, 11228, 11233, 11237, 11242, 11246, 0, 0, 0, 0, 
+    11251, 11256, 0, 0, 11261, 11266, 11271, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    11275, 11279, 11283, 11287, 0, 11291, 0, 0, 0, 0, 0, 0, 0, 11295, 11299, 
+    11302, 11305, 11308, 11311, 11314, 11317, 11320, 11323, 11326, 11329, 
+    11332, 11335, 11338, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11343, 11347, 
+    11351, 0, 11355, 11358, 11362, 11365, 11369, 11372, 11376, 11380, 11384, 
+    0, 11389, 11392, 11396, 0, 11401, 11404, 11408, 11411, 11415, 11419, 
+    11423, 11427, 11431, 11435, 11439, 11443, 11447, 11451, 11455, 11459, 
+    11463, 11467, 11471, 11475, 11479, 11483, 0, 11487, 11491, 11495, 11499, 
+    11503, 11506, 11509, 0, 11513, 11517, 0, 11521, 11525, 11529, 11533, 
+    11537, 0, 0, 11540, 11544, 11548, 11553, 11557, 11562, 11566, 11571, 
+    11576, 11582, 0, 11588, 11592, 11597, 0, 11603, 11607, 11612, 0, 0, 
+    11616, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11619, 11624, 11629, 
+    11634, 0, 0, 11640, 11644, 11647, 11650, 11653, 11656, 11659, 11662, 
+    11665, 11668, 0, 11671, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    11675, 11679, 11683, 0, 11687, 11690, 11694, 11697, 11701, 11704, 11708, 
+    11712, 0, 0, 11716, 11719, 0, 0, 11723, 11726, 11730, 11733, 11737, 
+    11741, 11745, 11749, 11753, 11757, 11761, 11765, 11769, 11773, 11777, 
+    11781, 11785, 11789, 11793, 11797, 11801, 11805, 0, 11809, 11813, 11817, 
+    11821, 11825, 11828, 11831, 0, 11835, 11839, 0, 11843, 11847, 11851, 
+    11855, 11859, 0, 0, 11862, 11866, 11870, 11875, 11879, 11884, 11888, 
+    11893, 0, 0, 0, 11898, 11902, 0, 0, 11907, 11911, 11916, 0, 0, 0, 0, 0, 
+    0, 0, 0, 11920, 11926, 0, 0, 0, 0, 11932, 11936, 0, 11940, 11944, 11949, 
+    0, 0, 0, 0, 11954, 11958, 11961, 11964, 11967, 11970, 11973, 11976, 
+    11979, 11982, 11985, 11988, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 11992, 11996, 0, 12000, 12003, 12007, 12010, 12014, 12017, 0, 0, 0, 
+    12021, 12024, 12028, 0, 12032, 12035, 12039, 12043, 0, 0, 0, 12046, 
+    12050, 0, 12054, 0, 12058, 12062, 0, 0, 0, 12066, 12070, 0, 0, 0, 12074, 
+    12078, 12082, 0, 0, 0, 12086, 12089, 12092, 12096, 12100, 12104, 12108, 
+    12112, 12116, 12120, 12124, 12128, 0, 0, 0, 0, 12131, 12136, 12140, 
+    12145, 12149, 0, 0, 0, 12154, 12158, 12163, 0, 12168, 12172, 12177, 
+    12182, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 12192, 12196, 12199, 12202, 12205, 12208, 12211, 12214, 12217, 
+    12220, 12223, 12227, 12233, 12239, 12243, 12247, 12251, 12255, 12259, 
+    12264, 12268, 0, 0, 0, 0, 0, 0, 12271, 12275, 12279, 0, 12283, 12286, 
+    12290, 12293, 12297, 12300, 12304, 12308, 0, 12312, 12315, 12319, 0, 
+    12323, 12326, 12330, 12334, 12337, 12341, 12345, 12349, 12353, 12357, 
+    12361, 12365, 12369, 12373, 12377, 12381, 12385, 12389, 12393, 12397, 
+    12401, 12405, 12409, 0, 12413, 12417, 12421, 12425, 12429, 12432, 12435, 
+    12439, 12443, 12447, 0, 12451, 12455, 12459, 12463, 12467, 0, 0, 0, 0, 
+    12470, 12475, 12479, 12484, 12488, 12493, 12498, 0, 12504, 12508, 12513, 
+    0, 12518, 12522, 12527, 12532, 0, 0, 0, 0, 0, 0, 0, 12536, 12540, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 12546, 12551, 0, 0, 0, 0, 12556, 12560, 12563, 
+    12566, 12569, 12572, 12575, 12578, 12581, 12584, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12587, 12591, 0, 12595, 12598, 12602, 
+    12605, 12609, 12612, 12616, 12620, 0, 12624, 12627, 12631, 0, 12635, 
+    12638, 12642, 12646, 12649, 12653, 12657, 12661, 12665, 12669, 12673, 
+    12677, 12681, 12685, 12689, 12693, 12697, 12701, 12705, 12709, 12713, 
+    12717, 12721, 0, 12725, 12729, 12733, 12737, 12741, 12744, 12747, 12751, 
+    12755, 12759, 0, 12763, 12767, 12771, 12775, 12779, 0, 0, 12782, 12786, 
+    12790, 12795, 12799, 12804, 12808, 12813, 12818, 0, 12824, 12828, 12833, 
+    0, 12838, 12842, 12847, 12852, 0, 0, 0, 0, 0, 0, 0, 12856, 12860, 0, 0, 
+    0, 0, 0, 0, 0, 12866, 0, 12870, 12875, 0, 0, 0, 0, 12880, 12884, 12887, 
+    12890, 12893, 12896, 12899, 12902, 12905, 12908, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12911, 12915, 0, 12919, 12922, 12926, 
+    12929, 12933, 12936, 12940, 12944, 0, 12948, 12951, 12955, 0, 12959, 
+    12962, 12966, 12970, 12973, 12977, 12981, 12985, 12989, 12993, 12997, 
+    13001, 13005, 13009, 13013, 13017, 13021, 13025, 13029, 13033, 13037, 
+    13041, 13045, 0, 13049, 13053, 13057, 13061, 13065, 13068, 13071, 13075, 
+    13079, 13083, 13087, 13091, 13095, 13099, 13103, 13107, 0, 0, 0, 0, 
+    13110, 13115, 13119, 13124, 13128, 13133, 0, 0, 13138, 13142, 13147, 0, 
+    13152, 13156, 13161, 13166, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13170, 0, 0, 0, 0, 
+    0, 0, 0, 0, 13176, 13181, 0, 0, 0, 0, 13186, 13190, 13193, 13196, 13199, 
+    13202, 13205, 13208, 13211, 13214, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 13217, 13221, 0, 13225, 13229, 13233, 13237, 13241, 13245, 
+    13249, 13253, 13257, 13261, 13265, 13269, 13273, 13277, 13281, 13285, 
+    13289, 13293, 0, 0, 0, 13297, 13303, 13309, 13315, 13321, 13327, 13333, 
+    13339, 13345, 13351, 13357, 13363, 13371, 13377, 13383, 13389, 13395, 
+    13401, 13407, 13413, 13419, 13425, 13431, 13437, 0, 13443, 13449, 13455, 
+    13461, 13467, 13473, 13477, 13483, 13487, 0, 13491, 0, 0, 13497, 13501, 
+    13507, 13513, 13519, 13523, 13529, 0, 0, 0, 13533, 0, 0, 0, 0, 13537, 
+    13542, 13549, 13556, 13563, 13570, 0, 13577, 0, 13584, 13589, 13594, 
+    13601, 13608, 13617, 13628, 13637, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 13642, 13649, 13656, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    13661, 13667, 13673, 13679, 13685, 13691, 13697, 13703, 13709, 13715, 
+    13721, 13727, 13733, 13739, 13745, 13750, 13756, 13762, 13768, 13774, 
+    13780, 13785, 13791, 13797, 13803, 13809, 13815, 13821, 13827, 13833, 
+    13839, 13845, 13851, 13856, 13862, 13868, 13872, 13878, 13882, 13888, 
+    13894, 13900, 13906, 13912, 13918, 13923, 13929, 13933, 13938, 13944, 
+    13950, 13956, 13961, 13967, 13973, 13979, 13984, 13990, 0, 0, 0, 0, 
+    13994, 14000, 14005, 14011, 14016, 14024, 14032, 14036, 14040, 14044, 
+    14050, 14056, 14062, 14068, 14072, 14076, 14080, 14084, 14088, 14091, 
+    14094, 14097, 14100, 14103, 14106, 14109, 14112, 14115, 14119, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14123, 14127, 0, 14133, 0, 0, 14139, 14143, 
+    0, 14147, 0, 0, 14153, 0, 0, 0, 0, 0, 0, 14157, 14161, 14164, 14170, 0, 
+    14176, 14180, 14184, 14188, 14194, 14200, 14206, 0, 14212, 14216, 14220, 
+    0, 14226, 0, 14232, 0, 0, 14236, 14242, 0, 14248, 14251, 14257, 14260, 
+    14264, 14271, 14276, 14281, 14285, 14290, 14295, 14300, 14304, 0, 14309, 
+    14316, 14322, 0, 0, 14328, 14332, 14337, 14341, 14346, 0, 14351, 0, 
+    14356, 14362, 14368, 14374, 14380, 14384, 0, 0, 14387, 14391, 14394, 
+    14397, 14400, 14403, 14406, 14409, 14412, 14415, 0, 0, 14418, 14423, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 14428, 14432, 14443, 14458, 14473, 14483, 
+    14494, 14507, 14518, 14524, 14532, 14542, 14548, 14556, 14560, 14566, 
+    14572, 14580, 14590, 14598, 14611, 14617, 14625, 14633, 14645, 14653, 
+    14661, 14669, 14677, 14685, 14693, 14701, 14711, 14715, 14718, 14721, 
+    14724, 14727, 14730, 14733, 14736, 14739, 14742, 14746, 14750, 14754, 
+    14758, 14762, 14766, 14770, 14774, 14778, 14783, 14789, 14799, 14813, 
+    14823, 14829, 14835, 14843, 14851, 14859, 14867, 14873, 14879, 14882, 
+    14886, 14890, 14894, 14898, 14902, 14906, 0, 14910, 14914, 14918, 14922, 
+    14926, 14930, 14934, 14938, 14942, 14946, 14950, 14954, 14958, 14962, 
+    14966, 14970, 14973, 14977, 14981, 14985, 14989, 14993, 14997, 15001, 
+    15005, 15008, 15012, 15016, 15020, 15024, 15028, 15031, 15034, 15038, 0, 
+    0, 0, 0, 0, 0, 15044, 15049, 15053, 15058, 15062, 15067, 15072, 15078, 
+    15083, 15089, 15093, 15098, 15102, 15107, 15117, 15123, 15128, 15134, 
+    15144, 15150, 15154, 15158, 15164, 15170, 15178, 15184, 15192, 0, 0, 0, 
+    0, 15200, 15204, 15209, 15214, 15219, 15224, 15229, 15234, 0, 15239, 
+    15244, 15249, 15254, 15259, 15264, 15269, 15274, 15279, 15284, 15289, 
+    15294, 15299, 15304, 15309, 15314, 15318, 15323, 15328, 15333, 15338, 
+    15343, 15348, 15353, 15358, 15362, 15367, 15372, 15377, 15382, 15387, 
+    15391, 15395, 15400, 15407, 15413, 0, 15420, 15427, 15440, 15447, 15454, 
+    15462, 15470, 15476, 15482, 15488, 15498, 15504, 15510, 15520, 15530, 0, 
+    0, 15540, 15548, 15560, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 15572, 15575, 15579, 15583, 15587, 15591, 15595, 15599, 
+    15603, 15607, 15611, 15615, 15619, 15623, 15627, 15631, 15635, 15639, 
+    15643, 15647, 15651, 15655, 15659, 15663, 15667, 15671, 15674, 15677, 
+    15681, 15685, 15689, 15693, 15696, 15700, 0, 15703, 15706, 15710, 15713, 
+    15717, 0, 15720, 15723, 0, 15727, 15732, 15736, 15741, 15745, 15750, 
+    15754, 0, 0, 0, 15759, 15763, 15767, 15771, 0, 0, 0, 0, 0, 0, 15775, 
+    15779, 15782, 15785, 15788, 15791, 15794, 15797, 15800, 15803, 15806, 
+    15812, 15816, 15820, 15824, 15828, 15832, 15836, 15840, 15844, 15849, 
+    15853, 15858, 15863, 15869, 15874, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 15880, 15885, 15890, 15895, 15900, 15905, 
+    15910, 15915, 15920, 15925, 15930, 15935, 15940, 15945, 15950, 15955, 
+    15960, 15965, 15970, 15975, 15980, 15985, 15990, 15995, 16000, 16005, 
+    16010, 16015, 16020, 16025, 16030, 16035, 16040, 16045, 16050, 16055, 
+    16060, 16065, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16070, 16074, 16078, 16082, 
+    16086, 16090, 16094, 16098, 16102, 16106, 16110, 16114, 16118, 16122, 
+    16126, 16130, 16134, 16138, 16142, 16146, 16150, 16154, 16158, 16162, 
+    16166, 16170, 16174, 16178, 16182, 16186, 16190, 16194, 16198, 16202, 
+    16206, 16210, 16214, 16218, 16222, 16226, 16230, 16234, 16239, 16243, 
+    16248, 0, 0, 0, 16253, 16257, 16261, 16265, 16269, 16273, 16277, 16281, 
+    16285, 16289, 16293, 16297, 16301, 16305, 16309, 16313, 16317, 16321, 
+    16325, 16329, 16333, 16337, 16341, 16345, 16349, 16353, 16357, 16361, 
+    16365, 16369, 16373, 16377, 16381, 16385, 16389, 16393, 16397, 16401, 
+    16405, 16409, 16413, 16417, 16421, 16425, 16429, 16433, 16437, 16441, 
+    16445, 16449, 16453, 16457, 16461, 16465, 16469, 16473, 16477, 16481, 
+    16485, 16489, 16493, 16497, 16501, 16505, 16509, 16513, 16517, 16521, 
+    16525, 16529, 16533, 16537, 16541, 16545, 16549, 16553, 16557, 16561, 
+    16565, 16569, 16573, 16577, 16581, 16585, 16589, 16593, 16597, 16601, 
+    16605, 16609, 0, 0, 0, 0, 0, 16613, 16617, 16621, 16624, 16628, 16631, 
+    16635, 16639, 16642, 16646, 16650, 16653, 16657, 16661, 16665, 16669, 
+    16672, 16676, 16680, 16684, 16688, 16692, 16696, 16699, 16703, 16707, 
+    16711, 16715, 16719, 16723, 16727, 16731, 16735, 16739, 16743, 16747, 
+    16751, 16755, 16759, 16763, 16767, 16771, 16775, 16779, 16783, 16787, 
+    16791, 16795, 16799, 16803, 16807, 16811, 16815, 16819, 16823, 16827, 
+    16831, 16835, 16839, 16843, 16847, 16851, 16855, 16859, 16863, 16867, 
+    16871, 16875, 0, 0, 0, 0, 0, 16879, 16883, 16887, 16891, 16895, 16899, 
+    16903, 16907, 16911, 16915, 16919, 16923, 16927, 16931, 16935, 16939, 
+    16943, 16947, 16951, 16955, 16959, 16963, 16967, 16971, 16975, 16979, 
+    16983, 16987, 16991, 16995, 16999, 17003, 17007, 17011, 17015, 17019, 
+    17023, 17027, 17031, 17035, 17039, 17043, 17047, 17051, 17055, 17059, 
+    17063, 17067, 17071, 17075, 17079, 17083, 17087, 17091, 17095, 17099, 
+    17103, 17107, 17111, 17115, 17119, 17123, 17127, 17131, 17135, 17139, 
+    17143, 17147, 17151, 17155, 17159, 17163, 17167, 17171, 17175, 17179, 
+    17183, 17187, 17191, 17195, 17199, 17203, 0, 0, 0, 0, 0, 0, 17207, 17210, 
+    17214, 17218, 17222, 17226, 17230, 17234, 17238, 17242, 17246, 17250, 
+    17254, 17258, 17262, 17266, 17270, 17274, 17278, 17282, 17286, 17290, 
+    17294, 17298, 17302, 17305, 17309, 17313, 17317, 17321, 17325, 17329, 
+    17333, 17337, 17341, 17345, 17349, 17353, 17357, 17361, 17365, 17369, 
+    17373, 17377, 17381, 17385, 17389, 17393, 17397, 17401, 17405, 17409, 
+    17413, 17417, 17421, 17425, 17429, 17433, 17437, 17441, 17445, 17449, 
+    17453, 17457, 17461, 17465, 17469, 17473, 17477, 17481, 17485, 17489, 
+    17493, 0, 17497, 17501, 17505, 17509, 0, 0, 17513, 17517, 17521, 17525, 
+    17529, 17533, 17537, 0, 17541, 0, 17545, 17549, 17553, 17557, 0, 0, 
+    17561, 17565, 17569, 17573, 17577, 17581, 17585, 17589, 17593, 17597, 
+    17601, 17605, 17609, 17613, 17617, 17621, 17625, 17629, 17633, 17637, 
+    17641, 17645, 17649, 17652, 17656, 17660, 17664, 17668, 17672, 17676, 
+    17680, 17684, 17688, 17692, 17696, 17700, 17704, 17708, 17712, 17716, 
+    17720, 0, 17724, 17728, 17732, 17736, 0, 0, 17740, 17744, 17748, 17752, 
+    17756, 17760, 17764, 17768, 17772, 17776, 17780, 17784, 17788, 17792, 
+    17796, 17800, 17804, 17809, 17814, 17819, 17825, 17831, 17836, 17841, 
+    17847, 17850, 17854, 17858, 17862, 17866, 17870, 17874, 17878, 0, 17882, 
+    17886, 17890, 17894, 0, 0, 17898, 17902, 17906, 17910, 17914, 17918, 
+    17922, 0, 17926, 0, 17930, 17934, 17938, 17942, 0, 0, 17946, 17950, 
+    17954, 17958, 17962, 17966, 17970, 17974, 17978, 17983, 17988, 17993, 
+    17999, 18005, 18010, 0, 18015, 18019, 18023, 18027, 18031, 18035, 18039, 
+    18043, 18047, 18051, 18055, 18059, 18063, 18067, 18071, 18075, 18079, 
+    18082, 18086, 18090, 18094, 18098, 18102, 18106, 18110, 18114, 18118, 
+    18122, 18126, 18130, 18134, 18138, 18142, 18146, 18150, 18154, 18158, 
+    18162, 18166, 18170, 18174, 18178, 18182, 18186, 18190, 18194, 18198, 
+    18202, 18206, 18210, 18214, 18218, 18222, 18226, 18230, 18234, 18238, 0, 
+    18242, 18246, 18250, 18254, 0, 0, 18258, 18262, 18266, 18270, 18274, 
+    18278, 18282, 18286, 18290, 18294, 18298, 18302, 18306, 18310, 18314, 
+    18318, 18322, 18326, 18330, 18334, 18338, 18342, 18346, 18350, 18354, 
+    18358, 18362, 18366, 18370, 18374, 18378, 18382, 18386, 18390, 18394, 
+    18398, 18402, 18406, 18410, 18414, 18418, 18422, 18426, 18430, 18434, 
+    18438, 18442, 18446, 18450, 18454, 18458, 18462, 18466, 18470, 18474, 
+    18478, 18482, 18486, 18490, 18494, 18498, 18502, 18506, 18510, 18514, 
+    18518, 18522, 0, 0, 0, 0, 18526, 18531, 18535, 18538, 18542, 18545, 
+    18548, 18551, 18556, 18560, 18565, 18568, 18571, 18574, 18577, 18580, 
+    18583, 18586, 18589, 18592, 18596, 18600, 18604, 18608, 18612, 18616, 
+    18620, 18624, 18628, 18632, 0, 0, 0, 18638, 18644, 18648, 18652, 18656, 
+    18662, 18666, 18670, 18674, 18680, 18684, 18688, 18692, 18698, 18702, 
+    18706, 18710, 18716, 18722, 18728, 18736, 18742, 18748, 18754, 18760, 
+    18766, 0, 0, 0, 0, 0, 0, 18772, 18775, 18778, 18781, 18784, 18787, 18790, 
+    18794, 18797, 18801, 18805, 18809, 18813, 18817, 18820, 18824, 18828, 
+    18832, 18836, 18840, 18844, 18848, 18852, 18856, 18860, 18864, 18867, 
+    18871, 18875, 18879, 18883, 18887, 18891, 18895, 18899, 18903, 18907, 
+    18911, 18915, 18919, 18923, 18927, 18931, 18935, 18939, 18943, 18946, 
+    18950, 18954, 18958, 18962, 18966, 18970, 18974, 18978, 18982, 18986, 
+    18990, 18994, 18998, 19002, 19006, 19010, 19014, 19018, 19022, 19026, 
+    19030, 19034, 19038, 19042, 19046, 19050, 19054, 19058, 19062, 19066, 
+    19070, 19074, 19078, 19081, 19085, 19089, 19093, 19097, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 19101, 19104, 19108, 19111, 19115, 19118, 19122, 19128, 
+    19133, 19137, 19140, 19144, 19148, 19153, 19157, 19162, 19166, 19171, 
+    19175, 19180, 19184, 19189, 19195, 19199, 19204, 19208, 19213, 19219, 
+    19223, 19229, 19234, 19238, 19242, 19250, 19258, 19265, 19270, 19275, 
+    19284, 19291, 19298, 19303, 19309, 19313, 19317, 19321, 19325, 19329, 
+    19333, 19337, 19341, 19345, 19349, 19355, 19360, 19365, 19369, 19373, 
+    19377, 19382, 19386, 19391, 19395, 19400, 19404, 19409, 19413, 19418, 
+    19422, 19427, 19431, 19436, 19442, 19445, 19449, 19453, 19457, 19461, 
+    19465, 19469, 19472, 19476, 19482, 19487, 19492, 19496, 19500, 19504, 
+    19509, 19513, 19518, 19522, 19527, 19530, 19534, 19538, 19543, 19547, 
+    19552, 19556, 19561, 19567, 19570, 19574, 19578, 19582, 19586, 19590, 
+    19594, 19598, 19602, 19606, 19610, 19616, 19619, 19623, 19627, 19632, 
+    19636, 19641, 19645, 19650, 19654, 19659, 19663, 19668, 19672, 19677, 
+    19681, 19686, 19692, 19696, 19700, 19706, 19712, 19718, 19724, 19728, 
+    19732, 19736, 19740, 19744, 19748, 19754, 19758, 19762, 19766, 19771, 
+    19775, 19780, 19784, 19789, 19793, 19798, 19802, 19807, 19811, 19816, 
+    19820, 19825, 19831, 19835, 19841, 19845, 19849, 19853, 19857, 19861, 
+    19865, 19871, 19874, 19878, 19882, 19887, 19891, 19896, 19900, 19905, 
+    19909, 19914, 19918, 19923, 19927, 19932, 19936, 19941, 19947, 19950, 
+    19954, 19958, 19963, 19968, 19972, 19976, 19980, 19984, 19988, 19992, 
+    19998, 20002, 20006, 20010, 20015, 20019, 20024, 20028, 20033, 20039, 
+    20042, 20047, 20051, 20055, 20059, 20063, 20067, 20071, 20075, 20081, 
+    20085, 20089, 20093, 20098, 20102, 20107, 20111, 20116, 20120, 20125, 
+    20129, 20134, 20138, 20143, 20147, 20152, 20155, 20159, 20163, 20167, 
+    20171, 20175, 20179, 20183, 20187, 20193, 20197, 20201, 20205, 20210, 
+    20214, 20219, 20223, 20228, 20232, 20237, 20241, 20246, 20250, 20255, 
+    20259, 20264, 20270, 20273, 20278, 20282, 20287, 20293, 20299, 20305, 
+    20311, 20317, 20323, 20329, 20333, 20337, 20341, 20345, 20349, 20353, 
+    20357, 20361, 20366, 20370, 20375, 20379, 20384, 20388, 20393, 20397, 
+    20402, 20406, 20411, 20415, 20420, 20424, 20428, 20432, 20436, 20440, 
+    20444, 20448, 20454, 20457, 20461, 20465, 20470, 20474, 20479, 20483, 
+    20488, 20492, 20497, 20501, 20506, 20510, 20515, 20519, 20524, 20530, 
+    20534, 20540, 20545, 20551, 20555, 20561, 20566, 20570, 20574, 20578, 
+    20582, 20586, 20591, 20595, 20599, 20604, 20608, 20613, 20616, 20620, 
+    20624, 20628, 20632, 20636, 20640, 20644, 20648, 20652, 20656, 20660, 
+    20665, 20669, 20673, 20679, 20683, 20689, 20693, 20699, 20703, 20707, 
+    20711, 20715, 20719, 20724, 20728, 20732, 20736, 20740, 20744, 20748, 
+    20752, 20756, 20760, 20764, 20770, 20776, 20782, 20788, 20794, 20799, 
+    20805, 20810, 20815, 20819, 20823, 20827, 20831, 20835, 20839, 20843, 
+    20847, 20851, 20855, 20859, 20863, 20867, 20872, 20877, 20882, 20887, 
+    20891, 20895, 20899, 20903, 20907, 20911, 20915, 20919, 20923, 20929, 
+    20935, 20941, 20947, 20953, 20959, 20965, 20971, 20977, 20981, 20985, 
+    20989, 20993, 20997, 21001, 21005, 21011, 21017, 21023, 21029, 21035, 
+    21041, 21047, 21053, 21058, 21063, 21068, 21073, 21078, 21084, 21090, 
+    21096, 21102, 21108, 21114, 21120, 21126, 21132, 21138, 21144, 21149, 
+    21155, 21161, 21167, 21172, 21177, 21182, 21187, 21192, 21197, 21202, 
+    21207, 21212, 21217, 21222, 21227, 21232, 21237, 21242, 21247, 21252, 
+    21257, 21262, 21267, 21272, 21277, 21282, 21287, 21292, 21297, 21302, 
+    21307, 21312, 21317, 21322, 21327, 21332, 21337, 21342, 21347, 21352, 
+    21357, 21362, 21367, 21372, 21377, 21382, 21386, 21391, 21396, 21401, 
+    21406, 21411, 21416, 21421, 21426, 21431, 21436, 21441, 21446, 21451, 
+    21456, 21461, 21466, 21471, 21476, 21481, 21486, 21491, 21496, 21501, 
+    21506, 21511, 21516, 21521, 21526, 21531, 21536, 21540, 21545, 21550, 
+    21555, 21560, 21565, 21569, 21574, 21580, 21585, 21590, 21595, 21600, 
+    21606, 21611, 21616, 21621, 21626, 21631, 21636, 21641, 21646, 21651, 
+    21656, 21661, 21666, 21671, 21676, 21681, 21686, 21691, 21696, 21701, 
+    21706, 21711, 21716, 21721, 21726, 21731, 21736, 21741, 21746, 21751, 
+    21756, 21761, 21766, 21771, 21776, 21781, 21786, 21791, 21796, 21801, 
+    21806, 21811, 21816, 21821, 21826, 21832, 21837, 21842, 21847, 21852, 
+    21857, 21862, 21867, 21872, 21877, 21882, 21887, 21892, 21897, 21902, 
+    21907, 21912, 21917, 21922, 21927, 21932, 21937, 21942, 21947, 21952, 
+    21957, 21962, 21967, 21972, 21977, 21982, 21987, 21992, 21997, 22002, 
+    22007, 22012, 22017, 22022, 22027, 22031, 22035, 22039, 22043, 22047, 
+    22051, 22055, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22059, 22064, 22069, 22074, 
+    22079, 22084, 22089, 22094, 22099, 22104, 22109, 22114, 22119, 22124, 
+    22129, 22134, 22139, 22144, 22149, 22154, 22159, 22164, 22169, 22174, 
+    22179, 22184, 22189, 22194, 22199, 0, 0, 0, 22205, 22215, 22218, 22225, 
+    22229, 22233, 22237, 22245, 22249, 22254, 22259, 22264, 22268, 22273, 
+    22278, 22281, 22285, 22289, 22298, 22302, 22306, 22312, 22315, 22319, 
+    22326, 22330, 22338, 22343, 22348, 22353, 22358, 22367, 22372, 22376, 
+    22385, 22388, 22393, 22397, 22403, 22408, 22414, 22421, 22427, 22432, 
+    22439, 22444, 22448, 22452, 22461, 22466, 22469, 22478, 22483, 22487, 
+    22491, 22498, 22505, 22510, 22515, 22524, 22528, 22532, 22536, 22543, 
+    22550, 22554, 22558, 22562, 22566, 22570, 22574, 22578, 22582, 22586, 
+    22590, 22593, 22598, 22603, 22608, 22612, 22616, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 22620, 22624, 22628, 22632, 22636, 22641, 22646, 
+    22651, 22656, 22661, 22666, 22671, 22675, 0, 22679, 22684, 22689, 22694, 
+    22698, 22703, 22708, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22713, 22717, 
+    22721, 22725, 22729, 22734, 22739, 22744, 22749, 22754, 22759, 22764, 
+    22768, 22772, 22777, 22782, 22787, 22792, 22796, 22801, 22806, 22811, 
+    22817, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22822, 22826, 22830, 22834, 22838, 
+    22843, 22848, 22853, 22858, 22863, 22868, 22873, 22877, 22881, 22886, 
+    22891, 22896, 22901, 22905, 22910, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    22915, 22919, 22923, 22927, 22931, 22936, 22941, 22946, 22951, 22956, 
+    22961, 22966, 22970, 0, 22974, 22979, 22984, 0, 22989, 22994, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 22999, 23002, 23006, 23010, 23014, 23018, 23022, 
+    23026, 23030, 23034, 23038, 23042, 23046, 23050, 23054, 23058, 23062, 
+    23066, 23069, 23073, 23077, 23081, 23085, 23089, 23093, 23097, 23101, 
+    23105, 23109, 23113, 23117, 23121, 23125, 23128, 23132, 23136, 23142, 
+    23148, 23154, 23160, 23166, 23172, 23178, 23184, 23190, 23196, 23202, 
+    23208, 23214, 23220, 23229, 23238, 23244, 23250, 23256, 23261, 23265, 
+    23270, 23275, 23280, 23284, 23289, 23294, 23299, 23303, 23308, 23312, 
+    23317, 23322, 23327, 23332, 23336, 23340, 23344, 23348, 23352, 23356, 
+    23360, 23364, 23368, 23372, 23378, 23382, 23386, 23390, 23394, 23398, 
+    23406, 23412, 23416, 23422, 23426, 23432, 23436, 0, 0, 23440, 23444, 
+    23447, 23450, 23453, 23456, 23459, 23462, 23465, 23468, 0, 0, 0, 0, 0, 0, 
+    23471, 23479, 23487, 23495, 23503, 23511, 23519, 23527, 23535, 23543, 0, 
+    0, 0, 0, 0, 0, 23551, 23554, 23557, 23560, 23564, 23567, 23572, 23579, 
+    23587, 23592, 23598, 23601, 23608, 23615, 23622, 0, 23626, 23630, 23633, 
+    23636, 23639, 23642, 23645, 23648, 23651, 23654, 0, 0, 0, 0, 0, 0, 23657, 
+    23660, 23663, 23666, 23669, 23672, 23676, 23680, 23684, 23688, 23692, 
+    23696, 23700, 23704, 23708, 23711, 23715, 23719, 23723, 23727, 23731, 
+    23735, 23739, 23742, 23746, 23750, 23754, 23757, 23761, 23765, 23769, 
+    23773, 23777, 23781, 23785, 23789, 23796, 23801, 23806, 23811, 23816, 
+    23822, 23828, 23834, 23840, 23846, 23852, 23858, 23863, 23869, 23875, 
+    23881, 23887, 23893, 23898, 23904, 23909, 23915, 23921, 23927, 23933, 
+    23939, 23944, 23949, 23955, 23961, 23966, 23972, 23977, 23983, 23988, 
+    23994, 24000, 24006, 24012, 24018, 24024, 24030, 24036, 24042, 24048, 
+    24054, 24060, 24066, 24071, 24076, 24082, 24088, 0, 0, 0, 0, 0, 0, 0, 0, 
+    24094, 24103, 24112, 24120, 24128, 24138, 24146, 24155, 24162, 24169, 
+    24176, 24184, 24192, 24200, 24208, 24216, 24224, 24232, 24240, 24248, 
+    24256, 24264, 24272, 24280, 24288, 24298, 24308, 24318, 24328, 24338, 
+    24348, 24358, 24368, 24378, 24388, 24398, 24408, 24418, 24428, 24436, 
+    24444, 24454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24462, 24467, 
+    24470, 24474, 24478, 24482, 24486, 24490, 24494, 24498, 24502, 24506, 
+    24510, 24514, 24518, 24522, 24526, 24530, 24534, 24538, 24542, 24545, 
+    24548, 24552, 24556, 24560, 24564, 24568, 24572, 0, 0, 0, 24575, 24579, 
+    24583, 24587, 24592, 24597, 24602, 24607, 24611, 24615, 24619, 24624, 0, 
+    0, 0, 0, 24629, 24633, 24638, 24643, 24648, 24653, 24658, 24662, 24667, 
+    24672, 24676, 24680, 0, 0, 0, 0, 24684, 0, 0, 0, 24688, 24692, 24696, 
+    24700, 24703, 24706, 24709, 24712, 24715, 24718, 24721, 24724, 24727, 
+    24732, 24738, 24744, 24750, 24756, 24761, 24767, 24773, 24779, 24785, 
+    24791, 24796, 24802, 24808, 24813, 24819, 24825, 24831, 24837, 24842, 
+    24847, 24853, 24859, 24864, 24870, 24875, 24881, 24886, 24892, 0, 0, 
+    24898, 24904, 24910, 24916, 24922, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    24928, 24935, 24942, 24948, 24955, 24962, 24968, 24975, 24982, 24989, 
+    24996, 25002, 25009, 25016, 25022, 25029, 25036, 25043, 25050, 25057, 
+    25064, 25071, 25078, 25084, 25091, 25098, 25104, 25111, 25118, 25125, 
+    25132, 25139, 25146, 25152, 25159, 25166, 25172, 25179, 25186, 25193, 
+    25200, 25207, 0, 0, 0, 0, 0, 0, 25214, 25222, 25229, 25236, 25242, 25249, 
+    25255, 25262, 25268, 25275, 25282, 25289, 25296, 25303, 25310, 25317, 
+    25324, 25331, 25337, 25344, 25350, 25356, 25363, 25369, 25375, 25381, 0, 
+    0, 0, 0, 0, 0, 25387, 25393, 25398, 25403, 25408, 25413, 25418, 25423, 
+    25428, 25433, 0, 0, 0, 0, 25438, 25444, 25450, 25454, 25460, 25466, 
+    25472, 25478, 25484, 25490, 25496, 25502, 25508, 25514, 25520, 25526, 
+    25532, 25538, 25544, 25548, 25554, 25560, 25566, 25572, 25578, 25584, 
+    25590, 25596, 25602, 25608, 25614, 25620, 25626, 25632, 25638, 25642, 
+    25647, 25652, 25657, 25662, 25667, 25671, 25676, 25681, 25686, 25691, 
+    25696, 25701, 25706, 25711, 25716, 25720, 25725, 25730, 25735, 25740, 
+    25744, 25748, 25753, 25758, 25763, 25768, 0, 0, 25774, 25778, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25785, 25790, 
+    25796, 25802, 25809, 25815, 25820, 25826, 25831, 25838, 25843, 25848, 
+    25854, 25862, 25867, 25873, 25878, 25885, 25891, 25899, 25907, 25913, 
+    25919, 25926, 25933, 25938, 25944, 25950, 25955, 25960, 25966, 25974, 
+    25981, 25986, 25992, 25998, 26004, 26012, 26016, 26022, 26028, 26034, 
+    26040, 26046, 26052, 26056, 26061, 26065, 26071, 26075, 26079, 26084, 
+    26088, 26092, 26096, 26100, 26105, 26109, 26113, 26117, 26122, 26126, 
+    26131, 26135, 26139, 26143, 26147, 26152, 26156, 26161, 26166, 26172, 
+    26176, 26180, 26184, 26189, 26195, 26202, 26206, 26211, 26216, 26220, 
+    26225, 26229, 26235, 26242, 26249, 26253, 26257, 26261, 26267, 26272, 
+    26276, 26281, 26286, 26292, 26297, 26303, 26308, 26314, 26320, 26326, 
+    26332, 26339, 26346, 26353, 26360, 26367, 26372, 26380, 26389, 26398, 
+    26407, 26416, 26425, 26434, 26446, 26455, 26464, 26473, 26478, 26483, 
+    26489, 26497, 26504, 26511, 26518, 26525, 26532, 26540, 26549, 26558, 
+    26567, 26576, 26585, 26594, 26603, 26612, 26621, 26630, 26639, 26648, 
+    26657, 26666, 26674, 26682, 26693, 26701, 26711, 26722, 26731, 26739, 
+    26749, 26758, 26766, 26775, 26781, 26786, 26794, 26799, 26806, 26811, 
+    26820, 26825, 26830, 26836, 26841, 26846, 26853, 26861, 26870, 26879, 
+    26884, 26891, 26901, 26909, 26918, 26923, 26929, 26934, 26941, 26946, 
+    26955, 26960, 26965, 26970, 26977, 26982, 26987, 26996, 27004, 27009, 
+    27014, 27021, 27028, 27032, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27036, 
+    27044, 27052, 27059, 27066, 27073, 27080, 27088, 27096, 27106, 27116, 
+    27124, 27132, 27140, 27148, 27157, 27166, 27174, 27182, 27190, 27198, 
+    27207, 27216, 27225, 27234, 27241, 27248, 27256, 27264, 27274, 27284, 
+    27292, 27300, 27307, 27314, 27322, 27330, 27338, 27346, 27353, 27360, 
+    27368, 27376, 27385, 27394, 27402, 27410, 27419, 27428, 27435, 27442, 
+    27450, 27458, 27467, 27476, 27484, 27492, 27503, 27514, 27523, 27532, 
+    27540, 27548, 27555, 27562, 27570, 27578, 27586, 27594, 27602, 27610, 
+    27618, 27626, 27635, 27644, 27652, 27660, 27669, 27678, 27687, 27696, 
+    27705, 27714, 27723, 27732, 27739, 27746, 27754, 27762, 27770, 27778, 
+    27786, 27794, 27805, 27816, 27825, 27834, 27842, 27850, 27858, 27866, 
+    27877, 27888, 27899, 27910, 27922, 27934, 27942, 27950, 27958, 27966, 
+    27975, 27984, 27992, 28000, 28008, 28016, 28024, 28032, 28039, 28046, 
+    28055, 28064, 28073, 28082, 28089, 28096, 28104, 28112, 28119, 28126, 
+    28133, 28140, 28147, 28154, 28162, 28170, 28178, 28186, 28194, 28202, 
+    28209, 28216, 28224, 28232, 28240, 28248, 28256, 28264, 28273, 28282, 
+    28291, 28298, 28307, 28316, 28325, 0, 0, 0, 0, 28334, 28341, 28348, 
+    28356, 28364, 28372, 28380, 28388, 28396, 28406, 28416, 28424, 28432, 
+    28441, 28450, 28459, 28468, 28477, 28486, 28497, 28508, 28517, 28526, 
+    28536, 28546, 28553, 28560, 28568, 28576, 28582, 28588, 28596, 28604, 
+    28612, 28620, 28630, 28640, 28648, 28656, 28665, 28674, 28682, 28690, 
+    28697, 28704, 28711, 28718, 28726, 28734, 28742, 28750, 28758, 28766, 
+    28776, 28786, 28794, 28802, 28811, 28820, 28829, 28838, 28847, 28856, 
+    28867, 28878, 28887, 28896, 28906, 28916, 28923, 28930, 28938, 28946, 
+    28955, 28964, 28973, 28982, 28993, 29004, 29013, 29022, 29032, 29042, 
+    29049, 29056, 29064, 29072, 29081, 29090, 29097, 0, 0, 0, 0, 0, 0, 29104, 
+    29111, 29118, 29126, 29134, 29142, 29150, 29159, 29168, 29175, 29182, 
+    29190, 29198, 29206, 29214, 29223, 29232, 29240, 29248, 29257, 29266, 
+    29275, 0, 0, 29284, 29292, 29300, 29309, 29318, 29327, 0, 0, 29336, 
+    29344, 29352, 29361, 29370, 29379, 29388, 29398, 29408, 29416, 29424, 
+    29433, 29442, 29451, 29460, 29470, 29480, 29488, 29496, 29505, 29514, 
+    29523, 29532, 29542, 29552, 29560, 29568, 29577, 29586, 29595, 29604, 
+    29614, 29624, 29632, 29640, 29649, 29658, 29667, 0, 0, 29676, 29684, 
+    29692, 29701, 29710, 29719, 0, 0, 29728, 29736, 29744, 29753, 29762, 
+    29771, 29780, 29790, 0, 29800, 0, 29808, 0, 29817, 0, 29826, 29836, 
+    29843, 29850, 29858, 29866, 29874, 29882, 29891, 29900, 29907, 29914, 
+    29922, 29930, 29938, 29946, 29955, 29964, 29970, 29976, 29983, 29990, 
+    29997, 30004, 30011, 30018, 30025, 30032, 30039, 30046, 30052, 0, 0, 
+    30058, 30067, 30076, 30088, 30100, 30112, 30124, 30136, 30148, 30157, 
+    30166, 30178, 30190, 30202, 30214, 30226, 30238, 30248, 30258, 30271, 
+    30284, 30297, 30310, 30323, 30336, 30346, 30356, 30369, 30382, 30395, 
+    30408, 30421, 30434, 30443, 30452, 30464, 30476, 30488, 30500, 30512, 
+    30524, 30533, 30542, 30554, 30566, 30578, 30590, 30602, 30614, 30621, 
+    30627, 30637, 30644, 0, 30654, 30661, 30671, 30678, 30684, 30690, 30696, 
+    30703, 30706, 30709, 30712, 30715, 30721, 30732, 30740, 0, 30751, 30759, 
+    30770, 30777, 30784, 30791, 30798, 30806, 30810, 30814, 30819, 30827, 
+    30834, 30844, 0, 0, 30854, 30862, 30873, 30881, 30888, 30895, 0, 30902, 
+    30906, 30910, 30915, 30923, 30930, 30940, 30950, 30958, 30966, 30974, 
+    30985, 30993, 31000, 31007, 31014, 31022, 31027, 31032, 0, 0, 31034, 
+    31044, 31051, 0, 31061, 31068, 31078, 31085, 31092, 31098, 31104, 31111, 
+    31113, 0, 31116, 31120, 31124, 31128, 31132, 31136, 31140, 31144, 31148, 
+    31152, 31156, 31160, 31166, 31172, 31178, 31181, 31184, 31186, 31190, 
+    31194, 31198, 31202, 31204, 31208, 31212, 31218, 31224, 31231, 31238, 
+    31243, 31248, 31254, 31260, 31262, 31265, 31267, 31271, 31276, 31280, 
+    31283, 31287, 31291, 31295, 31299, 31303, 31309, 31313, 31317, 31323, 
+    31328, 31335, 31337, 31340, 31344, 31347, 31351, 31356, 31358, 31366, 
+    31374, 31377, 31381, 31383, 31385, 31387, 31390, 31396, 31398, 31402, 
+    31406, 31413, 31420, 31424, 31429, 31434, 31439, 31443, 31447, 31451, 
+    31454, 31457, 31461, 31468, 31473, 31477, 31481, 31486, 31490, 31494, 
+    31499, 31504, 31508, 31512, 31516, 31518, 31523, 31528, 31532, 31536, 
+    31540, 0, 0, 0, 0, 0, 0, 31544, 31550, 31556, 31563, 31570, 31575, 31580, 
+    31584, 0, 0, 31590, 31593, 31596, 31599, 31602, 31605, 31608, 31613, 
+    31617, 31622, 31627, 31632, 31638, 31642, 31645, 31648, 31651, 31654, 
+    31657, 31660, 31663, 31666, 31669, 31674, 31678, 31683, 31688, 0, 31693, 
+    31699, 31705, 31711, 31717, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31724, 
+    31727, 31730, 31733, 31738, 31741, 31744, 31747, 31750, 31753, 31756, 
+    31760, 31763, 31766, 31769, 31772, 31775, 31780, 31783, 31786, 31789, 
+    31792, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 31795, 31799, 31803, 31810, 31818, 31823, 31828, 31832, 
+    31836, 31841, 31848, 31855, 31859, 31864, 31869, 31874, 31879, 31885, 
+    31890, 31895, 31900, 31909, 31916, 31923, 31927, 31932, 31938, 31943, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31950, 31954, 
+    31961, 31965, 31969, 31974, 31978, 31982, 31986, 31988, 31992, 31995, 
+    31998, 32002, 32005, 32009, 32018, 32021, 32025, 32028, 32031, 32037, 
+    32040, 32043, 32049, 32052, 32055, 32059, 32062, 32066, 32069, 32073, 
+    32075, 32078, 32081, 32085, 32087, 32091, 32094, 32097, 32102, 32107, 
+    32113, 32116, 32119, 32122, 32127, 32130, 32133, 32136, 32140, 32144, 
+    32147, 32150, 32152, 32155, 32158, 32161, 32165, 32170, 32173, 32177, 
+    32181, 32185, 32189, 32194, 32198, 32202, 32206, 32211, 32215, 32219, 
+    32223, 32227, 32231, 32235, 32238, 0, 0, 0, 0, 0, 0, 32241, 32249, 32256, 
+    32264, 32271, 32278, 32286, 32294, 32302, 32310, 32317, 32325, 32333, 
+    32338, 32342, 32346, 32350, 32354, 32358, 32362, 32366, 32370, 32374, 
+    32379, 32384, 32389, 32394, 32401, 32408, 32415, 32420, 32425, 32430, 
+    32435, 32440, 32445, 32450, 32455, 32460, 32466, 32472, 32478, 32484, 
+    32492, 32500, 32508, 32518, 32525, 32532, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 32540, 32542, 32545, 32547, 32550, 32553, 32556, 32561, 32566, 
+    32571, 32576, 32580, 32584, 32588, 32592, 32597, 32603, 32608, 32614, 
+    32619, 32624, 32629, 32635, 32640, 32646, 32652, 32656, 32660, 32665, 
+    32670, 32675, 32680, 32685, 32693, 32701, 32709, 32717, 32724, 32732, 
+    32739, 32746, 32754, 32765, 32771, 32777, 32783, 32789, 32796, 32803, 
+    32809, 32815, 32822, 32829, 32835, 32843, 32849, 32854, 32860, 32865, 
+    32871, 32878, 32885, 32890, 32896, 32901, 32904, 32908, 32911, 32915, 
+    32919, 32923, 32929, 32935, 32941, 32947, 32951, 32955, 32959, 32963, 
+    32969, 32975, 32979, 32984, 32988, 32993, 32997, 33001, 33004, 33008, 
+    33011, 33015, 33022, 33030, 33041, 33052, 33057, 33066, 33073, 33081, 
+    33089, 33093, 33099, 33107, 33111, 33116, 33121, 33127, 33133, 33139, 
+    33146, 33150, 33154, 33159, 33162, 33164, 33168, 33172, 33179, 33183, 
+    33185, 33187, 33191, 33198, 33203, 33209, 33218, 33225, 33230, 33234, 
+    33238, 33242, 33245, 33248, 33251, 33255, 33259, 33263, 33267, 33271, 
+    33274, 33278, 33282, 33285, 33287, 33290, 33292, 33296, 33300, 33302, 
+    33307, 33310, 33314, 33318, 33322, 33324, 33326, 33328, 33331, 33335, 
+    33339, 33343, 33347, 33351, 33357, 33363, 33365, 33367, 33369, 33371, 
+    33374, 33376, 33380, 33382, 33386, 33388, 33393, 33397, 33401, 33403, 
+    33406, 33410, 33415, 33419, 33428, 33438, 33442, 33447, 33453, 33456, 
+    33460, 33463, 33468, 33472, 33478, 33482, 33493, 33501, 33505, 33509, 
+    33515, 33519, 33522, 33524, 33527, 33531, 33535, 33541, 33545, 33549, 
+    33552, 33555, 33559, 33564, 33569, 33574, 33580, 33586, 33593, 33600, 
+    33604, 33608, 33610, 33614, 33617, 33620, 33628, 33636, 33642, 33648, 
+    33657, 33666, 33671, 33676, 33684, 33692, 33694, 33696, 33701, 33706, 
+    33712, 33718, 33723, 33728, 33732, 33736, 33742, 33748, 33754, 33760, 
+    33770, 33780, 33787, 33794, 33796, 33800, 33804, 33809, 33814, 33821, 
+    33828, 33831, 33834, 33837, 33840, 33843, 33848, 33852, 33857, 33862, 
+    33865, 33868, 33872, 33876, 33880, 33885, 33888, 33891, 33894, 33897, 
+    33899, 33901, 33903, 33905, 33913, 33921, 33926, 33929, 33934, 33944, 
+    33950, 33956, 33962, 33970, 33978, 33989, 33993, 33997, 33999, 34005, 
+    34007, 34009, 34011, 34013, 34018, 34021, 34027, 34033, 34037, 34041, 
+    34045, 34048, 34052, 34056, 34058, 34067, 34076, 34081, 34086, 34091, 
+    34097, 34103, 34106, 34109, 34112, 34115, 34117, 34122, 34127, 34132, 
+    34138, 34144, 34151, 34158, 34163, 34168, 34173, 34178, 34186, 34194, 
+    34202, 34210, 34218, 34226, 34234, 34242, 34250, 34258, 34265, 34276, 
+    34285, 34299, 34302, 34307, 34313, 34319, 34326, 34340, 34355, 34361, 
+    34367, 34374, 34380, 34388, 34394, 34407, 34421, 34426, 34432, 34439, 
+    34442, 34445, 34447, 34450, 34453, 34455, 34457, 34461, 34464, 34467, 
+    34470, 34473, 34478, 34483, 34488, 34493, 34496, 34499, 34501, 34503, 
+    34505, 34509, 34513, 34517, 34523, 34526, 34528, 34530, 34535, 34540, 
+    34545, 34550, 34555, 34560, 34562, 34564, 34573, 34577, 34583, 34592, 
+    34594, 34598, 34602, 34609, 34613, 34615, 34619, 34621, 34625, 34629, 
+    34633, 34635, 34637, 34639, 34644, 34651, 34658, 34665, 34672, 34679, 
+    34686, 34692, 34698, 34704, 34710, 34717, 34724, 34731, 34738, 34744, 
+    34750, 34757, 34764, 34770, 34778, 34785, 34793, 34800, 34808, 34815, 
+    34823, 34831, 34838, 34846, 34853, 34861, 34868, 34876, 34883, 34890, 
+    34897, 34904, 34910, 34918, 34925, 34931, 34938, 34945, 34951, 34957, 
+    34963, 34968, 34976, 34984, 34990, 34996, 35002, 35008, 35013, 35019, 
+    35026, 35034, 35041, 35048, 35055, 35060, 35065, 35070, 35076, 35083, 
+    35090, 35096, 35101, 35105, 35113, 35119, 35122, 35130, 35133, 35138, 
+    35143, 35146, 35149, 35157, 35160, 35165, 35168, 35175, 35180, 35187, 
+    35190, 35193, 35196, 35201, 35206, 35209, 35212, 35220, 35223, 35228, 
+    35235, 35239, 35243, 35248, 35253, 35258, 35263, 35268, 35273, 35278, 
+    35283, 35290, 35296, 35303, 35310, 35316, 35323, 35330, 35339, 35346, 
+    35352, 35359, 35368, 35375, 35379, 35384, 35395, 35406, 35410, 35414, 
+    35418, 35422, 35433, 35437, 35442, 35447, 35452, 35457, 35462, 35467, 
+    35476, 35485, 35493, 35503, 35513, 35521, 35531, 35541, 35549, 35559, 
+    35569, 35577, 35585, 35595, 35605, 35608, 35611, 35614, 35619, 35623, 
+    35630, 35638, 35646, 35655, 35662, 35666, 35670, 35674, 35678, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 35680, 35684, 35691, 35698, 35705, 35712, 
+    35716, 35720, 35724, 35728, 35733, 35739, 35744, 35750, 35756, 35762, 
+    35768, 35776, 35783, 35790, 35797, 35804, 35810, 35816, 35825, 35829, 
+    35836, 35840, 35844, 35850, 35856, 35862, 35868, 35872, 35876, 35879, 
+    35883, 35887, 35894, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 35901, 35904, 35908, 35912, 35918, 35924, 35930, 
+    35938, 35945, 35949, 35957, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 35962, 35965, 35968, 35971, 35974, 35977, 35980, 35983, 
+    35986, 35989, 35993, 35997, 36001, 36005, 36009, 36013, 36017, 36021, 
+    36025, 36029, 36033, 36036, 36039, 36042, 36045, 36048, 36051, 36054, 
+    36057, 36060, 36064, 36068, 36072, 36076, 36080, 36084, 36088, 36092, 
+    36096, 36100, 36104, 36110, 36115, 36120, 36126, 36132, 36138, 36144, 
+    36150, 36156, 36162, 36168, 36174, 36180, 36186, 36192, 36198, 36204, 
+    36210, 36216, 36222, 36227, 36232, 36238, 36243, 36248, 36254, 36259, 
+    36264, 36269, 36274, 36280, 36285, 36290, 36295, 36300, 36305, 36311, 
+    36316, 36321, 36326, 36331, 36336, 36342, 36347, 36353, 36359, 36364, 
+    36369, 36375, 36380, 36385, 36391, 36396, 36401, 36406, 36411, 36417, 
+    36422, 36427, 36432, 36437, 36442, 36448, 36453, 36458, 36463, 36468, 
+    36473, 36479, 36484, 36490, 36496, 36501, 36506, 36512, 36517, 36522, 
+    36528, 36533, 36538, 36543, 36548, 36554, 36559, 36564, 36569, 36574, 
+    36579, 36585, 36590, 36595, 36600, 36605, 36610, 36616, 36621, 36627, 
+    36633, 36637, 36643, 36649, 36655, 36661, 36667, 36673, 36679, 36685, 
+    36691, 36697, 36701, 36705, 36709, 36713, 36717, 36721, 36725, 36729, 
+    36733, 36738, 36744, 36749, 36754, 36759, 36764, 36773, 36782, 36791, 
+    36800, 36809, 36818, 36827, 36836, 36842, 36850, 36858, 36864, 36871, 
+    36879, 36887, 36894, 36900, 36908, 36916, 36922, 36929, 36937, 36945, 
+    36952, 36958, 36966, 36975, 36984, 36992, 37001, 37010, 37016, 37023, 
+    37031, 37040, 37049, 37057, 37066, 37075, 37082, 37089, 37098, 37107, 
+    37115, 37123, 37132, 37141, 37148, 37155, 37164, 37173, 37181, 37189, 
+    37198, 37207, 37214, 37221, 37230, 37239, 37247, 37256, 37265, 37273, 
+    37283, 37293, 37303, 37313, 37322, 37331, 37340, 37349, 37356, 37364, 
+    37372, 37380, 37388, 37393, 37398, 37407, 37415, 37421, 37430, 37438, 
+    37445, 37454, 37462, 37468, 37477, 37485, 37492, 37501, 37509, 37515, 
+    37524, 37532, 37539, 37548, 37556, 37563, 37572, 37580, 37587, 37596, 
+    37604, 37611, 37619, 37628, 37637, 37645, 37656, 37666, 37673, 37678, 
+    37683, 37687, 37692, 37697, 37702, 37706, 37711, 37718, 37726, 37733, 
+    37741, 37745, 37752, 37759, 37765, 37769, 37776, 37782, 37789, 37793, 
+    37800, 37806, 37813, 37817, 37823, 37830, 37837, 37841, 37844, 37848, 
+    37852, 37859, 37866, 37871, 37875, 37880, 37890, 37897, 37908, 37918, 
+    37922, 37930, 37940, 37943, 37946, 37953, 37961, 37966, 37971, 37979, 
+    37988, 37997, 38005, 38009, 38013, 38016, 38019, 38023, 38027, 38030, 
+    38033, 38038, 38043, 38049, 38055, 38060, 38065, 38071, 38077, 38082, 
+    38087, 38092, 38097, 38103, 38109, 38114, 38119, 38125, 38131, 38136, 
+    38141, 38144, 38147, 38156, 38158, 38160, 38163, 38167, 38172, 38174, 
+    38177, 38183, 38189, 38195, 38201, 38209, 38221, 38226, 38231, 38235, 
+    38240, 38247, 38254, 38262, 38270, 38278, 38286, 38290, 38294, 38299, 
+    38304, 38309, 38314, 38317, 38323, 38329, 38338, 38347, 38355, 38363, 
+    38372, 38381, 38385, 38392, 38399, 38406, 38413, 38420, 38427, 38434, 
+    38441, 38445, 38449, 38453, 38458, 38463, 38469, 38475, 38479, 38485, 
+    38487, 38489, 38491, 38493, 38496, 38499, 38501, 38503, 38505, 38509, 
+    38513, 38515, 38517, 38520, 38523, 38527, 38533, 38538, 38540, 38547, 
+    38551, 38556, 38561, 38563, 38572, 38578, 38584, 38590, 38596, 38602, 
+    38608, 38613, 38616, 38619, 38622, 38624, 38626, 38630, 38634, 38639, 
+    38644, 38649, 38652, 38656, 38661, 38664, 38668, 38673, 38678, 38683, 
+    38688, 38693, 38698, 38703, 38708, 38713, 38718, 38723, 38728, 38734, 
+    38740, 38746, 38748, 38751, 38753, 38756, 38758, 38760, 38762, 38764, 
+    38766, 38768, 38770, 38772, 38774, 38776, 38778, 38780, 38782, 38784, 
+    38786, 38788, 38790, 38795, 38800, 38805, 38810, 38815, 38820, 38825, 
+    38830, 38835, 38840, 38845, 38850, 38855, 38860, 38865, 38870, 38875, 
+    38880, 38885, 38890, 38894, 38898, 38902, 38908, 38914, 38919, 38924, 
+    38929, 38934, 38939, 38944, 38952, 38960, 38968, 38976, 38984, 38992, 
+    39000, 39008, 39014, 39019, 39024, 39029, 39032, 39036, 39040, 39044, 
+    39048, 39052, 39056, 39061, 39067, 39073, 39080, 39085, 39090, 39097, 
+    39104, 39111, 39118, 39121, 39124, 39129, 39131, 39135, 39140, 39142, 
+    39144, 39146, 39148, 39153, 39156, 0, 0, 0, 39158, 39161, 39165, 39170, 
+    39175, 39183, 39189, 39195, 39207, 39214, 39221, 39226, 39231, 39237, 
+    39240, 39243, 39248, 39250, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39254, 39259, 39262, 
+    39267, 0, 39270, 39275, 39279, 39281, 0, 0, 39283, 39287, 39291, 39295, 
+    39297, 39301, 39304, 39307, 39310, 39314, 39317, 39321, 39324, 39328, 
+    39333, 39337, 39343, 39350, 39353, 39359, 39364, 39368, 39373, 39379, 
+    39385, 39392, 39398, 39405, 0, 39412, 39419, 39423, 39430, 39436, 39441, 
+    39447, 39451, 39456, 39459, 39465, 39471, 39478, 39486, 39493, 39502, 
+    39512, 39519, 39525, 39529, 39537, 39542, 39551, 39554, 39557, 39566, 
+    39577, 39584, 39586, 39592, 39597, 39599, 39602, 39606, 39614, 0, 39623, 
+    0, 39628, 39635, 39642, 39649, 0, 0, 0, 39656, 0, 39663, 39666, 39670, 
+    39673, 39684, 39694, 39704, 0, 0, 39713, 39722, 39728, 39736, 39740, 
+    39748, 39752, 39760, 39767, 39774, 39783, 39792, 39801, 39810, 39819, 
+    39828, 39836, 39844, 39854, 39864, 39873, 39882, 39889, 39896, 39903, 
+    39910, 39917, 39924, 39931, 39938, 39945, 39953, 39959, 39965, 39971, 
+    39977, 39983, 39989, 39995, 40001, 40007, 40014, 40022, 40030, 40038, 
+    40046, 40054, 40062, 40070, 40078, 40086, 40095, 0, 0, 0, 40100, 40106, 
+    40109, 40115, 40121, 40126, 40130, 40135, 40141, 40148, 40151, 40158, 
+    40165, 40169, 40178, 40187, 40192, 40198, 40203, 40208, 40215, 40222, 
+    40229, 40236, 0, 40244, 40252, 40257, 40261, 40268, 40272, 40279, 40287, 
+    40292, 40300, 40304, 40309, 40313, 40318, 0, 40322, 40327, 40336, 40338, 
+    40342, 40346, 40353, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40360, 40368, 40372, 
+    40379, 40386, 40393, 40398, 40403, 40409, 40414, 40419, 40425, 40430, 
+    40433, 40437, 40441, 40447, 40456, 40461, 40470, 40479, 40485, 40491, 
+    40496, 40501, 40505, 40509, 40514, 0, 0, 0, 0, 40519, 40524, 40529, 
+    40535, 40541, 40547, 40550, 40553, 40557, 40561, 40565, 40570, 40576, 
+    40582, 40589, 40596, 40601, 40605, 40609, 40613, 40617, 40621, 40625, 
+    40629, 40633, 40637, 40641, 40645, 40649, 40653, 40657, 40661, 40665, 
+    40669, 40673, 40677, 40681, 40685, 40689, 40693, 40697, 40701, 40705, 
+    40709, 40713, 40717, 40721, 40725, 40729, 40733, 40737, 40741, 40745, 
+    40749, 40753, 40757, 40761, 40765, 40769, 40773, 40777, 40781, 40785, 
+    40789, 40793, 40797, 40801, 40805, 40809, 40813, 40817, 40821, 40825, 
+    40829, 40833, 40837, 40841, 40845, 40849, 40853, 40857, 40861, 40865, 
+    40869, 40873, 40877, 40881, 40885, 40889, 40893, 40897, 40901, 40905, 
+    40909, 40913, 40917, 40921, 40925, 40929, 40933, 40937, 40941, 40945, 
+    40949, 40953, 40957, 40961, 40965, 40969, 40973, 40977, 40981, 40985, 
+    40989, 40993, 40997, 41001, 41005, 41009, 41013, 41017, 41021, 41025, 
+    41029, 41033, 41037, 41041, 41045, 41049, 41053, 41057, 41061, 41065, 
+    41069, 41073, 41077, 41081, 41085, 41089, 41093, 41097, 41101, 41105, 
+    41109, 41113, 41117, 41121, 41125, 41129, 41133, 41137, 41141, 41145, 
+    41149, 41153, 41157, 41161, 41165, 41169, 41173, 41177, 41181, 41185, 
+    41189, 41193, 41197, 41201, 41205, 41209, 41213, 41217, 41221, 41225, 
+    41229, 41233, 41237, 41241, 41245, 41249, 41253, 41257, 41261, 41265, 
+    41269, 41273, 41277, 41281, 41285, 41289, 41293, 41297, 41301, 41305, 
+    41309, 41313, 41317, 41321, 41325, 41329, 41333, 41337, 41341, 41345, 
+    41349, 41353, 41357, 41361, 41365, 41369, 41373, 41377, 41381, 41385, 
+    41389, 41393, 41397, 41401, 41405, 41409, 41413, 41417, 41421, 41425, 
+    41429, 41433, 41437, 41441, 41445, 41449, 41453, 41457, 41461, 41465, 
+    41469, 41473, 41477, 41481, 41485, 41489, 41493, 41497, 41501, 41505, 
+    41509, 41513, 41517, 41521, 41525, 41529, 41533, 41537, 41541, 41545, 
+    41549, 41553, 41557, 41561, 41565, 41569, 41573, 41577, 41581, 41585, 
+    41589, 41593, 41597, 41601, 41605, 41609, 41613, 41617, 41621, 41625, 
+    41632, 41640, 41646, 41652, 41659, 41666, 41672, 41678, 41684, 41690, 
+    41695, 41700, 41705, 41710, 41716, 41722, 41730, 41737, 41742, 41747, 
+    41755, 41764, 41771, 41781, 41792, 41795, 41798, 41802, 41806, 41812, 
+    41818, 41828, 41838, 41848, 41858, 41865, 41872, 41879, 41886, 41897, 
+    41908, 41919, 41930, 41940, 41950, 41962, 41974, 41985, 41996, 42008, 
+    42020, 42028, 42038, 42048, 42059, 42070, 42077, 42084, 42091, 42098, 
+    42108, 42118, 42125, 42132, 42138, 42144, 42151, 42158, 42165, 42171, 
+    42177, 42182, 42190, 42200, 42208, 42216, 42224, 42232, 42240, 42248, 
+    42256, 42264, 42271, 42278, 42286, 42294, 42301, 42308, 42316, 42324, 
+    42332, 42340, 42349, 42358, 42366, 42374, 42383, 42392, 42404, 42418, 
+    42430, 42444, 42456, 42468, 42480, 42492, 42501, 42511, 42520, 42530, 
+    42544, 42558, 42566, 42572, 42579, 42586, 42593, 42600, 42605, 42611, 
+    42616, 42621, 42627, 42632, 42637, 42642, 42647, 42652, 42659, 42664, 
+    42671, 42676, 42681, 42685, 42689, 42696, 42703, 42710, 42717, 42724, 
+    42731, 42744, 42757, 42770, 42783, 42790, 42797, 42803, 42809, 42816, 
+    42823, 42830, 42837, 42841, 42846, 42853, 42860, 42867, 42873, 42877, 
+    42884, 42891, 42894, 42897, 42901, 42906, 42913, 42920, 42938, 42957, 
+    42975, 42994, 43013, 43032, 43051, 43070, 43075, 43082, 43090, 43098, 
+    43106, 43110, 43113, 43116, 43121, 43124, 43142, 43147, 43153, 43159, 
+    43163, 43166, 43169, 43172, 43180, 43190, 43198, 43206, 43210, 43215, 
+    43219, 43224, 43229, 43234, 43240, 43249, 43256, 43263, 43271, 43278, 
+    43285, 43288, 43295, 43302, 43305, 43308, 43313, 43318, 43324, 43330, 
+    43334, 43340, 43347, 43351, 43357, 43361, 43365, 43373, 43385, 43393, 
+    43397, 43399, 43408, 43417, 43423, 43426, 43431, 43436, 43441, 43446, 
+    43451, 43456, 43461, 43466, 43468, 43474, 43479, 43486, 43490, 43496, 
+    43499, 43503, 43509, 43515, 43517, 43519, 43525, 43532, 43539, 43548, 
+    43557, 43564, 43571, 43577, 43583, 43589, 43594, 43599, 43605, 43611, 
+    43616, 43623, 43627, 43631, 43644, 43657, 43668, 43677, 43683, 43690, 
+    43696, 43701, 43706, 43711, 43716, 43718, 43725, 43732, 43739, 43746, 
+    43753, 43761, 43768, 43774, 43781, 43788, 43795, 43802, 43808, 43816, 
+    43824, 43833, 43842, 43849, 43855, 43861, 43870, 43874, 43883, 43892, 
+    43900, 43908, 43912, 43919, 43926, 43933, 43937, 43943, 43950, 43955, 
+    43960, 43966, 43971, 43976, 43983, 43990, 43995, 44000, 44008, 44016, 
+    44026, 44036, 44043, 44050, 44054, 44058, 44070, 44076, 44082, 44087, 
+    44092, 44099, 44106, 44112, 44118, 44127, 44135, 44143, 44150, 44157, 
+    44164, 44170, 44177, 44183, 44190, 44197, 44204, 44211, 44217, 44222, 
+    44231, 44241, 44248, 44257, 44263, 44268, 44273, 44281, 44287, 44294, 
+    44301, 44309, 44314, 44321, 44328, 44339, 44346, 44352, 44358, 44365, 
+    44372, 44379, 44386, 44397, 44408, 44418, 44428, 44439, 44451, 44456, 
+    44461, 44469, 44477, 44483, 44489, 44498, 44507, 44515, 44523, 44531, 
+    44539, 44549, 44559, 44573, 44587, 44594, 44601, 44612, 44623, 44630, 
+    44637, 44646, 44655, 44660, 44665, 44674, 44683, 44688, 44693, 44701, 
+    44707, 44713, 44721, 44729, 44742, 44755, 44759, 44763, 44770, 44777, 
+    44784, 44792, 44800, 44808, 44816, 44822, 44828, 44834, 44840, 44847, 
+    44854, 44862, 44870, 44873, 44876, 44881, 44886, 44893, 44900, 44907, 
+    44914, 44923, 44932, 44939, 44946, 44954, 44962, 44970, 44978, 44985, 
+    44992, 44999, 45006, 45010, 45014, 45021, 45028, 45033, 45038, 45043, 
+    45048, 45054, 45068, 45075, 45082, 45086, 45088, 45090, 45095, 45100, 
+    45105, 45109, 45117, 45124, 45131, 45139, 45151, 45159, 45167, 45178, 
+    45182, 45186, 45191, 45197, 45208, 45214, 45220, 45226, 45231, 45238, 
+    45247, 45255, 45261, 45267, 45273, 45282, 45291, 45299, 45308, 45313, 
+    45316, 45321, 45327, 45333, 45339, 45345, 45349, 45352, 45356, 45360, 
+    45366, 45372, 45378, 45384, 45388, 45392, 45399, 45406, 45413, 45420, 
+    45427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45434, 45439, 45444, 45449, 
+    45454, 45459, 45464, 45469, 45474, 45479, 45484, 45490, 45494, 45499, 
+    45504, 45509, 45514, 45519, 45524, 45529, 45534, 45539, 45544, 45549, 
+    45554, 45559, 45564, 45569, 45574, 45579, 45584, 45589, 45594, 45599, 
+    45604, 45610, 45615, 45621, 45630, 45635, 45643, 45650, 45659, 45664, 
+    45669, 45674, 45680, 0, 45687, 45692, 45697, 45702, 45707, 45712, 45717, 
+    45722, 45727, 45732, 45737, 45743, 45747, 45752, 45757, 45762, 45767, 
+    45772, 45777, 45782, 45787, 45792, 45797, 45802, 45807, 45812, 45817, 
+    45822, 45827, 45832, 45837, 45842, 45847, 45852, 45857, 45863, 45868, 
+    45874, 45883, 45888, 45896, 45903, 45912, 45917, 45922, 45927, 45933, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 45940, 45945, 45950, 45955, 45960, 45965, 45970, 
+    45975, 45980, 45985, 45990, 45995, 46000, 46005, 46010, 46015, 46020, 
+    46025, 46030, 46035, 46040, 46045, 46050, 46055, 46060, 46065, 46070, 
+    46075, 46080, 46085, 46090, 46094, 46098, 46103, 46108, 46113, 46118, 
+    46123, 46128, 46133, 46138, 46143, 46148, 46153, 46158, 46163, 46168, 
+    46173, 46178, 46183, 46188, 46195, 46202, 46209, 46216, 46223, 46230, 
+    46237, 46244, 46251, 46258, 46265, 46272, 46279, 46286, 46291, 46296, 
+    46303, 46310, 46317, 46324, 46331, 46338, 46345, 46352, 46359, 46366, 
+    46373, 46380, 46386, 46392, 46398, 46404, 46411, 46418, 46425, 46432, 
+    46439, 46446, 46453, 46460, 46467, 46474, 46482, 46490, 46498, 46506, 
+    46514, 46522, 46530, 46538, 46542, 46548, 46554, 46558, 46564, 46570, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46576, 46583, 46592, 46601, 46609, 
+    46616, 46620, 46625, 46630, 46635, 46640, 46645, 46650, 46655, 46660, 
+    46665, 46670, 46675, 46680, 46685, 46690, 46695, 46700, 46705, 46710, 
+    46715, 46720, 46725, 46730, 46735, 46740, 46745, 46750, 46755, 46760, 
+    46765, 46770, 46775, 46780, 46785, 46790, 46795, 46800, 46805, 46810, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 46815, 46818, 46822, 46826, 46830, 46834, 
+    46842, 46846, 46850, 46854, 46858, 46862, 46866, 46870, 46874, 46880, 
+    46884, 46888, 46896, 46902, 46906, 46910, 46914, 46920, 46924, 46930, 
+    46934, 46938, 46944, 46950, 46954, 46958, 46962, 46968, 46974, 46978, 
+    46982, 46986, 46990, 46994, 47000, 47006, 47010, 47014, 47018, 47022, 
+    47026, 47030, 47034, 47038, 47042, 47046, 47050, 47056, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 47060, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47066, 
+    47070, 47074, 47078, 47082, 47086, 47090, 47094, 47098, 47102, 47106, 
+    47112, 47116, 47120, 47124, 47128, 47132, 47136, 47140, 47144, 47148, 
+    47152, 47156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47160, 47164, 47168, 47172, 
+    47176, 47180, 47184, 0, 47188, 47192, 47196, 47200, 47204, 47208, 47212, 
+    0, 47216, 47220, 47224, 47228, 47232, 47236, 47240, 0, 47244, 47248, 
+    47252, 47256, 47260, 47264, 47268, 0, 47272, 47276, 47280, 47284, 47288, 
+    47292, 47296, 0, 47300, 47304, 47308, 47312, 47316, 47320, 47324, 0, 
+    47328, 47332, 47336, 47340, 47344, 47348, 47352, 0, 47356, 47360, 47364, 
+    47368, 47372, 47376, 47380, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47384, 47390, 
+    47398, 47402, 47406, 47412, 47418, 47424, 47432, 47438, 47442, 47446, 
+    47450, 47456, 47462, 47466, 47468, 47472, 47477, 47479, 47483, 47487, 
+    47491, 47497, 0, 0, 0, 0, 47502, 47507, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47512, 47516, 47520, 47525, 
+    47530, 47535, 47539, 47543, 47547, 47552, 47557, 47561, 47565, 47569, 
+    47573, 47578, 47583, 47588, 47593, 47597, 47601, 47606, 47611, 47616, 
+    47621, 47625, 0, 47629, 47633, 47637, 47641, 47645, 47649, 47653, 47658, 
+    47663, 47667, 47672, 47677, 47686, 47690, 47694, 47698, 47705, 47709, 
+    47714, 47719, 47723, 47727, 47733, 47738, 47743, 47748, 47753, 47757, 
+    47761, 47765, 47769, 47773, 47778, 47783, 47787, 47791, 47796, 47801, 
+    47806, 47810, 47814, 47819, 47824, 47830, 47836, 47840, 47846, 47852, 
+    47856, 47862, 47868, 47873, 47878, 47882, 47888, 47892, 47896, 47902, 
+    47908, 47913, 47918, 47922, 47926, 47934, 47940, 47946, 47952, 47957, 
+    47962, 47967, 47973, 47977, 47983, 47987, 47991, 47997, 48003, 48009, 
+    48015, 48021, 48027, 48033, 48039, 48045, 48051, 48057, 48063, 48067, 
+    48073, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48079, 48082, 48086, 48090, 
+    48094, 48098, 48101, 48104, 48108, 48112, 48116, 48120, 48123, 48128, 
+    48132, 48136, 48140, 48146, 48150, 48154, 48158, 48162, 48169, 48175, 
+    48179, 48183, 48187, 48191, 48195, 48199, 48203, 48207, 48211, 48215, 
+    48219, 48225, 48229, 48233, 48237, 48241, 48245, 48249, 48253, 48257, 
+    48261, 48265, 48269, 48273, 48277, 48281, 48285, 48289, 48295, 48301, 
+    48306, 48311, 48315, 48319, 48323, 48327, 48331, 48335, 48339, 48343, 
+    48347, 48351, 48355, 48359, 48363, 48367, 48371, 48375, 48379, 48383, 
+    48387, 48391, 48395, 48398, 48402, 48406, 48412, 48416, 48420, 48424, 
+    48428, 48432, 48436, 48440, 48444, 48448, 48455, 48459, 48463, 48467, 
+    48471, 48475, 48479, 48483, 48487, 48491, 48495, 48499, 48503, 48510, 
+    48514, 48520, 48524, 48528, 48532, 48536, 48540, 48543, 48547, 48551, 
+    48555, 48559, 48563, 48567, 48571, 48575, 48579, 48583, 48587, 48591, 
+    48595, 48599, 48603, 48607, 48611, 48615, 48619, 48623, 48627, 48631, 
+    48635, 48639, 48643, 48647, 48651, 48655, 48659, 48663, 48667, 48671, 
+    48677, 48681, 48685, 48689, 48693, 48697, 48701, 48705, 48709, 48713, 
+    48717, 48721, 48725, 48729, 48733, 48737, 48741, 48745, 48749, 48753, 
+    48757, 48761, 48765, 48769, 48773, 48777, 48781, 48785, 48793, 48797, 
+    48801, 48805, 48809, 48813, 48819, 48823, 48827, 48831, 48835, 48839, 
+    48843, 48847, 48851, 48855, 48859, 48863, 48867, 48871, 48877, 48881, 
+    48885, 48889, 48893, 48897, 48901, 48905, 48909, 48913, 48917, 48921, 
+    48925, 48929, 48933, 48937, 48941, 48945, 48949, 48953, 48957, 48961, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 48965, 48972, 48979, 48989, 48999, 49007, 49016, 49025, 49035, 49046, 
+    49056, 49067, 0, 0, 0, 0, 49073, 49076, 49079, 49083, 49086, 49093, 
+    49097, 49101, 49105, 49108, 49111, 49115, 49119, 49123, 49127, 49132, 
+    49137, 49142, 49147, 49150, 49153, 49159, 49165, 49170, 49175, 49182, 
+    49189, 49193, 49197, 49201, 49208, 49214, 49221, 49226, 49230, 49234, 
+    49238, 49242, 49246, 49250, 49254, 49258, 49262, 49267, 49272, 49277, 
+    49282, 49288, 49293, 49297, 49303, 49314, 49323, 49337, 49346, 49350, 
+    49359, 49364, 49369, 49374, 49379, 49382, 49387, 49391, 0, 49397, 49401, 
+    49404, 49408, 49411, 49415, 49418, 49422, 49425, 49429, 49432, 49435, 
+    49439, 49443, 49447, 49451, 49455, 49459, 49463, 49467, 49471, 49475, 
+    49479, 49483, 49487, 49491, 49495, 49499, 49503, 49507, 49511, 49515, 
+    49519, 49523, 49527, 49532, 49536, 49540, 49544, 49548, 49551, 49555, 
+    49559, 49563, 49567, 49571, 49575, 49578, 49582, 49586, 49590, 49594, 
+    49598, 49602, 49606, 49610, 49614, 49618, 49622, 49626, 49630, 49634, 
+    49637, 49641, 49645, 49649, 49653, 49657, 49660, 49665, 49669, 49674, 
+    49678, 49682, 49686, 49690, 49694, 49698, 49703, 49707, 49711, 49715, 
+    49719, 49722, 49726, 49730, 0, 0, 49735, 49743, 49751, 49758, 49765, 
+    49769, 49775, 49780, 49785, 49789, 49792, 49796, 49799, 49803, 49806, 
+    49810, 49813, 49817, 49820, 49823, 49827, 49831, 49835, 49839, 49843, 
+    49847, 49851, 49855, 49859, 49863, 49867, 49871, 49875, 49879, 49883, 
+    49887, 49891, 49895, 49899, 49903, 49907, 49911, 49915, 49920, 49924, 
+    49928, 49932, 49936, 49939, 49943, 49947, 49951, 49955, 49959, 49963, 
+    49966, 49970, 49974, 49978, 49982, 49986, 49990, 49994, 49998, 50002, 
+    50006, 50010, 50014, 50018, 50022, 50025, 50029, 50033, 50037, 50041, 
+    50045, 50048, 50053, 50057, 50062, 50066, 50070, 50074, 50078, 50082, 
+    50086, 50091, 50095, 50099, 50103, 50107, 50110, 50114, 50118, 50123, 
+    50127, 50131, 50135, 50139, 50144, 50151, 50155, 50161, 0, 0, 0, 0, 0, 
+    50166, 50169, 50172, 50175, 50179, 50182, 50185, 50188, 50191, 50194, 
+    50198, 50201, 50204, 50208, 50211, 50215, 50219, 50223, 50226, 50230, 
+    50234, 50237, 50240, 50243, 50246, 50250, 50254, 50258, 50262, 50266, 
+    50270, 50274, 50278, 50282, 50286, 50289, 50292, 50296, 50299, 50303, 0, 
+    0, 0, 0, 50307, 50311, 50315, 50319, 50323, 50327, 50331, 50335, 50339, 
+    50343, 50347, 50351, 50355, 50359, 50363, 50367, 50371, 50375, 50379, 
+    50383, 50387, 50391, 50395, 50399, 50403, 50407, 50411, 50415, 50419, 
+    50423, 50427, 50430, 50434, 50437, 50441, 50445, 50448, 50452, 50456, 
+    50459, 50463, 50467, 50471, 50475, 50478, 50482, 50486, 50490, 50494, 
+    50498, 50502, 50505, 50508, 50512, 50516, 50520, 50524, 50528, 50532, 
+    50536, 50540, 50544, 50548, 50552, 50556, 50560, 50564, 50568, 50572, 
+    50576, 50580, 50584, 50588, 50592, 50596, 50600, 50604, 50608, 50612, 
+    50616, 50620, 50624, 50628, 50632, 50636, 50640, 50644, 50648, 50652, 
+    50656, 50660, 50664, 50668, 50672, 0, 50676, 50682, 50688, 50694, 50699, 
+    50704, 50710, 50716, 50722, 50728, 50734, 50740, 50746, 50752, 50758, 
+    50764, 50770, 50774, 50778, 50782, 50786, 50790, 50794, 50798, 50802, 
+    50806, 50810, 50814, 50818, 50822, 50826, 50830, 50834, 50838, 50842, 
+    50846, 50850, 50854, 50858, 50863, 0, 0, 0, 0, 0, 0, 0, 0, 50867, 50871, 
+    50876, 50881, 50886, 50891, 50896, 50901, 50906, 50911, 50916, 50921, 
+    50926, 50931, 50936, 50941, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50945, 50950, 50955, 
+    50960, 50964, 50969, 50973, 50978, 50983, 50988, 50993, 50998, 51003, 
+    51008, 51013, 51018, 51023, 51027, 51031, 51035, 51039, 51043, 51047, 
+    51051, 51055, 51059, 51063, 51067, 51071, 51075, 51079, 51084, 51089, 
+    51094, 51099, 51104, 51109, 51114, 51119, 51124, 51129, 51134, 51139, 
+    51144, 51149, 51154, 51160, 0, 51167, 51170, 51173, 51176, 51179, 51182, 
+    51185, 51188, 51191, 51194, 51198, 51202, 51206, 51210, 51214, 51218, 
+    51222, 51226, 51230, 51234, 51238, 51242, 51246, 51250, 51254, 51258, 
+    51262, 51266, 51270, 51274, 51278, 51282, 51286, 51290, 51294, 51298, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51302, 51305, 51310, 51315, 51320, 
+    51325, 51330, 51335, 51340, 51345, 51350, 51354, 51359, 51364, 51369, 
+    51374, 51379, 51383, 51387, 51391, 51395, 51399, 51403, 51407, 51411, 
+    51415, 51419, 51423, 51427, 51431, 51435, 51440, 51445, 51450, 51455, 
+    51460, 51465, 51470, 51475, 51480, 51485, 51490, 51495, 51500, 51505, 
+    51511, 51517, 51522, 51527, 51530, 51533, 51536, 51539, 51542, 51545, 
+    51548, 51551, 51554, 51558, 51562, 51566, 51570, 51574, 51578, 51582, 
+    51586, 51590, 51594, 51598, 51602, 51606, 51610, 51614, 51618, 51622, 
+    51626, 51630, 51634, 51638, 51642, 51646, 51650, 51654, 51658, 51662, 
+    51666, 51670, 51674, 51678, 51681, 51685, 51689, 51693, 51697, 51701, 
+    51705, 51709, 51713, 51718, 51723, 51728, 51733, 51737, 51742, 51747, 
+    51752, 51757, 51762, 51767, 51772, 51777, 51782, 51786, 51792, 51798, 
+    51804, 51810, 51816, 51822, 51828, 51834, 51840, 51846, 51852, 51858, 
+    51861, 51864, 51867, 51872, 51875, 51878, 51881, 51884, 51887, 51890, 
+    51894, 51898, 51902, 51906, 51910, 51914, 51918, 51922, 51926, 51930, 
+    51934, 51938, 51942, 51945, 51949, 51953, 51957, 51961, 51965, 51968, 
+    51972, 51976, 51980, 51984, 51987, 51991, 51995, 51999, 52003, 52006, 
+    52010, 52014, 52018, 52022, 52026, 52030, 52034, 52038, 52042, 52046, 0, 
+    52050, 52053, 52056, 52059, 52062, 52065, 52068, 52071, 52074, 52077, 
+    52080, 52083, 52086, 52089, 52092, 52095, 52098, 52101, 52104, 52107, 
+    52110, 52113, 52116, 52119, 52122, 52125, 52128, 52131, 52134, 52137, 
+    52140, 52143, 52146, 52149, 52152, 52155, 52158, 52161, 52164, 52167, 
+    52170, 52173, 52176, 52179, 52182, 52185, 52188, 52191, 52194, 52197, 
+    52200, 52203, 52206, 52209, 52212, 52215, 52218, 52221, 52224, 52227, 
+    52230, 52233, 52236, 52239, 52242, 52245, 52248, 52251, 52254, 52257, 
+    52260, 52263, 52266, 52269, 52272, 52275, 52278, 52281, 52284, 52287, 
+    52290, 52293, 52296, 52299, 52302, 52305, 52308, 52311, 52314, 52322, 
+    52329, 52336, 52343, 52350, 52357, 52364, 52371, 52378, 52385, 52393, 
+    52401, 52409, 52417, 52425, 52433, 52441, 52449, 52457, 52465, 52473, 
+    52481, 52489, 52497, 52505, 52508, 52511, 52514, 52516, 52519, 52522, 
+    52525, 52530, 52535, 52538, 52545, 52552, 52559, 52566, 52569, 52574, 
+    52577, 52581, 52583, 52585, 52588, 52591, 52594, 52597, 52600, 52603, 
+    52606, 52611, 52615, 52618, 52621, 52624, 52627, 52630, 52633, 52636, 
+    52640, 52643, 52646, 52649, 52652, 52655, 52659, 52662, 52665, 52668, 
+    52673, 52678, 52683, 52688, 52693, 52698, 52703, 52708, 52714, 52723, 
+    52726, 52729, 52732, 52735, 52738, 52744, 52753, 52756, 52759, 52763, 
+    52766, 52769, 52772, 52776, 52779, 52782, 52787, 52790, 52793, 52798, 
+    52801, 52804, 52809, 52814, 52819, 52822, 52825, 52828, 52831, 52838, 
+    52841, 52844, 52847, 52849, 52852, 52855, 52858, 52863, 52866, 52869, 
+    52872, 52875, 52878, 52883, 52886, 52889, 52892, 52895, 52898, 52901, 
+    52904, 52907, 52910, 52916, 52921, 52928, 52935, 52942, 52949, 52956, 
+    52963, 52970, 52977, 52984, 52992, 53000, 53008, 53016, 53024, 53032, 
+    53040, 53048, 53056, 53064, 53072, 53080, 53088, 53096, 53104, 53112, 
+    53120, 53128, 53136, 53144, 53152, 53160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 53163, 53171, 53179, 53189, 53195, 53199, 53203, 53209, 
+    53215, 53220, 53224, 53228, 53232, 53236, 53242, 53246, 53250, 53254, 
+    53264, 53268, 53272, 53278, 53282, 53288, 53292, 53296, 53302, 53308, 
+    53314, 53322, 53330, 53334, 53338, 53342, 53348, 53352, 53361, 53367, 
+    53371, 53375, 53379, 53383, 53387, 53391, 53398, 53404, 53410, 53414, 
+    53420, 53424, 53430, 53438, 53448, 53452, 53460, 53464, 53470, 53478, 
+    53486, 53490, 53494, 53500, 53505, 53511, 53517, 53521, 53525, 53528, 
+    53532, 53536, 53540, 53544, 53548, 53552, 53556, 53559, 53563, 53567, 
+    53571, 53575, 53579, 53583, 53586, 53590, 53594, 53597, 53601, 53605, 
+    53609, 53613, 53617, 53621, 53625, 53629, 53633, 53637, 53641, 53645, 
+    53649, 53653, 53657, 53661, 53665, 53669, 53673, 53677, 53681, 53685, 
+    53689, 53693, 53697, 53701, 53705, 53709, 53713, 53717, 53721, 53725, 
+    53729, 53733, 53737, 53741, 53745, 53749, 53753, 53757, 53761, 53765, 
+    53769, 53773, 53777, 53781, 53785, 53789, 53793, 53797, 53801, 53805, 
+    53809, 53813, 53817, 53821, 53825, 53829, 53833, 53837, 53841, 53845, 
+    53849, 53853, 53857, 53861, 53865, 53869, 53873, 53877, 53881, 53885, 
+    53889, 53893, 53897, 53901, 53905, 53909, 53913, 53917, 53921, 53925, 
+    53929, 53933, 53937, 53941, 53945, 53949, 53953, 53957, 53961, 53965, 
+    53969, 53973, 53977, 53981, 53985, 53989, 53993, 53997, 54001, 54005, 
+    54009, 54013, 54017, 54021, 54025, 54029, 54033, 54037, 54041, 54045, 
+    54049, 54053, 54057, 54061, 54065, 54069, 54073, 54077, 54081, 54085, 
+    54089, 54093, 54097, 54101, 54105, 54109, 54113, 54117, 54121, 54125, 
+    54129, 54133, 54137, 54141, 54145, 54149, 54153, 54157, 54161, 54165, 
+    54169, 54173, 54177, 54181, 54185, 54189, 54193, 54197, 54201, 54205, 
+    54209, 54213, 54217, 54221, 54225, 54229, 54233, 54237, 54241, 54245, 
+    54248, 54252, 54256, 54260, 54264, 54268, 54272, 54276, 54280, 54284, 
+    54288, 54292, 54296, 54300, 54304, 54308, 54312, 54316, 54320, 54324, 
+    54328, 54332, 54336, 54340, 54344, 54348, 54352, 54356, 54360, 54364, 
+    54368, 54372, 54376, 54380, 54384, 54388, 54392, 54396, 54400, 54404, 
+    54408, 54412, 54416, 54420, 54424, 54428, 54432, 54436, 54440, 54444, 
+    54448, 54452, 54456, 54460, 54464, 54468, 54472, 54476, 54480, 54484, 
+    54488, 54492, 54496, 54500, 54504, 54508, 54512, 54516, 54520, 54524, 
+    54528, 54532, 54536, 54540, 54544, 54548, 54552, 54556, 54560, 54564, 
+    54568, 54572, 54576, 54580, 54584, 54588, 54592, 54596, 54600, 54604, 
+    54608, 54612, 54616, 54620, 54624, 54628, 54632, 54636, 54640, 54644, 
+    54648, 54652, 54656, 54660, 54664, 54668, 54672, 54676, 54680, 54684, 
+    54688, 54692, 54696, 54700, 54704, 54708, 54711, 54715, 54719, 54723, 
+    54727, 54731, 54735, 54739, 54743, 54747, 54751, 54755, 54759, 54763, 
+    54767, 54771, 54775, 54779, 54783, 54787, 54791, 54795, 54799, 54803, 
+    54807, 54811, 54815, 54819, 54823, 54827, 54831, 54835, 54839, 54843, 
+    54847, 54851, 54855, 54859, 54863, 54867, 54871, 54875, 54879, 54883, 
+    54887, 54891, 54895, 54899, 54903, 54907, 54911, 54915, 54919, 54923, 
+    54927, 54931, 54935, 54939, 54943, 54947, 54951, 54955, 54959, 54963, 
+    54967, 54971, 54975, 54979, 54983, 54987, 54991, 54995, 54999, 55003, 
+    55007, 55011, 55015, 55019, 55023, 55027, 55031, 55035, 55039, 55043, 
+    55047, 55051, 55055, 55059, 55063, 55067, 55071, 55075, 55079, 55083, 
+    55087, 55091, 55095, 55099, 55103, 55107, 55111, 55115, 55119, 55123, 
+    55127, 55131, 55135, 55139, 55143, 55147, 55151, 55155, 55159, 55163, 
+    55167, 55171, 55175, 55179, 55183, 55187, 55191, 55195, 55199, 55203, 
+    55207, 55211, 55215, 55219, 55223, 55227, 55231, 55235, 55239, 55243, 
+    55247, 55251, 55255, 55259, 55263, 55267, 55271, 55275, 55279, 55283, 
+    55287, 55291, 55295, 55299, 55303, 55307, 55311, 55315, 55319, 55323, 
+    55327, 55331, 55335, 55339, 55343, 55347, 55351, 55355, 55359, 55363, 
+    55367, 55371, 55375, 55379, 55383, 55387, 55391, 55395, 55399, 55403, 
+    55407, 55411, 55415, 55419, 55423, 55427, 55431, 55435, 55439, 55443, 
+    55447, 55451, 55455, 55459, 55463, 55467, 55471, 55475, 55479, 55483, 
+    55487, 55491, 55495, 55499, 55503, 55507, 55511, 55515, 55519, 55523, 
+    55527, 55531, 55535, 55539, 55543, 55547, 55551, 55555, 55559, 55563, 
+    55566, 55570, 55574, 55578, 55582, 55586, 55590, 55594, 55598, 55602, 
+    55606, 55610, 55614, 55618, 55622, 55626, 55630, 55634, 55638, 55642, 
+    55646, 55650, 55654, 55658, 55662, 55666, 55670, 55674, 55678, 55682, 
+    55686, 55690, 55694, 55698, 55702, 55706, 55710, 55714, 55718, 55722, 
+    55726, 55730, 55734, 55738, 55742, 55746, 55750, 55754, 55758, 55762, 
+    55766, 55770, 55774, 55778, 55782, 55786, 55790, 55794, 55798, 55802, 
+    55806, 55810, 55814, 55818, 55822, 55826, 55830, 55834, 55838, 55842, 
+    55846, 55850, 55854, 55858, 55862, 55866, 55870, 55874, 55878, 55882, 
+    55886, 55890, 55894, 55898, 55902, 55906, 55910, 55914, 55918, 55922, 
+    55926, 55930, 55934, 55938, 55942, 55946, 55950, 55954, 55958, 55962, 
+    55966, 55970, 55974, 55978, 55982, 55986, 55990, 55994, 55998, 56002, 
+    56006, 56010, 56014, 56018, 56021, 56025, 56029, 56033, 56037, 56041, 
+    56045, 56049, 56053, 56057, 56061, 56065, 56069, 56073, 56077, 56081, 
+    56085, 56089, 56093, 56097, 56101, 56105, 56109, 56113, 56117, 56121, 
+    56125, 56129, 56133, 56137, 56141, 56145, 56149, 56153, 56157, 56161, 
+    56165, 56169, 56173, 56177, 56181, 56185, 56189, 56193, 56197, 56201, 
+    56205, 56209, 56213, 56217, 56221, 56225, 56229, 56233, 56237, 56241, 
+    56245, 56249, 56253, 56257, 56261, 56265, 56269, 56273, 56277, 56281, 
+    56285, 56289, 56293, 56297, 56301, 56305, 56309, 56313, 56317, 56321, 
+    56325, 56329, 56333, 56337, 56341, 56345, 56349, 56353, 56357, 56361, 
+    56365, 56369, 56373, 56377, 56381, 56385, 56389, 56393, 56397, 56401, 
+    56405, 56409, 56413, 56417, 56421, 56425, 56429, 56433, 56437, 56441, 
+    56445, 56449, 56453, 56457, 56461, 56465, 56469, 56473, 56477, 56481, 
+    56485, 56489, 56493, 56497, 56501, 56505, 56509, 56513, 56517, 56521, 
+    56525, 56529, 56533, 56537, 56541, 56545, 56549, 56553, 56557, 56561, 
+    56565, 56569, 56573, 56577, 56581, 56585, 56589, 56593, 56597, 56601, 
+    56605, 56609, 56613, 56617, 56621, 56624, 56628, 56632, 56636, 56640, 
+    56644, 56648, 56652, 56656, 56660, 56664, 56668, 56672, 56676, 56680, 
+    56684, 56688, 56692, 56696, 56700, 56704, 56708, 56712, 56716, 56720, 
+    56724, 56728, 56732, 56736, 56740, 56744, 56748, 56752, 56756, 56760, 
+    56764, 56768, 56772, 56776, 56780, 56784, 56788, 56792, 56796, 56800, 
+    56804, 56808, 56812, 56816, 56820, 56824, 56828, 56832, 56836, 56840, 
+    56844, 56848, 56852, 56856, 56860, 56864, 56868, 56872, 56876, 56880, 
+    56884, 56888, 56892, 56896, 56900, 56904, 56908, 56912, 56916, 56920, 
+    56924, 56928, 56932, 56936, 56940, 56944, 56948, 56952, 56956, 56960, 
+    56964, 56968, 56972, 56976, 56980, 56984, 56988, 56992, 56996, 57000, 
+    57004, 57008, 57012, 57016, 57020, 57024, 57028, 57032, 57036, 57040, 
+    57044, 57048, 57052, 57056, 57060, 57064, 57068, 57072, 57076, 57080, 
+    57084, 57088, 57092, 57096, 57100, 57104, 57108, 57112, 57116, 57120, 
+    57124, 57128, 57132, 57136, 57140, 57144, 57148, 57152, 57156, 57160, 
+    57164, 57168, 57172, 57176, 57180, 57184, 57188, 57192, 57196, 57200, 
+    57204, 57208, 57212, 57216, 57220, 57224, 57228, 57232, 57236, 57240, 
+    57244, 57248, 57252, 57256, 57260, 57264, 57268, 57272, 57276, 57280, 
+    57284, 57288, 57292, 57296, 57300, 57304, 57308, 57312, 57316, 57320, 
+    57324, 57328, 57332, 57336, 57340, 57344, 57348, 57352, 57356, 57360, 
+    57364, 57368, 57372, 57376, 57380, 57384, 57388, 57392, 57396, 57400, 
+    57404, 57408, 57412, 57416, 57420, 57424, 57428, 57432, 57436, 57440, 
+    57444, 57448, 57452, 57456, 57460, 57464, 57468, 57472, 57476, 57480, 
+    57484, 57488, 57492, 57496, 57500, 57504, 57508, 57512, 57516, 57520, 
+    57524, 57528, 57532, 57536, 57540, 57544, 57548, 57552, 57556, 57560, 
+    57564, 57568, 57572, 57576, 57580, 57584, 57588, 57592, 57596, 57600, 
+    57604, 57608, 57612, 57616, 57620, 57624, 57628, 57632, 57636, 57640, 
+    57644, 57648, 57652, 57656, 57660, 57664, 57668, 57672, 57676, 57680, 
+    57684, 57688, 57692, 57696, 57700, 57704, 57708, 57712, 57716, 57720, 
+    57724, 57728, 57732, 57736, 57740, 57744, 57748, 57752, 57756, 57760, 
+    57764, 57768, 57772, 57776, 57780, 57784, 57788, 57792, 57796, 57800, 
+    57804, 57808, 57812, 57816, 57820, 57824, 57828, 57832, 57836, 57840, 
+    57844, 57848, 57852, 57856, 57860, 57864, 57868, 57872, 57876, 57880, 
+    57884, 57888, 57892, 57896, 57900, 57904, 57908, 57912, 57916, 57920, 
+    57924, 57928, 57932, 57936, 57940, 57944, 57948, 57952, 57956, 57960, 
+    57964, 57968, 57972, 57976, 57980, 57984, 57988, 57992, 57996, 58000, 
+    58004, 58008, 58012, 58016, 58020, 58024, 58028, 58032, 58036, 58040, 
+    58044, 58048, 58052, 58056, 58060, 58064, 58068, 58072, 58076, 58080, 
+    58084, 58088, 58092, 58096, 58100, 58104, 58108, 58112, 58116, 58120, 
+    58124, 58128, 58132, 58136, 58140, 58144, 58148, 58152, 58156, 58160, 
+    58164, 0, 0, 0, 58168, 58172, 58176, 58180, 58184, 58188, 58192, 58196, 
+    58200, 58204, 58208, 58212, 58216, 58220, 58224, 58228, 58232, 58236, 
+    58240, 58244, 58248, 58252, 58256, 58260, 58264, 58268, 58272, 58276, 
+    58280, 58284, 58288, 58292, 58296, 58300, 58304, 58308, 58312, 58316, 
+    58320, 58324, 58328, 58332, 58336, 58340, 58344, 58348, 58352, 58356, 
+    58360, 58364, 58368, 58372, 58376, 58380, 58384, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 58388, 58397, 58406, 58415, 58424, 58433, 58442, 58451, 58460, 58468, 
+    58475, 58483, 58490, 58498, 58508, 58517, 58527, 58536, 58546, 58554, 
+    58561, 58569, 58576, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58584, 58590, 58596, 
+    58603, 58609, 58615, 58621, 58628, 58635, 58642, 58649, 58656, 58663, 
+    58670, 58677, 58684, 58691, 58698, 58705, 58712, 58719, 58725, 58732, 
+    58739, 58746, 58753, 58760, 58767, 58774, 58781, 58788, 58795, 58802, 
+    58809, 58816, 58823, 58830, 58837, 58844, 58851, 58859, 58867, 58875, 
+    58883, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58891, 58895, 58899, 58903, 
+    58907, 58911, 58915, 58919, 58923, 58927, 58931, 58935, 58939, 58943, 
+    58947, 58951, 58955, 58959, 58963, 58967, 58971, 58975, 58979, 58983, 
+    58987, 58991, 58995, 58999, 59003, 59007, 59011, 59015, 59019, 59023, 
+    59027, 59031, 59035, 59039, 59043, 59047, 59051, 59055, 59059, 59063, 
+    59067, 59071, 59075, 59079, 59083, 59087, 59091, 59095, 59099, 59103, 
+    59107, 59111, 59115, 59119, 59123, 59127, 59131, 59135, 59139, 59143, 
+    59147, 59151, 59155, 59159, 59163, 59167, 59171, 59175, 59179, 59183, 
+    59187, 59191, 59195, 59199, 59203, 59207, 59211, 59215, 59219, 59223, 
+    59227, 59231, 59235, 59239, 59243, 59247, 59251, 59255, 59259, 59263, 
+    59267, 59271, 59275, 59279, 59283, 59287, 59291, 59295, 59299, 59303, 
+    59307, 59311, 59315, 59319, 59323, 59327, 59331, 59335, 59339, 59343, 
+    59347, 59351, 59355, 59359, 59363, 59367, 59371, 59375, 59379, 59383, 
+    59387, 59391, 59395, 59399, 59403, 59407, 59411, 59415, 59419, 59423, 
+    59427, 59431, 59435, 59439, 59443, 59447, 59451, 59455, 59459, 59463, 
+    59467, 59471, 59475, 59479, 59483, 59487, 59491, 59495, 59499, 59503, 
+    59507, 59511, 59515, 59519, 59523, 59527, 59531, 59535, 59539, 59543, 
+    59547, 59551, 59555, 59559, 59563, 59567, 59571, 59575, 59579, 59583, 
+    59587, 59591, 59595, 59599, 59603, 59607, 59611, 59615, 59619, 59623, 
+    59627, 59631, 59635, 59639, 59643, 59647, 59651, 59655, 59659, 59663, 
+    59667, 59671, 59675, 59679, 59683, 59687, 59691, 59695, 59699, 59703, 
+    59707, 59711, 59715, 59719, 59723, 59727, 59731, 59735, 59739, 59743, 
+    59747, 59751, 59755, 59759, 59763, 59767, 59771, 59775, 59779, 59783, 
+    59787, 59791, 59795, 59799, 59803, 59807, 59811, 59815, 59819, 59823, 
+    59827, 59831, 59835, 59839, 59843, 59847, 59851, 59855, 59859, 59863, 
+    59867, 59871, 59875, 59879, 59883, 59887, 59891, 59895, 59899, 59903, 
+    59907, 59911, 59915, 59919, 59923, 59927, 59931, 59935, 59939, 59943, 
+    59947, 59951, 59955, 59959, 59963, 59967, 59971, 59975, 59979, 59983, 
+    59987, 59991, 59995, 59999, 60003, 60007, 60011, 60015, 60019, 60023, 
+    60027, 60031, 60035, 60039, 60043, 60047, 60051, 60055, 60059, 60063, 
+    60067, 60071, 60075, 60079, 60083, 60087, 60091, 60095, 0, 0, 60099, 
+    60103, 60107, 60111, 60115, 60119, 60123, 60127, 60131, 60135, 60139, 
+    60143, 60147, 60151, 60155, 60159, 60163, 60167, 60171, 60175, 60179, 
+    60183, 60187, 60191, 60195, 60199, 60203, 60207, 60211, 60215, 60219, 
+    60223, 60227, 60231, 60235, 60239, 60243, 60247, 60251, 60255, 60259, 
+    60263, 60267, 60271, 60275, 60279, 60283, 60287, 60291, 60295, 60299, 
+    60303, 60307, 60311, 60315, 60319, 60323, 60327, 60331, 0, 0, 0, 0, 0, 
+    60335, 60339, 60343, 60347, 60351, 60355, 60359, 60363, 60367, 60371, 
+    60375, 60379, 60383, 60387, 60391, 60395, 60399, 60403, 60407, 60411, 
+    60415, 60419, 60423, 60427, 60431, 60435, 60439, 60443, 60447, 60451, 
+    60455, 60459, 60463, 60467, 60471, 60475, 60479, 60483, 60487, 60491, 
+    60495, 60499, 60503, 60507, 60511, 60515, 60519, 60523, 60527, 60531, 
+    60535, 60539, 60543, 60547, 60551, 60555, 60559, 60563, 60567, 60571, 
+    60575, 60579, 60583, 60587, 60591, 60595, 60599, 60603, 60607, 60611, 
+    60615, 60619, 60623, 60627, 60631, 60635, 60639, 60643, 60647, 60651, 
+    60655, 60659, 60663, 60667, 60671, 60675, 60679, 60683, 60687, 60691, 
+    60695, 60699, 60703, 60707, 60711, 60715, 60719, 60723, 60727, 60731, 
+    60735, 60739, 60743, 60747, 60751, 60755, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 60759, 60764, 60769, 60774, 60779, 60784, 60791, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 60796, 60803, 60810, 60817, 60824, 0, 0, 0, 0, 0, 
+    60831, 60838, 60845, 60855, 60861, 60867, 60873, 60879, 60885, 60891, 
+    60898, 60904, 60910, 60917, 60926, 60935, 60947, 60959, 60965, 60971, 
+    60977, 60984, 60991, 60998, 61005, 61012, 0, 61019, 61026, 61033, 61041, 
+    61048, 0, 61055, 0, 61062, 61069, 0, 61076, 61084, 0, 61091, 61098, 
+    61105, 61112, 61119, 61126, 61133, 61140, 61147, 61154, 61159, 61166, 
+    61173, 61179, 61185, 61191, 61197, 61203, 61209, 61215, 61221, 61227, 
+    61233, 61239, 61245, 61251, 61257, 61263, 61269, 61275, 61281, 61287, 
+    61293, 61299, 61305, 61311, 61317, 61323, 61329, 61335, 61341, 61347, 
+    61353, 61359, 61365, 61371, 61377, 61383, 61389, 61395, 61401, 61407, 
+    61413, 61419, 61425, 61431, 61437, 61443, 61449, 61455, 61461, 61467, 
+    61473, 61479, 61485, 61491, 61497, 61503, 61509, 61515, 61521, 61527, 
+    61533, 61539, 61545, 61551, 61557, 61563, 61569, 61575, 61581, 61587, 
+    61593, 61599, 61605, 61611, 61617, 61623, 61629, 61636, 61643, 61649, 
+    61655, 61661, 61667, 61676, 61685, 61693, 61701, 61709, 61717, 61725, 
+    61733, 61741, 61749, 61756, 61763, 61773, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    61783, 61789, 61795, 61801, 61807, 61812, 61817, 61823, 61829, 61835, 
+    61841, 61849, 61855, 61861, 61869, 61877, 61885, 61893, 61898, 61903, 
+    61908, 61913, 61925, 61937, 61947, 61957, 61968, 61979, 61990, 62001, 
+    62011, 62021, 62032, 62043, 62054, 62065, 62075, 62085, 62095, 62110, 
+    62125, 62140, 62147, 62154, 62161, 62168, 62178, 62188, 62198, 62209, 
+    62219, 62227, 62235, 62243, 62251, 62260, 62268, 62276, 62284, 62292, 
+    62300, 62309, 62317, 62325, 62333, 62342, 62350, 62357, 62364, 62371, 
+    62378, 62385, 62392, 62399, 62407, 62415, 62423, 62431, 62439, 62447, 
+    62455, 62463, 62471, 62479, 62487, 62495, 62503, 62511, 62519, 62527, 
+    62535, 62543, 62551, 62559, 62567, 62576, 62584, 62592, 62600, 62609, 
+    62617, 62625, 62633, 62641, 62649, 62657, 62665, 62674, 62682, 62689, 
+    62696, 62703, 62710, 62718, 62725, 62732, 62739, 62746, 62753, 62761, 
+    62768, 62775, 62782, 62789, 62796, 62804, 62811, 62819, 62827, 62836, 
+    62844, 62851, 62858, 62865, 62872, 62880, 62887, 62897, 62907, 62917, 
+    62926, 62935, 62944, 62953, 62962, 62972, 62983, 62994, 63004, 63014, 
+    63025, 63035, 63044, 63053, 63061, 63069, 63078, 63086, 63095, 63104, 
+    63112, 63120, 63129, 63137, 63146, 63155, 63163, 63171, 63180, 63188, 
+    63197, 63205, 63214, 63222, 63230, 63238, 63246, 63255, 63263, 63270, 
+    63278, 63285, 63292, 63299, 63307, 63315, 63322, 63329, 63337, 63344, 
+    63354, 63362, 63370, 63377, 63384, 63392, 63399, 63409, 63419, 63429, 
+    63439, 63450, 63458, 63466, 63474, 63482, 63491, 63499, 63507, 63515, 
+    63523, 63532, 63540, 63547, 63554, 63561, 63568, 63575, 63582, 63590, 
+    63598, 63606, 63614, 63622, 63630, 63638, 63646, 63654, 63662, 63670, 
+    63678, 63686, 63694, 63702, 63710, 63718, 63726, 63734, 63742, 63750, 
+    63758, 63766, 63774, 63782, 63790, 63798, 63806, 63813, 63820, 63827, 
+    63834, 63842, 63849, 63856, 63863, 63870, 63877, 63884, 63891, 63898, 
+    63906, 63914, 63922, 63932, 63939, 63946, 63953, 63960, 63968, 63978, 
+    63989, 63997, 64006, 64014, 64023, 64031, 64040, 64048, 64057, 64065, 
+    64074, 64082, 64090, 64097, 64104, 64112, 64119, 64127, 64136, 64145, 
+    64154, 64163, 64171, 64180, 64188, 64197, 64205, 64214, 64222, 64231, 
+    64239, 64247, 64254, 64262, 64269, 64277, 64284, 64293, 64301, 64310, 
+    64318, 64326, 64334, 64342, 64350, 64359, 64368, 64377, 64386, 64395, 
+    64403, 64412, 64420, 64429, 64437, 64446, 64454, 64463, 64471, 64479, 
+    64486, 64494, 64501, 64509, 64516, 64525, 64533, 64542, 64550, 64558, 
+    64566, 64574, 64582, 64591, 64600, 64609, 64618, 64626, 64634, 64642, 
+    64650, 64659, 64668, 64676, 64684, 64692, 64700, 64708, 64716, 64724, 
+    64732, 64740, 64748, 64756, 64761, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 64766, 64776, 64786, 64796, 64806, 64816, 64826, 64836, 64846, 
+    64855, 64864, 64873, 64883, 64893, 64903, 64914, 64924, 64934, 64944, 
+    64954, 64964, 64974, 64984, 64994, 65004, 65014, 65024, 65034, 65044, 
+    65054, 65064, 65075, 65085, 65095, 65105, 65115, 65125, 65135, 65145, 
+    65155, 65165, 65176, 65186, 65196, 65207, 65217, 65227, 65237, 65247, 
+    65256, 65265, 65275, 65284, 65293, 65302, 65311, 65320, 65329, 65338, 
+    65347, 65356, 65365, 65374, 65383, 0, 0, 65392, 65401, 65411, 65421, 
+    65430, 65440, 65449, 65458, 65468, 65477, 65487, 65496, 65505, 65515, 
+    65525, 65536, 65546, 65557, 65567, 65578, 65587, 65597, 65607, 65618, 
+    65628, 65638, 65648, 65657, 65666, 65675, 65684, 65693, 65702, 65712, 
+    65721, 65731, 65740, 65750, 65760, 65769, 65778, 65787, 65797, 65806, 
+    65815, 65824, 65833, 65842, 65852, 65862, 65872, 65882, 65892, 65902, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65911, 65926, 65941, 65947, 
+    65953, 65959, 65965, 65971, 65977, 65983, 65989, 65997, 66001, 66004, 0, 
+    0, 66012, 66015, 66018, 66021, 66024, 66027, 66030, 66033, 66036, 66039, 
+    66042, 66045, 66048, 66051, 66054, 66057, 66060, 66068, 66077, 66087, 
+    66095, 66103, 66112, 66121, 66132, 66144, 0, 0, 0, 0, 0, 0, 66153, 66158, 
+    66163, 66170, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66177, 66187, 66197, 
+    66207, 66216, 66227, 66236, 66245, 66255, 66265, 66277, 66289, 66300, 
+    66311, 66321, 66331, 66340, 66349, 66359, 66369, 66380, 66391, 66395, 
+    66400, 66409, 66418, 66422, 66426, 66430, 66435, 66440, 66445, 66450, 
+    66453, 66457, 0, 66461, 66464, 66467, 66471, 66475, 66480, 66484, 66488, 
+    66493, 66498, 66505, 66512, 66515, 66518, 66521, 66525, 66528, 66532, 
+    66536, 0, 66540, 66545, 66549, 66553, 0, 0, 0, 0, 66558, 66563, 66570, 
+    66575, 66580, 0, 66585, 66590, 66595, 66600, 66605, 66610, 66615, 66620, 
+    66625, 66630, 66635, 66640, 66649, 66658, 66666, 66674, 66683, 66692, 
+    66701, 66710, 66718, 66726, 66734, 66742, 66747, 66752, 66758, 66764, 
+    66770, 66776, 66784, 66792, 66798, 66804, 66810, 66816, 66822, 66828, 
+    66834, 66840, 66845, 66850, 66855, 66860, 66865, 66870, 66875, 66880, 
+    66885, 66890, 66895, 66900, 66906, 66912, 66918, 66924, 66930, 66936, 
+    66942, 66948, 66954, 66960, 66966, 66972, 66978, 66984, 66990, 66996, 
+    67002, 67008, 67014, 67020, 67026, 67032, 67038, 67044, 67050, 67056, 
+    67062, 67068, 67074, 67080, 67086, 67092, 67098, 67104, 67110, 67116, 
+    67122, 67128, 67134, 67140, 67146, 67152, 67158, 67164, 67170, 67176, 
+    67182, 67188, 67194, 67200, 67206, 67212, 67217, 67222, 67227, 67232, 
+    67237, 67242, 67247, 67252, 67257, 67262, 67267, 67272, 67278, 67284, 
+    67290, 67296, 67302, 67308, 67314, 67320, 67325, 67330, 67335, 67340, 
+    67351, 67362, 67372, 67382, 67393, 67404, 67411, 0, 0, 67418, 0, 67426, 
+    67430, 67434, 67437, 67441, 67445, 67448, 67451, 67455, 67459, 67462, 
+    67466, 67469, 67472, 67476, 67479, 67483, 67486, 67489, 67492, 67495, 
+    67498, 67501, 67504, 67507, 67510, 67513, 67516, 67520, 67524, 67528, 
+    67532, 67537, 67542, 67547, 67553, 67558, 67563, 67569, 67574, 67579, 
+    67584, 67589, 67595, 67600, 67605, 67610, 67615, 67620, 67626, 67631, 
+    67636, 67641, 67646, 67651, 67657, 67662, 67668, 67674, 67678, 67683, 
+    67687, 67691, 67695, 67700, 67705, 67710, 67716, 67721, 67726, 67732, 
+    67737, 67742, 67747, 67752, 67758, 67763, 67768, 67773, 67778, 67783, 
+    67789, 67794, 67799, 67804, 67809, 67814, 67820, 67825, 67831, 67837, 
+    67842, 67846, 67851, 67853, 67858, 67863, 67868, 67873, 67878, 67882, 
+    67888, 67893, 67898, 67903, 67908, 67913, 67918, 67923, 67929, 67935, 
+    67941, 67949, 67953, 67957, 67961, 67965, 67969, 67973, 67978, 67983, 
+    67988, 67993, 67998, 68003, 68008, 68013, 68018, 68023, 68028, 68033, 
+    68038, 68042, 68047, 68052, 68057, 68062, 68067, 68071, 68076, 68081, 
+    68086, 68091, 68095, 68100, 68105, 68110, 68115, 68119, 68124, 68129, 
+    68134, 68139, 68144, 68149, 68154, 68159, 68163, 68170, 68177, 68181, 
+    68186, 68191, 68196, 68201, 68206, 68211, 68216, 68221, 68226, 68231, 
+    68236, 68241, 68246, 68251, 68256, 68261, 68266, 68271, 68276, 68281, 
+    68286, 68291, 68296, 68301, 68306, 68311, 68316, 68321, 68326, 0, 0, 0, 
+    68331, 68335, 68340, 68344, 68349, 68354, 0, 0, 68358, 68363, 68368, 
+    68372, 68377, 68382, 0, 0, 68387, 68392, 68396, 68401, 68406, 68411, 0, 
+    0, 68416, 68421, 68426, 0, 0, 0, 68430, 68434, 68438, 68441, 68443, 
+    68447, 68451, 0, 68455, 68461, 68464, 68468, 68471, 68475, 68479, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 68483, 68489, 68495, 68501, 68507, 0, 0, 68511, 
+    68517, 68523, 68529, 68535, 68541, 68548, 68555, 68562, 68569, 68576, 
+    68583, 0, 68590, 68597, 68604, 68610, 68617, 68624, 68631, 68638, 68644, 
+    68651, 68658, 68665, 68672, 68679, 68686, 68693, 68700, 68707, 68714, 
+    68721, 68728, 68735, 68742, 68749, 68756, 68763, 0, 68770, 68777, 68784, 
+    68791, 68798, 68805, 68812, 68819, 68826, 68833, 68840, 68847, 68854, 
+    68861, 68867, 68874, 68881, 68888, 68895, 0, 68902, 68909, 0, 68916, 
+    68923, 68930, 68937, 68944, 68951, 68958, 68965, 68972, 68979, 68986, 
+    68993, 69000, 69007, 69014, 0, 0, 69020, 69025, 69030, 69035, 69040, 
+    69045, 69050, 69055, 69060, 69065, 69070, 69075, 69080, 69085, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 69090, 69097, 69104, 69111, 69118, 69125, 69132, 
+    69139, 69146, 69153, 69160, 69167, 69174, 69181, 69188, 69195, 69202, 
+    69209, 69216, 69223, 69231, 69239, 69246, 69253, 69258, 69266, 69274, 
+    69281, 69288, 69293, 69300, 69305, 69310, 69317, 69322, 69327, 69332, 
+    69340, 69345, 69350, 69357, 69362, 69367, 69374, 69381, 69386, 69391, 
+    69396, 69401, 69406, 69411, 69416, 69421, 69426, 69433, 69438, 69445, 
+    69450, 69455, 69460, 69465, 69470, 69475, 69480, 69485, 69490, 69495, 
+    69500, 69507, 69514, 69521, 69528, 69534, 69539, 69546, 69551, 69556, 
+    69565, 69572, 69581, 69588, 69593, 69598, 69606, 69611, 69616, 69621, 
+    69626, 69631, 69638, 69643, 69648, 69653, 69658, 69663, 69670, 69677, 
+    69684, 69691, 69698, 69705, 69712, 69719, 69726, 69733, 69740, 69747, 
+    69754, 69761, 69768, 69775, 69782, 69789, 69796, 69803, 69810, 69817, 
+    69824, 69831, 69838, 69845, 69852, 69859, 0, 0, 0, 0, 0, 69866, 69873, 
+    69880, 0, 0, 0, 0, 69884, 69887, 69890, 69893, 69896, 69899, 69902, 
+    69905, 69908, 69911, 69915, 69919, 69923, 69927, 69931, 69935, 69939, 
+    69943, 69947, 69953, 69958, 69963, 69969, 69975, 69981, 69987, 69993, 
+    69999, 70005, 70010, 70015, 70021, 70027, 70033, 70039, 70045, 70051, 
+    70057, 70063, 70069, 70075, 70081, 70087, 70093, 70099, 0, 0, 0, 70105, 
+    70112, 70119, 70126, 70133, 70140, 70149, 70158, 70165, 70172, 70180, 
+    70188, 70196, 70201, 70207, 70215, 70223, 70231, 70239, 70247, 70255, 
+    70265, 70275, 70285, 70295, 70303, 70311, 70319, 70329, 70339, 70349, 
+    70359, 70369, 70377, 70385, 70390, 70395, 70400, 70405, 70412, 70419, 
+    70424, 70430, 70439, 70445, 70451, 70457, 70463, 70469, 70478, 70484, 
+    70490, 70498, 70505, 70513, 70521, 70529, 70537, 70545, 70553, 70561, 
+    70569, 70577, 70582, 70590, 70595, 70600, 70604, 70608, 70612, 70616, 
+    70621, 70626, 70632, 70638, 70642, 70648, 70652, 70656, 70660, 70664, 
+    70668, 70672, 70678, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 70682, 70686, 70691, 70696, 70701, 70705, 70710, 70715, 
+    70720, 70725, 70729, 70733, 70738, 70743, 70748, 70753, 70757, 70762, 
+    70767, 70772, 70777, 70782, 70787, 70791, 70796, 70801, 70806, 70811, 
+    70816, 70821, 70826, 0, 70831, 70835, 70839, 70844, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 70849, 70854, 70859, 70864, 70869, 70874, 70879, 70884, 
+    70889, 70894, 70899, 70904, 70909, 70914, 70919, 70924, 70929, 70934, 
+    70939, 70944, 70949, 70954, 70959, 70964, 70969, 70974, 70979, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 70986, 70991, 70996, 71001, 71006, 71011, 71016, 71021, 71026, 
+    71031, 71036, 71041, 71046, 71051, 71056, 71061, 71066, 71071, 71076, 
+    71081, 71086, 71091, 71096, 71101, 71106, 71111, 71116, 71120, 71124, 
+    71128, 0, 71133, 71139, 71143, 71147, 71151, 71155, 71160, 71165, 71170, 
+    71175, 71180, 71185, 71190, 71195, 71200, 71205, 71210, 71215, 71220, 
+    71225, 71230, 71235, 71240, 71245, 71249, 71254, 71259, 71263, 71268, 
+    71273, 71278, 71283, 71288, 71293, 71298, 71303, 71308, 0, 0, 0, 0, 
+    71312, 71317, 71322, 71327, 71332, 71337, 71342, 71347, 71352, 71358, 
+    71362, 71366, 71371, 71376, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 71381, 71386, 71391, 71396, 71402, 71407, 71413, 71419, 71425, 
+    71431, 71438, 71444, 71451, 71456, 71461, 71466, 71471, 71475, 71480, 
+    71485, 71490, 71495, 71500, 71505, 71510, 71515, 71520, 71525, 71530, 
+    71535, 71540, 71545, 71550, 71555, 71560, 71565, 71570, 71575, 71580, 
+    71585, 71590, 71595, 71600, 71605, 71611, 71616, 71622, 71628, 71634, 
+    71640, 71647, 71653, 71660, 71665, 71670, 71675, 71680, 71684, 71689, 
+    71694, 71699, 71704, 71709, 71714, 71719, 71724, 71729, 71734, 71739, 
+    71744, 71749, 71754, 71759, 71764, 71769, 71774, 71779, 71784, 71789, 
+    71794, 71799, 71803, 71807, 71811, 71815, 71819, 71823, 71827, 71831, 
+    71835, 71839, 71843, 71847, 71851, 71855, 71859, 71863, 71867, 71871, 
+    71875, 71879, 71883, 71887, 71891, 71895, 71899, 71903, 71907, 71911, 
+    71915, 71919, 71923, 71927, 71931, 71935, 71939, 71943, 71947, 71951, 
+    71955, 71959, 71963, 71967, 71971, 71975, 71979, 71983, 71987, 71991, 
+    71996, 72001, 72006, 72011, 72016, 72021, 72026, 72031, 72036, 72041, 
+    72046, 72051, 72056, 72061, 72066, 72071, 72076, 72081, 72086, 72091, 
+    72095, 72099, 72103, 72107, 72111, 72115, 72119, 72124, 72129, 0, 0, 
+    72134, 72139, 72143, 72147, 72151, 72155, 72159, 72163, 72167, 72171, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72175, 72178, 72181, 72184, 72187, 
+    72190, 0, 0, 72194, 0, 72198, 72201, 72205, 72209, 72213, 72217, 72221, 
+    72225, 72229, 72233, 72237, 72240, 72244, 72248, 72252, 72256, 72260, 
+    72264, 72268, 72272, 72276, 72280, 72284, 72288, 72292, 72296, 72300, 
+    72304, 72308, 72312, 72316, 72320, 72324, 72328, 72332, 72336, 72340, 
+    72344, 72348, 72351, 72355, 72359, 72363, 72367, 0, 72371, 72375, 0, 0, 
+    0, 72379, 0, 0, 72383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    72387, 72390, 72394, 72398, 0, 72403, 72407, 0, 0, 0, 0, 0, 72411, 72416, 
+    72422, 72426, 72430, 72433, 72437, 72441, 0, 72445, 72449, 72453, 0, 
+    72457, 72461, 72465, 72469, 72473, 72477, 72481, 72485, 72489, 72493, 
+    72497, 72501, 72505, 72509, 72513, 72517, 72520, 72523, 72527, 72531, 
+    72535, 72539, 72543, 72547, 72551, 72554, 72558, 0, 0, 0, 0, 72562, 
+    72567, 72571, 0, 0, 0, 0, 72575, 72578, 72581, 72584, 72587, 72590, 
+    72594, 72598, 72604, 0, 0, 0, 0, 0, 0, 0, 0, 72610, 72615, 72621, 72626, 
+    72632, 72637, 72642, 72647, 72653, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 72658, 72663, 72668, 72673, 72680, 72687, 72694, 72701, 72706, 
+    72711, 72716, 72721, 72728, 72733, 72740, 72747, 72752, 72757, 72762, 
+    72769, 72774, 72779, 72786, 72793, 72798, 72803, 72808, 72815, 72822, 
+    72829, 72834, 72839, 72846, 72853, 72860, 72867, 72872, 72877, 72882, 
+    72889, 72894, 72899, 72904, 72911, 72920, 72927, 72932, 72937, 72942, 
+    72947, 72952, 72957, 72966, 72973, 72978, 72985, 72992, 72997, 73002, 
+    73007, 73014, 73019, 73026, 73033, 73038, 73043, 73048, 73055, 73062, 
+    73067, 73072, 73079, 73086, 73093, 73098, 73103, 73108, 73113, 73120, 
+    73129, 73138, 73143, 73150, 73159, 73164, 73169, 73174, 73179, 73186, 
+    73193, 73200, 73207, 73212, 73217, 73222, 73229, 73236, 73243, 73248, 
+    73253, 73260, 73265, 73272, 73277, 73284, 73289, 73296, 73303, 73308, 
+    73313, 73318, 73323, 73328, 73333, 73338, 73343, 73348, 73355, 73362, 
+    73369, 73376, 73383, 73392, 73397, 73402, 73409, 73416, 73421, 73428, 
+    73435, 73442, 73449, 73456, 73463, 73468, 73473, 73478, 73483, 73488, 
+    73497, 73506, 73515, 73524, 73533, 73542, 73551, 73560, 73565, 73576, 
+    73587, 73596, 73601, 73606, 73611, 73616, 73625, 73632, 73639, 73646, 
+    73653, 73660, 73667, 73676, 73685, 73696, 73705, 73716, 73725, 73732, 
+    73741, 73752, 73761, 73770, 73779, 73788, 73795, 73802, 73809, 73818, 
+    73827, 73838, 73847, 73856, 73867, 73872, 73877, 73888, 73897, 73906, 
+    73915, 73924, 73935, 73944, 73953, 73964, 73975, 73986, 73997, 74008, 
+    74019, 74026, 74033, 74040, 74047, 74057, 74066, 74073, 74080, 74087, 
+    74098, 74109, 74120, 74131, 74142, 74153, 74164, 74175, 74182, 74189, 
+    74198, 74207, 74214, 74221, 74228, 74237, 74246, 74255, 74262, 74271, 
+    74280, 74289, 74296, 74303, 74308, 74315, 74322, 74329, 74336, 74343, 
+    74350, 74357, 74366, 74375, 74384, 74393, 74400, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 74409, 74415, 74420, 74425, 74432, 74438, 74444, 74450, 74456, 
+    74462, 74468, 74474, 74478, 74482, 74488, 74494, 74500, 74504, 74509, 
+    74514, 74518, 74522, 74525, 74531, 74537, 74543, 74549, 74555, 74561, 
+    74567, 74573, 74579, 74589, 74599, 74605, 74611, 74621, 74631, 74637, 0, 
+    0, 0, 74643, 74648, 74653, 74659, 74665, 74671, 74677, 74683, 74689, 
+    74696, 74703, 74709, 74715, 74721, 74727, 74733, 74739, 74745, 74751, 
+    74756, 74762, 74768, 74774, 74780, 74786, 74796, 74802, 74808, 74815, 
+    74822, 74829, 74838, 74847, 74856, 74865, 74874, 74883, 74892, 74901, 
+    74911, 74921, 74929, 74937, 74946, 74955, 74961, 74967, 74973, 74979, 
+    74987, 74995, 74999, 75005, 75010, 75016, 75022, 75028, 75034, 75040, 
+    75050, 75055, 75062, 75067, 75072, 75077, 75083, 75089, 75095, 75102, 
+    75107, 75112, 75117, 75122, 75127, 75133, 75139, 75145, 75151, 75157, 
+    75163, 75169, 75175, 75180, 75185, 75190, 75195, 75200, 75205, 75210, 
+    75215, 75221, 75227, 75232, 75237, 75242, 75247, 75252, 75258, 75265, 
+    75269, 75273, 75277, 75281, 75285, 75289, 75293, 75297, 75305, 75315, 
+    75319, 75323, 75329, 75335, 75341, 75347, 75353, 75359, 75365, 75371, 
+    75377, 75383, 75389, 75395, 75401, 75407, 75411, 75415, 75422, 75428, 
+    75434, 75440, 75445, 75452, 75457, 75463, 75469, 75475, 75481, 75486, 
+    75490, 75496, 75500, 75504, 75508, 75514, 75520, 75524, 75530, 75536, 
+    75542, 75548, 75554, 75562, 75570, 75576, 75582, 75588, 75594, 75606, 
+    75618, 75632, 75644, 75656, 75670, 75684, 75698, 75702, 75710, 75718, 
+    75722, 75726, 75730, 75734, 75738, 75742, 75746, 75750, 75756, 75762, 
+    75768, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 75774, 75780, 75786, 75792, 75798, 
+    75804, 75810, 75816, 75822, 75828, 75834, 75840, 75846, 75852, 75858, 
+    75864, 75870, 75876, 75882, 75888, 75894, 75900, 75906, 75912, 75918, 
+    75924, 75930, 75936, 75942, 75948, 75954, 75960, 75966, 75972, 75978, 
+    75984, 75990, 75996, 76002, 76008, 76014, 76020, 76026, 76032, 76038, 
+    76044, 76050, 76056, 76062, 76068, 76074, 76080, 76086, 76092, 76098, 
+    76104, 76110, 76116, 76122, 76128, 76134, 76140, 76146, 76152, 76158, 
+    76164, 76170, 76175, 76180, 76185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76189, 
+    76194, 76201, 76208, 76215, 76222, 76227, 76231, 76237, 76241, 76245, 
+    76251, 76255, 76259, 76263, 76269, 76276, 76280, 76284, 76288, 76292, 
+    76296, 76300, 76306, 76310, 76314, 76318, 76322, 76326, 76330, 76334, 
+    76338, 76342, 76346, 76350, 76354, 76359, 76363, 76367, 76371, 76375, 
+    76379, 76383, 76387, 76391, 76395, 76402, 76406, 76413, 76417, 76421, 
+    76425, 76429, 76433, 76437, 76441, 76448, 76452, 76456, 76460, 76464, 
+    76468, 76474, 76478, 76484, 76488, 76492, 76496, 76500, 76504, 76508, 
+    76512, 76516, 76520, 76524, 76528, 76532, 76536, 76540, 76544, 76548, 
+    76552, 76556, 76560, 76568, 76572, 76576, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 76580, 76584, 76588, 76593, 76597, 76601, 76606, 
+    76610, 76614, 76618, 76622, 76627, 76631, 76635, 76639, 76643, 76647, 
+    76652, 76656, 76660, 76664, 76668, 76672, 76677, 76681, 76686, 76691, 
+    76695, 76699, 76704, 76708, 76712, 76717, 76721, 76725, 76729, 76733, 
+    76738, 76742, 76746, 76750, 76754, 76758, 76763, 76767, 76771, 76775, 
+    76779, 76783, 76788, 76792, 76797, 76802, 76806, 76810, 76815, 76819, 
+    76823, 76828, 76832, 76836, 76840, 76844, 76849, 76853, 76857, 76861, 
+    76865, 76869, 76874, 76878, 76882, 76886, 76890, 76894, 76899, 76903, 
+    76908, 76913, 76917, 76921, 76926, 76930, 76934, 76939, 0, 76943, 76947, 
+    76951, 76956, 76960, 76964, 76968, 76972, 76976, 76981, 76985, 76989, 
+    76993, 76997, 77001, 77006, 77010, 77015, 77020, 77025, 77030, 77036, 
+    77041, 77046, 77052, 77057, 77062, 77067, 77072, 77078, 77083, 77088, 
+    77093, 77098, 77103, 77109, 77114, 77119, 77124, 77129, 77134, 77140, 
+    77145, 77151, 77157, 77162, 77167, 77173, 77178, 77183, 77189, 77194, 
+    77199, 77204, 77209, 77215, 77220, 77225, 77230, 77235, 77240, 77246, 
+    77251, 77256, 77261, 77266, 77271, 77277, 77282, 77288, 77294, 0, 77298, 
+    77303, 0, 0, 77307, 0, 0, 77311, 77315, 0, 0, 77320, 77324, 77328, 77332, 
+    0, 77337, 77341, 77345, 77349, 77353, 77358, 77362, 77367, 77372, 77376, 
+    77380, 77385, 0, 77389, 0, 77394, 77398, 77402, 77406, 77411, 77415, 
+    77419, 0, 77423, 77427, 77432, 77436, 77440, 77444, 77448, 77452, 77457, 
+    77461, 77466, 77471, 77476, 77481, 77487, 77492, 77497, 77503, 77508, 
+    77513, 77518, 77523, 77529, 77534, 77539, 77544, 77549, 77554, 77560, 
+    77565, 77570, 77575, 77580, 77585, 77591, 77596, 77602, 77608, 77613, 
+    77618, 77624, 77629, 77634, 77640, 77645, 77650, 77655, 77660, 77666, 
+    77671, 77676, 77681, 77686, 77691, 77697, 77702, 77707, 77712, 77717, 
+    77722, 77728, 77733, 77739, 77745, 77749, 0, 77753, 77757, 77761, 77766, 
+    0, 0, 77770, 77774, 77779, 77783, 77787, 77791, 77795, 77799, 0, 77804, 
+    77808, 77812, 77816, 77820, 77825, 77829, 0, 77834, 77838, 77842, 77847, 
+    77851, 77855, 77860, 77864, 77868, 77872, 77876, 77881, 77885, 77889, 
+    77893, 77897, 77901, 77906, 77910, 77914, 77918, 77922, 77926, 77931, 
+    77935, 77940, 77945, 77949, 0, 77953, 77957, 77961, 77966, 0, 77970, 
+    77974, 77978, 77983, 77987, 0, 77991, 0, 0, 0, 77995, 77999, 78003, 
+    78007, 78011, 78016, 78020, 0, 78025, 78029, 78033, 78038, 78042, 78046, 
+    78051, 78055, 78059, 78063, 78067, 78072, 78076, 78080, 78084, 78088, 
+    78092, 78097, 78101, 78105, 78109, 78113, 78117, 78122, 78126, 78131, 
+    78136, 78141, 78146, 78152, 78157, 78162, 78168, 78173, 78178, 78183, 
+    78188, 78194, 78199, 78204, 78209, 78214, 78219, 78225, 78230, 78235, 
+    78240, 78245, 78250, 78256, 78261, 78267, 78273, 78278, 78283, 78289, 
+    78294, 78299, 78305, 78310, 78315, 78320, 78325, 78331, 78336, 78341, 
+    78346, 78351, 78356, 78362, 78367, 78372, 78377, 78382, 78387, 78393, 
+    78398, 78404, 78410, 78414, 78418, 78423, 78427, 78431, 78436, 78440, 
+    78444, 78448, 78452, 78457, 78461, 78465, 78469, 78473, 78477, 78482, 
+    78486, 78490, 78494, 78498, 78502, 78507, 78511, 78516, 78521, 78525, 
+    78529, 78534, 78538, 78542, 78547, 78551, 78555, 78559, 78563, 78568, 
+    78572, 78576, 78580, 78584, 78588, 78593, 78597, 78601, 78605, 78609, 
+    78613, 78618, 78622, 78627, 78632, 78637, 78642, 78648, 78653, 78658, 
+    78664, 78669, 78674, 78679, 78684, 78690, 78695, 78700, 78705, 78710, 
+    78715, 78721, 78726, 78731, 78736, 78741, 78746, 78752, 78757, 78763, 
+    78769, 78774, 78779, 78785, 78790, 78795, 78801, 78806, 78811, 78816, 
+    78821, 78827, 78832, 78837, 78842, 78847, 78852, 78858, 78863, 78868, 
+    78873, 78878, 78883, 78889, 78894, 78900, 78906, 78911, 78916, 78922, 
+    78927, 78932, 78938, 78943, 78948, 78953, 78958, 78964, 78969, 78974, 
+    78979, 78984, 78989, 78995, 79000, 79005, 79010, 79015, 79020, 79026, 
+    79031, 79037, 79043, 79048, 79053, 79059, 79064, 79069, 79075, 79080, 
+    79085, 79090, 79095, 79101, 79106, 79111, 79116, 79121, 79126, 79132, 
+    79137, 79142, 79147, 79152, 79157, 79163, 79168, 79174, 79180, 79186, 
+    79192, 79199, 79205, 79211, 79218, 79224, 79230, 79236, 79242, 79249, 
+    79255, 79261, 79267, 79273, 79279, 79286, 79292, 79298, 79304, 79310, 
+    79316, 79323, 79329, 79336, 79343, 79349, 79355, 79362, 79368, 79374, 
+    79381, 79387, 79393, 79399, 79405, 79412, 79418, 79424, 79430, 79436, 
+    79442, 79449, 79455, 79461, 79467, 79473, 79479, 79486, 79492, 79499, 
+    79506, 79510, 79514, 79519, 79523, 79527, 79532, 79536, 79540, 79544, 
+    79548, 79553, 79557, 79561, 79565, 79569, 79573, 79578, 79582, 79586, 
+    79590, 79594, 79598, 79603, 79607, 79612, 79617, 79621, 79625, 79630, 
+    79634, 79638, 79643, 79647, 79651, 79655, 79659, 79664, 79668, 79672, 
+    79676, 79680, 79684, 79689, 79693, 79697, 79701, 79705, 79709, 79714, 
+    79718, 79723, 79728, 79734, 0, 0, 79740, 79745, 79750, 79755, 79760, 
+    79765, 79770, 79775, 79780, 79785, 79790, 79795, 79800, 79805, 79810, 
+    79815, 79820, 79825, 79831, 79836, 79841, 79846, 79851, 79856, 79861, 
+    79866, 79870, 79875, 79880, 79885, 79890, 79895, 79900, 79905, 79910, 
+    79915, 79920, 79925, 79930, 79935, 79940, 79945, 79950, 79955, 79961, 
+    79966, 79971, 79976, 79981, 79986, 79991, 79996, 80002, 80007, 80012, 
+    80017, 80022, 80027, 80032, 80037, 80042, 80047, 80052, 80057, 80062, 
+    80067, 80072, 80077, 80082, 80087, 80092, 80097, 80102, 80107, 80112, 
+    80117, 80123, 80128, 80133, 80138, 80143, 80148, 80153, 80158, 80162, 
+    80167, 80172, 80177, 80182, 80187, 80192, 80197, 80202, 80207, 80212, 
+    80217, 80222, 80227, 80232, 80237, 80242, 80247, 80253, 80258, 80263, 
+    80268, 80273, 80278, 80283, 80288, 80294, 80299, 80304, 80309, 80314, 
+    80319, 80324, 80330, 80336, 80342, 80348, 80354, 80360, 80366, 80372, 
+    80378, 80384, 80390, 80396, 80402, 80408, 80414, 80420, 80426, 80433, 
+    80439, 80445, 80451, 80457, 80463, 80469, 80475, 80480, 80486, 80492, 
+    80498, 80504, 80510, 80516, 80522, 80528, 80534, 80540, 80546, 80552, 
+    80558, 80564, 80570, 80576, 80582, 80589, 80595, 80601, 80607, 80613, 
+    80619, 80625, 80631, 80638, 80644, 80650, 80656, 80662, 80668, 80674, 
+    80680, 80686, 80692, 80698, 80704, 80710, 80716, 80722, 80728, 80734, 
+    80740, 80746, 80752, 80758, 80764, 80770, 80776, 80783, 80789, 80795, 
+    80801, 80807, 80813, 80819, 80825, 80830, 80836, 80842, 80848, 80854, 
+    80860, 80866, 80872, 80878, 80884, 80890, 80896, 80902, 80908, 80914, 
+    80920, 80926, 80932, 80939, 80945, 80951, 80957, 80963, 80969, 80975, 
+    80981, 80988, 80994, 81000, 81006, 81012, 81018, 81024, 81031, 81038, 
+    81045, 81052, 81059, 81066, 81073, 81080, 81087, 81094, 81101, 81108, 
+    81115, 81122, 81129, 81136, 81143, 81151, 81158, 81165, 81172, 81179, 
+    81186, 81193, 81200, 81206, 81213, 81220, 81227, 81234, 81241, 81248, 
+    81255, 81262, 81269, 81276, 81283, 81290, 81297, 81304, 81311, 81318, 
+    81325, 81333, 81340, 81347, 81354, 81361, 81368, 81375, 81382, 81390, 
+    81397, 81404, 81411, 81418, 81425, 0, 0, 0, 0, 81432, 81437, 81441, 
+    81445, 81449, 81453, 81457, 81461, 81465, 81469, 81473, 81478, 81482, 
+    81486, 81490, 81494, 81498, 81502, 81506, 81510, 81514, 81519, 81523, 
+    81527, 81531, 81535, 81539, 81543, 81547, 81551, 81555, 81561, 81566, 
+    81571, 81576, 81581, 81586, 81591, 81596, 81601, 81606, 81611, 81615, 
+    81619, 81623, 81627, 81631, 81635, 81639, 81643, 81647, 81651, 81655, 
+    81659, 81663, 81667, 81671, 81675, 81679, 81683, 81687, 81691, 81695, 
+    81699, 81703, 81707, 81711, 81715, 81719, 81723, 81727, 81731, 81735, 
+    81739, 81743, 81747, 81751, 81755, 81759, 81763, 81767, 81771, 81775, 
+    81779, 81783, 81787, 81791, 81795, 81799, 81803, 81807, 81811, 81815, 
+    81819, 81823, 81827, 81831, 81835, 81839, 81843, 81847, 81851, 81855, 
+    81859, 81863, 81867, 81871, 81875, 81879, 81883, 81887, 81891, 81895, 
+    81899, 81903, 81907, 81911, 81915, 81919, 81923, 81927, 81931, 81935, 
+    81939, 81943, 81947, 81951, 81955, 81959, 81963, 81967, 81971, 81975, 
+    81979, 81983, 81987, 81991, 81995, 81999, 82003, 82007, 82011, 82015, 
+    82019, 82023, 82027, 82031, 82035, 82039, 82043, 82047, 82051, 82055, 
+    82059, 82063, 82067, 82071, 82075, 82079, 82083, 82087, 82091, 82095, 
+    82099, 82103, 82107, 82111, 82115, 82119, 82123, 82127, 82131, 82135, 
+    82139, 82143, 82147, 82151, 82155, 82159, 82163, 82167, 82171, 82175, 
+    82179, 82183, 82187, 82191, 82195, 82199, 82203, 82207, 82211, 82215, 
+    82219, 82223, 82227, 82231, 82235, 82239, 82243, 82247, 82251, 82255, 
+    82259, 82263, 82267, 82271, 82275, 82279, 82283, 82287, 82291, 82295, 
+    82299, 82303, 82307, 82311, 82315, 82319, 82323, 82327, 82331, 82335, 
+    82339, 82343, 82347, 82351, 82355, 82359, 82363, 82367, 82371, 82375, 
+    82379, 82383, 82387, 82391, 82395, 82399, 82403, 82407, 82411, 82415, 
+    82419, 82423, 82427, 82431, 82435, 82439, 82443, 82447, 82451, 82455, 
+    82459, 82463, 82467, 82471, 82475, 82479, 82483, 82487, 82491, 82495, 
+    82499, 82503, 82507, 82511, 82515, 82519, 82523, 82527, 82531, 82535, 
+    82539, 82543, 82547, 82551, 82555, 82559, 82563, 82567, 82571, 82575, 
+    82579, 82583, 82587, 82591, 82595, 82599, 82603, 82607, 82611, 82615, 
+    82619, 82623, 82627, 82631, 82635, 82639, 82643, 82647, 82651, 82655, 
+    82659, 82663, 82667, 82671, 82675, 82679, 82683, 82687, 82691, 82695, 
+    82699, 82703, 82707, 82711, 82715, 82719, 82723, 82727, 82731, 82735, 
+    82739, 82743, 82747, 82751, 82755, 82759, 82763, 82767, 82771, 82775, 
+    82779, 82783, 82787, 82791, 82795, 82799, 82803, 82807, 82811, 82815, 
+    82819, 82823, 82827, 82831, 82835, 82839, 82843, 82847, 82851, 82855, 
+    82859, 82863, 82867, 82871, 82875, 82879, 82883, 82887, 82891, 82895, 
+    82899, 82903, 82907, 82911, 82915, 82919, 82923, 82927, 82931, 82935, 
+    82939, 82943, 82947, 82951, 82955, 82959, 82963, 82967, 82971, 82975, 
+    82979, 82983, 82987, 82991, 82995, 82999, 83003, 83007, 83011, 83015, 
+    83019, 83023, 83027, 83031, 83035, 83039, 83043, 83047, 83051, 83055, 
+    83059, 83063, 83067, 83071, 83075, 83079, 83083, 83087, 83091, 83095, 
+    83099, 83103, 83107, 83111, 83115, 83119, 83123, 83127, 83131, 83135, 
+    83139, 83143, 83147, 83151, 83155, 83159, 83163, 83167, 83171, 83175, 
+    83179, 83183, 83187, 83191, 83195, 83199, 83203, 83207, 83211, 83215, 
+    83219, 83223, 83227, 83231, 83235, 83239, 83243, 83247, 83251, 83255, 
+    83259, 83263, 83267, 83271, 83275, 83279, 83283, 83287, 83291, 83295, 
+    83299, 83303, 83307, 83311, 83315, 83319, 83323, 83327, 83331, 83335, 
+    83339, 83343, 83347, 83351, 83355, 83359, 83363, 83367, 83371, 83375, 
+    83379, 83383, 83387, 83391, 83395, 83399, 83403, 83407, 83411, 83415, 
+    83419, 83423, 83427, 83431, 83435, 83439, 83443, 83447, 83451, 83455, 
+    83459, 83463, 83467, 83471, 83475, 83479, 83483, 83487, 83491, 83495, 
+    83499, 83503, 83507, 83511, 83515, 83519, 83523, 83527, 83531, 83535, 
+    83539, 83543, 83547, 83551, 83555, 83559, 83563, 83567, 83571, 83575, 
+    83579, 83583, 83587, 83591, 83595, 83599, 83603, 83607, 83611, 83615, 
+    83619, 83623, 83627, 83631, 83635, 83639, 83643, 83647, 83651, 83655, 
+    83659, 83663, 83667, 83671, 83675, 83679, 83683, 83687, 83691, 83695, 
+    83699, 83703, 83707, 83711, 83715, 83719, 83723, 83727, 83731, 83735, 
+    83739, 83743, 83747, 83751, 83755, 83759, 83763, 83767, 83771, 83775, 
+    83779, 83783, 83787, 83791, 83795, 83799, 83803, 83807, 83811, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    83815, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 83819, 83822, 83826, 83830, 83833, 83837, 83841, 
+    83844, 83847, 83851, 83855, 83858, 83862, 83865, 83868, 83872, 83875, 
+    83879, 83882, 83885, 83888, 83891, 83894, 83897, 83900, 83903, 83906, 
+    83909, 83912, 83916, 83920, 83924, 83928, 83933, 83938, 83943, 83949, 
+    83954, 83959, 83965, 83970, 83975, 83980, 83985, 83991, 83996, 84001, 
+    84006, 84011, 84016, 84022, 84027, 84032, 84037, 84042, 84047, 84053, 
+    84058, 84064, 84070, 84074, 84079, 84083, 84087, 84091, 84096, 84101, 
+    84106, 84112, 84117, 84122, 84128, 84133, 84138, 84143, 84148, 84154, 
+    84159, 84164, 84169, 84174, 84179, 84185, 84190, 84195, 84200, 84205, 
+    84210, 84216, 84221, 84227, 84233, 84238, 84242, 84247, 84249, 84253, 
+    84256, 84259, 84262, 84265, 84268, 84271, 84274, 84277, 84280, 84283, 
+    84286, 84289, 84292, 84295, 84298, 84301, 84304, 84307, 84310, 84313, 
+    84316, 84319, 84322, 84325, 84328, 84331, 84334, 84337, 84340, 84343, 
+    84346, 84349, 84352, 84355, 84358, 84361, 84364, 84367, 84370, 84373, 
+    84376, 84379, 84382, 84385, 84388, 84391, 84394, 84397, 84400, 84403, 
+    84406, 84409, 84412, 84415, 84418, 84421, 84424, 84427, 84430, 84433, 
+    84436, 84439, 84442, 84445, 84448, 84451, 84454, 84457, 84460, 84463, 
+    84466, 84469, 84472, 84475, 84478, 84481, 84484, 84487, 84490, 84493, 
+    84496, 84499, 84502, 84505, 84508, 84511, 84514, 84517, 84520, 84523, 
+    84526, 84529, 84532, 84535, 84538, 84541, 84544, 84547, 84550, 84553, 
+    84556, 84559, 84562, 84565, 84568, 84571, 84574, 84577, 84580, 84583, 
+    84586, 84589, 84592, 84595, 84598, 84601, 84604, 84607, 84610, 84613, 
+    84616, 84619, 84622, 84625, 84628, 84631, 84634, 84637, 84640, 84643, 
+    84646, 84649, 84652, 84655, 84658, 84661, 84664, 84667, 84670, 84673, 
+    84676, 84679, 84682, 84685, 84688, 84691, 84694, 84697, 84700, 84703, 
+    84706, 84709, 84712, 84715, 84718, 84721, 84724, 84727, 84730, 84733, 
+    84736, 84739, 84742, 84745, 84748, 84751, 84754, 84757, 84760, 84763, 
+    84766, 84769, 84772, 84775, 84778, 84781, 84784, 84787, 84790, 84793, 
+    84796, 84799, 84802, 84805, 84808, 84811, 84814, 84817, 84820, 84823, 
+    84826, 84829, 84832, 84835, 84838, 84841, 84844, 84847, 84850, 84853, 
+    84856, 84859, 84862, 84865, 84868, 84871, 84874, 84877, 84880, 84883, 
+    84886, 84889, 84892, 84895, 84898, 84901, 84904, 84907, 84910, 84913, 
+    84916, 84919, 84922, 84925, 84928, 84931, 84934, 84937, 84940, 84943, 
+    84946, 84949, 84952, 84955, 84958, 84961, 84964, 84967, 84970, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+};
+
+/* name->code dictionary */
+static unsigned int code_hash[] = {
+    120470, 4851, 118860, 43024, 0, 66306, 7929, 64584, 9518, 6609, 120203, 
+    42166, 11319, 1097, 917856, 12064, 41730, 596, 8570, 66517, 12650, 8651, 
+    41728, 12738, 41835, 12995, 41202, 1373, 0, 11403, 5816, 119067, 64810, 
+    1000, 120676, 11951, 41140, 1209, 9717, 195073, 118972, 1073, 194579, 
+    65470, 41138, 8851, 917962, 64500, 12167, 1115, 8874, 9794, 194660, 
+    917846, 120753, 12237, 3966, 41603, 6587, 9290, 65222, 41600, 9231, 
+    120183, 2959, 1457, 3535, 195021, 42179, 63860, 41538, 6671, 8618, 42175, 
+    3404, 64661, 5148, 41737, 1759, 917565, 119974, 65257, 118949, 12290, 
+    66577, 120019, 9386, 12312, 10151, 8205, 118818, 5131, 917899, 9627, 
+    65930, 9834, 3055, 9852, 1944, 1248, 10148, 11398, 119990, 64543, 12701, 
+    119204, 9348, 603, 917851, 65327, 119998, 63781, 65111, 3350, 66576, 
+    64318, 917828, 8154, 3390, 119985, 41817, 119956, 64603, 66328, 65668, 
+    120013, 3400, 120015, 6041, 65020, 41899, 66446, 8002, 8562, 4364, 63991, 
+    4043, 8712, 64134, 7813, 11297, 120759, 10124, 7526, 8601, 6069, 10143, 
+    4814, 12041, 1418, 10885, 12673, 118961, 65307, 9660, 2764, 13012, 4571, 
+    5704, 120483, 119946, 12078, 2970, 5457, 5440, 8857, 917898, 118803, 
+    2843, 5355, 41599, 118883, 119004, 5194, 11657, 119362, 3486, 65324, 
+    12472, 10123, 65167, 194738, 10717, 8714, 2637, 64629, 8460, 10682, 8476, 
+    10602, 800, 917613, 66506, 65673, 1019, 64335, 11631, 8465, 12289, 64144, 
+    762, 13172, 10681, 8488, 5412, 10906, 1353, 194636, 41351, 41823, 5828, 
+    8206, 120166, 8933, 1601, 9072, 858, 13302, 12458, 120774, 8090, 5418, 
+    12452, 120081, 9483, 3351, 120602, 64510, 10817, 917939, 41539, 2750, 
+    11570, 556, 41855, 41246, 65564, 11277, 65892, 2760, 10620, 12195, 7608, 
+    65809, 64156, 5498, 9998, 41536, 64151, 63876, 9242, 3459, 8997, 11787, 
+    64153, 64152, 65734, 120184, 4839, 6615, 68115, 1874, 119016, 4975, 4635, 
+    295, 64124, 64123, 6050, 64898, 917804, 7600, 7590, 63903, 9036, 63901, 
+    19941, 3971, 66609, 119195, 2952, 64116, 6287, 8031, 2725, 63899, 63898, 
+    5482, 667, 12332, 1177, 6086, 12322, 11027, 5172, 41617, 64102, 7859, 
+    1945, 64099, 9815, 10453, 19934, 63882, 7997, 8555, 63878, 63877, 8705, 
+    64097, 64096, 9571, 528, 9172, 120170, 9828, 41723, 63875, 41578, 11460, 
+    7432, 63854, 41913, 9056, 195005, 6188, 64593, 6155, 10806, 446, 6494, 
+    64065, 41318, 63850, 63, 41878, 63846, 2972, 9455, 6639, 64064, 63849, 
+    63848, 63847, 1176, 120649, 8302, 8276, 63842, 4178, 13208, 13188, 10948, 
+    10041, 8105, 4333, 9855, 64112, 1105, 4180, 5388, 12094, 65879, 65197, 
+    7714, 63890, 5443, 7768, 5538, 9987, 194803, 118932, 1678, 917611, 552, 
+    9560, 64077, 10785, 8996, 4992, 4471, 12080, 9159, 10171, 63861, 10486, 
+    5540, 63858, 41781, 281, 63863, 12075, 42041, 64646, 5174, 120337, 3589, 
+    1388, 3123, 43018, 1077, 13272, 8408, 11531, 120387, 43042, 9223, 195029, 
+    65318, 42773, 119117, 42105, 1116, 13274, 43049, 3663, 43050, 1112, 
+    119122, 8686, 8881, 5334, 42108, 119937, 13087, 64091, 9322, 194701, 
+    6509, 64095, 5327, 8111, 19907, 41877, 3478, 7583, 6199, 2903, 195093, 
+    3001, 1158, 8745, 11329, 4741, 63866, 4737, 4370, 4846, 41616, 4742, 
+    41335, 4118, 1797, 64600, 805, 65691, 46, 12070, 8760, 298, 65452, 12212, 
+    120123, 65174, 63836, 32, 5965, 65469, 11495, 12225, 3665, 63837, 64793, 
+    65330, 41336, 4305, 66360, 8083, 917590, 119333, 63821, 4412, 63819, 
+    63818, 12244, 5227, 9047, 12283, 4181, 4752, 9029, 4634, 560, 5643, 8226, 
+    6181, 63812, 13247, 63810, 63790, 3639, 63815, 10122, 63813, 6047, 7937, 
+    63961, 780, 206, 42008, 4936, 7498, 1098, 19923, 120205, 1093, 9882, 
+    3016, 4869, 63932, 917554, 63929, 3546, 1605, 65058, 6182, 65566, 13176, 
+    8400, 11343, 63920, 917550, 5471, 2984, 5314, 9287, 5473, 44, 194667, 
+    194682, 13169, 5290, 5283, 1695, 63827, 1088, 5961, 1900, 1084, 1085, 
+    63829, 1083, 6581, 5576, 917793, 64184, 4263, 1092, 4754, 8947, 5252, 
+    120431, 65253, 64183, 917819, 7908, 11011, 120390, 6579, 194878, 2965, 
+    119177, 8808, 64710, 1089, 7761, 41641, 42119, 12355, 63889, 940, 5787, 
+    9992, 63938, 5057, 64679, 12463, 2994, 5054, 41694, 65794, 9664, 41026, 
+    1437, 9399, 658, 3497, 12920, 7486, 660, 5060, 666, 9022, 5532, 118941, 
+    5533, 5059, 4727, 6118, 222, 979, 3884, 12459, 7488, 5773, 978, 120163, 
+    7489, 41619, 10239, 12465, 917761, 118902, 64411, 13271, 1707, 120319, 
+    12461, 63895, 63949, 63948, 63947, 3376, 6038, 63943, 63942, 63894, 
+    65323, 194944, 65508, 7776, 64278, 2379, 8703, 63893, 64668, 801, 8125, 
+    1690, 63919, 63918, 63917, 2369, 65042, 12844, 65800, 119235, 5486, 2334, 
+    64893, 4463, 5483, 10207, 917608, 2367, 5484, 63909, 264, 2375, 8060, 
+    6194, 5485, 1844, 64035, 9061, 5534, 10672, 4502, 13178, 253, 118819, 
+    1823, 8800, 10746, 7912, 0, 10256, 6192, 194946, 42771, 11576, 119616, 
+    725, 4550, 13257, 120800, 118944, 12892, 917868, 64087, 41775, 8413, 
+    194805, 120146, 5693, 10397, 120440, 13209, 5074, 5073, 120438, 8983, 
+    120525, 41132, 66586, 5072, 19964, 6198, 11614, 65731, 196, 13206, 3111, 
+    64725, 4929, 12445, 0, 119074, 194646, 66606, 6628, 1076, 11294, 1436, 
+    4934, 64415, 41323, 7543, 195098, 12807, 63907, 63906, 4548, 4329, 6113, 
+    4979, 3048, 4423, 41320, 194963, 10515, 6218, 8971, 5071, 65583, 3642, 
+    1430, 5070, 10042, 118835, 3987, 5068, 7619, 3255, 3493, 917952, 8905, 
+    10735, 120134, 41635, 3378, 4531, 1245, 9105, 66311, 4921, 4481, 3771, 
+    65544, 2710, 41693, 64084, 41724, 64709, 41682, 41690, 120120, 4922, 325, 
+    992, 120305, 4925, 1628, 0, 9526, 4920, 65262, 948, 10783, 120208, 4930, 
+    917570, 4462, 194855, 4933, 5339, 6115, 65359, 4928, 917603, 4457, 
+    120506, 65290, 42163, 722, 5684, 8678, 12637, 65624, 5689, 8753, 1509, 
+    120180, 5468, 9511, 194968, 65183, 1672, 6205, 5832, 6310, 5686, 194931, 
+    64800, 64536, 120713, 41475, 50, 917926, 9871, 120115, 1679, 11982, 
+    10759, 41883, 66468, 3183, 13259, 4448, 119225, 401, 6427, 64930, 64763, 
+    5761, 342, 8553, 1151, 8143, 67589, 11983, 64384, 624, 65443, 42014, 
+    119630, 5078, 12501, 5656, 120168, 5076, 118870, 8812, 119170, 11538, 
+    685, 9025, 1524, 8003, 66467, 5539, 8087, 12971, 120101, 9894, 1252, 
+    12925, 194611, 4636, 194615, 118985, 8053, 9732, 917983, 5080, 13121, 
+    5036, 5035, 118968, 12277, 65904, 194780, 8074, 275, 12158, 194594, 8741, 
+    4432, 120610, 5033, 120668, 64605, 4836, 3888, 473, 65584, 8502, 120250, 
+    1873, 1087, 12499, 917808, 63844, 12345, 3601, 1922, 6409, 64965, 65422, 
+    12502, 120683, 12505, 66321, 66477, 9489, 119140, 3432, 4384, 63964, 
+    6094, 41530, 8815, 12851, 64753, 119950, 1676, 1154, 3857, 1205, 5030, 
+    917917, 13100, 12958, 10519, 9622, 194674, 64723, 4421, 10592, 0, 495, 
+    119007, 10544, 7983, 118882, 10749, 64186, 8494, 11980, 10979, 41710, 
+    947, 64187, 437, 41709, 10969, 65894, 7613, 9465, 13290, 4795, 4997, 
+    64306, 8826, 11486, 4999, 120611, 8626, 4590, 4711, 120255, 65037, 2739, 
+    19942, 8044, 40964, 251, 12686, 7895, 4395, 119927, 119926, 119929, 1779, 
+    6600, 6601, 41543, 5325, 642, 65830, 8880, 7685, 120071, 66729, 6234, 
+    13229, 625, 8187, 9990, 1113, 194643, 7915, 1104, 120176, 8179, 10655, 
+    195043, 9316, 10980, 2489, 1082, 8150, 1359, 194645, 194726, 119304, 
+    119555, 5042, 5041, 42769, 12084, 8049, 7509, 194806, 6458, 120182, 
+    119575, 4761, 10506, 4766, 1616, 1273, 120187, 8795, 118876, 194835, 
+    63957, 9232, 1138, 10483, 12677, 41545, 12881, 3239, 65517, 119558, 
+    66614, 119111, 42128, 3484, 64545, 11778, 11572, 8503, 5122, 41527, 5040, 
+    4924, 119014, 119085, 120201, 120748, 5039, 41926, 8303, 8282, 5038, 
+    65736, 10003, 7427, 65611, 120586, 1686, 120190, 9359, 11467, 3664, 
+    65921, 8238, 6662, 66472, 119329, 3863, 126, 4835, 68119, 120605, 13245, 
+    4309, 7744, 63867, 119846, 119023, 13184, 63870, 65431, 569, 8136, 
+    119010, 711, 1633, 120583, 63869, 4762, 1103, 194560, 12281, 4765, 41331, 
+    1006, 13040, 4760, 1550, 8201, 10871, 917990, 1102, 5031, 118904, 66671, 
+    64499, 11546, 13042, 337, 194781, 65781, 65678, 12279, 1111, 65780, 
+    119900, 4707, 194635, 5008, 7883, 8822, 7880, 4522, 8255, 5512, 13010, 
+    119232, 8304, 64313, 11611, 5906, 1119, 13039, 13038, 64910, 2455, 64734, 
+    13008, 41652, 4385, 12492, 11020, 6499, 64775, 119161, 13009, 160, 68110, 
+    120679, 64262, 5052, 64031, 5821, 6186, 41792, 42770, 5051, 65773, 1429, 
+    64573, 5050, 302, 388, 12058, 735, 6637, 1079, 3867, 5708, 12726, 119879, 
+    9117, 5706, 10679, 5513, 6666, 4005, 0, 5510, 10991, 120454, 65458, 2470, 
+    917581, 13305, 1925, 65760, 194914, 41924, 10092, 5048, 5047, 41532, 
+    10058, 917559, 119999, 9070, 12049, 3339, 8089, 1106, 639, 65764, 63967, 
+    3340, 3109, 3653, 4599, 10799, 6674, 10605, 917585, 1476, 648, 1754, 
+    11001, 3233, 864, 41782, 10164, 8972, 41865, 3530, 9750, 120690, 11024, 
+    6656, 5192, 4338, 5046, 8512, 63770, 13199, 8967, 1236, 5045, 12012, 
+    13189, 7986, 5044, 120102, 7440, 13128, 5043, 9553, 1590, 63777, 63776, 
+    9669, 12341, 8654, 8402, 63779, 1583, 4740, 13260, 3586, 13276, 11444, 
+    120306, 67634, 119606, 41523, 13296, 517, 12922, 11354, 11700, 41528, 
+    123, 65454, 12393, 11394, 41997, 10531, 7784, 13194, 1334, 11978, 4479, 
+    1126, 65586, 120663, 195061, 8520, 3925, 917621, 8069, 4357, 42154, 489, 
+    120450, 119836, 8848, 6476, 8450, 43044, 11926, 41557, 1145, 63788, 7910, 
+    63785, 63784, 754, 8711, 6183, 8183, 120741, 8928, 65166, 7952, 10747, 
+    125, 9235, 64861, 64207, 12689, 66445, 10779, 10990, 3523, 1074, 13258, 
+    9536, 8477, 11014, 4427, 10517, 63757, 7726, 11325, 19922, 267, 1349, 
+    10713, 1371, 12149, 195003, 2458, 63753, 6201, 41084, 41074, 4266, 10652, 
+    6483, 41077, 3402, 9050, 3398, 8140, 42084, 6260, 3391, 41075, 2476, 
+    41956, 11988, 3898, 10625, 10201, 10988, 11524, 63794, 10367, 12521, 
+    10431, 13014, 6289, 1068, 6673, 12523, 12945, 12524, 12438, 7950, 10804, 
+    13233, 12082, 4386, 9053, 12473, 2793, 12475, 704, 195020, 6195, 9530, 
+    6660, 12232, 194892, 64159, 5681, 12629, 4595, 63760, 792, 65538, 13004, 
+    9897, 8742, 195013, 64947, 65448, 63744, 12948, 64787, 7588, 63748, 1693, 
+    63746, 63745, 5055, 9883, 4287, 1090, 4902, 1131, 11665, 194602, 4558, 
+    1816, 9523, 41712, 168, 194897, 4898, 63857, 6157, 12960, 4901, 1821, 
+    13191, 12170, 3500, 3139, 791, 9162, 12485, 10306, 119001, 64200, 13006, 
+    64433, 8354, 10033, 941, 12037, 7557, 65570, 10565, 8234, 64559, 8228, 
+    8424, 10246, 64193, 12811, 65925, 3946, 42764, 8057, 41990, 673, 194853, 
+    64357, 917971, 194799, 9547, 288, 8752, 120820, 2448, 10025, 10267, 2918, 
+    2452, 65300, 41529, 8729, 64726, 2790, 7845, 3793, 194715, 4408, 4122, 
+    11568, 41535, 8723, 10709, 10087, 119302, 731, 42109, 11548, 2438, 64587, 
+    65396, 119169, 1175, 13256, 1282, 373, 119172, 5396, 8653, 8557, 7723, 0, 
+    3330, 120278, 41952, 917566, 5273, 8248, 5269, 3304, 5202, 2404, 5267, 
+    119357, 1627, 65549, 5277, 12963, 5371, 6189, 4125, 1826, 12133, 65241, 
+    8260, 1271, 917589, 195006, 64643, 9035, 3864, 12707, 4631, 3879, 118785, 
+    68125, 4166, 164, 9331, 7567, 7459, 119568, 10212, 5384, 41882, 67647, 
+    64346, 0, 68159, 917822, 41388, 120518, 12005, 12666, 13175, 13207, 8706, 
+    5552, 10172, 700, 5929, 5553, 12978, 120384, 5356, 7499, 8563, 41888, 
+    3180, 917818, 917960, 5554, 971, 12344, 8724, 194608, 6665, 63874, 
+    120275, 2866, 8517, 11455, 13190, 64632, 120227, 5555, 10045, 12882, 
+    13275, 120672, 41522, 11480, 9143, 6668, 41525, 120539, 195035, 656, 
+    118808, 43034, 4577, 12229, 8715, 68133, 194613, 120261, 4269, 64813, 
+    119163, 41609, 10476, 950, 118980, 3932, 41450, 68140, 66683, 68130, 
+    120014, 11974, 118884, 369, 119096, 41784, 66459, 5097, 4935, 9848, 
+    64216, 10293, 4796, 10317, 3651, 10127, 120603, 10269, 5102, 5101, 66628, 
+    9064, 8138, 120455, 404, 5100, 1439, 12093, 1247, 8092, 119330, 5099, 
+    1831, 1441, 4793, 3063, 650, 12292, 746, 120165, 120769, 7461, 12018, 
+    9031, 12182, 10115, 9078, 8545, 4422, 4708, 3799, 3268, 64556, 9118, 
+    119127, 2676, 7750, 4374, 64398, 6190, 1364, 64589, 8038, 68121, 9857, 
+    120638, 9858, 195033, 64170, 12129, 13174, 8481, 12412, 6202, 64380, 
+    10920, 10872, 2365, 7841, 120059, 5108, 5107, 11010, 13210, 6176, 65561, 
+    5541, 41785, 41171, 11291, 5284, 4372, 207, 194904, 4275, 119930, 854, 
+    68147, 120189, 12965, 384, 5103, 10404, 10340, 10702, 1556, 488, 13236, 
+    12937, 10017, 9733, 13187, 10014, 7844, 41373, 13198, 5203, 120517, 
+    13232, 5106, 349, 4863, 41371, 10965, 41367, 5105, 11721, 12861, 4398, 
+    5104, 5672, 304, 1096, 120557, 0, 932, 12441, 6567, 238, 65681, 4318, 
+    10452, 19905, 8032, 13243, 13237, 12719, 67640, 66570, 64814, 64884, 
+    119872, 10670, 8597, 1178, 64017, 9864, 13195, 8803, 309, 6622, 8151, 
+    10858, 64961, 7722, 12553, 10459, 12568, 12066, 12549, 66590, 12570, 
+    9712, 41417, 41496, 194943, 9805, 4965, 13150, 10538, 19944, 41401, 
+    120252, 120164, 6191, 6261, 119342, 119341, 11965, 1957, 10420, 982, 
+    2756, 9370, 2720, 12357, 41455, 2925, 118817, 13056, 3222, 13212, 10116, 
+    41644, 10105, 10378, 41581, 10834, 118793, 64407, 5242, 41963, 64476, 
+    1694, 8216, 10814, 67598, 7781, 6306, 64568, 917916, 120738, 11793, 
+    42057, 7594, 64598, 120325, 64799, 3475, 64206, 2479, 9709, 3632, 120322, 
+    10698, 65616, 3648, 3907, 10297, 67639, 3636, 19928, 2979, 8837, 8286, 
+    1843, 3936, 119052, 11699, 41347, 65119, 13235, 3640, 41248, 120579, 
+    4379, 13239, 12692, 7969, 12927, 66353, 194951, 12703, 120509, 41846, 
+    2529, 734, 10808, 65146, 42083, 9872, 957, 42055, 1846, 66367, 12181, 
+    9634, 120310, 9988, 12991, 1670, 5740, 119597, 10072, 5379, 120318, 
+    41163, 41157, 785, 8236, 194812, 9027, 63897, 13267, 64383, 64688, 925, 
+    41955, 120541, 41773, 41071, 9586, 120312, 41984, 9217, 6151, 12110, 
+    120689, 65572, 64580, 4016, 13265, 13264, 381, 12386, 6100, 42077, 
+    120768, 5808, 5184, 8200, 12967, 10810, 5612, 4583, 19943, 5860, 67633, 
+    64575, 194842, 812, 3615, 65284, 5178, 194929, 119015, 9825, 5188, 9698, 
+    7814, 120063, 10692, 1166, 64429, 41921, 924, 9756, 12359, 119258, 
+    194843, 2442, 10703, 120696, 67632, 8012, 5674, 12353, 119561, 12361, 
+    5677, 67626, 66657, 40972, 12453, 41920, 5673, 12751, 5676, 8542, 12694, 
+    118978, 2468, 1294, 41294, 3336, 3883, 64388, 1727, 194680, 64054, 3605, 
+    119632, 195015, 12034, 8718, 3550, 736, 7806, 4505, 2715, 806, 5826, 
+    41884, 5813, 64279, 65391, 5841, 5837, 64731, 12702, 3105, 2405, 5838, 
+    5796, 120604, 65259, 5793, 5735, 5866, 5797, 1432, 5865, 12143, 7956, 
+    598, 66448, 41886, 2480, 120152, 19952, 9037, 5671, 5537, 12749, 67601, 
+    10932, 41359, 1211, 847, 65690, 9529, 11799, 12318, 120766, 43026, 5645, 
+    10622, 41391, 194967, 64378, 6566, 917913, 5650, 11358, 119102, 13110, 
+    194834, 9624, 194928, 8284, 65896, 2748, 1554, 194733, 4035, 6492, 66504, 
+    4265, 2929, 3977, 65344, 12051, 836, 5698, 2488, 194634, 4582, 66514, 
+    5644, 10292, 12926, 8046, 7528, 8372, 11707, 65116, 119206, 11439, 13201, 
+    1374, 64878, 12742, 41013, 10568, 41374, 4030, 2869, 120776, 41015, 
+    65897, 2785, 400, 12597, 42051, 120540, 64477, 6661, 5659, 9884, 4759, 
+    118906, 390, 10266, 41349, 1170, 3473, 7718, 118962, 1609, 902, 917855, 
+    120062, 66352, 11661, 8122, 5712, 66308, 8004, 1887, 9540, 10278, 2554, 
+    5158, 5714, 41136, 194970, 64351, 807, 66652, 120793, 64677, 976, 5511, 
+    6146, 65518, 771, 10954, 41356, 9673, 11412, 11026, 41143, 8676, 7904, 
+    5579, 953, 451, 119560, 5578, 12635, 11491, 9724, 194697, 118881, 9524, 
+    7490, 118789, 1440, 3379, 10310, 7487, 12561, 471, 7484, 7482, 3795, 
+    7480, 7479, 7478, 7477, 6501, 7475, 64900, 7473, 7472, 2474, 7470, 6546, 
+    93, 10615, 10213, 8128, 12551, 10049, 8171, 3544, 194628, 6017, 65311, 
+    383, 120216, 13306, 10533, 7870, 63884, 5187, 119991, 1456, 120217, 
+    42164, 64217, 194702, 5232, 917994, 19961, 2472, 41005, 120699, 8710, 
+    6019, 4256, 119959, 4980, 8860, 9640, 10028, 12845, 66607, 13182, 65121, 
+    120685, 120308, 10631, 65126, 7972, 118928, 8066, 119623, 7900, 8316, 
+    11309, 11273, 119040, 64211, 120309, 64212, 10347, 445, 119029, 195074, 
+    12931, 64927, 8330, 65783, 66597, 64213, 64366, 64369, 8814, 3902, 64607, 
+    1770, 194723, 12836, 64208, 64552, 65821, 4584, 9684, 120714, 917944, 
+    10866, 65792, 1118, 7464, 194989, 8964, 1081, 7436, 64565, 8162, 9342, 
+    5996, 119245, 4903, 64332, 41386, 5162, 41007, 1330, 64486, 40995, 12209, 
+    12047, 41384, 194789, 195067, 1848, 4334, 65352, 9880, 64066, 10674, 
+    5522, 195014, 61, 120157, 195065, 3633, 41980, 65162, 41234, 12089, 
+    65871, 9771, 66685, 13251, 41959, 64749, 6262, 2784, 195040, 9334, 8126, 
+    66483, 64967, 7975, 441, 194591, 917599, 11608, 4884, 40999, 120269, 
+    120334, 10495, 6313, 10890, 119354, 65834, 8324, 7855, 2345, 67599, 463, 
+    64737, 194821, 119607, 3117, 5460, 119356, 1193, 10056, 1148, 12396, 
+    13252, 7829, 42173, 118994, 7743, 917981, 13248, 5499, 63763, 118960, 
+    9034, 6039, 120544, 5663, 119182, 41018, 65683, 10338, 2482, 1471, 
+    120086, 120077, 66370, 12378, 41966, 41970, 3084, 12374, 10903, 6638, 
+    10422, 911, 2460, 120499, 11944, 12376, 41032, 40996, 120614, 12380, 
+    5520, 64473, 10869, 5870, 64670, 13310, 2603, 12326, 539, 10826, 65105, 
+    917932, 3853, 11949, 64901, 120260, 64883, 10722, 41810, 8659, 120090, 
+    12474, 66721, 5857, 65342, 2478, 119120, 4162, 7942, 4260, 12953, 42028, 
+    120089, 12470, 64941, 11798, 2742, 12476, 1891, 10946, 9101, 5000, 66647, 
+    12302, 3018, 12942, 5748, 194584, 7771, 6161, 917934, 8796, 0, 6412, 
+    118986, 8519, 13146, 41973, 12906, 9422, 10333, 2882, 4366, 119123, 
+    12843, 4520, 917810, 65626, 10648, 118898, 4014, 12842, 194724, 12015, 
+    13117, 8275, 3893, 66362, 5810, 12210, 195071, 42147, 11536, 13292, 
+    65685, 12938, 10427, 9154, 3844, 63934, 9755, 1110, 6612, 10892, 8231, 
+    10775, 6473, 41968, 783, 10219, 3591, 41969, 917997, 2453, 8518, 3620, 
+    11466, 12443, 4556, 10349, 10413, 194569, 41159, 3202, 8599, 10510, 4382, 
+    66482, 195002, 10842, 687, 9177, 8902, 63950, 1840, 41751, 12400, 120177, 
+    4883, 285, 4723, 41917, 9788, 4459, 64158, 1634, 41958, 9155, 240, 9786, 
+    65082, 41919, 8579, 9743, 7981, 13134, 118878, 4508, 64178, 41999, 11328, 
+    119817, 65589, 63887, 3081, 11463, 120080, 119051, 119353, 10445, 41720, 
+    194662, 120229, 2614, 9024, 64620, 1729, 119840, 64289, 65221, 63883, 
+    65466, 64852, 64509, 41447, 63916, 64855, 41203, 5001, 41879, 11355, 
+    4121, 5003, 884, 41214, 63879, 4943, 5150, 7500, 5278, 7773, 643, 3086, 
+    118912, 64652, 120068, 58, 194621, 6167, 66656, 63872, 6594, 66366, 
+    11295, 41495, 3624, 43036, 118901, 64655, 2721, 9616, 63988, 19929, 
+    11296, 10500, 10440, 9611, 4264, 119303, 194657, 7738, 41857, 11446, 
+    12638, 64522, 3435, 3094, 12916, 9754, 66314, 4437, 41292, 8899, 12748, 
+    42058, 9517, 11518, 917889, 65360, 120700, 119047, 63956, 4306, 41380, 
+    11995, 63960, 9591, 8323, 10217, 67602, 11469, 120578, 12456, 2723, 
+    120061, 5088, 5086, 917783, 8524, 7752, 11397, 2880, 0, 194669, 2872, 
+    1386, 65034, 3498, 4378, 65039, 4270, 12392, 65036, 7853, 6633, 12101, 
+    5822, 5230, 194573, 710, 917790, 11663, 1666, 8161, 371, 12013, 63891, 
+    42092, 119103, 415, 63851, 63892, 11708, 42096, 5183, 1877, 7538, 7924, 
+    2927, 4324, 6608, 4472, 1244, 331, 194858, 12683, 10662, 64678, 4756, 
+    63831, 65852, 10730, 7691, 10331, 65320, 41964, 6238, 8938, 8628, 6043, 
+    118801, 64895, 1604, 9565, 10539, 120814, 41220, 13032, 120519, 120193, 
+    10032, 8750, 12373, 63828, 11992, 1351, 194868, 8698, 12190, 3622, 1930, 
+    65237, 9621, 10463, 63981, 4967, 13031, 1966, 2330, 195099, 3657, 120498, 
+    65202, 6000, 4347, 4416, 42098, 11009, 10694, 8099, 402, 41916, 13147, 
+    41912, 42100, 12217, 9695, 1897, 7562, 3515, 5170, 11805, 11796, 676, 
+    6259, 41742, 65558, 41870, 65553, 3536, 65093, 9752, 63902, 6162, 10532, 
+    66490, 10113, 41829, 65886, 5159, 12422, 41832, 439, 66640, 119611, 
+    11280, 12481, 2325, 40970, 41830, 120647, 917799, 5145, 12486, 65018, 
+    66516, 5409, 8976, 120051, 12336, 4135, 9685, 341, 2727, 4129, 3539, 
+    66616, 11530, 41736, 7913, 5405, 63859, 4131, 41267, 64721, 63865, 4133, 
+    63864, 210, 4600, 8082, 3254, 4137, 119205, 119853, 119062, 194577, 
+    120534, 4591, 65077, 64671, 194671, 3355, 9508, 3393, 561, 5723, 195, 
+    64261, 3377, 12497, 41269, 917545, 13135, 917993, 8368, 119224, 41499, 
+    917798, 11435, 917920, 41498, 120628, 1379, 246, 12603, 9680, 3788, 2924, 
+    42168, 12812, 8728, 64906, 119213, 8917, 120645, 301, 64765, 3969, 64964, 
+    9575, 64562, 40966, 9652, 64919, 42064, 42086, 120542, 194728, 8491, 
+    194962, 41876, 63772, 3182, 327, 120323, 9042, 118827, 917776, 42169, 
+    4755, 194684, 64660, 11443, 12431, 8668, 12434, 608, 600, 5999, 1219, 
+    3934, 9494, 11483, 917919, 1726, 1015, 64686, 8212, 11395, 64202, 13160, 
+    7759, 65363, 485, 43037, 65291, 8811, 927, 42102, 194979, 12436, 9351, 
+    7778, 64379, 7496, 65335, 7491, 1208, 7495, 64757, 9337, 64362, 917778, 
+    11348, 12235, 9021, 194949, 917830, 120066, 19914, 3742, 8758, 9648, 
+    64617, 63834, 9150, 63835, 1117, 13037, 2594, 63809, 10691, 12052, 6550, 
+    10469, 65212, 11265, 2546, 119216, 213, 65309, 10554, 3972, 917972, 
+    194678, 64194, 6554, 12416, 11914, 5452, 8230, 64197, 41951, 12418, 
+    42049, 3882, 8532, 2713, 1573, 9650, 42136, 4596, 66339, 1406, 120041, 
+    40990, 194593, 12414, 8287, 4143, 120378, 10489, 1143, 4141, 9682, 12415, 
+    1508, 42763, 8779, 10569, 8725, 120783, 65045, 11724, 119064, 4145, 
+    64872, 65751, 66613, 119576, 8027, 41505, 9171, 9550, 11400, 12518, 
+    65178, 65397, 6528, 10740, 65753, 64816, 10998, 66333, 12955, 10596, 
+    2888, 119572, 65033, 7715, 3881, 41487, 12118, 67622, 2878, 5390, 64167, 
+    3009, 41476, 41489, 63765, 3007, 1448, 2975, 10429, 3889, 8521, 5083, 
+    5082, 7503, 5235, 803, 194590, 3014, 5081, 8986, 11002, 10632, 11934, 
+    11452, 1332, 64802, 3929, 4597, 65532, 64767, 1791, 5191, 9288, 9657, 
+    2892, 10577, 6031, 555, 64173, 0, 194927, 12367, 42170, 11540, 63930, 
+    629, 1924, 119880, 11270, 64162, 5858, 8462, 8005, 12365, 1784, 1361, 
+    118939, 12369, 7905, 67644, 5077, 194668, 10880, 63927, 5075, 120065, 
+    9371, 65075, 41193, 11007, 1625, 10997, 917907, 1342, 66684, 64171, 3434, 
+    4843, 4506, 195060, 5266, 120521, 5272, 4482, 4507, 9578, 63923, 66319, 
+    7979, 64381, 9831, 64417, 65529, 461, 7984, 41972, 4504, 444, 42145, 
+    9127, 5276, 43021, 118922, 120179, 119638, 11349, 12848, 5177, 41324, 
+    12055, 8722, 120805, 1197, 65512, 1149, 4114, 409, 4383, 8900, 8948, 
+    7684, 3492, 721, 10182, 9108, 119005, 195041, 11954, 119191, 12993, 
+    40963, 3099, 917979, 65088, 41087, 119834, 12587, 66643, 120374, 12036, 
+    194736, 65123, 41576, 8152, 120721, 64428, 12227, 8578, 5995, 7573, 
+    41575, 2922, 63946, 63944, 11493, 194883, 2670, 4167, 194873, 11723, 
+    120025, 65173, 68154, 13023, 938, 917954, 195044, 11737, 9721, 118937, 
+    41017, 9606, 8504, 4024, 41063, 11411, 12334, 65231, 4153, 11911, 10793, 
+    5250, 12407, 3395, 4404, 6056, 12401, 11490, 5775, 42005, 41607, 68183, 
+    41091, 12205, 1344, 8870, 194744, 4940, 4735, 7683, 1167, 12822, 4983, 
+    120554, 861, 64907, 120045, 120458, 65149, 63896, 120651, 12039, 10559, 
+    11956, 119841, 118892, 9472, 4282, 6631, 120188, 12816, 9596, 7618, 
+    12710, 64147, 11579, 4101, 0, 64704, 5992, 7616, 65828, 64422, 1004, 
+    9632, 120185, 853, 0, 12627, 10953, 194681, 5016, 65619, 120441, 11300, 
+    9491, 9686, 5890, 917914, 7558, 12712, 195077, 65627, 10718, 13154, 3461, 
+    9139, 64756, 194990, 119151, 65628, 0, 13227, 12585, 6669, 119152, 12177, 
+    41708, 12860, 41098, 10015, 10838, 4900, 10352, 120742, 10061, 5903, 
+    4119, 5140, 209, 64002, 11520, 9702, 11702, 8277, 9245, 13048, 4927, 
+    4138, 41093, 65286, 64412, 2410, 993, 41025, 13054, 12394, 120020, 
+    917579, 68162, 12685, 64938, 65475, 10781, 41230, 64299, 5010, 1680, 
+    9107, 118809, 10659, 3600, 10968, 120027, 1336, 41518, 194796, 5896, 
+    119838, 5993, 2819, 12950, 12706, 12966, 1893, 120462, 63915, 917768, 
+    8184, 272, 1363, 8793, 8411, 63908, 41502, 3077, 983, 68118, 1512, 
+    119941, 1190, 4109, 1335, 841, 5888, 41358, 9836, 9544, 120021, 41481, 
+    8313, 7832, 65515, 3090, 2409, 817, 1664, 1850, 66690, 3079, 4731, 10118, 
+    66629, 64541, 12033, 1255, 11689, 9247, 64350, 66633, 12389, 66610, 
+    195078, 41996, 11526, 63985, 5864, 1147, 11690, 5835, 1551, 66625, 5480, 
+    7858, 11653, 4116, 11688, 66634, 1094, 194, 12384, 118987, 8180, 41686, 
+    12313, 41531, 63904, 13273, 6114, 10898, 195082, 64578, 8247, 507, 91, 
+    7545, 10695, 10952, 7534, 10896, 10036, 7857, 6067, 774, 65915, 2744, 
+    119815, 5994, 12539, 41420, 41601, 8359, 65264, 6028, 66511, 13167, 
+    120277, 7719, 119875, 2486, 7893, 41059, 162, 5436, 917583, 119809, 9687, 
+    64956, 6304, 65457, 6051, 120495, 5262, 5904, 66658, 12681, 194710, 
+    194616, 12406, 12219, 3652, 10537, 917946, 10492, 64550, 6549, 279, 
+    195030, 119978, 64619, 12403, 1489, 120771, 4132, 4899, 3899, 1007, 
+    42124, 4976, 2343, 4103, 19946, 120806, 10750, 1345, 120355, 120801, 
+    12859, 8956, 4098, 65267, 5861, 65559, 11999, 12151, 64804, 194856, 
+    12645, 5146, 11320, 64730, 64174, 41094, 492, 8685, 12974, 41060, 67613, 
+    41551, 5147, 2582, 11470, 64538, 7444, 1928, 118998, 9594, 5991, 10862, 
+    67609, 2527, 194809, 197, 2799, 8241, 64181, 65348, 65874, 194840, 64179, 
+    767, 4127, 120464, 10138, 119808, 0, 8897, 63911, 41553, 8357, 4124, 
+    1799, 65371, 42148, 194663, 12954, 120231, 65340, 1123, 963, 2434, 10120, 
+    12405, 41339, 2493, 398, 392, 9723, 6407, 119011, 7945, 64935, 4402, 
+    7570, 12402, 65926, 41392, 8414, 12408, 41265, 65713, 406, 120326, 9164, 
+    12411, 0, 4560, 6623, 4961, 64494, 1575, 64682, 5438, 165, 9993, 41467, 
+    63953, 8064, 9093, 9599, 9147, 118831, 63958, 4987, 9148, 2399, 4096, 53, 
+    10944, 12368, 65435, 119192, 8178, 64149, 3367, 12910, 10884, 727, 65272, 
+    119238, 5805, 1947, 11527, 194589, 42176, 12370, 11655, 1705, 5411, 8898, 
+    118810, 12372, 120642, 195023, 8017, 65287, 8813, 12366, 10963, 6066, 
+    1329, 4909, 3052, 9220, 66464, 4904, 66666, 10803, 1365, 9253, 42757, 
+    41264, 7462, 120712, 119350, 119814, 1499, 66727, 8055, 120803, 8740, 
+    5398, 63962, 13120, 8924, 917764, 5988, 3660, 12017, 11781, 9476, 8788, 
+    1357, 42113, 65743, 3629, 8774, 13005, 119082, 3628, 120172, 64394, 1933, 
+    3469, 1567, 42116, 11969, 64809, 2928, 4905, 2487, 851, 3121, 1804, 3311, 
+    67615, 9114, 194880, 12083, 9315, 4822, 4906, 3852, 2847, 6675, 3236, 
+    11317, 1251, 7777, 41852, 7951, 1198, 9132, 120767, 12274, 510, 10259, 
+    9865, 65686, 4561, 6018, 1398, 917869, 12276, 66487, 19931, 119061, 
+    11406, 8167, 12127, 41932, 840, 120300, 2443, 10918, 10410, 120338, 1001, 
+    9241, 1927, 333, 41930, 120272, 8144, 8034, 10680, 119598, 66663, 64199, 
+    12867, 64198, 6678, 7769, 7519, 12621, 65150, 8904, 518, 4764, 65165, 
+    41168, 13204, 4387, 857, 10530, 65369, 12736, 120724, 41044, 66458, 
+    11543, 9358, 67594, 42078, 5136, 1968, 19937, 66605, 1337, 10581, 1629, 
+    4533, 796, 66494, 6490, 194921, 12038, 119338, 12664, 195037, 65461, 
+    9798, 6120, 478, 1948, 68128, 10962, 952, 6016, 195055, 195088, 9512, 
+    4276, 1206, 3619, 41638, 13263, 3843, 8142, 8853, 3361, 41795, 490, 
+    10715, 3436, 65011, 63841, 12817, 9847, 6676, 3930, 12854, 13240, 6154, 
+    9551, 65354, 65346, 784, 65357, 334, 64797, 1453, 7541, 8940, 120329, 
+    8500, 10428, 10364, 64715, 778, 4317, 10004, 7989, 64676, 3227, 119583, 
+    67606, 120514, 120684, 10855, 13102, 41702, 10309, 6672, 10277, 194958, 
+    66691, 41624, 5415, 9613, 9001, 4526, 3462, 65215, 64520, 41020, 6664, 
+    66701, 42056, 9759, 64957, 3963, 120304, 8114, 1469, 65244, 65381, 41744, 
+    4988, 66453, 118956, 9598, 904, 352, 194760, 1451, 1356, 8453, 4134, 
+    120377, 917802, 1619, 9703, 41745, 3955, 8575, 119180, 1201, 64732, 
+    12846, 917980, 41860, 11919, 64962, 41550, 5289, 13144, 8511, 9460, 823, 
+    9675, 12305, 5940, 226, 2649, 12387, 1253, 13183, 65766, 500, 64521, 
+    9081, 1658, 11936, 64735, 65761, 8702, 11606, 64784, 9785, 42123, 64783, 
+    194619, 917779, 5152, 8935, 7533, 119101, 5304, 119820, 616, 4323, 64666, 
+    4684, 65103, 120613, 65735, 65339, 10560, 6048, 4763, 4112, 118935, 
+    10870, 5260, 5328, 65129, 326, 9681, 4475, 917933, 10771, 2876, 194915, 
+    119935, 6035, 41398, 41192, 9802, 13261, 120532, 453, 41396, 917564, 
+    6481, 12140, 9572, 41937, 10392, 10328, 40998, 7704, 66432, 120317, 9800, 
+    4123, 917900, 42103, 41000, 7854, 119239, 6487, 8334, 64061, 10344, 9808, 
+    11271, 5394, 4126, 12800, 9521, 9589, 41200, 41306, 4425, 119856, 10464, 
+    63802, 64769, 1288, 64514, 11528, 63984, 12173, 679, 64012, 41914, 5850, 
+    758, 7536, 10796, 4474, 10742, 10693, 64006, 1587, 64005, 10541, 64581, 
+    65490, 1369, 12134, 119050, 7927, 64009, 1139, 64030, 64026, 64029, 8970, 
+    64948, 4430, 195016, 10774, 4514, 66434, 12421, 8194, 194765, 1852, 3057, 
+    65483, 8893, 64032, 12542, 12973, 65341, 120497, 41206, 7925, 12423, 
+    10475, 917572, 3496, 1352, 10933, 7707, 9102, 627, 42034, 6158, 8327, 
+    64497, 65605, 6040, 917592, 10129, 64863, 9336, 11696, 5730, 1018, 7798, 
+    64474, 64259, 1682, 64290, 7820, 42756, 12951, 119873, 7746, 1492, 0, 
+    8288, 12563, 10728, 5127, 11285, 65509, 5495, 4273, 11577, 9644, 10849, 
+    1833, 2999, 120612, 64373, 120471, 185, 65085, 6023, 169, 5497, 7535, 
+    8085, 917909, 65717, 9749, 8224, 6131, 1949, 4117, 7847, 120489, 119982, 
+    5321, 66355, 65765, 9313, 2589, 64408, 1689, 7802, 4683, 120167, 12303, 
+    64667, 66704, 1184, 0, 815, 8273, 120807, 6049, 120530, 4027, 834, 
+    119833, 1803, 64683, 1503, 8995, 120653, 917924, 5731, 1381, 2387, 64511, 
+    12430, 8289, 10981, 12654, 2881, 65514, 917600, 9601, 332, 9668, 9766, 
+    5142, 2407, 65618, 66601, 6036, 64881, 4026, 8645, 64789, 2887, 6489, 
+    3526, 6298, 119136, 64475, 4833, 1834, 65621, 8572, 6021, 10940, 65249, 
+    119848, 8662, 65739, 119604, 2652, 7463, 11539, 10784, 120720, 64391, 
+    166, 19913, 8635, 9706, 10623, 408, 1828, 195084, 13298, 194889, 7426, 
+    8168, 6280, 12324, 7607, 10639, 66713, 4832, 64557, 41643, 6279, 12508, 
+    8713, 10690, 9161, 41645, 1620, 6645, 646, 66726, 66711, 42129, 609, 
+    11555, 3472, 8697, 41086, 119594, 4343, 6212, 917557, 11413, 5809, 1950, 
+    239, 119021, 637, 65785, 41592, 43029, 917539, 120285, 194837, 3247, 
+    120754, 12985, 12696, 65213, 66668, 65260, 12929, 10983, 712, 120291, 
+    119337, 41567, 65592, 194969, 120171, 119852, 120178, 119137, 1506, 8285, 
+    65617, 4509, 65608, 12651, 12216, 64628, 40988, 11961, 6204, 41727, 7494, 
+    64341, 2396, 41703, 41493, 13062, 41757, 355, 9719, 3886, 9814, 63912, 
+    68123, 65444, 996, 42075, 64880, 43045, 65199, 194810, 8655, 8222, 
+    194839, 7939, 10342, 64720, 3178, 68184, 120552, 5907, 19932, 3976, 
+    917849, 42161, 9471, 5833, 11966, 12555, 5969, 5699, 12562, 12550, 9488, 
+    40982, 8489, 0, 1488, 194829, 13149, 119997, 9799, 5265, 66612, 1563, 
+    11487, 9619, 12464, 119210, 120758, 118952, 41704, 5803, 7797, 6070, 
+    10006, 41181, 465, 6082, 13078, 9692, 194745, 12567, 8116, 795, 66480, 
+    7843, 12462, 3607, 10831, 10046, 9612, 42153, 8218, 9485, 66714, 120301, 
+    12468, 8607, 1008, 65322, 3306, 66485, 65138, 6057, 508, 120264, 1766, 
+    11282, 11996, 1820, 4547, 0, 638, 6083, 120160, 12308, 0, 2305, 917595, 
+    64777, 9470, 4345, 6659, 65236, 4818, 6085, 9899, 65207, 3915, 41634, 
+    5382, 41639, 119591, 6235, 119060, 4028, 1787, 19920, 41979, 120786, 
+    3249, 1768, 1130, 12328, 501, 42016, 10601, 43023, 6503, 65294, 7742, 
+    63992, 13280, 41922, 6505, 118925, 5310, 9475, 66716, 120810, 6500, 5526, 
+    65049, 11408, 65889, 8568, 119818, 11449, 9678, 5403, 120311, 9869, 
+    63780, 1771, 12460, 8936, 120631, 118832, 64903, 10760, 119115, 9158, 
+    66567, 120259, 119025, 120582, 5410, 5783, 10365, 8403, 5400, 11594, 
+    120295, 5027, 9326, 10491, 119348, 4831, 120698, 5028, 5587, 66492, 7540, 
+    5026, 4923, 65086, 8981, 12382, 8931, 120755, 1415, 8866, 917785, 65513, 
+    10461, 12103, 119602, 8642, 5029, 42766, 1580, 3598, 120067, 41070, 
+    10053, 120819, 6663, 119325, 6026, 41515, 118796, 64592, 1716, 1461, 910, 
+    11907, 620, 41001, 3658, 41541, 119980, 66728, 7617, 5024, 12888, 41003, 
+    68180, 5025, 11529, 41514, 64561, 5703, 119124, 41517, 41504, 41519, 
+    66473, 9726, 119160, 5849, 623, 781, 670, 10660, 5769, 613, 6105, 11584, 
+    477, 1268, 65275, 8906, 592, 1578, 2636, 64404, 10815, 11619, 8225, 
+    119578, 654, 6451, 653, 652, 7721, 647, 7869, 633, 120224, 42152, 64361, 
+    12480, 6119, 829, 39, 12487, 19950, 120399, 65865, 6616, 65672, 12489, 
+    9667, 391, 5550, 194870, 482, 917886, 1203, 120345, 1813, 64544, 41311, 
+    9503, 120623, 2877, 120249, 64135, 1675, 4939, 5315, 194801, 64128, 
+    10070, 10595, 13293, 4576, 42094, 12808, 119569, 4277, 40997, 4039, 
+    120429, 64472, 368, 13036, 3960, 65460, 8406, 68176, 120121, 66679, 3958, 
+    12132, 1849, 194564, 270, 13086, 10714, 194617, 11929, 11959, 917824, 
+    64657, 41608, 3618, 65009, 9069, 6273, 5156, 364, 9595, 929, 67616, 
+    42035, 707, 1555, 41725, 8691, 66435, 224, 41662, 68164, 9332, 4966, 
+    194977, 917538, 4578, 64513, 3841, 194647, 65922, 10732, 13074, 850, 
+    4972, 9356, 12820, 2909, 63968, 1286, 10166, 8682, 11544, 10203, 9608, 
+    12815, 7730, 11962, 41540, 12507, 1196, 0, 66471, 777, 10020, 4375, 
+    41372, 6641, 525, 12198, 120443, 8763, 120526, 41628, 533, 11931, 8658, 
+    120743, 41520, 2705, 65010, 13126, 9838, 4377, 8559, 7765, 119925, 8280, 
+    13193, 2701, 11666, 8679, 5767, 1576, 7735, 9809, 8353, 11513, 41960, 
+    42007, 66452, 10889, 1748, 7757, 65265, 120226, 12803, 66493, 2718, 4168, 
+    3061, 13308, 63764, 6596, 1179, 4440, 194759, 7694, 363, 8896, 63768, 
+    3485, 12987, 41586, 64908, 120332, 41149, 1591, 6593, 64625, 10192, 
+    64143, 66455, 13053, 10013, 5630, 194622, 120686, 9492, 10390, 13083, 
+    12833, 5543, 41327, 1640, 12495, 630, 120091, 3138, 10996, 41127, 1043, 
+    120674, 12498, 10090, 917568, 917609, 313, 65543, 8615, 119144, 12540, 
+    493, 41426, 5750, 1717, 9417, 479, 9405, 11268, 0, 9398, 9403, 3520, 
+    8426, 12490, 63855, 65185, 12586, 12493, 5815, 10707, 1002, 12491, 
+    194884, 12934, 631, 66474, 64922, 13161, 41303, 917957, 10546, 67635, 
+    65711, 11600, 65786, 2797, 13107, 65599, 306, 714, 3058, 8507, 65576, 
+    66700, 119961, 120731, 120694, 11607, 65591, 64711, 68166, 7909, 9157, 
+    4569, 63758, 63805, 13297, 7603, 40986, 180, 244, 11542, 12898, 12494, 
+    12674, 8244, 362, 65776, 64145, 8037, 194830, 11535, 120680, 4882, 5185, 
+    64866, 5521, 4885, 5519, 42155, 10302, 4880, 10104, 1027, 1360, 248, 
+    12424, 10523, 1446, 4319, 41646, 991, 5189, 63754, 10494, 65777, 1722, 
+    1870, 120151, 470, 9427, 65271, 5523, 194716, 64527, 4579, 120446, 9549, 
+    12511, 10549, 12514, 9661, 66486, 12000, 9602, 8623, 65172, 120042, 
+    119855, 13095, 12512, 11615, 13041, 6150, 9846, 659, 6098, 0, 1174, 
+    10334, 194592, 8311, 12510, 63856, 12107, 120341, 12513, 9284, 12471, 
+    120733, 12330, 917571, 63853, 119854, 2323, 65288, 2319, 6293, 12477, 
+    118807, 2311, 194661, 4415, 237, 6281, 917902, 0, 9010, 2309, 7897, 8173, 
+    64894, 12469, 7483, 118979, 1736, 10609, 3894, 12228, 9397, 10987, 3383, 
+    9396, 9393, 693, 9130, 314, 9389, 6209, 9387, 9388, 4932, 3842, 9383, 
+    5332, 12204, 9285, 10436, 8185, 41808, 1751, 273, 8165, 13166, 2313, 
+    65449, 7948, 9236, 8544, 4528, 2584, 6301, 41880, 6133, 10484, 9463, 
+    917823, 9339, 7943, 3757, 3147, 195092, 12420, 10421, 120488, 2310, 
+    41112, 2326, 9382, 2565, 9380, 7596, 7921, 9375, 9376, 1683, 9374, 2567, 
+    8596, 12444, 4044, 41274, 12527, 8210, 120756, 1023, 474, 12331, 0, 
+    42032, 8744, 726, 9839, 120313, 5005, 120383, 41276, 42030, 5007, 12522, 
+    9835, 65442, 4951, 634, 12213, 10895, 65492, 274, 120236, 1858, 4744, 
+    4746, 917852, 9548, 65899, 403, 120117, 12503, 9610, 8068, 8197, 63996, 
+    699, 42000, 41665, 1819, 10496, 13007, 42182, 7581, 13262, 194649, 41667, 
+    12506, 10840, 1923, 13084, 12500, 64507, 12509, 64393, 10507, 120692, 
+    10589, 6464, 41047, 2996, 1937, 41931, 12990, 8084, 4047, 3608, 8281, 
+    65016, 1107, 68101, 9076, 8862, 120636, 293, 9369, 64766, 64791, 7803, 
+    13222, 65416, 10579, 8560, 8546, 11553, 12678, 4803, 9043, 1739, 1941, 
+    498, 64471, 1713, 119091, 12529, 8042, 11407, 2344, 12528, 6297, 2414, 
+    64139, 66710, 3231, 11716, 6422, 9902, 65156, 12530, 2537, 969, 41429, 
+    12658, 13034, 6165, 13035, 917620, 6632, 4719, 469, 119240, 4363, 5211, 
+    8914, 119299, 119334, 1772, 1435, 64876, 2969, 6046, 64812, 6208, 64101, 
+    5746, 12215, 119332, 4931, 1951, 8612, 119363, 9607, 917904, 338, 118797, 
+    5061, 10675, 41106, 10767, 1491, 8115, 65459, 11941, 10139, 8227, 8270, 
+    1218, 12126, 41993, 12168, 6642, 63808, 12889, 1622, 41108, 4486, 41995, 
+    1075, 1958, 10925, 41992, 41506, 118975, 10249, 64122, 10257, 41569, 
+    10273, 120327, 7692, 12669, 8008, 120320, 330, 8566, 65083, 9046, 41117, 
+    41126, 12532, 120648, 64131, 3508, 7794, 119943, 64129, 9645, 64662, 
+    10770, 3669, 3968, 64115, 66644, 13028, 120302, 12537, 194802, 64120, 
+    65720, 12536, 2350, 13029, 6583, 120072, 12116, 13030, 66678, 4527, 1588, 
+    12538, 8409, 65718, 10683, 41670, 787, 9502, 4948, 12484, 4032, 118940, 
+    7449, 65399, 6207, 120536, 6117, 65401, 8412, 65247, 7438, 8734, 644, 
+    9769, 41657, 10149, 3659, 9533, 184, 1553, 10827, 12488, 65382, 10502, 
+    41556, 12623, 65474, 2354, 120214, 8220, 118856, 6295, 901, 41510, 7953, 
+    118826, 5157, 4020, 63811, 11927, 66584, 13079, 194959, 41687, 64303, 
+    120735, 7520, 848, 9868, 65620, 6424, 194714, 65916, 66495, 64094, 
+    118926, 7877, 2352, 41826, 120726, 64576, 11289, 1407, 10911, 65607, 
+    13026, 120503, 7941, 11715, 8362, 8903, 9777, 66715, 1871, 5869, 8636, 
+    120290, 1343, 65160, 12649, 9325, 13025, 6283, 11738, 12643, 194623, 
+    65181, 11741, 8543, 10051, 9216, 8263, 11279, 41258, 8625, 118840, 11290, 
+    10477, 3136, 8733, 11582, 8315, 13022, 8772, 64588, 0, 6152, 41456, 5477, 
+    6629, 10112, 19916, 13020, 66723, 8675, 120324, 194766, 67600, 120351, 
+    10978, 8029, 6091, 120350, 4485, 3335, 64591, 3590, 9776, 41397, 66578, 
+    5215, 194750, 3333, 1632, 63900, 3588, 3342, 9341, 5363, 12957, 12725, 
+    68113, 63852, 64076, 223, 64079, 1611, 13246, 13018, 65835, 63792, 65245, 
+    3337, 1171, 11275, 11736, 41097, 1805, 6482, 41423, 64113, 11945, 8708, 
+    13046, 8838, 425, 4025, 5013, 41868, 120235, 2392, 13047, 4530, 120105, 
+    10617, 1213, 119233, 120103, 797, 118814, 7888, 13050, 120349, 64387, 
+    4115, 65557, 65862, 65587, 3277, 8929, 4947, 41055, 195072, 64276, 426, 
+    66497, 13045, 8251, 10136, 7751, 120109, 8371, 119253, 1224, 12806, 8768, 
+    13044, 10701, 1764, 3101, 64469, 8480, 1078, 9757, 65223, 41057, 65567, 
+    120572, 8663, 9312, 4413, 4539, 3787, 42160, 9222, 67617, 9165, 1572, 
+    9092, 12593, 41961, 2346, 12724, 8958, 66653, 9646, 3773, 41825, 1293, 
+    7947, 12003, 120228, 13043, 8056, 2454, 5349, 208, 194718, 65869, 64849, 
+    65888, 8816, 10699, 6408, 0, 7825, 5661, 917587, 12595, 3603, 41109, 
+    2398, 3548, 1157, 64291, 8638, 68167, 917821, 3115, 194771, 11321, 
+    118787, 8235, 4405, 10086, 4876, 194808, 195085, 119256, 65430, 10624, 
+    6079, 12646, 10764, 8158, 41561, 41472, 998, 13051, 13105, 3143, 120156, 
+    194673, 41559, 1896, 7882, 13052, 118948, 5665, 530, 65814, 11269, 
+    120566, 12002, 64526, 5742, 5664, 4692, 8979, 12310, 4007, 5004, 11330, 
+    7896, 751, 6595, 3382, 63959, 66373, 13231, 11533, 64874, 4732, 6311, 
+    194936, 11596, 63976, 1626, 63977, 10110, 64056, 41705, 6420, 6598, 
+    64327, 6599, 2795, 4910, 65308, 118825, 119328, 6275, 6597, 41699, 8340, 
+    119335, 3229, 6423, 42774, 11019, 65390, 5407, 12823, 2331, 41678, 42026, 
+    6137, 2336, 7524, 194816, 66720, 42759, 8339, 1921, 120003, 19927, 
+    195038, 822, 64870, 9903, 4284, 119593, 194648, 43010, 12841, 9229, 
+    10956, 41255, 12607, 5311, 1795, 965, 3521, 10587, 5774, 8325, 917931, 
+    65403, 917915, 1854, 10794, 119250, 10057, 6294, 3144, 64780, 5280, 
+    65019, 4344, 12905, 41610, 6076, 748, 12385, 768, 535, 442, 9507, 194641, 
+    119346, 10556, 2475, 12388, 4889, 8968, 6071, 3593, 64093, 4804, 2342, 
+    917797, 1800, 120098, 4894, 467, 4890, 120342, 64644, 120707, 4893, 8421, 
+    12433, 10666, 4888, 502, 64080, 64615, 41490, 120142, 12043, 10119, 316, 
+    65878, 10230, 65191, 41297, 64924, 64086, 64746, 2332, 4860, 412, 65728, 
+    11997, 12432, 9583, 8058, 5546, 8019, 194597, 66561, 63750, 12203, 5544, 
+    2355, 8913, 65725, 4875, 10613, 66692, 12137, 5548, 9344, 6250, 7944, 
+    65582, 13104, 6077, 12383, 64519, 119132, 11301, 3134, 119339, 65696, 
+    4669, 917812, 917789, 194894, 3050, 63839, 10319, 119075, 10383, 118842, 
+    4592, 11008, 10809, 194800, 4691, 6543, 9345, 621, 917597, 120055, 4328, 
+    10734, 120032, 64631, 917906, 7804, 19904, 10811, 8457, 10545, 4914, 
+    10271, 3786, 8886, 4917, 66461, 64914, 7923, 3716, 5464, 9996, 8508, 
+    2361, 7971, 8195, 194706, 9566, 7682, 3722, 8086, 41707, 10845, 545, 
+    2312, 40977, 10050, 10874, 8305, 8859, 41458, 40980, 65110, 13202, 
+    195028, 12582, 9119, 2787, 7920, 41521, 4021, 6288, 7985, 119349, 5653, 
+    65802, 10891, 7698, 5658, 410, 41552, 1802, 12220, 4913, 120466, 41659, 
+    41671, 1827, 917894, 64396, 41668, 9077, 2327, 8810, 11422, 120372, 
+    12705, 3860, 10756, 9239, 8821, 6153, 2867, 119118, 42158, 698, 120359, 
+    8749, 10356, 12698, 64858, 361, 12641, 845, 194599, 41560, 11970, 4562, 
+    63756, 2926, 119566, 4099, 66439, 194695, 7936, 120303, 611, 68124, 4716, 
+    118891, 41382, 119207, 7686, 120568, 194595, 68178, 120543, 118875, 
+    119612, 6291, 5462, 10823, 41669, 9734, 65455, 9071, 4655, 4151, 13295, 
+    0, 66632, 839, 42162, 7695, 8769, 65246, 10737, 119194, 4859, 64467, 
+    65504, 4826, 64157, 41090, 917837, 6647, 64727, 66447, 63845, 2700, 
+    12576, 7842, 12839, 120825, 804, 2699, 66596, 10542, 2985, 119222, 64806, 
+    8271, 10091, 11915, 9468, 119312, 9827, 64106, 119311, 286, 12323, 
+    118830, 11481, 118942, 119305, 1425, 35, 119229, 65084, 66694, 41210, 
+    64432, 8482, 119113, 6090, 5032, 7812, 10534, 7894, 664, 119588, 5034, 
+    4272, 65211, 40967, 40965, 42024, 12704, 13294, 66589, 64869, 6032, 
+    120367, 9129, 7430, 917922, 119609, 68112, 194813, 5244, 6130, 65714, 
+    41161, 5518, 4174, 1879, 8189, 968, 12222, 1169, 434, 11541, 66573, 6034, 
+    9739, 64744, 12574, 118867, 194995, 524, 118990, 118934, 788, 120433, 
+    12679, 64506, 64150, 1663, 10419, 8574, 41227, 118805, 12346, 12855, 
+    64848, 41030, 10415, 41562, 120599, 65623, 118850, 64571, 0, 19939, 
+    67614, 959, 8885, 12564, 64333, 118855, 9469, 5195, 5445, 9355, 64323, 
+    42151, 4644, 8989, 221, 310, 41253, 41564, 8010, 119301, 4962, 63766, 
+    8855, 10054, 6497, 9091, 917544, 9012, 19958, 12088, 41002, 13215, 65047, 
+    10451, 64260, 374, 120153, 816, 64634, 120148, 120054, 41934, 3873, 8367, 
+    917784, 64608, 4715, 6101, 11987, 41936, 194572, 4879, 12723, 65089, 
+    11683, 307, 120416, 9585, 5374, 64286, 1462, 10235, 41390, 8627, 65579, 
+    12119, 65028, 13024, 1929, 120426, 12142, 8611, 12236, 41419, 194618, 
+    66507, 12982, 64374, 5378, 194666, 64295, 41421, 917838, 741, 10083, 
+    119309, 65026, 821, 65350, 2498, 5800, 10755, 2992, 1760, 8124, 4469, 
+    2324, 828, 3611, 119084, 757, 1185, 120271, 531, 120728, 10628, 119020, 
+    120437, 7999, 8204, 3614, 2827, 9696, 10942, 7713, 2348, 4354, 10904, 
+    4380, 19936, 7833, 10573, 5320, 41240, 862, 3000, 10301, 1810, 3673, 
+    5137, 9525, 64569, 9354, 65622, 0, 7566, 10121, 64940, 120716, 66693, 
+    12824, 13066, 3062, 7970, 64741, 12608, 194600, 5871, 41160, 9700, 12580, 
+    917591, 65748, 119811, 3967, 7898, 13137, 8775, 64560, 12713, 2963, 9090, 
+    8410, 4454, 723, 1734, 966, 4449, 917815, 64594, 2456, 231, 2320, 120225, 
+    339, 4968, 120535, 40989, 8075, 1230, 120795, 8047, 3597, 9761, 10584, 
+    41542, 65404, 1290, 66358, 8352, 917874, 5687, 66698, 3840, 1584, 119963, 
+    6045, 0, 10498, 9704, 64136, 64138, 10992, 7537, 12311, 8660, 120357, 
+    8365, 8643, 65029, 119049, 4483, 1709, 64399, 7466, 6080, 13092, 64140, 
+    1746, 6072, 8667, 12121, 65604, 13140, 11414, 65031, 2531, 4480, 120765, 
+    64141, 1226, 1259, 7517, 10394, 41231, 10897, 120257, 605, 67619, 641, 
+    5219, 12342, 64100, 41500, 41129, 311, 11453, 6221, 9075, 120358, 5466, 
+    10877, 118868, 11451, 120737, 4535, 2667, 4271, 65406, 64188, 345, 41410, 
+    10829, 41198, 195027, 41407, 64104, 5037, 41131, 1776, 8422, 11266, 
+    64103, 41508, 4660, 323, 65305, 917813, 6649, 1295, 120010, 4625, 2563, 
+    4630, 247, 119135, 119870, 12338, 4651, 2668, 6657, 194941, 13223, 11933, 
+    2519, 119973, 41903, 41079, 5053, 194787, 5049, 119924, 11335, 706, 7754, 
+    7727, 8738, 4031, 6278, 5009, 9672, 649, 5514, 118920, 66702, 10280, 
+    12670, 1013, 41218, 3877, 705, 41591, 8755, 194900, 1183, 4184, 8268, 
+    65918, 65301, 8157, 9736, 64503, 65418, 118921, 4747, 4712, 43013, 11913, 
+    4718, 194632, 10837, 5141, 10614, 65733, 7962, 12211, 9837, 65831, 64722, 
+    119008, 5719, 65706, 9773, 119068, 119147, 1857, 65547, 4626, 8464, 859, 
+    194795, 4629, 8499, 6059, 41134, 4624, 7818, 8535, 119914, 65179, 7805, 
+    64805, 11488, 12242, 41011, 120220, 64119, 10558, 917955, 917918, 118950, 
+    8492, 8250, 8459, 120597, 1788, 1579, 10766, 64117, 195050, 8048, 9543, 
+    9028, 120522, 64516, 65849, 13185, 1285, 64114, 120777, 8240, 8684, 8170, 
+    6102, 41762, 5298, 12625, 5294, 65204, 42013, 3940, 41597, 119917, 
+    917873, 9816, 8665, 65851, 11436, 12630, 1653, 64669, 10153, 120601, 
+    6166, 118791, 118989, 41377, 5292, 66673, 65046, 1939, 913, 3970, 64599, 
+    12455, 1793, 66637, 120162, 118837, 6643, 8211, 65263, 0, 194703, 64127, 
+    64081, 119125, 3514, 13219, 9569, 10865, 11958, 5263, 13286, 64126, 5500, 
+    10022, 65387, 65500, 65384, 5322, 980, 66354, 10008, 5324, 66600, 3784, 
+    41614, 64751, 6230, 194767, 63885, 10085, 3360, 8098, 11523, 6634, 41734, 
+    10096, 41613, 8072, 119321, 119322, 41821, 1249, 7783, 41731, 12032, 
+    8237, 63840, 64899, 12395, 7425, 12818, 120565, 10462, 41150, 194574, 
+    9795, 66680, 64664, 13213, 194601, 120222, 41152, 194679, 9249, 6565, 
+    7808, 1829, 120479, 11670, 4358, 65315, 6670, 11426, 194865, 120223, 
+    12391, 1710, 12160, 10168, 8777, 9781, 49, 6627, 66708, 6258, 8269, 
+    120594, 9741, 194923, 5649, 119100, 315, 12813, 1643, 119988, 12397, 
+    3470, 8884, 65175, 41099, 65314, 13299, 1378, 65163, 1072, 120607, 
+    118802, 3066, 6576, 119300, 120002, 65675, 1080, 41293, 8787, 194828, 
+    1101, 41618, 120001, 8405, 0, 12632, 1086, 1869, 42088, 7680, 8847, 
+    10805, 65884, 12639, 3380, 8123, 1091, 6121, 7977, 4501, 12665, 8119, 
+    12998, 66309, 917927, 1494, 11693, 3127, 194567, 64945, 12930, 1394, 
+    119230, 65872, 12363, 5345, 9789, 2998, 9527, 120659, 64582, 12977, 
+    12309, 42090, 3861, 10635, 12939, 12404, 12413, 42003, 2495, 5848, 8726, 
+    5570, 1881, 12410, 41722, 1012, 8100, 7890, 120296, 11298, 10649, 5569, 
+    6229, 1593, 65319, 6063, 619, 65128, 65080, 6053, 65602, 4120, 65337, 
+    64372, 9160, 917928, 119214, 11776, 9366, 9016, 42006, 6055, 3870, 4279, 
+    2500, 10757, 1507, 8497, 8602, 65316, 13021, 65334, 65333, 11694, 65331, 
+    42059, 42061, 9080, 120099, 9128, 64480, 5571, 3674, 9740, 9121, 4371, 
+    5798, 10408, 42085, 10107, 4106, 41989, 65313, 42074, 63999, 11326, 0, 
+    10233, 13098, 65813, 41239, 10094, 195026, 8182, 0, 119831, 68152, 11947, 
+    9803, 5847, 1505, 9131, 65161, 4615, 12695, 41988, 41250, 12175, 917864, 
+    19966, 119582, 7809, 120626, 120445, 562, 8120, 6590, 194565, 13033, 
+    64738, 3219, 68097, 10664, 1366, 1037, 67623, 4551, 65545, 68131, 66334, 
+    10637, 4568, 549, 1570, 10478, 2835, 12517, 557, 9457, 5952, 64649, 
+    41056, 12519, 41004, 119307, 2825, 66636, 10825, 8079, 2821, 41046, 0, 
+    42071, 12111, 3927, 13071, 12515, 452, 5271, 5492, 64718, 2831, 10604, 
+    10144, 11465, 5212, 5493, 41120, 8916, 13027, 9747, 12019, 41332, 1618, 
+    12069, 917584, 1668, 10430, 917766, 5853, 1187, 10363, 1121, 12956, 
+    120656, 119107, 11314, 3240, 12060, 12194, 65180, 41631, 11591, 5323, 
+    8166, 4557, 6415, 2707, 8309, 1623, 65297, 41052, 571, 2697, 4918, 11339, 
+    4912, 2695, 11598, 65048, 66438, 8864, 64755, 64798, 10736, 2693, 12125, 
+    7615, 12826, 1164, 194583, 6411, 1035, 41067, 119142, 7881, 701, 9758, 
+    3489, 119296, 7469, 11569, 5248, 12218, 120538, 6303, 3796, 41123, 65688, 
+    3994, 11421, 10457, 9991, 41128, 64485, 5792, 12347, 9873, 42171, 2855, 
+    7994, 64762, 6104, 65351, 6591, 9340, 9532, 1589, 119226, 296, 3246, 
+    7906, 2879, 41981, 41620, 64942, 7815, 65855, 120482, 917817, 66457, 
+    10585, 12579, 1496, 747, 6416, 942, 2378, 10960, 11618, 5299, 0, 9320, 
+    5449, 1232, 8139, 6216, 41431, 917970, 11409, 5295, 66624, 64392, 1223, 
+    1642, 174, 120824, 11612, 4161, 2374, 120546, 8475, 3212, 66313, 3211, 
+    194576, 5286, 119297, 0, 64142, 9728, 3846, 8070, 5536, 6636, 7705, 
+    11942, 11305, 12136, 3309, 67612, 66377, 41491, 66325, 4986, 12189, 
+    41653, 1280, 1241, 917537, 4257, 8496, 67608, 6220, 9004, 65411, 65203, 
+    41513, 41650, 120791, 194578, 120608, 12914, 12884, 194575, 9890, 6078, 
+    10237, 917943, 1475, 64917, 11979, 6084, 118900, 41064, 41061, 9635, 
+    12600, 3256, 41236, 42039, 0, 6469, 65377, 8727, 10654, 4679, 41237, 
+    64073, 64867, 6531, 65285, 65329, 64069, 10640, 3248, 2613, 3261, 9015, 
+    119829, 66568, 3635, 64337, 41651, 41241, 64944, 3494, 6449, 6555, 10588, 
+    66588, 120581, 194783, 67597, 635, 13139, 65898, 65613, 65312, 5447, 
+    68108, 194826, 64382, 4010, 7445, 8600, 41915, 65804, 4176, 41105, 5812, 
+    65820, 6232, 65891, 68142, 194588, 318, 5302, 195022, 6538, 4335, 3649, 
+    3941, 41122, 41110, 3634, 64892, 9113, 1954, 12155, 7866, 120297, 11402, 
+    11733, 64296, 120138, 66470, 2849, 66375, 66697, 7938, 11728, 1761, 4586, 
+    65379, 350, 10930, 119090, 509, 194792, 119603, 9365, 66687, 542, 5133, 
+    41680, 64551, 9500, 11534, 1514, 11668, 65823, 5453, 65533, 64921, 
+    119967, 2496, 8493, 944, 9368, 3890, 1624, 1438, 8817, 120592, 10818, 
+    41947, 1220, 120828, 63931, 1194, 3242, 1571, 9555, 8598, 11457, 6169, 
+    943, 564, 2798, 312, 194999, 11532, 66363, 120161, 8877, 269, 3495, 6272, 
+    9617, 1460, 8988, 120660, 4891, 195031, 10641, 0, 41119, 41416, 917602, 
+    4173, 120289, 63786, 120574, 12895, 64955, 41418, 11357, 119022, 120286, 
+    41415, 6296, 9582, 193, 12188, 917835, 64680, 11428, 1730, 2457, 4493, 
+    2314, 8427, 1362, 9822, 7703, 8840, 5807, 119054, 120451, 8534, 6658, 
+    4426, 917796, 41612, 42758, 11497, 7874, 8681, 5220, 120281, 13136, 
+    119825, 2416, 3310, 10972, 63886, 379, 119215, 13220, 63787, 120449, 
+    3223, 5517, 1284, 8041, 4549, 120475, 5240, 9811, 10012, 3096, 65239, 
+    42768, 43040, 8515, 8688, 12866, 64146, 3294, 9501, 119631, 1272, 65485, 
+    7564, 64654, 7467, 65210, 1467, 10158, 10040, 5288, 9519, 41861, 8132, 
+    64090, 118899, 12193, 66615, 65493, 3215, 917863, 7710, 1610, 65114, 
+    12307, 63881, 65682, 66465, 5181, 5275, 120195, 228, 8637, 1501, 66676, 
+    3789, 5179, 11471, 6225, 10765, 11474, 1725, 66603, 8196, 9352, 12042, 
+    42752, 917543, 9537, 3961, 5762, 1967, 2605, 4500, 63873, 8104, 4981, 
+    7474, 3405, 64862, 11667, 10414, 9821, 8141, 9559, 2600, 1557, 7589, 
+    64851, 64549, 3237, 8631, 2545, 10466, 8541, 917616, 194747, 41866, 
+    917973, 120430, 42762, 7481, 0, 1650, 262, 1637, 10958, 7901, 3238, 
+    41945, 65556, 41941, 3308, 65158, 10860, 8614, 65220, 7527, 120624, 
+    41943, 6419, 120244, 45, 6401, 120022, 8106, 4128, 10065, 64083, 4494, 
+    9590, 4012, 10395, 917762, 9084, 4537, 8737, 64089, 11004, 695, 739, 696, 
+    7611, 2620, 42755, 194913, 9227, 7506, 179, 5098, 691, 738, 2853, 7512, 
+    7515, 3868, 688, 119009, 690, 2548, 737, 974, 2801, 119837, 10854, 
+    119012, 10034, 3985, 8783, 65860, 9362, 10177, 120247, 4682, 118869, 
+    12809, 6406, 4685, 3158, 10879, 4389, 4680, 923, 41863, 3851, 292, 13002, 
+    119845, 119844, 3221, 1763, 64468, 4612, 119851, 119850, 12999, 41219, 
+    11718, 41314, 10782, 3637, 12996, 119141, 11717, 63922, 10594, 3228, 
+    11712, 64624, 120405, 10967, 2731, 194721, 9651, 651, 3891, 7696, 66706, 
+    2337, 1735, 120630, 917891, 4177, 11283, 9089, 66312, 64695, 120580, 
+    11438, 1860, 2654, 7580, 1856, 7497, 7584, 194722, 66356, 10914, 3458, 
+    3208, 12975, 8498, 119121, 8949, 3065, 9450, 120472, 1569, 63888, 12534, 
+    12124, 7690, 119254, 12533, 120251, 6418, 4543, 41471, 917629, 64674, 
+    42180, 194881, 0, 10859, 917615, 41544, 41689, 63789, 12282, 64909, 6646, 
+    11790, 8108, 8850, 9238, 5066, 8561, 4573, 13108, 6421, 12791, 119849, 0, 
+    8257, 12891, 8778, 10630, 12900, 917992, 10950, 8314, 6459, 12790, 8804, 
+    65092, 41153, 12792, 11342, 42018, 1744, 12789, 10366, 12317, 10137, 
+    67610, 13164, 10723, 967, 120253, 64546, 12690, 41307, 3257, 65550, 9862, 
+    1845, 2974, 10446, 11315, 0, 278, 10580, 10089, 870, 66569, 3499, 8609, 
+    42149, 876, 871, 877, 6002, 878, 42015, 879, 120336, 4563, 65176, 41308, 
+    7591, 65306, 867, 9520, 872, 8646, 868, 873, 119868, 11514, 869, 874, 
+    63989, 1940, 875, 790, 220, 65193, 194845, 10678, 10044, 41589, 5429, 
+    13082, 194585, 6403, 5707, 10393, 120005, 120267, 42067, 41890, 5433, 
+    10657, 7911, 120266, 1547, 9775, 3959, 119316, 5425, 4977, 2467, 5317, 
+    5423, 4611, 63843, 8040, 5069, 9679, 4182, 119244, 4676, 120501, 41073, 
+    4418, 2510, 4628, 10208, 12989, 118784, 10399, 1851, 12186, 119574, 
+    11908, 120254, 9360, 9083, 13180, 41764, 11601, 12837, 8829, 7711, 64423, 
+    12115, 67636, 12377, 41281, 8809, 41647, 365, 12056, 10857, 917831, 
+    41716, 65395, 41228, 119865, 5516, 2845, 7717, 4588, 41717, 63830, 544, 
+    12045, 2433, 917897, 5515, 3352, 65373, 64377, 65437, 793, 65194, 194740, 
+    305, 567, 119002, 842, 66627, 8208, 917556, 41695, 1647, 118877, 5608, 
+    63824, 65407, 818, 5337, 119143, 13278, 65597, 9638, 8061, 8735, 12483, 
+    120468, 13003, 6667, 10973, 66359, 1372, 118858, 7556, 4969, 1254, 11264, 
+    989, 64257, 118862, 65228, 6060, 65266, 4326, 2840, 64601, 13068, 194985, 
+    65242, 3245, 5768, 65601, 949, 119351, 194893, 6148, 8605, 2651, 119634, 
+    64570, 917912, 119563, 194888, 65106, 120418, 41451, 63871, 41796, 1269, 
+    6530, 63868, 41777, 6414, 5144, 3226, 655, 752, 4431, 4331, 7452, 3285, 
+    41834, 5279, 12908, 10336, 8312, 41754, 12091, 671, 250, 7434, 618, 668, 
+    610, 6428, 7431, 1152, 5256, 640, 41229, 7448, 1067, 255, 3905, 65196, 
+    9493, 65588, 41014, 10795, 194791, 194741, 120421, 917772, 10653, 41272, 
+    195001, 13287, 917805, 6560, 9019, 118943, 195052, 65409, 987, 64410, 
+    5527, 2768, 10684, 3365, 5135, 118924, 12796, 11953, 120412, 65732, 5139, 
+    346, 11334, 6305, 12609, 4675, 5168, 5530, 5210, 917774, 4627, 8253, 
+    5208, 1136, 65433, 120587, 5218, 7976, 118864, 11963, 3244, 5529, 0, 
+    194742, 917794, 5432, 64258, 4041, 8784, 2357, 11521, 5528, 229, 42140, 
+    65876, 12350, 65848, 119881, 12241, 119197, 4000, 7429, 7428, 665, 7424, 
+    3206, 7770, 7884, 64853, 0, 65838, 194779, 211, 2509, 7790, 10470, 7861, 
+    3220, 9156, 64050, 450, 8951, 5214, 10432, 8118, 5450, 10768, 1233, 4661, 
+    5852, 8984, 66338, 41802, 1708, 1839, 40985, 2623, 10927, 1701, 195064, 
+    2388, 4698, 41761, 1066, 8361, 4701, 41758, 5444, 2617, 64889, 8267, 
+    66645, 65610, 194642, 7516, 118958, 2625, 8801, 3053, 4340, 120139, 3631, 
+    10955, 7850, 120292, 8416, 119977, 4008, 65507, 12644, 12660, 8232, 
+    12156, 194807, 194624, 41069, 41719, 65812, 12099, 4310, 4336, 6252, 713, 
+    41068, 7990, 3990, 119203, 65113, 64638, 5017, 13145, 4489, 118959, 
+    42138, 1030, 5358, 64577, 9513, 10196, 9357, 194764, 1773, 10250, 10258, 
+    2712, 1635, 7745, 1410, 12077, 64650, 94, 1880, 120149, 194731, 8908, 
+    559, 118879, 12862, 194984, 10752, 4892, 10876, 64537, 6542, 8732, 8472, 
+    5777, 1757, 759, 4696, 2586, 65248, 8945, 8466, 3641, 5419, 41803, 42062, 
+    67596, 118806, 120344, 3668, 65754, 8610, 12226, 7592, 856, 2340, 936, 
+    13289, 64478, 66631, 1459, 65747, 10499, 2962, 19953, 2321, 1504, 10465, 
+    41312, 8921, 120548, 7529, 65154, 64525, 41901, 63814, 4113, 2949, 2372, 
+    336, 194774, 2958, 12152, 5348, 682, 2395, 65252, 13291, 7513, 10593, 
+    1703, 4013, 64764, 8033, 120064, 65152, 9810, 6534, 4150, 12970, 8318, 
+    41790, 10109, 41893, 2360, 41794, 12858, 120493, 3999, 3777, 65629, 1965, 
+    9796, 2411, 11336, 799, 195097, 10276, 10308, 10372, 41714, 8501, 63833, 
+    2317, 10260, 41317, 65767, 5417, 917969, 10384, 120073, 9353, 917546, 
+    7753, 2351, 6655, 64489, 6569, 13119, 119812, 41287, 119236, 230, 11293, 
+    12009, 119813, 4855, 4165, 8746, 5441, 9654, 10288, 10320, 65665, 855, 
+    120396, 6109, 4784, 12337, 13270, 7786, 10098, 41147, 194570, 63769, 680, 
+    6274, 10312, 1181, 19915, 3174, 13127, 120011, 64822, 41887, 41444, 4862, 
+    9735, 6537, 119237, 66650, 3914, 41037, 10828, 9007, 12961, 41039, 
+    118861, 9033, 6231, 289, 65302, 4694, 11420, 4690, 120654, 42760, 194898, 
+    4693, 63816, 40987, 4667, 4688, 120591, 8828, 194637, 65763, 1246, 3110, 
+    19940, 12197, 11021, 4749, 917895, 43035, 921, 218, 64868, 1520, 242, 
+    4786, 1566, 8217, 8932, 64653, 7834, 10088, 6548, 118908, 64681, 5313, 
+    951, 8888, 64534, 4816, 7604, 43032, 4009, 194694, 194717, 65440, 41549, 
+    119069, 12340, 119138, 119887, 4689, 119888, 4048, 120158, 119209, 6507, 
+    1646, 41755, 119891, 4040, 194734, 65118, 68134, 2579, 119905, 3177, 
+    8207, 9099, 4107, 120130, 119894, 662, 120706, 9244, 66623, 13059, 10084, 
+    120339, 65669, 65836, 10179, 41929, 3399, 9851, 40991, 8739, 9059, 0, 
+    7687, 64637, 8854, 40993, 52, 13241, 6475, 917901, 120444, 1777, 9151, 
+    1137, 118914, 749, 65169, 120584, 5385, 3978, 65842, 120283, 11592, 5989, 
+    65827, 10170, 65013, 6544, 41685, 64702, 119365, 8425, 41684, 917780, 
+    519, 10369, 11740, 1585, 194987, 9888, 422, 1500, 10305, 986, 41170, 
+    3666, 5781, 5599, 3098, 2494, 120202, 4861, 0, 64334, 63986, 6558, 64818, 
+    41221, 42165, 8961, 252, 10243, 10245, 63936, 917505, 120398, 194707, 
+    63751, 9478, 2508, 9060, 119587, 202, 10761, 119114, 1242, 12899, 120447, 
+    11734, 63940, 11730, 917937, 9593, 10543, 2403, 12979, 64609, 0, 9787, 
+    2504, 9784, 41024, 7764, 42076, 9514, 64132, 5859, 119259, 2858, 8298, 
+    12333, 65040, 65478, 9691, 4971, 12992, 2753, 1936, 917877, 8456, 2751, 
+    12662, 2763, 8953, 42104, 10731, 7774, 4780, 9792, 63990, 194753, 194871, 
+    194693, 118927, 2856, 10019, 47, 10482, 2823, 4365, 120629, 917551, 3647, 
+    7899, 2602, 8417, 65903, 917558, 41135, 118824, 4033, 118854, 194761, 
+    172, 194720, 212, 41137, 1889, 12320, 6545, 64623, 917859, 7597, 8915, 
+    2759, 945, 3732, 120230, 917567, 5344, 194851, 1291, 11485, 9062, 119252, 
+    9531, 13155, 8505, 64479, 12062, 119018, 64703, 65487, 42065, 10900, 
+    10370, 1263, 3720, 12048, 63935, 64292, 41524, 64692, 12652, 6099, 41534, 
+    64133, 63933, 64426, 299, 65540, 118859, 63951, 3524, 12933, 8831, 65752, 
+    8674, 3075, 119890, 8245, 917867, 12624, 120559, 1673, 4811, 63928, 5845, 
+    9338, 3046, 65414, 2581, 4001, 41811, 9820, 64098, 12187, 5551, 68114, 
+    5984, 63791, 120687, 4393, 10566, 68182, 8680, 65555, 118851, 2588, 5422, 
+    65900, 43028, 3491, 2471, 917626, 2883, 2749, 63921, 195054, 7492, 7740, 
+    119355, 119134, 675, 120551, 63924, 194568, 7502, 6219, 63926, 65726, 
+    41232, 9329, 63925, 7610, 219, 63945, 41330, 692, 65200, 120775, 9240, 
+    3181, 9688, 119816, 1222, 65775, 8262, 11785, 64530, 0, 64610, 3092, 
+    12092, 9615, 7453, 120128, 8013, 119857, 120456, 195019, 8895, 5253, 
+    65774, 5458, 917816, 922, 65923, 119318, 11338, 194930, 3218, 12618, 
+    63997, 120469, 11664, 8962, 8569, 9641, 11932, 12202, 3214, 120461, 9604, 
+    12053, 3207, 120465, 63826, 1901, 63939, 120141, 63825, 2844, 3205, 
+    41974, 41286, 12139, 65666, 64708, 119580, 3358, 2606, 119364, 3104, 
+    2608, 11496, 1173, 10901, 5308, 120079, 290, 917988, 11779, 2862, 2792, 
+    64498, 66371, 378, 2610, 66591, 65079, 6552, 65372, 66707, 37, 64195, 
+    120154, 1814, 64860, 3209, 118843, 120804, 10638, 9768, 64648, 917984, 
+    66372, 7606, 2591, 2837, 4341, 41403, 64105, 42159, 5233, 65270, 64792, 
+    120794, 3570, 9112, 119948, 863, 9490, 63761, 1685, 595, 12715, 118871, 
+    1292, 6222, 65705, 3654, 66638, 9637, 120268, 2535, 6541, 119181, 10656, 
+    120246, 3243, 9014, 5606, 63762, 538, 11006, 5602, 7807, 8073, 6547, 
+    10629, 8203, 63994, 3056, 8458, 41778, 8495, 8762, 10508, 917552, 779, 
+    9818, 64367, 2465, 3463, 8193, 65721, 9730, 8695, 4738, 11322, 5811, 
+    4346, 64904, 194735, 504, 64321, 10899, 8982, 119954, 0, 0, 782, 4867, 
+    10883, 1262, 64771, 732, 3737, 194954, 1548, 13151, 120589, 1832, 5604, 
+    5611, 41141, 7460, 4376, 64612, 11991, 3745, 41738, 10011, 1502, 65712, 
+    194670, 3869, 11937, 5702, 3655, 1783, 119899, 5728, 120564, 13285, 
+    42174, 11918, 9603, 5724, 5254, 5727, 7724, 119573, 119901, 764, 5129, 
+    120655, 120460, 10597, 7579, 5614, 5893, 6223, 11720, 42073, 11423, 
+    119863, 64409, 119862, 4792, 917770, 1964, 6559, 11726, 12146, 65378, 
+    10687, 43019, 119629, 894, 300, 65744, 10037, 12223, 118936, 1478, 9783, 
+    2562, 2607, 64740, 64830, 0, 11652, 917627, 11777, 41780, 6132, 64946, 
+    5096, 5095, 2863, 3424, 0, 10454, 68146, 5094, 10093, 4369, 13156, 12306, 
+    5401, 5093, 119909, 12004, 65251, 5092, 526, 11327, 41295, 5091, 176, 
+    41691, 8985, 4104, 119911, 6285, 1215, 11985, 5744, 12272, 9832, 65590, 
+    3713, 13218, 41191, 119343, 8980, 118988, 12293, 8844, 7433, 11794, 
+    42036, 4278, 1737, 8987, 12917, 195068, 9074, 4348, 9335, 7760, 118991, 
+    6553, 10339, 5255, 1786, 661, 120126, 5475, 917876, 41854, 68102, 194754, 
+    12419, 1160, 1267, 68143, 41217, 65858, 10018, 360, 67586, 3621, 64635, 
+    5863, 3137, 11345, 6562, 12928, 41216, 1228, 2616, 119190, 64401, 65234, 
+    10745, 1714, 3135, 120637, 120143, 0, 3142, 119186, 119995, 10819, 64163, 
+    6577, 65772, 64, 1470, 194566, 10291, 6227, 2826, 41749, 66433, 119864, 
+    6163, 9708, 13250, 0, 42011, 41224, 8603, 12206, 5839, 1702, 1240, 41461, 
+    6286, 119882, 5834, 66451, 3858, 119089, 1765, 12086, 42001, 1600, 13228, 
+    64729, 0, 8401, 120520, 11310, 9282, 8882, 118929, 10479, 2570, 2852, 
+    5367, 4601, 120818, 64075, 1234, 6540, 13115, 66310, 12667, 194686, 5002, 
+    10147, 12935, 917601, 194965, 118829, 194672, 8163, 6551, 12727, 120744, 
+    120533, 41289, 0, 13129, 2864, 8977, 602, 10435, 9395, 41675, 119554, 
+    2765, 64540, 41279, 120414, 65924, 0, 119922, 66662, 119220, 10887, 
+    65206, 118963, 64920, 66593, 63914, 12150, 263, 120012, 41288, 917982, 
+    9633, 10886, 119042, 7831, 12067, 10381, 917978, 11484, 8076, 43048, 
+    8290, 8291, 43051, 65833, 11616, 2596, 10852, 10285, 13113, 120711, 
+    42019, 2393, 8766, 9087, 750, 65232, 41574, 10163, 11015, 63913, 10441, 
+    5954, 10225, 4314, 65856, 198, 917956, 730, 41441, 7819, 120199, 917555, 
+    13165, 1720, 63905, 8619, 678, 6529, 68122, 41654, 3751, 917769, 119923, 
+    4262, 1798, 709, 917841, 1354, 1876, 13152, 6557, 3892, 8137, 10449, 
+    120035, 120428, 41470, 245, 41045, 11456, 41233, 64801, 120315, 497, 
+    6136, 5953, 65677, 7796, 41235, 65434, 42045, 9804, 8449, 432, 1281, 
+    64355, 65393, 64339, 10677, 604, 7511, 9120, 1859, 65541, 10460, 3425, 
+    917870, 65782, 2836, 8797, 8490, 9052, 64888, 120206, 2356, 95, 64786, 
+    1738, 120415, 194654, 2832, 64640, 9670, 6096, 917871, 64918, 65151, 
+    10063, 2822, 12199, 4436, 194852, 2566, 11971, 12090, 13064, 1065, 1331, 
+    119097, 0, 2576, 12708, 41142, 5090, 5089, 120263, 9505, 67595, 514, 
+    41692, 319, 2921, 11659, 9477, 5772, 12968, 5087, 118822, 41310, 96, 
+    2580, 0, 10522, 41223, 5085, 1463, 41342, 11346, 5293, 10550, 64389, 
+    3733, 3772, 13090, 12054, 4748, 12482, 64300, 12575, 13091, 63982, 
+    194794, 6677, 7601, 119078, 41413, 64419, 118953, 195086, 195100, 66648, 
+    118945, 64597, 10939, 6106, 65757, 1270, 1132, 120746, 4534, 41270, 
+    66655, 9224, 65574, 66331, 64761, 917881, 3671, 8510, 120695, 65770, 
+    41275, 120823, 917935, 10807, 7963, 42012, 119877, 568, 65227, 6187, 
+    13109, 3854, 41479, 13141, 9715, 66696, 8258, 13253, 4185, 41334, 65148, 
+    8871, 42, 8509, 0, 4102, 120258, 7458, 118995, 65863, 2353, 6308, 41604, 
+    7457, 2611, 7456, 41021, 120563, 194631, 66336, 8045, 11550, 12946, 4484, 
+    8747, 118976, 11789, 41065, 5557, 11990, 9737, 13216, 3747, 9467, 5291, 
+    8878, 1691, 41226, 7451, 7435, 10146, 10905, 9086, 64566, 697, 194675, 
+    628, 7454, 12594, 65261, 10468, 4546, 7731, 65256, 12010, 0, 120598, 
+    3805, 64304, 64293, 120284, 9844, 68111, 6307, 19949, 0, 7544, 12166, 
+    64697, 10516, 120074, 10152, 12648, 10354, 0, 7602, 5785, 41309, 9764, 
+    41316, 65877, 194640, 13230, 41299, 5559, 119835, 8704, 2397, 5556, 9877, 
+    66368, 13122, 9011, 191, 9630, 41837, 42040, 5506, 119842, 120697, 64850, 
+    41072, 12598, 8845, 41577, 194790, 10002, 8889, 6533, 11620, 41570, 
+    41838, 683, 396, 41580, 12526, 917610, 12901, 12351, 65115, 343, 7552, 
+    120553, 41360, 9898, 10481, 4559, 0, 1956, 118857, 917836, 64048, 1724, 
+    1210, 119323, 9412, 3739, 6263, 1886, 194869, 3964, 6592, 38, 8533, 9234, 
+    10947, 65073, 13063, 194752, 1778, 3956, 65091, 42070, 6563, 119324, 
+    8743, 8369, 11739, 10941, 12467, 65722, 5547, 66618, 120432, 120513, 
+    8175, 8843, 284, 2429, 934, 5696, 917996, 173, 65560, 8652, 12699, 11650, 
+    1750, 120709, 4394, 65056, 1807, 6613, 12606, 64528, 5889, 63783, 917949, 
+    64714, 41848, 11516, 12162, 12120, 12478, 1721, 7767, 7891, 65864, 10563, 
+    2583, 4512, 63973, 2462, 7693, 1837, 10434, 3855, 8107, 41337, 63972, 
+    4952, 65413, 64405, 5504, 41340, 3975, 65715, 65716, 65420, 12672, 3798, 
+    2703, 194709, 64347, 9349, 9774, 41847, 1127, 455, 41095, 3962, 10100, 
+    3483, 41101, 3954, 6457, 4513, 9104, 3503, 7688, 41298, 1468, 65386, 
+    1864, 41851, 63970, 41446, 2540, 7736, 41080, 41849, 917619, 4320, 3224, 
+    12909, 9705, 41565, 8604, 118903, 1510, 11306, 6149, 3887, 11393, 1411, 
+    2824, 194708, 10106, 8770, 1403, 120811, 1347, 9631, 8671, 65737, 4283, 
+    64074, 119936, 8640, 13124, 258, 1654, 41408, 8858, 65738, 42139, 3741, 
+    42761, 4042, 4581, 2873, 11617, 11522, 120114, 8549, 10861, 194784, 
+    41673, 64829, 1733, 4392, 2568, 10786, 63983, 67629, 376, 41486, 9221, 
+    64871, 119907, 8823, 41222, 12857, 6217, 7965, 4896, 64911, 10154, 
+    119108, 41350, 8301, 118823, 7446, 1684, 64501, 10974, 458, 41199, 
+    917562, 917576, 194798, 11916, 340, 119000, 12298, 10864, 119918, 12288, 
+    120287, 4388, 1493, 10521, 7553, 4097, 194971, 13080, 11656, 65808, 6610, 
+    6030, 8059, 3210, 13131, 119073, 194827, 13301, 8794, 41278, 41629, 
+    12154, 119131, 9461, 64658, 1186, 41571, 6625, 617, 9464, 12691, 3675, 
+    5207, 63955, 5213, 118896, 833, 41348, 41568, 917775, 3253, 63954, 41088, 
+    8630, 6062, 41440, 5596, 5545, 119313, 933, 1341, 9842, 5217, 194886, 
+    8942, 40962, 194730, 68126, 9905, 2635, 64504, 65130, 12620, 7493, 
+    917577, 7835, 41434, 9002, 19918, 194770, 64558, 194974, 9716, 19954, 
+    5651, 5990, 900, 5784, 194775, 9317, 119057, 3612, 4011, 64376, 41953, 
+    5389, 7864, 917548, 65336, 2839, 5600, 3903, 65609, 10447, 3749, 1207, 
+    7569, 194980, 3501, 194685, 64705, 4403, 19962, 1124, 5597, 195009, 
+    119921, 9321, 4429, 65810, 120515, 119072, 1719, 7598, 546, 9671, 1125, 
+    4399, 9542, 472, 7716, 8452, 5488, 41946, 42025, 194903, 5491, 3602, 
+    8328, 41182, 2604, 41949, 5490, 41183, 5489, 8522, 10287, 684, 6300, 
+    194777, 2854, 119586, 4390, 454, 7823, 65750, 9875, 7593, 65338, 119310, 
+    120625, 64487, 8478, 9881, 2394, 2575, 3415, 3746, 11016, 8648, 66515, 
+    65421, 43047, 119092, 11989, 65142, 418, 65025, 66378, 10295, 8249, 
+    10391, 41752, 4565, 6640, 41449, 2598, 513, 120763, 6586, 8656, 65826, 
+    1024, 11621, 7961, 120809, 8941, 917563, 4554, 11681, 9023, 11682, 
+    120788, 10176, 10964, 119315, 11437, 9509, 0, 1036, 12850, 917787, 1723, 
+    120577, 9049, 41185, 41579, 2444, 11680, 10705, 11686, 118792, 65224, 
+    63804, 740, 63963, 120113, 118874, 120681, 5300, 10407, 9459, 194739, 
+    1875, 66466, 7856, 8121, 10438, 5524, 41698, 2860, 12157, 5238, 120797, 
+    5690, 5743, 10424, 12065, 65805, 7578, 65859, 195051, 8875, 8694, 9506, 
+    13254, 5575, 12847, 2413, 68099, 119340, 962, 12176, 1122, 317, 9040, 
+    119116, 1582, 119251, 1920, 41477, 10173, 827, 10801, 195096, 118798, 
+    120401, 5223, 496, 10439, 4313, 5226, 12602, 7860, 120627, 906, 7758, 
+    2842, 6405, 5224, 5487, 798, 5692, 12801, 7791, 1153, 5695, 12100, 64627, 
+    8054, 9174, 120131, 5691, 287, 866, 233, 4642, 66574, 11556, 7514, 66436, 
+    65140, 42089, 8830, 9008, 120417, 10524, 41175, 42079, 7587, 65709, 5296, 
+    120505, 10688, 10663, 917814, 3302, 66478, 6437, 6516, 6515, 6514, 6513, 
+    6512, 41798, 3920, 8690, 119590, 41201, 12122, 4580, 6568, 6116, 1785, 
+    41965, 120635, 3021, 42004, 5138, 120129, 194587, 41998, 41867, 4540, 
+    41179, 194804, 6200, 11462, 5134, 42021, 322, 4643, 5132, 42010, 194988, 
+    43008, 5143, 64875, 8790, 917807, 65594, 64604, 6626, 8869, 66510, 64400, 
+    42060, 19908, 9878, 194814, 41133, 10270, 10286, 10318, 10382, 65671, 
+    4110, 120507, 11286, 10929, 64277, 3234, 66703, 13058, 8617, 41982, 6025, 
+    120736, 12805, 8767, 194580, 194690, 9597, 41283, 5201, 120293, 6215, 
+    12714, 6214, 13101, 65282, 120490, 65268, 120504, 64524, 120215, 187, 0, 
+    10059, 10511, 4963, 9767, 789, 1749, 7441, 64574, 9901, 320, 41948, 
+    41833, 194831, 3049, 41139, 6471, 9449, 10081, 10528, 42121, 118894, 
+    120562, 4960, 5549, 119359, 65882, 8485, 4671, 1189, 905, 480, 10985, 
+    10240, 10610, 5414, 3064, 1745, 4286, 5421, 5427, 9554, 119077, 66357, 
+    65465, 6653, 8806, 42047, 9442, 6213, 9443, 9436, 7867, 11613, 6236, 
+    42052, 195070, 2406, 119858, 11430, 4566, 348, 5474, 3801, 3103, 10406, 
+    5246, 5236, 64395, 195059, 5200, 64305, 41739, 41733, 64518, 10931, 
+    13181, 41402, 395, 5391, 5198, 8786, 9428, 41259, 5196, 120037, 2691, 
+    42009, 5205, 41244, 5562, 917578, 118973, 41262, 66364, 64421, 119615, 
+    41251, 9126, 435, 3979, 12014, 12893, 8093, 9079, 3203, 192, 119912, 
+    3385, 41266, 64430, 5383, 10294, 10326, 65741, 5738, 9574, 2666, 119861, 
+    5361, 831, 419, 8256, 10716, 7872, 64583, 66688, 1260, 3149, 5359, 7766, 
+    6432, 7914, 5357, 916, 769, 2624, 5364, 64739, 6433, 5563, 547, 1943, 
+    6439, 5560, 4994, 487, 119553, 4497, 3754, 120082, 120615, 9039, 10619, 
+    41776, 194797, 8716, 41622, 40983, 64072, 41516, 0, 9319, 195024, 41376, 
+    11610, 3232, 12185, 119928, 119331, 65905, 119347, 41889, 64071, 8634, 
+    1161, 41895, 118804, 9701, 8622, 41385, 120403, 65612, 120588, 669, 5679, 
+    41362, 43011, 64210, 11921, 42087, 5678, 120750, 66489, 41364, 460, 
+    64636, 41352, 41361, 194824, 41366, 0, 3356, 6178, 917, 7799, 118812, 
+    64068, 7782, 9044, 4974, 677, 119916, 7577, 64189, 41507, 1216, 12504, 
+    11952, 3349, 194683, 12296, 8927, 4739, 3738, 5802, 120474, 5683, 10368, 
+    120661, 491, 1549, 119621, 194659, 0, 5682, 6206, 8670, 9891, 5680, 
+    64297, 10001, 7586, 65580, 1449, 10241, 3768, 65255, 3776, 9095, 7741, 
+    12684, 41885, 1046, 120547, 5567, 2717, 4620, 5171, 5564, 41967, 41908, 
+    41786, 5565, 12819, 12578, 64743, 65708, 5169, 5566, 3465, 64694, 3175, 
+    11904, 1537, 119155, 5176, 5942, 8468, 4871, 10361, 10425, 65697, 65698, 
+    41991, 1128, 65920, 10548, 9711, 10647, 9408, 9409, 9410, 457, 3662, 
+    9413, 1934, 9415, 9416, 8802, 9418, 8909, 9420, 9421, 5897, 9423, 5165, 
+    5126, 9889, 8043, 8950, 65694, 8955, 3374, 9400, 9401, 9402, 8939, 9404, 
+    3507, 9406, 9407, 119241, 19925, 9499, 10035, 183, 65078, 2631, 119308, 
+    10636, 41130, 64958, 3996, 120650, 64675, 1667, 41584, 65486, 41582, 
+    6580, 4332, 64825, 10741, 10726, 12912, 11281, 5899, 8101, 3610, 12085, 
+    41748, 574, 955, 120092, 5340, 5350, 41058, 5446, 63799, 10875, 64796, 
+    5442, 65692, 12437, 9782, 5451, 12896, 3616, 64857, 917959, 3874, 7708, 
+    64370, 5505, 65867, 10345, 10409, 65603, 11909, 65687, 43015, 41038, 
+    120719, 120561, 4447, 8536, 64701, 65143, 66661, 120194, 724, 42048, 
+    1455, 205, 917593, 10351, 64618, 8571, 4175, 6588, 119059, 120380, 939, 
+    41355, 4743, 119154, 5503, 8021, 64622, 119150, 9819, 41357, 8011, 6088, 
+    5507, 12044, 190, 120282, 10026, 4356, 8188, 1191, 13106, 4417, 10329, 
+    5476, 8991, 195008, 7827, 120361, 5829, 8550, 67627, 5592, 2919, 64925, 
+    2675, 5595, 917967, 7918, 4367, 194626, 65554, 5478, 1728, 5594, 120710, 
+    178, 12972, 5590, 10727, 13067, 118909, 65254, 917941, 9731, 120600, 
+    64633, 917987, 12113, 13065, 118863, 9252, 12278, 4652, 119041, 12349, 
+    65907, 194704, 120688, 12887, 10551, 10710, 194833, 195017, 64663, 
+    120570, 41804, 5199, 9497, 1120, 11429, 8333, 1444, 9486, 7554, 13142, 
+    4538, 65096, 1442, 6177, 5894, 917833, 11910, 13224, 8278, 5591, 4034, 
+    9452, 65389, 3334, 64003, 41747, 10708, 194571, 8677, 118828, 1651, 9350, 
+    8861, 120040, 8836, 1142, 12747, 4396, 10928, 66705, 8922, 8856, 66611, 
+    4002, 119188, 10442, 10676, 3344, 11012, 64963, 10813, 2592, 12853, 
+    120242, 66642, 3438, 6536, 7871, 120239, 65516, 12321, 68141, 118890, 
+    120389, 10007, 11784, 9588, 10126, 4700, 11308, 41994, 65801, 8661, 
+    41721, 66572, 12240, 119876, 4973, 5573, 12588, 9629, 40981, 119176, 
+    118981, 5006, 64328, 42002, 64754, 41766, 8825, 13016, 195062, 0, 10346, 
+    6107, 42093, 9243, 2464, 194677, 6108, 3372, 335, 6247, 64689, 438, 4510, 
+    5765, 8721, 119878, 4036, 6092, 11654, 65914, 8876, 10303, 8096, 10284, 
+    3354, 10268, 119830, 9289, 8689, 10316, 3876, 10335, 9725, 42044, 11783, 
+    917893, 119581, 8050, 120030, 195025, 11603, 194820, 120053, 6589, 843, 
+    120419, 119260, 120770, 195053, 10117, 66560, 41902, 12829, 6312, 215, 
+    1963, 13225, 13192, 1953, 9579, 7550, 1256, 3910, 13015, 6242, 41329, 
+    9662, 41257, 41900, 3366, 10700, 8805, 1742, 5542, 9333, 8202, 120459, 
+    120232, 41611, 65895, 120159, 120385, 499, 118846, 8593, 119627, 917974, 
+    41169, 1712, 5932, 8097, 41642, 11519, 119562, 11967, 1775, 65296, 41243, 
+    118957, 5662, 416, 9458, 64687, 6470, 195081, 66675, 10984, 64386, 64672, 
+    65274, 12880, 195083, 41172, 41254, 64758, 120669, 41062, 194825, 9006, 
+    65446, 565, 41760, 5794, 201, 2662, 9419, 11332, 8254, 41726, 10975, 
+    120173, 1021, 65131, 1022, 4108, 3880, 8023, 1200, 12243, 194991, 5282, 
+    7507, 41881, 11545, 5891, 64406, 3343, 1636, 67587, 1885, 65024, 3896, 
+    195056, 9674, 2947, 99, 98, 97, 120571, 64414, 4049, 8221, 64085, 3381, 
+    194978, 7892, 120705, 10777, 194687, 5867, 3913, 66376, 66722, 64315, 
+    8039, 1265, 4316, 6309, 118815, 12969, 12596, 66595, 11791, 12541, 5593, 
+    67585, 5998, 9163, 12300, 6061, 64854, 119, 118, 117, 116, 8930, 122, 
+    121, 120, 111, 110, 109, 108, 115, 114, 113, 112, 103, 102, 101, 100, 
+    107, 106, 105, 104, 6436, 194788, 534, 41212, 119599, 1536, 12114, 
+    120381, 64287, 64936, 64324, 6020, 12716, 10561, 10075, 475, 118888, 
+    13266, 9144, 64590, 917580, 118887, 65749, 10645, 1212, 5079, 119619, 
+    8134, 8483, 2913, 6624, 4908, 1866, 1639, 119189, 194762, 8923, 1645, 
+    12059, 64505, 917977, 194664, 41503, 4817, 5935, 1250, 194727, 8174, 
+    9600, 9856, 9859, 7916, 9861, 5343, 5258, 1882, 1892, 11304, 10882, 405, 
+    11454, 4659, 12343, 657, 12610, 4970, 4461, 1134, 1838, 1454, 41242, 
+    6477, 4468, 5987, 65803, 9762, 4456, 5206, 10720, 194625, 10480, 41718, 
+    5818, 194773, 8264, 10229, 260, 645, 119827, 7609, 40973, 4821, 4466, 
+    120500, 5824, 984, 119027, 8791, 5851, 5705, 7729, 41166, 10591, 41797, 
+    119983, 65438, 66580, 119984, 42101, 41404, 1165, 7879, 4451, 11401, 
+    194849, 11284, 119987, 66566, 41909, 43014, 2791, 9363, 9552, 3375, 8641, 
+    5900, 7539, 7889, 2722, 194854, 13173, 2381, 11602, 10994, 10529, 10773, 
+    11574, 8644, 11581, 12425, 10661, 10856, 9614, 194917, 41478, 11571, 
+    10064, 8308, 10748, 66695, 11005, 4868, 119162, 1952, 41406, 8455, 10082, 
+    11575, 8467, 12577, 12721, 5182, 12183, 6145, 41759, 64929, 4465, 42120, 
+    12135, 5732, 4464, 7728, 3922, 977, 4458, 120043, 120545, 64770, 119556, 
+    3353, 344, 917963, 41626, 1395, 41939, 65832, 5776, 8558, 786, 65153, 
+    120191, 64340, 119352, 10202, 120084, 41027, 7612, 10132, 64413, 120087, 
+    12840, 119119, 119913, 119314, 119139, 63862, 41896, 8657, 194996, 8594, 
+    10204, 195049, 120477, 120069, 65819, 1399, 41375, 120056, 917938, 8852, 
+    64492, 241, 68135, 4907, 194757, 9738, 194975, 9727, 7851, 119196, 10951, 
+    4439, 11588, 119199, 65008, 9085, 65853, 41911, 9327, 6160, 917594, 8650, 
+    64865, 8088, 64933, 41910, 118872, 65217, 3965, 120050, 194713, 0, 13300, 
+    65902, 66654, 65491, 65145, 9041, 65847, 65017, 7504, 4420, 9900, 6410, 
+    7501, 11278, 65825, 9577, 120047, 13217, 8748, 65415, 0, 9867, 9066, 
+    12924, 11993, 917829, 2626, 7762, 10902, 7510, 119577, 41526, 64285, 
+    10472, 2995, 120704, 12907, 41184, 2371, 194994, 10038, 259, 1009, 
+    118838, 2402, 2333, 6440, 194768, 12050, 65125, 0, 12417, 65380, 9103, 
+    10181, 3148, 65873, 6434, 7779, 10198, 194952, 9479, 6029, 65325, 65157, 
+    9689, 41261, 119175, 8993, 8613, 0, 41167, 3368, 606, 41492, 7697, 10228, 
+    41596, 1890, 194769, 6027, 8370, 4322, 41661, 7991, 66512, 10578, 119168, 
+    41465, 41054, 2735, 41664, 120330, 63778, 65273, 1287, 65408, 6635, 
+    66659, 6164, 194563, 41273, 917951, 65027, 41271, 9576, 65043, 3347, 
+    4160, 5154, 917541, 3794, 66564, 9175, 11925, 7709, 9088, 3743, 65099, 
+    1396, 4572, 7546, 3847, 66327, 65081, 4985, 1615, 672, 809, 12980, 63806, 
+    0, 65218, 5799, 41615, 65072, 1577, 194934, 65875, 5928, 4525, 10658, 
+    65911, 1266, 10180, 120702, 6129, 12622, 9347, 917986, 6532, 64424, 
+    41048, 7789, 773, 19933, 1539, 283, 64416, 66374, 532, 917800, 120049, 
+    41115, 3051, 5862, 3370, 120789, 43033, 5439, 3250, 8153, 0, 66649, 9510, 
+    120279, 64647, 9541, 118916, 41066, 64706, 194612, 43038, 3505, 8707, 
+    9466, 11479, 8537, 120802, 3626, 3471, 194860, 915, 194689, 6686, 119584, 
+    120238, 5011, 42754, 120723, 41906, 65569, 119128, 119552, 64365, 119886, 
+    3225, 68161, 4433, 5186, 194957, 41933, 1443, 4381, 9829, 65124, 10926, 
+    194746, 195076, 64879, 10562, 194751, 65476, 64579, 66456, 10021, 5160, 
+    1387, 65495, 6103, 118923, 41480, 12786, 195000, 217, 119898, 11714, 
+    12466, 10443, 10789, 41158, 41460, 1630, 120782, 41483, 65818, 12565, 
+    41700, 10077, 12890, 5931, 194732, 9283, 7700, 41252, 6042, 65499, 
+    119637, 41249, 512, 2990, 917786, 120240, 6413, 917985, 632, 12940, 
+    194875, 41296, 9545, 41291, 5957, 120353, 8926, 3511, 41282, 5923, 10400, 
+    10174, 12073, 760, 5386, 4274, 5786, 10633, 120531, 5056, 119860, 417, 
+    41474, 120773, 11022, 9812, 5934, 4460, 66583, 119231, 64877, 65410, 
+    64481, 194692, 194705, 10937, 194748, 120218, 10509, 65829, 917540, 2953, 
+    5819, 1801, 12835, 194942, 120484, 194743, 65910, 41985, 8867, 702, 
+    120410, 1237, 10274, 4552, 65447, 119966, 194961, 1375, 12106, 120815, 
+    10264, 1755, 9065, 9228, 10376, 1163, 2951, 7840, 64336, 13282, 10252, 
+    120033, 3384, 120703, 10167, 830, 194656, 65425, 10769, 8451, 41368, 
+    12520, 9753, 120147, 8944, 194882, 120248, 10473, 2908, 119614, 19965, 
+    43025, 10299, 65041, 12097, 64733, 12952, 4441, 10503, 917839, 41430, 
+    9330, 194859, 6614, 411, 10315, 9676, 4996, 120213, 13281, 10009, 7865, 
+    2730, 10388, 9677, 5428, 118993, 3364, 7565, 12828, 41711, 118816, 65463, 
+    9535, 216, 10332, 1401, 119895, 622, 65095, 885, 64772, 1602, 4467, 
+    41405, 852, 119635, 12108, 41328, 484, 65187, 41051, 12071, 9609, 9806, 
+    41008, 3338, 120796, 572, 10411, 2736, 10255, 10263, 10279, 2794, 8807, 
+    64491, 10330, 4315, 5222, 5381, 119058, 917995, 5193, 5125, 5456, 5509, 
+    41177, 917832, 9534, 195042, 64431, 1603, 3430, 118982, 10298, 120407, 
+    917885, 981, 41176, 4330, 994, 65841, 1824, 10908, 917879, 41681, 41683, 
+    5921, 65600, 2597, 3957, 5922, 64547, 65784, 674, 119839, 194945, 2946, 
+    5354, 5251, 4406, 5307, 3759, 10131, 8364, 5123, 1433, 5281, 5469, 5121, 
+    5924, 5920, 65758, 5130, 64606, 66481, 119624, 8418, 7576, 1221, 2733, 0, 
+    742, 5216, 2893, 10772, 65276, 5937, 3468, 2553, 9230, 5939, 3997, 
+    195091, 8363, 120677, 2993, 7772, 3916, 10289, 64613, 1141, 41706, 8159, 
+    718, 7572, 973, 9666, 120718, 3235, 2415, 5938, 119620, 8018, 12448, 
+    120556, 9592, 10337, 194918, 917622, 11729, 120727, 8719, 1202, 195080, 
+    64651, 12983, 118970, 12165, 119095, 63747, 9067, 3260, 8077, 65388, 
+    68179, 8419, 63773, 65419, 63774, 194986, 63775, 10725, 10433, 64496, 
+    194861, 1431, 41843, 66565, 10821, 4359, 12804, 12192, 8229, 1235, 3307, 
+    11472, 120617, 3146, 4544, 9009, 8551, 118820, 1740, 194749, 7575, 985, 
+    2724, 13076, 65233, 12068, 119949, 515, 10141, 119944, 9539, 8785, 4476, 
+    119146, 10959, 12655, 8907, 13226, 4589, 4521, 64205, 9141, 64645, 10665, 
+    2741, 41572, 6197, 1370, 10101, 41573, 64294, 3931, 194924, 120585, 6184, 
+    8606, 3303, 11968, 11786, 9473, 13103, 63771, 8879, 11593, 66508, 4478, 
+    917588, 41735, 65837, 717, 10754, 4477, 120376, 814, 42066, 119962, 
+    63767, 1780, 41031, 119958, 41387, 819, 10611, 9694, 11955, 65919, 
+    119953, 41111, 9462, 119071, 7788, 4847, 65542, 6578, 8338, 7523, 120666, 
+    1581, 6535, 7525, 3346, 430, 64698, 66699, 575, 268, 194940, 4945, 66463, 
+    4950, 12918, 9456, 8336, 5936, 43017, 5964, 8337, 13081, 308, 917964, 
+    7522, 64309, 41746, 4949, 118946, 443, 11658, 4944, 5467, 65885, 5926, 
+    1862, 6044, 65392, 8820, 4946, 119247, 9038, 7887, 65667, 7830, 11651, 
+    13093, 2698, 41144, 65742, 12072, 41753, 11590, 41304, 824, 120095, 8595, 
+    65225, 42141, 11415, 4673, 41354, 4678, 13283, 12697, 65059, 12381, 3488, 
+    5933, 5481, 3490, 1199, 65014, 8356, 12297, 119153, 1955, 12375, 3102, 
+    10474, 4672, 118849, 119821, 5531, 119823, 119826, 66332, 8835, 4674, 
+    119006, 5831, 194932, 64896, 12379, 8025, 119947, 64542, 1855, 11957, 
+    5472, 64425, 7852, 119867, 64951, 120467, 11445, 2745, 5470, 65171, 9124, 
+    119110, 4654, 65289, 291, 120762, 12688, 10525, 4649, 65209, 11797, 
+    12647, 4648, 4640, 64713, 10224, 64902, 6246, 64950, 7828, 4650, 41464, 
+    917624, 119086, 4653, 7822, 120331, 12923, 65674, 8669, 194655, 10729, 
+    43031, 5778, 6302, 2716, 194606, 12680, 119130, 1417, 10916, 917569, 
+    6441, 8547, 2711, 11552, 120798, 64953, 7992, 12429, 41907, 4662, 65453, 
+    120408, 9149, 9146, 599, 4641, 9179, 64819, 63782, 4656, 10130, 41469, 
+    7811, 40994, 12426, 4646, 5967, 865, 3725, 5713, 5814, 4645, 42033, 
+    120422, 41756, 13132, 64728, 9026, 10833, 64673, 1659, 919, 41935, 1671, 
+    11459, 3054, 9219, 9744, 1661, 7605, 4622, 119087, 10140, 9713, 12427, 
+    41938, 66674, 9045, 2306, 10485, 19926, 6068, 10612, 10401, 4617, 119596, 
+    120463, 41462, 4616, 10518, 10423, 10359, 66491, 5958, 917842, 9564, 
+    4618, 826, 65577, 4321, 4621, 195048, 41313, 522, 5368, 1808, 7848, 
+    194992, 5366, 12201, 5372, 10913, 12668, 917781, 4391, 64331, 2696, 
+    120155, 11003, 4638, 64490, 1790, 66304, 167, 10921, 9791, 917631, 9840, 
+    5376, 1835, 5335, 10313, 41370, 4633, 64320, 10265, 1180, 4632, 43009, 
+    5387, 5333, 64256, 12903, 41, 5331, 1792, 11928, 41548, 5338, 4637, 
+    120373, 5971, 4289, 120393, 385, 4152, 2585, 194605, 10909, 3126, 1427, 
+    65551, 10957, 5970, 3431, 64890, 10358, 7531, 4758, 917573, 1608, 2738, 
+    7443, 10455, 4753, 917854, 11344, 65729, 6240, 5231, 119013, 12147, 
+    65216, 6248, 0, 2593, 8463, 7810, 65807, 5229, 4757, 65192, 66581, 2728, 
+    4411, 64563, 65235, 5234, 41124, 120424, 9580, 10066, 9746, 119559, 2622, 
+    6033, 13061, 8016, 41196, 8954, 64831, 65189, 2632, 12390, 10108, 1011, 
+    5574, 1853, 2709, 65139, 5577, 42091, 41165, 393, 12450, 8965, 11458, 
+    42177, 5316, 917940, 171, 5941, 5572, 68127, 5312, 12531, 5525, 5330, 
+    5319, 10043, 65710, 42080, 8937, 63798, 12454, 7548, 42132, 12063, 
+    917991, 64343, 3230, 0, 10350, 10644, 5209, 297, 5721, 12109, 8415, 8632, 
+    10102, 11267, 120219, 2497, 5720, 960, 1692, 42146, 4610, 8696, 4292, 
+    64760, 4609, 10512, 4614, 541, 194890, 5287, 5309, 2503, 119243, 1762, 
+    4647, 56, 10743, 5844, 41381, 601, 4613, 10194, 4663, 1899, 4608, 2507, 
+    11025, 5190, 67628, 63759, 68145, 11405, 8892, 120348, 67620, 66639, 
+    2734, 5782, 420, 64368, 63795, 41649, 10797, 5960, 63797, 8992, 65293, 
+    41238, 1782, 12814, 8959, 12525, 10686, 41383, 5501, 41842, 3650, 7442, 
+    120749, 359, 4183, 119957, 6239, 12787, 41256, 329, 66582, 12573, 120452, 
+    7437, 9346, 41188, 13196, 7439, 42167, 3767, 5737, 5380, 4865, 195047, 
+    1155, 120434, 5736, 4368, 64724, 63749, 68137, 5601, 5739, 41023, 4866, 
+    9985, 7987, 41928, 1172, 64572, 917596, 6253, 120365, 6650, 5603, 41666, 
+    4473, 64148, 4870, 65901, 65347, 41799, 65345, 8199, 195007, 5347, 
+    119063, 9280, 4864, 10398, 4144, 119633, 120567, 6245, 120478, 2732, 
+    5598, 745, 4555, 5341, 119847, 4777, 7821, 5351, 120747, 119589, 41950, 
+    120729, 120210, 3097, 63817, 5966, 120363, 4778, 120596, 10863, 1660, 
+    4781, 66460, 271, 41940, 65370, 8577, 65368, 12653, 65366, 10216, 4782, 
+    10000, 65362, 65361, 11912, 12325, 11323, 8717, 41583, 65355, 4776, 
+    65353, 11492, 8700, 761, 13168, 10575, 10426, 917905, 120150, 10362, 
+    11272, 1715, 4849, 8242, 9561, 194982, 195090, 10607, 120511, 120675, 
+    5963, 66563, 41509, 4916, 4850, 380, 1607, 466, 4853, 194905, 4854, 
+    917625, 5164, 41096, 1350, 5124, 64420, 120354, 5362, 8471, 2708, 64716, 
+    7946, 3785, 234, 19963, 120481, 41268, 4848, 2530, 41636, 4798, 1225, 
+    6630, 65684, 10458, 120595, 8576, 5197, 195087, 2704, 4794, 8329, 63823, 
+    8322, 4797, 66326, 5725, 2694, 2595, 3363, 2439, 65104, 5607, 41089, 303, 
+    41162, 119044, 2665, 2437, 917791, 9817, 4844, 8764, 13013, 8934, 65398, 
+    917929, 4492, 120347, 9843, 2441, 10739, 65090, 1188, 119327, 1100, 2451, 
+    2714, 41081, 2912, 194817, 4937, 65746, 753, 3572, 10023, 4959, 11722, 
+    9248, 65815, 9729, 11725, 65190, 119094, 2726, 3107, 194658, 4941, 7996, 
+    10995, 9140, 1408, 5261, 41412, 9068, 181, 119819, 4942, 43043, 4938, 
+    41341, 972, 5259, 4004, 64185, 4142, 5257, 194712, 120529, 4964, 5264, 
+    9538, 64177, 64176, 41225, 64182, 63800, 64180, 11396, 9482, 4873, 3265, 
+    1822, 194867, 12601, 41078, 3865, 261, 5927, 7568, 118931, 118930, 
+    917858, 10696, 9830, 6073, 389, 10467, 6255, 6075, 4872, 282, 194633, 
+    3125, 9567, 195012, 4878, 5459, 4874, 119046, 9557, 3474, 64774, 120356, 
+    11494, 6081, 9563, 9411, 11017, 13017, 11940, 41033, 65928, 10788, 64190, 
+    8751, 10385, 120273, 7816, 9414, 4665, 12628, 4670, 119871, 41555, 
+    120485, 9642, 10912, 958, 12959, 3082, 119112, 4666, 0, 4915, 917896, 
+    2891, 5856, 12096, 5163, 4664, 10836, 1817, 66724, 12231, 41554, 10564, 
+    7450, 13077, 42099, 4400, 9697, 3606, 10275, 8925, 10371, 10307, 1063, 
+    10227, 11410, 9772, 4541, 6299, 1389, 64203, 64201, 9823, 42081, 12941, 
+    19906, 10520, 118839, 119557, 12301, 64192, 10505, 10878, 42772, 64196, 
+    12172, 41814, 1017, 64175, 523, 505, 1447, 846, 0, 41813, 917827, 8608, 
+    120537, 65482, 2543, 12163, 3108, 9745, 4529, 64166, 64165, 64164, 7919, 
+    120639, 1641, 64168, 64949, 8966, 10251, 10247, 5908, 715, 64161, 64160, 
+    7542, 1699, 10943, 10763, 120379, 11352, 550, 10169, 11515, 64385, 66579, 
+    3766, 64856, 5780, 9504, 6611, 257, 10373, 13153, 12061, 10261, 10253, 
+    6404, 2599, 9433, 6496, 1552, 5930, 66664, 11476, 11447, 3128, 4789, 
+    5067, 4911, 3760, 1718, 9438, 8827, 1146, 5065, 41435, 4352, 68136, 2435, 
+    41839, 5064, 5326, 120453, 3778, 1809, 8873, 7824, 19919, 5062, 1264, 
+    64817, 765, 11697, 3764, 8473, 64092, 8469, 3933, 12947, 4564, 7954, 
+    917908, 10375, 917872, 119902, 64768, 194983, 41012, 5225, 63910, 42130, 
+    7903, 5151, 194862, 64121, 64685, 5626, 2569, 66498, 3800, 65424, 119859, 
+    917575, 5353, 5625, 10894, 954, 8022, 1010, 41043, 65456, 41438, 41439, 
+    9904, 10711, 4593, 119564, 119003, 2590, 5629, 13309, 7551, 10325, 5632, 
+    10471, 120038, 64759, 42054, 5166, 5628, 120031, 970, 120029, 4772, 2400, 
+    5627, 64130, 120018, 12885, 3119, 63998, 10961, 3060, 203, 9986, 917574, 
+    64344, 636, 11698, 120652, 63832, 42111, 11701, 120448, 554, 64137, 8320, 
+    64275, 8863, 120442, 42042, 1477, 63803, 194864, 120792, 5694, 7689, 
+    42142, 9323, 4325, 3047, 3937, 175, 194815, 3169, 64016, 64781, 912, 
+    1243, 4536, 5431, 6652, 120058, 6244, 65839, 120480, 3935, 120665, 1129, 
+    917936, 11950, 5392, 68177, 7846, 64024, 5397, 120008, 12046, 12599, 
+    3845, 4490, 5395, 6556, 5393, 354, 7530, 11977, 41029, 8366, 119183, 
+    7756, 3901, 65484, 51, 626, 41602, 5895, 9568, 64057, 456, 120333, 8145, 
+    1168, 9251, 9082, 119964, 9854, 4311, 3866, 8818, 41512, 119952, 118865, 
+    10324, 3918, 5377, 3797, 1644, 10405, 9658, 4140, 13057, 42029, 42037, 
+    9030, 813, 119945, 41454, 4146, 195036, 5360, 2466, 236, 195032, 119942, 
+    6249, 42117, 5898, 120670, 41457, 119148, 5855, 1969, 2384, 988, 119106, 
+    12838, 64483, 917834, 10341, 10552, 65479, 5854, 120397, 10583, 118933, 
+    119989, 119940, 10416, 11981, 3872, 119361, 64014, 120725, 6093, 9748, 
+    2838, 119939, 65843, 170, 120516, 13143, 4169, 118847, 13311, 6058, 6448, 
+    10553, 1662, 65295, 917782, 64342, 5892, 120822, 10178, 42106, 66, 65, 
+    68, 67, 70, 69, 72, 71, 74, 73, 76, 75, 78, 77, 80, 79, 82, 81, 84, 83, 
+    86, 85, 88, 87, 90, 89, 4736, 10357, 64155, 849, 1704, 8556, 120402, 
+    9659, 64926, 1743, 120512, 9556, 9496, 4503, 11353, 9647, 7876, 68132, 
+    120575, 3928, 11948, 65283, 10706, 63975, 65427, 4842, 6438, 66509, 9109, 
+    4841, 1289, 4171, 12008, 6251, 3923, 1490, 2447, 65539, 119187, 10907, 
+    5245, 119218, 10114, 64000, 9790, 4845, 8332, 10582, 119622, 4840, 5675, 
+    254, 1747, 65429, 4825, 10626, 8918, 10281, 5716, 64004, 65799, 120576, 
+    19955, 917989, 8080, 118895, 367, 1472, 120386, 6687, 4829, 64693, 5905, 
+    12339, 8919, 9515, 4435, 118992, 11023, 119109, 4830, 9134, 41365, 64125, 
+    41978, 1412, 4594, 1391, 10536, 7720, 4824, 7775, 120425, 120392, 1888, 
+    1960, 3140, 66449, 7960, 41836, 41844, 6052, 6064, 54, 1428, 12214, 
+    68098, 6211, 7699, 358, 66592, 10557, 11442, 10758, 8223, 65759, 4261, 
+    12642, 194844, 120343, 120400, 120496, 119053, 41858, 119055, 64118, 
+    194902, 64554, 10574, 3878, 4017, 12827, 1752, 65195, 12962, 41118, 3924, 
+    10199, 118965, 64966, 119019, 120107, 65664, 41116, 720, 324, 194964, 
+    41977, 12057, 11917, 1464, 41343, 4721, 7974, 64353, 8957, 66484, 64488, 
+    120371, 9853, 64041, 195058, 12740, 12640, 4722, 917617, 917820, 0, 4725, 
+    9690, 4726, 194756, 41173, 119843, 118969, 5204, 119248, 67588, 67605, 
+    4015, 3995, 8052, 476, 3714, 10073, 3595, 10232, 10999, 1382, 64209, 
+    12636, 64215, 64214, 1656, 41831, 8130, 8672, 8832, 8720, 3908, 1452, 
+    13111, 64523, 64067, 194926, 8552, 12398, 41845, 3849, 120657, 195063, 
+    9778, 468, 612, 42150, 55, 65546, 917911, 64515, 1674, 118951, 5823, 
+    120276, 1114, 42110, 540, 120052, 119017, 12516, 41743, 3938, 120057, 
+    65417, 64316, 120060, 11340, 820, 41741, 6292, 65303, 7955, 6452, 4713, 
+    3359, 7800, 41566, 65177, 6226, 353, 719, 9656, 9474, 64742, 41986, 4532, 
+    65412, 42114, 10868, 4717, 2349, 5902, 66450, 1884, 9481, 64070, 65400, 
+    3623, 8155, 1195, 3942, 4714, 9625, 41151, 194653, 5012, 12006, 917604, 
+    12074, 12409, 42027, 4360, 12964, 6454, 1229, 63793, 66437, 41344, 
+    917880, 8539, 65100, 120508, 4809, 9623, 4788, 120299, 64885, 64745, 
+    120207, 65405, 65032, 13075, 194866, 5365, 4545, 8901, 8000, 2492, 4813, 
+    65432, 917999, 5925, 4808, 64330, 9649, 41154, 65030, 5128, 4038, 12718, 
+    4810, 64859, 12794, 64928, 1648, 5435, 3522, 11303, 414, 10236, 65439, 
+    12709, 6456, 120494, 65120, 11905, 41082, 65243, 12581, 10374, 5175, 
+    63796, 68181, 10254, 63820, 9751, 10262, 64088, 41363, 3919, 607, 194698, 
+    120288, 9018, 5270, 10314, 10282, 65477, 6564, 64310, 40976, 8265, 7737, 
+    120752, 40975, 5840, 65436, 10162, 40978, 41632, 8454, 42072, 42038, 387, 
+    119098, 12737, 120294, 2550, 917910, 42069, 118971, 6442, 3525, 66617, 
+    9860, 64641, 41590, 5619, 41346, 13157, 375, 7455, 66444, 5616, 8531, 
+    11473, 42753, 119202, 9454, 5615, 194652, 2315, 120830, 1938, 5455, 
+    64752, 808, 5568, 11347, 119198, 1026, 5620, 65593, 120787, 11350, 5617, 
+    10893, 9225, 64639, 12902, 9145, 64595, 1338, 120352, 119178, 9863, 
+    12161, 2587, 64553, 120274, 6455, 6037, 12834, 3974, 7998, 10290, 10888, 
+    3083, 10322, 2316, 12348, 64027, 41036, 120369, 66442, 12552, 65606, 
+    119822, 12739, 5373, 120784, 64700, 3762, 1445, 40961, 65304, 11986, 
+    120708, 40960, 917923, 3780, 7485, 5779, 64952, 10402, 12011, 3906, 9707, 
+    10603, 8326, 0, 65498, 3763, 11468, 5618, 194688, 3779, 120078, 9324, 
+    118852, 63822, 9073, 66585, 64302, 10704, 280, 4787, 917861, 68138, 
+    13072, 1894, 41180, 120111, 9570, 64020, 8699, 2689, 7878, 65426, 65793, 
+    42135, 41824, 2551, 10456, 6453, 10200, 3998, 65229, 66562, 503, 194691, 
+    4470, 2690, 118853, 7780, 5369, 41954, 5249, 1652, 772, 8756, 8310, 
+    65428, 3487, 64873, 3585, 1688, 194956, 119159, 41822, 194874, 6468, 
+    41904, 9720, 41697, 41319, 13125, 10650, 5836, 12358, 4668, 4355, 9048, 
+    1465, 10850, 3943, 19947, 41205, 41315, 41488, 120827, 119613, 5352, 
+    12362, 12435, 8839, 41053, 3266, 7785, 12356, 8616, 12104, 917875, 65625, 
+    11450, 194755, 3638, 5420, 3897, 3216, 195011, 2358, 4018, 8633, 2850, 
+    13304, 9639, 65445, 0, 41263, 2561, 63807, 3542, 120023, 12076, 5303, 
+    8078, 12676, 64418, 6276, 1706, 194785, 41819, 41422, 12943, 11464, 
+    10792, 41484, 194607, 10847, 41050, 8872, 860, 13099, 118844, 194819, 
+    118886, 6435, 10830, 194935, 615, 10668, 7574, 917582, 10504, 9779, 3625, 
+    43016, 41409, 66651, 41425, 65087, 9178, 8789, 41427, 4022, 64531, 11804, 
+    118889, 11288, 41424, 917598, 118811, 41820, 195010, 65292, 4812, 1261, 
+    120340, 3911, 12102, 119179, 1033, 64939, 64642, 917921, 3904, 65822, 
+    10514, 3275, 65226, 917961, 13123, 10846, 11392, 41321, 66513, 12138, 
+    10989, 119048, 6233, 10598, 449, 2669, 903, 118997, 2920, 9636, 65240, 
+    10738, 118897, 9367, 593, 41085, 3917, 64172, 11732, 64307, 120457, 
+    41448, 3596, 119832, 0, 9763, 64082, 8819, 8113, 124, 12981, 41113, 232, 
+    12234, 120646, 9168, 65811, 10820, 194895, 64053, 9094, 1769, 41715, 
+    2463, 119065, 1064, 13307, 41976, 1538, 19924, 0, 120476, 7862, 7795, 
+    1474, 8516, 4828, 1258, 7561, 12744, 11585, 1878, 9498, 0, 2911, 120094, 
+    41178, 3939, 64823, 8846, 8943, 12617, 41174, 2650, 4491, 1961, 41463, 
+    11525, 11292, 1959, 775, 66488, 41732, 41016, 6074, 9618, 64827, 1511, 
+    3613, 66440, 4259, 41436, 3656, 19930, 64533, 41019, 12428, 68160, 11333, 
+    6243, 8514, 8513, 9054, 1613, 41828, 119360, 65531, 194879, 68139, 
+    194877, 67604, 5741, 10145, 8865, 6402, 119099, 5788, 7917, 64808, 65730, 
+    7733, 64359, 4998, 120375, 119904, 65494, 917968, 4268, 41247, 120524, 
+    120370, 3871, 8036, 10881, 9111, 10621, 41696, 65462, 67584, 10993, 
+    120745, 9765, 120368, 195089, 11648, 42118, 10321, 65281, 41587, 10949, 
+    194644, 42107, 917607, 917860, 5416, 10802, 41164, 66318, 65298, 65723, 
+    5685, 118845, 12633, 7928, 10848, 8094, 41595, 118821, 6474, 794, 65909, 
+    12656, 10355, 64665, 5274, 1665, 41598, 3993, 119165, 64512, 40971, 536, 
+    189, 12611, 119234, 194651, 2859, 4838, 63838, 4834, 2338, 195075, 
+    119145, 4837, 41944, 770, 41452, 811, 1687, 41042, 66620, 120730, 64427, 
+    64326, 40969, 10526, 3895, 5406, 40968, 1339, 11731, 120473, 10193, 3116, 
+    7747, 119185, 8020, 10843, 11554, 12825, 0, 8266, 41006, 12371, 2871, 
+    64614, 41245, 999, 119129, 64567, 12745, 2663, 64586, 119636, 64191, 
+    68096, 10150, 65367, 64308, 1522, 597, 4775, 10917, 12571, 10448, 12583, 
+    12560, 12558, 12556, 12584, 1741, 65097, 1227, 4783, 12566, 11013, 12554, 
+    120558, 10812, 1586, 4978, 195046, 3078, 1402, 5285, 9391, 40984, 9379, 
+    9372, 394, 3088, 6284, 917966, 41663, 3991, 9377, 120785, 9237, 424, 
+    41648, 41208, 120366, 9384, 41076, 1830, 120816, 8647, 41656, 8246, 
+    120307, 917948, 195039, 41840, 119605, 2377, 41676, 64864, 12572, 11318, 
+    12557, 12559, 5479, 2796, 1003, 2373, 9446, 9447, 9448, 48, 194920, 9480, 
+    481, 2359, 9125, 9439, 9440, 9441, 548, 9153, 9444, 9445, 9430, 9431, 
+    9432, 397, 9434, 9435, 3984, 9437, 195057, 1614, 9424, 9425, 9426, 6651, 
+    1358, 9429, 428, 9620, 9655, 917760, 10982, 9096, 1333, 65170, 407, 6425, 
+    917630, 917763, 5955, 66320, 1108, 5804, 11976, 8554, 41466, 64782, 3926, 
+    9057, 11434, 8798, 120734, 917857, 1392, 1883, 7476, 5986, 5985, 8065, 
+    41326, 10353, 7468, 0, 917866, 4407, 6502, 4019, 119595, 118919, 8448, 
+    8219, 41688, 1812, 12675, 12659, 41793, 194823, 119167, 42172, 42068, 
+    6054, 10697, 2386, 119810, 9170, 10642, 3909, 64585, 10296, 41763, 
+    119171, 10977, 42082, 4164, 1049, 195045, 65707, 11943, 41806, 8709, 
+    10606, 3921, 12275, 64691, 12936, 8994, 1038, 118966, 8470, 65695, 0, 
+    577, 119585, 8773, 10733, 36, 194793, 5153, 41805, 13097, 194782, 763, 
+    8736, 1414, 64495, 9683, 194841, 66681, 120831, 2536, 119951, 66330, 
+    119625, 8621, 8963, 12852, 3031, 120034, 41345, 66317, 182, 66315, 64402, 
+    65562, 10210, 120492, 9058, 366, 120764, 9892, 961, 63755, 6426, 4570, 
+    11478, 3106, 65917, 41284, 1696, 41189, 4003, 12105, 68109, 5766, 12802, 
+    3264, 8824, 13268, 917801, 10936, 63980, 11287, 6128, 119083, 19956, 
+    10923, 2322, 12797, 65506, 8300, 65861, 917536, 41285, 3547, 120144, 
+    8112, 119600, 41459, 41369, 6089, 13000, 43027, 12117, 4170, 1029, 10540, 
+    12315, 9063, 65101, 119979, 744, 120821, 12897, 3792, 4926, 917623, 6065, 
+    3551, 194598, 118800, 4623, 41186, 41816, 4598, 41818, 12795, 5968, 7922, 
+    12614, 10851, 8523, 6179, 119066, 6180, 1863, 4710, 194981, 5956, 11972, 
+    41290, 65552, 4705, 716, 177, 120739, 4704, 12360, 120270, 64719, 161, 
+    9020, 3362, 119931, 4706, 10646, 66594, 64788, 4709, 7518, 8754, 19909, 
+    120237, 120245, 119164, 68144, 7508, 9136, 1700, 4401, 41280, 194711, 
+    8974, 2308, 119910, 10634, 41791, 2318, 8506, 66361, 8198, 42022, 1005, 
+    937, 118996, 4734, 2870, 41277, 12319, 66619, 5404, 4729, 3667, 235, 
+    1384, 4728, 41049, 120420, 120644, 120017, 8109, 65505, 119920, 4730, 
+    447, 13186, 1513, 4733, 8664, 63978, 65219, 119221, 12911, 9665, 1383, 
+    8565, 2469, 119866, 12663, 6156, 68117, 917586, 7993, 4288, 119828, 2674, 
+    13238, 11922, 41145, 41468, 3510, 13234, 41148, 8683, 5605, 42095, 10497, 
+    12221, 1380, 12314, 41146, 118964, 11441, 13197, 3512, 120682, 9495, 
+    8103, 194596, 5959, 65184, 11780, 41563, 11586, 120028, 41925, 13205, 
+    13211, 5801, 41923, 119344, 120316, 1283, 11924, 4779, 7988, 3719, 4006, 
+    3271, 19957, 64038, 8355, 118799, 8842, 64747, 3804, 13070, 11557, 3875, 
+    5962, 1095, 64371, 3599, 65880, 5827, 120411, 7787, 120140, 41378, 7465, 
+    64493, 12207, 4773, 11684, 64034, 119565, 917865, 12785, 42043, 64943, 
+    66677, 917965, 42046, 9742, 521, 65136, 10800, 41473, 8404, 66725, 483, 
+    0, 1450, 12986, 928, 11605, 65441, 917882, 10599, 120435, 3989, 10971, 
+    120016, 5771, 9841, 6539, 12145, 118983, 10074, 194778, 9807, 3769, 
+    41190, 3973, 12821, 4575, 9573, 7982, 429, 8849, 118967, 65573, 41771, 
+    1796, 118918, 64887, 6417, 8164, 41301, 3502, 120382, 194912, 64959, 
+    4919, 10590, 5825, 7755, 68165, 0, 64548, 12661, 1621, 10214, 10418, 
+    41962, 65868, 41971, 1409, 11551, 1617, 3112, 10824, 5015, 1390, 64403, 
+    194976, 421, 1756, 5846, 66476, 8666, 120132, 7595, 120360, 7555, 3630, 
+    5408, 2817, 1214, 12883, 120124, 10218, 41769, 3168, 194916, 42134, 7957, 
+    2370, 2846, 1056, 119070, 12798, 118910, 120314, 1836, 8757, 65850, 
+    12327, 3740, 119028, 5622, 65374, 41765, 2341, 3944, 8484, 8474, 120817, 
+    6135, 3118, 8461, 41942, 12153, 5621, 12799, 8127, 8975, 9451, 7571, 
+    13073, 12169, 10618, 681, 194562, 703, 120812, 3272, 8781, 12894, 120527, 
+    11709, 119601, 4815, 42053, 6561, 8279, 8776, 64954, 3276, 917976, 6290, 
+    4267, 120104, 41325, 65021, 11706, 917825, 12171, 10047, 9710, 3262, 
+    194604, 194939, 119200, 42020, 118788, 163, 576, 9895, 1655, 5842, 12479, 
+    3122, 10417, 7793, 65581, 9328, 64352, 10039, 6003, 12569, 5623, 120026, 
+    5717, 3986, 120634, 42023, 8912, 64555, 12604, 64078, 65700, 3627, 4523, 
+    64934, 11595, 8540, 11498, 8887, 4574, 41040, 2459, 64886, 13060, 41041, 
+    8946, 10348, 10412, 5718, 120088, 10450, 8147, 13221, 66329, 9999, 3765, 
+    119885, 68153, 1606, 12178, 686, 3093, 119126, 4619, 10600, 6654, 7712, 
+    64826, 4312, 41918, 65689, 10128, 11923, 4023, 41892, 5763, 120335, 4827, 
+    2401, 12810, 8792, 120346, 4455, 7826, 433, 64824, 66660, 2499, 41812, 
+    12886, 65375, 11973, 13089, 4293, 10300, 10161, 10396, 12196, 66322, 
+    66630, 194901, 119319, 3010, 5817, 65719, 1458, 3120, 9797, 9643, 119317, 
+    4984, 10389, 66682, 9100, 9017, 120364, 120243, 1061, 4699, 9115, 3509, 
+    0, 486, 4290, 9896, 12291, 120620, 194887, 1045, 120204, 5631, 10380, 
+    9626, 2380, 0, 194863, 120678, 2376, 8486, 120618, 9824, 2335, 4362, 
+    12174, 194909, 2366, 1025, 195101, 12634, 120760, 65423, 41443, 120732, 
+    917847, 11713, 1774, 1523, 917561, 5058, 41445, 65762, 65310, 8567, 
+    41442, 3988, 0, 64882, 1847, 917947, 10403, 8564, 65385, 65076, 65117, 
+    120413, 194811, 65908, 12616, 65887, 6256, 119628, 12671, 194933, 10206, 
+    118974, 917792, 2673, 11960, 5820, 9318, 4488, 119567, 7926, 65358, 
+    10444, 42137, 9893, 2754, 9850, 41437, 4487, 12722, 41957, 1032, 65530, 
+    1711, 12984, 43039, 3114, 614, 120691, 13116, 64923, 120790, 926, 120640, 
+    65670, 64204, 194848, 194676, 10832, 120362, 1050, 7549, 41035, 11583, 
+    9314, 41801, 119088, 120616, 520, 10437, 9558, 8331, 917806, 3091, 41034, 
+    917887, 2307, 8360, 10097, 65768, 321, 41028, 12750, 917903, 65563, 
+    120241, 120262, 2861, 10360, 10095, 0, 66307, 440, 1861, 13085, 9233, 
+    120265, 64532, 43041, 119158, 12123, 13133, 3859, 10570, 41660, 8209, 
+    65778, 118841, 10910, 120423, 1521, 7875, 41658, 10487, 120606, 5760, 
+    13011, 743, 4414, 119571, 118873, 65769, 5243, 9849, 5239, 65771, 10778, 
+    1405, 5237, 917878, 65112, 10103, 5247, 4769, 42063, 5508, 120829, 5764, 
+    11792, 3513, 3008, 9378, 120395, 194960, 10125, 65364, 41103, 9394, 6485, 
+    1397, 64795, 65365, 119093, 4770, 120590, 9392, 8731, 7471, 12079, 
+    120619, 11316, 9122, 194725, 4774, 3019, 9997, 11549, 194919, 1099, 
+    10215, 65565, 1340, 9390, 66717, 41453, 464, 4281, 4768, 9385, 64470, 
+    1346, 4995, 65679, 12087, 9780, 423, 1818, 65144, 66665, 8272, 917844, 
+    66324, 12904, 3087, 64960, 10111, 19967, 64707, 0, 9584, 8214, 194998, 
+    12159, 12626, 9106, 118907, 40979, 5806, 64750, 64517, 8243, 9123, 5709, 
+    0, 265, 10922, 13255, 12605, 917628, 2752, 64626, 120256, 1434, 59, 5637, 
+    11573, 0, 64897, 68129, 19951, 10379, 66305, 119345, 41809, 10283, 41983, 
+    7547, 64684, 1156, 8009, 3305, 3782, 511, 12496, 63752, 1014, 64360, 
+    11906, 120125, 10835, 10157, 65536, 1400, 10323, 10685, 7702, 41211, 
+    10387, 4453, 2440, 3758, 1150, 10547, 5700, 19910, 65349, 65383, 2339, 
+    64019, 5697, 41156, 6617, 9116, 119227, 0, 462, 41841, 10493, 3862, 8129, 
+    917958, 120404, 12864, 6644, 9845, 64794, 8261, 5701, 9722, 9581, 1385, 
+    1426, 119992, 41125, 41872, 194620, 11404, 6493, 119896, 13288, 120108, 
+    5167, 120717, 1681, 12184, 1204, 3755, 11935, 7748, 8213, 3286, 8911, 
+    64712, 10744, 65356, 990, 5647, 5726, 64915, 10377, 118947, 11477, 5646, 
+    65044, 11018, 2851, 3945, 120096, 120119, 4373, 194948, 12997, 9587, 
+    1789, 1020, 120097, 3100, 41497, 5648, 64748, 13162, 119336, 10205, 3545, 
+    8190, 10016, 64616, 917890, 6506, 64312, 66669, 2368, 63993, 4419, 65727, 
+    66469, 3439, 1825, 1192, 119166, 8891, 3080, 118836, 2347, 5430, 1140, 
+    8990, 2848, 10159, 41859, 120212, 249, 917777, 9173, 12191, 1815, 194832, 
+    890, 8883, 3267, 728, 42144, 995, 120633, 4410, 1041, 10576, 8102, 10099, 
+    10343, 19945, 8091, 558, 120110, 12273, 13163, 19938, 12112, 12446, 
+    41389, 64482, 65214, 5375, 10142, 8548, 8215, 3129, 6134, 12913, 9005, 
+    41856, 13242, 64891, 7725, 11938, 11662, 119326, 8624, 5173, 19959, 527, 
+    120701, 41894, 10327, 6277, 10608, 10010, 9879, 917612, 3540, 41672, 835, 
+    2329, 120813, 12238, 13001, 7849, 12245, 5426, 4258, 63987, 41787, 5424, 
+    12016, 8283, 120808, 5434, 194561, 194937, 8067, 6144, 194758, 10311, 
+    118977, 1404, 3095, 11432, 120211, 3464, 494, 4819, 119608, 65098, 570, 
+    956, 3672, 13112, 1498, 120100, 65857, 119184, 431, 10029, 65159, 195066, 
+    8761, 41537, 13171, 13096, 194953, 65108, 118911, 9516, 1044, 5268, 0, 
+    4954, 194972, 4450, 11795, 11547, 64358, 11946, 356, 3477, 227, 10488, 
+    13214, 382, 11418, 12295, 120641, 11475, 917845, 3020, 11537, 6484, 2541, 
+    917998, 12364, 11337, 65568, 1057, 566, 9110, 119104, 2743, 64931, 63965, 
+    64338, 9097, 66571, 41305, 8782, 3006, 776, 2524, 1592, 8573, 917843, 
+    10924, 65164, 63941, 41593, 4397, 8952, 3856, 66505, 119892, 5872, 6495, 
+    120510, 6486, 41155, 1698, 13177, 12830, 5413, 3953, 1053, 19917, 65094, 
+    11448, 4339, 1052, 1051, 459, 1060, 917853, 66479, 65299, 65703, 5228, 
+    119955, 7868, 689, 6508, 4163, 120757, 8639, 66641, 43022, 65510, 1162, 
+    12130, 2671, 65806, 8095, 64375, 7521, 42178, 4553, 195034, 0, 12299, 
+    41433, 195004, 19921, 64298, 11424, 64169, 4567, 41891, 1926, 66646, 
+    119056, 4820, 8110, 10935, 64690, 194665, 5830, 119212, 1377, 119889, 
+    4897, 12932, 9250, 8693, 4438, 194947, 917560, 1753, 11331, 6147, 11431, 
+    64621, 8833, 120671, 0, 6504, 41428, 64596, 10719, 43012, 1898, 1413, 
+    194763, 65394, 802, 12141, 917953, 5561, 6648, 10671, 2528, 41774, 41379, 
+    9169, 838, 5669, 64484, 844, 5014, 65854, 256, 0, 5583, 41987, 120280, 
+    41399, 5580, 65464, 2923, 10853, 5582, 10048, 65699, 13069, 5795, 13158, 
+    66598, 65702, 6087, 65701, 41322, 12180, 65704, 120662, 194850, 194582, 
+    8894, 5370, 64055, 118917, 1638, 10966, 12200, 194630, 118848, 5733, 
+    67631, 64288, 194966, 8172, 42017, 5729, 10844, 8319, 6498, 9760, 0, 
+    120106, 1238, 200, 120555, 1062, 119993, 118893, 118905, 917606, 195069, 
+    1070, 9361, 917942, 6095, 3394, 120664, 3015, 120609, 41827, 4037, 7763, 
+    6400, 65186, 66626, 7817, 1841, 11276, 12976, 65724, 372, 1669, 10776, 
+    63937, 7701, 41585, 64397, 119211, 1732, 276, 41862, 2828, 33, 65326, 
+    41768, 6491, 65332, 41588, 914, 427, 8071, 3538, 3900, 65321, 41864, 
+    1031, 6257, 7614, 41869, 120826, 120573, 2328, 12399, 1071, 41400, 65537, 
+    13249, 10841, 41627, 5301, 1047, 195094, 5734, 8960, 11312, 8001, 10651, 
+    119970, 65012, 9663, 66441, 12304, 41621, 5711, 12921, 12098, 65571, 
+    9166, 12164, 5710, 64363, 65585, 65168, 12447, 10571, 917975, 119617, 
+    119246, 64611, 5558, 917888, 5715, 10915, 120118, 12007, 3670, 2761, 
+    11975, 64811, 3074, 5722, 194876, 8629, 120632, 11307, 4499, 2757, 4496, 
+    9718, 120116, 8910, 10689, 120391, 12717, 65451, 11782, 194822, 66316, 
+    194729, 41630, 41640, 65596, 917840, 11416, 4280, 13118, 8765, 12784, 
+    7792, 1393, 917542, 8701, 6585, 8487, 8233, 917788, 119874, 6683, 120009, 
+    4495, 12144, 2841, 12543, 119320, 1473, 10490, 64329, 118984, 65467, 
+    120006, 6488, 357, 1048, 41100, 917809, 41104, 65122, 8035, 1054, 917950, 
+    1040, 65450, 5454, 4434, 1069, 195095, 13019, 194906, 119261, 5084, 
+    65402, 119133, 9693, 12354, 733, 10762, 41677, 41102, 4353, 41674, 1059, 
+    9218, 1731, 917883, 120528, 120000, 120643, 41679, 8299, 11994, 118833, 
+    64390, 194922, 5155, 11599, 12743, 42122, 6480, 65740, 41779, 0, 3587, 
+    12131, 41432, 10986, 66602, 9605, 64807, 12788, 43020, 41767, 3371, 
+    917549, 13114, 8771, 1479, 41022, 194950, 1109, 11000, 120740, 64508, 
+    9770, 9246, 12230, 63801, 8868, 399, 65137, 41783, 41772, 64045, 11742, 
+    2755, 551, 917803, 10156, 4857, 9874, 4428, 2544, 65074, 194614, 120209, 
+    917811, 194786, 351, 5747, 12179, 194603, 7978, 41092, 118954, 120502, 
+    10791, 19935, 10712, 65015, 120667, 563, 64815, 120722, 9013, 5588, 57, 
+    0, 10386, 65269, 119043, 5585, 65881, 2549, 694, 66712, 9876, 5584, 8358, 
+    64717, 10238, 65279, 10919, 277, 7980, 119298, 41815, 120233, 41800, 
+    5589, 41807, 2664, 12793, 5586, 1574, 10513, 11356, 2525, 4852, 5749, 
+    917765, 41605, 64696, 119306, 1039, 9801, 10155, 5745, 188, 8135, 6450, 
+    10055, 66604, 9055, 41853, 4858, 5657, 194700, 436, 4771, 194639, 2786, 
+    5654, 4856, 8051, 120799, 119026, 194891, 5652, 10945, 194581, 120761, 
+    12280, 3661, 7863, 118834, 119933, 41302, 66608, 64699, 5402, 10234, 
+    5843, 11939, 5655, 42157, 195079, 3157, 1055, 194955, 917553, 3504, 
+    64785, 118790, 10822, 5149, 41927, 10226, 41871, 13159, 3594, 10272, 
+    10304, 40, 12657, 594, 10244, 386, 9453, 8834, 10816, 118866, 3467, 
+    41010, 119579, 3331, 946, 10231, 1495, 8131, 13179, 119045, 9562, 4304, 
+    65927, 8160, 120234, 63974, 64529, 64656, 63995, 1348, 12239, 64013, 
+    5666, 13303, 10555, 120751, 119919, 7599, 10798, 65230, 13269, 10195, 
+    119932, 7732, 41905, 9793, 0, 6097, 5668, 8780, 4982, 119883, 5670, 
+    63969, 120298, 12741, 2672, 3735, 5667, 13138, 119915, 9484, 10724, 
+    13203, 119024, 65258, 66496, 4361, 9487, 64314, 9286, 1497, 120169, 1932, 
+    12442, 6193, 3571, 11984, 917945, 7973, 119157, 64821, 11964, 12613, 
+    7873, 11399, 119219, 553, 13049, 41533, 194857, 3604, 65912, 4587, 66709, 
+    120048, 66667, 12746, 1962, 120083, 194696, 5633, 11660, 66337, 7559, 
+    120593, 64905, 12856, 5437, 65208, 10669, 6443, 7964, 63971, 9135, 199, 
+    10976, 4105, 63880, 120622, 120181, 65816, 12148, 13148, 7560, 66686, 
+    9226, 120439, 11669, 6472, 5634, 4524, 12720, 4724, 67625, 8407, 66323, 
+    12224, 119201, 194938, 5221, 64348, 328, 7886, 41701, 5448, 5636, 6680, 
+    5329, 194650, 5638, 6679, 7940, 119076, 118938, 65182, 5635, 3373, 2986, 
+    118880, 194629, 3437, 119358, 6203, 9833, 12693, 11920, 8274, 194838, 
+    11685, 1657, 41558, 119610, 7585, 5639, 2954, 5660, 5640, 65376, 194818, 
+    65102, 19960, 66475, 5297, 41637, 13284, 6112, 7968, 41625, 194737, 
+    194699, 118955, 11705, 5642, 0, 64630, 42181, 4342, 11710, 67630, 1677, 
+    64803, 4585, 5641, 8259, 10643, 1058, 2719, 119570, 194638, 194993, 1144, 
+    5868, 120436, 10867, 11302, 13277, 4308, 2539, 917848, 7505, 543, 64916, 
+    64736, 2547, 10209, 66670, 65317, 5399, 19911, 917850, 41633, 7902, 
+    64932, 9000, 12233, 11299, 66499, 1865, 119618, 5613, 194772, 12994, 
+    65057, 5610, 0, 6228, 4307, 3482, 42133, 10787, 194609, 2997, 506, 5609, 
+    41194, 12863, 194776, 12316, 41195, 2412, 8169, 8186, 8841, 9522, 516, 
+    13130, 41197, 917795, 34, 64007, 10030, 5306, 1612, 66622, 42765, 11704, 
+    65756, 12001, 10211, 119869, 64564, 66365, 65147, 6584, 7749, 120175, 
+    65693, 1758, 413, 10667, 4677, 120197, 9133, 1935, 11517, 1042, 120196, 
+    64779, 1931, 10248, 6185, 64776, 1217, 10242, 708, 825, 118913, 65680, 
+    12294, 41207, 119903, 9138, 2534, 810, 12631, 194911, 120491, 4424, 
+    119255, 4895, 1239, 2364, 11313, 119149, 3403, 119193, 194610, 64364, 
+    63952, 65250, 10027, 8998, 194627, 917771, 9152, 194896, 67592, 2980, 
+    755, 41850, 931, 3433, 13170, 12615, 1594, 42767, 11274, 67603, 12944, 
+    41623, 8730, 41353, 11587, 67611, 4337, 65188, 41394, 918, 119223, 935, 
+    7681, 65676, 377, 41393, 11649, 120621, 2477, 64301, 66454, 917826, 
+    194899, 65201, 9528, 65155, 573, 19912, 7907, 11417, 120186, 194885, 
+    65328, 10673, 119217, 119938, 67607, 11482, 1781, 5496, 3357, 62, 1649, 
+    120549, 964, 119242, 64535, 41009, 917773, 11589, 65035, 194872, 65038, 
+    917605, 64602, 67618, 65840, 11580, 12711, 66575, 4542, 65779, 8423, 
+    3348, 448, 119173, 2991, 9364, 120036, 997, 7949, 120772, 12849, 11341, 
+    11440, 3073, 9866, 9714, 11692, 4657, 12988, 4658, 6478, 12335, 119228, 
+    41975, 6241, 2818, 4877, 2385, 5463, 41897, 4172, 10052, 4409, 8373, 
+    10873, 12095, 65745, 5346, 120328, 194925, 6237, 5461, 64058, 9176, 
+    11597, 40974, 64937, 64828, 11419, 120406, 766, 1257, 917547, 10970, 
+    2408, 3251, 64154, 3274, 5465, 41501, 2461, 120523, 120321, 5342, 8317, 
+    120394, 68163, 3263, 120046, 8673, 194719, 3270, 64539, 11489, 118999, 
+    120388, 66672, 120560, 5535, 9142, 195018, 756, 8687, 10938, 120658, 
+    66443, 1182, 2542, 186, 917862, 119156, 5770, 529, 42115, 12612, 12949, 
+    10586, 10790, 10839, 8920, 5241, 6479, 41713, 120427, 41594, 225, 11578, 
+    5688, 41300, 41204, 119105, 118794, 10721, 41209, 9254, 42097, 1794, 
+    41875, 65238, 5624, 266, 120221, 67637, 41873, 3617, 11324, 41494, 
+    119824, 8420, 13088, 65755, 1872, 41338, 3734, 7734, 120174, 5502, 65890, 
+    4452, 41260, 917767, 0, 4511, 5161, 10572, 917614, 11425, 42050, 64349, 
+    41083, 917884, 917925, 63979, 9003, 8192, 120039, 5305, 9653, 10616, 
+    1697, 9546, 917930, 194847, 119174, 41482, 65205, 10031, 64063, 9870, 
+    12535, 8620, 65824, 5581, 8799, 42131, 42031, 64062, 1028, 64060, 64059, 
+    837, 10567, 119960, 41606, 3176, 64773, 11427, 2902, 64043, 64042, 41740, 
+    3609, 120550, 13200, 832, 64044, 42156, 10076, 64040, 64039, 12919, 1034, 
+    3392, 10753, 5180, 64033, 41395, 65468, 11691, 64037, 64036, 41898, 4291, 
+    63966, 64015, 41114, 243, 8479, 64354, 6024, 11351, 12128, 194908, 3476, 
+    8973, 8538, 64011, 64010, 64008, 4285, 4800, 7706, 41750, 11604, 2538, 
+    11609, 204, 7563, 4802, 4111, 8239, 9098, 4805, 64001, 214, 7885, 42143, 
+    8321, 65893, 12208, 4767, 9343, 64049, 41729, 119986, 1133, 19948, 64052, 
+    64051, 41187, 8692, 6022, 11788, 10005, 12329, 41333, 120569, 43, 1942, 
+    12682, 1016, 41107, 12619, 41121, 3885, 92, 64023, 64022, 64021, 6582, 
+    43030, 12451, 64025, 9167, 41485, 12035, 119208, 6254, 10501, 64018, 
+    8890, 12457, 66587, 194836, 7582, 64778, 118915, 118813, 66635, 120044, 
+    66621, 7995, 8759, 41411, 13094, 12449, 7532, 41414, 65109, 3179, 13279, 
+    4720, 10165, 917618, 119249, 120673, 10751, 9051, 12915, 65913, 10535, 
+    917892, 4993, 194586, 6168, 10934, 1946, 294, 41874, 5494, 4639, 65929, 
+    12040, 6196, 4498, 194907, 64028, 8146, 41789, 41788, 2960, 118786, 
+    118795, 8969, 119884, 10197, 66599, 67621, 2950, 11998, 6210, 11433, 370, 
+    3549, 64790, 7801, 4953, 11461, 64356, 194973, 3297, 9699, 120693, 1135, 
+    12700, 7447, 5063, 3517, 2964, 119257, 0, 2552, 41546, 60, 10627, 8649, 
+    8252, 729, 67624, 119934, 6682, 120007, 43046, 41770, 41547, 9032, 64820, 
+    65906, 65817, 41215, 119897, 65883, 12832, 119592, 8081, 3761, 3537, 
+    119908, 9137, 119906, 8999, 65343, 3850, 3466, 4327, 120112, 9373, 66369, 
+    908, 6282, 6681, 9813, 194997, 41655, 537, 41511, 4179, 8978, 41213, 
+    65866, 1842, 10527, 120409, 9628, 3848, 12081, 9826, 64502, 1767, 5336, 
+    120200, 64659, 663, 194846, 10780, 0, 3059, 120024, 119626, 120198, 
+    66689, 347, 42112, 40992, 4100, 920, 1811, 1355, 7739, 65198, 3592, 
+    10078, 5318, 194910, 65578, 8592, 65870, 6224, 120192, 9381, 13244, 
+    64345, 118885, 9281, 3296, 12865, 120715, 1895, 
+};
+
+#define code_magic 47
+#define code_size 16384
+#define code_poly 16427

Added: vendor/Python/current/Modules/xxmodule.c
===================================================================
--- vendor/Python/current/Modules/xxmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/xxmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,376 @@
+
+/* Use this file as a template to start implementing a module that
+   also declares object types. All occurrences of 'Xxo' should be changed
+   to something reasonable for your objects. After that, all other
+   occurrences of 'xx' should be changed to something reasonable for your
+   module. If your module is named foo your sourcefile should be named
+   foomodule.c.
+
+   You will probably want to delete all references to 'x_attr' and add
+   your own types of attributes instead.  Maybe you want to name your
+   local variables other than 'self'.  If your object type is needed in
+   other files, you'll have to create a file "foobarobject.h"; see
+   intobject.h for an example. */
+
+/* Xxo objects */
+
+#include "Python.h"
+
+static PyObject *ErrorObject;
+
+typedef struct {
+	PyObject_HEAD
+	PyObject	*x_attr;	/* Attributes dictionary */
+} XxoObject;
+
+static PyTypeObject Xxo_Type;
+
+#define XxoObject_Check(v)	((v)->ob_type == &Xxo_Type)
+
+static XxoObject *
+newXxoObject(PyObject *arg)
+{
+	XxoObject *self;
+	self = PyObject_New(XxoObject, &Xxo_Type);
+	if (self == NULL)
+		return NULL;
+	self->x_attr = NULL;
+	return self;
+}
+
+/* Xxo methods */
+
+static void
+Xxo_dealloc(XxoObject *self)
+{
+	Py_XDECREF(self->x_attr);
+	PyObject_Del(self);
+}
+
+static PyObject *
+Xxo_demo(XxoObject *self, PyObject *args)
+{
+	if (!PyArg_ParseTuple(args, ":demo"))
+		return NULL;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyMethodDef Xxo_methods[] = {
+	{"demo",	(PyCFunction)Xxo_demo,	METH_VARARGS,
+		PyDoc_STR("demo() -> None")},
+	{NULL,		NULL}		/* sentinel */
+};
+
+static PyObject *
+Xxo_getattr(XxoObject *self, char *name)
+{
+	if (self->x_attr != NULL) {
+		PyObject *v = PyDict_GetItemString(self->x_attr, name);
+		if (v != NULL) {
+			Py_INCREF(v);
+			return v;
+		}
+	}
+	return Py_FindMethod(Xxo_methods, (PyObject *)self, name);
+}
+
+static int
+Xxo_setattr(XxoObject *self, char *name, PyObject *v)
+{
+	if (self->x_attr == NULL) {
+		self->x_attr = PyDict_New();
+		if (self->x_attr == NULL)
+			return -1;
+	}
+	if (v == NULL) {
+		int rv = PyDict_DelItemString(self->x_attr, name);
+		if (rv < 0)
+			PyErr_SetString(PyExc_AttributeError,
+			        "delete non-existing Xxo attribute");
+		return rv;
+	}
+	else
+		return PyDict_SetItemString(self->x_attr, name, v);
+}
+
+static PyTypeObject Xxo_Type = {
+	/* The ob_type field must be initialized in the module init function
+	 * to be portable to Windows without using C++. */
+	PyObject_HEAD_INIT(NULL)
+	0,			/*ob_size*/
+	"xxmodule.Xxo",		/*tp_name*/
+	sizeof(XxoObject),	/*tp_basicsize*/
+	0,			/*tp_itemsize*/
+	/* methods */
+	(destructor)Xxo_dealloc, /*tp_dealloc*/
+	0,			/*tp_print*/
+	(getattrfunc)Xxo_getattr, /*tp_getattr*/
+	(setattrfunc)Xxo_setattr, /*tp_setattr*/
+	0,			/*tp_compare*/
+	0,			/*tp_repr*/
+	0,			/*tp_as_number*/
+	0,			/*tp_as_sequence*/
+	0,			/*tp_as_mapping*/
+	0,			/*tp_hash*/
+        0,                      /*tp_call*/
+        0,                      /*tp_str*/
+        0,                      /*tp_getattro*/
+        0,                      /*tp_setattro*/
+        0,                      /*tp_as_buffer*/
+        Py_TPFLAGS_DEFAULT,     /*tp_flags*/
+        0,                      /*tp_doc*/
+        0,                      /*tp_traverse*/
+        0,                      /*tp_clear*/
+        0,                      /*tp_richcompare*/
+        0,                      /*tp_weaklistoffset*/
+        0,                      /*tp_iter*/
+        0,                      /*tp_iternext*/
+        0,                      /*tp_methods*/
+        0,                      /*tp_members*/
+        0,                      /*tp_getset*/
+        0,                      /*tp_base*/
+        0,                      /*tp_dict*/
+        0,                      /*tp_descr_get*/
+        0,                      /*tp_descr_set*/
+        0,                      /*tp_dictoffset*/
+        0,                      /*tp_init*/
+        0,                      /*tp_alloc*/
+        0,                      /*tp_new*/
+        0,                      /*tp_free*/
+        0,                      /*tp_is_gc*/
+};
+/* --------------------------------------------------------------------- */
+
+/* Function of two integers returning integer */
+
+PyDoc_STRVAR(xx_foo_doc,
+"foo(i,j)\n\
+\n\
+Return the sum of i and j.");
+
+static PyObject *
+xx_foo(PyObject *self, PyObject *args)
+{
+	long i, j;
+	long res;
+	if (!PyArg_ParseTuple(args, "ll:foo", &i, &j))
+		return NULL;
+	res = i+j; /* XXX Do something here */
+	return PyInt_FromLong(res);
+}
+
+
+/* Function of no arguments returning new Xxo object */
+
+static PyObject *
+xx_new(PyObject *self, PyObject *args)
+{
+	XxoObject *rv;
+
+	if (!PyArg_ParseTuple(args, ":new"))
+		return NULL;
+	rv = newXxoObject(args);
+	if (rv == NULL)
+		return NULL;
+	return (PyObject *)rv;
+}
+
+/* Example with subtle bug from extensions manual ("Thin Ice"). */
+
+static PyObject *
+xx_bug(PyObject *self, PyObject *args)
+{
+	PyObject *list, *item;
+
+	if (!PyArg_ParseTuple(args, "O:bug", &list))
+		return NULL;
+
+	item = PyList_GetItem(list, 0);
+	/* Py_INCREF(item); */
+	PyList_SetItem(list, 1, PyInt_FromLong(0L));
+	PyObject_Print(item, stdout, 0);
+	printf("\n");
+	/* Py_DECREF(item); */
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* Test bad format character */
+
+static PyObject *
+xx_roj(PyObject *self, PyObject *args)
+{
+	PyObject *a;
+	long b;
+	if (!PyArg_ParseTuple(args, "O#:roj", &a, &b))
+		return NULL;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+
+/* ---------- */
+
+static PyTypeObject Str_Type = {
+	/* The ob_type field must be initialized in the module init function
+	 * to be portable to Windows without using C++. */
+	PyObject_HEAD_INIT(NULL)
+	0,			/*ob_size*/
+	"xxmodule.Str",		/*tp_name*/
+	0,			/*tp_basicsize*/
+	0,			/*tp_itemsize*/
+	/* methods */
+	0,			/*tp_dealloc*/
+	0,			/*tp_print*/
+	0,			/*tp_getattr*/
+	0,			/*tp_setattr*/
+	0,			/*tp_compare*/
+	0,			/*tp_repr*/
+	0,			/*tp_as_number*/
+	0,			/*tp_as_sequence*/
+	0,			/*tp_as_mapping*/
+	0,			/*tp_hash*/
+	0,			/*tp_call*/
+	0,			/*tp_str*/
+	0,			/*tp_getattro*/
+	0,			/*tp_setattro*/
+	0,			/*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+	0,			/*tp_doc*/
+	0,			/*tp_traverse*/
+	0,			/*tp_clear*/
+	0,			/*tp_richcompare*/
+	0,			/*tp_weaklistoffset*/
+	0,			/*tp_iter*/
+	0,			/*tp_iternext*/
+	0,			/*tp_methods*/
+	0,			/*tp_members*/
+	0,			/*tp_getset*/
+	&PyString_Type,		/*tp_base*/
+	0,			/*tp_dict*/
+	0,			/*tp_descr_get*/
+	0,			/*tp_descr_set*/
+	0,			/*tp_dictoffset*/
+	0,			/*tp_init*/
+	0,			/*tp_alloc*/
+	0,			/*tp_new*/
+	0,			/*tp_free*/
+	0,			/*tp_is_gc*/
+};
+
+/* ---------- */
+
+static PyObject *
+null_richcompare(PyObject *self, PyObject *other, int op)
+{
+	Py_INCREF(Py_NotImplemented);
+	return Py_NotImplemented;
+}
+
+static PyTypeObject Null_Type = {
+	/* The ob_type field must be initialized in the module init function
+	 * to be portable to Windows without using C++. */
+	PyObject_HEAD_INIT(NULL)
+	0,			/*ob_size*/
+	"xxmodule.Null",	/*tp_name*/
+	0,			/*tp_basicsize*/
+	0,			/*tp_itemsize*/
+	/* methods */
+	0,			/*tp_dealloc*/
+	0,			/*tp_print*/
+	0,			/*tp_getattr*/
+	0,			/*tp_setattr*/
+	0,			/*tp_compare*/
+	0,			/*tp_repr*/
+	0,			/*tp_as_number*/
+	0,			/*tp_as_sequence*/
+	0,			/*tp_as_mapping*/
+	0,			/*tp_hash*/
+	0,			/*tp_call*/
+	0,			/*tp_str*/
+	0,			/*tp_getattro*/
+	0,			/*tp_setattro*/
+	0,			/*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+	0,			/*tp_doc*/
+	0,			/*tp_traverse*/
+	0,			/*tp_clear*/
+	null_richcompare,	/*tp_richcompare*/
+	0,			/*tp_weaklistoffset*/
+	0,			/*tp_iter*/
+	0,			/*tp_iternext*/
+	0,			/*tp_methods*/
+	0,			/*tp_members*/
+	0,			/*tp_getset*/
+	&PyBaseObject_Type,	/*tp_base*/
+	0,			/*tp_dict*/
+	0,			/*tp_descr_get*/
+	0,			/*tp_descr_set*/
+	0,			/*tp_dictoffset*/
+	0,			/*tp_init*/
+	0,			/*tp_alloc*/
+	PyType_GenericNew,	/*tp_new*/
+	0,			/*tp_free*/
+	0,			/*tp_is_gc*/
+};
+
+
+/* ---------- */
+
+
+/* List of functions defined in the module */
+
+static PyMethodDef xx_methods[] = {
+	{"roj",		xx_roj,		METH_VARARGS,
+		PyDoc_STR("roj(a,b) -> None")},
+	{"foo",		xx_foo,		METH_VARARGS,
+	 	xx_foo_doc},
+	{"new",		xx_new,		METH_VARARGS,
+		PyDoc_STR("new() -> new Xx object")},
+	{"bug",		xx_bug,		METH_VARARGS,
+		PyDoc_STR("bug(o) -> None")},
+	{NULL,		NULL}		/* sentinel */
+};
+
+PyDoc_STRVAR(module_doc,
+"This is a template module just for instruction.");
+
+/* Initialization function for the module (*must* be called initxx) */
+
+PyMODINIT_FUNC
+initxx(void)
+{
+	PyObject *m;
+
+	/* Finalize the type object including setting type of the new type
+	 * object; doing it here is required for portability to Windows 
+	 * without requiring C++. */
+	if (PyType_Ready(&Xxo_Type) < 0)
+		return;
+
+	/* Create the module and add the functions */
+	m = Py_InitModule3("xx", xx_methods, module_doc);
+	if (m == NULL)
+		return;
+
+	/* Add some symbolic constants to the module */
+	if (ErrorObject == NULL) {
+		ErrorObject = PyErr_NewException("xx.error", NULL, NULL);
+		if (ErrorObject == NULL)
+			return;
+	}
+	Py_INCREF(ErrorObject);
+	PyModule_AddObject(m, "error", ErrorObject);
+
+	/* Add Str */
+	if (PyType_Ready(&Str_Type) < 0)
+		return;
+	PyModule_AddObject(m, "Str", (PyObject *)&Str_Type);
+
+	/* Add Null */
+	if (PyType_Ready(&Null_Type) < 0)
+		return;
+	PyModule_AddObject(m, "Null", (PyObject *)&Null_Type);
+}

Added: vendor/Python/current/Modules/xxsubtype.c
===================================================================
--- vendor/Python/current/Modules/xxsubtype.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/xxsubtype.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,299 @@
+#include "Python.h"
+#include "structmember.h"
+
+PyDoc_STRVAR(xxsubtype__doc__,
+"xxsubtype is an example module showing how to subtype builtin types from C.\n"
+"test_descr.py in the standard test suite requires it in order to complete.\n"
+"If you don't care about the examples, and don't intend to run the Python\n"
+"test suite, you can recompile Python without Modules/xxsubtype.c.");
+
+/* We link this module statically for convenience.  If compiled as a shared
+   library instead, some compilers don't allow addresses of Python objects
+   defined in other libraries to be used in static initializers here.  The
+   DEFERRED_ADDRESS macro is used to tag the slots where such addresses
+   appear; the module init function must fill in the tagged slots at runtime.
+   The argument is for documentation -- the macro ignores it.
+*/
+#define DEFERRED_ADDRESS(ADDR) 0
+
+/* spamlist -- a list subtype */
+
+typedef struct {
+	PyListObject list;
+	int state;
+} spamlistobject;
+
+static PyObject *
+spamlist_getstate(spamlistobject *self, PyObject *args)
+{
+	if (!PyArg_ParseTuple(args, ":getstate"))
+		return NULL;
+	return PyInt_FromLong(self->state);
+}
+
+static PyObject *
+spamlist_setstate(spamlistobject *self, PyObject *args)
+{
+	int state;
+
+	if (!PyArg_ParseTuple(args, "i:setstate", &state))
+		return NULL;
+	self->state = state;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+spamlist_specialmeth(PyObject *self, PyObject *args, PyObject *kw)
+{
+	PyObject *result = PyTuple_New(3);
+
+	if (result != NULL) {
+		if (self == NULL)
+			self = Py_None;
+		if (kw == NULL)
+			kw = Py_None;
+		Py_INCREF(self);
+		PyTuple_SET_ITEM(result, 0, self);
+		Py_INCREF(args);
+		PyTuple_SET_ITEM(result, 1, args);
+		Py_INCREF(kw);
+		PyTuple_SET_ITEM(result, 2, kw);
+	}
+	return result;
+}
+
+static PyMethodDef spamlist_methods[] = {
+	{"getstate", (PyCFunction)spamlist_getstate, METH_VARARGS,
+	 	PyDoc_STR("getstate() -> state")},
+	{"setstate", (PyCFunction)spamlist_setstate, METH_VARARGS,
+	 	PyDoc_STR("setstate(state)")},
+	/* These entries differ only in the flags; they are used by the tests
+	   in test.test_descr. */
+	{"classmeth", (PyCFunction)spamlist_specialmeth,
+		METH_VARARGS | METH_KEYWORDS | METH_CLASS,
+	 	PyDoc_STR("classmeth(*args, **kw)")},
+	{"staticmeth", (PyCFunction)spamlist_specialmeth,
+		METH_VARARGS | METH_KEYWORDS | METH_STATIC,
+	 	PyDoc_STR("staticmeth(*args, **kw)")},
+	{NULL,	NULL},
+};
+
+static int
+spamlist_init(spamlistobject *self, PyObject *args, PyObject *kwds)
+{
+	if (PyList_Type.tp_init((PyObject *)self, args, kwds) < 0)
+		return -1;
+	self->state = 0;
+	return 0;
+}
+
+static PyObject *
+spamlist_state_get(spamlistobject *self)
+{
+	return PyInt_FromLong(self->state);
+}
+
+static PyGetSetDef spamlist_getsets[] = {
+	{"state", (getter)spamlist_state_get, NULL,
+	 PyDoc_STR("an int variable for demonstration purposes")},
+	{0}
+};
+
+static PyTypeObject spamlist_type = {
+	PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
+	0,
+	"xxsubtype.spamlist",
+	sizeof(spamlistobject),
+	0,
+	0,					/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	0,					/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	0,					/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0,					/* tp_doc */
+	0,					/* tp_traverse */
+	0,					/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	spamlist_methods,			/* tp_methods */
+	0,					/* tp_members */
+	spamlist_getsets,			/* tp_getset */
+	DEFERRED_ADDRESS(&PyList_Type),		/* tp_base */
+	0,					/* tp_dict */
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	(initproc)spamlist_init,		/* tp_init */
+	0,					/* tp_alloc */
+	0,					/* tp_new */
+};
+
+/* spamdict -- a dict subtype */
+
+typedef struct {
+	PyDictObject dict;
+	int state;
+} spamdictobject;
+
+static PyObject *
+spamdict_getstate(spamdictobject *self, PyObject *args)
+{
+	if (!PyArg_ParseTuple(args, ":getstate"))
+		return NULL;
+	return PyInt_FromLong(self->state);
+}
+
+static PyObject *
+spamdict_setstate(spamdictobject *self, PyObject *args)
+{
+	int state;
+
+	if (!PyArg_ParseTuple(args, "i:setstate", &state))
+		return NULL;
+	self->state = state;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyMethodDef spamdict_methods[] = {
+	{"getstate", (PyCFunction)spamdict_getstate, METH_VARARGS,
+	 	PyDoc_STR("getstate() -> state")},
+	{"setstate", (PyCFunction)spamdict_setstate, METH_VARARGS,
+	 	PyDoc_STR("setstate(state)")},
+	{NULL,	NULL},
+};
+
+static int
+spamdict_init(spamdictobject *self, PyObject *args, PyObject *kwds)
+{
+	if (PyDict_Type.tp_init((PyObject *)self, args, kwds) < 0)
+		return -1;
+	self->state = 0;
+	return 0;
+}
+
+static PyMemberDef spamdict_members[] = {
+	{"state", T_INT, offsetof(spamdictobject, state), READONLY,
+	 PyDoc_STR("an int variable for demonstration purposes")},
+	{0}
+};
+
+static PyTypeObject spamdict_type = {
+	PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
+	0,
+	"xxsubtype.spamdict",
+	sizeof(spamdictobject),
+	0,
+	0,					/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	0,					/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	0,					/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+	0,					/* tp_doc */
+	0,					/* tp_traverse */
+	0,					/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	spamdict_methods,			/* tp_methods */
+	spamdict_members,			/* tp_members */
+	0,					/* tp_getset */
+	DEFERRED_ADDRESS(&PyDict_Type),		/* tp_base */
+	0,					/* tp_dict */
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	(initproc)spamdict_init,		/* tp_init */
+	0,					/* tp_alloc */
+	0,					/* tp_new */
+};
+
+static PyObject *
+spam_bench(PyObject *self, PyObject *args)
+{
+	PyObject *obj, *name, *res;
+	int n = 1000;
+	time_t t0, t1;
+
+	if (!PyArg_ParseTuple(args, "OS|i", &obj, &name, &n))
+		return NULL;
+	t0 = clock();
+	while (--n >= 0) {
+		res = PyObject_GetAttr(obj, name);
+		if (res == NULL)
+			return NULL;
+		Py_DECREF(res);
+	}
+	t1 = clock();
+	return PyFloat_FromDouble((double)(t1-t0) / CLOCKS_PER_SEC);
+}
+
+static PyMethodDef xxsubtype_functions[] = {
+	{"bench",	spam_bench, 	METH_VARARGS},
+	{NULL,		NULL}		/* sentinel */
+};
+
+PyMODINIT_FUNC
+initxxsubtype(void)
+{
+	PyObject *m;
+
+	/* Fill in deferred data addresses.  This must be done before
+	   PyType_Ready() is called.  Note that PyType_Ready() automatically
+	   initializes the ob.ob_type field to &PyType_Type if it's NULL,
+	   so it's not necessary to fill in ob_type first. */
+	spamdict_type.tp_base = &PyDict_Type;
+	if (PyType_Ready(&spamdict_type) < 0)
+		return;
+
+	spamlist_type.tp_base = &PyList_Type;
+	if (PyType_Ready(&spamlist_type) < 0)
+		return;
+
+	m = Py_InitModule3("xxsubtype",
+			   xxsubtype_functions,
+			   xxsubtype__doc__);
+	if (m == NULL)
+		return;
+
+	if (PyType_Ready(&spamlist_type) < 0)
+		return;
+	if (PyType_Ready(&spamdict_type) < 0)
+		return;
+
+	Py_INCREF(&spamlist_type);
+	if (PyModule_AddObject(m, "spamlist",
+			       (PyObject *) &spamlist_type) < 0)
+		return;
+
+	Py_INCREF(&spamdict_type);
+	if (PyModule_AddObject(m, "spamdict",
+			       (PyObject *) &spamdict_type) < 0)
+		return;
+}

Added: vendor/Python/current/Modules/yuv.h
===================================================================
--- vendor/Python/current/Modules/yuv.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/yuv.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,99 @@
+
+#ifndef Py_YUV_H
+#define Py_YUV_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * SVideo YUV 4:1:1 format.
+ *
+ * 4 consecutive quadwords describe 8 pixels on 2 lines, as depicted
+ * below.  An array of (width/4) of the below structure describes 2
+ * scan lines.
+ *
+ * +-------------------+
+ * | 00 | 01 | 02 | 03 | . . .
+ * +-------------------+
+ * | 10 | 11 | 12 | 13 | . . .
+ * +-------------------+
+ */
+struct yuv411 {
+	struct {
+		unsigned int dummy:8;
+		unsigned int y0:8;
+		unsigned int u0:2;
+		unsigned int v0:2;
+		unsigned int y1:8;
+		unsigned int u1:2;
+		unsigned int v1:2;
+	} v[4];
+};
+
+#define YUV411_Y00(y)	(y).v[0].y0
+#define YUV411_Y01(y)	(y).v[1].y0
+#define YUV411_Y02(y)	(y).v[2].y0
+#define YUV411_Y03(y)	(y).v[3].y0
+#define YUV411_Y10(y)	(y).v[0].y1
+#define YUV411_Y11(y)	(y).v[1].y1
+#define YUV411_Y12(y)	(y).v[2].y1
+#define YUV411_Y13(y)	(y).v[3].y1
+#define YUV411_U00(y)	((y).v[0].u0<<6|(y).v[1].u0<<4|(y).v[2].u0<<2|(y).v[3].u0)
+#define YUV411_U01(y)	YUV411_U00(y)
+#define YUV411_U02(y)	YUV411_U00(y)
+#define YUV411_U03(y)	YUV411_U00(y)
+#define YUV411_U10(y)	((y).v[0].u1<<6|(y).v[1].u1<<4|(y).v[2].u1<<2|(y).v[3].u1)
+#define YUV411_U11(y)	YUV411_U10(y)
+#define YUV411_U12(y)	YUV411_U10(y)
+#define YUV411_U13(y)	YUV411_U10(y)
+#define YUV411_V00(y)	((y).v[0].v0<<6|(y).v[1].v0<<4|(y).v[2].v0<<2|(y).v[3].v0)
+#define YUV411_V01(y)	YUV411_V00(y)
+#define YUV411_V02(y)	YUV411_V00(y)
+#define YUV411_V03(y)	YUV411_V00(y)
+#define YUV411_V10(y)	((y).v[0].v1<<6|(y).v[1].v1<<4|(y).v[2].v1<<2|(y).v[3].v1)
+#define YUV411_V11(y)	YUV411_V10(y)
+#define YUV411_V12(y)	YUV411_V10(y)
+#define YUV411_V13(y)	YUV411_V10(y)
+
+/*
+ * Compression Library YUV 4:2:2 format.
+ *
+ * 1 longword describes 2 pixels.
+ *
+ * +-------+
+ * | 0 | 1 |
+ * +-------+
+ */
+struct yuv422 {
+	unsigned int u:8;
+	unsigned int y0:8;
+	unsigned int v:8;
+	unsigned int y1:8;
+};
+#define YUV422_Y0(y)	(y).y0
+#define YUV422_Y1(y)	(y).y1
+#define YUV422_U0(y)	(y).u
+#define YUV422_U1(y)	(y).u
+#define YUV422_V0(y)	(y).v
+#define YUV422_V1(y)	(y).v
+
+/*
+ * Compression library YUV 4:2:2 Duplicate Chroma format.
+ *
+ * This is like the previous format, but the U and V values are
+ * duplicated vertically (and hence there is some redundancy in the
+ * data).  With other words, lines 2*n and 2*n+1 have the same U and V
+ * values but different Y values.
+ */
+
+/*
+ * Conversion functions.
+ */
+void yuv_sv411_to_cl422dc(int, void *, void *, int, int);
+void yuv_sv411_to_cl422dc_quartersize(int, void *, void *, int, int);
+void yuv_sv411_to_cl422dc_sixteenthsize(int, void *, void *, int, int);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_YUV_H */

Added: vendor/Python/current/Modules/yuvconvert.c
===================================================================
--- vendor/Python/current/Modules/yuvconvert.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/yuvconvert.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,118 @@
+
+#include "yuv.h"
+
+void
+yuv_sv411_to_cl422dc(int invert, void *data, void *yuv, int width, int height)
+{
+	struct yuv411 *in = data;
+	struct yuv422 *out_even = yuv;
+	struct yuv422 *out_odd = out_even + width / 2;
+	int i, j;		/* counters */
+
+	for (i = height / 2; i--; ) {
+		for (j = width / 4; j--; ) {
+			YUV422_Y0(*out_even) = YUV411_Y00(*in);
+			YUV422_U0(*out_even) = YUV411_U00(*in);
+			YUV422_V0(*out_even) = YUV411_V00(*in);
+			YUV422_Y1(*out_even) = YUV411_Y01(*in);
+			out_even++;
+			YUV422_Y0(*out_even) = YUV411_Y02(*in);
+			YUV422_U0(*out_even) = YUV411_U02(*in);
+			YUV422_V0(*out_even) = YUV411_V02(*in);
+			YUV422_Y1(*out_even) = YUV411_Y03(*in);
+			out_even++;
+			YUV422_Y0(*out_odd) = YUV411_Y10(*in);
+			YUV422_U0(*out_odd) = YUV411_U10(*in);
+			YUV422_V0(*out_odd) = YUV411_V10(*in);
+			YUV422_Y1(*out_odd) = YUV411_Y11(*in);
+			out_odd++;
+			YUV422_Y0(*out_odd) = YUV411_Y12(*in);
+			YUV422_U0(*out_odd) = YUV411_U12(*in);
+			YUV422_V0(*out_odd) = YUV411_V12(*in);
+			YUV422_Y1(*out_odd) = YUV411_Y13(*in);
+			out_odd++;
+			in++;
+		}
+		out_even += width / 2;
+		out_odd += width / 2;
+	}
+}
+
+void
+yuv_sv411_to_cl422dc_quartersize(int invert, void *data, void *yuv,
+				 int width, int height)
+{
+	int w4 = width / 4;	/* quarter of width is used often */
+	struct yuv411 *in_even = data;
+	struct yuv411 *in_odd = in_even + w4;
+	struct yuv422 *out_even = yuv;
+	struct yuv422 *out_odd = out_even + w4;
+	int i, j;		/* counters */
+	int u, v;		/* U and V values */
+
+	for (i = height / 4; i--; ) {
+		for (j = w4; j--; ) {
+			u = YUV411_U00(*in_even);
+			v = YUV411_V00(*in_even);
+
+			YUV422_Y0(*out_even) = YUV411_Y00(*in_even);
+			YUV422_U0(*out_even) = u;
+			YUV422_V0(*out_even) = v;
+			YUV422_Y1(*out_even) = YUV411_Y02(*in_even);
+
+			YUV422_Y0(*out_odd) = YUV411_Y10(*in_odd);
+			YUV422_U0(*out_odd) = u;
+			YUV422_V0(*out_odd) = v;
+			YUV422_Y1(*out_odd) = YUV411_Y12(*in_odd);
+
+			in_even++;
+			in_odd++;
+			out_even++;
+			out_odd++;
+		}
+		in_even += w4;
+		in_odd += w4;
+		out_even += w4;
+		out_odd += w4;
+	}
+}
+
+void
+yuv_sv411_to_cl422dc_sixteenthsize(int invert, void *data, void *yuv,
+				   int width, int height)
+{
+	int w4_3 = 3 * width / 4; /* three quarters of width is used often */
+	int w8 = width / 8;	/* and so is one eighth */
+	struct yuv411 *in_even = data;
+	struct yuv411 *in_odd = in_even + width / 2;
+	struct yuv422 *out_even = yuv;
+	struct yuv422 *out_odd = out_even + w8;
+	int i, j;		/* counters */
+	int u, v;		/* U and V values */
+
+	for (i = height / 8; i--; ) {
+		for (j = w8; j--; ) {
+			u = YUV411_U00(in_even[0]);
+			v = YUV411_V00(in_even[0]);
+
+			YUV422_Y0(*out_even) = YUV411_Y00(in_even[0]);
+			YUV422_U0(*out_even) = u;
+			YUV422_V0(*out_even) = v;
+			YUV422_Y1(*out_even) = YUV411_Y00(in_even[1]);
+
+			YUV422_Y0(*out_odd) = YUV411_Y00(in_odd[0]);
+			YUV422_U0(*out_odd) = u;
+			YUV422_V0(*out_odd) = v;
+			YUV422_Y1(*out_odd) = YUV411_Y00(in_even[1]);
+
+			in_even += 2;
+			in_odd += 2;
+			out_even++;
+			out_odd++;
+		}
+		in_even += w4_3;
+		in_odd += w4_3;
+		out_even += w8;
+		out_odd += w8;
+	}
+}

Added: vendor/Python/current/Modules/zipimport.c
===================================================================
--- vendor/Python/current/Modules/zipimport.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/zipimport.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1191 @@
+#include "Python.h"
+#include "structmember.h"
+#include "osdefs.h"
+#include "marshal.h"
+#include <time.h>
+
+
+#define IS_SOURCE   0x0
+#define IS_BYTECODE 0x1
+#define IS_PACKAGE  0x2
+
+struct st_zip_searchorder {
+	char suffix[14];
+	int type;
+};
+
+/* zip_searchorder defines how we search for a module in the Zip
+   archive: we first search for a package __init__, then for
+   non-package .pyc, .pyo and .py entries. The .pyc and .pyo entries
+   are swapped by initzipimport() if we run in optimized mode. Also,
+   '/' is replaced by SEP there. */
+static struct st_zip_searchorder zip_searchorder[] = {
+	{"/__init__.pyc", IS_PACKAGE | IS_BYTECODE},
+	{"/__init__.pyo", IS_PACKAGE | IS_BYTECODE},
+	{"/__init__.py", IS_PACKAGE | IS_SOURCE},
+	{".pyc", IS_BYTECODE},
+	{".pyo", IS_BYTECODE},
+	{".py", IS_SOURCE},
+	{"", 0}
+};
+
+/* zipimporter object definition and support */
+
+typedef struct _zipimporter ZipImporter;
+
+struct _zipimporter {
+	PyObject_HEAD
+	PyObject *archive;  /* pathname of the Zip archive */
+	PyObject *prefix;   /* file prefix: "a/sub/directory/" */
+	PyObject *files;    /* dict with file info {path: toc_entry} */
+};
+
+static PyObject *ZipImportError;
+static PyObject *zip_directory_cache = NULL;
+
+/* forward decls */
+static PyObject *read_directory(char *archive);
+static PyObject *get_data(char *archive, PyObject *toc_entry);
+static PyObject *get_module_code(ZipImporter *self, char *fullname,
+				 int *p_ispackage, char **p_modpath);
+
+
+#define ZipImporter_Check(op) PyObject_TypeCheck(op, &ZipImporter_Type)
+
+
+/* zipimporter.__init__
+   Split the "subdirectory" from the Zip archive path, lookup a matching
+   entry in sys.path_importer_cache, fetch the file directory from there
+   if found, or else read it from the archive. */
+static int
+zipimporter_init(ZipImporter *self, PyObject *args, PyObject *kwds)
+{
+	char *path, *p, *prefix, buf[MAXPATHLEN+2];
+	size_t len;
+
+	if (!_PyArg_NoKeywords("zipimporter()", kwds))
+		return -1;
+
+	if (!PyArg_ParseTuple(args, "s:zipimporter",
+			      &path))
+		return -1;
+
+	len = strlen(path);
+	if (len == 0) {
+		PyErr_SetString(ZipImportError, "archive path is empty");
+		return -1;
+	}
+	if (len >= MAXPATHLEN) {
+		PyErr_SetString(ZipImportError,
+				"archive path too long");
+		return -1;
+	}
+	strcpy(buf, path);
+
+#ifdef ALTSEP
+	for (p = buf; *p; p++) {
+		if (*p == ALTSEP)
+			*p = SEP;
+	}
+#endif
+
+	path = NULL;
+	prefix = NULL;
+	for (;;) {
+#ifndef RISCOS
+		struct stat statbuf;
+		int rv;
+
+		rv = stat(buf, &statbuf);
+		if (rv == 0) {
+			/* it exists */
+			if (S_ISREG(statbuf.st_mode))
+				/* it's a file */
+				path = buf;
+			break;
+		}
+#else
+		if (object_exists(buf)) {
+			/* it exists */
+			if (isfile(buf))
+				/* it's a file */
+				path = buf;
+			break;
+		}
+#endif
+		/* back up one path element */
+		p = strrchr(buf, SEP);
+		if (prefix != NULL)
+			*prefix = SEP;
+		if (p == NULL)
+			break;
+		*p = '\0';
+		prefix = p;
+	}
+	if (path != NULL) {
+		PyObject *files;
+		files = PyDict_GetItemString(zip_directory_cache, path);
+		if (files == NULL) {
+			files = read_directory(buf);
+			if (files == NULL)
+				return -1;
+			if (PyDict_SetItemString(zip_directory_cache, path,
+						 files) != 0)
+				return -1;
+		}
+		else
+			Py_INCREF(files);
+		self->files = files;
+	}
+	else {
+		PyErr_SetString(ZipImportError, "not a Zip file");
+		return -1;
+	}
+
+	if (prefix == NULL)
+		prefix = "";
+	else {
+		prefix++;
+		len = strlen(prefix);
+		if (prefix[len-1] != SEP) {
+			/* add trailing SEP */
+			prefix[len] = SEP;
+			prefix[len + 1] = '\0';
+		}
+	}
+
+	self->archive = PyString_FromString(buf);
+	if (self->archive == NULL)
+		return -1;
+
+	self->prefix = PyString_FromString(prefix);
+	if (self->prefix == NULL)
+		return -1;
+
+	return 0;
+}
+
+/* GC support. */
+static int
+zipimporter_traverse(PyObject *obj, visitproc visit, void *arg)
+{
+	ZipImporter *self = (ZipImporter *)obj;
+	Py_VISIT(self->files);
+	return 0;
+}
+
+static void
+zipimporter_dealloc(ZipImporter *self)
+{
+	PyObject_GC_UnTrack(self);
+	Py_XDECREF(self->archive);
+	Py_XDECREF(self->prefix);
+	Py_XDECREF(self->files);
+	self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *
+zipimporter_repr(ZipImporter *self)
+{
+	char buf[500];
+	char *archive = "???";
+	char *prefix = "";
+
+	if (self->archive != NULL && PyString_Check(self->archive))
+		archive = PyString_AsString(self->archive);
+	if (self->prefix != NULL && PyString_Check(self->prefix))
+		prefix = PyString_AsString(self->prefix);
+	if (prefix != NULL && *prefix)
+		PyOS_snprintf(buf, sizeof(buf),
+			      "<zipimporter object \"%.300s%c%.150s\">",
+			      archive, SEP, prefix);
+	else
+		PyOS_snprintf(buf, sizeof(buf),
+			      "<zipimporter object \"%.300s\">",
+			      archive);
+	return PyString_FromString(buf);
+}
+
+/* return fullname.split(".")[-1] */
+static char *
+get_subname(char *fullname)
+{
+	char *subname = strrchr(fullname, '.');
+	if (subname == NULL)
+		subname = fullname;
+	else
+		subname++;
+	return subname;
+}
+
+/* Given a (sub)modulename, write the potential file path in the
+   archive (without extension) to the path buffer. Return the
+   length of the resulting string. */
+static int
+make_filename(char *prefix, char *name, char *path)
+{
+	size_t len;
+	char *p;
+
+	len = strlen(prefix);
+
+	/* self.prefix + name [+ SEP + "__init__"] + ".py[co]" */
+	if (len + strlen(name) + 13 >= MAXPATHLEN) {
+		PyErr_SetString(ZipImportError, "path too long");
+		return -1;
+	}
+
+	strcpy(path, prefix);
+	strcpy(path + len, name);
+	for (p = path + len; *p; p++) {
+		if (*p == '.')
+			*p = SEP;
+	}
+	len += strlen(name);
+	assert(len < INT_MAX);
+	return (int)len;
+}
+
+enum zi_module_info {
+	MI_ERROR,
+	MI_NOT_FOUND,
+	MI_MODULE,
+	MI_PACKAGE
+};
+
+/* Return some information about a module. */
+static enum zi_module_info
+get_module_info(ZipImporter *self, char *fullname)
+{
+	char *subname, path[MAXPATHLEN + 1];
+	int len;
+	struct st_zip_searchorder *zso;
+
+	subname = get_subname(fullname);
+
+	len = make_filename(PyString_AsString(self->prefix), subname, path);
+	if (len < 0)
+		return MI_ERROR;
+
+	for (zso = zip_searchorder; *zso->suffix; zso++) {
+		strcpy(path + len, zso->suffix);
+		if (PyDict_GetItemString(self->files, path) != NULL) {
+			if (zso->type & IS_PACKAGE)
+				return MI_PACKAGE;
+			else
+				return MI_MODULE;
+		}
+	}
+	return MI_NOT_FOUND;
+}
+
+/* Check whether we can satisfy the import of the module named by
+   'fullname'. Return self if we can, None if we can't. */
+static PyObject *
+zipimporter_find_module(PyObject *obj, PyObject *args)
+{
+	ZipImporter *self = (ZipImporter *)obj;
+	PyObject *path = NULL;
+	char *fullname;
+	enum zi_module_info mi;
+
+	if (!PyArg_ParseTuple(args, "s|O:zipimporter.find_module",
+			      &fullname, &path))
+		return NULL;
+
+	mi = get_module_info(self, fullname);
+	if (mi == MI_ERROR)
+		return NULL;
+	if (mi == MI_NOT_FOUND) {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+	Py_INCREF(self);
+	return (PyObject *)self;
+}
+
+/* Load and return the module named by 'fullname'. */
+static PyObject *
+zipimporter_load_module(PyObject *obj, PyObject *args)
+{
+	ZipImporter *self = (ZipImporter *)obj;
+	PyObject *code, *mod, *dict;
+	char *fullname, *modpath;
+	int ispackage;
+
+	if (!PyArg_ParseTuple(args, "s:zipimporter.load_module",
+			      &fullname))
+		return NULL;
+
+	code = get_module_code(self, fullname, &ispackage, &modpath);
+	if (code == NULL)
+		return NULL;
+
+	mod = PyImport_AddModule(fullname);
+	if (mod == NULL) {
+		Py_DECREF(code);
+		return NULL;
+	}
+	dict = PyModule_GetDict(mod);
+
+	/* mod.__loader__ = self */
+	if (PyDict_SetItemString(dict, "__loader__", (PyObject *)self) != 0)
+		goto error;
+
+	if (ispackage) {
+		/* add __path__ to the module *before* the code gets
+		   executed */
+		PyObject *pkgpath, *fullpath;
+		char *prefix = PyString_AsString(self->prefix);
+		char *subname = get_subname(fullname);
+		int err;
+
+		fullpath = PyString_FromFormat("%s%c%s%s",
+					PyString_AsString(self->archive),
+					SEP,
+					*prefix ? prefix : "",
+					subname);
+		if (fullpath == NULL)
+			goto error;
+
+		pkgpath = Py_BuildValue("[O]", fullpath);
+		Py_DECREF(fullpath);
+		if (pkgpath == NULL)
+			goto error;
+		err = PyDict_SetItemString(dict, "__path__", pkgpath);
+		Py_DECREF(pkgpath);
+		if (err != 0)
+			goto error;
+	}
+	mod = PyImport_ExecCodeModuleEx(fullname, code, modpath);
+	Py_DECREF(code);
+	if (Py_VerboseFlag)
+		PySys_WriteStderr("import %s # loaded from Zip %s\n",
+				  fullname, modpath);
+	return mod;
+error:
+	Py_DECREF(code);
+	Py_DECREF(mod);
+	return NULL;
+}
+
+/* Return a bool signifying whether the module is a package or not. */
+static PyObject *
+zipimporter_is_package(PyObject *obj, PyObject *args)
+{
+	ZipImporter *self = (ZipImporter *)obj;
+	char *fullname;
+	enum zi_module_info mi;
+
+	if (!PyArg_ParseTuple(args, "s:zipimporter.is_package",
+			      &fullname))
+		return NULL;
+
+	mi = get_module_info(self, fullname);
+	if (mi == MI_ERROR)
+		return NULL;
+	if (mi == MI_NOT_FOUND) {
+		PyErr_Format(ZipImportError, "can't find module '%.200s'",
+			     fullname);
+		return NULL;
+	}
+	return PyBool_FromLong(mi == MI_PACKAGE);
+}
+
+static PyObject *
+zipimporter_get_data(PyObject *obj, PyObject *args)
+{
+	ZipImporter *self = (ZipImporter *)obj;
+	char *path;
+#ifdef ALTSEP
+	char *p, buf[MAXPATHLEN + 1];
+#endif
+	PyObject *toc_entry;
+	Py_ssize_t len;
+
+	if (!PyArg_ParseTuple(args, "s:zipimporter.get_data", &path))
+		return NULL;
+
+#ifdef ALTSEP
+	if (strlen(path) >= MAXPATHLEN) {
+		PyErr_SetString(ZipImportError, "path too long");
+		return NULL;
+	}
+	strcpy(buf, path);
+	for (p = buf; *p; p++) {
+		if (*p == ALTSEP)
+			*p = SEP;
+	}
+	path = buf;
+#endif
+	len = PyString_Size(self->archive);
+	if ((size_t)len < strlen(path) &&
+	    strncmp(path, PyString_AsString(self->archive), len) == 0 &&
+	    path[len] == SEP) {
+		path = path + len + 1;
+	}
+
+	toc_entry = PyDict_GetItemString(self->files, path);
+	if (toc_entry == NULL) {
+		PyErr_SetFromErrnoWithFilename(PyExc_IOError, path);
+		return NULL;
+	}
+	return get_data(PyString_AsString(self->archive), toc_entry);
+}
+
+static PyObject *
+zipimporter_get_code(PyObject *obj, PyObject *args)
+{
+	ZipImporter *self = (ZipImporter *)obj;
+	char *fullname;
+
+	if (!PyArg_ParseTuple(args, "s:zipimporter.get_code", &fullname))
+		return NULL;
+
+	return get_module_code(self, fullname, NULL, NULL);
+}
+
+static PyObject *
+zipimporter_get_source(PyObject *obj, PyObject *args)
+{
+	ZipImporter *self = (ZipImporter *)obj;
+	PyObject *toc_entry;
+	char *fullname, *subname, path[MAXPATHLEN+1];
+	int len;
+	enum zi_module_info mi;
+
+	if (!PyArg_ParseTuple(args, "s:zipimporter.get_source", &fullname))
+		return NULL;
+
+	mi = get_module_info(self, fullname);
+	if (mi == MI_ERROR)
+		return NULL;
+	if (mi == MI_NOT_FOUND) {
+		PyErr_Format(ZipImportError, "can't find module '%.200s'",
+			     fullname);
+		return NULL;
+	}
+	subname = get_subname(fullname);
+
+	len = make_filename(PyString_AsString(self->prefix), subname, path);
+	if (len < 0)
+		return NULL;
+
+	if (mi == MI_PACKAGE) {
+		path[len] = SEP;
+		strcpy(path + len + 1, "__init__.py");
+	}
+	else
+		strcpy(path + len, ".py");
+
+	toc_entry = PyDict_GetItemString(self->files, path);
+	if (toc_entry != NULL)
+		return get_data(PyString_AsString(self->archive), toc_entry);
+
+	/* we have the module, but no source */
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(doc_find_module,
+"find_module(fullname, path=None) -> self or None.\n\
+\n\
+Search for a module specified by 'fullname'. 'fullname' must be the\n\
+fully qualified (dotted) module name. It returns the zipimporter\n\
+instance itself if the module was found, or None if it wasn't.\n\
+The optional 'path' argument is ignored -- it's there for compatibility\n\
+with the importer protocol.");
+
+PyDoc_STRVAR(doc_load_module,
+"load_module(fullname) -> module.\n\
+\n\
+Load the module specified by 'fullname'. 'fullname' must be the\n\
+fully qualified (dotted) module name. It returns the imported\n\
+module, or raises ZipImportError if it wasn't found.");
+
+PyDoc_STRVAR(doc_get_data,
+"get_data(pathname) -> string with file data.\n\
+\n\
+Return the data associated with 'pathname'. Raise IOError if\n\
+the file wasn't found.");
+
+PyDoc_STRVAR(doc_is_package,
+"is_package(fullname) -> bool.\n\
+\n\
+Return True if the module specified by fullname is a package.\n\
+Raise ZipImportError is the module couldn't be found.");
+
+PyDoc_STRVAR(doc_get_code,
+"get_code(fullname) -> code object.\n\
+\n\
+Return the code object for the specified module. Raise ZipImportError\n\
+is the module couldn't be found.");
+
+PyDoc_STRVAR(doc_get_source,
+"get_source(fullname) -> source string.\n\
+\n\
+Return the source code for the specified module. Raise ZipImportError\n\
+is the module couldn't be found, return None if the archive does\n\
+contain the module, but has no source for it.");
+
+static PyMethodDef zipimporter_methods[] = {
+	{"find_module", zipimporter_find_module, METH_VARARGS,
+	 doc_find_module},
+	{"load_module", zipimporter_load_module, METH_VARARGS,
+	 doc_load_module},
+	{"get_data", zipimporter_get_data, METH_VARARGS,
+	 doc_get_data},
+	{"get_code", zipimporter_get_code, METH_VARARGS,
+	 doc_get_code},
+	{"get_source", zipimporter_get_source, METH_VARARGS,
+	 doc_get_source},
+	{"is_package", zipimporter_is_package, METH_VARARGS,
+	 doc_is_package},
+	{NULL,		NULL}	/* sentinel */
+};
+
+static PyMemberDef zipimporter_members[] = {
+	{"archive",  T_OBJECT, offsetof(ZipImporter, archive),  READONLY},
+	{"prefix",   T_OBJECT, offsetof(ZipImporter, prefix),   READONLY},
+	{"_files",   T_OBJECT, offsetof(ZipImporter, files),    READONLY},
+	{NULL}
+};
+
+PyDoc_STRVAR(zipimporter_doc,
+"zipimporter(archivepath) -> zipimporter object\n\
+\n\
+Create a new zipimporter instance. 'archivepath' must be a path to\n\
+a zipfile. ZipImportError is raised if 'archivepath' doesn't point to\n\
+a valid Zip archive.");
+
+#define DEFERRED_ADDRESS(ADDR) 0
+
+static PyTypeObject ZipImporter_Type = {
+	PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
+	0,
+	"zipimport.zipimporter",
+	sizeof(ZipImporter),
+	0,					/* tp_itemsize */
+	(destructor)zipimporter_dealloc,	/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	(reprfunc)zipimporter_repr,		/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
+		Py_TPFLAGS_HAVE_GC,		/* tp_flags */
+	zipimporter_doc,			/* tp_doc */
+	zipimporter_traverse,			/* tp_traverse */
+	0,					/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	zipimporter_methods,			/* tp_methods */
+	zipimporter_members,			/* tp_members */
+	0,					/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	(initproc)zipimporter_init,		/* tp_init */
+	PyType_GenericAlloc,			/* tp_alloc */
+	PyType_GenericNew,			/* tp_new */
+	PyObject_GC_Del,			/* tp_free */
+};
+
+
+/* implementation */
+
+/* Given a buffer, return the long that is represented by the first
+   4 bytes, encoded as little endian. This partially reimplements
+   marshal.c:r_long() */
+static long
+get_long(unsigned char *buf) {
+	long x;
+	x =  buf[0];
+	x |= (long)buf[1] <<  8;
+	x |= (long)buf[2] << 16;
+	x |= (long)buf[3] << 24;
+#if SIZEOF_LONG > 4
+	/* Sign extension for 64-bit machines */
+	x |= -(x & 0x80000000L);
+#endif
+	return x;
+}
+
+/*
+   read_directory(archive) -> files dict (new reference)
+
+   Given a path to a Zip archive, build a dict, mapping file names
+   (local to the archive, using SEP as a separator) to toc entries.
+
+   A toc_entry is a tuple:
+
+       (__file__,      # value to use for __file__, available for all files
+        compress,      # compression kind; 0 for uncompressed
+        data_size,     # size of compressed data on disk
+        file_size,     # size of decompressed data
+        file_offset,   # offset of file header from start of archive
+        time,          # mod time of file (in dos format)
+        date,          # mod data of file (in dos format)
+        crc,           # crc checksum of the data
+       )
+
+   Directories can be recognized by the trailing SEP in the name,
+   data_size and file_offset are 0.
+*/
+static PyObject *
+read_directory(char *archive)
+{
+	PyObject *files = NULL;
+	FILE *fp;
+	long compress, crc, data_size, file_size, file_offset, date, time;
+	long header_offset, name_size, header_size, header_position;
+	long i, l, count;
+	size_t length;
+	char path[MAXPATHLEN + 5];
+	char name[MAXPATHLEN + 5];
+	char *p, endof_central_dir[22];
+	long arc_offset; /* offset from beginning of file to start of zip-archive */
+
+	if (strlen(archive) > MAXPATHLEN) {
+		PyErr_SetString(PyExc_OverflowError,
+				"Zip path name is too long");
+		return NULL;
+	}
+	strcpy(path, archive);
+
+	fp = fopen(archive, "rb");
+	if (fp == NULL) {
+		PyErr_Format(ZipImportError, "can't open Zip file: "
+			     "'%.200s'", archive);
+		return NULL;
+	}
+	fseek(fp, -22, SEEK_END);
+	header_position = ftell(fp);
+	if (fread(endof_central_dir, 1, 22, fp) != 22) {
+		fclose(fp);
+		PyErr_Format(ZipImportError, "can't read Zip file: "
+			     "'%.200s'", archive);
+		return NULL;
+	}
+	if (get_long((unsigned char *)endof_central_dir) != 0x06054B50) {
+		/* Bad: End of Central Dir signature */
+		fclose(fp);
+		PyErr_Format(ZipImportError, "not a Zip file: "
+			     "'%.200s'", archive);
+		return NULL;
+	}
+
+	header_size = get_long((unsigned char *)endof_central_dir + 12);
+	header_offset = get_long((unsigned char *)endof_central_dir + 16);
+	arc_offset = header_position - header_offset - header_size;
+	header_offset += arc_offset;
+
+	files = PyDict_New();
+	if (files == NULL)
+		goto error;
+
+	length = (long)strlen(path);
+	path[length] = SEP;
+
+	/* Start of Central Directory */
+	count = 0;
+	for (;;) {
+		PyObject *t;
+		int err;
+
+		fseek(fp, header_offset, 0);  /* Start of file header */
+		l = PyMarshal_ReadLongFromFile(fp);
+		if (l != 0x02014B50)
+			break;	/* Bad: Central Dir File Header */
+		fseek(fp, header_offset + 10, 0);
+		compress = PyMarshal_ReadShortFromFile(fp);
+		time = PyMarshal_ReadShortFromFile(fp);
+		date = PyMarshal_ReadShortFromFile(fp);
+		crc = PyMarshal_ReadLongFromFile(fp);
+		data_size = PyMarshal_ReadLongFromFile(fp);
+		file_size = PyMarshal_ReadLongFromFile(fp);
+		name_size = PyMarshal_ReadShortFromFile(fp);
+		header_size = 46 + name_size +
+		   PyMarshal_ReadShortFromFile(fp) +
+		   PyMarshal_ReadShortFromFile(fp);
+		fseek(fp, header_offset + 42, 0);
+		file_offset = PyMarshal_ReadLongFromFile(fp) + arc_offset;
+		if (name_size > MAXPATHLEN)
+			name_size = MAXPATHLEN;
+
+		p = name;
+		for (i = 0; i < name_size; i++) {
+			*p = (char)getc(fp);
+			if (*p == '/')
+				*p = SEP;
+			p++;
+		}
+		*p = 0;	/* Add terminating null byte */
+		header_offset += header_size;
+
+		strncpy(path + length + 1, name, MAXPATHLEN - length - 1);
+
+		t = Py_BuildValue("siiiiiii", path, compress, data_size,
+				  file_size, file_offset, time, date, crc);
+		if (t == NULL)
+			goto error;
+		err = PyDict_SetItemString(files, name, t);
+		Py_DECREF(t);
+		if (err != 0)
+			goto error;
+		count++;
+	}
+	fclose(fp);
+	if (Py_VerboseFlag)
+		PySys_WriteStderr("# zipimport: found %ld names in %s\n",
+			count, archive);
+	return files;
+error:
+	fclose(fp);
+	Py_XDECREF(files);
+	return NULL;
+}
+
+/* Return the zlib.decompress function object, or NULL if zlib couldn't
+   be imported. The function is cached when found, so subsequent calls
+   don't import zlib again. Returns a *borrowed* reference.
+   XXX This makes zlib.decompress immortal. */
+static PyObject *
+get_decompress_func(void)
+{
+	static PyObject *decompress = NULL;
+
+	if (decompress == NULL) {
+		PyObject *zlib;
+		static int importing_zlib = 0;
+
+		if (importing_zlib != 0)
+			/* Someone has a zlib.py[co] in their Zip file;
+			   let's avoid a stack overflow. */
+			return NULL;
+		importing_zlib = 1;
+		zlib = PyImport_ImportModule("zlib");	/* import zlib */
+		importing_zlib = 0;
+		if (zlib != NULL) {
+			decompress = PyObject_GetAttrString(zlib,
+							    "decompress");
+			Py_DECREF(zlib);
+		}
+		else
+			PyErr_Clear();
+		if (Py_VerboseFlag)
+			PySys_WriteStderr("# zipimport: zlib %s\n",
+				zlib != NULL ? "available": "UNAVAILABLE");
+	}
+	return decompress;
+}
+
+/* Given a path to a Zip file and a toc_entry, return the (uncompressed)
+   data as a new reference. */
+static PyObject *
+get_data(char *archive, PyObject *toc_entry)
+{
+	PyObject *raw_data, *data = NULL, *decompress;
+	char *buf;
+	FILE *fp;
+	int err;
+	Py_ssize_t bytes_read = 0;
+	long l;
+	char *datapath;
+	long compress, data_size, file_size, file_offset;
+	long time, date, crc;
+
+	if (!PyArg_ParseTuple(toc_entry, "slllllll", &datapath, &compress,
+			      &data_size, &file_size, &file_offset, &time,
+			      &date, &crc)) {
+		return NULL;
+	}
+
+	fp = fopen(archive, "rb");
+	if (!fp) {
+		PyErr_Format(PyExc_IOError,
+		   "zipimport: can not open file %s", archive);
+		return NULL;
+	}
+
+	/* Check to make sure the local file header is correct */
+	fseek(fp, file_offset, 0);
+	l = PyMarshal_ReadLongFromFile(fp);
+	if (l != 0x04034B50) {
+		/* Bad: Local File Header */
+		PyErr_Format(ZipImportError,
+			     "bad local file header in %s",
+			     archive);
+		fclose(fp);
+		return NULL;
+	}
+	fseek(fp, file_offset + 26, 0);
+	l = 30 + PyMarshal_ReadShortFromFile(fp) +
+	    PyMarshal_ReadShortFromFile(fp);	/* local header size */
+	file_offset += l;	/* Start of file data */
+
+	raw_data = PyString_FromStringAndSize((char *)NULL, compress == 0 ?
+					      data_size : data_size + 1);
+	if (raw_data == NULL) {
+		fclose(fp);
+		return NULL;
+	}
+	buf = PyString_AsString(raw_data);
+
+	err = fseek(fp, file_offset, 0);
+	if (err == 0)
+		bytes_read = fread(buf, 1, data_size, fp);
+	fclose(fp);
+	if (err || bytes_read != data_size) {
+		PyErr_SetString(PyExc_IOError,
+				"zipimport: can't read data");
+		Py_DECREF(raw_data);
+		return NULL;
+	}
+
+	if (compress != 0) {
+		buf[data_size] = 'Z';  /* saw this in zipfile.py */
+		data_size++;
+	}
+	buf[data_size] = '\0';
+
+	if (compress == 0)  /* data is not compressed */
+		return raw_data;
+
+	/* Decompress with zlib */
+	decompress = get_decompress_func();
+	if (decompress == NULL) {
+		PyErr_SetString(ZipImportError,
+				"can't decompress data; "
+				"zlib not available");
+		goto error;
+	}
+	data = PyObject_CallFunction(decompress, "Oi", raw_data, -15);
+error:
+	Py_DECREF(raw_data);
+	return data;
+}
+
+/* Lenient date/time comparison function. The precision of the mtime
+   in the archive is lower than the mtime stored in a .pyc: we
+   must allow a difference of at most one second. */
+static int
+eq_mtime(time_t t1, time_t t2)
+{
+	time_t d = t1 - t2;
+	if (d < 0)
+		d = -d;
+	/* dostime only stores even seconds, so be lenient */
+	return d <= 1;
+}
+
+/* Given the contents of a .py[co] file in a buffer, unmarshal the data
+   and return the code object. Return None if it the magic word doesn't
+   match (we do this instead of raising an exception as we fall back
+   to .py if available and we don't want to mask other errors).
+   Returns a new reference. */
+static PyObject *
+unmarshal_code(char *pathname, PyObject *data, time_t mtime)
+{
+	PyObject *code;
+	char *buf = PyString_AsString(data);
+	Py_ssize_t size = PyString_Size(data);
+
+	if (size <= 9) {
+		PyErr_SetString(ZipImportError,
+				"bad pyc data");
+		return NULL;
+	}
+
+	if (get_long((unsigned char *)buf) != PyImport_GetMagicNumber()) {
+		if (Py_VerboseFlag)
+			PySys_WriteStderr("# %s has bad magic\n",
+					  pathname);
+		Py_INCREF(Py_None);
+		return Py_None;  /* signal caller to try alternative */
+	}
+
+	if (mtime != 0 && !eq_mtime(get_long((unsigned char *)buf + 4),
+				    mtime)) {
+		if (Py_VerboseFlag)
+			PySys_WriteStderr("# %s has bad mtime\n",
+					  pathname);
+		Py_INCREF(Py_None);
+		return Py_None;  /* signal caller to try alternative */
+	}
+
+	code = PyMarshal_ReadObjectFromString(buf + 8, size - 8);
+	if (code == NULL)
+		return NULL;
+	if (!PyCode_Check(code)) {
+		Py_DECREF(code);
+		PyErr_Format(PyExc_TypeError,
+		     "compiled module %.200s is not a code object",
+		     pathname);
+		return NULL;
+	}
+	return code;
+}
+
+/* Replace any occurances of "\r\n?" in the input string with "\n".
+   This converts DOS and Mac line endings to Unix line endings.
+   Also append a trailing "\n" to be compatible with
+   PyParser_SimpleParseFile(). Returns a new reference. */
+static PyObject *
+normalize_line_endings(PyObject *source)
+{
+	char *buf, *q, *p = PyString_AsString(source);
+	PyObject *fixed_source;
+
+	if (!p)
+		return NULL;
+
+	/* one char extra for trailing \n and one for terminating \0 */
+	buf = (char *)PyMem_Malloc(PyString_Size(source) + 2);
+	if (buf == NULL) {
+		PyErr_SetString(PyExc_MemoryError,
+				"zipimport: no memory to allocate "
+				"source buffer");
+		return NULL;
+	}
+	/* replace "\r\n?" by "\n" */
+	for (q = buf; *p != '\0'; p++) {
+		if (*p == '\r') {
+			*q++ = '\n';
+			if (*(p + 1) == '\n')
+				p++;
+		}
+		else
+			*q++ = *p;
+	}
+	*q++ = '\n';  /* add trailing \n */
+	*q = '\0';
+	fixed_source = PyString_FromString(buf);
+	PyMem_Free(buf);
+	return fixed_source;
+}
+
+/* Given a string buffer containing Python source code, compile it
+   return and return a code object as a new reference. */
+static PyObject *
+compile_source(char *pathname, PyObject *source)
+{
+	PyObject *code, *fixed_source;
+
+	fixed_source = normalize_line_endings(source);
+	if (fixed_source == NULL)
+		return NULL;
+
+	code = Py_CompileString(PyString_AsString(fixed_source), pathname,
+				Py_file_input);
+	Py_DECREF(fixed_source);
+	return code;
+}
+
+/* Convert the date/time values found in the Zip archive to a value
+   that's compatible with the time stamp stored in .pyc files. */
+static time_t
+parse_dostime(int dostime, int dosdate)
+{
+	struct tm stm;
+
+	stm.tm_sec   =  (dostime        & 0x1f) * 2;
+	stm.tm_min   =  (dostime >> 5)  & 0x3f;
+	stm.tm_hour  =  (dostime >> 11) & 0x1f;
+	stm.tm_mday  =   dosdate        & 0x1f;
+	stm.tm_mon   = ((dosdate >> 5)  & 0x0f) - 1;
+	stm.tm_year  = ((dosdate >> 9)  & 0x7f) + 80;
+	stm.tm_isdst =   -1; /* wday/yday is ignored */
+
+	return mktime(&stm);
+}
+
+/* Given a path to a .pyc or .pyo file in the archive, return the
+   modifictaion time of the matching .py file, or 0 if no source
+   is available. */
+static time_t
+get_mtime_of_source(ZipImporter *self, char *path)
+{
+	PyObject *toc_entry;
+	time_t mtime = 0;
+	Py_ssize_t lastchar = strlen(path) - 1;
+	char savechar = path[lastchar];
+	path[lastchar] = '\0';  /* strip 'c' or 'o' from *.py[co] */
+	toc_entry = PyDict_GetItemString(self->files, path);
+	if (toc_entry != NULL && PyTuple_Check(toc_entry) &&
+	    PyTuple_Size(toc_entry) == 8) {
+		/* fetch the time stamp of the .py file for comparison
+		   with an embedded pyc time stamp */
+		int time, date;
+		time = PyInt_AsLong(PyTuple_GetItem(toc_entry, 5));
+		date = PyInt_AsLong(PyTuple_GetItem(toc_entry, 6));
+		mtime = parse_dostime(time, date);
+	}
+	path[lastchar] = savechar;
+	return mtime;
+}
+
+/* Return the code object for the module named by 'fullname' from the
+   Zip archive as a new reference. */
+static PyObject *
+get_code_from_data(ZipImporter *self, int ispackage, int isbytecode,
+		   time_t mtime, PyObject *toc_entry)
+{
+	PyObject *data, *code;
+	char *modpath;
+	char *archive = PyString_AsString(self->archive);
+
+	if (archive == NULL)
+		return NULL;
+
+	data = get_data(archive, toc_entry);
+	if (data == NULL)
+		return NULL;
+
+	modpath = PyString_AsString(PyTuple_GetItem(toc_entry, 0));
+
+	if (isbytecode) {
+		code = unmarshal_code(modpath, data, mtime);
+	}
+	else {
+		code = compile_source(modpath, data);
+	}
+	Py_DECREF(data);
+	return code;
+}
+
+/* Get the code object assoiciated with the module specified by
+   'fullname'. */
+static PyObject *
+get_module_code(ZipImporter *self, char *fullname,
+		int *p_ispackage, char **p_modpath)
+{
+	PyObject *toc_entry;
+	char *subname, path[MAXPATHLEN + 1];
+	int len;
+	struct st_zip_searchorder *zso;
+
+	subname = get_subname(fullname);
+
+	len = make_filename(PyString_AsString(self->prefix), subname, path);
+	if (len < 0)
+		return NULL;
+
+	for (zso = zip_searchorder; *zso->suffix; zso++) {
+		PyObject *code = NULL;
+
+		strcpy(path + len, zso->suffix);
+		if (Py_VerboseFlag > 1)
+			PySys_WriteStderr("# trying %s%c%s\n",
+					  PyString_AsString(self->archive),
+					  SEP, path);
+		toc_entry = PyDict_GetItemString(self->files, path);
+		if (toc_entry != NULL) {
+			time_t mtime = 0;
+			int ispackage = zso->type & IS_PACKAGE;
+			int isbytecode = zso->type & IS_BYTECODE;
+
+			if (isbytecode)
+				mtime = get_mtime_of_source(self, path);
+			if (p_ispackage != NULL)
+				*p_ispackage = ispackage;
+			code = get_code_from_data(self, ispackage,
+						  isbytecode, mtime,
+						  toc_entry);
+			if (code == Py_None) {
+				/* bad magic number or non-matching mtime
+				   in byte code, try next */
+				Py_DECREF(code);
+				continue;
+			}
+			if (code != NULL && p_modpath != NULL)
+				*p_modpath = PyString_AsString(
+					PyTuple_GetItem(toc_entry, 0));
+			return code;
+		}
+	}
+	PyErr_Format(ZipImportError, "can't find module '%.200s'", fullname);
+	return NULL;
+}
+
+
+/* Module init */
+
+PyDoc_STRVAR(zipimport_doc,
+"zipimport provides support for importing Python modules from Zip archives.\n\
+\n\
+This module exports three objects:\n\
+- zipimporter: a class; its constructor takes a path to a Zip archive.\n\
+- ZipImportError: exception raised by zipimporter objects. It's a\n\
+  subclass of ImportError, so it can be caught as ImportError, too.\n\
+- _zip_directory_cache: a dict, mapping archive paths to zip directory\n\
+  info dicts, as used in zipimporter._files.\n\
+\n\
+It is usually not needed to use the zipimport module explicitly; it is\n\
+used by the builtin import mechanism for sys.path items that are paths\n\
+to Zip archives.");
+
+PyMODINIT_FUNC
+initzipimport(void)
+{
+	PyObject *mod;
+
+	if (PyType_Ready(&ZipImporter_Type) < 0)
+		return;
+
+	/* Correct directory separator */
+	zip_searchorder[0].suffix[0] = SEP;
+	zip_searchorder[1].suffix[0] = SEP;
+	zip_searchorder[2].suffix[0] = SEP;
+	if (Py_OptimizeFlag) {
+		/* Reverse *.pyc and *.pyo */
+		struct st_zip_searchorder tmp;
+		tmp = zip_searchorder[0];
+		zip_searchorder[0] = zip_searchorder[1];
+		zip_searchorder[1] = tmp;
+		tmp = zip_searchorder[3];
+		zip_searchorder[3] = zip_searchorder[4];
+		zip_searchorder[4] = tmp;
+	}
+
+	mod = Py_InitModule4("zipimport", NULL, zipimport_doc,
+			     NULL, PYTHON_API_VERSION);
+	if (mod == NULL)
+		return;
+
+	ZipImportError = PyErr_NewException("zipimport.ZipImportError",
+					    PyExc_ImportError, NULL);
+	if (ZipImportError == NULL)
+		return;
+
+	Py_INCREF(ZipImportError);
+	if (PyModule_AddObject(mod, "ZipImportError",
+			       ZipImportError) < 0)
+		return;
+
+	Py_INCREF(&ZipImporter_Type);
+	if (PyModule_AddObject(mod, "zipimporter",
+			       (PyObject *)&ZipImporter_Type) < 0)
+		return;
+
+	zip_directory_cache = PyDict_New();
+	if (zip_directory_cache == NULL)
+		return;
+	Py_INCREF(zip_directory_cache);
+	if (PyModule_AddObject(mod, "_zip_directory_cache",
+			       zip_directory_cache) < 0)
+		return;
+}

Added: vendor/Python/current/Modules/zlib/ChangeLog
===================================================================
--- vendor/Python/current/Modules/zlib/ChangeLog	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/zlib/ChangeLog	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,855 @@
+
+                ChangeLog file for zlib
+
+Changes in 1.2.3 (18 July 2005)
+- Apply security vulnerability fixes to contrib/infback9 as well
+- Clean up some text files (carriage returns, trailing space)
+- Update testzlib, vstudio, masmx64, and masmx86 in contrib [Vollant]
+
+Changes in 1.2.2.4 (11 July 2005)
+- Add inflatePrime() function for starting inflation at bit boundary
+- Avoid some Visual C warnings in deflate.c
+- Avoid more silly Visual C warnings in inflate.c and inftrees.c for 64-bit
+  compile
+- Fix some spelling errors in comments [Betts]
+- Correct inflateInit2() error return documentation in zlib.h
+- Added zran.c example of compressed data random access to examples
+  directory, shows use of inflatePrime()
+- Fix cast for assignments to strm->state in inflate.c and infback.c
+- Fix zlibCompileFlags() in zutil.c to use 1L for long shifts [Oberhumer]
+- Move declarations of gf2 functions to right place in crc32.c [Oberhumer]
+- Add cast in trees.c t avoid a warning [Oberhumer]
+- Avoid some warnings in fitblk.c, gun.c, gzjoin.c in examples [Oberhumer]
+- Update make_vms.com [Zinser]
+- Initialize state->write in inflateReset() since copied in inflate_fast()
+- Be more strict on incomplete code sets in inflate_table() and increase
+  ENOUGH and MAXD -- this repairs a possible security vulnerability for
+  invalid inflate input.  Thanks to Tavis Ormandy and Markus Oberhumer for
+  discovering the vulnerability and providing test cases.
+- Add ia64 support to configure for HP-UX [Smith]
+- Add error return to gzread() for format or i/o error [Levin]
+- Use malloc.h for OS/2 [Necasek]
+
+Changes in 1.2.2.3 (27 May 2005)
+- Replace 1U constants in inflate.c and inftrees.c for 64-bit compile
+- Typecast fread() return values in gzio.c [Vollant]
+- Remove trailing space in minigzip.c outmode (VC++ can't deal with it)
+- Fix crc check bug in gzread() after gzungetc() [Heiner]
+- Add the deflateTune() function to adjust internal compression parameters
+- Add a fast gzip decompressor, gun.c, to examples (use of inflateBack)
+- Remove an incorrect assertion in examples/zpipe.c
+- Add C++ wrapper in infback9.h [Donais]
+- Fix bug in inflateCopy() when decoding fixed codes
+- Note in zlib.h how much deflateSetDictionary() actually uses
+- Remove USE_DICT_HEAD in deflate.c (would mess up inflate if used)
+- Add _WIN32_WCE to define WIN32 in zconf.in.h [Spencer]
+- Don't include stderr.h or errno.h for _WIN32_WCE in zutil.h [Spencer]
+- Add gzdirect() function to indicate transparent reads
+- Update contrib/minizip [Vollant]
+- Fix compilation of deflate.c when both ASMV and FASTEST [Oberhumer]
+- Add casts in crc32.c to avoid warnings [Oberhumer]
+- Add contrib/masmx64 [Vollant]
+- Update contrib/asm586, asm686, masmx86, testzlib, vstudio [Vollant]
+
+Changes in 1.2.2.2 (30 December 2004)
+- Replace structure assignments in deflate.c and inflate.c with zmemcpy to
+  avoid implicit memcpy calls (portability for no-library compilation)
+- Increase sprintf() buffer size in gzdopen() to allow for large numbers
+- Add INFLATE_STRICT to check distances against zlib header
+- Improve WinCE errno handling and comments [Chang]
+- Remove comment about no gzip header processing in FAQ
+- Add Z_FIXED strategy option to deflateInit2() to force fixed trees
+- Add updated make_vms.com [Coghlan], update README
+- Create a new "examples" directory, move gzappend.c there, add zpipe.c,
+  fitblk.c, gzlog.[ch], gzjoin.c, and zlib_how.html.
+- Add FAQ entry and comments in deflate.c on uninitialized memory access
+- Add Solaris 9 make options in configure [Gilbert]
+- Allow strerror() usage in gzio.c for STDC
+- Fix DecompressBuf in contrib/delphi/ZLib.pas [ManChesTer]
+- Update contrib/masmx86/inffas32.asm and gvmat32.asm [Vollant]
+- Use z_off_t for adler32_combine() and crc32_combine() lengths
+- Make adler32() much faster for small len
+- Use OS_CODE in deflate() default gzip header
+
+Changes in 1.2.2.1 (31 October 2004)
+- Allow inflateSetDictionary() call for raw inflate
+- Fix inflate header crc check bug for file names and comments
+- Add deflateSetHeader() and gz_header structure for custom gzip headers
+- Add inflateGetheader() to retrieve gzip headers
+- Add crc32_combine() and adler32_combine() functions
+- Add alloc_func, free_func, in_func, out_func to Z_PREFIX list
+- Use zstreamp consistently in zlib.h (inflate_back functions)
+- Remove GUNZIP condition from definition of inflate_mode in inflate.h
+  and in contrib/inflate86/inffast.S [Truta, Anderson]
+- Add support for AMD64 in contrib/inflate86/inffas86.c [Anderson]
+- Update projects/README.projects and projects/visualc6 [Truta]
+- Update win32/DLL_FAQ.txt [Truta]
+- Avoid warning under NO_GZCOMPRESS in gzio.c; fix typo [Truta]
+- Deprecate Z_ASCII; use Z_TEXT instead [Truta]
+- Use a new algorithm for setting strm->data_type in trees.c [Truta]
+- Do not define an exit() prototype in zutil.c unless DEBUG defined
+- Remove prototype of exit() from zutil.c, example.c, minigzip.c [Truta]
+- Add comment in zlib.h for Z_NO_FLUSH parameter to deflate()
+- Fix Darwin build version identification [Peterson]
+
+Changes in 1.2.2 (3 October 2004)
+- Update zlib.h comments on gzip in-memory processing
+- Set adler to 1 in inflateReset() to support Java test suite [Walles]
+- Add contrib/dotzlib [Ravn]
+- Update win32/DLL_FAQ.txt [Truta]
+- Update contrib/minizip [Vollant]
+- Move contrib/visual-basic.txt to old/ [Truta]
+- Fix assembler builds in projects/visualc6/ [Truta]
+
+Changes in 1.2.1.2 (9 September 2004)
+- Update INDEX file
+- Fix trees.c to update strm->data_type (no one ever noticed!)
+- Fix bug in error case in inflate.c, infback.c, and infback9.c [Brown]
+- Add "volatile" to crc table flag declaration (for DYNAMIC_CRC_TABLE)
+- Add limited multitasking protection to DYNAMIC_CRC_TABLE
+- Add NO_vsnprintf for VMS in zutil.h [Mozilla]
+- Don't declare strerror() under VMS [Mozilla]
+- Add comment to DYNAMIC_CRC_TABLE to use get_crc_table() to initialize
+- Update contrib/ada [Anisimkov]
+- Update contrib/minizip [Vollant]
+- Fix configure to not hardcode directories for Darwin [Peterson]
+- Fix gzio.c to not return error on empty files [Brown]
+- Fix indentation; update version in contrib/delphi/ZLib.pas and
+  contrib/pascal/zlibpas.pas [Truta]
+- Update mkasm.bat in contrib/masmx86 [Truta]
+- Update contrib/untgz [Truta]
+- Add projects/README.projects [Truta]
+- Add project for MS Visual C++ 6.0 in projects/visualc6 [Cadieux, Truta]
+- Update win32/DLL_FAQ.txt [Truta]
+- Update list of Z_PREFIX symbols in zconf.h [Randers-Pehrson, Truta]
+- Remove an unnecessary assignment to curr in inftrees.c [Truta]
+- Add OS/2 to exe builds in configure [Poltorak]
+- Remove err dummy parameter in zlib.h [Kientzle]
+
+Changes in 1.2.1.1 (9 January 2004)
+- Update email address in README
+- Several FAQ updates
+- Fix a big fat bug in inftrees.c that prevented decoding valid
+  dynamic blocks with only literals and no distance codes --
+  Thanks to "Hot Emu" for the bug report and sample file
+- Add a note to puff.c on no distance codes case.
+
+Changes in 1.2.1 (17 November 2003)
+- Remove a tab in contrib/gzappend/gzappend.c
+- Update some interfaces in contrib for new zlib functions
+- Update zlib version number in some contrib entries
+- Add Windows CE definition for ptrdiff_t in zutil.h [Mai, Truta]
+- Support shared libraries on Hurd and KFreeBSD [Brown]
+- Fix error in NO_DIVIDE option of adler32.c
+
+Changes in 1.2.0.8 (4 November 2003)
+- Update version in contrib/delphi/ZLib.pas and contrib/pascal/zlibpas.pas
+- Add experimental NO_DIVIDE #define in adler32.c
+    - Possibly faster on some processors (let me know if it is)
+- Correct Z_BLOCK to not return on first inflate call if no wrap
+- Fix strm->data_type on inflate() return to correctly indicate EOB
+- Add deflatePrime() function for appending in the middle of a byte
+- Add contrib/gzappend for an example of appending to a stream
+- Update win32/DLL_FAQ.txt [Truta]
+- Delete Turbo C comment in README [Truta]
+- Improve some indentation in zconf.h [Truta]
+- Fix infinite loop on bad input in configure script [Church]
+- Fix gzeof() for concatenated gzip files [Johnson]
+- Add example to contrib/visual-basic.txt [Michael B.]
+- Add -p to mkdir's in Makefile.in [vda]
+- Fix configure to properly detect presence or lack of printf functions
+- Add AS400 support [Monnerat]
+- Add a little Cygwin support [Wilson]
+
+Changes in 1.2.0.7 (21 September 2003)
+- Correct some debug formats in contrib/infback9
+- Cast a type in a debug statement in trees.c
+- Change search and replace delimiter in configure from % to # [Beebe]
+- Update contrib/untgz to 0.2 with various fixes [Truta]
+- Add build support for Amiga [Nikl]
+- Remove some directories in old that have been updated to 1.2
+- Add dylib building for Mac OS X in configure and Makefile.in
+- Remove old distribution stuff from Makefile
+- Update README to point to DLL_FAQ.txt, and add comment on Mac OS X
+- Update links in README
+
+Changes in 1.2.0.6 (13 September 2003)
+- Minor FAQ updates
+- Update contrib/minizip to 1.00 [Vollant]
+- Remove test of gz functions in example.c when GZ_COMPRESS defined [Truta]
+- Update POSTINC comment for 68060 [Nikl]
+- Add contrib/infback9 with deflate64 decoding (unsupported)
+- For MVS define NO_vsnprintf and undefine FAR [van Burik]
+- Add pragma for fdopen on MVS [van Burik]
+
+Changes in 1.2.0.5 (8 September 2003)
+- Add OF to inflateBackEnd() declaration in zlib.h
+- Remember start when using gzdopen in the middle of a file
+- Use internal off_t counters in gz* functions to properly handle seeks
+- Perform more rigorous check for distance-too-far in inffast.c
+- Add Z_BLOCK flush option to return from inflate at block boundary
+- Set strm->data_type on return from inflate
+    - Indicate bits unused, if at block boundary, and if in last block
+- Replace size_t with ptrdiff_t in crc32.c, and check for correct size
+- Add condition so old NO_DEFLATE define still works for compatibility
+- FAQ update regarding the Windows DLL [Truta]
+- INDEX update: add qnx entry, remove aix entry [Truta]
+- Install zlib.3 into mandir [Wilson]
+- Move contrib/zlib_dll_FAQ.txt to win32/DLL_FAQ.txt; update [Truta]
+- Adapt the zlib interface to the new DLL convention guidelines [Truta]
+- Introduce ZLIB_WINAPI macro to allow the export of functions using
+  the WINAPI calling convention, for Visual Basic [Vollant, Truta]
+- Update msdos and win32 scripts and makefiles [Truta]
+- Export symbols by name, not by ordinal, in win32/zlib.def [Truta]
+- Add contrib/ada [Anisimkov]
+- Move asm files from contrib/vstudio/vc70_32 to contrib/asm386 [Truta]
+- Rename contrib/asm386 to contrib/masmx86 [Truta, Vollant]
+- Add contrib/masm686 [Truta]
+- Fix offsets in contrib/inflate86 and contrib/masmx86/inffas32.asm
+  [Truta, Vollant]
+- Update contrib/delphi; rename to contrib/pascal; add example [Truta]
+- Remove contrib/delphi2; add a new contrib/delphi [Truta]
+- Avoid inclusion of the nonstandard <memory.h> in contrib/iostream,
+  and fix some method prototypes [Truta]
+- Fix the ZCR_SEED2 constant to avoid warnings in contrib/minizip
+  [Truta]
+- Avoid the use of backslash (\) in contrib/minizip [Vollant]
+- Fix file time handling in contrib/untgz; update makefiles [Truta]
+- Update contrib/vstudio/vc70_32 to comply with the new DLL guidelines
+  [Vollant]
+- Remove contrib/vstudio/vc15_16 [Vollant]
+- Rename contrib/vstudio/vc70_32 to contrib/vstudio/vc7 [Truta]
+- Update README.contrib [Truta]
+- Invert the assignment order of match_head and s->prev[...] in
+  INSERT_STRING [Truta]
+- Compare TOO_FAR with 32767 instead of 32768, to avoid 16-bit warnings
+  [Truta]
+- Compare function pointers with 0, not with NULL or Z_NULL [Truta]
+- Fix prototype of syncsearch in inflate.c [Truta]
+- Introduce ASMINF macro to be enabled when using an ASM implementation
+  of inflate_fast [Truta]
+- Change NO_DEFLATE to NO_GZCOMPRESS [Truta]
+- Modify test_gzio in example.c to take a single file name as a
+  parameter [Truta]
+- Exit the example.c program if gzopen fails [Truta]
+- Add type casts around strlen in example.c [Truta]
+- Remove casting to sizeof in minigzip.c; give a proper type
+  to the variable compared with SUFFIX_LEN [Truta]
+- Update definitions of STDC and STDC99 in zconf.h [Truta]
+- Synchronize zconf.h with the new Windows DLL interface [Truta]
+- Use SYS16BIT instead of __32BIT__ to distinguish between
+  16- and 32-bit platforms [Truta]
+- Use far memory allocators in small 16-bit memory models for
+  Turbo C [Truta]
+- Add info about the use of ASMV, ASMINF and ZLIB_WINAPI in
+  zlibCompileFlags [Truta]
+- Cygwin has vsnprintf [Wilson]
+- In Windows16, OS_CODE is 0, as in MSDOS [Truta]
+- In Cygwin, OS_CODE is 3 (Unix), not 11 (Windows32) [Wilson]
+
+Changes in 1.2.0.4 (10 August 2003)
+- Minor FAQ updates
+- Be more strict when checking inflateInit2's windowBits parameter
+- Change NO_GUNZIP compile option to NO_GZIP to cover deflate as well
+- Add gzip wrapper option to deflateInit2 using windowBits
+- Add updated QNX rule in configure and qnx directory [Bonnefoy]
+- Make inflate distance-too-far checks more rigorous
+- Clean up FAR usage in inflate
+- Add casting to sizeof() in gzio.c and minigzip.c
+
+Changes in 1.2.0.3 (19 July 2003)
+- Fix silly error in gzungetc() implementation [Vollant]
+- Update contrib/minizip and contrib/vstudio [Vollant]
+- Fix printf format in example.c
+- Correct cdecl support in zconf.in.h [Anisimkov]
+- Minor FAQ updates
+
+Changes in 1.2.0.2 (13 July 2003)
+- Add ZLIB_VERNUM in zlib.h for numerical preprocessor comparisons
+- Attempt to avoid warnings in crc32.c for pointer-int conversion
+- Add AIX to configure, remove aix directory [Bakker]
+- Add some casts to minigzip.c
+- Improve checking after insecure sprintf() or vsprintf() calls
+- Remove #elif's from crc32.c
+- Change leave label to inf_leave in inflate.c and infback.c to avoid
+  library conflicts
+- Remove inflate gzip decoding by default--only enable gzip decoding by
+  special request for stricter backward compatibility
+- Add zlibCompileFlags() function to return compilation information
+- More typecasting in deflate.c to avoid warnings
+- Remove leading underscore from _Capital #defines [Truta]
+- Fix configure to link shared library when testing
+- Add some Windows CE target adjustments [Mai]
+- Remove #define ZLIB_DLL in zconf.h [Vollant]
+- Add zlib.3 [Rodgers]
+- Update RFC URL in deflate.c and algorithm.txt [Mai]
+- Add zlib_dll_FAQ.txt to contrib [Truta]
+- Add UL to some constants [Truta]
+- Update minizip and vstudio [Vollant]
+- Remove vestigial NEED_DUMMY_RETURN from zconf.in.h
+- Expand use of NO_DUMMY_DECL to avoid all dummy structures
+- Added iostream3 to contrib [Schwardt]
+- Replace rewind() with fseek() for WinCE [Truta]
+- Improve setting of zlib format compression level flags
+    - Report 0 for huffman and rle strategies and for level == 0 or 1
+    - Report 2 only for level == 6
+- Only deal with 64K limit when necessary at compile time [Truta]
+- Allow TOO_FAR check to be turned off at compile time [Truta]
+- Add gzclearerr() function [Souza]
+- Add gzungetc() function
+
+Changes in 1.2.0.1 (17 March 2003)
+- Add Z_RLE strategy for run-length encoding [Truta]
+    - When Z_RLE requested, restrict matches to distance one
+    - Update zlib.h, minigzip.c, gzopen(), gzdopen() for Z_RLE
+- Correct FASTEST compilation to allow level == 0
+- Clean up what gets compiled for FASTEST
+- Incorporate changes to zconf.in.h [Vollant]
+    - Refine detection of Turbo C need for dummy returns
+    - Refine ZLIB_DLL compilation
+    - Include additional header file on VMS for off_t typedef
+- Try to use _vsnprintf where it supplants vsprintf [Vollant]
+- Add some casts in inffast.c
+- Enchance comments in zlib.h on what happens if gzprintf() tries to
+  write more than 4095 bytes before compression
+- Remove unused state from inflateBackEnd()
+- Remove exit(0) from minigzip.c, example.c
+- Get rid of all those darn tabs
+- Add "check" target to Makefile.in that does the same thing as "test"
+- Add "mostlyclean" and "maintainer-clean" targets to Makefile.in
+- Update contrib/inflate86 [Anderson]
+- Update contrib/testzlib, contrib/vstudio, contrib/minizip [Vollant]
+- Add msdos and win32 directories with makefiles [Truta]
+- More additions and improvements to the FAQ
+
+Changes in 1.2.0 (9 March 2003)
+- New and improved inflate code
+    - About 20% faster
+    - Does not allocate 32K window unless and until needed
+    - Automatically detects and decompresses gzip streams
+    - Raw inflate no longer needs an extra dummy byte at end
+    - Added inflateBack functions using a callback interface--even faster
+      than inflate, useful for file utilities (gzip, zip)
+    - Added inflateCopy() function to record state for random access on
+      externally generated deflate streams (e.g. in gzip files)
+    - More readable code (I hope)
+- New and improved crc32()
+    - About 50% faster, thanks to suggestions from Rodney Brown
+- Add deflateBound() and compressBound() functions
+- Fix memory leak in deflateInit2()
+- Permit setting dictionary for raw deflate (for parallel deflate)
+- Fix const declaration for gzwrite()
+- Check for some malloc() failures in gzio.c
+- Fix bug in gzopen() on single-byte file 0x1f
+- Fix bug in gzread() on concatenated file with 0x1f at end of buffer
+  and next buffer doesn't start with 0x8b
+- Fix uncompress() to return Z_DATA_ERROR on truncated input
+- Free memory at end of example.c
+- Remove MAX #define in trees.c (conflicted with some libraries)
+- Fix static const's in deflate.c, gzio.c, and zutil.[ch]
+- Declare malloc() and free() in gzio.c if STDC not defined
+- Use malloc() instead of calloc() in zutil.c if int big enough
+- Define STDC for AIX
+- Add aix/ with approach for compiling shared library on AIX
+- Add HP-UX support for shared libraries in configure
+- Add OpenUNIX support for shared libraries in configure
+- Use $cc instead of gcc to build shared library
+- Make prefix directory if needed when installing
+- Correct Macintosh avoidance of typedef Byte in zconf.h
+- Correct Turbo C memory allocation when under Linux
+- Use libz.a instead of -lz in Makefile (assure use of compiled library)
+- Update configure to check for snprintf or vsnprintf functions and their
+  return value, warn during make if using an insecure function
+- Fix configure problem with compile-time knowledge of HAVE_UNISTD_H that
+  is lost when library is used--resolution is to build new zconf.h
+- Documentation improvements (in zlib.h):
+    - Document raw deflate and inflate
+    - Update RFCs URL
+    - Point out that zlib and gzip formats are different
+    - Note that Z_BUF_ERROR is not fatal
+    - Document string limit for gzprintf() and possible buffer overflow
+    - Note requirement on avail_out when flushing
+    - Note permitted values of flush parameter of inflate()
+- Add some FAQs (and even answers) to the FAQ
+- Add contrib/inflate86/ for x86 faster inflate
+- Add contrib/blast/ for PKWare Data Compression Library decompression
+- Add contrib/puff/ simple inflate for deflate format description
+
+Changes in 1.1.4 (11 March 2002)
+- ZFREE was repeated on same allocation on some error conditions.
+  This creates a security problem described in
+  http://www.zlib.org/advisory-2002-03-11.txt
+- Returned incorrect error (Z_MEM_ERROR) on some invalid data
+- Avoid accesses before window for invalid distances with inflate window
+  less than 32K.
+- force windowBits > 8 to avoid a bug in the encoder for a window size
+  of 256 bytes. (A complete fix will be available in 1.1.5).
+
+Changes in 1.1.3 (9 July 1998)
+- fix "an inflate input buffer bug that shows up on rare but persistent
+  occasions" (Mark)
+- fix gzread and gztell for concatenated .gz files (Didier Le Botlan)
+- fix gzseek(..., SEEK_SET) in write mode
+- fix crc check after a gzeek (Frank Faubert)
+- fix miniunzip when the last entry in a zip file is itself a zip file
+  (J Lillge)
+- add contrib/asm586 and contrib/asm686 (Brian Raiter)
+  See http://www.muppetlabs.com/~breadbox/software/assembly.html
+- add support for Delphi 3 in contrib/delphi (Bob Dellaca)
+- add support for C++Builder 3 and Delphi 3 in contrib/delphi2 (Davide Moretti)
+- do not exit prematurely in untgz if 0 at start of block (Magnus Holmgren)
+- use macro EXTERN instead of extern to support DLL for BeOS (Sander Stoks)
+- added a FAQ file
+
+- Support gzdopen on Mac with Metrowerks (Jason Linhart)
+- Do not redefine Byte on Mac (Brad Pettit & Jason Linhart)
+- define SEEK_END too if SEEK_SET is not defined (Albert Chin-A-Young)
+- avoid some warnings with Borland C (Tom Tanner)
+- fix a problem in contrib/minizip/zip.c for 16-bit MSDOS (Gilles Vollant)
+- emulate utime() for WIN32 in contrib/untgz  (Gilles Vollant)
+- allow several arguments to configure (Tim Mooney, Frodo Looijaard)
+- use libdir and includedir in Makefile.in (Tim Mooney)
+- support shared libraries on OSF1 V4 (Tim Mooney)
+- remove so_locations in "make clean"  (Tim Mooney)
+- fix maketree.c compilation error (Glenn, Mark)
+- Python interface to zlib now in Python 1.5 (Jeremy Hylton)
+- new Makefile.riscos (Rich Walker)
+- initialize static descriptors in trees.c for embedded targets (Nick Smith)
+- use "foo-gz" in example.c for RISCOS and VMS (Nick Smith)
+- add the OS/2 files in Makefile.in too (Andrew Zabolotny)
+- fix fdopen and halloc macros for Microsoft C 6.0 (Tom Lane)
+- fix maketree.c to allow clean compilation of inffixed.h (Mark)
+- fix parameter check in deflateCopy (Gunther Nikl)
+- cleanup trees.c, use compressed_len only in debug mode (Christian Spieler)
+- Many portability patches by Christian Spieler:
+  . zutil.c, zutil.h: added "const" for zmem*
+  . Make_vms.com: fixed some typos
+  . Make_vms.com: msdos/Makefile.*: removed zutil.h from some dependency lists
+  . msdos/Makefile.msc: remove "default rtl link library" info from obj files
+  . msdos/Makefile.*: use model-dependent name for the built zlib library
+  . msdos/Makefile.emx, nt/Makefile.emx, nt/Makefile.gcc:
+     new makefiles, for emx (DOS/OS2), emx&rsxnt and mingw32 (Windows 9x / NT)
+- use define instead of typedef for Bytef also for MSC small/medium (Tom Lane)
+- replace __far with _far for better portability (Christian Spieler, Tom Lane)
+- fix test for errno.h in configure (Tim Newsham)
+
+Changes in 1.1.2 (19 March 98)
+- added contrib/minzip, mini zip and unzip based on zlib (Gilles Vollant)
+  See http://www.winimage.com/zLibDll/unzip.html
+- preinitialize the inflate tables for fixed codes, to make the code
+  completely thread safe (Mark)
+- some simplifications and slight speed-up to the inflate code (Mark)
+- fix gzeof on non-compressed files (Allan Schrum)
+- add -std1 option in configure for OSF1 to fix gzprintf (Martin Mokrejs)
+- use default value of 4K for Z_BUFSIZE for 16-bit MSDOS (Tim Wegner + Glenn)
+- added os2/Makefile.def and os2/zlib.def (Andrew Zabolotny)
+- add shared lib support for UNIX_SV4.2MP (MATSUURA Takanori)
+- do not wrap extern "C" around system includes (Tom Lane)
+- mention zlib binding for TCL in README (Andreas Kupries)
+- added amiga/Makefile.pup for Amiga powerUP SAS/C PPC (Andreas Kleinert)
+- allow "make install prefix=..." even after configure (Glenn Randers-Pehrson)
+- allow "configure --prefix $HOME" (Tim Mooney)
+- remove warnings in example.c and gzio.c (Glenn Randers-Pehrson)
+- move Makefile.sas to amiga/Makefile.sas
+
+Changes in 1.1.1 (27 Feb 98)
+- fix macros _tr_tally_* in deflate.h for debug mode  (Glenn Randers-Pehrson)
+- remove block truncation heuristic which had very marginal effect for zlib
+  (smaller lit_bufsize than in gzip 1.2.4) and degraded a little the
+  compression ratio on some files. This also allows inlining _tr_tally for
+  matches in deflate_slow.
+- added msdos/Makefile.w32 for WIN32 Microsoft Visual C++ (Bob Frazier)
+
+Changes in 1.1.0 (24 Feb 98)
+- do not return STREAM_END prematurely in inflate (John Bowler)
+- revert to the zlib 1.0.8 inflate to avoid the gcc 2.8.0 bug (Jeremy Buhler)
+- compile with -DFASTEST to get compression code optimized for speed only
+- in minigzip, try mmap'ing the input file first (Miguel Albrecht)
+- increase size of I/O buffers in minigzip.c and gzio.c (not a big gain
+  on Sun but significant on HP)
+
+- add a pointer to experimental unzip library in README (Gilles Vollant)
+- initialize variable gcc in configure (Chris Herborth)
+
+Changes in 1.0.9 (17 Feb 1998)
+- added gzputs and gzgets functions
+- do not clear eof flag in gzseek (Mark Diekhans)
+- fix gzseek for files in transparent mode (Mark Diekhans)
+- do not assume that vsprintf returns the number of bytes written (Jens Krinke)
+- replace EXPORT with ZEXPORT to avoid conflict with other programs
+- added compress2 in zconf.h, zlib.def, zlib.dnt
+- new asm code from Gilles Vollant in contrib/asm386
+- simplify the inflate code (Mark):
+ . Replace ZALLOC's in huft_build() with single ZALLOC in inflate_blocks_new()
+ . ZALLOC the length list in inflate_trees_fixed() instead of using stack
+ . ZALLOC the value area for huft_build() instead of using stack
+ . Simplify Z_FINISH check in inflate()
+
+- Avoid gcc 2.8.0 comparison bug a little differently than zlib 1.0.8
+- in inftrees.c, avoid cc -O bug on HP (Farshid Elahi)
+- in zconf.h move the ZLIB_DLL stuff earlier to avoid problems with
+  the declaration of FAR (Gilles VOllant)
+- install libz.so* with mode 755 (executable) instead of 644 (Marc Lehmann)
+- read_buf buf parameter of type Bytef* instead of charf*
+- zmemcpy parameters are of type Bytef*, not charf* (Joseph Strout)
+- do not redeclare unlink in minigzip.c for WIN32 (John Bowler)
+- fix check for presence of directories in "make install" (Ian Willis)
+
+Changes in 1.0.8 (27 Jan 1998)
+- fixed offsets in contrib/asm386/gvmat32.asm (Gilles Vollant)
+- fix gzgetc and gzputc for big endian systems (Markus Oberhumer)
+- added compress2() to allow setting the compression level
+- include sys/types.h to get off_t on some systems (Marc Lehmann & QingLong)
+- use constant arrays for the static trees in trees.c instead of computing
+  them at run time (thanks to Ken Raeburn for this suggestion). To create
+  trees.h, compile with GEN_TREES_H and run "make test".
+- check return code of example in "make test" and display result
+- pass minigzip command line options to file_compress
+- simplifying code of inflateSync to avoid gcc 2.8 bug
+
+- support CC="gcc -Wall" in configure -s (QingLong)
+- avoid a flush caused by ftell in gzopen for write mode (Ken Raeburn)
+- fix test for shared library support to avoid compiler warnings
+- zlib.lib -> zlib.dll in msdos/zlib.rc (Gilles Vollant)
+- check for TARGET_OS_MAC in addition to MACOS (Brad Pettit)
+- do not use fdopen for Metrowerks on Mac (Brad Pettit))
+- add checks for gzputc and gzputc in example.c
+- avoid warnings in gzio.c and deflate.c (Andreas Kleinert)
+- use const for the CRC table (Ken Raeburn)
+- fixed "make uninstall" for shared libraries
+- use Tracev instead of Trace in infblock.c
+- in example.c use correct compressed length for test_sync
+- suppress +vnocompatwarnings in configure for HPUX (not always supported)
+
+Changes in 1.0.7 (20 Jan 1998)
+- fix gzseek which was broken in write mode
+- return error for gzseek to negative absolute position
+- fix configure for Linux (Chun-Chung Chen)
+- increase stack space for MSC (Tim Wegner)
+- get_crc_table and inflateSyncPoint are EXPORTed (Gilles Vollant)
+- define EXPORTVA for gzprintf (Gilles Vollant)
+- added man page zlib.3 (Rick Rodgers)
+- for contrib/untgz, fix makedir() and improve Makefile
+
+- check gzseek in write mode in example.c
+- allocate extra buffer for seeks only if gzseek is actually called
+- avoid signed/unsigned comparisons (Tim Wegner, Gilles Vollant)
+- add inflateSyncPoint in zconf.h
+- fix list of exported functions in nt/zlib.dnt and mdsos/zlib.def
+
+Changes in 1.0.6 (19 Jan 1998)
+- add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and
+  gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code)
+- Fix a deflate bug occurring only with compression level 0 (thanks to
+  Andy Buckler for finding this one).
+- In minigzip, pass transparently also the first byte for .Z files.
+- return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress()
+- check Z_FINISH in inflate (thanks to Marc Schluper)
+- Implement deflateCopy (thanks to Adam Costello)
+- make static libraries by default in configure, add --shared option.
+- move MSDOS or Windows specific files to directory msdos
+- suppress the notion of partial flush to simplify the interface
+  (but the symbol Z_PARTIAL_FLUSH is kept for compatibility with 1.0.4)
+- suppress history buffer provided by application to simplify the interface
+  (this feature was not implemented anyway in 1.0.4)
+- next_in and avail_in must be initialized before calling inflateInit or
+  inflateInit2
+- add EXPORT in all exported functions (for Windows DLL)
+- added Makefile.nt (thanks to Stephen Williams)
+- added the unsupported "contrib" directory:
+   contrib/asm386/ by Gilles Vollant <info at winimage.com>
+        386 asm code replacing longest_match().
+   contrib/iostream/ by Kevin Ruland <kevin at rodin.wustl.edu>
+        A C++ I/O streams interface to the zlib gz* functions
+   contrib/iostream2/  by Tyge Løvset <Tyge.Lovset at cmr.no>
+        Another C++ I/O streams interface
+   contrib/untgz/  by "Pedro A. Aranda Guti\irrez" <paag at tid.es>
+        A very simple tar.gz file extractor using zlib
+   contrib/visual-basic.txt by Carlos Rios <c_rios at sonda.cl>
+        How to use compress(), uncompress() and the gz* functions from VB.
+- pass params -f (filtered data), -h (huffman only), -1 to -9 (compression
+  level) in minigzip (thanks to Tom Lane)
+
+- use const for rommable constants in deflate
+- added test for gzseek and gztell in example.c
+- add undocumented function inflateSyncPoint() (hack for Paul Mackerras)
+- add undocumented function zError to convert error code to string
+  (for Tim Smithers)
+- Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code.
+- Use default memcpy for Symantec MSDOS compiler.
+- Add EXPORT keyword for check_func (needed for Windows DLL)
+- add current directory to LD_LIBRARY_PATH for "make test"
+- create also a link for libz.so.1
+- added support for FUJITSU UXP/DS (thanks to Toshiaki Nomura)
+- use $(SHAREDLIB) instead of libz.so in Makefile.in (for HPUX)
+- added -soname for Linux in configure (Chun-Chung Chen,
+- assign numbers to the exported functions in zlib.def (for Windows DLL)
+- add advice in zlib.h for best usage of deflateSetDictionary
+- work around compiler bug on Atari (cast Z_NULL in call of s->checkfn)
+- allow compilation with ANSI keywords only enabled for TurboC in large model
+- avoid "versionString"[0] (Borland bug)
+- add NEED_DUMMY_RETURN for Borland
+- use variable z_verbose for tracing in debug mode (L. Peter Deutsch).
+- allow compilation with CC
+- defined STDC for OS/2 (David Charlap)
+- limit external names to 8 chars for MVS (Thomas Lund)
+- in minigzip.c, use static buffers only for 16-bit systems
+- fix suffix check for "minigzip -d foo.gz"
+- do not return an error for the 2nd of two consecutive gzflush() (Felix Lee)
+- use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau)
+- added makelcc.bat for lcc-win32 (Tom St Denis)
+- in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe)
+- Avoid expanded $Id$. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion.
+- check for unistd.h in configure (for off_t)
+- remove useless check parameter in inflate_blocks_free
+- avoid useless assignment of s->check to itself in inflate_blocks_new
+- do not flush twice in gzclose (thanks to Ken Raeburn)
+- rename FOPEN as F_OPEN to avoid clash with /usr/include/sys/file.h
+- use NO_ERRNO_H instead of enumeration of operating systems with errno.h
+- work around buggy fclose on pipes for HP/UX
+- support zlib DLL with BORLAND C++ 5.0 (thanks to Glenn Randers-Pehrson)
+- fix configure if CC is already equal to gcc
+
+Changes in 1.0.5 (3 Jan 98)
+- Fix inflate to terminate gracefully when fed corrupted or invalid data
+- Use const for rommable constants in inflate
+- Eliminate memory leaks on error conditions in inflate
+- Removed some vestigial code in inflate
+- Update web address in README
+
+Changes in 1.0.4 (24 Jul 96)
+- In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF
+  bit, so the decompressor could decompress all the correct data but went
+  on to attempt decompressing extra garbage data. This affected minigzip too.
+- zlibVersion and gzerror return const char* (needed for DLL)
+- port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno)
+- use z_error only for DEBUG (avoid problem with DLLs)
+
+Changes in 1.0.3 (2 Jul 96)
+- use z_streamp instead of z_stream *, which is now a far pointer in MSDOS
+  small and medium models; this makes the library incompatible with previous
+  versions for these models. (No effect in large model or on other systems.)
+- return OK instead of BUF_ERROR if previous deflate call returned with
+  avail_out as zero but there is nothing to do
+- added memcmp for non STDC compilers
+- define NO_DUMMY_DECL for more Mac compilers (.h files merged incorrectly)
+- define __32BIT__ if __386__ or i386 is defined (pb. with Watcom and SCO)
+- better check for 16-bit mode MSC (avoids problem with Symantec)
+
+Changes in 1.0.2 (23 May 96)
+- added Windows DLL support
+- added a function zlibVersion (for the DLL support)
+- fixed declarations using Bytef in infutil.c (pb with MSDOS medium model)
+- Bytef is define's instead of typedef'd only for Borland C
+- avoid reading uninitialized memory in example.c
+- mention in README that the zlib format is now RFC1950
+- updated Makefile.dj2
+- added algorithm.doc
+
+Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion]
+- fix array overlay in deflate.c which sometimes caused bad compressed data
+- fix inflate bug with empty stored block
+- fix MSDOS medium model which was broken in 0.99
+- fix deflateParams() which could generated bad compressed data.
+- Bytef is define'd instead of typedef'ed (work around Borland bug)
+- added an INDEX file
+- new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32),
+  Watcom (Makefile.wat), Amiga SAS/C (Makefile.sas)
+- speed up adler32 for modern machines without auto-increment
+- added -ansi for IRIX in configure
+- static_init_done in trees.c is an int
+- define unlink as delete for VMS
+- fix configure for QNX
+- add configure branch for SCO and HPUX
+- avoid many warnings (unused variables, dead assignments, etc...)
+- no fdopen for BeOS
+- fix the Watcom fix for 32 bit mode (define FAR as empty)
+- removed redefinition of Byte for MKWERKS
+- work around an MWKERKS bug (incorrect merge of all .h files)
+
+Changes in 0.99 (27 Jan 96)
+- allow preset dictionary shared between compressor and decompressor
+- allow compression level 0 (no compression)
+- add deflateParams in zlib.h: allow dynamic change of compression level
+  and compression strategy.
+- test large buffers and deflateParams in example.c
+- add optional "configure" to build zlib as a shared library
+- suppress Makefile.qnx, use configure instead
+- fixed deflate for 64-bit systems (detected on Cray)
+- fixed inflate_blocks for 64-bit systems (detected on Alpha)
+- declare Z_DEFLATED in zlib.h (possible parameter for deflateInit2)
+- always return Z_BUF_ERROR when deflate() has nothing to do
+- deflateInit and inflateInit are now macros to allow version checking
+- prefix all global functions and types with z_ with -DZ_PREFIX
+- make falloc completely reentrant (inftrees.c)
+- fixed very unlikely race condition in ct_static_init
+- free in reverse order of allocation to help memory manager
+- use zlib-1.0/* instead of zlib/* inside the tar.gz
+- make zlib warning-free with "gcc -O3 -Wall -Wwrite-strings -Wpointer-arith
+  -Wconversion -Wstrict-prototypes -Wmissing-prototypes"
+- allow gzread on concatenated .gz files
+- deflateEnd now returns Z_DATA_ERROR if it was premature
+- deflate is finally (?) fully deterministic (no matches beyond end of input)
+- Document Z_SYNC_FLUSH
+- add uninstall in Makefile
+- Check for __cpluplus in zlib.h
+- Better test in ct_align for partial flush
+- avoid harmless warnings for Borland C++
+- initialize hash_head in deflate.c
+- avoid warning on fdopen (gzio.c) for HP cc -Aa
+- include stdlib.h for STDC compilers
+- include errno.h for Cray
+- ignore error if ranlib doesn't exist
+- call ranlib twice for NeXTSTEP
+- use exec_prefix instead of prefix for libz.a
+- renamed ct_* as _tr_* to avoid conflict with applications
+- clear z->msg in inflateInit2 before any error return
+- initialize opaque in example.c, gzio.c, deflate.c and inflate.c
+- fixed typo in zconf.h (_GNUC__ => __GNUC__)
+- check for WIN32 in zconf.h and zutil.c (avoid farmalloc in 32-bit mode)
+- fix typo in Make_vms.com (f$trnlnm -> f$getsyi)
+- in fcalloc, normalize pointer if size > 65520 bytes
+- don't use special fcalloc for 32 bit Borland C++
+- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc...
+- use Z_BINARY instead of BINARY
+- document that gzclose after gzdopen will close the file
+- allow "a" as mode in gzopen.
+- fix error checking in gzread
+- allow skipping .gz extra-field on pipes
+- added reference to Perl interface in README
+- put the crc table in FAR data (I dislike more and more the medium model :)
+- added get_crc_table
+- added a dimension to all arrays (Borland C can't count).
+- workaround Borland C bug in declaration of inflate_codes_new & inflate_fast
+- guard against multiple inclusion of *.h (for precompiled header on Mac)
+- Watcom C pretends to be Microsoft C small model even in 32 bit mode.
+- don't use unsized arrays to avoid silly warnings by Visual C++:
+     warning C4746: 'inflate_mask' : unsized array treated as  '__far'
+     (what's wrong with far data in far model?).
+- define enum out of inflate_blocks_state to allow compilation with C++
+
+Changes in 0.95 (16 Aug 95)
+- fix MSDOS small and medium model (now easier to adapt to any compiler)
+- inlined send_bits
+- fix the final (:-) bug for deflate with flush (output was correct but
+  not completely flushed in rare occasions).
+- default window size is same for compression and decompression
+  (it's now sufficient to set MAX_WBITS in zconf.h).
+- voidp -> voidpf and voidnp -> voidp (for consistency with other
+  typedefs and because voidnp was not near in large model).
+
+Changes in 0.94 (13 Aug 95)
+- support MSDOS medium model
+- fix deflate with flush (could sometimes generate bad output)
+- fix deflateReset (zlib header was incorrectly suppressed)
+- added support for VMS
+- allow a compression level in gzopen()
+- gzflush now calls fflush
+- For deflate with flush, flush even if no more input is provided.
+- rename libgz.a as libz.a
+- avoid complex expression in infcodes.c triggering Turbo C bug
+- work around a problem with gcc on Alpha (in INSERT_STRING)
+- don't use inline functions (problem with some gcc versions)
+- allow renaming of Byte, uInt, etc... with #define.
+- avoid warning about (unused) pointer before start of array in deflate.c
+- avoid various warnings in gzio.c, example.c, infblock.c, adler32.c, zutil.c
+- avoid reserved word 'new' in trees.c
+
+Changes in 0.93 (25 June 95)
+- temporarily disable inline functions
+- make deflate deterministic
+- give enough lookahead for PARTIAL_FLUSH
+- Set binary mode for stdin/stdout in minigzip.c for OS/2
+- don't even use signed char in inflate (not portable enough)
+- fix inflate memory leak for segmented architectures
+
+Changes in 0.92 (3 May 95)
+- don't assume that char is signed (problem on SGI)
+- Clear bit buffer when starting a stored block
+- no memcpy on Pyramid
+- suppressed inftest.c
+- optimized fill_window, put longest_match inline for gcc
+- optimized inflate on stored blocks.
+- untabify all sources to simplify patches
+
+Changes in 0.91 (2 May 95)
+- Default MEM_LEVEL is 8 (not 9 for Unix) as documented in zlib.h
+- Document the memory requirements in zconf.h
+- added "make install"
+- fix sync search logic in inflateSync
+- deflate(Z_FULL_FLUSH) now works even if output buffer too short
+- after inflateSync, don't scare people with just "lo world"
+- added support for DJGPP
+
+Changes in 0.9 (1 May 95)
+- don't assume that zalloc clears the allocated memory (the TurboC bug
+  was Mark's bug after all :)
+- let again gzread copy uncompressed data unchanged (was working in 0.71)
+- deflate(Z_FULL_FLUSH), inflateReset and inflateSync are now fully implemented
+- added a test of inflateSync in example.c
+- moved MAX_WBITS to zconf.h because users might want to change that.
+- document explicitly that zalloc(64K) on MSDOS must return a normalized
+  pointer (zero offset)
+- added Makefiles for Microsoft C, Turbo C, Borland C++
+- faster crc32()
+
+Changes in 0.8 (29 April 95)
+- added fast inflate (inffast.c)
+- deflate(Z_FINISH) now returns Z_STREAM_END when done. Warning: this
+  is incompatible with previous versions of zlib which returned Z_OK.
+- work around a TurboC compiler bug (bad code for b << 0, see infutil.h)
+  (actually that was not a compiler bug, see 0.81 above)
+- gzread no longer reads one extra byte in certain cases
+- In gzio destroy(), don't reference a freed structure
+- avoid many warnings for MSDOS
+- avoid the ERROR symbol which is used by MS Windows
+
+Changes in 0.71 (14 April 95)
+- Fixed more MSDOS compilation problems :( There is still a bug with
+  TurboC large model.
+
+Changes in 0.7 (14 April 95)
+- Added full inflate support.
+- Simplified the crc32() interface. The pre- and post-conditioning
+  (one's complement) is now done inside crc32(). WARNING: this is
+  incompatible with previous versions; see zlib.h for the new usage.
+
+Changes in 0.61 (12 April 95)
+- workaround for a bug in TurboC. example and minigzip now work on MSDOS.
+
+Changes in 0.6 (11 April 95)
+- added minigzip.c
+- added gzdopen to reopen a file descriptor as gzFile
+- added transparent reading of non-gziped files in gzread.
+- fixed bug in gzread (don't read crc as data)
+- fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose).
+- don't allocate big arrays in the stack (for MSDOS)
+- fix some MSDOS compilation problems
+
+Changes in 0.5:
+- do real compression in deflate.c. Z_PARTIAL_FLUSH is supported but
+  not yet Z_FULL_FLUSH.
+- support decompression but only in a single step (forced Z_FINISH)
+- added opaque object for zalloc and zfree.
+- added deflateReset and inflateReset
+- added a variable zlib_version for consistency checking.
+- renamed the 'filter' parameter of deflateInit2 as 'strategy'.
+  Added Z_FILTERED and Z_HUFFMAN_ONLY constants.
+
+Changes in 0.4:
+- avoid "zip" everywhere, use zlib instead of ziplib.
+- suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush
+  if compression method == 8.
+- added adler32 and crc32
+- renamed deflateOptions as deflateInit2, call one or the other but not both
+- added the method parameter for deflateInit2.
+- added inflateInit2
+- simplied considerably deflateInit and inflateInit by not supporting
+  user-provided history buffer. This is supported only in deflateInit2
+  and inflateInit2.
+
+Changes in 0.3:
+- prefix all macro names with Z_
+- use Z_FINISH instead of deflateEnd to finish compression.
+- added Z_HUFFMAN_ONLY
+- added gzerror()

Added: vendor/Python/current/Modules/zlib/FAQ
===================================================================
--- vendor/Python/current/Modules/zlib/FAQ	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/zlib/FAQ	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,339 @@
+
+                Frequently Asked Questions about zlib
+
+
+If your question is not there, please check the zlib home page
+http://www.zlib.org which may have more recent information.
+The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html
+
+
+ 1. Is zlib Y2K-compliant?
+
+    Yes. zlib doesn't handle dates.
+
+ 2. Where can I get a Windows DLL version?
+
+    The zlib sources can be compiled without change to produce a DLL.
+    See the file win32/DLL_FAQ.txt in the zlib distribution.
+    Pointers to the precompiled DLL are found in the zlib web site at
+    http://www.zlib.org.
+
+ 3. Where can I get a Visual Basic interface to zlib?
+
+    See
+        * http://www.dogma.net/markn/articles/zlibtool/zlibtool.htm
+        * contrib/visual-basic.txt in the zlib distribution
+        * win32/DLL_FAQ.txt in the zlib distribution
+
+ 4. compress() returns Z_BUF_ERROR.
+
+    Make sure that before the call of compress, the length of the compressed
+    buffer is equal to the total size of the compressed buffer and not
+    zero. For Visual Basic, check that this parameter is passed by reference
+    ("as any"), not by value ("as long").
+
+ 5. deflate() or inflate() returns Z_BUF_ERROR.
+
+    Before making the call, make sure that avail_in and avail_out are not
+    zero. When setting the parameter flush equal to Z_FINISH, also make sure
+    that avail_out is big enough to allow processing all pending input.
+    Note that a Z_BUF_ERROR is not fatal--another call to deflate() or
+    inflate() can be made with more input or output space. A Z_BUF_ERROR
+    may in fact be unavoidable depending on how the functions are used, since
+    it is not possible to tell whether or not there is more output pending
+    when strm.avail_out returns with zero.
+
+ 6. Where's the zlib documentation (man pages, etc.)?
+
+    It's in zlib.h for the moment, and Francis S. Lin has converted it to a
+    web page zlib.html. Volunteers to transform this to Unix-style man pages,
+    please contact us (zlib at gzip.org). Examples of zlib usage are in the files
+    example.c and minigzip.c.
+
+ 7. Why don't you use GNU autoconf or libtool or ...?
+
+    Because we would like to keep zlib as a very small and simple
+    package. zlib is rather portable and doesn't need much configuration.
+
+ 8. I found a bug in zlib.
+
+    Most of the time, such problems are due to an incorrect usage of
+    zlib. Please try to reproduce the problem with a small program and send
+    the corresponding source to us at zlib at gzip.org . Do not send
+    multi-megabyte data files without prior agreement.
+
+ 9. Why do I get "undefined reference to gzputc"?
+
+    If "make test" produces something like
+
+       example.o(.text+0x154): undefined reference to `gzputc'
+
+    check that you don't have old files libz.* in /usr/lib, /usr/local/lib or
+    /usr/X11R6/lib. Remove any old versions, then do "make install".
+
+10. I need a Delphi interface to zlib.
+
+    See the contrib/delphi directory in the zlib distribution.
+
+11. Can zlib handle .zip archives?
+
+    Not by itself, no.  See the directory contrib/minizip in the zlib
+    distribution.
+
+12. Can zlib handle .Z files?
+
+    No, sorry. You have to spawn an uncompress or gunzip subprocess, or adapt
+    the code of uncompress on your own.
+
+13. How can I make a Unix shared library?
+
+    make clean
+    ./configure -s
+    make
+
+14. How do I install a shared zlib library on Unix?
+
+    After the above, then:
+
+    make install
+
+    However, many flavors of Unix come with a shared zlib already installed.
+    Before going to the trouble of compiling a shared version of zlib and
+    trying to install it, you may want to check if it's already there! If you
+    can #include <zlib.h>, it's there. The -lz option will probably link to it.
+
+15. I have a question about OttoPDF.
+
+    We are not the authors of OttoPDF. The real author is on the OttoPDF web
+    site: Joel Hainley, jhainley at myndkryme.com.
+
+16. Can zlib decode Flate data in an Adobe PDF file?
+
+    Yes. See http://www.fastio.com/ (ClibPDF), or http://www.pdflib.com/ .
+    To modify PDF forms, see http://sourceforge.net/projects/acroformtool/ .
+
+17. Why am I getting this "register_frame_info not found" error on Solaris?
+
+    After installing zlib 1.1.4 on Solaris 2.6, running applications using zlib
+    generates an error such as:
+
+        ld.so.1: rpm: fatal: relocation error: file /usr/local/lib/libz.so:
+        symbol __register_frame_info: referenced symbol not found
+
+    The symbol __register_frame_info is not part of zlib, it is generated by
+    the C compiler (cc or gcc). You must recompile applications using zlib
+    which have this problem. This problem is specific to Solaris. See
+    http://www.sunfreeware.com for Solaris versions of zlib and applications
+    using zlib.
+
+18. Why does gzip give an error on a file I make with compress/deflate?
+
+    The compress and deflate functions produce data in the zlib format, which
+    is different and incompatible with the gzip format. The gz* functions in
+    zlib on the other hand use the gzip format. Both the zlib and gzip
+    formats use the same compressed data format internally, but have different
+    headers and trailers around the compressed data.
+
+19. Ok, so why are there two different formats?
+
+    The gzip format was designed to retain the directory information about
+    a single file, such as the name and last modification date. The zlib
+    format on the other hand was designed for in-memory and communication
+    channel applications, and has a much more compact header and trailer and
+    uses a faster integrity check than gzip.
+
+20. Well that's nice, but how do I make a gzip file in memory?
+
+    You can request that deflate write the gzip format instead of the zlib
+    format using deflateInit2(). You can also request that inflate decode
+    the gzip format using inflateInit2(). Read zlib.h for more details.
+
+21. Is zlib thread-safe?
+
+    Yes. However any library routines that zlib uses and any application-
+    provided memory allocation routines must also be thread-safe. zlib's gz*
+    functions use stdio library routines, and most of zlib's functions use the
+    library memory allocation routines by default. zlib's Init functions allow
+    for the application to provide custom memory allocation routines.
+
+    Of course, you should only operate on any given zlib or gzip stream from a
+    single thread at a time.
+
+22. Can I use zlib in my commercial application?
+
+    Yes. Please read the license in zlib.h.
+
+23. Is zlib under the GNU license?
+
+    No. Please read the license in zlib.h.
+
+24. The license says that altered source versions must be "plainly marked". So
+    what exactly do I need to do to meet that requirement?
+
+    You need to change the ZLIB_VERSION and ZLIB_VERNUM #defines in zlib.h. In
+    particular, the final version number needs to be changed to "f", and an
+    identification string should be appended to ZLIB_VERSION. Version numbers
+    x.x.x.f are reserved for modifications to zlib by others than the zlib
+    maintainers. For example, if the version of the base zlib you are altering
+    is "1.2.3.4", then in zlib.h you should change ZLIB_VERNUM to 0x123f, and
+    ZLIB_VERSION to something like "1.2.3.f-zachary-mods-v3". You can also
+    update the version strings in deflate.c and inftrees.c.
+
+    For altered source distributions, you should also note the origin and
+    nature of the changes in zlib.h, as well as in ChangeLog and README, along
+    with the dates of the alterations. The origin should include at least your
+    name (or your company's name), and an email address to contact for help or
+    issues with the library.
+
+    Note that distributing a compiled zlib library along with zlib.h and
+    zconf.h is also a source distribution, and so you should change
+    ZLIB_VERSION and ZLIB_VERNUM and note the origin and nature of the changes
+    in zlib.h as you would for a full source distribution.
+
+25. Will zlib work on a big-endian or little-endian architecture, and can I
+    exchange compressed data between them?
+
+    Yes and yes.
+
+26. Will zlib work on a 64-bit machine?
+
+    It should. It has been tested on 64-bit machines, and has no dependence
+    on any data types being limited to 32-bits in length. If you have any
+    difficulties, please provide a complete problem report to zlib at gzip.org
+
+27. Will zlib decompress data from the PKWare Data Compression Library?
+
+    No. The PKWare DCL uses a completely different compressed data format
+    than does PKZIP and zlib. However, you can look in zlib's contrib/blast
+    directory for a possible solution to your problem.
+
+28. Can I access data randomly in a compressed stream?
+
+    No, not without some preparation. If when compressing you periodically
+    use Z_FULL_FLUSH, carefully write all the pending data at those points,
+    and keep an index of those locations, then you can start decompression
+    at those points. You have to be careful to not use Z_FULL_FLUSH too
+    often, since it can significantly degrade compression.
+
+29. Does zlib work on MVS, OS/390, CICS, etc.?
+
+    We don't know for sure. We have heard occasional reports of success on
+    these systems. If you do use it on one of these, please provide us with
+    a report, instructions, and patches that we can reference when we get
+    these questions. Thanks.
+
+30. Is there some simpler, easier to read version of inflate I can look at
+    to understand the deflate format?
+
+    First off, you should read RFC 1951. Second, yes. Look in zlib's
+    contrib/puff directory.
+
+31. Does zlib infringe on any patents?
+
+    As far as we know, no. In fact, that was originally the whole point behind
+    zlib. Look here for some more information:
+
+    http://www.gzip.org/#faq11
+
+32. Can zlib work with greater than 4 GB of data?
+
+    Yes. inflate() and deflate() will process any amount of data correctly.
+    Each call of inflate() or deflate() is limited to input and output chunks
+    of the maximum value that can be stored in the compiler's "unsigned int"
+    type, but there is no limit to the number of chunks. Note however that the
+    strm.total_in and strm_total_out counters may be limited to 4 GB. These
+    counters are provided as a convenience and are not used internally by
+    inflate() or deflate(). The application can easily set up its own counters
+    updated after each call of inflate() or deflate() to count beyond 4 GB.
+    compress() and uncompress() may be limited to 4 GB, since they operate in a
+    single call. gzseek() and gztell() may be limited to 4 GB depending on how
+    zlib is compiled. See the zlibCompileFlags() function in zlib.h.
+
+    The word "may" appears several times above since there is a 4 GB limit
+    only if the compiler's "long" type is 32 bits. If the compiler's "long"
+    type is 64 bits, then the limit is 16 exabytes.
+
+33. Does zlib have any security vulnerabilities?
+
+    The only one that we are aware of is potentially in gzprintf(). If zlib
+    is compiled to use sprintf() or vsprintf(), then there is no protection
+    against a buffer overflow of a 4K string space, other than the caller of
+    gzprintf() assuring that the output will not exceed 4K. On the other
+    hand, if zlib is compiled to use snprintf() or vsnprintf(), which should
+    normally be the case, then there is no vulnerability. The ./configure
+    script will display warnings if an insecure variation of sprintf() will
+    be used by gzprintf(). Also the zlibCompileFlags() function will return
+    information on what variant of sprintf() is used by gzprintf().
+
+    If you don't have snprintf() or vsnprintf() and would like one, you can
+    find a portable implementation here:
+
+        http://www.ijs.si/software/snprintf/
+
+    Note that you should be using the most recent version of zlib. Versions
+    1.1.3 and before were subject to a double-free vulnerability.
+
+34. Is there a Java version of zlib?
+
+    Probably what you want is to use zlib in Java. zlib is already included
+    as part of the Java SDK in the java.util.zip package. If you really want
+    a version of zlib written in the Java language, look on the zlib home
+    page for links: http://www.zlib.org/
+
+35. I get this or that compiler or source-code scanner warning when I crank it
+    up to maximally-pedantic. Can't you guys write proper code?
+
+    Many years ago, we gave up attempting to avoid warnings on every compiler
+    in the universe. It just got to be a waste of time, and some compilers
+    were downright silly. So now, we simply make sure that the code always
+    works.
+
+36. Valgrind (or some similar memory access checker) says that deflate is
+    performing a conditional jump that depends on an uninitialized value.
+    Isn't that a bug?
+
+    No.  That is intentional for performance reasons, and the output of
+    deflate is not affected.  This only started showing up recently since
+    zlib 1.2.x uses malloc() by default for allocations, whereas earlier
+    versions used calloc(), which zeros out the allocated memory.
+
+37. Will zlib read the (insert any ancient or arcane format here) compressed
+    data format?
+
+    Probably not. Look in the comp.compression FAQ for pointers to various
+    formats and associated software.
+
+38. How can I encrypt/decrypt zip files with zlib?
+
+    zlib doesn't support encryption. The original PKZIP encryption is very weak
+    and can be broken with freely available programs. To get strong encryption,
+    use GnuPG, http://www.gnupg.org/ , which already includes zlib compression.
+    For PKZIP compatible "encryption", look at http://www.info-zip.org/
+
+39. What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings?
+
+    "gzip" is the gzip format, and "deflate" is the zlib format. They should
+    probably have called the second one "zlib" instead to avoid confusion
+    with the raw deflate compressed data format. While the HTTP 1.1 RFC 2616
+    correctly points to the zlib specification in RFC 1950 for the "deflate"
+    transfer encoding, there have been reports of servers and browsers that
+    incorrectly produce or expect raw deflate data per the deflate
+    specficiation in RFC 1951, most notably Microsoft. So even though the
+    "deflate" transfer encoding using the zlib format would be the more
+    efficient approach (and in fact exactly what the zlib format was designed
+    for), using the "gzip" transfer encoding is probably more reliable due to
+    an unfortunate choice of name on the part of the HTTP 1.1 authors.
+
+    Bottom line: use the gzip format for HTTP 1.1 encoding.
+
+40. Does zlib support the new "Deflate64" format introduced by PKWare?
+
+    No. PKWare has apparently decided to keep that format proprietary, since
+    they have not documented it as they have previous compression formats.
+    In any case, the compression improvements are so modest compared to other
+    more modern approaches, that it's not worth the effort to implement.
+
+41. Can you please sign these lengthy legal documents and fax them back to us
+    so that we can use your software in our product?
+
+    No. Go away. Shoo.

Added: vendor/Python/current/Modules/zlib/INDEX
===================================================================
--- vendor/Python/current/Modules/zlib/INDEX	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/zlib/INDEX	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,51 @@
+ChangeLog       history of changes
+FAQ             Frequently Asked Questions about zlib
+INDEX           this file
+Makefile        makefile for Unix (generated by configure)
+Makefile.in     makefile for Unix (template for configure)
+README          guess what
+algorithm.txt   description of the (de)compression algorithm
+configure       configure script for Unix
+zconf.in.h      template for zconf.h (used by configure)
+
+amiga/          makefiles for Amiga SAS C
+as400/          makefiles for IBM AS/400
+msdos/          makefiles for MSDOS
+old/            makefiles for various architectures and zlib documentation
+                files that have not yet been updated for zlib 1.2.x
+projects/       projects for various Integrated Development Environments
+qnx/            makefiles for QNX
+win32/          makefiles for Windows
+
+                zlib public header files (must be kept):
+zconf.h
+zlib.h
+
+                private source files used to build the zlib library:
+adler32.c
+compress.c
+crc32.c
+crc32.h
+deflate.c
+deflate.h
+gzio.c
+infback.c
+inffast.c
+inffast.h
+inffixed.h
+inflate.c
+inflate.h
+inftrees.c
+inftrees.h
+trees.c
+trees.h
+uncompr.c
+zutil.c
+zutil.h
+
+                source files for sample programs:
+example.c
+minigzip.c
+
+                unsupported contribution by third parties
+See contrib/README.contrib

Added: vendor/Python/current/Modules/zlib/README
===================================================================
--- vendor/Python/current/Modules/zlib/README	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/zlib/README	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,125 @@
+ZLIB DATA COMPRESSION LIBRARY
+
+zlib 1.2.3 is a general purpose data compression library.  All the code is
+thread safe.  The data format used by the zlib library is described by RFCs
+(Request for Comments) 1950 to 1952 in the files
+http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format)
+and rfc1952.txt (gzip format). These documents are also available in other
+formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html
+
+All functions of the compression library are documented in the file zlib.h
+(volunteer to write man pages welcome, contact zlib at gzip.org). A usage example
+of the library is given in the file example.c which also tests that the library
+is working correctly. Another example is given in the file minigzip.c. The
+compression library itself is composed of all source files except example.c and
+minigzip.c.
+
+To compile all files and run the test program, follow the instructions given at
+the top of Makefile. In short "make test; make install" should work for most
+machines. For Unix: "./configure; make test; make install". For MSDOS, use one
+of the special makefiles such as Makefile.msc. For VMS, use make_vms.com.
+
+Questions about zlib should be sent to <zlib at gzip.org>, or to Gilles Vollant
+<info at winimage.com> for the Windows DLL version. The zlib home page is
+http://www.zlib.org or http://www.gzip.org/zlib/ Before reporting a problem,
+please check this site to verify that you have the latest version of zlib;
+otherwise get the latest version and check whether the problem still exists or
+not.
+
+PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html before asking
+for help.
+
+Mark Nelson <markn at ieee.org> wrote an article about zlib for the Jan. 1997
+issue of  Dr. Dobb's Journal; a copy of the article is available in
+http://dogma.net/markn/articles/zlibtool/zlibtool.htm
+
+The changes made in version 1.2.3 are documented in the file ChangeLog.
+
+Unsupported third party contributions are provided in directory "contrib".
+
+A Java implementation of zlib is available in the Java Development Kit
+http://java.sun.com/j2se/1.4.2/docs/api/java/util/zip/package-summary.html
+See the zlib home page http://www.zlib.org for details.
+
+A Perl interface to zlib written by Paul Marquess <pmqs at cpan.org> is in the
+CPAN (Comprehensive Perl Archive Network) sites
+http://www.cpan.org/modules/by-module/Compress/
+
+A Python interface to zlib written by A.M. Kuchling <amk at amk.ca> is
+available in Python 1.5 and later versions, see
+http://www.python.org/doc/lib/module-zlib.html
+
+A zlib binding for TCL written by Andreas Kupries <a.kupries at westend.com> is
+availlable at http://www.oche.de/~akupries/soft/trf/trf_zip.html
+
+An experimental package to read and write files in .zip format, written on top
+of zlib by Gilles Vollant <info at winimage.com>, is available in the
+contrib/minizip directory of zlib.
+
+
+Notes for some targets:
+
+- For Windows DLL versions, please see win32/DLL_FAQ.txt
+
+- For 64-bit Irix, deflate.c must be compiled without any optimization. With
+  -O, one libpng test fails. The test works in 32 bit mode (with the -n32
+  compiler flag). The compiler bug has been reported to SGI.
+
+- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works
+  when compiled with cc.
+
+- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is
+  necessary to get gzprintf working correctly. This is done by configure.
+
+- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with
+  other compilers. Use "make test" to check your compiler.
+
+- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers.
+
+- For PalmOs, see http://palmzlib.sourceforge.net/
+
+- When building a shared, i.e. dynamic library on Mac OS X, the library must be
+  installed before testing (do "make install" before "make test"), since the
+  library location is specified in the library.
+
+
+Acknowledgments:
+
+  The deflate format used by zlib was defined by Phil Katz. The deflate
+  and zlib specifications were written by L. Peter Deutsch. Thanks to all the
+  people who reported problems and suggested various improvements in zlib;
+  they are too numerous to cite here.
+
+Copyright notice:
+
+ (C) 1995-2004 Jean-loup Gailly and Mark Adler
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  Jean-loup Gailly        Mark Adler
+  jloup at gzip.org          madler at alumni.caltech.edu
+
+If you use the zlib library in a product, we would appreciate *not*
+receiving lengthy legal documents to sign. The sources are provided
+for free but without warranty of any kind.  The library has been
+entirely written by Jean-loup Gailly and Mark Adler; it does not
+include third-party code.
+
+If you redistribute modified sources, we would appreciate that you include
+in the file ChangeLog history information documenting your changes. Please
+read the FAQ for more information on the distribution of modified source
+versions.

Added: vendor/Python/current/Modules/zlib/adler32.c
===================================================================
--- vendor/Python/current/Modules/zlib/adler32.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/zlib/adler32.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,149 @@
+/* adler32.c -- compute the Adler-32 checksum of a data stream
+ * Copyright (C) 1995-2004 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#define ZLIB_INTERNAL
+#include "zlib.h"
+
+#define BASE 65521UL    /* largest prime smaller than 65536 */
+#define NMAX 5552
+/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
+
+#define DO1(buf,i)  {adler += (buf)[i]; sum2 += adler;}
+#define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1);
+#define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2);
+#define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4);
+#define DO16(buf)   DO8(buf,0); DO8(buf,8);
+
+/* use NO_DIVIDE if your processor does not do division in hardware */
+#ifdef NO_DIVIDE
+#  define MOD(a) \
+    do { \
+        if (a >= (BASE << 16)) a -= (BASE << 16); \
+        if (a >= (BASE << 15)) a -= (BASE << 15); \
+        if (a >= (BASE << 14)) a -= (BASE << 14); \
+        if (a >= (BASE << 13)) a -= (BASE << 13); \
+        if (a >= (BASE << 12)) a -= (BASE << 12); \
+        if (a >= (BASE << 11)) a -= (BASE << 11); \
+        if (a >= (BASE << 10)) a -= (BASE << 10); \
+        if (a >= (BASE << 9)) a -= (BASE << 9); \
+        if (a >= (BASE << 8)) a -= (BASE << 8); \
+        if (a >= (BASE << 7)) a -= (BASE << 7); \
+        if (a >= (BASE << 6)) a -= (BASE << 6); \
+        if (a >= (BASE << 5)) a -= (BASE << 5); \
+        if (a >= (BASE << 4)) a -= (BASE << 4); \
+        if (a >= (BASE << 3)) a -= (BASE << 3); \
+        if (a >= (BASE << 2)) a -= (BASE << 2); \
+        if (a >= (BASE << 1)) a -= (BASE << 1); \
+        if (a >= BASE) a -= BASE; \
+    } while (0)
+#  define MOD4(a) \
+    do { \
+        if (a >= (BASE << 4)) a -= (BASE << 4); \
+        if (a >= (BASE << 3)) a -= (BASE << 3); \
+        if (a >= (BASE << 2)) a -= (BASE << 2); \
+        if (a >= (BASE << 1)) a -= (BASE << 1); \
+        if (a >= BASE) a -= BASE; \
+    } while (0)
+#else
+#  define MOD(a) a %= BASE
+#  define MOD4(a) a %= BASE
+#endif
+
+/* ========================================================================= */
+uLong ZEXPORT adler32(adler, buf, len)
+    uLong adler;
+    const Bytef *buf;
+    uInt len;
+{
+    unsigned long sum2;
+    unsigned n;
+
+    /* split Adler-32 into component sums */
+    sum2 = (adler >> 16) & 0xffff;
+    adler &= 0xffff;
+
+    /* in case user likes doing a byte at a time, keep it fast */
+    if (len == 1) {
+        adler += buf[0];
+        if (adler >= BASE)
+            adler -= BASE;
+        sum2 += adler;
+        if (sum2 >= BASE)
+            sum2 -= BASE;
+        return adler | (sum2 << 16);
+    }
+
+    /* initial Adler-32 value (deferred check for len == 1 speed) */
+    if (buf == Z_NULL)
+        return 1L;
+
+    /* in case short lengths are provided, keep it somewhat fast */
+    if (len < 16) {
+        while (len--) {
+            adler += *buf++;
+            sum2 += adler;
+        }
+        if (adler >= BASE)
+            adler -= BASE;
+        MOD4(sum2);             /* only added so many BASE's */
+        return adler | (sum2 << 16);
+    }
+
+    /* do length NMAX blocks -- requires just one modulo operation */
+    while (len >= NMAX) {
+        len -= NMAX;
+        n = NMAX / 16;          /* NMAX is divisible by 16 */
+        do {
+            DO16(buf);          /* 16 sums unrolled */
+            buf += 16;
+        } while (--n);
+        MOD(adler);
+        MOD(sum2);
+    }
+
+    /* do remaining bytes (less than NMAX, still just one modulo) */
+    if (len) {                  /* avoid modulos if none remaining */
+        while (len >= 16) {
+            len -= 16;
+            DO16(buf);
+            buf += 16;
+        }
+        while (len--) {
+            adler += *buf++;
+            sum2 += adler;
+        }
+        MOD(adler);
+        MOD(sum2);
+    }
+
+    /* return recombined sums */
+    return adler | (sum2 << 16);
+}
+
+/* ========================================================================= */
+uLong ZEXPORT adler32_combine(adler1, adler2, len2)
+    uLong adler1;
+    uLong adler2;
+    z_off_t len2;
+{
+    unsigned long sum1;
+    unsigned long sum2;
+    unsigned rem;
+
+    /* the derivation of this formula is left as an exercise for the reader */
+    rem = (unsigned)(len2 % BASE);
+    sum1 = adler1 & 0xffff;
+    sum2 = rem * sum1;
+    MOD(sum2);
+    sum1 += (adler2 & 0xffff) + BASE - 1;
+    sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
+    if (sum1 > BASE) sum1 -= BASE;
+    if (sum1 > BASE) sum1 -= BASE;
+    if (sum2 > (BASE << 1)) sum2 -= (BASE << 1);
+    if (sum2 > BASE) sum2 -= BASE;
+    return sum1 | (sum2 << 16);
+}

Added: vendor/Python/current/Modules/zlib/algorithm.txt
===================================================================
--- vendor/Python/current/Modules/zlib/algorithm.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/zlib/algorithm.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,209 @@
+1. Compression algorithm (deflate)
+
+The deflation algorithm used by gzip (also zip and zlib) is a variation of
+LZ77 (Lempel-Ziv 1977, see reference below). It finds duplicated strings in
+the input data.  The second occurrence of a string is replaced by a
+pointer to the previous string, in the form of a pair (distance,
+length).  Distances are limited to 32K bytes, and lengths are limited
+to 258 bytes. When a string does not occur anywhere in the previous
+32K bytes, it is emitted as a sequence of literal bytes.  (In this
+description, `string' must be taken as an arbitrary sequence of bytes,
+and is not restricted to printable characters.)
+
+Literals or match lengths are compressed with one Huffman tree, and
+match distances are compressed with another tree. The trees are stored
+in a compact form at the start of each block. The blocks can have any
+size (except that the compressed data for one block must fit in
+available memory). A block is terminated when deflate() determines that
+it would be useful to start another block with fresh trees. (This is
+somewhat similar to the behavior of LZW-based _compress_.)
+
+Duplicated strings are found using a hash table. All input strings of
+length 3 are inserted in the hash table. A hash index is computed for
+the next 3 bytes. If the hash chain for this index is not empty, all
+strings in the chain are compared with the current input string, and
+the longest match is selected.
+
+The hash chains are searched starting with the most recent strings, to
+favor small distances and thus take advantage of the Huffman encoding.
+The hash chains are singly linked. There are no deletions from the
+hash chains, the algorithm simply discards matches that are too old.
+
+To avoid a worst-case situation, very long hash chains are arbitrarily
+truncated at a certain length, determined by a runtime option (level
+parameter of deflateInit). So deflate() does not always find the longest
+possible match but generally finds a match which is long enough.
+
+deflate() also defers the selection of matches with a lazy evaluation
+mechanism. After a match of length N has been found, deflate() searches for
+a longer match at the next input byte. If a longer match is found, the
+previous match is truncated to a length of one (thus producing a single
+literal byte) and the process of lazy evaluation begins again. Otherwise,
+the original match is kept, and the next match search is attempted only N
+steps later.
+
+The lazy match evaluation is also subject to a runtime parameter. If
+the current match is long enough, deflate() reduces the search for a longer
+match, thus speeding up the whole process. If compression ratio is more
+important than speed, deflate() attempts a complete second search even if
+the first match is already long enough.
+
+The lazy match evaluation is not performed for the fastest compression
+modes (level parameter 1 to 3). For these fast modes, new strings
+are inserted in the hash table only when no match was found, or
+when the match is not too long. This degrades the compression ratio
+but saves time since there are both fewer insertions and fewer searches.
+
+
+2. Decompression algorithm (inflate)
+
+2.1 Introduction
+
+The key question is how to represent a Huffman code (or any prefix code) so
+that you can decode fast.  The most important characteristic is that shorter
+codes are much more common than longer codes, so pay attention to decoding the
+short codes fast, and let the long codes take longer to decode.
+
+inflate() sets up a first level table that covers some number of bits of
+input less than the length of longest code.  It gets that many bits from the
+stream, and looks it up in the table.  The table will tell if the next
+code is that many bits or less and how many, and if it is, it will tell
+the value, else it will point to the next level table for which inflate()
+grabs more bits and tries to decode a longer code.
+
+How many bits to make the first lookup is a tradeoff between the time it
+takes to decode and the time it takes to build the table.  If building the
+table took no time (and if you had infinite memory), then there would only
+be a first level table to cover all the way to the longest code.  However,
+building the table ends up taking a lot longer for more bits since short
+codes are replicated many times in such a table.  What inflate() does is
+simply to make the number of bits in the first table a variable, and  then
+to set that variable for the maximum speed.
+
+For inflate, which has 286 possible codes for the literal/length tree, the size
+of the first table is nine bits.  Also the distance trees have 30 possible
+values, and the size of the first table is six bits.  Note that for each of
+those cases, the table ended up one bit longer than the ``average'' code
+length, i.e. the code length of an approximately flat code which would be a
+little more than eight bits for 286 symbols and a little less than five bits
+for 30 symbols.
+
+
+2.2 More details on the inflate table lookup
+
+Ok, you want to know what this cleverly obfuscated inflate tree actually
+looks like.  You are correct that it's not a Huffman tree.  It is simply a
+lookup table for the first, let's say, nine bits of a Huffman symbol.  The
+symbol could be as short as one bit or as long as 15 bits.  If a particular
+symbol is shorter than nine bits, then that symbol's translation is duplicated
+in all those entries that start with that symbol's bits.  For example, if the
+symbol is four bits, then it's duplicated 32 times in a nine-bit table.  If a
+symbol is nine bits long, it appears in the table once.
+
+If the symbol is longer than nine bits, then that entry in the table points
+to another similar table for the remaining bits.  Again, there are duplicated
+entries as needed.  The idea is that most of the time the symbol will be short
+and there will only be one table look up.  (That's whole idea behind data
+compression in the first place.)  For the less frequent long symbols, there
+will be two lookups.  If you had a compression method with really long
+symbols, you could have as many levels of lookups as is efficient.  For
+inflate, two is enough.
+
+So a table entry either points to another table (in which case nine bits in
+the above example are gobbled), or it contains the translation for the symbol
+and the number of bits to gobble.  Then you start again with the next
+ungobbled bit.
+
+You may wonder: why not just have one lookup table for how ever many bits the
+longest symbol is?  The reason is that if you do that, you end up spending
+more time filling in duplicate symbol entries than you do actually decoding.
+At least for deflate's output that generates new trees every several 10's of
+kbytes.  You can imagine that filling in a 2^15 entry table for a 15-bit code
+would take too long if you're only decoding several thousand symbols.  At the
+other extreme, you could make a new table for every bit in the code.  In fact,
+that's essentially a Huffman tree.  But then you spend two much time
+traversing the tree while decoding, even for short symbols.
+
+So the number of bits for the first lookup table is a trade of the time to
+fill out the table vs. the time spent looking at the second level and above of
+the table.
+
+Here is an example, scaled down:
+
+The code being decoded, with 10 symbols, from 1 to 6 bits long:
+
+A: 0
+B: 10
+C: 1100
+D: 11010
+E: 11011
+F: 11100
+G: 11101
+H: 11110
+I: 111110
+J: 111111
+
+Let's make the first table three bits long (eight entries):
+
+000: A,1
+001: A,1
+010: A,1
+011: A,1
+100: B,2
+101: B,2
+110: -> table X (gobble 3 bits)
+111: -> table Y (gobble 3 bits)
+
+Each entry is what the bits decode as and how many bits that is, i.e. how
+many bits to gobble.  Or the entry points to another table, with the number of
+bits to gobble implicit in the size of the table.
+
+Table X is two bits long since the longest code starting with 110 is five bits
+long:
+
+00: C,1
+01: C,1
+10: D,2
+11: E,2
+
+Table Y is three bits long since the longest code starting with 111 is six
+bits long:
+
+000: F,2
+001: F,2
+010: G,2
+011: G,2
+100: H,2
+101: H,2
+110: I,3
+111: J,3
+
+So what we have here are three tables with a total of 20 entries that had to
+be constructed.  That's compared to 64 entries for a single table.  Or
+compared to 16 entries for a Huffman tree (six two entry tables and one four
+entry table).  Assuming that the code ideally represents the probability of
+the symbols, it takes on the average 1.25 lookups per symbol.  That's compared
+to one lookup for the single table, or 1.66 lookups per symbol for the
+Huffman tree.
+
+There, I think that gives you a picture of what's going on.  For inflate, the
+meaning of a particular symbol is often more than just a letter.  It can be a
+byte (a "literal"), or it can be either a length or a distance which
+indicates a base value and a number of bits to fetch after the code that is
+added to the base value.  Or it might be the special end-of-block code.  The
+data structures created in inftrees.c try to encode all that information
+compactly in the tables.
+
+
+Jean-loup Gailly        Mark Adler
+jloup at gzip.org          madler at alumni.caltech.edu
+
+
+References:
+
+[LZ77] Ziv J., Lempel A., ``A Universal Algorithm for Sequential Data
+Compression,'' IEEE Transactions on Information Theory, Vol. 23, No. 3,
+pp. 337-343.
+
+``DEFLATE Compressed Data Format Specification'' available in
+http://www.ietf.org/rfc/rfc1951.txt

Added: vendor/Python/current/Modules/zlib/compress.c
===================================================================
--- vendor/Python/current/Modules/zlib/compress.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/zlib/compress.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,79 @@
+/* compress.c -- compress a memory buffer
+ * Copyright (C) 1995-2003 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#define ZLIB_INTERNAL
+#include "zlib.h"
+
+/* ===========================================================================
+     Compresses the source buffer into the destination buffer. The level
+   parameter has the same meaning as in deflateInit.  sourceLen is the byte
+   length of the source buffer. Upon entry, destLen is the total size of the
+   destination buffer, which must be at least 0.1% larger than sourceLen plus
+   12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
+
+     compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+   Z_STREAM_ERROR if the level parameter is invalid.
+*/
+int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
+    Bytef *dest;
+    uLongf *destLen;
+    const Bytef *source;
+    uLong sourceLen;
+    int level;
+{
+    z_stream stream;
+    int err;
+
+    stream.next_in = (Bytef*)source;
+    stream.avail_in = (uInt)sourceLen;
+#ifdef MAXSEG_64K
+    /* Check for source > 64K on 16-bit machine: */
+    if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
+#endif
+    stream.next_out = dest;
+    stream.avail_out = (uInt)*destLen;
+    if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
+
+    stream.zalloc = (alloc_func)0;
+    stream.zfree = (free_func)0;
+    stream.opaque = (voidpf)0;
+
+    err = deflateInit(&stream, level);
+    if (err != Z_OK) return err;
+
+    err = deflate(&stream, Z_FINISH);
+    if (err != Z_STREAM_END) {
+        deflateEnd(&stream);
+        return err == Z_OK ? Z_BUF_ERROR : err;
+    }
+    *destLen = stream.total_out;
+
+    err = deflateEnd(&stream);
+    return err;
+}
+
+/* ===========================================================================
+ */
+int ZEXPORT compress (dest, destLen, source, sourceLen)
+    Bytef *dest;
+    uLongf *destLen;
+    const Bytef *source;
+    uLong sourceLen;
+{
+    return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
+}
+
+/* ===========================================================================
+     If the default memLevel or windowBits for deflateInit() is changed, then
+   this function needs to be updated.
+ */
+uLong ZEXPORT compressBound (sourceLen)
+    uLong sourceLen;
+{
+    return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11;
+}

Added: vendor/Python/current/Modules/zlib/crc32.c
===================================================================
--- vendor/Python/current/Modules/zlib/crc32.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/zlib/crc32.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,423 @@
+/* crc32.c -- compute the CRC-32 of a data stream
+ * Copyright (C) 1995-2005 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ *
+ * Thanks to Rodney Brown <rbrown64 at csc.com.au> for his contribution of faster
+ * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
+ * tables for updating the shift register in one step with three exclusive-ors
+ * instead of four steps with four exclusive-ors.  This results in about a
+ * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
+ */
+
+/* @(#) $Id$ */
+
+/*
+  Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
+  protection on the static variables used to control the first-use generation
+  of the crc tables.  Therefore, if you #define DYNAMIC_CRC_TABLE, you should
+  first call get_crc_table() to initialize the tables before allowing more than
+  one thread to use crc32().
+ */
+
+#ifdef MAKECRCH
+#  include <stdio.h>
+#  ifndef DYNAMIC_CRC_TABLE
+#    define DYNAMIC_CRC_TABLE
+#  endif /* !DYNAMIC_CRC_TABLE */
+#endif /* MAKECRCH */
+
+#include "zutil.h"      /* for STDC and FAR definitions */
+
+#define local static
+
+/* Find a four-byte integer type for crc32_little() and crc32_big(). */
+#ifndef NOBYFOUR
+#  ifdef STDC           /* need ANSI C limits.h to determine sizes */
+#    include <limits.h>
+#    define BYFOUR
+#    if (UINT_MAX == 0xffffffffUL)
+       typedef unsigned int u4;
+#    else
+#      if (ULONG_MAX == 0xffffffffUL)
+         typedef unsigned long u4;
+#      else
+#        if (USHRT_MAX == 0xffffffffUL)
+           typedef unsigned short u4;
+#        else
+#          undef BYFOUR     /* can't find a four-byte integer type! */
+#        endif
+#      endif
+#    endif
+#  endif /* STDC */
+#endif /* !NOBYFOUR */
+
+/* Definitions for doing the crc four data bytes at a time. */
+#ifdef BYFOUR
+#  define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \
+                (((w)&0xff00)<<8)+(((w)&0xff)<<24))
+   local unsigned long crc32_little OF((unsigned long,
+                        const unsigned char FAR *, unsigned));
+   local unsigned long crc32_big OF((unsigned long,
+                        const unsigned char FAR *, unsigned));
+#  define TBLS 8
+#else
+#  define TBLS 1
+#endif /* BYFOUR */
+
+/* Local functions for crc concatenation */
+local unsigned long gf2_matrix_times OF((unsigned long *mat,
+                                         unsigned long vec));
+local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
+
+#ifdef DYNAMIC_CRC_TABLE
+
+local volatile int crc_table_empty = 1;
+local unsigned long FAR crc_table[TBLS][256];
+local void make_crc_table OF((void));
+#ifdef MAKECRCH
+   local void write_table OF((FILE *, const unsigned long FAR *));
+#endif /* MAKECRCH */
+/*
+  Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
+  x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
+
+  Polynomials over GF(2) are represented in binary, one bit per coefficient,
+  with the lowest powers in the most significant bit.  Then adding polynomials
+  is just exclusive-or, and multiplying a polynomial by x is a right shift by
+  one.  If we call the above polynomial p, and represent a byte as the
+  polynomial q, also with the lowest power in the most significant bit (so the
+  byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
+  where a mod b means the remainder after dividing a by b.
+
+  This calculation is done using the shift-register method of multiplying and
+  taking the remainder.  The register is initialized to zero, and for each
+  incoming bit, x^32 is added mod p to the register if the bit is a one (where
+  x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
+  x (which is shifting right by one and adding x^32 mod p if the bit shifted
+  out is a one).  We start with the highest power (least significant bit) of
+  q and repeat for all eight bits of q.
+
+  The first table is simply the CRC of all possible eight bit values.  This is
+  all the information needed to generate CRCs on data a byte at a time for all
+  combinations of CRC register values and incoming bytes.  The remaining tables
+  allow for word-at-a-time CRC calculation for both big-endian and little-
+  endian machines, where a word is four bytes.
+*/
+local void make_crc_table()
+{
+    unsigned long c;
+    int n, k;
+    unsigned long poly;                 /* polynomial exclusive-or pattern */
+    /* terms of polynomial defining this crc (except x^32): */
+    static volatile int first = 1;      /* flag to limit concurrent making */
+    static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
+
+    /* See if another task is already doing this (not thread-safe, but better
+       than nothing -- significantly reduces duration of vulnerability in
+       case the advice about DYNAMIC_CRC_TABLE is ignored) */
+    if (first) {
+        first = 0;
+
+        /* make exclusive-or pattern from polynomial (0xedb88320UL) */
+        poly = 0UL;
+        for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++)
+            poly |= 1UL << (31 - p[n]);
+
+        /* generate a crc for every 8-bit value */
+        for (n = 0; n < 256; n++) {
+            c = (unsigned long)n;
+            for (k = 0; k < 8; k++)
+                c = c & 1 ? poly ^ (c >> 1) : c >> 1;
+            crc_table[0][n] = c;
+        }
+
+#ifdef BYFOUR
+        /* generate crc for each value followed by one, two, and three zeros,
+           and then the byte reversal of those as well as the first table */
+        for (n = 0; n < 256; n++) {
+            c = crc_table[0][n];
+            crc_table[4][n] = REV(c);
+            for (k = 1; k < 4; k++) {
+                c = crc_table[0][c & 0xff] ^ (c >> 8);
+                crc_table[k][n] = c;
+                crc_table[k + 4][n] = REV(c);
+            }
+        }
+#endif /* BYFOUR */
+
+        crc_table_empty = 0;
+    }
+    else {      /* not first */
+        /* wait for the other guy to finish (not efficient, but rare) */
+        while (crc_table_empty)
+            ;
+    }
+
+#ifdef MAKECRCH
+    /* write out CRC tables to crc32.h */
+    {
+        FILE *out;
+
+        out = fopen("crc32.h", "w");
+        if (out == NULL) return;
+        fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
+        fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
+        fprintf(out, "local const unsigned long FAR ");
+        fprintf(out, "crc_table[TBLS][256] =\n{\n  {\n");
+        write_table(out, crc_table[0]);
+#  ifdef BYFOUR
+        fprintf(out, "#ifdef BYFOUR\n");
+        for (k = 1; k < 8; k++) {
+            fprintf(out, "  },\n  {\n");
+            write_table(out, crc_table[k]);
+        }
+        fprintf(out, "#endif\n");
+#  endif /* BYFOUR */
+        fprintf(out, "  }\n};\n");
+        fclose(out);
+    }
+#endif /* MAKECRCH */
+}
+
+#ifdef MAKECRCH
+local void write_table(out, table)
+    FILE *out;
+    const unsigned long FAR *table;
+{
+    int n;
+
+    for (n = 0; n < 256; n++)
+        fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : "    ", table[n],
+                n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
+}
+#endif /* MAKECRCH */
+
+#else /* !DYNAMIC_CRC_TABLE */
+/* ========================================================================
+ * Tables of CRC-32s of all single-byte values, made by make_crc_table().
+ */
+#include "crc32.h"
+#endif /* DYNAMIC_CRC_TABLE */
+
+/* =========================================================================
+ * This function can be used by asm versions of crc32()
+ */
+const unsigned long FAR * ZEXPORT get_crc_table()
+{
+#ifdef DYNAMIC_CRC_TABLE
+    if (crc_table_empty)
+        make_crc_table();
+#endif /* DYNAMIC_CRC_TABLE */
+    return (const unsigned long FAR *)crc_table;
+}
+
+/* ========================================================================= */
+#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
+#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
+
+/* ========================================================================= */
+unsigned long ZEXPORT crc32(crc, buf, len)
+    unsigned long crc;
+    const unsigned char FAR *buf;
+    unsigned len;
+{
+    if (buf == Z_NULL) return 0UL;
+
+#ifdef DYNAMIC_CRC_TABLE
+    if (crc_table_empty)
+        make_crc_table();
+#endif /* DYNAMIC_CRC_TABLE */
+
+#ifdef BYFOUR
+    if (sizeof(void *) == sizeof(ptrdiff_t)) {
+        u4 endian;
+
+        endian = 1;
+        if (*((unsigned char *)(&endian)))
+            return crc32_little(crc, buf, len);
+        else
+            return crc32_big(crc, buf, len);
+    }
+#endif /* BYFOUR */
+    crc = crc ^ 0xffffffffUL;
+    while (len >= 8) {
+        DO8;
+        len -= 8;
+    }
+    if (len) do {
+        DO1;
+    } while (--len);
+    return crc ^ 0xffffffffUL;
+}
+
+#ifdef BYFOUR
+
+/* ========================================================================= */
+#define DOLIT4 c ^= *buf4++; \
+        c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
+            crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
+#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
+
+/* ========================================================================= */
+local unsigned long crc32_little(crc, buf, len)
+    unsigned long crc;
+    const unsigned char FAR *buf;
+    unsigned len;
+{
+    register u4 c;
+    register const u4 FAR *buf4;
+
+    c = (u4)crc;
+    c = ~c;
+    while (len && ((ptrdiff_t)buf & 3)) {
+        c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
+        len--;
+    }
+
+    buf4 = (const u4 FAR *)(const void FAR *)buf;
+    while (len >= 32) {
+        DOLIT32;
+        len -= 32;
+    }
+    while (len >= 4) {
+        DOLIT4;
+        len -= 4;
+    }
+    buf = (const unsigned char FAR *)buf4;
+
+    if (len) do {
+        c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
+    } while (--len);
+    c = ~c;
+    return (unsigned long)c;
+}
+
+/* ========================================================================= */
+#define DOBIG4 c ^= *++buf4; \
+        c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
+            crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
+#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
+
+/* ========================================================================= */
+local unsigned long crc32_big(crc, buf, len)
+    unsigned long crc;
+    const unsigned char FAR *buf;
+    unsigned len;
+{
+    register u4 c;
+    register const u4 FAR *buf4;
+
+    c = REV((u4)crc);
+    c = ~c;
+    while (len && ((ptrdiff_t)buf & 3)) {
+        c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
+        len--;
+    }
+
+    buf4 = (const u4 FAR *)(const void FAR *)buf;
+    buf4--;
+    while (len >= 32) {
+        DOBIG32;
+        len -= 32;
+    }
+    while (len >= 4) {
+        DOBIG4;
+        len -= 4;
+    }
+    buf4++;
+    buf = (const unsigned char FAR *)buf4;
+
+    if (len) do {
+        c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
+    } while (--len);
+    c = ~c;
+    return (unsigned long)(REV(c));
+}
+
+#endif /* BYFOUR */
+
+#define GF2_DIM 32      /* dimension of GF(2) vectors (length of CRC) */
+
+/* ========================================================================= */
+local unsigned long gf2_matrix_times(mat, vec)
+    unsigned long *mat;
+    unsigned long vec;
+{
+    unsigned long sum;
+
+    sum = 0;
+    while (vec) {
+        if (vec & 1)
+            sum ^= *mat;
+        vec >>= 1;
+        mat++;
+    }
+    return sum;
+}
+
+/* ========================================================================= */
+local void gf2_matrix_square(square, mat)
+    unsigned long *square;
+    unsigned long *mat;
+{
+    int n;
+
+    for (n = 0; n < GF2_DIM; n++)
+        square[n] = gf2_matrix_times(mat, mat[n]);
+}
+
+/* ========================================================================= */
+uLong ZEXPORT crc32_combine(crc1, crc2, len2)
+    uLong crc1;
+    uLong crc2;
+    z_off_t len2;
+{
+    int n;
+    unsigned long row;
+    unsigned long even[GF2_DIM];    /* even-power-of-two zeros operator */
+    unsigned long odd[GF2_DIM];     /* odd-power-of-two zeros operator */
+
+    /* degenerate case */
+    if (len2 == 0)
+        return crc1;
+
+    /* put operator for one zero bit in odd */
+    odd[0] = 0xedb88320L;           /* CRC-32 polynomial */
+    row = 1;
+    for (n = 1; n < GF2_DIM; n++) {
+        odd[n] = row;
+        row <<= 1;
+    }
+
+    /* put operator for two zero bits in even */
+    gf2_matrix_square(even, odd);
+
+    /* put operator for four zero bits in odd */
+    gf2_matrix_square(odd, even);
+
+    /* apply len2 zeros to crc1 (first square will put the operator for one
+       zero byte, eight zero bits, in even) */
+    do {
+        /* apply zeros operator for this bit of len2 */
+        gf2_matrix_square(even, odd);
+        if (len2 & 1)
+            crc1 = gf2_matrix_times(even, crc1);
+        len2 >>= 1;
+
+        /* if no more bits set, then done */
+        if (len2 == 0)
+            break;
+
+        /* another iteration of the loop with odd and even swapped */
+        gf2_matrix_square(odd, even);
+        if (len2 & 1)
+            crc1 = gf2_matrix_times(odd, crc1);
+        len2 >>= 1;
+
+        /* if no more bits set, then done */
+    } while (len2 != 0);
+
+    /* return combined crc */
+    crc1 ^= crc2;
+    return crc1;
+}

Added: vendor/Python/current/Modules/zlib/crc32.h
===================================================================
--- vendor/Python/current/Modules/zlib/crc32.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/zlib/crc32.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,441 @@
+/* crc32.h -- tables for rapid CRC calculation
+ * Generated automatically by crc32.c
+ */
+
+local const unsigned long FAR crc_table[TBLS][256] =
+{
+  {
+    0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
+    0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,
+    0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,
+    0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,
+    0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,
+    0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,
+    0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,
+    0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,
+    0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,
+    0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,
+    0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,
+    0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,
+    0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,
+    0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,
+    0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,
+    0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,
+    0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,
+    0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,
+    0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,
+    0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,
+    0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,
+    0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,
+    0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,
+    0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,
+    0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,
+    0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,
+    0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,
+    0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,
+    0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,
+    0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,
+    0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,
+    0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,
+    0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,
+    0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,
+    0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,
+    0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,
+    0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,
+    0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,
+    0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,
+    0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,
+    0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,
+    0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,
+    0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,
+    0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,
+    0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,
+    0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,
+    0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,
+    0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,
+    0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,
+    0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,
+    0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
+    0x2d02ef8dUL
+#ifdef BYFOUR
+  },
+  {
+    0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL,
+    0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL,
+    0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL,
+    0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL,
+    0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL,
+    0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL,
+    0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL,
+    0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL,
+    0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL,
+    0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL,
+    0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL,
+    0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL,
+    0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL,
+    0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL,
+    0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL,
+    0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL,
+    0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL,
+    0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL,
+    0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL,
+    0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL,
+    0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL,
+    0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL,
+    0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL,
+    0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL,
+    0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL,
+    0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL,
+    0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL,
+    0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL,
+    0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL,
+    0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL,
+    0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL,
+    0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL,
+    0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL,
+    0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL,
+    0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL,
+    0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL,
+    0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL,
+    0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL,
+    0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL,
+    0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL,
+    0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL,
+    0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL,
+    0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL,
+    0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL,
+    0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL,
+    0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL,
+    0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL,
+    0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL,
+    0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL,
+    0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL,
+    0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL,
+    0x9324fd72UL
+  },
+  {
+    0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL,
+    0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL,
+    0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL,
+    0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL,
+    0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL,
+    0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL,
+    0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL,
+    0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL,
+    0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL,
+    0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL,
+    0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL,
+    0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL,
+    0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL,
+    0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL,
+    0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL,
+    0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL,
+    0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL,
+    0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL,
+    0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL,
+    0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL,
+    0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL,
+    0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL,
+    0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL,
+    0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL,
+    0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL,
+    0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL,
+    0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL,
+    0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL,
+    0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL,
+    0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL,
+    0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL,
+    0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL,
+    0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL,
+    0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL,
+    0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL,
+    0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL,
+    0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL,
+    0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL,
+    0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL,
+    0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL,
+    0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL,
+    0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL,
+    0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL,
+    0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL,
+    0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL,
+    0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL,
+    0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL,
+    0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL,
+    0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL,
+    0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL,
+    0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL,
+    0xbe9834edUL
+  },
+  {
+    0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL,
+    0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL,
+    0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL,
+    0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL,
+    0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL,
+    0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL,
+    0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL,
+    0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL,
+    0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL,
+    0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL,
+    0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL,
+    0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL,
+    0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL,
+    0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL,
+    0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL,
+    0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL,
+    0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL,
+    0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL,
+    0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL,
+    0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL,
+    0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL,
+    0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL,
+    0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL,
+    0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL,
+    0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL,
+    0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL,
+    0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL,
+    0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL,
+    0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL,
+    0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL,
+    0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL,
+    0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL,
+    0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL,
+    0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL,
+    0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL,
+    0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL,
+    0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL,
+    0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL,
+    0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL,
+    0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL,
+    0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL,
+    0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL,
+    0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL,
+    0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL,
+    0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL,
+    0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL,
+    0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL,
+    0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL,
+    0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL,
+    0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL,
+    0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL,
+    0xde0506f1UL
+  },
+  {
+    0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL,
+    0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL,
+    0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL,
+    0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL,
+    0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL,
+    0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL,
+    0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL,
+    0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL,
+    0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL,
+    0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL,
+    0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL,
+    0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL,
+    0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL,
+    0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL,
+    0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL,
+    0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL,
+    0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL,
+    0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL,
+    0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL,
+    0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL,
+    0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL,
+    0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL,
+    0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL,
+    0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL,
+    0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL,
+    0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL,
+    0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL,
+    0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL,
+    0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL,
+    0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL,
+    0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL,
+    0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL,
+    0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL,
+    0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL,
+    0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL,
+    0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL,
+    0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL,
+    0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL,
+    0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL,
+    0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL,
+    0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL,
+    0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL,
+    0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL,
+    0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL,
+    0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL,
+    0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL,
+    0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL,
+    0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL,
+    0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL,
+    0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL,
+    0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL,
+    0x8def022dUL
+  },
+  {
+    0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL,
+    0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL,
+    0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL,
+    0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL,
+    0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL,
+    0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL,
+    0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL,
+    0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL,
+    0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL,
+    0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL,
+    0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL,
+    0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL,
+    0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL,
+    0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL,
+    0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL,
+    0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL,
+    0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL,
+    0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL,
+    0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL,
+    0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL,
+    0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL,
+    0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL,
+    0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL,
+    0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL,
+    0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL,
+    0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL,
+    0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL,
+    0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL,
+    0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL,
+    0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL,
+    0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL,
+    0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL,
+    0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL,
+    0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL,
+    0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL,
+    0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL,
+    0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL,
+    0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL,
+    0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL,
+    0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL,
+    0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL,
+    0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL,
+    0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL,
+    0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL,
+    0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL,
+    0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL,
+    0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL,
+    0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL,
+    0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL,
+    0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL,
+    0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL,
+    0x72fd2493UL
+  },
+  {
+    0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL,
+    0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL,
+    0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL,
+    0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL,
+    0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL,
+    0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL,
+    0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL,
+    0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL,
+    0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL,
+    0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL,
+    0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL,
+    0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL,
+    0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL,
+    0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL,
+    0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL,
+    0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL,
+    0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL,
+    0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL,
+    0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL,
+    0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL,
+    0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL,
+    0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL,
+    0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL,
+    0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL,
+    0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL,
+    0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL,
+    0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL,
+    0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL,
+    0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL,
+    0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL,
+    0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL,
+    0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL,
+    0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL,
+    0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL,
+    0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL,
+    0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL,
+    0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL,
+    0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL,
+    0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL,
+    0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL,
+    0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL,
+    0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL,
+    0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL,
+    0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL,
+    0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL,
+    0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL,
+    0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL,
+    0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL,
+    0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL,
+    0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL,
+    0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL,
+    0xed3498beUL
+  },
+  {
+    0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL,
+    0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL,
+    0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL,
+    0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL,
+    0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL,
+    0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL,
+    0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL,
+    0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL,
+    0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL,
+    0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL,
+    0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL,
+    0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL,
+    0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL,
+    0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL,
+    0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL,
+    0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL,
+    0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL,
+    0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL,
+    0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL,
+    0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL,
+    0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL,
+    0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL,
+    0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL,
+    0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL,
+    0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL,
+    0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL,
+    0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL,
+    0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL,
+    0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL,
+    0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL,
+    0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL,
+    0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL,
+    0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL,
+    0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL,
+    0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL,
+    0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL,
+    0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL,
+    0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL,
+    0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL,
+    0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL,
+    0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL,
+    0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL,
+    0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL,
+    0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL,
+    0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL,
+    0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL,
+    0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL,
+    0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL,
+    0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL,
+    0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL,
+    0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL,
+    0xf10605deUL
+#endif
+  }
+};

Added: vendor/Python/current/Modules/zlib/deflate.c
===================================================================
--- vendor/Python/current/Modules/zlib/deflate.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/zlib/deflate.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1736 @@
+/* deflate.c -- compress data using the deflation algorithm
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ *  ALGORITHM
+ *
+ *      The "deflation" process depends on being able to identify portions
+ *      of the input text which are identical to earlier input (within a
+ *      sliding window trailing behind the input currently being processed).
+ *
+ *      The most straightforward technique turns out to be the fastest for
+ *      most input files: try all possible matches and select the longest.
+ *      The key feature of this algorithm is that insertions into the string
+ *      dictionary are very simple and thus fast, and deletions are avoided
+ *      completely. Insertions are performed at each input character, whereas
+ *      string matches are performed only when the previous match ends. So it
+ *      is preferable to spend more time in matches to allow very fast string
+ *      insertions and avoid deletions. The matching algorithm for small
+ *      strings is inspired from that of Rabin & Karp. A brute force approach
+ *      is used to find longer strings when a small match has been found.
+ *      A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
+ *      (by Leonid Broukhis).
+ *         A previous version of this file used a more sophisticated algorithm
+ *      (by Fiala and Greene) which is guaranteed to run in linear amortized
+ *      time, but has a larger average cost, uses more memory and is patented.
+ *      However the F&G algorithm may be faster for some highly redundant
+ *      files if the parameter max_chain_length (described below) is too large.
+ *
+ *  ACKNOWLEDGEMENTS
+ *
+ *      The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
+ *      I found it in 'freeze' written by Leonid Broukhis.
+ *      Thanks to many people for bug reports and testing.
+ *
+ *  REFERENCES
+ *
+ *      Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
+ *      Available in http://www.ietf.org/rfc/rfc1951.txt
+ *
+ *      A description of the Rabin and Karp algorithm is given in the book
+ *         "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
+ *
+ *      Fiala,E.R., and Greene,D.H.
+ *         Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
+ *
+ */
+
+/* @(#) $Id$ */
+
+#include "deflate.h"
+
+const char deflate_copyright[] =
+   " deflate 1.2.3 Copyright 1995-2005 Jean-loup Gailly ";
+/*
+  If you use the zlib library in a product, an acknowledgment is welcome
+  in the documentation of your product. If for some reason you cannot
+  include such an acknowledgment, I would appreciate that you keep this
+  copyright string in the executable of your product.
+ */
+
+/* ===========================================================================
+ *  Function prototypes.
+ */
+typedef enum {
+    need_more,      /* block not completed, need more input or more output */
+    block_done,     /* block flush performed */
+    finish_started, /* finish started, need only more output at next deflate */
+    finish_done     /* finish done, accept no more input or output */
+} block_state;
+
+typedef block_state (*compress_func) OF((deflate_state *s, int flush));
+/* Compression function. Returns the block state after the call. */
+
+local void fill_window    OF((deflate_state *s));
+local block_state deflate_stored OF((deflate_state *s, int flush));
+local block_state deflate_fast   OF((deflate_state *s, int flush));
+#ifndef FASTEST
+local block_state deflate_slow   OF((deflate_state *s, int flush));
+#endif
+local void lm_init        OF((deflate_state *s));
+local void putShortMSB    OF((deflate_state *s, uInt b));
+local void flush_pending  OF((z_streamp strm));
+local int read_buf        OF((z_streamp strm, Bytef *buf, unsigned size));
+#ifndef FASTEST
+#ifdef ASMV
+      void match_init OF((void)); /* asm code initialization */
+      uInt longest_match  OF((deflate_state *s, IPos cur_match));
+#else
+local uInt longest_match  OF((deflate_state *s, IPos cur_match));
+#endif
+#endif
+local uInt longest_match_fast OF((deflate_state *s, IPos cur_match));
+
+#ifdef DEBUG
+local  void check_match OF((deflate_state *s, IPos start, IPos match,
+                            int length));
+#endif
+
+/* ===========================================================================
+ * Local data
+ */
+
+#define NIL 0
+/* Tail of hash chains */
+
+#ifndef TOO_FAR
+#  define TOO_FAR 4096
+#endif
+/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
+
+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
+/* Minimum amount of lookahead, except at the end of the input file.
+ * See deflate.c for comments about the MIN_MATCH+1.
+ */
+
+/* Values for max_lazy_match, good_match and max_chain_length, depending on
+ * the desired pack level (0..9). The values given below have been tuned to
+ * exclude worst case performance for pathological files. Better values may be
+ * found for specific files.
+ */
+typedef struct config_s {
+   ush good_length; /* reduce lazy search above this match length */
+   ush max_lazy;    /* do not perform lazy search above this match length */
+   ush nice_length; /* quit search above this match length */
+   ush max_chain;
+   compress_func func;
+} config;
+
+#ifdef FASTEST
+local const config configuration_table[2] = {
+/*      good lazy nice chain */
+/* 0 */ {0,    0,  0,    0, deflate_stored},  /* store only */
+/* 1 */ {4,    4,  8,    4, deflate_fast}}; /* max speed, no lazy matches */
+#else
+local const config configuration_table[10] = {
+/*      good lazy nice chain */
+/* 0 */ {0,    0,  0,    0, deflate_stored},  /* store only */
+/* 1 */ {4,    4,  8,    4, deflate_fast}, /* max speed, no lazy matches */
+/* 2 */ {4,    5, 16,    8, deflate_fast},
+/* 3 */ {4,    6, 32,   32, deflate_fast},
+
+/* 4 */ {4,    4, 16,   16, deflate_slow},  /* lazy matches */
+/* 5 */ {8,   16, 32,   32, deflate_slow},
+/* 6 */ {8,   16, 128, 128, deflate_slow},
+/* 7 */ {8,   32, 128, 256, deflate_slow},
+/* 8 */ {32, 128, 258, 1024, deflate_slow},
+/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */
+#endif
+
+/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
+ * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
+ * meaning.
+ */
+
+#define EQUAL 0
+/* result of memcmp for equal strings */
+
+#ifndef NO_DUMMY_DECL
+struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
+#endif
+
+/* ===========================================================================
+ * Update a hash value with the given input byte
+ * IN  assertion: all calls to to UPDATE_HASH are made with consecutive
+ *    input characters, so that a running hash key can be computed from the
+ *    previous key instead of complete recalculation each time.
+ */
+#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
+
+
+/* ===========================================================================
+ * Insert string str in the dictionary and set match_head to the previous head
+ * of the hash chain (the most recent string with same hash key). Return
+ * the previous length of the hash chain.
+ * If this file is compiled with -DFASTEST, the compression level is forced
+ * to 1, and no hash chains are maintained.
+ * IN  assertion: all calls to to INSERT_STRING are made with consecutive
+ *    input characters and the first MIN_MATCH bytes of str are valid
+ *    (except for the last MIN_MATCH-1 bytes of the input file).
+ */
+#ifdef FASTEST
+#define INSERT_STRING(s, str, match_head) \
+   (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
+    match_head = s->head[s->ins_h], \
+    s->head[s->ins_h] = (Pos)(str))
+#else
+#define INSERT_STRING(s, str, match_head) \
+   (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
+    match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \
+    s->head[s->ins_h] = (Pos)(str))
+#endif
+
+/* ===========================================================================
+ * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
+ * prev[] will be initialized on the fly.
+ */
+#define CLEAR_HASH(s) \
+    s->head[s->hash_size-1] = NIL; \
+    zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
+
+/* ========================================================================= */
+int ZEXPORT deflateInit_(strm, level, version, stream_size)
+    z_streamp strm;
+    int level;
+    const char *version;
+    int stream_size;
+{
+    return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
+                         Z_DEFAULT_STRATEGY, version, stream_size);
+    /* To do: ignore strm->next_in if we use it as window */
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
+                  version, stream_size)
+    z_streamp strm;
+    int  level;
+    int  method;
+    int  windowBits;
+    int  memLevel;
+    int  strategy;
+    const char *version;
+    int stream_size;
+{
+    deflate_state *s;
+    int wrap = 1;
+    static const char my_version[] = ZLIB_VERSION;
+
+    ushf *overlay;
+    /* We overlay pending_buf and d_buf+l_buf. This works since the average
+     * output size for (length,distance) codes is <= 24 bits.
+     */
+
+    if (version == Z_NULL || version[0] != my_version[0] ||
+        stream_size != sizeof(z_stream)) {
+        return Z_VERSION_ERROR;
+    }
+    if (strm == Z_NULL) return Z_STREAM_ERROR;
+
+    strm->msg = Z_NULL;
+    if (strm->zalloc == (alloc_func)0) {
+        strm->zalloc = zcalloc;
+        strm->opaque = (voidpf)0;
+    }
+    if (strm->zfree == (free_func)0) strm->zfree = zcfree;
+
+#ifdef FASTEST
+    if (level != 0) level = 1;
+#else
+    if (level == Z_DEFAULT_COMPRESSION) level = 6;
+#endif
+
+    if (windowBits < 0) { /* suppress zlib wrapper */
+        wrap = 0;
+        windowBits = -windowBits;
+    }
+#ifdef GZIP
+    else if (windowBits > 15) {
+        wrap = 2;       /* write gzip wrapper instead */
+        windowBits -= 16;
+    }
+#endif
+    if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
+        windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
+        strategy < 0 || strategy > Z_FIXED) {
+        return Z_STREAM_ERROR;
+    }
+    if (windowBits == 8) windowBits = 9;  /* until 256-byte window bug fixed */
+    s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
+    if (s == Z_NULL) return Z_MEM_ERROR;
+    strm->state = (struct internal_state FAR *)s;
+    s->strm = strm;
+
+    s->wrap = wrap;
+    s->gzhead = Z_NULL;
+    s->w_bits = windowBits;
+    s->w_size = 1 << s->w_bits;
+    s->w_mask = s->w_size - 1;
+
+    s->hash_bits = memLevel + 7;
+    s->hash_size = 1 << s->hash_bits;
+    s->hash_mask = s->hash_size - 1;
+    s->hash_shift =  ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
+
+    s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
+    s->prev   = (Posf *)  ZALLOC(strm, s->w_size, sizeof(Pos));
+    s->head   = (Posf *)  ZALLOC(strm, s->hash_size, sizeof(Pos));
+
+    s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
+
+    overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
+    s->pending_buf = (uchf *) overlay;
+    s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
+
+    if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
+        s->pending_buf == Z_NULL) {
+        s->status = FINISH_STATE;
+        strm->msg = (char*)ERR_MSG(Z_MEM_ERROR);
+        deflateEnd (strm);
+        return Z_MEM_ERROR;
+    }
+    s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
+    s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
+
+    s->level = level;
+    s->strategy = strategy;
+    s->method = (Byte)method;
+
+    return deflateReset(strm);
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
+    z_streamp strm;
+    const Bytef *dictionary;
+    uInt  dictLength;
+{
+    deflate_state *s;
+    uInt length = dictLength;
+    uInt n;
+    IPos hash_head = 0;
+
+    if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
+        strm->state->wrap == 2 ||
+        (strm->state->wrap == 1 && strm->state->status != INIT_STATE))
+        return Z_STREAM_ERROR;
+
+    s = strm->state;
+    if (s->wrap)
+        strm->adler = adler32(strm->adler, dictionary, dictLength);
+
+    if (length < MIN_MATCH) return Z_OK;
+    if (length > MAX_DIST(s)) {
+        length = MAX_DIST(s);
+        dictionary += dictLength - length; /* use the tail of the dictionary */
+    }
+    zmemcpy(s->window, dictionary, length);
+    s->strstart = length;
+    s->block_start = (long)length;
+
+    /* Insert all strings in the hash table (except for the last two bytes).
+     * s->lookahead stays null, so s->ins_h will be recomputed at the next
+     * call of fill_window.
+     */
+    s->ins_h = s->window[0];
+    UPDATE_HASH(s, s->ins_h, s->window[1]);
+    for (n = 0; n <= length - MIN_MATCH; n++) {
+        INSERT_STRING(s, n, hash_head);
+    }
+    if (hash_head) hash_head = 0;  /* to make compiler happy */
+    return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateReset (strm)
+    z_streamp strm;
+{
+    deflate_state *s;
+
+    if (strm == Z_NULL || strm->state == Z_NULL ||
+        strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) {
+        return Z_STREAM_ERROR;
+    }
+
+    strm->total_in = strm->total_out = 0;
+    strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
+    strm->data_type = Z_UNKNOWN;
+
+    s = (deflate_state *)strm->state;
+    s->pending = 0;
+    s->pending_out = s->pending_buf;
+
+    if (s->wrap < 0) {
+        s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */
+    }
+    s->status = s->wrap ? INIT_STATE : BUSY_STATE;
+    strm->adler =
+#ifdef GZIP
+        s->wrap == 2 ? crc32(0L, Z_NULL, 0) :
+#endif
+        adler32(0L, Z_NULL, 0);
+    s->last_flush = Z_NO_FLUSH;
+
+    _tr_init(s);
+    lm_init(s);
+
+    return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateSetHeader (strm, head)
+    z_streamp strm;
+    gz_headerp head;
+{
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    if (strm->state->wrap != 2) return Z_STREAM_ERROR;
+    strm->state->gzhead = head;
+    return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflatePrime (strm, bits, value)
+    z_streamp strm;
+    int bits;
+    int value;
+{
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    strm->state->bi_valid = bits;
+    strm->state->bi_buf = (ush)(value & ((1 << bits) - 1));
+    return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateParams(strm, level, strategy)
+    z_streamp strm;
+    int level;
+    int strategy;
+{
+    deflate_state *s;
+    compress_func func;
+    int err = Z_OK;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    s = strm->state;
+
+#ifdef FASTEST
+    if (level != 0) level = 1;
+#else
+    if (level == Z_DEFAULT_COMPRESSION) level = 6;
+#endif
+    if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) {
+        return Z_STREAM_ERROR;
+    }
+    func = configuration_table[s->level].func;
+
+    if (func != configuration_table[level].func && strm->total_in != 0) {
+        /* Flush the last buffer: */
+        err = deflate(strm, Z_PARTIAL_FLUSH);
+    }
+    if (s->level != level) {
+        s->level = level;
+        s->max_lazy_match   = configuration_table[level].max_lazy;
+        s->good_match       = configuration_table[level].good_length;
+        s->nice_match       = configuration_table[level].nice_length;
+        s->max_chain_length = configuration_table[level].max_chain;
+    }
+    s->strategy = strategy;
+    return err;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain)
+    z_streamp strm;
+    int good_length;
+    int max_lazy;
+    int nice_length;
+    int max_chain;
+{
+    deflate_state *s;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    s = strm->state;
+    s->good_match = good_length;
+    s->max_lazy_match = max_lazy;
+    s->nice_match = nice_length;
+    s->max_chain_length = max_chain;
+    return Z_OK;
+}
+
+/* =========================================================================
+ * For the default windowBits of 15 and memLevel of 8, this function returns
+ * a close to exact, as well as small, upper bound on the compressed size.
+ * They are coded as constants here for a reason--if the #define's are
+ * changed, then this function needs to be changed as well.  The return
+ * value for 15 and 8 only works for those exact settings.
+ *
+ * For any setting other than those defaults for windowBits and memLevel,
+ * the value returned is a conservative worst case for the maximum expansion
+ * resulting from using fixed blocks instead of stored blocks, which deflate
+ * can emit on compressed data for some combinations of the parameters.
+ *
+ * This function could be more sophisticated to provide closer upper bounds
+ * for every combination of windowBits and memLevel, as well as wrap.
+ * But even the conservative upper bound of about 14% expansion does not
+ * seem onerous for output buffer allocation.
+ */
+uLong ZEXPORT deflateBound(strm, sourceLen)
+    z_streamp strm;
+    uLong sourceLen;
+{
+    deflate_state *s;
+    uLong destLen;
+
+    /* conservative upper bound */
+    destLen = sourceLen +
+              ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 11;
+
+    /* if can't get parameters, return conservative bound */
+    if (strm == Z_NULL || strm->state == Z_NULL)
+        return destLen;
+
+    /* if not default parameters, return conservative bound */
+    s = strm->state;
+    if (s->w_bits != 15 || s->hash_bits != 8 + 7)
+        return destLen;
+
+    /* default settings: return tight bound for that case */
+    return compressBound(sourceLen);
+}
+
+/* =========================================================================
+ * Put a short in the pending buffer. The 16-bit value is put in MSB order.
+ * IN assertion: the stream state is correct and there is enough room in
+ * pending_buf.
+ */
+local void putShortMSB (s, b)
+    deflate_state *s;
+    uInt b;
+{
+    put_byte(s, (Byte)(b >> 8));
+    put_byte(s, (Byte)(b & 0xff));
+}
+
+/* =========================================================================
+ * Flush as much pending output as possible. All deflate() output goes
+ * through this function so some applications may wish to modify it
+ * to avoid allocating a large strm->next_out buffer and copying into it.
+ * (See also read_buf()).
+ */
+local void flush_pending(strm)
+    z_streamp strm;
+{
+    unsigned len = strm->state->pending;
+
+    if (len > strm->avail_out) len = strm->avail_out;
+    if (len == 0) return;
+
+    zmemcpy(strm->next_out, strm->state->pending_out, len);
+    strm->next_out  += len;
+    strm->state->pending_out  += len;
+    strm->total_out += len;
+    strm->avail_out  -= len;
+    strm->state->pending -= len;
+    if (strm->state->pending == 0) {
+        strm->state->pending_out = strm->state->pending_buf;
+    }
+}
+
+/* ========================================================================= */
+int ZEXPORT deflate (strm, flush)
+    z_streamp strm;
+    int flush;
+{
+    int old_flush; /* value of flush param for previous deflate call */
+    deflate_state *s;
+
+    if (strm == Z_NULL || strm->state == Z_NULL ||
+        flush > Z_FINISH || flush < 0) {
+        return Z_STREAM_ERROR;
+    }
+    s = strm->state;
+
+    if (strm->next_out == Z_NULL ||
+        (strm->next_in == Z_NULL && strm->avail_in != 0) ||
+        (s->status == FINISH_STATE && flush != Z_FINISH)) {
+        ERR_RETURN(strm, Z_STREAM_ERROR);
+    }
+    if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
+
+    s->strm = strm; /* just in case */
+    old_flush = s->last_flush;
+    s->last_flush = flush;
+
+    /* Write the header */
+    if (s->status == INIT_STATE) {
+#ifdef GZIP
+        if (s->wrap == 2) {
+            strm->adler = crc32(0L, Z_NULL, 0);
+            put_byte(s, 31);
+            put_byte(s, 139);
+            put_byte(s, 8);
+            if (s->gzhead == NULL) {
+                put_byte(s, 0);
+                put_byte(s, 0);
+                put_byte(s, 0);
+                put_byte(s, 0);
+                put_byte(s, 0);
+                put_byte(s, s->level == 9 ? 2 :
+                            (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
+                             4 : 0));
+                put_byte(s, OS_CODE);
+                s->status = BUSY_STATE;
+            }
+            else {
+                put_byte(s, (s->gzhead->text ? 1 : 0) +
+                            (s->gzhead->hcrc ? 2 : 0) +
+                            (s->gzhead->extra == Z_NULL ? 0 : 4) +
+                            (s->gzhead->name == Z_NULL ? 0 : 8) +
+                            (s->gzhead->comment == Z_NULL ? 0 : 16)
+                        );
+                put_byte(s, (Byte)(s->gzhead->time & 0xff));
+                put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff));
+                put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff));
+                put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff));
+                put_byte(s, s->level == 9 ? 2 :
+                            (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
+                             4 : 0));
+                put_byte(s, s->gzhead->os & 0xff);
+                if (s->gzhead->extra != NULL) {
+                    put_byte(s, s->gzhead->extra_len & 0xff);
+                    put_byte(s, (s->gzhead->extra_len >> 8) & 0xff);
+                }
+                if (s->gzhead->hcrc)
+                    strm->adler = crc32(strm->adler, s->pending_buf,
+                                        s->pending);
+                s->gzindex = 0;
+                s->status = EXTRA_STATE;
+            }
+        }
+        else
+#endif
+        {
+            uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
+            uInt level_flags;
+
+            if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2)
+                level_flags = 0;
+            else if (s->level < 6)
+                level_flags = 1;
+            else if (s->level == 6)
+                level_flags = 2;
+            else
+                level_flags = 3;
+            header |= (level_flags << 6);
+            if (s->strstart != 0) header |= PRESET_DICT;
+            header += 31 - (header % 31);
+
+            s->status = BUSY_STATE;
+            putShortMSB(s, header);
+
+            /* Save the adler32 of the preset dictionary: */
+            if (s->strstart != 0) {
+                putShortMSB(s, (uInt)(strm->adler >> 16));
+                putShortMSB(s, (uInt)(strm->adler & 0xffff));
+            }
+            strm->adler = adler32(0L, Z_NULL, 0);
+        }
+    }
+#ifdef GZIP
+    if (s->status == EXTRA_STATE) {
+        if (s->gzhead->extra != NULL) {
+            uInt beg = s->pending;  /* start of bytes to update crc */
+
+            while (s->gzindex < (s->gzhead->extra_len & 0xffff)) {
+                if (s->pending == s->pending_buf_size) {
+                    if (s->gzhead->hcrc && s->pending > beg)
+                        strm->adler = crc32(strm->adler, s->pending_buf + beg,
+                                            s->pending - beg);
+                    flush_pending(strm);
+                    beg = s->pending;
+                    if (s->pending == s->pending_buf_size)
+                        break;
+                }
+                put_byte(s, s->gzhead->extra[s->gzindex]);
+                s->gzindex++;
+            }
+            if (s->gzhead->hcrc && s->pending > beg)
+                strm->adler = crc32(strm->adler, s->pending_buf + beg,
+                                    s->pending - beg);
+            if (s->gzindex == s->gzhead->extra_len) {
+                s->gzindex = 0;
+                s->status = NAME_STATE;
+            }
+        }
+        else
+            s->status = NAME_STATE;
+    }
+    if (s->status == NAME_STATE) {
+        if (s->gzhead->name != NULL) {
+            uInt beg = s->pending;  /* start of bytes to update crc */
+            int val;
+
+            do {
+                if (s->pending == s->pending_buf_size) {
+                    if (s->gzhead->hcrc && s->pending > beg)
+                        strm->adler = crc32(strm->adler, s->pending_buf + beg,
+                                            s->pending - beg);
+                    flush_pending(strm);
+                    beg = s->pending;
+                    if (s->pending == s->pending_buf_size) {
+                        val = 1;
+                        break;
+                    }
+                }
+                val = s->gzhead->name[s->gzindex++];
+                put_byte(s, val);
+            } while (val != 0);
+            if (s->gzhead->hcrc && s->pending > beg)
+                strm->adler = crc32(strm->adler, s->pending_buf + beg,
+                                    s->pending - beg);
+            if (val == 0) {
+                s->gzindex = 0;
+                s->status = COMMENT_STATE;
+            }
+        }
+        else
+            s->status = COMMENT_STATE;
+    }
+    if (s->status == COMMENT_STATE) {
+        if (s->gzhead->comment != NULL) {
+            uInt beg = s->pending;  /* start of bytes to update crc */
+            int val;
+
+            do {
+                if (s->pending == s->pending_buf_size) {
+                    if (s->gzhead->hcrc && s->pending > beg)
+                        strm->adler = crc32(strm->adler, s->pending_buf + beg,
+                                            s->pending - beg);
+                    flush_pending(strm);
+                    beg = s->pending;
+                    if (s->pending == s->pending_buf_size) {
+                        val = 1;
+                        break;
+                    }
+                }
+                val = s->gzhead->comment[s->gzindex++];
+                put_byte(s, val);
+            } while (val != 0);
+            if (s->gzhead->hcrc && s->pending > beg)
+                strm->adler = crc32(strm->adler, s->pending_buf + beg,
+                                    s->pending - beg);
+            if (val == 0)
+                s->status = HCRC_STATE;
+        }
+        else
+            s->status = HCRC_STATE;
+    }
+    if (s->status == HCRC_STATE) {
+        if (s->gzhead->hcrc) {
+            if (s->pending + 2 > s->pending_buf_size)
+                flush_pending(strm);
+            if (s->pending + 2 <= s->pending_buf_size) {
+                put_byte(s, (Byte)(strm->adler & 0xff));
+                put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
+                strm->adler = crc32(0L, Z_NULL, 0);
+                s->status = BUSY_STATE;
+            }
+        }
+        else
+            s->status = BUSY_STATE;
+    }
+#endif
+
+    /* Flush as much pending output as possible */
+    if (s->pending != 0) {
+        flush_pending(strm);
+        if (strm->avail_out == 0) {
+            /* Since avail_out is 0, deflate will be called again with
+             * more output space, but possibly with both pending and
+             * avail_in equal to zero. There won't be anything to do,
+             * but this is not an error situation so make sure we
+             * return OK instead of BUF_ERROR at next call of deflate:
+             */
+            s->last_flush = -1;
+            return Z_OK;
+        }
+
+    /* Make sure there is something to do and avoid duplicate consecutive
+     * flushes. For repeated and useless calls with Z_FINISH, we keep
+     * returning Z_STREAM_END instead of Z_BUF_ERROR.
+     */
+    } else if (strm->avail_in == 0 && flush <= old_flush &&
+               flush != Z_FINISH) {
+        ERR_RETURN(strm, Z_BUF_ERROR);
+    }
+
+    /* User must not provide more input after the first FINISH: */
+    if (s->status == FINISH_STATE && strm->avail_in != 0) {
+        ERR_RETURN(strm, Z_BUF_ERROR);
+    }
+
+    /* Start a new block or continue the current one.
+     */
+    if (strm->avail_in != 0 || s->lookahead != 0 ||
+        (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
+        block_state bstate;
+
+        bstate = (*(configuration_table[s->level].func))(s, flush);
+
+        if (bstate == finish_started || bstate == finish_done) {
+            s->status = FINISH_STATE;
+        }
+        if (bstate == need_more || bstate == finish_started) {
+            if (strm->avail_out == 0) {
+                s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
+            }
+            return Z_OK;
+            /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
+             * of deflate should use the same flush parameter to make sure
+             * that the flush is complete. So we don't have to output an
+             * empty block here, this will be done at next call. This also
+             * ensures that for a very small output buffer, we emit at most
+             * one empty block.
+             */
+        }
+        if (bstate == block_done) {
+            if (flush == Z_PARTIAL_FLUSH) {
+                _tr_align(s);
+            } else { /* FULL_FLUSH or SYNC_FLUSH */
+                _tr_stored_block(s, (char*)0, 0L, 0);
+                /* For a full flush, this empty block will be recognized
+                 * as a special marker by inflate_sync().
+                 */
+                if (flush == Z_FULL_FLUSH) {
+                    CLEAR_HASH(s);             /* forget history */
+                }
+            }
+            flush_pending(strm);
+            if (strm->avail_out == 0) {
+              s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
+              return Z_OK;
+            }
+        }
+    }
+    Assert(strm->avail_out > 0, "bug2");
+
+    if (flush != Z_FINISH) return Z_OK;
+    if (s->wrap <= 0) return Z_STREAM_END;
+
+    /* Write the trailer */
+#ifdef GZIP
+    if (s->wrap == 2) {
+        put_byte(s, (Byte)(strm->adler & 0xff));
+        put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
+        put_byte(s, (Byte)((strm->adler >> 16) & 0xff));
+        put_byte(s, (Byte)((strm->adler >> 24) & 0xff));
+        put_byte(s, (Byte)(strm->total_in & 0xff));
+        put_byte(s, (Byte)((strm->total_in >> 8) & 0xff));
+        put_byte(s, (Byte)((strm->total_in >> 16) & 0xff));
+        put_byte(s, (Byte)((strm->total_in >> 24) & 0xff));
+    }
+    else
+#endif
+    {
+        putShortMSB(s, (uInt)(strm->adler >> 16));
+        putShortMSB(s, (uInt)(strm->adler & 0xffff));
+    }
+    flush_pending(strm);
+    /* If avail_out is zero, the application will call deflate again
+     * to flush the rest.
+     */
+    if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */
+    return s->pending != 0 ? Z_OK : Z_STREAM_END;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateEnd (strm)
+    z_streamp strm;
+{
+    int status;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+
+    status = strm->state->status;
+    if (status != INIT_STATE &&
+        status != EXTRA_STATE &&
+        status != NAME_STATE &&
+        status != COMMENT_STATE &&
+        status != HCRC_STATE &&
+        status != BUSY_STATE &&
+        status != FINISH_STATE) {
+      return Z_STREAM_ERROR;
+    }
+
+    /* Deallocate in reverse order of allocations: */
+    TRY_FREE(strm, strm->state->pending_buf);
+    TRY_FREE(strm, strm->state->head);
+    TRY_FREE(strm, strm->state->prev);
+    TRY_FREE(strm, strm->state->window);
+
+    ZFREE(strm, strm->state);
+    strm->state = Z_NULL;
+
+    return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
+}
+
+/* =========================================================================
+ * Copy the source state to the destination state.
+ * To simplify the source, this is not supported for 16-bit MSDOS (which
+ * doesn't have enough memory anyway to duplicate compression states).
+ */
+int ZEXPORT deflateCopy (dest, source)
+    z_streamp dest;
+    z_streamp source;
+{
+#ifdef MAXSEG_64K
+    return Z_STREAM_ERROR;
+#else
+    deflate_state *ds;
+    deflate_state *ss;
+    ushf *overlay;
+
+
+    if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
+        return Z_STREAM_ERROR;
+    }
+
+    ss = source->state;
+
+    zmemcpy(dest, source, sizeof(z_stream));
+
+    ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
+    if (ds == Z_NULL) return Z_MEM_ERROR;
+    dest->state = (struct internal_state FAR *) ds;
+    zmemcpy(ds, ss, sizeof(deflate_state));
+    ds->strm = dest;
+
+    ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
+    ds->prev   = (Posf *)  ZALLOC(dest, ds->w_size, sizeof(Pos));
+    ds->head   = (Posf *)  ZALLOC(dest, ds->hash_size, sizeof(Pos));
+    overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
+    ds->pending_buf = (uchf *) overlay;
+
+    if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
+        ds->pending_buf == Z_NULL) {
+        deflateEnd (dest);
+        return Z_MEM_ERROR;
+    }
+    /* following zmemcpy do not work for 16-bit MSDOS */
+    zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
+    zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
+    zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
+    zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
+
+    ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
+    ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
+    ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
+
+    ds->l_desc.dyn_tree = ds->dyn_ltree;
+    ds->d_desc.dyn_tree = ds->dyn_dtree;
+    ds->bl_desc.dyn_tree = ds->bl_tree;
+
+    return Z_OK;
+#endif /* MAXSEG_64K */
+}
+
+/* ===========================================================================
+ * Read a new buffer from the current input stream, update the adler32
+ * and total number of bytes read.  All deflate() input goes through
+ * this function so some applications may wish to modify it to avoid
+ * allocating a large strm->next_in buffer and copying from it.
+ * (See also flush_pending()).
+ */
+local int read_buf(strm, buf, size)
+    z_streamp strm;
+    Bytef *buf;
+    unsigned size;
+{
+    unsigned len = strm->avail_in;
+
+    if (len > size) len = size;
+    if (len == 0) return 0;
+
+    strm->avail_in  -= len;
+
+    if (strm->state->wrap == 1) {
+        strm->adler = adler32(strm->adler, strm->next_in, len);
+    }
+#ifdef GZIP
+    else if (strm->state->wrap == 2) {
+        strm->adler = crc32(strm->adler, strm->next_in, len);
+    }
+#endif
+    zmemcpy(buf, strm->next_in, len);
+    strm->next_in  += len;
+    strm->total_in += len;
+
+    return (int)len;
+}
+
+/* ===========================================================================
+ * Initialize the "longest match" routines for a new zlib stream
+ */
+local void lm_init (s)
+    deflate_state *s;
+{
+    s->window_size = (ulg)2L*s->w_size;
+
+    CLEAR_HASH(s);
+
+    /* Set the default configuration parameters:
+     */
+    s->max_lazy_match   = configuration_table[s->level].max_lazy;
+    s->good_match       = configuration_table[s->level].good_length;
+    s->nice_match       = configuration_table[s->level].nice_length;
+    s->max_chain_length = configuration_table[s->level].max_chain;
+
+    s->strstart = 0;
+    s->block_start = 0L;
+    s->lookahead = 0;
+    s->match_length = s->prev_length = MIN_MATCH-1;
+    s->match_available = 0;
+    s->ins_h = 0;
+#ifndef FASTEST
+#ifdef ASMV
+    match_init(); /* initialize the asm code */
+#endif
+#endif
+}
+
+#ifndef FASTEST
+/* ===========================================================================
+ * Set match_start to the longest match starting at the given string and
+ * return its length. Matches shorter or equal to prev_length are discarded,
+ * in which case the result is equal to prev_length and match_start is
+ * garbage.
+ * IN assertions: cur_match is the head of the hash chain for the current
+ *   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
+ * OUT assertion: the match length is not greater than s->lookahead.
+ */
+#ifndef ASMV
+/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
+ * match.S. The code will be functionally equivalent.
+ */
+local uInt longest_match(s, cur_match)
+    deflate_state *s;
+    IPos cur_match;                             /* current match */
+{
+    unsigned chain_length = s->max_chain_length;/* max hash chain length */
+    register Bytef *scan = s->window + s->strstart; /* current string */
+    register Bytef *match;                       /* matched string */
+    register int len;                           /* length of current match */
+    int best_len = s->prev_length;              /* best match length so far */
+    int nice_match = s->nice_match;             /* stop if match long enough */
+    IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
+        s->strstart - (IPos)MAX_DIST(s) : NIL;
+    /* Stop when cur_match becomes <= limit. To simplify the code,
+     * we prevent matches with the string of window index 0.
+     */
+    Posf *prev = s->prev;
+    uInt wmask = s->w_mask;
+
+#ifdef UNALIGNED_OK
+    /* Compare two bytes at a time. Note: this is not always beneficial.
+     * Try with and without -DUNALIGNED_OK to check.
+     */
+    register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
+    register ush scan_start = *(ushf*)scan;
+    register ush scan_end   = *(ushf*)(scan+best_len-1);
+#else
+    register Bytef *strend = s->window + s->strstart + MAX_MATCH;
+    register Byte scan_end1  = scan[best_len-1];
+    register Byte scan_end   = scan[best_len];
+#endif
+
+    /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+     * It is easy to get rid of this optimization if necessary.
+     */
+    Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
+
+    /* Do not waste too much time if we already have a good match: */
+    if (s->prev_length >= s->good_match) {
+        chain_length >>= 2;
+    }
+    /* Do not look for matches beyond the end of the input. This is necessary
+     * to make deflate deterministic.
+     */
+    if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
+
+    Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
+
+    do {
+        Assert(cur_match < s->strstart, "no future");
+        match = s->window + cur_match;
+
+        /* Skip to next match if the match length cannot increase
+         * or if the match length is less than 2.  Note that the checks below
+         * for insufficient lookahead only occur occasionally for performance
+         * reasons.  Therefore uninitialized memory will be accessed, and
+         * conditional jumps will be made that depend on those values.
+         * However the length of the match is limited to the lookahead, so
+         * the output of deflate is not affected by the uninitialized values.
+         */
+#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
+        /* This code assumes sizeof(unsigned short) == 2. Do not use
+         * UNALIGNED_OK if your compiler uses a different size.
+         */
+        if (*(ushf*)(match+best_len-1) != scan_end ||
+            *(ushf*)match != scan_start) continue;
+
+        /* It is not necessary to compare scan[2] and match[2] since they are
+         * always equal when the other bytes match, given that the hash keys
+         * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
+         * strstart+3, +5, ... up to strstart+257. We check for insufficient
+         * lookahead only every 4th comparison; the 128th check will be made
+         * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
+         * necessary to put more guard bytes at the end of the window, or
+         * to check more often for insufficient lookahead.
+         */
+        Assert(scan[2] == match[2], "scan[2]?");
+        scan++, match++;
+        do {
+        } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 scan < strend);
+        /* The funny "do {}" generates better code on most compilers */
+
+        /* Here, scan <= window+strstart+257 */
+        Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+        if (*scan == *match) scan++;
+
+        len = (MAX_MATCH - 1) - (int)(strend-scan);
+        scan = strend - (MAX_MATCH-1);
+
+#else /* UNALIGNED_OK */
+
+        if (match[best_len]   != scan_end  ||
+            match[best_len-1] != scan_end1 ||
+            *match            != *scan     ||
+            *++match          != scan[1])      continue;
+
+        /* The check at best_len-1 can be removed because it will be made
+         * again later. (This heuristic is not always a win.)
+         * It is not necessary to compare scan[2] and match[2] since they
+         * are always equal when the other bytes match, given that
+         * the hash keys are equal and that HASH_BITS >= 8.
+         */
+        scan += 2, match++;
+        Assert(*scan == *match, "match[2]?");
+
+        /* We check for insufficient lookahead only every 8th comparison;
+         * the 256th check will be made at strstart+258.
+         */
+        do {
+        } while (*++scan == *++match && *++scan == *++match &&
+                 *++scan == *++match && *++scan == *++match &&
+                 *++scan == *++match && *++scan == *++match &&
+                 *++scan == *++match && *++scan == *++match &&
+                 scan < strend);
+
+        Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+
+        len = MAX_MATCH - (int)(strend - scan);
+        scan = strend - MAX_MATCH;
+
+#endif /* UNALIGNED_OK */
+
+        if (len > best_len) {
+            s->match_start = cur_match;
+            best_len = len;
+            if (len >= nice_match) break;
+#ifdef UNALIGNED_OK
+            scan_end = *(ushf*)(scan+best_len-1);
+#else
+            scan_end1  = scan[best_len-1];
+            scan_end   = scan[best_len];
+#endif
+        }
+    } while ((cur_match = prev[cur_match & wmask]) > limit
+             && --chain_length != 0);
+
+    if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
+    return s->lookahead;
+}
+#endif /* ASMV */
+#endif /* FASTEST */
+
+/* ---------------------------------------------------------------------------
+ * Optimized version for level == 1 or strategy == Z_RLE only
+ */
+local uInt longest_match_fast(s, cur_match)
+    deflate_state *s;
+    IPos cur_match;                             /* current match */
+{
+    register Bytef *scan = s->window + s->strstart; /* current string */
+    register Bytef *match;                       /* matched string */
+    register int len;                           /* length of current match */
+    register Bytef *strend = s->window + s->strstart + MAX_MATCH;
+
+    /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+     * It is easy to get rid of this optimization if necessary.
+     */
+    Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
+
+    Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
+
+    Assert(cur_match < s->strstart, "no future");
+
+    match = s->window + cur_match;
+
+    /* Return failure if the match length is less than 2:
+     */
+    if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
+
+    /* The check at best_len-1 can be removed because it will be made
+     * again later. (This heuristic is not always a win.)
+     * It is not necessary to compare scan[2] and match[2] since they
+     * are always equal when the other bytes match, given that
+     * the hash keys are equal and that HASH_BITS >= 8.
+     */
+    scan += 2, match += 2;
+    Assert(*scan == *match, "match[2]?");
+
+    /* We check for insufficient lookahead only every 8th comparison;
+     * the 256th check will be made at strstart+258.
+     */
+    do {
+    } while (*++scan == *++match && *++scan == *++match &&
+             *++scan == *++match && *++scan == *++match &&
+             *++scan == *++match && *++scan == *++match &&
+             *++scan == *++match && *++scan == *++match &&
+             scan < strend);
+
+    Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+
+    len = MAX_MATCH - (int)(strend - scan);
+
+    if (len < MIN_MATCH) return MIN_MATCH - 1;
+
+    s->match_start = cur_match;
+    return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead;
+}
+
+#ifdef DEBUG
+/* ===========================================================================
+ * Check that the match at match_start is indeed a match.
+ */
+local void check_match(s, start, match, length)
+    deflate_state *s;
+    IPos start, match;
+    int length;
+{
+    /* check that the match is indeed a match */
+    if (zmemcmp(s->window + match,
+                s->window + start, length) != EQUAL) {
+        fprintf(stderr, " start %u, match %u, length %d\n",
+                start, match, length);
+        do {
+            fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
+        } while (--length != 0);
+        z_error("invalid match");
+    }
+    if (z_verbose > 1) {
+        fprintf(stderr,"\\[%d,%d]", start-match, length);
+        do { putc(s->window[start++], stderr); } while (--length != 0);
+    }
+}
+#else
+#  define check_match(s, start, match, length)
+#endif /* DEBUG */
+
+/* ===========================================================================
+ * Fill the window when the lookahead becomes insufficient.
+ * Updates strstart and lookahead.
+ *
+ * IN assertion: lookahead < MIN_LOOKAHEAD
+ * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
+ *    At least one byte has been read, or avail_in == 0; reads are
+ *    performed for at least two bytes (required for the zip translate_eol
+ *    option -- not supported here).
+ */
+local void fill_window(s)
+    deflate_state *s;
+{
+    register unsigned n, m;
+    register Posf *p;
+    unsigned more;    /* Amount of free space at the end of the window. */
+    uInt wsize = s->w_size;
+
+    do {
+        more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
+
+        /* Deal with !@#$% 64K limit: */
+        if (sizeof(int) <= 2) {
+            if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
+                more = wsize;
+
+            } else if (more == (unsigned)(-1)) {
+                /* Very unlikely, but possible on 16 bit machine if
+                 * strstart == 0 && lookahead == 1 (input done a byte at time)
+                 */
+                more--;
+            }
+        }
+
+        /* If the window is almost full and there is insufficient lookahead,
+         * move the upper half to the lower one to make room in the upper half.
+         */
+        if (s->strstart >= wsize+MAX_DIST(s)) {
+
+            zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
+            s->match_start -= wsize;
+            s->strstart    -= wsize; /* we now have strstart >= MAX_DIST */
+            s->block_start -= (long) wsize;
+
+            /* Slide the hash table (could be avoided with 32 bit values
+               at the expense of memory usage). We slide even when level == 0
+               to keep the hash table consistent if we switch back to level > 0
+               later. (Using level 0 permanently is not an optimal usage of
+               zlib, so we don't care about this pathological case.)
+             */
+            /* %%% avoid this when Z_RLE */
+            n = s->hash_size;
+            p = &s->head[n];
+            do {
+                m = *--p;
+                *p = (Pos)(m >= wsize ? m-wsize : NIL);
+            } while (--n);
+
+            n = wsize;
+#ifndef FASTEST
+            p = &s->prev[n];
+            do {
+                m = *--p;
+                *p = (Pos)(m >= wsize ? m-wsize : NIL);
+                /* If n is not on any hash chain, prev[n] is garbage but
+                 * its value will never be used.
+                 */
+            } while (--n);
+#endif
+            more += wsize;
+        }
+        if (s->strm->avail_in == 0) return;
+
+        /* If there was no sliding:
+         *    strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
+         *    more == window_size - lookahead - strstart
+         * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
+         * => more >= window_size - 2*WSIZE + 2
+         * In the BIG_MEM or MMAP case (not yet supported),
+         *   window_size == input_size + MIN_LOOKAHEAD  &&
+         *   strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
+         * Otherwise, window_size == 2*WSIZE so more >= 2.
+         * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
+         */
+        Assert(more >= 2, "more < 2");
+
+        n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
+        s->lookahead += n;
+
+        /* Initialize the hash value now that we have some input: */
+        if (s->lookahead >= MIN_MATCH) {
+            s->ins_h = s->window[s->strstart];
+            UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
+#if MIN_MATCH != 3
+            Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+        }
+        /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
+         * but this is not important since only literal bytes will be emitted.
+         */
+
+    } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
+}
+
+/* ===========================================================================
+ * Flush the current block, with given end-of-file flag.
+ * IN assertion: strstart is set to the end of the current match.
+ */
+#define FLUSH_BLOCK_ONLY(s, eof) { \
+   _tr_flush_block(s, (s->block_start >= 0L ? \
+                   (charf *)&s->window[(unsigned)s->block_start] : \
+                   (charf *)Z_NULL), \
+                (ulg)((long)s->strstart - s->block_start), \
+                (eof)); \
+   s->block_start = s->strstart; \
+   flush_pending(s->strm); \
+   Tracev((stderr,"[FLUSH]")); \
+}
+
+/* Same but force premature exit if necessary. */
+#define FLUSH_BLOCK(s, eof) { \
+   FLUSH_BLOCK_ONLY(s, eof); \
+   if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
+}
+
+/* ===========================================================================
+ * Copy without compression as much as possible from the input stream, return
+ * the current block state.
+ * This function does not insert new strings in the dictionary since
+ * uncompressible data is probably not useful. This function is used
+ * only for the level=0 compression option.
+ * NOTE: this function should be optimized to avoid extra copying from
+ * window to pending_buf.
+ */
+local block_state deflate_stored(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
+     * to pending_buf_size, and each stored block has a 5 byte header:
+     */
+    ulg max_block_size = 0xffff;
+    ulg max_start;
+
+    if (max_block_size > s->pending_buf_size - 5) {
+        max_block_size = s->pending_buf_size - 5;
+    }
+
+    /* Copy as much as possible from input to output: */
+    for (;;) {
+        /* Fill the window as much as possible: */
+        if (s->lookahead <= 1) {
+
+            Assert(s->strstart < s->w_size+MAX_DIST(s) ||
+                   s->block_start >= (long)s->w_size, "slide too late");
+
+            fill_window(s);
+            if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
+
+            if (s->lookahead == 0) break; /* flush the current block */
+        }
+        Assert(s->block_start >= 0L, "block gone");
+
+        s->strstart += s->lookahead;
+        s->lookahead = 0;
+
+        /* Emit a stored block if pending_buf will be full: */
+        max_start = s->block_start + max_block_size;
+        if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
+            /* strstart == 0 is possible when wraparound on 16-bit machine */
+            s->lookahead = (uInt)(s->strstart - max_start);
+            s->strstart = (uInt)max_start;
+            FLUSH_BLOCK(s, 0);
+        }
+        /* Flush if we may have to slide, otherwise block_start may become
+         * negative and the data will be gone:
+         */
+        if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
+            FLUSH_BLOCK(s, 0);
+        }
+    }
+    FLUSH_BLOCK(s, flush == Z_FINISH);
+    return flush == Z_FINISH ? finish_done : block_done;
+}
+
+/* ===========================================================================
+ * Compress as much as possible from the input stream, return the current
+ * block state.
+ * This function does not perform lazy evaluation of matches and inserts
+ * new strings in the dictionary only for unmatched strings or for short
+ * matches. It is used only for the fast compression options.
+ */
+local block_state deflate_fast(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    IPos hash_head = NIL; /* head of the hash chain */
+    int bflush;           /* set if current block must be flushed */
+
+    for (;;) {
+        /* Make sure that we always have enough lookahead, except
+         * at the end of the input file. We need MAX_MATCH bytes
+         * for the next match, plus MIN_MATCH bytes to insert the
+         * string following the next match.
+         */
+        if (s->lookahead < MIN_LOOKAHEAD) {
+            fill_window(s);
+            if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+                return need_more;
+            }
+            if (s->lookahead == 0) break; /* flush the current block */
+        }
+
+        /* Insert the string window[strstart .. strstart+2] in the
+         * dictionary, and set hash_head to the head of the hash chain:
+         */
+        if (s->lookahead >= MIN_MATCH) {
+            INSERT_STRING(s, s->strstart, hash_head);
+        }
+
+        /* Find the longest match, discarding those <= prev_length.
+         * At this point we have always match_length < MIN_MATCH
+         */
+        if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
+            /* To simplify the code, we prevent matches with the string
+             * of window index 0 (in particular we have to avoid a match
+             * of the string with itself at the start of the input file).
+             */
+#ifdef FASTEST
+            if ((s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) ||
+                (s->strategy == Z_RLE && s->strstart - hash_head == 1)) {
+                s->match_length = longest_match_fast (s, hash_head);
+            }
+#else
+            if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) {
+                s->match_length = longest_match (s, hash_head);
+            } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
+                s->match_length = longest_match_fast (s, hash_head);
+            }
+#endif
+            /* longest_match() or longest_match_fast() sets match_start */
+        }
+        if (s->match_length >= MIN_MATCH) {
+            check_match(s, s->strstart, s->match_start, s->match_length);
+
+            _tr_tally_dist(s, s->strstart - s->match_start,
+                           s->match_length - MIN_MATCH, bflush);
+
+            s->lookahead -= s->match_length;
+
+            /* Insert new strings in the hash table only if the match length
+             * is not too large. This saves time but degrades compression.
+             */
+#ifndef FASTEST
+            if (s->match_length <= s->max_insert_length &&
+                s->lookahead >= MIN_MATCH) {
+                s->match_length--; /* string at strstart already in table */
+                do {
+                    s->strstart++;
+                    INSERT_STRING(s, s->strstart, hash_head);
+                    /* strstart never exceeds WSIZE-MAX_MATCH, so there are
+                     * always MIN_MATCH bytes ahead.
+                     */
+                } while (--s->match_length != 0);
+                s->strstart++;
+            } else
+#endif
+            {
+                s->strstart += s->match_length;
+                s->match_length = 0;
+                s->ins_h = s->window[s->strstart];
+                UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
+#if MIN_MATCH != 3
+                Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+                /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
+                 * matter since it will be recomputed at next deflate call.
+                 */
+            }
+        } else {
+            /* No match, output a literal byte */
+            Tracevv((stderr,"%c", s->window[s->strstart]));
+            _tr_tally_lit (s, s->window[s->strstart], bflush);
+            s->lookahead--;
+            s->strstart++;
+        }
+        if (bflush) FLUSH_BLOCK(s, 0);
+    }
+    FLUSH_BLOCK(s, flush == Z_FINISH);
+    return flush == Z_FINISH ? finish_done : block_done;
+}
+
+#ifndef FASTEST
+/* ===========================================================================
+ * Same as above, but achieves better compression. We use a lazy
+ * evaluation for matches: a match is finally adopted only if there is
+ * no better match at the next window position.
+ */
+local block_state deflate_slow(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    IPos hash_head = NIL;    /* head of hash chain */
+    int bflush;              /* set if current block must be flushed */
+
+    /* Process the input block. */
+    for (;;) {
+        /* Make sure that we always have enough lookahead, except
+         * at the end of the input file. We need MAX_MATCH bytes
+         * for the next match, plus MIN_MATCH bytes to insert the
+         * string following the next match.
+         */
+        if (s->lookahead < MIN_LOOKAHEAD) {
+            fill_window(s);
+            if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+                return need_more;
+            }
+            if (s->lookahead == 0) break; /* flush the current block */
+        }
+
+        /* Insert the string window[strstart .. strstart+2] in the
+         * dictionary, and set hash_head to the head of the hash chain:
+         */
+        if (s->lookahead >= MIN_MATCH) {
+            INSERT_STRING(s, s->strstart, hash_head);
+        }
+
+        /* Find the longest match, discarding those <= prev_length.
+         */
+        s->prev_length = s->match_length, s->prev_match = s->match_start;
+        s->match_length = MIN_MATCH-1;
+
+        if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
+            s->strstart - hash_head <= MAX_DIST(s)) {
+            /* To simplify the code, we prevent matches with the string
+             * of window index 0 (in particular we have to avoid a match
+             * of the string with itself at the start of the input file).
+             */
+            if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) {
+                s->match_length = longest_match (s, hash_head);
+            } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
+                s->match_length = longest_match_fast (s, hash_head);
+            }
+            /* longest_match() or longest_match_fast() sets match_start */
+
+            if (s->match_length <= 5 && (s->strategy == Z_FILTERED
+#if TOO_FAR <= 32767
+                || (s->match_length == MIN_MATCH &&
+                    s->strstart - s->match_start > TOO_FAR)
+#endif
+                )) {
+
+                /* If prev_match is also MIN_MATCH, match_start is garbage
+                 * but we will ignore the current match anyway.
+                 */
+                s->match_length = MIN_MATCH-1;
+            }
+        }
+        /* If there was a match at the previous step and the current
+         * match is not better, output the previous match:
+         */
+        if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
+            uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
+            /* Do not insert strings in hash table beyond this. */
+
+            check_match(s, s->strstart-1, s->prev_match, s->prev_length);
+
+            _tr_tally_dist(s, s->strstart -1 - s->prev_match,
+                           s->prev_length - MIN_MATCH, bflush);
+
+            /* Insert in hash table all strings up to the end of the match.
+             * strstart-1 and strstart are already inserted. If there is not
+             * enough lookahead, the last two strings are not inserted in
+             * the hash table.
+             */
+            s->lookahead -= s->prev_length-1;
+            s->prev_length -= 2;
+            do {
+                if (++s->strstart <= max_insert) {
+                    INSERT_STRING(s, s->strstart, hash_head);
+                }
+            } while (--s->prev_length != 0);
+            s->match_available = 0;
+            s->match_length = MIN_MATCH-1;
+            s->strstart++;
+
+            if (bflush) FLUSH_BLOCK(s, 0);
+
+        } else if (s->match_available) {
+            /* If there was no match at the previous position, output a
+             * single literal. If there was a match but the current match
+             * is longer, truncate the previous match to a single literal.
+             */
+            Tracevv((stderr,"%c", s->window[s->strstart-1]));
+            _tr_tally_lit(s, s->window[s->strstart-1], bflush);
+            if (bflush) {
+                FLUSH_BLOCK_ONLY(s, 0);
+            }
+            s->strstart++;
+            s->lookahead--;
+            if (s->strm->avail_out == 0) return need_more;
+        } else {
+            /* There is no previous match to compare with, wait for
+             * the next step to decide.
+             */
+            s->match_available = 1;
+            s->strstart++;
+            s->lookahead--;
+        }
+    }
+    Assert (flush != Z_NO_FLUSH, "no flush?");
+    if (s->match_available) {
+        Tracevv((stderr,"%c", s->window[s->strstart-1]));
+        _tr_tally_lit(s, s->window[s->strstart-1], bflush);
+        s->match_available = 0;
+    }
+    FLUSH_BLOCK(s, flush == Z_FINISH);
+    return flush == Z_FINISH ? finish_done : block_done;
+}
+#endif /* FASTEST */
+
+#if 0
+/* ===========================================================================
+ * For Z_RLE, simply look for runs of bytes, generate matches only of distance
+ * one.  Do not maintain a hash table.  (It will be regenerated if this run of
+ * deflate switches away from Z_RLE.)
+ */
+local block_state deflate_rle(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    int bflush;         /* set if current block must be flushed */
+    uInt run;           /* length of run */
+    uInt max;           /* maximum length of run */
+    uInt prev;          /* byte at distance one to match */
+    Bytef *scan;        /* scan for end of run */
+
+    for (;;) {
+        /* Make sure that we always have enough lookahead, except
+         * at the end of the input file. We need MAX_MATCH bytes
+         * for the longest encodable run.
+         */
+        if (s->lookahead < MAX_MATCH) {
+            fill_window(s);
+            if (s->lookahead < MAX_MATCH && flush == Z_NO_FLUSH) {
+                return need_more;
+            }
+            if (s->lookahead == 0) break; /* flush the current block */
+        }
+
+        /* See how many times the previous byte repeats */
+        run = 0;
+        if (s->strstart > 0) {      /* if there is a previous byte, that is */
+            max = s->lookahead < MAX_MATCH ? s->lookahead : MAX_MATCH;
+            scan = s->window + s->strstart - 1;
+            prev = *scan++;
+            do {
+                if (*scan++ != prev)
+                    break;
+            } while (++run < max);
+        }
+
+        /* Emit match if have run of MIN_MATCH or longer, else emit literal */
+        if (run >= MIN_MATCH) {
+            check_match(s, s->strstart, s->strstart - 1, run);
+            _tr_tally_dist(s, 1, run - MIN_MATCH, bflush);
+            s->lookahead -= run;
+            s->strstart += run;
+        } else {
+            /* No match, output a literal byte */
+            Tracevv((stderr,"%c", s->window[s->strstart]));
+            _tr_tally_lit (s, s->window[s->strstart], bflush);
+            s->lookahead--;
+            s->strstart++;
+        }
+        if (bflush) FLUSH_BLOCK(s, 0);
+    }
+    FLUSH_BLOCK(s, flush == Z_FINISH);
+    return flush == Z_FINISH ? finish_done : block_done;
+}
+#endif

Added: vendor/Python/current/Modules/zlib/deflate.h
===================================================================
--- vendor/Python/current/Modules/zlib/deflate.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/zlib/deflate.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,331 @@
+/* deflate.h -- internal compression state
+ * Copyright (C) 1995-2004 Jean-loup Gailly
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* @(#) $Id$ */
+
+#ifndef DEFLATE_H
+#define DEFLATE_H
+
+#include "zutil.h"
+
+/* define NO_GZIP when compiling if you want to disable gzip header and
+   trailer creation by deflate().  NO_GZIP would be used to avoid linking in
+   the crc code when it is not needed.  For shared libraries, gzip encoding
+   should be left enabled. */
+#ifndef NO_GZIP
+#  define GZIP
+#endif
+
+/* ===========================================================================
+ * Internal compression state.
+ */
+
+#define LENGTH_CODES 29
+/* number of length codes, not counting the special END_BLOCK code */
+
+#define LITERALS  256
+/* number of literal bytes 0..255 */
+
+#define L_CODES (LITERALS+1+LENGTH_CODES)
+/* number of Literal or Length codes, including the END_BLOCK code */
+
+#define D_CODES   30
+/* number of distance codes */
+
+#define BL_CODES  19
+/* number of codes used to transfer the bit lengths */
+
+#define HEAP_SIZE (2*L_CODES+1)
+/* maximum heap size */
+
+#define MAX_BITS 15
+/* All codes must not exceed MAX_BITS bits */
+
+#define INIT_STATE    42
+#define EXTRA_STATE   69
+#define NAME_STATE    73
+#define COMMENT_STATE 91
+#define HCRC_STATE   103
+#define BUSY_STATE   113
+#define FINISH_STATE 666
+/* Stream status */
+
+
+/* Data structure describing a single value and its code string. */
+typedef struct ct_data_s {
+    union {
+        ush  freq;       /* frequency count */
+        ush  code;       /* bit string */
+    } fc;
+    union {
+        ush  dad;        /* father node in Huffman tree */
+        ush  len;        /* length of bit string */
+    } dl;
+} FAR ct_data;
+
+#define Freq fc.freq
+#define Code fc.code
+#define Dad  dl.dad
+#define Len  dl.len
+
+typedef struct static_tree_desc_s  static_tree_desc;
+
+typedef struct tree_desc_s {
+    ct_data *dyn_tree;           /* the dynamic tree */
+    int     max_code;            /* largest code with non zero frequency */
+    static_tree_desc *stat_desc; /* the corresponding static tree */
+} FAR tree_desc;
+
+typedef ush Pos;
+typedef Pos FAR Posf;
+typedef unsigned IPos;
+
+/* A Pos is an index in the character window. We use short instead of int to
+ * save space in the various tables. IPos is used only for parameter passing.
+ */
+
+typedef struct internal_state {
+    z_streamp strm;      /* pointer back to this zlib stream */
+    int   status;        /* as the name implies */
+    Bytef *pending_buf;  /* output still pending */
+    ulg   pending_buf_size; /* size of pending_buf */
+    Bytef *pending_out;  /* next pending byte to output to the stream */
+    uInt   pending;      /* nb of bytes in the pending buffer */
+    int   wrap;          /* bit 0 true for zlib, bit 1 true for gzip */
+    gz_headerp  gzhead;  /* gzip header information to write */
+    uInt   gzindex;      /* where in extra, name, or comment */
+    Byte  method;        /* STORED (for zip only) or DEFLATED */
+    int   last_flush;    /* value of flush param for previous deflate call */
+
+                /* used by deflate.c: */
+
+    uInt  w_size;        /* LZ77 window size (32K by default) */
+    uInt  w_bits;        /* log2(w_size)  (8..16) */
+    uInt  w_mask;        /* w_size - 1 */
+
+    Bytef *window;
+    /* Sliding window. Input bytes are read into the second half of the window,
+     * and move to the first half later to keep a dictionary of at least wSize
+     * bytes. With this organization, matches are limited to a distance of
+     * wSize-MAX_MATCH bytes, but this ensures that IO is always
+     * performed with a length multiple of the block size. Also, it limits
+     * the window size to 64K, which is quite useful on MSDOS.
+     * To do: use the user input buffer as sliding window.
+     */
+
+    ulg window_size;
+    /* Actual size of window: 2*wSize, except when the user input buffer
+     * is directly used as sliding window.
+     */
+
+    Posf *prev;
+    /* Link to older string with same hash index. To limit the size of this
+     * array to 64K, this link is maintained only for the last 32K strings.
+     * An index in this array is thus a window index modulo 32K.
+     */
+
+    Posf *head; /* Heads of the hash chains or NIL. */
+
+    uInt  ins_h;          /* hash index of string to be inserted */
+    uInt  hash_size;      /* number of elements in hash table */
+    uInt  hash_bits;      /* log2(hash_size) */
+    uInt  hash_mask;      /* hash_size-1 */
+
+    uInt  hash_shift;
+    /* Number of bits by which ins_h must be shifted at each input
+     * step. It must be such that after MIN_MATCH steps, the oldest
+     * byte no longer takes part in the hash key, that is:
+     *   hash_shift * MIN_MATCH >= hash_bits
+     */
+
+    long block_start;
+    /* Window position at the beginning of the current output block. Gets
+     * negative when the window is moved backwards.
+     */
+
+    uInt match_length;           /* length of best match */
+    IPos prev_match;             /* previous match */
+    int match_available;         /* set if previous match exists */
+    uInt strstart;               /* start of string to insert */
+    uInt match_start;            /* start of matching string */
+    uInt lookahead;              /* number of valid bytes ahead in window */
+
+    uInt prev_length;
+    /* Length of the best match at previous step. Matches not greater than this
+     * are discarded. This is used in the lazy match evaluation.
+     */
+
+    uInt max_chain_length;
+    /* To speed up deflation, hash chains are never searched beyond this
+     * length.  A higher limit improves compression ratio but degrades the
+     * speed.
+     */
+
+    uInt max_lazy_match;
+    /* Attempt to find a better match only when the current match is strictly
+     * smaller than this value. This mechanism is used only for compression
+     * levels >= 4.
+     */
+#   define max_insert_length  max_lazy_match
+    /* Insert new strings in the hash table only if the match length is not
+     * greater than this length. This saves time but degrades compression.
+     * max_insert_length is used only for compression levels <= 3.
+     */
+
+    int level;    /* compression level (1..9) */
+    int strategy; /* favor or force Huffman coding*/
+
+    uInt good_match;
+    /* Use a faster search when the previous match is longer than this */
+
+    int nice_match; /* Stop searching when current match exceeds this */
+
+                /* used by trees.c: */
+    /* Didn't use ct_data typedef below to supress compiler warning */
+    struct ct_data_s dyn_ltree[HEAP_SIZE];   /* literal and length tree */
+    struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
+    struct ct_data_s bl_tree[2*BL_CODES+1];  /* Huffman tree for bit lengths */
+
+    struct tree_desc_s l_desc;               /* desc. for literal tree */
+    struct tree_desc_s d_desc;               /* desc. for distance tree */
+    struct tree_desc_s bl_desc;              /* desc. for bit length tree */
+
+    ush bl_count[MAX_BITS+1];
+    /* number of codes at each bit length for an optimal tree */
+
+    int heap[2*L_CODES+1];      /* heap used to build the Huffman trees */
+    int heap_len;               /* number of elements in the heap */
+    int heap_max;               /* element of largest frequency */
+    /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
+     * The same heap array is used to build all trees.
+     */
+
+    uch depth[2*L_CODES+1];
+    /* Depth of each subtree used as tie breaker for trees of equal frequency
+     */
+
+    uchf *l_buf;          /* buffer for literals or lengths */
+
+    uInt  lit_bufsize;
+    /* Size of match buffer for literals/lengths.  There are 4 reasons for
+     * limiting lit_bufsize to 64K:
+     *   - frequencies can be kept in 16 bit counters
+     *   - if compression is not successful for the first block, all input
+     *     data is still in the window so we can still emit a stored block even
+     *     when input comes from standard input.  (This can also be done for
+     *     all blocks if lit_bufsize is not greater than 32K.)
+     *   - if compression is not successful for a file smaller than 64K, we can
+     *     even emit a stored file instead of a stored block (saving 5 bytes).
+     *     This is applicable only for zip (not gzip or zlib).
+     *   - creating new Huffman trees less frequently may not provide fast
+     *     adaptation to changes in the input data statistics. (Take for
+     *     example a binary file with poorly compressible code followed by
+     *     a highly compressible string table.) Smaller buffer sizes give
+     *     fast adaptation but have of course the overhead of transmitting
+     *     trees more frequently.
+     *   - I can't count above 4
+     */
+
+    uInt last_lit;      /* running index in l_buf */
+
+    ushf *d_buf;
+    /* Buffer for distances. To simplify the code, d_buf and l_buf have
+     * the same number of elements. To use different lengths, an extra flag
+     * array would be necessary.
+     */
+
+    ulg opt_len;        /* bit length of current block with optimal trees */
+    ulg static_len;     /* bit length of current block with static trees */
+    uInt matches;       /* number of string matches in current block */
+    int last_eob_len;   /* bit length of EOB code for last block */
+
+#ifdef DEBUG
+    ulg compressed_len; /* total bit length of compressed file mod 2^32 */
+    ulg bits_sent;      /* bit length of compressed data sent mod 2^32 */
+#endif
+
+    ush bi_buf;
+    /* Output buffer. bits are inserted starting at the bottom (least
+     * significant bits).
+     */
+    int bi_valid;
+    /* Number of valid bits in bi_buf.  All bits above the last valid bit
+     * are always zero.
+     */
+
+} FAR deflate_state;
+
+/* Output a byte on the stream.
+ * IN assertion: there is enough room in pending_buf.
+ */
+#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
+
+
+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
+/* Minimum amount of lookahead, except at the end of the input file.
+ * See deflate.c for comments about the MIN_MATCH+1.
+ */
+
+#define MAX_DIST(s)  ((s)->w_size-MIN_LOOKAHEAD)
+/* In order to simplify the code, particularly on 16 bit machines, match
+ * distances are limited to MAX_DIST instead of WSIZE.
+ */
+
+        /* in trees.c */
+void _tr_init         OF((deflate_state *s));
+int  _tr_tally        OF((deflate_state *s, unsigned dist, unsigned lc));
+void _tr_flush_block  OF((deflate_state *s, charf *buf, ulg stored_len,
+                          int eof));
+void _tr_align        OF((deflate_state *s));
+void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
+                          int eof));
+
+#define d_code(dist) \
+   ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
+/* Mapping from a distance to a distance code. dist is the distance - 1 and
+ * must not have side effects. _dist_code[256] and _dist_code[257] are never
+ * used.
+ */
+
+#ifndef DEBUG
+/* Inline versions of _tr_tally for speed: */
+
+#if defined(GEN_TREES_H) || !defined(STDC)
+  extern uch _length_code[];
+  extern uch _dist_code[];
+#else
+  extern const uch _length_code[];
+  extern const uch _dist_code[];
+#endif
+
+# define _tr_tally_lit(s, c, flush) \
+  { uch cc = (c); \
+    s->d_buf[s->last_lit] = 0; \
+    s->l_buf[s->last_lit++] = cc; \
+    s->dyn_ltree[cc].Freq++; \
+    flush = (s->last_lit == s->lit_bufsize-1); \
+   }
+# define _tr_tally_dist(s, distance, length, flush) \
+  { uch len = (length); \
+    ush dist = (distance); \
+    s->d_buf[s->last_lit] = dist; \
+    s->l_buf[s->last_lit++] = len; \
+    dist--; \
+    s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
+    s->dyn_dtree[d_code(dist)].Freq++; \
+    flush = (s->last_lit == s->lit_bufsize-1); \
+  }
+#else
+# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
+# define _tr_tally_dist(s, distance, length, flush) \
+              flush = _tr_tally(s, distance, length)
+#endif
+
+#endif /* DEFLATE_H */

Added: vendor/Python/current/Modules/zlib/example.c
===================================================================
--- vendor/Python/current/Modules/zlib/example.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/zlib/example.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,565 @@
+/* example.c -- usage example of the zlib compression library
+ * Copyright (C) 1995-2004 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#include <stdio.h>
+#include "zlib.h"
+
+#ifdef STDC
+#  include <string.h>
+#  include <stdlib.h>
+#endif
+
+#if defined(VMS) || defined(RISCOS)
+#  define TESTFILE "foo-gz"
+#else
+#  define TESTFILE "foo.gz"
+#endif
+
+#define CHECK_ERR(err, msg) { \
+    if (err != Z_OK) { \
+        fprintf(stderr, "%s error: %d\n", msg, err); \
+        exit(1); \
+    } \
+}
+
+const char hello[] = "hello, hello!";
+/* "hello world" would be more standard, but the repeated "hello"
+ * stresses the compression code better, sorry...
+ */
+
+const char dictionary[] = "hello";
+uLong dictId; /* Adler32 value of the dictionary */
+
+void test_compress      OF((Byte *compr, uLong comprLen,
+                            Byte *uncompr, uLong uncomprLen));
+void test_gzio          OF((const char *fname,
+                            Byte *uncompr, uLong uncomprLen));
+void test_deflate       OF((Byte *compr, uLong comprLen));
+void test_inflate       OF((Byte *compr, uLong comprLen,
+                            Byte *uncompr, uLong uncomprLen));
+void test_large_deflate OF((Byte *compr, uLong comprLen,
+                            Byte *uncompr, uLong uncomprLen));
+void test_large_inflate OF((Byte *compr, uLong comprLen,
+                            Byte *uncompr, uLong uncomprLen));
+void test_flush         OF((Byte *compr, uLong *comprLen));
+void test_sync          OF((Byte *compr, uLong comprLen,
+                            Byte *uncompr, uLong uncomprLen));
+void test_dict_deflate  OF((Byte *compr, uLong comprLen));
+void test_dict_inflate  OF((Byte *compr, uLong comprLen,
+                            Byte *uncompr, uLong uncomprLen));
+int  main               OF((int argc, char *argv[]));
+
+/* ===========================================================================
+ * Test compress() and uncompress()
+ */
+void test_compress(compr, comprLen, uncompr, uncomprLen)
+    Byte *compr, *uncompr;
+    uLong comprLen, uncomprLen;
+{
+    int err;
+    uLong len = (uLong)strlen(hello)+1;
+
+    err = compress(compr, &comprLen, (const Bytef*)hello, len);
+    CHECK_ERR(err, "compress");
+
+    strcpy((char*)uncompr, "garbage");
+
+    err = uncompress(uncompr, &uncomprLen, compr, comprLen);
+    CHECK_ERR(err, "uncompress");
+
+    if (strcmp((char*)uncompr, hello)) {
+        fprintf(stderr, "bad uncompress\n");
+        exit(1);
+    } else {
+        printf("uncompress(): %s\n", (char *)uncompr);
+    }
+}
+
+/* ===========================================================================
+ * Test read/write of .gz files
+ */
+void test_gzio(fname, uncompr, uncomprLen)
+    const char *fname; /* compressed file name */
+    Byte *uncompr;
+    uLong uncomprLen;
+{
+#ifdef NO_GZCOMPRESS
+    fprintf(stderr, "NO_GZCOMPRESS -- gz* functions cannot compress\n");
+#else
+    int err;
+    int len = (int)strlen(hello)+1;
+    gzFile file;
+    z_off_t pos;
+
+    file = gzopen(fname, "wb");
+    if (file == NULL) {
+        fprintf(stderr, "gzopen error\n");
+        exit(1);
+    }
+    gzputc(file, 'h');
+    if (gzputs(file, "ello") != 4) {
+        fprintf(stderr, "gzputs err: %s\n", gzerror(file, &err));
+        exit(1);
+    }
+    if (gzprintf(file, ", %s!", "hello") != 8) {
+        fprintf(stderr, "gzprintf err: %s\n", gzerror(file, &err));
+        exit(1);
+    }
+    gzseek(file, 1L, SEEK_CUR); /* add one zero byte */
+    gzclose(file);
+
+    file = gzopen(fname, "rb");
+    if (file == NULL) {
+        fprintf(stderr, "gzopen error\n");
+        exit(1);
+    }
+    strcpy((char*)uncompr, "garbage");
+
+    if (gzread(file, uncompr, (unsigned)uncomprLen) != len) {
+        fprintf(stderr, "gzread err: %s\n", gzerror(file, &err));
+        exit(1);
+    }
+    if (strcmp((char*)uncompr, hello)) {
+        fprintf(stderr, "bad gzread: %s\n", (char*)uncompr);
+        exit(1);
+    } else {
+        printf("gzread(): %s\n", (char*)uncompr);
+    }
+
+    pos = gzseek(file, -8L, SEEK_CUR);
+    if (pos != 6 || gztell(file) != pos) {
+        fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n",
+                (long)pos, (long)gztell(file));
+        exit(1);
+    }
+
+    if (gzgetc(file) != ' ') {
+        fprintf(stderr, "gzgetc error\n");
+        exit(1);
+    }
+
+    if (gzungetc(' ', file) != ' ') {
+        fprintf(stderr, "gzungetc error\n");
+        exit(1);
+    }
+
+    gzgets(file, (char*)uncompr, (int)uncomprLen);
+    if (strlen((char*)uncompr) != 7) { /* " hello!" */
+        fprintf(stderr, "gzgets err after gzseek: %s\n", gzerror(file, &err));
+        exit(1);
+    }
+    if (strcmp((char*)uncompr, hello + 6)) {
+        fprintf(stderr, "bad gzgets after gzseek\n");
+        exit(1);
+    } else {
+        printf("gzgets() after gzseek: %s\n", (char*)uncompr);
+    }
+
+    gzclose(file);
+#endif
+}
+
+/* ===========================================================================
+ * Test deflate() with small buffers
+ */
+void test_deflate(compr, comprLen)
+    Byte *compr;
+    uLong comprLen;
+{
+    z_stream c_stream; /* compression stream */
+    int err;
+    uLong len = (uLong)strlen(hello)+1;
+
+    c_stream.zalloc = (alloc_func)0;
+    c_stream.zfree = (free_func)0;
+    c_stream.opaque = (voidpf)0;
+
+    err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
+    CHECK_ERR(err, "deflateInit");
+
+    c_stream.next_in  = (Bytef*)hello;
+    c_stream.next_out = compr;
+
+    while (c_stream.total_in != len && c_stream.total_out < comprLen) {
+        c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
+        err = deflate(&c_stream, Z_NO_FLUSH);
+        CHECK_ERR(err, "deflate");
+    }
+    /* Finish the stream, still forcing small buffers: */
+    for (;;) {
+        c_stream.avail_out = 1;
+        err = deflate(&c_stream, Z_FINISH);
+        if (err == Z_STREAM_END) break;
+        CHECK_ERR(err, "deflate");
+    }
+
+    err = deflateEnd(&c_stream);
+    CHECK_ERR(err, "deflateEnd");
+}
+
+/* ===========================================================================
+ * Test inflate() with small buffers
+ */
+void test_inflate(compr, comprLen, uncompr, uncomprLen)
+    Byte *compr, *uncompr;
+    uLong comprLen, uncomprLen;
+{
+    int err;
+    z_stream d_stream; /* decompression stream */
+
+    strcpy((char*)uncompr, "garbage");
+
+    d_stream.zalloc = (alloc_func)0;
+    d_stream.zfree = (free_func)0;
+    d_stream.opaque = (voidpf)0;
+
+    d_stream.next_in  = compr;
+    d_stream.avail_in = 0;
+    d_stream.next_out = uncompr;
+
+    err = inflateInit(&d_stream);
+    CHECK_ERR(err, "inflateInit");
+
+    while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) {
+        d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
+        err = inflate(&d_stream, Z_NO_FLUSH);
+        if (err == Z_STREAM_END) break;
+        CHECK_ERR(err, "inflate");
+    }
+
+    err = inflateEnd(&d_stream);
+    CHECK_ERR(err, "inflateEnd");
+
+    if (strcmp((char*)uncompr, hello)) {
+        fprintf(stderr, "bad inflate\n");
+        exit(1);
+    } else {
+        printf("inflate(): %s\n", (char *)uncompr);
+    }
+}
+
+/* ===========================================================================
+ * Test deflate() with large buffers and dynamic change of compression level
+ */
+void test_large_deflate(compr, comprLen, uncompr, uncomprLen)
+    Byte *compr, *uncompr;
+    uLong comprLen, uncomprLen;
+{
+    z_stream c_stream; /* compression stream */
+    int err;
+
+    c_stream.zalloc = (alloc_func)0;
+    c_stream.zfree = (free_func)0;
+    c_stream.opaque = (voidpf)0;
+
+    err = deflateInit(&c_stream, Z_BEST_SPEED);
+    CHECK_ERR(err, "deflateInit");
+
+    c_stream.next_out = compr;
+    c_stream.avail_out = (uInt)comprLen;
+
+    /* At this point, uncompr is still mostly zeroes, so it should compress
+     * very well:
+     */
+    c_stream.next_in = uncompr;
+    c_stream.avail_in = (uInt)uncomprLen;
+    err = deflate(&c_stream, Z_NO_FLUSH);
+    CHECK_ERR(err, "deflate");
+    if (c_stream.avail_in != 0) {
+        fprintf(stderr, "deflate not greedy\n");
+        exit(1);
+    }
+
+    /* Feed in already compressed data and switch to no compression: */
+    deflateParams(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY);
+    c_stream.next_in = compr;
+    c_stream.avail_in = (uInt)comprLen/2;
+    err = deflate(&c_stream, Z_NO_FLUSH);
+    CHECK_ERR(err, "deflate");
+
+    /* Switch back to compressing mode: */
+    deflateParams(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED);
+    c_stream.next_in = uncompr;
+    c_stream.avail_in = (uInt)uncomprLen;
+    err = deflate(&c_stream, Z_NO_FLUSH);
+    CHECK_ERR(err, "deflate");
+
+    err = deflate(&c_stream, Z_FINISH);
+    if (err != Z_STREAM_END) {
+        fprintf(stderr, "deflate should report Z_STREAM_END\n");
+        exit(1);
+    }
+    err = deflateEnd(&c_stream);
+    CHECK_ERR(err, "deflateEnd");
+}
+
+/* ===========================================================================
+ * Test inflate() with large buffers
+ */
+void test_large_inflate(compr, comprLen, uncompr, uncomprLen)
+    Byte *compr, *uncompr;
+    uLong comprLen, uncomprLen;
+{
+    int err;
+    z_stream d_stream; /* decompression stream */
+
+    strcpy((char*)uncompr, "garbage");
+
+    d_stream.zalloc = (alloc_func)0;
+    d_stream.zfree = (free_func)0;
+    d_stream.opaque = (voidpf)0;
+
+    d_stream.next_in  = compr;
+    d_stream.avail_in = (uInt)comprLen;
+
+    err = inflateInit(&d_stream);
+    CHECK_ERR(err, "inflateInit");
+
+    for (;;) {
+        d_stream.next_out = uncompr;            /* discard the output */
+        d_stream.avail_out = (uInt)uncomprLen;
+        err = inflate(&d_stream, Z_NO_FLUSH);
+        if (err == Z_STREAM_END) break;
+        CHECK_ERR(err, "large inflate");
+    }
+
+    err = inflateEnd(&d_stream);
+    CHECK_ERR(err, "inflateEnd");
+
+    if (d_stream.total_out != 2*uncomprLen + comprLen/2) {
+        fprintf(stderr, "bad large inflate: %ld\n", d_stream.total_out);
+        exit(1);
+    } else {
+        printf("large_inflate(): OK\n");
+    }
+}
+
+/* ===========================================================================
+ * Test deflate() with full flush
+ */
+void test_flush(compr, comprLen)
+    Byte *compr;
+    uLong *comprLen;
+{
+    z_stream c_stream; /* compression stream */
+    int err;
+    uInt len = (uInt)strlen(hello)+1;
+
+    c_stream.zalloc = (alloc_func)0;
+    c_stream.zfree = (free_func)0;
+    c_stream.opaque = (voidpf)0;
+
+    err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
+    CHECK_ERR(err, "deflateInit");
+
+    c_stream.next_in  = (Bytef*)hello;
+    c_stream.next_out = compr;
+    c_stream.avail_in = 3;
+    c_stream.avail_out = (uInt)*comprLen;
+    err = deflate(&c_stream, Z_FULL_FLUSH);
+    CHECK_ERR(err, "deflate");
+
+    compr[3]++; /* force an error in first compressed block */
+    c_stream.avail_in = len - 3;
+
+    err = deflate(&c_stream, Z_FINISH);
+    if (err != Z_STREAM_END) {
+        CHECK_ERR(err, "deflate");
+    }
+    err = deflateEnd(&c_stream);
+    CHECK_ERR(err, "deflateEnd");
+
+    *comprLen = c_stream.total_out;
+}
+
+/* ===========================================================================
+ * Test inflateSync()
+ */
+void test_sync(compr, comprLen, uncompr, uncomprLen)
+    Byte *compr, *uncompr;
+    uLong comprLen, uncomprLen;
+{
+    int err;
+    z_stream d_stream; /* decompression stream */
+
+    strcpy((char*)uncompr, "garbage");
+
+    d_stream.zalloc = (alloc_func)0;
+    d_stream.zfree = (free_func)0;
+    d_stream.opaque = (voidpf)0;
+
+    d_stream.next_in  = compr;
+    d_stream.avail_in = 2; /* just read the zlib header */
+
+    err = inflateInit(&d_stream);
+    CHECK_ERR(err, "inflateInit");
+
+    d_stream.next_out = uncompr;
+    d_stream.avail_out = (uInt)uncomprLen;
+
+    inflate(&d_stream, Z_NO_FLUSH);
+    CHECK_ERR(err, "inflate");
+
+    d_stream.avail_in = (uInt)comprLen-2;   /* read all compressed data */
+    err = inflateSync(&d_stream);           /* but skip the damaged part */
+    CHECK_ERR(err, "inflateSync");
+
+    err = inflate(&d_stream, Z_FINISH);
+    if (err != Z_DATA_ERROR) {
+        fprintf(stderr, "inflate should report DATA_ERROR\n");
+        /* Because of incorrect adler32 */
+        exit(1);
+    }
+    err = inflateEnd(&d_stream);
+    CHECK_ERR(err, "inflateEnd");
+
+    printf("after inflateSync(): hel%s\n", (char *)uncompr);
+}
+
+/* ===========================================================================
+ * Test deflate() with preset dictionary
+ */
+void test_dict_deflate(compr, comprLen)
+    Byte *compr;
+    uLong comprLen;
+{
+    z_stream c_stream; /* compression stream */
+    int err;
+
+    c_stream.zalloc = (alloc_func)0;
+    c_stream.zfree = (free_func)0;
+    c_stream.opaque = (voidpf)0;
+
+    err = deflateInit(&c_stream, Z_BEST_COMPRESSION);
+    CHECK_ERR(err, "deflateInit");
+
+    err = deflateSetDictionary(&c_stream,
+                               (const Bytef*)dictionary, sizeof(dictionary));
+    CHECK_ERR(err, "deflateSetDictionary");
+
+    dictId = c_stream.adler;
+    c_stream.next_out = compr;
+    c_stream.avail_out = (uInt)comprLen;
+
+    c_stream.next_in = (Bytef*)hello;
+    c_stream.avail_in = (uInt)strlen(hello)+1;
+
+    err = deflate(&c_stream, Z_FINISH);
+    if (err != Z_STREAM_END) {
+        fprintf(stderr, "deflate should report Z_STREAM_END\n");
+        exit(1);
+    }
+    err = deflateEnd(&c_stream);
+    CHECK_ERR(err, "deflateEnd");
+}
+
+/* ===========================================================================
+ * Test inflate() with a preset dictionary
+ */
+void test_dict_inflate(compr, comprLen, uncompr, uncomprLen)
+    Byte *compr, *uncompr;
+    uLong comprLen, uncomprLen;
+{
+    int err;
+    z_stream d_stream; /* decompression stream */
+
+    strcpy((char*)uncompr, "garbage");
+
+    d_stream.zalloc = (alloc_func)0;
+    d_stream.zfree = (free_func)0;
+    d_stream.opaque = (voidpf)0;
+
+    d_stream.next_in  = compr;
+    d_stream.avail_in = (uInt)comprLen;
+
+    err = inflateInit(&d_stream);
+    CHECK_ERR(err, "inflateInit");
+
+    d_stream.next_out = uncompr;
+    d_stream.avail_out = (uInt)uncomprLen;
+
+    for (;;) {
+        err = inflate(&d_stream, Z_NO_FLUSH);
+        if (err == Z_STREAM_END) break;
+        if (err == Z_NEED_DICT) {
+            if (d_stream.adler != dictId) {
+                fprintf(stderr, "unexpected dictionary");
+                exit(1);
+            }
+            err = inflateSetDictionary(&d_stream, (const Bytef*)dictionary,
+                                       sizeof(dictionary));
+        }
+        CHECK_ERR(err, "inflate with dict");
+    }
+
+    err = inflateEnd(&d_stream);
+    CHECK_ERR(err, "inflateEnd");
+
+    if (strcmp((char*)uncompr, hello)) {
+        fprintf(stderr, "bad inflate with dict\n");
+        exit(1);
+    } else {
+        printf("inflate with dictionary: %s\n", (char *)uncompr);
+    }
+}
+
+/* ===========================================================================
+ * Usage:  example [output.gz  [input.gz]]
+ */
+
+int main(argc, argv)
+    int argc;
+    char *argv[];
+{
+    Byte *compr, *uncompr;
+    uLong comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */
+    uLong uncomprLen = comprLen;
+    static const char* myVersion = ZLIB_VERSION;
+
+    if (zlibVersion()[0] != myVersion[0]) {
+        fprintf(stderr, "incompatible zlib version\n");
+        exit(1);
+
+    } else if (strcmp(zlibVersion(), ZLIB_VERSION) != 0) {
+        fprintf(stderr, "warning: different zlib version\n");
+    }
+
+    printf("zlib version %s = 0x%04x, compile flags = 0x%lx\n",
+            ZLIB_VERSION, ZLIB_VERNUM, zlibCompileFlags());
+
+    compr    = (Byte*)calloc((uInt)comprLen, 1);
+    uncompr  = (Byte*)calloc((uInt)uncomprLen, 1);
+    /* compr and uncompr are cleared to avoid reading uninitialized
+     * data and to ensure that uncompr compresses well.
+     */
+    if (compr == Z_NULL || uncompr == Z_NULL) {
+        printf("out of memory\n");
+        exit(1);
+    }
+    test_compress(compr, comprLen, uncompr, uncomprLen);
+
+    test_gzio((argc > 1 ? argv[1] : TESTFILE),
+              uncompr, uncomprLen);
+
+    test_deflate(compr, comprLen);
+    test_inflate(compr, comprLen, uncompr, uncomprLen);
+
+    test_large_deflate(compr, comprLen, uncompr, uncomprLen);
+    test_large_inflate(compr, comprLen, uncompr, uncomprLen);
+
+    test_flush(compr, &comprLen);
+    test_sync(compr, comprLen, uncompr, uncomprLen);
+    comprLen = uncomprLen;
+
+    test_dict_deflate(compr, comprLen);
+    test_dict_inflate(compr, comprLen, uncompr, uncomprLen);
+
+    free(compr);
+    free(uncompr);
+
+    return 0;
+}

Added: vendor/Python/current/Modules/zlib/gzio.c
===================================================================
--- vendor/Python/current/Modules/zlib/gzio.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/zlib/gzio.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1026 @@
+/* gzio.c -- IO on .gz files
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ *
+ * Compile this file with -DNO_GZCOMPRESS to avoid the compression code.
+ */
+
+/* @(#) $Id$ */
+
+#include <stdio.h>
+
+#include "zutil.h"
+
+#ifdef NO_DEFLATE       /* for compatibility with old definition */
+#  define NO_GZCOMPRESS
+#endif
+
+#ifndef NO_DUMMY_DECL
+struct internal_state {int dummy;}; /* for buggy compilers */
+#endif
+
+#ifndef Z_BUFSIZE
+#  ifdef MAXSEG_64K
+#    define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */
+#  else
+#    define Z_BUFSIZE 16384
+#  endif
+#endif
+#ifndef Z_PRINTF_BUFSIZE
+#  define Z_PRINTF_BUFSIZE 4096
+#endif
+
+#ifdef __MVS__
+#  pragma map (fdopen , "\174\174FDOPEN")
+   FILE *fdopen(int, const char *);
+#endif
+
+#ifndef STDC
+extern voidp  malloc OF((uInt size));
+extern void   free   OF((voidpf ptr));
+#endif
+
+#define ALLOC(size) malloc(size)
+#define TRYFREE(p) {if (p) free(p);}
+
+static int const gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */
+
+/* gzip flag byte */
+#define ASCII_FLAG   0x01 /* bit 0 set: file probably ascii text */
+#define HEAD_CRC     0x02 /* bit 1 set: header CRC present */
+#define EXTRA_FIELD  0x04 /* bit 2 set: extra field present */
+#define ORIG_NAME    0x08 /* bit 3 set: original file name present */
+#define COMMENT      0x10 /* bit 4 set: file comment present */
+#define RESERVED     0xE0 /* bits 5..7: reserved */
+
+typedef struct gz_stream {
+    z_stream stream;
+    int      z_err;   /* error code for last stream operation */
+    int      z_eof;   /* set if end of input file */
+    FILE     *file;   /* .gz file */
+    Byte     *inbuf;  /* input buffer */
+    Byte     *outbuf; /* output buffer */
+    uLong    crc;     /* crc32 of uncompressed data */
+    char     *msg;    /* error message */
+    char     *path;   /* path name for debugging only */
+    int      transparent; /* 1 if input file is not a .gz file */
+    char     mode;    /* 'w' or 'r' */
+    z_off_t  start;   /* start of compressed data in file (header skipped) */
+    z_off_t  in;      /* bytes into deflate or inflate */
+    z_off_t  out;     /* bytes out of deflate or inflate */
+    int      back;    /* one character push-back */
+    int      last;    /* true if push-back is last character */
+} gz_stream;
+
+
+local gzFile gz_open      OF((const char *path, const char *mode, int  fd));
+local int do_flush        OF((gzFile file, int flush));
+local int    get_byte     OF((gz_stream *s));
+local void   check_header OF((gz_stream *s));
+local int    destroy      OF((gz_stream *s));
+local void   putLong      OF((FILE *file, uLong x));
+local uLong  getLong      OF((gz_stream *s));
+
+/* ===========================================================================
+     Opens a gzip (.gz) file for reading or writing. The mode parameter
+   is as in fopen ("rb" or "wb"). The file is given either by file descriptor
+   or path name (if fd == -1).
+     gz_open returns NULL if the file could not be opened or if there was
+   insufficient memory to allocate the (de)compression state; errno
+   can be checked to distinguish the two cases (if errno is zero, the
+   zlib error is Z_MEM_ERROR).
+*/
+local gzFile gz_open (path, mode, fd)
+    const char *path;
+    const char *mode;
+    int  fd;
+{
+    int err;
+    int level = Z_DEFAULT_COMPRESSION; /* compression level */
+    int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */
+    char *p = (char*)mode;
+    gz_stream *s;
+    char fmode[80]; /* copy of mode, without the compression level */
+    char *m = fmode;
+
+    if (!path || !mode) return Z_NULL;
+
+    s = (gz_stream *)ALLOC(sizeof(gz_stream));
+    if (!s) return Z_NULL;
+
+    s->stream.zalloc = (alloc_func)0;
+    s->stream.zfree = (free_func)0;
+    s->stream.opaque = (voidpf)0;
+    s->stream.next_in = s->inbuf = Z_NULL;
+    s->stream.next_out = s->outbuf = Z_NULL;
+    s->stream.avail_in = s->stream.avail_out = 0;
+    s->file = NULL;
+    s->z_err = Z_OK;
+    s->z_eof = 0;
+    s->in = 0;
+    s->out = 0;
+    s->back = EOF;
+    s->crc = crc32(0L, Z_NULL, 0);
+    s->msg = NULL;
+    s->transparent = 0;
+
+    s->path = (char*)ALLOC(strlen(path)+1);
+    if (s->path == NULL) {
+        return destroy(s), (gzFile)Z_NULL;
+    }
+    strcpy(s->path, path); /* do this early for debugging */
+
+    s->mode = '\0';
+    do {
+        if (*p == 'r') s->mode = 'r';
+        if (*p == 'w' || *p == 'a') s->mode = 'w';
+        if (*p >= '0' && *p <= '9') {
+            level = *p - '0';
+        } else if (*p == 'f') {
+          strategy = Z_FILTERED;
+        } else if (*p == 'h') {
+          strategy = Z_HUFFMAN_ONLY;
+        } else if (*p == 'R') {
+          strategy = Z_RLE;
+        } else {
+            *m++ = *p; /* copy the mode */
+        }
+    } while (*p++ && m != fmode + sizeof(fmode));
+    if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL;
+
+    if (s->mode == 'w') {
+#ifdef NO_GZCOMPRESS
+        err = Z_STREAM_ERROR;
+#else
+        err = deflateInit2(&(s->stream), level,
+                           Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy);
+        /* windowBits is passed < 0 to suppress zlib header */
+
+        s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
+#endif
+        if (err != Z_OK || s->outbuf == Z_NULL) {
+            return destroy(s), (gzFile)Z_NULL;
+        }
+    } else {
+        s->stream.next_in  = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE);
+
+        err = inflateInit2(&(s->stream), -MAX_WBITS);
+        /* windowBits is passed < 0 to tell that there is no zlib header.
+         * Note that in this case inflate *requires* an extra "dummy" byte
+         * after the compressed stream in order to complete decompression and
+         * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are
+         * present after the compressed stream.
+         */
+        if (err != Z_OK || s->inbuf == Z_NULL) {
+            return destroy(s), (gzFile)Z_NULL;
+        }
+    }
+    s->stream.avail_out = Z_BUFSIZE;
+
+    errno = 0;
+    s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode);
+
+    if (s->file == NULL) {
+        return destroy(s), (gzFile)Z_NULL;
+    }
+    if (s->mode == 'w') {
+        /* Write a very simple .gz header:
+         */
+        fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1],
+             Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE);
+        s->start = 10L;
+        /* We use 10L instead of ftell(s->file) to because ftell causes an
+         * fflush on some systems. This version of the library doesn't use
+         * start anyway in write mode, so this initialization is not
+         * necessary.
+         */
+    } else {
+        check_header(s); /* skip the .gz header */
+        s->start = ftell(s->file) - s->stream.avail_in;
+    }
+
+    return (gzFile)s;
+}
+
+/* ===========================================================================
+     Opens a gzip (.gz) file for reading or writing.
+*/
+gzFile ZEXPORT gzopen (path, mode)
+    const char *path;
+    const char *mode;
+{
+    return gz_open (path, mode, -1);
+}
+
+/* ===========================================================================
+     Associate a gzFile with the file descriptor fd. fd is not dup'ed here
+   to mimic the behavio(u)r of fdopen.
+*/
+gzFile ZEXPORT gzdopen (fd, mode)
+    int fd;
+    const char *mode;
+{
+    char name[46];      /* allow for up to 128-bit integers */
+
+    if (fd < 0) return (gzFile)Z_NULL;
+    sprintf(name, "<fd:%d>", fd); /* for debugging */
+
+    return gz_open (name, mode, fd);
+}
+
+/* ===========================================================================
+ * Update the compression level and strategy
+ */
+int ZEXPORT gzsetparams (file, level, strategy)
+    gzFile file;
+    int level;
+    int strategy;
+{
+    gz_stream *s = (gz_stream*)file;
+
+    if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
+
+    /* Make room to allow flushing */
+    if (s->stream.avail_out == 0) {
+
+        s->stream.next_out = s->outbuf;
+        if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
+            s->z_err = Z_ERRNO;
+        }
+        s->stream.avail_out = Z_BUFSIZE;
+    }
+
+    return deflateParams (&(s->stream), level, strategy);
+}
+
+/* ===========================================================================
+     Read a byte from a gz_stream; update next_in and avail_in. Return EOF
+   for end of file.
+   IN assertion: the stream s has been sucessfully opened for reading.
+*/
+local int get_byte(s)
+    gz_stream *s;
+{
+    if (s->z_eof) return EOF;
+    if (s->stream.avail_in == 0) {
+        errno = 0;
+        s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file);
+        if (s->stream.avail_in == 0) {
+            s->z_eof = 1;
+            if (ferror(s->file)) s->z_err = Z_ERRNO;
+            return EOF;
+        }
+        s->stream.next_in = s->inbuf;
+    }
+    s->stream.avail_in--;
+    return *(s->stream.next_in)++;
+}
+
+/* ===========================================================================
+      Check the gzip header of a gz_stream opened for reading. Set the stream
+    mode to transparent if the gzip magic header is not present; set s->err
+    to Z_DATA_ERROR if the magic header is present but the rest of the header
+    is incorrect.
+    IN assertion: the stream s has already been created sucessfully;
+       s->stream.avail_in is zero for the first time, but may be non-zero
+       for concatenated .gz files.
+*/
+local void check_header(s)
+    gz_stream *s;
+{
+    int method; /* method byte */
+    int flags;  /* flags byte */
+    uInt len;
+    int c;
+
+    /* Assure two bytes in the buffer so we can peek ahead -- handle case
+       where first byte of header is at the end of the buffer after the last
+       gzip segment */
+    len = s->stream.avail_in;
+    if (len < 2) {
+        if (len) s->inbuf[0] = s->stream.next_in[0];
+        errno = 0;
+        len = (uInt)fread(s->inbuf + len, 1, Z_BUFSIZE >> len, s->file);
+        if (len == 0 && ferror(s->file)) s->z_err = Z_ERRNO;
+        s->stream.avail_in += len;
+        s->stream.next_in = s->inbuf;
+        if (s->stream.avail_in < 2) {
+            s->transparent = s->stream.avail_in;
+            return;
+        }
+    }
+
+    /* Peek ahead to check the gzip magic header */
+    if (s->stream.next_in[0] != gz_magic[0] ||
+        s->stream.next_in[1] != gz_magic[1]) {
+        s->transparent = 1;
+        return;
+    }
+    s->stream.avail_in -= 2;
+    s->stream.next_in += 2;
+
+    /* Check the rest of the gzip header */
+    method = get_byte(s);
+    flags = get_byte(s);
+    if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
+        s->z_err = Z_DATA_ERROR;
+        return;
+    }
+
+    /* Discard time, xflags and OS code: */
+    for (len = 0; len < 6; len++) (void)get_byte(s);
+
+    if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
+        len  =  (uInt)get_byte(s);
+        len += ((uInt)get_byte(s))<<8;
+        /* len is garbage if EOF but the loop below will quit anyway */
+        while (len-- != 0 && get_byte(s) != EOF) ;
+    }
+    if ((flags & ORIG_NAME) != 0) { /* skip the original file name */
+        while ((c = get_byte(s)) != 0 && c != EOF) ;
+    }
+    if ((flags & COMMENT) != 0) {   /* skip the .gz file comment */
+        while ((c = get_byte(s)) != 0 && c != EOF) ;
+    }
+    if ((flags & HEAD_CRC) != 0) {  /* skip the header crc */
+        for (len = 0; len < 2; len++) (void)get_byte(s);
+    }
+    s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK;
+}
+
+ /* ===========================================================================
+ * Cleanup then free the given gz_stream. Return a zlib error code.
+   Try freeing in the reverse order of allocations.
+ */
+local int destroy (s)
+    gz_stream *s;
+{
+    int err = Z_OK;
+
+    if (!s) return Z_STREAM_ERROR;
+
+    TRYFREE(s->msg);
+
+    if (s->stream.state != NULL) {
+        if (s->mode == 'w') {
+#ifdef NO_GZCOMPRESS
+            err = Z_STREAM_ERROR;
+#else
+            err = deflateEnd(&(s->stream));
+#endif
+        } else if (s->mode == 'r') {
+            err = inflateEnd(&(s->stream));
+        }
+    }
+    if (s->file != NULL && fclose(s->file)) {
+#ifdef ESPIPE
+        if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */
+#endif
+            err = Z_ERRNO;
+    }
+    if (s->z_err < 0) err = s->z_err;
+
+    TRYFREE(s->inbuf);
+    TRYFREE(s->outbuf);
+    TRYFREE(s->path);
+    TRYFREE(s);
+    return err;
+}
+
+/* ===========================================================================
+     Reads the given number of uncompressed bytes from the compressed file.
+   gzread returns the number of bytes actually read (0 for end of file).
+*/
+int ZEXPORT gzread (file, buf, len)
+    gzFile file;
+    voidp buf;
+    unsigned len;
+{
+    gz_stream *s = (gz_stream*)file;
+    Bytef *start = (Bytef*)buf; /* starting point for crc computation */
+    Byte  *next_out; /* == stream.next_out but not forced far (for MSDOS) */
+
+    if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR;
+
+    if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1;
+    if (s->z_err == Z_STREAM_END) return 0;  /* EOF */
+
+    next_out = (Byte*)buf;
+    s->stream.next_out = (Bytef*)buf;
+    s->stream.avail_out = len;
+
+    if (s->stream.avail_out && s->back != EOF) {
+        *next_out++ = s->back;
+        s->stream.next_out++;
+        s->stream.avail_out--;
+        s->back = EOF;
+        s->out++;
+        start++;
+        if (s->last) {
+            s->z_err = Z_STREAM_END;
+            return 1;
+        }
+    }
+
+    while (s->stream.avail_out != 0) {
+
+        if (s->transparent) {
+            /* Copy first the lookahead bytes: */
+            uInt n = s->stream.avail_in;
+            if (n > s->stream.avail_out) n = s->stream.avail_out;
+            if (n > 0) {
+                zmemcpy(s->stream.next_out, s->stream.next_in, n);
+                next_out += n;
+                s->stream.next_out = next_out;
+                s->stream.next_in   += n;
+                s->stream.avail_out -= n;
+                s->stream.avail_in  -= n;
+            }
+            if (s->stream.avail_out > 0) {
+                s->stream.avail_out -=
+                    (uInt)fread(next_out, 1, s->stream.avail_out, s->file);
+            }
+            len -= s->stream.avail_out;
+            s->in  += len;
+            s->out += len;
+            if (len == 0) s->z_eof = 1;
+            return (int)len;
+        }
+        if (s->stream.avail_in == 0 && !s->z_eof) {
+
+            errno = 0;
+            s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file);
+            if (s->stream.avail_in == 0) {
+                s->z_eof = 1;
+                if (ferror(s->file)) {
+                    s->z_err = Z_ERRNO;
+                    break;
+                }
+            }
+            s->stream.next_in = s->inbuf;
+        }
+        s->in += s->stream.avail_in;
+        s->out += s->stream.avail_out;
+        s->z_err = inflate(&(s->stream), Z_NO_FLUSH);
+        s->in -= s->stream.avail_in;
+        s->out -= s->stream.avail_out;
+
+        if (s->z_err == Z_STREAM_END) {
+            /* Check CRC and original size */
+            s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
+            start = s->stream.next_out;
+
+            if (getLong(s) != s->crc) {
+                s->z_err = Z_DATA_ERROR;
+            } else {
+                (void)getLong(s);
+                /* The uncompressed length returned by above getlong() may be
+                 * different from s->out in case of concatenated .gz files.
+                 * Check for such files:
+                 */
+                check_header(s);
+                if (s->z_err == Z_OK) {
+                    inflateReset(&(s->stream));
+                    s->crc = crc32(0L, Z_NULL, 0);
+                }
+            }
+        }
+        if (s->z_err != Z_OK || s->z_eof) break;
+    }
+    s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
+
+    if (len == s->stream.avail_out &&
+        (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO))
+        return -1;
+    return (int)(len - s->stream.avail_out);
+}
+
+
+/* ===========================================================================
+      Reads one byte from the compressed file. gzgetc returns this byte
+   or -1 in case of end of file or error.
+*/
+int ZEXPORT gzgetc(file)
+    gzFile file;
+{
+    unsigned char c;
+
+    return gzread(file, &c, 1) == 1 ? c : -1;
+}
+
+
+/* ===========================================================================
+      Push one byte back onto the stream.
+*/
+int ZEXPORT gzungetc(c, file)
+    int c;
+    gzFile file;
+{
+    gz_stream *s = (gz_stream*)file;
+
+    if (s == NULL || s->mode != 'r' || c == EOF || s->back != EOF) return EOF;
+    s->back = c;
+    s->out--;
+    s->last = (s->z_err == Z_STREAM_END);
+    if (s->last) s->z_err = Z_OK;
+    s->z_eof = 0;
+    return c;
+}
+
+
+/* ===========================================================================
+      Reads bytes from the compressed file until len-1 characters are
+   read, or a newline character is read and transferred to buf, or an
+   end-of-file condition is encountered.  The string is then terminated
+   with a null character.
+      gzgets returns buf, or Z_NULL in case of error.
+
+      The current implementation is not optimized at all.
+*/
+char * ZEXPORT gzgets(file, buf, len)
+    gzFile file;
+    char *buf;
+    int len;
+{
+    char *b = buf;
+    if (buf == Z_NULL || len <= 0) return Z_NULL;
+
+    while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ;
+    *buf = '\0';
+    return b == buf && len > 0 ? Z_NULL : b;
+}
+
+
+#ifndef NO_GZCOMPRESS
+/* ===========================================================================
+     Writes the given number of uncompressed bytes into the compressed file.
+   gzwrite returns the number of bytes actually written (0 in case of error).
+*/
+int ZEXPORT gzwrite (file, buf, len)
+    gzFile file;
+    voidpc buf;
+    unsigned len;
+{
+    gz_stream *s = (gz_stream*)file;
+
+    if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
+
+    s->stream.next_in = (Bytef*)buf;
+    s->stream.avail_in = len;
+
+    while (s->stream.avail_in != 0) {
+
+        if (s->stream.avail_out == 0) {
+
+            s->stream.next_out = s->outbuf;
+            if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
+                s->z_err = Z_ERRNO;
+                break;
+            }
+            s->stream.avail_out = Z_BUFSIZE;
+        }
+        s->in += s->stream.avail_in;
+        s->out += s->stream.avail_out;
+        s->z_err = deflate(&(s->stream), Z_NO_FLUSH);
+        s->in -= s->stream.avail_in;
+        s->out -= s->stream.avail_out;
+        if (s->z_err != Z_OK) break;
+    }
+    s->crc = crc32(s->crc, (const Bytef *)buf, len);
+
+    return (int)(len - s->stream.avail_in);
+}
+
+
+/* ===========================================================================
+     Converts, formats, and writes the args to the compressed file under
+   control of the format string, as in fprintf. gzprintf returns the number of
+   uncompressed bytes actually written (0 in case of error).
+*/
+#ifdef STDC
+#include <stdarg.h>
+
+int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...)
+{
+    char buf[Z_PRINTF_BUFSIZE];
+    va_list va;
+    int len;
+
+    buf[sizeof(buf) - 1] = 0;
+    va_start(va, format);
+#ifdef NO_vsnprintf
+#  ifdef HAS_vsprintf_void
+    (void)vsprintf(buf, format, va);
+    va_end(va);
+    for (len = 0; len < sizeof(buf); len++)
+        if (buf[len] == 0) break;
+#  else
+    len = vsprintf(buf, format, va);
+    va_end(va);
+#  endif
+#else
+#  ifdef HAS_vsnprintf_void
+    (void)vsnprintf(buf, sizeof(buf), format, va);
+    va_end(va);
+    len = strlen(buf);
+#  else
+    len = vsnprintf(buf, sizeof(buf), format, va);
+    va_end(va);
+#  endif
+#endif
+    if (len <= 0 || len >= (int)sizeof(buf) || buf[sizeof(buf) - 1] != 0)
+        return 0;
+    return gzwrite(file, buf, (unsigned)len);
+}
+#else /* not ANSI C */
+
+int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
+                       a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
+    gzFile file;
+    const char *format;
+    int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
+        a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
+{
+    char buf[Z_PRINTF_BUFSIZE];
+    int len;
+
+    buf[sizeof(buf) - 1] = 0;
+#ifdef NO_snprintf
+#  ifdef HAS_sprintf_void
+    sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
+            a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+    for (len = 0; len < sizeof(buf); len++)
+        if (buf[len] == 0) break;
+#  else
+    len = sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
+                a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+#  endif
+#else
+#  ifdef HAS_snprintf_void
+    snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
+             a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+    len = strlen(buf);
+#  else
+    len = snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
+                 a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+#  endif
+#endif
+    if (len <= 0 || len >= sizeof(buf) || buf[sizeof(buf) - 1] != 0)
+        return 0;
+    return gzwrite(file, buf, len);
+}
+#endif
+
+/* ===========================================================================
+      Writes c, converted to an unsigned char, into the compressed file.
+   gzputc returns the value that was written, or -1 in case of error.
+*/
+int ZEXPORT gzputc(file, c)
+    gzFile file;
+    int c;
+{
+    unsigned char cc = (unsigned char) c; /* required for big endian systems */
+
+    return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1;
+}
+
+
+/* ===========================================================================
+      Writes the given null-terminated string to the compressed file, excluding
+   the terminating null character.
+      gzputs returns the number of characters written, or -1 in case of error.
+*/
+int ZEXPORT gzputs(file, s)
+    gzFile file;
+    const char *s;
+{
+    return gzwrite(file, (char*)s, (unsigned)strlen(s));
+}
+
+
+/* ===========================================================================
+     Flushes all pending output into the compressed file. The parameter
+   flush is as in the deflate() function.
+*/
+local int do_flush (file, flush)
+    gzFile file;
+    int flush;
+{
+    uInt len;
+    int done = 0;
+    gz_stream *s = (gz_stream*)file;
+
+    if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
+
+    s->stream.avail_in = 0; /* should be zero already anyway */
+
+    for (;;) {
+        len = Z_BUFSIZE - s->stream.avail_out;
+
+        if (len != 0) {
+            if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) {
+                s->z_err = Z_ERRNO;
+                return Z_ERRNO;
+            }
+            s->stream.next_out = s->outbuf;
+            s->stream.avail_out = Z_BUFSIZE;
+        }
+        if (done) break;
+        s->out += s->stream.avail_out;
+        s->z_err = deflate(&(s->stream), flush);
+        s->out -= s->stream.avail_out;
+
+        /* Ignore the second of two consecutive flushes: */
+        if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK;
+
+        /* deflate has finished flushing only when it hasn't used up
+         * all the available space in the output buffer:
+         */
+        done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END);
+
+        if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break;
+    }
+    return  s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
+}
+
+int ZEXPORT gzflush (file, flush)
+     gzFile file;
+     int flush;
+{
+    gz_stream *s = (gz_stream*)file;
+    int err = do_flush (file, flush);
+
+    if (err) return err;
+    fflush(s->file);
+    return  s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
+}
+#endif /* NO_GZCOMPRESS */
+
+/* ===========================================================================
+      Sets the starting position for the next gzread or gzwrite on the given
+   compressed file. The offset represents a number of bytes in the
+      gzseek returns the resulting offset location as measured in bytes from
+   the beginning of the uncompressed stream, or -1 in case of error.
+      SEEK_END is not implemented, returns error.
+      In this version of the library, gzseek can be extremely slow.
+*/
+z_off_t ZEXPORT gzseek (file, offset, whence)
+    gzFile file;
+    z_off_t offset;
+    int whence;
+{
+    gz_stream *s = (gz_stream*)file;
+
+    if (s == NULL || whence == SEEK_END ||
+        s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) {
+        return -1L;
+    }
+
+    if (s->mode == 'w') {
+#ifdef NO_GZCOMPRESS
+        return -1L;
+#else
+        if (whence == SEEK_SET) {
+            offset -= s->in;
+        }
+        if (offset < 0) return -1L;
+
+        /* At this point, offset is the number of zero bytes to write. */
+        if (s->inbuf == Z_NULL) {
+            s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */
+            if (s->inbuf == Z_NULL) return -1L;
+            zmemzero(s->inbuf, Z_BUFSIZE);
+        }
+        while (offset > 0)  {
+            uInt size = Z_BUFSIZE;
+            if (offset < Z_BUFSIZE) size = (uInt)offset;
+
+            size = gzwrite(file, s->inbuf, size);
+            if (size == 0) return -1L;
+
+            offset -= size;
+        }
+        return s->in;
+#endif
+    }
+    /* Rest of function is for reading only */
+
+    /* compute absolute position */
+    if (whence == SEEK_CUR) {
+        offset += s->out;
+    }
+    if (offset < 0) return -1L;
+
+    if (s->transparent) {
+        /* map to fseek */
+        s->back = EOF;
+        s->stream.avail_in = 0;
+        s->stream.next_in = s->inbuf;
+        if (fseek(s->file, offset, SEEK_SET) < 0) return -1L;
+
+        s->in = s->out = offset;
+        return offset;
+    }
+
+    /* For a negative seek, rewind and use positive seek */
+    if (offset >= s->out) {
+        offset -= s->out;
+    } else if (gzrewind(file) < 0) {
+        return -1L;
+    }
+    /* offset is now the number of bytes to skip. */
+
+    if (offset != 0 && s->outbuf == Z_NULL) {
+        s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
+        if (s->outbuf == Z_NULL) return -1L;
+    }
+    if (offset && s->back != EOF) {
+        s->back = EOF;
+        s->out++;
+        offset--;
+        if (s->last) s->z_err = Z_STREAM_END;
+    }
+    while (offset > 0)  {
+        int size = Z_BUFSIZE;
+        if (offset < Z_BUFSIZE) size = (int)offset;
+
+        size = gzread(file, s->outbuf, (uInt)size);
+        if (size <= 0) return -1L;
+        offset -= size;
+    }
+    return s->out;
+}
+
+/* ===========================================================================
+     Rewinds input file.
+*/
+int ZEXPORT gzrewind (file)
+    gzFile file;
+{
+    gz_stream *s = (gz_stream*)file;
+
+    if (s == NULL || s->mode != 'r') return -1;
+
+    s->z_err = Z_OK;
+    s->z_eof = 0;
+    s->back = EOF;
+    s->stream.avail_in = 0;
+    s->stream.next_in = s->inbuf;
+    s->crc = crc32(0L, Z_NULL, 0);
+    if (!s->transparent) (void)inflateReset(&s->stream);
+    s->in = 0;
+    s->out = 0;
+    return fseek(s->file, s->start, SEEK_SET);
+}
+
+/* ===========================================================================
+     Returns the starting position for the next gzread or gzwrite on the
+   given compressed file. This position represents a number of bytes in the
+   uncompressed data stream.
+*/
+z_off_t ZEXPORT gztell (file)
+    gzFile file;
+{
+    return gzseek(file, 0L, SEEK_CUR);
+}
+
+/* ===========================================================================
+     Returns 1 when EOF has previously been detected reading the given
+   input stream, otherwise zero.
+*/
+int ZEXPORT gzeof (file)
+    gzFile file;
+{
+    gz_stream *s = (gz_stream*)file;
+
+    /* With concatenated compressed files that can have embedded
+     * crc trailers, z_eof is no longer the only/best indicator of EOF
+     * on a gz_stream. Handle end-of-stream error explicitly here.
+     */
+    if (s == NULL || s->mode != 'r') return 0;
+    if (s->z_eof) return 1;
+    return s->z_err == Z_STREAM_END;
+}
+
+/* ===========================================================================
+     Returns 1 if reading and doing so transparently, otherwise zero.
+*/
+int ZEXPORT gzdirect (file)
+    gzFile file;
+{
+    gz_stream *s = (gz_stream*)file;
+
+    if (s == NULL || s->mode != 'r') return 0;
+    return s->transparent;
+}
+
+/* ===========================================================================
+   Outputs a long in LSB order to the given file
+*/
+local void putLong (file, x)
+    FILE *file;
+    uLong x;
+{
+    int n;
+    for (n = 0; n < 4; n++) {
+        fputc((int)(x & 0xff), file);
+        x >>= 8;
+    }
+}
+
+/* ===========================================================================
+   Reads a long in LSB order from the given gz_stream. Sets z_err in case
+   of error.
+*/
+local uLong getLong (s)
+    gz_stream *s;
+{
+    uLong x = (uLong)get_byte(s);
+    int c;
+
+    x += ((uLong)get_byte(s))<<8;
+    x += ((uLong)get_byte(s))<<16;
+    c = get_byte(s);
+    if (c == EOF) s->z_err = Z_DATA_ERROR;
+    x += ((uLong)c)<<24;
+    return x;
+}
+
+/* ===========================================================================
+     Flushes all pending output if necessary, closes the compressed file
+   and deallocates all the (de)compression state.
+*/
+int ZEXPORT gzclose (file)
+    gzFile file;
+{
+    gz_stream *s = (gz_stream*)file;
+
+    if (s == NULL) return Z_STREAM_ERROR;
+
+    if (s->mode == 'w') {
+#ifdef NO_GZCOMPRESS
+        return Z_STREAM_ERROR;
+#else
+        if (do_flush (file, Z_FINISH) != Z_OK)
+            return destroy((gz_stream*)file);
+
+        putLong (s->file, s->crc);
+        putLong (s->file, (uLong)(s->in & 0xffffffff));
+#endif
+    }
+    return destroy((gz_stream*)file);
+}
+
+#ifdef STDC
+#  define zstrerror(errnum) strerror(errnum)
+#else
+#  define zstrerror(errnum) ""
+#endif
+
+/* ===========================================================================
+     Returns the error message for the last error which occurred on the
+   given compressed file. errnum is set to zlib error number. If an
+   error occurred in the file system and not in the compression library,
+   errnum is set to Z_ERRNO and the application may consult errno
+   to get the exact error code.
+*/
+const char * ZEXPORT gzerror (file, errnum)
+    gzFile file;
+    int *errnum;
+{
+    char *m;
+    gz_stream *s = (gz_stream*)file;
+
+    if (s == NULL) {
+        *errnum = Z_STREAM_ERROR;
+        return (const char*)ERR_MSG(Z_STREAM_ERROR);
+    }
+    *errnum = s->z_err;
+    if (*errnum == Z_OK) return (const char*)"";
+
+    m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg);
+
+    if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err);
+
+    TRYFREE(s->msg);
+    s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3);
+    if (s->msg == Z_NULL) return (const char*)ERR_MSG(Z_MEM_ERROR);
+    strcpy(s->msg, s->path);
+    strcat(s->msg, ": ");
+    strcat(s->msg, m);
+    return (const char*)s->msg;
+}
+
+/* ===========================================================================
+     Clear the error and end-of-file flags, and do the same for the real file.
+*/
+void ZEXPORT gzclearerr (file)
+    gzFile file;
+{
+    gz_stream *s = (gz_stream*)file;
+
+    if (s == NULL) return;
+    if (s->z_err != Z_STREAM_END) s->z_err = Z_OK;
+    s->z_eof = 0;
+    clearerr(s->file);
+}

Added: vendor/Python/current/Modules/zlib/infback.c
===================================================================
--- vendor/Python/current/Modules/zlib/infback.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/zlib/infback.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,623 @@
+/* infback.c -- inflate using a call-back interface
+ * Copyright (C) 1995-2005 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+   This code is largely copied from inflate.c.  Normally either infback.o or
+   inflate.o would be linked into an application--not both.  The interface
+   with inffast.c is retained so that optimized assembler-coded versions of
+   inflate_fast() can be used with either inflate.c or infback.c.
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+/* function prototypes */
+local void fixedtables OF((struct inflate_state FAR *state));
+
+/*
+   strm provides memory allocation functions in zalloc and zfree, or
+   Z_NULL to use the library memory allocation functions.
+
+   windowBits is in the range 8..15, and window is a user-supplied
+   window and output buffer that is 2**windowBits bytes.
+ */
+int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size)
+z_streamp strm;
+int windowBits;
+unsigned char FAR *window;
+const char *version;
+int stream_size;
+{
+    struct inflate_state FAR *state;
+
+    if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
+        stream_size != (int)(sizeof(z_stream)))
+        return Z_VERSION_ERROR;
+    if (strm == Z_NULL || window == Z_NULL ||
+        windowBits < 8 || windowBits > 15)
+        return Z_STREAM_ERROR;
+    strm->msg = Z_NULL;                 /* in case we return an error */
+    if (strm->zalloc == (alloc_func)0) {
+        strm->zalloc = zcalloc;
+        strm->opaque = (voidpf)0;
+    }
+    if (strm->zfree == (free_func)0) strm->zfree = zcfree;
+    state = (struct inflate_state FAR *)ZALLOC(strm, 1,
+                                               sizeof(struct inflate_state));
+    if (state == Z_NULL) return Z_MEM_ERROR;
+    Tracev((stderr, "inflate: allocated\n"));
+    strm->state = (struct internal_state FAR *)state;
+    state->dmax = 32768U;
+    state->wbits = windowBits;
+    state->wsize = 1U << windowBits;
+    state->window = window;
+    state->write = 0;
+    state->whave = 0;
+    return Z_OK;
+}
+
+/*
+   Return state with length and distance decoding tables and index sizes set to
+   fixed code decoding.  Normally this returns fixed tables from inffixed.h.
+   If BUILDFIXED is defined, then instead this routine builds the tables the
+   first time it's called, and returns those tables the first time and
+   thereafter.  This reduces the size of the code by about 2K bytes, in
+   exchange for a little execution time.  However, BUILDFIXED should not be
+   used for threaded applications, since the rewriting of the tables and virgin
+   may not be thread-safe.
+ */
+local void fixedtables(state)
+struct inflate_state FAR *state;
+{
+#ifdef BUILDFIXED
+    static int virgin = 1;
+    static code *lenfix, *distfix;
+    static code fixed[544];
+
+    /* build fixed huffman tables if first call (may not be thread safe) */
+    if (virgin) {
+        unsigned sym, bits;
+        static code *next;
+
+        /* literal/length table */
+        sym = 0;
+        while (sym < 144) state->lens[sym++] = 8;
+        while (sym < 256) state->lens[sym++] = 9;
+        while (sym < 280) state->lens[sym++] = 7;
+        while (sym < 288) state->lens[sym++] = 8;
+        next = fixed;
+        lenfix = next;
+        bits = 9;
+        inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
+
+        /* distance table */
+        sym = 0;
+        while (sym < 32) state->lens[sym++] = 5;
+        distfix = next;
+        bits = 5;
+        inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
+
+        /* do this just once */
+        virgin = 0;
+    }
+#else /* !BUILDFIXED */
+#   include "inffixed.h"
+#endif /* BUILDFIXED */
+    state->lencode = lenfix;
+    state->lenbits = 9;
+    state->distcode = distfix;
+    state->distbits = 5;
+}
+
+/* Macros for inflateBack(): */
+
+/* Load returned state from inflate_fast() */
+#define LOAD() \
+    do { \
+        put = strm->next_out; \
+        left = strm->avail_out; \
+        next = strm->next_in; \
+        have = strm->avail_in; \
+        hold = state->hold; \
+        bits = state->bits; \
+    } while (0)
+
+/* Set state from registers for inflate_fast() */
+#define RESTORE() \
+    do { \
+        strm->next_out = put; \
+        strm->avail_out = left; \
+        strm->next_in = next; \
+        strm->avail_in = have; \
+        state->hold = hold; \
+        state->bits = bits; \
+    } while (0)
+
+/* Clear the input bit accumulator */
+#define INITBITS() \
+    do { \
+        hold = 0; \
+        bits = 0; \
+    } while (0)
+
+/* Assure that some input is available.  If input is requested, but denied,
+   then return a Z_BUF_ERROR from inflateBack(). */
+#define PULL() \
+    do { \
+        if (have == 0) { \
+            have = in(in_desc, &next); \
+            if (have == 0) { \
+                next = Z_NULL; \
+                ret = Z_BUF_ERROR; \
+                goto inf_leave; \
+            } \
+        } \
+    } while (0)
+
+/* Get a byte of input into the bit accumulator, or return from inflateBack()
+   with an error if there is no input available. */
+#define PULLBYTE() \
+    do { \
+        PULL(); \
+        have--; \
+        hold += (unsigned long)(*next++) << bits; \
+        bits += 8; \
+    } while (0)
+
+/* Assure that there are at least n bits in the bit accumulator.  If there is
+   not enough available input to do that, then return from inflateBack() with
+   an error. */
+#define NEEDBITS(n) \
+    do { \
+        while (bits < (unsigned)(n)) \
+            PULLBYTE(); \
+    } while (0)
+
+/* Return the low n bits of the bit accumulator (n < 16) */
+#define BITS(n) \
+    ((unsigned)hold & ((1U << (n)) - 1))
+
+/* Remove n bits from the bit accumulator */
+#define DROPBITS(n) \
+    do { \
+        hold >>= (n); \
+        bits -= (unsigned)(n); \
+    } while (0)
+
+/* Remove zero to seven bits as needed to go to a byte boundary */
+#define BYTEBITS() \
+    do { \
+        hold >>= bits & 7; \
+        bits -= bits & 7; \
+    } while (0)
+
+/* Assure that some output space is available, by writing out the window
+   if it's full.  If the write fails, return from inflateBack() with a
+   Z_BUF_ERROR. */
+#define ROOM() \
+    do { \
+        if (left == 0) { \
+            put = state->window; \
+            left = state->wsize; \
+            state->whave = left; \
+            if (out(out_desc, put, left)) { \
+                ret = Z_BUF_ERROR; \
+                goto inf_leave; \
+            } \
+        } \
+    } while (0)
+
+/*
+   strm provides the memory allocation functions and window buffer on input,
+   and provides information on the unused input on return.  For Z_DATA_ERROR
+   returns, strm will also provide an error message.
+
+   in() and out() are the call-back input and output functions.  When
+   inflateBack() needs more input, it calls in().  When inflateBack() has
+   filled the window with output, or when it completes with data in the
+   window, it calls out() to write out the data.  The application must not
+   change the provided input until in() is called again or inflateBack()
+   returns.  The application must not change the window/output buffer until
+   inflateBack() returns.
+
+   in() and out() are called with a descriptor parameter provided in the
+   inflateBack() call.  This parameter can be a structure that provides the
+   information required to do the read or write, as well as accumulated
+   information on the input and output such as totals and check values.
+
+   in() should return zero on failure.  out() should return non-zero on
+   failure.  If either in() or out() fails, than inflateBack() returns a
+   Z_BUF_ERROR.  strm->next_in can be checked for Z_NULL to see whether it
+   was in() or out() that caused in the error.  Otherwise,  inflateBack()
+   returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format
+   error, or Z_MEM_ERROR if it could not allocate memory for the state.
+   inflateBack() can also return Z_STREAM_ERROR if the input parameters
+   are not correct, i.e. strm is Z_NULL or the state was not initialized.
+ */
+int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc)
+z_streamp strm;
+in_func in;
+void FAR *in_desc;
+out_func out;
+void FAR *out_desc;
+{
+    struct inflate_state FAR *state;
+    unsigned char FAR *next;    /* next input */
+    unsigned char FAR *put;     /* next output */
+    unsigned have, left;        /* available input and output */
+    unsigned long hold;         /* bit buffer */
+    unsigned bits;              /* bits in bit buffer */
+    unsigned copy;              /* number of stored or match bytes to copy */
+    unsigned char FAR *from;    /* where to copy match bytes from */
+    code this;                  /* current decoding table entry */
+    code last;                  /* parent table entry */
+    unsigned len;               /* length to copy for repeats, bits to drop */
+    int ret;                    /* return code */
+    static const unsigned short order[19] = /* permutation of code lengths */
+        {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+    /* Check that the strm exists and that the state was initialized */
+    if (strm == Z_NULL || strm->state == Z_NULL)
+        return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+
+    /* Reset the state */
+    strm->msg = Z_NULL;
+    state->mode = TYPE;
+    state->last = 0;
+    state->whave = 0;
+    next = strm->next_in;
+    have = next != Z_NULL ? strm->avail_in : 0;
+    hold = 0;
+    bits = 0;
+    put = state->window;
+    left = state->wsize;
+
+    /* Inflate until end of block marked as last */
+    for (;;)
+        switch (state->mode) {
+        case TYPE:
+            /* determine and dispatch block type */
+            if (state->last) {
+                BYTEBITS();
+                state->mode = DONE;
+                break;
+            }
+            NEEDBITS(3);
+            state->last = BITS(1);
+            DROPBITS(1);
+            switch (BITS(2)) {
+            case 0:                             /* stored block */
+                Tracev((stderr, "inflate:     stored block%s\n",
+                        state->last ? " (last)" : ""));
+                state->mode = STORED;
+                break;
+            case 1:                             /* fixed block */
+                fixedtables(state);
+                Tracev((stderr, "inflate:     fixed codes block%s\n",
+                        state->last ? " (last)" : ""));
+                state->mode = LEN;              /* decode codes */
+                break;
+            case 2:                             /* dynamic block */
+                Tracev((stderr, "inflate:     dynamic codes block%s\n",
+                        state->last ? " (last)" : ""));
+                state->mode = TABLE;
+                break;
+            case 3:
+                strm->msg = (char *)"invalid block type";
+                state->mode = BAD;
+            }
+            DROPBITS(2);
+            break;
+
+        case STORED:
+            /* get and verify stored block length */
+            BYTEBITS();                         /* go to byte boundary */
+            NEEDBITS(32);
+            if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
+                strm->msg = (char *)"invalid stored block lengths";
+                state->mode = BAD;
+                break;
+            }
+            state->length = (unsigned)hold & 0xffff;
+            Tracev((stderr, "inflate:       stored length %u\n",
+                    state->length));
+            INITBITS();
+
+            /* copy stored block from input to output */
+            while (state->length != 0) {
+                copy = state->length;
+                PULL();
+                ROOM();
+                if (copy > have) copy = have;
+                if (copy > left) copy = left;
+                zmemcpy(put, next, copy);
+                have -= copy;
+                next += copy;
+                left -= copy;
+                put += copy;
+                state->length -= copy;
+            }
+            Tracev((stderr, "inflate:       stored end\n"));
+            state->mode = TYPE;
+            break;
+
+        case TABLE:
+            /* get dynamic table entries descriptor */
+            NEEDBITS(14);
+            state->nlen = BITS(5) + 257;
+            DROPBITS(5);
+            state->ndist = BITS(5) + 1;
+            DROPBITS(5);
+            state->ncode = BITS(4) + 4;
+            DROPBITS(4);
+#ifndef PKZIP_BUG_WORKAROUND
+            if (state->nlen > 286 || state->ndist > 30) {
+                strm->msg = (char *)"too many length or distance symbols";
+                state->mode = BAD;
+                break;
+            }
+#endif
+            Tracev((stderr, "inflate:       table sizes ok\n"));
+
+            /* get code length code lengths (not a typo) */
+            state->have = 0;
+            while (state->have < state->ncode) {
+                NEEDBITS(3);
+                state->lens[order[state->have++]] = (unsigned short)BITS(3);
+                DROPBITS(3);
+            }
+            while (state->have < 19)
+                state->lens[order[state->have++]] = 0;
+            state->next = state->codes;
+            state->lencode = (code const FAR *)(state->next);
+            state->lenbits = 7;
+            ret = inflate_table(CODES, state->lens, 19, &(state->next),
+                                &(state->lenbits), state->work);
+            if (ret) {
+                strm->msg = (char *)"invalid code lengths set";
+                state->mode = BAD;
+                break;
+            }
+            Tracev((stderr, "inflate:       code lengths ok\n"));
+
+            /* get length and distance code code lengths */
+            state->have = 0;
+            while (state->have < state->nlen + state->ndist) {
+                for (;;) {
+                    this = state->lencode[BITS(state->lenbits)];
+                    if ((unsigned)(this.bits) <= bits) break;
+                    PULLBYTE();
+                }
+                if (this.val < 16) {
+                    NEEDBITS(this.bits);
+                    DROPBITS(this.bits);
+                    state->lens[state->have++] = this.val;
+                }
+                else {
+                    if (this.val == 16) {
+                        NEEDBITS(this.bits + 2);
+                        DROPBITS(this.bits);
+                        if (state->have == 0) {
+                            strm->msg = (char *)"invalid bit length repeat";
+                            state->mode = BAD;
+                            break;
+                        }
+                        len = (unsigned)(state->lens[state->have - 1]);
+                        copy = 3 + BITS(2);
+                        DROPBITS(2);
+                    }
+                    else if (this.val == 17) {
+                        NEEDBITS(this.bits + 3);
+                        DROPBITS(this.bits);
+                        len = 0;
+                        copy = 3 + BITS(3);
+                        DROPBITS(3);
+                    }
+                    else {
+                        NEEDBITS(this.bits + 7);
+                        DROPBITS(this.bits);
+                        len = 0;
+                        copy = 11 + BITS(7);
+                        DROPBITS(7);
+                    }
+                    if (state->have + copy > state->nlen + state->ndist) {
+                        strm->msg = (char *)"invalid bit length repeat";
+                        state->mode = BAD;
+                        break;
+                    }
+                    while (copy--)
+                        state->lens[state->have++] = (unsigned short)len;
+                }
+            }
+
+            /* handle error breaks in while */
+            if (state->mode == BAD) break;
+
+            /* build code tables */
+            state->next = state->codes;
+            state->lencode = (code const FAR *)(state->next);
+            state->lenbits = 9;
+            ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
+                                &(state->lenbits), state->work);
+            if (ret) {
+                strm->msg = (char *)"invalid literal/lengths set";
+                state->mode = BAD;
+                break;
+            }
+            state->distcode = (code const FAR *)(state->next);
+            state->distbits = 6;
+            ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
+                            &(state->next), &(state->distbits), state->work);
+            if (ret) {
+                strm->msg = (char *)"invalid distances set";
+                state->mode = BAD;
+                break;
+            }
+            Tracev((stderr, "inflate:       codes ok\n"));
+            state->mode = LEN;
+
+        case LEN:
+            /* use inflate_fast() if we have enough input and output */
+            if (have >= 6 && left >= 258) {
+                RESTORE();
+                if (state->whave < state->wsize)
+                    state->whave = state->wsize - left;
+                inflate_fast(strm, state->wsize);
+                LOAD();
+                break;
+            }
+
+            /* get a literal, length, or end-of-block code */
+            for (;;) {
+                this = state->lencode[BITS(state->lenbits)];
+                if ((unsigned)(this.bits) <= bits) break;
+                PULLBYTE();
+            }
+            if (this.op && (this.op & 0xf0) == 0) {
+                last = this;
+                for (;;) {
+                    this = state->lencode[last.val +
+                            (BITS(last.bits + last.op) >> last.bits)];
+                    if ((unsigned)(last.bits + this.bits) <= bits) break;
+                    PULLBYTE();
+                }
+                DROPBITS(last.bits);
+            }
+            DROPBITS(this.bits);
+            state->length = (unsigned)this.val;
+
+            /* process literal */
+            if (this.op == 0) {
+                Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
+                        "inflate:         literal '%c'\n" :
+                        "inflate:         literal 0x%02x\n", this.val));
+                ROOM();
+                *put++ = (unsigned char)(state->length);
+                left--;
+                state->mode = LEN;
+                break;
+            }
+
+            /* process end of block */
+            if (this.op & 32) {
+                Tracevv((stderr, "inflate:         end of block\n"));
+                state->mode = TYPE;
+                break;
+            }
+
+            /* invalid code */
+            if (this.op & 64) {
+                strm->msg = (char *)"invalid literal/length code";
+                state->mode = BAD;
+                break;
+            }
+
+            /* length code -- get extra bits, if any */
+            state->extra = (unsigned)(this.op) & 15;
+            if (state->extra != 0) {
+                NEEDBITS(state->extra);
+                state->length += BITS(state->extra);
+                DROPBITS(state->extra);
+            }
+            Tracevv((stderr, "inflate:         length %u\n", state->length));
+
+            /* get distance code */
+            for (;;) {
+                this = state->distcode[BITS(state->distbits)];
+                if ((unsigned)(this.bits) <= bits) break;
+                PULLBYTE();
+            }
+            if ((this.op & 0xf0) == 0) {
+                last = this;
+                for (;;) {
+                    this = state->distcode[last.val +
+                            (BITS(last.bits + last.op) >> last.bits)];
+                    if ((unsigned)(last.bits + this.bits) <= bits) break;
+                    PULLBYTE();
+                }
+                DROPBITS(last.bits);
+            }
+            DROPBITS(this.bits);
+            if (this.op & 64) {
+                strm->msg = (char *)"invalid distance code";
+                state->mode = BAD;
+                break;
+            }
+            state->offset = (unsigned)this.val;
+
+            /* get distance extra bits, if any */
+            state->extra = (unsigned)(this.op) & 15;
+            if (state->extra != 0) {
+                NEEDBITS(state->extra);
+                state->offset += BITS(state->extra);
+                DROPBITS(state->extra);
+            }
+            if (state->offset > state->wsize - (state->whave < state->wsize ?
+                                                left : 0)) {
+                strm->msg = (char *)"invalid distance too far back";
+                state->mode = BAD;
+                break;
+            }
+            Tracevv((stderr, "inflate:         distance %u\n", state->offset));
+
+            /* copy match from window to output */
+            do {
+                ROOM();
+                copy = state->wsize - state->offset;
+                if (copy < left) {
+                    from = put + copy;
+                    copy = left - copy;
+                }
+                else {
+                    from = put - state->offset;
+                    copy = left;
+                }
+                if (copy > state->length) copy = state->length;
+                state->length -= copy;
+                left -= copy;
+                do {
+                    *put++ = *from++;
+                } while (--copy);
+            } while (state->length != 0);
+            break;
+
+        case DONE:
+            /* inflate stream terminated properly -- write leftover output */
+            ret = Z_STREAM_END;
+            if (left < state->wsize) {
+                if (out(out_desc, state->window, state->wsize - left))
+                    ret = Z_BUF_ERROR;
+            }
+            goto inf_leave;
+
+        case BAD:
+            ret = Z_DATA_ERROR;
+            goto inf_leave;
+
+        default:                /* can't happen, but makes compilers happy */
+            ret = Z_STREAM_ERROR;
+            goto inf_leave;
+        }
+
+    /* Return unused input */
+  inf_leave:
+    strm->next_in = next;
+    strm->avail_in = have;
+    return ret;
+}
+
+int ZEXPORT inflateBackEnd(strm)
+z_streamp strm;
+{
+    if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
+        return Z_STREAM_ERROR;
+    ZFREE(strm, strm->state);
+    strm->state = Z_NULL;
+    Tracev((stderr, "inflate: end\n"));
+    return Z_OK;
+}

Added: vendor/Python/current/Modules/zlib/inffast.c
===================================================================
--- vendor/Python/current/Modules/zlib/inffast.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/zlib/inffast.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,318 @@
+/* inffast.c -- fast decoding
+ * Copyright (C) 1995-2004 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+#ifndef ASMINF
+
+/* Allow machine dependent optimization for post-increment or pre-increment.
+   Based on testing to date,
+   Pre-increment preferred for:
+   - PowerPC G3 (Adler)
+   - MIPS R5000 (Randers-Pehrson)
+   Post-increment preferred for:
+   - none
+   No measurable difference:
+   - Pentium III (Anderson)
+   - M68060 (Nikl)
+ */
+#ifdef POSTINC
+#  define OFF 0
+#  define PUP(a) *(a)++
+#else
+#  define OFF 1
+#  define PUP(a) *++(a)
+#endif
+
+/*
+   Decode literal, length, and distance codes and write out the resulting
+   literal and match bytes until either not enough input or output is
+   available, an end-of-block is encountered, or a data error is encountered.
+   When large enough input and output buffers are supplied to inflate(), for
+   example, a 16K input buffer and a 64K output buffer, more than 95% of the
+   inflate execution time is spent in this routine.
+
+   Entry assumptions:
+
+        state->mode == LEN
+        strm->avail_in >= 6
+        strm->avail_out >= 258
+        start >= strm->avail_out
+        state->bits < 8
+
+   On return, state->mode is one of:
+
+        LEN -- ran out of enough output space or enough available input
+        TYPE -- reached end of block code, inflate() to interpret next block
+        BAD -- error in block data
+
+   Notes:
+
+    - The maximum input bits used by a length/distance pair is 15 bits for the
+      length code, 5 bits for the length extra, 15 bits for the distance code,
+      and 13 bits for the distance extra.  This totals 48 bits, or six bytes.
+      Therefore if strm->avail_in >= 6, then there is enough input to avoid
+      checking for available input while decoding.
+
+    - The maximum bytes that a single length/distance pair can output is 258
+      bytes, which is the maximum length that can be coded.  inflate_fast()
+      requires strm->avail_out >= 258 for each loop to avoid checking for
+      output space.
+ */
+void inflate_fast(strm, start)
+z_streamp strm;
+unsigned start;         /* inflate()'s starting value for strm->avail_out */
+{
+    struct inflate_state FAR *state;
+    unsigned char FAR *in;      /* local strm->next_in */
+    unsigned char FAR *last;    /* while in < last, enough input available */
+    unsigned char FAR *out;     /* local strm->next_out */
+    unsigned char FAR *beg;     /* inflate()'s initial strm->next_out */
+    unsigned char FAR *end;     /* while out < end, enough space available */
+#ifdef INFLATE_STRICT
+    unsigned dmax;              /* maximum distance from zlib header */
+#endif
+    unsigned wsize;             /* window size or zero if not using window */
+    unsigned whave;             /* valid bytes in the window */
+    unsigned write;             /* window write index */
+    unsigned char FAR *window;  /* allocated sliding window, if wsize != 0 */
+    unsigned long hold;         /* local strm->hold */
+    unsigned bits;              /* local strm->bits */
+    code const FAR *lcode;      /* local strm->lencode */
+    code const FAR *dcode;      /* local strm->distcode */
+    unsigned lmask;             /* mask for first level of length codes */
+    unsigned dmask;             /* mask for first level of distance codes */
+    code this;                  /* retrieved table entry */
+    unsigned op;                /* code bits, operation, extra bits, or */
+                                /*  window position, window bytes to copy */
+    unsigned len;               /* match length, unused bytes */
+    unsigned dist;              /* match distance */
+    unsigned char FAR *from;    /* where to copy match from */
+
+    /* copy state to local variables */
+    state = (struct inflate_state FAR *)strm->state;
+    in = strm->next_in - OFF;
+    last = in + (strm->avail_in - 5);
+    out = strm->next_out - OFF;
+    beg = out - (start - strm->avail_out);
+    end = out + (strm->avail_out - 257);
+#ifdef INFLATE_STRICT
+    dmax = state->dmax;
+#endif
+    wsize = state->wsize;
+    whave = state->whave;
+    write = state->write;
+    window = state->window;
+    hold = state->hold;
+    bits = state->bits;
+    lcode = state->lencode;
+    dcode = state->distcode;
+    lmask = (1U << state->lenbits) - 1;
+    dmask = (1U << state->distbits) - 1;
+
+    /* decode literals and length/distances until end-of-block or not enough
+       input data or output space */
+    do {
+        if (bits < 15) {
+            hold += (unsigned long)(PUP(in)) << bits;
+            bits += 8;
+            hold += (unsigned long)(PUP(in)) << bits;
+            bits += 8;
+        }
+        this = lcode[hold & lmask];
+      dolen:
+        op = (unsigned)(this.bits);
+        hold >>= op;
+        bits -= op;
+        op = (unsigned)(this.op);
+        if (op == 0) {                          /* literal */
+            Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
+                    "inflate:         literal '%c'\n" :
+                    "inflate:         literal 0x%02x\n", this.val));
+            PUP(out) = (unsigned char)(this.val);
+        }
+        else if (op & 16) {                     /* length base */
+            len = (unsigned)(this.val);
+            op &= 15;                           /* number of extra bits */
+            if (op) {
+                if (bits < op) {
+                    hold += (unsigned long)(PUP(in)) << bits;
+                    bits += 8;
+                }
+                len += (unsigned)hold & ((1U << op) - 1);
+                hold >>= op;
+                bits -= op;
+            }
+            Tracevv((stderr, "inflate:         length %u\n", len));
+            if (bits < 15) {
+                hold += (unsigned long)(PUP(in)) << bits;
+                bits += 8;
+                hold += (unsigned long)(PUP(in)) << bits;
+                bits += 8;
+            }
+            this = dcode[hold & dmask];
+          dodist:
+            op = (unsigned)(this.bits);
+            hold >>= op;
+            bits -= op;
+            op = (unsigned)(this.op);
+            if (op & 16) {                      /* distance base */
+                dist = (unsigned)(this.val);
+                op &= 15;                       /* number of extra bits */
+                if (bits < op) {
+                    hold += (unsigned long)(PUP(in)) << bits;
+                    bits += 8;
+                    if (bits < op) {
+                        hold += (unsigned long)(PUP(in)) << bits;
+                        bits += 8;
+                    }
+                }
+                dist += (unsigned)hold & ((1U << op) - 1);
+#ifdef INFLATE_STRICT
+                if (dist > dmax) {
+                    strm->msg = (char *)"invalid distance too far back";
+                    state->mode = BAD;
+                    break;
+                }
+#endif
+                hold >>= op;
+                bits -= op;
+                Tracevv((stderr, "inflate:         distance %u\n", dist));
+                op = (unsigned)(out - beg);     /* max distance in output */
+                if (dist > op) {                /* see if copy from window */
+                    op = dist - op;             /* distance back in window */
+                    if (op > whave) {
+                        strm->msg = (char *)"invalid distance too far back";
+                        state->mode = BAD;
+                        break;
+                    }
+                    from = window - OFF;
+                    if (write == 0) {           /* very common case */
+                        from += wsize - op;
+                        if (op < len) {         /* some from window */
+                            len -= op;
+                            do {
+                                PUP(out) = PUP(from);
+                            } while (--op);
+                            from = out - dist;  /* rest from output */
+                        }
+                    }
+                    else if (write < op) {      /* wrap around window */
+                        from += wsize + write - op;
+                        op -= write;
+                        if (op < len) {         /* some from end of window */
+                            len -= op;
+                            do {
+                                PUP(out) = PUP(from);
+                            } while (--op);
+                            from = window - OFF;
+                            if (write < len) {  /* some from start of window */
+                                op = write;
+                                len -= op;
+                                do {
+                                    PUP(out) = PUP(from);
+                                } while (--op);
+                                from = out - dist;      /* rest from output */
+                            }
+                        }
+                    }
+                    else {                      /* contiguous in window */
+                        from += write - op;
+                        if (op < len) {         /* some from window */
+                            len -= op;
+                            do {
+                                PUP(out) = PUP(from);
+                            } while (--op);
+                            from = out - dist;  /* rest from output */
+                        }
+                    }
+                    while (len > 2) {
+                        PUP(out) = PUP(from);
+                        PUP(out) = PUP(from);
+                        PUP(out) = PUP(from);
+                        len -= 3;
+                    }
+                    if (len) {
+                        PUP(out) = PUP(from);
+                        if (len > 1)
+                            PUP(out) = PUP(from);
+                    }
+                }
+                else {
+                    from = out - dist;          /* copy direct from output */
+                    do {                        /* minimum length is three */
+                        PUP(out) = PUP(from);
+                        PUP(out) = PUP(from);
+                        PUP(out) = PUP(from);
+                        len -= 3;
+                    } while (len > 2);
+                    if (len) {
+                        PUP(out) = PUP(from);
+                        if (len > 1)
+                            PUP(out) = PUP(from);
+                    }
+                }
+            }
+            else if ((op & 64) == 0) {          /* 2nd level distance code */
+                this = dcode[this.val + (hold & ((1U << op) - 1))];
+                goto dodist;
+            }
+            else {
+                strm->msg = (char *)"invalid distance code";
+                state->mode = BAD;
+                break;
+            }
+        }
+        else if ((op & 64) == 0) {              /* 2nd level length code */
+            this = lcode[this.val + (hold & ((1U << op) - 1))];
+            goto dolen;
+        }
+        else if (op & 32) {                     /* end-of-block */
+            Tracevv((stderr, "inflate:         end of block\n"));
+            state->mode = TYPE;
+            break;
+        }
+        else {
+            strm->msg = (char *)"invalid literal/length code";
+            state->mode = BAD;
+            break;
+        }
+    } while (in < last && out < end);
+
+    /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
+    len = bits >> 3;
+    in -= len;
+    bits -= len << 3;
+    hold &= (1U << bits) - 1;
+
+    /* update state and return */
+    strm->next_in = in + OFF;
+    strm->next_out = out + OFF;
+    strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
+    strm->avail_out = (unsigned)(out < end ?
+                                 257 + (end - out) : 257 - (out - end));
+    state->hold = hold;
+    state->bits = bits;
+    return;
+}
+
+/*
+   inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):
+   - Using bit fields for code structure
+   - Different op definition to avoid & for extra bits (do & for table bits)
+   - Three separate decoding do-loops for direct, window, and write == 0
+   - Special case for distance > 1 copies to do overlapped load and store copy
+   - Explicit branch predictions (based on measured branch probabilities)
+   - Deferring match copy and interspersed it with decoding subsequent codes
+   - Swapping literal/length else
+   - Swapping window/direct else
+   - Larger unrolled copy loops (three is about right)
+   - Moving len -= 3 statement into middle of loop
+ */
+
+#endif /* !ASMINF */

Added: vendor/Python/current/Modules/zlib/inffast.h
===================================================================
--- vendor/Python/current/Modules/zlib/inffast.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/zlib/inffast.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,11 @@
+/* inffast.h -- header to use inffast.c
+ * Copyright (C) 1995-2003 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+void inflate_fast OF((z_streamp strm, unsigned start));

Added: vendor/Python/current/Modules/zlib/inffixed.h
===================================================================
--- vendor/Python/current/Modules/zlib/inffixed.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/zlib/inffixed.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,94 @@
+    /* inffixed.h -- table for decoding fixed codes
+     * Generated automatically by makefixed().
+     */
+
+    /* WARNING: this file should *not* be used by applications. It
+       is part of the implementation of the compression library and
+       is subject to change. Applications should only use zlib.h.
+     */
+
+    static const code lenfix[512] = {
+        {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48},
+        {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128},
+        {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59},
+        {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176},
+        {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20},
+        {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100},
+        {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8},
+        {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216},
+        {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76},
+        {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114},
+        {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},
+        {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148},
+        {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42},
+        {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86},
+        {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15},
+        {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236},
+        {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62},
+        {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},
+        {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31},
+        {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162},
+        {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25},
+        {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105},
+        {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4},
+        {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202},
+        {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69},
+        {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125},
+        {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13},
+        {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195},
+        {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35},
+        {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91},
+        {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19},
+        {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246},
+        {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55},
+        {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135},
+        {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99},
+        {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190},
+        {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16},
+        {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96},
+        {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6},
+        {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209},
+        {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},
+        {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116},
+        {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4},
+        {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153},
+        {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44},
+        {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82},
+        {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11},
+        {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},
+        {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58},
+        {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138},
+        {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51},
+        {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173},
+        {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30},
+        {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110},
+        {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0},
+        {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195},
+        {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65},
+        {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121},
+        {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},
+        {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258},
+        {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37},
+        {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93},
+        {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23},
+        {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251},
+        {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51},
+        {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},
+        {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67},
+        {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183},
+        {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23},
+        {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103},
+        {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9},
+        {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223},
+        {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79},
+        {0,9,255}
+    };
+
+    static const code distfix[32] = {
+        {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025},
+        {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193},
+        {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385},
+        {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577},
+        {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073},
+        {22,5,193},{64,5,0}
+    };

Added: vendor/Python/current/Modules/zlib/inflate.c
===================================================================
--- vendor/Python/current/Modules/zlib/inflate.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/zlib/inflate.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1368 @@
+/* inflate.c -- zlib decompression
+ * Copyright (C) 1995-2005 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ * Change history:
+ *
+ * 1.2.beta0    24 Nov 2002
+ * - First version -- complete rewrite of inflate to simplify code, avoid
+ *   creation of window when not needed, minimize use of window when it is
+ *   needed, make inffast.c even faster, implement gzip decoding, and to
+ *   improve code readability and style over the previous zlib inflate code
+ *
+ * 1.2.beta1    25 Nov 2002
+ * - Use pointers for available input and output checking in inffast.c
+ * - Remove input and output counters in inffast.c
+ * - Change inffast.c entry and loop from avail_in >= 7 to >= 6
+ * - Remove unnecessary second byte pull from length extra in inffast.c
+ * - Unroll direct copy to three copies per loop in inffast.c
+ *
+ * 1.2.beta2    4 Dec 2002
+ * - Change external routine names to reduce potential conflicts
+ * - Correct filename to inffixed.h for fixed tables in inflate.c
+ * - Make hbuf[] unsigned char to match parameter type in inflate.c
+ * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset)
+ *   to avoid negation problem on Alphas (64 bit) in inflate.c
+ *
+ * 1.2.beta3    22 Dec 2002
+ * - Add comments on state->bits assertion in inffast.c
+ * - Add comments on op field in inftrees.h
+ * - Fix bug in reuse of allocated window after inflateReset()
+ * - Remove bit fields--back to byte structure for speed
+ * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths
+ * - Change post-increments to pre-increments in inflate_fast(), PPC biased?
+ * - Add compile time option, POSTINC, to use post-increments instead (Intel?)
+ * - Make MATCH copy in inflate() much faster for when inflate_fast() not used
+ * - Use local copies of stream next and avail values, as well as local bit
+ *   buffer and bit count in inflate()--for speed when inflate_fast() not used
+ *
+ * 1.2.beta4    1 Jan 2003
+ * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings
+ * - Move a comment on output buffer sizes from inffast.c to inflate.c
+ * - Add comments in inffast.c to introduce the inflate_fast() routine
+ * - Rearrange window copies in inflate_fast() for speed and simplification
+ * - Unroll last copy for window match in inflate_fast()
+ * - Use local copies of window variables in inflate_fast() for speed
+ * - Pull out common write == 0 case for speed in inflate_fast()
+ * - Make op and len in inflate_fast() unsigned for consistency
+ * - Add FAR to lcode and dcode declarations in inflate_fast()
+ * - Simplified bad distance check in inflate_fast()
+ * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new
+ *   source file infback.c to provide a call-back interface to inflate for
+ *   programs like gzip and unzip -- uses window as output buffer to avoid
+ *   window copying
+ *
+ * 1.2.beta5    1 Jan 2003
+ * - Improved inflateBack() interface to allow the caller to provide initial
+ *   input in strm.
+ * - Fixed stored blocks bug in inflateBack()
+ *
+ * 1.2.beta6    4 Jan 2003
+ * - Added comments in inffast.c on effectiveness of POSTINC
+ * - Typecasting all around to reduce compiler warnings
+ * - Changed loops from while (1) or do {} while (1) to for (;;), again to
+ *   make compilers happy
+ * - Changed type of window in inflateBackInit() to unsigned char *
+ *
+ * 1.2.beta7    27 Jan 2003
+ * - Changed many types to unsigned or unsigned short to avoid warnings
+ * - Added inflateCopy() function
+ *
+ * 1.2.0        9 Mar 2003
+ * - Changed inflateBack() interface to provide separate opaque descriptors
+ *   for the in() and out() functions
+ * - Changed inflateBack() argument and in_func typedef to swap the length
+ *   and buffer address return values for the input function
+ * - Check next_in and next_out for Z_NULL on entry to inflate()
+ *
+ * The history for versions after 1.2.0 are in ChangeLog in zlib distribution.
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+#ifdef MAKEFIXED
+#  ifndef BUILDFIXED
+#    define BUILDFIXED
+#  endif
+#endif
+
+/* function prototypes */
+local void fixedtables OF((struct inflate_state FAR *state));
+local int updatewindow OF((z_streamp strm, unsigned out));
+#ifdef BUILDFIXED
+   void makefixed OF((void));
+#endif
+local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf,
+                              unsigned len));
+
+int ZEXPORT inflateReset(strm)
+z_streamp strm;
+{
+    struct inflate_state FAR *state;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    strm->total_in = strm->total_out = state->total = 0;
+    strm->msg = Z_NULL;
+    strm->adler = 1;        /* to support ill-conceived Java test suite */
+    state->mode = HEAD;
+    state->last = 0;
+    state->havedict = 0;
+    state->dmax = 32768U;
+    state->head = Z_NULL;
+    state->wsize = 0;
+    state->whave = 0;
+    state->write = 0;
+    state->hold = 0;
+    state->bits = 0;
+    state->lencode = state->distcode = state->next = state->codes;
+    Tracev((stderr, "inflate: reset\n"));
+    return Z_OK;
+}
+
+int ZEXPORT inflatePrime(strm, bits, value)
+z_streamp strm;
+int bits;
+int value;
+{
+    struct inflate_state FAR *state;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR;
+    value &= (1L << bits) - 1;
+    state->hold += value << state->bits;
+    state->bits += bits;
+    return Z_OK;
+}
+
+int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)
+z_streamp strm;
+int windowBits;
+const char *version;
+int stream_size;
+{
+    struct inflate_state FAR *state;
+
+    if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
+        stream_size != (int)(sizeof(z_stream)))
+        return Z_VERSION_ERROR;
+    if (strm == Z_NULL) return Z_STREAM_ERROR;
+    strm->msg = Z_NULL;                 /* in case we return an error */
+    if (strm->zalloc == (alloc_func)0) {
+        strm->zalloc = zcalloc;
+        strm->opaque = (voidpf)0;
+    }
+    if (strm->zfree == (free_func)0) strm->zfree = zcfree;
+    state = (struct inflate_state FAR *)
+            ZALLOC(strm, 1, sizeof(struct inflate_state));
+    if (state == Z_NULL) return Z_MEM_ERROR;
+    Tracev((stderr, "inflate: allocated\n"));
+    strm->state = (struct internal_state FAR *)state;
+    if (windowBits < 0) {
+        state->wrap = 0;
+        windowBits = -windowBits;
+    }
+    else {
+        state->wrap = (windowBits >> 4) + 1;
+#ifdef GUNZIP
+        if (windowBits < 48) windowBits &= 15;
+#endif
+    }
+    if (windowBits < 8 || windowBits > 15) {
+        ZFREE(strm, state);
+        strm->state = Z_NULL;
+        return Z_STREAM_ERROR;
+    }
+    state->wbits = (unsigned)windowBits;
+    state->window = Z_NULL;
+    return inflateReset(strm);
+}
+
+int ZEXPORT inflateInit_(strm, version, stream_size)
+z_streamp strm;
+const char *version;
+int stream_size;
+{
+    return inflateInit2_(strm, DEF_WBITS, version, stream_size);
+}
+
+/*
+   Return state with length and distance decoding tables and index sizes set to
+   fixed code decoding.  Normally this returns fixed tables from inffixed.h.
+   If BUILDFIXED is defined, then instead this routine builds the tables the
+   first time it's called, and returns those tables the first time and
+   thereafter.  This reduces the size of the code by about 2K bytes, in
+   exchange for a little execution time.  However, BUILDFIXED should not be
+   used for threaded applications, since the rewriting of the tables and virgin
+   may not be thread-safe.
+ */
+local void fixedtables(state)
+struct inflate_state FAR *state;
+{
+#ifdef BUILDFIXED
+    static int virgin = 1;
+    static code *lenfix, *distfix;
+    static code fixed[544];
+
+    /* build fixed huffman tables if first call (may not be thread safe) */
+    if (virgin) {
+        unsigned sym, bits;
+        static code *next;
+
+        /* literal/length table */
+        sym = 0;
+        while (sym < 144) state->lens[sym++] = 8;
+        while (sym < 256) state->lens[sym++] = 9;
+        while (sym < 280) state->lens[sym++] = 7;
+        while (sym < 288) state->lens[sym++] = 8;
+        next = fixed;
+        lenfix = next;
+        bits = 9;
+        inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
+
+        /* distance table */
+        sym = 0;
+        while (sym < 32) state->lens[sym++] = 5;
+        distfix = next;
+        bits = 5;
+        inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
+
+        /* do this just once */
+        virgin = 0;
+    }
+#else /* !BUILDFIXED */
+#   include "inffixed.h"
+#endif /* BUILDFIXED */
+    state->lencode = lenfix;
+    state->lenbits = 9;
+    state->distcode = distfix;
+    state->distbits = 5;
+}
+
+#ifdef MAKEFIXED
+#include <stdio.h>
+
+/*
+   Write out the inffixed.h that is #include'd above.  Defining MAKEFIXED also
+   defines BUILDFIXED, so the tables are built on the fly.  makefixed() writes
+   those tables to stdout, which would be piped to inffixed.h.  A small program
+   can simply call makefixed to do this:
+
+    void makefixed(void);
+
+    int main(void)
+    {
+        makefixed();
+        return 0;
+    }
+
+   Then that can be linked with zlib built with MAKEFIXED defined and run:
+
+    a.out > inffixed.h
+ */
+void makefixed()
+{
+    unsigned low, size;
+    struct inflate_state state;
+
+    fixedtables(&state);
+    puts("    /* inffixed.h -- table for decoding fixed codes");
+    puts("     * Generated automatically by makefixed().");
+    puts("     */");
+    puts("");
+    puts("    /* WARNING: this file should *not* be used by applications.");
+    puts("       It is part of the implementation of this library and is");
+    puts("       subject to change. Applications should only use zlib.h.");
+    puts("     */");
+    puts("");
+    size = 1U << 9;
+    printf("    static const code lenfix[%u] = {", size);
+    low = 0;
+    for (;;) {
+        if ((low % 7) == 0) printf("\n        ");
+        printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits,
+               state.lencode[low].val);
+        if (++low == size) break;
+        putchar(',');
+    }
+    puts("\n    };");
+    size = 1U << 5;
+    printf("\n    static const code distfix[%u] = {", size);
+    low = 0;
+    for (;;) {
+        if ((low % 6) == 0) printf("\n        ");
+        printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits,
+               state.distcode[low].val);
+        if (++low == size) break;
+        putchar(',');
+    }
+    puts("\n    };");
+}
+#endif /* MAKEFIXED */
+
+/*
+   Update the window with the last wsize (normally 32K) bytes written before
+   returning.  If window does not exist yet, create it.  This is only called
+   when a window is already in use, or when output has been written during this
+   inflate call, but the end of the deflate stream has not been reached yet.
+   It is also called to create a window for dictionary data when a dictionary
+   is loaded.
+
+   Providing output buffers larger than 32K to inflate() should provide a speed
+   advantage, since only the last 32K of output is copied to the sliding window
+   upon return from inflate(), and since all distances after the first 32K of
+   output will fall in the output data, making match copies simpler and faster.
+   The advantage may be dependent on the size of the processor's data caches.
+ */
+local int updatewindow(strm, out)
+z_streamp strm;
+unsigned out;
+{
+    struct inflate_state FAR *state;
+    unsigned copy, dist;
+
+    state = (struct inflate_state FAR *)strm->state;
+
+    /* if it hasn't been done already, allocate space for the window */
+    if (state->window == Z_NULL) {
+        state->window = (unsigned char FAR *)
+                        ZALLOC(strm, 1U << state->wbits,
+                               sizeof(unsigned char));
+        if (state->window == Z_NULL) return 1;
+    }
+
+    /* if window not in use yet, initialize */
+    if (state->wsize == 0) {
+        state->wsize = 1U << state->wbits;
+        state->write = 0;
+        state->whave = 0;
+    }
+
+    /* copy state->wsize or less output bytes into the circular window */
+    copy = out - strm->avail_out;
+    if (copy >= state->wsize) {
+        zmemcpy(state->window, strm->next_out - state->wsize, state->wsize);
+        state->write = 0;
+        state->whave = state->wsize;
+    }
+    else {
+        dist = state->wsize - state->write;
+        if (dist > copy) dist = copy;
+        zmemcpy(state->window + state->write, strm->next_out - copy, dist);
+        copy -= dist;
+        if (copy) {
+            zmemcpy(state->window, strm->next_out - copy, copy);
+            state->write = copy;
+            state->whave = state->wsize;
+        }
+        else {
+            state->write += dist;
+            if (state->write == state->wsize) state->write = 0;
+            if (state->whave < state->wsize) state->whave += dist;
+        }
+    }
+    return 0;
+}
+
+/* Macros for inflate(): */
+
+/* check function to use adler32() for zlib or crc32() for gzip */
+#ifdef GUNZIP
+#  define UPDATE(check, buf, len) \
+    (state->flags ? crc32(check, buf, len) : adler32(check, buf, len))
+#else
+#  define UPDATE(check, buf, len) adler32(check, buf, len)
+#endif
+
+/* check macros for header crc */
+#ifdef GUNZIP
+#  define CRC2(check, word) \
+    do { \
+        hbuf[0] = (unsigned char)(word); \
+        hbuf[1] = (unsigned char)((word) >> 8); \
+        check = crc32(check, hbuf, 2); \
+    } while (0)
+
+#  define CRC4(check, word) \
+    do { \
+        hbuf[0] = (unsigned char)(word); \
+        hbuf[1] = (unsigned char)((word) >> 8); \
+        hbuf[2] = (unsigned char)((word) >> 16); \
+        hbuf[3] = (unsigned char)((word) >> 24); \
+        check = crc32(check, hbuf, 4); \
+    } while (0)
+#endif
+
+/* Load registers with state in inflate() for speed */
+#define LOAD() \
+    do { \
+        put = strm->next_out; \
+        left = strm->avail_out; \
+        next = strm->next_in; \
+        have = strm->avail_in; \
+        hold = state->hold; \
+        bits = state->bits; \
+    } while (0)
+
+/* Restore state from registers in inflate() */
+#define RESTORE() \
+    do { \
+        strm->next_out = put; \
+        strm->avail_out = left; \
+        strm->next_in = next; \
+        strm->avail_in = have; \
+        state->hold = hold; \
+        state->bits = bits; \
+    } while (0)
+
+/* Clear the input bit accumulator */
+#define INITBITS() \
+    do { \
+        hold = 0; \
+        bits = 0; \
+    } while (0)
+
+/* Get a byte of input into the bit accumulator, or return from inflate()
+   if there is no input available. */
+#define PULLBYTE() \
+    do { \
+        if (have == 0) goto inf_leave; \
+        have--; \
+        hold += (unsigned long)(*next++) << bits; \
+        bits += 8; \
+    } while (0)
+
+/* Assure that there are at least n bits in the bit accumulator.  If there is
+   not enough available input to do that, then return from inflate(). */
+#define NEEDBITS(n) \
+    do { \
+        while (bits < (unsigned)(n)) \
+            PULLBYTE(); \
+    } while (0)
+
+/* Return the low n bits of the bit accumulator (n < 16) */
+#define BITS(n) \
+    ((unsigned)hold & ((1U << (n)) - 1))
+
+/* Remove n bits from the bit accumulator */
+#define DROPBITS(n) \
+    do { \
+        hold >>= (n); \
+        bits -= (unsigned)(n); \
+    } while (0)
+
+/* Remove zero to seven bits as needed to go to a byte boundary */
+#define BYTEBITS() \
+    do { \
+        hold >>= bits & 7; \
+        bits -= bits & 7; \
+    } while (0)
+
+/* Reverse the bytes in a 32-bit value */
+#define REVERSE(q) \
+    ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
+     (((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
+
+/*
+   inflate() uses a state machine to process as much input data and generate as
+   much output data as possible before returning.  The state machine is
+   structured roughly as follows:
+
+    for (;;) switch (state) {
+    ...
+    case STATEn:
+        if (not enough input data or output space to make progress)
+            return;
+        ... make progress ...
+        state = STATEm;
+        break;
+    ...
+    }
+
+   so when inflate() is called again, the same case is attempted again, and
+   if the appropriate resources are provided, the machine proceeds to the
+   next state.  The NEEDBITS() macro is usually the way the state evaluates
+   whether it can proceed or should return.  NEEDBITS() does the return if
+   the requested bits are not available.  The typical use of the BITS macros
+   is:
+
+        NEEDBITS(n);
+        ... do something with BITS(n) ...
+        DROPBITS(n);
+
+   where NEEDBITS(n) either returns from inflate() if there isn't enough
+   input left to load n bits into the accumulator, or it continues.  BITS(n)
+   gives the low n bits in the accumulator.  When done, DROPBITS(n) drops
+   the low n bits off the accumulator.  INITBITS() clears the accumulator
+   and sets the number of available bits to zero.  BYTEBITS() discards just
+   enough bits to put the accumulator on a byte boundary.  After BYTEBITS()
+   and a NEEDBITS(8), then BITS(8) would return the next byte in the stream.
+
+   NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return
+   if there is no input available.  The decoding of variable length codes uses
+   PULLBYTE() directly in order to pull just enough bytes to decode the next
+   code, and no more.
+
+   Some states loop until they get enough input, making sure that enough
+   state information is maintained to continue the loop where it left off
+   if NEEDBITS() returns in the loop.  For example, want, need, and keep
+   would all have to actually be part of the saved state in case NEEDBITS()
+   returns:
+
+    case STATEw:
+        while (want < need) {
+            NEEDBITS(n);
+            keep[want++] = BITS(n);
+            DROPBITS(n);
+        }
+        state = STATEx;
+    case STATEx:
+
+   As shown above, if the next state is also the next case, then the break
+   is omitted.
+
+   A state may also return if there is not enough output space available to
+   complete that state.  Those states are copying stored data, writing a
+   literal byte, and copying a matching string.
+
+   When returning, a "goto inf_leave" is used to update the total counters,
+   update the check value, and determine whether any progress has been made
+   during that inflate() call in order to return the proper return code.
+   Progress is defined as a change in either strm->avail_in or strm->avail_out.
+   When there is a window, goto inf_leave will update the window with the last
+   output written.  If a goto inf_leave occurs in the middle of decompression
+   and there is no window currently, goto inf_leave will create one and copy
+   output to the window for the next call of inflate().
+
+   In this implementation, the flush parameter of inflate() only affects the
+   return code (per zlib.h).  inflate() always writes as much as possible to
+   strm->next_out, given the space available and the provided input--the effect
+   documented in zlib.h of Z_SYNC_FLUSH.  Furthermore, inflate() always defers
+   the allocation of and copying into a sliding window until necessary, which
+   provides the effect documented in zlib.h for Z_FINISH when the entire input
+   stream available.  So the only thing the flush parameter actually does is:
+   when flush is set to Z_FINISH, inflate() cannot return Z_OK.  Instead it
+   will return Z_BUF_ERROR if it has not reached the end of the stream.
+ */
+
+int ZEXPORT inflate(strm, flush)
+z_streamp strm;
+int flush;
+{
+    struct inflate_state FAR *state;
+    unsigned char FAR *next;    /* next input */
+    unsigned char FAR *put;     /* next output */
+    unsigned have, left;        /* available input and output */
+    unsigned long hold;         /* bit buffer */
+    unsigned bits;              /* bits in bit buffer */
+    unsigned in, out;           /* save starting available input and output */
+    unsigned copy;              /* number of stored or match bytes to copy */
+    unsigned char FAR *from;    /* where to copy match bytes from */
+    code this;                  /* current decoding table entry */
+    code last;                  /* parent table entry */
+    unsigned len;               /* length to copy for repeats, bits to drop */
+    int ret;                    /* return code */
+#ifdef GUNZIP
+    unsigned char hbuf[4];      /* buffer for gzip header crc calculation */
+#endif
+    static const unsigned short order[19] = /* permutation of code lengths */
+        {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+    if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL ||
+        (strm->next_in == Z_NULL && strm->avail_in != 0))
+        return Z_STREAM_ERROR;
+
+    state = (struct inflate_state FAR *)strm->state;
+    if (state->mode == TYPE) state->mode = TYPEDO;      /* skip check */
+    LOAD();
+    in = have;
+    out = left;
+    ret = Z_OK;
+    for (;;)
+        switch (state->mode) {
+        case HEAD:
+            if (state->wrap == 0) {
+                state->mode = TYPEDO;
+                break;
+            }
+            NEEDBITS(16);
+#ifdef GUNZIP
+            if ((state->wrap & 2) && hold == 0x8b1f) {  /* gzip header */
+                state->check = crc32(0L, Z_NULL, 0);
+                CRC2(state->check, hold);
+                INITBITS();
+                state->mode = FLAGS;
+                break;
+            }
+            state->flags = 0;           /* expect zlib header */
+            if (state->head != Z_NULL)
+                state->head->done = -1;
+            if (!(state->wrap & 1) ||   /* check if zlib header allowed */
+#else
+            if (
+#endif
+                ((BITS(8) << 8) + (hold >> 8)) % 31) {
+                strm->msg = (char *)"incorrect header check";
+                state->mode = BAD;
+                break;
+            }
+            if (BITS(4) != Z_DEFLATED) {
+                strm->msg = (char *)"unknown compression method";
+                state->mode = BAD;
+                break;
+            }
+            DROPBITS(4);
+            len = BITS(4) + 8;
+            if (len > state->wbits) {
+                strm->msg = (char *)"invalid window size";
+                state->mode = BAD;
+                break;
+            }
+            state->dmax = 1U << len;
+            Tracev((stderr, "inflate:   zlib header ok\n"));
+            strm->adler = state->check = adler32(0L, Z_NULL, 0);
+            state->mode = hold & 0x200 ? DICTID : TYPE;
+            INITBITS();
+            break;
+#ifdef GUNZIP
+        case FLAGS:
+            NEEDBITS(16);
+            state->flags = (int)(hold);
+            if ((state->flags & 0xff) != Z_DEFLATED) {
+                strm->msg = (char *)"unknown compression method";
+                state->mode = BAD;
+                break;
+            }
+            if (state->flags & 0xe000) {
+                strm->msg = (char *)"unknown header flags set";
+                state->mode = BAD;
+                break;
+            }
+            if (state->head != Z_NULL)
+                state->head->text = (int)((hold >> 8) & 1);
+            if (state->flags & 0x0200) CRC2(state->check, hold);
+            INITBITS();
+            state->mode = TIME;
+        case TIME:
+            NEEDBITS(32);
+            if (state->head != Z_NULL)
+                state->head->time = hold;
+            if (state->flags & 0x0200) CRC4(state->check, hold);
+            INITBITS();
+            state->mode = OS;
+        case OS:
+            NEEDBITS(16);
+            if (state->head != Z_NULL) {
+                state->head->xflags = (int)(hold & 0xff);
+                state->head->os = (int)(hold >> 8);
+            }
+            if (state->flags & 0x0200) CRC2(state->check, hold);
+            INITBITS();
+            state->mode = EXLEN;
+        case EXLEN:
+            if (state->flags & 0x0400) {
+                NEEDBITS(16);
+                state->length = (unsigned)(hold);
+                if (state->head != Z_NULL)
+                    state->head->extra_len = (unsigned)hold;
+                if (state->flags & 0x0200) CRC2(state->check, hold);
+                INITBITS();
+            }
+            else if (state->head != Z_NULL)
+                state->head->extra = Z_NULL;
+            state->mode = EXTRA;
+        case EXTRA:
+            if (state->flags & 0x0400) {
+                copy = state->length;
+                if (copy > have) copy = have;
+                if (copy) {
+                    if (state->head != Z_NULL &&
+                        state->head->extra != Z_NULL) {
+                        len = state->head->extra_len - state->length;
+                        zmemcpy(state->head->extra + len, next,
+                                len + copy > state->head->extra_max ?
+                                state->head->extra_max - len : copy);
+                    }
+                    if (state->flags & 0x0200)
+                        state->check = crc32(state->check, next, copy);
+                    have -= copy;
+                    next += copy;
+                    state->length -= copy;
+                }
+                if (state->length) goto inf_leave;
+            }
+            state->length = 0;
+            state->mode = NAME;
+        case NAME:
+            if (state->flags & 0x0800) {
+                if (have == 0) goto inf_leave;
+                copy = 0;
+                do {
+                    len = (unsigned)(next[copy++]);
+                    if (state->head != Z_NULL &&
+                            state->head->name != Z_NULL &&
+                            state->length < state->head->name_max)
+                        state->head->name[state->length++] = len;
+                } while (len && copy < have);
+                if (state->flags & 0x0200)
+                    state->check = crc32(state->check, next, copy);
+                have -= copy;
+                next += copy;
+                if (len) goto inf_leave;
+            }
+            else if (state->head != Z_NULL)
+                state->head->name = Z_NULL;
+            state->length = 0;
+            state->mode = COMMENT;
+        case COMMENT:
+            if (state->flags & 0x1000) {
+                if (have == 0) goto inf_leave;
+                copy = 0;
+                do {
+                    len = (unsigned)(next[copy++]);
+                    if (state->head != Z_NULL &&
+                            state->head->comment != Z_NULL &&
+                            state->length < state->head->comm_max)
+                        state->head->comment[state->length++] = len;
+                } while (len && copy < have);
+                if (state->flags & 0x0200)
+                    state->check = crc32(state->check, next, copy);
+                have -= copy;
+                next += copy;
+                if (len) goto inf_leave;
+            }
+            else if (state->head != Z_NULL)
+                state->head->comment = Z_NULL;
+            state->mode = HCRC;
+        case HCRC:
+            if (state->flags & 0x0200) {
+                NEEDBITS(16);
+                if (hold != (state->check & 0xffff)) {
+                    strm->msg = (char *)"header crc mismatch";
+                    state->mode = BAD;
+                    break;
+                }
+                INITBITS();
+            }
+            if (state->head != Z_NULL) {
+                state->head->hcrc = (int)((state->flags >> 9) & 1);
+                state->head->done = 1;
+            }
+            strm->adler = state->check = crc32(0L, Z_NULL, 0);
+            state->mode = TYPE;
+            break;
+#endif
+        case DICTID:
+            NEEDBITS(32);
+            strm->adler = state->check = REVERSE(hold);
+            INITBITS();
+            state->mode = DICT;
+        case DICT:
+            if (state->havedict == 0) {
+                RESTORE();
+                return Z_NEED_DICT;
+            }
+            strm->adler = state->check = adler32(0L, Z_NULL, 0);
+            state->mode = TYPE;
+        case TYPE:
+            if (flush == Z_BLOCK) goto inf_leave;
+        case TYPEDO:
+            if (state->last) {
+                BYTEBITS();
+                state->mode = CHECK;
+                break;
+            }
+            NEEDBITS(3);
+            state->last = BITS(1);
+            DROPBITS(1);
+            switch (BITS(2)) {
+            case 0:                             /* stored block */
+                Tracev((stderr, "inflate:     stored block%s\n",
+                        state->last ? " (last)" : ""));
+                state->mode = STORED;
+                break;
+            case 1:                             /* fixed block */
+                fixedtables(state);
+                Tracev((stderr, "inflate:     fixed codes block%s\n",
+                        state->last ? " (last)" : ""));
+                state->mode = LEN;              /* decode codes */
+                break;
+            case 2:                             /* dynamic block */
+                Tracev((stderr, "inflate:     dynamic codes block%s\n",
+                        state->last ? " (last)" : ""));
+                state->mode = TABLE;
+                break;
+            case 3:
+                strm->msg = (char *)"invalid block type";
+                state->mode = BAD;
+            }
+            DROPBITS(2);
+            break;
+        case STORED:
+            BYTEBITS();                         /* go to byte boundary */
+            NEEDBITS(32);
+            if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
+                strm->msg = (char *)"invalid stored block lengths";
+                state->mode = BAD;
+                break;
+            }
+            state->length = (unsigned)hold & 0xffff;
+            Tracev((stderr, "inflate:       stored length %u\n",
+                    state->length));
+            INITBITS();
+            state->mode = COPY;
+        case COPY:
+            copy = state->length;
+            if (copy) {
+                if (copy > have) copy = have;
+                if (copy > left) copy = left;
+                if (copy == 0) goto inf_leave;
+                zmemcpy(put, next, copy);
+                have -= copy;
+                next += copy;
+                left -= copy;
+                put += copy;
+                state->length -= copy;
+                break;
+            }
+            Tracev((stderr, "inflate:       stored end\n"));
+            state->mode = TYPE;
+            break;
+        case TABLE:
+            NEEDBITS(14);
+            state->nlen = BITS(5) + 257;
+            DROPBITS(5);
+            state->ndist = BITS(5) + 1;
+            DROPBITS(5);
+            state->ncode = BITS(4) + 4;
+            DROPBITS(4);
+#ifndef PKZIP_BUG_WORKAROUND
+            if (state->nlen > 286 || state->ndist > 30) {
+                strm->msg = (char *)"too many length or distance symbols";
+                state->mode = BAD;
+                break;
+            }
+#endif
+            Tracev((stderr, "inflate:       table sizes ok\n"));
+            state->have = 0;
+            state->mode = LENLENS;
+        case LENLENS:
+            while (state->have < state->ncode) {
+                NEEDBITS(3);
+                state->lens[order[state->have++]] = (unsigned short)BITS(3);
+                DROPBITS(3);
+            }
+            while (state->have < 19)
+                state->lens[order[state->have++]] = 0;
+            state->next = state->codes;
+            state->lencode = (code const FAR *)(state->next);
+            state->lenbits = 7;
+            ret = inflate_table(CODES, state->lens, 19, &(state->next),
+                                &(state->lenbits), state->work);
+            if (ret) {
+                strm->msg = (char *)"invalid code lengths set";
+                state->mode = BAD;
+                break;
+            }
+            Tracev((stderr, "inflate:       code lengths ok\n"));
+            state->have = 0;
+            state->mode = CODELENS;
+        case CODELENS:
+            while (state->have < state->nlen + state->ndist) {
+                for (;;) {
+                    this = state->lencode[BITS(state->lenbits)];
+                    if ((unsigned)(this.bits) <= bits) break;
+                    PULLBYTE();
+                }
+                if (this.val < 16) {
+                    NEEDBITS(this.bits);
+                    DROPBITS(this.bits);
+                    state->lens[state->have++] = this.val;
+                }
+                else {
+                    if (this.val == 16) {
+                        NEEDBITS(this.bits + 2);
+                        DROPBITS(this.bits);
+                        if (state->have == 0) {
+                            strm->msg = (char *)"invalid bit length repeat";
+                            state->mode = BAD;
+                            break;
+                        }
+                        len = state->lens[state->have - 1];
+                        copy = 3 + BITS(2);
+                        DROPBITS(2);
+                    }
+                    else if (this.val == 17) {
+                        NEEDBITS(this.bits + 3);
+                        DROPBITS(this.bits);
+                        len = 0;
+                        copy = 3 + BITS(3);
+                        DROPBITS(3);
+                    }
+                    else {
+                        NEEDBITS(this.bits + 7);
+                        DROPBITS(this.bits);
+                        len = 0;
+                        copy = 11 + BITS(7);
+                        DROPBITS(7);
+                    }
+                    if (state->have + copy > state->nlen + state->ndist) {
+                        strm->msg = (char *)"invalid bit length repeat";
+                        state->mode = BAD;
+                        break;
+                    }
+                    while (copy--)
+                        state->lens[state->have++] = (unsigned short)len;
+                }
+            }
+
+            /* handle error breaks in while */
+            if (state->mode == BAD) break;
+
+            /* build code tables */
+            state->next = state->codes;
+            state->lencode = (code const FAR *)(state->next);
+            state->lenbits = 9;
+            ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
+                                &(state->lenbits), state->work);
+            if (ret) {
+                strm->msg = (char *)"invalid literal/lengths set";
+                state->mode = BAD;
+                break;
+            }
+            state->distcode = (code const FAR *)(state->next);
+            state->distbits = 6;
+            ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
+                            &(state->next), &(state->distbits), state->work);
+            if (ret) {
+                strm->msg = (char *)"invalid distances set";
+                state->mode = BAD;
+                break;
+            }
+            Tracev((stderr, "inflate:       codes ok\n"));
+            state->mode = LEN;
+        case LEN:
+            if (have >= 6 && left >= 258) {
+                RESTORE();
+                inflate_fast(strm, out);
+                LOAD();
+                break;
+            }
+            for (;;) {
+                this = state->lencode[BITS(state->lenbits)];
+                if ((unsigned)(this.bits) <= bits) break;
+                PULLBYTE();
+            }
+            if (this.op && (this.op & 0xf0) == 0) {
+                last = this;
+                for (;;) {
+                    this = state->lencode[last.val +
+                            (BITS(last.bits + last.op) >> last.bits)];
+                    if ((unsigned)(last.bits + this.bits) <= bits) break;
+                    PULLBYTE();
+                }
+                DROPBITS(last.bits);
+            }
+            DROPBITS(this.bits);
+            state->length = (unsigned)this.val;
+            if ((int)(this.op) == 0) {
+                Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
+                        "inflate:         literal '%c'\n" :
+                        "inflate:         literal 0x%02x\n", this.val));
+                state->mode = LIT;
+                break;
+            }
+            if (this.op & 32) {
+                Tracevv((stderr, "inflate:         end of block\n"));
+                state->mode = TYPE;
+                break;
+            }
+            if (this.op & 64) {
+                strm->msg = (char *)"invalid literal/length code";
+                state->mode = BAD;
+                break;
+            }
+            state->extra = (unsigned)(this.op) & 15;
+            state->mode = LENEXT;
+        case LENEXT:
+            if (state->extra) {
+                NEEDBITS(state->extra);
+                state->length += BITS(state->extra);
+                DROPBITS(state->extra);
+            }
+            Tracevv((stderr, "inflate:         length %u\n", state->length));
+            state->mode = DIST;
+        case DIST:
+            for (;;) {
+                this = state->distcode[BITS(state->distbits)];
+                if ((unsigned)(this.bits) <= bits) break;
+                PULLBYTE();
+            }
+            if ((this.op & 0xf0) == 0) {
+                last = this;
+                for (;;) {
+                    this = state->distcode[last.val +
+                            (BITS(last.bits + last.op) >> last.bits)];
+                    if ((unsigned)(last.bits + this.bits) <= bits) break;
+                    PULLBYTE();
+                }
+                DROPBITS(last.bits);
+            }
+            DROPBITS(this.bits);
+            if (this.op & 64) {
+                strm->msg = (char *)"invalid distance code";
+                state->mode = BAD;
+                break;
+            }
+            state->offset = (unsigned)this.val;
+            state->extra = (unsigned)(this.op) & 15;
+            state->mode = DISTEXT;
+        case DISTEXT:
+            if (state->extra) {
+                NEEDBITS(state->extra);
+                state->offset += BITS(state->extra);
+                DROPBITS(state->extra);
+            }
+#ifdef INFLATE_STRICT
+            if (state->offset > state->dmax) {
+                strm->msg = (char *)"invalid distance too far back";
+                state->mode = BAD;
+                break;
+            }
+#endif
+            if (state->offset > state->whave + out - left) {
+                strm->msg = (char *)"invalid distance too far back";
+                state->mode = BAD;
+                break;
+            }
+            Tracevv((stderr, "inflate:         distance %u\n", state->offset));
+            state->mode = MATCH;
+        case MATCH:
+            if (left == 0) goto inf_leave;
+            copy = out - left;
+            if (state->offset > copy) {         /* copy from window */
+                copy = state->offset - copy;
+                if (copy > state->write) {
+                    copy -= state->write;
+                    from = state->window + (state->wsize - copy);
+                }
+                else
+                    from = state->window + (state->write - copy);
+                if (copy > state->length) copy = state->length;
+            }
+            else {                              /* copy from output */
+                from = put - state->offset;
+                copy = state->length;
+            }
+            if (copy > left) copy = left;
+            left -= copy;
+            state->length -= copy;
+            do {
+                *put++ = *from++;
+            } while (--copy);
+            if (state->length == 0) state->mode = LEN;
+            break;
+        case LIT:
+            if (left == 0) goto inf_leave;
+            *put++ = (unsigned char)(state->length);
+            left--;
+            state->mode = LEN;
+            break;
+        case CHECK:
+            if (state->wrap) {
+                NEEDBITS(32);
+                out -= left;
+                strm->total_out += out;
+                state->total += out;
+                if (out)
+                    strm->adler = state->check =
+                        UPDATE(state->check, put - out, out);
+                out = left;
+                if ((
+#ifdef GUNZIP
+                     state->flags ? hold :
+#endif
+                     REVERSE(hold)) != state->check) {
+                    strm->msg = (char *)"incorrect data check";
+                    state->mode = BAD;
+                    break;
+                }
+                INITBITS();
+                Tracev((stderr, "inflate:   check matches trailer\n"));
+            }
+#ifdef GUNZIP
+            state->mode = LENGTH;
+        case LENGTH:
+            if (state->wrap && state->flags) {
+                NEEDBITS(32);
+                if (hold != (state->total & 0xffffffffUL)) {
+                    strm->msg = (char *)"incorrect length check";
+                    state->mode = BAD;
+                    break;
+                }
+                INITBITS();
+                Tracev((stderr, "inflate:   length matches trailer\n"));
+            }
+#endif
+            state->mode = DONE;
+        case DONE:
+            ret = Z_STREAM_END;
+            goto inf_leave;
+        case BAD:
+            ret = Z_DATA_ERROR;
+            goto inf_leave;
+        case MEM:
+            return Z_MEM_ERROR;
+        case SYNC:
+        default:
+            return Z_STREAM_ERROR;
+        }
+
+    /*
+       Return from inflate(), updating the total counts and the check value.
+       If there was no progress during the inflate() call, return a buffer
+       error.  Call updatewindow() to create and/or update the window state.
+       Note: a memory error from inflate() is non-recoverable.
+     */
+  inf_leave:
+    RESTORE();
+    if (state->wsize || (state->mode < CHECK && out != strm->avail_out))
+        if (updatewindow(strm, out)) {
+            state->mode = MEM;
+            return Z_MEM_ERROR;
+        }
+    in -= strm->avail_in;
+    out -= strm->avail_out;
+    strm->total_in += in;
+    strm->total_out += out;
+    state->total += out;
+    if (state->wrap && out)
+        strm->adler = state->check =
+            UPDATE(state->check, strm->next_out - out, out);
+    strm->data_type = state->bits + (state->last ? 64 : 0) +
+                      (state->mode == TYPE ? 128 : 0);
+    if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
+        ret = Z_BUF_ERROR;
+    return ret;
+}
+
+int ZEXPORT inflateEnd(strm)
+z_streamp strm;
+{
+    struct inflate_state FAR *state;
+    if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
+        return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    if (state->window != Z_NULL) ZFREE(strm, state->window);
+    ZFREE(strm, strm->state);
+    strm->state = Z_NULL;
+    Tracev((stderr, "inflate: end\n"));
+    return Z_OK;
+}
+
+int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength)
+z_streamp strm;
+const Bytef *dictionary;
+uInt dictLength;
+{
+    struct inflate_state FAR *state;
+    unsigned long id;
+
+    /* check state */
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    if (state->wrap != 0 && state->mode != DICT)
+        return Z_STREAM_ERROR;
+
+    /* check for correct dictionary id */
+    if (state->mode == DICT) {
+        id = adler32(0L, Z_NULL, 0);
+        id = adler32(id, dictionary, dictLength);
+        if (id != state->check)
+            return Z_DATA_ERROR;
+    }
+
+    /* copy dictionary to window */
+    if (updatewindow(strm, strm->avail_out)) {
+        state->mode = MEM;
+        return Z_MEM_ERROR;
+    }
+    if (dictLength > state->wsize) {
+        zmemcpy(state->window, dictionary + dictLength - state->wsize,
+                state->wsize);
+        state->whave = state->wsize;
+    }
+    else {
+        zmemcpy(state->window + state->wsize - dictLength, dictionary,
+                dictLength);
+        state->whave = dictLength;
+    }
+    state->havedict = 1;
+    Tracev((stderr, "inflate:   dictionary set\n"));
+    return Z_OK;
+}
+
+int ZEXPORT inflateGetHeader(strm, head)
+z_streamp strm;
+gz_headerp head;
+{
+    struct inflate_state FAR *state;
+
+    /* check state */
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    if ((state->wrap & 2) == 0) return Z_STREAM_ERROR;
+
+    /* save header structure */
+    state->head = head;
+    head->done = 0;
+    return Z_OK;
+}
+
+/*
+   Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff.  Return when found
+   or when out of input.  When called, *have is the number of pattern bytes
+   found in order so far, in 0..3.  On return *have is updated to the new
+   state.  If on return *have equals four, then the pattern was found and the
+   return value is how many bytes were read including the last byte of the
+   pattern.  If *have is less than four, then the pattern has not been found
+   yet and the return value is len.  In the latter case, syncsearch() can be
+   called again with more data and the *have state.  *have is initialized to
+   zero for the first call.
+ */
+local unsigned syncsearch(have, buf, len)
+unsigned FAR *have;
+unsigned char FAR *buf;
+unsigned len;
+{
+    unsigned got;
+    unsigned next;
+
+    got = *have;
+    next = 0;
+    while (next < len && got < 4) {
+        if ((int)(buf[next]) == (got < 2 ? 0 : 0xff))
+            got++;
+        else if (buf[next])
+            got = 0;
+        else
+            got = 4 - got;
+        next++;
+    }
+    *have = got;
+    return next;
+}
+
+int ZEXPORT inflateSync(strm)
+z_streamp strm;
+{
+    unsigned len;               /* number of bytes to look at or looked at */
+    unsigned long in, out;      /* temporary to save total_in and total_out */
+    unsigned char buf[4];       /* to restore bit buffer to byte string */
+    struct inflate_state FAR *state;
+
+    /* check parameters */
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR;
+
+    /* if first time, start search in bit buffer */
+    if (state->mode != SYNC) {
+        state->mode = SYNC;
+        state->hold <<= state->bits & 7;
+        state->bits -= state->bits & 7;
+        len = 0;
+        while (state->bits >= 8) {
+            buf[len++] = (unsigned char)(state->hold);
+            state->hold >>= 8;
+            state->bits -= 8;
+        }
+        state->have = 0;
+        syncsearch(&(state->have), buf, len);
+    }
+
+    /* search available input */
+    len = syncsearch(&(state->have), strm->next_in, strm->avail_in);
+    strm->avail_in -= len;
+    strm->next_in += len;
+    strm->total_in += len;
+
+    /* return no joy or set up to restart inflate() on a new block */
+    if (state->have != 4) return Z_DATA_ERROR;
+    in = strm->total_in;  out = strm->total_out;
+    inflateReset(strm);
+    strm->total_in = in;  strm->total_out = out;
+    state->mode = TYPE;
+    return Z_OK;
+}
+
+/*
+   Returns true if inflate is currently at the end of a block generated by
+   Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
+   implementation to provide an additional safety check. PPP uses
+   Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored
+   block. When decompressing, PPP checks that at the end of input packet,
+   inflate is waiting for these length bytes.
+ */
+int ZEXPORT inflateSyncPoint(strm)
+z_streamp strm;
+{
+    struct inflate_state FAR *state;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    return state->mode == STORED && state->bits == 0;
+}
+
+int ZEXPORT inflateCopy(dest, source)
+z_streamp dest;
+z_streamp source;
+{
+    struct inflate_state FAR *state;
+    struct inflate_state FAR *copy;
+    unsigned char FAR *window;
+    unsigned wsize;
+
+    /* check input */
+    if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL ||
+        source->zalloc == (alloc_func)0 || source->zfree == (free_func)0)
+        return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)source->state;
+
+    /* allocate space */
+    copy = (struct inflate_state FAR *)
+           ZALLOC(source, 1, sizeof(struct inflate_state));
+    if (copy == Z_NULL) return Z_MEM_ERROR;
+    window = Z_NULL;
+    if (state->window != Z_NULL) {
+        window = (unsigned char FAR *)
+                 ZALLOC(source, 1U << state->wbits, sizeof(unsigned char));
+        if (window == Z_NULL) {
+            ZFREE(source, copy);
+            return Z_MEM_ERROR;
+        }
+    }
+
+    /* copy state */
+    zmemcpy(dest, source, sizeof(z_stream));
+    zmemcpy(copy, state, sizeof(struct inflate_state));
+    if (state->lencode >= state->codes &&
+        state->lencode <= state->codes + ENOUGH - 1) {
+        copy->lencode = copy->codes + (state->lencode - state->codes);
+        copy->distcode = copy->codes + (state->distcode - state->codes);
+    }
+    copy->next = copy->codes + (state->next - state->codes);
+    if (window != Z_NULL) {
+        wsize = 1U << state->wbits;
+        zmemcpy(window, state->window, wsize);
+    }
+    copy->window = window;
+    dest->state = (struct internal_state FAR *)copy;
+    return Z_OK;
+}

Added: vendor/Python/current/Modules/zlib/inflate.h
===================================================================
--- vendor/Python/current/Modules/zlib/inflate.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/zlib/inflate.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,115 @@
+/* inflate.h -- internal inflate state definition
+ * Copyright (C) 1995-2004 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* define NO_GZIP when compiling if you want to disable gzip header and
+   trailer decoding by inflate().  NO_GZIP would be used to avoid linking in
+   the crc code when it is not needed.  For shared libraries, gzip decoding
+   should be left enabled. */
+#ifndef NO_GZIP
+#  define GUNZIP
+#endif
+
+/* Possible inflate modes between inflate() calls */
+typedef enum {
+    HEAD,       /* i: waiting for magic header */
+    FLAGS,      /* i: waiting for method and flags (gzip) */
+    TIME,       /* i: waiting for modification time (gzip) */
+    OS,         /* i: waiting for extra flags and operating system (gzip) */
+    EXLEN,      /* i: waiting for extra length (gzip) */
+    EXTRA,      /* i: waiting for extra bytes (gzip) */
+    NAME,       /* i: waiting for end of file name (gzip) */
+    COMMENT,    /* i: waiting for end of comment (gzip) */
+    HCRC,       /* i: waiting for header crc (gzip) */
+    DICTID,     /* i: waiting for dictionary check value */
+    DICT,       /* waiting for inflateSetDictionary() call */
+        TYPE,       /* i: waiting for type bits, including last-flag bit */
+        TYPEDO,     /* i: same, but skip check to exit inflate on new block */
+        STORED,     /* i: waiting for stored size (length and complement) */
+        COPY,       /* i/o: waiting for input or output to copy stored block */
+        TABLE,      /* i: waiting for dynamic block table lengths */
+        LENLENS,    /* i: waiting for code length code lengths */
+        CODELENS,   /* i: waiting for length/lit and distance code lengths */
+            LEN,        /* i: waiting for length/lit code */
+            LENEXT,     /* i: waiting for length extra bits */
+            DIST,       /* i: waiting for distance code */
+            DISTEXT,    /* i: waiting for distance extra bits */
+            MATCH,      /* o: waiting for output space to copy string */
+            LIT,        /* o: waiting for output space to write literal */
+    CHECK,      /* i: waiting for 32-bit check value */
+    LENGTH,     /* i: waiting for 32-bit length (gzip) */
+    DONE,       /* finished check, done -- remain here until reset */
+    BAD,        /* got a data error -- remain here until reset */
+    MEM,        /* got an inflate() memory error -- remain here until reset */
+    SYNC        /* looking for synchronization bytes to restart inflate() */
+} inflate_mode;
+
+/*
+    State transitions between above modes -
+
+    (most modes can go to the BAD or MEM mode -- not shown for clarity)
+
+    Process header:
+        HEAD -> (gzip) or (zlib)
+        (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME
+        NAME -> COMMENT -> HCRC -> TYPE
+        (zlib) -> DICTID or TYPE
+        DICTID -> DICT -> TYPE
+    Read deflate blocks:
+            TYPE -> STORED or TABLE or LEN or CHECK
+            STORED -> COPY -> TYPE
+            TABLE -> LENLENS -> CODELENS -> LEN
+    Read deflate codes:
+                LEN -> LENEXT or LIT or TYPE
+                LENEXT -> DIST -> DISTEXT -> MATCH -> LEN
+                LIT -> LEN
+    Process trailer:
+        CHECK -> LENGTH -> DONE
+ */
+
+/* state maintained between inflate() calls.  Approximately 7K bytes. */
+struct inflate_state {
+    inflate_mode mode;          /* current inflate mode */
+    int last;                   /* true if processing last block */
+    int wrap;                   /* bit 0 true for zlib, bit 1 true for gzip */
+    int havedict;               /* true if dictionary provided */
+    int flags;                  /* gzip header method and flags (0 if zlib) */
+    unsigned dmax;              /* zlib header max distance (INFLATE_STRICT) */
+    unsigned long check;        /* protected copy of check value */
+    unsigned long total;        /* protected copy of output count */
+    gz_headerp head;            /* where to save gzip header information */
+        /* sliding window */
+    unsigned wbits;             /* log base 2 of requested window size */
+    unsigned wsize;             /* window size or zero if not using window */
+    unsigned whave;             /* valid bytes in the window */
+    unsigned write;             /* window write index */
+    unsigned char FAR *window;  /* allocated sliding window, if needed */
+        /* bit accumulator */
+    unsigned long hold;         /* input bit accumulator */
+    unsigned bits;              /* number of bits in "in" */
+        /* for string and stored block copying */
+    unsigned length;            /* literal or length of data to copy */
+    unsigned offset;            /* distance back to copy string from */
+        /* for table and code decoding */
+    unsigned extra;             /* extra bits needed */
+        /* fixed and dynamic code tables */
+    code const FAR *lencode;    /* starting table for length/literal codes */
+    code const FAR *distcode;   /* starting table for distance codes */
+    unsigned lenbits;           /* index bits for lencode */
+    unsigned distbits;          /* index bits for distcode */
+        /* dynamic table building */
+    unsigned ncode;             /* number of code length code lengths */
+    unsigned nlen;              /* number of length code lengths */
+    unsigned ndist;             /* number of distance code lengths */
+    unsigned have;              /* number of code lengths in lens[] */
+    code FAR *next;             /* next available space in codes[] */
+    unsigned short lens[320];   /* temporary storage for code lengths */
+    unsigned short work[288];   /* work area for code table building */
+    code codes[ENOUGH];         /* space for code tables */
+};

Added: vendor/Python/current/Modules/zlib/inftrees.c
===================================================================
--- vendor/Python/current/Modules/zlib/inftrees.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/zlib/inftrees.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,329 @@
+/* inftrees.c -- generate Huffman trees for efficient decoding
+ * Copyright (C) 1995-2005 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+
+#define MAXBITS 15
+
+const char inflate_copyright[] =
+   " inflate 1.2.3 Copyright 1995-2005 Mark Adler ";
+/*
+  If you use the zlib library in a product, an acknowledgment is welcome
+  in the documentation of your product. If for some reason you cannot
+  include such an acknowledgment, I would appreciate that you keep this
+  copyright string in the executable of your product.
+ */
+
+/*
+   Build a set of tables to decode the provided canonical Huffman code.
+   The code lengths are lens[0..codes-1].  The result starts at *table,
+   whose indices are 0..2^bits-1.  work is a writable array of at least
+   lens shorts, which is used as a work area.  type is the type of code
+   to be generated, CODES, LENS, or DISTS.  On return, zero is success,
+   -1 is an invalid code, and +1 means that ENOUGH isn't enough.  table
+   on return points to the next available entry's address.  bits is the
+   requested root table index bits, and on return it is the actual root
+   table index bits.  It will differ if the request is greater than the
+   longest code or if it is less than the shortest code.
+ */
+int inflate_table(type, lens, codes, table, bits, work)
+codetype type;
+unsigned short FAR *lens;
+unsigned codes;
+code FAR * FAR *table;
+unsigned FAR *bits;
+unsigned short FAR *work;
+{
+    unsigned len;               /* a code's length in bits */
+    unsigned sym;               /* index of code symbols */
+    unsigned min, max;          /* minimum and maximum code lengths */
+    unsigned root;              /* number of index bits for root table */
+    unsigned curr;              /* number of index bits for current table */
+    unsigned drop;              /* code bits to drop for sub-table */
+    int left;                   /* number of prefix codes available */
+    unsigned used;              /* code entries in table used */
+    unsigned huff;              /* Huffman code */
+    unsigned incr;              /* for incrementing code, index */
+    unsigned fill;              /* index for replicating entries */
+    unsigned low;               /* low bits for current root entry */
+    unsigned mask;              /* mask for low root bits */
+    code this;                  /* table entry for duplication */
+    code FAR *next;             /* next available space in table */
+    const unsigned short FAR *base;     /* base value table to use */
+    const unsigned short FAR *extra;    /* extra bits table to use */
+    int end;                    /* use base and extra for symbol > end */
+    unsigned short count[MAXBITS+1];    /* number of codes of each length */
+    unsigned short offs[MAXBITS+1];     /* offsets in table for each length */
+    static const unsigned short lbase[31] = { /* Length codes 257..285 base */
+        3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
+        35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
+    static const unsigned short lext[31] = { /* Length codes 257..285 extra */
+        16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
+        19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 201, 196};
+    static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
+        1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
+        257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
+        8193, 12289, 16385, 24577, 0, 0};
+    static const unsigned short dext[32] = { /* Distance codes 0..29 extra */
+        16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
+        23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
+        28, 28, 29, 29, 64, 64};
+
+    /*
+       Process a set of code lengths to create a canonical Huffman code.  The
+       code lengths are lens[0..codes-1].  Each length corresponds to the
+       symbols 0..codes-1.  The Huffman code is generated by first sorting the
+       symbols by length from short to long, and retaining the symbol order
+       for codes with equal lengths.  Then the code starts with all zero bits
+       for the first code of the shortest length, and the codes are integer
+       increments for the same length, and zeros are appended as the length
+       increases.  For the deflate format, these bits are stored backwards
+       from their more natural integer increment ordering, and so when the
+       decoding tables are built in the large loop below, the integer codes
+       are incremented backwards.
+
+       This routine assumes, but does not check, that all of the entries in
+       lens[] are in the range 0..MAXBITS.  The caller must assure this.
+       1..MAXBITS is interpreted as that code length.  zero means that that
+       symbol does not occur in this code.
+
+       The codes are sorted by computing a count of codes for each length,
+       creating from that a table of starting indices for each length in the
+       sorted table, and then entering the symbols in order in the sorted
+       table.  The sorted table is work[], with that space being provided by
+       the caller.
+
+       The length counts are used for other purposes as well, i.e. finding
+       the minimum and maximum length codes, determining if there are any
+       codes at all, checking for a valid set of lengths, and looking ahead
+       at length counts to determine sub-table sizes when building the
+       decoding tables.
+     */
+
+    /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
+    for (len = 0; len <= MAXBITS; len++)
+        count[len] = 0;
+    for (sym = 0; sym < codes; sym++)
+        count[lens[sym]]++;
+
+    /* bound code lengths, force root to be within code lengths */
+    root = *bits;
+    for (max = MAXBITS; max >= 1; max--)
+        if (count[max] != 0) break;
+    if (root > max) root = max;
+    if (max == 0) {                     /* no symbols to code at all */
+        this.op = (unsigned char)64;    /* invalid code marker */
+        this.bits = (unsigned char)1;
+        this.val = (unsigned short)0;
+        *(*table)++ = this;             /* make a table to force an error */
+        *(*table)++ = this;
+        *bits = 1;
+        return 0;     /* no symbols, but wait for decoding to report error */
+    }
+    for (min = 1; min <= MAXBITS; min++)
+        if (count[min] != 0) break;
+    if (root < min) root = min;
+
+    /* check for an over-subscribed or incomplete set of lengths */
+    left = 1;
+    for (len = 1; len <= MAXBITS; len++) {
+        left <<= 1;
+        left -= count[len];
+        if (left < 0) return -1;        /* over-subscribed */
+    }
+    if (left > 0 && (type == CODES || max != 1))
+        return -1;                      /* incomplete set */
+
+    /* generate offsets into symbol table for each length for sorting */
+    offs[1] = 0;
+    for (len = 1; len < MAXBITS; len++)
+        offs[len + 1] = offs[len] + count[len];
+
+    /* sort symbols by length, by symbol order within each length */
+    for (sym = 0; sym < codes; sym++)
+        if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym;
+
+    /*
+       Create and fill in decoding tables.  In this loop, the table being
+       filled is at next and has curr index bits.  The code being used is huff
+       with length len.  That code is converted to an index by dropping drop
+       bits off of the bottom.  For codes where len is less than drop + curr,
+       those top drop + curr - len bits are incremented through all values to
+       fill the table with replicated entries.
+
+       root is the number of index bits for the root table.  When len exceeds
+       root, sub-tables are created pointed to by the root entry with an index
+       of the low root bits of huff.  This is saved in low to check for when a
+       new sub-table should be started.  drop is zero when the root table is
+       being filled, and drop is root when sub-tables are being filled.
+
+       When a new sub-table is needed, it is necessary to look ahead in the
+       code lengths to determine what size sub-table is needed.  The length
+       counts are used for this, and so count[] is decremented as codes are
+       entered in the tables.
+
+       used keeps track of how many table entries have been allocated from the
+       provided *table space.  It is checked when a LENS table is being made
+       against the space in *table, ENOUGH, minus the maximum space needed by
+       the worst case distance code, MAXD.  This should never happen, but the
+       sufficiency of ENOUGH has not been proven exhaustively, hence the check.
+       This assumes that when type == LENS, bits == 9.
+
+       sym increments through all symbols, and the loop terminates when
+       all codes of length max, i.e. all codes, have been processed.  This
+       routine permits incomplete codes, so another loop after this one fills
+       in the rest of the decoding tables with invalid code markers.
+     */
+
+    /* set up for code type */
+    switch (type) {
+    case CODES:
+        base = extra = work;    /* dummy value--not used */
+        end = 19;
+        break;
+    case LENS:
+        base = lbase;
+        base -= 257;
+        extra = lext;
+        extra -= 257;
+        end = 256;
+        break;
+    default:            /* DISTS */
+        base = dbase;
+        extra = dext;
+        end = -1;
+    }
+
+    /* initialize state for loop */
+    huff = 0;                   /* starting code */
+    sym = 0;                    /* starting code symbol */
+    len = min;                  /* starting code length */
+    next = *table;              /* current table to fill in */
+    curr = root;                /* current table index bits */
+    drop = 0;                   /* current bits to drop from code for index */
+    low = (unsigned)(-1);       /* trigger new sub-table when len > root */
+    used = 1U << root;          /* use root table entries */
+    mask = used - 1;            /* mask for comparing low */
+
+    /* check available table space */
+    if (type == LENS && used >= ENOUGH - MAXD)
+        return 1;
+
+    /* process all codes and make table entries */
+    for (;;) {
+        /* create table entry */
+        this.bits = (unsigned char)(len - drop);
+        if ((int)(work[sym]) < end) {
+            this.op = (unsigned char)0;
+            this.val = work[sym];
+        }
+        else if ((int)(work[sym]) > end) {
+            this.op = (unsigned char)(extra[work[sym]]);
+            this.val = base[work[sym]];
+        }
+        else {
+            this.op = (unsigned char)(32 + 64);         /* end of block */
+            this.val = 0;
+        }
+
+        /* replicate for those indices with low len bits equal to huff */
+        incr = 1U << (len - drop);
+        fill = 1U << curr;
+        min = fill;                 /* save offset to next table */
+        do {
+            fill -= incr;
+            next[(huff >> drop) + fill] = this;
+        } while (fill != 0);
+
+        /* backwards increment the len-bit code huff */
+        incr = 1U << (len - 1);
+        while (huff & incr)
+            incr >>= 1;
+        if (incr != 0) {
+            huff &= incr - 1;
+            huff += incr;
+        }
+        else
+            huff = 0;
+
+        /* go to next symbol, update count, len */
+        sym++;
+        if (--(count[len]) == 0) {
+            if (len == max) break;
+            len = lens[work[sym]];
+        }
+
+        /* create new sub-table if needed */
+        if (len > root && (huff & mask) != low) {
+            /* if first time, transition to sub-tables */
+            if (drop == 0)
+                drop = root;
+
+            /* increment past last table */
+            next += min;            /* here min is 1 << curr */
+
+            /* determine length of next table */
+            curr = len - drop;
+            left = (int)(1 << curr);
+            while (curr + drop < max) {
+                left -= count[curr + drop];
+                if (left <= 0) break;
+                curr++;
+                left <<= 1;
+            }
+
+            /* check for enough space */
+            used += 1U << curr;
+            if (type == LENS && used >= ENOUGH - MAXD)
+                return 1;
+
+            /* point entry in root table to sub-table */
+            low = huff & mask;
+            (*table)[low].op = (unsigned char)curr;
+            (*table)[low].bits = (unsigned char)root;
+            (*table)[low].val = (unsigned short)(next - *table);
+        }
+    }
+
+    /*
+       Fill in rest of table for incomplete codes.  This loop is similar to the
+       loop above in incrementing huff for table indices.  It is assumed that
+       len is equal to curr + drop, so there is no loop needed to increment
+       through high index bits.  When the current sub-table is filled, the loop
+       drops back to the root table to fill in any remaining entries there.
+     */
+    this.op = (unsigned char)64;                /* invalid code marker */
+    this.bits = (unsigned char)(len - drop);
+    this.val = (unsigned short)0;
+    while (huff != 0) {
+        /* when done with sub-table, drop back to root table */
+        if (drop != 0 && (huff & mask) != low) {
+            drop = 0;
+            len = root;
+            next = *table;
+            this.bits = (unsigned char)len;
+        }
+
+        /* put invalid code marker in table */
+        next[huff >> drop] = this;
+
+        /* backwards increment the len-bit code huff */
+        incr = 1U << (len - 1);
+        while (huff & incr)
+            incr >>= 1;
+        if (incr != 0) {
+            huff &= incr - 1;
+            huff += incr;
+        }
+        else
+            huff = 0;
+    }
+
+    /* set return parameters */
+    *table += used;
+    *bits = root;
+    return 0;
+}

Added: vendor/Python/current/Modules/zlib/inftrees.h
===================================================================
--- vendor/Python/current/Modules/zlib/inftrees.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/zlib/inftrees.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,55 @@
+/* inftrees.h -- header to use inftrees.c
+ * Copyright (C) 1995-2005 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* Structure for decoding tables.  Each entry provides either the
+   information needed to do the operation requested by the code that
+   indexed that table entry, or it provides a pointer to another
+   table that indexes more bits of the code.  op indicates whether
+   the entry is a pointer to another table, a literal, a length or
+   distance, an end-of-block, or an invalid code.  For a table
+   pointer, the low four bits of op is the number of index bits of
+   that table.  For a length or distance, the low four bits of op
+   is the number of extra bits to get after the code.  bits is
+   the number of bits in this code or part of the code to drop off
+   of the bit buffer.  val is the actual byte to output in the case
+   of a literal, the base length or distance, or the offset from
+   the current table to the next table.  Each entry is four bytes. */
+typedef struct {
+    unsigned char op;           /* operation, extra bits, table bits */
+    unsigned char bits;         /* bits in this part of the code */
+    unsigned short val;         /* offset in table or code value */
+} code;
+
+/* op values as set by inflate_table():
+    00000000 - literal
+    0000tttt - table link, tttt != 0 is the number of table index bits
+    0001eeee - length or distance, eeee is the number of extra bits
+    01100000 - end of block
+    01000000 - invalid code
+ */
+
+/* Maximum size of dynamic tree.  The maximum found in a long but non-
+   exhaustive search was 1444 code structures (852 for length/literals
+   and 592 for distances, the latter actually the result of an
+   exhaustive search).  The true maximum is not known, but the value
+   below is more than safe. */
+#define ENOUGH 2048
+#define MAXD 592
+
+/* Type of code to build for inftable() */
+typedef enum {
+    CODES,
+    LENS,
+    DISTS
+} codetype;
+
+extern int inflate_table OF((codetype type, unsigned short FAR *lens,
+                             unsigned codes, code FAR * FAR *table,
+                             unsigned FAR *bits, unsigned short FAR *work));

Added: vendor/Python/current/Modules/zlib/make_vms.com
===================================================================
--- vendor/Python/current/Modules/zlib/make_vms.com	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/zlib/make_vms.com	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,461 @@
+$! make libz under VMS written by
+$! Martin P.J. Zinser
+$! <zinser at zinser.no-ip.info or zinser at sysdev.deutsche-boerse.com>
+$!
+$ on error then goto err_exit
+$!
+$!
+$! Just some general constants...
+$!
+$ true  = 1
+$ false = 0
+$ tmpnam = "temp_" + f$getjpi("","pid")
+$ SAY = "WRITE SYS$OUTPUT"
+$!
+$! Setup variables holding "config" information
+$!
+$ Make     = ""
+$ name     = "Zlib"
+$ version  = "?.?.?"
+$ v_string = "ZLIB_VERSION"
+$ v_file   = "zlib.h"
+$ ccopt    = ""
+$ lopts    = ""
+$ linkonly = false
+$ optfile  = name + ".opt"
+$ its_decc = false
+$ its_vaxc = false
+$ its_gnuc = false
+$ axp      = f$getsyi("HW_MODEL").ge.1024
+$ s_case   = false
+$! Check for MMK/MMS
+$!
+$ If F$Search ("Sys$System:MMS.EXE") .nes. "" Then Make = "MMS"
+$ If F$Type (MMK) .eqs. "STRING" Then Make = "MMK"
+$!
+$!
+$ gosub find_version
+$!
+$ gosub check_opts
+$!
+$! Look for the compiler used
+$!
+$ gosub check_compiler
+$ if its_decc
+$ then
+$   ccopt = "/prefix=all" + ccopt
+$   if f$trnlnm("SYS") .eqs. ""
+$   then
+$     if axp
+$     then
+$       define sys sys$library:
+$     else
+$       ccopt = "/decc" + ccopt
+$       define sys decc$library_include:
+$     endif
+$   endif
+$ endif
+$ if its_vaxc .or. its_gnuc
+$ then
+$    if f$trnlnm("SYS").eqs."" then define sys sys$library:
+$ endif
+$!
+$! Build the thing plain or with mms
+$!
+$ write sys$output "Compiling Zlib sources ..."
+$ if make.eqs.""
+$  then
+$   dele example.obj;*,minigzip.obj;*
+$   CALL MAKE adler32.OBJ "CC ''CCOPT' adler32" -
+                adler32.c zlib.h zconf.h
+$   CALL MAKE compress.OBJ "CC ''CCOPT' compress" -
+                compress.c zlib.h zconf.h
+$   CALL MAKE crc32.OBJ "CC ''CCOPT' crc32" -
+                crc32.c zlib.h zconf.h
+$   CALL MAKE deflate.OBJ "CC ''CCOPT' deflate" -
+                deflate.c deflate.h zutil.h zlib.h zconf.h
+$   CALL MAKE gzio.OBJ "CC ''CCOPT' gzio" -
+                gzio.c zutil.h zlib.h zconf.h
+$   CALL MAKE infback.OBJ "CC ''CCOPT' infback" -
+                infback.c zutil.h inftrees.h inflate.h inffast.h inffixed.h
+$   CALL MAKE inffast.OBJ "CC ''CCOPT' inffast" -
+                inffast.c zutil.h zlib.h zconf.h inffast.h
+$   CALL MAKE inflate.OBJ "CC ''CCOPT' inflate" -
+                inflate.c zutil.h zlib.h zconf.h infblock.h
+$   CALL MAKE inftrees.OBJ "CC ''CCOPT' inftrees" -
+                inftrees.c zutil.h zlib.h zconf.h inftrees.h
+$   CALL MAKE trees.OBJ "CC ''CCOPT' trees" -
+                trees.c deflate.h zutil.h zlib.h zconf.h
+$   CALL MAKE uncompr.OBJ "CC ''CCOPT' uncompr" -
+                uncompr.c zlib.h zconf.h
+$   CALL MAKE zutil.OBJ "CC ''CCOPT' zutil" -
+                zutil.c zutil.h zlib.h zconf.h
+$   write sys$output "Building Zlib ..."
+$   CALL MAKE libz.OLB "lib/crea libz.olb *.obj" *.OBJ
+$   write sys$output "Building example..."
+$   CALL MAKE example.OBJ "CC ''CCOPT' example" -
+                example.c zlib.h zconf.h
+$   call make example.exe "LINK example,libz.olb/lib" example.obj libz.olb
+$   if f$search("x11vms:xvmsutils.olb") .nes. ""
+$   then
+$     write sys$output "Building minigzip..."
+$     CALL MAKE minigzip.OBJ "CC ''CCOPT' minigzip" -
+                minigzip.c zlib.h zconf.h
+$     call make minigzip.exe -
+                "LINK minigzip,libz.olb/lib,x11vms:xvmsutils.olb/lib" -
+                minigzip.obj libz.olb
+$   endif
+$  else
+$   gosub crea_mms
+$   SAY "Make ''name' ''version' with ''Make' "
+$   'make'
+$  endif
+$!
+$! Alpha gets a shareable image
+$!
+$ If axp
+$ Then
+$   gosub crea_olist
+$   write sys$output "Creating libzshr.exe"
+$   call anal_obj_axp modules.opt _link.opt
+$   if s_case
+$   then
+$      open/append optf modules.opt
+$      write optf "case_sensitive=YES"
+$      close optf
+$   endif
+$   LINK_'lopts'/SHARE=libzshr.exe modules.opt/opt,_link.opt/opt
+$ endif
+$ write sys$output "Zlib build completed"
+$ exit
+$CC_ERR:
+$ write sys$output "C compiler required to build ''name'"
+$ goto err_exit
+$ERR_EXIT:
+$ set message/facil/ident/sever/text
+$ write sys$output "Exiting..."
+$ exit 2
+$!
+$!
+$MAKE: SUBROUTINE   !SUBROUTINE TO CHECK DEPENDENCIES
+$ V = 'F$Verify(0)
+$! P1 = What we are trying to make
+$! P2 = Command to make it
+$! P3 - P8  What it depends on
+$
+$ If F$Search(P1) .Eqs. "" Then Goto Makeit
+$ Time = F$CvTime(F$File(P1,"RDT"))
+$arg=3
+$Loop:
+$       Argument = P'arg
+$       If Argument .Eqs. "" Then Goto Exit
+$       El=0
+$Loop2:
+$       File = F$Element(El," ",Argument)
+$       If File .Eqs. " " Then Goto Endl
+$       AFile = ""
+$Loop3:
+$       OFile = AFile
+$       AFile = F$Search(File)
+$       If AFile .Eqs. "" .Or. AFile .Eqs. OFile Then Goto NextEl
+$       If F$CvTime(F$File(AFile,"RDT")) .Ges. Time Then Goto Makeit
+$       Goto Loop3
+$NextEL:
+$       El = El + 1
+$       Goto Loop2
+$EndL:
+$ arg=arg+1
+$ If arg .Le. 8 Then Goto Loop
+$ Goto Exit
+$
+$Makeit:
+$ VV=F$VERIFY(0)
+$ write sys$output P2
+$ 'P2
+$ VV='F$Verify(VV)
+$Exit:
+$ If V Then Set Verify
+$ENDSUBROUTINE
+$!------------------------------------------------------------------------------
+$!
+$! Check command line options and set symbols accordingly
+$!
+$ CHECK_OPTS:
+$ i = 1
+$ OPT_LOOP:
+$ if i .lt. 9
+$ then
+$   cparm = f$edit(p'i',"upcase")
+$   if cparm .eqs. "DEBUG"
+$   then
+$     ccopt = ccopt + "/noopt/deb"
+$     lopts = lopts + "/deb"
+$   endif
+$   if f$locate("CCOPT=",cparm) .lt. f$length(cparm)
+$   then
+$     start = f$locate("=",cparm) + 1
+$     len   = f$length(cparm) - start
+$     ccopt = ccopt + f$extract(start,len,cparm)
+$     if f$locate("AS_IS",f$edit(ccopt,"UPCASE")) .lt. f$length(ccopt) -
+         then s_case = true
+$   endif
+$   if cparm .eqs. "LINK" then linkonly = true
+$   if f$locate("LOPTS=",cparm) .lt. f$length(cparm)
+$   then
+$     start = f$locate("=",cparm) + 1
+$     len   = f$length(cparm) - start
+$     lopts = lopts + f$extract(start,len,cparm)
+$   endif
+$   if f$locate("CC=",cparm) .lt. f$length(cparm)
+$   then
+$     start  = f$locate("=",cparm) + 1
+$     len    = f$length(cparm) - start
+$     cc_com = f$extract(start,len,cparm)
+      if (cc_com .nes. "DECC") .and. -
+         (cc_com .nes. "VAXC") .and. -
+	 (cc_com .nes. "GNUC")
+$     then
+$       write sys$output "Unsupported compiler choice ''cc_com' ignored"
+$       write sys$output "Use DECC, VAXC, or GNUC instead"
+$     else
+$     	if cc_com .eqs. "DECC" then its_decc = true
+$     	if cc_com .eqs. "VAXC" then its_vaxc = true
+$     	if cc_com .eqs. "GNUC" then its_gnuc = true
+$     endif
+$   endif
+$   if f$locate("MAKE=",cparm) .lt. f$length(cparm)
+$   then
+$     start  = f$locate("=",cparm) + 1
+$     len    = f$length(cparm) - start
+$     mmks = f$extract(start,len,cparm)
+$     if (mmks .eqs. "MMK") .or. (mmks .eqs. "MMS")
+$     then
+$       make = mmks
+$     else
+$       write sys$output "Unsupported make choice ''mmks' ignored"
+$       write sys$output "Use MMK or MMS instead"
+$     endif
+$   endif
+$   i = i + 1
+$   goto opt_loop
+$ endif
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! Look for the compiler used
+$!
+$CHECK_COMPILER:
+$ if (.not. (its_decc .or. its_vaxc .or. its_gnuc))
+$ then
+$   its_decc = (f$search("SYS$SYSTEM:DECC$COMPILER.EXE") .nes. "")
+$   its_vaxc = .not. its_decc .and. (F$Search("SYS$System:VAXC.Exe") .nes. "")
+$   its_gnuc = .not. (its_decc .or. its_vaxc) .and. (f$trnlnm("gnu_cc") .nes. "")
+$ endif
+$!
+$! Exit if no compiler available
+$!
+$ if (.not. (its_decc .or. its_vaxc .or. its_gnuc))
+$ then goto CC_ERR
+$ else
+$   if its_decc then write sys$output "CC compiler check ... Compaq C"
+$   if its_vaxc then write sys$output "CC compiler check ... VAX C"
+$   if its_gnuc then write sys$output "CC compiler check ... GNU C"
+$ endif
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! If MMS/MMK are available dump out the descrip.mms if required
+$!
+$CREA_MMS:
+$ write sys$output "Creating descrip.mms..."
+$ create descrip.mms
+$ open/append out descrip.mms
+$ copy sys$input: out
+$ deck
+# descrip.mms: MMS description file for building zlib on VMS
+# written by Martin P.J. Zinser
+# <zinser at zinser.no-ip.info or zinser at sysdev.deutsche-boerse.com>
+
+OBJS = adler32.obj, compress.obj, crc32.obj, gzio.obj, uncompr.obj, infback.obj\
+       deflate.obj, trees.obj, zutil.obj, inflate.obj, \
+       inftrees.obj, inffast.obj
+
+$ eod
+$ write out "CFLAGS=", ccopt
+$ write out "LOPTS=", lopts
+$ copy sys$input: out
+$ deck
+
+all : example.exe minigzip.exe libz.olb
+        @ write sys$output " Example applications available"
+
+libz.olb : libz.olb($(OBJS))
+	@ write sys$output " libz available"
+
+example.exe : example.obj libz.olb
+              link $(LOPTS) example,libz.olb/lib
+
+minigzip.exe : minigzip.obj libz.olb
+              link $(LOPTS) minigzip,libz.olb/lib,x11vms:xvmsutils.olb/lib
+
+clean :
+	delete *.obj;*,libz.olb;*,*.opt;*,*.exe;*
+
+
+# Other dependencies.
+adler32.obj  : adler32.c zutil.h zlib.h zconf.h
+compress.obj : compress.c zlib.h zconf.h
+crc32.obj    : crc32.c zutil.h zlib.h zconf.h
+deflate.obj  : deflate.c deflate.h zutil.h zlib.h zconf.h
+example.obj  : example.c zlib.h zconf.h
+gzio.obj     : gzio.c zutil.h zlib.h zconf.h
+inffast.obj  : inffast.c zutil.h zlib.h zconf.h inftrees.h inffast.h
+inflate.obj  : inflate.c zutil.h zlib.h zconf.h
+inftrees.obj : inftrees.c zutil.h zlib.h zconf.h inftrees.h
+minigzip.obj : minigzip.c zlib.h zconf.h
+trees.obj    : trees.c deflate.h zutil.h zlib.h zconf.h
+uncompr.obj  : uncompr.c zlib.h zconf.h
+zutil.obj    : zutil.c zutil.h zlib.h zconf.h
+infback.obj  : infback.c zutil.h inftrees.h inflate.h inffast.h inffixed.h
+$ eod
+$ close out
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! Read list of core library sources from makefile.in and create options
+$! needed to build shareable image
+$!
+$CREA_OLIST:
+$ open/read min makefile.in
+$ open/write mod modules.opt
+$ src_check = "OBJS ="
+$MRLOOP:
+$ read/end=mrdone min rec
+$ if (f$extract(0,6,rec) .nes. src_check) then goto mrloop
+$ rec = rec - src_check
+$ gosub extra_filnam
+$ if (f$element(1,"\",rec) .eqs. "\") then goto mrdone
+$MRSLOOP:
+$ read/end=mrdone min rec
+$ gosub extra_filnam
+$ if (f$element(1,"\",rec) .nes. "\") then goto mrsloop
+$MRDONE:
+$ close min
+$ close mod
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! Take record extracted in crea_olist and split it into single filenames
+$!
+$EXTRA_FILNAM:
+$ myrec = f$edit(rec - "\", "trim,compress")
+$ i = 0
+$FELOOP:
+$ srcfil = f$element(i," ", myrec)
+$ if (srcfil .nes. " ")
+$ then
+$   write mod f$parse(srcfil,,,"NAME"), ".obj"
+$   i = i + 1
+$   goto feloop
+$ endif
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! Find current Zlib version number
+$!
+$FIND_VERSION:
+$ open/read h_in 'v_file'
+$hloop:
+$ read/end=hdone h_in rec
+$ rec = f$edit(rec,"TRIM")
+$ if (f$extract(0,1,rec) .nes. "#") then goto hloop
+$ rec = f$edit(rec - "#", "TRIM")
+$ if f$element(0," ",rec) .nes. "define" then goto hloop
+$ if f$element(1," ",rec) .eqs. v_string
+$ then
+$   version = 'f$element(2," ",rec)'
+$   goto hdone
+$ endif
+$ goto hloop
+$hdone:
+$ close h_in
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! Analyze Object files for OpenVMS AXP to extract Procedure and Data
+$! information to build a symbol vector for a shareable image
+$! All the "brains" of this logic was suggested by Hartmut Becker
+$! (Hartmut.Becker at compaq.com). All the bugs were introduced by me
+$! (zinser at decus.de), so if you do have problem reports please do not
+$! bother Hartmut/HP, but get in touch with me
+$!
+$ ANAL_OBJ_AXP: Subroutine
+$ V = 'F$Verify(0)
+$ SAY := "WRITE_ SYS$OUTPUT"
+$
+$ IF F$SEARCH("''P1'") .EQS. ""
+$ THEN
+$    SAY "ANAL_OBJ_AXP-E-NOSUCHFILE:  Error, inputfile ''p1' not available"
+$    goto exit_aa
+$ ENDIF
+$ IF "''P2'" .EQS. ""
+$ THEN
+$    SAY "ANAL_OBJ_AXP:  Error, no output file provided"
+$    goto exit_aa
+$ ENDIF
+$
+$ open/read in 'p1
+$ create a.tmp
+$ open/append atmp a.tmp
+$ loop:
+$ read/end=end_loop in line
+$ f= f$search(line)
+$ if f .eqs. ""
+$ then
+$	write sys$output "ANAL_OBJ_AXP-w-nosuchfile, ''line'"
+$	goto loop
+$ endif
+$ define/user sys$output nl:
+$ define/user sys$error nl:
+$ anal/obj/gsd 'f /out=x.tmp
+$ open/read xtmp x.tmp
+$ XLOOP:
+$ read/end=end_xloop xtmp xline
+$ xline = f$edit(xline,"compress")
+$ write atmp xline
+$ goto xloop
+$ END_XLOOP:
+$ close xtmp
+$ goto loop
+$ end_loop:
+$ close in
+$ close atmp
+$ if f$search("a.tmp") .eqs. "" -
+	then $ exit
+$ ! all global definitions
+$ search a.tmp "symbol:","EGSY$V_DEF 1","EGSY$V_NORM 1"/out=b.tmp
+$ ! all procedures
+$ search b.tmp "EGSY$V_NORM 1"/wind=(0,1) /out=c.tmp
+$ search c.tmp "symbol:"/out=d.tmp
+$ define/user sys$output nl:
+$ edito/edt/command=sys$input d.tmp
+sub/symbol: "/symbol_vector=(/whole
+sub/"/=PROCEDURE)/whole
+exit
+$ ! all data
+$ search b.tmp "EGSY$V_DEF 1"/wind=(0,1) /out=e.tmp
+$ search e.tmp "symbol:"/out=f.tmp
+$ define/user sys$output nl:
+$ edito/edt/command=sys$input f.tmp
+sub/symbol: "/symbol_vector=(/whole
+sub/"/=DATA)/whole
+exit
+$ sort/nodupl d.tmp,f.tmp 'p2'
+$ delete a.tmp;*,b.tmp;*,c.tmp;*,d.tmp;*,e.tmp;*,f.tmp;*
+$ if f$search("x.tmp") .nes. "" -
+	then $ delete x.tmp;*
+$!
+$ EXIT_AA:
+$ if V then set verify
+$ endsubroutine
+$!------------------------------------------------------------------------------

Added: vendor/Python/current/Modules/zlib/minigzip.c
===================================================================
--- vendor/Python/current/Modules/zlib/minigzip.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/zlib/minigzip.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,322 @@
+/* minigzip.c -- simulate gzip using the zlib compression library
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ * minigzip is a minimal implementation of the gzip utility. This is
+ * only an example of using zlib and isn't meant to replace the
+ * full-featured gzip. No attempt is made to deal with file systems
+ * limiting names to 14 or 8+3 characters, etc... Error checking is
+ * very limited. So use minigzip only for testing; use gzip for the
+ * real thing. On MSDOS, use only on file names without extension
+ * or in pipe mode.
+ */
+
+/* @(#) $Id$ */
+
+#include <stdio.h>
+#include "zlib.h"
+
+#ifdef STDC
+#  include <string.h>
+#  include <stdlib.h>
+#endif
+
+#ifdef USE_MMAP
+#  include <sys/types.h>
+#  include <sys/mman.h>
+#  include <sys/stat.h>
+#endif
+
+#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
+#  include <fcntl.h>
+#  include <io.h>
+#  define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
+#else
+#  define SET_BINARY_MODE(file)
+#endif
+
+#ifdef VMS
+#  define unlink delete
+#  define GZ_SUFFIX "-gz"
+#endif
+#ifdef RISCOS
+#  define unlink remove
+#  define GZ_SUFFIX "-gz"
+#  define fileno(file) file->__file
+#endif
+#if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
+#  include <unix.h> /* for fileno */
+#endif
+
+#ifndef WIN32 /* unlink already in stdio.h for WIN32 */
+  extern int unlink OF((const char *));
+#endif
+
+#ifndef GZ_SUFFIX
+#  define GZ_SUFFIX ".gz"
+#endif
+#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1)
+
+#define BUFLEN      16384
+#define MAX_NAME_LEN 1024
+
+#ifdef MAXSEG_64K
+#  define local static
+   /* Needed for systems with limitation on stack size. */
+#else
+#  define local
+#endif
+
+char *prog;
+
+void error            OF((const char *msg));
+void gz_compress      OF((FILE   *in, gzFile out));
+#ifdef USE_MMAP
+int  gz_compress_mmap OF((FILE   *in, gzFile out));
+#endif
+void gz_uncompress    OF((gzFile in, FILE   *out));
+void file_compress    OF((char  *file, char *mode));
+void file_uncompress  OF((char  *file));
+int  main             OF((int argc, char *argv[]));
+
+/* ===========================================================================
+ * Display error message and exit
+ */
+void error(msg)
+    const char *msg;
+{
+    fprintf(stderr, "%s: %s\n", prog, msg);
+    exit(1);
+}
+
+/* ===========================================================================
+ * Compress input to output then close both files.
+ */
+
+void gz_compress(in, out)
+    FILE   *in;
+    gzFile out;
+{
+    local char buf[BUFLEN];
+    int len;
+    int err;
+
+#ifdef USE_MMAP
+    /* Try first compressing with mmap. If mmap fails (minigzip used in a
+     * pipe), use the normal fread loop.
+     */
+    if (gz_compress_mmap(in, out) == Z_OK) return;
+#endif
+    for (;;) {
+        len = (int)fread(buf, 1, sizeof(buf), in);
+        if (ferror(in)) {
+            perror("fread");
+            exit(1);
+        }
+        if (len == 0) break;
+
+        if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err));
+    }
+    fclose(in);
+    if (gzclose(out) != Z_OK) error("failed gzclose");
+}
+
+#ifdef USE_MMAP /* MMAP version, Miguel Albrecht <malbrech at eso.org> */
+
+/* Try compressing the input file at once using mmap. Return Z_OK if
+ * if success, Z_ERRNO otherwise.
+ */
+int gz_compress_mmap(in, out)
+    FILE   *in;
+    gzFile out;
+{
+    int len;
+    int err;
+    int ifd = fileno(in);
+    caddr_t buf;    /* mmap'ed buffer for the entire input file */
+    off_t buf_len;  /* length of the input file */
+    struct stat sb;
+
+    /* Determine the size of the file, needed for mmap: */
+    if (fstat(ifd, &sb) < 0) return Z_ERRNO;
+    buf_len = sb.st_size;
+    if (buf_len <= 0) return Z_ERRNO;
+
+    /* Now do the actual mmap: */
+    buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0);
+    if (buf == (caddr_t)(-1)) return Z_ERRNO;
+
+    /* Compress the whole file at once: */
+    len = gzwrite(out, (char *)buf, (unsigned)buf_len);
+
+    if (len != (int)buf_len) error(gzerror(out, &err));
+
+    munmap(buf, buf_len);
+    fclose(in);
+    if (gzclose(out) != Z_OK) error("failed gzclose");
+    return Z_OK;
+}
+#endif /* USE_MMAP */
+
+/* ===========================================================================
+ * Uncompress input to output then close both files.
+ */
+void gz_uncompress(in, out)
+    gzFile in;
+    FILE   *out;
+{
+    local char buf[BUFLEN];
+    int len;
+    int err;
+
+    for (;;) {
+        len = gzread(in, buf, sizeof(buf));
+        if (len < 0) error (gzerror(in, &err));
+        if (len == 0) break;
+
+        if ((int)fwrite(buf, 1, (unsigned)len, out) != len) {
+            error("failed fwrite");
+        }
+    }
+    if (fclose(out)) error("failed fclose");
+
+    if (gzclose(in) != Z_OK) error("failed gzclose");
+}
+
+
+/* ===========================================================================
+ * Compress the given file: create a corresponding .gz file and remove the
+ * original.
+ */
+void file_compress(file, mode)
+    char  *file;
+    char  *mode;
+{
+    local char outfile[MAX_NAME_LEN];
+    FILE  *in;
+    gzFile out;
+
+    strcpy(outfile, file);
+    strcat(outfile, GZ_SUFFIX);
+
+    in = fopen(file, "rb");
+    if (in == NULL) {
+        perror(file);
+        exit(1);
+    }
+    out = gzopen(outfile, mode);
+    if (out == NULL) {
+        fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile);
+        exit(1);
+    }
+    gz_compress(in, out);
+
+    unlink(file);
+}
+
+
+/* ===========================================================================
+ * Uncompress the given file and remove the original.
+ */
+void file_uncompress(file)
+    char  *file;
+{
+    local char buf[MAX_NAME_LEN];
+    char *infile, *outfile;
+    FILE  *out;
+    gzFile in;
+    uInt len = (uInt)strlen(file);
+
+    strcpy(buf, file);
+
+    if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) {
+        infile = file;
+        outfile = buf;
+        outfile[len-3] = '\0';
+    } else {
+        outfile = file;
+        infile = buf;
+        strcat(infile, GZ_SUFFIX);
+    }
+    in = gzopen(infile, "rb");
+    if (in == NULL) {
+        fprintf(stderr, "%s: can't gzopen %s\n", prog, infile);
+        exit(1);
+    }
+    out = fopen(outfile, "wb");
+    if (out == NULL) {
+        perror(file);
+        exit(1);
+    }
+
+    gz_uncompress(in, out);
+
+    unlink(infile);
+}
+
+
+/* ===========================================================================
+ * Usage:  minigzip [-d] [-f] [-h] [-r] [-1 to -9] [files...]
+ *   -d : decompress
+ *   -f : compress with Z_FILTERED
+ *   -h : compress with Z_HUFFMAN_ONLY
+ *   -r : compress with Z_RLE
+ *   -1 to -9 : compression level
+ */
+
+int main(argc, argv)
+    int argc;
+    char *argv[];
+{
+    int uncompr = 0;
+    gzFile file;
+    char outmode[20];
+
+    strcpy(outmode, "wb6 ");
+
+    prog = argv[0];
+    argc--, argv++;
+
+    while (argc > 0) {
+      if (strcmp(*argv, "-d") == 0)
+        uncompr = 1;
+      else if (strcmp(*argv, "-f") == 0)
+        outmode[3] = 'f';
+      else if (strcmp(*argv, "-h") == 0)
+        outmode[3] = 'h';
+      else if (strcmp(*argv, "-r") == 0)
+        outmode[3] = 'R';
+      else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' &&
+               (*argv)[2] == 0)
+        outmode[2] = (*argv)[1];
+      else
+        break;
+      argc--, argv++;
+    }
+    if (outmode[3] == ' ')
+        outmode[3] = 0;
+    if (argc == 0) {
+        SET_BINARY_MODE(stdin);
+        SET_BINARY_MODE(stdout);
+        if (uncompr) {
+            file = gzdopen(fileno(stdin), "rb");
+            if (file == NULL) error("can't gzdopen stdin");
+            gz_uncompress(file, stdout);
+        } else {
+            file = gzdopen(fileno(stdout), outmode);
+            if (file == NULL) error("can't gzdopen stdout");
+            gz_compress(stdin, file);
+        }
+    } else {
+        do {
+            if (uncompr) {
+                file_uncompress(*argv);
+            } else {
+                file_compress(*argv, outmode);
+            }
+        } while (argv++, --argc);
+    }
+    return 0;
+}

Added: vendor/Python/current/Modules/zlib/trees.c
===================================================================
--- vendor/Python/current/Modules/zlib/trees.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/zlib/trees.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1219 @@
+/* trees.c -- output deflated data using Huffman coding
+ * Copyright (C) 1995-2005 Jean-loup Gailly
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ *  ALGORITHM
+ *
+ *      The "deflation" process uses several Huffman trees. The more
+ *      common source values are represented by shorter bit sequences.
+ *
+ *      Each code tree is stored in a compressed form which is itself
+ * a Huffman encoding of the lengths of all the code strings (in
+ * ascending order by source values).  The actual code strings are
+ * reconstructed from the lengths in the inflate process, as described
+ * in the deflate specification.
+ *
+ *  REFERENCES
+ *
+ *      Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
+ *      Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
+ *
+ *      Storer, James A.
+ *          Data Compression:  Methods and Theory, pp. 49-50.
+ *          Computer Science Press, 1988.  ISBN 0-7167-8156-5.
+ *
+ *      Sedgewick, R.
+ *          Algorithms, p290.
+ *          Addison-Wesley, 1983. ISBN 0-201-06672-6.
+ */
+
+/* @(#) $Id$ */
+
+/* #define GEN_TREES_H */
+
+#include "deflate.h"
+
+#ifdef DEBUG
+#  include <ctype.h>
+#endif
+
+/* ===========================================================================
+ * Constants
+ */
+
+#define MAX_BL_BITS 7
+/* Bit length codes must not exceed MAX_BL_BITS bits */
+
+#define END_BLOCK 256
+/* end of block literal code */
+
+#define REP_3_6      16
+/* repeat previous bit length 3-6 times (2 bits of repeat count) */
+
+#define REPZ_3_10    17
+/* repeat a zero length 3-10 times  (3 bits of repeat count) */
+
+#define REPZ_11_138  18
+/* repeat a zero length 11-138 times  (7 bits of repeat count) */
+
+local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
+   = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
+
+local const int extra_dbits[D_CODES] /* extra bits for each distance code */
+   = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
+
+local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
+   = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
+
+local const uch bl_order[BL_CODES]
+   = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
+/* The lengths of the bit length codes are sent in order of decreasing
+ * probability, to avoid transmitting the lengths for unused bit length codes.
+ */
+
+#define Buf_size (8 * 2*sizeof(char))
+/* Number of bits used within bi_buf. (bi_buf might be implemented on
+ * more than 16 bits on some systems.)
+ */
+
+/* ===========================================================================
+ * Local data. These are initialized only once.
+ */
+
+#define DIST_CODE_LEN  512 /* see definition of array dist_code below */
+
+#if defined(GEN_TREES_H) || !defined(STDC)
+/* non ANSI compilers may not accept trees.h */
+
+local ct_data static_ltree[L_CODES+2];
+/* The static literal tree. Since the bit lengths are imposed, there is no
+ * need for the L_CODES extra codes used during heap construction. However
+ * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
+ * below).
+ */
+
+local ct_data static_dtree[D_CODES];
+/* The static distance tree. (Actually a trivial tree since all codes use
+ * 5 bits.)
+ */
+
+uch _dist_code[DIST_CODE_LEN];
+/* Distance codes. The first 256 values correspond to the distances
+ * 3 .. 258, the last 256 values correspond to the top 8 bits of
+ * the 15 bit distances.
+ */
+
+uch _length_code[MAX_MATCH-MIN_MATCH+1];
+/* length code for each normalized match length (0 == MIN_MATCH) */
+
+local int base_length[LENGTH_CODES];
+/* First normalized length for each code (0 = MIN_MATCH) */
+
+local int base_dist[D_CODES];
+/* First normalized distance for each code (0 = distance of 1) */
+
+#else
+#  include "trees.h"
+#endif /* GEN_TREES_H */
+
+struct static_tree_desc_s {
+    const ct_data *static_tree;  /* static tree or NULL */
+    const intf *extra_bits;      /* extra bits for each code or NULL */
+    int     extra_base;          /* base index for extra_bits */
+    int     elems;               /* max number of elements in the tree */
+    int     max_length;          /* max bit length for the codes */
+};
+
+local static_tree_desc  static_l_desc =
+{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
+
+local static_tree_desc  static_d_desc =
+{static_dtree, extra_dbits, 0,          D_CODES, MAX_BITS};
+
+local static_tree_desc  static_bl_desc =
+{(const ct_data *)0, extra_blbits, 0,   BL_CODES, MAX_BL_BITS};
+
+/* ===========================================================================
+ * Local (static) routines in this file.
+ */
+
+local void tr_static_init OF((void));
+local void init_block     OF((deflate_state *s));
+local void pqdownheap     OF((deflate_state *s, ct_data *tree, int k));
+local void gen_bitlen     OF((deflate_state *s, tree_desc *desc));
+local void gen_codes      OF((ct_data *tree, int max_code, ushf *bl_count));
+local void build_tree     OF((deflate_state *s, tree_desc *desc));
+local void scan_tree      OF((deflate_state *s, ct_data *tree, int max_code));
+local void send_tree      OF((deflate_state *s, ct_data *tree, int max_code));
+local int  build_bl_tree  OF((deflate_state *s));
+local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
+                              int blcodes));
+local void compress_block OF((deflate_state *s, ct_data *ltree,
+                              ct_data *dtree));
+local void set_data_type  OF((deflate_state *s));
+local unsigned bi_reverse OF((unsigned value, int length));
+local void bi_windup      OF((deflate_state *s));
+local void bi_flush       OF((deflate_state *s));
+local void copy_block     OF((deflate_state *s, charf *buf, unsigned len,
+                              int header));
+
+#ifdef GEN_TREES_H
+local void gen_trees_header OF((void));
+#endif
+
+#ifndef DEBUG
+#  define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
+   /* Send a code of the given tree. c and tree must not have side effects */
+
+#else /* DEBUG */
+#  define send_code(s, c, tree) \
+     { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
+       send_bits(s, tree[c].Code, tree[c].Len); }
+#endif
+
+/* ===========================================================================
+ * Output a short LSB first on the stream.
+ * IN assertion: there is enough room in pendingBuf.
+ */
+#define put_short(s, w) { \
+    put_byte(s, (uch)((w) & 0xff)); \
+    put_byte(s, (uch)((ush)(w) >> 8)); \
+}
+
+/* ===========================================================================
+ * Send a value on a given number of bits.
+ * IN assertion: length <= 16 and value fits in length bits.
+ */
+#ifdef DEBUG
+local void send_bits      OF((deflate_state *s, int value, int length));
+
+local void send_bits(s, value, length)
+    deflate_state *s;
+    int value;  /* value to send */
+    int length; /* number of bits */
+{
+    Tracevv((stderr," l %2d v %4x ", length, value));
+    Assert(length > 0 && length <= 15, "invalid length");
+    s->bits_sent += (ulg)length;
+
+    /* If not enough room in bi_buf, use (valid) bits from bi_buf and
+     * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
+     * unused bits in value.
+     */
+    if (s->bi_valid > (int)Buf_size - length) {
+        s->bi_buf |= (value << s->bi_valid);
+        put_short(s, s->bi_buf);
+        s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
+        s->bi_valid += length - Buf_size;
+    } else {
+        s->bi_buf |= value << s->bi_valid;
+        s->bi_valid += length;
+    }
+}
+#else /* !DEBUG */
+
+#define send_bits(s, value, length) \
+{ int len = length;\
+  if (s->bi_valid > (int)Buf_size - len) {\
+    int val = value;\
+    s->bi_buf |= (val << s->bi_valid);\
+    put_short(s, s->bi_buf);\
+    s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
+    s->bi_valid += len - Buf_size;\
+  } else {\
+    s->bi_buf |= (value) << s->bi_valid;\
+    s->bi_valid += len;\
+  }\
+}
+#endif /* DEBUG */
+
+
+/* the arguments must not have side effects */
+
+/* ===========================================================================
+ * Initialize the various 'constant' tables.
+ */
+local void tr_static_init()
+{
+#if defined(GEN_TREES_H) || !defined(STDC)
+    static int static_init_done = 0;
+    int n;        /* iterates over tree elements */
+    int bits;     /* bit counter */
+    int length;   /* length value */
+    int code;     /* code value */
+    int dist;     /* distance index */
+    ush bl_count[MAX_BITS+1];
+    /* number of codes at each bit length for an optimal tree */
+
+    if (static_init_done) return;
+
+    /* For some embedded targets, global variables are not initialized: */
+    static_l_desc.static_tree = static_ltree;
+    static_l_desc.extra_bits = extra_lbits;
+    static_d_desc.static_tree = static_dtree;
+    static_d_desc.extra_bits = extra_dbits;
+    static_bl_desc.extra_bits = extra_blbits;
+
+    /* Initialize the mapping length (0..255) -> length code (0..28) */
+    length = 0;
+    for (code = 0; code < LENGTH_CODES-1; code++) {
+        base_length[code] = length;
+        for (n = 0; n < (1<<extra_lbits[code]); n++) {
+            _length_code[length++] = (uch)code;
+        }
+    }
+    Assert (length == 256, "tr_static_init: length != 256");
+    /* Note that the length 255 (match length 258) can be represented
+     * in two different ways: code 284 + 5 bits or code 285, so we
+     * overwrite length_code[255] to use the best encoding:
+     */
+    _length_code[length-1] = (uch)code;
+
+    /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
+    dist = 0;
+    for (code = 0 ; code < 16; code++) {
+        base_dist[code] = dist;
+        for (n = 0; n < (1<<extra_dbits[code]); n++) {
+            _dist_code[dist++] = (uch)code;
+        }
+    }
+    Assert (dist == 256, "tr_static_init: dist != 256");
+    dist >>= 7; /* from now on, all distances are divided by 128 */
+    for ( ; code < D_CODES; code++) {
+        base_dist[code] = dist << 7;
+        for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
+            _dist_code[256 + dist++] = (uch)code;
+        }
+    }
+    Assert (dist == 256, "tr_static_init: 256+dist != 512");
+
+    /* Construct the codes of the static literal tree */
+    for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
+    n = 0;
+    while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
+    while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
+    while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
+    while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
+    /* Codes 286 and 287 do not exist, but we must include them in the
+     * tree construction to get a canonical Huffman tree (longest code
+     * all ones)
+     */
+    gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
+
+    /* The static distance tree is trivial: */
+    for (n = 0; n < D_CODES; n++) {
+        static_dtree[n].Len = 5;
+        static_dtree[n].Code = bi_reverse((unsigned)n, 5);
+    }
+    static_init_done = 1;
+
+#  ifdef GEN_TREES_H
+    gen_trees_header();
+#  endif
+#endif /* defined(GEN_TREES_H) || !defined(STDC) */
+}
+
+/* ===========================================================================
+ * Genererate the file trees.h describing the static trees.
+ */
+#ifdef GEN_TREES_H
+#  ifndef DEBUG
+#    include <stdio.h>
+#  endif
+
+#  define SEPARATOR(i, last, width) \
+      ((i) == (last)? "\n};\n\n" :    \
+       ((i) % (width) == (width)-1 ? ",\n" : ", "))
+
+void gen_trees_header()
+{
+    FILE *header = fopen("trees.h", "w");
+    int i;
+
+    Assert (header != NULL, "Can't open trees.h");
+    fprintf(header,
+            "/* header created automatically with -DGEN_TREES_H */\n\n");
+
+    fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n");
+    for (i = 0; i < L_CODES+2; i++) {
+        fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code,
+                static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));
+    }
+
+    fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n");
+    for (i = 0; i < D_CODES; i++) {
+        fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code,
+                static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
+    }
+
+    fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n");
+    for (i = 0; i < DIST_CODE_LEN; i++) {
+        fprintf(header, "%2u%s", _dist_code[i],
+                SEPARATOR(i, DIST_CODE_LEN-1, 20));
+    }
+
+    fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
+    for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
+        fprintf(header, "%2u%s", _length_code[i],
+                SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
+    }
+
+    fprintf(header, "local const int base_length[LENGTH_CODES] = {\n");
+    for (i = 0; i < LENGTH_CODES; i++) {
+        fprintf(header, "%1u%s", base_length[i],
+                SEPARATOR(i, LENGTH_CODES-1, 20));
+    }
+
+    fprintf(header, "local const int base_dist[D_CODES] = {\n");
+    for (i = 0; i < D_CODES; i++) {
+        fprintf(header, "%5u%s", base_dist[i],
+                SEPARATOR(i, D_CODES-1, 10));
+    }
+
+    fclose(header);
+}
+#endif /* GEN_TREES_H */
+
+/* ===========================================================================
+ * Initialize the tree data structures for a new zlib stream.
+ */
+void _tr_init(s)
+    deflate_state *s;
+{
+    tr_static_init();
+
+    s->l_desc.dyn_tree = s->dyn_ltree;
+    s->l_desc.stat_desc = &static_l_desc;
+
+    s->d_desc.dyn_tree = s->dyn_dtree;
+    s->d_desc.stat_desc = &static_d_desc;
+
+    s->bl_desc.dyn_tree = s->bl_tree;
+    s->bl_desc.stat_desc = &static_bl_desc;
+
+    s->bi_buf = 0;
+    s->bi_valid = 0;
+    s->last_eob_len = 8; /* enough lookahead for inflate */
+#ifdef DEBUG
+    s->compressed_len = 0L;
+    s->bits_sent = 0L;
+#endif
+
+    /* Initialize the first block of the first file: */
+    init_block(s);
+}
+
+/* ===========================================================================
+ * Initialize a new block.
+ */
+local void init_block(s)
+    deflate_state *s;
+{
+    int n; /* iterates over tree elements */
+
+    /* Initialize the trees. */
+    for (n = 0; n < L_CODES;  n++) s->dyn_ltree[n].Freq = 0;
+    for (n = 0; n < D_CODES;  n++) s->dyn_dtree[n].Freq = 0;
+    for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
+
+    s->dyn_ltree[END_BLOCK].Freq = 1;
+    s->opt_len = s->static_len = 0L;
+    s->last_lit = s->matches = 0;
+}
+
+#define SMALLEST 1
+/* Index within the heap array of least frequent node in the Huffman tree */
+
+
+/* ===========================================================================
+ * Remove the smallest element from the heap and recreate the heap with
+ * one less element. Updates heap and heap_len.
+ */
+#define pqremove(s, tree, top) \
+{\
+    top = s->heap[SMALLEST]; \
+    s->heap[SMALLEST] = s->heap[s->heap_len--]; \
+    pqdownheap(s, tree, SMALLEST); \
+}
+
+/* ===========================================================================
+ * Compares to subtrees, using the tree depth as tie breaker when
+ * the subtrees have equal frequency. This minimizes the worst case length.
+ */
+#define smaller(tree, n, m, depth) \
+   (tree[n].Freq < tree[m].Freq || \
+   (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
+
+/* ===========================================================================
+ * Restore the heap property by moving down the tree starting at node k,
+ * exchanging a node with the smallest of its two sons if necessary, stopping
+ * when the heap property is re-established (each father smaller than its
+ * two sons).
+ */
+local void pqdownheap(s, tree, k)
+    deflate_state *s;
+    ct_data *tree;  /* the tree to restore */
+    int k;               /* node to move down */
+{
+    int v = s->heap[k];
+    int j = k << 1;  /* left son of k */
+    while (j <= s->heap_len) {
+        /* Set j to the smallest of the two sons: */
+        if (j < s->heap_len &&
+            smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
+            j++;
+        }
+        /* Exit if v is smaller than both sons */
+        if (smaller(tree, v, s->heap[j], s->depth)) break;
+
+        /* Exchange v with the smallest son */
+        s->heap[k] = s->heap[j];  k = j;
+
+        /* And continue down the tree, setting j to the left son of k */
+        j <<= 1;
+    }
+    s->heap[k] = v;
+}
+
+/* ===========================================================================
+ * Compute the optimal bit lengths for a tree and update the total bit length
+ * for the current block.
+ * IN assertion: the fields freq and dad are set, heap[heap_max] and
+ *    above are the tree nodes sorted by increasing frequency.
+ * OUT assertions: the field len is set to the optimal bit length, the
+ *     array bl_count contains the frequencies for each bit length.
+ *     The length opt_len is updated; static_len is also updated if stree is
+ *     not null.
+ */
+local void gen_bitlen(s, desc)
+    deflate_state *s;
+    tree_desc *desc;    /* the tree descriptor */
+{
+    ct_data *tree        = desc->dyn_tree;
+    int max_code         = desc->max_code;
+    const ct_data *stree = desc->stat_desc->static_tree;
+    const intf *extra    = desc->stat_desc->extra_bits;
+    int base             = desc->stat_desc->extra_base;
+    int max_length       = desc->stat_desc->max_length;
+    int h;              /* heap index */
+    int n, m;           /* iterate over the tree elements */
+    int bits;           /* bit length */
+    int xbits;          /* extra bits */
+    ush f;              /* frequency */
+    int overflow = 0;   /* number of elements with bit length too large */
+
+    for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
+
+    /* In a first pass, compute the optimal bit lengths (which may
+     * overflow in the case of the bit length tree).
+     */
+    tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
+
+    for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
+        n = s->heap[h];
+        bits = tree[tree[n].Dad].Len + 1;
+        if (bits > max_length) bits = max_length, overflow++;
+        tree[n].Len = (ush)bits;
+        /* We overwrite tree[n].Dad which is no longer needed */
+
+        if (n > max_code) continue; /* not a leaf node */
+
+        s->bl_count[bits]++;
+        xbits = 0;
+        if (n >= base) xbits = extra[n-base];
+        f = tree[n].Freq;
+        s->opt_len += (ulg)f * (bits + xbits);
+        if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
+    }
+    if (overflow == 0) return;
+
+    Trace((stderr,"\nbit length overflow\n"));
+    /* This happens for example on obj2 and pic of the Calgary corpus */
+
+    /* Find the first bit length which could increase: */
+    do {
+        bits = max_length-1;
+        while (s->bl_count[bits] == 0) bits--;
+        s->bl_count[bits]--;      /* move one leaf down the tree */
+        s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
+        s->bl_count[max_length]--;
+        /* The brother of the overflow item also moves one step up,
+         * but this does not affect bl_count[max_length]
+         */
+        overflow -= 2;
+    } while (overflow > 0);
+
+    /* Now recompute all bit lengths, scanning in increasing frequency.
+     * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
+     * lengths instead of fixing only the wrong ones. This idea is taken
+     * from 'ar' written by Haruhiko Okumura.)
+     */
+    for (bits = max_length; bits != 0; bits--) {
+        n = s->bl_count[bits];
+        while (n != 0) {
+            m = s->heap[--h];
+            if (m > max_code) continue;
+            if ((unsigned) tree[m].Len != (unsigned) bits) {
+                Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
+                s->opt_len += ((long)bits - (long)tree[m].Len)
+                              *(long)tree[m].Freq;
+                tree[m].Len = (ush)bits;
+            }
+            n--;
+        }
+    }
+}
+
+/* ===========================================================================
+ * Generate the codes for a given tree and bit counts (which need not be
+ * optimal).
+ * IN assertion: the array bl_count contains the bit length statistics for
+ * the given tree and the field len is set for all tree elements.
+ * OUT assertion: the field code is set for all tree elements of non
+ *     zero code length.
+ */
+local void gen_codes (tree, max_code, bl_count)
+    ct_data *tree;             /* the tree to decorate */
+    int max_code;              /* largest code with non zero frequency */
+    ushf *bl_count;            /* number of codes at each bit length */
+{
+    ush next_code[MAX_BITS+1]; /* next code value for each bit length */
+    ush code = 0;              /* running code value */
+    int bits;                  /* bit index */
+    int n;                     /* code index */
+
+    /* The distribution counts are first used to generate the code values
+     * without bit reversal.
+     */
+    for (bits = 1; bits <= MAX_BITS; bits++) {
+        next_code[bits] = code = (code + bl_count[bits-1]) << 1;
+    }
+    /* Check that the bit counts in bl_count are consistent. The last code
+     * must be all ones.
+     */
+    Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
+            "inconsistent bit counts");
+    Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
+
+    for (n = 0;  n <= max_code; n++) {
+        int len = tree[n].Len;
+        if (len == 0) continue;
+        /* Now reverse the bits */
+        tree[n].Code = bi_reverse(next_code[len]++, len);
+
+        Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
+             n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
+    }
+}
+
+/* ===========================================================================
+ * Construct one Huffman tree and assigns the code bit strings and lengths.
+ * Update the total bit length for the current block.
+ * IN assertion: the field freq is set for all tree elements.
+ * OUT assertions: the fields len and code are set to the optimal bit length
+ *     and corresponding code. The length opt_len is updated; static_len is
+ *     also updated if stree is not null. The field max_code is set.
+ */
+local void build_tree(s, desc)
+    deflate_state *s;
+    tree_desc *desc; /* the tree descriptor */
+{
+    ct_data *tree         = desc->dyn_tree;
+    const ct_data *stree  = desc->stat_desc->static_tree;
+    int elems             = desc->stat_desc->elems;
+    int n, m;          /* iterate over heap elements */
+    int max_code = -1; /* largest code with non zero frequency */
+    int node;          /* new node being created */
+
+    /* Construct the initial heap, with least frequent element in
+     * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
+     * heap[0] is not used.
+     */
+    s->heap_len = 0, s->heap_max = HEAP_SIZE;
+
+    for (n = 0; n < elems; n++) {
+        if (tree[n].Freq != 0) {
+            s->heap[++(s->heap_len)] = max_code = n;
+            s->depth[n] = 0;
+        } else {
+            tree[n].Len = 0;
+        }
+    }
+
+    /* The pkzip format requires that at least one distance code exists,
+     * and that at least one bit should be sent even if there is only one
+     * possible code. So to avoid special checks later on we force at least
+     * two codes of non zero frequency.
+     */
+    while (s->heap_len < 2) {
+        node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
+        tree[node].Freq = 1;
+        s->depth[node] = 0;
+        s->opt_len--; if (stree) s->static_len -= stree[node].Len;
+        /* node is 0 or 1 so it does not have extra bits */
+    }
+    desc->max_code = max_code;
+
+    /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
+     * establish sub-heaps of increasing lengths:
+     */
+    for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
+
+    /* Construct the Huffman tree by repeatedly combining the least two
+     * frequent nodes.
+     */
+    node = elems;              /* next internal node of the tree */
+    do {
+        pqremove(s, tree, n);  /* n = node of least frequency */
+        m = s->heap[SMALLEST]; /* m = node of next least frequency */
+
+        s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
+        s->heap[--(s->heap_max)] = m;
+
+        /* Create a new node father of n and m */
+        tree[node].Freq = tree[n].Freq + tree[m].Freq;
+        s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ?
+                                s->depth[n] : s->depth[m]) + 1);
+        tree[n].Dad = tree[m].Dad = (ush)node;
+#ifdef DUMP_BL_TREE
+        if (tree == s->bl_tree) {
+            fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
+                    node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
+        }
+#endif
+        /* and insert the new node in the heap */
+        s->heap[SMALLEST] = node++;
+        pqdownheap(s, tree, SMALLEST);
+
+    } while (s->heap_len >= 2);
+
+    s->heap[--(s->heap_max)] = s->heap[SMALLEST];
+
+    /* At this point, the fields freq and dad are set. We can now
+     * generate the bit lengths.
+     */
+    gen_bitlen(s, (tree_desc *)desc);
+
+    /* The field len is now set, we can generate the bit codes */
+    gen_codes ((ct_data *)tree, max_code, s->bl_count);
+}
+
+/* ===========================================================================
+ * Scan a literal or distance tree to determine the frequencies of the codes
+ * in the bit length tree.
+ */
+local void scan_tree (s, tree, max_code)
+    deflate_state *s;
+    ct_data *tree;   /* the tree to be scanned */
+    int max_code;    /* and its largest code of non zero frequency */
+{
+    int n;                     /* iterates over all tree elements */
+    int prevlen = -1;          /* last emitted length */
+    int curlen;                /* length of current code */
+    int nextlen = tree[0].Len; /* length of next code */
+    int count = 0;             /* repeat count of the current code */
+    int max_count = 7;         /* max repeat count */
+    int min_count = 4;         /* min repeat count */
+
+    if (nextlen == 0) max_count = 138, min_count = 3;
+    tree[max_code+1].Len = (ush)0xffff; /* guard */
+
+    for (n = 0; n <= max_code; n++) {
+        curlen = nextlen; nextlen = tree[n+1].Len;
+        if (++count < max_count && curlen == nextlen) {
+            continue;
+        } else if (count < min_count) {
+            s->bl_tree[curlen].Freq += count;
+        } else if (curlen != 0) {
+            if (curlen != prevlen) s->bl_tree[curlen].Freq++;
+            s->bl_tree[REP_3_6].Freq++;
+        } else if (count <= 10) {
+            s->bl_tree[REPZ_3_10].Freq++;
+        } else {
+            s->bl_tree[REPZ_11_138].Freq++;
+        }
+        count = 0; prevlen = curlen;
+        if (nextlen == 0) {
+            max_count = 138, min_count = 3;
+        } else if (curlen == nextlen) {
+            max_count = 6, min_count = 3;
+        } else {
+            max_count = 7, min_count = 4;
+        }
+    }
+}
+
+/* ===========================================================================
+ * Send a literal or distance tree in compressed form, using the codes in
+ * bl_tree.
+ */
+local void send_tree (s, tree, max_code)
+    deflate_state *s;
+    ct_data *tree; /* the tree to be scanned */
+    int max_code;       /* and its largest code of non zero frequency */
+{
+    int n;                     /* iterates over all tree elements */
+    int prevlen = -1;          /* last emitted length */
+    int curlen;                /* length of current code */
+    int nextlen = tree[0].Len; /* length of next code */
+    int count = 0;             /* repeat count of the current code */
+    int max_count = 7;         /* max repeat count */
+    int min_count = 4;         /* min repeat count */
+
+    /* tree[max_code+1].Len = -1; */  /* guard already set */
+    if (nextlen == 0) max_count = 138, min_count = 3;
+
+    for (n = 0; n <= max_code; n++) {
+        curlen = nextlen; nextlen = tree[n+1].Len;
+        if (++count < max_count && curlen == nextlen) {
+            continue;
+        } else if (count < min_count) {
+            do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
+
+        } else if (curlen != 0) {
+            if (curlen != prevlen) {
+                send_code(s, curlen, s->bl_tree); count--;
+            }
+            Assert(count >= 3 && count <= 6, " 3_6?");
+            send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
+
+        } else if (count <= 10) {
+            send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
+
+        } else {
+            send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
+        }
+        count = 0; prevlen = curlen;
+        if (nextlen == 0) {
+            max_count = 138, min_count = 3;
+        } else if (curlen == nextlen) {
+            max_count = 6, min_count = 3;
+        } else {
+            max_count = 7, min_count = 4;
+        }
+    }
+}
+
+/* ===========================================================================
+ * Construct the Huffman tree for the bit lengths and return the index in
+ * bl_order of the last bit length code to send.
+ */
+local int build_bl_tree(s)
+    deflate_state *s;
+{
+    int max_blindex;  /* index of last bit length code of non zero freq */
+
+    /* Determine the bit length frequencies for literal and distance trees */
+    scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
+    scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
+
+    /* Build the bit length tree: */
+    build_tree(s, (tree_desc *)(&(s->bl_desc)));
+    /* opt_len now includes the length of the tree representations, except
+     * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
+     */
+
+    /* Determine the number of bit length codes to send. The pkzip format
+     * requires that at least 4 bit length codes be sent. (appnote.txt says
+     * 3 but the actual value used is 4.)
+     */
+    for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
+        if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
+    }
+    /* Update opt_len to include the bit length tree and counts */
+    s->opt_len += 3*(max_blindex+1) + 5+5+4;
+    Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
+            s->opt_len, s->static_len));
+
+    return max_blindex;
+}
+
+/* ===========================================================================
+ * Send the header for a block using dynamic Huffman trees: the counts, the
+ * lengths of the bit length codes, the literal tree and the distance tree.
+ * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
+ */
+local void send_all_trees(s, lcodes, dcodes, blcodes)
+    deflate_state *s;
+    int lcodes, dcodes, blcodes; /* number of codes for each tree */
+{
+    int rank;                    /* index in bl_order */
+
+    Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
+    Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
+            "too many codes");
+    Tracev((stderr, "\nbl counts: "));
+    send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
+    send_bits(s, dcodes-1,   5);
+    send_bits(s, blcodes-4,  4); /* not -3 as stated in appnote.txt */
+    for (rank = 0; rank < blcodes; rank++) {
+        Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
+        send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
+    }
+    Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
+
+    send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
+    Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
+
+    send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
+    Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
+}
+
+/* ===========================================================================
+ * Send a stored block
+ */
+void _tr_stored_block(s, buf, stored_len, eof)
+    deflate_state *s;
+    charf *buf;       /* input block */
+    ulg stored_len;   /* length of input block */
+    int eof;          /* true if this is the last block for a file */
+{
+    send_bits(s, (STORED_BLOCK<<1)+eof, 3);  /* send block type */
+#ifdef DEBUG
+    s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
+    s->compressed_len += (stored_len + 4) << 3;
+#endif
+    copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
+}
+
+/* ===========================================================================
+ * Send one empty static block to give enough lookahead for inflate.
+ * This takes 10 bits, of which 7 may remain in the bit buffer.
+ * The current inflate code requires 9 bits of lookahead. If the
+ * last two codes for the previous block (real code plus EOB) were coded
+ * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
+ * the last real code. In this case we send two empty static blocks instead
+ * of one. (There are no problems if the previous block is stored or fixed.)
+ * To simplify the code, we assume the worst case of last real code encoded
+ * on one bit only.
+ */
+void _tr_align(s)
+    deflate_state *s;
+{
+    send_bits(s, STATIC_TREES<<1, 3);
+    send_code(s, END_BLOCK, static_ltree);
+#ifdef DEBUG
+    s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
+#endif
+    bi_flush(s);
+    /* Of the 10 bits for the empty block, we have already sent
+     * (10 - bi_valid) bits. The lookahead for the last real code (before
+     * the EOB of the previous block) was thus at least one plus the length
+     * of the EOB plus what we have just sent of the empty static block.
+     */
+    if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
+        send_bits(s, STATIC_TREES<<1, 3);
+        send_code(s, END_BLOCK, static_ltree);
+#ifdef DEBUG
+        s->compressed_len += 10L;
+#endif
+        bi_flush(s);
+    }
+    s->last_eob_len = 7;
+}
+
+/* ===========================================================================
+ * Determine the best encoding for the current block: dynamic trees, static
+ * trees or store, and output the encoded block to the zip file.
+ */
+void _tr_flush_block(s, buf, stored_len, eof)
+    deflate_state *s;
+    charf *buf;       /* input block, or NULL if too old */
+    ulg stored_len;   /* length of input block */
+    int eof;          /* true if this is the last block for a file */
+{
+    ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
+    int max_blindex = 0;  /* index of last bit length code of non zero freq */
+
+    /* Build the Huffman trees unless a stored block is forced */
+    if (s->level > 0) {
+
+        /* Check if the file is binary or text */
+        if (stored_len > 0 && s->strm->data_type == Z_UNKNOWN)
+            set_data_type(s);
+
+        /* Construct the literal and distance trees */
+        build_tree(s, (tree_desc *)(&(s->l_desc)));
+        Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
+                s->static_len));
+
+        build_tree(s, (tree_desc *)(&(s->d_desc)));
+        Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
+                s->static_len));
+        /* At this point, opt_len and static_len are the total bit lengths of
+         * the compressed block data, excluding the tree representations.
+         */
+
+        /* Build the bit length tree for the above two trees, and get the index
+         * in bl_order of the last bit length code to send.
+         */
+        max_blindex = build_bl_tree(s);
+
+        /* Determine the best encoding. Compute the block lengths in bytes. */
+        opt_lenb = (s->opt_len+3+7)>>3;
+        static_lenb = (s->static_len+3+7)>>3;
+
+        Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
+                opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
+                s->last_lit));
+
+        if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
+
+    } else {
+        Assert(buf != (char*)0, "lost buf");
+        opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
+    }
+
+#ifdef FORCE_STORED
+    if (buf != (char*)0) { /* force stored block */
+#else
+    if (stored_len+4 <= opt_lenb && buf != (char*)0) {
+                       /* 4: two words for the lengths */
+#endif
+        /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
+         * Otherwise we can't have processed more than WSIZE input bytes since
+         * the last block flush, because compression would have been
+         * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
+         * transform a block into a stored block.
+         */
+        _tr_stored_block(s, buf, stored_len, eof);
+
+#ifdef FORCE_STATIC
+    } else if (static_lenb >= 0) { /* force static trees */
+#else
+    } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) {
+#endif
+        send_bits(s, (STATIC_TREES<<1)+eof, 3);
+        compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree);
+#ifdef DEBUG
+        s->compressed_len += 3 + s->static_len;
+#endif
+    } else {
+        send_bits(s, (DYN_TREES<<1)+eof, 3);
+        send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
+                       max_blindex+1);
+        compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree);
+#ifdef DEBUG
+        s->compressed_len += 3 + s->opt_len;
+#endif
+    }
+    Assert (s->compressed_len == s->bits_sent, "bad compressed size");
+    /* The above check is made mod 2^32, for files larger than 512 MB
+     * and uLong implemented on 32 bits.
+     */
+    init_block(s);
+
+    if (eof) {
+        bi_windup(s);
+#ifdef DEBUG
+        s->compressed_len += 7;  /* align on byte boundary */
+#endif
+    }
+    Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
+           s->compressed_len-7*eof));
+}
+
+/* ===========================================================================
+ * Save the match info and tally the frequency counts. Return true if
+ * the current block must be flushed.
+ */
+int _tr_tally (s, dist, lc)
+    deflate_state *s;
+    unsigned dist;  /* distance of matched string */
+    unsigned lc;    /* match length-MIN_MATCH or unmatched char (if dist==0) */
+{
+    s->d_buf[s->last_lit] = (ush)dist;
+    s->l_buf[s->last_lit++] = (uch)lc;
+    if (dist == 0) {
+        /* lc is the unmatched char */
+        s->dyn_ltree[lc].Freq++;
+    } else {
+        s->matches++;
+        /* Here, lc is the match length - MIN_MATCH */
+        dist--;             /* dist = match distance - 1 */
+        Assert((ush)dist < (ush)MAX_DIST(s) &&
+               (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
+               (ush)d_code(dist) < (ush)D_CODES,  "_tr_tally: bad match");
+
+        s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
+        s->dyn_dtree[d_code(dist)].Freq++;
+    }
+
+#ifdef TRUNCATE_BLOCK
+    /* Try to guess if it is profitable to stop the current block here */
+    if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
+        /* Compute an upper bound for the compressed length */
+        ulg out_length = (ulg)s->last_lit*8L;
+        ulg in_length = (ulg)((long)s->strstart - s->block_start);
+        int dcode;
+        for (dcode = 0; dcode < D_CODES; dcode++) {
+            out_length += (ulg)s->dyn_dtree[dcode].Freq *
+                (5L+extra_dbits[dcode]);
+        }
+        out_length >>= 3;
+        Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
+               s->last_lit, in_length, out_length,
+               100L - out_length*100L/in_length));
+        if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
+    }
+#endif
+    return (s->last_lit == s->lit_bufsize-1);
+    /* We avoid equality with lit_bufsize because of wraparound at 64K
+     * on 16 bit machines and because stored blocks are restricted to
+     * 64K-1 bytes.
+     */
+}
+
+/* ===========================================================================
+ * Send the block data compressed using the given Huffman trees
+ */
+local void compress_block(s, ltree, dtree)
+    deflate_state *s;
+    ct_data *ltree; /* literal tree */
+    ct_data *dtree; /* distance tree */
+{
+    unsigned dist;      /* distance of matched string */
+    int lc;             /* match length or unmatched char (if dist == 0) */
+    unsigned lx = 0;    /* running index in l_buf */
+    unsigned code;      /* the code to send */
+    int extra;          /* number of extra bits to send */
+
+    if (s->last_lit != 0) do {
+        dist = s->d_buf[lx];
+        lc = s->l_buf[lx++];
+        if (dist == 0) {
+            send_code(s, lc, ltree); /* send a literal byte */
+            Tracecv(isgraph(lc), (stderr," '%c' ", lc));
+        } else {
+            /* Here, lc is the match length - MIN_MATCH */
+            code = _length_code[lc];
+            send_code(s, code+LITERALS+1, ltree); /* send the length code */
+            extra = extra_lbits[code];
+            if (extra != 0) {
+                lc -= base_length[code];
+                send_bits(s, lc, extra);       /* send the extra length bits */
+            }
+            dist--; /* dist is now the match distance - 1 */
+            code = d_code(dist);
+            Assert (code < D_CODES, "bad d_code");
+
+            send_code(s, code, dtree);       /* send the distance code */
+            extra = extra_dbits[code];
+            if (extra != 0) {
+                dist -= base_dist[code];
+                send_bits(s, dist, extra);   /* send the extra distance bits */
+            }
+        } /* literal or match pair ? */
+
+        /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
+        Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx,
+               "pendingBuf overflow");
+
+    } while (lx < s->last_lit);
+
+    send_code(s, END_BLOCK, ltree);
+    s->last_eob_len = ltree[END_BLOCK].Len;
+}
+
+/* ===========================================================================
+ * Set the data type to BINARY or TEXT, using a crude approximation:
+ * set it to Z_TEXT if all symbols are either printable characters (33 to 255)
+ * or white spaces (9 to 13, or 32); or set it to Z_BINARY otherwise.
+ * IN assertion: the fields Freq of dyn_ltree are set.
+ */
+local void set_data_type(s)
+    deflate_state *s;
+{
+    int n;
+
+    for (n = 0; n < 9; n++)
+        if (s->dyn_ltree[n].Freq != 0)
+            break;
+    if (n == 9)
+        for (n = 14; n < 32; n++)
+            if (s->dyn_ltree[n].Freq != 0)
+                break;
+    s->strm->data_type = (n == 32) ? Z_TEXT : Z_BINARY;
+}
+
+/* ===========================================================================
+ * Reverse the first len bits of a code, using straightforward code (a faster
+ * method would use a table)
+ * IN assertion: 1 <= len <= 15
+ */
+local unsigned bi_reverse(code, len)
+    unsigned code; /* the value to invert */
+    int len;       /* its bit length */
+{
+    register unsigned res = 0;
+    do {
+        res |= code & 1;
+        code >>= 1, res <<= 1;
+    } while (--len > 0);
+    return res >> 1;
+}
+
+/* ===========================================================================
+ * Flush the bit buffer, keeping at most 7 bits in it.
+ */
+local void bi_flush(s)
+    deflate_state *s;
+{
+    if (s->bi_valid == 16) {
+        put_short(s, s->bi_buf);
+        s->bi_buf = 0;
+        s->bi_valid = 0;
+    } else if (s->bi_valid >= 8) {
+        put_byte(s, (Byte)s->bi_buf);
+        s->bi_buf >>= 8;
+        s->bi_valid -= 8;
+    }
+}
+
+/* ===========================================================================
+ * Flush the bit buffer and align the output on a byte boundary
+ */
+local void bi_windup(s)
+    deflate_state *s;
+{
+    if (s->bi_valid > 8) {
+        put_short(s, s->bi_buf);
+    } else if (s->bi_valid > 0) {
+        put_byte(s, (Byte)s->bi_buf);
+    }
+    s->bi_buf = 0;
+    s->bi_valid = 0;
+#ifdef DEBUG
+    s->bits_sent = (s->bits_sent+7) & ~7;
+#endif
+}
+
+/* ===========================================================================
+ * Copy a stored block, storing first the length and its
+ * one's complement if requested.
+ */
+local void copy_block(s, buf, len, header)
+    deflate_state *s;
+    charf    *buf;    /* the input data */
+    unsigned len;     /* its length */
+    int      header;  /* true if block header must be written */
+{
+    bi_windup(s);        /* align on byte boundary */
+    s->last_eob_len = 8; /* enough lookahead for inflate */
+
+    if (header) {
+        put_short(s, (ush)len);
+        put_short(s, (ush)~len);
+#ifdef DEBUG
+        s->bits_sent += 2*16;
+#endif
+    }
+#ifdef DEBUG
+    s->bits_sent += (ulg)len<<3;
+#endif
+    while (len--) {
+        put_byte(s, *buf++);
+    }
+}

Added: vendor/Python/current/Modules/zlib/trees.h
===================================================================
--- vendor/Python/current/Modules/zlib/trees.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/zlib/trees.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,128 @@
+/* header created automatically with -DGEN_TREES_H */
+
+local const ct_data static_ltree[L_CODES+2] = {
+{{ 12},{  8}}, {{140},{  8}}, {{ 76},{  8}}, {{204},{  8}}, {{ 44},{  8}},
+{{172},{  8}}, {{108},{  8}}, {{236},{  8}}, {{ 28},{  8}}, {{156},{  8}},
+{{ 92},{  8}}, {{220},{  8}}, {{ 60},{  8}}, {{188},{  8}}, {{124},{  8}},
+{{252},{  8}}, {{  2},{  8}}, {{130},{  8}}, {{ 66},{  8}}, {{194},{  8}},
+{{ 34},{  8}}, {{162},{  8}}, {{ 98},{  8}}, {{226},{  8}}, {{ 18},{  8}},
+{{146},{  8}}, {{ 82},{  8}}, {{210},{  8}}, {{ 50},{  8}}, {{178},{  8}},
+{{114},{  8}}, {{242},{  8}}, {{ 10},{  8}}, {{138},{  8}}, {{ 74},{  8}},
+{{202},{  8}}, {{ 42},{  8}}, {{170},{  8}}, {{106},{  8}}, {{234},{  8}},
+{{ 26},{  8}}, {{154},{  8}}, {{ 90},{  8}}, {{218},{  8}}, {{ 58},{  8}},
+{{186},{  8}}, {{122},{  8}}, {{250},{  8}}, {{  6},{  8}}, {{134},{  8}},
+{{ 70},{  8}}, {{198},{  8}}, {{ 38},{  8}}, {{166},{  8}}, {{102},{  8}},
+{{230},{  8}}, {{ 22},{  8}}, {{150},{  8}}, {{ 86},{  8}}, {{214},{  8}},
+{{ 54},{  8}}, {{182},{  8}}, {{118},{  8}}, {{246},{  8}}, {{ 14},{  8}},
+{{142},{  8}}, {{ 78},{  8}}, {{206},{  8}}, {{ 46},{  8}}, {{174},{  8}},
+{{110},{  8}}, {{238},{  8}}, {{ 30},{  8}}, {{158},{  8}}, {{ 94},{  8}},
+{{222},{  8}}, {{ 62},{  8}}, {{190},{  8}}, {{126},{  8}}, {{254},{  8}},
+{{  1},{  8}}, {{129},{  8}}, {{ 65},{  8}}, {{193},{  8}}, {{ 33},{  8}},
+{{161},{  8}}, {{ 97},{  8}}, {{225},{  8}}, {{ 17},{  8}}, {{145},{  8}},
+{{ 81},{  8}}, {{209},{  8}}, {{ 49},{  8}}, {{177},{  8}}, {{113},{  8}},
+{{241},{  8}}, {{  9},{  8}}, {{137},{  8}}, {{ 73},{  8}}, {{201},{  8}},
+{{ 41},{  8}}, {{169},{  8}}, {{105},{  8}}, {{233},{  8}}, {{ 25},{  8}},
+{{153},{  8}}, {{ 89},{  8}}, {{217},{  8}}, {{ 57},{  8}}, {{185},{  8}},
+{{121},{  8}}, {{249},{  8}}, {{  5},{  8}}, {{133},{  8}}, {{ 69},{  8}},
+{{197},{  8}}, {{ 37},{  8}}, {{165},{  8}}, {{101},{  8}}, {{229},{  8}},
+{{ 21},{  8}}, {{149},{  8}}, {{ 85},{  8}}, {{213},{  8}}, {{ 53},{  8}},
+{{181},{  8}}, {{117},{  8}}, {{245},{  8}}, {{ 13},{  8}}, {{141},{  8}},
+{{ 77},{  8}}, {{205},{  8}}, {{ 45},{  8}}, {{173},{  8}}, {{109},{  8}},
+{{237},{  8}}, {{ 29},{  8}}, {{157},{  8}}, {{ 93},{  8}}, {{221},{  8}},
+{{ 61},{  8}}, {{189},{  8}}, {{125},{  8}}, {{253},{  8}}, {{ 19},{  9}},
+{{275},{  9}}, {{147},{  9}}, {{403},{  9}}, {{ 83},{  9}}, {{339},{  9}},
+{{211},{  9}}, {{467},{  9}}, {{ 51},{  9}}, {{307},{  9}}, {{179},{  9}},
+{{435},{  9}}, {{115},{  9}}, {{371},{  9}}, {{243},{  9}}, {{499},{  9}},
+{{ 11},{  9}}, {{267},{  9}}, {{139},{  9}}, {{395},{  9}}, {{ 75},{  9}},
+{{331},{  9}}, {{203},{  9}}, {{459},{  9}}, {{ 43},{  9}}, {{299},{  9}},
+{{171},{  9}}, {{427},{  9}}, {{107},{  9}}, {{363},{  9}}, {{235},{  9}},
+{{491},{  9}}, {{ 27},{  9}}, {{283},{  9}}, {{155},{  9}}, {{411},{  9}},
+{{ 91},{  9}}, {{347},{  9}}, {{219},{  9}}, {{475},{  9}}, {{ 59},{  9}},
+{{315},{  9}}, {{187},{  9}}, {{443},{  9}}, {{123},{  9}}, {{379},{  9}},
+{{251},{  9}}, {{507},{  9}}, {{  7},{  9}}, {{263},{  9}}, {{135},{  9}},
+{{391},{  9}}, {{ 71},{  9}}, {{327},{  9}}, {{199},{  9}}, {{455},{  9}},
+{{ 39},{  9}}, {{295},{  9}}, {{167},{  9}}, {{423},{  9}}, {{103},{  9}},
+{{359},{  9}}, {{231},{  9}}, {{487},{  9}}, {{ 23},{  9}}, {{279},{  9}},
+{{151},{  9}}, {{407},{  9}}, {{ 87},{  9}}, {{343},{  9}}, {{215},{  9}},
+{{471},{  9}}, {{ 55},{  9}}, {{311},{  9}}, {{183},{  9}}, {{439},{  9}},
+{{119},{  9}}, {{375},{  9}}, {{247},{  9}}, {{503},{  9}}, {{ 15},{  9}},
+{{271},{  9}}, {{143},{  9}}, {{399},{  9}}, {{ 79},{  9}}, {{335},{  9}},
+{{207},{  9}}, {{463},{  9}}, {{ 47},{  9}}, {{303},{  9}}, {{175},{  9}},
+{{431},{  9}}, {{111},{  9}}, {{367},{  9}}, {{239},{  9}}, {{495},{  9}},
+{{ 31},{  9}}, {{287},{  9}}, {{159},{  9}}, {{415},{  9}}, {{ 95},{  9}},
+{{351},{  9}}, {{223},{  9}}, {{479},{  9}}, {{ 63},{  9}}, {{319},{  9}},
+{{191},{  9}}, {{447},{  9}}, {{127},{  9}}, {{383},{  9}}, {{255},{  9}},
+{{511},{  9}}, {{  0},{  7}}, {{ 64},{  7}}, {{ 32},{  7}}, {{ 96},{  7}},
+{{ 16},{  7}}, {{ 80},{  7}}, {{ 48},{  7}}, {{112},{  7}}, {{  8},{  7}},
+{{ 72},{  7}}, {{ 40},{  7}}, {{104},{  7}}, {{ 24},{  7}}, {{ 88},{  7}},
+{{ 56},{  7}}, {{120},{  7}}, {{  4},{  7}}, {{ 68},{  7}}, {{ 36},{  7}},
+{{100},{  7}}, {{ 20},{  7}}, {{ 84},{  7}}, {{ 52},{  7}}, {{116},{  7}},
+{{  3},{  8}}, {{131},{  8}}, {{ 67},{  8}}, {{195},{  8}}, {{ 35},{  8}},
+{{163},{  8}}, {{ 99},{  8}}, {{227},{  8}}
+};
+
+local const ct_data static_dtree[D_CODES] = {
+{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
+{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
+{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
+{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
+{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
+{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
+};
+
+const uch _dist_code[DIST_CODE_LEN] = {
+ 0,  1,  2,  3,  4,  4,  5,  5,  6,  6,  6,  6,  7,  7,  7,  7,  8,  8,  8,  8,
+ 8,  8,  8,  8,  9,  9,  9,  9,  9,  9,  9,  9, 10, 10, 10, 10, 10, 10, 10, 10,
+10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
+13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,  0,  0, 16, 17,
+18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
+};
+
+const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {
+ 0,  1,  2,  3,  4,  5,  6,  7,  8,  8,  9,  9, 10, 10, 11, 11, 12, 12, 12, 12,
+13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
+17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
+19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
+22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
+};
+
+local const int base_length[LENGTH_CODES] = {
+0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
+64, 80, 96, 112, 128, 160, 192, 224, 0
+};
+
+local const int base_dist[D_CODES] = {
+    0,     1,     2,     3,     4,     6,     8,    12,    16,    24,
+   32,    48,    64,    96,   128,   192,   256,   384,   512,   768,
+ 1024,  1536,  2048,  3072,  4096,  6144,  8192, 12288, 16384, 24576
+};
+

Added: vendor/Python/current/Modules/zlib/uncompr.c
===================================================================
--- vendor/Python/current/Modules/zlib/uncompr.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/zlib/uncompr.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,61 @@
+/* uncompr.c -- decompress a memory buffer
+ * Copyright (C) 1995-2003 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#define ZLIB_INTERNAL
+#include "zlib.h"
+
+/* ===========================================================================
+     Decompresses the source buffer into the destination buffer.  sourceLen is
+   the byte length of the source buffer. Upon entry, destLen is the total
+   size of the destination buffer, which must be large enough to hold the
+   entire uncompressed data. (The size of the uncompressed data must have
+   been saved previously by the compressor and transmitted to the decompressor
+   by some mechanism outside the scope of this compression library.)
+   Upon exit, destLen is the actual size of the compressed buffer.
+     This function can be used to decompress a whole file at once if the
+   input file is mmap'ed.
+
+     uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_BUF_ERROR if there was not enough room in the output
+   buffer, or Z_DATA_ERROR if the input data was corrupted.
+*/
+int ZEXPORT uncompress (dest, destLen, source, sourceLen)
+    Bytef *dest;
+    uLongf *destLen;
+    const Bytef *source;
+    uLong sourceLen;
+{
+    z_stream stream;
+    int err;
+
+    stream.next_in = (Bytef*)source;
+    stream.avail_in = (uInt)sourceLen;
+    /* Check for source > 64K on 16-bit machine: */
+    if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
+
+    stream.next_out = dest;
+    stream.avail_out = (uInt)*destLen;
+    if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
+
+    stream.zalloc = (alloc_func)0;
+    stream.zfree = (free_func)0;
+
+    err = inflateInit(&stream);
+    if (err != Z_OK) return err;
+
+    err = inflate(&stream, Z_FINISH);
+    if (err != Z_STREAM_END) {
+        inflateEnd(&stream);
+        if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0))
+            return Z_DATA_ERROR;
+        return err;
+    }
+    *destLen = stream.total_out;
+
+    err = inflateEnd(&stream);
+    return err;
+}

Added: vendor/Python/current/Modules/zlib/zconf.h
===================================================================
--- vendor/Python/current/Modules/zlib/zconf.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/zlib/zconf.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,332 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZCONF_H
+#define ZCONF_H
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ */
+#ifdef Z_PREFIX
+#  define deflateInit_          z_deflateInit_
+#  define deflate               z_deflate
+#  define deflateEnd            z_deflateEnd
+#  define inflateInit_          z_inflateInit_
+#  define inflate               z_inflate
+#  define inflateEnd            z_inflateEnd
+#  define deflateInit2_         z_deflateInit2_
+#  define deflateSetDictionary  z_deflateSetDictionary
+#  define deflateCopy           z_deflateCopy
+#  define deflateReset          z_deflateReset
+#  define deflateParams         z_deflateParams
+#  define deflateBound          z_deflateBound
+#  define deflatePrime          z_deflatePrime
+#  define inflateInit2_         z_inflateInit2_
+#  define inflateSetDictionary  z_inflateSetDictionary
+#  define inflateSync           z_inflateSync
+#  define inflateSyncPoint      z_inflateSyncPoint
+#  define inflateCopy           z_inflateCopy
+#  define inflateReset          z_inflateReset
+#  define inflateBack           z_inflateBack
+#  define inflateBackEnd        z_inflateBackEnd
+#  define compress              z_compress
+#  define compress2             z_compress2
+#  define compressBound         z_compressBound
+#  define uncompress            z_uncompress
+#  define adler32               z_adler32
+#  define crc32                 z_crc32
+#  define get_crc_table         z_get_crc_table
+#  define zError                z_zError
+
+#  define alloc_func            z_alloc_func
+#  define free_func             z_free_func
+#  define in_func               z_in_func
+#  define out_func              z_out_func
+#  define Byte                  z_Byte
+#  define uInt                  z_uInt
+#  define uLong                 z_uLong
+#  define Bytef                 z_Bytef
+#  define charf                 z_charf
+#  define intf                  z_intf
+#  define uIntf                 z_uIntf
+#  define uLongf                z_uLongf
+#  define voidpf                z_voidpf
+#  define voidp                 z_voidp
+#endif
+
+#if defined(__MSDOS__) && !defined(MSDOS)
+#  define MSDOS
+#endif
+#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
+#  define OS2
+#endif
+#if defined(_WINDOWS) && !defined(WINDOWS)
+#  define WINDOWS
+#endif
+#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
+#  ifndef WIN32
+#    define WIN32
+#  endif
+#endif
+#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
+#  if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
+#    ifndef SYS16BIT
+#      define SYS16BIT
+#    endif
+#  endif
+#endif
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#ifdef SYS16BIT
+#  define MAXSEG_64K
+#endif
+#ifdef MSDOS
+#  define UNALIGNED_OK
+#endif
+
+#ifdef __STDC_VERSION__
+#  ifndef STDC
+#    define STDC
+#  endif
+#  if __STDC_VERSION__ >= 199901L
+#    ifndef STDC99
+#      define STDC99
+#    endif
+#  endif
+#endif
+#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
+#  define STDC
+#endif
+
+#if defined(__OS400__) && !defined(STDC)    /* iSeries (formerly AS/400). */
+#  define STDC
+#endif
+
+#ifndef STDC
+#  ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+#    define const       /* note: need a more gentle solution here */
+#  endif
+#endif
+
+/* Some Mac compilers merge all .h files incorrectly: */
+#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
+#  define NO_DUMMY_DECL
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+#  ifdef MAXSEG_64K
+#    define MAX_MEM_LEVEL 8
+#  else
+#    define MAX_MEM_LEVEL 9
+#  endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+#  define MAX_WBITS   15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+            (1 << (windowBits+2)) +  (1 << (memLevel+9))
+ that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+     make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+   The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
+ for small objects.
+*/
+
+                        /* Type declarations */
+
+#ifndef OF /* function prototypes */
+#  ifdef STDC
+#    define OF(args)  args
+#  else
+#    define OF(args)  ()
+#  endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h.  If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#ifdef SYS16BIT
+#  if defined(M_I86SM) || defined(M_I86MM)
+     /* MSC small or medium model */
+#    define SMALL_MEDIUM
+#    ifdef _MSC_VER
+#      define FAR _far
+#    else
+#      define FAR far
+#    endif
+#  endif
+#  if (defined(__SMALL__) || defined(__MEDIUM__))
+     /* Turbo C small or medium model */
+#    define SMALL_MEDIUM
+#    ifdef __BORLANDC__
+#      define FAR _far
+#    else
+#      define FAR far
+#    endif
+#  endif
+#endif
+
+#if defined(WINDOWS) || defined(WIN32)
+   /* If building or using zlib as a DLL, define ZLIB_DLL.
+    * This is not mandatory, but it offers a little performance increase.
+    */
+#  ifdef ZLIB_DLL
+#    if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
+#      ifdef ZLIB_INTERNAL
+#        define ZEXTERN extern __declspec(dllexport)
+#      else
+#        define ZEXTERN extern __declspec(dllimport)
+#      endif
+#    endif
+#  endif  /* ZLIB_DLL */
+   /* If building or using zlib with the WINAPI/WINAPIV calling convention,
+    * define ZLIB_WINAPI.
+    * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
+    */
+#  ifdef ZLIB_WINAPI
+#    ifdef FAR
+#      undef FAR
+#    endif
+#    include <windows.h>
+     /* No need for _export, use ZLIB.DEF instead. */
+     /* For complete Windows compatibility, use WINAPI, not __stdcall. */
+#    define ZEXPORT WINAPI
+#    ifdef WIN32
+#      define ZEXPORTVA WINAPIV
+#    else
+#      define ZEXPORTVA FAR CDECL
+#    endif
+#  endif
+#endif
+
+#if defined (__BEOS__)
+#  ifdef ZLIB_DLL
+#    ifdef ZLIB_INTERNAL
+#      define ZEXPORT   __declspec(dllexport)
+#      define ZEXPORTVA __declspec(dllexport)
+#    else
+#      define ZEXPORT   __declspec(dllimport)
+#      define ZEXPORTVA __declspec(dllimport)
+#    endif
+#  endif
+#endif
+
+#ifndef ZEXTERN
+#  define ZEXTERN extern
+#endif
+#ifndef ZEXPORT
+#  define ZEXPORT
+#endif
+#ifndef ZEXPORTVA
+#  define ZEXPORTVA
+#endif
+
+#ifndef FAR
+#  define FAR
+#endif
+
+#if !defined(__MACTYPES__)
+typedef unsigned char  Byte;  /* 8 bits */
+#endif
+typedef unsigned int   uInt;  /* 16 bits or more */
+typedef unsigned long  uLong; /* 32 bits or more */
+
+#ifdef SMALL_MEDIUM
+   /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
+#  define Bytef Byte FAR
+#else
+   typedef Byte  FAR Bytef;
+#endif
+typedef char  FAR charf;
+typedef int   FAR intf;
+typedef uInt  FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+   typedef void const *voidpc;
+   typedef void FAR   *voidpf;
+   typedef void       *voidp;
+#else
+   typedef Byte const *voidpc;
+   typedef Byte FAR   *voidpf;
+   typedef Byte       *voidp;
+#endif
+
+#if 0           /* HAVE_UNISTD_H -- this line is updated by ./configure */
+#  include <sys/types.h> /* for off_t */
+#  include <unistd.h>    /* for SEEK_* and off_t */
+#  ifdef VMS
+#    include <unixio.h>   /* for off_t */
+#  endif
+#  define z_off_t off_t
+#endif
+#ifndef SEEK_SET
+#  define SEEK_SET        0       /* Seek from beginning of file.  */
+#  define SEEK_CUR        1       /* Seek from current position.  */
+#  define SEEK_END        2       /* Set file pointer to EOF plus "offset" */
+#endif
+#ifndef z_off_t
+#  define z_off_t long
+#endif
+
+#if defined(__OS400__)
+#  define NO_vsnprintf
+#endif
+
+#if defined(__MVS__)
+#  define NO_vsnprintf
+#  ifdef FAR
+#    undef FAR
+#  endif
+#endif
+
+/* MVS linker does not support external names larger than 8 bytes */
+#if defined(__MVS__)
+#   pragma map(deflateInit_,"DEIN")
+#   pragma map(deflateInit2_,"DEIN2")
+#   pragma map(deflateEnd,"DEEND")
+#   pragma map(deflateBound,"DEBND")
+#   pragma map(inflateInit_,"ININ")
+#   pragma map(inflateInit2_,"ININ2")
+#   pragma map(inflateEnd,"INEND")
+#   pragma map(inflateSync,"INSY")
+#   pragma map(inflateSetDictionary,"INSEDI")
+#   pragma map(compressBound,"CMBND")
+#   pragma map(inflate_table,"INTABL")
+#   pragma map(inflate_fast,"INFA")
+#   pragma map(inflate_copyright,"INCOPY")
+#endif
+
+#endif /* ZCONF_H */

Added: vendor/Python/current/Modules/zlib/zconf.in.h
===================================================================
--- vendor/Python/current/Modules/zlib/zconf.in.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/zlib/zconf.in.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,332 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZCONF_H
+#define ZCONF_H
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ */
+#ifdef Z_PREFIX
+#  define deflateInit_          z_deflateInit_
+#  define deflate               z_deflate
+#  define deflateEnd            z_deflateEnd
+#  define inflateInit_          z_inflateInit_
+#  define inflate               z_inflate
+#  define inflateEnd            z_inflateEnd
+#  define deflateInit2_         z_deflateInit2_
+#  define deflateSetDictionary  z_deflateSetDictionary
+#  define deflateCopy           z_deflateCopy
+#  define deflateReset          z_deflateReset
+#  define deflateParams         z_deflateParams
+#  define deflateBound          z_deflateBound
+#  define deflatePrime          z_deflatePrime
+#  define inflateInit2_         z_inflateInit2_
+#  define inflateSetDictionary  z_inflateSetDictionary
+#  define inflateSync           z_inflateSync
+#  define inflateSyncPoint      z_inflateSyncPoint
+#  define inflateCopy           z_inflateCopy
+#  define inflateReset          z_inflateReset
+#  define inflateBack           z_inflateBack
+#  define inflateBackEnd        z_inflateBackEnd
+#  define compress              z_compress
+#  define compress2             z_compress2
+#  define compressBound         z_compressBound
+#  define uncompress            z_uncompress
+#  define adler32               z_adler32
+#  define crc32                 z_crc32
+#  define get_crc_table         z_get_crc_table
+#  define zError                z_zError
+
+#  define alloc_func            z_alloc_func
+#  define free_func             z_free_func
+#  define in_func               z_in_func
+#  define out_func              z_out_func
+#  define Byte                  z_Byte
+#  define uInt                  z_uInt
+#  define uLong                 z_uLong
+#  define Bytef                 z_Bytef
+#  define charf                 z_charf
+#  define intf                  z_intf
+#  define uIntf                 z_uIntf
+#  define uLongf                z_uLongf
+#  define voidpf                z_voidpf
+#  define voidp                 z_voidp
+#endif
+
+#if defined(__MSDOS__) && !defined(MSDOS)
+#  define MSDOS
+#endif
+#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
+#  define OS2
+#endif
+#if defined(_WINDOWS) && !defined(WINDOWS)
+#  define WINDOWS
+#endif
+#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
+#  ifndef WIN32
+#    define WIN32
+#  endif
+#endif
+#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
+#  if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
+#    ifndef SYS16BIT
+#      define SYS16BIT
+#    endif
+#  endif
+#endif
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#ifdef SYS16BIT
+#  define MAXSEG_64K
+#endif
+#ifdef MSDOS
+#  define UNALIGNED_OK
+#endif
+
+#ifdef __STDC_VERSION__
+#  ifndef STDC
+#    define STDC
+#  endif
+#  if __STDC_VERSION__ >= 199901L
+#    ifndef STDC99
+#      define STDC99
+#    endif
+#  endif
+#endif
+#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
+#  define STDC
+#endif
+
+#if defined(__OS400__) && !defined(STDC)    /* iSeries (formerly AS/400). */
+#  define STDC
+#endif
+
+#ifndef STDC
+#  ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+#    define const       /* note: need a more gentle solution here */
+#  endif
+#endif
+
+/* Some Mac compilers merge all .h files incorrectly: */
+#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
+#  define NO_DUMMY_DECL
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+#  ifdef MAXSEG_64K
+#    define MAX_MEM_LEVEL 8
+#  else
+#    define MAX_MEM_LEVEL 9
+#  endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+#  define MAX_WBITS   15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+            (1 << (windowBits+2)) +  (1 << (memLevel+9))
+ that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+     make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+   The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
+ for small objects.
+*/
+
+                        /* Type declarations */
+
+#ifndef OF /* function prototypes */
+#  ifdef STDC
+#    define OF(args)  args
+#  else
+#    define OF(args)  ()
+#  endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h.  If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#ifdef SYS16BIT
+#  if defined(M_I86SM) || defined(M_I86MM)
+     /* MSC small or medium model */
+#    define SMALL_MEDIUM
+#    ifdef _MSC_VER
+#      define FAR _far
+#    else
+#      define FAR far
+#    endif
+#  endif
+#  if (defined(__SMALL__) || defined(__MEDIUM__))
+     /* Turbo C small or medium model */
+#    define SMALL_MEDIUM
+#    ifdef __BORLANDC__
+#      define FAR _far
+#    else
+#      define FAR far
+#    endif
+#  endif
+#endif
+
+#if defined(WINDOWS) || defined(WIN32)
+   /* If building or using zlib as a DLL, define ZLIB_DLL.
+    * This is not mandatory, but it offers a little performance increase.
+    */
+#  ifdef ZLIB_DLL
+#    if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
+#      ifdef ZLIB_INTERNAL
+#        define ZEXTERN extern __declspec(dllexport)
+#      else
+#        define ZEXTERN extern __declspec(dllimport)
+#      endif
+#    endif
+#  endif  /* ZLIB_DLL */
+   /* If building or using zlib with the WINAPI/WINAPIV calling convention,
+    * define ZLIB_WINAPI.
+    * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
+    */
+#  ifdef ZLIB_WINAPI
+#    ifdef FAR
+#      undef FAR
+#    endif
+#    include <windows.h>
+     /* No need for _export, use ZLIB.DEF instead. */
+     /* For complete Windows compatibility, use WINAPI, not __stdcall. */
+#    define ZEXPORT WINAPI
+#    ifdef WIN32
+#      define ZEXPORTVA WINAPIV
+#    else
+#      define ZEXPORTVA FAR CDECL
+#    endif
+#  endif
+#endif
+
+#if defined (__BEOS__)
+#  ifdef ZLIB_DLL
+#    ifdef ZLIB_INTERNAL
+#      define ZEXPORT   __declspec(dllexport)
+#      define ZEXPORTVA __declspec(dllexport)
+#    else
+#      define ZEXPORT   __declspec(dllimport)
+#      define ZEXPORTVA __declspec(dllimport)
+#    endif
+#  endif
+#endif
+
+#ifndef ZEXTERN
+#  define ZEXTERN extern
+#endif
+#ifndef ZEXPORT
+#  define ZEXPORT
+#endif
+#ifndef ZEXPORTVA
+#  define ZEXPORTVA
+#endif
+
+#ifndef FAR
+#  define FAR
+#endif
+
+#if !defined(__MACTYPES__)
+typedef unsigned char  Byte;  /* 8 bits */
+#endif
+typedef unsigned int   uInt;  /* 16 bits or more */
+typedef unsigned long  uLong; /* 32 bits or more */
+
+#ifdef SMALL_MEDIUM
+   /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
+#  define Bytef Byte FAR
+#else
+   typedef Byte  FAR Bytef;
+#endif
+typedef char  FAR charf;
+typedef int   FAR intf;
+typedef uInt  FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+   typedef void const *voidpc;
+   typedef void FAR   *voidpf;
+   typedef void       *voidp;
+#else
+   typedef Byte const *voidpc;
+   typedef Byte FAR   *voidpf;
+   typedef Byte       *voidp;
+#endif
+
+#if 0           /* HAVE_UNISTD_H -- this line is updated by ./configure */
+#  include <sys/types.h> /* for off_t */
+#  include <unistd.h>    /* for SEEK_* and off_t */
+#  ifdef VMS
+#    include <unixio.h>   /* for off_t */
+#  endif
+#  define z_off_t off_t
+#endif
+#ifndef SEEK_SET
+#  define SEEK_SET        0       /* Seek from beginning of file.  */
+#  define SEEK_CUR        1       /* Seek from current position.  */
+#  define SEEK_END        2       /* Set file pointer to EOF plus "offset" */
+#endif
+#ifndef z_off_t
+#  define z_off_t long
+#endif
+
+#if defined(__OS400__)
+#  define NO_vsnprintf
+#endif
+
+#if defined(__MVS__)
+#  define NO_vsnprintf
+#  ifdef FAR
+#    undef FAR
+#  endif
+#endif
+
+/* MVS linker does not support external names larger than 8 bytes */
+#if defined(__MVS__)
+#   pragma map(deflateInit_,"DEIN")
+#   pragma map(deflateInit2_,"DEIN2")
+#   pragma map(deflateEnd,"DEEND")
+#   pragma map(deflateBound,"DEBND")
+#   pragma map(inflateInit_,"ININ")
+#   pragma map(inflateInit2_,"ININ2")
+#   pragma map(inflateEnd,"INEND")
+#   pragma map(inflateSync,"INSY")
+#   pragma map(inflateSetDictionary,"INSEDI")
+#   pragma map(compressBound,"CMBND")
+#   pragma map(inflate_table,"INTABL")
+#   pragma map(inflate_fast,"INFA")
+#   pragma map(inflate_copyright,"INCOPY")
+#endif
+
+#endif /* ZCONF_H */

Added: vendor/Python/current/Modules/zlib/zlib.3
===================================================================
--- vendor/Python/current/Modules/zlib/zlib.3	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/zlib/zlib.3	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,159 @@
+.TH ZLIB 3 "18 July 2005"
+.SH NAME
+zlib \- compression/decompression library
+.SH SYNOPSIS
+[see
+.I zlib.h
+for full description]
+.SH DESCRIPTION
+The
+.I zlib
+library is a general purpose data compression library.
+The code is thread safe.
+It provides in-memory compression and decompression functions,
+including integrity checks of the uncompressed data.
+This version of the library supports only one compression method (deflation)
+but other algorithms will be added later
+and will have the same stream interface.
+.LP
+Compression can be done in a single step if the buffers are large enough
+(for example if an input file is mmap'ed),
+or can be done by repeated calls of the compression function.
+In the latter case,
+the application must provide more input and/or consume the output
+(providing more output space) before each call.
+.LP
+The library also supports reading and writing files in
+.IR gzip (1)
+(.gz) format
+with an interface similar to that of stdio.
+.LP
+The library does not install any signal handler.
+The decoder checks the consistency of the compressed data,
+so the library should never crash even in case of corrupted input.
+.LP
+All functions of the compression library are documented in the file
+.IR zlib.h .
+The distribution source includes examples of use of the library
+in the files
+.I example.c
+and
+.IR minigzip.c .
+.LP
+Changes to this version are documented in the file
+.I ChangeLog
+that accompanies the source,
+and are concerned primarily with bug fixes and portability enhancements.
+.LP
+A Java implementation of
+.I zlib
+is available in the Java Development Kit 1.1:
+.IP
+http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html
+.LP
+A Perl interface to
+.IR zlib ,
+written by Paul Marquess (pmqs at cpan.org),
+is available at CPAN (Comprehensive Perl Archive Network) sites,
+including:
+.IP
+http://www.cpan.org/modules/by-module/Compress/
+.LP
+A Python interface to
+.IR zlib ,
+written by A.M. Kuchling (amk at magnet.com),
+is available in Python 1.5 and later versions:
+.IP
+http://www.python.org/doc/lib/module-zlib.html
+.LP
+A
+.I zlib
+binding for
+.IR tcl (1),
+written by Andreas Kupries (a.kupries at westend.com),
+is availlable at:
+.IP
+http://www.westend.com/~kupries/doc/trf/man/man.html
+.LP
+An experimental package to read and write files in .zip format,
+written on top of
+.I zlib
+by Gilles Vollant (info at winimage.com),
+is available at:
+.IP
+http://www.winimage.com/zLibDll/unzip.html
+and also in the
+.I contrib/minizip
+directory of the main
+.I zlib
+web site.
+.SH "SEE ALSO"
+The
+.I zlib
+web site can be found at either of these locations:
+.IP
+http://www.zlib.org
+.br
+http://www.gzip.org/zlib/
+.LP
+The data format used by the zlib library is described by RFC
+(Request for Comments) 1950 to 1952 in the files:
+.IP
+http://www.ietf.org/rfc/rfc1950.txt (concerning zlib format)
+.br
+http://www.ietf.org/rfc/rfc1951.txt (concerning deflate format)
+.br
+http://www.ietf.org/rfc/rfc1952.txt (concerning gzip format)
+.LP
+These documents are also available in other formats from:
+.IP
+ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html
+.LP
+Mark Nelson (markn at ieee.org) wrote an article about
+.I zlib
+for the Jan. 1997 issue of  Dr. Dobb's Journal;
+a copy of the article is available at:
+.IP
+http://dogma.net/markn/articles/zlibtool/zlibtool.htm
+.SH "REPORTING PROBLEMS"
+Before reporting a problem,
+please check the
+.I zlib
+web site to verify that you have the latest version of
+.IR zlib ;
+otherwise,
+obtain the latest version and see if the problem still exists.
+Please read the
+.I zlib
+FAQ at:
+.IP
+http://www.gzip.org/zlib/zlib_faq.html
+.LP
+before asking for help.
+Send questions and/or comments to zlib at gzip.org,
+or (for the Windows DLL version) to Gilles Vollant (info at winimage.com).
+.SH AUTHORS
+Version 1.2.3
+Copyright (C) 1995-2005 Jean-loup Gailly (jloup at gzip.org)
+and Mark Adler (madler at alumni.caltech.edu).
+.LP
+This software is provided "as-is,"
+without any express or implied warranty.
+In no event will the authors be held liable for any damages
+arising from the use of this software.
+See the distribution directory with respect to requirements
+governing redistribution.
+The deflate format used by
+.I zlib
+was defined by Phil Katz.
+The deflate and
+.I zlib
+specifications were written by L. Peter Deutsch.
+Thanks to all the people who reported problems and suggested various
+improvements in
+.IR zlib ;
+who are too numerous to cite here.
+.LP
+UNIX manual page by R. P. C. Rodgers,
+U.S. National Library of Medicine (rodgers at nlm.nih.gov).
+.\" end of man page

Added: vendor/Python/current/Modules/zlib/zlib.h
===================================================================
--- vendor/Python/current/Modules/zlib/zlib.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/zlib/zlib.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1357 @@
+/* zlib.h -- interface of the 'zlib' general purpose compression library
+  version 1.2.3, July 18th, 2005
+
+  Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  Jean-loup Gailly        Mark Adler
+  jloup at gzip.org          madler at alumni.caltech.edu
+
+
+  The data format used by the zlib library is described by RFCs (Request for
+  Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt
+  (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
+*/
+
+#ifndef ZLIB_H
+#define ZLIB_H
+
+#include "zconf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ZLIB_VERSION "1.2.3"
+#define ZLIB_VERNUM 0x1230
+
+/*
+     The 'zlib' compression library provides in-memory compression and
+  decompression functions, including integrity checks of the uncompressed
+  data.  This version of the library supports only one compression method
+  (deflation) but other algorithms will be added later and will have the same
+  stream interface.
+
+     Compression can be done in a single step if the buffers are large
+  enough (for example if an input file is mmap'ed), or can be done by
+  repeated calls of the compression function.  In the latter case, the
+  application must provide more input and/or consume the output
+  (providing more output space) before each call.
+
+     The compressed data format used by default by the in-memory functions is
+  the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped
+  around a deflate stream, which is itself documented in RFC 1951.
+
+     The library also supports reading and writing files in gzip (.gz) format
+  with an interface similar to that of stdio using the functions that start
+  with "gz".  The gzip format is different from the zlib format.  gzip is a
+  gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.
+
+     This library can optionally read and write gzip streams in memory as well.
+
+     The zlib format was designed to be compact and fast for use in memory
+  and on communications channels.  The gzip format was designed for single-
+  file compression on file systems, has a larger header than zlib to maintain
+  directory information, and uses a different, slower check method than zlib.
+
+     The library does not install any signal handler. The decoder checks
+  the consistency of the compressed data, so the library should never
+  crash even in case of corrupted input.
+*/
+
+typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
+typedef void   (*free_func)  OF((voidpf opaque, voidpf address));
+
+struct internal_state;
+
+typedef struct z_stream_s {
+    Bytef    *next_in;  /* next input byte */
+    uInt     avail_in;  /* number of bytes available at next_in */
+    uLong    total_in;  /* total nb of input bytes read so far */
+
+    Bytef    *next_out; /* next output byte should be put there */
+    uInt     avail_out; /* remaining free space at next_out */
+    uLong    total_out; /* total nb of bytes output so far */
+
+    char     *msg;      /* last error message, NULL if no error */
+    struct internal_state FAR *state; /* not visible by applications */
+
+    alloc_func zalloc;  /* used to allocate the internal state */
+    free_func  zfree;   /* used to free the internal state */
+    voidpf     opaque;  /* private data object passed to zalloc and zfree */
+
+    int     data_type;  /* best guess about the data type: binary or text */
+    uLong   adler;      /* adler32 value of the uncompressed data */
+    uLong   reserved;   /* reserved for future use */
+} z_stream;
+
+typedef z_stream FAR *z_streamp;
+
+/*
+     gzip header information passed to and from zlib routines.  See RFC 1952
+  for more details on the meanings of these fields.
+*/
+typedef struct gz_header_s {
+    int     text;       /* true if compressed data believed to be text */
+    uLong   time;       /* modification time */
+    int     xflags;     /* extra flags (not used when writing a gzip file) */
+    int     os;         /* operating system */
+    Bytef   *extra;     /* pointer to extra field or Z_NULL if none */
+    uInt    extra_len;  /* extra field length (valid if extra != Z_NULL) */
+    uInt    extra_max;  /* space at extra (only when reading header) */
+    Bytef   *name;      /* pointer to zero-terminated file name or Z_NULL */
+    uInt    name_max;   /* space at name (only when reading header) */
+    Bytef   *comment;   /* pointer to zero-terminated comment or Z_NULL */
+    uInt    comm_max;   /* space at comment (only when reading header) */
+    int     hcrc;       /* true if there was or will be a header crc */
+    int     done;       /* true when done reading gzip header (not used
+                           when writing a gzip file) */
+} gz_header;
+
+typedef gz_header FAR *gz_headerp;
+
+/*
+   The application must update next_in and avail_in when avail_in has
+   dropped to zero. It must update next_out and avail_out when avail_out
+   has dropped to zero. The application must initialize zalloc, zfree and
+   opaque before calling the init function. All other fields are set by the
+   compression library and must not be updated by the application.
+
+   The opaque value provided by the application will be passed as the first
+   parameter for calls of zalloc and zfree. This can be useful for custom
+   memory management. The compression library attaches no meaning to the
+   opaque value.
+
+   zalloc must return Z_NULL if there is not enough memory for the object.
+   If zlib is used in a multi-threaded application, zalloc and zfree must be
+   thread safe.
+
+   On 16-bit systems, the functions zalloc and zfree must be able to allocate
+   exactly 65536 bytes, but will not be required to allocate more than this
+   if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
+   pointers returned by zalloc for objects of exactly 65536 bytes *must*
+   have their offset normalized to zero. The default allocation function
+   provided by this library ensures this (see zutil.c). To reduce memory
+   requirements and avoid any allocation of 64K objects, at the expense of
+   compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
+
+   The fields total_in and total_out can be used for statistics or
+   progress reports. After compression, total_in holds the total size of
+   the uncompressed data and may be saved for use in the decompressor
+   (particularly if the decompressor wants to decompress everything in
+   a single step).
+*/
+
+                        /* constants */
+
+#define Z_NO_FLUSH      0
+#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
+#define Z_SYNC_FLUSH    2
+#define Z_FULL_FLUSH    3
+#define Z_FINISH        4
+#define Z_BLOCK         5
+/* Allowed flush values; see deflate() and inflate() below for details */
+
+#define Z_OK            0
+#define Z_STREAM_END    1
+#define Z_NEED_DICT     2
+#define Z_ERRNO        (-1)
+#define Z_STREAM_ERROR (-2)
+#define Z_DATA_ERROR   (-3)
+#define Z_MEM_ERROR    (-4)
+#define Z_BUF_ERROR    (-5)
+#define Z_VERSION_ERROR (-6)
+/* Return codes for the compression/decompression functions. Negative
+ * values are errors, positive values are used for special but normal events.
+ */
+
+#define Z_NO_COMPRESSION         0
+#define Z_BEST_SPEED             1
+#define Z_BEST_COMPRESSION       9
+#define Z_DEFAULT_COMPRESSION  (-1)
+/* compression levels */
+
+#define Z_FILTERED            1
+#define Z_HUFFMAN_ONLY        2
+#define Z_RLE                 3
+#define Z_FIXED               4
+#define Z_DEFAULT_STRATEGY    0
+/* compression strategy; see deflateInit2() below for details */
+
+#define Z_BINARY   0
+#define Z_TEXT     1
+#define Z_ASCII    Z_TEXT   /* for compatibility with 1.2.2 and earlier */
+#define Z_UNKNOWN  2
+/* Possible values of the data_type field (though see inflate()) */
+
+#define Z_DEFLATED   8
+/* The deflate compression method (the only one supported in this version) */
+
+#define Z_NULL  0  /* for initializing zalloc, zfree, opaque */
+
+#define zlib_version zlibVersion()
+/* for compatibility with versions < 1.0.2 */
+
+                        /* basic functions */
+
+ZEXTERN const char * ZEXPORT zlibVersion OF((void));
+/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
+   If the first character differs, the library code actually used is
+   not compatible with the zlib.h header file used by the application.
+   This check is automatically made by deflateInit and inflateInit.
+ */
+
+/*
+ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
+
+     Initializes the internal stream state for compression. The fields
+   zalloc, zfree and opaque must be initialized before by the caller.
+   If zalloc and zfree are set to Z_NULL, deflateInit updates them to
+   use default allocation functions.
+
+     The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
+   1 gives best speed, 9 gives best compression, 0 gives no compression at
+   all (the input data is simply copied a block at a time).
+   Z_DEFAULT_COMPRESSION requests a default compromise between speed and
+   compression (currently equivalent to level 6).
+
+     deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_STREAM_ERROR if level is not a valid compression level,
+   Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
+   with the version assumed by the caller (ZLIB_VERSION).
+   msg is set to null if there is no error message.  deflateInit does not
+   perform any compression: this will be done by deflate().
+*/
+
+
+ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
+/*
+    deflate compresses as much data as possible, and stops when the input
+  buffer becomes empty or the output buffer becomes full. It may introduce some
+  output latency (reading input without producing any output) except when
+  forced to flush.
+
+    The detailed semantics are as follows. deflate performs one or both of the
+  following actions:
+
+  - Compress more input starting at next_in and update next_in and avail_in
+    accordingly. If not all input can be processed (because there is not
+    enough room in the output buffer), next_in and avail_in are updated and
+    processing will resume at this point for the next call of deflate().
+
+  - Provide more output starting at next_out and update next_out and avail_out
+    accordingly. This action is forced if the parameter flush is non zero.
+    Forcing flush frequently degrades the compression ratio, so this parameter
+    should be set only when necessary (in interactive applications).
+    Some output may be provided even if flush is not set.
+
+  Before the call of deflate(), the application should ensure that at least
+  one of the actions is possible, by providing more input and/or consuming
+  more output, and updating avail_in or avail_out accordingly; avail_out
+  should never be zero before the call. The application can consume the
+  compressed output when it wants, for example when the output buffer is full
+  (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
+  and with zero avail_out, it must be called again after making room in the
+  output buffer because there might be more output pending.
+
+    Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to
+  decide how much data to accumualte before producing output, in order to
+  maximize compression.
+
+    If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
+  flushed to the output buffer and the output is aligned on a byte boundary, so
+  that the decompressor can get all input data available so far. (In particular
+  avail_in is zero after the call if enough output space has been provided
+  before the call.)  Flushing may degrade compression for some compression
+  algorithms and so it should be used only when necessary.
+
+    If flush is set to Z_FULL_FLUSH, all output is flushed as with
+  Z_SYNC_FLUSH, and the compression state is reset so that decompression can
+  restart from this point if previous compressed data has been damaged or if
+  random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
+  compression.
+
+    If deflate returns with avail_out == 0, this function must be called again
+  with the same value of the flush parameter and more output space (updated
+  avail_out), until the flush is complete (deflate returns with non-zero
+  avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
+  avail_out is greater than six to avoid repeated flush markers due to
+  avail_out == 0 on return.
+
+    If the parameter flush is set to Z_FINISH, pending input is processed,
+  pending output is flushed and deflate returns with Z_STREAM_END if there
+  was enough output space; if deflate returns with Z_OK, this function must be
+  called again with Z_FINISH and more output space (updated avail_out) but no
+  more input data, until it returns with Z_STREAM_END or an error. After
+  deflate has returned Z_STREAM_END, the only possible operations on the
+  stream are deflateReset or deflateEnd.
+
+    Z_FINISH can be used immediately after deflateInit if all the compression
+  is to be done in a single step. In this case, avail_out must be at least
+  the value returned by deflateBound (see below). If deflate does not return
+  Z_STREAM_END, then it must be called again as described above.
+
+    deflate() sets strm->adler to the adler32 checksum of all input read
+  so far (that is, total_in bytes).
+
+    deflate() may update strm->data_type if it can make a good guess about
+  the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered
+  binary. This field is only for information purposes and does not affect
+  the compression algorithm in any manner.
+
+    deflate() returns Z_OK if some progress has been made (more input
+  processed or more output produced), Z_STREAM_END if all input has been
+  consumed and all output has been produced (only when flush is set to
+  Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
+  if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
+  (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not
+  fatal, and deflate() can be called again with more input and more output
+  space to continue compressing.
+*/
+
+
+ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
+/*
+     All dynamically allocated data structures for this stream are freed.
+   This function discards any unprocessed input and does not flush any
+   pending output.
+
+     deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
+   stream state was inconsistent, Z_DATA_ERROR if the stream was freed
+   prematurely (some input or output was discarded). In the error case,
+   msg may be set but then points to a static string (which must not be
+   deallocated).
+*/
+
+
+/*
+ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
+
+     Initializes the internal stream state for decompression. The fields
+   next_in, avail_in, zalloc, zfree and opaque must be initialized before by
+   the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
+   value depends on the compression method), inflateInit determines the
+   compression method from the zlib header and allocates all data structures
+   accordingly; otherwise the allocation will be deferred to the first call of
+   inflate.  If zalloc and zfree are set to Z_NULL, inflateInit updates them to
+   use default allocation functions.
+
+     inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
+   version assumed by the caller.  msg is set to null if there is no error
+   message. inflateInit does not perform any decompression apart from reading
+   the zlib header if present: this will be done by inflate().  (So next_in and
+   avail_in may be modified, but next_out and avail_out are unchanged.)
+*/
+
+
+ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
+/*
+    inflate decompresses as much data as possible, and stops when the input
+  buffer becomes empty or the output buffer becomes full. It may introduce
+  some output latency (reading input without producing any output) except when
+  forced to flush.
+
+  The detailed semantics are as follows. inflate performs one or both of the
+  following actions:
+
+  - Decompress more input starting at next_in and update next_in and avail_in
+    accordingly. If not all input can be processed (because there is not
+    enough room in the output buffer), next_in is updated and processing
+    will resume at this point for the next call of inflate().
+
+  - Provide more output starting at next_out and update next_out and avail_out
+    accordingly.  inflate() provides as much output as possible, until there
+    is no more input data or no more space in the output buffer (see below
+    about the flush parameter).
+
+  Before the call of inflate(), the application should ensure that at least
+  one of the actions is possible, by providing more input and/or consuming
+  more output, and updating the next_* and avail_* values accordingly.
+  The application can consume the uncompressed output when it wants, for
+  example when the output buffer is full (avail_out == 0), or after each
+  call of inflate(). If inflate returns Z_OK and with zero avail_out, it
+  must be called again after making room in the output buffer because there
+  might be more output pending.
+
+    The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH,
+  Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much
+  output as possible to the output buffer. Z_BLOCK requests that inflate() stop
+  if and when it gets to the next deflate block boundary. When decoding the
+  zlib or gzip format, this will cause inflate() to return immediately after
+  the header and before the first block. When doing a raw inflate, inflate()
+  will go ahead and process the first block, and will return when it gets to
+  the end of that block, or when it runs out of data.
+
+    The Z_BLOCK option assists in appending to or combining deflate streams.
+  Also to assist in this, on return inflate() will set strm->data_type to the
+  number of unused bits in the last byte taken from strm->next_in, plus 64
+  if inflate() is currently decoding the last block in the deflate stream,
+  plus 128 if inflate() returned immediately after decoding an end-of-block
+  code or decoding the complete header up to just before the first byte of the
+  deflate stream. The end-of-block will not be indicated until all of the
+  uncompressed data from that block has been written to strm->next_out.  The
+  number of unused bits may in general be greater than seven, except when
+  bit 7 of data_type is set, in which case the number of unused bits will be
+  less than eight.
+
+    inflate() should normally be called until it returns Z_STREAM_END or an
+  error. However if all decompression is to be performed in a single step
+  (a single call of inflate), the parameter flush should be set to
+  Z_FINISH. In this case all pending input is processed and all pending
+  output is flushed; avail_out must be large enough to hold all the
+  uncompressed data. (The size of the uncompressed data may have been saved
+  by the compressor for this purpose.) The next operation on this stream must
+  be inflateEnd to deallocate the decompression state. The use of Z_FINISH
+  is never required, but can be used to inform inflate that a faster approach
+  may be used for the single inflate() call.
+
+     In this implementation, inflate() always flushes as much output as
+  possible to the output buffer, and always uses the faster approach on the
+  first call. So the only effect of the flush parameter in this implementation
+  is on the return value of inflate(), as noted below, or when it returns early
+  because Z_BLOCK is used.
+
+     If a preset dictionary is needed after this call (see inflateSetDictionary
+  below), inflate sets strm->adler to the adler32 checksum of the dictionary
+  chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
+  strm->adler to the adler32 checksum of all output produced so far (that is,
+  total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
+  below. At the end of the stream, inflate() checks that its computed adler32
+  checksum is equal to that saved by the compressor and returns Z_STREAM_END
+  only if the checksum is correct.
+
+    inflate() will decompress and check either zlib-wrapped or gzip-wrapped
+  deflate data.  The header type is detected automatically.  Any information
+  contained in the gzip header is not retained, so applications that need that
+  information should instead use raw inflate, see inflateInit2() below, or
+  inflateBack() and perform their own processing of the gzip header and
+  trailer.
+
+    inflate() returns Z_OK if some progress has been made (more input processed
+  or more output produced), Z_STREAM_END if the end of the compressed data has
+  been reached and all uncompressed output has been produced, Z_NEED_DICT if a
+  preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
+  corrupted (input stream not conforming to the zlib format or incorrect check
+  value), Z_STREAM_ERROR if the stream structure was inconsistent (for example
+  if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory,
+  Z_BUF_ERROR if no progress is possible or if there was not enough room in the
+  output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and
+  inflate() can be called again with more input and more output space to
+  continue decompressing. If Z_DATA_ERROR is returned, the application may then
+  call inflateSync() to look for a good compression block if a partial recovery
+  of the data is desired.
+*/
+
+
+ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
+/*
+     All dynamically allocated data structures for this stream are freed.
+   This function discards any unprocessed input and does not flush any
+   pending output.
+
+     inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
+   was inconsistent. In the error case, msg may be set but then points to a
+   static string (which must not be deallocated).
+*/
+
+                        /* Advanced functions */
+
+/*
+    The following functions are needed only in some special applications.
+*/
+
+/*
+ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
+                                     int  level,
+                                     int  method,
+                                     int  windowBits,
+                                     int  memLevel,
+                                     int  strategy));
+
+     This is another version of deflateInit with more compression options. The
+   fields next_in, zalloc, zfree and opaque must be initialized before by
+   the caller.
+
+     The method parameter is the compression method. It must be Z_DEFLATED in
+   this version of the library.
+
+     The windowBits parameter is the base two logarithm of the window size
+   (the size of the history buffer). It should be in the range 8..15 for this
+   version of the library. Larger values of this parameter result in better
+   compression at the expense of memory usage. The default value is 15 if
+   deflateInit is used instead.
+
+     windowBits can also be -8..-15 for raw deflate. In this case, -windowBits
+   determines the window size. deflate() will then generate raw deflate data
+   with no zlib header or trailer, and will not compute an adler32 check value.
+
+     windowBits can also be greater than 15 for optional gzip encoding. Add
+   16 to windowBits to write a simple gzip header and trailer around the
+   compressed data instead of a zlib wrapper. The gzip header will have no
+   file name, no extra data, no comment, no modification time (set to zero),
+   no header crc, and the operating system will be set to 255 (unknown).  If a
+   gzip stream is being written, strm->adler is a crc32 instead of an adler32.
+
+     The memLevel parameter specifies how much memory should be allocated
+   for the internal compression state. memLevel=1 uses minimum memory but
+   is slow and reduces compression ratio; memLevel=9 uses maximum memory
+   for optimal speed. The default value is 8. See zconf.h for total memory
+   usage as a function of windowBits and memLevel.
+
+     The strategy parameter is used to tune the compression algorithm. Use the
+   value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
+   filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no
+   string match), or Z_RLE to limit match distances to one (run-length
+   encoding). Filtered data consists mostly of small values with a somewhat
+   random distribution. In this case, the compression algorithm is tuned to
+   compress them better. The effect of Z_FILTERED is to force more Huffman
+   coding and less string matching; it is somewhat intermediate between
+   Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as
+   Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy
+   parameter only affects the compression ratio but not the correctness of the
+   compressed output even if it is not set appropriately.  Z_FIXED prevents the
+   use of dynamic Huffman codes, allowing for a simpler decoder for special
+   applications.
+
+      deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
+   method). msg is set to null if there is no error message.  deflateInit2 does
+   not perform any compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
+                                             const Bytef *dictionary,
+                                             uInt  dictLength));
+/*
+     Initializes the compression dictionary from the given byte sequence
+   without producing any compressed output. This function must be called
+   immediately after deflateInit, deflateInit2 or deflateReset, before any
+   call of deflate. The compressor and decompressor must use exactly the same
+   dictionary (see inflateSetDictionary).
+
+     The dictionary should consist of strings (byte sequences) that are likely
+   to be encountered later in the data to be compressed, with the most commonly
+   used strings preferably put towards the end of the dictionary. Using a
+   dictionary is most useful when the data to be compressed is short and can be
+   predicted with good accuracy; the data can then be compressed better than
+   with the default empty dictionary.
+
+     Depending on the size of the compression data structures selected by
+   deflateInit or deflateInit2, a part of the dictionary may in effect be
+   discarded, for example if the dictionary is larger than the window size in
+   deflate or deflate2. Thus the strings most likely to be useful should be
+   put at the end of the dictionary, not at the front. In addition, the
+   current implementation of deflate will use at most the window size minus
+   262 bytes of the provided dictionary.
+
+     Upon return of this function, strm->adler is set to the adler32 value
+   of the dictionary; the decompressor may later use this value to determine
+   which dictionary has been used by the compressor. (The adler32 value
+   applies to the whole dictionary even if only a subset of the dictionary is
+   actually used by the compressor.) If a raw deflate was requested, then the
+   adler32 value is not computed and strm->adler is not set.
+
+     deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
+   parameter is invalid (such as NULL dictionary) or the stream state is
+   inconsistent (for example if deflate has already been called for this stream
+   or if the compression method is bsort). deflateSetDictionary does not
+   perform any compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
+                                    z_streamp source));
+/*
+     Sets the destination stream as a complete copy of the source stream.
+
+     This function can be useful when several compression strategies will be
+   tried, for example when there are several ways of pre-processing the input
+   data with a filter. The streams that will be discarded should then be freed
+   by calling deflateEnd.  Note that deflateCopy duplicates the internal
+   compression state which can be quite large, so this strategy is slow and
+   can consume lots of memory.
+
+     deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+   (such as zalloc being NULL). msg is left unchanged in both source and
+   destination.
+*/
+
+ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
+/*
+     This function is equivalent to deflateEnd followed by deflateInit,
+   but does not free and reallocate all the internal compression state.
+   The stream will keep the same compression level and any other attributes
+   that may have been set by deflateInit2.
+
+      deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent (such as zalloc or state being NULL).
+*/
+
+ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
+                                      int level,
+                                      int strategy));
+/*
+     Dynamically update the compression level and compression strategy.  The
+   interpretation of level and strategy is as in deflateInit2.  This can be
+   used to switch between compression and straight copy of the input data, or
+   to switch to a different kind of input data requiring a different
+   strategy. If the compression level is changed, the input available so far
+   is compressed with the old level (and may be flushed); the new level will
+   take effect only at the next call of deflate().
+
+     Before the call of deflateParams, the stream state must be set as for
+   a call of deflate(), since the currently available input may have to
+   be compressed and flushed. In particular, strm->avail_out must be non-zero.
+
+     deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
+   stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
+   if strm->avail_out was zero.
+*/
+
+ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm,
+                                    int good_length,
+                                    int max_lazy,
+                                    int nice_length,
+                                    int max_chain));
+/*
+     Fine tune deflate's internal compression parameters.  This should only be
+   used by someone who understands the algorithm used by zlib's deflate for
+   searching for the best matching string, and even then only by the most
+   fanatic optimizer trying to squeeze out the last compressed bit for their
+   specific input data.  Read the deflate.c source code for the meaning of the
+   max_lazy, good_length, nice_length, and max_chain parameters.
+
+     deflateTune() can be called after deflateInit() or deflateInit2(), and
+   returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream.
+ */
+
+ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
+                                       uLong sourceLen));
+/*
+     deflateBound() returns an upper bound on the compressed size after
+   deflation of sourceLen bytes.  It must be called after deflateInit()
+   or deflateInit2().  This would be used to allocate an output buffer
+   for deflation in a single pass, and so would be called before deflate().
+*/
+
+ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
+                                     int bits,
+                                     int value));
+/*
+     deflatePrime() inserts bits in the deflate output stream.  The intent
+  is that this function is used to start off the deflate output with the
+  bits leftover from a previous deflate stream when appending to it.  As such,
+  this function can only be used for raw deflate, and must be used before the
+  first deflate() call after a deflateInit2() or deflateReset().  bits must be
+  less than or equal to 16, and that many of the least significant bits of
+  value will be inserted in the output.
+
+      deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent.
+*/
+
+ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
+                                         gz_headerp head));
+/*
+      deflateSetHeader() provides gzip header information for when a gzip
+   stream is requested by deflateInit2().  deflateSetHeader() may be called
+   after deflateInit2() or deflateReset() and before the first call of
+   deflate().  The text, time, os, extra field, name, and comment information
+   in the provided gz_header structure are written to the gzip header (xflag is
+   ignored -- the extra flags are set according to the compression level).  The
+   caller must assure that, if not Z_NULL, name and comment are terminated with
+   a zero byte, and that if extra is not Z_NULL, that extra_len bytes are
+   available there.  If hcrc is true, a gzip header crc is included.  Note that
+   the current versions of the command-line version of gzip (up through version
+   1.3.x) do not support header crc's, and will report that it is a "multi-part
+   gzip file" and give up.
+
+      If deflateSetHeader is not used, the default gzip header has text false,
+   the time set to zero, and os set to 255, with no extra, name, or comment
+   fields.  The gzip header is returned to the default state by deflateReset().
+
+      deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent.
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
+                                     int  windowBits));
+
+     This is another version of inflateInit with an extra parameter. The
+   fields next_in, avail_in, zalloc, zfree and opaque must be initialized
+   before by the caller.
+
+     The windowBits parameter is the base two logarithm of the maximum window
+   size (the size of the history buffer).  It should be in the range 8..15 for
+   this version of the library. The default value is 15 if inflateInit is used
+   instead. windowBits must be greater than or equal to the windowBits value
+   provided to deflateInit2() while compressing, or it must be equal to 15 if
+   deflateInit2() was not used. If a compressed stream with a larger window
+   size is given as input, inflate() will return with the error code
+   Z_DATA_ERROR instead of trying to allocate a larger window.
+
+     windowBits can also be -8..-15 for raw inflate. In this case, -windowBits
+   determines the window size. inflate() will then process raw deflate data,
+   not looking for a zlib or gzip header, not generating a check value, and not
+   looking for any check values for comparison at the end of the stream. This
+   is for use with other formats that use the deflate compressed data format
+   such as zip.  Those formats provide their own check values. If a custom
+   format is developed using the raw deflate format for compressed data, it is
+   recommended that a check value such as an adler32 or a crc32 be applied to
+   the uncompressed data as is done in the zlib, gzip, and zip formats.  For
+   most applications, the zlib format should be used as is. Note that comments
+   above on the use in deflateInit2() applies to the magnitude of windowBits.
+
+     windowBits can also be greater than 15 for optional gzip decoding. Add
+   32 to windowBits to enable zlib and gzip decoding with automatic header
+   detection, or add 16 to decode only the gzip format (the zlib format will
+   return a Z_DATA_ERROR).  If a gzip stream is being decoded, strm->adler is
+   a crc32 instead of an adler32.
+
+     inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg
+   is set to null if there is no error message.  inflateInit2 does not perform
+   any decompression apart from reading the zlib header if present: this will
+   be done by inflate(). (So next_in and avail_in may be modified, but next_out
+   and avail_out are unchanged.)
+*/
+
+ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
+                                             const Bytef *dictionary,
+                                             uInt  dictLength));
+/*
+     Initializes the decompression dictionary from the given uncompressed byte
+   sequence. This function must be called immediately after a call of inflate,
+   if that call returned Z_NEED_DICT. The dictionary chosen by the compressor
+   can be determined from the adler32 value returned by that call of inflate.
+   The compressor and decompressor must use exactly the same dictionary (see
+   deflateSetDictionary).  For raw inflate, this function can be called
+   immediately after inflateInit2() or inflateReset() and before any call of
+   inflate() to set the dictionary.  The application must insure that the
+   dictionary that was used for compression is provided.
+
+     inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
+   parameter is invalid (such as NULL dictionary) or the stream state is
+   inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
+   expected one (incorrect adler32 value). inflateSetDictionary does not
+   perform any decompression: this will be done by subsequent calls of
+   inflate().
+*/
+
+ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
+/*
+    Skips invalid compressed data until a full flush point (see above the
+  description of deflate with Z_FULL_FLUSH) can be found, or until all
+  available input is skipped. No output is provided.
+
+    inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
+  if no more input was provided, Z_DATA_ERROR if no flush point has been found,
+  or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
+  case, the application may save the current current value of total_in which
+  indicates where valid compressed data was found. In the error case, the
+  application may repeatedly call inflateSync, providing more input each time,
+  until success or end of the input data.
+*/
+
+ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
+                                    z_streamp source));
+/*
+     Sets the destination stream as a complete copy of the source stream.
+
+     This function can be useful when randomly accessing a large stream.  The
+   first pass through the stream can periodically record the inflate state,
+   allowing restarting inflate at those points when randomly accessing the
+   stream.
+
+     inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+   (such as zalloc being NULL). msg is left unchanged in both source and
+   destination.
+*/
+
+ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
+/*
+     This function is equivalent to inflateEnd followed by inflateInit,
+   but does not free and reallocate all the internal decompression state.
+   The stream will keep attributes that may have been set by inflateInit2.
+
+      inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent (such as zalloc or state being NULL).
+*/
+
+ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
+                                     int bits,
+                                     int value));
+/*
+     This function inserts bits in the inflate input stream.  The intent is
+  that this function is used to start inflating at a bit position in the
+  middle of a byte.  The provided bits will be used before any bytes are used
+  from next_in.  This function should only be used with raw inflate, and
+  should be used before the first inflate() call after inflateInit2() or
+  inflateReset().  bits must be less than or equal to 16, and that many of the
+  least significant bits of value will be inserted in the input.
+
+      inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent.
+*/
+
+ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
+                                         gz_headerp head));
+/*
+      inflateGetHeader() requests that gzip header information be stored in the
+   provided gz_header structure.  inflateGetHeader() may be called after
+   inflateInit2() or inflateReset(), and before the first call of inflate().
+   As inflate() processes the gzip stream, head->done is zero until the header
+   is completed, at which time head->done is set to one.  If a zlib stream is
+   being decoded, then head->done is set to -1 to indicate that there will be
+   no gzip header information forthcoming.  Note that Z_BLOCK can be used to
+   force inflate() to return immediately after header processing is complete
+   and before any actual data is decompressed.
+
+      The text, time, xflags, and os fields are filled in with the gzip header
+   contents.  hcrc is set to true if there is a header CRC.  (The header CRC
+   was valid if done is set to one.)  If extra is not Z_NULL, then extra_max
+   contains the maximum number of bytes to write to extra.  Once done is true,
+   extra_len contains the actual extra field length, and extra contains the
+   extra field, or that field truncated if extra_max is less than extra_len.
+   If name is not Z_NULL, then up to name_max characters are written there,
+   terminated with a zero unless the length is greater than name_max.  If
+   comment is not Z_NULL, then up to comm_max characters are written there,
+   terminated with a zero unless the length is greater than comm_max.  When
+   any of extra, name, or comment are not Z_NULL and the respective field is
+   not present in the header, then that field is set to Z_NULL to signal its
+   absence.  This allows the use of deflateSetHeader() with the returned
+   structure to duplicate the header.  However if those fields are set to
+   allocated memory, then the application will need to save those pointers
+   elsewhere so that they can be eventually freed.
+
+      If inflateGetHeader is not used, then the header information is simply
+   discarded.  The header is always checked for validity, including the header
+   CRC if present.  inflateReset() will reset the process to discard the header
+   information.  The application would need to call inflateGetHeader() again to
+   retrieve the header from the next gzip stream.
+
+      inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent.
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
+                                        unsigned char FAR *window));
+
+     Initialize the internal stream state for decompression using inflateBack()
+   calls.  The fields zalloc, zfree and opaque in strm must be initialized
+   before the call.  If zalloc and zfree are Z_NULL, then the default library-
+   derived memory allocation routines are used.  windowBits is the base two
+   logarithm of the window size, in the range 8..15.  window is a caller
+   supplied buffer of that size.  Except for special applications where it is
+   assured that deflate was used with small window sizes, windowBits must be 15
+   and a 32K byte window must be supplied to be able to decompress general
+   deflate streams.
+
+     See inflateBack() for the usage of these routines.
+
+     inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
+   the paramaters are invalid, Z_MEM_ERROR if the internal state could not
+   be allocated, or Z_VERSION_ERROR if the version of the library does not
+   match the version of the header file.
+*/
+
+typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *));
+typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
+
+ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
+                                    in_func in, void FAR *in_desc,
+                                    out_func out, void FAR *out_desc));
+/*
+     inflateBack() does a raw inflate with a single call using a call-back
+   interface for input and output.  This is more efficient than inflate() for
+   file i/o applications in that it avoids copying between the output and the
+   sliding window by simply making the window itself the output buffer.  This
+   function trusts the application to not change the output buffer passed by
+   the output function, at least until inflateBack() returns.
+
+     inflateBackInit() must be called first to allocate the internal state
+   and to initialize the state with the user-provided window buffer.
+   inflateBack() may then be used multiple times to inflate a complete, raw
+   deflate stream with each call.  inflateBackEnd() is then called to free
+   the allocated state.
+
+     A raw deflate stream is one with no zlib or gzip header or trailer.
+   This routine would normally be used in a utility that reads zip or gzip
+   files and writes out uncompressed files.  The utility would decode the
+   header and process the trailer on its own, hence this routine expects
+   only the raw deflate stream to decompress.  This is different from the
+   normal behavior of inflate(), which expects either a zlib or gzip header and
+   trailer around the deflate stream.
+
+     inflateBack() uses two subroutines supplied by the caller that are then
+   called by inflateBack() for input and output.  inflateBack() calls those
+   routines until it reads a complete deflate stream and writes out all of the
+   uncompressed data, or until it encounters an error.  The function's
+   parameters and return types are defined above in the in_func and out_func
+   typedefs.  inflateBack() will call in(in_desc, &buf) which should return the
+   number of bytes of provided input, and a pointer to that input in buf.  If
+   there is no input available, in() must return zero--buf is ignored in that
+   case--and inflateBack() will return a buffer error.  inflateBack() will call
+   out(out_desc, buf, len) to write the uncompressed data buf[0..len-1].  out()
+   should return zero on success, or non-zero on failure.  If out() returns
+   non-zero, inflateBack() will return with an error.  Neither in() nor out()
+   are permitted to change the contents of the window provided to
+   inflateBackInit(), which is also the buffer that out() uses to write from.
+   The length written by out() will be at most the window size.  Any non-zero
+   amount of input may be provided by in().
+
+     For convenience, inflateBack() can be provided input on the first call by
+   setting strm->next_in and strm->avail_in.  If that input is exhausted, then
+   in() will be called.  Therefore strm->next_in must be initialized before
+   calling inflateBack().  If strm->next_in is Z_NULL, then in() will be called
+   immediately for input.  If strm->next_in is not Z_NULL, then strm->avail_in
+   must also be initialized, and then if strm->avail_in is not zero, input will
+   initially be taken from strm->next_in[0 .. strm->avail_in - 1].
+
+     The in_desc and out_desc parameters of inflateBack() is passed as the
+   first parameter of in() and out() respectively when they are called.  These
+   descriptors can be optionally used to pass any information that the caller-
+   supplied in() and out() functions need to do their job.
+
+     On return, inflateBack() will set strm->next_in and strm->avail_in to
+   pass back any unused input that was provided by the last in() call.  The
+   return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR
+   if in() or out() returned an error, Z_DATA_ERROR if there was a format
+   error in the deflate stream (in which case strm->msg is set to indicate the
+   nature of the error), or Z_STREAM_ERROR if the stream was not properly
+   initialized.  In the case of Z_BUF_ERROR, an input or output error can be
+   distinguished using strm->next_in which will be Z_NULL only if in() returned
+   an error.  If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to
+   out() returning non-zero.  (in() will always be called before out(), so
+   strm->next_in is assured to be defined if out() returns non-zero.)  Note
+   that inflateBack() cannot return Z_OK.
+*/
+
+ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));
+/*
+     All memory allocated by inflateBackInit() is freed.
+
+     inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream
+   state was inconsistent.
+*/
+
+ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
+/* Return flags indicating compile-time options.
+
+    Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other:
+     1.0: size of uInt
+     3.2: size of uLong
+     5.4: size of voidpf (pointer)
+     7.6: size of z_off_t
+
+    Compiler, assembler, and debug options:
+     8: DEBUG
+     9: ASMV or ASMINF -- use ASM code
+     10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention
+     11: 0 (reserved)
+
+    One-time table building (smaller code, but not thread-safe if true):
+     12: BUILDFIXED -- build static block decoding tables when needed
+     13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed
+     14,15: 0 (reserved)
+
+    Library content (indicates missing functionality):
+     16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking
+                          deflate code when not needed)
+     17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect
+                    and decode gzip streams (to avoid linking crc code)
+     18-19: 0 (reserved)
+
+    Operation variations (changes in library functionality):
+     20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate
+     21: FASTEST -- deflate algorithm with only one, lowest compression level
+     22,23: 0 (reserved)
+
+    The sprintf variant used by gzprintf (zero is best):
+     24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format
+     25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure!
+     26: 0 = returns value, 1 = void -- 1 means inferred string length returned
+
+    Remainder:
+     27-31: 0 (reserved)
+ */
+
+
+                        /* utility functions */
+
+/*
+     The following utility functions are implemented on top of the
+   basic stream-oriented functions. To simplify the interface, some
+   default options are assumed (compression level and memory usage,
+   standard memory allocation functions). The source code of these
+   utility functions can easily be modified if you need special options.
+*/
+
+ZEXTERN int ZEXPORT compress OF((Bytef *dest,   uLongf *destLen,
+                                 const Bytef *source, uLong sourceLen));
+/*
+     Compresses the source buffer into the destination buffer.  sourceLen is
+   the byte length of the source buffer. Upon entry, destLen is the total
+   size of the destination buffer, which must be at least the value returned
+   by compressBound(sourceLen). Upon exit, destLen is the actual size of the
+   compressed buffer.
+     This function can be used to compress a whole file at once if the
+   input file is mmap'ed.
+     compress returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_BUF_ERROR if there was not enough room in the output
+   buffer.
+*/
+
+ZEXTERN int ZEXPORT compress2 OF((Bytef *dest,   uLongf *destLen,
+                                  const Bytef *source, uLong sourceLen,
+                                  int level));
+/*
+     Compresses the source buffer into the destination buffer. The level
+   parameter has the same meaning as in deflateInit.  sourceLen is the byte
+   length of the source buffer. Upon entry, destLen is the total size of the
+   destination buffer, which must be at least the value returned by
+   compressBound(sourceLen). Upon exit, destLen is the actual size of the
+   compressed buffer.
+
+     compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+   Z_STREAM_ERROR if the level parameter is invalid.
+*/
+
+ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
+/*
+     compressBound() returns an upper bound on the compressed size after
+   compress() or compress2() on sourceLen bytes.  It would be used before
+   a compress() or compress2() call to allocate the destination buffer.
+*/
+
+ZEXTERN int ZEXPORT uncompress OF((Bytef *dest,   uLongf *destLen,
+                                   const Bytef *source, uLong sourceLen));
+/*
+     Decompresses the source buffer into the destination buffer.  sourceLen is
+   the byte length of the source buffer. Upon entry, destLen is the total
+   size of the destination buffer, which must be large enough to hold the
+   entire uncompressed data. (The size of the uncompressed data must have
+   been saved previously by the compressor and transmitted to the decompressor
+   by some mechanism outside the scope of this compression library.)
+   Upon exit, destLen is the actual size of the compressed buffer.
+     This function can be used to decompress a whole file at once if the
+   input file is mmap'ed.
+
+     uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_BUF_ERROR if there was not enough room in the output
+   buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete.
+*/
+
+
+typedef voidp gzFile;
+
+ZEXTERN gzFile ZEXPORT gzopen  OF((const char *path, const char *mode));
+/*
+     Opens a gzip (.gz) file for reading or writing. The mode parameter
+   is as in fopen ("rb" or "wb") but can also include a compression level
+   ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
+   Huffman only compression as in "wb1h", or 'R' for run-length encoding
+   as in "wb1R". (See the description of deflateInit2 for more information
+   about the strategy parameter.)
+
+     gzopen can be used to read a file which is not in gzip format; in this
+   case gzread will directly read from the file without decompression.
+
+     gzopen returns NULL if the file could not be opened or if there was
+   insufficient memory to allocate the (de)compression state; errno
+   can be checked to distinguish the two cases (if errno is zero, the
+   zlib error is Z_MEM_ERROR).  */
+
+ZEXTERN gzFile ZEXPORT gzdopen  OF((int fd, const char *mode));
+/*
+     gzdopen() associates a gzFile with the file descriptor fd.  File
+   descriptors are obtained from calls like open, dup, creat, pipe or
+   fileno (in the file has been previously opened with fopen).
+   The mode parameter is as in gzopen.
+     The next call of gzclose on the returned gzFile will also close the
+   file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
+   descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
+     gzdopen returns NULL if there was insufficient memory to allocate
+   the (de)compression state.
+*/
+
+ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
+/*
+     Dynamically update the compression level or strategy. See the description
+   of deflateInit2 for the meaning of these parameters.
+     gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
+   opened for writing.
+*/
+
+ZEXTERN int ZEXPORT    gzread  OF((gzFile file, voidp buf, unsigned len));
+/*
+     Reads the given number of uncompressed bytes from the compressed file.
+   If the input file was not in gzip format, gzread copies the given number
+   of bytes into the buffer.
+     gzread returns the number of uncompressed bytes actually read (0 for
+   end of file, -1 for error). */
+
+ZEXTERN int ZEXPORT    gzwrite OF((gzFile file,
+                                   voidpc buf, unsigned len));
+/*
+     Writes the given number of uncompressed bytes into the compressed file.
+   gzwrite returns the number of uncompressed bytes actually written
+   (0 in case of error).
+*/
+
+ZEXTERN int ZEXPORTVA   gzprintf OF((gzFile file, const char *format, ...));
+/*
+     Converts, formats, and writes the args to the compressed file under
+   control of the format string, as in fprintf. gzprintf returns the number of
+   uncompressed bytes actually written (0 in case of error).  The number of
+   uncompressed bytes written is limited to 4095. The caller should assure that
+   this limit is not exceeded. If it is exceeded, then gzprintf() will return
+   return an error (0) with nothing written. In this case, there may also be a
+   buffer overflow with unpredictable consequences, which is possible only if
+   zlib was compiled with the insecure functions sprintf() or vsprintf()
+   because the secure snprintf() or vsnprintf() functions were not available.
+*/
+
+ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
+/*
+      Writes the given null-terminated string to the compressed file, excluding
+   the terminating null character.
+      gzputs returns the number of characters written, or -1 in case of error.
+*/
+
+ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
+/*
+      Reads bytes from the compressed file until len-1 characters are read, or
+   a newline character is read and transferred to buf, or an end-of-file
+   condition is encountered.  The string is then terminated with a null
+   character.
+      gzgets returns buf, or Z_NULL in case of error.
+*/
+
+ZEXTERN int ZEXPORT    gzputc OF((gzFile file, int c));
+/*
+      Writes c, converted to an unsigned char, into the compressed file.
+   gzputc returns the value that was written, or -1 in case of error.
+*/
+
+ZEXTERN int ZEXPORT    gzgetc OF((gzFile file));
+/*
+      Reads one byte from the compressed file. gzgetc returns this byte
+   or -1 in case of end of file or error.
+*/
+
+ZEXTERN int ZEXPORT    gzungetc OF((int c, gzFile file));
+/*
+      Push one character back onto the stream to be read again later.
+   Only one character of push-back is allowed.  gzungetc() returns the
+   character pushed, or -1 on failure.  gzungetc() will fail if a
+   character has been pushed but not read yet, or if c is -1. The pushed
+   character will be discarded if the stream is repositioned with gzseek()
+   or gzrewind().
+*/
+
+ZEXTERN int ZEXPORT    gzflush OF((gzFile file, int flush));
+/*
+     Flushes all pending output into the compressed file. The parameter
+   flush is as in the deflate() function. The return value is the zlib
+   error number (see function gzerror below). gzflush returns Z_OK if
+   the flush parameter is Z_FINISH and all output could be flushed.
+     gzflush should be called only when strictly necessary because it can
+   degrade compression.
+*/
+
+ZEXTERN z_off_t ZEXPORT    gzseek OF((gzFile file,
+                                      z_off_t offset, int whence));
+/*
+      Sets the starting position for the next gzread or gzwrite on the
+   given compressed file. The offset represents a number of bytes in the
+   uncompressed data stream. The whence parameter is defined as in lseek(2);
+   the value SEEK_END is not supported.
+     If the file is opened for reading, this function is emulated but can be
+   extremely slow. If the file is opened for writing, only forward seeks are
+   supported; gzseek then compresses a sequence of zeroes up to the new
+   starting position.
+
+      gzseek returns the resulting offset location as measured in bytes from
+   the beginning of the uncompressed stream, or -1 in case of error, in
+   particular if the file is opened for writing and the new starting position
+   would be before the current position.
+*/
+
+ZEXTERN int ZEXPORT    gzrewind OF((gzFile file));
+/*
+     Rewinds the given file. This function is supported only for reading.
+
+   gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
+*/
+
+ZEXTERN z_off_t ZEXPORT    gztell OF((gzFile file));
+/*
+     Returns the starting position for the next gzread or gzwrite on the
+   given compressed file. This position represents a number of bytes in the
+   uncompressed data stream.
+
+   gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
+*/
+
+ZEXTERN int ZEXPORT gzeof OF((gzFile file));
+/*
+     Returns 1 when EOF has previously been detected reading the given
+   input stream, otherwise zero.
+*/
+
+ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
+/*
+     Returns 1 if file is being read directly without decompression, otherwise
+   zero.
+*/
+
+ZEXTERN int ZEXPORT    gzclose OF((gzFile file));
+/*
+     Flushes all pending output if necessary, closes the compressed file
+   and deallocates all the (de)compression state. The return value is the zlib
+   error number (see function gzerror below).
+*/
+
+ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
+/*
+     Returns the error message for the last error which occurred on the
+   given compressed file. errnum is set to zlib error number. If an
+   error occurred in the file system and not in the compression library,
+   errnum is set to Z_ERRNO and the application may consult errno
+   to get the exact error code.
+*/
+
+ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
+/*
+     Clears the error and end-of-file flags for file. This is analogous to the
+   clearerr() function in stdio. This is useful for continuing to read a gzip
+   file that is being written concurrently.
+*/
+
+                        /* checksum functions */
+
+/*
+     These functions are not related to compression but are exported
+   anyway because they might be useful in applications using the
+   compression library.
+*/
+
+ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
+/*
+     Update a running Adler-32 checksum with the bytes buf[0..len-1] and
+   return the updated checksum. If buf is NULL, this function returns
+   the required initial value for the checksum.
+   An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
+   much faster. Usage example:
+
+     uLong adler = adler32(0L, Z_NULL, 0);
+
+     while (read_buffer(buffer, length) != EOF) {
+       adler = adler32(adler, buffer, length);
+     }
+     if (adler != original_adler) error();
+*/
+
+ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
+                                          z_off_t len2));
+/*
+     Combine two Adler-32 checksums into one.  For two sequences of bytes, seq1
+   and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
+   each, adler1 and adler2.  adler32_combine() returns the Adler-32 checksum of
+   seq1 and seq2 concatenated, requiring only adler1, adler2, and len2.
+*/
+
+ZEXTERN uLong ZEXPORT crc32   OF((uLong crc, const Bytef *buf, uInt len));
+/*
+     Update a running CRC-32 with the bytes buf[0..len-1] and return the
+   updated CRC-32. If buf is NULL, this function returns the required initial
+   value for the for the crc. Pre- and post-conditioning (one's complement) is
+   performed within this function so it shouldn't be done by the application.
+   Usage example:
+
+     uLong crc = crc32(0L, Z_NULL, 0);
+
+     while (read_buffer(buffer, length) != EOF) {
+       crc = crc32(crc, buffer, length);
+     }
+     if (crc != original_crc) error();
+*/
+
+ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));
+
+/*
+     Combine two CRC-32 check values into one.  For two sequences of bytes,
+   seq1 and seq2 with lengths len1 and len2, CRC-32 check values were
+   calculated for each, crc1 and crc2.  crc32_combine() returns the CRC-32
+   check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and
+   len2.
+*/
+
+
+                        /* various hacks, don't look :) */
+
+/* deflateInit and inflateInit are macros to allow checking the zlib version
+ * and the compiler's view of z_stream:
+ */
+ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
+                                     const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
+                                     const char *version, int stream_size));
+ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int  level, int  method,
+                                      int windowBits, int memLevel,
+                                      int strategy, const char *version,
+                                      int stream_size));
+ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int  windowBits,
+                                      const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
+                                         unsigned char FAR *window,
+                                         const char *version,
+                                         int stream_size));
+#define deflateInit(strm, level) \
+        deflateInit_((strm), (level),       ZLIB_VERSION, sizeof(z_stream))
+#define inflateInit(strm) \
+        inflateInit_((strm),                ZLIB_VERSION, sizeof(z_stream))
+#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
+        deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
+                      (strategy),           ZLIB_VERSION, sizeof(z_stream))
+#define inflateInit2(strm, windowBits) \
+        inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
+#define inflateBackInit(strm, windowBits, window) \
+        inflateBackInit_((strm), (windowBits), (window), \
+        ZLIB_VERSION, sizeof(z_stream))
+
+
+#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)
+    struct internal_state {int dummy;}; /* hack for buggy compilers */
+#endif
+
+ZEXTERN const char   * ZEXPORT zError           OF((int));
+ZEXTERN int            ZEXPORT inflateSyncPoint OF((z_streamp z));
+ZEXTERN const uLongf * ZEXPORT get_crc_table    OF((void));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ZLIB_H */

Added: vendor/Python/current/Modules/zlib/zutil.c
===================================================================
--- vendor/Python/current/Modules/zlib/zutil.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/zlib/zutil.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,318 @@
+/* zutil.c -- target dependent utility functions for the compression library
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#include "zutil.h"
+
+#ifndef NO_DUMMY_DECL
+struct internal_state      {int dummy;}; /* for buggy compilers */
+#endif
+
+const char * const z_errmsg[10] = {
+"need dictionary",     /* Z_NEED_DICT       2  */
+"stream end",          /* Z_STREAM_END      1  */
+"",                    /* Z_OK              0  */
+"file error",          /* Z_ERRNO         (-1) */
+"stream error",        /* Z_STREAM_ERROR  (-2) */
+"data error",          /* Z_DATA_ERROR    (-3) */
+"insufficient memory", /* Z_MEM_ERROR     (-4) */
+"buffer error",        /* Z_BUF_ERROR     (-5) */
+"incompatible version",/* Z_VERSION_ERROR (-6) */
+""};
+
+
+const char * ZEXPORT zlibVersion()
+{
+    return ZLIB_VERSION;
+}
+
+uLong ZEXPORT zlibCompileFlags()
+{
+    uLong flags;
+
+    flags = 0;
+    switch (sizeof(uInt)) {
+    case 2:     break;
+    case 4:     flags += 1;     break;
+    case 8:     flags += 2;     break;
+    default:    flags += 3;
+    }
+    switch (sizeof(uLong)) {
+    case 2:     break;
+    case 4:     flags += 1 << 2;        break;
+    case 8:     flags += 2 << 2;        break;
+    default:    flags += 3 << 2;
+    }
+    switch (sizeof(voidpf)) {
+    case 2:     break;
+    case 4:     flags += 1 << 4;        break;
+    case 8:     flags += 2 << 4;        break;
+    default:    flags += 3 << 4;
+    }
+    switch (sizeof(z_off_t)) {
+    case 2:     break;
+    case 4:     flags += 1 << 6;        break;
+    case 8:     flags += 2 << 6;        break;
+    default:    flags += 3 << 6;
+    }
+#ifdef DEBUG
+    flags += 1 << 8;
+#endif
+#if defined(ASMV) || defined(ASMINF)
+    flags += 1 << 9;
+#endif
+#ifdef ZLIB_WINAPI
+    flags += 1 << 10;
+#endif
+#ifdef BUILDFIXED
+    flags += 1 << 12;
+#endif
+#ifdef DYNAMIC_CRC_TABLE
+    flags += 1 << 13;
+#endif
+#ifdef NO_GZCOMPRESS
+    flags += 1L << 16;
+#endif
+#ifdef NO_GZIP
+    flags += 1L << 17;
+#endif
+#ifdef PKZIP_BUG_WORKAROUND
+    flags += 1L << 20;
+#endif
+#ifdef FASTEST
+    flags += 1L << 21;
+#endif
+#ifdef STDC
+#  ifdef NO_vsnprintf
+        flags += 1L << 25;
+#    ifdef HAS_vsprintf_void
+        flags += 1L << 26;
+#    endif
+#  else
+#    ifdef HAS_vsnprintf_void
+        flags += 1L << 26;
+#    endif
+#  endif
+#else
+        flags += 1L << 24;
+#  ifdef NO_snprintf
+        flags += 1L << 25;
+#    ifdef HAS_sprintf_void
+        flags += 1L << 26;
+#    endif
+#  else
+#    ifdef HAS_snprintf_void
+        flags += 1L << 26;
+#    endif
+#  endif
+#endif
+    return flags;
+}
+
+#ifdef DEBUG
+
+#  ifndef verbose
+#    define verbose 0
+#  endif
+int z_verbose = verbose;
+
+void z_error (m)
+    char *m;
+{
+    fprintf(stderr, "%s\n", m);
+    exit(1);
+}
+#endif
+
+/* exported to allow conversion of error code to string for compress() and
+ * uncompress()
+ */
+const char * ZEXPORT zError(err)
+    int err;
+{
+    return ERR_MSG(err);
+}
+
+#if defined(_WIN32_WCE)
+    /* The Microsoft C Run-Time Library for Windows CE doesn't have
+     * errno.  We define it as a global variable to simplify porting.
+     * Its value is always 0 and should not be used.
+     */
+    int errno = 0;
+#endif
+
+#ifndef HAVE_MEMCPY
+
+void zmemcpy(dest, source, len)
+    Bytef* dest;
+    const Bytef* source;
+    uInt  len;
+{
+    if (len == 0) return;
+    do {
+        *dest++ = *source++; /* ??? to be unrolled */
+    } while (--len != 0);
+}
+
+int zmemcmp(s1, s2, len)
+    const Bytef* s1;
+    const Bytef* s2;
+    uInt  len;
+{
+    uInt j;
+
+    for (j = 0; j < len; j++) {
+        if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
+    }
+    return 0;
+}
+
+void zmemzero(dest, len)
+    Bytef* dest;
+    uInt  len;
+{
+    if (len == 0) return;
+    do {
+        *dest++ = 0;  /* ??? to be unrolled */
+    } while (--len != 0);
+}
+#endif
+
+
+#ifdef SYS16BIT
+
+#ifdef __TURBOC__
+/* Turbo C in 16-bit mode */
+
+#  define MY_ZCALLOC
+
+/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
+ * and farmalloc(64K) returns a pointer with an offset of 8, so we
+ * must fix the pointer. Warning: the pointer must be put back to its
+ * original form in order to free it, use zcfree().
+ */
+
+#define MAX_PTR 10
+/* 10*64K = 640K */
+
+local int next_ptr = 0;
+
+typedef struct ptr_table_s {
+    voidpf org_ptr;
+    voidpf new_ptr;
+} ptr_table;
+
+local ptr_table table[MAX_PTR];
+/* This table is used to remember the original form of pointers
+ * to large buffers (64K). Such pointers are normalized with a zero offset.
+ * Since MSDOS is not a preemptive multitasking OS, this table is not
+ * protected from concurrent access. This hack doesn't work anyway on
+ * a protected system like OS/2. Use Microsoft C instead.
+ */
+
+voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
+{
+    voidpf buf = opaque; /* just to make some compilers happy */
+    ulg bsize = (ulg)items*size;
+
+    /* If we allocate less than 65520 bytes, we assume that farmalloc
+     * will return a usable pointer which doesn't have to be normalized.
+     */
+    if (bsize < 65520L) {
+        buf = farmalloc(bsize);
+        if (*(ush*)&buf != 0) return buf;
+    } else {
+        buf = farmalloc(bsize + 16L);
+    }
+    if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
+    table[next_ptr].org_ptr = buf;
+
+    /* Normalize the pointer to seg:0 */
+    *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
+    *(ush*)&buf = 0;
+    table[next_ptr++].new_ptr = buf;
+    return buf;
+}
+
+void  zcfree (voidpf opaque, voidpf ptr)
+{
+    int n;
+    if (*(ush*)&ptr != 0) { /* object < 64K */
+        farfree(ptr);
+        return;
+    }
+    /* Find the original pointer */
+    for (n = 0; n < next_ptr; n++) {
+        if (ptr != table[n].new_ptr) continue;
+
+        farfree(table[n].org_ptr);
+        while (++n < next_ptr) {
+            table[n-1] = table[n];
+        }
+        next_ptr--;
+        return;
+    }
+    ptr = opaque; /* just to make some compilers happy */
+    Assert(0, "zcfree: ptr not found");
+}
+
+#endif /* __TURBOC__ */
+
+
+#ifdef M_I86
+/* Microsoft C in 16-bit mode */
+
+#  define MY_ZCALLOC
+
+#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
+#  define _halloc  halloc
+#  define _hfree   hfree
+#endif
+
+voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
+{
+    if (opaque) opaque = 0; /* to make compiler happy */
+    return _halloc((long)items, size);
+}
+
+void  zcfree (voidpf opaque, voidpf ptr)
+{
+    if (opaque) opaque = 0; /* to make compiler happy */
+    _hfree(ptr);
+}
+
+#endif /* M_I86 */
+
+#endif /* SYS16BIT */
+
+
+#ifndef MY_ZCALLOC /* Any system without a special alloc function */
+
+#ifndef STDC
+extern voidp  malloc OF((uInt size));
+extern voidp  calloc OF((uInt items, uInt size));
+extern void   free   OF((voidpf ptr));
+#endif
+
+voidpf zcalloc (opaque, items, size)
+    voidpf opaque;
+    unsigned items;
+    unsigned size;
+{
+    if (opaque) items += size - size; /* make compiler happy */
+    return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) :
+                              (voidpf)calloc(items, size);
+}
+
+void  zcfree (opaque, ptr)
+    voidpf opaque;
+    voidpf ptr;
+{
+    free(ptr);
+    if (opaque) return; /* make compiler happy */
+}
+
+#endif /* MY_ZCALLOC */

Added: vendor/Python/current/Modules/zlib/zutil.h
===================================================================
--- vendor/Python/current/Modules/zlib/zutil.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/zlib/zutil.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,269 @@
+/* zutil.h -- internal interface and configuration of the compression library
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZUTIL_H
+#define ZUTIL_H
+
+#define ZLIB_INTERNAL
+#include "zlib.h"
+
+#ifdef STDC
+#  ifndef _WIN32_WCE
+#    include <stddef.h>
+#  endif
+#  include <string.h>
+#  include <stdlib.h>
+#endif
+#ifdef NO_ERRNO_H
+#   ifdef _WIN32_WCE
+      /* The Microsoft C Run-Time Library for Windows CE doesn't have
+       * errno.  We define it as a global variable to simplify porting.
+       * Its value is always 0 and should not be used.  We rename it to
+       * avoid conflict with other libraries that use the same workaround.
+       */
+#     define errno z_errno
+#   endif
+    extern int errno;
+#else
+#  ifndef _WIN32_WCE
+#    include <errno.h>
+#  endif
+#endif
+
+#ifndef local
+#  define local static
+#endif
+/* compile with -Dlocal if your debugger can't find static symbols */
+
+typedef unsigned char  uch;
+typedef uch FAR uchf;
+typedef unsigned short ush;
+typedef ush FAR ushf;
+typedef unsigned long  ulg;
+
+extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
+/* (size given to avoid silly warnings with Visual C++) */
+
+#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
+
+#define ERR_RETURN(strm,err) \
+  return (strm->msg = (char*)ERR_MSG(err), (err))
+/* To be used only when the state is known to be valid */
+
+        /* common constants */
+
+#ifndef DEF_WBITS
+#  define DEF_WBITS MAX_WBITS
+#endif
+/* default windowBits for decompression. MAX_WBITS is for compression only */
+
+#if MAX_MEM_LEVEL >= 8
+#  define DEF_MEM_LEVEL 8
+#else
+#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL
+#endif
+/* default memLevel */
+
+#define STORED_BLOCK 0
+#define STATIC_TREES 1
+#define DYN_TREES    2
+/* The three kinds of block type */
+
+#define MIN_MATCH  3
+#define MAX_MATCH  258
+/* The minimum and maximum match lengths */
+
+#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
+
+        /* target dependencies */
+
+#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
+#  define OS_CODE  0x00
+#  if defined(__TURBOC__) || defined(__BORLANDC__)
+#    if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
+       /* Allow compilation with ANSI keywords only enabled */
+       void _Cdecl farfree( void *block );
+       void *_Cdecl farmalloc( unsigned long nbytes );
+#    else
+#      include <alloc.h>
+#    endif
+#  else /* MSC or DJGPP */
+#    include <malloc.h>
+#  endif
+#endif
+
+#ifdef AMIGA
+#  define OS_CODE  0x01
+#endif
+
+#if defined(VAXC) || defined(VMS)
+#  define OS_CODE  0x02
+#  define F_OPEN(name, mode) \
+     fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
+#endif
+
+#if defined(ATARI) || defined(atarist)
+#  define OS_CODE  0x05
+#endif
+
+#ifdef OS2
+#  define OS_CODE  0x06
+#  ifdef M_I86
+     #include <malloc.h>
+#  endif
+#endif
+
+#if defined(MACOS) || defined(TARGET_OS_MAC)
+#  define OS_CODE  0x07
+#  if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
+#    include <unix.h> /* for fdopen */
+#  else
+#    ifndef fdopen
+#      define fdopen(fd,mode) NULL /* No fdopen() */
+#    endif
+#  endif
+#endif
+
+#ifdef TOPS20
+#  define OS_CODE  0x0a
+#endif
+
+#ifdef WIN32
+#  ifndef __CYGWIN__  /* Cygwin is Unix, not Win32 */
+#    define OS_CODE  0x0b
+#  endif
+#endif
+
+#ifdef __50SERIES /* Prime/PRIMOS */
+#  define OS_CODE  0x0f
+#endif
+
+#if defined(_BEOS_) || defined(RISCOS)
+#  define fdopen(fd,mode) NULL /* No fdopen() */
+#endif
+
+#if (defined(_MSC_VER) && (_MSC_VER > 600))
+#  if defined(_WIN32_WCE)
+#    define fdopen(fd,mode) NULL /* No fdopen() */
+#    ifndef _PTRDIFF_T_DEFINED
+       typedef int ptrdiff_t;
+#      define _PTRDIFF_T_DEFINED
+#    endif
+#  else
+#    define fdopen(fd,type)  _fdopen(fd,type)
+#  endif
+#endif
+
+        /* common defaults */
+
+#ifndef OS_CODE
+#  define OS_CODE  0x03  /* assume Unix */
+#endif
+
+#ifndef F_OPEN
+#  define F_OPEN(name, mode) fopen((name), (mode))
+#endif
+
+         /* functions */
+
+#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550)
+#  ifndef HAVE_VSNPRINTF
+#    define HAVE_VSNPRINTF
+#  endif
+#endif
+#if defined(__CYGWIN__)
+#  ifndef HAVE_VSNPRINTF
+#    define HAVE_VSNPRINTF
+#  endif
+#endif
+#ifndef HAVE_VSNPRINTF
+#  ifdef MSDOS
+     /* vsnprintf may exist on some MS-DOS compilers (DJGPP?),
+        but for now we just assume it doesn't. */
+#    define NO_vsnprintf
+#  endif
+#  ifdef __TURBOC__
+#    define NO_vsnprintf
+#  endif
+#  ifdef WIN32
+     /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */
+#    if !defined(vsnprintf) && !defined(NO_vsnprintf)
+#      define vsnprintf _vsnprintf
+#    endif
+#  endif
+#  ifdef __SASC
+#    define NO_vsnprintf
+#  endif
+#endif
+#ifdef VMS
+#  define NO_vsnprintf
+#endif
+
+#if defined(pyr)
+#  define NO_MEMCPY
+#endif
+#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
+ /* Use our own functions for small and medium model with MSC <= 5.0.
+  * You may have to use the same strategy for Borland C (untested).
+  * The __SC__ check is for Symantec.
+  */
+#  define NO_MEMCPY
+#endif
+#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
+#  define HAVE_MEMCPY
+#endif
+#ifdef HAVE_MEMCPY
+#  ifdef SMALL_MEDIUM /* MSDOS small or medium model */
+#    define zmemcpy _fmemcpy
+#    define zmemcmp _fmemcmp
+#    define zmemzero(dest, len) _fmemset(dest, 0, len)
+#  else
+#    define zmemcpy memcpy
+#    define zmemcmp memcmp
+#    define zmemzero(dest, len) memset(dest, 0, len)
+#  endif
+#else
+   extern void zmemcpy  OF((Bytef* dest, const Bytef* source, uInt len));
+   extern int  zmemcmp  OF((const Bytef* s1, const Bytef* s2, uInt len));
+   extern void zmemzero OF((Bytef* dest, uInt len));
+#endif
+
+/* Diagnostic functions */
+#ifdef DEBUG
+#  include <stdio.h>
+   extern int z_verbose;
+   extern void z_error    OF((char *m));
+#  define Assert(cond,msg) {if(!(cond)) z_error(msg);}
+#  define Trace(x) {if (z_verbose>=0) fprintf x ;}
+#  define Tracev(x) {if (z_verbose>0) fprintf x ;}
+#  define Tracevv(x) {if (z_verbose>1) fprintf x ;}
+#  define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
+#  define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
+#else
+#  define Assert(cond,msg)
+#  define Trace(x)
+#  define Tracev(x)
+#  define Tracevv(x)
+#  define Tracec(c,x)
+#  define Tracecv(c,x)
+#endif
+
+
+voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
+void   zcfree  OF((voidpf opaque, voidpf ptr));
+
+#define ZALLOC(strm, items, size) \
+           (*((strm)->zalloc))((strm)->opaque, (items), (size))
+#define ZFREE(strm, addr)  (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
+#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
+
+#endif /* ZUTIL_H */

Added: vendor/Python/current/Modules/zlibmodule.c
===================================================================
--- vendor/Python/current/Modules/zlibmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Modules/zlibmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1027 @@
+/* zlibmodule.c -- gzip-compatible data compression */
+/* See http://www.gzip.org/zlib/ */
+
+/* Windows users:  read Python's PCbuild\readme.txt */
+
+
+#include "Python.h"
+#include "zlib.h"
+
+#ifdef WITH_THREAD
+#include "pythread.h"
+
+/* #defs ripped off from _tkinter.c, even though the situation here is much
+   simpler, because we don't have to worry about waiting for Tcl
+   events!  And, since zlib itself is threadsafe, we don't need to worry
+   about re-entering zlib functions.
+
+   N.B.
+
+   Since ENTER_ZLIB and LEAVE_ZLIB only need to be called on functions
+   that modify the components of preexisting de/compress objects, it
+   could prove to be a performance gain on multiprocessor machines if
+   there was an de/compress object-specific lock.  However, for the
+   moment the ENTER_ZLIB and LEAVE_ZLIB calls are global for ALL
+   de/compress objects.
+ */
+
+static PyThread_type_lock zlib_lock = NULL; /* initialized on module load */
+
+#define ENTER_ZLIB \
+	Py_BEGIN_ALLOW_THREADS \
+	PyThread_acquire_lock(zlib_lock, 1); \
+	Py_END_ALLOW_THREADS
+
+#define LEAVE_ZLIB \
+	PyThread_release_lock(zlib_lock);
+
+#else
+
+#define ENTER_ZLIB
+#define LEAVE_ZLIB
+
+#endif
+
+/* The following parameters are copied from zutil.h, version 0.95 */
+#define DEFLATED   8
+#if MAX_MEM_LEVEL >= 8
+#  define DEF_MEM_LEVEL 8
+#else
+#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL
+#endif
+#define DEF_WBITS MAX_WBITS
+
+/* The output buffer will be increased in chunks of DEFAULTALLOC bytes. */
+#define DEFAULTALLOC (16*1024)
+#define PyInit_zlib initzlib
+
+static PyTypeObject Comptype;
+static PyTypeObject Decomptype;
+
+static PyObject *ZlibError;
+
+typedef struct
+{
+    PyObject_HEAD
+    z_stream zst;
+    PyObject *unused_data;
+    PyObject *unconsumed_tail;
+    int is_initialised;
+} compobject;
+
+static void
+zlib_error(z_stream zst, int err, char *msg)
+{
+    if (zst.msg == Z_NULL)
+	PyErr_Format(ZlibError, "Error %d %s", err, msg);
+    else
+	PyErr_Format(ZlibError, "Error %d %s: %.200s", err, msg, zst.msg);
+}
+
+PyDoc_STRVAR(compressobj__doc__,
+"compressobj([level]) -- Return a compressor object.\n"
+"\n"
+"Optional arg level is the compression level, in 1-9.");
+
+PyDoc_STRVAR(decompressobj__doc__,
+"decompressobj([wbits]) -- Return a decompressor object.\n"
+"\n"
+"Optional arg wbits is the window buffer size.");
+
+static compobject *
+newcompobject(PyTypeObject *type)
+{
+    compobject *self;
+    self = PyObject_New(compobject, type);
+    if (self == NULL)
+	return NULL;
+    self->is_initialised = 0;
+    self->unused_data = PyString_FromString("");
+    if (self->unused_data == NULL) {
+	Py_DECREF(self);
+	return NULL;
+    }
+    self->unconsumed_tail = PyString_FromString("");
+    if (self->unconsumed_tail == NULL) {
+	Py_DECREF(self);
+	return NULL;
+    }
+    return self;
+}
+
+PyDoc_STRVAR(compress__doc__,
+"compress(string[, level]) -- Returned compressed string.\n"
+"\n"
+"Optional arg level is the compression level, in 1-9.");
+
+static PyObject *
+PyZlib_compress(PyObject *self, PyObject *args)
+{
+    PyObject *ReturnVal = NULL;
+    Byte *input, *output;
+    int length, level=Z_DEFAULT_COMPRESSION, err;
+    z_stream zst;
+
+    /* require Python string object, optional 'level' arg */
+    if (!PyArg_ParseTuple(args, "s#|i:compress", &input, &length, &level))
+	return NULL;
+
+    zst.avail_out = length + length/1000 + 12 + 1;
+
+    output = (Byte*)malloc(zst.avail_out);
+    if (output == NULL) {
+	PyErr_SetString(PyExc_MemoryError,
+			"Can't allocate memory to compress data");
+	return NULL;
+    }
+
+    /* Past the point of no return.  From here on out, we need to make sure
+       we clean up mallocs & INCREFs. */
+
+    zst.zalloc = (alloc_func)NULL;
+    zst.zfree = (free_func)Z_NULL;
+    zst.next_out = (Byte *)output;
+    zst.next_in = (Byte *)input;
+    zst.avail_in = length;
+    err = deflateInit(&zst, level);
+
+    switch(err) {
+    case(Z_OK):
+	break;
+    case(Z_MEM_ERROR):
+	PyErr_SetString(PyExc_MemoryError,
+			"Out of memory while compressing data");
+	goto error;
+    case(Z_STREAM_ERROR):
+	PyErr_SetString(ZlibError,
+			"Bad compression level");
+	goto error;
+    default:
+        deflateEnd(&zst);
+	zlib_error(zst, err, "while compressing data");
+	goto error;
+    }
+
+    Py_BEGIN_ALLOW_THREADS;
+    err = deflate(&zst, Z_FINISH);
+    Py_END_ALLOW_THREADS;
+
+    if (err != Z_STREAM_END) {
+	zlib_error(zst, err, "while compressing data");
+	deflateEnd(&zst);
+	goto error;
+    }
+
+    err=deflateEnd(&zst);
+    if (err == Z_OK)
+	ReturnVal = PyString_FromStringAndSize((char *)output,
+					       zst.total_out);
+    else
+	zlib_error(zst, err, "while finishing compression");
+
+ error:
+    free(output);
+
+    return ReturnVal;
+}
+
+PyDoc_STRVAR(decompress__doc__,
+"decompress(string[, wbits[, bufsize]]) -- Return decompressed string.\n"
+"\n"
+"Optional arg wbits is the window buffer size.  Optional arg bufsize is\n"
+"the initial output buffer size.");
+
+static PyObject *
+PyZlib_decompress(PyObject *self, PyObject *args)
+{
+    PyObject *result_str;
+    Byte *input;
+    int length, err;
+    int wsize=DEF_WBITS, r_strlen=DEFAULTALLOC;
+    z_stream zst;
+
+    if (!PyArg_ParseTuple(args, "s#|ii:decompress",
+			  &input, &length, &wsize, &r_strlen))
+	return NULL;
+
+    if (r_strlen <= 0)
+	r_strlen = 1;
+
+    zst.avail_in = length;
+    zst.avail_out = r_strlen;
+
+    if (!(result_str = PyString_FromStringAndSize(NULL, r_strlen)))
+	return NULL;
+
+    zst.zalloc = (alloc_func)NULL;
+    zst.zfree = (free_func)Z_NULL;
+    zst.next_out = (Byte *)PyString_AS_STRING(result_str);
+    zst.next_in = (Byte *)input;
+    err = inflateInit2(&zst, wsize);
+
+    switch(err) {
+    case(Z_OK):
+	break;
+    case(Z_MEM_ERROR):
+	PyErr_SetString(PyExc_MemoryError,
+			"Out of memory while decompressing data");
+	goto error;
+    default:
+        inflateEnd(&zst);
+	zlib_error(zst, err, "while preparing to decompress data");
+	goto error;
+    }
+
+    do {
+	Py_BEGIN_ALLOW_THREADS
+	err=inflate(&zst, Z_FINISH);
+	Py_END_ALLOW_THREADS
+
+	switch(err) {
+	case(Z_STREAM_END):
+	    break;
+	case(Z_BUF_ERROR):
+	    /*
+	     * If there is at least 1 byte of room according to zst.avail_out
+	     * and we get this error, assume that it means zlib cannot
+	     * process the inflate call() due to an error in the data.
+	     */
+	    if (zst.avail_out > 0) {
+		PyErr_Format(ZlibError, "Error %i while decompressing data",
+			     err);
+		inflateEnd(&zst);
+		goto error;
+	    }
+	    /* fall through */
+	case(Z_OK):
+	    /* need more memory */
+	    if (_PyString_Resize(&result_str, r_strlen << 1) < 0) {
+		inflateEnd(&zst);
+		goto error;
+	    }
+	    zst.next_out = (unsigned char *)PyString_AS_STRING(result_str) \
+		+ r_strlen;
+	    zst.avail_out = r_strlen;
+	    r_strlen = r_strlen << 1;
+	    break;
+	default:
+	    inflateEnd(&zst);
+	    zlib_error(zst, err, "while decompressing data");
+	    goto error;
+	}
+    } while (err != Z_STREAM_END);
+
+    err = inflateEnd(&zst);
+    if (err != Z_OK) {
+	zlib_error(zst, err, "while finishing data decompression");
+	goto error;
+    }
+
+    _PyString_Resize(&result_str, zst.total_out);
+    return result_str;
+
+ error:
+    Py_XDECREF(result_str);
+    return NULL;
+}
+
+static PyObject *
+PyZlib_compressobj(PyObject *selfptr, PyObject *args)
+{
+    compobject *self;
+    int level=Z_DEFAULT_COMPRESSION, method=DEFLATED;
+    int wbits=MAX_WBITS, memLevel=DEF_MEM_LEVEL, strategy=0, err;
+
+    if (!PyArg_ParseTuple(args, "|iiiii:compressobj", &level, &method, &wbits,
+			  &memLevel, &strategy))
+	return NULL;
+
+    self = newcompobject(&Comptype);
+    if (self==NULL)
+	return(NULL);
+    self->zst.zalloc = (alloc_func)NULL;
+    self->zst.zfree = (free_func)Z_NULL;
+    self->zst.next_in = NULL;
+    self->zst.avail_in = 0;
+    err = deflateInit2(&self->zst, level, method, wbits, memLevel, strategy);
+    switch(err) {
+    case (Z_OK):
+	self->is_initialised = 1;
+	return (PyObject*)self;
+    case (Z_MEM_ERROR):
+	Py_DECREF(self);
+	PyErr_SetString(PyExc_MemoryError,
+			"Can't allocate memory for compression object");
+	return NULL;
+    case(Z_STREAM_ERROR):
+	Py_DECREF(self);
+	PyErr_SetString(PyExc_ValueError, "Invalid initialization option");
+	return NULL;
+    default:
+	zlib_error(self->zst, err, "while creating compression object");
+        Py_DECREF(self);
+	return NULL;
+    }
+}
+
+static PyObject *
+PyZlib_decompressobj(PyObject *selfptr, PyObject *args)
+{
+    int wbits=DEF_WBITS, err;
+    compobject *self;
+    if (!PyArg_ParseTuple(args, "|i:decompressobj", &wbits))
+	return NULL;
+
+    self = newcompobject(&Decomptype);
+    if (self == NULL)
+	return(NULL);
+    self->zst.zalloc = (alloc_func)NULL;
+    self->zst.zfree = (free_func)Z_NULL;
+    self->zst.next_in = NULL;
+    self->zst.avail_in = 0;
+    err = inflateInit2(&self->zst, wbits);
+    switch(err) {
+    case (Z_OK):
+	self->is_initialised = 1;
+	return (PyObject*)self;
+    case(Z_STREAM_ERROR):
+	Py_DECREF(self);
+	PyErr_SetString(PyExc_ValueError, "Invalid initialization option");
+	return NULL;
+    case (Z_MEM_ERROR):
+	Py_DECREF(self);
+	PyErr_SetString(PyExc_MemoryError,
+			"Can't allocate memory for decompression object");
+	return NULL;
+    default:
+	zlib_error(self->zst, err, "while creating decompression object");
+        Py_DECREF(self);
+	return NULL;
+    }
+}
+
+static void
+Comp_dealloc(compobject *self)
+{
+    if (self->is_initialised)
+	deflateEnd(&self->zst);
+    Py_XDECREF(self->unused_data);
+    Py_XDECREF(self->unconsumed_tail);
+    PyObject_Del(self);
+}
+
+static void
+Decomp_dealloc(compobject *self)
+{
+    if (self->is_initialised)
+	inflateEnd(&self->zst);
+    Py_XDECREF(self->unused_data);
+    Py_XDECREF(self->unconsumed_tail);
+    PyObject_Del(self);
+}
+
+PyDoc_STRVAR(comp_compress__doc__,
+"compress(data) -- Return a string containing data compressed.\n"
+"\n"
+"After calling this function, some of the input data may still\n"
+"be stored in internal buffers for later processing.\n"
+"Call the flush() method to clear these buffers.");
+
+
+static PyObject *
+PyZlib_objcompress(compobject *self, PyObject *args)
+{
+    int err, inplen, length = DEFAULTALLOC;
+    PyObject *RetVal;
+    Byte *input;
+    unsigned long start_total_out;
+
+    if (!PyArg_ParseTuple(args, "s#:compress", &input, &inplen))
+	return NULL;
+
+    if (!(RetVal = PyString_FromStringAndSize(NULL, length)))
+	return NULL;
+
+    ENTER_ZLIB
+
+    start_total_out = self->zst.total_out;
+    self->zst.avail_in = inplen;
+    self->zst.next_in = input;
+    self->zst.avail_out = length;
+    self->zst.next_out = (unsigned char *)PyString_AS_STRING(RetVal);
+
+    Py_BEGIN_ALLOW_THREADS
+    err = deflate(&(self->zst), Z_NO_FLUSH);
+    Py_END_ALLOW_THREADS
+
+    /* while Z_OK and the output buffer is full, there might be more output,
+       so extend the output buffer and try again */
+    while (err == Z_OK && self->zst.avail_out == 0) {
+	if (_PyString_Resize(&RetVal, length << 1) < 0)
+	    goto error;
+	self->zst.next_out = (unsigned char *)PyString_AS_STRING(RetVal) \
+	    + length;
+	self->zst.avail_out = length;
+	length = length << 1;
+
+	Py_BEGIN_ALLOW_THREADS
+	err = deflate(&(self->zst), Z_NO_FLUSH);
+	Py_END_ALLOW_THREADS
+    }
+    /* We will only get Z_BUF_ERROR if the output buffer was full but
+       there wasn't more output when we tried again, so it is not an error
+       condition.
+    */
+
+    if (err != Z_OK && err != Z_BUF_ERROR) {
+	zlib_error(self->zst, err, "while compressing");
+	Py_DECREF(RetVal);
+	RetVal = NULL;
+	goto error;
+    }
+    _PyString_Resize(&RetVal, self->zst.total_out - start_total_out);
+
+ error:
+    LEAVE_ZLIB
+    return RetVal;
+}
+
+PyDoc_STRVAR(decomp_decompress__doc__,
+"decompress(data, max_length) -- Return a string containing the decompressed\n"
+"version of the data.\n"
+"\n"
+"After calling this function, some of the input data may still be stored in\n"
+"internal buffers for later processing.\n"
+"Call the flush() method to clear these buffers.\n"
+"If the max_length parameter is specified then the return value will be\n"
+"no longer than max_length.  Unconsumed input data will be stored in\n"
+"the unconsumed_tail attribute.");
+
+static PyObject *
+PyZlib_objdecompress(compobject *self, PyObject *args)
+{
+    int err, inplen, old_length, length = DEFAULTALLOC;
+    int max_length = 0;
+    PyObject *RetVal;
+    Byte *input;
+    unsigned long start_total_out;
+
+    if (!PyArg_ParseTuple(args, "s#|i:decompress", &input,
+			  &inplen, &max_length))
+	return NULL;
+    if (max_length < 0) {
+	PyErr_SetString(PyExc_ValueError,
+			"max_length must be greater than zero");
+	return NULL;
+    }
+
+    /* limit amount of data allocated to max_length */
+    if (max_length && length > max_length)
+	length = max_length;
+    if (!(RetVal = PyString_FromStringAndSize(NULL, length)))
+	return NULL;
+
+    ENTER_ZLIB
+
+    start_total_out = self->zst.total_out;
+    self->zst.avail_in = inplen;
+    self->zst.next_in = input;
+    self->zst.avail_out = length;
+    self->zst.next_out = (unsigned char *)PyString_AS_STRING(RetVal);
+
+    Py_BEGIN_ALLOW_THREADS
+    err = inflate(&(self->zst), Z_SYNC_FLUSH);
+    Py_END_ALLOW_THREADS
+
+    /* While Z_OK and the output buffer is full, there might be more output.
+       So extend the output buffer and try again.
+    */
+    while (err == Z_OK && self->zst.avail_out == 0) {
+	/* If max_length set, don't continue decompressing if we've already
+	   reached the limit.
+	*/
+	if (max_length && length >= max_length)
+	    break;
+
+	/* otherwise, ... */
+	old_length = length;
+	length = length << 1;
+	if (max_length && length > max_length)
+	    length = max_length;
+
+	if (_PyString_Resize(&RetVal, length) < 0)
+	    goto error;
+	self->zst.next_out = (unsigned char *)PyString_AS_STRING(RetVal) \
+	    + old_length;
+	self->zst.avail_out = length - old_length;
+
+	Py_BEGIN_ALLOW_THREADS
+	err = inflate(&(self->zst), Z_SYNC_FLUSH);
+	Py_END_ALLOW_THREADS
+    }
+
+    /* Not all of the compressed data could be accommodated in the output buffer
+       of specified size. Return the unconsumed tail in an attribute.*/
+    if(max_length) {
+	Py_DECREF(self->unconsumed_tail);
+	self->unconsumed_tail = PyString_FromStringAndSize((char *)self->zst.next_in,
+							   self->zst.avail_in);
+	if(!self->unconsumed_tail) {
+	    Py_DECREF(RetVal);
+	    RetVal = NULL;
+	    goto error;
+	}
+    }
+
+    /* The end of the compressed data has been reached, so set the
+       unused_data attribute to a string containing the remainder of the
+       data in the string.  Note that this is also a logical place to call
+       inflateEnd, but the old behaviour of only calling it on flush() is
+       preserved.
+    */
+    if (err == Z_STREAM_END) {
+	Py_XDECREF(self->unused_data);  /* Free original empty string */
+	self->unused_data = PyString_FromStringAndSize(
+	    (char *)self->zst.next_in, self->zst.avail_in);
+	if (self->unused_data == NULL) {
+	    Py_DECREF(RetVal);
+	    goto error;
+	}
+	/* We will only get Z_BUF_ERROR if the output buffer was full
+	   but there wasn't more output when we tried again, so it is
+	   not an error condition.
+	*/
+    } else if (err != Z_OK && err != Z_BUF_ERROR) {
+	zlib_error(self->zst, err, "while decompressing");
+	Py_DECREF(RetVal);
+	RetVal = NULL;
+	goto error;
+    }
+
+    _PyString_Resize(&RetVal, self->zst.total_out - start_total_out);
+
+ error:
+    LEAVE_ZLIB
+
+    return RetVal;
+}
+
+PyDoc_STRVAR(comp_flush__doc__,
+"flush( [mode] ) -- Return a string containing any remaining compressed data.\n"
+"\n"
+"mode can be one of the constants Z_SYNC_FLUSH, Z_FULL_FLUSH, Z_FINISH; the\n"
+"default value used when mode is not specified is Z_FINISH.\n"
+"If mode == Z_FINISH, the compressor object can no longer be used after\n"
+"calling the flush() method.  Otherwise, more data can still be compressed.");
+
+static PyObject *
+PyZlib_flush(compobject *self, PyObject *args)
+{
+    int err, length = DEFAULTALLOC;
+    PyObject *RetVal;
+    int flushmode = Z_FINISH;
+    unsigned long start_total_out;
+
+    if (!PyArg_ParseTuple(args, "|i:flush", &flushmode))
+	return NULL;
+
+    /* Flushing with Z_NO_FLUSH is a no-op, so there's no point in
+       doing any work at all; just return an empty string. */
+    if (flushmode == Z_NO_FLUSH) {
+	return PyString_FromStringAndSize(NULL, 0);
+    }
+
+    if (!(RetVal = PyString_FromStringAndSize(NULL, length)))
+	return NULL;
+
+    ENTER_ZLIB
+
+    start_total_out = self->zst.total_out;
+    self->zst.avail_in = 0;
+    self->zst.avail_out = length;
+    self->zst.next_out = (unsigned char *)PyString_AS_STRING(RetVal);
+
+    Py_BEGIN_ALLOW_THREADS
+    err = deflate(&(self->zst), flushmode);
+    Py_END_ALLOW_THREADS
+
+    /* while Z_OK and the output buffer is full, there might be more output,
+       so extend the output buffer and try again */
+    while (err == Z_OK && self->zst.avail_out == 0) {
+	if (_PyString_Resize(&RetVal, length << 1) < 0)
+	    goto error;
+	self->zst.next_out = (unsigned char *)PyString_AS_STRING(RetVal) \
+	    + length;
+	self->zst.avail_out = length;
+	length = length << 1;
+
+	Py_BEGIN_ALLOW_THREADS
+	err = deflate(&(self->zst), flushmode);
+	Py_END_ALLOW_THREADS
+    }
+
+    /* If flushmode is Z_FINISH, we also have to call deflateEnd() to free
+       various data structures. Note we should only get Z_STREAM_END when
+       flushmode is Z_FINISH, but checking both for safety*/
+    if (err == Z_STREAM_END && flushmode == Z_FINISH) {
+	err = deflateEnd(&(self->zst));
+	if (err != Z_OK) {
+	    zlib_error(self->zst, err, "from deflateEnd()");
+	    Py_DECREF(RetVal);
+	    RetVal = NULL;
+	    goto error;
+	}
+	else
+	    self->is_initialised = 0;
+
+	/* We will only get Z_BUF_ERROR if the output buffer was full
+	   but there wasn't more output when we tried again, so it is
+	   not an error condition.
+	*/
+    } else if (err!=Z_OK && err!=Z_BUF_ERROR) {
+	zlib_error(self->zst, err, "while flushing");
+	Py_DECREF(RetVal);
+	RetVal = NULL;
+	goto error;
+    }
+
+    _PyString_Resize(&RetVal, self->zst.total_out - start_total_out);
+
+ error:
+    LEAVE_ZLIB
+
+    return RetVal;
+}
+
+#ifdef HAVE_ZLIB_COPY
+PyDoc_STRVAR(comp_copy__doc__,
+"copy() -- Return a copy of the compression object.");
+
+static PyObject *
+PyZlib_copy(compobject *self)
+{
+    compobject *retval = NULL;
+    int err;
+
+    retval = newcompobject(&Comptype);
+    if (!retval) return NULL;
+
+    /* Copy the zstream state
+     * We use ENTER_ZLIB / LEAVE_ZLIB to make this thread-safe
+     */
+    ENTER_ZLIB
+    err = deflateCopy(&retval->zst, &self->zst);
+    switch(err) {
+    case(Z_OK):
+        break;
+    case(Z_STREAM_ERROR):
+        PyErr_SetString(PyExc_ValueError, "Inconsistent stream state");
+        goto error;
+    case(Z_MEM_ERROR):
+        PyErr_SetString(PyExc_MemoryError,
+                        "Can't allocate memory for compression object");
+        goto error;
+    default:
+        zlib_error(self->zst, err, "while copying compression object");
+        goto error;
+    }
+
+    Py_INCREF(self->unused_data);
+    Py_INCREF(self->unconsumed_tail);
+    Py_XDECREF(retval->unused_data);
+    Py_XDECREF(retval->unconsumed_tail);
+    retval->unused_data = self->unused_data;
+    retval->unconsumed_tail = self->unconsumed_tail;
+
+    /* Mark it as being initialized */
+    retval->is_initialised = 1;
+
+    LEAVE_ZLIB
+    return (PyObject *)retval;
+
+error:
+    LEAVE_ZLIB
+    Py_XDECREF(retval);
+    return NULL;
+}
+
+PyDoc_STRVAR(decomp_copy__doc__,
+"copy() -- Return a copy of the decompression object.");
+
+static PyObject *
+PyZlib_uncopy(compobject *self)
+{
+    compobject *retval = NULL;
+    int err;
+
+    retval = newcompobject(&Decomptype);
+    if (!retval) return NULL;
+
+    /* Copy the zstream state
+     * We use ENTER_ZLIB / LEAVE_ZLIB to make this thread-safe
+     */
+    ENTER_ZLIB
+    err = inflateCopy(&retval->zst, &self->zst);
+    switch(err) {
+    case(Z_OK):
+        break;
+    case(Z_STREAM_ERROR):
+        PyErr_SetString(PyExc_ValueError, "Inconsistent stream state");
+        goto error;
+    case(Z_MEM_ERROR):
+        PyErr_SetString(PyExc_MemoryError,
+                        "Can't allocate memory for decompression object");
+        goto error;
+    default:
+        zlib_error(self->zst, err, "while copying decompression object");
+        goto error;
+    }
+
+    Py_INCREF(self->unused_data);
+    Py_INCREF(self->unconsumed_tail);
+    Py_XDECREF(retval->unused_data);
+    Py_XDECREF(retval->unconsumed_tail);
+    retval->unused_data = self->unused_data;
+    retval->unconsumed_tail = self->unconsumed_tail;
+
+    /* Mark it as being initialized */
+    retval->is_initialised = 1;
+
+    LEAVE_ZLIB
+    return (PyObject *)retval;
+
+error:
+    LEAVE_ZLIB
+    Py_XDECREF(retval);
+    return NULL;
+}
+#endif
+
+PyDoc_STRVAR(decomp_flush__doc__,
+"flush( [length] ) -- Return a string containing any remaining\n"
+"decompressed data. length, if given, is the initial size of the\n"
+"output buffer.\n"
+"\n"
+"The decompressor object can no longer be used after this call.");
+
+static PyObject *
+PyZlib_unflush(compobject *self, PyObject *args)
+{
+    int err, length = DEFAULTALLOC;
+    PyObject * retval = NULL;
+    unsigned long start_total_out;
+
+    if (!PyArg_ParseTuple(args, "|i:flush", &length))
+	return NULL;
+    if (!(retval = PyString_FromStringAndSize(NULL, length)))
+	return NULL;
+
+
+    ENTER_ZLIB
+
+    start_total_out = self->zst.total_out;
+    self->zst.avail_out = length;
+    self->zst.next_out = (Byte *)PyString_AS_STRING(retval);
+
+    Py_BEGIN_ALLOW_THREADS
+    err = inflate(&(self->zst), Z_FINISH);
+    Py_END_ALLOW_THREADS
+
+    /* while Z_OK and the output buffer is full, there might be more output,
+       so extend the output buffer and try again */
+    while ((err == Z_OK || err == Z_BUF_ERROR) && self->zst.avail_out == 0) {
+	if (_PyString_Resize(&retval, length << 1) < 0)
+	    goto error;
+	self->zst.next_out = (Byte *)PyString_AS_STRING(retval) + length;
+	self->zst.avail_out = length;
+	length = length << 1;
+
+	Py_BEGIN_ALLOW_THREADS
+	err = inflate(&(self->zst), Z_FINISH);
+	Py_END_ALLOW_THREADS
+    }
+
+    /* If flushmode is Z_FINISH, we also have to call deflateEnd() to free
+       various data structures. Note we should only get Z_STREAM_END when
+       flushmode is Z_FINISH */
+    if (err == Z_STREAM_END) {
+	err = inflateEnd(&(self->zst));
+        self->is_initialised = 0;
+	if (err != Z_OK) {
+	    zlib_error(self->zst, err, "from inflateEnd()");
+	    Py_DECREF(retval);
+	    retval = NULL;
+	    goto error;
+	}
+    }
+    _PyString_Resize(&retval, self->zst.total_out - start_total_out);
+
+error:
+
+    LEAVE_ZLIB
+
+    return retval;
+}
+
+static PyMethodDef comp_methods[] =
+{
+    {"compress", (binaryfunc)PyZlib_objcompress, METH_VARARGS,
+                 comp_compress__doc__},
+    {"flush", (binaryfunc)PyZlib_flush, METH_VARARGS,
+              comp_flush__doc__},
+#ifdef HAVE_ZLIB_COPY
+    {"copy",  (PyCFunction)PyZlib_copy, METH_NOARGS,
+              comp_copy__doc__},
+#endif
+    {NULL, NULL}
+};
+
+static PyMethodDef Decomp_methods[] =
+{
+    {"decompress", (binaryfunc)PyZlib_objdecompress, METH_VARARGS,
+                   decomp_decompress__doc__},
+    {"flush", (binaryfunc)PyZlib_unflush, METH_VARARGS,
+              decomp_flush__doc__},
+#ifdef HAVE_ZLIB_COPY
+    {"copy",  (PyCFunction)PyZlib_uncopy, METH_NOARGS,
+              decomp_copy__doc__},
+#endif
+    {NULL, NULL}
+};
+
+static PyObject *
+Comp_getattr(compobject *self, char *name)
+{
+  /* No ENTER/LEAVE_ZLIB is necessary because this fn doesn't touch
+     internal data. */
+
+  return Py_FindMethod(comp_methods, (PyObject *)self, name);
+}
+
+static PyObject *
+Decomp_getattr(compobject *self, char *name)
+{
+    PyObject * retval;
+
+    ENTER_ZLIB
+
+    if (strcmp(name, "unused_data") == 0) {
+	Py_INCREF(self->unused_data);
+	retval = self->unused_data;
+    } else if (strcmp(name, "unconsumed_tail") == 0) {
+	Py_INCREF(self->unconsumed_tail);
+	retval = self->unconsumed_tail;
+    } else
+	retval = Py_FindMethod(Decomp_methods, (PyObject *)self, name);
+
+    LEAVE_ZLIB
+
+    return retval;
+}
+
+PyDoc_STRVAR(adler32__doc__,
+"adler32(string[, start]) -- Compute an Adler-32 checksum of string.\n"
+"\n"
+"An optional starting value can be specified.  The returned checksum is\n"
+"an integer.");
+
+static PyObject *
+PyZlib_adler32(PyObject *self, PyObject *args)
+{
+    uLong adler32val = adler32(0L, Z_NULL, 0);
+    Byte *buf;
+    int len;
+
+    if (!PyArg_ParseTuple(args, "s#|k:adler32", &buf, &len, &adler32val))
+	return NULL;
+    adler32val = adler32(adler32val, buf, len);
+    return PyInt_FromLong(adler32val);
+}
+
+PyDoc_STRVAR(crc32__doc__,
+"crc32(string[, start]) -- Compute a CRC-32 checksum of string.\n"
+"\n"
+"An optional starting value can be specified.  The returned checksum is\n"
+"an integer.");
+
+static PyObject *
+PyZlib_crc32(PyObject *self, PyObject *args)
+{
+    uLong crc32val = crc32(0L, Z_NULL, 0);
+    Byte *buf;
+    int len;
+    if (!PyArg_ParseTuple(args, "s#|k:crc32", &buf, &len, &crc32val))
+	return NULL;
+    crc32val = crc32(crc32val, buf, len);
+    return PyInt_FromLong(crc32val);
+}
+
+
+static PyMethodDef zlib_methods[] =
+{
+    {"adler32", (PyCFunction)PyZlib_adler32, METH_VARARGS,
+                adler32__doc__},
+    {"compress", (PyCFunction)PyZlib_compress,  METH_VARARGS,
+                 compress__doc__},
+    {"compressobj", (PyCFunction)PyZlib_compressobj, METH_VARARGS,
+                    compressobj__doc__},
+    {"crc32", (PyCFunction)PyZlib_crc32, METH_VARARGS,
+              crc32__doc__},
+    {"decompress", (PyCFunction)PyZlib_decompress, METH_VARARGS,
+                   decompress__doc__},
+    {"decompressobj", (PyCFunction)PyZlib_decompressobj, METH_VARARGS,
+                   decompressobj__doc__},
+    {NULL, NULL}
+};
+
+static PyTypeObject Comptype = {
+    PyObject_HEAD_INIT(0)
+    0,
+    "zlib.Compress",
+    sizeof(compobject),
+    0,
+    (destructor)Comp_dealloc,       /*tp_dealloc*/
+    0,                              /*tp_print*/
+    (getattrfunc)Comp_getattr,      /*tp_getattr*/
+    0,                              /*tp_setattr*/
+    0,                              /*tp_compare*/
+    0,                              /*tp_repr*/
+    0,                              /*tp_as_number*/
+    0,                              /*tp_as_sequence*/
+    0,                              /*tp_as_mapping*/
+};
+
+static PyTypeObject Decomptype = {
+    PyObject_HEAD_INIT(0)
+    0,
+    "zlib.Decompress",
+    sizeof(compobject),
+    0,
+    (destructor)Decomp_dealloc,     /*tp_dealloc*/
+    0,                              /*tp_print*/
+    (getattrfunc)Decomp_getattr,    /*tp_getattr*/
+    0,                              /*tp_setattr*/
+    0,                              /*tp_compare*/
+    0,                              /*tp_repr*/
+    0,                              /*tp_as_number*/
+    0,                              /*tp_as_sequence*/
+    0,                              /*tp_as_mapping*/
+};
+
+PyDoc_STRVAR(zlib_module_documentation,
+"The functions in this module allow compression and decompression using the\n"
+"zlib library, which is based on GNU zip.\n"
+"\n"
+"adler32(string[, start]) -- Compute an Adler-32 checksum.\n"
+"compress(string[, level]) -- Compress string, with compression level in 1-9.\n"
+"compressobj([level]) -- Return a compressor object.\n"
+"crc32(string[, start]) -- Compute a CRC-32 checksum.\n"
+"decompress(string,[wbits],[bufsize]) -- Decompresses a compressed string.\n"
+"decompressobj([wbits]) -- Return a decompressor object.\n"
+"\n"
+"'wbits' is window buffer size.\n"
+"Compressor objects support compress() and flush() methods; decompressor\n"
+"objects support decompress() and flush().");
+
+PyMODINIT_FUNC
+PyInit_zlib(void)
+{
+    PyObject *m, *ver;
+    Comptype.ob_type = &PyType_Type;
+    Decomptype.ob_type = &PyType_Type;
+    m = Py_InitModule4("zlib", zlib_methods,
+		       zlib_module_documentation,
+		       (PyObject*)NULL,PYTHON_API_VERSION);
+    if (m == NULL)
+	return;
+
+    ZlibError = PyErr_NewException("zlib.error", NULL, NULL);
+    if (ZlibError != NULL) {
+        Py_INCREF(ZlibError);
+	PyModule_AddObject(m, "error", ZlibError);
+    }
+    PyModule_AddIntConstant(m, "MAX_WBITS", MAX_WBITS);
+    PyModule_AddIntConstant(m, "DEFLATED", DEFLATED);
+    PyModule_AddIntConstant(m, "DEF_MEM_LEVEL", DEF_MEM_LEVEL);
+    PyModule_AddIntConstant(m, "Z_BEST_SPEED", Z_BEST_SPEED);
+    PyModule_AddIntConstant(m, "Z_BEST_COMPRESSION", Z_BEST_COMPRESSION);
+    PyModule_AddIntConstant(m, "Z_DEFAULT_COMPRESSION", Z_DEFAULT_COMPRESSION);
+    PyModule_AddIntConstant(m, "Z_FILTERED", Z_FILTERED);
+    PyModule_AddIntConstant(m, "Z_HUFFMAN_ONLY", Z_HUFFMAN_ONLY);
+    PyModule_AddIntConstant(m, "Z_DEFAULT_STRATEGY", Z_DEFAULT_STRATEGY);
+
+    PyModule_AddIntConstant(m, "Z_FINISH", Z_FINISH);
+    PyModule_AddIntConstant(m, "Z_NO_FLUSH", Z_NO_FLUSH);
+    PyModule_AddIntConstant(m, "Z_SYNC_FLUSH", Z_SYNC_FLUSH);
+    PyModule_AddIntConstant(m, "Z_FULL_FLUSH", Z_FULL_FLUSH);
+
+    ver = PyString_FromString(ZLIB_VERSION);
+    if (ver != NULL)
+	PyModule_AddObject(m, "ZLIB_VERSION", ver);
+
+    PyModule_AddStringConstant(m, "__version__", "1.0");
+
+#ifdef WITH_THREAD
+    zlib_lock = PyThread_allocate_lock();
+#endif /* WITH_THREAD */
+}

Added: vendor/Python/current/Objects/abstract.c
===================================================================
--- vendor/Python/current/Objects/abstract.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Objects/abstract.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2381 @@
+/* Abstract Object Interface (many thanks to Jim Fulton) */
+
+#include "Python.h"
+#include <ctype.h>
+#include "structmember.h" /* we need the offsetof() macro from there */
+#include "longintrepr.h"
+
+#define NEW_STYLE_NUMBER(o) PyType_HasFeature((o)->ob_type, \
+				Py_TPFLAGS_CHECKTYPES)
+
+
+/* Shorthands to return certain errors */
+
+static PyObject *
+type_error(const char *msg, PyObject *obj)
+{
+	PyErr_Format(PyExc_TypeError, msg, obj->ob_type->tp_name);
+	return NULL;
+}
+
+static PyObject *
+null_error(void)
+{
+	if (!PyErr_Occurred())
+		PyErr_SetString(PyExc_SystemError,
+				"null argument to internal routine");
+	return NULL;
+}
+
+/* Operations on any object */
+
+int
+PyObject_Cmp(PyObject *o1, PyObject *o2, int *result)
+{
+	int r;
+
+	if (o1 == NULL || o2 == NULL) {
+		null_error();
+		return -1;
+	}
+	r = PyObject_Compare(o1, o2);
+	if (PyErr_Occurred())
+		return -1;
+	*result = r;
+	return 0;
+}
+
+PyObject *
+PyObject_Type(PyObject *o)
+{
+	PyObject *v;
+
+	if (o == NULL)
+		return null_error();
+	v = (PyObject *)o->ob_type;
+	Py_INCREF(v);
+	return v;
+}
+
+Py_ssize_t
+PyObject_Size(PyObject *o)
+{
+	PySequenceMethods *m;
+
+	if (o == NULL) {
+		null_error();
+		return -1;
+	}
+
+	m = o->ob_type->tp_as_sequence;
+	if (m && m->sq_length)
+		return m->sq_length(o);
+
+	return PyMapping_Size(o);
+}
+
+#undef PyObject_Length
+Py_ssize_t
+PyObject_Length(PyObject *o)
+{
+	return PyObject_Size(o);
+}
+#define PyObject_Length PyObject_Size
+
+Py_ssize_t
+_PyObject_LengthHint(PyObject *o)
+{
+	Py_ssize_t rv = PyObject_Size(o);
+	if (rv != -1)
+		return rv;
+	if (PyErr_ExceptionMatches(PyExc_TypeError) ||
+	    PyErr_ExceptionMatches(PyExc_AttributeError)) {
+		PyObject *err_type, *err_value, *err_tb, *ro;
+
+		PyErr_Fetch(&err_type, &err_value, &err_tb);
+		ro = PyObject_CallMethod(o, "__length_hint__", NULL);
+		if (ro != NULL) {
+			rv = PyInt_AsLong(ro);
+			Py_DECREF(ro);
+			Py_XDECREF(err_type);
+			Py_XDECREF(err_value);
+			Py_XDECREF(err_tb);
+			return rv;
+		}
+		PyErr_Restore(err_type, err_value, err_tb);
+	}
+	return -1;
+}
+
+PyObject *
+PyObject_GetItem(PyObject *o, PyObject *key)
+{
+	PyMappingMethods *m;
+
+	if (o == NULL || key == NULL)
+		return null_error();
+
+	m = o->ob_type->tp_as_mapping;
+	if (m && m->mp_subscript)
+		return m->mp_subscript(o, key);
+
+	if (o->ob_type->tp_as_sequence) {
+		if (PyIndex_Check(key)) {
+			Py_ssize_t key_value;
+			key_value = PyNumber_AsSsize_t(key, PyExc_IndexError);
+			if (key_value == -1 && PyErr_Occurred())
+				return NULL;
+			return PySequence_GetItem(o, key_value);
+		}
+		else if (o->ob_type->tp_as_sequence->sq_item)
+			return type_error("sequence index must "
+					  "be integer, not '%.200s'", key);
+	}
+
+	return type_error("'%.200s' object is unsubscriptable", o);
+}
+
+int
+PyObject_SetItem(PyObject *o, PyObject *key, PyObject *value)
+{
+	PyMappingMethods *m;
+
+	if (o == NULL || key == NULL || value == NULL) {
+		null_error();
+		return -1;
+	}
+	m = o->ob_type->tp_as_mapping;
+	if (m && m->mp_ass_subscript)
+		return m->mp_ass_subscript(o, key, value);
+
+	if (o->ob_type->tp_as_sequence) {
+		if (PyIndex_Check(key)) {
+			Py_ssize_t key_value;
+			key_value = PyNumber_AsSsize_t(key, PyExc_IndexError);
+			if (key_value == -1 && PyErr_Occurred())
+				return -1;
+			return PySequence_SetItem(o, key_value, value);
+		}
+		else if (o->ob_type->tp_as_sequence->sq_ass_item) {
+			type_error("sequence index must be "
+				   "integer, not '%.200s'", key);
+			return -1;
+		}
+	}
+
+	type_error("'%.200s' object does not support item assignment", o);
+	return -1;
+}
+
+int
+PyObject_DelItem(PyObject *o, PyObject *key)
+{
+	PyMappingMethods *m;
+
+	if (o == NULL || key == NULL) {
+		null_error();
+		return -1;
+	}
+	m = o->ob_type->tp_as_mapping;
+	if (m && m->mp_ass_subscript)
+		return m->mp_ass_subscript(o, key, (PyObject*)NULL);
+
+	if (o->ob_type->tp_as_sequence) {
+		if (PyIndex_Check(key)) {
+			Py_ssize_t key_value;
+			key_value = PyNumber_AsSsize_t(key, PyExc_IndexError);
+			if (key_value == -1 && PyErr_Occurred())
+				return -1;
+			return PySequence_DelItem(o, key_value);
+		}
+		else if (o->ob_type->tp_as_sequence->sq_ass_item) {
+			type_error("sequence index must be "
+				   "integer, not '%.200s'", key);
+			return -1;
+		}
+	}
+
+	type_error("'%.200s' object does not support item deletion", o);
+	return -1;
+}
+
+int
+PyObject_DelItemString(PyObject *o, char *key)
+{
+	PyObject *okey;
+	int ret;
+
+	if (o == NULL || key == NULL) {
+		null_error();
+		return -1;
+	}
+	okey = PyString_FromString(key);
+	if (okey == NULL)
+		return -1;
+	ret = PyObject_DelItem(o, okey);
+	Py_DECREF(okey);
+	return ret;
+}
+
+int
+PyObject_AsCharBuffer(PyObject *obj,
+			  const char **buffer,
+			  Py_ssize_t *buffer_len)
+{
+	PyBufferProcs *pb;
+	char *pp;
+	Py_ssize_t len;
+
+	if (obj == NULL || buffer == NULL || buffer_len == NULL) {
+		null_error();
+		return -1;
+	}
+	pb = obj->ob_type->tp_as_buffer;
+	if (pb == NULL ||
+	     pb->bf_getcharbuffer == NULL ||
+	     pb->bf_getsegcount == NULL) {
+		PyErr_SetString(PyExc_TypeError,
+				"expected a character buffer object");
+		return -1;
+	}
+	if ((*pb->bf_getsegcount)(obj,NULL) != 1) {
+		PyErr_SetString(PyExc_TypeError,
+				"expected a single-segment buffer object");
+		return -1;
+	}
+	len = (*pb->bf_getcharbuffer)(obj, 0, &pp);
+	if (len < 0)
+		return -1;
+	*buffer = pp;
+	*buffer_len = len;
+	return 0;
+}
+
+int
+PyObject_CheckReadBuffer(PyObject *obj)
+{
+	PyBufferProcs *pb = obj->ob_type->tp_as_buffer;
+
+	if (pb == NULL ||
+	    pb->bf_getreadbuffer == NULL ||
+	    pb->bf_getsegcount == NULL ||
+	    (*pb->bf_getsegcount)(obj, NULL) != 1)
+		return 0;
+	return 1;
+}
+
+int PyObject_AsReadBuffer(PyObject *obj,
+			  const void **buffer,
+			  Py_ssize_t *buffer_len)
+{
+	PyBufferProcs *pb;
+	void *pp;
+	Py_ssize_t len;
+
+	if (obj == NULL || buffer == NULL || buffer_len == NULL) {
+		null_error();
+		return -1;
+	}
+	pb = obj->ob_type->tp_as_buffer;
+	if (pb == NULL ||
+	     pb->bf_getreadbuffer == NULL ||
+	     pb->bf_getsegcount == NULL) {
+		PyErr_SetString(PyExc_TypeError,
+				"expected a readable buffer object");
+		return -1;
+	}
+	if ((*pb->bf_getsegcount)(obj, NULL) != 1) {
+		PyErr_SetString(PyExc_TypeError,
+				"expected a single-segment buffer object");
+		return -1;
+	}
+	len = (*pb->bf_getreadbuffer)(obj, 0, &pp);
+	if (len < 0)
+		return -1;
+	*buffer = pp;
+	*buffer_len = len;
+	return 0;
+}
+
+int PyObject_AsWriteBuffer(PyObject *obj,
+			   void **buffer,
+			   Py_ssize_t *buffer_len)
+{
+	PyBufferProcs *pb;
+	void*pp;
+	Py_ssize_t len;
+
+	if (obj == NULL || buffer == NULL || buffer_len == NULL) {
+		null_error();
+		return -1;
+	}
+	pb = obj->ob_type->tp_as_buffer;
+	if (pb == NULL ||
+	     pb->bf_getwritebuffer == NULL ||
+	     pb->bf_getsegcount == NULL) {
+		PyErr_SetString(PyExc_TypeError,
+				"expected a writeable buffer object");
+		return -1;
+	}
+	if ((*pb->bf_getsegcount)(obj, NULL) != 1) {
+		PyErr_SetString(PyExc_TypeError,
+				"expected a single-segment buffer object");
+		return -1;
+	}
+	len = (*pb->bf_getwritebuffer)(obj,0,&pp);
+	if (len < 0)
+		return -1;
+	*buffer = pp;
+	*buffer_len = len;
+	return 0;
+}
+
+/* Operations on numbers */
+
+int
+PyNumber_Check(PyObject *o)
+{
+	return o && o->ob_type->tp_as_number &&
+	       (o->ob_type->tp_as_number->nb_int ||
+		o->ob_type->tp_as_number->nb_float);
+}
+
+/* Binary operators */
+
+/* New style number protocol support */
+
+#define NB_SLOT(x) offsetof(PyNumberMethods, x)
+#define NB_BINOP(nb_methods, slot) \
+		(*(binaryfunc*)(& ((char*)nb_methods)[slot]))
+#define NB_TERNOP(nb_methods, slot) \
+		(*(ternaryfunc*)(& ((char*)nb_methods)[slot]))
+
+/*
+  Calling scheme used for binary operations:
+
+  v	w	Action
+  -------------------------------------------------------------------
+  new	new	w.op(v,w)[*], v.op(v,w), w.op(v,w)
+  new	old	v.op(v,w), coerce(v,w), v.op(v,w)
+  old	new	w.op(v,w), coerce(v,w), v.op(v,w)
+  old	old	coerce(v,w), v.op(v,w)
+
+  [*] only when v->ob_type != w->ob_type && w->ob_type is a subclass of
+      v->ob_type
+
+  Legend:
+  -------
+  * new == new style number
+  * old == old style number
+  * Action indicates the order in which operations are tried until either
+    a valid result is produced or an error occurs.
+
+ */
+
+static PyObject *
+binary_op1(PyObject *v, PyObject *w, const int op_slot)
+{
+	PyObject *x;
+	binaryfunc slotv = NULL;
+	binaryfunc slotw = NULL;
+
+	if (v->ob_type->tp_as_number != NULL && NEW_STYLE_NUMBER(v))
+		slotv = NB_BINOP(v->ob_type->tp_as_number, op_slot);
+	if (w->ob_type != v->ob_type &&
+	    w->ob_type->tp_as_number != NULL && NEW_STYLE_NUMBER(w)) {
+		slotw = NB_BINOP(w->ob_type->tp_as_number, op_slot);
+		if (slotw == slotv)
+			slotw = NULL;
+	}
+	if (slotv) {
+		if (slotw && PyType_IsSubtype(w->ob_type, v->ob_type)) {
+			x = slotw(v, w);
+			if (x != Py_NotImplemented)
+				return x;
+			Py_DECREF(x); /* can't do it */
+			slotw = NULL;
+		}
+		x = slotv(v, w);
+		if (x != Py_NotImplemented)
+			return x;
+		Py_DECREF(x); /* can't do it */
+	}
+	if (slotw) {
+		x = slotw(v, w);
+		if (x != Py_NotImplemented)
+			return x;
+		Py_DECREF(x); /* can't do it */
+	}
+	if (!NEW_STYLE_NUMBER(v) || !NEW_STYLE_NUMBER(w)) {
+		int err = PyNumber_CoerceEx(&v, &w);
+		if (err < 0) {
+			return NULL;
+		}
+		if (err == 0) {
+			PyNumberMethods *mv = v->ob_type->tp_as_number;
+			if (mv) {
+				binaryfunc slot;
+				slot = NB_BINOP(mv, op_slot);
+				if (slot) {
+					x = slot(v, w);
+					Py_DECREF(v);
+					Py_DECREF(w);
+					return x;
+				}
+			}
+			/* CoerceEx incremented the reference counts */
+			Py_DECREF(v);
+			Py_DECREF(w);
+		}
+	}
+	Py_INCREF(Py_NotImplemented);
+	return Py_NotImplemented;
+}
+
+static PyObject *
+binop_type_error(PyObject *v, PyObject *w, const char *op_name)
+{
+	PyErr_Format(PyExc_TypeError,
+		     "unsupported operand type(s) for %.100s: "
+		     "'%.100s' and '%.100s'",
+		     op_name,
+		     v->ob_type->tp_name,
+		     w->ob_type->tp_name);
+	return NULL;
+}
+
+static PyObject *
+binary_op(PyObject *v, PyObject *w, const int op_slot, const char *op_name)
+{
+	PyObject *result = binary_op1(v, w, op_slot);
+	if (result == Py_NotImplemented) {
+		Py_DECREF(result);
+		return binop_type_error(v, w, op_name);
+	}
+	return result;
+}
+
+
+/*
+  Calling scheme used for ternary operations:
+
+  *** In some cases, w.op is called before v.op; see binary_op1. ***
+
+  v	w	z	Action
+  -------------------------------------------------------------------
+  new	new	new	v.op(v,w,z), w.op(v,w,z), z.op(v,w,z)
+  new	old	new	v.op(v,w,z), z.op(v,w,z), coerce(v,w,z), v.op(v,w,z)
+  old	new	new	w.op(v,w,z), z.op(v,w,z), coerce(v,w,z), v.op(v,w,z)
+  old	old	new	z.op(v,w,z), coerce(v,w,z), v.op(v,w,z)
+  new	new	old	v.op(v,w,z), w.op(v,w,z), coerce(v,w,z), v.op(v,w,z)
+  new	old	old	v.op(v,w,z), coerce(v,w,z), v.op(v,w,z)
+  old	new	old	w.op(v,w,z), coerce(v,w,z), v.op(v,w,z)
+  old	old	old	coerce(v,w,z), v.op(v,w,z)
+
+  Legend:
+  -------
+  * new == new style number
+  * old == old style number
+  * Action indicates the order in which operations are tried until either
+    a valid result is produced or an error occurs.
+  * coerce(v,w,z) actually does: coerce(v,w), coerce(v,z), coerce(w,z) and
+    only if z != Py_None; if z == Py_None, then it is treated as absent
+    variable and only coerce(v,w) is tried.
+
+ */
+
+static PyObject *
+ternary_op(PyObject *v,
+	   PyObject *w,
+	   PyObject *z,
+	   const int op_slot,
+	   const char *op_name)
+{
+	PyNumberMethods *mv, *mw, *mz;
+	PyObject *x = NULL;
+	ternaryfunc slotv = NULL;
+	ternaryfunc slotw = NULL;
+	ternaryfunc slotz = NULL;
+
+	mv = v->ob_type->tp_as_number;
+	mw = w->ob_type->tp_as_number;
+	if (mv != NULL && NEW_STYLE_NUMBER(v))
+		slotv = NB_TERNOP(mv, op_slot);
+	if (w->ob_type != v->ob_type &&
+	    mw != NULL && NEW_STYLE_NUMBER(w)) {
+		slotw = NB_TERNOP(mw, op_slot);
+		if (slotw == slotv)
+			slotw = NULL;
+	}
+	if (slotv) {
+		if (slotw && PyType_IsSubtype(w->ob_type, v->ob_type)) {
+			x = slotw(v, w, z);
+			if (x != Py_NotImplemented)
+				return x;
+			Py_DECREF(x); /* can't do it */
+			slotw = NULL;
+		}
+		x = slotv(v, w, z);
+		if (x != Py_NotImplemented)
+			return x;
+		Py_DECREF(x); /* can't do it */
+	}
+	if (slotw) {
+		x = slotw(v, w, z);
+		if (x != Py_NotImplemented)
+			return x;
+		Py_DECREF(x); /* can't do it */
+	}
+	mz = z->ob_type->tp_as_number;
+	if (mz != NULL && NEW_STYLE_NUMBER(z)) {
+		slotz = NB_TERNOP(mz, op_slot);
+		if (slotz == slotv || slotz == slotw)
+			slotz = NULL;
+		if (slotz) {
+			x = slotz(v, w, z);
+			if (x != Py_NotImplemented)
+				return x;
+			Py_DECREF(x); /* can't do it */
+		}
+	}
+
+	if (!NEW_STYLE_NUMBER(v) || !NEW_STYLE_NUMBER(w) ||
+			(z != Py_None && !NEW_STYLE_NUMBER(z))) {
+		/* we have an old style operand, coerce */
+		PyObject *v1, *z1, *w2, *z2;
+		int c;
+
+		c = PyNumber_Coerce(&v, &w);
+		if (c != 0)
+			goto error3;
+
+		/* Special case: if the third argument is None, it is
+		   treated as absent argument and not coerced. */
+		if (z == Py_None) {
+			if (v->ob_type->tp_as_number) {
+				slotz = NB_TERNOP(v->ob_type->tp_as_number,
+						  op_slot);
+				if (slotz)
+					x = slotz(v, w, z);
+				else
+					c = -1;
+			}
+			else
+				c = -1;
+			goto error2;
+		}
+		v1 = v;
+		z1 = z;
+		c = PyNumber_Coerce(&v1, &z1);
+		if (c != 0)
+			goto error2;
+		w2 = w;
+		z2 = z1;
+		c = PyNumber_Coerce(&w2, &z2);
+		if (c != 0)
+			goto error1;
+
+		if (v1->ob_type->tp_as_number != NULL) {
+			slotv = NB_TERNOP(v1->ob_type->tp_as_number,
+					  op_slot);
+			if (slotv)
+				x = slotv(v1, w2, z2);
+			else
+				c = -1;
+		}
+		else
+			c = -1;
+
+		Py_DECREF(w2);
+		Py_DECREF(z2);
+	error1:
+		Py_DECREF(v1);
+		Py_DECREF(z1);
+	error2:
+		Py_DECREF(v);
+		Py_DECREF(w);
+	error3:
+		if (c >= 0)
+			return x;
+	}
+
+	if (z == Py_None)
+		PyErr_Format(
+			PyExc_TypeError,
+			"unsupported operand type(s) for ** or pow(): "
+			"'%.100s' and '%.100s'",
+			v->ob_type->tp_name,
+			w->ob_type->tp_name);
+	else
+		PyErr_Format(
+			PyExc_TypeError,
+			"unsupported operand type(s) for pow(): "
+			"'%.100s', '%.100s', '%.100s'",
+			v->ob_type->tp_name,
+			w->ob_type->tp_name,
+			z->ob_type->tp_name);
+	return NULL;
+}
+
+#define BINARY_FUNC(func, op, op_name) \
+    PyObject * \
+    func(PyObject *v, PyObject *w) { \
+	    return binary_op(v, w, NB_SLOT(op), op_name); \
+    }
+
+BINARY_FUNC(PyNumber_Or, nb_or, "|")
+BINARY_FUNC(PyNumber_Xor, nb_xor, "^")
+BINARY_FUNC(PyNumber_And, nb_and, "&")
+BINARY_FUNC(PyNumber_Lshift, nb_lshift, "<<")
+BINARY_FUNC(PyNumber_Rshift, nb_rshift, ">>")
+BINARY_FUNC(PyNumber_Subtract, nb_subtract, "-")
+BINARY_FUNC(PyNumber_Divide, nb_divide, "/")
+BINARY_FUNC(PyNumber_Divmod, nb_divmod, "divmod()")
+
+PyObject *
+PyNumber_Add(PyObject *v, PyObject *w)
+{
+	PyObject *result = binary_op1(v, w, NB_SLOT(nb_add));
+	if (result == Py_NotImplemented) {
+		PySequenceMethods *m = v->ob_type->tp_as_sequence;
+		Py_DECREF(result);
+		if (m && m->sq_concat) {
+			return (*m->sq_concat)(v, w);
+		}
+		result = binop_type_error(v, w, "+");
+	}
+	return result;
+}
+
+static PyObject *
+sequence_repeat(ssizeargfunc repeatfunc, PyObject *seq, PyObject *n)
+{
+	Py_ssize_t count;
+	if (PyIndex_Check(n)) {
+		count = PyNumber_AsSsize_t(n, PyExc_OverflowError);
+		if (count == -1 && PyErr_Occurred())
+			return NULL;
+	}
+	else {
+		return type_error("can't multiply sequence by "
+				  "non-int of type '%.200s'", n);
+	}
+	return (*repeatfunc)(seq, count);
+}
+
+PyObject *
+PyNumber_Multiply(PyObject *v, PyObject *w)
+{
+	PyObject *result = binary_op1(v, w, NB_SLOT(nb_multiply));
+	if (result == Py_NotImplemented) {
+		PySequenceMethods *mv = v->ob_type->tp_as_sequence;
+		PySequenceMethods *mw = w->ob_type->tp_as_sequence;
+		Py_DECREF(result);
+		if  (mv && mv->sq_repeat) {
+			return sequence_repeat(mv->sq_repeat, v, w);
+		}
+		else if (mw && mw->sq_repeat) {
+			return sequence_repeat(mw->sq_repeat, w, v);
+		}
+		result = binop_type_error(v, w, "*");
+	}
+	return result;
+}
+
+PyObject *
+PyNumber_FloorDivide(PyObject *v, PyObject *w)
+{
+	/* XXX tp_flags test */
+	return binary_op(v, w, NB_SLOT(nb_floor_divide), "//");
+}
+
+PyObject *
+PyNumber_TrueDivide(PyObject *v, PyObject *w)
+{
+	/* XXX tp_flags test */
+	return binary_op(v, w, NB_SLOT(nb_true_divide), "/");
+}
+
+PyObject *
+PyNumber_Remainder(PyObject *v, PyObject *w)
+{
+	return binary_op(v, w, NB_SLOT(nb_remainder), "%");
+}
+
+PyObject *
+PyNumber_Power(PyObject *v, PyObject *w, PyObject *z)
+{
+	return ternary_op(v, w, z, NB_SLOT(nb_power), "** or pow()");
+}
+
+/* Binary in-place operators */
+
+/* The in-place operators are defined to fall back to the 'normal',
+   non in-place operations, if the in-place methods are not in place.
+
+   - If the left hand object has the appropriate struct members, and
+     they are filled, call the appropriate function and return the
+     result.  No coercion is done on the arguments; the left-hand object
+     is the one the operation is performed on, and it's up to the
+     function to deal with the right-hand object.
+
+   - Otherwise, in-place modification is not supported. Handle it exactly as
+     a non in-place operation of the same kind.
+
+   */
+
+#define HASINPLACE(t) \
+	PyType_HasFeature((t)->ob_type, Py_TPFLAGS_HAVE_INPLACEOPS)
+
+static PyObject *
+binary_iop1(PyObject *v, PyObject *w, const int iop_slot, const int op_slot)
+{
+	PyNumberMethods *mv = v->ob_type->tp_as_number;
+	if (mv != NULL && HASINPLACE(v)) {
+		binaryfunc slot = NB_BINOP(mv, iop_slot);
+		if (slot) {
+			PyObject *x = (slot)(v, w);
+			if (x != Py_NotImplemented) {
+				return x;
+			}
+			Py_DECREF(x);
+		}
+	}
+	return binary_op1(v, w, op_slot);
+}
+
+static PyObject *
+binary_iop(PyObject *v, PyObject *w, const int iop_slot, const int op_slot,
+		const char *op_name)
+{
+	PyObject *result = binary_iop1(v, w, iop_slot, op_slot);
+	if (result == Py_NotImplemented) {
+		Py_DECREF(result);
+		return binop_type_error(v, w, op_name);
+	}
+	return result;
+}
+
+#define INPLACE_BINOP(func, iop, op, op_name) \
+	PyObject * \
+	func(PyObject *v, PyObject *w) { \
+		return binary_iop(v, w, NB_SLOT(iop), NB_SLOT(op), op_name); \
+	}
+
+INPLACE_BINOP(PyNumber_InPlaceOr, nb_inplace_or, nb_or, "|=")
+INPLACE_BINOP(PyNumber_InPlaceXor, nb_inplace_xor, nb_xor, "^=")
+INPLACE_BINOP(PyNumber_InPlaceAnd, nb_inplace_and, nb_and, "&=")
+INPLACE_BINOP(PyNumber_InPlaceLshift, nb_inplace_lshift, nb_lshift, "<<=")
+INPLACE_BINOP(PyNumber_InPlaceRshift, nb_inplace_rshift, nb_rshift, ">>=")
+INPLACE_BINOP(PyNumber_InPlaceSubtract, nb_inplace_subtract, nb_subtract, "-=")
+INPLACE_BINOP(PyNumber_InPlaceDivide, nb_inplace_divide, nb_divide, "/=")
+
+PyObject *
+PyNumber_InPlaceFloorDivide(PyObject *v, PyObject *w)
+{
+	/* XXX tp_flags test */
+	return binary_iop(v, w, NB_SLOT(nb_inplace_floor_divide),
+			  NB_SLOT(nb_floor_divide), "//=");
+}
+
+PyObject *
+PyNumber_InPlaceTrueDivide(PyObject *v, PyObject *w)
+{
+	/* XXX tp_flags test */
+	return binary_iop(v, w, NB_SLOT(nb_inplace_true_divide),
+			  NB_SLOT(nb_true_divide), "/=");
+}
+
+PyObject *
+PyNumber_InPlaceAdd(PyObject *v, PyObject *w)
+{
+	PyObject *result = binary_iop1(v, w, NB_SLOT(nb_inplace_add),
+				       NB_SLOT(nb_add));
+	if (result == Py_NotImplemented) {
+		PySequenceMethods *m = v->ob_type->tp_as_sequence;
+		Py_DECREF(result);
+		if (m != NULL) {
+			binaryfunc f = NULL;
+			if (HASINPLACE(v))
+				f = m->sq_inplace_concat;
+			if (f == NULL)
+				f = m->sq_concat;
+			if (f != NULL)
+				return (*f)(v, w);
+		}
+		result = binop_type_error(v, w, "+=");
+	}
+	return result;
+}
+
+PyObject *
+PyNumber_InPlaceMultiply(PyObject *v, PyObject *w)
+{
+	PyObject *result = binary_iop1(v, w, NB_SLOT(nb_inplace_multiply),
+				       NB_SLOT(nb_multiply));
+	if (result == Py_NotImplemented) {
+		ssizeargfunc f = NULL;
+		PySequenceMethods *mv = v->ob_type->tp_as_sequence;
+		PySequenceMethods *mw = w->ob_type->tp_as_sequence;
+		Py_DECREF(result);
+		if (mv != NULL) {
+			if (HASINPLACE(v))
+				f = mv->sq_inplace_repeat;
+			if (f == NULL)
+				f = mv->sq_repeat;
+			if (f != NULL)
+				return sequence_repeat(f, v, w);
+		}
+		else if (mw != NULL) {
+			/* Note that the right hand operand should not be
+			 * mutated in this case so sq_inplace_repeat is not
+			 * used. */
+			if (mw->sq_repeat)
+				return sequence_repeat(mw->sq_repeat, w, v);
+		}
+		result = binop_type_error(v, w, "*=");
+	}
+	return result;
+}
+
+PyObject *
+PyNumber_InPlaceRemainder(PyObject *v, PyObject *w)
+{
+	return binary_iop(v, w, NB_SLOT(nb_inplace_remainder),
+				NB_SLOT(nb_remainder), "%=");
+}
+
+PyObject *
+PyNumber_InPlacePower(PyObject *v, PyObject *w, PyObject *z)
+{
+	if (HASINPLACE(v) && v->ob_type->tp_as_number &&
+	    v->ob_type->tp_as_number->nb_inplace_power != NULL) {
+		return ternary_op(v, w, z, NB_SLOT(nb_inplace_power), "**=");
+	}
+	else {
+		return ternary_op(v, w, z, NB_SLOT(nb_power), "**=");
+	}
+}
+
+
+/* Unary operators and functions */
+
+PyObject *
+PyNumber_Negative(PyObject *o)
+{
+	PyNumberMethods *m;
+
+	if (o == NULL)
+		return null_error();
+	m = o->ob_type->tp_as_number;
+	if (m && m->nb_negative)
+		return (*m->nb_negative)(o);
+
+	return type_error("bad operand type for unary -: '%.200s'", o);
+}
+
+PyObject *
+PyNumber_Positive(PyObject *o)
+{
+	PyNumberMethods *m;
+
+	if (o == NULL)
+		return null_error();
+	m = o->ob_type->tp_as_number;
+	if (m && m->nb_positive)
+		return (*m->nb_positive)(o);
+
+	return type_error("bad operand type for unary +: '%.200s'", o);
+}
+
+PyObject *
+PyNumber_Invert(PyObject *o)
+{
+	PyNumberMethods *m;
+
+	if (o == NULL)
+		return null_error();
+	m = o->ob_type->tp_as_number;
+	if (m && m->nb_invert)
+		return (*m->nb_invert)(o);
+
+	return type_error("bad operand type for unary ~: '%.200s'", o);
+}
+
+PyObject *
+PyNumber_Absolute(PyObject *o)
+{
+	PyNumberMethods *m;
+
+	if (o == NULL)
+		return null_error();
+	m = o->ob_type->tp_as_number;
+	if (m && m->nb_absolute)
+		return m->nb_absolute(o);
+
+	return type_error("bad operand type for abs(): '%.200s'", o);
+}
+
+/* Add a check for embedded NULL-bytes in the argument. */
+static PyObject *
+int_from_string(const char *s, Py_ssize_t len)
+{
+	char *end;
+	PyObject *x;
+
+	x = PyInt_FromString((char*)s, &end, 10);
+	if (x == NULL)
+		return NULL;
+	if (end != s + len) {
+		PyErr_SetString(PyExc_ValueError,
+				"null byte in argument for int()");
+		Py_DECREF(x);
+		return NULL;
+	}
+	return x;
+}
+
+/* Return a Python Int or Long from the object item 
+   Raise TypeError if the result is not an int-or-long
+   or if the object cannot be interpreted as an index. 
+*/
+PyObject *
+PyNumber_Index(PyObject *item)
+{
+	PyObject *result = NULL;
+	if (item == NULL)
+		return null_error();
+	if (PyInt_Check(item) || PyLong_Check(item)) {
+		Py_INCREF(item);
+		return item;
+	}
+	if (PyIndex_Check(item)) {
+		result = item->ob_type->tp_as_number->nb_index(item);
+		if (result &&
+		    !PyInt_Check(result) && !PyLong_Check(result)) {
+			PyErr_Format(PyExc_TypeError,
+				     "__index__ returned non-(int,long) " \
+				     "(type %.200s)",
+				     result->ob_type->tp_name);
+			Py_DECREF(result);
+			return NULL;
+		}
+	}
+	else {
+		PyErr_Format(PyExc_TypeError,
+			     "'%.200s' object cannot be interpreted "
+			     "as an index", item->ob_type->tp_name);
+	}
+	return result;
+}
+
+/* Return an error on Overflow only if err is not NULL*/
+
+Py_ssize_t
+PyNumber_AsSsize_t(PyObject *item, PyObject *err)
+{
+	Py_ssize_t result;
+	PyObject *runerr;
+	PyObject *value = PyNumber_Index(item);
+	if (value == NULL)
+		return -1;
+
+	/* We're done if PyInt_AsSsize_t() returns without error. */
+	result = PyInt_AsSsize_t(value);
+	if (result != -1 || !(runerr = PyErr_Occurred()))
+		goto finish;
+
+	/* Error handling code -- only manage OverflowError differently */
+	if (!PyErr_GivenExceptionMatches(runerr, PyExc_OverflowError)) 
+		goto finish;
+
+	PyErr_Clear();
+	/* If no error-handling desired then the default clipping 
+	   is sufficient.
+	 */
+	if (!err) {
+		assert(PyLong_Check(value));
+		/* Whether or not it is less than or equal to 
+		   zero is determined by the sign of ob_size
+		*/
+		if (_PyLong_Sign(value) < 0) 
+			result = PY_SSIZE_T_MIN;
+		else
+			result = PY_SSIZE_T_MAX;
+	}
+	else {
+		/* Otherwise replace the error with caller's error object. */
+		PyErr_Format(err,
+			     "cannot fit '%.200s' into an index-sized integer", 
+			     item->ob_type->tp_name); 
+	}
+	
+ finish:
+	Py_DECREF(value);
+	return result;
+}
+
+
+PyObject *
+PyNumber_Int(PyObject *o)
+{
+	PyNumberMethods *m;
+	const char *buffer;
+	Py_ssize_t buffer_len;
+
+	if (o == NULL)
+		return null_error();
+	if (PyInt_CheckExact(o)) {
+		Py_INCREF(o);
+		return o;
+	}
+	m = o->ob_type->tp_as_number;
+	if (m && m->nb_int) { /* This should include subclasses of int */
+		PyObject *res = m->nb_int(o);
+		if (res && (!PyInt_Check(res) && !PyLong_Check(res))) {
+			PyErr_Format(PyExc_TypeError,
+				     "__int__ returned non-int (type %.200s)",
+				     res->ob_type->tp_name);
+			Py_DECREF(res);
+			return NULL;
+		}
+		return res;
+	}
+	if (PyInt_Check(o)) { /* A int subclass without nb_int */
+		PyIntObject *io = (PyIntObject*)o;
+		return PyInt_FromLong(io->ob_ival);
+	}
+	if (PyString_Check(o))
+		return int_from_string(PyString_AS_STRING(o),
+				       PyString_GET_SIZE(o));
+#ifdef Py_USING_UNICODE
+	if (PyUnicode_Check(o))
+		return PyInt_FromUnicode(PyUnicode_AS_UNICODE(o),
+					 PyUnicode_GET_SIZE(o),
+					 10);
+#endif
+	if (!PyObject_AsCharBuffer(o, &buffer, &buffer_len))
+		return int_from_string((char*)buffer, buffer_len);
+
+	return type_error("int() argument must be a string or a "
+			  "number, not '%.200s'", o);
+}
+
+/* Add a check for embedded NULL-bytes in the argument. */
+static PyObject *
+long_from_string(const char *s, Py_ssize_t len)
+{
+	char *end;
+	PyObject *x;
+
+	x = PyLong_FromString((char*)s, &end, 10);
+	if (x == NULL)
+		return NULL;
+	if (end != s + len) {
+		PyErr_SetString(PyExc_ValueError,
+				"null byte in argument for long()");
+		Py_DECREF(x);
+		return NULL;
+	}
+	return x;
+}
+
+PyObject *
+PyNumber_Long(PyObject *o)
+{
+	PyNumberMethods *m;
+	const char *buffer;
+	Py_ssize_t buffer_len;
+
+	if (o == NULL)
+		return null_error();
+	m = o->ob_type->tp_as_number;
+	if (m && m->nb_long) { /* This should include subclasses of long */
+		PyObject *res = m->nb_long(o);
+		if (res && (!PyInt_Check(res) && !PyLong_Check(res))) {
+			PyErr_Format(PyExc_TypeError,
+				     "__long__ returned non-long (type %.200s)",
+				     res->ob_type->tp_name);
+			Py_DECREF(res);
+			return NULL;
+		}
+		return res;
+	}
+	if (PyLong_Check(o)) /* A long subclass without nb_long */
+		return _PyLong_Copy((PyLongObject *)o);
+	if (PyString_Check(o))
+		/* need to do extra error checking that PyLong_FromString()
+		 * doesn't do.  In particular long('9.5') must raise an
+		 * exception, not truncate the float.
+		 */
+		return long_from_string(PyString_AS_STRING(o),
+					PyString_GET_SIZE(o));
+#ifdef Py_USING_UNICODE
+	if (PyUnicode_Check(o))
+		/* The above check is done in PyLong_FromUnicode(). */
+		return PyLong_FromUnicode(PyUnicode_AS_UNICODE(o),
+					  PyUnicode_GET_SIZE(o),
+					  10);
+#endif
+	if (!PyObject_AsCharBuffer(o, &buffer, &buffer_len))
+		return long_from_string(buffer, buffer_len);
+
+	return type_error("long() argument must be a string or a "
+			  "number, not '%.200s'", o);
+}
+
+PyObject *
+PyNumber_Float(PyObject *o)
+{
+	PyNumberMethods *m;
+
+	if (o == NULL)
+		return null_error();
+	m = o->ob_type->tp_as_number;
+	if (m && m->nb_float) { /* This should include subclasses of float */
+		PyObject *res = m->nb_float(o);
+		if (res && !PyFloat_Check(res)) {
+			PyErr_Format(PyExc_TypeError,
+		          "__float__ returned non-float (type %.200s)",
+		          res->ob_type->tp_name);
+			Py_DECREF(res);
+			return NULL;
+		}
+		return res;
+	}
+	if (PyFloat_Check(o)) { /* A float subclass with nb_float == NULL */
+		PyFloatObject *po = (PyFloatObject *)o;
+		return PyFloat_FromDouble(po->ob_fval);
+	}
+	return PyFloat_FromString(o, NULL);
+}
+
+/* Operations on sequences */
+
+int
+PySequence_Check(PyObject *s)
+{
+	if (s && PyInstance_Check(s))
+		return PyObject_HasAttrString(s, "__getitem__");
+	if (PyObject_IsInstance(s, (PyObject *)&PyDict_Type))
+		return 0;
+	return s != NULL && s->ob_type->tp_as_sequence &&
+		s->ob_type->tp_as_sequence->sq_item != NULL;
+}
+
+Py_ssize_t
+PySequence_Size(PyObject *s)
+{
+	PySequenceMethods *m;
+
+	if (s == NULL) {
+		null_error();
+		return -1;
+	}
+
+	m = s->ob_type->tp_as_sequence;
+	if (m && m->sq_length)
+		return m->sq_length(s);
+
+	type_error("object of type '%.200s' has no len()", s);
+	return -1;
+}
+
+#undef PySequence_Length
+Py_ssize_t
+PySequence_Length(PyObject *s)
+{
+	return PySequence_Size(s);
+}
+#define PySequence_Length PySequence_Size
+
+PyObject *
+PySequence_Concat(PyObject *s, PyObject *o)
+{
+	PySequenceMethods *m;
+
+	if (s == NULL || o == NULL)
+		return null_error();
+
+	m = s->ob_type->tp_as_sequence;
+	if (m && m->sq_concat)
+		return m->sq_concat(s, o);
+
+	/* Instances of user classes defining an __add__() method only
+	   have an nb_add slot, not an sq_concat slot.  So we fall back
+	   to nb_add if both arguments appear to be sequences. */
+	if (PySequence_Check(s) && PySequence_Check(o)) {
+		PyObject *result = binary_op1(s, o, NB_SLOT(nb_add));
+		if (result != Py_NotImplemented)
+			return result;
+		Py_DECREF(result);
+	}
+	return type_error("'%.200s' object can't be concatenated", s);
+}
+
+PyObject *
+PySequence_Repeat(PyObject *o, Py_ssize_t count)
+{
+	PySequenceMethods *m;
+
+	if (o == NULL)
+		return null_error();
+
+	m = o->ob_type->tp_as_sequence;
+	if (m && m->sq_repeat)
+		return m->sq_repeat(o, count);
+
+	/* Instances of user classes defining a __mul__() method only
+	   have an nb_multiply slot, not an sq_repeat slot. so we fall back
+	   to nb_multiply if o appears to be a sequence. */
+	if (PySequence_Check(o)) {
+		PyObject *n, *result;
+		n = PyInt_FromSsize_t(count);
+		if (n == NULL)
+			return NULL;
+		result = binary_op1(o, n, NB_SLOT(nb_multiply));
+		Py_DECREF(n);
+		if (result != Py_NotImplemented)
+			return result;
+		Py_DECREF(result);
+	}
+	return type_error("'%.200s' object can't be repeated", o);
+}
+
+PyObject *
+PySequence_InPlaceConcat(PyObject *s, PyObject *o)
+{
+	PySequenceMethods *m;
+
+	if (s == NULL || o == NULL)
+		return null_error();
+
+	m = s->ob_type->tp_as_sequence;
+	if (m && HASINPLACE(s) && m->sq_inplace_concat)
+		return m->sq_inplace_concat(s, o);
+	if (m && m->sq_concat)
+		return m->sq_concat(s, o);
+
+	if (PySequence_Check(s) && PySequence_Check(o)) {
+		PyObject *result = binary_iop1(s, o, NB_SLOT(nb_inplace_add),
+					       NB_SLOT(nb_add));
+		if (result != Py_NotImplemented)
+			return result;
+		Py_DECREF(result);
+	}
+	return type_error("'%.200s' object can't be concatenated", s);
+}
+
+PyObject *
+PySequence_InPlaceRepeat(PyObject *o, Py_ssize_t count)
+{
+	PySequenceMethods *m;
+
+	if (o == NULL)
+		return null_error();
+
+	m = o->ob_type->tp_as_sequence;
+	if (m && HASINPLACE(o) && m->sq_inplace_repeat)
+		return m->sq_inplace_repeat(o, count);
+	if (m && m->sq_repeat)
+		return m->sq_repeat(o, count);
+
+	if (PySequence_Check(o)) {
+		PyObject *n, *result;
+		n = PyInt_FromSsize_t(count);
+		if (n == NULL)
+			return NULL;
+		result = binary_iop1(o, n, NB_SLOT(nb_inplace_multiply),
+				     NB_SLOT(nb_multiply));
+		Py_DECREF(n);
+		if (result != Py_NotImplemented)
+			return result;
+		Py_DECREF(result);
+	}
+	return type_error("'%.200s' object can't be repeated", o);
+}
+
+PyObject *
+PySequence_GetItem(PyObject *s, Py_ssize_t i)
+{
+	PySequenceMethods *m;
+
+	if (s == NULL)
+		return null_error();
+
+	m = s->ob_type->tp_as_sequence;
+	if (m && m->sq_item) {
+		if (i < 0) {
+			if (m->sq_length) {
+				Py_ssize_t l = (*m->sq_length)(s);
+				if (l < 0)
+					return NULL;
+				i += l;
+			}
+		}
+		return m->sq_item(s, i);
+	}
+
+	return type_error("'%.200s' object is unindexable", s);
+}
+
+PyObject *
+PySequence_GetSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2)
+{
+	PySequenceMethods *m;
+	PyMappingMethods *mp;
+
+	if (!s) return null_error();
+
+	m = s->ob_type->tp_as_sequence;
+	if (m && m->sq_slice) {
+		if (i1 < 0 || i2 < 0) {
+			if (m->sq_length) {
+				Py_ssize_t l = (*m->sq_length)(s);
+				if (l < 0)
+					return NULL;
+				if (i1 < 0)
+					i1 += l;
+				if (i2 < 0)
+					i2 += l;
+			}
+		}
+		return m->sq_slice(s, i1, i2);
+	} else if ((mp = s->ob_type->tp_as_mapping) && mp->mp_subscript) {
+		PyObject *res;
+		PyObject *slice = _PySlice_FromIndices(i1, i2);
+		if (!slice)
+			return NULL;
+		res = mp->mp_subscript(s, slice);
+		Py_DECREF(slice);
+		return res;
+	}
+
+	return type_error("'%.200s' object is unsliceable", s);
+}
+
+int
+PySequence_SetItem(PyObject *s, Py_ssize_t i, PyObject *o)
+{
+	PySequenceMethods *m;
+
+	if (s == NULL) {
+		null_error();
+		return -1;
+	}
+
+	m = s->ob_type->tp_as_sequence;
+	if (m && m->sq_ass_item) {
+		if (i < 0) {
+			if (m->sq_length) {
+				Py_ssize_t l = (*m->sq_length)(s);
+				if (l < 0)
+					return -1;
+				i += l;
+			}
+		}
+		return m->sq_ass_item(s, i, o);
+	}
+
+	type_error("'%.200s' object does not support item assignment", s);
+	return -1;
+}
+
+int
+PySequence_DelItem(PyObject *s, Py_ssize_t i)
+{
+	PySequenceMethods *m;
+
+	if (s == NULL) {
+		null_error();
+		return -1;
+	}
+
+	m = s->ob_type->tp_as_sequence;
+	if (m && m->sq_ass_item) {
+		if (i < 0) {
+			if (m->sq_length) {
+				Py_ssize_t l = (*m->sq_length)(s);
+				if (l < 0)
+					return -1;
+				i += l;
+			}
+		}
+		return m->sq_ass_item(s, i, (PyObject *)NULL);
+	}
+
+	type_error("'%.200s' object doesn't support item deletion", s);
+	return -1;
+}
+
+int
+PySequence_SetSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2, PyObject *o)
+{
+	PySequenceMethods *m;
+	PyMappingMethods *mp;
+
+	if (s == NULL) {
+		null_error();
+		return -1;
+	}
+
+	m = s->ob_type->tp_as_sequence;
+	if (m && m->sq_ass_slice) {
+		if (i1 < 0 || i2 < 0) {
+			if (m->sq_length) {
+				Py_ssize_t l = (*m->sq_length)(s);
+				if (l < 0)
+					return -1;
+				if (i1 < 0)
+					i1 += l;
+				if (i2 < 0)
+					i2 += l;
+			}
+		}
+		return m->sq_ass_slice(s, i1, i2, o);
+	} else if ((mp = s->ob_type->tp_as_mapping) && mp->mp_ass_subscript) {
+		int res;
+		PyObject *slice = _PySlice_FromIndices(i1, i2);
+		if (!slice)
+			return -1;
+		res = mp->mp_ass_subscript(s, slice, o);
+		Py_DECREF(slice);
+		return res;
+	}
+
+	type_error("'%.200s' object doesn't support slice assignment", s);
+	return -1;
+}
+
+int
+PySequence_DelSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2)
+{
+	PySequenceMethods *m;
+
+	if (s == NULL) {
+		null_error();
+		return -1;
+	}
+
+	m = s->ob_type->tp_as_sequence;
+	if (m && m->sq_ass_slice) {
+		if (i1 < 0 || i2 < 0) {
+			if (m->sq_length) {
+				Py_ssize_t l = (*m->sq_length)(s);
+				if (l < 0)
+					return -1;
+				if (i1 < 0)
+					i1 += l;
+				if (i2 < 0)
+					i2 += l;
+			}
+		}
+		return m->sq_ass_slice(s, i1, i2, (PyObject *)NULL);
+	}
+	type_error("'%.200s' object doesn't support slice deletion", s);
+	return -1;
+}
+
+PyObject *
+PySequence_Tuple(PyObject *v)
+{
+	PyObject *it;  /* iter(v) */
+	Py_ssize_t n;         /* guess for result tuple size */
+	PyObject *result;
+	Py_ssize_t j;
+
+	if (v == NULL)
+		return null_error();
+
+	/* Special-case the common tuple and list cases, for efficiency. */
+	if (PyTuple_CheckExact(v)) {
+		/* Note that we can't know whether it's safe to return
+		   a tuple *subclass* instance as-is, hence the restriction
+		   to exact tuples here.  In contrast, lists always make
+		   a copy, so there's no need for exactness below. */
+		Py_INCREF(v);
+		return v;
+	}
+	if (PyList_Check(v))
+		return PyList_AsTuple(v);
+
+	/* Get iterator. */
+	it = PyObject_GetIter(v);
+	if (it == NULL)
+		return NULL;
+
+	/* Guess result size and allocate space. */
+	n = _PyObject_LengthHint(v);
+	if (n < 0) {
+		if (!PyErr_ExceptionMatches(PyExc_TypeError)  &&
+		    !PyErr_ExceptionMatches(PyExc_AttributeError)) {
+			Py_DECREF(it);
+			return NULL;
+		}
+		PyErr_Clear();
+		n = 10;  /* arbitrary */
+	}
+	result = PyTuple_New(n);
+	if (result == NULL)
+		goto Fail;
+
+	/* Fill the tuple. */
+	for (j = 0; ; ++j) {
+		PyObject *item = PyIter_Next(it);
+		if (item == NULL) {
+			if (PyErr_Occurred())
+				goto Fail;
+			break;
+		}
+		if (j >= n) {
+			Py_ssize_t oldn = n;
+			/* The over-allocation strategy can grow a bit faster
+			   than for lists because unlike lists the 
+			   over-allocation isn't permanent -- we reclaim
+			   the excess before the end of this routine.
+			   So, grow by ten and then add 25%.
+			*/
+			n += 10;
+			n += n >> 2;
+			if (n < oldn) {
+				/* Check for overflow */
+				PyErr_NoMemory();
+				Py_DECREF(item);
+				goto Fail; 
+			}
+			if (_PyTuple_Resize(&result, n) != 0) {
+				Py_DECREF(item);
+				goto Fail;
+			}
+		}
+		PyTuple_SET_ITEM(result, j, item);
+	}
+
+	/* Cut tuple back if guess was too large. */
+	if (j < n &&
+	    _PyTuple_Resize(&result, j) != 0)
+		goto Fail;
+
+	Py_DECREF(it);
+	return result;
+
+Fail:
+	Py_XDECREF(result);
+	Py_DECREF(it);
+	return NULL;
+}
+
+PyObject *
+PySequence_List(PyObject *v)
+{
+	PyObject *result;  /* result list */
+	PyObject *rv;      /* return value from PyList_Extend */
+
+	if (v == NULL)
+		return null_error();
+
+	result = PyList_New(0);
+	if (result == NULL)
+		return NULL;
+
+	rv = _PyList_Extend((PyListObject *)result, v);
+	if (rv == NULL) {
+		Py_DECREF(result);
+		return NULL;
+	}
+	Py_DECREF(rv);
+	return result;
+}
+
+PyObject *
+PySequence_Fast(PyObject *v, const char *m)
+{
+	PyObject *it;
+
+	if (v == NULL)
+		return null_error();
+
+	if (PyList_CheckExact(v) || PyTuple_CheckExact(v)) {
+		Py_INCREF(v);
+		return v;
+	}
+
+ 	it = PyObject_GetIter(v);
+	if (it == NULL) {
+		if (PyErr_ExceptionMatches(PyExc_TypeError))
+			PyErr_SetString(PyExc_TypeError, m);
+		return NULL;
+	}
+
+	v = PySequence_List(it);
+	Py_DECREF(it);
+
+	return v;
+}
+
+/* Iterate over seq.  Result depends on the operation:
+   PY_ITERSEARCH_COUNT:  -1 if error, else # of times obj appears in seq.
+   PY_ITERSEARCH_INDEX:  0-based index of first occurence of obj in seq;
+   	set ValueError and return -1 if none found; also return -1 on error.
+   Py_ITERSEARCH_CONTAINS:  return 1 if obj in seq, else 0; -1 on error.
+*/
+Py_ssize_t
+_PySequence_IterSearch(PyObject *seq, PyObject *obj, int operation)
+{
+	Py_ssize_t n;
+	int wrapped;  /* for PY_ITERSEARCH_INDEX, true iff n wrapped around */
+	PyObject *it;  /* iter(seq) */
+
+	if (seq == NULL || obj == NULL) {
+		null_error();
+		return -1;
+	}
+
+	it = PyObject_GetIter(seq);
+	if (it == NULL) {
+		type_error("argument of type '%.200s' is not iterable", seq);
+		return -1;
+	}
+
+	n = wrapped = 0;
+	for (;;) {
+		int cmp;
+		PyObject *item = PyIter_Next(it);
+		if (item == NULL) {
+			if (PyErr_Occurred())
+				goto Fail;
+			break;
+		}
+
+		cmp = PyObject_RichCompareBool(obj, item, Py_EQ);
+		Py_DECREF(item);
+		if (cmp < 0)
+			goto Fail;
+		if (cmp > 0) {
+			switch (operation) {
+			case PY_ITERSEARCH_COUNT:
+				if (n == PY_SSIZE_T_MAX) {
+					PyErr_SetString(PyExc_OverflowError,
+					       "count exceeds C integer size");
+					goto Fail;
+				}
+				++n;
+				break;
+
+			case PY_ITERSEARCH_INDEX:
+				if (wrapped) {
+					PyErr_SetString(PyExc_OverflowError,
+					       "index exceeds C integer size");
+					goto Fail;
+				}
+				goto Done;
+
+			case PY_ITERSEARCH_CONTAINS:
+				n = 1;
+				goto Done;
+
+			default:
+				assert(!"unknown operation");
+			}
+		}
+
+		if (operation == PY_ITERSEARCH_INDEX) {
+			if (n == PY_SSIZE_T_MAX)
+				wrapped = 1;
+			++n;
+		}
+	}
+
+	if (operation != PY_ITERSEARCH_INDEX)
+		goto Done;
+
+	PyErr_SetString(PyExc_ValueError,
+		        "sequence.index(x): x not in sequence");
+	/* fall into failure code */
+Fail:
+	n = -1;
+	/* fall through */
+Done:
+	Py_DECREF(it);
+	return n;
+
+}
+
+/* Return # of times o appears in s. */
+Py_ssize_t
+PySequence_Count(PyObject *s, PyObject *o)
+{
+	return _PySequence_IterSearch(s, o, PY_ITERSEARCH_COUNT);
+}
+
+/* Return -1 if error; 1 if ob in seq; 0 if ob not in seq.
+ * Use sq_contains if possible, else defer to _PySequence_IterSearch().
+ */
+int
+PySequence_Contains(PyObject *seq, PyObject *ob)
+{
+	Py_ssize_t result;
+	if (PyType_HasFeature(seq->ob_type, Py_TPFLAGS_HAVE_SEQUENCE_IN)) {
+		PySequenceMethods *sqm = seq->ob_type->tp_as_sequence;
+	        if (sqm != NULL && sqm->sq_contains != NULL)
+			return (*sqm->sq_contains)(seq, ob);
+	}
+	result = _PySequence_IterSearch(seq, ob, PY_ITERSEARCH_CONTAINS);
+	return Py_SAFE_DOWNCAST(result, Py_ssize_t, int);
+}
+
+/* Backwards compatibility */
+#undef PySequence_In
+int
+PySequence_In(PyObject *w, PyObject *v)
+{
+	return PySequence_Contains(w, v);
+}
+
+Py_ssize_t
+PySequence_Index(PyObject *s, PyObject *o)
+{
+	return _PySequence_IterSearch(s, o, PY_ITERSEARCH_INDEX);
+}
+
+/* Operations on mappings */
+
+int
+PyMapping_Check(PyObject *o)
+{
+	if (o && PyInstance_Check(o))
+		return PyObject_HasAttrString(o, "__getitem__");
+
+	return  o && o->ob_type->tp_as_mapping &&
+		o->ob_type->tp_as_mapping->mp_subscript &&
+		!(o->ob_type->tp_as_sequence && 
+		  o->ob_type->tp_as_sequence->sq_slice);
+}
+
+Py_ssize_t
+PyMapping_Size(PyObject *o)
+{
+	PyMappingMethods *m;
+
+	if (o == NULL) {
+		null_error();
+		return -1;
+	}
+
+	m = o->ob_type->tp_as_mapping;
+	if (m && m->mp_length)
+		return m->mp_length(o);
+
+	type_error("object of type '%.200s' has no len()", o);
+	return -1;
+}
+
+#undef PyMapping_Length
+Py_ssize_t
+PyMapping_Length(PyObject *o)
+{
+	return PyMapping_Size(o);
+}
+#define PyMapping_Length PyMapping_Size
+
+PyObject *
+PyMapping_GetItemString(PyObject *o, char *key)
+{
+	PyObject *okey, *r;
+
+	if (key == NULL)
+		return null_error();
+
+	okey = PyString_FromString(key);
+	if (okey == NULL)
+		return NULL;
+	r = PyObject_GetItem(o, okey);
+	Py_DECREF(okey);
+	return r;
+}
+
+int
+PyMapping_SetItemString(PyObject *o, char *key, PyObject *value)
+{
+	PyObject *okey;
+	int r;
+
+	if (key == NULL) {
+		null_error();
+		return -1;
+	}
+
+	okey = PyString_FromString(key);
+	if (okey == NULL)
+		return -1;
+	r = PyObject_SetItem(o, okey, value);
+	Py_DECREF(okey);
+	return r;
+}
+
+int
+PyMapping_HasKeyString(PyObject *o, char *key)
+{
+	PyObject *v;
+
+	v = PyMapping_GetItemString(o, key);
+	if (v) {
+		Py_DECREF(v);
+		return 1;
+	}
+	PyErr_Clear();
+	return 0;
+}
+
+int
+PyMapping_HasKey(PyObject *o, PyObject *key)
+{
+	PyObject *v;
+
+	v = PyObject_GetItem(o, key);
+	if (v) {
+		Py_DECREF(v);
+		return 1;
+	}
+	PyErr_Clear();
+	return 0;
+}
+
+/* Operations on callable objects */
+
+/* XXX PyCallable_Check() is in object.c */
+
+PyObject *
+PyObject_CallObject(PyObject *o, PyObject *a)
+{
+	return PyEval_CallObjectWithKeywords(o, a, NULL);
+}
+
+PyObject *
+PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw)
+{
+        ternaryfunc call;
+
+	if ((call = func->ob_type->tp_call) != NULL) {
+		PyObject *result = (*call)(func, arg, kw);
+		if (result == NULL && !PyErr_Occurred())
+			PyErr_SetString(
+				PyExc_SystemError,
+				"NULL result without error in PyObject_Call");
+		return result;
+	}
+	PyErr_Format(PyExc_TypeError, "'%.200s' object is not callable",
+		     func->ob_type->tp_name);
+	return NULL;
+}
+
+static PyObject*
+call_function_tail(PyObject *callable, PyObject *args)
+{
+	PyObject *retval;
+
+	if (args == NULL)
+		return NULL;
+
+	if (!PyTuple_Check(args)) {
+		PyObject *a;
+
+		a = PyTuple_New(1);
+		if (a == NULL) {
+			Py_DECREF(args);
+			return NULL;
+		}
+		PyTuple_SET_ITEM(a, 0, args);
+		args = a;
+	}
+	retval = PyObject_Call(callable, args, NULL);
+
+	Py_DECREF(args);
+
+	return retval;
+}
+
+PyObject *
+PyObject_CallFunction(PyObject *callable, char *format, ...)
+{
+	va_list va;
+	PyObject *args;
+
+	if (callable == NULL)
+		return null_error();
+
+	if (format && *format) {
+		va_start(va, format);
+		args = Py_VaBuildValue(format, va);
+		va_end(va);
+	}
+	else
+		args = PyTuple_New(0);
+
+	return call_function_tail(callable, args);
+}
+
+PyObject *
+_PyObject_CallFunction_SizeT(PyObject *callable, char *format, ...)
+{
+	va_list va;
+	PyObject *args;
+
+	if (callable == NULL)
+		return null_error();
+
+	if (format && *format) {
+		va_start(va, format);
+		args = _Py_VaBuildValue_SizeT(format, va);
+		va_end(va);
+	}
+	else
+		args = PyTuple_New(0);
+
+	return call_function_tail(callable, args);
+}
+
+PyObject *
+PyObject_CallMethod(PyObject *o, char *name, char *format, ...)
+{
+	va_list va;
+	PyObject *args;
+	PyObject *func = NULL;
+	PyObject *retval = NULL;
+
+	if (o == NULL || name == NULL)
+		return null_error();
+
+	func = PyObject_GetAttrString(o, name);
+	if (func == NULL) {
+		PyErr_SetString(PyExc_AttributeError, name);
+		return 0;
+	}
+
+	if (!PyCallable_Check(func)) {
+		type_error("attribute of type '%.200s' is not callable", func); 
+		goto exit;
+	}
+
+	if (format && *format) {
+		va_start(va, format);
+		args = Py_VaBuildValue(format, va);
+		va_end(va);
+	}
+	else
+		args = PyTuple_New(0);
+
+	retval = call_function_tail(func, args);
+
+  exit:
+	/* args gets consumed in call_function_tail */
+	Py_XDECREF(func);
+
+	return retval;
+}
+
+PyObject *
+_PyObject_CallMethod_SizeT(PyObject *o, char *name, char *format, ...)
+{
+	va_list va;
+	PyObject *args;
+	PyObject *func = NULL;
+	PyObject *retval = NULL;
+
+	if (o == NULL || name == NULL)
+		return null_error();
+
+	func = PyObject_GetAttrString(o, name);
+	if (func == NULL) {
+		PyErr_SetString(PyExc_AttributeError, name);
+		return 0;
+	}
+
+	if (!PyCallable_Check(func)) {
+		type_error("attribute of type '%.200s' is not callable", func); 
+		goto exit;
+	}
+
+	if (format && *format) {
+		va_start(va, format);
+		args = _Py_VaBuildValue_SizeT(format, va);
+		va_end(va);
+	}
+	else
+		args = PyTuple_New(0);
+
+	retval = call_function_tail(func, args);
+
+  exit:
+	/* args gets consumed in call_function_tail */
+	Py_XDECREF(func);
+
+	return retval;
+}
+
+
+static PyObject *
+objargs_mktuple(va_list va)
+{
+	int i, n = 0;
+	va_list countva;
+	PyObject *result, *tmp;
+
+#ifdef VA_LIST_IS_ARRAY
+	memcpy(countva, va, sizeof(va_list));
+#else
+#ifdef __va_copy
+	__va_copy(countva, va);
+#else
+	countva = va;
+#endif
+#endif
+
+	while (((PyObject *)va_arg(countva, PyObject *)) != NULL)
+		++n;
+	result = PyTuple_New(n);
+	if (result != NULL && n > 0) {
+		for (i = 0; i < n; ++i) {
+			tmp = (PyObject *)va_arg(va, PyObject *);
+			PyTuple_SET_ITEM(result, i, tmp);
+			Py_INCREF(tmp);
+		}
+	}
+	return result;
+}
+
+PyObject *
+PyObject_CallMethodObjArgs(PyObject *callable, PyObject *name, ...)
+{
+	PyObject *args, *tmp;
+	va_list vargs;
+
+	if (callable == NULL || name == NULL)
+		return null_error();
+
+	callable = PyObject_GetAttr(callable, name);
+	if (callable == NULL)
+		return NULL;
+
+	/* count the args */
+	va_start(vargs, name);
+	args = objargs_mktuple(vargs);
+	va_end(vargs);
+	if (args == NULL) {
+		Py_DECREF(callable);
+		return NULL;
+	}
+	tmp = PyObject_Call(callable, args, NULL);
+	Py_DECREF(args);
+	Py_DECREF(callable);
+
+	return tmp;
+}
+
+PyObject *
+PyObject_CallFunctionObjArgs(PyObject *callable, ...)
+{
+	PyObject *args, *tmp;
+	va_list vargs;
+
+	if (callable == NULL)
+		return null_error();
+
+	/* count the args */
+	va_start(vargs, callable);
+	args = objargs_mktuple(vargs);
+	va_end(vargs);
+	if (args == NULL)
+		return NULL;
+	tmp = PyObject_Call(callable, args, NULL);
+	Py_DECREF(args);
+
+	return tmp;
+}
+
+
+/* isinstance(), issubclass() */
+
+/* abstract_get_bases() has logically 4 return states, with a sort of 0th
+ * state that will almost never happen.
+ *
+ * 0. creating the __bases__ static string could get a MemoryError
+ * 1. getattr(cls, '__bases__') could raise an AttributeError
+ * 2. getattr(cls, '__bases__') could raise some other exception
+ * 3. getattr(cls, '__bases__') could return a tuple
+ * 4. getattr(cls, '__bases__') could return something other than a tuple
+ *
+ * Only state #3 is a non-error state and only it returns a non-NULL object
+ * (it returns the retrieved tuple).
+ *
+ * Any raised AttributeErrors are masked by clearing the exception and
+ * returning NULL.  If an object other than a tuple comes out of __bases__,
+ * then again, the return value is NULL.  So yes, these two situations
+ * produce exactly the same results: NULL is returned and no error is set.
+ *
+ * If some exception other than AttributeError is raised, then NULL is also
+ * returned, but the exception is not cleared.  That's because we want the
+ * exception to be propagated along.
+ *
+ * Callers are expected to test for PyErr_Occurred() when the return value
+ * is NULL to decide whether a valid exception should be propagated or not.
+ * When there's no exception to propagate, it's customary for the caller to
+ * set a TypeError.
+ */
+static PyObject *
+abstract_get_bases(PyObject *cls)
+{
+	static PyObject *__bases__ = NULL;
+	PyObject *bases;
+
+	if (__bases__ == NULL) {
+		__bases__ = PyString_FromString("__bases__");
+		if (__bases__ == NULL)
+			return NULL;
+	}
+	bases = PyObject_GetAttr(cls, __bases__);
+	if (bases == NULL) {
+		if (PyErr_ExceptionMatches(PyExc_AttributeError))
+			PyErr_Clear();
+		return NULL;
+	}
+	if (!PyTuple_Check(bases)) {
+	        Py_DECREF(bases);
+		return NULL;
+	}
+	return bases;
+}
+
+
+static int
+abstract_issubclass(PyObject *derived, PyObject *cls)
+{
+	PyObject *bases;
+	Py_ssize_t i, n;
+	int r = 0;
+
+
+	if (derived == cls)
+		return 1;
+
+	if (PyTuple_Check(cls)) {
+		/* Not a general sequence -- that opens up the road to
+		   recursion and stack overflow. */
+		n = PyTuple_GET_SIZE(cls);
+		for (i = 0; i < n; i++) {
+			if (derived == PyTuple_GET_ITEM(cls, i))
+				return 1;
+		}
+	}
+	bases = abstract_get_bases(derived);
+	if (bases == NULL) {
+		if (PyErr_Occurred())
+			return -1;
+		return 0;
+	}
+	n = PyTuple_GET_SIZE(bases);
+	for (i = 0; i < n; i++) {
+		r = abstract_issubclass(PyTuple_GET_ITEM(bases, i), cls);
+		if (r != 0)
+			break;
+	}
+
+	Py_DECREF(bases);
+
+	return r;
+}
+
+static int
+check_class(PyObject *cls, const char *error)
+{
+	PyObject *bases = abstract_get_bases(cls);
+	if (bases == NULL) {
+		/* Do not mask errors. */
+		if (!PyErr_Occurred())
+			PyErr_SetString(PyExc_TypeError, error);
+		return 0;
+	}
+	Py_DECREF(bases);
+	return -1;
+}
+
+static int
+recursive_isinstance(PyObject *inst, PyObject *cls, int recursion_depth)
+{
+	PyObject *icls;
+	static PyObject *__class__ = NULL;
+	int retval = 0;
+
+	if (__class__ == NULL) {
+		__class__ = PyString_FromString("__class__");
+		if (__class__ == NULL)
+			return -1;
+	}
+
+	if (PyClass_Check(cls) && PyInstance_Check(inst)) {
+		PyObject *inclass =
+			(PyObject*)((PyInstanceObject*)inst)->in_class;
+		retval = PyClass_IsSubclass(inclass, cls);
+	}
+	else if (PyType_Check(cls)) {
+		retval = PyObject_TypeCheck(inst, (PyTypeObject *)cls);
+		if (retval == 0) {
+			PyObject *c = PyObject_GetAttr(inst, __class__);
+			if (c == NULL) {
+				PyErr_Clear();
+			}
+			else {
+				if (c != (PyObject *)(inst->ob_type) &&
+				    PyType_Check(c))
+					retval = PyType_IsSubtype(
+						(PyTypeObject *)c,
+						(PyTypeObject *)cls);
+				Py_DECREF(c);
+			}
+		}
+	}
+	else if (PyTuple_Check(cls)) {
+		Py_ssize_t i, n;
+
+                if (!recursion_depth) {
+                    PyErr_SetString(PyExc_RuntimeError,
+                                    "nest level of tuple too deep");
+                    return -1;
+                }
+
+		n = PyTuple_GET_SIZE(cls);
+		for (i = 0; i < n; i++) {
+			retval = recursive_isinstance(
+                                    inst,
+                                    PyTuple_GET_ITEM(cls, i),
+                                    recursion_depth-1);
+			if (retval != 0)
+				break;
+		}
+	}
+	else {
+		if (!check_class(cls,
+			"isinstance() arg 2 must be a class, type,"
+			" or tuple of classes and types"))
+			return -1;
+		icls = PyObject_GetAttr(inst, __class__);
+		if (icls == NULL) {
+			PyErr_Clear();
+			retval = 0;
+		}
+		else {
+			retval = abstract_issubclass(icls, cls);
+			Py_DECREF(icls);
+		}
+	}
+
+	return retval;
+}
+
+int
+PyObject_IsInstance(PyObject *inst, PyObject *cls)
+{
+    return recursive_isinstance(inst, cls, Py_GetRecursionLimit());
+}
+
+static  int
+recursive_issubclass(PyObject *derived, PyObject *cls, int recursion_depth)
+{
+	int retval;
+
+	if (!PyClass_Check(derived) || !PyClass_Check(cls)) {
+		if (!check_class(derived,
+				 "issubclass() arg 1 must be a class"))
+			return -1;
+
+		if (PyTuple_Check(cls)) {
+			Py_ssize_t i;
+			Py_ssize_t n = PyTuple_GET_SIZE(cls);
+
+                        if (!recursion_depth) {
+                            PyErr_SetString(PyExc_RuntimeError,
+                                            "nest level of tuple too deep");
+                            return -1;
+                        }
+			for (i = 0; i < n; ++i) {
+				retval = recursive_issubclass(
+                                            derived,
+                                            PyTuple_GET_ITEM(cls, i),
+                                            recursion_depth-1);
+				if (retval != 0) {
+					/* either found it, or got an error */
+					return retval;
+				}
+			}
+			return 0;
+		}
+		else {
+			if (!check_class(cls,
+					"issubclass() arg 2 must be a class"
+					" or tuple of classes"))
+				return -1;
+		}
+
+		retval = abstract_issubclass(derived, cls);
+	}
+	else {
+		/* shortcut */
+	  	if (!(retval = (derived == cls)))
+			retval = PyClass_IsSubclass(derived, cls);
+	}
+
+	return retval;
+}
+
+int
+PyObject_IsSubclass(PyObject *derived, PyObject *cls)
+{
+    return recursive_issubclass(derived, cls, Py_GetRecursionLimit());
+}
+
+
+PyObject *
+PyObject_GetIter(PyObject *o)
+{
+	PyTypeObject *t = o->ob_type;
+	getiterfunc f = NULL;
+	if (PyType_HasFeature(t, Py_TPFLAGS_HAVE_ITER))
+		f = t->tp_iter;
+	if (f == NULL) {
+		if (PySequence_Check(o))
+			return PySeqIter_New(o);
+		return type_error("'%.200s' object is not iterable", o);
+	}
+	else {
+		PyObject *res = (*f)(o);
+		if (res != NULL && !PyIter_Check(res)) {
+			PyErr_Format(PyExc_TypeError,
+				     "iter() returned non-iterator "
+				     "of type '%.100s'",
+				     res->ob_type->tp_name);
+			Py_DECREF(res);
+			res = NULL;
+		}
+		return res;
+	}
+}
+
+/* Return next item.
+ * If an error occurs, return NULL.  PyErr_Occurred() will be true.
+ * If the iteration terminates normally, return NULL and clear the
+ * PyExc_StopIteration exception (if it was set).  PyErr_Occurred()
+ * will be false.
+ * Else return the next object.  PyErr_Occurred() will be false.
+ */
+PyObject *
+PyIter_Next(PyObject *iter)
+{
+	PyObject *result;
+	assert(PyIter_Check(iter));
+	result = (*iter->ob_type->tp_iternext)(iter);
+	if (result == NULL &&
+	    PyErr_Occurred() &&
+	    PyErr_ExceptionMatches(PyExc_StopIteration))
+		PyErr_Clear();
+	return result;
+}

Added: vendor/Python/current/Objects/boolobject.c
===================================================================
--- vendor/Python/current/Objects/boolobject.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Objects/boolobject.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,201 @@
+/* Boolean type, a subtype of int */
+
+#include "Python.h"
+
+/* We need to define bool_print to override int_print */
+
+static int
+bool_print(PyBoolObject *self, FILE *fp, int flags)
+{
+	fputs(self->ob_ival == 0 ? "False" : "True", fp);
+	return 0;
+}
+
+/* We define bool_repr to return "False" or "True" */
+
+static PyObject *false_str = NULL;
+static PyObject *true_str = NULL;
+
+static PyObject *
+bool_repr(PyBoolObject *self)
+{
+	PyObject *s;
+
+	if (self->ob_ival)
+		s = true_str ? true_str :
+			(true_str = PyString_InternFromString("True"));
+	else
+		s = false_str ? false_str :
+			(false_str = PyString_InternFromString("False"));
+	Py_XINCREF(s);
+	return s;
+}
+
+/* Function to return a bool from a C long */
+
+PyObject *PyBool_FromLong(long ok)
+{
+	PyObject *result;
+
+	if (ok)
+		result = Py_True;
+	else
+		result = Py_False;
+	Py_INCREF(result);
+	return result;
+}
+
+/* We define bool_new to always return either Py_True or Py_False */
+
+static PyObject *
+bool_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	static char *kwlist[] = {"x", 0};
+	PyObject *x = Py_False;
+	long ok;
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:bool", kwlist, &x))
+		return NULL;
+	ok = PyObject_IsTrue(x);
+	if (ok < 0)
+		return NULL;
+	return PyBool_FromLong(ok);
+}
+
+/* Arithmetic operations redefined to return bool if both args are bool. */
+
+static PyObject *
+bool_and(PyObject *a, PyObject *b)
+{
+	if (!PyBool_Check(a) || !PyBool_Check(b))
+		return PyInt_Type.tp_as_number->nb_and(a, b);
+	return PyBool_FromLong(
+		((PyBoolObject *)a)->ob_ival & ((PyBoolObject *)b)->ob_ival);
+}
+
+static PyObject *
+bool_or(PyObject *a, PyObject *b)
+{
+	if (!PyBool_Check(a) || !PyBool_Check(b))
+		return PyInt_Type.tp_as_number->nb_or(a, b);
+	return PyBool_FromLong(
+		((PyBoolObject *)a)->ob_ival | ((PyBoolObject *)b)->ob_ival);
+}
+
+static PyObject *
+bool_xor(PyObject *a, PyObject *b)
+{
+	if (!PyBool_Check(a) || !PyBool_Check(b))
+		return PyInt_Type.tp_as_number->nb_xor(a, b);
+	return PyBool_FromLong(
+		((PyBoolObject *)a)->ob_ival ^ ((PyBoolObject *)b)->ob_ival);
+}
+
+/* Doc string */
+
+PyDoc_STRVAR(bool_doc,
+"bool(x) -> bool\n\
+\n\
+Returns True when the argument x is true, False otherwise.\n\
+The builtins True and False are the only two instances of the class bool.\n\
+The class bool is a subclass of the class int, and cannot be subclassed.");
+
+/* Arithmetic methods -- only so we can override &, |, ^. */
+
+static PyNumberMethods bool_as_number = {
+	0,			/* nb_add */
+	0,			/* nb_subtract */
+	0,			/* nb_multiply */
+	0,			/* nb_divide */
+	0,			/* nb_remainder */
+	0,			/* nb_divmod */
+	0,			/* nb_power */
+	0,			/* nb_negative */
+	0,			/* nb_positive */
+	0,			/* nb_absolute */
+	0,			/* nb_nonzero */
+	0,			/* nb_invert */
+	0,			/* nb_lshift */
+	0,			/* nb_rshift */
+	bool_and,		/* nb_and */
+	bool_xor,		/* nb_xor */
+	bool_or,		/* nb_or */
+	0,			/* nb_coerce */
+	0,			/* nb_int */
+	0,			/* nb_long */
+	0,			/* nb_float */
+	0,			/* nb_oct */
+	0,		 	/* nb_hex */
+	0,			/* nb_inplace_add */
+	0,			/* nb_inplace_subtract */
+	0,			/* nb_inplace_multiply */
+	0,			/* nb_inplace_divide */
+	0,			/* nb_inplace_remainder */
+	0,			/* nb_inplace_power */
+	0,			/* nb_inplace_lshift */
+	0,			/* nb_inplace_rshift */
+	0,			/* nb_inplace_and */
+	0,			/* nb_inplace_xor */
+	0,			/* nb_inplace_or */
+	0,			/* nb_floor_divide */
+	0,			/* nb_true_divide */
+	0,			/* nb_inplace_floor_divide */
+	0,			/* nb_inplace_true_divide */
+};
+
+/* The type object for bool.  Note that this cannot be subclassed! */
+
+PyTypeObject PyBool_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,
+	"bool",
+	sizeof(PyIntObject),
+	0,
+	0,					/* tp_dealloc */
+	(printfunc)bool_print,			/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	(reprfunc)bool_repr,			/* tp_repr */
+	&bool_as_number,			/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+        0,					/* tp_call */
+        (reprfunc)bool_repr,			/* tp_str */
+	0,					/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, /* tp_flags */
+	bool_doc,				/* tp_doc */
+	0,					/* tp_traverse */
+	0,					/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	0,					/* tp_methods */
+	0,					/* tp_members */
+	0,					/* tp_getset */
+	&PyInt_Type,				/* tp_base */
+	0,					/* tp_dict */
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	0,					/* tp_init */
+	0,					/* tp_alloc */
+	bool_new,				/* tp_new */
+};
+
+/* The objects representing bool values False and True */
+
+/* Named Zero for link-level compatibility */
+PyIntObject _Py_ZeroStruct = {
+	PyObject_HEAD_INIT(&PyBool_Type)
+	0
+};
+
+PyIntObject _Py_TrueStruct = {
+	PyObject_HEAD_INIT(&PyBool_Type)
+	1
+};

Added: vendor/Python/current/Objects/bufferobject.c
===================================================================
--- vendor/Python/current/Objects/bufferobject.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Objects/bufferobject.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,706 @@
+
+/* Buffer object implementation */
+
+#include "Python.h"
+
+
+typedef struct {
+	PyObject_HEAD
+	PyObject *b_base;
+	void *b_ptr;
+	Py_ssize_t b_size;
+	Py_ssize_t b_offset;
+	int b_readonly;
+	long b_hash;
+} PyBufferObject;
+
+
+enum buffer_t {
+    READ_BUFFER,
+    WRITE_BUFFER,
+    CHAR_BUFFER,
+    ANY_BUFFER,
+};
+
+static int
+get_buf(PyBufferObject *self, void **ptr, Py_ssize_t *size,
+	enum buffer_t buffer_type)
+{
+	if (self->b_base == NULL) {
+		assert (ptr != NULL);
+		*ptr = self->b_ptr;
+		*size = self->b_size;
+	}
+	else {
+		Py_ssize_t count, offset;
+		readbufferproc proc = 0;
+		PyBufferProcs *bp = self->b_base->ob_type->tp_as_buffer;
+		if ((*bp->bf_getsegcount)(self->b_base, NULL) != 1) {
+			PyErr_SetString(PyExc_TypeError,
+				"single-segment buffer object expected");
+			return 0;
+		}
+		if ((buffer_type == READ_BUFFER) ||
+			((buffer_type == ANY_BUFFER) && self->b_readonly))
+		    proc = bp->bf_getreadbuffer;
+		else if ((buffer_type == WRITE_BUFFER) ||
+			(buffer_type == ANY_BUFFER))
+    		    proc = (readbufferproc)bp->bf_getwritebuffer;
+		else if (buffer_type == CHAR_BUFFER) {
+		    if (!PyType_HasFeature(self->ob_type,
+				Py_TPFLAGS_HAVE_GETCHARBUFFER)) {
+			PyErr_SetString(PyExc_TypeError,
+				"Py_TPFLAGS_HAVE_GETCHARBUFFER needed");
+			return 0;
+		    }
+		    proc = (readbufferproc)bp->bf_getcharbuffer;
+		}
+		if (!proc) {
+		    char *buffer_type_name;
+		    switch (buffer_type) {
+			case READ_BUFFER:
+			    buffer_type_name = "read";
+			    break;
+			case WRITE_BUFFER:
+			    buffer_type_name = "write";
+			    break;
+			case CHAR_BUFFER:
+			    buffer_type_name = "char";
+			    break;
+			default:
+			    buffer_type_name = "no";
+			    break;
+		    }
+		    PyErr_Format(PyExc_TypeError,
+			    "%s buffer type not available",
+			    buffer_type_name);
+		    return 0;
+		}
+		if ((count = (*proc)(self->b_base, 0, ptr)) < 0)
+			return 0;
+		/* apply constraints to the start/end */
+		if (self->b_offset > count)
+			offset = count;
+		else
+			offset = self->b_offset;
+		*(char **)ptr = *(char **)ptr + offset;
+		if (self->b_size == Py_END_OF_BUFFER)
+			*size = count;
+		else
+			*size = self->b_size;
+		if (offset + *size > count)
+			*size = count - offset;
+	}
+	return 1;
+}
+
+
+static PyObject *
+buffer_from_memory(PyObject *base, Py_ssize_t size, Py_ssize_t offset, void *ptr,
+		   int readonly)
+{
+	PyBufferObject * b;
+
+	if (size < 0 && size != Py_END_OF_BUFFER) {
+		PyErr_SetString(PyExc_ValueError,
+				"size must be zero or positive");
+		return NULL;
+	}
+	if (offset < 0) {
+		PyErr_SetString(PyExc_ValueError,
+				"offset must be zero or positive");
+		return NULL;
+	}
+
+	b = PyObject_NEW(PyBufferObject, &PyBuffer_Type);
+	if ( b == NULL )
+		return NULL;
+
+	Py_XINCREF(base);
+	b->b_base = base;
+	b->b_ptr = ptr;
+	b->b_size = size;
+	b->b_offset = offset;
+	b->b_readonly = readonly;
+	b->b_hash = -1;
+
+	return (PyObject *) b;
+}
+
+static PyObject *
+buffer_from_object(PyObject *base, Py_ssize_t size, Py_ssize_t offset, int readonly)
+{
+	if (offset < 0) {
+		PyErr_SetString(PyExc_ValueError,
+				"offset must be zero or positive");
+		return NULL;
+	}
+	if ( PyBuffer_Check(base) && (((PyBufferObject *)base)->b_base) ) {
+		/* another buffer, refer to the base object */
+		PyBufferObject *b = (PyBufferObject *)base;
+		if (b->b_size != Py_END_OF_BUFFER) {
+			Py_ssize_t base_size = b->b_size - offset;
+			if (base_size < 0)
+				base_size = 0;
+			if (size == Py_END_OF_BUFFER || size > base_size)
+				size = base_size;
+		}
+		offset += b->b_offset;
+		base = b->b_base;
+	}
+	return buffer_from_memory(base, size, offset, NULL, readonly);
+}
+
+
+PyObject *
+PyBuffer_FromObject(PyObject *base, Py_ssize_t offset, Py_ssize_t size)
+{
+	PyBufferProcs *pb = base->ob_type->tp_as_buffer;
+
+	if ( pb == NULL ||
+	     pb->bf_getreadbuffer == NULL ||
+	     pb->bf_getsegcount == NULL )
+	{
+		PyErr_SetString(PyExc_TypeError, "buffer object expected");
+		return NULL;
+	}
+
+	return buffer_from_object(base, size, offset, 1);
+}
+
+PyObject *
+PyBuffer_FromReadWriteObject(PyObject *base, Py_ssize_t offset, Py_ssize_t size)
+{
+	PyBufferProcs *pb = base->ob_type->tp_as_buffer;
+
+	if ( pb == NULL ||
+	     pb->bf_getwritebuffer == NULL ||
+	     pb->bf_getsegcount == NULL )
+	{
+		PyErr_SetString(PyExc_TypeError, "buffer object expected");
+		return NULL;
+	}
+
+	return buffer_from_object(base, size,  offset, 0);
+}
+
+PyObject *
+PyBuffer_FromMemory(void *ptr, Py_ssize_t size)
+{
+	return buffer_from_memory(NULL, size, 0, ptr, 1);
+}
+
+PyObject *
+PyBuffer_FromReadWriteMemory(void *ptr, Py_ssize_t size)
+{
+	return buffer_from_memory(NULL, size, 0, ptr, 0);
+}
+
+PyObject *
+PyBuffer_New(Py_ssize_t size)
+{
+	PyObject *o;
+	PyBufferObject * b;
+
+	if (size < 0) {
+		PyErr_SetString(PyExc_ValueError,
+				"size must be zero or positive");
+		return NULL;
+	}
+	/* XXX: check for overflow in multiply */
+	/* Inline PyObject_New */
+	o = (PyObject *)PyObject_MALLOC(sizeof(*b) + size);
+	if ( o == NULL )
+		return PyErr_NoMemory();
+	b = (PyBufferObject *) PyObject_INIT(o, &PyBuffer_Type);
+
+	b->b_base = NULL;
+	b->b_ptr = (void *)(b + 1);
+	b->b_size = size;
+	b->b_offset = 0;
+	b->b_readonly = 0;
+	b->b_hash = -1;
+
+	return o;
+}
+
+/* Methods */
+
+static PyObject *
+buffer_new(PyTypeObject *type, PyObject *args, PyObject *kw)
+{
+	PyObject *ob;
+	Py_ssize_t offset = 0;
+	Py_ssize_t size = Py_END_OF_BUFFER;
+
+	if (!_PyArg_NoKeywords("buffer()", kw))
+		return NULL;
+
+	if (!PyArg_ParseTuple(args, "O|nn:buffer", &ob, &offset, &size))
+	    return NULL;
+	return PyBuffer_FromObject(ob, offset, size);
+}
+
+PyDoc_STRVAR(buffer_doc,
+"buffer(object [, offset[, size]])\n\
+\n\
+Create a new buffer object which references the given object.\n\
+The buffer will reference a slice of the target object from the\n\
+start of the object (or at the specified offset). The slice will\n\
+extend to the end of the target object (or with the specified size).");
+
+
+static void
+buffer_dealloc(PyBufferObject *self)
+{
+	Py_XDECREF(self->b_base);
+	PyObject_DEL(self);
+}
+
+static int
+buffer_compare(PyBufferObject *self, PyBufferObject *other)
+{
+	void *p1, *p2;
+	Py_ssize_t len_self, len_other, min_len;
+	int cmp;
+
+	if (!get_buf(self, &p1, &len_self, ANY_BUFFER))
+		return -1;
+	if (!get_buf(other, &p2, &len_other, ANY_BUFFER))
+		return -1;
+	min_len = (len_self < len_other) ? len_self : len_other;
+	if (min_len > 0) {
+		cmp = memcmp(p1, p2, min_len);
+		if (cmp != 0)
+			return cmp < 0 ? -1 : 1;
+	}
+	return (len_self < len_other) ? -1 : (len_self > len_other) ? 1 : 0;
+}
+
+static PyObject *
+buffer_repr(PyBufferObject *self)
+{
+	const char *status = self->b_readonly ? "read-only" : "read-write";
+
+	if ( self->b_base == NULL )
+		return PyString_FromFormat("<%s buffer ptr %p, size %zd at %p>",
+					   status,
+					   self->b_ptr,
+					   self->b_size,
+					   self);
+	else
+		return PyString_FromFormat(
+			"<%s buffer for %p, size %zd, offset %zd at %p>",
+			status,
+			self->b_base,
+			self->b_size,
+			self->b_offset,
+			self);
+}
+
+static long
+buffer_hash(PyBufferObject *self)
+{
+	void *ptr;
+	Py_ssize_t size;
+	register Py_ssize_t len;
+	register unsigned char *p;
+	register long x;
+
+	if ( self->b_hash != -1 )
+		return self->b_hash;
+
+	/* XXX potential bugs here, a readonly buffer does not imply that the
+	 * underlying memory is immutable.  b_readonly is a necessary but not
+	 * sufficient condition for a buffer to be hashable.  Perhaps it would
+	 * be better to only allow hashing if the underlying object is known to
+	 * be immutable (e.g. PyString_Check() is true).  Another idea would
+	 * be to call tp_hash on the underlying object and see if it raises
+	 * an error. */
+	if ( !self->b_readonly )
+	{
+		PyErr_SetString(PyExc_TypeError,
+				"writable buffers are not hashable");
+		return -1;
+	}
+
+	if (!get_buf(self, &ptr, &size, ANY_BUFFER))
+		return -1;
+	p = (unsigned char *) ptr;
+	len = size;
+	x = *p << 7;
+	while (--len >= 0)
+		x = (1000003*x) ^ *p++;
+	x ^= size;
+	if (x == -1)
+		x = -2;
+	self->b_hash = x;
+	return x;
+}
+
+static PyObject *
+buffer_str(PyBufferObject *self)
+{
+	void *ptr;
+	Py_ssize_t size;
+	if (!get_buf(self, &ptr, &size, ANY_BUFFER))
+		return NULL;
+	return PyString_FromStringAndSize((const char *)ptr, size);
+}
+
+/* Sequence methods */
+
+static Py_ssize_t
+buffer_length(PyBufferObject *self)
+{
+	void *ptr;
+	Py_ssize_t size;
+	if (!get_buf(self, &ptr, &size, ANY_BUFFER))
+		return -1;
+	return size;
+}
+
+static PyObject *
+buffer_concat(PyBufferObject *self, PyObject *other)
+{
+	PyBufferProcs *pb = other->ob_type->tp_as_buffer;
+	void *ptr1, *ptr2;
+	char *p;
+	PyObject *ob;
+	Py_ssize_t size, count;
+
+	if ( pb == NULL ||
+	     pb->bf_getreadbuffer == NULL ||
+	     pb->bf_getsegcount == NULL )
+	{
+		PyErr_BadArgument();
+		return NULL;
+	}
+	if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
+	{
+		/* ### use a different exception type/message? */
+		PyErr_SetString(PyExc_TypeError,
+				"single-segment buffer object expected");
+		return NULL;
+	}
+
+ 	if (!get_buf(self, &ptr1, &size, ANY_BUFFER))
+ 		return NULL;
+ 
+	/* optimize special case */
+	if ( size == 0 )
+	{
+	    Py_INCREF(other);
+	    return other;
+	}
+
+	if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 )
+		return NULL;
+
+ 	ob = PyString_FromStringAndSize(NULL, size + count);
+	if ( ob == NULL )
+		return NULL;
+ 	p = PyString_AS_STRING(ob);
+ 	memcpy(p, ptr1, size);
+ 	memcpy(p + size, ptr2, count);
+
+	/* there is an extra byte in the string object, so this is safe */
+	p[size + count] = '\0';
+
+	return ob;
+}
+
+static PyObject *
+buffer_repeat(PyBufferObject *self, Py_ssize_t count)
+{
+	PyObject *ob;
+	register char *p;
+	void *ptr;
+	Py_ssize_t size;
+
+	if ( count < 0 )
+		count = 0;
+	if (!get_buf(self, &ptr, &size, ANY_BUFFER))
+		return NULL;
+	ob = PyString_FromStringAndSize(NULL, size * count);
+	if ( ob == NULL )
+		return NULL;
+
+	p = PyString_AS_STRING(ob);
+	while ( count-- )
+	{
+	    memcpy(p, ptr, size);
+	    p += size;
+	}
+
+	/* there is an extra byte in the string object, so this is safe */
+	*p = '\0';
+
+	return ob;
+}
+
+static PyObject *
+buffer_item(PyBufferObject *self, Py_ssize_t idx)
+{
+	void *ptr;
+	Py_ssize_t size;
+	if (!get_buf(self, &ptr, &size, ANY_BUFFER))
+		return NULL;
+	if ( idx < 0 || idx >= size ) {
+		PyErr_SetString(PyExc_IndexError, "buffer index out of range");
+		return NULL;
+	}
+	return PyString_FromStringAndSize((char *)ptr + idx, 1);
+}
+
+static PyObject *
+buffer_slice(PyBufferObject *self, Py_ssize_t left, Py_ssize_t right)
+{
+	void *ptr;
+	Py_ssize_t size;
+	if (!get_buf(self, &ptr, &size, ANY_BUFFER))
+		return NULL;
+	if ( left < 0 )
+		left = 0;
+	if ( right < 0 )
+		right = 0;
+	if ( right > size )
+		right = size;
+	if ( right < left )
+		right = left;
+	return PyString_FromStringAndSize((char *)ptr + left,
+					  right - left);
+}
+
+static int
+buffer_ass_item(PyBufferObject *self, Py_ssize_t idx, PyObject *other)
+{
+	PyBufferProcs *pb;
+	void *ptr1, *ptr2;
+	Py_ssize_t size;
+	Py_ssize_t count;
+
+	if ( self->b_readonly ) {
+		PyErr_SetString(PyExc_TypeError,
+				"buffer is read-only");
+		return -1;
+	}
+
+	if (!get_buf(self, &ptr1, &size, ANY_BUFFER))
+		return -1;
+
+	if (idx < 0 || idx >= size) {
+		PyErr_SetString(PyExc_IndexError,
+				"buffer assignment index out of range");
+		return -1;
+	}
+
+	pb = other ? other->ob_type->tp_as_buffer : NULL;
+	if ( pb == NULL ||
+	     pb->bf_getreadbuffer == NULL ||
+	     pb->bf_getsegcount == NULL )
+	{
+		PyErr_BadArgument();
+		return -1;
+	}
+	if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
+	{
+		/* ### use a different exception type/message? */
+		PyErr_SetString(PyExc_TypeError,
+				"single-segment buffer object expected");
+		return -1;
+	}
+
+	if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 )
+		return -1;
+	if ( count != 1 ) {
+		PyErr_SetString(PyExc_TypeError,
+				"right operand must be a single byte");
+		return -1;
+	}
+
+	((char *)ptr1)[idx] = *(char *)ptr2;
+	return 0;
+}
+
+static int
+buffer_ass_slice(PyBufferObject *self, Py_ssize_t left, Py_ssize_t right, PyObject *other)
+{
+	PyBufferProcs *pb;
+	void *ptr1, *ptr2;
+	Py_ssize_t size;
+	Py_ssize_t slice_len;
+	Py_ssize_t count;
+
+	if ( self->b_readonly ) {
+		PyErr_SetString(PyExc_TypeError,
+				"buffer is read-only");
+		return -1;
+	}
+
+	pb = other ? other->ob_type->tp_as_buffer : NULL;
+	if ( pb == NULL ||
+	     pb->bf_getreadbuffer == NULL ||
+	     pb->bf_getsegcount == NULL )
+	{
+		PyErr_BadArgument();
+		return -1;
+	}
+	if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
+	{
+		/* ### use a different exception type/message? */
+		PyErr_SetString(PyExc_TypeError,
+				"single-segment buffer object expected");
+		return -1;
+	}
+	if (!get_buf(self, &ptr1, &size, ANY_BUFFER))
+		return -1;
+	if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 )
+		return -1;
+
+	if ( left < 0 )
+		left = 0;
+	else if ( left > size )
+		left = size;
+	if ( right < left )
+		right = left;
+	else if ( right > size )
+		right = size;
+	slice_len = right - left;
+
+	if ( count != slice_len ) {
+		PyErr_SetString(
+			PyExc_TypeError,
+			"right operand length must match slice length");
+		return -1;
+	}
+
+	if ( slice_len )
+	    memcpy((char *)ptr1 + left, ptr2, slice_len);
+
+	return 0;
+}
+
+/* Buffer methods */
+
+static Py_ssize_t
+buffer_getreadbuf(PyBufferObject *self, Py_ssize_t idx, void **pp)
+{
+	Py_ssize_t size;
+	if ( idx != 0 ) {
+		PyErr_SetString(PyExc_SystemError,
+				"accessing non-existent buffer segment");
+		return -1;
+	}
+	if (!get_buf(self, pp, &size, READ_BUFFER))
+		return -1;
+	return size;
+}
+
+static Py_ssize_t
+buffer_getwritebuf(PyBufferObject *self, Py_ssize_t idx, void **pp)
+{
+	Py_ssize_t size;
+
+	if ( self->b_readonly )
+	{
+		PyErr_SetString(PyExc_TypeError, "buffer is read-only");
+		return -1;
+	}
+
+	if ( idx != 0 ) {
+		PyErr_SetString(PyExc_SystemError,
+				"accessing non-existent buffer segment");
+		return -1;
+	}
+	if (!get_buf(self, pp, &size, WRITE_BUFFER))
+		return -1;
+	return size;
+}
+
+static Py_ssize_t
+buffer_getsegcount(PyBufferObject *self, Py_ssize_t *lenp)
+{
+	void *ptr;
+	Py_ssize_t size;
+	if (!get_buf(self, &ptr, &size, ANY_BUFFER))
+		return -1;
+	if (lenp)
+		*lenp = size;
+	return 1;
+}
+
+static Py_ssize_t
+buffer_getcharbuf(PyBufferObject *self, Py_ssize_t idx, const char **pp)
+{
+	void *ptr;
+	Py_ssize_t size;
+	if ( idx != 0 ) {
+		PyErr_SetString(PyExc_SystemError,
+				"accessing non-existent buffer segment");
+		return -1;
+	}
+	if (!get_buf(self, &ptr, &size, CHAR_BUFFER))
+		return -1;
+	*pp = (const char *)ptr;
+	return size;
+}
+
+static PySequenceMethods buffer_as_sequence = {
+	(lenfunc)buffer_length, /*sq_length*/
+	(binaryfunc)buffer_concat, /*sq_concat*/
+	(ssizeargfunc)buffer_repeat, /*sq_repeat*/
+	(ssizeargfunc)buffer_item, /*sq_item*/
+	(ssizessizeargfunc)buffer_slice, /*sq_slice*/
+	(ssizeobjargproc)buffer_ass_item, /*sq_ass_item*/
+	(ssizessizeobjargproc)buffer_ass_slice, /*sq_ass_slice*/
+};
+
+static PyBufferProcs buffer_as_buffer = {
+	(readbufferproc)buffer_getreadbuf,
+	(writebufferproc)buffer_getwritebuf,
+	(segcountproc)buffer_getsegcount,
+	(charbufferproc)buffer_getcharbuf,
+};
+
+PyTypeObject PyBuffer_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,
+	"buffer",
+	sizeof(PyBufferObject),
+	0,
+	(destructor)buffer_dealloc, 		/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	(cmpfunc)buffer_compare,		/* tp_compare */
+	(reprfunc)buffer_repr,			/* tp_repr */
+	0,					/* tp_as_number */
+	&buffer_as_sequence,			/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	(hashfunc)buffer_hash,			/* tp_hash */
+	0,					/* tp_call */
+	(reprfunc)buffer_str,			/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	0,					/* tp_setattro */
+	&buffer_as_buffer,			/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GETCHARBUFFER, /* tp_flags */
+	buffer_doc,				/* tp_doc */
+	0,					/* tp_traverse */
+	0,					/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	0,					/* tp_methods */	
+	0,					/* tp_members */
+	0,					/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	0,					/* tp_init */
+	0,					/* tp_alloc */
+	buffer_new,				/* tp_new */
+};

Added: vendor/Python/current/Objects/cellobject.c
===================================================================
--- vendor/Python/current/Objects/cellobject.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Objects/cellobject.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,133 @@
+/* Cell object implementation */
+
+#include "Python.h"
+
+PyObject *
+PyCell_New(PyObject *obj)
+{
+	PyCellObject *op;
+
+	op = (PyCellObject *)PyObject_GC_New(PyCellObject, &PyCell_Type);
+	if (op == NULL)
+		return NULL;
+	op->ob_ref = obj;
+	Py_XINCREF(obj);
+
+	_PyObject_GC_TRACK(op);
+	return (PyObject *)op;
+}
+
+PyObject *
+PyCell_Get(PyObject *op)
+{
+	if (!PyCell_Check(op)) {
+		PyErr_BadInternalCall();
+		return NULL;
+	}
+	Py_XINCREF(((PyCellObject*)op)->ob_ref);
+	return PyCell_GET(op);
+}
+
+int
+PyCell_Set(PyObject *op, PyObject *obj)
+{
+	if (!PyCell_Check(op)) {
+		PyErr_BadInternalCall();
+		return -1;
+	}
+	Py_XDECREF(((PyCellObject*)op)->ob_ref);
+	Py_XINCREF(obj);
+	PyCell_SET(op, obj);
+	return 0;
+}
+
+static void
+cell_dealloc(PyCellObject *op)
+{
+	_PyObject_GC_UNTRACK(op);
+	Py_XDECREF(op->ob_ref);
+	PyObject_GC_Del(op);
+}
+
+static int
+cell_compare(PyCellObject *a, PyCellObject *b)
+{
+	if (a->ob_ref == NULL) {
+		if (b->ob_ref == NULL)
+			return 0;
+		return -1;
+	} else if (b->ob_ref == NULL)
+		return 1;
+	return PyObject_Compare(a->ob_ref, b->ob_ref);
+}
+
+static PyObject *
+cell_repr(PyCellObject *op)
+{
+	if (op->ob_ref == NULL)
+		return PyString_FromFormat("<cell at %p: empty>", op);
+
+	return PyString_FromFormat("<cell at %p: %.80s object at %p>",
+				   op, op->ob_ref->ob_type->tp_name,
+				   op->ob_ref);
+}
+
+static int
+cell_traverse(PyCellObject *op, visitproc visit, void *arg)
+{
+	Py_VISIT(op->ob_ref);
+	return 0;
+}
+
+static int
+cell_clear(PyCellObject *op)
+{
+	Py_CLEAR(op->ob_ref);
+	return 0;
+}
+
+static PyObject *
+cell_get_contents(PyCellObject *op, void *closure)
+{
+	Py_XINCREF(op->ob_ref);
+	return op->ob_ref;
+}
+
+static PyGetSetDef cell_getsetlist[] = {
+	{"cell_contents", (getter)cell_get_contents, NULL},
+	{NULL} /* sentinel */
+};
+
+PyTypeObject PyCell_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,
+	"cell",
+	sizeof(PyCellObject),
+	0,
+	(destructor)cell_dealloc,               /* tp_dealloc */
+	0,                                      /* tp_print */
+	0,	                                /* tp_getattr */
+	0,					/* tp_setattr */
+	(cmpfunc)cell_compare,			/* tp_compare */
+	(reprfunc)cell_repr,			/* tp_repr */
+	0,					/* tp_as_number */
+	0,			                /* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+ 	0,					/* tp_doc */
+ 	(traverseproc)cell_traverse,		/* tp_traverse */
+ 	(inquiry)cell_clear,			/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0, 					/* tp_iter */
+	0,					/* tp_iternext */
+	0,					/* tp_methods */
+	0,					/* tp_members */
+	cell_getsetlist,			/* tp_getset */
+};

Added: vendor/Python/current/Objects/classobject.c
===================================================================
--- vendor/Python/current/Objects/classobject.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Objects/classobject.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2580 @@
+
+/* Class object implementation */
+
+#include "Python.h"
+#include "structmember.h"
+
+#define TP_DESCR_GET(t) \
+    (PyType_HasFeature(t, Py_TPFLAGS_HAVE_CLASS) ? (t)->tp_descr_get : NULL)
+
+
+/* Forward */
+static PyObject *class_lookup(PyClassObject *, PyObject *,
+			      PyClassObject **);
+static PyObject *instance_getattr1(PyInstanceObject *, PyObject *);
+static PyObject *instance_getattr2(PyInstanceObject *, PyObject *);
+
+static PyObject *getattrstr, *setattrstr, *delattrstr;
+
+
+PyObject *
+PyClass_New(PyObject *bases, PyObject *dict, PyObject *name)
+     /* bases is NULL or tuple of classobjects! */
+{
+	PyClassObject *op, *dummy;
+	static PyObject *docstr, *modstr, *namestr;
+	if (docstr == NULL) {
+		docstr= PyString_InternFromString("__doc__");
+		if (docstr == NULL)
+			return NULL;
+	}
+	if (modstr == NULL) {
+		modstr= PyString_InternFromString("__module__");
+		if (modstr == NULL)
+			return NULL;
+	}
+	if (namestr == NULL) {
+		namestr= PyString_InternFromString("__name__");
+		if (namestr == NULL)
+			return NULL;
+	}
+	if (name == NULL || !PyString_Check(name)) {
+		PyErr_SetString(PyExc_TypeError,
+				"PyClass_New: name must be a string");
+		return NULL;
+	}
+	if (dict == NULL || !PyDict_Check(dict)) {
+		PyErr_SetString(PyExc_TypeError,
+				"PyClass_New: dict must be a dictionary");
+		return NULL;
+	}
+	if (PyDict_GetItem(dict, docstr) == NULL) {
+		if (PyDict_SetItem(dict, docstr, Py_None) < 0)
+			return NULL;
+	}
+	if (PyDict_GetItem(dict, modstr) == NULL) {
+		PyObject *globals = PyEval_GetGlobals();
+		if (globals != NULL) {
+			PyObject *modname = PyDict_GetItem(globals, namestr);
+			if (modname != NULL) {
+				if (PyDict_SetItem(dict, modstr, modname) < 0)
+					return NULL;
+			}
+		}
+	}
+	if (bases == NULL) {
+		bases = PyTuple_New(0);
+		if (bases == NULL)
+			return NULL;
+	}
+	else {
+		Py_ssize_t i, n;
+		PyObject *base;
+		if (!PyTuple_Check(bases)) {
+			PyErr_SetString(PyExc_TypeError,
+					"PyClass_New: bases must be a tuple");
+			return NULL;
+		}
+		n = PyTuple_Size(bases);
+		for (i = 0; i < n; i++) {
+			base = PyTuple_GET_ITEM(bases, i);
+			if (!PyClass_Check(base)) {
+				if (PyCallable_Check(
+					(PyObject *) base->ob_type))
+					return PyObject_CallFunctionObjArgs(
+						(PyObject *) base->ob_type,
+						name, bases, dict, NULL);
+				PyErr_SetString(PyExc_TypeError,
+					"PyClass_New: base must be a class");
+				return NULL;
+			}
+		}
+		Py_INCREF(bases);
+	}
+
+	if (getattrstr == NULL) {
+		getattrstr = PyString_InternFromString("__getattr__");
+		if (getattrstr == NULL)
+			goto alloc_error;
+		setattrstr = PyString_InternFromString("__setattr__");
+		if (setattrstr == NULL)
+			goto alloc_error;
+		delattrstr = PyString_InternFromString("__delattr__");
+		if (delattrstr == NULL)
+			goto alloc_error;
+	}
+
+	op = PyObject_GC_New(PyClassObject, &PyClass_Type);
+	if (op == NULL) {
+alloc_error:
+		Py_DECREF(bases);
+		return NULL;
+	}
+	op->cl_bases = bases;
+	Py_INCREF(dict);
+	op->cl_dict = dict;
+	Py_XINCREF(name);
+	op->cl_name = name;
+
+	op->cl_getattr = class_lookup(op, getattrstr, &dummy);
+	op->cl_setattr = class_lookup(op, setattrstr, &dummy);
+	op->cl_delattr = class_lookup(op, delattrstr, &dummy);
+	Py_XINCREF(op->cl_getattr);
+	Py_XINCREF(op->cl_setattr);
+	Py_XINCREF(op->cl_delattr);
+	_PyObject_GC_TRACK(op);
+	return (PyObject *) op;
+}
+
+PyObject *
+PyMethod_Function(PyObject *im)
+{
+	if (!PyMethod_Check(im)) {
+		PyErr_BadInternalCall();
+		return NULL;
+	}
+	return ((PyMethodObject *)im)->im_func;
+}
+
+PyObject *
+PyMethod_Self(PyObject *im)
+{
+	if (!PyMethod_Check(im)) {
+		PyErr_BadInternalCall();
+		return NULL;
+	}
+	return ((PyMethodObject *)im)->im_self;
+}
+
+PyObject *
+PyMethod_Class(PyObject *im)
+{
+	if (!PyMethod_Check(im)) {
+		PyErr_BadInternalCall();
+		return NULL;
+	}
+	return ((PyMethodObject *)im)->im_class;
+}
+
+PyDoc_STRVAR(class_doc,
+"classobj(name, bases, dict)\n\
+\n\
+Create a class object.  The name must be a string; the second argument\n\
+a tuple of classes, and the third a dictionary.");
+
+static PyObject *
+class_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	PyObject *name, *bases, *dict;
+	static char *kwlist[] = {"name", "bases", "dict", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwds, "SOO", kwlist,
+					 &name, &bases, &dict))
+		return NULL;
+	return PyClass_New(bases, dict, name);
+}
+
+/* Class methods */
+
+static void
+class_dealloc(PyClassObject *op)
+{
+	_PyObject_GC_UNTRACK(op);
+	Py_DECREF(op->cl_bases);
+	Py_DECREF(op->cl_dict);
+	Py_XDECREF(op->cl_name);
+	Py_XDECREF(op->cl_getattr);
+	Py_XDECREF(op->cl_setattr);
+	Py_XDECREF(op->cl_delattr);
+	PyObject_GC_Del(op);
+}
+
+static PyObject *
+class_lookup(PyClassObject *cp, PyObject *name, PyClassObject **pclass)
+{
+	Py_ssize_t i, n;
+	PyObject *value = PyDict_GetItem(cp->cl_dict, name);
+	if (value != NULL) {
+		*pclass = cp;
+		return value;
+	}
+	n = PyTuple_Size(cp->cl_bases);
+	for (i = 0; i < n; i++) {
+		/* XXX What if one of the bases is not a class? */
+		PyObject *v = class_lookup(
+			(PyClassObject *)
+			PyTuple_GetItem(cp->cl_bases, i), name, pclass);
+		if (v != NULL)
+			return v;
+	}
+	return NULL;
+}
+
+static PyObject *
+class_getattr(register PyClassObject *op, PyObject *name)
+{
+	register PyObject *v;
+	register char *sname = PyString_AsString(name);
+	PyClassObject *klass;
+	descrgetfunc f;
+
+	if (sname[0] == '_' && sname[1] == '_') {
+		if (strcmp(sname, "__dict__") == 0) {
+			if (PyEval_GetRestricted()) {
+				PyErr_SetString(PyExc_RuntimeError,
+			   "class.__dict__ not accessible in restricted mode");
+				return NULL;
+			}
+			Py_INCREF(op->cl_dict);
+			return op->cl_dict;
+		}
+		if (strcmp(sname, "__bases__") == 0) {
+			Py_INCREF(op->cl_bases);
+			return op->cl_bases;
+		}
+		if (strcmp(sname, "__name__") == 0) {
+			if (op->cl_name == NULL)
+				v = Py_None;
+			else
+				v = op->cl_name;
+			Py_INCREF(v);
+			return v;
+		}
+	}
+	v = class_lookup(op, name, &klass);
+	if (v == NULL) {
+		PyErr_Format(PyExc_AttributeError,
+			     "class %.50s has no attribute '%.400s'",
+			     PyString_AS_STRING(op->cl_name), sname);
+		return NULL;
+	}
+	f = TP_DESCR_GET(v->ob_type);
+	if (f == NULL)
+		Py_INCREF(v);
+	else
+		v = f(v, (PyObject *)NULL, (PyObject *)op);
+	return v;
+}
+
+static void
+set_slot(PyObject **slot, PyObject *v)
+{
+	PyObject *temp = *slot;
+	Py_XINCREF(v);
+	*slot = v;
+	Py_XDECREF(temp);
+}
+
+static void
+set_attr_slots(PyClassObject *c)
+{
+	PyClassObject *dummy;
+
+	set_slot(&c->cl_getattr, class_lookup(c, getattrstr, &dummy));
+	set_slot(&c->cl_setattr, class_lookup(c, setattrstr, &dummy));
+	set_slot(&c->cl_delattr, class_lookup(c, delattrstr, &dummy));
+}
+
+static char *
+set_dict(PyClassObject *c, PyObject *v)
+{
+	if (v == NULL || !PyDict_Check(v))
+		return "__dict__ must be a dictionary object";
+	set_slot(&c->cl_dict, v);
+	set_attr_slots(c);
+	return "";
+}
+
+static char *
+set_bases(PyClassObject *c, PyObject *v)
+{
+	Py_ssize_t i, n;
+
+	if (v == NULL || !PyTuple_Check(v))
+		return "__bases__ must be a tuple object";
+	n = PyTuple_Size(v);
+	for (i = 0; i < n; i++) {
+		PyObject *x = PyTuple_GET_ITEM(v, i);
+		if (!PyClass_Check(x))
+			return "__bases__ items must be classes";
+		if (PyClass_IsSubclass(x, (PyObject *)c))
+			return "a __bases__ item causes an inheritance cycle";
+	}
+	set_slot(&c->cl_bases, v);
+	set_attr_slots(c);
+	return "";
+}
+
+static char *
+set_name(PyClassObject *c, PyObject *v)
+{
+	if (v == NULL || !PyString_Check(v))
+		return "__name__ must be a string object";
+	if (strlen(PyString_AS_STRING(v)) != (size_t)PyString_GET_SIZE(v))
+		return "__name__ must not contain null bytes";
+	set_slot(&c->cl_name, v);
+	return "";
+}
+
+static int
+class_setattr(PyClassObject *op, PyObject *name, PyObject *v)
+{
+	char *sname;
+	if (PyEval_GetRestricted()) {
+		PyErr_SetString(PyExc_RuntimeError,
+			   "classes are read-only in restricted mode");
+		return -1;
+	}
+	sname = PyString_AsString(name);
+	if (sname[0] == '_' && sname[1] == '_') {
+		Py_ssize_t n = PyString_Size(name);
+		if (sname[n-1] == '_' && sname[n-2] == '_') {
+			char *err = NULL;
+			if (strcmp(sname, "__dict__") == 0)
+				err = set_dict(op, v);
+			else if (strcmp(sname, "__bases__") == 0)
+				err = set_bases(op, v);
+			else if (strcmp(sname, "__name__") == 0)
+				err = set_name(op, v);
+			else if (strcmp(sname, "__getattr__") == 0)
+				set_slot(&op->cl_getattr, v);
+			else if (strcmp(sname, "__setattr__") == 0)
+				set_slot(&op->cl_setattr, v);
+			else if (strcmp(sname, "__delattr__") == 0)
+				set_slot(&op->cl_delattr, v);
+			/* For the last three, we fall through to update the
+			   dictionary as well. */
+			if (err != NULL) {
+				if (*err == '\0')
+					return 0;
+				PyErr_SetString(PyExc_TypeError, err);
+				return -1;
+			}
+		}
+	}
+	if (v == NULL) {
+		int rv = PyDict_DelItem(op->cl_dict, name);
+		if (rv < 0)
+			PyErr_Format(PyExc_AttributeError,
+				     "class %.50s has no attribute '%.400s'",
+				     PyString_AS_STRING(op->cl_name), sname);
+		return rv;
+	}
+	else
+		return PyDict_SetItem(op->cl_dict, name, v);
+}
+
+static PyObject *
+class_repr(PyClassObject *op)
+{
+	PyObject *mod = PyDict_GetItemString(op->cl_dict, "__module__");
+	char *name;
+	if (op->cl_name == NULL || !PyString_Check(op->cl_name))
+		name = "?";
+	else
+		name = PyString_AsString(op->cl_name);
+	if (mod == NULL || !PyString_Check(mod))
+		return PyString_FromFormat("<class ?.%s at %p>", name, op);
+	else
+		return PyString_FromFormat("<class %s.%s at %p>",
+					   PyString_AsString(mod),
+					   name, op);
+}
+
+static PyObject *
+class_str(PyClassObject *op)
+{
+	PyObject *mod = PyDict_GetItemString(op->cl_dict, "__module__");
+	PyObject *name = op->cl_name;
+	PyObject *res;
+	Py_ssize_t m, n;
+
+	if (name == NULL || !PyString_Check(name))
+		return class_repr(op);
+	if (mod == NULL || !PyString_Check(mod)) {
+		Py_INCREF(name);
+		return name;
+	}
+	m = PyString_GET_SIZE(mod);
+	n = PyString_GET_SIZE(name);
+	res = PyString_FromStringAndSize((char *)NULL, m+1+n);
+	if (res != NULL) {
+		char *s = PyString_AS_STRING(res);
+		memcpy(s, PyString_AS_STRING(mod), m);
+		s += m;
+		*s++ = '.';
+		memcpy(s, PyString_AS_STRING(name), n);
+	}
+	return res;
+}
+
+static int
+class_traverse(PyClassObject *o, visitproc visit, void *arg)
+{
+	Py_VISIT(o->cl_bases);
+	Py_VISIT(o->cl_dict);
+	Py_VISIT(o->cl_name);
+	Py_VISIT(o->cl_getattr);
+	Py_VISIT(o->cl_setattr);
+	Py_VISIT(o->cl_delattr);
+	return 0;
+}
+
+PyTypeObject PyClass_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,
+	"classobj",
+	sizeof(PyClassObject),
+	0,
+	(destructor)class_dealloc,		/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	(reprfunc)class_repr,			/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	PyInstance_New,				/* tp_call */
+	(reprfunc)class_str,			/* tp_str */
+	(getattrofunc)class_getattr,		/* tp_getattro */
+	(setattrofunc)class_setattr,		/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+	class_doc,				/* tp_doc */
+	(traverseproc)class_traverse,		/* tp_traverse */
+ 	0,					/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	0,					/* tp_methods */
+	0,					/* tp_members */
+	0,					/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	0,					/* tp_init */
+	0,					/* tp_alloc */
+	class_new,				/* tp_new */
+};
+
+int
+PyClass_IsSubclass(PyObject *klass, PyObject *base)
+{
+	Py_ssize_t i, n;
+	PyClassObject *cp;
+	if (klass == base)
+		return 1;
+	if (PyTuple_Check(base)) {
+		n = PyTuple_GET_SIZE(base);
+		for (i = 0; i < n; i++) {
+			if (PyClass_IsSubclass(klass, PyTuple_GET_ITEM(base, i)))
+				return 1;
+		}
+		return 0;
+	}
+	if (klass == NULL || !PyClass_Check(klass))
+		return 0;
+	cp = (PyClassObject *)klass;
+	n = PyTuple_Size(cp->cl_bases);
+	for (i = 0; i < n; i++) {
+		if (PyClass_IsSubclass(PyTuple_GetItem(cp->cl_bases, i), base))
+			return 1;
+	}
+	return 0;
+}
+
+
+/* Instance objects */
+
+PyObject *
+PyInstance_NewRaw(PyObject *klass, PyObject *dict)
+{
+	PyInstanceObject *inst;
+
+	if (!PyClass_Check(klass)) {
+		PyErr_BadInternalCall();
+		return NULL;
+	}
+	if (dict == NULL) {
+		dict = PyDict_New();
+		if (dict == NULL)
+			return NULL;
+	}
+	else {
+		if (!PyDict_Check(dict)) {
+			PyErr_BadInternalCall();
+			return NULL;
+		}
+		Py_INCREF(dict);
+	}
+	inst = PyObject_GC_New(PyInstanceObject, &PyInstance_Type);
+	if (inst == NULL) {
+		Py_DECREF(dict);
+		return NULL;
+	}
+	inst->in_weakreflist = NULL;
+	Py_INCREF(klass);
+	inst->in_class = (PyClassObject *)klass;
+	inst->in_dict = dict;
+	_PyObject_GC_TRACK(inst);
+	return (PyObject *)inst;
+}
+
+PyObject *
+PyInstance_New(PyObject *klass, PyObject *arg, PyObject *kw)
+{
+	register PyInstanceObject *inst;
+	PyObject *init;
+	static PyObject *initstr;
+
+	if (initstr == NULL) {
+		initstr = PyString_InternFromString("__init__");
+		if (initstr == NULL)
+			return NULL;
+	}
+	inst = (PyInstanceObject *) PyInstance_NewRaw(klass, NULL);
+	if (inst == NULL)
+		return NULL;
+	init = instance_getattr2(inst, initstr);
+	if (init == NULL) {
+		if (PyErr_Occurred()) {
+			Py_DECREF(inst);
+			return NULL;
+		}
+		if ((arg != NULL && (!PyTuple_Check(arg) ||
+				     PyTuple_Size(arg) != 0))
+		    || (kw != NULL && (!PyDict_Check(kw) ||
+				      PyDict_Size(kw) != 0))) {
+			PyErr_SetString(PyExc_TypeError,
+				   "this constructor takes no arguments");
+			Py_DECREF(inst);
+			inst = NULL;
+		}
+	}
+	else {
+		PyObject *res = PyEval_CallObjectWithKeywords(init, arg, kw);
+		Py_DECREF(init);
+		if (res == NULL) {
+			Py_DECREF(inst);
+			inst = NULL;
+		}
+		else {
+			if (res != Py_None) {
+				PyErr_SetString(PyExc_TypeError,
+					   "__init__() should return None");
+				Py_DECREF(inst);
+				inst = NULL;
+			}
+			Py_DECREF(res);
+		}
+	}
+	return (PyObject *)inst;
+}
+
+/* Instance methods */
+
+PyDoc_STRVAR(instance_doc,
+"instance(class[, dict])\n\
+\n\
+Create an instance without calling its __init__() method.\n\
+The class must be a classic class.\n\
+If present, dict must be a dictionary or None.");
+
+static PyObject *
+instance_new(PyTypeObject* type, PyObject* args, PyObject *kw)
+{
+	PyObject *klass;
+	PyObject *dict = Py_None;
+
+	if (!PyArg_ParseTuple(args, "O!|O:instance",
+			      &PyClass_Type, &klass, &dict))
+		return NULL;
+
+	if (dict == Py_None)
+		dict = NULL;
+	else if (!PyDict_Check(dict)) {
+		PyErr_SetString(PyExc_TypeError,
+		      "instance() second arg must be dictionary or None");
+		return NULL;
+	}
+	return PyInstance_NewRaw(klass, dict);
+}
+
+
+static void
+instance_dealloc(register PyInstanceObject *inst)
+{
+	PyObject *error_type, *error_value, *error_traceback;
+	PyObject *del;
+	static PyObject *delstr;
+
+	_PyObject_GC_UNTRACK(inst);
+	if (inst->in_weakreflist != NULL)
+		PyObject_ClearWeakRefs((PyObject *) inst);
+
+	/* Temporarily resurrect the object. */
+	assert(inst->ob_type == &PyInstance_Type);
+	assert(inst->ob_refcnt == 0);
+	inst->ob_refcnt = 1;
+
+	/* Save the current exception, if any. */
+	PyErr_Fetch(&error_type, &error_value, &error_traceback);
+	/* Execute __del__ method, if any. */
+	if (delstr == NULL) {
+		delstr = PyString_InternFromString("__del__");
+		if (delstr == NULL)
+			PyErr_WriteUnraisable((PyObject*)inst);
+	}
+	if (delstr && (del = instance_getattr2(inst, delstr)) != NULL) {
+		PyObject *res = PyEval_CallObject(del, (PyObject *)NULL);
+		if (res == NULL)
+			PyErr_WriteUnraisable(del);
+		else
+			Py_DECREF(res);
+		Py_DECREF(del);
+	}
+	/* Restore the saved exception. */
+	PyErr_Restore(error_type, error_value, error_traceback);
+
+	/* Undo the temporary resurrection; can't use DECREF here, it would
+	 * cause a recursive call.
+	 */
+	assert(inst->ob_refcnt > 0);
+	if (--inst->ob_refcnt == 0) {
+		Py_DECREF(inst->in_class);
+		Py_XDECREF(inst->in_dict);
+		PyObject_GC_Del(inst);
+	}
+	else {
+		Py_ssize_t refcnt = inst->ob_refcnt;
+		/* __del__ resurrected it!  Make it look like the original
+		 * Py_DECREF never happened.
+		 */
+		_Py_NewReference((PyObject *)inst);
+		inst->ob_refcnt = refcnt;
+		_PyObject_GC_TRACK(inst);
+		/* If Py_REF_DEBUG, _Py_NewReference bumped _Py_RefTotal, so
+		 * we need to undo that. */
+		_Py_DEC_REFTOTAL;
+		/* If Py_TRACE_REFS, _Py_NewReference re-added self to the
+		 * object chain, so no more to do there.
+		 * If COUNT_ALLOCS, the original decref bumped tp_frees, and
+		 * _Py_NewReference bumped tp_allocs: both of those need to be
+		 * undone.
+		 */
+#ifdef COUNT_ALLOCS
+		--inst->ob_type->tp_frees;
+		--inst->ob_type->tp_allocs;
+#endif
+	}
+}
+
+static PyObject *
+instance_getattr1(register PyInstanceObject *inst, PyObject *name)
+{
+	register PyObject *v;
+	register char *sname = PyString_AsString(name);
+	if (sname[0] == '_' && sname[1] == '_') {
+		if (strcmp(sname, "__dict__") == 0) {
+			if (PyEval_GetRestricted()) {
+				PyErr_SetString(PyExc_RuntimeError,
+			"instance.__dict__ not accessible in restricted mode");
+				return NULL;
+			}
+			Py_INCREF(inst->in_dict);
+			return inst->in_dict;
+		}
+		if (strcmp(sname, "__class__") == 0) {
+			Py_INCREF(inst->in_class);
+			return (PyObject *)inst->in_class;
+		}
+	}
+	v = instance_getattr2(inst, name);
+	if (v == NULL && !PyErr_Occurred()) {
+		PyErr_Format(PyExc_AttributeError,
+			     "%.50s instance has no attribute '%.400s'",
+			     PyString_AS_STRING(inst->in_class->cl_name), sname);
+	}
+	return v;
+}
+
+static PyObject *
+instance_getattr2(register PyInstanceObject *inst, PyObject *name)
+{
+	register PyObject *v;
+	PyClassObject *klass;
+	descrgetfunc f;
+
+	v = PyDict_GetItem(inst->in_dict, name);
+	if (v != NULL) {
+		Py_INCREF(v);
+		return v;
+	}
+	v = class_lookup(inst->in_class, name, &klass);
+	if (v != NULL) {
+		Py_INCREF(v);
+		f = TP_DESCR_GET(v->ob_type);
+		if (f != NULL) {
+			PyObject *w = f(v, (PyObject *)inst,
+					(PyObject *)(inst->in_class));
+			Py_DECREF(v);
+			v = w;
+		}
+	}
+	return v;
+}
+
+static PyObject *
+instance_getattr(register PyInstanceObject *inst, PyObject *name)
+{
+	register PyObject *func, *res;
+	res = instance_getattr1(inst, name);
+	if (res == NULL && (func = inst->in_class->cl_getattr) != NULL) {
+		PyObject *args;
+		if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+			return NULL;
+		PyErr_Clear();
+		args = PyTuple_Pack(2, inst, name);
+		if (args == NULL)
+			return NULL;
+		res = PyEval_CallObject(func, args);
+		Py_DECREF(args);
+	}
+	return res;
+}
+
+/* See classobject.h comments:  this only does dict lookups, and is always
+ * safe to call.
+ */
+PyObject *
+_PyInstance_Lookup(PyObject *pinst, PyObject *name)
+{
+	PyObject *v;
+	PyClassObject *klass;
+	PyInstanceObject *inst;	/* pinst cast to the right type */
+
+	assert(PyInstance_Check(pinst));
+	inst = (PyInstanceObject *)pinst;
+
+	assert(PyString_Check(name));
+
+ 	v = PyDict_GetItem(inst->in_dict, name);
+	if (v == NULL)
+		v = class_lookup(inst->in_class, name, &klass);
+	return v;
+}
+
+static int
+instance_setattr1(PyInstanceObject *inst, PyObject *name, PyObject *v)
+{
+	if (v == NULL) {
+		int rv = PyDict_DelItem(inst->in_dict, name);
+		if (rv < 0)
+			PyErr_Format(PyExc_AttributeError,
+				     "%.50s instance has no attribute '%.400s'",
+				     PyString_AS_STRING(inst->in_class->cl_name),
+				     PyString_AS_STRING(name));
+		return rv;
+	}
+	else
+		return PyDict_SetItem(inst->in_dict, name, v);
+}
+
+static int
+instance_setattr(PyInstanceObject *inst, PyObject *name, PyObject *v)
+{
+	PyObject *func, *args, *res, *tmp;
+	char *sname = PyString_AsString(name);
+	if (sname[0] == '_' && sname[1] == '_') {
+		Py_ssize_t n = PyString_Size(name);
+		if (sname[n-1] == '_' && sname[n-2] == '_') {
+			if (strcmp(sname, "__dict__") == 0) {
+				if (PyEval_GetRestricted()) {
+					PyErr_SetString(PyExc_RuntimeError,
+				 "__dict__ not accessible in restricted mode");
+					return -1;
+				}
+				if (v == NULL || !PyDict_Check(v)) {
+				    PyErr_SetString(PyExc_TypeError,
+				       "__dict__ must be set to a dictionary");
+				    return -1;
+				}
+				tmp = inst->in_dict;
+				Py_INCREF(v);
+				inst->in_dict = v;
+				Py_DECREF(tmp);
+				return 0;
+			}
+			if (strcmp(sname, "__class__") == 0) {
+				if (PyEval_GetRestricted()) {
+					PyErr_SetString(PyExc_RuntimeError,
+				"__class__ not accessible in restricted mode");
+					return -1;
+				}
+				if (v == NULL || !PyClass_Check(v)) {
+					PyErr_SetString(PyExc_TypeError,
+					   "__class__ must be set to a class");
+					return -1;
+				}
+				tmp = (PyObject *)(inst->in_class);
+				Py_INCREF(v);
+				inst->in_class = (PyClassObject *)v;
+				Py_DECREF(tmp);
+				return 0;
+			}
+		}
+	}
+	if (v == NULL)
+		func = inst->in_class->cl_delattr;
+	else
+		func = inst->in_class->cl_setattr;
+	if (func == NULL)
+		return instance_setattr1(inst, name, v);
+	if (v == NULL)
+		args = PyTuple_Pack(2, inst, name);
+	else
+		args = PyTuple_Pack(3, inst, name, v);
+	if (args == NULL)
+		return -1;
+	res = PyEval_CallObject(func, args);
+	Py_DECREF(args);
+	if (res == NULL)
+		return -1;
+	Py_DECREF(res);
+	return 0;
+}
+
+static PyObject *
+instance_repr(PyInstanceObject *inst)
+{
+	PyObject *func;
+	PyObject *res;
+	static PyObject *reprstr;
+
+	if (reprstr == NULL) {
+		reprstr = PyString_InternFromString("__repr__");
+		if (reprstr == NULL)
+			return NULL;
+	}
+	func = instance_getattr(inst, reprstr);
+	if (func == NULL) {
+		PyObject *classname, *mod;
+		char *cname;
+		if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+			return NULL;
+		PyErr_Clear();
+		classname = inst->in_class->cl_name;
+		mod = PyDict_GetItemString(inst->in_class->cl_dict,
+					   "__module__");
+		if (classname != NULL && PyString_Check(classname))
+			cname = PyString_AsString(classname);
+		else
+			cname = "?";
+		if (mod == NULL || !PyString_Check(mod))
+			return PyString_FromFormat("<?.%s instance at %p>",
+						   cname, inst);
+		else
+			return PyString_FromFormat("<%s.%s instance at %p>",
+						   PyString_AsString(mod),
+						   cname, inst);
+	}
+	res = PyEval_CallObject(func, (PyObject *)NULL);
+	Py_DECREF(func);
+	return res;
+}
+
+static PyObject *
+instance_str(PyInstanceObject *inst)
+{
+	PyObject *func;
+	PyObject *res;
+	static PyObject *strstr;
+
+	if (strstr == NULL) {
+		strstr = PyString_InternFromString("__str__");
+		if (strstr == NULL)
+			return NULL;
+	}
+	func = instance_getattr(inst, strstr);
+	if (func == NULL) {
+		if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+			return NULL;
+		PyErr_Clear();
+		return instance_repr(inst);
+	}
+	res = PyEval_CallObject(func, (PyObject *)NULL);
+	Py_DECREF(func);
+	return res;
+}
+
+static long
+instance_hash(PyInstanceObject *inst)
+{
+	PyObject *func;
+	PyObject *res;
+	long outcome;
+	static PyObject *hashstr, *eqstr, *cmpstr;
+
+	if (hashstr == NULL) {
+		hashstr = PyString_InternFromString("__hash__");
+		if (hashstr == NULL)
+			return -1;
+	}
+	func = instance_getattr(inst, hashstr);
+	if (func == NULL) {
+		if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+			return -1;
+		PyErr_Clear();
+		/* If there is no __eq__ and no __cmp__ method, we hash on the
+		   address.  If an __eq__ or __cmp__ method exists, there must
+		   be a __hash__. */
+		if (eqstr == NULL) {
+			eqstr = PyString_InternFromString("__eq__");
+			if (eqstr == NULL)
+				return -1;
+		}
+		func = instance_getattr(inst, eqstr);
+		if (func == NULL) {
+			if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+				return -1;
+			PyErr_Clear();
+			if (cmpstr == NULL) {
+				cmpstr = PyString_InternFromString("__cmp__");
+				if (cmpstr == NULL)
+					return -1;
+			}
+			func = instance_getattr(inst, cmpstr);
+			if (func == NULL) {
+				if (!PyErr_ExceptionMatches(
+					PyExc_AttributeError))
+					return -1;
+				PyErr_Clear();
+				return _Py_HashPointer(inst);
+			}
+		}
+		Py_XDECREF(func);
+		PyErr_SetString(PyExc_TypeError, "unhashable instance");
+		return -1;
+	}
+	res = PyEval_CallObject(func, (PyObject *)NULL);
+	Py_DECREF(func);
+	if (res == NULL)
+		return -1;
+	if (PyInt_Check(res) || PyLong_Check(res))
+		/* This already converts a -1 result to -2. */
+		outcome = res->ob_type->tp_hash(res);
+	else {
+		PyErr_SetString(PyExc_TypeError,
+				"__hash__() should return an int");
+		outcome = -1;
+	}
+	Py_DECREF(res);
+	return outcome;
+}
+
+static int
+instance_traverse(PyInstanceObject *o, visitproc visit, void *arg)
+{
+	Py_VISIT(o->in_class);
+	Py_VISIT(o->in_dict);
+	return 0;
+}
+
+static PyObject *getitemstr, *setitemstr, *delitemstr, *lenstr;
+static PyObject *iterstr, *nextstr;
+
+static Py_ssize_t
+instance_length(PyInstanceObject *inst)
+{
+	PyObject *func;
+	PyObject *res;
+	Py_ssize_t outcome;
+
+	if (lenstr == NULL) {
+		lenstr = PyString_InternFromString("__len__");
+		if (lenstr == NULL)
+			return -1;
+	}
+	func = instance_getattr(inst, lenstr);
+	if (func == NULL)
+		return -1;
+	res = PyEval_CallObject(func, (PyObject *)NULL);
+	Py_DECREF(func);
+	if (res == NULL)
+		return -1;
+	if (PyInt_Check(res)) {
+		outcome = PyInt_AsSsize_t(res);
+		if (outcome == -1 && PyErr_Occurred()) {
+			Py_DECREF(res);
+			return -1;
+		}
+#if SIZEOF_SIZE_T < SIZEOF_INT
+		/* Overflow check -- range of PyInt is more than C int */
+		if (outcome != (int)outcome) {
+			PyErr_SetString(PyExc_OverflowError,
+			 "__len__() should return 0 <= outcome < 2**31");
+			outcome = -1;
+		}
+		else
+#endif
+		if (outcome < 0) {
+			PyErr_SetString(PyExc_ValueError,
+					"__len__() should return >= 0");
+			outcome = -1;
+		}
+	}
+	else {
+		PyErr_SetString(PyExc_TypeError,
+				"__len__() should return an int");
+		outcome = -1;
+	}
+	Py_DECREF(res);
+	return outcome;
+}
+
+static PyObject *
+instance_subscript(PyInstanceObject *inst, PyObject *key)
+{
+	PyObject *func;
+	PyObject *arg;
+	PyObject *res;
+
+	if (getitemstr == NULL) {
+		getitemstr = PyString_InternFromString("__getitem__");
+		if (getitemstr == NULL)
+			return NULL;
+	}
+	func = instance_getattr(inst, getitemstr);
+	if (func == NULL)
+		return NULL;
+	arg = PyTuple_Pack(1, key);
+	if (arg == NULL) {
+		Py_DECREF(func);
+		return NULL;
+	}
+	res = PyEval_CallObject(func, arg);
+	Py_DECREF(func);
+	Py_DECREF(arg);
+	return res;
+}
+
+static int
+instance_ass_subscript(PyInstanceObject *inst, PyObject *key, PyObject *value)
+{
+	PyObject *func;
+	PyObject *arg;
+	PyObject *res;
+
+	if (value == NULL) {
+		if (delitemstr == NULL) {
+			delitemstr = PyString_InternFromString("__delitem__");
+			if (delitemstr == NULL)
+				return -1;
+		}
+		func = instance_getattr(inst, delitemstr);
+	}
+	else {
+		if (setitemstr == NULL) {
+			setitemstr = PyString_InternFromString("__setitem__");
+			if (setitemstr == NULL)
+				return -1;
+		}
+		func = instance_getattr(inst, setitemstr);
+	}
+	if (func == NULL)
+		return -1;
+	if (value == NULL)
+		arg = PyTuple_Pack(1, key);
+	else
+		arg = PyTuple_Pack(2, key, value);
+	if (arg == NULL) {
+		Py_DECREF(func);
+		return -1;
+	}
+	res = PyEval_CallObject(func, arg);
+	Py_DECREF(func);
+	Py_DECREF(arg);
+	if (res == NULL)
+		return -1;
+	Py_DECREF(res);
+	return 0;
+}
+
+static PyMappingMethods instance_as_mapping = {
+	(lenfunc)instance_length,		/* mp_length */
+	(binaryfunc)instance_subscript,		/* mp_subscript */
+	(objobjargproc)instance_ass_subscript,	/* mp_ass_subscript */
+};
+
+static PyObject *
+instance_item(PyInstanceObject *inst, Py_ssize_t i)
+{
+	PyObject *func, *res;
+
+	if (getitemstr == NULL) {
+		getitemstr = PyString_InternFromString("__getitem__");
+		if (getitemstr == NULL)
+			return NULL;
+	}
+	func = instance_getattr(inst, getitemstr);
+	if (func == NULL)
+		return NULL;
+	res = PyObject_CallFunction(func, "n", i);
+	Py_DECREF(func);
+	return res;
+}
+
+static PyObject *
+instance_slice(PyInstanceObject *inst, Py_ssize_t i, Py_ssize_t j)
+{
+	PyObject *func, *arg, *res;
+	static PyObject *getslicestr;
+
+	if (getslicestr == NULL) {
+		getslicestr = PyString_InternFromString("__getslice__");
+		if (getslicestr == NULL)
+			return NULL;
+	}
+	func = instance_getattr(inst, getslicestr);
+
+	if (func == NULL) {
+		if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+			return NULL;
+		PyErr_Clear();
+
+		if (getitemstr == NULL) {
+			getitemstr = PyString_InternFromString("__getitem__");
+			if (getitemstr == NULL)
+				return NULL;
+		}
+		func = instance_getattr(inst, getitemstr);
+		if (func == NULL)
+			return NULL;
+		arg = Py_BuildValue("(N)", _PySlice_FromIndices(i, j));
+	} else
+		arg = Py_BuildValue("(nn)", i, j);
+
+	if (arg == NULL) {
+		Py_DECREF(func);
+		return NULL;
+	}
+	res = PyEval_CallObject(func, arg);
+	Py_DECREF(func);
+	Py_DECREF(arg);
+	return res;
+}
+
+static int
+instance_ass_item(PyInstanceObject *inst, Py_ssize_t i, PyObject *item)
+{
+	PyObject *func, *arg, *res;
+
+	if (item == NULL) {
+		if (delitemstr == NULL) {
+			delitemstr = PyString_InternFromString("__delitem__");
+			if (delitemstr == NULL)
+				return -1;
+		}
+		func = instance_getattr(inst, delitemstr);
+	}
+	else {
+		if (setitemstr == NULL) {
+			setitemstr = PyString_InternFromString("__setitem__");
+			if (setitemstr == NULL)
+				return -1;
+		}
+		func = instance_getattr(inst, setitemstr);
+	}
+	if (func == NULL)
+		return -1;
+	if (item == NULL)
+		arg = PyInt_FromSsize_t(i);
+	else
+		arg = Py_BuildValue("(nO)", i, item);
+	if (arg == NULL) {
+		Py_DECREF(func);
+		return -1;
+	}
+	res = PyEval_CallObject(func, arg);
+	Py_DECREF(func);
+	Py_DECREF(arg);
+	if (res == NULL)
+		return -1;
+	Py_DECREF(res);
+	return 0;
+}
+
+static int
+instance_ass_slice(PyInstanceObject *inst, Py_ssize_t i, Py_ssize_t j, PyObject *value)
+{
+	PyObject *func, *arg, *res;
+	static PyObject *setslicestr, *delslicestr;
+
+	if (value == NULL) {
+		if (delslicestr == NULL) {
+			delslicestr =
+				PyString_InternFromString("__delslice__");
+			if (delslicestr == NULL)
+				return -1;
+		}
+		func = instance_getattr(inst, delslicestr);
+		if (func == NULL) {
+			if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+				return -1;
+			PyErr_Clear();
+			if (delitemstr == NULL) {
+				delitemstr =
+				    PyString_InternFromString("__delitem__");
+				if (delitemstr == NULL)
+					return -1;
+			}
+			func = instance_getattr(inst, delitemstr);
+			if (func == NULL)
+				return -1;
+
+			arg = Py_BuildValue("(N)",
+					    _PySlice_FromIndices(i, j));
+		} else
+			arg = Py_BuildValue("(nn)", i, j);
+	}
+	else {
+		if (setslicestr == NULL) {
+			setslicestr =
+				PyString_InternFromString("__setslice__");
+			if (setslicestr == NULL)
+				return -1;
+		}
+		func = instance_getattr(inst, setslicestr);
+		if (func == NULL) {
+			if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+				return -1;
+			PyErr_Clear();
+			if (setitemstr == NULL) {
+				setitemstr =
+				    PyString_InternFromString("__setitem__");
+				if (setitemstr == NULL)
+					return -1;
+			}
+			func = instance_getattr(inst, setitemstr);
+			if (func == NULL)
+				return -1;
+
+			arg = Py_BuildValue("(NO)",
+					    _PySlice_FromIndices(i, j), value);
+		} else
+			arg = Py_BuildValue("(nnO)", i, j, value);
+	}
+	if (arg == NULL) {
+		Py_DECREF(func);
+		return -1;
+	}
+	res = PyEval_CallObject(func, arg);
+	Py_DECREF(func);
+	Py_DECREF(arg);
+	if (res == NULL)
+		return -1;
+	Py_DECREF(res);
+	return 0;
+}
+
+static int
+instance_contains(PyInstanceObject *inst, PyObject *member)
+{
+	static PyObject *__contains__;
+	PyObject *func;
+
+	/* Try __contains__ first.
+	 * If that can't be done, try iterator-based searching.
+	 */
+
+	if(__contains__ == NULL) {
+		__contains__ = PyString_InternFromString("__contains__");
+		if(__contains__ == NULL)
+			return -1;
+	}
+	func = instance_getattr(inst, __contains__);
+	if (func) {
+		PyObject *res;
+		int ret;
+		PyObject *arg = PyTuple_Pack(1, member);
+		if(arg == NULL) {
+			Py_DECREF(func);
+			return -1;
+		}
+		res = PyEval_CallObject(func, arg);
+		Py_DECREF(func);
+		Py_DECREF(arg);
+		if(res == NULL)
+			return -1;
+		ret = PyObject_IsTrue(res);
+		Py_DECREF(res);
+		return ret;
+	}
+
+	/* Couldn't find __contains__. */
+	if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
+		Py_ssize_t rc;
+		/* Assume the failure was simply due to that there is no
+		 * __contains__ attribute, and try iterating instead.
+		 */
+		PyErr_Clear();
+		rc = _PySequence_IterSearch((PyObject *)inst, member,
+					    PY_ITERSEARCH_CONTAINS);
+		if (rc >= 0)
+			return rc > 0;
+	}
+	return -1;
+}
+
+static PySequenceMethods
+instance_as_sequence = {
+	(lenfunc)instance_length,		/* sq_length */
+	0,					/* sq_concat */
+	0,					/* sq_repeat */
+	(ssizeargfunc)instance_item,		/* sq_item */
+	(ssizessizeargfunc)instance_slice,	/* sq_slice */
+	(ssizeobjargproc)instance_ass_item,	/* sq_ass_item */
+	(ssizessizeobjargproc)instance_ass_slice,/* sq_ass_slice */
+	(objobjproc)instance_contains,		/* sq_contains */
+};
+
+static PyObject *
+generic_unary_op(PyInstanceObject *self, PyObject *methodname)
+{
+	PyObject *func, *res;
+
+	if ((func = instance_getattr(self, methodname)) == NULL)
+		return NULL;
+	res = PyEval_CallObject(func, (PyObject *)NULL);
+	Py_DECREF(func);
+	return res;
+}
+
+static PyObject *
+generic_binary_op(PyObject *v, PyObject *w, char *opname)
+{
+	PyObject *result;
+	PyObject *args;
+	PyObject *func = PyObject_GetAttrString(v, opname);
+	if (func == NULL) {
+		if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+			return NULL;
+		PyErr_Clear();
+		Py_INCREF(Py_NotImplemented);
+		return Py_NotImplemented;
+	}
+	args = PyTuple_Pack(1, w);
+	if (args == NULL) {
+		Py_DECREF(func);
+		return NULL;
+	}
+	result = PyEval_CallObject(func, args);
+	Py_DECREF(args);
+	Py_DECREF(func);
+	return result;
+}
+
+
+static PyObject *coerce_obj;
+
+/* Try one half of a binary operator involving a class instance. */
+static PyObject *
+half_binop(PyObject *v, PyObject *w, char *opname, binaryfunc thisfunc,
+		int swapped)
+{
+	PyObject *args;
+	PyObject *coercefunc;
+	PyObject *coerced = NULL;
+	PyObject *v1;
+	PyObject *result;
+
+	if (!PyInstance_Check(v)) {
+		Py_INCREF(Py_NotImplemented);
+		return Py_NotImplemented;
+	}
+
+	if (coerce_obj == NULL) {
+		coerce_obj = PyString_InternFromString("__coerce__");
+		if (coerce_obj == NULL)
+			return NULL;
+	}
+	coercefunc = PyObject_GetAttr(v, coerce_obj);
+	if (coercefunc == NULL) {
+		if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+			return NULL;
+		PyErr_Clear();
+		return generic_binary_op(v, w, opname);
+	}
+
+	args = PyTuple_Pack(1, w);
+	if (args == NULL) {
+		Py_DECREF(coercefunc);
+		return NULL;
+	}
+	coerced = PyEval_CallObject(coercefunc, args);
+	Py_DECREF(args);
+	Py_DECREF(coercefunc);
+	if (coerced == NULL) {
+		return NULL;
+	}
+	if (coerced == Py_None || coerced == Py_NotImplemented) {
+		Py_DECREF(coerced);
+		return generic_binary_op(v, w, opname);
+	}
+	if (!PyTuple_Check(coerced) || PyTuple_Size(coerced) != 2) {
+		Py_DECREF(coerced);
+		PyErr_SetString(PyExc_TypeError,
+				"coercion should return None or 2-tuple");
+		return NULL;
+	}
+	v1 = PyTuple_GetItem(coerced, 0);
+	w = PyTuple_GetItem(coerced, 1);
+	if (v1->ob_type == v->ob_type && PyInstance_Check(v)) {
+		/* prevent recursion if __coerce__ returns self as the first
+		 * argument */
+		result = generic_binary_op(v1, w, opname);
+	} else {
+		if (Py_EnterRecursiveCall(" after coercion"))
+		    return NULL;
+		if (swapped)
+			result = (thisfunc)(w, v1);
+		else
+			result = (thisfunc)(v1, w);
+		Py_LeaveRecursiveCall();
+	}
+	Py_DECREF(coerced);
+	return result;
+}
+
+/* Implement a binary operator involving at least one class instance. */
+static PyObject *
+do_binop(PyObject *v, PyObject *w, char *opname, char *ropname,
+                   binaryfunc thisfunc)
+{
+	PyObject *result = half_binop(v, w, opname, thisfunc, 0);
+	if (result == Py_NotImplemented) {
+		Py_DECREF(result);
+		result = half_binop(w, v, ropname, thisfunc, 1);
+	}
+	return result;
+}
+
+static PyObject *
+do_binop_inplace(PyObject *v, PyObject *w, char *iopname, char *opname,
+			char *ropname, binaryfunc thisfunc)
+{
+	PyObject *result = half_binop(v, w, iopname, thisfunc, 0);
+	if (result == Py_NotImplemented) {
+		Py_DECREF(result);
+		result = do_binop(v, w, opname, ropname, thisfunc);
+	}
+	return result;
+}
+
+static int
+instance_coerce(PyObject **pv, PyObject **pw)
+{
+	PyObject *v = *pv;
+	PyObject *w = *pw;
+	PyObject *coercefunc;
+	PyObject *args;
+	PyObject *coerced;
+
+	if (coerce_obj == NULL) {
+		coerce_obj = PyString_InternFromString("__coerce__");
+		if (coerce_obj == NULL)
+			return -1;
+	}
+	coercefunc = PyObject_GetAttr(v, coerce_obj);
+	if (coercefunc == NULL) {
+		/* No __coerce__ method */
+		if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+			return -1;
+		PyErr_Clear();
+		return 1;
+	}
+	/* Has __coerce__ method: call it */
+	args = PyTuple_Pack(1, w);
+	if (args == NULL) {
+		return -1;
+	}
+	coerced = PyEval_CallObject(coercefunc, args);
+	Py_DECREF(args);
+	Py_DECREF(coercefunc);
+	if (coerced == NULL) {
+		/* __coerce__ call raised an exception */
+		return -1;
+	}
+	if (coerced == Py_None || coerced == Py_NotImplemented) {
+		/* __coerce__ says "I can't do it" */
+		Py_DECREF(coerced);
+		return 1;
+	}
+	if (!PyTuple_Check(coerced) || PyTuple_Size(coerced) != 2) {
+		/* __coerce__ return value is malformed */
+		Py_DECREF(coerced);
+		PyErr_SetString(PyExc_TypeError,
+			   "coercion should return None or 2-tuple");
+		return -1;
+	}
+	/* __coerce__ returned two new values */
+	*pv = PyTuple_GetItem(coerced, 0);
+	*pw = PyTuple_GetItem(coerced, 1);
+	Py_INCREF(*pv);
+	Py_INCREF(*pw);
+	Py_DECREF(coerced);
+	return 0;
+}
+
+#define UNARY(funcname, methodname) \
+static PyObject *funcname(PyInstanceObject *self) { \
+	static PyObject *o; \
+	if (o == NULL) { o = PyString_InternFromString(methodname); \
+			 if (o == NULL) return NULL; } \
+	return generic_unary_op(self, o); \
+}
+
+#define BINARY(f, m, n) \
+static PyObject *f(PyObject *v, PyObject *w) { \
+	return do_binop(v, w, "__" m "__", "__r" m "__", n); \
+}
+
+#define BINARY_INPLACE(f, m, n) \
+static PyObject *f(PyObject *v, PyObject *w) { \
+	return do_binop_inplace(v, w, "__i" m "__", "__" m "__", \
+			"__r" m "__", n); \
+}
+
+UNARY(instance_neg, "__neg__")
+UNARY(instance_pos, "__pos__")
+UNARY(instance_abs, "__abs__")
+
+BINARY(instance_or, "or", PyNumber_Or)
+BINARY(instance_and, "and", PyNumber_And)
+BINARY(instance_xor, "xor", PyNumber_Xor)
+BINARY(instance_lshift, "lshift", PyNumber_Lshift)
+BINARY(instance_rshift, "rshift", PyNumber_Rshift)
+BINARY(instance_add, "add", PyNumber_Add)
+BINARY(instance_sub, "sub", PyNumber_Subtract)
+BINARY(instance_mul, "mul", PyNumber_Multiply)
+BINARY(instance_div, "div", PyNumber_Divide)
+BINARY(instance_mod, "mod", PyNumber_Remainder)
+BINARY(instance_divmod, "divmod", PyNumber_Divmod)
+BINARY(instance_floordiv, "floordiv", PyNumber_FloorDivide)
+BINARY(instance_truediv, "truediv", PyNumber_TrueDivide)
+
+BINARY_INPLACE(instance_ior, "or", PyNumber_InPlaceOr)
+BINARY_INPLACE(instance_ixor, "xor", PyNumber_InPlaceXor)
+BINARY_INPLACE(instance_iand, "and", PyNumber_InPlaceAnd)
+BINARY_INPLACE(instance_ilshift, "lshift", PyNumber_InPlaceLshift)
+BINARY_INPLACE(instance_irshift, "rshift", PyNumber_InPlaceRshift)
+BINARY_INPLACE(instance_iadd, "add", PyNumber_InPlaceAdd)
+BINARY_INPLACE(instance_isub, "sub", PyNumber_InPlaceSubtract)
+BINARY_INPLACE(instance_imul, "mul", PyNumber_InPlaceMultiply)
+BINARY_INPLACE(instance_idiv, "div", PyNumber_InPlaceDivide)
+BINARY_INPLACE(instance_imod, "mod", PyNumber_InPlaceRemainder)
+BINARY_INPLACE(instance_ifloordiv, "floordiv", PyNumber_InPlaceFloorDivide)
+BINARY_INPLACE(instance_itruediv, "truediv", PyNumber_InPlaceTrueDivide)
+
+/* Try a 3-way comparison, returning an int; v is an instance.  Return:
+   -2 for an exception;
+   -1 if v < w;
+   0 if v == w;
+   1 if v > w;
+   2 if this particular 3-way comparison is not implemented or undefined.
+*/
+static int
+half_cmp(PyObject *v, PyObject *w)
+{
+	static PyObject *cmp_obj;
+	PyObject *args;
+	PyObject *cmp_func;
+	PyObject *result;
+	long l;
+
+	assert(PyInstance_Check(v));
+
+	if (cmp_obj == NULL) {
+		cmp_obj = PyString_InternFromString("__cmp__");
+		if (cmp_obj == NULL)
+			return -2;
+	}
+
+	cmp_func = PyObject_GetAttr(v, cmp_obj);
+	if (cmp_func == NULL) {
+		if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+			return -2;
+		PyErr_Clear();
+		return 2;
+	}
+
+	args = PyTuple_Pack(1, w);
+	if (args == NULL) {
+		Py_DECREF(cmp_func);
+		return -2;
+	}
+
+	result = PyEval_CallObject(cmp_func, args);
+	Py_DECREF(args);
+	Py_DECREF(cmp_func);
+
+	if (result == NULL)
+		return -2;
+
+	if (result == Py_NotImplemented) {
+		Py_DECREF(result);
+		return 2;
+	}
+
+	l = PyInt_AsLong(result);
+	Py_DECREF(result);
+	if (l == -1 && PyErr_Occurred()) {
+		PyErr_SetString(PyExc_TypeError,
+			     "comparison did not return an int");
+		return -2;
+	}
+
+	return l < 0 ? -1 : l > 0 ? 1 : 0;
+}
+
+/* Try a 3-way comparison, returning an int; either v or w is an instance.
+   We first try a coercion.  Return:
+   -2 for an exception;
+   -1 if v < w;
+   0 if v == w;
+   1 if v > w;
+   2 if this particular 3-way comparison is not implemented or undefined.
+   THIS IS ONLY CALLED FROM object.c!
+*/
+static int
+instance_compare(PyObject *v, PyObject *w)
+{
+	int c;
+
+	c = PyNumber_CoerceEx(&v, &w);
+	if (c < 0)
+		return -2;
+	if (c == 0) {
+		/* If neither is now an instance, use regular comparison */
+		if (!PyInstance_Check(v) && !PyInstance_Check(w)) {
+			c = PyObject_Compare(v, w);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			if (PyErr_Occurred())
+				return -2;
+			return c < 0 ? -1 : c > 0 ? 1 : 0;
+		}
+	}
+	else {
+		/* The coercion didn't do anything.
+		   Treat this the same as returning v and w unchanged. */
+		Py_INCREF(v);
+		Py_INCREF(w);
+	}
+
+	if (PyInstance_Check(v)) {
+		c = half_cmp(v, w);
+		if (c <= 1) {
+			Py_DECREF(v);
+			Py_DECREF(w);
+			return c;
+		}
+	}
+	if (PyInstance_Check(w)) {
+		c = half_cmp(w, v);
+		if (c <= 1) {
+			Py_DECREF(v);
+			Py_DECREF(w);
+			if (c >= -1)
+				c = -c;
+			return c;
+		}
+	}
+	Py_DECREF(v);
+	Py_DECREF(w);
+	return 2;
+}
+
+static int
+instance_nonzero(PyInstanceObject *self)
+{
+	PyObject *func, *res;
+	long outcome;
+	static PyObject *nonzerostr;
+
+	if (nonzerostr == NULL) {
+		nonzerostr = PyString_InternFromString("__nonzero__");
+		if (nonzerostr == NULL)
+			return -1;
+	}
+	if ((func = instance_getattr(self, nonzerostr)) == NULL) {
+		if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+			return -1;
+		PyErr_Clear();
+		if (lenstr == NULL) {
+			lenstr = PyString_InternFromString("__len__");
+			if (lenstr == NULL)
+				return -1;
+		}
+		if ((func = instance_getattr(self, lenstr)) == NULL) {
+			if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+				return -1;
+			PyErr_Clear();
+			/* Fall back to the default behavior:
+			   all instances are nonzero */
+			return 1;
+		}
+	}
+	res = PyEval_CallObject(func, (PyObject *)NULL);
+	Py_DECREF(func);
+	if (res == NULL)
+		return -1;
+	if (!PyInt_Check(res)) {
+		Py_DECREF(res);
+		PyErr_SetString(PyExc_TypeError,
+				"__nonzero__ should return an int");
+		return -1;
+	}
+	outcome = PyInt_AsLong(res);
+	Py_DECREF(res);
+	if (outcome < 0) {
+		PyErr_SetString(PyExc_ValueError,
+				"__nonzero__ should return >= 0");
+		return -1;
+	}
+	return outcome > 0;
+}
+
+static PyObject *
+instance_index(PyInstanceObject *self)
+{
+	PyObject *func, *res;
+	static PyObject *indexstr = NULL;
+
+	if (indexstr == NULL) {
+		indexstr = PyString_InternFromString("__index__");
+		if (indexstr == NULL)
+			return NULL;
+	}	
+	if ((func = instance_getattr(self, indexstr)) == NULL) {
+		if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+			return NULL;
+		PyErr_Clear();
+		PyErr_SetString(PyExc_TypeError, 
+				"object cannot be interpreted as an index");
+		return NULL;
+	}
+	res = PyEval_CallObject(func, (PyObject *)NULL);
+	Py_DECREF(func);
+	return res;
+}
+
+
+UNARY(instance_invert, "__invert__")
+UNARY(instance_int, "__int__")
+UNARY(instance_long, "__long__")
+UNARY(instance_float, "__float__")
+UNARY(instance_oct, "__oct__")
+UNARY(instance_hex, "__hex__")
+
+static PyObject *
+bin_power(PyObject *v, PyObject *w)
+{
+	return PyNumber_Power(v, w, Py_None);
+}
+
+/* This version is for ternary calls only (z != None) */
+static PyObject *
+instance_pow(PyObject *v, PyObject *w, PyObject *z)
+{
+	if (z == Py_None) {
+		return do_binop(v, w, "__pow__", "__rpow__", bin_power);
+	}
+	else {
+		PyObject *func;
+		PyObject *args;
+		PyObject *result;
+
+		/* XXX Doesn't do coercions... */
+		func = PyObject_GetAttrString(v, "__pow__");
+		if (func == NULL)
+			return NULL;
+		args = PyTuple_Pack(2, w, z);
+		if (args == NULL) {
+			Py_DECREF(func);
+			return NULL;
+		}
+		result = PyEval_CallObject(func, args);
+		Py_DECREF(func);
+		Py_DECREF(args);
+		return result;
+	}
+}
+
+static PyObject *
+bin_inplace_power(PyObject *v, PyObject *w)
+{
+	return PyNumber_InPlacePower(v, w, Py_None);
+}
+
+
+static PyObject *
+instance_ipow(PyObject *v, PyObject *w, PyObject *z)
+{
+	if (z == Py_None) {
+		return do_binop_inplace(v, w, "__ipow__", "__pow__",
+			"__rpow__", bin_inplace_power);
+	}
+	else {
+		/* XXX Doesn't do coercions... */
+		PyObject *func;
+		PyObject *args;
+		PyObject *result;
+
+		func = PyObject_GetAttrString(v, "__ipow__");
+		if (func == NULL) {
+			if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+				return NULL;
+			PyErr_Clear();
+			return instance_pow(v, w, z);
+		}
+		args = PyTuple_Pack(2, w, z);
+		if (args == NULL) {
+			Py_DECREF(func);
+			return NULL;
+		}
+		result = PyEval_CallObject(func, args);
+		Py_DECREF(func);
+		Py_DECREF(args);
+		return result;
+	}
+}
+
+
+/* Map rich comparison operators to their __xx__ namesakes */
+#define NAME_OPS 6
+static PyObject **name_op = NULL;
+
+static int
+init_name_op(void)
+{
+	int i;
+	char *_name_op[] = {
+		"__lt__",
+		"__le__",
+		"__eq__",
+		"__ne__",
+		"__gt__",
+		"__ge__",
+	};
+
+	name_op = (PyObject **)malloc(sizeof(PyObject *) * NAME_OPS);
+	if (name_op == NULL)
+		return -1;
+	for (i = 0; i < NAME_OPS; ++i) {
+		name_op[i] = PyString_InternFromString(_name_op[i]);
+		if (name_op[i] == NULL)
+			return -1;
+	}
+	return 0;
+}
+
+static PyObject *
+half_richcompare(PyObject *v, PyObject *w, int op)
+{
+	PyObject *method;
+	PyObject *args;
+	PyObject *res;
+
+	assert(PyInstance_Check(v));
+
+	if (name_op == NULL) {
+		if (init_name_op() < 0)
+			return NULL;
+	}
+	/* If the instance doesn't define an __getattr__ method, use
+	   instance_getattr2 directly because it will not set an
+	   exception on failure. */
+	if (((PyInstanceObject *)v)->in_class->cl_getattr == NULL)
+		method = instance_getattr2((PyInstanceObject *)v,
+					   name_op[op]);
+	else
+		method = PyObject_GetAttr(v, name_op[op]);
+	if (method == NULL) {
+		if (PyErr_Occurred()) {
+			if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+				return NULL;
+			PyErr_Clear();
+		}
+		res = Py_NotImplemented;
+		Py_INCREF(res);
+		return res;
+	}
+
+	args = PyTuple_Pack(1, w);
+	if (args == NULL) {
+		Py_DECREF(method);
+		return NULL;
+	}
+
+	res = PyEval_CallObject(method, args);
+	Py_DECREF(args);
+	Py_DECREF(method);
+
+	return res;
+}
+
+static PyObject *
+instance_richcompare(PyObject *v, PyObject *w, int op)
+{
+	PyObject *res;
+
+	if (PyInstance_Check(v)) {
+		res = half_richcompare(v, w, op);
+		if (res != Py_NotImplemented)
+			return res;
+		Py_DECREF(res);
+	}
+
+	if (PyInstance_Check(w)) {
+		res = half_richcompare(w, v, _Py_SwappedOp[op]);
+		if (res != Py_NotImplemented)
+			return res;
+		Py_DECREF(res);
+	}
+
+	Py_INCREF(Py_NotImplemented);
+	return Py_NotImplemented;
+}
+
+
+/* Get the iterator */
+static PyObject *
+instance_getiter(PyInstanceObject *self)
+{
+	PyObject *func;
+
+	if (iterstr == NULL) {
+		iterstr = PyString_InternFromString("__iter__");
+		if (iterstr == NULL)
+			return NULL;
+	}
+	if (getitemstr == NULL) {
+		getitemstr = PyString_InternFromString("__getitem__");
+		if (getitemstr == NULL)
+			return NULL;
+	}
+
+	if ((func = instance_getattr(self, iterstr)) != NULL) {
+		PyObject *res = PyEval_CallObject(func, (PyObject *)NULL);
+		Py_DECREF(func);
+		if (res != NULL && !PyIter_Check(res)) {
+			PyErr_Format(PyExc_TypeError,
+				     "__iter__ returned non-iterator "
+				     "of type '%.100s'",
+				     res->ob_type->tp_name);
+			Py_DECREF(res);
+			res = NULL;
+		}
+		return res;
+	}
+	if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+		return NULL;
+	PyErr_Clear();
+	if ((func = instance_getattr(self, getitemstr)) == NULL) {
+		PyErr_SetString(PyExc_TypeError,
+				"iteration over non-sequence");
+		return NULL;
+	}
+	Py_DECREF(func);
+	return PySeqIter_New((PyObject *)self);
+}
+
+
+/* Call the iterator's next */
+static PyObject *
+instance_iternext(PyInstanceObject *self)
+{
+	PyObject *func;
+
+	if (nextstr == NULL) {
+		nextstr = PyString_InternFromString("next");
+		if (nextstr == NULL)
+			return NULL;
+	}
+
+	if ((func = instance_getattr(self, nextstr)) != NULL) {
+		PyObject *res = PyEval_CallObject(func, (PyObject *)NULL);
+		Py_DECREF(func);
+		if (res != NULL) {
+			return res;
+		}
+		if (PyErr_ExceptionMatches(PyExc_StopIteration)) {
+			PyErr_Clear();
+			return NULL;
+		}
+		return NULL;
+	}
+	PyErr_SetString(PyExc_TypeError, "instance has no next() method");
+	return NULL;
+}
+
+static PyObject *
+instance_call(PyObject *func, PyObject *arg, PyObject *kw)
+{
+	PyObject *res, *call = PyObject_GetAttrString(func, "__call__");
+	if (call == NULL) {
+		PyInstanceObject *inst = (PyInstanceObject*) func;
+		if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+			return NULL;
+		PyErr_Clear();
+		PyErr_Format(PyExc_AttributeError,
+			     "%.200s instance has no __call__ method",
+			     PyString_AsString(inst->in_class->cl_name));
+		return NULL;
+	}
+	/* We must check and increment the recursion depth here. Scenario:
+	       class A:
+	           pass
+	       A.__call__ = A() # that's right
+	       a = A() # ok
+	       a() # infinite recursion
+	   This bounces between instance_call() and PyObject_Call() without
+	   ever hitting eval_frame() (which has the main recursion check). */
+	if (Py_EnterRecursiveCall(" in __call__")) {
+		res = NULL;
+	}
+	else {
+		res = PyObject_Call(call, arg, kw);
+		Py_LeaveRecursiveCall();
+	}
+	Py_DECREF(call);
+	return res;
+}
+
+
+static PyNumberMethods instance_as_number = {
+	instance_add,			/* nb_add */
+	instance_sub,			/* nb_subtract */
+	instance_mul,			/* nb_multiply */
+	instance_div,			/* nb_divide */
+	instance_mod,			/* nb_remainder */
+	instance_divmod,		/* nb_divmod */
+	instance_pow,			/* nb_power */
+	(unaryfunc)instance_neg,	/* nb_negative */
+	(unaryfunc)instance_pos,	/* nb_positive */
+	(unaryfunc)instance_abs,	/* nb_absolute */
+	(inquiry)instance_nonzero,	/* nb_nonzero */
+	(unaryfunc)instance_invert,	/* nb_invert */
+	instance_lshift,		/* nb_lshift */
+	instance_rshift,		/* nb_rshift */
+	instance_and,			/* nb_and */
+	instance_xor,			/* nb_xor */
+	instance_or,			/* nb_or */
+	instance_coerce,		/* nb_coerce */
+	(unaryfunc)instance_int,	/* nb_int */
+	(unaryfunc)instance_long,	/* nb_long */
+	(unaryfunc)instance_float,	/* nb_float */
+	(unaryfunc)instance_oct,	/* nb_oct */
+	(unaryfunc)instance_hex,	/* nb_hex */
+	instance_iadd,			/* nb_inplace_add */
+	instance_isub,			/* nb_inplace_subtract */
+	instance_imul,			/* nb_inplace_multiply */
+	instance_idiv,			/* nb_inplace_divide */
+	instance_imod,			/* nb_inplace_remainder */
+	instance_ipow,			/* nb_inplace_power */
+	instance_ilshift,		/* nb_inplace_lshift */
+	instance_irshift,		/* nb_inplace_rshift */
+	instance_iand,			/* nb_inplace_and */
+	instance_ixor,			/* nb_inplace_xor */
+	instance_ior,			/* nb_inplace_or */
+	instance_floordiv,		/* nb_floor_divide */
+	instance_truediv,		/* nb_true_divide */
+	instance_ifloordiv,		/* nb_inplace_floor_divide */
+	instance_itruediv,		/* nb_inplace_true_divide */
+	(unaryfunc)instance_index,	/* nb_index */
+};
+
+PyTypeObject PyInstance_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,
+	"instance",
+	sizeof(PyInstanceObject),
+	0,
+	(destructor)instance_dealloc,		/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	instance_compare,			/* tp_compare */
+	(reprfunc)instance_repr,		/* tp_repr */
+	&instance_as_number,			/* tp_as_number */
+	&instance_as_sequence,			/* tp_as_sequence */
+	&instance_as_mapping,			/* tp_as_mapping */
+	(hashfunc)instance_hash,		/* tp_hash */
+	instance_call,				/* tp_call */
+	(reprfunc)instance_str,			/* tp_str */
+	(getattrofunc)instance_getattr,		/* tp_getattro */
+	(setattrofunc)instance_setattr,		/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES,/*tp_flags*/
+	instance_doc,				/* tp_doc */
+	(traverseproc)instance_traverse,	/* tp_traverse */
+	0,					/* tp_clear */
+	instance_richcompare,			/* tp_richcompare */
+ 	offsetof(PyInstanceObject, in_weakreflist), /* tp_weaklistoffset */
+	(getiterfunc)instance_getiter,		/* tp_iter */
+	(iternextfunc)instance_iternext,	/* tp_iternext */
+	0,					/* tp_methods */
+	0,					/* tp_members */
+	0,					/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	0,					/* tp_init */
+	0,					/* tp_alloc */
+	instance_new,				/* tp_new */
+};
+
+
+/* Instance method objects are used for two purposes:
+   (a) as bound instance methods (returned by instancename.methodname)
+   (b) as unbound methods (returned by ClassName.methodname)
+   In case (b), im_self is NULL
+*/
+
+static PyMethodObject *free_list;
+
+PyObject *
+PyMethod_New(PyObject *func, PyObject *self, PyObject *klass)
+{
+	register PyMethodObject *im;
+	if (!PyCallable_Check(func)) {
+		PyErr_BadInternalCall();
+		return NULL;
+	}
+	im = free_list;
+	if (im != NULL) {
+		free_list = (PyMethodObject *)(im->im_self);
+		PyObject_INIT(im, &PyMethod_Type);
+	}
+	else {
+		im = PyObject_GC_New(PyMethodObject, &PyMethod_Type);
+		if (im == NULL)
+			return NULL;
+	}
+	im->im_weakreflist = NULL;
+	Py_INCREF(func);
+	im->im_func = func;
+	Py_XINCREF(self);
+	im->im_self = self;
+	Py_XINCREF(klass);
+	im->im_class = klass;
+	_PyObject_GC_TRACK(im);
+	return (PyObject *)im;
+}
+
+/* Descriptors for PyMethod attributes */
+
+/* im_class, im_func and im_self are stored in the PyMethod object */
+
+#define OFF(x) offsetof(PyMethodObject, x)
+
+static PyMemberDef instancemethod_memberlist[] = {
+	{"im_class",	T_OBJECT,	OFF(im_class),	READONLY|RESTRICTED,
+	 "the class associated with a method"},
+	{"im_func",	T_OBJECT,	OFF(im_func),	READONLY|RESTRICTED,
+	 "the function (or other callable) implementing a method"},
+	{"im_self",	T_OBJECT,	OFF(im_self),	READONLY|RESTRICTED,
+	 "the instance to which a method is bound; None for unbound methods"},
+	{NULL}	/* Sentinel */
+};
+
+/* Christian Tismer argued convincingly that method attributes should
+   (nearly) always override function attributes.
+   The one exception is __doc__; there's a default __doc__ which
+   should only be used for the class, not for instances */
+
+static PyObject *
+instancemethod_get_doc(PyMethodObject *im, void *context)
+{
+	static PyObject *docstr;
+	if (docstr == NULL) {
+		docstr= PyString_InternFromString("__doc__");
+		if (docstr == NULL)
+			return NULL;
+	}
+	return PyObject_GetAttr(im->im_func, docstr);
+}
+
+static PyGetSetDef instancemethod_getset[] = {
+	{"__doc__", (getter)instancemethod_get_doc, NULL, NULL},
+	{0}
+};
+
+static PyObject *
+instancemethod_getattro(PyObject *obj, PyObject *name)
+{
+	PyMethodObject *im = (PyMethodObject *)obj;
+	PyTypeObject *tp = obj->ob_type;
+	PyObject *descr = NULL;
+
+	if (PyType_HasFeature(tp, Py_TPFLAGS_HAVE_CLASS)) {
+		if (tp->tp_dict == NULL) {
+			if (PyType_Ready(tp) < 0)
+				return NULL;
+		}
+		descr = _PyType_Lookup(tp, name);
+	}
+
+	if (descr != NULL) {
+		descrgetfunc f = TP_DESCR_GET(descr->ob_type);
+		if (f != NULL)
+			return f(descr, obj, (PyObject *)obj->ob_type);
+		else {
+			Py_INCREF(descr);
+			return descr;
+		}
+	}
+
+	return PyObject_GetAttr(im->im_func, name);
+}
+
+PyDoc_STRVAR(instancemethod_doc,
+"instancemethod(function, instance, class)\n\
+\n\
+Create an instance method object.");
+
+static PyObject *
+instancemethod_new(PyTypeObject* type, PyObject* args, PyObject *kw)
+{
+	PyObject *func;
+	PyObject *self;
+	PyObject *classObj = NULL;
+
+	if (!_PyArg_NoKeywords("instancemethod", kw))
+		return NULL;
+	if (!PyArg_UnpackTuple(args, "instancemethod", 2, 3,
+			      &func, &self, &classObj))
+		return NULL;
+	if (!PyCallable_Check(func)) {
+		PyErr_SetString(PyExc_TypeError,
+				"first argument must be callable");
+		return NULL;
+	}
+	if (self == Py_None)
+		self = NULL;
+	if (self == NULL && classObj == NULL) {
+		PyErr_SetString(PyExc_TypeError,
+			"unbound methods must have non-NULL im_class");
+		return NULL;
+	}
+
+	return PyMethod_New(func, self, classObj);
+}
+
+static void
+instancemethod_dealloc(register PyMethodObject *im)
+{
+	_PyObject_GC_UNTRACK(im);
+	if (im->im_weakreflist != NULL)
+		PyObject_ClearWeakRefs((PyObject *)im);
+	Py_DECREF(im->im_func);
+	Py_XDECREF(im->im_self);
+	Py_XDECREF(im->im_class);
+	im->im_self = (PyObject *)free_list;
+	free_list = im;
+}
+
+static int
+instancemethod_compare(PyMethodObject *a, PyMethodObject *b)
+{
+	int cmp;
+	cmp = PyObject_Compare(a->im_func, b->im_func);
+	if (cmp)
+		return cmp;
+
+	if (a->im_self == b->im_self)
+		return 0;
+	if (a->im_self == NULL || b->im_self == NULL)
+		return (a->im_self < b->im_self) ? -1 : 1;
+	else
+		return PyObject_Compare(a->im_self, b->im_self);
+}
+
+static PyObject *
+instancemethod_repr(PyMethodObject *a)
+{
+	PyObject *self = a->im_self;
+	PyObject *func = a->im_func;
+	PyObject *klass = a->im_class;
+	PyObject *funcname = NULL, *klassname = NULL, *result = NULL;
+	char *sfuncname = "?", *sklassname = "?";
+
+	funcname = PyObject_GetAttrString(func, "__name__");
+	if (funcname == NULL) {
+		if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+			return NULL;
+		PyErr_Clear();
+	}
+	else if (!PyString_Check(funcname)) {
+		Py_DECREF(funcname);
+		funcname = NULL;
+	}
+	else
+		sfuncname = PyString_AS_STRING(funcname);
+	if (klass == NULL)
+		klassname = NULL;
+	else {
+		klassname = PyObject_GetAttrString(klass, "__name__");
+		if (klassname == NULL) {
+			if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+				return NULL;
+			PyErr_Clear();
+		}
+		else if (!PyString_Check(klassname)) {
+			Py_DECREF(klassname);
+			klassname = NULL;
+		}
+		else
+			sklassname = PyString_AS_STRING(klassname);
+	}
+	if (self == NULL)
+		result = PyString_FromFormat("<unbound method %s.%s>",
+					     sklassname, sfuncname);
+	else {
+		/* XXX Shouldn't use repr() here! */
+		PyObject *selfrepr = PyObject_Repr(self);
+		if (selfrepr == NULL)
+			goto fail;
+		if (!PyString_Check(selfrepr)) {
+			Py_DECREF(selfrepr);
+			goto fail;
+		}
+		result = PyString_FromFormat("<bound method %s.%s of %s>",
+					     sklassname, sfuncname,
+					     PyString_AS_STRING(selfrepr));
+		Py_DECREF(selfrepr);
+	}
+  fail:
+	Py_XDECREF(funcname);
+	Py_XDECREF(klassname);
+	return result;
+}
+
+static long
+instancemethod_hash(PyMethodObject *a)
+{
+	long x, y;
+	if (a->im_self == NULL)
+		x = PyObject_Hash(Py_None);
+	else
+		x = PyObject_Hash(a->im_self);
+	if (x == -1)
+		return -1;
+	y = PyObject_Hash(a->im_func);
+	if (y == -1)
+		return -1;
+	x = x ^ y;
+	if (x == -1)
+		x = -2;
+	return x;
+}
+
+static int
+instancemethod_traverse(PyMethodObject *im, visitproc visit, void *arg)
+{
+	Py_VISIT(im->im_func);
+	Py_VISIT(im->im_self);
+	Py_VISIT(im->im_class);
+	return 0;
+}
+
+static void
+getclassname(PyObject *klass, char *buf, int bufsize)
+{
+	PyObject *name;
+
+	assert(bufsize > 1);
+	strcpy(buf, "?"); /* Default outcome */
+	if (klass == NULL)
+		return;
+	name = PyObject_GetAttrString(klass, "__name__");
+	if (name == NULL) {
+		/* This function cannot return an exception */
+		PyErr_Clear();
+		return;
+	}
+	if (PyString_Check(name)) {
+		strncpy(buf, PyString_AS_STRING(name), bufsize);
+		buf[bufsize-1] = '\0';
+	}
+	Py_DECREF(name);
+}
+
+static void
+getinstclassname(PyObject *inst, char *buf, int bufsize)
+{
+	PyObject *klass;
+
+	if (inst == NULL) {
+		assert(bufsize > 0 && (size_t)bufsize > strlen("nothing"));
+		strcpy(buf, "nothing");
+		return;
+	}
+
+	klass = PyObject_GetAttrString(inst, "__class__");
+	if (klass == NULL) {
+		/* This function cannot return an exception */
+		PyErr_Clear();
+		klass = (PyObject *)(inst->ob_type);
+		Py_INCREF(klass);
+	}
+	getclassname(klass, buf, bufsize);
+	Py_XDECREF(klass);
+}
+
+static PyObject *
+instancemethod_call(PyObject *func, PyObject *arg, PyObject *kw)
+{
+	PyObject *self = PyMethod_GET_SELF(func);
+	PyObject *klass = PyMethod_GET_CLASS(func);
+	PyObject *result;
+
+	func = PyMethod_GET_FUNCTION(func);
+	if (self == NULL) {
+		/* Unbound methods must be called with an instance of
+		   the class (or a derived class) as first argument */
+		int ok;
+		if (PyTuple_Size(arg) >= 1)
+			self = PyTuple_GET_ITEM(arg, 0);
+		if (self == NULL)
+			ok = 0;
+		else {
+			ok = PyObject_IsInstance(self, klass);
+			if (ok < 0)
+				return NULL;
+		}
+		if (!ok) {
+			char clsbuf[256];
+			char instbuf[256];
+			getclassname(klass, clsbuf, sizeof(clsbuf));
+			getinstclassname(self, instbuf, sizeof(instbuf));
+			PyErr_Format(PyExc_TypeError,
+				     "unbound method %s%s must be called with "
+				     "%s instance as first argument "
+				     "(got %s%s instead)",
+				     PyEval_GetFuncName(func),
+				     PyEval_GetFuncDesc(func),
+				     clsbuf,
+				     instbuf,
+				     self == NULL ? "" : " instance");
+			return NULL;
+		}
+		Py_INCREF(arg);
+	}
+	else {
+		Py_ssize_t argcount = PyTuple_Size(arg);
+		PyObject *newarg = PyTuple_New(argcount + 1);
+		int i;
+		if (newarg == NULL)
+			return NULL;
+		Py_INCREF(self);
+		PyTuple_SET_ITEM(newarg, 0, self);
+		for (i = 0; i < argcount; i++) {
+			PyObject *v = PyTuple_GET_ITEM(arg, i);
+			Py_XINCREF(v);
+			PyTuple_SET_ITEM(newarg, i+1, v);
+		}
+		arg = newarg;
+	}
+	result = PyObject_Call((PyObject *)func, arg, kw);
+	Py_DECREF(arg);
+	return result;
+}
+
+static PyObject *
+instancemethod_descr_get(PyObject *meth, PyObject *obj, PyObject *cls)
+{
+	/* Don't rebind an already bound method, or an unbound method
+	   of a class that's not a base class of cls. */
+
+	if (PyMethod_GET_SELF(meth) != NULL) {
+		/* Already bound */
+		Py_INCREF(meth);
+		return meth;
+	}
+	/* No, it is an unbound method */
+	if (PyMethod_GET_CLASS(meth) != NULL && cls != NULL) {
+		/* Do subclass test.  If it fails, return meth unchanged. */
+		int ok = PyObject_IsSubclass(cls, PyMethod_GET_CLASS(meth));
+		if (ok < 0)
+			return NULL;
+		if (!ok) {
+			Py_INCREF(meth);
+			return meth;
+		}
+	}
+	/* Bind it to obj */
+	return PyMethod_New(PyMethod_GET_FUNCTION(meth), obj, cls);
+}
+
+PyTypeObject PyMethod_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,
+	"instancemethod",
+	sizeof(PyMethodObject),
+	0,
+	(destructor)instancemethod_dealloc,	/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	(cmpfunc)instancemethod_compare,	/* tp_compare */
+	(reprfunc)instancemethod_repr,		/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	(hashfunc)instancemethod_hash,		/* tp_hash */
+	instancemethod_call,			/* tp_call */
+	0,					/* tp_str */
+	instancemethod_getattro,		/* tp_getattro */
+	PyObject_GenericSetAttr,		/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC  | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
+	instancemethod_doc,			/* tp_doc */
+	(traverseproc)instancemethod_traverse,	/* tp_traverse */
+	0,					/* tp_clear */
+	0,					/* tp_richcompare */
+ 	offsetof(PyMethodObject, im_weakreflist), /* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	0,					/* tp_methods */
+	instancemethod_memberlist,		/* tp_members */
+	instancemethod_getset,			/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	instancemethod_descr_get,		/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	0,					/* tp_init */
+	0,					/* tp_alloc */
+	instancemethod_new,			/* tp_new */
+};
+
+/* Clear out the free list */
+
+void
+PyMethod_Fini(void)
+{
+	while (free_list) {
+		PyMethodObject *im = free_list;
+		free_list = (PyMethodObject *)(im->im_self);
+		PyObject_GC_Del(im);
+	}
+}

Added: vendor/Python/current/Objects/cobject.c
===================================================================
--- vendor/Python/current/Objects/cobject.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Objects/cobject.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,161 @@
+
+/* Wrap void* pointers to be passed between C modules */
+
+#include "Python.h"
+
+
+/* Declarations for objects of type PyCObject */
+
+typedef void (*destructor1)(void *);
+typedef void (*destructor2)(void *, void*);
+
+typedef struct {
+    PyObject_HEAD
+    void *cobject;
+    void *desc;
+    void (*destructor)(void *);
+} PyCObject;
+
+PyObject *
+PyCObject_FromVoidPtr(void *cobj, void (*destr)(void *))
+{
+    PyCObject *self;
+
+    self = PyObject_NEW(PyCObject, &PyCObject_Type);
+    if (self == NULL)
+        return NULL;
+    self->cobject=cobj;
+    self->destructor=destr;
+    self->desc=NULL;
+
+    return (PyObject *)self;
+}
+
+PyObject *
+PyCObject_FromVoidPtrAndDesc(void *cobj, void *desc,
+                             void (*destr)(void *, void *))
+{
+    PyCObject *self;
+
+    if (!desc) {
+        PyErr_SetString(PyExc_TypeError,
+                        "PyCObject_FromVoidPtrAndDesc called with null"
+                        " description");
+        return NULL;
+    }
+    self = PyObject_NEW(PyCObject, &PyCObject_Type);
+    if (self == NULL)
+        return NULL;
+    self->cobject = cobj;
+    self->destructor = (destructor1)destr;
+    self->desc = desc;
+
+    return (PyObject *)self;
+}
+
+void *
+PyCObject_AsVoidPtr(PyObject *self)
+{
+    if (self) {
+        if (self->ob_type == &PyCObject_Type)
+            return ((PyCObject *)self)->cobject;
+        PyErr_SetString(PyExc_TypeError,
+                        "PyCObject_AsVoidPtr with non-C-object");
+    }
+    if (!PyErr_Occurred())
+        PyErr_SetString(PyExc_TypeError,
+                        "PyCObject_AsVoidPtr called with null pointer");
+    return NULL;
+}
+
+void *
+PyCObject_GetDesc(PyObject *self)
+{
+    if (self) {
+        if (self->ob_type == &PyCObject_Type)
+            return ((PyCObject *)self)->desc;
+        PyErr_SetString(PyExc_TypeError,
+                        "PyCObject_GetDesc with non-C-object");
+    }
+    if (!PyErr_Occurred())
+        PyErr_SetString(PyExc_TypeError,
+                        "PyCObject_GetDesc called with null pointer");
+    return NULL;
+}
+
+void *
+PyCObject_Import(char *module_name, char *name)
+{
+    PyObject *m, *c;
+    void *r = NULL;
+
+    if ((m = PyImport_ImportModule(module_name))) {
+        if ((c = PyObject_GetAttrString(m,name))) {
+            r = PyCObject_AsVoidPtr(c);
+            Py_DECREF(c);
+	}
+        Py_DECREF(m);
+    }
+    return r;
+}
+
+int
+PyCObject_SetVoidPtr(PyObject *self, void *cobj)
+{
+    PyCObject* cself = (PyCObject*)self;
+    if (cself == NULL || !PyCObject_Check(cself) ||
+	cself->destructor != NULL) {
+	PyErr_SetString(PyExc_TypeError, 
+			"Invalid call to PyCObject_SetVoidPtr");
+	return 0;
+    }
+    cself->cobject = cobj;
+    return 1;
+}
+
+static void
+PyCObject_dealloc(PyCObject *self)
+{
+    if (self->destructor) {
+        if(self->desc)
+            ((destructor2)(self->destructor))(self->cobject, self->desc);
+        else
+            (self->destructor)(self->cobject);
+    }
+    PyObject_DEL(self);
+}
+
+
+PyDoc_STRVAR(PyCObject_Type__doc__,
+"C objects to be exported from one extension module to another\n\
+\n\
+C objects are used for communication between extension modules.  They\n\
+provide a way for an extension module to export a C interface to other\n\
+extension modules, so that extension modules can use the Python import\n\
+mechanism to link to one another.");
+
+PyTypeObject PyCObject_Type = {
+    PyObject_HEAD_INIT(&PyType_Type)
+    0,				/*ob_size*/
+    "PyCObject",		/*tp_name*/
+    sizeof(PyCObject),		/*tp_basicsize*/
+    0,				/*tp_itemsize*/
+    /* methods */
+    (destructor)PyCObject_dealloc, /*tp_dealloc*/
+    0,				/*tp_print*/
+    0,				/*tp_getattr*/
+    0,				/*tp_setattr*/
+    0,				/*tp_compare*/
+    0,				/*tp_repr*/
+    0,				/*tp_as_number*/
+    0,				/*tp_as_sequence*/
+    0,				/*tp_as_mapping*/
+    0,				/*tp_hash*/
+    0,				/*tp_call*/
+    0,				/*tp_str*/
+    0,				/*tp_getattro*/
+    0,				/*tp_setattro*/
+    0,				/*tp_as_buffer*/
+    0,				/*tp_flags*/
+    PyCObject_Type__doc__	/*tp_doc*/
+};

Added: vendor/Python/current/Objects/codeobject.c
===================================================================
--- vendor/Python/current/Objects/codeobject.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Objects/codeobject.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,590 @@
+#include "Python.h"
+#include "code.h"
+#include "structmember.h"
+
+#define NAME_CHARS \
+	"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"
+
+/* all_name_chars(s): true iff all chars in s are valid NAME_CHARS */
+
+static int
+all_name_chars(unsigned char *s)
+{
+	static char ok_name_char[256];
+	static unsigned char *name_chars = (unsigned char *)NAME_CHARS;
+
+	if (ok_name_char[*name_chars] == 0) {
+		unsigned char *p;
+		for (p = name_chars; *p; p++)
+			ok_name_char[*p] = 1;
+	}
+	while (*s) {
+		if (ok_name_char[*s++] == 0)
+			return 0;
+	}
+	return 1;
+}
+
+static void
+intern_strings(PyObject *tuple)
+{
+	Py_ssize_t i;
+
+	for (i = PyTuple_GET_SIZE(tuple); --i >= 0; ) {
+		PyObject *v = PyTuple_GET_ITEM(tuple, i);
+		if (v == NULL || !PyString_CheckExact(v)) {
+			Py_FatalError("non-string found in code slot");
+		}
+		PyString_InternInPlace(&PyTuple_GET_ITEM(tuple, i));
+	}
+}
+
+
+PyCodeObject *
+PyCode_New(int argcount, int nlocals, int stacksize, int flags,
+	   PyObject *code, PyObject *consts, PyObject *names,
+	   PyObject *varnames, PyObject *freevars, PyObject *cellvars,
+	   PyObject *filename, PyObject *name, int firstlineno,
+	   PyObject *lnotab)
+{
+	PyCodeObject *co;
+	Py_ssize_t i;
+	/* Check argument types */
+	if (argcount < 0 || nlocals < 0 ||
+	    code == NULL ||
+	    consts == NULL || !PyTuple_Check(consts) ||
+	    names == NULL || !PyTuple_Check(names) ||
+	    varnames == NULL || !PyTuple_Check(varnames) ||
+	    freevars == NULL || !PyTuple_Check(freevars) ||
+	    cellvars == NULL || !PyTuple_Check(cellvars) ||
+	    name == NULL || !PyString_Check(name) ||
+	    filename == NULL || !PyString_Check(filename) ||
+	    lnotab == NULL || !PyString_Check(lnotab) ||
+	    !PyObject_CheckReadBuffer(code)) {
+		PyErr_BadInternalCall();
+		return NULL;
+	}
+	intern_strings(names);
+	intern_strings(varnames);
+	intern_strings(freevars);
+	intern_strings(cellvars);
+	/* Intern selected string constants */
+	for (i = PyTuple_Size(consts); --i >= 0; ) {
+		PyObject *v = PyTuple_GetItem(consts, i);
+		if (!PyString_Check(v))
+			continue;
+		if (!all_name_chars((unsigned char *)PyString_AS_STRING(v)))
+			continue;
+		PyString_InternInPlace(&PyTuple_GET_ITEM(consts, i));
+	}
+	co = PyObject_NEW(PyCodeObject, &PyCode_Type);
+	if (co != NULL) {
+		co->co_argcount = argcount;
+		co->co_nlocals = nlocals;
+		co->co_stacksize = stacksize;
+		co->co_flags = flags;
+		Py_INCREF(code);
+		co->co_code = code;
+		Py_INCREF(consts);
+		co->co_consts = consts;
+		Py_INCREF(names);
+		co->co_names = names;
+		Py_INCREF(varnames);
+		co->co_varnames = varnames;
+		Py_INCREF(freevars);
+		co->co_freevars = freevars;
+		Py_INCREF(cellvars);
+		co->co_cellvars = cellvars;
+		Py_INCREF(filename);
+		co->co_filename = filename;
+		Py_INCREF(name);
+		co->co_name = name;
+		co->co_firstlineno = firstlineno;
+		Py_INCREF(lnotab);
+		co->co_lnotab = lnotab;
+                co->co_zombieframe = NULL;
+	}
+	return co;
+}
+
+
+#define OFF(x) offsetof(PyCodeObject, x)
+
+static PyMemberDef code_memberlist[] = {
+	{"co_argcount",	T_INT,		OFF(co_argcount),	READONLY},
+	{"co_nlocals",	T_INT,		OFF(co_nlocals),	READONLY},
+	{"co_stacksize",T_INT,		OFF(co_stacksize),	READONLY},
+	{"co_flags",	T_INT,		OFF(co_flags),		READONLY},
+	{"co_code",	T_OBJECT,	OFF(co_code),		READONLY},
+	{"co_consts",	T_OBJECT,	OFF(co_consts),		READONLY},
+	{"co_names",	T_OBJECT,	OFF(co_names),		READONLY},
+	{"co_varnames",	T_OBJECT,	OFF(co_varnames),	READONLY},
+	{"co_freevars",	T_OBJECT,	OFF(co_freevars),	READONLY},
+	{"co_cellvars",	T_OBJECT,	OFF(co_cellvars),	READONLY},
+	{"co_filename",	T_OBJECT,	OFF(co_filename),	READONLY},
+	{"co_name",	T_OBJECT,	OFF(co_name),		READONLY},
+	{"co_firstlineno", T_INT,	OFF(co_firstlineno),	READONLY},
+	{"co_lnotab",	T_OBJECT,	OFF(co_lnotab),		READONLY},
+	{NULL}	/* Sentinel */
+};
+
+/* Helper for code_new: return a shallow copy of a tuple that is
+   guaranteed to contain exact strings, by converting string subclasses
+   to exact strings and complaining if a non-string is found. */
+static PyObject*
+validate_and_copy_tuple(PyObject *tup)
+{
+	PyObject *newtuple;
+	PyObject *item;
+	Py_ssize_t i, len;
+
+	len = PyTuple_GET_SIZE(tup);
+	newtuple = PyTuple_New(len);
+	if (newtuple == NULL)
+		return NULL;
+
+	for (i = 0; i < len; i++) {
+		item = PyTuple_GET_ITEM(tup, i);
+		if (PyString_CheckExact(item)) {
+			Py_INCREF(item);
+		}
+		else if (!PyString_Check(item)) {
+			PyErr_Format(
+				PyExc_TypeError,
+				"name tuples must contain only "
+				"strings, not '%.500s'",
+				item->ob_type->tp_name);
+			Py_DECREF(newtuple);
+			return NULL;
+		}
+		else {
+			item = PyString_FromStringAndSize(
+				PyString_AS_STRING(item),
+				PyString_GET_SIZE(item));
+			if (item == NULL) {
+				Py_DECREF(newtuple);
+				return NULL;
+			}
+		}
+		PyTuple_SET_ITEM(newtuple, i, item);
+	}
+
+	return newtuple;
+}
+
+PyDoc_STRVAR(code_doc,
+"code(argcount, nlocals, stacksize, flags, codestring, constants, names,\n\
+      varnames, filename, name, firstlineno, lnotab[, freevars[, cellvars]])\n\
+\n\
+Create a code object.  Not for the faint of heart.");
+
+static PyObject *
+code_new(PyTypeObject *type, PyObject *args, PyObject *kw)
+{
+	int argcount;
+	int nlocals;
+	int stacksize;
+	int flags;
+	PyObject *co = NULL;
+	PyObject *code;
+	PyObject *consts;
+	PyObject *names, *ournames = NULL;
+	PyObject *varnames, *ourvarnames = NULL;
+	PyObject *freevars = NULL, *ourfreevars = NULL;
+	PyObject *cellvars = NULL, *ourcellvars = NULL;
+	PyObject *filename;
+	PyObject *name;
+	int firstlineno;
+	PyObject *lnotab;
+
+	if (!PyArg_ParseTuple(args, "iiiiSO!O!O!SSiS|O!O!:code",
+			      &argcount, &nlocals, &stacksize, &flags,
+			      &code,
+			      &PyTuple_Type, &consts,
+			      &PyTuple_Type, &names,
+			      &PyTuple_Type, &varnames,
+			      &filename, &name,
+			      &firstlineno, &lnotab,
+			      &PyTuple_Type, &freevars,
+			      &PyTuple_Type, &cellvars))
+		return NULL;
+
+	if (argcount < 0) {
+		PyErr_SetString(
+			PyExc_ValueError,
+			"code: argcount must not be negative");
+		goto cleanup;
+	}
+
+	if (nlocals < 0) {
+		PyErr_SetString(
+			PyExc_ValueError,
+			"code: nlocals must not be negative");
+		goto cleanup;
+	}
+
+	ournames = validate_and_copy_tuple(names);
+	if (ournames == NULL)
+		goto cleanup;
+	ourvarnames = validate_and_copy_tuple(varnames);
+	if (ourvarnames == NULL)
+		goto cleanup;
+	if (freevars)
+		ourfreevars = validate_and_copy_tuple(freevars);
+	else
+		ourfreevars = PyTuple_New(0);
+	if (ourfreevars == NULL)
+		goto cleanup;
+	if (cellvars)
+		ourcellvars = validate_and_copy_tuple(cellvars);
+	else
+		ourcellvars = PyTuple_New(0);
+	if (ourcellvars == NULL)
+		goto cleanup;
+
+	co = (PyObject *)PyCode_New(argcount, nlocals, stacksize, flags,
+				    code, consts, ournames, ourvarnames,
+				    ourfreevars, ourcellvars, filename,
+				    name, firstlineno, lnotab);
+  cleanup:
+	Py_XDECREF(ournames);
+	Py_XDECREF(ourvarnames);
+	Py_XDECREF(ourfreevars);
+	Py_XDECREF(ourcellvars);
+	return co;
+}
+
+static void
+code_dealloc(PyCodeObject *co)
+{
+	Py_XDECREF(co->co_code);
+	Py_XDECREF(co->co_consts);
+	Py_XDECREF(co->co_names);
+	Py_XDECREF(co->co_varnames);
+	Py_XDECREF(co->co_freevars);
+	Py_XDECREF(co->co_cellvars);
+	Py_XDECREF(co->co_filename);
+	Py_XDECREF(co->co_name);
+	Py_XDECREF(co->co_lnotab);
+        if (co->co_zombieframe != NULL)
+                PyObject_GC_Del(co->co_zombieframe);
+	PyObject_DEL(co);
+}
+
+static PyObject *
+code_repr(PyCodeObject *co)
+{
+	char buf[500];
+	int lineno = -1;
+	char *filename = "???";
+	char *name = "???";
+
+	if (co->co_firstlineno != 0)
+		lineno = co->co_firstlineno;
+	if (co->co_filename && PyString_Check(co->co_filename))
+		filename = PyString_AS_STRING(co->co_filename);
+	if (co->co_name && PyString_Check(co->co_name))
+		name = PyString_AS_STRING(co->co_name);
+	PyOS_snprintf(buf, sizeof(buf),
+		      "<code object %.100s at %p, file \"%.300s\", line %d>",
+		      name, co, filename, lineno);
+	return PyString_FromString(buf);
+}
+
+static int
+code_compare(PyCodeObject *co, PyCodeObject *cp)
+{
+	int cmp;
+	cmp = PyObject_Compare(co->co_name, cp->co_name);
+	if (cmp) return cmp;
+	cmp = co->co_argcount - cp->co_argcount;
+	if (cmp) goto normalize;
+	cmp = co->co_nlocals - cp->co_nlocals;
+	if (cmp) goto normalize;
+	cmp = co->co_flags - cp->co_flags;
+	if (cmp) goto normalize;
+	cmp = co->co_firstlineno - cp->co_firstlineno;
+	if (cmp) goto normalize;
+	cmp = PyObject_Compare(co->co_code, cp->co_code);
+	if (cmp) return cmp;
+	cmp = PyObject_Compare(co->co_consts, cp->co_consts);
+	if (cmp) return cmp;
+	cmp = PyObject_Compare(co->co_names, cp->co_names);
+	if (cmp) return cmp;
+	cmp = PyObject_Compare(co->co_varnames, cp->co_varnames);
+	if (cmp) return cmp;
+	cmp = PyObject_Compare(co->co_freevars, cp->co_freevars);
+	if (cmp) return cmp;
+	cmp = PyObject_Compare(co->co_cellvars, cp->co_cellvars);
+	return cmp;
+
+ normalize:
+	if (cmp > 0)
+		return 1;
+	else if (cmp < 0)
+		return -1;
+	else
+		return 0;
+}
+
+static long
+code_hash(PyCodeObject *co)
+{
+	long h, h0, h1, h2, h3, h4, h5, h6;
+	h0 = PyObject_Hash(co->co_name);
+	if (h0 == -1) return -1;
+	h1 = PyObject_Hash(co->co_code);
+	if (h1 == -1) return -1;
+	h2 = PyObject_Hash(co->co_consts);
+	if (h2 == -1) return -1;
+	h3 = PyObject_Hash(co->co_names);
+	if (h3 == -1) return -1;
+	h4 = PyObject_Hash(co->co_varnames);
+	if (h4 == -1) return -1;
+	h5 = PyObject_Hash(co->co_freevars);
+	if (h5 == -1) return -1;
+	h6 = PyObject_Hash(co->co_cellvars);
+	if (h6 == -1) return -1;
+	h = h0 ^ h1 ^ h2 ^ h3 ^ h4 ^ h5 ^ h6 ^
+		co->co_argcount ^ co->co_nlocals ^ co->co_flags;
+	if (h == -1) h = -2;
+	return h;
+}
+
+/* XXX code objects need to participate in GC? */
+
+PyTypeObject PyCode_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,
+	"code",
+	sizeof(PyCodeObject),
+	0,
+	(destructor)code_dealloc, 	/* tp_dealloc */
+	0,				/* tp_print */
+	0, 				/* tp_getattr */
+	0,				/* tp_setattr */
+	(cmpfunc)code_compare, 		/* tp_compare */
+	(reprfunc)code_repr,		/* tp_repr */
+	0,				/* tp_as_number */
+	0,				/* tp_as_sequence */
+	0,				/* tp_as_mapping */
+	(hashfunc)code_hash, 		/* tp_hash */
+	0,				/* tp_call */
+	0,				/* tp_str */
+	PyObject_GenericGetAttr,	/* tp_getattro */
+	0,				/* tp_setattro */
+	0,				/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT,		/* tp_flags */
+	code_doc,			/* tp_doc */
+	0,				/* tp_traverse */
+	0,				/* tp_clear */
+	0,				/* tp_richcompare */
+	0,				/* tp_weaklistoffset */
+	0,				/* tp_iter */
+	0,				/* tp_iternext */
+	0,				/* tp_methods */
+	code_memberlist,		/* tp_members */
+	0,				/* tp_getset */
+	0,				/* tp_base */
+	0,				/* tp_dict */
+	0,				/* tp_descr_get */
+	0,				/* tp_descr_set */
+	0,				/* tp_dictoffset */
+	0,				/* tp_init */
+	0,				/* tp_alloc */
+	code_new,			/* tp_new */
+};
+
+/* All about c_lnotab.
+
+c_lnotab is an array of unsigned bytes disguised as a Python string.  In -O
+mode, SET_LINENO opcodes aren't generated, and bytecode offsets are mapped
+to source code line #s (when needed for tracebacks) via c_lnotab instead.
+The array is conceptually a list of
+    (bytecode offset increment, line number increment)
+pairs.  The details are important and delicate, best illustrated by example:
+
+    byte code offset    source code line number
+        0		    1
+        6		    2
+       50		    7
+      350                 307
+      361                 308
+
+The first trick is that these numbers aren't stored, only the increments
+from one row to the next (this doesn't really work, but it's a start):
+
+    0, 1,  6, 1,  44, 5,  300, 300,  11, 1
+
+The second trick is that an unsigned byte can't hold negative values, or
+values larger than 255, so (a) there's a deep assumption that byte code
+offsets and their corresponding line #s both increase monotonically, and (b)
+if at least one column jumps by more than 255 from one row to the next, more
+than one pair is written to the table. In case #b, there's no way to know
+from looking at the table later how many were written.  That's the delicate
+part.  A user of c_lnotab desiring to find the source line number
+corresponding to a bytecode address A should do something like this
+
+    lineno = addr = 0
+    for addr_incr, line_incr in c_lnotab:
+        addr += addr_incr
+        if addr > A:
+            return lineno
+        lineno += line_incr
+
+In order for this to work, when the addr field increments by more than 255,
+the line # increment in each pair generated must be 0 until the remaining addr
+increment is < 256.  So, in the example above, com_set_lineno should not (as
+was actually done until 2.2) expand 300, 300 to 255, 255,  45, 45, but to
+255, 0,  45, 255,  0, 45.
+*/
+
+int
+PyCode_Addr2Line(PyCodeObject *co, int addrq)
+{
+	int size = PyString_Size(co->co_lnotab) / 2;
+	unsigned char *p = (unsigned char*)PyString_AsString(co->co_lnotab);
+	int line = co->co_firstlineno;
+	int addr = 0;
+	while (--size >= 0) {
+		addr += *p++;
+		if (addr > addrq)
+			break;
+		line += *p++;
+	}
+	return line;
+}
+
+/* 
+   Check whether the current instruction is at the start of a line.
+
+ */
+
+	/* The theory of SET_LINENO-less tracing.
+
+	   In a nutshell, we use the co_lnotab field of the code object
+	   to tell when execution has moved onto a different line.
+
+	   As mentioned above, the basic idea is so set things up so
+	   that
+
+	         *instr_lb <= frame->f_lasti < *instr_ub
+
+	   is true so long as execution does not change lines.
+
+	   This is all fairly simple.  Digging the information out of
+	   co_lnotab takes some work, but is conceptually clear.
+
+	   Somewhat harder to explain is why we don't *always* call the
+	   line trace function when the above test fails.
+
+	   Consider this code:
+
+	   1: def f(a):
+	   2:     if a:
+	   3:        print 1
+	   4:     else:
+	   5:        print 2
+
+	   which compiles to this:
+
+	   2           0 LOAD_FAST                0 (a)
+		       3 JUMP_IF_FALSE            9 (to 15)
+		       6 POP_TOP
+
+	   3           7 LOAD_CONST               1 (1)
+		      10 PRINT_ITEM
+		      11 PRINT_NEWLINE
+		      12 JUMP_FORWARD             6 (to 21)
+		 >>   15 POP_TOP
+
+	   5          16 LOAD_CONST               2 (2)
+		      19 PRINT_ITEM
+		      20 PRINT_NEWLINE
+		 >>   21 LOAD_CONST               0 (None)
+		      24 RETURN_VALUE
+
+	   If 'a' is false, execution will jump to instruction at offset
+	   15 and the co_lnotab will claim that execution has moved to
+	   line 3.  This is at best misleading.  In this case we could
+	   associate the POP_TOP with line 4, but that doesn't make
+	   sense in all cases (I think).
+
+	   What we do is only call the line trace function if the co_lnotab
+	   indicates we have jumped to the *start* of a line, i.e. if the
+	   current instruction offset matches the offset given for the
+	   start of a line by the co_lnotab.
+
+	   This also takes care of the situation where 'a' is true.
+	   Execution will jump from instruction offset 12 to offset 21.
+	   Then the co_lnotab would imply that execution has moved to line
+	   5, which is again misleading.
+
+	   Why do we set f_lineno when tracing?  Well, consider the code
+	   above when 'a' is true.  If stepping through this with 'n' in
+	   pdb, you would stop at line 1 with a "call" type event, then
+	   line events on lines 2 and 3, then a "return" type event -- but
+	   you would be shown line 5 during this event.  This is a change
+	   from the behaviour in 2.2 and before, and I've found it
+	   confusing in practice.  By setting and using f_lineno when
+	   tracing, one can report a line number different from that
+	   suggested by f_lasti on this one occasion where it's desirable.
+	*/
+
+
+int 
+PyCode_CheckLineNumber(PyCodeObject* co, int lasti, PyAddrPair *bounds)
+{
+        int size, addr, line;
+        unsigned char* p;
+
+        p = (unsigned char*)PyString_AS_STRING(co->co_lnotab);
+        size = PyString_GET_SIZE(co->co_lnotab) / 2;
+
+        addr = 0;
+        line = co->co_firstlineno;
+        assert(line > 0);
+
+        /* possible optimization: if f->f_lasti == instr_ub
+           (likely to be a common case) then we already know
+           instr_lb -- if we stored the matching value of p
+           somwhere we could skip the first while loop. */
+
+        /* see comments in compile.c for the description of
+           co_lnotab.  A point to remember: increments to p
+           should come in pairs -- although we don't care about
+           the line increments here, treating them as byte
+           increments gets confusing, to say the least. */
+
+        bounds->ap_lower = 0;
+        while (size > 0) {
+                if (addr + *p > lasti)
+                        break;
+                addr += *p++;
+                if (*p) 
+                        bounds->ap_lower = addr;
+                line += *p++;
+                --size;
+        }
+
+        /* If lasti and addr don't match exactly, we don't want to
+           change the lineno slot on the frame or execute a trace
+           function.  Return -1 instead.
+        */
+        if (addr != lasti)
+                line = -1;
+        
+        if (size > 0) {
+                while (--size >= 0) {
+                        addr += *p++;
+                        if (*p++)
+                                break;
+                }
+                bounds->ap_upper = addr;
+        }
+        else {
+                bounds->ap_upper = INT_MAX;
+        }
+
+        return line;
+}

Added: vendor/Python/current/Objects/complexobject.c
===================================================================
--- vendor/Python/current/Objects/complexobject.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Objects/complexobject.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1031 @@
+
+/* Complex object implementation */
+
+/* Borrows heavily from floatobject.c */
+
+/* Submitted by Jim Hugunin */
+
+#include "Python.h"
+#include "structmember.h"
+
+#ifndef WITHOUT_COMPLEX
+
+/* Precisions used by repr() and str(), respectively.
+
+   The repr() precision (17 significant decimal digits) is the minimal number
+   that is guaranteed to have enough precision so that if the number is read
+   back in the exact same binary value is recreated.  This is true for IEEE
+   floating point by design, and also happens to work for all other modern
+   hardware.
+
+   The str() precision is chosen so that in most cases, the rounding noise
+   created by various operations is suppressed, while giving plenty of
+   precision for practical use.
+*/
+
+#define PREC_REPR	17
+#define PREC_STR	12
+
+/* elementary operations on complex numbers */
+
+static Py_complex c_1 = {1., 0.};
+
+Py_complex
+c_sum(Py_complex a, Py_complex b)
+{
+	Py_complex r;
+	r.real = a.real + b.real;
+	r.imag = a.imag + b.imag;
+	return r;
+}
+
+Py_complex
+c_diff(Py_complex a, Py_complex b)
+{
+	Py_complex r;
+	r.real = a.real - b.real;
+	r.imag = a.imag - b.imag;
+	return r;
+}
+
+Py_complex
+c_neg(Py_complex a)
+{
+	Py_complex r;
+	r.real = -a.real;
+	r.imag = -a.imag;
+	return r;
+}
+
+Py_complex
+c_prod(Py_complex a, Py_complex b)
+{
+	Py_complex r;
+	r.real = a.real*b.real - a.imag*b.imag;
+	r.imag = a.real*b.imag + a.imag*b.real;
+	return r;
+}
+
+Py_complex
+c_quot(Py_complex a, Py_complex b)
+{
+	/******************************************************************
+	This was the original algorithm.  It's grossly prone to spurious
+	overflow and underflow errors.  It also merrily divides by 0 despite
+	checking for that(!).  The code still serves a doc purpose here, as
+	the algorithm following is a simple by-cases transformation of this
+	one:
+
+	Py_complex r;
+	double d = b.real*b.real + b.imag*b.imag;
+	if (d == 0.)
+		errno = EDOM;
+	r.real = (a.real*b.real + a.imag*b.imag)/d;
+	r.imag = (a.imag*b.real - a.real*b.imag)/d;
+	return r;
+	******************************************************************/
+
+	/* This algorithm is better, and is pretty obvious:  first divide the
+	 * numerators and denominator by whichever of {b.real, b.imag} has
+	 * larger magnitude.  The earliest reference I found was to CACM
+	 * Algorithm 116 (Complex Division, Robert L. Smith, Stanford
+	 * University).  As usual, though, we're still ignoring all IEEE
+	 * endcases.
+	 */
+	 Py_complex r;	/* the result */
+ 	 const double abs_breal = b.real < 0 ? -b.real : b.real;
+	 const double abs_bimag = b.imag < 0 ? -b.imag : b.imag;
+
+	 if (abs_breal >= abs_bimag) {
+ 		/* divide tops and bottom by b.real */
+	 	if (abs_breal == 0.0) {
+	 		errno = EDOM;
+	 		r.real = r.imag = 0.0;
+	 	}
+	 	else {
+	 		const double ratio = b.imag / b.real;
+	 		const double denom = b.real + b.imag * ratio;
+	 		r.real = (a.real + a.imag * ratio) / denom;
+	 		r.imag = (a.imag - a.real * ratio) / denom;
+	 	}
+	}
+	else {
+		/* divide tops and bottom by b.imag */
+		const double ratio = b.real / b.imag;
+		const double denom = b.real * ratio + b.imag;
+		assert(b.imag != 0.0);
+		r.real = (a.real * ratio + a.imag) / denom;
+		r.imag = (a.imag * ratio - a.real) / denom;
+	}
+	return r;
+}
+
+Py_complex
+c_pow(Py_complex a, Py_complex b)
+{
+	Py_complex r;
+	double vabs,len,at,phase;
+	if (b.real == 0. && b.imag == 0.) {
+		r.real = 1.;
+		r.imag = 0.;
+	}
+	else if (a.real == 0. && a.imag == 0.) {
+		if (b.imag != 0. || b.real < 0.)
+			errno = EDOM;
+		r.real = 0.;
+		r.imag = 0.;
+	}
+	else {
+		vabs = hypot(a.real,a.imag);
+		len = pow(vabs,b.real);
+		at = atan2(a.imag, a.real);
+		phase = at*b.real;
+		if (b.imag != 0.0) {
+			len /= exp(at*b.imag);
+			phase += b.imag*log(vabs);
+		}
+		r.real = len*cos(phase);
+		r.imag = len*sin(phase);
+	}
+	return r;
+}
+
+static Py_complex
+c_powu(Py_complex x, long n)
+{
+	Py_complex r, p;
+	long mask = 1;
+	r = c_1;
+	p = x;
+	while (mask > 0 && n >= mask) {
+		if (n & mask)
+			r = c_prod(r,p);
+		mask <<= 1;
+		p = c_prod(p,p);
+	}
+	return r;
+}
+
+static Py_complex
+c_powi(Py_complex x, long n)
+{
+	Py_complex cn;
+
+	if (n > 100 || n < -100) {
+		cn.real = (double) n;
+		cn.imag = 0.;
+		return c_pow(x,cn);
+	}
+	else if (n > 0)
+		return c_powu(x,n);
+	else
+		return c_quot(c_1,c_powu(x,-n));
+
+}
+
+static PyObject *
+complex_subtype_from_c_complex(PyTypeObject *type, Py_complex cval)
+{
+	PyObject *op;
+
+	op = type->tp_alloc(type, 0);
+	if (op != NULL)
+		((PyComplexObject *)op)->cval = cval;
+	return op;
+}
+
+PyObject *
+PyComplex_FromCComplex(Py_complex cval)
+{
+	register PyComplexObject *op;
+
+	/* Inline PyObject_New */
+	op = (PyComplexObject *) PyObject_MALLOC(sizeof(PyComplexObject));
+	if (op == NULL)
+		return PyErr_NoMemory();
+	PyObject_INIT(op, &PyComplex_Type);
+	op->cval = cval;
+	return (PyObject *) op;
+}
+
+static PyObject *
+complex_subtype_from_doubles(PyTypeObject *type, double real, double imag)
+{
+	Py_complex c;
+	c.real = real;
+	c.imag = imag;
+	return complex_subtype_from_c_complex(type, c);
+}
+
+PyObject *
+PyComplex_FromDoubles(double real, double imag)
+{
+	Py_complex c;
+	c.real = real;
+	c.imag = imag;
+	return PyComplex_FromCComplex(c);
+}
+
+double
+PyComplex_RealAsDouble(PyObject *op)
+{
+	if (PyComplex_Check(op)) {
+		return ((PyComplexObject *)op)->cval.real;
+	}
+	else {
+		return PyFloat_AsDouble(op);
+	}
+}
+
+double
+PyComplex_ImagAsDouble(PyObject *op)
+{
+	if (PyComplex_Check(op)) {
+		return ((PyComplexObject *)op)->cval.imag;
+	}
+	else {
+		return 0.0;
+	}
+}
+
+Py_complex
+PyComplex_AsCComplex(PyObject *op)
+{
+	Py_complex cv;
+	if (PyComplex_Check(op)) {
+		return ((PyComplexObject *)op)->cval;
+	}
+	else {
+		cv.real = PyFloat_AsDouble(op);
+		cv.imag = 0.;
+		return cv;
+	}
+}
+
+static void
+complex_dealloc(PyObject *op)
+{
+	op->ob_type->tp_free(op);
+}
+
+
+static void
+complex_to_buf(char *buf, int bufsz, PyComplexObject *v, int precision)
+{
+	char format[32];
+	if (v->cval.real == 0.) {
+		PyOS_snprintf(format, sizeof(format), "%%.%ig", precision);
+		PyOS_ascii_formatd(buf, bufsz - 1, format, v->cval.imag);
+		strncat(buf, "j", 1);
+	} else {
+		char re[64], im[64];
+		/* Format imaginary part with sign, real part without */
+		PyOS_snprintf(format, sizeof(format), "%%.%ig", precision);
+		PyOS_ascii_formatd(re, sizeof(re), format, v->cval.real);
+		PyOS_snprintf(format, sizeof(format), "%%+.%ig", precision);
+		PyOS_ascii_formatd(im, sizeof(im), format, v->cval.imag);
+		PyOS_snprintf(buf, bufsz, "(%s%sj)", re, im);
+	}
+}
+
+static int
+complex_print(PyComplexObject *v, FILE *fp, int flags)
+{
+	char buf[100];
+	complex_to_buf(buf, sizeof(buf), v,
+		       (flags & Py_PRINT_RAW) ? PREC_STR : PREC_REPR);
+	fputs(buf, fp);
+	return 0;
+}
+
+static PyObject *
+complex_repr(PyComplexObject *v)
+{
+	char buf[100];
+	complex_to_buf(buf, sizeof(buf), v, PREC_REPR);
+	return PyString_FromString(buf);
+}
+
+static PyObject *
+complex_str(PyComplexObject *v)
+{
+	char buf[100];
+	complex_to_buf(buf, sizeof(buf), v, PREC_STR);
+	return PyString_FromString(buf);
+}
+
+static long
+complex_hash(PyComplexObject *v)
+{
+	long hashreal, hashimag, combined;
+	hashreal = _Py_HashDouble(v->cval.real);
+	if (hashreal == -1)
+		return -1;
+	hashimag = _Py_HashDouble(v->cval.imag);
+	if (hashimag == -1)
+		return -1;
+	/* Note:  if the imaginary part is 0, hashimag is 0 now,
+	 * so the following returns hashreal unchanged.  This is
+	 * important because numbers of different types that
+	 * compare equal must have the same hash value, so that
+	 * hash(x + 0*j) must equal hash(x).
+	 */
+	combined = hashreal + 1000003 * hashimag;
+	if (combined == -1)
+		combined = -2;
+	return combined;
+}
+
+static PyObject *
+complex_add(PyComplexObject *v, PyComplexObject *w)
+{
+	Py_complex result;
+	PyFPE_START_PROTECT("complex_add", return 0)
+	result = c_sum(v->cval,w->cval);
+	PyFPE_END_PROTECT(result)
+	return PyComplex_FromCComplex(result);
+}
+
+static PyObject *
+complex_sub(PyComplexObject *v, PyComplexObject *w)
+{
+	Py_complex result;
+	PyFPE_START_PROTECT("complex_sub", return 0)
+	result = c_diff(v->cval,w->cval);
+	PyFPE_END_PROTECT(result)
+	return PyComplex_FromCComplex(result);
+}
+
+static PyObject *
+complex_mul(PyComplexObject *v, PyComplexObject *w)
+{
+	Py_complex result;
+	PyFPE_START_PROTECT("complex_mul", return 0)
+	result = c_prod(v->cval,w->cval);
+	PyFPE_END_PROTECT(result)
+	return PyComplex_FromCComplex(result);
+}
+
+static PyObject *
+complex_div(PyComplexObject *v, PyComplexObject *w)
+{
+	Py_complex quot;
+	PyFPE_START_PROTECT("complex_div", return 0)
+	errno = 0;
+	quot = c_quot(v->cval,w->cval);
+	PyFPE_END_PROTECT(quot)
+	if (errno == EDOM) {
+		PyErr_SetString(PyExc_ZeroDivisionError, "complex division");
+		return NULL;
+	}
+	return PyComplex_FromCComplex(quot);
+}
+
+static PyObject *
+complex_classic_div(PyComplexObject *v, PyComplexObject *w)
+{
+	Py_complex quot;
+
+	if (Py_DivisionWarningFlag >= 2 &&
+	    PyErr_Warn(PyExc_DeprecationWarning,
+		       "classic complex division") < 0)
+		return NULL;
+
+	PyFPE_START_PROTECT("complex_classic_div", return 0)
+	errno = 0;
+	quot = c_quot(v->cval,w->cval);
+	PyFPE_END_PROTECT(quot)
+	if (errno == EDOM) {
+		PyErr_SetString(PyExc_ZeroDivisionError, "complex division");
+		return NULL;
+	}
+	return PyComplex_FromCComplex(quot);
+}
+
+static PyObject *
+complex_remainder(PyComplexObject *v, PyComplexObject *w)
+{
+        Py_complex div, mod;
+
+	if (PyErr_Warn(PyExc_DeprecationWarning,
+		       "complex divmod(), // and % are deprecated") < 0)
+		return NULL;
+
+	errno = 0;
+	div = c_quot(v->cval,w->cval); /* The raw divisor value. */
+	if (errno == EDOM) {
+		PyErr_SetString(PyExc_ZeroDivisionError, "complex remainder");
+		return NULL;
+	}
+	div.real = floor(div.real); /* Use the floor of the real part. */
+	div.imag = 0.0;
+	mod = c_diff(v->cval, c_prod(w->cval, div));
+
+	return PyComplex_FromCComplex(mod);
+}
+
+
+static PyObject *
+complex_divmod(PyComplexObject *v, PyComplexObject *w)
+{
+        Py_complex div, mod;
+	PyObject *d, *m, *z;
+
+	if (PyErr_Warn(PyExc_DeprecationWarning,
+		       "complex divmod(), // and % are deprecated") < 0)
+		return NULL;
+
+	errno = 0;
+	div = c_quot(v->cval,w->cval); /* The raw divisor value. */
+	if (errno == EDOM) {
+		PyErr_SetString(PyExc_ZeroDivisionError, "complex divmod()");
+		return NULL;
+	}
+	div.real = floor(div.real); /* Use the floor of the real part. */
+	div.imag = 0.0;
+	mod = c_diff(v->cval, c_prod(w->cval, div));
+	d = PyComplex_FromCComplex(div);
+	m = PyComplex_FromCComplex(mod);
+	z = PyTuple_Pack(2, d, m);
+	Py_XDECREF(d);
+	Py_XDECREF(m);
+	return z;
+}
+
+static PyObject *
+complex_pow(PyComplexObject *v, PyObject *w, PyComplexObject *z)
+{
+	Py_complex p;
+	Py_complex exponent;
+	long int_exponent;
+
+ 	if ((PyObject *)z!=Py_None) {
+		PyErr_SetString(PyExc_ValueError, "complex modulo");
+		return NULL;
+	}
+	PyFPE_START_PROTECT("complex_pow", return 0)
+	errno = 0;
+	exponent = ((PyComplexObject*)w)->cval;
+	int_exponent = (long)exponent.real;
+	if (exponent.imag == 0. && exponent.real == int_exponent)
+		p = c_powi(v->cval,int_exponent);
+	else
+		p = c_pow(v->cval,exponent);
+
+	PyFPE_END_PROTECT(p)
+	Py_ADJUST_ERANGE2(p.real, p.imag);
+	if (errno == EDOM) {
+		PyErr_SetString(PyExc_ZeroDivisionError,
+				"0.0 to a negative or complex power");
+		return NULL;
+	}
+	else if (errno == ERANGE) {
+		PyErr_SetString(PyExc_OverflowError,
+				"complex exponentiation");
+		return NULL;
+	}
+	return PyComplex_FromCComplex(p);
+}
+
+static PyObject *
+complex_int_div(PyComplexObject *v, PyComplexObject *w)
+{
+	PyObject *t, *r;
+	
+	t = complex_divmod(v, w);
+	if (t != NULL) {
+		r = PyTuple_GET_ITEM(t, 0);
+		Py_INCREF(r);
+		Py_DECREF(t);
+		return r;
+	}
+	return NULL;
+}
+
+static PyObject *
+complex_neg(PyComplexObject *v)
+{
+	Py_complex neg;
+	neg.real = -v->cval.real;
+	neg.imag = -v->cval.imag;
+	return PyComplex_FromCComplex(neg);
+}
+
+static PyObject *
+complex_pos(PyComplexObject *v)
+{
+	if (PyComplex_CheckExact(v)) {
+		Py_INCREF(v);
+		return (PyObject *)v;
+	}
+	else
+		return PyComplex_FromCComplex(v->cval);
+}
+
+static PyObject *
+complex_abs(PyComplexObject *v)
+{
+	double result;
+	PyFPE_START_PROTECT("complex_abs", return 0)
+	result = hypot(v->cval.real,v->cval.imag);
+	PyFPE_END_PROTECT(result)
+	return PyFloat_FromDouble(result);
+}
+
+static int
+complex_nonzero(PyComplexObject *v)
+{
+	return v->cval.real != 0.0 || v->cval.imag != 0.0;
+}
+
+static int
+complex_coerce(PyObject **pv, PyObject **pw)
+{
+	Py_complex cval;
+	cval.imag = 0.;
+	if (PyInt_Check(*pw)) {
+		cval.real = (double)PyInt_AsLong(*pw);
+		*pw = PyComplex_FromCComplex(cval);
+		Py_INCREF(*pv);
+		return 0;
+	}
+	else if (PyLong_Check(*pw)) {
+		cval.real = PyLong_AsDouble(*pw);
+		if (cval.real == -1.0 && PyErr_Occurred())
+			return -1;
+		*pw = PyComplex_FromCComplex(cval);
+		Py_INCREF(*pv);
+		return 0;
+	}
+	else if (PyFloat_Check(*pw)) {
+		cval.real = PyFloat_AsDouble(*pw);
+		*pw = PyComplex_FromCComplex(cval);
+		Py_INCREF(*pv);
+		return 0;
+	}
+	else if (PyComplex_Check(*pw)) {
+		Py_INCREF(*pv);
+		Py_INCREF(*pw);
+		return 0;
+	}
+	return 1; /* Can't do it */
+}
+
+static PyObject *
+complex_richcompare(PyObject *v, PyObject *w, int op)
+{
+	int c;
+	Py_complex i, j;
+	PyObject *res;
+
+	c = PyNumber_CoerceEx(&v, &w);
+	if (c < 0)
+		return NULL;
+	if (c > 0) {
+		Py_INCREF(Py_NotImplemented);
+		return Py_NotImplemented;
+	}
+	/* Make sure both arguments are complex. */
+	if (!(PyComplex_Check(v) && PyComplex_Check(w))) {
+		Py_DECREF(v);
+		Py_DECREF(w);
+		Py_INCREF(Py_NotImplemented);
+		return Py_NotImplemented;
+	}
+
+	i = ((PyComplexObject *)v)->cval;
+	j = ((PyComplexObject *)w)->cval;
+	Py_DECREF(v);
+	Py_DECREF(w);
+
+	if (op != Py_EQ && op != Py_NE) {
+		PyErr_SetString(PyExc_TypeError,
+			"no ordering relation is defined for complex numbers");
+		return NULL;
+	}
+
+	if ((i.real == j.real && i.imag == j.imag) == (op == Py_EQ))
+		res = Py_True;
+	else
+		res = Py_False;
+
+	Py_INCREF(res);
+	return res;
+}
+
+static PyObject *
+complex_int(PyObject *v)
+{
+	PyErr_SetString(PyExc_TypeError,
+		   "can't convert complex to int; use int(abs(z))");
+	return NULL;
+}
+
+static PyObject *
+complex_long(PyObject *v)
+{
+	PyErr_SetString(PyExc_TypeError,
+		   "can't convert complex to long; use long(abs(z))");
+	return NULL;
+}
+
+static PyObject *
+complex_float(PyObject *v)
+{
+	PyErr_SetString(PyExc_TypeError,
+		   "can't convert complex to float; use abs(z)");
+	return NULL;
+}
+
+static PyObject *
+complex_conjugate(PyObject *self)
+{
+	Py_complex c;
+	c = ((PyComplexObject *)self)->cval;
+	c.imag = -c.imag;
+	return PyComplex_FromCComplex(c);
+}
+
+static PyObject *
+complex_getnewargs(PyComplexObject *v)
+{
+	return Py_BuildValue("(D)", &v->cval);
+}
+
+static PyMethodDef complex_methods[] = {
+	{"conjugate",	(PyCFunction)complex_conjugate,	METH_NOARGS},
+	{"__getnewargs__",	(PyCFunction)complex_getnewargs,	METH_NOARGS},
+	{NULL,		NULL}		/* sentinel */
+};
+
+static PyMemberDef complex_members[] = {
+	{"real", T_DOUBLE, offsetof(PyComplexObject, cval.real), READONLY,
+	 "the real part of a complex number"},
+	{"imag", T_DOUBLE, offsetof(PyComplexObject, cval.imag), READONLY,
+	 "the imaginary part of a complex number"},
+	{0},
+};
+
+static PyObject *
+complex_subtype_from_string(PyTypeObject *type, PyObject *v)
+{
+	const char *s, *start;
+	char *end;
+	double x=0.0, y=0.0, z;
+	int got_re=0, got_im=0, done=0;
+	int digit_or_dot;
+	int sw_error=0;
+	int sign;
+	char buffer[256]; /* For errors */
+#ifdef Py_USING_UNICODE
+	char s_buffer[256];
+#endif
+	Py_ssize_t len;
+
+	if (PyString_Check(v)) {
+		s = PyString_AS_STRING(v);
+		len = PyString_GET_SIZE(v);
+	}
+#ifdef Py_USING_UNICODE
+	else if (PyUnicode_Check(v)) {
+		if (PyUnicode_GET_SIZE(v) >= (Py_ssize_t)sizeof(s_buffer)) {
+			PyErr_SetString(PyExc_ValueError,
+				 "complex() literal too large to convert");
+			return NULL;
+		}
+		if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(v),
+					    PyUnicode_GET_SIZE(v),
+					    s_buffer,
+					    NULL))
+			return NULL;
+		s = s_buffer;
+		len = strlen(s);
+	}
+#endif
+	else if (PyObject_AsCharBuffer(v, &s, &len)) {
+		PyErr_SetString(PyExc_TypeError,
+				"complex() arg is not a string");
+		return NULL;
+	}
+
+	/* position on first nonblank */
+	start = s;
+	while (*s && isspace(Py_CHARMASK(*s)))
+		s++;
+	if (s[0] == '\0') {
+		PyErr_SetString(PyExc_ValueError,
+				"complex() arg is an empty string");
+		return NULL;
+	}
+
+	z = -1.0;
+	sign = 1;
+	do {
+
+		switch (*s) {
+
+		case '\0':
+			if (s-start != len) {
+				PyErr_SetString(
+					PyExc_ValueError,
+					"complex() arg contains a null byte");
+				return NULL;
+			}
+			if(!done) sw_error=1;
+			break;
+
+		case '-':
+			sign = -1;
+				/* Fallthrough */
+		case '+':
+			if (done)  sw_error=1;
+			s++;
+			if  (  *s=='\0'||*s=='+'||*s=='-'  ||
+			       isspace(Py_CHARMASK(*s))  )  sw_error=1;
+			break;
+
+		case 'J':
+		case 'j':
+			if (got_im || done) {
+				sw_error = 1;
+				break;
+			}
+			if  (z<0.0) {
+				y=sign;
+			}
+			else{
+				y=sign*z;
+			}
+			got_im=1;
+			s++;
+			if  (*s!='+' && *s!='-' )
+				done=1;
+			break;
+
+		default:
+			if (isspace(Py_CHARMASK(*s))) {
+				while (*s && isspace(Py_CHARMASK(*s)))
+					s++;
+				if (s[0] != '\0')
+					sw_error=1;
+				else
+					done = 1;
+				break;
+			}
+			digit_or_dot =
+				(*s=='.' || isdigit(Py_CHARMASK(*s)));
+			if  (done||!digit_or_dot) {
+				sw_error=1;
+				break;
+			}
+			errno = 0;
+			PyFPE_START_PROTECT("strtod", return 0)
+				z = PyOS_ascii_strtod(s, &end) ;
+			PyFPE_END_PROTECT(z)
+				if (errno != 0) {
+					PyOS_snprintf(buffer, sizeof(buffer),
+					  "float() out of range: %.150s", s);
+					PyErr_SetString(
+						PyExc_ValueError,
+						buffer);
+					return NULL;
+				}
+			s=end;
+			if  (*s=='J' || *s=='j') {
+
+				break;
+			}
+			if  (got_re) {
+				sw_error=1;
+				break;
+			}
+
+				/* accept a real part */
+			x=sign*z;
+			got_re=1;
+			if  (got_im)  done=1;
+			z = -1.0;
+			sign = 1;
+			break;
+
+		}  /* end of switch  */
+
+	} while (s - start < len && !sw_error);
+
+	if (sw_error) {
+		PyErr_SetString(PyExc_ValueError,
+				"complex() arg is a malformed string");
+		return NULL;
+	}
+
+	return complex_subtype_from_doubles(type, x, y);
+}
+
+static PyObject *
+complex_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	PyObject *r, *i, *tmp, *f;
+	PyNumberMethods *nbr, *nbi = NULL;
+	Py_complex cr, ci;
+	int own_r = 0;
+	static PyObject *complexstr;
+	static char *kwlist[] = {"real", "imag", 0};
+
+	r = Py_False;
+	i = NULL;
+	if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO:complex", kwlist,
+					 &r, &i))
+		return NULL;
+
+	/* Special-case for single argument that is already complex */
+	if (PyComplex_CheckExact(r) && i == NULL &&
+	    type == &PyComplex_Type) {
+		/* Note that we can't know whether it's safe to return
+		   a complex *subclass* instance as-is, hence the restriction
+		   to exact complexes here.  */
+		Py_INCREF(r);
+		return r;
+	}
+	if (PyString_Check(r) || PyUnicode_Check(r)) {
+		if (i != NULL) {
+			PyErr_SetString(PyExc_TypeError,
+					"complex() can't take second arg"
+					" if first is a string");
+			return NULL;
+                }
+		return complex_subtype_from_string(type, r);
+	}
+	if (i != NULL && (PyString_Check(i) || PyUnicode_Check(i))) {
+		PyErr_SetString(PyExc_TypeError,
+				"complex() second arg can't be a string");
+		return NULL;
+	}
+
+	/* XXX Hack to support classes with __complex__ method */
+	if (complexstr == NULL) {
+		complexstr = PyString_InternFromString("__complex__");
+		if (complexstr == NULL)
+			return NULL;
+	}
+	f = PyObject_GetAttr(r, complexstr);
+	if (f == NULL)
+		PyErr_Clear();
+	else {
+		PyObject *args = PyTuple_New(0);
+		if (args == NULL)
+			return NULL;
+		r = PyEval_CallObject(f, args);
+		Py_DECREF(args);
+		Py_DECREF(f);
+		if (r == NULL)
+			return NULL;
+		own_r = 1;
+	}
+	nbr = r->ob_type->tp_as_number;
+	if (i != NULL)
+		nbi = i->ob_type->tp_as_number;
+	if (nbr == NULL || nbr->nb_float == NULL ||
+	    ((i != NULL) && (nbi == NULL || nbi->nb_float == NULL))) {
+		PyErr_SetString(PyExc_TypeError,
+			   "complex() argument must be a string or a number");
+		if (own_r) {
+			Py_DECREF(r);
+		}
+		return NULL;
+	}
+	if (PyComplex_Check(r)) {
+		/* Note that if r is of a complex subtype, we're only
+		   retaining its real & imag parts here, and the return
+		   value is (properly) of the builtin complex type. */
+		cr = ((PyComplexObject*)r)->cval;
+		if (own_r) {
+			Py_DECREF(r);
+		}
+	}
+	else {
+		tmp = PyNumber_Float(r);
+		if (own_r) {
+			Py_DECREF(r);
+		}
+		if (tmp == NULL)
+			return NULL;
+		if (!PyFloat_Check(tmp)) {
+			PyErr_SetString(PyExc_TypeError,
+					"float(r) didn't return a float");
+			Py_DECREF(tmp);
+			return NULL;
+		}
+		cr.real = PyFloat_AsDouble(tmp);
+		Py_DECREF(tmp);
+		cr.imag = 0.0;
+	}
+	if (i == NULL) {
+		ci.real = 0.0;
+		ci.imag = 0.0;
+	}
+	else if (PyComplex_Check(i))
+		ci = ((PyComplexObject*)i)->cval;
+	else {
+		tmp = (*nbi->nb_float)(i);
+		if (tmp == NULL)
+			return NULL;
+		ci.real = PyFloat_AsDouble(tmp);
+		Py_DECREF(tmp);
+		ci.imag = 0.;
+	}
+	cr.real -= ci.imag;
+	cr.imag += ci.real;
+	return complex_subtype_from_c_complex(type, cr);
+}
+
+PyDoc_STRVAR(complex_doc,
+"complex(real[, imag]) -> complex number\n"
+"\n"
+"Create a complex number from a real part and an optional imaginary part.\n"
+"This is equivalent to (real + imag*1j) where imag defaults to 0.");
+
+static PyNumberMethods complex_as_number = {
+	(binaryfunc)complex_add, 		/* nb_add */
+	(binaryfunc)complex_sub, 		/* nb_subtract */
+	(binaryfunc)complex_mul, 		/* nb_multiply */
+	(binaryfunc)complex_classic_div,	/* nb_divide */
+	(binaryfunc)complex_remainder,		/* nb_remainder */
+	(binaryfunc)complex_divmod,		/* nb_divmod */
+	(ternaryfunc)complex_pow,		/* nb_power */
+	(unaryfunc)complex_neg,			/* nb_negative */
+	(unaryfunc)complex_pos,			/* nb_positive */
+	(unaryfunc)complex_abs,			/* nb_absolute */
+	(inquiry)complex_nonzero,		/* nb_nonzero */
+	0,					/* nb_invert */
+	0,					/* nb_lshift */
+	0,					/* nb_rshift */
+	0,					/* nb_and */
+	0,					/* nb_xor */
+	0,					/* nb_or */
+	complex_coerce,				/* nb_coerce */
+	complex_int,				/* nb_int */
+	complex_long,				/* nb_long */
+	complex_float,				/* nb_float */
+	0,					/* nb_oct */
+	0,					/* nb_hex */
+	0,					/* nb_inplace_add */
+	0,					/* nb_inplace_subtract */
+	0,					/* nb_inplace_multiply*/
+	0,					/* nb_inplace_divide */
+	0,					/* nb_inplace_remainder */
+	0, 					/* nb_inplace_power */
+	0,					/* nb_inplace_lshift */
+	0,					/* nb_inplace_rshift */
+	0,					/* nb_inplace_and */
+	0,					/* nb_inplace_xor */
+	0,					/* nb_inplace_or */
+	(binaryfunc)complex_int_div,		/* nb_floor_divide */
+	(binaryfunc)complex_div,		/* nb_true_divide */
+	0,					/* nb_inplace_floor_divide */
+	0,					/* nb_inplace_true_divide */
+};
+
+PyTypeObject PyComplex_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,
+	"complex",
+	sizeof(PyComplexObject),
+	0,
+	complex_dealloc,			/* tp_dealloc */
+	(printfunc)complex_print,		/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	(reprfunc)complex_repr,			/* tp_repr */
+	&complex_as_number,    			/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	(hashfunc)complex_hash, 		/* tp_hash */
+	0,					/* tp_call */
+	(reprfunc)complex_str,			/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+	complex_doc,				/* tp_doc */
+	0,					/* tp_traverse */
+	0,					/* tp_clear */
+	complex_richcompare,			/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	complex_methods,			/* tp_methods */
+	complex_members,			/* tp_members */
+	0,					/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	0,					/* tp_init */
+	PyType_GenericAlloc,			/* tp_alloc */
+	complex_new,				/* tp_new */
+	PyObject_Del,           		/* tp_free */
+};
+
+#endif

Added: vendor/Python/current/Objects/descrobject.c
===================================================================
--- vendor/Python/current/Objects/descrobject.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Objects/descrobject.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1283 @@
+/* Descriptors -- a new, flexible way to describe attributes */
+
+#include "Python.h"
+#include "structmember.h" /* Why is this not included in Python.h? */
+
+static void
+descr_dealloc(PyDescrObject *descr)
+{
+	_PyObject_GC_UNTRACK(descr);
+	Py_XDECREF(descr->d_type);
+	Py_XDECREF(descr->d_name);
+	PyObject_GC_Del(descr);
+}
+
+static char *
+descr_name(PyDescrObject *descr)
+{
+	if (descr->d_name != NULL && PyString_Check(descr->d_name))
+		return PyString_AS_STRING(descr->d_name);
+	else
+		return "?";
+}
+
+static PyObject *
+descr_repr(PyDescrObject *descr, char *format)
+{
+	return PyString_FromFormat(format, descr_name(descr),
+				   descr->d_type->tp_name);
+}
+
+static PyObject *
+method_repr(PyMethodDescrObject *descr)
+{
+	return descr_repr((PyDescrObject *)descr, 
+			  "<method '%s' of '%s' objects>");
+}
+
+static PyObject *
+member_repr(PyMemberDescrObject *descr)
+{
+	return descr_repr((PyDescrObject *)descr, 
+			  "<member '%s' of '%s' objects>");
+}
+
+static PyObject *
+getset_repr(PyGetSetDescrObject *descr)
+{
+	return descr_repr((PyDescrObject *)descr, 
+			  "<attribute '%s' of '%s' objects>");
+}
+
+static PyObject *
+wrapperdescr_repr(PyWrapperDescrObject *descr)
+{
+	return descr_repr((PyDescrObject *)descr, 
+			  "<slot wrapper '%s' of '%s' objects>");
+}
+
+static int
+descr_check(PyDescrObject *descr, PyObject *obj, PyObject **pres)
+{
+	if (obj == NULL) {
+		Py_INCREF(descr);
+		*pres = (PyObject *)descr;
+		return 1;
+	}
+	if (!PyObject_TypeCheck(obj, descr->d_type)) {
+		PyErr_Format(PyExc_TypeError,
+			     "descriptor '%s' for '%s' objects "
+			     "doesn't apply to '%s' object",
+			     descr_name((PyDescrObject *)descr),
+			     descr->d_type->tp_name,
+			     obj->ob_type->tp_name);
+		*pres = NULL;
+		return 1;
+	}
+	return 0;
+}
+
+static PyObject *
+classmethod_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type)
+{
+	/* Ensure a valid type.  Class methods ignore obj. */
+	if (type == NULL) {
+		if (obj != NULL)
+			type = (PyObject *)obj->ob_type;
+		else {
+			/* Wot - no type?! */
+			PyErr_Format(PyExc_TypeError,
+				     "descriptor '%s' for type '%s' "
+				     "needs either an object or a type",
+				     descr_name((PyDescrObject *)descr),
+				     descr->d_type->tp_name);
+			return NULL;
+		}
+	}
+	if (!PyType_Check(type)) {
+		PyErr_Format(PyExc_TypeError,
+			     "descriptor '%s' for type '%s' "
+			     "needs a type, not a '%s' as arg 2",
+			     descr_name((PyDescrObject *)descr),
+			     descr->d_type->tp_name,
+			     type->ob_type->tp_name);
+		return NULL;
+	}
+	if (!PyType_IsSubtype((PyTypeObject *)type, descr->d_type)) {
+		PyErr_Format(PyExc_TypeError,
+			     "descriptor '%s' for type '%s' "
+			     "doesn't apply to type '%s'",
+			     descr_name((PyDescrObject *)descr),
+			     descr->d_type->tp_name,
+			     ((PyTypeObject *)type)->tp_name);
+		return NULL;
+	}
+	return PyCFunction_New(descr->d_method, type);
+}
+
+static PyObject *
+method_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type)
+{
+	PyObject *res;
+
+	if (descr_check((PyDescrObject *)descr, obj, &res))
+		return res;
+	return PyCFunction_New(descr->d_method, obj);
+}
+
+static PyObject *
+member_get(PyMemberDescrObject *descr, PyObject *obj, PyObject *type)
+{
+	PyObject *res;
+
+	if (descr_check((PyDescrObject *)descr, obj, &res))
+		return res;
+	return PyMember_GetOne((char *)obj, descr->d_member);
+}
+
+static PyObject *
+getset_get(PyGetSetDescrObject *descr, PyObject *obj, PyObject *type)
+{
+	PyObject *res;
+
+	if (descr_check((PyDescrObject *)descr, obj, &res))
+		return res;
+	if (descr->d_getset->get != NULL)
+		return descr->d_getset->get(obj, descr->d_getset->closure);
+	PyErr_Format(PyExc_AttributeError,
+		     "attribute '%.300s' of '%.100s' objects is not readable",
+		     descr_name((PyDescrObject *)descr),
+		     descr->d_type->tp_name);
+	return NULL;
+}
+
+static PyObject *
+wrapperdescr_get(PyWrapperDescrObject *descr, PyObject *obj, PyObject *type)
+{
+	PyObject *res;
+
+	if (descr_check((PyDescrObject *)descr, obj, &res))
+		return res;
+	return PyWrapper_New((PyObject *)descr, obj);
+}
+
+static int
+descr_setcheck(PyDescrObject *descr, PyObject *obj, PyObject *value,
+	       int *pres)
+{
+	assert(obj != NULL);
+	if (!PyObject_IsInstance(obj, (PyObject *)(descr->d_type))) {
+		PyErr_Format(PyExc_TypeError,
+			     "descriptor '%.200s' for '%.100s' objects "
+			     "doesn't apply to '%.100s' object",
+			     descr_name(descr),
+			     descr->d_type->tp_name,
+			     obj->ob_type->tp_name);
+		*pres = -1;
+		return 1;
+	}
+	return 0;
+}
+
+static int
+member_set(PyMemberDescrObject *descr, PyObject *obj, PyObject *value)
+{
+	int res;
+
+	if (descr_setcheck((PyDescrObject *)descr, obj, value, &res))
+		return res;
+	return PyMember_SetOne((char *)obj, descr->d_member, value);
+}
+
+static int
+getset_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value)
+{
+	int res;
+
+	if (descr_setcheck((PyDescrObject *)descr, obj, value, &res))
+		return res;
+	if (descr->d_getset->set != NULL)
+		return descr->d_getset->set(obj, value,
+					    descr->d_getset->closure);
+	PyErr_Format(PyExc_AttributeError,
+		     "attribute '%.300s' of '%.100s' objects is not writable",
+		     descr_name((PyDescrObject *)descr),
+		     descr->d_type->tp_name);
+	return -1;
+}
+
+static PyObject *
+methoddescr_call(PyMethodDescrObject *descr, PyObject *args, PyObject *kwds)
+{
+	Py_ssize_t argc;
+	PyObject *self, *func, *result;
+
+	/* Make sure that the first argument is acceptable as 'self' */
+	assert(PyTuple_Check(args));
+	argc = PyTuple_GET_SIZE(args);
+	if (argc < 1) {
+		PyErr_Format(PyExc_TypeError,
+			     "descriptor '%.300s' of '%.100s' "
+			     "object needs an argument",
+			     descr_name((PyDescrObject *)descr),
+			     descr->d_type->tp_name);
+		return NULL;
+	}
+	self = PyTuple_GET_ITEM(args, 0);
+	if (!PyObject_IsInstance(self, (PyObject *)(descr->d_type))) {
+		PyErr_Format(PyExc_TypeError,
+			     "descriptor '%.200s' "
+			     "requires a '%.100s' object "
+			     "but received a '%.100s'",
+			     descr_name((PyDescrObject *)descr),
+			     descr->d_type->tp_name,
+			     self->ob_type->tp_name);
+		return NULL;
+	}
+
+	func = PyCFunction_New(descr->d_method, self);
+	if (func == NULL)
+		return NULL;
+	args = PyTuple_GetSlice(args, 1, argc);
+	if (args == NULL) {
+		Py_DECREF(func);
+		return NULL;
+	}
+	result = PyEval_CallObjectWithKeywords(func, args, kwds);
+	Py_DECREF(args);
+	Py_DECREF(func);
+	return result;
+}
+
+static PyObject *
+classmethoddescr_call(PyMethodDescrObject *descr, PyObject *args,
+		      PyObject *kwds)
+{
+	PyObject *func, *result;
+
+	func = PyCFunction_New(descr->d_method, (PyObject *)descr->d_type);
+	if (func == NULL)
+		return NULL;
+
+	result = PyEval_CallObjectWithKeywords(func, args, kwds);
+	Py_DECREF(func);
+	return result;
+}
+
+static PyObject *
+wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds)
+{
+	Py_ssize_t argc;
+	PyObject *self, *func, *result;
+
+	/* Make sure that the first argument is acceptable as 'self' */
+	assert(PyTuple_Check(args));
+	argc = PyTuple_GET_SIZE(args);
+	if (argc < 1) {
+		PyErr_Format(PyExc_TypeError,
+			     "descriptor '%.300s' of '%.100s' "
+			     "object needs an argument",
+			     descr_name((PyDescrObject *)descr),
+			     descr->d_type->tp_name);
+		return NULL;
+	}
+	self = PyTuple_GET_ITEM(args, 0);
+	if (!PyObject_IsInstance(self, (PyObject *)(descr->d_type))) {
+		PyErr_Format(PyExc_TypeError,
+			     "descriptor '%.200s' "
+			     "requires a '%.100s' object "
+			     "but received a '%.100s'",
+			     descr_name((PyDescrObject *)descr),
+			     descr->d_type->tp_name,
+			     self->ob_type->tp_name);
+		return NULL;
+	}
+
+	func = PyWrapper_New((PyObject *)descr, self);
+	if (func == NULL)
+		return NULL;
+	args = PyTuple_GetSlice(args, 1, argc);
+	if (args == NULL) {
+		Py_DECREF(func);
+		return NULL;
+	}
+	result = PyEval_CallObjectWithKeywords(func, args, kwds);
+	Py_DECREF(args);
+	Py_DECREF(func);
+	return result;
+}
+
+static PyObject *
+method_get_doc(PyMethodDescrObject *descr, void *closure)
+{
+	if (descr->d_method->ml_doc == NULL) {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+	return PyString_FromString(descr->d_method->ml_doc);
+}
+
+static PyMemberDef descr_members[] = {
+	{"__objclass__", T_OBJECT, offsetof(PyDescrObject, d_type), READONLY},
+	{"__name__", T_OBJECT, offsetof(PyDescrObject, d_name), READONLY},
+	{0}
+};
+
+static PyGetSetDef method_getset[] = {
+	{"__doc__", (getter)method_get_doc},
+	{0}
+};
+
+static PyObject *
+member_get_doc(PyMemberDescrObject *descr, void *closure)
+{
+	if (descr->d_member->doc == NULL) {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+	return PyString_FromString(descr->d_member->doc);
+}
+
+static PyGetSetDef member_getset[] = {
+	{"__doc__", (getter)member_get_doc},
+	{0}
+};
+
+static PyObject *
+getset_get_doc(PyGetSetDescrObject *descr, void *closure)
+{
+	if (descr->d_getset->doc == NULL) {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+	return PyString_FromString(descr->d_getset->doc);
+}
+
+static PyGetSetDef getset_getset[] = {
+	{"__doc__", (getter)getset_get_doc},
+	{0}
+};
+
+static PyObject *
+wrapperdescr_get_doc(PyWrapperDescrObject *descr, void *closure)
+{
+	if (descr->d_base->doc == NULL) {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+	return PyString_FromString(descr->d_base->doc);
+}
+
+static PyGetSetDef wrapperdescr_getset[] = {
+	{"__doc__", (getter)wrapperdescr_get_doc},
+	{0}
+};
+
+static int
+descr_traverse(PyObject *self, visitproc visit, void *arg)
+{
+	PyDescrObject *descr = (PyDescrObject *)self;
+	Py_VISIT(descr->d_type);
+	return 0;
+}
+
+static PyTypeObject PyMethodDescr_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,
+	"method_descriptor",
+	sizeof(PyMethodDescrObject),
+	0,
+	(destructor)descr_dealloc,		/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	(reprfunc)method_repr,			/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	(ternaryfunc)methoddescr_call,		/* tp_call */
+	0,					/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+	0,					/* tp_doc */
+	descr_traverse,				/* tp_traverse */
+	0,					/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	0,					/* tp_methods */
+	descr_members,				/* tp_members */
+	method_getset,				/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	(descrgetfunc)method_get,		/* tp_descr_get */
+	0,					/* tp_descr_set */
+};
+
+/* This is for METH_CLASS in C, not for "f = classmethod(f)" in Python! */
+static PyTypeObject PyClassMethodDescr_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,
+	"classmethod_descriptor",
+	sizeof(PyMethodDescrObject),
+	0,
+	(destructor)descr_dealloc,		/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	(reprfunc)method_repr,			/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	(ternaryfunc)classmethoddescr_call,	/* tp_call */
+	0,					/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+	0,					/* tp_doc */
+	descr_traverse,				/* tp_traverse */
+	0,					/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	0,					/* tp_methods */
+	descr_members,				/* tp_members */
+	method_getset,				/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	(descrgetfunc)classmethod_get,		/* tp_descr_get */
+	0,					/* tp_descr_set */
+};
+
+static PyTypeObject PyMemberDescr_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,
+	"member_descriptor",
+	sizeof(PyMemberDescrObject),
+	0,
+	(destructor)descr_dealloc,		/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	(reprfunc)member_repr,			/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+	0,					/* tp_doc */
+	descr_traverse,				/* tp_traverse */
+	0,					/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	0,					/* tp_methods */
+	descr_members,				/* tp_members */
+	member_getset,				/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	(descrgetfunc)member_get,		/* tp_descr_get */
+	(descrsetfunc)member_set,		/* tp_descr_set */
+};
+
+static PyTypeObject PyGetSetDescr_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,
+	"getset_descriptor",
+	sizeof(PyGetSetDescrObject),
+	0,
+	(destructor)descr_dealloc,		/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	(reprfunc)getset_repr,			/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+	0,					/* tp_doc */
+	descr_traverse,				/* tp_traverse */
+	0,					/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	0,					/* tp_methods */
+	descr_members,				/* tp_members */
+	getset_getset,				/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	(descrgetfunc)getset_get,		/* tp_descr_get */
+	(descrsetfunc)getset_set,		/* tp_descr_set */
+};
+
+PyTypeObject PyWrapperDescr_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,
+	"wrapper_descriptor",
+	sizeof(PyWrapperDescrObject),
+	0,
+	(destructor)descr_dealloc,		/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	(reprfunc)wrapperdescr_repr,		/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	(ternaryfunc)wrapperdescr_call,		/* tp_call */
+	0,					/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+	0,					/* tp_doc */
+	descr_traverse,				/* tp_traverse */
+	0,					/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	0,					/* tp_methods */
+	descr_members,				/* tp_members */
+	wrapperdescr_getset,			/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	(descrgetfunc)wrapperdescr_get,		/* tp_descr_get */
+	0,					/* tp_descr_set */
+};
+
+static PyDescrObject *
+descr_new(PyTypeObject *descrtype, PyTypeObject *type, const char *name)
+{
+	PyDescrObject *descr;
+
+	descr = (PyDescrObject *)PyType_GenericAlloc(descrtype, 0);
+	if (descr != NULL) {
+		Py_XINCREF(type);
+		descr->d_type = type;
+		descr->d_name = PyString_InternFromString(name);
+		if (descr->d_name == NULL) {
+			Py_DECREF(descr);
+			descr = NULL;
+		}
+	}
+	return descr;
+}
+
+PyObject *
+PyDescr_NewMethod(PyTypeObject *type, PyMethodDef *method)
+{
+	PyMethodDescrObject *descr;
+
+	descr = (PyMethodDescrObject *)descr_new(&PyMethodDescr_Type,
+						 type, method->ml_name);
+	if (descr != NULL)
+		descr->d_method = method;
+	return (PyObject *)descr;
+}
+
+PyObject *
+PyDescr_NewClassMethod(PyTypeObject *type, PyMethodDef *method)
+{
+	PyMethodDescrObject *descr;
+
+	descr = (PyMethodDescrObject *)descr_new(&PyClassMethodDescr_Type,
+						 type, method->ml_name);
+	if (descr != NULL)
+		descr->d_method = method;
+	return (PyObject *)descr;
+}
+
+PyObject *
+PyDescr_NewMember(PyTypeObject *type, PyMemberDef *member)
+{
+	PyMemberDescrObject *descr;
+
+	descr = (PyMemberDescrObject *)descr_new(&PyMemberDescr_Type,
+						 type, member->name);
+	if (descr != NULL)
+		descr->d_member = member;
+	return (PyObject *)descr;
+}
+
+PyObject *
+PyDescr_NewGetSet(PyTypeObject *type, PyGetSetDef *getset)
+{
+	PyGetSetDescrObject *descr;
+
+	descr = (PyGetSetDescrObject *)descr_new(&PyGetSetDescr_Type,
+						 type, getset->name);
+	if (descr != NULL)
+		descr->d_getset = getset;
+	return (PyObject *)descr;
+}
+
+PyObject *
+PyDescr_NewWrapper(PyTypeObject *type, struct wrapperbase *base, void *wrapped)
+{
+	PyWrapperDescrObject *descr;
+
+	descr = (PyWrapperDescrObject *)descr_new(&PyWrapperDescr_Type,
+						 type, base->name);
+	if (descr != NULL) {
+		descr->d_base = base;
+		descr->d_wrapped = wrapped;
+	}
+	return (PyObject *)descr;
+}
+
+
+/* --- Readonly proxy for dictionaries (actually any mapping) --- */
+
+/* This has no reason to be in this file except that adding new files is a
+   bit of a pain */
+
+typedef struct {
+	PyObject_HEAD
+	PyObject *dict;
+} proxyobject;
+
+static Py_ssize_t
+proxy_len(proxyobject *pp)
+{
+	return PyObject_Size(pp->dict);
+}
+
+static PyObject *
+proxy_getitem(proxyobject *pp, PyObject *key)
+{
+	return PyObject_GetItem(pp->dict, key);
+}
+
+static PyMappingMethods proxy_as_mapping = {
+	(lenfunc)proxy_len,			/* mp_length */
+	(binaryfunc)proxy_getitem,		/* mp_subscript */
+	0,					/* mp_ass_subscript */
+};
+
+static int
+proxy_contains(proxyobject *pp, PyObject *key)
+{
+	return PyDict_Contains(pp->dict, key);
+}
+
+static PySequenceMethods proxy_as_sequence = {
+	0,					/* sq_length */
+	0,					/* sq_concat */
+	0,					/* sq_repeat */
+	0,					/* sq_item */
+	0,					/* sq_slice */
+	0,					/* sq_ass_item */
+	0,					/* sq_ass_slice */
+	(objobjproc)proxy_contains,		/* sq_contains */
+	0,					/* sq_inplace_concat */
+	0,					/* sq_inplace_repeat */
+};
+
+static PyObject *
+proxy_has_key(proxyobject *pp, PyObject *key)
+{
+	int res = PyDict_Contains(pp->dict, key);
+	if (res < 0)
+		return NULL;
+	return PyBool_FromLong(res);
+}
+
+static PyObject *
+proxy_get(proxyobject *pp, PyObject *args)
+{
+	PyObject *key, *def = Py_None;
+
+	if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &def))
+		return NULL;
+	return PyObject_CallMethod(pp->dict, "get", "(OO)", key, def);
+}
+
+static PyObject *
+proxy_keys(proxyobject *pp)
+{
+	return PyMapping_Keys(pp->dict);
+}
+
+static PyObject *
+proxy_values(proxyobject *pp)
+{
+	return PyMapping_Values(pp->dict);
+}
+
+static PyObject *
+proxy_items(proxyobject *pp)
+{
+	return PyMapping_Items(pp->dict);
+}
+
+static PyObject *
+proxy_iterkeys(proxyobject *pp)
+{
+	return PyObject_CallMethod(pp->dict, "iterkeys", NULL);
+}
+
+static PyObject *
+proxy_itervalues(proxyobject *pp)
+{
+	return PyObject_CallMethod(pp->dict, "itervalues", NULL);
+}
+
+static PyObject *
+proxy_iteritems(proxyobject *pp)
+{
+	return PyObject_CallMethod(pp->dict, "iteritems", NULL);
+}
+static PyObject *
+proxy_copy(proxyobject *pp)
+{
+	return PyObject_CallMethod(pp->dict, "copy", NULL);
+}
+
+static PyMethodDef proxy_methods[] = {
+	{"has_key",   (PyCFunction)proxy_has_key,    METH_O,
+	 PyDoc_STR("D.has_key(k) -> True if D has a key k, else False")},
+	{"get",       (PyCFunction)proxy_get,        METH_VARARGS,
+	 PyDoc_STR("D.get(k[,d]) -> D[k] if D.has_key(k), else d."
+	 				"  d defaults to None.")},
+	{"keys",      (PyCFunction)proxy_keys,       METH_NOARGS,
+	 PyDoc_STR("D.keys() -> list of D's keys")},
+	{"values",    (PyCFunction)proxy_values,     METH_NOARGS,
+	 PyDoc_STR("D.values() -> list of D's values")},
+	{"items",     (PyCFunction)proxy_items,      METH_NOARGS,
+	 PyDoc_STR("D.items() -> list of D's (key, value) pairs, as 2-tuples")},
+	{"iterkeys",  (PyCFunction)proxy_iterkeys,   METH_NOARGS,
+	 PyDoc_STR("D.iterkeys() -> an iterator over the keys of D")},
+	{"itervalues",(PyCFunction)proxy_itervalues, METH_NOARGS,
+	 PyDoc_STR("D.itervalues() -> an iterator over the values of D")},
+	{"iteritems", (PyCFunction)proxy_iteritems,  METH_NOARGS,
+	 PyDoc_STR("D.iteritems() ->"
+	 	   " an iterator over the (key, value) items of D")},
+	{"copy",      (PyCFunction)proxy_copy,       METH_NOARGS,
+	 PyDoc_STR("D.copy() -> a shallow copy of D")},
+	{0}
+};
+
+static void
+proxy_dealloc(proxyobject *pp)
+{
+	_PyObject_GC_UNTRACK(pp);
+	Py_DECREF(pp->dict);
+	PyObject_GC_Del(pp);
+}
+
+static PyObject *
+proxy_getiter(proxyobject *pp)
+{
+	return PyObject_GetIter(pp->dict);
+}
+
+static PyObject *
+proxy_str(proxyobject *pp)
+{
+	return PyObject_Str(pp->dict);
+}
+
+static int
+proxy_traverse(PyObject *self, visitproc visit, void *arg)
+{
+	proxyobject *pp = (proxyobject *)self;
+	Py_VISIT(pp->dict);
+	return 0;
+}
+
+static int
+proxy_compare(proxyobject *v, PyObject *w)
+{
+	return PyObject_Compare(v->dict, w);
+}
+
+static PyObject *
+proxy_richcompare(proxyobject *v, PyObject *w, int op)
+{
+	return PyObject_RichCompare(v->dict, w, op);
+}
+
+static PyTypeObject proxytype = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,					/* ob_size */
+	"dictproxy",				/* tp_name */
+	sizeof(proxyobject),			/* tp_basicsize */
+	0,					/* tp_itemsize */
+	/* methods */
+	(destructor)proxy_dealloc, 		/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	(cmpfunc)proxy_compare,			/* tp_compare */
+	0,					/* tp_repr */
+	0,					/* tp_as_number */
+	&proxy_as_sequence,			/* tp_as_sequence */
+	&proxy_as_mapping,			/* tp_as_mapping */
+	0,					/* tp_hash */
+	0,					/* tp_call */
+	(reprfunc)proxy_str,			/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+ 	0,					/* tp_doc */
+	proxy_traverse,				/* tp_traverse */
+ 	0,					/* tp_clear */
+	(richcmpfunc)proxy_richcompare,		/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	(getiterfunc)proxy_getiter,		/* tp_iter */
+	0,					/* tp_iternext */
+	proxy_methods,				/* tp_methods */
+	0,					/* tp_members */
+	0,					/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+};
+
+PyObject *
+PyDictProxy_New(PyObject *dict)
+{
+	proxyobject *pp;
+
+	pp = PyObject_GC_New(proxyobject, &proxytype);
+	if (pp != NULL) {
+		Py_INCREF(dict);
+		pp->dict = dict;
+		_PyObject_GC_TRACK(pp);
+	}
+	return (PyObject *)pp;
+}
+
+
+/* --- Wrapper object for "slot" methods --- */
+
+/* This has no reason to be in this file except that adding new files is a
+   bit of a pain */
+
+typedef struct {
+	PyObject_HEAD
+	PyWrapperDescrObject *descr;
+	PyObject *self;
+} wrapperobject;
+
+static void
+wrapper_dealloc(wrapperobject *wp)
+{
+	PyObject_GC_UnTrack(wp);
+	Py_TRASHCAN_SAFE_BEGIN(wp)
+	Py_XDECREF(wp->descr);
+	Py_XDECREF(wp->self);
+	PyObject_GC_Del(wp);
+	Py_TRASHCAN_SAFE_END(wp)
+}
+
+static int
+wrapper_compare(wrapperobject *a, wrapperobject *b)
+{
+	if (a->descr == b->descr)
+		return PyObject_Compare(a->self, b->self);
+	else
+		return (a->descr < b->descr) ? -1 : 1;
+}
+
+static long
+wrapper_hash(wrapperobject *wp)
+{
+	int x, y;
+	x = _Py_HashPointer(wp->descr);
+	if (x == -1)
+		return -1;
+	y = PyObject_Hash(wp->self);
+	if (y == -1)
+		return -1;
+	x = x ^ y;
+	if (x == -1)
+		x = -2;
+	return x;
+}
+
+static PyObject *
+wrapper_repr(wrapperobject *wp)
+{
+	return PyString_FromFormat("<method-wrapper '%s' of %s object at %p>",
+				   wp->descr->d_base->name,
+				   wp->self->ob_type->tp_name,
+				   wp->self);
+}
+
+static PyMemberDef wrapper_members[] = {
+	{"__self__", T_OBJECT, offsetof(wrapperobject, self), READONLY},
+	{0}
+};
+
+static PyObject *
+wrapper_objclass(wrapperobject *wp)
+{
+	PyObject *c = (PyObject *)wp->descr->d_type;
+
+	Py_INCREF(c);
+	return c;
+}
+
+static PyObject *
+wrapper_name(wrapperobject *wp)
+{
+	char *s = wp->descr->d_base->name;
+
+	return PyString_FromString(s);
+}
+
+static PyObject *
+wrapper_doc(wrapperobject *wp)
+{
+	char *s = wp->descr->d_base->doc;
+
+	if (s == NULL) {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+	else {
+		return PyString_FromString(s);
+	}
+}
+
+static PyGetSetDef wrapper_getsets[] = {
+	{"__objclass__", (getter)wrapper_objclass},
+	{"__name__", (getter)wrapper_name},
+	{"__doc__", (getter)wrapper_doc},
+	{0}
+};
+
+static PyObject *
+wrapper_call(wrapperobject *wp, PyObject *args, PyObject *kwds)
+{
+	wrapperfunc wrapper = wp->descr->d_base->wrapper;
+	PyObject *self = wp->self;
+
+	if (wp->descr->d_base->flags & PyWrapperFlag_KEYWORDS) {
+		wrapperfunc_kwds wk = (wrapperfunc_kwds)wrapper;
+		return (*wk)(self, args, wp->descr->d_wrapped, kwds);
+	}
+
+	if (kwds != NULL && (!PyDict_Check(kwds) || PyDict_Size(kwds) != 0)) {
+		PyErr_Format(PyExc_TypeError,
+			     "wrapper %s doesn't take keyword arguments",
+			     wp->descr->d_base->name);
+		return NULL;
+	}
+	return (*wrapper)(self, args, wp->descr->d_wrapped);
+}
+
+static int
+wrapper_traverse(PyObject *self, visitproc visit, void *arg)
+{
+	wrapperobject *wp = (wrapperobject *)self;
+	Py_VISIT(wp->descr);
+	Py_VISIT(wp->self);
+	return 0;
+}
+
+static PyTypeObject wrappertype = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,					/* ob_size */
+	"method-wrapper",			/* tp_name */
+	sizeof(wrapperobject),			/* tp_basicsize */
+	0,					/* tp_itemsize */
+	/* methods */
+	(destructor)wrapper_dealloc, 		/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	(cmpfunc)wrapper_compare,		/* tp_compare */
+	(reprfunc)wrapper_repr,			/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,		       			/* tp_as_mapping */
+	(hashfunc)wrapper_hash,			/* tp_hash */
+	(ternaryfunc)wrapper_call,		/* tp_call */
+	0,					/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+ 	0,					/* tp_doc */
+	wrapper_traverse,			/* tp_traverse */
+ 	0,					/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	0,					/* tp_methods */
+	wrapper_members,			/* tp_members */
+	wrapper_getsets,			/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+};
+
+PyObject *
+PyWrapper_New(PyObject *d, PyObject *self)
+{
+	wrapperobject *wp;
+	PyWrapperDescrObject *descr;
+
+	assert(PyObject_TypeCheck(d, &PyWrapperDescr_Type));
+	descr = (PyWrapperDescrObject *)d;
+	assert(PyObject_IsInstance(self, (PyObject *)(descr->d_type)));
+
+	wp = PyObject_GC_New(wrapperobject, &wrappertype);
+	if (wp != NULL) {
+		Py_INCREF(descr);
+		wp->descr = descr;
+		Py_INCREF(self);
+		wp->self = self;
+		_PyObject_GC_TRACK(wp);
+	}
+	return (PyObject *)wp;
+}
+
+
+/* A built-in 'property' type */
+
+/*
+    class property(object):
+
+        def __init__(self, fget=None, fset=None, fdel=None, doc=None):
+            if doc is None and fget is not None and hasattr(fget, "__doc__"):
+                doc = fget.__doc__
+            self.__get = fget
+            self.__set = fset
+            self.__del = fdel
+            self.__doc__ = doc
+
+        def __get__(self, inst, type=None):
+            if inst is None:
+                return self
+            if self.__get is None:
+                raise AttributeError, "unreadable attribute"
+            return self.__get(inst)
+
+        def __set__(self, inst, value):
+            if self.__set is None:
+                raise AttributeError, "can't set attribute"
+            return self.__set(inst, value)
+
+        def __delete__(self, inst):
+            if self.__del is None:
+                raise AttributeError, "can't delete attribute"
+            return self.__del(inst)
+
+*/
+
+typedef struct {
+	PyObject_HEAD
+	PyObject *prop_get;
+	PyObject *prop_set;
+	PyObject *prop_del;
+	PyObject *prop_doc;
+} propertyobject;
+
+static PyMemberDef property_members[] = {
+	{"fget", T_OBJECT, offsetof(propertyobject, prop_get), READONLY},
+	{"fset", T_OBJECT, offsetof(propertyobject, prop_set), READONLY},
+	{"fdel", T_OBJECT, offsetof(propertyobject, prop_del), READONLY},
+	{"__doc__",  T_OBJECT, offsetof(propertyobject, prop_doc), READONLY},
+	{0}
+};
+
+
+static void
+property_dealloc(PyObject *self)
+{
+	propertyobject *gs = (propertyobject *)self;
+
+	_PyObject_GC_UNTRACK(self);
+	Py_XDECREF(gs->prop_get);
+	Py_XDECREF(gs->prop_set);
+	Py_XDECREF(gs->prop_del);
+	Py_XDECREF(gs->prop_doc);
+	self->ob_type->tp_free(self);
+}
+
+static PyObject *
+property_descr_get(PyObject *self, PyObject *obj, PyObject *type)
+{
+	propertyobject *gs = (propertyobject *)self;
+
+	if (obj == NULL || obj == Py_None) {
+		Py_INCREF(self);
+		return self;
+	}
+	if (gs->prop_get == NULL) {
+		PyErr_SetString(PyExc_AttributeError, "unreadable attribute");
+		return NULL;
+	}
+	return PyObject_CallFunction(gs->prop_get, "(O)", obj);
+}
+
+static int
+property_descr_set(PyObject *self, PyObject *obj, PyObject *value)
+{
+	propertyobject *gs = (propertyobject *)self;
+	PyObject *func, *res;
+
+	if (value == NULL)
+		func = gs->prop_del;
+	else
+		func = gs->prop_set;
+	if (func == NULL) {
+		PyErr_SetString(PyExc_AttributeError,
+				value == NULL ?
+				"can't delete attribute" :
+				"can't set attribute");
+		return -1;
+	}
+	if (value == NULL)
+		res = PyObject_CallFunction(func, "(O)", obj);
+	else
+		res = PyObject_CallFunction(func, "(OO)", obj, value);
+	if (res == NULL)
+		return -1;
+	Py_DECREF(res);
+	return 0;
+}
+
+static int
+property_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+	PyObject *get = NULL, *set = NULL, *del = NULL, *doc = NULL;
+	static char *kwlist[] = {"fget", "fset", "fdel", "doc", 0};
+	propertyobject *gs = (propertyobject *)self;
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOOO:property",
+	     				 kwlist, &get, &set, &del, &doc))
+		return -1;
+
+	if (get == Py_None)
+		get = NULL;
+	if (set == Py_None)
+		set = NULL;
+	if (del == Py_None)
+		del = NULL;
+
+	Py_XINCREF(get);
+	Py_XINCREF(set);
+	Py_XINCREF(del);
+	Py_XINCREF(doc);
+
+	/* if no docstring given and the getter has one, use that one */
+	if ((doc == NULL || doc == Py_None) && get != NULL) {
+		PyObject *get_doc = PyObject_GetAttrString(get, "__doc__");
+		if (get_doc != NULL) {
+			Py_XDECREF(doc);
+			doc = get_doc;  /* get_doc already INCREF'd by GetAttr */
+		} else {
+			PyErr_Clear();
+		}
+	}
+
+	gs->prop_get = get;
+	gs->prop_set = set;
+	gs->prop_del = del;
+	gs->prop_doc = doc;
+
+	return 0;
+}
+
+PyDoc_STRVAR(property_doc,
+"property(fget=None, fset=None, fdel=None, doc=None) -> property attribute\n"
+"\n"
+"fget is a function to be used for getting an attribute value, and likewise\n"
+"fset is a function for setting, and fdel a function for del'ing, an\n"
+"attribute.  Typical use is to define a managed attribute x:\n"
+"class C(object):\n"
+"    def getx(self): return self.__x\n"
+"    def setx(self, value): self.__x = value\n"
+"    def delx(self): del self.__x\n"
+"    x = property(getx, setx, delx, \"I'm the 'x' property.\")");
+
+static int
+property_traverse(PyObject *self, visitproc visit, void *arg)
+{
+	propertyobject *pp = (propertyobject *)self;
+	Py_VISIT(pp->prop_get);
+	Py_VISIT(pp->prop_set);
+	Py_VISIT(pp->prop_del);
+	Py_VISIT(pp->prop_doc);
+	return 0;
+}
+
+PyTypeObject PyProperty_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,					/* ob_size */
+	"property",				/* tp_name */
+	sizeof(propertyobject),			/* tp_basicsize */
+	0,					/* tp_itemsize */
+	/* methods */
+	property_dealloc,	 		/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	0,					/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,		       			/* tp_as_mapping */
+	0,					/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+		Py_TPFLAGS_BASETYPE,		/* tp_flags */
+ 	property_doc,				/* tp_doc */
+	property_traverse,			/* tp_traverse */
+ 	0,					/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	0,					/* tp_methods */
+	property_members,			/* tp_members */
+	0,					/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	property_descr_get,			/* tp_descr_get */
+	property_descr_set,			/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	property_init,				/* tp_init */
+	PyType_GenericAlloc,			/* tp_alloc */
+	PyType_GenericNew,			/* tp_new */
+	PyObject_GC_Del,               		/* tp_free */
+};

Added: vendor/Python/current/Objects/dictnotes.txt
===================================================================
--- vendor/Python/current/Objects/dictnotes.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Objects/dictnotes.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,250 @@
+NOTES ON OPTIMIZING DICTIONARIES
+================================
+
+
+Principal Use Cases for Dictionaries
+------------------------------------
+
+Passing keyword arguments
+    Typically, one read and one write for 1 to 3 elements.
+    Occurs frequently in normal python code.
+
+Class method lookup
+    Dictionaries vary in size with 8 to 16 elements being common.
+    Usually written once with many lookups.
+    When base classes are used, there are many failed lookups
+        followed by a lookup in a base class.
+
+Instance attribute lookup and Global variables
+    Dictionaries vary in size.  4 to 10 elements are common.
+    Both reads and writes are common.
+
+Builtins
+    Frequent reads.  Almost never written.
+    Size 126 interned strings (as of Py2.3b1).
+    A few keys are accessed much more frequently than others.
+
+Uniquification
+    Dictionaries of any size.  Bulk of work is in creation.
+    Repeated writes to a smaller set of keys.
+    Single read of each key.
+    Some use cases have two consecutive accesses to the same key.
+
+    * Removing duplicates from a sequence.
+        dict.fromkeys(seqn).keys()
+
+    * Counting elements in a sequence.
+        for e in seqn:
+          d[e] = d.get(e,0) + 1
+
+    * Accumulating references in a dictionary of lists:
+
+        for pagenumber, page in enumerate(pages):
+          for word in page:
+            d.setdefault(word, []).append(pagenumber)
+
+    Note, the second example is a use case characterized by a get and set
+    to the same key.  There are similar used cases with a __contains__
+    followed by a get, set, or del to the same key.  Part of the
+    justification for d.setdefault is combining the two lookups into one.
+
+Membership Testing
+    Dictionaries of any size.  Created once and then rarely changes.
+    Single write to each key.
+    Many calls to __contains__() or has_key().
+    Similar access patterns occur with replacement dictionaries
+        such as with the % formatting operator.
+
+Dynamic Mappings
+    Characterized by deletions interspersed with adds and replacements.
+    Performance benefits greatly from the re-use of dummy entries.
+
+
+Data Layout (assuming a 32-bit box with 64 bytes per cache line)
+----------------------------------------------------------------
+
+Smalldicts (8 entries) are attached to the dictobject structure
+and the whole group nearly fills two consecutive cache lines.
+
+Larger dicts use the first half of the dictobject structure (one cache
+line) and a separate, continuous block of entries (at 12 bytes each
+for a total of 5.333 entries per cache line).
+
+
+Tunable Dictionary Parameters
+-----------------------------
+
+* PyDict_MINSIZE.  Currently set to 8.
+    Must be a power of two.  New dicts have to zero-out every cell.
+    Each additional 8 consumes 1.5 cache lines.  Increasing improves
+    the sparseness of small dictionaries but costs time to read in
+    the additional cache lines if they are not already in cache.
+    That case is common when keyword arguments are passed.
+
+* Maximum dictionary load in PyDict_SetItem.  Currently set to 2/3.
+    Increasing this ratio makes dictionaries more dense resulting
+    in more collisions.  Decreasing it improves sparseness at the
+    expense of spreading entries over more cache lines and at the
+    cost of total memory consumed.
+
+    The load test occurs in highly time sensitive code.  Efforts
+    to make the test more complex (for example, varying the load
+    for different sizes) have degraded performance.
+
+* Growth rate upon hitting maximum load.  Currently set to *2.
+    Raising this to *4 results in half the number of resizes,
+    less effort to resize, better sparseness for some (but not
+    all dict sizes), and potentially doubles memory consumption
+    depending on the size of the dictionary.  Setting to *4
+    eliminates every other resize step.
+
+Tune-ups should be measured across a broad range of applications and
+use cases.  A change to any parameter will help in some situations and
+hurt in others.  The key is to find settings that help the most common
+cases and do the least damage to the less common cases.  Results will
+vary dramatically depending on the exact number of keys, whether the
+keys are all strings, whether reads or writes dominate, the exact
+hash values of the keys (some sets of values have fewer collisions than
+others).  Any one test or benchmark is likely to prove misleading.
+
+While making a dictionary more sparse reduces collisions, it impairs
+iteration and key listing.  Those methods loop over every potential
+entry.  Doubling the size of dictionary results in twice as many
+non-overlapping memory accesses for keys(), items(), values(),
+__iter__(), iterkeys(), iteritems(), itervalues(), and update().
+Also, every dictionary iterates at least twice, once for the memset()
+when it is created and once by dealloc().
+
+
+Results of Cache Locality Experiments
+-------------------------------------
+
+When an entry is retrieved from memory, 4.333 adjacent entries are also
+retrieved into a cache line.  Since accessing items in cache is *much*
+cheaper than a cache miss, an enticing idea is to probe the adjacent
+entries as a first step in collision resolution.  Unfortunately, the
+introduction of any regularity into collision searches results in more
+collisions than the current random chaining approach.
+
+Exploiting cache locality at the expense of additional collisions fails
+to payoff when the entries are already loaded in cache (the expense
+is paid with no compensating benefit).  This occurs in small dictionaries
+where the whole dictionary fits into a pair of cache lines.  It also
+occurs frequently in large dictionaries which have a common access pattern
+where some keys are accessed much more frequently than others.  The
+more popular entries *and* their collision chains tend to remain in cache.
+
+To exploit cache locality, change the collision resolution section
+in lookdict() and lookdict_string().  Set i^=1 at the top of the
+loop and move the  i = (i << 2) + i + perturb + 1 to an unrolled
+version of the loop.
+
+This optimization strategy can be leveraged in several ways:
+
+* If the dictionary is kept sparse (through the tunable parameters),
+then the occurrence of additional collisions is lessened.
+
+* If lookdict() and lookdict_string() are specialized for small dicts
+and for largedicts, then the versions for large_dicts can be given
+an alternate search strategy without increasing collisions in small dicts
+which already have the maximum benefit of cache locality.
+
+* If the use case for a dictionary is known to have a random key
+access pattern (as opposed to a more common pattern with a Zipf's law
+distribution), then there will be more benefit for large dictionaries
+because any given key is no more likely than another to already be
+in cache.
+
+* In use cases with paired accesses to the same key, the second access
+is always in cache and gets no benefit from efforts to further improve
+cache locality.
+
+Optimizing the Search of Small Dictionaries
+-------------------------------------------
+
+If lookdict() and lookdict_string() are specialized for smaller dictionaries,
+then a custom search approach can be implemented that exploits the small
+search space and cache locality.
+
+* The simplest example is a linear search of contiguous entries.  This is
+  simple to implement, guaranteed to terminate rapidly, never searches
+  the same entry twice, and precludes the need to check for dummy entries.
+
+* A more advanced example is a self-organizing search so that the most
+  frequently accessed entries get probed first.  The organization
+  adapts if the access pattern changes over time.  Treaps are ideally
+  suited for self-organization with the most common entries at the
+  top of the heap and a rapid binary search pattern.  Most probes and
+  results are all located at the top of the tree allowing them all to
+  be located in one or two cache lines.
+
+* Also, small dictionaries may be made more dense, perhaps filling all
+  eight cells to take the maximum advantage of two cache lines.
+
+
+Strategy Pattern
+----------------
+
+Consider allowing the user to set the tunable parameters or to select a
+particular search method.  Since some dictionary use cases have known
+sizes and access patterns, the user may be able to provide useful hints.
+
+1) For example, if membership testing or lookups dominate runtime and memory
+   is not at a premium, the user may benefit from setting the maximum load
+   ratio at 5% or 10% instead of the usual 66.7%.  This will sharply
+   curtail the number of collisions but will increase iteration time.
+   The builtin namespace is a prime example of a dictionary that can
+   benefit from being highly sparse.
+
+2) Dictionary creation time can be shortened in cases where the ultimate
+   size of the dictionary is known in advance.  The dictionary can be
+   pre-sized so that no resize operations are required during creation.
+   Not only does this save resizes, but the key insertion will go
+   more quickly because the first half of the keys will be inserted into
+   a more sparse environment than before.  The preconditions for this
+   strategy arise whenever a dictionary is created from a key or item
+   sequence and the number of *unique* keys is known.
+
+3) If the key space is large and the access pattern is known to be random,
+   then search strategies exploiting cache locality can be fruitful.
+   The preconditions for this strategy arise in simulations and
+   numerical analysis.
+
+4) If the keys are fixed and the access pattern strongly favors some of
+   the keys, then the entries can be stored contiguously and accessed
+   with a linear search or treap.  This exploits knowledge of the data,
+   cache locality, and a simplified search routine.  It also eliminates
+   the need to test for dummy entries on each probe.  The preconditions
+   for this strategy arise in symbol tables and in the builtin dictionary.
+
+
+Readonly Dictionaries
+---------------------
+Some dictionary use cases pass through a build stage and then move to a
+more heavily exercised lookup stage with no further changes to the
+dictionary.
+
+An idea that emerged on python-dev is to be able to convert a dictionary
+to a read-only state.  This can help prevent programming errors and also
+provide knowledge that can be exploited for lookup optimization.
+
+The dictionary can be immediately rebuilt (eliminating dummy entries),
+resized (to an appropriate level of sparseness), and the keys can be
+jostled (to minimize collisions).  The lookdict() routine can then
+eliminate the test for dummy entries (saving about 1/4 of the time
+spent in the collision resolution loop).
+
+An additional possibility is to insert links into the empty spaces
+so that dictionary iteration can proceed in len(d) steps instead of
+(mp->mask + 1) steps.  Alternatively, a separate tuple of keys can be
+kept just for iteration.
+
+
+Caching Lookups
+---------------
+The idea is to exploit key access patterns by anticipating future lookups
+based on previous lookups.
+
+The simplest incarnation is to save the most recently accessed entry.
+This gives optimal performance for use cases where every get is followed
+by a set or del to the same key.

Added: vendor/Python/current/Objects/dictobject.c
===================================================================
--- vendor/Python/current/Objects/dictobject.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Objects/dictobject.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2486 @@
+
+/* Dictionary object implementation using a hash table */
+
+/* The distribution includes a separate file, Objects/dictnotes.txt,
+   describing explorations into dictionary design and optimization.
+   It covers typical dictionary use patterns, the parameters for
+   tuning dictionaries, and several ideas for possible optimizations.
+*/
+
+#include "Python.h"
+
+typedef PyDictEntry dictentry;
+typedef PyDictObject dictobject;
+
+/* Set a key error with the specified argument, wrapping it in a
+ * tuple automatically so that tuple keys are not unpacked as the
+ * exception arguments. */
+static void
+set_key_error(PyObject *arg)
+{
+	PyObject *tup;
+	tup = PyTuple_Pack(1, arg);
+	if (!tup)
+		return; /* caller will expect error to be set anyway */
+	PyErr_SetObject(PyExc_KeyError, tup);
+	Py_DECREF(tup);
+}
+
+/* Define this out if you don't want conversion statistics on exit. */
+#undef SHOW_CONVERSION_COUNTS
+
+/* See large comment block below.  This must be >= 1. */
+#define PERTURB_SHIFT 5
+
+/*
+Major subtleties ahead:  Most hash schemes depend on having a "good" hash
+function, in the sense of simulating randomness.  Python doesn't:  its most
+important hash functions (for strings and ints) are very regular in common
+cases:
+
+>>> map(hash, (0, 1, 2, 3))
+[0, 1, 2, 3]
+>>> map(hash, ("namea", "nameb", "namec", "named"))
+[-1658398457, -1658398460, -1658398459, -1658398462]
+>>>
+
+This isn't necessarily bad!  To the contrary, in a table of size 2**i, taking
+the low-order i bits as the initial table index is extremely fast, and there
+are no collisions at all for dicts indexed by a contiguous range of ints.
+The same is approximately true when keys are "consecutive" strings.  So this
+gives better-than-random behavior in common cases, and that's very desirable.
+
+OTOH, when collisions occur, the tendency to fill contiguous slices of the
+hash table makes a good collision resolution strategy crucial.  Taking only
+the last i bits of the hash code is also vulnerable:  for example, consider
+[i << 16 for i in range(20000)] as a set of keys.  Since ints are their own
+hash codes, and this fits in a dict of size 2**15, the last 15 bits of every
+hash code are all 0:  they *all* map to the same table index.
+
+But catering to unusual cases should not slow the usual ones, so we just take
+the last i bits anyway.  It's up to collision resolution to do the rest.  If
+we *usually* find the key we're looking for on the first try (and, it turns
+out, we usually do -- the table load factor is kept under 2/3, so the odds
+are solidly in our favor), then it makes best sense to keep the initial index
+computation dirt cheap.
+
+The first half of collision resolution is to visit table indices via this
+recurrence:
+
+    j = ((5*j) + 1) mod 2**i
+
+For any initial j in range(2**i), repeating that 2**i times generates each
+int in range(2**i) exactly once (see any text on random-number generation for
+proof).  By itself, this doesn't help much:  like linear probing (setting
+j += 1, or j -= 1, on each loop trip), it scans the table entries in a fixed
+order.  This would be bad, except that's not the only thing we do, and it's
+actually *good* in the common cases where hash keys are consecutive.  In an
+example that's really too small to make this entirely clear, for a table of
+size 2**3 the order of indices is:
+
+    0 -> 1 -> 6 -> 7 -> 4 -> 5 -> 2 -> 3 -> 0 [and here it's repeating]
+
+If two things come in at index 5, the first place we look after is index 2,
+not 6, so if another comes in at index 6 the collision at 5 didn't hurt it.
+Linear probing is deadly in this case because there the fixed probe order
+is the *same* as the order consecutive keys are likely to arrive.  But it's
+extremely unlikely hash codes will follow a 5*j+1 recurrence by accident,
+and certain that consecutive hash codes do not.
+
+The other half of the strategy is to get the other bits of the hash code
+into play.  This is done by initializing a (unsigned) vrbl "perturb" to the
+full hash code, and changing the recurrence to:
+
+    j = (5*j) + 1 + perturb;
+    perturb >>= PERTURB_SHIFT;
+    use j % 2**i as the next table index;
+
+Now the probe sequence depends (eventually) on every bit in the hash code,
+and the pseudo-scrambling property of recurring on 5*j+1 is more valuable,
+because it quickly magnifies small differences in the bits that didn't affect
+the initial index.  Note that because perturb is unsigned, if the recurrence
+is executed often enough perturb eventually becomes and remains 0.  At that
+point (very rarely reached) the recurrence is on (just) 5*j+1 again, and
+that's certain to find an empty slot eventually (since it generates every int
+in range(2**i), and we make sure there's always at least one empty slot).
+
+Selecting a good value for PERTURB_SHIFT is a balancing act.  You want it
+small so that the high bits of the hash code continue to affect the probe
+sequence across iterations; but you want it large so that in really bad cases
+the high-order hash bits have an effect on early iterations.  5 was "the
+best" in minimizing total collisions across experiments Tim Peters ran (on
+both normal and pathological cases), but 4 and 6 weren't significantly worse.
+
+Historical:  Reimer Behrends contributed the idea of using a polynomial-based
+approach, using repeated multiplication by x in GF(2**n) where an irreducible
+polynomial for each table size was chosen such that x was a primitive root.
+Christian Tismer later extended that to use division by x instead, as an
+efficient way to get the high bits of the hash code into play.  This scheme
+also gave excellent collision statistics, but was more expensive:  two
+if-tests were required inside the loop; computing "the next" index took about
+the same number of operations but without as much potential parallelism
+(e.g., computing 5*j can go on at the same time as computing 1+perturb in the
+above, and then shifting perturb can be done while the table index is being
+masked); and the dictobject struct required a member to hold the table's
+polynomial.  In Tim's experiments the current scheme ran faster, produced
+equally good collision statistics, needed less code & used less memory.
+
+Theoretical Python 2.5 headache:  hash codes are only C "long", but
+sizeof(Py_ssize_t) > sizeof(long) may be possible.  In that case, and if a
+dict is genuinely huge, then only the slots directly reachable via indexing
+by a C long can be the first slot in a probe sequence.  The probe sequence
+will still eventually reach every slot in the table, but the collision rate
+on initial probes may be much higher than this scheme was designed for.
+Getting a hash code as fat as Py_ssize_t is the only real cure.  But in
+practice, this probably won't make a lick of difference for many years (at
+which point everyone will have terabytes of RAM on 64-bit boxes).
+*/
+
+/* Object used as dummy key to fill deleted entries */
+static PyObject *dummy = NULL; /* Initialized by first call to newdictobject() */
+
+#ifdef Py_REF_DEBUG
+PyObject *
+_PyDict_Dummy(void)
+{
+	return dummy;
+}
+#endif
+
+/* forward declarations */
+static dictentry *
+lookdict_string(dictobject *mp, PyObject *key, long hash);
+
+#ifdef SHOW_CONVERSION_COUNTS
+static long created = 0L;
+static long converted = 0L;
+
+static void
+show_counts(void)
+{
+	fprintf(stderr, "created %ld string dicts\n", created);
+	fprintf(stderr, "converted %ld to normal dicts\n", converted);
+	fprintf(stderr, "%.2f%% conversion rate\n", (100.0*converted)/created);
+}
+#endif
+
+/* Initialization macros.
+   There are two ways to create a dict:  PyDict_New() is the main C API
+   function, and the tp_new slot maps to dict_new().  In the latter case we
+   can save a little time over what PyDict_New does because it's guaranteed
+   that the PyDictObject struct is already zeroed out.
+   Everyone except dict_new() should use EMPTY_TO_MINSIZE (unless they have
+   an excellent reason not to).
+*/
+
+#define INIT_NONZERO_DICT_SLOTS(mp) do {				\
+	(mp)->ma_table = (mp)->ma_smalltable;				\
+	(mp)->ma_mask = PyDict_MINSIZE - 1;				\
+    } while(0)
+
+#define EMPTY_TO_MINSIZE(mp) do {					\
+	memset((mp)->ma_smalltable, 0, sizeof((mp)->ma_smalltable));	\
+	(mp)->ma_used = (mp)->ma_fill = 0;				\
+	INIT_NONZERO_DICT_SLOTS(mp);					\
+    } while(0)
+
+/* Dictionary reuse scheme to save calls to malloc, free, and memset */
+#define MAXFREEDICTS 80
+static PyDictObject *free_dicts[MAXFREEDICTS];
+static int num_free_dicts = 0;
+
+PyObject *
+PyDict_New(void)
+{
+	register dictobject *mp;
+	if (dummy == NULL) { /* Auto-initialize dummy */
+		dummy = PyString_FromString("<dummy key>");
+		if (dummy == NULL)
+			return NULL;
+#ifdef SHOW_CONVERSION_COUNTS
+		Py_AtExit(show_counts);
+#endif
+	}
+	if (num_free_dicts) {
+		mp = free_dicts[--num_free_dicts];
+		assert (mp != NULL);
+		assert (mp->ob_type == &PyDict_Type);
+		_Py_NewReference((PyObject *)mp);
+		if (mp->ma_fill) {
+			EMPTY_TO_MINSIZE(mp);
+		}
+		assert (mp->ma_used == 0);
+		assert (mp->ma_table == mp->ma_smalltable);
+		assert (mp->ma_mask == PyDict_MINSIZE - 1);
+	} else {
+		mp = PyObject_GC_New(dictobject, &PyDict_Type);
+		if (mp == NULL)
+			return NULL;
+		EMPTY_TO_MINSIZE(mp);
+	}
+	mp->ma_lookup = lookdict_string;
+#ifdef SHOW_CONVERSION_COUNTS
+	++created;
+#endif
+	_PyObject_GC_TRACK(mp);
+	return (PyObject *)mp;
+}
+
+/*
+The basic lookup function used by all operations.
+This is based on Algorithm D from Knuth Vol. 3, Sec. 6.4.
+Open addressing is preferred over chaining since the link overhead for
+chaining would be substantial (100% with typical malloc overhead).
+
+The initial probe index is computed as hash mod the table size. Subsequent
+probe indices are computed as explained earlier.
+
+All arithmetic on hash should ignore overflow.
+
+(The details in this version are due to Tim Peters, building on many past
+contributions by Reimer Behrends, Jyrki Alakuijala, Vladimir Marangozov and
+Christian Tismer).
+
+lookdict() is general-purpose, and may return NULL if (and only if) a
+comparison raises an exception (this was new in Python 2.5).
+lookdict_string() below is specialized to string keys, comparison of which can
+never raise an exception; that function can never return NULL.  For both, when
+the key isn't found a dictentry* is returned for which the me_value field is
+NULL; this is the slot in the dict at which the key would have been found, and
+the caller can (if it wishes) add the <key, value> pair to the returned
+dictentry*.
+*/
+static dictentry *
+lookdict(dictobject *mp, PyObject *key, register long hash)
+{
+	register size_t i;
+	register size_t perturb;
+	register dictentry *freeslot;
+	register size_t mask = (size_t)mp->ma_mask;
+	dictentry *ep0 = mp->ma_table;
+	register dictentry *ep;
+	register int cmp;
+	PyObject *startkey;
+
+	i = (size_t)hash & mask;
+	ep = &ep0[i];
+	if (ep->me_key == NULL || ep->me_key == key)
+		return ep;
+
+	if (ep->me_key == dummy)
+		freeslot = ep;
+	else {
+		if (ep->me_hash == hash) {
+			startkey = ep->me_key;
+			cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
+			if (cmp < 0)
+				return NULL;
+			if (ep0 == mp->ma_table && ep->me_key == startkey) {
+				if (cmp > 0)
+					return ep;
+			}
+			else {
+				/* The compare did major nasty stuff to the
+				 * dict:  start over.
+				 * XXX A clever adversary could prevent this
+				 * XXX from terminating.
+ 				 */
+ 				return lookdict(mp, key, hash);
+ 			}
+		}
+		freeslot = NULL;
+	}
+
+	/* In the loop, me_key == dummy is by far (factor of 100s) the
+	   least likely outcome, so test for that last. */
+	for (perturb = hash; ; perturb >>= PERTURB_SHIFT) {
+		i = (i << 2) + i + perturb + 1;
+		ep = &ep0[i & mask];
+		if (ep->me_key == NULL)
+			return freeslot == NULL ? ep : freeslot;
+		if (ep->me_key == key)
+			return ep;
+		if (ep->me_hash == hash && ep->me_key != dummy) {
+			startkey = ep->me_key;
+			cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
+			if (cmp < 0)
+				return NULL;
+			if (ep0 == mp->ma_table && ep->me_key == startkey) {
+				if (cmp > 0)
+					return ep;
+			}
+			else {
+				/* The compare did major nasty stuff to the
+				 * dict:  start over.
+				 * XXX A clever adversary could prevent this
+				 * XXX from terminating.
+ 				 */
+ 				return lookdict(mp, key, hash);
+ 			}
+		}
+		else if (ep->me_key == dummy && freeslot == NULL)
+			freeslot = ep;
+	}
+	assert(0);	/* NOT REACHED */
+	return 0;
+}
+
+/*
+ * Hacked up version of lookdict which can assume keys are always strings;
+ * this assumption allows testing for errors during PyObject_RichCompareBool()
+ * to be dropped; string-string comparisons never raise exceptions.  This also
+ * means we don't need to go through PyObject_RichCompareBool(); we can always
+ * use _PyString_Eq() directly.
+ *
+ * This is valuable because dicts with only string keys are very common.
+ */
+static dictentry *
+lookdict_string(dictobject *mp, PyObject *key, register long hash)
+{
+	register size_t i;
+	register size_t perturb;
+	register dictentry *freeslot;
+	register size_t mask = (size_t)mp->ma_mask;
+	dictentry *ep0 = mp->ma_table;
+	register dictentry *ep;
+
+	/* Make sure this function doesn't have to handle non-string keys,
+	   including subclasses of str; e.g., one reason to subclass
+	   strings is to override __eq__, and for speed we don't cater to
+	   that here. */
+	if (!PyString_CheckExact(key)) {
+#ifdef SHOW_CONVERSION_COUNTS
+		++converted;
+#endif
+		mp->ma_lookup = lookdict;
+		return lookdict(mp, key, hash);
+	}
+	i = hash & mask;
+	ep = &ep0[i];
+	if (ep->me_key == NULL || ep->me_key == key)
+		return ep;
+	if (ep->me_key == dummy)
+		freeslot = ep;
+	else {
+		if (ep->me_hash == hash && _PyString_Eq(ep->me_key, key))
+			return ep;
+		freeslot = NULL;
+	}
+
+	/* In the loop, me_key == dummy is by far (factor of 100s) the
+	   least likely outcome, so test for that last. */
+	for (perturb = hash; ; perturb >>= PERTURB_SHIFT) {
+		i = (i << 2) + i + perturb + 1;
+		ep = &ep0[i & mask];
+		if (ep->me_key == NULL)
+			return freeslot == NULL ? ep : freeslot;
+		if (ep->me_key == key
+		    || (ep->me_hash == hash
+		        && ep->me_key != dummy
+			&& _PyString_Eq(ep->me_key, key)))
+			return ep;
+		if (ep->me_key == dummy && freeslot == NULL)
+			freeslot = ep;
+	}
+	assert(0);	/* NOT REACHED */
+	return 0;
+}
+
+/*
+Internal routine to insert a new item into the table.
+Used both by the internal resize routine and by the public insert routine.
+Eats a reference to key and one to value.
+Returns -1 if an error occurred, or 0 on success.
+*/
+static int
+insertdict(register dictobject *mp, PyObject *key, long hash, PyObject *value)
+{
+	PyObject *old_value;
+	register dictentry *ep;
+	typedef PyDictEntry *(*lookupfunc)(PyDictObject *, PyObject *, long);
+
+	assert(mp->ma_lookup != NULL);
+	ep = mp->ma_lookup(mp, key, hash);
+	if (ep == NULL) {
+		Py_DECREF(key);
+		Py_DECREF(value);
+		return -1;
+	}
+	if (ep->me_value != NULL) {
+		old_value = ep->me_value;
+		ep->me_value = value;
+		Py_DECREF(old_value); /* which **CAN** re-enter */
+		Py_DECREF(key);
+	}
+	else {
+		if (ep->me_key == NULL)
+			mp->ma_fill++;
+		else {
+			assert(ep->me_key == dummy);
+			Py_DECREF(dummy);
+		}
+		ep->me_key = key;
+		ep->me_hash = (Py_ssize_t)hash;
+		ep->me_value = value;
+		mp->ma_used++;
+	}
+	return 0;
+}
+
+/*
+Internal routine used by dictresize() to insert an item which is
+known to be absent from the dict.  This routine also assumes that
+the dict contains no deleted entries.  Besides the performance benefit,
+using insertdict() in dictresize() is dangerous (SF bug #1456209).
+Note that no refcounts are changed by this routine; if needed, the caller
+is responsible for incref'ing `key` and `value`.
+*/
+static void
+insertdict_clean(register dictobject *mp, PyObject *key, long hash,
+		 PyObject *value)
+{
+	register size_t i;
+	register size_t perturb;
+	register size_t mask = (size_t)mp->ma_mask;
+	dictentry *ep0 = mp->ma_table;
+	register dictentry *ep;
+
+	i = hash & mask;
+	ep = &ep0[i];
+	for (perturb = hash; ep->me_key != NULL; perturb >>= PERTURB_SHIFT) {
+		i = (i << 2) + i + perturb + 1;
+		ep = &ep0[i & mask];
+	}
+	assert(ep->me_value == NULL);
+	mp->ma_fill++;
+	ep->me_key = key;
+	ep->me_hash = (Py_ssize_t)hash;
+	ep->me_value = value;
+	mp->ma_used++;
+}
+
+/*
+Restructure the table by allocating a new table and reinserting all
+items again.  When entries have been deleted, the new table may
+actually be smaller than the old one.
+*/
+static int
+dictresize(dictobject *mp, Py_ssize_t minused)
+{
+	Py_ssize_t newsize;
+	dictentry *oldtable, *newtable, *ep;
+	Py_ssize_t i;
+	int is_oldtable_malloced;
+	dictentry small_copy[PyDict_MINSIZE];
+
+	assert(minused >= 0);
+
+	/* Find the smallest table size > minused. */
+	for (newsize = PyDict_MINSIZE;
+	     newsize <= minused && newsize > 0;
+	     newsize <<= 1)
+		;
+	if (newsize <= 0) {
+		PyErr_NoMemory();
+		return -1;
+	}
+
+	/* Get space for a new table. */
+	oldtable = mp->ma_table;
+	assert(oldtable != NULL);
+	is_oldtable_malloced = oldtable != mp->ma_smalltable;
+
+	if (newsize == PyDict_MINSIZE) {
+		/* A large table is shrinking, or we can't get any smaller. */
+		newtable = mp->ma_smalltable;
+		if (newtable == oldtable) {
+			if (mp->ma_fill == mp->ma_used) {
+				/* No dummies, so no point doing anything. */
+				return 0;
+			}
+			/* We're not going to resize it, but rebuild the
+			   table anyway to purge old dummy entries.
+			   Subtle:  This is *necessary* if fill==size,
+			   as lookdict needs at least one virgin slot to
+			   terminate failing searches.  If fill < size, it's
+			   merely desirable, as dummies slow searches. */
+			assert(mp->ma_fill > mp->ma_used);
+			memcpy(small_copy, oldtable, sizeof(small_copy));
+			oldtable = small_copy;
+		}
+	}
+	else {
+		newtable = PyMem_NEW(dictentry, newsize);
+		if (newtable == NULL) {
+			PyErr_NoMemory();
+			return -1;
+		}
+	}
+
+	/* Make the dict empty, using the new table. */
+	assert(newtable != oldtable);
+	mp->ma_table = newtable;
+	mp->ma_mask = newsize - 1;
+	memset(newtable, 0, sizeof(dictentry) * newsize);
+	mp->ma_used = 0;
+	i = mp->ma_fill;
+	mp->ma_fill = 0;
+
+	/* Copy the data over; this is refcount-neutral for active entries;
+	   dummy entries aren't copied over, of course */
+	for (ep = oldtable; i > 0; ep++) {
+		if (ep->me_value != NULL) {	/* active entry */
+			--i;
+			insertdict_clean(mp, ep->me_key, (long)ep->me_hash,
+					 ep->me_value);
+		}
+		else if (ep->me_key != NULL) {	/* dummy entry */
+			--i;
+			assert(ep->me_key == dummy);
+			Py_DECREF(ep->me_key);
+		}
+		/* else key == value == NULL:  nothing to do */
+	}
+
+	if (is_oldtable_malloced)
+		PyMem_DEL(oldtable);
+	return 0;
+}
+
+/* Note that, for historical reasons, PyDict_GetItem() suppresses all errors
+ * that may occur (originally dicts supported only string keys, and exceptions
+ * weren't possible).  So, while the original intent was that a NULL return
+ * meant the key wasn't present, in reality it can mean that, or that an error
+ * (suppressed) occurred while computing the key's hash, or that some error
+ * (suppressed) occurred when comparing keys in the dict's internal probe
+ * sequence.  A nasty example of the latter is when a Python-coded comparison
+ * function hits a stack-depth error, which can cause this to return NULL
+ * even if the key is present.
+ */
+PyObject *
+PyDict_GetItem(PyObject *op, PyObject *key)
+{
+	long hash;
+	dictobject *mp = (dictobject *)op;
+	dictentry *ep;
+	PyThreadState *tstate;
+	if (!PyDict_Check(op))
+		return NULL;
+	if (!PyString_CheckExact(key) ||
+	    (hash = ((PyStringObject *) key)->ob_shash) == -1)
+	{
+		hash = PyObject_Hash(key);
+		if (hash == -1) {
+			PyErr_Clear();
+			return NULL;
+		}
+	}
+
+	/* We can arrive here with a NULL tstate during initialization:
+	   try running "python -Wi" for an example related to string
+	   interning.  Let's just hope that no exception occurs then... */
+	tstate = _PyThreadState_Current;
+	if (tstate != NULL && tstate->curexc_type != NULL) {
+		/* preserve the existing exception */
+		PyObject *err_type, *err_value, *err_tb;
+		PyErr_Fetch(&err_type, &err_value, &err_tb);
+		ep = (mp->ma_lookup)(mp, key, hash);
+		/* ignore errors */
+		PyErr_Restore(err_type, err_value, err_tb);
+		if (ep == NULL)
+			return NULL;
+	}
+	else {
+		ep = (mp->ma_lookup)(mp, key, hash);
+		if (ep == NULL) {
+			PyErr_Clear();
+			return NULL;
+		}
+	}
+	return ep->me_value;
+}
+
+/* CAUTION: PyDict_SetItem() must guarantee that it won't resize the
+ * dictionary if it's merely replacing the value for an existing key.
+ * This means that it's safe to loop over a dictionary with PyDict_Next()
+ * and occasionally replace a value -- but you can't insert new keys or
+ * remove them.
+ */
+int
+PyDict_SetItem(register PyObject *op, PyObject *key, PyObject *value)
+{
+	register dictobject *mp;
+	register long hash;
+	register Py_ssize_t n_used;
+
+	if (!PyDict_Check(op)) {
+		PyErr_BadInternalCall();
+		return -1;
+	}
+	assert(key);
+	assert(value);
+	mp = (dictobject *)op;
+	if (PyString_CheckExact(key)) {
+		hash = ((PyStringObject *)key)->ob_shash;
+		if (hash == -1)
+			hash = PyObject_Hash(key);
+	}
+	else {
+		hash = PyObject_Hash(key);
+		if (hash == -1)
+			return -1;
+	}
+	assert(mp->ma_fill <= mp->ma_mask);  /* at least one empty slot */
+	n_used = mp->ma_used;
+	Py_INCREF(value);
+	Py_INCREF(key);
+	if (insertdict(mp, key, hash, value) != 0)
+		return -1;
+	/* If we added a key, we can safely resize.  Otherwise just return!
+	 * If fill >= 2/3 size, adjust size.  Normally, this doubles or
+	 * quaduples the size, but it's also possible for the dict to shrink
+	 * (if ma_fill is much larger than ma_used, meaning a lot of dict
+	 * keys have been * deleted).
+	 *
+	 * Quadrupling the size improves average dictionary sparseness
+	 * (reducing collisions) at the cost of some memory and iteration
+	 * speed (which loops over every possible entry).  It also halves
+	 * the number of expensive resize operations in a growing dictionary.
+	 *
+	 * Very large dictionaries (over 50K items) use doubling instead.
+	 * This may help applications with severe memory constraints.
+	 */
+	if (!(mp->ma_used > n_used && mp->ma_fill*3 >= (mp->ma_mask+1)*2))
+		return 0;
+	return dictresize(mp, (mp->ma_used > 50000 ? 2 : 4) * mp->ma_used);
+}
+
+int
+PyDict_DelItem(PyObject *op, PyObject *key)
+{
+	register dictobject *mp;
+	register long hash;
+	register dictentry *ep;
+	PyObject *old_value, *old_key;
+
+	if (!PyDict_Check(op)) {
+		PyErr_BadInternalCall();
+		return -1;
+	}
+	assert(key);
+	if (!PyString_CheckExact(key) ||
+	    (hash = ((PyStringObject *) key)->ob_shash) == -1) {
+		hash = PyObject_Hash(key);
+		if (hash == -1)
+			return -1;
+	}
+	mp = (dictobject *)op;
+	ep = (mp->ma_lookup)(mp, key, hash);
+	if (ep == NULL)
+		return -1;
+	if (ep->me_value == NULL) {
+		set_key_error(key);
+		return -1;
+	}
+	old_key = ep->me_key;
+	Py_INCREF(dummy);
+	ep->me_key = dummy;
+	old_value = ep->me_value;
+	ep->me_value = NULL;
+	mp->ma_used--;
+	Py_DECREF(old_value);
+	Py_DECREF(old_key);
+	return 0;
+}
+
+void
+PyDict_Clear(PyObject *op)
+{
+	dictobject *mp;
+	dictentry *ep, *table;
+	int table_is_malloced;
+	Py_ssize_t fill;
+	dictentry small_copy[PyDict_MINSIZE];
+#ifdef Py_DEBUG
+	Py_ssize_t i, n;
+#endif
+
+	if (!PyDict_Check(op))
+		return;
+	mp = (dictobject *)op;
+#ifdef Py_DEBUG
+	n = mp->ma_mask + 1;
+	i = 0;
+#endif
+
+	table = mp->ma_table;
+	assert(table != NULL);
+	table_is_malloced = table != mp->ma_smalltable;
+
+	/* This is delicate.  During the process of clearing the dict,
+	 * decrefs can cause the dict to mutate.  To avoid fatal confusion
+	 * (voice of experience), we have to make the dict empty before
+	 * clearing the slots, and never refer to anything via mp->xxx while
+	 * clearing.
+	 */
+	fill = mp->ma_fill;
+	if (table_is_malloced)
+		EMPTY_TO_MINSIZE(mp);
+
+	else if (fill > 0) {
+		/* It's a small table with something that needs to be cleared.
+		 * Afraid the only safe way is to copy the dict entries into
+		 * another small table first.
+		 */
+		memcpy(small_copy, table, sizeof(small_copy));
+		table = small_copy;
+		EMPTY_TO_MINSIZE(mp);
+	}
+	/* else it's a small table that's already empty */
+
+	/* Now we can finally clear things.  If C had refcounts, we could
+	 * assert that the refcount on table is 1 now, i.e. that this function
+	 * has unique access to it, so decref side-effects can't alter it.
+	 */
+	for (ep = table; fill > 0; ++ep) {
+#ifdef Py_DEBUG
+		assert(i < n);
+		++i;
+#endif
+		if (ep->me_key) {
+			--fill;
+			Py_DECREF(ep->me_key);
+			Py_XDECREF(ep->me_value);
+		}
+#ifdef Py_DEBUG
+		else
+			assert(ep->me_value == NULL);
+#endif
+	}
+
+	if (table_is_malloced)
+		PyMem_DEL(table);
+}
+
+/*
+ * Iterate over a dict.  Use like so:
+ *
+ *     Py_ssize_t i;
+ *     PyObject *key, *value;
+ *     i = 0;   # important!  i should not otherwise be changed by you
+ *     while (PyDict_Next(yourdict, &i, &key, &value)) {
+ *              Refer to borrowed references in key and value.
+ *     }
+ *
+ * CAUTION:  In general, it isn't safe to use PyDict_Next in a loop that
+ * mutates the dict.  One exception:  it is safe if the loop merely changes
+ * the values associated with the keys (but doesn't insert new keys or
+ * delete keys), via PyDict_SetItem().
+ */
+int
+PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue)
+{
+	register Py_ssize_t i;
+	register Py_ssize_t mask;
+	register dictentry *ep;
+
+	if (!PyDict_Check(op))
+		return 0;
+	i = *ppos;
+	if (i < 0)
+		return 0;
+	ep = ((dictobject *)op)->ma_table;
+	mask = ((dictobject *)op)->ma_mask;
+	while (i <= mask && ep[i].me_value == NULL)
+		i++;
+	*ppos = i+1;
+	if (i > mask)
+		return 0;
+	if (pkey)
+		*pkey = ep[i].me_key;
+	if (pvalue)
+		*pvalue = ep[i].me_value;
+	return 1;
+}
+
+/* Internal version of PyDict_Next that returns a hash value in addition to the key and value.*/
+int
+_PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue, long *phash)
+{
+	register Py_ssize_t i;
+	register Py_ssize_t mask;
+	register dictentry *ep;
+
+	if (!PyDict_Check(op))
+		return 0;
+	i = *ppos;
+	if (i < 0)
+		return 0;
+	ep = ((dictobject *)op)->ma_table;
+	mask = ((dictobject *)op)->ma_mask;
+	while (i <= mask && ep[i].me_value == NULL)
+		i++;
+	*ppos = i+1;
+	if (i > mask)
+		return 0;
+        *phash = (long)(ep[i].me_hash);
+	if (pkey)
+		*pkey = ep[i].me_key;
+	if (pvalue)
+		*pvalue = ep[i].me_value;
+	return 1;
+}
+
+/* Methods */
+
+static void
+dict_dealloc(register dictobject *mp)
+{
+	register dictentry *ep;
+	Py_ssize_t fill = mp->ma_fill;
+ 	PyObject_GC_UnTrack(mp);
+	Py_TRASHCAN_SAFE_BEGIN(mp)
+	for (ep = mp->ma_table; fill > 0; ep++) {
+		if (ep->me_key) {
+			--fill;
+			Py_DECREF(ep->me_key);
+			Py_XDECREF(ep->me_value);
+		}
+	}
+	if (mp->ma_table != mp->ma_smalltable)
+		PyMem_DEL(mp->ma_table);
+	if (num_free_dicts < MAXFREEDICTS && mp->ob_type == &PyDict_Type)
+		free_dicts[num_free_dicts++] = mp;
+	else
+		mp->ob_type->tp_free((PyObject *)mp);
+	Py_TRASHCAN_SAFE_END(mp)
+}
+
+static int
+dict_print(register dictobject *mp, register FILE *fp, register int flags)
+{
+	register Py_ssize_t i;
+	register Py_ssize_t any;
+	int status;
+
+	status = Py_ReprEnter((PyObject*)mp);
+	if (status != 0) {
+		if (status < 0)
+			return status;
+		fprintf(fp, "{...}");
+		return 0;
+	}
+
+	fprintf(fp, "{");
+	any = 0;
+	for (i = 0; i <= mp->ma_mask; i++) {
+		dictentry *ep = mp->ma_table + i;
+		PyObject *pvalue = ep->me_value;
+		if (pvalue != NULL) {
+			/* Prevent PyObject_Repr from deleting value during
+			   key format */
+			Py_INCREF(pvalue);
+			if (any++ > 0)
+				fprintf(fp, ", ");
+			if (PyObject_Print((PyObject *)ep->me_key, fp, 0)!=0) {
+				Py_DECREF(pvalue);
+				Py_ReprLeave((PyObject*)mp);
+				return -1;
+			}
+			fprintf(fp, ": ");
+			if (PyObject_Print(pvalue, fp, 0) != 0) {
+				Py_DECREF(pvalue);
+				Py_ReprLeave((PyObject*)mp);
+				return -1;
+			}
+			Py_DECREF(pvalue);
+		}
+	}
+	fprintf(fp, "}");
+	Py_ReprLeave((PyObject*)mp);
+	return 0;
+}
+
+static PyObject *
+dict_repr(dictobject *mp)
+{
+	Py_ssize_t i;
+	PyObject *s, *temp, *colon = NULL;
+	PyObject *pieces = NULL, *result = NULL;
+	PyObject *key, *value;
+
+	i = Py_ReprEnter((PyObject *)mp);
+	if (i != 0) {
+		return i > 0 ? PyString_FromString("{...}") : NULL;
+	}
+
+	if (mp->ma_used == 0) {
+		result = PyString_FromString("{}");
+		goto Done;
+	}
+
+	pieces = PyList_New(0);
+	if (pieces == NULL)
+		goto Done;
+
+	colon = PyString_FromString(": ");
+	if (colon == NULL)
+		goto Done;
+
+	/* Do repr() on each key+value pair, and insert ": " between them.
+	   Note that repr may mutate the dict. */
+	i = 0;
+	while (PyDict_Next((PyObject *)mp, &i, &key, &value)) {
+		int status;
+		/* Prevent repr from deleting value during key format. */
+		Py_INCREF(value);
+		s = PyObject_Repr(key);
+		PyString_Concat(&s, colon);
+		PyString_ConcatAndDel(&s, PyObject_Repr(value));
+		Py_DECREF(value);
+		if (s == NULL)
+			goto Done;
+		status = PyList_Append(pieces, s);
+		Py_DECREF(s);  /* append created a new ref */
+		if (status < 0)
+			goto Done;
+	}
+
+	/* Add "{}" decorations to the first and last items. */
+	assert(PyList_GET_SIZE(pieces) > 0);
+	s = PyString_FromString("{");
+	if (s == NULL)
+		goto Done;
+	temp = PyList_GET_ITEM(pieces, 0);
+	PyString_ConcatAndDel(&s, temp);
+	PyList_SET_ITEM(pieces, 0, s);
+	if (s == NULL)
+		goto Done;
+
+	s = PyString_FromString("}");
+	if (s == NULL)
+		goto Done;
+	temp = PyList_GET_ITEM(pieces, PyList_GET_SIZE(pieces) - 1);
+	PyString_ConcatAndDel(&temp, s);
+	PyList_SET_ITEM(pieces, PyList_GET_SIZE(pieces) - 1, temp);
+	if (temp == NULL)
+		goto Done;
+
+	/* Paste them all together with ", " between. */
+	s = PyString_FromString(", ");
+	if (s == NULL)
+		goto Done;
+	result = _PyString_Join(s, pieces);
+	Py_DECREF(s);
+
+Done:
+	Py_XDECREF(pieces);
+	Py_XDECREF(colon);
+	Py_ReprLeave((PyObject *)mp);
+	return result;
+}
+
+static Py_ssize_t
+dict_length(dictobject *mp)
+{
+	return mp->ma_used;
+}
+
+static PyObject *
+dict_subscript(dictobject *mp, register PyObject *key)
+{
+	PyObject *v;
+	long hash;
+	dictentry *ep;
+	assert(mp->ma_table != NULL);
+	if (!PyString_CheckExact(key) ||
+	    (hash = ((PyStringObject *) key)->ob_shash) == -1) {
+		hash = PyObject_Hash(key);
+		if (hash == -1)
+			return NULL;
+	}
+	ep = (mp->ma_lookup)(mp, key, hash);
+	if (ep == NULL)
+		return NULL;
+	v = ep->me_value;
+	if (v == NULL) {
+		if (!PyDict_CheckExact(mp)) {
+			/* Look up __missing__ method if we're a subclass. */
+		    	PyObject *missing;
+			static PyObject *missing_str = NULL;
+			if (missing_str == NULL)
+				missing_str =
+				  PyString_InternFromString("__missing__");
+			missing = _PyType_Lookup(mp->ob_type, missing_str);
+			if (missing != NULL)
+				return PyObject_CallFunctionObjArgs(missing,
+					(PyObject *)mp, key, NULL);
+		}
+		set_key_error(key);
+		return NULL;
+	}
+	else
+		Py_INCREF(v);
+	return v;
+}
+
+static int
+dict_ass_sub(dictobject *mp, PyObject *v, PyObject *w)
+{
+	if (w == NULL)
+		return PyDict_DelItem((PyObject *)mp, v);
+	else
+		return PyDict_SetItem((PyObject *)mp, v, w);
+}
+
+static PyMappingMethods dict_as_mapping = {
+	(lenfunc)dict_length, /*mp_length*/
+	(binaryfunc)dict_subscript, /*mp_subscript*/
+	(objobjargproc)dict_ass_sub, /*mp_ass_subscript*/
+};
+
+static PyObject *
+dict_keys(register dictobject *mp)
+{
+	register PyObject *v;
+	register Py_ssize_t i, j;
+	dictentry *ep;
+	Py_ssize_t mask, n;
+
+  again:
+	n = mp->ma_used;
+	v = PyList_New(n);
+	if (v == NULL)
+		return NULL;
+	if (n != mp->ma_used) {
+		/* Durnit.  The allocations caused the dict to resize.
+		 * Just start over, this shouldn't normally happen.
+		 */
+		Py_DECREF(v);
+		goto again;
+	}
+	ep = mp->ma_table;
+	mask = mp->ma_mask;
+	for (i = 0, j = 0; i <= mask; i++) {
+		if (ep[i].me_value != NULL) {
+			PyObject *key = ep[i].me_key;
+			Py_INCREF(key);
+			PyList_SET_ITEM(v, j, key);
+			j++;
+		}
+	}
+	assert(j == n);
+	return v;
+}
+
+static PyObject *
+dict_values(register dictobject *mp)
+{
+	register PyObject *v;
+	register Py_ssize_t i, j;
+	dictentry *ep;
+	Py_ssize_t mask, n;
+
+  again:
+	n = mp->ma_used;
+	v = PyList_New(n);
+	if (v == NULL)
+		return NULL;
+	if (n != mp->ma_used) {
+		/* Durnit.  The allocations caused the dict to resize.
+		 * Just start over, this shouldn't normally happen.
+		 */
+		Py_DECREF(v);
+		goto again;
+	}
+	ep = mp->ma_table;
+	mask = mp->ma_mask;
+	for (i = 0, j = 0; i <= mask; i++) {
+		if (ep[i].me_value != NULL) {
+			PyObject *value = ep[i].me_value;
+			Py_INCREF(value);
+			PyList_SET_ITEM(v, j, value);
+			j++;
+		}
+	}
+	assert(j == n);
+	return v;
+}
+
+static PyObject *
+dict_items(register dictobject *mp)
+{
+	register PyObject *v;
+	register Py_ssize_t i, j, n;
+	Py_ssize_t mask;
+	PyObject *item, *key, *value;
+	dictentry *ep;
+
+	/* Preallocate the list of tuples, to avoid allocations during
+	 * the loop over the items, which could trigger GC, which
+	 * could resize the dict. :-(
+	 */
+  again:
+	n = mp->ma_used;
+	v = PyList_New(n);
+	if (v == NULL)
+		return NULL;
+	for (i = 0; i < n; i++) {
+		item = PyTuple_New(2);
+		if (item == NULL) {
+			Py_DECREF(v);
+			return NULL;
+		}
+		PyList_SET_ITEM(v, i, item);
+	}
+	if (n != mp->ma_used) {
+		/* Durnit.  The allocations caused the dict to resize.
+		 * Just start over, this shouldn't normally happen.
+		 */
+		Py_DECREF(v);
+		goto again;
+	}
+	/* Nothing we do below makes any function calls. */
+	ep = mp->ma_table;
+	mask = mp->ma_mask;
+	for (i = 0, j = 0; i <= mask; i++) {
+		if ((value=ep[i].me_value) != NULL) {
+			key = ep[i].me_key;
+			item = PyList_GET_ITEM(v, j);
+			Py_INCREF(key);
+			PyTuple_SET_ITEM(item, 0, key);
+			Py_INCREF(value);
+			PyTuple_SET_ITEM(item, 1, value);
+			j++;
+		}
+	}
+	assert(j == n);
+	return v;
+}
+
+static PyObject *
+dict_fromkeys(PyObject *cls, PyObject *args)
+{
+	PyObject *seq;
+	PyObject *value = Py_None;
+	PyObject *it;	/* iter(seq) */
+	PyObject *key;
+	PyObject *d;
+	int status;
+
+	if (!PyArg_UnpackTuple(args, "fromkeys", 1, 2, &seq, &value))
+		return NULL;
+
+	d = PyObject_CallObject(cls, NULL);
+	if (d == NULL)
+		return NULL;
+
+	if (PyDict_CheckExact(d) && PyAnySet_CheckExact(seq)) {
+		dictobject *mp = (dictobject *)d;
+		Py_ssize_t pos = 0;
+		PyObject *key;
+		long hash;
+
+		if (dictresize(mp, PySet_GET_SIZE(seq)))
+			return NULL;
+
+		while (_PySet_NextEntry(seq, &pos, &key, &hash)) {
+			Py_INCREF(key);
+			Py_INCREF(value);
+			if (insertdict(mp, key, hash, value))
+				return NULL;
+		}
+		return d;
+	}
+
+	it = PyObject_GetIter(seq);
+	if (it == NULL){
+		Py_DECREF(d);
+		return NULL;
+	}
+
+	for (;;) {
+		key = PyIter_Next(it);
+		if (key == NULL) {
+			if (PyErr_Occurred())
+				goto Fail;
+			break;
+		}
+		status = PyObject_SetItem(d, key, value);
+		Py_DECREF(key);
+		if (status < 0)
+			goto Fail;
+	}
+
+	Py_DECREF(it);
+	return d;
+
+Fail:
+	Py_DECREF(it);
+	Py_DECREF(d);
+	return NULL;
+}
+
+static int
+dict_update_common(PyObject *self, PyObject *args, PyObject *kwds, char *methname)
+{
+	PyObject *arg = NULL;
+	int result = 0;
+
+	if (!PyArg_UnpackTuple(args, methname, 0, 1, &arg))
+		result = -1;
+
+	else if (arg != NULL) {
+		if (PyObject_HasAttrString(arg, "keys"))
+			result = PyDict_Merge(self, arg, 1);
+		else
+			result = PyDict_MergeFromSeq2(self, arg, 1);
+	}
+	if (result == 0 && kwds != NULL)
+		result = PyDict_Merge(self, kwds, 1);
+	return result;
+}
+
+static PyObject *
+dict_update(PyObject *self, PyObject *args, PyObject *kwds)
+{
+	if (dict_update_common(self, args, kwds, "update") != -1)
+		Py_RETURN_NONE;
+	return NULL;
+}
+
+/* Update unconditionally replaces existing items.
+   Merge has a 3rd argument 'override'; if set, it acts like Update,
+   otherwise it leaves existing items unchanged.
+
+   PyDict_{Update,Merge} update/merge from a mapping object.
+
+   PyDict_MergeFromSeq2 updates/merges from any iterable object
+   producing iterable objects of length 2.
+*/
+
+int
+PyDict_MergeFromSeq2(PyObject *d, PyObject *seq2, int override)
+{
+	PyObject *it;	/* iter(seq2) */
+	Py_ssize_t i;	/* index into seq2 of current element */
+	PyObject *item;	/* seq2[i] */
+	PyObject *fast;	/* item as a 2-tuple or 2-list */
+
+	assert(d != NULL);
+	assert(PyDict_Check(d));
+	assert(seq2 != NULL);
+
+	it = PyObject_GetIter(seq2);
+	if (it == NULL)
+		return -1;
+
+	for (i = 0; ; ++i) {
+		PyObject *key, *value;
+		Py_ssize_t n;
+
+		fast = NULL;
+		item = PyIter_Next(it);
+		if (item == NULL) {
+			if (PyErr_Occurred())
+				goto Fail;
+			break;
+		}
+
+		/* Convert item to sequence, and verify length 2. */
+		fast = PySequence_Fast(item, "");
+		if (fast == NULL) {
+			if (PyErr_ExceptionMatches(PyExc_TypeError))
+				PyErr_Format(PyExc_TypeError,
+					"cannot convert dictionary update "
+					"sequence element #%zd to a sequence",
+					i);
+			goto Fail;
+		}
+		n = PySequence_Fast_GET_SIZE(fast);
+		if (n != 2) {
+			PyErr_Format(PyExc_ValueError,
+				     "dictionary update sequence element #%zd "
+				     "has length %zd; 2 is required",
+				     i, n);
+			goto Fail;
+		}
+
+		/* Update/merge with this (key, value) pair. */
+		key = PySequence_Fast_GET_ITEM(fast, 0);
+		value = PySequence_Fast_GET_ITEM(fast, 1);
+		if (override || PyDict_GetItem(d, key) == NULL) {
+			int status = PyDict_SetItem(d, key, value);
+			if (status < 0)
+				goto Fail;
+		}
+		Py_DECREF(fast);
+		Py_DECREF(item);
+	}
+
+	i = 0;
+	goto Return;
+Fail:
+	Py_XDECREF(item);
+	Py_XDECREF(fast);
+	i = -1;
+Return:
+	Py_DECREF(it);
+	return Py_SAFE_DOWNCAST(i, Py_ssize_t, int);
+}
+
+int
+PyDict_Update(PyObject *a, PyObject *b)
+{
+	return PyDict_Merge(a, b, 1);
+}
+
+int
+PyDict_Merge(PyObject *a, PyObject *b, int override)
+{
+	register PyDictObject *mp, *other;
+	register Py_ssize_t i;
+	dictentry *entry;
+
+	/* We accept for the argument either a concrete dictionary object,
+	 * or an abstract "mapping" object.  For the former, we can do
+	 * things quite efficiently.  For the latter, we only require that
+	 * PyMapping_Keys() and PyObject_GetItem() be supported.
+	 */
+	if (a == NULL || !PyDict_Check(a) || b == NULL) {
+		PyErr_BadInternalCall();
+		return -1;
+	}
+	mp = (dictobject*)a;
+	if (PyDict_Check(b)) {
+		other = (dictobject*)b;
+		if (other == mp || other->ma_used == 0)
+			/* a.update(a) or a.update({}); nothing to do */
+			return 0;
+		if (mp->ma_used == 0)
+			/* Since the target dict is empty, PyDict_GetItem()
+			 * always returns NULL.  Setting override to 1
+			 * skips the unnecessary test.
+			 */
+			override = 1;
+		/* Do one big resize at the start, rather than
+		 * incrementally resizing as we insert new items.  Expect
+		 * that there will be no (or few) overlapping keys.
+		 */
+		if ((mp->ma_fill + other->ma_used)*3 >= (mp->ma_mask+1)*2) {
+		   if (dictresize(mp, (mp->ma_used + other->ma_used)*2) != 0)
+			   return -1;
+		}
+		for (i = 0; i <= other->ma_mask; i++) {
+			entry = &other->ma_table[i];
+			if (entry->me_value != NULL &&
+			    (override ||
+			     PyDict_GetItem(a, entry->me_key) == NULL)) {
+				Py_INCREF(entry->me_key);
+				Py_INCREF(entry->me_value);
+				if (insertdict(mp, entry->me_key,
+					       (long)entry->me_hash,
+					       entry->me_value) != 0)
+					return -1;
+			}
+		}
+	}
+	else {
+		/* Do it the generic, slower way */
+		PyObject *keys = PyMapping_Keys(b);
+		PyObject *iter;
+		PyObject *key, *value;
+		int status;
+
+		if (keys == NULL)
+			/* Docstring says this is equivalent to E.keys() so
+			 * if E doesn't have a .keys() method we want
+			 * AttributeError to percolate up.  Might as well
+			 * do the same for any other error.
+			 */
+			return -1;
+
+		iter = PyObject_GetIter(keys);
+		Py_DECREF(keys);
+		if (iter == NULL)
+			return -1;
+
+		for (key = PyIter_Next(iter); key; key = PyIter_Next(iter)) {
+			if (!override && PyDict_GetItem(a, key) != NULL) {
+				Py_DECREF(key);
+				continue;
+			}
+			value = PyObject_GetItem(b, key);
+			if (value == NULL) {
+				Py_DECREF(iter);
+				Py_DECREF(key);
+				return -1;
+			}
+			status = PyDict_SetItem(a, key, value);
+			Py_DECREF(key);
+			Py_DECREF(value);
+			if (status < 0) {
+				Py_DECREF(iter);
+				return -1;
+			}
+		}
+		Py_DECREF(iter);
+		if (PyErr_Occurred())
+			/* Iterator completed, via error */
+			return -1;
+	}
+	return 0;
+}
+
+static PyObject *
+dict_copy(register dictobject *mp)
+{
+	return PyDict_Copy((PyObject*)mp);
+}
+
+PyObject *
+PyDict_Copy(PyObject *o)
+{
+	PyObject *copy;
+
+	if (o == NULL || !PyDict_Check(o)) {
+		PyErr_BadInternalCall();
+		return NULL;
+	}
+	copy = PyDict_New();
+	if (copy == NULL)
+		return NULL;
+	if (PyDict_Merge(copy, o, 1) == 0)
+		return copy;
+	Py_DECREF(copy);
+	return NULL;
+}
+
+Py_ssize_t
+PyDict_Size(PyObject *mp)
+{
+	if (mp == NULL || !PyDict_Check(mp)) {
+		PyErr_BadInternalCall();
+		return -1;
+	}
+	return ((dictobject *)mp)->ma_used;
+}
+
+PyObject *
+PyDict_Keys(PyObject *mp)
+{
+	if (mp == NULL || !PyDict_Check(mp)) {
+		PyErr_BadInternalCall();
+		return NULL;
+	}
+	return dict_keys((dictobject *)mp);
+}
+
+PyObject *
+PyDict_Values(PyObject *mp)
+{
+	if (mp == NULL || !PyDict_Check(mp)) {
+		PyErr_BadInternalCall();
+		return NULL;
+	}
+	return dict_values((dictobject *)mp);
+}
+
+PyObject *
+PyDict_Items(PyObject *mp)
+{
+	if (mp == NULL || !PyDict_Check(mp)) {
+		PyErr_BadInternalCall();
+		return NULL;
+	}
+	return dict_items((dictobject *)mp);
+}
+
+/* Subroutine which returns the smallest key in a for which b's value
+   is different or absent.  The value is returned too, through the
+   pval argument.  Both are NULL if no key in a is found for which b's status
+   differs.  The refcounts on (and only on) non-NULL *pval and function return
+   values must be decremented by the caller (characterize() increments them
+   to ensure that mutating comparison and PyDict_GetItem calls can't delete
+   them before the caller is done looking at them). */
+
+static PyObject *
+characterize(dictobject *a, dictobject *b, PyObject **pval)
+{
+	PyObject *akey = NULL; /* smallest key in a s.t. a[akey] != b[akey] */
+	PyObject *aval = NULL; /* a[akey] */
+	Py_ssize_t i;
+	int cmp;
+
+	for (i = 0; i <= a->ma_mask; i++) {
+		PyObject *thiskey, *thisaval, *thisbval;
+		if (a->ma_table[i].me_value == NULL)
+			continue;
+		thiskey = a->ma_table[i].me_key;
+		Py_INCREF(thiskey);  /* keep alive across compares */
+		if (akey != NULL) {
+			cmp = PyObject_RichCompareBool(akey, thiskey, Py_LT);
+			if (cmp < 0) {
+				Py_DECREF(thiskey);
+				goto Fail;
+			}
+			if (cmp > 0 ||
+			    i > a->ma_mask ||
+			    a->ma_table[i].me_value == NULL)
+			{
+				/* Not the *smallest* a key; or maybe it is
+				 * but the compare shrunk the dict so we can't
+				 * find its associated value anymore; or
+				 * maybe it is but the compare deleted the
+				 * a[thiskey] entry.
+				 */
+				Py_DECREF(thiskey);
+				continue;
+			}
+		}
+
+		/* Compare a[thiskey] to b[thiskey]; cmp <- true iff equal. */
+		thisaval = a->ma_table[i].me_value;
+		assert(thisaval);
+		Py_INCREF(thisaval);   /* keep alive */
+		thisbval = PyDict_GetItem((PyObject *)b, thiskey);
+		if (thisbval == NULL)
+			cmp = 0;
+		else {
+			/* both dicts have thiskey:  same values? */
+			cmp = PyObject_RichCompareBool(
+						thisaval, thisbval, Py_EQ);
+			if (cmp < 0) {
+		    		Py_DECREF(thiskey);
+		    		Py_DECREF(thisaval);
+		    		goto Fail;
+			}
+		}
+		if (cmp == 0) {
+			/* New winner. */
+			Py_XDECREF(akey);
+			Py_XDECREF(aval);
+			akey = thiskey;
+			aval = thisaval;
+		}
+		else {
+			Py_DECREF(thiskey);
+			Py_DECREF(thisaval);
+		}
+	}
+	*pval = aval;
+	return akey;
+
+Fail:
+	Py_XDECREF(akey);
+	Py_XDECREF(aval);
+	*pval = NULL;
+	return NULL;
+}
+
+static int
+dict_compare(dictobject *a, dictobject *b)
+{
+	PyObject *adiff, *bdiff, *aval, *bval;
+	int res;
+
+	/* Compare lengths first */
+	if (a->ma_used < b->ma_used)
+		return -1;	/* a is shorter */
+	else if (a->ma_used > b->ma_used)
+		return 1;	/* b is shorter */
+
+	/* Same length -- check all keys */
+	bdiff = bval = NULL;
+	adiff = characterize(a, b, &aval);
+	if (adiff == NULL) {
+		assert(!aval);
+		/* Either an error, or a is a subset with the same length so
+		 * must be equal.
+		 */
+		res = PyErr_Occurred() ? -1 : 0;
+		goto Finished;
+	}
+	bdiff = characterize(b, a, &bval);
+	if (bdiff == NULL && PyErr_Occurred()) {
+		assert(!bval);
+		res = -1;
+		goto Finished;
+	}
+	res = 0;
+	if (bdiff) {
+		/* bdiff == NULL "should be" impossible now, but perhaps
+		 * the last comparison done by the characterize() on a had
+		 * the side effect of making the dicts equal!
+		 */
+		res = PyObject_Compare(adiff, bdiff);
+	}
+	if (res == 0 && bval != NULL)
+		res = PyObject_Compare(aval, bval);
+
+Finished:
+	Py_XDECREF(adiff);
+	Py_XDECREF(bdiff);
+	Py_XDECREF(aval);
+	Py_XDECREF(bval);
+	return res;
+}
+
+/* Return 1 if dicts equal, 0 if not, -1 if error.
+ * Gets out as soon as any difference is detected.
+ * Uses only Py_EQ comparison.
+ */
+static int
+dict_equal(dictobject *a, dictobject *b)
+{
+	Py_ssize_t i;
+
+	if (a->ma_used != b->ma_used)
+		/* can't be equal if # of entries differ */
+		return 0;
+
+	/* Same # of entries -- check all of 'em.  Exit early on any diff. */
+	for (i = 0; i <= a->ma_mask; i++) {
+		PyObject *aval = a->ma_table[i].me_value;
+		if (aval != NULL) {
+			int cmp;
+			PyObject *bval;
+			PyObject *key = a->ma_table[i].me_key;
+			/* temporarily bump aval's refcount to ensure it stays
+			   alive until we're done with it */
+			Py_INCREF(aval);
+			/* ditto for key */
+			Py_INCREF(key);
+			bval = PyDict_GetItem((PyObject *)b, key);
+			Py_DECREF(key);
+			if (bval == NULL) {
+				Py_DECREF(aval);
+				return 0;
+			}
+			cmp = PyObject_RichCompareBool(aval, bval, Py_EQ);
+			Py_DECREF(aval);
+			if (cmp <= 0)  /* error or not equal */
+				return cmp;
+ 		}
+	}
+	return 1;
+ }
+
+static PyObject *
+dict_richcompare(PyObject *v, PyObject *w, int op)
+{
+	int cmp;
+	PyObject *res;
+
+	if (!PyDict_Check(v) || !PyDict_Check(w)) {
+		res = Py_NotImplemented;
+	}
+	else if (op == Py_EQ || op == Py_NE) {
+		cmp = dict_equal((dictobject *)v, (dictobject *)w);
+		if (cmp < 0)
+			return NULL;
+		res = (cmp == (op == Py_EQ)) ? Py_True : Py_False;
+	}
+	else
+		res = Py_NotImplemented;
+	Py_INCREF(res);
+	return res;
+ }
+
+static PyObject *
+dict_has_key(register dictobject *mp, PyObject *key)
+{
+	long hash;
+	dictentry *ep;
+
+	if (!PyString_CheckExact(key) ||
+	    (hash = ((PyStringObject *) key)->ob_shash) == -1) {
+		hash = PyObject_Hash(key);
+		if (hash == -1)
+			return NULL;
+	}
+	ep = (mp->ma_lookup)(mp, key, hash);
+	if (ep == NULL)
+		return NULL;
+	return PyBool_FromLong(ep->me_value != NULL);
+}
+
+static PyObject *
+dict_get(register dictobject *mp, PyObject *args)
+{
+	PyObject *key;
+	PyObject *failobj = Py_None;
+	PyObject *val = NULL;
+	long hash;
+	dictentry *ep;
+
+	if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &failobj))
+		return NULL;
+
+	if (!PyString_CheckExact(key) ||
+	    (hash = ((PyStringObject *) key)->ob_shash) == -1) {
+		hash = PyObject_Hash(key);
+		if (hash == -1)
+			return NULL;
+	}
+	ep = (mp->ma_lookup)(mp, key, hash);
+	if (ep == NULL)
+		return NULL;
+	val = ep->me_value;
+	if (val == NULL)
+		val = failobj;
+	Py_INCREF(val);
+	return val;
+}
+
+
+static PyObject *
+dict_setdefault(register dictobject *mp, PyObject *args)
+{
+	PyObject *key;
+	PyObject *failobj = Py_None;
+	PyObject *val = NULL;
+	long hash;
+	dictentry *ep;
+
+	if (!PyArg_UnpackTuple(args, "setdefault", 1, 2, &key, &failobj))
+		return NULL;
+
+	if (!PyString_CheckExact(key) ||
+	    (hash = ((PyStringObject *) key)->ob_shash) == -1) {
+		hash = PyObject_Hash(key);
+		if (hash == -1)
+			return NULL;
+	}
+	ep = (mp->ma_lookup)(mp, key, hash);
+	if (ep == NULL)
+		return NULL;
+	val = ep->me_value;
+	if (val == NULL) {
+		val = failobj;
+		if (PyDict_SetItem((PyObject*)mp, key, failobj))
+			val = NULL;
+	}
+	Py_XINCREF(val);
+	return val;
+}
+
+
+static PyObject *
+dict_clear(register dictobject *mp)
+{
+	PyDict_Clear((PyObject *)mp);
+	Py_RETURN_NONE;
+}
+
+static PyObject *
+dict_pop(dictobject *mp, PyObject *args)
+{
+	long hash;
+	dictentry *ep;
+	PyObject *old_value, *old_key;
+	PyObject *key, *deflt = NULL;
+
+	if(!PyArg_UnpackTuple(args, "pop", 1, 2, &key, &deflt))
+		return NULL;
+	if (mp->ma_used == 0) {
+		if (deflt) {
+			Py_INCREF(deflt);
+			return deflt;
+		}
+		PyErr_SetString(PyExc_KeyError,
+				"pop(): dictionary is empty");
+		return NULL;
+	}
+	if (!PyString_CheckExact(key) ||
+	    (hash = ((PyStringObject *) key)->ob_shash) == -1) {
+		hash = PyObject_Hash(key);
+		if (hash == -1)
+			return NULL;
+	}
+	ep = (mp->ma_lookup)(mp, key, hash);
+	if (ep == NULL)
+		return NULL;
+	if (ep->me_value == NULL) {
+		if (deflt) {
+			Py_INCREF(deflt);
+			return deflt;
+		}
+		set_key_error(key);
+		return NULL;
+	}
+	old_key = ep->me_key;
+	Py_INCREF(dummy);
+	ep->me_key = dummy;
+	old_value = ep->me_value;
+	ep->me_value = NULL;
+	mp->ma_used--;
+	Py_DECREF(old_key);
+	return old_value;
+}
+
+static PyObject *
+dict_popitem(dictobject *mp)
+{
+	Py_ssize_t i = 0;
+	dictentry *ep;
+	PyObject *res;
+
+	/* Allocate the result tuple before checking the size.  Believe it
+	 * or not, this allocation could trigger a garbage collection which
+	 * could empty the dict, so if we checked the size first and that
+	 * happened, the result would be an infinite loop (searching for an
+	 * entry that no longer exists).  Note that the usual popitem()
+	 * idiom is "while d: k, v = d.popitem()". so needing to throw the
+	 * tuple away if the dict *is* empty isn't a significant
+	 * inefficiency -- possible, but unlikely in practice.
+	 */
+	res = PyTuple_New(2);
+	if (res == NULL)
+		return NULL;
+	if (mp->ma_used == 0) {
+		Py_DECREF(res);
+		PyErr_SetString(PyExc_KeyError,
+				"popitem(): dictionary is empty");
+		return NULL;
+	}
+	/* Set ep to "the first" dict entry with a value.  We abuse the hash
+	 * field of slot 0 to hold a search finger:
+	 * If slot 0 has a value, use slot 0.
+	 * Else slot 0 is being used to hold a search finger,
+	 * and we use its hash value as the first index to look.
+	 */
+	ep = &mp->ma_table[0];
+	if (ep->me_value == NULL) {
+		i = ep->me_hash;
+		/* The hash field may be a real hash value, or it may be a
+		 * legit search finger, or it may be a once-legit search
+		 * finger that's out of bounds now because it wrapped around
+		 * or the table shrunk -- simply make sure it's in bounds now.
+		 */
+		if (i > mp->ma_mask || i < 1)
+			i = 1;	/* skip slot 0 */
+		while ((ep = &mp->ma_table[i])->me_value == NULL) {
+			i++;
+			if (i > mp->ma_mask)
+				i = 1;
+		}
+	}
+	PyTuple_SET_ITEM(res, 0, ep->me_key);
+	PyTuple_SET_ITEM(res, 1, ep->me_value);
+	Py_INCREF(dummy);
+	ep->me_key = dummy;
+	ep->me_value = NULL;
+	mp->ma_used--;
+	assert(mp->ma_table[0].me_value == NULL);
+	mp->ma_table[0].me_hash = i + 1;  /* next place to start */
+	return res;
+}
+
+static int
+dict_traverse(PyObject *op, visitproc visit, void *arg)
+{
+	Py_ssize_t i = 0;
+	PyObject *pk;
+	PyObject *pv;
+
+	while (PyDict_Next(op, &i, &pk, &pv)) {
+		Py_VISIT(pk);
+		Py_VISIT(pv);
+	}
+	return 0;
+}
+
+static int
+dict_tp_clear(PyObject *op)
+{
+	PyDict_Clear(op);
+	return 0;
+}
+
+
+extern PyTypeObject PyDictIterKey_Type; /* Forward */
+extern PyTypeObject PyDictIterValue_Type; /* Forward */
+extern PyTypeObject PyDictIterItem_Type; /* Forward */
+static PyObject *dictiter_new(dictobject *, PyTypeObject *);
+
+static PyObject *
+dict_iterkeys(dictobject *dict)
+{
+	return dictiter_new(dict, &PyDictIterKey_Type);
+}
+
+static PyObject *
+dict_itervalues(dictobject *dict)
+{
+	return dictiter_new(dict, &PyDictIterValue_Type);
+}
+
+static PyObject *
+dict_iteritems(dictobject *dict)
+{
+	return dictiter_new(dict, &PyDictIterItem_Type);
+}
+
+
+PyDoc_STRVAR(has_key__doc__,
+"D.has_key(k) -> True if D has a key k, else False");
+
+PyDoc_STRVAR(contains__doc__,
+"D.__contains__(k) -> True if D has a key k, else False");
+
+PyDoc_STRVAR(getitem__doc__, "x.__getitem__(y) <==> x[y]");
+
+PyDoc_STRVAR(get__doc__,
+"D.get(k[,d]) -> D[k] if k in D, else d.  d defaults to None.");
+
+PyDoc_STRVAR(setdefault_doc__,
+"D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D");
+
+PyDoc_STRVAR(pop__doc__,
+"D.pop(k[,d]) -> v, remove specified key and return the corresponding value\n\
+If key is not found, d is returned if given, otherwise KeyError is raised");
+
+PyDoc_STRVAR(popitem__doc__,
+"D.popitem() -> (k, v), remove and return some (key, value) pair as a\n\
+2-tuple; but raise KeyError if D is empty");
+
+PyDoc_STRVAR(keys__doc__,
+"D.keys() -> list of D's keys");
+
+PyDoc_STRVAR(items__doc__,
+"D.items() -> list of D's (key, value) pairs, as 2-tuples");
+
+PyDoc_STRVAR(values__doc__,
+"D.values() -> list of D's values");
+
+PyDoc_STRVAR(update__doc__,
+"D.update(E, **F) -> None.  Update D from E and F: for k in E: D[k] = E[k]\n\
+(if E has keys else: for (k, v) in E: D[k] = v) then: for k in F: D[k] = F[k]");
+
+PyDoc_STRVAR(fromkeys__doc__,
+"dict.fromkeys(S[,v]) -> New dict with keys from S and values equal to v.\n\
+v defaults to None.");
+
+PyDoc_STRVAR(clear__doc__,
+"D.clear() -> None.  Remove all items from D.");
+
+PyDoc_STRVAR(copy__doc__,
+"D.copy() -> a shallow copy of D");
+
+PyDoc_STRVAR(iterkeys__doc__,
+"D.iterkeys() -> an iterator over the keys of D");
+
+PyDoc_STRVAR(itervalues__doc__,
+"D.itervalues() -> an iterator over the values of D");
+
+PyDoc_STRVAR(iteritems__doc__,
+"D.iteritems() -> an iterator over the (key, value) items of D");
+
+static PyMethodDef mapp_methods[] = {
+	{"__contains__",(PyCFunction)dict_has_key,      METH_O | METH_COEXIST,
+	 contains__doc__},
+	{"__getitem__", (PyCFunction)dict_subscript,	METH_O | METH_COEXIST,
+	 getitem__doc__},
+	{"has_key",	(PyCFunction)dict_has_key,      METH_O,
+	 has_key__doc__},
+	{"get",         (PyCFunction)dict_get,          METH_VARARGS,
+	 get__doc__},
+	{"setdefault",  (PyCFunction)dict_setdefault,   METH_VARARGS,
+	 setdefault_doc__},
+	{"pop",         (PyCFunction)dict_pop,          METH_VARARGS,
+	 pop__doc__},
+	{"popitem",	(PyCFunction)dict_popitem,	METH_NOARGS,
+	 popitem__doc__},
+	{"keys",	(PyCFunction)dict_keys,		METH_NOARGS,
+	keys__doc__},
+	{"items",	(PyCFunction)dict_items,	METH_NOARGS,
+	 items__doc__},
+	{"values",	(PyCFunction)dict_values,	METH_NOARGS,
+	 values__doc__},
+	{"update",	(PyCFunction)dict_update,	METH_VARARGS | METH_KEYWORDS,
+	 update__doc__},
+	{"fromkeys",	(PyCFunction)dict_fromkeys,	METH_VARARGS | METH_CLASS,
+	 fromkeys__doc__},
+	{"clear",	(PyCFunction)dict_clear,	METH_NOARGS,
+	 clear__doc__},
+	{"copy",	(PyCFunction)dict_copy,		METH_NOARGS,
+	 copy__doc__},
+	{"iterkeys",	(PyCFunction)dict_iterkeys,	METH_NOARGS,
+	 iterkeys__doc__},
+	{"itervalues",	(PyCFunction)dict_itervalues,	METH_NOARGS,
+	 itervalues__doc__},
+	{"iteritems",	(PyCFunction)dict_iteritems,	METH_NOARGS,
+	 iteritems__doc__},
+	{NULL,		NULL}	/* sentinel */
+};
+
+/* Return 1 if `key` is in dict `op`, 0 if not, and -1 on error. */
+int
+PyDict_Contains(PyObject *op, PyObject *key)
+{
+	long hash;
+	dictobject *mp = (dictobject *)op;
+	dictentry *ep;
+
+	if (!PyString_CheckExact(key) ||
+	    (hash = ((PyStringObject *) key)->ob_shash) == -1) {
+		hash = PyObject_Hash(key);
+		if (hash == -1)
+			return -1;
+	}
+	ep = (mp->ma_lookup)(mp, key, hash);
+	return ep == NULL ? -1 : (ep->me_value != NULL);
+}
+
+/* Internal version of PyDict_Contains used when the hash value is already known */
+int
+_PyDict_Contains(PyObject *op, PyObject *key, long hash)
+{
+	dictobject *mp = (dictobject *)op;
+	dictentry *ep;
+
+	ep = (mp->ma_lookup)(mp, key, hash);
+	return ep == NULL ? -1 : (ep->me_value != NULL);
+}
+
+/* Hack to implement "key in dict" */
+static PySequenceMethods dict_as_sequence = {
+	0,			/* sq_length */
+	0,			/* sq_concat */
+	0,			/* sq_repeat */
+	0,			/* sq_item */
+	0,			/* sq_slice */
+	0,			/* sq_ass_item */
+	0,			/* sq_ass_slice */
+	PyDict_Contains,	/* sq_contains */
+	0,			/* sq_inplace_concat */
+	0,			/* sq_inplace_repeat */
+};
+
+static PyObject *
+dict_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	PyObject *self;
+
+	assert(type != NULL && type->tp_alloc != NULL);
+	self = type->tp_alloc(type, 0);
+	if (self != NULL) {
+		PyDictObject *d = (PyDictObject *)self;
+		/* It's guaranteed that tp->alloc zeroed out the struct. */
+		assert(d->ma_table == NULL && d->ma_fill == 0 && d->ma_used == 0);
+		INIT_NONZERO_DICT_SLOTS(d);
+		d->ma_lookup = lookdict_string;
+#ifdef SHOW_CONVERSION_COUNTS
+		++created;
+#endif
+	}
+	return self;
+}
+
+static int
+dict_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+	return dict_update_common(self, args, kwds, "dict");
+}
+
+static long
+dict_nohash(PyObject *self)
+{
+	PyErr_SetString(PyExc_TypeError, "dict objects are unhashable");
+	return -1;
+}
+
+static PyObject *
+dict_iter(dictobject *dict)
+{
+	return dictiter_new(dict, &PyDictIterKey_Type);
+}
+
+PyDoc_STRVAR(dictionary_doc,
+"dict() -> new empty dictionary.\n"
+"dict(mapping) -> new dictionary initialized from a mapping object's\n"
+"    (key, value) pairs.\n"
+"dict(seq) -> new dictionary initialized as if via:\n"
+"    d = {}\n"
+"    for k, v in seq:\n"
+"        d[k] = v\n"
+"dict(**kwargs) -> new dictionary initialized with the name=value pairs\n"
+"    in the keyword argument list.  For example:  dict(one=1, two=2)");
+
+PyTypeObject PyDict_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,
+	"dict",
+	sizeof(dictobject),
+	0,
+	(destructor)dict_dealloc,		/* tp_dealloc */
+	(printfunc)dict_print,			/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	(cmpfunc)dict_compare,			/* tp_compare */
+	(reprfunc)dict_repr,			/* tp_repr */
+	0,					/* tp_as_number */
+	&dict_as_sequence,			/* tp_as_sequence */
+	&dict_as_mapping,			/* tp_as_mapping */
+	dict_nohash,				/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+		Py_TPFLAGS_BASETYPE,		/* tp_flags */
+	dictionary_doc,				/* tp_doc */
+	dict_traverse,				/* tp_traverse */
+	dict_tp_clear,				/* tp_clear */
+	dict_richcompare,			/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	(getiterfunc)dict_iter,			/* tp_iter */
+	0,					/* tp_iternext */
+	mapp_methods,				/* tp_methods */
+	0,					/* tp_members */
+	0,					/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	dict_init,				/* tp_init */
+	PyType_GenericAlloc,			/* tp_alloc */
+	dict_new,				/* tp_new */
+	PyObject_GC_Del,        		/* tp_free */
+};
+
+/* For backward compatibility with old dictionary interface */
+
+PyObject *
+PyDict_GetItemString(PyObject *v, const char *key)
+{
+	PyObject *kv, *rv;
+	kv = PyString_FromString(key);
+	if (kv == NULL)
+		return NULL;
+	rv = PyDict_GetItem(v, kv);
+	Py_DECREF(kv);
+	return rv;
+}
+
+int
+PyDict_SetItemString(PyObject *v, const char *key, PyObject *item)
+{
+	PyObject *kv;
+	int err;
+	kv = PyString_FromString(key);
+	if (kv == NULL)
+		return -1;
+	PyString_InternInPlace(&kv); /* XXX Should we really? */
+	err = PyDict_SetItem(v, kv, item);
+	Py_DECREF(kv);
+	return err;
+}
+
+int
+PyDict_DelItemString(PyObject *v, const char *key)
+{
+	PyObject *kv;
+	int err;
+	kv = PyString_FromString(key);
+	if (kv == NULL)
+		return -1;
+	err = PyDict_DelItem(v, kv);
+	Py_DECREF(kv);
+	return err;
+}
+
+/* Dictionary iterator types */
+
+typedef struct {
+	PyObject_HEAD
+	dictobject *di_dict; /* Set to NULL when iterator is exhausted */
+	Py_ssize_t di_used;
+	Py_ssize_t di_pos;
+	PyObject* di_result; /* reusable result tuple for iteritems */
+	Py_ssize_t len;
+} dictiterobject;
+
+static PyObject *
+dictiter_new(dictobject *dict, PyTypeObject *itertype)
+{
+	dictiterobject *di;
+	di = PyObject_New(dictiterobject, itertype);
+	if (di == NULL)
+		return NULL;
+	Py_INCREF(dict);
+	di->di_dict = dict;
+	di->di_used = dict->ma_used;
+	di->di_pos = 0;
+	di->len = dict->ma_used;
+	if (itertype == &PyDictIterItem_Type) {
+		di->di_result = PyTuple_Pack(2, Py_None, Py_None);
+		if (di->di_result == NULL) {
+			Py_DECREF(di);
+			return NULL;
+		}
+	}
+	else
+		di->di_result = NULL;
+	return (PyObject *)di;
+}
+
+static void
+dictiter_dealloc(dictiterobject *di)
+{
+	Py_XDECREF(di->di_dict);
+	Py_XDECREF(di->di_result);
+	PyObject_Del(di);
+}
+
+static PyObject *
+dictiter_len(dictiterobject *di)
+{
+	Py_ssize_t len = 0;
+	if (di->di_dict != NULL && di->di_used == di->di_dict->ma_used)
+		len = di->len;
+	return PyInt_FromSize_t(len);
+}
+
+PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
+
+static PyMethodDef dictiter_methods[] = {
+	{"__length_hint__", (PyCFunction)dictiter_len, METH_NOARGS, length_hint_doc},
+ 	{NULL,		NULL}		/* sentinel */
+};
+
+static PyObject *dictiter_iternextkey(dictiterobject *di)
+{
+	PyObject *key;
+	register Py_ssize_t i, mask;
+	register dictentry *ep;
+	dictobject *d = di->di_dict;
+
+	if (d == NULL)
+		return NULL;
+	assert (PyDict_Check(d));
+
+	if (di->di_used != d->ma_used) {
+		PyErr_SetString(PyExc_RuntimeError,
+				"dictionary changed size during iteration");
+		di->di_used = -1; /* Make this state sticky */
+		return NULL;
+	}
+
+	i = di->di_pos;
+	if (i < 0)
+		goto fail;
+	ep = d->ma_table;
+	mask = d->ma_mask;
+	while (i <= mask && ep[i].me_value == NULL)
+		i++;
+	di->di_pos = i+1;
+	if (i > mask)
+		goto fail;
+	di->len--;
+	key = ep[i].me_key;
+	Py_INCREF(key);
+	return key;
+
+fail:
+	Py_DECREF(d);
+	di->di_dict = NULL;
+	return NULL;
+}
+
+PyTypeObject PyDictIterKey_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,					/* ob_size */
+	"dictionary-keyiterator",		/* tp_name */
+	sizeof(dictiterobject),			/* tp_basicsize */
+	0,					/* tp_itemsize */
+	/* methods */
+	(destructor)dictiter_dealloc, 		/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	0,					/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT,			/* tp_flags */
+ 	0,					/* tp_doc */
+ 	0,					/* tp_traverse */
+ 	0,					/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	PyObject_SelfIter,			/* tp_iter */
+	(iternextfunc)dictiter_iternextkey,	/* tp_iternext */
+	dictiter_methods,			/* tp_methods */
+	0,
+};
+
+static PyObject *dictiter_iternextvalue(dictiterobject *di)
+{
+	PyObject *value;
+	register Py_ssize_t i, mask;
+	register dictentry *ep;
+	dictobject *d = di->di_dict;
+
+	if (d == NULL)
+		return NULL;
+	assert (PyDict_Check(d));
+
+	if (di->di_used != d->ma_used) {
+		PyErr_SetString(PyExc_RuntimeError,
+				"dictionary changed size during iteration");
+		di->di_used = -1; /* Make this state sticky */
+		return NULL;
+	}
+
+	i = di->di_pos;
+	mask = d->ma_mask;
+	if (i < 0 || i > mask)
+		goto fail;
+	ep = d->ma_table;
+	while ((value=ep[i].me_value) == NULL) {
+		i++;
+		if (i > mask)
+			goto fail;
+	}
+	di->di_pos = i+1;
+	di->len--;
+	Py_INCREF(value);
+	return value;
+
+fail:
+	Py_DECREF(d);
+	di->di_dict = NULL;
+	return NULL;
+}
+
+PyTypeObject PyDictIterValue_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,					/* ob_size */
+	"dictionary-valueiterator",		/* tp_name */
+	sizeof(dictiterobject),			/* tp_basicsize */
+	0,					/* tp_itemsize */
+	/* methods */
+	(destructor)dictiter_dealloc, 		/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	0,					/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT,			/* tp_flags */
+ 	0,					/* tp_doc */
+ 	0,					/* tp_traverse */
+ 	0,					/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	PyObject_SelfIter,			/* tp_iter */
+	(iternextfunc)dictiter_iternextvalue,	/* tp_iternext */
+	dictiter_methods,			/* tp_methods */
+	0,
+};
+
+static PyObject *dictiter_iternextitem(dictiterobject *di)
+{
+	PyObject *key, *value, *result = di->di_result;
+	register Py_ssize_t i, mask;
+	register dictentry *ep;
+	dictobject *d = di->di_dict;
+
+	if (d == NULL)
+		return NULL;
+	assert (PyDict_Check(d));
+
+	if (di->di_used != d->ma_used) {
+		PyErr_SetString(PyExc_RuntimeError,
+				"dictionary changed size during iteration");
+		di->di_used = -1; /* Make this state sticky */
+		return NULL;
+	}
+
+	i = di->di_pos;
+	if (i < 0)
+		goto fail;
+	ep = d->ma_table;
+	mask = d->ma_mask;
+	while (i <= mask && ep[i].me_value == NULL)
+		i++;
+	di->di_pos = i+1;
+	if (i > mask)
+		goto fail;
+
+	if (result->ob_refcnt == 1) {
+		Py_INCREF(result);
+		Py_DECREF(PyTuple_GET_ITEM(result, 0));
+		Py_DECREF(PyTuple_GET_ITEM(result, 1));
+	} else {
+		result = PyTuple_New(2);
+		if (result == NULL)
+			return NULL;
+	}
+	di->len--;
+	key = ep[i].me_key;
+	value = ep[i].me_value;
+	Py_INCREF(key);
+	Py_INCREF(value);
+	PyTuple_SET_ITEM(result, 0, key);
+	PyTuple_SET_ITEM(result, 1, value);
+	return result;
+
+fail:
+	Py_DECREF(d);
+	di->di_dict = NULL;
+	return NULL;
+}
+
+PyTypeObject PyDictIterItem_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,					/* ob_size */
+	"dictionary-itemiterator",		/* tp_name */
+	sizeof(dictiterobject),			/* tp_basicsize */
+	0,					/* tp_itemsize */
+	/* methods */
+	(destructor)dictiter_dealloc, 		/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	0,					/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT,			/* tp_flags */
+ 	0,					/* tp_doc */
+ 	0,					/* tp_traverse */
+ 	0,					/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	PyObject_SelfIter,			/* tp_iter */
+	(iternextfunc)dictiter_iternextitem,	/* tp_iternext */
+	dictiter_methods,			/* tp_methods */
+	0,
+};

Added: vendor/Python/current/Objects/enumobject.c
===================================================================
--- vendor/Python/current/Objects/enumobject.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Objects/enumobject.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,298 @@
+/* enumerate object */
+
+#include "Python.h"
+
+typedef struct {
+	PyObject_HEAD
+	long      en_index;        /* current index of enumeration */
+	PyObject* en_sit;          /* secondary iterator of enumeration */
+	PyObject* en_result;	   /* result tuple  */
+} enumobject;
+
+static PyObject *
+enum_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	enumobject *en;
+	PyObject *seq = NULL;
+	static char *kwlist[] = {"sequence", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:enumerate", kwlist,
+					 &seq))
+		return NULL;
+
+	en = (enumobject *)type->tp_alloc(type, 0);
+	if (en == NULL)
+		return NULL;
+	en->en_index = 0;
+	en->en_sit = PyObject_GetIter(seq);
+	if (en->en_sit == NULL) {
+		Py_DECREF(en);
+		return NULL;
+	}
+	en->en_result = PyTuple_Pack(2, Py_None, Py_None);
+	if (en->en_result == NULL) {
+		Py_DECREF(en);
+		return NULL;
+	}
+	return (PyObject *)en;
+}
+
+static void
+enum_dealloc(enumobject *en)
+{
+	PyObject_GC_UnTrack(en);
+	Py_XDECREF(en->en_sit);
+	Py_XDECREF(en->en_result);
+	en->ob_type->tp_free(en);
+}
+
+static int
+enum_traverse(enumobject *en, visitproc visit, void *arg)
+{
+	Py_VISIT(en->en_sit);
+	Py_VISIT(en->en_result);
+	return 0;
+}
+
+static PyObject *
+enum_next(enumobject *en)
+{
+	PyObject *next_index;
+	PyObject *next_item;
+	PyObject *result = en->en_result;
+	PyObject *it = en->en_sit;
+
+	if (en->en_index == LONG_MAX) {
+		PyErr_SetString(PyExc_OverflowError,
+			"enumerate() is limited to LONG_MAX items");                
+		return NULL;         
+	}
+
+	next_item = (*it->ob_type->tp_iternext)(it);
+	if (next_item == NULL)
+		return NULL;
+
+	next_index = PyInt_FromLong(en->en_index);
+	if (next_index == NULL) {
+		Py_DECREF(next_item);
+		return NULL;
+	}
+	en->en_index++;
+
+	if (result->ob_refcnt == 1) {
+		Py_INCREF(result);
+		Py_DECREF(PyTuple_GET_ITEM(result, 0));
+		Py_DECREF(PyTuple_GET_ITEM(result, 1));
+	} else {
+		result = PyTuple_New(2);
+		if (result == NULL) {
+			Py_DECREF(next_index);
+			Py_DECREF(next_item);
+			return NULL;
+		}
+	}
+	PyTuple_SET_ITEM(result, 0, next_index);
+	PyTuple_SET_ITEM(result, 1, next_item);
+	return result;
+}
+
+PyDoc_STRVAR(enum_doc,
+"enumerate(iterable) -> iterator for index, value of iterable\n"
+"\n"
+"Return an enumerate object.  iterable must be an other object that supports\n"
+"iteration.  The enumerate object yields pairs containing a count (from\n"
+"zero) and a value yielded by the iterable argument.  enumerate is useful\n"
+"for obtaining an indexed list: (0, seq[0]), (1, seq[1]), (2, seq[2]), ...");
+
+PyTypeObject PyEnum_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,                              /* ob_size */
+	"enumerate",                    /* tp_name */
+	sizeof(enumobject),             /* tp_basicsize */
+	0,                              /* tp_itemsize */
+	/* methods */
+	(destructor)enum_dealloc,       /* tp_dealloc */
+	0,                              /* tp_print */
+	0,                              /* tp_getattr */
+	0,                              /* tp_setattr */
+	0,                              /* tp_compare */
+	0,                              /* tp_repr */
+	0,                              /* tp_as_number */
+	0,                              /* tp_as_sequence */
+	0,                              /* tp_as_mapping */
+	0,                              /* tp_hash */
+	0,                              /* tp_call */
+	0,                              /* tp_str */
+	PyObject_GenericGetAttr,        /* tp_getattro */
+	0,                              /* tp_setattro */
+	0,                              /* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+		Py_TPFLAGS_BASETYPE,    /* tp_flags */
+	enum_doc,                       /* tp_doc */
+	(traverseproc)enum_traverse,    /* tp_traverse */
+	0,                              /* tp_clear */
+	0,                              /* tp_richcompare */
+	0,                              /* tp_weaklistoffset */
+	PyObject_SelfIter,		/* tp_iter */
+	(iternextfunc)enum_next,        /* tp_iternext */
+	0,                              /* tp_methods */
+	0,                              /* tp_members */
+	0,                              /* tp_getset */
+	0,                              /* tp_base */
+	0,                              /* tp_dict */
+	0,                              /* tp_descr_get */
+	0,                              /* tp_descr_set */
+	0,                              /* tp_dictoffset */
+	0,                              /* tp_init */
+	PyType_GenericAlloc,            /* tp_alloc */
+	enum_new,                       /* tp_new */
+	PyObject_GC_Del,                /* tp_free */
+};
+
+/* Reversed Object ***************************************************************/
+
+typedef struct {
+	PyObject_HEAD
+	Py_ssize_t      index;
+	PyObject* seq;
+} reversedobject;
+
+static PyObject *
+reversed_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	Py_ssize_t n;
+	PyObject *seq;
+	reversedobject *ro;
+
+	if (!PyArg_UnpackTuple(args, "reversed", 1, 1, &seq))
+		return NULL;
+
+	if (PyObject_HasAttrString(seq, "__reversed__"))
+		return PyObject_CallMethod(seq, "__reversed__", NULL);
+
+	if (!PySequence_Check(seq)) {
+		PyErr_SetString(PyExc_TypeError,
+				"argument to reversed() must be a sequence");
+		return NULL;
+	}
+
+	n = PySequence_Size(seq);
+	if (n == -1)
+		return NULL;
+
+	ro = (reversedobject *)type->tp_alloc(type, 0);
+	if (ro == NULL)
+		return NULL;
+
+	ro->index = n-1;
+	Py_INCREF(seq);
+	ro->seq = seq;
+	return (PyObject *)ro;
+}
+
+static void
+reversed_dealloc(reversedobject *ro)
+{
+	PyObject_GC_UnTrack(ro);
+	Py_XDECREF(ro->seq);
+	ro->ob_type->tp_free(ro);
+}
+
+static int
+reversed_traverse(reversedobject *ro, visitproc visit, void *arg)
+{
+	Py_VISIT(ro->seq);
+	return 0;
+}
+
+static PyObject *
+reversed_next(reversedobject *ro)
+{
+	PyObject *item;
+	Py_ssize_t index = ro->index;
+
+	if (index >= 0) {
+		item = PySequence_GetItem(ro->seq, index);
+		if (item != NULL) {
+			ro->index--;
+			return item;
+		}
+		if (PyErr_ExceptionMatches(PyExc_IndexError) ||
+		    PyErr_ExceptionMatches(PyExc_StopIteration))
+			PyErr_Clear();
+	}
+	ro->index = -1;
+	Py_CLEAR(ro->seq);
+	return NULL;
+}
+
+PyDoc_STRVAR(reversed_doc,
+"reversed(sequence) -> reverse iterator over values of the sequence\n"
+"\n"
+"Return a reverse iterator");
+
+static PyObject *
+reversed_len(reversedobject *ro)
+{
+	Py_ssize_t position, seqsize;
+
+	if (ro->seq == NULL)
+		return PyInt_FromLong(0);
+	seqsize = PySequence_Size(ro->seq);
+	if (seqsize == -1)
+		return NULL;
+	position = ro->index + 1;
+	return PyInt_FromSsize_t((seqsize < position)  ?  0  :  position);
+}
+
+PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
+
+static PyMethodDef reversediter_methods[] = {
+	{"__length_hint__", (PyCFunction)reversed_len, METH_NOARGS, length_hint_doc},
+ 	{NULL,		NULL}		/* sentinel */
+};
+
+PyTypeObject PyReversed_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,                              /* ob_size */
+	"reversed",                     /* tp_name */
+	sizeof(reversedobject),         /* tp_basicsize */
+	0,                              /* tp_itemsize */
+	/* methods */
+	(destructor)reversed_dealloc,   /* tp_dealloc */
+	0,                              /* tp_print */
+	0,                              /* tp_getattr */
+	0,                              /* tp_setattr */
+	0,                              /* tp_compare */
+	0,                              /* tp_repr */
+	0,                              /* tp_as_number */
+	0,				/* tp_as_sequence */
+	0,                              /* tp_as_mapping */
+	0,                              /* tp_hash */
+	0,                              /* tp_call */
+	0,                              /* tp_str */
+	PyObject_GenericGetAttr,        /* tp_getattro */
+	0,                              /* tp_setattro */
+	0,                              /* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+		Py_TPFLAGS_BASETYPE,    /* tp_flags */
+	reversed_doc,                   /* tp_doc */
+	(traverseproc)reversed_traverse,/* tp_traverse */
+	0,                              /* tp_clear */
+	0,                              /* tp_richcompare */
+	0,                              /* tp_weaklistoffset */
+	PyObject_SelfIter,		/* tp_iter */
+	(iternextfunc)reversed_next,    /* tp_iternext */
+	reversediter_methods,		/* tp_methods */
+	0,                              /* tp_members */
+	0,                              /* tp_getset */
+	0,                              /* tp_base */
+	0,                              /* tp_dict */
+	0,                              /* tp_descr_get */
+	0,                              /* tp_descr_set */
+	0,                              /* tp_dictoffset */
+	0,                              /* tp_init */
+	PyType_GenericAlloc,            /* tp_alloc */
+	reversed_new,                   /* tp_new */
+	PyObject_GC_Del,                /* tp_free */
+};

Added: vendor/Python/current/Objects/exceptions.c
===================================================================
--- vendor/Python/current/Objects/exceptions.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Objects/exceptions.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2147 @@
+/*
+ * New exceptions.c written in Iceland by Richard Jones and Georg Brandl.
+ *
+ * Thanks go to Tim Peters and Michael Hudson for debugging.
+ */
+
+#define PY_SSIZE_T_CLEAN
+#include <Python.h>
+#include "structmember.h"
+#include "osdefs.h"
+
+#define MAKE_IT_NONE(x) (x) = Py_None; Py_INCREF(Py_None);
+#define EXC_MODULE_NAME "exceptions."
+
+/* NOTE: If the exception class hierarchy changes, don't forget to update
+ * Lib/test/exception_hierarchy.txt
+ */
+
+PyDoc_STRVAR(exceptions_doc, "Python's standard exception class hierarchy.\n\
+\n\
+Exceptions found here are defined both in the exceptions module and the\n\
+built-in namespace.  It is recommended that user-defined exceptions\n\
+inherit from Exception.  See the documentation for the exception\n\
+inheritance hierarchy.\n\
+");
+
+/*
+ *    BaseException
+ */
+static PyObject *
+BaseException_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    PyBaseExceptionObject *self;
+
+    self = (PyBaseExceptionObject *)type->tp_alloc(type, 0);
+    /* the dict is created on the fly in PyObject_GenericSetAttr */
+    self->message = self->dict = NULL;
+
+    self->args = PyTuple_New(0);
+    if (!self->args) {
+        Py_DECREF(self);
+        return NULL;
+    }
+
+    self->message = PyString_FromString("");
+    if (!self->message) {
+        Py_DECREF(self);
+        return NULL;
+    }
+
+    return (PyObject *)self;
+}
+
+static int
+BaseException_init(PyBaseExceptionObject *self, PyObject *args, PyObject *kwds)
+{
+    if (!_PyArg_NoKeywords(self->ob_type->tp_name, kwds))
+        return -1;
+
+    Py_DECREF(self->args);
+    self->args = args;
+    Py_INCREF(self->args);
+
+    if (PyTuple_GET_SIZE(self->args) == 1) {
+        Py_CLEAR(self->message);
+        self->message = PyTuple_GET_ITEM(self->args, 0);
+        Py_INCREF(self->message);
+    }
+    return 0;
+}
+
+static int
+BaseException_clear(PyBaseExceptionObject *self)
+{
+    Py_CLEAR(self->dict);
+    Py_CLEAR(self->args);
+    Py_CLEAR(self->message);
+    return 0;
+}
+
+static void
+BaseException_dealloc(PyBaseExceptionObject *self)
+{
+    _PyObject_GC_UNTRACK(self);
+    BaseException_clear(self);
+    self->ob_type->tp_free((PyObject *)self);
+}
+
+static int
+BaseException_traverse(PyBaseExceptionObject *self, visitproc visit, void *arg)
+{
+    Py_VISIT(self->dict);
+    Py_VISIT(self->args);
+    Py_VISIT(self->message);
+    return 0;
+}
+
+static PyObject *
+BaseException_str(PyBaseExceptionObject *self)
+{
+    PyObject *out;
+
+    switch (PyTuple_GET_SIZE(self->args)) {
+    case 0:
+        out = PyString_FromString("");
+        break;
+    case 1:
+        out = PyObject_Str(PyTuple_GET_ITEM(self->args, 0));
+        break;
+    default:
+        out = PyObject_Str(self->args);
+        break;
+    }
+
+    return out;
+}
+
+static PyObject *
+BaseException_repr(PyBaseExceptionObject *self)
+{
+    PyObject *repr_suffix;
+    PyObject *repr;
+    char *name;
+    char *dot;
+
+    repr_suffix = PyObject_Repr(self->args);
+    if (!repr_suffix)
+        return NULL;
+
+    name = (char *)self->ob_type->tp_name;
+    dot = strrchr(name, '.');
+    if (dot != NULL) name = dot+1;
+
+    repr = PyString_FromString(name);
+    if (!repr) {
+        Py_DECREF(repr_suffix);
+        return NULL;
+    }
+
+    PyString_ConcatAndDel(&repr, repr_suffix);
+    return repr;
+}
+
+/* Pickling support */
+static PyObject *
+BaseException_reduce(PyBaseExceptionObject *self)
+{
+    if (self->args && self->dict)
+        return PyTuple_Pack(3, self->ob_type, self->args, self->dict);
+    else
+        return PyTuple_Pack(2, self->ob_type, self->args);
+}
+
+/*
+ * Needed for backward compatibility, since exceptions used to store
+ * all their attributes in the __dict__. Code is taken from cPickle's
+ * load_build function.
+ */
+static PyObject *
+BaseException_setstate(PyObject *self, PyObject *state)
+{
+    PyObject *d_key, *d_value;
+    Py_ssize_t i = 0;
+
+    if (state != Py_None) {
+        if (!PyDict_Check(state)) {
+            PyErr_SetString(PyExc_TypeError, "state is not a dictionary");
+            return NULL;
+        }
+        while (PyDict_Next(state, &i, &d_key, &d_value)) {
+            if (PyObject_SetAttr(self, d_key, d_value) < 0)
+                return NULL;
+        }
+    }
+    Py_RETURN_NONE;
+}
+
+
+static PyMethodDef BaseException_methods[] = {
+   {"__reduce__", (PyCFunction)BaseException_reduce, METH_NOARGS },
+   {"__setstate__", (PyCFunction)BaseException_setstate, METH_O },
+   {NULL, NULL, 0, NULL},
+};
+
+
+
+static PyObject *
+BaseException_getitem(PyBaseExceptionObject *self, Py_ssize_t index)
+{
+    return PySequence_GetItem(self->args, index);
+}
+
+static PyObject *
+BaseException_getslice(PyBaseExceptionObject *self,
+			Py_ssize_t start, Py_ssize_t stop)
+{
+    return PySequence_GetSlice(self->args, start, stop);
+}
+
+static PySequenceMethods BaseException_as_sequence = {
+    0,                      /* sq_length; */
+    0,                      /* sq_concat; */
+    0,                      /* sq_repeat; */
+    (ssizeargfunc)BaseException_getitem,  /* sq_item; */
+    (ssizessizeargfunc)BaseException_getslice,  /* sq_slice; */
+    0,                      /* sq_ass_item; */
+    0,                      /* sq_ass_slice; */
+    0,                      /* sq_contains; */
+    0,                      /* sq_inplace_concat; */
+    0                       /* sq_inplace_repeat; */
+};
+
+static PyMemberDef BaseException_members[] = {
+    {"message", T_OBJECT, offsetof(PyBaseExceptionObject, message), 0,
+        PyDoc_STR("exception message")},
+    {NULL}  /* Sentinel */
+};
+
+
+static PyObject *
+BaseException_get_dict(PyBaseExceptionObject *self)
+{
+    if (self->dict == NULL) {
+        self->dict = PyDict_New();
+        if (!self->dict)
+            return NULL;
+    }
+    Py_INCREF(self->dict);
+    return self->dict;
+}
+
+static int
+BaseException_set_dict(PyBaseExceptionObject *self, PyObject *val)
+{
+    if (val == NULL) {
+        PyErr_SetString(PyExc_TypeError, "__dict__ may not be deleted");
+        return -1;
+    }
+    if (!PyDict_Check(val)) {
+        PyErr_SetString(PyExc_TypeError, "__dict__ must be a dictionary");
+        return -1;
+    }
+    Py_CLEAR(self->dict);
+    Py_INCREF(val);
+    self->dict = val;
+    return 0;
+}
+
+static PyObject *
+BaseException_get_args(PyBaseExceptionObject *self)
+{
+    if (self->args == NULL) {
+        Py_INCREF(Py_None);
+        return Py_None;
+    }
+    Py_INCREF(self->args);
+    return self->args;
+}
+
+static int
+BaseException_set_args(PyBaseExceptionObject *self, PyObject *val)
+{
+    PyObject *seq;
+    if (val == NULL) {
+        PyErr_SetString(PyExc_TypeError, "args may not be deleted");
+        return -1;
+    }
+    seq = PySequence_Tuple(val);
+    if (!seq) return -1;
+    Py_CLEAR(self->args);
+    self->args = seq;
+    return 0;
+}
+
+static PyGetSetDef BaseException_getset[] = {
+    {"__dict__", (getter)BaseException_get_dict, (setter)BaseException_set_dict},
+    {"args", (getter)BaseException_get_args, (setter)BaseException_set_args},
+    {NULL},
+};
+
+
+static PyTypeObject _PyExc_BaseException = {
+    PyObject_HEAD_INIT(NULL)
+    0,                          /*ob_size*/
+    EXC_MODULE_NAME "BaseException", /*tp_name*/
+    sizeof(PyBaseExceptionObject), /*tp_basicsize*/
+    0,                          /*tp_itemsize*/
+    (destructor)BaseException_dealloc, /*tp_dealloc*/
+    0,                          /*tp_print*/
+    0,                          /*tp_getattr*/
+    0,                          /*tp_setattr*/
+    0,                          /* tp_compare; */
+    (reprfunc)BaseException_repr, /*tp_repr*/
+    0,                          /*tp_as_number*/
+    &BaseException_as_sequence, /*tp_as_sequence*/
+    0,                          /*tp_as_mapping*/
+    0,                          /*tp_hash */
+    0,                          /*tp_call*/
+    (reprfunc)BaseException_str,  /*tp_str*/
+    PyObject_GenericGetAttr,    /*tp_getattro*/
+    PyObject_GenericSetAttr,    /*tp_setattro*/
+    0,                          /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,  /*tp_flags*/
+    PyDoc_STR("Common base class for all exceptions"), /* tp_doc */
+    (traverseproc)BaseException_traverse, /* tp_traverse */
+    (inquiry)BaseException_clear, /* tp_clear */
+    0,                          /* tp_richcompare */
+    0,                          /* tp_weaklistoffset */
+    0,                          /* tp_iter */
+    0,                          /* tp_iternext */
+    BaseException_methods,      /* tp_methods */
+    BaseException_members,      /* tp_members */
+    BaseException_getset,       /* tp_getset */
+    0,                          /* tp_base */
+    0,                          /* tp_dict */
+    0,                          /* tp_descr_get */
+    0,                          /* tp_descr_set */
+    offsetof(PyBaseExceptionObject, dict), /* tp_dictoffset */
+    (initproc)BaseException_init, /* tp_init */
+    0,                          /* tp_alloc */
+    BaseException_new,          /* tp_new */
+};
+/* the CPython API expects exceptions to be (PyObject *) - both a hold-over
+from the previous implmentation and also allowing Python objects to be used
+in the API */
+PyObject *PyExc_BaseException = (PyObject *)&_PyExc_BaseException;
+
+/* note these macros omit the last semicolon so the macro invocation may
+ * include it and not look strange.
+ */
+#define SimpleExtendsException(EXCBASE, EXCNAME, EXCDOC) \
+static PyTypeObject _PyExc_ ## EXCNAME = { \
+    PyObject_HEAD_INIT(NULL) \
+    0, \
+    EXC_MODULE_NAME # EXCNAME, \
+    sizeof(PyBaseExceptionObject), \
+    0, (destructor)BaseException_dealloc, 0, 0, 0, 0, 0, 0, 0, \
+    0, 0, 0, 0, 0, 0, 0, \
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
+    PyDoc_STR(EXCDOC), (traverseproc)BaseException_traverse, \
+    (inquiry)BaseException_clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
+    0, 0, 0, offsetof(PyBaseExceptionObject, dict), \
+    (initproc)BaseException_init, 0, BaseException_new,\
+}; \
+PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
+
+#define MiddlingExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDOC) \
+static PyTypeObject _PyExc_ ## EXCNAME = { \
+    PyObject_HEAD_INIT(NULL) \
+    0, \
+    EXC_MODULE_NAME # EXCNAME, \
+    sizeof(Py ## EXCSTORE ## Object), \
+    0, (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+    0, 0, 0, 0, 0, \
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
+    PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
+    (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
+    0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
+    (initproc)EXCSTORE ## _init, 0, BaseException_new,\
+}; \
+PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
+
+#define ComplexExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDEALLOC, EXCMETHODS, EXCMEMBERS, EXCSTR, EXCDOC) \
+static PyTypeObject _PyExc_ ## EXCNAME = { \
+    PyObject_HEAD_INIT(NULL) \
+    0, \
+    EXC_MODULE_NAME # EXCNAME, \
+    sizeof(Py ## EXCSTORE ## Object), 0, \
+    (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+    (reprfunc)EXCSTR, 0, 0, 0, \
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
+    PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
+    (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, EXCMETHODS, \
+    EXCMEMBERS, 0, &_ ## EXCBASE, \
+    0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
+    (initproc)EXCSTORE ## _init, 0, BaseException_new,\
+}; \
+PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
+
+
+/*
+ *    Exception extends BaseException
+ */
+SimpleExtendsException(PyExc_BaseException, Exception,
+                       "Common base class for all non-exit exceptions.");
+
+
+/*
+ *    StandardError extends Exception
+ */
+SimpleExtendsException(PyExc_Exception, StandardError,
+    "Base class for all standard Python exceptions that do not represent\n"
+    "interpreter exiting.");
+
+
+/*
+ *    TypeError extends StandardError
+ */
+SimpleExtendsException(PyExc_StandardError, TypeError,
+                       "Inappropriate argument type.");
+
+
+/*
+ *    StopIteration extends Exception
+ */
+SimpleExtendsException(PyExc_Exception, StopIteration,
+                       "Signal the end from iterator.next().");
+
+
+/*
+ *    GeneratorExit extends Exception
+ */
+SimpleExtendsException(PyExc_Exception, GeneratorExit,
+                       "Request that a generator exit.");
+
+
+/*
+ *    SystemExit extends BaseException
+ */
+
+static int
+SystemExit_init(PySystemExitObject *self, PyObject *args, PyObject *kwds)
+{
+    Py_ssize_t size = PyTuple_GET_SIZE(args);
+
+    if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
+        return -1;
+
+    if (size == 0)
+        return 0;
+    Py_CLEAR(self->code);
+    if (size == 1)
+        self->code = PyTuple_GET_ITEM(args, 0);
+    else if (size > 1)
+        self->code = args;
+    Py_INCREF(self->code);
+    return 0;
+}
+
+static int
+SystemExit_clear(PySystemExitObject *self)
+{
+    Py_CLEAR(self->code);
+    return BaseException_clear((PyBaseExceptionObject *)self);
+}
+
+static void
+SystemExit_dealloc(PySystemExitObject *self)
+{
+    _PyObject_GC_UNTRACK(self);
+    SystemExit_clear(self);
+    self->ob_type->tp_free((PyObject *)self);
+}
+
+static int
+SystemExit_traverse(PySystemExitObject *self, visitproc visit, void *arg)
+{
+    Py_VISIT(self->code);
+    return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
+}
+
+static PyMemberDef SystemExit_members[] = {
+    {"message", T_OBJECT, offsetof(PySystemExitObject, message), 0,
+        PyDoc_STR("exception message")},
+    {"code", T_OBJECT, offsetof(PySystemExitObject, code), 0,
+        PyDoc_STR("exception code")},
+    {NULL}  /* Sentinel */
+};
+
+ComplexExtendsException(PyExc_BaseException, SystemExit, SystemExit,
+                        SystemExit_dealloc, 0, SystemExit_members, 0,
+                        "Request to exit from the interpreter.");
+
+/*
+ *    KeyboardInterrupt extends BaseException
+ */
+SimpleExtendsException(PyExc_BaseException, KeyboardInterrupt,
+                       "Program interrupted by user.");
+
+
+/*
+ *    ImportError extends StandardError
+ */
+SimpleExtendsException(PyExc_StandardError, ImportError,
+          "Import can't find module, or can't find name in module.");
+
+
+/*
+ *    EnvironmentError extends StandardError
+ */
+
+/* Where a function has a single filename, such as open() or some
+ * of the os module functions, PyErr_SetFromErrnoWithFilename() is
+ * called, giving a third argument which is the filename.  But, so
+ * that old code using in-place unpacking doesn't break, e.g.:
+ *
+ * except IOError, (errno, strerror):
+ *
+ * we hack args so that it only contains two items.  This also
+ * means we need our own __str__() which prints out the filename
+ * when it was supplied.
+ */
+static int
+EnvironmentError_init(PyEnvironmentErrorObject *self, PyObject *args,
+    PyObject *kwds)
+{
+    PyObject *myerrno = NULL, *strerror = NULL, *filename = NULL;
+    PyObject *subslice = NULL;
+
+    if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
+        return -1;
+
+    if (PyTuple_GET_SIZE(args) <= 1 || PyTuple_GET_SIZE(args) > 3) {
+        return 0;
+    }
+
+    if (!PyArg_UnpackTuple(args, "EnvironmentError", 2, 3,
+                           &myerrno, &strerror, &filename)) {
+        return -1;
+    }
+    Py_CLEAR(self->myerrno);       /* replacing */
+    self->myerrno = myerrno;
+    Py_INCREF(self->myerrno);
+
+    Py_CLEAR(self->strerror);      /* replacing */
+    self->strerror = strerror;
+    Py_INCREF(self->strerror);
+
+    /* self->filename will remain Py_None otherwise */
+    if (filename != NULL) {
+        Py_CLEAR(self->filename);      /* replacing */
+        self->filename = filename;
+        Py_INCREF(self->filename);
+
+        subslice = PyTuple_GetSlice(args, 0, 2);
+        if (!subslice)
+            return -1;
+
+        Py_DECREF(self->args);  /* replacing args */
+        self->args = subslice;
+    }
+    return 0;
+}
+
+static int
+EnvironmentError_clear(PyEnvironmentErrorObject *self)
+{
+    Py_CLEAR(self->myerrno);
+    Py_CLEAR(self->strerror);
+    Py_CLEAR(self->filename);
+    return BaseException_clear((PyBaseExceptionObject *)self);
+}
+
+static void
+EnvironmentError_dealloc(PyEnvironmentErrorObject *self)
+{
+    _PyObject_GC_UNTRACK(self);
+    EnvironmentError_clear(self);
+    self->ob_type->tp_free((PyObject *)self);
+}
+
+static int
+EnvironmentError_traverse(PyEnvironmentErrorObject *self, visitproc visit,
+        void *arg)
+{
+    Py_VISIT(self->myerrno);
+    Py_VISIT(self->strerror);
+    Py_VISIT(self->filename);
+    return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
+}
+
+static PyObject *
+EnvironmentError_str(PyEnvironmentErrorObject *self)
+{
+    PyObject *rtnval = NULL;
+
+    if (self->filename) {
+        PyObject *fmt;
+        PyObject *repr;
+        PyObject *tuple;
+
+        fmt = PyString_FromString("[Errno %s] %s: %s");
+        if (!fmt)
+            return NULL;
+
+        repr = PyObject_Repr(self->filename);
+        if (!repr) {
+            Py_DECREF(fmt);
+            return NULL;
+        }
+        tuple = PyTuple_New(3);
+        if (!tuple) {
+            Py_DECREF(repr);
+            Py_DECREF(fmt);
+            return NULL;
+        }
+
+        if (self->myerrno) {
+            Py_INCREF(self->myerrno);
+            PyTuple_SET_ITEM(tuple, 0, self->myerrno);
+        }
+        else {
+            Py_INCREF(Py_None);
+            PyTuple_SET_ITEM(tuple, 0, Py_None);
+        }
+        if (self->strerror) {
+            Py_INCREF(self->strerror);
+            PyTuple_SET_ITEM(tuple, 1, self->strerror);
+        }
+        else {
+            Py_INCREF(Py_None);
+            PyTuple_SET_ITEM(tuple, 1, Py_None);
+        }
+
+        PyTuple_SET_ITEM(tuple, 2, repr);
+
+        rtnval = PyString_Format(fmt, tuple);
+
+        Py_DECREF(fmt);
+        Py_DECREF(tuple);
+    }
+    else if (self->myerrno && self->strerror) {
+        PyObject *fmt;
+        PyObject *tuple;
+
+        fmt = PyString_FromString("[Errno %s] %s");
+        if (!fmt)
+            return NULL;
+
+        tuple = PyTuple_New(2);
+        if (!tuple) {
+            Py_DECREF(fmt);
+            return NULL;
+        }
+
+        if (self->myerrno) {
+            Py_INCREF(self->myerrno);
+            PyTuple_SET_ITEM(tuple, 0, self->myerrno);
+        }
+        else {
+            Py_INCREF(Py_None);
+            PyTuple_SET_ITEM(tuple, 0, Py_None);
+        }
+        if (self->strerror) {
+            Py_INCREF(self->strerror);
+            PyTuple_SET_ITEM(tuple, 1, self->strerror);
+        }
+        else {
+            Py_INCREF(Py_None);
+            PyTuple_SET_ITEM(tuple, 1, Py_None);
+        }
+
+        rtnval = PyString_Format(fmt, tuple);
+
+        Py_DECREF(fmt);
+        Py_DECREF(tuple);
+    }
+    else
+        rtnval = BaseException_str((PyBaseExceptionObject *)self);
+
+    return rtnval;
+}
+
+static PyMemberDef EnvironmentError_members[] = {
+    {"message", T_OBJECT, offsetof(PyEnvironmentErrorObject, message), 0,
+        PyDoc_STR("exception message")},
+    {"errno", T_OBJECT, offsetof(PyEnvironmentErrorObject, myerrno), 0,
+        PyDoc_STR("exception errno")},
+    {"strerror", T_OBJECT, offsetof(PyEnvironmentErrorObject, strerror), 0,
+        PyDoc_STR("exception strerror")},
+    {"filename", T_OBJECT, offsetof(PyEnvironmentErrorObject, filename), 0,
+        PyDoc_STR("exception filename")},
+    {NULL}  /* Sentinel */
+};
+
+
+static PyObject *
+EnvironmentError_reduce(PyEnvironmentErrorObject *self)
+{
+    PyObject *args = self->args;
+    PyObject *res = NULL, *tmp;
+
+    /* self->args is only the first two real arguments if there was a
+     * file name given to EnvironmentError. */
+    if (PyTuple_GET_SIZE(args) == 2 && self->filename) {
+        args = PyTuple_New(3);
+        if (!args) return NULL;
+
+        tmp = PyTuple_GET_ITEM(self->args, 0);
+        Py_INCREF(tmp);
+        PyTuple_SET_ITEM(args, 0, tmp);
+
+        tmp = PyTuple_GET_ITEM(self->args, 1);
+        Py_INCREF(tmp);
+        PyTuple_SET_ITEM(args, 1, tmp);
+
+        Py_INCREF(self->filename);
+        PyTuple_SET_ITEM(args, 2, self->filename);
+    } else
+        Py_INCREF(args);
+
+    if (self->dict)
+        res = PyTuple_Pack(3, self->ob_type, args, self->dict);
+    else
+        res = PyTuple_Pack(2, self->ob_type, args);
+    Py_DECREF(args);
+    return res;
+}
+
+
+static PyMethodDef EnvironmentError_methods[] = {
+    {"__reduce__", (PyCFunction)EnvironmentError_reduce, METH_NOARGS},
+    {NULL}
+};
+
+ComplexExtendsException(PyExc_StandardError, EnvironmentError,
+                        EnvironmentError, EnvironmentError_dealloc,
+                        EnvironmentError_methods, EnvironmentError_members,
+                        EnvironmentError_str,
+                        "Base class for I/O related errors.");
+
+
+/*
+ *    IOError extends EnvironmentError
+ */
+MiddlingExtendsException(PyExc_EnvironmentError, IOError,
+                         EnvironmentError, "I/O operation failed.");
+
+
+/*
+ *    OSError extends EnvironmentError
+ */
+MiddlingExtendsException(PyExc_EnvironmentError, OSError,
+                         EnvironmentError, "OS system call failed.");
+
+
+/*
+ *    WindowsError extends OSError
+ */
+#ifdef MS_WINDOWS
+#include "errmap.h"
+
+static int
+WindowsError_clear(PyWindowsErrorObject *self)
+{
+    Py_CLEAR(self->myerrno);
+    Py_CLEAR(self->strerror);
+    Py_CLEAR(self->filename);
+    Py_CLEAR(self->winerror);
+    return BaseException_clear((PyBaseExceptionObject *)self);
+}
+
+static void
+WindowsError_dealloc(PyWindowsErrorObject *self)
+{
+    _PyObject_GC_UNTRACK(self);
+    WindowsError_clear(self);
+    self->ob_type->tp_free((PyObject *)self);
+}
+
+static int
+WindowsError_traverse(PyWindowsErrorObject *self, visitproc visit, void *arg)
+{
+    Py_VISIT(self->myerrno);
+    Py_VISIT(self->strerror);
+    Py_VISIT(self->filename);
+    Py_VISIT(self->winerror);
+    return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
+}
+
+static int
+WindowsError_init(PyWindowsErrorObject *self, PyObject *args, PyObject *kwds)
+{
+    PyObject *o_errcode = NULL;
+    long errcode;
+    long posix_errno;
+
+    if (EnvironmentError_init((PyEnvironmentErrorObject *)self, args, kwds)
+            == -1)
+        return -1;
+
+    if (self->myerrno == NULL)
+        return 0;
+
+    /* Set errno to the POSIX errno, and winerror to the Win32
+       error code. */
+    errcode = PyInt_AsLong(self->myerrno);
+    if (errcode == -1 && PyErr_Occurred())
+        return -1;
+    posix_errno = winerror_to_errno(errcode);
+
+    Py_CLEAR(self->winerror);
+    self->winerror = self->myerrno;
+
+    o_errcode = PyInt_FromLong(posix_errno);
+    if (!o_errcode)
+        return -1;
+
+    self->myerrno = o_errcode;
+
+    return 0;
+}
+
+
+static PyObject *
+WindowsError_str(PyWindowsErrorObject *self)
+{
+    PyObject *rtnval = NULL;
+
+    if (self->filename) {
+        PyObject *fmt;
+        PyObject *repr;
+        PyObject *tuple;
+
+        fmt = PyString_FromString("[Error %s] %s: %s");
+        if (!fmt)
+            return NULL;
+
+        repr = PyObject_Repr(self->filename);
+        if (!repr) {
+            Py_DECREF(fmt);
+            return NULL;
+        }
+        tuple = PyTuple_New(3);
+        if (!tuple) {
+            Py_DECREF(repr);
+            Py_DECREF(fmt);
+            return NULL;
+        }
+
+        if (self->winerror) {
+            Py_INCREF(self->winerror);
+            PyTuple_SET_ITEM(tuple, 0, self->winerror);
+        }
+        else {
+            Py_INCREF(Py_None);
+            PyTuple_SET_ITEM(tuple, 0, Py_None);
+        }
+        if (self->strerror) {
+            Py_INCREF(self->strerror);
+            PyTuple_SET_ITEM(tuple, 1, self->strerror);
+        }
+        else {
+            Py_INCREF(Py_None);
+            PyTuple_SET_ITEM(tuple, 1, Py_None);
+        }
+
+        PyTuple_SET_ITEM(tuple, 2, repr);
+
+        rtnval = PyString_Format(fmt, tuple);
+
+        Py_DECREF(fmt);
+        Py_DECREF(tuple);
+    }
+    else if (self->winerror && self->strerror) {
+        PyObject *fmt;
+        PyObject *tuple;
+
+        fmt = PyString_FromString("[Error %s] %s");
+        if (!fmt)
+            return NULL;
+
+        tuple = PyTuple_New(2);
+        if (!tuple) {
+            Py_DECREF(fmt);
+            return NULL;
+        }
+
+        if (self->winerror) {
+            Py_INCREF(self->winerror);
+            PyTuple_SET_ITEM(tuple, 0, self->winerror);
+        }
+        else {
+            Py_INCREF(Py_None);
+            PyTuple_SET_ITEM(tuple, 0, Py_None);
+        }
+        if (self->strerror) {
+            Py_INCREF(self->strerror);
+            PyTuple_SET_ITEM(tuple, 1, self->strerror);
+        }
+        else {
+            Py_INCREF(Py_None);
+            PyTuple_SET_ITEM(tuple, 1, Py_None);
+        }
+
+        rtnval = PyString_Format(fmt, tuple);
+
+        Py_DECREF(fmt);
+        Py_DECREF(tuple);
+    }
+    else
+        rtnval = EnvironmentError_str((PyEnvironmentErrorObject *)self);
+
+    return rtnval;
+}
+
+static PyMemberDef WindowsError_members[] = {
+    {"message", T_OBJECT, offsetof(PyWindowsErrorObject, message), 0,
+        PyDoc_STR("exception message")},
+    {"errno", T_OBJECT, offsetof(PyWindowsErrorObject, myerrno), 0,
+        PyDoc_STR("POSIX exception code")},
+    {"strerror", T_OBJECT, offsetof(PyWindowsErrorObject, strerror), 0,
+        PyDoc_STR("exception strerror")},
+    {"filename", T_OBJECT, offsetof(PyWindowsErrorObject, filename), 0,
+        PyDoc_STR("exception filename")},
+    {"winerror", T_OBJECT, offsetof(PyWindowsErrorObject, winerror), 0,
+        PyDoc_STR("Win32 exception code")},
+    {NULL}  /* Sentinel */
+};
+
+ComplexExtendsException(PyExc_OSError, WindowsError, WindowsError,
+                        WindowsError_dealloc, 0, WindowsError_members,
+                        WindowsError_str, "MS-Windows OS system call failed.");
+
+#endif /* MS_WINDOWS */
+
+
+/*
+ *    VMSError extends OSError (I think)
+ */
+#ifdef __VMS
+MiddlingExtendsException(PyExc_OSError, VMSError, EnvironmentError,
+                         "OpenVMS OS system call failed.");
+#endif
+
+
+/*
+ *    EOFError extends StandardError
+ */
+SimpleExtendsException(PyExc_StandardError, EOFError,
+                       "Read beyond end of file.");
+
+
+/*
+ *    RuntimeError extends StandardError
+ */
+SimpleExtendsException(PyExc_StandardError, RuntimeError,
+                       "Unspecified run-time error.");
+
+
+/*
+ *    NotImplementedError extends RuntimeError
+ */
+SimpleExtendsException(PyExc_RuntimeError, NotImplementedError,
+                       "Method or function hasn't been implemented yet.");
+
+/*
+ *    NameError extends StandardError
+ */
+SimpleExtendsException(PyExc_StandardError, NameError,
+                       "Name not found globally.");
+
+/*
+ *    UnboundLocalError extends NameError
+ */
+SimpleExtendsException(PyExc_NameError, UnboundLocalError,
+                       "Local name referenced but not bound to a value.");
+
+/*
+ *    AttributeError extends StandardError
+ */
+SimpleExtendsException(PyExc_StandardError, AttributeError,
+                       "Attribute not found.");
+
+
+/*
+ *    SyntaxError extends StandardError
+ */
+
+static int
+SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds)
+{
+    PyObject *info = NULL;
+    Py_ssize_t lenargs = PyTuple_GET_SIZE(args);
+
+    if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
+        return -1;
+
+    if (lenargs >= 1) {
+        Py_CLEAR(self->msg);
+        self->msg = PyTuple_GET_ITEM(args, 0);
+        Py_INCREF(self->msg);
+    }
+    if (lenargs == 2) {
+        info = PyTuple_GET_ITEM(args, 1);
+        info = PySequence_Tuple(info);
+        if (!info) return -1;
+
+        if (PyTuple_GET_SIZE(info) != 4) {
+            /* not a very good error message, but it's what Python 2.4 gives */
+            PyErr_SetString(PyExc_IndexError, "tuple index out of range");
+            Py_DECREF(info);
+            return -1;
+        }
+
+        Py_CLEAR(self->filename);
+        self->filename = PyTuple_GET_ITEM(info, 0);
+        Py_INCREF(self->filename);
+
+        Py_CLEAR(self->lineno);
+        self->lineno = PyTuple_GET_ITEM(info, 1);
+        Py_INCREF(self->lineno);
+
+        Py_CLEAR(self->offset);
+        self->offset = PyTuple_GET_ITEM(info, 2);
+        Py_INCREF(self->offset);
+
+        Py_CLEAR(self->text);
+        self->text = PyTuple_GET_ITEM(info, 3);
+        Py_INCREF(self->text);
+
+        Py_DECREF(info);
+    }
+    return 0;
+}
+
+static int
+SyntaxError_clear(PySyntaxErrorObject *self)
+{
+    Py_CLEAR(self->msg);
+    Py_CLEAR(self->filename);
+    Py_CLEAR(self->lineno);
+    Py_CLEAR(self->offset);
+    Py_CLEAR(self->text);
+    Py_CLEAR(self->print_file_and_line);
+    return BaseException_clear((PyBaseExceptionObject *)self);
+}
+
+static void
+SyntaxError_dealloc(PySyntaxErrorObject *self)
+{
+    _PyObject_GC_UNTRACK(self);
+    SyntaxError_clear(self);
+    self->ob_type->tp_free((PyObject *)self);
+}
+
+static int
+SyntaxError_traverse(PySyntaxErrorObject *self, visitproc visit, void *arg)
+{
+    Py_VISIT(self->msg);
+    Py_VISIT(self->filename);
+    Py_VISIT(self->lineno);
+    Py_VISIT(self->offset);
+    Py_VISIT(self->text);
+    Py_VISIT(self->print_file_and_line);
+    return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
+}
+
+/* This is called "my_basename" instead of just "basename" to avoid name
+   conflicts with glibc; basename is already prototyped if _GNU_SOURCE is
+   defined, and Python does define that. */
+static char *
+my_basename(char *name)
+{
+    char *cp = name;
+    char *result = name;
+
+    if (name == NULL)
+        return "???";
+    while (*cp != '\0') {
+        if (*cp == SEP)
+            result = cp + 1;
+        ++cp;
+    }
+    return result;
+}
+
+
+static PyObject *
+SyntaxError_str(PySyntaxErrorObject *self)
+{
+    PyObject *str;
+    PyObject *result;
+    int have_filename = 0;
+    int have_lineno = 0;
+    char *buffer = NULL;
+    Py_ssize_t bufsize;
+
+    if (self->msg)
+        str = PyObject_Str(self->msg);
+    else
+        str = PyObject_Str(Py_None);
+    if (!str) return NULL;
+    /* Don't fiddle with non-string return (shouldn't happen anyway) */
+    if (!PyString_Check(str)) return str;
+
+    /* XXX -- do all the additional formatting with filename and
+       lineno here */
+
+    have_filename = (self->filename != NULL) &&
+        PyString_Check(self->filename);
+    have_lineno = (self->lineno != NULL) && PyInt_Check(self->lineno);
+
+    if (!have_filename && !have_lineno)
+        return str;
+
+    bufsize = PyString_GET_SIZE(str) + 64;
+    if (have_filename)
+        bufsize += PyString_GET_SIZE(self->filename);
+
+    buffer = PyMem_MALLOC(bufsize);
+    if (buffer == NULL)
+        return str;
+
+    if (have_filename && have_lineno)
+        PyOS_snprintf(buffer, bufsize, "%s (%s, line %ld)",
+            PyString_AS_STRING(str),
+            my_basename(PyString_AS_STRING(self->filename)),
+            PyInt_AsLong(self->lineno));
+    else if (have_filename)
+        PyOS_snprintf(buffer, bufsize, "%s (%s)",
+            PyString_AS_STRING(str),
+            my_basename(PyString_AS_STRING(self->filename)));
+    else /* only have_lineno */
+        PyOS_snprintf(buffer, bufsize, "%s (line %ld)",
+            PyString_AS_STRING(str),
+            PyInt_AsLong(self->lineno));
+
+    result = PyString_FromString(buffer);
+    PyMem_FREE(buffer);
+
+    if (result == NULL)
+        result = str;
+    else
+        Py_DECREF(str);
+    return result;
+}
+
+static PyMemberDef SyntaxError_members[] = {
+    {"message", T_OBJECT, offsetof(PySyntaxErrorObject, message), 0,
+        PyDoc_STR("exception message")},
+    {"msg", T_OBJECT, offsetof(PySyntaxErrorObject, msg), 0,
+        PyDoc_STR("exception msg")},
+    {"filename", T_OBJECT, offsetof(PySyntaxErrorObject, filename), 0,
+        PyDoc_STR("exception filename")},
+    {"lineno", T_OBJECT, offsetof(PySyntaxErrorObject, lineno), 0,
+        PyDoc_STR("exception lineno")},
+    {"offset", T_OBJECT, offsetof(PySyntaxErrorObject, offset), 0,
+        PyDoc_STR("exception offset")},
+    {"text", T_OBJECT, offsetof(PySyntaxErrorObject, text), 0,
+        PyDoc_STR("exception text")},
+    {"print_file_and_line", T_OBJECT,
+        offsetof(PySyntaxErrorObject, print_file_and_line), 0,
+        PyDoc_STR("exception print_file_and_line")},
+    {NULL}  /* Sentinel */
+};
+
+ComplexExtendsException(PyExc_StandardError, SyntaxError, SyntaxError,
+                        SyntaxError_dealloc, 0, SyntaxError_members,
+                        SyntaxError_str, "Invalid syntax.");
+
+
+/*
+ *    IndentationError extends SyntaxError
+ */
+MiddlingExtendsException(PyExc_SyntaxError, IndentationError, SyntaxError,
+                         "Improper indentation.");
+
+
+/*
+ *    TabError extends IndentationError
+ */
+MiddlingExtendsException(PyExc_IndentationError, TabError, SyntaxError,
+                         "Improper mixture of spaces and tabs.");
+
+
+/*
+ *    LookupError extends StandardError
+ */
+SimpleExtendsException(PyExc_StandardError, LookupError,
+                       "Base class for lookup errors.");
+
+
+/*
+ *    IndexError extends LookupError
+ */
+SimpleExtendsException(PyExc_LookupError, IndexError,
+                       "Sequence index out of range.");
+
+
+/*
+ *    KeyError extends LookupError
+ */
+static PyObject *
+KeyError_str(PyBaseExceptionObject *self)
+{
+    /* If args is a tuple of exactly one item, apply repr to args[0].
+       This is done so that e.g. the exception raised by {}[''] prints
+         KeyError: ''
+       rather than the confusing
+         KeyError
+       alone.  The downside is that if KeyError is raised with an explanatory
+       string, that string will be displayed in quotes.  Too bad.
+       If args is anything else, use the default BaseException__str__().
+    */
+    if (PyTuple_GET_SIZE(self->args) == 1) {
+        return PyObject_Repr(PyTuple_GET_ITEM(self->args, 0));
+    }
+    return BaseException_str(self);
+}
+
+ComplexExtendsException(PyExc_LookupError, KeyError, BaseException,
+                        0, 0, 0, KeyError_str, "Mapping key not found.");
+
+
+/*
+ *    ValueError extends StandardError
+ */
+SimpleExtendsException(PyExc_StandardError, ValueError,
+                       "Inappropriate argument value (of correct type).");
+
+/*
+ *    UnicodeError extends ValueError
+ */
+
+SimpleExtendsException(PyExc_ValueError, UnicodeError,
+                       "Unicode related error.");
+
+#ifdef Py_USING_UNICODE
+static int
+get_int(PyObject *attr, Py_ssize_t *value, const char *name)
+{
+    if (!attr) {
+        PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
+        return -1;
+    }
+
+    if (PyInt_Check(attr)) {
+        *value = PyInt_AS_LONG(attr);
+    } else if (PyLong_Check(attr)) {
+        *value = _PyLong_AsSsize_t(attr);
+        if (*value == -1 && PyErr_Occurred())
+            return -1;
+    } else {
+        PyErr_Format(PyExc_TypeError, "%.200s attribute must be int", name);
+        return -1;
+    }
+    return 0;
+}
+
+static int
+set_ssize_t(PyObject **attr, Py_ssize_t value)
+{
+    PyObject *obj = PyInt_FromSsize_t(value);
+    if (!obj)
+        return -1;
+    Py_CLEAR(*attr);
+    *attr = obj;
+    return 0;
+}
+
+static PyObject *
+get_string(PyObject *attr, const char *name)
+{
+    if (!attr) {
+        PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
+        return NULL;
+    }
+
+    if (!PyString_Check(attr)) {
+        PyErr_Format(PyExc_TypeError, "%.200s attribute must be str", name);
+        return NULL;
+    }
+    Py_INCREF(attr);
+    return attr;
+}
+
+
+static int
+set_string(PyObject **attr, const char *value)
+{
+    PyObject *obj = PyString_FromString(value);
+    if (!obj)
+        return -1;
+    Py_CLEAR(*attr);
+    *attr = obj;
+    return 0;
+}
+
+
+static PyObject *
+get_unicode(PyObject *attr, const char *name)
+{
+    if (!attr) {
+        PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
+        return NULL;
+    }
+
+    if (!PyUnicode_Check(attr)) {
+        PyErr_Format(PyExc_TypeError,
+                     "%.200s attribute must be unicode", name);
+        return NULL;
+    }
+    Py_INCREF(attr);
+    return attr;
+}
+
+PyObject *
+PyUnicodeEncodeError_GetEncoding(PyObject *exc)
+{
+    return get_string(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
+}
+
+PyObject *
+PyUnicodeDecodeError_GetEncoding(PyObject *exc)
+{
+    return get_string(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
+}
+
+PyObject *
+PyUnicodeEncodeError_GetObject(PyObject *exc)
+{
+    return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
+}
+
+PyObject *
+PyUnicodeDecodeError_GetObject(PyObject *exc)
+{
+    return get_string(((PyUnicodeErrorObject *)exc)->object, "object");
+}
+
+PyObject *
+PyUnicodeTranslateError_GetObject(PyObject *exc)
+{
+    return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
+}
+
+int
+PyUnicodeEncodeError_GetStart(PyObject *exc, Py_ssize_t *start)
+{
+    if (!get_int(((PyUnicodeErrorObject *)exc)->start, start, "start")) {
+        Py_ssize_t size;
+        PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
+                                    "object");
+        if (!obj) return -1;
+        size = PyUnicode_GET_SIZE(obj);
+        if (*start<0)
+            *start = 0; /*XXX check for values <0*/
+        if (*start>=size)
+            *start = size-1;
+        Py_DECREF(obj);
+        return 0;
+    }
+    return -1;
+}
+
+
+int
+PyUnicodeDecodeError_GetStart(PyObject *exc, Py_ssize_t *start)
+{
+    if (!get_int(((PyUnicodeErrorObject *)exc)->start, start, "start")) {
+        Py_ssize_t size;
+        PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object,
+                                   "object");
+        if (!obj) return -1;
+        size = PyString_GET_SIZE(obj);
+        if (*start<0)
+            *start = 0;
+        if (*start>=size)
+            *start = size-1;
+        Py_DECREF(obj);
+        return 0;
+    }
+    return -1;
+}
+
+
+int
+PyUnicodeTranslateError_GetStart(PyObject *exc, Py_ssize_t *start)
+{
+    return PyUnicodeEncodeError_GetStart(exc, start);
+}
+
+
+int
+PyUnicodeEncodeError_SetStart(PyObject *exc, Py_ssize_t start)
+{
+    return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
+}
+
+
+int
+PyUnicodeDecodeError_SetStart(PyObject *exc, Py_ssize_t start)
+{
+    return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
+}
+
+
+int
+PyUnicodeTranslateError_SetStart(PyObject *exc, Py_ssize_t start)
+{
+    return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
+}
+
+
+int
+PyUnicodeEncodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
+{
+    if (!get_int(((PyUnicodeErrorObject *)exc)->end, end, "end")) {
+        Py_ssize_t size;
+        PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
+                                    "object");
+        if (!obj) return -1;
+        size = PyUnicode_GET_SIZE(obj);
+        if (*end<1)
+            *end = 1;
+        if (*end>size)
+            *end = size;
+        Py_DECREF(obj);
+        return 0;
+    }
+    return -1;
+}
+
+
+int
+PyUnicodeDecodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
+{
+    if (!get_int(((PyUnicodeErrorObject *)exc)->end, end, "end")) {
+        Py_ssize_t size;
+        PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object,
+                                   "object");
+        if (!obj) return -1;
+        size = PyString_GET_SIZE(obj);
+        if (*end<1)
+            *end = 1;
+        if (*end>size)
+            *end = size;
+        Py_DECREF(obj);
+        return 0;
+    }
+    return -1;
+}
+
+
+int
+PyUnicodeTranslateError_GetEnd(PyObject *exc, Py_ssize_t *start)
+{
+    return PyUnicodeEncodeError_GetEnd(exc, start);
+}
+
+
+int
+PyUnicodeEncodeError_SetEnd(PyObject *exc, Py_ssize_t end)
+{
+    return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
+}
+
+
+int
+PyUnicodeDecodeError_SetEnd(PyObject *exc, Py_ssize_t end)
+{
+    return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
+}
+
+
+int
+PyUnicodeTranslateError_SetEnd(PyObject *exc, Py_ssize_t end)
+{
+    return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
+}
+
+PyObject *
+PyUnicodeEncodeError_GetReason(PyObject *exc)
+{
+    return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
+}
+
+
+PyObject *
+PyUnicodeDecodeError_GetReason(PyObject *exc)
+{
+    return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
+}
+
+
+PyObject *
+PyUnicodeTranslateError_GetReason(PyObject *exc)
+{
+    return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
+}
+
+
+int
+PyUnicodeEncodeError_SetReason(PyObject *exc, const char *reason)
+{
+    return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
+}
+
+
+int
+PyUnicodeDecodeError_SetReason(PyObject *exc, const char *reason)
+{
+    return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
+}
+
+
+int
+PyUnicodeTranslateError_SetReason(PyObject *exc, const char *reason)
+{
+    return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
+}
+
+
+static int
+UnicodeError_init(PyUnicodeErrorObject *self, PyObject *args, PyObject *kwds,
+                  PyTypeObject *objecttype)
+{
+    Py_CLEAR(self->encoding);
+    Py_CLEAR(self->object);
+    Py_CLEAR(self->start);
+    Py_CLEAR(self->end);
+    Py_CLEAR(self->reason);
+
+    if (!PyArg_ParseTuple(args, "O!O!O!O!O!",
+        &PyString_Type, &self->encoding,
+        objecttype, &self->object,
+        &PyInt_Type, &self->start,
+        &PyInt_Type, &self->end,
+        &PyString_Type, &self->reason)) {
+        self->encoding = self->object = self->start = self->end =
+            self->reason = NULL;
+        return -1;
+    }
+
+    Py_INCREF(self->encoding);
+    Py_INCREF(self->object);
+    Py_INCREF(self->start);
+    Py_INCREF(self->end);
+    Py_INCREF(self->reason);
+
+    return 0;
+}
+
+static int
+UnicodeError_clear(PyUnicodeErrorObject *self)
+{
+    Py_CLEAR(self->encoding);
+    Py_CLEAR(self->object);
+    Py_CLEAR(self->start);
+    Py_CLEAR(self->end);
+    Py_CLEAR(self->reason);
+    return BaseException_clear((PyBaseExceptionObject *)self);
+}
+
+static void
+UnicodeError_dealloc(PyUnicodeErrorObject *self)
+{
+    _PyObject_GC_UNTRACK(self);
+    UnicodeError_clear(self);
+    self->ob_type->tp_free((PyObject *)self);
+}
+
+static int
+UnicodeError_traverse(PyUnicodeErrorObject *self, visitproc visit, void *arg)
+{
+    Py_VISIT(self->encoding);
+    Py_VISIT(self->object);
+    Py_VISIT(self->start);
+    Py_VISIT(self->end);
+    Py_VISIT(self->reason);
+    return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
+}
+
+static PyMemberDef UnicodeError_members[] = {
+    {"message", T_OBJECT, offsetof(PyUnicodeErrorObject, message), 0,
+        PyDoc_STR("exception message")},
+    {"encoding", T_OBJECT, offsetof(PyUnicodeErrorObject, encoding), 0,
+        PyDoc_STR("exception encoding")},
+    {"object", T_OBJECT, offsetof(PyUnicodeErrorObject, object), 0,
+        PyDoc_STR("exception object")},
+    {"start", T_OBJECT, offsetof(PyUnicodeErrorObject, start), 0,
+        PyDoc_STR("exception start")},
+    {"end", T_OBJECT, offsetof(PyUnicodeErrorObject, end), 0,
+        PyDoc_STR("exception end")},
+    {"reason", T_OBJECT, offsetof(PyUnicodeErrorObject, reason), 0,
+        PyDoc_STR("exception reason")},
+    {NULL}  /* Sentinel */
+};
+
+
+/*
+ *    UnicodeEncodeError extends UnicodeError
+ */
+
+static int
+UnicodeEncodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+    if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
+        return -1;
+    return UnicodeError_init((PyUnicodeErrorObject *)self, args,
+                             kwds, &PyUnicode_Type);
+}
+
+static PyObject *
+UnicodeEncodeError_str(PyObject *self)
+{
+    Py_ssize_t start;
+    Py_ssize_t end;
+
+    if (PyUnicodeEncodeError_GetStart(self, &start))
+        return NULL;
+
+    if (PyUnicodeEncodeError_GetEnd(self, &end))
+        return NULL;
+
+    if (end==start+1) {
+        int badchar = (int)PyUnicode_AS_UNICODE(((PyUnicodeErrorObject *)self)->object)[start];
+        char badchar_str[20];
+        if (badchar <= 0xff)
+            PyOS_snprintf(badchar_str, sizeof(badchar_str), "x%02x", badchar);
+        else if (badchar <= 0xffff)
+            PyOS_snprintf(badchar_str, sizeof(badchar_str), "u%04x", badchar);
+        else
+            PyOS_snprintf(badchar_str, sizeof(badchar_str), "U%08x", badchar);
+        return PyString_FromFormat(
+            "'%.400s' codec can't encode character u'\\%s' in position %zd: %.400s",
+            PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
+            badchar_str,
+            start,
+            PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
+        );
+    }
+    return PyString_FromFormat(
+        "'%.400s' codec can't encode characters in position %zd-%zd: %.400s",
+        PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
+        start,
+        (end-1),
+        PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
+    );
+}
+
+static PyTypeObject _PyExc_UnicodeEncodeError = {
+    PyObject_HEAD_INIT(NULL)
+    0,
+    EXC_MODULE_NAME "UnicodeEncodeError",
+    sizeof(PyUnicodeErrorObject), 0,
+    (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    (reprfunc)UnicodeEncodeError_str, 0, 0, 0,
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
+    PyDoc_STR("Unicode encoding error."), (traverseproc)UnicodeError_traverse,
+    (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
+    0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
+    (initproc)UnicodeEncodeError_init, 0, BaseException_new,
+};
+PyObject *PyExc_UnicodeEncodeError = (PyObject *)&_PyExc_UnicodeEncodeError;
+
+PyObject *
+PyUnicodeEncodeError_Create(
+    const char *encoding, const Py_UNICODE *object, Py_ssize_t length,
+    Py_ssize_t start, Py_ssize_t end, const char *reason)
+{
+    return PyObject_CallFunction(PyExc_UnicodeEncodeError, "su#nns",
+                                 encoding, object, length, start, end, reason);
+}
+
+
+/*
+ *    UnicodeDecodeError extends UnicodeError
+ */
+
+static int
+UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+    if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
+        return -1;
+    return UnicodeError_init((PyUnicodeErrorObject *)self, args,
+                             kwds, &PyString_Type);
+}
+
+static PyObject *
+UnicodeDecodeError_str(PyObject *self)
+{
+    Py_ssize_t start = 0;
+    Py_ssize_t end = 0;
+
+    if (PyUnicodeDecodeError_GetStart(self, &start))
+    return NULL;
+
+    if (PyUnicodeDecodeError_GetEnd(self, &end))
+    return NULL;
+
+    if (end==start+1) {
+        /* FromFormat does not support %02x, so format that separately */
+        char byte[4];
+        PyOS_snprintf(byte, sizeof(byte), "%02x",
+                      ((int)PyString_AS_STRING(((PyUnicodeErrorObject *)self)->object)[start])&0xff);
+        return PyString_FromFormat(
+            "'%.400s' codec can't decode byte 0x%s in position %zd: %.400s",
+            PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
+            byte,
+            start,
+            PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
+        );
+    }
+    return PyString_FromFormat(
+        "'%.400s' codec can't decode bytes in position %zd-%zd: %.400s",
+        PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
+        start,
+        (end-1),
+        PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
+    );
+}
+
+static PyTypeObject _PyExc_UnicodeDecodeError = {
+    PyObject_HEAD_INIT(NULL)
+    0,
+    EXC_MODULE_NAME "UnicodeDecodeError",
+    sizeof(PyUnicodeErrorObject), 0,
+    (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    (reprfunc)UnicodeDecodeError_str, 0, 0, 0,
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
+    PyDoc_STR("Unicode decoding error."), (traverseproc)UnicodeError_traverse,
+    (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
+    0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
+    (initproc)UnicodeDecodeError_init, 0, BaseException_new,
+};
+PyObject *PyExc_UnicodeDecodeError = (PyObject *)&_PyExc_UnicodeDecodeError;
+
+PyObject *
+PyUnicodeDecodeError_Create(
+    const char *encoding, const char *object, Py_ssize_t length,
+    Py_ssize_t start, Py_ssize_t end, const char *reason)
+{
+    assert(length < INT_MAX);
+    assert(start < INT_MAX);
+    assert(end < INT_MAX);
+    return PyObject_CallFunction(PyExc_UnicodeDecodeError, "ss#nns",
+                                 encoding, object, length, start, end, reason);
+}
+
+
+/*
+ *    UnicodeTranslateError extends UnicodeError
+ */
+
+static int
+UnicodeTranslateError_init(PyUnicodeErrorObject *self, PyObject *args,
+                           PyObject *kwds)
+{
+    if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
+        return -1;
+
+    Py_CLEAR(self->object);
+    Py_CLEAR(self->start);
+    Py_CLEAR(self->end);
+    Py_CLEAR(self->reason);
+
+    if (!PyArg_ParseTuple(args, "O!O!O!O!",
+        &PyUnicode_Type, &self->object,
+        &PyInt_Type, &self->start,
+        &PyInt_Type, &self->end,
+        &PyString_Type, &self->reason)) {
+        self->object = self->start = self->end = self->reason = NULL;
+        return -1;
+    }
+
+    Py_INCREF(self->object);
+    Py_INCREF(self->start);
+    Py_INCREF(self->end);
+    Py_INCREF(self->reason);
+
+    return 0;
+}
+
+
+static PyObject *
+UnicodeTranslateError_str(PyObject *self)
+{
+    Py_ssize_t start;
+    Py_ssize_t end;
+
+    if (PyUnicodeTranslateError_GetStart(self, &start))
+        return NULL;
+
+    if (PyUnicodeTranslateError_GetEnd(self, &end))
+        return NULL;
+
+    if (end==start+1) {
+        int badchar = (int)PyUnicode_AS_UNICODE(((PyUnicodeErrorObject *)self)->object)[start];
+        char badchar_str[20];
+        if (badchar <= 0xff)
+            PyOS_snprintf(badchar_str, sizeof(badchar_str), "x%02x", badchar);
+        else if (badchar <= 0xffff)
+            PyOS_snprintf(badchar_str, sizeof(badchar_str), "u%04x", badchar);
+        else
+            PyOS_snprintf(badchar_str, sizeof(badchar_str), "U%08x", badchar);
+        return PyString_FromFormat(
+            "can't translate character u'\\%s' in position %zd: %.400s",
+            badchar_str,
+            start,
+            PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
+        );
+    }
+    return PyString_FromFormat(
+        "can't translate characters in position %zd-%zd: %.400s",
+        start,
+        (end-1),
+        PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
+    );
+}
+
+static PyTypeObject _PyExc_UnicodeTranslateError = {
+    PyObject_HEAD_INIT(NULL)
+    0,
+    EXC_MODULE_NAME "UnicodeTranslateError",
+    sizeof(PyUnicodeErrorObject), 0,
+    (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    (reprfunc)UnicodeTranslateError_str, 0, 0, 0,
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
+    PyDoc_STR("Unicode translation error."), (traverseproc)UnicodeError_traverse,
+    (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
+    0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
+    (initproc)UnicodeTranslateError_init, 0, BaseException_new,
+};
+PyObject *PyExc_UnicodeTranslateError = (PyObject *)&_PyExc_UnicodeTranslateError;
+
+PyObject *
+PyUnicodeTranslateError_Create(
+    const Py_UNICODE *object, Py_ssize_t length,
+    Py_ssize_t start, Py_ssize_t end, const char *reason)
+{
+    return PyObject_CallFunction(PyExc_UnicodeTranslateError, "u#nns",
+                                 object, length, start, end, reason);
+}
+#endif
+
+
+/*
+ *    AssertionError extends StandardError
+ */
+SimpleExtendsException(PyExc_StandardError, AssertionError,
+                       "Assertion failed.");
+
+
+/*
+ *    ArithmeticError extends StandardError
+ */
+SimpleExtendsException(PyExc_StandardError, ArithmeticError,
+                       "Base class for arithmetic errors.");
+
+
+/*
+ *    FloatingPointError extends ArithmeticError
+ */
+SimpleExtendsException(PyExc_ArithmeticError, FloatingPointError,
+                       "Floating point operation failed.");
+
+
+/*
+ *    OverflowError extends ArithmeticError
+ */
+SimpleExtendsException(PyExc_ArithmeticError, OverflowError,
+                       "Result too large to be represented.");
+
+
+/*
+ *    ZeroDivisionError extends ArithmeticError
+ */
+SimpleExtendsException(PyExc_ArithmeticError, ZeroDivisionError,
+          "Second argument to a division or modulo operation was zero.");
+
+
+/*
+ *    SystemError extends StandardError
+ */
+SimpleExtendsException(PyExc_StandardError, SystemError,
+    "Internal error in the Python interpreter.\n"
+    "\n"
+    "Please report this to the Python maintainer, along with the traceback,\n"
+    "the Python version, and the hardware/OS platform and version.");
+
+
+/*
+ *    ReferenceError extends StandardError
+ */
+SimpleExtendsException(PyExc_StandardError, ReferenceError,
+                       "Weak ref proxy used after referent went away.");
+
+
+/*
+ *    MemoryError extends StandardError
+ */
+SimpleExtendsException(PyExc_StandardError, MemoryError, "Out of memory.");
+
+
+/* Warning category docstrings */
+
+/*
+ *    Warning extends Exception
+ */
+SimpleExtendsException(PyExc_Exception, Warning,
+                       "Base class for warning categories.");
+
+
+/*
+ *    UserWarning extends Warning
+ */
+SimpleExtendsException(PyExc_Warning, UserWarning,
+                       "Base class for warnings generated by user code.");
+
+
+/*
+ *    DeprecationWarning extends Warning
+ */
+SimpleExtendsException(PyExc_Warning, DeprecationWarning,
+                       "Base class for warnings about deprecated features.");
+
+
+/*
+ *    PendingDeprecationWarning extends Warning
+ */
+SimpleExtendsException(PyExc_Warning, PendingDeprecationWarning,
+    "Base class for warnings about features which will be deprecated\n"
+    "in the future.");
+
+
+/*
+ *    SyntaxWarning extends Warning
+ */
+SimpleExtendsException(PyExc_Warning, SyntaxWarning,
+                       "Base class for warnings about dubious syntax.");
+
+
+/*
+ *    RuntimeWarning extends Warning
+ */
+SimpleExtendsException(PyExc_Warning, RuntimeWarning,
+                 "Base class for warnings about dubious runtime behavior.");
+
+
+/*
+ *    FutureWarning extends Warning
+ */
+SimpleExtendsException(PyExc_Warning, FutureWarning,
+    "Base class for warnings about constructs that will change semantically\n"
+    "in the future.");
+
+
+/*
+ *    ImportWarning extends Warning
+ */
+SimpleExtendsException(PyExc_Warning, ImportWarning,
+          "Base class for warnings about probable mistakes in module imports");
+
+
+/*
+ *    UnicodeWarning extends Warning
+ */
+SimpleExtendsException(PyExc_Warning, UnicodeWarning,
+    "Base class for warnings about Unicode related problems, mostly\n"
+    "related to conversion problems.");
+
+
+/* Pre-computed MemoryError instance.  Best to create this as early as
+ * possible and not wait until a MemoryError is actually raised!
+ */
+PyObject *PyExc_MemoryErrorInst=NULL;
+
+/* module global functions */
+static PyMethodDef functions[] = {
+    /* Sentinel */
+    {NULL, NULL}
+};
+
+#define PRE_INIT(TYPE) if (PyType_Ready(&_PyExc_ ## TYPE) < 0) \
+    Py_FatalError("exceptions bootstrapping error.");
+
+#define POST_INIT(TYPE) Py_INCREF(PyExc_ ## TYPE); \
+    PyModule_AddObject(m, # TYPE, PyExc_ ## TYPE); \
+    if (PyDict_SetItemString(bdict, # TYPE, PyExc_ ## TYPE)) \
+        Py_FatalError("Module dictionary insertion problem.");
+
+#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
+/* crt variable checking in VisualStudio .NET 2005 */
+#include <crtdbg.h>
+
+static int	prevCrtReportMode;
+static _invalid_parameter_handler	prevCrtHandler;
+
+/* Invalid parameter handler.  Sets a ValueError exception */
+static void
+InvalidParameterHandler(
+    const wchar_t * expression,
+    const wchar_t * function,
+    const wchar_t * file,
+    unsigned int line,
+    uintptr_t pReserved)
+{
+    /* Do nothing, allow execution to continue.  Usually this
+     * means that the CRT will set errno to EINVAL
+     */
+}
+#endif
+
+
+PyMODINIT_FUNC
+_PyExc_Init(void)
+{
+    PyObject *m, *bltinmod, *bdict;
+
+    PRE_INIT(BaseException)
+    PRE_INIT(Exception)
+    PRE_INIT(StandardError)
+    PRE_INIT(TypeError)
+    PRE_INIT(StopIteration)
+    PRE_INIT(GeneratorExit)
+    PRE_INIT(SystemExit)
+    PRE_INIT(KeyboardInterrupt)
+    PRE_INIT(ImportError)
+    PRE_INIT(EnvironmentError)
+    PRE_INIT(IOError)
+    PRE_INIT(OSError)
+#ifdef MS_WINDOWS
+    PRE_INIT(WindowsError)
+#endif
+#ifdef __VMS
+    PRE_INIT(VMSError)
+#endif
+    PRE_INIT(EOFError)
+    PRE_INIT(RuntimeError)
+    PRE_INIT(NotImplementedError)
+    PRE_INIT(NameError)
+    PRE_INIT(UnboundLocalError)
+    PRE_INIT(AttributeError)
+    PRE_INIT(SyntaxError)
+    PRE_INIT(IndentationError)
+    PRE_INIT(TabError)
+    PRE_INIT(LookupError)
+    PRE_INIT(IndexError)
+    PRE_INIT(KeyError)
+    PRE_INIT(ValueError)
+    PRE_INIT(UnicodeError)
+#ifdef Py_USING_UNICODE
+    PRE_INIT(UnicodeEncodeError)
+    PRE_INIT(UnicodeDecodeError)
+    PRE_INIT(UnicodeTranslateError)
+#endif
+    PRE_INIT(AssertionError)
+    PRE_INIT(ArithmeticError)
+    PRE_INIT(FloatingPointError)
+    PRE_INIT(OverflowError)
+    PRE_INIT(ZeroDivisionError)
+    PRE_INIT(SystemError)
+    PRE_INIT(ReferenceError)
+    PRE_INIT(MemoryError)
+    PRE_INIT(Warning)
+    PRE_INIT(UserWarning)
+    PRE_INIT(DeprecationWarning)
+    PRE_INIT(PendingDeprecationWarning)
+    PRE_INIT(SyntaxWarning)
+    PRE_INIT(RuntimeWarning)
+    PRE_INIT(FutureWarning)
+    PRE_INIT(ImportWarning)
+    PRE_INIT(UnicodeWarning)
+
+    m = Py_InitModule4("exceptions", functions, exceptions_doc,
+        (PyObject *)NULL, PYTHON_API_VERSION);
+    if (m == NULL) return;
+
+    bltinmod = PyImport_ImportModule("__builtin__");
+    if (bltinmod == NULL)
+        Py_FatalError("exceptions bootstrapping error.");
+    bdict = PyModule_GetDict(bltinmod);
+    if (bdict == NULL)
+        Py_FatalError("exceptions bootstrapping error.");
+
+    POST_INIT(BaseException)
+    POST_INIT(Exception)
+    POST_INIT(StandardError)
+    POST_INIT(TypeError)
+    POST_INIT(StopIteration)
+    POST_INIT(GeneratorExit)
+    POST_INIT(SystemExit)
+    POST_INIT(KeyboardInterrupt)
+    POST_INIT(ImportError)
+    POST_INIT(EnvironmentError)
+    POST_INIT(IOError)
+    POST_INIT(OSError)
+#ifdef MS_WINDOWS
+    POST_INIT(WindowsError)
+#endif
+#ifdef __VMS
+    POST_INIT(VMSError)
+#endif
+    POST_INIT(EOFError)
+    POST_INIT(RuntimeError)
+    POST_INIT(NotImplementedError)
+    POST_INIT(NameError)
+    POST_INIT(UnboundLocalError)
+    POST_INIT(AttributeError)
+    POST_INIT(SyntaxError)
+    POST_INIT(IndentationError)
+    POST_INIT(TabError)
+    POST_INIT(LookupError)
+    POST_INIT(IndexError)
+    POST_INIT(KeyError)
+    POST_INIT(ValueError)
+    POST_INIT(UnicodeError)
+#ifdef Py_USING_UNICODE
+    POST_INIT(UnicodeEncodeError)
+    POST_INIT(UnicodeDecodeError)
+    POST_INIT(UnicodeTranslateError)
+#endif
+    POST_INIT(AssertionError)
+    POST_INIT(ArithmeticError)
+    POST_INIT(FloatingPointError)
+    POST_INIT(OverflowError)
+    POST_INIT(ZeroDivisionError)
+    POST_INIT(SystemError)
+    POST_INIT(ReferenceError)
+    POST_INIT(MemoryError)
+    POST_INIT(Warning)
+    POST_INIT(UserWarning)
+    POST_INIT(DeprecationWarning)
+    POST_INIT(PendingDeprecationWarning)
+    POST_INIT(SyntaxWarning)
+    POST_INIT(RuntimeWarning)
+    POST_INIT(FutureWarning)
+    POST_INIT(ImportWarning)
+    POST_INIT(UnicodeWarning)
+
+    PyExc_MemoryErrorInst = BaseException_new(&_PyExc_MemoryError, NULL, NULL);
+    if (!PyExc_MemoryErrorInst)
+        Py_FatalError("Cannot pre-allocate MemoryError instance\n");
+
+    Py_DECREF(bltinmod);
+
+#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
+    /* Set CRT argument error handler */
+    prevCrtHandler = _set_invalid_parameter_handler(InvalidParameterHandler);
+    /* turn off assertions in debug mode */
+    prevCrtReportMode = _CrtSetReportMode(_CRT_ASSERT, 0);
+#endif
+}
+
+void
+_PyExc_Fini(void)
+{
+    Py_XDECREF(PyExc_MemoryErrorInst);
+    PyExc_MemoryErrorInst = NULL;
+#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
+    /* reset CRT error handling */
+    _set_invalid_parameter_handler(prevCrtHandler);
+    _CrtSetReportMode(_CRT_ASSERT, prevCrtReportMode);
+#endif
+}

Added: vendor/Python/current/Objects/fileobject.c
===================================================================
--- vendor/Python/current/Objects/fileobject.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Objects/fileobject.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2484 @@
+/* File object implementation */
+
+#define PY_SSIZE_T_CLEAN
+#include "Python.h"
+#include "structmember.h"
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif /* HAVE_SYS_TYPES_H */
+
+#ifdef MS_WINDOWS
+#define fileno _fileno
+/* can simulate truncate with Win32 API functions; see file_truncate */
+#define HAVE_FTRUNCATE
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#endif
+
+#ifdef _MSC_VER
+/* Need GetVersion to see if on NT so safe to use _wfopen */
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#endif /* _MSC_VER */
+
+#if defined(PYOS_OS2) && defined(PYCC_GCC)
+#include <io.h>
+#endif
+
+#define BUF(v) PyString_AS_STRING((PyStringObject *)v)
+
+#ifndef DONT_HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#ifdef HAVE_GETC_UNLOCKED
+#define GETC(f) getc_unlocked(f)
+#define FLOCKFILE(f) flockfile(f)
+#define FUNLOCKFILE(f) funlockfile(f)
+#else
+#define GETC(f) getc(f)
+#define FLOCKFILE(f)
+#define FUNLOCKFILE(f)
+#endif
+
+/* Bits in f_newlinetypes */
+#define NEWLINE_UNKNOWN	0	/* No newline seen, yet */
+#define NEWLINE_CR 1		/* \r newline seen */
+#define NEWLINE_LF 2		/* \n newline seen */
+#define NEWLINE_CRLF 4		/* \r\n newline seen */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+FILE *
+PyFile_AsFile(PyObject *f)
+{
+	if (f == NULL || !PyFile_Check(f))
+		return NULL;
+	else
+		return ((PyFileObject *)f)->f_fp;
+}
+
+PyObject *
+PyFile_Name(PyObject *f)
+{
+	if (f == NULL || !PyFile_Check(f))
+		return NULL;
+	else
+		return ((PyFileObject *)f)->f_name;
+}
+
+/* On Unix, fopen will succeed for directories.
+   In Python, there should be no file objects referring to
+   directories, so we need a check.  */
+
+static PyFileObject*
+dircheck(PyFileObject* f)
+{
+#if defined(HAVE_FSTAT) && defined(S_IFDIR) && defined(EISDIR)
+	struct stat buf;
+	if (f->f_fp == NULL)
+		return f;
+	if (fstat(fileno(f->f_fp), &buf) == 0 &&
+	    S_ISDIR(buf.st_mode)) {
+#ifdef HAVE_STRERROR
+		char *msg = strerror(EISDIR);
+#else
+		char *msg = "Is a directory";
+#endif
+		PyObject *exc = PyObject_CallFunction(PyExc_IOError, "(is)",
+						      EISDIR, msg);
+		PyErr_SetObject(PyExc_IOError, exc);
+		Py_XDECREF(exc);
+		return NULL;
+	}
+#endif
+	return f;
+}
+
+
+static PyObject *
+fill_file_fields(PyFileObject *f, FILE *fp, PyObject *name, char *mode,
+		 int (*close)(FILE *))
+{
+	assert(name != NULL);
+	assert(f != NULL);
+	assert(PyFile_Check(f));
+	assert(f->f_fp == NULL);
+
+	Py_DECREF(f->f_name);
+	Py_DECREF(f->f_mode);
+	Py_DECREF(f->f_encoding);
+
+        Py_INCREF(name);
+        f->f_name = name;
+
+	f->f_mode = PyString_FromString(mode);
+
+	f->f_close = close;
+	f->f_softspace = 0;
+	f->f_binary = strchr(mode,'b') != NULL;
+	f->f_buf = NULL;
+	f->f_univ_newline = (strchr(mode, 'U') != NULL);
+	f->f_newlinetypes = NEWLINE_UNKNOWN;
+	f->f_skipnextlf = 0;
+	Py_INCREF(Py_None);
+	f->f_encoding = Py_None;
+
+	if (f->f_mode == NULL)
+		return NULL;
+	f->f_fp = fp;
+        f = dircheck(f);
+	return (PyObject *) f;
+}
+
+/* check for known incorrect mode strings - problem is, platforms are
+   free to accept any mode characters they like and are supposed to
+   ignore stuff they don't understand... write or append mode with
+   universal newline support is expressly forbidden by PEP 278.
+   Additionally, remove the 'U' from the mode string as platforms
+   won't know what it is. */
+/* zero return is kewl - one is un-kewl */
+static int
+sanitize_the_mode(char *mode)
+{
+	char *upos;
+	size_t len = strlen(mode);
+
+	if (!len) {
+		PyErr_SetString(PyExc_ValueError, "empty mode string");
+		return 1;
+	}
+
+	upos = strchr(mode, 'U');
+	if (upos) {
+		memmove(upos, upos+1, len-(upos-mode)); /* incl null char */
+
+		if (mode[0] == 'w' || mode[0] == 'a') {
+			PyErr_Format(PyExc_ValueError, "universal newline "
+			             "mode can only be used with modes "
+				     "starting with 'r'");
+			return 1;
+		}
+
+		if (mode[0] != 'r') {
+			memmove(mode+1, mode, strlen(mode)+1);
+			mode[0] = 'r';
+		}
+
+		if (!strchr(mode, 'b')) {
+			memmove(mode+2, mode+1, strlen(mode));
+			mode[1] = 'b';
+		}
+	} else if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
+		PyErr_Format(PyExc_ValueError, "mode string must begin with "
+	        	    "one of 'r', 'w', 'a' or 'U', not '%.200s'", mode);
+		return 1;
+	}
+
+	return 0;
+}
+
+static PyObject *
+open_the_file(PyFileObject *f, char *name, char *mode)
+{
+	char *newmode;
+	assert(f != NULL);
+	assert(PyFile_Check(f));
+#ifdef MS_WINDOWS
+	/* windows ignores the passed name in order to support Unicode */
+	assert(f->f_name != NULL);
+#else
+	assert(name != NULL);
+#endif
+	assert(mode != NULL);
+	assert(f->f_fp == NULL);
+
+	/* probably need to replace 'U' by 'rb' */
+	newmode = PyMem_MALLOC(strlen(mode) + 3);
+	if (!newmode) {
+		PyErr_NoMemory();
+		return NULL;
+	}
+	strcpy(newmode, mode);
+
+	if (sanitize_the_mode(newmode)) {
+		f = NULL;
+		goto cleanup;
+	}
+
+	/* rexec.py can't stop a user from getting the file() constructor --
+	   all they have to do is get *any* file object f, and then do
+	   type(f).  Here we prevent them from doing damage with it. */
+	if (PyEval_GetRestricted()) {
+		PyErr_SetString(PyExc_IOError,
+		"file() constructor not accessible in restricted mode");
+		f = NULL;
+		goto cleanup;
+	}
+	errno = 0;
+
+#ifdef MS_WINDOWS
+	if (PyUnicode_Check(f->f_name)) {
+		PyObject *wmode;
+		wmode = PyUnicode_DecodeASCII(newmode, strlen(newmode), NULL);
+		if (f->f_name && wmode) {
+			Py_BEGIN_ALLOW_THREADS
+			/* PyUnicode_AS_UNICODE OK without thread
+			   lock as it is a simple dereference. */
+			f->f_fp = _wfopen(PyUnicode_AS_UNICODE(f->f_name),
+					  PyUnicode_AS_UNICODE(wmode));
+			Py_END_ALLOW_THREADS
+		}
+		Py_XDECREF(wmode);
+	}
+#endif
+	if (NULL == f->f_fp && NULL != name) {
+		Py_BEGIN_ALLOW_THREADS
+		f->f_fp = fopen(name, newmode);
+		Py_END_ALLOW_THREADS
+	}
+
+	if (f->f_fp == NULL) {
+#if defined  _MSC_VER && (_MSC_VER < 1400 || !defined(__STDC_SECURE_LIB__))
+		/* MSVC 6 (Microsoft) leaves errno at 0 for bad mode strings,
+		 * across all Windows flavors.  When it sets EINVAL varies
+		 * across Windows flavors, the exact conditions aren't
+		 * documented, and the answer lies in the OS's implementation
+		 * of Win32's CreateFile function (whose source is secret).
+		 * Seems the best we can do is map EINVAL to ENOENT.
+		 * Starting with Visual Studio .NET 2005, EINVAL is correctly
+		 * set by our CRT error handler (set in exceptions.c.)
+		 */
+		if (errno == 0)	/* bad mode string */
+			errno = EINVAL;
+		else if (errno == EINVAL) /* unknown, but not a mode string */
+			errno = ENOENT;
+#endif
+		if (errno == EINVAL)
+			PyErr_Format(PyExc_IOError, "invalid mode: %s",
+				     mode);
+		else
+			PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, f->f_name);
+		f = NULL;
+	}
+	if (f != NULL)
+		f = dircheck(f);
+
+cleanup:
+	PyMem_FREE(newmode);
+
+	return (PyObject *)f;
+}
+
+PyObject *
+PyFile_FromFile(FILE *fp, char *name, char *mode, int (*close)(FILE *))
+{
+	PyFileObject *f = (PyFileObject *)PyFile_Type.tp_new(&PyFile_Type,
+							     NULL, NULL);
+	if (f != NULL) {
+		PyObject *o_name = PyString_FromString(name);
+		if (o_name == NULL)
+			return NULL;
+		if (fill_file_fields(f, fp, o_name, mode, close) == NULL) {
+			Py_DECREF(f);
+			f = NULL;
+		}
+                Py_DECREF(o_name);
+	}
+	return (PyObject *) f;
+}
+
+PyObject *
+PyFile_FromString(char *name, char *mode)
+{
+	extern int fclose(FILE *);
+	PyFileObject *f;
+
+	f = (PyFileObject *)PyFile_FromFile((FILE *)NULL, name, mode, fclose);
+	if (f != NULL) {
+		if (open_the_file(f, name, mode) == NULL) {
+			Py_DECREF(f);
+			f = NULL;
+		}
+	}
+	return (PyObject *)f;
+}
+
+void
+PyFile_SetBufSize(PyObject *f, int bufsize)
+{
+	PyFileObject *file = (PyFileObject *)f;
+	if (bufsize >= 0) {
+		int type;
+		switch (bufsize) {
+		case 0:
+			type = _IONBF;
+			break;
+#ifdef HAVE_SETVBUF
+		case 1:
+			type = _IOLBF;
+			bufsize = BUFSIZ;
+			break;
+#endif
+		default:
+			type = _IOFBF;
+#ifndef HAVE_SETVBUF
+			bufsize = BUFSIZ;
+#endif
+			break;
+		}
+		fflush(file->f_fp);
+		if (type == _IONBF) {
+			PyMem_Free(file->f_setbuf);
+			file->f_setbuf = NULL;
+		} else {
+			file->f_setbuf = (char *)PyMem_Realloc(file->f_setbuf, 
+                                                                bufsize);
+		}
+#ifdef HAVE_SETVBUF
+		setvbuf(file->f_fp, file->f_setbuf, type, bufsize);
+#else /* !HAVE_SETVBUF */
+		setbuf(file->f_fp, file->f_setbuf);
+#endif /* !HAVE_SETVBUF */
+	}
+}
+
+/* Set the encoding used to output Unicode strings.
+   Returh 1 on success, 0 on failure. */
+
+int
+PyFile_SetEncoding(PyObject *f, const char *enc)
+{
+	PyFileObject *file = (PyFileObject*)f;
+	PyObject *str = PyString_FromString(enc);
+
+	assert(PyFile_Check(f));
+	if (!str)
+		return 0;
+	Py_DECREF(file->f_encoding);
+	file->f_encoding = str;
+	return 1;
+}
+
+static PyObject *
+err_closed(void)
+{
+	PyErr_SetString(PyExc_ValueError, "I/O operation on closed file");
+	return NULL;
+}
+
+/* Refuse regular file I/O if there's data in the iteration-buffer.
+ * Mixing them would cause data to arrive out of order, as the read*
+ * methods don't use the iteration buffer. */
+static PyObject *
+err_iterbuffered(void)
+{
+	PyErr_SetString(PyExc_ValueError,
+		"Mixing iteration and read methods would lose data");
+	return NULL;
+}
+
+static void drop_readahead(PyFileObject *);
+
+/* Methods */
+
+static void
+file_dealloc(PyFileObject *f)
+{
+	int sts = 0;
+	if (f->weakreflist != NULL)
+		PyObject_ClearWeakRefs((PyObject *) f);
+	if (f->f_fp != NULL && f->f_close != NULL) {
+		Py_BEGIN_ALLOW_THREADS
+		sts = (*f->f_close)(f->f_fp);
+		Py_END_ALLOW_THREADS
+		if (sts == EOF) 
+#ifdef HAVE_STRERROR
+			PySys_WriteStderr("close failed: [Errno %d] %s\n", errno, strerror(errno)); 
+#else
+			PySys_WriteStderr("close failed: [Errno %d]\n", errno); 
+#endif
+	}
+	PyMem_Free(f->f_setbuf);
+	Py_XDECREF(f->f_name);
+	Py_XDECREF(f->f_mode);
+	Py_XDECREF(f->f_encoding);
+	drop_readahead(f);
+	f->ob_type->tp_free((PyObject *)f);
+}
+
+static PyObject *
+file_repr(PyFileObject *f)
+{
+	if (PyUnicode_Check(f->f_name)) {
+#ifdef Py_USING_UNICODE
+		PyObject *ret = NULL;
+		PyObject *name = PyUnicode_AsUnicodeEscapeString(f->f_name);
+		const char *name_str = name ? PyString_AsString(name) : "?";
+		ret = PyString_FromFormat("<%s file u'%s', mode '%s' at %p>",
+				   f->f_fp == NULL ? "closed" : "open",
+				   name_str,
+				   PyString_AsString(f->f_mode),
+				   f);
+		Py_XDECREF(name);
+		return ret;
+#endif
+	} else {
+		return PyString_FromFormat("<%s file '%s', mode '%s' at %p>",
+				   f->f_fp == NULL ? "closed" : "open",
+				   PyString_AsString(f->f_name),
+				   PyString_AsString(f->f_mode),
+				   f);
+	}
+}
+
+static PyObject *
+file_close(PyFileObject *f)
+{
+	int sts = 0;
+	if (f->f_fp != NULL) {
+		if (f->f_close != NULL) {
+			Py_BEGIN_ALLOW_THREADS
+			errno = 0;
+			sts = (*f->f_close)(f->f_fp);
+			Py_END_ALLOW_THREADS
+		}
+		f->f_fp = NULL;
+	}
+	PyMem_Free(f->f_setbuf);
+	f->f_setbuf = NULL;
+	if (sts == EOF)
+		return PyErr_SetFromErrno(PyExc_IOError);
+	if (sts != 0)
+		return PyInt_FromLong((long)sts);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+
+/* Our very own off_t-like type, 64-bit if possible */
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+typedef off_t Py_off_t;
+#elif SIZEOF_OFF_T >= 8
+typedef off_t Py_off_t;
+#elif SIZEOF_FPOS_T >= 8
+typedef fpos_t Py_off_t;
+#else
+#error "Large file support, but neither off_t nor fpos_t is large enough."
+#endif
+
+
+/* a portable fseek() function
+   return 0 on success, non-zero on failure (with errno set) */
+static int
+_portable_fseek(FILE *fp, Py_off_t offset, int whence)
+{
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+	return fseek(fp, offset, whence);
+#elif defined(HAVE_FSEEKO) && SIZEOF_OFF_T >= 8
+	return fseeko(fp, offset, whence);
+#elif defined(HAVE_FSEEK64)
+	return fseek64(fp, offset, whence);
+#elif defined(__BEOS__)
+	return _fseek(fp, offset, whence);
+#elif SIZEOF_FPOS_T >= 8
+	/* lacking a 64-bit capable fseek(), use a 64-bit capable fsetpos()
+	   and fgetpos() to implement fseek()*/
+	fpos_t pos;
+	switch (whence) {
+	case SEEK_END:
+#ifdef MS_WINDOWS
+		fflush(fp);
+		if (_lseeki64(fileno(fp), 0, 2) == -1)
+			return -1;
+#else
+		if (fseek(fp, 0, SEEK_END) != 0)
+			return -1;
+#endif
+		/* fall through */
+	case SEEK_CUR:
+		if (fgetpos(fp, &pos) != 0)
+			return -1;
+		offset += pos;
+		break;
+	/* case SEEK_SET: break; */
+	}
+	return fsetpos(fp, &offset);
+#else
+#error "Large file support, but no way to fseek."
+#endif
+}
+
+
+/* a portable ftell() function
+   Return -1 on failure with errno set appropriately, current file
+   position on success */
+static Py_off_t
+_portable_ftell(FILE* fp)
+{
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+	return ftell(fp);
+#elif defined(HAVE_FTELLO) && SIZEOF_OFF_T >= 8
+	return ftello(fp);
+#elif defined(HAVE_FTELL64)
+	return ftell64(fp);
+#elif SIZEOF_FPOS_T >= 8
+	fpos_t pos;
+	if (fgetpos(fp, &pos) != 0)
+		return -1;
+	return pos;
+#else
+#error "Large file support, but no way to ftell."
+#endif
+}
+
+
+static PyObject *
+file_seek(PyFileObject *f, PyObject *args)
+{
+	int whence;
+	int ret;
+	Py_off_t offset;
+	PyObject *offobj;
+
+	if (f->f_fp == NULL)
+		return err_closed();
+	drop_readahead(f);
+	whence = 0;
+	if (!PyArg_ParseTuple(args, "O|i:seek", &offobj, &whence))
+		return NULL;
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+	offset = PyInt_AsLong(offobj);
+#else
+	offset = PyLong_Check(offobj) ?
+		PyLong_AsLongLong(offobj) : PyInt_AsLong(offobj);
+#endif
+	if (PyErr_Occurred())
+		return NULL;
+
+	Py_BEGIN_ALLOW_THREADS
+	errno = 0;
+	ret = _portable_fseek(f->f_fp, offset, whence);
+	Py_END_ALLOW_THREADS
+
+	if (ret != 0) {
+		PyErr_SetFromErrno(PyExc_IOError);
+		clearerr(f->f_fp);
+		return NULL;
+	}
+	f->f_skipnextlf = 0;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+
+#ifdef HAVE_FTRUNCATE
+static PyObject *
+file_truncate(PyFileObject *f, PyObject *args)
+{
+	Py_off_t newsize;
+	PyObject *newsizeobj = NULL;
+	Py_off_t initialpos;
+	int ret;
+
+	if (f->f_fp == NULL)
+		return err_closed();
+	if (!PyArg_UnpackTuple(args, "truncate", 0, 1, &newsizeobj))
+		return NULL;
+
+	/* Get current file position.  If the file happens to be open for
+	 * update and the last operation was an input operation, C doesn't
+	 * define what the later fflush() will do, but we promise truncate()
+	 * won't change the current position (and fflush() *does* change it
+	 * then at least on Windows).  The easiest thing is to capture
+	 * current pos now and seek back to it at the end.
+	 */
+	Py_BEGIN_ALLOW_THREADS
+	errno = 0;
+	initialpos = _portable_ftell(f->f_fp);
+	Py_END_ALLOW_THREADS
+	if (initialpos == -1)
+		goto onioerror;
+
+	/* Set newsize to current postion if newsizeobj NULL, else to the
+	 * specified value.
+	 */
+	if (newsizeobj != NULL) {
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+		newsize = PyInt_AsLong(newsizeobj);
+#else
+		newsize = PyLong_Check(newsizeobj) ?
+				PyLong_AsLongLong(newsizeobj) :
+				PyInt_AsLong(newsizeobj);
+#endif
+		if (PyErr_Occurred())
+			return NULL;
+	}
+	else /* default to current position */
+		newsize = initialpos;
+
+	/* Flush the stream.  We're mixing stream-level I/O with lower-level
+	 * I/O, and a flush may be necessary to synch both platform views
+	 * of the current file state.
+	 */
+	Py_BEGIN_ALLOW_THREADS
+	errno = 0;
+	ret = fflush(f->f_fp);
+	Py_END_ALLOW_THREADS
+	if (ret != 0)
+		goto onioerror;
+
+#ifdef MS_WINDOWS
+	/* MS _chsize doesn't work if newsize doesn't fit in 32 bits,
+	   so don't even try using it. */
+	{
+		HANDLE hFile;
+
+		/* Have to move current pos to desired endpoint on Windows. */
+		Py_BEGIN_ALLOW_THREADS
+		errno = 0;
+		ret = _portable_fseek(f->f_fp, newsize, SEEK_SET) != 0;
+		Py_END_ALLOW_THREADS
+		if (ret)
+			goto onioerror;
+
+		/* Truncate.  Note that this may grow the file! */
+		Py_BEGIN_ALLOW_THREADS
+		errno = 0;
+		hFile = (HANDLE)_get_osfhandle(fileno(f->f_fp));
+		ret = hFile == (HANDLE)-1;
+		if (ret == 0) {
+			ret = SetEndOfFile(hFile) == 0;
+			if (ret)
+				errno = EACCES;
+		}
+		Py_END_ALLOW_THREADS
+		if (ret)
+			goto onioerror;
+	}
+#else
+	Py_BEGIN_ALLOW_THREADS
+	errno = 0;
+	ret = ftruncate(fileno(f->f_fp), newsize);
+	Py_END_ALLOW_THREADS
+	if (ret != 0)
+		goto onioerror;
+#endif /* !MS_WINDOWS */
+
+	/* Restore original file position. */
+	Py_BEGIN_ALLOW_THREADS
+	errno = 0;
+	ret = _portable_fseek(f->f_fp, initialpos, SEEK_SET) != 0;
+	Py_END_ALLOW_THREADS
+	if (ret)
+		goto onioerror;
+
+	Py_INCREF(Py_None);
+	return Py_None;
+
+onioerror:
+	PyErr_SetFromErrno(PyExc_IOError);
+	clearerr(f->f_fp);
+	return NULL;
+}
+#endif /* HAVE_FTRUNCATE */
+
+static PyObject *
+file_tell(PyFileObject *f)
+{
+	Py_off_t pos;
+
+	if (f->f_fp == NULL)
+		return err_closed();
+	Py_BEGIN_ALLOW_THREADS
+	errno = 0;
+	pos = _portable_ftell(f->f_fp);
+	Py_END_ALLOW_THREADS
+	if (pos == -1) {
+		PyErr_SetFromErrno(PyExc_IOError);
+		clearerr(f->f_fp);
+		return NULL;
+	}
+	if (f->f_skipnextlf) {
+		int c;
+		c = GETC(f->f_fp);
+		if (c == '\n') {
+			pos++;
+			f->f_skipnextlf = 0;
+		} else if (c != EOF) ungetc(c, f->f_fp);
+	}
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+	return PyInt_FromLong(pos);
+#else
+	return PyLong_FromLongLong(pos);
+#endif
+}
+
+static PyObject *
+file_fileno(PyFileObject *f)
+{
+	if (f->f_fp == NULL)
+		return err_closed();
+	return PyInt_FromLong((long) fileno(f->f_fp));
+}
+
+static PyObject *
+file_flush(PyFileObject *f)
+{
+	int res;
+
+	if (f->f_fp == NULL)
+		return err_closed();
+	Py_BEGIN_ALLOW_THREADS
+	errno = 0;
+	res = fflush(f->f_fp);
+	Py_END_ALLOW_THREADS
+	if (res != 0) {
+		PyErr_SetFromErrno(PyExc_IOError);
+		clearerr(f->f_fp);
+		return NULL;
+	}
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+file_isatty(PyFileObject *f)
+{
+	long res;
+	if (f->f_fp == NULL)
+		return err_closed();
+	Py_BEGIN_ALLOW_THREADS
+	res = isatty((int)fileno(f->f_fp));
+	Py_END_ALLOW_THREADS
+	return PyBool_FromLong(res);
+}
+
+
+#if BUFSIZ < 8192
+#define SMALLCHUNK 8192
+#else
+#define SMALLCHUNK BUFSIZ
+#endif
+
+#if SIZEOF_INT < 4
+#define BIGCHUNK  (512 * 32)
+#else
+#define BIGCHUNK  (512 * 1024)
+#endif
+
+static size_t
+new_buffersize(PyFileObject *f, size_t currentsize)
+{
+#ifdef HAVE_FSTAT
+	off_t pos, end;
+	struct stat st;
+	if (fstat(fileno(f->f_fp), &st) == 0) {
+		end = st.st_size;
+		/* The following is not a bug: we really need to call lseek()
+		   *and* ftell().  The reason is that some stdio libraries
+		   mistakenly flush their buffer when ftell() is called and
+		   the lseek() call it makes fails, thereby throwing away
+		   data that cannot be recovered in any way.  To avoid this,
+		   we first test lseek(), and only call ftell() if lseek()
+		   works.  We can't use the lseek() value either, because we
+		   need to take the amount of buffered data into account.
+		   (Yet another reason why stdio stinks. :-) */
+		pos = lseek(fileno(f->f_fp), 0L, SEEK_CUR);
+		if (pos >= 0) {
+			pos = ftell(f->f_fp);
+		}
+		if (pos < 0)
+			clearerr(f->f_fp);
+		if (end > pos && pos >= 0)
+			return currentsize + end - pos + 1;
+		/* Add 1 so if the file were to grow we'd notice. */
+	}
+#endif
+	if (currentsize > SMALLCHUNK) {
+		/* Keep doubling until we reach BIGCHUNK;
+		   then keep adding BIGCHUNK. */
+		if (currentsize <= BIGCHUNK)
+			return currentsize + currentsize;
+		else
+			return currentsize + BIGCHUNK;
+	}
+	return currentsize + SMALLCHUNK;
+}
+
+#if defined(EWOULDBLOCK) && defined(EAGAIN) && EWOULDBLOCK != EAGAIN
+#define BLOCKED_ERRNO(x) ((x) == EWOULDBLOCK || (x) == EAGAIN)
+#else
+#ifdef EWOULDBLOCK
+#define BLOCKED_ERRNO(x) ((x) == EWOULDBLOCK)
+#else
+#ifdef EAGAIN
+#define BLOCKED_ERRNO(x) ((x) == EAGAIN)
+#else
+#define BLOCKED_ERRNO(x) 0
+#endif
+#endif
+#endif
+
+static PyObject *
+file_read(PyFileObject *f, PyObject *args)
+{
+	long bytesrequested = -1;
+	size_t bytesread, buffersize, chunksize;
+	PyObject *v;
+
+	if (f->f_fp == NULL)
+		return err_closed();
+	/* refuse to mix with f.next() */
+	if (f->f_buf != NULL &&
+	    (f->f_bufend - f->f_bufptr) > 0 &&
+	    f->f_buf[0] != '\0')
+		return err_iterbuffered();
+	if (!PyArg_ParseTuple(args, "|l:read", &bytesrequested))
+		return NULL;
+	if (bytesrequested < 0)
+		buffersize = new_buffersize(f, (size_t)0);
+	else
+		buffersize = bytesrequested;
+	if (buffersize > PY_SSIZE_T_MAX) {
+		PyErr_SetString(PyExc_OverflowError,
+	"requested number of bytes is more than a Python string can hold");
+		return NULL;
+	}
+	v = PyString_FromStringAndSize((char *)NULL, buffersize);
+	if (v == NULL)
+		return NULL;
+	bytesread = 0;
+	for (;;) {
+		Py_BEGIN_ALLOW_THREADS
+		errno = 0;
+		chunksize = Py_UniversalNewlineFread(BUF(v) + bytesread,
+			  buffersize - bytesread, f->f_fp, (PyObject *)f);
+		Py_END_ALLOW_THREADS
+		if (chunksize == 0) {
+			if (!ferror(f->f_fp))
+				break;
+			clearerr(f->f_fp);
+			/* When in non-blocking mode, data shouldn't
+			 * be discarded if a blocking signal was
+			 * received. That will also happen if
+			 * chunksize != 0, but bytesread < buffersize. */
+			if (bytesread > 0 && BLOCKED_ERRNO(errno))
+				break;
+			PyErr_SetFromErrno(PyExc_IOError);
+			Py_DECREF(v);
+			return NULL;
+		}
+		bytesread += chunksize;
+		if (bytesread < buffersize) {
+			clearerr(f->f_fp);
+			break;
+		}
+		if (bytesrequested < 0) {
+			buffersize = new_buffersize(f, buffersize);
+			if (_PyString_Resize(&v, buffersize) < 0)
+				return NULL;
+		} else {
+			/* Got what was requested. */
+			break;
+		}
+	}
+	if (bytesread != buffersize)
+		_PyString_Resize(&v, bytesread);
+	return v;
+}
+
+static PyObject *
+file_readinto(PyFileObject *f, PyObject *args)
+{
+	char *ptr;
+	Py_ssize_t ntodo;
+	Py_ssize_t ndone, nnow;
+
+	if (f->f_fp == NULL)
+		return err_closed();
+	/* refuse to mix with f.next() */
+	if (f->f_buf != NULL &&
+	    (f->f_bufend - f->f_bufptr) > 0 &&
+	    f->f_buf[0] != '\0')
+		return err_iterbuffered();
+	if (!PyArg_ParseTuple(args, "w#", &ptr, &ntodo))
+		return NULL;
+	ndone = 0;
+	while (ntodo > 0) {
+		Py_BEGIN_ALLOW_THREADS
+		errno = 0;
+		nnow = Py_UniversalNewlineFread(ptr+ndone, ntodo, f->f_fp,
+						(PyObject *)f);
+		Py_END_ALLOW_THREADS
+		if (nnow == 0) {
+			if (!ferror(f->f_fp))
+				break;
+			PyErr_SetFromErrno(PyExc_IOError);
+			clearerr(f->f_fp);
+			return NULL;
+		}
+		ndone += nnow;
+		ntodo -= nnow;
+	}
+	return PyInt_FromSsize_t(ndone);
+}
+
+/**************************************************************************
+Routine to get next line using platform fgets().
+
+Under MSVC 6:
+
++ MS threadsafe getc is very slow (multiple layers of function calls before+
+  after each character, to lock+unlock the stream).
++ The stream-locking functions are MS-internal -- can't access them from user
+  code.
++ There's nothing Tim could find in the MS C or platform SDK libraries that
+  can worm around this.
++ MS fgets locks/unlocks only once per line; it's the only hook we have.
+
+So we use fgets for speed(!), despite that it's painful.
+
+MS realloc is also slow.
+
+Reports from other platforms on this method vs getc_unlocked (which MS doesn't
+have):
+	Linux		a wash
+	Solaris		a wash
+	Tru64 Unix	getline_via_fgets significantly faster
+
+CAUTION:  The C std isn't clear about this:  in those cases where fgets
+writes something into the buffer, can it write into any position beyond the
+required trailing null byte?  MSVC 6 fgets does not, and no platform is (yet)
+known on which it does; and it would be a strange way to code fgets. Still,
+getline_via_fgets may not work correctly if it does.  The std test
+test_bufio.py should fail if platform fgets() routinely writes beyond the
+trailing null byte.  #define DONT_USE_FGETS_IN_GETLINE to disable this code.
+**************************************************************************/
+
+/* Use this routine if told to, or by default on non-get_unlocked()
+ * platforms unless told not to.  Yikes!  Let's spell that out:
+ * On a platform with getc_unlocked():
+ *     By default, use getc_unlocked().
+ *     If you want to use fgets() instead, #define USE_FGETS_IN_GETLINE.
+ * On a platform without getc_unlocked():
+ *     By default, use fgets().
+ *     If you don't want to use fgets(), #define DONT_USE_FGETS_IN_GETLINE.
+ */
+#if !defined(USE_FGETS_IN_GETLINE) && !defined(HAVE_GETC_UNLOCKED)
+#define USE_FGETS_IN_GETLINE
+#endif
+
+#if defined(DONT_USE_FGETS_IN_GETLINE) && defined(USE_FGETS_IN_GETLINE)
+#undef USE_FGETS_IN_GETLINE
+#endif
+
+#ifdef USE_FGETS_IN_GETLINE
+static PyObject*
+getline_via_fgets(FILE *fp)
+{
+/* INITBUFSIZE is the maximum line length that lets us get away with the fast
+ * no-realloc, one-fgets()-call path.  Boosting it isn't free, because we have
+ * to fill this much of the buffer with a known value in order to figure out
+ * how much of the buffer fgets() overwrites.  So if INITBUFSIZE is larger
+ * than "most" lines, we waste time filling unused buffer slots.  100 is
+ * surely adequate for most peoples' email archives, chewing over source code,
+ * etc -- "regular old text files".
+ * MAXBUFSIZE is the maximum line length that lets us get away with the less
+ * fast (but still zippy) no-realloc, two-fgets()-call path.  See above for
+ * cautions about boosting that.  300 was chosen because the worst real-life
+ * text-crunching job reported on Python-Dev was a mail-log crawler where over
+ * half the lines were 254 chars.
+ */
+#define INITBUFSIZE 100
+#define MAXBUFSIZE 300
+	char* p;	/* temp */
+	char buf[MAXBUFSIZE];
+	PyObject* v;	/* the string object result */
+	char* pvfree;	/* address of next free slot */
+	char* pvend;    /* address one beyond last free slot */
+	size_t nfree;	/* # of free buffer slots; pvend-pvfree */
+	size_t total_v_size;  /* total # of slots in buffer */
+	size_t increment;	/* amount to increment the buffer */
+	size_t prev_v_size;
+
+	/* Optimize for normal case:  avoid _PyString_Resize if at all
+	 * possible via first reading into stack buffer "buf".
+	 */
+	total_v_size = INITBUFSIZE;	/* start small and pray */
+	pvfree = buf;
+	for (;;) {
+		Py_BEGIN_ALLOW_THREADS
+		pvend = buf + total_v_size;
+		nfree = pvend - pvfree;
+		memset(pvfree, '\n', nfree);
+		assert(nfree < INT_MAX); /* Should be atmost MAXBUFSIZE */
+		p = fgets(pvfree, (int)nfree, fp);
+		Py_END_ALLOW_THREADS
+
+		if (p == NULL) {
+			clearerr(fp);
+			if (PyErr_CheckSignals())
+				return NULL;
+			v = PyString_FromStringAndSize(buf, pvfree - buf);
+			return v;
+		}
+		/* fgets read *something* */
+		p = memchr(pvfree, '\n', nfree);
+		if (p != NULL) {
+			/* Did the \n come from fgets or from us?
+			 * Since fgets stops at the first \n, and then writes
+			 * \0, if it's from fgets a \0 must be next.  But if
+			 * that's so, it could not have come from us, since
+			 * the \n's we filled the buffer with have only more
+			 * \n's to the right.
+			 */
+			if (p+1 < pvend && *(p+1) == '\0') {
+				/* It's from fgets:  we win!  In particular,
+				 * we haven't done any mallocs yet, and can
+				 * build the final result on the first try.
+				 */
+				++p;	/* include \n from fgets */
+			}
+			else {
+				/* Must be from us:  fgets didn't fill the
+				 * buffer and didn't find a newline, so it
+				 * must be the last and newline-free line of
+				 * the file.
+				 */
+				assert(p > pvfree && *(p-1) == '\0');
+				--p;	/* don't include \0 from fgets */
+			}
+			v = PyString_FromStringAndSize(buf, p - buf);
+			return v;
+		}
+		/* yuck:  fgets overwrote all the newlines, i.e. the entire
+		 * buffer.  So this line isn't over yet, or maybe it is but
+		 * we're exactly at EOF.  If we haven't already, try using the
+		 * rest of the stack buffer.
+		 */
+		assert(*(pvend-1) == '\0');
+		if (pvfree == buf) {
+			pvfree = pvend - 1;	/* overwrite trailing null */
+			total_v_size = MAXBUFSIZE;
+		}
+		else
+			break;
+	}
+
+	/* The stack buffer isn't big enough; malloc a string object and read
+	 * into its buffer.
+	 */
+	total_v_size = MAXBUFSIZE << 1;
+	v = PyString_FromStringAndSize((char*)NULL, (int)total_v_size);
+	if (v == NULL)
+		return v;
+	/* copy over everything except the last null byte */
+	memcpy(BUF(v), buf, MAXBUFSIZE-1);
+	pvfree = BUF(v) + MAXBUFSIZE - 1;
+
+	/* Keep reading stuff into v; if it ever ends successfully, break
+	 * after setting p one beyond the end of the line.  The code here is
+	 * very much like the code above, except reads into v's buffer; see
+	 * the code above for detailed comments about the logic.
+	 */
+	for (;;) {
+		Py_BEGIN_ALLOW_THREADS
+		pvend = BUF(v) + total_v_size;
+		nfree = pvend - pvfree;
+		memset(pvfree, '\n', nfree);
+		assert(nfree < INT_MAX);
+		p = fgets(pvfree, (int)nfree, fp);
+		Py_END_ALLOW_THREADS
+
+		if (p == NULL) {
+			clearerr(fp);
+			if (PyErr_CheckSignals()) {
+				Py_DECREF(v);
+				return NULL;
+			}
+			p = pvfree;
+			break;
+		}
+		p = memchr(pvfree, '\n', nfree);
+		if (p != NULL) {
+			if (p+1 < pvend && *(p+1) == '\0') {
+				/* \n came from fgets */
+				++p;
+				break;
+			}
+			/* \n came from us; last line of file, no newline */
+			assert(p > pvfree && *(p-1) == '\0');
+			--p;
+			break;
+		}
+		/* expand buffer and try again */
+		assert(*(pvend-1) == '\0');
+		increment = total_v_size >> 2;	/* mild exponential growth */
+		prev_v_size = total_v_size;
+		total_v_size += increment;
+		/* check for overflow */
+		if (total_v_size <= prev_v_size ||
+		    total_v_size > PY_SSIZE_T_MAX) {
+			PyErr_SetString(PyExc_OverflowError,
+			    "line is longer than a Python string can hold");
+			Py_DECREF(v);
+			return NULL;
+		}
+		if (_PyString_Resize(&v, (int)total_v_size) < 0)
+			return NULL;
+		/* overwrite the trailing null byte */
+		pvfree = BUF(v) + (prev_v_size - 1);
+	}
+	if (BUF(v) + total_v_size != p)
+		_PyString_Resize(&v, p - BUF(v));
+	return v;
+#undef INITBUFSIZE
+#undef MAXBUFSIZE
+}
+#endif	/* ifdef USE_FGETS_IN_GETLINE */
+
+/* Internal routine to get a line.
+   Size argument interpretation:
+   > 0: max length;
+   <= 0: read arbitrary line
+*/
+
+static PyObject *
+get_line(PyFileObject *f, int n)
+{
+	FILE *fp = f->f_fp;
+	int c;
+	char *buf, *end;
+	size_t total_v_size;	/* total # of slots in buffer */
+	size_t used_v_size;	/* # used slots in buffer */
+	size_t increment;       /* amount to increment the buffer */
+	PyObject *v;
+	int newlinetypes = f->f_newlinetypes;
+	int skipnextlf = f->f_skipnextlf;
+	int univ_newline = f->f_univ_newline;
+
+#if defined(USE_FGETS_IN_GETLINE)
+	if (n <= 0 && !univ_newline )
+		return getline_via_fgets(fp);
+#endif
+	total_v_size = n > 0 ? n : 100;
+	v = PyString_FromStringAndSize((char *)NULL, total_v_size);
+	if (v == NULL)
+		return NULL;
+	buf = BUF(v);
+	end = buf + total_v_size;
+
+	for (;;) {
+		Py_BEGIN_ALLOW_THREADS
+		FLOCKFILE(fp);
+		if (univ_newline) {
+			c = 'x'; /* Shut up gcc warning */
+			while ( buf != end && (c = GETC(fp)) != EOF ) {
+				if (skipnextlf ) {
+					skipnextlf = 0;
+					if (c == '\n') {
+						/* Seeing a \n here with
+						 * skipnextlf true means we
+						 * saw a \r before.
+						 */
+						newlinetypes |= NEWLINE_CRLF;
+						c = GETC(fp);
+						if (c == EOF) break;
+					} else {
+						newlinetypes |= NEWLINE_CR;
+					}
+				}
+				if (c == '\r') {
+					skipnextlf = 1;
+					c = '\n';
+				} else if ( c == '\n')
+					newlinetypes |= NEWLINE_LF;
+				*buf++ = c;
+				if (c == '\n') break;
+			}
+			if ( c == EOF && skipnextlf )
+				newlinetypes |= NEWLINE_CR;
+		} else /* If not universal newlines use the normal loop */
+		while ((c = GETC(fp)) != EOF &&
+		       (*buf++ = c) != '\n' &&
+			buf != end)
+			;
+		FUNLOCKFILE(fp);
+		Py_END_ALLOW_THREADS
+		f->f_newlinetypes = newlinetypes;
+		f->f_skipnextlf = skipnextlf;
+		if (c == '\n')
+			break;
+		if (c == EOF) {
+			if (ferror(fp)) {
+				PyErr_SetFromErrno(PyExc_IOError);
+				clearerr(fp);
+				Py_DECREF(v);
+				return NULL;
+			}
+			clearerr(fp);
+			if (PyErr_CheckSignals()) {
+				Py_DECREF(v);
+				return NULL;
+			}
+			break;
+		}
+		/* Must be because buf == end */
+		if (n > 0)
+			break;
+		used_v_size = total_v_size;
+		increment = total_v_size >> 2; /* mild exponential growth */
+		total_v_size += increment;
+		if (total_v_size > PY_SSIZE_T_MAX) {
+			PyErr_SetString(PyExc_OverflowError,
+			    "line is longer than a Python string can hold");
+			Py_DECREF(v);
+			return NULL;
+		}
+		if (_PyString_Resize(&v, total_v_size) < 0)
+			return NULL;
+		buf = BUF(v) + used_v_size;
+		end = BUF(v) + total_v_size;
+	}
+
+	used_v_size = buf - BUF(v);
+	if (used_v_size != total_v_size)
+		_PyString_Resize(&v, used_v_size);
+	return v;
+}
+
+/* External C interface */
+
+PyObject *
+PyFile_GetLine(PyObject *f, int n)
+{
+	PyObject *result;
+
+	if (f == NULL) {
+		PyErr_BadInternalCall();
+		return NULL;
+	}
+
+	if (PyFile_Check(f)) {
+		PyFileObject *fo = (PyFileObject *)f;
+		if (fo->f_fp == NULL)
+			return err_closed();
+		/* refuse to mix with f.next() */
+		if (fo->f_buf != NULL &&
+		    (fo->f_bufend - fo->f_bufptr) > 0 &&
+		    fo->f_buf[0] != '\0')
+			return err_iterbuffered();
+		result = get_line(fo, n);
+	}
+	else {
+		PyObject *reader;
+		PyObject *args;
+
+		reader = PyObject_GetAttrString(f, "readline");
+		if (reader == NULL)
+			return NULL;
+		if (n <= 0)
+			args = PyTuple_New(0);
+		else
+			args = Py_BuildValue("(i)", n);
+		if (args == NULL) {
+			Py_DECREF(reader);
+			return NULL;
+		}
+		result = PyEval_CallObject(reader, args);
+		Py_DECREF(reader);
+		Py_DECREF(args);
+		if (result != NULL && !PyString_Check(result) &&
+		    !PyUnicode_Check(result)) {
+			Py_DECREF(result);
+			result = NULL;
+			PyErr_SetString(PyExc_TypeError,
+				   "object.readline() returned non-string");
+		}
+	}
+
+	if (n < 0 && result != NULL && PyString_Check(result)) {
+		char *s = PyString_AS_STRING(result);
+		Py_ssize_t len = PyString_GET_SIZE(result);
+		if (len == 0) {
+			Py_DECREF(result);
+			result = NULL;
+			PyErr_SetString(PyExc_EOFError,
+					"EOF when reading a line");
+		}
+		else if (s[len-1] == '\n') {
+			if (result->ob_refcnt == 1)
+				_PyString_Resize(&result, len-1);
+			else {
+				PyObject *v;
+				v = PyString_FromStringAndSize(s, len-1);
+				Py_DECREF(result);
+				result = v;
+			}
+		}
+	}
+#ifdef Py_USING_UNICODE
+	if (n < 0 && result != NULL && PyUnicode_Check(result)) {
+		Py_UNICODE *s = PyUnicode_AS_UNICODE(result);
+		Py_ssize_t len = PyUnicode_GET_SIZE(result);
+		if (len == 0) {
+			Py_DECREF(result);
+			result = NULL;
+			PyErr_SetString(PyExc_EOFError,
+					"EOF when reading a line");
+		}
+		else if (s[len-1] == '\n') {
+			if (result->ob_refcnt == 1)
+				PyUnicode_Resize(&result, len-1);
+			else {
+				PyObject *v;
+				v = PyUnicode_FromUnicode(s, len-1);
+				Py_DECREF(result);
+				result = v;
+			}
+		}
+	}
+#endif
+	return result;
+}
+
+/* Python method */
+
+static PyObject *
+file_readline(PyFileObject *f, PyObject *args)
+{
+	int n = -1;
+
+	if (f->f_fp == NULL)
+		return err_closed();
+	/* refuse to mix with f.next() */
+	if (f->f_buf != NULL &&
+	    (f->f_bufend - f->f_bufptr) > 0 &&
+	    f->f_buf[0] != '\0')
+		return err_iterbuffered();
+	if (!PyArg_ParseTuple(args, "|i:readline", &n))
+		return NULL;
+	if (n == 0)
+		return PyString_FromString("");
+	if (n < 0)
+		n = 0;
+	return get_line(f, n);
+}
+
+static PyObject *
+file_readlines(PyFileObject *f, PyObject *args)
+{
+	long sizehint = 0;
+	PyObject *list;
+	PyObject *line;
+	char small_buffer[SMALLCHUNK];
+	char *buffer = small_buffer;
+	size_t buffersize = SMALLCHUNK;
+	PyObject *big_buffer = NULL;
+	size_t nfilled = 0;
+	size_t nread;
+	size_t totalread = 0;
+	char *p, *q, *end;
+	int err;
+	int shortread = 0;
+
+	if (f->f_fp == NULL)
+		return err_closed();
+	/* refuse to mix with f.next() */
+	if (f->f_buf != NULL &&
+	    (f->f_bufend - f->f_bufptr) > 0 &&
+	    f->f_buf[0] != '\0')
+		return err_iterbuffered();
+	if (!PyArg_ParseTuple(args, "|l:readlines", &sizehint))
+		return NULL;
+	if ((list = PyList_New(0)) == NULL)
+		return NULL;
+	for (;;) {
+		if (shortread)
+			nread = 0;
+		else {
+			Py_BEGIN_ALLOW_THREADS
+			errno = 0;
+			nread = Py_UniversalNewlineFread(buffer+nfilled,
+				buffersize-nfilled, f->f_fp, (PyObject *)f);
+			Py_END_ALLOW_THREADS
+			shortread = (nread < buffersize-nfilled);
+		}
+		if (nread == 0) {
+			sizehint = 0;
+			if (!ferror(f->f_fp))
+				break;
+			PyErr_SetFromErrno(PyExc_IOError);
+			clearerr(f->f_fp);
+		  error:
+			Py_DECREF(list);
+			list = NULL;
+			goto cleanup;
+		}
+		totalread += nread;
+		p = (char *)memchr(buffer+nfilled, '\n', nread);
+		if (p == NULL) {
+			/* Need a larger buffer to fit this line */
+			nfilled += nread;
+			buffersize *= 2;
+			if (buffersize > PY_SSIZE_T_MAX) {
+				PyErr_SetString(PyExc_OverflowError,
+			    "line is longer than a Python string can hold");
+				goto error;
+			}
+			if (big_buffer == NULL) {
+				/* Create the big buffer */
+				big_buffer = PyString_FromStringAndSize(
+					NULL, buffersize);
+				if (big_buffer == NULL)
+					goto error;
+				buffer = PyString_AS_STRING(big_buffer);
+				memcpy(buffer, small_buffer, nfilled);
+			}
+			else {
+				/* Grow the big buffer */
+				if ( _PyString_Resize(&big_buffer, buffersize) < 0 )
+					goto error;
+				buffer = PyString_AS_STRING(big_buffer);
+			}
+			continue;
+		}
+		end = buffer+nfilled+nread;
+		q = buffer;
+		do {
+			/* Process complete lines */
+			p++;
+			line = PyString_FromStringAndSize(q, p-q);
+			if (line == NULL)
+				goto error;
+			err = PyList_Append(list, line);
+			Py_DECREF(line);
+			if (err != 0)
+				goto error;
+			q = p;
+			p = (char *)memchr(q, '\n', end-q);
+		} while (p != NULL);
+		/* Move the remaining incomplete line to the start */
+		nfilled = end-q;
+		memmove(buffer, q, nfilled);
+		if (sizehint > 0)
+			if (totalread >= (size_t)sizehint)
+				break;
+	}
+	if (nfilled != 0) {
+		/* Partial last line */
+		line = PyString_FromStringAndSize(buffer, nfilled);
+		if (line == NULL)
+			goto error;
+		if (sizehint > 0) {
+			/* Need to complete the last line */
+			PyObject *rest = get_line(f, 0);
+			if (rest == NULL) {
+				Py_DECREF(line);
+				goto error;
+			}
+			PyString_Concat(&line, rest);
+			Py_DECREF(rest);
+			if (line == NULL)
+				goto error;
+		}
+		err = PyList_Append(list, line);
+		Py_DECREF(line);
+		if (err != 0)
+			goto error;
+	}
+  cleanup:
+	Py_XDECREF(big_buffer);
+	return list;
+}
+
+static PyObject *
+file_write(PyFileObject *f, PyObject *args)
+{
+	char *s;
+	Py_ssize_t n, n2;
+	if (f->f_fp == NULL)
+		return err_closed();
+	if (!PyArg_ParseTuple(args, f->f_binary ? "s#" : "t#", &s, &n))
+		return NULL;
+	f->f_softspace = 0;
+	Py_BEGIN_ALLOW_THREADS
+	errno = 0;
+	n2 = fwrite(s, 1, n, f->f_fp);
+	Py_END_ALLOW_THREADS
+	if (n2 != n) {
+		PyErr_SetFromErrno(PyExc_IOError);
+		clearerr(f->f_fp);
+		return NULL;
+	}
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+file_writelines(PyFileObject *f, PyObject *seq)
+{
+#define CHUNKSIZE 1000
+	PyObject *list, *line;
+	PyObject *it;	/* iter(seq) */
+	PyObject *result;
+	int index, islist;
+	Py_ssize_t i, j, nwritten, len;
+
+	assert(seq != NULL);
+	if (f->f_fp == NULL)
+		return err_closed();
+
+	result = NULL;
+	list = NULL;
+	islist = PyList_Check(seq);
+	if  (islist)
+		it = NULL;
+	else {
+		it = PyObject_GetIter(seq);
+		if (it == NULL) {
+			PyErr_SetString(PyExc_TypeError,
+				"writelines() requires an iterable argument");
+			return NULL;
+		}
+		/* From here on, fail by going to error, to reclaim "it". */
+		list = PyList_New(CHUNKSIZE);
+		if (list == NULL)
+			goto error;
+	}
+
+	/* Strategy: slurp CHUNKSIZE lines into a private list,
+	   checking that they are all strings, then write that list
+	   without holding the interpreter lock, then come back for more. */
+	for (index = 0; ; index += CHUNKSIZE) {
+		if (islist) {
+			Py_XDECREF(list);
+			list = PyList_GetSlice(seq, index, index+CHUNKSIZE);
+			if (list == NULL)
+				goto error;
+			j = PyList_GET_SIZE(list);
+		}
+		else {
+			for (j = 0; j < CHUNKSIZE; j++) {
+				line = PyIter_Next(it);
+				if (line == NULL) {
+					if (PyErr_Occurred())
+						goto error;
+					break;
+				}
+				PyList_SetItem(list, j, line);
+			}
+		}
+		if (j == 0)
+			break;
+
+		/* Check that all entries are indeed strings. If not,
+		   apply the same rules as for file.write() and
+		   convert the results to strings. This is slow, but
+		   seems to be the only way since all conversion APIs
+		   could potentially execute Python code. */
+		for (i = 0; i < j; i++) {
+			PyObject *v = PyList_GET_ITEM(list, i);
+			if (!PyString_Check(v)) {
+			    	const char *buffer;
+				if (((f->f_binary &&
+				      PyObject_AsReadBuffer(v,
+					      (const void**)&buffer,
+							    &len)) ||
+				     PyObject_AsCharBuffer(v,
+							   &buffer,
+							   &len))) {
+					PyErr_SetString(PyExc_TypeError,
+			"writelines() argument must be a sequence of strings");
+					goto error;
+				}
+				line = PyString_FromStringAndSize(buffer,
+								  len);
+				if (line == NULL)
+					goto error;
+				Py_DECREF(v);
+				PyList_SET_ITEM(list, i, line);
+			}
+		}
+
+		/* Since we are releasing the global lock, the
+		   following code may *not* execute Python code. */
+		Py_BEGIN_ALLOW_THREADS
+		f->f_softspace = 0;
+		errno = 0;
+		for (i = 0; i < j; i++) {
+		    	line = PyList_GET_ITEM(list, i);
+			len = PyString_GET_SIZE(line);
+			nwritten = fwrite(PyString_AS_STRING(line),
+					  1, len, f->f_fp);
+			if (nwritten != len) {
+				Py_BLOCK_THREADS
+				PyErr_SetFromErrno(PyExc_IOError);
+				clearerr(f->f_fp);
+				goto error;
+			}
+		}
+		Py_END_ALLOW_THREADS
+
+		if (j < CHUNKSIZE)
+			break;
+	}
+
+	Py_INCREF(Py_None);
+	result = Py_None;
+  error:
+	Py_XDECREF(list);
+  	Py_XDECREF(it);
+	return result;
+#undef CHUNKSIZE
+}
+
+static PyObject *
+file_self(PyFileObject *f)
+{
+	if (f->f_fp == NULL)
+		return err_closed();
+	Py_INCREF(f);
+	return (PyObject *)f;
+}
+
+static PyObject *
+file_exit(PyFileObject *f, PyObject *args)
+{
+	PyObject *ret = file_close(f);
+	if (!ret)
+		/* If error occurred, pass through */
+		return NULL;
+	Py_DECREF(ret);
+	/* We cannot return the result of close since a true
+	 * value will be interpreted as "yes, swallow the
+	 * exception if one was raised inside the with block". */
+	Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(readline_doc,
+"readline([size]) -> next line from the file, as a string.\n"
+"\n"
+"Retain newline.  A non-negative size argument limits the maximum\n"
+"number of bytes to return (an incomplete line may be returned then).\n"
+"Return an empty string at EOF.");
+
+PyDoc_STRVAR(read_doc,
+"read([size]) -> read at most size bytes, returned as a string.\n"
+"\n"
+"If the size argument is negative or omitted, read until EOF is reached.\n"
+"Notice that when in non-blocking mode, less data than what was requested\n"
+"may be returned, even if no size parameter was given.");
+
+PyDoc_STRVAR(write_doc,
+"write(str) -> None.  Write string str to file.\n"
+"\n"
+"Note that due to buffering, flush() or close() may be needed before\n"
+"the file on disk reflects the data written.");
+
+PyDoc_STRVAR(fileno_doc,
+"fileno() -> integer \"file descriptor\".\n"
+"\n"
+"This is needed for lower-level file interfaces, such os.read().");
+
+PyDoc_STRVAR(seek_doc,
+"seek(offset[, whence]) -> None.  Move to new file position.\n"
+"\n"
+"Argument offset is a byte count.  Optional argument whence defaults to\n"
+"0 (offset from start of file, offset should be >= 0); other values are 1\n"
+"(move relative to current position, positive or negative), and 2 (move\n"
+"relative to end of file, usually negative, although many platforms allow\n"
+"seeking beyond the end of a file).  If the file is opened in text mode,\n"
+"only offsets returned by tell() are legal.  Use of other offsets causes\n"
+"undefined behavior."
+"\n"
+"Note that not all file objects are seekable.");
+
+#ifdef HAVE_FTRUNCATE
+PyDoc_STRVAR(truncate_doc,
+"truncate([size]) -> None.  Truncate the file to at most size bytes.\n"
+"\n"
+"Size defaults to the current file position, as returned by tell().");
+#endif
+
+PyDoc_STRVAR(tell_doc,
+"tell() -> current file position, an integer (may be a long integer).");
+
+PyDoc_STRVAR(readinto_doc,
+"readinto() -> Undocumented.  Don't use this; it may go away.");
+
+PyDoc_STRVAR(readlines_doc,
+"readlines([size]) -> list of strings, each a line from the file.\n"
+"\n"
+"Call readline() repeatedly and return a list of the lines so read.\n"
+"The optional size argument, if given, is an approximate bound on the\n"
+"total number of bytes in the lines returned.");
+
+PyDoc_STRVAR(xreadlines_doc,
+"xreadlines() -> returns self.\n"
+"\n"
+"For backward compatibility. File objects now include the performance\n"
+"optimizations previously implemented in the xreadlines module.");
+
+PyDoc_STRVAR(writelines_doc,
+"writelines(sequence_of_strings) -> None.  Write the strings to the file.\n"
+"\n"
+"Note that newlines are not added.  The sequence can be any iterable object\n"
+"producing strings. This is equivalent to calling write() for each string.");
+
+PyDoc_STRVAR(flush_doc,
+"flush() -> None.  Flush the internal I/O buffer.");
+
+PyDoc_STRVAR(close_doc,
+"close() -> None or (perhaps) an integer.  Close the file.\n"
+"\n"
+"Sets data attribute .closed to True.  A closed file cannot be used for\n"
+"further I/O operations.  close() may be called more than once without\n"
+"error.  Some kinds of file objects (for example, opened by popen())\n"
+"may return an exit status upon closing.");
+
+PyDoc_STRVAR(isatty_doc,
+"isatty() -> true or false.  True if the file is connected to a tty device.");
+
+PyDoc_STRVAR(enter_doc,
+	     "__enter__() -> self.");
+
+PyDoc_STRVAR(exit_doc,
+	     "__exit__(*excinfo) -> None.  Closes the file.");
+
+static PyMethodDef file_methods[] = {
+	{"readline",  (PyCFunction)file_readline, METH_VARARGS, readline_doc},
+	{"read",      (PyCFunction)file_read,     METH_VARARGS, read_doc},
+	{"write",     (PyCFunction)file_write,    METH_VARARGS, write_doc},
+	{"fileno",    (PyCFunction)file_fileno,   METH_NOARGS,  fileno_doc},
+	{"seek",      (PyCFunction)file_seek,     METH_VARARGS, seek_doc},
+#ifdef HAVE_FTRUNCATE
+	{"truncate",  (PyCFunction)file_truncate, METH_VARARGS, truncate_doc},
+#endif
+	{"tell",      (PyCFunction)file_tell,     METH_NOARGS,  tell_doc},
+	{"readinto",  (PyCFunction)file_readinto, METH_VARARGS, readinto_doc},
+	{"readlines", (PyCFunction)file_readlines,METH_VARARGS, readlines_doc},
+	{"xreadlines",(PyCFunction)file_self,     METH_NOARGS, xreadlines_doc},
+	{"writelines",(PyCFunction)file_writelines, METH_O,    writelines_doc},
+	{"flush",     (PyCFunction)file_flush,    METH_NOARGS,  flush_doc},
+	{"close",     (PyCFunction)file_close,    METH_NOARGS,  close_doc},
+	{"isatty",    (PyCFunction)file_isatty,   METH_NOARGS,  isatty_doc},
+	{"__enter__", (PyCFunction)file_self,     METH_NOARGS,  enter_doc},
+	{"__exit__",  (PyCFunction)file_exit,     METH_VARARGS, exit_doc},
+	{NULL,	      NULL}		/* sentinel */
+};
+
+#define OFF(x) offsetof(PyFileObject, x)
+
+static PyMemberDef file_memberlist[] = {
+	{"softspace",	T_INT,		OFF(f_softspace), 0,
+	 "flag indicating that a space needs to be printed; used by print"},
+	{"mode",	T_OBJECT,	OFF(f_mode),	RO,
+	 "file mode ('r', 'U', 'w', 'a', possibly with 'b' or '+' added)"},
+	{"name",	T_OBJECT,	OFF(f_name),	RO,
+	 "file name"},
+	{"encoding",	T_OBJECT,	OFF(f_encoding),	RO,
+	 "file encoding"},
+	/* getattr(f, "closed") is implemented without this table */
+	{NULL}	/* Sentinel */
+};
+
+static PyObject *
+get_closed(PyFileObject *f, void *closure)
+{
+	return PyBool_FromLong((long)(f->f_fp == 0));
+}
+static PyObject *
+get_newlines(PyFileObject *f, void *closure)
+{
+	switch (f->f_newlinetypes) {
+	case NEWLINE_UNKNOWN:
+		Py_INCREF(Py_None);
+		return Py_None;
+	case NEWLINE_CR:
+		return PyString_FromString("\r");
+	case NEWLINE_LF:
+		return PyString_FromString("\n");
+	case NEWLINE_CR|NEWLINE_LF:
+		return Py_BuildValue("(ss)", "\r", "\n");
+	case NEWLINE_CRLF:
+		return PyString_FromString("\r\n");
+	case NEWLINE_CR|NEWLINE_CRLF:
+		return Py_BuildValue("(ss)", "\r", "\r\n");
+	case NEWLINE_LF|NEWLINE_CRLF:
+		return Py_BuildValue("(ss)", "\n", "\r\n");
+	case NEWLINE_CR|NEWLINE_LF|NEWLINE_CRLF:
+		return Py_BuildValue("(sss)", "\r", "\n", "\r\n");
+	default:
+		PyErr_Format(PyExc_SystemError,
+			     "Unknown newlines value 0x%x\n",
+			     f->f_newlinetypes);
+		return NULL;
+	}
+}
+
+static PyGetSetDef file_getsetlist[] = {
+	{"closed", (getter)get_closed, NULL, "True if the file is closed"},
+	{"newlines", (getter)get_newlines, NULL,
+	 "end-of-line convention used in this file"},
+	{0},
+};
+
+static void
+drop_readahead(PyFileObject *f)
+{
+	if (f->f_buf != NULL) {
+		PyMem_Free(f->f_buf);
+		f->f_buf = NULL;
+	}
+}
+
+/* Make sure that file has a readahead buffer with at least one byte
+   (unless at EOF) and no more than bufsize.  Returns negative value on
+   error, will set MemoryError if bufsize bytes cannot be allocated. */
+static int
+readahead(PyFileObject *f, int bufsize)
+{
+	Py_ssize_t chunksize;
+
+	if (f->f_buf != NULL) {
+		if( (f->f_bufend - f->f_bufptr) >= 1)
+			return 0;
+		else
+			drop_readahead(f);
+	}
+	if ((f->f_buf = (char *)PyMem_Malloc(bufsize)) == NULL) {
+		PyErr_NoMemory();
+		return -1;
+	}
+	Py_BEGIN_ALLOW_THREADS
+	errno = 0;
+	chunksize = Py_UniversalNewlineFread(
+		f->f_buf, bufsize, f->f_fp, (PyObject *)f);
+	Py_END_ALLOW_THREADS
+	if (chunksize == 0) {
+		if (ferror(f->f_fp)) {
+			PyErr_SetFromErrno(PyExc_IOError);
+			clearerr(f->f_fp);
+			drop_readahead(f);
+			return -1;
+		}
+	}
+	f->f_bufptr = f->f_buf;
+	f->f_bufend = f->f_buf + chunksize;
+	return 0;
+}
+
+/* Used by file_iternext.  The returned string will start with 'skip'
+   uninitialized bytes followed by the remainder of the line. Don't be
+   horrified by the recursive call: maximum recursion depth is limited by
+   logarithmic buffer growth to about 50 even when reading a 1gb line. */
+
+static PyStringObject *
+readahead_get_line_skip(PyFileObject *f, int skip, int bufsize)
+{
+	PyStringObject* s;
+	char *bufptr;
+	char *buf;
+	Py_ssize_t len;
+
+	if (f->f_buf == NULL)
+		if (readahead(f, bufsize) < 0)
+			return NULL;
+
+	len = f->f_bufend - f->f_bufptr;
+	if (len == 0)
+		return (PyStringObject *)
+			PyString_FromStringAndSize(NULL, skip);
+	bufptr = (char *)memchr(f->f_bufptr, '\n', len);
+	if (bufptr != NULL) {
+		bufptr++;			/* Count the '\n' */
+		len = bufptr - f->f_bufptr;
+		s = (PyStringObject *)
+			PyString_FromStringAndSize(NULL, skip+len);
+		if (s == NULL)
+			return NULL;
+		memcpy(PyString_AS_STRING(s)+skip, f->f_bufptr, len);
+		f->f_bufptr = bufptr;
+		if (bufptr == f->f_bufend)
+			drop_readahead(f);
+	} else {
+		bufptr = f->f_bufptr;
+		buf = f->f_buf;
+		f->f_buf = NULL; 	/* Force new readahead buffer */
+		assert(skip+len < INT_MAX);
+                s = readahead_get_line_skip(
+			f, (int)(skip+len), bufsize + (bufsize>>2) );
+		if (s == NULL) {
+		        PyMem_Free(buf);
+			return NULL;
+		}
+		memcpy(PyString_AS_STRING(s)+skip, bufptr, len);
+		PyMem_Free(buf);
+	}
+	return s;
+}
+
+/* A larger buffer size may actually decrease performance. */
+#define READAHEAD_BUFSIZE 8192
+
+static PyObject *
+file_iternext(PyFileObject *f)
+{
+	PyStringObject* l;
+
+	if (f->f_fp == NULL)
+		return err_closed();
+
+	l = readahead_get_line_skip(f, 0, READAHEAD_BUFSIZE);
+	if (l == NULL || PyString_GET_SIZE(l) == 0) {
+		Py_XDECREF(l);
+		return NULL;
+	}
+	return (PyObject *)l;
+}
+
+
+static PyObject *
+file_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	PyObject *self;
+	static PyObject *not_yet_string;
+
+	assert(type != NULL && type->tp_alloc != NULL);
+
+	if (not_yet_string == NULL) {
+		not_yet_string = PyString_FromString("<uninitialized file>");
+		if (not_yet_string == NULL)
+			return NULL;
+	}
+
+	self = type->tp_alloc(type, 0);
+	if (self != NULL) {
+		/* Always fill in the name and mode, so that nobody else
+		   needs to special-case NULLs there. */
+		Py_INCREF(not_yet_string);
+		((PyFileObject *)self)->f_name = not_yet_string;
+		Py_INCREF(not_yet_string);
+		((PyFileObject *)self)->f_mode = not_yet_string;
+		Py_INCREF(Py_None);
+		((PyFileObject *)self)->f_encoding = Py_None;
+		((PyFileObject *)self)->weakreflist = NULL;
+	}
+	return self;
+}
+
+static int
+file_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+	PyFileObject *foself = (PyFileObject *)self;
+	int ret = 0;
+	static char *kwlist[] = {"name", "mode", "buffering", 0};
+	char *name = NULL;
+	char *mode = "r";
+	int bufsize = -1;
+	int wideargument = 0;
+
+	assert(PyFile_Check(self));
+	if (foself->f_fp != NULL) {
+		/* Have to close the existing file first. */
+		PyObject *closeresult = file_close(foself);
+		if (closeresult == NULL)
+			return -1;
+		Py_DECREF(closeresult);
+	}
+
+#ifdef Py_WIN_WIDE_FILENAMES
+	if (GetVersion() < 0x80000000) {    /* On NT, so wide API available */
+		PyObject *po;
+		if (PyArg_ParseTupleAndKeywords(args, kwds, "U|si:file",
+						kwlist, &po, &mode, &bufsize)) {
+			wideargument = 1;
+			if (fill_file_fields(foself, NULL, po, mode,
+					     fclose) == NULL)
+				goto Error;
+		} else {
+			/* Drop the argument parsing error as narrow
+			   strings are also valid. */
+			PyErr_Clear();
+		}
+	}
+#endif
+
+	if (!wideargument) {
+                PyObject *o_name;
+
+		if (!PyArg_ParseTupleAndKeywords(args, kwds, "et|si:file", kwlist,
+						 Py_FileSystemDefaultEncoding,
+						 &name,
+						 &mode, &bufsize))
+			return -1;
+
+                /* We parse again to get the name as a PyObject */
+                if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|si:file", 
+                                                 kwlist, &o_name, &mode, 
+                                                 &bufsize))
+                        goto Error;
+
+		if (fill_file_fields(foself, NULL, o_name, mode,
+				     fclose) == NULL)
+			goto Error;
+	}
+	if (open_the_file(foself, name, mode) == NULL)
+		goto Error;
+	foself->f_setbuf = NULL;
+	PyFile_SetBufSize(self, bufsize);
+	goto Done;
+
+Error:
+	ret = -1;
+	/* fall through */
+Done:
+	PyMem_Free(name); /* free the encoded string */
+	return ret;
+}
+
+PyDoc_VAR(file_doc) =
+PyDoc_STR(
+"file(name[, mode[, buffering]]) -> file object\n"
+"\n"
+"Open a file.  The mode can be 'r', 'w' or 'a' for reading (default),\n"
+"writing or appending.  The file will be created if it doesn't exist\n"
+"when opened for writing or appending; it will be truncated when\n"
+"opened for writing.  Add a 'b' to the mode for binary files.\n"
+"Add a '+' to the mode to allow simultaneous reading and writing.\n"
+"If the buffering argument is given, 0 means unbuffered, 1 means line\n"
+"buffered, and larger numbers specify the buffer size.\n"
+)
+PyDoc_STR(
+"Add a 'U' to mode to open the file for input with universal newline\n"
+"support.  Any line ending in the input file will be seen as a '\\n'\n"
+"in Python.  Also, a file so opened gains the attribute 'newlines';\n"
+"the value for this attribute is one of None (no newline read yet),\n"
+"'\\r', '\\n', '\\r\\n' or a tuple containing all the newline types seen.\n"
+"\n"
+"'U' cannot be combined with 'w' or '+' mode.\n"
+);
+
+PyTypeObject PyFile_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,
+	"file",
+	sizeof(PyFileObject),
+	0,
+	(destructor)file_dealloc,		/* tp_dealloc */
+	0,					/* tp_print */
+	0,			 		/* tp_getattr */
+	0,			 		/* tp_setattr */
+	0,					/* tp_compare */
+	(reprfunc)file_repr, 			/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	/* softspace is writable:  we must supply tp_setattro */
+	PyObject_GenericSetAttr,		/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
+	file_doc,				/* tp_doc */
+	0,					/* tp_traverse */
+	0,					/* tp_clear */
+	0,					/* tp_richcompare */
+	offsetof(PyFileObject, weakreflist),	/* tp_weaklistoffset */
+	(getiterfunc)file_self,			/* tp_iter */
+	(iternextfunc)file_iternext,		/* tp_iternext */
+	file_methods,				/* tp_methods */
+	file_memberlist,			/* tp_members */
+	file_getsetlist,			/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	file_init,				/* tp_init */
+	PyType_GenericAlloc,			/* tp_alloc */
+	file_new,				/* tp_new */
+	PyObject_Del,                           /* tp_free */
+};
+
+/* Interface for the 'soft space' between print items. */
+
+int
+PyFile_SoftSpace(PyObject *f, int newflag)
+{
+	long oldflag = 0;
+	if (f == NULL) {
+		/* Do nothing */
+	}
+	else if (PyFile_Check(f)) {
+		oldflag = ((PyFileObject *)f)->f_softspace;
+		((PyFileObject *)f)->f_softspace = newflag;
+	}
+	else {
+		PyObject *v;
+		v = PyObject_GetAttrString(f, "softspace");
+		if (v == NULL)
+			PyErr_Clear();
+		else {
+			if (PyInt_Check(v))
+				oldflag = PyInt_AsLong(v);
+			assert(oldflag < INT_MAX);
+			Py_DECREF(v);
+		}
+		v = PyInt_FromLong((long)newflag);
+		if (v == NULL)
+			PyErr_Clear();
+		else {
+			if (PyObject_SetAttrString(f, "softspace", v) != 0)
+				PyErr_Clear();
+			Py_DECREF(v);
+		}
+	}
+	return (int)oldflag;
+}
+
+/* Interfaces to write objects/strings to file-like objects */
+
+int
+PyFile_WriteObject(PyObject *v, PyObject *f, int flags)
+{
+	PyObject *writer, *value, *args, *result;
+	if (f == NULL) {
+		PyErr_SetString(PyExc_TypeError, "writeobject with NULL file");
+		return -1;
+	}
+	else if (PyFile_Check(f)) {
+		FILE *fp = PyFile_AsFile(f);
+#ifdef Py_USING_UNICODE
+		PyObject *enc = ((PyFileObject*)f)->f_encoding;
+		int result;
+#endif
+		if (fp == NULL) {
+			err_closed();
+			return -1;
+		}
+#ifdef Py_USING_UNICODE
+                if ((flags & Py_PRINT_RAW) &&
+		    PyUnicode_Check(v) && enc != Py_None) {
+			char *cenc = PyString_AS_STRING(enc);
+			value = PyUnicode_AsEncodedString(v, cenc, "strict");
+			if (value == NULL)
+				return -1;
+		} else {
+			value = v;
+			Py_INCREF(value);
+		}
+		result = PyObject_Print(value, fp, flags);
+		Py_DECREF(value);
+		return result;
+#else
+		return PyObject_Print(v, fp, flags);
+#endif
+	}
+	writer = PyObject_GetAttrString(f, "write");
+	if (writer == NULL)
+		return -1;
+	if (flags & Py_PRINT_RAW) {
+                if (PyUnicode_Check(v)) {
+                        value = v;
+                        Py_INCREF(value);
+                } else
+                        value = PyObject_Str(v);
+	}
+        else
+		value = PyObject_Repr(v);
+	if (value == NULL) {
+		Py_DECREF(writer);
+		return -1;
+	}
+	args = PyTuple_Pack(1, value);
+	if (args == NULL) {
+		Py_DECREF(value);
+		Py_DECREF(writer);
+		return -1;
+	}
+	result = PyEval_CallObject(writer, args);
+	Py_DECREF(args);
+	Py_DECREF(value);
+	Py_DECREF(writer);
+	if (result == NULL)
+		return -1;
+	Py_DECREF(result);
+	return 0;
+}
+
+int
+PyFile_WriteString(const char *s, PyObject *f)
+{
+	if (f == NULL) {
+		/* Should be caused by a pre-existing error */
+		if (!PyErr_Occurred())
+			PyErr_SetString(PyExc_SystemError,
+					"null file for PyFile_WriteString");
+		return -1;
+	}
+	else if (PyFile_Check(f)) {
+		FILE *fp = PyFile_AsFile(f);
+		if (fp == NULL) {
+			err_closed();
+			return -1;
+		}
+		fputs(s, fp);
+		return 0;
+	}
+	else if (!PyErr_Occurred()) {
+		PyObject *v = PyString_FromString(s);
+		int err;
+		if (v == NULL)
+			return -1;
+		err = PyFile_WriteObject(v, f, Py_PRINT_RAW);
+		Py_DECREF(v);
+		return err;
+	}
+	else
+		return -1;
+}
+
+/* Try to get a file-descriptor from a Python object.  If the object
+   is an integer or long integer, its value is returned.  If not, the
+   object's fileno() method is called if it exists; the method must return
+   an integer or long integer, which is returned as the file descriptor value.
+   -1 is returned on failure.
+*/
+
+int PyObject_AsFileDescriptor(PyObject *o)
+{
+	int fd;
+	PyObject *meth;
+
+	if (PyInt_Check(o)) {
+		fd = PyInt_AsLong(o);
+	}
+	else if (PyLong_Check(o)) {
+		fd = PyLong_AsLong(o);
+	}
+	else if ((meth = PyObject_GetAttrString(o, "fileno")) != NULL)
+	{
+		PyObject *fno = PyEval_CallObject(meth, NULL);
+		Py_DECREF(meth);
+		if (fno == NULL)
+			return -1;
+
+		if (PyInt_Check(fno)) {
+			fd = PyInt_AsLong(fno);
+			Py_DECREF(fno);
+		}
+		else if (PyLong_Check(fno)) {
+			fd = PyLong_AsLong(fno);
+			Py_DECREF(fno);
+		}
+		else {
+			PyErr_SetString(PyExc_TypeError,
+					"fileno() returned a non-integer");
+			Py_DECREF(fno);
+			return -1;
+		}
+	}
+	else {
+		PyErr_SetString(PyExc_TypeError,
+				"argument must be an int, or have a fileno() method.");
+		return -1;
+	}
+
+	if (fd < 0) {
+		PyErr_Format(PyExc_ValueError,
+			     "file descriptor cannot be a negative integer (%i)",
+			     fd);
+		return -1;
+	}
+	return fd;
+}
+
+/* From here on we need access to the real fgets and fread */
+#undef fgets
+#undef fread
+
+/*
+** Py_UniversalNewlineFgets is an fgets variation that understands
+** all of \r, \n and \r\n conventions.
+** The stream should be opened in binary mode.
+** If fobj is NULL the routine always does newline conversion, and
+** it may peek one char ahead to gobble the second char in \r\n.
+** If fobj is non-NULL it must be a PyFileObject. In this case there
+** is no readahead but in stead a flag is used to skip a following
+** \n on the next read. Also, if the file is open in binary mode
+** the whole conversion is skipped. Finally, the routine keeps track of
+** the different types of newlines seen.
+** Note that we need no error handling: fgets() treats error and eof
+** identically.
+*/
+char *
+Py_UniversalNewlineFgets(char *buf, int n, FILE *stream, PyObject *fobj)
+{
+	char *p = buf;
+	int c;
+	int newlinetypes = 0;
+	int skipnextlf = 0;
+	int univ_newline = 1;
+
+	if (fobj) {
+		if (!PyFile_Check(fobj)) {
+			errno = ENXIO;	/* What can you do... */
+			return NULL;
+		}
+		univ_newline = ((PyFileObject *)fobj)->f_univ_newline;
+		if ( !univ_newline )
+			return fgets(buf, n, stream);
+		newlinetypes = ((PyFileObject *)fobj)->f_newlinetypes;
+		skipnextlf = ((PyFileObject *)fobj)->f_skipnextlf;
+	}
+	FLOCKFILE(stream);
+	c = 'x'; /* Shut up gcc warning */
+	while (--n > 0 && (c = GETC(stream)) != EOF ) {
+		if (skipnextlf ) {
+			skipnextlf = 0;
+			if (c == '\n') {
+				/* Seeing a \n here with skipnextlf true
+				** means we saw a \r before.
+				*/
+				newlinetypes |= NEWLINE_CRLF;
+				c = GETC(stream);
+				if (c == EOF) break;
+			} else {
+				/*
+				** Note that c == EOF also brings us here,
+				** so we're okay if the last char in the file
+				** is a CR.
+				*/
+				newlinetypes |= NEWLINE_CR;
+			}
+		}
+		if (c == '\r') {
+			/* A \r is translated into a \n, and we skip
+			** an adjacent \n, if any. We don't set the
+			** newlinetypes flag until we've seen the next char.
+			*/
+			skipnextlf = 1;
+			c = '\n';
+		} else if ( c == '\n') {
+			newlinetypes |= NEWLINE_LF;
+		}
+		*p++ = c;
+		if (c == '\n') break;
+	}
+	if ( c == EOF && skipnextlf )
+		newlinetypes |= NEWLINE_CR;
+	FUNLOCKFILE(stream);
+	*p = '\0';
+	if (fobj) {
+		((PyFileObject *)fobj)->f_newlinetypes = newlinetypes;
+		((PyFileObject *)fobj)->f_skipnextlf = skipnextlf;
+	} else if ( skipnextlf ) {
+		/* If we have no file object we cannot save the
+		** skipnextlf flag. We have to readahead, which
+		** will cause a pause if we're reading from an
+		** interactive stream, but that is very unlikely
+		** unless we're doing something silly like
+		** execfile("/dev/tty").
+		*/
+		c = GETC(stream);
+		if ( c != '\n' )
+			ungetc(c, stream);
+	}
+	if (p == buf)
+		return NULL;
+	return buf;
+}
+
+/*
+** Py_UniversalNewlineFread is an fread variation that understands
+** all of \r, \n and \r\n conventions.
+** The stream should be opened in binary mode.
+** fobj must be a PyFileObject. In this case there
+** is no readahead but in stead a flag is used to skip a following
+** \n on the next read. Also, if the file is open in binary mode
+** the whole conversion is skipped. Finally, the routine keeps track of
+** the different types of newlines seen.
+*/
+size_t
+Py_UniversalNewlineFread(char *buf, size_t n,
+			 FILE *stream, PyObject *fobj)
+{
+	char *dst = buf;
+	PyFileObject *f = (PyFileObject *)fobj;
+	int newlinetypes, skipnextlf;
+
+	assert(buf != NULL);
+	assert(stream != NULL);
+
+	if (!fobj || !PyFile_Check(fobj)) {
+		errno = ENXIO;	/* What can you do... */
+		return 0;
+	}
+	if (!f->f_univ_newline)
+		return fread(buf, 1, n, stream);
+	newlinetypes = f->f_newlinetypes;
+	skipnextlf = f->f_skipnextlf;
+	/* Invariant:  n is the number of bytes remaining to be filled
+	 * in the buffer.
+	 */
+	while (n) {
+		size_t nread;
+		int shortread;
+		char *src = dst;
+
+		nread = fread(dst, 1, n, stream);
+		assert(nread <= n);
+		if (nread == 0)
+			break;
+
+		n -= nread; /* assuming 1 byte out for each in; will adjust */
+		shortread = n != 0;	/* true iff EOF or error */
+		while (nread--) {
+			char c = *src++;
+			if (c == '\r') {
+				/* Save as LF and set flag to skip next LF. */
+				*dst++ = '\n';
+				skipnextlf = 1;
+			}
+			else if (skipnextlf && c == '\n') {
+				/* Skip LF, and remember we saw CR LF. */
+				skipnextlf = 0;
+				newlinetypes |= NEWLINE_CRLF;
+				++n;
+			}
+			else {
+				/* Normal char to be stored in buffer.  Also
+				 * update the newlinetypes flag if either this
+				 * is an LF or the previous char was a CR.
+				 */
+				if (c == '\n')
+					newlinetypes |= NEWLINE_LF;
+				else if (skipnextlf)
+					newlinetypes |= NEWLINE_CR;
+				*dst++ = c;
+				skipnextlf = 0;
+			}
+		}
+		if (shortread) {
+			/* If this is EOF, update type flags. */
+			if (skipnextlf && feof(stream))
+				newlinetypes |= NEWLINE_CR;
+			break;
+		}
+	}
+	f->f_newlinetypes = newlinetypes;
+	f->f_skipnextlf = skipnextlf;
+	return dst - buf;
+}
+
+#ifdef __cplusplus
+}
+#endif

Added: vendor/Python/current/Objects/floatobject.c
===================================================================
--- vendor/Python/current/Objects/floatobject.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Objects/floatobject.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1748 @@
+
+/* Float object implementation */
+
+/* XXX There should be overflow checks here, but it's hard to check
+   for any kind of float exception without losing portability. */
+
+#include "Python.h"
+
+#include <ctype.h>
+
+#if !defined(__STDC__)
+extern double fmod(double, double);
+extern double pow(double, double);
+#endif
+
+/* Special free list -- see comments for same code in intobject.c. */
+#define BLOCK_SIZE	1000	/* 1K less typical malloc overhead */
+#define BHEAD_SIZE	8	/* Enough for a 64-bit pointer */
+#define N_FLOATOBJECTS	((BLOCK_SIZE - BHEAD_SIZE) / sizeof(PyFloatObject))
+
+struct _floatblock {
+	struct _floatblock *next;
+	PyFloatObject objects[N_FLOATOBJECTS];
+};
+
+typedef struct _floatblock PyFloatBlock;
+
+static PyFloatBlock *block_list = NULL;
+static PyFloatObject *free_list = NULL;
+
+static PyFloatObject *
+fill_free_list(void)
+{
+	PyFloatObject *p, *q;
+	/* XXX Float blocks escape the object heap. Use PyObject_MALLOC ??? */
+	p = (PyFloatObject *) PyMem_MALLOC(sizeof(PyFloatBlock));
+	if (p == NULL)
+		return (PyFloatObject *) PyErr_NoMemory();
+	((PyFloatBlock *)p)->next = block_list;
+	block_list = (PyFloatBlock *)p;
+	p = &((PyFloatBlock *)p)->objects[0];
+	q = p + N_FLOATOBJECTS;
+	while (--q > p)
+		q->ob_type = (struct _typeobject *)(q-1);
+	q->ob_type = NULL;
+	return p + N_FLOATOBJECTS - 1;
+}
+
+PyObject *
+PyFloat_FromDouble(double fval)
+{
+	register PyFloatObject *op;
+	if (free_list == NULL) {
+		if ((free_list = fill_free_list()) == NULL)
+			return NULL;
+	}
+	/* Inline PyObject_New */
+	op = free_list;
+	free_list = (PyFloatObject *)op->ob_type;
+	PyObject_INIT(op, &PyFloat_Type);
+	op->ob_fval = fval;
+	return (PyObject *) op;
+}
+
+/**************************************************************************
+RED_FLAG 22-Sep-2000 tim
+PyFloat_FromString's pend argument is braindead.  Prior to this RED_FLAG,
+
+1.  If v was a regular string, *pend was set to point to its terminating
+    null byte.  That's useless (the caller can find that without any
+    help from this function!).
+
+2.  If v was a Unicode string, or an object convertible to a character
+    buffer, *pend was set to point into stack trash (the auto temp
+    vector holding the character buffer).  That was downright dangerous.
+
+Since we can't change the interface of a public API function, pend is
+still supported but now *officially* useless:  if pend is not NULL,
+*pend is set to NULL.
+**************************************************************************/
+PyObject *
+PyFloat_FromString(PyObject *v, char **pend)
+{
+	const char *s, *last, *end;
+	double x;
+	char buffer[256]; /* for errors */
+#ifdef Py_USING_UNICODE
+	char s_buffer[256]; /* for objects convertible to a char buffer */
+#endif
+	Py_ssize_t len;
+
+	if (pend)
+		*pend = NULL;
+	if (PyString_Check(v)) {
+		s = PyString_AS_STRING(v);
+		len = PyString_GET_SIZE(v);
+	}
+#ifdef Py_USING_UNICODE
+	else if (PyUnicode_Check(v)) {
+		if (PyUnicode_GET_SIZE(v) >= (Py_ssize_t)sizeof(s_buffer)) {
+			PyErr_SetString(PyExc_ValueError,
+				"Unicode float() literal too long to convert");
+			return NULL;
+		}
+		if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(v),
+					    PyUnicode_GET_SIZE(v),
+					    s_buffer,
+					    NULL))
+			return NULL;
+		s = s_buffer;
+		len = strlen(s);
+	}
+#endif
+	else if (PyObject_AsCharBuffer(v, &s, &len)) {
+		PyErr_SetString(PyExc_TypeError,
+				"float() argument must be a string or a number");
+		return NULL;
+	}
+
+	last = s + len;
+	while (*s && isspace(Py_CHARMASK(*s)))
+		s++;
+	if (*s == '\0') {
+		PyErr_SetString(PyExc_ValueError, "empty string for float()");
+		return NULL;
+	}
+	/* We don't care about overflow or underflow.  If the platform supports
+	 * them, infinities and signed zeroes (on underflow) are fine.
+	 * However, strtod can return 0 for denormalized numbers, where atof
+	 * does not.  So (alas!) we special-case a zero result.  Note that
+	 * whether strtod sets errno on underflow is not defined, so we can't
+	 * key off errno.
+         */
+	PyFPE_START_PROTECT("strtod", return NULL)
+	x = PyOS_ascii_strtod(s, (char **)&end);
+	PyFPE_END_PROTECT(x)
+	errno = 0;
+	/* Believe it or not, Solaris 2.6 can move end *beyond* the null
+	   byte at the end of the string, when the input is inf(inity). */
+	if (end > last)
+		end = last;
+	if (end == s) {
+		PyOS_snprintf(buffer, sizeof(buffer),
+			      "invalid literal for float(): %.200s", s);
+		PyErr_SetString(PyExc_ValueError, buffer);
+		return NULL;
+	}
+	/* Since end != s, the platform made *some* kind of sense out
+	   of the input.  Trust it. */
+	while (*end && isspace(Py_CHARMASK(*end)))
+		end++;
+	if (*end != '\0') {
+		PyOS_snprintf(buffer, sizeof(buffer),
+			      "invalid literal for float(): %.200s", s);
+		PyErr_SetString(PyExc_ValueError, buffer);
+		return NULL;
+	}
+	else if (end != last) {
+		PyErr_SetString(PyExc_ValueError,
+				"null byte in argument for float()");
+		return NULL;
+	}
+	if (x == 0.0) {
+		/* See above -- may have been strtod being anal
+		   about denorms. */
+		PyFPE_START_PROTECT("atof", return NULL)
+		x = PyOS_ascii_atof(s);
+		PyFPE_END_PROTECT(x)
+		errno = 0;    /* whether atof ever set errno is undefined */
+	}
+	return PyFloat_FromDouble(x);
+}
+
+static void
+float_dealloc(PyFloatObject *op)
+{
+	if (PyFloat_CheckExact(op)) {
+		op->ob_type = (struct _typeobject *)free_list;
+		free_list = op;
+	}
+	else
+		op->ob_type->tp_free((PyObject *)op);
+}
+
+double
+PyFloat_AsDouble(PyObject *op)
+{
+	PyNumberMethods *nb;
+	PyFloatObject *fo;
+	double val;
+
+	if (op && PyFloat_Check(op))
+		return PyFloat_AS_DOUBLE((PyFloatObject*) op);
+
+	if (op == NULL) {
+		PyErr_BadArgument();
+		return -1;
+	}
+
+	if ((nb = op->ob_type->tp_as_number) == NULL || nb->nb_float == NULL) {
+		PyErr_SetString(PyExc_TypeError, "a float is required");
+		return -1;
+	}
+
+	fo = (PyFloatObject*) (*nb->nb_float) (op);
+	if (fo == NULL)
+		return -1;
+	if (!PyFloat_Check(fo)) {
+		PyErr_SetString(PyExc_TypeError,
+				"nb_float should return float object");
+		return -1;
+	}
+
+	val = PyFloat_AS_DOUBLE(fo);
+	Py_DECREF(fo);
+
+	return val;
+}
+
+/* Methods */
+
+static void
+format_float(char *buf, size_t buflen, PyFloatObject *v, int precision)
+{
+	register char *cp;
+	char format[32];
+	/* Subroutine for float_repr and float_print.
+	   We want float numbers to be recognizable as such,
+	   i.e., they should contain a decimal point or an exponent.
+	   However, %g may print the number as an integer;
+	   in such cases, we append ".0" to the string. */
+
+	assert(PyFloat_Check(v));
+	PyOS_snprintf(format, 32, "%%.%ig", precision);
+	PyOS_ascii_formatd(buf, buflen, format, v->ob_fval);
+	cp = buf;
+	if (*cp == '-')
+		cp++;
+	for (; *cp != '\0'; cp++) {
+		/* Any non-digit means it's not an integer;
+		   this takes care of NAN and INF as well. */
+		if (!isdigit(Py_CHARMASK(*cp)))
+			break;
+	}
+	if (*cp == '\0') {
+		*cp++ = '.';
+		*cp++ = '0';
+		*cp++ = '\0';
+	}
+}
+
+/* XXX PyFloat_AsStringEx should not be a public API function (for one
+   XXX thing, its signature passes a buffer without a length; for another,
+   XXX it isn't useful outside this file).
+*/
+void
+PyFloat_AsStringEx(char *buf, PyFloatObject *v, int precision)
+{
+	format_float(buf, 100, v, precision);
+}
+
+/* Macro and helper that convert PyObject obj to a C double and store
+   the value in dbl; this replaces the functionality of the coercion
+   slot function.  If conversion to double raises an exception, obj is
+   set to NULL, and the function invoking this macro returns NULL.  If
+   obj is not of float, int or long type, Py_NotImplemented is incref'ed,
+   stored in obj, and returned from the function invoking this macro.
+*/
+#define CONVERT_TO_DOUBLE(obj, dbl)			\
+	if (PyFloat_Check(obj))				\
+		dbl = PyFloat_AS_DOUBLE(obj);		\
+	else if (convert_to_double(&(obj), &(dbl)) < 0)	\
+		return obj;
+
+static int
+convert_to_double(PyObject **v, double *dbl)
+{
+	register PyObject *obj = *v;
+
+	if (PyInt_Check(obj)) {
+		*dbl = (double)PyInt_AS_LONG(obj);
+	}
+	else if (PyLong_Check(obj)) {
+		*dbl = PyLong_AsDouble(obj);
+		if (*dbl == -1.0 && PyErr_Occurred()) {
+			*v = NULL;
+			return -1;
+		}
+	}
+	else {
+		Py_INCREF(Py_NotImplemented);
+		*v = Py_NotImplemented;
+		return -1;
+	}
+	return 0;
+}
+
+/* Precisions used by repr() and str(), respectively.
+
+   The repr() precision (17 significant decimal digits) is the minimal number
+   that is guaranteed to have enough precision so that if the number is read
+   back in the exact same binary value is recreated.  This is true for IEEE
+   floating point by design, and also happens to work for all other modern
+   hardware.
+
+   The str() precision is chosen so that in most cases, the rounding noise
+   created by various operations is suppressed, while giving plenty of
+   precision for practical use.
+
+*/
+
+#define PREC_REPR	17
+#define PREC_STR	12
+
+/* XXX PyFloat_AsString and PyFloat_AsReprString should be deprecated:
+   XXX they pass a char buffer without passing a length.
+*/
+void
+PyFloat_AsString(char *buf, PyFloatObject *v)
+{
+	format_float(buf, 100, v, PREC_STR);
+}
+
+void
+PyFloat_AsReprString(char *buf, PyFloatObject *v)
+{
+	format_float(buf, 100, v, PREC_REPR);
+}
+
+/* ARGSUSED */
+static int
+float_print(PyFloatObject *v, FILE *fp, int flags)
+{
+	char buf[100];
+	format_float(buf, sizeof(buf), v,
+		     (flags & Py_PRINT_RAW) ? PREC_STR : PREC_REPR);
+	fputs(buf, fp);
+	return 0;
+}
+
+static PyObject *
+float_repr(PyFloatObject *v)
+{
+	char buf[100];
+	format_float(buf, sizeof(buf), v, PREC_REPR);
+	return PyString_FromString(buf);
+}
+
+static PyObject *
+float_str(PyFloatObject *v)
+{
+	char buf[100];
+	format_float(buf, sizeof(buf), v, PREC_STR);
+	return PyString_FromString(buf);
+}
+
+/* Comparison is pretty much a nightmare.  When comparing float to float,
+ * we do it as straightforwardly (and long-windedly) as conceivable, so
+ * that, e.g., Python x == y delivers the same result as the platform
+ * C x == y when x and/or y is a NaN.
+ * When mixing float with an integer type, there's no good *uniform* approach.
+ * Converting the double to an integer obviously doesn't work, since we
+ * may lose info from fractional bits.  Converting the integer to a double
+ * also has two failure modes:  (1) a long int may trigger overflow (too
+ * large to fit in the dynamic range of a C double); (2) even a C long may have
+ * more bits than fit in a C double (e.g., on a a 64-bit box long may have
+ * 63 bits of precision, but a C double probably has only 53), and then
+ * we can falsely claim equality when low-order integer bits are lost by
+ * coercion to double.  So this part is painful too.
+ */
+
+static PyObject*
+float_richcompare(PyObject *v, PyObject *w, int op)
+{
+	double i, j;
+	int r = 0;
+
+	assert(PyFloat_Check(v));
+	i = PyFloat_AS_DOUBLE(v);
+
+	/* Switch on the type of w.  Set i and j to doubles to be compared,
+	 * and op to the richcomp to use.
+	 */
+	if (PyFloat_Check(w))
+		j = PyFloat_AS_DOUBLE(w);
+
+	else if (!Py_IS_FINITE(i)) {
+		if (PyInt_Check(w) || PyLong_Check(w))
+			/* If i is an infinity, its magnitude exceeds any
+			 * finite integer, so it doesn't matter which int we
+			 * compare i with.  If i is a NaN, similarly.
+			 */
+			j = 0.0;
+		else
+			goto Unimplemented;
+	}
+
+	else if (PyInt_Check(w)) {
+		long jj = PyInt_AS_LONG(w);
+		/* In the worst realistic case I can imagine, C double is a
+		 * Cray single with 48 bits of precision, and long has 64
+		 * bits.
+		 */
+#if SIZEOF_LONG > 6
+		unsigned long abs = (unsigned long)(jj < 0 ? -jj : jj);
+		if (abs >> 48) {
+			/* Needs more than 48 bits.  Make it take the
+			 * PyLong path.
+			 */
+			PyObject *result;
+			PyObject *ww = PyLong_FromLong(jj);
+
+			if (ww == NULL)
+				return NULL;
+			result = float_richcompare(v, ww, op);
+			Py_DECREF(ww);
+			return result;
+		}
+#endif
+		j = (double)jj;
+		assert((long)j == jj);
+	}
+
+	else if (PyLong_Check(w)) {
+		int vsign = i == 0.0 ? 0 : i < 0.0 ? -1 : 1;
+		int wsign = _PyLong_Sign(w);
+		size_t nbits;
+		int exponent;
+
+		if (vsign != wsign) {
+			/* Magnitudes are irrelevant -- the signs alone
+			 * determine the outcome.
+			 */
+			i = (double)vsign;
+			j = (double)wsign;
+			goto Compare;
+		}
+		/* The signs are the same. */
+		/* Convert w to a double if it fits.  In particular, 0 fits. */
+		nbits = _PyLong_NumBits(w);
+		if (nbits == (size_t)-1 && PyErr_Occurred()) {
+			/* This long is so large that size_t isn't big enough
+			 * to hold the # of bits.  Replace with little doubles
+			 * that give the same outcome -- w is so large that
+			 * its magnitude must exceed the magnitude of any
+			 * finite float.
+			 */
+			PyErr_Clear();
+			i = (double)vsign;
+			assert(wsign != 0);
+			j = wsign * 2.0;
+			goto Compare;
+		}
+		if (nbits <= 48) {
+			j = PyLong_AsDouble(w);
+			/* It's impossible that <= 48 bits overflowed. */
+			assert(j != -1.0 || ! PyErr_Occurred());
+			goto Compare;
+		}
+		assert(wsign != 0); /* else nbits was 0 */
+		assert(vsign != 0); /* if vsign were 0, then since wsign is
+		                     * not 0, we would have taken the
+		                     * vsign != wsign branch at the start */
+		/* We want to work with non-negative numbers. */
+		if (vsign < 0) {
+			/* "Multiply both sides" by -1; this also swaps the
+			 * comparator.
+			 */
+			i = -i;
+			op = _Py_SwappedOp[op];
+		}
+		assert(i > 0.0);
+		(void) frexp(i, &exponent);
+		/* exponent is the # of bits in v before the radix point;
+		 * we know that nbits (the # of bits in w) > 48 at this point
+		 */
+		if (exponent < 0 || (size_t)exponent < nbits) {
+			i = 1.0;
+			j = 2.0;
+			goto Compare;
+		}
+		if ((size_t)exponent > nbits) {
+			i = 2.0;
+			j = 1.0;
+			goto Compare;
+		}
+		/* v and w have the same number of bits before the radix
+		 * point.  Construct two longs that have the same comparison
+		 * outcome.
+		 */
+		{
+			double fracpart;
+			double intpart;
+			PyObject *result = NULL;
+			PyObject *one = NULL;
+			PyObject *vv = NULL;
+			PyObject *ww = w;
+
+			if (wsign < 0) {
+				ww = PyNumber_Negative(w);
+				if (ww == NULL)
+					goto Error;
+			}
+			else
+				Py_INCREF(ww);
+
+			fracpart = modf(i, &intpart);
+			vv = PyLong_FromDouble(intpart);
+			if (vv == NULL)
+				goto Error;
+
+			if (fracpart != 0.0) {
+				/* Shift left, and or a 1 bit into vv
+				 * to represent the lost fraction.
+				 */
+				PyObject *temp;
+
+				one = PyInt_FromLong(1);
+				if (one == NULL)
+					goto Error;
+
+				temp = PyNumber_Lshift(ww, one);
+				if (temp == NULL)
+					goto Error;
+				Py_DECREF(ww);
+				ww = temp;
+
+				temp = PyNumber_Lshift(vv, one);
+				if (temp == NULL)
+					goto Error;
+				Py_DECREF(vv);
+				vv = temp;
+
+				temp = PyNumber_Or(vv, one);
+				if (temp == NULL)
+					goto Error;
+				Py_DECREF(vv);
+				vv = temp;
+			}
+
+			r = PyObject_RichCompareBool(vv, ww, op);
+			if (r < 0)
+				goto Error;
+			result = PyBool_FromLong(r);
+ 		 Error:
+ 		 	Py_XDECREF(vv);
+ 		 	Py_XDECREF(ww);
+ 		 	Py_XDECREF(one);
+ 		 	return result;
+		}
+	} /* else if (PyLong_Check(w)) */
+
+	else	/* w isn't float, int, or long */
+		goto Unimplemented;
+
+ Compare:
+	PyFPE_START_PROTECT("richcompare", return NULL)
+	switch (op) {
+	case Py_EQ:
+		r = i == j;
+		break;
+	case Py_NE:
+		r = i != j;
+		break;
+	case Py_LE:
+		r = i <= j;
+		break;
+	case Py_GE:
+		r = i >= j;
+		break;
+	case Py_LT:
+		r = i < j;
+		break;
+	case Py_GT:
+		r = i > j;
+		break;
+	}
+	PyFPE_END_PROTECT(r)
+	return PyBool_FromLong(r);
+
+ Unimplemented:
+	Py_INCREF(Py_NotImplemented);
+	return Py_NotImplemented;
+}
+
+static long
+float_hash(PyFloatObject *v)
+{
+	return _Py_HashDouble(v->ob_fval);
+}
+
+static PyObject *
+float_add(PyObject *v, PyObject *w)
+{
+	double a,b;
+	CONVERT_TO_DOUBLE(v, a);
+	CONVERT_TO_DOUBLE(w, b);
+	PyFPE_START_PROTECT("add", return 0)
+	a = a + b;
+	PyFPE_END_PROTECT(a)
+	return PyFloat_FromDouble(a);
+}
+
+static PyObject *
+float_sub(PyObject *v, PyObject *w)
+{
+	double a,b;
+	CONVERT_TO_DOUBLE(v, a);
+	CONVERT_TO_DOUBLE(w, b);
+	PyFPE_START_PROTECT("subtract", return 0)
+	a = a - b;
+	PyFPE_END_PROTECT(a)
+	return PyFloat_FromDouble(a);
+}
+
+static PyObject *
+float_mul(PyObject *v, PyObject *w)
+{
+	double a,b;
+	CONVERT_TO_DOUBLE(v, a);
+	CONVERT_TO_DOUBLE(w, b);
+	PyFPE_START_PROTECT("multiply", return 0)
+	a = a * b;
+	PyFPE_END_PROTECT(a)
+	return PyFloat_FromDouble(a);
+}
+
+static PyObject *
+float_div(PyObject *v, PyObject *w)
+{
+	double a,b;
+	CONVERT_TO_DOUBLE(v, a);
+	CONVERT_TO_DOUBLE(w, b);
+	if (b == 0.0) {
+		PyErr_SetString(PyExc_ZeroDivisionError, "float division");
+		return NULL;
+	}
+	PyFPE_START_PROTECT("divide", return 0)
+	a = a / b;
+	PyFPE_END_PROTECT(a)
+	return PyFloat_FromDouble(a);
+}
+
+static PyObject *
+float_classic_div(PyObject *v, PyObject *w)
+{
+	double a,b;
+	CONVERT_TO_DOUBLE(v, a);
+	CONVERT_TO_DOUBLE(w, b);
+	if (Py_DivisionWarningFlag >= 2 &&
+	    PyErr_Warn(PyExc_DeprecationWarning, "classic float division") < 0)
+		return NULL;
+	if (b == 0.0) {
+		PyErr_SetString(PyExc_ZeroDivisionError, "float division");
+		return NULL;
+	}
+	PyFPE_START_PROTECT("divide", return 0)
+	a = a / b;
+	PyFPE_END_PROTECT(a)
+	return PyFloat_FromDouble(a);
+}
+
+static PyObject *
+float_rem(PyObject *v, PyObject *w)
+{
+	double vx, wx;
+	double mod;
+ 	CONVERT_TO_DOUBLE(v, vx);
+ 	CONVERT_TO_DOUBLE(w, wx);
+	if (wx == 0.0) {
+		PyErr_SetString(PyExc_ZeroDivisionError, "float modulo");
+		return NULL;
+	}
+	PyFPE_START_PROTECT("modulo", return 0)
+	mod = fmod(vx, wx);
+	/* note: checking mod*wx < 0 is incorrect -- underflows to
+	   0 if wx < sqrt(smallest nonzero double) */
+	if (mod && ((wx < 0) != (mod < 0))) {
+		mod += wx;
+	}
+	PyFPE_END_PROTECT(mod)
+	return PyFloat_FromDouble(mod);
+}
+
+static PyObject *
+float_divmod(PyObject *v, PyObject *w)
+{
+	double vx, wx;
+	double div, mod, floordiv;
+ 	CONVERT_TO_DOUBLE(v, vx);
+ 	CONVERT_TO_DOUBLE(w, wx);
+	if (wx == 0.0) {
+		PyErr_SetString(PyExc_ZeroDivisionError, "float divmod()");
+		return NULL;
+	}
+	PyFPE_START_PROTECT("divmod", return 0)
+	mod = fmod(vx, wx);
+	/* fmod is typically exact, so vx-mod is *mathematically* an
+	   exact multiple of wx.  But this is fp arithmetic, and fp
+	   vx - mod is an approximation; the result is that div may
+	   not be an exact integral value after the division, although
+	   it will always be very close to one.
+	*/
+	div = (vx - mod) / wx;
+	if (mod) {
+		/* ensure the remainder has the same sign as the denominator */
+		if ((wx < 0) != (mod < 0)) {
+			mod += wx;
+			div -= 1.0;
+		}
+	}
+	else {
+		/* the remainder is zero, and in the presence of signed zeroes
+		   fmod returns different results across platforms; ensure
+		   it has the same sign as the denominator; we'd like to do
+		   "mod = wx * 0.0", but that may get optimized away */
+		mod *= mod;  /* hide "mod = +0" from optimizer */
+		if (wx < 0.0)
+			mod = -mod;
+	}
+	/* snap quotient to nearest integral value */
+	if (div) {
+		floordiv = floor(div);
+		if (div - floordiv > 0.5)
+			floordiv += 1.0;
+	}
+	else {
+		/* div is zero - get the same sign as the true quotient */
+		div *= div;	/* hide "div = +0" from optimizers */
+		floordiv = div * vx / wx; /* zero w/ sign of vx/wx */
+	}
+	PyFPE_END_PROTECT(floordiv)
+	return Py_BuildValue("(dd)", floordiv, mod);
+}
+
+static PyObject *
+float_floor_div(PyObject *v, PyObject *w)
+{
+	PyObject *t, *r;
+
+	t = float_divmod(v, w);
+	if (t == NULL || t == Py_NotImplemented)
+		return t;
+	assert(PyTuple_CheckExact(t));
+	r = PyTuple_GET_ITEM(t, 0);
+	Py_INCREF(r);
+	Py_DECREF(t);
+	return r;
+}
+
+static PyObject *
+float_pow(PyObject *v, PyObject *w, PyObject *z)
+{
+	double iv, iw, ix;
+
+	if ((PyObject *)z != Py_None) {
+		PyErr_SetString(PyExc_TypeError, "pow() 3rd argument not "
+			"allowed unless all arguments are integers");
+		return NULL;
+	}
+
+	CONVERT_TO_DOUBLE(v, iv);
+	CONVERT_TO_DOUBLE(w, iw);
+
+	/* Sort out special cases here instead of relying on pow() */
+	if (iw == 0) { 		/* v**0 is 1, even 0**0 */
+		PyFPE_START_PROTECT("pow", return NULL)
+		if ((PyObject *)z != Py_None) {
+			double iz;
+			CONVERT_TO_DOUBLE(z, iz);
+			ix = fmod(1.0, iz);
+			if (ix != 0 && iz < 0)
+				ix += iz;
+		}
+		else
+			ix = 1.0;
+		PyFPE_END_PROTECT(ix)
+		return PyFloat_FromDouble(ix);
+	}
+	if (iv == 0.0) {  /* 0**w is error if w<0, else 1 */
+		if (iw < 0.0) {
+			PyErr_SetString(PyExc_ZeroDivisionError,
+					"0.0 cannot be raised to a negative power");
+			return NULL;
+		}
+		return PyFloat_FromDouble(0.0);
+	}
+	if (iv < 0.0) {
+		/* Whether this is an error is a mess, and bumps into libm
+		 * bugs so we have to figure it out ourselves.
+		 */
+		if (iw != floor(iw)) {
+			PyErr_SetString(PyExc_ValueError, "negative number "
+				"cannot be raised to a fractional power");
+			return NULL;
+		}
+		/* iw is an exact integer, albeit perhaps a very large one.
+		 * -1 raised to an exact integer should never be exceptional.
+		 * Alas, some libms (chiefly glibc as of early 2003) return
+		 * NaN and set EDOM on pow(-1, large_int) if the int doesn't
+		 * happen to be representable in a *C* integer.  That's a
+		 * bug; we let that slide in math.pow() (which currently
+		 * reflects all platform accidents), but not for Python's **.
+		 */
+		 if (iv == -1.0 && Py_IS_FINITE(iw)) {
+		 	/* Return 1 if iw is even, -1 if iw is odd; there's
+		 	 * no guarantee that any C integral type is big
+		 	 * enough to hold iw, so we have to check this
+		 	 * indirectly.
+		 	 */
+		 	ix = floor(iw * 0.5) * 2.0;
+			return PyFloat_FromDouble(ix == iw ? 1.0 : -1.0);
+		}
+		/* Else iv != -1.0, and overflow or underflow are possible.
+		 * Unless we're to write pow() ourselves, we have to trust
+		 * the platform to do this correctly.
+		 */
+	}
+	errno = 0;
+	PyFPE_START_PROTECT("pow", return NULL)
+	ix = pow(iv, iw);
+	PyFPE_END_PROTECT(ix)
+	Py_ADJUST_ERANGE1(ix);
+	if (errno != 0) {
+		/* We don't expect any errno value other than ERANGE, but
+		 * the range of libm bugs appears unbounded.
+		 */
+		PyErr_SetFromErrno(errno == ERANGE ? PyExc_OverflowError :
+						     PyExc_ValueError);
+		return NULL;
+	}
+	return PyFloat_FromDouble(ix);
+}
+
+static PyObject *
+float_neg(PyFloatObject *v)
+{
+	return PyFloat_FromDouble(-v->ob_fval);
+}
+
+static PyObject *
+float_pos(PyFloatObject *v)
+{
+	if (PyFloat_CheckExact(v)) {
+		Py_INCREF(v);
+		return (PyObject *)v;
+	}
+	else
+		return PyFloat_FromDouble(v->ob_fval);
+}
+
+static PyObject *
+float_abs(PyFloatObject *v)
+{
+	return PyFloat_FromDouble(fabs(v->ob_fval));
+}
+
+static int
+float_nonzero(PyFloatObject *v)
+{
+	return v->ob_fval != 0.0;
+}
+
+static int
+float_coerce(PyObject **pv, PyObject **pw)
+{
+	if (PyInt_Check(*pw)) {
+		long x = PyInt_AsLong(*pw);
+		*pw = PyFloat_FromDouble((double)x);
+		Py_INCREF(*pv);
+		return 0;
+	}
+	else if (PyLong_Check(*pw)) {
+		double x = PyLong_AsDouble(*pw);
+		if (x == -1.0 && PyErr_Occurred())
+			return -1;
+		*pw = PyFloat_FromDouble(x);
+		Py_INCREF(*pv);
+		return 0;
+	}
+	else if (PyFloat_Check(*pw)) {
+		Py_INCREF(*pv);
+		Py_INCREF(*pw);
+		return 0;
+	}
+	return 1; /* Can't do it */
+}
+
+static PyObject *
+float_long(PyObject *v)
+{
+	double x = PyFloat_AsDouble(v);
+	return PyLong_FromDouble(x);
+}
+
+static PyObject *
+float_int(PyObject *v)
+{
+	double x = PyFloat_AsDouble(v);
+	double wholepart;	/* integral portion of x, rounded toward 0 */
+
+	(void)modf(x, &wholepart);
+	/* Try to get out cheap if this fits in a Python int.  The attempt
+	 * to cast to long must be protected, as C doesn't define what
+	 * happens if the double is too big to fit in a long.  Some rare
+	 * systems raise an exception then (RISCOS was mentioned as one,
+	 * and someone using a non-default option on Sun also bumped into
+	 * that).  Note that checking for >= and <= LONG_{MIN,MAX} would
+	 * still be vulnerable:  if a long has more bits of precision than
+	 * a double, casting MIN/MAX to double may yield an approximation,
+	 * and if that's rounded up, then, e.g., wholepart=LONG_MAX+1 would
+	 * yield true from the C expression wholepart<=LONG_MAX, despite
+	 * that wholepart is actually greater than LONG_MAX.
+	 */
+	if (LONG_MIN < wholepart && wholepart < LONG_MAX) {
+		const long aslong = (long)wholepart;
+		return PyInt_FromLong(aslong);
+	}
+	return PyLong_FromDouble(wholepart);
+}
+
+static PyObject *
+float_float(PyObject *v)
+{
+	if (PyFloat_CheckExact(v))
+		Py_INCREF(v);
+	else
+		v = PyFloat_FromDouble(((PyFloatObject *)v)->ob_fval);
+	return v;
+}
+
+
+static PyObject *
+float_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
+
+static PyObject *
+float_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	PyObject *x = Py_False; /* Integer zero */
+	static char *kwlist[] = {"x", 0};
+
+	if (type != &PyFloat_Type)
+		return float_subtype_new(type, args, kwds); /* Wimp out */
+	if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:float", kwlist, &x))
+		return NULL;
+	if (PyString_Check(x))
+		return PyFloat_FromString(x, NULL);
+	return PyNumber_Float(x);
+}
+
+/* Wimpy, slow approach to tp_new calls for subtypes of float:
+   first create a regular float from whatever arguments we got,
+   then allocate a subtype instance and initialize its ob_fval
+   from the regular float.  The regular float is then thrown away.
+*/
+static PyObject *
+float_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	PyObject *tmp, *newobj;
+
+	assert(PyType_IsSubtype(type, &PyFloat_Type));
+	tmp = float_new(&PyFloat_Type, args, kwds);
+	if (tmp == NULL)
+		return NULL;
+	assert(PyFloat_CheckExact(tmp));
+	newobj = type->tp_alloc(type, 0);
+	if (newobj == NULL) {
+		Py_DECREF(tmp);
+		return NULL;
+	}
+	((PyFloatObject *)newobj)->ob_fval = ((PyFloatObject *)tmp)->ob_fval;
+	Py_DECREF(tmp);
+	return newobj;
+}
+
+static PyObject *
+float_getnewargs(PyFloatObject *v)
+{
+	return Py_BuildValue("(d)", v->ob_fval);
+}
+
+/* this is for the benefit of the pack/unpack routines below */
+
+typedef enum {
+	unknown_format, ieee_big_endian_format, ieee_little_endian_format
+} float_format_type;
+
+static float_format_type double_format, float_format;
+static float_format_type detected_double_format, detected_float_format;
+
+static PyObject *
+float_getformat(PyTypeObject *v, PyObject* arg)
+{
+	char* s;
+	float_format_type r;
+
+	if (!PyString_Check(arg)) {
+		PyErr_Format(PyExc_TypeError,
+	     "__getformat__() argument must be string, not %.500s",
+			     arg->ob_type->tp_name);
+		return NULL;
+	}
+	s = PyString_AS_STRING(arg);
+	if (strcmp(s, "double") == 0) {
+		r = double_format;
+	}
+	else if (strcmp(s, "float") == 0) {
+		r = float_format;
+	}
+	else {
+		PyErr_SetString(PyExc_ValueError,
+				"__getformat__() argument 1 must be "
+				"'double' or 'float'");
+		return NULL;
+	}
+	
+	switch (r) {
+	case unknown_format:
+		return PyString_FromString("unknown");
+	case ieee_little_endian_format:
+		return PyString_FromString("IEEE, little-endian");
+	case ieee_big_endian_format:
+		return PyString_FromString("IEEE, big-endian");
+	default:
+		Py_FatalError("insane float_format or double_format");
+		return NULL;
+	}
+}
+
+PyDoc_STRVAR(float_getformat_doc,
+"float.__getformat__(typestr) -> string\n"
+"\n"
+"You probably don't want to use this function.  It exists mainly to be\n"
+"used in Python's test suite.\n"
+"\n"
+"typestr must be 'double' or 'float'.  This function returns whichever of\n"
+"'unknown', 'IEEE, big-endian' or 'IEEE, little-endian' best describes the\n"
+"format of floating point numbers used by the C type named by typestr.");
+
+static PyObject *
+float_setformat(PyTypeObject *v, PyObject* args)
+{
+	char* typestr;
+	char* format;
+	float_format_type f;
+	float_format_type detected;
+	float_format_type *p;
+
+	if (!PyArg_ParseTuple(args, "ss:__setformat__", &typestr, &format))
+		return NULL;
+
+	if (strcmp(typestr, "double") == 0) {
+		p = &double_format;
+		detected = detected_double_format;
+	}
+	else if (strcmp(typestr, "float") == 0) {
+		p = &float_format;
+		detected = detected_float_format;
+	}
+	else {
+		PyErr_SetString(PyExc_ValueError,
+				"__setformat__() argument 1 must "
+				"be 'double' or 'float'");
+		return NULL;
+	}
+	
+	if (strcmp(format, "unknown") == 0) {
+		f = unknown_format;
+	}
+	else if (strcmp(format, "IEEE, little-endian") == 0) {
+		f = ieee_little_endian_format;
+	}
+	else if (strcmp(format, "IEEE, big-endian") == 0) {
+		f = ieee_big_endian_format;
+	}
+	else {
+		PyErr_SetString(PyExc_ValueError,
+				"__setformat__() argument 2 must be "
+				"'unknown', 'IEEE, little-endian' or "
+				"'IEEE, big-endian'");
+		return NULL;
+
+	}
+
+	if (f != unknown_format && f != detected) {
+		PyErr_Format(PyExc_ValueError,
+			     "can only set %s format to 'unknown' or the "
+			     "detected platform value", typestr);
+		return NULL;
+	}
+
+	*p = f;
+	Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(float_setformat_doc,
+"float.__setformat__(typestr, fmt) -> None\n"
+"\n"
+"You probably don't want to use this function.  It exists mainly to be\n"
+"used in Python's test suite.\n"
+"\n"
+"typestr must be 'double' or 'float'.  fmt must be one of 'unknown',\n"
+"'IEEE, big-endian' or 'IEEE, little-endian', and in addition can only be\n"
+"one of the latter two if it appears to match the underlying C reality.\n"
+"\n"
+"Overrides the automatic determination of C-level floating point type.\n"
+"This affects how floats are converted to and from binary strings.");
+
+static PyMethodDef float_methods[] = {
+	{"__getnewargs__",	(PyCFunction)float_getnewargs,	METH_NOARGS},
+	{"__getformat__",	(PyCFunction)float_getformat,	
+	 METH_O|METH_CLASS,		float_getformat_doc},
+	{"__setformat__",	(PyCFunction)float_setformat,	
+	 METH_VARARGS|METH_CLASS,	float_setformat_doc},
+	{NULL,		NULL}		/* sentinel */
+};
+
+PyDoc_STRVAR(float_doc,
+"float(x) -> floating point number\n\
+\n\
+Convert a string or number to a floating point number, if possible.");
+
+
+static PyNumberMethods float_as_number = {
+	float_add, 	/*nb_add*/
+	float_sub, 	/*nb_subtract*/
+	float_mul, 	/*nb_multiply*/
+	float_classic_div, /*nb_divide*/
+	float_rem, 	/*nb_remainder*/
+	float_divmod, 	/*nb_divmod*/
+	float_pow, 	/*nb_power*/
+	(unaryfunc)float_neg, /*nb_negative*/
+	(unaryfunc)float_pos, /*nb_positive*/
+	(unaryfunc)float_abs, /*nb_absolute*/
+	(inquiry)float_nonzero, /*nb_nonzero*/
+	0,		/*nb_invert*/
+	0,		/*nb_lshift*/
+	0,		/*nb_rshift*/
+	0,		/*nb_and*/
+	0,		/*nb_xor*/
+	0,		/*nb_or*/
+	float_coerce, 	/*nb_coerce*/
+	float_int, 	/*nb_int*/
+	float_long, 	/*nb_long*/
+	float_float,	/*nb_float*/
+	0,		/* nb_oct */
+	0,		/* nb_hex */
+	0,		/* nb_inplace_add */
+	0,		/* nb_inplace_subtract */
+	0,		/* nb_inplace_multiply */
+	0,		/* nb_inplace_divide */
+	0,		/* nb_inplace_remainder */
+	0, 		/* nb_inplace_power */
+	0,		/* nb_inplace_lshift */
+	0,		/* nb_inplace_rshift */
+	0,		/* nb_inplace_and */
+	0,		/* nb_inplace_xor */
+	0,		/* nb_inplace_or */
+	float_floor_div, /* nb_floor_divide */
+	float_div,	/* nb_true_divide */
+	0,		/* nb_inplace_floor_divide */
+	0,		/* nb_inplace_true_divide */
+};
+
+PyTypeObject PyFloat_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,
+	"float",
+	sizeof(PyFloatObject),
+	0,
+	(destructor)float_dealloc,		/* tp_dealloc */
+	(printfunc)float_print, 		/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,			 		/* tp_compare */
+	(reprfunc)float_repr,			/* tp_repr */
+	&float_as_number,			/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	(hashfunc)float_hash,			/* tp_hash */
+	0,					/* tp_call */
+	(reprfunc)float_str,			/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
+		Py_TPFLAGS_BASETYPE,		/* tp_flags */
+	float_doc,				/* tp_doc */
+ 	0,					/* tp_traverse */
+	0,					/* tp_clear */
+	float_richcompare,			/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	float_methods,				/* tp_methods */
+	0,					/* tp_members */
+	0,					/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	0,					/* tp_init */
+	0,					/* tp_alloc */
+	float_new,				/* tp_new */
+};
+
+void
+_PyFloat_Init(void)
+{
+	/* We attempt to determine if this machine is using IEEE
+	   floating point formats by peering at the bits of some
+	   carefully chosen values.  If it looks like we are on an
+	   IEEE platform, the float packing/unpacking routines can
+	   just copy bits, if not they resort to arithmetic & shifts
+	   and masks.  The shifts & masks approach works on all finite
+	   values, but what happens to infinities, NaNs and signed
+	   zeroes on packing is an accident, and attempting to unpack
+	   a NaN or an infinity will raise an exception.
+
+	   Note that if we're on some whacked-out platform which uses
+	   IEEE formats but isn't strictly little-endian or big-
+	   endian, we will fall back to the portable shifts & masks
+	   method. */
+
+#if SIZEOF_DOUBLE == 8
+	{
+		double x = 9006104071832581.0;
+		if (memcmp(&x, "\x43\x3f\xff\x01\x02\x03\x04\x05", 8) == 0)
+			detected_double_format = ieee_big_endian_format;
+		else if (memcmp(&x, "\x05\x04\x03\x02\x01\xff\x3f\x43", 8) == 0)
+			detected_double_format = ieee_little_endian_format;
+		else 
+			detected_double_format = unknown_format;
+	}
+#else
+	detected_double_format = unknown_format;
+#endif
+
+#if SIZEOF_FLOAT == 4
+	{
+		float y = 16711938.0;
+		if (memcmp(&y, "\x4b\x7f\x01\x02", 4) == 0)
+			detected_float_format = ieee_big_endian_format;
+		else if (memcmp(&y, "\x02\x01\x7f\x4b", 4) == 0)
+			detected_float_format = ieee_little_endian_format;
+		else 
+			detected_float_format = unknown_format;
+	}
+#else
+	detected_float_format = unknown_format;
+#endif
+
+	double_format = detected_double_format;
+	float_format = detected_float_format;
+}
+
+void
+PyFloat_Fini(void)
+{
+	PyFloatObject *p;
+	PyFloatBlock *list, *next;
+	unsigned i;
+	int bc, bf;	/* block count, number of freed blocks */
+	int frem, fsum;	/* remaining unfreed floats per block, total */
+
+	bc = 0;
+	bf = 0;
+	fsum = 0;
+	list = block_list;
+	block_list = NULL;
+	free_list = NULL;
+	while (list != NULL) {
+		bc++;
+		frem = 0;
+		for (i = 0, p = &list->objects[0];
+		     i < N_FLOATOBJECTS;
+		     i++, p++) {
+			if (PyFloat_CheckExact(p) && p->ob_refcnt != 0)
+				frem++;
+		}
+		next = list->next;
+		if (frem) {
+			list->next = block_list;
+			block_list = list;
+			for (i = 0, p = &list->objects[0];
+			     i < N_FLOATOBJECTS;
+			     i++, p++) {
+				if (!PyFloat_CheckExact(p) ||
+				    p->ob_refcnt == 0) {
+					p->ob_type = (struct _typeobject *)
+						free_list;
+					free_list = p;
+				}
+			}
+		}
+		else {
+			PyMem_FREE(list); /* XXX PyObject_FREE ??? */
+			bf++;
+		}
+		fsum += frem;
+		list = next;
+	}
+	if (!Py_VerboseFlag)
+		return;
+	fprintf(stderr, "# cleanup floats");
+	if (!fsum) {
+		fprintf(stderr, "\n");
+	}
+	else {
+		fprintf(stderr,
+			": %d unfreed float%s in %d out of %d block%s\n",
+			fsum, fsum == 1 ? "" : "s",
+			bc - bf, bc, bc == 1 ? "" : "s");
+	}
+	if (Py_VerboseFlag > 1) {
+		list = block_list;
+		while (list != NULL) {
+			for (i = 0, p = &list->objects[0];
+			     i < N_FLOATOBJECTS;
+			     i++, p++) {
+				if (PyFloat_CheckExact(p) &&
+				    p->ob_refcnt != 0) {
+					char buf[100];
+					PyFloat_AsString(buf, p);
+					/* XXX(twouters) cast refcount to
+					   long until %zd is universally
+					   available
+					 */
+					fprintf(stderr,
+			     "#   <float at %p, refcnt=%ld, val=%s>\n",
+						p, (long)p->ob_refcnt, buf);
+				}
+			}
+			list = list->next;
+		}
+	}
+}
+
+/*----------------------------------------------------------------------------
+ * _PyFloat_{Pack,Unpack}{4,8}.  See floatobject.h.
+ *
+ * TODO:  On platforms that use the standard IEEE-754 single and double
+ * formats natively, these routines could simply copy the bytes.
+ */
+int
+_PyFloat_Pack4(double x, unsigned char *p, int le)
+{
+	if (float_format == unknown_format) {
+		unsigned char sign;
+		int e;
+		double f;
+		unsigned int fbits;
+		int incr = 1;
+
+		if (le) {
+			p += 3;
+			incr = -1;
+		}
+
+		if (x < 0) {
+			sign = 1;
+			x = -x;
+		}
+		else
+			sign = 0;
+
+		f = frexp(x, &e);
+
+		/* Normalize f to be in the range [1.0, 2.0) */
+		if (0.5 <= f && f < 1.0) {
+			f *= 2.0;
+			e--;
+		}
+		else if (f == 0.0)
+			e = 0;
+		else {
+			PyErr_SetString(PyExc_SystemError,
+					"frexp() result out of range");
+			return -1;
+		}
+
+		if (e >= 128)
+			goto Overflow;
+		else if (e < -126) {
+			/* Gradual underflow */
+			f = ldexp(f, 126 + e);
+			e = 0;
+		}
+		else if (!(e == 0 && f == 0.0)) {
+			e += 127;
+			f -= 1.0; /* Get rid of leading 1 */
+		}
+
+		f *= 8388608.0; /* 2**23 */
+		fbits = (unsigned int)(f + 0.5); /* Round */
+		assert(fbits <= 8388608);
+		if (fbits >> 23) {
+			/* The carry propagated out of a string of 23 1 bits. */
+			fbits = 0;
+			++e;
+			if (e >= 255)
+				goto Overflow;
+		}
+
+		/* First byte */
+		*p = (sign << 7) | (e >> 1);
+		p += incr;
+
+		/* Second byte */
+		*p = (char) (((e & 1) << 7) | (fbits >> 16));
+		p += incr;
+
+		/* Third byte */
+		*p = (fbits >> 8) & 0xFF;
+		p += incr;
+
+		/* Fourth byte */
+		*p = fbits & 0xFF;
+
+		/* Done */
+		return 0;
+
+	  Overflow:
+		PyErr_SetString(PyExc_OverflowError,
+				"float too large to pack with f format");
+		return -1;
+	}
+	else {
+		float y = (float)x;
+		const char *s = (char*)&y;
+		int i, incr = 1;
+
+		if ((float_format == ieee_little_endian_format && !le)
+		    || (float_format == ieee_big_endian_format && le)) {
+			p += 3;
+			incr = -1;
+		}
+		
+		for (i = 0; i < 4; i++) {
+			*p = *s++;
+			p += incr;
+		}
+		return 0;
+	}
+}
+
+int
+_PyFloat_Pack8(double x, unsigned char *p, int le)
+{
+	if (double_format == unknown_format) {
+		unsigned char sign;
+		int e;
+		double f;
+		unsigned int fhi, flo;
+		int incr = 1;
+
+		if (le) {
+			p += 7;
+			incr = -1;
+		}
+
+		if (x < 0) {
+			sign = 1;
+			x = -x;
+		}
+		else
+			sign = 0;
+
+		f = frexp(x, &e);
+
+		/* Normalize f to be in the range [1.0, 2.0) */
+		if (0.5 <= f && f < 1.0) {
+			f *= 2.0;
+			e--;
+		}
+		else if (f == 0.0)
+			e = 0;
+		else {
+			PyErr_SetString(PyExc_SystemError,
+					"frexp() result out of range");
+			return -1;
+		}
+
+		if (e >= 1024)
+			goto Overflow;
+		else if (e < -1022) {
+			/* Gradual underflow */
+			f = ldexp(f, 1022 + e);
+			e = 0;
+		}
+		else if (!(e == 0 && f == 0.0)) {
+			e += 1023;
+			f -= 1.0; /* Get rid of leading 1 */
+		}
+
+		/* fhi receives the high 28 bits; flo the low 24 bits (== 52 bits) */
+		f *= 268435456.0; /* 2**28 */
+		fhi = (unsigned int)f; /* Truncate */
+		assert(fhi < 268435456);
+
+		f -= (double)fhi;
+		f *= 16777216.0; /* 2**24 */
+		flo = (unsigned int)(f + 0.5); /* Round */
+		assert(flo <= 16777216);
+		if (flo >> 24) {
+			/* The carry propagated out of a string of 24 1 bits. */
+			flo = 0;
+			++fhi;
+			if (fhi >> 28) {
+				/* And it also progagated out of the next 28 bits. */
+				fhi = 0;
+				++e;
+				if (e >= 2047)
+					goto Overflow;
+			}
+		}
+
+		/* First byte */
+		*p = (sign << 7) | (e >> 4);
+		p += incr;
+
+		/* Second byte */
+		*p = (unsigned char) (((e & 0xF) << 4) | (fhi >> 24));
+		p += incr;
+
+		/* Third byte */
+		*p = (fhi >> 16) & 0xFF;
+		p += incr;
+
+		/* Fourth byte */
+		*p = (fhi >> 8) & 0xFF;
+		p += incr;
+
+		/* Fifth byte */
+		*p = fhi & 0xFF;
+		p += incr;
+
+		/* Sixth byte */
+		*p = (flo >> 16) & 0xFF;
+		p += incr;
+
+		/* Seventh byte */
+		*p = (flo >> 8) & 0xFF;
+		p += incr;
+
+		/* Eighth byte */
+		*p = flo & 0xFF;
+		p += incr;
+
+		/* Done */
+		return 0;
+
+	  Overflow:
+		PyErr_SetString(PyExc_OverflowError,
+				"float too large to pack with d format");
+		return -1;
+	}
+	else {
+		const char *s = (char*)&x;
+		int i, incr = 1;
+
+		if ((double_format == ieee_little_endian_format && !le)
+		    || (double_format == ieee_big_endian_format && le)) {
+			p += 7;
+			incr = -1;
+		}
+		
+		for (i = 0; i < 8; i++) {
+			*p = *s++;
+			p += incr;
+		}
+		return 0;
+	}
+}
+
+double
+_PyFloat_Unpack4(const unsigned char *p, int le)
+{
+	if (float_format == unknown_format) {
+		unsigned char sign;
+		int e;
+		unsigned int f;
+		double x;
+		int incr = 1;
+
+		if (le) {
+			p += 3;
+			incr = -1;
+		}
+
+		/* First byte */
+		sign = (*p >> 7) & 1;
+		e = (*p & 0x7F) << 1;
+		p += incr;
+
+		/* Second byte */
+		e |= (*p >> 7) & 1;
+		f = (*p & 0x7F) << 16;
+		p += incr;
+
+		if (e == 255) {
+			PyErr_SetString(
+				PyExc_ValueError,
+				"can't unpack IEEE 754 special value "
+				"on non-IEEE platform");
+			return -1;
+		}
+
+		/* Third byte */
+		f |= *p << 8;
+		p += incr;
+
+		/* Fourth byte */
+		f |= *p;
+
+		x = (double)f / 8388608.0;
+
+		/* XXX This sadly ignores Inf/NaN issues */
+		if (e == 0)
+			e = -126;
+		else {
+			x += 1.0;
+			e -= 127;
+		}
+		x = ldexp(x, e);
+
+		if (sign)
+			x = -x;
+
+		return x;
+	}
+	else {
+		float x;
+
+		if ((float_format == ieee_little_endian_format && !le)
+		    || (float_format == ieee_big_endian_format && le)) {
+			char buf[4];
+			char *d = &buf[3];
+			int i;
+
+			for (i = 0; i < 4; i++) {
+				*d-- = *p++;
+			}
+			memcpy(&x, buf, 4);
+		}
+		else {
+			memcpy(&x, p, 4);
+		}
+
+		return x;
+	}		
+}
+
+double
+_PyFloat_Unpack8(const unsigned char *p, int le)
+{
+	if (double_format == unknown_format) {
+		unsigned char sign;
+		int e;
+		unsigned int fhi, flo;
+		double x;
+		int incr = 1;
+
+		if (le) {
+			p += 7;
+			incr = -1;
+		}
+
+		/* First byte */
+		sign = (*p >> 7) & 1;
+		e = (*p & 0x7F) << 4;
+		
+		p += incr;
+
+		/* Second byte */
+		e |= (*p >> 4) & 0xF;
+		fhi = (*p & 0xF) << 24;
+		p += incr;
+
+		if (e == 2047) {
+			PyErr_SetString(
+				PyExc_ValueError,
+				"can't unpack IEEE 754 special value "
+				"on non-IEEE platform");
+			return -1.0;
+		}
+
+		/* Third byte */
+		fhi |= *p << 16;
+		p += incr;
+
+		/* Fourth byte */
+		fhi |= *p  << 8;
+		p += incr;
+
+		/* Fifth byte */
+		fhi |= *p;
+		p += incr;
+
+		/* Sixth byte */
+		flo = *p << 16;
+		p += incr;
+
+		/* Seventh byte */
+		flo |= *p << 8;
+		p += incr;
+
+		/* Eighth byte */
+		flo |= *p;
+
+		x = (double)fhi + (double)flo / 16777216.0; /* 2**24 */
+		x /= 268435456.0; /* 2**28 */
+
+		if (e == 0)
+			e = -1022;
+		else {
+			x += 1.0;
+			e -= 1023;
+		}
+		x = ldexp(x, e);
+
+		if (sign)
+			x = -x;
+
+		return x;
+	}
+	else {
+		double x;
+
+		if ((double_format == ieee_little_endian_format && !le)
+		    || (double_format == ieee_big_endian_format && le)) {
+			char buf[8];
+			char *d = &buf[7];
+			int i;
+			
+			for (i = 0; i < 8; i++) {
+				*d-- = *p++;
+			}
+			memcpy(&x, buf, 8);
+		}
+		else {
+			memcpy(&x, p, 8);
+		}
+
+		return x;
+	}
+}

Added: vendor/Python/current/Objects/frameobject.c
===================================================================
--- vendor/Python/current/Objects/frameobject.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Objects/frameobject.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,849 @@
+/* Frame object implementation */
+
+#include "Python.h"
+
+#include "code.h"
+#include "frameobject.h"
+#include "opcode.h"
+#include "structmember.h"
+
+#undef MIN
+#undef MAX
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+
+#define OFF(x) offsetof(PyFrameObject, x)
+
+static PyMemberDef frame_memberlist[] = {
+	{"f_back",	T_OBJECT,	OFF(f_back),	RO},
+	{"f_code",	T_OBJECT,	OFF(f_code),	RO},
+	{"f_builtins",	T_OBJECT,	OFF(f_builtins),RO},
+	{"f_globals",	T_OBJECT,	OFF(f_globals),	RO},
+	{"f_lasti",	T_INT,		OFF(f_lasti),	RO},
+	{"f_exc_type",	T_OBJECT,	OFF(f_exc_type)},
+	{"f_exc_value",	T_OBJECT,	OFF(f_exc_value)},
+	{"f_exc_traceback", T_OBJECT,	OFF(f_exc_traceback)},
+	{NULL}	/* Sentinel */
+};
+
+static PyObject *
+frame_getlocals(PyFrameObject *f, void *closure)
+{
+	PyFrame_FastToLocals(f);
+	Py_INCREF(f->f_locals);
+	return f->f_locals;
+}
+
+static PyObject *
+frame_getlineno(PyFrameObject *f, void *closure)
+{
+	int lineno;
+
+	if (f->f_trace)
+		lineno = f->f_lineno;
+	else
+		lineno = PyCode_Addr2Line(f->f_code, f->f_lasti);
+
+	return PyInt_FromLong(lineno);
+}
+
+/* Setter for f_lineno - you can set f_lineno from within a trace function in
+ * order to jump to a given line of code, subject to some restrictions.  Most
+ * lines are OK to jump to because they don't make any assumptions about the
+ * state of the stack (obvious because you could remove the line and the code
+ * would still work without any stack errors), but there are some constructs
+ * that limit jumping:
+ *
+ *  o Lines with an 'except' statement on them can't be jumped to, because
+ *    they expect an exception to be on the top of the stack.
+ *  o Lines that live in a 'finally' block can't be jumped from or to, since
+ *    the END_FINALLY expects to clean up the stack after the 'try' block.
+ *  o 'try'/'for'/'while' blocks can't be jumped into because the blockstack
+ *    needs to be set up before their code runs, and for 'for' loops the
+ *    iterator needs to be on the stack.
+ */
+static int
+frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno)
+{
+	int new_lineno = 0;		/* The new value of f_lineno */
+	int new_lasti = 0;		/* The new value of f_lasti */
+	int new_iblock = 0;		/* The new value of f_iblock */
+	char *code = NULL;		/* The bytecode for the frame... */
+	Py_ssize_t code_len = 0;	/* ...and its length */
+	char *lnotab = NULL;		/* Iterating over co_lnotab */
+	Py_ssize_t lnotab_len = 0;	/* (ditto) */
+	int offset = 0;			/* (ditto) */
+	int line = 0;			/* (ditto) */
+	int addr = 0;			/* (ditto) */
+	int min_addr = 0;		/* Scanning the SETUPs and POPs */
+	int max_addr = 0;		/* (ditto) */
+	int delta_iblock = 0;		/* (ditto) */
+	int min_delta_iblock = 0;	/* (ditto) */
+	int min_iblock = 0;		/* (ditto) */
+	int f_lasti_setup_addr = 0;	/* Policing no-jump-into-finally */
+	int new_lasti_setup_addr = 0;	/* (ditto) */
+	int blockstack[CO_MAXBLOCKS];	/* Walking the 'finally' blocks */
+	int in_finally[CO_MAXBLOCKS];	/* (ditto) */
+	int blockstack_top = 0;		/* (ditto) */
+	int setup_op = 0;               /* (ditto) */
+
+	/* f_lineno must be an integer. */
+	if (!PyInt_Check(p_new_lineno)) {
+		PyErr_SetString(PyExc_ValueError,
+				"lineno must be an integer");
+		return -1;
+	}
+
+	/* You can only do this from within a trace function, not via
+	 * _getframe or similar hackery. */
+	if (!f->f_trace)
+	{
+		PyErr_Format(PyExc_ValueError,
+			     "f_lineno can only be set by a trace function");
+		return -1;
+	}
+
+	/* Fail if the line comes before the start of the code block. */
+	new_lineno = (int) PyInt_AsLong(p_new_lineno);
+	if (new_lineno < f->f_code->co_firstlineno) {
+		PyErr_Format(PyExc_ValueError,
+			     "line %d comes before the current code block",
+			     new_lineno);
+		return -1;
+	}
+
+	/* Find the bytecode offset for the start of the given line, or the
+	 * first code-owning line after it. */
+	PyString_AsStringAndSize(f->f_code->co_lnotab, &lnotab, &lnotab_len);
+	addr = 0;
+	line = f->f_code->co_firstlineno;
+	new_lasti = -1;
+	for (offset = 0; offset < lnotab_len; offset += 2) {
+		addr += lnotab[offset];
+		line += lnotab[offset+1];
+		if (line >= new_lineno) {
+			new_lasti = addr;
+			new_lineno = line;
+			break;
+		}
+	}
+
+	/* If we didn't reach the requested line, return an error. */
+	if (new_lasti == -1) {
+		PyErr_Format(PyExc_ValueError,
+			     "line %d comes after the current code block",
+			     new_lineno);
+		return -1;
+	}
+
+	/* We're now ready to look at the bytecode. */
+	PyString_AsStringAndSize(f->f_code->co_code, &code, &code_len);
+	min_addr = MIN(new_lasti, f->f_lasti);
+	max_addr = MAX(new_lasti, f->f_lasti);
+
+	/* You can't jump onto a line with an 'except' statement on it -
+	 * they expect to have an exception on the top of the stack, which
+	 * won't be true if you jump to them.  They always start with code
+	 * that either pops the exception using POP_TOP (plain 'except:'
+	 * lines do this) or duplicates the exception on the stack using
+	 * DUP_TOP (if there's an exception type specified).  See compile.c,
+	 * 'com_try_except' for the full details.  There aren't any other
+	 * cases (AFAIK) where a line's code can start with DUP_TOP or
+	 * POP_TOP, but if any ever appear, they'll be subject to the same
+	 * restriction (but with a different error message). */
+	if (code[new_lasti] == DUP_TOP || code[new_lasti] == POP_TOP) {
+		PyErr_SetString(PyExc_ValueError,
+		    "can't jump to 'except' line as there's no exception");
+		return -1;
+	}
+
+	/* You can't jump into or out of a 'finally' block because the 'try'
+	 * block leaves something on the stack for the END_FINALLY to clean
+	 * up.  So we walk the bytecode, maintaining a simulated blockstack.
+	 * When we reach the old or new address and it's in a 'finally' block
+	 * we note the address of the corresponding SETUP_FINALLY.  The jump
+	 * is only legal if neither address is in a 'finally' block or
+	 * they're both in the same one.  'blockstack' is a stack of the
+	 * bytecode addresses of the SETUP_X opcodes, and 'in_finally' tracks
+	 * whether we're in a 'finally' block at each blockstack level. */
+	f_lasti_setup_addr = -1;
+	new_lasti_setup_addr = -1;
+	memset(blockstack, '\0', sizeof(blockstack));
+	memset(in_finally, '\0', sizeof(in_finally));
+	blockstack_top = 0;
+	for (addr = 0; addr < code_len; addr++) {
+		unsigned char op = code[addr];
+		switch (op) {
+		case SETUP_LOOP:
+		case SETUP_EXCEPT:
+		case SETUP_FINALLY:
+			blockstack[blockstack_top++] = addr;
+			in_finally[blockstack_top-1] = 0;
+			break;
+
+		case POP_BLOCK:
+			assert(blockstack_top > 0);
+			setup_op = code[blockstack[blockstack_top-1]];
+			if (setup_op == SETUP_FINALLY) {
+				in_finally[blockstack_top-1] = 1;
+			}
+			else {
+				blockstack_top--;
+			}
+			break;
+
+		case END_FINALLY:
+			/* Ignore END_FINALLYs for SETUP_EXCEPTs - they exist
+			 * in the bytecode but don't correspond to an actual
+			 * 'finally' block.  (If blockstack_top is 0, we must
+			 * be seeing such an END_FINALLY.) */
+			if (blockstack_top > 0) {
+				setup_op = code[blockstack[blockstack_top-1]];
+				if (setup_op == SETUP_FINALLY) {
+					blockstack_top--;
+				}
+			}
+			break;
+		}
+
+		/* For the addresses we're interested in, see whether they're
+		 * within a 'finally' block and if so, remember the address
+		 * of the SETUP_FINALLY. */
+		if (addr == new_lasti || addr == f->f_lasti) {
+			int i = 0;
+			int setup_addr = -1;
+			for (i = blockstack_top-1; i >= 0; i--) {
+				if (in_finally[i]) {
+					setup_addr = blockstack[i];
+					break;
+				}
+			}
+
+			if (setup_addr != -1) {
+				if (addr == new_lasti) {
+					new_lasti_setup_addr = setup_addr;
+				}
+
+				if (addr == f->f_lasti) {
+					f_lasti_setup_addr = setup_addr;
+				}
+			}
+		}
+
+		if (op >= HAVE_ARGUMENT) {
+			addr += 2;
+		}
+	}
+
+	/* Verify that the blockstack tracking code didn't get lost. */
+	assert(blockstack_top == 0);
+
+	/* After all that, are we jumping into / out of a 'finally' block? */
+	if (new_lasti_setup_addr != f_lasti_setup_addr) {
+		PyErr_SetString(PyExc_ValueError,
+			    "can't jump into or out of a 'finally' block");
+		return -1;
+	}
+
+
+	/* Police block-jumping (you can't jump into the middle of a block)
+	 * and ensure that the blockstack finishes up in a sensible state (by
+	 * popping any blocks we're jumping out of).  We look at all the
+	 * blockstack operations between the current position and the new
+	 * one, and keep track of how many blocks we drop out of on the way.
+	 * By also keeping track of the lowest blockstack position we see, we
+	 * can tell whether the jump goes into any blocks without coming out
+	 * again - in that case we raise an exception below. */
+	delta_iblock = 0;
+	for (addr = min_addr; addr < max_addr; addr++) {
+		unsigned char op = code[addr];
+		switch (op) {
+		case SETUP_LOOP:
+		case SETUP_EXCEPT:
+		case SETUP_FINALLY:
+			delta_iblock++;
+			break;
+
+		case POP_BLOCK:
+			delta_iblock--;
+			break;
+		}
+
+		min_delta_iblock = MIN(min_delta_iblock, delta_iblock);
+
+		if (op >= HAVE_ARGUMENT) {
+			addr += 2;
+		}
+	}
+
+	/* Derive the absolute iblock values from the deltas. */
+	min_iblock = f->f_iblock + min_delta_iblock;
+	if (new_lasti > f->f_lasti) {
+		/* Forwards jump. */
+		new_iblock = f->f_iblock + delta_iblock;
+	}
+	else {
+		/* Backwards jump. */
+		new_iblock = f->f_iblock - delta_iblock;
+	}
+
+	/* Are we jumping into a block? */
+	if (new_iblock > min_iblock) {
+		PyErr_SetString(PyExc_ValueError,
+				"can't jump into the middle of a block");
+		return -1;
+	}
+
+	/* Pop any blocks that we're jumping out of. */
+	while (f->f_iblock > new_iblock) {
+		PyTryBlock *b = &f->f_blockstack[--f->f_iblock];
+		while ((f->f_stacktop - f->f_valuestack) > b->b_level) {
+			PyObject *v = (*--f->f_stacktop);
+			Py_DECREF(v);
+		}
+	}
+
+	/* Finally set the new f_lineno and f_lasti and return OK. */
+	f->f_lineno = new_lineno;
+	f->f_lasti = new_lasti;
+	return 0;
+}
+
+static PyObject *
+frame_gettrace(PyFrameObject *f, void *closure)
+{
+	PyObject* trace = f->f_trace;
+
+	if (trace == NULL)
+		trace = Py_None;
+
+	Py_INCREF(trace);
+
+	return trace;
+}
+
+static int
+frame_settrace(PyFrameObject *f, PyObject* v, void *closure)
+{
+	/* We rely on f_lineno being accurate when f_trace is set. */
+
+	PyObject* old_value = f->f_trace;
+
+	Py_XINCREF(v);
+	f->f_trace = v;
+
+	if (v != NULL)
+		f->f_lineno = PyCode_Addr2Line(f->f_code, f->f_lasti);
+
+	Py_XDECREF(old_value);
+
+	return 0;
+}
+
+static PyObject *
+frame_getrestricted(PyFrameObject *f, void *closure)
+{
+	return PyBool_FromLong(PyFrame_IsRestricted(f));
+}
+
+static PyGetSetDef frame_getsetlist[] = {
+	{"f_locals",	(getter)frame_getlocals, NULL, NULL},
+	{"f_lineno",	(getter)frame_getlineno,
+			(setter)frame_setlineno, NULL},
+	{"f_trace",	(getter)frame_gettrace, (setter)frame_settrace, NULL},
+	{"f_restricted",(getter)frame_getrestricted,NULL, NULL},
+	{0}
+};
+
+/* Stack frames are allocated and deallocated at a considerable rate.
+   In an attempt to improve the speed of function calls, we:
+
+   1. Hold a single "zombie" frame on each code object. This retains
+   the allocated and initialised frame object from an invocation of
+   the code object. The zombie is reanimated the next time we need a
+   frame object for that code object. Doing this saves the malloc/
+   realloc required when using a free_list frame that isn't the
+   correct size. It also saves some field initialisation.
+
+   In zombie mode, no field of PyFrameObject holds a reference, but
+   the following fields are still valid:
+
+     * ob_type, ob_size, f_code, f_valuestack;
+       
+     * f_locals, f_trace,
+       f_exc_type, f_exc_value, f_exc_traceback are NULL;
+
+     * f_localsplus does not require re-allocation and
+       the local variables in f_localsplus are NULL.
+
+   2. We also maintain a separate free list of stack frames (just like
+   integers are allocated in a special way -- see intobject.c).  When
+   a stack frame is on the free list, only the following members have
+   a meaning:
+	ob_type		== &Frametype
+	f_back		next item on free list, or NULL
+	f_stacksize	size of value stack
+        ob_size         size of localsplus
+   Note that the value and block stacks are preserved -- this can save
+   another malloc() call or two (and two free() calls as well!).
+   Also note that, unlike for integers, each frame object is a
+   malloc'ed object in its own right -- it is only the actual calls to
+   malloc() that we are trying to save here, not the administration.
+   After all, while a typical program may make millions of calls, a
+   call depth of more than 20 or 30 is probably already exceptional
+   unless the program contains run-away recursion.  I hope.
+
+   Later, MAXFREELIST was added to bound the # of frames saved on
+   free_list.  Else programs creating lots of cyclic trash involving
+   frames could provoke free_list into growing without bound.
+*/
+
+static PyFrameObject *free_list = NULL;
+static int numfree = 0;		/* number of frames currently in free_list */
+#define MAXFREELIST 200		/* max value for numfree */
+
+static void
+frame_dealloc(PyFrameObject *f)
+{
+	PyObject **p, **valuestack;
+	PyCodeObject *co;
+
+ 	PyObject_GC_UnTrack(f);
+	Py_TRASHCAN_SAFE_BEGIN(f)
+	/* Kill all local variables */
+        valuestack = f->f_valuestack;
+        for (p = f->f_localsplus; p < valuestack; p++)
+                Py_CLEAR(*p);
+
+	/* Free stack */
+	if (f->f_stacktop != NULL) {
+		for (p = valuestack; p < f->f_stacktop; p++)
+			Py_XDECREF(*p);
+	}
+
+	Py_XDECREF(f->f_back);
+	Py_DECREF(f->f_builtins);
+	Py_DECREF(f->f_globals);
+	Py_CLEAR(f->f_locals);
+	Py_CLEAR(f->f_trace);
+	Py_CLEAR(f->f_exc_type);
+	Py_CLEAR(f->f_exc_value);
+	Py_CLEAR(f->f_exc_traceback);
+
+        co = f->f_code;
+        if (co->co_zombieframe == NULL)
+                co->co_zombieframe = f;
+	else if (numfree < MAXFREELIST) {
+		++numfree;
+		f->f_back = free_list;
+		free_list = f;
+        }
+	else 
+		PyObject_GC_Del(f);
+
+        Py_DECREF(co);
+	Py_TRASHCAN_SAFE_END(f)
+}
+
+static int
+frame_traverse(PyFrameObject *f, visitproc visit, void *arg)
+{
+	PyObject **fastlocals, **p;
+	int i, slots;
+
+	Py_VISIT(f->f_back);
+	Py_VISIT(f->f_code);
+	Py_VISIT(f->f_builtins);
+	Py_VISIT(f->f_globals);
+	Py_VISIT(f->f_locals);
+	Py_VISIT(f->f_trace);
+	Py_VISIT(f->f_exc_type);
+	Py_VISIT(f->f_exc_value);
+	Py_VISIT(f->f_exc_traceback);
+
+	/* locals */
+	slots = f->f_code->co_nlocals + PyTuple_GET_SIZE(f->f_code->co_cellvars) + PyTuple_GET_SIZE(f->f_code->co_freevars);
+	fastlocals = f->f_localsplus;
+	for (i = slots; --i >= 0; ++fastlocals)
+		Py_VISIT(*fastlocals);
+
+	/* stack */
+	if (f->f_stacktop != NULL) {
+		for (p = f->f_valuestack; p < f->f_stacktop; p++)
+			Py_VISIT(*p);
+	}
+	return 0;
+}
+
+static void
+frame_clear(PyFrameObject *f)
+{
+	PyObject **fastlocals, **p, **oldtop;
+	int i, slots;
+
+	/* Before anything else, make sure that this frame is clearly marked
+         * as being defunct!  Else, e.g., a generator reachable from this
+         * frame may also point to this frame, believe itself to still be
+         * active, and try cleaning up this frame again.
+         */
+	oldtop = f->f_stacktop;
+        f->f_stacktop = NULL;
+
+	Py_CLEAR(f->f_exc_type);
+	Py_CLEAR(f->f_exc_value);
+	Py_CLEAR(f->f_exc_traceback);
+	Py_CLEAR(f->f_trace);
+
+	/* locals */
+	slots = f->f_code->co_nlocals + PyTuple_GET_SIZE(f->f_code->co_cellvars) + PyTuple_GET_SIZE(f->f_code->co_freevars);
+	fastlocals = f->f_localsplus;
+	for (i = slots; --i >= 0; ++fastlocals)
+		Py_CLEAR(*fastlocals);
+
+	/* stack */
+	if (oldtop != NULL) {
+		for (p = f->f_valuestack; p < oldtop; p++)
+			Py_CLEAR(*p);
+	}
+}
+
+
+PyTypeObject PyFrame_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,
+	"frame",
+	sizeof(PyFrameObject),
+	sizeof(PyObject *),
+	(destructor)frame_dealloc, 		/* tp_dealloc */
+	0,					/* tp_print */
+	0, 					/* tp_getattr */
+	0,			 		/* tp_setattr */
+	0,					/* tp_compare */
+	0,					/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	PyObject_GenericSetAttr,		/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+	0,             				/* tp_doc */
+ 	(traverseproc)frame_traverse,		/* tp_traverse */
+	(inquiry)frame_clear,			/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	0,					/* tp_methods */
+	frame_memberlist,			/* tp_members */
+	frame_getsetlist,			/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+};
+
+static PyObject *builtin_object;
+
+int _PyFrame_Init()
+{
+	builtin_object = PyString_InternFromString("__builtins__");
+	return (builtin_object != NULL);
+}
+
+PyFrameObject *
+PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals,
+	    PyObject *locals)
+{
+	PyFrameObject *back = tstate->frame;
+	PyFrameObject *f;
+	PyObject *builtins;
+	Py_ssize_t i;
+
+#ifdef Py_DEBUG
+	if (code == NULL || globals == NULL || !PyDict_Check(globals) ||
+	    (locals != NULL && !PyMapping_Check(locals))) {
+		PyErr_BadInternalCall();
+		return NULL;
+	}
+#endif
+	if (back == NULL || back->f_globals != globals) {
+		builtins = PyDict_GetItem(globals, builtin_object);
+		if (builtins) {
+			if (PyModule_Check(builtins)) {
+				builtins = PyModule_GetDict(builtins);
+				assert(!builtins || PyDict_Check(builtins));
+			}
+			else if (!PyDict_Check(builtins))
+				builtins = NULL;
+		}
+		if (builtins == NULL) {
+			/* No builtins!  Make up a minimal one
+			   Give them 'None', at least. */
+			builtins = PyDict_New();
+			if (builtins == NULL ||
+			    PyDict_SetItemString(
+				    builtins, "None", Py_None) < 0)
+				return NULL;
+		}
+		else
+			Py_INCREF(builtins);
+
+	}
+	else {
+		/* If we share the globals, we share the builtins.
+		   Save a lookup and a call. */
+		builtins = back->f_builtins;
+		assert(builtins != NULL && PyDict_Check(builtins));
+		Py_INCREF(builtins);
+	}
+	if (code->co_zombieframe != NULL) {
+                f = code->co_zombieframe;
+                code->co_zombieframe = NULL;
+                _Py_NewReference((PyObject *)f);
+                assert(f->f_code == code);
+	}
+        else {
+                Py_ssize_t extras, ncells, nfrees;
+                ncells = PyTuple_GET_SIZE(code->co_cellvars);
+                nfrees = PyTuple_GET_SIZE(code->co_freevars);
+                extras = code->co_stacksize + code->co_nlocals + ncells +
+                    nfrees;
+                if (free_list == NULL) {
+                    f = PyObject_GC_NewVar(PyFrameObject, &PyFrame_Type,
+                        extras);
+                    if (f == NULL) {
+                            Py_DECREF(builtins);
+                            return NULL;
+                    }
+                }
+                else {
+                    assert(numfree > 0);
+                    --numfree;
+                    f = free_list;
+                    free_list = free_list->f_back;
+                    if (f->ob_size < extras) {
+                            f = PyObject_GC_Resize(PyFrameObject, f, extras);
+                            if (f == NULL) {
+                                    Py_DECREF(builtins);
+                                    return NULL;
+                            }
+                    }
+                    _Py_NewReference((PyObject *)f);
+                }
+
+		f->f_code = code;
+		extras = code->co_nlocals + ncells + nfrees;
+		f->f_valuestack = f->f_localsplus + extras;
+		for (i=0; i<extras; i++)
+			f->f_localsplus[i] = NULL;
+		f->f_locals = NULL;
+		f->f_trace = NULL;
+                f->f_exc_type = f->f_exc_value = f->f_exc_traceback = NULL;
+	}
+	f->f_stacktop = f->f_valuestack;
+	f->f_builtins = builtins;
+	Py_XINCREF(back);
+	f->f_back = back;
+	Py_INCREF(code);
+	Py_INCREF(globals);
+	f->f_globals = globals;
+	/* Most functions have CO_NEWLOCALS and CO_OPTIMIZED set. */
+	if ((code->co_flags & (CO_NEWLOCALS | CO_OPTIMIZED)) ==
+		(CO_NEWLOCALS | CO_OPTIMIZED))
+		; /* f_locals = NULL; will be set by PyFrame_FastToLocals() */
+	else if (code->co_flags & CO_NEWLOCALS) {
+		locals = PyDict_New();
+		if (locals == NULL) {
+			Py_DECREF(f);
+			return NULL;
+		}
+                f->f_locals = locals;
+	}
+	else {
+		if (locals == NULL)
+			locals = globals;
+		Py_INCREF(locals);
+                f->f_locals = locals;
+	}
+	f->f_tstate = tstate;
+
+	f->f_lasti = -1;
+	f->f_lineno = code->co_firstlineno;
+	f->f_iblock = 0;
+
+	_PyObject_GC_TRACK(f);
+	return f;
+}
+
+/* Block management */
+
+void
+PyFrame_BlockSetup(PyFrameObject *f, int type, int handler, int level)
+{
+	PyTryBlock *b;
+	if (f->f_iblock >= CO_MAXBLOCKS)
+		Py_FatalError("XXX block stack overflow");
+	b = &f->f_blockstack[f->f_iblock++];
+	b->b_type = type;
+	b->b_level = level;
+	b->b_handler = handler;
+}
+
+PyTryBlock *
+PyFrame_BlockPop(PyFrameObject *f)
+{
+	PyTryBlock *b;
+	if (f->f_iblock <= 0)
+		Py_FatalError("XXX block stack underflow");
+	b = &f->f_blockstack[--f->f_iblock];
+	return b;
+}
+
+/* Convert between "fast" version of locals and dictionary version */
+
+static void
+map_to_dict(PyObject *map, Py_ssize_t nmap, PyObject *dict, PyObject **values,
+	    Py_ssize_t deref)
+{
+	Py_ssize_t j;
+	for (j = nmap; --j >= 0; ) {
+		PyObject *key = PyTuple_GET_ITEM(map, j);
+		PyObject *value = values[j];
+		if (deref)
+			value = PyCell_GET(value);
+		if (value == NULL) {
+			if (PyObject_DelItem(dict, key) != 0)
+				PyErr_Clear();
+		}
+		else {
+			if (PyObject_SetItem(dict, key, value) != 0)
+				PyErr_Clear();
+		}
+	}
+}
+
+static void
+dict_to_map(PyObject *map, Py_ssize_t nmap, PyObject *dict, PyObject **values,
+	    Py_ssize_t deref, int clear)
+{
+	Py_ssize_t j;
+	for (j = nmap; --j >= 0; ) {
+		PyObject *key = PyTuple_GET_ITEM(map, j);
+		PyObject *value = PyObject_GetItem(dict, key);
+		if (value == NULL)
+			PyErr_Clear();
+		if (deref) {
+			if (value || clear) {
+				if (PyCell_GET(values[j]) != value) {
+					if (PyCell_Set(values[j], value) < 0)
+						PyErr_Clear();
+				}
+			}
+		} else if (value != NULL || clear) {
+			if (values[j] != value) {
+				Py_XINCREF(value);
+				Py_XDECREF(values[j]);
+				values[j] = value;
+			}
+		}
+		Py_XDECREF(value);
+	}
+}
+
+void
+PyFrame_FastToLocals(PyFrameObject *f)
+{
+	/* Merge fast locals into f->f_locals */
+	PyObject *locals, *map;
+	PyObject **fast;
+	PyObject *error_type, *error_value, *error_traceback;
+	PyCodeObject *co;
+	Py_ssize_t j;
+        int ncells, nfreevars;
+	if (f == NULL)
+		return;
+	locals = f->f_locals;
+	if (locals == NULL) {
+		locals = f->f_locals = PyDict_New();
+		if (locals == NULL) {
+			PyErr_Clear(); /* Can't report it :-( */
+			return;
+		}
+	}
+	co = f->f_code;
+	map = co->co_varnames;
+	if (!PyTuple_Check(map))
+		return;
+	PyErr_Fetch(&error_type, &error_value, &error_traceback);
+	fast = f->f_localsplus;
+	j = PyTuple_GET_SIZE(map);
+	if (j > co->co_nlocals)
+		j = co->co_nlocals;
+	if (co->co_nlocals)
+		map_to_dict(map, j, locals, fast, 0);
+	ncells = PyTuple_GET_SIZE(co->co_cellvars);
+	nfreevars = PyTuple_GET_SIZE(co->co_freevars);
+	if (ncells || nfreevars) {
+		map_to_dict(co->co_cellvars, ncells,
+			    locals, fast + co->co_nlocals, 1);
+		map_to_dict(co->co_freevars, nfreevars,
+			    locals, fast + co->co_nlocals + ncells, 1);
+	}
+	PyErr_Restore(error_type, error_value, error_traceback);
+}
+
+void
+PyFrame_LocalsToFast(PyFrameObject *f, int clear)
+{
+	/* Merge f->f_locals into fast locals */
+	PyObject *locals, *map;
+	PyObject **fast;
+	PyObject *error_type, *error_value, *error_traceback;
+	PyCodeObject *co;
+	Py_ssize_t j;
+	int ncells, nfreevars;
+	if (f == NULL)
+		return;
+	locals = f->f_locals;
+	co = f->f_code;
+	map = co->co_varnames;
+	if (locals == NULL)
+		return;
+	if (!PyTuple_Check(map))
+		return;
+	PyErr_Fetch(&error_type, &error_value, &error_traceback);
+	fast = f->f_localsplus;
+	j = PyTuple_GET_SIZE(map);
+	if (j > co->co_nlocals)
+		j = co->co_nlocals;
+	if (co->co_nlocals)
+	    dict_to_map(co->co_varnames, j, locals, fast, 0, clear);
+	ncells = PyTuple_GET_SIZE(co->co_cellvars);
+	nfreevars = PyTuple_GET_SIZE(co->co_freevars);
+	if (ncells || nfreevars) {
+		dict_to_map(co->co_cellvars, ncells,
+			    locals, fast + co->co_nlocals, 1, clear);
+		dict_to_map(co->co_freevars, nfreevars,
+			    locals, fast + co->co_nlocals + ncells, 1, 
+ 			    clear);
+	}
+	PyErr_Restore(error_type, error_value, error_traceback);
+}
+
+/* Clear out the free list */
+
+void
+PyFrame_Fini(void)
+{
+	while (free_list != NULL) {
+		PyFrameObject *f = free_list;
+		free_list = free_list->f_back;
+		PyObject_GC_Del(f);
+		--numfree;
+	}
+	assert(numfree == 0);
+	Py_XDECREF(builtin_object);
+	builtin_object = NULL;
+}

Added: vendor/Python/current/Objects/funcobject.c
===================================================================
--- vendor/Python/current/Objects/funcobject.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Objects/funcobject.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,888 @@
+
+/* Function object implementation */
+
+#include "Python.h"
+#include "code.h"
+#include "eval.h"
+#include "structmember.h"
+
+PyObject *
+PyFunction_New(PyObject *code, PyObject *globals)
+{
+	PyFunctionObject *op = PyObject_GC_New(PyFunctionObject,
+					    &PyFunction_Type);
+	static PyObject *__name__ = 0;
+	if (op != NULL) {
+		PyObject *doc;
+		PyObject *consts;
+		PyObject *module;
+		op->func_weakreflist = NULL;
+		Py_INCREF(code);
+		op->func_code = code;
+		Py_INCREF(globals);
+		op->func_globals = globals;
+		op->func_name = ((PyCodeObject *)code)->co_name;
+		Py_INCREF(op->func_name);
+		op->func_defaults = NULL; /* No default arguments */
+		op->func_closure = NULL;
+		consts = ((PyCodeObject *)code)->co_consts;
+		if (PyTuple_Size(consts) >= 1) {
+			doc = PyTuple_GetItem(consts, 0);
+			if (!PyString_Check(doc) && !PyUnicode_Check(doc))
+				doc = Py_None;
+		}
+		else
+			doc = Py_None;
+		Py_INCREF(doc);
+		op->func_doc = doc;
+		op->func_dict = NULL;
+		op->func_module = NULL;
+
+		/* __module__: If module name is in globals, use it.
+		   Otherwise, use None.
+		*/
+		if (!__name__) {
+			__name__ = PyString_InternFromString("__name__");
+			if (!__name__) {
+				Py_DECREF(op);
+				return NULL;
+			}
+		}
+		module = PyDict_GetItem(globals, __name__);
+		if (module) {
+		    Py_INCREF(module);
+		    op->func_module = module;
+		}
+	}
+	else
+		return NULL;
+	_PyObject_GC_TRACK(op);
+	return (PyObject *)op;
+}
+
+PyObject *
+PyFunction_GetCode(PyObject *op)
+{
+	if (!PyFunction_Check(op)) {
+		PyErr_BadInternalCall();
+		return NULL;
+	}
+	return ((PyFunctionObject *) op) -> func_code;
+}
+
+PyObject *
+PyFunction_GetGlobals(PyObject *op)
+{
+	if (!PyFunction_Check(op)) {
+		PyErr_BadInternalCall();
+		return NULL;
+	}
+	return ((PyFunctionObject *) op) -> func_globals;
+}
+
+PyObject *
+PyFunction_GetModule(PyObject *op)
+{
+	if (!PyFunction_Check(op)) {
+		PyErr_BadInternalCall();
+		return NULL;
+	}
+	return ((PyFunctionObject *) op) -> func_module;
+}
+
+PyObject *
+PyFunction_GetDefaults(PyObject *op)
+{
+	if (!PyFunction_Check(op)) {
+		PyErr_BadInternalCall();
+		return NULL;
+	}
+	return ((PyFunctionObject *) op) -> func_defaults;
+}
+
+int
+PyFunction_SetDefaults(PyObject *op, PyObject *defaults)
+{
+	if (!PyFunction_Check(op)) {
+		PyErr_BadInternalCall();
+		return -1;
+	}
+	if (defaults == Py_None)
+		defaults = NULL;
+	else if (defaults && PyTuple_Check(defaults)) {
+		Py_INCREF(defaults);
+	}
+	else {
+		PyErr_SetString(PyExc_SystemError, "non-tuple default args");
+		return -1;
+	}
+	Py_XDECREF(((PyFunctionObject *) op) -> func_defaults);
+	((PyFunctionObject *) op) -> func_defaults = defaults;
+	return 0;
+}
+
+PyObject *
+PyFunction_GetClosure(PyObject *op)
+{
+	if (!PyFunction_Check(op)) {
+		PyErr_BadInternalCall();
+		return NULL;
+	}
+	return ((PyFunctionObject *) op) -> func_closure;
+}
+
+int
+PyFunction_SetClosure(PyObject *op, PyObject *closure)
+{
+	if (!PyFunction_Check(op)) {
+		PyErr_BadInternalCall();
+		return -1;
+	}
+	if (closure == Py_None)
+		closure = NULL;
+	else if (PyTuple_Check(closure)) {
+		Py_INCREF(closure);
+	}
+	else {
+		PyErr_Format(PyExc_SystemError, 
+			     "expected tuple for closure, got '%.100s'",
+			     closure->ob_type->tp_name);
+		return -1;
+	}
+	Py_XDECREF(((PyFunctionObject *) op) -> func_closure);
+	((PyFunctionObject *) op) -> func_closure = closure;
+	return 0;
+}
+
+/* Methods */
+
+#define OFF(x) offsetof(PyFunctionObject, x)
+
+static PyMemberDef func_memberlist[] = {
+        {"func_closure",  T_OBJECT,     OFF(func_closure),
+	 RESTRICTED|READONLY},
+        {"func_doc",      T_OBJECT,     OFF(func_doc), WRITE_RESTRICTED},
+        {"__doc__",       T_OBJECT,     OFF(func_doc), WRITE_RESTRICTED},
+        {"func_globals",  T_OBJECT,     OFF(func_globals),
+	 RESTRICTED|READONLY},
+        {"__module__",    T_OBJECT,     OFF(func_module), WRITE_RESTRICTED},
+        {NULL}  /* Sentinel */
+};
+
+static int
+restricted(void)
+{
+	if (!PyEval_GetRestricted())
+		return 0;
+	PyErr_SetString(PyExc_RuntimeError,
+		"function attributes not accessible in restricted mode");
+	return 1;
+}
+
+static PyObject *
+func_get_dict(PyFunctionObject *op)
+{
+	if (restricted())
+		return NULL;
+	if (op->func_dict == NULL) {
+		op->func_dict = PyDict_New();
+		if (op->func_dict == NULL)
+			return NULL;
+	}
+	Py_INCREF(op->func_dict);
+	return op->func_dict;
+}
+
+static int
+func_set_dict(PyFunctionObject *op, PyObject *value)
+{
+	PyObject *tmp;
+
+	if (restricted())
+		return -1;
+	/* It is illegal to del f.func_dict */
+	if (value == NULL) {
+		PyErr_SetString(PyExc_TypeError,
+				"function's dictionary may not be deleted");
+		return -1;
+	}
+	/* Can only set func_dict to a dictionary */
+	if (!PyDict_Check(value)) {
+		PyErr_SetString(PyExc_TypeError,
+				"setting function's dictionary to a non-dict");
+		return -1;
+	}
+	tmp = op->func_dict;
+	Py_INCREF(value);
+	op->func_dict = value;
+	Py_XDECREF(tmp);
+	return 0;
+}
+
+static PyObject *
+func_get_code(PyFunctionObject *op)
+{
+	if (restricted())
+		return NULL;
+	Py_INCREF(op->func_code);
+	return op->func_code;
+}
+
+static int
+func_set_code(PyFunctionObject *op, PyObject *value)
+{
+	PyObject *tmp;
+	Py_ssize_t nfree, nclosure;
+
+	if (restricted())
+		return -1;
+	/* Not legal to del f.func_code or to set it to anything
+	 * other than a code object. */
+	if (value == NULL || !PyCode_Check(value)) {
+		PyErr_SetString(PyExc_TypeError,
+				"func_code must be set to a code object");
+		return -1;
+	}
+	nfree = PyCode_GetNumFree((PyCodeObject *)value);
+	nclosure = (op->func_closure == NULL ? 0 :
+		    PyTuple_GET_SIZE(op->func_closure));
+	if (nclosure != nfree) {
+		PyErr_Format(PyExc_ValueError,
+			     "%s() requires a code object with %zd free vars,"
+			     " not %zd",
+			     PyString_AsString(op->func_name),
+			     nclosure, nfree);
+		return -1;
+	}
+	tmp = op->func_code;
+	Py_INCREF(value);
+	op->func_code = value;
+	Py_DECREF(tmp);
+	return 0;
+}
+
+static PyObject *
+func_get_name(PyFunctionObject *op)
+{
+	Py_INCREF(op->func_name);
+	return op->func_name;
+}
+
+static int
+func_set_name(PyFunctionObject *op, PyObject *value)
+{
+	PyObject *tmp;
+
+	if (restricted())
+		return -1;
+	/* Not legal to del f.func_name or to set it to anything
+	 * other than a string object. */
+	if (value == NULL || !PyString_Check(value)) {
+		PyErr_SetString(PyExc_TypeError,
+				"func_name must be set to a string object");
+		return -1;
+	}
+	tmp = op->func_name;
+	Py_INCREF(value);
+	op->func_name = value;
+	Py_DECREF(tmp);
+	return 0;
+}
+
+static PyObject *
+func_get_defaults(PyFunctionObject *op)
+{
+	if (restricted())
+		return NULL;
+	if (op->func_defaults == NULL) {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+	Py_INCREF(op->func_defaults);
+	return op->func_defaults;
+}
+
+static int
+func_set_defaults(PyFunctionObject *op, PyObject *value)
+{
+	PyObject *tmp;
+
+	if (restricted())
+		return -1;
+	/* Legal to del f.func_defaults.
+	 * Can only set func_defaults to NULL or a tuple. */
+	if (value == Py_None)
+		value = NULL;
+	if (value != NULL && !PyTuple_Check(value)) {
+		PyErr_SetString(PyExc_TypeError,
+				"func_defaults must be set to a tuple object");
+		return -1;
+	}
+	tmp = op->func_defaults;
+	Py_XINCREF(value);
+	op->func_defaults = value;
+	Py_XDECREF(tmp);
+	return 0;
+}
+
+static PyGetSetDef func_getsetlist[] = {
+        {"func_code", (getter)func_get_code, (setter)func_set_code},
+        {"func_defaults", (getter)func_get_defaults,
+	 (setter)func_set_defaults},
+	{"func_dict", (getter)func_get_dict, (setter)func_set_dict},
+	{"__dict__", (getter)func_get_dict, (setter)func_set_dict},
+	{"func_name", (getter)func_get_name, (setter)func_set_name},
+	{"__name__", (getter)func_get_name, (setter)func_set_name},
+	{NULL} /* Sentinel */
+};
+
+PyDoc_STRVAR(func_doc,
+"function(code, globals[, name[, argdefs[, closure]]])\n\
+\n\
+Create a function object from a code object and a dictionary.\n\
+The optional name string overrides the name from the code object.\n\
+The optional argdefs tuple specifies the default argument values.\n\
+The optional closure tuple supplies the bindings for free variables.");
+
+/* func_new() maintains the following invariants for closures.  The
+   closure must correspond to the free variables of the code object.
+   
+   if len(code.co_freevars) == 0: 
+           closure = NULL
+   else:
+           len(closure) == len(code.co_freevars)
+   for every elt in closure, type(elt) == cell
+*/
+
+static PyObject *
+func_new(PyTypeObject* type, PyObject* args, PyObject* kw)
+{
+	PyCodeObject *code;
+	PyObject *globals;
+	PyObject *name = Py_None;
+	PyObject *defaults = Py_None;
+	PyObject *closure = Py_None;
+	PyFunctionObject *newfunc;
+	Py_ssize_t nfree, nclosure;
+	static char *kwlist[] = {"code", "globals", "name",
+				 "argdefs", "closure", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(args, kw, "O!O!|OOO:function",
+			      kwlist,
+			      &PyCode_Type, &code,
+			      &PyDict_Type, &globals,
+			      &name, &defaults, &closure))
+		return NULL;
+	if (name != Py_None && !PyString_Check(name)) {
+		PyErr_SetString(PyExc_TypeError,
+				"arg 3 (name) must be None or string");
+		return NULL;
+	}
+	if (defaults != Py_None && !PyTuple_Check(defaults)) {
+		PyErr_SetString(PyExc_TypeError,
+				"arg 4 (defaults) must be None or tuple");
+		return NULL;
+	}
+	nfree = PyTuple_GET_SIZE(code->co_freevars);
+	if (!PyTuple_Check(closure)) {
+		if (nfree && closure == Py_None) {
+			PyErr_SetString(PyExc_TypeError,
+					"arg 5 (closure) must be tuple");
+			return NULL;
+		}
+		else if (closure != Py_None) {
+			PyErr_SetString(PyExc_TypeError,
+				"arg 5 (closure) must be None or tuple");
+			return NULL;
+		}
+	}
+
+	/* check that the closure is well-formed */
+	nclosure = closure == Py_None ? 0 : PyTuple_GET_SIZE(closure);
+	if (nfree != nclosure)
+		return PyErr_Format(PyExc_ValueError,
+				    "%s requires closure of length %zd, not %zd",
+				    PyString_AS_STRING(code->co_name),
+				    nfree, nclosure);
+	if (nclosure) {
+		Py_ssize_t i;
+		for (i = 0; i < nclosure; i++) {
+			PyObject *o = PyTuple_GET_ITEM(closure, i);
+			if (!PyCell_Check(o)) {
+				return PyErr_Format(PyExc_TypeError,
+				    "arg 5 (closure) expected cell, found %s",
+						    o->ob_type->tp_name);
+			}
+		}
+	}
+	
+	newfunc = (PyFunctionObject *)PyFunction_New((PyObject *)code, 
+						     globals);
+	if (newfunc == NULL)
+		return NULL;
+	
+	if (name != Py_None) {
+		Py_INCREF(name);
+		Py_DECREF(newfunc->func_name);
+		newfunc->func_name = name;
+	}
+	if (defaults != Py_None) {
+		Py_INCREF(defaults);
+		newfunc->func_defaults  = defaults;
+	}
+	if (closure != Py_None) {
+		Py_INCREF(closure);
+		newfunc->func_closure = closure;
+	}
+
+	return (PyObject *)newfunc;
+}
+
+static void
+func_dealloc(PyFunctionObject *op)
+{
+	_PyObject_GC_UNTRACK(op);
+	if (op->func_weakreflist != NULL)
+		PyObject_ClearWeakRefs((PyObject *) op);
+	Py_DECREF(op->func_code);
+	Py_DECREF(op->func_globals);
+	Py_XDECREF(op->func_module);
+	Py_DECREF(op->func_name);
+	Py_XDECREF(op->func_defaults);
+	Py_XDECREF(op->func_doc);
+	Py_XDECREF(op->func_dict);
+	Py_XDECREF(op->func_closure);
+	PyObject_GC_Del(op);
+}
+
+static PyObject*
+func_repr(PyFunctionObject *op)
+{
+	return PyString_FromFormat("<function %s at %p>",
+				   PyString_AsString(op->func_name),
+				   op);
+}
+
+static int
+func_traverse(PyFunctionObject *f, visitproc visit, void *arg)
+{
+	Py_VISIT(f->func_code);
+	Py_VISIT(f->func_globals);
+	Py_VISIT(f->func_module);
+	Py_VISIT(f->func_defaults);
+	Py_VISIT(f->func_doc);
+	Py_VISIT(f->func_name);
+	Py_VISIT(f->func_dict);
+	Py_VISIT(f->func_closure);
+	return 0;
+}
+
+static PyObject *
+function_call(PyObject *func, PyObject *arg, PyObject *kw)
+{
+	PyObject *result;
+	PyObject *argdefs;
+	PyObject **d, **k;
+	Py_ssize_t nk, nd;
+
+	argdefs = PyFunction_GET_DEFAULTS(func);
+	if (argdefs != NULL && PyTuple_Check(argdefs)) {
+		d = &PyTuple_GET_ITEM((PyTupleObject *)argdefs, 0);
+		nd = PyTuple_Size(argdefs);
+	}
+	else {
+		d = NULL;
+		nd = 0;
+	}
+
+	if (kw != NULL && PyDict_Check(kw)) {
+		Py_ssize_t pos, i;
+		nk = PyDict_Size(kw);
+		k = PyMem_NEW(PyObject *, 2*nk);
+		if (k == NULL) {
+			PyErr_NoMemory();
+			return NULL;
+		}
+		pos = i = 0;
+		while (PyDict_Next(kw, &pos, &k[i], &k[i+1]))
+			i += 2;
+		nk = i/2;
+		/* XXX This is broken if the caller deletes dict items! */
+	}
+	else {
+		k = NULL;
+		nk = 0;
+	}
+
+	result = PyEval_EvalCodeEx(
+		(PyCodeObject *)PyFunction_GET_CODE(func),
+		PyFunction_GET_GLOBALS(func), (PyObject *)NULL,
+		&PyTuple_GET_ITEM(arg, 0), PyTuple_Size(arg),
+		k, nk, d, nd,
+		PyFunction_GET_CLOSURE(func));
+
+	if (k != NULL)
+		PyMem_DEL(k);
+
+	return result;
+}
+
+/* Bind a function to an object */
+static PyObject *
+func_descr_get(PyObject *func, PyObject *obj, PyObject *type)
+{
+	if (obj == Py_None)
+		obj = NULL;
+	return PyMethod_New(func, obj, type);
+}
+
+PyTypeObject PyFunction_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,
+	"function",
+	sizeof(PyFunctionObject),
+	0,
+	(destructor)func_dealloc,		/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	(reprfunc)func_repr,			/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	function_call,				/* tp_call */
+	0,					/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	PyObject_GenericSetAttr,		/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+	func_doc,				/* tp_doc */
+	(traverseproc)func_traverse,		/* tp_traverse */
+	0,					/* tp_clear */
+	0,					/* tp_richcompare */
+	offsetof(PyFunctionObject, func_weakreflist), /* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	0,					/* tp_methods */
+	func_memberlist,			/* tp_members */
+	func_getsetlist,			/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	func_descr_get,				/* tp_descr_get */
+	0,					/* tp_descr_set */
+	offsetof(PyFunctionObject, func_dict),	/* tp_dictoffset */
+	0,					/* tp_init */
+	0,					/* tp_alloc */
+	func_new,				/* tp_new */
+};
+
+
+/* Class method object */
+
+/* A class method receives the class as implicit first argument,
+   just like an instance method receives the instance.
+   To declare a class method, use this idiom:
+
+     class C:
+         def f(cls, arg1, arg2, ...): ...
+	 f = classmethod(f)
+   
+   It can be called either on the class (e.g. C.f()) or on an instance
+   (e.g. C().f()); the instance is ignored except for its class.
+   If a class method is called for a derived class, the derived class
+   object is passed as the implied first argument.
+
+   Class methods are different than C++ or Java static methods.
+   If you want those, see static methods below.
+*/
+
+typedef struct {
+	PyObject_HEAD
+	PyObject *cm_callable;
+} classmethod;
+
+static void
+cm_dealloc(classmethod *cm)
+{
+	_PyObject_GC_UNTRACK((PyObject *)cm);
+	Py_XDECREF(cm->cm_callable);
+	cm->ob_type->tp_free((PyObject *)cm);
+}
+
+static int
+cm_traverse(classmethod *cm, visitproc visit, void *arg)
+{
+	Py_VISIT(cm->cm_callable);
+	return 0;
+}
+
+static int
+cm_clear(classmethod *cm)
+{
+	Py_CLEAR(cm->cm_callable);
+	return 0;
+}
+
+
+static PyObject *
+cm_descr_get(PyObject *self, PyObject *obj, PyObject *type)
+{
+	classmethod *cm = (classmethod *)self;
+
+	if (cm->cm_callable == NULL) {
+		PyErr_SetString(PyExc_RuntimeError,
+				"uninitialized classmethod object");
+		return NULL;
+	}
+	if (type == NULL)
+		type = (PyObject *)(obj->ob_type);
+ 	return PyMethod_New(cm->cm_callable,
+			    type, (PyObject *)(type->ob_type));
+}
+
+static int
+cm_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+	classmethod *cm = (classmethod *)self;
+	PyObject *callable;
+
+	if (!PyArg_UnpackTuple(args, "classmethod", 1, 1, &callable))
+		return -1;
+	if (!_PyArg_NoKeywords("classmethod", kwds))
+		return -1;
+	if (!PyCallable_Check(callable)) {
+		PyErr_Format(PyExc_TypeError, "'%s' object is not callable",
+		     callable->ob_type->tp_name);
+		return -1;
+	}
+	
+	Py_INCREF(callable);
+	cm->cm_callable = callable;
+	return 0;
+}
+
+PyDoc_STRVAR(classmethod_doc,
+"classmethod(function) -> method\n\
+\n\
+Convert a function to be a class method.\n\
+\n\
+A class method receives the class as implicit first argument,\n\
+just like an instance method receives the instance.\n\
+To declare a class method, use this idiom:\n\
+\n\
+  class C:\n\
+      def f(cls, arg1, arg2, ...): ...\n\
+      f = classmethod(f)\n\
+\n\
+It can be called either on the class (e.g. C.f()) or on an instance\n\
+(e.g. C().f()).  The instance is ignored except for its class.\n\
+If a class method is called for a derived class, the derived class\n\
+object is passed as the implied first argument.\n\
+\n\
+Class methods are different than C++ or Java static methods.\n\
+If you want those, see the staticmethod builtin.");
+
+PyTypeObject PyClassMethod_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,
+	"classmethod",
+	sizeof(classmethod),
+	0,
+	(destructor)cm_dealloc,			/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	0,					/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
+	classmethod_doc,			/* tp_doc */
+	(traverseproc)cm_traverse,		/* tp_traverse */
+	(inquiry)cm_clear,			/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	0,					/* tp_methods */
+	0,					/* tp_members */
+	0,					/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	cm_descr_get,				/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	cm_init,				/* tp_init */
+	PyType_GenericAlloc,			/* tp_alloc */
+	PyType_GenericNew,			/* tp_new */
+	PyObject_GC_Del,	                /* tp_free */
+};
+
+PyObject *
+PyClassMethod_New(PyObject *callable)
+{
+	classmethod *cm = (classmethod *)
+		PyType_GenericAlloc(&PyClassMethod_Type, 0);
+	if (cm != NULL) {
+		Py_INCREF(callable);
+		cm->cm_callable = callable;
+	}
+	return (PyObject *)cm;
+}
+
+
+/* Static method object */
+
+/* A static method does not receive an implicit first argument.
+   To declare a static method, use this idiom:
+
+     class C:
+         def f(arg1, arg2, ...): ...
+	 f = staticmethod(f)
+
+   It can be called either on the class (e.g. C.f()) or on an instance
+   (e.g. C().f()); the instance is ignored except for its class.
+
+   Static methods in Python are similar to those found in Java or C++.
+   For a more advanced concept, see class methods above.
+*/
+
+typedef struct {
+	PyObject_HEAD
+	PyObject *sm_callable;
+} staticmethod;
+
+static void
+sm_dealloc(staticmethod *sm)
+{
+	_PyObject_GC_UNTRACK((PyObject *)sm);
+	Py_XDECREF(sm->sm_callable);
+	sm->ob_type->tp_free((PyObject *)sm);
+}
+
+static int
+sm_traverse(staticmethod *sm, visitproc visit, void *arg)
+{
+	Py_VISIT(sm->sm_callable);
+	return 0;
+}
+
+static int
+sm_clear(staticmethod *sm)
+{
+	Py_XDECREF(sm->sm_callable);
+	sm->sm_callable = NULL;
+
+	return 0;
+}
+
+static PyObject *
+sm_descr_get(PyObject *self, PyObject *obj, PyObject *type)
+{
+	staticmethod *sm = (staticmethod *)self;
+
+	if (sm->sm_callable == NULL) {
+		PyErr_SetString(PyExc_RuntimeError,
+				"uninitialized staticmethod object");
+		return NULL;
+	}
+	Py_INCREF(sm->sm_callable);
+	return sm->sm_callable;
+}
+
+static int
+sm_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+	staticmethod *sm = (staticmethod *)self;
+	PyObject *callable;
+
+	if (!PyArg_UnpackTuple(args, "staticmethod", 1, 1, &callable))
+		return -1;
+	if (!_PyArg_NoKeywords("staticmethod", kwds))
+		return -1;
+	Py_INCREF(callable);
+	sm->sm_callable = callable;
+	return 0;
+}
+
+PyDoc_STRVAR(staticmethod_doc,
+"staticmethod(function) -> method\n\
+\n\
+Convert a function to be a static method.\n\
+\n\
+A static method does not receive an implicit first argument.\n\
+To declare a static method, use this idiom:\n\
+\n\
+     class C:\n\
+         def f(arg1, arg2, ...): ...\n\
+	 f = staticmethod(f)\n\
+\n\
+It can be called either on the class (e.g. C.f()) or on an instance\n\
+(e.g. C().f()).  The instance is ignored except for its class.\n\
+\n\
+Static methods in Python are similar to those found in Java or C++.\n\
+For a more advanced concept, see the classmethod builtin.");
+
+PyTypeObject PyStaticMethod_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,
+	"staticmethod",
+	sizeof(staticmethod),
+	0,
+	(destructor)sm_dealloc,			/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	0,					/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
+	staticmethod_doc,			/* tp_doc */
+	(traverseproc)sm_traverse,		/* tp_traverse */
+	(inquiry)sm_clear,			/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	0,					/* tp_methods */
+	0,					/* tp_members */
+	0,					/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	sm_descr_get,				/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	sm_init,				/* tp_init */
+	PyType_GenericAlloc,			/* tp_alloc */
+	PyType_GenericNew,			/* tp_new */
+	PyObject_GC_Del,           		/* tp_free */
+};
+
+PyObject *
+PyStaticMethod_New(PyObject *callable)
+{
+	staticmethod *sm = (staticmethod *)
+		PyType_GenericAlloc(&PyStaticMethod_Type, 0);
+	if (sm != NULL) {
+		Py_INCREF(callable);
+		sm->sm_callable = callable;
+	}
+	return (PyObject *)sm;
+}

Added: vendor/Python/current/Objects/genobject.c
===================================================================
--- vendor/Python/current/Objects/genobject.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Objects/genobject.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,383 @@
+/* Generator object implementation */
+
+#include "Python.h"
+#include "frameobject.h"
+#include "genobject.h"
+#include "ceval.h"
+#include "structmember.h"
+#include "opcode.h"
+
+static int
+gen_traverse(PyGenObject *gen, visitproc visit, void *arg)
+{
+	Py_VISIT((PyObject *)gen->gi_frame);
+	return 0;
+}
+
+static void
+gen_dealloc(PyGenObject *gen)
+{
+	PyObject *self = (PyObject *) gen;
+
+	_PyObject_GC_UNTRACK(gen);
+
+	if (gen->gi_weakreflist != NULL)
+		PyObject_ClearWeakRefs(self);
+
+	_PyObject_GC_TRACK(self);
+
+	if (gen->gi_frame != NULL && gen->gi_frame->f_stacktop != NULL) {
+		/* Generator is paused, so we need to close */
+		gen->ob_type->tp_del(self);
+		if (self->ob_refcnt > 0)
+			return;		/* resurrected.  :( */
+	}
+
+	_PyObject_GC_UNTRACK(self);
+	Py_CLEAR(gen->gi_frame);
+	PyObject_GC_Del(gen);
+}
+
+
+static PyObject *
+gen_send_ex(PyGenObject *gen, PyObject *arg, int exc)
+{
+	PyThreadState *tstate = PyThreadState_GET();
+	PyFrameObject *f = gen->gi_frame;
+	PyObject *result;
+
+	if (gen->gi_running) {
+		PyErr_SetString(PyExc_ValueError,
+				"generator already executing");
+		return NULL;
+	}
+	if (f==NULL || f->f_stacktop == NULL) {
+		/* Only set exception if called from send() */
+		if (arg && !exc)
+			PyErr_SetNone(PyExc_StopIteration);
+		return NULL;
+	}
+
+	if (f->f_lasti == -1) {
+		if (arg && arg != Py_None) {
+			PyErr_SetString(PyExc_TypeError,
+					"can't send non-None value to a "
+					"just-started generator");
+			return NULL;
+		}
+	} else {
+		/* Push arg onto the frame's value stack */
+		result = arg ? arg : Py_None;
+	        Py_INCREF(result);
+	        *(f->f_stacktop++) = result;
+	}
+
+	/* Generators always return to their most recent caller, not
+	 * necessarily their creator. */
+	Py_XINCREF(tstate->frame);
+	assert(f->f_back == NULL);
+	f->f_back = tstate->frame;
+
+	gen->gi_running = 1;
+	result = PyEval_EvalFrameEx(f, exc);
+	gen->gi_running = 0;
+
+	/* Don't keep the reference to f_back any longer than necessary.  It
+	 * may keep a chain of frames alive or it could create a reference
+	 * cycle. */
+	assert(f->f_back == tstate->frame);
+	Py_CLEAR(f->f_back);
+
+	/* If the generator just returned (as opposed to yielding), signal
+	 * that the generator is exhausted. */
+	if (result == Py_None && f->f_stacktop == NULL) {
+		Py_DECREF(result);
+		result = NULL;
+		/* Set exception if not called by gen_iternext() */
+		if (arg)
+			PyErr_SetNone(PyExc_StopIteration);
+	}
+
+	if (!result || f->f_stacktop == NULL) {
+		/* generator can't be rerun, so release the frame */
+		Py_DECREF(f);
+		gen->gi_frame = NULL;
+	}
+
+	return result;
+}
+
+PyDoc_STRVAR(send_doc,
+"send(arg) -> send 'arg' into generator,\n\
+return next yielded value or raise StopIteration.");
+
+static PyObject *
+gen_send(PyGenObject *gen, PyObject *arg)
+{
+	return gen_send_ex(gen, arg, 0);
+}
+
+PyDoc_STRVAR(close_doc,
+"close(arg) -> raise GeneratorExit inside generator.");
+
+static PyObject *
+gen_close(PyGenObject *gen, PyObject *args)
+{
+	PyObject *retval;
+	PyErr_SetNone(PyExc_GeneratorExit);
+	retval = gen_send_ex(gen, Py_None, 1);
+	if (retval) {
+		Py_DECREF(retval);
+		PyErr_SetString(PyExc_RuntimeError,
+				"generator ignored GeneratorExit");
+		return NULL;
+	}
+	if (PyErr_ExceptionMatches(PyExc_StopIteration)
+	    || PyErr_ExceptionMatches(PyExc_GeneratorExit))
+	{
+		PyErr_Clear();	/* ignore these errors */
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+	return NULL;
+}
+
+static void
+gen_del(PyObject *self)
+{
+        PyObject *res;
+        PyObject *error_type, *error_value, *error_traceback;
+	PyGenObject *gen = (PyGenObject *)self;
+
+	if (gen->gi_frame == NULL || gen->gi_frame->f_stacktop == NULL)
+		/* Generator isn't paused, so no need to close */
+		return;
+
+        /* Temporarily resurrect the object. */
+        assert(self->ob_refcnt == 0);
+        self->ob_refcnt = 1;
+
+        /* Save the current exception, if any. */
+        PyErr_Fetch(&error_type, &error_value, &error_traceback);
+
+	res = gen_close(gen, NULL);
+
+	if (res == NULL)
+		PyErr_WriteUnraisable(self);
+	else
+		Py_DECREF(res);
+
+        /* Restore the saved exception. */
+        PyErr_Restore(error_type, error_value, error_traceback);
+
+        /* Undo the temporary resurrection; can't use DECREF here, it would
+         * cause a recursive call.
+         */
+        assert(self->ob_refcnt > 0);
+        if (--self->ob_refcnt == 0)
+                return; /* this is the normal path out */
+
+        /* close() resurrected it!  Make it look like the original Py_DECREF
+         * never happened.
+         */
+        {
+                Py_ssize_t refcnt = self->ob_refcnt;
+                _Py_NewReference(self);
+                self->ob_refcnt = refcnt;
+        }
+        assert(PyType_IS_GC(self->ob_type) &&
+               _Py_AS_GC(self)->gc.gc_refs != _PyGC_REFS_UNTRACKED);
+
+        /* If Py_REF_DEBUG, _Py_NewReference bumped _Py_RefTotal, so
+         * we need to undo that. */
+        _Py_DEC_REFTOTAL;
+        /* If Py_TRACE_REFS, _Py_NewReference re-added self to the object
+         * chain, so no more to do there.
+         * If COUNT_ALLOCS, the original decref bumped tp_frees, and
+         * _Py_NewReference bumped tp_allocs:  both of those need to be
+         * undone.
+         */
+#ifdef COUNT_ALLOCS
+        --self->ob_type->tp_frees;
+        --self->ob_type->tp_allocs;
+#endif
+}
+
+
+
+PyDoc_STRVAR(throw_doc,
+"throw(typ[,val[,tb]]) -> raise exception in generator,\n\
+return next yielded value or raise StopIteration.");
+
+static PyObject *
+gen_throw(PyGenObject *gen, PyObject *args)
+{
+	PyObject *typ;
+	PyObject *tb = NULL;
+	PyObject *val = NULL;
+
+	if (!PyArg_UnpackTuple(args, "throw", 1, 3, &typ, &val, &tb))
+		return NULL;
+
+	/* First, check the traceback argument, replacing None with
+	   NULL. */
+	if (tb == Py_None)
+		tb = NULL;
+	else if (tb != NULL && !PyTraceBack_Check(tb)) {
+		PyErr_SetString(PyExc_TypeError,
+			"throw() third argument must be a traceback object");
+		return NULL;
+	}
+
+	Py_INCREF(typ);
+	Py_XINCREF(val);
+	Py_XINCREF(tb);
+
+	if (PyExceptionClass_Check(typ)) {
+		PyErr_NormalizeException(&typ, &val, &tb);
+	}
+
+	else if (PyExceptionInstance_Check(typ)) {
+		/* Raising an instance.  The value should be a dummy. */
+		if (val && val != Py_None) {
+			PyErr_SetString(PyExc_TypeError,
+			  "instance exception may not have a separate value");
+			goto failed_throw;
+		}
+		else {
+			/* Normalize to raise <class>, <instance> */
+			Py_XDECREF(val);
+			val = typ;
+			typ = PyExceptionInstance_Class(typ);
+			Py_INCREF(typ);
+		}
+	}
+
+	/* Allow raising builtin string exceptions */
+
+	else if (!PyString_CheckExact(typ)) {
+		/* Not something you can raise.  throw() fails. */
+		PyErr_Format(PyExc_TypeError,
+			     "exceptions must be classes, or instances, not %s",
+			     typ->ob_type->tp_name);
+			goto failed_throw;
+	}
+
+	PyErr_Restore(typ, val, tb);
+	return gen_send_ex(gen, Py_None, 1);
+
+failed_throw:
+	/* Didn't use our arguments, so restore their original refcounts */
+	Py_DECREF(typ);
+	Py_XDECREF(val);
+	Py_XDECREF(tb);
+	return NULL;
+}
+
+
+static PyObject *
+gen_iternext(PyGenObject *gen)
+{
+	return gen_send_ex(gen, NULL, 0);
+}
+
+
+static PyMemberDef gen_memberlist[] = {
+	{"gi_frame",	T_OBJECT, offsetof(PyGenObject, gi_frame),	RO},
+	{"gi_running",	T_INT,    offsetof(PyGenObject, gi_running),	RO},
+	{NULL}	/* Sentinel */
+};
+
+static PyMethodDef gen_methods[] = {
+	{"send",(PyCFunction)gen_send, METH_O, send_doc},
+	{"throw",(PyCFunction)gen_throw, METH_VARARGS, throw_doc},
+	{"close",(PyCFunction)gen_close, METH_NOARGS, close_doc},
+	{NULL, NULL}	/* Sentinel */
+};
+
+PyTypeObject PyGen_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,					/* ob_size */
+	"generator",				/* tp_name */
+	sizeof(PyGenObject),			/* tp_basicsize */
+	0,					/* tp_itemsize */
+	/* methods */
+	(destructor)gen_dealloc, 		/* tp_dealloc */
+	0,					/* tp_print */
+	0, 					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	0,					/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+ 	0,					/* tp_doc */
+ 	(traverseproc)gen_traverse,		/* tp_traverse */
+ 	0,					/* tp_clear */
+	0,					/* tp_richcompare */
+	offsetof(PyGenObject, gi_weakreflist),	/* tp_weaklistoffset */
+	PyObject_SelfIter,			/* tp_iter */
+	(iternextfunc)gen_iternext,		/* tp_iternext */
+	gen_methods,				/* tp_methods */
+	gen_memberlist,				/* tp_members */
+	0,					/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	0,					/* tp_init */
+	0,					/* tp_alloc */
+	0,					/* tp_new */
+	0,					/* tp_free */
+	0,					/* tp_is_gc */
+	0,					/* tp_bases */
+	0,					/* tp_mro */
+	0,					/* tp_cache */
+	0,					/* tp_subclasses */
+	0,					/* tp_weaklist */
+	gen_del,				/* tp_del */
+};
+
+PyObject *
+PyGen_New(PyFrameObject *f)
+{
+	PyGenObject *gen = PyObject_GC_New(PyGenObject, &PyGen_Type);
+	if (gen == NULL) {
+		Py_DECREF(f);
+		return NULL;
+	}
+	gen->gi_frame = f;
+	gen->gi_running = 0;
+	gen->gi_weakreflist = NULL;
+	_PyObject_GC_TRACK(gen);
+	return (PyObject *)gen;
+}
+
+int
+PyGen_NeedsFinalizing(PyGenObject *gen)
+{
+	int i;
+	PyFrameObject *f = gen->gi_frame;
+
+	if (f == NULL || f->f_stacktop == NULL || f->f_iblock <= 0)
+		return 0; /* no frame or empty blockstack == no finalization */
+
+	/* Any block type besides a loop requires cleanup. */
+	i = f->f_iblock;
+	while (--i >= 0) {
+		if (f->f_blockstack[i].b_type != SETUP_LOOP)
+			return 1;
+	}
+
+	/* No blocks except loops, it's safe to skip finalization. */
+	return 0;
+}

Added: vendor/Python/current/Objects/intobject.c
===================================================================
--- vendor/Python/current/Objects/intobject.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Objects/intobject.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1280 @@
+
+/* Integer object implementation */
+
+#include "Python.h"
+#include <ctype.h>
+
+long
+PyInt_GetMax(void)
+{
+	return LONG_MAX;	/* To initialize sys.maxint */
+}
+
+/* Integers are quite normal objects, to make object handling uniform.
+   (Using odd pointers to represent integers would save much space
+   but require extra checks for this special case throughout the code.)
+   Since a typical Python program spends much of its time allocating
+   and deallocating integers, these operations should be very fast.
+   Therefore we use a dedicated allocation scheme with a much lower
+   overhead (in space and time) than straight malloc(): a simple
+   dedicated free list, filled when necessary with memory from malloc().
+
+   block_list is a singly-linked list of all PyIntBlocks ever allocated,
+   linked via their next members.  PyIntBlocks are never returned to the
+   system before shutdown (PyInt_Fini).
+
+   free_list is a singly-linked list of available PyIntObjects, linked
+   via abuse of their ob_type members.
+*/
+
+#define BLOCK_SIZE	1000	/* 1K less typical malloc overhead */
+#define BHEAD_SIZE	8	/* Enough for a 64-bit pointer */
+#define N_INTOBJECTS	((BLOCK_SIZE - BHEAD_SIZE) / sizeof(PyIntObject))
+
+struct _intblock {
+	struct _intblock *next;
+	PyIntObject objects[N_INTOBJECTS];
+};
+
+typedef struct _intblock PyIntBlock;
+
+static PyIntBlock *block_list = NULL;
+static PyIntObject *free_list = NULL;
+
+static PyIntObject *
+fill_free_list(void)
+{
+	PyIntObject *p, *q;
+	/* Python's object allocator isn't appropriate for large blocks. */
+	p = (PyIntObject *) PyMem_MALLOC(sizeof(PyIntBlock));
+	if (p == NULL)
+		return (PyIntObject *) PyErr_NoMemory();
+	((PyIntBlock *)p)->next = block_list;
+	block_list = (PyIntBlock *)p;
+	/* Link the int objects together, from rear to front, then return
+	   the address of the last int object in the block. */
+	p = &((PyIntBlock *)p)->objects[0];
+	q = p + N_INTOBJECTS;
+	while (--q > p)
+		q->ob_type = (struct _typeobject *)(q-1);
+	q->ob_type = NULL;
+	return p + N_INTOBJECTS - 1;
+}
+
+#ifndef NSMALLPOSINTS
+#define NSMALLPOSINTS		257
+#endif
+#ifndef NSMALLNEGINTS
+#define NSMALLNEGINTS		5
+#endif
+#if NSMALLNEGINTS + NSMALLPOSINTS > 0
+/* References to small integers are saved in this array so that they
+   can be shared.
+   The integers that are saved are those in the range
+   -NSMALLNEGINTS (inclusive) to NSMALLPOSINTS (not inclusive).
+*/
+static PyIntObject *small_ints[NSMALLNEGINTS + NSMALLPOSINTS];
+#endif
+#ifdef COUNT_ALLOCS
+int quick_int_allocs, quick_neg_int_allocs;
+#endif
+
+PyObject *
+PyInt_FromLong(long ival)
+{
+	register PyIntObject *v;
+#if NSMALLNEGINTS + NSMALLPOSINTS > 0
+	if (-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS) {
+		v = small_ints[ival + NSMALLNEGINTS];
+		Py_INCREF(v);
+#ifdef COUNT_ALLOCS
+		if (ival >= 0)
+			quick_int_allocs++;
+		else
+			quick_neg_int_allocs++;
+#endif
+		return (PyObject *) v;
+	}
+#endif
+	if (free_list == NULL) {
+		if ((free_list = fill_free_list()) == NULL)
+			return NULL;
+	}
+	/* Inline PyObject_New */
+	v = free_list;
+	free_list = (PyIntObject *)v->ob_type;
+	PyObject_INIT(v, &PyInt_Type);
+	v->ob_ival = ival;
+	return (PyObject *) v;
+}
+
+PyObject *
+PyInt_FromSize_t(size_t ival)
+{
+	if (ival <= LONG_MAX)
+		return PyInt_FromLong((long)ival);
+	return _PyLong_FromSize_t(ival);
+}
+
+PyObject *
+PyInt_FromSsize_t(Py_ssize_t ival)
+{
+	if (ival >= LONG_MIN && ival <= LONG_MAX)
+		return PyInt_FromLong((long)ival);
+	return _PyLong_FromSsize_t(ival);
+}
+
+static void
+int_dealloc(PyIntObject *v)
+{
+	if (PyInt_CheckExact(v)) {
+		v->ob_type = (struct _typeobject *)free_list;
+		free_list = v;
+	}
+	else
+		v->ob_type->tp_free((PyObject *)v);
+}
+
+static void
+int_free(PyIntObject *v)
+{
+	v->ob_type = (struct _typeobject *)free_list;
+	free_list = v;
+}
+
+long
+PyInt_AsLong(register PyObject *op)
+{
+	PyNumberMethods *nb;
+	PyIntObject *io;
+	long val;
+
+	if (op && PyInt_Check(op))
+		return PyInt_AS_LONG((PyIntObject*) op);
+
+	if (op == NULL || (nb = op->ob_type->tp_as_number) == NULL ||
+	    nb->nb_int == NULL) {
+		PyErr_SetString(PyExc_TypeError, "an integer is required");
+		return -1;
+	}
+
+	io = (PyIntObject*) (*nb->nb_int) (op);
+	if (io == NULL)
+		return -1;
+	if (!PyInt_Check(io)) {
+		if (PyLong_Check(io)) {
+			/* got a long? => retry int conversion */
+			val = PyLong_AsLong((PyObject *)io);
+			Py_DECREF(io);
+			if ((val == -1) && PyErr_Occurred())
+				return -1;
+			return val;
+		}
+		else
+		{
+			Py_DECREF(io);
+			PyErr_SetString(PyExc_TypeError,
+					"nb_int should return int object");
+			return -1;
+		}
+	}
+
+	val = PyInt_AS_LONG(io);
+	Py_DECREF(io);
+
+	return val;
+}
+
+Py_ssize_t
+PyInt_AsSsize_t(register PyObject *op)
+{
+#if SIZEOF_SIZE_T != SIZEOF_LONG
+	PyNumberMethods *nb;
+	PyIntObject *io;
+	Py_ssize_t val;
+#endif
+
+	if (op == NULL) {
+		PyErr_SetString(PyExc_TypeError, "an integer is required");
+		return -1;
+	}
+
+	if (PyInt_Check(op))
+		return PyInt_AS_LONG((PyIntObject*) op);
+	if (PyLong_Check(op))
+		return _PyLong_AsSsize_t(op);
+#if SIZEOF_SIZE_T == SIZEOF_LONG
+	return PyInt_AsLong(op);
+#else
+
+	if ((nb = op->ob_type->tp_as_number) == NULL ||
+	    (nb->nb_int == NULL && nb->nb_long == 0)) {
+		PyErr_SetString(PyExc_TypeError, "an integer is required");
+		return -1;
+	}
+
+	if (nb->nb_long != 0) {
+		io = (PyIntObject*) (*nb->nb_long) (op);
+	} else {
+		io = (PyIntObject*) (*nb->nb_int) (op);
+	}
+	if (io == NULL)
+		return -1;
+	if (!PyInt_Check(io)) {
+		if (PyLong_Check(io)) {
+			/* got a long? => retry int conversion */
+			val = _PyLong_AsSsize_t((PyObject *)io);
+			Py_DECREF(io);
+			if ((val == -1) && PyErr_Occurred())
+				return -1;
+			return val;
+		}
+		else
+		{
+			Py_DECREF(io);
+			PyErr_SetString(PyExc_TypeError,
+					"nb_int should return int object");
+			return -1;
+		}
+	}
+
+	val = PyInt_AS_LONG(io);
+	Py_DECREF(io);
+
+	return val;
+#endif
+}
+
+unsigned long
+PyInt_AsUnsignedLongMask(register PyObject *op)
+{
+	PyNumberMethods *nb;
+	PyIntObject *io;
+	unsigned long val;
+
+	if (op && PyInt_Check(op))
+		return PyInt_AS_LONG((PyIntObject*) op);
+	if (op && PyLong_Check(op))
+		return PyLong_AsUnsignedLongMask(op);
+
+	if (op == NULL || (nb = op->ob_type->tp_as_number) == NULL ||
+	    nb->nb_int == NULL) {
+		PyErr_SetString(PyExc_TypeError, "an integer is required");
+		return (unsigned long)-1;
+	}
+
+	io = (PyIntObject*) (*nb->nb_int) (op);
+	if (io == NULL)
+		return (unsigned long)-1;
+	if (!PyInt_Check(io)) {
+		if (PyLong_Check(io)) {
+			val = PyLong_AsUnsignedLongMask((PyObject *)io);
+			Py_DECREF(io);
+			if (PyErr_Occurred())
+				return (unsigned long)-1;
+			return val;
+		}
+		else
+		{
+			Py_DECREF(io);
+			PyErr_SetString(PyExc_TypeError,
+					"nb_int should return int object");
+			return (unsigned long)-1;
+		}
+	}
+
+	val = PyInt_AS_LONG(io);
+	Py_DECREF(io);
+
+	return val;
+}
+
+#ifdef HAVE_LONG_LONG
+unsigned PY_LONG_LONG
+PyInt_AsUnsignedLongLongMask(register PyObject *op)
+{
+	PyNumberMethods *nb;
+	PyIntObject *io;
+	unsigned PY_LONG_LONG val;
+
+	if (op && PyInt_Check(op))
+		return PyInt_AS_LONG((PyIntObject*) op);
+	if (op && PyLong_Check(op))
+		return PyLong_AsUnsignedLongLongMask(op);
+
+	if (op == NULL || (nb = op->ob_type->tp_as_number) == NULL ||
+	    nb->nb_int == NULL) {
+		PyErr_SetString(PyExc_TypeError, "an integer is required");
+		return (unsigned PY_LONG_LONG)-1;
+	}
+
+	io = (PyIntObject*) (*nb->nb_int) (op);
+	if (io == NULL)
+		return (unsigned PY_LONG_LONG)-1;
+	if (!PyInt_Check(io)) {
+		if (PyLong_Check(io)) {
+			val = PyLong_AsUnsignedLongLongMask((PyObject *)io);
+			Py_DECREF(io);
+			if (PyErr_Occurred())
+				return (unsigned PY_LONG_LONG)-1;
+			return val;
+		}
+		else
+		{
+			Py_DECREF(io);
+			PyErr_SetString(PyExc_TypeError,
+					"nb_int should return int object");
+			return (unsigned PY_LONG_LONG)-1;
+		}
+	}
+
+	val = PyInt_AS_LONG(io);
+	Py_DECREF(io);
+
+	return val;
+}
+#endif
+
+PyObject *
+PyInt_FromString(char *s, char **pend, int base)
+{
+	char *end;
+	long x;
+	Py_ssize_t slen;
+	PyObject *sobj, *srepr;
+
+	if ((base != 0 && base < 2) || base > 36) {
+		PyErr_SetString(PyExc_ValueError,
+				"int() base must be >= 2 and <= 36");
+		return NULL;
+	}
+
+	while (*s && isspace(Py_CHARMASK(*s)))
+		s++;
+	errno = 0;
+	if (base == 0 && s[0] == '0') {
+		x = (long) PyOS_strtoul(s, &end, base);
+		if (x < 0)
+			return PyLong_FromString(s, pend, base);
+	}
+	else
+		x = PyOS_strtol(s, &end, base);
+	if (end == s || !isalnum(Py_CHARMASK(end[-1])))
+		goto bad;
+	while (*end && isspace(Py_CHARMASK(*end)))
+		end++;
+	if (*end != '\0') {
+  bad:
+		slen = strlen(s) < 200 ? strlen(s) : 200;
+		sobj = PyString_FromStringAndSize(s, slen);
+		if (sobj == NULL)
+			return NULL;
+		srepr = PyObject_Repr(sobj);
+		Py_DECREF(sobj);
+		if (srepr == NULL)
+			return NULL;
+		PyErr_Format(PyExc_ValueError,
+			     "invalid literal for int() with base %d: %s",
+			     base, PyString_AS_STRING(srepr));
+		Py_DECREF(srepr);
+		return NULL;
+	}
+	else if (errno != 0)
+		return PyLong_FromString(s, pend, base);
+	if (pend)
+		*pend = end;
+	return PyInt_FromLong(x);
+}
+
+#ifdef Py_USING_UNICODE
+PyObject *
+PyInt_FromUnicode(Py_UNICODE *s, Py_ssize_t length, int base)
+{
+	PyObject *result;
+	char *buffer = (char *)PyMem_MALLOC(length+1);
+
+	if (buffer == NULL)
+		return NULL;
+
+	if (PyUnicode_EncodeDecimal(s, length, buffer, NULL)) {
+		PyMem_FREE(buffer);
+		return NULL;
+	}
+	result = PyInt_FromString(buffer, NULL, base);
+	PyMem_FREE(buffer);
+	return result;
+}
+#endif
+
+/* Methods */
+
+/* Integers are seen as the "smallest" of all numeric types and thus
+   don't have any knowledge about conversion of other types to
+   integers. */
+
+#define CONVERT_TO_LONG(obj, lng)		\
+	if (PyInt_Check(obj)) {			\
+		lng = PyInt_AS_LONG(obj);	\
+	}					\
+	else {					\
+		Py_INCREF(Py_NotImplemented);	\
+		return Py_NotImplemented;	\
+	}
+
+/* ARGSUSED */
+static int
+int_print(PyIntObject *v, FILE *fp, int flags)
+     /* flags -- not used but required by interface */
+{
+	fprintf(fp, "%ld", v->ob_ival);
+	return 0;
+}
+
+static PyObject *
+int_repr(PyIntObject *v)
+{
+	char buf[64];
+	PyOS_snprintf(buf, sizeof(buf), "%ld", v->ob_ival);
+	return PyString_FromString(buf);
+}
+
+static int
+int_compare(PyIntObject *v, PyIntObject *w)
+{
+	register long i = v->ob_ival;
+	register long j = w->ob_ival;
+	return (i < j) ? -1 : (i > j) ? 1 : 0;
+}
+
+static long
+int_hash(PyIntObject *v)
+{
+	/* XXX If this is changed, you also need to change the way
+	   Python's long, float and complex types are hashed. */
+	long x = v -> ob_ival;
+	if (x == -1)
+		x = -2;
+	return x;
+}
+
+static PyObject *
+int_add(PyIntObject *v, PyIntObject *w)
+{
+	register long a, b, x;
+	CONVERT_TO_LONG(v, a);
+	CONVERT_TO_LONG(w, b);
+	x = a + b;
+	if ((x^a) >= 0 || (x^b) >= 0)
+		return PyInt_FromLong(x);
+	return PyLong_Type.tp_as_number->nb_add((PyObject *)v, (PyObject *)w);
+}
+
+static PyObject *
+int_sub(PyIntObject *v, PyIntObject *w)
+{
+	register long a, b, x;
+	CONVERT_TO_LONG(v, a);
+	CONVERT_TO_LONG(w, b);
+	x = a - b;
+	if ((x^a) >= 0 || (x^~b) >= 0)
+		return PyInt_FromLong(x);
+	return PyLong_Type.tp_as_number->nb_subtract((PyObject *)v,
+						     (PyObject *)w);
+}
+
+/*
+Integer overflow checking for * is painful:  Python tried a couple ways, but
+they didn't work on all platforms, or failed in endcases (a product of
+-sys.maxint-1 has been a particular pain).
+
+Here's another way:
+
+The native long product x*y is either exactly right or *way* off, being
+just the last n bits of the true product, where n is the number of bits
+in a long (the delivered product is the true product plus i*2**n for
+some integer i).
+
+The native double product (double)x * (double)y is subject to three
+rounding errors:  on a sizeof(long)==8 box, each cast to double can lose
+info, and even on a sizeof(long)==4 box, the multiplication can lose info.
+But, unlike the native long product, it's not in *range* trouble:  even
+if sizeof(long)==32 (256-bit longs), the product easily fits in the
+dynamic range of a double.  So the leading 50 (or so) bits of the double
+product are correct.
+
+We check these two ways against each other, and declare victory if they're
+approximately the same.  Else, because the native long product is the only
+one that can lose catastrophic amounts of information, it's the native long
+product that must have overflowed.
+*/
+
+static PyObject *
+int_mul(PyObject *v, PyObject *w)
+{
+	long a, b;
+	long longprod;			/* a*b in native long arithmetic */
+	double doubled_longprod;	/* (double)longprod */
+	double doubleprod;		/* (double)a * (double)b */
+
+	CONVERT_TO_LONG(v, a);
+	CONVERT_TO_LONG(w, b);
+	longprod = a * b;
+	doubleprod = (double)a * (double)b;
+	doubled_longprod = (double)longprod;
+
+	/* Fast path for normal case:  small multiplicands, and no info
+	   is lost in either method. */
+	if (doubled_longprod == doubleprod)
+		return PyInt_FromLong(longprod);
+
+	/* Somebody somewhere lost info.  Close enough, or way off?  Note
+	   that a != 0 and b != 0 (else doubled_longprod == doubleprod == 0).
+	   The difference either is or isn't significant compared to the
+	   true value (of which doubleprod is a good approximation).
+	*/
+	{
+		const double diff = doubled_longprod - doubleprod;
+		const double absdiff = diff >= 0.0 ? diff : -diff;
+		const double absprod = doubleprod >= 0.0 ? doubleprod :
+							  -doubleprod;
+		/* absdiff/absprod <= 1/32 iff
+		   32 * absdiff <= absprod -- 5 good bits is "close enough" */
+		if (32.0 * absdiff <= absprod)
+			return PyInt_FromLong(longprod);
+		else
+			return PyLong_Type.tp_as_number->nb_multiply(v, w);
+	}
+}
+
+/* Integer overflow checking for unary negation: on a 2's-complement
+ * box, -x overflows iff x is the most negative long.  In this case we
+ * get -x == x.  However, -x is undefined (by C) if x /is/ the most
+ * negative long (it's a signed overflow case), and some compilers care.
+ * So we cast x to unsigned long first.  However, then other compilers
+ * warn about applying unary minus to an unsigned operand.  Hence the
+ * weird "0-".
+ */
+#define UNARY_NEG_WOULD_OVERFLOW(x)	\
+	((x) < 0 && (unsigned long)(x) == 0-(unsigned long)(x))
+
+/* Return type of i_divmod */
+enum divmod_result {
+	DIVMOD_OK,		/* Correct result */
+	DIVMOD_OVERFLOW,	/* Overflow, try again using longs */
+	DIVMOD_ERROR		/* Exception raised */
+};
+
+static enum divmod_result
+i_divmod(register long x, register long y,
+         long *p_xdivy, long *p_xmody)
+{
+	long xdivy, xmody;
+
+	if (y == 0) {
+		PyErr_SetString(PyExc_ZeroDivisionError,
+				"integer division or modulo by zero");
+		return DIVMOD_ERROR;
+	}
+	/* (-sys.maxint-1)/-1 is the only overflow case. */
+	if (y == -1 && UNARY_NEG_WOULD_OVERFLOW(x))
+		return DIVMOD_OVERFLOW;
+	xdivy = x / y;
+	xmody = x - xdivy * y;
+	/* If the signs of x and y differ, and the remainder is non-0,
+	 * C89 doesn't define whether xdivy is now the floor or the
+	 * ceiling of the infinitely precise quotient.  We want the floor,
+	 * and we have it iff the remainder's sign matches y's.
+	 */
+	if (xmody && ((y ^ xmody) < 0) /* i.e. and signs differ */) {
+		xmody += y;
+		--xdivy;
+		assert(xmody && ((y ^ xmody) >= 0));
+	}
+	*p_xdivy = xdivy;
+	*p_xmody = xmody;
+	return DIVMOD_OK;
+}
+
+static PyObject *
+int_div(PyIntObject *x, PyIntObject *y)
+{
+	long xi, yi;
+	long d, m;
+	CONVERT_TO_LONG(x, xi);
+	CONVERT_TO_LONG(y, yi);
+	switch (i_divmod(xi, yi, &d, &m)) {
+	case DIVMOD_OK:
+		return PyInt_FromLong(d);
+	case DIVMOD_OVERFLOW:
+		return PyLong_Type.tp_as_number->nb_divide((PyObject *)x,
+							   (PyObject *)y);
+	default:
+		return NULL;
+	}
+}
+
+static PyObject *
+int_classic_div(PyIntObject *x, PyIntObject *y)
+{
+	long xi, yi;
+	long d, m;
+	CONVERT_TO_LONG(x, xi);
+	CONVERT_TO_LONG(y, yi);
+	if (Py_DivisionWarningFlag &&
+	    PyErr_Warn(PyExc_DeprecationWarning, "classic int division") < 0)
+		return NULL;
+	switch (i_divmod(xi, yi, &d, &m)) {
+	case DIVMOD_OK:
+		return PyInt_FromLong(d);
+	case DIVMOD_OVERFLOW:
+		return PyLong_Type.tp_as_number->nb_divide((PyObject *)x,
+							   (PyObject *)y);
+	default:
+		return NULL;
+	}
+}
+
+static PyObject *
+int_true_divide(PyObject *v, PyObject *w)
+{
+	/* If they aren't both ints, give someone else a chance.  In
+	   particular, this lets int/long get handled by longs, which
+	   underflows to 0 gracefully if the long is too big to convert
+	   to float. */
+	if (PyInt_Check(v) && PyInt_Check(w))
+		return PyFloat_Type.tp_as_number->nb_true_divide(v, w);
+	Py_INCREF(Py_NotImplemented);
+	return Py_NotImplemented;
+}
+
+static PyObject *
+int_mod(PyIntObject *x, PyIntObject *y)
+{
+	long xi, yi;
+	long d, m;
+	CONVERT_TO_LONG(x, xi);
+	CONVERT_TO_LONG(y, yi);
+	switch (i_divmod(xi, yi, &d, &m)) {
+	case DIVMOD_OK:
+		return PyInt_FromLong(m);
+	case DIVMOD_OVERFLOW:
+		return PyLong_Type.tp_as_number->nb_remainder((PyObject *)x,
+							      (PyObject *)y);
+	default:
+		return NULL;
+	}
+}
+
+static PyObject *
+int_divmod(PyIntObject *x, PyIntObject *y)
+{
+	long xi, yi;
+	long d, m;
+	CONVERT_TO_LONG(x, xi);
+	CONVERT_TO_LONG(y, yi);
+	switch (i_divmod(xi, yi, &d, &m)) {
+	case DIVMOD_OK:
+		return Py_BuildValue("(ll)", d, m);
+	case DIVMOD_OVERFLOW:
+		return PyLong_Type.tp_as_number->nb_divmod((PyObject *)x,
+							   (PyObject *)y);
+	default:
+		return NULL;
+	}
+}
+
+static PyObject *
+int_pow(PyIntObject *v, PyIntObject *w, PyIntObject *z)
+{
+	register long iv, iw, iz=0, ix, temp, prev;
+	CONVERT_TO_LONG(v, iv);
+	CONVERT_TO_LONG(w, iw);
+	if (iw < 0) {
+		if ((PyObject *)z != Py_None) {
+			PyErr_SetString(PyExc_TypeError, "pow() 2nd argument "
+			     "cannot be negative when 3rd argument specified");
+			return NULL;
+		}
+		/* Return a float.  This works because we know that
+		   this calls float_pow() which converts its
+		   arguments to double. */
+		return PyFloat_Type.tp_as_number->nb_power(
+			(PyObject *)v, (PyObject *)w, (PyObject *)z);
+	}
+ 	if ((PyObject *)z != Py_None) {
+		CONVERT_TO_LONG(z, iz);
+		if (iz == 0) {
+			PyErr_SetString(PyExc_ValueError,
+					"pow() 3rd argument cannot be 0");
+			return NULL;
+		}
+	}
+	/*
+	 * XXX: The original exponentiation code stopped looping
+	 * when temp hit zero; this code will continue onwards
+	 * unnecessarily, but at least it won't cause any errors.
+	 * Hopefully the speed improvement from the fast exponentiation
+	 * will compensate for the slight inefficiency.
+	 * XXX: Better handling of overflows is desperately needed.
+	 */
+ 	temp = iv;
+	ix = 1;
+	while (iw > 0) {
+	 	prev = ix;	/* Save value for overflow check */
+	 	if (iw & 1) {
+		 	ix = ix*temp;
+			if (temp == 0)
+				break; /* Avoid ix / 0 */
+			if (ix / temp != prev) {
+				return PyLong_Type.tp_as_number->nb_power(
+					(PyObject *)v,
+					(PyObject *)w,
+					(PyObject *)z);
+			}
+		}
+	 	iw >>= 1;	/* Shift exponent down by 1 bit */
+	        if (iw==0) break;
+	 	prev = temp;
+	 	temp *= temp;	/* Square the value of temp */
+	 	if (prev != 0 && temp / prev != prev) {
+			return PyLong_Type.tp_as_number->nb_power(
+				(PyObject *)v, (PyObject *)w, (PyObject *)z);
+		}
+	 	if (iz) {
+			/* If we did a multiplication, perform a modulo */
+		 	ix = ix % iz;
+		 	temp = temp % iz;
+		}
+	}
+	if (iz) {
+	 	long div, mod;
+		switch (i_divmod(ix, iz, &div, &mod)) {
+		case DIVMOD_OK:
+			ix = mod;
+			break;
+		case DIVMOD_OVERFLOW:
+			return PyLong_Type.tp_as_number->nb_power(
+				(PyObject *)v, (PyObject *)w, (PyObject *)z);
+		default:
+			return NULL;
+		}
+	}
+	return PyInt_FromLong(ix);
+}
+
+static PyObject *
+int_neg(PyIntObject *v)
+{
+	register long a;
+	a = v->ob_ival;
+        /* check for overflow */
+	if (UNARY_NEG_WOULD_OVERFLOW(a)) {
+		PyObject *o = PyLong_FromLong(a);
+		if (o != NULL) {
+			PyObject *result = PyNumber_Negative(o);
+			Py_DECREF(o);
+			return result;
+		}
+		return NULL;
+	}
+	return PyInt_FromLong(-a);
+}
+
+static PyObject *
+int_pos(PyIntObject *v)
+{
+	if (PyInt_CheckExact(v)) {
+		Py_INCREF(v);
+		return (PyObject *)v;
+	}
+	else
+		return PyInt_FromLong(v->ob_ival);
+}
+
+static PyObject *
+int_abs(PyIntObject *v)
+{
+	if (v->ob_ival >= 0)
+		return int_pos(v);
+	else
+		return int_neg(v);
+}
+
+static int
+int_nonzero(PyIntObject *v)
+{
+	return v->ob_ival != 0;
+}
+
+static PyObject *
+int_invert(PyIntObject *v)
+{
+	return PyInt_FromLong(~v->ob_ival);
+}
+
+static PyObject *
+int_lshift(PyIntObject *v, PyIntObject *w)
+{
+	long a, b, c;
+	PyObject *vv, *ww, *result;
+
+	CONVERT_TO_LONG(v, a);
+	CONVERT_TO_LONG(w, b);
+	if (b < 0) {
+		PyErr_SetString(PyExc_ValueError, "negative shift count");
+		return NULL;
+	}
+	if (a == 0 || b == 0)
+		return int_pos(v);
+	if (b >= LONG_BIT) {
+		vv = PyLong_FromLong(PyInt_AS_LONG(v));
+		if (vv == NULL)
+			return NULL;
+		ww = PyLong_FromLong(PyInt_AS_LONG(w));
+		if (ww == NULL) {
+			Py_DECREF(vv);
+			return NULL;
+		}
+		result = PyNumber_Lshift(vv, ww);
+		Py_DECREF(vv);
+		Py_DECREF(ww);
+		return result;
+	}
+	c = a << b;
+	if (a != Py_ARITHMETIC_RIGHT_SHIFT(long, c, b)) {
+		vv = PyLong_FromLong(PyInt_AS_LONG(v));
+		if (vv == NULL)
+			return NULL;
+		ww = PyLong_FromLong(PyInt_AS_LONG(w));
+		if (ww == NULL) {
+			Py_DECREF(vv);
+			return NULL;
+		}
+		result = PyNumber_Lshift(vv, ww);
+		Py_DECREF(vv);
+		Py_DECREF(ww);
+		return result;
+	}
+	return PyInt_FromLong(c);
+}
+
+static PyObject *
+int_rshift(PyIntObject *v, PyIntObject *w)
+{
+	register long a, b;
+	CONVERT_TO_LONG(v, a);
+	CONVERT_TO_LONG(w, b);
+	if (b < 0) {
+		PyErr_SetString(PyExc_ValueError, "negative shift count");
+		return NULL;
+	}
+	if (a == 0 || b == 0)
+		return int_pos(v);
+	if (b >= LONG_BIT) {
+		if (a < 0)
+			a = -1;
+		else
+			a = 0;
+	}
+	else {
+		a = Py_ARITHMETIC_RIGHT_SHIFT(long, a, b);
+	}
+	return PyInt_FromLong(a);
+}
+
+static PyObject *
+int_and(PyIntObject *v, PyIntObject *w)
+{
+	register long a, b;
+	CONVERT_TO_LONG(v, a);
+	CONVERT_TO_LONG(w, b);
+	return PyInt_FromLong(a & b);
+}
+
+static PyObject *
+int_xor(PyIntObject *v, PyIntObject *w)
+{
+	register long a, b;
+	CONVERT_TO_LONG(v, a);
+	CONVERT_TO_LONG(w, b);
+	return PyInt_FromLong(a ^ b);
+}
+
+static PyObject *
+int_or(PyIntObject *v, PyIntObject *w)
+{
+	register long a, b;
+	CONVERT_TO_LONG(v, a);
+	CONVERT_TO_LONG(w, b);
+	return PyInt_FromLong(a | b);
+}
+
+static int
+int_coerce(PyObject **pv, PyObject **pw)
+{
+	if (PyInt_Check(*pw)) {
+		Py_INCREF(*pv);
+		Py_INCREF(*pw);
+		return 0;
+	}
+	return 1; /* Can't do it */
+}
+
+static PyObject *
+int_int(PyIntObject *v)
+{
+	if (PyInt_CheckExact(v))
+		Py_INCREF(v);
+	else
+		v = (PyIntObject *)PyInt_FromLong(v->ob_ival);
+	return (PyObject *)v;
+}
+
+static PyObject *
+int_long(PyIntObject *v)
+{
+	return PyLong_FromLong((v -> ob_ival));
+}
+
+static PyObject *
+int_float(PyIntObject *v)
+{
+	return PyFloat_FromDouble((double)(v -> ob_ival));
+}
+
+static PyObject *
+int_oct(PyIntObject *v)
+{
+	char buf[100];
+	long x = v -> ob_ival;
+	if (x < 0)
+		PyOS_snprintf(buf, sizeof(buf), "-0%lo", -x);
+	else if (x == 0)
+		strcpy(buf, "0");
+	else
+		PyOS_snprintf(buf, sizeof(buf), "0%lo", x);
+	return PyString_FromString(buf);
+}
+
+static PyObject *
+int_hex(PyIntObject *v)
+{
+	char buf[100];
+	long x = v -> ob_ival;
+	if (x < 0)
+		PyOS_snprintf(buf, sizeof(buf), "-0x%lx", -x);
+	else
+		PyOS_snprintf(buf, sizeof(buf), "0x%lx", x);
+	return PyString_FromString(buf);
+}
+
+static PyObject *
+int_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
+
+static PyObject *
+int_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	PyObject *x = NULL;
+	int base = -909;
+	static char *kwlist[] = {"x", "base", 0};
+
+	if (type != &PyInt_Type)
+		return int_subtype_new(type, args, kwds); /* Wimp out */
+	if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:int", kwlist,
+					 &x, &base))
+		return NULL;
+	if (x == NULL)
+		return PyInt_FromLong(0L);
+	if (base == -909)
+		return PyNumber_Int(x);
+	if (PyString_Check(x)) {
+		/* Since PyInt_FromString doesn't have a length parameter,
+		 * check here for possible NULs in the string. */
+		char *string = PyString_AS_STRING(x);
+		if (strlen(string) != PyString_Size(x)) {
+			/* create a repr() of the input string,
+			 * just like PyInt_FromString does */
+			PyObject *srepr;
+			srepr = PyObject_Repr(x);
+			if (srepr == NULL)
+				return NULL;
+			PyErr_Format(PyExc_ValueError,
+			     "invalid literal for int() with base %d: %s",
+			     base, PyString_AS_STRING(srepr));
+			Py_DECREF(srepr);
+			return NULL;
+		}
+		return PyInt_FromString(string, NULL, base);
+	}
+#ifdef Py_USING_UNICODE
+	if (PyUnicode_Check(x))
+		return PyInt_FromUnicode(PyUnicode_AS_UNICODE(x),
+					 PyUnicode_GET_SIZE(x),
+					 base);
+#endif
+	PyErr_SetString(PyExc_TypeError,
+			"int() can't convert non-string with explicit base");
+	return NULL;
+}
+
+/* Wimpy, slow approach to tp_new calls for subtypes of int:
+   first create a regular int from whatever arguments we got,
+   then allocate a subtype instance and initialize its ob_ival
+   from the regular int.  The regular int is then thrown away.
+*/
+static PyObject *
+int_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	PyObject *tmp, *newobj;
+	long ival;
+
+	assert(PyType_IsSubtype(type, &PyInt_Type));
+	tmp = int_new(&PyInt_Type, args, kwds);
+	if (tmp == NULL)
+		return NULL;
+	if (!PyInt_Check(tmp)) {
+		ival = PyLong_AsLong(tmp);
+		if (ival == -1 && PyErr_Occurred()) {
+			Py_DECREF(tmp);
+			return NULL;
+		}
+	} else {
+		ival = ((PyIntObject *)tmp)->ob_ival;
+	}
+
+	newobj = type->tp_alloc(type, 0);
+	if (newobj == NULL) {
+		Py_DECREF(tmp);
+		return NULL;
+	}
+	((PyIntObject *)newobj)->ob_ival = ival;
+	Py_DECREF(tmp);
+	return newobj;
+}
+
+static PyObject *
+int_getnewargs(PyIntObject *v)
+{
+	return Py_BuildValue("(l)", v->ob_ival);
+}
+
+static PyMethodDef int_methods[] = {
+	{"__getnewargs__",	(PyCFunction)int_getnewargs,	METH_NOARGS},
+	{NULL,		NULL}		/* sentinel */
+};
+
+PyDoc_STRVAR(int_doc,
+"int(x[, base]) -> integer\n\
+\n\
+Convert a string or number to an integer, if possible.  A floating point\n\
+argument will be truncated towards zero (this does not include a string\n\
+representation of a floating point number!)  When converting a string, use\n\
+the optional base.  It is an error to supply a base when converting a\n\
+non-string. If the argument is outside the integer range a long object\n\
+will be returned instead.");
+
+static PyNumberMethods int_as_number = {
+	(binaryfunc)int_add,	/*nb_add*/
+	(binaryfunc)int_sub,	/*nb_subtract*/
+	(binaryfunc)int_mul,	/*nb_multiply*/
+	(binaryfunc)int_classic_div, /*nb_divide*/
+	(binaryfunc)int_mod,	/*nb_remainder*/
+	(binaryfunc)int_divmod,	/*nb_divmod*/
+	(ternaryfunc)int_pow,	/*nb_power*/
+	(unaryfunc)int_neg,	/*nb_negative*/
+	(unaryfunc)int_pos,	/*nb_positive*/
+	(unaryfunc)int_abs,	/*nb_absolute*/
+	(inquiry)int_nonzero,	/*nb_nonzero*/
+	(unaryfunc)int_invert,	/*nb_invert*/
+	(binaryfunc)int_lshift,	/*nb_lshift*/
+	(binaryfunc)int_rshift,	/*nb_rshift*/
+	(binaryfunc)int_and,	/*nb_and*/
+	(binaryfunc)int_xor,	/*nb_xor*/
+	(binaryfunc)int_or,	/*nb_or*/
+	int_coerce,		/*nb_coerce*/
+	(unaryfunc)int_int,	/*nb_int*/
+	(unaryfunc)int_long,	/*nb_long*/
+	(unaryfunc)int_float,	/*nb_float*/
+	(unaryfunc)int_oct,	/*nb_oct*/
+	(unaryfunc)int_hex, 	/*nb_hex*/
+	0,			/*nb_inplace_add*/
+	0,			/*nb_inplace_subtract*/
+	0,			/*nb_inplace_multiply*/
+	0,			/*nb_inplace_divide*/
+	0,			/*nb_inplace_remainder*/
+	0,			/*nb_inplace_power*/
+	0,			/*nb_inplace_lshift*/
+	0,			/*nb_inplace_rshift*/
+	0,			/*nb_inplace_and*/
+	0,			/*nb_inplace_xor*/
+	0,			/*nb_inplace_or*/
+	(binaryfunc)int_div,	/* nb_floor_divide */
+	int_true_divide,	/* nb_true_divide */
+	0,			/* nb_inplace_floor_divide */
+	0,			/* nb_inplace_true_divide */
+	(unaryfunc)int_int,	/* nb_index */
+};
+
+PyTypeObject PyInt_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,
+	"int",
+	sizeof(PyIntObject),
+	0,
+	(destructor)int_dealloc,		/* tp_dealloc */
+	(printfunc)int_print,			/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	(cmpfunc)int_compare,			/* tp_compare */
+	(reprfunc)int_repr,			/* tp_repr */
+	&int_as_number,				/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	(hashfunc)int_hash,			/* tp_hash */
+        0,					/* tp_call */
+        (reprfunc)int_repr,			/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
+		Py_TPFLAGS_BASETYPE,		/* tp_flags */
+	int_doc,				/* tp_doc */
+	0,					/* tp_traverse */
+	0,					/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	int_methods,				/* tp_methods */
+	0,					/* tp_members */
+	0,					/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	0,					/* tp_init */
+	0,					/* tp_alloc */
+	int_new,				/* tp_new */
+	(freefunc)int_free,           		/* tp_free */
+};
+
+int
+_PyInt_Init(void)
+{
+	PyIntObject *v;
+	int ival;
+#if NSMALLNEGINTS + NSMALLPOSINTS > 0
+	for (ival = -NSMALLNEGINTS; ival < NSMALLPOSINTS; ival++) {
+              if (!free_list && (free_list = fill_free_list()) == NULL)
+			return 0;
+		/* PyObject_New is inlined */
+		v = free_list;
+		free_list = (PyIntObject *)v->ob_type;
+		PyObject_INIT(v, &PyInt_Type);
+		v->ob_ival = ival;
+		small_ints[ival + NSMALLNEGINTS] = v;
+	}
+#endif
+	return 1;
+}
+
+void
+PyInt_Fini(void)
+{
+	PyIntObject *p;
+	PyIntBlock *list, *next;
+	int i;
+	unsigned int ctr;
+	int bc, bf;	/* block count, number of freed blocks */
+	int irem, isum;	/* remaining unfreed ints per block, total */
+
+#if NSMALLNEGINTS + NSMALLPOSINTS > 0
+        PyIntObject **q;
+
+        i = NSMALLNEGINTS + NSMALLPOSINTS;
+        q = small_ints;
+        while (--i >= 0) {
+                Py_XDECREF(*q);
+                *q++ = NULL;
+        }
+#endif
+	bc = 0;
+	bf = 0;
+	isum = 0;
+	list = block_list;
+	block_list = NULL;
+	free_list = NULL;
+	while (list != NULL) {
+		bc++;
+		irem = 0;
+		for (ctr = 0, p = &list->objects[0];
+		     ctr < N_INTOBJECTS;
+		     ctr++, p++) {
+			if (PyInt_CheckExact(p) && p->ob_refcnt != 0)
+				irem++;
+		}
+		next = list->next;
+		if (irem) {
+			list->next = block_list;
+			block_list = list;
+			for (ctr = 0, p = &list->objects[0];
+			     ctr < N_INTOBJECTS;
+			     ctr++, p++) {
+				if (!PyInt_CheckExact(p) ||
+				    p->ob_refcnt == 0) {
+					p->ob_type = (struct _typeobject *)
+						free_list;
+					free_list = p;
+				}
+#if NSMALLNEGINTS + NSMALLPOSINTS > 0
+				else if (-NSMALLNEGINTS <= p->ob_ival &&
+					 p->ob_ival < NSMALLPOSINTS &&
+					 small_ints[p->ob_ival +
+						    NSMALLNEGINTS] == NULL) {
+					Py_INCREF(p);
+					small_ints[p->ob_ival +
+						   NSMALLNEGINTS] = p;
+				}
+#endif
+			}
+		}
+		else {
+			PyMem_FREE(list);
+			bf++;
+		}
+		isum += irem;
+		list = next;
+	}
+	if (!Py_VerboseFlag)
+		return;
+	fprintf(stderr, "# cleanup ints");
+	if (!isum) {
+		fprintf(stderr, "\n");
+	}
+	else {
+		fprintf(stderr,
+			": %d unfreed int%s in %d out of %d block%s\n",
+			isum, isum == 1 ? "" : "s",
+			bc - bf, bc, bc == 1 ? "" : "s");
+	}
+	if (Py_VerboseFlag > 1) {
+		list = block_list;
+		while (list != NULL) {
+			for (ctr = 0, p = &list->objects[0];
+			     ctr < N_INTOBJECTS;
+			     ctr++, p++) {
+				if (PyInt_CheckExact(p) && p->ob_refcnt != 0)
+					/* XXX(twouters) cast refcount to
+					   long until %zd is universally
+					   available
+					 */
+					fprintf(stderr,
+				"#   <int at %p, refcnt=%ld, val=%ld>\n",
+						p, (long)p->ob_refcnt,
+						p->ob_ival);
+			}
+			list = list->next;
+		}
+	}
+}

Added: vendor/Python/current/Objects/iterobject.c
===================================================================
--- vendor/Python/current/Objects/iterobject.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Objects/iterobject.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,232 @@
+/* Iterator objects */
+
+#include "Python.h"
+
+typedef struct {
+	PyObject_HEAD
+	long      it_index;
+	PyObject *it_seq; /* Set to NULL when iterator is exhausted */
+} seqiterobject;
+
+PyObject *
+PySeqIter_New(PyObject *seq)
+{
+	seqiterobject *it;
+
+	if (!PySequence_Check(seq)) {
+		PyErr_BadInternalCall();
+		return NULL;
+	}	
+	it = PyObject_GC_New(seqiterobject, &PySeqIter_Type);
+	if (it == NULL)
+		return NULL;
+	it->it_index = 0;
+	Py_INCREF(seq);
+	it->it_seq = seq;
+	_PyObject_GC_TRACK(it);
+	return (PyObject *)it;
+}
+
+static void
+iter_dealloc(seqiterobject *it)
+{
+	_PyObject_GC_UNTRACK(it);
+	Py_XDECREF(it->it_seq);
+	PyObject_GC_Del(it);
+}
+
+static int
+iter_traverse(seqiterobject *it, visitproc visit, void *arg)
+{
+	Py_VISIT(it->it_seq);
+	return 0;
+}
+
+static PyObject *
+iter_iternext(PyObject *iterator)
+{
+	seqiterobject *it;
+	PyObject *seq;
+	PyObject *result;
+
+	assert(PySeqIter_Check(iterator));
+	it = (seqiterobject *)iterator;
+	seq = it->it_seq;
+	if (seq == NULL)
+		return NULL;
+
+	result = PySequence_GetItem(seq, it->it_index);
+	if (result != NULL) {
+		it->it_index++;
+		return result;
+	}
+	if (PyErr_ExceptionMatches(PyExc_IndexError) ||
+	    PyErr_ExceptionMatches(PyExc_StopIteration))
+	{
+		PyErr_Clear();
+		Py_DECREF(seq);
+		it->it_seq = NULL;
+	}
+	return NULL;
+}
+
+static PyObject *
+iter_len(seqiterobject *it)
+{
+	Py_ssize_t seqsize, len;
+
+	if (it->it_seq) {
+		seqsize = PySequence_Size(it->it_seq);
+		if (seqsize == -1)
+			return NULL;
+		len = seqsize - it->it_index;
+		if (len >= 0)
+			return PyInt_FromSsize_t(len);
+	}
+	return PyInt_FromLong(0);
+}
+
+PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
+
+static PyMethodDef seqiter_methods[] = {
+	{"__length_hint__", (PyCFunction)iter_len, METH_NOARGS, length_hint_doc},
+ 	{NULL,		NULL}		/* sentinel */
+};
+
+PyTypeObject PySeqIter_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,					/* ob_size */
+	"iterator",				/* tp_name */
+	sizeof(seqiterobject),			/* tp_basicsize */
+	0,					/* tp_itemsize */
+	/* methods */
+	(destructor)iter_dealloc, 		/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	0,					/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+ 	0,					/* tp_doc */
+ 	(traverseproc)iter_traverse,		/* tp_traverse */
+ 	0,					/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	PyObject_SelfIter,			/* tp_iter */
+	iter_iternext,				/* tp_iternext */
+	seqiter_methods,			/* tp_methods */
+	0,					/* tp_members */
+};
+
+/* -------------------------------------- */
+
+typedef struct {
+	PyObject_HEAD
+	PyObject *it_callable; /* Set to NULL when iterator is exhausted */
+	PyObject *it_sentinel; /* Set to NULL when iterator is exhausted */
+} calliterobject;
+
+PyObject *
+PyCallIter_New(PyObject *callable, PyObject *sentinel)
+{
+	calliterobject *it;
+	it = PyObject_GC_New(calliterobject, &PyCallIter_Type);
+	if (it == NULL)
+		return NULL;
+	Py_INCREF(callable);
+	it->it_callable = callable;
+	Py_INCREF(sentinel);
+	it->it_sentinel = sentinel;
+	_PyObject_GC_TRACK(it);
+	return (PyObject *)it;
+}
+static void
+calliter_dealloc(calliterobject *it)
+{
+	_PyObject_GC_UNTRACK(it);
+	Py_XDECREF(it->it_callable);
+	Py_XDECREF(it->it_sentinel);
+	PyObject_GC_Del(it);
+}
+
+static int
+calliter_traverse(calliterobject *it, visitproc visit, void *arg)
+{
+	Py_VISIT(it->it_callable);
+	Py_VISIT(it->it_sentinel);
+	return 0;
+}
+
+static PyObject *
+calliter_iternext(calliterobject *it)
+{
+	if (it->it_callable != NULL) {
+		PyObject *args = PyTuple_New(0);
+		PyObject *result;
+		if (args == NULL)
+			return NULL;
+		result = PyObject_Call(it->it_callable, args, NULL);
+		Py_DECREF(args);
+		if (result != NULL) {
+			int ok;
+			ok = PyObject_RichCompareBool(result,
+						      it->it_sentinel,
+						      Py_EQ);
+			if (ok == 0)
+				return result; /* Common case, fast path */
+			Py_DECREF(result);
+			if (ok > 0) {
+				Py_CLEAR(it->it_callable);
+				Py_CLEAR(it->it_sentinel);
+			}
+		}
+		else if (PyErr_ExceptionMatches(PyExc_StopIteration)) {
+			PyErr_Clear();
+			Py_CLEAR(it->it_callable);
+			Py_CLEAR(it->it_sentinel);
+		}
+	}
+	return NULL;
+}
+
+PyTypeObject PyCallIter_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,					/* ob_size */
+	"callable-iterator",			/* tp_name */
+	sizeof(calliterobject),			/* tp_basicsize */
+	0,					/* tp_itemsize */
+	/* methods */
+	(destructor)calliter_dealloc, 		/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	0,					/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+	0,					/* tp_doc */
+	(traverseproc)calliter_traverse,	/* tp_traverse */
+	0,					/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	PyObject_SelfIter,			/* tp_iter */
+	(iternextfunc)calliter_iternext,	/* tp_iternext */
+	0,					/* tp_methods */
+};

Added: vendor/Python/current/Objects/listobject.c
===================================================================
--- vendor/Python/current/Objects/listobject.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Objects/listobject.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2930 @@
+/* List object implementation */
+
+#include "Python.h"
+
+#ifdef STDC_HEADERS
+#include <stddef.h>
+#else
+#include <sys/types.h>		/* For size_t */
+#endif
+
+/* Ensure ob_item has room for at least newsize elements, and set
+ * ob_size to newsize.  If newsize > ob_size on entry, the content
+ * of the new slots at exit is undefined heap trash; it's the caller's
+ * responsiblity to overwrite them with sane values.
+ * The number of allocated elements may grow, shrink, or stay the same.
+ * Failure is impossible if newsize <= self.allocated on entry, although
+ * that partly relies on an assumption that the system realloc() never
+ * fails when passed a number of bytes <= the number of bytes last
+ * allocated (the C standard doesn't guarantee this, but it's hard to
+ * imagine a realloc implementation where it wouldn't be true).
+ * Note that self->ob_item may change, and even if newsize is less
+ * than ob_size on entry.
+ */
+static int
+list_resize(PyListObject *self, Py_ssize_t newsize)
+{
+	PyObject **items;
+	size_t new_allocated;
+	Py_ssize_t allocated = self->allocated;
+
+	/* Bypass realloc() when a previous overallocation is large enough
+	   to accommodate the newsize.  If the newsize falls lower than half
+	   the allocated size, then proceed with the realloc() to shrink the list.
+	*/
+	if (allocated >= newsize && newsize >= (allocated >> 1)) {
+		assert(self->ob_item != NULL || newsize == 0);
+		self->ob_size = newsize;
+		return 0;
+	}
+
+	/* This over-allocates proportional to the list size, making room
+	 * for additional growth.  The over-allocation is mild, but is
+	 * enough to give linear-time amortized behavior over a long
+	 * sequence of appends() in the presence of a poorly-performing
+	 * system realloc().
+	 * The growth pattern is:  0, 4, 8, 16, 25, 35, 46, 58, 72, 88, ...
+	 */
+	new_allocated = (newsize >> 3) + (newsize < 9 ? 3 : 6) + newsize;
+	if (newsize == 0)
+		new_allocated = 0;
+	items = self->ob_item;
+	if (new_allocated <= ((~(size_t)0) / sizeof(PyObject *)))
+		PyMem_RESIZE(items, PyObject *, new_allocated);
+	else
+		items = NULL;
+	if (items == NULL) {
+		PyErr_NoMemory();
+		return -1;
+	}
+	self->ob_item = items;
+	self->ob_size = newsize;
+	self->allocated = new_allocated;
+	return 0;
+}
+
+/* Empty list reuse scheme to save calls to malloc and free */
+#define MAXFREELISTS 80
+static PyListObject *free_lists[MAXFREELISTS];
+static int num_free_lists = 0;
+
+void
+PyList_Fini(void)
+{
+	PyListObject *op;
+
+	while (num_free_lists) {
+		num_free_lists--;
+		op = free_lists[num_free_lists]; 
+		assert(PyList_CheckExact(op));
+		PyObject_GC_Del(op);
+	}
+}
+
+PyObject *
+PyList_New(Py_ssize_t size)
+{
+	PyListObject *op;
+	size_t nbytes;
+
+	if (size < 0) {
+		PyErr_BadInternalCall();
+		return NULL;
+	}
+	nbytes = size * sizeof(PyObject *);
+	/* Check for overflow */
+	if (nbytes / sizeof(PyObject *) != (size_t)size)
+		return PyErr_NoMemory();
+	if (num_free_lists) {
+		num_free_lists--;
+		op = free_lists[num_free_lists];
+		_Py_NewReference((PyObject *)op);
+	} else {
+		op = PyObject_GC_New(PyListObject, &PyList_Type);
+		if (op == NULL)
+			return NULL;
+	}
+	if (size <= 0)
+		op->ob_item = NULL;
+	else {
+		op->ob_item = (PyObject **) PyMem_MALLOC(nbytes);
+		if (op->ob_item == NULL) {
+			Py_DECREF(op);
+			return PyErr_NoMemory();
+		}
+		memset(op->ob_item, 0, nbytes);
+	}
+	op->ob_size = size;
+	op->allocated = size;
+	_PyObject_GC_TRACK(op);
+	return (PyObject *) op;
+}
+
+Py_ssize_t
+PyList_Size(PyObject *op)
+{
+	if (!PyList_Check(op)) {
+		PyErr_BadInternalCall();
+		return -1;
+	}
+	else
+		return ((PyListObject *)op) -> ob_size;
+}
+
+static PyObject *indexerr = NULL;
+
+PyObject *
+PyList_GetItem(PyObject *op, Py_ssize_t i)
+{
+	if (!PyList_Check(op)) {
+		PyErr_BadInternalCall();
+		return NULL;
+	}
+	if (i < 0 || i >= ((PyListObject *)op) -> ob_size) {
+		if (indexerr == NULL)
+			indexerr = PyString_FromString(
+				"list index out of range");
+		PyErr_SetObject(PyExc_IndexError, indexerr);
+		return NULL;
+	}
+	return ((PyListObject *)op) -> ob_item[i];
+}
+
+int
+PyList_SetItem(register PyObject *op, register Py_ssize_t i,
+               register PyObject *newitem)
+{
+	register PyObject *olditem;
+	register PyObject **p;
+	if (!PyList_Check(op)) {
+		Py_XDECREF(newitem);
+		PyErr_BadInternalCall();
+		return -1;
+	}
+	if (i < 0 || i >= ((PyListObject *)op) -> ob_size) {
+		Py_XDECREF(newitem);
+		PyErr_SetString(PyExc_IndexError,
+				"list assignment index out of range");
+		return -1;
+	}
+	p = ((PyListObject *)op) -> ob_item + i;
+	olditem = *p;
+	*p = newitem;
+	Py_XDECREF(olditem);
+	return 0;
+}
+
+static int
+ins1(PyListObject *self, Py_ssize_t where, PyObject *v)
+{
+	Py_ssize_t i, n = self->ob_size;
+	PyObject **items;
+	if (v == NULL) {
+		PyErr_BadInternalCall();
+		return -1;
+	}
+	if (n == PY_SSIZE_T_MAX) {
+		PyErr_SetString(PyExc_OverflowError,
+			"cannot add more objects to list");
+		return -1;
+	}
+
+	if (list_resize(self, n+1) == -1)
+		return -1;
+
+	if (where < 0) {
+		where += n;
+		if (where < 0)
+			where = 0;
+	}
+	if (where > n)
+		where = n;
+	items = self->ob_item;
+	for (i = n; --i >= where; )
+		items[i+1] = items[i];
+	Py_INCREF(v);
+	items[where] = v;
+	return 0;
+}
+
+int
+PyList_Insert(PyObject *op, Py_ssize_t where, PyObject *newitem)
+{
+	if (!PyList_Check(op)) {
+		PyErr_BadInternalCall();
+		return -1;
+	}
+	return ins1((PyListObject *)op, where, newitem);
+}
+
+static int
+app1(PyListObject *self, PyObject *v)
+{
+	Py_ssize_t n = PyList_GET_SIZE(self);
+
+	assert (v != NULL);
+	if (n == PY_SSIZE_T_MAX) {
+		PyErr_SetString(PyExc_OverflowError,
+			"cannot add more objects to list");
+		return -1;
+	}
+
+	if (list_resize(self, n+1) == -1)
+		return -1;
+
+	Py_INCREF(v);
+	PyList_SET_ITEM(self, n, v);
+	return 0;
+}
+
+int
+PyList_Append(PyObject *op, PyObject *newitem)
+{
+	if (PyList_Check(op) && (newitem != NULL))
+		return app1((PyListObject *)op, newitem);
+	PyErr_BadInternalCall();
+	return -1;
+}
+
+/* Methods */
+
+static void
+list_dealloc(PyListObject *op)
+{
+	Py_ssize_t i;
+	PyObject_GC_UnTrack(op);
+	Py_TRASHCAN_SAFE_BEGIN(op)
+	if (op->ob_item != NULL) {
+		/* Do it backwards, for Christian Tismer.
+		   There's a simple test case where somehow this reduces
+		   thrashing when a *very* large list is created and
+		   immediately deleted. */
+		i = op->ob_size;
+		while (--i >= 0) {
+			Py_XDECREF(op->ob_item[i]);
+		}
+		PyMem_FREE(op->ob_item);
+	}
+	if (num_free_lists < MAXFREELISTS && PyList_CheckExact(op))
+		free_lists[num_free_lists++] = op;
+	else
+		op->ob_type->tp_free((PyObject *)op);
+	Py_TRASHCAN_SAFE_END(op)
+}
+
+static int
+list_print(PyListObject *op, FILE *fp, int flags)
+{
+	int rc;
+	Py_ssize_t i;
+
+	rc = Py_ReprEnter((PyObject*)op);
+	if (rc != 0) {
+		if (rc < 0)
+			return rc;
+		fprintf(fp, "[...]");
+		return 0;
+	}
+	fprintf(fp, "[");
+	for (i = 0; i < op->ob_size; i++) {
+		if (i > 0)
+			fprintf(fp, ", ");
+		if (PyObject_Print(op->ob_item[i], fp, 0) != 0) {
+			Py_ReprLeave((PyObject *)op);
+			return -1;
+		}
+	}
+	fprintf(fp, "]");
+	Py_ReprLeave((PyObject *)op);
+	return 0;
+}
+
+static PyObject *
+list_repr(PyListObject *v)
+{
+	Py_ssize_t i;
+	PyObject *s, *temp;
+	PyObject *pieces = NULL, *result = NULL;
+
+	i = Py_ReprEnter((PyObject*)v);
+	if (i != 0) {
+		return i > 0 ? PyString_FromString("[...]") : NULL;
+	}
+
+	if (v->ob_size == 0) {
+		result = PyString_FromString("[]");
+		goto Done;
+	}
+
+	pieces = PyList_New(0);
+	if (pieces == NULL)
+		goto Done;
+
+	/* Do repr() on each element.  Note that this may mutate the list,
+	   so must refetch the list size on each iteration. */
+	for (i = 0; i < v->ob_size; ++i) {
+		int status;
+		s = PyObject_Repr(v->ob_item[i]);
+		if (s == NULL)
+			goto Done;
+		status = PyList_Append(pieces, s);
+		Py_DECREF(s);  /* append created a new ref */
+		if (status < 0)
+			goto Done;
+	}
+
+	/* Add "[]" decorations to the first and last items. */
+	assert(PyList_GET_SIZE(pieces) > 0);
+	s = PyString_FromString("[");
+	if (s == NULL)
+		goto Done;
+	temp = PyList_GET_ITEM(pieces, 0);
+	PyString_ConcatAndDel(&s, temp);
+	PyList_SET_ITEM(pieces, 0, s);
+	if (s == NULL)
+		goto Done;
+
+	s = PyString_FromString("]");
+	if (s == NULL)
+		goto Done;
+	temp = PyList_GET_ITEM(pieces, PyList_GET_SIZE(pieces) - 1);
+	PyString_ConcatAndDel(&temp, s);
+	PyList_SET_ITEM(pieces, PyList_GET_SIZE(pieces) - 1, temp);
+	if (temp == NULL)
+		goto Done;
+
+	/* Paste them all together with ", " between. */
+	s = PyString_FromString(", ");
+	if (s == NULL)
+		goto Done;
+	result = _PyString_Join(s, pieces);
+	Py_DECREF(s);
+
+Done:
+	Py_XDECREF(pieces);
+	Py_ReprLeave((PyObject *)v);
+	return result;
+}
+
+static Py_ssize_t
+list_length(PyListObject *a)
+{
+	return a->ob_size;
+}
+
+static int
+list_contains(PyListObject *a, PyObject *el)
+{
+	Py_ssize_t i;
+	int cmp;
+
+	for (i = 0, cmp = 0 ; cmp == 0 && i < a->ob_size; ++i)
+		cmp = PyObject_RichCompareBool(el, PyList_GET_ITEM(a, i),
+						   Py_EQ);
+	return cmp;
+}
+
+static PyObject *
+list_item(PyListObject *a, Py_ssize_t i)
+{
+	if (i < 0 || i >= a->ob_size) {
+		if (indexerr == NULL)
+			indexerr = PyString_FromString(
+				"list index out of range");
+		PyErr_SetObject(PyExc_IndexError, indexerr);
+		return NULL;
+	}
+	Py_INCREF(a->ob_item[i]);
+	return a->ob_item[i];
+}
+
+static PyObject *
+list_slice(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh)
+{
+	PyListObject *np;
+	PyObject **src, **dest;
+	Py_ssize_t i, len;
+	if (ilow < 0)
+		ilow = 0;
+	else if (ilow > a->ob_size)
+		ilow = a->ob_size;
+	if (ihigh < ilow)
+		ihigh = ilow;
+	else if (ihigh > a->ob_size)
+		ihigh = a->ob_size;
+	len = ihigh - ilow;
+	np = (PyListObject *) PyList_New(len);
+	if (np == NULL)
+		return NULL;
+
+	src = a->ob_item + ilow;
+	dest = np->ob_item;
+	for (i = 0; i < len; i++) {
+		PyObject *v = src[i];
+		Py_INCREF(v);
+		dest[i] = v;
+	}
+	return (PyObject *)np;
+}
+
+PyObject *
+PyList_GetSlice(PyObject *a, Py_ssize_t ilow, Py_ssize_t ihigh)
+{
+	if (!PyList_Check(a)) {
+		PyErr_BadInternalCall();
+		return NULL;
+	}
+	return list_slice((PyListObject *)a, ilow, ihigh);
+}
+
+static PyObject *
+list_concat(PyListObject *a, PyObject *bb)
+{
+	Py_ssize_t size;
+	Py_ssize_t i;
+	PyObject **src, **dest;
+	PyListObject *np;
+	if (!PyList_Check(bb)) {
+		PyErr_Format(PyExc_TypeError,
+			  "can only concatenate list (not \"%.200s\") to list",
+			  bb->ob_type->tp_name);
+		return NULL;
+	}
+#define b ((PyListObject *)bb)
+	size = a->ob_size + b->ob_size;
+	if (size < 0)
+		return PyErr_NoMemory();
+	np = (PyListObject *) PyList_New(size);
+	if (np == NULL) {
+		return NULL;
+	}
+	src = a->ob_item;
+	dest = np->ob_item;
+	for (i = 0; i < a->ob_size; i++) {
+		PyObject *v = src[i];
+		Py_INCREF(v);
+		dest[i] = v;
+	}
+	src = b->ob_item;
+	dest = np->ob_item + a->ob_size;
+	for (i = 0; i < b->ob_size; i++) {
+		PyObject *v = src[i];
+		Py_INCREF(v);
+		dest[i] = v;
+	}
+	return (PyObject *)np;
+#undef b
+}
+
+static PyObject *
+list_repeat(PyListObject *a, Py_ssize_t n)
+{
+	Py_ssize_t i, j;
+	Py_ssize_t size;
+	PyListObject *np;
+	PyObject **p, **items;
+	PyObject *elem;
+	if (n < 0)
+		n = 0;
+	size = a->ob_size * n;
+	if (size == 0)
+              return PyList_New(0);
+	if (n && size/n != a->ob_size)
+		return PyErr_NoMemory();
+	np = (PyListObject *) PyList_New(size);
+	if (np == NULL)
+		return NULL;
+
+	items = np->ob_item;
+	if (a->ob_size == 1) {
+		elem = a->ob_item[0];
+		for (i = 0; i < n; i++) {
+			items[i] = elem;
+			Py_INCREF(elem);
+		}
+		return (PyObject *) np;
+	}
+	p = np->ob_item;
+	items = a->ob_item;
+	for (i = 0; i < n; i++) {
+		for (j = 0; j < a->ob_size; j++) {
+			*p = items[j];
+			Py_INCREF(*p);
+			p++;
+		}
+	}
+	return (PyObject *) np;
+}
+
+static int
+list_clear(PyListObject *a)
+{
+	Py_ssize_t i;
+	PyObject **item = a->ob_item;
+	if (item != NULL) {
+		/* Because XDECREF can recursively invoke operations on
+		   this list, we make it empty first. */
+		i = a->ob_size;
+		a->ob_size = 0;
+		a->ob_item = NULL;
+		a->allocated = 0;
+		while (--i >= 0) {
+			Py_XDECREF(item[i]);
+		}
+		PyMem_FREE(item);
+	}
+	/* Never fails; the return value can be ignored.
+	   Note that there is no guarantee that the list is actually empty
+	   at this point, because XDECREF may have populated it again! */
+	return 0;
+}
+
+/* a[ilow:ihigh] = v if v != NULL.
+ * del a[ilow:ihigh] if v == NULL.
+ *
+ * Special speed gimmick:  when v is NULL and ihigh - ilow <= 8, it's
+ * guaranteed the call cannot fail.
+ */
+static int
+list_ass_slice(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v)
+{
+	/* Because [X]DECREF can recursively invoke list operations on
+	   this list, we must postpone all [X]DECREF activity until
+	   after the list is back in its canonical shape.  Therefore
+	   we must allocate an additional array, 'recycle', into which
+	   we temporarily copy the items that are deleted from the
+	   list. :-( */
+	PyObject *recycle_on_stack[8];
+	PyObject **recycle = recycle_on_stack; /* will allocate more if needed */
+	PyObject **item;
+	PyObject **vitem = NULL;
+	PyObject *v_as_SF = NULL; /* PySequence_Fast(v) */
+	Py_ssize_t n; /* # of elements in replacement list */
+	Py_ssize_t norig; /* # of elements in list getting replaced */
+	Py_ssize_t d; /* Change in size */
+	Py_ssize_t k;
+	size_t s;
+	int result = -1;	/* guilty until proved innocent */
+#define b ((PyListObject *)v)
+	if (v == NULL)
+		n = 0;
+	else {
+		if (a == b) {
+			/* Special case "a[i:j] = a" -- copy b first */
+			v = list_slice(b, 0, b->ob_size);
+			if (v == NULL)
+				return result;
+			result = list_ass_slice(a, ilow, ihigh, v);
+			Py_DECREF(v);
+			return result;
+		}
+		v_as_SF = PySequence_Fast(v, "can only assign an iterable");
+		if(v_as_SF == NULL)
+			goto Error;
+		n = PySequence_Fast_GET_SIZE(v_as_SF);
+		vitem = PySequence_Fast_ITEMS(v_as_SF);
+	}
+	if (ilow < 0)
+		ilow = 0;
+	else if (ilow > a->ob_size)
+		ilow = a->ob_size;
+
+	if (ihigh < ilow)
+		ihigh = ilow;
+	else if (ihigh > a->ob_size)
+		ihigh = a->ob_size;
+
+	norig = ihigh - ilow;
+	assert(norig >= 0);
+	d = n - norig;
+	if (a->ob_size + d == 0) {
+		Py_XDECREF(v_as_SF);
+		return list_clear(a);
+	}
+	item = a->ob_item;
+	/* recycle the items that we are about to remove */
+	s = norig * sizeof(PyObject *);
+	if (s > sizeof(recycle_on_stack)) {
+		recycle = (PyObject **)PyMem_MALLOC(s);
+		if (recycle == NULL) {
+			PyErr_NoMemory();
+			goto Error;
+		}
+	}
+	memcpy(recycle, &item[ilow], s);
+
+	if (d < 0) { /* Delete -d items */
+		memmove(&item[ihigh+d], &item[ihigh],
+			(a->ob_size - ihigh)*sizeof(PyObject *));
+		list_resize(a, a->ob_size + d);
+		item = a->ob_item;
+	}
+	else if (d > 0) { /* Insert d items */
+		k = a->ob_size;
+		if (list_resize(a, k+d) < 0)
+			goto Error;
+		item = a->ob_item;
+		memmove(&item[ihigh+d], &item[ihigh],
+			(k - ihigh)*sizeof(PyObject *));
+	}
+	for (k = 0; k < n; k++, ilow++) {
+		PyObject *w = vitem[k];
+		Py_XINCREF(w);
+		item[ilow] = w;
+	}
+	for (k = norig - 1; k >= 0; --k)
+		Py_XDECREF(recycle[k]);
+	result = 0;
+ Error:
+	if (recycle != recycle_on_stack)
+		PyMem_FREE(recycle);
+	Py_XDECREF(v_as_SF);
+	return result;
+#undef b
+}
+
+int
+PyList_SetSlice(PyObject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v)
+{
+	if (!PyList_Check(a)) {
+		PyErr_BadInternalCall();
+		return -1;
+	}
+	return list_ass_slice((PyListObject *)a, ilow, ihigh, v);
+}
+
+static PyObject *
+list_inplace_repeat(PyListObject *self, Py_ssize_t n)
+{
+	PyObject **items;
+	Py_ssize_t size, i, j, p;
+
+
+	size = PyList_GET_SIZE(self);
+	if (size == 0) {
+		Py_INCREF(self);
+		return (PyObject *)self;
+	}
+
+	if (n < 1) {
+		(void)list_clear(self);
+		Py_INCREF(self);
+		return (PyObject *)self;
+	}
+
+	if (list_resize(self, size*n) == -1)
+		return NULL;
+
+	p = size;
+	items = self->ob_item;
+	for (i = 1; i < n; i++) { /* Start counting at 1, not 0 */
+		for (j = 0; j < size; j++) {
+			PyObject *o = items[j];
+			Py_INCREF(o);
+			items[p++] = o;
+		}
+	}
+	Py_INCREF(self);
+	return (PyObject *)self;
+}
+
+static int
+list_ass_item(PyListObject *a, Py_ssize_t i, PyObject *v)
+{
+	PyObject *old_value;
+	if (i < 0 || i >= a->ob_size) {
+		PyErr_SetString(PyExc_IndexError,
+				"list assignment index out of range");
+		return -1;
+	}
+	if (v == NULL)
+		return list_ass_slice(a, i, i+1, v);
+	Py_INCREF(v);
+	old_value = a->ob_item[i];
+	a->ob_item[i] = v;
+	Py_DECREF(old_value);
+	return 0;
+}
+
+static PyObject *
+listinsert(PyListObject *self, PyObject *args)
+{
+	Py_ssize_t i;
+	PyObject *v;
+	if (!PyArg_ParseTuple(args, "nO:insert", &i, &v))
+		return NULL;
+	if (ins1(self, i, v) == 0)
+		Py_RETURN_NONE;
+	return NULL;
+}
+
+static PyObject *
+listappend(PyListObject *self, PyObject *v)
+{
+	if (app1(self, v) == 0)
+		Py_RETURN_NONE;
+	return NULL;
+}
+
+static PyObject *
+listextend(PyListObject *self, PyObject *b)
+{
+	PyObject *it;      /* iter(v) */
+	Py_ssize_t m;		   /* size of self */
+	Py_ssize_t n;		   /* guess for size of b */
+	Py_ssize_t mn;		   /* m + n */
+	Py_ssize_t i;
+	PyObject *(*iternext)(PyObject *);
+
+	/* Special cases:
+	   1) lists and tuples which can use PySequence_Fast ops
+	   2) extending self to self requires making a copy first
+	*/
+	if (PyList_CheckExact(b) || PyTuple_CheckExact(b) || (PyObject *)self == b) {
+		PyObject **src, **dest;
+		b = PySequence_Fast(b, "argument must be iterable");
+		if (!b)
+			return NULL;
+		n = PySequence_Fast_GET_SIZE(b);
+		if (n == 0) {
+			/* short circuit when b is empty */
+			Py_DECREF(b);
+			Py_RETURN_NONE;
+		}
+		m = self->ob_size;
+		if (list_resize(self, m + n) == -1) {
+			Py_DECREF(b);
+			return NULL;
+		}
+		/* note that we may still have self == b here for the
+		 * situation a.extend(a), but the following code works
+		 * in that case too.  Just make sure to resize self
+		 * before calling PySequence_Fast_ITEMS.
+		 */
+		/* populate the end of self with b's items */
+		src = PySequence_Fast_ITEMS(b);
+		dest = self->ob_item + m;
+		for (i = 0; i < n; i++) {
+			PyObject *o = src[i];
+			Py_INCREF(o);
+			dest[i] = o;
+		}
+		Py_DECREF(b);
+		Py_RETURN_NONE;
+	}
+
+	it = PyObject_GetIter(b);
+	if (it == NULL)
+		return NULL;
+	iternext = *it->ob_type->tp_iternext;
+
+	/* Guess a result list size. */
+	n = _PyObject_LengthHint(b);
+	if (n < 0) {
+		if (!PyErr_ExceptionMatches(PyExc_TypeError)  &&
+		    !PyErr_ExceptionMatches(PyExc_AttributeError)) {
+			Py_DECREF(it);
+			return NULL;
+		}
+		PyErr_Clear();
+		n = 8;	/* arbitrary */
+	}
+	m = self->ob_size;
+	mn = m + n;
+	if (mn >= m) {
+		/* Make room. */
+		if (list_resize(self, mn) == -1)
+			goto error;
+		/* Make the list sane again. */
+		self->ob_size = m;
+	}
+	/* Else m + n overflowed; on the chance that n lied, and there really
+	 * is enough room, ignore it.  If n was telling the truth, we'll
+	 * eventually run out of memory during the loop.
+	 */
+
+	/* Run iterator to exhaustion. */
+	for (;;) {
+		PyObject *item = iternext(it);
+		if (item == NULL) {
+			if (PyErr_Occurred()) {
+				if (PyErr_ExceptionMatches(PyExc_StopIteration))
+					PyErr_Clear();
+				else
+					goto error;
+			}
+			break;
+		}
+		if (self->ob_size < self->allocated) {
+			/* steals ref */
+			PyList_SET_ITEM(self, self->ob_size, item);
+			++self->ob_size;
+		}
+		else {
+			int status = app1(self, item);
+			Py_DECREF(item);  /* append creates a new ref */
+			if (status < 0)
+				goto error;
+		}
+	}
+
+	/* Cut back result list if initial guess was too large. */
+	if (self->ob_size < self->allocated)
+		list_resize(self, self->ob_size);  /* shrinking can't fail */
+
+	Py_DECREF(it);
+	Py_RETURN_NONE;
+
+  error:
+	Py_DECREF(it);
+	return NULL;
+}
+
+PyObject *
+_PyList_Extend(PyListObject *self, PyObject *b)
+{
+	return listextend(self, b);
+}
+
+static PyObject *
+list_inplace_concat(PyListObject *self, PyObject *other)
+{
+	PyObject *result;
+
+	result = listextend(self, other);
+	if (result == NULL)
+		return result;
+	Py_DECREF(result);
+	Py_INCREF(self);
+	return (PyObject *)self;
+}
+
+static PyObject *
+listpop(PyListObject *self, PyObject *args)
+{
+	Py_ssize_t i = -1;
+	PyObject *v;
+	int status;
+
+	if (!PyArg_ParseTuple(args, "|n:pop", &i))
+		return NULL;
+
+	if (self->ob_size == 0) {
+		/* Special-case most common failure cause */
+		PyErr_SetString(PyExc_IndexError, "pop from empty list");
+		return NULL;
+	}
+	if (i < 0)
+		i += self->ob_size;
+	if (i < 0 || i >= self->ob_size) {
+		PyErr_SetString(PyExc_IndexError, "pop index out of range");
+		return NULL;
+	}
+	v = self->ob_item[i];
+	if (i == self->ob_size - 1) {
+		status = list_resize(self, self->ob_size - 1);
+		assert(status >= 0);
+		return v; /* and v now owns the reference the list had */
+	}
+	Py_INCREF(v);
+	status = list_ass_slice(self, i, i+1, (PyObject *)NULL);
+	assert(status >= 0);
+	/* Use status, so that in a release build compilers don't
+	 * complain about the unused name.
+	 */
+	(void) status;
+
+	return v;
+}
+
+/* Reverse a slice of a list in place, from lo up to (exclusive) hi. */
+static void
+reverse_slice(PyObject **lo, PyObject **hi)
+{
+	assert(lo && hi);
+
+	--hi;
+	while (lo < hi) {
+		PyObject *t = *lo;
+		*lo = *hi;
+		*hi = t;
+		++lo;
+		--hi;
+	}
+}
+
+/* Lots of code for an adaptive, stable, natural mergesort.  There are many
+ * pieces to this algorithm; read listsort.txt for overviews and details.
+ */
+
+/* Comparison function.  Takes care of calling a user-supplied
+ * comparison function (any callable Python object), which must not be
+ * NULL (use the ISLT macro if you don't know, or call PyObject_RichCompareBool
+ * with Py_LT if you know it's NULL).
+ * Returns -1 on error, 1 if x < y, 0 if x >= y.
+ */
+static int
+islt(PyObject *x, PyObject *y, PyObject *compare)
+{
+	PyObject *res;
+	PyObject *args;
+	Py_ssize_t i;
+
+	assert(compare != NULL);
+	/* Call the user's comparison function and translate the 3-way
+	 * result into true or false (or error).
+	 */
+	args = PyTuple_New(2);
+	if (args == NULL)
+		return -1;
+	Py_INCREF(x);
+	Py_INCREF(y);
+	PyTuple_SET_ITEM(args, 0, x);
+	PyTuple_SET_ITEM(args, 1, y);
+	res = PyObject_Call(compare, args, NULL);
+	Py_DECREF(args);
+	if (res == NULL)
+		return -1;
+	if (!PyInt_Check(res)) {
+		Py_DECREF(res);
+		PyErr_SetString(PyExc_TypeError,
+				"comparison function must return int");
+		return -1;
+	}
+	i = PyInt_AsLong(res);
+	Py_DECREF(res);
+	return i < 0;
+}
+
+/* If COMPARE is NULL, calls PyObject_RichCompareBool with Py_LT, else calls
+ * islt.  This avoids a layer of function call in the usual case, and
+ * sorting does many comparisons.
+ * Returns -1 on error, 1 if x < y, 0 if x >= y.
+ */
+#define ISLT(X, Y, COMPARE) ((COMPARE) == NULL ?			\
+			     PyObject_RichCompareBool(X, Y, Py_LT) :	\
+			     islt(X, Y, COMPARE))
+
+/* Compare X to Y via "<".  Goto "fail" if the comparison raises an
+   error.  Else "k" is set to true iff X<Y, and an "if (k)" block is
+   started.  It makes more sense in context <wink>.  X and Y are PyObject*s.
+*/
+#define IFLT(X, Y) if ((k = ISLT(X, Y, compare)) < 0) goto fail;  \
+		   if (k)
+
+/* binarysort is the best method for sorting small arrays: it does
+   few compares, but can do data movement quadratic in the number of
+   elements.
+   [lo, hi) is a contiguous slice of a list, and is sorted via
+   binary insertion.  This sort is stable.
+   On entry, must have lo <= start <= hi, and that [lo, start) is already
+   sorted (pass start == lo if you don't know!).
+   If islt() complains return -1, else 0.
+   Even in case of error, the output slice will be some permutation of
+   the input (nothing is lost or duplicated).
+*/
+static int
+binarysort(PyObject **lo, PyObject **hi, PyObject **start, PyObject *compare)
+     /* compare -- comparison function object, or NULL for default */
+{
+	register Py_ssize_t k;
+	register PyObject **l, **p, **r;
+	register PyObject *pivot;
+
+	assert(lo <= start && start <= hi);
+	/* assert [lo, start) is sorted */
+	if (lo == start)
+		++start;
+	for (; start < hi; ++start) {
+		/* set l to where *start belongs */
+		l = lo;
+		r = start;
+		pivot = *r;
+		/* Invariants:
+		 * pivot >= all in [lo, l).
+		 * pivot  < all in [r, start).
+		 * The second is vacuously true at the start.
+		 */
+		assert(l < r);
+		do {
+			p = l + ((r - l) >> 1);
+			IFLT(pivot, *p)
+				r = p;
+			else
+				l = p+1;
+		} while (l < r);
+		assert(l == r);
+		/* The invariants still hold, so pivot >= all in [lo, l) and
+		   pivot < all in [l, start), so pivot belongs at l.  Note
+		   that if there are elements equal to pivot, l points to the
+		   first slot after them -- that's why this sort is stable.
+		   Slide over to make room.
+		   Caution: using memmove is much slower under MSVC 5;
+		   we're not usually moving many slots. */
+		for (p = start; p > l; --p)
+			*p = *(p-1);
+		*l = pivot;
+	}
+	return 0;
+
+ fail:
+	return -1;
+}
+
+/*
+Return the length of the run beginning at lo, in the slice [lo, hi).  lo < hi
+is required on entry.  "A run" is the longest ascending sequence, with
+
+    lo[0] <= lo[1] <= lo[2] <= ...
+
+or the longest descending sequence, with
+
+    lo[0] > lo[1] > lo[2] > ...
+
+Boolean *descending is set to 0 in the former case, or to 1 in the latter.
+For its intended use in a stable mergesort, the strictness of the defn of
+"descending" is needed so that the caller can safely reverse a descending
+sequence without violating stability (strict > ensures there are no equal
+elements to get out of order).
+
+Returns -1 in case of error.
+*/
+static Py_ssize_t
+count_run(PyObject **lo, PyObject **hi, PyObject *compare, int *descending)
+{
+	Py_ssize_t k;
+	Py_ssize_t n;
+
+	assert(lo < hi);
+	*descending = 0;
+	++lo;
+	if (lo == hi)
+		return 1;
+
+	n = 2;
+	IFLT(*lo, *(lo-1)) {
+		*descending = 1;
+		for (lo = lo+1; lo < hi; ++lo, ++n) {
+			IFLT(*lo, *(lo-1))
+				;
+			else
+				break;
+		}
+	}
+	else {
+		for (lo = lo+1; lo < hi; ++lo, ++n) {
+			IFLT(*lo, *(lo-1))
+				break;
+		}
+	}
+
+	return n;
+fail:
+	return -1;
+}
+
+/*
+Locate the proper position of key in a sorted vector; if the vector contains
+an element equal to key, return the position immediately to the left of
+the leftmost equal element.  [gallop_right() does the same except returns
+the position to the right of the rightmost equal element (if any).]
+
+"a" is a sorted vector with n elements, starting at a[0].  n must be > 0.
+
+"hint" is an index at which to begin the search, 0 <= hint < n.  The closer
+hint is to the final result, the faster this runs.
+
+The return value is the int k in 0..n such that
+
+    a[k-1] < key <= a[k]
+
+pretending that *(a-1) is minus infinity and a[n] is plus infinity.  IOW,
+key belongs at index k; or, IOW, the first k elements of a should precede
+key, and the last n-k should follow key.
+
+Returns -1 on error.  See listsort.txt for info on the method.
+*/
+static Py_ssize_t
+gallop_left(PyObject *key, PyObject **a, Py_ssize_t n, Py_ssize_t hint, PyObject *compare)
+{
+	Py_ssize_t ofs;
+	Py_ssize_t lastofs;
+	Py_ssize_t k;
+
+	assert(key && a && n > 0 && hint >= 0 && hint < n);
+
+	a += hint;
+	lastofs = 0;
+	ofs = 1;
+	IFLT(*a, key) {
+		/* a[hint] < key -- gallop right, until
+		 * a[hint + lastofs] < key <= a[hint + ofs]
+		 */
+		const Py_ssize_t maxofs = n - hint;	/* &a[n-1] is highest */
+		while (ofs < maxofs) {
+			IFLT(a[ofs], key) {
+				lastofs = ofs;
+				ofs = (ofs << 1) + 1;
+				if (ofs <= 0)	/* int overflow */
+					ofs = maxofs;
+			}
+ 			else	/* key <= a[hint + ofs] */
+				break;
+		}
+		if (ofs > maxofs)
+			ofs = maxofs;
+		/* Translate back to offsets relative to &a[0]. */
+		lastofs += hint;
+		ofs += hint;
+	}
+	else {
+		/* key <= a[hint] -- gallop left, until
+		 * a[hint - ofs] < key <= a[hint - lastofs]
+		 */
+		const Py_ssize_t maxofs = hint + 1;	/* &a[0] is lowest */
+		while (ofs < maxofs) {
+			IFLT(*(a-ofs), key)
+				break;
+			/* key <= a[hint - ofs] */
+			lastofs = ofs;
+			ofs = (ofs << 1) + 1;
+			if (ofs <= 0)	/* int overflow */
+				ofs = maxofs;
+		}
+		if (ofs > maxofs)
+			ofs = maxofs;
+		/* Translate back to positive offsets relative to &a[0]. */
+		k = lastofs;
+		lastofs = hint - ofs;
+		ofs = hint - k;
+	}
+	a -= hint;
+
+	assert(-1 <= lastofs && lastofs < ofs && ofs <= n);
+	/* Now a[lastofs] < key <= a[ofs], so key belongs somewhere to the
+	 * right of lastofs but no farther right than ofs.  Do a binary
+	 * search, with invariant a[lastofs-1] < key <= a[ofs].
+	 */
+	++lastofs;
+	while (lastofs < ofs) {
+		Py_ssize_t m = lastofs + ((ofs - lastofs) >> 1);
+
+		IFLT(a[m], key)
+			lastofs = m+1;	/* a[m] < key */
+		else
+			ofs = m;	/* key <= a[m] */
+	}
+	assert(lastofs == ofs);		/* so a[ofs-1] < key <= a[ofs] */
+	return ofs;
+
+fail:
+	return -1;
+}
+
+/*
+Exactly like gallop_left(), except that if key already exists in a[0:n],
+finds the position immediately to the right of the rightmost equal value.
+
+The return value is the int k in 0..n such that
+
+    a[k-1] <= key < a[k]
+
+or -1 if error.
+
+The code duplication is massive, but this is enough different given that
+we're sticking to "<" comparisons that it's much harder to follow if
+written as one routine with yet another "left or right?" flag.
+*/
+static Py_ssize_t
+gallop_right(PyObject *key, PyObject **a, Py_ssize_t n, Py_ssize_t hint, PyObject *compare)
+{
+	Py_ssize_t ofs;
+	Py_ssize_t lastofs;
+	Py_ssize_t k;
+
+	assert(key && a && n > 0 && hint >= 0 && hint < n);
+
+	a += hint;
+	lastofs = 0;
+	ofs = 1;
+	IFLT(key, *a) {
+		/* key < a[hint] -- gallop left, until
+		 * a[hint - ofs] <= key < a[hint - lastofs]
+		 */
+		const Py_ssize_t maxofs = hint + 1;	/* &a[0] is lowest */
+		while (ofs < maxofs) {
+			IFLT(key, *(a-ofs)) {
+				lastofs = ofs;
+				ofs = (ofs << 1) + 1;
+				if (ofs <= 0)	/* int overflow */
+					ofs = maxofs;
+			}
+			else	/* a[hint - ofs] <= key */
+				break;
+		}
+		if (ofs > maxofs)
+			ofs = maxofs;
+		/* Translate back to positive offsets relative to &a[0]. */
+		k = lastofs;
+		lastofs = hint - ofs;
+		ofs = hint - k;
+	}
+	else {
+		/* a[hint] <= key -- gallop right, until
+		 * a[hint + lastofs] <= key < a[hint + ofs]
+		*/
+		const Py_ssize_t maxofs = n - hint;	/* &a[n-1] is highest */
+		while (ofs < maxofs) {
+			IFLT(key, a[ofs])
+				break;
+			/* a[hint + ofs] <= key */
+			lastofs = ofs;
+			ofs = (ofs << 1) + 1;
+			if (ofs <= 0)	/* int overflow */
+				ofs = maxofs;
+		}
+		if (ofs > maxofs)
+			ofs = maxofs;
+		/* Translate back to offsets relative to &a[0]. */
+		lastofs += hint;
+		ofs += hint;
+	}
+	a -= hint;
+
+	assert(-1 <= lastofs && lastofs < ofs && ofs <= n);
+	/* Now a[lastofs] <= key < a[ofs], so key belongs somewhere to the
+	 * right of lastofs but no farther right than ofs.  Do a binary
+	 * search, with invariant a[lastofs-1] <= key < a[ofs].
+	 */
+	++lastofs;
+	while (lastofs < ofs) {
+		Py_ssize_t m = lastofs + ((ofs - lastofs) >> 1);
+
+		IFLT(key, a[m])
+			ofs = m;	/* key < a[m] */
+		else
+			lastofs = m+1;	/* a[m] <= key */
+	}
+	assert(lastofs == ofs);		/* so a[ofs-1] <= key < a[ofs] */
+	return ofs;
+
+fail:
+	return -1;
+}
+
+/* The maximum number of entries in a MergeState's pending-runs stack.
+ * This is enough to sort arrays of size up to about
+ *     32 * phi ** MAX_MERGE_PENDING
+ * where phi ~= 1.618.  85 is ridiculouslylarge enough, good for an array
+ * with 2**64 elements.
+ */
+#define MAX_MERGE_PENDING 85
+
+/* When we get into galloping mode, we stay there until both runs win less
+ * often than MIN_GALLOP consecutive times.  See listsort.txt for more info.
+ */
+#define MIN_GALLOP 7
+
+/* Avoid malloc for small temp arrays. */
+#define MERGESTATE_TEMP_SIZE 256
+
+/* One MergeState exists on the stack per invocation of mergesort.  It's just
+ * a convenient way to pass state around among the helper functions.
+ */
+struct s_slice {
+	PyObject **base;
+	Py_ssize_t len;
+};
+
+typedef struct s_MergeState {
+	/* The user-supplied comparison function. or NULL if none given. */
+	PyObject *compare;
+
+	/* This controls when we get *into* galloping mode.  It's initialized
+	 * to MIN_GALLOP.  merge_lo and merge_hi tend to nudge it higher for
+	 * random data, and lower for highly structured data.
+	 */
+	Py_ssize_t min_gallop;
+
+	/* 'a' is temp storage to help with merges.  It contains room for
+	 * alloced entries.
+	 */
+	PyObject **a;	/* may point to temparray below */
+	Py_ssize_t alloced;
+
+	/* A stack of n pending runs yet to be merged.  Run #i starts at
+	 * address base[i] and extends for len[i] elements.  It's always
+	 * true (so long as the indices are in bounds) that
+	 *
+	 *     pending[i].base + pending[i].len == pending[i+1].base
+	 *
+	 * so we could cut the storage for this, but it's a minor amount,
+	 * and keeping all the info explicit simplifies the code.
+	 */
+	int n;
+	struct s_slice pending[MAX_MERGE_PENDING];
+
+	/* 'a' points to this when possible, rather than muck with malloc. */
+	PyObject *temparray[MERGESTATE_TEMP_SIZE];
+} MergeState;
+
+/* Conceptually a MergeState's constructor. */
+static void
+merge_init(MergeState *ms, PyObject *compare)
+{
+	assert(ms != NULL);
+	ms->compare = compare;
+	ms->a = ms->temparray;
+	ms->alloced = MERGESTATE_TEMP_SIZE;
+	ms->n = 0;
+	ms->min_gallop = MIN_GALLOP;
+}
+
+/* Free all the temp memory owned by the MergeState.  This must be called
+ * when you're done with a MergeState, and may be called before then if
+ * you want to free the temp memory early.
+ */
+static void
+merge_freemem(MergeState *ms)
+{
+	assert(ms != NULL);
+	if (ms->a != ms->temparray)
+		PyMem_Free(ms->a);
+	ms->a = ms->temparray;
+	ms->alloced = MERGESTATE_TEMP_SIZE;
+}
+
+/* Ensure enough temp memory for 'need' array slots is available.
+ * Returns 0 on success and -1 if the memory can't be gotten.
+ */
+static int
+merge_getmem(MergeState *ms, Py_ssize_t need)
+{
+	assert(ms != NULL);
+	if (need <= ms->alloced)
+		return 0;
+	/* Don't realloc!  That can cost cycles to copy the old data, but
+	 * we don't care what's in the block.
+	 */
+	merge_freemem(ms);
+	ms->a = (PyObject **)PyMem_Malloc(need * sizeof(PyObject*));
+	if (ms->a) {
+		ms->alloced = need;
+		return 0;
+	}
+	PyErr_NoMemory();
+	merge_freemem(ms);	/* reset to sane state */
+	return -1;
+}
+#define MERGE_GETMEM(MS, NEED) ((NEED) <= (MS)->alloced ? 0 :	\
+				merge_getmem(MS, NEED))
+
+/* Merge the na elements starting at pa with the nb elements starting at pb
+ * in a stable way, in-place.  na and nb must be > 0, and pa + na == pb.
+ * Must also have that *pb < *pa, that pa[na-1] belongs at the end of the
+ * merge, and should have na <= nb.  See listsort.txt for more info.
+ * Return 0 if successful, -1 if error.
+ */
+static Py_ssize_t
+merge_lo(MergeState *ms, PyObject **pa, Py_ssize_t na,
+                         PyObject **pb, Py_ssize_t nb)
+{
+	Py_ssize_t k;
+	PyObject *compare;
+	PyObject **dest;
+	int result = -1;	/* guilty until proved innocent */
+	Py_ssize_t min_gallop = ms->min_gallop;
+
+	assert(ms && pa && pb && na > 0 && nb > 0 && pa + na == pb);
+	if (MERGE_GETMEM(ms, na) < 0)
+		return -1;
+	memcpy(ms->a, pa, na * sizeof(PyObject*));
+	dest = pa;
+	pa = ms->a;
+
+	*dest++ = *pb++;
+	--nb;
+	if (nb == 0)
+		goto Succeed;
+	if (na == 1)
+		goto CopyB;
+
+	compare = ms->compare;
+	for (;;) {
+		Py_ssize_t acount = 0;	/* # of times A won in a row */
+		Py_ssize_t bcount = 0;	/* # of times B won in a row */
+
+		/* Do the straightforward thing until (if ever) one run
+		 * appears to win consistently.
+		 */
+ 		for (;;) {
+ 			assert(na > 1 && nb > 0);
+	 		k = ISLT(*pb, *pa, compare);
+			if (k) {
+				if (k < 0)
+					goto Fail;
+				*dest++ = *pb++;
+				++bcount;
+				acount = 0;
+				--nb;
+				if (nb == 0)
+					goto Succeed;
+				if (bcount >= min_gallop)
+					break;
+			}
+			else {
+				*dest++ = *pa++;
+				++acount;
+				bcount = 0;
+				--na;
+				if (na == 1)
+					goto CopyB;
+				if (acount >= min_gallop)
+					break;
+			}
+ 		}
+
+		/* One run is winning so consistently that galloping may
+		 * be a huge win.  So try that, and continue galloping until
+		 * (if ever) neither run appears to be winning consistently
+		 * anymore.
+		 */
+		++min_gallop;
+		do {
+ 			assert(na > 1 && nb > 0);
+			min_gallop -= min_gallop > 1;
+	 		ms->min_gallop = min_gallop;
+			k = gallop_right(*pb, pa, na, 0, compare);
+			acount = k;
+			if (k) {
+				if (k < 0)
+					goto Fail;
+				memcpy(dest, pa, k * sizeof(PyObject *));
+				dest += k;
+				pa += k;
+				na -= k;
+				if (na == 1)
+					goto CopyB;
+				/* na==0 is impossible now if the comparison
+				 * function is consistent, but we can't assume
+				 * that it is.
+				 */
+				if (na == 0)
+					goto Succeed;
+			}
+			*dest++ = *pb++;
+			--nb;
+			if (nb == 0)
+				goto Succeed;
+
+ 			k = gallop_left(*pa, pb, nb, 0, compare);
+ 			bcount = k;
+			if (k) {
+				if (k < 0)
+					goto Fail;
+				memmove(dest, pb, k * sizeof(PyObject *));
+				dest += k;
+				pb += k;
+				nb -= k;
+				if (nb == 0)
+					goto Succeed;
+			}
+			*dest++ = *pa++;
+			--na;
+			if (na == 1)
+				goto CopyB;
+ 		} while (acount >= MIN_GALLOP || bcount >= MIN_GALLOP);
+ 		++min_gallop;	/* penalize it for leaving galloping mode */
+ 		ms->min_gallop = min_gallop;
+ 	}
+Succeed:
+	result = 0;
+Fail:
+	if (na)
+		memcpy(dest, pa, na * sizeof(PyObject*));
+	return result;
+CopyB:
+	assert(na == 1 && nb > 0);
+	/* The last element of pa belongs at the end of the merge. */
+	memmove(dest, pb, nb * sizeof(PyObject *));
+	dest[nb] = *pa;
+	return 0;
+}
+
+/* Merge the na elements starting at pa with the nb elements starting at pb
+ * in a stable way, in-place.  na and nb must be > 0, and pa + na == pb.
+ * Must also have that *pb < *pa, that pa[na-1] belongs at the end of the
+ * merge, and should have na >= nb.  See listsort.txt for more info.
+ * Return 0 if successful, -1 if error.
+ */
+static Py_ssize_t
+merge_hi(MergeState *ms, PyObject **pa, Py_ssize_t na, PyObject **pb, Py_ssize_t nb)
+{
+	Py_ssize_t k;
+	PyObject *compare;
+	PyObject **dest;
+	int result = -1;	/* guilty until proved innocent */
+	PyObject **basea;
+	PyObject **baseb;
+	Py_ssize_t min_gallop = ms->min_gallop;
+
+	assert(ms && pa && pb && na > 0 && nb > 0 && pa + na == pb);
+	if (MERGE_GETMEM(ms, nb) < 0)
+		return -1;
+	dest = pb + nb - 1;
+	memcpy(ms->a, pb, nb * sizeof(PyObject*));
+	basea = pa;
+	baseb = ms->a;
+	pb = ms->a + nb - 1;
+	pa += na - 1;
+
+	*dest-- = *pa--;
+	--na;
+	if (na == 0)
+		goto Succeed;
+	if (nb == 1)
+		goto CopyA;
+
+	compare = ms->compare;
+	for (;;) {
+		Py_ssize_t acount = 0;	/* # of times A won in a row */
+		Py_ssize_t bcount = 0;	/* # of times B won in a row */
+
+		/* Do the straightforward thing until (if ever) one run
+		 * appears to win consistently.
+		 */
+ 		for (;;) {
+ 			assert(na > 0 && nb > 1);
+	 		k = ISLT(*pb, *pa, compare);
+			if (k) {
+				if (k < 0)
+					goto Fail;
+				*dest-- = *pa--;
+				++acount;
+				bcount = 0;
+				--na;
+				if (na == 0)
+					goto Succeed;
+				if (acount >= min_gallop)
+					break;
+			}
+			else {
+				*dest-- = *pb--;
+				++bcount;
+				acount = 0;
+				--nb;
+				if (nb == 1)
+					goto CopyA;
+				if (bcount >= min_gallop)
+					break;
+			}
+ 		}
+
+		/* One run is winning so consistently that galloping may
+		 * be a huge win.  So try that, and continue galloping until
+		 * (if ever) neither run appears to be winning consistently
+		 * anymore.
+		 */
+		++min_gallop;
+		do {
+ 			assert(na > 0 && nb > 1);
+			min_gallop -= min_gallop > 1;
+	 		ms->min_gallop = min_gallop;
+			k = gallop_right(*pb, basea, na, na-1, compare);
+			if (k < 0)
+				goto Fail;
+			k = na - k;
+			acount = k;
+			if (k) {
+				dest -= k;
+				pa -= k;
+				memmove(dest+1, pa+1, k * sizeof(PyObject *));
+				na -= k;
+				if (na == 0)
+					goto Succeed;
+			}
+			*dest-- = *pb--;
+			--nb;
+			if (nb == 1)
+				goto CopyA;
+
+ 			k = gallop_left(*pa, baseb, nb, nb-1, compare);
+			if (k < 0)
+				goto Fail;
+			k = nb - k;
+			bcount = k;
+			if (k) {
+				dest -= k;
+				pb -= k;
+				memcpy(dest+1, pb+1, k * sizeof(PyObject *));
+				nb -= k;
+				if (nb == 1)
+					goto CopyA;
+				/* nb==0 is impossible now if the comparison
+				 * function is consistent, but we can't assume
+				 * that it is.
+				 */
+				if (nb == 0)
+					goto Succeed;
+			}
+			*dest-- = *pa--;
+			--na;
+			if (na == 0)
+				goto Succeed;
+ 		} while (acount >= MIN_GALLOP || bcount >= MIN_GALLOP);
+ 		++min_gallop;	/* penalize it for leaving galloping mode */
+ 		ms->min_gallop = min_gallop;
+ 	}
+Succeed:
+	result = 0;
+Fail:
+	if (nb)
+		memcpy(dest-(nb-1), baseb, nb * sizeof(PyObject*));
+	return result;
+CopyA:
+	assert(nb == 1 && na > 0);
+	/* The first element of pb belongs at the front of the merge. */
+	dest -= na;
+	pa -= na;
+	memmove(dest+1, pa+1, na * sizeof(PyObject *));
+	*dest = *pb;
+	return 0;
+}
+
+/* Merge the two runs at stack indices i and i+1.
+ * Returns 0 on success, -1 on error.
+ */
+static Py_ssize_t
+merge_at(MergeState *ms, Py_ssize_t i)
+{
+	PyObject **pa, **pb;
+	Py_ssize_t na, nb;
+	Py_ssize_t k;
+	PyObject *compare;
+
+	assert(ms != NULL);
+	assert(ms->n >= 2);
+	assert(i >= 0);
+	assert(i == ms->n - 2 || i == ms->n - 3);
+
+	pa = ms->pending[i].base;
+	na = ms->pending[i].len;
+	pb = ms->pending[i+1].base;
+	nb = ms->pending[i+1].len;
+	assert(na > 0 && nb > 0);
+	assert(pa + na == pb);
+
+	/* Record the length of the combined runs; if i is the 3rd-last
+	 * run now, also slide over the last run (which isn't involved
+	 * in this merge).  The current run i+1 goes away in any case.
+	 */
+	ms->pending[i].len = na + nb;
+	if (i == ms->n - 3)
+		ms->pending[i+1] = ms->pending[i+2];
+	--ms->n;
+
+	/* Where does b start in a?  Elements in a before that can be
+	 * ignored (already in place).
+	 */
+	compare = ms->compare;
+	k = gallop_right(*pb, pa, na, 0, compare);
+	if (k < 0)
+		return -1;
+	pa += k;
+	na -= k;
+	if (na == 0)
+		return 0;
+
+	/* Where does a end in b?  Elements in b after that can be
+	 * ignored (already in place).
+	 */
+	nb = gallop_left(pa[na-1], pb, nb, nb-1, compare);
+	if (nb <= 0)
+		return nb;
+
+	/* Merge what remains of the runs, using a temp array with
+	 * min(na, nb) elements.
+	 */
+	if (na <= nb)
+		return merge_lo(ms, pa, na, pb, nb);
+	else
+		return merge_hi(ms, pa, na, pb, nb);
+}
+
+/* Examine the stack of runs waiting to be merged, merging adjacent runs
+ * until the stack invariants are re-established:
+ *
+ * 1. len[-3] > len[-2] + len[-1]
+ * 2. len[-2] > len[-1]
+ *
+ * See listsort.txt for more info.
+ *
+ * Returns 0 on success, -1 on error.
+ */
+static int
+merge_collapse(MergeState *ms)
+{
+	struct s_slice *p = ms->pending;
+
+	assert(ms);
+	while (ms->n > 1) {
+		Py_ssize_t n = ms->n - 2;
+		if (n > 0 && p[n-1].len <= p[n].len + p[n+1].len) {
+		    	if (p[n-1].len < p[n+1].len)
+		    		--n;
+			if (merge_at(ms, n) < 0)
+				return -1;
+		}
+		else if (p[n].len <= p[n+1].len) {
+			 if (merge_at(ms, n) < 0)
+			 	return -1;
+		}
+		else
+			break;
+	}
+	return 0;
+}
+
+/* Regardless of invariants, merge all runs on the stack until only one
+ * remains.  This is used at the end of the mergesort.
+ *
+ * Returns 0 on success, -1 on error.
+ */
+static int
+merge_force_collapse(MergeState *ms)
+{
+	struct s_slice *p = ms->pending;
+
+	assert(ms);
+	while (ms->n > 1) {
+		Py_ssize_t n = ms->n - 2;
+		if (n > 0 && p[n-1].len < p[n+1].len)
+			--n;
+		if (merge_at(ms, n) < 0)
+			return -1;
+	}
+	return 0;
+}
+
+/* Compute a good value for the minimum run length; natural runs shorter
+ * than this are boosted artificially via binary insertion.
+ *
+ * If n < 64, return n (it's too small to bother with fancy stuff).
+ * Else if n is an exact power of 2, return 32.
+ * Else return an int k, 32 <= k <= 64, such that n/k is close to, but
+ * strictly less than, an exact power of 2.
+ *
+ * See listsort.txt for more info.
+ */
+static Py_ssize_t
+merge_compute_minrun(Py_ssize_t n)
+{
+	Py_ssize_t r = 0;	/* becomes 1 if any 1 bits are shifted off */
+
+	assert(n >= 0);
+	while (n >= 64) {
+		r |= n & 1;
+		n >>= 1;
+	}
+	return n + r;
+}
+
+/* Special wrapper to support stable sorting using the decorate-sort-undecorate
+   pattern.  Holds a key which is used for comparisons and the original record
+   which is returned during the undecorate phase.  By exposing only the key
+   during comparisons, the underlying sort stability characteristics are left
+   unchanged.  Also, if a custom comparison function is used, it will only see
+   the key instead of a full record. */
+
+typedef struct {
+	PyObject_HEAD
+	PyObject *key;
+	PyObject *value;
+} sortwrapperobject;
+
+PyDoc_STRVAR(sortwrapper_doc, "Object wrapper with a custom sort key.");
+static PyObject *
+sortwrapper_richcompare(sortwrapperobject *, sortwrapperobject *, int);
+static void
+sortwrapper_dealloc(sortwrapperobject *);
+
+static PyTypeObject sortwrapper_type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,					/* ob_size */
+	"sortwrapper",				/* tp_name */
+	sizeof(sortwrapperobject),		/* tp_basicsize */
+	0,					/* tp_itemsize */
+	/* methods */
+	(destructor)sortwrapper_dealloc,	/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	0,					/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT |
+	Py_TPFLAGS_HAVE_RICHCOMPARE, 		/* tp_flags */
+	sortwrapper_doc,			/* tp_doc */
+	0,					/* tp_traverse */
+	0,					/* tp_clear */
+	(richcmpfunc)sortwrapper_richcompare,	/* tp_richcompare */
+};
+
+
+static PyObject *
+sortwrapper_richcompare(sortwrapperobject *a, sortwrapperobject *b, int op)
+{
+	if (!PyObject_TypeCheck(b, &sortwrapper_type)) {
+		PyErr_SetString(PyExc_TypeError,
+			"expected a sortwrapperobject");
+		return NULL;
+	}
+	return PyObject_RichCompare(a->key, b->key, op);
+}
+
+static void
+sortwrapper_dealloc(sortwrapperobject *so)
+{
+	Py_XDECREF(so->key);
+	Py_XDECREF(so->value);
+	PyObject_Del(so);
+}
+
+/* Returns a new reference to a sortwrapper.
+   Consumes the references to the two underlying objects. */
+
+static PyObject *
+build_sortwrapper(PyObject *key, PyObject *value)
+{
+	sortwrapperobject *so;
+
+	so = PyObject_New(sortwrapperobject, &sortwrapper_type);
+	if (so == NULL)
+		return NULL;
+	so->key = key;
+	so->value = value;
+	return (PyObject *)so;
+}
+
+/* Returns a new reference to the value underlying the wrapper. */
+static PyObject *
+sortwrapper_getvalue(PyObject *so)
+{
+	PyObject *value;
+
+	if (!PyObject_TypeCheck(so, &sortwrapper_type)) {
+		PyErr_SetString(PyExc_TypeError,
+			"expected a sortwrapperobject");
+		return NULL;
+	}
+	value = ((sortwrapperobject *)so)->value;
+	Py_INCREF(value);
+	return value;
+}
+
+/* Wrapper for user specified cmp functions in combination with a
+   specified key function.  Makes sure the cmp function is presented
+   with the actual key instead of the sortwrapper */
+
+typedef struct {
+	PyObject_HEAD
+	PyObject *func;
+} cmpwrapperobject;
+
+static void
+cmpwrapper_dealloc(cmpwrapperobject *co)
+{
+	Py_XDECREF(co->func);
+	PyObject_Del(co);
+}
+
+static PyObject *
+cmpwrapper_call(cmpwrapperobject *co, PyObject *args, PyObject *kwds)
+{
+	PyObject *x, *y, *xx, *yy;
+
+	if (!PyArg_UnpackTuple(args, "", 2, 2, &x, &y))
+		return NULL;
+	if (!PyObject_TypeCheck(x, &sortwrapper_type) ||
+	    !PyObject_TypeCheck(y, &sortwrapper_type)) {
+		PyErr_SetString(PyExc_TypeError,
+			"expected a sortwrapperobject");
+		return NULL;
+	}
+	xx = ((sortwrapperobject *)x)->key;
+	yy = ((sortwrapperobject *)y)->key;
+	return PyObject_CallFunctionObjArgs(co->func, xx, yy, NULL);
+}
+
+PyDoc_STRVAR(cmpwrapper_doc, "cmp() wrapper for sort with custom keys.");
+
+static PyTypeObject cmpwrapper_type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,					/* ob_size */
+	"cmpwrapper",				/* tp_name */
+	sizeof(cmpwrapperobject),		/* tp_basicsize */
+	0,					/* tp_itemsize */
+	/* methods */
+	(destructor)cmpwrapper_dealloc,		/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	0,					/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	(ternaryfunc)cmpwrapper_call,		/* tp_call */
+	0,					/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT,			/* tp_flags */
+	cmpwrapper_doc,				/* tp_doc */
+};
+
+static PyObject *
+build_cmpwrapper(PyObject *cmpfunc)
+{
+	cmpwrapperobject *co;
+
+	co = PyObject_New(cmpwrapperobject, &cmpwrapper_type);
+	if (co == NULL)
+		return NULL;
+	Py_INCREF(cmpfunc);
+	co->func = cmpfunc;
+	return (PyObject *)co;
+}
+
+/* An adaptive, stable, natural mergesort.  See listsort.txt.
+ * Returns Py_None on success, NULL on error.  Even in case of error, the
+ * list will be some permutation of its input state (nothing is lost or
+ * duplicated).
+ */
+static PyObject *
+listsort(PyListObject *self, PyObject *args, PyObject *kwds)
+{
+	MergeState ms;
+	PyObject **lo, **hi;
+	Py_ssize_t nremaining;
+	Py_ssize_t minrun;
+	Py_ssize_t saved_ob_size, saved_allocated;
+	PyObject **saved_ob_item;
+	PyObject **final_ob_item;
+	PyObject *compare = NULL;
+	PyObject *result = NULL;	/* guilty until proved innocent */
+	int reverse = 0;
+	PyObject *keyfunc = NULL;
+	Py_ssize_t i;
+	PyObject *key, *value, *kvpair;
+	static char *kwlist[] = {"cmp", "key", "reverse", 0};
+
+	assert(self != NULL);
+	assert (PyList_Check(self));
+	if (args != NULL) {
+		if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOi:sort",
+			kwlist, &compare, &keyfunc, &reverse))
+			return NULL;
+	}
+	if (compare == Py_None)
+		compare = NULL;
+	if (keyfunc == Py_None)
+		keyfunc = NULL;
+	if (compare != NULL && keyfunc != NULL) {
+		compare = build_cmpwrapper(compare);
+		if (compare == NULL)
+			return NULL;
+	} else
+		Py_XINCREF(compare);
+
+	/* The list is temporarily made empty, so that mutations performed
+	 * by comparison functions can't affect the slice of memory we're
+	 * sorting (allowing mutations during sorting is a core-dump
+	 * factory, since ob_item may change).
+	 */
+	saved_ob_size = self->ob_size;
+	saved_ob_item = self->ob_item;
+	saved_allocated = self->allocated;
+	self->ob_size = 0;
+	self->ob_item = NULL;
+	self->allocated = -1; /* any operation will reset it to >= 0 */
+
+	if (keyfunc != NULL) {
+		for (i=0 ; i < saved_ob_size ; i++) {
+			value = saved_ob_item[i];
+			key = PyObject_CallFunctionObjArgs(keyfunc, value,
+							   NULL);
+			if (key == NULL) {
+				for (i=i-1 ; i>=0 ; i--) {
+					kvpair = saved_ob_item[i];
+					value = sortwrapper_getvalue(kvpair);
+					saved_ob_item[i] = value;
+					Py_DECREF(kvpair);
+				}
+				goto dsu_fail;
+			}
+			kvpair = build_sortwrapper(key, value);
+			if (kvpair == NULL)
+				goto dsu_fail;
+			saved_ob_item[i] = kvpair;
+		}
+	}
+
+	/* Reverse sort stability achieved by initially reversing the list,
+	applying a stable forward sort, then reversing the final result. */
+	if (reverse && saved_ob_size > 1)
+		reverse_slice(saved_ob_item, saved_ob_item + saved_ob_size);
+
+	merge_init(&ms, compare);
+
+	nremaining = saved_ob_size;
+	if (nremaining < 2)
+		goto succeed;
+
+	/* March over the array once, left to right, finding natural runs,
+	 * and extending short natural runs to minrun elements.
+	 */
+	lo = saved_ob_item;
+	hi = lo + nremaining;
+	minrun = merge_compute_minrun(nremaining);
+	do {
+		int descending;
+		Py_ssize_t n;
+
+		/* Identify next run. */
+		n = count_run(lo, hi, compare, &descending);
+		if (n < 0)
+			goto fail;
+		if (descending)
+			reverse_slice(lo, lo + n);
+		/* If short, extend to min(minrun, nremaining). */
+		if (n < minrun) {
+			const Py_ssize_t force = nremaining <= minrun ?
+	 			  	  nremaining : minrun;
+			if (binarysort(lo, lo + force, lo + n, compare) < 0)
+				goto fail;
+			n = force;
+		}
+		/* Push run onto pending-runs stack, and maybe merge. */
+		assert(ms.n < MAX_MERGE_PENDING);
+		ms.pending[ms.n].base = lo;
+		ms.pending[ms.n].len = n;
+		++ms.n;
+		if (merge_collapse(&ms) < 0)
+			goto fail;
+		/* Advance to find next run. */
+		lo += n;
+		nremaining -= n;
+	} while (nremaining);
+	assert(lo == hi);
+
+	if (merge_force_collapse(&ms) < 0)
+		goto fail;
+	assert(ms.n == 1);
+	assert(ms.pending[0].base == saved_ob_item);
+	assert(ms.pending[0].len == saved_ob_size);
+
+succeed:
+	result = Py_None;
+fail:
+	if (keyfunc != NULL) {
+		for (i=0 ; i < saved_ob_size ; i++) {
+			kvpair = saved_ob_item[i];
+			value = sortwrapper_getvalue(kvpair);
+			saved_ob_item[i] = value;
+			Py_DECREF(kvpair);
+		}
+	}
+
+	if (self->allocated != -1 && result != NULL) {
+		/* The user mucked with the list during the sort,
+		 * and we don't already have another error to report.
+		 */
+		PyErr_SetString(PyExc_ValueError, "list modified during sort");
+		result = NULL;
+	}
+
+	if (reverse && saved_ob_size > 1)
+		reverse_slice(saved_ob_item, saved_ob_item + saved_ob_size);
+
+	merge_freemem(&ms);
+
+dsu_fail:
+	final_ob_item = self->ob_item;
+	i = self->ob_size;
+	self->ob_size = saved_ob_size;
+	self->ob_item = saved_ob_item;
+	self->allocated = saved_allocated;
+	if (final_ob_item != NULL) {
+		/* we cannot use list_clear() for this because it does not
+		   guarantee that the list is really empty when it returns */
+		while (--i >= 0) {
+			Py_XDECREF(final_ob_item[i]);
+		}
+		PyMem_FREE(final_ob_item);
+	}
+	Py_XDECREF(compare);
+	Py_XINCREF(result);
+	return result;
+}
+#undef IFLT
+#undef ISLT
+
+int
+PyList_Sort(PyObject *v)
+{
+	if (v == NULL || !PyList_Check(v)) {
+		PyErr_BadInternalCall();
+		return -1;
+	}
+	v = listsort((PyListObject *)v, (PyObject *)NULL, (PyObject *)NULL);
+	if (v == NULL)
+		return -1;
+	Py_DECREF(v);
+	return 0;
+}
+
+static PyObject *
+listreverse(PyListObject *self)
+{
+	if (self->ob_size > 1)
+		reverse_slice(self->ob_item, self->ob_item + self->ob_size);
+	Py_RETURN_NONE;
+}
+
+int
+PyList_Reverse(PyObject *v)
+{
+	PyListObject *self = (PyListObject *)v;
+
+	if (v == NULL || !PyList_Check(v)) {
+		PyErr_BadInternalCall();
+		return -1;
+	}
+	if (self->ob_size > 1)
+		reverse_slice(self->ob_item, self->ob_item + self->ob_size);
+	return 0;
+}
+
+PyObject *
+PyList_AsTuple(PyObject *v)
+{
+	PyObject *w;
+	PyObject **p;
+	Py_ssize_t n;
+	if (v == NULL || !PyList_Check(v)) {
+		PyErr_BadInternalCall();
+		return NULL;
+	}
+	n = ((PyListObject *)v)->ob_size;
+	w = PyTuple_New(n);
+	if (w == NULL)
+		return NULL;
+	p = ((PyTupleObject *)w)->ob_item;
+	memcpy((void *)p,
+	       (void *)((PyListObject *)v)->ob_item,
+	       n*sizeof(PyObject *));
+	while (--n >= 0) {
+		Py_INCREF(*p);
+		p++;
+	}
+	return w;
+}
+
+static PyObject *
+listindex(PyListObject *self, PyObject *args)
+{
+	Py_ssize_t i, start=0, stop=self->ob_size;
+	PyObject *v;
+
+	if (!PyArg_ParseTuple(args, "O|O&O&:index", &v,
+	                            _PyEval_SliceIndex, &start,
+	                            _PyEval_SliceIndex, &stop))
+		return NULL;
+	if (start < 0) {
+		start += self->ob_size;
+		if (start < 0)
+			start = 0;
+	}
+	if (stop < 0) {
+		stop += self->ob_size;
+		if (stop < 0)
+			stop = 0;
+	}
+	for (i = start; i < stop && i < self->ob_size; i++) {
+		int cmp = PyObject_RichCompareBool(self->ob_item[i], v, Py_EQ);
+		if (cmp > 0)
+			return PyInt_FromSsize_t(i);
+		else if (cmp < 0)
+			return NULL;
+	}
+	PyErr_SetString(PyExc_ValueError, "list.index(x): x not in list");
+	return NULL;
+}
+
+static PyObject *
+listcount(PyListObject *self, PyObject *v)
+{
+	Py_ssize_t count = 0;
+	Py_ssize_t i;
+
+	for (i = 0; i < self->ob_size; i++) {
+		int cmp = PyObject_RichCompareBool(self->ob_item[i], v, Py_EQ);
+		if (cmp > 0)
+			count++;
+		else if (cmp < 0)
+			return NULL;
+	}
+	return PyInt_FromSsize_t(count);
+}
+
+static PyObject *
+listremove(PyListObject *self, PyObject *v)
+{
+	Py_ssize_t i;
+
+	for (i = 0; i < self->ob_size; i++) {
+		int cmp = PyObject_RichCompareBool(self->ob_item[i], v, Py_EQ);
+		if (cmp > 0) {
+			if (list_ass_slice(self, i, i+1,
+					   (PyObject *)NULL) == 0)
+				Py_RETURN_NONE;
+			return NULL;
+		}
+		else if (cmp < 0)
+			return NULL;
+	}
+	PyErr_SetString(PyExc_ValueError, "list.remove(x): x not in list");
+	return NULL;
+}
+
+static int
+list_traverse(PyListObject *o, visitproc visit, void *arg)
+{
+	Py_ssize_t i;
+
+	for (i = o->ob_size; --i >= 0; )
+		Py_VISIT(o->ob_item[i]);
+	return 0;
+}
+
+static PyObject *
+list_richcompare(PyObject *v, PyObject *w, int op)
+{
+	PyListObject *vl, *wl;
+	Py_ssize_t i;
+
+	if (!PyList_Check(v) || !PyList_Check(w)) {
+		Py_INCREF(Py_NotImplemented);
+		return Py_NotImplemented;
+	}
+
+	vl = (PyListObject *)v;
+	wl = (PyListObject *)w;
+
+	if (vl->ob_size != wl->ob_size && (op == Py_EQ || op == Py_NE)) {
+		/* Shortcut: if the lengths differ, the lists differ */
+		PyObject *res;
+		if (op == Py_EQ)
+			res = Py_False;
+		else
+			res = Py_True;
+		Py_INCREF(res);
+		return res;
+	}
+
+	/* Search for the first index where items are different */
+	for (i = 0; i < vl->ob_size && i < wl->ob_size; i++) {
+		int k = PyObject_RichCompareBool(vl->ob_item[i],
+						 wl->ob_item[i], Py_EQ);
+		if (k < 0)
+			return NULL;
+		if (!k)
+			break;
+	}
+
+	if (i >= vl->ob_size || i >= wl->ob_size) {
+		/* No more items to compare -- compare sizes */
+		Py_ssize_t vs = vl->ob_size;
+		Py_ssize_t ws = wl->ob_size;
+		int cmp;
+		PyObject *res;
+		switch (op) {
+		case Py_LT: cmp = vs <  ws; break;
+		case Py_LE: cmp = vs <= ws; break;
+		case Py_EQ: cmp = vs == ws; break;
+		case Py_NE: cmp = vs != ws; break;
+		case Py_GT: cmp = vs >  ws; break;
+		case Py_GE: cmp = vs >= ws; break;
+		default: return NULL; /* cannot happen */
+		}
+		if (cmp)
+			res = Py_True;
+		else
+			res = Py_False;
+		Py_INCREF(res);
+		return res;
+	}
+
+	/* We have an item that differs -- shortcuts for EQ/NE */
+	if (op == Py_EQ) {
+		Py_INCREF(Py_False);
+		return Py_False;
+	}
+	if (op == Py_NE) {
+		Py_INCREF(Py_True);
+		return Py_True;
+	}
+
+	/* Compare the final item again using the proper operator */
+	return PyObject_RichCompare(vl->ob_item[i], wl->ob_item[i], op);
+}
+
+static int
+list_init(PyListObject *self, PyObject *args, PyObject *kw)
+{
+	PyObject *arg = NULL;
+	static char *kwlist[] = {"sequence", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(args, kw, "|O:list", kwlist, &arg))
+		return -1;
+
+	/* Verify list invariants established by PyType_GenericAlloc() */
+	assert(0 <= self->ob_size);
+	assert(self->ob_size <= self->allocated || self->allocated == -1);
+	assert(self->ob_item != NULL ||
+	       self->allocated == 0 || self->allocated == -1);
+
+	/* Empty previous contents */
+	if (self->ob_item != NULL) {
+		(void)list_clear(self);
+	}
+	if (arg != NULL) {
+		PyObject *rv = listextend(self, arg);
+		if (rv == NULL)
+			return -1;
+		Py_DECREF(rv);
+	}
+	return 0;
+}
+
+static long
+list_nohash(PyObject *self)
+{
+	PyErr_SetString(PyExc_TypeError, "list objects are unhashable");
+	return -1;
+}
+
+static PyObject *list_iter(PyObject *seq);
+static PyObject *list_reversed(PyListObject* seq, PyObject* unused);
+
+PyDoc_STRVAR(getitem_doc,
+"x.__getitem__(y) <==> x[y]");
+PyDoc_STRVAR(reversed_doc,
+"L.__reversed__() -- return a reverse iterator over the list");
+PyDoc_STRVAR(append_doc,
+"L.append(object) -- append object to end");
+PyDoc_STRVAR(extend_doc,
+"L.extend(iterable) -- extend list by appending elements from the iterable");
+PyDoc_STRVAR(insert_doc,
+"L.insert(index, object) -- insert object before index");
+PyDoc_STRVAR(pop_doc,
+"L.pop([index]) -> item -- remove and return item at index (default last)");
+PyDoc_STRVAR(remove_doc,
+"L.remove(value) -- remove first occurrence of value");
+PyDoc_STRVAR(index_doc,
+"L.index(value, [start, [stop]]) -> integer -- return first index of value");
+PyDoc_STRVAR(count_doc,
+"L.count(value) -> integer -- return number of occurrences of value");
+PyDoc_STRVAR(reverse_doc,
+"L.reverse() -- reverse *IN PLACE*");
+PyDoc_STRVAR(sort_doc,
+"L.sort(cmp=None, key=None, reverse=False) -- stable sort *IN PLACE*;\n\
+cmp(x, y) -> -1, 0, 1");
+
+static PyObject *list_subscript(PyListObject*, PyObject*);
+
+static PyMethodDef list_methods[] = {
+	{"__getitem__", (PyCFunction)list_subscript, METH_O|METH_COEXIST, getitem_doc},
+	{"__reversed__",(PyCFunction)list_reversed, METH_NOARGS, reversed_doc},
+	{"append",	(PyCFunction)listappend,  METH_O, append_doc},
+	{"insert",	(PyCFunction)listinsert,  METH_VARARGS, insert_doc},
+	{"extend",      (PyCFunction)listextend,  METH_O, extend_doc},
+	{"pop",		(PyCFunction)listpop, 	  METH_VARARGS, pop_doc},
+	{"remove",	(PyCFunction)listremove,  METH_O, remove_doc},
+	{"index",	(PyCFunction)listindex,   METH_VARARGS, index_doc},
+	{"count",	(PyCFunction)listcount,   METH_O, count_doc},
+	{"reverse",	(PyCFunction)listreverse, METH_NOARGS, reverse_doc},
+	{"sort",	(PyCFunction)listsort, 	  METH_VARARGS | METH_KEYWORDS, sort_doc},
+ 	{NULL,		NULL}		/* sentinel */
+};
+
+static PySequenceMethods list_as_sequence = {
+	(lenfunc)list_length,			/* sq_length */
+	(binaryfunc)list_concat,		/* sq_concat */
+	(ssizeargfunc)list_repeat,		/* sq_repeat */
+	(ssizeargfunc)list_item,		/* sq_item */
+	(ssizessizeargfunc)list_slice,		/* sq_slice */
+	(ssizeobjargproc)list_ass_item,		/* sq_ass_item */
+	(ssizessizeobjargproc)list_ass_slice,	/* sq_ass_slice */
+	(objobjproc)list_contains,		/* sq_contains */
+	(binaryfunc)list_inplace_concat,	/* sq_inplace_concat */
+	(ssizeargfunc)list_inplace_repeat,	/* sq_inplace_repeat */
+};
+
+PyDoc_STRVAR(list_doc,
+"list() -> new list\n"
+"list(sequence) -> new list initialized from sequence's items");
+
+
+static PyObject *
+list_subscript(PyListObject* self, PyObject* item)
+{
+	if (PyIndex_Check(item)) {
+		Py_ssize_t i;
+		i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+		if (i == -1 && PyErr_Occurred())
+			return NULL;
+		if (i < 0)
+			i += PyList_GET_SIZE(self);
+		return list_item(self, i);
+	}
+	else if (PySlice_Check(item)) {
+		Py_ssize_t start, stop, step, slicelength, cur, i;
+		PyObject* result;
+		PyObject* it;
+		PyObject **src, **dest;
+
+		if (PySlice_GetIndicesEx((PySliceObject*)item, self->ob_size,
+				 &start, &stop, &step, &slicelength) < 0) {
+			return NULL;
+		}
+
+		if (slicelength <= 0) {
+			return PyList_New(0);
+		}
+		else {
+			result = PyList_New(slicelength);
+			if (!result) return NULL;
+
+			src = self->ob_item;
+			dest = ((PyListObject *)result)->ob_item;
+			for (cur = start, i = 0; i < slicelength;
+			     cur += step, i++) {
+				it = src[cur];
+				Py_INCREF(it);
+				dest[i] = it;
+			}
+
+			return result;
+		}
+	}
+	else {
+		PyErr_SetString(PyExc_TypeError,
+				"list indices must be integers");
+		return NULL;
+	}
+}
+
+static int
+list_ass_subscript(PyListObject* self, PyObject* item, PyObject* value)
+{
+	if (PyIndex_Check(item)) {
+		Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+		if (i == -1 && PyErr_Occurred())
+			return -1;
+		if (i < 0)
+			i += PyList_GET_SIZE(self);
+		return list_ass_item(self, i, value);
+	}
+	else if (PySlice_Check(item)) {
+		Py_ssize_t start, stop, step, slicelength;
+
+		if (PySlice_GetIndicesEx((PySliceObject*)item, self->ob_size,
+				 &start, &stop, &step, &slicelength) < 0) {
+			return -1;
+		}
+
+		/* treat L[slice(a,b)] = v _exactly_ like L[a:b] = v */
+		if (step == 1 && ((PySliceObject*)item)->step == Py_None)
+			return list_ass_slice(self, start, stop, value);
+
+		if (value == NULL) {
+			/* delete slice */
+			PyObject **garbage;
+			Py_ssize_t cur, i;
+
+			if (slicelength <= 0)
+				return 0;
+
+			if (step < 0) {
+				stop = start + 1;
+				start = stop + step*(slicelength - 1) - 1;
+				step = -step;
+			}
+
+			garbage = (PyObject**)
+				PyMem_MALLOC(slicelength*sizeof(PyObject*));
+			if (!garbage) {
+				PyErr_NoMemory();
+				return -1;
+			}
+
+			/* drawing pictures might help
+			   understand these for loops */
+			for (cur = start, i = 0;
+			     cur < stop;
+			     cur += step, i++) {
+				Py_ssize_t lim = step;
+
+				garbage[i] = PyList_GET_ITEM(self, cur);
+
+				if (cur + step >= self->ob_size) {
+					lim = self->ob_size - cur - 1;
+				}
+
+				memmove(self->ob_item + cur - i,
+					self->ob_item + cur + 1,
+					lim * sizeof(PyObject *));
+			}
+
+			for (cur = start + slicelength*step + 1;
+			     cur < self->ob_size; cur++) {
+				PyList_SET_ITEM(self, cur - slicelength,
+						PyList_GET_ITEM(self, cur));
+			}
+
+			self->ob_size -= slicelength;
+			list_resize(self, self->ob_size);
+
+			for (i = 0; i < slicelength; i++) {
+				Py_DECREF(garbage[i]);
+			}
+			PyMem_FREE(garbage);
+
+			return 0;
+		}
+		else {
+			/* assign slice */
+			PyObject **garbage, *ins, *seq, **seqitems, **selfitems;
+			Py_ssize_t cur, i;
+
+			/* protect against a[::-1] = a */
+			if (self == (PyListObject*)value) {
+				seq = list_slice((PyListObject*)value, 0,
+						   PyList_GET_SIZE(value));
+			}
+			else {
+				seq = PySequence_Fast(value,
+					"must assign iterable to extended slice");
+			}
+			if (!seq)
+				return -1;
+
+			if (PySequence_Fast_GET_SIZE(seq) != slicelength) {
+				PyErr_Format(PyExc_ValueError,
+            "attempt to assign sequence of size %zd to extended slice of size %zd",
+					     PySequence_Fast_GET_SIZE(seq),
+					     slicelength);
+				Py_DECREF(seq);
+				return -1;
+			}
+
+			if (!slicelength) {
+				Py_DECREF(seq);
+				return 0;
+			}
+
+			garbage = (PyObject**)
+				PyMem_MALLOC(slicelength*sizeof(PyObject*));
+			if (!garbage) {
+				Py_DECREF(seq);
+				PyErr_NoMemory();
+				return -1;
+			}
+
+			selfitems = self->ob_item;
+			seqitems = PySequence_Fast_ITEMS(seq);
+			for (cur = start, i = 0; i < slicelength;
+			     cur += step, i++) {
+				garbage[i] = selfitems[cur];
+				ins = seqitems[i];
+				Py_INCREF(ins);
+				selfitems[cur] = ins;
+			}
+
+			for (i = 0; i < slicelength; i++) {
+				Py_DECREF(garbage[i]);
+			}
+
+			PyMem_FREE(garbage);
+			Py_DECREF(seq);
+
+			return 0;
+		}
+	}
+	else {
+		PyErr_SetString(PyExc_TypeError,
+				"list indices must be integers");
+		return -1;
+	}
+}
+
+static PyMappingMethods list_as_mapping = {
+	(lenfunc)list_length,
+	(binaryfunc)list_subscript,
+	(objobjargproc)list_ass_subscript
+};
+
+PyTypeObject PyList_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,
+	"list",
+	sizeof(PyListObject),
+	0,
+	(destructor)list_dealloc,		/* tp_dealloc */
+	(printfunc)list_print,			/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	(reprfunc)list_repr,			/* tp_repr */
+	0,					/* tp_as_number */
+	&list_as_sequence,			/* tp_as_sequence */
+	&list_as_mapping,			/* tp_as_mapping */
+	list_nohash,				/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+		Py_TPFLAGS_BASETYPE,		/* tp_flags */
+ 	list_doc,				/* tp_doc */
+ 	(traverseproc)list_traverse,		/* tp_traverse */
+ 	(inquiry)list_clear,			/* tp_clear */
+	list_richcompare,			/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	list_iter,				/* tp_iter */
+	0,					/* tp_iternext */
+	list_methods,				/* tp_methods */
+	0,					/* tp_members */
+	0,					/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	(initproc)list_init,			/* tp_init */
+	PyType_GenericAlloc,			/* tp_alloc */
+	PyType_GenericNew,			/* tp_new */
+	PyObject_GC_Del,			/* tp_free */
+};
+
+
+/*********************** List Iterator **************************/
+
+typedef struct {
+	PyObject_HEAD
+	long it_index;
+	PyListObject *it_seq; /* Set to NULL when iterator is exhausted */
+} listiterobject;
+
+static PyObject *list_iter(PyObject *);
+static void listiter_dealloc(listiterobject *);
+static int listiter_traverse(listiterobject *, visitproc, void *);
+static PyObject *listiter_next(listiterobject *);
+static PyObject *listiter_len(listiterobject *);
+
+PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
+
+static PyMethodDef listiter_methods[] = {
+	{"__length_hint__", (PyCFunction)listiter_len, METH_NOARGS, length_hint_doc},
+ 	{NULL,		NULL}		/* sentinel */
+};
+
+PyTypeObject PyListIter_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,					/* ob_size */
+	"listiterator",				/* tp_name */
+	sizeof(listiterobject),			/* tp_basicsize */
+	0,					/* tp_itemsize */
+	/* methods */
+	(destructor)listiter_dealloc,		/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	0,					/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+	0,					/* tp_doc */
+	(traverseproc)listiter_traverse,	/* tp_traverse */
+	0,					/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	PyObject_SelfIter,			/* tp_iter */
+	(iternextfunc)listiter_next,		/* tp_iternext */
+	listiter_methods,			/* tp_methods */
+	0,					/* tp_members */
+};
+
+
+static PyObject *
+list_iter(PyObject *seq)
+{
+	listiterobject *it;
+
+	if (!PyList_Check(seq)) {
+		PyErr_BadInternalCall();
+		return NULL;
+	}
+	it = PyObject_GC_New(listiterobject, &PyListIter_Type);
+	if (it == NULL)
+		return NULL;
+	it->it_index = 0;
+	Py_INCREF(seq);
+	it->it_seq = (PyListObject *)seq;
+	_PyObject_GC_TRACK(it);
+	return (PyObject *)it;
+}
+
+static void
+listiter_dealloc(listiterobject *it)
+{
+	_PyObject_GC_UNTRACK(it);
+	Py_XDECREF(it->it_seq);
+	PyObject_GC_Del(it);
+}
+
+static int
+listiter_traverse(listiterobject *it, visitproc visit, void *arg)
+{
+	Py_VISIT(it->it_seq);
+	return 0;
+}
+
+static PyObject *
+listiter_next(listiterobject *it)
+{
+	PyListObject *seq;
+	PyObject *item;
+
+	assert(it != NULL);
+	seq = it->it_seq;
+	if (seq == NULL)
+		return NULL;
+	assert(PyList_Check(seq));
+
+	if (it->it_index < PyList_GET_SIZE(seq)) {
+		item = PyList_GET_ITEM(seq, it->it_index);
+		++it->it_index;
+		Py_INCREF(item);
+		return item;
+	}
+
+	Py_DECREF(seq);
+	it->it_seq = NULL;
+	return NULL;
+}
+
+static PyObject *
+listiter_len(listiterobject *it)
+{
+	Py_ssize_t len;
+	if (it->it_seq) {
+		len = PyList_GET_SIZE(it->it_seq) - it->it_index;
+		if (len >= 0)
+			return PyInt_FromSsize_t(len);
+	}
+	return PyInt_FromLong(0);
+}
+/*********************** List Reverse Iterator **************************/
+
+typedef struct {
+	PyObject_HEAD
+	Py_ssize_t it_index;
+	PyListObject *it_seq; /* Set to NULL when iterator is exhausted */
+} listreviterobject;
+
+static PyObject *list_reversed(PyListObject *, PyObject *);
+static void listreviter_dealloc(listreviterobject *);
+static int listreviter_traverse(listreviterobject *, visitproc, void *);
+static PyObject *listreviter_next(listreviterobject *);
+static Py_ssize_t listreviter_len(listreviterobject *);
+
+static PySequenceMethods listreviter_as_sequence = {
+	(lenfunc)listreviter_len,	/* sq_length */
+	0,				/* sq_concat */
+};
+
+PyTypeObject PyListRevIter_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,					/* ob_size */
+	"listreverseiterator",			/* tp_name */
+	sizeof(listreviterobject),		/* tp_basicsize */
+	0,					/* tp_itemsize */
+	/* methods */
+	(destructor)listreviter_dealloc,	/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	0,					/* tp_repr */
+	0,					/* tp_as_number */
+	&listreviter_as_sequence,		/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+	0,					/* tp_doc */
+	(traverseproc)listreviter_traverse,	/* tp_traverse */
+	0,					/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	PyObject_SelfIter,			/* tp_iter */
+	(iternextfunc)listreviter_next,		/* tp_iternext */
+	0,
+};
+
+static PyObject *
+list_reversed(PyListObject *seq, PyObject *unused)
+{
+	listreviterobject *it;
+
+	it = PyObject_GC_New(listreviterobject, &PyListRevIter_Type);
+	if (it == NULL)
+		return NULL;
+	assert(PyList_Check(seq));
+	it->it_index = PyList_GET_SIZE(seq) - 1;
+	Py_INCREF(seq);
+	it->it_seq = seq;
+	PyObject_GC_Track(it);
+	return (PyObject *)it;
+}
+
+static void
+listreviter_dealloc(listreviterobject *it)
+{
+	PyObject_GC_UnTrack(it);
+	Py_XDECREF(it->it_seq);
+	PyObject_GC_Del(it);
+}
+
+static int
+listreviter_traverse(listreviterobject *it, visitproc visit, void *arg)
+{
+	Py_VISIT(it->it_seq);
+	return 0;
+}
+
+static PyObject *
+listreviter_next(listreviterobject *it)
+{
+	PyObject *item;
+	Py_ssize_t index = it->it_index;
+	PyListObject *seq = it->it_seq;
+
+	if (index>=0 && index < PyList_GET_SIZE(seq)) {
+		item = PyList_GET_ITEM(seq, index);
+		it->it_index--;
+		Py_INCREF(item);
+		return item;
+	}
+	it->it_index = -1;
+	if (seq != NULL) {
+		it->it_seq = NULL;
+		Py_DECREF(seq);
+	}
+	return NULL;
+}
+
+static Py_ssize_t
+listreviter_len(listreviterobject *it)
+{
+	Py_ssize_t len = it->it_index + 1;
+	if (it->it_seq == NULL || PyList_GET_SIZE(it->it_seq) < len)
+		return 0;
+	return len;
+}
+

Added: vendor/Python/current/Objects/listsort.txt
===================================================================
--- vendor/Python/current/Objects/listsort.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Objects/listsort.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,677 @@
+Intro
+-----
+This describes an adaptive, stable, natural mergesort, modestly called
+timsort (hey, I earned it <wink>).  It has supernatural performance on many
+kinds of partially ordered arrays (less than lg(N!) comparisons needed, and
+as few as N-1), yet as fast as Python's previous highly tuned samplesort
+hybrid on random arrays.
+
+In a nutshell, the main routine marches over the array once, left to right,
+alternately identifying the next run, then merging it into the previous
+runs "intelligently".  Everything else is complication for speed, and some
+hard-won measure of memory efficiency.
+
+
+Comparison with Python's Samplesort Hybrid
+------------------------------------------
++ timsort can require a temp array containing as many as N//2 pointers,
+  which means as many as 2*N extra bytes on 32-bit boxes.  It can be
+  expected to require a temp array this large when sorting random data; on
+  data with significant structure, it may get away without using any extra
+  heap memory.  This appears to be the strongest argument against it, but
+  compared to the size of an object, 2 temp bytes worst-case (also expected-
+  case for random data) doesn't scare me much.
+
+  It turns out that Perl is moving to a stable mergesort, and the code for
+  that appears always to require a temp array with room for at least N
+  pointers. (Note that I wouldn't want to do that even if space weren't an
+  issue; I believe its efforts at memory frugality also save timsort
+  significant pointer-copying costs, and allow it to have a smaller working
+  set.)
+
++ Across about four hours of generating random arrays, and sorting them
+  under both methods, samplesort required about 1.5% more comparisons
+  (the program is at the end of this file).
+
++ In real life, this may be faster or slower on random arrays than
+  samplesort was, depending on platform quirks.  Since it does fewer
+  comparisons on average, it can be expected to do better the more
+  expensive a comparison function is.  OTOH, it does more data movement
+  (pointer copying) than samplesort, and that may negate its small
+  comparison advantage (depending on platform quirks) unless comparison
+  is very expensive.
+
++ On arrays with many kinds of pre-existing order, this blows samplesort out
+  of the water.  It's significantly faster than samplesort even on some
+  cases samplesort was special-casing the snot out of.  I believe that lists
+  very often do have exploitable partial order in real life, and this is the
+  strongest argument in favor of timsort (indeed, samplesort's special cases
+  for extreme partial order are appreciated by real users, and timsort goes
+  much deeper than those, in particular naturally covering every case where
+  someone has suggested "and it would be cool if list.sort() had a special
+  case for this too ... and for that ...").
+
++ Here are exact comparison counts across all the tests in sortperf.py,
+  when run with arguments "15 20 1".
+
+  Column Key:
+      *sort: random data
+      \sort: descending data
+      /sort: ascending data
+      3sort: ascending, then 3 random exchanges
+      +sort: ascending, then 10 random at the end
+      ~sort: many duplicates
+      =sort: all equal
+      !sort: worst case scenario
+
+  First the trivial cases, trivial for samplesort because it special-cased
+  them, and trivial for timsort because it naturally works on runs.  Within
+  an "n" block, the first line gives the # of compares done by samplesort,
+  the second line by timsort, and the third line is the percentage by
+  which the samplesort count exceeds the timsort count:
+
+      n   \sort   /sort   =sort
+-------  ------  ------  ------
+  32768   32768   32767   32767  samplesort
+          32767   32767   32767  timsort
+          0.00%   0.00%   0.00%  (samplesort - timsort) / timsort
+
+  65536   65536   65535   65535
+          65535   65535   65535
+          0.00%   0.00%   0.00%
+
+ 131072  131072  131071  131071
+         131071  131071  131071
+          0.00%   0.00%   0.00%
+
+ 262144  262144  262143  262143
+         262143  262143  262143
+          0.00%   0.00%   0.00%
+
+ 524288  524288  524287  524287
+         524287  524287  524287
+          0.00%   0.00%   0.00%
+
+1048576 1048576 1048575 1048575
+        1048575 1048575 1048575
+          0.00%   0.00%   0.00%
+
+  The algorithms are effectively identical in these cases, except that
+  timsort does one less compare in \sort.
+
+  Now for the more interesting cases.  lg(n!) is the information-theoretic
+  limit for the best any comparison-based sorting algorithm can do on
+  average (across all permutations).  When a method gets significantly
+  below that, it's either astronomically lucky, or is finding exploitable
+  structure in the data.
+
+      n   lg(n!)    *sort    3sort     +sort   %sort    ~sort     !sort
+-------  -------   ------   -------  -------  ------  -------  --------
+  32768   444255   453096   453614    32908   452871   130491    469141 old
+                   448885    33016    33007    50426   182083     65534 new
+                    0.94% 1273.92%   -0.30%  798.09%  -28.33%   615.87% %ch from new
+
+  65536   954037   972699   981940    65686   973104   260029   1004607
+                   962991    65821    65808   101667   364341    131070
+                    1.01% 1391.83%   -0.19%  857.15%  -28.63%   666.47%
+
+ 131072  2039137  2101881  2091491   131232  2092894   554790   2161379
+                  2057533   131410   131361   206193   728871    262142
+                    2.16% 1491.58%   -0.10%  915.02%  -23.88%   724.51%
+
+ 262144  4340409  4464460  4403233   262314  4445884  1107842   4584560
+                  4377402   262437   262459   416347  1457945    524286
+                    1.99% 1577.82%   -0.06%  967.83%  -24.01%   774.44%
+
+ 524288  9205096  9453356  9408463   524468  9441930  2218577   9692015
+                  9278734   524580   524633   837947  2916107   1048574
+                   1.88%  1693.52%   -0.03% 1026.79%  -23.92%   824.30%
+
+1048576 19458756 19950272 19838588  1048766 19912134  4430649  20434212
+                 19606028  1048958  1048941  1694896  5832445   2097150
+                    1.76% 1791.27%   -0.02% 1074.83%  -24.03%   874.38%
+
+  Discussion of cases:
+
+  *sort:  There's no structure in random data to exploit, so the theoretical
+  limit is lg(n!).  Both methods get close to that, and timsort is hugging
+  it (indeed, in a *marginal* sense, it's a spectacular improvement --
+  there's only about 1% left before hitting the wall, and timsort knows
+  darned well it's doing compares that won't pay on random data -- but so
+  does the samplesort hybrid).  For contrast, Hoare's original random-pivot
+  quicksort does about 39% more compares than the limit, and the median-of-3
+  variant about 19% more.
+
+  3sort, %sort, and !sort:  No contest; there's structure in this data, but
+  not of the specific kinds samplesort special-cases.  Note that structure
+  in !sort wasn't put there on purpose -- it was crafted as a worst case for
+  a previous quicksort implementation.  That timsort nails it came as a
+  surprise to me (although it's obvious in retrospect).
+
+  +sort:  samplesort special-cases this data, and does a few less compares
+  than timsort.  However, timsort runs this case significantly faster on all
+  boxes we have timings for, because timsort is in the business of merging
+  runs efficiently, while samplesort does much more data movement in this
+  (for it) special case.
+
+  ~sort:  samplesort's special cases for large masses of equal elements are
+  extremely effective on ~sort's specific data pattern, and timsort just
+  isn't going to get close to that, despite that it's clearly getting a
+  great deal of benefit out of the duplicates (the # of compares is much less
+  than lg(n!)).  ~sort has a perfectly uniform distribution of just 4
+  distinct values, and as the distribution gets more skewed, samplesort's
+  equal-element gimmicks become less effective, while timsort's adaptive
+  strategies find more to exploit; in a database supplied by Kevin Altis, a
+  sort on its highly skewed "on which stock exchange does this company's
+  stock trade?" field ran over twice as fast under timsort.
+
+  However, despite that timsort does many more comparisons on ~sort, and
+  that on several platforms ~sort runs highly significantly slower under
+  timsort, on other platforms ~sort runs highly significantly faster under
+  timsort.  No other kind of data has shown this wild x-platform behavior,
+  and we don't have an explanation for it.  The only thing I can think of
+  that could transform what "should be" highly significant slowdowns into
+  highly significant speedups on some boxes are catastrophic cache effects
+  in samplesort.
+
+  But timsort "should be" slower than samplesort on ~sort, so it's hard
+  to count that it isn't on some boxes as a strike against it <wink>.
+
++ Here's the highwater mark for the number of heap-based temp slots (4
+  bytes each on this box) needed by each test, again with arguments
+  "15 20 1":
+
+   2**i  *sort \sort /sort  3sort  +sort  %sort  ~sort  =sort  !sort
+  32768  16384     0     0   6256      0  10821  12288      0  16383
+  65536  32766     0     0  21652      0  31276  24576      0  32767
+ 131072  65534     0     0  17258      0  58112  49152      0  65535
+ 262144 131072     0     0  35660      0 123561  98304      0 131071
+ 524288 262142     0     0  31302      0 212057 196608      0 262143
+1048576 524286     0     0 312438      0 484942 393216      0 524287
+
+  Discussion:  The tests that end up doing (close to) perfectly balanced
+  merges (*sort, !sort) need all N//2 temp slots (or almost all).  ~sort
+  also ends up doing balanced merges, but systematically benefits a lot from
+  the preliminary pre-merge searches described under "Merge Memory" later.
+  %sort approaches having a balanced merge at the end because the random
+  selection of elements to replace is expected to produce an out-of-order
+  element near the midpoint.  \sort, /sort, =sort are the trivial one-run
+  cases, needing no merging at all.  +sort ends up having one very long run
+  and one very short, and so gets all the temp space it needs from the small
+  temparray member of the MergeState struct (note that the same would be
+  true if the new random elements were prefixed to the sorted list instead,
+  but not if they appeared "in the middle").  3sort approaches N//3 temp
+  slots twice, but the run lengths that remain after 3 random exchanges
+  clearly has very high variance.
+
+
+A detailed description of timsort follows.
+
+Runs
+----
+count_run() returns the # of elements in the next run.  A run is either
+"ascending", which means non-decreasing:
+
+    a0 <= a1 <= a2 <= ...
+
+or "descending", which means strictly decreasing:
+
+    a0 > a1 > a2 > ...
+
+Note that a run is always at least 2 long, unless we start at the array's
+last element.
+
+The definition of descending is strict, because the main routine reverses
+a descending run in-place, transforming a descending run into an ascending
+run.  Reversal is done via the obvious fast "swap elements starting at each
+end, and converge at the middle" method, and that can violate stability if
+the slice contains any equal elements.  Using a strict definition of
+descending ensures that a descending run contains distinct elements.
+
+If an array is random, it's very unlikely we'll see long runs.  If a natural
+run contains less than minrun elements (see next section), the main loop
+artificially boosts it to minrun elements, via a stable binary insertion sort
+applied to the right number of array elements following the short natural
+run.  In a random array, *all* runs are likely to be minrun long as a
+result.  This has two primary good effects:
+
+1. Random data strongly tends then toward perfectly balanced (both runs have
+   the same length) merges, which is the most efficient way to proceed when
+   data is random.
+
+2. Because runs are never very short, the rest of the code doesn't make
+   heroic efforts to shave a few cycles off per-merge overheads.  For
+   example, reasonable use of function calls is made, rather than trying to
+   inline everything.  Since there are no more than N/minrun runs to begin
+   with, a few "extra" function calls per merge is barely measurable.
+
+
+Computing minrun
+----------------
+If N < 64, minrun is N.  IOW, binary insertion sort is used for the whole
+array then; it's hard to beat that given the overheads of trying something
+fancier.
+
+When N is a power of 2, testing on random data showed that minrun values of
+16, 32, 64 and 128 worked about equally well.  At 256 the data-movement cost
+in binary insertion sort clearly hurt, and at 8 the increase in the number
+of function calls clearly hurt.  Picking *some* power of 2 is important
+here, so that the merges end up perfectly balanced (see next section).  We
+pick 32 as a good value in the sweet range; picking a value at the low end
+allows the adaptive gimmicks more opportunity to exploit shorter natural
+runs.
+
+Because sortperf.py only tries powers of 2, it took a long time to notice
+that 32 isn't a good choice for the general case!  Consider N=2112:
+
+>>> divmod(2112, 32)
+(66, 0)
+>>>
+
+If the data is randomly ordered, we're very likely to end up with 66 runs
+each of length 32.  The first 64 of these trigger a sequence of perfectly
+balanced merges (see next section), leaving runs of lengths 2048 and 64 to
+merge at the end.  The adaptive gimmicks can do that with fewer than 2048+64
+compares, but it's still more compares than necessary, and-- mergesort's
+bugaboo relative to samplesort --a lot more data movement (O(N) copies just
+to get 64 elements into place).
+
+If we take minrun=33 in this case, then we're very likely to end up with 64
+runs each of length 33, and then all merges are perfectly balanced.  Better!
+
+What we want to avoid is picking minrun such that in
+
+    q, r = divmod(N, minrun)
+
+q is a power of 2 and r>0 (then the last merge only gets r elements into
+place, and r < minrun is small compared to N), or q a little larger than a
+power of 2 regardless of r (then we've got a case similar to "2112", again
+leaving too little work for the last merge to do).
+
+Instead we pick a minrun in range(32, 65) such that N/minrun is exactly a
+power of 2, or if that isn't possible, is close to, but strictly less than,
+a power of 2.  This is easier to do than it may sound:  take the first 6
+bits of N, and add 1 if any of the remaining bits are set.  In fact, that
+rule covers every case in this section, including small N and exact powers
+of 2; merge_compute_minrun() is a deceptively simple function.
+
+
+The Merge Pattern
+-----------------
+In order to exploit regularities in the data, we're merging on natural
+run lengths, and they can become wildly unbalanced.  That's a Good Thing
+for this sort!  It means we have to find a way to manage an assortment of
+potentially very different run lengths, though.
+
+Stability constrains permissible merging patterns.  For example, if we have
+3 consecutive runs of lengths
+
+    A:10000  B:20000  C:10000
+
+we dare not merge A with C first, because if A, B and C happen to contain
+a common element, it would get out of order wrt its occurence(s) in B.  The
+merging must be done as (A+B)+C or A+(B+C) instead.
+
+So merging is always done on two consecutive runs at a time, and in-place,
+although this may require some temp memory (more on that later).
+
+When a run is identified, its base address and length are pushed on a stack
+in the MergeState struct.  merge_collapse() is then called to see whether it
+should merge it with preceding run(s).  We would like to delay merging as
+long as possible in order to exploit patterns that may come up later, but we
+like even more to do merging as soon as possible to exploit that the run just
+found is still high in the memory hierarchy.  We also can't delay merging
+"too long" because it consumes memory to remember the runs that are still
+unmerged, and the stack has a fixed size.
+
+What turned out to be a good compromise maintains two invariants on the
+stack entries, where A, B and C are the lengths of the three righmost not-yet
+merged slices:
+
+1.  A > B+C
+2.  B > C
+
+Note that, by induction, #2 implies the lengths of pending runs form a
+decreasing sequence.  #1 implies that, reading the lengths right to left,
+the pending-run lengths grow at least as fast as the Fibonacci numbers.
+Therefore the stack can never grow larger than about log_base_phi(N) entries,
+where phi = (1+sqrt(5))/2 ~= 1.618.  Thus a small # of stack slots suffice
+for very large arrays.
+
+If A <= B+C, the smaller of A and C is merged with B (ties favor C, for the
+freshness-in-cache reason), and the new run replaces the A,B or B,C entries;
+e.g., if the last 3 entries are
+
+    A:30  B:20  C:10
+
+then B is merged with C, leaving
+
+    A:30  BC:30
+
+on the stack.  Or if they were
+
+    A:500  B:400:  C:1000
+
+then A is merged with B, leaving
+
+    AB:900  C:1000
+
+on the stack.
+
+In both examples, the stack configuration after the merge still violates
+invariant #2, and merge_collapse() goes on to continue merging runs until
+both invariants are satisfied.  As an extreme case, suppose we didn't do the
+minrun gimmick, and natural runs were of lengths 128, 64, 32, 16, 8, 4, 2,
+and 2.  Nothing would get merged until the final 2 was seen, and that would
+trigger 7 perfectly balanced merges.
+
+The thrust of these rules when they trigger merging is to balance the run
+lengths as closely as possible, while keeping a low bound on the number of
+runs we have to remember.  This is maximally effective for random data,
+where all runs are likely to be of (artificially forced) length minrun, and
+then we get a sequence of perfectly balanced merges (with, perhaps, some
+oddballs at the end).
+
+OTOH, one reason this sort is so good for partly ordered data has to do
+with wildly unbalanced run lengths.
+
+
+Merge Memory
+------------
+Merging adjacent runs of lengths A and B in-place is very difficult.
+Theoretical constructions are known that can do it, but they're too difficult
+and slow for practical use.  But if we have temp memory equal to min(A, B),
+it's easy.
+
+If A is smaller (function merge_lo), copy A to a temp array, leave B alone,
+and then we can do the obvious merge algorithm left to right, from the temp
+area and B, starting the stores into where A used to live.  There's always a
+free area in the original area comprising a number of elements equal to the
+number not yet merged from the temp array (trivially true at the start;
+proceed by induction).  The only tricky bit is that if a comparison raises an
+exception, we have to remember to copy the remaining elements back in from
+the temp area, lest the array end up with duplicate entries from B.  But
+that's exactly the same thing we need to do if we reach the end of B first,
+so the exit code is pleasantly common to both the normal and error cases.
+
+If B is smaller (function merge_hi, which is merge_lo's "mirror image"),
+much the same, except that we need to merge right to left, copying B into a
+temp array and starting the stores at the right end of where B used to live.
+
+A refinement:  When we're about to merge adjacent runs A and B, we first do
+a form of binary search (more on that later) to see where B[0] should end up
+in A.  Elements in A preceding that point are already in their final
+positions, effectively shrinking the size of A.  Likewise we also search to
+see where A[-1] should end up in B, and elements of B after that point can
+also be ignored.  This cuts the amount of temp memory needed by the same
+amount.
+
+These preliminary searches may not pay off, and can be expected *not* to
+repay their cost if the data is random.  But they can win huge in all of
+time, copying, and memory savings when they do pay, so this is one of the
+"per-merge overheads" mentioned above that we're happy to endure because
+there is at most one very short run.  It's generally true in this algorithm
+that we're willing to gamble a little to win a lot, even though the net
+expectation is negative for random data.
+
+
+Merge Algorithms
+----------------
+merge_lo() and merge_hi() are where the bulk of the time is spent.  merge_lo
+deals with runs where A <= B, and merge_hi where A > B.  They don't know
+whether the data is clustered or uniform, but a lovely thing about merging
+is that many kinds of clustering "reveal themselves" by how many times in a
+row the winning merge element comes from the same run.  We'll only discuss
+merge_lo here; merge_hi is exactly analogous.
+
+Merging begins in the usual, obvious way, comparing the first element of A
+to the first of B, and moving B[0] to the merge area if it's less than A[0],
+else moving A[0] to the merge area.  Call that the "one pair at a time"
+mode.  The only twist here is keeping track of how many times in a row "the
+winner" comes from the same run.
+
+If that count reaches MIN_GALLOP, we switch to "galloping mode".  Here
+we *search* B for where A[0] belongs, and move over all the B's before
+that point in one chunk to the merge area, then move A[0] to the merge
+area.  Then we search A for where B[0] belongs, and similarly move a
+slice of A in one chunk.  Then back to searching B for where A[0] belongs,
+etc.  We stay in galloping mode until both searches find slices to copy
+less than MIN_GALLOP elements long, at which point we go back to one-pair-
+at-a-time mode.
+
+A refinement:  The MergeState struct contains the value of min_gallop that
+controls when we enter galloping mode, initialized to MIN_GALLOP.
+merge_lo() and merge_hi() adjust this higher when galloping isn't paying
+off, and lower when it is.
+
+
+Galloping
+---------
+Still without loss of generality, assume A is the shorter run.  In galloping
+mode, we first look for A[0] in B.  We do this via "galloping", comparing
+A[0] in turn to B[0], B[1], B[3], B[7], ..., B[2**j - 1], ..., until finding
+the k such that B[2**(k-1) - 1] < A[0] <= B[2**k - 1].  This takes at most
+roughly lg(B) comparisons, and, unlike a straight binary search, favors
+finding the right spot early in B (more on that later).
+
+After finding such a k, the region of uncertainty is reduced to 2**(k-1) - 1
+consecutive elements, and a straight binary search requires exactly k-1
+additional comparisons to nail it.  Then we copy all the B's up to that
+point in one chunk, and then copy A[0].  Note that no matter where A[0]
+belongs in B, the combination of galloping + binary search finds it in no
+more than about 2*lg(B) comparisons.
+
+If we did a straight binary search, we could find it in no more than
+ceiling(lg(B+1)) comparisons -- but straight binary search takes that many
+comparisons no matter where A[0] belongs.  Straight binary search thus loses
+to galloping unless the run is quite long, and we simply can't guess
+whether it is in advance.
+
+If data is random and runs have the same length, A[0] belongs at B[0] half
+the time, at B[1] a quarter of the time, and so on:  a consecutive winning
+sub-run in B of length k occurs with probability 1/2**(k+1).  So long
+winning sub-runs are extremely unlikely in random data, and guessing that a
+winning sub-run is going to be long is a dangerous game.
+
+OTOH, if data is lopsided or lumpy or contains many duplicates, long
+stretches of winning sub-runs are very likely, and cutting the number of
+comparisons needed to find one from O(B) to O(log B) is a huge win.
+
+Galloping compromises by getting out fast if there isn't a long winning
+sub-run, yet finding such very efficiently when they exist.
+
+I first learned about the galloping strategy in a related context; see:
+
+    "Adaptive Set Intersections, Unions, and Differences" (2000)
+    Erik D. Demaine, Alejandro López-Ortiz, J. Ian Munro
+
+and its followup(s).  An earlier paper called the same strategy
+"exponential search":
+
+   "Optimistic Sorting and Information Theoretic Complexity"
+   Peter McIlroy
+   SODA (Fourth Annual ACM-SIAM Symposium on Discrete Algorithms), pp
+   467-474, Austin, Texas, 25-27 January 1993.
+
+and it probably dates back to an earlier paper by Bentley and Yao.  The
+McIlroy paper in particular has good analysis of a mergesort that's
+probably strongly related to this one in its galloping strategy.
+
+
+Galloping with a Broken Leg
+---------------------------
+So why don't we always gallop?  Because it can lose, on two counts:
+
+1. While we're willing to endure small per-merge overheads, per-comparison
+   overheads are a different story.  Calling Yet Another Function per
+   comparison is expensive, and gallop_left() and gallop_right() are
+   too long-winded for sane inlining.
+
+2. Galloping can-- alas --require more comparisons than linear one-at-time
+   search, depending on the data.
+
+#2 requires details.  If A[0] belongs before B[0], galloping requires 1
+compare to determine that, same as linear search, except it costs more
+to call the gallop function.  If A[0] belongs right before B[1], galloping
+requires 2 compares, again same as linear search.  On the third compare,
+galloping checks A[0] against B[3], and if it's <=, requires one more
+compare to determine whether A[0] belongs at B[2] or B[3].  That's a total
+of 4 compares, but if A[0] does belong at B[2], linear search would have
+discovered that in only 3 compares, and that's a huge loss!  Really.  It's
+an increase of 33% in the number of compares needed, and comparisons are
+expensive in Python.
+
+index in B where    # compares linear  # gallop  # binary  gallop
+A[0] belongs        search needs       compares  compares  total
+----------------    -----------------  --------  --------  ------
+               0                    1         1         0       1
+
+               1                    2         2         0       2
+
+               2                    3         3         1       4
+               3                    4         3         1       4
+
+               4                    5         4         2       6
+               5                    6         4         2       6
+               6                    7         4         2       6
+               7                    8         4         2       6
+
+               8                    9         5         3       8
+               9                   10         5         3       8
+              10                   11         5         3       8
+              11                   12         5         3       8
+                                        ...
+
+In general, if A[0] belongs at B[i], linear search requires i+1 comparisons
+to determine that, and galloping a total of 2*floor(lg(i))+2 comparisons.
+The advantage of galloping is unbounded as i grows, but it doesn't win at
+all until i=6.  Before then, it loses twice (at i=2 and i=4), and ties
+at the other values.  At and after i=6, galloping always wins.
+
+We can't guess in advance when it's going to win, though, so we do one pair
+at a time until the evidence seems strong that galloping may pay.  MIN_GALLOP
+is 7, and that's pretty strong evidence.  However, if the data is random, it
+simply will trigger galloping mode purely by luck every now and again, and
+it's quite likely to hit one of the losing cases next.  On the other hand,
+in cases like ~sort, galloping always pays, and MIN_GALLOP is larger than it
+"should be" then.  So the MergeState struct keeps a min_gallop variable
+that merge_lo and merge_hi adjust:  the longer we stay in galloping mode,
+the smaller min_gallop gets, making it easier to transition back to
+galloping mode (if we ever leave it in the current merge, and at the
+start of the next merge).  But whenever the gallop loop doesn't pay,
+min_gallop is increased by one, making it harder to transition back
+to galloping mode (and again both within a merge and across merges).  For
+random data, this all but eliminates the gallop penalty:  min_gallop grows
+large enough that we almost never get into galloping mode.  And for cases
+like ~sort, min_gallop can fall to as low as 1.  This seems to work well,
+but in all it's a minor improvement over using a fixed MIN_GALLOP value.
+
+
+Galloping Complication
+----------------------
+The description above was for merge_lo.  merge_hi has to merge "from the
+other end", and really needs to gallop starting at the last element in a run
+instead of the first.  Galloping from the first still works, but does more
+comparisons than it should (this is significant -- I timed it both ways).
+For this reason, the gallop_left() and gallop_right() functions have a
+"hint" argument, which is the index at which galloping should begin.  So
+galloping can actually start at any index, and proceed at offsets of 1, 3,
+7, 15, ... or -1, -3, -7, -15, ... from the starting index.
+
+In the code as I type it's always called with either 0 or n-1 (where n is
+the # of elements in a run).  It's tempting to try to do something fancier,
+melding galloping with some form of interpolation search; for example, if
+we're merging a run of length 1 with a run of length 10000, index 5000 is
+probably a better guess at the final result than either 0 or 9999.  But
+it's unclear how to generalize that intuition usefully, and merging of
+wildly unbalanced runs already enjoys excellent performance.
+
+~sort is a good example of when balanced runs could benefit from a better
+hint value:  to the extent possible, this would like to use a starting
+offset equal to the previous value of acount/bcount.  Doing so saves about
+10% of the compares in ~sort.  However, doing so is also a mixed bag,
+hurting other cases.
+
+
+Comparing Average # of Compares on Random Arrays
+------------------------------------------------
+[NOTE:  This was done when the new algorithm used about 0.1% more compares
+ on random data than does its current incarnation.]
+
+Here list.sort() is samplesort, and list.msort() this sort:
+
+"""
+import random
+from time import clock as now
+
+def fill(n):
+    from random import random
+    return [random() for i in xrange(n)]
+
+def mycmp(x, y):
+    global ncmp
+    ncmp += 1
+    return cmp(x, y)
+
+def timeit(values, method):
+    global ncmp
+    X = values[:]
+    bound = getattr(X, method)
+    ncmp = 0
+    t1 = now()
+    bound(mycmp)
+    t2 = now()
+    return t2-t1, ncmp
+
+format = "%5s  %9.2f  %11d"
+f2     = "%5s  %9.2f  %11.2f"
+
+def drive():
+    count = sst = sscmp = mst = mscmp = nelts = 0
+    while True:
+        n = random.randrange(100000)
+        nelts += n
+        x = fill(n)
+
+        t, c = timeit(x, 'sort')
+        sst += t
+        sscmp += c
+
+        t, c = timeit(x, 'msort')
+        mst += t
+        mscmp += c
+
+        count += 1
+        if count % 10:
+            continue
+
+        print "count", count, "nelts", nelts
+        print format % ("sort",  sst, sscmp)
+        print format % ("msort", mst, mscmp)
+        print f2     % ("", (sst-mst)*1e2/mst, (sscmp-mscmp)*1e2/mscmp)
+
+drive()
+"""
+
+I ran this on Windows and kept using the computer lightly while it was
+running.  time.clock() is wall-clock time on Windows, with better than
+microsecond resolution.  samplesort started with a 1.52% #-of-comparisons
+disadvantage, fell quickly to 1.48%, and then fluctuated within that small
+range.  Here's the last chunk of output before I killed the job:
+
+count 2630 nelts 130906543
+ sort    6110.80   1937887573
+msort    6002.78   1909389381
+            1.80         1.49
+
+We've done nearly 2 billion comparisons apiece at Python speed there, and
+that's enough <wink>.
+
+For random arrays of size 2 (yes, there are only 2 interesting ones),
+samplesort has a 50%(!) comparison disadvantage.  This is a consequence of
+samplesort special-casing at most one ascending run at the start, then
+falling back to the general case if it doesn't find an ascending run
+immediately.  The consequence is that it ends up using two compares to sort
+[2, 1].  Gratifyingly, timsort doesn't do any special-casing, so had to be
+taught how to deal with mixtures of ascending and descending runs
+efficiently in all cases.

Added: vendor/Python/current/Objects/longobject.c
===================================================================
--- vendor/Python/current/Objects/longobject.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Objects/longobject.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,3458 @@
+
+
+/* Long (arbitrary precision) integer object implementation */
+
+/* XXX The functional organization of this file is terrible */
+
+#include "Python.h"
+#include "longintrepr.h"
+
+#include <ctype.h>
+
+/* For long multiplication, use the O(N**2) school algorithm unless
+ * both operands contain more than KARATSUBA_CUTOFF digits (this
+ * being an internal Python long digit, in base BASE).
+ */
+#define KARATSUBA_CUTOFF 70
+#define KARATSUBA_SQUARE_CUTOFF (2 * KARATSUBA_CUTOFF)
+
+/* For exponentiation, use the binary left-to-right algorithm
+ * unless the exponent contains more than FIVEARY_CUTOFF digits.
+ * In that case, do 5 bits at a time.  The potential drawback is that
+ * a table of 2**5 intermediate results is computed.
+ */
+#define FIVEARY_CUTOFF 8
+
+#define ABS(x) ((x) < 0 ? -(x) : (x))
+
+#undef MIN
+#undef MAX
+#define MAX(x, y) ((x) < (y) ? (y) : (x))
+#define MIN(x, y) ((x) > (y) ? (y) : (x))
+
+/* Forward */
+static PyLongObject *long_normalize(PyLongObject *);
+static PyLongObject *mul1(PyLongObject *, wdigit);
+static PyLongObject *muladd1(PyLongObject *, wdigit, wdigit);
+static PyLongObject *divrem1(PyLongObject *, digit, digit *);
+static PyObject *long_format(PyObject *aa, int base, int addL);
+
+#define SIGCHECK(PyTryBlock) \
+	if (--_Py_Ticker < 0) { \
+		_Py_Ticker = _Py_CheckInterval; \
+		if (PyErr_CheckSignals()) PyTryBlock \
+	}
+
+/* Normalize (remove leading zeros from) a long int object.
+   Doesn't attempt to free the storage--in most cases, due to the nature
+   of the algorithms used, this could save at most be one word anyway. */
+
+static PyLongObject *
+long_normalize(register PyLongObject *v)
+{
+	Py_ssize_t j = ABS(v->ob_size);
+	Py_ssize_t i = j;
+
+	while (i > 0 && v->ob_digit[i-1] == 0)
+		--i;
+	if (i != j)
+		v->ob_size = (v->ob_size < 0) ? -(i) : i;
+	return v;
+}
+
+/* Allocate a new long int object with size digits.
+   Return NULL and set exception if we run out of memory. */
+
+PyLongObject *
+_PyLong_New(Py_ssize_t size)
+{
+	if (size > PY_SSIZE_T_MAX) {
+		PyErr_NoMemory();
+		return NULL;
+	}
+	return PyObject_NEW_VAR(PyLongObject, &PyLong_Type, size);
+}
+
+PyObject *
+_PyLong_Copy(PyLongObject *src)
+{
+	PyLongObject *result;
+	Py_ssize_t i;
+
+	assert(src != NULL);
+	i = src->ob_size;
+	if (i < 0)
+		i = -(i);
+	result = _PyLong_New(i);
+	if (result != NULL) {
+		result->ob_size = src->ob_size;
+		while (--i >= 0)
+			result->ob_digit[i] = src->ob_digit[i];
+	}
+	return (PyObject *)result;
+}
+
+/* Create a new long int object from a C long int */
+
+PyObject *
+PyLong_FromLong(long ival)
+{
+	PyLongObject *v;
+	unsigned long t;  /* unsigned so >> doesn't propagate sign bit */
+	int ndigits = 0;
+	int negative = 0;
+
+	if (ival < 0) {
+		ival = -ival;
+		negative = 1;
+	}
+
+	/* Count the number of Python digits.
+	   We used to pick 5 ("big enough for anything"), but that's a
+	   waste of time and space given that 5*15 = 75 bits are rarely
+	   needed. */
+	t = (unsigned long)ival;
+	while (t) {
+		++ndigits;
+		t >>= SHIFT;
+	}
+	v = _PyLong_New(ndigits);
+	if (v != NULL) {
+		digit *p = v->ob_digit;
+		v->ob_size = negative ? -ndigits : ndigits;
+		t = (unsigned long)ival;
+		while (t) {
+			*p++ = (digit)(t & MASK);
+			t >>= SHIFT;
+		}
+	}
+	return (PyObject *)v;
+}
+
+/* Create a new long int object from a C unsigned long int */
+
+PyObject *
+PyLong_FromUnsignedLong(unsigned long ival)
+{
+	PyLongObject *v;
+	unsigned long t;
+	int ndigits = 0;
+
+	/* Count the number of Python digits. */
+	t = (unsigned long)ival;
+	while (t) {
+		++ndigits;
+		t >>= SHIFT;
+	}
+	v = _PyLong_New(ndigits);
+	if (v != NULL) {
+		digit *p = v->ob_digit;
+		v->ob_size = ndigits;
+		while (ival) {
+			*p++ = (digit)(ival & MASK);
+			ival >>= SHIFT;
+		}
+	}
+	return (PyObject *)v;
+}
+
+/* Create a new long int object from a C double */
+
+PyObject *
+PyLong_FromDouble(double dval)
+{
+	PyLongObject *v;
+	double frac;
+	int i, ndig, expo, neg;
+	neg = 0;
+	if (Py_IS_INFINITY(dval)) {
+		PyErr_SetString(PyExc_OverflowError,
+			"cannot convert float infinity to long");
+		return NULL;
+	}
+	if (dval < 0.0) {
+		neg = 1;
+		dval = -dval;
+	}
+	frac = frexp(dval, &expo); /* dval = frac*2**expo; 0.0 <= frac < 1.0 */
+	if (expo <= 0)
+		return PyLong_FromLong(0L);
+	ndig = (expo-1) / SHIFT + 1; /* Number of 'digits' in result */
+	v = _PyLong_New(ndig);
+	if (v == NULL)
+		return NULL;
+	frac = ldexp(frac, (expo-1) % SHIFT + 1);
+	for (i = ndig; --i >= 0; ) {
+		long bits = (long)frac;
+		v->ob_digit[i] = (digit) bits;
+		frac = frac - (double)bits;
+		frac = ldexp(frac, SHIFT);
+	}
+	if (neg)
+		v->ob_size = -(v->ob_size);
+	return (PyObject *)v;
+}
+
+/* Checking for overflow in PyLong_AsLong is a PITA since C doesn't define
+ * anything about what happens when a signed integer operation overflows,
+ * and some compilers think they're doing you a favor by being "clever"
+ * then.  The bit pattern for the largest postive signed long is
+ * (unsigned long)LONG_MAX, and for the smallest negative signed long
+ * it is abs(LONG_MIN), which we could write -(unsigned long)LONG_MIN.
+ * However, some other compilers warn about applying unary minus to an
+ * unsigned operand.  Hence the weird "0-".
+ */
+#define PY_ABS_LONG_MIN		(0-(unsigned long)LONG_MIN)
+#define PY_ABS_SSIZE_T_MIN	(0-(size_t)PY_SSIZE_T_MIN)
+
+/* Get a C long int from a long int object.
+   Returns -1 and sets an error condition if overflow occurs. */
+
+long
+PyLong_AsLong(PyObject *vv)
+{
+	/* This version by Tim Peters */
+	register PyLongObject *v;
+	unsigned long x, prev;
+	Py_ssize_t i;
+	int sign;
+
+	if (vv == NULL || !PyLong_Check(vv)) {
+		if (vv != NULL && PyInt_Check(vv))
+			return PyInt_AsLong(vv);
+		PyErr_BadInternalCall();
+		return -1;
+	}
+	v = (PyLongObject *)vv;
+	i = v->ob_size;
+	sign = 1;
+	x = 0;
+	if (i < 0) {
+		sign = -1;
+		i = -(i);
+	}
+	while (--i >= 0) {
+		prev = x;
+		x = (x << SHIFT) + v->ob_digit[i];
+		if ((x >> SHIFT) != prev)
+			goto overflow;
+	}
+	/* Haven't lost any bits, but casting to long requires extra care
+	 * (see comment above).
+         */
+	if (x <= (unsigned long)LONG_MAX) {
+		return (long)x * sign;
+	}
+	else if (sign < 0 && x == PY_ABS_LONG_MIN) {
+		return LONG_MIN;
+	}
+	/* else overflow */
+
+ overflow:
+	PyErr_SetString(PyExc_OverflowError,
+			"long int too large to convert to int");
+	return -1;
+}
+
+/* Get a Py_ssize_t from a long int object.
+   Returns -1 and sets an error condition if overflow occurs. */
+
+Py_ssize_t
+_PyLong_AsSsize_t(PyObject *vv) {
+	register PyLongObject *v;
+	size_t x, prev;
+	Py_ssize_t i;
+	int sign;
+
+	if (vv == NULL || !PyLong_Check(vv)) {
+		PyErr_BadInternalCall();
+		return -1;
+	}
+	v = (PyLongObject *)vv;
+	i = v->ob_size;
+	sign = 1;
+	x = 0;
+	if (i < 0) {
+		sign = -1;
+		i = -(i);
+	}
+	while (--i >= 0) {
+		prev = x;
+		x = (x << SHIFT) + v->ob_digit[i];
+		if ((x >> SHIFT) != prev)
+			goto overflow;
+	}
+	/* Haven't lost any bits, but casting to a signed type requires
+	 * extra care (see comment above).
+	 */
+	if (x <= (size_t)PY_SSIZE_T_MAX) {
+		return (Py_ssize_t)x * sign;
+	}
+	else if (sign < 0 && x == PY_ABS_SSIZE_T_MIN) {
+		return PY_SSIZE_T_MIN;
+	}
+	/* else overflow */
+
+ overflow:
+	PyErr_SetString(PyExc_OverflowError,
+			"long int too large to convert to int");
+	return -1;
+}
+
+/* Get a C unsigned long int from a long int object.
+   Returns -1 and sets an error condition if overflow occurs. */
+
+unsigned long
+PyLong_AsUnsignedLong(PyObject *vv)
+{
+	register PyLongObject *v;
+	unsigned long x, prev;
+	Py_ssize_t i;
+
+	if (vv == NULL || !PyLong_Check(vv)) {
+		if (vv != NULL && PyInt_Check(vv)) {
+			long val = PyInt_AsLong(vv);
+			if (val < 0) {
+				PyErr_SetString(PyExc_OverflowError,
+				"can't convert negative value to unsigned long");
+				return (unsigned long) -1;
+			}
+			return val;
+		}
+		PyErr_BadInternalCall();
+		return (unsigned long) -1;
+	}
+	v = (PyLongObject *)vv;
+	i = v->ob_size;
+	x = 0;
+	if (i < 0) {
+		PyErr_SetString(PyExc_OverflowError,
+			   "can't convert negative value to unsigned long");
+		return (unsigned long) -1;
+	}
+	while (--i >= 0) {
+		prev = x;
+		x = (x << SHIFT) + v->ob_digit[i];
+		if ((x >> SHIFT) != prev) {
+			PyErr_SetString(PyExc_OverflowError,
+				"long int too large to convert");
+			return (unsigned long) -1;
+		}
+	}
+	return x;
+}
+
+/* Get a C unsigned long int from a long int object, ignoring the high bits.
+   Returns -1 and sets an error condition if an error occurs. */
+
+unsigned long
+PyLong_AsUnsignedLongMask(PyObject *vv)
+{
+	register PyLongObject *v;
+	unsigned long x;
+	Py_ssize_t i;
+	int sign;
+
+	if (vv == NULL || !PyLong_Check(vv)) {
+		if (vv != NULL && PyInt_Check(vv))
+			return PyInt_AsUnsignedLongMask(vv);
+		PyErr_BadInternalCall();
+		return (unsigned long) -1;
+	}
+	v = (PyLongObject *)vv;
+	i = v->ob_size;
+	sign = 1;
+	x = 0;
+	if (i < 0) {
+		sign = -1;
+		i = -i;
+	}
+	while (--i >= 0) {
+		x = (x << SHIFT) + v->ob_digit[i];
+	}
+	return x * sign;
+}
+
+int
+_PyLong_Sign(PyObject *vv)
+{
+	PyLongObject *v = (PyLongObject *)vv;
+
+	assert(v != NULL);
+	assert(PyLong_Check(v));
+
+	return v->ob_size == 0 ? 0 : (v->ob_size < 0 ? -1 : 1);
+}
+
+size_t
+_PyLong_NumBits(PyObject *vv)
+{
+	PyLongObject *v = (PyLongObject *)vv;
+	size_t result = 0;
+	Py_ssize_t ndigits;
+
+	assert(v != NULL);
+	assert(PyLong_Check(v));
+	ndigits = ABS(v->ob_size);
+	assert(ndigits == 0 || v->ob_digit[ndigits - 1] != 0);
+	if (ndigits > 0) {
+		digit msd = v->ob_digit[ndigits - 1];
+
+		result = (ndigits - 1) * SHIFT;
+		if (result / SHIFT != (size_t)(ndigits - 1))
+			goto Overflow;
+		do {
+			++result;
+			if (result == 0)
+				goto Overflow;
+			msd >>= 1;
+		} while (msd);
+	}
+	return result;
+
+Overflow:
+	PyErr_SetString(PyExc_OverflowError, "long has too many bits "
+			"to express in a platform size_t");
+	return (size_t)-1;
+}
+
+PyObject *
+_PyLong_FromByteArray(const unsigned char* bytes, size_t n,
+		      int little_endian, int is_signed)
+{
+	const unsigned char* pstartbyte;/* LSB of bytes */
+	int incr;			/* direction to move pstartbyte */
+	const unsigned char* pendbyte;	/* MSB of bytes */
+	size_t numsignificantbytes;	/* number of bytes that matter */
+	size_t ndigits;			/* number of Python long digits */
+	PyLongObject* v;		/* result */
+	int idigit = 0;  		/* next free index in v->ob_digit */
+
+	if (n == 0)
+		return PyLong_FromLong(0L);
+
+	if (little_endian) {
+		pstartbyte = bytes;
+		pendbyte = bytes + n - 1;
+		incr = 1;
+	}
+	else {
+		pstartbyte = bytes + n - 1;
+		pendbyte = bytes;
+		incr = -1;
+	}
+
+	if (is_signed)
+		is_signed = *pendbyte >= 0x80;
+
+	/* Compute numsignificantbytes.  This consists of finding the most
+	   significant byte.  Leading 0 bytes are insignficant if the number
+	   is positive, and leading 0xff bytes if negative. */
+	{
+		size_t i;
+		const unsigned char* p = pendbyte;
+		const int pincr = -incr;  /* search MSB to LSB */
+		const unsigned char insignficant = is_signed ? 0xff : 0x00;
+
+		for (i = 0; i < n; ++i, p += pincr) {
+			if (*p != insignficant)
+				break;
+		}
+		numsignificantbytes = n - i;
+		/* 2's-comp is a bit tricky here, e.g. 0xff00 == -0x0100, so
+		   actually has 2 significant bytes.  OTOH, 0xff0001 ==
+		   -0x00ffff, so we wouldn't *need* to bump it there; but we
+		   do for 0xffff = -0x0001.  To be safe without bothering to
+		   check every case, bump it regardless. */
+		if (is_signed && numsignificantbytes < n)
+			++numsignificantbytes;
+	}
+
+	/* How many Python long digits do we need?  We have
+	   8*numsignificantbytes bits, and each Python long digit has SHIFT
+	   bits, so it's the ceiling of the quotient. */
+	ndigits = (numsignificantbytes * 8 + SHIFT - 1) / SHIFT;
+	if (ndigits > (size_t)INT_MAX)
+		return PyErr_NoMemory();
+	v = _PyLong_New((int)ndigits);
+	if (v == NULL)
+		return NULL;
+
+	/* Copy the bits over.  The tricky parts are computing 2's-comp on
+	   the fly for signed numbers, and dealing with the mismatch between
+	   8-bit bytes and (probably) 15-bit Python digits.*/
+	{
+		size_t i;
+		twodigits carry = 1;		/* for 2's-comp calculation */
+		twodigits accum = 0;		/* sliding register */
+		unsigned int accumbits = 0; 	/* number of bits in accum */
+		const unsigned char* p = pstartbyte;
+
+		for (i = 0; i < numsignificantbytes; ++i, p += incr) {
+			twodigits thisbyte = *p;
+			/* Compute correction for 2's comp, if needed. */
+			if (is_signed) {
+				thisbyte = (0xff ^ thisbyte) + carry;
+				carry = thisbyte >> 8;
+				thisbyte &= 0xff;
+			}
+			/* Because we're going LSB to MSB, thisbyte is
+			   more significant than what's already in accum,
+			   so needs to be prepended to accum. */
+			accum |= thisbyte << accumbits;
+			accumbits += 8;
+			if (accumbits >= SHIFT) {
+				/* There's enough to fill a Python digit. */
+				assert(idigit < (int)ndigits);
+				v->ob_digit[idigit] = (digit)(accum & MASK);
+				++idigit;
+				accum >>= SHIFT;
+				accumbits -= SHIFT;
+				assert(accumbits < SHIFT);
+			}
+		}
+		assert(accumbits < SHIFT);
+		if (accumbits) {
+			assert(idigit < (int)ndigits);
+			v->ob_digit[idigit] = (digit)accum;
+			++idigit;
+		}
+	}
+
+	v->ob_size = is_signed ? -idigit : idigit;
+	return (PyObject *)long_normalize(v);
+}
+
+int
+_PyLong_AsByteArray(PyLongObject* v,
+		    unsigned char* bytes, size_t n,
+		    int little_endian, int is_signed)
+{
+	int i;			/* index into v->ob_digit */
+	Py_ssize_t ndigits;		/* |v->ob_size| */
+	twodigits accum;	/* sliding register */
+	unsigned int accumbits; /* # bits in accum */
+	int do_twos_comp;	/* store 2's-comp?  is_signed and v < 0 */
+	twodigits carry;	/* for computing 2's-comp */
+	size_t j;		/* # bytes filled */
+	unsigned char* p;	/* pointer to next byte in bytes */
+	int pincr;		/* direction to move p */
+
+	assert(v != NULL && PyLong_Check(v));
+
+	if (v->ob_size < 0) {
+		ndigits = -(v->ob_size);
+		if (!is_signed) {
+			PyErr_SetString(PyExc_TypeError,
+				"can't convert negative long to unsigned");
+			return -1;
+		}
+		do_twos_comp = 1;
+	}
+	else {
+		ndigits = v->ob_size;
+		do_twos_comp = 0;
+	}
+
+	if (little_endian) {
+		p = bytes;
+		pincr = 1;
+	}
+	else {
+		p = bytes + n - 1;
+		pincr = -1;
+	}
+
+	/* Copy over all the Python digits.
+	   It's crucial that every Python digit except for the MSD contribute
+	   exactly SHIFT bits to the total, so first assert that the long is
+	   normalized. */
+	assert(ndigits == 0 || v->ob_digit[ndigits - 1] != 0);
+	j = 0;
+	accum = 0;
+	accumbits = 0;
+	carry = do_twos_comp ? 1 : 0;
+	for (i = 0; i < ndigits; ++i) {
+		twodigits thisdigit = v->ob_digit[i];
+		if (do_twos_comp) {
+			thisdigit = (thisdigit ^ MASK) + carry;
+			carry = thisdigit >> SHIFT;
+			thisdigit &= MASK;
+		}
+		/* Because we're going LSB to MSB, thisdigit is more
+		   significant than what's already in accum, so needs to be
+		   prepended to accum. */
+		accum |= thisdigit << accumbits;
+		accumbits += SHIFT;
+
+		/* The most-significant digit may be (probably is) at least
+		   partly empty. */
+		if (i == ndigits - 1) {
+			/* Count # of sign bits -- they needn't be stored,
+			 * although for signed conversion we need later to
+			 * make sure at least one sign bit gets stored.
+			 * First shift conceptual sign bit to real sign bit.
+			 */
+			stwodigits s = (stwodigits)(thisdigit <<
+				(8*sizeof(stwodigits) - SHIFT));
+			unsigned int nsignbits = 0;
+			while ((s < 0) == do_twos_comp && nsignbits < SHIFT) {
+				++nsignbits;
+				s <<= 1;
+			}
+			accumbits -= nsignbits;
+		}
+
+		/* Store as many bytes as possible. */
+		while (accumbits >= 8) {
+			if (j >= n)
+				goto Overflow;
+			++j;
+			*p = (unsigned char)(accum & 0xff);
+			p += pincr;
+			accumbits -= 8;
+			accum >>= 8;
+		}
+	}
+
+	/* Store the straggler (if any). */
+	assert(accumbits < 8);
+	assert(carry == 0);  /* else do_twos_comp and *every* digit was 0 */
+	if (accumbits > 0) {
+		if (j >= n)
+			goto Overflow;
+		++j;
+		if (do_twos_comp) {
+			/* Fill leading bits of the byte with sign bits
+			   (appropriately pretending that the long had an
+			   infinite supply of sign bits). */
+			accum |= (~(twodigits)0) << accumbits;
+		}
+		*p = (unsigned char)(accum & 0xff);
+		p += pincr;
+	}
+	else if (j == n && n > 0 && is_signed) {
+		/* The main loop filled the byte array exactly, so the code
+		   just above didn't get to ensure there's a sign bit, and the
+		   loop below wouldn't add one either.  Make sure a sign bit
+		   exists. */
+		unsigned char msb = *(p - pincr);
+		int sign_bit_set = msb >= 0x80;
+		assert(accumbits == 0);
+		if (sign_bit_set == do_twos_comp)
+			return 0;
+		else
+			goto Overflow;
+	}
+
+	/* Fill remaining bytes with copies of the sign bit. */
+	{
+		unsigned char signbyte = do_twos_comp ? 0xffU : 0U;
+		for ( ; j < n; ++j, p += pincr)
+			*p = signbyte;
+	}
+
+	return 0;
+
+Overflow:
+	PyErr_SetString(PyExc_OverflowError, "long too big to convert");
+	return -1;
+
+}
+
+double
+_PyLong_AsScaledDouble(PyObject *vv, int *exponent)
+{
+/* NBITS_WANTED should be > the number of bits in a double's precision,
+   but small enough so that 2**NBITS_WANTED is within the normal double
+   range.  nbitsneeded is set to 1 less than that because the most-significant
+   Python digit contains at least 1 significant bit, but we don't want to
+   bother counting them (catering to the worst case cheaply).
+
+   57 is one more than VAX-D double precision; I (Tim) don't know of a double
+   format with more precision than that; it's 1 larger so that we add in at
+   least one round bit to stand in for the ignored least-significant bits.
+*/
+#define NBITS_WANTED 57
+	PyLongObject *v;
+	double x;
+	const double multiplier = (double)(1L << SHIFT);
+	Py_ssize_t i;
+	int sign;
+	int nbitsneeded;
+
+	if (vv == NULL || !PyLong_Check(vv)) {
+		PyErr_BadInternalCall();
+		return -1;
+	}
+	v = (PyLongObject *)vv;
+	i = v->ob_size;
+	sign = 1;
+	if (i < 0) {
+		sign = -1;
+		i = -(i);
+	}
+	else if (i == 0) {
+		*exponent = 0;
+		return 0.0;
+	}
+	--i;
+	x = (double)v->ob_digit[i];
+	nbitsneeded = NBITS_WANTED - 1;
+	/* Invariant:  i Python digits remain unaccounted for. */
+	while (i > 0 && nbitsneeded > 0) {
+		--i;
+		x = x * multiplier + (double)v->ob_digit[i];
+		nbitsneeded -= SHIFT;
+	}
+	/* There are i digits we didn't shift in.  Pretending they're all
+	   zeroes, the true value is x * 2**(i*SHIFT). */
+	*exponent = i;
+	assert(x > 0.0);
+	return x * sign;
+#undef NBITS_WANTED
+}
+
+/* Get a C double from a long int object. */
+
+double
+PyLong_AsDouble(PyObject *vv)
+{
+	int e = -1;
+	double x;
+
+	if (vv == NULL || !PyLong_Check(vv)) {
+		PyErr_BadInternalCall();
+		return -1;
+	}
+	x = _PyLong_AsScaledDouble(vv, &e);
+	if (x == -1.0 && PyErr_Occurred())
+		return -1.0;
+	/* 'e' initialized to -1 to silence gcc-4.0.x, but it should be
+	   set correctly after a successful _PyLong_AsScaledDouble() call */
+	assert(e >= 0);
+	if (e > INT_MAX / SHIFT)
+		goto overflow;
+	errno = 0;
+	x = ldexp(x, e * SHIFT);
+	if (Py_OVERFLOWED(x))
+		goto overflow;
+	return x;
+
+overflow:
+	PyErr_SetString(PyExc_OverflowError,
+		"long int too large to convert to float");
+	return -1.0;
+}
+
+/* Create a new long (or int) object from a C pointer */
+
+PyObject *
+PyLong_FromVoidPtr(void *p)
+{
+#if SIZEOF_VOID_P <= SIZEOF_LONG
+	if ((long)p < 0)
+		return PyLong_FromUnsignedLong((unsigned long)p);
+	return PyInt_FromLong((long)p);
+#else
+
+#ifndef HAVE_LONG_LONG
+#   error "PyLong_FromVoidPtr: sizeof(void*) > sizeof(long), but no long long"
+#endif
+#if SIZEOF_LONG_LONG < SIZEOF_VOID_P
+#   error "PyLong_FromVoidPtr: sizeof(PY_LONG_LONG) < sizeof(void*)"
+#endif
+	/* optimize null pointers */
+	if (p == NULL)
+		return PyInt_FromLong(0);
+	return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG)p);
+
+#endif /* SIZEOF_VOID_P <= SIZEOF_LONG */
+}
+
+/* Get a C pointer from a long object (or an int object in some cases) */
+
+void *
+PyLong_AsVoidPtr(PyObject *vv)
+{
+	/* This function will allow int or long objects. If vv is neither,
+	   then the PyLong_AsLong*() functions will raise the exception:
+	   PyExc_SystemError, "bad argument to internal function"
+	*/
+#if SIZEOF_VOID_P <= SIZEOF_LONG
+	long x;
+
+	if (PyInt_Check(vv))
+		x = PyInt_AS_LONG(vv);
+	else if (PyLong_Check(vv) && _PyLong_Sign(vv) < 0)
+		x = PyLong_AsLong(vv);
+	else
+		x = PyLong_AsUnsignedLong(vv);
+#else
+
+#ifndef HAVE_LONG_LONG
+#   error "PyLong_AsVoidPtr: sizeof(void*) > sizeof(long), but no long long"
+#endif
+#if SIZEOF_LONG_LONG < SIZEOF_VOID_P
+#   error "PyLong_AsVoidPtr: sizeof(PY_LONG_LONG) < sizeof(void*)"
+#endif
+	PY_LONG_LONG x;
+
+	if (PyInt_Check(vv))
+		x = PyInt_AS_LONG(vv);
+	else if (PyLong_Check(vv) && _PyLong_Sign(vv) < 0)
+		x = PyLong_AsLongLong(vv);
+	else
+		x = PyLong_AsUnsignedLongLong(vv);
+
+#endif /* SIZEOF_VOID_P <= SIZEOF_LONG */
+
+	if (x == -1 && PyErr_Occurred())
+		return NULL;
+	return (void *)x;
+}
+
+#ifdef HAVE_LONG_LONG
+
+/* Initial PY_LONG_LONG support by Chris Herborth (chrish at qnx.com), later
+ * rewritten to use the newer PyLong_{As,From}ByteArray API.
+ */
+
+#define IS_LITTLE_ENDIAN (int)*(unsigned char*)&one
+
+/* Create a new long int object from a C PY_LONG_LONG int. */
+
+PyObject *
+PyLong_FromLongLong(PY_LONG_LONG ival)
+{
+	PyLongObject *v;
+	unsigned PY_LONG_LONG t;  /* unsigned so >> doesn't propagate sign bit */
+	int ndigits = 0;
+	int negative = 0;
+
+	if (ival < 0) {
+		ival = -ival;
+		negative = 1;
+	}
+
+	/* Count the number of Python digits.
+	   We used to pick 5 ("big enough for anything"), but that's a
+	   waste of time and space given that 5*15 = 75 bits are rarely
+	   needed. */
+	t = (unsigned PY_LONG_LONG)ival;
+	while (t) {
+		++ndigits;
+		t >>= SHIFT;
+	}
+	v = _PyLong_New(ndigits);
+	if (v != NULL) {
+		digit *p = v->ob_digit;
+		v->ob_size = negative ? -ndigits : ndigits;
+		t = (unsigned PY_LONG_LONG)ival;
+		while (t) {
+			*p++ = (digit)(t & MASK);
+			t >>= SHIFT;
+		}
+	}
+	return (PyObject *)v;
+}
+
+/* Create a new long int object from a C unsigned PY_LONG_LONG int. */
+
+PyObject *
+PyLong_FromUnsignedLongLong(unsigned PY_LONG_LONG ival)
+{
+	PyLongObject *v;
+	unsigned PY_LONG_LONG t;
+	int ndigits = 0;
+
+	/* Count the number of Python digits. */
+	t = (unsigned PY_LONG_LONG)ival;
+	while (t) {
+		++ndigits;
+		t >>= SHIFT;
+	}
+	v = _PyLong_New(ndigits);
+	if (v != NULL) {
+		digit *p = v->ob_digit;
+		v->ob_size = ndigits;
+		while (ival) {
+			*p++ = (digit)(ival & MASK);
+			ival >>= SHIFT;
+		}
+	}
+	return (PyObject *)v;
+}
+
+/* Create a new long int object from a C Py_ssize_t. */
+
+PyObject *
+_PyLong_FromSsize_t(Py_ssize_t ival)
+{
+	Py_ssize_t bytes = ival;
+	int one = 1;
+	return _PyLong_FromByteArray(
+			(unsigned char *)&bytes,
+			SIZEOF_SIZE_T, IS_LITTLE_ENDIAN, 0);
+}
+
+/* Create a new long int object from a C size_t. */
+
+PyObject *
+_PyLong_FromSize_t(size_t ival)
+{
+	size_t bytes = ival;
+	int one = 1;
+	return _PyLong_FromByteArray(
+			(unsigned char *)&bytes,
+			SIZEOF_SIZE_T, IS_LITTLE_ENDIAN, 0);
+}
+
+/* Get a C PY_LONG_LONG int from a long int object.
+   Return -1 and set an error if overflow occurs. */
+
+PY_LONG_LONG
+PyLong_AsLongLong(PyObject *vv)
+{
+	PY_LONG_LONG bytes;
+	int one = 1;
+	int res;
+
+	if (vv == NULL) {
+		PyErr_BadInternalCall();
+		return -1;
+	}
+	if (!PyLong_Check(vv)) {
+		PyNumberMethods *nb;
+		PyObject *io;
+		if (PyInt_Check(vv))
+			return (PY_LONG_LONG)PyInt_AsLong(vv);
+		if ((nb = vv->ob_type->tp_as_number) == NULL ||
+		    nb->nb_int == NULL) {
+			PyErr_SetString(PyExc_TypeError, "an integer is required");
+			return -1;
+		}
+		io = (*nb->nb_int) (vv);
+		if (io == NULL)
+			return -1;
+		if (PyInt_Check(io)) {
+			bytes = PyInt_AsLong(io);
+			Py_DECREF(io);
+			return bytes;
+		}
+		if (PyLong_Check(io)) {
+			bytes = PyLong_AsLongLong(io);
+			Py_DECREF(io);
+			return bytes;
+		}
+		Py_DECREF(io);
+		PyErr_SetString(PyExc_TypeError, "integer conversion failed");
+		return -1;
+	}
+
+	res = _PyLong_AsByteArray(
+			(PyLongObject *)vv, (unsigned char *)&bytes,
+			SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 1);
+
+	/* Plan 9 can't handle PY_LONG_LONG in ? : expressions */
+	if (res < 0)
+		return (PY_LONG_LONG)-1;
+	else
+		return bytes;
+}
+
+/* Get a C unsigned PY_LONG_LONG int from a long int object.
+   Return -1 and set an error if overflow occurs. */
+
+unsigned PY_LONG_LONG
+PyLong_AsUnsignedLongLong(PyObject *vv)
+{
+	unsigned PY_LONG_LONG bytes;
+	int one = 1;
+	int res;
+
+	if (vv == NULL || !PyLong_Check(vv)) {
+		PyErr_BadInternalCall();
+		return (unsigned PY_LONG_LONG)-1;
+	}
+
+	res = _PyLong_AsByteArray(
+			(PyLongObject *)vv, (unsigned char *)&bytes,
+			SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 0);
+
+	/* Plan 9 can't handle PY_LONG_LONG in ? : expressions */
+	if (res < 0)
+		return (unsigned PY_LONG_LONG)res;
+	else
+		return bytes;
+}
+
+/* Get a C unsigned long int from a long int object, ignoring the high bits.
+   Returns -1 and sets an error condition if an error occurs. */
+
+unsigned PY_LONG_LONG
+PyLong_AsUnsignedLongLongMask(PyObject *vv)
+{
+	register PyLongObject *v;
+	unsigned PY_LONG_LONG x;
+	Py_ssize_t i;
+	int sign;
+
+	if (vv == NULL || !PyLong_Check(vv)) {
+		PyErr_BadInternalCall();
+		return (unsigned long) -1;
+	}
+	v = (PyLongObject *)vv;
+	i = v->ob_size;
+	sign = 1;
+	x = 0;
+	if (i < 0) {
+		sign = -1;
+		i = -i;
+	}
+	while (--i >= 0) {
+		x = (x << SHIFT) + v->ob_digit[i];
+	}
+	return x * sign;
+}
+#undef IS_LITTLE_ENDIAN
+
+#endif /* HAVE_LONG_LONG */
+
+
+static int
+convert_binop(PyObject *v, PyObject *w, PyLongObject **a, PyLongObject **b) {
+	if (PyLong_Check(v)) {
+		*a = (PyLongObject *) v;
+		Py_INCREF(v);
+	}
+	else if (PyInt_Check(v)) {
+		*a = (PyLongObject *) PyLong_FromLong(PyInt_AS_LONG(v));
+	}
+	else {
+		return 0;
+	}
+	if (PyLong_Check(w)) {
+		*b = (PyLongObject *) w;
+		Py_INCREF(w);
+	}
+	else if (PyInt_Check(w)) {
+		*b = (PyLongObject *) PyLong_FromLong(PyInt_AS_LONG(w));
+	}
+	else {
+		Py_DECREF(*a);
+		return 0;
+	}
+	return 1;
+}
+
+#define CONVERT_BINOP(v, w, a, b) \
+	if (!convert_binop(v, w, a, b)) { \
+		Py_INCREF(Py_NotImplemented); \
+		return Py_NotImplemented; \
+	}
+
+/* x[0:m] and y[0:n] are digit vectors, LSD first, m >= n required.  x[0:n]
+ * is modified in place, by adding y to it.  Carries are propagated as far as
+ * x[m-1], and the remaining carry (0 or 1) is returned.
+ */
+static digit
+v_iadd(digit *x, Py_ssize_t m, digit *y, Py_ssize_t n)
+{
+	int i;
+	digit carry = 0;
+
+	assert(m >= n);
+	for (i = 0; i < n; ++i) {
+		carry += x[i] + y[i];
+		x[i] = carry & MASK;
+		carry >>= SHIFT;
+		assert((carry & 1) == carry);
+	}
+	for (; carry && i < m; ++i) {
+		carry += x[i];
+		x[i] = carry & MASK;
+		carry >>= SHIFT;
+		assert((carry & 1) == carry);
+	}
+	return carry;
+}
+
+/* x[0:m] and y[0:n] are digit vectors, LSD first, m >= n required.  x[0:n]
+ * is modified in place, by subtracting y from it.  Borrows are propagated as
+ * far as x[m-1], and the remaining borrow (0 or 1) is returned.
+ */
+static digit
+v_isub(digit *x, Py_ssize_t m, digit *y, Py_ssize_t n)
+{
+	int i;
+	digit borrow = 0;
+
+	assert(m >= n);
+	for (i = 0; i < n; ++i) {
+		borrow = x[i] - y[i] - borrow;
+		x[i] = borrow & MASK;
+		borrow >>= SHIFT;
+		borrow &= 1;	/* keep only 1 sign bit */
+	}
+	for (; borrow && i < m; ++i) {
+		borrow = x[i] - borrow;
+		x[i] = borrow & MASK;
+		borrow >>= SHIFT;
+		borrow &= 1;
+	}
+	return borrow;
+}
+
+/* Multiply by a single digit, ignoring the sign. */
+
+static PyLongObject *
+mul1(PyLongObject *a, wdigit n)
+{
+	return muladd1(a, n, (digit)0);
+}
+
+/* Multiply by a single digit and add a single digit, ignoring the sign. */
+
+static PyLongObject *
+muladd1(PyLongObject *a, wdigit n, wdigit extra)
+{
+	Py_ssize_t size_a = ABS(a->ob_size);
+	PyLongObject *z = _PyLong_New(size_a+1);
+	twodigits carry = extra;
+	Py_ssize_t i;
+
+	if (z == NULL)
+		return NULL;
+	for (i = 0; i < size_a; ++i) {
+		carry += (twodigits)a->ob_digit[i] * n;
+		z->ob_digit[i] = (digit) (carry & MASK);
+		carry >>= SHIFT;
+	}
+	z->ob_digit[i] = (digit) carry;
+	return long_normalize(z);
+}
+
+/* Divide long pin, w/ size digits, by non-zero digit n, storing quotient
+   in pout, and returning the remainder.  pin and pout point at the LSD.
+   It's OK for pin == pout on entry, which saves oodles of mallocs/frees in
+   long_format, but that should be done with great care since longs are
+   immutable. */
+
+static digit
+inplace_divrem1(digit *pout, digit *pin, Py_ssize_t size, digit n)
+{
+	twodigits rem = 0;
+
+	assert(n > 0 && n <= MASK);
+	pin += size;
+	pout += size;
+	while (--size >= 0) {
+		digit hi;
+		rem = (rem << SHIFT) + *--pin;
+		*--pout = hi = (digit)(rem / n);
+		rem -= hi * n;
+	}
+	return (digit)rem;
+}
+
+/* Divide a long integer by a digit, returning both the quotient
+   (as function result) and the remainder (through *prem).
+   The sign of a is ignored; n should not be zero. */
+
+static PyLongObject *
+divrem1(PyLongObject *a, digit n, digit *prem)
+{
+	const Py_ssize_t size = ABS(a->ob_size);
+	PyLongObject *z;
+
+	assert(n > 0 && n <= MASK);
+	z = _PyLong_New(size);
+	if (z == NULL)
+		return NULL;
+	*prem = inplace_divrem1(z->ob_digit, a->ob_digit, size, n);
+	return long_normalize(z);
+}
+
+/* Convert a long int object to a string, using a given conversion base.
+   Return a string object.
+   If base is 8 or 16, add the proper prefix '0' or '0x'. */
+
+static PyObject *
+long_format(PyObject *aa, int base, int addL)
+{
+	register PyLongObject *a = (PyLongObject *)aa;
+	PyStringObject *str;
+	Py_ssize_t i, j, sz;
+	Py_ssize_t size_a;
+	char *p;
+	int bits;
+	char sign = '\0';
+
+	if (a == NULL || !PyLong_Check(a)) {
+		PyErr_BadInternalCall();
+		return NULL;
+	}
+	assert(base >= 2 && base <= 36);
+	size_a = ABS(a->ob_size);
+
+	/* Compute a rough upper bound for the length of the string */
+	i = base;
+	bits = 0;
+	while (i > 1) {
+		++bits;
+		i >>= 1;
+	}
+	i = 5 + (addL ? 1 : 0);
+	j = size_a*SHIFT + bits-1;
+	sz = i + j / bits;
+	if (j / SHIFT < size_a || sz < i) {
+		PyErr_SetString(PyExc_OverflowError,
+				"long is too large to format");
+		return NULL;
+	}
+	str = (PyStringObject *) PyString_FromStringAndSize((char *)0, sz);
+	if (str == NULL)
+		return NULL;
+	p = PyString_AS_STRING(str) + sz;
+	*p = '\0';
+        if (addL)
+                *--p = 'L';
+	if (a->ob_size < 0)
+		sign = '-';
+
+	if (a->ob_size == 0) {
+		*--p = '0';
+	}
+	else if ((base & (base - 1)) == 0) {
+		/* JRH: special case for power-of-2 bases */
+		twodigits accum = 0;
+		int accumbits = 0;	/* # of bits in accum */
+		int basebits = 1;	/* # of bits in base-1 */
+		i = base;
+		while ((i >>= 1) > 1)
+			++basebits;
+
+		for (i = 0; i < size_a; ++i) {
+			accum |= (twodigits)a->ob_digit[i] << accumbits;
+			accumbits += SHIFT;
+			assert(accumbits >= basebits);
+			do {
+				char cdigit = (char)(accum & (base - 1));
+				cdigit += (cdigit < 10) ? '0' : 'a'-10;
+				assert(p > PyString_AS_STRING(str));
+				*--p = cdigit;
+				accumbits -= basebits;
+				accum >>= basebits;
+			} while (i < size_a-1 ? accumbits >= basebits :
+					 	accum > 0);
+		}
+	}
+	else {
+		/* Not 0, and base not a power of 2.  Divide repeatedly by
+		   base, but for speed use the highest power of base that
+		   fits in a digit. */
+		Py_ssize_t size = size_a;
+		digit *pin = a->ob_digit;
+		PyLongObject *scratch;
+		/* powbasw <- largest power of base that fits in a digit. */
+		digit powbase = base;  /* powbase == base ** power */
+		int power = 1;
+		for (;;) {
+			unsigned long newpow = powbase * (unsigned long)base;
+			if (newpow >> SHIFT)  /* doesn't fit in a digit */
+				break;
+			powbase = (digit)newpow;
+			++power;
+		}
+
+		/* Get a scratch area for repeated division. */
+		scratch = _PyLong_New(size);
+		if (scratch == NULL) {
+			Py_DECREF(str);
+			return NULL;
+		}
+
+		/* Repeatedly divide by powbase. */
+		do {
+			int ntostore = power;
+			digit rem = inplace_divrem1(scratch->ob_digit,
+						     pin, size, powbase);
+			pin = scratch->ob_digit; /* no need to use a again */
+			if (pin[size - 1] == 0)
+				--size;
+			SIGCHECK({
+				Py_DECREF(scratch);
+				Py_DECREF(str);
+				return NULL;
+			})
+
+			/* Break rem into digits. */
+			assert(ntostore > 0);
+			do {
+				digit nextrem = (digit)(rem / base);
+				char c = (char)(rem - nextrem * base);
+				assert(p > PyString_AS_STRING(str));
+				c += (c < 10) ? '0' : 'a'-10;
+				*--p = c;
+				rem = nextrem;
+				--ntostore;
+				/* Termination is a bit delicate:  must not
+				   store leading zeroes, so must get out if
+				   remaining quotient and rem are both 0. */
+			} while (ntostore && (size || rem));
+		} while (size != 0);
+		Py_DECREF(scratch);
+	}
+
+	if (base == 8) {
+		if (size_a != 0)
+			*--p = '0';
+	}
+	else if (base == 16) {
+		*--p = 'x';
+		*--p = '0';
+	}
+	else if (base != 10) {
+		*--p = '#';
+		*--p = '0' + base%10;
+		if (base > 10)
+			*--p = '0' + base/10;
+	}
+	if (sign)
+		*--p = sign;
+	if (p != PyString_AS_STRING(str)) {
+		char *q = PyString_AS_STRING(str);
+		assert(p > q);
+		do {
+		} while ((*q++ = *p++) != '\0');
+		q--;
+		_PyString_Resize((PyObject **)&str,
+				 (Py_ssize_t) (q - PyString_AS_STRING(str)));
+	}
+	return (PyObject *)str;
+}
+
+/* Table of digit values for 8-bit string -> integer conversion.
+ * '0' maps to 0, ..., '9' maps to 9.
+ * 'a' and 'A' map to 10, ..., 'z' and 'Z' map to 35.
+ * All other indices map to 37.
+ * Note that when converting a base B string, a char c is a legitimate
+ * base B digit iff _PyLong_DigitValue[Py_CHARMASK(c)] < B.
+ */
+int _PyLong_DigitValue[256] = {
+	37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+	37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+	37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+	0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  37, 37, 37, 37, 37, 37,
+	37, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+	25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 37, 37, 37, 37, 37,
+	37, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+	25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 37, 37, 37, 37, 37,
+	37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+	37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+	37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+	37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+	37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+	37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+	37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+	37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+};
+
+/* *str points to the first digit in a string of base `base` digits.  base
+ * is a power of 2 (2, 4, 8, 16, or 32).  *str is set to point to the first
+ * non-digit (which may be *str!).  A normalized long is returned.
+ * The point to this routine is that it takes time linear in the number of
+ * string characters.
+ */
+static PyLongObject *
+long_from_binary_base(char **str, int base)
+{
+	char *p = *str;
+	char *start = p;
+	int bits_per_char;
+	Py_ssize_t n;
+	PyLongObject *z;
+	twodigits accum;
+	int bits_in_accum;
+	digit *pdigit;
+
+	assert(base >= 2 && base <= 32 && (base & (base - 1)) == 0);
+	n = base;
+	for (bits_per_char = -1; n; ++bits_per_char)
+		n >>= 1;
+	/* n <- total # of bits needed, while setting p to end-of-string */
+	n = 0;
+	while (_PyLong_DigitValue[Py_CHARMASK(*p)] < base)
+		++p;
+	*str = p;
+	/* n <- # of Python digits needed, = ceiling(n/SHIFT). */
+	n = (p - start) * bits_per_char + SHIFT - 1;
+	if (n / bits_per_char < p - start) {
+		PyErr_SetString(PyExc_ValueError,
+				"long string too large to convert");
+		return NULL;
+	}
+	n = n / SHIFT;
+	z = _PyLong_New(n);
+	if (z == NULL)
+		return NULL;
+	/* Read string from right, and fill in long from left; i.e.,
+	 * from least to most significant in both.
+	 */
+	accum = 0;
+	bits_in_accum = 0;
+	pdigit = z->ob_digit;
+	while (--p >= start) {
+		int k = _PyLong_DigitValue[Py_CHARMASK(*p)];
+		assert(k >= 0 && k < base);
+		accum |= (twodigits)(k << bits_in_accum);
+		bits_in_accum += bits_per_char;
+		if (bits_in_accum >= SHIFT) {
+			*pdigit++ = (digit)(accum & MASK);
+			assert(pdigit - z->ob_digit <= (int)n);
+			accum >>= SHIFT;
+			bits_in_accum -= SHIFT;
+			assert(bits_in_accum < SHIFT);
+		}
+	}
+	if (bits_in_accum) {
+		assert(bits_in_accum <= SHIFT);
+		*pdigit++ = (digit)accum;
+		assert(pdigit - z->ob_digit <= (int)n);
+	}
+	while (pdigit - z->ob_digit < n)
+		*pdigit++ = 0;
+	return long_normalize(z);
+}
+
+PyObject *
+PyLong_FromString(char *str, char **pend, int base)
+{
+	int sign = 1;
+	char *start, *orig_str = str;
+	PyLongObject *z;
+	PyObject *strobj, *strrepr;
+	Py_ssize_t slen;
+
+	if ((base != 0 && base < 2) || base > 36) {
+		PyErr_SetString(PyExc_ValueError,
+				"long() arg 2 must be >= 2 and <= 36");
+		return NULL;
+	}
+	while (*str != '\0' && isspace(Py_CHARMASK(*str)))
+		str++;
+	if (*str == '+')
+		++str;
+	else if (*str == '-') {
+		++str;
+		sign = -1;
+	}
+	while (*str != '\0' && isspace(Py_CHARMASK(*str)))
+		str++;
+	if (base == 0) {
+		if (str[0] != '0')
+			base = 10;
+		else if (str[1] == 'x' || str[1] == 'X')
+			base = 16;
+		else
+			base = 8;
+	}
+	if (base == 16 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
+		str += 2;
+
+	start = str;
+	if ((base & (base - 1)) == 0)
+		z = long_from_binary_base(&str, base);
+	else {
+/***
+Binary bases can be converted in time linear in the number of digits, because
+Python's representation base is binary.  Other bases (including decimal!) use
+the simple quadratic-time algorithm below, complicated by some speed tricks.
+
+First some math:  the largest integer that can be expressed in N base-B digits
+is B**N-1.  Consequently, if we have an N-digit input in base B, the worst-
+case number of Python digits needed to hold it is the smallest integer n s.t.
+
+    BASE**n-1 >= B**N-1  [or, adding 1 to both sides]
+    BASE**n >= B**N      [taking logs to base BASE]
+    n >= log(B**N)/log(BASE) = N * log(B)/log(BASE)
+
+The static array log_base_BASE[base] == log(base)/log(BASE) so we can compute
+this quickly.  A Python long with that much space is reserved near the start,
+and the result is computed into it.
+
+The input string is actually treated as being in base base**i (i.e., i digits
+are processed at a time), where two more static arrays hold:
+
+    convwidth_base[base] = the largest integer i such that base**i <= BASE
+    convmultmax_base[base] = base ** convwidth_base[base]
+
+The first of these is the largest i such that i consecutive input digits
+must fit in a single Python digit.  The second is effectively the input
+base we're really using.
+
+Viewing the input as a sequence <c0, c1, ..., c_n-1> of digits in base
+convmultmax_base[base], the result is "simply"
+
+   (((c0*B + c1)*B + c2)*B + c3)*B + ... ))) + c_n-1
+
+where B = convmultmax_base[base].
+
+Error analysis:  as above, the number of Python digits `n` needed is worst-
+case
+
+    n >= N * log(B)/log(BASE)
+
+where `N` is the number of input digits in base `B`.  This is computed via
+
+    size_z = (Py_ssize_t)((scan - str) * log_base_BASE[base]) + 1;
+
+below.  Two numeric concerns are how much space this can waste, and whether
+the computed result can be too small.  To be concrete, assume BASE = 2**15,
+which is the default (and it's unlikely anyone changes that).
+
+Waste isn't a problem:  provided the first input digit isn't 0, the difference
+between the worst-case input with N digits and the smallest input with N
+digits is about a factor of B, but B is small compared to BASE so at most
+one allocated Python digit can remain unused on that count.  If
+N*log(B)/log(BASE) is mathematically an exact integer, then truncating that
+and adding 1 returns a result 1 larger than necessary.  However, that can't
+happen:  whenever B is a power of 2, long_from_binary_base() is called
+instead, and it's impossible for B**i to be an integer power of 2**15 when
+B is not a power of 2 (i.e., it's impossible for N*log(B)/log(BASE) to be
+an exact integer when B is not a power of 2, since B**i has a prime factor
+other than 2 in that case, but (2**15)**j's only prime factor is 2).
+
+The computed result can be too small if the true value of N*log(B)/log(BASE)
+is a little bit larger than an exact integer, but due to roundoff errors (in
+computing log(B), log(BASE), their quotient, and/or multiplying that by N)
+yields a numeric result a little less than that integer.  Unfortunately, "how
+close can a transcendental function get to an integer over some range?"
+questions are generally theoretically intractable.  Computer analysis via
+continued fractions is practical:  expand log(B)/log(BASE) via continued
+fractions, giving a sequence i/j of "the best" rational approximations.  Then
+j*log(B)/log(BASE) is approximately equal to (the integer) i.  This shows that
+we can get very close to being in trouble, but very rarely.  For example,
+76573 is a denominator in one of the continued-fraction approximations to
+log(10)/log(2**15), and indeed:
+
+    >>> log(10)/log(2**15)*76573
+    16958.000000654003
+
+is very close to an integer.  If we were working with IEEE single-precision,
+rounding errors could kill us.  Finding worst cases in IEEE double-precision
+requires better-than-double-precision log() functions, and Tim didn't bother.
+Instead the code checks to see whether the allocated space is enough as each
+new Python digit is added, and copies the whole thing to a larger long if not.
+This should happen extremely rarely, and in fact I don't have a test case
+that triggers it(!).  Instead the code was tested by artificially allocating
+just 1 digit at the start, so that the copying code was exercised for every
+digit beyond the first.
+***/
+		register twodigits c;	/* current input character */
+		Py_ssize_t size_z;
+		int i;
+		int convwidth;
+		twodigits convmultmax, convmult;
+		digit *pz, *pzstop;
+		char* scan;
+
+		static double log_base_BASE[37] = {0.0e0,};
+		static int convwidth_base[37] = {0,};
+		static twodigits convmultmax_base[37] = {0,};
+
+		if (log_base_BASE[base] == 0.0) {
+			twodigits convmax = base;
+			int i = 1;
+
+			log_base_BASE[base] = log((double)base) /
+						log((double)BASE);
+			for (;;) {
+				twodigits next = convmax * base;
+				if (next > BASE)
+					break;
+				convmax = next;
+				++i;
+			}
+			convmultmax_base[base] = convmax;
+			assert(i > 0);
+			convwidth_base[base] = i;
+		}
+
+		/* Find length of the string of numeric characters. */
+		scan = str;
+		while (_PyLong_DigitValue[Py_CHARMASK(*scan)] < base)
+			++scan;
+
+		/* Create a long object that can contain the largest possible
+		 * integer with this base and length.  Note that there's no
+		 * need to initialize z->ob_digit -- no slot is read up before
+		 * being stored into.
+		 */
+		size_z = (Py_ssize_t)((scan - str) * log_base_BASE[base]) + 1;
+		/* Uncomment next line to test exceedingly rare copy code */
+		/* size_z = 1; */
+		assert(size_z > 0);
+		z = _PyLong_New(size_z);
+		if (z == NULL)
+			return NULL;
+		z->ob_size = 0;
+
+		/* `convwidth` consecutive input digits are treated as a single
+		 * digit in base `convmultmax`.
+		 */
+		convwidth = convwidth_base[base];
+		convmultmax = convmultmax_base[base];
+
+		/* Work ;-) */
+		while (str < scan) {
+			/* grab up to convwidth digits from the input string */
+			c = (digit)_PyLong_DigitValue[Py_CHARMASK(*str++)];
+			for (i = 1; i < convwidth && str != scan; ++i, ++str) {
+				c = (twodigits)(c *  base +
+					_PyLong_DigitValue[Py_CHARMASK(*str)]);
+				assert(c < BASE);
+			}
+
+			convmult = convmultmax;
+			/* Calculate the shift only if we couldn't get
+			 * convwidth digits.
+			 */
+			if (i != convwidth) {
+				convmult = base;
+				for ( ; i > 1; --i)
+					convmult *= base;
+			}
+
+			/* Multiply z by convmult, and add c. */
+			pz = z->ob_digit;
+			pzstop = pz + z->ob_size;
+			for (; pz < pzstop; ++pz) {
+				c += (twodigits)*pz * convmult;
+				*pz = (digit)(c & MASK);
+				c >>= SHIFT;
+			}
+			/* carry off the current end? */
+			if (c) {
+				assert(c < BASE);
+				if (z->ob_size < size_z) {
+					*pz = (digit)c;
+					++z->ob_size;
+				}
+				else {
+					PyLongObject *tmp;
+					/* Extremely rare.  Get more space. */
+					assert(z->ob_size == size_z);
+					tmp = _PyLong_New(size_z + 1);
+					if (tmp == NULL) {
+						Py_DECREF(z);
+						return NULL;
+					}
+					memcpy(tmp->ob_digit,
+					       z->ob_digit,
+					       sizeof(digit) * size_z);
+					Py_DECREF(z);
+					z = tmp;
+					z->ob_digit[size_z] = (digit)c;
+					++size_z;
+				}
+			}
+		}
+	}
+	if (z == NULL)
+		return NULL;
+	if (str == start)
+		goto onError;
+	if (sign < 0)
+		z->ob_size = -(z->ob_size);
+	if (*str == 'L' || *str == 'l')
+		str++;
+	while (*str && isspace(Py_CHARMASK(*str)))
+		str++;
+	if (*str != '\0')
+		goto onError;
+	if (pend)
+		*pend = str;
+	return (PyObject *) z;
+
+ onError:
+	Py_XDECREF(z);
+	slen = strlen(orig_str) < 200 ? strlen(orig_str) : 200;
+	strobj = PyString_FromStringAndSize(orig_str, slen);
+	if (strobj == NULL)
+		return NULL;
+	strrepr = PyObject_Repr(strobj);
+	Py_DECREF(strobj);
+	if (strrepr == NULL)
+		return NULL;
+	PyErr_Format(PyExc_ValueError,
+		     "invalid literal for long() with base %d: %s",
+		     base, PyString_AS_STRING(strrepr));
+	Py_DECREF(strrepr);
+	return NULL;
+}
+
+#ifdef Py_USING_UNICODE
+PyObject *
+PyLong_FromUnicode(Py_UNICODE *u, Py_ssize_t length, int base)
+{
+	PyObject *result;
+	char *buffer = (char *)PyMem_MALLOC(length+1);
+
+	if (buffer == NULL)
+		return NULL;
+
+	if (PyUnicode_EncodeDecimal(u, length, buffer, NULL)) {
+		PyMem_FREE(buffer);
+		return NULL;
+	}
+	result = PyLong_FromString(buffer, NULL, base);
+	PyMem_FREE(buffer);
+	return result;
+}
+#endif
+
+/* forward */
+static PyLongObject *x_divrem
+	(PyLongObject *, PyLongObject *, PyLongObject **);
+static PyObject *long_pos(PyLongObject *);
+static int long_divrem(PyLongObject *, PyLongObject *,
+	PyLongObject **, PyLongObject **);
+
+/* Long division with remainder, top-level routine */
+
+static int
+long_divrem(PyLongObject *a, PyLongObject *b,
+	    PyLongObject **pdiv, PyLongObject **prem)
+{
+	Py_ssize_t size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
+	PyLongObject *z;
+
+	if (size_b == 0) {
+		PyErr_SetString(PyExc_ZeroDivisionError,
+				"long division or modulo by zero");
+		return -1;
+	}
+	if (size_a < size_b ||
+	    (size_a == size_b &&
+	     a->ob_digit[size_a-1] < b->ob_digit[size_b-1])) {
+		/* |a| < |b|. */
+		*pdiv = _PyLong_New(0);
+		Py_INCREF(a);
+		*prem = (PyLongObject *) a;
+		return 0;
+	}
+	if (size_b == 1) {
+		digit rem = 0;
+		z = divrem1(a, b->ob_digit[0], &rem);
+		if (z == NULL)
+			return -1;
+		*prem = (PyLongObject *) PyLong_FromLong((long)rem);
+	}
+	else {
+		z = x_divrem(a, b, prem);
+		if (z == NULL)
+			return -1;
+	}
+	/* Set the signs.
+	   The quotient z has the sign of a*b;
+	   the remainder r has the sign of a,
+	   so a = b*z + r. */
+	if ((a->ob_size < 0) != (b->ob_size < 0))
+		z->ob_size = -(z->ob_size);
+	if (a->ob_size < 0 && (*prem)->ob_size != 0)
+		(*prem)->ob_size = -((*prem)->ob_size);
+	*pdiv = z;
+	return 0;
+}
+
+/* Unsigned long division with remainder -- the algorithm */
+
+static PyLongObject *
+x_divrem(PyLongObject *v1, PyLongObject *w1, PyLongObject **prem)
+{
+	Py_ssize_t size_v = ABS(v1->ob_size), size_w = ABS(w1->ob_size);
+	digit d = (digit) ((twodigits)BASE / (w1->ob_digit[size_w-1] + 1));
+	PyLongObject *v = mul1(v1, d);
+	PyLongObject *w = mul1(w1, d);
+	PyLongObject *a;
+	Py_ssize_t j, k;
+
+	if (v == NULL || w == NULL) {
+		Py_XDECREF(v);
+		Py_XDECREF(w);
+		return NULL;
+	}
+
+	assert(size_v >= size_w && size_w > 1); /* Assert checks by div() */
+	assert(v->ob_refcnt == 1); /* Since v will be used as accumulator! */
+	assert(size_w == ABS(w->ob_size)); /* That's how d was calculated */
+
+	size_v = ABS(v->ob_size);
+	k = size_v - size_w;
+	a = _PyLong_New(k + 1);
+
+	for (j = size_v; a != NULL && k >= 0; --j, --k) {
+		digit vj = (j >= size_v) ? 0 : v->ob_digit[j];
+		twodigits q;
+		stwodigits carry = 0;
+		int i;
+
+		SIGCHECK({
+			Py_DECREF(a);
+			a = NULL;
+			break;
+		})
+		if (vj == w->ob_digit[size_w-1])
+			q = MASK;
+		else
+			q = (((twodigits)vj << SHIFT) + v->ob_digit[j-1]) /
+				w->ob_digit[size_w-1];
+
+		while (w->ob_digit[size_w-2]*q >
+				((
+					((twodigits)vj << SHIFT)
+					+ v->ob_digit[j-1]
+					- q*w->ob_digit[size_w-1]
+								) << SHIFT)
+				+ v->ob_digit[j-2])
+			--q;
+
+		for (i = 0; i < size_w && i+k < size_v; ++i) {
+			twodigits z = w->ob_digit[i] * q;
+			digit zz = (digit) (z >> SHIFT);
+			carry += v->ob_digit[i+k] - z
+				+ ((twodigits)zz << SHIFT);
+			v->ob_digit[i+k] = (digit)(carry & MASK);
+			carry = Py_ARITHMETIC_RIGHT_SHIFT(BASE_TWODIGITS_TYPE,
+							  carry, SHIFT);
+			carry -= zz;
+		}
+
+		if (i+k < size_v) {
+			carry += v->ob_digit[i+k];
+			v->ob_digit[i+k] = 0;
+		}
+
+		if (carry == 0)
+			a->ob_digit[k] = (digit) q;
+		else {
+			assert(carry == -1);
+			a->ob_digit[k] = (digit) q-1;
+			carry = 0;
+			for (i = 0; i < size_w && i+k < size_v; ++i) {
+				carry += v->ob_digit[i+k] + w->ob_digit[i];
+				v->ob_digit[i+k] = (digit)(carry & MASK);
+				carry = Py_ARITHMETIC_RIGHT_SHIFT(
+						BASE_TWODIGITS_TYPE,
+						carry, SHIFT);
+			}
+		}
+	} /* for j, k */
+
+	if (a == NULL)
+		*prem = NULL;
+	else {
+		a = long_normalize(a);
+		*prem = divrem1(v, d, &d);
+		/* d receives the (unused) remainder */
+		if (*prem == NULL) {
+			Py_DECREF(a);
+			a = NULL;
+		}
+	}
+	Py_DECREF(v);
+	Py_DECREF(w);
+	return a;
+}
+
+/* Methods */
+
+static void
+long_dealloc(PyObject *v)
+{
+	v->ob_type->tp_free(v);
+}
+
+static PyObject *
+long_repr(PyObject *v)
+{
+	return long_format(v, 10, 1);
+}
+
+static PyObject *
+long_str(PyObject *v)
+{
+	return long_format(v, 10, 0);
+}
+
+static int
+long_compare(PyLongObject *a, PyLongObject *b)
+{
+	Py_ssize_t sign;
+
+	if (a->ob_size != b->ob_size) {
+		if (ABS(a->ob_size) == 0 && ABS(b->ob_size) == 0)
+			sign = 0;
+		else
+			sign = a->ob_size - b->ob_size;
+	}
+	else {
+		Py_ssize_t i = ABS(a->ob_size);
+		while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i])
+			;
+		if (i < 0)
+			sign = 0;
+		else {
+			sign = (int)a->ob_digit[i] - (int)b->ob_digit[i];
+			if (a->ob_size < 0)
+				sign = -sign;
+		}
+	}
+	return sign < 0 ? -1 : sign > 0 ? 1 : 0;
+}
+
+static long
+long_hash(PyLongObject *v)
+{
+	long x;
+	Py_ssize_t i;
+	int sign;
+
+	/* This is designed so that Python ints and longs with the
+	   same value hash to the same value, otherwise comparisons
+	   of mapping keys will turn out weird */
+	i = v->ob_size;
+	sign = 1;
+	x = 0;
+	if (i < 0) {
+		sign = -1;
+		i = -(i);
+	}
+#define LONG_BIT_SHIFT	(8*sizeof(long) - SHIFT)
+	while (--i >= 0) {
+		/* Force a native long #-bits (32 or 64) circular shift */
+		x = ((x << SHIFT) & ~MASK) | ((x >> LONG_BIT_SHIFT) & MASK);
+		x += v->ob_digit[i];
+	}
+#undef LONG_BIT_SHIFT
+	x = x * sign;
+	if (x == -1)
+		x = -2;
+	return x;
+}
+
+
+/* Add the absolute values of two long integers. */
+
+static PyLongObject *
+x_add(PyLongObject *a, PyLongObject *b)
+{
+	Py_ssize_t size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
+	PyLongObject *z;
+	int i;
+	digit carry = 0;
+
+	/* Ensure a is the larger of the two: */
+	if (size_a < size_b) {
+		{ PyLongObject *temp = a; a = b; b = temp; }
+		{ Py_ssize_t size_temp = size_a;
+		  size_a = size_b;
+		  size_b = size_temp; }
+	}
+	z = _PyLong_New(size_a+1);
+	if (z == NULL)
+		return NULL;
+	for (i = 0; i < size_b; ++i) {
+		carry += a->ob_digit[i] + b->ob_digit[i];
+		z->ob_digit[i] = carry & MASK;
+		carry >>= SHIFT;
+	}
+	for (; i < size_a; ++i) {
+		carry += a->ob_digit[i];
+		z->ob_digit[i] = carry & MASK;
+		carry >>= SHIFT;
+	}
+	z->ob_digit[i] = carry;
+	return long_normalize(z);
+}
+
+/* Subtract the absolute values of two integers. */
+
+static PyLongObject *
+x_sub(PyLongObject *a, PyLongObject *b)
+{
+	Py_ssize_t size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
+	PyLongObject *z;
+	Py_ssize_t i;
+	int sign = 1;
+	digit borrow = 0;
+
+	/* Ensure a is the larger of the two: */
+	if (size_a < size_b) {
+		sign = -1;
+		{ PyLongObject *temp = a; a = b; b = temp; }
+		{ Py_ssize_t size_temp = size_a;
+		  size_a = size_b;
+		  size_b = size_temp; }
+	}
+	else if (size_a == size_b) {
+		/* Find highest digit where a and b differ: */
+		i = size_a;
+		while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i])
+			;
+		if (i < 0)
+			return _PyLong_New(0);
+		if (a->ob_digit[i] < b->ob_digit[i]) {
+			sign = -1;
+			{ PyLongObject *temp = a; a = b; b = temp; }
+		}
+		size_a = size_b = i+1;
+	}
+	z = _PyLong_New(size_a);
+	if (z == NULL)
+		return NULL;
+	for (i = 0; i < size_b; ++i) {
+		/* The following assumes unsigned arithmetic
+		   works module 2**N for some N>SHIFT. */
+		borrow = a->ob_digit[i] - b->ob_digit[i] - borrow;
+		z->ob_digit[i] = borrow & MASK;
+		borrow >>= SHIFT;
+		borrow &= 1; /* Keep only one sign bit */
+	}
+	for (; i < size_a; ++i) {
+		borrow = a->ob_digit[i] - borrow;
+		z->ob_digit[i] = borrow & MASK;
+		borrow >>= SHIFT;
+		borrow &= 1; /* Keep only one sign bit */
+	}
+	assert(borrow == 0);
+	if (sign < 0)
+		z->ob_size = -(z->ob_size);
+	return long_normalize(z);
+}
+
+static PyObject *
+long_add(PyLongObject *v, PyLongObject *w)
+{
+	PyLongObject *a, *b, *z;
+
+	CONVERT_BINOP((PyObject *)v, (PyObject *)w, &a, &b);
+
+	if (a->ob_size < 0) {
+		if (b->ob_size < 0) {
+			z = x_add(a, b);
+			if (z != NULL && z->ob_size != 0)
+				z->ob_size = -(z->ob_size);
+		}
+		else
+			z = x_sub(b, a);
+	}
+	else {
+		if (b->ob_size < 0)
+			z = x_sub(a, b);
+		else
+			z = x_add(a, b);
+	}
+	Py_DECREF(a);
+	Py_DECREF(b);
+	return (PyObject *)z;
+}
+
+static PyObject *
+long_sub(PyLongObject *v, PyLongObject *w)
+{
+	PyLongObject *a, *b, *z;
+
+	CONVERT_BINOP((PyObject *)v, (PyObject *)w, &a, &b);
+
+	if (a->ob_size < 0) {
+		if (b->ob_size < 0)
+			z = x_sub(a, b);
+		else
+			z = x_add(a, b);
+		if (z != NULL && z->ob_size != 0)
+			z->ob_size = -(z->ob_size);
+	}
+	else {
+		if (b->ob_size < 0)
+			z = x_add(a, b);
+		else
+			z = x_sub(a, b);
+	}
+	Py_DECREF(a);
+	Py_DECREF(b);
+	return (PyObject *)z;
+}
+
+/* Grade school multiplication, ignoring the signs.
+ * Returns the absolute value of the product, or NULL if error.
+ */
+static PyLongObject *
+x_mul(PyLongObject *a, PyLongObject *b)
+{
+	PyLongObject *z;
+	Py_ssize_t size_a = ABS(a->ob_size);
+	Py_ssize_t size_b = ABS(b->ob_size);
+	Py_ssize_t i;
+
+     	z = _PyLong_New(size_a + size_b);
+	if (z == NULL)
+		return NULL;
+
+	memset(z->ob_digit, 0, z->ob_size * sizeof(digit));
+	if (a == b) {
+		/* Efficient squaring per HAC, Algorithm 14.16:
+		 * http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf
+		 * Gives slightly less than a 2x speedup when a == b,
+		 * via exploiting that each entry in the multiplication
+		 * pyramid appears twice (except for the size_a squares).
+		 */
+		for (i = 0; i < size_a; ++i) {
+			twodigits carry;
+			twodigits f = a->ob_digit[i];
+			digit *pz = z->ob_digit + (i << 1);
+			digit *pa = a->ob_digit + i + 1;
+			digit *paend = a->ob_digit + size_a;
+
+			SIGCHECK({
+				Py_DECREF(z);
+				return NULL;
+			})
+
+			carry = *pz + f * f;
+			*pz++ = (digit)(carry & MASK);
+			carry >>= SHIFT;
+			assert(carry <= MASK);
+
+			/* Now f is added in twice in each column of the
+			 * pyramid it appears.  Same as adding f<<1 once.
+			 */
+			f <<= 1;
+			while (pa < paend) {
+				carry += *pz + *pa++ * f;
+				*pz++ = (digit)(carry & MASK);
+				carry >>= SHIFT;
+				assert(carry <= (MASK << 1));
+			}
+			if (carry) {
+				carry += *pz;
+				*pz++ = (digit)(carry & MASK);
+				carry >>= SHIFT;
+			}
+			if (carry)
+				*pz += (digit)(carry & MASK);
+			assert((carry >> SHIFT) == 0);
+		}
+	}
+	else {	/* a is not the same as b -- gradeschool long mult */
+		for (i = 0; i < size_a; ++i) {
+			twodigits carry = 0;
+			twodigits f = a->ob_digit[i];
+			digit *pz = z->ob_digit + i;
+			digit *pb = b->ob_digit;
+			digit *pbend = b->ob_digit + size_b;
+
+			SIGCHECK({
+				Py_DECREF(z);
+				return NULL;
+			})
+
+			while (pb < pbend) {
+				carry += *pz + *pb++ * f;
+				*pz++ = (digit)(carry & MASK);
+				carry >>= SHIFT;
+				assert(carry <= MASK);
+			}
+			if (carry)
+				*pz += (digit)(carry & MASK);
+			assert((carry >> SHIFT) == 0);
+		}
+	}
+	return long_normalize(z);
+}
+
+/* A helper for Karatsuba multiplication (k_mul).
+   Takes a long "n" and an integer "size" representing the place to
+   split, and sets low and high such that abs(n) == (high << size) + low,
+   viewing the shift as being by digits.  The sign bit is ignored, and
+   the return values are >= 0.
+   Returns 0 on success, -1 on failure.
+*/
+static int
+kmul_split(PyLongObject *n, Py_ssize_t size, PyLongObject **high, PyLongObject **low)
+{
+	PyLongObject *hi, *lo;
+	Py_ssize_t size_lo, size_hi;
+	const Py_ssize_t size_n = ABS(n->ob_size);
+
+	size_lo = MIN(size_n, size);
+	size_hi = size_n - size_lo;
+
+	if ((hi = _PyLong_New(size_hi)) == NULL)
+		return -1;
+	if ((lo = _PyLong_New(size_lo)) == NULL) {
+		Py_DECREF(hi);
+		return -1;
+	}
+
+	memcpy(lo->ob_digit, n->ob_digit, size_lo * sizeof(digit));
+	memcpy(hi->ob_digit, n->ob_digit + size_lo, size_hi * sizeof(digit));
+
+	*high = long_normalize(hi);
+	*low = long_normalize(lo);
+	return 0;
+}
+
+static PyLongObject *k_lopsided_mul(PyLongObject *a, PyLongObject *b);
+
+/* Karatsuba multiplication.  Ignores the input signs, and returns the
+ * absolute value of the product (or NULL if error).
+ * See Knuth Vol. 2 Chapter 4.3.3 (Pp. 294-295).
+ */
+static PyLongObject *
+k_mul(PyLongObject *a, PyLongObject *b)
+{
+	Py_ssize_t asize = ABS(a->ob_size);
+	Py_ssize_t bsize = ABS(b->ob_size);
+	PyLongObject *ah = NULL;
+	PyLongObject *al = NULL;
+	PyLongObject *bh = NULL;
+	PyLongObject *bl = NULL;
+	PyLongObject *ret = NULL;
+	PyLongObject *t1, *t2, *t3;
+	Py_ssize_t shift;	/* the number of digits we split off */
+	Py_ssize_t i;
+
+	/* (ah*X+al)(bh*X+bl) = ah*bh*X*X + (ah*bl + al*bh)*X + al*bl
+	 * Let k = (ah+al)*(bh+bl) = ah*bl + al*bh  + ah*bh + al*bl
+	 * Then the original product is
+	 *     ah*bh*X*X + (k - ah*bh - al*bl)*X + al*bl
+	 * By picking X to be a power of 2, "*X" is just shifting, and it's
+	 * been reduced to 3 multiplies on numbers half the size.
+	 */
+
+	/* We want to split based on the larger number; fiddle so that b
+	 * is largest.
+	 */
+	if (asize > bsize) {
+		t1 = a;
+		a = b;
+		b = t1;
+
+		i = asize;
+		asize = bsize;
+		bsize = i;
+	}
+
+	/* Use gradeschool math when either number is too small. */
+	i = a == b ? KARATSUBA_SQUARE_CUTOFF : KARATSUBA_CUTOFF;
+	if (asize <= i) {
+		if (asize == 0)
+			return _PyLong_New(0);
+		else
+			return x_mul(a, b);
+	}
+
+	/* If a is small compared to b, splitting on b gives a degenerate
+	 * case with ah==0, and Karatsuba may be (even much) less efficient
+	 * than "grade school" then.  However, we can still win, by viewing
+	 * b as a string of "big digits", each of width a->ob_size.  That
+	 * leads to a sequence of balanced calls to k_mul.
+	 */
+	if (2 * asize <= bsize)
+		return k_lopsided_mul(a, b);
+
+	/* Split a & b into hi & lo pieces. */
+	shift = bsize >> 1;
+	if (kmul_split(a, shift, &ah, &al) < 0) goto fail;
+	assert(ah->ob_size > 0);	/* the split isn't degenerate */
+
+	if (a == b) {
+		bh = ah;
+		bl = al;
+		Py_INCREF(bh);
+		Py_INCREF(bl);
+	}
+	else if (kmul_split(b, shift, &bh, &bl) < 0) goto fail;
+
+	/* The plan:
+	 * 1. Allocate result space (asize + bsize digits:  that's always
+	 *    enough).
+	 * 2. Compute ah*bh, and copy into result at 2*shift.
+	 * 3. Compute al*bl, and copy into result at 0.  Note that this
+	 *    can't overlap with #2.
+	 * 4. Subtract al*bl from the result, starting at shift.  This may
+	 *    underflow (borrow out of the high digit), but we don't care:
+	 *    we're effectively doing unsigned arithmetic mod
+	 *    BASE**(sizea + sizeb), and so long as the *final* result fits,
+	 *    borrows and carries out of the high digit can be ignored.
+	 * 5. Subtract ah*bh from the result, starting at shift.
+	 * 6. Compute (ah+al)*(bh+bl), and add it into the result starting
+	 *    at shift.
+	 */
+
+	/* 1. Allocate result space. */
+	ret = _PyLong_New(asize + bsize);
+	if (ret == NULL) goto fail;
+#ifdef Py_DEBUG
+	/* Fill with trash, to catch reference to uninitialized digits. */
+	memset(ret->ob_digit, 0xDF, ret->ob_size * sizeof(digit));
+#endif
+
+	/* 2. t1 <- ah*bh, and copy into high digits of result. */
+	if ((t1 = k_mul(ah, bh)) == NULL) goto fail;
+	assert(t1->ob_size >= 0);
+	assert(2*shift + t1->ob_size <= ret->ob_size);
+	memcpy(ret->ob_digit + 2*shift, t1->ob_digit,
+	       t1->ob_size * sizeof(digit));
+
+	/* Zero-out the digits higher than the ah*bh copy. */
+	i = ret->ob_size - 2*shift - t1->ob_size;
+	if (i)
+		memset(ret->ob_digit + 2*shift + t1->ob_size, 0,
+		       i * sizeof(digit));
+
+	/* 3. t2 <- al*bl, and copy into the low digits. */
+	if ((t2 = k_mul(al, bl)) == NULL) {
+		Py_DECREF(t1);
+		goto fail;
+	}
+	assert(t2->ob_size >= 0);
+	assert(t2->ob_size <= 2*shift); /* no overlap with high digits */
+	memcpy(ret->ob_digit, t2->ob_digit, t2->ob_size * sizeof(digit));
+
+	/* Zero out remaining digits. */
+	i = 2*shift - t2->ob_size;	/* number of uninitialized digits */
+	if (i)
+		memset(ret->ob_digit + t2->ob_size, 0, i * sizeof(digit));
+
+	/* 4 & 5. Subtract ah*bh (t1) and al*bl (t2).  We do al*bl first
+	 * because it's fresher in cache.
+	 */
+	i = ret->ob_size - shift;  /* # digits after shift */
+	(void)v_isub(ret->ob_digit + shift, i, t2->ob_digit, t2->ob_size);
+	Py_DECREF(t2);
+
+	(void)v_isub(ret->ob_digit + shift, i, t1->ob_digit, t1->ob_size);
+	Py_DECREF(t1);
+
+	/* 6. t3 <- (ah+al)(bh+bl), and add into result. */
+	if ((t1 = x_add(ah, al)) == NULL) goto fail;
+	Py_DECREF(ah);
+	Py_DECREF(al);
+	ah = al = NULL;
+
+	if (a == b) {
+		t2 = t1;
+		Py_INCREF(t2);
+	}
+	else if ((t2 = x_add(bh, bl)) == NULL) {
+		Py_DECREF(t1);
+		goto fail;
+	}
+	Py_DECREF(bh);
+	Py_DECREF(bl);
+	bh = bl = NULL;
+
+	t3 = k_mul(t1, t2);
+	Py_DECREF(t1);
+	Py_DECREF(t2);
+	if (t3 == NULL) goto fail;
+	assert(t3->ob_size >= 0);
+
+	/* Add t3.  It's not obvious why we can't run out of room here.
+	 * See the (*) comment after this function.
+	 */
+	(void)v_iadd(ret->ob_digit + shift, i, t3->ob_digit, t3->ob_size);
+	Py_DECREF(t3);
+
+	return long_normalize(ret);
+
+ fail:
+ 	Py_XDECREF(ret);
+	Py_XDECREF(ah);
+	Py_XDECREF(al);
+	Py_XDECREF(bh);
+	Py_XDECREF(bl);
+	return NULL;
+}
+
+/* (*) Why adding t3 can't "run out of room" above.
+
+Let f(x) mean the floor of x and c(x) mean the ceiling of x.  Some facts
+to start with:
+
+1. For any integer i, i = c(i/2) + f(i/2).  In particular,
+   bsize = c(bsize/2) + f(bsize/2).
+2. shift = f(bsize/2)
+3. asize <= bsize
+4. Since we call k_lopsided_mul if asize*2 <= bsize, asize*2 > bsize in this
+   routine, so asize > bsize/2 >= f(bsize/2) in this routine.
+
+We allocated asize + bsize result digits, and add t3 into them at an offset
+of shift.  This leaves asize+bsize-shift allocated digit positions for t3
+to fit into, = (by #1 and #2) asize + f(bsize/2) + c(bsize/2) - f(bsize/2) =
+asize + c(bsize/2) available digit positions.
+
+bh has c(bsize/2) digits, and bl at most f(size/2) digits.  So bh+hl has
+at most c(bsize/2) digits + 1 bit.
+
+If asize == bsize, ah has c(bsize/2) digits, else ah has at most f(bsize/2)
+digits, and al has at most f(bsize/2) digits in any case.  So ah+al has at
+most (asize == bsize ? c(bsize/2) : f(bsize/2)) digits + 1 bit.
+
+The product (ah+al)*(bh+bl) therefore has at most
+
+    c(bsize/2) + (asize == bsize ? c(bsize/2) : f(bsize/2)) digits + 2 bits
+
+and we have asize + c(bsize/2) available digit positions.  We need to show
+this is always enough.  An instance of c(bsize/2) cancels out in both, so
+the question reduces to whether asize digits is enough to hold
+(asize == bsize ? c(bsize/2) : f(bsize/2)) digits + 2 bits.  If asize < bsize,
+then we're asking whether asize digits >= f(bsize/2) digits + 2 bits.  By #4,
+asize is at least f(bsize/2)+1 digits, so this in turn reduces to whether 1
+digit is enough to hold 2 bits.  This is so since SHIFT=15 >= 2.  If
+asize == bsize, then we're asking whether bsize digits is enough to hold
+c(bsize/2) digits + 2 bits, or equivalently (by #1) whether f(bsize/2) digits
+is enough to hold 2 bits.  This is so if bsize >= 2, which holds because
+bsize >= KARATSUBA_CUTOFF >= 2.
+
+Note that since there's always enough room for (ah+al)*(bh+bl), and that's
+clearly >= each of ah*bh and al*bl, there's always enough room to subtract
+ah*bh and al*bl too.
+*/
+
+/* b has at least twice the digits of a, and a is big enough that Karatsuba
+ * would pay off *if* the inputs had balanced sizes.  View b as a sequence
+ * of slices, each with a->ob_size digits, and multiply the slices by a,
+ * one at a time.  This gives k_mul balanced inputs to work with, and is
+ * also cache-friendly (we compute one double-width slice of the result
+ * at a time, then move on, never bactracking except for the helpful
+ * single-width slice overlap between successive partial sums).
+ */
+static PyLongObject *
+k_lopsided_mul(PyLongObject *a, PyLongObject *b)
+{
+	const Py_ssize_t asize = ABS(a->ob_size);
+	Py_ssize_t bsize = ABS(b->ob_size);
+	Py_ssize_t nbdone;	/* # of b digits already multiplied */
+	PyLongObject *ret;
+	PyLongObject *bslice = NULL;
+
+	assert(asize > KARATSUBA_CUTOFF);
+	assert(2 * asize <= bsize);
+
+	/* Allocate result space, and zero it out. */
+	ret = _PyLong_New(asize + bsize);
+	if (ret == NULL)
+		return NULL;
+	memset(ret->ob_digit, 0, ret->ob_size * sizeof(digit));
+
+	/* Successive slices of b are copied into bslice. */
+	bslice = _PyLong_New(asize);
+	if (bslice == NULL)
+		goto fail;
+
+	nbdone = 0;
+	while (bsize > 0) {
+		PyLongObject *product;
+		const Py_ssize_t nbtouse = MIN(bsize, asize);
+
+		/* Multiply the next slice of b by a. */
+		memcpy(bslice->ob_digit, b->ob_digit + nbdone,
+		       nbtouse * sizeof(digit));
+		bslice->ob_size = nbtouse;
+		product = k_mul(a, bslice);
+		if (product == NULL)
+			goto fail;
+
+		/* Add into result. */
+		(void)v_iadd(ret->ob_digit + nbdone, ret->ob_size - nbdone,
+			     product->ob_digit, product->ob_size);
+		Py_DECREF(product);
+
+		bsize -= nbtouse;
+		nbdone += nbtouse;
+	}
+
+	Py_DECREF(bslice);
+	return long_normalize(ret);
+
+ fail:
+	Py_DECREF(ret);
+	Py_XDECREF(bslice);
+	return NULL;
+}
+
+static PyObject *
+long_mul(PyLongObject *v, PyLongObject *w)
+{
+	PyLongObject *a, *b, *z;
+
+	if (!convert_binop((PyObject *)v, (PyObject *)w, &a, &b)) {
+		Py_INCREF(Py_NotImplemented);
+		return Py_NotImplemented;
+	}
+
+	z = k_mul(a, b);
+	/* Negate if exactly one of the inputs is negative. */
+	if (((a->ob_size ^ b->ob_size) < 0) && z)
+		z->ob_size = -(z->ob_size);
+	Py_DECREF(a);
+	Py_DECREF(b);
+	return (PyObject *)z;
+}
+
+/* The / and % operators are now defined in terms of divmod().
+   The expression a mod b has the value a - b*floor(a/b).
+   The long_divrem function gives the remainder after division of
+   |a| by |b|, with the sign of a.  This is also expressed
+   as a - b*trunc(a/b), if trunc truncates towards zero.
+   Some examples:
+   	 a	 b	a rem b		a mod b
+   	 13	 10	 3		 3
+   	-13	 10	-3		 7
+   	 13	-10	 3		-7
+   	-13	-10	-3		-3
+   So, to get from rem to mod, we have to add b if a and b
+   have different signs.  We then subtract one from the 'div'
+   part of the outcome to keep the invariant intact. */
+
+/* Compute
+ *     *pdiv, *pmod = divmod(v, w)
+ * NULL can be passed for pdiv or pmod, in which case that part of
+ * the result is simply thrown away.  The caller owns a reference to
+ * each of these it requests (does not pass NULL for).
+ */
+static int
+l_divmod(PyLongObject *v, PyLongObject *w,
+	 PyLongObject **pdiv, PyLongObject **pmod)
+{
+	PyLongObject *div, *mod;
+
+	if (long_divrem(v, w, &div, &mod) < 0)
+		return -1;
+	if ((mod->ob_size < 0 && w->ob_size > 0) ||
+	    (mod->ob_size > 0 && w->ob_size < 0)) {
+		PyLongObject *temp;
+		PyLongObject *one;
+		temp = (PyLongObject *) long_add(mod, w);
+		Py_DECREF(mod);
+		mod = temp;
+		if (mod == NULL) {
+			Py_DECREF(div);
+			return -1;
+		}
+		one = (PyLongObject *) PyLong_FromLong(1L);
+		if (one == NULL ||
+		    (temp = (PyLongObject *) long_sub(div, one)) == NULL) {
+			Py_DECREF(mod);
+			Py_DECREF(div);
+			Py_XDECREF(one);
+			return -1;
+		}
+		Py_DECREF(one);
+		Py_DECREF(div);
+		div = temp;
+	}
+	if (pdiv != NULL)
+		*pdiv = div;
+	else
+		Py_DECREF(div);
+
+	if (pmod != NULL)
+		*pmod = mod;
+	else
+		Py_DECREF(mod);
+
+	return 0;
+}
+
+static PyObject *
+long_div(PyObject *v, PyObject *w)
+{
+	PyLongObject *a, *b, *div;
+
+	CONVERT_BINOP(v, w, &a, &b);
+	if (l_divmod(a, b, &div, NULL) < 0)
+		div = NULL;
+	Py_DECREF(a);
+	Py_DECREF(b);
+	return (PyObject *)div;
+}
+
+static PyObject *
+long_classic_div(PyObject *v, PyObject *w)
+{
+	PyLongObject *a, *b, *div;
+
+	CONVERT_BINOP(v, w, &a, &b);
+	if (Py_DivisionWarningFlag &&
+	    PyErr_Warn(PyExc_DeprecationWarning, "classic long division") < 0)
+		div = NULL;
+	else if (l_divmod(a, b, &div, NULL) < 0)
+		div = NULL;
+	Py_DECREF(a);
+	Py_DECREF(b);
+	return (PyObject *)div;
+}
+
+static PyObject *
+long_true_divide(PyObject *v, PyObject *w)
+{
+	PyLongObject *a, *b;
+	double ad, bd;
+	int failed, aexp = -1, bexp = -1;
+
+	CONVERT_BINOP(v, w, &a, &b);
+	ad = _PyLong_AsScaledDouble((PyObject *)a, &aexp);
+	bd = _PyLong_AsScaledDouble((PyObject *)b, &bexp);
+	failed = (ad == -1.0 || bd == -1.0) && PyErr_Occurred();
+	Py_DECREF(a);
+	Py_DECREF(b);
+	if (failed)
+		return NULL;
+	/* 'aexp' and 'bexp' were initialized to -1 to silence gcc-4.0.x,
+	   but should really be set correctly after sucessful calls to
+	   _PyLong_AsScaledDouble() */
+	assert(aexp >= 0 && bexp >= 0);
+
+	if (bd == 0.0) {
+		PyErr_SetString(PyExc_ZeroDivisionError,
+			"long division or modulo by zero");
+		return NULL;
+	}
+
+	/* True value is very close to ad/bd * 2**(SHIFT*(aexp-bexp)) */
+	ad /= bd;	/* overflow/underflow impossible here */
+	aexp -= bexp;
+	if (aexp > INT_MAX / SHIFT)
+		goto overflow;
+	else if (aexp < -(INT_MAX / SHIFT))
+		return PyFloat_FromDouble(0.0);	/* underflow to 0 */
+	errno = 0;
+	ad = ldexp(ad, aexp * SHIFT);
+	if (Py_OVERFLOWED(ad)) /* ignore underflow to 0.0 */
+		goto overflow;
+	return PyFloat_FromDouble(ad);
+
+overflow:
+	PyErr_SetString(PyExc_OverflowError,
+		"long/long too large for a float");
+	return NULL;
+
+}
+
+static PyObject *
+long_mod(PyObject *v, PyObject *w)
+{
+	PyLongObject *a, *b, *mod;
+
+	CONVERT_BINOP(v, w, &a, &b);
+
+	if (l_divmod(a, b, NULL, &mod) < 0)
+		mod = NULL;
+	Py_DECREF(a);
+	Py_DECREF(b);
+	return (PyObject *)mod;
+}
+
+static PyObject *
+long_divmod(PyObject *v, PyObject *w)
+{
+	PyLongObject *a, *b, *div, *mod;
+	PyObject *z;
+
+	CONVERT_BINOP(v, w, &a, &b);
+
+	if (l_divmod(a, b, &div, &mod) < 0) {
+		Py_DECREF(a);
+		Py_DECREF(b);
+		return NULL;
+	}
+	z = PyTuple_New(2);
+	if (z != NULL) {
+		PyTuple_SetItem(z, 0, (PyObject *) div);
+		PyTuple_SetItem(z, 1, (PyObject *) mod);
+	}
+	else {
+		Py_DECREF(div);
+		Py_DECREF(mod);
+	}
+	Py_DECREF(a);
+	Py_DECREF(b);
+	return z;
+}
+
+/* pow(v, w, x) */
+static PyObject *
+long_pow(PyObject *v, PyObject *w, PyObject *x)
+{
+	PyLongObject *a, *b, *c; /* a,b,c = v,w,x */
+	int negativeOutput = 0;  /* if x<0 return negative output */
+
+	PyLongObject *z = NULL;  /* accumulated result */
+	Py_ssize_t i, j, k;             /* counters */
+	PyLongObject *temp = NULL;
+
+	/* 5-ary values.  If the exponent is large enough, table is
+	 * precomputed so that table[i] == a**i % c for i in range(32).
+	 */
+	PyLongObject *table[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+				   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+
+	/* a, b, c = v, w, x */
+	CONVERT_BINOP(v, w, &a, &b);
+	if (PyLong_Check(x)) {
+		c = (PyLongObject *)x;
+		Py_INCREF(x);
+	}
+	else if (PyInt_Check(x)) {
+		c = (PyLongObject *)PyLong_FromLong(PyInt_AS_LONG(x));
+		if (c == NULL)
+			goto Error;
+	}
+	else if (x == Py_None)
+		c = NULL;
+	else {
+		Py_DECREF(a);
+		Py_DECREF(b);
+		Py_INCREF(Py_NotImplemented);
+		return Py_NotImplemented;
+	}
+
+	if (b->ob_size < 0) {  /* if exponent is negative */
+		if (c) {
+			PyErr_SetString(PyExc_TypeError, "pow() 2nd argument "
+			    "cannot be negative when 3rd argument specified");
+			goto Error;
+		}
+		else {
+			/* else return a float.  This works because we know
+			   that this calls float_pow() which converts its
+			   arguments to double. */
+			Py_DECREF(a);
+			Py_DECREF(b);
+			return PyFloat_Type.tp_as_number->nb_power(v, w, x);
+		}
+	}
+
+	if (c) {
+		/* if modulus == 0:
+		       raise ValueError() */
+		if (c->ob_size == 0) {
+			PyErr_SetString(PyExc_ValueError,
+					"pow() 3rd argument cannot be 0");
+			goto Error;
+		}
+
+		/* if modulus < 0:
+		       negativeOutput = True
+		       modulus = -modulus */
+		if (c->ob_size < 0) {
+			negativeOutput = 1;
+			temp = (PyLongObject *)_PyLong_Copy(c);
+			if (temp == NULL)
+				goto Error;
+			Py_DECREF(c);
+			c = temp;
+			temp = NULL;
+			c->ob_size = - c->ob_size;
+		}
+
+		/* if modulus == 1:
+		       return 0 */
+		if ((c->ob_size == 1) && (c->ob_digit[0] == 1)) {
+			z = (PyLongObject *)PyLong_FromLong(0L);
+			goto Done;
+		}
+
+		/* if base < 0:
+		       base = base % modulus
+		   Having the base positive just makes things easier. */
+		if (a->ob_size < 0) {
+			if (l_divmod(a, c, NULL, &temp) < 0)
+				goto Error;
+			Py_DECREF(a);
+			a = temp;
+			temp = NULL;
+		}
+	}
+
+	/* At this point a, b, and c are guaranteed non-negative UNLESS
+	   c is NULL, in which case a may be negative. */
+
+	z = (PyLongObject *)PyLong_FromLong(1L);
+	if (z == NULL)
+		goto Error;
+
+	/* Perform a modular reduction, X = X % c, but leave X alone if c
+	 * is NULL.
+	 */
+#define REDUCE(X)					\
+	if (c != NULL) {				\
+		if (l_divmod(X, c, NULL, &temp) < 0)	\
+			goto Error;			\
+		Py_XDECREF(X);				\
+		X = temp;				\
+		temp = NULL;				\
+	}
+
+	/* Multiply two values, then reduce the result:
+	   result = X*Y % c.  If c is NULL, skip the mod. */
+#define MULT(X, Y, result)				\
+{							\
+	temp = (PyLongObject *)long_mul(X, Y);		\
+	if (temp == NULL)				\
+		goto Error;				\
+	Py_XDECREF(result);				\
+	result = temp;					\
+	temp = NULL;					\
+	REDUCE(result)					\
+}
+
+	if (b->ob_size <= FIVEARY_CUTOFF) {
+		/* Left-to-right binary exponentiation (HAC Algorithm 14.79) */
+		/* http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf    */
+		for (i = b->ob_size - 1; i >= 0; --i) {
+			digit bi = b->ob_digit[i];
+
+			for (j = 1 << (SHIFT-1); j != 0; j >>= 1) {
+				MULT(z, z, z)
+				if (bi & j)
+					MULT(z, a, z)
+			}
+		}
+	}
+	else {
+		/* Left-to-right 5-ary exponentiation (HAC Algorithm 14.82) */
+		Py_INCREF(z);	/* still holds 1L */
+		table[0] = z;
+		for (i = 1; i < 32; ++i)
+			MULT(table[i-1], a, table[i])
+
+		for (i = b->ob_size - 1; i >= 0; --i) {
+			const digit bi = b->ob_digit[i];
+
+			for (j = SHIFT - 5; j >= 0; j -= 5) {
+				const int index = (bi >> j) & 0x1f;
+				for (k = 0; k < 5; ++k)
+					MULT(z, z, z)
+				if (index)
+					MULT(z, table[index], z)
+			}
+		}
+	}
+
+	if (negativeOutput && (z->ob_size != 0)) {
+		temp = (PyLongObject *)long_sub(z, c);
+		if (temp == NULL)
+			goto Error;
+		Py_DECREF(z);
+		z = temp;
+		temp = NULL;
+	}
+	goto Done;
+
+ Error:
+ 	if (z != NULL) {
+ 		Py_DECREF(z);
+ 		z = NULL;
+ 	}
+	/* fall through */
+ Done:
+	if (b->ob_size > FIVEARY_CUTOFF) {
+		for (i = 0; i < 32; ++i)
+			Py_XDECREF(table[i]);
+	}
+	Py_DECREF(a);
+	Py_DECREF(b);
+	Py_XDECREF(c);
+	Py_XDECREF(temp);
+	return (PyObject *)z;
+}
+
+static PyObject *
+long_invert(PyLongObject *v)
+{
+	/* Implement ~x as -(x+1) */
+	PyLongObject *x;
+	PyLongObject *w;
+	w = (PyLongObject *)PyLong_FromLong(1L);
+	if (w == NULL)
+		return NULL;
+	x = (PyLongObject *) long_add(v, w);
+	Py_DECREF(w);
+	if (x == NULL)
+		return NULL;
+	x->ob_size = -(x->ob_size);
+	return (PyObject *)x;
+}
+
+static PyObject *
+long_pos(PyLongObject *v)
+{
+	if (PyLong_CheckExact(v)) {
+		Py_INCREF(v);
+		return (PyObject *)v;
+	}
+	else
+		return _PyLong_Copy(v);
+}
+
+static PyObject *
+long_neg(PyLongObject *v)
+{
+	PyLongObject *z;
+	if (v->ob_size == 0 && PyLong_CheckExact(v)) {
+		/* -0 == 0 */
+		Py_INCREF(v);
+		return (PyObject *) v;
+	}
+	z = (PyLongObject *)_PyLong_Copy(v);
+	if (z != NULL)
+		z->ob_size = -(v->ob_size);
+	return (PyObject *)z;
+}
+
+static PyObject *
+long_abs(PyLongObject *v)
+{
+	if (v->ob_size < 0)
+		return long_neg(v);
+	else
+		return long_pos(v);
+}
+
+static int
+long_nonzero(PyLongObject *v)
+{
+	return ABS(v->ob_size) != 0;
+}
+
+static PyObject *
+long_rshift(PyLongObject *v, PyLongObject *w)
+{
+	PyLongObject *a, *b;
+	PyLongObject *z = NULL;
+	long shiftby;
+	Py_ssize_t newsize, wordshift, loshift, hishift, i, j;
+	digit lomask, himask;
+
+	CONVERT_BINOP((PyObject *)v, (PyObject *)w, &a, &b);
+
+	if (a->ob_size < 0) {
+		/* Right shifting negative numbers is harder */
+		PyLongObject *a1, *a2;
+		a1 = (PyLongObject *) long_invert(a);
+		if (a1 == NULL)
+			goto rshift_error;
+		a2 = (PyLongObject *) long_rshift(a1, b);
+		Py_DECREF(a1);
+		if (a2 == NULL)
+			goto rshift_error;
+		z = (PyLongObject *) long_invert(a2);
+		Py_DECREF(a2);
+	}
+	else {
+
+		shiftby = PyLong_AsLong((PyObject *)b);
+		if (shiftby == -1L && PyErr_Occurred())
+			goto rshift_error;
+		if (shiftby < 0) {
+			PyErr_SetString(PyExc_ValueError,
+					"negative shift count");
+			goto rshift_error;
+		}
+		wordshift = shiftby / SHIFT;
+		newsize = ABS(a->ob_size) - wordshift;
+		if (newsize <= 0) {
+			z = _PyLong_New(0);
+			Py_DECREF(a);
+			Py_DECREF(b);
+			return (PyObject *)z;
+		}
+		loshift = shiftby % SHIFT;
+		hishift = SHIFT - loshift;
+		lomask = ((digit)1 << hishift) - 1;
+		himask = MASK ^ lomask;
+		z = _PyLong_New(newsize);
+		if (z == NULL)
+			goto rshift_error;
+		if (a->ob_size < 0)
+			z->ob_size = -(z->ob_size);
+		for (i = 0, j = wordshift; i < newsize; i++, j++) {
+			z->ob_digit[i] = (a->ob_digit[j] >> loshift) & lomask;
+			if (i+1 < newsize)
+				z->ob_digit[i] |=
+				  (a->ob_digit[j+1] << hishift) & himask;
+		}
+		z = long_normalize(z);
+	}
+rshift_error:
+	Py_DECREF(a);
+	Py_DECREF(b);
+	return (PyObject *) z;
+
+}
+
+static PyObject *
+long_lshift(PyObject *v, PyObject *w)
+{
+	/* This version due to Tim Peters */
+	PyLongObject *a, *b;
+	PyLongObject *z = NULL;
+	long shiftby;
+	Py_ssize_t oldsize, newsize, wordshift, remshift, i, j;
+	twodigits accum;
+
+	CONVERT_BINOP(v, w, &a, &b);
+
+	shiftby = PyLong_AsLong((PyObject *)b);
+	if (shiftby == -1L && PyErr_Occurred())
+		goto lshift_error;
+	if (shiftby < 0) {
+		PyErr_SetString(PyExc_ValueError, "negative shift count");
+		goto lshift_error;
+	}
+	if ((long)(int)shiftby != shiftby) {
+		PyErr_SetString(PyExc_ValueError,
+				"outrageous left shift count");
+		goto lshift_error;
+	}
+	/* wordshift, remshift = divmod(shiftby, SHIFT) */
+	wordshift = (int)shiftby / SHIFT;
+	remshift  = (int)shiftby - wordshift * SHIFT;
+
+	oldsize = ABS(a->ob_size);
+	newsize = oldsize + wordshift;
+	if (remshift)
+		++newsize;
+	z = _PyLong_New(newsize);
+	if (z == NULL)
+		goto lshift_error;
+	if (a->ob_size < 0)
+		z->ob_size = -(z->ob_size);
+	for (i = 0; i < wordshift; i++)
+		z->ob_digit[i] = 0;
+	accum = 0;
+	for (i = wordshift, j = 0; j < oldsize; i++, j++) {
+		accum |= (twodigits)a->ob_digit[j] << remshift;
+		z->ob_digit[i] = (digit)(accum & MASK);
+		accum >>= SHIFT;
+	}
+	if (remshift)
+		z->ob_digit[newsize-1] = (digit)accum;
+	else
+		assert(!accum);
+	z = long_normalize(z);
+lshift_error:
+	Py_DECREF(a);
+	Py_DECREF(b);
+	return (PyObject *) z;
+}
+
+
+/* Bitwise and/xor/or operations */
+
+static PyObject *
+long_bitwise(PyLongObject *a,
+	     int op,  /* '&', '|', '^' */
+	     PyLongObject *b)
+{
+	digit maska, maskb; /* 0 or MASK */
+	int negz;
+	Py_ssize_t size_a, size_b, size_z;
+	PyLongObject *z;
+	int i;
+	digit diga, digb;
+	PyObject *v;
+
+	if (a->ob_size < 0) {
+		a = (PyLongObject *) long_invert(a);
+		if (a == NULL)
+			return NULL;
+		maska = MASK;
+	}
+	else {
+		Py_INCREF(a);
+		maska = 0;
+	}
+	if (b->ob_size < 0) {
+		b = (PyLongObject *) long_invert(b);
+		if (b == NULL) {
+			Py_DECREF(a);
+			return NULL;
+		}
+		maskb = MASK;
+	}
+	else {
+		Py_INCREF(b);
+		maskb = 0;
+	}
+
+	negz = 0;
+	switch (op) {
+	case '^':
+		if (maska != maskb) {
+			maska ^= MASK;
+			negz = -1;
+		}
+		break;
+	case '&':
+		if (maska && maskb) {
+			op = '|';
+			maska ^= MASK;
+			maskb ^= MASK;
+			negz = -1;
+		}
+		break;
+	case '|':
+		if (maska || maskb) {
+			op = '&';
+			maska ^= MASK;
+			maskb ^= MASK;
+			negz = -1;
+		}
+		break;
+	}
+
+	/* JRH: The original logic here was to allocate the result value (z)
+	   as the longer of the two operands.  However, there are some cases
+	   where the result is guaranteed to be shorter than that: AND of two
+	   positives, OR of two negatives: use the shorter number.  AND with
+	   mixed signs: use the positive number.  OR with mixed signs: use the
+	   negative number.  After the transformations above, op will be '&'
+	   iff one of these cases applies, and mask will be non-0 for operands
+	   whose length should be ignored.
+	*/
+
+	size_a = a->ob_size;
+	size_b = b->ob_size;
+	size_z = op == '&'
+		? (maska
+		   ? size_b
+		   : (maskb ? size_a : MIN(size_a, size_b)))
+		: MAX(size_a, size_b);
+	z = _PyLong_New(size_z);
+	if (z == NULL) {
+		Py_DECREF(a);
+		Py_DECREF(b);
+		return NULL;
+	}
+
+	for (i = 0; i < size_z; ++i) {
+		diga = (i < size_a ? a->ob_digit[i] : 0) ^ maska;
+		digb = (i < size_b ? b->ob_digit[i] : 0) ^ maskb;
+		switch (op) {
+		case '&': z->ob_digit[i] = diga & digb; break;
+		case '|': z->ob_digit[i] = diga | digb; break;
+		case '^': z->ob_digit[i] = diga ^ digb; break;
+		}
+	}
+
+	Py_DECREF(a);
+	Py_DECREF(b);
+	z = long_normalize(z);
+	if (negz == 0)
+		return (PyObject *) z;
+	v = long_invert(z);
+	Py_DECREF(z);
+	return v;
+}
+
+static PyObject *
+long_and(PyObject *v, PyObject *w)
+{
+	PyLongObject *a, *b;
+	PyObject *c;
+	CONVERT_BINOP(v, w, &a, &b);
+	c = long_bitwise(a, '&', b);
+	Py_DECREF(a);
+	Py_DECREF(b);
+	return c;
+}
+
+static PyObject *
+long_xor(PyObject *v, PyObject *w)
+{
+	PyLongObject *a, *b;
+	PyObject *c;
+	CONVERT_BINOP(v, w, &a, &b);
+	c = long_bitwise(a, '^', b);
+	Py_DECREF(a);
+	Py_DECREF(b);
+	return c;
+}
+
+static PyObject *
+long_or(PyObject *v, PyObject *w)
+{
+	PyLongObject *a, *b;
+	PyObject *c;
+	CONVERT_BINOP(v, w, &a, &b);
+	c = long_bitwise(a, '|', b);
+	Py_DECREF(a);
+	Py_DECREF(b);
+	return c;
+}
+
+static int
+long_coerce(PyObject **pv, PyObject **pw)
+{
+	if (PyInt_Check(*pw)) {
+		*pw = PyLong_FromLong(PyInt_AS_LONG(*pw));
+		Py_INCREF(*pv);
+		return 0;
+	}
+	else if (PyLong_Check(*pw)) {
+		Py_INCREF(*pv);
+		Py_INCREF(*pw);
+		return 0;
+	}
+	return 1; /* Can't do it */
+}
+
+static PyObject *
+long_long(PyObject *v)
+{
+	if (PyLong_CheckExact(v))
+		Py_INCREF(v);
+	else
+		v = _PyLong_Copy((PyLongObject *)v);
+	return v;
+}
+
+static PyObject *
+long_int(PyObject *v)
+{
+	long x;
+	x = PyLong_AsLong(v);
+	if (PyErr_Occurred()) {
+		if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
+				PyErr_Clear();
+				if (PyLong_CheckExact(v)) {
+					Py_INCREF(v);
+					return v;
+				}
+				else
+					return _PyLong_Copy((PyLongObject *)v);
+		}
+		else
+			return NULL;
+	}
+	return PyInt_FromLong(x);
+}
+
+static PyObject *
+long_float(PyObject *v)
+{
+	double result;
+	result = PyLong_AsDouble(v);
+	if (result == -1.0 && PyErr_Occurred())
+		return NULL;
+	return PyFloat_FromDouble(result);
+}
+
+static PyObject *
+long_oct(PyObject *v)
+{
+	return long_format(v, 8, 1);
+}
+
+static PyObject *
+long_hex(PyObject *v)
+{
+	return long_format(v, 16, 1);
+}
+
+static PyObject *
+long_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
+
+static PyObject *
+long_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	PyObject *x = NULL;
+	int base = -909;		     /* unlikely! */
+	static char *kwlist[] = {"x", "base", 0};
+
+	if (type != &PyLong_Type)
+		return long_subtype_new(type, args, kwds); /* Wimp out */
+	if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:long", kwlist,
+					 &x, &base))
+		return NULL;
+	if (x == NULL)
+		return PyLong_FromLong(0L);
+	if (base == -909)
+		return PyNumber_Long(x);
+	else if (PyString_Check(x)) {
+		/* Since PyLong_FromString doesn't have a length parameter,
+		 * check here for possible NULs in the string. */
+		char *string = PyString_AS_STRING(x);
+		if (strlen(string) != PyString_Size(x)) {
+			/* create a repr() of the input string,
+			 * just like PyLong_FromString does. */
+			PyObject *srepr;
+			srepr = PyObject_Repr(x);
+			if (srepr == NULL)
+				return NULL;
+			PyErr_Format(PyExc_ValueError,
+			     "invalid literal for long() with base %d: %s",
+			     base, PyString_AS_STRING(srepr));
+			Py_DECREF(srepr);
+			return NULL;
+		}
+		return PyLong_FromString(PyString_AS_STRING(x), NULL, base);
+	}
+#ifdef Py_USING_UNICODE
+	else if (PyUnicode_Check(x))
+		return PyLong_FromUnicode(PyUnicode_AS_UNICODE(x),
+					  PyUnicode_GET_SIZE(x),
+					  base);
+#endif
+	else {
+		PyErr_SetString(PyExc_TypeError,
+			"long() can't convert non-string with explicit base");
+		return NULL;
+	}
+}
+
+/* Wimpy, slow approach to tp_new calls for subtypes of long:
+   first create a regular long from whatever arguments we got,
+   then allocate a subtype instance and initialize it from
+   the regular long.  The regular long is then thrown away.
+*/
+static PyObject *
+long_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	PyLongObject *tmp, *newobj;
+	Py_ssize_t i, n;
+
+	assert(PyType_IsSubtype(type, &PyLong_Type));
+	tmp = (PyLongObject *)long_new(&PyLong_Type, args, kwds);
+	if (tmp == NULL)
+		return NULL;
+	assert(PyLong_CheckExact(tmp));
+	n = tmp->ob_size;
+	if (n < 0)
+		n = -n;
+	newobj = (PyLongObject *)type->tp_alloc(type, n);
+	if (newobj == NULL) {
+		Py_DECREF(tmp);
+		return NULL;
+	}
+	assert(PyLong_Check(newobj));
+	newobj->ob_size = tmp->ob_size;
+	for (i = 0; i < n; i++)
+		newobj->ob_digit[i] = tmp->ob_digit[i];
+	Py_DECREF(tmp);
+	return (PyObject *)newobj;
+}
+
+static PyObject *
+long_getnewargs(PyLongObject *v)
+{
+	return Py_BuildValue("(N)", _PyLong_Copy(v));
+}
+
+static PyMethodDef long_methods[] = {
+	{"__getnewargs__",	(PyCFunction)long_getnewargs,	METH_NOARGS},
+	{NULL,		NULL}		/* sentinel */
+};
+
+PyDoc_STRVAR(long_doc,
+"long(x[, base]) -> integer\n\
+\n\
+Convert a string or number to a long integer, if possible.  A floating\n\
+point argument will be truncated towards zero (this does not include a\n\
+string representation of a floating point number!)  When converting a\n\
+string, use the optional base.  It is an error to supply a base when\n\
+converting a non-string.");
+
+static PyNumberMethods long_as_number = {
+	(binaryfunc)	long_add,	/*nb_add*/
+	(binaryfunc)	long_sub,	/*nb_subtract*/
+	(binaryfunc)	long_mul,	/*nb_multiply*/
+			long_classic_div, /*nb_divide*/
+			long_mod,	/*nb_remainder*/
+			long_divmod,	/*nb_divmod*/
+			long_pow,	/*nb_power*/
+	(unaryfunc) 	long_neg,	/*nb_negative*/
+	(unaryfunc) 	long_pos,	/*tp_positive*/
+	(unaryfunc) 	long_abs,	/*tp_absolute*/
+	(inquiry)	long_nonzero,	/*tp_nonzero*/
+	(unaryfunc)	long_invert,	/*nb_invert*/
+			long_lshift,	/*nb_lshift*/
+	(binaryfunc)	long_rshift,	/*nb_rshift*/
+			long_and,	/*nb_and*/
+			long_xor,	/*nb_xor*/
+			long_or,	/*nb_or*/
+			long_coerce,	/*nb_coerce*/
+			long_int,	/*nb_int*/
+			long_long,	/*nb_long*/
+			long_float,	/*nb_float*/
+			long_oct,	/*nb_oct*/
+			long_hex,	/*nb_hex*/
+	0,				/* nb_inplace_add */
+	0,				/* nb_inplace_subtract */
+	0,				/* nb_inplace_multiply */
+	0,				/* nb_inplace_divide */
+	0,				/* nb_inplace_remainder */
+	0,				/* nb_inplace_power */
+	0,				/* nb_inplace_lshift */
+	0,				/* nb_inplace_rshift */
+	0,				/* nb_inplace_and */
+	0,				/* nb_inplace_xor */
+	0,				/* nb_inplace_or */
+	long_div,			/* nb_floor_divide */
+	long_true_divide,		/* nb_true_divide */
+	0,				/* nb_inplace_floor_divide */
+	0,				/* nb_inplace_true_divide */
+	long_long,			/* nb_index */
+};
+
+PyTypeObject PyLong_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,					/* ob_size */
+	"long",					/* tp_name */
+	sizeof(PyLongObject) - sizeof(digit),	/* tp_basicsize */
+	sizeof(digit),				/* tp_itemsize */
+	long_dealloc,				/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	(cmpfunc)long_compare,			/* tp_compare */
+	long_repr,				/* tp_repr */
+	&long_as_number,			/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	(hashfunc)long_hash,			/* tp_hash */
+        0,              			/* tp_call */
+        long_str,				/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
+		Py_TPFLAGS_BASETYPE,		/* tp_flags */
+	long_doc,				/* tp_doc */
+	0,					/* tp_traverse */
+	0,					/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	long_methods,				/* tp_methods */
+	0,					/* tp_members */
+	0,					/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	0,					/* tp_init */
+	0,					/* tp_alloc */
+	long_new,				/* tp_new */
+	PyObject_Del,                           /* tp_free */
+};

Added: vendor/Python/current/Objects/methodobject.c
===================================================================
--- vendor/Python/current/Objects/methodobject.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Objects/methodobject.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,365 @@
+
+/* Method object implementation */
+
+#include "Python.h"
+#include "structmember.h"
+
+static PyCFunctionObject *free_list = NULL;
+
+PyObject *
+PyCFunction_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module)
+{
+	PyCFunctionObject *op;
+	op = free_list;
+	if (op != NULL) {
+		free_list = (PyCFunctionObject *)(op->m_self);
+		PyObject_INIT(op, &PyCFunction_Type);
+	}
+	else {
+		op = PyObject_GC_New(PyCFunctionObject, &PyCFunction_Type);
+		if (op == NULL)
+			return NULL;
+	}
+	op->m_ml = ml;
+	Py_XINCREF(self);
+	op->m_self = self;
+	Py_XINCREF(module);
+	op->m_module = module;
+	_PyObject_GC_TRACK(op);
+	return (PyObject *)op;
+}
+
+PyCFunction
+PyCFunction_GetFunction(PyObject *op)
+{
+	if (!PyCFunction_Check(op)) {
+		PyErr_BadInternalCall();
+		return NULL;
+	}
+	return ((PyCFunctionObject *)op) -> m_ml -> ml_meth;
+}
+
+PyObject *
+PyCFunction_GetSelf(PyObject *op)
+{
+	if (!PyCFunction_Check(op)) {
+		PyErr_BadInternalCall();
+		return NULL;
+	}
+	return ((PyCFunctionObject *)op) -> m_self;
+}
+
+int
+PyCFunction_GetFlags(PyObject *op)
+{
+	if (!PyCFunction_Check(op)) {
+		PyErr_BadInternalCall();
+		return -1;
+	}
+	return ((PyCFunctionObject *)op) -> m_ml -> ml_flags;
+}
+
+PyObject *
+PyCFunction_Call(PyObject *func, PyObject *arg, PyObject *kw)
+{
+	PyCFunctionObject* f = (PyCFunctionObject*)func;
+	PyCFunction meth = PyCFunction_GET_FUNCTION(func);
+	PyObject *self = PyCFunction_GET_SELF(func);
+	Py_ssize_t size;
+
+	switch (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST)) {
+	case METH_VARARGS:
+		if (kw == NULL || PyDict_Size(kw) == 0)
+			return (*meth)(self, arg);
+		break;
+	case METH_VARARGS | METH_KEYWORDS:
+	case METH_OLDARGS | METH_KEYWORDS:
+		return (*(PyCFunctionWithKeywords)meth)(self, arg, kw);
+	case METH_NOARGS:
+		if (kw == NULL || PyDict_Size(kw) == 0) {
+			size = PyTuple_GET_SIZE(arg);
+			if (size == 0)
+				return (*meth)(self, NULL);
+			PyErr_Format(PyExc_TypeError,
+			    "%.200s() takes no arguments (%zd given)",
+			    f->m_ml->ml_name, size);
+			return NULL;
+		}
+		break;
+	case METH_O:
+		if (kw == NULL || PyDict_Size(kw) == 0) {
+			size = PyTuple_GET_SIZE(arg);
+			if (size == 1)
+				return (*meth)(self, PyTuple_GET_ITEM(arg, 0));
+			PyErr_Format(PyExc_TypeError,
+			    "%.200s() takes exactly one argument (%zd given)",
+			    f->m_ml->ml_name, size);
+			return NULL;
+		}
+		break;
+	case METH_OLDARGS:
+		/* the really old style */
+		if (kw == NULL || PyDict_Size(kw) == 0) {
+			size = PyTuple_GET_SIZE(arg);
+			if (size == 1)
+				arg = PyTuple_GET_ITEM(arg, 0);
+			else if (size == 0)
+				arg = NULL;
+			return (*meth)(self, arg);
+		}
+		break;
+	default:
+		PyErr_BadInternalCall();
+		return NULL;
+	}
+	PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments",
+		     f->m_ml->ml_name);
+	return NULL;
+}
+
+/* Methods (the standard built-in methods, that is) */
+
+static void
+meth_dealloc(PyCFunctionObject *m)
+{
+	_PyObject_GC_UNTRACK(m);
+	Py_XDECREF(m->m_self);
+	Py_XDECREF(m->m_module);
+	m->m_self = (PyObject *)free_list;
+	free_list = m;
+}
+
+static PyObject *
+meth_get__doc__(PyCFunctionObject *m, void *closure)
+{
+	const char *doc = m->m_ml->ml_doc;
+
+	if (doc != NULL)
+		return PyString_FromString(doc);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+meth_get__name__(PyCFunctionObject *m, void *closure)
+{
+	return PyString_FromString(m->m_ml->ml_name);
+}
+
+static int
+meth_traverse(PyCFunctionObject *m, visitproc visit, void *arg)
+{
+	Py_VISIT(m->m_self);
+	Py_VISIT(m->m_module);
+	return 0;
+}
+
+static PyObject *
+meth_get__self__(PyCFunctionObject *m, void *closure)
+{
+	PyObject *self;
+	if (PyEval_GetRestricted()) {
+		PyErr_SetString(PyExc_RuntimeError,
+			"method.__self__ not accessible in restricted mode");
+		return NULL;
+	}
+	self = m->m_self;
+	if (self == NULL)
+		self = Py_None;
+	Py_INCREF(self);
+	return self;
+}
+
+static PyGetSetDef meth_getsets [] = {
+	{"__doc__",  (getter)meth_get__doc__,  NULL, NULL},
+	{"__name__", (getter)meth_get__name__, NULL, NULL},
+	{"__self__", (getter)meth_get__self__, NULL, NULL},
+	{0}
+};
+
+#define OFF(x) offsetof(PyCFunctionObject, x)
+
+static PyMemberDef meth_members[] = {
+	{"__module__",    T_OBJECT,     OFF(m_module), WRITE_RESTRICTED},
+	{NULL}
+};
+
+static PyObject *
+meth_repr(PyCFunctionObject *m)
+{
+	if (m->m_self == NULL)
+		return PyString_FromFormat("<built-in function %s>",
+					   m->m_ml->ml_name);
+	return PyString_FromFormat("<built-in method %s of %s object at %p>",
+				   m->m_ml->ml_name,
+				   m->m_self->ob_type->tp_name,
+				   m->m_self);
+}
+
+static int
+meth_compare(PyCFunctionObject *a, PyCFunctionObject *b)
+{
+	if (a->m_self != b->m_self)
+		return (a->m_self < b->m_self) ? -1 : 1;
+	if (a->m_ml->ml_meth == b->m_ml->ml_meth)
+		return 0;
+	if (strcmp(a->m_ml->ml_name, b->m_ml->ml_name) < 0)
+		return -1;
+	else
+		return 1;
+}
+
+static long
+meth_hash(PyCFunctionObject *a)
+{
+	long x,y;
+	if (a->m_self == NULL)
+		x = 0;
+	else {
+		x = PyObject_Hash(a->m_self);
+		if (x == -1)
+			return -1;
+	}
+	y = _Py_HashPointer((void*)(a->m_ml->ml_meth));
+	if (y == -1)
+		return -1;
+	x ^= y;
+	if (x == -1)
+		x = -2;
+	return x;
+}
+
+
+PyTypeObject PyCFunction_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,
+	"builtin_function_or_method",
+	sizeof(PyCFunctionObject),
+	0,
+	(destructor)meth_dealloc, 		/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	(cmpfunc)meth_compare,			/* tp_compare */
+	(reprfunc)meth_repr,			/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	(hashfunc)meth_hash,			/* tp_hash */
+	PyCFunction_Call,			/* tp_call */
+	0,					/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+ 	0,					/* tp_doc */
+ 	(traverseproc)meth_traverse,		/* tp_traverse */
+	0,					/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	0,					/* tp_methods */
+	meth_members,				/* tp_members */
+	meth_getsets,				/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+};
+
+/* List all methods in a chain -- helper for findmethodinchain */
+
+static PyObject *
+listmethodchain(PyMethodChain *chain)
+{
+	PyMethodChain *c;
+	PyMethodDef *ml;
+	int i, n;
+	PyObject *v;
+
+	n = 0;
+	for (c = chain; c != NULL; c = c->link) {
+		for (ml = c->methods; ml->ml_name != NULL; ml++)
+			n++;
+	}
+	v = PyList_New(n);
+	if (v == NULL)
+		return NULL;
+	i = 0;
+	for (c = chain; c != NULL; c = c->link) {
+		for (ml = c->methods; ml->ml_name != NULL; ml++) {
+			PyList_SetItem(v, i, PyString_FromString(ml->ml_name));
+			i++;
+		}
+	}
+	if (PyErr_Occurred()) {
+		Py_DECREF(v);
+		return NULL;
+	}
+	PyList_Sort(v);
+	return v;
+}
+
+/* Find a method in a method chain */
+
+PyObject *
+Py_FindMethodInChain(PyMethodChain *chain, PyObject *self, const char *name)
+{
+	if (name[0] == '_' && name[1] == '_') {
+		if (strcmp(name, "__methods__") == 0)
+			return listmethodchain(chain);
+		if (strcmp(name, "__doc__") == 0) {
+			const char *doc = self->ob_type->tp_doc;
+			if (doc != NULL)
+				return PyString_FromString(doc);
+		}
+	}
+	while (chain != NULL) {
+		PyMethodDef *ml = chain->methods;
+		for (; ml->ml_name != NULL; ml++) {
+			if (name[0] == ml->ml_name[0] &&
+			    strcmp(name+1, ml->ml_name+1) == 0)
+				/* XXX */
+				return PyCFunction_New(ml, self);
+		}
+		chain = chain->link;
+	}
+	PyErr_SetString(PyExc_AttributeError, name);
+	return NULL;
+}
+
+/* Find a method in a single method list */
+
+PyObject *
+Py_FindMethod(PyMethodDef *methods, PyObject *self, const char *name)
+{
+	PyMethodChain chain;
+	chain.methods = methods;
+	chain.link = NULL;
+	return Py_FindMethodInChain(&chain, self, name);
+}
+
+/* Clear out the free list */
+
+void
+PyCFunction_Fini(void)
+{
+	while (free_list) {
+		PyCFunctionObject *v = free_list;
+		free_list = (PyCFunctionObject *)(v->m_self);
+		PyObject_GC_Del(v);
+	}
+}
+
+/* PyCFunction_New() is now just a macro that calls PyCFunction_NewEx(),
+   but it's part of the API so we need to keep a function around that
+   existing C extensions can call.
+*/
+   
+#undef PyCFunction_New
+PyAPI_FUNC(PyObject *) PyCFunction_New(PyMethodDef *, PyObject *);
+
+PyObject *
+PyCFunction_New(PyMethodDef *ml, PyObject *self)
+{
+	return PyCFunction_NewEx(ml, self, NULL);
+}

Added: vendor/Python/current/Objects/moduleobject.c
===================================================================
--- vendor/Python/current/Objects/moduleobject.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Objects/moduleobject.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,259 @@
+
+/* Module object implementation */
+
+#include "Python.h"
+#include "structmember.h"
+
+typedef struct {
+	PyObject_HEAD
+	PyObject *md_dict;
+} PyModuleObject;
+
+static PyMemberDef module_members[] = {
+	{"__dict__", T_OBJECT, offsetof(PyModuleObject, md_dict), READONLY},
+	{0}
+};
+
+PyObject *
+PyModule_New(const char *name)
+{
+	PyModuleObject *m;
+	PyObject *nameobj;
+	m = PyObject_GC_New(PyModuleObject, &PyModule_Type);
+	if (m == NULL)
+		return NULL;
+	nameobj = PyString_FromString(name);
+	m->md_dict = PyDict_New();
+	if (m->md_dict == NULL || nameobj == NULL)
+		goto fail;
+	if (PyDict_SetItemString(m->md_dict, "__name__", nameobj) != 0)
+		goto fail;
+	if (PyDict_SetItemString(m->md_dict, "__doc__", Py_None) != 0)
+		goto fail;
+	Py_DECREF(nameobj);
+	PyObject_GC_Track(m);
+	return (PyObject *)m;
+
+ fail:
+	Py_XDECREF(nameobj);
+	Py_DECREF(m);
+	return NULL;
+}
+
+PyObject *
+PyModule_GetDict(PyObject *m)
+{
+	PyObject *d;
+	if (!PyModule_Check(m)) {
+		PyErr_BadInternalCall();
+		return NULL;
+	}
+	d = ((PyModuleObject *)m) -> md_dict;
+	if (d == NULL)
+		((PyModuleObject *)m) -> md_dict = d = PyDict_New();
+	return d;
+}
+
+char *
+PyModule_GetName(PyObject *m)
+{
+	PyObject *d;
+	PyObject *nameobj;
+	if (!PyModule_Check(m)) {
+		PyErr_BadArgument();
+		return NULL;
+	}
+	d = ((PyModuleObject *)m)->md_dict;
+	if (d == NULL ||
+	    (nameobj = PyDict_GetItemString(d, "__name__")) == NULL ||
+	    !PyString_Check(nameobj))
+	{
+		PyErr_SetString(PyExc_SystemError, "nameless module");
+		return NULL;
+	}
+	return PyString_AsString(nameobj);
+}
+
+char *
+PyModule_GetFilename(PyObject *m)
+{
+	PyObject *d;
+	PyObject *fileobj;
+	if (!PyModule_Check(m)) {
+		PyErr_BadArgument();
+		return NULL;
+	}
+	d = ((PyModuleObject *)m)->md_dict;
+	if (d == NULL ||
+	    (fileobj = PyDict_GetItemString(d, "__file__")) == NULL ||
+	    !PyString_Check(fileobj))
+	{
+		PyErr_SetString(PyExc_SystemError, "module filename missing");
+		return NULL;
+	}
+	return PyString_AsString(fileobj);
+}
+
+void
+_PyModule_Clear(PyObject *m)
+{
+	/* To make the execution order of destructors for global
+	   objects a bit more predictable, we first zap all objects
+	   whose name starts with a single underscore, before we clear
+	   the entire dictionary.  We zap them by replacing them with
+	   None, rather than deleting them from the dictionary, to
+	   avoid rehashing the dictionary (to some extent). */
+
+	Py_ssize_t pos;
+	PyObject *key, *value;
+	PyObject *d;
+
+	d = ((PyModuleObject *)m)->md_dict;
+	if (d == NULL)
+		return;
+
+	/* First, clear only names starting with a single underscore */
+	pos = 0;
+	while (PyDict_Next(d, &pos, &key, &value)) {
+		if (value != Py_None && PyString_Check(key)) {
+			char *s = PyString_AsString(key);
+			if (s[0] == '_' && s[1] != '_') {
+				if (Py_VerboseFlag > 1)
+				    PySys_WriteStderr("#   clear[1] %s\n", s);
+				PyDict_SetItem(d, key, Py_None);
+			}
+		}
+	}
+
+	/* Next, clear all names except for __builtins__ */
+	pos = 0;
+	while (PyDict_Next(d, &pos, &key, &value)) {
+		if (value != Py_None && PyString_Check(key)) {
+			char *s = PyString_AsString(key);
+			if (s[0] != '_' || strcmp(s, "__builtins__") != 0) {
+				if (Py_VerboseFlag > 1)
+				    PySys_WriteStderr("#   clear[2] %s\n", s);
+				PyDict_SetItem(d, key, Py_None);
+			}
+		}
+	}
+
+	/* Note: we leave __builtins__ in place, so that destructors
+	   of non-global objects defined in this module can still use
+	   builtins, in particularly 'None'. */
+
+}
+
+/* Methods */
+
+static int
+module_init(PyModuleObject *m, PyObject *args, PyObject *kwds)
+{
+	static char *kwlist[] = {"name", "doc", NULL};
+	PyObject *dict, *name = Py_None, *doc = Py_None;
+	if (!PyArg_ParseTupleAndKeywords(args, kwds, "S|O:module.__init__",
+                                         kwlist, &name, &doc))
+		return -1;
+	dict = m->md_dict;
+	if (dict == NULL) {
+		dict = PyDict_New();
+		if (dict == NULL)
+			return -1;
+		m->md_dict = dict;
+	}
+	if (PyDict_SetItemString(dict, "__name__", name) < 0)
+		return -1;
+	if (PyDict_SetItemString(dict, "__doc__", doc) < 0)
+		return -1;
+	return 0;
+}
+
+static void
+module_dealloc(PyModuleObject *m)
+{
+	PyObject_GC_UnTrack(m);
+	if (m->md_dict != NULL) {
+		_PyModule_Clear((PyObject *)m);
+		Py_DECREF(m->md_dict);
+	}
+	m->ob_type->tp_free((PyObject *)m);
+}
+
+static PyObject *
+module_repr(PyModuleObject *m)
+{
+	char *name;
+	char *filename;
+
+	name = PyModule_GetName((PyObject *)m);
+	if (name == NULL) {
+		PyErr_Clear();
+		name = "?";
+	}
+	filename = PyModule_GetFilename((PyObject *)m);
+	if (filename == NULL) {
+		PyErr_Clear();
+		return PyString_FromFormat("<module '%s' (built-in)>", name);
+	}
+	return PyString_FromFormat("<module '%s' from '%s'>", name, filename);
+}
+
+/* We only need a traverse function, no clear function: If the module
+   is in a cycle, md_dict will be cleared as well, which will break
+   the cycle. */
+static int
+module_traverse(PyModuleObject *m, visitproc visit, void *arg)
+{
+	Py_VISIT(m->md_dict);
+	return 0;
+}
+
+PyDoc_STRVAR(module_doc,
+"module(name[, doc])\n\
+\n\
+Create a module object.\n\
+The name must be a string; the optional doc argument can have any type.");
+
+PyTypeObject PyModule_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,					/* ob_size */
+	"module",				/* tp_name */
+	sizeof(PyModuleObject),			/* tp_size */
+	0,					/* tp_itemsize */
+	(destructor)module_dealloc,		/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	(reprfunc)module_repr,			/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	PyObject_GenericSetAttr,		/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+		Py_TPFLAGS_BASETYPE,		/* tp_flags */
+	module_doc,				/* tp_doc */
+	(traverseproc)module_traverse,		/* tp_traverse */
+	0,					/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	0,					/* tp_methods */
+	module_members,				/* tp_members */
+	0,					/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+	offsetof(PyModuleObject, md_dict),	/* tp_dictoffset */
+	(initproc)module_init,			/* tp_init */
+	PyType_GenericAlloc,			/* tp_alloc */
+	PyType_GenericNew,			/* tp_new */
+	PyObject_GC_Del,		        /* tp_free */
+};

Added: vendor/Python/current/Objects/object.c
===================================================================
--- vendor/Python/current/Objects/object.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Objects/object.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2139 @@
+
+/* Generic object operations; and implementation of None (NoObject) */
+
+#include "Python.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef Py_REF_DEBUG
+Py_ssize_t _Py_RefTotal;
+
+Py_ssize_t
+_Py_GetRefTotal(void)
+{
+	PyObject *o;
+	Py_ssize_t total = _Py_RefTotal;
+        /* ignore the references to the dummy object of the dicts and sets
+           because they are not reliable and not useful (now that the
+           hash table code is well-tested) */
+	o = _PyDict_Dummy();
+	if (o != NULL)
+		total -= o->ob_refcnt;
+	o = _PySet_Dummy();
+	if (o != NULL)
+		total -= o->ob_refcnt;
+	return total;
+}
+#endif /* Py_REF_DEBUG */
+
+int Py_DivisionWarningFlag;
+
+/* Object allocation routines used by NEWOBJ and NEWVAROBJ macros.
+   These are used by the individual routines for object creation.
+   Do not call them otherwise, they do not initialize the object! */
+
+#ifdef Py_TRACE_REFS
+/* Head of circular doubly-linked list of all objects.  These are linked
+ * together via the _ob_prev and _ob_next members of a PyObject, which
+ * exist only in a Py_TRACE_REFS build.
+ */
+static PyObject refchain = {&refchain, &refchain};
+
+/* Insert op at the front of the list of all objects.  If force is true,
+ * op is added even if _ob_prev and _ob_next are non-NULL already.  If
+ * force is false amd _ob_prev or _ob_next are non-NULL, do nothing.
+ * force should be true if and only if op points to freshly allocated,
+ * uninitialized memory, or you've unlinked op from the list and are
+ * relinking it into the front.
+ * Note that objects are normally added to the list via _Py_NewReference,
+ * which is called by PyObject_Init.  Not all objects are initialized that
+ * way, though; exceptions include statically allocated type objects, and
+ * statically allocated singletons (like Py_True and Py_None).
+ */
+void
+_Py_AddToAllObjects(PyObject *op, int force)
+{
+#ifdef  Py_DEBUG
+	if (!force) {
+		/* If it's initialized memory, op must be in or out of
+		 * the list unambiguously.
+		 */
+		assert((op->_ob_prev == NULL) == (op->_ob_next == NULL));
+	}
+#endif
+	if (force || op->_ob_prev == NULL) {
+		op->_ob_next = refchain._ob_next;
+		op->_ob_prev = &refchain;
+		refchain._ob_next->_ob_prev = op;
+		refchain._ob_next = op;
+	}
+}
+#endif	/* Py_TRACE_REFS */
+
+#ifdef COUNT_ALLOCS
+static PyTypeObject *type_list;
+/* All types are added to type_list, at least when
+   they get one object created. That makes them
+   immortal, which unfortunately contributes to
+   garbage itself. If unlist_types_without_objects
+   is set, they will be removed from the type_list
+   once the last object is deallocated. */
+int unlist_types_without_objects;
+extern int tuple_zero_allocs, fast_tuple_allocs;
+extern int quick_int_allocs, quick_neg_int_allocs;
+extern int null_strings, one_strings;
+void
+dump_counts(FILE* f)
+{
+	PyTypeObject *tp;
+
+	for (tp = type_list; tp; tp = tp->tp_next)
+		fprintf(f, "%s alloc'd: %d, freed: %d, max in use: %d\n",
+			tp->tp_name, tp->tp_allocs, tp->tp_frees,
+			tp->tp_maxalloc);
+	fprintf(f, "fast tuple allocs: %d, empty: %d\n",
+		fast_tuple_allocs, tuple_zero_allocs);
+	fprintf(f, "fast int allocs: pos: %d, neg: %d\n",
+		quick_int_allocs, quick_neg_int_allocs);
+	fprintf(f, "null strings: %d, 1-strings: %d\n",
+		null_strings, one_strings);
+}
+
+PyObject *
+get_counts(void)
+{
+	PyTypeObject *tp;
+	PyObject *result;
+	PyObject *v;
+
+	result = PyList_New(0);
+	if (result == NULL)
+		return NULL;
+	for (tp = type_list; tp; tp = tp->tp_next) {
+		v = Py_BuildValue("(snnn)", tp->tp_name, tp->tp_allocs,
+				  tp->tp_frees, tp->tp_maxalloc);
+		if (v == NULL) {
+			Py_DECREF(result);
+			return NULL;
+		}
+		if (PyList_Append(result, v) < 0) {
+			Py_DECREF(v);
+			Py_DECREF(result);
+			return NULL;
+		}
+		Py_DECREF(v);
+	}
+	return result;
+}
+
+void
+inc_count(PyTypeObject *tp)
+{
+	if (tp->tp_next == NULL && tp->tp_prev == NULL) {
+		/* first time; insert in linked list */
+		if (tp->tp_next != NULL) /* sanity check */
+			Py_FatalError("XXX inc_count sanity check");
+		if (type_list)
+			type_list->tp_prev = tp;
+		tp->tp_next = type_list;
+		/* Note that as of Python 2.2, heap-allocated type objects
+		 * can go away, but this code requires that they stay alive
+		 * until program exit.  That's why we're careful with
+		 * refcounts here.  type_list gets a new reference to tp,
+		 * while ownership of the reference type_list used to hold
+		 * (if any) was transferred to tp->tp_next in the line above.
+		 * tp is thus effectively immortal after this.
+		 */
+		Py_INCREF(tp);
+		type_list = tp;
+#ifdef Py_TRACE_REFS
+		/* Also insert in the doubly-linked list of all objects,
+		 * if not already there.
+		 */
+		_Py_AddToAllObjects((PyObject *)tp, 0);
+#endif
+	}
+	tp->tp_allocs++;
+	if (tp->tp_allocs - tp->tp_frees > tp->tp_maxalloc)
+		tp->tp_maxalloc = tp->tp_allocs - tp->tp_frees;
+}
+
+void dec_count(PyTypeObject *tp)
+{
+	tp->tp_frees++;
+	if (unlist_types_without_objects &&
+	    tp->tp_allocs == tp->tp_frees) {
+		/* unlink the type from type_list */
+		if (tp->tp_prev)
+			tp->tp_prev->tp_next = tp->tp_next;
+		else
+			type_list = tp->tp_next;
+		if (tp->tp_next)
+			tp->tp_next->tp_prev = tp->tp_prev;
+		tp->tp_next = tp->tp_prev = NULL;
+		Py_DECREF(tp);
+	}
+}
+
+#endif
+
+#ifdef Py_REF_DEBUG
+/* Log a fatal error; doesn't return. */
+void
+_Py_NegativeRefcount(const char *fname, int lineno, PyObject *op)
+{
+	char buf[300];
+
+	PyOS_snprintf(buf, sizeof(buf),
+		      "%s:%i object at %p has negative ref count "
+		      "%" PY_FORMAT_SIZE_T "d",
+		      fname, lineno, op, op->ob_refcnt);
+	Py_FatalError(buf);
+}
+
+#endif /* Py_REF_DEBUG */
+
+void
+Py_IncRef(PyObject *o)
+{
+    Py_XINCREF(o);
+}
+
+void
+Py_DecRef(PyObject *o)
+{
+    Py_XDECREF(o);
+}
+
+PyObject *
+PyObject_Init(PyObject *op, PyTypeObject *tp)
+{
+	if (op == NULL)
+		return PyErr_NoMemory();
+	/* Any changes should be reflected in PyObject_INIT (objimpl.h) */
+	op->ob_type = tp;
+	_Py_NewReference(op);
+	return op;
+}
+
+PyVarObject *
+PyObject_InitVar(PyVarObject *op, PyTypeObject *tp, Py_ssize_t size)
+{
+	if (op == NULL)
+		return (PyVarObject *) PyErr_NoMemory();
+	/* Any changes should be reflected in PyObject_INIT_VAR */
+	op->ob_size = size;
+	op->ob_type = tp;
+	_Py_NewReference((PyObject *)op);
+	return op;
+}
+
+PyObject *
+_PyObject_New(PyTypeObject *tp)
+{
+	PyObject *op;
+	op = (PyObject *) PyObject_MALLOC(_PyObject_SIZE(tp));
+	if (op == NULL)
+		return PyErr_NoMemory();
+	return PyObject_INIT(op, tp);
+}
+
+PyVarObject *
+_PyObject_NewVar(PyTypeObject *tp, Py_ssize_t nitems)
+{
+	PyVarObject *op;
+	const size_t size = _PyObject_VAR_SIZE(tp, nitems);
+	op = (PyVarObject *) PyObject_MALLOC(size);
+	if (op == NULL)
+		return (PyVarObject *)PyErr_NoMemory();
+	return PyObject_INIT_VAR(op, tp, nitems);
+}
+
+/* for binary compatibility with 2.2 */
+#undef _PyObject_Del
+void
+_PyObject_Del(PyObject *op)
+{
+	PyObject_FREE(op);
+}
+
+/* Implementation of PyObject_Print with recursion checking */
+static int
+internal_print(PyObject *op, FILE *fp, int flags, int nesting)
+{
+	int ret = 0;
+	if (nesting > 10) {
+		PyErr_SetString(PyExc_RuntimeError, "print recursion");
+		return -1;
+	}
+	if (PyErr_CheckSignals())
+		return -1;
+#ifdef USE_STACKCHECK
+	if (PyOS_CheckStack()) {
+		PyErr_SetString(PyExc_MemoryError, "stack overflow");
+		return -1;
+	}
+#endif
+	clearerr(fp); /* Clear any previous error condition */
+	if (op == NULL) {
+		fprintf(fp, "<nil>");
+	}
+	else {
+		if (op->ob_refcnt <= 0)
+			/* XXX(twouters) cast refcount to long until %zd is
+			   universally available */
+			fprintf(fp, "<refcnt %ld at %p>",
+				(long)op->ob_refcnt, op);
+		else if (op->ob_type->tp_print == NULL) {
+			PyObject *s;
+			if (flags & Py_PRINT_RAW)
+				s = PyObject_Str(op);
+			else
+				s = PyObject_Repr(op);
+			if (s == NULL)
+				ret = -1;
+			else {
+				ret = internal_print(s, fp, Py_PRINT_RAW,
+						     nesting+1);
+			}
+			Py_XDECREF(s);
+		}
+		else
+			ret = (*op->ob_type->tp_print)(op, fp, flags);
+	}
+	if (ret == 0) {
+		if (ferror(fp)) {
+			PyErr_SetFromErrno(PyExc_IOError);
+			clearerr(fp);
+			ret = -1;
+		}
+	}
+	return ret;
+}
+
+int
+PyObject_Print(PyObject *op, FILE *fp, int flags)
+{
+	return internal_print(op, fp, flags, 0);
+}
+
+
+/* For debugging convenience.  See Misc/gdbinit for some useful gdb hooks */
+void _PyObject_Dump(PyObject* op)
+{
+	if (op == NULL)
+		fprintf(stderr, "NULL\n");
+	else {
+		fprintf(stderr, "object  : ");
+		(void)PyObject_Print(op, stderr, 0);
+		/* XXX(twouters) cast refcount to long until %zd is
+		   universally available */
+		fprintf(stderr, "\n"
+			"type    : %s\n"
+			"refcount: %ld\n"
+			"address : %p\n",
+			op->ob_type==NULL ? "NULL" : op->ob_type->tp_name,
+			(long)op->ob_refcnt,
+			op);
+	}
+}
+
+PyObject *
+PyObject_Repr(PyObject *v)
+{
+	if (PyErr_CheckSignals())
+		return NULL;
+#ifdef USE_STACKCHECK
+	if (PyOS_CheckStack()) {
+		PyErr_SetString(PyExc_MemoryError, "stack overflow");
+		return NULL;
+	}
+#endif
+	if (v == NULL)
+		return PyString_FromString("<NULL>");
+	else if (v->ob_type->tp_repr == NULL)
+		return PyString_FromFormat("<%s object at %p>",
+					   v->ob_type->tp_name, v);
+	else {
+		PyObject *res;
+		res = (*v->ob_type->tp_repr)(v);
+		if (res == NULL)
+			return NULL;
+#ifdef Py_USING_UNICODE
+		if (PyUnicode_Check(res)) {
+			PyObject* str;
+			str = PyUnicode_AsEncodedString(res, NULL, NULL);
+			Py_DECREF(res);
+			if (str)
+				res = str;
+			else
+				return NULL;
+		}
+#endif
+		if (!PyString_Check(res)) {
+			PyErr_Format(PyExc_TypeError,
+				     "__repr__ returned non-string (type %.200s)",
+				     res->ob_type->tp_name);
+			Py_DECREF(res);
+			return NULL;
+		}
+		return res;
+	}
+}
+
+PyObject *
+_PyObject_Str(PyObject *v)
+{
+	PyObject *res;
+	int type_ok;
+	if (v == NULL)
+		return PyString_FromString("<NULL>");
+	if (PyString_CheckExact(v)) {
+		Py_INCREF(v);
+		return v;
+	}
+#ifdef Py_USING_UNICODE
+	if (PyUnicode_CheckExact(v)) {
+		Py_INCREF(v);
+		return v;
+	}
+#endif
+	if (v->ob_type->tp_str == NULL)
+		return PyObject_Repr(v);
+
+	res = (*v->ob_type->tp_str)(v);
+	if (res == NULL)
+		return NULL;
+	type_ok = PyString_Check(res);
+#ifdef Py_USING_UNICODE
+	type_ok = type_ok || PyUnicode_Check(res);
+#endif
+	if (!type_ok) {
+		PyErr_Format(PyExc_TypeError,
+			     "__str__ returned non-string (type %.200s)",
+			     res->ob_type->tp_name);
+		Py_DECREF(res);
+		return NULL;
+	}
+	return res;
+}
+
+PyObject *
+PyObject_Str(PyObject *v)
+{
+	PyObject *res = _PyObject_Str(v);
+	if (res == NULL)
+		return NULL;
+#ifdef Py_USING_UNICODE
+	if (PyUnicode_Check(res)) {
+		PyObject* str;
+		str = PyUnicode_AsEncodedString(res, NULL, NULL);
+		Py_DECREF(res);
+		if (str)
+			res = str;
+		else
+		    	return NULL;
+	}
+#endif
+	assert(PyString_Check(res));
+	return res;
+}
+
+#ifdef Py_USING_UNICODE
+PyObject *
+PyObject_Unicode(PyObject *v)
+{
+	PyObject *res;
+	PyObject *func;
+	PyObject *str;
+	static PyObject *unicodestr;
+
+	if (v == NULL) {
+		res = PyString_FromString("<NULL>");
+		if (res == NULL)
+			return NULL;
+		str = PyUnicode_FromEncodedObject(res, NULL, "strict");
+		Py_DECREF(res);
+		return str;
+	} else if (PyUnicode_CheckExact(v)) {
+		Py_INCREF(v);
+		return v;
+	}
+	/* XXX As soon as we have a tp_unicode slot, we should
+	   check this before trying the __unicode__
+	   method. */
+	if (unicodestr == NULL) {
+		unicodestr= PyString_InternFromString("__unicode__");
+		if (unicodestr == NULL)
+			return NULL;
+	}
+	func = PyObject_GetAttr(v, unicodestr);
+	if (func != NULL) {
+		res = PyEval_CallObject(func, (PyObject *)NULL);
+		Py_DECREF(func);
+	}
+	else {
+		PyErr_Clear();
+		if (PyUnicode_Check(v)) {
+			/* For a Unicode subtype that's didn't overwrite __unicode__,
+			   return a true Unicode object with the same data. */
+			return PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(v),
+			                             PyUnicode_GET_SIZE(v));
+		}
+		if (PyString_CheckExact(v)) {
+			Py_INCREF(v);
+			res = v;
+		}
+		else {
+			if (v->ob_type->tp_str != NULL)
+				res = (*v->ob_type->tp_str)(v);
+			else
+				res = PyObject_Repr(v);
+		}
+	}
+	if (res == NULL)
+		return NULL;
+	if (!PyUnicode_Check(res)) {
+		str = PyUnicode_FromEncodedObject(res, NULL, "strict");
+		Py_DECREF(res);
+		res = str;
+	}
+	return res;
+}
+#endif
+
+
+/* Helper to warn about deprecated tp_compare return values.  Return:
+   -2 for an exception;
+   -1 if v <  w;
+    0 if v == w;
+    1 if v  > w.
+   (This function cannot return 2.)
+*/
+static int
+adjust_tp_compare(int c)
+{
+	if (PyErr_Occurred()) {
+		if (c != -1 && c != -2) {
+			PyObject *t, *v, *tb;
+			PyErr_Fetch(&t, &v, &tb);
+			if (PyErr_Warn(PyExc_RuntimeWarning,
+				       "tp_compare didn't return -1 or -2 "
+				       "for exception") < 0) {
+				Py_XDECREF(t);
+				Py_XDECREF(v);
+				Py_XDECREF(tb);
+			}
+			else
+				PyErr_Restore(t, v, tb);
+		}
+		return -2;
+	}
+	else if (c < -1 || c > 1) {
+		if (PyErr_Warn(PyExc_RuntimeWarning,
+			       "tp_compare didn't return -1, 0 or 1") < 0)
+			return -2;
+		else
+			return c < -1 ? -1 : 1;
+	}
+	else {
+		assert(c >= -1 && c <= 1);
+		return c;
+	}
+}
+
+
+/* Macro to get the tp_richcompare field of a type if defined */
+#define RICHCOMPARE(t) (PyType_HasFeature((t), Py_TPFLAGS_HAVE_RICHCOMPARE) \
+                         ? (t)->tp_richcompare : NULL)
+
+/* Map rich comparison operators to their swapped version, e.g. LT --> GT */
+int _Py_SwappedOp[] = {Py_GT, Py_GE, Py_EQ, Py_NE, Py_LT, Py_LE};
+
+/* Try a genuine rich comparison, returning an object.  Return:
+   NULL for exception;
+   NotImplemented if this particular rich comparison is not implemented or
+     undefined;
+   some object not equal to NotImplemented if it is implemented
+     (this latter object may not be a Boolean).
+*/
+static PyObject *
+try_rich_compare(PyObject *v, PyObject *w, int op)
+{
+	richcmpfunc f;
+	PyObject *res;
+
+	if (v->ob_type != w->ob_type &&
+	    PyType_IsSubtype(w->ob_type, v->ob_type) &&
+	    (f = RICHCOMPARE(w->ob_type)) != NULL) {
+		res = (*f)(w, v, _Py_SwappedOp[op]);
+		if (res != Py_NotImplemented)
+			return res;
+		Py_DECREF(res);
+	}
+	if ((f = RICHCOMPARE(v->ob_type)) != NULL) {
+		res = (*f)(v, w, op);
+		if (res != Py_NotImplemented)
+			return res;
+		Py_DECREF(res);
+	}
+	if ((f = RICHCOMPARE(w->ob_type)) != NULL) {
+		return (*f)(w, v, _Py_SwappedOp[op]);
+	}
+	res = Py_NotImplemented;
+	Py_INCREF(res);
+	return res;
+}
+
+/* Try a genuine rich comparison, returning an int.  Return:
+   -1 for exception (including the case where try_rich_compare() returns an
+      object that's not a Boolean);
+    0 if the outcome is false;
+    1 if the outcome is true;
+    2 if this particular rich comparison is not implemented or undefined.
+*/
+static int
+try_rich_compare_bool(PyObject *v, PyObject *w, int op)
+{
+	PyObject *res;
+	int ok;
+
+	if (RICHCOMPARE(v->ob_type) == NULL && RICHCOMPARE(w->ob_type) == NULL)
+		return 2; /* Shortcut, avoid INCREF+DECREF */
+	res = try_rich_compare(v, w, op);
+	if (res == NULL)
+		return -1;
+	if (res == Py_NotImplemented) {
+		Py_DECREF(res);
+		return 2;
+	}
+	ok = PyObject_IsTrue(res);
+	Py_DECREF(res);
+	return ok;
+}
+
+/* Try rich comparisons to determine a 3-way comparison.  Return:
+   -2 for an exception;
+   -1 if v  < w;
+    0 if v == w;
+    1 if v  > w;
+    2 if this particular rich comparison is not implemented or undefined.
+*/
+static int
+try_rich_to_3way_compare(PyObject *v, PyObject *w)
+{
+	static struct { int op; int outcome; } tries[3] = {
+		/* Try this operator, and if it is true, use this outcome: */
+		{Py_EQ, 0},
+		{Py_LT, -1},
+		{Py_GT, 1},
+	};
+	int i;
+
+	if (RICHCOMPARE(v->ob_type) == NULL && RICHCOMPARE(w->ob_type) == NULL)
+		return 2; /* Shortcut */
+
+	for (i = 0; i < 3; i++) {
+		switch (try_rich_compare_bool(v, w, tries[i].op)) {
+		case -1:
+			return -2;
+		case 1:
+			return tries[i].outcome;
+		}
+	}
+
+	return 2;
+}
+
+/* Try a 3-way comparison, returning an int.  Return:
+   -2 for an exception;
+   -1 if v <  w;
+    0 if v == w;
+    1 if v  > w;
+    2 if this particular 3-way comparison is not implemented or undefined.
+*/
+static int
+try_3way_compare(PyObject *v, PyObject *w)
+{
+	int c;
+	cmpfunc f;
+
+	/* Comparisons involving instances are given to instance_compare,
+	   which has the same return conventions as this function. */
+
+	f = v->ob_type->tp_compare;
+	if (PyInstance_Check(v))
+		return (*f)(v, w);
+	if (PyInstance_Check(w))
+		return (*w->ob_type->tp_compare)(v, w);
+
+	/* If both have the same (non-NULL) tp_compare, use it. */
+	if (f != NULL && f == w->ob_type->tp_compare) {
+		c = (*f)(v, w);
+		return adjust_tp_compare(c);
+	}
+
+	/* If either tp_compare is _PyObject_SlotCompare, that's safe. */
+	if (f == _PyObject_SlotCompare ||
+	    w->ob_type->tp_compare == _PyObject_SlotCompare)
+		return _PyObject_SlotCompare(v, w);
+
+	/* If we're here, v and w,
+	    a) are not instances;
+	    b) have different types or a type without tp_compare; and
+	    c) don't have a user-defined tp_compare.
+	   tp_compare implementations in C assume that both arguments
+	   have their type, so we give up if the coercion fails or if
+	   it yields types which are still incompatible (which can
+	   happen with a user-defined nb_coerce).
+	*/
+	c = PyNumber_CoerceEx(&v, &w);
+	if (c < 0)
+		return -2;
+	if (c > 0)
+		return 2;
+	f = v->ob_type->tp_compare;
+	if (f != NULL && f == w->ob_type->tp_compare) {
+		c = (*f)(v, w);
+		Py_DECREF(v);
+		Py_DECREF(w);
+		return adjust_tp_compare(c);
+	}
+
+	/* No comparison defined */
+	Py_DECREF(v);
+	Py_DECREF(w);
+	return 2;
+}
+
+/* Final fallback 3-way comparison, returning an int.  Return:
+   -2 if an error occurred;
+   -1 if v <  w;
+    0 if v == w;
+    1 if v >  w.
+*/
+static int
+default_3way_compare(PyObject *v, PyObject *w)
+{
+	int c;
+	const char *vname, *wname;
+
+	if (v->ob_type == w->ob_type) {
+		/* When comparing these pointers, they must be cast to
+		 * integer types (i.e. Py_uintptr_t, our spelling of C9X's
+		 * uintptr_t).  ANSI specifies that pointer compares other
+		 * than == and != to non-related structures are undefined.
+		 */
+		Py_uintptr_t vv = (Py_uintptr_t)v;
+		Py_uintptr_t ww = (Py_uintptr_t)w;
+		return (vv < ww) ? -1 : (vv > ww) ? 1 : 0;
+	}
+
+	/* None is smaller than anything */
+	if (v == Py_None)
+		return -1;
+	if (w == Py_None)
+		return 1;
+
+	/* different type: compare type names; numbers are smaller */
+	if (PyNumber_Check(v))
+		vname = "";
+	else
+		vname = v->ob_type->tp_name;
+	if (PyNumber_Check(w))
+		wname = "";
+	else
+		wname = w->ob_type->tp_name;
+	c = strcmp(vname, wname);
+	if (c < 0)
+		return -1;
+	if (c > 0)
+		return 1;
+	/* Same type name, or (more likely) incomparable numeric types */
+	return ((Py_uintptr_t)(v->ob_type) < (
+		Py_uintptr_t)(w->ob_type)) ? -1 : 1;
+}
+
+/* Do a 3-way comparison, by hook or by crook.  Return:
+   -2 for an exception (but see below);
+   -1 if v <  w;
+    0 if v == w;
+    1 if v >  w;
+   BUT: if the object implements a tp_compare function, it returns
+   whatever this function returns (whether with an exception or not).
+*/
+static int
+do_cmp(PyObject *v, PyObject *w)
+{
+	int c;
+	cmpfunc f;
+
+	if (v->ob_type == w->ob_type
+	    && (f = v->ob_type->tp_compare) != NULL) {
+		c = (*f)(v, w);
+		if (PyInstance_Check(v)) {
+			/* Instance tp_compare has a different signature.
+			   But if it returns undefined we fall through. */
+			if (c != 2)
+				return c;
+			/* Else fall through to try_rich_to_3way_compare() */
+		}
+		else
+			return adjust_tp_compare(c);
+	}
+	/* We only get here if one of the following is true:
+	   a) v and w have different types
+	   b) v and w have the same type, which doesn't have tp_compare
+	   c) v and w are instances, and either __cmp__ is not defined or
+	      __cmp__ returns NotImplemented
+	*/
+	c = try_rich_to_3way_compare(v, w);
+	if (c < 2)
+		return c;
+	c = try_3way_compare(v, w);
+	if (c < 2)
+		return c;
+	return default_3way_compare(v, w);
+}
+
+/* Compare v to w.  Return
+   -1 if v <  w or exception (PyErr_Occurred() true in latter case).
+    0 if v == w.
+    1 if v > w.
+   XXX The docs (C API manual) say the return value is undefined in case
+   XXX of error.
+*/
+int
+PyObject_Compare(PyObject *v, PyObject *w)
+{
+	int result;
+
+	if (v == NULL || w == NULL) {
+		PyErr_BadInternalCall();
+		return -1;
+	}
+	if (v == w)
+		return 0;
+	if (Py_EnterRecursiveCall(" in cmp"))
+		return -1;
+	result = do_cmp(v, w);
+	Py_LeaveRecursiveCall();
+	return result < 0 ? -1 : result;
+}
+
+/* Return (new reference to) Py_True or Py_False. */
+static PyObject *
+convert_3way_to_object(int op, int c)
+{
+	PyObject *result;
+	switch (op) {
+	case Py_LT: c = c <  0; break;
+	case Py_LE: c = c <= 0; break;
+	case Py_EQ: c = c == 0; break;
+	case Py_NE: c = c != 0; break;
+	case Py_GT: c = c >  0; break;
+	case Py_GE: c = c >= 0; break;
+	}
+	result = c ? Py_True : Py_False;
+	Py_INCREF(result);
+	return result;
+}
+
+/* We want a rich comparison but don't have one.  Try a 3-way cmp instead.
+   Return
+   NULL      if error
+   Py_True   if v op w
+   Py_False  if not (v op w)
+*/
+static PyObject *
+try_3way_to_rich_compare(PyObject *v, PyObject *w, int op)
+{
+	int c;
+
+	c = try_3way_compare(v, w);
+	if (c >= 2)
+		c = default_3way_compare(v, w);
+	if (c <= -2)
+		return NULL;
+	return convert_3way_to_object(op, c);
+}
+
+/* Do rich comparison on v and w.  Return
+   NULL      if error
+   Else a new reference to an object other than Py_NotImplemented, usually(?):
+   Py_True   if v op w
+   Py_False  if not (v op w)
+*/
+static PyObject *
+do_richcmp(PyObject *v, PyObject *w, int op)
+{
+	PyObject *res;
+
+	res = try_rich_compare(v, w, op);
+	if (res != Py_NotImplemented)
+		return res;
+	Py_DECREF(res);
+
+	return try_3way_to_rich_compare(v, w, op);
+}
+
+/* Return:
+   NULL for exception;
+   some object not equal to NotImplemented if it is implemented
+     (this latter object may not be a Boolean).
+*/
+PyObject *
+PyObject_RichCompare(PyObject *v, PyObject *w, int op)
+{
+	PyObject *res;
+
+	assert(Py_LT <= op && op <= Py_GE);
+	if (Py_EnterRecursiveCall(" in cmp"))
+		return NULL;
+
+	/* If the types are equal, and not old-style instances, try to
+	   get out cheap (don't bother with coercions etc.). */
+	if (v->ob_type == w->ob_type && !PyInstance_Check(v)) {
+		cmpfunc fcmp;
+		richcmpfunc frich = RICHCOMPARE(v->ob_type);
+		/* If the type has richcmp, try it first.  try_rich_compare
+		   tries it two-sided, which is not needed since we've a
+		   single type only. */
+		if (frich != NULL) {
+			res = (*frich)(v, w, op);
+			if (res != Py_NotImplemented)
+				goto Done;
+			Py_DECREF(res);
+		}
+		/* No richcmp, or this particular richmp not implemented.
+		   Try 3-way cmp. */
+		fcmp = v->ob_type->tp_compare;
+		if (fcmp != NULL) {
+			int c = (*fcmp)(v, w);
+			c = adjust_tp_compare(c);
+			if (c == -2) {
+				res = NULL;
+				goto Done;
+			}
+			res = convert_3way_to_object(op, c);
+			goto Done;
+		}
+	}
+
+	/* Fast path not taken, or couldn't deliver a useful result. */
+	res = do_richcmp(v, w, op);
+Done:
+	Py_LeaveRecursiveCall();
+	return res;
+}
+
+/* Return -1 if error; 1 if v op w; 0 if not (v op w). */
+int
+PyObject_RichCompareBool(PyObject *v, PyObject *w, int op)
+{
+	PyObject *res;
+	int ok;
+
+	/* Quick result when objects are the same.
+	   Guarantees that identity implies equality. */
+	if (v == w) {
+		if (op == Py_EQ)
+			return 1;
+		else if (op == Py_NE)
+			return 0;
+	}
+
+	res = PyObject_RichCompare(v, w, op);
+	if (res == NULL)
+		return -1;
+	if (PyBool_Check(res))
+		ok = (res == Py_True);
+	else
+		ok = PyObject_IsTrue(res);
+	Py_DECREF(res);
+	return ok;
+}
+
+/* Set of hash utility functions to help maintaining the invariant that
+	if a==b then hash(a)==hash(b)
+
+   All the utility functions (_Py_Hash*()) return "-1" to signify an error.
+*/
+
+long
+_Py_HashDouble(double v)
+{
+	double intpart, fractpart;
+	int expo;
+	long hipart;
+	long x;		/* the final hash value */
+	/* This is designed so that Python numbers of different types
+	 * that compare equal hash to the same value; otherwise comparisons
+	 * of mapping keys will turn out weird.
+	 */
+
+	fractpart = modf(v, &intpart);
+	if (fractpart == 0.0) {
+		/* This must return the same hash as an equal int or long. */
+		if (intpart > LONG_MAX || -intpart > LONG_MAX) {
+			/* Convert to long and use its hash. */
+			PyObject *plong;	/* converted to Python long */
+			if (Py_IS_INFINITY(intpart))
+				/* can't convert to long int -- arbitrary */
+				v = v < 0 ? -271828.0 : 314159.0;
+			plong = PyLong_FromDouble(v);
+			if (plong == NULL)
+				return -1;
+			x = PyObject_Hash(plong);
+			Py_DECREF(plong);
+			return x;
+		}
+		/* Fits in a C long == a Python int, so is its own hash. */
+		x = (long)intpart;
+		if (x == -1)
+			x = -2;
+		return x;
+	}
+	/* The fractional part is non-zero, so we don't have to worry about
+	 * making this match the hash of some other type.
+	 * Use frexp to get at the bits in the double.
+	 * Since the VAX D double format has 56 mantissa bits, which is the
+	 * most of any double format in use, each of these parts may have as
+	 * many as (but no more than) 56 significant bits.
+	 * So, assuming sizeof(long) >= 4, each part can be broken into two
+	 * longs; frexp and multiplication are used to do that.
+	 * Also, since the Cray double format has 15 exponent bits, which is
+	 * the most of any double format in use, shifting the exponent field
+	 * left by 15 won't overflow a long (again assuming sizeof(long) >= 4).
+	 */
+	v = frexp(v, &expo);
+	v *= 2147483648.0;	/* 2**31 */
+	hipart = (long)v;	/* take the top 32 bits */
+	v = (v - (double)hipart) * 2147483648.0; /* get the next 32 bits */
+	x = hipart + (long)v + (expo << 15);
+	if (x == -1)
+		x = -2;
+	return x;
+}
+
+long
+_Py_HashPointer(void *p)
+{
+#if SIZEOF_LONG >= SIZEOF_VOID_P
+	return (long)p;
+#else
+	/* convert to a Python long and hash that */
+	PyObject* longobj;
+	long x;
+
+	if ((longobj = PyLong_FromVoidPtr(p)) == NULL) {
+		x = -1;
+		goto finally;
+	}
+	x = PyObject_Hash(longobj);
+
+finally:
+	Py_XDECREF(longobj);
+	return x;
+#endif
+}
+
+
+long
+PyObject_Hash(PyObject *v)
+{
+	PyTypeObject *tp = v->ob_type;
+	if (tp->tp_hash != NULL)
+		return (*tp->tp_hash)(v);
+	if (tp->tp_compare == NULL && RICHCOMPARE(tp) == NULL) {
+		return _Py_HashPointer(v); /* Use address as hash value */
+	}
+	/* If there's a cmp but no hash defined, the object can't be hashed */
+	PyErr_Format(PyExc_TypeError, "unhashable type: '%.200s'",
+		     v->ob_type->tp_name);
+	return -1;
+}
+
+PyObject *
+PyObject_GetAttrString(PyObject *v, const char *name)
+{
+	PyObject *w, *res;
+
+	if (v->ob_type->tp_getattr != NULL)
+		return (*v->ob_type->tp_getattr)(v, (char*)name);
+	w = PyString_InternFromString(name);
+	if (w == NULL)
+		return NULL;
+	res = PyObject_GetAttr(v, w);
+	Py_XDECREF(w);
+	return res;
+}
+
+int
+PyObject_HasAttrString(PyObject *v, const char *name)
+{
+	PyObject *res = PyObject_GetAttrString(v, name);
+	if (res != NULL) {
+		Py_DECREF(res);
+		return 1;
+	}
+	PyErr_Clear();
+	return 0;
+}
+
+int
+PyObject_SetAttrString(PyObject *v, const char *name, PyObject *w)
+{
+	PyObject *s;
+	int res;
+
+	if (v->ob_type->tp_setattr != NULL)
+		return (*v->ob_type->tp_setattr)(v, (char*)name, w);
+	s = PyString_InternFromString(name);
+	if (s == NULL)
+		return -1;
+	res = PyObject_SetAttr(v, s, w);
+	Py_XDECREF(s);
+	return res;
+}
+
+PyObject *
+PyObject_GetAttr(PyObject *v, PyObject *name)
+{
+	PyTypeObject *tp = v->ob_type;
+
+	if (!PyString_Check(name)) {
+#ifdef Py_USING_UNICODE
+		/* The Unicode to string conversion is done here because the
+		   existing tp_getattro slots expect a string object as name
+		   and we wouldn't want to break those. */
+		if (PyUnicode_Check(name)) {
+			name = _PyUnicode_AsDefaultEncodedString(name, NULL);
+			if (name == NULL)
+				return NULL;
+		}
+		else
+#endif
+		{
+			PyErr_Format(PyExc_TypeError,
+				     "attribute name must be string, not '%.200s'",
+				     name->ob_type->tp_name);
+			return NULL;
+		}
+	}
+	if (tp->tp_getattro != NULL)
+		return (*tp->tp_getattro)(v, name);
+	if (tp->tp_getattr != NULL)
+		return (*tp->tp_getattr)(v, PyString_AS_STRING(name));
+	PyErr_Format(PyExc_AttributeError,
+		     "'%.50s' object has no attribute '%.400s'",
+		     tp->tp_name, PyString_AS_STRING(name));
+	return NULL;
+}
+
+int
+PyObject_HasAttr(PyObject *v, PyObject *name)
+{
+	PyObject *res = PyObject_GetAttr(v, name);
+	if (res != NULL) {
+		Py_DECREF(res);
+		return 1;
+	}
+	PyErr_Clear();
+	return 0;
+}
+
+int
+PyObject_SetAttr(PyObject *v, PyObject *name, PyObject *value)
+{
+	PyTypeObject *tp = v->ob_type;
+	int err;
+
+	if (!PyString_Check(name)){
+#ifdef Py_USING_UNICODE
+		/* The Unicode to string conversion is done here because the
+		   existing tp_setattro slots expect a string object as name
+		   and we wouldn't want to break those. */
+		if (PyUnicode_Check(name)) {
+			name = PyUnicode_AsEncodedString(name, NULL, NULL);
+			if (name == NULL)
+				return -1;
+		}
+		else
+#endif
+		{
+			PyErr_Format(PyExc_TypeError,
+				     "attribute name must be string, not '%.200s'",
+				     name->ob_type->tp_name);
+			return -1;
+		}
+	}
+	else
+		Py_INCREF(name);
+
+	PyString_InternInPlace(&name);
+	if (tp->tp_setattro != NULL) {
+		err = (*tp->tp_setattro)(v, name, value);
+		Py_DECREF(name);
+		return err;
+	}
+	if (tp->tp_setattr != NULL) {
+		err = (*tp->tp_setattr)(v, PyString_AS_STRING(name), value);
+		Py_DECREF(name);
+		return err;
+	}
+	Py_DECREF(name);
+	if (tp->tp_getattr == NULL && tp->tp_getattro == NULL)
+		PyErr_Format(PyExc_TypeError,
+			     "'%.100s' object has no attributes "
+			     "(%s .%.100s)",
+			     tp->tp_name,
+			     value==NULL ? "del" : "assign to",
+			     PyString_AS_STRING(name));
+	else
+		PyErr_Format(PyExc_TypeError,
+			     "'%.100s' object has only read-only attributes "
+			     "(%s .%.100s)",
+			     tp->tp_name,
+			     value==NULL ? "del" : "assign to",
+			     PyString_AS_STRING(name));
+	return -1;
+}
+
+/* Helper to get a pointer to an object's __dict__ slot, if any */
+
+PyObject **
+_PyObject_GetDictPtr(PyObject *obj)
+{
+	Py_ssize_t dictoffset;
+	PyTypeObject *tp = obj->ob_type;
+
+	if (!(tp->tp_flags & Py_TPFLAGS_HAVE_CLASS))
+		return NULL;
+	dictoffset = tp->tp_dictoffset;
+	if (dictoffset == 0)
+		return NULL;
+	if (dictoffset < 0) {
+		Py_ssize_t tsize;
+		size_t size;
+
+		tsize = ((PyVarObject *)obj)->ob_size;
+		if (tsize < 0)
+			tsize = -tsize;
+		size = _PyObject_VAR_SIZE(tp, tsize);
+
+		dictoffset += (long)size;
+		assert(dictoffset > 0);
+		assert(dictoffset % SIZEOF_VOID_P == 0);
+	}
+	return (PyObject **) ((char *)obj + dictoffset);
+}
+
+PyObject *
+PyObject_SelfIter(PyObject *obj)
+{
+	Py_INCREF(obj);
+	return obj;
+}
+
+/* Generic GetAttr functions - put these in your tp_[gs]etattro slot */
+
+PyObject *
+PyObject_GenericGetAttr(PyObject *obj, PyObject *name)
+{
+	PyTypeObject *tp = obj->ob_type;
+	PyObject *descr = NULL;
+	PyObject *res = NULL;
+	descrgetfunc f;
+	Py_ssize_t dictoffset;
+	PyObject **dictptr;
+
+	if (!PyString_Check(name)){
+#ifdef Py_USING_UNICODE
+		/* The Unicode to string conversion is done here because the
+		   existing tp_setattro slots expect a string object as name
+		   and we wouldn't want to break those. */
+		if (PyUnicode_Check(name)) {
+			name = PyUnicode_AsEncodedString(name, NULL, NULL);
+			if (name == NULL)
+				return NULL;
+		}
+		else
+#endif
+		{
+			PyErr_Format(PyExc_TypeError,
+				     "attribute name must be string, not '%.200s'",
+				     name->ob_type->tp_name);
+			return NULL;
+		}
+	}
+	else
+		Py_INCREF(name);
+
+	if (tp->tp_dict == NULL) {
+		if (PyType_Ready(tp) < 0)
+			goto done;
+	}
+
+	/* Inline _PyType_Lookup */
+	{
+		Py_ssize_t i, n;
+		PyObject *mro, *base, *dict;
+
+		/* Look in tp_dict of types in MRO */
+		mro = tp->tp_mro;
+		assert(mro != NULL);
+		assert(PyTuple_Check(mro));
+		n = PyTuple_GET_SIZE(mro);
+		for (i = 0; i < n; i++) {
+			base = PyTuple_GET_ITEM(mro, i);
+			if (PyClass_Check(base))
+				dict = ((PyClassObject *)base)->cl_dict;
+			else {
+				assert(PyType_Check(base));
+				dict = ((PyTypeObject *)base)->tp_dict;
+			}
+			assert(dict && PyDict_Check(dict));
+			descr = PyDict_GetItem(dict, name);
+			if (descr != NULL)
+				break;
+		}
+	}
+
+	Py_XINCREF(descr);
+
+	f = NULL;
+	if (descr != NULL &&
+	    PyType_HasFeature(descr->ob_type, Py_TPFLAGS_HAVE_CLASS)) {
+		f = descr->ob_type->tp_descr_get;
+		if (f != NULL && PyDescr_IsData(descr)) {
+			res = f(descr, obj, (PyObject *)obj->ob_type);
+			Py_DECREF(descr);
+			goto done;
+		}
+	}
+
+	/* Inline _PyObject_GetDictPtr */
+	dictoffset = tp->tp_dictoffset;
+	if (dictoffset != 0) {
+		PyObject *dict;
+		if (dictoffset < 0) {
+			Py_ssize_t tsize;
+			size_t size;
+
+			tsize = ((PyVarObject *)obj)->ob_size;
+			if (tsize < 0)
+				tsize = -tsize;
+			size = _PyObject_VAR_SIZE(tp, tsize);
+
+			dictoffset += (long)size;
+			assert(dictoffset > 0);
+			assert(dictoffset % SIZEOF_VOID_P == 0);
+		}
+		dictptr = (PyObject **) ((char *)obj + dictoffset);
+		dict = *dictptr;
+		if (dict != NULL) {
+			res = PyDict_GetItem(dict, name);
+			if (res != NULL) {
+				Py_INCREF(res);
+				Py_XDECREF(descr);
+				goto done;
+			}
+		}
+	}
+
+	if (f != NULL) {
+		res = f(descr, obj, (PyObject *)obj->ob_type);
+		Py_DECREF(descr);
+		goto done;
+	}
+
+	if (descr != NULL) {
+		res = descr;
+		/* descr was already increfed above */
+		goto done;
+	}
+
+	PyErr_Format(PyExc_AttributeError,
+		     "'%.50s' object has no attribute '%.400s'",
+		     tp->tp_name, PyString_AS_STRING(name));
+  done:
+	Py_DECREF(name);
+	return res;
+}
+
+int
+PyObject_GenericSetAttr(PyObject *obj, PyObject *name, PyObject *value)
+{
+	PyTypeObject *tp = obj->ob_type;
+	PyObject *descr;
+	descrsetfunc f;
+	PyObject **dictptr;
+	int res = -1;
+
+	if (!PyString_Check(name)){
+#ifdef Py_USING_UNICODE
+		/* The Unicode to string conversion is done here because the
+		   existing tp_setattro slots expect a string object as name
+		   and we wouldn't want to break those. */
+		if (PyUnicode_Check(name)) {
+			name = PyUnicode_AsEncodedString(name, NULL, NULL);
+			if (name == NULL)
+				return -1;
+		}
+		else
+#endif
+		{
+			PyErr_Format(PyExc_TypeError,
+				     "attribute name must be string, not '%.200s'",
+				     name->ob_type->tp_name);
+			return -1;
+		}
+	}
+	else
+		Py_INCREF(name);
+
+	if (tp->tp_dict == NULL) {
+		if (PyType_Ready(tp) < 0)
+			goto done;
+	}
+
+	descr = _PyType_Lookup(tp, name);
+	f = NULL;
+	if (descr != NULL &&
+	    PyType_HasFeature(descr->ob_type, Py_TPFLAGS_HAVE_CLASS)) {
+		f = descr->ob_type->tp_descr_set;
+		if (f != NULL && PyDescr_IsData(descr)) {
+			res = f(descr, obj, value);
+			goto done;
+		}
+	}
+
+	dictptr = _PyObject_GetDictPtr(obj);
+	if (dictptr != NULL) {
+		PyObject *dict = *dictptr;
+		if (dict == NULL && value != NULL) {
+			dict = PyDict_New();
+			if (dict == NULL)
+				goto done;
+			*dictptr = dict;
+		}
+		if (dict != NULL) {
+			if (value == NULL)
+				res = PyDict_DelItem(dict, name);
+			else
+				res = PyDict_SetItem(dict, name, value);
+			if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError))
+				PyErr_SetObject(PyExc_AttributeError, name);
+			goto done;
+		}
+	}
+
+	if (f != NULL) {
+		res = f(descr, obj, value);
+		goto done;
+	}
+
+	if (descr == NULL) {
+		PyErr_Format(PyExc_AttributeError,
+			     "'%.100s' object has no attribute '%.200s'",
+			     tp->tp_name, PyString_AS_STRING(name));
+		goto done;
+	}
+
+	PyErr_Format(PyExc_AttributeError,
+		     "'%.50s' object attribute '%.400s' is read-only",
+		     tp->tp_name, PyString_AS_STRING(name));
+  done:
+	Py_DECREF(name);
+	return res;
+}
+
+/* Test a value used as condition, e.g., in a for or if statement.
+   Return -1 if an error occurred */
+
+int
+PyObject_IsTrue(PyObject *v)
+{
+	Py_ssize_t res;
+	if (v == Py_True)
+		return 1;
+	if (v == Py_False)
+		return 0;
+	if (v == Py_None)
+		return 0;
+	else if (v->ob_type->tp_as_number != NULL &&
+		 v->ob_type->tp_as_number->nb_nonzero != NULL)
+		res = (*v->ob_type->tp_as_number->nb_nonzero)(v);
+	else if (v->ob_type->tp_as_mapping != NULL &&
+		 v->ob_type->tp_as_mapping->mp_length != NULL)
+		res = (*v->ob_type->tp_as_mapping->mp_length)(v);
+	else if (v->ob_type->tp_as_sequence != NULL &&
+		 v->ob_type->tp_as_sequence->sq_length != NULL)
+		res = (*v->ob_type->tp_as_sequence->sq_length)(v);
+	else
+		return 1;
+	/* if it is negative, it should be either -1 or -2 */
+	return (res > 0) ? 1 : Py_SAFE_DOWNCAST(res, Py_ssize_t, int);
+}
+
+/* equivalent of 'not v'
+   Return -1 if an error occurred */
+
+int
+PyObject_Not(PyObject *v)
+{
+	int res;
+	res = PyObject_IsTrue(v);
+	if (res < 0)
+		return res;
+	return res == 0;
+}
+
+/* Coerce two numeric types to the "larger" one.
+   Increment the reference count on each argument.
+   Return value:
+   -1 if an error occurred;
+   0 if the coercion succeeded (and then the reference counts are increased);
+   1 if no coercion is possible (and no error is raised).
+*/
+int
+PyNumber_CoerceEx(PyObject **pv, PyObject **pw)
+{
+	register PyObject *v = *pv;
+	register PyObject *w = *pw;
+	int res;
+
+	/* Shortcut only for old-style types */
+	if (v->ob_type == w->ob_type &&
+	    !PyType_HasFeature(v->ob_type, Py_TPFLAGS_CHECKTYPES))
+	{
+		Py_INCREF(v);
+		Py_INCREF(w);
+		return 0;
+	}
+	if (v->ob_type->tp_as_number && v->ob_type->tp_as_number->nb_coerce) {
+		res = (*v->ob_type->tp_as_number->nb_coerce)(pv, pw);
+		if (res <= 0)
+			return res;
+	}
+	if (w->ob_type->tp_as_number && w->ob_type->tp_as_number->nb_coerce) {
+		res = (*w->ob_type->tp_as_number->nb_coerce)(pw, pv);
+		if (res <= 0)
+			return res;
+	}
+	return 1;
+}
+
+/* Coerce two numeric types to the "larger" one.
+   Increment the reference count on each argument.
+   Return -1 and raise an exception if no coercion is possible
+   (and then no reference count is incremented).
+*/
+int
+PyNumber_Coerce(PyObject **pv, PyObject **pw)
+{
+	int err = PyNumber_CoerceEx(pv, pw);
+	if (err <= 0)
+		return err;
+	PyErr_SetString(PyExc_TypeError, "number coercion failed");
+	return -1;
+}
+
+
+/* Test whether an object can be called */
+
+int
+PyCallable_Check(PyObject *x)
+{
+	if (x == NULL)
+		return 0;
+	if (PyInstance_Check(x)) {
+		PyObject *call = PyObject_GetAttrString(x, "__call__");
+		if (call == NULL) {
+			PyErr_Clear();
+			return 0;
+		}
+		/* Could test recursively but don't, for fear of endless
+		   recursion if some joker sets self.__call__ = self */
+		Py_DECREF(call);
+		return 1;
+	}
+	else {
+		return x->ob_type->tp_call != NULL;
+	}
+}
+
+/* Helper for PyObject_Dir.
+   Merge the __dict__ of aclass into dict, and recursively also all
+   the __dict__s of aclass's base classes.  The order of merging isn't
+   defined, as it's expected that only the final set of dict keys is
+   interesting.
+   Return 0 on success, -1 on error.
+*/
+
+static int
+merge_class_dict(PyObject* dict, PyObject* aclass)
+{
+	PyObject *classdict;
+	PyObject *bases;
+
+	assert(PyDict_Check(dict));
+	assert(aclass);
+
+	/* Merge in the type's dict (if any). */
+	classdict = PyObject_GetAttrString(aclass, "__dict__");
+	if (classdict == NULL)
+		PyErr_Clear();
+	else {
+		int status = PyDict_Update(dict, classdict);
+		Py_DECREF(classdict);
+		if (status < 0)
+			return -1;
+	}
+
+	/* Recursively merge in the base types' (if any) dicts. */
+	bases = PyObject_GetAttrString(aclass, "__bases__");
+	if (bases == NULL)
+		PyErr_Clear();
+	else {
+		/* We have no guarantee that bases is a real tuple */
+		Py_ssize_t i, n;
+		n = PySequence_Size(bases); /* This better be right */
+		if (n < 0)
+			PyErr_Clear();
+		else {
+			for (i = 0; i < n; i++) {
+				int status;
+				PyObject *base = PySequence_GetItem(bases, i);
+				if (base == NULL) {
+					Py_DECREF(bases);
+					return -1;
+				}
+				status = merge_class_dict(dict, base);
+				Py_DECREF(base);
+				if (status < 0) {
+					Py_DECREF(bases);
+					return -1;
+				}
+			}
+		}
+		Py_DECREF(bases);
+	}
+	return 0;
+}
+
+/* Helper for PyObject_Dir.
+   If obj has an attr named attrname that's a list, merge its string
+   elements into keys of dict.
+   Return 0 on success, -1 on error.  Errors due to not finding the attr,
+   or the attr not being a list, are suppressed.
+*/
+
+static int
+merge_list_attr(PyObject* dict, PyObject* obj, const char *attrname)
+{
+	PyObject *list;
+	int result = 0;
+
+	assert(PyDict_Check(dict));
+	assert(obj);
+	assert(attrname);
+
+	list = PyObject_GetAttrString(obj, attrname);
+	if (list == NULL)
+		PyErr_Clear();
+
+	else if (PyList_Check(list)) {
+		int i;
+		for (i = 0; i < PyList_GET_SIZE(list); ++i) {
+			PyObject *item = PyList_GET_ITEM(list, i);
+			if (PyString_Check(item)) {
+				result = PyDict_SetItem(dict, item, Py_None);
+				if (result < 0)
+					break;
+			}
+		}
+	}
+
+	Py_XDECREF(list);
+	return result;
+}
+
+/* Like __builtin__.dir(arg).  See bltinmodule.c's builtin_dir for the
+   docstring, which should be kept in synch with this implementation. */
+
+PyObject *
+PyObject_Dir(PyObject *arg)
+{
+	/* Set exactly one of these non-NULL before the end. */
+	PyObject *result = NULL;	/* result list */
+	PyObject *masterdict = NULL;	/* result is masterdict.keys() */
+
+	/* If NULL arg, return the locals. */
+	if (arg == NULL) {
+		PyObject *locals = PyEval_GetLocals();
+		if (locals == NULL)
+			goto error;
+		result = PyMapping_Keys(locals);
+		if (result == NULL)
+			goto error;
+	}
+
+	/* Elif this is some form of module, we only want its dict. */
+	else if (PyModule_Check(arg)) {
+		masterdict = PyObject_GetAttrString(arg, "__dict__");
+		if (masterdict == NULL)
+			goto error;
+		if (!PyDict_Check(masterdict)) {
+			PyErr_SetString(PyExc_TypeError,
+					"module.__dict__ is not a dictionary");
+			goto error;
+		}
+	}
+
+	/* Elif some form of type or class, grab its dict and its bases.
+	   We deliberately don't suck up its __class__, as methods belonging
+	   to the metaclass would probably be more confusing than helpful. */
+	else if (PyType_Check(arg) || PyClass_Check(arg)) {
+		masterdict = PyDict_New();
+		if (masterdict == NULL)
+			goto error;
+		if (merge_class_dict(masterdict, arg) < 0)
+			goto error;
+	}
+
+	/* Else look at its dict, and the attrs reachable from its class. */
+	else {
+		PyObject *itsclass;
+		/* Create a dict to start with.  CAUTION:  Not everything
+		   responding to __dict__ returns a dict! */
+		masterdict = PyObject_GetAttrString(arg, "__dict__");
+		if (masterdict == NULL) {
+			PyErr_Clear();
+			masterdict = PyDict_New();
+		}
+		else if (!PyDict_Check(masterdict)) {
+			Py_DECREF(masterdict);
+			masterdict = PyDict_New();
+		}
+		else {
+			/* The object may have returned a reference to its
+			   dict, so copy it to avoid mutating it. */
+			PyObject *temp = PyDict_Copy(masterdict);
+			Py_DECREF(masterdict);
+			masterdict = temp;
+		}
+		if (masterdict == NULL)
+			goto error;
+
+		/* Merge in __members__ and __methods__ (if any).
+		   XXX Would like this to go away someday; for now, it's
+		   XXX needed to get at im_self etc of method objects. */
+		if (merge_list_attr(masterdict, arg, "__members__") < 0)
+			goto error;
+		if (merge_list_attr(masterdict, arg, "__methods__") < 0)
+			goto error;
+
+		/* Merge in attrs reachable from its class.
+		   CAUTION:  Not all objects have a __class__ attr. */
+		itsclass = PyObject_GetAttrString(arg, "__class__");
+		if (itsclass == NULL)
+			PyErr_Clear();
+		else {
+			int status = merge_class_dict(masterdict, itsclass);
+			Py_DECREF(itsclass);
+			if (status < 0)
+				goto error;
+		}
+	}
+
+	assert((result == NULL) ^ (masterdict == NULL));
+	if (masterdict != NULL) {
+		/* The result comes from its keys. */
+		assert(result == NULL);
+		result = PyDict_Keys(masterdict);
+		if (result == NULL)
+			goto error;
+	}
+
+	assert(result);
+	if (!PyList_Check(result)) {
+		PyErr_Format(PyExc_TypeError,
+			"Expected keys() to be a list, not '%.200s'",
+			result->ob_type->tp_name);
+		goto error;
+	}
+	if (PyList_Sort(result) != 0)
+		goto error;
+	else
+		goto normal_return;
+
+  error:
+	Py_XDECREF(result);
+	result = NULL;
+	/* fall through */
+  normal_return:
+  	Py_XDECREF(masterdict);
+	return result;
+}
+
+/*
+NoObject is usable as a non-NULL undefined value, used by the macro None.
+There is (and should be!) no way to create other objects of this type,
+so there is exactly one (which is indestructible, by the way).
+(XXX This type and the type of NotImplemented below should be unified.)
+*/
+
+/* ARGSUSED */
+static PyObject *
+none_repr(PyObject *op)
+{
+	return PyString_FromString("None");
+}
+
+/* ARGUSED */
+static void
+none_dealloc(PyObject* ignore)
+{
+	/* This should never get called, but we also don't want to SEGV if
+	 * we accidently decref None out of existance.
+	 */
+	Py_FatalError("deallocating None");
+}
+
+
+static PyTypeObject PyNone_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,
+	"NoneType",
+	0,
+	0,
+	none_dealloc,	/*tp_dealloc*/ /*never called*/
+	0,		/*tp_print*/
+	0,		/*tp_getattr*/
+	0,		/*tp_setattr*/
+	0,		/*tp_compare*/
+	none_repr,	/*tp_repr*/
+	0,		/*tp_as_number*/
+	0,		/*tp_as_sequence*/
+	0,		/*tp_as_mapping*/
+	0,		/*tp_hash */
+};
+
+PyObject _Py_NoneStruct = {
+	PyObject_HEAD_INIT(&PyNone_Type)
+};
+
+/* NotImplemented is an object that can be used to signal that an
+   operation is not implemented for the given type combination. */
+
+static PyObject *
+NotImplemented_repr(PyObject *op)
+{
+	return PyString_FromString("NotImplemented");
+}
+
+static PyTypeObject PyNotImplemented_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,
+	"NotImplementedType",
+	0,
+	0,
+	none_dealloc,	/*tp_dealloc*/ /*never called*/
+	0,		/*tp_print*/
+	0,		/*tp_getattr*/
+	0,		/*tp_setattr*/
+	0,		/*tp_compare*/
+	NotImplemented_repr, /*tp_repr*/
+	0,		/*tp_as_number*/
+	0,		/*tp_as_sequence*/
+	0,		/*tp_as_mapping*/
+	0,		/*tp_hash */
+};
+
+PyObject _Py_NotImplementedStruct = {
+	PyObject_HEAD_INIT(&PyNotImplemented_Type)
+};
+
+void
+_Py_ReadyTypes(void)
+{
+	if (PyType_Ready(&PyType_Type) < 0)
+		Py_FatalError("Can't initialize 'type'");
+
+	if (PyType_Ready(&_PyWeakref_RefType) < 0)
+		Py_FatalError("Can't initialize 'weakref'");
+
+	if (PyType_Ready(&PyBool_Type) < 0)
+		Py_FatalError("Can't initialize 'bool'");
+
+	if (PyType_Ready(&PyString_Type) < 0)
+		Py_FatalError("Can't initialize 'str'");
+
+	if (PyType_Ready(&PyList_Type) < 0)
+		Py_FatalError("Can't initialize 'list'");
+
+	if (PyType_Ready(&PyNone_Type) < 0)
+		Py_FatalError("Can't initialize type(None)");
+
+	if (PyType_Ready(&PyNotImplemented_Type) < 0)
+		Py_FatalError("Can't initialize type(NotImplemented)");
+}
+
+
+#ifdef Py_TRACE_REFS
+
+void
+_Py_NewReference(PyObject *op)
+{
+	_Py_INC_REFTOTAL;
+	op->ob_refcnt = 1;
+	_Py_AddToAllObjects(op, 1);
+	_Py_INC_TPALLOCS(op);
+}
+
+void
+_Py_ForgetReference(register PyObject *op)
+{
+#ifdef SLOW_UNREF_CHECK
+        register PyObject *p;
+#endif
+	if (op->ob_refcnt < 0)
+		Py_FatalError("UNREF negative refcnt");
+	if (op == &refchain ||
+	    op->_ob_prev->_ob_next != op || op->_ob_next->_ob_prev != op)
+		Py_FatalError("UNREF invalid object");
+#ifdef SLOW_UNREF_CHECK
+	for (p = refchain._ob_next; p != &refchain; p = p->_ob_next) {
+		if (p == op)
+			break;
+	}
+	if (p == &refchain) /* Not found */
+		Py_FatalError("UNREF unknown object");
+#endif
+	op->_ob_next->_ob_prev = op->_ob_prev;
+	op->_ob_prev->_ob_next = op->_ob_next;
+	op->_ob_next = op->_ob_prev = NULL;
+	_Py_INC_TPFREES(op);
+}
+
+void
+_Py_Dealloc(PyObject *op)
+{
+	destructor dealloc = op->ob_type->tp_dealloc;
+	_Py_ForgetReference(op);
+	(*dealloc)(op);
+}
+
+/* Print all live objects.  Because PyObject_Print is called, the
+ * interpreter must be in a healthy state.
+ */
+void
+_Py_PrintReferences(FILE *fp)
+{
+	PyObject *op;
+	fprintf(fp, "Remaining objects:\n");
+	for (op = refchain._ob_next; op != &refchain; op = op->_ob_next) {
+		fprintf(fp, "%p [%" PY_FORMAT_SIZE_T "d] ", op, op->ob_refcnt);
+		if (PyObject_Print(op, fp, 0) != 0)
+			PyErr_Clear();
+		putc('\n', fp);
+	}
+}
+
+/* Print the addresses of all live objects.  Unlike _Py_PrintReferences, this
+ * doesn't make any calls to the Python C API, so is always safe to call.
+ */
+void
+_Py_PrintReferenceAddresses(FILE *fp)
+{
+	PyObject *op;
+	fprintf(fp, "Remaining object addresses:\n");
+	for (op = refchain._ob_next; op != &refchain; op = op->_ob_next)
+		fprintf(fp, "%p [%" PY_FORMAT_SIZE_T "d] %s\n", op,
+			op->ob_refcnt, op->ob_type->tp_name);
+}
+
+PyObject *
+_Py_GetObjects(PyObject *self, PyObject *args)
+{
+	int i, n;
+	PyObject *t = NULL;
+	PyObject *res, *op;
+
+	if (!PyArg_ParseTuple(args, "i|O", &n, &t))
+		return NULL;
+	op = refchain._ob_next;
+	res = PyList_New(0);
+	if (res == NULL)
+		return NULL;
+	for (i = 0; (n == 0 || i < n) && op != &refchain; i++) {
+		while (op == self || op == args || op == res || op == t ||
+		       (t != NULL && op->ob_type != (PyTypeObject *) t)) {
+			op = op->_ob_next;
+			if (op == &refchain)
+				return res;
+		}
+		if (PyList_Append(res, op) < 0) {
+			Py_DECREF(res);
+			return NULL;
+		}
+		op = op->_ob_next;
+	}
+	return res;
+}
+
+#endif
+
+
+/* Hack to force loading of cobject.o */
+PyTypeObject *_Py_cobject_hack = &PyCObject_Type;
+
+
+/* Hack to force loading of abstract.o */
+Py_ssize_t (*_Py_abstract_hack)(PyObject *) = PyObject_Size;
+
+
+/* Python's malloc wrappers (see pymem.h) */
+
+void *
+PyMem_Malloc(size_t nbytes)
+{
+	return PyMem_MALLOC(nbytes);
+}
+
+void *
+PyMem_Realloc(void *p, size_t nbytes)
+{
+	return PyMem_REALLOC(p, nbytes);
+}
+
+void
+PyMem_Free(void *p)
+{
+	PyMem_FREE(p);
+}
+
+
+/* These methods are used to control infinite recursion in repr, str, print,
+   etc.  Container objects that may recursively contain themselves,
+   e.g. builtin dictionaries and lists, should used Py_ReprEnter() and
+   Py_ReprLeave() to avoid infinite recursion.
+
+   Py_ReprEnter() returns 0 the first time it is called for a particular
+   object and 1 every time thereafter.  It returns -1 if an exception
+   occurred.  Py_ReprLeave() has no return value.
+
+   See dictobject.c and listobject.c for examples of use.
+*/
+
+#define KEY "Py_Repr"
+
+int
+Py_ReprEnter(PyObject *obj)
+{
+	PyObject *dict;
+	PyObject *list;
+	Py_ssize_t i;
+
+	dict = PyThreadState_GetDict();
+	if (dict == NULL)
+		return 0;
+	list = PyDict_GetItemString(dict, KEY);
+	if (list == NULL) {
+		list = PyList_New(0);
+		if (list == NULL)
+			return -1;
+		if (PyDict_SetItemString(dict, KEY, list) < 0)
+			return -1;
+		Py_DECREF(list);
+	}
+	i = PyList_GET_SIZE(list);
+	while (--i >= 0) {
+		if (PyList_GET_ITEM(list, i) == obj)
+			return 1;
+	}
+	PyList_Append(list, obj);
+	return 0;
+}
+
+void
+Py_ReprLeave(PyObject *obj)
+{
+	PyObject *dict;
+	PyObject *list;
+	Py_ssize_t i;
+
+	dict = PyThreadState_GetDict();
+	if (dict == NULL)
+		return;
+	list = PyDict_GetItemString(dict, KEY);
+	if (list == NULL || !PyList_Check(list))
+		return;
+	i = PyList_GET_SIZE(list);
+	/* Count backwards because we always expect obj to be list[-1] */
+	while (--i >= 0) {
+		if (PyList_GET_ITEM(list, i) == obj) {
+			PyList_SetSlice(list, i, i + 1, NULL);
+			break;
+		}
+	}
+}
+
+/* Trashcan support. */
+
+/* Current call-stack depth of tp_dealloc calls. */
+int _PyTrash_delete_nesting = 0;
+
+/* List of objects that still need to be cleaned up, singly linked via their
+ * gc headers' gc_prev pointers.
+ */
+PyObject *_PyTrash_delete_later = NULL;
+
+/* Add op to the _PyTrash_delete_later list.  Called when the current
+ * call-stack depth gets large.  op must be a currently untracked gc'ed
+ * object, with refcount 0.  Py_DECREF must already have been called on it.
+ */
+void
+_PyTrash_deposit_object(PyObject *op)
+{
+	assert(PyObject_IS_GC(op));
+	assert(_Py_AS_GC(op)->gc.gc_refs == _PyGC_REFS_UNTRACKED);
+	assert(op->ob_refcnt == 0);
+	_Py_AS_GC(op)->gc.gc_prev = (PyGC_Head *)_PyTrash_delete_later;
+	_PyTrash_delete_later = op;
+}
+
+/* Dealloccate all the objects in the _PyTrash_delete_later list.  Called when
+ * the call-stack unwinds again.
+ */
+void
+_PyTrash_destroy_chain(void)
+{
+	while (_PyTrash_delete_later) {
+		PyObject *op = _PyTrash_delete_later;
+		destructor dealloc = op->ob_type->tp_dealloc;
+
+		_PyTrash_delete_later =
+			(PyObject*) _Py_AS_GC(op)->gc.gc_prev;
+
+		/* Call the deallocator directly.  This used to try to
+		 * fool Py_DECREF into calling it indirectly, but
+		 * Py_DECREF was already called on this object, and in
+		 * assorted non-release builds calling Py_DECREF again ends
+		 * up distorting allocation statistics.
+		 */
+		assert(op->ob_refcnt == 0);
+		++_PyTrash_delete_nesting;
+		(*dealloc)(op);
+		--_PyTrash_delete_nesting;
+	}
+}
+
+#ifdef __cplusplus
+}
+#endif
+

Added: vendor/Python/current/Objects/obmalloc.c
===================================================================
--- vendor/Python/current/Objects/obmalloc.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Objects/obmalloc.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1745 @@
+#include "Python.h"
+
+#ifdef WITH_PYMALLOC
+
+/* An object allocator for Python.
+
+   Here is an introduction to the layers of the Python memory architecture,
+   showing where the object allocator is actually used (layer +2), It is
+   called for every object allocation and deallocation (PyObject_New/Del),
+   unless the object-specific allocators implement a proprietary allocation
+   scheme (ex.: ints use a simple free list). This is also the place where
+   the cyclic garbage collector operates selectively on container objects.
+
+
+        Object-specific allocators
+    _____   ______   ______       ________
+   [ int ] [ dict ] [ list ] ... [ string ]       Python core         |
++3 | <----- Object-specific memory -----> | <-- Non-object memory --> |
+    _______________________________       |                           |
+   [   Python's object allocator   ]      |                           |
++2 | ####### Object memory ####### | <------ Internal buffers ------> |
+    ______________________________________________________________    |
+   [          Python's raw memory allocator (PyMem_ API)          ]   |
++1 | <----- Python memory (under PyMem manager's control) ------> |   |
+    __________________________________________________________________
+   [    Underlying general-purpose allocator (ex: C library malloc)   ]
+ 0 | <------ Virtual memory allocated for the python process -------> |
+
+   =========================================================================
+    _______________________________________________________________________
+   [                OS-specific Virtual Memory Manager (VMM)               ]
+-1 | <--- Kernel dynamic storage allocation & management (page-based) ---> |
+    __________________________________   __________________________________
+   [                                  ] [                                  ]
+-2 | <-- Physical memory: ROM/RAM --> | | <-- Secondary storage (swap) --> |
+
+*/
+/*==========================================================================*/
+
+/* A fast, special-purpose memory allocator for small blocks, to be used
+   on top of a general-purpose malloc -- heavily based on previous art. */
+
+/* Vladimir Marangozov -- August 2000 */
+
+/*
+ * "Memory management is where the rubber meets the road -- if we do the wrong
+ * thing at any level, the results will not be good. And if we don't make the
+ * levels work well together, we are in serious trouble." (1)
+ *
+ * (1) Paul R. Wilson, Mark S. Johnstone, Michael Neely, and David Boles,
+ *    "Dynamic Storage Allocation: A Survey and Critical Review",
+ *    in Proc. 1995 Int'l. Workshop on Memory Management, September 1995.
+ */
+
+/* #undef WITH_MEMORY_LIMITS */		/* disable mem limit checks  */
+
+/*==========================================================================*/
+
+/*
+ * Allocation strategy abstract:
+ *
+ * For small requests, the allocator sub-allocates <Big> blocks of memory.
+ * Requests greater than 256 bytes are routed to the system's allocator.
+ *
+ * Small requests are grouped in size classes spaced 8 bytes apart, due
+ * to the required valid alignment of the returned address. Requests of
+ * a particular size are serviced from memory pools of 4K (one VMM page).
+ * Pools are fragmented on demand and contain free lists of blocks of one
+ * particular size class. In other words, there is a fixed-size allocator
+ * for each size class. Free pools are shared by the different allocators
+ * thus minimizing the space reserved for a particular size class.
+ *
+ * This allocation strategy is a variant of what is known as "simple
+ * segregated storage based on array of free lists". The main drawback of
+ * simple segregated storage is that we might end up with lot of reserved
+ * memory for the different free lists, which degenerate in time. To avoid
+ * this, we partition each free list in pools and we share dynamically the
+ * reserved space between all free lists. This technique is quite efficient
+ * for memory intensive programs which allocate mainly small-sized blocks.
+ *
+ * For small requests we have the following table:
+ *
+ * Request in bytes	Size of allocated block      Size class idx
+ * ----------------------------------------------------------------
+ *        1-8                     8                       0
+ *	  9-16                   16                       1
+ *	 17-24                   24                       2
+ *	 25-32                   32                       3
+ *	 33-40                   40                       4
+ *	 41-48                   48                       5
+ *	 49-56                   56                       6
+ *	 57-64                   64                       7
+ *	 65-72                   72                       8
+ *	  ...                   ...                     ...
+ *	241-248                 248                      30
+ *	249-256                 256                      31
+ *
+ *	0, 257 and up: routed to the underlying allocator.
+ */
+
+/*==========================================================================*/
+
+/*
+ * -- Main tunable settings section --
+ */
+
+/*
+ * Alignment of addresses returned to the user. 8-bytes alignment works
+ * on most current architectures (with 32-bit or 64-bit address busses).
+ * The alignment value is also used for grouping small requests in size
+ * classes spaced ALIGNMENT bytes apart.
+ *
+ * You shouldn't change this unless you know what you are doing.
+ */
+#define ALIGNMENT		8		/* must be 2^N */
+#define ALIGNMENT_SHIFT		3
+#define ALIGNMENT_MASK		(ALIGNMENT - 1)
+
+/* Return the number of bytes in size class I, as a uint. */
+#define INDEX2SIZE(I) (((uint)(I) + 1) << ALIGNMENT_SHIFT)
+
+/*
+ * Max size threshold below which malloc requests are considered to be
+ * small enough in order to use preallocated memory pools. You can tune
+ * this value according to your application behaviour and memory needs.
+ *
+ * The following invariants must hold:
+ *	1) ALIGNMENT <= SMALL_REQUEST_THRESHOLD <= 256
+ *	2) SMALL_REQUEST_THRESHOLD is evenly divisible by ALIGNMENT
+ *
+ * Although not required, for better performance and space efficiency,
+ * it is recommended that SMALL_REQUEST_THRESHOLD is set to a power of 2.
+ */
+#define SMALL_REQUEST_THRESHOLD	256
+#define NB_SMALL_SIZE_CLASSES	(SMALL_REQUEST_THRESHOLD / ALIGNMENT)
+
+/*
+ * The system's VMM page size can be obtained on most unices with a
+ * getpagesize() call or deduced from various header files. To make
+ * things simpler, we assume that it is 4K, which is OK for most systems.
+ * It is probably better if this is the native page size, but it doesn't
+ * have to be.  In theory, if SYSTEM_PAGE_SIZE is larger than the native page
+ * size, then `POOL_ADDR(p)->arenaindex' could rarely cause a segmentation
+ * violation fault.  4K is apparently OK for all the platforms that python
+ * currently targets.
+ */
+#define SYSTEM_PAGE_SIZE	(4 * 1024)
+#define SYSTEM_PAGE_SIZE_MASK	(SYSTEM_PAGE_SIZE - 1)
+
+/*
+ * Maximum amount of memory managed by the allocator for small requests.
+ */
+#ifdef WITH_MEMORY_LIMITS
+#ifndef SMALL_MEMORY_LIMIT
+#define SMALL_MEMORY_LIMIT	(64 * 1024 * 1024)	/* 64 MB -- more? */
+#endif
+#endif
+
+/*
+ * The allocator sub-allocates <Big> blocks of memory (called arenas) aligned
+ * on a page boundary. This is a reserved virtual address space for the
+ * current process (obtained through a malloc call). In no way this means
+ * that the memory arenas will be used entirely. A malloc(<Big>) is usually
+ * an address range reservation for <Big> bytes, unless all pages within this
+ * space are referenced subsequently. So malloc'ing big blocks and not using
+ * them does not mean "wasting memory". It's an addressable range wastage...
+ *
+ * Therefore, allocating arenas with malloc is not optimal, because there is
+ * some address space wastage, but this is the most portable way to request
+ * memory from the system across various platforms.
+ */
+#define ARENA_SIZE		(256 << 10)	/* 256KB */
+
+#ifdef WITH_MEMORY_LIMITS
+#define MAX_ARENAS		(SMALL_MEMORY_LIMIT / ARENA_SIZE)
+#endif
+
+/*
+ * Size of the pools used for small blocks. Should be a power of 2,
+ * between 1K and SYSTEM_PAGE_SIZE, that is: 1k, 2k, 4k.
+ */
+#define POOL_SIZE		SYSTEM_PAGE_SIZE	/* must be 2^N */
+#define POOL_SIZE_MASK		SYSTEM_PAGE_SIZE_MASK
+
+/*
+ * -- End of tunable settings section --
+ */
+
+/*==========================================================================*/
+
+/*
+ * Locking
+ *
+ * To reduce lock contention, it would probably be better to refine the
+ * crude function locking with per size class locking. I'm not positive
+ * however, whether it's worth switching to such locking policy because
+ * of the performance penalty it might introduce.
+ *
+ * The following macros describe the simplest (should also be the fastest)
+ * lock object on a particular platform and the init/fini/lock/unlock
+ * operations on it. The locks defined here are not expected to be recursive
+ * because it is assumed that they will always be called in the order:
+ * INIT, [LOCK, UNLOCK]*, FINI.
+ */
+
+/*
+ * Python's threads are serialized, so object malloc locking is disabled.
+ */
+#define SIMPLELOCK_DECL(lock)	/* simple lock declaration		*/
+#define SIMPLELOCK_INIT(lock)	/* allocate (if needed) and initialize	*/
+#define SIMPLELOCK_FINI(lock)	/* free/destroy an existing lock 	*/
+#define SIMPLELOCK_LOCK(lock)	/* acquire released lock */
+#define SIMPLELOCK_UNLOCK(lock)	/* release acquired lock */
+
+/*
+ * Basic types
+ * I don't care if these are defined in <sys/types.h> or elsewhere. Axiom.
+ */
+#undef  uchar
+#define uchar	unsigned char	/* assuming == 8 bits  */
+
+#undef  uint
+#define uint	unsigned int	/* assuming >= 16 bits */
+
+#undef  ulong
+#define ulong	unsigned long	/* assuming >= 32 bits */
+
+#undef uptr
+#define uptr	Py_uintptr_t
+
+/* When you say memory, my mind reasons in terms of (pointers to) blocks */
+typedef uchar block;
+
+/* Pool for small blocks. */
+struct pool_header {
+	union { block *_padding;
+		uint count; } ref;	/* number of allocated blocks    */
+	block *freeblock;		/* pool's free list head         */
+	struct pool_header *nextpool;	/* next pool of this size class  */
+	struct pool_header *prevpool;	/* previous pool       ""        */
+	uint arenaindex;		/* index into arenas of base adr */
+	uint szidx;			/* block size class index	 */
+	uint nextoffset;		/* bytes to virgin block	 */
+	uint maxnextoffset;		/* largest valid nextoffset	 */
+};
+
+typedef struct pool_header *poolp;
+
+/* Record keeping for arenas. */
+struct arena_object {
+	/* The address of the arena, as returned by malloc.  Note that 0
+	 * will never be returned by a successful malloc, and is used
+	 * here to mark an arena_object that doesn't correspond to an
+	 * allocated arena.
+	 */
+	uptr address;
+
+	/* Pool-aligned pointer to the next pool to be carved off. */
+	block* pool_address;
+
+	/* The number of available pools in the arena:  free pools + never-
+	 * allocated pools.
+	 */
+	uint nfreepools;
+
+	/* The total number of pools in the arena, whether or not available. */
+	uint ntotalpools;
+
+	/* Singly-linked list of available pools. */
+	struct pool_header* freepools;
+
+	/* Whenever this arena_object is not associated with an allocated
+	 * arena, the nextarena member is used to link all unassociated
+	 * arena_objects in the singly-linked `unused_arena_objects` list.
+	 * The prevarena member is unused in this case.
+	 *
+	 * When this arena_object is associated with an allocated arena
+	 * with at least one available pool, both members are used in the
+	 * doubly-linked `usable_arenas` list, which is maintained in
+	 * increasing order of `nfreepools` values.
+	 *
+	 * Else this arena_object is associated with an allocated arena
+	 * all of whose pools are in use.  `nextarena` and `prevarena`
+	 * are both meaningless in this case.
+	 */
+	struct arena_object* nextarena;
+	struct arena_object* prevarena;
+};
+
+#undef  ROUNDUP
+#define ROUNDUP(x)		(((x) + ALIGNMENT_MASK) & ~ALIGNMENT_MASK)
+#define POOL_OVERHEAD		ROUNDUP(sizeof(struct pool_header))
+
+#define DUMMY_SIZE_IDX		0xffff	/* size class of newly cached pools */
+
+/* Round pointer P down to the closest pool-aligned address <= P, as a poolp */
+#define POOL_ADDR(P) ((poolp)((uptr)(P) & ~(uptr)POOL_SIZE_MASK))
+
+/* Return total number of blocks in pool of size index I, as a uint. */
+#define NUMBLOCKS(I) ((uint)(POOL_SIZE - POOL_OVERHEAD) / INDEX2SIZE(I))
+
+/*==========================================================================*/
+
+/*
+ * This malloc lock
+ */
+SIMPLELOCK_DECL(_malloc_lock)
+#define LOCK()		SIMPLELOCK_LOCK(_malloc_lock)
+#define UNLOCK()	SIMPLELOCK_UNLOCK(_malloc_lock)
+#define LOCK_INIT()	SIMPLELOCK_INIT(_malloc_lock)
+#define LOCK_FINI()	SIMPLELOCK_FINI(_malloc_lock)
+
+/*
+ * Pool table -- headed, circular, doubly-linked lists of partially used pools.
+
+This is involved.  For an index i, usedpools[i+i] is the header for a list of
+all partially used pools holding small blocks with "size class idx" i. So
+usedpools[0] corresponds to blocks of size 8, usedpools[2] to blocks of size
+16, and so on:  index 2*i <-> blocks of size (i+1)<<ALIGNMENT_SHIFT.
+
+Pools are carved off an arena's highwater mark (an arena_object's pool_address
+member) as needed.  Once carved off, a pool is in one of three states forever
+after:
+
+used == partially used, neither empty nor full
+    At least one block in the pool is currently allocated, and at least one
+    block in the pool is not currently allocated (note this implies a pool
+    has room for at least two blocks).
+    This is a pool's initial state, as a pool is created only when malloc
+    needs space.
+    The pool holds blocks of a fixed size, and is in the circular list headed
+    at usedpools[i] (see above).  It's linked to the other used pools of the
+    same size class via the pool_header's nextpool and prevpool members.
+    If all but one block is currently allocated, a malloc can cause a
+    transition to the full state.  If all but one block is not currently
+    allocated, a free can cause a transition to the empty state.
+
+full == all the pool's blocks are currently allocated
+    On transition to full, a pool is unlinked from its usedpools[] list.
+    It's not linked to from anything then anymore, and its nextpool and
+    prevpool members are meaningless until it transitions back to used.
+    A free of a block in a full pool puts the pool back in the used state.
+    Then it's linked in at the front of the appropriate usedpools[] list, so
+    that the next allocation for its size class will reuse the freed block.
+
+empty == all the pool's blocks are currently available for allocation
+    On transition to empty, a pool is unlinked from its usedpools[] list,
+    and linked to the front of its arena_object's singly-linked freepools list,
+    via its nextpool member.  The prevpool member has no meaning in this case.
+    Empty pools have no inherent size class:  the next time a malloc finds
+    an empty list in usedpools[], it takes the first pool off of freepools.
+    If the size class needed happens to be the same as the size class the pool
+    last had, some pool initialization can be skipped.
+
+
+Block Management
+
+Blocks within pools are again carved out as needed.  pool->freeblock points to
+the start of a singly-linked list of free blocks within the pool.  When a
+block is freed, it's inserted at the front of its pool's freeblock list.  Note
+that the available blocks in a pool are *not* linked all together when a pool
+is initialized.  Instead only "the first two" (lowest addresses) blocks are
+set up, returning the first such block, and setting pool->freeblock to a
+one-block list holding the second such block.  This is consistent with that
+pymalloc strives at all levels (arena, pool, and block) never to touch a piece
+of memory until it's actually needed.
+
+So long as a pool is in the used state, we're certain there *is* a block
+available for allocating, and pool->freeblock is not NULL.  If pool->freeblock
+points to the end of the free list before we've carved the entire pool into
+blocks, that means we simply haven't yet gotten to one of the higher-address
+blocks.  The offset from the pool_header to the start of "the next" virgin
+block is stored in the pool_header nextoffset member, and the largest value
+of nextoffset that makes sense is stored in the maxnextoffset member when a
+pool is initialized.  All the blocks in a pool have been passed out at least
+once when and only when nextoffset > maxnextoffset.
+
+
+Major obscurity:  While the usedpools vector is declared to have poolp
+entries, it doesn't really.  It really contains two pointers per (conceptual)
+poolp entry, the nextpool and prevpool members of a pool_header.  The
+excruciating initialization code below fools C so that
+
+    usedpool[i+i]
+
+"acts like" a genuine poolp, but only so long as you only reference its
+nextpool and prevpool members.  The "- 2*sizeof(block *)" gibberish is
+compensating for that a pool_header's nextpool and prevpool members
+immediately follow a pool_header's first two members:
+
+	union { block *_padding;
+		uint count; } ref;
+	block *freeblock;
+
+each of which consume sizeof(block *) bytes.  So what usedpools[i+i] really
+contains is a fudged-up pointer p such that *if* C believes it's a poolp
+pointer, then p->nextpool and p->prevpool are both p (meaning that the headed
+circular list is empty).
+
+It's unclear why the usedpools setup is so convoluted.  It could be to
+minimize the amount of cache required to hold this heavily-referenced table
+(which only *needs* the two interpool pointer members of a pool_header). OTOH,
+referencing code has to remember to "double the index" and doing so isn't
+free, usedpools[0] isn't a strictly legal pointer, and we're crucially relying
+on that C doesn't insert any padding anywhere in a pool_header at or before
+the prevpool member.
+**************************************************************************** */
+
+#define PTA(x)	((poolp )((uchar *)&(usedpools[2*(x)]) - 2*sizeof(block *)))
+#define PT(x)	PTA(x), PTA(x)
+
+static poolp usedpools[2 * ((NB_SMALL_SIZE_CLASSES + 7) / 8) * 8] = {
+	PT(0), PT(1), PT(2), PT(3), PT(4), PT(5), PT(6), PT(7)
+#if NB_SMALL_SIZE_CLASSES > 8
+	, PT(8), PT(9), PT(10), PT(11), PT(12), PT(13), PT(14), PT(15)
+#if NB_SMALL_SIZE_CLASSES > 16
+	, PT(16), PT(17), PT(18), PT(19), PT(20), PT(21), PT(22), PT(23)
+#if NB_SMALL_SIZE_CLASSES > 24
+	, PT(24), PT(25), PT(26), PT(27), PT(28), PT(29), PT(30), PT(31)
+#if NB_SMALL_SIZE_CLASSES > 32
+	, PT(32), PT(33), PT(34), PT(35), PT(36), PT(37), PT(38), PT(39)
+#if NB_SMALL_SIZE_CLASSES > 40
+	, PT(40), PT(41), PT(42), PT(43), PT(44), PT(45), PT(46), PT(47)
+#if NB_SMALL_SIZE_CLASSES > 48
+	, PT(48), PT(49), PT(50), PT(51), PT(52), PT(53), PT(54), PT(55)
+#if NB_SMALL_SIZE_CLASSES > 56
+	, PT(56), PT(57), PT(58), PT(59), PT(60), PT(61), PT(62), PT(63)
+#endif /* NB_SMALL_SIZE_CLASSES > 56 */
+#endif /* NB_SMALL_SIZE_CLASSES > 48 */
+#endif /* NB_SMALL_SIZE_CLASSES > 40 */
+#endif /* NB_SMALL_SIZE_CLASSES > 32 */
+#endif /* NB_SMALL_SIZE_CLASSES > 24 */
+#endif /* NB_SMALL_SIZE_CLASSES > 16 */
+#endif /* NB_SMALL_SIZE_CLASSES >  8 */
+};
+
+/*==========================================================================
+Arena management.
+
+`arenas` is a vector of arena_objects.  It contains maxarenas entries, some of
+which may not be currently used (== they're arena_objects that aren't
+currently associated with an allocated arena).  Note that arenas proper are
+separately malloc'ed.
+
+Prior to Python 2.5, arenas were never free()'ed.  Starting with Python 2.5,
+we do try to free() arenas, and use some mild heuristic strategies to increase
+the likelihood that arenas eventually can be freed.
+
+unused_arena_objects
+
+    This is a singly-linked list of the arena_objects that are currently not
+    being used (no arena is associated with them).  Objects are taken off the
+    head of the list in new_arena(), and are pushed on the head of the list in
+    PyObject_Free() when the arena is empty.  Key invariant:  an arena_object
+    is on this list if and only if its .address member is 0.
+
+usable_arenas
+
+    This is a doubly-linked list of the arena_objects associated with arenas
+    that have pools available.  These pools are either waiting to be reused,
+    or have not been used before.  The list is sorted to have the most-
+    allocated arenas first (ascending order based on the nfreepools member).
+    This means that the next allocation will come from a heavily used arena,
+    which gives the nearly empty arenas a chance to be returned to the system.
+    In my unscientific tests this dramatically improved the number of arenas
+    that could be freed.
+
+Note that an arena_object associated with an arena all of whose pools are
+currently in use isn't on either list.
+*/
+
+/* Array of objects used to track chunks of memory (arenas). */
+static struct arena_object* arenas = NULL;
+/* Number of slots currently allocated in the `arenas` vector. */
+static uint maxarenas = 0;
+
+/* The head of the singly-linked, NULL-terminated list of available
+ * arena_objects.
+ */
+static struct arena_object* unused_arena_objects = NULL;
+
+/* The head of the doubly-linked, NULL-terminated at each end, list of
+ * arena_objects associated with arenas that have pools available.
+ */
+static struct arena_object* usable_arenas = NULL;
+
+/* How many arena_objects do we initially allocate?
+ * 16 = can allocate 16 arenas = 16 * ARENA_SIZE = 4MB before growing the
+ * `arenas` vector.
+ */
+#define INITIAL_ARENA_OBJECTS 16
+
+/* Number of arenas allocated that haven't been free()'d. */
+static size_t narenas_currently_allocated = 0;
+
+#ifdef PYMALLOC_DEBUG
+/* Total number of times malloc() called to allocate an arena. */
+static size_t ntimes_arena_allocated = 0;
+/* High water mark (max value ever seen) for narenas_currently_allocated. */
+static size_t narenas_highwater = 0;
+#endif
+
+/* Allocate a new arena.  If we run out of memory, return NULL.  Else
+ * allocate a new arena, and return the address of an arena_object
+ * describing the new arena.  It's expected that the caller will set
+ * `usable_arenas` to the return value.
+ */
+static struct arena_object*
+new_arena(void)
+{
+	struct arena_object* arenaobj;
+	uint excess;	/* number of bytes above pool alignment */
+
+#ifdef PYMALLOC_DEBUG
+	if (Py_GETENV("PYTHONMALLOCSTATS"))
+		_PyObject_DebugMallocStats();
+#endif
+	if (unused_arena_objects == NULL) {
+		uint i;
+		uint numarenas;
+		size_t nbytes;
+
+		/* Double the number of arena objects on each allocation.
+		 * Note that it's possible for `numarenas` to overflow.
+		 */
+		numarenas = maxarenas ? maxarenas << 1 : INITIAL_ARENA_OBJECTS;
+		if (numarenas <= maxarenas)
+			return NULL;	/* overflow */
+		nbytes = numarenas * sizeof(*arenas);
+		if (nbytes / sizeof(*arenas) != numarenas)
+			return NULL;	/* overflow */
+		arenaobj = (struct arena_object *)realloc(arenas, nbytes);
+		if (arenaobj == NULL)
+			return NULL;
+		arenas = arenaobj;
+
+		/* We might need to fix pointers that were copied.  However,
+		 * new_arena only gets called when all the pages in the
+		 * previous arenas are full.  Thus, there are *no* pointers
+		 * into the old array. Thus, we don't have to worry about
+		 * invalid pointers.  Just to be sure, some asserts:
+		 */
+		assert(usable_arenas == NULL);
+		assert(unused_arena_objects == NULL);
+
+		/* Put the new arenas on the unused_arena_objects list. */
+		for (i = maxarenas; i < numarenas; ++i) {
+			arenas[i].address = 0;	/* mark as unassociated */
+			arenas[i].nextarena = i < numarenas - 1 ?
+					       &arenas[i+1] : NULL;
+		}
+
+		/* Update globals. */
+		unused_arena_objects = &arenas[maxarenas];
+		maxarenas = numarenas;
+	}
+
+	/* Take the next available arena object off the head of the list. */
+	assert(unused_arena_objects != NULL);
+	arenaobj = unused_arena_objects;
+	unused_arena_objects = arenaobj->nextarena;
+	assert(arenaobj->address == 0);
+	arenaobj->address = (uptr)malloc(ARENA_SIZE);
+	if (arenaobj->address == 0) {
+		/* The allocation failed: return NULL after putting the
+		 * arenaobj back.
+		 */
+		arenaobj->nextarena = unused_arena_objects;
+		unused_arena_objects = arenaobj;
+		return NULL;
+	}
+
+	++narenas_currently_allocated;
+#ifdef PYMALLOC_DEBUG
+	++ntimes_arena_allocated;
+	if (narenas_currently_allocated > narenas_highwater)
+		narenas_highwater = narenas_currently_allocated;
+#endif
+	arenaobj->freepools = NULL;
+	/* pool_address <- first pool-aligned address in the arena
+	   nfreepools <- number of whole pools that fit after alignment */
+	arenaobj->pool_address = (block*)arenaobj->address;
+	arenaobj->nfreepools = ARENA_SIZE / POOL_SIZE;
+	assert(POOL_SIZE * arenaobj->nfreepools == ARENA_SIZE);
+	excess = (uint)(arenaobj->address & POOL_SIZE_MASK);
+	if (excess != 0) {
+		--arenaobj->nfreepools;
+		arenaobj->pool_address += POOL_SIZE - excess;
+	}
+	arenaobj->ntotalpools = arenaobj->nfreepools;
+
+	return arenaobj;
+}
+
+/*
+Py_ADDRESS_IN_RANGE(P, POOL)
+
+Return true if and only if P is an address that was allocated by pymalloc.
+POOL must be the pool address associated with P, i.e., POOL = POOL_ADDR(P)
+(the caller is asked to compute this because the macro expands POOL more than
+once, and for efficiency it's best for the caller to assign POOL_ADDR(P) to a
+variable and pass the latter to the macro; because Py_ADDRESS_IN_RANGE is
+called on every alloc/realloc/free, micro-efficiency is important here).
+
+Tricky:  Let B be the arena base address associated with the pool, B =
+arenas[(POOL)->arenaindex].address.  Then P belongs to the arena if and only if
+
+	B <= P < B + ARENA_SIZE
+
+Subtracting B throughout, this is true iff
+
+	0 <= P-B < ARENA_SIZE
+
+By using unsigned arithmetic, the "0 <=" half of the test can be skipped.
+
+Obscure:  A PyMem "free memory" function can call the pymalloc free or realloc
+before the first arena has been allocated.  `arenas` is still NULL in that
+case.  We're relying on that maxarenas is also 0 in that case, so that
+(POOL)->arenaindex < maxarenas  must be false, saving us from trying to index
+into a NULL arenas.
+
+Details:  given P and POOL, the arena_object corresponding to P is AO =
+arenas[(POOL)->arenaindex].  Suppose obmalloc controls P.  Then (barring wild
+stores, etc), POOL is the correct address of P's pool, AO.address is the
+correct base address of the pool's arena, and P must be within ARENA_SIZE of
+AO.address.  In addition, AO.address is not 0 (no arena can start at address 0
+(NULL)).  Therefore Py_ADDRESS_IN_RANGE correctly reports that obmalloc
+controls P.
+
+Now suppose obmalloc does not control P (e.g., P was obtained via a direct
+call to the system malloc() or realloc()).  (POOL)->arenaindex may be anything
+in this case -- it may even be uninitialized trash.  If the trash arenaindex
+is >= maxarenas, the macro correctly concludes at once that obmalloc doesn't
+control P.
+
+Else arenaindex is < maxarena, and AO is read up.  If AO corresponds to an
+allocated arena, obmalloc controls all the memory in slice AO.address :
+AO.address+ARENA_SIZE.  By case assumption, P is not controlled by obmalloc,
+so P doesn't lie in that slice, so the macro correctly reports that P is not
+controlled by obmalloc.
+
+Finally, if P is not controlled by obmalloc and AO corresponds to an unused
+arena_object (one not currently associated with an allocated arena),
+AO.address is 0, and the second test in the macro reduces to:
+
+	P < ARENA_SIZE
+
+If P >= ARENA_SIZE (extremely likely), the macro again correctly concludes
+that P is not controlled by obmalloc.  However, if P < ARENA_SIZE, this part
+of the test still passes, and the third clause (AO.address != 0) is necessary
+to get the correct result:  AO.address is 0 in this case, so the macro
+correctly reports that P is not controlled by obmalloc (despite that P lies in
+slice AO.address : AO.address + ARENA_SIZE).
+
+Note:  The third (AO.address != 0) clause was added in Python 2.5.  Before
+2.5, arenas were never free()'ed, and an arenaindex < maxarena always
+corresponded to a currently-allocated arena, so the "P is not controlled by
+obmalloc, AO corresponds to an unused arena_object, and P < ARENA_SIZE" case
+was impossible.
+
+Note that the logic is excruciating, and reading up possibly uninitialized
+memory when P is not controlled by obmalloc (to get at (POOL)->arenaindex)
+creates problems for some memory debuggers.  The overwhelming advantage is
+that this test determines whether an arbitrary address is controlled by
+obmalloc in a small constant time, independent of the number of arenas
+obmalloc controls.  Since this test is needed at every entry point, it's
+extremely desirable that it be this fast.
+*/
+#define Py_ADDRESS_IN_RANGE(P, POOL)			\
+	((POOL)->arenaindex < maxarenas &&		\
+	 (uptr)(P) - arenas[(POOL)->arenaindex].address < (uptr)ARENA_SIZE && \
+	 arenas[(POOL)->arenaindex].address != 0)
+
+
+/* This is only useful when running memory debuggers such as
+ * Purify or Valgrind.  Uncomment to use.
+ *
+#define Py_USING_MEMORY_DEBUGGER
+ */
+
+#ifdef Py_USING_MEMORY_DEBUGGER
+
+/* Py_ADDRESS_IN_RANGE may access uninitialized memory by design
+ * This leads to thousands of spurious warnings when using
+ * Purify or Valgrind.  By making a function, we can easily
+ * suppress the uninitialized memory reads in this one function.
+ * So we won't ignore real errors elsewhere.
+ *
+ * Disable the macro and use a function.
+ */
+
+#undef Py_ADDRESS_IN_RANGE
+
+#if defined(__GNUC__) && ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1) || \
+			  (__GNUC__ >= 4))
+#define Py_NO_INLINE __attribute__((__noinline__))
+#else
+#define Py_NO_INLINE
+#endif
+
+/* Don't make static, to try to ensure this isn't inlined. */
+int Py_ADDRESS_IN_RANGE(void *P, poolp pool) Py_NO_INLINE;
+#undef Py_NO_INLINE
+#endif
+
+/*==========================================================================*/
+
+/* malloc.  Note that nbytes==0 tries to return a non-NULL pointer, distinct
+ * from all other currently live pointers.  This may not be possible.
+ */
+
+/*
+ * The basic blocks are ordered by decreasing execution frequency,
+ * which minimizes the number of jumps in the most common cases,
+ * improves branching prediction and instruction scheduling (small
+ * block allocations typically result in a couple of instructions).
+ * Unless the optimizer reorders everything, being too smart...
+ */
+
+#undef PyObject_Malloc
+void *
+PyObject_Malloc(size_t nbytes)
+{
+	block *bp;
+	poolp pool;
+	poolp next;
+	uint size;
+
+	/*
+	 * This implicitly redirects malloc(0).
+	 */
+	if ((nbytes - 1) < SMALL_REQUEST_THRESHOLD) {
+		LOCK();
+		/*
+		 * Most frequent paths first
+		 */
+		size = (uint)(nbytes - 1) >> ALIGNMENT_SHIFT;
+		pool = usedpools[size + size];
+		if (pool != pool->nextpool) {
+			/*
+			 * There is a used pool for this size class.
+			 * Pick up the head block of its free list.
+			 */
+			++pool->ref.count;
+			bp = pool->freeblock;
+			assert(bp != NULL);
+			if ((pool->freeblock = *(block **)bp) != NULL) {
+				UNLOCK();
+				return (void *)bp;
+			}
+			/*
+			 * Reached the end of the free list, try to extend it.
+			 */
+			if (pool->nextoffset <= pool->maxnextoffset) {
+				/* There is room for another block. */
+				pool->freeblock = (block*)pool +
+						  pool->nextoffset;
+				pool->nextoffset += INDEX2SIZE(size);
+				*(block **)(pool->freeblock) = NULL;
+				UNLOCK();
+				return (void *)bp;
+			}
+			/* Pool is full, unlink from used pools. */
+			next = pool->nextpool;
+			pool = pool->prevpool;
+			next->prevpool = pool;
+			pool->nextpool = next;
+			UNLOCK();
+			return (void *)bp;
+		}
+
+		/* There isn't a pool of the right size class immediately
+		 * available:  use a free pool.
+		 */
+		if (usable_arenas == NULL) {
+			/* No arena has a free pool:  allocate a new arena. */
+#ifdef WITH_MEMORY_LIMITS
+			if (narenas_currently_allocated >= MAX_ARENAS) {
+				UNLOCK();
+				goto redirect;
+			}
+#endif
+			usable_arenas = new_arena();
+			if (usable_arenas == NULL) {
+				UNLOCK();
+				goto redirect;
+			}
+			usable_arenas->nextarena =
+				usable_arenas->prevarena = NULL;
+		}
+		assert(usable_arenas->address != 0);
+
+		/* Try to get a cached free pool. */
+		pool = usable_arenas->freepools;
+		if (pool != NULL) {
+			/* Unlink from cached pools. */
+			usable_arenas->freepools = pool->nextpool;
+
+			/* This arena already had the smallest nfreepools
+			 * value, so decreasing nfreepools doesn't change
+			 * that, and we don't need to rearrange the
+			 * usable_arenas list.  However, if the arena has
+			 * become wholly allocated, we need to remove its
+			 * arena_object from usable_arenas.
+			 */
+			--usable_arenas->nfreepools;
+			if (usable_arenas->nfreepools == 0) {
+				/* Wholly allocated:  remove. */
+				assert(usable_arenas->freepools == NULL);
+				assert(usable_arenas->nextarena == NULL ||
+				       usable_arenas->nextarena->prevarena ==
+					   usable_arenas);
+
+				usable_arenas = usable_arenas->nextarena;
+				if (usable_arenas != NULL) {
+					usable_arenas->prevarena = NULL;
+					assert(usable_arenas->address != 0);
+				}
+			}
+			else {
+				/* nfreepools > 0:  it must be that freepools
+				 * isn't NULL, or that we haven't yet carved
+				 * off all the arena's pools for the first
+				 * time.
+				 */
+				assert(usable_arenas->freepools != NULL ||
+				       usable_arenas->pool_address <=
+				           (block*)usable_arenas->address +
+				               ARENA_SIZE - POOL_SIZE);
+			}
+		init_pool:
+			/* Frontlink to used pools. */
+			next = usedpools[size + size]; /* == prev */
+			pool->nextpool = next;
+			pool->prevpool = next;
+			next->nextpool = pool;
+			next->prevpool = pool;
+			pool->ref.count = 1;
+			if (pool->szidx == size) {
+				/* Luckily, this pool last contained blocks
+				 * of the same size class, so its header
+				 * and free list are already initialized.
+				 */
+				bp = pool->freeblock;
+				pool->freeblock = *(block **)bp;
+				UNLOCK();
+				return (void *)bp;
+			}
+			/*
+			 * Initialize the pool header, set up the free list to
+			 * contain just the second block, and return the first
+			 * block.
+			 */
+			pool->szidx = size;
+			size = INDEX2SIZE(size);
+			bp = (block *)pool + POOL_OVERHEAD;
+			pool->nextoffset = POOL_OVERHEAD + (size << 1);
+			pool->maxnextoffset = POOL_SIZE - size;
+			pool->freeblock = bp + size;
+			*(block **)(pool->freeblock) = NULL;
+			UNLOCK();
+			return (void *)bp;
+		}
+
+		/* Carve off a new pool. */
+		assert(usable_arenas->nfreepools > 0);
+		assert(usable_arenas->freepools == NULL);
+		pool = (poolp)usable_arenas->pool_address;
+		assert((block*)pool <= (block*)usable_arenas->address +
+		                       ARENA_SIZE - POOL_SIZE);
+		pool->arenaindex = usable_arenas - arenas;
+		assert(&arenas[pool->arenaindex] == usable_arenas);
+		pool->szidx = DUMMY_SIZE_IDX;
+		usable_arenas->pool_address += POOL_SIZE;
+		--usable_arenas->nfreepools;
+
+		if (usable_arenas->nfreepools == 0) {
+			assert(usable_arenas->nextarena == NULL ||
+			       usable_arenas->nextarena->prevarena ==
+			       	   usable_arenas);
+			/* Unlink the arena:  it is completely allocated. */
+			usable_arenas = usable_arenas->nextarena;
+			if (usable_arenas != NULL) {
+				usable_arenas->prevarena = NULL;
+				assert(usable_arenas->address != 0);
+			}
+		}
+
+		goto init_pool;
+	}
+
+        /* The small block allocator ends here. */
+
+redirect:
+	/* Redirect the original request to the underlying (libc) allocator.
+	 * We jump here on bigger requests, on error in the code above (as a
+	 * last chance to serve the request) or when the max memory limit
+	 * has been reached.
+	 */
+	if (nbytes == 0)
+		nbytes = 1;
+	return (void *)malloc(nbytes);
+}
+
+/* free */
+
+#undef PyObject_Free
+void
+PyObject_Free(void *p)
+{
+	poolp pool;
+	block *lastfree;
+	poolp next, prev;
+	uint size;
+
+	if (p == NULL)	/* free(NULL) has no effect */
+		return;
+
+	pool = POOL_ADDR(p);
+	if (Py_ADDRESS_IN_RANGE(p, pool)) {
+		/* We allocated this address. */
+		LOCK();
+		/* Link p to the start of the pool's freeblock list.  Since
+		 * the pool had at least the p block outstanding, the pool
+		 * wasn't empty (so it's already in a usedpools[] list, or
+		 * was full and is in no list -- it's not in the freeblocks
+		 * list in any case).
+		 */
+		assert(pool->ref.count > 0);	/* else it was empty */
+		*(block **)p = lastfree = pool->freeblock;
+		pool->freeblock = (block *)p;
+		if (lastfree) {
+			struct arena_object* ao;
+			uint nf;  /* ao->nfreepools */
+
+			/* freeblock wasn't NULL, so the pool wasn't full,
+			 * and the pool is in a usedpools[] list.
+			 */
+			if (--pool->ref.count != 0) {
+				/* pool isn't empty:  leave it in usedpools */
+				UNLOCK();
+				return;
+			}
+			/* Pool is now empty:  unlink from usedpools, and
+			 * link to the front of freepools.  This ensures that
+			 * previously freed pools will be allocated later
+			 * (being not referenced, they are perhaps paged out).
+			 */
+			next = pool->nextpool;
+			prev = pool->prevpool;
+			next->prevpool = prev;
+			prev->nextpool = next;
+
+			/* Link the pool to freepools.  This is a singly-linked
+			 * list, and pool->prevpool isn't used there.
+			 */
+			ao = &arenas[pool->arenaindex];
+			pool->nextpool = ao->freepools;
+			ao->freepools = pool;
+			nf = ++ao->nfreepools;
+
+			/* All the rest is arena management.  We just freed
+			 * a pool, and there are 4 cases for arena mgmt:
+			 * 1. If all the pools are free, return the arena to
+			 *    the system free().
+			 * 2. If this is the only free pool in the arena,
+			 *    add the arena back to the `usable_arenas` list.
+			 * 3. If the "next" arena has a smaller count of free
+			 *    pools, we have to "slide this arena right" to
+			 *    restore that usable_arenas is sorted in order of
+			 *    nfreepools.
+			 * 4. Else there's nothing more to do.
+			 */
+			if (nf == ao->ntotalpools) {
+				/* Case 1.  First unlink ao from usable_arenas.
+				 */
+				assert(ao->prevarena == NULL ||
+				       ao->prevarena->address != 0);
+				assert(ao ->nextarena == NULL ||
+				       ao->nextarena->address != 0);
+
+				/* Fix the pointer in the prevarena, or the
+				 * usable_arenas pointer.
+				 */
+				if (ao->prevarena == NULL) {
+					usable_arenas = ao->nextarena;
+					assert(usable_arenas == NULL ||
+					       usable_arenas->address != 0);
+				}
+				else {
+					assert(ao->prevarena->nextarena == ao);
+					ao->prevarena->nextarena =
+						ao->nextarena;
+				}
+				/* Fix the pointer in the nextarena. */
+				if (ao->nextarena != NULL) {
+					assert(ao->nextarena->prevarena == ao);
+					ao->nextarena->prevarena =
+						ao->prevarena;
+				}
+				/* Record that this arena_object slot is
+				 * available to be reused.
+				 */
+				ao->nextarena = unused_arena_objects;
+				unused_arena_objects = ao;
+
+				/* Free the entire arena. */
+				free((void *)ao->address);
+				ao->address = 0;	/* mark unassociated */
+				--narenas_currently_allocated;
+
+				UNLOCK();
+				return;
+			}
+			if (nf == 1) {
+				/* Case 2.  Put ao at the head of
+				 * usable_arenas.  Note that because
+				 * ao->nfreepools was 0 before, ao isn't
+				 * currently on the usable_arenas list.
+				 */
+				ao->nextarena = usable_arenas;
+				ao->prevarena = NULL;
+				if (usable_arenas)
+					usable_arenas->prevarena = ao;
+				usable_arenas = ao;
+				assert(usable_arenas->address != 0);
+
+				UNLOCK();
+				return;
+			}
+			/* If this arena is now out of order, we need to keep
+			 * the list sorted.  The list is kept sorted so that
+			 * the "most full" arenas are used first, which allows
+			 * the nearly empty arenas to be completely freed.  In
+			 * a few un-scientific tests, it seems like this
+			 * approach allowed a lot more memory to be freed.
+			 */
+			if (ao->nextarena == NULL ||
+				     nf <= ao->nextarena->nfreepools) {
+				/* Case 4.  Nothing to do. */
+				UNLOCK();
+				return;
+			}
+			/* Case 3:  We have to move the arena towards the end
+			 * of the list, because it has more free pools than
+			 * the arena to its right.
+			 * First unlink ao from usable_arenas.
+			 */
+			if (ao->prevarena != NULL) {
+				/* ao isn't at the head of the list */
+				assert(ao->prevarena->nextarena == ao);
+				ao->prevarena->nextarena = ao->nextarena;
+			}
+			else {
+				/* ao is at the head of the list */
+				assert(usable_arenas == ao);
+				usable_arenas = ao->nextarena;
+			}
+			ao->nextarena->prevarena = ao->prevarena;
+
+			/* Locate the new insertion point by iterating over
+			 * the list, using our nextarena pointer.
+			 */
+			while (ao->nextarena != NULL &&
+					nf > ao->nextarena->nfreepools) {
+				ao->prevarena = ao->nextarena;
+				ao->nextarena = ao->nextarena->nextarena;
+			}
+
+			/* Insert ao at this point. */
+			assert(ao->nextarena == NULL ||
+				ao->prevarena == ao->nextarena->prevarena);
+			assert(ao->prevarena->nextarena == ao->nextarena);
+
+			ao->prevarena->nextarena = ao;
+			if (ao->nextarena != NULL)
+				ao->nextarena->prevarena = ao;
+
+			/* Verify that the swaps worked. */
+			assert(ao->nextarena == NULL ||
+				  nf <= ao->nextarena->nfreepools);
+			assert(ao->prevarena == NULL ||
+				  nf > ao->prevarena->nfreepools);
+			assert(ao->nextarena == NULL ||
+				ao->nextarena->prevarena == ao);
+			assert((usable_arenas == ao &&
+				ao->prevarena == NULL) ||
+				ao->prevarena->nextarena == ao);
+
+			UNLOCK();
+			return;
+		}
+		/* Pool was full, so doesn't currently live in any list:
+		 * link it to the front of the appropriate usedpools[] list.
+		 * This mimics LRU pool usage for new allocations and
+		 * targets optimal filling when several pools contain
+		 * blocks of the same size class.
+		 */
+		--pool->ref.count;
+		assert(pool->ref.count > 0);	/* else the pool is empty */
+		size = pool->szidx;
+		next = usedpools[size + size];
+		prev = next->prevpool;
+		/* insert pool before next:   prev <-> pool <-> next */
+		pool->nextpool = next;
+		pool->prevpool = prev;
+		next->prevpool = pool;
+		prev->nextpool = pool;
+		UNLOCK();
+		return;
+	}
+
+	/* We didn't allocate this address. */
+	free(p);
+}
+
+/* realloc.  If p is NULL, this acts like malloc(nbytes).  Else if nbytes==0,
+ * then as the Python docs promise, we do not treat this like free(p), and
+ * return a non-NULL result.
+ */
+
+#undef PyObject_Realloc
+void *
+PyObject_Realloc(void *p, size_t nbytes)
+{
+	void *bp;
+	poolp pool;
+	size_t size;
+
+	if (p == NULL)
+		return PyObject_Malloc(nbytes);
+
+	pool = POOL_ADDR(p);
+	if (Py_ADDRESS_IN_RANGE(p, pool)) {
+		/* We're in charge of this block */
+		size = INDEX2SIZE(pool->szidx);
+		if (nbytes <= size) {
+			/* The block is staying the same or shrinking.  If
+			 * it's shrinking, there's a tradeoff:  it costs
+			 * cycles to copy the block to a smaller size class,
+			 * but it wastes memory not to copy it.  The
+			 * compromise here is to copy on shrink only if at
+			 * least 25% of size can be shaved off.
+			 */
+			if (4 * nbytes > 3 * size) {
+				/* It's the same,
+				 * or shrinking and new/old > 3/4.
+				 */
+				return p;
+			}
+			size = nbytes;
+		}
+		bp = PyObject_Malloc(nbytes);
+		if (bp != NULL) {
+			memcpy(bp, p, size);
+			PyObject_Free(p);
+		}
+		return bp;
+	}
+	/* We're not managing this block.  If nbytes <=
+	 * SMALL_REQUEST_THRESHOLD, it's tempting to try to take over this
+	 * block.  However, if we do, we need to copy the valid data from
+	 * the C-managed block to one of our blocks, and there's no portable
+	 * way to know how much of the memory space starting at p is valid.
+	 * As bug 1185883 pointed out the hard way, it's possible that the
+	 * C-managed block is "at the end" of allocated VM space, so that
+	 * a memory fault can occur if we try to copy nbytes bytes starting
+	 * at p.  Instead we punt:  let C continue to manage this block.
+         */
+	if (nbytes)
+		return realloc(p, nbytes);
+	/* C doesn't define the result of realloc(p, 0) (it may or may not
+	 * return NULL then), but Python's docs promise that nbytes==0 never
+	 * returns NULL.  We don't pass 0 to realloc(), to avoid that endcase
+	 * to begin with.  Even then, we can't be sure that realloc() won't
+	 * return NULL.
+	 */
+	bp = realloc(p, 1);
+   	return bp ? bp : p;
+}
+
+#else	/* ! WITH_PYMALLOC */
+
+/*==========================================================================*/
+/* pymalloc not enabled:  Redirect the entry points to malloc.  These will
+ * only be used by extensions that are compiled with pymalloc enabled. */
+
+void *
+PyObject_Malloc(size_t n)
+{
+	return PyMem_MALLOC(n);
+}
+
+void *
+PyObject_Realloc(void *p, size_t n)
+{
+	return PyMem_REALLOC(p, n);
+}
+
+void
+PyObject_Free(void *p)
+{
+	PyMem_FREE(p);
+}
+#endif /* WITH_PYMALLOC */
+
+#ifdef PYMALLOC_DEBUG
+/*==========================================================================*/
+/* A x-platform debugging allocator.  This doesn't manage memory directly,
+ * it wraps a real allocator, adding extra debugging info to the memory blocks.
+ */
+
+/* Special bytes broadcast into debug memory blocks at appropriate times.
+ * Strings of these are unlikely to be valid addresses, floats, ints or
+ * 7-bit ASCII.
+ */
+#undef CLEANBYTE
+#undef DEADBYTE
+#undef FORBIDDENBYTE
+#define CLEANBYTE      0xCB    /* clean (newly allocated) memory */
+#define DEADBYTE       0xDB    /* dead (newly freed) memory */
+#define FORBIDDENBYTE  0xFB    /* untouchable bytes at each end of a block */
+
+static size_t serialno = 0;	/* incremented on each debug {m,re}alloc */
+
+/* serialno is always incremented via calling this routine.  The point is
+ * to supply a single place to set a breakpoint.
+ */
+static void
+bumpserialno(void)
+{
+	++serialno;
+}
+
+#define SST SIZEOF_SIZE_T
+
+/* Read sizeof(size_t) bytes at p as a big-endian size_t. */
+static size_t
+read_size_t(const void *p)
+{
+	const uchar *q = (const uchar *)p;
+	size_t result = *q++;
+	int i;
+
+	for (i = SST; --i > 0; ++q)
+		result = (result << 8) | *q;
+	return result;
+}
+
+/* Write n as a big-endian size_t, MSB at address p, LSB at
+ * p + sizeof(size_t) - 1.
+ */
+static void
+write_size_t(void *p, size_t n)
+{
+	uchar *q = (uchar *)p + SST - 1;
+	int i;
+
+	for (i = SST; --i >= 0; --q) {
+		*q = (uchar)(n & 0xff);
+		n >>= 8;
+	}
+}
+
+#ifdef Py_DEBUG
+/* Is target in the list?  The list is traversed via the nextpool pointers.
+ * The list may be NULL-terminated, or circular.  Return 1 if target is in
+ * list, else 0.
+ */
+static int
+pool_is_in_list(const poolp target, poolp list)
+{
+	poolp origlist = list;
+	assert(target != NULL);
+	if (list == NULL)
+		return 0;
+	do {
+		if (target == list)
+			return 1;
+		list = list->nextpool;
+	} while (list != NULL && list != origlist);
+	return 0;
+}
+
+#else
+#define pool_is_in_list(X, Y) 1
+
+#endif	/* Py_DEBUG */
+
+/* Let S = sizeof(size_t).  The debug malloc asks for 4*S extra bytes and
+   fills them with useful stuff, here calling the underlying malloc's result p:
+
+p[0: S]
+    Number of bytes originally asked for.  This is a size_t, big-endian (easier
+    to read in a memory dump).
+p[S: 2*S]
+    Copies of FORBIDDENBYTE.  Used to catch under- writes and reads.
+p[2*S: 2*S+n]
+    The requested memory, filled with copies of CLEANBYTE.
+    Used to catch reference to uninitialized memory.
+    &p[2*S] is returned.  Note that this is 8-byte aligned if pymalloc
+    handled the request itself.
+p[2*S+n: 2*S+n+S]
+    Copies of FORBIDDENBYTE.  Used to catch over- writes and reads.
+p[2*S+n+S: 2*S+n+2*S]
+    A serial number, incremented by 1 on each call to _PyObject_DebugMalloc
+    and _PyObject_DebugRealloc.
+    This is a big-endian size_t.
+    If "bad memory" is detected later, the serial number gives an
+    excellent way to set a breakpoint on the next run, to capture the
+    instant at which this block was passed out.
+*/
+
+void *
+_PyObject_DebugMalloc(size_t nbytes)
+{
+	uchar *p;	/* base address of malloc'ed block */
+	uchar *tail;	/* p + 2*SST + nbytes == pointer to tail pad bytes */
+	size_t total;	/* nbytes + 4*SST */
+
+	bumpserialno();
+	total = nbytes + 4*SST;
+	if (total < nbytes)
+		/* overflow:  can't represent total as a size_t */
+		return NULL;
+
+	p = (uchar *)PyObject_Malloc(total);
+	if (p == NULL)
+		return NULL;
+
+	write_size_t(p, nbytes);
+	memset(p + SST, FORBIDDENBYTE, SST);
+
+	if (nbytes > 0)
+		memset(p + 2*SST, CLEANBYTE, nbytes);
+
+	tail = p + 2*SST + nbytes;
+	memset(tail, FORBIDDENBYTE, SST);
+	write_size_t(tail + SST, serialno);
+
+	return p + 2*SST;
+}
+
+/* The debug free first checks the 2*SST bytes on each end for sanity (in
+   particular, that the FORBIDDENBYTEs are still intact).
+   Then fills the original bytes with DEADBYTE.
+   Then calls the underlying free.
+*/
+void
+_PyObject_DebugFree(void *p)
+{
+	uchar *q = (uchar *)p - 2*SST;  /* address returned from malloc */
+	size_t nbytes;
+
+	if (p == NULL)
+		return;
+	_PyObject_DebugCheckAddress(p);
+	nbytes = read_size_t(q);
+	if (nbytes > 0)
+		memset(q, DEADBYTE, nbytes);
+	PyObject_Free(q);
+}
+
+void *
+_PyObject_DebugRealloc(void *p, size_t nbytes)
+{
+	uchar *q = (uchar *)p;
+	uchar *tail;
+	size_t total;	/* nbytes + 4*SST */
+	size_t original_nbytes;
+	int i;
+
+	if (p == NULL)
+		return _PyObject_DebugMalloc(nbytes);
+
+	_PyObject_DebugCheckAddress(p);
+	bumpserialno();
+	original_nbytes = read_size_t(q - 2*SST);
+	total = nbytes + 4*SST;
+	if (total < nbytes)
+		/* overflow:  can't represent total as a size_t */
+		return NULL;
+
+	if (nbytes < original_nbytes) {
+		/* shrinking:  mark old extra memory dead */
+		memset(q + nbytes, DEADBYTE, original_nbytes - nbytes);
+	}
+
+	/* Resize and add decorations. */
+	q = (uchar *)PyObject_Realloc(q - 2*SST, total);
+	if (q == NULL)
+		return NULL;
+
+	write_size_t(q, nbytes);
+	for (i = 0; i < SST; ++i)
+		assert(q[SST + i] == FORBIDDENBYTE);
+	q += 2*SST;
+	tail = q + nbytes;
+	memset(tail, FORBIDDENBYTE, SST);
+	write_size_t(tail + SST, serialno);
+
+	if (nbytes > original_nbytes) {
+		/* growing:  mark new extra memory clean */
+		memset(q + original_nbytes, CLEANBYTE,
+			nbytes - original_nbytes);
+	}
+
+	return q;
+}
+
+/* Check the forbidden bytes on both ends of the memory allocated for p.
+ * If anything is wrong, print info to stderr via _PyObject_DebugDumpAddress,
+ * and call Py_FatalError to kill the program.
+ */
+ void
+_PyObject_DebugCheckAddress(const void *p)
+{
+	const uchar *q = (const uchar *)p;
+	char *msg;
+	size_t nbytes;
+	const uchar *tail;
+	int i;
+
+	if (p == NULL) {
+		msg = "didn't expect a NULL pointer";
+		goto error;
+	}
+
+	/* Check the stuff at the start of p first:  if there's underwrite
+	 * corruption, the number-of-bytes field may be nuts, and checking
+	 * the tail could lead to a segfault then.
+	 */
+	for (i = SST; i >= 1; --i) {
+		if (*(q-i) != FORBIDDENBYTE) {
+			msg = "bad leading pad byte";
+			goto error;
+		}
+	}
+
+	nbytes = read_size_t(q - 2*SST);
+	tail = q + nbytes;
+	for (i = 0; i < SST; ++i) {
+		if (tail[i] != FORBIDDENBYTE) {
+			msg = "bad trailing pad byte";
+			goto error;
+		}
+	}
+
+	return;
+
+error:
+	_PyObject_DebugDumpAddress(p);
+	Py_FatalError(msg);
+}
+
+/* Display info to stderr about the memory block at p. */
+void
+_PyObject_DebugDumpAddress(const void *p)
+{
+	const uchar *q = (const uchar *)p;
+	const uchar *tail;
+	size_t nbytes, serial;
+	int i;
+	int ok;
+
+	fprintf(stderr, "Debug memory block at address p=%p:\n", p);
+	if (p == NULL)
+		return;
+
+	nbytes = read_size_t(q - 2*SST);
+	fprintf(stderr, "    %" PY_FORMAT_SIZE_T "u bytes originally "
+	                "requested\n", nbytes);
+
+	/* In case this is nuts, check the leading pad bytes first. */
+	fprintf(stderr, "    The %d pad bytes at p-%d are ", SST, SST);
+	ok = 1;
+	for (i = 1; i <= SST; ++i) {
+		if (*(q-i) != FORBIDDENBYTE) {
+			ok = 0;
+			break;
+		}
+	}
+	if (ok)
+		fputs("FORBIDDENBYTE, as expected.\n", stderr);
+	else {
+		fprintf(stderr, "not all FORBIDDENBYTE (0x%02x):\n",
+			FORBIDDENBYTE);
+		for (i = SST; i >= 1; --i) {
+			const uchar byte = *(q-i);
+			fprintf(stderr, "        at p-%d: 0x%02x", i, byte);
+			if (byte != FORBIDDENBYTE)
+				fputs(" *** OUCH", stderr);
+			fputc('\n', stderr);
+		}
+
+		fputs("    Because memory is corrupted at the start, the "
+		      "count of bytes requested\n"
+		      "       may be bogus, and checking the trailing pad "
+		      "bytes may segfault.\n", stderr);
+	}
+
+	tail = q + nbytes;
+	fprintf(stderr, "    The %d pad bytes at tail=%p are ", SST, tail);
+	ok = 1;
+	for (i = 0; i < SST; ++i) {
+		if (tail[i] != FORBIDDENBYTE) {
+			ok = 0;
+			break;
+		}
+	}
+	if (ok)
+		fputs("FORBIDDENBYTE, as expected.\n", stderr);
+	else {
+		fprintf(stderr, "not all FORBIDDENBYTE (0x%02x):\n",
+			FORBIDDENBYTE);
+		for (i = 0; i < SST; ++i) {
+			const uchar byte = tail[i];
+			fprintf(stderr, "        at tail+%d: 0x%02x",
+				i, byte);
+			if (byte != FORBIDDENBYTE)
+				fputs(" *** OUCH", stderr);
+			fputc('\n', stderr);
+		}
+	}
+
+	serial = read_size_t(tail + SST);
+	fprintf(stderr, "    The block was made by call #%" PY_FORMAT_SIZE_T
+			"u to debug malloc/realloc.\n", serial);
+
+	if (nbytes > 0) {
+		i = 0;
+		fputs("    Data at p:", stderr);
+		/* print up to 8 bytes at the start */
+		while (q < tail && i < 8) {
+			fprintf(stderr, " %02x", *q);
+			++i;
+			++q;
+		}
+		/* and up to 8 at the end */
+		if (q < tail) {
+			if (tail - q > 8) {
+				fputs(" ...", stderr);
+				q = tail - 8;
+			}
+			while (q < tail) {
+				fprintf(stderr, " %02x", *q);
+				++q;
+			}
+		}
+		fputc('\n', stderr);
+	}
+}
+
+static size_t
+printone(const char* msg, size_t value)
+{
+	int i, k;
+	char buf[100];
+	size_t origvalue = value;
+
+	fputs(msg, stderr);
+	for (i = (int)strlen(msg); i < 35; ++i)
+		fputc(' ', stderr);
+	fputc('=', stderr);
+
+	/* Write the value with commas. */
+	i = 22;
+	buf[i--] = '\0';
+	buf[i--] = '\n';
+	k = 3;
+	do {
+		size_t nextvalue = value / 10;
+		uint digit = (uint)(value - nextvalue * 10);
+		value = nextvalue;
+		buf[i--] = (char)(digit + '0');
+		--k;
+		if (k == 0 && value && i >= 0) {
+			k = 3;
+			buf[i--] = ',';
+		}
+	} while (value && i >= 0);
+
+	while (i >= 0)
+		buf[i--] = ' ';
+	fputs(buf, stderr);
+
+	return origvalue;
+}
+
+/* Print summary info to stderr about the state of pymalloc's structures.
+ * In Py_DEBUG mode, also perform some expensive internal consistency
+ * checks.
+ */
+void
+_PyObject_DebugMallocStats(void)
+{
+	uint i;
+	const uint numclasses = SMALL_REQUEST_THRESHOLD >> ALIGNMENT_SHIFT;
+	/* # of pools, allocated blocks, and free blocks per class index */
+	size_t numpools[SMALL_REQUEST_THRESHOLD >> ALIGNMENT_SHIFT];
+	size_t numblocks[SMALL_REQUEST_THRESHOLD >> ALIGNMENT_SHIFT];
+	size_t numfreeblocks[SMALL_REQUEST_THRESHOLD >> ALIGNMENT_SHIFT];
+	/* total # of allocated bytes in used and full pools */
+	size_t allocated_bytes = 0;
+	/* total # of available bytes in used pools */
+	size_t available_bytes = 0;
+	/* # of free pools + pools not yet carved out of current arena */
+	uint numfreepools = 0;
+	/* # of bytes for arena alignment padding */
+	size_t arena_alignment = 0;
+	/* # of bytes in used and full pools used for pool_headers */
+	size_t pool_header_bytes = 0;
+	/* # of bytes in used and full pools wasted due to quantization,
+	 * i.e. the necessarily leftover space at the ends of used and
+	 * full pools.
+	 */
+	size_t quantization = 0;
+	/* # of arenas actually allocated. */
+	size_t narenas = 0;
+	/* running total -- should equal narenas * ARENA_SIZE */
+	size_t total;
+	char buf[128];
+
+	fprintf(stderr, "Small block threshold = %d, in %u size classes.\n",
+		SMALL_REQUEST_THRESHOLD, numclasses);
+
+	for (i = 0; i < numclasses; ++i)
+		numpools[i] = numblocks[i] = numfreeblocks[i] = 0;
+
+	/* Because full pools aren't linked to from anything, it's easiest
+	 * to march over all the arenas.  If we're lucky, most of the memory
+	 * will be living in full pools -- would be a shame to miss them.
+	 */
+	for (i = 0; i < maxarenas; ++i) {
+		uint poolsinarena;
+		uint j;
+		uptr base = arenas[i].address;
+
+		/* Skip arenas which are not allocated. */
+		if (arenas[i].address == (uptr)NULL)
+			continue;
+		narenas += 1;
+
+		poolsinarena = arenas[i].ntotalpools;
+		numfreepools += arenas[i].nfreepools;
+
+		/* round up to pool alignment */
+		if (base & (uptr)POOL_SIZE_MASK) {
+			arena_alignment += POOL_SIZE;
+			base &= ~(uptr)POOL_SIZE_MASK;
+			base += POOL_SIZE;
+		}
+
+		/* visit every pool in the arena */
+		assert(base <= (uptr) arenas[i].pool_address);
+		for (j = 0;
+			    base < (uptr) arenas[i].pool_address;
+			    ++j, base += POOL_SIZE) {
+			poolp p = (poolp)base;
+			const uint sz = p->szidx;
+			uint freeblocks;
+
+			if (p->ref.count == 0) {
+				/* currently unused */
+				assert(pool_is_in_list(p, arenas[i].freepools));
+				continue;
+			}
+			++numpools[sz];
+			numblocks[sz] += p->ref.count;
+			freeblocks = NUMBLOCKS(sz) - p->ref.count;
+			numfreeblocks[sz] += freeblocks;
+#ifdef Py_DEBUG
+			if (freeblocks > 0)
+				assert(pool_is_in_list(p, usedpools[sz + sz]));
+#endif
+		}
+	}
+	assert(narenas == narenas_currently_allocated);
+
+	fputc('\n', stderr);
+	fputs("class   size   num pools   blocks in use  avail blocks\n"
+	      "-----   ----   ---------   -------------  ------------\n",
+		stderr);
+
+	for (i = 0; i < numclasses; ++i) {
+		size_t p = numpools[i];
+		size_t b = numblocks[i];
+		size_t f = numfreeblocks[i];
+		uint size = INDEX2SIZE(i);
+		if (p == 0) {
+			assert(b == 0 && f == 0);
+			continue;
+		}
+		fprintf(stderr, "%5u %6u "
+				"%11" PY_FORMAT_SIZE_T "u "
+				"%15" PY_FORMAT_SIZE_T "u "
+				"%13" PY_FORMAT_SIZE_T "u\n",
+			i, size, p, b, f);
+		allocated_bytes += b * size;
+		available_bytes += f * size;
+		pool_header_bytes += p * POOL_OVERHEAD;
+		quantization += p * ((POOL_SIZE - POOL_OVERHEAD) % size);
+	}
+	fputc('\n', stderr);
+	(void)printone("# times object malloc called", serialno);
+
+	(void)printone("# arenas allocated total", ntimes_arena_allocated);
+	(void)printone("# arenas reclaimed", ntimes_arena_allocated - narenas);
+	(void)printone("# arenas highwater mark", narenas_highwater);
+	(void)printone("# arenas allocated current", narenas);
+
+	PyOS_snprintf(buf, sizeof(buf),
+		"%" PY_FORMAT_SIZE_T "u arenas * %d bytes/arena",
+		narenas, ARENA_SIZE);
+	(void)printone(buf, narenas * ARENA_SIZE);
+
+	fputc('\n', stderr);
+
+	total = printone("# bytes in allocated blocks", allocated_bytes);
+	total += printone("# bytes in available blocks", available_bytes);
+
+	PyOS_snprintf(buf, sizeof(buf),
+		"%u unused pools * %d bytes", numfreepools, POOL_SIZE);
+	total += printone(buf, (size_t)numfreepools * POOL_SIZE);
+
+	total += printone("# bytes lost to pool headers", pool_header_bytes);
+	total += printone("# bytes lost to quantization", quantization);
+	total += printone("# bytes lost to arena alignment", arena_alignment);
+	(void)printone("Total", total);
+}
+
+#endif	/* PYMALLOC_DEBUG */
+
+#ifdef Py_USING_MEMORY_DEBUGGER
+/* Make this function last so gcc won't inline it since the definition is
+ * after the reference.
+ */
+int
+Py_ADDRESS_IN_RANGE(void *P, poolp pool)
+{
+	return pool->arenaindex < maxarenas &&
+	       (uptr)P - arenas[pool->arenaindex].address < (uptr)ARENA_SIZE &&
+	       arenas[pool->arenaindex].address != 0;
+}
+#endif

Added: vendor/Python/current/Objects/rangeobject.c
===================================================================
--- vendor/Python/current/Objects/rangeobject.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Objects/rangeobject.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,301 @@
+/* Range object implementation */
+
+#include "Python.h"
+
+typedef struct {
+	PyObject_HEAD
+	long	start;
+	long	step;
+	long	len;
+} rangeobject;
+
+/* Return number of items in range/xrange (lo, hi, step).  step > 0
+ * required.  Return a value < 0 if & only if the true value is too
+ * large to fit in a signed long.
+ */
+static long
+get_len_of_range(long lo, long hi, long step)
+{
+	/* -------------------------------------------------------------
+	If lo >= hi, the range is empty.
+	Else if n values are in the range, the last one is
+	lo + (n-1)*step, which must be <= hi-1.  Rearranging,
+	n <= (hi - lo - 1)/step + 1, so taking the floor of the RHS gives
+	the proper value.  Since lo < hi in this case, hi-lo-1 >= 0, so
+	the RHS is non-negative and so truncation is the same as the
+	floor.  Letting M be the largest positive long, the worst case
+	for the RHS numerator is hi=M, lo=-M-1, and then
+	hi-lo-1 = M-(-M-1)-1 = 2*M.  Therefore unsigned long has enough
+	precision to compute the RHS exactly.
+	---------------------------------------------------------------*/
+	long n = 0;
+	if (lo < hi) {
+		unsigned long uhi = (unsigned long)hi;
+		unsigned long ulo = (unsigned long)lo;
+		unsigned long diff = uhi - ulo - 1;
+		n = (long)(diff / (unsigned long)step + 1);
+	}
+	return n;
+}
+
+static PyObject *
+range_new(PyTypeObject *type, PyObject *args, PyObject *kw)
+{
+	rangeobject *obj;
+	long ilow = 0, ihigh = 0, istep = 1;
+	long n;
+
+	if (!_PyArg_NoKeywords("xrange()", kw))
+		return NULL;
+
+	if (PyTuple_Size(args) <= 1) {
+		if (!PyArg_ParseTuple(args,
+				"l;xrange() requires 1-3 int arguments",
+				&ihigh))
+			return NULL;
+	}
+	else {
+		if (!PyArg_ParseTuple(args,
+				"ll|l;xrange() requires 1-3 int arguments",
+				&ilow, &ihigh, &istep))
+			return NULL;
+	}
+	if (istep == 0) {
+		PyErr_SetString(PyExc_ValueError, "xrange() arg 3 must not be zero");
+		return NULL;
+	}
+	if (istep > 0)
+		n = get_len_of_range(ilow, ihigh, istep);
+	else
+		n = get_len_of_range(ihigh, ilow, -istep);
+	if (n < 0) {
+		PyErr_SetString(PyExc_OverflowError,
+				"xrange() result has too many items");
+		return NULL;
+	}
+
+	obj = PyObject_New(rangeobject, &PyRange_Type);
+	if (obj == NULL)
+		return NULL;
+	obj->start = ilow;
+	obj->len   = n;
+	obj->step  = istep;
+	return (PyObject *) obj;
+}
+
+PyDoc_STRVAR(range_doc,
+"xrange([start,] stop[, step]) -> xrange object\n\
+\n\
+Like range(), but instead of returning a list, returns an object that\n\
+generates the numbers in the range on demand.  For looping, this is \n\
+slightly faster than range() and more memory efficient.");
+
+static PyObject *
+range_item(rangeobject *r, Py_ssize_t i)
+{
+	if (i < 0 || i >= r->len) {
+		PyErr_SetString(PyExc_IndexError,
+				"xrange object index out of range");
+		return NULL;
+	}
+	return PyInt_FromSsize_t(r->start + (i % r->len) * r->step);
+}
+
+static Py_ssize_t
+range_length(rangeobject *r)
+{
+	return (Py_ssize_t)(r->len);
+}
+
+static PyObject *
+range_repr(rangeobject *r)
+{
+	PyObject *rtn;
+
+	if (r->start == 0 && r->step == 1)
+		rtn = PyString_FromFormat("xrange(%ld)",
+					  r->start + r->len * r->step);
+
+	else if (r->step == 1)
+		rtn = PyString_FromFormat("xrange(%ld, %ld)",
+					  r->start,
+					  r->start + r->len * r->step);
+
+	else
+		rtn = PyString_FromFormat("xrange(%ld, %ld, %ld)",
+					  r->start,
+					  r->start + r->len * r->step,
+					  r->step);
+	return rtn;
+}
+
+static PySequenceMethods range_as_sequence = {
+	(lenfunc)range_length,	/* sq_length */
+	0,			/* sq_concat */
+	0,			/* sq_repeat */
+	(ssizeargfunc)range_item, /* sq_item */
+	0,			/* sq_slice */
+};
+
+static PyObject * range_iter(PyObject *seq);
+static PyObject * range_reverse(PyObject *seq);
+
+PyDoc_STRVAR(reverse_doc,
+"Returns a reverse iterator.");
+
+static PyMethodDef range_methods[] = {
+	{"__reversed__",	(PyCFunction)range_reverse, METH_NOARGS, reverse_doc},
+ 	{NULL,		NULL}		/* sentinel */
+};
+
+PyTypeObject PyRange_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,			/* Number of items for varobject */
+	"xrange",		/* Name of this type */
+	sizeof(rangeobject),	/* Basic object size */
+	0,			/* Item size for varobject */
+	(destructor)PyObject_Del, /* tp_dealloc */
+	0,			/* tp_print */
+	0,			/* tp_getattr */
+	0,			/* tp_setattr */
+	0,			/* tp_compare */
+	(reprfunc)range_repr,	/* tp_repr */
+	0,			/* tp_as_number */
+	&range_as_sequence,	/* tp_as_sequence */
+	0,			/* tp_as_mapping */
+	0,			/* tp_hash */
+	0,			/* tp_call */
+	0,			/* tp_str */
+	PyObject_GenericGetAttr,  /* tp_getattro */
+	0,			/* tp_setattro */
+	0,			/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT,	/* tp_flags */
+	range_doc,		/* tp_doc */
+	0,			/* tp_traverse */
+	0,			/* tp_clear */
+	0,			/* tp_richcompare */
+	0,			/* tp_weaklistoffset */
+	range_iter,		/* tp_iter */
+	0,			/* tp_iternext */
+	range_methods,		/* tp_methods */
+	0,			/* tp_members */
+	0,			/* tp_getset */
+	0,			/* tp_base */
+	0,			/* tp_dict */
+	0,			/* tp_descr_get */
+	0,			/* tp_descr_set */
+	0,			/* tp_dictoffset */
+	0,			/* tp_init */
+	0,			/* tp_alloc */
+	range_new,		/* tp_new */
+};
+
+/*********************** Xrange Iterator **************************/
+
+typedef struct {
+	PyObject_HEAD
+	long	index;
+	long	start;
+	long	step;
+	long	len;
+} rangeiterobject;
+
+static PyObject *
+rangeiter_next(rangeiterobject *r)
+{
+	if (r->index < r->len)
+		return PyInt_FromLong(r->start + (r->index++) * r->step);
+	return NULL;
+}
+
+static PyObject *
+rangeiter_len(rangeiterobject *r)
+{
+	return PyInt_FromLong(r->len - r->index);
+}
+
+PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
+
+static PyMethodDef rangeiter_methods[] = {
+	{"__length_hint__", (PyCFunction)rangeiter_len, METH_NOARGS, length_hint_doc},
+ 	{NULL,		NULL}		/* sentinel */
+};
+
+static PyTypeObject Pyrangeiter_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,                                      /* ob_size */
+	"rangeiterator",                        /* tp_name */
+	sizeof(rangeiterobject),                /* tp_basicsize */
+	0,                                      /* tp_itemsize */
+	/* methods */
+	(destructor)PyObject_Del,		/* tp_dealloc */
+	0,                                      /* tp_print */
+	0,                                      /* tp_getattr */
+	0,                                      /* tp_setattr */
+	0,                                      /* tp_compare */
+	0,                                      /* tp_repr */
+	0,                                      /* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,                                      /* tp_as_mapping */
+	0,                                      /* tp_hash */
+	0,                                      /* tp_call */
+	0,                                      /* tp_str */
+	PyObject_GenericGetAttr,                /* tp_getattro */
+	0,                                      /* tp_setattro */
+	0,                                      /* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT,			/* tp_flags */
+	0,                                      /* tp_doc */
+	0,					/* tp_traverse */
+	0,                                      /* tp_clear */
+	0,                                      /* tp_richcompare */
+	0,                                      /* tp_weaklistoffset */
+	PyObject_SelfIter,			/* tp_iter */
+	(iternextfunc)rangeiter_next,		/* tp_iternext */
+	rangeiter_methods,			/* tp_methods */
+	0,
+};
+
+static PyObject *
+range_iter(PyObject *seq)
+{
+	rangeiterobject *it;
+
+	if (!PyRange_Check(seq)) {
+		PyErr_BadInternalCall();
+		return NULL;
+	}
+	it = PyObject_New(rangeiterobject, &Pyrangeiter_Type);
+	if (it == NULL)
+		return NULL;
+	it->index = 0;
+	it->start = ((rangeobject *)seq)->start;
+	it->step = ((rangeobject *)seq)->step;
+	it->len = ((rangeobject *)seq)->len;
+	return (PyObject *)it;
+}
+
+static PyObject *
+range_reverse(PyObject *seq)
+{
+	rangeiterobject *it;
+	long start, step, len;
+
+	if (!PyRange_Check(seq)) {
+		PyErr_BadInternalCall();
+		return NULL;
+	}
+	it = PyObject_New(rangeiterobject, &Pyrangeiter_Type);
+	if (it == NULL)
+		return NULL;
+
+	start = ((rangeobject *)seq)->start;
+	step = ((rangeobject *)seq)->step;
+	len = ((rangeobject *)seq)->len;
+
+	it->index = 0;
+	it->start = start + (len-1) * step;
+	it->step = -step;
+	it->len = len;
+
+	return (PyObject *)it;
+}

Added: vendor/Python/current/Objects/setobject.c
===================================================================
--- vendor/Python/current/Objects/setobject.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Objects/setobject.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2312 @@
+
+/* set object implementation 
+   Written and maintained by Raymond D. Hettinger <python at rcn.com>
+   Derived from Lib/sets.py and Objects/dictobject.c.
+
+   Copyright (c) 2003-6 Python Software Foundation.
+   All rights reserved.
+*/
+
+#include "Python.h"
+#include "structmember.h"
+
+/* Set a key error with the specified argument, wrapping it in a
+ * tuple automatically so that tuple keys are not unpacked as the
+ * exception arguments. */
+static void
+set_key_error(PyObject *arg)
+{
+	PyObject *tup;
+	tup = PyTuple_Pack(1, arg);
+	if (!tup)
+		return; /* caller will expect error to be set anyway */
+	PyErr_SetObject(PyExc_KeyError, tup);
+	Py_DECREF(tup);
+}
+
+/* This must be >= 1. */
+#define PERTURB_SHIFT 5
+
+/* Object used as dummy key to fill deleted entries */
+static PyObject *dummy = NULL; /* Initialized by first call to make_new_set() */
+
+#ifdef Py_REF_DEBUG
+PyObject *
+_PySet_Dummy(void)
+{
+	return dummy;
+}
+#endif
+
+#define INIT_NONZERO_SET_SLOTS(so) do {				\
+	(so)->table = (so)->smalltable;				\
+	(so)->mask = PySet_MINSIZE - 1;				\
+	(so)->hash = -1;					\
+    } while(0)
+
+#define EMPTY_TO_MINSIZE(so) do {				\
+	memset((so)->smalltable, 0, sizeof((so)->smalltable));	\
+	(so)->used = (so)->fill = 0;				\
+	INIT_NONZERO_SET_SLOTS(so);				\
+    } while(0)
+
+/* Reuse scheme to save calls to malloc, free, and memset */
+#define MAXFREESETS 80
+static PySetObject *free_sets[MAXFREESETS];
+static int num_free_sets = 0;
+
+/*
+The basic lookup function used by all operations.
+This is based on Algorithm D from Knuth Vol. 3, Sec. 6.4.
+Open addressing is preferred over chaining since the link overhead for
+chaining would be substantial (100% with typical malloc overhead).
+
+The initial probe index is computed as hash mod the table size. Subsequent
+probe indices are computed as explained in Objects/dictobject.c.
+
+All arithmetic on hash should ignore overflow.
+
+Unlike the dictionary implementation, the lookkey functions can return
+NULL if the rich comparison returns an error.
+*/
+
+static setentry *
+set_lookkey(PySetObject *so, PyObject *key, register long hash)
+{
+	register Py_ssize_t i;
+	register size_t perturb;
+	register setentry *freeslot;
+	register size_t mask = so->mask;
+	setentry *table = so->table;
+	register setentry *entry;
+	register int cmp;
+	PyObject *startkey;
+
+	i = hash & mask;
+	entry = &table[i];
+	if (entry->key == NULL || entry->key == key)
+		return entry;
+
+	if (entry->key == dummy)
+		freeslot = entry;
+	else {
+		if (entry->hash == hash) {
+			startkey = entry->key;
+			cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
+			if (cmp < 0)
+				return NULL;
+			if (table == so->table && entry->key == startkey) {
+				if (cmp > 0)
+					return entry;
+			}
+			else {
+				/* The compare did major nasty stuff to the
+				 * set:  start over.
+ 				 */
+ 				return set_lookkey(so, key, hash);
+ 			}
+		}
+		freeslot = NULL;
+	}
+
+	/* In the loop, key == dummy is by far (factor of 100s) the
+	   least likely outcome, so test for that last. */
+	for (perturb = hash; ; perturb >>= PERTURB_SHIFT) {
+		i = (i << 2) + i + perturb + 1;
+		entry = &table[i & mask];
+		if (entry->key == NULL) {
+			if (freeslot != NULL)
+				entry = freeslot;
+			break;
+		}
+		if (entry->key == key)
+			break;
+		if (entry->hash == hash && entry->key != dummy) {
+			startkey = entry->key;
+			cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
+			if (cmp < 0)
+				return NULL;
+			if (table == so->table && entry->key == startkey) {
+				if (cmp > 0)
+					break;
+			}
+			else {
+				/* The compare did major nasty stuff to the
+				 * set:  start over.
+ 				 */
+ 				return set_lookkey(so, key, hash);
+ 			}
+		}
+		else if (entry->key == dummy && freeslot == NULL)
+			freeslot = entry;
+	}
+	return entry;
+}
+
+/*
+ * Hacked up version of set_lookkey which can assume keys are always strings;
+ * This means we can always use _PyString_Eq directly and not have to check to
+ * see if the comparison altered the table.
+ */
+static setentry *
+set_lookkey_string(PySetObject *so, PyObject *key, register long hash)
+{
+	register Py_ssize_t i;
+	register size_t perturb;
+	register setentry *freeslot;
+	register size_t mask = so->mask;
+	setentry *table = so->table;
+	register setentry *entry;
+
+	/* Make sure this function doesn't have to handle non-string keys,
+	   including subclasses of str; e.g., one reason to subclass
+	   strings is to override __eq__, and for speed we don't cater to
+	   that here. */
+	if (!PyString_CheckExact(key)) {
+		so->lookup = set_lookkey;
+		return set_lookkey(so, key, hash);
+	}
+	i = hash & mask;
+	entry = &table[i];
+	if (entry->key == NULL || entry->key == key)
+		return entry;
+	if (entry->key == dummy)
+		freeslot = entry;
+	else {
+		if (entry->hash == hash && _PyString_Eq(entry->key, key))
+			return entry;
+		freeslot = NULL;
+	}
+
+	/* In the loop, key == dummy is by far (factor of 100s) the
+	   least likely outcome, so test for that last. */
+	for (perturb = hash; ; perturb >>= PERTURB_SHIFT) {
+		i = (i << 2) + i + perturb + 1;
+		entry = &table[i & mask];
+		if (entry->key == NULL)
+			return freeslot == NULL ? entry : freeslot;
+		if (entry->key == key
+		    || (entry->hash == hash
+			&& entry->key != dummy
+			&& _PyString_Eq(entry->key, key)))
+			return entry;
+		if (entry->key == dummy && freeslot == NULL)
+			freeslot = entry;
+	}
+	assert(0);	/* NOT REACHED */
+	return 0;
+}
+
+/*
+Internal routine to insert a new key into the table.
+Used by the public insert routine.
+Eats a reference to key.
+*/
+static int
+set_insert_key(register PySetObject *so, PyObject *key, long hash)
+{
+	register setentry *entry;
+	typedef setentry *(*lookupfunc)(PySetObject *, PyObject *, long);
+
+	assert(so->lookup != NULL);
+	entry = so->lookup(so, key, hash);
+	if (entry == NULL)
+		return -1;
+	if (entry->key == NULL) {
+		/* UNUSED */
+		so->fill++; 
+		entry->key = key;
+		entry->hash = hash;
+		so->used++;
+	} else if (entry->key == dummy) {
+		/* DUMMY */
+		entry->key = key;
+		entry->hash = hash;
+		so->used++;
+		Py_DECREF(dummy);
+	} else {
+		/* ACTIVE */
+		Py_DECREF(key);
+	}
+	return 0;
+}
+
+/*
+Internal routine used by set_table_resize() to insert an item which is
+known to be absent from the set.  This routine also assumes that
+the set contains no deleted entries.  Besides the performance benefit,
+using set_insert_clean() in set_table_resize() is dangerous (SF bug #1456209).
+Note that no refcounts are changed by this routine; if needed, the caller
+is responsible for incref'ing `key`.
+*/
+static void
+set_insert_clean(register PySetObject *so, PyObject *key, long hash)
+{
+	register size_t i;
+	register size_t perturb;
+	register size_t mask = (size_t)so->mask;
+	setentry *table = so->table;
+	register setentry *entry;
+
+	i = hash & mask;
+	entry = &table[i];
+	for (perturb = hash; entry->key != NULL; perturb >>= PERTURB_SHIFT) {
+		i = (i << 2) + i + perturb + 1;
+		entry = &table[i & mask];
+	}
+	so->fill++;
+	entry->key = key;
+	entry->hash = hash;
+	so->used++;
+}
+
+/*
+Restructure the table by allocating a new table and reinserting all
+keys again.  When entries have been deleted, the new table may
+actually be smaller than the old one.
+*/
+static int
+set_table_resize(PySetObject *so, Py_ssize_t minused)
+{
+	Py_ssize_t newsize;
+	setentry *oldtable, *newtable, *entry;
+	Py_ssize_t i;
+	int is_oldtable_malloced;
+	setentry small_copy[PySet_MINSIZE];
+
+	assert(minused >= 0);
+
+	/* Find the smallest table size > minused. */
+	for (newsize = PySet_MINSIZE;
+	     newsize <= minused && newsize > 0;
+	     newsize <<= 1)
+		;
+	if (newsize <= 0) {
+		PyErr_NoMemory();
+		return -1;
+	}
+
+	/* Get space for a new table. */
+	oldtable = so->table;
+	assert(oldtable != NULL);
+	is_oldtable_malloced = oldtable != so->smalltable;
+
+	if (newsize == PySet_MINSIZE) {
+		/* A large table is shrinking, or we can't get any smaller. */
+		newtable = so->smalltable;
+		if (newtable == oldtable) {
+			if (so->fill == so->used) {
+				/* No dummies, so no point doing anything. */
+				return 0;
+			}
+			/* We're not going to resize it, but rebuild the
+			   table anyway to purge old dummy entries.
+			   Subtle:  This is *necessary* if fill==size,
+			   as set_lookkey needs at least one virgin slot to
+			   terminate failing searches.  If fill < size, it's
+			   merely desirable, as dummies slow searches. */
+			assert(so->fill > so->used);
+			memcpy(small_copy, oldtable, sizeof(small_copy));
+			oldtable = small_copy;
+		}
+	}
+	else {
+		newtable = PyMem_NEW(setentry, newsize);
+		if (newtable == NULL) {
+			PyErr_NoMemory();
+			return -1;
+		}
+	}
+
+	/* Make the set empty, using the new table. */
+	assert(newtable != oldtable);
+	so->table = newtable;
+	so->mask = newsize - 1;
+	memset(newtable, 0, sizeof(setentry) * newsize);
+	so->used = 0;
+	i = so->fill;
+	so->fill = 0;
+
+	/* Copy the data over; this is refcount-neutral for active entries;
+	   dummy entries aren't copied over, of course */
+	for (entry = oldtable; i > 0; entry++) {
+		if (entry->key == NULL) {
+			/* UNUSED */
+			;
+		} else if (entry->key == dummy) {
+			/* DUMMY */
+			--i;
+			assert(entry->key == dummy);
+			Py_DECREF(entry->key);
+		} else {
+			/* ACTIVE */
+			--i;
+			set_insert_clean(so, entry->key, entry->hash);
+		}
+	}
+
+	if (is_oldtable_malloced)
+		PyMem_DEL(oldtable);
+	return 0;
+}
+
+/* CAUTION: set_add_key/entry() must guarantee it won't resize the table */
+
+static int
+set_add_entry(register PySetObject *so, setentry *entry)
+{
+	register Py_ssize_t n_used;
+
+	assert(so->fill <= so->mask);  /* at least one empty slot */
+	n_used = so->used;
+	Py_INCREF(entry->key);
+	if (set_insert_key(so, entry->key, entry->hash) == -1) {
+		Py_DECREF(entry->key);
+		return -1;
+	}
+	if (!(so->used > n_used && so->fill*3 >= (so->mask+1)*2))
+		return 0;
+	return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);
+}
+
+static int
+set_add_key(register PySetObject *so, PyObject *key)
+{
+	register long hash;
+	register Py_ssize_t n_used;
+
+	if (!PyString_CheckExact(key) ||
+	    (hash = ((PyStringObject *) key)->ob_shash) == -1) {
+		hash = PyObject_Hash(key);
+		if (hash == -1)
+			return -1;
+	}
+	assert(so->fill <= so->mask);  /* at least one empty slot */
+	n_used = so->used;
+	Py_INCREF(key);
+	if (set_insert_key(so, key, hash) == -1) {
+		Py_DECREF(key);
+		return -1;
+	}
+	if (!(so->used > n_used && so->fill*3 >= (so->mask+1)*2))
+		return 0;
+	return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);
+}
+
+#define DISCARD_NOTFOUND 0
+#define DISCARD_FOUND 1
+
+static int
+set_discard_entry(PySetObject *so, setentry *oldentry)
+{	register setentry *entry;
+	PyObject *old_key;
+
+	entry = (so->lookup)(so, oldentry->key, oldentry->hash);
+	if (entry == NULL)
+		return -1;
+	if (entry->key == NULL  ||  entry->key == dummy)
+		return DISCARD_NOTFOUND;
+	old_key = entry->key;
+	Py_INCREF(dummy);
+	entry->key = dummy;
+	so->used--;
+	Py_DECREF(old_key);
+	return DISCARD_FOUND;
+}
+
+static int
+set_discard_key(PySetObject *so, PyObject *key)
+{
+	register long hash;
+	register setentry *entry;
+	PyObject *old_key;
+
+	assert (PyAnySet_Check(so));
+	if (!PyString_CheckExact(key) ||
+	    (hash = ((PyStringObject *) key)->ob_shash) == -1) {
+		hash = PyObject_Hash(key);
+		if (hash == -1)
+			return -1;
+	}
+	entry = (so->lookup)(so, key, hash);
+	if (entry == NULL)
+		return -1;
+	if (entry->key == NULL  ||  entry->key == dummy)
+		return DISCARD_NOTFOUND;
+	old_key = entry->key;
+	Py_INCREF(dummy);
+	entry->key = dummy;
+	so->used--;
+	Py_DECREF(old_key);
+	return DISCARD_FOUND;
+}
+
+static int
+set_clear_internal(PySetObject *so)
+{
+	setentry *entry, *table;
+	int table_is_malloced;
+	Py_ssize_t fill;
+	setentry small_copy[PySet_MINSIZE];
+#ifdef Py_DEBUG
+	Py_ssize_t i, n;
+	assert (PyAnySet_Check(so));
+
+	n = so->mask + 1;
+	i = 0;
+#endif
+
+	table = so->table;
+	assert(table != NULL);
+	table_is_malloced = table != so->smalltable;
+
+	/* This is delicate.  During the process of clearing the set,
+	 * decrefs can cause the set to mutate.  To avoid fatal confusion
+	 * (voice of experience), we have to make the set empty before
+	 * clearing the slots, and never refer to anything via so->ref while
+	 * clearing.
+	 */
+	fill = so->fill;
+	if (table_is_malloced)
+		EMPTY_TO_MINSIZE(so);
+
+	else if (fill > 0) {
+		/* It's a small table with something that needs to be cleared.
+		 * Afraid the only safe way is to copy the set entries into
+		 * another small table first.
+		 */
+		memcpy(small_copy, table, sizeof(small_copy));
+		table = small_copy;
+		EMPTY_TO_MINSIZE(so);
+	}
+	/* else it's a small table that's already empty */
+
+	/* Now we can finally clear things.  If C had refcounts, we could
+	 * assert that the refcount on table is 1 now, i.e. that this function
+	 * has unique access to it, so decref side-effects can't alter it.
+	 */
+	for (entry = table; fill > 0; ++entry) {
+#ifdef Py_DEBUG
+		assert(i < n);
+		++i;
+#endif
+		if (entry->key) {
+			--fill;
+			Py_DECREF(entry->key);
+		}
+#ifdef Py_DEBUG
+		else
+			assert(entry->key == NULL);
+#endif
+	}
+
+	if (table_is_malloced)
+		PyMem_DEL(table);
+	return 0;
+}
+
+/*
+ * Iterate over a set table.  Use like so:
+ *
+ *     Py_ssize_t pos;
+ *     setentry *entry;
+ *     pos = 0;   # important!  pos should not otherwise be changed by you
+ *     while (set_next(yourset, &pos, &entry)) {
+ *              Refer to borrowed reference in entry->key.
+ *     }
+ *
+ * CAUTION:  In general, it isn't safe to use set_next in a loop that
+ * mutates the table.  
+ */
+static int
+set_next(PySetObject *so, Py_ssize_t *pos_ptr, setentry **entry_ptr)
+{
+	Py_ssize_t i;
+	Py_ssize_t mask;
+	register setentry *table;
+
+	assert (PyAnySet_Check(so));
+	i = *pos_ptr;
+	assert(i >= 0);
+	table = so->table;
+	mask = so->mask;
+	while (i <= mask && (table[i].key == NULL || table[i].key == dummy))
+		i++;
+	*pos_ptr = i+1;
+	if (i > mask)
+		return 0;
+	assert(table[i].key != NULL);
+	*entry_ptr = &table[i];
+	return 1;
+}
+
+static void
+set_dealloc(PySetObject *so)
+{
+	register setentry *entry;
+	Py_ssize_t fill = so->fill;
+	PyObject_GC_UnTrack(so);
+	Py_TRASHCAN_SAFE_BEGIN(so)
+	if (so->weakreflist != NULL)
+		PyObject_ClearWeakRefs((PyObject *) so);
+
+	for (entry = so->table; fill > 0; entry++) {
+		if (entry->key) {
+			--fill;
+			Py_DECREF(entry->key);
+		}
+	}
+	if (so->table != so->smalltable)
+		PyMem_DEL(so->table);
+	if (num_free_sets < MAXFREESETS && PyAnySet_CheckExact(so))
+		free_sets[num_free_sets++] = so;
+	else 
+		so->ob_type->tp_free(so);
+	Py_TRASHCAN_SAFE_END(so)
+}
+
+static int
+set_tp_print(PySetObject *so, FILE *fp, int flags)
+{
+	setentry *entry;
+	Py_ssize_t pos=0;
+	char *emit = "";	/* No separator emitted on first pass */
+	char *separator = ", ";
+	int status = Py_ReprEnter((PyObject*)so);
+
+	if (status != 0) {
+		if (status < 0)
+			return status;
+		fprintf(fp, "%s(...)", so->ob_type->tp_name);
+		return 0;
+	}        
+
+	fprintf(fp, "%s([", so->ob_type->tp_name);
+	while (set_next(so, &pos, &entry)) {
+		fputs(emit, fp);
+		emit = separator;
+		if (PyObject_Print(entry->key, fp, 0) != 0) {
+			Py_ReprLeave((PyObject*)so);
+			return -1;
+		}
+	}
+	fputs("])", fp);
+	Py_ReprLeave((PyObject*)so);        
+	return 0;
+}
+
+static PyObject *
+set_repr(PySetObject *so)
+{
+	PyObject *keys, *result=NULL, *listrepr;
+	int status = Py_ReprEnter((PyObject*)so);
+
+	if (status != 0) {
+		if (status < 0)
+			return NULL;
+		return PyString_FromFormat("%s(...)", so->ob_type->tp_name);
+	}
+
+	keys = PySequence_List((PyObject *)so);
+	if (keys == NULL)
+		goto done;
+	listrepr = PyObject_Repr(keys);
+	Py_DECREF(keys);
+	if (listrepr == NULL)
+		goto done;
+
+	result = PyString_FromFormat("%s(%s)", so->ob_type->tp_name,
+		PyString_AS_STRING(listrepr));
+	Py_DECREF(listrepr);
+done:
+	Py_ReprLeave((PyObject*)so);
+	return result;
+}
+
+static Py_ssize_t
+set_len(PyObject *so)
+{
+	return ((PySetObject *)so)->used;
+}
+
+static int
+set_merge(PySetObject *so, PyObject *otherset)
+{
+	PySetObject *other;
+	register Py_ssize_t i;
+	register setentry *entry;
+
+	assert (PyAnySet_Check(so));
+	assert (PyAnySet_Check(otherset));
+
+	other = (PySetObject*)otherset;
+	if (other == so || other->used == 0)
+		/* a.update(a) or a.update({}); nothing to do */
+		return 0;
+	/* Do one big resize at the start, rather than
+	 * incrementally resizing as we insert new keys.  Expect
+	 * that there will be no (or few) overlapping keys.
+	 */
+	if ((so->fill + other->used)*3 >= (so->mask+1)*2) {
+	   if (set_table_resize(so, (so->used + other->used)*2) != 0)
+		   return -1;
+	}
+	for (i = 0; i <= other->mask; i++) {
+		entry = &other->table[i];
+		if (entry->key != NULL && 
+		    entry->key != dummy) {
+			Py_INCREF(entry->key);
+			if (set_insert_key(so, entry->key, entry->hash) == -1) {
+				Py_DECREF(entry->key);
+				return -1;
+			}
+		}
+	}
+	return 0;
+}
+
+static int
+set_contains_key(PySetObject *so, PyObject *key)
+{
+	long hash;
+	setentry *entry;
+
+	if (!PyString_CheckExact(key) ||
+	    (hash = ((PyStringObject *) key)->ob_shash) == -1) {
+		hash = PyObject_Hash(key);
+		if (hash == -1)
+			return -1;
+	}
+	entry = (so->lookup)(so, key, hash);
+	if (entry == NULL)
+		return -1;
+	key = entry->key;
+	return key != NULL && key != dummy;
+}
+
+static int
+set_contains_entry(PySetObject *so, setentry *entry)
+{
+	PyObject *key;
+	setentry *lu_entry;
+
+	lu_entry = (so->lookup)(so, entry->key, entry->hash);
+	if (lu_entry == NULL)
+		return -1;
+	key = lu_entry->key; 
+	return key != NULL && key != dummy;
+}
+
+static PyObject *
+set_pop(PySetObject *so)
+{
+	register Py_ssize_t i = 0;
+	register setentry *entry;
+	PyObject *key;
+
+	assert (PyAnySet_Check(so));
+	if (so->used == 0) {
+		PyErr_SetString(PyExc_KeyError, "pop from an empty set");
+		return NULL;
+	}
+
+	/* Set entry to "the first" unused or dummy set entry.  We abuse
+	 * the hash field of slot 0 to hold a search finger:
+	 * If slot 0 has a value, use slot 0.
+	 * Else slot 0 is being used to hold a search finger,
+	 * and we use its hash value as the first index to look.
+	 */
+	entry = &so->table[0];
+	if (entry->key == NULL || entry->key == dummy) {
+		i = entry->hash;
+		/* The hash field may be a real hash value, or it may be a
+		 * legit search finger, or it may be a once-legit search
+		 * finger that's out of bounds now because it wrapped around
+		 * or the table shrunk -- simply make sure it's in bounds now.
+		 */
+		if (i > so->mask || i < 1)
+			i = 1;	/* skip slot 0 */
+		while ((entry = &so->table[i])->key == NULL || entry->key==dummy) {
+			i++;
+			if (i > so->mask)
+				i = 1;
+		}
+	}
+	key = entry->key;
+	Py_INCREF(dummy);
+	entry->key = dummy;
+	so->used--;
+	so->table[0].hash = i + 1;  /* next place to start */
+	return key;
+}
+
+PyDoc_STRVAR(pop_doc, "Remove and return an arbitrary set element.");
+
+static int
+set_traverse(PySetObject *so, visitproc visit, void *arg)
+{
+	Py_ssize_t pos = 0;
+	setentry *entry;
+
+	while (set_next(so, &pos, &entry))
+		Py_VISIT(entry->key);
+	return 0;
+}
+
+static long
+frozenset_hash(PyObject *self)
+{
+	PySetObject *so = (PySetObject *)self;
+	long h, hash = 1927868237L;
+	setentry *entry;
+	Py_ssize_t pos = 0;
+
+	if (so->hash != -1)
+		return so->hash;
+
+	hash *= PySet_GET_SIZE(self) + 1;
+	while (set_next(so, &pos, &entry)) {
+		/* Work to increase the bit dispersion for closely spaced hash
+		   values.  The is important because some use cases have many 
+		   combinations of a small number of elements with nearby 
+		   hashes so that many distinct combinations collapse to only 
+		   a handful of distinct hash values. */
+		h = entry->hash;
+		hash ^= (h ^ (h << 16) ^ 89869747L)  * 3644798167u;
+	}
+	hash = hash * 69069L + 907133923L;
+	if (hash == -1)
+		hash = 590923713L;
+	so->hash = hash;
+	return hash;
+}
+
+static long
+set_nohash(PyObject *self)
+{
+	PyErr_SetString(PyExc_TypeError, "set objects are unhashable");
+	return -1;
+}
+
+/***** Set iterator type ***********************************************/
+
+typedef struct {
+	PyObject_HEAD
+	PySetObject *si_set; /* Set to NULL when iterator is exhausted */
+	Py_ssize_t si_used;
+	Py_ssize_t si_pos;
+	Py_ssize_t len;
+} setiterobject;
+
+static void
+setiter_dealloc(setiterobject *si)
+{
+	Py_XDECREF(si->si_set);
+	PyObject_Del(si);
+}
+
+static PyObject *
+setiter_len(setiterobject *si)
+{
+	Py_ssize_t len = 0;
+	if (si->si_set != NULL && si->si_used == si->si_set->used)
+		len = si->len;
+	return PyInt_FromLong(len);
+}
+
+PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
+
+static PyMethodDef setiter_methods[] = {
+	{"__length_hint__", (PyCFunction)setiter_len, METH_NOARGS, length_hint_doc},
+ 	{NULL,		NULL}		/* sentinel */
+};
+
+static PyObject *setiter_iternext(setiterobject *si)
+{
+	PyObject *key;
+	register Py_ssize_t i, mask;
+	register setentry *entry;
+	PySetObject *so = si->si_set;
+
+	if (so == NULL)
+		return NULL;
+	assert (PyAnySet_Check(so));
+
+	if (si->si_used != so->used) {
+		PyErr_SetString(PyExc_RuntimeError,
+				"Set changed size during iteration");
+		si->si_used = -1; /* Make this state sticky */
+		return NULL;
+	}
+
+	i = si->si_pos;
+	assert(i>=0);
+	entry = so->table;
+	mask = so->mask;
+	while (i <= mask && (entry[i].key == NULL || entry[i].key == dummy))
+		i++;
+	si->si_pos = i+1;
+	if (i > mask)
+		goto fail;
+	si->len--;
+	key = entry[i].key;
+	Py_INCREF(key);
+	return key;
+
+fail:
+	Py_DECREF(so);
+	si->si_set = NULL;
+	return NULL;
+}
+
+static PyTypeObject PySetIter_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,					/* ob_size */
+	"setiterator",				/* tp_name */
+	sizeof(setiterobject),			/* tp_basicsize */
+	0,					/* tp_itemsize */
+	/* methods */
+	(destructor)setiter_dealloc, 		/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	0,					/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT,			/* tp_flags */
+ 	0,					/* tp_doc */
+ 	0,					/* tp_traverse */
+ 	0,					/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	PyObject_SelfIter,			/* tp_iter */
+	(iternextfunc)setiter_iternext,		/* tp_iternext */
+	setiter_methods,			/* tp_methods */
+	0,
+};
+
+static PyObject *
+set_iter(PySetObject *so)
+{
+	setiterobject *si = PyObject_New(setiterobject, &PySetIter_Type);
+	if (si == NULL)
+		return NULL;
+	Py_INCREF(so);
+	si->si_set = so;
+	si->si_used = so->used;
+	si->si_pos = 0;
+	si->len = so->used;
+	return (PyObject *)si;
+}
+
+static int
+set_update_internal(PySetObject *so, PyObject *other)
+{
+	PyObject *key, *it;
+
+	if (PyAnySet_Check(other))
+		return set_merge(so, other);
+
+	if (PyDict_CheckExact(other)) {
+		PyObject *value;
+		Py_ssize_t pos = 0;
+		long hash;
+		Py_ssize_t dictsize = PyDict_Size(other);
+
+		/* Do one big resize at the start, rather than
+		* incrementally resizing as we insert new keys.  Expect
+		* that there will be no (or few) overlapping keys.
+		*/
+		if (dictsize == -1)
+			return -1;
+		if ((so->fill + dictsize)*3 >= (so->mask+1)*2) {
+			if (set_table_resize(so, (so->used + dictsize)*2) != 0)
+				return -1;
+		}
+		while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
+			setentry an_entry;
+
+			an_entry.hash = hash;
+			an_entry.key = key;
+			if (set_add_entry(so, &an_entry) == -1)
+				return -1;
+		}
+		return 0;
+	}
+
+	it = PyObject_GetIter(other);
+	if (it == NULL)
+		return -1;
+
+	while ((key = PyIter_Next(it)) != NULL) {
+                if (set_add_key(so, key) == -1) {
+			Py_DECREF(it);
+			Py_DECREF(key);
+			return -1;
+                } 
+		Py_DECREF(key);
+	}
+	Py_DECREF(it);
+	if (PyErr_Occurred())
+		return -1;
+	return 0;
+}
+
+static PyObject *
+set_update(PySetObject *so, PyObject *other)
+{
+	if (set_update_internal(so, other) == -1)
+		return NULL;
+	Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(update_doc, 
+"Update a set with the union of itself and another.");
+
+static PyObject *
+make_new_set(PyTypeObject *type, PyObject *iterable)
+{
+	register PySetObject *so = NULL;
+
+	if (dummy == NULL) { /* Auto-initialize dummy */
+		dummy = PyString_FromString("<dummy key>");
+		if (dummy == NULL)
+			return NULL;
+	}
+
+	/* create PySetObject structure */
+	if (num_free_sets && 
+	    (type == &PySet_Type  ||  type == &PyFrozenSet_Type)) {
+		so = free_sets[--num_free_sets];
+		assert (so != NULL && PyAnySet_CheckExact(so));
+		so->ob_type = type;
+		_Py_NewReference((PyObject *)so);
+		EMPTY_TO_MINSIZE(so);
+		PyObject_GC_Track(so);
+	} else {
+		so = (PySetObject *)type->tp_alloc(type, 0);
+		if (so == NULL)
+			return NULL;
+		/* tp_alloc has already zeroed the structure */
+		assert(so->table == NULL && so->fill == 0 && so->used == 0);
+		INIT_NONZERO_SET_SLOTS(so);
+	}
+
+	so->lookup = set_lookkey_string;
+	so->weakreflist = NULL;
+
+	if (iterable != NULL) {
+		if (set_update_internal(so, iterable) == -1) {
+			Py_DECREF(so);
+			return NULL;
+		}
+	}
+
+	return (PyObject *)so;
+}
+
+/* The empty frozenset is a singleton */
+static PyObject *emptyfrozenset = NULL;
+
+static PyObject *
+frozenset_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	PyObject *iterable = NULL, *result;
+
+	if (type == &PyFrozenSet_Type && !_PyArg_NoKeywords("frozenset()", kwds))
+		return NULL;
+
+	if (!PyArg_UnpackTuple(args, type->tp_name, 0, 1, &iterable))
+		return NULL;
+
+	if (type != &PyFrozenSet_Type)
+		return make_new_set(type, iterable);
+
+	if (iterable != NULL) {
+		/* frozenset(f) is idempotent */
+		if (PyFrozenSet_CheckExact(iterable)) {
+			Py_INCREF(iterable);
+			return iterable;
+		}
+		result = make_new_set(type, iterable);
+		if (result == NULL || PySet_GET_SIZE(result))
+			return result;
+		Py_DECREF(result);
+	}
+	/* The empty frozenset is a singleton */
+	if (emptyfrozenset == NULL)
+		emptyfrozenset = make_new_set(type, NULL);
+	Py_XINCREF(emptyfrozenset);
+	return emptyfrozenset;
+}
+
+void
+PySet_Fini(void)
+{
+	PySetObject *so;
+
+	while (num_free_sets) {
+		num_free_sets--;
+		so = free_sets[num_free_sets];
+		PyObject_GC_Del(so);
+	}
+	Py_CLEAR(dummy);
+	Py_CLEAR(emptyfrozenset);
+}
+
+static PyObject *
+set_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	if (type == &PySet_Type && !_PyArg_NoKeywords("set()", kwds))
+		return NULL;
+	
+	return make_new_set(type, NULL);
+}
+
+/* set_swap_bodies() switches the contents of any two sets by moving their
+   internal data pointers and, if needed, copying the internal smalltables.
+   Semantically equivalent to:
+
+     t=set(a); a.clear(); a.update(b); b.clear(); b.update(t); del t
+
+   The function always succeeds and it leaves both objects in a stable state.
+   Useful for creating temporary frozensets from sets for membership testing 
+   in __contains__(), discard(), and remove().  Also useful for operations
+   that update in-place (by allowing an intermediate result to be swapped 
+   into one of the original inputs).
+*/
+
+static void
+set_swap_bodies(PySetObject *a, PySetObject *b)
+{
+	Py_ssize_t t;
+	setentry *u;
+	setentry *(*f)(PySetObject *so, PyObject *key, long hash);
+	setentry tab[PySet_MINSIZE];
+	long h;
+
+	t = a->fill;     a->fill   = b->fill;        b->fill  = t;
+	t = a->used;     a->used   = b->used;        b->used  = t;
+	t = a->mask;     a->mask   = b->mask;        b->mask  = t;
+
+	u = a->table;
+	if (a->table == a->smalltable)
+		u = b->smalltable;
+	a->table  = b->table;
+	if (b->table == b->smalltable)
+		a->table = a->smalltable;
+	b->table = u;
+
+	f = a->lookup;   a->lookup = b->lookup;      b->lookup = f;
+
+	if (a->table == a->smalltable || b->table == b->smalltable) {
+		memcpy(tab, a->smalltable, sizeof(tab));
+		memcpy(a->smalltable, b->smalltable, sizeof(tab));
+		memcpy(b->smalltable, tab, sizeof(tab));
+	}
+
+	if (PyType_IsSubtype(a->ob_type, &PyFrozenSet_Type)  &&
+	    PyType_IsSubtype(b->ob_type, &PyFrozenSet_Type)) {
+		h = a->hash;     a->hash = b->hash;  b->hash = h;
+	} else {
+		a->hash = -1;
+		b->hash = -1;
+	}
+}
+
+static PyObject *
+set_copy(PySetObject *so)
+{
+	return make_new_set(so->ob_type, (PyObject *)so);
+}
+
+static PyObject *
+frozenset_copy(PySetObject *so)
+{
+	if (PyFrozenSet_CheckExact(so)) {
+		Py_INCREF(so);
+		return (PyObject *)so;
+	}
+	return set_copy(so);
+}
+
+PyDoc_STRVAR(copy_doc, "Return a shallow copy of a set.");
+
+static PyObject *
+set_clear(PySetObject *so)
+{
+	set_clear_internal(so);
+	Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(clear_doc, "Remove all elements from this set.");
+
+static PyObject *
+set_union(PySetObject *so, PyObject *other)
+{
+	PySetObject *result;
+
+	result = (PySetObject *)set_copy(so);
+	if (result == NULL)
+		return NULL;
+	if ((PyObject *)so == other)
+		return (PyObject *)result;
+	if (set_update_internal(result, other) == -1) {
+		Py_DECREF(result);
+		return NULL;
+	}
+	return (PyObject *)result;
+}
+
+PyDoc_STRVAR(union_doc,
+ "Return the union of two sets as a new set.\n\
+\n\
+(i.e. all elements that are in either set.)");
+
+static PyObject *
+set_or(PySetObject *so, PyObject *other)
+{
+	if (!PyAnySet_Check(so) || !PyAnySet_Check(other)) {
+		Py_INCREF(Py_NotImplemented);
+		return Py_NotImplemented;
+	}
+	return set_union(so, other);
+}
+
+static PyObject *
+set_ior(PySetObject *so, PyObject *other)
+{
+	if (!PyAnySet_Check(other)) {
+		Py_INCREF(Py_NotImplemented);
+		return Py_NotImplemented;
+	}
+	if (set_update_internal(so, other) == -1)
+		return NULL;
+	Py_INCREF(so);
+	return (PyObject *)so;
+}
+
+static PyObject *
+set_intersection(PySetObject *so, PyObject *other)
+{
+	PySetObject *result;
+	PyObject *key, *it, *tmp;
+
+	if ((PyObject *)so == other)
+		return set_copy(so);
+
+	result = (PySetObject *)make_new_set(so->ob_type, NULL);
+	if (result == NULL)
+		return NULL;
+
+	if (PyAnySet_Check(other)) {		
+		Py_ssize_t pos = 0;
+		setentry *entry;
+
+		if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
+			tmp = (PyObject *)so;
+			so = (PySetObject *)other;
+			other = tmp;
+		}
+
+		while (set_next((PySetObject *)other, &pos, &entry)) {
+			int rv = set_contains_entry(so, entry);
+			if (rv == -1) {
+				Py_DECREF(result);
+				return NULL;
+			}
+			if (rv) {
+				if (set_add_entry(result, entry) == -1) {
+					Py_DECREF(result);
+					return NULL;
+				}
+			}
+		}
+		return (PyObject *)result;
+	}
+
+	it = PyObject_GetIter(other);
+	if (it == NULL) {
+		Py_DECREF(result);
+		return NULL;
+	}
+
+	while ((key = PyIter_Next(it)) != NULL) {
+		int rv;
+		setentry entry;
+		long hash = PyObject_Hash(key);
+
+		if (hash == -1) {
+			Py_DECREF(it);
+			Py_DECREF(result);
+			Py_DECREF(key);
+			return NULL;
+		}
+		entry.hash = hash;
+		entry.key = key;
+		rv = set_contains_entry(so, &entry);
+		if (rv == -1) {
+			Py_DECREF(it);
+			Py_DECREF(result);
+			Py_DECREF(key);
+			return NULL;
+		}
+		if (rv) {
+			if (set_add_entry(result, &entry) == -1) {
+				Py_DECREF(it);
+				Py_DECREF(result);
+				Py_DECREF(key);
+				return NULL;
+			}
+		}
+		Py_DECREF(key);
+	}
+	Py_DECREF(it);
+	if (PyErr_Occurred()) {
+		Py_DECREF(result);
+		return NULL;
+	}
+	return (PyObject *)result;
+}
+
+PyDoc_STRVAR(intersection_doc,
+"Return the intersection of two sets as a new set.\n\
+\n\
+(i.e. all elements that are in both sets.)");
+
+static PyObject *
+set_intersection_update(PySetObject *so, PyObject *other)
+{
+	PyObject *tmp;
+
+	tmp = set_intersection(so, other);
+	if (tmp == NULL)
+		return NULL;
+	set_swap_bodies(so, (PySetObject *)tmp);
+	Py_DECREF(tmp);
+	Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(intersection_update_doc,
+"Update a set with the intersection of itself and another.");
+
+static PyObject *
+set_and(PySetObject *so, PyObject *other)
+{
+	if (!PyAnySet_Check(so) || !PyAnySet_Check(other)) {
+		Py_INCREF(Py_NotImplemented);
+		return Py_NotImplemented;
+	}
+	return set_intersection(so, other);
+}
+
+static PyObject *
+set_iand(PySetObject *so, PyObject *other)
+{
+	PyObject *result;
+
+	if (!PyAnySet_Check(other)) {
+		Py_INCREF(Py_NotImplemented);
+		return Py_NotImplemented;
+	}
+	result = set_intersection_update(so, other);
+	if (result == NULL)
+		return NULL;
+	Py_DECREF(result);
+	Py_INCREF(so);
+	return (PyObject *)so;
+}
+
+static int
+set_difference_update_internal(PySetObject *so, PyObject *other)
+{
+	if ((PyObject *)so == other)
+		return set_clear_internal(so);
+	
+	if (PyAnySet_Check(other)) {
+		setentry *entry;
+		Py_ssize_t pos = 0;
+
+		while (set_next((PySetObject *)other, &pos, &entry))
+			if (set_discard_entry(so, entry) == -1)
+				return -1;
+	} else {
+		PyObject *key, *it;
+		it = PyObject_GetIter(other);
+		if (it == NULL)
+			return -1;
+
+		while ((key = PyIter_Next(it)) != NULL) {
+			if (set_discard_key(so, key) == -1) {
+				Py_DECREF(it);
+				Py_DECREF(key);
+				return -1;
+			}
+			Py_DECREF(key);
+		}
+		Py_DECREF(it);
+		if (PyErr_Occurred())
+			return -1;
+	}
+	/* If more than 1/5 are dummies, then resize them away. */
+	if ((so->fill - so->used) * 5 < so->mask)
+		return 0;
+	return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);
+}
+
+static PyObject *
+set_difference_update(PySetObject *so, PyObject *other)
+{
+	if (set_difference_update_internal(so, other) != -1)
+		Py_RETURN_NONE;
+	return NULL;
+}
+
+PyDoc_STRVAR(difference_update_doc,
+"Remove all elements of another set from this set.");
+
+static PyObject *
+set_difference(PySetObject *so, PyObject *other)
+{
+	PyObject *result;
+	setentry *entry;
+	Py_ssize_t pos = 0;
+
+	if (!PyAnySet_Check(other)  && !PyDict_CheckExact(other)) {
+		result = set_copy(so);
+		if (result == NULL)
+			return NULL;
+		if (set_difference_update_internal((PySetObject *)result, other) != -1)
+			return result;
+		Py_DECREF(result);
+		return NULL;
+	}
+	
+	result = make_new_set(so->ob_type, NULL);
+	if (result == NULL)
+		return NULL;
+
+	if (PyDict_CheckExact(other)) {
+		while (set_next(so, &pos, &entry)) {
+			setentry entrycopy;
+			entrycopy.hash = entry->hash;
+			entrycopy.key = entry->key;
+			if (!_PyDict_Contains(other, entry->key, entry->hash)) {
+				if (set_add_entry((PySetObject *)result, &entrycopy) == -1) {
+					Py_DECREF(result);
+					return NULL;
+				}
+			}
+		}
+		return result;
+	}
+
+	while (set_next(so, &pos, &entry)) {
+		int rv = set_contains_entry((PySetObject *)other, entry);
+		if (rv == -1) {
+			Py_DECREF(result);
+			return NULL;
+		}
+		if (!rv) {
+			if (set_add_entry((PySetObject *)result, entry) == -1) {
+				Py_DECREF(result);
+				return NULL;
+			}
+		}
+	}
+	return result;
+}
+
+PyDoc_STRVAR(difference_doc,
+"Return the difference of two sets as a new set.\n\
+\n\
+(i.e. all elements that are in this set but not the other.)");
+static PyObject *
+set_sub(PySetObject *so, PyObject *other)
+{
+	if (!PyAnySet_Check(so) || !PyAnySet_Check(other)) {
+		Py_INCREF(Py_NotImplemented);
+		return Py_NotImplemented;
+	}
+	return set_difference(so, other);
+}
+
+static PyObject *
+set_isub(PySetObject *so, PyObject *other)
+{
+	PyObject *result;
+
+	if (!PyAnySet_Check(other)) {
+		Py_INCREF(Py_NotImplemented);
+		return Py_NotImplemented;
+	}
+	result = set_difference_update(so, other);
+	if (result == NULL)
+		return NULL;
+	Py_DECREF(result);
+	Py_INCREF(so);
+	return (PyObject *)so;
+}
+
+static PyObject *
+set_symmetric_difference_update(PySetObject *so, PyObject *other)
+{
+	PySetObject *otherset;
+	PyObject *key;
+	Py_ssize_t pos = 0;
+	setentry *entry;
+
+	if ((PyObject *)so == other)
+		return set_clear(so);
+
+	if (PyDict_CheckExact(other)) {
+		PyObject *value;
+		int rv;
+		long hash;
+		while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
+			setentry an_entry;
+
+			an_entry.hash = hash;
+			an_entry.key = key;
+			rv = set_discard_entry(so, &an_entry);
+			if (rv == -1)
+				return NULL;
+			if (rv == DISCARD_NOTFOUND) {
+				if (set_add_entry(so, &an_entry) == -1)
+					return NULL;
+			}
+		}
+		Py_RETURN_NONE;
+	}
+
+	if (PyAnySet_Check(other)) {
+		Py_INCREF(other);
+		otherset = (PySetObject *)other;
+	} else {
+		otherset = (PySetObject *)make_new_set(so->ob_type, other);
+		if (otherset == NULL)
+			return NULL;
+	}
+
+	while (set_next(otherset, &pos, &entry)) {
+		int rv = set_discard_entry(so, entry);
+		if (rv == -1) {
+			Py_DECREF(otherset);
+			return NULL;
+		}
+		if (rv == DISCARD_NOTFOUND) {
+			if (set_add_entry(so, entry) == -1) {
+				Py_DECREF(otherset);
+				return NULL;
+			}
+		}
+	}
+	Py_DECREF(otherset);
+	Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(symmetric_difference_update_doc,
+"Update a set with the symmetric difference of itself and another.");
+
+static PyObject *
+set_symmetric_difference(PySetObject *so, PyObject *other)
+{
+	PyObject *rv;
+	PySetObject *otherset;
+
+	otherset = (PySetObject *)make_new_set(so->ob_type, other);
+	if (otherset == NULL)
+		return NULL;
+	rv = set_symmetric_difference_update(otherset, (PyObject *)so);
+	if (rv == NULL)
+		return NULL;
+	Py_DECREF(rv);
+	return (PyObject *)otherset;
+}
+
+PyDoc_STRVAR(symmetric_difference_doc,
+"Return the symmetric difference of two sets as a new set.\n\
+\n\
+(i.e. all elements that are in exactly one of the sets.)");
+
+static PyObject *
+set_xor(PySetObject *so, PyObject *other)
+{
+	if (!PyAnySet_Check(so) || !PyAnySet_Check(other)) {
+		Py_INCREF(Py_NotImplemented);
+		return Py_NotImplemented;
+	}
+	return set_symmetric_difference(so, other);
+}
+
+static PyObject *
+set_ixor(PySetObject *so, PyObject *other)
+{
+	PyObject *result;
+
+	if (!PyAnySet_Check(other)) {
+		Py_INCREF(Py_NotImplemented);
+		return Py_NotImplemented;
+	}
+	result = set_symmetric_difference_update(so, other);
+	if (result == NULL)
+		return NULL;
+	Py_DECREF(result);
+	Py_INCREF(so);
+	return (PyObject *)so;
+}
+
+static PyObject *
+set_issubset(PySetObject *so, PyObject *other)
+{
+	setentry *entry;
+	Py_ssize_t pos = 0;
+
+	if (!PyAnySet_Check(other)) {
+		PyObject *tmp, *result;
+		tmp = make_new_set(&PySet_Type, other);
+		if (tmp == NULL)
+			return NULL;
+		result = set_issubset(so, tmp);
+		Py_DECREF(tmp);
+		return result;
+	}
+	if (PySet_GET_SIZE(so) > PySet_GET_SIZE(other)) 
+		Py_RETURN_FALSE;
+
+	while (set_next(so, &pos, &entry)) {
+		int rv = set_contains_entry((PySetObject *)other, entry);
+		if (rv == -1)
+			return NULL;
+		if (!rv)
+			Py_RETURN_FALSE;
+	}
+	Py_RETURN_TRUE;
+}
+
+PyDoc_STRVAR(issubset_doc, "Report whether another set contains this set.");
+
+static PyObject *
+set_issuperset(PySetObject *so, PyObject *other)
+{
+	PyObject *tmp, *result;
+
+	if (!PyAnySet_Check(other)) {
+		tmp = make_new_set(&PySet_Type, other);
+		if (tmp == NULL)
+			return NULL;
+		result = set_issuperset(so, tmp);
+		Py_DECREF(tmp);
+		return result;
+	}
+	return set_issubset((PySetObject *)other, (PyObject *)so);
+}
+
+PyDoc_STRVAR(issuperset_doc, "Report whether this set contains another set.");
+
+static PyObject *
+set_richcompare(PySetObject *v, PyObject *w, int op)
+{
+	PyObject *r1, *r2;
+
+	if(!PyAnySet_Check(w)) {
+		if (op == Py_EQ)
+			Py_RETURN_FALSE;
+		if (op == Py_NE)
+			Py_RETURN_TRUE;
+		PyErr_SetString(PyExc_TypeError, "can only compare to a set");
+		return NULL;
+	}
+	switch (op) {
+	case Py_EQ:
+		if (PySet_GET_SIZE(v) != PySet_GET_SIZE(w))
+			Py_RETURN_FALSE;
+		if (v->hash != -1  &&
+		    ((PySetObject *)w)->hash != -1 &&
+		    v->hash != ((PySetObject *)w)->hash)
+			Py_RETURN_FALSE;
+		return set_issubset(v, w);
+	case Py_NE:
+		r1 = set_richcompare(v, w, Py_EQ);
+		if (r1 == NULL)
+			return NULL;
+		r2 = PyBool_FromLong(PyObject_Not(r1));
+		Py_DECREF(r1);
+		return r2;
+	case Py_LE:
+		return set_issubset(v, w);
+	case Py_GE:
+		return set_issuperset(v, w);
+	case Py_LT:
+		if (PySet_GET_SIZE(v) >= PySet_GET_SIZE(w))
+			Py_RETURN_FALSE;		
+		return set_issubset(v, w);
+	case Py_GT:
+		if (PySet_GET_SIZE(v) <= PySet_GET_SIZE(w))
+			Py_RETURN_FALSE;
+		return set_issuperset(v, w);
+	}
+	Py_INCREF(Py_NotImplemented);
+	return Py_NotImplemented;
+}
+
+static int
+set_nocmp(PyObject *self, PyObject *other)
+{
+	PyErr_SetString(PyExc_TypeError, "cannot compare sets using cmp()");
+	return -1;
+}
+
+static PyObject *
+set_add(PySetObject *so, PyObject *key)
+{
+	if (set_add_key(so, key) == -1)
+		return NULL;
+	Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(add_doc, 
+"Add an element to a set.\n\
+\n\
+This has no effect if the element is already present.");
+
+static int
+set_contains(PySetObject *so, PyObject *key)
+{
+	PyObject *tmpkey;
+	int rv;
+
+	rv = set_contains_key(so, key);
+	if (rv == -1) {
+		if (!PyAnySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
+			return -1;
+		PyErr_Clear();
+		tmpkey = make_new_set(&PyFrozenSet_Type, NULL);
+		if (tmpkey == NULL)
+			return -1;
+		set_swap_bodies((PySetObject *)tmpkey, (PySetObject *)key);
+		rv = set_contains(so, tmpkey);
+		set_swap_bodies((PySetObject *)tmpkey, (PySetObject *)key);
+		Py_DECREF(tmpkey);
+	}
+	return rv;
+}
+
+static PyObject *
+set_direct_contains(PySetObject *so, PyObject *key)
+{
+	long result;
+
+	result = set_contains(so, key);
+	if (result == -1)
+		return NULL;
+	return PyBool_FromLong(result);
+}
+
+PyDoc_STRVAR(contains_doc, "x.__contains__(y) <==> y in x.");
+
+static PyObject *
+set_remove(PySetObject *so, PyObject *key)
+{
+	PyObject *tmpkey, *result;
+	int rv;
+
+	rv = set_discard_key(so, key);
+	if (rv == -1) {
+		if (!PyAnySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
+			return NULL;
+		PyErr_Clear();
+		tmpkey = make_new_set(&PyFrozenSet_Type, NULL);
+		if (tmpkey == NULL)
+			return NULL;
+		set_swap_bodies((PySetObject *)tmpkey, (PySetObject *)key);
+		result = set_remove(so, tmpkey);
+		set_swap_bodies((PySetObject *)tmpkey, (PySetObject *)key);
+		Py_DECREF(tmpkey);
+		return result;
+	} else if (rv == DISCARD_NOTFOUND) {
+		set_key_error(key);
+		return NULL;
+	}
+	Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(remove_doc,
+"Remove an element from a set; it must be a member.\n\
+\n\
+If the element is not a member, raise a KeyError.");
+
+static PyObject *
+set_discard(PySetObject *so, PyObject *key)
+{
+	PyObject *tmpkey, *result;
+	int rv;
+
+	rv = set_discard_key(so, key);
+	if (rv == -1) {
+		if (!PyAnySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
+			return NULL;
+		PyErr_Clear();
+		tmpkey = make_new_set(&PyFrozenSet_Type, NULL);
+		if (tmpkey == NULL)
+			return NULL;
+		set_swap_bodies((PySetObject *)tmpkey, (PySetObject *)key);
+		result = set_discard(so, tmpkey);
+		set_swap_bodies((PySetObject *)tmpkey, (PySetObject *)key);
+		Py_DECREF(tmpkey);
+		return result;
+	}
+	Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(discard_doc,
+"Remove an element from a set if it is a member.\n\
+\n\
+If the element is not a member, do nothing."); 
+
+static PyObject *
+set_reduce(PySetObject *so)
+{
+	PyObject *keys=NULL, *args=NULL, *result=NULL, *dict=NULL;
+
+	keys = PySequence_List((PyObject *)so);
+	if (keys == NULL)
+		goto done;
+	args = PyTuple_Pack(1, keys);
+	if (args == NULL)
+		goto done;
+	dict = PyObject_GetAttrString((PyObject *)so, "__dict__");
+	if (dict == NULL) {
+		PyErr_Clear();
+		dict = Py_None;
+		Py_INCREF(dict);
+	}
+	result = PyTuple_Pack(3, so->ob_type, args, dict);
+done:
+	Py_XDECREF(args);
+	Py_XDECREF(keys);
+	Py_XDECREF(dict);
+	return result;
+}
+
+PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
+
+static int
+set_init(PySetObject *self, PyObject *args, PyObject *kwds)
+{
+	PyObject *iterable = NULL;
+
+	if (!PyAnySet_Check(self))
+		return -1;
+	if (!PyArg_UnpackTuple(args, self->ob_type->tp_name, 0, 1, &iterable))
+		return -1;
+	set_clear_internal(self);
+	self->hash = -1;
+	if (iterable == NULL)
+		return 0;
+	return set_update_internal(self, iterable);
+}
+
+static PySequenceMethods set_as_sequence = {
+	set_len,			/* sq_length */
+	0,				/* sq_concat */
+	0,				/* sq_repeat */
+	0,				/* sq_item */
+	0,				/* sq_slice */
+	0,				/* sq_ass_item */
+	0,				/* sq_ass_slice */
+	(objobjproc)set_contains,	/* sq_contains */
+};
+
+/* set object ********************************************************/
+
+#ifdef Py_DEBUG
+static PyObject *test_c_api(PySetObject *so);
+
+PyDoc_STRVAR(test_c_api_doc, "Exercises C API.  Returns True.\n\
+All is well if assertions don't fail.");
+#endif
+
+static PyMethodDef set_methods[] = {
+	{"add",		(PyCFunction)set_add,		METH_O,
+	 add_doc},
+	{"clear",	(PyCFunction)set_clear,		METH_NOARGS,
+	 clear_doc},
+	{"__contains__",(PyCFunction)set_direct_contains,	METH_O | METH_COEXIST,
+	 contains_doc},
+	{"copy",	(PyCFunction)set_copy,		METH_NOARGS,
+	 copy_doc},
+	{"discard",	(PyCFunction)set_discard,	METH_O,
+	 discard_doc},
+	{"difference",	(PyCFunction)set_difference,	METH_O,
+	 difference_doc},
+	{"difference_update",	(PyCFunction)set_difference_update,	METH_O,
+	 difference_update_doc},
+	{"intersection",(PyCFunction)set_intersection,	METH_O,
+	 intersection_doc},
+	{"intersection_update",(PyCFunction)set_intersection_update,	METH_O,
+	 intersection_update_doc},
+	{"issubset",	(PyCFunction)set_issubset,	METH_O,
+	 issubset_doc},
+	{"issuperset",	(PyCFunction)set_issuperset,	METH_O,
+	 issuperset_doc},
+	{"pop",		(PyCFunction)set_pop,		METH_NOARGS,
+	 pop_doc},
+	{"__reduce__",	(PyCFunction)set_reduce,	METH_NOARGS,
+	 reduce_doc},
+	{"remove",	(PyCFunction)set_remove,	METH_O,
+	 remove_doc},
+	{"symmetric_difference",(PyCFunction)set_symmetric_difference,	METH_O,
+	 symmetric_difference_doc},
+	{"symmetric_difference_update",(PyCFunction)set_symmetric_difference_update,	METH_O,
+	 symmetric_difference_update_doc},
+#ifdef Py_DEBUG
+	{"test_c_api",	(PyCFunction)test_c_api,	METH_NOARGS,
+	 test_c_api_doc},
+#endif
+	{"union",	(PyCFunction)set_union,		METH_O,
+	 union_doc},
+	{"update",	(PyCFunction)set_update,	METH_O,
+	 update_doc},
+	{NULL,		NULL}	/* sentinel */
+};
+
+static PyNumberMethods set_as_number = {
+	0,				/*nb_add*/
+	(binaryfunc)set_sub,		/*nb_subtract*/
+	0,				/*nb_multiply*/
+	0,				/*nb_divide*/
+	0,				/*nb_remainder*/
+	0,				/*nb_divmod*/
+	0,				/*nb_power*/
+	0,				/*nb_negative*/
+	0,				/*nb_positive*/
+	0,				/*nb_absolute*/
+	0,				/*nb_nonzero*/
+	0,				/*nb_invert*/
+	0,				/*nb_lshift*/
+	0,				/*nb_rshift*/
+	(binaryfunc)set_and,		/*nb_and*/
+	(binaryfunc)set_xor,		/*nb_xor*/
+	(binaryfunc)set_or,		/*nb_or*/
+	0,				/*nb_coerce*/
+	0,				/*nb_int*/
+	0,				/*nb_long*/
+	0,				/*nb_float*/
+	0,				/*nb_oct*/
+	0, 				/*nb_hex*/
+	0,				/*nb_inplace_add*/
+	(binaryfunc)set_isub,		/*nb_inplace_subtract*/
+	0,				/*nb_inplace_multiply*/
+	0,				/*nb_inplace_divide*/
+	0,				/*nb_inplace_remainder*/
+	0,				/*nb_inplace_power*/
+	0,				/*nb_inplace_lshift*/
+	0,				/*nb_inplace_rshift*/
+	(binaryfunc)set_iand,		/*nb_inplace_and*/
+	(binaryfunc)set_ixor,		/*nb_inplace_xor*/
+	(binaryfunc)set_ior,		/*nb_inplace_or*/
+};
+
+PyDoc_STRVAR(set_doc,
+"set(iterable) --> set object\n\
+\n\
+Build an unordered collection of unique elements.");
+
+PyTypeObject PySet_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,				/* ob_size */
+	"set",				/* tp_name */
+	sizeof(PySetObject),		/* tp_basicsize */
+	0,				/* tp_itemsize */
+	/* methods */
+	(destructor)set_dealloc,	/* tp_dealloc */
+	(printfunc)set_tp_print,	/* tp_print */
+	0,				/* tp_getattr */
+	0,				/* tp_setattr */
+	set_nocmp,			/* tp_compare */
+	(reprfunc)set_repr,		/* tp_repr */
+	&set_as_number,			/* tp_as_number */
+	&set_as_sequence,		/* tp_as_sequence */
+	0,				/* tp_as_mapping */
+	set_nohash,			/* tp_hash */
+	0,				/* tp_call */
+	0,				/* tp_str */
+	PyObject_GenericGetAttr,	/* tp_getattro */
+	0,				/* tp_setattro */
+	0,				/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES |
+		Py_TPFLAGS_BASETYPE,	/* tp_flags */
+	set_doc,			/* tp_doc */
+	(traverseproc)set_traverse,	/* tp_traverse */
+	(inquiry)set_clear_internal,	/* tp_clear */
+	(richcmpfunc)set_richcompare,	/* tp_richcompare */
+	offsetof(PySetObject, weakreflist),	/* tp_weaklistoffset */
+	(getiterfunc)set_iter,	/* tp_iter */
+	0,				/* tp_iternext */
+	set_methods,			/* tp_methods */
+	0,				/* tp_members */
+	0,				/* tp_getset */
+	0,				/* tp_base */
+	0,				/* tp_dict */
+	0,				/* tp_descr_get */
+	0,				/* tp_descr_set */
+	0,				/* tp_dictoffset */
+	(initproc)set_init,		/* tp_init */
+	PyType_GenericAlloc,		/* tp_alloc */
+	set_new,			/* tp_new */
+	PyObject_GC_Del,		/* tp_free */
+};
+
+/* frozenset object ********************************************************/
+
+
+static PyMethodDef frozenset_methods[] = {
+	{"__contains__",(PyCFunction)set_direct_contains,	METH_O | METH_COEXIST,
+	 contains_doc},
+	{"copy",	(PyCFunction)frozenset_copy,	METH_NOARGS,
+	 copy_doc},
+	{"difference",	(PyCFunction)set_difference,	METH_O,
+	 difference_doc},
+	{"intersection",(PyCFunction)set_intersection,	METH_O,
+	 intersection_doc},
+	{"issubset",	(PyCFunction)set_issubset,	METH_O,
+	 issubset_doc},
+	{"issuperset",	(PyCFunction)set_issuperset,	METH_O,
+	 issuperset_doc},
+	{"__reduce__",	(PyCFunction)set_reduce,	METH_NOARGS,
+	 reduce_doc},
+	{"symmetric_difference",(PyCFunction)set_symmetric_difference,	METH_O,
+	 symmetric_difference_doc},
+	{"union",	(PyCFunction)set_union,		METH_O,
+	 union_doc},
+	{NULL,		NULL}	/* sentinel */
+};
+
+static PyNumberMethods frozenset_as_number = {
+	0,				/*nb_add*/
+	(binaryfunc)set_sub,		/*nb_subtract*/
+	0,				/*nb_multiply*/
+	0,				/*nb_divide*/
+	0,				/*nb_remainder*/
+	0,				/*nb_divmod*/
+	0,				/*nb_power*/
+	0,				/*nb_negative*/
+	0,				/*nb_positive*/
+	0,				/*nb_absolute*/
+	0,				/*nb_nonzero*/
+	0,				/*nb_invert*/
+	0,				/*nb_lshift*/
+	0,				/*nb_rshift*/
+	(binaryfunc)set_and,		/*nb_and*/
+	(binaryfunc)set_xor,		/*nb_xor*/
+	(binaryfunc)set_or,		/*nb_or*/
+};
+
+PyDoc_STRVAR(frozenset_doc,
+"frozenset(iterable) --> frozenset object\n\
+\n\
+Build an immutable unordered collection of unique elements.");
+
+PyTypeObject PyFrozenSet_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,				/* ob_size */
+	"frozenset",			/* tp_name */
+	sizeof(PySetObject),		/* tp_basicsize */
+	0,				/* tp_itemsize */
+	/* methods */
+	(destructor)set_dealloc,	/* tp_dealloc */
+	(printfunc)set_tp_print,	/* tp_print */
+	0,				/* tp_getattr */
+	0,				/* tp_setattr */
+	set_nocmp,			/* tp_compare */
+	(reprfunc)set_repr,		/* tp_repr */
+	&frozenset_as_number,		/* tp_as_number */
+	&set_as_sequence,		/* tp_as_sequence */
+	0,				/* tp_as_mapping */
+	frozenset_hash,			/* tp_hash */
+	0,				/* tp_call */
+	0,				/* tp_str */
+	PyObject_GenericGetAttr,	/* tp_getattro */
+	0,				/* tp_setattro */
+	0,				/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES |
+		Py_TPFLAGS_BASETYPE,	/* tp_flags */
+	frozenset_doc,			/* tp_doc */
+	(traverseproc)set_traverse,	/* tp_traverse */
+	(inquiry)set_clear_internal,	/* tp_clear */
+	(richcmpfunc)set_richcompare,	/* tp_richcompare */
+	offsetof(PySetObject, weakreflist),	/* tp_weaklistoffset */
+	(getiterfunc)set_iter,		/* tp_iter */
+	0,				/* tp_iternext */
+	frozenset_methods,		/* tp_methods */
+	0,				/* tp_members */
+	0,				/* tp_getset */
+	0,				/* tp_base */
+	0,				/* tp_dict */
+	0,				/* tp_descr_get */
+	0,				/* tp_descr_set */
+	0,				/* tp_dictoffset */
+	0,				/* tp_init */
+	PyType_GenericAlloc,		/* tp_alloc */
+	frozenset_new,			/* tp_new */
+	PyObject_GC_Del,		/* tp_free */
+};
+
+
+/***** C API functions *************************************************/
+
+PyObject *
+PySet_New(PyObject *iterable)
+{
+	return make_new_set(&PySet_Type, iterable);
+}
+
+PyObject *
+PyFrozenSet_New(PyObject *iterable)
+{
+	PyObject *args, *result;
+
+	if (iterable == NULL)
+		args = PyTuple_New(0);
+	else
+		args = PyTuple_Pack(1, iterable);
+	if (args == NULL)
+		return NULL;
+	result = frozenset_new(&PyFrozenSet_Type, args, NULL);
+	Py_DECREF(args);
+	return result;
+}
+
+Py_ssize_t
+PySet_Size(PyObject *anyset)
+{
+	if (!PyAnySet_Check(anyset)) {
+		PyErr_BadInternalCall();
+		return -1;
+	}
+	return PySet_GET_SIZE(anyset);
+}
+
+int
+PySet_Clear(PyObject *set)
+{
+	if (!PyType_IsSubtype(set->ob_type, &PySet_Type)) {
+		PyErr_BadInternalCall();
+		return -1;
+	}
+	return set_clear_internal((PySetObject *)set);
+}
+
+int
+PySet_Contains(PyObject *anyset, PyObject *key)
+{
+	if (!PyAnySet_Check(anyset)) {
+		PyErr_BadInternalCall();
+		return -1;
+	}
+	return set_contains_key((PySetObject *)anyset, key);
+}
+
+int
+PySet_Discard(PyObject *set, PyObject *key)
+{
+	if (!PyType_IsSubtype(set->ob_type, &PySet_Type)) {
+		PyErr_BadInternalCall();
+		return -1;
+	}
+	return set_discard_key((PySetObject *)set, key);
+}
+
+int
+PySet_Add(PyObject *set, PyObject *key)
+{
+	if (!PyType_IsSubtype(set->ob_type, &PySet_Type)) {
+		PyErr_BadInternalCall();
+		return -1;
+	}
+	return set_add_key((PySetObject *)set, key);
+}
+
+int
+_PySet_Next(PyObject *set, Py_ssize_t *pos, PyObject **key)
+{
+	setentry *entry_ptr;
+
+	if (!PyAnySet_Check(set)) {
+		PyErr_BadInternalCall();
+		return -1;
+	}
+	if (set_next((PySetObject *)set, pos, &entry_ptr) == 0)
+		return 0;
+	*key = entry_ptr->key;
+	return 1;
+}
+
+int
+_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, long *hash)
+{
+	setentry *entry;
+
+	if (!PyAnySet_Check(set)) {
+		PyErr_BadInternalCall();
+		return -1;
+	}
+	if (set_next((PySetObject *)set, pos, &entry) == 0)
+		return 0;
+	*key = entry->key;
+	*hash = entry->hash;
+	return 1;
+}
+
+PyObject *
+PySet_Pop(PyObject *set)
+{
+	if (!PyType_IsSubtype(set->ob_type, &PySet_Type)) {
+		PyErr_BadInternalCall();
+		return NULL;
+	}
+	return set_pop((PySetObject *)set);
+}
+
+int
+_PySet_Update(PyObject *set, PyObject *iterable)
+{
+	if (!PyType_IsSubtype(set->ob_type, &PySet_Type)) {
+		PyErr_BadInternalCall();
+		return -1;
+	}
+	return set_update_internal((PySetObject *)set, iterable);
+}
+
+#ifdef Py_DEBUG
+
+/* Test code to be called with any three element set. 
+   Returns True and original set is restored. */
+
+#define assertRaises(call_return_value, exception)		\
+	do {							\
+		assert(call_return_value);			\
+		assert(PyErr_ExceptionMatches(exception));	\
+		PyErr_Clear();					\
+	} while(0)
+
+static PyObject *
+test_c_api(PySetObject *so)
+{
+	Py_ssize_t count;
+	char *s;
+	Py_ssize_t i;
+	PyObject *elem, *dup, *t, *f, *dup2;
+	PyObject *ob = (PyObject *)so;
+
+	/* Verify preconditions and exercise type/size checks */
+	assert(PyAnySet_Check(ob));
+	assert(PyAnySet_CheckExact(ob));
+	assert(!PyFrozenSet_CheckExact(ob));
+	assert(PySet_Size(ob) == 3);
+	assert(PySet_GET_SIZE(ob) == 3);
+
+	/* Raise TypeError for non-iterable constructor arguments */
+	assertRaises(PySet_New(Py_None) == NULL, PyExc_TypeError);
+	assertRaises(PyFrozenSet_New(Py_None) == NULL, PyExc_TypeError);
+
+	/* Raise TypeError for unhashable key */
+	dup = PySet_New(ob);
+	assertRaises(PySet_Discard(ob, dup) == -1, PyExc_TypeError);
+	assertRaises(PySet_Contains(ob, dup) == -1, PyExc_TypeError);
+	assertRaises(PySet_Add(ob, dup) == -1, PyExc_TypeError);
+
+	/* Exercise successful pop, contains, add, and discard */
+	elem = PySet_Pop(ob);
+	assert(PySet_Contains(ob, elem) == 0);
+	assert(PySet_GET_SIZE(ob) == 2);
+	assert(PySet_Add(ob, elem) == 0);
+	assert(PySet_Contains(ob, elem) == 1);
+	assert(PySet_GET_SIZE(ob) == 3);
+	assert(PySet_Discard(ob, elem) == 1);
+	assert(PySet_GET_SIZE(ob) == 2);
+	assert(PySet_Discard(ob, elem) == 0);
+	assert(PySet_GET_SIZE(ob) == 2);
+
+	/* Exercise clear */
+	dup2 = PySet_New(dup);
+	assert(PySet_Clear(dup2) == 0);
+	assert(PySet_Size(dup2) == 0);
+	Py_DECREF(dup2);
+
+	/* Raise SystemError on clear or update of frozen set */
+	f = PyFrozenSet_New(dup);
+	assertRaises(PySet_Clear(f) == -1, PyExc_SystemError);
+	assertRaises(_PySet_Update(f, dup) == -1, PyExc_SystemError);
+	Py_DECREF(f);
+
+	/* Exercise direct iteration */
+	i = 0, count = 0;
+	while (_PySet_Next((PyObject *)dup, &i, &elem)) {
+		s = PyString_AsString(elem);
+		assert(s && (s[0] == 'a' || s[0] == 'b' || s[0] == 'c'));
+		count++;
+	}
+	assert(count == 3);
+
+	/* Exercise updates */
+	dup2 = PySet_New(NULL);
+	assert(_PySet_Update(dup2, dup) == 0);
+	assert(PySet_Size(dup2) == 3);
+	assert(_PySet_Update(dup2, dup) == 0);
+	assert(PySet_Size(dup2) == 3);
+	Py_DECREF(dup2);
+
+	/* Raise SystemError when self argument is not a set or frozenset. */
+	t = PyTuple_New(0);
+	assertRaises(PySet_Size(t) == -1, PyExc_SystemError);
+	assertRaises(PySet_Contains(t, elem) == -1, PyExc_SystemError);
+	Py_DECREF(t);
+
+	/* Raise SystemError when self argument is not a set. */
+	f = PyFrozenSet_New(dup);
+	assert(PySet_Size(f) == 3);
+	assert(PyFrozenSet_CheckExact(f));
+	assertRaises(PySet_Add(f, elem) == -1, PyExc_SystemError);
+	assertRaises(PySet_Discard(f, elem) == -1, PyExc_SystemError);
+	assertRaises(PySet_Pop(f) == NULL, PyExc_SystemError);
+	Py_DECREF(f);
+
+	/* Raise KeyError when popping from an empty set */
+	assert(PyNumber_InPlaceSubtract(ob, ob) == ob);
+	Py_DECREF(ob);
+	assert(PySet_GET_SIZE(ob) == 0);
+	assertRaises(PySet_Pop(ob) == NULL, PyExc_KeyError);
+
+	/* Restore the set from the copy using the PyNumber API */
+	assert(PyNumber_InPlaceOr(ob, dup) == ob);
+	Py_DECREF(ob);
+
+	/* Verify constructors accept NULL arguments */
+	f = PySet_New(NULL);
+	assert(f != NULL);
+	assert(PySet_GET_SIZE(f) == 0);
+	Py_DECREF(f);
+	f = PyFrozenSet_New(NULL);
+	assert(f != NULL);
+	assert(PyFrozenSet_CheckExact(f));
+	assert(PySet_GET_SIZE(f) == 0);
+	Py_DECREF(f);
+
+	Py_DECREF(elem);
+	Py_DECREF(dup);
+	Py_RETURN_TRUE;
+}
+
+#undef assertRaises
+
+#endif

Added: vendor/Python/current/Objects/sliceobject.c
===================================================================
--- vendor/Python/current/Objects/sliceobject.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Objects/sliceobject.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,351 @@
+/*
+Written by Jim Hugunin and Chris Chase.
+
+This includes both the singular ellipsis object and slice objects.
+
+Guido, feel free to do whatever you want in the way of copyrights
+for this file.
+*/
+
+/* 
+Py_Ellipsis encodes the '...' rubber index token. It is similar to
+the Py_NoneStruct in that there is no way to create other objects of
+this type and there is exactly one in existence.
+*/
+
+#include "Python.h"
+#include "structmember.h"
+
+static PyObject *
+ellipsis_repr(PyObject *op)
+{
+	return PyString_FromString("Ellipsis");
+}
+
+static PyTypeObject PyEllipsis_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,				/* ob_size */
+	"ellipsis",			/* tp_name */
+	0,				/* tp_basicsize */
+	0,				/* tp_itemsize */
+	0, /*never called*/		/* tp_dealloc */
+	0,				/* tp_print */
+	0,				/* tp_getattr */
+	0,				/* tp_setattr */
+	0,				/* tp_compare */
+	ellipsis_repr,			/* tp_repr */
+	0,				/* tp_as_number */
+	0,				/* tp_as_sequence */
+	0,				/* tp_as_mapping */
+	0,				/* tp_hash */
+	0,				/* tp_call */
+	0,				/* tp_str */
+	PyObject_GenericGetAttr,	/* tp_getattro */
+	0,				/* tp_setattro */
+	0,				/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT,		/* tp_flags */
+};
+
+PyObject _Py_EllipsisObject = {
+	PyObject_HEAD_INIT(&PyEllipsis_Type)
+};
+
+
+/* Slice object implementation
+
+   start, stop, and step are python objects with None indicating no
+   index is present.
+*/
+
+PyObject *
+PySlice_New(PyObject *start, PyObject *stop, PyObject *step)
+{
+	PySliceObject *obj = PyObject_New(PySliceObject, &PySlice_Type);
+
+	if (obj == NULL)
+		return NULL;
+
+	if (step == NULL) step = Py_None;
+	Py_INCREF(step);
+	if (start == NULL) start = Py_None;
+	Py_INCREF(start);
+	if (stop == NULL) stop = Py_None;
+	Py_INCREF(stop);
+
+	obj->step = step;
+	obj->start = start;
+	obj->stop = stop;
+
+	return (PyObject *) obj;
+}
+
+PyObject *
+_PySlice_FromIndices(Py_ssize_t istart, Py_ssize_t istop)
+{
+	PyObject *start, *end, *slice;
+	start = PyInt_FromSsize_t(istart);
+	if (!start)
+		return NULL;
+	end = PyInt_FromSsize_t(istop);
+	if (!end) {
+		Py_DECREF(start);
+		return NULL;
+	}
+
+	slice = PySlice_New(start, end, NULL);
+	Py_DECREF(start);
+	Py_DECREF(end);
+	return slice;
+}
+
+int
+PySlice_GetIndices(PySliceObject *r, Py_ssize_t length,
+                   Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step)
+{
+	/* XXX support long ints */
+	if (r->step == Py_None) {
+		*step = 1;
+	} else {
+		if (!PyInt_Check(r->step) && !PyLong_Check(r->step)) return -1;
+		*step = PyInt_AsSsize_t(r->step);
+	}
+	if (r->start == Py_None) {
+		*start = *step < 0 ? length-1 : 0;
+	} else {
+		if (!PyInt_Check(r->start) && !PyLong_Check(r->step)) return -1;
+		*start = PyInt_AsSsize_t(r->start);
+		if (*start < 0) *start += length;
+	}
+	if (r->stop == Py_None) {
+		*stop = *step < 0 ? -1 : length;
+	} else {
+		if (!PyInt_Check(r->stop) && !PyLong_Check(r->step)) return -1;
+		*stop = PyInt_AsSsize_t(r->stop);
+		if (*stop < 0) *stop += length;
+	}
+	if (*stop > length) return -1;
+	if (*start >= length) return -1;
+	if (*step == 0) return -1;
+	return 0;
+}
+
+int
+PySlice_GetIndicesEx(PySliceObject *r, Py_ssize_t length,
+		     Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, Py_ssize_t *slicelength)
+{
+	/* this is harder to get right than you might think */
+
+	Py_ssize_t defstart, defstop;
+
+	if (r->step == Py_None) {
+		*step = 1;
+	} 
+	else {
+		if (!_PyEval_SliceIndex(r->step, step)) return -1;
+		if (*step == 0) {
+			PyErr_SetString(PyExc_ValueError,
+					"slice step cannot be zero");
+			return -1;
+		}
+	}
+
+	defstart = *step < 0 ? length-1 : 0;
+	defstop = *step < 0 ? -1 : length;
+
+	if (r->start == Py_None) {
+		*start = defstart;
+	}
+	else {
+		if (!_PyEval_SliceIndex(r->start, start)) return -1;
+		if (*start < 0) *start += length;
+		if (*start < 0) *start = (*step < 0) ? -1 : 0;
+		if (*start >= length) 
+			*start = (*step < 0) ? length - 1 : length;
+	}
+
+	if (r->stop == Py_None) {
+		*stop = defstop;
+	}
+	else {
+		if (!_PyEval_SliceIndex(r->stop, stop)) return -1;
+		if (*stop < 0) *stop += length;
+		if (*stop < 0) *stop = -1;
+		if (*stop > length) *stop = length;
+	}
+
+	if ((*step < 0 && *stop >= *start) 
+	    || (*step > 0 && *start >= *stop)) {
+		*slicelength = 0;
+	}
+	else if (*step < 0) {
+		*slicelength = (*stop-*start+1)/(*step)+1;
+	}
+	else {
+		*slicelength = (*stop-*start-1)/(*step)+1;
+	}
+
+	return 0;
+}
+
+static PyObject *
+slice_new(PyTypeObject *type, PyObject *args, PyObject *kw)
+{
+	PyObject *start, *stop, *step;
+
+	start = stop = step = NULL;
+
+	if (!_PyArg_NoKeywords("slice()", kw))
+		return NULL;
+
+	if (!PyArg_UnpackTuple(args, "slice", 1, 3, &start, &stop, &step))
+		return NULL;
+
+	/* This swapping of stop and start is to maintain similarity with
+	   range(). */
+	if (stop == NULL) {
+		stop = start;
+		start = NULL;
+	}
+	return PySlice_New(start, stop, step);
+}
+
+PyDoc_STRVAR(slice_doc,
+"slice([start,] stop[, step])\n\
+\n\
+Create a slice object.  This is used for extended slicing (e.g. a[0:10:2]).");
+
+static void
+slice_dealloc(PySliceObject *r)
+{
+	Py_DECREF(r->step);
+	Py_DECREF(r->start);
+	Py_DECREF(r->stop);
+	PyObject_Del(r);
+}
+
+static PyObject *
+slice_repr(PySliceObject *r)
+{
+	PyObject *s, *comma;
+
+	s = PyString_FromString("slice(");
+	comma = PyString_FromString(", ");
+	PyString_ConcatAndDel(&s, PyObject_Repr(r->start));
+	PyString_Concat(&s, comma);
+	PyString_ConcatAndDel(&s, PyObject_Repr(r->stop));
+	PyString_Concat(&s, comma);
+	PyString_ConcatAndDel(&s, PyObject_Repr(r->step));
+	PyString_ConcatAndDel(&s, PyString_FromString(")"));
+	Py_DECREF(comma);
+	return s;
+}
+
+static PyMemberDef slice_members[] = {
+	{"start", T_OBJECT, offsetof(PySliceObject, start), READONLY},
+	{"stop", T_OBJECT, offsetof(PySliceObject, stop), READONLY},
+	{"step", T_OBJECT, offsetof(PySliceObject, step), READONLY},
+	{0}
+};
+
+static PyObject*
+slice_indices(PySliceObject* self, PyObject* len)
+{
+	Py_ssize_t ilen, start, stop, step, slicelength;
+
+	ilen = PyNumber_AsSsize_t(len, PyExc_OverflowError);
+
+	if (ilen == -1 && PyErr_Occurred()) {
+		return NULL;
+	}
+
+	if (PySlice_GetIndicesEx(self, ilen, &start, &stop, 
+				 &step, &slicelength) < 0) {
+		return NULL;
+	}
+
+	return Py_BuildValue("(nnn)", start, stop, step);
+}
+
+PyDoc_STRVAR(slice_indices_doc,
+"S.indices(len) -> (start, stop, stride)\n\
+\n\
+Assuming a sequence of length len, calculate the start and stop\n\
+indices, and the stride length of the extended slice described by\n\
+S. Out of bounds indices are clipped in a manner consistent with the\n\
+handling of normal slices.");
+
+static PyMethodDef slice_methods[] = {
+	{"indices",	(PyCFunction)slice_indices,
+	 METH_O,	slice_indices_doc},
+	{NULL, NULL}
+};
+
+static int
+slice_compare(PySliceObject *v, PySliceObject *w)
+{
+	int result = 0;
+
+        if (v == w)
+		return 0;
+
+	if (PyObject_Cmp(v->start, w->start, &result) < 0)
+	    return -2;
+	if (result != 0)
+		return result;
+	if (PyObject_Cmp(v->stop, w->stop, &result) < 0)
+	    return -2;
+	if (result != 0)
+		return result;
+	if (PyObject_Cmp(v->step, w->step, &result) < 0)
+	    return -2;
+	return result;
+}
+
+static long
+slice_hash(PySliceObject *v)
+{
+	PyErr_SetString(PyExc_TypeError, "unhashable type");
+	return -1L;
+}
+
+PyTypeObject PySlice_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,			/* Number of items for varobject */
+	"slice",		/* Name of this type */
+	sizeof(PySliceObject),	/* Basic object size */
+	0,			/* Item size for varobject */
+	(destructor)slice_dealloc,		/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	(cmpfunc)slice_compare, 		/* tp_compare */
+	(reprfunc)slice_repr,   		/* tp_repr */
+	0,					/* tp_as_number */
+	0,	    				/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	(hashfunc)slice_hash,			/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT,			/* tp_flags */
+	slice_doc,				/* tp_doc */
+	0,					/* tp_traverse */
+	0,					/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	slice_methods,				/* tp_methods */
+	slice_members,				/* tp_members */
+	0,					/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	0,					/* tp_init */
+	0,					/* tp_alloc */
+	slice_new,				/* tp_new */
+};

Added: vendor/Python/current/Objects/stringlib/README.txt
===================================================================
--- vendor/Python/current/Objects/stringlib/README.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Objects/stringlib/README.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,34 @@
+bits shared by the stringobject and unicodeobject implementations (and
+possibly other modules, in a not too distant future).
+
+the stuff in here is included into relevant places; see the individual
+source files for details.
+
+--------------------------------------------------------------------
+the following defines used by the different modules:
+
+STRINGLIB_CHAR
+
+    the type used to hold a character (char or Py_UNICODE)
+
+STRINGLIB_EMPTY
+
+    a PyObject representing the empty string
+
+int STRINGLIB_CMP(STRINGLIB_CHAR*, STRINGLIB_CHAR*, Py_ssize_t)
+
+    compares two strings. returns 0 if they match, and non-zero if not.
+
+Py_ssize_t STRINGLIB_LEN(PyObject*)
+
+    returns the length of the given string object (which must be of the
+    right type)
+
+PyObject* STRINGLIB_NEW(STRINGLIB_CHAR*, Py_ssize_t)
+
+    creates a new string object
+
+STRINGLIB_CHAR* STRINGLIB_STR(PyObject*)
+
+    returns the pointer to the character data for the given string
+    object (which must be of the right type)

Added: vendor/Python/current/Objects/stringlib/count.h
===================================================================
--- vendor/Python/current/Objects/stringlib/count.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Objects/stringlib/count.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,37 @@
+/* stringlib: count implementation */
+
+#ifndef STRINGLIB_COUNT_H
+#define STRINGLIB_COUNT_H
+
+#ifndef STRINGLIB_FASTSEARCH_H
+#error must include "stringlib/fastsearch.h" before including this module
+#endif
+
+Py_LOCAL_INLINE(Py_ssize_t)
+stringlib_count(const STRINGLIB_CHAR* str, Py_ssize_t str_len,
+                const STRINGLIB_CHAR* sub, Py_ssize_t sub_len)
+{
+    Py_ssize_t count;
+
+    if (sub_len == 0) {
+        if (str_len < 0)
+            return 0; /* start > len(str) */
+        return str_len + 1;
+    }
+
+    count = fastsearch(str, str_len, sub, sub_len, FAST_COUNT);
+
+    if (count < 0)
+        count = 0; /* no match */
+
+    return count;
+}
+
+#endif
+
+/*
+Local variables:
+c-basic-offset: 4
+indent-tabs-mode: nil
+End:
+*/

Added: vendor/Python/current/Objects/stringlib/fastsearch.h
===================================================================
--- vendor/Python/current/Objects/stringlib/fastsearch.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Objects/stringlib/fastsearch.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,104 @@
+/* stringlib: fastsearch implementation */
+
+#ifndef STRINGLIB_FASTSEARCH_H
+#define STRINGLIB_FASTSEARCH_H
+
+/* fast search/count implementation, based on a mix between boyer-
+   moore and horspool, with a few more bells and whistles on the top.
+   for some more background, see: http://effbot.org/stringlib */
+
+/* note: fastsearch may access s[n], which isn't a problem when using
+   Python's ordinary string types, but may cause problems if you're
+   using this code in other contexts.  also, the count mode returns -1
+   if there cannot possible be a match in the target string, and 0 if
+   it has actually checked for matches, but didn't find any.  callers
+   beware! */
+
+#define FAST_COUNT 0
+#define FAST_SEARCH 1
+
+Py_LOCAL_INLINE(Py_ssize_t)
+fastsearch(const STRINGLIB_CHAR* s, Py_ssize_t n,
+           const STRINGLIB_CHAR* p, Py_ssize_t m,
+           int mode)
+{
+    long mask;
+    Py_ssize_t skip, count = 0;
+    Py_ssize_t i, j, mlast, w;
+
+    w = n - m;
+
+    if (w < 0)
+        return -1;
+
+    /* look for special cases */
+    if (m <= 1) {
+        if (m <= 0)
+            return -1;
+        /* use special case for 1-character strings */
+        if (mode == FAST_COUNT) {
+            for (i = 0; i < n; i++)
+                if (s[i] == p[0])
+                    count++;
+            return count;
+        } else {
+            for (i = 0; i < n; i++)
+                if (s[i] == p[0])
+                    return i;
+        }
+        return -1;
+    }
+
+    mlast = m - 1;
+
+    /* create compressed boyer-moore delta 1 table */
+    skip = mlast - 1;
+    /* process pattern[:-1] */
+    for (mask = i = 0; i < mlast; i++) {
+        mask |= (1 << (p[i] & 0x1F));
+        if (p[i] == p[mlast])
+            skip = mlast - i - 1;
+    }
+    /* process pattern[-1] outside the loop */
+    mask |= (1 << (p[mlast] & 0x1F));
+
+    for (i = 0; i <= w; i++) {
+        /* note: using mlast in the skip path slows things down on x86 */
+        if (s[i+m-1] == p[m-1]) {
+            /* candidate match */
+            for (j = 0; j < mlast; j++)
+                if (s[i+j] != p[j])
+                    break;
+            if (j == mlast) {
+                /* got a match! */
+                if (mode != FAST_COUNT)
+                    return i;
+                count++;
+                i = i + mlast;
+                continue;
+            }
+            /* miss: check if next character is part of pattern */
+            if (!(mask & (1 << (s[i+m] & 0x1F))))
+                i = i + m;
+            else
+                i = i + skip;
+        } else {
+            /* skip: check if next character is part of pattern */
+            if (!(mask & (1 << (s[i+m] & 0x1F))))
+                i = i + m;
+        }
+    }
+
+    if (mode != FAST_COUNT)
+        return -1;
+    return count;
+}
+
+#endif
+
+/*
+Local variables:
+c-basic-offset: 4
+indent-tabs-mode: nil
+End:
+*/

Added: vendor/Python/current/Objects/stringlib/find.h
===================================================================
--- vendor/Python/current/Objects/stringlib/find.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Objects/stringlib/find.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,113 @@
+/* stringlib: find/index implementation */
+
+#ifndef STRINGLIB_FIND_H
+#define STRINGLIB_FIND_H
+
+#ifndef STRINGLIB_FASTSEARCH_H
+#error must include "stringlib/fastsearch.h" before including this module
+#endif
+
+Py_LOCAL_INLINE(Py_ssize_t)
+stringlib_find(const STRINGLIB_CHAR* str, Py_ssize_t str_len,
+               const STRINGLIB_CHAR* sub, Py_ssize_t sub_len,
+               Py_ssize_t offset)
+{
+    Py_ssize_t pos;
+
+    if (sub_len == 0) {
+        if (str_len < 0)
+            return -1;
+        return offset;
+    }
+
+    pos = fastsearch(str, str_len, sub, sub_len, FAST_SEARCH);
+
+    if (pos >= 0)
+        pos += offset;
+
+    return pos;
+}
+
+Py_LOCAL_INLINE(Py_ssize_t)
+stringlib_rfind(const STRINGLIB_CHAR* str, Py_ssize_t str_len,
+                const STRINGLIB_CHAR* sub, Py_ssize_t sub_len,
+                Py_ssize_t offset)
+{
+    /* XXX - create reversefastsearch helper! */
+    if (sub_len == 0) {
+        if (str_len < 0)
+            return -1;
+	return str_len + offset;
+    } else {
+	Py_ssize_t j, pos = -1;
+	for (j = str_len - sub_len; j >= 0; --j)
+            if (STRINGLIB_CMP(str+j, sub, sub_len) == 0) {
+                pos = j + offset;
+                break;
+            }
+        return pos;
+    }
+}
+
+Py_LOCAL_INLINE(Py_ssize_t)
+stringlib_find_slice(const STRINGLIB_CHAR* str, Py_ssize_t str_len,
+                     const STRINGLIB_CHAR* sub, Py_ssize_t sub_len,
+                     Py_ssize_t start, Py_ssize_t end)
+{
+    if (start < 0)
+        start += str_len;
+    if (start < 0)
+        start = 0;
+    if (end > str_len)
+        end = str_len;
+    if (end < 0)
+        end += str_len;
+    if (end < 0)
+        end = 0;
+
+    return stringlib_find(
+        str + start, end - start,
+        sub, sub_len, start
+        );
+}
+
+Py_LOCAL_INLINE(Py_ssize_t)
+stringlib_rfind_slice(const STRINGLIB_CHAR* str, Py_ssize_t str_len,
+                      const STRINGLIB_CHAR* sub, Py_ssize_t sub_len,
+                      Py_ssize_t start, Py_ssize_t end)
+{
+    if (start < 0)
+        start += str_len;
+    if (start < 0)
+        start = 0;
+    if (end > str_len)
+        end = str_len;
+    if (end < 0)
+        end += str_len;
+    if (end < 0)
+        end = 0;
+
+    return stringlib_rfind(str + start, end - start, sub, sub_len, start);
+}
+
+#ifdef STRINGLIB_STR
+
+Py_LOCAL_INLINE(int)
+stringlib_contains_obj(PyObject* str, PyObject* sub)
+{
+    return stringlib_find(
+        STRINGLIB_STR(str), STRINGLIB_LEN(str),
+        STRINGLIB_STR(sub), STRINGLIB_LEN(sub), 0
+        ) != -1;
+}
+
+#endif /* STRINGLIB_STR */
+
+#endif /* STRINGLIB_FIND_H */
+
+/*
+Local variables:
+c-basic-offset: 4
+indent-tabs-mode: nil
+End:
+*/

Added: vendor/Python/current/Objects/stringlib/partition.h
===================================================================
--- vendor/Python/current/Objects/stringlib/partition.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Objects/stringlib/partition.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,111 @@
+/* stringlib: partition implementation */
+
+#ifndef STRINGLIB_PARTITION_H
+#define STRINGLIB_PARTITION_H
+
+#ifndef STRINGLIB_FASTSEARCH_H
+#error must include "stringlib/fastsearch.h" before including this module
+#endif
+
+Py_LOCAL_INLINE(PyObject*)
+stringlib_partition(
+    PyObject* str_obj, const STRINGLIB_CHAR* str, Py_ssize_t str_len,
+    PyObject* sep_obj, const STRINGLIB_CHAR* sep, Py_ssize_t sep_len
+    )
+{
+    PyObject* out;
+    Py_ssize_t pos;
+
+    if (sep_len == 0) {
+        PyErr_SetString(PyExc_ValueError, "empty separator");
+	return NULL;
+    }
+
+    out = PyTuple_New(3);
+    if (!out)
+	return NULL;
+
+    pos = fastsearch(str, str_len, sep, sep_len, FAST_SEARCH);
+
+    if (pos < 0) {
+	Py_INCREF(str_obj);
+	PyTuple_SET_ITEM(out, 0, (PyObject*) str_obj);
+	Py_INCREF(STRINGLIB_EMPTY);
+	PyTuple_SET_ITEM(out, 1, (PyObject*) STRINGLIB_EMPTY);
+	Py_INCREF(STRINGLIB_EMPTY);
+	PyTuple_SET_ITEM(out, 2, (PyObject*) STRINGLIB_EMPTY);
+	return out;
+    }
+
+    PyTuple_SET_ITEM(out, 0, STRINGLIB_NEW(str, pos));
+    Py_INCREF(sep_obj);
+    PyTuple_SET_ITEM(out, 1, sep_obj);
+    pos += sep_len;
+    PyTuple_SET_ITEM(out, 2, STRINGLIB_NEW(str + pos, str_len - pos));
+
+    if (PyErr_Occurred()) {
+	Py_DECREF(out);
+	return NULL;
+    }
+
+    return out;
+}
+
+Py_LOCAL_INLINE(PyObject*)
+stringlib_rpartition(
+    PyObject* str_obj, const STRINGLIB_CHAR* str, Py_ssize_t str_len,
+    PyObject* sep_obj, const STRINGLIB_CHAR* sep, Py_ssize_t sep_len
+    )
+{
+    PyObject* out;
+    Py_ssize_t pos, j;
+
+    if (sep_len == 0) {
+        PyErr_SetString(PyExc_ValueError, "empty separator");
+	return NULL;
+    }
+
+    out = PyTuple_New(3);
+    if (!out)
+	return NULL;
+
+    /* XXX - create reversefastsearch helper! */
+        pos = -1;
+	for (j = str_len - sep_len; j >= 0; --j)
+            if (STRINGLIB_CMP(str+j, sep, sep_len) == 0) {
+                pos = j;
+                break;
+            }
+
+    if (pos < 0) {
+	Py_INCREF(STRINGLIB_EMPTY);
+	PyTuple_SET_ITEM(out, 0, (PyObject*) STRINGLIB_EMPTY);
+	Py_INCREF(STRINGLIB_EMPTY);
+	PyTuple_SET_ITEM(out, 1, (PyObject*) STRINGLIB_EMPTY);
+	Py_INCREF(str_obj);        
+	PyTuple_SET_ITEM(out, 2, (PyObject*) str_obj);
+	return out;
+    }
+
+    PyTuple_SET_ITEM(out, 0, STRINGLIB_NEW(str, pos));
+    Py_INCREF(sep_obj);
+    PyTuple_SET_ITEM(out, 1, sep_obj);
+    pos += sep_len;
+    PyTuple_SET_ITEM(out, 2, STRINGLIB_NEW(str + pos, str_len - pos));
+
+    if (PyErr_Occurred()) {
+	Py_DECREF(out);
+	return NULL;
+    }
+
+    return out;
+}
+
+#endif
+
+/*
+Local variables:
+c-basic-offset: 4
+indent-tabs-mode: nil
+End:
+*/

Added: vendor/Python/current/Objects/stringobject.c
===================================================================
--- vendor/Python/current/Objects/stringobject.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Objects/stringobject.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,5009 @@
+/* String object implementation */
+
+#define PY_SSIZE_T_CLEAN
+
+#include "Python.h"
+
+#include <ctype.h>
+
+#ifdef COUNT_ALLOCS
+int null_strings, one_strings;
+#endif
+
+static PyStringObject *characters[UCHAR_MAX + 1];
+static PyStringObject *nullstring;
+
+/* This dictionary holds all interned strings.  Note that references to
+   strings in this dictionary are *not* counted in the string's ob_refcnt.
+   When the interned string reaches a refcnt of 0 the string deallocation
+   function will delete the reference from this dictionary.
+
+   Another way to look at this is that to say that the actual reference
+   count of a string is:  s->ob_refcnt + (s->ob_sstate?2:0)
+*/
+static PyObject *interned;
+
+/*
+   For both PyString_FromString() and PyString_FromStringAndSize(), the
+   parameter `size' denotes number of characters to allocate, not counting any
+   null terminating character.
+
+   For PyString_FromString(), the parameter `str' points to a null-terminated
+   string containing exactly `size' bytes.
+
+   For PyString_FromStringAndSize(), the parameter the parameter `str' is
+   either NULL or else points to a string containing at least `size' bytes.
+   For PyString_FromStringAndSize(), the string in the `str' parameter does
+   not have to be null-terminated.  (Therefore it is safe to construct a
+   substring by calling `PyString_FromStringAndSize(origstring, substrlen)'.)
+   If `str' is NULL then PyString_FromStringAndSize() will allocate `size+1'
+   bytes (setting the last byte to the null terminating character) and you can
+   fill in the data yourself.  If `str' is non-NULL then the resulting
+   PyString object must be treated as immutable and you must not fill in nor
+   alter the data yourself, since the strings may be shared.
+
+   The PyObject member `op->ob_size', which denotes the number of "extra
+   items" in a variable-size object, will contain the number of bytes
+   allocated for string data, not counting the null terminating character.  It
+   is therefore equal to the equal to the `size' parameter (for
+   PyString_FromStringAndSize()) or the length of the string in the `str'
+   parameter (for PyString_FromString()).
+*/
+PyObject *
+PyString_FromStringAndSize(const char *str, Py_ssize_t size)
+{
+	register PyStringObject *op;
+	assert(size >= 0);
+	if (size == 0 && (op = nullstring) != NULL) {
+#ifdef COUNT_ALLOCS
+		null_strings++;
+#endif
+		Py_INCREF(op);
+		return (PyObject *)op;
+	}
+	if (size == 1 && str != NULL &&
+	    (op = characters[*str & UCHAR_MAX]) != NULL)
+	{
+#ifdef COUNT_ALLOCS
+		one_strings++;
+#endif
+		Py_INCREF(op);
+		return (PyObject *)op;
+	}
+
+	/* Inline PyObject_NewVar */
+	op = (PyStringObject *)PyObject_MALLOC(sizeof(PyStringObject) + size);
+	if (op == NULL)
+		return PyErr_NoMemory();
+	PyObject_INIT_VAR(op, &PyString_Type, size);
+	op->ob_shash = -1;
+	op->ob_sstate = SSTATE_NOT_INTERNED;
+	if (str != NULL)
+		Py_MEMCPY(op->ob_sval, str, size);
+	op->ob_sval[size] = '\0';
+	/* share short strings */
+	if (size == 0) {
+		PyObject *t = (PyObject *)op;
+		PyString_InternInPlace(&t);
+		op = (PyStringObject *)t;
+		nullstring = op;
+		Py_INCREF(op);
+	} else if (size == 1 && str != NULL) {
+		PyObject *t = (PyObject *)op;
+		PyString_InternInPlace(&t);
+		op = (PyStringObject *)t;
+		characters[*str & UCHAR_MAX] = op;
+		Py_INCREF(op);
+	}
+	return (PyObject *) op;
+}
+
+PyObject *
+PyString_FromString(const char *str)
+{
+	register size_t size;
+	register PyStringObject *op;
+
+	assert(str != NULL);
+	size = strlen(str);
+	if (size > PY_SSIZE_T_MAX) {
+		PyErr_SetString(PyExc_OverflowError,
+			"string is too long for a Python string");
+		return NULL;
+	}
+	if (size == 0 && (op = nullstring) != NULL) {
+#ifdef COUNT_ALLOCS
+		null_strings++;
+#endif
+		Py_INCREF(op);
+		return (PyObject *)op;
+	}
+	if (size == 1 && (op = characters[*str & UCHAR_MAX]) != NULL) {
+#ifdef COUNT_ALLOCS
+		one_strings++;
+#endif
+		Py_INCREF(op);
+		return (PyObject *)op;
+	}
+
+	/* Inline PyObject_NewVar */
+	op = (PyStringObject *)PyObject_MALLOC(sizeof(PyStringObject) + size);
+	if (op == NULL)
+		return PyErr_NoMemory();
+	PyObject_INIT_VAR(op, &PyString_Type, size);
+	op->ob_shash = -1;
+	op->ob_sstate = SSTATE_NOT_INTERNED;
+	Py_MEMCPY(op->ob_sval, str, size+1);
+	/* share short strings */
+	if (size == 0) {
+		PyObject *t = (PyObject *)op;
+		PyString_InternInPlace(&t);
+		op = (PyStringObject *)t;
+		nullstring = op;
+		Py_INCREF(op);
+	} else if (size == 1) {
+		PyObject *t = (PyObject *)op;
+		PyString_InternInPlace(&t);
+		op = (PyStringObject *)t;
+		characters[*str & UCHAR_MAX] = op;
+		Py_INCREF(op);
+	}
+	return (PyObject *) op;
+}
+
+PyObject *
+PyString_FromFormatV(const char *format, va_list vargs)
+{
+	va_list count;
+	Py_ssize_t n = 0;
+	const char* f;
+	char *s;
+	PyObject* string;
+
+#ifdef VA_LIST_IS_ARRAY
+	Py_MEMCPY(count, vargs, sizeof(va_list));
+#else
+#ifdef  __va_copy
+	__va_copy(count, vargs);
+#else
+	count = vargs;
+#endif
+#endif
+	/* step 1: figure out how large a buffer we need */
+	for (f = format; *f; f++) {
+		if (*f == '%') {
+			const char* p = f;
+			while (*++f && *f != '%' && !isalpha(Py_CHARMASK(*f)))
+				;
+
+			/* skip the 'l' or 'z' in {%ld, %zd, %lu, %zu} since
+			 * they don't affect the amount of space we reserve.
+			 */
+			if ((*f == 'l' || *f == 'z') &&
+					(f[1] == 'd' || f[1] == 'u'))
+				++f;
+
+			switch (*f) {
+			case 'c':
+				(void)va_arg(count, int);
+				/* fall through... */
+			case '%':
+				n++;
+				break;
+			case 'd': case 'u': case 'i': case 'x':
+				(void) va_arg(count, int);
+				/* 20 bytes is enough to hold a 64-bit
+				   integer.  Decimal takes the most space.
+				   This isn't enough for octal. */
+				n += 20;
+				break;
+			case 's':
+				s = va_arg(count, char*);
+				n += strlen(s);
+				break;
+			case 'p':
+				(void) va_arg(count, int);
+				/* maximum 64-bit pointer representation:
+				 * 0xffffffffffffffff
+				 * so 19 characters is enough.
+				 * XXX I count 18 -- what's the extra for?
+				 */
+				n += 19;
+				break;
+			default:
+				/* if we stumble upon an unknown
+				   formatting code, copy the rest of
+				   the format string to the output
+				   string. (we cannot just skip the
+				   code, since there's no way to know
+				   what's in the argument list) */
+				n += strlen(p);
+				goto expand;
+			}
+		} else
+			n++;
+	}
+ expand:
+	/* step 2: fill the buffer */
+	/* Since we've analyzed how much space we need for the worst case,
+	   use sprintf directly instead of the slower PyOS_snprintf. */
+	string = PyString_FromStringAndSize(NULL, n);
+	if (!string)
+		return NULL;
+
+	s = PyString_AsString(string);
+
+	for (f = format; *f; f++) {
+		if (*f == '%') {
+			const char* p = f++;
+			Py_ssize_t i;
+			int longflag = 0;
+			int size_tflag = 0;
+			/* parse the width.precision part (we're only
+			   interested in the precision value, if any) */
+			n = 0;
+			while (isdigit(Py_CHARMASK(*f)))
+				n = (n*10) + *f++ - '0';
+			if (*f == '.') {
+				f++;
+				n = 0;
+				while (isdigit(Py_CHARMASK(*f)))
+					n = (n*10) + *f++ - '0';
+			}
+			while (*f && *f != '%' && !isalpha(Py_CHARMASK(*f)))
+				f++;
+			/* handle the long flag, but only for %ld and %lu.
+			   others can be added when necessary. */
+			if (*f == 'l' && (f[1] == 'd' || f[1] == 'u')) {
+				longflag = 1;
+				++f;
+			}
+			/* handle the size_t flag. */
+			if (*f == 'z' && (f[1] == 'd' || f[1] == 'u')) {
+				size_tflag = 1;
+				++f;
+			}
+
+			switch (*f) {
+			case 'c':
+				*s++ = va_arg(vargs, int);
+				break;
+			case 'd':
+				if (longflag)
+					sprintf(s, "%ld", va_arg(vargs, long));
+				else if (size_tflag)
+					sprintf(s, "%" PY_FORMAT_SIZE_T "d",
+					        va_arg(vargs, Py_ssize_t));
+				else
+					sprintf(s, "%d", va_arg(vargs, int));
+				s += strlen(s);
+				break;
+			case 'u':
+				if (longflag)
+					sprintf(s, "%lu",
+						va_arg(vargs, unsigned long));
+				else if (size_tflag)
+					sprintf(s, "%" PY_FORMAT_SIZE_T "u",
+					        va_arg(vargs, size_t));
+				else
+					sprintf(s, "%u",
+						va_arg(vargs, unsigned int));
+				s += strlen(s);
+				break;
+			case 'i':
+				sprintf(s, "%i", va_arg(vargs, int));
+				s += strlen(s);
+				break;
+			case 'x':
+				sprintf(s, "%x", va_arg(vargs, int));
+				s += strlen(s);
+				break;
+			case 's':
+				p = va_arg(vargs, char*);
+				i = strlen(p);
+				if (n > 0 && i > n)
+					i = n;
+				Py_MEMCPY(s, p, i);
+				s += i;
+				break;
+			case 'p':
+				sprintf(s, "%p", va_arg(vargs, void*));
+				/* %p is ill-defined:  ensure leading 0x. */
+				if (s[1] == 'X')
+					s[1] = 'x';
+				else if (s[1] != 'x') {
+					memmove(s+2, s, strlen(s)+1);
+					s[0] = '0';
+					s[1] = 'x';
+				}
+				s += strlen(s);
+				break;
+			case '%':
+				*s++ = '%';
+				break;
+			default:
+				strcpy(s, p);
+				s += strlen(s);
+				goto end;
+			}
+		} else
+			*s++ = *f;
+	}
+
+ end:
+	_PyString_Resize(&string, s - PyString_AS_STRING(string));
+	return string;
+}
+
+PyObject *
+PyString_FromFormat(const char *format, ...)
+{
+	PyObject* ret;
+	va_list vargs;
+
+#ifdef HAVE_STDARG_PROTOTYPES
+	va_start(vargs, format);
+#else
+	va_start(vargs);
+#endif
+	ret = PyString_FromFormatV(format, vargs);
+	va_end(vargs);
+	return ret;
+}
+
+
+PyObject *PyString_Decode(const char *s,
+			  Py_ssize_t size,
+			  const char *encoding,
+			  const char *errors)
+{
+    PyObject *v, *str;
+
+    str = PyString_FromStringAndSize(s, size);
+    if (str == NULL)
+	return NULL;
+    v = PyString_AsDecodedString(str, encoding, errors);
+    Py_DECREF(str);
+    return v;
+}
+
+PyObject *PyString_AsDecodedObject(PyObject *str,
+				   const char *encoding,
+				   const char *errors)
+{
+    PyObject *v;
+
+    if (!PyString_Check(str)) {
+        PyErr_BadArgument();
+        goto onError;
+    }
+
+    if (encoding == NULL) {
+#ifdef Py_USING_UNICODE
+	encoding = PyUnicode_GetDefaultEncoding();
+#else
+	PyErr_SetString(PyExc_ValueError, "no encoding specified");
+	goto onError;
+#endif
+    }
+
+    /* Decode via the codec registry */
+    v = PyCodec_Decode(str, encoding, errors);
+    if (v == NULL)
+        goto onError;
+
+    return v;
+
+ onError:
+    return NULL;
+}
+
+PyObject *PyString_AsDecodedString(PyObject *str,
+				   const char *encoding,
+				   const char *errors)
+{
+    PyObject *v;
+
+    v = PyString_AsDecodedObject(str, encoding, errors);
+    if (v == NULL)
+        goto onError;
+
+#ifdef Py_USING_UNICODE
+    /* Convert Unicode to a string using the default encoding */
+    if (PyUnicode_Check(v)) {
+	PyObject *temp = v;
+	v = PyUnicode_AsEncodedString(v, NULL, NULL);
+	Py_DECREF(temp);
+	if (v == NULL)
+	    goto onError;
+    }
+#endif
+    if (!PyString_Check(v)) {
+        PyErr_Format(PyExc_TypeError,
+                     "decoder did not return a string object (type=%.400s)",
+                     v->ob_type->tp_name);
+        Py_DECREF(v);
+        goto onError;
+    }
+
+    return v;
+
+ onError:
+    return NULL;
+}
+
+PyObject *PyString_Encode(const char *s,
+			  Py_ssize_t size,
+			  const char *encoding,
+			  const char *errors)
+{
+    PyObject *v, *str;
+
+    str = PyString_FromStringAndSize(s, size);
+    if (str == NULL)
+	return NULL;
+    v = PyString_AsEncodedString(str, encoding, errors);
+    Py_DECREF(str);
+    return v;
+}
+
+PyObject *PyString_AsEncodedObject(PyObject *str,
+				   const char *encoding,
+				   const char *errors)
+{
+    PyObject *v;
+
+    if (!PyString_Check(str)) {
+        PyErr_BadArgument();
+        goto onError;
+    }
+
+    if (encoding == NULL) {
+#ifdef Py_USING_UNICODE
+	encoding = PyUnicode_GetDefaultEncoding();
+#else
+	PyErr_SetString(PyExc_ValueError, "no encoding specified");
+	goto onError;
+#endif
+    }
+
+    /* Encode via the codec registry */
+    v = PyCodec_Encode(str, encoding, errors);
+    if (v == NULL)
+        goto onError;
+
+    return v;
+
+ onError:
+    return NULL;
+}
+
+PyObject *PyString_AsEncodedString(PyObject *str,
+				   const char *encoding,
+				   const char *errors)
+{
+    PyObject *v;
+
+    v = PyString_AsEncodedObject(str, encoding, errors);
+    if (v == NULL)
+        goto onError;
+
+#ifdef Py_USING_UNICODE
+    /* Convert Unicode to a string using the default encoding */
+    if (PyUnicode_Check(v)) {
+	PyObject *temp = v;
+	v = PyUnicode_AsEncodedString(v, NULL, NULL);
+	Py_DECREF(temp);
+	if (v == NULL)
+	    goto onError;
+    }
+#endif
+    if (!PyString_Check(v)) {
+        PyErr_Format(PyExc_TypeError,
+                     "encoder did not return a string object (type=%.400s)",
+                     v->ob_type->tp_name);
+        Py_DECREF(v);
+        goto onError;
+    }
+
+    return v;
+
+ onError:
+    return NULL;
+}
+
+static void
+string_dealloc(PyObject *op)
+{
+	switch (PyString_CHECK_INTERNED(op)) {
+		case SSTATE_NOT_INTERNED:
+			break;
+
+		case SSTATE_INTERNED_MORTAL:
+			/* revive dead object temporarily for DelItem */
+			op->ob_refcnt = 3;
+			if (PyDict_DelItem(interned, op) != 0)
+				Py_FatalError(
+					"deletion of interned string failed");
+			break;
+
+		case SSTATE_INTERNED_IMMORTAL:
+			Py_FatalError("Immortal interned string died.");
+
+		default:
+			Py_FatalError("Inconsistent interned string state.");
+	}
+	op->ob_type->tp_free(op);
+}
+
+/* Unescape a backslash-escaped string. If unicode is non-zero,
+   the string is a u-literal. If recode_encoding is non-zero,
+   the string is UTF-8 encoded and should be re-encoded in the
+   specified encoding.  */
+
+PyObject *PyString_DecodeEscape(const char *s,
+				Py_ssize_t len,
+				const char *errors,
+				Py_ssize_t unicode,
+				const char *recode_encoding)
+{
+	int c;
+	char *p, *buf;
+	const char *end;
+	PyObject *v;
+	Py_ssize_t newlen = recode_encoding ? 4*len:len;
+	v = PyString_FromStringAndSize((char *)NULL, newlen);
+	if (v == NULL)
+		return NULL;
+	p = buf = PyString_AsString(v);
+	end = s + len;
+	while (s < end) {
+		if (*s != '\\') {
+		  non_esc:
+#ifdef Py_USING_UNICODE
+			if (recode_encoding && (*s & 0x80)) {
+				PyObject *u, *w;
+				char *r;
+				const char* t;
+				Py_ssize_t rn;
+				t = s;
+				/* Decode non-ASCII bytes as UTF-8. */
+				while (t < end && (*t & 0x80)) t++;
+				u = PyUnicode_DecodeUTF8(s, t - s, errors);
+				if(!u) goto failed;
+
+				/* Recode them in target encoding. */
+				w = PyUnicode_AsEncodedString(
+					u, recode_encoding, errors);
+				Py_DECREF(u);
+				if (!w)	goto failed;
+
+				/* Append bytes to output buffer. */
+				assert(PyString_Check(w));
+				r = PyString_AS_STRING(w);
+				rn = PyString_GET_SIZE(w);
+				Py_MEMCPY(p, r, rn);
+				p += rn;
+				Py_DECREF(w);
+				s = t;
+			} else {
+				*p++ = *s++;
+			}
+#else
+			*p++ = *s++;
+#endif
+			continue;
+		}
+		s++;
+                if (s==end) {
+			PyErr_SetString(PyExc_ValueError,
+					"Trailing \\ in string");
+			goto failed;
+		}
+		switch (*s++) {
+		/* XXX This assumes ASCII! */
+		case '\n': break;
+		case '\\': *p++ = '\\'; break;
+		case '\'': *p++ = '\''; break;
+		case '\"': *p++ = '\"'; break;
+		case 'b': *p++ = '\b'; break;
+		case 'f': *p++ = '\014'; break; /* FF */
+		case 't': *p++ = '\t'; break;
+		case 'n': *p++ = '\n'; break;
+		case 'r': *p++ = '\r'; break;
+		case 'v': *p++ = '\013'; break; /* VT */
+		case 'a': *p++ = '\007'; break; /* BEL, not classic C */
+		case '0': case '1': case '2': case '3':
+		case '4': case '5': case '6': case '7':
+			c = s[-1] - '0';
+			if ('0' <= *s && *s <= '7') {
+				c = (c<<3) + *s++ - '0';
+				if ('0' <= *s && *s <= '7')
+					c = (c<<3) + *s++ - '0';
+			}
+			*p++ = c;
+			break;
+		case 'x':
+			if (isxdigit(Py_CHARMASK(s[0]))
+			    && isxdigit(Py_CHARMASK(s[1]))) {
+				unsigned int x = 0;
+				c = Py_CHARMASK(*s);
+				s++;
+				if (isdigit(c))
+					x = c - '0';
+				else if (islower(c))
+					x = 10 + c - 'a';
+				else
+					x = 10 + c - 'A';
+				x = x << 4;
+				c = Py_CHARMASK(*s);
+				s++;
+				if (isdigit(c))
+					x += c - '0';
+				else if (islower(c))
+					x += 10 + c - 'a';
+				else
+					x += 10 + c - 'A';
+				*p++ = x;
+				break;
+			}
+			if (!errors || strcmp(errors, "strict") == 0) {
+				PyErr_SetString(PyExc_ValueError,
+						"invalid \\x escape");
+				goto failed;
+			}
+			if (strcmp(errors, "replace") == 0) {
+				*p++ = '?';
+			} else if (strcmp(errors, "ignore") == 0)
+				/* do nothing */;
+			else {
+				PyErr_Format(PyExc_ValueError,
+					     "decoding error; "
+					     "unknown error handling code: %.400s",
+					     errors);
+				goto failed;
+			}
+#ifndef Py_USING_UNICODE
+		case 'u':
+		case 'U':
+		case 'N':
+			if (unicode) {
+				PyErr_SetString(PyExc_ValueError,
+					  "Unicode escapes not legal "
+					  "when Unicode disabled");
+				goto failed;
+			}
+#endif
+		default:
+			*p++ = '\\';
+			s--;
+			goto non_esc; /* an arbitry number of unescaped
+					 UTF-8 bytes may follow. */
+		}
+	}
+	if (p-buf < newlen)
+		_PyString_Resize(&v, p - buf);
+	return v;
+  failed:
+	Py_DECREF(v);
+	return NULL;
+}
+
+/* -------------------------------------------------------------------- */
+/* object api */
+
+static Py_ssize_t
+string_getsize(register PyObject *op)
+{
+    	char *s;
+    	Py_ssize_t len;
+	if (PyString_AsStringAndSize(op, &s, &len))
+		return -1;
+	return len;
+}
+
+static /*const*/ char *
+string_getbuffer(register PyObject *op)
+{
+    	char *s;
+    	Py_ssize_t len;
+	if (PyString_AsStringAndSize(op, &s, &len))
+		return NULL;
+	return s;
+}
+
+Py_ssize_t
+PyString_Size(register PyObject *op)
+{
+	if (!PyString_Check(op))
+		return string_getsize(op);
+	return ((PyStringObject *)op) -> ob_size;
+}
+
+/*const*/ char *
+PyString_AsString(register PyObject *op)
+{
+	if (!PyString_Check(op))
+		return string_getbuffer(op);
+	return ((PyStringObject *)op) -> ob_sval;
+}
+
+int
+PyString_AsStringAndSize(register PyObject *obj,
+			 register char **s,
+			 register Py_ssize_t *len)
+{
+	if (s == NULL) {
+		PyErr_BadInternalCall();
+		return -1;
+	}
+
+	if (!PyString_Check(obj)) {
+#ifdef Py_USING_UNICODE
+		if (PyUnicode_Check(obj)) {
+			obj = _PyUnicode_AsDefaultEncodedString(obj, NULL);
+			if (obj == NULL)
+				return -1;
+		}
+		else
+#endif
+		{
+			PyErr_Format(PyExc_TypeError,
+				     "expected string or Unicode object, "
+				     "%.200s found", obj->ob_type->tp_name);
+			return -1;
+		}
+	}
+
+	*s = PyString_AS_STRING(obj);
+	if (len != NULL)
+		*len = PyString_GET_SIZE(obj);
+	else if (strlen(*s) != (size_t)PyString_GET_SIZE(obj)) {
+		PyErr_SetString(PyExc_TypeError,
+				"expected string without null bytes");
+		return -1;
+	}
+	return 0;
+}
+
+/* -------------------------------------------------------------------- */
+/* Methods */
+
+#define STRINGLIB_CHAR char
+
+#define STRINGLIB_CMP memcmp
+#define STRINGLIB_LEN PyString_GET_SIZE
+#define STRINGLIB_NEW PyString_FromStringAndSize
+#define STRINGLIB_STR PyString_AS_STRING
+
+#define STRINGLIB_EMPTY nullstring
+
+#include "stringlib/fastsearch.h"
+
+#include "stringlib/count.h"
+#include "stringlib/find.h"
+#include "stringlib/partition.h"
+
+
+static int
+string_print(PyStringObject *op, FILE *fp, int flags)
+{
+	Py_ssize_t i;
+	char c;
+	int quote;
+
+	/* XXX Ought to check for interrupts when writing long strings */
+	if (! PyString_CheckExact(op)) {
+		int ret;
+		/* A str subclass may have its own __str__ method. */
+		op = (PyStringObject *) PyObject_Str((PyObject *)op);
+		if (op == NULL)
+			return -1;
+		ret = string_print(op, fp, flags);
+		Py_DECREF(op);
+		return ret;
+	}
+	if (flags & Py_PRINT_RAW) {
+		char *data = op->ob_sval;
+		Py_ssize_t size = op->ob_size;
+		while (size > INT_MAX) {
+			/* Very long strings cannot be written atomically.
+			 * But don't write exactly INT_MAX bytes at a time
+			 * to avoid memory aligment issues.
+			 */
+			const int chunk_size = INT_MAX & ~0x3FFF;
+			fwrite(data, 1, chunk_size, fp);
+			data += chunk_size;
+			size -= chunk_size;
+		}
+#ifdef __VMS
+                if (size) fwrite(data, (int)size, 1, fp);
+#else
+                fwrite(data, 1, (int)size, fp);
+#endif
+		return 0;
+	}
+
+	/* figure out which quote to use; single is preferred */
+	quote = '\'';
+	if (memchr(op->ob_sval, '\'', op->ob_size) &&
+	    !memchr(op->ob_sval, '"', op->ob_size))
+		quote = '"';
+
+	fputc(quote, fp);
+	for (i = 0; i < op->ob_size; i++) {
+		c = op->ob_sval[i];
+		if (c == quote || c == '\\')
+			fprintf(fp, "\\%c", c);
+                else if (c == '\t')
+                        fprintf(fp, "\\t");
+                else if (c == '\n')
+                        fprintf(fp, "\\n");
+                else if (c == '\r')
+                        fprintf(fp, "\\r");
+		else if (c < ' ' || c >= 0x7f)
+			fprintf(fp, "\\x%02x", c & 0xff);
+		else
+			fputc(c, fp);
+	}
+	fputc(quote, fp);
+	return 0;
+}
+
+PyObject *
+PyString_Repr(PyObject *obj, int smartquotes)
+{
+	register PyStringObject* op = (PyStringObject*) obj;
+	size_t newsize = 2 + 4 * op->ob_size;
+	PyObject *v;
+	if (newsize > PY_SSIZE_T_MAX || newsize / 4 != op->ob_size) {
+		PyErr_SetString(PyExc_OverflowError,
+			"string is too large to make repr");
+	}
+	v = PyString_FromStringAndSize((char *)NULL, newsize);
+	if (v == NULL) {
+		return NULL;
+	}
+	else {
+		register Py_ssize_t i;
+		register char c;
+		register char *p;
+		int quote;
+
+		/* figure out which quote to use; single is preferred */
+		quote = '\'';
+		if (smartquotes &&
+		    memchr(op->ob_sval, '\'', op->ob_size) &&
+		    !memchr(op->ob_sval, '"', op->ob_size))
+			quote = '"';
+
+		p = PyString_AS_STRING(v);
+		*p++ = quote;
+		for (i = 0; i < op->ob_size; i++) {
+			/* There's at least enough room for a hex escape
+			   and a closing quote. */
+			assert(newsize - (p - PyString_AS_STRING(v)) >= 5);
+			c = op->ob_sval[i];
+			if (c == quote || c == '\\')
+				*p++ = '\\', *p++ = c;
+			else if (c == '\t')
+				*p++ = '\\', *p++ = 't';
+			else if (c == '\n')
+				*p++ = '\\', *p++ = 'n';
+			else if (c == '\r')
+				*p++ = '\\', *p++ = 'r';
+			else if (c < ' ' || c >= 0x7f) {
+				/* For performance, we don't want to call
+				   PyOS_snprintf here (extra layers of
+				   function call). */
+				sprintf(p, "\\x%02x", c & 0xff);
+                                p += 4;
+			}
+			else
+				*p++ = c;
+		}
+		assert(newsize - (p - PyString_AS_STRING(v)) >= 1);
+		*p++ = quote;
+		*p = '\0';
+		_PyString_Resize(
+			&v, (p - PyString_AS_STRING(v)));
+		return v;
+	}
+}
+
+static PyObject *
+string_repr(PyObject *op)
+{
+	return PyString_Repr(op, 1);
+}
+
+static PyObject *
+string_str(PyObject *s)
+{
+	assert(PyString_Check(s));
+	if (PyString_CheckExact(s)) {
+		Py_INCREF(s);
+		return s;
+	}
+	else {
+		/* Subtype -- return genuine string with the same value. */
+		PyStringObject *t = (PyStringObject *) s;
+		return PyString_FromStringAndSize(t->ob_sval, t->ob_size);
+	}
+}
+
+static Py_ssize_t
+string_length(PyStringObject *a)
+{
+	return a->ob_size;
+}
+
+static PyObject *
+string_concat(register PyStringObject *a, register PyObject *bb)
+{
+	register Py_ssize_t size;
+	register PyStringObject *op;
+	if (!PyString_Check(bb)) {
+#ifdef Py_USING_UNICODE
+		if (PyUnicode_Check(bb))
+		    return PyUnicode_Concat((PyObject *)a, bb);
+#endif
+		PyErr_Format(PyExc_TypeError,
+			     "cannot concatenate 'str' and '%.200s' objects",
+			     bb->ob_type->tp_name);
+		return NULL;
+	}
+#define b ((PyStringObject *)bb)
+	/* Optimize cases with empty left or right operand */
+	if ((a->ob_size == 0 || b->ob_size == 0) &&
+	    PyString_CheckExact(a) && PyString_CheckExact(b)) {
+		if (a->ob_size == 0) {
+			Py_INCREF(bb);
+			return bb;
+		}
+		Py_INCREF(a);
+		return (PyObject *)a;
+	}
+	size = a->ob_size + b->ob_size;
+	if (size < 0) {
+		PyErr_SetString(PyExc_OverflowError,
+				"strings are too large to concat");
+		return NULL;
+	}
+	  
+	/* Inline PyObject_NewVar */
+	op = (PyStringObject *)PyObject_MALLOC(sizeof(PyStringObject) + size);
+	if (op == NULL)
+		return PyErr_NoMemory();
+	PyObject_INIT_VAR(op, &PyString_Type, size);
+	op->ob_shash = -1;
+	op->ob_sstate = SSTATE_NOT_INTERNED;
+	Py_MEMCPY(op->ob_sval, a->ob_sval, a->ob_size);
+	Py_MEMCPY(op->ob_sval + a->ob_size, b->ob_sval, b->ob_size);
+	op->ob_sval[size] = '\0';
+	return (PyObject *) op;
+#undef b
+}
+
+static PyObject *
+string_repeat(register PyStringObject *a, register Py_ssize_t n)
+{
+	register Py_ssize_t i;
+	register Py_ssize_t j;
+	register Py_ssize_t size;
+	register PyStringObject *op;
+	size_t nbytes;
+	if (n < 0)
+		n = 0;
+	/* watch out for overflows:  the size can overflow int,
+	 * and the # of bytes needed can overflow size_t
+	 */
+	size = a->ob_size * n;
+	if (n && size / n != a->ob_size) {
+		PyErr_SetString(PyExc_OverflowError,
+			"repeated string is too long");
+		return NULL;
+	}
+	if (size == a->ob_size && PyString_CheckExact(a)) {
+		Py_INCREF(a);
+		return (PyObject *)a;
+	}
+	nbytes = (size_t)size;
+	if (nbytes + sizeof(PyStringObject) <= nbytes) {
+		PyErr_SetString(PyExc_OverflowError,
+			"repeated string is too long");
+		return NULL;
+	}
+	op = (PyStringObject *)
+		PyObject_MALLOC(sizeof(PyStringObject) + nbytes);
+	if (op == NULL)
+		return PyErr_NoMemory();
+	PyObject_INIT_VAR(op, &PyString_Type, size);
+	op->ob_shash = -1;
+	op->ob_sstate = SSTATE_NOT_INTERNED;
+	op->ob_sval[size] = '\0';
+	if (a->ob_size == 1 && n > 0) {
+		memset(op->ob_sval, a->ob_sval[0] , n);
+		return (PyObject *) op;
+	}
+	i = 0;
+	if (i < size) {
+		Py_MEMCPY(op->ob_sval, a->ob_sval, a->ob_size);
+		i = a->ob_size;
+	}
+	while (i < size) {
+		j = (i <= size-i)  ?  i  :  size-i;
+		Py_MEMCPY(op->ob_sval+i, op->ob_sval, j);
+		i += j;
+	}
+	return (PyObject *) op;
+}
+
+/* String slice a[i:j] consists of characters a[i] ... a[j-1] */
+
+static PyObject *
+string_slice(register PyStringObject *a, register Py_ssize_t i,
+	     register Py_ssize_t j)
+     /* j -- may be negative! */
+{
+	if (i < 0)
+		i = 0;
+	if (j < 0)
+		j = 0; /* Avoid signed/unsigned bug in next line */
+	if (j > a->ob_size)
+		j = a->ob_size;
+	if (i == 0 && j == a->ob_size && PyString_CheckExact(a)) {
+		/* It's the same as a */
+		Py_INCREF(a);
+		return (PyObject *)a;
+	}
+	if (j < i)
+		j = i;
+	return PyString_FromStringAndSize(a->ob_sval + i, j-i);
+}
+
+static int
+string_contains(PyObject *str_obj, PyObject *sub_obj)
+{
+	if (!PyString_CheckExact(sub_obj)) {
+#ifdef Py_USING_UNICODE
+		if (PyUnicode_Check(sub_obj))
+			return PyUnicode_Contains(str_obj, sub_obj);
+#endif
+		if (!PyString_Check(sub_obj)) {
+			PyErr_SetString(PyExc_TypeError,
+			    "'in <string>' requires string as left operand");
+			return -1;
+		}
+	}
+
+	return stringlib_contains_obj(str_obj, sub_obj);
+}
+
+static PyObject *
+string_item(PyStringObject *a, register Py_ssize_t i)
+{
+	char pchar;
+	PyObject *v;
+	if (i < 0 || i >= a->ob_size) {
+		PyErr_SetString(PyExc_IndexError, "string index out of range");
+		return NULL;
+	}
+	pchar = a->ob_sval[i];
+	v = (PyObject *)characters[pchar & UCHAR_MAX];
+	if (v == NULL)
+		v = PyString_FromStringAndSize(&pchar, 1);
+	else {
+#ifdef COUNT_ALLOCS
+		one_strings++;
+#endif
+		Py_INCREF(v);
+	}
+	return v;
+}
+
+static PyObject*
+string_richcompare(PyStringObject *a, PyStringObject *b, int op)
+{
+	int c;
+	Py_ssize_t len_a, len_b;
+	Py_ssize_t min_len;
+	PyObject *result;
+
+	/* Make sure both arguments are strings. */
+	if (!(PyString_Check(a) && PyString_Check(b))) {
+		result = Py_NotImplemented;
+		goto out;
+	}
+	if (a == b) {
+		switch (op) {
+		case Py_EQ:case Py_LE:case Py_GE:
+			result = Py_True;
+			goto out;
+		case Py_NE:case Py_LT:case Py_GT:
+			result = Py_False;
+			goto out;
+		}
+	}
+	if (op == Py_EQ) {
+		/* Supporting Py_NE here as well does not save
+		   much time, since Py_NE is rarely used.  */
+		if (a->ob_size == b->ob_size
+		    && (a->ob_sval[0] == b->ob_sval[0]
+			&& memcmp(a->ob_sval, b->ob_sval,
+				  a->ob_size) == 0)) {
+			result = Py_True;
+		} else {
+			result = Py_False;
+		}
+		goto out;
+	}
+	len_a = a->ob_size; len_b = b->ob_size;
+	min_len = (len_a < len_b) ? len_a : len_b;
+	if (min_len > 0) {
+		c = Py_CHARMASK(*a->ob_sval) - Py_CHARMASK(*b->ob_sval);
+		if (c==0)
+			c = memcmp(a->ob_sval, b->ob_sval, min_len);
+	}else
+		c = 0;
+	if (c == 0)
+		c = (len_a < len_b) ? -1 : (len_a > len_b) ? 1 : 0;
+	switch (op) {
+	case Py_LT: c = c <  0; break;
+	case Py_LE: c = c <= 0; break;
+	case Py_EQ: assert(0);  break; /* unreachable */
+	case Py_NE: c = c != 0; break;
+	case Py_GT: c = c >  0; break;
+	case Py_GE: c = c >= 0; break;
+	default:
+		result = Py_NotImplemented;
+		goto out;
+	}
+	result = c ? Py_True : Py_False;
+  out:
+	Py_INCREF(result);
+	return result;
+}
+
+int
+_PyString_Eq(PyObject *o1, PyObject *o2)
+{
+	PyStringObject *a = (PyStringObject*) o1;
+	PyStringObject *b = (PyStringObject*) o2;
+        return a->ob_size == b->ob_size
+          && *a->ob_sval == *b->ob_sval
+          && memcmp(a->ob_sval, b->ob_sval, a->ob_size) == 0;
+}
+
+static long
+string_hash(PyStringObject *a)
+{
+	register Py_ssize_t len;
+	register unsigned char *p;
+	register long x;
+
+	if (a->ob_shash != -1)
+		return a->ob_shash;
+	len = a->ob_size;
+	p = (unsigned char *) a->ob_sval;
+	x = *p << 7;
+	while (--len >= 0)
+		x = (1000003*x) ^ *p++;
+	x ^= a->ob_size;
+	if (x == -1)
+		x = -2;
+	a->ob_shash = x;
+	return x;
+}
+
+static PyObject*
+string_subscript(PyStringObject* self, PyObject* item)
+{
+	if (PyIndex_Check(item)) {
+		Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+		if (i == -1 && PyErr_Occurred())
+			return NULL;
+		if (i < 0)
+			i += PyString_GET_SIZE(self);
+		return string_item(self, i);
+	}
+	else if (PySlice_Check(item)) {
+		Py_ssize_t start, stop, step, slicelength, cur, i;
+		char* source_buf;
+		char* result_buf;
+		PyObject* result;
+
+		if (PySlice_GetIndicesEx((PySliceObject*)item,
+				 PyString_GET_SIZE(self),
+				 &start, &stop, &step, &slicelength) < 0) {
+			return NULL;
+		}
+
+		if (slicelength <= 0) {
+			return PyString_FromStringAndSize("", 0);
+		}
+		else {
+			source_buf = PyString_AsString((PyObject*)self);
+			result_buf = (char *)PyMem_Malloc(slicelength);
+			if (result_buf == NULL)
+				return PyErr_NoMemory();
+
+			for (cur = start, i = 0; i < slicelength;
+			     cur += step, i++) {
+				result_buf[i] = source_buf[cur];
+			}
+
+			result = PyString_FromStringAndSize(result_buf,
+							    slicelength);
+			PyMem_Free(result_buf);
+			return result;
+		}
+	}
+	else {
+		PyErr_SetString(PyExc_TypeError,
+				"string indices must be integers");
+		return NULL;
+	}
+}
+
+static Py_ssize_t
+string_buffer_getreadbuf(PyStringObject *self, Py_ssize_t index, const void **ptr)
+{
+	if ( index != 0 ) {
+		PyErr_SetString(PyExc_SystemError,
+				"accessing non-existent string segment");
+		return -1;
+	}
+	*ptr = (void *)self->ob_sval;
+	return self->ob_size;
+}
+
+static Py_ssize_t
+string_buffer_getwritebuf(PyStringObject *self, Py_ssize_t index, const void **ptr)
+{
+	PyErr_SetString(PyExc_TypeError,
+			"Cannot use string as modifiable buffer");
+	return -1;
+}
+
+static Py_ssize_t
+string_buffer_getsegcount(PyStringObject *self, Py_ssize_t *lenp)
+{
+	if ( lenp )
+		*lenp = self->ob_size;
+	return 1;
+}
+
+static Py_ssize_t
+string_buffer_getcharbuf(PyStringObject *self, Py_ssize_t index, const char **ptr)
+{
+	if ( index != 0 ) {
+		PyErr_SetString(PyExc_SystemError,
+				"accessing non-existent string segment");
+		return -1;
+	}
+	*ptr = self->ob_sval;
+	return self->ob_size;
+}
+
+static PySequenceMethods string_as_sequence = {
+	(lenfunc)string_length, /*sq_length*/
+	(binaryfunc)string_concat, /*sq_concat*/
+	(ssizeargfunc)string_repeat, /*sq_repeat*/
+	(ssizeargfunc)string_item, /*sq_item*/
+	(ssizessizeargfunc)string_slice, /*sq_slice*/
+	0,		/*sq_ass_item*/
+	0,		/*sq_ass_slice*/
+	(objobjproc)string_contains /*sq_contains*/
+};
+
+static PyMappingMethods string_as_mapping = {
+	(lenfunc)string_length,
+	(binaryfunc)string_subscript,
+	0,
+};
+
+static PyBufferProcs string_as_buffer = {
+	(readbufferproc)string_buffer_getreadbuf,
+	(writebufferproc)string_buffer_getwritebuf,
+	(segcountproc)string_buffer_getsegcount,
+	(charbufferproc)string_buffer_getcharbuf,
+};
+
+
+
+#define LEFTSTRIP 0
+#define RIGHTSTRIP 1
+#define BOTHSTRIP 2
+
+/* Arrays indexed by above */
+static const char *stripformat[] = {"|O:lstrip", "|O:rstrip", "|O:strip"};
+
+#define STRIPNAME(i) (stripformat[i]+3)
+
+
+/* Don't call if length < 2 */
+#define Py_STRING_MATCH(target, offset, pattern, length)	\
+  (target[offset] == pattern[0] &&				\
+   target[offset+length-1] == pattern[length-1] &&		\
+   !memcmp(target+offset+1, pattern+1, length-2) )
+
+
+/* Overallocate the initial list to reduce the number of reallocs for small
+   split sizes.  Eg, "A A A A A A A A A A".split() (10 elements) has three
+   resizes, to sizes 4, 8, then 16.  Most observed string splits are for human
+   text (roughly 11 words per line) and field delimited data (usually 1-10
+   fields).  For large strings the split algorithms are bandwidth limited
+   so increasing the preallocation likely will not improve things.*/
+
+#define MAX_PREALLOC 12
+
+/* 5 splits gives 6 elements */
+#define PREALLOC_SIZE(maxsplit) \
+	(maxsplit >= MAX_PREALLOC ? MAX_PREALLOC : maxsplit+1)
+
+#define SPLIT_APPEND(data, left, right)				\
+	str = PyString_FromStringAndSize((data) + (left),	\
+					 (right) - (left));	\
+	if (str == NULL)					\
+		goto onError;					\
+	if (PyList_Append(list, str)) {				\
+		Py_DECREF(str);					\
+		goto onError;					\
+	}							\
+	else							\
+		Py_DECREF(str);
+
+#define SPLIT_ADD(data, left, right) {				\
+	str = PyString_FromStringAndSize((data) + (left),	\
+					 (right) - (left));	\
+	if (str == NULL)					\
+		goto onError;					\
+	if (count < MAX_PREALLOC) {				\
+		PyList_SET_ITEM(list, count, str);		\
+	} else {						\
+		if (PyList_Append(list, str)) {			\
+			Py_DECREF(str);				\
+			goto onError;				\
+		}						\
+		else						\
+			Py_DECREF(str);				\
+	}							\
+	count++; }
+
+/* Always force the list to the expected size. */
+#define FIX_PREALLOC_SIZE(list) ((PyListObject *)list)->ob_size = count
+
+#define SKIP_SPACE(s, i, len)    { while (i<len &&  isspace(Py_CHARMASK(s[i]))) i++; }
+#define SKIP_NONSPACE(s, i, len) { while (i<len && !isspace(Py_CHARMASK(s[i]))) i++; }
+#define RSKIP_SPACE(s, i)        { while (i>=0  &&  isspace(Py_CHARMASK(s[i]))) i--; }
+#define RSKIP_NONSPACE(s, i)     { while (i>=0  && !isspace(Py_CHARMASK(s[i]))) i--; }
+
+Py_LOCAL_INLINE(PyObject *)
+split_whitespace(const char *s, Py_ssize_t len, Py_ssize_t maxsplit)
+{
+	Py_ssize_t i, j, count=0;
+	PyObject *str;
+	PyObject *list = PyList_New(PREALLOC_SIZE(maxsplit));
+
+	if (list == NULL)
+		return NULL;
+
+	i = j = 0;
+
+	while (maxsplit-- > 0) {
+		SKIP_SPACE(s, i, len);
+		if (i==len) break;
+		j = i; i++;
+		SKIP_NONSPACE(s, i, len);
+		SPLIT_ADD(s, j, i);
+	}
+
+	if (i < len) {
+		/* Only occurs when maxsplit was reached */
+		/* Skip any remaining whitespace and copy to end of string */
+		SKIP_SPACE(s, i, len);
+		if (i != len)
+			SPLIT_ADD(s, i, len);
+	}
+	FIX_PREALLOC_SIZE(list);
+	return list;
+  onError:
+	Py_DECREF(list);
+	return NULL;
+}
+
+Py_LOCAL_INLINE(PyObject *)
+split_char(const char *s, Py_ssize_t len, char ch, Py_ssize_t maxcount)
+{
+	register Py_ssize_t i, j, count=0;
+	PyObject *str;
+	PyObject *list = PyList_New(PREALLOC_SIZE(maxcount));
+
+	if (list == NULL)
+		return NULL;
+
+	i = j = 0;
+	while ((j < len) && (maxcount-- > 0)) {
+		for(; j<len; j++) {
+			/* I found that using memchr makes no difference */
+			if (s[j] == ch) {
+				SPLIT_ADD(s, i, j);
+				i = j = j + 1;
+				break;
+			}
+		}
+	}
+	if (i <= len) {
+		SPLIT_ADD(s, i, len);
+	}
+	FIX_PREALLOC_SIZE(list);
+	return list;
+
+  onError:
+	Py_DECREF(list);
+	return NULL;
+}
+
+PyDoc_STRVAR(split__doc__,
+"S.split([sep [,maxsplit]]) -> list of strings\n\
+\n\
+Return a list of the words in the string S, using sep as the\n\
+delimiter string.  If maxsplit is given, at most maxsplit\n\
+splits are done. If sep is not specified or is None, any\n\
+whitespace string is a separator.");
+
+static PyObject *
+string_split(PyStringObject *self, PyObject *args)
+{
+	Py_ssize_t len = PyString_GET_SIZE(self), n, i, j;
+	Py_ssize_t maxsplit = -1, count=0;
+	const char *s = PyString_AS_STRING(self), *sub;
+	PyObject *list, *str, *subobj = Py_None;
+#ifdef USE_FAST
+	Py_ssize_t pos;
+#endif
+
+	if (!PyArg_ParseTuple(args, "|On:split", &subobj, &maxsplit))
+		return NULL;
+	if (maxsplit < 0)
+		maxsplit = PY_SSIZE_T_MAX;
+	if (subobj == Py_None)
+		return split_whitespace(s, len, maxsplit);
+	if (PyString_Check(subobj)) {
+		sub = PyString_AS_STRING(subobj);
+		n = PyString_GET_SIZE(subobj);
+	}
+#ifdef Py_USING_UNICODE
+	else if (PyUnicode_Check(subobj))
+		return PyUnicode_Split((PyObject *)self, subobj, maxsplit);
+#endif
+	else if (PyObject_AsCharBuffer(subobj, &sub, &n))
+		return NULL;
+
+	if (n == 0) {
+		PyErr_SetString(PyExc_ValueError, "empty separator");
+		return NULL;
+	}
+	else if (n == 1)
+		return split_char(s, len, sub[0], maxsplit);
+
+	list = PyList_New(PREALLOC_SIZE(maxsplit));
+	if (list == NULL)
+		return NULL;
+
+#ifdef USE_FAST
+	i = j = 0;
+	while (maxsplit-- > 0) {
+		pos = fastsearch(s+i, len-i, sub, n, FAST_SEARCH);
+		if (pos < 0)
+			break;
+		j = i+pos;
+		SPLIT_ADD(s, i, j);
+		i = j + n;
+	}
+#else
+	i = j = 0;
+	while ((j+n <= len) && (maxsplit-- > 0)) {
+		for (; j+n <= len; j++) {
+			if (Py_STRING_MATCH(s, j, sub, n)) {
+				SPLIT_ADD(s, i, j);
+				i = j = j + n;
+				break;
+			}
+		}
+	}
+#endif
+	SPLIT_ADD(s, i, len);
+	FIX_PREALLOC_SIZE(list);
+	return list;
+
+ onError:
+	Py_DECREF(list);
+	return NULL;
+}
+
+PyDoc_STRVAR(partition__doc__,
+"S.partition(sep) -> (head, sep, tail)\n\
+\n\
+Searches for the separator sep in S, and returns the part before it,\n\
+the separator itself, and the part after it.  If the separator is not\n\
+found, returns S and two empty strings.");
+
+static PyObject *
+string_partition(PyStringObject *self, PyObject *sep_obj)
+{
+	const char *sep;
+	Py_ssize_t sep_len;
+
+	if (PyString_Check(sep_obj)) {
+		sep = PyString_AS_STRING(sep_obj);
+		sep_len = PyString_GET_SIZE(sep_obj);
+	}
+#ifdef Py_USING_UNICODE
+	else if (PyUnicode_Check(sep_obj))
+		return PyUnicode_Partition((PyObject *) self, sep_obj);
+#endif
+	else if (PyObject_AsCharBuffer(sep_obj, &sep, &sep_len))
+		return NULL;
+
+	return stringlib_partition(
+		(PyObject*) self,
+		PyString_AS_STRING(self), PyString_GET_SIZE(self),
+		sep_obj, sep, sep_len
+		);
+}
+
+PyDoc_STRVAR(rpartition__doc__,
+"S.rpartition(sep) -> (tail, sep, head)\n\
+\n\
+Searches for the separator sep in S, starting at the end of S, and returns\n\
+the part before it, the separator itself, and the part after it.  If the\n\
+separator is not found, returns two empty strings and S.");
+
+static PyObject *
+string_rpartition(PyStringObject *self, PyObject *sep_obj)
+{
+	const char *sep;
+	Py_ssize_t sep_len;
+
+	if (PyString_Check(sep_obj)) {
+		sep = PyString_AS_STRING(sep_obj);
+		sep_len = PyString_GET_SIZE(sep_obj);
+	}
+#ifdef Py_USING_UNICODE
+	else if (PyUnicode_Check(sep_obj))
+		return PyUnicode_Partition((PyObject *) self, sep_obj);
+#endif
+	else if (PyObject_AsCharBuffer(sep_obj, &sep, &sep_len))
+		return NULL;
+
+	return stringlib_rpartition(
+		(PyObject*) self,
+		PyString_AS_STRING(self), PyString_GET_SIZE(self),
+		sep_obj, sep, sep_len
+		);
+}
+
+Py_LOCAL_INLINE(PyObject *)
+rsplit_whitespace(const char *s, Py_ssize_t len, Py_ssize_t maxsplit)
+{
+	Py_ssize_t i, j, count=0;
+	PyObject *str;
+	PyObject *list = PyList_New(PREALLOC_SIZE(maxsplit));
+
+	if (list == NULL)
+		return NULL;
+
+	i = j = len-1;
+
+	while (maxsplit-- > 0) {
+		RSKIP_SPACE(s, i);
+		if (i<0) break;
+		j = i; i--;
+		RSKIP_NONSPACE(s, i);
+		SPLIT_ADD(s, i + 1, j + 1);
+	}
+	if (i >= 0) {
+		/* Only occurs when maxsplit was reached */
+		/* Skip any remaining whitespace and copy to beginning of string */
+		RSKIP_SPACE(s, i);
+		if (i >= 0)
+			SPLIT_ADD(s, 0, i + 1);
+
+	}
+	FIX_PREALLOC_SIZE(list);
+	if (PyList_Reverse(list) < 0)
+		goto onError;
+	return list;
+  onError:
+	Py_DECREF(list);
+	return NULL;
+}
+
+Py_LOCAL_INLINE(PyObject *)
+rsplit_char(const char *s, Py_ssize_t len, char ch, Py_ssize_t maxcount)
+{
+	register Py_ssize_t i, j, count=0;
+	PyObject *str;
+	PyObject *list = PyList_New(PREALLOC_SIZE(maxcount));
+
+	if (list == NULL)
+		return NULL;
+
+	i = j = len - 1;
+	while ((i >= 0) && (maxcount-- > 0)) {
+		for (; i >= 0; i--) {
+			if (s[i] == ch) {
+				SPLIT_ADD(s, i + 1, j + 1);
+				j = i = i - 1;
+				break;
+			}
+		}
+	}
+	if (j >= -1) {
+		SPLIT_ADD(s, 0, j + 1);
+	}
+	FIX_PREALLOC_SIZE(list);
+	if (PyList_Reverse(list) < 0)
+		goto onError;
+	return list;
+
+ onError:
+	Py_DECREF(list);
+	return NULL;
+}
+
+PyDoc_STRVAR(rsplit__doc__,
+"S.rsplit([sep [,maxsplit]]) -> list of strings\n\
+\n\
+Return a list of the words in the string S, using sep as the\n\
+delimiter string, starting at the end of the string and working\n\
+to the front.  If maxsplit is given, at most maxsplit splits are\n\
+done. If sep is not specified or is None, any whitespace string\n\
+is a separator.");
+
+static PyObject *
+string_rsplit(PyStringObject *self, PyObject *args)
+{
+	Py_ssize_t len = PyString_GET_SIZE(self), n, i, j;
+	Py_ssize_t maxsplit = -1, count=0;
+	const char *s = PyString_AS_STRING(self), *sub;
+	PyObject *list, *str, *subobj = Py_None;
+
+	if (!PyArg_ParseTuple(args, "|On:rsplit", &subobj, &maxsplit))
+		return NULL;
+	if (maxsplit < 0)
+		maxsplit = PY_SSIZE_T_MAX;
+	if (subobj == Py_None)
+		return rsplit_whitespace(s, len, maxsplit);
+	if (PyString_Check(subobj)) {
+		sub = PyString_AS_STRING(subobj);
+		n = PyString_GET_SIZE(subobj);
+	}
+#ifdef Py_USING_UNICODE
+	else if (PyUnicode_Check(subobj))
+		return PyUnicode_RSplit((PyObject *)self, subobj, maxsplit);
+#endif
+	else if (PyObject_AsCharBuffer(subobj, &sub, &n))
+		return NULL;
+
+	if (n == 0) {
+		PyErr_SetString(PyExc_ValueError, "empty separator");
+		return NULL;
+	}
+	else if (n == 1)
+		return rsplit_char(s, len, sub[0], maxsplit);
+
+	list = PyList_New(PREALLOC_SIZE(maxsplit));
+	if (list == NULL)
+		return NULL;
+
+	j = len;
+	i = j - n;
+
+	while ( (i >= 0) && (maxsplit-- > 0) ) {
+		for (; i>=0; i--) {
+			if (Py_STRING_MATCH(s, i, sub, n)) {
+				SPLIT_ADD(s, i + n, j);
+				j = i;
+				i -= n;
+				break;
+			}
+		}
+	}
+	SPLIT_ADD(s, 0, j);
+	FIX_PREALLOC_SIZE(list);
+	if (PyList_Reverse(list) < 0)
+		goto onError;
+	return list;
+
+onError:
+	Py_DECREF(list);
+	return NULL;
+}
+
+
+PyDoc_STRVAR(join__doc__,
+"S.join(sequence) -> string\n\
+\n\
+Return a string which is the concatenation of the strings in the\n\
+sequence.  The separator between elements is S.");
+
+static PyObject *
+string_join(PyStringObject *self, PyObject *orig)
+{
+	char *sep = PyString_AS_STRING(self);
+	const Py_ssize_t seplen = PyString_GET_SIZE(self);
+	PyObject *res = NULL;
+	char *p;
+	Py_ssize_t seqlen = 0;
+	size_t sz = 0;
+	Py_ssize_t i;
+	PyObject *seq, *item;
+
+	seq = PySequence_Fast(orig, "");
+	if (seq == NULL) {
+		return NULL;
+	}
+
+	seqlen = PySequence_Size(seq);
+	if (seqlen == 0) {
+		Py_DECREF(seq);
+		return PyString_FromString("");
+	}
+	if (seqlen == 1) {
+		item = PySequence_Fast_GET_ITEM(seq, 0);
+		if (PyString_CheckExact(item) || PyUnicode_CheckExact(item)) {
+			Py_INCREF(item);
+			Py_DECREF(seq);
+			return item;
+		}
+	}
+
+	/* There are at least two things to join, or else we have a subclass
+	 * of the builtin types in the sequence.
+	 * Do a pre-pass to figure out the total amount of space we'll
+	 * need (sz), see whether any argument is absurd, and defer to
+	 * the Unicode join if appropriate.
+	 */
+	for (i = 0; i < seqlen; i++) {
+		const size_t old_sz = sz;
+		item = PySequence_Fast_GET_ITEM(seq, i);
+		if (!PyString_Check(item)){
+#ifdef Py_USING_UNICODE
+			if (PyUnicode_Check(item)) {
+				/* Defer to Unicode join.
+				 * CAUTION:  There's no gurantee that the
+				 * original sequence can be iterated over
+				 * again, so we must pass seq here.
+				 */
+				PyObject *result;
+				result = PyUnicode_Join((PyObject *)self, seq);
+				Py_DECREF(seq);
+				return result;
+			}
+#endif
+			PyErr_Format(PyExc_TypeError,
+				     "sequence item %zd: expected string,"
+				     " %.80s found",
+				     i, item->ob_type->tp_name);
+			Py_DECREF(seq);
+			return NULL;
+		}
+		sz += PyString_GET_SIZE(item);
+		if (i != 0)
+			sz += seplen;
+		if (sz < old_sz || sz > PY_SSIZE_T_MAX) {
+			PyErr_SetString(PyExc_OverflowError,
+				"join() result is too long for a Python string");
+			Py_DECREF(seq);
+			return NULL;
+		}
+	}
+
+	/* Allocate result space. */
+	res = PyString_FromStringAndSize((char*)NULL, sz);
+	if (res == NULL) {
+		Py_DECREF(seq);
+		return NULL;
+	}
+
+	/* Catenate everything. */
+	p = PyString_AS_STRING(res);
+	for (i = 0; i < seqlen; ++i) {
+		size_t n;
+		item = PySequence_Fast_GET_ITEM(seq, i);
+		n = PyString_GET_SIZE(item);
+		Py_MEMCPY(p, PyString_AS_STRING(item), n);
+		p += n;
+		if (i < seqlen - 1) {
+			Py_MEMCPY(p, sep, seplen);
+			p += seplen;
+		}
+	}
+
+	Py_DECREF(seq);
+	return res;
+}
+
+PyObject *
+_PyString_Join(PyObject *sep, PyObject *x)
+{
+	assert(sep != NULL && PyString_Check(sep));
+	assert(x != NULL);
+	return string_join((PyStringObject *)sep, x);
+}
+
+Py_LOCAL_INLINE(void)
+string_adjust_indices(Py_ssize_t *start, Py_ssize_t *end, Py_ssize_t len)
+{
+	if (*end > len)
+		*end = len;
+	else if (*end < 0)
+		*end += len;
+	if (*end < 0)
+		*end = 0;
+	if (*start < 0)
+		*start += len;
+	if (*start < 0)
+		*start = 0;
+}
+
+Py_LOCAL_INLINE(Py_ssize_t)
+string_find_internal(PyStringObject *self, PyObject *args, int dir)
+{
+	PyObject *subobj;
+	const char *sub;
+	Py_ssize_t sub_len;
+	Py_ssize_t start=0, end=PY_SSIZE_T_MAX;
+
+	if (!PyArg_ParseTuple(args, "O|O&O&:find/rfind/index/rindex", &subobj,
+		_PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
+		return -2;
+	if (PyString_Check(subobj)) {
+		sub = PyString_AS_STRING(subobj);
+		sub_len = PyString_GET_SIZE(subobj);
+	}
+#ifdef Py_USING_UNICODE
+	else if (PyUnicode_Check(subobj))
+		return PyUnicode_Find(
+			(PyObject *)self, subobj, start, end, dir);
+#endif
+	else if (PyObject_AsCharBuffer(subobj, &sub, &sub_len))
+		/* XXX - the "expected a character buffer object" is pretty
+		   confusing for a non-expert.  remap to something else ? */
+		return -2;
+
+	if (dir > 0)
+		return stringlib_find_slice(
+			PyString_AS_STRING(self), PyString_GET_SIZE(self),
+			sub, sub_len, start, end);
+	else
+		return stringlib_rfind_slice(
+			PyString_AS_STRING(self), PyString_GET_SIZE(self),
+			sub, sub_len, start, end);
+}
+
+
+PyDoc_STRVAR(find__doc__,
+"S.find(sub [,start [,end]]) -> int\n\
+\n\
+Return the lowest index in S where substring sub is found,\n\
+such that sub is contained within s[start,end].  Optional\n\
+arguments start and end are interpreted as in slice notation.\n\
+\n\
+Return -1 on failure.");
+
+static PyObject *
+string_find(PyStringObject *self, PyObject *args)
+{
+	Py_ssize_t result = string_find_internal(self, args, +1);
+	if (result == -2)
+		return NULL;
+	return PyInt_FromSsize_t(result);
+}
+
+
+PyDoc_STRVAR(index__doc__,
+"S.index(sub [,start [,end]]) -> int\n\
+\n\
+Like S.find() but raise ValueError when the substring is not found.");
+
+static PyObject *
+string_index(PyStringObject *self, PyObject *args)
+{
+	Py_ssize_t result = string_find_internal(self, args, +1);
+	if (result == -2)
+		return NULL;
+	if (result == -1) {
+		PyErr_SetString(PyExc_ValueError,
+				"substring not found");
+		return NULL;
+	}
+	return PyInt_FromSsize_t(result);
+}
+
+
+PyDoc_STRVAR(rfind__doc__,
+"S.rfind(sub [,start [,end]]) -> int\n\
+\n\
+Return the highest index in S where substring sub is found,\n\
+such that sub is contained within s[start,end].  Optional\n\
+arguments start and end are interpreted as in slice notation.\n\
+\n\
+Return -1 on failure.");
+
+static PyObject *
+string_rfind(PyStringObject *self, PyObject *args)
+{
+	Py_ssize_t result = string_find_internal(self, args, -1);
+	if (result == -2)
+		return NULL;
+	return PyInt_FromSsize_t(result);
+}
+
+
+PyDoc_STRVAR(rindex__doc__,
+"S.rindex(sub [,start [,end]]) -> int\n\
+\n\
+Like S.rfind() but raise ValueError when the substring is not found.");
+
+static PyObject *
+string_rindex(PyStringObject *self, PyObject *args)
+{
+	Py_ssize_t result = string_find_internal(self, args, -1);
+	if (result == -2)
+		return NULL;
+	if (result == -1) {
+		PyErr_SetString(PyExc_ValueError,
+				"substring not found");
+		return NULL;
+	}
+	return PyInt_FromSsize_t(result);
+}
+
+
+Py_LOCAL_INLINE(PyObject *)
+do_xstrip(PyStringObject *self, int striptype, PyObject *sepobj)
+{
+	char *s = PyString_AS_STRING(self);
+	Py_ssize_t len = PyString_GET_SIZE(self);
+	char *sep = PyString_AS_STRING(sepobj);
+	Py_ssize_t seplen = PyString_GET_SIZE(sepobj);
+	Py_ssize_t i, j;
+
+	i = 0;
+	if (striptype != RIGHTSTRIP) {
+		while (i < len && memchr(sep, Py_CHARMASK(s[i]), seplen)) {
+			i++;
+		}
+	}
+
+	j = len;
+	if (striptype != LEFTSTRIP) {
+		do {
+			j--;
+		} while (j >= i && memchr(sep, Py_CHARMASK(s[j]), seplen));
+		j++;
+	}
+
+	if (i == 0 && j == len && PyString_CheckExact(self)) {
+		Py_INCREF(self);
+		return (PyObject*)self;
+	}
+	else
+		return PyString_FromStringAndSize(s+i, j-i);
+}
+
+
+Py_LOCAL_INLINE(PyObject *)
+do_strip(PyStringObject *self, int striptype)
+{
+	char *s = PyString_AS_STRING(self);
+	Py_ssize_t len = PyString_GET_SIZE(self), i, j;
+
+	i = 0;
+	if (striptype != RIGHTSTRIP) {
+		while (i < len && isspace(Py_CHARMASK(s[i]))) {
+			i++;
+		}
+	}
+
+	j = len;
+	if (striptype != LEFTSTRIP) {
+		do {
+			j--;
+		} while (j >= i && isspace(Py_CHARMASK(s[j])));
+		j++;
+	}
+
+	if (i == 0 && j == len && PyString_CheckExact(self)) {
+		Py_INCREF(self);
+		return (PyObject*)self;
+	}
+	else
+		return PyString_FromStringAndSize(s+i, j-i);
+}
+
+
+Py_LOCAL_INLINE(PyObject *)
+do_argstrip(PyStringObject *self, int striptype, PyObject *args)
+{
+	PyObject *sep = NULL;
+
+	if (!PyArg_ParseTuple(args, (char *)stripformat[striptype], &sep))
+		return NULL;
+
+	if (sep != NULL && sep != Py_None) {
+		if (PyString_Check(sep))
+			return do_xstrip(self, striptype, sep);
+#ifdef Py_USING_UNICODE
+		else if (PyUnicode_Check(sep)) {
+			PyObject *uniself = PyUnicode_FromObject((PyObject *)self);
+			PyObject *res;
+			if (uniself==NULL)
+				return NULL;
+			res = _PyUnicode_XStrip((PyUnicodeObject *)uniself,
+				striptype, sep);
+			Py_DECREF(uniself);
+			return res;
+		}
+#endif
+		PyErr_Format(PyExc_TypeError,
+#ifdef Py_USING_UNICODE
+			     "%s arg must be None, str or unicode",
+#else
+			     "%s arg must be None or str",
+#endif
+			     STRIPNAME(striptype));
+		return NULL;
+	}
+
+	return do_strip(self, striptype);
+}
+
+
+PyDoc_STRVAR(strip__doc__,
+"S.strip([chars]) -> string or unicode\n\
+\n\
+Return a copy of the string S with leading and trailing\n\
+whitespace removed.\n\
+If chars is given and not None, remove characters in chars instead.\n\
+If chars is unicode, S will be converted to unicode before stripping");
+
+static PyObject *
+string_strip(PyStringObject *self, PyObject *args)
+{
+	if (PyTuple_GET_SIZE(args) == 0)
+		return do_strip(self, BOTHSTRIP); /* Common case */
+	else
+		return do_argstrip(self, BOTHSTRIP, args);
+}
+
+
+PyDoc_STRVAR(lstrip__doc__,
+"S.lstrip([chars]) -> string or unicode\n\
+\n\
+Return a copy of the string S with leading whitespace removed.\n\
+If chars is given and not None, remove characters in chars instead.\n\
+If chars is unicode, S will be converted to unicode before stripping");
+
+static PyObject *
+string_lstrip(PyStringObject *self, PyObject *args)
+{
+	if (PyTuple_GET_SIZE(args) == 0)
+		return do_strip(self, LEFTSTRIP); /* Common case */
+	else
+		return do_argstrip(self, LEFTSTRIP, args);
+}
+
+
+PyDoc_STRVAR(rstrip__doc__,
+"S.rstrip([chars]) -> string or unicode\n\
+\n\
+Return a copy of the string S with trailing whitespace removed.\n\
+If chars is given and not None, remove characters in chars instead.\n\
+If chars is unicode, S will be converted to unicode before stripping");
+
+static PyObject *
+string_rstrip(PyStringObject *self, PyObject *args)
+{
+	if (PyTuple_GET_SIZE(args) == 0)
+		return do_strip(self, RIGHTSTRIP); /* Common case */
+	else
+		return do_argstrip(self, RIGHTSTRIP, args);
+}
+
+
+PyDoc_STRVAR(lower__doc__,
+"S.lower() -> string\n\
+\n\
+Return a copy of the string S converted to lowercase.");
+
+/* _tolower and _toupper are defined by SUSv2, but they're not ISO C */
+#ifndef _tolower
+#define _tolower tolower
+#endif
+
+static PyObject *
+string_lower(PyStringObject *self)
+{
+	char *s;
+	Py_ssize_t i, n = PyString_GET_SIZE(self);
+	PyObject *newobj;
+
+	newobj = PyString_FromStringAndSize(NULL, n);
+	if (!newobj)
+		return NULL;
+
+	s = PyString_AS_STRING(newobj);
+
+	Py_MEMCPY(s, PyString_AS_STRING(self), n);
+
+	for (i = 0; i < n; i++) {
+		int c = Py_CHARMASK(s[i]);
+		if (isupper(c))
+			s[i] = _tolower(c);
+	}
+
+	return newobj;
+}
+
+PyDoc_STRVAR(upper__doc__,
+"S.upper() -> string\n\
+\n\
+Return a copy of the string S converted to uppercase.");
+
+#ifndef _toupper
+#define _toupper toupper
+#endif
+
+static PyObject *
+string_upper(PyStringObject *self)
+{
+	char *s;
+	Py_ssize_t i, n = PyString_GET_SIZE(self);
+	PyObject *newobj;
+
+	newobj = PyString_FromStringAndSize(NULL, n);
+	if (!newobj)
+		return NULL;
+
+	s = PyString_AS_STRING(newobj);
+
+	Py_MEMCPY(s, PyString_AS_STRING(self), n);
+
+	for (i = 0; i < n; i++) {
+		int c = Py_CHARMASK(s[i]);
+		if (islower(c))
+			s[i] = _toupper(c);
+	}
+
+	return newobj;
+}
+
+PyDoc_STRVAR(title__doc__,
+"S.title() -> string\n\
+\n\
+Return a titlecased version of S, i.e. words start with uppercase\n\
+characters, all remaining cased characters have lowercase.");
+
+static PyObject*
+string_title(PyStringObject *self)
+{
+	char *s = PyString_AS_STRING(self), *s_new;
+	Py_ssize_t i, n = PyString_GET_SIZE(self);
+	int previous_is_cased = 0;
+	PyObject *newobj;
+
+	newobj = PyString_FromStringAndSize(NULL, n);
+	if (newobj == NULL)
+		return NULL;
+	s_new = PyString_AsString(newobj);
+	for (i = 0; i < n; i++) {
+		int c = Py_CHARMASK(*s++);
+		if (islower(c)) {
+			if (!previous_is_cased)
+			    c = toupper(c);
+			previous_is_cased = 1;
+		} else if (isupper(c)) {
+			if (previous_is_cased)
+			    c = tolower(c);
+			previous_is_cased = 1;
+		} else
+			previous_is_cased = 0;
+		*s_new++ = c;
+	}
+	return newobj;
+}
+
+PyDoc_STRVAR(capitalize__doc__,
+"S.capitalize() -> string\n\
+\n\
+Return a copy of the string S with only its first character\n\
+capitalized.");
+
+static PyObject *
+string_capitalize(PyStringObject *self)
+{
+	char *s = PyString_AS_STRING(self), *s_new;
+	Py_ssize_t i, n = PyString_GET_SIZE(self);
+	PyObject *newobj;
+
+	newobj = PyString_FromStringAndSize(NULL, n);
+	if (newobj == NULL)
+		return NULL;
+	s_new = PyString_AsString(newobj);
+	if (0 < n) {
+		int c = Py_CHARMASK(*s++);
+		if (islower(c))
+			*s_new = toupper(c);
+		else
+			*s_new = c;
+		s_new++;
+	}
+	for (i = 1; i < n; i++) {
+		int c = Py_CHARMASK(*s++);
+		if (isupper(c))
+			*s_new = tolower(c);
+		else
+			*s_new = c;
+		s_new++;
+	}
+	return newobj;
+}
+
+
+PyDoc_STRVAR(count__doc__,
+"S.count(sub[, start[, end]]) -> int\n\
+\n\
+Return the number of non-overlapping occurrences of substring sub in\n\
+string S[start:end].  Optional arguments start and end are interpreted\n\
+as in slice notation.");
+
+static PyObject *
+string_count(PyStringObject *self, PyObject *args)
+{
+	PyObject *sub_obj;
+	const char *str = PyString_AS_STRING(self), *sub;
+	Py_ssize_t sub_len;
+	Py_ssize_t start = 0, end = PY_SSIZE_T_MAX;
+
+	if (!PyArg_ParseTuple(args, "O|O&O&:count", &sub_obj,
+		_PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
+		return NULL;
+
+	if (PyString_Check(sub_obj)) {
+		sub = PyString_AS_STRING(sub_obj);
+		sub_len = PyString_GET_SIZE(sub_obj);
+	}
+#ifdef Py_USING_UNICODE
+	else if (PyUnicode_Check(sub_obj)) {
+		Py_ssize_t count;
+		count = PyUnicode_Count((PyObject *)self, sub_obj, start, end);
+		if (count == -1)
+			return NULL;
+		else
+		    	return PyInt_FromSsize_t(count);
+	}
+#endif
+	else if (PyObject_AsCharBuffer(sub_obj, &sub, &sub_len))
+		return NULL;
+
+	string_adjust_indices(&start, &end, PyString_GET_SIZE(self));
+
+	return PyInt_FromSsize_t(
+		stringlib_count(str + start, end - start, sub, sub_len)
+		);
+}
+
+PyDoc_STRVAR(swapcase__doc__,
+"S.swapcase() -> string\n\
+\n\
+Return a copy of the string S with uppercase characters\n\
+converted to lowercase and vice versa.");
+
+static PyObject *
+string_swapcase(PyStringObject *self)
+{
+	char *s = PyString_AS_STRING(self), *s_new;
+	Py_ssize_t i, n = PyString_GET_SIZE(self);
+	PyObject *newobj;
+
+	newobj = PyString_FromStringAndSize(NULL, n);
+	if (newobj == NULL)
+		return NULL;
+	s_new = PyString_AsString(newobj);
+	for (i = 0; i < n; i++) {
+		int c = Py_CHARMASK(*s++);
+		if (islower(c)) {
+			*s_new = toupper(c);
+		}
+		else if (isupper(c)) {
+			*s_new = tolower(c);
+		}
+		else
+			*s_new = c;
+		s_new++;
+	}
+	return newobj;
+}
+
+
+PyDoc_STRVAR(translate__doc__,
+"S.translate(table [,deletechars]) -> string\n\
+\n\
+Return a copy of the string S, where all characters occurring\n\
+in the optional argument deletechars are removed, and the\n\
+remaining characters have been mapped through the given\n\
+translation table, which must be a string of length 256.");
+
+static PyObject *
+string_translate(PyStringObject *self, PyObject *args)
+{
+	register char *input, *output;
+	register const char *table;
+	register Py_ssize_t i, c, changed = 0;
+	PyObject *input_obj = (PyObject*)self;
+	const char *table1, *output_start, *del_table=NULL;
+	Py_ssize_t inlen, tablen, dellen = 0;
+	PyObject *result;
+	int trans_table[256];
+	PyObject *tableobj, *delobj = NULL;
+
+	if (!PyArg_UnpackTuple(args, "translate", 1, 2,
+			      &tableobj, &delobj))
+		return NULL;
+
+	if (PyString_Check(tableobj)) {
+		table1 = PyString_AS_STRING(tableobj);
+		tablen = PyString_GET_SIZE(tableobj);
+	}
+#ifdef Py_USING_UNICODE
+	else if (PyUnicode_Check(tableobj)) {
+		/* Unicode .translate() does not support the deletechars
+		   parameter; instead a mapping to None will cause characters
+		   to be deleted. */
+		if (delobj != NULL) {
+			PyErr_SetString(PyExc_TypeError,
+			"deletions are implemented differently for unicode");
+			return NULL;
+		}
+		return PyUnicode_Translate((PyObject *)self, tableobj, NULL);
+	}
+#endif
+	else if (PyObject_AsCharBuffer(tableobj, &table1, &tablen))
+		return NULL;
+
+	if (tablen != 256) {
+		PyErr_SetString(PyExc_ValueError,
+		  "translation table must be 256 characters long");
+		return NULL;
+	}
+
+	if (delobj != NULL) {
+		if (PyString_Check(delobj)) {
+			del_table = PyString_AS_STRING(delobj);
+			dellen = PyString_GET_SIZE(delobj);
+		}
+#ifdef Py_USING_UNICODE
+		else if (PyUnicode_Check(delobj)) {
+			PyErr_SetString(PyExc_TypeError,
+			"deletions are implemented differently for unicode");
+			return NULL;
+		}
+#endif
+		else if (PyObject_AsCharBuffer(delobj, &del_table, &dellen))
+			return NULL;
+	}
+	else {
+		del_table = NULL;
+		dellen = 0;
+	}
+
+	table = table1;
+	inlen = PyString_GET_SIZE(input_obj);
+	result = PyString_FromStringAndSize((char *)NULL, inlen);
+	if (result == NULL)
+		return NULL;
+	output_start = output = PyString_AsString(result);
+	input = PyString_AS_STRING(input_obj);
+
+	if (dellen == 0) {
+		/* If no deletions are required, use faster code */
+		for (i = inlen; --i >= 0; ) {
+			c = Py_CHARMASK(*input++);
+			if (Py_CHARMASK((*output++ = table[c])) != c)
+				changed = 1;
+		}
+		if (changed || !PyString_CheckExact(input_obj))
+			return result;
+		Py_DECREF(result);
+		Py_INCREF(input_obj);
+		return input_obj;
+	}
+
+	for (i = 0; i < 256; i++)
+		trans_table[i] = Py_CHARMASK(table[i]);
+
+	for (i = 0; i < dellen; i++)
+		trans_table[(int) Py_CHARMASK(del_table[i])] = -1;
+
+	for (i = inlen; --i >= 0; ) {
+		c = Py_CHARMASK(*input++);
+		if (trans_table[c] != -1)
+			if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c)
+				continue;
+		changed = 1;
+	}
+	if (!changed && PyString_CheckExact(input_obj)) {
+		Py_DECREF(result);
+		Py_INCREF(input_obj);
+		return input_obj;
+	}
+	/* Fix the size of the resulting string */
+	if (inlen > 0)
+		_PyString_Resize(&result, output - output_start);
+	return result;
+}
+
+
+#define FORWARD 1
+#define REVERSE -1
+
+/* find and count characters and substrings */
+
+#define findchar(target, target_len, c)				\
+  ((char *)memchr((const void *)(target), c, target_len))
+
+/* String ops must return a string.  */
+/* If the object is subclass of string, create a copy */
+Py_LOCAL(PyStringObject *)
+return_self(PyStringObject *self)
+{
+	if (PyString_CheckExact(self)) {
+		Py_INCREF(self);
+		return self;
+	}
+	return (PyStringObject *)PyString_FromStringAndSize(
+		PyString_AS_STRING(self),
+		PyString_GET_SIZE(self));
+}
+
+Py_LOCAL_INLINE(Py_ssize_t)
+countchar(const char *target, int target_len, char c, Py_ssize_t maxcount)
+{
+	Py_ssize_t count=0;
+	const char *start=target;
+	const char *end=target+target_len;
+
+	while ( (start=findchar(start, end-start, c)) != NULL ) {
+		count++;
+		if (count >= maxcount)
+			break;
+		start += 1;
+	}
+	return count;
+}
+
+Py_LOCAL(Py_ssize_t)
+findstring(const char *target, Py_ssize_t target_len,
+	   const char *pattern, Py_ssize_t pattern_len,
+	   Py_ssize_t start,
+	   Py_ssize_t end,
+	   int direction)
+{
+	if (start < 0) {
+		start += target_len;
+		if (start < 0)
+			start = 0;
+	}
+	if (end > target_len) {
+		end = target_len;
+	} else if (end < 0) {
+		end += target_len;
+		if (end < 0)
+			end = 0;
+	}
+
+	/* zero-length substrings always match at the first attempt */
+	if (pattern_len == 0)
+		return (direction > 0) ? start : end;
+
+	end -= pattern_len;
+
+	if (direction < 0) {
+		for (; end >= start; end--)
+			if (Py_STRING_MATCH(target, end, pattern, pattern_len))
+				return end;
+	} else {
+		for (; start <= end; start++)
+			if (Py_STRING_MATCH(target, start, pattern, pattern_len))
+				return start;
+	}
+	return -1;
+}
+
+Py_LOCAL_INLINE(Py_ssize_t)
+countstring(const char *target, Py_ssize_t target_len,
+	    const char *pattern, Py_ssize_t pattern_len,
+	    Py_ssize_t start,
+	    Py_ssize_t end,
+	    int direction, Py_ssize_t maxcount)
+{
+	Py_ssize_t count=0;
+
+	if (start < 0) {
+		start += target_len;
+		if (start < 0)
+			start = 0;
+	}
+	if (end > target_len) {
+		end = target_len;
+	} else if (end < 0) {
+		end += target_len;
+		if (end < 0)
+			end = 0;
+	}
+
+	/* zero-length substrings match everywhere */
+	if (pattern_len == 0 || maxcount == 0) {
+		if (target_len+1 < maxcount)
+			return target_len+1;
+		return maxcount;
+	}
+
+	end -= pattern_len;
+	if (direction < 0) {
+		for (; (end >= start); end--)
+			if (Py_STRING_MATCH(target, end, pattern, pattern_len)) {
+				count++;
+				if (--maxcount <= 0) break;
+				end -= pattern_len-1;
+			}
+	} else {
+		for (; (start <= end); start++)
+			if (Py_STRING_MATCH(target, start, pattern, pattern_len)) {
+				count++;
+				if (--maxcount <= 0)
+					break;
+				start += pattern_len-1;
+			}
+	}
+	return count;
+}
+
+
+/* Algorithms for different cases of string replacement */
+
+/* len(self)>=1, from="", len(to)>=1, maxcount>=1 */
+Py_LOCAL(PyStringObject *)
+replace_interleave(PyStringObject *self,
+		   const char *to_s, Py_ssize_t to_len,
+		   Py_ssize_t maxcount)
+{
+	char *self_s, *result_s;
+	Py_ssize_t self_len, result_len;
+	Py_ssize_t count, i, product;
+	PyStringObject *result;
+
+	self_len = PyString_GET_SIZE(self);
+
+	/* 1 at the end plus 1 after every character */
+	count = self_len+1;
+	if (maxcount < count) 
+		count = maxcount;
+
+	/* Check for overflow */
+	/*   result_len = count * to_len + self_len; */
+	product = count * to_len;
+	if (product / to_len != count) {
+		PyErr_SetString(PyExc_OverflowError,
+				"replace string is too long");
+		return NULL;
+	}
+	result_len = product + self_len;
+	if (result_len < 0) {
+		PyErr_SetString(PyExc_OverflowError,
+				"replace string is too long");
+		return NULL;
+	}
+  
+	if (! (result = (PyStringObject *)
+	                 PyString_FromStringAndSize(NULL, result_len)) )
+		return NULL;
+
+	self_s = PyString_AS_STRING(self);
+	result_s = PyString_AS_STRING(result);
+
+	/* TODO: special case single character, which doesn't need memcpy */
+
+	/* Lay the first one down (guaranteed this will occur) */
+	Py_MEMCPY(result_s, to_s, to_len);
+	result_s += to_len;
+	count -= 1;
+  
+	for (i=0; i<count; i++) {
+		*result_s++ = *self_s++;
+		Py_MEMCPY(result_s, to_s, to_len);
+		result_s += to_len;
+	}
+
+	/* Copy the rest of the original string */
+	Py_MEMCPY(result_s, self_s, self_len-i);
+
+	return result;
+}
+
+/* Special case for deleting a single character */
+/* len(self)>=1, len(from)==1, to="", maxcount>=1 */
+Py_LOCAL(PyStringObject *)
+replace_delete_single_character(PyStringObject *self,
+				char from_c, Py_ssize_t maxcount)
+{
+	char *self_s, *result_s;
+	char *start, *next, *end;
+	Py_ssize_t self_len, result_len;
+	Py_ssize_t count;
+	PyStringObject *result;
+
+	self_len = PyString_GET_SIZE(self);
+	self_s = PyString_AS_STRING(self);
+
+	count = countchar(self_s, self_len, from_c, maxcount);
+	if (count == 0) {
+		return return_self(self);
+	}
+  
+	result_len = self_len - count;  /* from_len == 1 */
+	assert(result_len>=0);
+
+	if ( (result = (PyStringObject *)
+	                PyString_FromStringAndSize(NULL, result_len)) == NULL)
+		return NULL;
+	result_s = PyString_AS_STRING(result);
+
+	start = self_s;
+	end = self_s + self_len;
+	while (count-- > 0) {
+		next = findchar(start, end-start, from_c);
+		if (next == NULL)
+			break;
+		Py_MEMCPY(result_s, start, next-start);
+		result_s += (next-start);
+		start = next+1;
+	}
+	Py_MEMCPY(result_s, start, end-start);
+
+	return result;
+}
+
+/* len(self)>=1, len(from)>=2, to="", maxcount>=1 */
+
+Py_LOCAL(PyStringObject *)
+replace_delete_substring(PyStringObject *self,
+			 const char *from_s, Py_ssize_t from_len,
+			 Py_ssize_t maxcount) {
+	char *self_s, *result_s;
+	char *start, *next, *end;
+	Py_ssize_t self_len, result_len;
+	Py_ssize_t count, offset;
+	PyStringObject *result;
+
+	self_len = PyString_GET_SIZE(self);
+	self_s = PyString_AS_STRING(self);
+
+	count = countstring(self_s, self_len,
+			    from_s, from_len,
+			    0, self_len, 1,
+			    maxcount);
+
+	if (count == 0) {
+		/* no matches */
+		return return_self(self);
+	}
+
+	result_len = self_len - (count * from_len);
+	assert (result_len>=0);
+
+	if ( (result = (PyStringObject *)
+	      PyString_FromStringAndSize(NULL, result_len)) == NULL )
+		return NULL;
+
+	result_s = PyString_AS_STRING(result);
+
+	start = self_s;
+	end = self_s + self_len;
+	while (count-- > 0) {
+		offset = findstring(start, end-start,
+				    from_s, from_len,
+				    0, end-start, FORWARD);
+		if (offset == -1)
+			break;
+		next = start + offset;
+
+		Py_MEMCPY(result_s, start, next-start);
+
+		result_s += (next-start);
+		start = next+from_len;
+	}
+	Py_MEMCPY(result_s, start, end-start);
+	return result;
+}
+
+/* len(self)>=1, len(from)==len(to)==1, maxcount>=1 */
+Py_LOCAL(PyStringObject *)
+replace_single_character_in_place(PyStringObject *self,
+				  char from_c, char to_c,
+				  Py_ssize_t maxcount)
+{
+	char *self_s, *result_s, *start, *end, *next;
+	Py_ssize_t self_len;
+	PyStringObject *result;
+
+	/* The result string will be the same size */
+	self_s = PyString_AS_STRING(self);
+	self_len = PyString_GET_SIZE(self);
+
+	next = findchar(self_s, self_len, from_c);
+
+	if (next == NULL) {
+		/* No matches; return the original string */
+		return return_self(self);
+	}
+
+	/* Need to make a new string */
+	result = (PyStringObject *) PyString_FromStringAndSize(NULL, self_len);
+	if (result == NULL)
+		return NULL;
+	result_s = PyString_AS_STRING(result);
+	Py_MEMCPY(result_s, self_s, self_len);
+
+	/* change everything in-place, starting with this one */
+	start =  result_s + (next-self_s);
+	*start = to_c;
+	start++;
+	end = result_s + self_len;
+
+	while (--maxcount > 0) {
+		next = findchar(start, end-start, from_c);
+		if (next == NULL)
+			break;
+		*next = to_c;
+		start = next+1;
+	}
+
+	return result;
+}
+
+/* len(self)>=1, len(from)==len(to)>=2, maxcount>=1 */
+Py_LOCAL(PyStringObject *)
+replace_substring_in_place(PyStringObject *self,
+			   const char *from_s, Py_ssize_t from_len,
+			   const char *to_s, Py_ssize_t to_len,
+			   Py_ssize_t maxcount)
+{
+	char *result_s, *start, *end;
+	char *self_s;
+	Py_ssize_t self_len, offset;
+	PyStringObject *result;
+
+	/* The result string will be the same size */
+
+	self_s = PyString_AS_STRING(self);
+	self_len = PyString_GET_SIZE(self);
+
+	offset = findstring(self_s, self_len,
+			    from_s, from_len,
+			    0, self_len, FORWARD);
+	if (offset == -1) {
+		/* No matches; return the original string */
+		return return_self(self);
+	}
+
+	/* Need to make a new string */
+	result = (PyStringObject *) PyString_FromStringAndSize(NULL, self_len);
+	if (result == NULL)
+		return NULL;
+	result_s = PyString_AS_STRING(result);
+	Py_MEMCPY(result_s, self_s, self_len);
+
+	/* change everything in-place, starting with this one */
+	start =  result_s + offset;
+	Py_MEMCPY(start, to_s, from_len);
+	start += from_len;
+	end = result_s + self_len;
+
+	while ( --maxcount > 0) {
+		offset = findstring(start, end-start,
+				    from_s, from_len,
+				    0, end-start, FORWARD);
+		if (offset==-1)
+			break;
+		Py_MEMCPY(start+offset, to_s, from_len);
+		start += offset+from_len;
+	}
+
+	return result;
+}
+
+/* len(self)>=1, len(from)==1, len(to)>=2, maxcount>=1 */
+Py_LOCAL(PyStringObject *)
+replace_single_character(PyStringObject *self,
+			 char from_c,
+			 const char *to_s, Py_ssize_t to_len,
+			 Py_ssize_t maxcount)
+{
+	char *self_s, *result_s;
+	char *start, *next, *end;
+	Py_ssize_t self_len, result_len;
+	Py_ssize_t count, product;
+	PyStringObject *result;
+
+	self_s = PyString_AS_STRING(self);
+	self_len = PyString_GET_SIZE(self);
+
+	count = countchar(self_s, self_len, from_c, maxcount);
+	if (count == 0) {
+		/* no matches, return unchanged */
+		return return_self(self);
+	}
+
+	/* use the difference between current and new, hence the "-1" */
+	/*   result_len = self_len + count * (to_len-1)  */
+	product = count * (to_len-1);
+	if (product / (to_len-1) != count) {
+		PyErr_SetString(PyExc_OverflowError, "replace string is too long");
+		return NULL;
+	}
+	result_len = self_len + product;
+	if (result_len < 0) {
+		PyErr_SetString(PyExc_OverflowError, "replace string is too long");
+		return NULL;
+	}
+
+	if ( (result = (PyStringObject *)
+	      PyString_FromStringAndSize(NULL, result_len)) == NULL)
+		return NULL;
+	result_s = PyString_AS_STRING(result);
+
+	start = self_s;
+	end = self_s + self_len;
+	while (count-- > 0) {
+		next = findchar(start, end-start, from_c);
+		if (next == NULL) 
+			break;
+
+		if (next == start) {
+			/* replace with the 'to' */
+			Py_MEMCPY(result_s, to_s, to_len);
+			result_s += to_len;
+			start += 1;
+		} else {
+			/* copy the unchanged old then the 'to' */
+			Py_MEMCPY(result_s, start, next-start);
+			result_s += (next-start);
+			Py_MEMCPY(result_s, to_s, to_len);
+			result_s += to_len;
+			start = next+1;
+		}
+	}
+	/* Copy the remainder of the remaining string */
+	Py_MEMCPY(result_s, start, end-start);
+
+	return result;
+}
+
+/* len(self)>=1, len(from)>=2, len(to)>=2, maxcount>=1 */
+Py_LOCAL(PyStringObject *)
+replace_substring(PyStringObject *self,
+		  const char *from_s, Py_ssize_t from_len,
+		  const char *to_s, Py_ssize_t to_len,
+		  Py_ssize_t maxcount) {
+	char *self_s, *result_s;
+	char *start, *next, *end;
+	Py_ssize_t self_len, result_len;
+	Py_ssize_t count, offset, product;
+	PyStringObject *result;
+
+	self_s = PyString_AS_STRING(self);
+	self_len = PyString_GET_SIZE(self);
+
+	count = countstring(self_s, self_len,
+			    from_s, from_len,
+			    0, self_len, FORWARD, maxcount);
+	if (count == 0) {
+		/* no matches, return unchanged */
+		return return_self(self);
+	}
+
+	/* Check for overflow */
+	/*    result_len = self_len + count * (to_len-from_len) */
+	product = count * (to_len-from_len);
+	if (product / (to_len-from_len) != count) {
+		PyErr_SetString(PyExc_OverflowError, "replace string is too long");
+		return NULL;
+	}
+	result_len = self_len + product;
+	if (result_len < 0) {
+		PyErr_SetString(PyExc_OverflowError, "replace string is too long");
+		return NULL;
+	}
+
+	if ( (result = (PyStringObject *)
+	      PyString_FromStringAndSize(NULL, result_len)) == NULL)
+		return NULL;
+	result_s = PyString_AS_STRING(result);
+
+	start = self_s;
+	end = self_s + self_len;
+	while (count-- > 0) {
+		offset = findstring(start, end-start,
+				    from_s, from_len,
+				    0, end-start, FORWARD);
+		if (offset == -1)
+			break;
+		next = start+offset;
+		if (next == start) {
+			/* replace with the 'to' */
+			Py_MEMCPY(result_s, to_s, to_len);
+			result_s += to_len;
+			start += from_len;
+		} else {
+			/* copy the unchanged old then the 'to' */
+			Py_MEMCPY(result_s, start, next-start);
+			result_s += (next-start);
+			Py_MEMCPY(result_s, to_s, to_len);
+			result_s += to_len;
+			start = next+from_len;
+		}
+	}
+	/* Copy the remainder of the remaining string */
+	Py_MEMCPY(result_s, start, end-start);
+
+	return result;
+}
+
+
+Py_LOCAL(PyStringObject *)
+replace(PyStringObject *self,
+	const char *from_s, Py_ssize_t from_len,
+	const char *to_s, Py_ssize_t to_len,
+	Py_ssize_t maxcount)
+{
+	if (maxcount < 0) {
+		maxcount = PY_SSIZE_T_MAX;
+	} else if (maxcount == 0 || PyString_GET_SIZE(self) == 0) {
+		/* nothing to do; return the original string */
+		return return_self(self);
+	}
+
+	if (maxcount == 0 ||
+	    (from_len == 0 && to_len == 0)) {
+		/* nothing to do; return the original string */
+		return return_self(self);
+	}
+
+	/* Handle zero-length special cases */
+
+	if (from_len == 0) {
+		/* insert the 'to' string everywhere.   */
+		/*    >>> "Python".replace("", ".")     */
+		/*    '.P.y.t.h.o.n.'                   */
+		return replace_interleave(self, to_s, to_len, maxcount);
+	}
+
+	/* Except for "".replace("", "A") == "A" there is no way beyond this */
+	/* point for an empty self string to generate a non-empty string */
+	/* Special case so the remaining code always gets a non-empty string */
+	if (PyString_GET_SIZE(self) == 0) {
+		return return_self(self);
+	}
+
+	if (to_len == 0) {
+		/* delete all occurances of 'from' string */
+		if (from_len == 1) {
+			return replace_delete_single_character(
+				self, from_s[0], maxcount);
+		} else {
+			return replace_delete_substring(self, from_s, from_len, maxcount);
+		}
+	}
+
+	/* Handle special case where both strings have the same length */
+
+	if (from_len == to_len) {
+		if (from_len == 1) {
+			return replace_single_character_in_place(
+				self,
+				from_s[0],
+				to_s[0],
+				maxcount);
+		} else {
+			return replace_substring_in_place(
+				self, from_s, from_len, to_s, to_len, maxcount);
+		}
+	}
+
+	/* Otherwise use the more generic algorithms */
+	if (from_len == 1) {
+		return replace_single_character(self, from_s[0],
+						to_s, to_len, maxcount);
+	} else {
+		/* len('from')>=2, len('to')>=1 */
+		return replace_substring(self, from_s, from_len, to_s, to_len, maxcount);
+	}
+}
+
+PyDoc_STRVAR(replace__doc__,
+"S.replace (old, new[, count]) -> string\n\
+\n\
+Return a copy of string S with all occurrences of substring\n\
+old replaced by new.  If the optional argument count is\n\
+given, only the first count occurrences are replaced.");
+
+static PyObject *
+string_replace(PyStringObject *self, PyObject *args)
+{
+	Py_ssize_t count = -1;
+	PyObject *from, *to;
+	const char *from_s, *to_s;
+	Py_ssize_t from_len, to_len;
+
+	if (!PyArg_ParseTuple(args, "OO|n:replace", &from, &to, &count))
+		return NULL;
+
+	if (PyString_Check(from)) {
+		from_s = PyString_AS_STRING(from);
+		from_len = PyString_GET_SIZE(from);
+	}
+#ifdef Py_USING_UNICODE
+	if (PyUnicode_Check(from))
+		return PyUnicode_Replace((PyObject *)self,
+					 from, to, count);
+#endif
+	else if (PyObject_AsCharBuffer(from, &from_s, &from_len))
+		return NULL;
+
+	if (PyString_Check(to)) {
+		to_s = PyString_AS_STRING(to);
+		to_len = PyString_GET_SIZE(to);
+	}
+#ifdef Py_USING_UNICODE
+	else if (PyUnicode_Check(to))
+		return PyUnicode_Replace((PyObject *)self,
+					 from, to, count);
+#endif
+	else if (PyObject_AsCharBuffer(to, &to_s, &to_len))
+		return NULL;
+
+	return (PyObject *)replace((PyStringObject *) self,
+				   from_s, from_len,
+				   to_s, to_len, count);
+}
+
+/** End DALKE **/
+
+/* Matches the end (direction >= 0) or start (direction < 0) of self
+ * against substr, using the start and end arguments. Returns
+ * -1 on error, 0 if not found and 1 if found.
+ */
+Py_LOCAL(int)
+_string_tailmatch(PyStringObject *self, PyObject *substr, Py_ssize_t start,
+		  Py_ssize_t end, int direction)
+{
+	Py_ssize_t len = PyString_GET_SIZE(self);
+	Py_ssize_t slen;
+	const char* sub;
+	const char* str;
+
+	if (PyString_Check(substr)) {
+		sub = PyString_AS_STRING(substr);
+		slen = PyString_GET_SIZE(substr);
+	}
+#ifdef Py_USING_UNICODE
+	else if (PyUnicode_Check(substr))
+		return PyUnicode_Tailmatch((PyObject *)self,
+					   substr, start, end, direction);
+#endif
+	else if (PyObject_AsCharBuffer(substr, &sub, &slen))
+		return -1;
+	str = PyString_AS_STRING(self);
+
+	string_adjust_indices(&start, &end, len);
+
+	if (direction < 0) {
+		/* startswith */
+		if (start+slen > len)
+			return 0;
+	} else {
+		/* endswith */
+		if (end-start < slen || start > len)
+			return 0;
+
+		if (end-slen > start)
+			start = end - slen;
+	}
+	if (end-start >= slen)
+		return ! memcmp(str+start, sub, slen);
+	return 0;
+}
+
+
+PyDoc_STRVAR(startswith__doc__,
+"S.startswith(prefix[, start[, end]]) -> bool\n\
+\n\
+Return True if S starts with the specified prefix, False otherwise.\n\
+With optional start, test S beginning at that position.\n\
+With optional end, stop comparing S at that position.\n\
+prefix can also be a tuple of strings to try.");
+
+static PyObject *
+string_startswith(PyStringObject *self, PyObject *args)
+{
+	Py_ssize_t start = 0;
+	Py_ssize_t end = PY_SSIZE_T_MAX;
+	PyObject *subobj;
+	int result;
+
+	if (!PyArg_ParseTuple(args, "O|O&O&:startswith", &subobj,
+		_PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
+		return NULL;
+	if (PyTuple_Check(subobj)) {
+		Py_ssize_t i;
+		for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
+			result = _string_tailmatch(self,
+					PyTuple_GET_ITEM(subobj, i),
+					start, end, -1);
+			if (result == -1)
+				return NULL;
+			else if (result) {
+				Py_RETURN_TRUE;
+			}
+		}
+		Py_RETURN_FALSE;
+	}
+	result = _string_tailmatch(self, subobj, start, end, -1);
+	if (result == -1)
+		return NULL;
+	else
+		return PyBool_FromLong(result);
+}
+
+
+PyDoc_STRVAR(endswith__doc__,
+"S.endswith(suffix[, start[, end]]) -> bool\n\
+\n\
+Return True if S ends with the specified suffix, False otherwise.\n\
+With optional start, test S beginning at that position.\n\
+With optional end, stop comparing S at that position.\n\
+suffix can also be a tuple of strings to try.");
+
+static PyObject *
+string_endswith(PyStringObject *self, PyObject *args)
+{
+	Py_ssize_t start = 0;
+	Py_ssize_t end = PY_SSIZE_T_MAX;
+	PyObject *subobj;
+	int result;
+
+	if (!PyArg_ParseTuple(args, "O|O&O&:endswith", &subobj,
+		_PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
+		return NULL;
+	if (PyTuple_Check(subobj)) {
+		Py_ssize_t i;
+		for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
+			result = _string_tailmatch(self,
+					PyTuple_GET_ITEM(subobj, i),
+					start, end, +1);
+			if (result == -1)
+				return NULL;
+			else if (result) {
+				Py_RETURN_TRUE;
+			}
+		}
+		Py_RETURN_FALSE;
+	}
+	result = _string_tailmatch(self, subobj, start, end, +1);
+	if (result == -1)
+		return NULL;
+	else
+		return PyBool_FromLong(result);
+}
+
+
+PyDoc_STRVAR(encode__doc__,
+"S.encode([encoding[,errors]]) -> object\n\
+\n\
+Encodes S using the codec registered for encoding. encoding defaults\n\
+to the default encoding. errors may be given to set a different error\n\
+handling scheme. Default is 'strict' meaning that encoding errors raise\n\
+a UnicodeEncodeError. Other possible values are 'ignore', 'replace' and\n\
+'xmlcharrefreplace' as well as any other name registered with\n\
+codecs.register_error that is able to handle UnicodeEncodeErrors.");
+
+static PyObject *
+string_encode(PyStringObject *self, PyObject *args)
+{
+    char *encoding = NULL;
+    char *errors = NULL;
+    PyObject *v;
+
+    if (!PyArg_ParseTuple(args, "|ss:encode", &encoding, &errors))
+        return NULL;
+    v = PyString_AsEncodedObject((PyObject *)self, encoding, errors);
+    if (v == NULL)
+        goto onError;
+    if (!PyString_Check(v) && !PyUnicode_Check(v)) {
+        PyErr_Format(PyExc_TypeError,
+                     "encoder did not return a string/unicode object "
+                     "(type=%.400s)",
+                     v->ob_type->tp_name);
+        Py_DECREF(v);
+        return NULL;
+    }
+    return v;
+
+ onError:
+    return NULL;
+}
+
+
+PyDoc_STRVAR(decode__doc__,
+"S.decode([encoding[,errors]]) -> object\n\
+\n\
+Decodes S using the codec registered for encoding. encoding defaults\n\
+to the default encoding. errors may be given to set a different error\n\
+handling scheme. Default is 'strict' meaning that encoding errors raise\n\
+a UnicodeDecodeError. Other possible values are 'ignore' and 'replace'\n\
+as well as any other name registerd with codecs.register_error that is\n\
+able to handle UnicodeDecodeErrors.");
+
+static PyObject *
+string_decode(PyStringObject *self, PyObject *args)
+{
+    char *encoding = NULL;
+    char *errors = NULL;
+    PyObject *v;
+
+    if (!PyArg_ParseTuple(args, "|ss:decode", &encoding, &errors))
+        return NULL;
+    v = PyString_AsDecodedObject((PyObject *)self, encoding, errors);
+    if (v == NULL)
+        goto onError;
+    if (!PyString_Check(v) && !PyUnicode_Check(v)) {
+        PyErr_Format(PyExc_TypeError,
+                     "decoder did not return a string/unicode object "
+                     "(type=%.400s)",
+                     v->ob_type->tp_name);
+        Py_DECREF(v);
+        return NULL;
+    }
+    return v;
+
+ onError:
+    return NULL;
+}
+
+
+PyDoc_STRVAR(expandtabs__doc__,
+"S.expandtabs([tabsize]) -> string\n\
+\n\
+Return a copy of S where all tab characters are expanded using spaces.\n\
+If tabsize is not given, a tab size of 8 characters is assumed.");
+
+static PyObject*
+string_expandtabs(PyStringObject *self, PyObject *args)
+{
+    const char *e, *p;
+    char *q;
+    Py_ssize_t i, j;
+    PyObject *u;
+    int tabsize = 8;
+
+    if (!PyArg_ParseTuple(args, "|i:expandtabs", &tabsize))
+	return NULL;
+
+    /* First pass: determine size of output string */
+    i = j = 0;
+    e = PyString_AS_STRING(self) + PyString_GET_SIZE(self);
+    for (p = PyString_AS_STRING(self); p < e; p++)
+        if (*p == '\t') {
+	    if (tabsize > 0)
+		j += tabsize - (j % tabsize);
+	}
+        else {
+            j++;
+            if (*p == '\n' || *p == '\r') {
+                i += j;
+                j = 0;
+            }
+        }
+
+    /* Second pass: create output string and fill it */
+    u = PyString_FromStringAndSize(NULL, i + j);
+    if (!u)
+        return NULL;
+
+    j = 0;
+    q = PyString_AS_STRING(u);
+
+    for (p = PyString_AS_STRING(self); p < e; p++)
+        if (*p == '\t') {
+	    if (tabsize > 0) {
+		i = tabsize - (j % tabsize);
+		j += i;
+		while (i--)
+		    *q++ = ' ';
+	    }
+	}
+	else {
+            j++;
+	    *q++ = *p;
+            if (*p == '\n' || *p == '\r')
+                j = 0;
+        }
+
+    return u;
+}
+
+Py_LOCAL_INLINE(PyObject *)
+pad(PyStringObject *self, Py_ssize_t left, Py_ssize_t right, char fill)
+{
+    PyObject *u;
+
+    if (left < 0)
+        left = 0;
+    if (right < 0)
+        right = 0;
+
+    if (left == 0 && right == 0 && PyString_CheckExact(self)) {
+        Py_INCREF(self);
+        return (PyObject *)self;
+    }
+
+    u = PyString_FromStringAndSize(NULL,
+				   left + PyString_GET_SIZE(self) + right);
+    if (u) {
+        if (left)
+            memset(PyString_AS_STRING(u), fill, left);
+        Py_MEMCPY(PyString_AS_STRING(u) + left,
+	       PyString_AS_STRING(self),
+	       PyString_GET_SIZE(self));
+        if (right)
+            memset(PyString_AS_STRING(u) + left + PyString_GET_SIZE(self),
+		   fill, right);
+    }
+
+    return u;
+}
+
+PyDoc_STRVAR(ljust__doc__,
+"S.ljust(width[, fillchar]) -> string\n"
+"\n"
+"Return S left justified in a string of length width. Padding is\n"
+"done using the specified fill character (default is a space).");
+
+static PyObject *
+string_ljust(PyStringObject *self, PyObject *args)
+{
+    Py_ssize_t width;
+    char fillchar = ' ';
+
+    if (!PyArg_ParseTuple(args, "n|c:ljust", &width, &fillchar))
+        return NULL;
+
+    if (PyString_GET_SIZE(self) >= width && PyString_CheckExact(self)) {
+        Py_INCREF(self);
+        return (PyObject*) self;
+    }
+
+    return pad(self, 0, width - PyString_GET_SIZE(self), fillchar);
+}
+
+
+PyDoc_STRVAR(rjust__doc__,
+"S.rjust(width[, fillchar]) -> string\n"
+"\n"
+"Return S right justified in a string of length width. Padding is\n"
+"done using the specified fill character (default is a space)");
+
+static PyObject *
+string_rjust(PyStringObject *self, PyObject *args)
+{
+    Py_ssize_t width;
+    char fillchar = ' ';
+
+    if (!PyArg_ParseTuple(args, "n|c:rjust", &width, &fillchar))
+        return NULL;
+
+    if (PyString_GET_SIZE(self) >= width && PyString_CheckExact(self)) {
+        Py_INCREF(self);
+        return (PyObject*) self;
+    }
+
+    return pad(self, width - PyString_GET_SIZE(self), 0, fillchar);
+}
+
+
+PyDoc_STRVAR(center__doc__,
+"S.center(width[, fillchar]) -> string\n"
+"\n"
+"Return S centered in a string of length width. Padding is\n"
+"done using the specified fill character (default is a space)");
+
+static PyObject *
+string_center(PyStringObject *self, PyObject *args)
+{
+    Py_ssize_t marg, left;
+    Py_ssize_t width;
+    char fillchar = ' ';
+
+    if (!PyArg_ParseTuple(args, "n|c:center", &width, &fillchar))
+        return NULL;
+
+    if (PyString_GET_SIZE(self) >= width && PyString_CheckExact(self)) {
+        Py_INCREF(self);
+        return (PyObject*) self;
+    }
+
+    marg = width - PyString_GET_SIZE(self);
+    left = marg / 2 + (marg & width & 1);
+
+    return pad(self, left, marg - left, fillchar);
+}
+
+PyDoc_STRVAR(zfill__doc__,
+"S.zfill(width) -> string\n"
+"\n"
+"Pad a numeric string S with zeros on the left, to fill a field\n"
+"of the specified width.  The string S is never truncated.");
+
+static PyObject *
+string_zfill(PyStringObject *self, PyObject *args)
+{
+    Py_ssize_t fill;
+    PyObject *s;
+    char *p;
+    Py_ssize_t width;
+
+    if (!PyArg_ParseTuple(args, "n:zfill", &width))
+        return NULL;
+
+    if (PyString_GET_SIZE(self) >= width) {
+        if (PyString_CheckExact(self)) {
+            Py_INCREF(self);
+            return (PyObject*) self;
+        }
+        else
+            return PyString_FromStringAndSize(
+                PyString_AS_STRING(self),
+                PyString_GET_SIZE(self)
+            );
+    }
+
+    fill = width - PyString_GET_SIZE(self);
+
+    s = pad(self, fill, 0, '0');
+
+    if (s == NULL)
+        return NULL;
+
+    p = PyString_AS_STRING(s);
+    if (p[fill] == '+' || p[fill] == '-') {
+        /* move sign to beginning of string */
+        p[0] = p[fill];
+        p[fill] = '0';
+    }
+
+    return (PyObject*) s;
+}
+
+PyDoc_STRVAR(isspace__doc__,
+"S.isspace() -> bool\n\
+\n\
+Return True if all characters in S are whitespace\n\
+and there is at least one character in S, False otherwise.");
+
+static PyObject*
+string_isspace(PyStringObject *self)
+{
+    register const unsigned char *p
+        = (unsigned char *) PyString_AS_STRING(self);
+    register const unsigned char *e;
+
+    /* Shortcut for single character strings */
+    if (PyString_GET_SIZE(self) == 1 &&
+	isspace(*p))
+	return PyBool_FromLong(1);
+
+    /* Special case for empty strings */
+    if (PyString_GET_SIZE(self) == 0)
+	return PyBool_FromLong(0);
+
+    e = p + PyString_GET_SIZE(self);
+    for (; p < e; p++) {
+	if (!isspace(*p))
+	    return PyBool_FromLong(0);
+    }
+    return PyBool_FromLong(1);
+}
+
+
+PyDoc_STRVAR(isalpha__doc__,
+"S.isalpha() -> bool\n\
+\n\
+Return True if all characters in S are alphabetic\n\
+and there is at least one character in S, False otherwise.");
+
+static PyObject*
+string_isalpha(PyStringObject *self)
+{
+    register const unsigned char *p
+        = (unsigned char *) PyString_AS_STRING(self);
+    register const unsigned char *e;
+
+    /* Shortcut for single character strings */
+    if (PyString_GET_SIZE(self) == 1 &&
+	isalpha(*p))
+	return PyBool_FromLong(1);
+
+    /* Special case for empty strings */
+    if (PyString_GET_SIZE(self) == 0)
+	return PyBool_FromLong(0);
+
+    e = p + PyString_GET_SIZE(self);
+    for (; p < e; p++) {
+	if (!isalpha(*p))
+	    return PyBool_FromLong(0);
+    }
+    return PyBool_FromLong(1);
+}
+
+
+PyDoc_STRVAR(isalnum__doc__,
+"S.isalnum() -> bool\n\
+\n\
+Return True if all characters in S are alphanumeric\n\
+and there is at least one character in S, False otherwise.");
+
+static PyObject*
+string_isalnum(PyStringObject *self)
+{
+    register const unsigned char *p
+        = (unsigned char *) PyString_AS_STRING(self);
+    register const unsigned char *e;
+
+    /* Shortcut for single character strings */
+    if (PyString_GET_SIZE(self) == 1 &&
+	isalnum(*p))
+	return PyBool_FromLong(1);
+
+    /* Special case for empty strings */
+    if (PyString_GET_SIZE(self) == 0)
+	return PyBool_FromLong(0);
+
+    e = p + PyString_GET_SIZE(self);
+    for (; p < e; p++) {
+	if (!isalnum(*p))
+	    return PyBool_FromLong(0);
+    }
+    return PyBool_FromLong(1);
+}
+
+
+PyDoc_STRVAR(isdigit__doc__,
+"S.isdigit() -> bool\n\
+\n\
+Return True if all characters in S are digits\n\
+and there is at least one character in S, False otherwise.");
+
+static PyObject*
+string_isdigit(PyStringObject *self)
+{
+    register const unsigned char *p
+        = (unsigned char *) PyString_AS_STRING(self);
+    register const unsigned char *e;
+
+    /* Shortcut for single character strings */
+    if (PyString_GET_SIZE(self) == 1 &&
+	isdigit(*p))
+	return PyBool_FromLong(1);
+
+    /* Special case for empty strings */
+    if (PyString_GET_SIZE(self) == 0)
+	return PyBool_FromLong(0);
+
+    e = p + PyString_GET_SIZE(self);
+    for (; p < e; p++) {
+	if (!isdigit(*p))
+	    return PyBool_FromLong(0);
+    }
+    return PyBool_FromLong(1);
+}
+
+
+PyDoc_STRVAR(islower__doc__,
+"S.islower() -> bool\n\
+\n\
+Return True if all cased characters in S are lowercase and there is\n\
+at least one cased character in S, False otherwise.");
+
+static PyObject*
+string_islower(PyStringObject *self)
+{
+    register const unsigned char *p
+        = (unsigned char *) PyString_AS_STRING(self);
+    register const unsigned char *e;
+    int cased;
+
+    /* Shortcut for single character strings */
+    if (PyString_GET_SIZE(self) == 1)
+	return PyBool_FromLong(islower(*p) != 0);
+
+    /* Special case for empty strings */
+    if (PyString_GET_SIZE(self) == 0)
+	return PyBool_FromLong(0);
+
+    e = p + PyString_GET_SIZE(self);
+    cased = 0;
+    for (; p < e; p++) {
+	if (isupper(*p))
+	    return PyBool_FromLong(0);
+	else if (!cased && islower(*p))
+	    cased = 1;
+    }
+    return PyBool_FromLong(cased);
+}
+
+
+PyDoc_STRVAR(isupper__doc__,
+"S.isupper() -> bool\n\
+\n\
+Return True if all cased characters in S are uppercase and there is\n\
+at least one cased character in S, False otherwise.");
+
+static PyObject*
+string_isupper(PyStringObject *self)
+{
+    register const unsigned char *p
+        = (unsigned char *) PyString_AS_STRING(self);
+    register const unsigned char *e;
+    int cased;
+
+    /* Shortcut for single character strings */
+    if (PyString_GET_SIZE(self) == 1)
+	return PyBool_FromLong(isupper(*p) != 0);
+
+    /* Special case for empty strings */
+    if (PyString_GET_SIZE(self) == 0)
+	return PyBool_FromLong(0);
+
+    e = p + PyString_GET_SIZE(self);
+    cased = 0;
+    for (; p < e; p++) {
+	if (islower(*p))
+	    return PyBool_FromLong(0);
+	else if (!cased && isupper(*p))
+	    cased = 1;
+    }
+    return PyBool_FromLong(cased);
+}
+
+
+PyDoc_STRVAR(istitle__doc__,
+"S.istitle() -> bool\n\
+\n\
+Return True if S is a titlecased string and there is at least one\n\
+character in S, i.e. uppercase characters may only follow uncased\n\
+characters and lowercase characters only cased ones. Return False\n\
+otherwise.");
+
+static PyObject*
+string_istitle(PyStringObject *self, PyObject *uncased)
+{
+    register const unsigned char *p
+        = (unsigned char *) PyString_AS_STRING(self);
+    register const unsigned char *e;
+    int cased, previous_is_cased;
+
+    /* Shortcut for single character strings */
+    if (PyString_GET_SIZE(self) == 1)
+	return PyBool_FromLong(isupper(*p) != 0);
+
+    /* Special case for empty strings */
+    if (PyString_GET_SIZE(self) == 0)
+	return PyBool_FromLong(0);
+
+    e = p + PyString_GET_SIZE(self);
+    cased = 0;
+    previous_is_cased = 0;
+    for (; p < e; p++) {
+	register const unsigned char ch = *p;
+
+	if (isupper(ch)) {
+	    if (previous_is_cased)
+		return PyBool_FromLong(0);
+	    previous_is_cased = 1;
+	    cased = 1;
+	}
+	else if (islower(ch)) {
+	    if (!previous_is_cased)
+		return PyBool_FromLong(0);
+	    previous_is_cased = 1;
+	    cased = 1;
+	}
+	else
+	    previous_is_cased = 0;
+    }
+    return PyBool_FromLong(cased);
+}
+
+
+PyDoc_STRVAR(splitlines__doc__,
+"S.splitlines([keepends]) -> list of strings\n\
+\n\
+Return a list of the lines in S, breaking at line boundaries.\n\
+Line breaks are not included in the resulting list unless keepends\n\
+is given and true.");
+
+static PyObject*
+string_splitlines(PyStringObject *self, PyObject *args)
+{
+    register Py_ssize_t i;
+    register Py_ssize_t j;
+    Py_ssize_t len;
+    int keepends = 0;
+    PyObject *list;
+    PyObject *str;
+    char *data;
+
+    if (!PyArg_ParseTuple(args, "|i:splitlines", &keepends))
+        return NULL;
+
+    data = PyString_AS_STRING(self);
+    len = PyString_GET_SIZE(self);
+
+    /* This does not use the preallocated list because splitlines is
+       usually run with hundreds of newlines.  The overhead of
+       switching between PyList_SET_ITEM and append causes about a
+       2-3% slowdown for that common case.  A smarter implementation
+       could move the if check out, so the SET_ITEMs are done first
+       and the appends only done when the prealloc buffer is full.
+       That's too much work for little gain.*/
+
+    list = PyList_New(0);
+    if (!list)
+        goto onError;
+
+    for (i = j = 0; i < len; ) {
+	Py_ssize_t eol;
+
+	/* Find a line and append it */
+	while (i < len && data[i] != '\n' && data[i] != '\r')
+	    i++;
+
+	/* Skip the line break reading CRLF as one line break */
+	eol = i;
+	if (i < len) {
+	    if (data[i] == '\r' && i + 1 < len &&
+		data[i+1] == '\n')
+		i += 2;
+	    else
+		i++;
+	    if (keepends)
+		eol = i;
+	}
+	SPLIT_APPEND(data, j, eol);
+	j = i;
+    }
+    if (j < len) {
+	SPLIT_APPEND(data, j, len);
+    }
+
+    return list;
+
+ onError:
+    Py_XDECREF(list);
+    return NULL;
+}
+
+#undef SPLIT_APPEND
+#undef SPLIT_ADD
+#undef MAX_PREALLOC
+#undef PREALLOC_SIZE
+
+static PyObject *
+string_getnewargs(PyStringObject *v)
+{
+	return Py_BuildValue("(s#)", v->ob_sval, v->ob_size);
+}
+
+
+static PyMethodDef
+string_methods[] = {
+	/* Counterparts of the obsolete stropmodule functions; except
+	   string.maketrans(). */
+	{"join", (PyCFunction)string_join, METH_O, join__doc__},
+	{"split", (PyCFunction)string_split, METH_VARARGS, split__doc__},
+	{"rsplit", (PyCFunction)string_rsplit, METH_VARARGS, rsplit__doc__},
+	{"lower", (PyCFunction)string_lower, METH_NOARGS, lower__doc__},
+	{"upper", (PyCFunction)string_upper, METH_NOARGS, upper__doc__},
+	{"islower", (PyCFunction)string_islower, METH_NOARGS, islower__doc__},
+	{"isupper", (PyCFunction)string_isupper, METH_NOARGS, isupper__doc__},
+	{"isspace", (PyCFunction)string_isspace, METH_NOARGS, isspace__doc__},
+	{"isdigit", (PyCFunction)string_isdigit, METH_NOARGS, isdigit__doc__},
+	{"istitle", (PyCFunction)string_istitle, METH_NOARGS, istitle__doc__},
+	{"isalpha", (PyCFunction)string_isalpha, METH_NOARGS, isalpha__doc__},
+	{"isalnum", (PyCFunction)string_isalnum, METH_NOARGS, isalnum__doc__},
+	{"capitalize", (PyCFunction)string_capitalize, METH_NOARGS,
+	 capitalize__doc__},
+	{"count", (PyCFunction)string_count, METH_VARARGS, count__doc__},
+	{"endswith", (PyCFunction)string_endswith, METH_VARARGS,
+	 endswith__doc__},
+	{"partition", (PyCFunction)string_partition, METH_O, partition__doc__},
+	{"find", (PyCFunction)string_find, METH_VARARGS, find__doc__},
+	{"index", (PyCFunction)string_index, METH_VARARGS, index__doc__},
+	{"lstrip", (PyCFunction)string_lstrip, METH_VARARGS, lstrip__doc__},
+	{"replace", (PyCFunction)string_replace, METH_VARARGS, replace__doc__},
+	{"rfind", (PyCFunction)string_rfind, METH_VARARGS, rfind__doc__},
+	{"rindex", (PyCFunction)string_rindex, METH_VARARGS, rindex__doc__},
+	{"rstrip", (PyCFunction)string_rstrip, METH_VARARGS, rstrip__doc__},
+	{"rpartition", (PyCFunction)string_rpartition, METH_O,
+	 rpartition__doc__},
+	{"startswith", (PyCFunction)string_startswith, METH_VARARGS,
+	 startswith__doc__},
+	{"strip", (PyCFunction)string_strip, METH_VARARGS, strip__doc__},
+	{"swapcase", (PyCFunction)string_swapcase, METH_NOARGS,
+	 swapcase__doc__},
+	{"translate", (PyCFunction)string_translate, METH_VARARGS,
+	 translate__doc__},
+	{"title", (PyCFunction)string_title, METH_NOARGS, title__doc__},
+	{"ljust", (PyCFunction)string_ljust, METH_VARARGS, ljust__doc__},
+	{"rjust", (PyCFunction)string_rjust, METH_VARARGS, rjust__doc__},
+	{"center", (PyCFunction)string_center, METH_VARARGS, center__doc__},
+	{"zfill", (PyCFunction)string_zfill, METH_VARARGS, zfill__doc__},
+	{"encode", (PyCFunction)string_encode, METH_VARARGS, encode__doc__},
+	{"decode", (PyCFunction)string_decode, METH_VARARGS, decode__doc__},
+	{"expandtabs", (PyCFunction)string_expandtabs, METH_VARARGS,
+	 expandtabs__doc__},
+	{"splitlines", (PyCFunction)string_splitlines, METH_VARARGS,
+	 splitlines__doc__},
+	{"__getnewargs__",	(PyCFunction)string_getnewargs,	METH_NOARGS},
+	{NULL,     NULL}		     /* sentinel */
+};
+
+static PyObject *
+str_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
+
+static PyObject *
+string_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	PyObject *x = NULL;
+	static char *kwlist[] = {"object", 0};
+
+	if (type != &PyString_Type)
+		return str_subtype_new(type, args, kwds);
+	if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:str", kwlist, &x))
+		return NULL;
+	if (x == NULL)
+		return PyString_FromString("");
+	return PyObject_Str(x);
+}
+
+static PyObject *
+str_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	PyObject *tmp, *pnew;
+	Py_ssize_t n;
+
+	assert(PyType_IsSubtype(type, &PyString_Type));
+	tmp = string_new(&PyString_Type, args, kwds);
+	if (tmp == NULL)
+		return NULL;
+	assert(PyString_CheckExact(tmp));
+	n = PyString_GET_SIZE(tmp);
+	pnew = type->tp_alloc(type, n);
+	if (pnew != NULL) {
+		Py_MEMCPY(PyString_AS_STRING(pnew), PyString_AS_STRING(tmp), n+1);
+		((PyStringObject *)pnew)->ob_shash =
+			((PyStringObject *)tmp)->ob_shash;
+		((PyStringObject *)pnew)->ob_sstate = SSTATE_NOT_INTERNED;
+	}
+	Py_DECREF(tmp);
+	return pnew;
+}
+
+static PyObject *
+basestring_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	PyErr_SetString(PyExc_TypeError,
+			"The basestring type cannot be instantiated");
+	return NULL;
+}
+
+static PyObject *
+string_mod(PyObject *v, PyObject *w)
+{
+	if (!PyString_Check(v)) {
+		Py_INCREF(Py_NotImplemented);
+		return Py_NotImplemented;
+	}
+	return PyString_Format(v, w);
+}
+
+PyDoc_STRVAR(basestring_doc,
+"Type basestring cannot be instantiated; it is the base for str and unicode.");
+
+static PyNumberMethods string_as_number = {
+	0,			/*nb_add*/
+	0,			/*nb_subtract*/
+	0,			/*nb_multiply*/
+	0, 			/*nb_divide*/
+	string_mod,		/*nb_remainder*/
+};
+
+
+PyTypeObject PyBaseString_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,
+	"basestring",
+	0,
+	0,
+ 	0,			 		/* tp_dealloc */
+	0,			 		/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	0,		 			/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,		 			/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	0,					/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+	basestring_doc,				/* tp_doc */
+	0,					/* tp_traverse */
+	0,					/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	0,					/* tp_methods */
+	0,					/* tp_members */
+	0,					/* tp_getset */
+	&PyBaseObject_Type,			/* tp_base */
+	0,					/* tp_dict */
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	0,					/* tp_init */
+	0,					/* tp_alloc */
+	basestring_new,				/* tp_new */
+	0,		                	/* tp_free */
+};
+
+PyDoc_STRVAR(string_doc,
+"str(object) -> string\n\
+\n\
+Return a nice string representation of the object.\n\
+If the argument is a string, the return value is the same object.");
+
+PyTypeObject PyString_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,
+	"str",
+	sizeof(PyStringObject),
+	sizeof(char),
+ 	string_dealloc, 			/* tp_dealloc */
+	(printfunc)string_print, 		/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	string_repr, 				/* tp_repr */
+	&string_as_number,			/* tp_as_number */
+	&string_as_sequence,			/* tp_as_sequence */
+	&string_as_mapping,			/* tp_as_mapping */
+	(hashfunc)string_hash, 			/* tp_hash */
+	0,					/* tp_call */
+	string_str,				/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	0,					/* tp_setattro */
+	&string_as_buffer,			/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
+		Py_TPFLAGS_BASETYPE,		/* tp_flags */
+	string_doc,				/* tp_doc */
+	0,					/* tp_traverse */
+	0,					/* tp_clear */
+	(richcmpfunc)string_richcompare,	/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	string_methods,				/* tp_methods */
+	0,					/* tp_members */
+	0,					/* tp_getset */
+	&PyBaseString_Type,			/* tp_base */
+	0,					/* tp_dict */
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	0,					/* tp_init */
+	0,					/* tp_alloc */
+	string_new,				/* tp_new */
+	PyObject_Del,	                	/* tp_free */
+};
+
+void
+PyString_Concat(register PyObject **pv, register PyObject *w)
+{
+	register PyObject *v;
+	if (*pv == NULL)
+		return;
+	if (w == NULL || !PyString_Check(*pv)) {
+		Py_DECREF(*pv);
+		*pv = NULL;
+		return;
+	}
+	v = string_concat((PyStringObject *) *pv, w);
+	Py_DECREF(*pv);
+	*pv = v;
+}
+
+void
+PyString_ConcatAndDel(register PyObject **pv, register PyObject *w)
+{
+	PyString_Concat(pv, w);
+	Py_XDECREF(w);
+}
+
+
+/* The following function breaks the notion that strings are immutable:
+   it changes the size of a string.  We get away with this only if there
+   is only one module referencing the object.  You can also think of it
+   as creating a new string object and destroying the old one, only
+   more efficiently.  In any case, don't use this if the string may
+   already be known to some other part of the code...
+   Note that if there's not enough memory to resize the string, the original
+   string object at *pv is deallocated, *pv is set to NULL, an "out of
+   memory" exception is set, and -1 is returned.  Else (on success) 0 is
+   returned, and the value in *pv may or may not be the same as on input.
+   As always, an extra byte is allocated for a trailing \0 byte (newsize
+   does *not* include that), and a trailing \0 byte is stored.
+*/
+
+int
+_PyString_Resize(PyObject **pv, Py_ssize_t newsize)
+{
+	register PyObject *v;
+	register PyStringObject *sv;
+	v = *pv;
+	if (!PyString_Check(v) || v->ob_refcnt != 1 || newsize < 0 ||
+	    PyString_CHECK_INTERNED(v)) {
+		*pv = 0;
+		Py_DECREF(v);
+		PyErr_BadInternalCall();
+		return -1;
+	}
+	/* XXX UNREF/NEWREF interface should be more symmetrical */
+	_Py_DEC_REFTOTAL;
+	_Py_ForgetReference(v);
+	*pv = (PyObject *)
+		PyObject_REALLOC((char *)v, sizeof(PyStringObject) + newsize);
+	if (*pv == NULL) {
+		PyObject_Del(v);
+		PyErr_NoMemory();
+		return -1;
+	}
+	_Py_NewReference(*pv);
+	sv = (PyStringObject *) *pv;
+	sv->ob_size = newsize;
+	sv->ob_sval[newsize] = '\0';
+	sv->ob_shash = -1;	/* invalidate cached hash value */
+	return 0;
+}
+
+/* Helpers for formatstring */
+
+Py_LOCAL_INLINE(PyObject *)
+getnextarg(PyObject *args, Py_ssize_t arglen, Py_ssize_t *p_argidx)
+{
+	Py_ssize_t argidx = *p_argidx;
+	if (argidx < arglen) {
+		(*p_argidx)++;
+		if (arglen < 0)
+			return args;
+		else
+			return PyTuple_GetItem(args, argidx);
+	}
+	PyErr_SetString(PyExc_TypeError,
+			"not enough arguments for format string");
+	return NULL;
+}
+
+/* Format codes
+ * F_LJUST	'-'
+ * F_SIGN	'+'
+ * F_BLANK	' '
+ * F_ALT	'#'
+ * F_ZERO	'0'
+ */
+#define F_LJUST (1<<0)
+#define F_SIGN	(1<<1)
+#define F_BLANK (1<<2)
+#define F_ALT	(1<<3)
+#define F_ZERO	(1<<4)
+
+Py_LOCAL_INLINE(int)
+formatfloat(char *buf, size_t buflen, int flags,
+            int prec, int type, PyObject *v)
+{
+	/* fmt = '%#.' + `prec` + `type`
+	   worst case length = 3 + 10 (len of INT_MAX) + 1 = 14 (use 20)*/
+	char fmt[20];
+	double x;
+	x = PyFloat_AsDouble(v);
+	if (x == -1.0 && PyErr_Occurred()) {
+		PyErr_SetString(PyExc_TypeError, "float argument required");
+		return -1;
+	}
+	if (prec < 0)
+		prec = 6;
+	if (type == 'f' && fabs(x)/1e25 >= 1e25)
+		type = 'g';
+	/* Worst case length calc to ensure no buffer overrun:
+
+	   'g' formats:
+	     fmt = %#.<prec>g
+	     buf = '-' + [0-9]*prec + '.' + 'e+' + (longest exp
+	        for any double rep.)
+	     len = 1 + prec + 1 + 2 + 5 = 9 + prec
+
+	   'f' formats:
+	     buf = '-' + [0-9]*x + '.' + [0-9]*prec (with x < 50)
+	     len = 1 + 50 + 1 + prec = 52 + prec
+
+	   If prec=0 the effective precision is 1 (the leading digit is
+	   always given), therefore increase the length by one.
+
+	*/
+	if ((type == 'g' && buflen <= (size_t)10 + (size_t)prec) ||
+	    (type == 'f' && buflen <= (size_t)53 + (size_t)prec)) {
+		PyErr_SetString(PyExc_OverflowError,
+			"formatted float is too long (precision too large?)");
+		return -1;
+	}
+	PyOS_snprintf(fmt, sizeof(fmt), "%%%s.%d%c",
+		      (flags&F_ALT) ? "#" : "",
+		      prec, type);
+        PyOS_ascii_formatd(buf, buflen, fmt, x);
+	return (int)strlen(buf);
+}
+
+/* _PyString_FormatLong emulates the format codes d, u, o, x and X, and
+ * the F_ALT flag, for Python's long (unbounded) ints.  It's not used for
+ * Python's regular ints.
+ * Return value:  a new PyString*, or NULL if error.
+ *  .  *pbuf is set to point into it,
+ *     *plen set to the # of chars following that.
+ *     Caller must decref it when done using pbuf.
+ *     The string starting at *pbuf is of the form
+ *         "-"? ("0x" | "0X")? digit+
+ *     "0x"/"0X" are present only for x and X conversions, with F_ALT
+ *         set in flags.  The case of hex digits will be correct,
+ *     There will be at least prec digits, zero-filled on the left if
+ *         necessary to get that many.
+ * val		object to be converted
+ * flags	bitmask of format flags; only F_ALT is looked at
+ * prec		minimum number of digits; 0-fill on left if needed
+ * type		a character in [duoxX]; u acts the same as d
+ *
+ * CAUTION:  o, x and X conversions on regular ints can never
+ * produce a '-' sign, but can for Python's unbounded ints.
+ */
+PyObject*
+_PyString_FormatLong(PyObject *val, int flags, int prec, int type,
+		     char **pbuf, int *plen)
+{
+	PyObject *result = NULL;
+	char *buf;
+	Py_ssize_t i;
+	int sign;	/* 1 if '-', else 0 */
+	int len;	/* number of characters */
+	Py_ssize_t llen;
+	int numdigits;	/* len == numnondigits + numdigits */
+	int numnondigits = 0;
+
+	switch (type) {
+	case 'd':
+	case 'u':
+		result = val->ob_type->tp_str(val);
+		break;
+	case 'o':
+		result = val->ob_type->tp_as_number->nb_oct(val);
+		break;
+	case 'x':
+	case 'X':
+		numnondigits = 2;
+		result = val->ob_type->tp_as_number->nb_hex(val);
+		break;
+	default:
+		assert(!"'type' not in [duoxX]");
+	}
+	if (!result)
+		return NULL;
+
+	buf = PyString_AsString(result);
+	if (!buf) {
+		Py_DECREF(result);
+		return NULL;
+	}
+
+	/* To modify the string in-place, there can only be one reference. */
+	if (result->ob_refcnt != 1) {
+		PyErr_BadInternalCall();
+		return NULL;
+	}
+	llen = PyString_Size(result);
+	if (llen > INT_MAX) {
+		PyErr_SetString(PyExc_ValueError, "string too large in _PyString_FormatLong");
+		return NULL;
+	}
+	len = (int)llen;
+	if (buf[len-1] == 'L') {
+		--len;
+		buf[len] = '\0';
+	}
+	sign = buf[0] == '-';
+	numnondigits += sign;
+	numdigits = len - numnondigits;
+	assert(numdigits > 0);
+
+	/* Get rid of base marker unless F_ALT */
+	if ((flags & F_ALT) == 0) {
+		/* Need to skip 0x, 0X or 0. */
+		int skipped = 0;
+		switch (type) {
+		case 'o':
+			assert(buf[sign] == '0');
+			/* If 0 is only digit, leave it alone. */
+			if (numdigits > 1) {
+				skipped = 1;
+				--numdigits;
+			}
+			break;
+		case 'x':
+		case 'X':
+			assert(buf[sign] == '0');
+			assert(buf[sign + 1] == 'x');
+			skipped = 2;
+			numnondigits -= 2;
+			break;
+		}
+		if (skipped) {
+			buf += skipped;
+			len -= skipped;
+			if (sign)
+				buf[0] = '-';
+		}
+		assert(len == numnondigits + numdigits);
+		assert(numdigits > 0);
+	}
+
+	/* Fill with leading zeroes to meet minimum width. */
+	if (prec > numdigits) {
+		PyObject *r1 = PyString_FromStringAndSize(NULL,
+					numnondigits + prec);
+		char *b1;
+		if (!r1) {
+			Py_DECREF(result);
+			return NULL;
+		}
+		b1 = PyString_AS_STRING(r1);
+		for (i = 0; i < numnondigits; ++i)
+			*b1++ = *buf++;
+		for (i = 0; i < prec - numdigits; i++)
+			*b1++ = '0';
+		for (i = 0; i < numdigits; i++)
+			*b1++ = *buf++;
+		*b1 = '\0';
+		Py_DECREF(result);
+		result = r1;
+		buf = PyString_AS_STRING(result);
+		len = numnondigits + prec;
+	}
+
+	/* Fix up case for hex conversions. */
+	if (type == 'X') {
+		/* Need to convert all lower case letters to upper case.
+		   and need to convert 0x to 0X (and -0x to -0X). */
+		for (i = 0; i < len; i++)
+			if (buf[i] >= 'a' && buf[i] <= 'x')
+				buf[i] -= 'a'-'A';
+	}
+	*pbuf = buf;
+	*plen = len;
+	return result;
+}
+
+Py_LOCAL_INLINE(int)
+formatint(char *buf, size_t buflen, int flags,
+          int prec, int type, PyObject *v)
+{
+	/* fmt = '%#.' + `prec` + 'l' + `type`
+	   worst case length = 3 + 19 (worst len of INT_MAX on 64-bit machine)
+	   + 1 + 1 = 24 */
+	char fmt[64];	/* plenty big enough! */
+	char *sign;
+	long x;
+
+	x = PyInt_AsLong(v);
+	if (x == -1 && PyErr_Occurred()) {
+		PyErr_SetString(PyExc_TypeError, "int argument required");
+		return -1;
+	}
+	if (x < 0 && type == 'u') {
+		type = 'd';
+	}
+	if (x < 0 && (type == 'x' || type == 'X' || type == 'o'))
+		sign = "-";
+	else
+		sign = "";
+	if (prec < 0)
+		prec = 1;
+
+	if ((flags & F_ALT) &&
+	    (type == 'x' || type == 'X')) {
+		/* When converting under %#x or %#X, there are a number
+		 * of issues that cause pain:
+		 * - when 0 is being converted, the C standard leaves off
+		 *   the '0x' or '0X', which is inconsistent with other
+		 *   %#x/%#X conversions and inconsistent with Python's
+		 *   hex() function
+		 * - there are platforms that violate the standard and
+		 *   convert 0 with the '0x' or '0X'
+		 *   (Metrowerks, Compaq Tru64)
+		 * - there are platforms that give '0x' when converting
+		 *   under %#X, but convert 0 in accordance with the
+		 *   standard (OS/2 EMX)
+		 *
+		 * We can achieve the desired consistency by inserting our
+		 * own '0x' or '0X' prefix, and substituting %x/%X in place
+		 * of %#x/%#X.
+		 *
+		 * Note that this is the same approach as used in
+		 * formatint() in unicodeobject.c
+		 */
+		PyOS_snprintf(fmt, sizeof(fmt), "%s0%c%%.%dl%c",
+			      sign, type, prec, type);
+	}
+	else {
+		PyOS_snprintf(fmt, sizeof(fmt), "%s%%%s.%dl%c",
+			      sign, (flags&F_ALT) ? "#" : "",
+			      prec, type);
+	}
+
+	/* buf = '+'/'-'/'' + '0'/'0x'/'' + '[0-9]'*max(prec, len(x in octal))
+	 * worst case buf = '-0x' + [0-9]*prec, where prec >= 11
+	 */
+	if (buflen <= 14 || buflen <= (size_t)3 + (size_t)prec) {
+		PyErr_SetString(PyExc_OverflowError,
+		    "formatted integer is too long (precision too large?)");
+		return -1;
+	}
+	if (sign[0])
+		PyOS_snprintf(buf, buflen, fmt, -x);
+	else
+		PyOS_snprintf(buf, buflen, fmt, x);
+	return (int)strlen(buf);
+}
+
+Py_LOCAL_INLINE(int)
+formatchar(char *buf, size_t buflen, PyObject *v)
+{
+	/* presume that the buffer is at least 2 characters long */
+	if (PyString_Check(v)) {
+		if (!PyArg_Parse(v, "c;%c requires int or char", &buf[0]))
+			return -1;
+	}
+	else {
+		if (!PyArg_Parse(v, "b;%c requires int or char", &buf[0]))
+			return -1;
+	}
+	buf[1] = '\0';
+	return 1;
+}
+
+/* fmt%(v1,v2,...) is roughly equivalent to sprintf(fmt, v1, v2, ...)
+
+   FORMATBUFLEN is the length of the buffer in which the floats, ints, &
+   chars are formatted. XXX This is a magic number. Each formatting
+   routine does bounds checking to ensure no overflow, but a better
+   solution may be to malloc a buffer of appropriate size for each
+   format. For now, the current solution is sufficient.
+*/
+#define FORMATBUFLEN (size_t)120
+
+PyObject *
+PyString_Format(PyObject *format, PyObject *args)
+{
+	char *fmt, *res;
+	Py_ssize_t arglen, argidx;
+	Py_ssize_t reslen, rescnt, fmtcnt;
+	int args_owned = 0;
+	PyObject *result, *orig_args;
+#ifdef Py_USING_UNICODE
+	PyObject *v, *w;
+#endif
+	PyObject *dict = NULL;
+	if (format == NULL || !PyString_Check(format) || args == NULL) {
+		PyErr_BadInternalCall();
+		return NULL;
+	}
+	orig_args = args;
+	fmt = PyString_AS_STRING(format);
+	fmtcnt = PyString_GET_SIZE(format);
+	reslen = rescnt = fmtcnt + 100;
+	result = PyString_FromStringAndSize((char *)NULL, reslen);
+	if (result == NULL)
+		return NULL;
+	res = PyString_AsString(result);
+	if (PyTuple_Check(args)) {
+		arglen = PyTuple_GET_SIZE(args);
+		argidx = 0;
+	}
+	else {
+		arglen = -1;
+		argidx = -2;
+	}
+	if (args->ob_type->tp_as_mapping && !PyTuple_Check(args) &&
+	    !PyObject_TypeCheck(args, &PyBaseString_Type))
+		dict = args;
+	while (--fmtcnt >= 0) {
+		if (*fmt != '%') {
+			if (--rescnt < 0) {
+				rescnt = fmtcnt + 100;
+				reslen += rescnt;
+				if (_PyString_Resize(&result, reslen) < 0)
+					return NULL;
+				res = PyString_AS_STRING(result)
+					+ reslen - rescnt;
+				--rescnt;
+			}
+			*res++ = *fmt++;
+		}
+		else {
+			/* Got a format specifier */
+			int flags = 0;
+			Py_ssize_t width = -1;
+			int prec = -1;
+			int c = '\0';
+			int fill;
+			PyObject *v = NULL;
+			PyObject *temp = NULL;
+			char *pbuf;
+			int sign;
+			Py_ssize_t len;
+			char formatbuf[FORMATBUFLEN];
+			     /* For format{float,int,char}() */
+#ifdef Py_USING_UNICODE
+			char *fmt_start = fmt;
+			Py_ssize_t argidx_start = argidx;
+#endif
+
+			fmt++;
+			if (*fmt == '(') {
+				char *keystart;
+				Py_ssize_t keylen;
+				PyObject *key;
+				int pcount = 1;
+
+				if (dict == NULL) {
+					PyErr_SetString(PyExc_TypeError,
+						 "format requires a mapping");
+					goto error;
+				}
+				++fmt;
+				--fmtcnt;
+				keystart = fmt;
+				/* Skip over balanced parentheses */
+				while (pcount > 0 && --fmtcnt >= 0) {
+					if (*fmt == ')')
+						--pcount;
+					else if (*fmt == '(')
+						++pcount;
+					fmt++;
+				}
+				keylen = fmt - keystart - 1;
+				if (fmtcnt < 0 || pcount > 0) {
+					PyErr_SetString(PyExc_ValueError,
+						   "incomplete format key");
+					goto error;
+				}
+				key = PyString_FromStringAndSize(keystart,
+								 keylen);
+				if (key == NULL)
+					goto error;
+				if (args_owned) {
+					Py_DECREF(args);
+					args_owned = 0;
+				}
+				args = PyObject_GetItem(dict, key);
+				Py_DECREF(key);
+				if (args == NULL) {
+					goto error;
+				}
+				args_owned = 1;
+				arglen = -1;
+				argidx = -2;
+			}
+			while (--fmtcnt >= 0) {
+				switch (c = *fmt++) {
+				case '-': flags |= F_LJUST; continue;
+				case '+': flags |= F_SIGN; continue;
+				case ' ': flags |= F_BLANK; continue;
+				case '#': flags |= F_ALT; continue;
+				case '0': flags |= F_ZERO; continue;
+				}
+				break;
+			}
+			if (c == '*') {
+				v = getnextarg(args, arglen, &argidx);
+				if (v == NULL)
+					goto error;
+				if (!PyInt_Check(v)) {
+					PyErr_SetString(PyExc_TypeError,
+							"* wants int");
+					goto error;
+				}
+				width = PyInt_AsLong(v);
+				if (width < 0) {
+					flags |= F_LJUST;
+					width = -width;
+				}
+				if (--fmtcnt >= 0)
+					c = *fmt++;
+			}
+			else if (c >= 0 && isdigit(c)) {
+				width = c - '0';
+				while (--fmtcnt >= 0) {
+					c = Py_CHARMASK(*fmt++);
+					if (!isdigit(c))
+						break;
+					if ((width*10) / 10 != width) {
+						PyErr_SetString(
+							PyExc_ValueError,
+							"width too big");
+						goto error;
+					}
+					width = width*10 + (c - '0');
+				}
+			}
+			if (c == '.') {
+				prec = 0;
+				if (--fmtcnt >= 0)
+					c = *fmt++;
+				if (c == '*') {
+					v = getnextarg(args, arglen, &argidx);
+					if (v == NULL)
+						goto error;
+					if (!PyInt_Check(v)) {
+						PyErr_SetString(
+							PyExc_TypeError,
+							"* wants int");
+						goto error;
+					}
+					prec = PyInt_AsLong(v);
+					if (prec < 0)
+						prec = 0;
+					if (--fmtcnt >= 0)
+						c = *fmt++;
+				}
+				else if (c >= 0 && isdigit(c)) {
+					prec = c - '0';
+					while (--fmtcnt >= 0) {
+						c = Py_CHARMASK(*fmt++);
+						if (!isdigit(c))
+							break;
+						if ((prec*10) / 10 != prec) {
+							PyErr_SetString(
+							    PyExc_ValueError,
+							    "prec too big");
+							goto error;
+						}
+						prec = prec*10 + (c - '0');
+					}
+				}
+			} /* prec */
+			if (fmtcnt >= 0) {
+				if (c == 'h' || c == 'l' || c == 'L') {
+					if (--fmtcnt >= 0)
+						c = *fmt++;
+				}
+			}
+			if (fmtcnt < 0) {
+				PyErr_SetString(PyExc_ValueError,
+						"incomplete format");
+				goto error;
+			}
+			if (c != '%') {
+				v = getnextarg(args, arglen, &argidx);
+				if (v == NULL)
+					goto error;
+			}
+			sign = 0;
+			fill = ' ';
+			switch (c) {
+			case '%':
+				pbuf = "%";
+				len = 1;
+				break;
+			case 's':
+#ifdef Py_USING_UNICODE
+				if (PyUnicode_Check(v)) {
+					fmt = fmt_start;
+					argidx = argidx_start;
+					goto unicode;
+				}
+#endif
+				temp = _PyObject_Str(v);
+#ifdef Py_USING_UNICODE
+				if (temp != NULL && PyUnicode_Check(temp)) {
+					Py_DECREF(temp);
+					fmt = fmt_start;
+					argidx = argidx_start;
+					goto unicode;
+				}
+#endif
+				/* Fall through */
+			case 'r':
+				if (c == 'r')
+					temp = PyObject_Repr(v);
+				if (temp == NULL)
+					goto error;
+				if (!PyString_Check(temp)) {
+					PyErr_SetString(PyExc_TypeError,
+					  "%s argument has non-string str()");
+					Py_DECREF(temp);
+					goto error;
+				}
+				pbuf = PyString_AS_STRING(temp);
+				len = PyString_GET_SIZE(temp);
+				if (prec >= 0 && len > prec)
+					len = prec;
+				break;
+			case 'i':
+			case 'd':
+			case 'u':
+			case 'o':
+			case 'x':
+			case 'X':
+				if (c == 'i')
+					c = 'd';
+				if (PyLong_Check(v)) {
+					int ilen;
+					temp = _PyString_FormatLong(v, flags,
+						prec, c, &pbuf, &ilen);
+					len = ilen;
+					if (!temp)
+						goto error;
+					sign = 1;
+				}
+				else {
+					pbuf = formatbuf;
+					len = formatint(pbuf,
+							sizeof(formatbuf),
+							flags, prec, c, v);
+					if (len < 0)
+						goto error;
+					sign = 1;
+				}
+				if (flags & F_ZERO)
+					fill = '0';
+				break;
+			case 'e':
+			case 'E':
+			case 'f':
+			case 'F':
+			case 'g':
+			case 'G':
+				if (c == 'F')
+					c = 'f';
+				pbuf = formatbuf;
+				len = formatfloat(pbuf, sizeof(formatbuf),
+						  flags, prec, c, v);
+				if (len < 0)
+					goto error;
+				sign = 1;
+				if (flags & F_ZERO)
+					fill = '0';
+				break;
+			case 'c':
+#ifdef Py_USING_UNICODE
+				if (PyUnicode_Check(v)) {
+					fmt = fmt_start;
+					argidx = argidx_start;
+					goto unicode;
+				}
+#endif
+				pbuf = formatbuf;
+				len = formatchar(pbuf, sizeof(formatbuf), v);
+				if (len < 0)
+					goto error;
+				break;
+			default:
+				PyErr_Format(PyExc_ValueError,
+				  "unsupported format character '%c' (0x%x) "
+				  "at index %zd",
+				  c, c,
+				  (Py_ssize_t)(fmt - 1 -
+					       PyString_AsString(format)));
+				goto error;
+			}
+			if (sign) {
+				if (*pbuf == '-' || *pbuf == '+') {
+					sign = *pbuf++;
+					len--;
+				}
+				else if (flags & F_SIGN)
+					sign = '+';
+				else if (flags & F_BLANK)
+					sign = ' ';
+				else
+					sign = 0;
+			}
+			if (width < len)
+				width = len;
+			if (rescnt - (sign != 0) < width) {
+				reslen -= rescnt;
+				rescnt = width + fmtcnt + 100;
+				reslen += rescnt;
+				if (reslen < 0) {
+					Py_DECREF(result);
+					Py_XDECREF(temp);
+					return PyErr_NoMemory();
+				}
+				if (_PyString_Resize(&result, reslen) < 0) {
+					Py_XDECREF(temp);
+					return NULL;
+				}
+				res = PyString_AS_STRING(result)
+					+ reslen - rescnt;
+			}
+			if (sign) {
+				if (fill != ' ')
+					*res++ = sign;
+				rescnt--;
+				if (width > len)
+					width--;
+			}
+			if ((flags & F_ALT) && (c == 'x' || c == 'X')) {
+				assert(pbuf[0] == '0');
+				assert(pbuf[1] == c);
+				if (fill != ' ') {
+					*res++ = *pbuf++;
+					*res++ = *pbuf++;
+				}
+				rescnt -= 2;
+				width -= 2;
+				if (width < 0)
+					width = 0;
+				len -= 2;
+			}
+			if (width > len && !(flags & F_LJUST)) {
+				do {
+					--rescnt;
+					*res++ = fill;
+				} while (--width > len);
+			}
+			if (fill == ' ') {
+				if (sign)
+					*res++ = sign;
+				if ((flags & F_ALT) &&
+				    (c == 'x' || c == 'X')) {
+					assert(pbuf[0] == '0');
+					assert(pbuf[1] == c);
+					*res++ = *pbuf++;
+					*res++ = *pbuf++;
+				}
+			}
+			Py_MEMCPY(res, pbuf, len);
+			res += len;
+			rescnt -= len;
+			while (--width >= len) {
+				--rescnt;
+				*res++ = ' ';
+			}
+                        if (dict && (argidx < arglen) && c != '%') {
+                                PyErr_SetString(PyExc_TypeError,
+                                           "not all arguments converted during string formatting");
+                                Py_XDECREF(temp);
+                                goto error;
+                        }
+			Py_XDECREF(temp);
+		} /* '%' */
+	} /* until end */
+	if (argidx < arglen && !dict) {
+		PyErr_SetString(PyExc_TypeError,
+				"not all arguments converted during string formatting");
+		goto error;
+	}
+	if (args_owned) {
+		Py_DECREF(args);
+	}
+	_PyString_Resize(&result, reslen - rescnt);
+	return result;
+
+#ifdef Py_USING_UNICODE
+ unicode:
+	if (args_owned) {
+		Py_DECREF(args);
+		args_owned = 0;
+	}
+	/* Fiddle args right (remove the first argidx arguments) */
+	if (PyTuple_Check(orig_args) && argidx > 0) {
+		PyObject *v;
+		Py_ssize_t n = PyTuple_GET_SIZE(orig_args) - argidx;
+		v = PyTuple_New(n);
+		if (v == NULL)
+			goto error;
+		while (--n >= 0) {
+			PyObject *w = PyTuple_GET_ITEM(orig_args, n + argidx);
+			Py_INCREF(w);
+			PyTuple_SET_ITEM(v, n, w);
+		}
+		args = v;
+	} else {
+		Py_INCREF(orig_args);
+		args = orig_args;
+	}
+	args_owned = 1;
+	/* Take what we have of the result and let the Unicode formatting
+	   function format the rest of the input. */
+	rescnt = res - PyString_AS_STRING(result);
+	if (_PyString_Resize(&result, rescnt))
+		goto error;
+	fmtcnt = PyString_GET_SIZE(format) - \
+		 (fmt - PyString_AS_STRING(format));
+	format = PyUnicode_Decode(fmt, fmtcnt, NULL, NULL);
+	if (format == NULL)
+		goto error;
+	v = PyUnicode_Format(format, args);
+	Py_DECREF(format);
+	if (v == NULL)
+		goto error;
+	/* Paste what we have (result) to what the Unicode formatting
+	   function returned (v) and return the result (or error) */
+	w = PyUnicode_Concat(result, v);
+	Py_DECREF(result);
+	Py_DECREF(v);
+	Py_DECREF(args);
+	return w;
+#endif /* Py_USING_UNICODE */
+
+ error:
+	Py_DECREF(result);
+	if (args_owned) {
+		Py_DECREF(args);
+	}
+	return NULL;
+}
+
+void
+PyString_InternInPlace(PyObject **p)
+{
+	register PyStringObject *s = (PyStringObject *)(*p);
+	PyObject *t;
+	if (s == NULL || !PyString_Check(s))
+		Py_FatalError("PyString_InternInPlace: strings only please!");
+	/* If it's a string subclass, we don't really know what putting
+	   it in the interned dict might do. */
+	if (!PyString_CheckExact(s))
+		return;
+	if (PyString_CHECK_INTERNED(s))
+		return;
+	if (interned == NULL) {
+		interned = PyDict_New();
+		if (interned == NULL) {
+			PyErr_Clear(); /* Don't leave an exception */
+			return;
+		}
+	}
+	t = PyDict_GetItem(interned, (PyObject *)s);
+	if (t) {
+		Py_INCREF(t);
+		Py_DECREF(*p);
+		*p = t;
+		return;
+	}
+
+	if (PyDict_SetItem(interned, (PyObject *)s, (PyObject *)s) < 0) {
+		PyErr_Clear();
+		return;
+	}
+	/* The two references in interned are not counted by refcnt.
+	   The string deallocator will take care of this */
+	s->ob_refcnt -= 2;
+	PyString_CHECK_INTERNED(s) = SSTATE_INTERNED_MORTAL;
+}
+
+void
+PyString_InternImmortal(PyObject **p)
+{
+	PyString_InternInPlace(p);
+	if (PyString_CHECK_INTERNED(*p) != SSTATE_INTERNED_IMMORTAL) {
+		PyString_CHECK_INTERNED(*p) = SSTATE_INTERNED_IMMORTAL;
+		Py_INCREF(*p);
+	}
+}
+
+
+PyObject *
+PyString_InternFromString(const char *cp)
+{
+	PyObject *s = PyString_FromString(cp);
+	if (s == NULL)
+		return NULL;
+	PyString_InternInPlace(&s);
+	return s;
+}
+
+void
+PyString_Fini(void)
+{
+	int i;
+	for (i = 0; i < UCHAR_MAX + 1; i++) {
+		Py_XDECREF(characters[i]);
+		characters[i] = NULL;
+	}
+	Py_XDECREF(nullstring);
+	nullstring = NULL;
+}
+
+void _Py_ReleaseInternedStrings(void)
+{
+	PyObject *keys;
+	PyStringObject *s;
+	Py_ssize_t i, n;
+
+	if (interned == NULL || !PyDict_Check(interned))
+		return;
+	keys = PyDict_Keys(interned);
+	if (keys == NULL || !PyList_Check(keys)) {
+		PyErr_Clear();
+		return;
+	}
+
+	/* Since _Py_ReleaseInternedStrings() is intended to help a leak
+	   detector, interned strings are not forcibly deallocated; rather, we
+	   give them their stolen references back, and then clear and DECREF
+	   the interned dict. */
+
+	fprintf(stderr, "releasing interned strings\n");
+	n = PyList_GET_SIZE(keys);
+	for (i = 0; i < n; i++) {
+		s = (PyStringObject *) PyList_GET_ITEM(keys, i);
+		switch (s->ob_sstate) {
+		case SSTATE_NOT_INTERNED:
+			/* XXX Shouldn't happen */
+			break;
+		case SSTATE_INTERNED_IMMORTAL:
+			s->ob_refcnt += 1;
+			break;
+		case SSTATE_INTERNED_MORTAL:
+			s->ob_refcnt += 2;
+			break;
+		default:
+			Py_FatalError("Inconsistent interned string state.");
+		}
+		s->ob_sstate = SSTATE_NOT_INTERNED;
+	}
+	Py_DECREF(keys);
+	PyDict_Clear(interned);
+	Py_DECREF(interned);
+	interned = NULL;
+}

Added: vendor/Python/current/Objects/structseq.c
===================================================================
--- vendor/Python/current/Objects/structseq.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Objects/structseq.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,407 @@
+/* Implementation helper: a struct that looks like a tuple.  See timemodule
+   and posixmodule for example uses. */
+
+#include "Python.h"
+#include "structmember.h"
+#include "structseq.h"
+
+static char visible_length_key[] = "n_sequence_fields";
+static char real_length_key[] = "n_fields";
+static char unnamed_fields_key[] = "n_unnamed_fields";
+
+/* Fields with this name have only a field index, not a field name. 
+   They are only allowed for indices < n_visible_fields. */
+char *PyStructSequence_UnnamedField = "unnamed field";
+
+#define VISIBLE_SIZE(op) ((op)->ob_size)
+#define VISIBLE_SIZE_TP(tp) PyInt_AsLong( \
+                      PyDict_GetItemString((tp)->tp_dict, visible_length_key))
+
+#define REAL_SIZE_TP(tp) PyInt_AsLong( \
+                      PyDict_GetItemString((tp)->tp_dict, real_length_key))
+#define REAL_SIZE(op) REAL_SIZE_TP((op)->ob_type)
+
+#define UNNAMED_FIELDS_TP(tp) PyInt_AsLong( \
+                      PyDict_GetItemString((tp)->tp_dict, unnamed_fields_key))
+#define UNNAMED_FIELDS(op) UNNAMED_FIELDS_TP((op)->ob_type)
+
+
+PyObject *
+PyStructSequence_New(PyTypeObject *type)
+{
+	PyStructSequence *obj;
+       
+	obj = PyObject_New(PyStructSequence, type);
+	obj->ob_size = VISIBLE_SIZE_TP(type);
+
+	return (PyObject*) obj;
+}
+
+static void
+structseq_dealloc(PyStructSequence *obj)
+{
+	Py_ssize_t i, size;
+
+	size = REAL_SIZE(obj);
+	for (i = 0; i < size; ++i) {
+		Py_XDECREF(obj->ob_item[i]);
+	}
+	PyObject_Del(obj);
+}
+
+static Py_ssize_t
+structseq_length(PyStructSequence *obj)
+{
+	return VISIBLE_SIZE(obj);
+}
+
+static PyObject*
+structseq_item(PyStructSequence *obj, Py_ssize_t i)
+{
+	if (i < 0 || i >= VISIBLE_SIZE(obj)) {
+		PyErr_SetString(PyExc_IndexError, "tuple index out of range");
+		return NULL;
+	}
+	Py_INCREF(obj->ob_item[i]);
+	return obj->ob_item[i];
+}
+
+static PyObject*
+structseq_slice(PyStructSequence *obj, Py_ssize_t low, Py_ssize_t high)
+{
+	PyTupleObject *np;
+	Py_ssize_t i;
+
+	if (low < 0)
+		low = 0;
+	if (high > VISIBLE_SIZE(obj))
+		high = VISIBLE_SIZE(obj);
+	if (high < low)
+		high = low;
+	np = (PyTupleObject *)PyTuple_New(high-low);
+	if (np == NULL)
+		return NULL;
+	for(i = low; i < high; ++i) {
+		PyObject *v = obj->ob_item[i];
+		Py_INCREF(v);
+		PyTuple_SET_ITEM(np, i-low, v);
+	}
+	return (PyObject *) np;
+}
+
+static PyObject *
+structseq_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	PyObject *arg = NULL;
+	PyObject *dict = NULL;
+	PyObject *ob;
+	PyStructSequence *res = NULL;
+	Py_ssize_t len, min_len, max_len, i, n_unnamed_fields;
+	static char *kwlist[] = {"sequence", "dict", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:structseq", 
+					 kwlist, &arg, &dict))
+		return NULL;
+
+	arg = PySequence_Fast(arg, "constructor requires a sequence");
+
+	if (!arg) {				
+		return NULL;
+	}
+
+	if (dict && !PyDict_Check(dict)) {
+		PyErr_Format(PyExc_TypeError, 
+			     "%.500s() takes a dict as second arg, if any",
+			     type->tp_name);
+		Py_DECREF(arg);
+		return NULL;
+	}
+
+	len = PySequence_Fast_GET_SIZE(arg);
+	min_len = VISIBLE_SIZE_TP(type);
+	max_len = REAL_SIZE_TP(type);
+	n_unnamed_fields = UNNAMED_FIELDS_TP(type);
+
+	if (min_len != max_len) {
+		if (len < min_len) {
+			PyErr_Format(PyExc_TypeError, 
+	       "%.500s() takes an at least %zd-sequence (%zd-sequence given)",
+				     type->tp_name, min_len, len);
+			Py_DECREF(arg);
+			return NULL;
+		}
+
+		if (len > max_len) {
+			PyErr_Format(PyExc_TypeError, 
+	       "%.500s() takes an at most %zd-sequence (%zd-sequence given)",
+				     type->tp_name, max_len, len);
+			Py_DECREF(arg);
+			return NULL;
+		}
+	} 
+	else {
+		if (len != min_len) {
+			PyErr_Format(PyExc_TypeError, 
+	       "%.500s() takes a %zd-sequence (%zd-sequence given)",
+				     type->tp_name, min_len, len);
+			Py_DECREF(arg);
+			return NULL;
+		}
+	}
+
+	res = (PyStructSequence*) PyStructSequence_New(type);
+	if (res == NULL) {
+		return NULL;
+	}
+	for (i = 0; i < len; ++i) {
+		PyObject *v = PySequence_Fast_GET_ITEM(arg, i);
+		Py_INCREF(v);
+		res->ob_item[i] = v;
+	}
+	for (; i < max_len; ++i) {
+		if (dict && (ob = PyDict_GetItemString(
+			dict, type->tp_members[i-n_unnamed_fields].name))) {
+		}
+		else {
+			ob = Py_None;
+		}
+		Py_INCREF(ob);
+		res->ob_item[i] = ob;
+	}
+	
+	Py_DECREF(arg);
+	return (PyObject*) res;
+}
+
+static PyObject *
+make_tuple(PyStructSequence *obj)
+{
+	return structseq_slice(obj, 0, VISIBLE_SIZE(obj));
+}
+
+static PyObject *
+structseq_repr(PyStructSequence *obj)
+{
+	PyObject *tup, *str;
+	tup = make_tuple(obj);
+	str = PyObject_Repr(tup);
+	Py_DECREF(tup);
+	return str;
+}
+
+static PyObject *
+structseq_concat(PyStructSequence *obj, PyObject *b)
+{
+	PyObject *tup, *result;
+	tup = make_tuple(obj);
+	result = PySequence_Concat(tup, b);
+	Py_DECREF(tup);
+	return result;
+}
+
+static PyObject *
+structseq_repeat(PyStructSequence *obj, Py_ssize_t n)
+{
+	PyObject *tup, *result;
+	tup = make_tuple(obj);
+	result = PySequence_Repeat(tup, n);
+	Py_DECREF(tup);
+	return result;
+}
+
+static int
+structseq_contains(PyStructSequence *obj, PyObject *o)
+{
+	PyObject *tup;
+	int result;
+	tup = make_tuple(obj);
+	if (!tup)
+		return -1;
+	result = PySequence_Contains(tup, o);
+	Py_DECREF(tup);
+	return result;
+}
+
+static long
+structseq_hash(PyObject *obj)
+{
+	PyObject *tup;
+	long result;
+	tup = make_tuple((PyStructSequence*) obj);
+	if (!tup)
+		return -1;
+	result = PyObject_Hash(tup);
+	Py_DECREF(tup);
+	return result;
+}
+
+static PyObject *
+structseq_richcompare(PyObject *obj, PyObject *o2, int op)
+{
+	PyObject *tup, *result;
+	tup = make_tuple((PyStructSequence*) obj);
+	result = PyObject_RichCompare(tup, o2, op);
+	Py_DECREF(tup);
+	return result;
+}
+
+static PyObject *
+structseq_reduce(PyStructSequence* self)
+{
+	PyObject* tup;
+	PyObject* dict;
+	PyObject* result;
+	Py_ssize_t n_fields, n_visible_fields, n_unnamed_fields;
+	int i;
+	
+	n_fields = REAL_SIZE(self);
+	n_visible_fields = VISIBLE_SIZE(self);
+	n_unnamed_fields = UNNAMED_FIELDS(self);
+	tup = PyTuple_New(n_visible_fields);
+	if (!tup) {
+		return NULL;
+	}
+
+	dict = PyDict_New();
+	if (!dict) {
+		Py_DECREF(tup);
+		return NULL;
+	}
+
+	for (i = 0; i < n_visible_fields; i++) {
+		Py_INCREF(self->ob_item[i]);
+		PyTuple_SET_ITEM(tup, i, self->ob_item[i]);
+	}
+	
+	for (; i < n_fields; i++) {
+		char *n = self->ob_type->tp_members[i-n_unnamed_fields].name;
+		PyDict_SetItemString(dict, n,
+				     self->ob_item[i]);
+	}
+
+	result = Py_BuildValue("(O(OO))", self->ob_type, tup, dict);
+
+	Py_DECREF(tup);
+	Py_DECREF(dict);
+
+	return result;
+}
+
+static PySequenceMethods structseq_as_sequence = {
+	(lenfunc)structseq_length,
+	(binaryfunc)structseq_concat,           /* sq_concat */
+	(ssizeargfunc)structseq_repeat,         /* sq_repeat */
+	(ssizeargfunc)structseq_item,		/* sq_item */
+	(ssizessizeargfunc)structseq_slice,	/* sq_slice */
+	0,					/* sq_ass_item */
+	0,					/* sq_ass_slice */
+	(objobjproc)structseq_contains,	        /* sq_contains */
+};
+
+static PyMethodDef structseq_methods[] = {
+	{"__reduce__", (PyCFunction)structseq_reduce, 
+	 METH_NOARGS, NULL},
+	{NULL, NULL}
+};
+
+static PyTypeObject _struct_sequence_template = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,					/* ob_size */
+	NULL,	                     		/* tp_name */
+        0,		                        /* tp_basicsize */
+	0,	                      		/* tp_itemsize */
+	(destructor)structseq_dealloc,	        /* tp_dealloc */
+	0,                        	        /* tp_print */
+	0,			 		/* tp_getattr */
+	0,					/* tp_setattr */
+	0,               			/* tp_compare */
+	(reprfunc)structseq_repr,             	/* tp_repr */
+	0,					/* tp_as_number */
+	&structseq_as_sequence,			/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	structseq_hash,				/* tp_hash */
+	0,              			/* tp_call */
+	0,					/* tp_str */
+	0,                       		/* tp_getattro */
+	0,	                           	/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT,                     /* tp_flags */
+	NULL,	 		         	/* tp_doc */
+	0,					/* tp_traverse */
+	0,					/* tp_clear */
+	structseq_richcompare,			/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	structseq_methods,      		/* tp_methods */
+        NULL,			             	/* tp_members */
+	0,			          	/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,	                                /* tp_dictoffset */
+	0,					/* tp_init */
+	0,					/* tp_alloc */
+	structseq_new,				/* tp_new */
+};
+
+void
+PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc)
+{
+	PyObject *dict;
+	PyMemberDef* members;
+	int n_members, n_unnamed_members, i, k;
+
+#ifdef Py_TRACE_REFS
+	/* if the type object was chained, unchain it first
+	   before overwriting its storage */
+	if (type->_ob_next) {
+		_Py_ForgetReference((PyObject*)type);
+	}
+#endif
+
+	n_unnamed_members = 0;
+	for (i = 0; desc->fields[i].name != NULL; ++i)
+		if (desc->fields[i].name == PyStructSequence_UnnamedField)
+			n_unnamed_members++;
+	n_members = i;
+
+	memcpy(type, &_struct_sequence_template, sizeof(PyTypeObject));
+	type->tp_name = desc->name;
+	type->tp_doc = desc->doc;
+	type->tp_basicsize = sizeof(PyStructSequence)+
+		sizeof(PyObject*)*(n_members-1);
+	type->tp_itemsize = 0;
+
+	members = PyMem_NEW(PyMemberDef, n_members-n_unnamed_members+1);
+	if (members == NULL)
+		return;
+	
+	for (i = k = 0; i < n_members; ++i) {
+		if (desc->fields[i].name == PyStructSequence_UnnamedField)
+			continue;
+		members[k].name = desc->fields[i].name;
+		members[k].type = T_OBJECT;
+		members[k].offset = offsetof(PyStructSequence, ob_item)
+		  + i * sizeof(PyObject*);
+		members[k].flags = READONLY;
+		members[k].doc = desc->fields[i].doc;
+		k++;
+	}
+	members[k].name = NULL;
+
+	type->tp_members = members;
+
+	if (PyType_Ready(type) < 0)
+		return;
+	Py_INCREF(type);
+
+	dict = type->tp_dict;
+	PyDict_SetItemString(dict, visible_length_key, 
+		       PyInt_FromLong((long) desc->n_in_sequence));
+	PyDict_SetItemString(dict, real_length_key, 
+		       PyInt_FromLong((long) n_members));
+	PyDict_SetItemString(dict, unnamed_fields_key, 
+		       PyInt_FromLong((long) n_unnamed_members));
+}

Added: vendor/Python/current/Objects/tupleobject.c
===================================================================
--- vendor/Python/current/Objects/tupleobject.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Objects/tupleobject.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,890 @@
+
+/* Tuple object implementation */
+
+#include "Python.h"
+
+/* Speed optimization to avoid frequent malloc/free of small tuples */
+#ifndef MAXSAVESIZE
+#define MAXSAVESIZE	20  /* Largest tuple to save on free list */
+#endif
+#ifndef MAXSAVEDTUPLES 
+#define MAXSAVEDTUPLES  2000  /* Maximum number of tuples of each size to save */
+#endif
+
+#if MAXSAVESIZE > 0
+/* Entries 1 up to MAXSAVESIZE are free lists, entry 0 is the empty
+   tuple () of which at most one instance will be allocated.
+*/
+static PyTupleObject *free_tuples[MAXSAVESIZE];
+static int num_free_tuples[MAXSAVESIZE];
+#endif
+#ifdef COUNT_ALLOCS
+int fast_tuple_allocs;
+int tuple_zero_allocs;
+#endif
+
+PyObject *
+PyTuple_New(register Py_ssize_t size)
+{
+	register PyTupleObject *op;
+	Py_ssize_t i;
+	if (size < 0) {
+		PyErr_BadInternalCall();
+		return NULL;
+	}
+#if MAXSAVESIZE > 0
+	if (size == 0 && free_tuples[0]) {
+		op = free_tuples[0];
+		Py_INCREF(op);
+#ifdef COUNT_ALLOCS
+		tuple_zero_allocs++;
+#endif
+		return (PyObject *) op;
+	}
+	if (size < MAXSAVESIZE && (op = free_tuples[size]) != NULL) {
+		free_tuples[size] = (PyTupleObject *) op->ob_item[0];
+		num_free_tuples[size]--;
+#ifdef COUNT_ALLOCS
+		fast_tuple_allocs++;
+#endif
+		/* Inline PyObject_InitVar */
+#ifdef Py_TRACE_REFS
+		op->ob_size = size;
+		op->ob_type = &PyTuple_Type;
+#endif
+		_Py_NewReference((PyObject *)op);
+	}
+	else
+#endif
+	{
+		Py_ssize_t nbytes = size * sizeof(PyObject *);
+		/* Check for overflow */
+		if (nbytes / sizeof(PyObject *) != (size_t)size ||
+		    (nbytes += sizeof(PyTupleObject) - sizeof(PyObject *))
+		    <= 0)
+		{
+			return PyErr_NoMemory();
+		}
+		op = PyObject_GC_NewVar(PyTupleObject, &PyTuple_Type, size);
+		if (op == NULL)
+			return NULL;
+	}
+	for (i=0; i < size; i++)
+		op->ob_item[i] = NULL;
+#if MAXSAVESIZE > 0
+	if (size == 0) {
+		free_tuples[0] = op;
+		++num_free_tuples[0];
+		Py_INCREF(op);	/* extra INCREF so that this is never freed */
+	}
+#endif
+	_PyObject_GC_TRACK(op);
+	return (PyObject *) op;
+}
+
+Py_ssize_t
+PyTuple_Size(register PyObject *op)
+{
+	if (!PyTuple_Check(op)) {
+		PyErr_BadInternalCall();
+		return -1;
+	}
+	else
+		return ((PyTupleObject *)op)->ob_size;
+}
+
+PyObject *
+PyTuple_GetItem(register PyObject *op, register Py_ssize_t i)
+{
+	if (!PyTuple_Check(op)) {
+		PyErr_BadInternalCall();
+		return NULL;
+	}
+	if (i < 0 || i >= ((PyTupleObject *)op) -> ob_size) {
+		PyErr_SetString(PyExc_IndexError, "tuple index out of range");
+		return NULL;
+	}
+	return ((PyTupleObject *)op) -> ob_item[i];
+}
+
+int
+PyTuple_SetItem(register PyObject *op, register Py_ssize_t i, PyObject *newitem)
+{
+	register PyObject *olditem;
+	register PyObject **p;
+	if (!PyTuple_Check(op) || op->ob_refcnt != 1) {
+		Py_XDECREF(newitem);
+		PyErr_BadInternalCall();
+		return -1;
+	}
+	if (i < 0 || i >= ((PyTupleObject *)op) -> ob_size) {
+		Py_XDECREF(newitem);
+		PyErr_SetString(PyExc_IndexError,
+				"tuple assignment index out of range");
+		return -1;
+	}
+	p = ((PyTupleObject *)op) -> ob_item + i;
+	olditem = *p;
+	*p = newitem;
+	Py_XDECREF(olditem);
+	return 0;
+}
+
+PyObject *
+PyTuple_Pack(Py_ssize_t n, ...)
+{
+	Py_ssize_t i;
+	PyObject *o;
+	PyObject *result;
+	PyObject **items;
+	va_list vargs;
+
+	va_start(vargs, n);
+	result = PyTuple_New(n);
+	if (result == NULL)
+		return NULL;
+	items = ((PyTupleObject *)result)->ob_item;
+	for (i = 0; i < n; i++) {
+		o = va_arg(vargs, PyObject *);
+		Py_INCREF(o);
+		items[i] = o;
+	}
+	va_end(vargs);
+	return result;
+}
+
+
+/* Methods */
+
+static void
+tupledealloc(register PyTupleObject *op)
+{
+	register Py_ssize_t i;
+	register Py_ssize_t len =  op->ob_size;
+	PyObject_GC_UnTrack(op);
+	Py_TRASHCAN_SAFE_BEGIN(op)
+	if (len > 0) {
+		i = len;
+		while (--i >= 0)
+			Py_XDECREF(op->ob_item[i]);
+#if MAXSAVESIZE > 0
+		if (len < MAXSAVESIZE &&
+		    num_free_tuples[len] < MAXSAVEDTUPLES &&
+		    op->ob_type == &PyTuple_Type)
+		{
+			op->ob_item[0] = (PyObject *) free_tuples[len];
+			num_free_tuples[len]++;
+			free_tuples[len] = op;
+			goto done; /* return */
+		}
+#endif
+	}
+	op->ob_type->tp_free((PyObject *)op);
+done:
+	Py_TRASHCAN_SAFE_END(op)
+}
+
+static int
+tupleprint(PyTupleObject *op, FILE *fp, int flags)
+{
+	Py_ssize_t i;
+	fprintf(fp, "(");
+	for (i = 0; i < op->ob_size; i++) {
+		if (i > 0)
+			fprintf(fp, ", ");
+		if (PyObject_Print(op->ob_item[i], fp, 0) != 0)
+			return -1;
+	}
+	if (op->ob_size == 1)
+		fprintf(fp, ",");
+	fprintf(fp, ")");
+	return 0;
+}
+
+static PyObject *
+tuplerepr(PyTupleObject *v)
+{
+	Py_ssize_t i, n;
+	PyObject *s, *temp;
+	PyObject *pieces, *result = NULL;
+
+	n = v->ob_size;
+	if (n == 0)
+		return PyString_FromString("()");
+
+	pieces = PyTuple_New(n);
+	if (pieces == NULL)
+		return NULL;
+
+	/* Do repr() on each element. */
+	for (i = 0; i < n; ++i) {
+		s = PyObject_Repr(v->ob_item[i]);
+		if (s == NULL)
+			goto Done;
+		PyTuple_SET_ITEM(pieces, i, s);
+	}
+
+	/* Add "()" decorations to the first and last items. */
+	assert(n > 0);
+	s = PyString_FromString("(");
+	if (s == NULL)
+		goto Done;
+	temp = PyTuple_GET_ITEM(pieces, 0);
+	PyString_ConcatAndDel(&s, temp);
+	PyTuple_SET_ITEM(pieces, 0, s);
+	if (s == NULL)
+		goto Done;
+
+	s = PyString_FromString(n == 1 ? ",)" : ")");
+	if (s == NULL)
+		goto Done;
+	temp = PyTuple_GET_ITEM(pieces, n-1);
+	PyString_ConcatAndDel(&temp, s);
+	PyTuple_SET_ITEM(pieces, n-1, temp);
+	if (temp == NULL)
+		goto Done;
+
+	/* Paste them all together with ", " between. */
+	s = PyString_FromString(", ");
+	if (s == NULL)
+		goto Done;
+	result = _PyString_Join(s, pieces);
+	Py_DECREF(s);	
+
+Done:
+	Py_DECREF(pieces);
+	return result;
+}
+
+/* The addend 82520, was selected from the range(0, 1000000) for 
+   generating the greatest number of prime multipliers for tuples 
+   upto length eight:
+
+     1082527, 1165049, 1082531, 1165057, 1247581, 1330103, 1082533, 
+     1330111, 1412633, 1165069, 1247599, 1495177, 1577699
+*/
+
+static long
+tuplehash(PyTupleObject *v)
+{
+	register long x, y;
+	register Py_ssize_t len = v->ob_size;
+	register PyObject **p;
+	long mult = 1000003L;
+	x = 0x345678L;
+	p = v->ob_item;
+	while (--len >= 0) {
+		y = PyObject_Hash(*p++);
+		if (y == -1)
+			return -1;
+		x = (x ^ y) * mult;
+		/* the cast might truncate len; that doesn't change hash stability */
+		mult += (long)(82520L + len + len);
+	}
+	x += 97531L;
+	if (x == -1)
+		x = -2;
+	return x;
+}
+
+static Py_ssize_t
+tuplelength(PyTupleObject *a)
+{
+	return a->ob_size;
+}
+
+static int
+tuplecontains(PyTupleObject *a, PyObject *el)
+{
+	Py_ssize_t i;
+	int cmp;
+
+	for (i = 0, cmp = 0 ; cmp == 0 && i < a->ob_size; ++i)
+		cmp = PyObject_RichCompareBool(el, PyTuple_GET_ITEM(a, i),
+						   Py_EQ);
+	return cmp;
+}
+
+static PyObject *
+tupleitem(register PyTupleObject *a, register Py_ssize_t i)
+{
+	if (i < 0 || i >= a->ob_size) {
+		PyErr_SetString(PyExc_IndexError, "tuple index out of range");
+		return NULL;
+	}
+	Py_INCREF(a->ob_item[i]);
+	return a->ob_item[i];
+}
+
+static PyObject *
+tupleslice(register PyTupleObject *a, register Py_ssize_t ilow, 
+	   register Py_ssize_t ihigh)
+{
+	register PyTupleObject *np;
+	PyObject **src, **dest;
+	register Py_ssize_t i;
+	Py_ssize_t len;
+	if (ilow < 0)
+		ilow = 0;
+	if (ihigh > a->ob_size)
+		ihigh = a->ob_size;
+	if (ihigh < ilow)
+		ihigh = ilow;
+	if (ilow == 0 && ihigh == a->ob_size && PyTuple_CheckExact(a)) {
+		Py_INCREF(a);
+		return (PyObject *)a;
+	}
+	len = ihigh - ilow;
+	np = (PyTupleObject *)PyTuple_New(len);
+	if (np == NULL)
+		return NULL;
+	src = a->ob_item + ilow;
+	dest = np->ob_item;
+	for (i = 0; i < len; i++) {
+		PyObject *v = src[i];
+		Py_INCREF(v);
+		dest[i] = v;
+	}
+	return (PyObject *)np;
+}
+
+PyObject *
+PyTuple_GetSlice(PyObject *op, Py_ssize_t i, Py_ssize_t j)
+{
+	if (op == NULL || !PyTuple_Check(op)) {
+		PyErr_BadInternalCall();
+		return NULL;
+	}
+	return tupleslice((PyTupleObject *)op, i, j);
+}
+
+static PyObject *
+tupleconcat(register PyTupleObject *a, register PyObject *bb)
+{
+	register Py_ssize_t size;
+	register Py_ssize_t i;
+	PyObject **src, **dest;
+	PyTupleObject *np;
+	if (!PyTuple_Check(bb)) {
+		PyErr_Format(PyExc_TypeError,
+       		     "can only concatenate tuple (not \"%.200s\") to tuple",
+			     bb->ob_type->tp_name);
+		return NULL;
+	}
+#define b ((PyTupleObject *)bb)
+	size = a->ob_size + b->ob_size;
+	if (size < 0)
+		return PyErr_NoMemory();
+	np = (PyTupleObject *) PyTuple_New(size);
+	if (np == NULL) {
+		return NULL;
+	}
+	src = a->ob_item;
+	dest = np->ob_item;
+	for (i = 0; i < a->ob_size; i++) {
+		PyObject *v = src[i];
+		Py_INCREF(v);
+		dest[i] = v;
+	}
+	src = b->ob_item;
+	dest = np->ob_item + a->ob_size;
+	for (i = 0; i < b->ob_size; i++) {
+		PyObject *v = src[i];
+		Py_INCREF(v);
+		dest[i] = v;
+	}
+	return (PyObject *)np;
+#undef b
+}
+
+static PyObject *
+tuplerepeat(PyTupleObject *a, Py_ssize_t n)
+{
+	Py_ssize_t i, j;
+	Py_ssize_t size;
+	PyTupleObject *np;
+	PyObject **p, **items;
+	if (n < 0)
+		n = 0;
+	if (a->ob_size == 0 || n == 1) {
+		if (PyTuple_CheckExact(a)) {
+			/* Since tuples are immutable, we can return a shared
+			   copy in this case */
+			Py_INCREF(a);
+			return (PyObject *)a;
+		}
+		if (a->ob_size == 0)
+			return PyTuple_New(0);
+	}
+	size = a->ob_size * n;
+	if (size/a->ob_size != n)
+		return PyErr_NoMemory();
+	np = (PyTupleObject *) PyTuple_New(size);
+	if (np == NULL)
+		return NULL;
+	p = np->ob_item;
+	items = a->ob_item;
+	for (i = 0; i < n; i++) {
+		for (j = 0; j < a->ob_size; j++) {
+			*p = items[j];
+			Py_INCREF(*p);
+			p++;
+		}
+	}
+	return (PyObject *) np;
+}
+
+static int
+tupletraverse(PyTupleObject *o, visitproc visit, void *arg)
+{
+	Py_ssize_t i;
+
+	for (i = o->ob_size; --i >= 0; )
+		Py_VISIT(o->ob_item[i]);
+	return 0;
+}
+
+static PyObject *
+tuplerichcompare(PyObject *v, PyObject *w, int op)
+{
+	PyTupleObject *vt, *wt;
+	Py_ssize_t i;
+	Py_ssize_t vlen, wlen;
+
+	if (!PyTuple_Check(v) || !PyTuple_Check(w)) {
+		Py_INCREF(Py_NotImplemented);
+		return Py_NotImplemented;
+	}
+
+	vt = (PyTupleObject *)v;
+	wt = (PyTupleObject *)w;
+
+	vlen = vt->ob_size;
+	wlen = wt->ob_size;
+
+	/* Note:  the corresponding code for lists has an "early out" test
+	 * here when op is EQ or NE and the lengths differ.  That pays there,
+	 * but Tim was unable to find any real code where EQ/NE tuple
+	 * compares don't have the same length, so testing for it here would
+	 * have cost without benefit.
+	 */
+
+	/* Search for the first index where items are different.
+	 * Note that because tuples are immutable, it's safe to reuse
+	 * vlen and wlen across the comparison calls.
+	 */
+	for (i = 0; i < vlen && i < wlen; i++) {
+		int k = PyObject_RichCompareBool(vt->ob_item[i],
+						 wt->ob_item[i], Py_EQ);
+		if (k < 0)
+			return NULL;
+		if (!k)
+			break;
+	}
+
+	if (i >= vlen || i >= wlen) {
+		/* No more items to compare -- compare sizes */
+		int cmp;
+		PyObject *res;
+		switch (op) {
+		case Py_LT: cmp = vlen <  wlen; break;
+		case Py_LE: cmp = vlen <= wlen; break;
+		case Py_EQ: cmp = vlen == wlen; break;
+		case Py_NE: cmp = vlen != wlen; break;
+		case Py_GT: cmp = vlen >  wlen; break;
+		case Py_GE: cmp = vlen >= wlen; break;
+		default: return NULL; /* cannot happen */
+		}
+		if (cmp)
+			res = Py_True;
+		else
+			res = Py_False;
+		Py_INCREF(res);
+		return res;
+	}
+
+	/* We have an item that differs -- shortcuts for EQ/NE */
+	if (op == Py_EQ) {
+		Py_INCREF(Py_False);
+		return Py_False;
+	}
+	if (op == Py_NE) {
+		Py_INCREF(Py_True);
+		return Py_True;
+	}
+
+	/* Compare the final item again using the proper operator */
+	return PyObject_RichCompare(vt->ob_item[i], wt->ob_item[i], op);
+}
+
+static PyObject *
+tuple_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
+
+static PyObject *
+tuple_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	PyObject *arg = NULL;
+	static char *kwlist[] = {"sequence", 0};
+
+	if (type != &PyTuple_Type)
+		return tuple_subtype_new(type, args, kwds);
+	if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:tuple", kwlist, &arg))
+		return NULL;
+
+	if (arg == NULL)
+		return PyTuple_New(0);
+	else
+		return PySequence_Tuple(arg);
+}
+
+static PyObject *
+tuple_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	PyObject *tmp, *newobj, *item;
+	Py_ssize_t i, n;
+
+	assert(PyType_IsSubtype(type, &PyTuple_Type));
+	tmp = tuple_new(&PyTuple_Type, args, kwds);
+	if (tmp == NULL)
+		return NULL;
+	assert(PyTuple_Check(tmp));
+	newobj = type->tp_alloc(type, n = PyTuple_GET_SIZE(tmp));
+	if (newobj == NULL)
+		return NULL;
+	for (i = 0; i < n; i++) {
+		item = PyTuple_GET_ITEM(tmp, i);
+		Py_INCREF(item);
+		PyTuple_SET_ITEM(newobj, i, item);
+	}
+	Py_DECREF(tmp);
+	return newobj;
+}
+
+PyDoc_STRVAR(tuple_doc,
+"tuple() -> an empty tuple\n"
+"tuple(sequence) -> tuple initialized from sequence's items\n"
+"\n"
+"If the argument is a tuple, the return value is the same object.");
+
+static PySequenceMethods tuple_as_sequence = {
+	(lenfunc)tuplelength,			/* sq_length */
+	(binaryfunc)tupleconcat,		/* sq_concat */
+	(ssizeargfunc)tuplerepeat,		/* sq_repeat */
+	(ssizeargfunc)tupleitem,		/* sq_item */
+	(ssizessizeargfunc)tupleslice,		/* sq_slice */
+	0,					/* sq_ass_item */
+	0,					/* sq_ass_slice */
+	(objobjproc)tuplecontains,		/* sq_contains */
+};
+
+static PyObject*
+tuplesubscript(PyTupleObject* self, PyObject* item)
+{
+	if (PyIndex_Check(item)) {
+		Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+		if (i == -1 && PyErr_Occurred())
+			return NULL;
+		if (i < 0)
+			i += PyTuple_GET_SIZE(self);
+		return tupleitem(self, i);
+	}
+	else if (PySlice_Check(item)) {
+		Py_ssize_t start, stop, step, slicelength, cur, i;
+		PyObject* result;
+		PyObject* it;
+		PyObject **src, **dest;
+
+		if (PySlice_GetIndicesEx((PySliceObject*)item,
+				 PyTuple_GET_SIZE(self),
+				 &start, &stop, &step, &slicelength) < 0) {
+			return NULL;
+		}
+
+		if (slicelength <= 0) {
+			return PyTuple_New(0);
+		}
+		else {
+			result = PyTuple_New(slicelength);
+			if (!result) return NULL;
+
+			src = self->ob_item;
+			dest = ((PyTupleObject *)result)->ob_item;
+			for (cur = start, i = 0; i < slicelength; 
+			     cur += step, i++) {
+				it = src[cur];
+				Py_INCREF(it);
+				dest[i] = it;
+			}
+			
+			return result;
+		}
+	}
+	else {
+		PyErr_SetString(PyExc_TypeError, 
+				"tuple indices must be integers");
+		return NULL;
+	}
+}
+
+static PyObject *
+tuple_getnewargs(PyTupleObject *v)
+{
+	return Py_BuildValue("(N)", tupleslice(v, 0, v->ob_size));
+	
+}
+
+static PyMethodDef tuple_methods[] = {
+	{"__getnewargs__",	(PyCFunction)tuple_getnewargs,	METH_NOARGS},
+	{NULL,		NULL}		/* sentinel */
+};
+
+static PyMappingMethods tuple_as_mapping = {
+	(lenfunc)tuplelength,
+	(binaryfunc)tuplesubscript,
+	0
+};
+
+static PyObject *tuple_iter(PyObject *seq);
+
+PyTypeObject PyTuple_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,
+	"tuple",
+	sizeof(PyTupleObject) - sizeof(PyObject *),
+	sizeof(PyObject *),
+	(destructor)tupledealloc,		/* tp_dealloc */
+	(printfunc)tupleprint,			/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	(reprfunc)tuplerepr,			/* tp_repr */
+	0,					/* tp_as_number */
+	&tuple_as_sequence,			/* tp_as_sequence */
+	&tuple_as_mapping,			/* tp_as_mapping */
+	(hashfunc)tuplehash,			/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+		Py_TPFLAGS_BASETYPE,		/* tp_flags */
+	tuple_doc,				/* tp_doc */
+ 	(traverseproc)tupletraverse,		/* tp_traverse */
+	0,					/* tp_clear */
+	tuplerichcompare,			/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	tuple_iter,	    			/* tp_iter */
+	0,					/* tp_iternext */
+	tuple_methods,				/* tp_methods */
+	0,					/* tp_members */
+	0,					/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	0,					/* tp_init */
+	0,					/* tp_alloc */
+	tuple_new,				/* tp_new */
+	PyObject_GC_Del,        		/* tp_free */
+};
+
+/* The following function breaks the notion that tuples are immutable:
+   it changes the size of a tuple.  We get away with this only if there
+   is only one module referencing the object.  You can also think of it
+   as creating a new tuple object and destroying the old one, only more
+   efficiently.  In any case, don't use this if the tuple may already be
+   known to some other part of the code. */
+
+int
+_PyTuple_Resize(PyObject **pv, Py_ssize_t newsize)
+{
+	register PyTupleObject *v;
+	register PyTupleObject *sv;
+	Py_ssize_t i;
+	Py_ssize_t oldsize;
+
+	v = (PyTupleObject *) *pv;
+	if (v == NULL || v->ob_type != &PyTuple_Type ||
+	    (v->ob_size != 0 && v->ob_refcnt != 1)) {
+		*pv = 0;
+		Py_XDECREF(v);
+		PyErr_BadInternalCall();
+		return -1;
+	}
+	oldsize = v->ob_size;
+	if (oldsize == newsize)
+		return 0;
+
+	if (oldsize == 0) {
+		/* Empty tuples are often shared, so we should never 
+		   resize them in-place even if we do own the only
+		   (current) reference */
+		Py_DECREF(v);
+		*pv = PyTuple_New(newsize);
+		return *pv == NULL ? -1 : 0;
+	}
+
+	/* XXX UNREF/NEWREF interface should be more symmetrical */
+	_Py_DEC_REFTOTAL;
+	_PyObject_GC_UNTRACK(v);
+	_Py_ForgetReference((PyObject *) v);
+	/* DECREF items deleted by shrinkage */
+	for (i = newsize; i < oldsize; i++) {
+		Py_XDECREF(v->ob_item[i]);
+		v->ob_item[i] = NULL;
+	}
+	sv = PyObject_GC_Resize(PyTupleObject, v, newsize);
+	if (sv == NULL) {
+		*pv = NULL;
+		PyObject_GC_Del(v);
+		return -1;
+	}
+	_Py_NewReference((PyObject *) sv);
+	/* Zero out items added by growing */
+	if (newsize > oldsize)
+		memset(&sv->ob_item[oldsize], 0,
+		       sizeof(*sv->ob_item) * (newsize - oldsize));
+	*pv = (PyObject *) sv;
+	_PyObject_GC_TRACK(sv);
+	return 0;
+}
+
+void
+PyTuple_Fini(void)
+{
+#if MAXSAVESIZE > 0
+	int i;
+
+	Py_XDECREF(free_tuples[0]);
+	free_tuples[0] = NULL;
+
+	for (i = 1; i < MAXSAVESIZE; i++) {
+		PyTupleObject *p, *q;
+		p = free_tuples[i];
+		free_tuples[i] = NULL;
+		while (p) {
+			q = p;
+			p = (PyTupleObject *)(p->ob_item[0]);
+			PyObject_GC_Del(q);
+		}
+	}
+#endif
+}
+
+/*********************** Tuple Iterator **************************/
+
+typedef struct {
+	PyObject_HEAD
+	long it_index;
+	PyTupleObject *it_seq; /* Set to NULL when iterator is exhausted */
+} tupleiterobject;
+
+static void
+tupleiter_dealloc(tupleiterobject *it)
+{
+	_PyObject_GC_UNTRACK(it);
+	Py_XDECREF(it->it_seq);
+	PyObject_GC_Del(it);
+}
+
+static int
+tupleiter_traverse(tupleiterobject *it, visitproc visit, void *arg)
+{
+	Py_VISIT(it->it_seq);
+	return 0;
+}
+
+static PyObject *
+tupleiter_next(tupleiterobject *it)
+{
+	PyTupleObject *seq;
+	PyObject *item;
+
+	assert(it != NULL);
+	seq = it->it_seq;
+	if (seq == NULL)
+		return NULL;
+	assert(PyTuple_Check(seq));
+
+	if (it->it_index < PyTuple_GET_SIZE(seq)) {
+		item = PyTuple_GET_ITEM(seq, it->it_index);
+		++it->it_index;
+		Py_INCREF(item);
+		return item;
+	}
+
+	Py_DECREF(seq);
+	it->it_seq = NULL;
+	return NULL;
+}
+
+static PyObject *
+tupleiter_len(tupleiterobject *it)
+{
+	Py_ssize_t len = 0;
+	if (it->it_seq)
+		len = PyTuple_GET_SIZE(it->it_seq) - it->it_index;
+	return PyInt_FromSsize_t(len);
+}
+
+PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
+
+static PyMethodDef tupleiter_methods[] = {
+	{"__length_hint__", (PyCFunction)tupleiter_len, METH_NOARGS, length_hint_doc},
+ 	{NULL,		NULL}		/* sentinel */
+};
+
+PyTypeObject PyTupleIter_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,					/* ob_size */
+	"tupleiterator",			/* tp_name */
+	sizeof(tupleiterobject),		/* tp_basicsize */
+	0,					/* tp_itemsize */
+	/* methods */
+	(destructor)tupleiter_dealloc,		/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	0,					/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+	0,					/* tp_doc */
+	(traverseproc)tupleiter_traverse,	/* tp_traverse */
+	0,					/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	PyObject_SelfIter,			/* tp_iter */
+	(iternextfunc)tupleiter_next,		/* tp_iternext */
+	tupleiter_methods,			/* tp_methods */
+	0,
+};
+
+static PyObject *
+tuple_iter(PyObject *seq)
+{
+	tupleiterobject *it;
+
+	if (!PyTuple_Check(seq)) {
+		PyErr_BadInternalCall();
+		return NULL;
+	}
+	it = PyObject_GC_New(tupleiterobject, &PyTupleIter_Type);
+	if (it == NULL)
+		return NULL;
+	it->it_index = 0;
+	Py_INCREF(seq);
+	it->it_seq = (PyTupleObject *)seq;
+	_PyObject_GC_TRACK(it);
+	return (PyObject *)it;
+}

Added: vendor/Python/current/Objects/typeobject.c
===================================================================
--- vendor/Python/current/Objects/typeobject.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Objects/typeobject.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,5891 @@
+/* Type object implementation */
+
+#include "Python.h"
+#include "structmember.h"
+
+#include <ctype.h>
+
+static PyMemberDef type_members[] = {
+	{"__basicsize__", T_INT, offsetof(PyTypeObject,tp_basicsize),READONLY},
+	{"__itemsize__", T_INT, offsetof(PyTypeObject, tp_itemsize), READONLY},
+	{"__flags__", T_LONG, offsetof(PyTypeObject, tp_flags), READONLY},
+	{"__weakrefoffset__", T_LONG,
+	 offsetof(PyTypeObject, tp_weaklistoffset), READONLY},
+	{"__base__", T_OBJECT, offsetof(PyTypeObject, tp_base), READONLY},
+	{"__dictoffset__", T_LONG,
+	 offsetof(PyTypeObject, tp_dictoffset), READONLY},
+	{"__mro__", T_OBJECT, offsetof(PyTypeObject, tp_mro), READONLY},
+	{0}
+};
+
+static PyObject *
+type_name(PyTypeObject *type, void *context)
+{
+	const char *s;
+
+	if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) {
+		PyHeapTypeObject* et = (PyHeapTypeObject*)type;
+
+		Py_INCREF(et->ht_name);
+		return et->ht_name;
+	}
+	else {
+		s = strrchr(type->tp_name, '.');
+		if (s == NULL)
+			s = type->tp_name;
+		else
+			s++;
+		return PyString_FromString(s);
+	}
+}
+
+static int
+type_set_name(PyTypeObject *type, PyObject *value, void *context)
+{
+	PyHeapTypeObject* et;
+
+	if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) {
+		PyErr_Format(PyExc_TypeError,
+			     "can't set %s.__name__", type->tp_name);
+		return -1;
+	}
+	if (!value) {
+		PyErr_Format(PyExc_TypeError,
+			     "can't delete %s.__name__", type->tp_name);
+		return -1;
+	}
+	if (!PyString_Check(value)) {
+		PyErr_Format(PyExc_TypeError,
+			     "can only assign string to %s.__name__, not '%s'",
+			     type->tp_name, value->ob_type->tp_name);
+		return -1;
+	}
+	if (strlen(PyString_AS_STRING(value))
+	    != (size_t)PyString_GET_SIZE(value)) {
+		PyErr_Format(PyExc_ValueError,
+			     "__name__ must not contain null bytes");
+		return -1;
+	}
+
+	et = (PyHeapTypeObject*)type;
+
+	Py_INCREF(value);
+
+	Py_DECREF(et->ht_name);
+	et->ht_name = value;
+
+	type->tp_name = PyString_AS_STRING(value);
+
+	return 0;
+}
+
+static PyObject *
+type_module(PyTypeObject *type, void *context)
+{
+	PyObject *mod;
+	char *s;
+
+	if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) {
+		mod = PyDict_GetItemString(type->tp_dict, "__module__");
+		if (!mod) { 
+			PyErr_Format(PyExc_AttributeError, "__module__");
+			return 0;
+		}
+		Py_XINCREF(mod);
+		return mod;
+	}
+	else {
+		s = strrchr(type->tp_name, '.');
+		if (s != NULL)
+			return PyString_FromStringAndSize(
+			    type->tp_name, (Py_ssize_t)(s - type->tp_name));
+		return PyString_FromString("__builtin__");
+	}
+}
+
+static int
+type_set_module(PyTypeObject *type, PyObject *value, void *context)
+{
+	if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) {
+		PyErr_Format(PyExc_TypeError,
+			     "can't set %s.__module__", type->tp_name);
+		return -1;
+	}
+	if (!value) {
+		PyErr_Format(PyExc_TypeError,
+			     "can't delete %s.__module__", type->tp_name);
+		return -1;
+	}
+
+	return PyDict_SetItemString(type->tp_dict, "__module__", value);
+}
+
+static PyObject *
+type_get_bases(PyTypeObject *type, void *context)
+{
+	Py_INCREF(type->tp_bases);
+	return type->tp_bases;
+}
+
+static PyTypeObject *best_base(PyObject *);
+static int mro_internal(PyTypeObject *);
+static int compatible_for_assignment(PyTypeObject *, PyTypeObject *, char *);
+static int add_subclass(PyTypeObject*, PyTypeObject*);
+static void remove_subclass(PyTypeObject *, PyTypeObject *);
+static void update_all_slots(PyTypeObject *);
+
+typedef int (*update_callback)(PyTypeObject *, void *);
+static int update_subclasses(PyTypeObject *type, PyObject *name,
+			     update_callback callback, void *data);
+static int recurse_down_subclasses(PyTypeObject *type, PyObject *name,
+				   update_callback callback, void *data);
+
+static int
+mro_subclasses(PyTypeObject *type, PyObject* temp)
+{
+	PyTypeObject *subclass;
+	PyObject *ref, *subclasses, *old_mro;
+	Py_ssize_t i, n;
+
+	subclasses = type->tp_subclasses;
+	if (subclasses == NULL)
+		return 0;
+	assert(PyList_Check(subclasses));
+	n = PyList_GET_SIZE(subclasses);
+	for (i = 0; i < n; i++) {
+		ref = PyList_GET_ITEM(subclasses, i);
+		assert(PyWeakref_CheckRef(ref));
+		subclass = (PyTypeObject *)PyWeakref_GET_OBJECT(ref);
+		assert(subclass != NULL);
+		if ((PyObject *)subclass == Py_None)
+			continue;
+		assert(PyType_Check(subclass));
+		old_mro = subclass->tp_mro;
+		if (mro_internal(subclass) < 0) {
+			subclass->tp_mro = old_mro;
+			return -1;
+		}
+		else {
+			PyObject* tuple;
+			tuple = PyTuple_Pack(2, subclass, old_mro);
+			Py_DECREF(old_mro);
+			if (!tuple)
+				return -1;
+			if (PyList_Append(temp, tuple) < 0)
+				return -1;
+			Py_DECREF(tuple);
+		}
+		if (mro_subclasses(subclass, temp) < 0)
+			return -1;
+	}
+	return 0;
+}
+
+static int
+type_set_bases(PyTypeObject *type, PyObject *value, void *context)
+{
+	Py_ssize_t i;
+	int r = 0;
+	PyObject *ob, *temp;
+	PyTypeObject *new_base, *old_base;
+	PyObject *old_bases, *old_mro;
+
+	if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) {
+		PyErr_Format(PyExc_TypeError,
+			     "can't set %s.__bases__", type->tp_name);
+		return -1;
+	}
+	if (!value) {
+		PyErr_Format(PyExc_TypeError,
+			     "can't delete %s.__bases__", type->tp_name);
+		return -1;
+	}
+	if (!PyTuple_Check(value)) {
+		PyErr_Format(PyExc_TypeError,
+		     "can only assign tuple to %s.__bases__, not %s",
+			     type->tp_name, value->ob_type->tp_name);
+		return -1;
+	}
+	if (PyTuple_GET_SIZE(value) == 0) {
+		PyErr_Format(PyExc_TypeError,
+		     "can only assign non-empty tuple to %s.__bases__, not ()",
+			     type->tp_name);
+		return -1;
+	}
+	for (i = 0; i < PyTuple_GET_SIZE(value); i++) {
+		ob = PyTuple_GET_ITEM(value, i);
+		if (!PyClass_Check(ob) && !PyType_Check(ob)) {
+			PyErr_Format(
+				PyExc_TypeError,
+	"%s.__bases__ must be tuple of old- or new-style classes, not '%s'",
+				type->tp_name, ob->ob_type->tp_name);
+			return -1;
+		}
+		if (PyType_Check(ob)) {
+			if (PyType_IsSubtype((PyTypeObject*)ob, type)) {
+				PyErr_SetString(PyExc_TypeError,
+			"a __bases__ item causes an inheritance cycle");
+				return -1;
+			}
+		}
+	}
+
+	new_base = best_base(value);
+
+	if (!new_base) {
+		return -1;
+	}
+
+	if (!compatible_for_assignment(type->tp_base, new_base, "__bases__"))
+		return -1;
+
+	Py_INCREF(new_base);
+	Py_INCREF(value);
+
+	old_bases = type->tp_bases;
+	old_base = type->tp_base;
+	old_mro = type->tp_mro;
+
+	type->tp_bases = value;
+	type->tp_base = new_base;
+
+	if (mro_internal(type) < 0) {
+		goto bail;
+	}
+
+	temp = PyList_New(0);
+	if (!temp)
+		goto bail;
+
+	r = mro_subclasses(type, temp);
+
+	if (r < 0) {
+		for (i = 0; i < PyList_Size(temp); i++) {
+			PyTypeObject* cls;
+			PyObject* mro;
+			PyArg_UnpackTuple(PyList_GET_ITEM(temp, i),
+					 "", 2, 2, &cls, &mro);
+			Py_DECREF(cls->tp_mro);
+			cls->tp_mro = mro;
+			Py_INCREF(cls->tp_mro);
+		}
+		Py_DECREF(temp);
+		goto bail;
+	}
+
+	Py_DECREF(temp);
+
+	/* any base that was in __bases__ but now isn't, we
+	   need to remove |type| from its tp_subclasses.
+	   conversely, any class now in __bases__ that wasn't
+	   needs to have |type| added to its subclasses. */
+
+	/* for now, sod that: just remove from all old_bases,
+	   add to all new_bases */
+
+	for (i = PyTuple_GET_SIZE(old_bases) - 1; i >= 0; i--) {
+		ob = PyTuple_GET_ITEM(old_bases, i);
+		if (PyType_Check(ob)) {
+			remove_subclass(
+				(PyTypeObject*)ob, type);
+		}
+	}
+
+	for (i = PyTuple_GET_SIZE(value) - 1; i >= 0; i--) {
+		ob = PyTuple_GET_ITEM(value, i);
+		if (PyType_Check(ob)) {
+			if (add_subclass((PyTypeObject*)ob, type) < 0)
+				r = -1;
+		}
+	}
+
+	update_all_slots(type);
+
+	Py_DECREF(old_bases);
+	Py_DECREF(old_base);
+	Py_DECREF(old_mro);
+
+	return r;
+
+  bail:
+	Py_DECREF(type->tp_bases);
+	Py_DECREF(type->tp_base);
+	if (type->tp_mro != old_mro) {
+		Py_DECREF(type->tp_mro);
+	}
+
+	type->tp_bases = old_bases;
+	type->tp_base = old_base;
+	type->tp_mro = old_mro;
+
+	return -1;
+}
+
+static PyObject *
+type_dict(PyTypeObject *type, void *context)
+{
+	if (type->tp_dict == NULL) {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+	return PyDictProxy_New(type->tp_dict);
+}
+
+static PyObject *
+type_get_doc(PyTypeObject *type, void *context)
+{
+	PyObject *result;
+	if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE) && type->tp_doc != NULL)
+		return PyString_FromString(type->tp_doc);
+	result = PyDict_GetItemString(type->tp_dict, "__doc__");
+	if (result == NULL) {
+		result = Py_None;
+		Py_INCREF(result);
+	}
+	else if (result->ob_type->tp_descr_get) {
+		result = result->ob_type->tp_descr_get(result, NULL,
+						       (PyObject *)type);
+	}
+	else {
+		Py_INCREF(result);
+	}
+	return result;
+}
+
+static PyGetSetDef type_getsets[] = {
+	{"__name__", (getter)type_name, (setter)type_set_name, NULL},
+	{"__bases__", (getter)type_get_bases, (setter)type_set_bases, NULL},
+	{"__module__", (getter)type_module, (setter)type_set_module, NULL},
+	{"__dict__",  (getter)type_dict,  NULL, NULL},
+	{"__doc__", (getter)type_get_doc, NULL, NULL},
+	{0}
+};
+
+static int
+type_compare(PyObject *v, PyObject *w)
+{
+	/* This is called with type objects only. So we
+	   can just compare the addresses. */
+	Py_uintptr_t vv = (Py_uintptr_t)v;
+	Py_uintptr_t ww = (Py_uintptr_t)w;
+	return (vv < ww) ? -1 : (vv > ww) ? 1 : 0;
+}
+
+static PyObject *
+type_repr(PyTypeObject *type)
+{
+	PyObject *mod, *name, *rtn;
+	char *kind;
+
+	mod = type_module(type, NULL);
+	if (mod == NULL)
+		PyErr_Clear();
+	else if (!PyString_Check(mod)) {
+		Py_DECREF(mod);
+		mod = NULL;
+	}
+	name = type_name(type, NULL);
+	if (name == NULL)
+		return NULL;
+
+	if (type->tp_flags & Py_TPFLAGS_HEAPTYPE)
+		kind = "class";
+	else
+		kind = "type";
+
+	if (mod != NULL && strcmp(PyString_AS_STRING(mod), "__builtin__")) {
+		rtn = PyString_FromFormat("<%s '%s.%s'>",
+					  kind,
+					  PyString_AS_STRING(mod),
+					  PyString_AS_STRING(name));
+	}
+	else
+		rtn = PyString_FromFormat("<%s '%s'>", kind, type->tp_name);
+
+	Py_XDECREF(mod);
+	Py_DECREF(name);
+	return rtn;
+}
+
+static PyObject *
+type_call(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	PyObject *obj;
+
+	if (type->tp_new == NULL) {
+		PyErr_Format(PyExc_TypeError,
+			     "cannot create '%.100s' instances",
+			     type->tp_name);
+		return NULL;
+	}
+
+	obj = type->tp_new(type, args, kwds);
+	if (obj != NULL) {
+		/* Ugly exception: when the call was type(something),
+		   don't call tp_init on the result. */
+		if (type == &PyType_Type &&
+		    PyTuple_Check(args) && PyTuple_GET_SIZE(args) == 1 &&
+		    (kwds == NULL ||
+		     (PyDict_Check(kwds) && PyDict_Size(kwds) == 0)))
+			return obj;
+		/* If the returned object is not an instance of type,
+		   it won't be initialized. */
+		if (!PyType_IsSubtype(obj->ob_type, type))
+			return obj;
+		type = obj->ob_type;
+		if (PyType_HasFeature(type, Py_TPFLAGS_HAVE_CLASS) &&
+		    type->tp_init != NULL &&
+		    type->tp_init(obj, args, kwds) < 0) {
+			Py_DECREF(obj);
+			obj = NULL;
+		}
+	}
+	return obj;
+}
+
+PyObject *
+PyType_GenericAlloc(PyTypeObject *type, Py_ssize_t nitems)
+{
+	PyObject *obj;
+	const size_t size = _PyObject_VAR_SIZE(type, nitems+1);
+	/* note that we need to add one, for the sentinel */
+
+	if (PyType_IS_GC(type))
+		obj = _PyObject_GC_Malloc(size);
+	else
+		obj = (PyObject *)PyObject_MALLOC(size);
+
+	if (obj == NULL)
+		return PyErr_NoMemory();
+
+	memset(obj, '\0', size);
+
+	if (type->tp_flags & Py_TPFLAGS_HEAPTYPE)
+		Py_INCREF(type);
+
+	if (type->tp_itemsize == 0)
+		PyObject_INIT(obj, type);
+	else
+		(void) PyObject_INIT_VAR((PyVarObject *)obj, type, nitems);
+
+	if (PyType_IS_GC(type))
+		_PyObject_GC_TRACK(obj);
+	return obj;
+}
+
+PyObject *
+PyType_GenericNew(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	return type->tp_alloc(type, 0);
+}
+
+/* Helpers for subtyping */
+
+static int
+traverse_slots(PyTypeObject *type, PyObject *self, visitproc visit, void *arg)
+{
+	Py_ssize_t i, n;
+	PyMemberDef *mp;
+
+	n = type->ob_size;
+	mp = PyHeapType_GET_MEMBERS((PyHeapTypeObject *)type);
+	for (i = 0; i < n; i++, mp++) {
+		if (mp->type == T_OBJECT_EX) {
+			char *addr = (char *)self + mp->offset;
+			PyObject *obj = *(PyObject **)addr;
+			if (obj != NULL) {
+				int err = visit(obj, arg);
+				if (err)
+					return err;
+			}
+		}
+	}
+	return 0;
+}
+
+static int
+subtype_traverse(PyObject *self, visitproc visit, void *arg)
+{
+	PyTypeObject *type, *base;
+	traverseproc basetraverse;
+
+	/* Find the nearest base with a different tp_traverse,
+	   and traverse slots while we're at it */
+	type = self->ob_type;
+	base = type;
+	while ((basetraverse = base->tp_traverse) == subtype_traverse) {
+		if (base->ob_size) {
+			int err = traverse_slots(base, self, visit, arg);
+			if (err)
+				return err;
+		}
+		base = base->tp_base;
+		assert(base);
+	}
+
+	if (type->tp_dictoffset != base->tp_dictoffset) {
+		PyObject **dictptr = _PyObject_GetDictPtr(self);
+		if (dictptr && *dictptr)
+			Py_VISIT(*dictptr);
+	}
+
+	if (type->tp_flags & Py_TPFLAGS_HEAPTYPE)
+		/* For a heaptype, the instances count as references
+		   to the type.  Traverse the type so the collector
+		   can find cycles involving this link. */
+		Py_VISIT(type);
+
+	if (basetraverse)
+		return basetraverse(self, visit, arg);
+	return 0;
+}
+
+static void
+clear_slots(PyTypeObject *type, PyObject *self)
+{
+	Py_ssize_t i, n;
+	PyMemberDef *mp;
+
+	n = type->ob_size;
+	mp = PyHeapType_GET_MEMBERS((PyHeapTypeObject *)type);
+	for (i = 0; i < n; i++, mp++) {
+		if (mp->type == T_OBJECT_EX && !(mp->flags & READONLY)) {
+			char *addr = (char *)self + mp->offset;
+			PyObject *obj = *(PyObject **)addr;
+			if (obj != NULL) {
+				*(PyObject **)addr = NULL;
+				Py_DECREF(obj);
+			}
+		}
+	}
+}
+
+static int
+subtype_clear(PyObject *self)
+{
+	PyTypeObject *type, *base;
+	inquiry baseclear;
+
+	/* Find the nearest base with a different tp_clear
+	   and clear slots while we're at it */
+	type = self->ob_type;
+	base = type;
+	while ((baseclear = base->tp_clear) == subtype_clear) {
+		if (base->ob_size)
+			clear_slots(base, self);
+		base = base->tp_base;
+		assert(base);
+	}
+
+	/* There's no need to clear the instance dict (if any);
+	   the collector will call its tp_clear handler. */
+
+	if (baseclear)
+		return baseclear(self);
+	return 0;
+}
+
+static void
+subtype_dealloc(PyObject *self)
+{
+	PyTypeObject *type, *base;
+	destructor basedealloc;
+
+	/* Extract the type; we expect it to be a heap type */
+	type = self->ob_type;
+	assert(type->tp_flags & Py_TPFLAGS_HEAPTYPE);
+
+	/* Test whether the type has GC exactly once */
+
+	if (!PyType_IS_GC(type)) {
+		/* It's really rare to find a dynamic type that doesn't have
+		   GC; it can only happen when deriving from 'object' and not
+		   adding any slots or instance variables.  This allows
+		   certain simplifications: there's no need to call
+		   clear_slots(), or DECREF the dict, or clear weakrefs. */
+
+		/* Maybe call finalizer; exit early if resurrected */
+		if (type->tp_del) {
+			type->tp_del(self);
+			if (self->ob_refcnt > 0)
+				return;
+		}
+
+		/* Find the nearest base with a different tp_dealloc */
+		base = type;
+		while ((basedealloc = base->tp_dealloc) == subtype_dealloc) {
+			assert(base->ob_size == 0);
+			base = base->tp_base;
+			assert(base);
+		}
+
+		/* Call the base tp_dealloc() */
+		assert(basedealloc);
+		basedealloc(self);
+
+		/* Can't reference self beyond this point */
+		Py_DECREF(type);
+
+		/* Done */
+		return;
+	}
+
+	/* We get here only if the type has GC */
+
+	/* UnTrack and re-Track around the trashcan macro, alas */
+	/* See explanation at end of function for full disclosure */
+	PyObject_GC_UnTrack(self);
+	++_PyTrash_delete_nesting;
+	Py_TRASHCAN_SAFE_BEGIN(self);
+	--_PyTrash_delete_nesting;
+	/* DO NOT restore GC tracking at this point.  weakref callbacks
+	 * (if any, and whether directly here or indirectly in something we
+	 * call) may trigger GC, and if self is tracked at that point, it
+	 * will look like trash to GC and GC will try to delete self again.
+	 */
+
+	/* Find the nearest base with a different tp_dealloc */
+	base = type;
+	while ((basedealloc = base->tp_dealloc) == subtype_dealloc) {
+		base = base->tp_base;
+		assert(base);
+	}
+
+	/* If we added a weaklist, we clear it.  Do this *before* calling
+	   the finalizer (__del__), clearing slots, or clearing the instance
+	   dict. */
+
+	if (type->tp_weaklistoffset && !base->tp_weaklistoffset)
+		PyObject_ClearWeakRefs(self);
+
+	/* Maybe call finalizer; exit early if resurrected */
+	if (type->tp_del) {
+		_PyObject_GC_TRACK(self);
+		type->tp_del(self);
+		if (self->ob_refcnt > 0)
+			goto endlabel;	/* resurrected */
+		else
+			_PyObject_GC_UNTRACK(self);
+		/* New weakrefs could be created during the finalizer call.
+		    If this occurs, clear them out without calling their
+		    finalizers since they might rely on part of the object
+		    being finalized that has already been destroyed. */
+		if (type->tp_weaklistoffset && !base->tp_weaklistoffset) {
+			/* Modeled after GET_WEAKREFS_LISTPTR() */
+			PyWeakReference **list = (PyWeakReference **) \
+				PyObject_GET_WEAKREFS_LISTPTR(self);
+			while (*list)
+				_PyWeakref_ClearRef(*list);
+		}
+	}
+
+	/*  Clear slots up to the nearest base with a different tp_dealloc */
+	base = type;
+	while ((basedealloc = base->tp_dealloc) == subtype_dealloc) {
+		if (base->ob_size)
+			clear_slots(base, self);
+		base = base->tp_base;
+		assert(base);
+	}
+
+	/* If we added a dict, DECREF it */
+	if (type->tp_dictoffset && !base->tp_dictoffset) {
+		PyObject **dictptr = _PyObject_GetDictPtr(self);
+		if (dictptr != NULL) {
+			PyObject *dict = *dictptr;
+			if (dict != NULL) {
+				Py_DECREF(dict);
+				*dictptr = NULL;
+			}
+		}
+	}
+
+	/* Call the base tp_dealloc(); first retrack self if
+	 * basedealloc knows about gc.
+	 */
+	if (PyType_IS_GC(base))
+		_PyObject_GC_TRACK(self);
+	assert(basedealloc);
+	basedealloc(self);
+
+	/* Can't reference self beyond this point */
+	Py_DECREF(type);
+
+  endlabel:
+	++_PyTrash_delete_nesting;
+	Py_TRASHCAN_SAFE_END(self);
+	--_PyTrash_delete_nesting;
+
+	/* Explanation of the weirdness around the trashcan macros:
+
+	   Q. What do the trashcan macros do?
+
+	   A. Read the comment titled "Trashcan mechanism" in object.h.
+	      For one, this explains why there must be a call to GC-untrack
+	      before the trashcan begin macro.  Without understanding the
+	      trashcan code, the answers to the following questions don't make
+	      sense.
+
+	   Q. Why do we GC-untrack before the trashcan and then immediately
+	      GC-track again afterward?
+
+	   A. In the case that the base class is GC-aware, the base class
+	      probably GC-untracks the object.  If it does that using the
+	      UNTRACK macro, this will crash when the object is already
+	      untracked.  Because we don't know what the base class does, the
+	      only safe thing is to make sure the object is tracked when we
+	      call the base class dealloc.  But...  The trashcan begin macro
+	      requires that the object is *untracked* before it is called.  So
+	      the dance becomes:
+
+	         GC untrack
+		 trashcan begin
+		 GC track
+
+           Q. Why did the last question say "immediately GC-track again"?
+              It's nowhere near immediately.
+
+           A. Because the code *used* to re-track immediately.  Bad Idea.
+              self has a refcount of 0, and if gc ever gets its hands on it
+              (which can happen if any weakref callback gets invoked), it
+              looks like trash to gc too, and gc also tries to delete self
+              then.  But we're already deleting self.  Double dealloction is
+              a subtle disaster.
+
+	   Q. Why the bizarre (net-zero) manipulation of
+	      _PyTrash_delete_nesting around the trashcan macros?
+
+	   A. Some base classes (e.g. list) also use the trashcan mechanism.
+	      The following scenario used to be possible:
+
+	      - suppose the trashcan level is one below the trashcan limit
+
+	      - subtype_dealloc() is called
+
+	      - the trashcan limit is not yet reached, so the trashcan level
+	        is incremented and the code between trashcan begin and end is
+	        executed
+
+	      - this destroys much of the object's contents, including its
+	        slots and __dict__
+
+	      - basedealloc() is called; this is really list_dealloc(), or
+	        some other type which also uses the trashcan macros
+
+	      - the trashcan limit is now reached, so the object is put on the
+	        trashcan's to-be-deleted-later list
+
+	      - basedealloc() returns
+
+	      - subtype_dealloc() decrefs the object's type
+
+	      - subtype_dealloc() returns
+
+	      - later, the trashcan code starts deleting the objects from its
+	        to-be-deleted-later list
+
+	      - subtype_dealloc() is called *AGAIN* for the same object
+
+	      - at the very least (if the destroyed slots and __dict__ don't
+	        cause problems) the object's type gets decref'ed a second
+	        time, which is *BAD*!!!
+
+	      The remedy is to make sure that if the code between trashcan
+	      begin and end in subtype_dealloc() is called, the code between
+	      trashcan begin and end in basedealloc() will also be called.
+	      This is done by decrementing the level after passing into the
+	      trashcan block, and incrementing it just before leaving the
+	      block.
+
+	      But now it's possible that a chain of objects consisting solely
+	      of objects whose deallocator is subtype_dealloc() will defeat
+	      the trashcan mechanism completely: the decremented level means
+	      that the effective level never reaches the limit.  Therefore, we
+	      *increment* the level *before* entering the trashcan block, and
+	      matchingly decrement it after leaving.  This means the trashcan
+	      code will trigger a little early, but that's no big deal.
+
+	   Q. Are there any live examples of code in need of all this
+	      complexity?
+
+	   A. Yes.  See SF bug 668433 for code that crashed (when Python was
+	      compiled in debug mode) before the trashcan level manipulations
+	      were added.  For more discussion, see SF patches 581742, 575073
+	      and bug 574207.
+	*/
+}
+
+static PyTypeObject *solid_base(PyTypeObject *type);
+
+/* type test with subclassing support */
+
+int
+PyType_IsSubtype(PyTypeObject *a, PyTypeObject *b)
+{
+	PyObject *mro;
+
+	if (!(a->tp_flags & Py_TPFLAGS_HAVE_CLASS))
+		return b == a || b == &PyBaseObject_Type;
+
+	mro = a->tp_mro;
+	if (mro != NULL) {
+		/* Deal with multiple inheritance without recursion
+		   by walking the MRO tuple */
+		Py_ssize_t i, n;
+		assert(PyTuple_Check(mro));
+		n = PyTuple_GET_SIZE(mro);
+		for (i = 0; i < n; i++) {
+			if (PyTuple_GET_ITEM(mro, i) == (PyObject *)b)
+				return 1;
+		}
+		return 0;
+	}
+	else {
+		/* a is not completely initilized yet; follow tp_base */
+		do {
+			if (a == b)
+				return 1;
+			a = a->tp_base;
+		} while (a != NULL);
+		return b == &PyBaseObject_Type;
+	}
+}
+
+/* Internal routines to do a method lookup in the type
+   without looking in the instance dictionary
+   (so we can't use PyObject_GetAttr) but still binding
+   it to the instance.  The arguments are the object,
+   the method name as a C string, and the address of a
+   static variable used to cache the interned Python string.
+
+   Two variants:
+
+   - lookup_maybe() returns NULL without raising an exception
+     when the _PyType_Lookup() call fails;
+
+   - lookup_method() always raises an exception upon errors.
+*/
+
+static PyObject *
+lookup_maybe(PyObject *self, char *attrstr, PyObject **attrobj)
+{
+	PyObject *res;
+
+	if (*attrobj == NULL) {
+		*attrobj = PyString_InternFromString(attrstr);
+		if (*attrobj == NULL)
+			return NULL;
+	}
+	res = _PyType_Lookup(self->ob_type, *attrobj);
+	if (res != NULL) {
+		descrgetfunc f;
+		if ((f = res->ob_type->tp_descr_get) == NULL)
+			Py_INCREF(res);
+		else
+			res = f(res, self, (PyObject *)(self->ob_type));
+	}
+	return res;
+}
+
+static PyObject *
+lookup_method(PyObject *self, char *attrstr, PyObject **attrobj)
+{
+	PyObject *res = lookup_maybe(self, attrstr, attrobj);
+	if (res == NULL && !PyErr_Occurred())
+		PyErr_SetObject(PyExc_AttributeError, *attrobj);
+	return res;
+}
+
+/* A variation of PyObject_CallMethod that uses lookup_method()
+   instead of PyObject_GetAttrString().  This uses the same convention
+   as lookup_method to cache the interned name string object. */
+
+static PyObject *
+call_method(PyObject *o, char *name, PyObject **nameobj, char *format, ...)
+{
+	va_list va;
+	PyObject *args, *func = 0, *retval;
+	va_start(va, format);
+
+	func = lookup_maybe(o, name, nameobj);
+	if (func == NULL) {
+		va_end(va);
+		if (!PyErr_Occurred())
+			PyErr_SetObject(PyExc_AttributeError, *nameobj);
+		return NULL;
+	}
+
+	if (format && *format)
+		args = Py_VaBuildValue(format, va);
+	else
+		args = PyTuple_New(0);
+
+	va_end(va);
+
+	if (args == NULL)
+		return NULL;
+
+	assert(PyTuple_Check(args));
+	retval = PyObject_Call(func, args, NULL);
+
+	Py_DECREF(args);
+	Py_DECREF(func);
+
+	return retval;
+}
+
+/* Clone of call_method() that returns NotImplemented when the lookup fails. */
+
+static PyObject *
+call_maybe(PyObject *o, char *name, PyObject **nameobj, char *format, ...)
+{
+	va_list va;
+	PyObject *args, *func = 0, *retval;
+	va_start(va, format);
+
+	func = lookup_maybe(o, name, nameobj);
+	if (func == NULL) {
+		va_end(va);
+		if (!PyErr_Occurred()) {
+			Py_INCREF(Py_NotImplemented);
+			return Py_NotImplemented;
+		}
+		return NULL;
+	}
+
+	if (format && *format)
+		args = Py_VaBuildValue(format, va);
+	else
+		args = PyTuple_New(0);
+
+	va_end(va);
+
+	if (args == NULL)
+		return NULL;
+
+	assert(PyTuple_Check(args));
+	retval = PyObject_Call(func, args, NULL);
+
+	Py_DECREF(args);
+	Py_DECREF(func);
+
+	return retval;
+}
+
+static int
+fill_classic_mro(PyObject *mro, PyObject *cls)
+{
+	PyObject *bases, *base;
+	Py_ssize_t i, n;
+
+	assert(PyList_Check(mro));
+	assert(PyClass_Check(cls));
+	i = PySequence_Contains(mro, cls);
+	if (i < 0)
+		return -1;
+	if (!i) {
+		if (PyList_Append(mro, cls) < 0)
+			return -1;
+	}
+	bases = ((PyClassObject *)cls)->cl_bases;
+	assert(bases && PyTuple_Check(bases));
+	n = PyTuple_GET_SIZE(bases);
+	for (i = 0; i < n; i++) {
+		base = PyTuple_GET_ITEM(bases, i);
+		if (fill_classic_mro(mro, base) < 0)
+			return -1;
+	}
+	return 0;
+}
+
+static PyObject *
+classic_mro(PyObject *cls)
+{
+	PyObject *mro;
+
+	assert(PyClass_Check(cls));
+	mro = PyList_New(0);
+	if (mro != NULL) {
+		if (fill_classic_mro(mro, cls) == 0)
+			return mro;
+		Py_DECREF(mro);
+	}
+	return NULL;
+}
+
+/*
+    Method resolution order algorithm C3 described in
+    "A Monotonic Superclass Linearization for Dylan",
+    by Kim Barrett, Bob Cassel, Paul Haahr,
+    David A. Moon, Keith Playford, and P. Tucker Withington.
+    (OOPSLA 1996)
+
+    Some notes about the rules implied by C3:
+
+    No duplicate bases.
+    It isn't legal to repeat a class in a list of base classes.
+
+    The next three properties are the 3 constraints in "C3".
+
+    Local precendece order.
+    If A precedes B in C's MRO, then A will precede B in the MRO of all
+    subclasses of C.
+
+    Monotonicity.
+    The MRO of a class must be an extension without reordering of the
+    MRO of each of its superclasses.
+
+    Extended Precedence Graph (EPG).
+    Linearization is consistent if there is a path in the EPG from
+    each class to all its successors in the linearization.  See
+    the paper for definition of EPG.
+ */
+
+static int
+tail_contains(PyObject *list, int whence, PyObject *o) {
+	Py_ssize_t j, size;
+	size = PyList_GET_SIZE(list);
+
+	for (j = whence+1; j < size; j++) {
+		if (PyList_GET_ITEM(list, j) == o)
+			return 1;
+	}
+	return 0;
+}
+
+static PyObject *
+class_name(PyObject *cls)
+{
+	PyObject *name = PyObject_GetAttrString(cls, "__name__");
+	if (name == NULL) {
+		PyErr_Clear();
+		Py_XDECREF(name);
+		name = PyObject_Repr(cls);
+	}
+	if (name == NULL)
+		return NULL;
+	if (!PyString_Check(name)) {
+		Py_DECREF(name);
+		return NULL;
+	}
+	return name;
+}
+
+static int
+check_duplicates(PyObject *list)
+{
+	Py_ssize_t i, j, n;
+	/* Let's use a quadratic time algorithm,
+	   assuming that the bases lists is short.
+	*/
+	n = PyList_GET_SIZE(list);
+	for (i = 0; i < n; i++) {
+		PyObject *o = PyList_GET_ITEM(list, i);
+		for (j = i + 1; j < n; j++) {
+			if (PyList_GET_ITEM(list, j) == o) {
+				o = class_name(o);
+				PyErr_Format(PyExc_TypeError,
+					     "duplicate base class %s",
+					     o ? PyString_AS_STRING(o) : "?");
+				Py_XDECREF(o);
+				return -1;
+			}
+		}
+	}
+	return 0;
+}
+
+/* Raise a TypeError for an MRO order disagreement.
+
+   It's hard to produce a good error message.  In the absence of better
+   insight into error reporting, report the classes that were candidates
+   to be put next into the MRO.  There is some conflict between the
+   order in which they should be put in the MRO, but it's hard to
+   diagnose what constraint can't be satisfied.
+*/
+
+static void
+set_mro_error(PyObject *to_merge, int *remain)
+{
+	Py_ssize_t i, n, off, to_merge_size;
+	char buf[1000];
+	PyObject *k, *v;
+	PyObject *set = PyDict_New();
+	if (!set) return;
+
+	to_merge_size = PyList_GET_SIZE(to_merge);
+	for (i = 0; i < to_merge_size; i++) {
+		PyObject *L = PyList_GET_ITEM(to_merge, i);
+		if (remain[i] < PyList_GET_SIZE(L)) {
+			PyObject *c = PyList_GET_ITEM(L, remain[i]);
+			if (PyDict_SetItem(set, c, Py_None) < 0) {
+				Py_DECREF(set);
+				return;
+			}
+		}
+	}
+	n = PyDict_Size(set);
+
+	off = PyOS_snprintf(buf, sizeof(buf), "Cannot create a \
+consistent method resolution\norder (MRO) for bases");
+	i = 0;
+	while (PyDict_Next(set, &i, &k, &v) && (size_t)off < sizeof(buf)) {
+		PyObject *name = class_name(k);
+		off += PyOS_snprintf(buf + off, sizeof(buf) - off, " %s",
+				     name ? PyString_AS_STRING(name) : "?");
+		Py_XDECREF(name);
+		if (--n && (size_t)(off+1) < sizeof(buf)) {
+			buf[off++] = ',';
+			buf[off] = '\0';
+		}
+	}
+	PyErr_SetString(PyExc_TypeError, buf);
+	Py_DECREF(set);
+}
+
+static int
+pmerge(PyObject *acc, PyObject* to_merge) {
+	Py_ssize_t i, j, to_merge_size, empty_cnt;
+	int *remain;
+	int ok;
+
+	to_merge_size = PyList_GET_SIZE(to_merge);
+
+	/* remain stores an index into each sublist of to_merge.
+	   remain[i] is the index of the next base in to_merge[i]
+	   that is not included in acc.
+	*/
+	remain = (int *)PyMem_MALLOC(SIZEOF_INT*to_merge_size);
+	if (remain == NULL)
+		return -1;
+	for (i = 0; i < to_merge_size; i++)
+		remain[i] = 0;
+
+  again:
+	empty_cnt = 0;
+	for (i = 0; i < to_merge_size; i++) {
+		PyObject *candidate;
+
+		PyObject *cur_list = PyList_GET_ITEM(to_merge, i);
+
+		if (remain[i] >= PyList_GET_SIZE(cur_list)) {
+			empty_cnt++;
+			continue;
+                }
+
+		/* Choose next candidate for MRO.
+
+		   The input sequences alone can determine the choice.
+		   If not, choose the class which appears in the MRO
+		   of the earliest direct superclass of the new class.
+		*/
+
+		candidate = PyList_GET_ITEM(cur_list, remain[i]);
+		for (j = 0; j < to_merge_size; j++) {
+			PyObject *j_lst = PyList_GET_ITEM(to_merge, j);
+			if (tail_contains(j_lst, remain[j], candidate)) {
+				goto skip; /* continue outer loop */
+			}
+		}
+		ok = PyList_Append(acc, candidate);
+		if (ok < 0) {
+			PyMem_Free(remain);
+			return -1;
+		}
+		for (j = 0; j < to_merge_size; j++) {
+			PyObject *j_lst = PyList_GET_ITEM(to_merge, j);
+			if (remain[j] < PyList_GET_SIZE(j_lst) &&
+			    PyList_GET_ITEM(j_lst, remain[j]) == candidate) {
+				remain[j]++;
+			}
+		}
+		goto again;
+	  skip: ;
+	}
+
+	if (empty_cnt == to_merge_size) {
+		PyMem_FREE(remain);
+		return 0;
+	}
+	set_mro_error(to_merge, remain);
+	PyMem_FREE(remain);
+	return -1;
+}
+
+static PyObject *
+mro_implementation(PyTypeObject *type)
+{
+	Py_ssize_t i, n;
+	int ok;
+	PyObject *bases, *result;
+	PyObject *to_merge, *bases_aslist;
+
+	if(type->tp_dict == NULL) {
+		if(PyType_Ready(type) < 0)
+			return NULL;
+	}
+
+	/* Find a superclass linearization that honors the constraints
+	   of the explicit lists of bases and the constraints implied by
+	   each base class.
+
+	   to_merge is a list of lists, where each list is a superclass
+	   linearization implied by a base class.  The last element of
+	   to_merge is the declared list of bases.
+	*/
+
+	bases = type->tp_bases;
+	n = PyTuple_GET_SIZE(bases);
+
+	to_merge = PyList_New(n+1);
+	if (to_merge == NULL)
+		return NULL;
+
+	for (i = 0; i < n; i++) {
+		PyObject *base = PyTuple_GET_ITEM(bases, i);
+		PyObject *parentMRO;
+		if (PyType_Check(base))
+			parentMRO = PySequence_List(
+				((PyTypeObject*)base)->tp_mro);
+		else
+			parentMRO = classic_mro(base);
+		if (parentMRO == NULL) {
+			Py_DECREF(to_merge);
+			return NULL;
+	        }
+
+		PyList_SET_ITEM(to_merge, i, parentMRO);
+	}
+
+	bases_aslist = PySequence_List(bases);
+	if (bases_aslist == NULL) {
+		Py_DECREF(to_merge);
+		return NULL;
+	}
+	/* This is just a basic sanity check. */
+	if (check_duplicates(bases_aslist) < 0) {
+		Py_DECREF(to_merge);
+		Py_DECREF(bases_aslist);
+		return NULL;
+	}
+	PyList_SET_ITEM(to_merge, n, bases_aslist);
+
+	result = Py_BuildValue("[O]", (PyObject *)type);
+	if (result == NULL) {
+		Py_DECREF(to_merge);
+		return NULL;
+	}
+
+	ok = pmerge(result, to_merge);
+	Py_DECREF(to_merge);
+	if (ok < 0) {
+		Py_DECREF(result);
+		return NULL;
+	}
+
+	return result;
+}
+
+static PyObject *
+mro_external(PyObject *self)
+{
+	PyTypeObject *type = (PyTypeObject *)self;
+
+	return mro_implementation(type);
+}
+
+static int
+mro_internal(PyTypeObject *type)
+{
+	PyObject *mro, *result, *tuple;
+	int checkit = 0;
+
+	if (type->ob_type == &PyType_Type) {
+		result = mro_implementation(type);
+	}
+	else {
+		static PyObject *mro_str;
+		checkit = 1;
+		mro = lookup_method((PyObject *)type, "mro", &mro_str);
+		if (mro == NULL)
+			return -1;
+		result = PyObject_CallObject(mro, NULL);
+		Py_DECREF(mro);
+	}
+	if (result == NULL)
+		return -1;
+	tuple = PySequence_Tuple(result);
+	Py_DECREF(result);
+	if (tuple == NULL)
+		return -1;
+	if (checkit) {
+		Py_ssize_t i, len;
+		PyObject *cls;
+		PyTypeObject *solid;
+
+		solid = solid_base(type);
+
+		len = PyTuple_GET_SIZE(tuple);
+
+		for (i = 0; i < len; i++) {
+			PyTypeObject *t;
+			cls = PyTuple_GET_ITEM(tuple, i);
+			if (PyClass_Check(cls)) 
+				continue;
+			else if (!PyType_Check(cls)) {
+				PyErr_Format(PyExc_TypeError,
+			     "mro() returned a non-class ('%.500s')",
+					     cls->ob_type->tp_name);
+				Py_DECREF(tuple);
+				return -1;
+			}
+			t = (PyTypeObject*)cls;
+			if (!PyType_IsSubtype(solid, solid_base(t))) {
+				PyErr_Format(PyExc_TypeError,
+		     "mro() returned base with unsuitable layout ('%.500s')",
+					     t->tp_name);
+				Py_DECREF(tuple);
+				return -1;
+			}
+		}
+	}
+	type->tp_mro = tuple;
+	return 0;
+}
+
+
+/* Calculate the best base amongst multiple base classes.
+   This is the first one that's on the path to the "solid base". */
+
+static PyTypeObject *
+best_base(PyObject *bases)
+{
+	Py_ssize_t i, n;
+	PyTypeObject *base, *winner, *candidate, *base_i;
+	PyObject *base_proto;
+
+	assert(PyTuple_Check(bases));
+	n = PyTuple_GET_SIZE(bases);
+	assert(n > 0);
+	base = NULL;
+	winner = NULL;
+	for (i = 0; i < n; i++) {
+		base_proto = PyTuple_GET_ITEM(bases, i);
+		if (PyClass_Check(base_proto))
+			continue;
+		if (!PyType_Check(base_proto)) {
+			PyErr_SetString(
+				PyExc_TypeError,
+				"bases must be types");
+			return NULL;
+		}
+		base_i = (PyTypeObject *)base_proto;
+		if (base_i->tp_dict == NULL) {
+			if (PyType_Ready(base_i) < 0)
+				return NULL;
+		}
+		candidate = solid_base(base_i);
+		if (winner == NULL) {
+			winner = candidate;
+			base = base_i;
+		}
+		else if (PyType_IsSubtype(winner, candidate))
+			;
+		else if (PyType_IsSubtype(candidate, winner)) {
+			winner = candidate;
+			base = base_i;
+		}
+		else {
+			PyErr_SetString(
+				PyExc_TypeError,
+				"multiple bases have "
+				"instance lay-out conflict");
+			return NULL;
+		}
+	}
+	if (base == NULL)
+		PyErr_SetString(PyExc_TypeError,
+			"a new-style class can't have only classic bases");
+	return base;
+}
+
+static int
+extra_ivars(PyTypeObject *type, PyTypeObject *base)
+{
+	size_t t_size = type->tp_basicsize;
+	size_t b_size = base->tp_basicsize;
+
+	assert(t_size >= b_size); /* Else type smaller than base! */
+	if (type->tp_itemsize || base->tp_itemsize) {
+		/* If itemsize is involved, stricter rules */
+		return t_size != b_size ||
+			type->tp_itemsize != base->tp_itemsize;
+	}
+	if (type->tp_weaklistoffset && base->tp_weaklistoffset == 0 &&
+	    type->tp_weaklistoffset + sizeof(PyObject *) == t_size)
+		t_size -= sizeof(PyObject *);
+	if (type->tp_dictoffset && base->tp_dictoffset == 0 &&
+	    type->tp_dictoffset + sizeof(PyObject *) == t_size)
+		t_size -= sizeof(PyObject *);
+
+	return t_size != b_size;
+}
+
+static PyTypeObject *
+solid_base(PyTypeObject *type)
+{
+	PyTypeObject *base;
+
+	if (type->tp_base)
+		base = solid_base(type->tp_base);
+	else
+		base = &PyBaseObject_Type;
+	if (extra_ivars(type, base))
+		return type;
+	else
+		return base;
+}
+
+static void object_dealloc(PyObject *);
+static int object_init(PyObject *, PyObject *, PyObject *);
+static int update_slot(PyTypeObject *, PyObject *);
+static void fixup_slot_dispatchers(PyTypeObject *);
+
+static PyObject *
+subtype_dict(PyObject *obj, void *context)
+{
+	PyObject **dictptr = _PyObject_GetDictPtr(obj);
+	PyObject *dict;
+
+	if (dictptr == NULL) {
+		PyErr_SetString(PyExc_AttributeError,
+				"This object has no __dict__");
+		return NULL;
+	}
+	dict = *dictptr;
+	if (dict == NULL)
+		*dictptr = dict = PyDict_New();
+	Py_XINCREF(dict);
+	return dict;
+}
+
+static int
+subtype_setdict(PyObject *obj, PyObject *value, void *context)
+{
+	PyObject **dictptr = _PyObject_GetDictPtr(obj);
+	PyObject *dict;
+
+	if (dictptr == NULL) {
+		PyErr_SetString(PyExc_AttributeError,
+				"This object has no __dict__");
+		return -1;
+	}
+	if (value != NULL && !PyDict_Check(value)) {
+		PyErr_Format(PyExc_TypeError,
+			     "__dict__ must be set to a dictionary, "
+			     "not a '%.200s'", value->ob_type->tp_name);
+		return -1;
+	}
+	dict = *dictptr;
+	Py_XINCREF(value);
+	*dictptr = value;
+	Py_XDECREF(dict);
+	return 0;
+}
+
+static PyObject *
+subtype_getweakref(PyObject *obj, void *context)
+{
+	PyObject **weaklistptr;
+	PyObject *result;
+
+	if (obj->ob_type->tp_weaklistoffset == 0) {
+		PyErr_SetString(PyExc_AttributeError,
+				"This object has no __weakref__");
+		return NULL;
+	}
+	assert(obj->ob_type->tp_weaklistoffset > 0);
+	assert(obj->ob_type->tp_weaklistoffset + sizeof(PyObject *) <=
+	       (size_t)(obj->ob_type->tp_basicsize));
+	weaklistptr = (PyObject **)
+		((char *)obj + obj->ob_type->tp_weaklistoffset);
+	if (*weaklistptr == NULL)
+		result = Py_None;
+	else
+		result = *weaklistptr;
+	Py_INCREF(result);
+	return result;
+}
+
+/* Three variants on the subtype_getsets list. */
+
+static PyGetSetDef subtype_getsets_full[] = {
+	{"__dict__", subtype_dict, subtype_setdict,
+	 PyDoc_STR("dictionary for instance variables (if defined)")},
+	{"__weakref__", subtype_getweakref, NULL,
+	 PyDoc_STR("list of weak references to the object (if defined)")},
+	{0}
+};
+
+static PyGetSetDef subtype_getsets_dict_only[] = {
+	{"__dict__", subtype_dict, subtype_setdict,
+	 PyDoc_STR("dictionary for instance variables (if defined)")},
+	{0}
+};
+
+static PyGetSetDef subtype_getsets_weakref_only[] = {
+	{"__weakref__", subtype_getweakref, NULL,
+	 PyDoc_STR("list of weak references to the object (if defined)")},
+	{0}
+};
+
+static int
+valid_identifier(PyObject *s)
+{
+	unsigned char *p;
+	Py_ssize_t i, n;
+
+	if (!PyString_Check(s)) {
+		PyErr_Format(PyExc_TypeError,
+			     "__slots__ items must be strings, not '%.200s'",
+			     s->ob_type->tp_name);
+		return 0;
+	}
+	p = (unsigned char *) PyString_AS_STRING(s);
+	n = PyString_GET_SIZE(s);
+	/* We must reject an empty name.  As a hack, we bump the
+	   length to 1 so that the loop will balk on the trailing \0. */
+	if (n == 0)
+		n = 1;
+	for (i = 0; i < n; i++, p++) {
+		if (!(i == 0 ? isalpha(*p) : isalnum(*p)) && *p != '_') {
+			PyErr_SetString(PyExc_TypeError,
+					"__slots__ must be identifiers");
+			return 0;
+		}
+	}
+	return 1;
+}
+
+#ifdef Py_USING_UNICODE
+/* Replace Unicode objects in slots.  */
+
+static PyObject *
+_unicode_to_string(PyObject *slots, Py_ssize_t nslots)
+{
+	PyObject *tmp = NULL;
+	PyObject *slot_name, *new_name;
+	Py_ssize_t i;
+
+	for (i = 0; i < nslots; i++) {
+		if (PyUnicode_Check(slot_name = PyTuple_GET_ITEM(slots, i))) {
+			if (tmp == NULL) {
+				tmp = PySequence_List(slots);
+				if (tmp == NULL)
+					return NULL;
+			}
+			new_name = _PyUnicode_AsDefaultEncodedString(slot_name,
+								     NULL);
+			if (new_name == NULL) {
+				Py_DECREF(tmp);
+				return NULL;
+			}
+			Py_INCREF(new_name);
+			PyList_SET_ITEM(tmp, i, new_name);
+			Py_DECREF(slot_name);
+		}
+	}
+	if (tmp != NULL) {
+		slots = PyList_AsTuple(tmp);
+		Py_DECREF(tmp);
+	}
+	return slots;
+}
+#endif
+
+static PyObject *
+type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
+{
+	PyObject *name, *bases, *dict;
+	static char *kwlist[] = {"name", "bases", "dict", 0};
+	PyObject *slots, *tmp, *newslots;
+	PyTypeObject *type, *base, *tmptype, *winner;
+	PyHeapTypeObject *et;
+	PyMemberDef *mp;
+	Py_ssize_t i, nbases, nslots, slotoffset, add_dict, add_weak;
+	int j, may_add_dict, may_add_weak;
+
+	assert(args != NULL && PyTuple_Check(args));
+	assert(kwds == NULL || PyDict_Check(kwds));
+
+	/* Special case: type(x) should return x->ob_type */
+	{
+		const Py_ssize_t nargs = PyTuple_GET_SIZE(args);
+		const Py_ssize_t nkwds = kwds == NULL ? 0 : PyDict_Size(kwds);
+
+		if (PyType_CheckExact(metatype) && nargs == 1 && nkwds == 0) {
+			PyObject *x = PyTuple_GET_ITEM(args, 0);
+			Py_INCREF(x->ob_type);
+			return (PyObject *) x->ob_type;
+		}
+
+		/* SF bug 475327 -- if that didn't trigger, we need 3
+		   arguments. but PyArg_ParseTupleAndKeywords below may give
+		   a msg saying type() needs exactly 3. */
+		if (nargs + nkwds != 3) {
+			PyErr_SetString(PyExc_TypeError,
+					"type() takes 1 or 3 arguments");
+			return NULL;
+		}
+	}
+
+	/* Check arguments: (name, bases, dict) */
+	if (!PyArg_ParseTupleAndKeywords(args, kwds, "SO!O!:type", kwlist,
+					 &name,
+					 &PyTuple_Type, &bases,
+					 &PyDict_Type, &dict))
+		return NULL;
+
+	/* Determine the proper metatype to deal with this,
+	   and check for metatype conflicts while we're at it.
+	   Note that if some other metatype wins to contract,
+	   it's possible that its instances are not types. */
+	nbases = PyTuple_GET_SIZE(bases);
+	winner = metatype;
+	for (i = 0; i < nbases; i++) {
+		tmp = PyTuple_GET_ITEM(bases, i);
+		tmptype = tmp->ob_type;
+		if (tmptype == &PyClass_Type)
+			continue; /* Special case classic classes */
+		if (PyType_IsSubtype(winner, tmptype))
+			continue;
+		if (PyType_IsSubtype(tmptype, winner)) {
+			winner = tmptype;
+			continue;
+		}
+		PyErr_SetString(PyExc_TypeError,
+				"metaclass conflict: "
+				"the metaclass of a derived class "
+				"must be a (non-strict) subclass "
+				"of the metaclasses of all its bases");
+		return NULL;
+	}
+	if (winner != metatype) {
+		if (winner->tp_new != type_new) /* Pass it to the winner */
+			return winner->tp_new(winner, args, kwds);
+		metatype = winner;
+	}
+
+	/* Adjust for empty tuple bases */
+	if (nbases == 0) {
+		bases = PyTuple_Pack(1, &PyBaseObject_Type);
+		if (bases == NULL)
+			return NULL;
+		nbases = 1;
+	}
+	else
+		Py_INCREF(bases);
+
+	/* XXX From here until type is allocated, "return NULL" leaks bases! */
+
+	/* Calculate best base, and check that all bases are type objects */
+	base = best_base(bases);
+	if (base == NULL) {
+		Py_DECREF(bases);
+		return NULL;
+	}
+	if (!PyType_HasFeature(base, Py_TPFLAGS_BASETYPE)) {
+		PyErr_Format(PyExc_TypeError,
+			     "type '%.100s' is not an acceptable base type",
+			     base->tp_name);
+		Py_DECREF(bases);
+		return NULL;
+	}
+
+	/* Check for a __slots__ sequence variable in dict, and count it */
+	slots = PyDict_GetItemString(dict, "__slots__");
+	nslots = 0;
+	add_dict = 0;
+	add_weak = 0;
+	may_add_dict = base->tp_dictoffset == 0;
+	may_add_weak = base->tp_weaklistoffset == 0 && base->tp_itemsize == 0;
+	if (slots == NULL) {
+		if (may_add_dict) {
+			add_dict++;
+		}
+		if (may_add_weak) {
+			add_weak++;
+		}
+	}
+	else {
+		/* Have slots */
+
+		/* Make it into a tuple */
+		if (PyString_Check(slots))
+			slots = PyTuple_Pack(1, slots);
+		else
+			slots = PySequence_Tuple(slots);
+		if (slots == NULL) {
+			Py_DECREF(bases);
+			return NULL;
+		}
+		assert(PyTuple_Check(slots));
+
+		/* Are slots allowed? */
+		nslots = PyTuple_GET_SIZE(slots);
+		if (nslots > 0 && base->tp_itemsize != 0) {
+			PyErr_Format(PyExc_TypeError,
+				     "nonempty __slots__ "
+				     "not supported for subtype of '%s'",
+				     base->tp_name);
+		  bad_slots:
+			Py_DECREF(bases);
+			Py_DECREF(slots);
+			return NULL;
+		}
+
+#ifdef Py_USING_UNICODE
+		tmp = _unicode_to_string(slots, nslots);
+		if (tmp == NULL)
+			goto bad_slots;
+		if (tmp != slots) {
+			Py_DECREF(slots);
+			slots = tmp;
+		}
+#endif
+		/* Check for valid slot names and two special cases */
+		for (i = 0; i < nslots; i++) {
+			PyObject *tmp = PyTuple_GET_ITEM(slots, i);
+			char *s;
+			if (!valid_identifier(tmp))
+				goto bad_slots;
+			assert(PyString_Check(tmp));
+			s = PyString_AS_STRING(tmp);
+			if (strcmp(s, "__dict__") == 0) {
+				if (!may_add_dict || add_dict) {
+					PyErr_SetString(PyExc_TypeError,
+						"__dict__ slot disallowed: "
+						"we already got one");
+					goto bad_slots;
+				}
+				add_dict++;
+			}
+			if (strcmp(s, "__weakref__") == 0) {
+				if (!may_add_weak || add_weak) {
+					PyErr_SetString(PyExc_TypeError,
+						"__weakref__ slot disallowed: "
+						"either we already got one, "
+						"or __itemsize__ != 0");
+					goto bad_slots;
+				}
+				add_weak++;
+			}
+		}
+
+		/* Copy slots into yet another tuple, demangling names */
+		newslots = PyTuple_New(nslots - add_dict - add_weak);
+		if (newslots == NULL)
+			goto bad_slots;
+		for (i = j = 0; i < nslots; i++) {
+			char *s;
+			tmp = PyTuple_GET_ITEM(slots, i);
+			s = PyString_AS_STRING(tmp);
+			if ((add_dict && strcmp(s, "__dict__") == 0) ||
+			    (add_weak && strcmp(s, "__weakref__") == 0))
+				continue;
+			tmp =_Py_Mangle(name, tmp);
+                        if (!tmp)
+                            goto bad_slots;
+			PyTuple_SET_ITEM(newslots, j, tmp);
+			j++;
+		}
+		assert(j == nslots - add_dict - add_weak);
+		nslots = j;
+		Py_DECREF(slots);
+		slots = newslots;
+
+		/* Secondary bases may provide weakrefs or dict */
+		if (nbases > 1 &&
+		    ((may_add_dict && !add_dict) ||
+		     (may_add_weak && !add_weak))) {
+			for (i = 0; i < nbases; i++) {
+				tmp = PyTuple_GET_ITEM(bases, i);
+				if (tmp == (PyObject *)base)
+					continue; /* Skip primary base */
+				if (PyClass_Check(tmp)) {
+					/* Classic base class provides both */
+					if (may_add_dict && !add_dict)
+						add_dict++;
+					if (may_add_weak && !add_weak)
+						add_weak++;
+					break;
+				}
+				assert(PyType_Check(tmp));
+				tmptype = (PyTypeObject *)tmp;
+				if (may_add_dict && !add_dict &&
+				    tmptype->tp_dictoffset != 0)
+					add_dict++;
+				if (may_add_weak && !add_weak &&
+				    tmptype->tp_weaklistoffset != 0)
+					add_weak++;
+				if (may_add_dict && !add_dict)
+					continue;
+				if (may_add_weak && !add_weak)
+					continue;
+				/* Nothing more to check */
+				break;
+			}
+		}
+	}
+
+	/* XXX From here until type is safely allocated,
+	   "return NULL" may leak slots! */
+
+	/* Allocate the type object */
+	type = (PyTypeObject *)metatype->tp_alloc(metatype, nslots);
+	if (type == NULL) {
+		Py_XDECREF(slots);
+		Py_DECREF(bases);
+		return NULL;
+	}
+
+	/* Keep name and slots alive in the extended type object */
+	et = (PyHeapTypeObject *)type;
+	Py_INCREF(name);
+	et->ht_name = name;
+	et->ht_slots = slots;
+
+	/* Initialize tp_flags */
+	type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE |
+		Py_TPFLAGS_BASETYPE;
+	if (base->tp_flags & Py_TPFLAGS_HAVE_GC)
+		type->tp_flags |= Py_TPFLAGS_HAVE_GC;
+
+	/* It's a new-style number unless it specifically inherits any
+	   old-style numeric behavior */
+	if ((base->tp_flags & Py_TPFLAGS_CHECKTYPES) ||
+	    (base->tp_as_number == NULL))
+		type->tp_flags |= Py_TPFLAGS_CHECKTYPES;
+
+	/* Initialize essential fields */
+	type->tp_as_number = &et->as_number;
+	type->tp_as_sequence = &et->as_sequence;
+	type->tp_as_mapping = &et->as_mapping;
+	type->tp_as_buffer = &et->as_buffer;
+	type->tp_name = PyString_AS_STRING(name);
+
+	/* Set tp_base and tp_bases */
+	type->tp_bases = bases;
+	Py_INCREF(base);
+	type->tp_base = base;
+
+	/* Initialize tp_dict from passed-in dict */
+	type->tp_dict = dict = PyDict_Copy(dict);
+	if (dict == NULL) {
+		Py_DECREF(type);
+		return NULL;
+	}
+
+	/* Set __module__ in the dict */
+	if (PyDict_GetItemString(dict, "__module__") == NULL) {
+		tmp = PyEval_GetGlobals();
+		if (tmp != NULL) {
+			tmp = PyDict_GetItemString(tmp, "__name__");
+			if (tmp != NULL) {
+				if (PyDict_SetItemString(dict, "__module__",
+							 tmp) < 0)
+					return NULL;
+			}
+		}
+	}
+
+	/* Set tp_doc to a copy of dict['__doc__'], if the latter is there
+	   and is a string.  The __doc__ accessor will first look for tp_doc;
+	   if that fails, it will still look into __dict__.
+	*/
+	{
+		PyObject *doc = PyDict_GetItemString(dict, "__doc__");
+		if (doc != NULL && PyString_Check(doc)) {
+			const size_t n = (size_t)PyString_GET_SIZE(doc);
+                        char *tp_doc = (char *)PyObject_MALLOC(n+1);
+			if (tp_doc == NULL) {
+				Py_DECREF(type);
+				return NULL;
+			}
+			memcpy(tp_doc, PyString_AS_STRING(doc), n+1);
+                        type->tp_doc = tp_doc;
+		}
+	}
+
+	/* Special-case __new__: if it's a plain function,
+	   make it a static function */
+	tmp = PyDict_GetItemString(dict, "__new__");
+	if (tmp != NULL && PyFunction_Check(tmp)) {
+		tmp = PyStaticMethod_New(tmp);
+		if (tmp == NULL) {
+			Py_DECREF(type);
+			return NULL;
+		}
+		PyDict_SetItemString(dict, "__new__", tmp);
+		Py_DECREF(tmp);
+	}
+
+	/* Add descriptors for custom slots from __slots__, or for __dict__ */
+	mp = PyHeapType_GET_MEMBERS(et);
+	slotoffset = base->tp_basicsize;
+	if (slots != NULL) {
+		for (i = 0; i < nslots; i++, mp++) {
+			mp->name = PyString_AS_STRING(
+				PyTuple_GET_ITEM(slots, i));
+			mp->type = T_OBJECT_EX;
+			mp->offset = slotoffset;
+
+			/* __dict__ and __weakref__ are already filtered out */
+			assert(strcmp(mp->name, "__dict__") != 0);
+			assert(strcmp(mp->name, "__weakref__") != 0);
+
+			slotoffset += sizeof(PyObject *);
+		}
+	}
+	if (add_dict) {
+		if (base->tp_itemsize)
+			type->tp_dictoffset = -(long)sizeof(PyObject *);
+		else
+			type->tp_dictoffset = slotoffset;
+		slotoffset += sizeof(PyObject *);
+	}
+	if (add_weak) {
+		assert(!base->tp_itemsize);
+		type->tp_weaklistoffset = slotoffset;
+		slotoffset += sizeof(PyObject *);
+	}
+	type->tp_basicsize = slotoffset;
+	type->tp_itemsize = base->tp_itemsize;
+	type->tp_members = PyHeapType_GET_MEMBERS(et);
+
+	if (type->tp_weaklistoffset && type->tp_dictoffset)
+		type->tp_getset = subtype_getsets_full;
+	else if (type->tp_weaklistoffset && !type->tp_dictoffset)
+		type->tp_getset = subtype_getsets_weakref_only;
+	else if (!type->tp_weaklistoffset && type->tp_dictoffset)
+		type->tp_getset = subtype_getsets_dict_only;
+	else
+		type->tp_getset = NULL;
+
+	/* Special case some slots */
+	if (type->tp_dictoffset != 0 || nslots > 0) {
+		if (base->tp_getattr == NULL && base->tp_getattro == NULL)
+			type->tp_getattro = PyObject_GenericGetAttr;
+		if (base->tp_setattr == NULL && base->tp_setattro == NULL)
+			type->tp_setattro = PyObject_GenericSetAttr;
+	}
+	type->tp_dealloc = subtype_dealloc;
+
+	/* Enable GC unless there are really no instance variables possible */
+	if (!(type->tp_basicsize == sizeof(PyObject) &&
+	      type->tp_itemsize == 0))
+		type->tp_flags |= Py_TPFLAGS_HAVE_GC;
+
+	/* Always override allocation strategy to use regular heap */
+	type->tp_alloc = PyType_GenericAlloc;
+	if (type->tp_flags & Py_TPFLAGS_HAVE_GC) {
+		type->tp_free = PyObject_GC_Del;
+		type->tp_traverse = subtype_traverse;
+		type->tp_clear = subtype_clear;
+	}
+	else
+		type->tp_free = PyObject_Del;
+
+	/* Initialize the rest */
+	if (PyType_Ready(type) < 0) {
+		Py_DECREF(type);
+		return NULL;
+	}
+
+	/* Put the proper slots in place */
+	fixup_slot_dispatchers(type);
+
+	return (PyObject *)type;
+}
+
+/* Internal API to look for a name through the MRO.
+   This returns a borrowed reference, and doesn't set an exception! */
+PyObject *
+_PyType_Lookup(PyTypeObject *type, PyObject *name)
+{
+	Py_ssize_t i, n;
+	PyObject *mro, *res, *base, *dict;
+
+	/* Look in tp_dict of types in MRO */
+	mro = type->tp_mro;
+
+	/* If mro is NULL, the type is either not yet initialized
+	   by PyType_Ready(), or already cleared by type_clear().
+	   Either way the safest thing to do is to return NULL. */
+	if (mro == NULL)
+		return NULL;
+
+	assert(PyTuple_Check(mro));
+	n = PyTuple_GET_SIZE(mro);
+	for (i = 0; i < n; i++) {
+		base = PyTuple_GET_ITEM(mro, i);
+		if (PyClass_Check(base))
+			dict = ((PyClassObject *)base)->cl_dict;
+		else {
+			assert(PyType_Check(base));
+			dict = ((PyTypeObject *)base)->tp_dict;
+		}
+		assert(dict && PyDict_Check(dict));
+		res = PyDict_GetItem(dict, name);
+		if (res != NULL)
+			return res;
+	}
+	return NULL;
+}
+
+/* This is similar to PyObject_GenericGetAttr(),
+   but uses _PyType_Lookup() instead of just looking in type->tp_dict. */
+static PyObject *
+type_getattro(PyTypeObject *type, PyObject *name)
+{
+	PyTypeObject *metatype = type->ob_type;
+	PyObject *meta_attribute, *attribute;
+	descrgetfunc meta_get;
+
+	/* Initialize this type (we'll assume the metatype is initialized) */
+	if (type->tp_dict == NULL) {
+		if (PyType_Ready(type) < 0)
+			return NULL;
+	}
+
+	/* No readable descriptor found yet */
+	meta_get = NULL;
+
+	/* Look for the attribute in the metatype */
+	meta_attribute = _PyType_Lookup(metatype, name);
+
+	if (meta_attribute != NULL) {
+		meta_get = meta_attribute->ob_type->tp_descr_get;
+
+		if (meta_get != NULL && PyDescr_IsData(meta_attribute)) {
+			/* Data descriptors implement tp_descr_set to intercept
+			 * writes. Assume the attribute is not overridden in
+			 * type's tp_dict (and bases): call the descriptor now.
+			 */
+			return meta_get(meta_attribute, (PyObject *)type,
+					(PyObject *)metatype);
+		}
+		Py_INCREF(meta_attribute);
+	}
+
+	/* No data descriptor found on metatype. Look in tp_dict of this
+	 * type and its bases */
+	attribute = _PyType_Lookup(type, name);
+	if (attribute != NULL) {
+		/* Implement descriptor functionality, if any */
+		descrgetfunc local_get = attribute->ob_type->tp_descr_get;
+
+		Py_XDECREF(meta_attribute);
+
+		if (local_get != NULL) {
+			/* NULL 2nd argument indicates the descriptor was
+			 * found on the target object itself (or a base)  */
+			return local_get(attribute, (PyObject *)NULL,
+					 (PyObject *)type);
+		}
+
+		Py_INCREF(attribute);
+		return attribute;
+	}
+
+	/* No attribute found in local __dict__ (or bases): use the
+	 * descriptor from the metatype, if any */
+	if (meta_get != NULL) {
+		PyObject *res;
+		res = meta_get(meta_attribute, (PyObject *)type,
+			       (PyObject *)metatype);
+		Py_DECREF(meta_attribute);
+		return res;
+	}
+
+	/* If an ordinary attribute was found on the metatype, return it now */
+	if (meta_attribute != NULL) {
+		return meta_attribute;
+	}
+
+	/* Give up */
+	PyErr_Format(PyExc_AttributeError,
+			 "type object '%.50s' has no attribute '%.400s'",
+			 type->tp_name, PyString_AS_STRING(name));
+	return NULL;
+}
+
+static int
+type_setattro(PyTypeObject *type, PyObject *name, PyObject *value)
+{
+	if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) {
+		PyErr_Format(
+			PyExc_TypeError,
+			"can't set attributes of built-in/extension type '%s'",
+			type->tp_name);
+		return -1;
+	}
+	/* XXX Example of how I expect this to be used...
+	if (update_subclasses(type, name, invalidate_cache, NULL) < 0)
+		return -1;
+	*/
+	if (PyObject_GenericSetAttr((PyObject *)type, name, value) < 0)
+		return -1;
+	return update_slot(type, name);
+}
+
+static void
+type_dealloc(PyTypeObject *type)
+{
+	PyHeapTypeObject *et;
+
+	/* Assert this is a heap-allocated type object */
+	assert(type->tp_flags & Py_TPFLAGS_HEAPTYPE);
+	_PyObject_GC_UNTRACK(type);
+	PyObject_ClearWeakRefs((PyObject *)type);
+	et = (PyHeapTypeObject *)type;
+	Py_XDECREF(type->tp_base);
+	Py_XDECREF(type->tp_dict);
+	Py_XDECREF(type->tp_bases);
+	Py_XDECREF(type->tp_mro);
+	Py_XDECREF(type->tp_cache);
+	Py_XDECREF(type->tp_subclasses);
+        /* A type's tp_doc is heap allocated, unlike the tp_doc slots
+         * of most other objects.  It's okay to cast it to char *.
+         */
+	PyObject_Free((char *)type->tp_doc);
+	Py_XDECREF(et->ht_name);
+	Py_XDECREF(et->ht_slots);
+	type->ob_type->tp_free((PyObject *)type);
+}
+
+static PyObject *
+type_subclasses(PyTypeObject *type, PyObject *args_ignored)
+{
+	PyObject *list, *raw, *ref;
+	Py_ssize_t i, n;
+
+	list = PyList_New(0);
+	if (list == NULL)
+		return NULL;
+	raw = type->tp_subclasses;
+	if (raw == NULL)
+		return list;
+	assert(PyList_Check(raw));
+	n = PyList_GET_SIZE(raw);
+	for (i = 0; i < n; i++) {
+		ref = PyList_GET_ITEM(raw, i);
+		assert(PyWeakref_CheckRef(ref));
+		ref = PyWeakref_GET_OBJECT(ref);
+		if (ref != Py_None) {
+			if (PyList_Append(list, ref) < 0) {
+				Py_DECREF(list);
+				return NULL;
+			}
+		}
+	}
+	return list;
+}
+
+static PyMethodDef type_methods[] = {
+	{"mro", (PyCFunction)mro_external, METH_NOARGS,
+	 PyDoc_STR("mro() -> list\nreturn a type's method resolution order")},
+	{"__subclasses__", (PyCFunction)type_subclasses, METH_NOARGS,
+	 PyDoc_STR("__subclasses__() -> list of immediate subclasses")},
+	{0}
+};
+
+PyDoc_STRVAR(type_doc,
+"type(object) -> the object's type\n"
+"type(name, bases, dict) -> a new type");
+
+static int
+type_traverse(PyTypeObject *type, visitproc visit, void *arg)
+{
+	/* Because of type_is_gc(), the collector only calls this
+	   for heaptypes. */
+	assert(type->tp_flags & Py_TPFLAGS_HEAPTYPE);
+
+	Py_VISIT(type->tp_dict);
+	Py_VISIT(type->tp_cache);
+	Py_VISIT(type->tp_mro);
+	Py_VISIT(type->tp_bases);
+	Py_VISIT(type->tp_base);
+
+	/* There's no need to visit type->tp_subclasses or
+	   ((PyHeapTypeObject *)type)->ht_slots, because they can't be involved
+	   in cycles; tp_subclasses is a list of weak references,
+	   and slots is a tuple of strings. */
+
+	return 0;
+}
+
+static int
+type_clear(PyTypeObject *type)
+{
+	/* Because of type_is_gc(), the collector only calls this
+	   for heaptypes. */
+	assert(type->tp_flags & Py_TPFLAGS_HEAPTYPE);
+
+	/* The only field we need to clear is tp_mro, which is part of a
+	   hard cycle (its first element is the class itself) that won't
+	   be broken otherwise (it's a tuple and tuples don't have a
+	   tp_clear handler).  None of the other fields need to be
+	   cleared, and here's why:
+
+	   tp_dict:
+	       It is a dict, so the collector will call its tp_clear.
+
+	   tp_cache:
+	       Not used; if it were, it would be a dict.
+
+	   tp_bases, tp_base:
+	       If these are involved in a cycle, there must be at least
+	       one other, mutable object in the cycle, e.g. a base
+	       class's dict; the cycle will be broken that way.
+
+	   tp_subclasses:
+	       A list of weak references can't be part of a cycle; and
+	       lists have their own tp_clear.
+
+	   slots (in PyHeapTypeObject):
+	       A tuple of strings can't be part of a cycle.
+	*/
+
+	Py_CLEAR(type->tp_mro);
+
+	return 0;
+}
+
+static int
+type_is_gc(PyTypeObject *type)
+{
+	return type->tp_flags & Py_TPFLAGS_HEAPTYPE;
+}
+
+PyTypeObject PyType_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,					/* ob_size */
+	"type",					/* tp_name */
+	sizeof(PyHeapTypeObject),		/* tp_basicsize */
+	sizeof(PyMemberDef),			/* tp_itemsize */
+	(destructor)type_dealloc,		/* tp_dealloc */
+	0,					/* tp_print */
+	0,			 		/* tp_getattr */
+	0,					/* tp_setattr */
+	type_compare,				/* tp_compare */
+	(reprfunc)type_repr,			/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	(hashfunc)_Py_HashPointer,		/* tp_hash */
+	(ternaryfunc)type_call,			/* tp_call */
+	0,					/* tp_str */
+	(getattrofunc)type_getattro,		/* tp_getattro */
+	(setattrofunc)type_setattro,		/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+		Py_TPFLAGS_BASETYPE,		/* tp_flags */
+	type_doc,				/* tp_doc */
+	(traverseproc)type_traverse,		/* tp_traverse */
+	(inquiry)type_clear,			/* tp_clear */
+	0,					/* tp_richcompare */
+	offsetof(PyTypeObject, tp_weaklist),	/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	type_methods,				/* tp_methods */
+	type_members,				/* tp_members */
+	type_getsets,				/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+	offsetof(PyTypeObject, tp_dict),	/* tp_dictoffset */
+	0,					/* tp_init */
+	0,					/* tp_alloc */
+	type_new,				/* tp_new */
+	PyObject_GC_Del,        		/* tp_free */
+	(inquiry)type_is_gc,			/* tp_is_gc */
+};
+
+
+/* The base type of all types (eventually)... except itself. */
+
+static int
+object_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+	return 0;
+}
+
+/* If we don't have a tp_new for a new-style class, new will use this one.
+   Therefore this should take no arguments/keywords.  However, this new may
+   also be inherited by objects that define a tp_init but no tp_new.  These
+   objects WILL pass argumets to tp_new, because it gets the same args as
+   tp_init.  So only allow arguments if we aren't using the default init, in
+   which case we expect init to handle argument parsing. */
+static PyObject *
+object_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	if (type->tp_init == object_init && (PyTuple_GET_SIZE(args) ||
+	     (kwds && PyDict_Check(kwds) && PyDict_Size(kwds)))) {
+		PyErr_SetString(PyExc_TypeError,
+				"default __new__ takes no parameters");
+		return NULL;
+	}
+	return type->tp_alloc(type, 0);
+}
+
+static void
+object_dealloc(PyObject *self)
+{
+	self->ob_type->tp_free(self);
+}
+
+static PyObject *
+object_repr(PyObject *self)
+{
+	PyTypeObject *type;
+	PyObject *mod, *name, *rtn;
+
+	type = self->ob_type;
+	mod = type_module(type, NULL);
+	if (mod == NULL)
+		PyErr_Clear();
+	else if (!PyString_Check(mod)) {
+		Py_DECREF(mod);
+		mod = NULL;
+	}
+	name = type_name(type, NULL);
+	if (name == NULL)
+		return NULL;
+	if (mod != NULL && strcmp(PyString_AS_STRING(mod), "__builtin__"))
+		rtn = PyString_FromFormat("<%s.%s object at %p>",
+					  PyString_AS_STRING(mod),
+					  PyString_AS_STRING(name),
+					  self);
+	else
+		rtn = PyString_FromFormat("<%s object at %p>",
+					  type->tp_name, self);
+	Py_XDECREF(mod);
+	Py_DECREF(name);
+	return rtn;
+}
+
+static PyObject *
+object_str(PyObject *self)
+{
+	unaryfunc f;
+
+	f = self->ob_type->tp_repr;
+	if (f == NULL)
+		f = object_repr;
+	return f(self);
+}
+
+static long
+object_hash(PyObject *self)
+{
+	return _Py_HashPointer(self);
+}
+
+static PyObject *
+object_get_class(PyObject *self, void *closure)
+{
+	Py_INCREF(self->ob_type);
+	return (PyObject *)(self->ob_type);
+}
+
+static int
+equiv_structs(PyTypeObject *a, PyTypeObject *b)
+{
+	return a == b ||
+	       (a != NULL &&
+		b != NULL &&
+		a->tp_basicsize == b->tp_basicsize &&
+		a->tp_itemsize == b->tp_itemsize &&
+		a->tp_dictoffset == b->tp_dictoffset &&
+		a->tp_weaklistoffset == b->tp_weaklistoffset &&
+		((a->tp_flags & Py_TPFLAGS_HAVE_GC) ==
+		 (b->tp_flags & Py_TPFLAGS_HAVE_GC)));
+}
+
+static int
+same_slots_added(PyTypeObject *a, PyTypeObject *b)
+{
+	PyTypeObject *base = a->tp_base;
+	Py_ssize_t size;
+
+	if (base != b->tp_base)
+		return 0;
+	if (equiv_structs(a, base) && equiv_structs(b, base))
+		return 1;
+	size = base->tp_basicsize;
+	if (a->tp_dictoffset == size && b->tp_dictoffset == size)
+		size += sizeof(PyObject *);
+	if (a->tp_weaklistoffset == size && b->tp_weaklistoffset == size)
+		size += sizeof(PyObject *);
+	return size == a->tp_basicsize && size == b->tp_basicsize;
+}
+
+static int
+compatible_for_assignment(PyTypeObject* oldto, PyTypeObject* newto, char* attr)
+{
+	PyTypeObject *newbase, *oldbase;
+
+	if (newto->tp_dealloc != oldto->tp_dealloc ||
+	    newto->tp_free != oldto->tp_free)
+	{
+		PyErr_Format(PyExc_TypeError,
+			     "%s assignment: "
+			     "'%s' deallocator differs from '%s'",
+			     attr,
+			     newto->tp_name,
+			     oldto->tp_name);
+		return 0;
+	}
+	newbase = newto;
+	oldbase = oldto;
+	while (equiv_structs(newbase, newbase->tp_base))
+		newbase = newbase->tp_base;
+	while (equiv_structs(oldbase, oldbase->tp_base))
+		oldbase = oldbase->tp_base;
+	if (newbase != oldbase &&
+	    (newbase->tp_base != oldbase->tp_base ||
+	     !same_slots_added(newbase, oldbase))) {
+		PyErr_Format(PyExc_TypeError,
+			     "%s assignment: "
+			     "'%s' object layout differs from '%s'",
+			     attr,
+			     newto->tp_name,
+			     oldto->tp_name);
+		return 0;
+	}
+
+	return 1;
+}
+
+static int
+object_set_class(PyObject *self, PyObject *value, void *closure)
+{
+	PyTypeObject *oldto = self->ob_type;
+	PyTypeObject *newto;
+
+	if (value == NULL) {
+		PyErr_SetString(PyExc_TypeError,
+				"can't delete __class__ attribute");
+		return -1;
+	}
+	if (!PyType_Check(value)) {
+		PyErr_Format(PyExc_TypeError,
+		  "__class__ must be set to new-style class, not '%s' object",
+		  value->ob_type->tp_name);
+		return -1;
+	}
+	newto = (PyTypeObject *)value;
+	if (!(newto->tp_flags & Py_TPFLAGS_HEAPTYPE) ||
+	    !(oldto->tp_flags & Py_TPFLAGS_HEAPTYPE))
+	{
+		PyErr_Format(PyExc_TypeError,
+			     "__class__ assignment: only for heap types");
+		return -1;
+	}
+	if (compatible_for_assignment(newto, oldto, "__class__")) {
+		Py_INCREF(newto);
+		self->ob_type = newto;
+		Py_DECREF(oldto);
+		return 0;
+	}
+	else {
+		return -1;
+	}
+}
+
+static PyGetSetDef object_getsets[] = {
+	{"__class__", object_get_class, object_set_class,
+	 PyDoc_STR("the object's class")},
+	{0}
+};
+
+
+/* Stuff to implement __reduce_ex__ for pickle protocols >= 2.
+   We fall back to helpers in copy_reg for:
+   - pickle protocols < 2
+   - calculating the list of slot names (done only once per class)
+   - the __newobj__ function (which is used as a token but never called)
+*/
+
+static PyObject *
+import_copy_reg(void)
+{
+	static PyObject *copy_reg_str;
+
+	if (!copy_reg_str) {
+		copy_reg_str = PyString_InternFromString("copy_reg");
+		if (copy_reg_str == NULL)
+			return NULL;
+	}
+
+	return PyImport_Import(copy_reg_str);
+}
+
+static PyObject *
+slotnames(PyObject *cls)
+{
+	PyObject *clsdict;
+	PyObject *copy_reg;
+	PyObject *slotnames;
+
+	if (!PyType_Check(cls)) {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+
+	clsdict = ((PyTypeObject *)cls)->tp_dict;
+	slotnames = PyDict_GetItemString(clsdict, "__slotnames__");
+	if (slotnames != NULL && PyList_Check(slotnames)) {
+		Py_INCREF(slotnames);
+		return slotnames;
+	}
+
+	copy_reg = import_copy_reg();
+	if (copy_reg == NULL)
+		return NULL;
+
+	slotnames = PyObject_CallMethod(copy_reg, "_slotnames", "O", cls);
+	Py_DECREF(copy_reg);
+	if (slotnames != NULL &&
+	    slotnames != Py_None &&
+	    !PyList_Check(slotnames))
+	{
+		PyErr_SetString(PyExc_TypeError,
+			"copy_reg._slotnames didn't return a list or None");
+		Py_DECREF(slotnames);
+		slotnames = NULL;
+	}
+
+	return slotnames;
+}
+
+static PyObject *
+reduce_2(PyObject *obj)
+{
+	PyObject *cls, *getnewargs;
+	PyObject *args = NULL, *args2 = NULL;
+	PyObject *getstate = NULL, *state = NULL, *names = NULL;
+	PyObject *slots = NULL, *listitems = NULL, *dictitems = NULL;
+	PyObject *copy_reg = NULL, *newobj = NULL, *res = NULL;
+	Py_ssize_t i, n;
+
+	cls = PyObject_GetAttrString(obj, "__class__");
+	if (cls == NULL)
+		return NULL;
+
+	getnewargs = PyObject_GetAttrString(obj, "__getnewargs__");
+	if (getnewargs != NULL) {
+		args = PyObject_CallObject(getnewargs, NULL);
+		Py_DECREF(getnewargs);
+		if (args != NULL && !PyTuple_Check(args)) {
+			PyErr_Format(PyExc_TypeError,
+				"__getnewargs__ should return a tuple, "
+				"not '%.200s'", args->ob_type->tp_name);
+			goto end;
+		}
+	}
+	else {
+		PyErr_Clear();
+		args = PyTuple_New(0);
+	}
+	if (args == NULL)
+		goto end;
+
+	getstate = PyObject_GetAttrString(obj, "__getstate__");
+	if (getstate != NULL) {
+		state = PyObject_CallObject(getstate, NULL);
+		Py_DECREF(getstate);
+		if (state == NULL)
+			goto end;
+	}
+	else {
+		PyErr_Clear();
+		state = PyObject_GetAttrString(obj, "__dict__");
+		if (state == NULL) {
+			PyErr_Clear();
+			state = Py_None;
+			Py_INCREF(state);
+		}
+		names = slotnames(cls);
+		if (names == NULL)
+			goto end;
+		if (names != Py_None) {
+			assert(PyList_Check(names));
+			slots = PyDict_New();
+			if (slots == NULL)
+				goto end;
+			n = 0;
+			/* Can't pre-compute the list size; the list
+			   is stored on the class so accessible to other
+			   threads, which may be run by DECREF */
+			for (i = 0; i < PyList_GET_SIZE(names); i++) {
+				PyObject *name, *value;
+				name = PyList_GET_ITEM(names, i);
+				value = PyObject_GetAttr(obj, name);
+				if (value == NULL)
+					PyErr_Clear();
+				else {
+					int err = PyDict_SetItem(slots, name,
+								 value);
+					Py_DECREF(value);
+					if (err)
+						goto end;
+					n++;
+				}
+			}
+			if (n) {
+				state = Py_BuildValue("(NO)", state, slots);
+				if (state == NULL)
+					goto end;
+			}
+		}
+	}
+
+	if (!PyList_Check(obj)) {
+		listitems = Py_None;
+		Py_INCREF(listitems);
+	}
+	else {
+		listitems = PyObject_GetIter(obj);
+		if (listitems == NULL)
+			goto end;
+	}
+
+	if (!PyDict_Check(obj)) {
+		dictitems = Py_None;
+		Py_INCREF(dictitems);
+	}
+	else {
+		dictitems = PyObject_CallMethod(obj, "iteritems", "");
+		if (dictitems == NULL)
+			goto end;
+	}
+
+	copy_reg = import_copy_reg();
+	if (copy_reg == NULL)
+		goto end;
+	newobj = PyObject_GetAttrString(copy_reg, "__newobj__");
+	if (newobj == NULL)
+		goto end;
+
+	n = PyTuple_GET_SIZE(args);
+	args2 = PyTuple_New(n+1);
+	if (args2 == NULL)
+		goto end;
+	PyTuple_SET_ITEM(args2, 0, cls);
+	cls = NULL;
+	for (i = 0; i < n; i++) {
+		PyObject *v = PyTuple_GET_ITEM(args, i);
+		Py_INCREF(v);
+		PyTuple_SET_ITEM(args2, i+1, v);
+	}
+
+	res = PyTuple_Pack(5, newobj, args2, state, listitems, dictitems);
+
+  end:
+	Py_XDECREF(cls);
+	Py_XDECREF(args);
+	Py_XDECREF(args2);
+	Py_XDECREF(slots);
+	Py_XDECREF(state);
+	Py_XDECREF(names);
+	Py_XDECREF(listitems);
+	Py_XDECREF(dictitems);
+	Py_XDECREF(copy_reg);
+	Py_XDECREF(newobj);
+	return res;
+}
+
+/*
+ * There were two problems when object.__reduce__ and object.__reduce_ex__
+ * were implemented in the same function:
+ *  - trying to pickle an object with a custom __reduce__ method that
+ *    fell back to object.__reduce__ in certain circumstances led to
+ *    infinite recursion at Python level and eventual RuntimeError.
+ *  - Pickling objects that lied about their type by overwriting the
+ *    __class__ descriptor could lead to infinite recursion at C level
+ *    and eventual segfault.
+ *
+ * Because of backwards compatibility, the two methods still have to
+ * behave in the same way, even if this is not required by the pickle
+ * protocol. This common functionality was moved to the _common_reduce
+ * function.
+ */
+static PyObject *
+_common_reduce(PyObject *self, int proto)
+{
+	PyObject *copy_reg, *res;
+
+	if (proto >= 2)
+		return reduce_2(self);
+
+	copy_reg = import_copy_reg();
+	if (!copy_reg)
+		return NULL;
+
+	res = PyEval_CallMethod(copy_reg, "_reduce_ex", "(Oi)", self, proto);
+	Py_DECREF(copy_reg);
+
+	return res;
+}
+
+static PyObject *
+object_reduce(PyObject *self, PyObject *args)
+{
+	int proto = 0;
+
+	if (!PyArg_ParseTuple(args, "|i:__reduce__", &proto))
+		return NULL;
+
+	return _common_reduce(self, proto);
+}
+
+static PyObject *
+object_reduce_ex(PyObject *self, PyObject *args)
+{
+	PyObject *reduce, *res;
+	int proto = 0;
+
+	if (!PyArg_ParseTuple(args, "|i:__reduce_ex__", &proto))
+		return NULL;
+
+	reduce = PyObject_GetAttrString(self, "__reduce__");
+	if (reduce == NULL)
+		PyErr_Clear();
+	else {
+		PyObject *cls, *clsreduce, *objreduce;
+		int override;
+		cls = PyObject_GetAttrString(self, "__class__");
+		if (cls == NULL) {
+			Py_DECREF(reduce);
+			return NULL;
+		}
+		clsreduce = PyObject_GetAttrString(cls, "__reduce__");
+		Py_DECREF(cls);
+		if (clsreduce == NULL) {
+			Py_DECREF(reduce);
+			return NULL;
+		}
+		objreduce = PyDict_GetItemString(PyBaseObject_Type.tp_dict,
+						 "__reduce__");
+		override = (clsreduce != objreduce);
+		Py_DECREF(clsreduce);
+		if (override) {
+			res = PyObject_CallObject(reduce, NULL);
+			Py_DECREF(reduce);
+			return res;
+		}
+		else
+			Py_DECREF(reduce);
+	}
+
+	return _common_reduce(self, proto);
+}
+
+static PyMethodDef object_methods[] = {
+	{"__reduce_ex__", object_reduce_ex, METH_VARARGS,
+	 PyDoc_STR("helper for pickle")},
+	{"__reduce__", object_reduce, METH_VARARGS,
+	 PyDoc_STR("helper for pickle")},
+	{0}
+};
+
+
+PyTypeObject PyBaseObject_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+ 	0,					/* ob_size */
+	"object",				/* tp_name */
+	sizeof(PyObject),			/* tp_basicsize */
+	0,					/* tp_itemsize */
+	object_dealloc,				/* tp_dealloc */
+	0,					/* tp_print */
+	0,			 		/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	object_repr,				/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	object_hash,				/* tp_hash */
+	0,					/* tp_call */
+	object_str,				/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	PyObject_GenericSetAttr,		/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+	PyDoc_STR("The most base type"),	/* tp_doc */
+	0,					/* tp_traverse */
+	0,					/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	object_methods,				/* tp_methods */
+	0,					/* tp_members */
+	object_getsets,				/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	object_init,				/* tp_init */
+	PyType_GenericAlloc,			/* tp_alloc */
+	object_new,				/* tp_new */
+	PyObject_Del,           		/* tp_free */
+};
+
+
+/* Initialize the __dict__ in a type object */
+
+static int
+add_methods(PyTypeObject *type, PyMethodDef *meth)
+{
+	PyObject *dict = type->tp_dict;
+
+	for (; meth->ml_name != NULL; meth++) {
+		PyObject *descr;
+		if (PyDict_GetItemString(dict, meth->ml_name) &&
+			!(meth->ml_flags & METH_COEXIST))
+				continue;
+		if (meth->ml_flags & METH_CLASS) {
+			if (meth->ml_flags & METH_STATIC) {
+				PyErr_SetString(PyExc_ValueError,
+				     "method cannot be both class and static");
+				return -1;
+			}
+			descr = PyDescr_NewClassMethod(type, meth);
+		}
+		else if (meth->ml_flags & METH_STATIC) {
+			PyObject *cfunc = PyCFunction_New(meth, NULL);
+			if (cfunc == NULL)
+				return -1;
+			descr = PyStaticMethod_New(cfunc);
+			Py_DECREF(cfunc);
+		}
+		else {
+			descr = PyDescr_NewMethod(type, meth);
+		}
+		if (descr == NULL)
+			return -1;
+		if (PyDict_SetItemString(dict, meth->ml_name, descr) < 0)
+			return -1;
+		Py_DECREF(descr);
+	}
+	return 0;
+}
+
+static int
+add_members(PyTypeObject *type, PyMemberDef *memb)
+{
+	PyObject *dict = type->tp_dict;
+
+	for (; memb->name != NULL; memb++) {
+		PyObject *descr;
+		if (PyDict_GetItemString(dict, memb->name))
+			continue;
+		descr = PyDescr_NewMember(type, memb);
+		if (descr == NULL)
+			return -1;
+		if (PyDict_SetItemString(dict, memb->name, descr) < 0)
+			return -1;
+		Py_DECREF(descr);
+	}
+	return 0;
+}
+
+static int
+add_getset(PyTypeObject *type, PyGetSetDef *gsp)
+{
+	PyObject *dict = type->tp_dict;
+
+	for (; gsp->name != NULL; gsp++) {
+		PyObject *descr;
+		if (PyDict_GetItemString(dict, gsp->name))
+			continue;
+		descr = PyDescr_NewGetSet(type, gsp);
+
+		if (descr == NULL)
+			return -1;
+		if (PyDict_SetItemString(dict, gsp->name, descr) < 0)
+			return -1;
+		Py_DECREF(descr);
+	}
+	return 0;
+}
+
+static void
+inherit_special(PyTypeObject *type, PyTypeObject *base)
+{
+	Py_ssize_t oldsize, newsize;
+
+	/* Special flag magic */
+	if (!type->tp_as_buffer && base->tp_as_buffer) {
+		type->tp_flags &= ~Py_TPFLAGS_HAVE_GETCHARBUFFER;
+		type->tp_flags |=
+			base->tp_flags & Py_TPFLAGS_HAVE_GETCHARBUFFER;
+	}
+	if (!type->tp_as_sequence && base->tp_as_sequence) {
+		type->tp_flags &= ~Py_TPFLAGS_HAVE_SEQUENCE_IN;
+		type->tp_flags |= base->tp_flags & Py_TPFLAGS_HAVE_SEQUENCE_IN;
+	}
+	if ((type->tp_flags & Py_TPFLAGS_HAVE_INPLACEOPS) !=
+	    (base->tp_flags & Py_TPFLAGS_HAVE_INPLACEOPS)) {
+		if ((!type->tp_as_number && base->tp_as_number) ||
+		    (!type->tp_as_sequence && base->tp_as_sequence)) {
+			type->tp_flags &= ~Py_TPFLAGS_HAVE_INPLACEOPS;
+			if (!type->tp_as_number && !type->tp_as_sequence) {
+				type->tp_flags |= base->tp_flags &
+					Py_TPFLAGS_HAVE_INPLACEOPS;
+			}
+		}
+		/* Wow */
+	}
+	if (!type->tp_as_number && base->tp_as_number) {
+		type->tp_flags &= ~Py_TPFLAGS_CHECKTYPES;
+		type->tp_flags |= base->tp_flags & Py_TPFLAGS_CHECKTYPES;
+	}
+
+	/* Copying basicsize is connected to the GC flags */
+	oldsize = base->tp_basicsize;
+	newsize = type->tp_basicsize ? type->tp_basicsize : oldsize;
+	if (!(type->tp_flags & Py_TPFLAGS_HAVE_GC) &&
+	    (base->tp_flags & Py_TPFLAGS_HAVE_GC) &&
+	    (type->tp_flags & Py_TPFLAGS_HAVE_RICHCOMPARE/*GC slots exist*/) &&
+	    (!type->tp_traverse && !type->tp_clear)) {
+		type->tp_flags |= Py_TPFLAGS_HAVE_GC;
+		if (type->tp_traverse == NULL)
+			type->tp_traverse = base->tp_traverse;
+		if (type->tp_clear == NULL)
+			type->tp_clear = base->tp_clear;
+	}
+	if (type->tp_flags & base->tp_flags & Py_TPFLAGS_HAVE_CLASS) {
+		/* The condition below could use some explanation.
+		   It appears that tp_new is not inherited for static types
+		   whose base class is 'object'; this seems to be a precaution
+		   so that old extension types don't suddenly become
+		   callable (object.__new__ wouldn't insure the invariants
+		   that the extension type's own factory function ensures).
+		   Heap types, of course, are under our control, so they do
+		   inherit tp_new; static extension types that specify some
+		   other built-in type as the default are considered
+		   new-style-aware so they also inherit object.__new__. */
+		if (base != &PyBaseObject_Type ||
+		    (type->tp_flags & Py_TPFLAGS_HEAPTYPE)) {
+			if (type->tp_new == NULL)
+				type->tp_new = base->tp_new;
+		}
+	}
+	type->tp_basicsize = newsize;
+
+	/* Copy other non-function slots */
+
+#undef COPYVAL
+#define COPYVAL(SLOT) \
+	if (type->SLOT == 0) type->SLOT = base->SLOT
+
+	COPYVAL(tp_itemsize);
+	if (type->tp_flags & base->tp_flags & Py_TPFLAGS_HAVE_WEAKREFS) {
+		COPYVAL(tp_weaklistoffset);
+	}
+	if (type->tp_flags & base->tp_flags & Py_TPFLAGS_HAVE_CLASS) {
+		COPYVAL(tp_dictoffset);
+	}
+}
+
+static void
+inherit_slots(PyTypeObject *type, PyTypeObject *base)
+{
+	PyTypeObject *basebase;
+
+#undef SLOTDEFINED
+#undef COPYSLOT
+#undef COPYNUM
+#undef COPYSEQ
+#undef COPYMAP
+#undef COPYBUF
+
+#define SLOTDEFINED(SLOT) \
+	(base->SLOT != 0 && \
+	 (basebase == NULL || base->SLOT != basebase->SLOT))
+
+#define COPYSLOT(SLOT) \
+	if (!type->SLOT && SLOTDEFINED(SLOT)) type->SLOT = base->SLOT
+
+#define COPYNUM(SLOT) COPYSLOT(tp_as_number->SLOT)
+#define COPYSEQ(SLOT) COPYSLOT(tp_as_sequence->SLOT)
+#define COPYMAP(SLOT) COPYSLOT(tp_as_mapping->SLOT)
+#define COPYBUF(SLOT) COPYSLOT(tp_as_buffer->SLOT)
+
+	/* This won't inherit indirect slots (from tp_as_number etc.)
+	   if type doesn't provide the space. */
+
+	if (type->tp_as_number != NULL && base->tp_as_number != NULL) {
+		basebase = base->tp_base;
+		if (basebase->tp_as_number == NULL)
+			basebase = NULL;
+		COPYNUM(nb_add);
+		COPYNUM(nb_subtract);
+		COPYNUM(nb_multiply);
+		COPYNUM(nb_divide);
+		COPYNUM(nb_remainder);
+		COPYNUM(nb_divmod);
+		COPYNUM(nb_power);
+		COPYNUM(nb_negative);
+		COPYNUM(nb_positive);
+		COPYNUM(nb_absolute);
+		COPYNUM(nb_nonzero);
+		COPYNUM(nb_invert);
+		COPYNUM(nb_lshift);
+		COPYNUM(nb_rshift);
+		COPYNUM(nb_and);
+		COPYNUM(nb_xor);
+		COPYNUM(nb_or);
+		COPYNUM(nb_coerce);
+		COPYNUM(nb_int);
+		COPYNUM(nb_long);
+		COPYNUM(nb_float);
+		COPYNUM(nb_oct);
+		COPYNUM(nb_hex);
+		COPYNUM(nb_inplace_add);
+		COPYNUM(nb_inplace_subtract);
+		COPYNUM(nb_inplace_multiply);
+		COPYNUM(nb_inplace_divide);
+		COPYNUM(nb_inplace_remainder);
+		COPYNUM(nb_inplace_power);
+		COPYNUM(nb_inplace_lshift);
+		COPYNUM(nb_inplace_rshift);
+		COPYNUM(nb_inplace_and);
+		COPYNUM(nb_inplace_xor);
+		COPYNUM(nb_inplace_or);
+		if (base->tp_flags & Py_TPFLAGS_CHECKTYPES) {
+			COPYNUM(nb_true_divide);
+			COPYNUM(nb_floor_divide);
+			COPYNUM(nb_inplace_true_divide);
+			COPYNUM(nb_inplace_floor_divide);
+		}
+		if (base->tp_flags & Py_TPFLAGS_HAVE_INDEX) {
+			COPYNUM(nb_index);
+		}
+	}
+
+	if (type->tp_as_sequence != NULL && base->tp_as_sequence != NULL) {
+		basebase = base->tp_base;
+		if (basebase->tp_as_sequence == NULL)
+			basebase = NULL;
+		COPYSEQ(sq_length);
+		COPYSEQ(sq_concat);
+		COPYSEQ(sq_repeat);
+		COPYSEQ(sq_item);
+		COPYSEQ(sq_slice);
+		COPYSEQ(sq_ass_item);
+		COPYSEQ(sq_ass_slice);
+		COPYSEQ(sq_contains);
+		COPYSEQ(sq_inplace_concat);
+		COPYSEQ(sq_inplace_repeat);
+	}
+
+	if (type->tp_as_mapping != NULL && base->tp_as_mapping != NULL) {
+		basebase = base->tp_base;
+		if (basebase->tp_as_mapping == NULL)
+			basebase = NULL;
+		COPYMAP(mp_length);
+		COPYMAP(mp_subscript);
+		COPYMAP(mp_ass_subscript);
+	}
+
+	if (type->tp_as_buffer != NULL && base->tp_as_buffer != NULL) {
+		basebase = base->tp_base;
+		if (basebase->tp_as_buffer == NULL)
+			basebase = NULL;
+		COPYBUF(bf_getreadbuffer);
+		COPYBUF(bf_getwritebuffer);
+		COPYBUF(bf_getsegcount);
+		COPYBUF(bf_getcharbuffer);
+	}
+
+	basebase = base->tp_base;
+
+	COPYSLOT(tp_dealloc);
+	COPYSLOT(tp_print);
+	if (type->tp_getattr == NULL && type->tp_getattro == NULL) {
+		type->tp_getattr = base->tp_getattr;
+		type->tp_getattro = base->tp_getattro;
+	}
+	if (type->tp_setattr == NULL && type->tp_setattro == NULL) {
+		type->tp_setattr = base->tp_setattr;
+		type->tp_setattro = base->tp_setattro;
+	}
+	/* tp_compare see tp_richcompare */
+	COPYSLOT(tp_repr);
+	/* tp_hash see tp_richcompare */
+	COPYSLOT(tp_call);
+	COPYSLOT(tp_str);
+	if (type->tp_flags & base->tp_flags & Py_TPFLAGS_HAVE_RICHCOMPARE) {
+		if (type->tp_compare == NULL &&
+		    type->tp_richcompare == NULL &&
+		    type->tp_hash == NULL)
+		{
+			type->tp_compare = base->tp_compare;
+			type->tp_richcompare = base->tp_richcompare;
+			type->tp_hash = base->tp_hash;
+		}
+	}
+	else {
+		COPYSLOT(tp_compare);
+	}
+	if (type->tp_flags & base->tp_flags & Py_TPFLAGS_HAVE_ITER) {
+		COPYSLOT(tp_iter);
+		COPYSLOT(tp_iternext);
+	}
+	if (type->tp_flags & base->tp_flags & Py_TPFLAGS_HAVE_CLASS) {
+		COPYSLOT(tp_descr_get);
+		COPYSLOT(tp_descr_set);
+		COPYSLOT(tp_dictoffset);
+		COPYSLOT(tp_init);
+		COPYSLOT(tp_alloc);
+		COPYSLOT(tp_is_gc);
+		if ((type->tp_flags & Py_TPFLAGS_HAVE_GC) ==
+		    (base->tp_flags & Py_TPFLAGS_HAVE_GC)) {
+			/* They agree about gc. */
+			COPYSLOT(tp_free);
+		}
+		else if ((type->tp_flags & Py_TPFLAGS_HAVE_GC) &&
+			 type->tp_free == NULL &&
+			 base->tp_free == _PyObject_Del) {
+			/* A bit of magic to plug in the correct default
+			 * tp_free function when a derived class adds gc,
+			 * didn't define tp_free, and the base uses the
+			 * default non-gc tp_free.
+			 */
+			type->tp_free = PyObject_GC_Del;
+		}
+		/* else they didn't agree about gc, and there isn't something
+		 * obvious to be done -- the type is on its own.
+		 */
+	}
+}
+
+static int add_operators(PyTypeObject *);
+
+int
+PyType_Ready(PyTypeObject *type)
+{
+	PyObject *dict, *bases;
+	PyTypeObject *base;
+	Py_ssize_t i, n;
+
+	if (type->tp_flags & Py_TPFLAGS_READY) {
+		assert(type->tp_dict != NULL);
+		return 0;
+	}
+	assert((type->tp_flags & Py_TPFLAGS_READYING) == 0);
+
+	type->tp_flags |= Py_TPFLAGS_READYING;
+
+#ifdef Py_TRACE_REFS
+	/* PyType_Ready is the closest thing we have to a choke point
+	 * for type objects, so is the best place I can think of to try
+	 * to get type objects into the doubly-linked list of all objects.
+	 * Still, not all type objects go thru PyType_Ready.
+	 */
+	_Py_AddToAllObjects((PyObject *)type, 0);
+#endif
+
+	/* Initialize tp_base (defaults to BaseObject unless that's us) */
+	base = type->tp_base;
+	if (base == NULL && type != &PyBaseObject_Type) {
+		base = type->tp_base = &PyBaseObject_Type;
+		Py_INCREF(base);
+	}
+
+        /* Now the only way base can still be NULL is if type is
+         * &PyBaseObject_Type.
+         */
+
+	/* Initialize the base class */
+	if (base && base->tp_dict == NULL) {
+		if (PyType_Ready(base) < 0)
+			goto error;
+	}
+
+	/* Initialize ob_type if NULL.  This means extensions that want to be
+	   compilable separately on Windows can call PyType_Ready() instead of
+	   initializing the ob_type field of their type objects. */
+        /* The test for base != NULL is really unnecessary, since base is only
+           NULL when type is &PyBaseObject_Type, and we know its ob_type is
+           not NULL (it's initialized to &PyType_Type).  But coverity doesn't
+           know that. */
+	if (type->ob_type == NULL && base != NULL)
+		type->ob_type = base->ob_type;
+
+	/* Initialize tp_bases */
+	bases = type->tp_bases;
+	if (bases == NULL) {
+		if (base == NULL)
+			bases = PyTuple_New(0);
+		else
+			bases = PyTuple_Pack(1, base);
+		if (bases == NULL)
+			goto error;
+		type->tp_bases = bases;
+	}
+
+	/* Initialize tp_dict */
+	dict = type->tp_dict;
+	if (dict == NULL) {
+		dict = PyDict_New();
+		if (dict == NULL)
+			goto error;
+		type->tp_dict = dict;
+	}
+
+	/* Add type-specific descriptors to tp_dict */
+	if (add_operators(type) < 0)
+		goto error;
+	if (type->tp_methods != NULL) {
+		if (add_methods(type, type->tp_methods) < 0)
+			goto error;
+	}
+	if (type->tp_members != NULL) {
+		if (add_members(type, type->tp_members) < 0)
+			goto error;
+	}
+	if (type->tp_getset != NULL) {
+		if (add_getset(type, type->tp_getset) < 0)
+			goto error;
+	}
+
+	/* Calculate method resolution order */
+	if (mro_internal(type) < 0) {
+		goto error;
+	}
+
+	/* Inherit special flags from dominant base */
+	if (type->tp_base != NULL)
+		inherit_special(type, type->tp_base);
+
+	/* Initialize tp_dict properly */
+	bases = type->tp_mro;
+	assert(bases != NULL);
+	assert(PyTuple_Check(bases));
+	n = PyTuple_GET_SIZE(bases);
+	for (i = 1; i < n; i++) {
+		PyObject *b = PyTuple_GET_ITEM(bases, i);
+		if (PyType_Check(b))
+			inherit_slots(type, (PyTypeObject *)b);
+	}
+
+	/* Sanity check for tp_free. */
+	if (PyType_IS_GC(type) && (type->tp_flags & Py_TPFLAGS_BASETYPE) &&
+	    (type->tp_free == NULL || type->tp_free == PyObject_Del)) {
+	    	/* This base class needs to call tp_free, but doesn't have
+	    	 * one, or its tp_free is for non-gc'ed objects.
+	    	 */
+		PyErr_Format(PyExc_TypeError, "type '%.100s' participates in "
+			     "gc and is a base type but has inappropriate "
+			     "tp_free slot",
+			     type->tp_name);
+		goto error;
+	}
+
+	/* if the type dictionary doesn't contain a __doc__, set it from
+	   the tp_doc slot.
+	 */
+	if (PyDict_GetItemString(type->tp_dict, "__doc__") == NULL) {
+		if (type->tp_doc != NULL) {
+			PyObject *doc = PyString_FromString(type->tp_doc);
+			if (doc == NULL)
+				goto error;
+			PyDict_SetItemString(type->tp_dict, "__doc__", doc);
+			Py_DECREF(doc);
+		} else {
+			PyDict_SetItemString(type->tp_dict,
+					     "__doc__", Py_None);
+		}
+	}
+
+	/* Some more special stuff */
+	base = type->tp_base;
+	if (base != NULL) {
+		if (type->tp_as_number == NULL)
+			type->tp_as_number = base->tp_as_number;
+		if (type->tp_as_sequence == NULL)
+			type->tp_as_sequence = base->tp_as_sequence;
+		if (type->tp_as_mapping == NULL)
+			type->tp_as_mapping = base->tp_as_mapping;
+		if (type->tp_as_buffer == NULL)
+			type->tp_as_buffer = base->tp_as_buffer;
+	}
+
+	/* Link into each base class's list of subclasses */
+	bases = type->tp_bases;
+	n = PyTuple_GET_SIZE(bases);
+	for (i = 0; i < n; i++) {
+		PyObject *b = PyTuple_GET_ITEM(bases, i);
+		if (PyType_Check(b) &&
+		    add_subclass((PyTypeObject *)b, type) < 0)
+			goto error;
+	}
+
+	/* All done -- set the ready flag */
+	assert(type->tp_dict != NULL);
+	type->tp_flags =
+		(type->tp_flags & ~Py_TPFLAGS_READYING) | Py_TPFLAGS_READY;
+	return 0;
+
+  error:
+	type->tp_flags &= ~Py_TPFLAGS_READYING;
+	return -1;
+}
+
+static int
+add_subclass(PyTypeObject *base, PyTypeObject *type)
+{
+	Py_ssize_t i;
+	int result;
+	PyObject *list, *ref, *newobj;
+
+	list = base->tp_subclasses;
+	if (list == NULL) {
+		base->tp_subclasses = list = PyList_New(0);
+		if (list == NULL)
+			return -1;
+	}
+	assert(PyList_Check(list));
+	newobj = PyWeakref_NewRef((PyObject *)type, NULL);
+	i = PyList_GET_SIZE(list);
+	while (--i >= 0) {
+		ref = PyList_GET_ITEM(list, i);
+		assert(PyWeakref_CheckRef(ref));
+		if (PyWeakref_GET_OBJECT(ref) == Py_None)
+			return PyList_SetItem(list, i, newobj);
+	}
+	result = PyList_Append(list, newobj);
+	Py_DECREF(newobj);
+	return result;
+}
+
+static void
+remove_subclass(PyTypeObject *base, PyTypeObject *type)
+{
+	Py_ssize_t i;
+	PyObject *list, *ref;
+
+	list = base->tp_subclasses;
+	if (list == NULL) {
+		return;
+	}
+	assert(PyList_Check(list));
+	i = PyList_GET_SIZE(list);
+	while (--i >= 0) {
+		ref = PyList_GET_ITEM(list, i);
+		assert(PyWeakref_CheckRef(ref));
+		if (PyWeakref_GET_OBJECT(ref) == (PyObject*)type) {
+			/* this can't fail, right? */
+			PySequence_DelItem(list, i);
+			return;
+		}
+	}
+}
+
+static int
+check_num_args(PyObject *ob, int n)
+{
+	if (!PyTuple_CheckExact(ob)) {
+		PyErr_SetString(PyExc_SystemError,
+		    "PyArg_UnpackTuple() argument list is not a tuple");
+		return 0;
+	}
+	if (n == PyTuple_GET_SIZE(ob))
+		return 1;
+	PyErr_Format(
+	    PyExc_TypeError, 
+	    "expected %d arguments, got %zd", n, PyTuple_GET_SIZE(ob));
+	return 0;
+}
+
+/* Generic wrappers for overloadable 'operators' such as __getitem__ */
+
+/* There's a wrapper *function* for each distinct function typedef used
+   for type object slots (e.g. binaryfunc, ternaryfunc, etc.).  There's a
+   wrapper *table* for each distinct operation (e.g. __len__, __add__).
+   Most tables have only one entry; the tables for binary operators have two
+   entries, one regular and one with reversed arguments. */
+
+static PyObject *
+wrap_lenfunc(PyObject *self, PyObject *args, void *wrapped)
+{
+	lenfunc func = (lenfunc)wrapped;
+	Py_ssize_t res;
+
+	if (!check_num_args(args, 0))
+		return NULL;
+	res = (*func)(self);
+	if (res == -1 && PyErr_Occurred())
+		return NULL;
+	return PyInt_FromLong((long)res);
+}
+
+static PyObject *
+wrap_inquirypred(PyObject *self, PyObject *args, void *wrapped)
+{
+	inquiry func = (inquiry)wrapped;
+	int res;
+
+	if (!check_num_args(args, 0))
+		return NULL;
+	res = (*func)(self);
+	if (res == -1 && PyErr_Occurred())
+		return NULL;
+	return PyBool_FromLong((long)res);
+}
+
+static PyObject *
+wrap_binaryfunc(PyObject *self, PyObject *args, void *wrapped)
+{
+	binaryfunc func = (binaryfunc)wrapped;
+	PyObject *other;
+
+	if (!check_num_args(args, 1))
+		return NULL;
+	other = PyTuple_GET_ITEM(args, 0);
+	return (*func)(self, other);
+}
+
+static PyObject *
+wrap_binaryfunc_l(PyObject *self, PyObject *args, void *wrapped)
+{
+	binaryfunc func = (binaryfunc)wrapped;
+	PyObject *other;
+
+	if (!check_num_args(args, 1))
+		return NULL;
+	other = PyTuple_GET_ITEM(args, 0);
+	if (!(self->ob_type->tp_flags & Py_TPFLAGS_CHECKTYPES) &&
+	    !PyType_IsSubtype(other->ob_type, self->ob_type)) {
+		Py_INCREF(Py_NotImplemented);
+		return Py_NotImplemented;
+	}
+	return (*func)(self, other);
+}
+
+static PyObject *
+wrap_binaryfunc_r(PyObject *self, PyObject *args, void *wrapped)
+{
+	binaryfunc func = (binaryfunc)wrapped;
+	PyObject *other;
+
+	if (!check_num_args(args, 1))
+		return NULL;
+	other = PyTuple_GET_ITEM(args, 0);
+	if (!(self->ob_type->tp_flags & Py_TPFLAGS_CHECKTYPES) &&
+	    !PyType_IsSubtype(other->ob_type, self->ob_type)) {
+		Py_INCREF(Py_NotImplemented);
+		return Py_NotImplemented;
+	}
+	return (*func)(other, self);
+}
+
+static PyObject *
+wrap_coercefunc(PyObject *self, PyObject *args, void *wrapped)
+{
+	coercion func = (coercion)wrapped;
+	PyObject *other, *res;
+	int ok;
+
+	if (!check_num_args(args, 1))
+		return NULL;
+	other = PyTuple_GET_ITEM(args, 0);
+	ok = func(&self, &other);
+	if (ok < 0)
+		return NULL;
+	if (ok > 0) {
+		Py_INCREF(Py_NotImplemented);
+		return Py_NotImplemented;
+	}
+	res = PyTuple_New(2);
+	if (res == NULL) {
+		Py_DECREF(self);
+		Py_DECREF(other);
+		return NULL;
+	}
+	PyTuple_SET_ITEM(res, 0, self);
+	PyTuple_SET_ITEM(res, 1, other);
+	return res;
+}
+
+static PyObject *
+wrap_ternaryfunc(PyObject *self, PyObject *args, void *wrapped)
+{
+	ternaryfunc func = (ternaryfunc)wrapped;
+	PyObject *other;
+	PyObject *third = Py_None;
+
+	/* Note: This wrapper only works for __pow__() */
+
+	if (!PyArg_UnpackTuple(args, "", 1, 2, &other, &third))
+		return NULL;
+	return (*func)(self, other, third);
+}
+
+static PyObject *
+wrap_ternaryfunc_r(PyObject *self, PyObject *args, void *wrapped)
+{
+	ternaryfunc func = (ternaryfunc)wrapped;
+	PyObject *other;
+	PyObject *third = Py_None;
+
+	/* Note: This wrapper only works for __pow__() */
+
+	if (!PyArg_UnpackTuple(args, "", 1, 2, &other, &third))
+		return NULL;
+	return (*func)(other, self, third);
+}
+
+static PyObject *
+wrap_unaryfunc(PyObject *self, PyObject *args, void *wrapped)
+{
+	unaryfunc func = (unaryfunc)wrapped;
+
+	if (!check_num_args(args, 0))
+		return NULL;
+	return (*func)(self);
+}
+
+static PyObject *
+wrap_indexargfunc(PyObject *self, PyObject *args, void *wrapped)
+{
+	ssizeargfunc func = (ssizeargfunc)wrapped;
+	PyObject* o;
+	Py_ssize_t i;
+
+	if (!PyArg_UnpackTuple(args, "", 1, 1, &o))
+		return NULL;
+	i = PyNumber_AsSsize_t(o, PyExc_OverflowError);
+	if (i == -1 && PyErr_Occurred())
+		return NULL;
+	return (*func)(self, i);
+}
+
+static Py_ssize_t
+getindex(PyObject *self, PyObject *arg)
+{
+	Py_ssize_t i;
+
+	i = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
+	if (i == -1 && PyErr_Occurred())
+		return -1;
+	if (i < 0) {
+		PySequenceMethods *sq = self->ob_type->tp_as_sequence;
+		if (sq && sq->sq_length) {
+			Py_ssize_t n = (*sq->sq_length)(self);
+			if (n < 0)
+				return -1;
+			i += n;
+		}
+	}
+	return i;
+}
+
+static PyObject *
+wrap_sq_item(PyObject *self, PyObject *args, void *wrapped)
+{
+	ssizeargfunc func = (ssizeargfunc)wrapped;
+	PyObject *arg;
+	Py_ssize_t i;
+
+	if (PyTuple_GET_SIZE(args) == 1) {
+		arg = PyTuple_GET_ITEM(args, 0);
+		i = getindex(self, arg);
+		if (i == -1 && PyErr_Occurred())
+			return NULL;
+		return (*func)(self, i);
+	}
+	check_num_args(args, 1);
+	assert(PyErr_Occurred());
+	return NULL;
+}
+
+static PyObject *
+wrap_ssizessizeargfunc(PyObject *self, PyObject *args, void *wrapped)
+{
+	ssizessizeargfunc func = (ssizessizeargfunc)wrapped;
+	Py_ssize_t i, j;
+
+	if (!PyArg_ParseTuple(args, "nn", &i, &j))
+		return NULL;
+	return (*func)(self, i, j);
+}
+
+static PyObject *
+wrap_sq_setitem(PyObject *self, PyObject *args, void *wrapped)
+{
+	ssizeobjargproc func = (ssizeobjargproc)wrapped;
+	Py_ssize_t i;
+	int res;
+	PyObject *arg, *value;
+
+	if (!PyArg_UnpackTuple(args, "", 2, 2, &arg, &value))
+		return NULL;
+	i = getindex(self, arg);
+	if (i == -1 && PyErr_Occurred())
+		return NULL;
+	res = (*func)(self, i, value);
+	if (res == -1 && PyErr_Occurred())
+		return NULL;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+wrap_sq_delitem(PyObject *self, PyObject *args, void *wrapped)
+{
+	ssizeobjargproc func = (ssizeobjargproc)wrapped;
+	Py_ssize_t i;
+	int res;
+	PyObject *arg;
+
+	if (!check_num_args(args, 1))
+		return NULL;
+	arg = PyTuple_GET_ITEM(args, 0);
+	i = getindex(self, arg);
+	if (i == -1 && PyErr_Occurred())
+		return NULL;
+	res = (*func)(self, i, NULL);
+	if (res == -1 && PyErr_Occurred())
+		return NULL;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+wrap_ssizessizeobjargproc(PyObject *self, PyObject *args, void *wrapped)
+{
+	ssizessizeobjargproc func = (ssizessizeobjargproc)wrapped;
+	Py_ssize_t i, j;
+	int res;
+	PyObject *value;
+
+	if (!PyArg_ParseTuple(args, "nnO", &i, &j, &value))
+		return NULL;
+	res = (*func)(self, i, j, value);
+	if (res == -1 && PyErr_Occurred())
+		return NULL;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+wrap_delslice(PyObject *self, PyObject *args, void *wrapped)
+{
+	ssizessizeobjargproc func = (ssizessizeobjargproc)wrapped;
+	Py_ssize_t i, j;
+	int res;
+
+	if (!PyArg_ParseTuple(args, "nn", &i, &j))
+		return NULL;
+	res = (*func)(self, i, j, NULL);
+	if (res == -1 && PyErr_Occurred())
+		return NULL;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* XXX objobjproc is a misnomer; should be objargpred */
+static PyObject *
+wrap_objobjproc(PyObject *self, PyObject *args, void *wrapped)
+{
+	objobjproc func = (objobjproc)wrapped;
+	int res;
+	PyObject *value;
+
+	if (!check_num_args(args, 1))
+		return NULL;
+	value = PyTuple_GET_ITEM(args, 0);
+	res = (*func)(self, value);
+	if (res == -1 && PyErr_Occurred())
+		return NULL;
+	else
+		return PyBool_FromLong(res);
+}
+
+static PyObject *
+wrap_objobjargproc(PyObject *self, PyObject *args, void *wrapped)
+{
+	objobjargproc func = (objobjargproc)wrapped;
+	int res;
+	PyObject *key, *value;
+
+	if (!PyArg_UnpackTuple(args, "", 2, 2, &key, &value))
+		return NULL;
+	res = (*func)(self, key, value);
+	if (res == -1 && PyErr_Occurred())
+		return NULL;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+wrap_delitem(PyObject *self, PyObject *args, void *wrapped)
+{
+	objobjargproc func = (objobjargproc)wrapped;
+	int res;
+	PyObject *key;
+
+	if (!check_num_args(args, 1))
+		return NULL;
+	key = PyTuple_GET_ITEM(args, 0);
+	res = (*func)(self, key, NULL);
+	if (res == -1 && PyErr_Occurred())
+		return NULL;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+wrap_cmpfunc(PyObject *self, PyObject *args, void *wrapped)
+{
+	cmpfunc func = (cmpfunc)wrapped;
+	int res;
+	PyObject *other;
+
+	if (!check_num_args(args, 1))
+		return NULL;
+	other = PyTuple_GET_ITEM(args, 0);
+	if (other->ob_type->tp_compare != func &&
+	    !PyType_IsSubtype(other->ob_type, self->ob_type)) {
+		PyErr_Format(
+			PyExc_TypeError,
+			"%s.__cmp__(x,y) requires y to be a '%s', not a '%s'",
+			self->ob_type->tp_name,
+			self->ob_type->tp_name,
+			other->ob_type->tp_name);
+		return NULL;
+	}
+	res = (*func)(self, other);
+	if (PyErr_Occurred())
+		return NULL;
+	return PyInt_FromLong((long)res);
+}
+
+/* Helper to check for object.__setattr__ or __delattr__ applied to a type.
+   This is called the Carlo Verre hack after its discoverer. */
+static int
+hackcheck(PyObject *self, setattrofunc func, char *what)
+{
+	PyTypeObject *type = self->ob_type;
+	while (type && type->tp_flags & Py_TPFLAGS_HEAPTYPE)
+		type = type->tp_base;
+        /* If type is NULL now, this is a really weird type.
+           In the same of backwards compatibility (?), just shut up. */
+	if (type && type->tp_setattro != func) {
+		PyErr_Format(PyExc_TypeError,
+			     "can't apply this %s to %s object",
+			     what,
+			     type->tp_name);
+		return 0;
+	}
+	return 1;
+}
+
+static PyObject *
+wrap_setattr(PyObject *self, PyObject *args, void *wrapped)
+{
+	setattrofunc func = (setattrofunc)wrapped;
+	int res;
+	PyObject *name, *value;
+
+	if (!PyArg_UnpackTuple(args, "", 2, 2, &name, &value))
+		return NULL;
+	if (!hackcheck(self, func, "__setattr__"))
+		return NULL;
+	res = (*func)(self, name, value);
+	if (res < 0)
+		return NULL;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+wrap_delattr(PyObject *self, PyObject *args, void *wrapped)
+{
+	setattrofunc func = (setattrofunc)wrapped;
+	int res;
+	PyObject *name;
+
+	if (!check_num_args(args, 1))
+		return NULL;
+	name = PyTuple_GET_ITEM(args, 0);
+	if (!hackcheck(self, func, "__delattr__"))
+		return NULL;
+	res = (*func)(self, name, NULL);
+	if (res < 0)
+		return NULL;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+wrap_hashfunc(PyObject *self, PyObject *args, void *wrapped)
+{
+	hashfunc func = (hashfunc)wrapped;
+	long res;
+
+	if (!check_num_args(args, 0))
+		return NULL;
+	res = (*func)(self);
+	if (res == -1 && PyErr_Occurred())
+		return NULL;
+	return PyInt_FromLong(res);
+}
+
+static PyObject *
+wrap_call(PyObject *self, PyObject *args, void *wrapped, PyObject *kwds)
+{
+	ternaryfunc func = (ternaryfunc)wrapped;
+
+	return (*func)(self, args, kwds);
+}
+
+static PyObject *
+wrap_richcmpfunc(PyObject *self, PyObject *args, void *wrapped, int op)
+{
+	richcmpfunc func = (richcmpfunc)wrapped;
+	PyObject *other;
+
+	if (!check_num_args(args, 1))
+		return NULL;
+	other = PyTuple_GET_ITEM(args, 0);
+	return (*func)(self, other, op);
+}
+
+#undef RICHCMP_WRAPPER
+#define RICHCMP_WRAPPER(NAME, OP) \
+static PyObject * \
+richcmp_##NAME(PyObject *self, PyObject *args, void *wrapped) \
+{ \
+	return wrap_richcmpfunc(self, args, wrapped, OP); \
+}
+
+RICHCMP_WRAPPER(lt, Py_LT)
+RICHCMP_WRAPPER(le, Py_LE)
+RICHCMP_WRAPPER(eq, Py_EQ)
+RICHCMP_WRAPPER(ne, Py_NE)
+RICHCMP_WRAPPER(gt, Py_GT)
+RICHCMP_WRAPPER(ge, Py_GE)
+
+static PyObject *
+wrap_next(PyObject *self, PyObject *args, void *wrapped)
+{
+	unaryfunc func = (unaryfunc)wrapped;
+	PyObject *res;
+
+	if (!check_num_args(args, 0))
+		return NULL;
+	res = (*func)(self);
+	if (res == NULL && !PyErr_Occurred())
+		PyErr_SetNone(PyExc_StopIteration);
+	return res;
+}
+
+static PyObject *
+wrap_descr_get(PyObject *self, PyObject *args, void *wrapped)
+{
+	descrgetfunc func = (descrgetfunc)wrapped;
+	PyObject *obj;
+	PyObject *type = NULL;
+
+	if (!PyArg_UnpackTuple(args, "", 1, 2, &obj, &type))
+		return NULL;
+	if (obj == Py_None)
+		obj = NULL;
+	if (type == Py_None)
+		type = NULL;
+	if (type == NULL &&obj == NULL) {
+		PyErr_SetString(PyExc_TypeError,
+				"__get__(None, None) is invalid");
+		return NULL;
+	}
+	return (*func)(self, obj, type);
+}
+
+static PyObject *
+wrap_descr_set(PyObject *self, PyObject *args, void *wrapped)
+{
+	descrsetfunc func = (descrsetfunc)wrapped;
+	PyObject *obj, *value;
+	int ret;
+
+	if (!PyArg_UnpackTuple(args, "", 2, 2, &obj, &value))
+		return NULL;
+	ret = (*func)(self, obj, value);
+	if (ret < 0)
+		return NULL;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+wrap_descr_delete(PyObject *self, PyObject *args, void *wrapped)
+{
+	descrsetfunc func = (descrsetfunc)wrapped;
+	PyObject *obj;
+	int ret;
+
+	if (!check_num_args(args, 1))
+		return NULL;
+	obj = PyTuple_GET_ITEM(args, 0);
+	ret = (*func)(self, obj, NULL);
+	if (ret < 0)
+		return NULL;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+wrap_init(PyObject *self, PyObject *args, void *wrapped, PyObject *kwds)
+{
+	initproc func = (initproc)wrapped;
+
+	if (func(self, args, kwds) < 0)
+		return NULL;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+tp_new_wrapper(PyObject *self, PyObject *args, PyObject *kwds)
+{
+	PyTypeObject *type, *subtype, *staticbase;
+	PyObject *arg0, *res;
+
+	if (self == NULL || !PyType_Check(self))
+		Py_FatalError("__new__() called with non-type 'self'");
+	type = (PyTypeObject *)self;
+	if (!PyTuple_Check(args) || PyTuple_GET_SIZE(args) < 1) {
+		PyErr_Format(PyExc_TypeError,
+			     "%s.__new__(): not enough arguments",
+			     type->tp_name);
+		return NULL;
+	}
+	arg0 = PyTuple_GET_ITEM(args, 0);
+	if (!PyType_Check(arg0)) {
+		PyErr_Format(PyExc_TypeError,
+			     "%s.__new__(X): X is not a type object (%s)",
+			     type->tp_name,
+			     arg0->ob_type->tp_name);
+		return NULL;
+	}
+	subtype = (PyTypeObject *)arg0;
+	if (!PyType_IsSubtype(subtype, type)) {
+		PyErr_Format(PyExc_TypeError,
+			     "%s.__new__(%s): %s is not a subtype of %s",
+			     type->tp_name,
+			     subtype->tp_name,
+			     subtype->tp_name,
+			     type->tp_name);
+		return NULL;
+	}
+
+	/* Check that the use doesn't do something silly and unsafe like
+	   object.__new__(dict).  To do this, we check that the
+	   most derived base that's not a heap type is this type. */
+	staticbase = subtype;
+	while (staticbase && (staticbase->tp_flags & Py_TPFLAGS_HEAPTYPE))
+		staticbase = staticbase->tp_base;
+        /* If staticbase is NULL now, it is a really weird type.
+           In the same of backwards compatibility (?), just shut up. */
+	if (staticbase && staticbase->tp_new != type->tp_new) {
+		PyErr_Format(PyExc_TypeError,
+			     "%s.__new__(%s) is not safe, use %s.__new__()",
+			     type->tp_name,
+			     subtype->tp_name,
+			     staticbase == NULL ? "?" : staticbase->tp_name);
+		return NULL;
+	}
+
+	args = PyTuple_GetSlice(args, 1, PyTuple_GET_SIZE(args));
+	if (args == NULL)
+		return NULL;
+	res = type->tp_new(subtype, args, kwds);
+	Py_DECREF(args);
+	return res;
+}
+
+static struct PyMethodDef tp_new_methoddef[] = {
+	{"__new__", (PyCFunction)tp_new_wrapper, METH_KEYWORDS,
+	 PyDoc_STR("T.__new__(S, ...) -> "
+	 	   "a new object with type S, a subtype of T")},
+	{0}
+};
+
+static int
+add_tp_new_wrapper(PyTypeObject *type)
+{
+	PyObject *func;
+
+	if (PyDict_GetItemString(type->tp_dict, "__new__") != NULL)
+		return 0;
+	func = PyCFunction_New(tp_new_methoddef, (PyObject *)type);
+	if (func == NULL)
+		return -1;
+	if (PyDict_SetItemString(type->tp_dict, "__new__", func)) {
+		Py_DECREF(func);
+		return -1;
+	}
+	Py_DECREF(func);
+	return 0;
+}
+
+/* Slot wrappers that call the corresponding __foo__ slot.  See comments
+   below at override_slots() for more explanation. */
+
+#define SLOT0(FUNCNAME, OPSTR) \
+static PyObject * \
+FUNCNAME(PyObject *self) \
+{ \
+	static PyObject *cache_str; \
+	return call_method(self, OPSTR, &cache_str, "()"); \
+}
+
+#define SLOT1(FUNCNAME, OPSTR, ARG1TYPE, ARGCODES) \
+static PyObject * \
+FUNCNAME(PyObject *self, ARG1TYPE arg1) \
+{ \
+	static PyObject *cache_str; \
+	return call_method(self, OPSTR, &cache_str, "(" ARGCODES ")", arg1); \
+}
+
+/* Boolean helper for SLOT1BINFULL().
+   right.__class__ is a nontrivial subclass of left.__class__. */
+static int
+method_is_overloaded(PyObject *left, PyObject *right, char *name)
+{
+	PyObject *a, *b;
+	int ok;
+
+	b = PyObject_GetAttrString((PyObject *)(right->ob_type), name);
+	if (b == NULL) {
+		PyErr_Clear();
+		/* If right doesn't have it, it's not overloaded */
+		return 0;
+	}
+
+	a = PyObject_GetAttrString((PyObject *)(left->ob_type), name);
+	if (a == NULL) {
+		PyErr_Clear();
+		Py_DECREF(b);
+		/* If right has it but left doesn't, it's overloaded */
+		return 1;
+	}
+
+	ok = PyObject_RichCompareBool(a, b, Py_NE);
+	Py_DECREF(a);
+	Py_DECREF(b);
+	if (ok < 0) {
+		PyErr_Clear();
+		return 0;
+	}
+
+	return ok;
+}
+
+
+#define SLOT1BINFULL(FUNCNAME, TESTFUNC, SLOTNAME, OPSTR, ROPSTR) \
+static PyObject * \
+FUNCNAME(PyObject *self, PyObject *other) \
+{ \
+	static PyObject *cache_str, *rcache_str; \
+	int do_other = self->ob_type != other->ob_type && \
+	    other->ob_type->tp_as_number != NULL && \
+	    other->ob_type->tp_as_number->SLOTNAME == TESTFUNC; \
+	if (self->ob_type->tp_as_number != NULL && \
+	    self->ob_type->tp_as_number->SLOTNAME == TESTFUNC) { \
+		PyObject *r; \
+		if (do_other && \
+		    PyType_IsSubtype(other->ob_type, self->ob_type) && \
+		    method_is_overloaded(self, other, ROPSTR)) { \
+			r = call_maybe( \
+				other, ROPSTR, &rcache_str, "(O)", self); \
+			if (r != Py_NotImplemented) \
+				return r; \
+			Py_DECREF(r); \
+			do_other = 0; \
+		} \
+		r = call_maybe( \
+			self, OPSTR, &cache_str, "(O)", other); \
+		if (r != Py_NotImplemented || \
+		    other->ob_type == self->ob_type) \
+			return r; \
+		Py_DECREF(r); \
+	} \
+	if (do_other) { \
+		return call_maybe( \
+			other, ROPSTR, &rcache_str, "(O)", self); \
+	} \
+	Py_INCREF(Py_NotImplemented); \
+	return Py_NotImplemented; \
+}
+
+#define SLOT1BIN(FUNCNAME, SLOTNAME, OPSTR, ROPSTR) \
+	SLOT1BINFULL(FUNCNAME, FUNCNAME, SLOTNAME, OPSTR, ROPSTR)
+
+#define SLOT2(FUNCNAME, OPSTR, ARG1TYPE, ARG2TYPE, ARGCODES) \
+static PyObject * \
+FUNCNAME(PyObject *self, ARG1TYPE arg1, ARG2TYPE arg2) \
+{ \
+	static PyObject *cache_str; \
+	return call_method(self, OPSTR, &cache_str, \
+			   "(" ARGCODES ")", arg1, arg2); \
+}
+
+static Py_ssize_t
+slot_sq_length(PyObject *self)
+{
+	static PyObject *len_str;
+	PyObject *res = call_method(self, "__len__", &len_str, "()");
+	Py_ssize_t len;
+
+	if (res == NULL)
+		return -1;
+	len = PyInt_AsSsize_t(res);
+	Py_DECREF(res);
+	if (len < 0) {
+		if (!PyErr_Occurred())
+			PyErr_SetString(PyExc_ValueError,
+					"__len__() should return >= 0");
+		return -1;
+	}
+	return len;
+}
+
+/* Super-optimized version of slot_sq_item.
+   Other slots could do the same... */
+static PyObject *
+slot_sq_item(PyObject *self, Py_ssize_t i)
+{
+	static PyObject *getitem_str;
+	PyObject *func, *args = NULL, *ival = NULL, *retval = NULL;
+	descrgetfunc f;
+
+	if (getitem_str == NULL) {
+		getitem_str = PyString_InternFromString("__getitem__");
+		if (getitem_str == NULL)
+			return NULL;
+	}
+	func = _PyType_Lookup(self->ob_type, getitem_str);
+	if (func != NULL) {
+		if ((f = func->ob_type->tp_descr_get) == NULL)
+			Py_INCREF(func);
+		else {
+			func = f(func, self, (PyObject *)(self->ob_type));
+			if (func == NULL) {
+				return NULL;
+			}
+		}
+		ival = PyInt_FromSsize_t(i);
+		if (ival != NULL) {
+			args = PyTuple_New(1);
+			if (args != NULL) {
+				PyTuple_SET_ITEM(args, 0, ival);
+				retval = PyObject_Call(func, args, NULL);
+				Py_XDECREF(args);
+				Py_XDECREF(func);
+				return retval;
+			}
+		}
+	}
+	else {
+		PyErr_SetObject(PyExc_AttributeError, getitem_str);
+	}
+	Py_XDECREF(args);
+	Py_XDECREF(ival);
+	Py_XDECREF(func);
+	return NULL;
+}
+
+SLOT2(slot_sq_slice, "__getslice__", Py_ssize_t, Py_ssize_t, "nn")
+
+static int
+slot_sq_ass_item(PyObject *self, Py_ssize_t index, PyObject *value)
+{
+	PyObject *res;
+	static PyObject *delitem_str, *setitem_str;
+
+	if (value == NULL)
+		res = call_method(self, "__delitem__", &delitem_str,
+				  "(n)", index);
+	else
+		res = call_method(self, "__setitem__", &setitem_str,
+				  "(nO)", index, value);
+	if (res == NULL)
+		return -1;
+	Py_DECREF(res);
+	return 0;
+}
+
+static int
+slot_sq_ass_slice(PyObject *self, Py_ssize_t i, Py_ssize_t j, PyObject *value)
+{
+	PyObject *res;
+	static PyObject *delslice_str, *setslice_str;
+
+	if (value == NULL)
+		res = call_method(self, "__delslice__", &delslice_str,
+				  "(nn)", i, j);
+	else
+		res = call_method(self, "__setslice__", &setslice_str,
+				  "(nnO)", i, j, value);
+	if (res == NULL)
+		return -1;
+	Py_DECREF(res);
+	return 0;
+}
+
+static int
+slot_sq_contains(PyObject *self, PyObject *value)
+{
+	PyObject *func, *res, *args;
+	int result = -1;
+
+	static PyObject *contains_str;
+
+	func = lookup_maybe(self, "__contains__", &contains_str);
+	if (func != NULL) {
+		args = PyTuple_Pack(1, value);
+		if (args == NULL)
+			res = NULL;
+		else {
+			res = PyObject_Call(func, args, NULL);
+			Py_DECREF(args);
+		}
+		Py_DECREF(func);
+		if (res != NULL) {
+			result = PyObject_IsTrue(res);
+			Py_DECREF(res);
+		}
+	}
+	else if (! PyErr_Occurred()) {
+		/* Possible results: -1 and 1 */
+		result = (int)_PySequence_IterSearch(self, value,
+						 PY_ITERSEARCH_CONTAINS);
+	}
+	return result;
+}
+
+#define slot_mp_length slot_sq_length
+
+SLOT1(slot_mp_subscript, "__getitem__", PyObject *, "O")
+
+static int
+slot_mp_ass_subscript(PyObject *self, PyObject *key, PyObject *value)
+{
+	PyObject *res;
+	static PyObject *delitem_str, *setitem_str;
+
+	if (value == NULL)
+		res = call_method(self, "__delitem__", &delitem_str,
+				  "(O)", key);
+	else
+		res = call_method(self, "__setitem__", &setitem_str,
+				 "(OO)", key, value);
+	if (res == NULL)
+		return -1;
+	Py_DECREF(res);
+	return 0;
+}
+
+SLOT1BIN(slot_nb_add, nb_add, "__add__", "__radd__")
+SLOT1BIN(slot_nb_subtract, nb_subtract, "__sub__", "__rsub__")
+SLOT1BIN(slot_nb_multiply, nb_multiply, "__mul__", "__rmul__")
+SLOT1BIN(slot_nb_divide, nb_divide, "__div__", "__rdiv__")
+SLOT1BIN(slot_nb_remainder, nb_remainder, "__mod__", "__rmod__")
+SLOT1BIN(slot_nb_divmod, nb_divmod, "__divmod__", "__rdivmod__")
+
+static PyObject *slot_nb_power(PyObject *, PyObject *, PyObject *);
+
+SLOT1BINFULL(slot_nb_power_binary, slot_nb_power,
+	     nb_power, "__pow__", "__rpow__")
+
+static PyObject *
+slot_nb_power(PyObject *self, PyObject *other, PyObject *modulus)
+{
+	static PyObject *pow_str;
+
+	if (modulus == Py_None)
+		return slot_nb_power_binary(self, other);
+	/* Three-arg power doesn't use __rpow__.  But ternary_op
+	   can call this when the second argument's type uses
+	   slot_nb_power, so check before calling self.__pow__. */
+	if (self->ob_type->tp_as_number != NULL &&
+	    self->ob_type->tp_as_number->nb_power == slot_nb_power) {
+		return call_method(self, "__pow__", &pow_str,
+				   "(OO)", other, modulus);
+	}
+	Py_INCREF(Py_NotImplemented);
+	return Py_NotImplemented;
+}
+
+SLOT0(slot_nb_negative, "__neg__")
+SLOT0(slot_nb_positive, "__pos__")
+SLOT0(slot_nb_absolute, "__abs__")
+
+static int
+slot_nb_nonzero(PyObject *self)
+{
+	PyObject *func, *args;
+	static PyObject *nonzero_str, *len_str;
+	int result = -1;
+
+	func = lookup_maybe(self, "__nonzero__", &nonzero_str);
+	if (func == NULL) {
+		if (PyErr_Occurred())
+			return -1;
+		func = lookup_maybe(self, "__len__", &len_str);
+		if (func == NULL)
+			return PyErr_Occurred() ? -1 : 1;
+ 	}
+	args = PyTuple_New(0);
+	if (args != NULL) {
+		PyObject *temp = PyObject_Call(func, args, NULL);
+		Py_DECREF(args);
+		if (temp != NULL) {
+			if (PyInt_CheckExact(temp) || PyBool_Check(temp))
+				result = PyObject_IsTrue(temp);
+			else {
+				PyErr_Format(PyExc_TypeError,
+					     "__nonzero__ should return "
+					     "bool or int, returned %s",
+					     temp->ob_type->tp_name);
+				result = -1;
+			}
+			Py_DECREF(temp);
+		}
+	}
+	Py_DECREF(func);
+	return result;
+}
+
+
+static PyObject *
+slot_nb_index(PyObject *self)
+{
+	static PyObject *index_str;
+	return call_method(self, "__index__", &index_str, "()");
+}
+
+
+SLOT0(slot_nb_invert, "__invert__")
+SLOT1BIN(slot_nb_lshift, nb_lshift, "__lshift__", "__rlshift__")
+SLOT1BIN(slot_nb_rshift, nb_rshift, "__rshift__", "__rrshift__")
+SLOT1BIN(slot_nb_and, nb_and, "__and__", "__rand__")
+SLOT1BIN(slot_nb_xor, nb_xor, "__xor__", "__rxor__")
+SLOT1BIN(slot_nb_or, nb_or, "__or__", "__ror__")
+
+static int
+slot_nb_coerce(PyObject **a, PyObject **b)
+{
+	static PyObject *coerce_str;
+	PyObject *self = *a, *other = *b;
+
+	if (self->ob_type->tp_as_number != NULL &&
+	    self->ob_type->tp_as_number->nb_coerce == slot_nb_coerce) {
+		PyObject *r;
+		r = call_maybe(
+			self, "__coerce__", &coerce_str, "(O)", other);
+		if (r == NULL)
+			return -1;
+		if (r == Py_NotImplemented) {
+			Py_DECREF(r);
+		}
+		else {
+			if (!PyTuple_Check(r) || PyTuple_GET_SIZE(r) != 2) {
+				PyErr_SetString(PyExc_TypeError,
+					"__coerce__ didn't return a 2-tuple");
+				Py_DECREF(r);
+				return -1;
+			}
+			*a = PyTuple_GET_ITEM(r, 0);
+			Py_INCREF(*a);
+			*b = PyTuple_GET_ITEM(r, 1);
+			Py_INCREF(*b);
+			Py_DECREF(r);
+			return 0;
+		}
+	}
+	if (other->ob_type->tp_as_number != NULL &&
+	    other->ob_type->tp_as_number->nb_coerce == slot_nb_coerce) {
+		PyObject *r;
+		r = call_maybe(
+			other, "__coerce__", &coerce_str, "(O)", self);
+		if (r == NULL)
+			return -1;
+		if (r == Py_NotImplemented) {
+			Py_DECREF(r);
+			return 1;
+		}
+		if (!PyTuple_Check(r) || PyTuple_GET_SIZE(r) != 2) {
+			PyErr_SetString(PyExc_TypeError,
+					"__coerce__ didn't return a 2-tuple");
+			Py_DECREF(r);
+			return -1;
+		}
+		*a = PyTuple_GET_ITEM(r, 1);
+		Py_INCREF(*a);
+		*b = PyTuple_GET_ITEM(r, 0);
+		Py_INCREF(*b);
+		Py_DECREF(r);
+		return 0;
+	}
+	return 1;
+}
+
+SLOT0(slot_nb_int, "__int__")
+SLOT0(slot_nb_long, "__long__")
+SLOT0(slot_nb_float, "__float__")
+SLOT0(slot_nb_oct, "__oct__")
+SLOT0(slot_nb_hex, "__hex__")
+SLOT1(slot_nb_inplace_add, "__iadd__", PyObject *, "O")
+SLOT1(slot_nb_inplace_subtract, "__isub__", PyObject *, "O")
+SLOT1(slot_nb_inplace_multiply, "__imul__", PyObject *, "O")
+SLOT1(slot_nb_inplace_divide, "__idiv__", PyObject *, "O")
+SLOT1(slot_nb_inplace_remainder, "__imod__", PyObject *, "O")
+/* Can't use SLOT1 here, because nb_inplace_power is ternary */
+static PyObject * 
+slot_nb_inplace_power(PyObject *self, PyObject * arg1, PyObject *arg2) 
+{ 
+  static PyObject *cache_str; 
+  return call_method(self, "__ipow__", &cache_str, "(" "O" ")", arg1); 
+}
+SLOT1(slot_nb_inplace_lshift, "__ilshift__", PyObject *, "O")
+SLOT1(slot_nb_inplace_rshift, "__irshift__", PyObject *, "O")
+SLOT1(slot_nb_inplace_and, "__iand__", PyObject *, "O")
+SLOT1(slot_nb_inplace_xor, "__ixor__", PyObject *, "O")
+SLOT1(slot_nb_inplace_or, "__ior__", PyObject *, "O")
+SLOT1BIN(slot_nb_floor_divide, nb_floor_divide,
+	 "__floordiv__", "__rfloordiv__")
+SLOT1BIN(slot_nb_true_divide, nb_true_divide, "__truediv__", "__rtruediv__")
+SLOT1(slot_nb_inplace_floor_divide, "__ifloordiv__", PyObject *, "O")
+SLOT1(slot_nb_inplace_true_divide, "__itruediv__", PyObject *, "O")
+
+static int
+half_compare(PyObject *self, PyObject *other)
+{
+	PyObject *func, *args, *res;
+	static PyObject *cmp_str;
+	Py_ssize_t c;
+
+	func = lookup_method(self, "__cmp__", &cmp_str);
+	if (func == NULL) {
+		PyErr_Clear();
+	}
+	else {
+		args = PyTuple_Pack(1, other);
+		if (args == NULL)
+			res = NULL;
+		else {
+			res = PyObject_Call(func, args, NULL);
+			Py_DECREF(args);
+		}
+		Py_DECREF(func);
+		if (res != Py_NotImplemented) {
+			if (res == NULL)
+				return -2;
+			c = PyInt_AsLong(res);
+			Py_DECREF(res);
+			if (c == -1 && PyErr_Occurred())
+				return -2;
+			return (c < 0) ? -1 : (c > 0) ? 1 : 0;
+		}
+		Py_DECREF(res);
+	}
+	return 2;
+}
+
+/* This slot is published for the benefit of try_3way_compare in object.c */
+int
+_PyObject_SlotCompare(PyObject *self, PyObject *other)
+{
+	int c;
+
+	if (self->ob_type->tp_compare == _PyObject_SlotCompare) {
+		c = half_compare(self, other);
+		if (c <= 1)
+			return c;
+	}
+	if (other->ob_type->tp_compare == _PyObject_SlotCompare) {
+		c = half_compare(other, self);
+		if (c < -1)
+			return -2;
+		if (c <= 1)
+			return -c;
+	}
+	return (void *)self < (void *)other ? -1 :
+		(void *)self > (void *)other ? 1 : 0;
+}
+
+static PyObject *
+slot_tp_repr(PyObject *self)
+{
+	PyObject *func, *res;
+	static PyObject *repr_str;
+
+	func = lookup_method(self, "__repr__", &repr_str);
+	if (func != NULL) {
+		res = PyEval_CallObject(func, NULL);
+		Py_DECREF(func);
+		return res;
+	}
+	PyErr_Clear();
+	return PyString_FromFormat("<%s object at %p>",
+				   self->ob_type->tp_name, self);
+}
+
+static PyObject *
+slot_tp_str(PyObject *self)
+{
+	PyObject *func, *res;
+	static PyObject *str_str;
+
+	func = lookup_method(self, "__str__", &str_str);
+	if (func != NULL) {
+		res = PyEval_CallObject(func, NULL);
+		Py_DECREF(func);
+		return res;
+	}
+	else {
+		PyErr_Clear();
+		return slot_tp_repr(self);
+	}
+}
+
+static long
+slot_tp_hash(PyObject *self)
+{
+	PyObject *func;
+	static PyObject *hash_str, *eq_str, *cmp_str;
+	long h;
+
+	func = lookup_method(self, "__hash__", &hash_str);
+
+	if (func != NULL) {
+		PyObject *res = PyEval_CallObject(func, NULL);
+		Py_DECREF(func);
+		if (res == NULL)
+			return -1;
+		if (PyLong_Check(res))
+			h = PyLong_Type.tp_hash(res);
+		else
+			h = PyInt_AsLong(res);
+		Py_DECREF(res);
+	}
+	else {
+		PyErr_Clear();
+		func = lookup_method(self, "__eq__", &eq_str);
+		if (func == NULL) {
+			PyErr_Clear();
+			func = lookup_method(self, "__cmp__", &cmp_str);
+		}
+		if (func != NULL) {
+			PyErr_Format(PyExc_TypeError, "unhashable type: '%.200s'",
+				     self->ob_type->tp_name);
+			Py_DECREF(func);
+			return -1;
+		}
+		PyErr_Clear();
+		h = _Py_HashPointer((void *)self);
+	}
+	if (h == -1 && !PyErr_Occurred())
+		h = -2;
+	return h;
+}
+
+static PyObject *
+slot_tp_call(PyObject *self, PyObject *args, PyObject *kwds)
+{
+	static PyObject *call_str;
+	PyObject *meth = lookup_method(self, "__call__", &call_str);
+	PyObject *res;
+
+	if (meth == NULL)
+		return NULL;
+
+	/* PyObject_Call() will end up calling slot_tp_call() again if
+	   the object returned for __call__ has __call__ itself defined
+	   upon it.  This can be an infinite recursion if you set
+	   __call__ in a class to an instance of it. */
+	if (Py_EnterRecursiveCall(" in __call__")) {
+		Py_DECREF(meth);
+		return NULL;
+	}
+	res = PyObject_Call(meth, args, kwds);
+	Py_LeaveRecursiveCall();
+
+	Py_DECREF(meth);
+	return res;
+}
+
+/* There are two slot dispatch functions for tp_getattro.
+
+   - slot_tp_getattro() is used when __getattribute__ is overridden
+     but no __getattr__ hook is present;
+
+   - slot_tp_getattr_hook() is used when a __getattr__ hook is present.
+
+   The code in update_one_slot() always installs slot_tp_getattr_hook(); this
+   detects the absence of __getattr__ and then installs the simpler slot if
+   necessary. */
+
+static PyObject *
+slot_tp_getattro(PyObject *self, PyObject *name)
+{
+	static PyObject *getattribute_str = NULL;
+	return call_method(self, "__getattribute__", &getattribute_str,
+			   "(O)", name);
+}
+
+static PyObject *
+slot_tp_getattr_hook(PyObject *self, PyObject *name)
+{
+	PyTypeObject *tp = self->ob_type;
+	PyObject *getattr, *getattribute, *res;
+	static PyObject *getattribute_str = NULL;
+	static PyObject *getattr_str = NULL;
+
+	if (getattr_str == NULL) {
+		getattr_str = PyString_InternFromString("__getattr__");
+		if (getattr_str == NULL)
+			return NULL;
+	}
+	if (getattribute_str == NULL) {
+		getattribute_str =
+			PyString_InternFromString("__getattribute__");
+		if (getattribute_str == NULL)
+			return NULL;
+	}
+	getattr = _PyType_Lookup(tp, getattr_str);
+	if (getattr == NULL) {
+		/* No __getattr__ hook: use a simpler dispatcher */
+		tp->tp_getattro = slot_tp_getattro;
+		return slot_tp_getattro(self, name);
+	}
+	getattribute = _PyType_Lookup(tp, getattribute_str);
+	if (getattribute == NULL ||
+	    (getattribute->ob_type == &PyWrapperDescr_Type &&
+	     ((PyWrapperDescrObject *)getattribute)->d_wrapped ==
+	     (void *)PyObject_GenericGetAttr))
+		res = PyObject_GenericGetAttr(self, name);
+	else
+		res = PyObject_CallFunctionObjArgs(getattribute, self, name, NULL);
+	if (res == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) {
+		PyErr_Clear();
+		res = PyObject_CallFunctionObjArgs(getattr, self, name, NULL);
+	}
+	return res;
+}
+
+static int
+slot_tp_setattro(PyObject *self, PyObject *name, PyObject *value)
+{
+	PyObject *res;
+	static PyObject *delattr_str, *setattr_str;
+
+	if (value == NULL)
+		res = call_method(self, "__delattr__", &delattr_str,
+				  "(O)", name);
+	else
+		res = call_method(self, "__setattr__", &setattr_str,
+				  "(OO)", name, value);
+	if (res == NULL)
+		return -1;
+	Py_DECREF(res);
+	return 0;
+}
+
+/* Map rich comparison operators to their __xx__ namesakes */
+static char *name_op[] = {
+	"__lt__",
+	"__le__",
+	"__eq__",
+	"__ne__",
+	"__gt__",
+	"__ge__",
+};
+
+static PyObject *
+half_richcompare(PyObject *self, PyObject *other, int op)
+{
+	PyObject *func, *args, *res;
+	static PyObject *op_str[6];
+
+	func = lookup_method(self, name_op[op], &op_str[op]);
+	if (func == NULL) {
+		PyErr_Clear();
+		Py_INCREF(Py_NotImplemented);
+		return Py_NotImplemented;
+	}
+	args = PyTuple_Pack(1, other);
+	if (args == NULL)
+		res = NULL;
+	else {
+		res = PyObject_Call(func, args, NULL);
+		Py_DECREF(args);
+	}
+	Py_DECREF(func);
+	return res;
+}
+
+static PyObject *
+slot_tp_richcompare(PyObject *self, PyObject *other, int op)
+{
+	PyObject *res;
+
+	if (self->ob_type->tp_richcompare == slot_tp_richcompare) {
+		res = half_richcompare(self, other, op);
+		if (res != Py_NotImplemented)
+			return res;
+		Py_DECREF(res);
+	}
+	if (other->ob_type->tp_richcompare == slot_tp_richcompare) {
+		res = half_richcompare(other, self, _Py_SwappedOp[op]);
+		if (res != Py_NotImplemented) {
+			return res;
+		}
+		Py_DECREF(res);
+	}
+	Py_INCREF(Py_NotImplemented);
+	return Py_NotImplemented;
+}
+
+static PyObject *
+slot_tp_iter(PyObject *self)
+{
+	PyObject *func, *res;
+	static PyObject *iter_str, *getitem_str;
+
+	func = lookup_method(self, "__iter__", &iter_str);
+	if (func != NULL) {
+		PyObject *args;
+		args = res = PyTuple_New(0);
+		if (args != NULL) {
+			res = PyObject_Call(func, args, NULL);
+			Py_DECREF(args);
+		}
+		Py_DECREF(func);
+		return res;
+	}
+	PyErr_Clear();
+	func = lookup_method(self, "__getitem__", &getitem_str);
+	if (func == NULL) {
+		PyErr_Format(PyExc_TypeError,
+			     "'%.200s' object is not iterable",
+			     self->ob_type->tp_name);
+		return NULL;
+	}
+	Py_DECREF(func);
+	return PySeqIter_New(self);
+}
+
+static PyObject *
+slot_tp_iternext(PyObject *self)
+{
+	static PyObject *next_str;
+	return call_method(self, "next", &next_str, "()");
+}
+
+static PyObject *
+slot_tp_descr_get(PyObject *self, PyObject *obj, PyObject *type)
+{
+	PyTypeObject *tp = self->ob_type;
+	PyObject *get;
+	static PyObject *get_str = NULL;
+
+	if (get_str == NULL) {
+		get_str = PyString_InternFromString("__get__");
+		if (get_str == NULL)
+			return NULL;
+	}
+	get = _PyType_Lookup(tp, get_str);
+	if (get == NULL) {
+		/* Avoid further slowdowns */
+		if (tp->tp_descr_get == slot_tp_descr_get)
+			tp->tp_descr_get = NULL;
+		Py_INCREF(self);
+		return self;
+	}
+	if (obj == NULL)
+		obj = Py_None;
+	if (type == NULL)
+		type = Py_None;
+	return PyObject_CallFunctionObjArgs(get, self, obj, type, NULL);
+}
+
+static int
+slot_tp_descr_set(PyObject *self, PyObject *target, PyObject *value)
+{
+	PyObject *res;
+	static PyObject *del_str, *set_str;
+
+	if (value == NULL)
+		res = call_method(self, "__delete__", &del_str,
+				  "(O)", target);
+	else
+		res = call_method(self, "__set__", &set_str,
+				  "(OO)", target, value);
+	if (res == NULL)
+		return -1;
+	Py_DECREF(res);
+	return 0;
+}
+
+static int
+slot_tp_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+	static PyObject *init_str;
+	PyObject *meth = lookup_method(self, "__init__", &init_str);
+	PyObject *res;
+
+	if (meth == NULL)
+		return -1;
+	res = PyObject_Call(meth, args, kwds);
+	Py_DECREF(meth);
+	if (res == NULL)
+		return -1;
+	if (res != Py_None) {
+		PyErr_Format(PyExc_TypeError,
+			     "__init__() should return None, not '%.200s'",
+			     res->ob_type->tp_name);
+		Py_DECREF(res);
+		return -1;
+	}
+	Py_DECREF(res);
+	return 0;
+}
+
+static PyObject *
+slot_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	static PyObject *new_str;
+	PyObject *func;
+	PyObject *newargs, *x;
+	Py_ssize_t i, n;
+
+	if (new_str == NULL) {
+		new_str = PyString_InternFromString("__new__");
+		if (new_str == NULL)
+			return NULL;
+	}
+	func = PyObject_GetAttr((PyObject *)type, new_str);
+	if (func == NULL)
+		return NULL;
+	assert(PyTuple_Check(args));
+	n = PyTuple_GET_SIZE(args);
+	newargs = PyTuple_New(n+1);
+	if (newargs == NULL)
+		return NULL;
+	Py_INCREF(type);
+	PyTuple_SET_ITEM(newargs, 0, (PyObject *)type);
+	for (i = 0; i < n; i++) {
+		x = PyTuple_GET_ITEM(args, i);
+		Py_INCREF(x);
+		PyTuple_SET_ITEM(newargs, i+1, x);
+	}
+	x = PyObject_Call(func, newargs, kwds);
+	Py_DECREF(newargs);
+	Py_DECREF(func);
+	return x;
+}
+
+static void
+slot_tp_del(PyObject *self)
+{
+	static PyObject *del_str = NULL;
+	PyObject *del, *res;
+	PyObject *error_type, *error_value, *error_traceback;
+
+	/* Temporarily resurrect the object. */
+	assert(self->ob_refcnt == 0);
+	self->ob_refcnt = 1;
+
+	/* Save the current exception, if any. */
+	PyErr_Fetch(&error_type, &error_value, &error_traceback);
+
+	/* Execute __del__ method, if any. */
+	del = lookup_maybe(self, "__del__", &del_str);
+	if (del != NULL) {
+		res = PyEval_CallObject(del, NULL);
+		if (res == NULL)
+			PyErr_WriteUnraisable(del);
+		else
+			Py_DECREF(res);
+		Py_DECREF(del);
+	}
+
+	/* Restore the saved exception. */
+	PyErr_Restore(error_type, error_value, error_traceback);
+
+	/* Undo the temporary resurrection; can't use DECREF here, it would
+	 * cause a recursive call.
+	 */
+	assert(self->ob_refcnt > 0);
+	if (--self->ob_refcnt == 0)
+		return;	/* this is the normal path out */
+
+	/* __del__ resurrected it!  Make it look like the original Py_DECREF
+	 * never happened.
+	 */
+	{
+		Py_ssize_t refcnt = self->ob_refcnt;
+		_Py_NewReference(self);
+		self->ob_refcnt = refcnt;
+	}
+	assert(!PyType_IS_GC(self->ob_type) ||
+	       _Py_AS_GC(self)->gc.gc_refs != _PyGC_REFS_UNTRACKED);
+	/* If Py_REF_DEBUG, _Py_NewReference bumped _Py_RefTotal, so
+	 * we need to undo that. */
+	_Py_DEC_REFTOTAL;
+	/* If Py_TRACE_REFS, _Py_NewReference re-added self to the object
+	 * chain, so no more to do there.
+	 * If COUNT_ALLOCS, the original decref bumped tp_frees, and
+	 * _Py_NewReference bumped tp_allocs:  both of those need to be
+	 * undone.
+	 */
+#ifdef COUNT_ALLOCS
+	--self->ob_type->tp_frees;
+	--self->ob_type->tp_allocs;
+#endif
+}
+
+
+/* Table mapping __foo__ names to tp_foo offsets and slot_tp_foo wrapper
+   functions.  The offsets here are relative to the 'PyHeapTypeObject'
+   structure, which incorporates the additional structures used for numbers,
+   sequences and mappings.
+   Note that multiple names may map to the same slot (e.g. __eq__,
+   __ne__ etc. all map to tp_richcompare) and one name may map to multiple
+   slots (e.g. __str__ affects tp_str as well as tp_repr). The table is
+   terminated with an all-zero entry.  (This table is further initialized and
+   sorted in init_slotdefs() below.) */
+
+typedef struct wrapperbase slotdef;
+
+#undef TPSLOT
+#undef FLSLOT
+#undef ETSLOT
+#undef SQSLOT
+#undef MPSLOT
+#undef NBSLOT
+#undef UNSLOT
+#undef IBSLOT
+#undef BINSLOT
+#undef RBINSLOT
+
+#define TPSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
+	{NAME, offsetof(PyTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, \
+	 PyDoc_STR(DOC)}
+#define FLSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC, FLAGS) \
+	{NAME, offsetof(PyTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, \
+	 PyDoc_STR(DOC), FLAGS}
+#define ETSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
+	{NAME, offsetof(PyHeapTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, \
+	 PyDoc_STR(DOC)}
+#define SQSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
+	ETSLOT(NAME, as_sequence.SLOT, FUNCTION, WRAPPER, DOC)
+#define MPSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
+	ETSLOT(NAME, as_mapping.SLOT, FUNCTION, WRAPPER, DOC)
+#define NBSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
+	ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, DOC)
+#define UNSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
+	ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, \
+	       "x." NAME "() <==> " DOC)
+#define IBSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
+	ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, \
+	       "x." NAME "(y) <==> x" DOC "y")
+#define BINSLOT(NAME, SLOT, FUNCTION, DOC) \
+	ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_l, \
+	       "x." NAME "(y) <==> x" DOC "y")
+#define RBINSLOT(NAME, SLOT, FUNCTION, DOC) \
+	ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_r, \
+	       "x." NAME "(y) <==> y" DOC "x")
+#define BINSLOTNOTINFIX(NAME, SLOT, FUNCTION, DOC) \
+	ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_l, \
+	       "x." NAME "(y) <==> " DOC)
+#define RBINSLOTNOTINFIX(NAME, SLOT, FUNCTION, DOC) \
+	ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_r, \
+	       "x." NAME "(y) <==> " DOC)
+
+static slotdef slotdefs[] = {
+	SQSLOT("__len__", sq_length, slot_sq_length, wrap_lenfunc,
+	       "x.__len__() <==> len(x)"),
+	/* Heap types defining __add__/__mul__ have sq_concat/sq_repeat == NULL.
+	   The logic in abstract.c always falls back to nb_add/nb_multiply in
+	   this case.  Defining both the nb_* and the sq_* slots to call the
+	   user-defined methods has unexpected side-effects, as shown by
+	   test_descr.notimplemented() */
+	SQSLOT("__add__", sq_concat, NULL, wrap_binaryfunc,
+          "x.__add__(y) <==> x+y"),
+	SQSLOT("__mul__", sq_repeat, NULL, wrap_indexargfunc,
+          "x.__mul__(n) <==> x*n"),
+	SQSLOT("__rmul__", sq_repeat, NULL, wrap_indexargfunc,
+          "x.__rmul__(n) <==> n*x"),
+	SQSLOT("__getitem__", sq_item, slot_sq_item, wrap_sq_item,
+	       "x.__getitem__(y) <==> x[y]"),
+	SQSLOT("__getslice__", sq_slice, slot_sq_slice, wrap_ssizessizeargfunc,
+	       "x.__getslice__(i, j) <==> x[i:j]\n\
+               \n\
+               Use of negative indices is not supported."),
+	SQSLOT("__setitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_setitem,
+	       "x.__setitem__(i, y) <==> x[i]=y"),
+	SQSLOT("__delitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_delitem,
+	       "x.__delitem__(y) <==> del x[y]"),
+	SQSLOT("__setslice__", sq_ass_slice, slot_sq_ass_slice,
+	       wrap_ssizessizeobjargproc,
+	       "x.__setslice__(i, j, y) <==> x[i:j]=y\n\
+               \n\
+               Use  of negative indices is not supported."),
+	SQSLOT("__delslice__", sq_ass_slice, slot_sq_ass_slice, wrap_delslice,
+	       "x.__delslice__(i, j) <==> del x[i:j]\n\
+               \n\
+               Use of negative indices is not supported."),
+	SQSLOT("__contains__", sq_contains, slot_sq_contains, wrap_objobjproc,
+	       "x.__contains__(y) <==> y in x"),
+	SQSLOT("__iadd__", sq_inplace_concat, NULL,
+          wrap_binaryfunc, "x.__iadd__(y) <==> x+=y"),
+	SQSLOT("__imul__", sq_inplace_repeat, NULL,
+          wrap_indexargfunc, "x.__imul__(y) <==> x*=y"),
+
+	MPSLOT("__len__", mp_length, slot_mp_length, wrap_lenfunc,
+	       "x.__len__() <==> len(x)"),
+	MPSLOT("__getitem__", mp_subscript, slot_mp_subscript,
+	       wrap_binaryfunc,
+	       "x.__getitem__(y) <==> x[y]"),
+	MPSLOT("__setitem__", mp_ass_subscript, slot_mp_ass_subscript,
+	       wrap_objobjargproc,
+	       "x.__setitem__(i, y) <==> x[i]=y"),
+	MPSLOT("__delitem__", mp_ass_subscript, slot_mp_ass_subscript,
+	       wrap_delitem,
+	       "x.__delitem__(y) <==> del x[y]"),
+
+	BINSLOT("__add__", nb_add, slot_nb_add,
+		"+"),
+	RBINSLOT("__radd__", nb_add, slot_nb_add,
+		 "+"),
+	BINSLOT("__sub__", nb_subtract, slot_nb_subtract,
+		"-"),
+	RBINSLOT("__rsub__", nb_subtract, slot_nb_subtract,
+		 "-"),
+	BINSLOT("__mul__", nb_multiply, slot_nb_multiply,
+		"*"),
+	RBINSLOT("__rmul__", nb_multiply, slot_nb_multiply,
+		 "*"),
+	BINSLOT("__div__", nb_divide, slot_nb_divide,
+		"/"),
+	RBINSLOT("__rdiv__", nb_divide, slot_nb_divide,
+		 "/"),
+	BINSLOT("__mod__", nb_remainder, slot_nb_remainder,
+		"%"),
+	RBINSLOT("__rmod__", nb_remainder, slot_nb_remainder,
+		 "%"),
+	BINSLOTNOTINFIX("__divmod__", nb_divmod, slot_nb_divmod,
+		"divmod(x, y)"),
+	RBINSLOTNOTINFIX("__rdivmod__", nb_divmod, slot_nb_divmod,
+		 "divmod(y, x)"),
+	NBSLOT("__pow__", nb_power, slot_nb_power, wrap_ternaryfunc,
+	       "x.__pow__(y[, z]) <==> pow(x, y[, z])"),
+	NBSLOT("__rpow__", nb_power, slot_nb_power, wrap_ternaryfunc_r,
+	       "y.__rpow__(x[, z]) <==> pow(x, y[, z])"),
+	UNSLOT("__neg__", nb_negative, slot_nb_negative, wrap_unaryfunc, "-x"),
+	UNSLOT("__pos__", nb_positive, slot_nb_positive, wrap_unaryfunc, "+x"),
+	UNSLOT("__abs__", nb_absolute, slot_nb_absolute, wrap_unaryfunc,
+	       "abs(x)"),
+	UNSLOT("__nonzero__", nb_nonzero, slot_nb_nonzero, wrap_inquirypred,
+	       "x != 0"),
+	UNSLOT("__invert__", nb_invert, slot_nb_invert, wrap_unaryfunc, "~x"),
+	BINSLOT("__lshift__", nb_lshift, slot_nb_lshift, "<<"),
+	RBINSLOT("__rlshift__", nb_lshift, slot_nb_lshift, "<<"),
+	BINSLOT("__rshift__", nb_rshift, slot_nb_rshift, ">>"),
+	RBINSLOT("__rrshift__", nb_rshift, slot_nb_rshift, ">>"),
+	BINSLOT("__and__", nb_and, slot_nb_and, "&"),
+	RBINSLOT("__rand__", nb_and, slot_nb_and, "&"),
+	BINSLOT("__xor__", nb_xor, slot_nb_xor, "^"),
+	RBINSLOT("__rxor__", nb_xor, slot_nb_xor, "^"),
+	BINSLOT("__or__", nb_or, slot_nb_or, "|"),
+	RBINSLOT("__ror__", nb_or, slot_nb_or, "|"),
+	NBSLOT("__coerce__", nb_coerce, slot_nb_coerce, wrap_coercefunc,
+	       "x.__coerce__(y) <==> coerce(x, y)"),
+	UNSLOT("__int__", nb_int, slot_nb_int, wrap_unaryfunc,
+	       "int(x)"),
+	UNSLOT("__long__", nb_long, slot_nb_long, wrap_unaryfunc,
+	       "long(x)"),
+	UNSLOT("__float__", nb_float, slot_nb_float, wrap_unaryfunc,
+	       "float(x)"),
+	UNSLOT("__oct__", nb_oct, slot_nb_oct, wrap_unaryfunc,
+	       "oct(x)"),
+	UNSLOT("__hex__", nb_hex, slot_nb_hex, wrap_unaryfunc,
+	       "hex(x)"),
+	NBSLOT("__index__", nb_index, slot_nb_index, wrap_unaryfunc, 
+	       "x[y:z] <==> x[y.__index__():z.__index__()]"),
+	IBSLOT("__iadd__", nb_inplace_add, slot_nb_inplace_add,
+	       wrap_binaryfunc, "+"),
+	IBSLOT("__isub__", nb_inplace_subtract, slot_nb_inplace_subtract,
+	       wrap_binaryfunc, "-"),
+	IBSLOT("__imul__", nb_inplace_multiply, slot_nb_inplace_multiply,
+	       wrap_binaryfunc, "*"),
+	IBSLOT("__idiv__", nb_inplace_divide, slot_nb_inplace_divide,
+	       wrap_binaryfunc, "/"),
+	IBSLOT("__imod__", nb_inplace_remainder, slot_nb_inplace_remainder,
+	       wrap_binaryfunc, "%"),
+	IBSLOT("__ipow__", nb_inplace_power, slot_nb_inplace_power,
+	       wrap_binaryfunc, "**"),
+	IBSLOT("__ilshift__", nb_inplace_lshift, slot_nb_inplace_lshift,
+	       wrap_binaryfunc, "<<"),
+	IBSLOT("__irshift__", nb_inplace_rshift, slot_nb_inplace_rshift,
+	       wrap_binaryfunc, ">>"),
+	IBSLOT("__iand__", nb_inplace_and, slot_nb_inplace_and,
+	       wrap_binaryfunc, "&"),
+	IBSLOT("__ixor__", nb_inplace_xor, slot_nb_inplace_xor,
+	       wrap_binaryfunc, "^"),
+	IBSLOT("__ior__", nb_inplace_or, slot_nb_inplace_or,
+	       wrap_binaryfunc, "|"),
+	BINSLOT("__floordiv__", nb_floor_divide, slot_nb_floor_divide, "//"),
+	RBINSLOT("__rfloordiv__", nb_floor_divide, slot_nb_floor_divide, "//"),
+	BINSLOT("__truediv__", nb_true_divide, slot_nb_true_divide, "/"),
+	RBINSLOT("__rtruediv__", nb_true_divide, slot_nb_true_divide, "/"),
+	IBSLOT("__ifloordiv__", nb_inplace_floor_divide,
+	       slot_nb_inplace_floor_divide, wrap_binaryfunc, "//"),
+	IBSLOT("__itruediv__", nb_inplace_true_divide,
+	       slot_nb_inplace_true_divide, wrap_binaryfunc, "/"),
+
+	TPSLOT("__str__", tp_str, slot_tp_str, wrap_unaryfunc,
+	       "x.__str__() <==> str(x)"),
+	TPSLOT("__str__", tp_print, NULL, NULL, ""),
+	TPSLOT("__repr__", tp_repr, slot_tp_repr, wrap_unaryfunc,
+	       "x.__repr__() <==> repr(x)"),
+	TPSLOT("__repr__", tp_print, NULL, NULL, ""),
+	TPSLOT("__cmp__", tp_compare, _PyObject_SlotCompare, wrap_cmpfunc,
+	       "x.__cmp__(y) <==> cmp(x,y)"),
+	TPSLOT("__hash__", tp_hash, slot_tp_hash, wrap_hashfunc,
+	       "x.__hash__() <==> hash(x)"),
+	FLSLOT("__call__", tp_call, slot_tp_call, (wrapperfunc)wrap_call,
+	       "x.__call__(...) <==> x(...)", PyWrapperFlag_KEYWORDS),
+	TPSLOT("__getattribute__", tp_getattro, slot_tp_getattr_hook,
+	       wrap_binaryfunc, "x.__getattribute__('name') <==> x.name"),
+	TPSLOT("__getattribute__", tp_getattr, NULL, NULL, ""),
+	TPSLOT("__getattr__", tp_getattro, slot_tp_getattr_hook, NULL, ""),
+	TPSLOT("__getattr__", tp_getattr, NULL, NULL, ""),
+	TPSLOT("__setattr__", tp_setattro, slot_tp_setattro, wrap_setattr,
+	       "x.__setattr__('name', value) <==> x.name = value"),
+	TPSLOT("__setattr__", tp_setattr, NULL, NULL, ""),
+	TPSLOT("__delattr__", tp_setattro, slot_tp_setattro, wrap_delattr,
+	       "x.__delattr__('name') <==> del x.name"),
+	TPSLOT("__delattr__", tp_setattr, NULL, NULL, ""),
+	TPSLOT("__lt__", tp_richcompare, slot_tp_richcompare, richcmp_lt,
+	       "x.__lt__(y) <==> x<y"),
+	TPSLOT("__le__", tp_richcompare, slot_tp_richcompare, richcmp_le,
+	       "x.__le__(y) <==> x<=y"),
+	TPSLOT("__eq__", tp_richcompare, slot_tp_richcompare, richcmp_eq,
+	       "x.__eq__(y) <==> x==y"),
+	TPSLOT("__ne__", tp_richcompare, slot_tp_richcompare, richcmp_ne,
+	       "x.__ne__(y) <==> x!=y"),
+	TPSLOT("__gt__", tp_richcompare, slot_tp_richcompare, richcmp_gt,
+	       "x.__gt__(y) <==> x>y"),
+	TPSLOT("__ge__", tp_richcompare, slot_tp_richcompare, richcmp_ge,
+	       "x.__ge__(y) <==> x>=y"),
+	TPSLOT("__iter__", tp_iter, slot_tp_iter, wrap_unaryfunc,
+	       "x.__iter__() <==> iter(x)"),
+	TPSLOT("next", tp_iternext, slot_tp_iternext, wrap_next,
+	       "x.next() -> the next value, or raise StopIteration"),
+	TPSLOT("__get__", tp_descr_get, slot_tp_descr_get, wrap_descr_get,
+	       "descr.__get__(obj[, type]) -> value"),
+	TPSLOT("__set__", tp_descr_set, slot_tp_descr_set, wrap_descr_set,
+	       "descr.__set__(obj, value)"),
+	TPSLOT("__delete__", tp_descr_set, slot_tp_descr_set,
+	       wrap_descr_delete, "descr.__delete__(obj)"),
+	FLSLOT("__init__", tp_init, slot_tp_init, (wrapperfunc)wrap_init,
+	       "x.__init__(...) initializes x; "
+	       "see x.__class__.__doc__ for signature",
+	       PyWrapperFlag_KEYWORDS),
+	TPSLOT("__new__", tp_new, slot_tp_new, NULL, ""),
+	TPSLOT("__del__", tp_del, slot_tp_del, NULL, ""),
+	{NULL}
+};
+
+/* Given a type pointer and an offset gotten from a slotdef entry, return a
+   pointer to the actual slot.  This is not quite the same as simply adding
+   the offset to the type pointer, since it takes care to indirect through the
+   proper indirection pointer (as_buffer, etc.); it returns NULL if the
+   indirection pointer is NULL. */
+static void **
+slotptr(PyTypeObject *type, int ioffset)
+{
+	char *ptr;
+	long offset = ioffset;
+
+	/* Note: this depends on the order of the members of PyHeapTypeObject! */
+	assert(offset >= 0);
+	assert((size_t)offset < offsetof(PyHeapTypeObject, as_buffer));
+	if ((size_t)offset >= offsetof(PyHeapTypeObject, as_sequence)) {
+		ptr = (char *)type->tp_as_sequence;
+		offset -= offsetof(PyHeapTypeObject, as_sequence);
+	}
+	else if ((size_t)offset >= offsetof(PyHeapTypeObject, as_mapping)) {
+		ptr = (char *)type->tp_as_mapping;
+		offset -= offsetof(PyHeapTypeObject, as_mapping);
+	}
+	else if ((size_t)offset >= offsetof(PyHeapTypeObject, as_number)) {
+		ptr = (char *)type->tp_as_number;
+		offset -= offsetof(PyHeapTypeObject, as_number);
+	}
+	else {
+		ptr = (char *)type;
+	}
+	if (ptr != NULL)
+		ptr += offset;
+	return (void **)ptr;
+}
+
+/* Length of array of slotdef pointers used to store slots with the
+   same __name__.  There should be at most MAX_EQUIV-1 slotdef entries with
+   the same __name__, for any __name__. Since that's a static property, it is
+   appropriate to declare fixed-size arrays for this. */
+#define MAX_EQUIV 10
+
+/* Return a slot pointer for a given name, but ONLY if the attribute has
+   exactly one slot function.  The name must be an interned string. */
+static void **
+resolve_slotdups(PyTypeObject *type, PyObject *name)
+{
+	/* XXX Maybe this could be optimized more -- but is it worth it? */
+
+	/* pname and ptrs act as a little cache */
+	static PyObject *pname;
+	static slotdef *ptrs[MAX_EQUIV];
+	slotdef *p, **pp;
+	void **res, **ptr;
+
+	if (pname != name) {
+		/* Collect all slotdefs that match name into ptrs. */
+		pname = name;
+		pp = ptrs;
+		for (p = slotdefs; p->name_strobj; p++) {
+			if (p->name_strobj == name)
+				*pp++ = p;
+		}
+		*pp = NULL;
+	}
+
+	/* Look in all matching slots of the type; if exactly one of these has
+	   a filled-in slot, return its value.  Otherwise return NULL. */
+	res = NULL;
+	for (pp = ptrs; *pp; pp++) {
+		ptr = slotptr(type, (*pp)->offset);
+		if (ptr == NULL || *ptr == NULL)
+			continue;
+		if (res != NULL)
+			return NULL;
+		res = ptr;
+	}
+	return res;
+}
+
+/* Common code for update_slots_callback() and fixup_slot_dispatchers().  This
+   does some incredibly complex thinking and then sticks something into the
+   slot.  (It sees if the adjacent slotdefs for the same slot have conflicting
+   interests, and then stores a generic wrapper or a specific function into
+   the slot.)  Return a pointer to the next slotdef with a different offset,
+   because that's convenient  for fixup_slot_dispatchers(). */
+static slotdef *
+update_one_slot(PyTypeObject *type, slotdef *p)
+{
+	PyObject *descr;
+	PyWrapperDescrObject *d;
+	void *generic = NULL, *specific = NULL;
+	int use_generic = 0;
+	int offset = p->offset;
+	void **ptr = slotptr(type, offset);
+
+	if (ptr == NULL) {
+		do {
+			++p;
+		} while (p->offset == offset);
+		return p;
+	}
+	do {
+		descr = _PyType_Lookup(type, p->name_strobj);
+		if (descr == NULL)
+			continue;
+		if (descr->ob_type == &PyWrapperDescr_Type) {
+			void **tptr = resolve_slotdups(type, p->name_strobj);
+			if (tptr == NULL || tptr == ptr)
+				generic = p->function;
+			d = (PyWrapperDescrObject *)descr;
+			if (d->d_base->wrapper == p->wrapper &&
+			    PyType_IsSubtype(type, d->d_type))
+			{
+				if (specific == NULL ||
+				    specific == d->d_wrapped)
+					specific = d->d_wrapped;
+				else
+					use_generic = 1;
+			}
+		}
+		else if (descr->ob_type == &PyCFunction_Type &&
+			 PyCFunction_GET_FUNCTION(descr) ==
+			 (PyCFunction)tp_new_wrapper &&
+			 strcmp(p->name, "__new__") == 0)
+		{
+			/* The __new__ wrapper is not a wrapper descriptor,
+			   so must be special-cased differently.
+			   If we don't do this, creating an instance will
+			   always use slot_tp_new which will look up
+			   __new__ in the MRO which will call tp_new_wrapper
+			   which will look through the base classes looking
+			   for a static base and call its tp_new (usually
+			   PyType_GenericNew), after performing various
+			   sanity checks and constructing a new argument
+			   list.  Cut all that nonsense short -- this speeds
+			   up instance creation tremendously. */
+			specific = (void *)type->tp_new;
+			/* XXX I'm not 100% sure that there isn't a hole
+			   in this reasoning that requires additional
+			   sanity checks.  I'll buy the first person to
+			   point out a bug in this reasoning a beer. */
+		}
+		else {
+			use_generic = 1;
+			generic = p->function;
+		}
+	} while ((++p)->offset == offset);
+	if (specific && !use_generic)
+		*ptr = specific;
+	else
+		*ptr = generic;
+	return p;
+}
+
+/* In the type, update the slots whose slotdefs are gathered in the pp array.
+   This is a callback for update_subclasses(). */
+static int
+update_slots_callback(PyTypeObject *type, void *data)
+{
+	slotdef **pp = (slotdef **)data;
+
+	for (; *pp; pp++)
+		update_one_slot(type, *pp);
+	return 0;
+}
+
+/* Comparison function for qsort() to compare slotdefs by their offset, and
+   for equal offset by their address (to force a stable sort). */
+static int
+slotdef_cmp(const void *aa, const void *bb)
+{
+	const slotdef *a = (const slotdef *)aa, *b = (const slotdef *)bb;
+	int c = a->offset - b->offset;
+	if (c != 0)
+		return c;
+	else
+		/* Cannot use a-b, as this gives off_t, 
+		   which may lose precision when converted to int. */
+		return (a > b) ? 1 : (a < b) ? -1 : 0;
+}
+
+/* Initialize the slotdefs table by adding interned string objects for the
+   names and sorting the entries. */
+static void
+init_slotdefs(void)
+{
+	slotdef *p;
+	static int initialized = 0;
+
+	if (initialized)
+		return;
+	for (p = slotdefs; p->name; p++) {
+		p->name_strobj = PyString_InternFromString(p->name);
+		if (!p->name_strobj)
+			Py_FatalError("Out of memory interning slotdef names");
+	}
+	qsort((void *)slotdefs, (size_t)(p-slotdefs), sizeof(slotdef),
+	      slotdef_cmp);
+	initialized = 1;
+}
+
+/* Update the slots after assignment to a class (type) attribute. */
+static int
+update_slot(PyTypeObject *type, PyObject *name)
+{
+	slotdef *ptrs[MAX_EQUIV];
+	slotdef *p;
+	slotdef **pp;
+	int offset;
+
+	init_slotdefs();
+	pp = ptrs;
+	for (p = slotdefs; p->name; p++) {
+		/* XXX assume name is interned! */
+		if (p->name_strobj == name)
+			*pp++ = p;
+	}
+	*pp = NULL;
+	for (pp = ptrs; *pp; pp++) {
+		p = *pp;
+		offset = p->offset;
+		while (p > slotdefs && (p-1)->offset == offset)
+			--p;
+		*pp = p;
+	}
+	if (ptrs[0] == NULL)
+		return 0; /* Not an attribute that affects any slots */
+	return update_subclasses(type, name,
+				 update_slots_callback, (void *)ptrs);
+}
+
+/* Store the proper functions in the slot dispatches at class (type)
+   definition time, based upon which operations the class overrides in its
+   dict. */
+static void
+fixup_slot_dispatchers(PyTypeObject *type)
+{
+	slotdef *p;
+
+	init_slotdefs();
+	for (p = slotdefs; p->name; )
+		p = update_one_slot(type, p);
+}
+
+static void
+update_all_slots(PyTypeObject* type)
+{
+	slotdef *p;
+
+	init_slotdefs();
+	for (p = slotdefs; p->name; p++) {
+		/* update_slot returns int but can't actually fail */
+		update_slot(type, p->name_strobj);
+	}
+}
+
+/* recurse_down_subclasses() and update_subclasses() are mutually
+   recursive functions to call a callback for all subclasses,
+   but refraining from recursing into subclasses that define 'name'. */
+
+static int
+update_subclasses(PyTypeObject *type, PyObject *name,
+		  update_callback callback, void *data)
+{
+	if (callback(type, data) < 0)
+		return -1;
+	return recurse_down_subclasses(type, name, callback, data);
+}
+
+static int
+recurse_down_subclasses(PyTypeObject *type, PyObject *name,
+			update_callback callback, void *data)
+{
+	PyTypeObject *subclass;
+	PyObject *ref, *subclasses, *dict;
+	Py_ssize_t i, n;
+
+	subclasses = type->tp_subclasses;
+	if (subclasses == NULL)
+		return 0;
+	assert(PyList_Check(subclasses));
+	n = PyList_GET_SIZE(subclasses);
+	for (i = 0; i < n; i++) {
+		ref = PyList_GET_ITEM(subclasses, i);
+		assert(PyWeakref_CheckRef(ref));
+		subclass = (PyTypeObject *)PyWeakref_GET_OBJECT(ref);
+		assert(subclass != NULL);
+		if ((PyObject *)subclass == Py_None)
+			continue;
+		assert(PyType_Check(subclass));
+		/* Avoid recursing down into unaffected classes */
+		dict = subclass->tp_dict;
+		if (dict != NULL && PyDict_Check(dict) &&
+		    PyDict_GetItem(dict, name) != NULL)
+			continue;
+		if (update_subclasses(subclass, name, callback, data) < 0)
+			return -1;
+	}
+	return 0;
+}
+
+/* This function is called by PyType_Ready() to populate the type's
+   dictionary with method descriptors for function slots.  For each
+   function slot (like tp_repr) that's defined in the type, one or more
+   corresponding descriptors are added in the type's tp_dict dictionary
+   under the appropriate name (like __repr__).  Some function slots
+   cause more than one descriptor to be added (for example, the nb_add
+   slot adds both __add__ and __radd__ descriptors) and some function
+   slots compete for the same descriptor (for example both sq_item and
+   mp_subscript generate a __getitem__ descriptor).
+
+   In the latter case, the first slotdef entry encoutered wins.  Since
+   slotdef entries are sorted by the offset of the slot in the
+   PyHeapTypeObject, this gives us some control over disambiguating
+   between competing slots: the members of PyHeapTypeObject are listed
+   from most general to least general, so the most general slot is
+   preferred.  In particular, because as_mapping comes before as_sequence,
+   for a type that defines both mp_subscript and sq_item, mp_subscript
+   wins.
+
+   This only adds new descriptors and doesn't overwrite entries in
+   tp_dict that were previously defined.  The descriptors contain a
+   reference to the C function they must call, so that it's safe if they
+   are copied into a subtype's __dict__ and the subtype has a different
+   C function in its slot -- calling the method defined by the
+   descriptor will call the C function that was used to create it,
+   rather than the C function present in the slot when it is called.
+   (This is important because a subtype may have a C function in the
+   slot that calls the method from the dictionary, and we want to avoid
+   infinite recursion here.) */
+
+static int
+add_operators(PyTypeObject *type)
+{
+	PyObject *dict = type->tp_dict;
+	slotdef *p;
+	PyObject *descr;
+	void **ptr;
+
+	init_slotdefs();
+	for (p = slotdefs; p->name; p++) {
+		if (p->wrapper == NULL)
+			continue;
+		ptr = slotptr(type, p->offset);
+		if (!ptr || !*ptr)
+			continue;
+		if (PyDict_GetItem(dict, p->name_strobj))
+			continue;
+		descr = PyDescr_NewWrapper(type, p, *ptr);
+		if (descr == NULL)
+			return -1;
+		if (PyDict_SetItem(dict, p->name_strobj, descr) < 0)
+			return -1;
+		Py_DECREF(descr);
+	}
+	if (type->tp_new != NULL) {
+		if (add_tp_new_wrapper(type) < 0)
+			return -1;
+	}
+	return 0;
+}
+
+
+/* Cooperative 'super' */
+
+typedef struct {
+	PyObject_HEAD
+	PyTypeObject *type;
+	PyObject *obj;
+	PyTypeObject *obj_type;
+} superobject;
+
+static PyMemberDef super_members[] = {
+	{"__thisclass__", T_OBJECT, offsetof(superobject, type), READONLY,
+	 "the class invoking super()"},
+	{"__self__",  T_OBJECT, offsetof(superobject, obj), READONLY,
+	 "the instance invoking super(); may be None"},
+	{"__self_class__", T_OBJECT, offsetof(superobject, obj_type), READONLY,
+	 "the type of the instance invoking super(); may be None"},
+	{0}
+};
+
+static void
+super_dealloc(PyObject *self)
+{
+	superobject *su = (superobject *)self;
+
+	_PyObject_GC_UNTRACK(self);
+	Py_XDECREF(su->obj);
+	Py_XDECREF(su->type);
+	Py_XDECREF(su->obj_type);
+	self->ob_type->tp_free(self);
+}
+
+static PyObject *
+super_repr(PyObject *self)
+{
+	superobject *su = (superobject *)self;
+
+	if (su->obj_type)
+		return PyString_FromFormat(
+			"<super: <class '%s'>, <%s object>>",
+			su->type ? su->type->tp_name : "NULL",
+			su->obj_type->tp_name);
+	else
+		return PyString_FromFormat(
+			"<super: <class '%s'>, NULL>",
+			su->type ? su->type->tp_name : "NULL");
+}
+
+static PyObject *
+super_getattro(PyObject *self, PyObject *name)
+{
+	superobject *su = (superobject *)self;
+	int skip = su->obj_type == NULL;
+
+	if (!skip) {
+		/* We want __class__ to return the class of the super object
+		   (i.e. super, or a subclass), not the class of su->obj. */
+		skip = (PyString_Check(name) &&
+			PyString_GET_SIZE(name) == 9 &&
+			strcmp(PyString_AS_STRING(name), "__class__") == 0);
+	}
+
+	if (!skip) {
+		PyObject *mro, *res, *tmp, *dict;
+		PyTypeObject *starttype;
+		descrgetfunc f;
+		Py_ssize_t i, n;
+
+		starttype = su->obj_type;
+		mro = starttype->tp_mro;
+
+		if (mro == NULL)
+			n = 0;
+		else {
+			assert(PyTuple_Check(mro));
+			n = PyTuple_GET_SIZE(mro);
+		}
+		for (i = 0; i < n; i++) {
+			if ((PyObject *)(su->type) == PyTuple_GET_ITEM(mro, i))
+				break;
+		}
+		i++;
+		res = NULL;
+		for (; i < n; i++) {
+			tmp = PyTuple_GET_ITEM(mro, i);
+			if (PyType_Check(tmp))
+				dict = ((PyTypeObject *)tmp)->tp_dict;
+			else if (PyClass_Check(tmp))
+				dict = ((PyClassObject *)tmp)->cl_dict;
+			else
+				continue;
+			res = PyDict_GetItem(dict, name);
+			if (res != NULL) {
+				Py_INCREF(res);
+				f = res->ob_type->tp_descr_get;
+				if (f != NULL) {
+					tmp = f(res,
+						/* Only pass 'obj' param if
+						   this is instance-mode super 
+						   (See SF ID #743627)
+						*/
+						(su->obj == (PyObject *)
+							    su->obj_type 
+							? (PyObject *)NULL 
+							: su->obj),
+						(PyObject *)starttype);
+					Py_DECREF(res);
+					res = tmp;
+				}
+				return res;
+			}
+		}
+	}
+	return PyObject_GenericGetAttr(self, name);
+}
+
+static PyTypeObject *
+supercheck(PyTypeObject *type, PyObject *obj)
+{
+	/* Check that a super() call makes sense.  Return a type object.
+
+	   obj can be a new-style class, or an instance of one:
+
+	   - If it is a class, it must be a subclass of 'type'.  This case is
+	     used for class methods; the return value is obj.
+
+	   - If it is an instance, it must be an instance of 'type'.  This is
+	     the normal case; the return value is obj.__class__.
+
+	   But... when obj is an instance, we want to allow for the case where
+	   obj->ob_type is not a subclass of type, but obj.__class__ is!
+	   This will allow using super() with a proxy for obj.
+	*/
+
+	/* Check for first bullet above (special case) */
+	if (PyType_Check(obj) && PyType_IsSubtype((PyTypeObject *)obj, type)) {
+		Py_INCREF(obj);
+		return (PyTypeObject *)obj;
+	}
+
+	/* Normal case */
+	if (PyType_IsSubtype(obj->ob_type, type)) {
+		Py_INCREF(obj->ob_type);
+		return obj->ob_type;
+	}
+	else {
+		/* Try the slow way */
+		static PyObject *class_str = NULL;
+		PyObject *class_attr;
+
+		if (class_str == NULL) {
+			class_str = PyString_FromString("__class__");
+			if (class_str == NULL)
+				return NULL;
+		}
+
+		class_attr = PyObject_GetAttr(obj, class_str);
+
+		if (class_attr != NULL &&
+		    PyType_Check(class_attr) &&
+		    (PyTypeObject *)class_attr != obj->ob_type)
+		{
+			int ok = PyType_IsSubtype(
+				(PyTypeObject *)class_attr, type);
+			if (ok)
+				return (PyTypeObject *)class_attr;
+		}
+
+		if (class_attr == NULL)
+			PyErr_Clear();
+		else
+			Py_DECREF(class_attr);
+	}
+
+  	PyErr_SetString(PyExc_TypeError,
+			"super(type, obj): "
+			"obj must be an instance or subtype of type");
+	return NULL;
+}
+
+static PyObject *
+super_descr_get(PyObject *self, PyObject *obj, PyObject *type)
+{
+	superobject *su = (superobject *)self;
+	superobject *newobj;
+
+	if (obj == NULL || obj == Py_None || su->obj != NULL) {
+		/* Not binding to an object, or already bound */
+		Py_INCREF(self);
+		return self;
+	}
+	if (su->ob_type != &PySuper_Type)
+		/* If su is an instance of a (strict) subclass of super,
+		   call its type */
+		return PyObject_CallFunctionObjArgs((PyObject *)su->ob_type,
+					            su->type, obj, NULL);
+	else {
+		/* Inline the common case */
+		PyTypeObject *obj_type = supercheck(su->type, obj);
+		if (obj_type == NULL)
+			return NULL;
+		newobj = (superobject *)PySuper_Type.tp_new(&PySuper_Type,
+							 NULL, NULL);
+		if (newobj == NULL)
+			return NULL;
+		Py_INCREF(su->type);
+		Py_INCREF(obj);
+		newobj->type = su->type;
+		newobj->obj = obj;
+		newobj->obj_type = obj_type;
+		return (PyObject *)newobj;
+	}
+}
+
+static int
+super_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+	superobject *su = (superobject *)self;
+	PyTypeObject *type;
+	PyObject *obj = NULL;
+	PyTypeObject *obj_type = NULL;
+
+	if (!_PyArg_NoKeywords("super", kwds))
+		return -1;
+	if (!PyArg_ParseTuple(args, "O!|O:super", &PyType_Type, &type, &obj))
+		return -1;
+	if (obj == Py_None)
+		obj = NULL;
+	if (obj != NULL) {
+		obj_type = supercheck(type, obj);
+		if (obj_type == NULL)
+			return -1;
+		Py_INCREF(obj);
+	}
+	Py_INCREF(type);
+	su->type = type;
+	su->obj = obj;
+	su->obj_type = obj_type;
+	return 0;
+}
+
+PyDoc_STRVAR(super_doc,
+"super(type) -> unbound super object\n"
+"super(type, obj) -> bound super object; requires isinstance(obj, type)\n"
+"super(type, type2) -> bound super object; requires issubclass(type2, type)\n"
+"Typical use to call a cooperative superclass method:\n"
+"class C(B):\n"
+"    def meth(self, arg):\n"
+"        super(C, self).meth(arg)");
+
+static int
+super_traverse(PyObject *self, visitproc visit, void *arg)
+{
+	superobject *su = (superobject *)self;
+
+	Py_VISIT(su->obj);
+	Py_VISIT(su->type);
+	Py_VISIT(su->obj_type);
+
+	return 0;
+}
+
+PyTypeObject PySuper_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,					/* ob_size */
+	"super",				/* tp_name */
+	sizeof(superobject),			/* tp_basicsize */
+	0,					/* tp_itemsize */
+	/* methods */
+	super_dealloc,		 		/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	super_repr,				/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,		       			/* tp_as_mapping */
+	0,					/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	super_getattro,				/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+		Py_TPFLAGS_BASETYPE,		/* tp_flags */
+ 	super_doc,				/* tp_doc */
+ 	super_traverse,				/* tp_traverse */
+ 	0,					/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	0,					/* tp_methods */
+	super_members,				/* tp_members */
+	0,					/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	super_descr_get,			/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	super_init,				/* tp_init */
+	PyType_GenericAlloc,			/* tp_alloc */
+	PyType_GenericNew,			/* tp_new */
+	PyObject_GC_Del,        		/* tp_free */
+};

Added: vendor/Python/current/Objects/unicodectype.c
===================================================================
--- vendor/Python/current/Objects/unicodectype.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Objects/unicodectype.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,789 @@
+/*
+   Unicode character type helpers.
+
+   Written by Marc-Andre Lemburg (mal at lemburg.com).
+   Modified for Python 2.0 by Fredrik Lundh (fredrik at pythonware.com)
+
+   Copyright (c) Corporation for National Research Initiatives.
+
+*/
+
+#include "Python.h"
+#include "unicodeobject.h"
+
+#define ALPHA_MASK 0x01
+#define DECIMAL_MASK 0x02
+#define DIGIT_MASK 0x04
+#define LOWER_MASK 0x08
+#define LINEBREAK_MASK 0x10
+#define SPACE_MASK 0x20
+#define TITLE_MASK 0x40
+#define UPPER_MASK 0x80
+
+typedef struct {
+    const Py_UNICODE upper;
+    const Py_UNICODE lower;
+    const Py_UNICODE title;
+    const unsigned char decimal;
+    const unsigned char digit;
+    const unsigned short flags;
+} _PyUnicode_TypeRecord;
+
+#include "unicodetype_db.h"
+
+static const _PyUnicode_TypeRecord *
+gettyperecord(Py_UNICODE code)
+{
+    int index;
+
+#ifdef Py_UNICODE_WIDE
+    if (code >= 0x110000)
+        index = 0;
+    else
+#endif
+    {
+        index = index1[(code>>SHIFT)];
+        index = index2[(index<<SHIFT)+(code&((1<<SHIFT)-1))];
+    }
+
+    return &_PyUnicode_TypeRecords[index];
+}
+
+/* Returns 1 for Unicode characters having the category 'Zl', 'Zp' or
+   type 'B', 0 otherwise. */
+
+int _PyUnicode_IsLinebreak(register const Py_UNICODE ch)
+{
+    switch (ch) {
+    case 0x000A: /* LINE FEED */
+    case 0x000D: /* CARRIAGE RETURN */
+    case 0x001C: /* FILE SEPARATOR */
+    case 0x001D: /* GROUP SEPARATOR */
+    case 0x001E: /* RECORD SEPARATOR */
+    case 0x0085: /* NEXT LINE */
+    case 0x2028: /* LINE SEPARATOR */
+    case 0x2029: /* PARAGRAPH SEPARATOR */
+	return 1;
+    default:
+	return 0;
+    }
+}
+
+/* Returns the titlecase Unicode characters corresponding to ch or just
+   ch if no titlecase mapping is known. */
+
+Py_UNICODE _PyUnicode_ToTitlecase(register Py_UNICODE ch)
+{
+    const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
+    int delta;
+
+    if (ctype->title)
+        delta = ctype->title;
+    else
+	delta = ctype->upper;
+
+    if (delta >= 32768)
+	    delta -= 65536;
+
+    return ch + delta;
+}
+
+/* Returns 1 for Unicode characters having the category 'Lt', 0
+   otherwise. */
+
+int _PyUnicode_IsTitlecase(Py_UNICODE ch)
+{
+    const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
+
+    return (ctype->flags & TITLE_MASK) != 0;
+}
+
+/* Returns the integer decimal (0-9) for Unicode characters having
+   this property, -1 otherwise. */
+
+int _PyUnicode_ToDecimalDigit(Py_UNICODE ch)
+{
+    const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
+
+    return (ctype->flags & DECIMAL_MASK) ? ctype->decimal : -1;
+}
+
+int _PyUnicode_IsDecimalDigit(Py_UNICODE ch)
+{
+    if (_PyUnicode_ToDecimalDigit(ch) < 0)
+	return 0;
+    return 1;
+}
+
+/* Returns the integer digit (0-9) for Unicode characters having
+   this property, -1 otherwise. */
+
+int _PyUnicode_ToDigit(Py_UNICODE ch)
+{
+    const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
+
+    return (ctype->flags & DIGIT_MASK) ? ctype->digit : -1;
+}
+
+int _PyUnicode_IsDigit(Py_UNICODE ch)
+{
+    if (_PyUnicode_ToDigit(ch) < 0)
+	return 0;
+    return 1;
+}
+
+/* Returns the numeric value as double for Unicode characters having
+   this property, -1.0 otherwise. */
+
+/* TODO: replace with unicodetype_db.h table */
+
+double _PyUnicode_ToNumeric(Py_UNICODE ch)
+{
+    switch (ch) {
+    case 0x0F33:
+        return (double) -1 / 2;
+    case 0x17F0:
+    case 0x3007:
+#ifdef Py_UNICODE_WIDE
+    case 0x1018A:
+#endif
+	return (double) 0;
+    case 0x09F4:
+    case 0x17F1:
+    case 0x215F:
+    case 0x2160:
+    case 0x2170:
+    case 0x3021:
+    case 0x3192:
+    case 0x3220:
+    case 0x3280:
+#ifdef Py_UNICODE_WIDE
+    case 0x10107:
+    case 0x10142:
+    case 0x10158:
+    case 0x10159:
+    case 0x1015A:
+    case 0x10320:
+    case 0x103D1:
+#endif
+	return (double) 1;
+    case 0x00BD:
+    case 0x0F2A:
+    case 0x2CFD:
+#ifdef Py_UNICODE_WIDE
+    case 0x10141:
+    case 0x10175:
+    case 0x10176:
+#endif
+	return (double) 1 / 2;
+    case 0x2153:
+	return (double) 1 / 3;
+    case 0x00BC:
+#ifdef Py_UNICODE_WIDE
+    case 0x10140:
+#endif
+	return (double) 1 / 4;
+    case 0x2155:
+	return (double) 1 / 5;
+    case 0x2159:
+	return (double) 1 / 6;
+    case 0x215B:
+	return (double) 1 / 8;
+    case 0x0BF0:
+    case 0x1372:
+    case 0x2169:
+    case 0x2179:
+    case 0x2469:
+    case 0x247D:
+    case 0x2491:
+    case 0x24FE:
+    case 0x277F:
+    case 0x2789:
+    case 0x2793:
+    case 0x3038:
+    case 0x3229:
+    case 0x3289:
+#ifdef Py_UNICODE_WIDE
+    case 0x10110:
+    case 0x10149:
+    case 0x10150:
+    case 0x10157:
+    case 0x10160:
+    case 0x10161:
+    case 0x10162:
+    case 0x10163:
+    case 0x10164:
+    case 0x10322:
+    case 0x103D3:
+    case 0x10A44:
+#endif
+	return (double) 10;
+    case 0x0BF1:
+    case 0x137B:
+    case 0x216D:
+    case 0x217D:
+#ifdef Py_UNICODE_WIDE
+    case 0x10119:
+    case 0x1014B:
+    case 0x10152:
+    case 0x1016A:
+    case 0x103D5:
+    case 0x10A46:
+#endif
+	return (double) 100;
+    case 0x0BF2:
+    case 0x216F:
+    case 0x217F:
+    case 0x2180:
+#ifdef Py_UNICODE_WIDE
+    case 0x10122:
+    case 0x1014D:
+    case 0x10154:
+    case 0x10171:
+    case 0x10A47:
+#endif
+	return (double) 1000;
+    case 0x137C:
+    case 0x2182:
+#ifdef Py_UNICODE_WIDE
+    case 0x1012B:
+    case 0x10155:
+#endif
+	return (double) 10000;
+    case 0x216A:
+    case 0x217A:
+    case 0x246A:
+    case 0x247E:
+    case 0x2492:
+    case 0x24EB:
+	return (double) 11;
+    case 0x0F2F:
+        return (double) 11 / 2;
+    case 0x216B:
+    case 0x217B:
+    case 0x246B:
+    case 0x247F:
+    case 0x2493:
+    case 0x24EC:
+	return (double) 12;
+    case 0x246C:
+    case 0x2480:
+    case 0x2494:
+    case 0x24ED:
+	return (double) 13;
+    case 0x0F30:
+        return (double) 13 / 2;
+    case 0x246D:
+    case 0x2481:
+    case 0x2495:
+    case 0x24EE:
+	return (double) 14;
+    case 0x246E:
+    case 0x2482:
+    case 0x2496:
+    case 0x24EF:
+	return (double) 15;
+    case 0x0F31:
+        return (double) 15 / 2;
+    case 0x09F9:
+    case 0x246F:
+    case 0x2483:
+    case 0x2497:
+    case 0x24F0:
+	return (double) 16;
+    case 0x16EE:
+    case 0x2470:
+    case 0x2484:
+    case 0x2498:
+    case 0x24F1:
+	return (double) 17;
+    case 0x0F32:
+        return (double) 17 / 2;
+    case 0x16EF:
+    case 0x2471:
+    case 0x2485:
+    case 0x2499:
+    case 0x24F2:
+	return (double) 18;
+    case 0x16F0:
+    case 0x2472:
+    case 0x2486:
+    case 0x249A:
+    case 0x24F3:
+	return (double) 19;
+    case 0x09F5:
+    case 0x17F2:
+    case 0x2161:
+    case 0x2171:
+    case 0x3022:
+    case 0x3193:
+    case 0x3221:
+    case 0x3281:
+#ifdef Py_UNICODE_WIDE
+    case 0x10108:
+    case 0x1015B:
+    case 0x1015C:
+    case 0x1015D:
+    case 0x1015E:
+    case 0x103D2:
+#endif
+	return (double) 2;
+    case 0x2154:
+#ifdef Py_UNICODE_WIDE
+    case 0x10177:
+#endif
+	return (double) 2 / 3;
+    case 0x2156:
+        return (double) 2 / 5;
+    case 0x1373:
+    case 0x2473:
+    case 0x2487:
+    case 0x249B:
+    case 0x24F4:
+    case 0x3039:
+#ifdef Py_UNICODE_WIDE
+    case 0x10111:
+    case 0x103D4:
+    case 0x10A45:
+#endif
+        return (double) 20;
+#ifdef Py_UNICODE_WIDE
+    case 0x1011A:
+        return (double) 200;
+    case 0x10123:
+        return (double) 2000;
+    case 0x1012C:
+        return (double) 20000;
+#endif
+    case 0x3251:
+        return (double) 21;
+    case 0x3252:
+        return (double) 22;
+    case 0x3253:
+        return (double) 23;
+    case 0x3254:
+        return (double) 24;
+    case 0x3255:
+        return (double) 25;
+    case 0x3256:
+        return (double) 26;
+    case 0x3257:
+        return (double) 27;
+    case 0x3258:
+        return (double) 28;
+    case 0x3259:
+        return (double) 29;
+    case 0x09F6:
+    case 0x17F3:
+    case 0x2162:
+    case 0x2172:
+    case 0x3023:
+    case 0x3194:
+    case 0x3222:
+    case 0x3282:
+#ifdef Py_UNICODE_WIDE
+    case 0x10109:
+#endif
+	return (double) 3;
+    case 0x0F2B:
+        return (double) 3 / 2;
+    case 0x00BE:
+#ifdef Py_UNICODE_WIDE
+    case 0x10178:
+#endif
+	return (double) 3 / 4;
+    case 0x2157:
+	return (double) 3 / 5;
+    case 0x215C:
+	return (double) 3 / 8;
+    case 0x1374:
+    case 0x303A:
+    case 0x325A:
+#ifdef Py_UNICODE_WIDE
+    case 0x10112:
+    case 0x10165:
+#endif
+	return (double) 30;
+#ifdef Py_UNICODE_WIDE
+    case 0x1011B:
+    case 0x1016B:
+        return (double) 300;
+    case 0x10124:
+        return (double) 3000;
+    case 0x1012D:
+        return (double) 30000;
+#endif
+    case 0x325B:
+        return (double) 31;
+    case 0x325C:
+        return (double) 32;
+    case 0x325D:
+        return (double) 33;
+    case 0x325E:
+        return (double) 34;
+    case 0x325F:
+        return (double) 35;
+    case 0x32B1:
+        return (double) 36;
+    case 0x32B2:
+        return (double) 37;
+    case 0x32B3:
+        return (double) 38;
+    case 0x32B4:
+        return (double) 39;
+    case 0x09F7:
+    case 0x17F4:
+    case 0x2163:
+    case 0x2173:
+    case 0x3024:
+    case 0x3195:
+    case 0x3223:
+    case 0x3283:
+#ifdef Py_UNICODE_WIDE
+    case 0x1010A:
+#endif
+	return (double) 4;
+    case 0x2158:
+	return (double) 4 / 5;
+    case 0x1375:
+    case 0x32B5:
+#ifdef Py_UNICODE_WIDE
+    case 0x10113:
+#endif
+        return (double) 40;
+#ifdef Py_UNICODE_WIDE
+    case 0x1011C:
+        return (double) 400;
+    case 0x10125:
+        return (double) 4000;
+    case 0x1012E:
+        return (double) 40000;
+#endif
+    case 0x32B6:
+        return (double) 41;
+    case 0x32B7:
+        return (double) 42;
+    case 0x32B8:
+        return (double) 43;
+    case 0x32B9:
+        return (double) 44;
+    case 0x32BA:
+        return (double) 45;
+    case 0x32BB:
+        return (double) 46;
+    case 0x32BC:
+        return (double) 47;
+    case 0x32BD:
+        return (double) 48;
+    case 0x32BE:
+        return (double) 49;
+    case 0x17F5:
+    case 0x2164:
+    case 0x2174:
+    case 0x3025:
+    case 0x3224:
+    case 0x3284:
+#ifdef Py_UNICODE_WIDE
+    case 0x1010B:
+    case 0x10143:
+    case 0x10148:
+    case 0x1014F:
+    case 0x1015F:
+    case 0x10173:
+    case 0x10321:
+#endif
+	return (double) 5;
+    case 0x0F2C:
+        return (double) 5 / 2;
+    case 0x215A:
+	return (double) 5 / 6;
+    case 0x215D:
+	return (double) 5 / 8;
+    case 0x1376:
+    case 0x216C:
+    case 0x217C:
+    case 0x32BF:
+#ifdef Py_UNICODE_WIDE
+    case 0x10114:
+    case 0x10144:
+    case 0x1014A:
+    case 0x10151:
+    case 0x10166:
+    case 0x10167:
+    case 0x10168:
+    case 0x10169:
+    case 0x10174:
+    case 0x10323:
+#endif
+	return (double) 50;
+    case 0x216E:
+    case 0x217E:
+#ifdef Py_UNICODE_WIDE
+    case 0x1011D:
+    case 0x10145:
+    case 0x1014C:
+    case 0x10153:
+    case 0x1016C:
+    case 0x1016D:
+    case 0x1016E:
+    case 0x1016F:
+    case 0x10170:
+#endif
+	return (double) 500;
+    case 0x2181:
+#ifdef Py_UNICODE_WIDE
+    case 0x10126:
+    case 0x10146:
+    case 0x1014E:
+    case 0x10172:
+#endif
+	return (double) 5000;
+#ifdef Py_UNICODE_WIDE
+    case 0x1012F:
+    case 0x10147:
+    case 0x10156:
+        return (double) 50000;
+#endif
+    case 0x17F6:
+    case 0x2165:
+    case 0x2175:
+    case 0x3026:
+    case 0x3225:
+    case 0x3285:
+#ifdef Py_UNICODE_WIDE
+    case 0x1010C:
+#endif
+	return (double) 6;
+    case 0x1377:
+#ifdef Py_UNICODE_WIDE
+    case 0x10115:
+#endif
+	return (double) 60;
+#ifdef Py_UNICODE_WIDE
+    case 0x1011E:
+        return (double) 600;
+    case 0x10127:
+        return (double) 6000;
+    case 0x10130:
+        return (double) 60000;
+#endif
+    case 0x17F7:
+    case 0x2166:
+    case 0x2176:
+    case 0x3027:
+    case 0x3226:
+    case 0x3286:
+#ifdef Py_UNICODE_WIDE
+    case 0x1010D:
+#endif
+	return (double) 7;
+    case 0x0F2D:
+        return (double) 7 / 2;
+    case 0x215E:
+	return (double) 7 / 8;
+    case 0x1378:
+#ifdef Py_UNICODE_WIDE
+    case 0x10116:
+#endif
+	return (double) 70;
+#ifdef Py_UNICODE_WIDE
+    case 0x1011F:
+        return (double) 700;
+    case 0x10128:
+        return (double) 7000;
+    case 0x10131:
+        return (double) 70000;
+#endif
+    case 0x17F8:
+    case 0x2167:
+    case 0x2177:
+    case 0x3028:
+    case 0x3227:
+    case 0x3287:
+#ifdef Py_UNICODE_WIDE
+    case 0x1010E:
+#endif
+	return (double) 8;
+    case 0x1379:
+#ifdef Py_UNICODE_WIDE
+    case 0x10117:
+#endif
+	return (double) 80;
+#ifdef Py_UNICODE_WIDE
+    case 0x10120:
+        return (double) 800;
+    case 0x10129:
+        return (double) 8000;
+    case 0x10132:
+        return (double) 80000;
+#endif
+    case 0x17F9:
+    case 0x2168:
+    case 0x2178:
+    case 0x3029:
+    case 0x3228:
+    case 0x3288:
+#ifdef Py_UNICODE_WIDE
+    case 0x1010F:
+#endif
+	return (double) 9;
+    case 0x0F2E:
+        return (double) 9 / 2;
+    case 0x137A:
+#ifdef Py_UNICODE_WIDE
+    case 0x10118:
+#endif
+	return (double) 90;
+#ifdef Py_UNICODE_WIDE
+    case 0x10121:
+    case 0x1034A:
+        return (double) 900;
+    case 0x1012A:
+        return (double) 9000;
+    case 0x10133:
+        return (double) 90000;
+#endif
+    default:
+	return (double) _PyUnicode_ToDigit(ch);
+    }
+}
+
+int _PyUnicode_IsNumeric(Py_UNICODE ch)
+{
+    return _PyUnicode_ToNumeric(ch) != -1.0;
+}
+
+#ifndef WANT_WCTYPE_FUNCTIONS
+
+/* Returns 1 for Unicode characters having the bidirectional type
+   'WS', 'B' or 'S' or the category 'Zs', 0 otherwise. */
+
+int _PyUnicode_IsWhitespace(register const Py_UNICODE ch)
+{
+    switch (ch) {
+    case 0x0009: /* HORIZONTAL TABULATION */
+    case 0x000A: /* LINE FEED */
+    case 0x000B: /* VERTICAL TABULATION */
+    case 0x000C: /* FORM FEED */
+    case 0x000D: /* CARRIAGE RETURN */
+    case 0x001C: /* FILE SEPARATOR */
+    case 0x001D: /* GROUP SEPARATOR */
+    case 0x001E: /* RECORD SEPARATOR */
+    case 0x001F: /* UNIT SEPARATOR */
+    case 0x0020: /* SPACE */
+    case 0x0085: /* NEXT LINE */
+    case 0x00A0: /* NO-BREAK SPACE */
+    case 0x1680: /* OGHAM SPACE MARK */
+    case 0x2000: /* EN QUAD */
+    case 0x2001: /* EM QUAD */
+    case 0x2002: /* EN SPACE */
+    case 0x2003: /* EM SPACE */
+    case 0x2004: /* THREE-PER-EM SPACE */
+    case 0x2005: /* FOUR-PER-EM SPACE */
+    case 0x2006: /* SIX-PER-EM SPACE */
+    case 0x2007: /* FIGURE SPACE */
+    case 0x2008: /* PUNCTUATION SPACE */
+    case 0x2009: /* THIN SPACE */
+    case 0x200A: /* HAIR SPACE */
+    case 0x200B: /* ZERO WIDTH SPACE */
+    case 0x2028: /* LINE SEPARATOR */
+    case 0x2029: /* PARAGRAPH SEPARATOR */
+    case 0x202F: /* NARROW NO-BREAK SPACE */
+    case 0x205F: /* MEDIUM MATHEMATICAL SPACE */
+    case 0x3000: /* IDEOGRAPHIC SPACE */
+	return 1;
+    default:
+	return 0;
+    }
+}
+
+/* Returns 1 for Unicode characters having the category 'Ll', 0
+   otherwise. */
+
+int _PyUnicode_IsLowercase(Py_UNICODE ch)
+{
+    const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
+
+    return (ctype->flags & LOWER_MASK) != 0;
+}
+
+/* Returns 1 for Unicode characters having the category 'Lu', 0
+   otherwise. */
+
+int _PyUnicode_IsUppercase(Py_UNICODE ch)
+{
+    const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
+
+    return (ctype->flags & UPPER_MASK) != 0;
+}
+
+/* Returns the uppercase Unicode characters corresponding to ch or just
+   ch if no uppercase mapping is known. */
+
+Py_UNICODE _PyUnicode_ToUppercase(Py_UNICODE ch)
+{
+    const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
+    int delta = ctype->upper;
+    if (delta >= 32768)
+	    delta -= 65536;
+    return ch + delta;
+}
+
+/* Returns the lowercase Unicode characters corresponding to ch or just
+   ch if no lowercase mapping is known. */
+
+Py_UNICODE _PyUnicode_ToLowercase(Py_UNICODE ch)
+{
+    const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
+    int delta = ctype->lower;
+    if (delta >= 32768)
+	    delta -= 65536;
+    return ch + delta;
+}
+
+/* Returns 1 for Unicode characters having the category 'Ll', 'Lu', 'Lt',
+   'Lo' or 'Lm',  0 otherwise. */
+
+int _PyUnicode_IsAlpha(Py_UNICODE ch)
+{
+    const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
+
+    return (ctype->flags & ALPHA_MASK) != 0;
+}
+
+#else
+
+/* Export the interfaces using the wchar_t type for portability
+   reasons:  */
+
+int _PyUnicode_IsWhitespace(Py_UNICODE ch)
+{
+    return iswspace(ch);
+}
+
+int _PyUnicode_IsLowercase(Py_UNICODE ch)
+{
+    return iswlower(ch);
+}
+
+int _PyUnicode_IsUppercase(Py_UNICODE ch)
+{
+    return iswupper(ch);
+}
+
+Py_UNICODE _PyUnicode_ToLowercase(Py_UNICODE ch)
+{
+    return towlower(ch);
+}
+
+Py_UNICODE _PyUnicode_ToUppercase(Py_UNICODE ch)
+{
+    return towupper(ch);
+}
+
+int _PyUnicode_IsAlpha(Py_UNICODE ch)
+{
+    return iswalpha(ch);
+}
+
+#endif

Added: vendor/Python/current/Objects/unicodeobject.c
===================================================================
--- vendor/Python/current/Objects/unicodeobject.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Objects/unicodeobject.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,8067 @@
+/*
+
+Unicode implementation based on original code by Fredrik Lundh,
+modified by Marc-Andre Lemburg <mal at lemburg.com> according to the
+Unicode Integration Proposal (see file Misc/unicode.txt).
+
+Major speed upgrades to the method implementations at the Reykjavik
+NeedForSpeed sprint, by Fredrik Lundh and Andrew Dalke.
+
+Copyright (c) Corporation for National Research Initiatives.
+
+--------------------------------------------------------------------
+The original string type implementation is:
+
+    Copyright (c) 1999 by Secret Labs AB
+    Copyright (c) 1999 by Fredrik Lundh
+
+By obtaining, using, and/or copying this software and/or its
+associated documentation, you agree that you have read, understood,
+and will comply with the following terms and conditions:
+
+Permission to use, copy, modify, and distribute this software and its
+associated documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appears in all
+copies, and that both that copyright notice and this permission notice
+appear in supporting documentation, and that the name of Secret Labs
+AB or the author not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO
+THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS.  IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+--------------------------------------------------------------------
+
+*/
+
+#define PY_SSIZE_T_CLEAN
+#include "Python.h"
+
+#include "unicodeobject.h"
+#include "ucnhash.h"
+
+#ifdef MS_WINDOWS
+#include <windows.h>
+#endif
+
+/* Limit for the Unicode object free list */
+
+#define MAX_UNICODE_FREELIST_SIZE       1024
+
+/* Limit for the Unicode object free list stay alive optimization.
+
+   The implementation will keep allocated Unicode memory intact for
+   all objects on the free list having a size less than this
+   limit. This reduces malloc() overhead for small Unicode objects.
+
+   At worst this will result in MAX_UNICODE_FREELIST_SIZE *
+   (sizeof(PyUnicodeObject) + KEEPALIVE_SIZE_LIMIT +
+   malloc()-overhead) bytes of unused garbage.
+
+   Setting the limit to 0 effectively turns the feature off.
+
+   Note: This is an experimental feature ! If you get core dumps when
+   using Unicode objects, turn this feature off.
+
+*/
+
+#define KEEPALIVE_SIZE_LIMIT       9
+
+/* Endianness switches; defaults to little endian */
+
+#ifdef WORDS_BIGENDIAN
+# define BYTEORDER_IS_BIG_ENDIAN
+#else
+# define BYTEORDER_IS_LITTLE_ENDIAN
+#endif
+
+/* --- Globals ------------------------------------------------------------
+
+   The globals are initialized by the _PyUnicode_Init() API and should
+   not be used before calling that API.
+
+*/
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Free list for Unicode objects */
+static PyUnicodeObject *unicode_freelist;
+static int unicode_freelist_size;
+
+/* The empty Unicode object is shared to improve performance. */
+static PyUnicodeObject *unicode_empty;
+
+/* Single character Unicode strings in the Latin-1 range are being
+   shared as well. */
+static PyUnicodeObject *unicode_latin1[256];
+
+/* Default encoding to use and assume when NULL is passed as encoding
+   parameter; it is initialized by _PyUnicode_Init().
+
+   Always use the PyUnicode_SetDefaultEncoding() and
+   PyUnicode_GetDefaultEncoding() APIs to access this global.
+
+*/
+static char unicode_default_encoding[100];
+
+Py_UNICODE
+PyUnicode_GetMax(void)
+{
+#ifdef Py_UNICODE_WIDE
+	return 0x10FFFF;
+#else
+	/* This is actually an illegal character, so it should
+	   not be passed to unichr. */
+	return 0xFFFF;
+#endif
+}
+
+/* --- Bloom Filters ----------------------------------------------------- */
+
+/* stuff to implement simple "bloom filters" for Unicode characters.
+   to keep things simple, we use a single bitmask, using the least 5
+   bits from each unicode characters as the bit index. */
+
+/* the linebreak mask is set up by Unicode_Init below */
+
+#define BLOOM_MASK unsigned long
+
+static BLOOM_MASK bloom_linebreak;
+
+#define BLOOM(mask, ch) ((mask & (1 << ((ch) & 0x1F))))
+
+#define BLOOM_LINEBREAK(ch)\
+    (BLOOM(bloom_linebreak, (ch)) && Py_UNICODE_ISLINEBREAK((ch)))
+
+Py_LOCAL_INLINE(BLOOM_MASK) make_bloom_mask(Py_UNICODE* ptr, Py_ssize_t len)
+{
+    /* calculate simple bloom-style bitmask for a given unicode string */
+
+    long mask;
+    Py_ssize_t i;
+
+    mask = 0;
+    for (i = 0; i < len; i++)
+        mask |= (1 << (ptr[i] & 0x1F));
+
+    return mask;
+}
+
+Py_LOCAL_INLINE(int) unicode_member(Py_UNICODE chr, Py_UNICODE* set, Py_ssize_t setlen)
+{
+    Py_ssize_t i;
+
+    for (i = 0; i < setlen; i++)
+        if (set[i] == chr)
+            return 1;
+
+    return 0;
+}
+
+#define BLOOM_MEMBER(mask, chr, set, setlen)\
+    BLOOM(mask, chr) && unicode_member(chr, set, setlen)
+
+/* --- Unicode Object ----------------------------------------------------- */
+
+static
+int unicode_resize(register PyUnicodeObject *unicode,
+                      Py_ssize_t length)
+{
+    void *oldstr;
+
+    /* Shortcut if there's nothing much to do. */
+    if (unicode->length == length)
+	goto reset;
+
+    /* Resizing shared object (unicode_empty or single character
+       objects) in-place is not allowed. Use PyUnicode_Resize()
+       instead ! */
+
+    if (unicode == unicode_empty || 
+	(unicode->length == 1 && 
+	 unicode->str[0] < 256U &&
+	 unicode_latin1[unicode->str[0]] == unicode)) {
+        PyErr_SetString(PyExc_SystemError,
+                        "can't resize shared unicode objects");
+        return -1;
+    }
+
+    /* We allocate one more byte to make sure the string is Ux0000 terminated.
+       The overallocation is also used by fastsearch, which assumes that it's
+       safe to look at str[length] (without making any assumptions about what
+       it contains). */
+
+    oldstr = unicode->str;
+    PyMem_RESIZE(unicode->str, Py_UNICODE, length + 1);
+    if (!unicode->str) {
+	unicode->str = (Py_UNICODE *)oldstr;
+        PyErr_NoMemory();
+        return -1;
+    }
+    unicode->str[length] = 0;
+    unicode->length = length;
+
+ reset:
+    /* Reset the object caches */
+    if (unicode->defenc) {
+        Py_DECREF(unicode->defenc);
+        unicode->defenc = NULL;
+    }
+    unicode->hash = -1;
+
+    return 0;
+}
+
+/* We allocate one more byte to make sure the string is
+   Ux0000 terminated -- XXX is this needed ?
+
+   XXX This allocator could further be enhanced by assuring that the
+       free list never reduces its size below 1.
+
+*/
+
+static
+PyUnicodeObject *_PyUnicode_New(Py_ssize_t length)
+{
+    register PyUnicodeObject *unicode;
+
+    /* Optimization for empty strings */
+    if (length == 0 && unicode_empty != NULL) {
+        Py_INCREF(unicode_empty);
+        return unicode_empty;
+    }
+
+    /* Unicode freelist & memory allocation */
+    if (unicode_freelist) {
+        unicode = unicode_freelist;
+        unicode_freelist = *(PyUnicodeObject **)unicode;
+        unicode_freelist_size--;
+	if (unicode->str) {
+	    /* Keep-Alive optimization: we only upsize the buffer,
+	       never downsize it. */
+	    if ((unicode->length < length) &&
+                unicode_resize(unicode, length) < 0) {
+		PyMem_DEL(unicode->str);
+		goto onError;
+	    }
+	}
+        else {
+	    unicode->str = PyMem_NEW(Py_UNICODE, length + 1);
+        }
+        PyObject_INIT(unicode, &PyUnicode_Type);
+    }
+    else {
+        unicode = PyObject_New(PyUnicodeObject, &PyUnicode_Type);
+        if (unicode == NULL)
+            return NULL;
+	unicode->str = PyMem_NEW(Py_UNICODE, length + 1);
+    }
+
+    if (!unicode->str) {
+	PyErr_NoMemory();
+	goto onError;
+    }
+    /* Initialize the first element to guard against cases where
+     * the caller fails before initializing str -- unicode_resize()
+     * reads str[0], and the Keep-Alive optimization can keep memory
+     * allocated for str alive across a call to unicode_dealloc(unicode).
+     * We don't want unicode_resize to read uninitialized memory in
+     * that case.
+     */
+    unicode->str[0] = 0;
+    unicode->str[length] = 0;
+    unicode->length = length;
+    unicode->hash = -1;
+    unicode->defenc = NULL;
+    return unicode;
+
+ onError:
+    _Py_ForgetReference((PyObject *)unicode);
+    PyObject_Del(unicode);
+    return NULL;
+}
+
+static
+void unicode_dealloc(register PyUnicodeObject *unicode)
+{
+    if (PyUnicode_CheckExact(unicode) &&
+	unicode_freelist_size < MAX_UNICODE_FREELIST_SIZE) {
+        /* Keep-Alive optimization */
+	if (unicode->length >= KEEPALIVE_SIZE_LIMIT) {
+	    PyMem_DEL(unicode->str);
+	    unicode->str = NULL;
+	    unicode->length = 0;
+	}
+	if (unicode->defenc) {
+	    Py_DECREF(unicode->defenc);
+	    unicode->defenc = NULL;
+	}
+	/* Add to free list */
+        *(PyUnicodeObject **)unicode = unicode_freelist;
+        unicode_freelist = unicode;
+        unicode_freelist_size++;
+    }
+    else {
+	PyMem_DEL(unicode->str);
+	Py_XDECREF(unicode->defenc);
+	unicode->ob_type->tp_free((PyObject *)unicode);
+    }
+}
+
+int PyUnicode_Resize(PyObject **unicode, Py_ssize_t length)
+{
+    register PyUnicodeObject *v;
+
+    /* Argument checks */
+    if (unicode == NULL) {
+	PyErr_BadInternalCall();
+	return -1;
+    }
+    v = (PyUnicodeObject *)*unicode;
+    if (v == NULL || !PyUnicode_Check(v) || v->ob_refcnt != 1 || length < 0) {
+	PyErr_BadInternalCall();
+	return -1;
+    }
+
+    /* Resizing unicode_empty and single character objects is not
+       possible since these are being shared. We simply return a fresh
+       copy with the same Unicode content. */
+    if (v->length != length &&
+	(v == unicode_empty || v->length == 1)) {
+	PyUnicodeObject *w = _PyUnicode_New(length);
+	if (w == NULL)
+	    return -1;
+	Py_UNICODE_COPY(w->str, v->str,
+			length < v->length ? length : v->length);
+	Py_DECREF(*unicode);
+	*unicode = (PyObject *)w;
+	return 0;
+    }
+
+    /* Note that we don't have to modify *unicode for unshared Unicode
+       objects, since we can modify them in-place. */
+    return unicode_resize(v, length);
+}
+
+/* Internal API for use in unicodeobject.c only ! */
+#define _PyUnicode_Resize(unicodevar, length) \
+        PyUnicode_Resize(((PyObject **)(unicodevar)), length)
+
+PyObject *PyUnicode_FromUnicode(const Py_UNICODE *u,
+				Py_ssize_t size)
+{
+    PyUnicodeObject *unicode;
+
+    /* If the Unicode data is known at construction time, we can apply
+       some optimizations which share commonly used objects. */
+    if (u != NULL) {
+
+	/* Optimization for empty strings */
+	if (size == 0 && unicode_empty != NULL) {
+	    Py_INCREF(unicode_empty);
+	    return (PyObject *)unicode_empty;
+	}
+
+	/* Single character Unicode objects in the Latin-1 range are
+	   shared when using this constructor */
+	if (size == 1 && *u < 256) {
+	    unicode = unicode_latin1[*u];
+	    if (!unicode) {
+		unicode = _PyUnicode_New(1);
+		if (!unicode)
+		    return NULL;
+		unicode->str[0] = *u;
+		unicode_latin1[*u] = unicode;
+	    }
+	    Py_INCREF(unicode);
+	    return (PyObject *)unicode;
+	}
+    }
+
+    unicode = _PyUnicode_New(size);
+    if (!unicode)
+        return NULL;
+
+    /* Copy the Unicode data into the new object */
+    if (u != NULL)
+	Py_UNICODE_COPY(unicode->str, u, size);
+
+    return (PyObject *)unicode;
+}
+
+#ifdef HAVE_WCHAR_H
+
+PyObject *PyUnicode_FromWideChar(register const wchar_t *w,
+				 Py_ssize_t size)
+{
+    PyUnicodeObject *unicode;
+
+    if (w == NULL) {
+	PyErr_BadInternalCall();
+	return NULL;
+    }
+
+    unicode = _PyUnicode_New(size);
+    if (!unicode)
+        return NULL;
+
+    /* Copy the wchar_t data into the new object */
+#ifdef HAVE_USABLE_WCHAR_T
+    memcpy(unicode->str, w, size * sizeof(wchar_t));
+#else
+    {
+	register Py_UNICODE *u;
+	register Py_ssize_t i;
+	u = PyUnicode_AS_UNICODE(unicode);
+	for (i = size; i > 0; i--)
+	    *u++ = *w++;
+    }
+#endif
+
+    return (PyObject *)unicode;
+}
+
+Py_ssize_t PyUnicode_AsWideChar(PyUnicodeObject *unicode,
+				wchar_t *w,
+				Py_ssize_t size)
+{
+    if (unicode == NULL) {
+	PyErr_BadInternalCall();
+	return -1;
+    }
+
+    /* If possible, try to copy the 0-termination as well */
+    if (size > PyUnicode_GET_SIZE(unicode))
+	size = PyUnicode_GET_SIZE(unicode) + 1;
+
+#ifdef HAVE_USABLE_WCHAR_T
+    memcpy(w, unicode->str, size * sizeof(wchar_t));
+#else
+    {
+	register Py_UNICODE *u;
+	register Py_ssize_t i;
+	u = PyUnicode_AS_UNICODE(unicode);
+	for (i = size; i > 0; i--)
+	    *w++ = *u++;
+    }
+#endif
+
+    if (size > PyUnicode_GET_SIZE(unicode))
+        return PyUnicode_GET_SIZE(unicode);
+    else
+    return size;
+}
+
+#endif
+
+PyObject *PyUnicode_FromOrdinal(int ordinal)
+{
+    Py_UNICODE s[1];
+
+#ifdef Py_UNICODE_WIDE
+    if (ordinal < 0 || ordinal > 0x10ffff) {
+	PyErr_SetString(PyExc_ValueError,
+			"unichr() arg not in range(0x110000) "
+			"(wide Python build)");
+	return NULL;
+    }
+#else
+    if (ordinal < 0 || ordinal > 0xffff) {
+	PyErr_SetString(PyExc_ValueError,
+			"unichr() arg not in range(0x10000) "
+			"(narrow Python build)");
+	return NULL;
+    }
+#endif
+
+    s[0] = (Py_UNICODE)ordinal;
+    return PyUnicode_FromUnicode(s, 1);
+}
+
+PyObject *PyUnicode_FromObject(register PyObject *obj)
+{
+    /* XXX Perhaps we should make this API an alias of
+           PyObject_Unicode() instead ?! */
+    if (PyUnicode_CheckExact(obj)) {
+	Py_INCREF(obj);
+	return obj;
+    }
+    if (PyUnicode_Check(obj)) {
+	/* For a Unicode subtype that's not a Unicode object,
+	   return a true Unicode object with the same data. */
+	return PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(obj),
+				     PyUnicode_GET_SIZE(obj));
+    }
+    return PyUnicode_FromEncodedObject(obj, NULL, "strict");
+}
+
+PyObject *PyUnicode_FromEncodedObject(register PyObject *obj,
+				      const char *encoding,
+				      const char *errors)
+{
+    const char *s = NULL;
+    Py_ssize_t len;
+    PyObject *v;
+
+    if (obj == NULL) {
+	PyErr_BadInternalCall();
+	return NULL;
+    }
+
+#if 0
+    /* For b/w compatibility we also accept Unicode objects provided
+       that no encodings is given and then redirect to
+       PyObject_Unicode() which then applies the additional logic for
+       Unicode subclasses.
+
+       NOTE: This API should really only be used for object which
+             represent *encoded* Unicode !
+
+    */
+	if (PyUnicode_Check(obj)) {
+	    if (encoding) {
+		PyErr_SetString(PyExc_TypeError,
+				"decoding Unicode is not supported");
+	    return NULL;
+	    }
+	return PyObject_Unicode(obj);
+	    }
+#else
+    if (PyUnicode_Check(obj)) {
+	PyErr_SetString(PyExc_TypeError,
+			"decoding Unicode is not supported");
+	return NULL;
+	}
+#endif
+
+    /* Coerce object */
+    if (PyString_Check(obj)) {
+	    s = PyString_AS_STRING(obj);
+	    len = PyString_GET_SIZE(obj);
+	    }
+    else if (PyObject_AsCharBuffer(obj, &s, &len)) {
+	/* Overwrite the error message with something more useful in
+	   case of a TypeError. */
+	if (PyErr_ExceptionMatches(PyExc_TypeError))
+	PyErr_Format(PyExc_TypeError,
+			 "coercing to Unicode: need string or buffer, "
+			 "%.80s found",
+		     obj->ob_type->tp_name);
+	goto onError;
+    }
+
+    /* Convert to Unicode */
+    if (len == 0) {
+	Py_INCREF(unicode_empty);
+	v = (PyObject *)unicode_empty;
+    }
+    else
+	v = PyUnicode_Decode(s, len, encoding, errors);
+
+    return v;
+
+ onError:
+    return NULL;
+}
+
+PyObject *PyUnicode_Decode(const char *s,
+			   Py_ssize_t size,
+			   const char *encoding,
+			   const char *errors)
+{
+    PyObject *buffer = NULL, *unicode;
+
+    if (encoding == NULL)
+	encoding = PyUnicode_GetDefaultEncoding();
+
+    /* Shortcuts for common default encodings */
+    if (strcmp(encoding, "utf-8") == 0)
+        return PyUnicode_DecodeUTF8(s, size, errors);
+    else if (strcmp(encoding, "latin-1") == 0)
+        return PyUnicode_DecodeLatin1(s, size, errors);
+#if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T)
+    else if (strcmp(encoding, "mbcs") == 0)
+        return PyUnicode_DecodeMBCS(s, size, errors);
+#endif
+    else if (strcmp(encoding, "ascii") == 0)
+        return PyUnicode_DecodeASCII(s, size, errors);
+
+    /* Decode via the codec registry */
+    buffer = PyBuffer_FromMemory((void *)s, size);
+    if (buffer == NULL)
+        goto onError;
+    unicode = PyCodec_Decode(buffer, encoding, errors);
+    if (unicode == NULL)
+        goto onError;
+    if (!PyUnicode_Check(unicode)) {
+        PyErr_Format(PyExc_TypeError,
+                     "decoder did not return an unicode object (type=%.400s)",
+                     unicode->ob_type->tp_name);
+        Py_DECREF(unicode);
+        goto onError;
+    }
+    Py_DECREF(buffer);
+    return unicode;
+
+ onError:
+    Py_XDECREF(buffer);
+    return NULL;
+}
+
+PyObject *PyUnicode_AsDecodedObject(PyObject *unicode,
+                                    const char *encoding,
+                                    const char *errors)
+{
+    PyObject *v;
+
+    if (!PyUnicode_Check(unicode)) {
+        PyErr_BadArgument();
+        goto onError;
+    }
+
+    if (encoding == NULL)
+	encoding = PyUnicode_GetDefaultEncoding();
+
+    /* Decode via the codec registry */
+    v = PyCodec_Decode(unicode, encoding, errors);
+    if (v == NULL)
+        goto onError;
+    return v;
+
+ onError:
+    return NULL;
+}
+
+PyObject *PyUnicode_Encode(const Py_UNICODE *s,
+			   Py_ssize_t size,
+			   const char *encoding,
+			   const char *errors)
+{
+    PyObject *v, *unicode;
+
+    unicode = PyUnicode_FromUnicode(s, size);
+    if (unicode == NULL)
+	return NULL;
+    v = PyUnicode_AsEncodedString(unicode, encoding, errors);
+    Py_DECREF(unicode);
+    return v;
+}
+
+PyObject *PyUnicode_AsEncodedObject(PyObject *unicode,
+                                    const char *encoding,
+                                    const char *errors)
+{
+    PyObject *v;
+
+    if (!PyUnicode_Check(unicode)) {
+        PyErr_BadArgument();
+        goto onError;
+    }
+
+    if (encoding == NULL)
+	encoding = PyUnicode_GetDefaultEncoding();
+
+    /* Encode via the codec registry */
+    v = PyCodec_Encode(unicode, encoding, errors);
+    if (v == NULL)
+        goto onError;
+    return v;
+
+ onError:
+    return NULL;
+}
+
+PyObject *PyUnicode_AsEncodedString(PyObject *unicode,
+                                    const char *encoding,
+                                    const char *errors)
+{
+    PyObject *v;
+
+    if (!PyUnicode_Check(unicode)) {
+        PyErr_BadArgument();
+        goto onError;
+    }
+
+    if (encoding == NULL)
+	encoding = PyUnicode_GetDefaultEncoding();
+
+    /* Shortcuts for common default encodings */
+    if (errors == NULL) {
+	if (strcmp(encoding, "utf-8") == 0)
+	    return PyUnicode_AsUTF8String(unicode);
+	else if (strcmp(encoding, "latin-1") == 0)
+	    return PyUnicode_AsLatin1String(unicode);
+#if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T)
+	else if (strcmp(encoding, "mbcs") == 0)
+	    return PyUnicode_AsMBCSString(unicode);
+#endif
+	else if (strcmp(encoding, "ascii") == 0)
+	    return PyUnicode_AsASCIIString(unicode);
+    }
+
+    /* Encode via the codec registry */
+    v = PyCodec_Encode(unicode, encoding, errors);
+    if (v == NULL)
+        goto onError;
+    if (!PyString_Check(v)) {
+        PyErr_Format(PyExc_TypeError,
+                     "encoder did not return a string object (type=%.400s)",
+                     v->ob_type->tp_name);
+        Py_DECREF(v);
+        goto onError;
+    }
+    return v;
+
+ onError:
+    return NULL;
+}
+
+PyObject *_PyUnicode_AsDefaultEncodedString(PyObject *unicode,
+					    const char *errors)
+{
+    PyObject *v = ((PyUnicodeObject *)unicode)->defenc;
+
+    if (v)
+        return v;
+    v = PyUnicode_AsEncodedString(unicode, NULL, errors);
+    if (v && errors == NULL)
+        ((PyUnicodeObject *)unicode)->defenc = v;
+    return v;
+}
+
+Py_UNICODE *PyUnicode_AsUnicode(PyObject *unicode)
+{
+    if (!PyUnicode_Check(unicode)) {
+        PyErr_BadArgument();
+        goto onError;
+    }
+    return PyUnicode_AS_UNICODE(unicode);
+
+ onError:
+    return NULL;
+}
+
+Py_ssize_t PyUnicode_GetSize(PyObject *unicode)
+{
+    if (!PyUnicode_Check(unicode)) {
+        PyErr_BadArgument();
+        goto onError;
+    }
+    return PyUnicode_GET_SIZE(unicode);
+
+ onError:
+    return -1;
+}
+
+const char *PyUnicode_GetDefaultEncoding(void)
+{
+    return unicode_default_encoding;
+}
+
+int PyUnicode_SetDefaultEncoding(const char *encoding)
+{
+    PyObject *v;
+
+    /* Make sure the encoding is valid. As side effect, this also
+       loads the encoding into the codec registry cache. */
+    v = _PyCodec_Lookup(encoding);
+    if (v == NULL)
+	goto onError;
+    Py_DECREF(v);
+    strncpy(unicode_default_encoding,
+	    encoding,
+	    sizeof(unicode_default_encoding));
+    return 0;
+
+ onError:
+    return -1;
+}
+
+/* error handling callback helper:
+   build arguments, call the callback and check the arguments,
+   if no exception occurred, copy the replacement to the output
+   and adjust various state variables.
+   return 0 on success, -1 on error
+*/
+
+static
+int unicode_decode_call_errorhandler(const char *errors, PyObject **errorHandler,
+                 const char *encoding, const char *reason,
+                 const char *input, Py_ssize_t insize, Py_ssize_t *startinpos, Py_ssize_t *endinpos, PyObject **exceptionObject, const char **inptr,
+                 PyObject **output, Py_ssize_t *outpos, Py_UNICODE **outptr)
+{
+    static char *argparse = "O!n;decoding error handler must return (unicode, int) tuple";
+
+    PyObject *restuple = NULL;
+    PyObject *repunicode = NULL;
+    Py_ssize_t outsize = PyUnicode_GET_SIZE(*output);
+    Py_ssize_t requiredsize;
+    Py_ssize_t newpos;
+    Py_UNICODE *repptr;
+    Py_ssize_t repsize;
+    int res = -1;
+
+    if (*errorHandler == NULL) {
+	*errorHandler = PyCodec_LookupError(errors);
+	if (*errorHandler == NULL)
+	   goto onError;
+    }
+
+    if (*exceptionObject == NULL) {
+    	*exceptionObject = PyUnicodeDecodeError_Create(
+	    encoding, input, insize, *startinpos, *endinpos, reason);
+	if (*exceptionObject == NULL)
+	   goto onError;
+    }
+    else {
+	if (PyUnicodeDecodeError_SetStart(*exceptionObject, *startinpos))
+	    goto onError;
+	if (PyUnicodeDecodeError_SetEnd(*exceptionObject, *endinpos))
+	    goto onError;
+	if (PyUnicodeDecodeError_SetReason(*exceptionObject, reason))
+	    goto onError;
+    }
+
+    restuple = PyObject_CallFunctionObjArgs(*errorHandler, *exceptionObject, NULL);
+    if (restuple == NULL)
+	goto onError;
+    if (!PyTuple_Check(restuple)) {
+	PyErr_Format(PyExc_TypeError, &argparse[4]);
+	goto onError;
+    }
+    if (!PyArg_ParseTuple(restuple, argparse, &PyUnicode_Type, &repunicode, &newpos))
+	goto onError;
+    if (newpos<0)
+	newpos = insize+newpos;
+    if (newpos<0 || newpos>insize) {
+	PyErr_Format(PyExc_IndexError, "position %zd from error handler out of bounds", newpos);
+	goto onError;
+    }
+
+    /* need more space? (at least enough for what we
+       have+the replacement+the rest of the string (starting
+       at the new input position), so we won't have to check space
+       when there are no errors in the rest of the string) */
+    repptr = PyUnicode_AS_UNICODE(repunicode);
+    repsize = PyUnicode_GET_SIZE(repunicode);
+    requiredsize = *outpos + repsize + insize-newpos;
+    if (requiredsize > outsize) {
+	if (requiredsize<2*outsize)
+	    requiredsize = 2*outsize;
+	if (PyUnicode_Resize(output, requiredsize) < 0)
+	    goto onError;
+	*outptr = PyUnicode_AS_UNICODE(*output) + *outpos;
+    }
+    *endinpos = newpos;
+    *inptr = input + newpos;
+    Py_UNICODE_COPY(*outptr, repptr, repsize);
+    *outptr += repsize;
+    *outpos += repsize;
+    /* we made it! */
+    res = 0;
+
+    onError:
+    Py_XDECREF(restuple);
+    return res;
+}
+
+/* --- UTF-7 Codec -------------------------------------------------------- */
+
+/* see RFC2152 for details */
+
+static
+char utf7_special[128] = {
+    /* indicate whether a UTF-7 character is special i.e. cannot be directly
+       encoded:
+	   0 - not special
+	   1 - special
+	   2 - whitespace (optional)
+	   3 - RFC2152 Set O (optional) */
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 2, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    2, 3, 3, 3, 3, 3, 3, 0, 0, 0, 3, 1, 0, 0, 0, 1,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0,
+    3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 3, 3, 3,
+    3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 1, 1,
+
+};
+
+/* Note: The comparison (c) <= 0 is a trick to work-around gcc
+   warnings about the comparison always being false; since
+   utf7_special[0] is 1, we can safely make that one comparison
+   true  */
+
+#define SPECIAL(c, encodeO, encodeWS) \
+    ((c) > 127 || (c) <= 0 || utf7_special[(c)] == 1 || \
+     (encodeWS && (utf7_special[(c)] == 2)) || \
+     (encodeO && (utf7_special[(c)] == 3)))
+
+#define B64(n)  \
+    ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(n) & 0x3f])
+#define B64CHAR(c) \
+    (isalnum(c) || (c) == '+' || (c) == '/')
+#define UB64(c) \
+    ((c) == '+' ? 62 : (c) == '/' ? 63 : (c) >= 'a' ?                   \
+     (c) - 71 : (c) >= 'A' ? (c) - 65 : (c) + 4 )
+
+#define ENCODE(out, ch, bits)                   \
+    while (bits >= 6) {                         \
+        *out++ = B64(ch >> (bits-6));           \
+        bits -= 6;                              \
+    }
+
+#define DECODE(out, ch, bits, surrogate)                                \
+    while (bits >= 16) {                                                \
+        Py_UNICODE outCh = (Py_UNICODE) ((ch >> (bits-16)) & 0xffff);   \
+        bits -= 16;                                                     \
+        if (surrogate) {                                                \
+            /* We have already generated an error for the high surrogate \
+               so let's not bother seeing if the low surrogate is correct or not */ \
+            surrogate = 0;                                              \
+        } else if (0xDC00 <= outCh && outCh <= 0xDFFF) {                \
+            /* This is a surrogate pair. Unfortunately we can't represent \
+               it in a 16-bit character */                              \
+            surrogate = 1;                                              \
+            errmsg = "code pairs are not supported";                    \
+            goto utf7Error;                                             \
+        } else {                                                        \
+            *out++ = outCh;                                             \
+        }                                                               \
+    }
+
+PyObject *PyUnicode_DecodeUTF7(const char *s,
+			       Py_ssize_t size,
+			       const char *errors)
+{
+    const char *starts = s;
+    Py_ssize_t startinpos;
+    Py_ssize_t endinpos;
+    Py_ssize_t outpos;
+    const char *e;
+    PyUnicodeObject *unicode;
+    Py_UNICODE *p;
+    const char *errmsg = "";
+    int inShift = 0;
+    unsigned int bitsleft = 0;
+    unsigned long charsleft = 0;
+    int surrogate = 0;
+    PyObject *errorHandler = NULL;
+    PyObject *exc = NULL;
+
+    unicode = _PyUnicode_New(size);
+    if (!unicode)
+        return NULL;
+    if (size == 0)
+        return (PyObject *)unicode;
+
+    p = unicode->str;
+    e = s + size;
+
+    while (s < e) {
+        Py_UNICODE ch;
+        restart:
+        ch = *s;
+
+        if (inShift) {
+            if ((ch == '-') || !B64CHAR(ch)) {
+                inShift = 0;
+                s++;
+
+                /* p, charsleft, bitsleft, surrogate = */ DECODE(p, charsleft, bitsleft, surrogate);
+                if (bitsleft >= 6) {
+                    /* The shift sequence has a partial character in it. If
+                       bitsleft < 6 then we could just classify it as padding
+                       but that is not the case here */
+
+                    errmsg = "partial character in shift sequence";
+                    goto utf7Error;
+                }
+                /* According to RFC2152 the remaining bits should be zero. We
+                   choose to signal an error/insert a replacement character
+                   here so indicate the potential of a misencoded character. */
+
+                /* On x86, a << b == a << (b%32) so make sure that bitsleft != 0 */
+                if (bitsleft && charsleft << (sizeof(charsleft) * 8 - bitsleft)) {
+                    errmsg = "non-zero padding bits in shift sequence";
+                    goto utf7Error;
+                }
+
+                if (ch == '-') {
+                    if ((s < e) && (*(s) == '-')) {
+                        *p++ = '-';
+                        inShift = 1;
+                    }
+                } else if (SPECIAL(ch,0,0)) {
+                    errmsg = "unexpected special character";
+	                goto utf7Error;
+                } else  {
+                    *p++ = ch;
+                }
+            } else {
+                charsleft = (charsleft << 6) | UB64(ch);
+                bitsleft += 6;
+                s++;
+                /* p, charsleft, bitsleft, surrogate = */ DECODE(p, charsleft, bitsleft, surrogate);
+            }
+        }
+        else if ( ch == '+' ) {
+            startinpos = s-starts;
+            s++;
+            if (s < e && *s == '-') {
+                s++;
+                *p++ = '+';
+            } else
+            {
+                inShift = 1;
+                bitsleft = 0;
+            }
+        }
+        else if (SPECIAL(ch,0,0)) {
+            errmsg = "unexpected special character";
+            s++;
+	        goto utf7Error;
+        }
+        else {
+            *p++ = ch;
+            s++;
+        }
+        continue;
+    utf7Error:
+        outpos = p-PyUnicode_AS_UNICODE(unicode);
+        endinpos = s-starts;
+        if (unicode_decode_call_errorhandler(
+             errors, &errorHandler,
+             "utf7", errmsg,
+             starts, size, &startinpos, &endinpos, &exc, &s,
+             (PyObject **)&unicode, &outpos, &p))
+        goto onError;
+    }
+
+    if (inShift) {
+        outpos = p-PyUnicode_AS_UNICODE(unicode);
+        endinpos = size;
+        if (unicode_decode_call_errorhandler(
+             errors, &errorHandler,
+             "utf7", "unterminated shift sequence",
+             starts, size, &startinpos, &endinpos, &exc, &s,
+             (PyObject **)&unicode, &outpos, &p))
+            goto onError;
+        if (s < e)
+           goto restart;
+    }
+
+    if (_PyUnicode_Resize(&unicode, p - PyUnicode_AS_UNICODE(unicode)) < 0)
+        goto onError;
+
+    Py_XDECREF(errorHandler);
+    Py_XDECREF(exc);
+    return (PyObject *)unicode;
+
+onError:
+    Py_XDECREF(errorHandler);
+    Py_XDECREF(exc);
+    Py_DECREF(unicode);
+    return NULL;
+}
+
+
+PyObject *PyUnicode_EncodeUTF7(const Py_UNICODE *s,
+                   Py_ssize_t size,
+                   int encodeSetO,
+                   int encodeWhiteSpace,
+                   const char *errors)
+{
+    PyObject *v;
+    /* It might be possible to tighten this worst case */
+    Py_ssize_t cbAllocated = 5 * size;
+    int inShift = 0;
+    Py_ssize_t i = 0;
+    unsigned int bitsleft = 0;
+    unsigned long charsleft = 0;
+    char * out;
+    char * start;
+
+    if (size == 0)
+		return PyString_FromStringAndSize(NULL, 0);
+
+    v = PyString_FromStringAndSize(NULL, cbAllocated);
+    if (v == NULL)
+        return NULL;
+
+    start = out = PyString_AS_STRING(v);
+    for (;i < size; ++i) {
+        Py_UNICODE ch = s[i];
+
+        if (!inShift) {
+            if (ch == '+') {
+                *out++ = '+';
+                *out++ = '-';
+            } else if (SPECIAL(ch, encodeSetO, encodeWhiteSpace)) {
+                charsleft = ch;
+                bitsleft = 16;
+                *out++ = '+';
+                /* out, charsleft, bitsleft = */ ENCODE(out, charsleft, bitsleft);
+                inShift = bitsleft > 0;
+            } else {
+                *out++ = (char) ch;
+            }
+        } else {
+            if (!SPECIAL(ch, encodeSetO, encodeWhiteSpace)) {
+                *out++ = B64(charsleft << (6-bitsleft));
+                charsleft = 0;
+                bitsleft = 0;
+                /* Characters not in the BASE64 set implicitly unshift the sequence
+                   so no '-' is required, except if the character is itself a '-' */
+                if (B64CHAR(ch) || ch == '-') {
+                    *out++ = '-';
+                }
+                inShift = 0;
+                *out++ = (char) ch;
+            } else {
+                bitsleft += 16;
+                charsleft = (charsleft << 16) | ch;
+                /* out, charsleft, bitsleft = */ ENCODE(out, charsleft, bitsleft);
+
+                /* If the next character is special then we dont' need to terminate
+                   the shift sequence. If the next character is not a BASE64 character
+                   or '-' then the shift sequence will be terminated implicitly and we
+                   don't have to insert a '-'. */
+
+                if (bitsleft == 0) {
+                    if (i + 1 < size) {
+                        Py_UNICODE ch2 = s[i+1];
+
+                        if (SPECIAL(ch2, encodeSetO, encodeWhiteSpace)) {
+
+                        } else if (B64CHAR(ch2) || ch2 == '-') {
+                            *out++ = '-';
+                            inShift = 0;
+                        } else {
+                            inShift = 0;
+                        }
+
+                    }
+                    else {
+                        *out++ = '-';
+                        inShift = 0;
+                    }
+                }
+            }
+        }
+    }
+    if (bitsleft) {
+        *out++= B64(charsleft << (6-bitsleft) );
+        *out++ = '-';
+    }
+
+    _PyString_Resize(&v, out - start);
+    return v;
+}
+
+#undef SPECIAL
+#undef B64
+#undef B64CHAR
+#undef UB64
+#undef ENCODE
+#undef DECODE
+
+/* --- UTF-8 Codec -------------------------------------------------------- */
+
+static
+char utf8_code_length[256] = {
+    /* Map UTF-8 encoded prefix byte to sequence length.  zero means
+       illegal prefix.  see RFC 2279 for details */
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+    4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 0, 0
+};
+
+PyObject *PyUnicode_DecodeUTF8(const char *s,
+			       Py_ssize_t size,
+			       const char *errors)
+{
+    return PyUnicode_DecodeUTF8Stateful(s, size, errors, NULL);
+}
+
+PyObject *PyUnicode_DecodeUTF8Stateful(const char *s,
+			                Py_ssize_t size,
+			                const char *errors,
+			                Py_ssize_t *consumed)
+{
+    const char *starts = s;
+    int n;
+    Py_ssize_t startinpos;
+    Py_ssize_t endinpos;
+    Py_ssize_t outpos;
+    const char *e;
+    PyUnicodeObject *unicode;
+    Py_UNICODE *p;
+    const char *errmsg = "";
+    PyObject *errorHandler = NULL;
+    PyObject *exc = NULL;
+
+    /* Note: size will always be longer than the resulting Unicode
+       character count */
+    unicode = _PyUnicode_New(size);
+    if (!unicode)
+        return NULL;
+    if (size == 0) {
+        if (consumed)
+            *consumed = 0;
+        return (PyObject *)unicode;
+    }
+
+    /* Unpack UTF-8 encoded data */
+    p = unicode->str;
+    e = s + size;
+
+    while (s < e) {
+        Py_UCS4 ch = (unsigned char)*s;
+
+        if (ch < 0x80) {
+            *p++ = (Py_UNICODE)ch;
+            s++;
+            continue;
+        }
+
+        n = utf8_code_length[ch];
+
+        if (s + n > e) {
+	    if (consumed)
+		break;
+	    else {
+		errmsg = "unexpected end of data";
+		startinpos = s-starts;
+		endinpos = size;
+		goto utf8Error;
+	    }
+	}
+
+        switch (n) {
+
+        case 0:
+            errmsg = "unexpected code byte";
+	    startinpos = s-starts;
+	    endinpos = startinpos+1;
+	    goto utf8Error;
+
+        case 1:
+            errmsg = "internal error";
+	    startinpos = s-starts;
+	    endinpos = startinpos+1;
+	    goto utf8Error;
+
+        case 2:
+            if ((s[1] & 0xc0) != 0x80) {
+                errmsg = "invalid data";
+		startinpos = s-starts;
+		endinpos = startinpos+2;
+		goto utf8Error;
+	    }
+            ch = ((s[0] & 0x1f) << 6) + (s[1] & 0x3f);
+            if (ch < 0x80) {
+		startinpos = s-starts;
+		endinpos = startinpos+2;
+                errmsg = "illegal encoding";
+		goto utf8Error;
+	    }
+	    else
+		*p++ = (Py_UNICODE)ch;
+            break;
+
+        case 3:
+            if ((s[1] & 0xc0) != 0x80 ||
+                (s[2] & 0xc0) != 0x80) {
+                errmsg = "invalid data";
+		startinpos = s-starts;
+		endinpos = startinpos+3;
+		goto utf8Error;
+	    }
+            ch = ((s[0] & 0x0f) << 12) + ((s[1] & 0x3f) << 6) + (s[2] & 0x3f);
+            if (ch < 0x0800) {
+		/* Note: UTF-8 encodings of surrogates are considered
+		   legal UTF-8 sequences;
+
+		   XXX For wide builds (UCS-4) we should probably try
+		       to recombine the surrogates into a single code
+		       unit.
+		*/
+                errmsg = "illegal encoding";
+		startinpos = s-starts;
+		endinpos = startinpos+3;
+		goto utf8Error;
+	    }
+	    else
+		*p++ = (Py_UNICODE)ch;
+            break;
+
+        case 4:
+            if ((s[1] & 0xc0) != 0x80 ||
+                (s[2] & 0xc0) != 0x80 ||
+                (s[3] & 0xc0) != 0x80) {
+                errmsg = "invalid data";
+		startinpos = s-starts;
+		endinpos = startinpos+4;
+		goto utf8Error;
+	    }
+            ch = ((s[0] & 0x7) << 18) + ((s[1] & 0x3f) << 12) +
+                 ((s[2] & 0x3f) << 6) + (s[3] & 0x3f);
+            /* validate and convert to UTF-16 */
+            if ((ch < 0x10000)        /* minimum value allowed for 4
+					 byte encoding */
+                || (ch > 0x10ffff))   /* maximum value allowed for
+					 UTF-16 */
+	    {
+                errmsg = "illegal encoding";
+		startinpos = s-starts;
+		endinpos = startinpos+4;
+		goto utf8Error;
+	    }
+#ifdef Py_UNICODE_WIDE
+	    *p++ = (Py_UNICODE)ch;
+#else
+            /*  compute and append the two surrogates: */
+
+            /*  translate from 10000..10FFFF to 0..FFFF */
+            ch -= 0x10000;
+
+            /*  high surrogate = top 10 bits added to D800 */
+            *p++ = (Py_UNICODE)(0xD800 + (ch >> 10));
+
+            /*  low surrogate = bottom 10 bits added to DC00 */
+            *p++ = (Py_UNICODE)(0xDC00 + (ch & 0x03FF));
+#endif
+            break;
+
+        default:
+            /* Other sizes are only needed for UCS-4 */
+            errmsg = "unsupported Unicode code range";
+	    startinpos = s-starts;
+	    endinpos = startinpos+n;
+	    goto utf8Error;
+        }
+        s += n;
+	continue;
+
+    utf8Error:
+    outpos = p-PyUnicode_AS_UNICODE(unicode);
+    if (unicode_decode_call_errorhandler(
+	     errors, &errorHandler,
+	     "utf8", errmsg,
+	     starts, size, &startinpos, &endinpos, &exc, &s,
+	     (PyObject **)&unicode, &outpos, &p))
+	goto onError;
+    }
+    if (consumed)
+	*consumed = s-starts;
+
+    /* Adjust length */
+    if (_PyUnicode_Resize(&unicode, p - unicode->str) < 0)
+        goto onError;
+
+    Py_XDECREF(errorHandler);
+    Py_XDECREF(exc);
+    return (PyObject *)unicode;
+
+onError:
+    Py_XDECREF(errorHandler);
+    Py_XDECREF(exc);
+    Py_DECREF(unicode);
+    return NULL;
+}
+
+/* Allocation strategy:  if the string is short, convert into a stack buffer
+   and allocate exactly as much space needed at the end.  Else allocate the
+   maximum possible needed (4 result bytes per Unicode character), and return
+   the excess memory at the end.
+*/
+PyObject *
+PyUnicode_EncodeUTF8(const Py_UNICODE *s,
+		     Py_ssize_t size,
+		     const char *errors)
+{
+#define MAX_SHORT_UNICHARS 300  /* largest size we'll do on the stack */
+
+    Py_ssize_t i;           /* index into s of next input byte */
+    PyObject *v;        /* result string object */
+    char *p;            /* next free byte in output buffer */
+    Py_ssize_t nallocated;  /* number of result bytes allocated */
+    Py_ssize_t nneeded;        /* number of result bytes needed */
+    char stackbuf[MAX_SHORT_UNICHARS * 4];
+
+    assert(s != NULL);
+    assert(size >= 0);
+
+    if (size <= MAX_SHORT_UNICHARS) {
+        /* Write into the stack buffer; nallocated can't overflow.
+         * At the end, we'll allocate exactly as much heap space as it
+         * turns out we need.
+         */
+        nallocated = Py_SAFE_DOWNCAST(sizeof(stackbuf), size_t, int);
+        v = NULL;   /* will allocate after we're done */
+        p = stackbuf;
+    }
+    else {
+        /* Overallocate on the heap, and give the excess back at the end. */
+        nallocated = size * 4;
+        if (nallocated / 4 != size)  /* overflow! */
+            return PyErr_NoMemory();
+        v = PyString_FromStringAndSize(NULL, nallocated);
+        if (v == NULL)
+            return NULL;
+        p = PyString_AS_STRING(v);
+    }
+
+    for (i = 0; i < size;) {
+        Py_UCS4 ch = s[i++];
+
+        if (ch < 0x80)
+            /* Encode ASCII */
+            *p++ = (char) ch;
+
+        else if (ch < 0x0800) {
+            /* Encode Latin-1 */
+            *p++ = (char)(0xc0 | (ch >> 6));
+            *p++ = (char)(0x80 | (ch & 0x3f));
+        }
+        else {
+            /* Encode UCS2 Unicode ordinals */
+            if (ch < 0x10000) {
+                /* Special case: check for high surrogate */
+                if (0xD800 <= ch && ch <= 0xDBFF && i != size) {
+                    Py_UCS4 ch2 = s[i];
+                    /* Check for low surrogate and combine the two to
+                       form a UCS4 value */
+                    if (0xDC00 <= ch2 && ch2 <= 0xDFFF) {
+                        ch = ((ch - 0xD800) << 10 | (ch2 - 0xDC00)) + 0x10000;
+                        i++;
+                        goto encodeUCS4;
+                    }
+                    /* Fall through: handles isolated high surrogates */
+                }
+                *p++ = (char)(0xe0 | (ch >> 12));
+                *p++ = (char)(0x80 | ((ch >> 6) & 0x3f));
+                *p++ = (char)(0x80 | (ch & 0x3f));
+                continue;
+    	    }
+encodeUCS4:
+            /* Encode UCS4 Unicode ordinals */
+            *p++ = (char)(0xf0 | (ch >> 18));
+            *p++ = (char)(0x80 | ((ch >> 12) & 0x3f));
+            *p++ = (char)(0x80 | ((ch >> 6) & 0x3f));
+            *p++ = (char)(0x80 | (ch & 0x3f));
+        }
+    }
+
+    if (v == NULL) {
+        /* This was stack allocated. */
+        nneeded = p - stackbuf;
+        assert(nneeded <= nallocated);
+        v = PyString_FromStringAndSize(stackbuf, nneeded);
+    }
+    else {
+    	/* Cut back to size actually needed. */
+        nneeded = p - PyString_AS_STRING(v);
+        assert(nneeded <= nallocated);
+        _PyString_Resize(&v, nneeded);
+    }
+    return v;
+
+#undef MAX_SHORT_UNICHARS
+}
+
+PyObject *PyUnicode_AsUTF8String(PyObject *unicode)
+{
+    if (!PyUnicode_Check(unicode)) {
+        PyErr_BadArgument();
+        return NULL;
+    }
+    return PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(unicode),
+				PyUnicode_GET_SIZE(unicode),
+				NULL);
+}
+
+/* --- UTF-16 Codec ------------------------------------------------------- */
+
+PyObject *
+PyUnicode_DecodeUTF16(const char *s,
+		      Py_ssize_t size,
+		      const char *errors,
+		      int *byteorder)
+{
+    return PyUnicode_DecodeUTF16Stateful(s, size, errors, byteorder, NULL);
+}
+
+PyObject *
+PyUnicode_DecodeUTF16Stateful(const char *s,
+			      Py_ssize_t size,
+			      const char *errors,
+			      int *byteorder,
+			      Py_ssize_t *consumed)
+{
+    const char *starts = s;
+    Py_ssize_t startinpos;
+    Py_ssize_t endinpos;
+    Py_ssize_t outpos;
+    PyUnicodeObject *unicode;
+    Py_UNICODE *p;
+    const unsigned char *q, *e;
+    int bo = 0;       /* assume native ordering by default */
+    const char *errmsg = "";
+    /* Offsets from q for retrieving byte pairs in the right order. */
+#ifdef BYTEORDER_IS_LITTLE_ENDIAN
+    int ihi = 1, ilo = 0;
+#else
+    int ihi = 0, ilo = 1;
+#endif
+    PyObject *errorHandler = NULL;
+    PyObject *exc = NULL;
+
+    /* Note: size will always be longer than the resulting Unicode
+       character count */
+    unicode = _PyUnicode_New(size);
+    if (!unicode)
+        return NULL;
+    if (size == 0)
+        return (PyObject *)unicode;
+
+    /* Unpack UTF-16 encoded data */
+    p = unicode->str;
+    q = (unsigned char *)s;
+    e = q + size;
+
+    if (byteorder)
+        bo = *byteorder;
+
+    /* Check for BOM marks (U+FEFF) in the input and adjust current
+       byte order setting accordingly. In native mode, the leading BOM
+       mark is skipped, in all other modes, it is copied to the output
+       stream as-is (giving a ZWNBSP character). */
+    if (bo == 0) {
+        if (size >= 2) {
+            const Py_UNICODE bom = (q[ihi] << 8) | q[ilo];
+#ifdef BYTEORDER_IS_LITTLE_ENDIAN
+	    if (bom == 0xFEFF) {
+		q += 2;
+		bo = -1;
+	    }
+	    else if (bom == 0xFFFE) {
+		q += 2;
+		bo = 1;
+	    }
+#else
+	    if (bom == 0xFEFF) {
+		q += 2;
+		bo = 1;
+	    }
+	    else if (bom == 0xFFFE) {
+		q += 2;
+		bo = -1;
+	    }
+#endif
+	}
+    }
+
+    if (bo == -1) {
+        /* force LE */
+        ihi = 1;
+        ilo = 0;
+    }
+    else if (bo == 1) {
+        /* force BE */
+        ihi = 0;
+        ilo = 1;
+    }
+
+    while (q < e) {
+	Py_UNICODE ch;
+	/* remaining bytes at the end? (size should be even) */
+	if (e-q<2) {
+	    if (consumed)
+		break;
+	    errmsg = "truncated data";
+	    startinpos = ((const char *)q)-starts;
+	    endinpos = ((const char *)e)-starts;
+	    goto utf16Error;
+	    /* The remaining input chars are ignored if the callback
+	       chooses to skip the input */
+	}
+	ch = (q[ihi] << 8) | q[ilo];
+
+	q += 2;
+
+	if (ch < 0xD800 || ch > 0xDFFF) {
+	    *p++ = ch;
+	    continue;
+	}
+
+	/* UTF-16 code pair: */
+	if (q >= e) {
+	    errmsg = "unexpected end of data";
+	    startinpos = (((const char *)q)-2)-starts;
+	    endinpos = ((const char *)e)-starts;
+	    goto utf16Error;
+	}
+	if (0xD800 <= ch && ch <= 0xDBFF) {
+	    Py_UNICODE ch2 = (q[ihi] << 8) | q[ilo];
+	    q += 2;
+	    if (0xDC00 <= ch2 && ch2 <= 0xDFFF) {
+#ifndef Py_UNICODE_WIDE
+		*p++ = ch;
+		*p++ = ch2;
+#else
+		*p++ = (((ch & 0x3FF)<<10) | (ch2 & 0x3FF)) + 0x10000;
+#endif
+		continue;
+	    }
+	    else {
+                errmsg = "illegal UTF-16 surrogate";
+		startinpos = (((const char *)q)-4)-starts;
+		endinpos = startinpos+2;
+		goto utf16Error;
+	    }
+
+	}
+	errmsg = "illegal encoding";
+	startinpos = (((const char *)q)-2)-starts;
+	endinpos = startinpos+2;
+	/* Fall through to report the error */
+
+    utf16Error:
+	outpos = p-PyUnicode_AS_UNICODE(unicode);
+	if (unicode_decode_call_errorhandler(
+	         errors, &errorHandler,
+	         "utf16", errmsg,
+	         starts, size, &startinpos, &endinpos, &exc, (const char **)&q,
+	         (PyObject **)&unicode, &outpos, &p))
+	    goto onError;
+    }
+
+    if (byteorder)
+        *byteorder = bo;
+
+    if (consumed)
+	*consumed = (const char *)q-starts;
+
+    /* Adjust length */
+    if (_PyUnicode_Resize(&unicode, p - unicode->str) < 0)
+        goto onError;
+
+    Py_XDECREF(errorHandler);
+    Py_XDECREF(exc);
+    return (PyObject *)unicode;
+
+onError:
+    Py_DECREF(unicode);
+    Py_XDECREF(errorHandler);
+    Py_XDECREF(exc);
+    return NULL;
+}
+
+PyObject *
+PyUnicode_EncodeUTF16(const Py_UNICODE *s,
+		      Py_ssize_t size,
+		      const char *errors,
+		      int byteorder)
+{
+    PyObject *v;
+    unsigned char *p;
+#ifdef Py_UNICODE_WIDE
+    int i, pairs;
+#else
+    const int pairs = 0;
+#endif
+    /* Offsets from p for storing byte pairs in the right order. */
+#ifdef BYTEORDER_IS_LITTLE_ENDIAN
+    int ihi = 1, ilo = 0;
+#else
+    int ihi = 0, ilo = 1;
+#endif
+
+#define STORECHAR(CH)                   \
+    do {                                \
+        p[ihi] = ((CH) >> 8) & 0xff;    \
+        p[ilo] = (CH) & 0xff;           \
+        p += 2;                         \
+    } while(0)
+
+#ifdef Py_UNICODE_WIDE
+    for (i = pairs = 0; i < size; i++)
+	if (s[i] >= 0x10000)
+	    pairs++;
+#endif
+    v = PyString_FromStringAndSize(NULL,
+		  2 * (size + pairs + (byteorder == 0)));
+    if (v == NULL)
+        return NULL;
+
+    p = (unsigned char *)PyString_AS_STRING(v);
+    if (byteorder == 0)
+	STORECHAR(0xFEFF);
+    if (size == 0)
+        return v;
+
+    if (byteorder == -1) {
+        /* force LE */
+        ihi = 1;
+        ilo = 0;
+    }
+    else if (byteorder == 1) {
+        /* force BE */
+        ihi = 0;
+        ilo = 1;
+    }
+
+    while (size-- > 0) {
+	Py_UNICODE ch = *s++;
+	Py_UNICODE ch2 = 0;
+#ifdef Py_UNICODE_WIDE
+	if (ch >= 0x10000) {
+	    ch2 = 0xDC00 | ((ch-0x10000) & 0x3FF);
+	    ch  = 0xD800 | ((ch-0x10000) >> 10);
+	}
+#endif
+        STORECHAR(ch);
+        if (ch2)
+            STORECHAR(ch2);
+    }
+    return v;
+#undef STORECHAR
+}
+
+PyObject *PyUnicode_AsUTF16String(PyObject *unicode)
+{
+    if (!PyUnicode_Check(unicode)) {
+        PyErr_BadArgument();
+        return NULL;
+    }
+    return PyUnicode_EncodeUTF16(PyUnicode_AS_UNICODE(unicode),
+				 PyUnicode_GET_SIZE(unicode),
+				 NULL,
+				 0);
+}
+
+/* --- Unicode Escape Codec ----------------------------------------------- */
+
+static _PyUnicode_Name_CAPI *ucnhash_CAPI = NULL;
+
+PyObject *PyUnicode_DecodeUnicodeEscape(const char *s,
+					Py_ssize_t size,
+					const char *errors)
+{
+    const char *starts = s;
+    Py_ssize_t startinpos;
+    Py_ssize_t endinpos;
+    Py_ssize_t outpos;
+    int i;
+    PyUnicodeObject *v;
+    Py_UNICODE *p;
+    const char *end;
+    char* message;
+    Py_UCS4 chr = 0xffffffff; /* in case 'getcode' messes up */
+    PyObject *errorHandler = NULL;
+    PyObject *exc = NULL;
+
+    /* Escaped strings will always be longer than the resulting
+       Unicode string, so we start with size here and then reduce the
+       length after conversion to the true value.
+       (but if the error callback returns a long replacement string
+       we'll have to allocate more space) */
+    v = _PyUnicode_New(size);
+    if (v == NULL)
+        goto onError;
+    if (size == 0)
+        return (PyObject *)v;
+
+    p = PyUnicode_AS_UNICODE(v);
+    end = s + size;
+
+    while (s < end) {
+        unsigned char c;
+        Py_UNICODE x;
+        int digits;
+
+        /* Non-escape characters are interpreted as Unicode ordinals */
+        if (*s != '\\') {
+            *p++ = (unsigned char) *s++;
+            continue;
+        }
+
+        startinpos = s-starts;
+        /* \ - Escapes */
+        s++;
+        switch (*s++) {
+
+        /* \x escapes */
+        case '\n': break;
+        case '\\': *p++ = '\\'; break;
+        case '\'': *p++ = '\''; break;
+        case '\"': *p++ = '\"'; break;
+        case 'b': *p++ = '\b'; break;
+        case 'f': *p++ = '\014'; break; /* FF */
+        case 't': *p++ = '\t'; break;
+        case 'n': *p++ = '\n'; break;
+        case 'r': *p++ = '\r'; break;
+        case 'v': *p++ = '\013'; break; /* VT */
+        case 'a': *p++ = '\007'; break; /* BEL, not classic C */
+
+        /* \OOO (octal) escapes */
+        case '0': case '1': case '2': case '3':
+        case '4': case '5': case '6': case '7':
+            x = s[-1] - '0';
+            if ('0' <= *s && *s <= '7') {
+                x = (x<<3) + *s++ - '0';
+                if ('0' <= *s && *s <= '7')
+                    x = (x<<3) + *s++ - '0';
+            }
+            *p++ = x;
+            break;
+
+        /* hex escapes */
+        /* \xXX */
+        case 'x':
+            digits = 2;
+            message = "truncated \\xXX escape";
+            goto hexescape;
+
+        /* \uXXXX */
+        case 'u':
+            digits = 4;
+            message = "truncated \\uXXXX escape";
+            goto hexescape;
+
+        /* \UXXXXXXXX */
+        case 'U':
+            digits = 8;
+            message = "truncated \\UXXXXXXXX escape";
+        hexescape:
+            chr = 0;
+            outpos = p-PyUnicode_AS_UNICODE(v);
+            if (s+digits>end) {
+                endinpos = size;
+                if (unicode_decode_call_errorhandler(
+                    errors, &errorHandler,
+                    "unicodeescape", "end of string in escape sequence",
+                    starts, size, &startinpos, &endinpos, &exc, &s,
+                    (PyObject **)&v, &outpos, &p))
+                    goto onError;
+                goto nextByte;
+            }
+            for (i = 0; i < digits; ++i) {
+                c = (unsigned char) s[i];
+                if (!isxdigit(c)) {
+                    endinpos = (s+i+1)-starts;
+                    if (unicode_decode_call_errorhandler(
+                        errors, &errorHandler,
+                        "unicodeescape", message,
+                        starts, size, &startinpos, &endinpos, &exc, &s,
+                        (PyObject **)&v, &outpos, &p))
+                        goto onError;
+                    goto nextByte;
+                }
+                chr = (chr<<4) & ~0xF;
+                if (c >= '0' && c <= '9')
+                    chr += c - '0';
+                else if (c >= 'a' && c <= 'f')
+                    chr += 10 + c - 'a';
+                else
+                    chr += 10 + c - 'A';
+            }
+            s += i;
+            if (chr == 0xffffffff && PyErr_Occurred())
+                /* _decoding_error will have already written into the
+                   target buffer. */
+                break;
+        store:
+            /* when we get here, chr is a 32-bit unicode character */
+            if (chr <= 0xffff)
+                /* UCS-2 character */
+                *p++ = (Py_UNICODE) chr;
+            else if (chr <= 0x10ffff) {
+                /* UCS-4 character. Either store directly, or as
+                   surrogate pair. */
+#ifdef Py_UNICODE_WIDE
+                *p++ = chr;
+#else
+                chr -= 0x10000L;
+                *p++ = 0xD800 + (Py_UNICODE) (chr >> 10);
+                *p++ = 0xDC00 + (Py_UNICODE) (chr & 0x03FF);
+#endif
+            } else {
+                endinpos = s-starts;
+                outpos = p-PyUnicode_AS_UNICODE(v);
+                if (unicode_decode_call_errorhandler(
+                    errors, &errorHandler,
+                    "unicodeescape", "illegal Unicode character",
+                    starts, size, &startinpos, &endinpos, &exc, &s,
+                    (PyObject **)&v, &outpos, &p))
+                    goto onError;
+            }
+            break;
+
+        /* \N{name} */
+        case 'N':
+            message = "malformed \\N character escape";
+            if (ucnhash_CAPI == NULL) {
+                /* load the unicode data module */
+                PyObject *m, *api;
+                m = PyImport_ImportModule("unicodedata");
+                if (m == NULL)
+                    goto ucnhashError;
+                api = PyObject_GetAttrString(m, "ucnhash_CAPI");
+                Py_DECREF(m);
+                if (api == NULL)
+                    goto ucnhashError;
+                ucnhash_CAPI = (_PyUnicode_Name_CAPI *)PyCObject_AsVoidPtr(api);
+                Py_DECREF(api);
+                if (ucnhash_CAPI == NULL)
+                    goto ucnhashError;
+            }
+            if (*s == '{') {
+                const char *start = s+1;
+                /* look for the closing brace */
+                while (*s != '}' && s < end)
+                    s++;
+                if (s > start && s < end && *s == '}') {
+                    /* found a name.  look it up in the unicode database */
+                    message = "unknown Unicode character name";
+                    s++;
+                    if (ucnhash_CAPI->getcode(NULL, start, (int)(s-start-1), &chr))
+                        goto store;
+                }
+            }
+            endinpos = s-starts;
+            outpos = p-PyUnicode_AS_UNICODE(v);
+            if (unicode_decode_call_errorhandler(
+                errors, &errorHandler,
+                "unicodeescape", message,
+                starts, size, &startinpos, &endinpos, &exc, &s,
+                (PyObject **)&v, &outpos, &p))
+                goto onError;
+            break;
+
+        default:
+            if (s > end) {
+                message = "\\ at end of string";
+                s--;
+                endinpos = s-starts;
+                outpos = p-PyUnicode_AS_UNICODE(v);
+                if (unicode_decode_call_errorhandler(
+                    errors, &errorHandler,
+                    "unicodeescape", message,
+                    starts, size, &startinpos, &endinpos, &exc, &s,
+                    (PyObject **)&v, &outpos, &p))
+                    goto onError;
+            }
+            else {
+                *p++ = '\\';
+                *p++ = (unsigned char)s[-1];
+            }
+            break;
+        }
+        nextByte:
+        ;
+    }
+    if (_PyUnicode_Resize(&v, p - PyUnicode_AS_UNICODE(v)) < 0)
+        goto onError;
+    Py_XDECREF(errorHandler);
+    Py_XDECREF(exc);
+    return (PyObject *)v;
+
+ucnhashError:
+    PyErr_SetString(
+        PyExc_UnicodeError,
+        "\\N escapes not supported (can't load unicodedata module)"
+        );
+    Py_XDECREF(v);
+    Py_XDECREF(errorHandler);
+    Py_XDECREF(exc);
+    return NULL;
+
+onError:
+    Py_XDECREF(v);
+    Py_XDECREF(errorHandler);
+    Py_XDECREF(exc);
+    return NULL;
+}
+
+/* Return a Unicode-Escape string version of the Unicode object.
+
+   If quotes is true, the string is enclosed in u"" or u'' quotes as
+   appropriate.
+
+*/
+
+Py_LOCAL_INLINE(const Py_UNICODE *) findchar(const Py_UNICODE *s,
+                                      Py_ssize_t size,
+                                      Py_UNICODE ch)
+{
+    /* like wcschr, but doesn't stop at NULL characters */
+
+    while (size-- > 0) {
+        if (*s == ch)
+            return s;
+        s++;
+    }
+
+    return NULL;
+}
+
+static
+PyObject *unicodeescape_string(const Py_UNICODE *s,
+                               Py_ssize_t size,
+                               int quotes)
+{
+    PyObject *repr;
+    char *p;
+
+    static const char *hexdigit = "0123456789abcdef";
+
+    /* Initial allocation is based on the longest-possible unichr
+       escape.
+
+       In wide (UTF-32) builds '\U00xxxxxx' is 10 chars per source
+       unichr, so in this case it's the longest unichr escape. In
+       narrow (UTF-16) builds this is five chars per source unichr
+       since there are two unichrs in the surrogate pair, so in narrow
+       (UTF-16) builds it's not the longest unichr escape.
+
+       In wide or narrow builds '\uxxxx' is 6 chars per source unichr,
+       so in the narrow (UTF-16) build case it's the longest unichr
+       escape.
+    */
+
+    repr = PyString_FromStringAndSize(NULL,
+        2
+#ifdef Py_UNICODE_WIDE
+        + 10*size
+#else
+        + 6*size
+#endif
+        + 1);
+    if (repr == NULL)
+        return NULL;
+
+    p = PyString_AS_STRING(repr);
+
+    if (quotes) {
+        *p++ = 'u';
+        *p++ = (findchar(s, size, '\'') &&
+                !findchar(s, size, '"')) ? '"' : '\'';
+    }
+    while (size-- > 0) {
+        Py_UNICODE ch = *s++;
+
+        /* Escape quotes and backslashes */
+        if ((quotes &&
+	     ch == (Py_UNICODE) PyString_AS_STRING(repr)[1]) || ch == '\\') {
+            *p++ = '\\';
+            *p++ = (char) ch;
+	    continue;
+        }
+
+#ifdef Py_UNICODE_WIDE
+        /* Map 21-bit characters to '\U00xxxxxx' */
+        else if (ch >= 0x10000) {
+            *p++ = '\\';
+            *p++ = 'U';
+            *p++ = hexdigit[(ch >> 28) & 0x0000000F];
+            *p++ = hexdigit[(ch >> 24) & 0x0000000F];
+            *p++ = hexdigit[(ch >> 20) & 0x0000000F];
+            *p++ = hexdigit[(ch >> 16) & 0x0000000F];
+            *p++ = hexdigit[(ch >> 12) & 0x0000000F];
+            *p++ = hexdigit[(ch >> 8) & 0x0000000F];
+            *p++ = hexdigit[(ch >> 4) & 0x0000000F];
+            *p++ = hexdigit[ch & 0x0000000F];
+	    continue;
+        }
+#else
+	/* Map UTF-16 surrogate pairs to '\U00xxxxxx' */
+	else if (ch >= 0xD800 && ch < 0xDC00) {
+	    Py_UNICODE ch2;
+	    Py_UCS4 ucs;
+
+	    ch2 = *s++;
+	    size--;
+	    if (ch2 >= 0xDC00 && ch2 <= 0xDFFF) {
+		ucs = (((ch & 0x03FF) << 10) | (ch2 & 0x03FF)) + 0x00010000;
+		*p++ = '\\';
+		*p++ = 'U';
+		*p++ = hexdigit[(ucs >> 28) & 0x0000000F];
+		*p++ = hexdigit[(ucs >> 24) & 0x0000000F];
+		*p++ = hexdigit[(ucs >> 20) & 0x0000000F];
+		*p++ = hexdigit[(ucs >> 16) & 0x0000000F];
+		*p++ = hexdigit[(ucs >> 12) & 0x0000000F];
+		*p++ = hexdigit[(ucs >> 8) & 0x0000000F];
+		*p++ = hexdigit[(ucs >> 4) & 0x0000000F];
+		*p++ = hexdigit[ucs & 0x0000000F];
+		continue;
+	    }
+	    /* Fall through: isolated surrogates are copied as-is */
+	    s--;
+	    size++;
+	}
+#endif
+
+        /* Map 16-bit characters to '\uxxxx' */
+        if (ch >= 256) {
+            *p++ = '\\';
+            *p++ = 'u';
+            *p++ = hexdigit[(ch >> 12) & 0x000F];
+            *p++ = hexdigit[(ch >> 8) & 0x000F];
+            *p++ = hexdigit[(ch >> 4) & 0x000F];
+            *p++ = hexdigit[ch & 0x000F];
+        }
+
+        /* Map special whitespace to '\t', \n', '\r' */
+        else if (ch == '\t') {
+            *p++ = '\\';
+            *p++ = 't';
+        }
+        else if (ch == '\n') {
+            *p++ = '\\';
+            *p++ = 'n';
+        }
+        else if (ch == '\r') {
+            *p++ = '\\';
+            *p++ = 'r';
+        }
+
+        /* Map non-printable US ASCII to '\xhh' */
+        else if (ch < ' ' || ch >= 0x7F) {
+            *p++ = '\\';
+            *p++ = 'x';
+            *p++ = hexdigit[(ch >> 4) & 0x000F];
+            *p++ = hexdigit[ch & 0x000F];
+        }
+
+        /* Copy everything else as-is */
+        else
+            *p++ = (char) ch;
+    }
+    if (quotes)
+        *p++ = PyString_AS_STRING(repr)[1];
+
+    *p = '\0';
+    _PyString_Resize(&repr, p - PyString_AS_STRING(repr));
+    return repr;
+}
+
+PyObject *PyUnicode_EncodeUnicodeEscape(const Py_UNICODE *s,
+					Py_ssize_t size)
+{
+    return unicodeescape_string(s, size, 0);
+}
+
+PyObject *PyUnicode_AsUnicodeEscapeString(PyObject *unicode)
+{
+    if (!PyUnicode_Check(unicode)) {
+        PyErr_BadArgument();
+        return NULL;
+    }
+    return PyUnicode_EncodeUnicodeEscape(PyUnicode_AS_UNICODE(unicode),
+					 PyUnicode_GET_SIZE(unicode));
+}
+
+/* --- Raw Unicode Escape Codec ------------------------------------------- */
+
+PyObject *PyUnicode_DecodeRawUnicodeEscape(const char *s,
+					   Py_ssize_t size,
+					   const char *errors)
+{
+    const char *starts = s;
+    Py_ssize_t startinpos;
+    Py_ssize_t endinpos;
+    Py_ssize_t outpos;
+    PyUnicodeObject *v;
+    Py_UNICODE *p;
+    const char *end;
+    const char *bs;
+    PyObject *errorHandler = NULL;
+    PyObject *exc = NULL;
+
+    /* Escaped strings will always be longer than the resulting
+       Unicode string, so we start with size here and then reduce the
+       length after conversion to the true value. (But decoding error
+       handler might have to resize the string) */
+    v = _PyUnicode_New(size);
+    if (v == NULL)
+	goto onError;
+    if (size == 0)
+	return (PyObject *)v;
+    p = PyUnicode_AS_UNICODE(v);
+    end = s + size;
+    while (s < end) {
+	unsigned char c;
+	Py_UCS4 x;
+	int i;
+        int count;
+
+	/* Non-escape characters are interpreted as Unicode ordinals */
+	if (*s != '\\') {
+	    *p++ = (unsigned char)*s++;
+	    continue;
+	}
+	startinpos = s-starts;
+
+	/* \u-escapes are only interpreted iff the number of leading
+	   backslashes if odd */
+	bs = s;
+	for (;s < end;) {
+	    if (*s != '\\')
+		break;
+	    *p++ = (unsigned char)*s++;
+	}
+	if (((s - bs) & 1) == 0 ||
+	    s >= end ||
+	    (*s != 'u' && *s != 'U')) {
+	    continue;
+	}
+	p--;
+        count = *s=='u' ? 4 : 8;
+	s++;
+
+	/* \uXXXX with 4 hex digits, \Uxxxxxxxx with 8 */
+	outpos = p-PyUnicode_AS_UNICODE(v);
+	for (x = 0, i = 0; i < count; ++i, ++s) {
+	    c = (unsigned char)*s;
+	    if (!isxdigit(c)) {
+		endinpos = s-starts;
+		if (unicode_decode_call_errorhandler(
+		    errors, &errorHandler,
+		    "rawunicodeescape", "truncated \\uXXXX",
+		    starts, size, &startinpos, &endinpos, &exc, &s,
+		    (PyObject **)&v, &outpos, &p))
+		    goto onError;
+		goto nextByte;
+	    }
+	    x = (x<<4) & ~0xF;
+	    if (c >= '0' && c <= '9')
+		x += c - '0';
+	    else if (c >= 'a' && c <= 'f')
+		x += 10 + c - 'a';
+	    else
+		x += 10 + c - 'A';
+	}
+#ifndef Py_UNICODE_WIDE
+        if (x > 0x10000) {
+            if (unicode_decode_call_errorhandler(
+                    errors, &errorHandler,
+                    "rawunicodeescape", "\\Uxxxxxxxx out of range",
+		    starts, size, &startinpos, &endinpos, &exc, &s,
+		    (PyObject **)&v, &outpos, &p))
+		    goto onError;
+        }
+#endif
+	*p++ = x;
+	nextByte:
+	;
+    }
+    if (_PyUnicode_Resize(&v, p - PyUnicode_AS_UNICODE(v)) < 0)
+	goto onError;
+    Py_XDECREF(errorHandler);
+    Py_XDECREF(exc);
+    return (PyObject *)v;
+
+ onError:
+    Py_XDECREF(v);
+    Py_XDECREF(errorHandler);
+    Py_XDECREF(exc);
+    return NULL;
+}
+
+PyObject *PyUnicode_EncodeRawUnicodeEscape(const Py_UNICODE *s,
+					   Py_ssize_t size)
+{
+    PyObject *repr;
+    char *p;
+    char *q;
+
+    static const char *hexdigit = "0123456789abcdef";
+
+#ifdef Py_UNICODE_WIDE
+    repr = PyString_FromStringAndSize(NULL, 10 * size);
+#else
+    repr = PyString_FromStringAndSize(NULL, 6 * size);
+#endif
+    if (repr == NULL)
+        return NULL;
+    if (size == 0)
+	return repr;
+
+    p = q = PyString_AS_STRING(repr);
+    while (size-- > 0) {
+        Py_UNICODE ch = *s++;
+#ifdef Py_UNICODE_WIDE
+	/* Map 32-bit characters to '\Uxxxxxxxx' */
+	if (ch >= 0x10000) {
+            *p++ = '\\';
+            *p++ = 'U';
+            *p++ = hexdigit[(ch >> 28) & 0xf];
+            *p++ = hexdigit[(ch >> 24) & 0xf];
+            *p++ = hexdigit[(ch >> 20) & 0xf];
+            *p++ = hexdigit[(ch >> 16) & 0xf];
+            *p++ = hexdigit[(ch >> 12) & 0xf];
+            *p++ = hexdigit[(ch >> 8) & 0xf];
+            *p++ = hexdigit[(ch >> 4) & 0xf];
+            *p++ = hexdigit[ch & 15];
+        }
+        else
+#endif
+	/* Map 16-bit characters to '\uxxxx' */
+	if (ch >= 256) {
+            *p++ = '\\';
+            *p++ = 'u';
+            *p++ = hexdigit[(ch >> 12) & 0xf];
+            *p++ = hexdigit[(ch >> 8) & 0xf];
+            *p++ = hexdigit[(ch >> 4) & 0xf];
+            *p++ = hexdigit[ch & 15];
+        }
+	/* Copy everything else as-is */
+	else
+            *p++ = (char) ch;
+    }
+    *p = '\0';
+    _PyString_Resize(&repr, p - q);
+    return repr;
+}
+
+PyObject *PyUnicode_AsRawUnicodeEscapeString(PyObject *unicode)
+{
+    if (!PyUnicode_Check(unicode)) {
+	PyErr_BadArgument();
+	return NULL;
+    }
+    return PyUnicode_EncodeRawUnicodeEscape(PyUnicode_AS_UNICODE(unicode),
+					    PyUnicode_GET_SIZE(unicode));
+}
+
+/* --- Unicode Internal Codec ------------------------------------------- */
+
+PyObject *_PyUnicode_DecodeUnicodeInternal(const char *s,
+					   Py_ssize_t size,
+					   const char *errors)
+{
+    const char *starts = s;
+    Py_ssize_t startinpos;
+    Py_ssize_t endinpos;
+    Py_ssize_t outpos;
+    PyUnicodeObject *v;
+    Py_UNICODE *p;
+    const char *end;
+    const char *reason;
+    PyObject *errorHandler = NULL;
+    PyObject *exc = NULL;
+
+#ifdef Py_UNICODE_WIDE
+    Py_UNICODE unimax = PyUnicode_GetMax();
+#endif
+
+    /* XXX overflow detection missing */
+    v = _PyUnicode_New((size+Py_UNICODE_SIZE-1)/ Py_UNICODE_SIZE);
+    if (v == NULL)
+	goto onError;
+    if (PyUnicode_GetSize((PyObject *)v) == 0)
+	return (PyObject *)v;
+    p = PyUnicode_AS_UNICODE(v);
+    end = s + size;
+
+    while (s < end) {
+        memcpy(p, s, sizeof(Py_UNICODE));
+        /* We have to sanity check the raw data, otherwise doom looms for
+           some malformed UCS-4 data. */
+        if (
+            #ifdef Py_UNICODE_WIDE
+            *p > unimax || *p < 0 ||
+            #endif
+            end-s < Py_UNICODE_SIZE
+            )
+            {
+            startinpos = s - starts;
+            if (end-s < Py_UNICODE_SIZE) {
+                endinpos = end-starts;
+                reason = "truncated input";
+            }
+            else {
+                endinpos = s - starts + Py_UNICODE_SIZE;
+                reason = "illegal code point (> 0x10FFFF)";
+            }
+            outpos = p - PyUnicode_AS_UNICODE(v);
+            if (unicode_decode_call_errorhandler(
+                    errors, &errorHandler,
+                    "unicode_internal", reason,
+                    starts, size, &startinpos, &endinpos, &exc, &s,
+                    (PyObject **)&v, &outpos, &p)) {
+                goto onError;
+            }
+        }
+        else {
+            p++;
+            s += Py_UNICODE_SIZE;
+        }
+    }
+
+    if (_PyUnicode_Resize(&v, p - PyUnicode_AS_UNICODE(v)) < 0)
+        goto onError;
+    Py_XDECREF(errorHandler);
+    Py_XDECREF(exc);
+    return (PyObject *)v;
+
+ onError:
+    Py_XDECREF(v);
+    Py_XDECREF(errorHandler);
+    Py_XDECREF(exc);
+    return NULL;
+}
+
+/* --- Latin-1 Codec ------------------------------------------------------ */
+
+PyObject *PyUnicode_DecodeLatin1(const char *s,
+				 Py_ssize_t size,
+				 const char *errors)
+{
+    PyUnicodeObject *v;
+    Py_UNICODE *p;
+
+    /* Latin-1 is equivalent to the first 256 ordinals in Unicode. */
+    if (size == 1) {
+	Py_UNICODE r = *(unsigned char*)s;
+	return PyUnicode_FromUnicode(&r, 1);
+    }
+
+    v = _PyUnicode_New(size);
+    if (v == NULL)
+	goto onError;
+    if (size == 0)
+	return (PyObject *)v;
+    p = PyUnicode_AS_UNICODE(v);
+    while (size-- > 0)
+	*p++ = (unsigned char)*s++;
+    return (PyObject *)v;
+
+ onError:
+    Py_XDECREF(v);
+    return NULL;
+}
+
+/* create or adjust a UnicodeEncodeError */
+static void make_encode_exception(PyObject **exceptionObject,
+    const char *encoding,
+    const Py_UNICODE *unicode, Py_ssize_t size,
+    Py_ssize_t startpos, Py_ssize_t endpos,
+    const char *reason)
+{
+    if (*exceptionObject == NULL) {
+	*exceptionObject = PyUnicodeEncodeError_Create(
+	    encoding, unicode, size, startpos, endpos, reason);
+    }
+    else {
+	if (PyUnicodeEncodeError_SetStart(*exceptionObject, startpos))
+	    goto onError;
+	if (PyUnicodeEncodeError_SetEnd(*exceptionObject, endpos))
+	    goto onError;
+	if (PyUnicodeEncodeError_SetReason(*exceptionObject, reason))
+	    goto onError;
+	return;
+	onError:
+	Py_DECREF(*exceptionObject);
+	*exceptionObject = NULL;
+    }
+}
+
+/* raises a UnicodeEncodeError */
+static void raise_encode_exception(PyObject **exceptionObject,
+    const char *encoding,
+    const Py_UNICODE *unicode, Py_ssize_t size,
+    Py_ssize_t startpos, Py_ssize_t endpos,
+    const char *reason)
+{
+    make_encode_exception(exceptionObject,
+	encoding, unicode, size, startpos, endpos, reason);
+    if (*exceptionObject != NULL)
+	PyCodec_StrictErrors(*exceptionObject);
+}
+
+/* error handling callback helper:
+   build arguments, call the callback and check the arguments,
+   put the result into newpos and return the replacement string, which
+   has to be freed by the caller */
+static PyObject *unicode_encode_call_errorhandler(const char *errors,
+    PyObject **errorHandler,
+    const char *encoding, const char *reason,
+    const Py_UNICODE *unicode, Py_ssize_t size, PyObject **exceptionObject,
+    Py_ssize_t startpos, Py_ssize_t endpos,
+    Py_ssize_t *newpos)
+{
+    static char *argparse = "O!n;encoding error handler must return (unicode, int) tuple";
+
+    PyObject *restuple;
+    PyObject *resunicode;
+
+    if (*errorHandler == NULL) {
+	*errorHandler = PyCodec_LookupError(errors);
+        if (*errorHandler == NULL)
+	    return NULL;
+    }
+
+    make_encode_exception(exceptionObject,
+	encoding, unicode, size, startpos, endpos, reason);
+    if (*exceptionObject == NULL)
+	return NULL;
+
+    restuple = PyObject_CallFunctionObjArgs(
+	*errorHandler, *exceptionObject, NULL);
+    if (restuple == NULL)
+	return NULL;
+    if (!PyTuple_Check(restuple)) {
+	PyErr_Format(PyExc_TypeError, &argparse[4]);
+	Py_DECREF(restuple);
+	return NULL;
+    }
+    if (!PyArg_ParseTuple(restuple, argparse, &PyUnicode_Type,
+	&resunicode, newpos)) {
+	Py_DECREF(restuple);
+	return NULL;
+    }
+    if (*newpos<0)
+	*newpos = size+*newpos;
+    if (*newpos<0 || *newpos>size) {
+	PyErr_Format(PyExc_IndexError, "position %zd from error handler out of bounds", *newpos);
+	Py_DECREF(restuple);
+	return NULL;
+    }
+    Py_INCREF(resunicode);
+    Py_DECREF(restuple);
+    return resunicode;
+}
+
+static PyObject *unicode_encode_ucs1(const Py_UNICODE *p,
+				 Py_ssize_t size,
+				 const char *errors,
+				 int limit)
+{
+    /* output object */
+    PyObject *res;
+    /* pointers to the beginning and end+1 of input */
+    const Py_UNICODE *startp = p;
+    const Py_UNICODE *endp = p + size;
+    /* pointer to the beginning of the unencodable characters */
+    /* const Py_UNICODE *badp = NULL; */
+    /* pointer into the output */
+    char *str;
+    /* current output position */
+    Py_ssize_t respos = 0;
+    Py_ssize_t ressize;
+    const char *encoding = (limit == 256) ? "latin-1" : "ascii";
+    const char *reason = (limit == 256) ? "ordinal not in range(256)" : "ordinal not in range(128)";
+    PyObject *errorHandler = NULL;
+    PyObject *exc = NULL;
+    /* the following variable is used for caching string comparisons
+     * -1=not initialized, 0=unknown, 1=strict, 2=replace, 3=ignore, 4=xmlcharrefreplace */
+    int known_errorHandler = -1;
+
+    /* allocate enough for a simple encoding without
+       replacements, if we need more, we'll resize */
+    res = PyString_FromStringAndSize(NULL, size);
+    if (res == NULL)
+        goto onError;
+    if (size == 0)
+	return res;
+    str = PyString_AS_STRING(res);
+    ressize = size;
+
+    while (p<endp) {
+	Py_UNICODE c = *p;
+
+	/* can we encode this? */
+	if (c<limit) {
+	    /* no overflow check, because we know that the space is enough */
+	    *str++ = (char)c;
+	    ++p;
+	}
+	else {
+	    Py_ssize_t unicodepos = p-startp;
+	    Py_ssize_t requiredsize;
+	    PyObject *repunicode;
+	    Py_ssize_t repsize;
+	    Py_ssize_t newpos;
+	    Py_ssize_t respos;
+	    Py_UNICODE *uni2;
+	    /* startpos for collecting unencodable chars */
+	    const Py_UNICODE *collstart = p;
+	    const Py_UNICODE *collend = p;
+	    /* find all unecodable characters */
+	    while ((collend < endp) && ((*collend)>=limit))
+		++collend;
+	    /* cache callback name lookup (if not done yet, i.e. it's the first error) */
+	    if (known_errorHandler==-1) {
+		if ((errors==NULL) || (!strcmp(errors, "strict")))
+		    known_errorHandler = 1;
+		else if (!strcmp(errors, "replace"))
+		    known_errorHandler = 2;
+		else if (!strcmp(errors, "ignore"))
+		    known_errorHandler = 3;
+		else if (!strcmp(errors, "xmlcharrefreplace"))
+		    known_errorHandler = 4;
+		else
+		    known_errorHandler = 0;
+	    }
+	    switch (known_errorHandler) {
+		case 1: /* strict */
+		    raise_encode_exception(&exc, encoding, startp, size, collstart-startp, collend-startp, reason);
+		    goto onError;
+		case 2: /* replace */
+		    while (collstart++<collend)
+			*str++ = '?'; /* fall through */
+		case 3: /* ignore */
+		    p = collend;
+		    break;
+		case 4: /* xmlcharrefreplace */
+		    respos = str-PyString_AS_STRING(res);
+		    /* determine replacement size (temporarily (mis)uses p) */
+		    for (p = collstart, repsize = 0; p < collend; ++p) {
+			if (*p<10)
+			    repsize += 2+1+1;
+			else if (*p<100)
+			    repsize += 2+2+1;
+			else if (*p<1000)
+			    repsize += 2+3+1;
+			else if (*p<10000)
+			    repsize += 2+4+1;
+#ifndef Py_UNICODE_WIDE
+			else
+			    repsize += 2+5+1;
+#else
+			else if (*p<100000)
+			    repsize += 2+5+1;
+			else if (*p<1000000)
+			    repsize += 2+6+1;
+			else
+			    repsize += 2+7+1;
+#endif
+		    }
+		    requiredsize = respos+repsize+(endp-collend);
+		    if (requiredsize > ressize) {
+			if (requiredsize<2*ressize)
+			    requiredsize = 2*ressize;
+			if (_PyString_Resize(&res, requiredsize))
+			    goto onError;
+			str = PyString_AS_STRING(res) + respos;
+			ressize = requiredsize;
+		    }
+		    /* generate replacement (temporarily (mis)uses p) */
+		    for (p = collstart; p < collend; ++p) {
+			str += sprintf(str, "&#%d;", (int)*p);
+		    }
+		    p = collend;
+		    break;
+		default:
+		    repunicode = unicode_encode_call_errorhandler(errors, &errorHandler,
+			encoding, reason, startp, size, &exc,
+			collstart-startp, collend-startp, &newpos);
+		    if (repunicode == NULL)
+			goto onError;
+		    /* need more space? (at least enough for what we
+		       have+the replacement+the rest of the string, so
+		       we won't have to check space for encodable characters) */
+		    respos = str-PyString_AS_STRING(res);
+		    repsize = PyUnicode_GET_SIZE(repunicode);
+		    requiredsize = respos+repsize+(endp-collend);
+		    if (requiredsize > ressize) {
+			if (requiredsize<2*ressize)
+			    requiredsize = 2*ressize;
+			if (_PyString_Resize(&res, requiredsize)) {
+			    Py_DECREF(repunicode);
+			    goto onError;
+			}
+			str = PyString_AS_STRING(res) + respos;
+			ressize = requiredsize;
+		    }
+		    /* check if there is anything unencodable in the replacement
+		       and copy it to the output */
+		    for (uni2 = PyUnicode_AS_UNICODE(repunicode);repsize-->0; ++uni2, ++str) {
+			c = *uni2;
+			if (c >= limit) {
+			    raise_encode_exception(&exc, encoding, startp, size,
+				unicodepos, unicodepos+1, reason);
+			    Py_DECREF(repunicode);
+			    goto onError;
+			}
+			*str = (char)c;
+		    }
+		    p = startp + newpos;
+		    Py_DECREF(repunicode);
+	    }
+	}
+    }
+    /* Resize if we allocated to much */
+    respos = str-PyString_AS_STRING(res);
+    if (respos<ressize)
+       /* If this falls res will be NULL */
+	_PyString_Resize(&res, respos);
+    Py_XDECREF(errorHandler);
+    Py_XDECREF(exc);
+    return res;
+
+    onError:
+    Py_XDECREF(res);
+    Py_XDECREF(errorHandler);
+    Py_XDECREF(exc);
+    return NULL;
+}
+
+PyObject *PyUnicode_EncodeLatin1(const Py_UNICODE *p,
+				 Py_ssize_t size,
+				 const char *errors)
+{
+    return unicode_encode_ucs1(p, size, errors, 256);
+}
+
+PyObject *PyUnicode_AsLatin1String(PyObject *unicode)
+{
+    if (!PyUnicode_Check(unicode)) {
+	PyErr_BadArgument();
+	return NULL;
+    }
+    return PyUnicode_EncodeLatin1(PyUnicode_AS_UNICODE(unicode),
+				  PyUnicode_GET_SIZE(unicode),
+				  NULL);
+}
+
+/* --- 7-bit ASCII Codec -------------------------------------------------- */
+
+PyObject *PyUnicode_DecodeASCII(const char *s,
+				Py_ssize_t size,
+				const char *errors)
+{
+    const char *starts = s;
+    PyUnicodeObject *v;
+    Py_UNICODE *p;
+    Py_ssize_t startinpos;
+    Py_ssize_t endinpos;
+    Py_ssize_t outpos;
+    const char *e;
+    PyObject *errorHandler = NULL;
+    PyObject *exc = NULL;
+
+    /* ASCII is equivalent to the first 128 ordinals in Unicode. */
+    if (size == 1 && *(unsigned char*)s < 128) {
+	Py_UNICODE r = *(unsigned char*)s;
+	return PyUnicode_FromUnicode(&r, 1);
+    }
+
+    v = _PyUnicode_New(size);
+    if (v == NULL)
+	goto onError;
+    if (size == 0)
+	return (PyObject *)v;
+    p = PyUnicode_AS_UNICODE(v);
+    e = s + size;
+    while (s < e) {
+	register unsigned char c = (unsigned char)*s;
+	if (c < 128) {
+	    *p++ = c;
+	    ++s;
+	}
+	else {
+	    startinpos = s-starts;
+	    endinpos = startinpos + 1;
+	    outpos = p - (Py_UNICODE *)PyUnicode_AS_UNICODE(v);
+	    if (unicode_decode_call_errorhandler(
+		 errors, &errorHandler,
+		 "ascii", "ordinal not in range(128)",
+		 starts, size, &startinpos, &endinpos, &exc, &s,
+		 (PyObject **)&v, &outpos, &p))
+		goto onError;
+	}
+    }
+    if (p - PyUnicode_AS_UNICODE(v) < PyString_GET_SIZE(v))
+	if (_PyUnicode_Resize(&v, p - PyUnicode_AS_UNICODE(v)) < 0)
+	    goto onError;
+    Py_XDECREF(errorHandler);
+    Py_XDECREF(exc);
+    return (PyObject *)v;
+
+ onError:
+    Py_XDECREF(v);
+    Py_XDECREF(errorHandler);
+    Py_XDECREF(exc);
+    return NULL;
+}
+
+PyObject *PyUnicode_EncodeASCII(const Py_UNICODE *p,
+				Py_ssize_t size,
+				const char *errors)
+{
+    return unicode_encode_ucs1(p, size, errors, 128);
+}
+
+PyObject *PyUnicode_AsASCIIString(PyObject *unicode)
+{
+    if (!PyUnicode_Check(unicode)) {
+	PyErr_BadArgument();
+	return NULL;
+    }
+    return PyUnicode_EncodeASCII(PyUnicode_AS_UNICODE(unicode),
+				 PyUnicode_GET_SIZE(unicode),
+				 NULL);
+}
+
+#if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T)
+
+/* --- MBCS codecs for Windows -------------------------------------------- */
+
+#if SIZEOF_INT < SIZEOF_SSIZE_T
+#define NEED_RETRY
+#endif
+
+/* XXX This code is limited to "true" double-byte encodings, as
+   a) it assumes an incomplete character consists of a single byte, and
+   b) IsDBCSLeadByte (probably) does not work for non-DBCS multi-byte
+      encodings, see IsDBCSLeadByteEx documentation. */
+
+static int is_dbcs_lead_byte(const char *s, int offset)
+{
+    const char *curr = s + offset;
+
+    if (IsDBCSLeadByte(*curr)) {
+	const char *prev = CharPrev(s, curr);
+	return (prev == curr) || !IsDBCSLeadByte(*prev) || (curr - prev == 2);
+    }
+    return 0;
+}
+
+/*
+ * Decode MBCS string into unicode object. If 'final' is set, converts
+ * trailing lead-byte too. Returns consumed size if succeed, -1 otherwise.
+ */
+static int decode_mbcs(PyUnicodeObject **v,
+			const char *s, /* MBCS string */
+			int size, /* sizeof MBCS string */
+			int final)
+{
+    Py_UNICODE *p;
+    Py_ssize_t n = 0;
+    int usize = 0;
+
+    assert(size >= 0);
+
+    /* Skip trailing lead-byte unless 'final' is set */
+    if (!final && size >= 1 && is_dbcs_lead_byte(s, size - 1))
+	--size;
+
+    /* First get the size of the result */
+    if (size > 0) {
+	usize = MultiByteToWideChar(CP_ACP, 0, s, size, NULL, 0);
+	if (usize == 0) {
+	    PyErr_SetFromWindowsErrWithFilename(0, NULL);
+	    return -1;
+	}
+    }
+
+    if (*v == NULL) {
+	/* Create unicode object */
+	*v = _PyUnicode_New(usize);
+	if (*v == NULL)
+	    return -1;
+    }
+    else {
+	/* Extend unicode object */
+	n = PyUnicode_GET_SIZE(*v);
+	if (_PyUnicode_Resize(v, n + usize) < 0)
+	    return -1;
+    }
+
+    /* Do the conversion */
+    if (size > 0) {
+	p = PyUnicode_AS_UNICODE(*v) + n;
+	if (0 == MultiByteToWideChar(CP_ACP, 0, s, size, p, usize)) {
+	    PyErr_SetFromWindowsErrWithFilename(0, NULL);
+	    return -1;
+	}
+    }
+
+    return size;
+}
+
+PyObject *PyUnicode_DecodeMBCSStateful(const char *s,
+					Py_ssize_t size,
+					const char *errors,
+					Py_ssize_t *consumed)
+{
+    PyUnicodeObject *v = NULL;
+    int done;
+
+    if (consumed)
+	*consumed = 0;
+
+#ifdef NEED_RETRY
+  retry:
+    if (size > INT_MAX)
+	done = decode_mbcs(&v, s, INT_MAX, 0);
+    else
+#endif
+	done = decode_mbcs(&v, s, (int)size, !consumed);
+
+    if (done < 0) {
+        Py_XDECREF(v);
+	return NULL;
+    }
+
+    if (consumed)
+	*consumed += done;
+
+#ifdef NEED_RETRY
+    if (size > INT_MAX) {
+	s += done;
+	size -= done;
+	goto retry;
+    }
+#endif
+
+    return (PyObject *)v;
+}
+
+PyObject *PyUnicode_DecodeMBCS(const char *s,
+				Py_ssize_t size,
+				const char *errors)
+{
+    return PyUnicode_DecodeMBCSStateful(s, size, errors, NULL);
+}
+
+/*
+ * Convert unicode into string object (MBCS).
+ * Returns 0 if succeed, -1 otherwise.
+ */
+static int encode_mbcs(PyObject **repr,
+			const Py_UNICODE *p, /* unicode */
+			int size) /* size of unicode */
+{
+    int mbcssize = 0;
+    Py_ssize_t n = 0;
+
+    assert(size >= 0);
+
+    /* First get the size of the result */
+    if (size > 0) {
+	mbcssize = WideCharToMultiByte(CP_ACP, 0, p, size, NULL, 0, NULL, NULL);
+	if (mbcssize == 0) {
+	    PyErr_SetFromWindowsErrWithFilename(0, NULL);
+	    return -1;
+	}
+    }
+
+    if (*repr == NULL) {
+	/* Create string object */
+	*repr = PyString_FromStringAndSize(NULL, mbcssize);
+	if (*repr == NULL)
+	    return -1;
+    }
+    else {
+	/* Extend string object */
+	n = PyString_Size(*repr);
+	if (_PyString_Resize(repr, n + mbcssize) < 0)
+	    return -1;
+    }
+
+    /* Do the conversion */
+    if (size > 0) {
+	char *s = PyString_AS_STRING(*repr) + n;
+	if (0 == WideCharToMultiByte(CP_ACP, 0, p, size, s, mbcssize, NULL, NULL)) {
+	    PyErr_SetFromWindowsErrWithFilename(0, NULL);
+	    return -1;
+	}
+    }
+
+    return 0;
+}
+
+PyObject *PyUnicode_EncodeMBCS(const Py_UNICODE *p,
+				Py_ssize_t size,
+				const char *errors)
+{
+    PyObject *repr = NULL;
+    int ret;
+
+#ifdef NEED_RETRY
+ retry:
+    if (size > INT_MAX)
+	ret = encode_mbcs(&repr, p, INT_MAX);
+    else
+#endif
+	ret = encode_mbcs(&repr, p, (int)size);
+
+    if (ret < 0) {
+	Py_XDECREF(repr);
+	return NULL;
+    }
+
+#ifdef NEED_RETRY
+    if (size > INT_MAX) {
+	p += INT_MAX;
+	size -= INT_MAX;
+	goto retry;
+    }
+#endif
+
+    return repr;
+}
+
+PyObject *PyUnicode_AsMBCSString(PyObject *unicode)
+{
+    if (!PyUnicode_Check(unicode)) {
+        PyErr_BadArgument();
+        return NULL;
+    }
+    return PyUnicode_EncodeMBCS(PyUnicode_AS_UNICODE(unicode),
+				PyUnicode_GET_SIZE(unicode),
+				NULL);
+}
+
+#undef NEED_RETRY
+
+#endif /* MS_WINDOWS */
+
+/* --- Character Mapping Codec -------------------------------------------- */
+
+PyObject *PyUnicode_DecodeCharmap(const char *s,
+				  Py_ssize_t size,
+				  PyObject *mapping,
+				  const char *errors)
+{
+    const char *starts = s;
+    Py_ssize_t startinpos;
+    Py_ssize_t endinpos;
+    Py_ssize_t outpos;
+    const char *e;
+    PyUnicodeObject *v;
+    Py_UNICODE *p;
+    Py_ssize_t extrachars = 0;
+    PyObject *errorHandler = NULL;
+    PyObject *exc = NULL;
+    Py_UNICODE *mapstring = NULL;
+    Py_ssize_t maplen = 0;
+
+    /* Default to Latin-1 */
+    if (mapping == NULL)
+	return PyUnicode_DecodeLatin1(s, size, errors);
+
+    v = _PyUnicode_New(size);
+    if (v == NULL)
+	goto onError;
+    if (size == 0)
+	return (PyObject *)v;
+    p = PyUnicode_AS_UNICODE(v);
+    e = s + size;
+    if (PyUnicode_CheckExact(mapping)) {
+	mapstring = PyUnicode_AS_UNICODE(mapping);
+	maplen = PyUnicode_GET_SIZE(mapping);
+	while (s < e) {
+	    unsigned char ch = *s;
+	    Py_UNICODE x = 0xfffe; /* illegal value */
+
+	    if (ch < maplen)
+		x = mapstring[ch];
+
+	    if (x == 0xfffe) {
+		/* undefined mapping */
+		outpos = p-PyUnicode_AS_UNICODE(v);
+		startinpos = s-starts;
+		endinpos = startinpos+1;
+		if (unicode_decode_call_errorhandler(
+		     errors, &errorHandler,
+		     "charmap", "character maps to <undefined>",
+		     starts, size, &startinpos, &endinpos, &exc, &s,
+		     (PyObject **)&v, &outpos, &p)) {
+		    goto onError;
+		}
+		continue;
+	    }
+	    *p++ = x;
+	    ++s;
+	}
+    }
+    else {
+	while (s < e) {
+	    unsigned char ch = *s;
+	    PyObject *w, *x;
+
+	    /* Get mapping (char ordinal -> integer, Unicode char or None) */
+	    w = PyInt_FromLong((long)ch);
+	    if (w == NULL)
+		goto onError;
+	    x = PyObject_GetItem(mapping, w);
+	    Py_DECREF(w);
+	    if (x == NULL) {
+		if (PyErr_ExceptionMatches(PyExc_LookupError)) {
+		    /* No mapping found means: mapping is undefined. */
+		    PyErr_Clear();
+		    x = Py_None;
+		    Py_INCREF(x);
+		} else
+		    goto onError;
+	    }
+    
+	    /* Apply mapping */
+	    if (PyInt_Check(x)) {
+		long value = PyInt_AS_LONG(x);
+		if (value < 0 || value > 65535) {
+		    PyErr_SetString(PyExc_TypeError,
+				    "character mapping must be in range(65536)");
+		    Py_DECREF(x);
+		    goto onError;
+		}
+		*p++ = (Py_UNICODE)value;
+	    }
+	    else if (x == Py_None) {
+		/* undefined mapping */
+		outpos = p-PyUnicode_AS_UNICODE(v);
+		startinpos = s-starts;
+		endinpos = startinpos+1;
+		if (unicode_decode_call_errorhandler(
+		     errors, &errorHandler,
+		     "charmap", "character maps to <undefined>",
+		     starts, size, &startinpos, &endinpos, &exc, &s,
+		     (PyObject **)&v, &outpos, &p)) {
+		    Py_DECREF(x);
+		    goto onError;
+		}
+		Py_DECREF(x);
+		continue;
+	    }
+	    else if (PyUnicode_Check(x)) {
+		Py_ssize_t targetsize = PyUnicode_GET_SIZE(x);
+    
+		if (targetsize == 1)
+		    /* 1-1 mapping */
+		    *p++ = *PyUnicode_AS_UNICODE(x);
+    
+		else if (targetsize > 1) {
+		    /* 1-n mapping */
+		    if (targetsize > extrachars) {
+			/* resize first */
+			Py_ssize_t oldpos = p - PyUnicode_AS_UNICODE(v);
+			Py_ssize_t needed = (targetsize - extrachars) + \
+				     (targetsize << 2);
+			extrachars += needed;
+			/* XXX overflow detection missing */
+			if (_PyUnicode_Resize(&v,
+					     PyUnicode_GET_SIZE(v) + needed) < 0) {
+			    Py_DECREF(x);
+			    goto onError;
+			}
+			p = PyUnicode_AS_UNICODE(v) + oldpos;
+		    }
+		    Py_UNICODE_COPY(p,
+				    PyUnicode_AS_UNICODE(x),
+				    targetsize);
+		    p += targetsize;
+		    extrachars -= targetsize;
+		}
+		/* 1-0 mapping: skip the character */
+	    }
+	    else {
+		/* wrong return value */
+		PyErr_SetString(PyExc_TypeError,
+		      "character mapping must return integer, None or unicode");
+		Py_DECREF(x);
+		goto onError;
+	    }
+	    Py_DECREF(x);
+	    ++s;
+	}
+    }
+    if (p - PyUnicode_AS_UNICODE(v) < PyUnicode_GET_SIZE(v))
+	if (_PyUnicode_Resize(&v, p - PyUnicode_AS_UNICODE(v)) < 0)
+	    goto onError;
+    Py_XDECREF(errorHandler);
+    Py_XDECREF(exc);
+    return (PyObject *)v;
+
+ onError:
+    Py_XDECREF(errorHandler);
+    Py_XDECREF(exc);
+    Py_XDECREF(v);
+    return NULL;
+}
+
+/* Charmap encoding: the lookup table */
+
+struct encoding_map{
+  PyObject_HEAD
+  unsigned char level1[32];
+  int count2, count3;
+  unsigned char level23[1];
+};
+
+static PyObject*
+encoding_map_size(PyObject *obj, PyObject* args)
+{
+    struct encoding_map *map = (struct encoding_map*)obj;
+    return PyInt_FromLong(sizeof(*map) - 1 + 16*map->count2 + 
+                          128*map->count3);
+}
+
+static PyMethodDef encoding_map_methods[] = {
+	{"size", encoding_map_size, METH_NOARGS, 
+         PyDoc_STR("Return the size (in bytes) of this object") },
+        { 0 }
+};
+
+static void
+encoding_map_dealloc(PyObject* o)
+{
+	PyObject_FREE(o);
+}
+
+static PyTypeObject EncodingMapType = {
+	PyObject_HEAD_INIT(NULL)
+        0,                      /*ob_size*/
+        "EncodingMap",          /*tp_name*/
+        sizeof(struct encoding_map),   /*tp_basicsize*/
+        0,                      /*tp_itemsize*/
+        /* methods */
+        encoding_map_dealloc,   /*tp_dealloc*/
+        0,                      /*tp_print*/
+        0,                      /*tp_getattr*/
+        0,                      /*tp_setattr*/
+        0,                      /*tp_compare*/
+        0,                      /*tp_repr*/
+        0,                      /*tp_as_number*/
+        0,                      /*tp_as_sequence*/
+        0,                      /*tp_as_mapping*/
+        0,                      /*tp_hash*/
+        0,                      /*tp_call*/
+        0,                      /*tp_str*/
+        0,                      /*tp_getattro*/
+        0,                      /*tp_setattro*/
+        0,                      /*tp_as_buffer*/
+        Py_TPFLAGS_DEFAULT,     /*tp_flags*/
+        0,                      /*tp_doc*/
+        0,                      /*tp_traverse*/
+        0,                      /*tp_clear*/
+        0,                      /*tp_richcompare*/
+        0,                      /*tp_weaklistoffset*/
+        0,                      /*tp_iter*/
+        0,                      /*tp_iternext*/
+        encoding_map_methods,   /*tp_methods*/
+        0,                      /*tp_members*/
+        0,                      /*tp_getset*/
+        0,                      /*tp_base*/
+        0,                      /*tp_dict*/
+        0,                      /*tp_descr_get*/
+        0,                      /*tp_descr_set*/
+        0,                      /*tp_dictoffset*/
+        0,                      /*tp_init*/
+        0,                      /*tp_alloc*/
+        0,                      /*tp_new*/
+        0,                      /*tp_free*/
+        0,                      /*tp_is_gc*/
+};
+
+PyObject*
+PyUnicode_BuildEncodingMap(PyObject* string)
+{
+    Py_UNICODE *decode;
+    PyObject *result;
+    struct encoding_map *mresult;
+    int i;
+    int need_dict = 0;
+    unsigned char level1[32];
+    unsigned char level2[512];
+    unsigned char *mlevel1, *mlevel2, *mlevel3;
+    int count2 = 0, count3 = 0;
+
+    if (!PyUnicode_Check(string) || PyUnicode_GetSize(string) != 256) {
+        PyErr_BadArgument();
+        return NULL;
+    }
+    decode = PyUnicode_AS_UNICODE(string);
+    memset(level1, 0xFF, sizeof level1);
+    memset(level2, 0xFF, sizeof level2);
+
+    /* If there isn't a one-to-one mapping of NULL to \0,
+       or if there are non-BMP characters, we need to use
+       a mapping dictionary. */
+    if (decode[0] != 0)
+        need_dict = 1;
+    for (i = 1; i < 256; i++) {
+        int l1, l2;
+        if (decode[i] == 0
+            #ifdef Py_UNICODE_WIDE
+            || decode[i] > 0xFFFF
+            #endif
+        ) {
+            need_dict = 1;
+            break;
+        }
+        if (decode[i] == 0xFFFE)
+            /* unmapped character */
+            continue;
+        l1 = decode[i] >> 11;
+        l2 = decode[i] >> 7;
+        if (level1[l1] == 0xFF)
+            level1[l1] = count2++;
+        if (level2[l2] == 0xFF)
+            level2[l2] = count3++; 
+    }
+
+    if (count2 >= 0xFF || count3 >= 0xFF)
+        need_dict = 1;
+
+    if (need_dict) {
+        PyObject *result = PyDict_New();
+        PyObject *key, *value;
+        if (!result)
+            return NULL;
+        for (i = 0; i < 256; i++) {
+            key = value = NULL;
+            key = PyInt_FromLong(decode[i]);
+            value = PyInt_FromLong(i);
+            if (!key || !value)
+                goto failed1;
+            if (PyDict_SetItem(result, key, value) == -1)
+                goto failed1;
+            Py_DECREF(key);
+            Py_DECREF(value);
+        }
+        return result;
+      failed1:
+        Py_XDECREF(key);
+        Py_XDECREF(value);
+        Py_DECREF(result);
+        return NULL;
+    }
+
+    /* Create a three-level trie */
+    result = PyObject_MALLOC(sizeof(struct encoding_map) +
+                             16*count2 + 128*count3 - 1);
+    if (!result)
+        return PyErr_NoMemory();
+    PyObject_Init(result, &EncodingMapType);
+    mresult = (struct encoding_map*)result;
+    mresult->count2 = count2;
+    mresult->count3 = count3;
+    mlevel1 = mresult->level1;
+    mlevel2 = mresult->level23;
+    mlevel3 = mresult->level23 + 16*count2;
+    memcpy(mlevel1, level1, 32);
+    memset(mlevel2, 0xFF, 16*count2);
+    memset(mlevel3, 0, 128*count3);
+    count3 = 0;
+    for (i = 1; i < 256; i++) {
+        int o1, o2, o3, i2, i3;
+        if (decode[i] == 0xFFFE)
+            /* unmapped character */
+            continue;
+        o1 = decode[i]>>11;
+        o2 = (decode[i]>>7) & 0xF;
+        i2 = 16*mlevel1[o1] + o2;
+        if (mlevel2[i2] == 0xFF)
+            mlevel2[i2] = count3++;
+        o3 = decode[i] & 0x7F;
+        i3 = 128*mlevel2[i2] + o3;
+        mlevel3[i3] = i;
+    }
+    return result;
+}
+
+static int
+encoding_map_lookup(Py_UNICODE c, PyObject *mapping)
+{
+    struct encoding_map *map = (struct encoding_map*)mapping;
+    int l1 = c>>11;
+    int l2 = (c>>7) & 0xF;
+    int l3 = c & 0x7F;
+    int i;
+
+#ifdef Py_UNICODE_WIDE
+    if (c > 0xFFFF) {
+	return -1;
+    }
+#endif
+    if (c == 0)
+        return 0;
+    /* level 1*/
+    i = map->level1[l1];
+    if (i == 0xFF) {
+        return -1;
+    }
+    /* level 2*/
+    i = map->level23[16*i+l2];
+    if (i == 0xFF) {
+        return -1;
+    }
+    /* level 3 */
+    i = map->level23[16*map->count2 + 128*i + l3];
+    if (i == 0) {
+        return -1;
+    }
+    return i;
+}
+
+/* Lookup the character ch in the mapping. If the character
+   can't be found, Py_None is returned (or NULL, if another
+   error occurred). */
+static PyObject *charmapencode_lookup(Py_UNICODE c, PyObject *mapping)
+{
+    PyObject *w = PyInt_FromLong((long)c);
+    PyObject *x;
+
+    if (w == NULL)
+	 return NULL;
+    x = PyObject_GetItem(mapping, w);
+    Py_DECREF(w);
+    if (x == NULL) {
+	if (PyErr_ExceptionMatches(PyExc_LookupError)) {
+	    /* No mapping found means: mapping is undefined. */
+	    PyErr_Clear();
+	    x = Py_None;
+	    Py_INCREF(x);
+	    return x;
+	} else
+	    return NULL;
+    }
+    else if (x == Py_None)
+	return x;
+    else if (PyInt_Check(x)) {
+	long value = PyInt_AS_LONG(x);
+	if (value < 0 || value > 255) {
+	    PyErr_SetString(PyExc_TypeError,
+			     "character mapping must be in range(256)");
+	    Py_DECREF(x);
+	    return NULL;
+	}
+	return x;
+    }
+    else if (PyString_Check(x))
+	return x;
+    else {
+	/* wrong return value */
+	PyErr_SetString(PyExc_TypeError,
+	      "character mapping must return integer, None or str");
+	Py_DECREF(x);
+	return NULL;
+    }
+}
+
+static int
+charmapencode_resize(PyObject **outobj, Py_ssize_t *outpos, Py_ssize_t requiredsize)
+{
+	Py_ssize_t outsize = PyString_GET_SIZE(*outobj);
+	/* exponentially overallocate to minimize reallocations */
+	if (requiredsize < 2*outsize)
+	    requiredsize = 2*outsize;
+	if (_PyString_Resize(outobj, requiredsize)) {
+	    return 0;
+	}
+	return 1;
+}
+
+typedef enum charmapencode_result { 
+  enc_SUCCESS, enc_FAILED, enc_EXCEPTION 
+}charmapencode_result;
+/* lookup the character, put the result in the output string and adjust
+   various state variables. Reallocate the output string if not enough
+   space is available. Return a new reference to the object that
+   was put in the output buffer, or Py_None, if the mapping was undefined
+   (in which case no character was written) or NULL, if a
+   reallocation error occurred. The caller must decref the result */
+static
+charmapencode_result charmapencode_output(Py_UNICODE c, PyObject *mapping,
+    PyObject **outobj, Py_ssize_t *outpos)
+{
+    PyObject *rep;
+    char *outstart;
+    Py_ssize_t outsize = PyString_GET_SIZE(*outobj);
+
+    if (mapping->ob_type == &EncodingMapType) {
+        int res = encoding_map_lookup(c, mapping);
+	Py_ssize_t requiredsize = *outpos+1;
+        if (res == -1)
+            return enc_FAILED;
+	if (outsize<requiredsize) 
+	    if (!charmapencode_resize(outobj, outpos, requiredsize))
+		return enc_EXCEPTION;
+        outstart = PyString_AS_STRING(*outobj);
+	outstart[(*outpos)++] = (char)res;
+	return enc_SUCCESS;
+    }
+
+    rep = charmapencode_lookup(c, mapping);
+    if (rep==NULL)
+	return enc_EXCEPTION;
+    else if (rep==Py_None) {
+	Py_DECREF(rep);
+	return enc_FAILED;
+    } else {
+	if (PyInt_Check(rep)) {
+	    Py_ssize_t requiredsize = *outpos+1;
+	    if (outsize<requiredsize)
+		if (!charmapencode_resize(outobj, outpos, requiredsize)) {
+		    Py_DECREF(rep);
+		    return enc_EXCEPTION;
+		}
+            outstart = PyString_AS_STRING(*outobj);
+	    outstart[(*outpos)++] = (char)PyInt_AS_LONG(rep);
+	}
+	else {
+	    const char *repchars = PyString_AS_STRING(rep);
+	    Py_ssize_t repsize = PyString_GET_SIZE(rep);
+	    Py_ssize_t requiredsize = *outpos+repsize;
+	    if (outsize<requiredsize)
+		if (!charmapencode_resize(outobj, outpos, requiredsize)) {
+		    Py_DECREF(rep);
+		    return enc_EXCEPTION;
+		}
+            outstart = PyString_AS_STRING(*outobj);
+	    memcpy(outstart + *outpos, repchars, repsize);
+	    *outpos += repsize;
+	}
+    }
+    Py_DECREF(rep);
+    return enc_SUCCESS;
+}
+
+/* handle an error in PyUnicode_EncodeCharmap
+   Return 0 on success, -1 on error */
+static
+int charmap_encoding_error(
+    const Py_UNICODE *p, Py_ssize_t size, Py_ssize_t *inpos, PyObject *mapping,
+    PyObject **exceptionObject,
+    int *known_errorHandler, PyObject **errorHandler, const char *errors,
+    PyObject **res, Py_ssize_t *respos)
+{
+    PyObject *repunicode = NULL; /* initialize to prevent gcc warning */
+    Py_ssize_t repsize;
+    Py_ssize_t newpos;
+    Py_UNICODE *uni2;
+    /* startpos for collecting unencodable chars */
+    Py_ssize_t collstartpos = *inpos;
+    Py_ssize_t collendpos = *inpos+1;
+    Py_ssize_t collpos;
+    char *encoding = "charmap";
+    char *reason = "character maps to <undefined>";
+    charmapencode_result x;
+
+    /* find all unencodable characters */
+    while (collendpos < size) {
+        PyObject *rep;
+        if (mapping->ob_type == &EncodingMapType) {
+	    int res = encoding_map_lookup(p[collendpos], mapping);
+	    if (res != -1)
+		break;
+	    ++collendpos;
+	    continue;
+	}
+            
+	rep = charmapencode_lookup(p[collendpos], mapping);
+	if (rep==NULL)
+	    return -1;
+	else if (rep!=Py_None) {
+	    Py_DECREF(rep);
+	    break;
+	}
+	Py_DECREF(rep);
+	++collendpos;
+    }
+    /* cache callback name lookup
+     * (if not done yet, i.e. it's the first error) */
+    if (*known_errorHandler==-1) {
+	if ((errors==NULL) || (!strcmp(errors, "strict")))
+	    *known_errorHandler = 1;
+	else if (!strcmp(errors, "replace"))
+	    *known_errorHandler = 2;
+	else if (!strcmp(errors, "ignore"))
+	    *known_errorHandler = 3;
+	else if (!strcmp(errors, "xmlcharrefreplace"))
+	    *known_errorHandler = 4;
+	else
+	    *known_errorHandler = 0;
+    }
+    switch (*known_errorHandler) {
+	case 1: /* strict */
+	    raise_encode_exception(exceptionObject, encoding, p, size, collstartpos, collendpos, reason);
+	    return -1;
+	case 2: /* replace */
+	    for (collpos = collstartpos; collpos<collendpos; ++collpos) {
+		x = charmapencode_output('?', mapping, res, respos);
+		if (x==enc_EXCEPTION) {
+		    return -1;
+		}
+		else if (x==enc_FAILED) {
+		    raise_encode_exception(exceptionObject, encoding, p, size, collstartpos, collendpos, reason);
+		    return -1;
+		}
+	    }
+	    /* fall through */
+	case 3: /* ignore */
+	    *inpos = collendpos;
+	    break;
+	case 4: /* xmlcharrefreplace */
+	    /* generate replacement (temporarily (mis)uses p) */
+	    for (collpos = collstartpos; collpos < collendpos; ++collpos) {
+		char buffer[2+29+1+1];
+		char *cp;
+		sprintf(buffer, "&#%d;", (int)p[collpos]);
+		for (cp = buffer; *cp; ++cp) {
+		    x = charmapencode_output(*cp, mapping, res, respos);
+		    if (x==enc_EXCEPTION)
+			return -1;
+		    else if (x==enc_FAILED) {
+			raise_encode_exception(exceptionObject, encoding, p, size, collstartpos, collendpos, reason);
+			return -1;
+		    }
+		}
+	    }
+	    *inpos = collendpos;
+	    break;
+	default:
+	    repunicode = unicode_encode_call_errorhandler(errors, errorHandler,
+		encoding, reason, p, size, exceptionObject,
+		collstartpos, collendpos, &newpos);
+	    if (repunicode == NULL)
+		return -1;
+	    /* generate replacement  */
+	    repsize = PyUnicode_GET_SIZE(repunicode);
+	    for (uni2 = PyUnicode_AS_UNICODE(repunicode); repsize-->0; ++uni2) {
+		x = charmapencode_output(*uni2, mapping, res, respos);
+		if (x==enc_EXCEPTION) {
+		    return -1;
+		}
+		else if (x==enc_FAILED) {
+		    Py_DECREF(repunicode);
+		    raise_encode_exception(exceptionObject, encoding, p, size, collstartpos, collendpos, reason);
+		    return -1;
+		}
+	    }
+	    *inpos = newpos;
+	    Py_DECREF(repunicode);
+    }
+    return 0;
+}
+
+PyObject *PyUnicode_EncodeCharmap(const Py_UNICODE *p,
+				  Py_ssize_t size,
+				  PyObject *mapping,
+				  const char *errors)
+{
+    /* output object */
+    PyObject *res = NULL;
+    /* current input position */
+    Py_ssize_t inpos = 0;
+    /* current output position */
+    Py_ssize_t respos = 0;
+    PyObject *errorHandler = NULL;
+    PyObject *exc = NULL;
+    /* the following variable is used for caching string comparisons
+     * -1=not initialized, 0=unknown, 1=strict, 2=replace,
+     * 3=ignore, 4=xmlcharrefreplace */
+    int known_errorHandler = -1;
+
+    /* Default to Latin-1 */
+    if (mapping == NULL)
+	return PyUnicode_EncodeLatin1(p, size, errors);
+
+    /* allocate enough for a simple encoding without
+       replacements, if we need more, we'll resize */
+    res = PyString_FromStringAndSize(NULL, size);
+    if (res == NULL)
+        goto onError;
+    if (size == 0)
+	return res;
+
+    while (inpos<size) {
+	/* try to encode it */
+	charmapencode_result x = charmapencode_output(p[inpos], mapping, &res, &respos);
+	if (x==enc_EXCEPTION) /* error */
+	    goto onError;
+	if (x==enc_FAILED) { /* unencodable character */
+	    if (charmap_encoding_error(p, size, &inpos, mapping,
+		&exc,
+		&known_errorHandler, &errorHandler, errors,
+		&res, &respos)) {
+		goto onError;
+	    }
+	}
+	else
+	    /* done with this character => adjust input position */
+	    ++inpos;
+    }
+
+    /* Resize if we allocated to much */
+    if (respos<PyString_GET_SIZE(res)) {
+	if (_PyString_Resize(&res, respos))
+	    goto onError;
+    }
+    Py_XDECREF(exc);
+    Py_XDECREF(errorHandler);
+    return res;
+
+    onError:
+    Py_XDECREF(res);
+    Py_XDECREF(exc);
+    Py_XDECREF(errorHandler);
+    return NULL;
+}
+
+PyObject *PyUnicode_AsCharmapString(PyObject *unicode,
+				    PyObject *mapping)
+{
+    if (!PyUnicode_Check(unicode) || mapping == NULL) {
+	PyErr_BadArgument();
+	return NULL;
+    }
+    return PyUnicode_EncodeCharmap(PyUnicode_AS_UNICODE(unicode),
+				   PyUnicode_GET_SIZE(unicode),
+				   mapping,
+				   NULL);
+}
+
+/* create or adjust a UnicodeTranslateError */
+static void make_translate_exception(PyObject **exceptionObject,
+    const Py_UNICODE *unicode, Py_ssize_t size,
+    Py_ssize_t startpos, Py_ssize_t endpos,
+    const char *reason)
+{
+    if (*exceptionObject == NULL) {
+    	*exceptionObject = PyUnicodeTranslateError_Create(
+	    unicode, size, startpos, endpos, reason);
+    }
+    else {
+	if (PyUnicodeTranslateError_SetStart(*exceptionObject, startpos))
+	    goto onError;
+	if (PyUnicodeTranslateError_SetEnd(*exceptionObject, endpos))
+	    goto onError;
+	if (PyUnicodeTranslateError_SetReason(*exceptionObject, reason))
+	    goto onError;
+	return;
+	onError:
+	Py_DECREF(*exceptionObject);
+	*exceptionObject = NULL;
+    }
+}
+
+/* raises a UnicodeTranslateError */
+static void raise_translate_exception(PyObject **exceptionObject,
+    const Py_UNICODE *unicode, Py_ssize_t size,
+    Py_ssize_t startpos, Py_ssize_t endpos,
+    const char *reason)
+{
+    make_translate_exception(exceptionObject,
+	unicode, size, startpos, endpos, reason);
+    if (*exceptionObject != NULL)
+	PyCodec_StrictErrors(*exceptionObject);
+}
+
+/* error handling callback helper:
+   build arguments, call the callback and check the arguments,
+   put the result into newpos and return the replacement string, which
+   has to be freed by the caller */
+static PyObject *unicode_translate_call_errorhandler(const char *errors,
+    PyObject **errorHandler,
+    const char *reason,
+    const Py_UNICODE *unicode, Py_ssize_t size, PyObject **exceptionObject,
+    Py_ssize_t startpos, Py_ssize_t endpos,
+    Py_ssize_t *newpos)
+{
+    static char *argparse = "O!n;translating error handler must return (unicode, int) tuple";
+
+    Py_ssize_t i_newpos;
+    PyObject *restuple;
+    PyObject *resunicode;
+
+    if (*errorHandler == NULL) {
+	*errorHandler = PyCodec_LookupError(errors);
+        if (*errorHandler == NULL)
+	    return NULL;
+    }
+
+    make_translate_exception(exceptionObject,
+	unicode, size, startpos, endpos, reason);
+    if (*exceptionObject == NULL)
+	return NULL;
+
+    restuple = PyObject_CallFunctionObjArgs(
+	*errorHandler, *exceptionObject, NULL);
+    if (restuple == NULL)
+	return NULL;
+    if (!PyTuple_Check(restuple)) {
+	PyErr_Format(PyExc_TypeError, &argparse[4]);
+	Py_DECREF(restuple);
+	return NULL;
+    }
+    if (!PyArg_ParseTuple(restuple, argparse, &PyUnicode_Type,
+	&resunicode, &i_newpos)) {
+	Py_DECREF(restuple);
+	return NULL;
+    }
+    if (i_newpos<0)
+	*newpos = size+i_newpos;
+    else
+        *newpos = i_newpos;
+    if (*newpos<0 || *newpos>size) {
+	PyErr_Format(PyExc_IndexError, "position %zd from error handler out of bounds", *newpos);
+	Py_DECREF(restuple);
+	return NULL;
+    }
+    Py_INCREF(resunicode);
+    Py_DECREF(restuple);
+    return resunicode;
+}
+
+/* Lookup the character ch in the mapping and put the result in result,
+   which must be decrefed by the caller.
+   Return 0 on success, -1 on error */
+static
+int charmaptranslate_lookup(Py_UNICODE c, PyObject *mapping, PyObject **result)
+{
+    PyObject *w = PyInt_FromLong((long)c);
+    PyObject *x;
+
+    if (w == NULL)
+	 return -1;
+    x = PyObject_GetItem(mapping, w);
+    Py_DECREF(w);
+    if (x == NULL) {
+	if (PyErr_ExceptionMatches(PyExc_LookupError)) {
+	    /* No mapping found means: use 1:1 mapping. */
+	    PyErr_Clear();
+	    *result = NULL;
+	    return 0;
+	} else
+	    return -1;
+    }
+    else if (x == Py_None) {
+	*result = x;
+	return 0;
+    }
+    else if (PyInt_Check(x)) {
+	long value = PyInt_AS_LONG(x);
+	long max = PyUnicode_GetMax();
+	if (value < 0 || value > max) {
+	    PyErr_Format(PyExc_TypeError,
+			     "character mapping must be in range(0x%lx)", max+1);
+	    Py_DECREF(x);
+	    return -1;
+	}
+	*result = x;
+	return 0;
+    }
+    else if (PyUnicode_Check(x)) {
+	*result = x;
+	return 0;
+    }
+    else {
+	/* wrong return value */
+	PyErr_SetString(PyExc_TypeError,
+	      "character mapping must return integer, None or unicode");
+	Py_DECREF(x);
+	return -1;
+    }
+}
+/* ensure that *outobj is at least requiredsize characters long,
+if not reallocate and adjust various state variables.
+Return 0 on success, -1 on error */
+static
+int charmaptranslate_makespace(PyObject **outobj, Py_UNICODE **outp,
+    Py_ssize_t requiredsize)
+{
+    Py_ssize_t oldsize = PyUnicode_GET_SIZE(*outobj);
+    if (requiredsize > oldsize) {
+	/* remember old output position */
+	Py_ssize_t outpos = *outp-PyUnicode_AS_UNICODE(*outobj);
+	/* exponentially overallocate to minimize reallocations */
+	if (requiredsize < 2 * oldsize)
+	    requiredsize = 2 * oldsize;
+	if (_PyUnicode_Resize(outobj, requiredsize) < 0)
+	    return -1;
+	*outp = PyUnicode_AS_UNICODE(*outobj) + outpos;
+    }
+    return 0;
+}
+/* lookup the character, put the result in the output string and adjust
+   various state variables. Return a new reference to the object that
+   was put in the output buffer in *result, or Py_None, if the mapping was
+   undefined (in which case no character was written).
+   The called must decref result.
+   Return 0 on success, -1 on error. */
+static
+int charmaptranslate_output(const Py_UNICODE *startinp, const Py_UNICODE *curinp,
+    Py_ssize_t insize, PyObject *mapping, PyObject **outobj, Py_UNICODE **outp,
+    PyObject **res)
+{
+    if (charmaptranslate_lookup(*curinp, mapping, res))
+	return -1;
+    if (*res==NULL) {
+	/* not found => default to 1:1 mapping */
+	*(*outp)++ = *curinp;
+    }
+    else if (*res==Py_None)
+	;
+    else if (PyInt_Check(*res)) {
+	/* no overflow check, because we know that the space is enough */
+	*(*outp)++ = (Py_UNICODE)PyInt_AS_LONG(*res);
+    }
+    else if (PyUnicode_Check(*res)) {
+	Py_ssize_t repsize = PyUnicode_GET_SIZE(*res);
+	if (repsize==1) {
+	    /* no overflow check, because we know that the space is enough */
+	    *(*outp)++ = *PyUnicode_AS_UNICODE(*res);
+	}
+	else if (repsize!=0) {
+	    /* more than one character */
+	    Py_ssize_t requiredsize = (*outp-PyUnicode_AS_UNICODE(*outobj)) +
+		(insize - (curinp-startinp)) +
+		repsize - 1;
+	    if (charmaptranslate_makespace(outobj, outp, requiredsize))
+		return -1;
+	    memcpy(*outp, PyUnicode_AS_UNICODE(*res), sizeof(Py_UNICODE)*repsize);
+	    *outp += repsize;
+	}
+    }
+    else
+	return -1;
+    return 0;
+}
+
+PyObject *PyUnicode_TranslateCharmap(const Py_UNICODE *p,
+				     Py_ssize_t size,
+				     PyObject *mapping,
+				     const char *errors)
+{
+    /* output object */
+    PyObject *res = NULL;
+    /* pointers to the beginning and end+1 of input */
+    const Py_UNICODE *startp = p;
+    const Py_UNICODE *endp = p + size;
+    /* pointer into the output */
+    Py_UNICODE *str;
+    /* current output position */
+    Py_ssize_t respos = 0;
+    char *reason = "character maps to <undefined>";
+    PyObject *errorHandler = NULL;
+    PyObject *exc = NULL;
+    /* the following variable is used for caching string comparisons
+     * -1=not initialized, 0=unknown, 1=strict, 2=replace,
+     * 3=ignore, 4=xmlcharrefreplace */
+    int known_errorHandler = -1;
+
+    if (mapping == NULL) {
+	PyErr_BadArgument();
+	return NULL;
+    }
+
+    /* allocate enough for a simple 1:1 translation without
+       replacements, if we need more, we'll resize */
+    res = PyUnicode_FromUnicode(NULL, size);
+    if (res == NULL)
+	goto onError;
+    if (size == 0)
+	return res;
+    str = PyUnicode_AS_UNICODE(res);
+
+    while (p<endp) {
+	/* try to encode it */
+	PyObject *x = NULL;
+	if (charmaptranslate_output(startp, p, size, mapping, &res, &str, &x)) {
+	    Py_XDECREF(x);
+	    goto onError;
+	}
+	Py_XDECREF(x);
+	if (x!=Py_None) /* it worked => adjust input pointer */
+	    ++p;
+	else { /* untranslatable character */
+	    PyObject *repunicode = NULL; /* initialize to prevent gcc warning */
+	    Py_ssize_t repsize;
+	    Py_ssize_t newpos;
+	    Py_UNICODE *uni2;
+	    /* startpos for collecting untranslatable chars */
+	    const Py_UNICODE *collstart = p;
+	    const Py_UNICODE *collend = p+1;
+	    const Py_UNICODE *coll;
+
+	    /* find all untranslatable characters */
+	    while (collend < endp) {
+		if (charmaptranslate_lookup(*collend, mapping, &x))
+		    goto onError;
+		Py_XDECREF(x);
+		if (x!=Py_None)
+		    break;
+		++collend;
+	    }
+	    /* cache callback name lookup
+	     * (if not done yet, i.e. it's the first error) */
+	    if (known_errorHandler==-1) {
+		if ((errors==NULL) || (!strcmp(errors, "strict")))
+		    known_errorHandler = 1;
+		else if (!strcmp(errors, "replace"))
+		    known_errorHandler = 2;
+		else if (!strcmp(errors, "ignore"))
+		    known_errorHandler = 3;
+		else if (!strcmp(errors, "xmlcharrefreplace"))
+		    known_errorHandler = 4;
+		else
+		    known_errorHandler = 0;
+	    }
+	    switch (known_errorHandler) {
+		case 1: /* strict */
+		    raise_translate_exception(&exc, startp, size, collstart-startp, collend-startp, reason);
+		    goto onError;
+		case 2: /* replace */
+		    /* No need to check for space, this is a 1:1 replacement */
+		    for (coll = collstart; coll<collend; ++coll)
+			*str++ = '?';
+		    /* fall through */
+		case 3: /* ignore */
+		    p = collend;
+		    break;
+		case 4: /* xmlcharrefreplace */
+		    /* generate replacement (temporarily (mis)uses p) */
+		    for (p = collstart; p < collend; ++p) {
+			char buffer[2+29+1+1];
+			char *cp;
+			sprintf(buffer, "&#%d;", (int)*p);
+			if (charmaptranslate_makespace(&res, &str,
+			    (str-PyUnicode_AS_UNICODE(res))+strlen(buffer)+(endp-collend)))
+			    goto onError;
+			for (cp = buffer; *cp; ++cp)
+			    *str++ = *cp;
+		    }
+		    p = collend;
+		    break;
+		default:
+		    repunicode = unicode_translate_call_errorhandler(errors, &errorHandler,
+			reason, startp, size, &exc,
+			collstart-startp, collend-startp, &newpos);
+		    if (repunicode == NULL)
+			goto onError;
+		    /* generate replacement  */
+		    repsize = PyUnicode_GET_SIZE(repunicode);
+		    if (charmaptranslate_makespace(&res, &str,
+			(str-PyUnicode_AS_UNICODE(res))+repsize+(endp-collend))) {
+			Py_DECREF(repunicode);
+			goto onError;
+		    }
+		    for (uni2 = PyUnicode_AS_UNICODE(repunicode); repsize-->0; ++uni2)
+			*str++ = *uni2;
+		    p = startp + newpos;
+		    Py_DECREF(repunicode);
+	    }
+	}
+    }
+    /* Resize if we allocated to much */
+    respos = str-PyUnicode_AS_UNICODE(res);
+    if (respos<PyUnicode_GET_SIZE(res)) {
+	if (_PyUnicode_Resize(&res, respos) < 0)
+	    goto onError;
+    }
+    Py_XDECREF(exc);
+    Py_XDECREF(errorHandler);
+    return res;
+
+    onError:
+    Py_XDECREF(res);
+    Py_XDECREF(exc);
+    Py_XDECREF(errorHandler);
+    return NULL;
+}
+
+PyObject *PyUnicode_Translate(PyObject *str,
+			      PyObject *mapping,
+			      const char *errors)
+{
+    PyObject *result;
+
+    str = PyUnicode_FromObject(str);
+    if (str == NULL)
+	goto onError;
+    result = PyUnicode_TranslateCharmap(PyUnicode_AS_UNICODE(str),
+					PyUnicode_GET_SIZE(str),
+					mapping,
+					errors);
+    Py_DECREF(str);
+    return result;
+
+ onError:
+    Py_XDECREF(str);
+    return NULL;
+}
+
+/* --- Decimal Encoder ---------------------------------------------------- */
+
+int PyUnicode_EncodeDecimal(Py_UNICODE *s,
+			    Py_ssize_t length,
+			    char *output,
+			    const char *errors)
+{
+    Py_UNICODE *p, *end;
+    PyObject *errorHandler = NULL;
+    PyObject *exc = NULL;
+    const char *encoding = "decimal";
+    const char *reason = "invalid decimal Unicode string";
+    /* the following variable is used for caching string comparisons
+     * -1=not initialized, 0=unknown, 1=strict, 2=replace, 3=ignore, 4=xmlcharrefreplace */
+    int known_errorHandler = -1;
+
+    if (output == NULL) {
+	PyErr_BadArgument();
+	return -1;
+    }
+
+    p = s;
+    end = s + length;
+    while (p < end) {
+	register Py_UNICODE ch = *p;
+	int decimal;
+	PyObject *repunicode;
+	Py_ssize_t repsize;
+	Py_ssize_t newpos;
+	Py_UNICODE *uni2;
+	Py_UNICODE *collstart;
+	Py_UNICODE *collend;
+
+	if (Py_UNICODE_ISSPACE(ch)) {
+	    *output++ = ' ';
+	    ++p;
+	    continue;
+	}
+	decimal = Py_UNICODE_TODECIMAL(ch);
+	if (decimal >= 0) {
+	    *output++ = '0' + decimal;
+	    ++p;
+	    continue;
+	}
+	if (0 < ch && ch < 256) {
+	    *output++ = (char)ch;
+	    ++p;
+	    continue;
+	}
+	/* All other characters are considered unencodable */
+	collstart = p;
+	collend = p+1;
+	while (collend < end) {
+	    if ((0 < *collend && *collend < 256) ||
+	        !Py_UNICODE_ISSPACE(*collend) ||
+	        Py_UNICODE_TODECIMAL(*collend))
+		break;
+	}
+	/* cache callback name lookup
+	 * (if not done yet, i.e. it's the first error) */
+	if (known_errorHandler==-1) {
+	    if ((errors==NULL) || (!strcmp(errors, "strict")))
+		known_errorHandler = 1;
+	    else if (!strcmp(errors, "replace"))
+		known_errorHandler = 2;
+	    else if (!strcmp(errors, "ignore"))
+		known_errorHandler = 3;
+	    else if (!strcmp(errors, "xmlcharrefreplace"))
+		known_errorHandler = 4;
+	    else
+		known_errorHandler = 0;
+	}
+	switch (known_errorHandler) {
+	    case 1: /* strict */
+		raise_encode_exception(&exc, encoding, s, length, collstart-s, collend-s, reason);
+		goto onError;
+	    case 2: /* replace */
+		for (p = collstart; p < collend; ++p)
+		    *output++ = '?';
+		/* fall through */
+	    case 3: /* ignore */
+		p = collend;
+		break;
+	    case 4: /* xmlcharrefreplace */
+		/* generate replacement (temporarily (mis)uses p) */
+		for (p = collstart; p < collend; ++p)
+		    output += sprintf(output, "&#%d;", (int)*p);
+		p = collend;
+		break;
+	    default:
+		repunicode = unicode_encode_call_errorhandler(errors, &errorHandler,
+		    encoding, reason, s, length, &exc,
+		    collstart-s, collend-s, &newpos);
+		if (repunicode == NULL)
+		    goto onError;
+		/* generate replacement  */
+		repsize = PyUnicode_GET_SIZE(repunicode);
+		for (uni2 = PyUnicode_AS_UNICODE(repunicode); repsize-->0; ++uni2) {
+		    Py_UNICODE ch = *uni2;
+		    if (Py_UNICODE_ISSPACE(ch))
+			*output++ = ' ';
+		    else {
+			decimal = Py_UNICODE_TODECIMAL(ch);
+			if (decimal >= 0)
+			    *output++ = '0' + decimal;
+			else if (0 < ch && ch < 256)
+			    *output++ = (char)ch;
+			else {
+			    Py_DECREF(repunicode);
+			    raise_encode_exception(&exc, encoding,
+				s, length, collstart-s, collend-s, reason);
+			    goto onError;
+			}
+		    }
+		}
+		p = s + newpos;
+		Py_DECREF(repunicode);
+	}
+    }
+    /* 0-terminate the output string */
+    *output++ = '\0';
+    Py_XDECREF(exc);
+    Py_XDECREF(errorHandler);
+    return 0;
+
+ onError:
+    Py_XDECREF(exc);
+    Py_XDECREF(errorHandler);
+    return -1;
+}
+
+/* --- Helpers ------------------------------------------------------------ */
+
+#define STRINGLIB_CHAR Py_UNICODE
+
+#define STRINGLIB_LEN PyUnicode_GET_SIZE
+#define STRINGLIB_NEW PyUnicode_FromUnicode
+#define STRINGLIB_STR PyUnicode_AS_UNICODE
+
+Py_LOCAL_INLINE(int)
+STRINGLIB_CMP(const Py_UNICODE* str, const Py_UNICODE* other, Py_ssize_t len)
+{
+    if (str[0] != other[0])
+        return 1;
+    return memcmp((void*) str, (void*) other, len * sizeof(Py_UNICODE));
+}
+
+#define STRINGLIB_EMPTY unicode_empty
+
+#include "stringlib/fastsearch.h"
+
+#include "stringlib/count.h"
+#include "stringlib/find.h"
+#include "stringlib/partition.h"
+
+/* helper macro to fixup start/end slice values */
+#define FIX_START_END(obj)                      \
+    if (start < 0)                              \
+        start += (obj)->length;                 \
+    if (start < 0)                              \
+        start = 0;                              \
+    if (end > (obj)->length)                    \
+        end = (obj)->length;                    \
+    if (end < 0)                                \
+        end += (obj)->length;                   \
+    if (end < 0)                                \
+        end = 0;
+
+Py_ssize_t PyUnicode_Count(PyObject *str,
+                           PyObject *substr,
+                           Py_ssize_t start,
+                           Py_ssize_t end)
+{
+    Py_ssize_t result;
+    PyUnicodeObject* str_obj;
+    PyUnicodeObject* sub_obj;
+
+    str_obj = (PyUnicodeObject*) PyUnicode_FromObject(str);
+    if (!str_obj)
+	return -1;
+    sub_obj = (PyUnicodeObject*) PyUnicode_FromObject(substr);
+    if (!sub_obj) {
+	Py_DECREF(str_obj);
+	return -1;
+    }
+
+    FIX_START_END(str_obj);
+
+    result = stringlib_count(
+        str_obj->str + start, end - start, sub_obj->str, sub_obj->length
+        );
+
+    Py_DECREF(sub_obj);
+    Py_DECREF(str_obj);
+
+    return result;
+}
+
+Py_ssize_t PyUnicode_Find(PyObject *str,
+                          PyObject *sub,
+                          Py_ssize_t start,
+                          Py_ssize_t end,
+                          int direction)
+{
+    Py_ssize_t result;
+
+    str = PyUnicode_FromObject(str);
+    if (!str)
+	return -2;
+    sub = PyUnicode_FromObject(sub);
+    if (!sub) {
+	Py_DECREF(str);
+	return -2;
+    }
+
+    if (direction > 0)
+        result = stringlib_find_slice(
+            PyUnicode_AS_UNICODE(str), PyUnicode_GET_SIZE(str),
+            PyUnicode_AS_UNICODE(sub), PyUnicode_GET_SIZE(sub),
+            start, end
+            );
+    else
+        result = stringlib_rfind_slice(
+            PyUnicode_AS_UNICODE(str), PyUnicode_GET_SIZE(str),
+            PyUnicode_AS_UNICODE(sub), PyUnicode_GET_SIZE(sub),
+            start, end
+            );
+
+    Py_DECREF(str);
+    Py_DECREF(sub);
+
+    return result;
+}
+
+static
+int tailmatch(PyUnicodeObject *self,
+	      PyUnicodeObject *substring,
+	      Py_ssize_t start,
+	      Py_ssize_t end,
+	      int direction)
+{
+    if (substring->length == 0)
+        return 1;
+
+    FIX_START_END(self);
+
+    end -= substring->length;
+    if (end < start)
+	return 0;
+
+    if (direction > 0) {
+	if (Py_UNICODE_MATCH(self, end, substring))
+	    return 1;
+    } else {
+        if (Py_UNICODE_MATCH(self, start, substring))
+	    return 1;
+    }
+
+    return 0;
+}
+
+Py_ssize_t PyUnicode_Tailmatch(PyObject *str,
+			PyObject *substr,
+			Py_ssize_t start,
+			Py_ssize_t end,
+			int direction)
+{
+    Py_ssize_t result;
+
+    str = PyUnicode_FromObject(str);
+    if (str == NULL)
+	return -1;
+    substr = PyUnicode_FromObject(substr);
+    if (substr == NULL) {
+	Py_DECREF(str);
+	return -1;
+    }
+
+    result = tailmatch((PyUnicodeObject *)str,
+		       (PyUnicodeObject *)substr,
+		       start, end, direction);
+    Py_DECREF(str);
+    Py_DECREF(substr);
+    return result;
+}
+
+/* Apply fixfct filter to the Unicode object self and return a
+   reference to the modified object */
+
+static
+PyObject *fixup(PyUnicodeObject *self,
+		int (*fixfct)(PyUnicodeObject *s))
+{
+
+    PyUnicodeObject *u;
+
+    u = (PyUnicodeObject*) PyUnicode_FromUnicode(NULL, self->length);
+    if (u == NULL)
+	return NULL;
+
+    Py_UNICODE_COPY(u->str, self->str, self->length);
+
+    if (!fixfct(u) && PyUnicode_CheckExact(self)) {
+	/* fixfct should return TRUE if it modified the buffer. If
+	   FALSE, return a reference to the original buffer instead
+	   (to save space, not time) */
+	Py_INCREF(self);
+	Py_DECREF(u);
+	return (PyObject*) self;
+    }
+    return (PyObject*) u;
+}
+
+static
+int fixupper(PyUnicodeObject *self)
+{
+    Py_ssize_t len = self->length;
+    Py_UNICODE *s = self->str;
+    int status = 0;
+
+    while (len-- > 0) {
+	register Py_UNICODE ch;
+
+	ch = Py_UNICODE_TOUPPER(*s);
+	if (ch != *s) {
+            status = 1;
+	    *s = ch;
+	}
+        s++;
+    }
+
+    return status;
+}
+
+static
+int fixlower(PyUnicodeObject *self)
+{
+    Py_ssize_t len = self->length;
+    Py_UNICODE *s = self->str;
+    int status = 0;
+
+    while (len-- > 0) {
+	register Py_UNICODE ch;
+
+	ch = Py_UNICODE_TOLOWER(*s);
+	if (ch != *s) {
+            status = 1;
+	    *s = ch;
+	}
+        s++;
+    }
+
+    return status;
+}
+
+static
+int fixswapcase(PyUnicodeObject *self)
+{
+    Py_ssize_t len = self->length;
+    Py_UNICODE *s = self->str;
+    int status = 0;
+
+    while (len-- > 0) {
+        if (Py_UNICODE_ISUPPER(*s)) {
+            *s = Py_UNICODE_TOLOWER(*s);
+            status = 1;
+        } else if (Py_UNICODE_ISLOWER(*s)) {
+            *s = Py_UNICODE_TOUPPER(*s);
+            status = 1;
+        }
+        s++;
+    }
+
+    return status;
+}
+
+static
+int fixcapitalize(PyUnicodeObject *self)
+{
+    Py_ssize_t len = self->length;
+    Py_UNICODE *s = self->str;
+    int status = 0;
+
+    if (len == 0)
+	return 0;
+    if (Py_UNICODE_ISLOWER(*s)) {
+	*s = Py_UNICODE_TOUPPER(*s);
+	status = 1;
+    }
+    s++;
+    while (--len > 0) {
+        if (Py_UNICODE_ISUPPER(*s)) {
+            *s = Py_UNICODE_TOLOWER(*s);
+            status = 1;
+        }
+        s++;
+    }
+    return status;
+}
+
+static
+int fixtitle(PyUnicodeObject *self)
+{
+    register Py_UNICODE *p = PyUnicode_AS_UNICODE(self);
+    register Py_UNICODE *e;
+    int previous_is_cased;
+
+    /* Shortcut for single character strings */
+    if (PyUnicode_GET_SIZE(self) == 1) {
+	Py_UNICODE ch = Py_UNICODE_TOTITLE(*p);
+	if (*p != ch) {
+	    *p = ch;
+	    return 1;
+	}
+	else
+	    return 0;
+    }
+
+    e = p + PyUnicode_GET_SIZE(self);
+    previous_is_cased = 0;
+    for (; p < e; p++) {
+	register const Py_UNICODE ch = *p;
+
+	if (previous_is_cased)
+	    *p = Py_UNICODE_TOLOWER(ch);
+	else
+	    *p = Py_UNICODE_TOTITLE(ch);
+
+	if (Py_UNICODE_ISLOWER(ch) ||
+	    Py_UNICODE_ISUPPER(ch) ||
+	    Py_UNICODE_ISTITLE(ch))
+	    previous_is_cased = 1;
+	else
+	    previous_is_cased = 0;
+    }
+    return 1;
+}
+
+PyObject *
+PyUnicode_Join(PyObject *separator, PyObject *seq)
+{
+    PyObject *internal_separator = NULL;
+    const Py_UNICODE blank = ' ';
+    const Py_UNICODE *sep = &blank;
+    Py_ssize_t seplen = 1;
+    PyUnicodeObject *res = NULL; /* the result */
+    Py_ssize_t res_alloc = 100;  /* # allocated bytes for string in res */
+    Py_ssize_t res_used;         /* # used bytes */
+    Py_UNICODE *res_p;       /* pointer to free byte in res's string area */
+    PyObject *fseq;          /* PySequence_Fast(seq) */
+    Py_ssize_t seqlen;              /* len(fseq) -- number of items in sequence */
+    PyObject *item;
+    Py_ssize_t i;
+
+    fseq = PySequence_Fast(seq, "");
+    if (fseq == NULL) {
+    	return NULL;
+    }
+
+    /* Grrrr.  A codec may be invoked to convert str objects to
+     * Unicode, and so it's possible to call back into Python code
+     * during PyUnicode_FromObject(), and so it's possible for a sick
+     * codec to change the size of fseq (if seq is a list).  Therefore
+     * we have to keep refetching the size -- can't assume seqlen
+     * is invariant.
+     */
+    seqlen = PySequence_Fast_GET_SIZE(fseq);
+    /* If empty sequence, return u"". */
+    if (seqlen == 0) {
+    	res = _PyUnicode_New(0);  /* empty sequence; return u"" */
+    	goto Done;
+    }
+    /* If singleton sequence with an exact Unicode, return that. */
+    if (seqlen == 1) {
+	item = PySequence_Fast_GET_ITEM(fseq, 0);
+	if (PyUnicode_CheckExact(item)) {
+	    Py_INCREF(item);
+	    res = (PyUnicodeObject *)item;
+	    goto Done;
+	}
+    }
+
+    /* At least two items to join, or one that isn't exact Unicode. */
+    if (seqlen > 1) {
+        /* Set up sep and seplen -- they're needed. */
+    	if (separator == NULL) {
+	    sep = &blank;
+	    seplen = 1;
+        }
+    	else {
+	    internal_separator = PyUnicode_FromObject(separator);
+	    if (internal_separator == NULL)
+	        goto onError;
+	    sep = PyUnicode_AS_UNICODE(internal_separator);
+	    seplen = PyUnicode_GET_SIZE(internal_separator);
+	    /* In case PyUnicode_FromObject() mutated seq. */
+	    seqlen = PySequence_Fast_GET_SIZE(fseq);
+        }
+    }
+
+    /* Get space. */
+    res = _PyUnicode_New(res_alloc);
+    if (res == NULL)
+        goto onError;
+    res_p = PyUnicode_AS_UNICODE(res);
+    res_used = 0;
+
+    for (i = 0; i < seqlen; ++i) {
+	Py_ssize_t itemlen;
+	Py_ssize_t new_res_used;
+
+	item = PySequence_Fast_GET_ITEM(fseq, i);
+	/* Convert item to Unicode. */
+	if (! PyUnicode_Check(item) && ! PyString_Check(item)) {
+	    PyErr_Format(PyExc_TypeError,
+			 "sequence item %zd: expected string or Unicode,"
+			 " %.80s found",
+			 i, item->ob_type->tp_name);
+	    goto onError;
+	}
+	item = PyUnicode_FromObject(item);
+	if (item == NULL)
+	    goto onError;
+	/* We own a reference to item from here on. */
+
+	/* In case PyUnicode_FromObject() mutated seq. */
+	seqlen = PySequence_Fast_GET_SIZE(fseq);
+
+        /* Make sure we have enough space for the separator and the item. */
+	itemlen = PyUnicode_GET_SIZE(item);
+	new_res_used = res_used + itemlen;
+	if (new_res_used < 0)
+	    goto Overflow;
+	if (i < seqlen - 1) {
+	    new_res_used += seplen;
+	    if (new_res_used < 0)
+		goto Overflow;
+	}
+	if (new_res_used > res_alloc) {
+	    /* double allocated size until it's big enough */
+	    do {
+	        res_alloc += res_alloc;
+	        if (res_alloc <= 0)
+	            goto Overflow;
+	    } while (new_res_used > res_alloc);
+	    if (_PyUnicode_Resize(&res, res_alloc) < 0) {
+		Py_DECREF(item);
+		goto onError;
+	    }
+            res_p = PyUnicode_AS_UNICODE(res) + res_used;
+	}
+
+	/* Copy item, and maybe the separator. */
+	Py_UNICODE_COPY(res_p, PyUnicode_AS_UNICODE(item), itemlen);
+	res_p += itemlen;
+	if (i < seqlen - 1) {
+	    Py_UNICODE_COPY(res_p, sep, seplen);
+	    res_p += seplen;
+	}
+	Py_DECREF(item);
+	res_used = new_res_used;
+    }
+
+    /* Shrink res to match the used area; this probably can't fail,
+     * but it's cheap to check.
+     */
+    if (_PyUnicode_Resize(&res, res_used) < 0)
+	goto onError;
+
+ Done:
+    Py_XDECREF(internal_separator);
+    Py_DECREF(fseq);
+    return (PyObject *)res;
+
+ Overflow:
+    PyErr_SetString(PyExc_OverflowError,
+                    "join() result is too long for a Python string");
+    Py_DECREF(item);
+    /* fall through */
+
+ onError:
+    Py_XDECREF(internal_separator);
+    Py_DECREF(fseq);
+    Py_XDECREF(res);
+    return NULL;
+}
+
+static
+PyUnicodeObject *pad(PyUnicodeObject *self,
+		     Py_ssize_t left,
+		     Py_ssize_t right,
+		     Py_UNICODE fill)
+{
+    PyUnicodeObject *u;
+
+    if (left < 0)
+        left = 0;
+    if (right < 0)
+        right = 0;
+
+    if (left == 0 && right == 0 && PyUnicode_CheckExact(self)) {
+        Py_INCREF(self);
+        return self;
+    }
+
+    u = _PyUnicode_New(left + self->length + right);
+    if (u) {
+        if (left)
+            Py_UNICODE_FILL(u->str, fill, left);
+        Py_UNICODE_COPY(u->str + left, self->str, self->length);
+        if (right)
+            Py_UNICODE_FILL(u->str + left + self->length, fill, right);
+    }
+
+    return u;
+}
+
+#define SPLIT_APPEND(data, left, right)					\
+	str = PyUnicode_FromUnicode((data) + (left), (right) - (left));	\
+	if (!str)							\
+	    goto onError;						\
+	if (PyList_Append(list, str)) {					\
+	    Py_DECREF(str);						\
+	    goto onError;						\
+	}								\
+        else								\
+            Py_DECREF(str);
+
+static
+PyObject *split_whitespace(PyUnicodeObject *self,
+			   PyObject *list,
+			   Py_ssize_t maxcount)
+{
+    register Py_ssize_t i;
+    register Py_ssize_t j;
+    Py_ssize_t len = self->length;
+    PyObject *str;
+
+    for (i = j = 0; i < len; ) {
+	/* find a token */
+	while (i < len && Py_UNICODE_ISSPACE(self->str[i]))
+	    i++;
+	j = i;
+	while (i < len && !Py_UNICODE_ISSPACE(self->str[i]))
+	    i++;
+	if (j < i) {
+	    if (maxcount-- <= 0)
+		break;
+	    SPLIT_APPEND(self->str, j, i);
+	    while (i < len && Py_UNICODE_ISSPACE(self->str[i]))
+		i++;
+	    j = i;
+	}
+    }
+    if (j < len) {
+	SPLIT_APPEND(self->str, j, len);
+    }
+    return list;
+
+ onError:
+    Py_DECREF(list);
+    return NULL;
+}
+
+PyObject *PyUnicode_Splitlines(PyObject *string,
+			       int keepends)
+{
+    register Py_ssize_t i;
+    register Py_ssize_t j;
+    Py_ssize_t len;
+    PyObject *list;
+    PyObject *str;
+    Py_UNICODE *data;
+
+    string = PyUnicode_FromObject(string);
+    if (string == NULL)
+	return NULL;
+    data = PyUnicode_AS_UNICODE(string);
+    len = PyUnicode_GET_SIZE(string);
+
+    list = PyList_New(0);
+    if (!list)
+        goto onError;
+
+    for (i = j = 0; i < len; ) {
+	Py_ssize_t eol;
+
+	/* Find a line and append it */
+	while (i < len && !BLOOM_LINEBREAK(data[i]))
+	    i++;
+
+	/* Skip the line break reading CRLF as one line break */
+	eol = i;
+	if (i < len) {
+	    if (data[i] == '\r' && i + 1 < len &&
+		data[i+1] == '\n')
+		i += 2;
+	    else
+		i++;
+	    if (keepends)
+		eol = i;
+	}
+	SPLIT_APPEND(data, j, eol);
+	j = i;
+    }
+    if (j < len) {
+	SPLIT_APPEND(data, j, len);
+    }
+
+    Py_DECREF(string);
+    return list;
+
+ onError:
+    Py_XDECREF(list);
+    Py_DECREF(string);
+    return NULL;
+}
+
+static
+PyObject *split_char(PyUnicodeObject *self,
+		     PyObject *list,
+		     Py_UNICODE ch,
+		     Py_ssize_t maxcount)
+{
+    register Py_ssize_t i;
+    register Py_ssize_t j;
+    Py_ssize_t len = self->length;
+    PyObject *str;
+
+    for (i = j = 0; i < len; ) {
+	if (self->str[i] == ch) {
+	    if (maxcount-- <= 0)
+		break;
+	    SPLIT_APPEND(self->str, j, i);
+	    i = j = i + 1;
+	} else
+	    i++;
+    }
+    if (j <= len) {
+	SPLIT_APPEND(self->str, j, len);
+    }
+    return list;
+
+ onError:
+    Py_DECREF(list);
+    return NULL;
+}
+
+static
+PyObject *split_substring(PyUnicodeObject *self,
+			  PyObject *list,
+			  PyUnicodeObject *substring,
+			  Py_ssize_t maxcount)
+{
+    register Py_ssize_t i;
+    register Py_ssize_t j;
+    Py_ssize_t len = self->length;
+    Py_ssize_t sublen = substring->length;
+    PyObject *str;
+
+    for (i = j = 0; i <= len - sublen; ) {
+	if (Py_UNICODE_MATCH(self, i, substring)) {
+	    if (maxcount-- <= 0)
+		break;
+	    SPLIT_APPEND(self->str, j, i);
+	    i = j = i + sublen;
+	} else
+	    i++;
+    }
+    if (j <= len) {
+	SPLIT_APPEND(self->str, j, len);
+    }
+    return list;
+
+ onError:
+    Py_DECREF(list);
+    return NULL;
+}
+
+static
+PyObject *rsplit_whitespace(PyUnicodeObject *self,
+			    PyObject *list,
+			    Py_ssize_t maxcount)
+{
+    register Py_ssize_t i;
+    register Py_ssize_t j;
+    Py_ssize_t len = self->length;
+    PyObject *str;
+
+    for (i = j = len - 1; i >= 0; ) {
+	/* find a token */
+	while (i >= 0 && Py_UNICODE_ISSPACE(self->str[i]))
+	    i--;
+	j = i;
+	while (i >= 0 && !Py_UNICODE_ISSPACE(self->str[i]))
+	    i--;
+	if (j > i) {
+	    if (maxcount-- <= 0)
+		break;
+	    SPLIT_APPEND(self->str, i + 1, j + 1);
+	    while (i >= 0 && Py_UNICODE_ISSPACE(self->str[i]))
+		i--;
+	    j = i;
+	}
+    }
+    if (j >= 0) {
+	SPLIT_APPEND(self->str, 0, j + 1);
+    }
+    if (PyList_Reverse(list) < 0)
+        goto onError;
+    return list;
+
+ onError:
+    Py_DECREF(list);
+    return NULL;
+}
+
+static 
+PyObject *rsplit_char(PyUnicodeObject *self,
+		      PyObject *list,
+		      Py_UNICODE ch,
+		      Py_ssize_t maxcount)
+{
+    register Py_ssize_t i;
+    register Py_ssize_t j;
+    Py_ssize_t len = self->length;
+    PyObject *str;
+
+    for (i = j = len - 1; i >= 0; ) {
+	if (self->str[i] == ch) {
+	    if (maxcount-- <= 0)
+		break;
+	    SPLIT_APPEND(self->str, i + 1, j + 1);
+	    j = i = i - 1;
+	} else
+	    i--;
+    }
+    if (j >= -1) {
+	SPLIT_APPEND(self->str, 0, j + 1);
+    }
+    if (PyList_Reverse(list) < 0)
+        goto onError;
+    return list;
+
+ onError:
+    Py_DECREF(list);
+    return NULL;
+}
+
+static 
+PyObject *rsplit_substring(PyUnicodeObject *self,
+			   PyObject *list,
+			   PyUnicodeObject *substring,
+			   Py_ssize_t maxcount)
+{
+    register Py_ssize_t i;
+    register Py_ssize_t j;
+    Py_ssize_t len = self->length;
+    Py_ssize_t sublen = substring->length;
+    PyObject *str;
+
+    for (i = len - sublen, j = len; i >= 0; ) {
+	if (Py_UNICODE_MATCH(self, i, substring)) {
+	    if (maxcount-- <= 0)
+		break;
+	    SPLIT_APPEND(self->str, i + sublen, j);
+	    j = i;
+	    i -= sublen;
+	} else
+	    i--;
+    }
+    if (j >= 0) {
+	SPLIT_APPEND(self->str, 0, j);
+    }
+    if (PyList_Reverse(list) < 0)
+        goto onError;
+    return list;
+
+ onError:
+    Py_DECREF(list);
+    return NULL;
+}
+
+#undef SPLIT_APPEND
+
+static
+PyObject *split(PyUnicodeObject *self,
+		PyUnicodeObject *substring,
+		Py_ssize_t maxcount)
+{
+    PyObject *list;
+
+    if (maxcount < 0)
+        maxcount = PY_SSIZE_T_MAX;
+
+    list = PyList_New(0);
+    if (!list)
+        return NULL;
+
+    if (substring == NULL)
+	return split_whitespace(self,list,maxcount);
+
+    else if (substring->length == 1)
+	return split_char(self,list,substring->str[0],maxcount);
+
+    else if (substring->length == 0) {
+	Py_DECREF(list);
+	PyErr_SetString(PyExc_ValueError, "empty separator");
+	return NULL;
+    }
+    else
+	return split_substring(self,list,substring,maxcount);
+}
+
+static
+PyObject *rsplit(PyUnicodeObject *self,
+		 PyUnicodeObject *substring,
+		 Py_ssize_t maxcount)
+{
+    PyObject *list;
+
+    if (maxcount < 0)
+        maxcount = PY_SSIZE_T_MAX;
+
+    list = PyList_New(0);
+    if (!list)
+        return NULL;
+
+    if (substring == NULL)
+	return rsplit_whitespace(self,list,maxcount);
+
+    else if (substring->length == 1)
+	return rsplit_char(self,list,substring->str[0],maxcount);
+
+    else if (substring->length == 0) {
+	Py_DECREF(list);
+	PyErr_SetString(PyExc_ValueError, "empty separator");
+	return NULL;
+    }
+    else
+	return rsplit_substring(self,list,substring,maxcount);
+}
+
+static
+PyObject *replace(PyUnicodeObject *self,
+		  PyUnicodeObject *str1,
+		  PyUnicodeObject *str2,
+		  Py_ssize_t maxcount)
+{
+    PyUnicodeObject *u;
+
+    if (maxcount < 0)
+	maxcount = PY_SSIZE_T_MAX;
+
+    if (str1->length == str2->length) {
+        /* same length */
+        Py_ssize_t i;
+        if (str1->length == 1) {
+            /* replace characters */
+            Py_UNICODE u1, u2;
+            if (!findchar(self->str, self->length, str1->str[0]))
+                goto nothing;
+            u = (PyUnicodeObject*) PyUnicode_FromUnicode(NULL, self->length);
+            if (!u)
+                return NULL;
+            Py_UNICODE_COPY(u->str, self->str, self->length);
+            u1 = str1->str[0];
+            u2 = str2->str[0];
+            for (i = 0; i < u->length; i++)
+                if (u->str[i] == u1) {
+                    if (--maxcount < 0)
+                        break;
+                    u->str[i] = u2;
+                }
+        } else {
+            i = fastsearch(
+                self->str, self->length, str1->str, str1->length, FAST_SEARCH
+                );
+            if (i < 0)
+                goto nothing;
+            u = (PyUnicodeObject*) PyUnicode_FromUnicode(NULL, self->length);
+            if (!u)
+                return NULL;
+            Py_UNICODE_COPY(u->str, self->str, self->length);
+            while (i <= self->length - str1->length)
+                if (Py_UNICODE_MATCH(self, i, str1)) {
+                    if (--maxcount < 0)
+                        break;
+                    Py_UNICODE_COPY(u->str+i, str2->str, str2->length);
+                    i += str1->length;
+                } else
+                    i++;
+        }
+    } else {
+
+        Py_ssize_t n, i, j, e;
+        Py_ssize_t product, new_size, delta;
+        Py_UNICODE *p;
+
+        /* replace strings */
+        n = stringlib_count(self->str, self->length, str1->str, str1->length);
+        if (n > maxcount)
+            n = maxcount;
+        if (n == 0)
+            goto nothing;
+        /* new_size = self->length + n * (str2->length - str1->length)); */
+        delta = (str2->length - str1->length);
+        if (delta == 0) {
+            new_size = self->length;
+        } else {
+            product = n * (str2->length - str1->length);
+            if ((product / (str2->length - str1->length)) != n) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "replace string is too long");
+                return NULL;
+            }
+            new_size = self->length + product;
+            if (new_size < 0) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "replace string is too long");
+                return NULL;
+            }
+        }
+        u = _PyUnicode_New(new_size);
+        if (!u)
+            return NULL;
+        i = 0;
+        p = u->str;
+        e = self->length - str1->length;
+        if (str1->length > 0) {
+            while (n-- > 0) {
+                /* look for next match */
+                j = i;
+                while (j <= e) {
+                    if (Py_UNICODE_MATCH(self, j, str1))
+                        break;
+                    j++;
+                }
+		if (j > i) {
+                    if (j > e)
+                        break;
+                    /* copy unchanged part [i:j] */
+                    Py_UNICODE_COPY(p, self->str+i, j-i);
+                    p += j - i;
+                }
+                /* copy substitution string */
+                if (str2->length > 0) {
+                    Py_UNICODE_COPY(p, str2->str, str2->length);
+                    p += str2->length;
+                }
+                i = j + str1->length;
+            }
+            if (i < self->length)
+                /* copy tail [i:] */
+                Py_UNICODE_COPY(p, self->str+i, self->length-i);
+        } else {
+            /* interleave */
+            while (n > 0) {
+                Py_UNICODE_COPY(p, str2->str, str2->length);
+                p += str2->length;
+                if (--n <= 0)
+                    break;
+                *p++ = self->str[i++];
+            }
+            Py_UNICODE_COPY(p, self->str+i, self->length-i);
+        }
+    }
+    return (PyObject *) u;
+
+nothing:
+    /* nothing to replace; return original string (when possible) */
+    if (PyUnicode_CheckExact(self)) {
+        Py_INCREF(self);
+        return (PyObject *) self;
+    }
+    return PyUnicode_FromUnicode(self->str, self->length);
+}
+
+/* --- Unicode Object Methods --------------------------------------------- */
+
+PyDoc_STRVAR(title__doc__,
+"S.title() -> unicode\n\
+\n\
+Return a titlecased version of S, i.e. words start with title case\n\
+characters, all remaining cased characters have lower case.");
+
+static PyObject*
+unicode_title(PyUnicodeObject *self)
+{
+    return fixup(self, fixtitle);
+}
+
+PyDoc_STRVAR(capitalize__doc__,
+"S.capitalize() -> unicode\n\
+\n\
+Return a capitalized version of S, i.e. make the first character\n\
+have upper case.");
+
+static PyObject*
+unicode_capitalize(PyUnicodeObject *self)
+{
+    return fixup(self, fixcapitalize);
+}
+
+#if 0
+PyDoc_STRVAR(capwords__doc__,
+"S.capwords() -> unicode\n\
+\n\
+Apply .capitalize() to all words in S and return the result with\n\
+normalized whitespace (all whitespace strings are replaced by ' ').");
+
+static PyObject*
+unicode_capwords(PyUnicodeObject *self)
+{
+    PyObject *list;
+    PyObject *item;
+    Py_ssize_t i;
+
+    /* Split into words */
+    list = split(self, NULL, -1);
+    if (!list)
+        return NULL;
+
+    /* Capitalize each word */
+    for (i = 0; i < PyList_GET_SIZE(list); i++) {
+        item = fixup((PyUnicodeObject *)PyList_GET_ITEM(list, i),
+		     fixcapitalize);
+        if (item == NULL)
+            goto onError;
+        Py_DECREF(PyList_GET_ITEM(list, i));
+        PyList_SET_ITEM(list, i, item);
+    }
+
+    /* Join the words to form a new string */
+    item = PyUnicode_Join(NULL, list);
+
+onError:
+    Py_DECREF(list);
+    return (PyObject *)item;
+}
+#endif
+
+/* Argument converter.  Coerces to a single unicode character */
+
+static int
+convert_uc(PyObject *obj, void *addr)
+{
+	Py_UNICODE *fillcharloc = (Py_UNICODE *)addr;
+	PyObject *uniobj;
+	Py_UNICODE *unistr;
+
+	uniobj = PyUnicode_FromObject(obj);
+	if (uniobj == NULL) {
+		PyErr_SetString(PyExc_TypeError,
+			"The fill character cannot be converted to Unicode");
+		return 0;
+	}
+	if (PyUnicode_GET_SIZE(uniobj) != 1) {
+		PyErr_SetString(PyExc_TypeError,
+			"The fill character must be exactly one character long");
+		Py_DECREF(uniobj);
+		return 0;
+	}
+	unistr = PyUnicode_AS_UNICODE(uniobj);
+	*fillcharloc = unistr[0];
+	Py_DECREF(uniobj);
+	return 1;
+}
+
+PyDoc_STRVAR(center__doc__,
+"S.center(width[, fillchar]) -> unicode\n\
+\n\
+Return S centered in a Unicode string of length width. Padding is\n\
+done using the specified fill character (default is a space)");
+
+static PyObject *
+unicode_center(PyUnicodeObject *self, PyObject *args)
+{
+    Py_ssize_t marg, left;
+    Py_ssize_t width;
+    Py_UNICODE fillchar = ' ';
+
+    if (!PyArg_ParseTuple(args, "n|O&:center", &width, convert_uc, &fillchar))
+        return NULL;
+
+    if (self->length >= width && PyUnicode_CheckExact(self)) {
+        Py_INCREF(self);
+        return (PyObject*) self;
+    }
+
+    marg = width - self->length;
+    left = marg / 2 + (marg & width & 1);
+
+    return (PyObject*) pad(self, left, marg - left, fillchar);
+}
+
+#if 0
+
+/* This code should go into some future Unicode collation support
+   module. The basic comparison should compare ordinals on a naive
+   basis (this is what Java does and thus JPython too). */
+
+/* speedy UTF-16 code point order comparison */
+/* gleaned from: */
+/* http://www-4.ibm.com/software/developer/library/utf16.html?dwzone=unicode */
+
+static short utf16Fixup[32] =
+{
+    0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0x2000, -0x800, -0x800, -0x800, -0x800
+};
+
+static int
+unicode_compare(PyUnicodeObject *str1, PyUnicodeObject *str2)
+{
+    Py_ssize_t len1, len2;
+
+    Py_UNICODE *s1 = str1->str;
+    Py_UNICODE *s2 = str2->str;
+
+    len1 = str1->length;
+    len2 = str2->length;
+
+    while (len1 > 0 && len2 > 0) {
+        Py_UNICODE c1, c2;
+
+        c1 = *s1++;
+        c2 = *s2++;
+
+	if (c1 > (1<<11) * 26)
+	    c1 += utf16Fixup[c1>>11];
+	if (c2 > (1<<11) * 26)
+            c2 += utf16Fixup[c2>>11];
+        /* now c1 and c2 are in UTF-32-compatible order */
+
+        if (c1 != c2)
+            return (c1 < c2) ? -1 : 1;
+
+        len1--; len2--;
+    }
+
+    return (len1 < len2) ? -1 : (len1 != len2);
+}
+
+#else
+
+static int
+unicode_compare(PyUnicodeObject *str1, PyUnicodeObject *str2)
+{
+    register Py_ssize_t len1, len2;
+
+    Py_UNICODE *s1 = str1->str;
+    Py_UNICODE *s2 = str2->str;
+
+    len1 = str1->length;
+    len2 = str2->length;
+
+    while (len1 > 0 && len2 > 0) {
+        Py_UNICODE c1, c2;
+
+        c1 = *s1++;
+        c2 = *s2++;
+
+        if (c1 != c2)
+            return (c1 < c2) ? -1 : 1;
+
+        len1--; len2--;
+    }
+
+    return (len1 < len2) ? -1 : (len1 != len2);
+}
+
+#endif
+
+int PyUnicode_Compare(PyObject *left,
+		      PyObject *right)
+{
+    PyUnicodeObject *u = NULL, *v = NULL;
+    int result;
+
+    /* Coerce the two arguments */
+    u = (PyUnicodeObject *)PyUnicode_FromObject(left);
+    if (u == NULL)
+	goto onError;
+    v = (PyUnicodeObject *)PyUnicode_FromObject(right);
+    if (v == NULL)
+	goto onError;
+
+    /* Shortcut for empty or interned objects */
+    if (v == u) {
+	Py_DECREF(u);
+	Py_DECREF(v);
+	return 0;
+    }
+
+    result = unicode_compare(u, v);
+
+    Py_DECREF(u);
+    Py_DECREF(v);
+    return result;
+
+onError:
+    Py_XDECREF(u);
+    Py_XDECREF(v);
+    return -1;
+}
+
+PyObject *PyUnicode_RichCompare(PyObject *left,
+                                PyObject *right,
+                                int op)
+{
+    int result;
+
+    result = PyUnicode_Compare(left, right);
+    if (result == -1 && PyErr_Occurred())
+        goto onError;
+
+    /* Convert the return value to a Boolean */
+    switch (op) {
+    case Py_EQ:
+        result = (result == 0);
+        break;
+    case Py_NE:
+        result = (result != 0);
+        break;
+    case Py_LE:
+        result = (result <= 0);
+        break;
+    case Py_GE:
+        result = (result >= 0);
+        break;
+    case Py_LT:
+        result = (result == -1);
+        break;
+    case Py_GT:
+        result = (result == 1);
+        break;
+    }
+    return PyBool_FromLong(result);
+
+ onError:
+
+    /* Standard case
+
+       Type errors mean that PyUnicode_FromObject() could not convert
+       one of the arguments (usually the right hand side) to Unicode,
+       ie. we can't handle the comparison request. However, it is
+       possible that the other object knows a comparison method, which
+       is why we return Py_NotImplemented to give the other object a
+       chance.
+
+    */
+    if (PyErr_ExceptionMatches(PyExc_TypeError)) {
+        PyErr_Clear();
+        Py_INCREF(Py_NotImplemented);
+        return Py_NotImplemented;
+    }
+    if (op != Py_EQ && op != Py_NE)
+        return NULL;
+
+    /* Equality comparison.
+
+       This is a special case: we silence any PyExc_UnicodeDecodeError
+       and instead turn it into a PyErr_UnicodeWarning.
+
+    */
+    if (!PyErr_ExceptionMatches(PyExc_UnicodeDecodeError))
+        return NULL;
+    PyErr_Clear();
+    if (PyErr_Warn(PyExc_UnicodeWarning, 
+                   (op == Py_EQ) ? 
+                   "Unicode equal comparison "
+                   "failed to convert both arguments to Unicode - "
+                   "interpreting them as being unequal" :
+                   "Unicode unequal comparison "
+                   "failed to convert both arguments to Unicode - "
+                   "interpreting them as being unequal"
+                   ) < 0)
+        return NULL;
+    result = (op == Py_NE);
+    return PyBool_FromLong(result);
+}
+
+int PyUnicode_Contains(PyObject *container,
+		       PyObject *element)
+{
+    PyObject *str, *sub;
+    int result;
+
+    /* Coerce the two arguments */
+    sub = PyUnicode_FromObject(element);
+    if (!sub) {
+	PyErr_SetString(PyExc_TypeError,
+	    "'in <string>' requires string as left operand");
+        return -1;
+    }
+
+    str = PyUnicode_FromObject(container);
+    if (!str) {
+        Py_DECREF(sub);
+        return -1;
+    }
+
+    result = stringlib_contains_obj(str, sub);
+
+    Py_DECREF(str);
+    Py_DECREF(sub);
+
+    return result;
+}
+
+/* Concat to string or Unicode object giving a new Unicode object. */
+
+PyObject *PyUnicode_Concat(PyObject *left,
+			   PyObject *right)
+{
+    PyUnicodeObject *u = NULL, *v = NULL, *w;
+
+    /* Coerce the two arguments */
+    u = (PyUnicodeObject *)PyUnicode_FromObject(left);
+    if (u == NULL)
+	goto onError;
+    v = (PyUnicodeObject *)PyUnicode_FromObject(right);
+    if (v == NULL)
+	goto onError;
+
+    /* Shortcuts */
+    if (v == unicode_empty) {
+	Py_DECREF(v);
+	return (PyObject *)u;
+    }
+    if (u == unicode_empty) {
+	Py_DECREF(u);
+	return (PyObject *)v;
+    }
+
+    /* Concat the two Unicode strings */
+    w = _PyUnicode_New(u->length + v->length);
+    if (w == NULL)
+	goto onError;
+    Py_UNICODE_COPY(w->str, u->str, u->length);
+    Py_UNICODE_COPY(w->str + u->length, v->str, v->length);
+
+    Py_DECREF(u);
+    Py_DECREF(v);
+    return (PyObject *)w;
+
+onError:
+    Py_XDECREF(u);
+    Py_XDECREF(v);
+    return NULL;
+}
+
+PyDoc_STRVAR(count__doc__,
+"S.count(sub[, start[, end]]) -> int\n\
+\n\
+Return the number of non-overlapping occurrences of substring sub in\n\
+Unicode string S[start:end].  Optional arguments start and end are\n\
+interpreted as in slice notation.");
+
+static PyObject *
+unicode_count(PyUnicodeObject *self, PyObject *args)
+{
+    PyUnicodeObject *substring;
+    Py_ssize_t start = 0;
+    Py_ssize_t end = PY_SSIZE_T_MAX;
+    PyObject *result;
+
+    if (!PyArg_ParseTuple(args, "O|O&O&:count", &substring,
+		_PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
+        return NULL;
+
+    substring = (PyUnicodeObject *)PyUnicode_FromObject(
+        (PyObject *)substring);
+    if (substring == NULL)
+	return NULL;
+
+    FIX_START_END(self);
+
+    result = PyInt_FromSsize_t(
+        stringlib_count(self->str + start, end - start,
+                        substring->str, substring->length)
+        );
+
+    Py_DECREF(substring);
+
+    return result;
+}
+
+PyDoc_STRVAR(encode__doc__,
+"S.encode([encoding[,errors]]) -> string or unicode\n\
+\n\
+Encodes S using the codec registered for encoding. encoding defaults\n\
+to the default encoding. errors may be given to set a different error\n\
+handling scheme. Default is 'strict' meaning that encoding errors raise\n\
+a UnicodeEncodeError. Other possible values are 'ignore', 'replace' and\n\
+'xmlcharrefreplace' as well as any other name registered with\n\
+codecs.register_error that can handle UnicodeEncodeErrors.");
+
+static PyObject *
+unicode_encode(PyUnicodeObject *self, PyObject *args)
+{
+    char *encoding = NULL;
+    char *errors = NULL;
+    PyObject *v;
+    
+    if (!PyArg_ParseTuple(args, "|ss:encode", &encoding, &errors))
+        return NULL;
+    v = PyUnicode_AsEncodedObject((PyObject *)self, encoding, errors);
+    if (v == NULL)
+        goto onError;
+    if (!PyString_Check(v) && !PyUnicode_Check(v)) {
+        PyErr_Format(PyExc_TypeError,
+                     "encoder did not return a string/unicode object "
+                     "(type=%.400s)",
+                     v->ob_type->tp_name);
+        Py_DECREF(v);
+        return NULL;
+    }
+    return v;
+
+ onError:
+    return NULL;
+}
+
+PyDoc_STRVAR(decode__doc__,
+"S.decode([encoding[,errors]]) -> string or unicode\n\
+\n\
+Decodes S using the codec registered for encoding. encoding defaults\n\
+to the default encoding. errors may be given to set a different error\n\
+handling scheme. Default is 'strict' meaning that encoding errors raise\n\
+a UnicodeDecodeError. Other possible values are 'ignore' and 'replace'\n\
+as well as any other name registerd with codecs.register_error that is\n\
+able to handle UnicodeDecodeErrors.");
+
+static PyObject *
+unicode_decode(PyUnicodeObject *self, PyObject *args)
+{
+    char *encoding = NULL;
+    char *errors = NULL;
+    PyObject *v;
+    
+    if (!PyArg_ParseTuple(args, "|ss:decode", &encoding, &errors))
+        return NULL;
+    v = PyUnicode_AsDecodedObject((PyObject *)self, encoding, errors);
+    if (v == NULL)
+        goto onError;
+    if (!PyString_Check(v) && !PyUnicode_Check(v)) {
+        PyErr_Format(PyExc_TypeError,
+                     "decoder did not return a string/unicode object "
+                     "(type=%.400s)",
+                     v->ob_type->tp_name);
+        Py_DECREF(v);
+        return NULL;
+    }
+    return v;
+
+ onError:
+    return NULL;
+}
+
+PyDoc_STRVAR(expandtabs__doc__,
+"S.expandtabs([tabsize]) -> unicode\n\
+\n\
+Return a copy of S where all tab characters are expanded using spaces.\n\
+If tabsize is not given, a tab size of 8 characters is assumed.");
+
+static PyObject*
+unicode_expandtabs(PyUnicodeObject *self, PyObject *args)
+{
+    Py_UNICODE *e;
+    Py_UNICODE *p;
+    Py_UNICODE *q;
+    Py_ssize_t i, j;
+    PyUnicodeObject *u;
+    int tabsize = 8;
+
+    if (!PyArg_ParseTuple(args, "|i:expandtabs", &tabsize))
+	return NULL;
+
+    /* First pass: determine size of output string */
+    i = j = 0;
+    e = self->str + self->length;
+    for (p = self->str; p < e; p++)
+        if (*p == '\t') {
+	    if (tabsize > 0)
+		j += tabsize - (j % tabsize);
+	}
+        else {
+            j++;
+            if (*p == '\n' || *p == '\r') {
+                i += j;
+                j = 0;
+            }
+        }
+
+    /* Second pass: create output string and fill it */
+    u = _PyUnicode_New(i + j);
+    if (!u)
+        return NULL;
+
+    j = 0;
+    q = u->str;
+
+    for (p = self->str; p < e; p++)
+        if (*p == '\t') {
+	    if (tabsize > 0) {
+		i = tabsize - (j % tabsize);
+		j += i;
+		while (i--)
+		    *q++ = ' ';
+	    }
+	}
+	else {
+            j++;
+	    *q++ = *p;
+            if (*p == '\n' || *p == '\r')
+                j = 0;
+        }
+
+    return (PyObject*) u;
+}
+
+PyDoc_STRVAR(find__doc__,
+"S.find(sub [,start [,end]]) -> int\n\
+\n\
+Return the lowest index in S where substring sub is found,\n\
+such that sub is contained within s[start,end].  Optional\n\
+arguments start and end are interpreted as in slice notation.\n\
+\n\
+Return -1 on failure.");
+
+static PyObject *
+unicode_find(PyUnicodeObject *self, PyObject *args)
+{
+    PyObject *substring;
+    Py_ssize_t start = 0;
+    Py_ssize_t end = PY_SSIZE_T_MAX;
+    Py_ssize_t result;
+
+    if (!PyArg_ParseTuple(args, "O|O&O&:find", &substring,
+		_PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
+        return NULL;
+    substring = PyUnicode_FromObject(substring);
+    if (!substring)
+	return NULL;
+
+    result = stringlib_find_slice(
+        PyUnicode_AS_UNICODE(self), PyUnicode_GET_SIZE(self),
+        PyUnicode_AS_UNICODE(substring), PyUnicode_GET_SIZE(substring),
+        start, end
+        );
+
+    Py_DECREF(substring);
+
+    return PyInt_FromSsize_t(result);
+}
+
+static PyObject *
+unicode_getitem(PyUnicodeObject *self, Py_ssize_t index)
+{
+    if (index < 0 || index >= self->length) {
+        PyErr_SetString(PyExc_IndexError, "string index out of range");
+        return NULL;
+    }
+
+    return (PyObject*) PyUnicode_FromUnicode(&self->str[index], 1);
+}
+
+static long
+unicode_hash(PyUnicodeObject *self)
+{
+    /* Since Unicode objects compare equal to their ASCII string
+       counterparts, they should use the individual character values
+       as basis for their hash value.  This is needed to assure that
+       strings and Unicode objects behave in the same way as
+       dictionary keys. */
+
+    register Py_ssize_t len;
+    register Py_UNICODE *p;
+    register long x;
+
+    if (self->hash != -1)
+	return self->hash;
+    len = PyUnicode_GET_SIZE(self);
+    p = PyUnicode_AS_UNICODE(self);
+    x = *p << 7;
+    while (--len >= 0)
+	x = (1000003*x) ^ *p++;
+    x ^= PyUnicode_GET_SIZE(self);
+    if (x == -1)
+	x = -2;
+    self->hash = x;
+    return x;
+}
+
+PyDoc_STRVAR(index__doc__,
+"S.index(sub [,start [,end]]) -> int\n\
+\n\
+Like S.find() but raise ValueError when the substring is not found.");
+
+static PyObject *
+unicode_index(PyUnicodeObject *self, PyObject *args)
+{
+    Py_ssize_t result;
+    PyObject *substring;
+    Py_ssize_t start = 0;
+    Py_ssize_t end = PY_SSIZE_T_MAX;
+
+    if (!PyArg_ParseTuple(args, "O|O&O&:index", &substring,
+		_PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
+        return NULL;
+    substring = PyUnicode_FromObject(substring);
+    if (!substring)
+	return NULL;
+
+    result = stringlib_find_slice(
+        PyUnicode_AS_UNICODE(self), PyUnicode_GET_SIZE(self),
+        PyUnicode_AS_UNICODE(substring), PyUnicode_GET_SIZE(substring),
+        start, end
+        );
+
+    Py_DECREF(substring);
+
+    if (result < 0) {
+        PyErr_SetString(PyExc_ValueError, "substring not found");
+        return NULL;
+    }
+
+    return PyInt_FromSsize_t(result);
+}
+
+PyDoc_STRVAR(islower__doc__,
+"S.islower() -> bool\n\
+\n\
+Return True if all cased characters in S are lowercase and there is\n\
+at least one cased character in S, False otherwise.");
+
+static PyObject*
+unicode_islower(PyUnicodeObject *self)
+{
+    register const Py_UNICODE *p = PyUnicode_AS_UNICODE(self);
+    register const Py_UNICODE *e;
+    int cased;
+
+    /* Shortcut for single character strings */
+    if (PyUnicode_GET_SIZE(self) == 1)
+	return PyBool_FromLong(Py_UNICODE_ISLOWER(*p));
+
+    /* Special case for empty strings */
+    if (PyUnicode_GET_SIZE(self) == 0)
+	return PyBool_FromLong(0);
+
+    e = p + PyUnicode_GET_SIZE(self);
+    cased = 0;
+    for (; p < e; p++) {
+	register const Py_UNICODE ch = *p;
+
+	if (Py_UNICODE_ISUPPER(ch) || Py_UNICODE_ISTITLE(ch))
+	    return PyBool_FromLong(0);
+	else if (!cased && Py_UNICODE_ISLOWER(ch))
+	    cased = 1;
+    }
+    return PyBool_FromLong(cased);
+}
+
+PyDoc_STRVAR(isupper__doc__,
+"S.isupper() -> bool\n\
+\n\
+Return True if all cased characters in S are uppercase and there is\n\
+at least one cased character in S, False otherwise.");
+
+static PyObject*
+unicode_isupper(PyUnicodeObject *self)
+{
+    register const Py_UNICODE *p = PyUnicode_AS_UNICODE(self);
+    register const Py_UNICODE *e;
+    int cased;
+
+    /* Shortcut for single character strings */
+    if (PyUnicode_GET_SIZE(self) == 1)
+	return PyBool_FromLong(Py_UNICODE_ISUPPER(*p) != 0);
+
+    /* Special case for empty strings */
+    if (PyUnicode_GET_SIZE(self) == 0)
+	return PyBool_FromLong(0);
+
+    e = p + PyUnicode_GET_SIZE(self);
+    cased = 0;
+    for (; p < e; p++) {
+	register const Py_UNICODE ch = *p;
+
+	if (Py_UNICODE_ISLOWER(ch) || Py_UNICODE_ISTITLE(ch))
+	    return PyBool_FromLong(0);
+	else if (!cased && Py_UNICODE_ISUPPER(ch))
+	    cased = 1;
+    }
+    return PyBool_FromLong(cased);
+}
+
+PyDoc_STRVAR(istitle__doc__,
+"S.istitle() -> bool\n\
+\n\
+Return True if S is a titlecased string and there is at least one\n\
+character in S, i.e. upper- and titlecase characters may only\n\
+follow uncased characters and lowercase characters only cased ones.\n\
+Return False otherwise.");
+
+static PyObject*
+unicode_istitle(PyUnicodeObject *self)
+{
+    register const Py_UNICODE *p = PyUnicode_AS_UNICODE(self);
+    register const Py_UNICODE *e;
+    int cased, previous_is_cased;
+
+    /* Shortcut for single character strings */
+    if (PyUnicode_GET_SIZE(self) == 1)
+	return PyBool_FromLong((Py_UNICODE_ISTITLE(*p) != 0) ||
+			       (Py_UNICODE_ISUPPER(*p) != 0));
+
+    /* Special case for empty strings */
+    if (PyUnicode_GET_SIZE(self) == 0)
+	return PyBool_FromLong(0);
+
+    e = p + PyUnicode_GET_SIZE(self);
+    cased = 0;
+    previous_is_cased = 0;
+    for (; p < e; p++) {
+	register const Py_UNICODE ch = *p;
+
+	if (Py_UNICODE_ISUPPER(ch) || Py_UNICODE_ISTITLE(ch)) {
+	    if (previous_is_cased)
+		return PyBool_FromLong(0);
+	    previous_is_cased = 1;
+	    cased = 1;
+	}
+	else if (Py_UNICODE_ISLOWER(ch)) {
+	    if (!previous_is_cased)
+		return PyBool_FromLong(0);
+	    previous_is_cased = 1;
+	    cased = 1;
+	}
+	else
+	    previous_is_cased = 0;
+    }
+    return PyBool_FromLong(cased);
+}
+
+PyDoc_STRVAR(isspace__doc__,
+"S.isspace() -> bool\n\
+\n\
+Return True if all characters in S are whitespace\n\
+and there is at least one character in S, False otherwise.");
+
+static PyObject*
+unicode_isspace(PyUnicodeObject *self)
+{
+    register const Py_UNICODE *p = PyUnicode_AS_UNICODE(self);
+    register const Py_UNICODE *e;
+
+    /* Shortcut for single character strings */
+    if (PyUnicode_GET_SIZE(self) == 1 &&
+	Py_UNICODE_ISSPACE(*p))
+	return PyBool_FromLong(1);
+
+    /* Special case for empty strings */
+    if (PyUnicode_GET_SIZE(self) == 0)
+	return PyBool_FromLong(0);
+
+    e = p + PyUnicode_GET_SIZE(self);
+    for (; p < e; p++) {
+	if (!Py_UNICODE_ISSPACE(*p))
+	    return PyBool_FromLong(0);
+    }
+    return PyBool_FromLong(1);
+}
+
+PyDoc_STRVAR(isalpha__doc__,
+"S.isalpha() -> bool\n\
+\n\
+Return True if all characters in S are alphabetic\n\
+and there is at least one character in S, False otherwise.");
+
+static PyObject*
+unicode_isalpha(PyUnicodeObject *self)
+{
+    register const Py_UNICODE *p = PyUnicode_AS_UNICODE(self);
+    register const Py_UNICODE *e;
+
+    /* Shortcut for single character strings */
+    if (PyUnicode_GET_SIZE(self) == 1 &&
+	Py_UNICODE_ISALPHA(*p))
+	return PyBool_FromLong(1);
+
+    /* Special case for empty strings */
+    if (PyUnicode_GET_SIZE(self) == 0)
+	return PyBool_FromLong(0);
+
+    e = p + PyUnicode_GET_SIZE(self);
+    for (; p < e; p++) {
+	if (!Py_UNICODE_ISALPHA(*p))
+	    return PyBool_FromLong(0);
+    }
+    return PyBool_FromLong(1);
+}
+
+PyDoc_STRVAR(isalnum__doc__,
+"S.isalnum() -> bool\n\
+\n\
+Return True if all characters in S are alphanumeric\n\
+and there is at least one character in S, False otherwise.");
+
+static PyObject*
+unicode_isalnum(PyUnicodeObject *self)
+{
+    register const Py_UNICODE *p = PyUnicode_AS_UNICODE(self);
+    register const Py_UNICODE *e;
+
+    /* Shortcut for single character strings */
+    if (PyUnicode_GET_SIZE(self) == 1 &&
+	Py_UNICODE_ISALNUM(*p))
+	return PyBool_FromLong(1);
+
+    /* Special case for empty strings */
+    if (PyUnicode_GET_SIZE(self) == 0)
+	return PyBool_FromLong(0);
+
+    e = p + PyUnicode_GET_SIZE(self);
+    for (; p < e; p++) {
+	if (!Py_UNICODE_ISALNUM(*p))
+	    return PyBool_FromLong(0);
+    }
+    return PyBool_FromLong(1);
+}
+
+PyDoc_STRVAR(isdecimal__doc__,
+"S.isdecimal() -> bool\n\
+\n\
+Return True if there are only decimal characters in S,\n\
+False otherwise.");
+
+static PyObject*
+unicode_isdecimal(PyUnicodeObject *self)
+{
+    register const Py_UNICODE *p = PyUnicode_AS_UNICODE(self);
+    register const Py_UNICODE *e;
+
+    /* Shortcut for single character strings */
+    if (PyUnicode_GET_SIZE(self) == 1 &&
+	Py_UNICODE_ISDECIMAL(*p))
+	return PyBool_FromLong(1);
+
+    /* Special case for empty strings */
+    if (PyUnicode_GET_SIZE(self) == 0)
+	return PyBool_FromLong(0);
+
+    e = p + PyUnicode_GET_SIZE(self);
+    for (; p < e; p++) {
+	if (!Py_UNICODE_ISDECIMAL(*p))
+	    return PyBool_FromLong(0);
+    }
+    return PyBool_FromLong(1);
+}
+
+PyDoc_STRVAR(isdigit__doc__,
+"S.isdigit() -> bool\n\
+\n\
+Return True if all characters in S are digits\n\
+and there is at least one character in S, False otherwise.");
+
+static PyObject*
+unicode_isdigit(PyUnicodeObject *self)
+{
+    register const Py_UNICODE *p = PyUnicode_AS_UNICODE(self);
+    register const Py_UNICODE *e;
+
+    /* Shortcut for single character strings */
+    if (PyUnicode_GET_SIZE(self) == 1 &&
+	Py_UNICODE_ISDIGIT(*p))
+	return PyBool_FromLong(1);
+
+    /* Special case for empty strings */
+    if (PyUnicode_GET_SIZE(self) == 0)
+	return PyBool_FromLong(0);
+
+    e = p + PyUnicode_GET_SIZE(self);
+    for (; p < e; p++) {
+	if (!Py_UNICODE_ISDIGIT(*p))
+	    return PyBool_FromLong(0);
+    }
+    return PyBool_FromLong(1);
+}
+
+PyDoc_STRVAR(isnumeric__doc__,
+"S.isnumeric() -> bool\n\
+\n\
+Return True if there are only numeric characters in S,\n\
+False otherwise.");
+
+static PyObject*
+unicode_isnumeric(PyUnicodeObject *self)
+{
+    register const Py_UNICODE *p = PyUnicode_AS_UNICODE(self);
+    register const Py_UNICODE *e;
+
+    /* Shortcut for single character strings */
+    if (PyUnicode_GET_SIZE(self) == 1 &&
+	Py_UNICODE_ISNUMERIC(*p))
+	return PyBool_FromLong(1);
+
+    /* Special case for empty strings */
+    if (PyUnicode_GET_SIZE(self) == 0)
+	return PyBool_FromLong(0);
+
+    e = p + PyUnicode_GET_SIZE(self);
+    for (; p < e; p++) {
+	if (!Py_UNICODE_ISNUMERIC(*p))
+	    return PyBool_FromLong(0);
+    }
+    return PyBool_FromLong(1);
+}
+
+PyDoc_STRVAR(join__doc__,
+"S.join(sequence) -> unicode\n\
+\n\
+Return a string which is the concatenation of the strings in the\n\
+sequence.  The separator between elements is S.");
+
+static PyObject*
+unicode_join(PyObject *self, PyObject *data)
+{
+    return PyUnicode_Join(self, data);
+}
+
+static Py_ssize_t
+unicode_length(PyUnicodeObject *self)
+{
+    return self->length;
+}
+
+PyDoc_STRVAR(ljust__doc__,
+"S.ljust(width[, fillchar]) -> int\n\
+\n\
+Return S left justified in a Unicode string of length width. Padding is\n\
+done using the specified fill character (default is a space).");
+
+static PyObject *
+unicode_ljust(PyUnicodeObject *self, PyObject *args)
+{
+    Py_ssize_t width;
+    Py_UNICODE fillchar = ' ';
+
+    if (!PyArg_ParseTuple(args, "n|O&:ljust", &width, convert_uc, &fillchar))
+        return NULL;
+
+    if (self->length >= width && PyUnicode_CheckExact(self)) {
+        Py_INCREF(self);
+        return (PyObject*) self;
+    }
+
+    return (PyObject*) pad(self, 0, width - self->length, fillchar);
+}
+
+PyDoc_STRVAR(lower__doc__,
+"S.lower() -> unicode\n\
+\n\
+Return a copy of the string S converted to lowercase.");
+
+static PyObject*
+unicode_lower(PyUnicodeObject *self)
+{
+    return fixup(self, fixlower);
+}
+
+#define LEFTSTRIP 0
+#define RIGHTSTRIP 1
+#define BOTHSTRIP 2
+
+/* Arrays indexed by above */
+static const char *stripformat[] = {"|O:lstrip", "|O:rstrip", "|O:strip"};
+
+#define STRIPNAME(i) (stripformat[i]+3)
+
+/* externally visible for str.strip(unicode) */
+PyObject *
+_PyUnicode_XStrip(PyUnicodeObject *self, int striptype, PyObject *sepobj)
+{
+	Py_UNICODE *s = PyUnicode_AS_UNICODE(self);
+	Py_ssize_t len = PyUnicode_GET_SIZE(self);
+	Py_UNICODE *sep = PyUnicode_AS_UNICODE(sepobj);
+	Py_ssize_t seplen = PyUnicode_GET_SIZE(sepobj);
+	Py_ssize_t i, j;
+
+        BLOOM_MASK sepmask = make_bloom_mask(sep, seplen);
+
+	i = 0;
+	if (striptype != RIGHTSTRIP) {
+            while (i < len && BLOOM_MEMBER(sepmask, s[i], sep, seplen)) {
+                i++;
+            }
+	}
+
+	j = len;
+	if (striptype != LEFTSTRIP) {
+            do {
+                j--;
+            } while (j >= i && BLOOM_MEMBER(sepmask, s[j], sep, seplen));
+            j++;
+	}
+
+	if (i == 0 && j == len && PyUnicode_CheckExact(self)) {
+            Py_INCREF(self);
+            return (PyObject*)self;
+	}
+	else
+            return PyUnicode_FromUnicode(s+i, j-i);
+}
+
+
+static PyObject *
+do_strip(PyUnicodeObject *self, int striptype)
+{
+	Py_UNICODE *s = PyUnicode_AS_UNICODE(self);
+	Py_ssize_t len = PyUnicode_GET_SIZE(self), i, j;
+
+	i = 0;
+	if (striptype != RIGHTSTRIP) {
+		while (i < len && Py_UNICODE_ISSPACE(s[i])) {
+			i++;
+		}
+	}
+
+	j = len;
+	if (striptype != LEFTSTRIP) {
+		do {
+			j--;
+		} while (j >= i && Py_UNICODE_ISSPACE(s[j]));
+		j++;
+	}
+
+	if (i == 0 && j == len && PyUnicode_CheckExact(self)) {
+		Py_INCREF(self);
+		return (PyObject*)self;
+	}
+	else
+		return PyUnicode_FromUnicode(s+i, j-i);
+}
+
+
+static PyObject *
+do_argstrip(PyUnicodeObject *self, int striptype, PyObject *args)
+{
+	PyObject *sep = NULL;
+
+	if (!PyArg_ParseTuple(args, (char *)stripformat[striptype], &sep))
+		return NULL;
+
+	if (sep != NULL && sep != Py_None) {
+		if (PyUnicode_Check(sep))
+			return _PyUnicode_XStrip(self, striptype, sep);
+		else if (PyString_Check(sep)) {
+			PyObject *res;
+			sep = PyUnicode_FromObject(sep);
+			if (sep==NULL)
+				return NULL;
+			res = _PyUnicode_XStrip(self, striptype, sep);
+			Py_DECREF(sep);
+			return res;
+		}
+		else {
+			PyErr_Format(PyExc_TypeError,
+				     "%s arg must be None, unicode or str",
+				     STRIPNAME(striptype));
+			return NULL;
+		}
+	}
+
+	return do_strip(self, striptype);
+}
+
+
+PyDoc_STRVAR(strip__doc__,
+"S.strip([chars]) -> unicode\n\
+\n\
+Return a copy of the string S with leading and trailing\n\
+whitespace removed.\n\
+If chars is given and not None, remove characters in chars instead.\n\
+If chars is a str, it will be converted to unicode before stripping");
+
+static PyObject *
+unicode_strip(PyUnicodeObject *self, PyObject *args)
+{
+	if (PyTuple_GET_SIZE(args) == 0)
+		return do_strip(self, BOTHSTRIP); /* Common case */
+	else
+		return do_argstrip(self, BOTHSTRIP, args);
+}
+
+
+PyDoc_STRVAR(lstrip__doc__,
+"S.lstrip([chars]) -> unicode\n\
+\n\
+Return a copy of the string S with leading whitespace removed.\n\
+If chars is given and not None, remove characters in chars instead.\n\
+If chars is a str, it will be converted to unicode before stripping");
+
+static PyObject *
+unicode_lstrip(PyUnicodeObject *self, PyObject *args)
+{
+	if (PyTuple_GET_SIZE(args) == 0)
+		return do_strip(self, LEFTSTRIP); /* Common case */
+	else
+		return do_argstrip(self, LEFTSTRIP, args);
+}
+
+
+PyDoc_STRVAR(rstrip__doc__,
+"S.rstrip([chars]) -> unicode\n\
+\n\
+Return a copy of the string S with trailing whitespace removed.\n\
+If chars is given and not None, remove characters in chars instead.\n\
+If chars is a str, it will be converted to unicode before stripping");
+
+static PyObject *
+unicode_rstrip(PyUnicodeObject *self, PyObject *args)
+{
+	if (PyTuple_GET_SIZE(args) == 0)
+		return do_strip(self, RIGHTSTRIP); /* Common case */
+	else
+		return do_argstrip(self, RIGHTSTRIP, args);
+}
+
+
+static PyObject*
+unicode_repeat(PyUnicodeObject *str, Py_ssize_t len)
+{
+    PyUnicodeObject *u;
+    Py_UNICODE *p;
+    Py_ssize_t nchars;
+    size_t nbytes;
+
+    if (len < 0)
+        len = 0;
+
+    if (len == 1 && PyUnicode_CheckExact(str)) {
+        /* no repeat, return original string */
+        Py_INCREF(str);
+        return (PyObject*) str;
+    }
+
+    /* ensure # of chars needed doesn't overflow int and # of bytes
+     * needed doesn't overflow size_t
+     */
+    nchars = len * str->length;
+    if (len && nchars / len != str->length) {
+        PyErr_SetString(PyExc_OverflowError,
+                        "repeated string is too long");
+        return NULL;
+    }
+    nbytes = (nchars + 1) * sizeof(Py_UNICODE);
+    if (nbytes / sizeof(Py_UNICODE) != (size_t)(nchars + 1)) {
+        PyErr_SetString(PyExc_OverflowError,
+                        "repeated string is too long");
+        return NULL;
+    }
+    u = _PyUnicode_New(nchars);
+    if (!u)
+        return NULL;
+
+    p = u->str;
+
+    if (str->length == 1 && len > 0) {
+        Py_UNICODE_FILL(p, str->str[0], len);
+    } else {
+	Py_ssize_t done = 0; /* number of characters copied this far */
+	if (done < nchars) {
+            Py_UNICODE_COPY(p, str->str, str->length);
+            done = str->length;
+	}
+	while (done < nchars) {
+            int n = (done <= nchars-done) ? done : nchars-done;
+            Py_UNICODE_COPY(p+done, p, n);
+            done += n;
+	}
+    }
+
+    return (PyObject*) u;
+}
+
+PyObject *PyUnicode_Replace(PyObject *obj,
+			    PyObject *subobj,
+			    PyObject *replobj,
+			    Py_ssize_t maxcount)
+{
+    PyObject *self;
+    PyObject *str1;
+    PyObject *str2;
+    PyObject *result;
+
+    self = PyUnicode_FromObject(obj);
+    if (self == NULL)
+	return NULL;
+    str1 = PyUnicode_FromObject(subobj);
+    if (str1 == NULL) {
+	Py_DECREF(self);
+	return NULL;
+    }
+    str2 = PyUnicode_FromObject(replobj);
+    if (str2 == NULL) {
+	Py_DECREF(self);
+	Py_DECREF(str1);
+	return NULL;
+    }
+    result = replace((PyUnicodeObject *)self,
+		     (PyUnicodeObject *)str1,
+		     (PyUnicodeObject *)str2,
+		     maxcount);
+    Py_DECREF(self);
+    Py_DECREF(str1);
+    Py_DECREF(str2);
+    return result;
+}
+
+PyDoc_STRVAR(replace__doc__,
+"S.replace (old, new[, maxsplit]) -> unicode\n\
+\n\
+Return a copy of S with all occurrences of substring\n\
+old replaced by new.  If the optional argument maxsplit is\n\
+given, only the first maxsplit occurrences are replaced.");
+
+static PyObject*
+unicode_replace(PyUnicodeObject *self, PyObject *args)
+{
+    PyUnicodeObject *str1;
+    PyUnicodeObject *str2;
+    Py_ssize_t maxcount = -1;
+    PyObject *result;
+
+    if (!PyArg_ParseTuple(args, "OO|n:replace", &str1, &str2, &maxcount))
+        return NULL;
+    str1 = (PyUnicodeObject *)PyUnicode_FromObject((PyObject *)str1);
+    if (str1 == NULL)
+	return NULL;
+    str2 = (PyUnicodeObject *)PyUnicode_FromObject((PyObject *)str2);
+    if (str2 == NULL) {
+	Py_DECREF(str1);
+	return NULL;
+    }
+
+    result = replace(self, str1, str2, maxcount);
+
+    Py_DECREF(str1);
+    Py_DECREF(str2);
+    return result;
+}
+
+static
+PyObject *unicode_repr(PyObject *unicode)
+{
+    return unicodeescape_string(PyUnicode_AS_UNICODE(unicode),
+				PyUnicode_GET_SIZE(unicode),
+				1);
+}
+
+PyDoc_STRVAR(rfind__doc__,
+"S.rfind(sub [,start [,end]]) -> int\n\
+\n\
+Return the highest index in S where substring sub is found,\n\
+such that sub is contained within s[start,end].  Optional\n\
+arguments start and end are interpreted as in slice notation.\n\
+\n\
+Return -1 on failure.");
+
+static PyObject *
+unicode_rfind(PyUnicodeObject *self, PyObject *args)
+{
+    PyObject *substring;
+    Py_ssize_t start = 0;
+    Py_ssize_t end = PY_SSIZE_T_MAX;
+    Py_ssize_t result;
+
+    if (!PyArg_ParseTuple(args, "O|O&O&:rfind", &substring,
+		_PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
+        return NULL;
+    substring = PyUnicode_FromObject(substring);
+    if (!substring)
+	return NULL;
+
+    result = stringlib_rfind_slice(
+        PyUnicode_AS_UNICODE(self), PyUnicode_GET_SIZE(self),
+        PyUnicode_AS_UNICODE(substring), PyUnicode_GET_SIZE(substring),
+        start, end
+        );
+
+    Py_DECREF(substring);
+
+    return PyInt_FromSsize_t(result);
+}
+
+PyDoc_STRVAR(rindex__doc__,
+"S.rindex(sub [,start [,end]]) -> int\n\
+\n\
+Like S.rfind() but raise ValueError when the substring is not found.");
+
+static PyObject *
+unicode_rindex(PyUnicodeObject *self, PyObject *args)
+{
+    PyObject *substring;
+    Py_ssize_t start = 0;
+    Py_ssize_t end = PY_SSIZE_T_MAX;
+    Py_ssize_t result;
+
+    if (!PyArg_ParseTuple(args, "O|O&O&:rindex", &substring,
+		_PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
+        return NULL;
+    substring = PyUnicode_FromObject(substring);
+    if (!substring)
+	return NULL;
+
+    result = stringlib_rfind_slice(
+        PyUnicode_AS_UNICODE(self), PyUnicode_GET_SIZE(self),
+        PyUnicode_AS_UNICODE(substring), PyUnicode_GET_SIZE(substring),
+        start, end
+        );
+
+    Py_DECREF(substring);
+
+    if (result < 0) {
+        PyErr_SetString(PyExc_ValueError, "substring not found");
+        return NULL;
+    }
+    return PyInt_FromSsize_t(result);
+}
+
+PyDoc_STRVAR(rjust__doc__,
+"S.rjust(width[, fillchar]) -> unicode\n\
+\n\
+Return S right justified in a Unicode string of length width. Padding is\n\
+done using the specified fill character (default is a space).");
+
+static PyObject *
+unicode_rjust(PyUnicodeObject *self, PyObject *args)
+{
+    Py_ssize_t width;
+    Py_UNICODE fillchar = ' ';
+
+    if (!PyArg_ParseTuple(args, "n|O&:rjust", &width, convert_uc, &fillchar))
+        return NULL;
+
+    if (self->length >= width && PyUnicode_CheckExact(self)) {
+        Py_INCREF(self);
+        return (PyObject*) self;
+    }
+
+    return (PyObject*) pad(self, width - self->length, 0, fillchar);
+}
+
+static PyObject*
+unicode_slice(PyUnicodeObject *self, Py_ssize_t start, Py_ssize_t end)
+{
+    /* standard clamping */
+    if (start < 0)
+        start = 0;
+    if (end < 0)
+        end = 0;
+    if (end > self->length)
+        end = self->length;
+    if (start == 0 && end == self->length && PyUnicode_CheckExact(self)) {
+        /* full slice, return original string */
+        Py_INCREF(self);
+        return (PyObject*) self;
+    }
+    if (start > end)
+        start = end;
+    /* copy slice */
+    return (PyObject*) PyUnicode_FromUnicode(self->str + start,
+					     end - start);
+}
+
+PyObject *PyUnicode_Split(PyObject *s,
+			  PyObject *sep,
+			  Py_ssize_t maxsplit)
+{
+    PyObject *result;
+
+    s = PyUnicode_FromObject(s);
+    if (s == NULL)
+	return NULL;
+    if (sep != NULL) {
+	sep = PyUnicode_FromObject(sep);
+	if (sep == NULL) {
+	    Py_DECREF(s);
+	    return NULL;
+	}
+    }
+
+    result = split((PyUnicodeObject *)s, (PyUnicodeObject *)sep, maxsplit);
+
+    Py_DECREF(s);
+    Py_XDECREF(sep);
+    return result;
+}
+
+PyDoc_STRVAR(split__doc__,
+"S.split([sep [,maxsplit]]) -> list of strings\n\
+\n\
+Return a list of the words in S, using sep as the\n\
+delimiter string.  If maxsplit is given, at most maxsplit\n\
+splits are done. If sep is not specified or is None,\n\
+any whitespace string is a separator.");
+
+static PyObject*
+unicode_split(PyUnicodeObject *self, PyObject *args)
+{
+    PyObject *substring = Py_None;
+    Py_ssize_t maxcount = -1;
+
+    if (!PyArg_ParseTuple(args, "|On:split", &substring, &maxcount))
+        return NULL;
+
+    if (substring == Py_None)
+	return split(self, NULL, maxcount);
+    else if (PyUnicode_Check(substring))
+	return split(self, (PyUnicodeObject *)substring, maxcount);
+    else
+	return PyUnicode_Split((PyObject *)self, substring, maxcount);
+}
+
+PyObject *
+PyUnicode_Partition(PyObject *str_in, PyObject *sep_in)
+{
+    PyObject* str_obj;
+    PyObject* sep_obj;
+    PyObject* out;
+
+    str_obj = PyUnicode_FromObject(str_in);
+    if (!str_obj)
+	return NULL;
+    sep_obj = PyUnicode_FromObject(sep_in);
+    if (!sep_obj) {
+        Py_DECREF(str_obj);
+        return NULL;
+    }
+
+    out = stringlib_partition(
+        str_obj, PyUnicode_AS_UNICODE(str_obj), PyUnicode_GET_SIZE(str_obj),
+        sep_obj, PyUnicode_AS_UNICODE(sep_obj), PyUnicode_GET_SIZE(sep_obj)
+        );
+
+    Py_DECREF(sep_obj);
+    Py_DECREF(str_obj);
+
+    return out;
+}
+
+
+PyObject *
+PyUnicode_RPartition(PyObject *str_in, PyObject *sep_in)
+{
+    PyObject* str_obj;
+    PyObject* sep_obj;
+    PyObject* out;
+
+    str_obj = PyUnicode_FromObject(str_in);
+    if (!str_obj)
+	return NULL;
+    sep_obj = PyUnicode_FromObject(sep_in);
+    if (!sep_obj) {
+        Py_DECREF(str_obj);
+        return NULL;
+    }
+
+    out = stringlib_rpartition(
+        str_obj, PyUnicode_AS_UNICODE(str_obj), PyUnicode_GET_SIZE(str_obj),
+        sep_obj, PyUnicode_AS_UNICODE(sep_obj), PyUnicode_GET_SIZE(sep_obj)
+        );
+
+    Py_DECREF(sep_obj);
+    Py_DECREF(str_obj);
+
+    return out;
+}
+
+PyDoc_STRVAR(partition__doc__,
+"S.partition(sep) -> (head, sep, tail)\n\
+\n\
+Searches for the separator sep in S, and returns the part before it,\n\
+the separator itself, and the part after it.  If the separator is not\n\
+found, returns S and two empty strings.");
+
+static PyObject*
+unicode_partition(PyUnicodeObject *self, PyObject *separator)
+{
+    return PyUnicode_Partition((PyObject *)self, separator);
+}
+
+PyDoc_STRVAR(rpartition__doc__,
+"S.rpartition(sep) -> (tail, sep, head)\n\
+\n\
+Searches for the separator sep in S, starting at the end of S, and returns\n\
+the part before it, the separator itself, and the part after it.  If the\n\
+separator is not found, returns two empty strings and S.");
+
+static PyObject*
+unicode_rpartition(PyUnicodeObject *self, PyObject *separator)
+{
+    return PyUnicode_RPartition((PyObject *)self, separator);
+}
+
+PyObject *PyUnicode_RSplit(PyObject *s,
+			   PyObject *sep,
+			   Py_ssize_t maxsplit)
+{
+    PyObject *result;
+    
+    s = PyUnicode_FromObject(s);
+    if (s == NULL)
+	return NULL;
+    if (sep != NULL) {
+	sep = PyUnicode_FromObject(sep);
+	if (sep == NULL) {
+	    Py_DECREF(s);
+	    return NULL;
+	}
+    }
+
+    result = rsplit((PyUnicodeObject *)s, (PyUnicodeObject *)sep, maxsplit);
+
+    Py_DECREF(s);
+    Py_XDECREF(sep);
+    return result;
+}
+
+PyDoc_STRVAR(rsplit__doc__,
+"S.rsplit([sep [,maxsplit]]) -> list of strings\n\
+\n\
+Return a list of the words in S, using sep as the\n\
+delimiter string, starting at the end of the string and\n\
+working to the front.  If maxsplit is given, at most maxsplit\n\
+splits are done. If sep is not specified, any whitespace string\n\
+is a separator.");
+
+static PyObject*
+unicode_rsplit(PyUnicodeObject *self, PyObject *args)
+{
+    PyObject *substring = Py_None;
+    Py_ssize_t maxcount = -1;
+
+    if (!PyArg_ParseTuple(args, "|On:rsplit", &substring, &maxcount))
+        return NULL;
+
+    if (substring == Py_None)
+	return rsplit(self, NULL, maxcount);
+    else if (PyUnicode_Check(substring))
+	return rsplit(self, (PyUnicodeObject *)substring, maxcount);
+    else
+	return PyUnicode_RSplit((PyObject *)self, substring, maxcount);
+}
+
+PyDoc_STRVAR(splitlines__doc__,
+"S.splitlines([keepends]]) -> list of strings\n\
+\n\
+Return a list of the lines in S, breaking at line boundaries.\n\
+Line breaks are not included in the resulting list unless keepends\n\
+is given and true.");
+
+static PyObject*
+unicode_splitlines(PyUnicodeObject *self, PyObject *args)
+{
+    int keepends = 0;
+
+    if (!PyArg_ParseTuple(args, "|i:splitlines", &keepends))
+        return NULL;
+
+    return PyUnicode_Splitlines((PyObject *)self, keepends);
+}
+
+static
+PyObject *unicode_str(PyUnicodeObject *self)
+{
+    return PyUnicode_AsEncodedString((PyObject *)self, NULL, NULL);
+}
+
+PyDoc_STRVAR(swapcase__doc__,
+"S.swapcase() -> unicode\n\
+\n\
+Return a copy of S with uppercase characters converted to lowercase\n\
+and vice versa.");
+
+static PyObject*
+unicode_swapcase(PyUnicodeObject *self)
+{
+    return fixup(self, fixswapcase);
+}
+
+PyDoc_STRVAR(translate__doc__,
+"S.translate(table) -> unicode\n\
+\n\
+Return a copy of the string S, where all characters have been mapped\n\
+through the given translation table, which must be a mapping of\n\
+Unicode ordinals to Unicode ordinals, Unicode strings or None.\n\
+Unmapped characters are left untouched. Characters mapped to None\n\
+are deleted.");
+
+static PyObject*
+unicode_translate(PyUnicodeObject *self, PyObject *table)
+{
+    return PyUnicode_TranslateCharmap(self->str,
+				      self->length,
+				      table,
+				      "ignore");
+}
+
+PyDoc_STRVAR(upper__doc__,
+"S.upper() -> unicode\n\
+\n\
+Return a copy of S converted to uppercase.");
+
+static PyObject*
+unicode_upper(PyUnicodeObject *self)
+{
+    return fixup(self, fixupper);
+}
+
+PyDoc_STRVAR(zfill__doc__,
+"S.zfill(width) -> unicode\n\
+\n\
+Pad a numeric string x with zeros on the left, to fill a field\n\
+of the specified width. The string x is never truncated.");
+
+static PyObject *
+unicode_zfill(PyUnicodeObject *self, PyObject *args)
+{
+    Py_ssize_t fill;
+    PyUnicodeObject *u;
+
+    Py_ssize_t width;
+    if (!PyArg_ParseTuple(args, "n:zfill", &width))
+        return NULL;
+
+    if (self->length >= width) {
+        if (PyUnicode_CheckExact(self)) {
+            Py_INCREF(self);
+            return (PyObject*) self;
+        }
+        else
+            return PyUnicode_FromUnicode(
+                PyUnicode_AS_UNICODE(self),
+                PyUnicode_GET_SIZE(self)
+            );
+    }
+
+    fill = width - self->length;
+
+    u = pad(self, fill, 0, '0');
+
+    if (u == NULL)
+        return NULL;
+
+    if (u->str[fill] == '+' || u->str[fill] == '-') {
+        /* move sign to beginning of string */
+        u->str[0] = u->str[fill];
+        u->str[fill] = '0';
+    }
+
+    return (PyObject*) u;
+}
+
+#if 0
+static PyObject*
+unicode_freelistsize(PyUnicodeObject *self)
+{
+    return PyInt_FromLong(unicode_freelist_size);
+}
+#endif
+
+PyDoc_STRVAR(startswith__doc__,
+"S.startswith(prefix[, start[, end]]) -> bool\n\
+\n\
+Return True if S starts with the specified prefix, False otherwise.\n\
+With optional start, test S beginning at that position.\n\
+With optional end, stop comparing S at that position.\n\
+prefix can also be a tuple of strings to try.");
+
+static PyObject *
+unicode_startswith(PyUnicodeObject *self,
+		   PyObject *args)
+{
+    PyObject *subobj;
+    PyUnicodeObject *substring;
+    Py_ssize_t start = 0;
+    Py_ssize_t end = PY_SSIZE_T_MAX;
+    int result;
+
+    if (!PyArg_ParseTuple(args, "O|O&O&:startswith", &subobj,
+		_PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
+	return NULL;
+    if (PyTuple_Check(subobj)) {
+        Py_ssize_t i;
+        for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
+            substring = (PyUnicodeObject *)PyUnicode_FromObject(
+                            PyTuple_GET_ITEM(subobj, i));
+            if (substring == NULL)
+                return NULL;
+            result = tailmatch(self, substring, start, end, -1);
+            Py_DECREF(substring);
+            if (result) {
+                Py_RETURN_TRUE;
+            }
+        }
+        /* nothing matched */
+        Py_RETURN_FALSE;
+    }
+    substring = (PyUnicodeObject *)PyUnicode_FromObject(subobj);
+    if (substring == NULL)
+         return NULL;
+    result = tailmatch(self, substring, start, end, -1);
+    Py_DECREF(substring);
+    return PyBool_FromLong(result);
+}
+
+
+PyDoc_STRVAR(endswith__doc__,
+"S.endswith(suffix[, start[, end]]) -> bool\n\
+\n\
+Return True if S ends with the specified suffix, False otherwise.\n\
+With optional start, test S beginning at that position.\n\
+With optional end, stop comparing S at that position.\n\
+suffix can also be a tuple of strings to try.");
+
+static PyObject *
+unicode_endswith(PyUnicodeObject *self,
+		 PyObject *args)
+{
+    PyObject *subobj;
+    PyUnicodeObject *substring;
+    Py_ssize_t start = 0;
+    Py_ssize_t end = PY_SSIZE_T_MAX;
+    int result;
+
+    if (!PyArg_ParseTuple(args, "O|O&O&:endswith", &subobj,
+        _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
+	return NULL;
+    if (PyTuple_Check(subobj)) {
+        Py_ssize_t i;
+        for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
+            substring = (PyUnicodeObject *)PyUnicode_FromObject(
+                            PyTuple_GET_ITEM(subobj, i));
+            if (substring == NULL)
+            return NULL;
+            result = tailmatch(self, substring, start, end, +1);
+            Py_DECREF(substring);
+            if (result) {
+                Py_RETURN_TRUE;
+            }
+        }
+        Py_RETURN_FALSE;
+    }
+    substring = (PyUnicodeObject *)PyUnicode_FromObject(subobj);
+    if (substring == NULL)
+    return NULL;
+
+    result = tailmatch(self, substring, start, end, +1);
+    Py_DECREF(substring);
+    return PyBool_FromLong(result);
+}
+
+
+
+static PyObject *
+unicode_getnewargs(PyUnicodeObject *v)
+{
+	return Py_BuildValue("(u#)", v->str, v->length);
+}
+
+
+static PyMethodDef unicode_methods[] = {
+
+    /* Order is according to common usage: often used methods should
+       appear first, since lookup is done sequentially. */
+
+    {"encode", (PyCFunction) unicode_encode, METH_VARARGS, encode__doc__},
+    {"replace", (PyCFunction) unicode_replace, METH_VARARGS, replace__doc__},
+    {"split", (PyCFunction) unicode_split, METH_VARARGS, split__doc__},
+    {"rsplit", (PyCFunction) unicode_rsplit, METH_VARARGS, rsplit__doc__},
+    {"join", (PyCFunction) unicode_join, METH_O, join__doc__},
+    {"capitalize", (PyCFunction) unicode_capitalize, METH_NOARGS, capitalize__doc__},
+    {"title", (PyCFunction) unicode_title, METH_NOARGS, title__doc__},
+    {"center", (PyCFunction) unicode_center, METH_VARARGS, center__doc__},
+    {"count", (PyCFunction) unicode_count, METH_VARARGS, count__doc__},
+    {"expandtabs", (PyCFunction) unicode_expandtabs, METH_VARARGS, expandtabs__doc__},
+    {"find", (PyCFunction) unicode_find, METH_VARARGS, find__doc__},
+    {"partition", (PyCFunction) unicode_partition, METH_O, partition__doc__},
+    {"index", (PyCFunction) unicode_index, METH_VARARGS, index__doc__},
+    {"ljust", (PyCFunction) unicode_ljust, METH_VARARGS, ljust__doc__},
+    {"lower", (PyCFunction) unicode_lower, METH_NOARGS, lower__doc__},
+    {"lstrip", (PyCFunction) unicode_lstrip, METH_VARARGS, lstrip__doc__},
+    {"decode", (PyCFunction) unicode_decode, METH_VARARGS, decode__doc__},
+/*  {"maketrans", (PyCFunction) unicode_maketrans, METH_VARARGS, maketrans__doc__}, */
+    {"rfind", (PyCFunction) unicode_rfind, METH_VARARGS, rfind__doc__},
+    {"rindex", (PyCFunction) unicode_rindex, METH_VARARGS, rindex__doc__},
+    {"rjust", (PyCFunction) unicode_rjust, METH_VARARGS, rjust__doc__},
+    {"rstrip", (PyCFunction) unicode_rstrip, METH_VARARGS, rstrip__doc__},
+    {"rpartition", (PyCFunction) unicode_rpartition, METH_O, rpartition__doc__},
+    {"splitlines", (PyCFunction) unicode_splitlines, METH_VARARGS, splitlines__doc__},
+    {"strip", (PyCFunction) unicode_strip, METH_VARARGS, strip__doc__},
+    {"swapcase", (PyCFunction) unicode_swapcase, METH_NOARGS, swapcase__doc__},
+    {"translate", (PyCFunction) unicode_translate, METH_O, translate__doc__},
+    {"upper", (PyCFunction) unicode_upper, METH_NOARGS, upper__doc__},
+    {"startswith", (PyCFunction) unicode_startswith, METH_VARARGS, startswith__doc__},
+    {"endswith", (PyCFunction) unicode_endswith, METH_VARARGS, endswith__doc__},
+    {"islower", (PyCFunction) unicode_islower, METH_NOARGS, islower__doc__},
+    {"isupper", (PyCFunction) unicode_isupper, METH_NOARGS, isupper__doc__},
+    {"istitle", (PyCFunction) unicode_istitle, METH_NOARGS, istitle__doc__},
+    {"isspace", (PyCFunction) unicode_isspace, METH_NOARGS, isspace__doc__},
+    {"isdecimal", (PyCFunction) unicode_isdecimal, METH_NOARGS, isdecimal__doc__},
+    {"isdigit", (PyCFunction) unicode_isdigit, METH_NOARGS, isdigit__doc__},
+    {"isnumeric", (PyCFunction) unicode_isnumeric, METH_NOARGS, isnumeric__doc__},
+    {"isalpha", (PyCFunction) unicode_isalpha, METH_NOARGS, isalpha__doc__},
+    {"isalnum", (PyCFunction) unicode_isalnum, METH_NOARGS, isalnum__doc__},
+    {"zfill", (PyCFunction) unicode_zfill, METH_VARARGS, zfill__doc__},
+#if 0
+    {"capwords", (PyCFunction) unicode_capwords, METH_NOARGS, capwords__doc__},
+#endif
+
+#if 0
+    /* This one is just used for debugging the implementation. */
+    {"freelistsize", (PyCFunction) unicode_freelistsize, METH_NOARGS},
+#endif
+
+    {"__getnewargs__",	(PyCFunction)unicode_getnewargs, METH_NOARGS},
+    {NULL, NULL}
+};
+
+static PyObject *
+unicode_mod(PyObject *v, PyObject *w)
+{
+       if (!PyUnicode_Check(v)) {
+               Py_INCREF(Py_NotImplemented);
+               return Py_NotImplemented;
+       }
+       return PyUnicode_Format(v, w);
+}
+
+static PyNumberMethods unicode_as_number = {
+	0,				/*nb_add*/
+	0,				/*nb_subtract*/
+	0,				/*nb_multiply*/
+	0,				/*nb_divide*/
+	unicode_mod,			/*nb_remainder*/
+};
+
+static PySequenceMethods unicode_as_sequence = {
+    (lenfunc) unicode_length, 		/* sq_length */
+    PyUnicode_Concat,		 	/* sq_concat */
+    (ssizeargfunc) unicode_repeat, 	/* sq_repeat */
+    (ssizeargfunc) unicode_getitem, 	/* sq_item */
+    (ssizessizeargfunc) unicode_slice, 	/* sq_slice */
+    0, 					/* sq_ass_item */
+    0, 					/* sq_ass_slice */
+    PyUnicode_Contains, 		/* sq_contains */
+};
+
+static PyObject*
+unicode_subscript(PyUnicodeObject* self, PyObject* item)
+{
+    if (PyIndex_Check(item)) {
+        Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+        if (i == -1 && PyErr_Occurred())
+            return NULL;
+        if (i < 0)
+            i += PyUnicode_GET_SIZE(self);
+        return unicode_getitem(self, i);
+    } else if (PySlice_Check(item)) {
+        Py_ssize_t start, stop, step, slicelength, cur, i;
+        Py_UNICODE* source_buf;
+        Py_UNICODE* result_buf;
+        PyObject* result;
+
+        if (PySlice_GetIndicesEx((PySliceObject*)item, PyUnicode_GET_SIZE(self),
+				 &start, &stop, &step, &slicelength) < 0) {
+            return NULL;
+        }
+
+        if (slicelength <= 0) {
+            return PyUnicode_FromUnicode(NULL, 0);
+        } else {
+            source_buf = PyUnicode_AS_UNICODE((PyObject*)self);
+            result_buf = (Py_UNICODE *)PyMem_MALLOC(slicelength*
+                                                    sizeof(Py_UNICODE));
+	    
+	    if (result_buf == NULL)
+		    return PyErr_NoMemory();
+
+            for (cur = start, i = 0; i < slicelength; cur += step, i++) {
+                result_buf[i] = source_buf[cur];
+            }
+
+            result = PyUnicode_FromUnicode(result_buf, slicelength);
+            PyMem_FREE(result_buf);
+            return result;
+        }
+    } else {
+        PyErr_SetString(PyExc_TypeError, "string indices must be integers");
+        return NULL;
+    }
+}
+
+static PyMappingMethods unicode_as_mapping = {
+    (lenfunc)unicode_length,		/* mp_length */
+    (binaryfunc)unicode_subscript,	/* mp_subscript */
+    (objobjargproc)0,			/* mp_ass_subscript */
+};
+
+static Py_ssize_t
+unicode_buffer_getreadbuf(PyUnicodeObject *self,
+			  Py_ssize_t index,
+			  const void **ptr)
+{
+    if (index != 0) {
+        PyErr_SetString(PyExc_SystemError,
+			"accessing non-existent unicode segment");
+        return -1;
+    }
+    *ptr = (void *) self->str;
+    return PyUnicode_GET_DATA_SIZE(self);
+}
+
+static Py_ssize_t
+unicode_buffer_getwritebuf(PyUnicodeObject *self, Py_ssize_t index,
+			   const void **ptr)
+{
+    PyErr_SetString(PyExc_TypeError,
+		    "cannot use unicode as modifiable buffer");
+    return -1;
+}
+
+static int
+unicode_buffer_getsegcount(PyUnicodeObject *self,
+			   Py_ssize_t *lenp)
+{
+    if (lenp)
+        *lenp = PyUnicode_GET_DATA_SIZE(self);
+    return 1;
+}
+
+static Py_ssize_t
+unicode_buffer_getcharbuf(PyUnicodeObject *self,
+			  Py_ssize_t index,
+			  const void **ptr)
+{
+    PyObject *str;
+
+    if (index != 0) {
+        PyErr_SetString(PyExc_SystemError,
+			"accessing non-existent unicode segment");
+        return -1;
+    }
+    str = _PyUnicode_AsDefaultEncodedString((PyObject *)self, NULL);
+    if (str == NULL)
+	return -1;
+    *ptr = (void *) PyString_AS_STRING(str);
+    return PyString_GET_SIZE(str);
+}
+
+/* Helpers for PyUnicode_Format() */
+
+static PyObject *
+getnextarg(PyObject *args, Py_ssize_t arglen, Py_ssize_t *p_argidx)
+{
+    Py_ssize_t argidx = *p_argidx;
+    if (argidx < arglen) {
+	(*p_argidx)++;
+	if (arglen < 0)
+	    return args;
+	else
+	    return PyTuple_GetItem(args, argidx);
+    }
+    PyErr_SetString(PyExc_TypeError,
+		    "not enough arguments for format string");
+    return NULL;
+}
+
+#define F_LJUST (1<<0)
+#define F_SIGN	(1<<1)
+#define F_BLANK (1<<2)
+#define F_ALT	(1<<3)
+#define F_ZERO	(1<<4)
+
+static Py_ssize_t
+strtounicode(Py_UNICODE *buffer, const char *charbuffer)
+{
+    register Py_ssize_t i;
+    Py_ssize_t len = strlen(charbuffer);
+    for (i = len - 1; i >= 0; i--)
+	buffer[i] = (Py_UNICODE) charbuffer[i];
+
+    return len;
+}
+
+static int
+doubletounicode(Py_UNICODE *buffer, size_t len, const char *format, double x)
+{
+    Py_ssize_t result;
+
+    PyOS_ascii_formatd((char *)buffer, len, format, x);
+    result = strtounicode(buffer, (char *)buffer);
+    return Py_SAFE_DOWNCAST(result, Py_ssize_t, int);
+}
+
+static int
+longtounicode(Py_UNICODE *buffer, size_t len, const char *format, long x)
+{
+    Py_ssize_t result;
+
+    PyOS_snprintf((char *)buffer, len, format, x);
+    result = strtounicode(buffer, (char *)buffer);
+    return Py_SAFE_DOWNCAST(result, Py_ssize_t, int);
+}
+
+/* XXX To save some code duplication, formatfloat/long/int could have been
+   shared with stringobject.c, converting from 8-bit to Unicode after the
+   formatting is done. */
+
+static int
+formatfloat(Py_UNICODE *buf,
+	    size_t buflen,
+	    int flags,
+	    int prec,
+	    int type,
+	    PyObject *v)
+{
+    /* fmt = '%#.' + `prec` + `type`
+       worst case length = 3 + 10 (len of INT_MAX) + 1 = 14 (use 20)*/
+    char fmt[20];
+    double x;
+
+    x = PyFloat_AsDouble(v);
+    if (x == -1.0 && PyErr_Occurred())
+	return -1;
+    if (prec < 0)
+	prec = 6;
+    if (type == 'f' && (fabs(x) / 1e25) >= 1e25)
+	type = 'g';
+    /* Worst case length calc to ensure no buffer overrun:
+
+       'g' formats:
+	 fmt = %#.<prec>g
+	 buf = '-' + [0-9]*prec + '.' + 'e+' + (longest exp
+	    for any double rep.)
+	 len = 1 + prec + 1 + 2 + 5 = 9 + prec
+
+       'f' formats:
+	 buf = '-' + [0-9]*x + '.' + [0-9]*prec (with x < 50)
+	 len = 1 + 50 + 1 + prec = 52 + prec
+
+       If prec=0 the effective precision is 1 (the leading digit is
+       always given), therefore increase the length by one.
+
+    */
+    if ((type == 'g' && buflen <= (size_t)10 + (size_t)prec) ||
+	(type == 'f' && buflen <= (size_t)53 + (size_t)prec)) {
+	PyErr_SetString(PyExc_OverflowError,
+			"formatted float is too long (precision too large?)");
+	return -1;
+    }
+    PyOS_snprintf(fmt, sizeof(fmt), "%%%s.%d%c",
+		  (flags&F_ALT) ? "#" : "",
+		  prec, type);
+    return doubletounicode(buf, buflen, fmt, x);
+}
+
+static PyObject*
+formatlong(PyObject *val, int flags, int prec, int type)
+{
+	char *buf;
+	int i, len;
+	PyObject *str; /* temporary string object. */
+	PyUnicodeObject *result;
+
+	str = _PyString_FormatLong(val, flags, prec, type, &buf, &len);
+	if (!str)
+		return NULL;
+	result = _PyUnicode_New(len);
+	if (!result) {
+		Py_DECREF(str);
+		return NULL;
+	}
+	for (i = 0; i < len; i++)
+		result->str[i] = buf[i];
+	result->str[len] = 0;
+	Py_DECREF(str);
+	return (PyObject*)result;
+}
+
+static int
+formatint(Py_UNICODE *buf,
+	  size_t buflen,
+	  int flags,
+	  int prec,
+	  int type,
+	  PyObject *v)
+{
+    /* fmt = '%#.' + `prec` + 'l' + `type`
+     * worst case length = 3 + 19 (worst len of INT_MAX on 64-bit machine)
+     *                     + 1 + 1
+     *                   = 24
+     */
+    char fmt[64]; /* plenty big enough! */
+    char *sign;
+    long x;
+
+    x = PyInt_AsLong(v);
+    if (x == -1 && PyErr_Occurred())
+        return -1;
+    if (x < 0 && type == 'u') {
+        type = 'd';
+    }
+    if (x < 0 && (type == 'x' || type == 'X' || type == 'o'))
+        sign = "-";
+    else
+        sign = "";
+    if (prec < 0)
+        prec = 1;
+
+    /* buf = '+'/'-'/'' + '0'/'0x'/'' + '[0-9]'*max(prec, len(x in octal))
+     * worst case buf = '-0x' + [0-9]*prec, where prec >= 11
+     */
+    if (buflen <= 14 || buflen <= (size_t)3 + (size_t)prec) {
+        PyErr_SetString(PyExc_OverflowError,
+    	        "formatted integer is too long (precision too large?)");
+        return -1;
+    }
+
+    if ((flags & F_ALT) &&
+        (type == 'x' || type == 'X')) {
+        /* When converting under %#x or %#X, there are a number
+         * of issues that cause pain:
+         * - when 0 is being converted, the C standard leaves off
+         *   the '0x' or '0X', which is inconsistent with other
+         *   %#x/%#X conversions and inconsistent with Python's
+         *   hex() function
+         * - there are platforms that violate the standard and
+         *   convert 0 with the '0x' or '0X'
+         *   (Metrowerks, Compaq Tru64)
+         * - there are platforms that give '0x' when converting
+         *   under %#X, but convert 0 in accordance with the
+         *   standard (OS/2 EMX)
+         *
+         * We can achieve the desired consistency by inserting our
+         * own '0x' or '0X' prefix, and substituting %x/%X in place
+         * of %#x/%#X.
+         *
+         * Note that this is the same approach as used in
+         * formatint() in stringobject.c
+         */
+        PyOS_snprintf(fmt, sizeof(fmt), "%s0%c%%.%dl%c",
+                      sign, type, prec, type);
+    }
+    else {
+        PyOS_snprintf(fmt, sizeof(fmt), "%s%%%s.%dl%c",
+                      sign, (flags&F_ALT) ? "#" : "",
+                      prec, type);
+    }
+    if (sign[0])
+        return longtounicode(buf, buflen, fmt, -x);
+    else
+        return longtounicode(buf, buflen, fmt, x);
+}
+
+static int
+formatchar(Py_UNICODE *buf,
+           size_t buflen,
+           PyObject *v)
+{
+    /* presume that the buffer is at least 2 characters long */
+    if (PyUnicode_Check(v)) {
+	if (PyUnicode_GET_SIZE(v) != 1)
+	    goto onError;
+	buf[0] = PyUnicode_AS_UNICODE(v)[0];
+    }
+
+    else if (PyString_Check(v)) {
+	if (PyString_GET_SIZE(v) != 1)
+	    goto onError;
+	buf[0] = (Py_UNICODE)PyString_AS_STRING(v)[0];
+    }
+
+    else {
+	/* Integer input truncated to a character */
+        long x;
+	x = PyInt_AsLong(v);
+	if (x == -1 && PyErr_Occurred())
+	    goto onError;
+#ifdef Py_UNICODE_WIDE
+	if (x < 0 || x > 0x10ffff) {
+	    PyErr_SetString(PyExc_OverflowError,
+			    "%c arg not in range(0x110000) "
+			    "(wide Python build)");
+	    return -1;
+	}
+#else
+	if (x < 0 || x > 0xffff) {
+	    PyErr_SetString(PyExc_OverflowError,
+			    "%c arg not in range(0x10000) "
+			    "(narrow Python build)");
+	    return -1;
+	}
+#endif
+	buf[0] = (Py_UNICODE) x;
+    }
+    buf[1] = '\0';
+    return 1;
+
+ onError:
+    PyErr_SetString(PyExc_TypeError,
+		    "%c requires int or char");
+    return -1;
+}
+
+/* fmt%(v1,v2,...) is roughly equivalent to sprintf(fmt, v1, v2, ...)
+
+   FORMATBUFLEN is the length of the buffer in which the floats, ints, &
+   chars are formatted. XXX This is a magic number. Each formatting
+   routine does bounds checking to ensure no overflow, but a better
+   solution may be to malloc a buffer of appropriate size for each
+   format. For now, the current solution is sufficient.
+*/
+#define FORMATBUFLEN (size_t)120
+
+PyObject *PyUnicode_Format(PyObject *format,
+			   PyObject *args)
+{
+    Py_UNICODE *fmt, *res;
+    Py_ssize_t fmtcnt, rescnt, reslen, arglen, argidx;
+    int args_owned = 0;
+    PyUnicodeObject *result = NULL;
+    PyObject *dict = NULL;
+    PyObject *uformat;
+
+    if (format == NULL || args == NULL) {
+	PyErr_BadInternalCall();
+	return NULL;
+    }
+    uformat = PyUnicode_FromObject(format);
+    if (uformat == NULL)
+	return NULL;
+    fmt = PyUnicode_AS_UNICODE(uformat);
+    fmtcnt = PyUnicode_GET_SIZE(uformat);
+
+    reslen = rescnt = fmtcnt + 100;
+    result = _PyUnicode_New(reslen);
+    if (result == NULL)
+	goto onError;
+    res = PyUnicode_AS_UNICODE(result);
+
+    if (PyTuple_Check(args)) {
+	arglen = PyTuple_Size(args);
+	argidx = 0;
+    }
+    else {
+	arglen = -1;
+	argidx = -2;
+    }
+    if (args->ob_type->tp_as_mapping && !PyTuple_Check(args) &&
+        !PyObject_TypeCheck(args, &PyBaseString_Type))
+	dict = args;
+
+    while (--fmtcnt >= 0) {
+	if (*fmt != '%') {
+	    if (--rescnt < 0) {
+		rescnt = fmtcnt + 100;
+		reslen += rescnt;
+		if (_PyUnicode_Resize(&result, reslen) < 0)
+		    goto onError;
+		res = PyUnicode_AS_UNICODE(result) + reslen - rescnt;
+		--rescnt;
+	    }
+	    *res++ = *fmt++;
+	}
+	else {
+	    /* Got a format specifier */
+	    int flags = 0;
+	    Py_ssize_t width = -1;
+	    int prec = -1;
+	    Py_UNICODE c = '\0';
+	    Py_UNICODE fill;
+	    PyObject *v = NULL;
+	    PyObject *temp = NULL;
+	    Py_UNICODE *pbuf;
+	    Py_UNICODE sign;
+	    Py_ssize_t len;
+	    Py_UNICODE formatbuf[FORMATBUFLEN]; /* For format{float,int,char}() */
+
+	    fmt++;
+	    if (*fmt == '(') {
+		Py_UNICODE *keystart;
+		Py_ssize_t keylen;
+		PyObject *key;
+		int pcount = 1;
+
+		if (dict == NULL) {
+		    PyErr_SetString(PyExc_TypeError,
+				    "format requires a mapping");
+		    goto onError;
+		}
+		++fmt;
+		--fmtcnt;
+		keystart = fmt;
+		/* Skip over balanced parentheses */
+		while (pcount > 0 && --fmtcnt >= 0) {
+		    if (*fmt == ')')
+			--pcount;
+		    else if (*fmt == '(')
+			++pcount;
+		    fmt++;
+		}
+		keylen = fmt - keystart - 1;
+		if (fmtcnt < 0 || pcount > 0) {
+		    PyErr_SetString(PyExc_ValueError,
+				    "incomplete format key");
+		    goto onError;
+		}
+#if 0
+		/* keys are converted to strings using UTF-8 and
+		   then looked up since Python uses strings to hold
+		   variables names etc. in its namespaces and we
+		   wouldn't want to break common idioms. */
+		key = PyUnicode_EncodeUTF8(keystart,
+					   keylen,
+					   NULL);
+#else
+		key = PyUnicode_FromUnicode(keystart, keylen);
+#endif
+		if (key == NULL)
+		    goto onError;
+		if (args_owned) {
+		    Py_DECREF(args);
+		    args_owned = 0;
+		}
+		args = PyObject_GetItem(dict, key);
+		Py_DECREF(key);
+		if (args == NULL) {
+		    goto onError;
+		}
+		args_owned = 1;
+		arglen = -1;
+		argidx = -2;
+	    }
+	    while (--fmtcnt >= 0) {
+		switch (c = *fmt++) {
+		case '-': flags |= F_LJUST; continue;
+		case '+': flags |= F_SIGN; continue;
+		case ' ': flags |= F_BLANK; continue;
+		case '#': flags |= F_ALT; continue;
+		case '0': flags |= F_ZERO; continue;
+		}
+		break;
+	    }
+	    if (c == '*') {
+		v = getnextarg(args, arglen, &argidx);
+		if (v == NULL)
+		    goto onError;
+		if (!PyInt_Check(v)) {
+		    PyErr_SetString(PyExc_TypeError,
+				    "* wants int");
+		    goto onError;
+		}
+		width = PyInt_AsLong(v);
+		if (width < 0) {
+		    flags |= F_LJUST;
+		    width = -width;
+		}
+		if (--fmtcnt >= 0)
+		    c = *fmt++;
+	    }
+	    else if (c >= '0' && c <= '9') {
+		width = c - '0';
+		while (--fmtcnt >= 0) {
+		    c = *fmt++;
+		    if (c < '0' || c > '9')
+			break;
+		    if ((width*10) / 10 != width) {
+			PyErr_SetString(PyExc_ValueError,
+					"width too big");
+			goto onError;
+		    }
+		    width = width*10 + (c - '0');
+		}
+	    }
+	    if (c == '.') {
+		prec = 0;
+		if (--fmtcnt >= 0)
+		    c = *fmt++;
+		if (c == '*') {
+		    v = getnextarg(args, arglen, &argidx);
+		    if (v == NULL)
+			goto onError;
+		    if (!PyInt_Check(v)) {
+			PyErr_SetString(PyExc_TypeError,
+					"* wants int");
+			goto onError;
+		    }
+		    prec = PyInt_AsLong(v);
+		    if (prec < 0)
+			prec = 0;
+		    if (--fmtcnt >= 0)
+			c = *fmt++;
+		}
+		else if (c >= '0' && c <= '9') {
+		    prec = c - '0';
+		    while (--fmtcnt >= 0) {
+			c = Py_CHARMASK(*fmt++);
+			if (c < '0' || c > '9')
+			    break;
+			if ((prec*10) / 10 != prec) {
+			    PyErr_SetString(PyExc_ValueError,
+					    "prec too big");
+			    goto onError;
+			}
+			prec = prec*10 + (c - '0');
+		    }
+		}
+	    } /* prec */
+	    if (fmtcnt >= 0) {
+		if (c == 'h' || c == 'l' || c == 'L') {
+		    if (--fmtcnt >= 0)
+			c = *fmt++;
+		}
+	    }
+	    if (fmtcnt < 0) {
+		PyErr_SetString(PyExc_ValueError,
+				"incomplete format");
+		goto onError;
+	    }
+	    if (c != '%') {
+		v = getnextarg(args, arglen, &argidx);
+		if (v == NULL)
+		    goto onError;
+	    }
+	    sign = 0;
+	    fill = ' ';
+	    switch (c) {
+
+	    case '%':
+		pbuf = formatbuf;
+		/* presume that buffer length is at least 1 */
+		pbuf[0] = '%';
+		len = 1;
+		break;
+
+	    case 's':
+	    case 'r':
+		if (PyUnicode_Check(v) && c == 's') {
+		    temp = v;
+		    Py_INCREF(temp);
+		}
+		else {
+		    PyObject *unicode;
+		    if (c == 's')
+			temp = PyObject_Unicode(v);
+		    else
+			temp = PyObject_Repr(v);
+		    if (temp == NULL)
+			goto onError;
+                    if (PyUnicode_Check(temp))
+                        /* nothing to do */;
+                    else if (PyString_Check(temp)) {
+                        /* convert to string to Unicode */
+		        unicode = PyUnicode_Decode(PyString_AS_STRING(temp),
+						   PyString_GET_SIZE(temp),
+						   NULL,
+						   "strict");
+		        Py_DECREF(temp);
+		        temp = unicode;
+		        if (temp == NULL)
+			    goto onError;
+		    }
+		    else {
+			Py_DECREF(temp);
+			PyErr_SetString(PyExc_TypeError,
+					"%s argument has non-string str()");
+			goto onError;
+		    }
+		}
+		pbuf = PyUnicode_AS_UNICODE(temp);
+		len = PyUnicode_GET_SIZE(temp);
+		if (prec >= 0 && len > prec)
+		    len = prec;
+		break;
+
+	    case 'i':
+	    case 'd':
+	    case 'u':
+	    case 'o':
+	    case 'x':
+	    case 'X':
+		if (c == 'i')
+		    c = 'd';
+		if (PyLong_Check(v)) {
+		    temp = formatlong(v, flags, prec, c);
+		    if (!temp)
+			goto onError;
+		    pbuf = PyUnicode_AS_UNICODE(temp);
+		    len = PyUnicode_GET_SIZE(temp);
+		    sign = 1;
+		}
+		else {
+		    pbuf = formatbuf;
+		    len = formatint(pbuf, sizeof(formatbuf)/sizeof(Py_UNICODE),
+				    flags, prec, c, v);
+		    if (len < 0)
+			goto onError;
+		    sign = 1;
+		}
+		if (flags & F_ZERO)
+		    fill = '0';
+		break;
+
+	    case 'e':
+	    case 'E':
+	    case 'f':
+	    case 'F':
+	    case 'g':
+	    case 'G':
+		if (c == 'F')
+			c = 'f';
+		pbuf = formatbuf;
+		len = formatfloat(pbuf, sizeof(formatbuf)/sizeof(Py_UNICODE),
+			flags, prec, c, v);
+		if (len < 0)
+		    goto onError;
+		sign = 1;
+		if (flags & F_ZERO)
+		    fill = '0';
+		break;
+
+	    case 'c':
+		pbuf = formatbuf;
+		len = formatchar(pbuf, sizeof(formatbuf)/sizeof(Py_UNICODE), v);
+		if (len < 0)
+		    goto onError;
+		break;
+
+	    default:
+		PyErr_Format(PyExc_ValueError,
+			     "unsupported format character '%c' (0x%x) "
+			     "at index %zd",
+			     (31<=c && c<=126) ? (char)c : '?',
+                             (int)c,
+			     (Py_ssize_t)(fmt - 1 -
+					  PyUnicode_AS_UNICODE(uformat)));
+		goto onError;
+	    }
+	    if (sign) {
+		if (*pbuf == '-' || *pbuf == '+') {
+		    sign = *pbuf++;
+		    len--;
+		}
+		else if (flags & F_SIGN)
+		    sign = '+';
+		else if (flags & F_BLANK)
+		    sign = ' ';
+		else
+		    sign = 0;
+	    }
+	    if (width < len)
+		width = len;
+	    if (rescnt - (sign != 0) < width) {
+		reslen -= rescnt;
+		rescnt = width + fmtcnt + 100;
+		reslen += rescnt;
+		if (reslen < 0) {
+		    Py_XDECREF(temp);
+		    PyErr_NoMemory();
+		    goto onError;
+		}
+		if (_PyUnicode_Resize(&result, reslen) < 0) {
+		    Py_XDECREF(temp);
+		    goto onError;
+		}
+		res = PyUnicode_AS_UNICODE(result)
+		    + reslen - rescnt;
+	    }
+	    if (sign) {
+		if (fill != ' ')
+		    *res++ = sign;
+		rescnt--;
+		if (width > len)
+		    width--;
+	    }
+	    if ((flags & F_ALT) && (c == 'x' || c == 'X')) {
+		assert(pbuf[0] == '0');
+		assert(pbuf[1] == c);
+		if (fill != ' ') {
+		    *res++ = *pbuf++;
+		    *res++ = *pbuf++;
+		}
+		rescnt -= 2;
+		width -= 2;
+		if (width < 0)
+		    width = 0;
+		len -= 2;
+	    }
+	    if (width > len && !(flags & F_LJUST)) {
+		do {
+		    --rescnt;
+		    *res++ = fill;
+		} while (--width > len);
+	    }
+	    if (fill == ' ') {
+		if (sign)
+		    *res++ = sign;
+		if ((flags & F_ALT) && (c == 'x' || c == 'X')) {
+		    assert(pbuf[0] == '0');
+		    assert(pbuf[1] == c);
+		    *res++ = *pbuf++;
+		    *res++ = *pbuf++;
+		}
+	    }
+	    Py_UNICODE_COPY(res, pbuf, len);
+	    res += len;
+	    rescnt -= len;
+	    while (--width >= len) {
+		--rescnt;
+		*res++ = ' ';
+	    }
+	    if (dict && (argidx < arglen) && c != '%') {
+		PyErr_SetString(PyExc_TypeError,
+				"not all arguments converted during string formatting");
+                Py_XDECREF(temp);
+		goto onError;
+	    }
+	    Py_XDECREF(temp);
+	} /* '%' */
+    } /* until end */
+    if (argidx < arglen && !dict) {
+	PyErr_SetString(PyExc_TypeError,
+			"not all arguments converted during string formatting");
+	goto onError;
+    }
+
+    if (_PyUnicode_Resize(&result, reslen - rescnt) < 0)
+	goto onError;
+    if (args_owned) {
+	Py_DECREF(args);
+    }
+    Py_DECREF(uformat);
+    return (PyObject *)result;
+
+ onError:
+    Py_XDECREF(result);
+    Py_DECREF(uformat);
+    if (args_owned) {
+	Py_DECREF(args);
+    }
+    return NULL;
+}
+
+static PyBufferProcs unicode_as_buffer = {
+    (readbufferproc) unicode_buffer_getreadbuf,
+    (writebufferproc) unicode_buffer_getwritebuf,
+    (segcountproc) unicode_buffer_getsegcount,
+    (charbufferproc) unicode_buffer_getcharbuf,
+};
+
+static PyObject *
+unicode_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
+
+static PyObject *
+unicode_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+        PyObject *x = NULL;
+	static char *kwlist[] = {"string", "encoding", "errors", 0};
+	char *encoding = NULL;
+	char *errors = NULL;
+
+	if (type != &PyUnicode_Type)
+		return unicode_subtype_new(type, args, kwds);
+	if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:unicode",
+					  kwlist, &x, &encoding, &errors))
+	    return NULL;
+	if (x == NULL)
+		return (PyObject *)_PyUnicode_New(0);
+	if (encoding == NULL && errors == NULL)
+	    return PyObject_Unicode(x);
+	else
+	return PyUnicode_FromEncodedObject(x, encoding, errors);
+}
+
+static PyObject *
+unicode_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	PyUnicodeObject *tmp, *pnew;
+	Py_ssize_t n;
+
+	assert(PyType_IsSubtype(type, &PyUnicode_Type));
+	tmp = (PyUnicodeObject *)unicode_new(&PyUnicode_Type, args, kwds);
+	if (tmp == NULL)
+		return NULL;
+	assert(PyUnicode_Check(tmp));
+	pnew = (PyUnicodeObject *) type->tp_alloc(type, n = tmp->length);
+	if (pnew == NULL) {
+		Py_DECREF(tmp);
+		return NULL;
+	}
+	pnew->str = PyMem_NEW(Py_UNICODE, n+1);
+	if (pnew->str == NULL) {
+		_Py_ForgetReference((PyObject *)pnew);
+		PyObject_Del(pnew);
+		Py_DECREF(tmp);
+		return PyErr_NoMemory();
+	}
+	Py_UNICODE_COPY(pnew->str, tmp->str, n+1);
+	pnew->length = n;
+	pnew->hash = tmp->hash;
+	Py_DECREF(tmp);
+	return (PyObject *)pnew;
+}
+
+PyDoc_STRVAR(unicode_doc,
+"unicode(string [, encoding[, errors]]) -> object\n\
+\n\
+Create a new Unicode object from the given encoded string.\n\
+encoding defaults to the current default string encoding.\n\
+errors can be 'strict', 'replace' or 'ignore' and defaults to 'strict'.");
+
+PyTypeObject PyUnicode_Type = {
+    PyObject_HEAD_INIT(&PyType_Type)
+    0, 					/* ob_size */
+    "unicode", 				/* tp_name */
+    sizeof(PyUnicodeObject), 		/* tp_size */
+    0, 					/* tp_itemsize */
+    /* Slots */
+    (destructor)unicode_dealloc, 	/* tp_dealloc */
+    0, 					/* tp_print */
+    0,				 	/* tp_getattr */
+    0, 					/* tp_setattr */
+    0, 					/* tp_compare */
+    unicode_repr, 			/* tp_repr */
+    &unicode_as_number, 		/* tp_as_number */
+    &unicode_as_sequence, 		/* tp_as_sequence */
+    &unicode_as_mapping, 		/* tp_as_mapping */
+    (hashfunc) unicode_hash, 		/* tp_hash*/
+    0, 					/* tp_call*/
+    (reprfunc) unicode_str,	 	/* tp_str */
+    PyObject_GenericGetAttr, 		/* tp_getattro */
+    0,			 		/* tp_setattro */
+    &unicode_as_buffer,			/* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
+	    Py_TPFLAGS_BASETYPE,	/* tp_flags */
+    unicode_doc,			/* tp_doc */
+    0,					/* tp_traverse */
+    0,					/* tp_clear */
+    PyUnicode_RichCompare,		/* tp_richcompare */
+    0,					/* tp_weaklistoffset */
+    0,					/* tp_iter */
+    0,					/* tp_iternext */
+    unicode_methods,			/* tp_methods */
+    0,					/* tp_members */
+    0,					/* tp_getset */
+    &PyBaseString_Type,			/* tp_base */
+    0,					/* tp_dict */
+    0,					/* tp_descr_get */
+    0,					/* tp_descr_set */
+    0,					/* tp_dictoffset */
+    0,					/* tp_init */
+    0,					/* tp_alloc */
+    unicode_new,			/* tp_new */
+    PyObject_Del,      		/* tp_free */
+};
+
+/* Initialize the Unicode implementation */
+
+void _PyUnicode_Init(void)
+{
+    int i;
+
+    /* XXX - move this array to unicodectype.c ? */
+    Py_UNICODE linebreak[] = {
+        0x000A, /* LINE FEED */
+        0x000D, /* CARRIAGE RETURN */
+        0x001C, /* FILE SEPARATOR */
+        0x001D, /* GROUP SEPARATOR */
+        0x001E, /* RECORD SEPARATOR */
+        0x0085, /* NEXT LINE */
+        0x2028, /* LINE SEPARATOR */
+        0x2029, /* PARAGRAPH SEPARATOR */
+    };
+
+    /* Init the implementation */
+    unicode_freelist = NULL;
+    unicode_freelist_size = 0;
+    unicode_empty = _PyUnicode_New(0);
+    if (!unicode_empty)
+	return;
+
+    strcpy(unicode_default_encoding, "ascii");
+    for (i = 0; i < 256; i++)
+	unicode_latin1[i] = NULL;
+    if (PyType_Ready(&PyUnicode_Type) < 0)
+	Py_FatalError("Can't initialize 'unicode'");
+
+    /* initialize the linebreak bloom filter */
+    bloom_linebreak = make_bloom_mask(
+        linebreak, sizeof(linebreak) / sizeof(linebreak[0])
+        );
+
+    PyType_Ready(&EncodingMapType);
+}
+
+/* Finalize the Unicode implementation */
+
+void
+_PyUnicode_Fini(void)
+{
+    PyUnicodeObject *u;
+    int i;
+
+    Py_XDECREF(unicode_empty);
+    unicode_empty = NULL;
+
+    for (i = 0; i < 256; i++) {
+	if (unicode_latin1[i]) {
+	    Py_DECREF(unicode_latin1[i]);
+	    unicode_latin1[i] = NULL;
+	}
+    }
+
+    for (u = unicode_freelist; u != NULL;) {
+	PyUnicodeObject *v = u;
+	u = *(PyUnicodeObject **)u;
+	if (v->str)
+	    PyMem_DEL(v->str);
+	Py_XDECREF(v->defenc);
+	PyObject_Del(v);
+    }
+    unicode_freelist = NULL;
+    unicode_freelist_size = 0;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/*
+Local variables:
+c-basic-offset: 4
+indent-tabs-mode: nil
+End:
+*/

Added: vendor/Python/current/Objects/unicodetype_db.h
===================================================================
--- vendor/Python/current/Objects/unicodetype_db.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Objects/unicodetype_db.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1269 @@
+/* this file was generated by Tools/unicode/makeunicodedata.py 2.5 */
+
+/* a list of unique character type descriptors */
+const _PyUnicode_TypeRecord _PyUnicode_TypeRecords[] = {
+    {0, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 32},
+    {0, 0, 0, 0, 0, 48},
+    {0, 0, 0, 0, 0, 6},
+    {0, 0, 0, 1, 1, 6},
+    {0, 0, 0, 2, 2, 6},
+    {0, 0, 0, 3, 3, 6},
+    {0, 0, 0, 4, 4, 6},
+    {0, 0, 0, 5, 5, 6},
+    {0, 0, 0, 6, 6, 6},
+    {0, 0, 0, 7, 7, 6},
+    {0, 0, 0, 8, 8, 6},
+    {0, 0, 0, 9, 9, 6},
+    {0, 32, 0, 0, 0, 129},
+    {65504, 0, 65504, 0, 0, 9},
+    {0, 0, 0, 0, 0, 9},
+    {0, 0, 0, 0, 2, 4},
+    {0, 0, 0, 0, 3, 4},
+    {743, 0, 743, 0, 0, 9},
+    {0, 0, 0, 0, 1, 4},
+    {121, 0, 121, 0, 0, 9},
+    {0, 1, 0, 0, 0, 129},
+    {65535, 0, 65535, 0, 0, 9},
+    {0, 65337, 0, 0, 0, 129},
+    {65304, 0, 65304, 0, 0, 9},
+    {0, 65415, 0, 0, 0, 129},
+    {65236, 0, 65236, 0, 0, 9},
+    {0, 210, 0, 0, 0, 129},
+    {0, 206, 0, 0, 0, 129},
+    {0, 205, 0, 0, 0, 129},
+    {0, 79, 0, 0, 0, 129},
+    {0, 202, 0, 0, 0, 129},
+    {0, 203, 0, 0, 0, 129},
+    {0, 207, 0, 0, 0, 129},
+    {97, 0, 97, 0, 0, 9},
+    {0, 211, 0, 0, 0, 129},
+    {0, 209, 0, 0, 0, 129},
+    {163, 0, 163, 0, 0, 9},
+    {0, 213, 0, 0, 0, 129},
+    {130, 0, 130, 0, 0, 9},
+    {0, 214, 0, 0, 0, 129},
+    {0, 218, 0, 0, 0, 129},
+    {0, 217, 0, 0, 0, 129},
+    {0, 219, 0, 0, 0, 129},
+    {0, 0, 0, 0, 0, 1},
+    {56, 0, 56, 0, 0, 9},
+    {0, 2, 1, 0, 0, 129},
+    {65535, 1, 0, 0, 0, 65},
+    {65534, 0, 65535, 0, 0, 9},
+    {65457, 0, 65457, 0, 0, 9},
+    {0, 65439, 0, 0, 0, 129},
+    {0, 65480, 0, 0, 0, 129},
+    {0, 65406, 0, 0, 0, 129},
+    {0, 0, 0, 0, 0, 129},
+    {0, 65373, 0, 0, 0, 129},
+    {0, 83, 0, 0, 0, 129},
+    {65326, 0, 65326, 0, 0, 9},
+    {65330, 0, 65330, 0, 0, 9},
+    {65331, 0, 65331, 0, 0, 9},
+    {65334, 0, 65334, 0, 0, 9},
+    {65333, 0, 65333, 0, 0, 9},
+    {65329, 0, 65329, 0, 0, 9},
+    {65327, 0, 65327, 0, 0, 9},
+    {65325, 0, 65325, 0, 0, 9},
+    {65323, 0, 65323, 0, 0, 9},
+    {65322, 0, 65322, 0, 0, 9},
+    {65318, 0, 65318, 0, 0, 9},
+    {65319, 0, 65319, 0, 0, 9},
+    {65317, 0, 65317, 0, 0, 9},
+    {65453, 0, 65453, 0, 0, 9},
+    {84, 0, 84, 0, 0, 0},
+    {0, 38, 0, 0, 0, 129},
+    {0, 37, 0, 0, 0, 129},
+    {0, 64, 0, 0, 0, 129},
+    {0, 63, 0, 0, 0, 129},
+    {65498, 0, 65498, 0, 0, 9},
+    {65499, 0, 65499, 0, 0, 9},
+    {65505, 0, 65505, 0, 0, 9},
+    {65472, 0, 65472, 0, 0, 9},
+    {65473, 0, 65473, 0, 0, 9},
+    {65474, 0, 65474, 0, 0, 9},
+    {65479, 0, 65479, 0, 0, 9},
+    {65489, 0, 65489, 0, 0, 9},
+    {65482, 0, 65482, 0, 0, 9},
+    {65450, 0, 65450, 0, 0, 9},
+    {65456, 0, 65456, 0, 0, 9},
+    {7, 0, 7, 0, 0, 9},
+    {0, 65476, 0, 0, 0, 129},
+    {65440, 0, 65440, 0, 0, 9},
+    {0, 65529, 0, 0, 0, 129},
+    {0, 80, 0, 0, 0, 129},
+    {0, 48, 0, 0, 0, 129},
+    {65488, 0, 65488, 0, 0, 9},
+    {0, 7264, 0, 0, 0, 129},
+    {0, 0, 0, 0, 4, 4},
+    {0, 0, 0, 0, 5, 4},
+    {0, 0, 0, 0, 6, 4},
+    {0, 0, 0, 0, 7, 4},
+    {0, 0, 0, 0, 8, 4},
+    {0, 0, 0, 0, 9, 4},
+    {65477, 0, 65477, 0, 0, 9},
+    {8, 0, 8, 0, 0, 9},
+    {0, 65528, 0, 0, 0, 129},
+    {74, 0, 74, 0, 0, 9},
+    {86, 0, 86, 0, 0, 9},
+    {100, 0, 100, 0, 0, 9},
+    {128, 0, 128, 0, 0, 9},
+    {112, 0, 112, 0, 0, 9},
+    {126, 0, 126, 0, 0, 9},
+    {0, 65528, 0, 0, 0, 65},
+    {9, 0, 9, 0, 0, 9},
+    {0, 65462, 0, 0, 0, 129},
+    {0, 65527, 0, 0, 0, 65},
+    {58331, 0, 58331, 0, 0, 9},
+    {0, 65450, 0, 0, 0, 129},
+    {0, 65436, 0, 0, 0, 129},
+    {0, 65424, 0, 0, 0, 129},
+    {0, 65408, 0, 0, 0, 129},
+    {0, 65410, 0, 0, 0, 129},
+    {0, 0, 0, 0, 0, 4},
+    {0, 58019, 0, 0, 0, 129},
+    {0, 57153, 0, 0, 0, 129},
+    {0, 57274, 0, 0, 0, 129},
+    {0, 16, 0, 0, 0, 0},
+    {65520, 0, 65520, 0, 0, 0},
+    {0, 26, 0, 0, 0, 0},
+    {65510, 0, 65510, 0, 0, 0},
+    {58272, 0, 58272, 0, 0, 9},
+    {0, 40, 0, 0, 0, 129},
+    {65496, 0, 65496, 0, 0, 9},
+};
+
+/* type indexes */
+#define SHIFT 8
+static unsigned char index1[] = {
+    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 
+    21, 22, 23, 24, 25, 26, 8, 8, 27, 28, 29, 30, 31, 32, 33, 34, 32, 35, 36, 
+    32, 32, 32, 37, 38, 39, 40, 41, 42, 43, 44, 32, 21, 21, 21, 21, 21, 21, 
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
+    21, 45, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 46, 21, 21, 21, 21, 47, 8, 8, 
+    48, 49, 8, 8, 8, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 50, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 21, 51, 52, 21, 53, 54, 55, 56, 57, 
+    8, 58, 59, 8, 8, 8, 60, 8, 61, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 62, 63, 64, 65, 66, 67, 68, 
+    69, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 21, 21, 21, 21, 21, 
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 70, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 21, 21, 71, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 72, 73, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 74, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 74, 
+};
+
+static unsigned char index2[] = {
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 2, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 3, 3, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 1, 1, 1, 1, 1, 1, 14, 14, 14, 14, 
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
+    14, 14, 14, 14, 1, 1, 1, 1, 1, 1, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 1, 1, 1, 
+    1, 1, 1, 1, 17, 18, 1, 19, 1, 1, 1, 20, 16, 1, 1, 1, 1, 1, 14, 14, 14, 
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
+    14, 14, 1, 14, 14, 14, 14, 14, 14, 14, 16, 15, 15, 15, 15, 15, 15, 15, 
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 1, 15, 
+    15, 15, 15, 15, 15, 15, 21, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 
+    23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 
+    23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 
+    23, 24, 25, 22, 23, 22, 23, 22, 23, 16, 22, 23, 22, 23, 22, 23, 22, 23, 
+    22, 23, 22, 23, 22, 23, 22, 23, 16, 22, 23, 22, 23, 22, 23, 22, 23, 22, 
+    23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 
+    23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 
+    23, 26, 22, 23, 22, 23, 22, 23, 27, 16, 28, 22, 23, 22, 23, 29, 22, 23, 
+    30, 30, 22, 23, 16, 31, 32, 33, 22, 23, 30, 34, 35, 36, 37, 22, 23, 38, 
+    16, 36, 39, 40, 41, 22, 23, 22, 23, 22, 23, 42, 22, 23, 42, 16, 16, 22, 
+    23, 42, 22, 23, 43, 43, 22, 23, 22, 23, 44, 22, 23, 16, 45, 22, 23, 16, 
+    46, 45, 45, 45, 45, 47, 48, 49, 47, 48, 49, 47, 48, 49, 22, 23, 22, 23, 
+    22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 50, 22, 23, 22, 23, 22, 
+    23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 16, 47, 48, 49, 22, 
+    23, 51, 52, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 
+    23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 
+    23, 22, 23, 22, 23, 22, 23, 53, 16, 22, 23, 22, 23, 22, 23, 22, 23, 22, 
+    23, 22, 23, 22, 23, 22, 23, 22, 23, 16, 16, 16, 16, 16, 16, 54, 22, 23, 
+    55, 54, 16, 16, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 
+    57, 58, 16, 59, 59, 16, 60, 16, 61, 16, 16, 16, 16, 59, 16, 16, 62, 16, 
+    16, 16, 16, 63, 64, 16, 16, 16, 16, 16, 64, 16, 16, 65, 16, 16, 66, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 67, 16, 16, 67, 16, 16, 16, 16, 67, 
+    16, 68, 68, 16, 16, 16, 16, 16, 16, 69, 16, 70, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 1, 1, 1, 1, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 45, 45, 45, 45, 45, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 45, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 71, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 
+    0, 45, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 72, 1, 73, 73, 73, 0, 74, 0, 75, 
+    75, 16, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
+    14, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 76, 77, 77, 77, 16, 15, 15, 
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 78, 15, 15, 
+    15, 15, 15, 15, 15, 15, 15, 79, 80, 80, 0, 81, 82, 54, 54, 54, 83, 84, 
+    16, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 
+    23, 22, 23, 22, 23, 22, 23, 85, 86, 87, 16, 88, 89, 1, 22, 23, 90, 22, 
+    23, 16, 54, 54, 54, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 
+    91, 91, 91, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 86, 86, 86, 86, 86, 
+    86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 22, 23, 22, 23, 22, 23, 22, 
+    23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 
+    23, 22, 23, 22, 23, 22, 23, 22, 23, 1, 1, 1, 1, 1, 0, 1, 1, 22, 23, 22, 
+    23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 
+    23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 
+    23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 54, 22, 23, 
+    22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 0, 22, 23, 22, 23, 22, 
+    23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 
+    23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 
+    23, 0, 0, 0, 0, 0, 0, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 
+    23, 22, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 92, 92, 92, 92, 92, 92, 92, 
+    92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 
+    92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 0, 0, 45, 1, 1, 1, 1, 1, 
+    1, 0, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 
+    93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 
+    93, 93, 93, 16, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 
+    0, 0, 0, 0, 0, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 0, 0, 0, 0, 0, 45, 
+    45, 45, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 
+    0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 0, 0, 0, 0, 0, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 1, 1, 1, 45, 45, 1, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 1, 45, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 45, 45, 1, 1, 1, 1, 1, 1, 1, 45, 45, 4, 5, 6, 7, 8, 9, 10, 11, 12, 
+    13, 45, 45, 45, 1, 1, 45, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 
+    45, 1, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 1, 1, 1, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 0, 0, 1, 45, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    0, 0, 45, 1, 1, 1, 1, 0, 0, 0, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 1, 
+    1, 1, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 45, 0, 0, 0, 1, 1, 1, 0, 45, 45, 45, 45, 45, 45, 45, 45, 0, 0, 
+    45, 45, 0, 0, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 0, 45, 45, 45, 45, 45, 45, 45, 0, 45, 0, 0, 
+    0, 45, 45, 45, 45, 0, 0, 1, 45, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 
+    1, 1, 45, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 45, 45, 0, 45, 45, 45, 
+    1, 1, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 45, 45, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 45, 45, 45, 45, 45, 45, 0, 0, 0, 
+    0, 45, 45, 0, 0, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 0, 45, 45, 45, 45, 45, 45, 45, 0, 45, 45, 
+    0, 45, 45, 0, 45, 45, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 
+    1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 45, 45, 0, 45, 0, 0, 0, 
+    0, 0, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 1, 45, 45, 45, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 0, 45, 45, 45, 0, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 0, 45, 45, 45, 45, 45, 45, 45, 0, 45, 
+    45, 0, 45, 45, 45, 45, 45, 0, 0, 1, 45, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 
+    1, 0, 1, 1, 1, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 
+    45, 1, 1, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 1, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 45, 45, 45, 45, 45, 45, 45, 45, 0, 
+    0, 45, 45, 0, 0, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 0, 45, 45, 45, 45, 45, 45, 45, 0, 45, 45, 
+    0, 45, 45, 45, 45, 45, 0, 0, 1, 45, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 
+    0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 45, 45, 0, 45, 45, 
+    45, 0, 0, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 45, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 45, 0, 45, 45, 45, 45, 45, 45, 0, 0, 
+    0, 45, 45, 45, 0, 45, 45, 45, 45, 0, 0, 0, 45, 45, 0, 45, 0, 45, 45, 0, 
+    0, 0, 45, 45, 0, 0, 0, 45, 45, 45, 0, 0, 0, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 
+    1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 45, 45, 45, 45, 45, 45, 45, 45, 0, 45, 45, 
+    45, 0, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 0, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 0, 
+    45, 45, 45, 45, 45, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 
+    1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 
+    0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 45, 45, 45, 45, 45, 45, 45, 45, 0, 45, 45, 
+    45, 0, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 0, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 0, 
+    45, 45, 45, 45, 45, 0, 0, 1, 45, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 
+    1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 45, 0, 45, 45, 
+    0, 0, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 45, 45, 45, 45, 45, 45, 45, 45, 0, 
+    45, 45, 45, 0, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 0, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 
+    1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 
+    45, 45, 0, 0, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 0, 0, 0, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 0, 45, 45, 45, 45, 45, 45, 45, 45, 45, 0, 45, 0, 0, 45, 45, 45, 45, 
+    45, 45, 45, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 
+    1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 
+    1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 1, 45, 45, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 45, 45, 
+    45, 45, 45, 45, 45, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 5, 6, 7, 8, 9, 10, 11, 
+    12, 13, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 45, 0, 0, 
+    45, 45, 0, 45, 0, 0, 45, 0, 0, 0, 0, 0, 0, 45, 45, 45, 45, 0, 45, 45, 45, 
+    45, 45, 45, 45, 0, 45, 45, 45, 0, 45, 0, 45, 0, 0, 45, 45, 0, 45, 45, 45, 
+    45, 1, 45, 45, 1, 1, 1, 1, 1, 1, 0, 1, 1, 45, 0, 0, 45, 45, 45, 45, 45, 
+    0, 45, 0, 1, 1, 1, 1, 1, 1, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 
+    45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 5, 6, 7, 
+    8, 9, 10, 11, 12, 13, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 45, 45, 45, 45, 45, 45, 45, 45, 0, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 45, 45, 45, 45, 0, 
+    0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 0, 45, 45, 45, 45, 45, 0, 
+    45, 45, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 4, 
+    5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 1, 1, 1, 1, 1, 45, 45, 45, 45, 45, 45, 
+    1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
+    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
+    94, 94, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 1, 
+    45, 0, 0, 0, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 0, 0, 0, 0, 0, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 0, 0, 0, 0, 0, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 0, 0, 
+    0, 0, 0, 0, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 0, 45, 45, 45, 45, 0, 0, 45, 45, 45, 45, 45, 45, 45, 0, 
+    45, 0, 45, 45, 45, 45, 0, 0, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 0, 45, 45, 45, 45, 0, 0, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 0, 45, 45, 
+    45, 45, 0, 0, 45, 45, 45, 45, 45, 45, 45, 0, 45, 0, 45, 45, 45, 45, 0, 0, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 0, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 0, 45, 45, 45, 45, 0, 0, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 20, 17, 18, 95, 96, 97, 
+    98, 99, 100, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 0, 0, 0, 0, 0, 0, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    1, 1, 45, 45, 45, 45, 45, 45, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 1, 1, 0, 0, 0, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 1, 1, 1, 1, 1, 1, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 0, 45, 45, 45, 45, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 1, 1, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    0, 45, 45, 45, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 45, 1, 1, 1, 1, 45, 1, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 
+    13, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 4, 5, 6, 7, 8, 9, 10, 11, 
+    12, 13, 0, 0, 0, 0, 0, 0, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 1, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 4, 5, 6, 7, 8, 9, 
+    10, 11, 12, 13, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 0, 0, 45, 
+    45, 45, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 45, 
+    45, 45, 45, 45, 45, 45, 1, 1, 0, 0, 0, 0, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 
+    12, 13, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 1, 1, 
+    1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 45, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 23, 
+    22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 
+    22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 
+    22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 
+    22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 
+    22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 
+    22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 
+    22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 
+    22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 
+    22, 23, 22, 23, 16, 16, 16, 16, 16, 101, 0, 0, 0, 0, 22, 23, 22, 23, 22, 
+    23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 
+    23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 
+    23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 
+    23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 
+    23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 0, 0, 0, 0, 0, 0, 
+    102, 102, 102, 102, 102, 102, 102, 102, 103, 103, 103, 103, 103, 103, 
+    103, 103, 102, 102, 102, 102, 102, 102, 0, 0, 103, 103, 103, 103, 103, 
+    103, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 103, 103, 103, 103, 
+    103, 103, 103, 103, 102, 102, 102, 102, 102, 102, 102, 102, 103, 103, 
+    103, 103, 103, 103, 103, 103, 102, 102, 102, 102, 102, 102, 0, 0, 103, 
+    103, 103, 103, 103, 103, 0, 0, 16, 102, 16, 102, 16, 102, 16, 102, 0, 
+    103, 0, 103, 0, 103, 0, 103, 102, 102, 102, 102, 102, 102, 102, 102, 103, 
+    103, 103, 103, 103, 103, 103, 103, 104, 104, 105, 105, 105, 105, 106, 
+    106, 107, 107, 108, 108, 109, 109, 0, 0, 102, 102, 102, 102, 102, 102, 
+    102, 102, 110, 110, 110, 110, 110, 110, 110, 110, 102, 102, 102, 102, 
+    102, 102, 102, 102, 110, 110, 110, 110, 110, 110, 110, 110, 102, 102, 
+    102, 102, 102, 102, 102, 102, 110, 110, 110, 110, 110, 110, 110, 110, 
+    102, 102, 16, 111, 16, 0, 16, 16, 103, 103, 112, 112, 113, 1, 114, 1, 1, 
+    1, 16, 111, 16, 0, 16, 16, 115, 115, 115, 115, 113, 1, 1, 1, 102, 102, 
+    16, 16, 0, 0, 16, 16, 103, 103, 116, 116, 0, 1, 1, 1, 102, 102, 16, 16, 
+    16, 87, 16, 16, 103, 103, 117, 117, 90, 1, 1, 1, 0, 0, 16, 111, 16, 0, 
+    16, 16, 118, 118, 119, 119, 113, 1, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+    2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 
+    1, 1, 1, 1, 1, 1, 120, 16, 0, 0, 95, 96, 97, 98, 99, 100, 1, 1, 1, 1, 1, 
+    16, 120, 20, 17, 18, 95, 96, 97, 98, 99, 100, 1, 1, 1, 1, 1, 0, 45, 45, 
+    45, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 54, 1, 1, 1, 1, 54, 1, 
+    1, 16, 54, 54, 54, 16, 16, 54, 54, 54, 16, 1, 54, 1, 1, 1, 54, 54, 54, 
+    54, 54, 1, 1, 1, 1, 1, 1, 54, 1, 121, 1, 54, 1, 122, 123, 54, 54, 1, 16, 
+    54, 54, 1, 54, 16, 45, 45, 45, 45, 16, 1, 1, 16, 16, 54, 54, 1, 1, 1, 1, 
+    1, 54, 16, 16, 16, 16, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 
+    124, 124, 124, 124, 124, 125, 125, 125, 125, 125, 125, 125, 125, 125, 
+    125, 125, 125, 125, 125, 125, 125, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 20, 17, 18, 95, 96, 97, 98, 99, 100, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 20, 17, 18, 95, 96, 97, 98, 99, 100, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 20, 17, 18, 95, 96, 97, 98, 99, 100, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 
+    126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 120, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 20, 17, 18, 95, 96, 97, 98, 99, 100, 1, 120, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 
+    0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 20, 17, 18, 95, 96, 97, 98, 99, 100, 1, 
+    20, 17, 18, 95, 96, 97, 98, 99, 100, 1, 20, 17, 18, 95, 96, 97, 98, 99, 
+    100, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 
+    1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 
+    92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 
+    92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 0, 93, 93, 
+    93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 
+    93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 
+    93, 93, 93, 93, 93, 93, 93, 93, 93, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 23, 
+    22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 
+    22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 
+    22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 
+    22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 
+    22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 
+    22, 23, 22, 23, 22, 23, 22, 23, 16, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 128, 128, 128, 128, 128, 
+    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 
+    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 
+    128, 128, 128, 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 45, 45, 45, 45, 45, 0, 45, 45, 
+    45, 45, 45, 45, 45, 0, 45, 45, 45, 45, 45, 45, 45, 0, 45, 45, 45, 45, 45, 
+    45, 45, 0, 45, 45, 45, 45, 45, 45, 45, 0, 45, 45, 45, 45, 45, 45, 45, 0, 
+    45, 45, 45, 45, 45, 45, 45, 0, 45, 45, 45, 45, 45, 45, 45, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 2, 1, 1, 1, 1, 45, 45, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 45, 45, 45, 45, 45, 1, 1, 1, 1, 1, 
+    45, 45, 1, 1, 1, 0, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 0, 0, 1, 1, 1, 1, 45, 45, 45, 1, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 1, 45, 45, 45, 45, 0, 0, 0, 0, 0, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 0, 0, 0, 0, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 0, 0, 0, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 45, 45, 1, 45, 45, 45, 1, 45, 45, 45, 45, 1, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 0, 0, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 0, 0, 0, 0, 0, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 
+    16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 0, 0, 0, 
+    0, 0, 45, 1, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 1, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 0, 45, 45, 45, 45, 45, 0, 45, 0, 45, 
+    45, 0, 45, 45, 0, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 0, 0, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 
+    45, 45, 45, 45, 45, 0, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 0, 0, 1, 0, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 5, 6, 7, 8, 9, 10, 11, 
+    12, 13, 1, 1, 1, 1, 1, 1, 1, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 1, 1, 1, 1, 
+    1, 1, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 0, 0, 0, 
+    45, 45, 45, 45, 45, 45, 0, 0, 45, 45, 45, 45, 45, 45, 0, 0, 45, 45, 45, 
+    45, 45, 45, 0, 0, 45, 45, 45, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 
+    1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 0, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 0, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 0, 45, 45, 0, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 0, 0, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 0, 1, 1, 1, 1, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 1, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 0, 1, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 0, 0, 0, 0, 
+    45, 45, 45, 45, 45, 45, 45, 45, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 129, 129, 129, 129, 129, 129, 129, 
+    129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 
+    129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 
+    129, 129, 129, 129, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 
+    130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 
+    130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 
+    130, 130, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 45, 45, 45, 45, 0, 0, 
+    45, 0, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 0, 45, 45, 0, 0, 0, 45, 0, 0, 45, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    45, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 45, 45, 45, 45, 0, 45, 
+    45, 45, 0, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 0, 0, 0, 0, 1, 1, 1, 0, 
+    0, 0, 0, 1, 20, 17, 18, 95, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 
+    54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 
+    54, 54, 54, 54, 54, 54, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 54, 54, 54, 54, 
+    54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 
+    54, 54, 54, 54, 16, 16, 16, 16, 16, 16, 16, 0, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 54, 54, 54, 54, 54, 54, 
+    54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 
+    54, 54, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 54, 0, 54, 54, 0, 0, 54, 0, 0, 
+    54, 54, 0, 0, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, 16, 16, 
+    16, 16, 0, 16, 0, 16, 16, 16, 16, 16, 16, 16, 0, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 
+    54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 54, 54, 0, 54, 54, 54, 54, 0, 0, 54, 54, 54, 54, 54, 54, 54, 
+    54, 0, 54, 54, 54, 54, 54, 54, 54, 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 54, 
+    54, 0, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 0, 54, 0, 0, 0, 54, 54, 54, 
+    54, 54, 54, 54, 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 54, 54, 54, 54, 54, 
+    54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 
+    54, 54, 54, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 54, 54, 54, 54, 54, 54, 54, 
+    54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 
+    54, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 54, 54, 54, 54, 54, 54, 54, 54, 54, 
+    54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 
+    54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 
+    54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 
+    54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 
+    54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 1, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 1, 16, 16, 16, 16, 16, 16, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 
+    54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 1, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 1, 16, 16, 16, 16, 16, 16, 54, 54, 54, 54, 54, 54, 
+    54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 
+    54, 1, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 1, 16, 16, 16, 16, 16, 16, 54, 54, 
+    54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 
+    54, 54, 54, 54, 54, 1, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 1, 16, 16, 16, 16, 
+    16, 16, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 
+    54, 54, 54, 54, 54, 54, 54, 54, 54, 1, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 1, 
+    16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 4, 
+    5, 6, 7, 8, 9, 10, 11, 12, 13, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 4, 5, 6, 
+    7, 8, 9, 10, 11, 12, 13, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 
+    45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 
+};
+

Added: vendor/Python/current/Objects/weakrefobject.c
===================================================================
--- vendor/Python/current/Objects/weakrefobject.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Objects/weakrefobject.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,941 @@
+#include "Python.h"
+#include "structmember.h"
+
+
+#define GET_WEAKREFS_LISTPTR(o) \
+        ((PyWeakReference **) PyObject_GET_WEAKREFS_LISTPTR(o))
+
+
+Py_ssize_t
+_PyWeakref_GetWeakrefCount(PyWeakReference *head)
+{
+    Py_ssize_t count = 0;
+
+    while (head != NULL) {
+        ++count;
+        head = head->wr_next;
+    }
+    return count;
+}
+
+
+static void
+init_weakref(PyWeakReference *self, PyObject *ob, PyObject *callback)
+{
+    self->hash = -1;
+    self->wr_object = ob;
+    Py_XINCREF(callback);
+    self->wr_callback = callback;
+}
+
+static PyWeakReference *
+new_weakref(PyObject *ob, PyObject *callback)
+{
+    PyWeakReference *result;
+
+    result = PyObject_GC_New(PyWeakReference, &_PyWeakref_RefType);
+    if (result) {
+        init_weakref(result, ob, callback);
+        PyObject_GC_Track(result);
+    }
+    return result;
+}
+
+
+/* This function clears the passed-in reference and removes it from the
+ * list of weak references for the referent.  This is the only code that
+ * removes an item from the doubly-linked list of weak references for an
+ * object; it is also responsible for clearing the callback slot.
+ */
+static void
+clear_weakref(PyWeakReference *self)
+{
+    PyObject *callback = self->wr_callback;
+
+    if (PyWeakref_GET_OBJECT(self) != Py_None) {
+        PyWeakReference **list = GET_WEAKREFS_LISTPTR(
+            PyWeakref_GET_OBJECT(self));
+
+        if (*list == self)
+	    /* If 'self' is the end of the list (and thus self->wr_next == NULL)
+	       then the weakref list itself (and thus the value of *list) will
+	       end up being set to NULL. */
+            *list = self->wr_next;
+        self->wr_object = Py_None;
+        if (self->wr_prev != NULL)
+            self->wr_prev->wr_next = self->wr_next;
+        if (self->wr_next != NULL)
+            self->wr_next->wr_prev = self->wr_prev;
+        self->wr_prev = NULL;
+        self->wr_next = NULL;
+    }
+    if (callback != NULL) {
+        Py_DECREF(callback);
+        self->wr_callback = NULL;
+    }
+}
+
+/* Cyclic gc uses this to *just* clear the passed-in reference, leaving
+ * the callback intact and uncalled.  It must be possible to call self's
+ * tp_dealloc() after calling this, so self has to be left in a sane enough
+ * state for that to work.  We expect tp_dealloc to decref the callback
+ * then.  The reason for not letting clear_weakref() decref the callback
+ * right now is that if the callback goes away, that may in turn trigger
+ * another callback (if a weak reference to the callback exists) -- running
+ * arbitrary Python code in the middle of gc is a disaster.  The convolution
+ * here allows gc to delay triggering such callbacks until the world is in
+ * a sane state again.
+ */
+void
+_PyWeakref_ClearRef(PyWeakReference *self)
+{
+    PyObject *callback;
+
+    assert(self != NULL);
+    assert(PyWeakref_Check(self));
+    /* Preserve and restore the callback around clear_weakref. */
+    callback = self->wr_callback;
+    self->wr_callback = NULL;
+    clear_weakref(self);
+    self->wr_callback = callback;
+}
+
+static void
+weakref_dealloc(PyObject *self)
+{
+    PyObject_GC_UnTrack(self);
+    clear_weakref((PyWeakReference *) self);
+    self->ob_type->tp_free(self);
+}
+
+
+static int
+gc_traverse(PyWeakReference *self, visitproc visit, void *arg)
+{
+    Py_VISIT(self->wr_callback);
+    return 0;
+}
+
+
+static int
+gc_clear(PyWeakReference *self)
+{
+    clear_weakref(self);
+    return 0;
+}
+
+
+static PyObject *
+weakref_call(PyWeakReference *self, PyObject *args, PyObject *kw)
+{
+    static char *kwlist[] = {NULL};
+
+    if (PyArg_ParseTupleAndKeywords(args, kw, ":__call__", kwlist)) {
+        PyObject *object = PyWeakref_GET_OBJECT(self);
+        Py_INCREF(object);
+        return (object);
+    }
+    return NULL;
+}
+
+
+static long
+weakref_hash(PyWeakReference *self)
+{
+    if (self->hash != -1)
+        return self->hash;
+    if (PyWeakref_GET_OBJECT(self) == Py_None) {
+        PyErr_SetString(PyExc_TypeError, "weak object has gone away");
+        return -1;
+    }
+    self->hash = PyObject_Hash(PyWeakref_GET_OBJECT(self));
+    return self->hash;
+}
+
+
+static PyObject *
+weakref_repr(PyWeakReference *self)
+{
+    char buffer[256];
+    if (PyWeakref_GET_OBJECT(self) == Py_None) {
+        PyOS_snprintf(buffer, sizeof(buffer), "<weakref at %p; dead>", self);
+    }
+    else {
+	char *name = NULL;
+	PyObject *nameobj = PyObject_GetAttrString(PyWeakref_GET_OBJECT(self),
+						   "__name__");
+	if (nameobj == NULL)
+		PyErr_Clear();
+	else if (PyString_Check(nameobj))
+		name = PyString_AS_STRING(nameobj);
+        PyOS_snprintf(buffer, sizeof(buffer),
+		      name ? "<weakref at %p; to '%.50s' at %p (%s)>"
+		           : "<weakref at %p; to '%.50s' at %p>",
+		      self,
+		      PyWeakref_GET_OBJECT(self)->ob_type->tp_name,
+		      PyWeakref_GET_OBJECT(self),
+		      name);
+	Py_XDECREF(nameobj);
+    }
+    return PyString_FromString(buffer);
+}
+
+/* Weak references only support equality, not ordering. Two weak references
+   are equal if the underlying objects are equal. If the underlying object has
+   gone away, they are equal if they are identical. */
+
+static PyObject *
+weakref_richcompare(PyWeakReference* self, PyWeakReference* other, int op)
+{
+    if (op != Py_EQ || self->ob_type != other->ob_type) {
+        Py_INCREF(Py_NotImplemented);
+        return Py_NotImplemented;
+    }
+    if (PyWeakref_GET_OBJECT(self) == Py_None
+        || PyWeakref_GET_OBJECT(other) == Py_None) {
+        PyObject *res = self==other ? Py_True : Py_False;
+        Py_INCREF(res);
+        return res;
+    }
+    return PyObject_RichCompare(PyWeakref_GET_OBJECT(self),
+                                PyWeakref_GET_OBJECT(other), op);
+}
+
+/* Given the head of an object's list of weak references, extract the
+ * two callback-less refs (ref and proxy).  Used to determine if the
+ * shared references exist and to determine the back link for newly
+ * inserted references.
+ */
+static void
+get_basic_refs(PyWeakReference *head,
+               PyWeakReference **refp, PyWeakReference **proxyp)
+{
+    *refp = NULL;
+    *proxyp = NULL;
+
+    if (head != NULL && head->wr_callback == NULL) {
+        /* We need to be careful that the "basic refs" aren't
+           subclasses of the main types.  That complicates this a
+           little. */
+        if (PyWeakref_CheckRefExact(head)) {
+            *refp = head;
+            head = head->wr_next;
+        }
+        if (head != NULL
+            && head->wr_callback == NULL
+            && PyWeakref_CheckProxy(head)) {
+            *proxyp = head;
+            /* head = head->wr_next; */
+        }
+    }
+}
+
+/* Insert 'newref' in the list after 'prev'.  Both must be non-NULL. */
+static void
+insert_after(PyWeakReference *newref, PyWeakReference *prev)
+{
+    newref->wr_prev = prev;
+    newref->wr_next = prev->wr_next;
+    if (prev->wr_next != NULL)
+        prev->wr_next->wr_prev = newref;
+    prev->wr_next = newref;
+}
+
+/* Insert 'newref' at the head of the list; 'list' points to the variable
+ * that stores the head.
+ */
+static void
+insert_head(PyWeakReference *newref, PyWeakReference **list)
+{
+    PyWeakReference *next = *list;
+
+    newref->wr_prev = NULL;
+    newref->wr_next = next;
+    if (next != NULL)
+        next->wr_prev = newref;
+    *list = newref;
+}
+
+static int
+parse_weakref_init_args(char *funcname, PyObject *args, PyObject *kwargs,
+                        PyObject **obp, PyObject **callbackp)
+{
+    /* XXX Should check that kwargs == NULL or is empty. */
+    return PyArg_UnpackTuple(args, funcname, 1, 2, obp, callbackp);
+}
+
+static PyObject *
+weakref___new__(PyTypeObject *type, PyObject *args, PyObject *kwargs)
+{
+    PyWeakReference *self = NULL;
+    PyObject *ob, *callback = NULL;
+
+    if (parse_weakref_init_args("__new__", args, kwargs, &ob, &callback)) {
+        PyWeakReference *ref, *proxy;
+        PyWeakReference **list;
+
+        if (!PyType_SUPPORTS_WEAKREFS(ob->ob_type)) {
+            PyErr_Format(PyExc_TypeError,
+                         "cannot create weak reference to '%s' object",
+                         ob->ob_type->tp_name);
+            return NULL;
+        }
+        if (callback == Py_None)
+            callback = NULL;
+        list = GET_WEAKREFS_LISTPTR(ob);
+        get_basic_refs(*list, &ref, &proxy);
+        if (callback == NULL && type == &_PyWeakref_RefType) {
+            if (ref != NULL) {
+                /* We can re-use an existing reference. */
+                Py_INCREF(ref);
+                return (PyObject *)ref;
+            }
+        }
+        /* We have to create a new reference. */
+        /* Note: the tp_alloc() can trigger cyclic GC, so the weakref
+           list on ob can be mutated.  This means that the ref and
+           proxy pointers we got back earlier may have been collected,
+           so we need to compute these values again before we use
+           them. */
+        self = (PyWeakReference *) (type->tp_alloc(type, 0));
+        if (self != NULL) {
+            init_weakref(self, ob, callback);
+            if (callback == NULL && type == &_PyWeakref_RefType) {
+                insert_head(self, list);
+            }
+            else {
+                PyWeakReference *prev;
+
+                get_basic_refs(*list, &ref, &proxy);
+                prev = (proxy == NULL) ? ref : proxy;
+                if (prev == NULL)
+                    insert_head(self, list);
+                else
+                    insert_after(self, prev);
+            }
+        }
+    }
+    return (PyObject *)self;
+}
+
+static int
+weakref___init__(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+    PyObject *tmp;
+
+    if (parse_weakref_init_args("__init__", args, kwargs, &tmp, &tmp))
+        return 0;
+    else
+        return 1;
+}
+
+
+PyTypeObject
+_PyWeakref_RefType = {
+    PyObject_HEAD_INIT(&PyType_Type)
+    0,
+    "weakref",
+    sizeof(PyWeakReference),
+    0,
+    weakref_dealloc,            /*tp_dealloc*/
+    0,	                        /*tp_print*/
+    0,                          /*tp_getattr*/
+    0,                          /*tp_setattr*/
+    0,	                        /*tp_compare*/
+    (reprfunc)weakref_repr,     /*tp_repr*/
+    0,                          /*tp_as_number*/
+    0,                          /*tp_as_sequence*/
+    0,                          /*tp_as_mapping*/
+    (hashfunc)weakref_hash,     /*tp_hash*/
+    (ternaryfunc)weakref_call,  /*tp_call*/
+    0,                          /*tp_str*/
+    0,                          /*tp_getattro*/
+    0,                          /*tp_setattro*/
+    0,                          /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_RICHCOMPARE
+        | Py_TPFLAGS_BASETYPE,  /*tp_flags*/
+    0,                          /*tp_doc*/
+    (traverseproc)gc_traverse,  /*tp_traverse*/
+    (inquiry)gc_clear,          /*tp_clear*/
+    (richcmpfunc)weakref_richcompare,	/*tp_richcompare*/
+    0,                          /*tp_weaklistoffset*/
+    0,                          /*tp_iter*/
+    0,                          /*tp_iternext*/
+    0,                          /*tp_methods*/
+    0,                          /*tp_members*/
+    0,                          /*tp_getset*/
+    0,                          /*tp_base*/
+    0,                          /*tp_dict*/
+    0,                          /*tp_descr_get*/
+    0,                          /*tp_descr_set*/
+    0,                          /*tp_dictoffset*/
+    weakref___init__,           /*tp_init*/
+    PyType_GenericAlloc,        /*tp_alloc*/
+    weakref___new__,            /*tp_new*/
+    PyObject_GC_Del,            /*tp_free*/
+};
+
+
+static int
+proxy_checkref(PyWeakReference *proxy)
+{
+    if (PyWeakref_GET_OBJECT(proxy) == Py_None) {
+        PyErr_SetString(PyExc_ReferenceError,
+                        "weakly-referenced object no longer exists");
+        return 0;
+    }
+    return 1;
+}
+
+
+/* If a parameter is a proxy, check that it is still "live" and wrap it,
+ * replacing the original value with the raw object.  Raises ReferenceError
+ * if the param is a dead proxy.
+ */
+#define UNWRAP(o) \
+        if (PyWeakref_CheckProxy(o)) { \
+            if (!proxy_checkref((PyWeakReference *)o)) \
+                return NULL; \
+            o = PyWeakref_GET_OBJECT(o); \
+        }
+
+#define UNWRAP_I(o) \
+        if (PyWeakref_CheckProxy(o)) { \
+            if (!proxy_checkref((PyWeakReference *)o)) \
+                return -1; \
+            o = PyWeakref_GET_OBJECT(o); \
+        }
+
+#define WRAP_UNARY(method, generic) \
+    static PyObject * \
+    method(PyObject *proxy) { \
+        UNWRAP(proxy); \
+        return generic(proxy); \
+    }
+
+#define WRAP_BINARY(method, generic) \
+    static PyObject * \
+    method(PyObject *x, PyObject *y) { \
+        UNWRAP(x); \
+        UNWRAP(y); \
+        return generic(x, y); \
+    }
+
+/* Note that the third arg needs to be checked for NULL since the tp_call
+ * slot can receive NULL for this arg.
+ */
+#define WRAP_TERNARY(method, generic) \
+    static PyObject * \
+    method(PyObject *proxy, PyObject *v, PyObject *w) { \
+        UNWRAP(proxy); \
+        UNWRAP(v); \
+        if (w != NULL) \
+            UNWRAP(w); \
+        return generic(proxy, v, w); \
+    }
+
+
+/* direct slots */
+
+WRAP_BINARY(proxy_getattr, PyObject_GetAttr)
+WRAP_UNARY(proxy_str, PyObject_Str)
+WRAP_TERNARY(proxy_call, PyEval_CallObjectWithKeywords)
+
+static PyObject *
+proxy_repr(PyWeakReference *proxy)
+{
+    char buf[160];
+    PyOS_snprintf(buf, sizeof(buf),
+		  "<weakproxy at %p to %.100s at %p>", proxy,
+		  PyWeakref_GET_OBJECT(proxy)->ob_type->tp_name,
+		  PyWeakref_GET_OBJECT(proxy));
+    return PyString_FromString(buf);
+}
+
+
+static int
+proxy_setattr(PyWeakReference *proxy, PyObject *name, PyObject *value)
+{
+    if (!proxy_checkref(proxy))
+        return -1;
+    return PyObject_SetAttr(PyWeakref_GET_OBJECT(proxy), name, value);
+}
+
+static int
+proxy_compare(PyObject *proxy, PyObject *v)
+{
+    UNWRAP_I(proxy);
+    UNWRAP_I(v);
+    return PyObject_Compare(proxy, v);
+}
+
+/* number slots */
+WRAP_BINARY(proxy_add, PyNumber_Add)
+WRAP_BINARY(proxy_sub, PyNumber_Subtract)
+WRAP_BINARY(proxy_mul, PyNumber_Multiply)
+WRAP_BINARY(proxy_div, PyNumber_Divide)
+WRAP_BINARY(proxy_mod, PyNumber_Remainder)
+WRAP_BINARY(proxy_divmod, PyNumber_Divmod)
+WRAP_TERNARY(proxy_pow, PyNumber_Power)
+WRAP_UNARY(proxy_neg, PyNumber_Negative)
+WRAP_UNARY(proxy_pos, PyNumber_Positive)
+WRAP_UNARY(proxy_abs, PyNumber_Absolute)
+WRAP_UNARY(proxy_invert, PyNumber_Invert)
+WRAP_BINARY(proxy_lshift, PyNumber_Lshift)
+WRAP_BINARY(proxy_rshift, PyNumber_Rshift)
+WRAP_BINARY(proxy_and, PyNumber_And)
+WRAP_BINARY(proxy_xor, PyNumber_Xor)
+WRAP_BINARY(proxy_or, PyNumber_Or)
+WRAP_UNARY(proxy_int, PyNumber_Int)
+WRAP_UNARY(proxy_long, PyNumber_Long)
+WRAP_UNARY(proxy_float, PyNumber_Float)
+WRAP_BINARY(proxy_iadd, PyNumber_InPlaceAdd)
+WRAP_BINARY(proxy_isub, PyNumber_InPlaceSubtract)
+WRAP_BINARY(proxy_imul, PyNumber_InPlaceMultiply)
+WRAP_BINARY(proxy_idiv, PyNumber_InPlaceDivide)
+WRAP_BINARY(proxy_imod, PyNumber_InPlaceRemainder)
+WRAP_TERNARY(proxy_ipow, PyNumber_InPlacePower)
+WRAP_BINARY(proxy_ilshift, PyNumber_InPlaceLshift)
+WRAP_BINARY(proxy_irshift, PyNumber_InPlaceRshift)
+WRAP_BINARY(proxy_iand, PyNumber_InPlaceAnd)
+WRAP_BINARY(proxy_ixor, PyNumber_InPlaceXor)
+WRAP_BINARY(proxy_ior, PyNumber_InPlaceOr)
+
+static int
+proxy_nonzero(PyWeakReference *proxy)
+{
+    PyObject *o = PyWeakref_GET_OBJECT(proxy);
+    if (!proxy_checkref(proxy))
+        return -1;
+    return PyObject_IsTrue(o);
+}
+
+static void
+proxy_dealloc(PyWeakReference *self)
+{
+    if (self->wr_callback != NULL)
+        PyObject_GC_UnTrack((PyObject *)self);
+    clear_weakref(self);
+    PyObject_GC_Del(self);
+}
+
+/* sequence slots */
+
+static PyObject *
+proxy_slice(PyWeakReference *proxy, Py_ssize_t i, Py_ssize_t j)
+{
+    if (!proxy_checkref(proxy))
+        return NULL;
+    return PySequence_GetSlice(PyWeakref_GET_OBJECT(proxy), i, j);
+}
+
+static int
+proxy_ass_slice(PyWeakReference *proxy, Py_ssize_t i, Py_ssize_t j, PyObject *value)
+{
+    if (!proxy_checkref(proxy))
+        return -1;
+    return PySequence_SetSlice(PyWeakref_GET_OBJECT(proxy), i, j, value);
+}
+
+static int
+proxy_contains(PyWeakReference *proxy, PyObject *value)
+{
+    if (!proxy_checkref(proxy))
+        return -1;
+    return PySequence_Contains(PyWeakref_GET_OBJECT(proxy), value);
+}
+
+
+/* mapping slots */
+
+static Py_ssize_t
+proxy_length(PyWeakReference *proxy)
+{
+    if (!proxy_checkref(proxy))
+        return -1;
+    return PyObject_Length(PyWeakref_GET_OBJECT(proxy));
+}
+
+WRAP_BINARY(proxy_getitem, PyObject_GetItem)
+
+static int
+proxy_setitem(PyWeakReference *proxy, PyObject *key, PyObject *value)
+{
+    if (!proxy_checkref(proxy))
+        return -1;
+
+    if (value == NULL)
+        return PyObject_DelItem(PyWeakref_GET_OBJECT(proxy), key);
+    else
+        return PyObject_SetItem(PyWeakref_GET_OBJECT(proxy), key, value);
+}
+
+/* iterator slots */
+
+static PyObject *
+proxy_iter(PyWeakReference *proxy)
+{
+    if (!proxy_checkref(proxy))
+        return NULL;
+    return PyObject_GetIter(PyWeakref_GET_OBJECT(proxy));
+}
+
+static PyObject *
+proxy_iternext(PyWeakReference *proxy)
+{
+    if (!proxy_checkref(proxy))
+        return NULL;
+    return PyIter_Next(PyWeakref_GET_OBJECT(proxy));
+}
+
+
+static PyNumberMethods proxy_as_number = {
+    proxy_add,              /*nb_add*/
+    proxy_sub,              /*nb_subtract*/
+    proxy_mul,              /*nb_multiply*/
+    proxy_div,              /*nb_divide*/
+    proxy_mod,              /*nb_remainder*/
+    proxy_divmod,           /*nb_divmod*/
+    proxy_pow,              /*nb_power*/
+    proxy_neg,              /*nb_negative*/
+    proxy_pos,              /*nb_positive*/
+    proxy_abs,              /*nb_absolute*/
+    (inquiry)proxy_nonzero, /*nb_nonzero*/
+    proxy_invert,           /*nb_invert*/
+    proxy_lshift,           /*nb_lshift*/
+    proxy_rshift,           /*nb_rshift*/
+    proxy_and,              /*nb_and*/
+    proxy_xor,              /*nb_xor*/
+    proxy_or,               /*nb_or*/
+    0,                      /*nb_coerce*/
+    proxy_int,              /*nb_int*/
+    proxy_long,             /*nb_long*/
+    proxy_float,            /*nb_float*/
+    0,                      /*nb_oct*/
+    0,                      /*nb_hex*/
+    proxy_iadd,             /*nb_inplace_add*/
+    proxy_isub,             /*nb_inplace_subtract*/
+    proxy_imul,             /*nb_inplace_multiply*/
+    proxy_idiv,             /*nb_inplace_divide*/
+    proxy_imod,             /*nb_inplace_remainder*/
+    proxy_ipow,             /*nb_inplace_power*/
+    proxy_ilshift,          /*nb_inplace_lshift*/
+    proxy_irshift,          /*nb_inplace_rshift*/
+    proxy_iand,             /*nb_inplace_and*/
+    proxy_ixor,             /*nb_inplace_xor*/
+    proxy_ior,              /*nb_inplace_or*/
+};
+
+static PySequenceMethods proxy_as_sequence = {
+    (lenfunc)proxy_length,      /*sq_length*/
+    0,                          /*sq_concat*/
+    0,                          /*sq_repeat*/
+    0,                          /*sq_item*/
+    (ssizessizeargfunc)proxy_slice, /*sq_slice*/
+    0,                          /*sq_ass_item*/
+    (ssizessizeobjargproc)proxy_ass_slice, /*sq_ass_slice*/
+    (objobjproc)proxy_contains, /* sq_contains */
+};
+
+static PyMappingMethods proxy_as_mapping = {
+    (lenfunc)proxy_length,        /*mp_length*/
+    proxy_getitem,                /*mp_subscript*/
+    (objobjargproc)proxy_setitem, /*mp_ass_subscript*/
+};
+
+
+PyTypeObject
+_PyWeakref_ProxyType = {
+    PyObject_HEAD_INIT(&PyType_Type)
+    0,
+    "weakproxy",
+    sizeof(PyWeakReference),
+    0,
+    /* methods */
+    (destructor)proxy_dealloc,          /* tp_dealloc */
+    0,				        /* tp_print */
+    0,				        /* tp_getattr */
+    0, 				        /* tp_setattr */
+    proxy_compare,		        /* tp_compare */
+    (reprfunc)proxy_repr,	        /* tp_repr */
+    &proxy_as_number,		        /* tp_as_number */
+    &proxy_as_sequence,		        /* tp_as_sequence */
+    &proxy_as_mapping,		        /* tp_as_mapping */
+    0,	                                /* tp_hash */
+    0,	                                /* tp_call */
+    proxy_str,                          /* tp_str */
+    proxy_getattr,                      /* tp_getattro */
+    (setattrofunc)proxy_setattr,        /* tp_setattro */
+    0,				        /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC
+    | Py_TPFLAGS_CHECKTYPES,            /* tp_flags */
+    0,                                  /* tp_doc */
+    (traverseproc)gc_traverse,          /* tp_traverse */
+    (inquiry)gc_clear,                  /* tp_clear */
+    0,                                  /* tp_richcompare */
+    0,                                  /* tp_weaklistoffset */
+    (getiterfunc)proxy_iter,            /* tp_iter */
+    (iternextfunc)proxy_iternext,       /* tp_iternext */
+};
+
+
+PyTypeObject
+_PyWeakref_CallableProxyType = {
+    PyObject_HEAD_INIT(&PyType_Type)
+    0,
+    "weakcallableproxy",
+    sizeof(PyWeakReference),
+    0,
+    /* methods */
+    (destructor)proxy_dealloc,          /* tp_dealloc */
+    0,				        /* tp_print */
+    0,				        /* tp_getattr */
+    0, 				        /* tp_setattr */
+    proxy_compare,		        /* tp_compare */
+    (unaryfunc)proxy_repr,	        /* tp_repr */
+    &proxy_as_number,		        /* tp_as_number */
+    &proxy_as_sequence,		        /* tp_as_sequence */
+    &proxy_as_mapping,		        /* tp_as_mapping */
+    0,	                                /* tp_hash */
+    proxy_call,	                        /* tp_call */
+    proxy_str,	                        /* tp_str */
+    proxy_getattr,                      /* tp_getattro */
+    (setattrofunc)proxy_setattr,        /* tp_setattro */
+    0,				        /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC
+    | Py_TPFLAGS_CHECKTYPES,            /* tp_flags */
+    0,                                  /* tp_doc */
+    (traverseproc)gc_traverse,          /* tp_traverse */
+    (inquiry)gc_clear,                  /* tp_clear */
+    0,                                  /* tp_richcompare */
+    0,                                  /* tp_weaklistoffset */
+    (getiterfunc)proxy_iter,            /* tp_iter */
+    (iternextfunc)proxy_iternext,       /* tp_iternext */
+};
+
+
+
+PyObject *
+PyWeakref_NewRef(PyObject *ob, PyObject *callback)
+{
+    PyWeakReference *result = NULL;
+    PyWeakReference **list;
+    PyWeakReference *ref, *proxy;
+
+    if (!PyType_SUPPORTS_WEAKREFS(ob->ob_type)) {
+        PyErr_Format(PyExc_TypeError,
+		     "cannot create weak reference to '%s' object",
+                     ob->ob_type->tp_name);
+        return NULL;
+    }
+    list = GET_WEAKREFS_LISTPTR(ob);
+    get_basic_refs(*list, &ref, &proxy);
+    if (callback == Py_None)
+        callback = NULL;
+    if (callback == NULL)
+        /* return existing weak reference if it exists */
+        result = ref;
+    if (result != NULL)
+        Py_INCREF(result);
+    else {
+        /* Note: new_weakref() can trigger cyclic GC, so the weakref
+           list on ob can be mutated.  This means that the ref and
+           proxy pointers we got back earlier may have been collected,
+           so we need to compute these values again before we use
+           them. */
+        result = new_weakref(ob, callback);
+        if (result != NULL) {
+            get_basic_refs(*list, &ref, &proxy);
+            if (callback == NULL) {
+                if (ref == NULL)
+                    insert_head(result, list);
+                else {
+                    /* Someone else added a ref without a callback
+                       during GC.  Return that one instead of this one
+                       to avoid violating the invariants of the list
+                       of weakrefs for ob. */
+                    Py_DECREF(result);
+                    Py_INCREF(ref);
+                    result = ref;
+                }
+            }
+            else {
+                PyWeakReference *prev;
+
+                prev = (proxy == NULL) ? ref : proxy;
+                if (prev == NULL)
+                    insert_head(result, list);
+                else
+                    insert_after(result, prev);
+            }
+        }
+    }
+    return (PyObject *) result;
+}
+
+
+PyObject *
+PyWeakref_NewProxy(PyObject *ob, PyObject *callback)
+{
+    PyWeakReference *result = NULL;
+    PyWeakReference **list;
+    PyWeakReference *ref, *proxy;
+
+    if (!PyType_SUPPORTS_WEAKREFS(ob->ob_type)) {
+        PyErr_Format(PyExc_TypeError,
+		     "cannot create weak reference to '%s' object",
+                     ob->ob_type->tp_name);
+        return NULL;
+    }
+    list = GET_WEAKREFS_LISTPTR(ob);
+    get_basic_refs(*list, &ref, &proxy);
+    if (callback == Py_None)
+        callback = NULL;
+    if (callback == NULL)
+        /* attempt to return an existing weak reference if it exists */
+        result = proxy;
+    if (result != NULL)
+        Py_INCREF(result);
+    else {
+        /* Note: new_weakref() can trigger cyclic GC, so the weakref
+           list on ob can be mutated.  This means that the ref and
+           proxy pointers we got back earlier may have been collected,
+           so we need to compute these values again before we use
+           them. */
+        result = new_weakref(ob, callback);
+        if (result != NULL) {
+            PyWeakReference *prev;
+
+            if (PyCallable_Check(ob))
+                result->ob_type = &_PyWeakref_CallableProxyType;
+            else
+                result->ob_type = &_PyWeakref_ProxyType;
+            get_basic_refs(*list, &ref, &proxy);
+            if (callback == NULL) {
+                if (proxy != NULL) {
+                    /* Someone else added a proxy without a callback
+                       during GC.  Return that one instead of this one
+                       to avoid violating the invariants of the list
+                       of weakrefs for ob. */
+                    Py_DECREF(result);
+                    Py_INCREF(result = proxy);
+                    goto skip_insert;
+                }
+                prev = ref;
+            }
+            else
+                prev = (proxy == NULL) ? ref : proxy;
+
+            if (prev == NULL)
+                insert_head(result, list);
+            else
+                insert_after(result, prev);
+        skip_insert:
+            ;
+        }
+    }
+    return (PyObject *) result;
+}
+
+
+PyObject *
+PyWeakref_GetObject(PyObject *ref)
+{
+    if (ref == NULL || !PyWeakref_Check(ref)) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+    return PyWeakref_GET_OBJECT(ref);
+}
+
+/* Note that there's an inlined copy-paste of handle_callback() in gcmodule.c's
+ * handle_weakrefs().
+ */
+static void
+handle_callback(PyWeakReference *ref, PyObject *callback)
+{
+    PyObject *cbresult = PyObject_CallFunctionObjArgs(callback, ref, NULL);
+
+    if (cbresult == NULL)
+        PyErr_WriteUnraisable(callback);
+    else
+        Py_DECREF(cbresult);
+}
+
+/* This function is called by the tp_dealloc handler to clear weak references.
+ *
+ * This iterates through the weak references for 'object' and calls callbacks
+ * for those references which have one.  It returns when all callbacks have
+ * been attempted.
+ */
+void
+PyObject_ClearWeakRefs(PyObject *object)
+{
+    PyWeakReference **list;
+
+    if (object == NULL
+        || !PyType_SUPPORTS_WEAKREFS(object->ob_type)
+        || object->ob_refcnt != 0) {
+        PyErr_BadInternalCall();
+        return;
+    }
+    list = GET_WEAKREFS_LISTPTR(object);
+    /* Remove the callback-less basic and proxy references */
+    if (*list != NULL && (*list)->wr_callback == NULL) {
+        clear_weakref(*list);
+        if (*list != NULL && (*list)->wr_callback == NULL)
+            clear_weakref(*list);
+    }
+    if (*list != NULL) {
+        PyWeakReference *current = *list;
+        Py_ssize_t count = _PyWeakref_GetWeakrefCount(current);
+        int restore_error = PyErr_Occurred() ? 1 : 0;
+        PyObject *err_type, *err_value, *err_tb;
+
+        if (restore_error)
+            PyErr_Fetch(&err_type, &err_value, &err_tb);
+        if (count == 1) {
+            PyObject *callback = current->wr_callback;
+
+            current->wr_callback = NULL;
+            clear_weakref(current);
+            if (callback != NULL) {
+                handle_callback(current, callback);
+                Py_DECREF(callback);
+            }
+        }
+        else {
+            PyObject *tuple;
+            Py_ssize_t i = 0;
+    
+            tuple = PyTuple_New(count * 2);
+            if (tuple == NULL) {
+                if (restore_error)
+                    PyErr_Fetch(&err_type, &err_value, &err_tb);
+                return;
+            }
+
+            for (i = 0; i < count; ++i) {
+                PyWeakReference *next = current->wr_next;
+
+                Py_INCREF(current);
+                PyTuple_SET_ITEM(tuple, i * 2, (PyObject *) current);
+                PyTuple_SET_ITEM(tuple, i * 2 + 1, current->wr_callback);
+                current->wr_callback = NULL;
+                clear_weakref(current);
+                current = next;
+            }
+            for (i = 0; i < count; ++i) {
+                PyObject *callback = PyTuple_GET_ITEM(tuple, i * 2 + 1);
+
+                if (callback != NULL) {
+                    PyObject *item = PyTuple_GET_ITEM(tuple, i * 2);
+                    handle_callback((PyWeakReference *)item, callback);
+                }
+            }
+            Py_DECREF(tuple);
+        }
+        if (restore_error)
+            PyErr_Restore(err_type, err_value, err_tb);
+    }
+}

Added: vendor/Python/current/PC/VC6/_bsddb.dsp
===================================================================
--- vendor/Python/current/PC/VC6/_bsddb.dsp	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/VC6/_bsddb.dsp	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,99 @@
+# Microsoft Developer Studio Project File - Name="_bsddb" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=_bsddb - Win32 Release
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "_bsddb.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "_bsddb.mak" CFG="_bsddb - Win32 Release"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "_bsddb - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "_bsddb - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName "_bsddb"
+# PROP Scc_LocalPath ".."
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "_bsddb - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "."
+# PROP Intermediate_Dir "x86-temp-release\_bsddb"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+F90=df.exe
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /Zi /O2 /I "..\..\Include" /I ".." /I "..\..\..\db-4.4.20\build_win32" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
+# ADD LINK32 user32.lib kernel32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ..\..\..\db-4.4.20\build_win32\Release\libdb44s.lib /nologo /base:"0x1e180000" /subsystem:windows /dll /debug /machine:I386 /nodefaultlib:"msvcrt" /out:"./_bsddb.pyd"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF  "$(CFG)" == "_bsddb - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "."
+# PROP Intermediate_Dir "x86-temp-debug\_bsddb"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+F90=df.exe
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\Include" /I ".." /I "..\..\..\db-4.4.20\build_win32" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /YX /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 user32.lib kernel32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ..\..\..\db-4.4.20\build_win32\Release\libdb44s.lib /nologo /base:"0x1e180000" /subsystem:windows /dll /debug /machine:I386 /nodefaultlib:"msvcrtd" /out:"./_bsddb_d.pyd" /pdbtype:sept
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF 
+
+# Begin Target
+
+# Name "_bsddb - Win32 Release"
+# Name "_bsddb - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\..\Modules\_bsddb.c
+# End Source File
+# End Target
+# End Project

Added: vendor/Python/current/PC/VC6/_ctypes.dsp
===================================================================
--- vendor/Python/current/PC/VC6/_ctypes.dsp	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/VC6/_ctypes.dsp	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,131 @@
+# Microsoft Developer Studio Project File - Name="_ctypes" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=_ctypes - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "_ctypes.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "_ctypes.mak" CFG="_ctypes - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "_ctypes - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "_ctypes - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName "_ctypes"
+# PROP Scc_LocalPath ".."
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "_ctypes - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "."
+# PROP Intermediate_Dir "x86-temp-release\_ctypes"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+F90=df.exe
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /Zi /O2 /I "..\..\Include" /I ".." /I "..\..\Modules\_ctypes\libffi_msvc" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /base:"0x1d1a0000" /subsystem:windows /dll /debug /machine:I386 /out:"./_ctypes.pyd"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF  "$(CFG)" == "_ctypes - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "."
+# PROP Intermediate_Dir "x86-temp-debug\_ctypes"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+F90=df.exe
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\Include" /I ".." /I "..\..\Modules\_ctypes\libffi_msvc" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /YX /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /base:"0x1d1a0000" /subsystem:windows /dll /debug /machine:I386 /out:"./_ctypes_d.pyd" /pdbtype:sept
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF 
+
+# Begin Target
+
+# Name "_ctypes - Win32 Release"
+# Name "_ctypes - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\..\Modules\_ctypes\_ctypes.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\_ctypes\callbacks.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\_ctypes\callproc.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\_ctypes\cfield.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\_ctypes\libffi_msvc\ffi.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\_ctypes\malloc_closure.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\_ctypes\libffi_msvc\prep_cif.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\_ctypes\stgdict.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\_ctypes\libffi_msvc\win32.c
+# End Source File
+# End Target
+# End Project

Added: vendor/Python/current/PC/VC6/_ctypes_test.dsp
===================================================================
--- vendor/Python/current/PC/VC6/_ctypes_test.dsp	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/VC6/_ctypes_test.dsp	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,99 @@
+# Microsoft Developer Studio Project File - Name="_ctypes_test" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=_ctypes_test - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "_ctypes_test.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "_ctypes_test.mak" CFG="_ctypes_test - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "_ctypes_test - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "_ctypes_test - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName "_ctypes_test"
+# PROP Scc_LocalPath ".."
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "_ctypes_test - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "."
+# PROP Intermediate_Dir "x86-temp-release\_ctypes_test"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+F90=df.exe
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /Zi /O2 /I "..\..\Include" /I ".." /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:"./_ctypes_test.pyd"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF  "$(CFG)" == "_ctypes_test - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "."
+# PROP Intermediate_Dir "x86-temp-debug\_ctypes_test"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+F90=df.exe
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\Include" /I ".." /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /YX /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:"./_ctypes_test_d.pyd" /pdbtype:sept
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF 
+
+# Begin Target
+
+# Name "_ctypes_test - Win32 Release"
+# Name "_ctypes_test - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\..\Modules\_ctypes\_ctypes_test.c
+# End Source File
+# End Target
+# End Project

Added: vendor/Python/current/PC/VC6/_elementtree.dsp
===================================================================
--- vendor/Python/current/PC/VC6/_elementtree.dsp	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/VC6/_elementtree.dsp	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,111 @@
+# Microsoft Developer Studio Project File - Name="_elementtree" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=_elementtree - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "_elementtree.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "_elementtree.mak" CFG="_elementtree - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "_elementtree - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "_elementtree - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName "_elementtree"
+# PROP Scc_LocalPath ".."
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "_elementtree - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "."
+# PROP Intermediate_Dir "x86-temp-release\_elementtree"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+F90=df.exe
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /Zi /O2 /I "..\..\Include" /I ".." /I "..\..\Modules\expat" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "XML_NS" /D "XML_DTD" /D "BYTEORDER=1234" /D "XML_CONTEXT_BYTES=1024" /D "USE_PYEXPAT_CAPI" /D "XML_STATIC" /D "HAVE_MEMMOVE" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /base:"0x1d100000" /subsystem:windows /dll /debug /machine:I386 /out:"./_elementtree.pyd"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF  "$(CFG)" == "_elementtree - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "."
+# PROP Intermediate_Dir "x86-temp-debug\_elementtree"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+F90=df.exe
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\Include" /I ".." /I "..\..\Modules\expat" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "XML_NS" /D "XML_DTD" /D "BYTEORDER=1234" /D "XML_CONTEXT_BYTES=1024" /D "USE_PYEXPAT_CAPI" /D "XML_STATIC" /D "HAVE_MEMMOVE" /YX /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /base:"0x1d100000" /subsystem:windows /dll /debug /machine:I386 /out:"./_elementtree_d.pyd" /pdbtype:sept
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF 
+
+# Begin Target
+
+# Name "_elementtree - Win32 Release"
+# Name "_elementtree - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\..\Modules\_elementtree.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\expat\xmlparse.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\expat\xmlrole.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\expat\xmltok.c
+# End Source File
+# End Target
+# End Project

Added: vendor/Python/current/PC/VC6/_socket.dsp
===================================================================
--- vendor/Python/current/PC/VC6/_socket.dsp	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/VC6/_socket.dsp	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,99 @@
+# Microsoft Developer Studio Project File - Name="_socket" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=_socket - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "_socket.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "_socket.mak" CFG="_socket - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "_socket - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "_socket - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName "_socket"
+# PROP Scc_LocalPath ".."
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "_socket - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "."
+# PROP Intermediate_Dir "x86-temp-release\_socket"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+F90=df.exe
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /Zi /O2 /I "..\..\Include" /I ".." /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
+# ADD LINK32 user32.lib kernel32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /base:"0x1e1D0000" /subsystem:windows /dll /debug /machine:I386 /out:"./_socket.pyd"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF  "$(CFG)" == "_socket - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "."
+# PROP Intermediate_Dir "x86-temp-debug\_socket"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+F90=df.exe
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\Include" /I ".." /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /YX /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 user32.lib kernel32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /base:"0x1e1D0000" /subsystem:windows /dll /debug /machine:I386 /out:"./_socket_d.pyd" /pdbtype:sept
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF 
+
+# Begin Target
+
+# Name "_socket - Win32 Release"
+# Name "_socket - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\..\Modules\socketmodule.c
+# End Source File
+# End Target
+# End Project

Added: vendor/Python/current/PC/VC6/_sqlite3.dsp
===================================================================
--- vendor/Python/current/PC/VC6/_sqlite3.dsp	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/VC6/_sqlite3.dsp	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,131 @@
+# Microsoft Developer Studio Project File - Name="_sqlite3" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=_sqlite3 - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "_sqlite3.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "_sqlite3.mak" CFG="_sqlite3 - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "_sqlite3 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "_sqlite3 - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName "_sqlite3"
+# PROP Scc_LocalPath ".."
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "_sqlite3 - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "."
+# PROP Intermediate_Dir "x86-temp-release\_sqlite3"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+F90=df.exe
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /Zi /O2 /I "..\..\Include" /I ".." /I "..\..\..\sqlite-source-3.3.4" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "MODULE_NAME=\"sqlite3\"" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
+# ADD LINK32 user32.lib kernel32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ..\..\..\sqlite-source-3.3.4\sqlite3.lib /nologo /base:"0x1e180000" /subsystem:windows /dll /debug /machine:I386 /out:"./_sqlite3.pyd"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF  "$(CFG)" == "_sqlite3 - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "."
+# PROP Intermediate_Dir "x86-temp-debug\_sqlite3"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+F90=df.exe
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\Include" /I ".." /I "..\..\..\sqlite-source-3.3.4" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "MODULE_NAME=\"sqlite3\"" /YX /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 user32.lib kernel32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ..\..\..\sqlite-source-3.3.4\sqlite3.lib /nologo /base:"0x1e180000" /subsystem:windows /dll /debug /machine:I386 /out:"./_sqlite3_d.pyd" /pdbtype:sept
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF 
+
+# Begin Target
+
+# Name "_sqlite3 - Win32 Release"
+# Name "_sqlite3 - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\..\Modules\_sqlite\cache.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\_sqlite\connection.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\_sqlite\cursor.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\_sqlite\microprotocols.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\_sqlite\module.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\_sqlite\prepare_protocol.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\_sqlite\row.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\_sqlite\statement.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\_sqlite\util.c
+# End Source File
+# End Target
+# End Project

Added: vendor/Python/current/PC/VC6/_ssl.dsp
===================================================================
--- vendor/Python/current/PC/VC6/_ssl.dsp	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/VC6/_ssl.dsp	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,89 @@
+# Microsoft Developer Studio Project File - Name="_ssl" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) External Target" 0x0106
+
+CFG=_ssl - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "_ssl.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "_ssl.mak" CFG="_ssl - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "_ssl - Win32 Release" (based on "Win32 (x86) External Target")
+!MESSAGE "_ssl - Win32 Debug" (based on "Win32 (x86) External Target")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+
+!IF  "$(CFG)" == "_ssl - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Cmd_Line "NMAKE /f _ssl.mak"
+# PROP BASE Rebuild_Opt "/a"
+# PROP BASE Target_File "_ssl.exe"
+# PROP BASE Bsc_Name "_ssl.bsc"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "."
+# PROP Intermediate_Dir "x86-temp-release\_ssl"
+# PROP Cmd_Line "python build_ssl.py"
+# PROP Rebuild_Opt "-a"
+# PROP Target_File "_ssl.pyd"
+# PROP Bsc_Name ""
+# PROP Target_Dir ""
+
+!ELSEIF  "$(CFG)" == "_ssl - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "x86-temp-debug\_ssl"
+# PROP BASE Intermediate_Dir "x86-temp-debug\_ssl"
+# PROP BASE Cmd_Line "NMAKE /f _ssl.mak"
+# PROP BASE Rebuild_Opt "/a"
+# PROP BASE Target_File "_ssl_d.pyd"
+# PROP BASE Bsc_Name "_ssl_d.bsc"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "."
+# PROP Intermediate_Dir "x86-temp-debug\_ssl"
+# PROP Cmd_Line "python_d -u build_ssl.py -d"
+# PROP Rebuild_Opt "-a"
+# PROP Target_File "_ssl_d.pyd"
+# PROP Bsc_Name ""
+# PROP Target_Dir ""
+
+!ENDIF 
+
+# Begin Target
+
+# Name "_ssl - Win32 Release"
+# Name "_ssl - Win32 Debug"
+
+!IF  "$(CFG)" == "_ssl - Win32 Release"
+
+!ELSEIF  "$(CFG)" == "_ssl - Win32 Debug"
+
+!ENDIF 
+
+# Begin Source File
+
+SOURCE=..\..\Modules\_ssl.c
+# End Source File
+# End Target
+# End Project

Added: vendor/Python/current/PC/VC6/_ssl.mak
===================================================================
--- vendor/Python/current/PC/VC6/_ssl.mak	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/VC6/_ssl.mak	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,21 @@
+
+!IFDEF DEBUG
+MODULE=_ssl_d.pyd
+TEMP_DIR=x86-temp-debug/_ssl
+CFLAGS=/Od /Zi /MDd /LDd /DDEBUG /D_DEBUG /DWIN32
+SSL_LIB_DIR=$(SSL_DIR)/out32.dbg
+!ELSE
+MODULE=_ssl.pyd
+TEMP_DIR=x86-temp-release/_ssl
+CFLAGS=/Ox /MD /LD /DWIN32
+SSL_LIB_DIR=$(SSL_DIR)/out32
+!ENDIF
+
+INCLUDES=-I ../../Include -I .. -I $(SSL_DIR)/inc32
+LIBS=gdi32.lib wsock32.lib user32.lib advapi32.lib /libpath:$(SSL_LIB_DIR) libeay32.lib ssleay32.lib
+
+SOURCE=../../Modules/_ssl.c $(SSL_LIB_DIR)/libeay32.lib $(SSL_LIB_DIR)/ssleay32.lib
+
+$(MODULE): $(SOURCE) ../*.h ../../Include/*.h
+    @if not exist "$(TEMP_DIR)/." mkdir "$(TEMP_DIR)"
+    cl /nologo $(SOURCE) $(CFLAGS) /Fo$(TEMP_DIR)\$*.obj $(INCLUDES) /link /out:$(MODULE) $(LIBS)

Added: vendor/Python/current/PC/VC6/_testcapi.dsp
===================================================================
--- vendor/Python/current/PC/VC6/_testcapi.dsp	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/VC6/_testcapi.dsp	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,99 @@
+# Microsoft Developer Studio Project File - Name="_testcapi" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=_testcapi - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "_testcapi.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "_testcapi.mak" CFG="_testcapi - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "_testcapi - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "_testcapi - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName "_testcapi"
+# PROP Scc_LocalPath ".."
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "_testcapi - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "."
+# PROP Intermediate_Dir "x86-temp-release\_testcapi"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+F90=df.exe
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MMAP_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\Include" /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MMAP_EXPORTS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0xc09 /d "NDEBUG"
+# ADD RSC /l 0xc09 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /base:"0x1e1F0000" /dll /machine:I386 /out:"./_testcapi.pyd"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF  "$(CFG)" == "_testcapi - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "."
+# PROP Intermediate_Dir "x86-temp-debug\_testcapi"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+F90=df.exe
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MMAP_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\Include" /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MMAP_EXPORTS" /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0xc09 /d "_DEBUG"
+# ADD RSC /l 0xc09 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /base:"0x1e1F0000" /dll /debug /machine:I386 /out:"./_testcapi_d.pyd" /pdbtype:sept
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF 
+
+# Begin Target
+
+# Name "_testcapi - Win32 Release"
+# Name "_testcapi - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\..\Modules\_testcapimodule.c
+# End Source File
+# End Target
+# End Project

Added: vendor/Python/current/PC/VC6/_tkinter.dsp
===================================================================
--- vendor/Python/current/PC/VC6/_tkinter.dsp	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/VC6/_tkinter.dsp	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,103 @@
+# Microsoft Developer Studio Project File - Name="_tkinter" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=_tkinter - Win32 Release
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "_tkinter.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "_tkinter.mak" CFG="_tkinter - Win32 Release"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "_tkinter - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "_tkinter - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName "_tkinter"
+# PROP Scc_LocalPath "..\..\.."
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "_tkinter - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "."
+# PROP Intermediate_Dir "x86-temp-debug\_tkinter"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+F90=df.exe
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\..\tcltk\include" /I "..\..\Include" /I ".." /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "WITH_APPINIT" /YX /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\..\..\tcltk\lib\tk84.lib ..\..\..\tcltk\lib\tcl84.lib odbc32.lib odbccp32.lib user32.lib kernel32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /base:"0x1e190000" /subsystem:windows /dll /debug /machine:I386 /out:"./_tkinter_d.pyd" /pdbtype:sept /libpath:"C:\Program Files\Tcl\lib"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF  "$(CFG)" == "_tkinter - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "."
+# PROP Intermediate_Dir "x86-temp-release\_tkinter"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+F90=df.exe
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /Zi /O2 /I "..\..\..\tcltk\include" /I "..\..\Include" /I ".." /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "WITH_APPINIT" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
+# ADD LINK32 ..\..\..\tcltk\lib\tk84.lib ..\..\..\tcltk\lib\tcl84.lib odbc32.lib odbccp32.lib user32.lib kernel32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /base:"0x1e190000" /subsystem:windows /dll /debug /machine:I386 /out:"./_tkinter.pyd" /libpath:"C:\Program Files\Tcl\lib"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF 
+
+# Begin Target
+
+# Name "_tkinter - Win32 Release"
+# Name "_tkinter - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\..\Modules\_tkinter.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\tkappinit.c
+# End Source File
+# End Target
+# End Project

Added: vendor/Python/current/PC/VC6/build_ssl.py
===================================================================
--- vendor/Python/current/PC/VC6/build_ssl.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/VC6/build_ssl.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,163 @@
+# Script for building the _ssl module for Windows.
+# Uses Perl to setup the OpenSSL environment correctly
+# and build OpenSSL, then invokes a simple nmake session
+# for _ssl.pyd itself.
+
+# THEORETICALLY, you can:
+# * Unpack the latest SSL release one level above your main Python source
+#   directory.  It is likely you will already find the zlib library and
+#   any other external packages there.
+# * Install ActivePerl and ensure it is somewhere on your path.
+# * Run this script from the PCBuild directory.
+#
+# it should configure and build SSL, then build the ssl Python extension
+# without intervention.
+
+import os, sys, re
+
+# Find all "foo.exe" files on the PATH.
+def find_all_on_path(filename, extras = None):
+    entries = os.environ["PATH"].split(os.pathsep)
+    ret = []
+    for p in entries:
+        fname = os.path.abspath(os.path.join(p, filename))
+        if os.path.isfile(fname) and fname not in ret:
+            ret.append(fname)
+    if extras:
+        for p in extras:
+            fname = os.path.abspath(os.path.join(p, filename))
+            if os.path.isfile(fname) and fname not in ret:
+                ret.append(fname)
+    return ret
+
+# Find a suitable Perl installation for OpenSSL.
+# cygwin perl does *not* work.  ActivePerl does.
+# Being a Perl dummy, the simplest way I can check is if the "Win32" package
+# is available.
+def find_working_perl(perls):
+    for perl in perls:
+        fh = os.popen(perl + ' -e "use Win32;"')
+        fh.read()
+        rc = fh.close()
+        if rc:
+            continue
+        return perl
+    print "Can not find a suitable PERL:"
+    if perls:
+        print " the following perl interpreters were found:"
+        for p in perls:
+            print " ", p
+        print " None of these versions appear suitable for building OpenSSL"
+    else:
+        print " NO perl interpreters were found on this machine at all!"
+    print " Please install ActivePerl and ensure it appears on your path"
+    print "The Python SSL module was not built"
+    return None
+
+# Locate the best SSL directory given a few roots to look into.
+def find_best_ssl_dir(sources):
+    candidates = []
+    for s in sources:
+        try:
+            s = os.path.abspath(s)
+            fnames = os.listdir(s)
+        except os.error:
+            fnames = []
+        for fname in fnames:
+            fqn = os.path.join(s, fname)
+            if os.path.isdir(fqn) and fname.startswith("openssl-"):
+                candidates.append(fqn)
+    # Now we have all the candidates, locate the best.
+    best_parts = []
+    best_name = None
+    for c in candidates:
+        parts = re.split("[.-]", os.path.basename(c))[1:]
+        # eg - openssl-0.9.7-beta1 - ignore all "beta" or any other qualifiers
+        if len(parts) >= 4:
+            continue
+        if parts > best_parts:
+            best_parts = parts
+            best_name = c
+    if best_name is not None:
+        print "Found an SSL directory at '%s'" % (best_name,)
+    else:
+        print "Could not find an SSL directory in '%s'" % (sources,)
+    return best_name
+
+def main():
+    debug = "-d" in sys.argv
+    build_all = "-a" in sys.argv
+    make_flags = ""
+    if build_all:
+        make_flags = "-a"
+    # perl should be on the path, but we also look in "\perl" and "c:\\perl"
+    # as "well known" locations
+    perls = find_all_on_path("perl.exe", ["\\perl\\bin", "C:\\perl\\bin"])
+    perl = find_working_perl(perls)
+    if perl is None:
+        sys.exit(1)
+
+    print "Found a working perl at '%s'" % (perl,)
+    # Look for SSL 3 levels up from pcbuild - ie, same place zlib etc all live.
+    ssl_dir = find_best_ssl_dir(("../../..",))
+    if ssl_dir is None:
+        sys.exit(1)
+
+    old_cd = os.getcwd()
+    try:
+        os.chdir(ssl_dir)
+        # If the ssl makefiles do not exist, we invoke Perl to generate them.
+        if not os.path.isfile(os.path.join(ssl_dir, "32.mak")) or \
+           not os.path.isfile(os.path.join(ssl_dir, "d32.mak")):
+            print "Creating the makefiles..."
+            # Put our working Perl at the front of our path
+            os.environ["PATH"] = os.path.split(perl)[0] + \
+                                          os.pathsep + \
+                                          os.environ["PATH"]
+            # ms\32all.bat will reconfigure OpenSSL and then try to build
+            # all outputs (debug/nondebug/dll/lib).  So we filter the file
+            # to exclude any "nmake" commands and then execute.
+            tempname = "ms\\32all_py.bat"
+
+            in_bat  = open("ms\\32all.bat")
+            temp_bat = open(tempname,"w")
+            while 1:
+                cmd = in_bat.readline()
+                print 'cmd', repr(cmd)
+                if not cmd: break
+                if cmd.strip()[:5].lower() == "nmake":
+                    continue
+                temp_bat.write(cmd)
+            in_bat.close()
+            temp_bat.close()
+            os.system(tempname)
+            try:
+                os.remove(tempname)
+            except:
+                pass
+
+        # Now run make.
+        print "Executing nmake over the ssl makefiles..."
+        if debug:
+            rc = os.system("nmake /nologo -f d32.mak")
+            if rc:
+                print "Executing d32.mak failed"
+                print rc
+                sys.exit(rc)
+        else:
+            rc = os.system("nmake /nologo -f 32.mak")
+            if rc:
+                print "Executing 32.mak failed"
+                print rc
+                sys.exit(rc)
+    finally:
+        os.chdir(old_cd)
+    # And finally, we can build the _ssl module itself for Python.
+    defs = "SSL_DIR=%s" % (ssl_dir,)
+    if debug:
+        defs = defs + " " + "DEBUG=1"
+    rc = os.system('nmake /nologo -f _ssl.mak ' + defs + " " + make_flags)
+    sys.exit(rc)
+
+if __name__=='__main__':
+    main()

Added: vendor/Python/current/PC/VC6/bz2.dsp
===================================================================
--- vendor/Python/current/PC/VC6/bz2.dsp	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/VC6/bz2.dsp	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,99 @@
+# Microsoft Developer Studio Project File - Name="bz2" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=bz2 - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "bz2.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "bz2.mak" CFG="bz2 - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "bz2 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "bz2 - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName "bz2"
+# PROP Scc_LocalPath ".."
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "bz2 - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "."
+# PROP Intermediate_Dir "x86-temp-release\bz2"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+F90=df.exe
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /Zi /O2 /I "..\..\Include" /I ".." /I "..\..\..\bzip2-1.0.3" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
+# ADD LINK32 ..\..\..\bzip2-1.0.3\libbz2.lib /nologo /base:"0x1D170000" /subsystem:windows /dll /debug /machine:I386 /nodefaultlib:"libc" /out:"./bz2.pyd"
+# SUBTRACT LINK32 /pdb:none /nodefaultlib
+
+!ELSEIF  "$(CFG)" == "bz2 - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "."
+# PROP Intermediate_Dir "x86-temp-debug\bz2"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+F90=df.exe
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\Include" /I ".." /I "..\..\..\bzip2-1.0.3" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /YX /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\..\..\bzip2-1.0.3\libbz2.lib /nologo /base:"0x1D170000" /subsystem:windows /dll /debug /machine:I386 /nodefaultlib:"msvcrt" /nodefaultlib:"libc" /out:"./bz2_d.pyd" /pdbtype:sept
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF 
+
+# Begin Target
+
+# Name "bz2 - Win32 Release"
+# Name "bz2 - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\..\Modules\bz2module.c
+# End Source File
+# End Target
+# End Project

Added: vendor/Python/current/PC/VC6/make_versioninfo.dsp
===================================================================
--- vendor/Python/current/PC/VC6/make_versioninfo.dsp	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/VC6/make_versioninfo.dsp	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,108 @@
+# Microsoft Developer Studio Project File - Name="make_versioninfo" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=make_versioninfo - Win32 Release
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "make_versioninfo.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "make_versioninfo.mak" CFG="make_versioninfo - Win32 Release"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "make_versioninfo - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "make_versioninfo - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName "make_versioninfo"
+# PROP Scc_LocalPath ".."
+CPP=cl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "make_versioninfo - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "."
+# PROP Intermediate_Dir "x86-temp-release\make_versioninfo"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /Zi /O2 /I "..\..\Include" /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /base:"0x1d000000" /subsystem:console /debug /machine:I386
+# SUBTRACT LINK32 /pdb:none
+# Begin Custom Build
+InputPath=.\make_versioninfo.exe
+SOURCE="$(InputPath)"
+
+"..\pythonnt_rc.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+	.\make_versioninfo.exe >..\pythonnt_rc.h
+
+# End Custom Build
+
+!ELSEIF  "$(CFG)" == "make_versioninfo - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "."
+# PROP Intermediate_Dir "x86-temp-debug\make_versioninfo"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\Include" /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /i "..\..\Include" /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /base:"0x1d000000" /subsystem:console /debug /machine:I386 /out:"./make_versioninfo_d.exe" /pdbtype:sept
+# SUBTRACT LINK32 /pdb:none
+# Begin Custom Build
+InputPath=.\make_versioninfo_d.exe
+SOURCE="$(InputPath)"
+
+"..\pythonnt_rc_d.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+	.\make_versioninfo_d.exe >..\pythonnt_rc_d.h
+
+# End Custom Build
+
+!ENDIF 
+
+# Begin Target
+
+# Name "make_versioninfo - Win32 Release"
+# Name "make_versioninfo - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\make_versioninfo.c
+# End Source File
+# End Target
+# End Project

Added: vendor/Python/current/PC/VC6/pcbuild.dsw
===================================================================
--- vendor/Python/current/PC/VC6/pcbuild.dsw	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/VC6/pcbuild.dsw	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,287 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "_bsddb"=".\_bsddb.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+    Begin Project Dependency
+    Project_Dep_Name pythoncore
+    End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "_ctypes"=".\_ctypes.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "_ctypes_test"=".\_ctypes_test.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "_elementtree"=".\_elementtree.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "_socket"=".\_socket.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+    Begin Project Dependency
+    Project_Dep_Name pythoncore
+    End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "_sqlite3"=".\_sqlite3.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "_ssl"=".\_ssl.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+    Begin Project Dependency
+    Project_Dep_Name pythoncore
+    End Project Dependency
+    Begin Project Dependency
+    Project_Dep_Name python
+    End Project Dependency
+    Begin Project Dependency
+    Project_Dep_Name w9xpopen
+    End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "_testcapi"=".\_testcapi.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+    Begin Project Dependency
+    Project_Dep_Name pythoncore
+    End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "_tkinter"=".\_tkinter.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+    Begin Project Dependency
+    Project_Dep_Name pythoncore
+    End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "bz2"=".\bz2.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "make_versioninfo"=".\make_versioninfo.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "pyexpat"=".\pyexpat.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+    Begin Project Dependency
+    Project_Dep_Name pythoncore
+    End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "python"=".\python.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+    Begin Project Dependency
+    Project_Dep_Name pythoncore
+    End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "pythoncore"=".\pythoncore.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+    Begin Project Dependency
+    Project_Dep_Name make_versioninfo
+    End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "pythonw"=".\pythonw.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+    Begin Project Dependency
+    Project_Dep_Name pythoncore
+    End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "select"=".\select.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+    Begin Project Dependency
+    Project_Dep_Name pythoncore
+    End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "unicodedata"=".\unicodedata.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+    Begin Project Dependency
+    Project_Dep_Name pythoncore
+    End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "w9xpopen"=".\w9xpopen.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "winsound"=".\winsound.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+    Begin Project Dependency
+    Project_Dep_Name pythoncore
+    End Project Dependency
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+

Added: vendor/Python/current/PC/VC6/pyexpat.dsp
===================================================================
--- vendor/Python/current/PC/VC6/pyexpat.dsp	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/VC6/pyexpat.dsp	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,111 @@
+# Microsoft Developer Studio Project File - Name="pyexpat" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=pyexpat - Win32 Release
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "pyexpat.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "pyexpat.mak" CFG="pyexpat - Win32 Release"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "pyexpat - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "pyexpat - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName "pyexpat"
+# PROP Scc_LocalPath ".."
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "pyexpat - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "."
+# PROP Intermediate_Dir "x86-temp-release\pyexpat"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+F90=df.exe
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /Zi /O2 /I "..\..\Include" /I ".." /I "..\..\Modules\expat" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "XML_NS" /D "XML_DTD" /D BYTEORDER=1234 /D XML_CONTEXT_BYTES=1024 /D "XML_STATIC" /D "HAVE_MEMMOVE" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
+# ADD LINK32 user32.lib kernel32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /base:"0x1D100000" /subsystem:windows /dll /debug /machine:I386 /out:"./pyexpat.pyd"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF  "$(CFG)" == "pyexpat - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "."
+# PROP Intermediate_Dir "x86-temp-debug\pyexpat"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+F90=df.exe
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\Include" /I ".." /I "..\..\Modules\expat" /D "_DEBUG" /D "HAVE_EXPAT_H" /D "WIN32" /D "_WINDOWS" /D "XML_NS" /D "XML_DTD" /D BYTEORDER=1234 /D XML_CONTEXT_BYTES=1024 /D "XML_STATIC" /D "HAVE_MEMMOVE" /YX /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 user32.lib kernel32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /base:"0x1D100000" /subsystem:windows /dll /debug /machine:I386 /out:"./pyexpat_d.pyd" /pdbtype:sept
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF 
+
+# Begin Target
+
+# Name "pyexpat - Win32 Release"
+# Name "pyexpat - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\..\Modules\pyexpat.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\expat\xmlparse.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\expat\xmlrole.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\expat\xmltok.c
+# End Source File
+# End Target
+# End Project

Added: vendor/Python/current/PC/VC6/python.dsp
===================================================================
--- vendor/Python/current/PC/VC6/python.dsp	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/VC6/python.dsp	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,100 @@
+# Microsoft Developer Studio Project File - Name="python" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=python - Win32 Release
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "python.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "python.mak" CFG="python - Win32 Release"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "python - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "python - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName "python"
+# PROP Scc_LocalPath ".."
+CPP=cl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "python - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "."
+# PROP Intermediate_Dir "x86-temp-release\python"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /Zi /O2 /I "..\..\Include" /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /base:"0x1d000000" /subsystem:console /debug /machine:I386
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF  "$(CFG)" == "python - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "."
+# PROP Intermediate_Dir "x86-temp-debug\python"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\Include" /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /i "....\\Include" /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /base:"0x1d000000" /subsystem:console /debug /machine:I386 /out:"./python_d.exe" /pdbtype:sept
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF 
+
+# Begin Target
+
+# Name "python - Win32 Release"
+# Name "python - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\pycon.ico
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\python.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\python_exe.rc
+# End Source File
+# End Target
+# End Project

Added: vendor/Python/current/PC/VC6/pythoncore.dsp
===================================================================
--- vendor/Python/current/PC/VC6/pythoncore.dsp	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/VC6/pythoncore.dsp	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,705 @@
+# Microsoft Developer Studio Project File - Name="pythoncore" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=pythoncore - Win32 Release
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "pythoncore.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "pythoncore.mak" CFG="pythoncore - Win32 Release"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "pythoncore - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "pythoncore - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName "pythoncore"
+# PROP Scc_LocalPath ".."
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "pythoncore - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "."
+# PROP Intermediate_Dir "x86-temp-release\pythoncore"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+F90=df.exe
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /Zi /O2 /I "..\..\Include" /I ".." /I "..\..\modules\zlib" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "USE_DL_EXPORT" /YX /FD /Zm200 /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /i "..\..\Include" /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
+# ADD LINK32 largeint.lib kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /base:"0x1e000000" /subsystem:windows /dll /debug /machine:I386 /nodefaultlib:"libc" /out:"./python25.dll"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF  "$(CFG)" == "pythoncore - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "."
+# PROP Intermediate_Dir "x86-temp-debug\pythoncore"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+F90=df.exe
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\Include" /I ".." /I "..\..\modules\zlib" /D "_DEBUG" /D "USE_DL_EXPORT" /D "WIN32" /D "_WINDOWS" /YX /FD /Zm200 /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /i "..\..\Include" /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 largeint.lib kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /base:"0x1e000000" /subsystem:windows /dll /debug /machine:I386 /nodefaultlib:"libc" /out:"./python25_d.dll" /pdbtype:sept
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF 
+
+# Begin Target
+
+# Name "pythoncore - Win32 Release"
+# Name "pythoncore - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\..\Modules\_bisectmodule.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\cjkcodecs\_codecs_cn.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\cjkcodecs\_codecs_hk.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\cjkcodecs\_codecs_iso2022.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\cjkcodecs\_codecs_jp.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\cjkcodecs\_codecs_kr.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\cjkcodecs\_codecs_tw.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\_codecsmodule.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\_csv.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\_functoolsmodule.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\_heapqmodule.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\_hotshot.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\_localemodule.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\_lsprof.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\_randommodule.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\_sre.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\_struct.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\PC\_subprocess.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\_typesmodule.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\_weakref.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\_winreg.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Objects\abstract.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Parser\acceler.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\zlib\adler32.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\arraymodule.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Python\asdl.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Python\ast.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\audioop.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\binascii.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Parser\bitset.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Python\bltinmodule.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Objects\boolobject.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Objects\bufferobject.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Objects\cellobject.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Python\ceval.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Objects\classobject.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\cmathmodule.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Objects\cobject.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Python\codecs.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Objects\codeobject.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\collectionsmodule.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Python\compile.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Objects\complexobject.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\zlib\compress.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\config.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\cPickle.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\zlib\crc32.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\cStringIO.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\datetimemodule.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\zlib\deflate.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Objects\descrobject.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Objects\dictobject.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\dl_nt.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Python\dynload_win.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Objects\enumobject.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\errnomodule.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Python\errors.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Objects\exceptions.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Objects\fileobject.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Objects\floatobject.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Objects\frameobject.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Python\frozen.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Objects\funcobject.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Python\future.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\gcmodule.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Objects\genobject.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Python\getargs.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\getbuildinfo.c
+# ADD CPP /D BUILD=46
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Python\getcompiler.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Python\getcopyright.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Python\getmtime.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Python\getopt.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\getpathp.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Python\getplatform.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Python\getversion.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Python\graminit.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Parser\grammar1.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\imageop.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Python\import.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\import_nt.c
+# ADD CPP /I "..\..\Python"
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Python\importdl.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\zlib\inffast.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\zlib\inflate.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\zlib\inftrees.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Objects\intobject.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Objects\iterobject.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\itertoolsmodule.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Parser\listnode.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Objects\listobject.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Objects\longobject.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\main.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Python\marshal.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\mathmodule.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\md5.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\md5module.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Parser\metagrammar.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Objects\methodobject.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\mmapmodule.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Python\modsupport.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Objects\moduleobject.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\msvcrtmodule.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\cjkcodecs\multibytecodec.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Parser\myreadline.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Python\mysnprintf.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Python\mystrtoul.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Parser\node.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Objects\object.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Objects\obmalloc.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\operator.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Parser\parser.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\parsermodule.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Parser\parsetok.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\posixmodule.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Python\pyarena.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Python\pyfpe.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Python\pystate.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Python\pystrtod.c
+# End Source File
+# Begin Source File
+
+SOURCE="..\..\Python\Python-ast.c"
+# End Source File
+# Begin Source File
+
+SOURCE=..\python_nt.rc
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Python\pythonrun.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Objects\rangeobject.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\rgbimgmodule.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\rotatingtree.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Objects\setobject.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\sha256module.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\sha512module.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\shamodule.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\signalmodule.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Objects\sliceobject.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Objects\stringobject.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\stropmodule.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Python\structmember.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Objects\structseq.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Python\symtable.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\symtablemodule.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Python\sysmodule.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Python\thread.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\threadmodule.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\timemodule.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Parser\tokenizer.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Python\traceback.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\zlib\trees.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Objects\tupleobject.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Objects\typeobject.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Objects\unicodectype.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Objects\unicodeobject.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Objects\weakrefobject.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\xxsubtype.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\yuvconvert.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\zipimport.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\zlibmodule.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\zlib\zutil.c
+# End Source File
+# End Target
+# End Project

Added: vendor/Python/current/PC/VC6/pythonw.dsp
===================================================================
--- vendor/Python/current/PC/VC6/pythonw.dsp	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/VC6/pythonw.dsp	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,101 @@
+# Microsoft Developer Studio Project File - Name="pythonw" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=pythonw - Win32 Alpha Release
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "pythonw.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "pythonw.mak" CFG="pythonw - Win32 Alpha Release"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "pythonw - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "pythonw - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName "pythonw"
+# PROP Scc_LocalPath "..\pc"
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "pythonw - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "."
+# PROP Intermediate_Dir "x86-temp-release\pythonw"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /Zi /O2 /I "..\..\Include" /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /base:"0x1d000000" /subsystem:windows /debug /machine:I386
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF  "$(CFG)" == "pythonw - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "."
+# PROP Intermediate_Dir "x86-temp-debug\pythonw"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\Include" /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /base:"0x1d000000" /subsystem:windows /debug /machine:I386 /out:"./pythonw_d.exe" /pdbtype:sept
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF 
+
+# Begin Target
+
+# Name "pythonw - Win32 Release"
+# Name "pythonw - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\python_exe.rc
+# End Source File
+# Begin Source File
+
+SOURCE=..\WinMain.c
+# End Source File
+# End Target
+# End Project

Added: vendor/Python/current/PC/VC6/readme.txt
===================================================================
--- vendor/Python/current/PC/VC6/readme.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/VC6/readme.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,248 @@
+Building Python using VC++ 6.0 or 5.0
+-------------------------------------
+This directory is used to build Python for Win32 platforms, e.g. Windows
+95, 98 and NT.  It requires Microsoft Visual C++ 6.x or 5.x.
+(For other Windows platforms and compilers, see ../readme.txt.)
+
+All you need to do is open the workspace "pcbuild.dsw" in MSVC++, select
+the Debug or Release setting (using Build -> Set Active Configuration...),
+and build the projects.
+
+The proper order to build subprojects:
+
+1) pythoncore (this builds the main Python DLL and library files,
+               python21.{dll, lib} in Release mode)
+              NOTE:  in previous releases, this subproject was
+              named after the release number, e.g. python20.
+
+2) python (this builds the main Python executable,
+           python.exe in Release mode)
+
+3) the other subprojects, as desired or needed (note:  you probably don't
+   want to build most of the other subprojects, unless you're building an
+   entire Python distribution from scratch, or specifically making changes
+   to the subsystems they implement; see SUBPROJECTS below)
+
+When using the Debug setting, the output files have a _d added to
+their name:  python21_d.dll, python_d.exe, parser_d.pyd, and so on.
+
+SUBPROJECTS
+-----------
+These subprojects should build out of the box.  Subprojects other than the
+main ones (pythoncore, python, pythonw) generally build a DLL (renamed to
+.pyd) from a specific module so that users don't have to load the code
+supporting that module unless they import the module.
+
+pythoncore
+    .dll and .lib
+python
+    .exe
+pythonw
+    pythonw.exe, a variant of python.exe that doesn't pop up a DOS box
+_socket
+    socketmodule.c
+_testcapi
+    tests of the Python C API, run via Lib/test/test_capi.py, and
+    implemented by module Modules/_testcapimodule.c
+pyexpat
+    Python wrapper for accelerated XML parsing, which incorporates stable
+    code from the Expat project:  http://sourceforge.net/projects/expat/
+select
+    selectmodule.c
+unicodedata
+    large tables of Unicode data
+winsound
+    play sounds (typically .wav files) under Windows
+
+The following subprojects will generally NOT build out of the box.  They
+wrap code Python doesn't control, and you'll need to download the base
+packages first and unpack them into siblings of PCbuilds's parent
+directory; for example, if your PCbuild is  .......\dist\src\PCbuild\,
+unpack into new subdirectories of dist\.
+
+_tkinter
+    Python wrapper for the Tk windowing system.  Requires building
+    Tcl/Tk first.  Following are instructions for Tcl/Tk 8.4.12.
+
+    Get source
+    ----------
+    In the dist directory, run
+    svn export http://svn.python.org/projects/external/tcl8.4.12
+    svn export http://svn.python.org/projects/external/tk8.4.12
+    svn export http://svn.python.org/projects/external/tix-8.4.0
+
+    Build Tcl first (done here w/ MSVC 6 on Win2K)
+    ---------------
+    cd dist\tcl8.4.12\win
+    run vcvars32.bat
+    nmake -f makefile.vc
+    nmake -f makefile.vc INSTALLDIR=..\..\tcltk install
+
+    XXX Should we compile with OPTS=threads?
+
+    Optional:  run tests, via
+        nmake -f makefile.vc test
+
+        all.tcl:        Total   10835   Passed  10096   Skipped 732     Failed  7
+        Sourced 129 Test Files.
+        Files with failing tests: exec.test expr.test io.test main.test string.test stri
+        ngObj.test
+
+    Build Tk
+    --------
+    cd dist\tk8.4.12\win
+    nmake -f makefile.vc TCLDIR=..\..\tcl8.4.12
+    nmake -f makefile.vc TCLDIR=..\..\tcl8.4.12 INSTALLDIR=..\..\tcltk install
+
+    XXX Should we compile with OPTS=threads?
+
+    XXX I have no idea whether "nmake -f makefile.vc test" passed or
+    XXX failed.  It popped up tons of little windows, and did lots of
+    XXX stuff, and nothing blew up.
+
+   Built Tix
+   ---------
+   cd dist\tix-8.4.0\win
+   nmake -f python.mak
+   nmake -f python.mak install
+
+bz2
+    Python wrapper for the libbz2 compression library.  Homepage
+        http://sources.redhat.com/bzip2/
+    Download the source from the python.org copy into the dist
+    directory:
+
+    svn export http://svn.python.org/projects/external/bzip2-1.0.3
+
+    And requires building bz2 first.
+
+    cd dist\bzip2-1.0.3
+    nmake -f makefile.msc
+
+    All of this managed to build bzip2-1.0.3\libbz2.lib, which the Python
+    project links in.
+
+
+_bsddb
+    To use the version of bsddb that Python is built with by default, invoke
+    (in the dist directory)
+
+     svn export http://svn.python.org/projects/external/db-4.4.20
+
+    Then open db-4.4.20\build_win32\Berkeley_DB.dsw and build the "db_static"
+    project for "Release" mode.
+
+    Alternatively, if you want to start with the original sources,
+    go to Sleepycat's download page:
+        http://www.sleepycat.com/downloads/releasehistorybdb.html
+
+    and download version 4.4.20.
+
+    With or without strong cryptography? You can choose either with or
+    without strong cryptography, as per the instructions below.  By
+    default, Python is built and distributed WITHOUT strong crypto.
+
+    Unpack the sources; if you downloaded the non-crypto version, rename
+    the directory from db-4.4.20.NC to db-4.4.20.
+
+    Now apply any patches that apply to your version.
+
+    To run extensive tests, pass "-u bsddb" to regrtest.py.  test_bsddb3.py
+    is then enabled.  Running in verbose mode may be helpful.
+
+    XXX The test_bsddb3 tests don't always pass, on Windows (according to
+    XXX me) or on Linux (according to Barry).  (I had much better luck
+    XXX on Win2K than on Win98SE.)  The common failure mode across platforms
+    XXX is
+    XXX     DBAgainError: (11, 'Resource temporarily unavailable -- unable
+    XXX                         to join the environment')
+    XXX
+    XXX and it appears timing-dependent.  On Win2K I also saw this once:
+    XXX
+    XXX test02_SimpleLocks (bsddb.test.test_thread.HashSimpleThreaded) ...
+    XXX Exception in thread reader 1:
+    XXX Traceback (most recent call last):
+    XXX File "C:\Code\python\lib\threading.py", line 411, in __bootstrap
+    XXX    self.run()
+    XXX File "C:\Code\python\lib\threading.py", line 399, in run
+    XXX    apply(self.__target, self.__args, self.__kwargs)
+    XXX File "C:\Code\python\lib\bsddb\test\test_thread.py", line 268, in
+    XXX                  readerThread
+    XXX    rec = c.next()
+    XXX DBLockDeadlockError: (-30996, 'DB_LOCK_DEADLOCK: Locker killed
+    XXX                                to resolve a deadlock')
+    XXX
+    XXX I'm told that DBLockDeadlockError is expected at times.  It
+    XXX doesn't cause a test to fail when it happens (exceptions in
+    XXX threads are invisible to unittest).
+
+
+_ssl
+    Python wrapper for the secure sockets library.
+
+    Get the latest source code for OpenSSL from
+        http://www.openssl.org
+
+    You (probably) don't want the "engine" code.  For example, get
+        openssl-0.9.6g.tar.gz
+    not
+        openssl-engine-0.9.6g.tar.gz
+
+    Unpack into the "dist" directory, retaining the folder name from
+    the archive - for example, the latest stable OpenSSL will install as
+        dist/openssl-0.9.6g
+
+    You can (theoretically) use any version of OpenSSL you like - the
+    build process will automatically select the latest version.
+
+    You must also install ActivePerl from
+        http://www.activestate.com/Products/ActivePerl/
+    as this is used by the OpenSSL build process.  Complain to them <wink>.
+
+    The MSVC project simply invokes PCBuild/build_ssl.py to perform
+    the build.  This Python script locates and builds your OpenSSL
+    installation, then invokes a simple makefile to build the final .pyd.
+
+    Win9x users:  see "Win9x note" below.
+
+    build_ssl.py attempts to catch the most common errors (such as not
+    being able to find OpenSSL sources, or not being able to find a Perl
+    that works with OpenSSL) and give a reasonable error message.
+    If you have a problem that doesn't seem to be handled correctly
+    (eg, you know you have ActivePerl but we can't find it), please take
+    a peek at build_ssl.py and suggest patches.  Note that build_ssl.py
+    should be able to be run directly from the command-line.
+
+    build_ssl.py/MSVC isn't clever enough to clean OpenSSL - you must do
+    this by hand.
+
+    Win9x note:  If, near the start of the build process, you see
+    something like
+
+        C:\Code\openssl-0.9.6g>set OPTS=no-asm
+        Out of environment space
+
+    then you're in trouble, and will probably also see these errors near
+    the end of the process:
+
+        NMAKE : fatal error U1073: don't know how to make
+            'crypto\md5\asm\m5_win32.asm'
+        Stop.
+        NMAKE : fatal error U1073: don't know how to make
+            'C:\Code\openssl-0.9.6g/out32/libeay32.lib'
+        Stop.
+
+    You need more environment space.  Win9x only has room for 256 bytes
+    by default, and especially after installing ActivePerl (which fiddles
+    the PATH envar), you're likely to run out.  KB Q230205
+
+        http://support.microsoft.com/default.aspx?scid=KB;en-us;q230205
+
+    explains how to edit CONFIG.SYS to cure this.
+
+
+YOUR OWN EXTENSION DLLs
+-----------------------
+If you want to create your own extension module DLL, there's an example
+with easy-to-follow instructions in ../PC/example/; read the file
+readme.txt there first.

Added: vendor/Python/current/PC/VC6/rmpyc.py
===================================================================
--- vendor/Python/current/PC/VC6/rmpyc.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/VC6/rmpyc.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,25 @@
+# Remove all the .pyc and .pyo files under ../Lib.
+
+
+def deltree(root):
+    import os
+    from os.path import join
+
+    npyc = npyo = 0
+    for root, dirs, files in os.walk(root):
+        for name in files:
+            delete = False
+            if name.endswith('.pyc'):
+                delete = True
+                npyc += 1
+            elif name.endswith('.pyo'):
+                delete = True
+                npyo += 1
+
+            if delete:
+                os.remove(join(root, name))
+
+    return npyc, npyo
+
+npyc, npyo = deltree("../../Lib")
+print npyc, ".pyc deleted,", npyo, ".pyo deleted"

Added: vendor/Python/current/PC/VC6/rt.bat
===================================================================
--- vendor/Python/current/PC/VC6/rt.bat	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/VC6/rt.bat	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,41 @@
+ at rem Run Tests.  Run the regression test suite.
+ at rem Usage:  rt [-d] [-O] [-q] regrtest_args
+ at rem -d   Run Debug build (python_d.exe).  Else release build.
+ at rem -O   Run python.exe or python_d.exe (see -d) with -O.
+ at rem -q   "quick" -- normally the tests are run twice, the first time
+ at rem      after deleting all the .py[co] files reachable from Lib/.
+ at rem      -q runs the tests just once, and without deleting .py[co] files.
+ at rem All leading instances of these switches are shifted off, and
+ at rem whatever remains is passed to regrtest.py.  For example,
+ at rem     rt -O -d -x test_thread
+ at rem runs
+ at rem     python_d -O ../../lib/test/regrtest.py -x test_thread
+ at rem twice, and
+ at rem     rt -q -g test_binascii
+ at rem runs
+ at rem     python_d ../../lib/test/regrtest.py -g test_binascii
+ at rem to generate the expected-output file for binascii quickly.
+ at set _exe=python
+ at set _qmode=no
+ at set _dashO=
+ at goto CheckOpts
+:Again
+ at shift
+:CheckOpts
+ at if "%1"=="-O" set _dashO=-O
+ at if "%1"=="-O" goto Again
+ at if "%1"=="-q" set _qmode=yes
+ at if "%1"=="-q" goto Again
+ at if "%1"=="-d" set _exe=python_d
+ at if "%1"=="-d" goto Again
+ at if "%_qmode%"=="yes" goto Qmode
+ at echo Deleting .pyc/.pyo files ...
+@%_exe% rmpyc.py
+%_exe% %_dashO% -E -tt ../../lib/test/regrtest.py %1 %2 %3 %4 %5 %6 %7 %8 %9
+ at echo About to run again without deleting .pyc/.pyo first:
+ at pause
+:Qmode
+%_exe% %_dashO% -E -tt ../../lib/test/regrtest.py %1 %2 %3 %4 %5 %6 %7 %8 %9
+ at set _exe=
+ at set _qmode=
+ at set _dashO=


Property changes on: vendor/Python/current/PC/VC6/rt.bat
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/PC/VC6/select.dsp
===================================================================
--- vendor/Python/current/PC/VC6/select.dsp	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/VC6/select.dsp	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,99 @@
+# Microsoft Developer Studio Project File - Name="select" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=select - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "select.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "select.mak" CFG="select - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "select - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "select - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName "select"
+# PROP Scc_LocalPath ".."
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "select - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "."
+# PROP Intermediate_Dir "x86-temp-release\select"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+F90=df.exe
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /Zi /O2 /I "..\..\Include" /I ".." /I "..\..\..\select113" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
+# ADD LINK32 user32.lib kernel32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /base:"0x1D110000" /subsystem:windows /dll /debug /machine:I386 /nodefaultlib:"libc" /out:"./select.pyd"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF  "$(CFG)" == "select - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "."
+# PROP Intermediate_Dir "x86-temp-debug\select"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+F90=df.exe
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\Include" /I ".." /I "..\..\..\select113" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /YX /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 user32.lib kernel32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /base:"0x1D110000" /subsystem:windows /dll /debug /machine:I386 /nodefaultlib:"libc" /nodefaultlib:"msvcrt" /out:"./select_d.pyd" /pdbtype:sept
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF 
+
+# Begin Target
+
+# Name "select - Win32 Release"
+# Name "select - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\..\Modules\selectmodule.c
+# End Source File
+# End Target
+# End Project

Added: vendor/Python/current/PC/VC6/unicodedata.dsp
===================================================================
--- vendor/Python/current/PC/VC6/unicodedata.dsp	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/VC6/unicodedata.dsp	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,99 @@
+# Microsoft Developer Studio Project File - Name="unicodedata" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=unicodedata - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "unicodedata.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "unicodedata.mak" CFG="unicodedata - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "unicodedata - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "unicodedata - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName "unicodedata"
+# PROP Scc_LocalPath ".."
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "unicodedata - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "."
+# PROP Intermediate_Dir "x86-temp-release\unicodedata"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+F90=df.exe
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MMAP_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\Include" /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MMAP_EXPORTS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0xc09 /d "NDEBUG"
+# ADD RSC /l 0xc09 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /base:"0x1D120000" /dll /machine:I386 /out:"./unicodedata.pyd"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF  "$(CFG)" == "unicodedata - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "."
+# PROP Intermediate_Dir "x86-temp-debug\unicodedata"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+F90=df.exe
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MMAP_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\Include" /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MMAP_EXPORTS" /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0xc09 /d "_DEBUG"
+# ADD RSC /l 0xc09 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /base:"0x1D120000" /dll /debug /machine:I386 /out:"./unicodedata_d.pyd" /pdbtype:sept
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF 
+
+# Begin Target
+
+# Name "unicodedata - Win32 Release"
+# Name "unicodedata - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\..\Modules\unicodedata.c
+# End Source File
+# End Target
+# End Project

Added: vendor/Python/current/PC/VC6/w9xpopen.dsp
===================================================================
--- vendor/Python/current/PC/VC6/w9xpopen.dsp	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/VC6/w9xpopen.dsp	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,97 @@
+# Microsoft Developer Studio Project File - Name="w9xpopen" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=w9xpopen - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "w9xpopen.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "w9xpopen.mak" CFG="w9xpopen - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "w9xpopen - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "w9xpopen - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "w9xpopen - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "."
+# PROP Intermediate_Dir "x86-temp-release\w9xpopen"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0xc09 /d "NDEBUG"
+# ADD RSC /l 0xc09 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 user32.lib /nologo /machine:I386
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF  "$(CFG)" == "w9xpopen - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "."
+# PROP Intermediate_Dir "x86-temp-debug\w9xpopen"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0xc09 /d "_DEBUG"
+# ADD RSC /l 0xc09 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 user32.lib /nologo /debug /machine:I386 /out:"./w9xpopen_d.exe" /pdbtype:sept
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF 
+
+# Begin Target
+
+# Name "w9xpopen - Win32 Release"
+# Name "w9xpopen - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\w9xpopen.c
+# End Source File
+# End Target
+# End Project

Added: vendor/Python/current/PC/VC6/winsound.dsp
===================================================================
--- vendor/Python/current/PC/VC6/winsound.dsp	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/VC6/winsound.dsp	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,99 @@
+# Microsoft Developer Studio Project File - Name="winsound" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=winsound - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "winsound.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "winsound.mak" CFG="winsound - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "winsound - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "winsound - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName "winsound"
+# PROP Scc_LocalPath "..\pc"
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "winsound - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "."
+# PROP Intermediate_Dir "x86-temp-release\winsound"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+F90=df.exe
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "WINSOUND_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\Include" /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "WINSOUND_EXPORTS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0xc09 /d "NDEBUG"
+# ADD RSC /l 0xc09 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib winmm.lib user32.lib /nologo /base:"0x1D160000" /dll /machine:I386 /out:"./winsound.pyd"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF  "$(CFG)" == "winsound - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "."
+# PROP Intermediate_Dir "x86-temp-debug\winsound"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+F90=df.exe
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "WINSOUND_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\Include" /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "WINSOUND_EXPORTS" /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0xc09 /d "_DEBUG"
+# ADD RSC /l 0xc09 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 user32.lib kernel32.lib winmm.lib /nologo /base:"0x1D160000" /dll /debug /machine:I386 /out:"./winsound_d.pyd" /pdbtype:sept
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF 
+
+# Begin Target
+
+# Name "winsound - Win32 Release"
+# Name "winsound - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\winsound.c
+# End Source File
+# End Target
+# End Project

Added: vendor/Python/current/PC/WinMain.c
===================================================================
--- vendor/Python/current/PC/WinMain.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/WinMain.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,16 @@
+/* Minimal main program -- everything is loaded from the library. */
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+#include "Python.h"
+
+int WINAPI WinMain(
+    HINSTANCE hInstance,      /* handle to current instance */
+    HINSTANCE hPrevInstance,  /* handle to previous instance */
+    LPSTR lpCmdLine,          /* pointer to command line */
+    int nCmdShow              /* show state of window */
+)
+{
+    return Py_Main(__argc, __argv);
+}

Added: vendor/Python/current/PC/_msi.c
===================================================================
--- vendor/Python/current/PC/_msi.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/_msi.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1008 @@
+/* Helper library for MSI creation with Python.
+ * Copyright (C) 2005 Martin v. Löwis
+ * Licensed to PSF under a contributor agreement.
+ */
+
+#include <Python.h>
+#include <fci.h>
+#include <fcntl.h>
+#include <windows.h>
+#include <msi.h>
+#include <msiquery.h>
+#include <msidefs.h>
+#include <rpc.h>
+
+static PyObject *MSIError;
+
+static PyObject*
+uuidcreate(PyObject* obj, PyObject*args)
+{
+    UUID result;
+    char *cresult;
+    PyObject *oresult;
+    
+    /* May return ok, local only, and no address.
+       For local only, the documentation says we still get a uuid.
+       For RPC_S_UUID_NO_ADDRESS, it's not clear whether we can
+       use the result. */
+    if (UuidCreate(&result) == RPC_S_UUID_NO_ADDRESS) {
+	PyErr_SetString(PyExc_NotImplementedError, "processing 'no address' result");
+	return NULL;
+    }
+
+    if (UuidToString(&result, &cresult) == RPC_S_OUT_OF_MEMORY) {
+	PyErr_SetString(PyExc_MemoryError, "out of memory in uuidgen");
+	return NULL;
+    }
+
+    oresult = PyString_FromString(cresult);
+    RpcStringFree(&cresult);
+    return oresult;
+
+}
+
+/* FCI callback functions */
+
+static FNFCIALLOC(cb_alloc)
+{
+    return malloc(cb);
+}
+
+static FNFCIFREE(cb_free)
+{
+    free(memory);
+}
+
+static FNFCIOPEN(cb_open)
+{
+    int result = _open(pszFile, oflag, pmode);
+    if (result == -1)
+	*err = errno;
+    return result;
+}
+
+static FNFCIREAD(cb_read)
+{
+    UINT result = (UINT)_read(hf, memory, cb);
+    if (result != cb)
+	*err = errno;
+    return result;
+}
+
+static FNFCIWRITE(cb_write)
+{
+    UINT result = (UINT)_write(hf, memory, cb);
+    if (result != cb)
+	*err = errno;
+    return result;
+}
+
+static FNFCICLOSE(cb_close)
+{
+    int result = _close(hf);
+    if (result != 0)
+	*err = errno;
+    return result;
+}
+
+static FNFCISEEK(cb_seek)
+{
+    long result = (long)_lseek(hf, dist, seektype);
+    if (result == -1)
+	*err = errno;
+    return result;
+}
+
+static FNFCIDELETE(cb_delete)
+{
+    int result = remove(pszFile);
+    if (result != 0)
+	*err = errno;
+    return result;
+}
+
+static FNFCIFILEPLACED(cb_fileplaced)
+{
+    return 0;
+}
+
+static FNFCIGETTEMPFILE(cb_gettempfile)
+{
+    char *name = _tempnam("", "tmp");
+    if ((name != NULL) && ((int)strlen(name) < cbTempName)) {
+	strcpy(pszTempName, name);
+	free(name);
+	return TRUE;
+    }
+
+    if (name) free(name);
+    return FALSE;
+}
+
+static FNFCISTATUS(cb_status)
+{
+    if (pv) {
+	PyObject *result = PyObject_CallMethod(pv, "status", "iii", typeStatus, cb1, cb2);
+	if (result == NULL)
+	    return -1;
+	Py_DECREF(result);
+    }
+    return 0;
+}
+
+static FNFCIGETNEXTCABINET(cb_getnextcabinet)
+{
+    if (pv) {
+	PyObject *result = PyObject_CallMethod(pv, "getnextcabinet", "i", pccab->iCab);
+	if (result == NULL)
+	    return -1;
+	if (!PyString_Check(result)) {
+	    PyErr_Format(PyExc_TypeError, 
+		"Incorrect return type %s from getnextcabinet",
+		result->ob_type->tp_name);
+	    Py_DECREF(result);
+	    return FALSE;
+	}
+	strncpy(pccab->szCab, PyString_AsString(result), sizeof(pccab->szCab));
+	return TRUE;
+    }
+    return FALSE;
+}
+
+static FNFCIGETOPENINFO(cb_getopeninfo)
+{
+    BY_HANDLE_FILE_INFORMATION bhfi;
+    FILETIME filetime;
+    HANDLE handle;
+
+    /* Need Win32 handle to get time stamps */
+    handle = CreateFile(pszName, GENERIC_READ, FILE_SHARE_READ, NULL,
+	OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+    if (handle == INVALID_HANDLE_VALUE)
+	return -1;
+
+    if (GetFileInformationByHandle(handle, &bhfi) == FALSE)
+    {
+	CloseHandle(handle);
+	return -1;
+    }
+
+    FileTimeToLocalFileTime(&bhfi.ftLastWriteTime, &filetime);
+    FileTimeToDosDateTime(&filetime, pdate, ptime);
+
+    *pattribs = (int)(bhfi.dwFileAttributes & 
+	(_A_RDONLY | _A_SYSTEM | _A_HIDDEN | _A_ARCH));
+
+    CloseHandle(handle);
+
+    return _open(pszName, _O_RDONLY | _O_BINARY);
+}
+
+static PyObject* fcicreate(PyObject* obj, PyObject* args)
+{
+    char *cabname;
+    PyObject *files;
+    CCAB ccab;
+    HFCI hfci;
+    ERF erf;
+    int i;
+
+
+    if (!PyArg_ParseTuple(args, "sO:FCICreate", &cabname, &files))
+	return NULL;
+
+    if (!PyList_Check(files)) {
+	PyErr_SetString(PyExc_TypeError, "FCICreate expects a list");
+	return NULL;
+    }
+
+    ccab.cb = INT_MAX; /* no need to split CAB into multiple media */
+    ccab.cbFolderThresh = 1000000; /* flush directory after this many bytes */
+    ccab.cbReserveCFData = 0;
+    ccab.cbReserveCFFolder = 0;
+    ccab.cbReserveCFHeader = 0;
+
+    ccab.iCab = 1;
+    ccab.iDisk = 1;
+
+    ccab.setID = 0;
+    ccab.szDisk[0] = '\0';
+
+    for (i=0; cabname[i]; i++)
+	if (cabname[i] == '\\' || cabname[i] == '/')
+	    break;
+
+    if (i > sizeof(ccab.szCabPath) ||
+	strlen(cabname+i) > sizeof(ccab.szCab)) {
+	PyErr_SetString(PyExc_ValueError, "path name too long");
+	return 0;
+    }
+
+    if (cabname[i]) {
+	memcpy(ccab.szCabPath, cabname, i);
+	ccab.szCabPath[i] = '\0';
+	strcpy(ccab.szCab, cabname+i);
+    } else {
+	strcpy(ccab.szCabPath, ".");
+	strcpy(ccab.szCab, cabname);
+    }
+
+    hfci = FCICreate(&erf, cb_fileplaced, cb_alloc, cb_free,
+	cb_open, cb_read, cb_write, cb_close, cb_seek, cb_delete,
+	cb_gettempfile, &ccab, NULL);
+
+    if (hfci == NULL) {
+	PyErr_Format(PyExc_ValueError, "FCI error %d", erf.erfOper);
+	return NULL;
+    }
+
+    for (i=0; i < PyList_GET_SIZE(files); i++) {
+	PyObject *item = PyList_GET_ITEM(files, i);
+	char *filename, *cabname;
+	if (!PyArg_ParseTuple(item, "ss", &filename, &cabname))
+	    goto err;
+	if (!FCIAddFile(hfci, filename, cabname, FALSE, 
+	    cb_getnextcabinet, cb_status, cb_getopeninfo,
+	    tcompTYPE_MSZIP))
+	    goto err;
+    }
+
+    if (!FCIFlushCabinet(hfci, FALSE, cb_getnextcabinet, cb_status))
+	goto err;
+
+    if (!FCIDestroy(hfci))
+	goto err;
+
+    Py_INCREF(Py_None);
+    return Py_None;
+err:
+    PyErr_Format(PyExc_ValueError, "FCI error %d", erf.erfOper); /* XXX better error type */
+    FCIDestroy(hfci);
+    return NULL;
+}
+
+typedef struct msiobj{
+    PyObject_HEAD
+    MSIHANDLE h;
+}msiobj;
+
+static void 
+msiobj_dealloc(msiobj* msidb)
+{
+    MsiCloseHandle(msidb->h);
+    msidb->h = 0;
+}
+
+static PyObject*
+msiobj_close(msiobj* msidb, PyObject *args)
+{
+    MsiCloseHandle(msidb->h);
+    msidb->h = 0;
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject*
+msierror(int status)
+{
+    int code;
+    char buf[2000];
+    char *res = buf;
+    DWORD size = sizeof(buf);
+    MSIHANDLE err = MsiGetLastErrorRecord();
+
+    if (err == 0) {
+	switch(status) {
+	case ERROR_ACCESS_DENIED:
+	    PyErr_SetString(MSIError, "access denied");
+	    return NULL;
+	case ERROR_FUNCTION_FAILED:
+	    PyErr_SetString(MSIError, "function failed");
+	    return NULL;
+	case ERROR_INVALID_DATA:
+	    PyErr_SetString(MSIError, "invalid data");
+	    return NULL;
+	case ERROR_INVALID_HANDLE:
+	    PyErr_SetString(MSIError, "invalid handle");
+	    return NULL;
+	case ERROR_INVALID_STATE:
+	    PyErr_SetString(MSIError, "invalid state");
+	    return NULL;
+	case ERROR_INVALID_PARAMETER:
+	    PyErr_SetString(MSIError, "invalid parameter");
+	    return NULL;
+	default:
+	    PyErr_Format(MSIError, "unknown error %x", status);
+	    return NULL;
+	}
+    }
+
+    code = MsiRecordGetInteger(err, 1); /* XXX code */
+    if (MsiFormatRecord(0, err, res, &size) == ERROR_MORE_DATA) {
+	res = malloc(size+1);
+	MsiFormatRecord(0, err, res, &size);
+	res[size]='\0';
+    }
+    MsiCloseHandle(err);
+    PyErr_SetString(MSIError, res);
+    if (res != buf)
+	free(res);
+    return NULL;
+}
+
+/*************************** Record objects **********************/
+
+static PyObject*
+record_getfieldcount(msiobj* record, PyObject* args)
+{
+    return PyInt_FromLong(MsiRecordGetFieldCount(record->h));
+}
+
+static PyObject*
+record_cleardata(msiobj* record, PyObject *args)
+{
+    int status = MsiRecordClearData(record->h);
+    if (status != ERROR_SUCCESS)
+	return msierror(status);
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject*
+record_setstring(msiobj* record, PyObject *args)
+{
+    int status;
+    int field;
+    char *data;
+
+    if (!PyArg_ParseTuple(args, "is:SetString", &field, &data))
+	return NULL;
+
+    if ((status = MsiRecordSetString(record->h, field, data)) != ERROR_SUCCESS)
+	return msierror(status);
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject*
+record_setstream(msiobj* record, PyObject *args)
+{
+    int status;
+    int field;
+    char *data;
+
+    if (!PyArg_ParseTuple(args, "is:SetStream", &field, &data))
+	return NULL;
+
+    if ((status = MsiRecordSetStream(record->h, field, data)) != ERROR_SUCCESS)
+	return msierror(status);
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject*
+record_setinteger(msiobj* record, PyObject *args)
+{
+    int status;
+    int field;
+    int data;
+
+    if (!PyArg_ParseTuple(args, "ii:SetInteger", &field, &data))
+	return NULL;
+
+    if ((status = MsiRecordSetInteger(record->h, field, data)) != ERROR_SUCCESS)
+	return msierror(status);
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+
+
+static PyMethodDef record_methods[] = {
+    { "GetFieldCount", (PyCFunction)record_getfieldcount, METH_NOARGS, 
+	PyDoc_STR("GetFieldCount() -> int\nWraps MsiRecordGetFieldCount")},
+    { "SetString", (PyCFunction)record_setstring, METH_VARARGS, 
+	PyDoc_STR("SetString(field,str) -> None\nWraps MsiRecordSetString")},
+    { "SetStream", (PyCFunction)record_setstream, METH_VARARGS, 
+	PyDoc_STR("SetStream(field,filename) -> None\nWraps MsiRecordSetInteger")},
+    { "SetInteger", (PyCFunction)record_setinteger, METH_VARARGS, 
+	PyDoc_STR("SetInteger(field,int) -> None\nWraps MsiRecordSetInteger")},
+    { "ClearData", (PyCFunction)record_cleardata, METH_NOARGS, 
+	PyDoc_STR("ClearData() -> int\nWraps MsiRecordGClearData")},
+    { NULL, NULL }
+};
+
+static PyTypeObject record_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0,			/*ob_size*/
+	"_msi.Record",		/*tp_name*/
+	sizeof(msiobj),	/*tp_basicsize*/
+	0,			/*tp_itemsize*/
+	/* methods */
+	(destructor)msiobj_dealloc, /*tp_dealloc*/
+	0,			/*tp_print*/
+	0,			/*tp_getattr*/
+	0,			/*tp_setattr*/
+	0,			/*tp_compare*/
+	0,			/*tp_repr*/
+	0,			/*tp_as_number*/
+	0,			/*tp_as_sequence*/
+	0,			/*tp_as_mapping*/
+	0,			/*tp_hash*/
+        0,                      /*tp_call*/
+        0,                      /*tp_str*/
+        PyObject_GenericGetAttr,/*tp_getattro*/
+        PyObject_GenericSetAttr,/*tp_setattro*/
+        0,                      /*tp_as_buffer*/
+        Py_TPFLAGS_DEFAULT,     /*tp_flags*/
+        0,                      /*tp_doc*/
+        0,                      /*tp_traverse*/
+        0,                      /*tp_clear*/
+        0,                      /*tp_richcompare*/
+        0,                      /*tp_weaklistoffset*/
+        0,                      /*tp_iter*/
+        0,                      /*tp_iternext*/
+        record_methods,           /*tp_methods*/
+        0,                      /*tp_members*/
+        0,                      /*tp_getset*/
+        0,                      /*tp_base*/
+        0,                      /*tp_dict*/
+        0,                      /*tp_descr_get*/
+        0,                      /*tp_descr_set*/
+        0,                      /*tp_dictoffset*/
+        0,                      /*tp_init*/
+        0,                      /*tp_alloc*/
+        0,                      /*tp_new*/
+        0,                      /*tp_free*/
+        0,                      /*tp_is_gc*/
+};
+
+static PyObject*
+record_new(MSIHANDLE h)
+{
+    msiobj *result = PyObject_NEW(struct msiobj, &record_Type);
+
+    if (!result) {
+	MsiCloseHandle(h);
+	return NULL;
+    }
+
+    result->h = h;
+    return (PyObject*)result;
+}
+
+/*************************** SummaryInformation objects **************/
+
+static PyObject*
+summary_getproperty(msiobj* si, PyObject *args)
+{
+    int status;
+    int field;
+    PyObject *result;
+    UINT type;
+    INT ival;
+    FILETIME fval;
+    char sbuf[1000];
+    char *sval = sbuf;
+    DWORD ssize = sizeof(sval);
+
+    if (!PyArg_ParseTuple(args, "i:GetProperty", &field))
+	return NULL;
+
+    status = MsiSummaryInfoGetProperty(si->h, field, &type, &ival, 
+	&fval, sval, &ssize);
+    if (status == ERROR_MORE_DATA) {
+	sval = malloc(ssize);
+        status = MsiSummaryInfoGetProperty(si->h, field, &type, &ival, 
+    	    &fval, sval, &ssize);
+    }
+
+    switch(type) {
+	case VT_I2: case VT_I4:
+	    return PyInt_FromLong(ival);
+	case VT_FILETIME:
+	    PyErr_SetString(PyExc_NotImplementedError, "FILETIME result");
+	    return NULL;
+	case VT_LPSTR:
+	    result = PyString_FromStringAndSize(sval, ssize);
+	    if (sval != sbuf)
+		free(sval);
+	    return result;
+    }
+    PyErr_Format(PyExc_NotImplementedError, "result of type %d", type);
+    return NULL;
+}
+
+static PyObject*
+summary_getpropertycount(msiobj* si, PyObject *args)
+{
+    int status;
+    UINT result;
+
+    status = MsiSummaryInfoGetPropertyCount(si->h, &result);
+    if (status != ERROR_SUCCESS)
+	return msierror(status);
+
+    return PyInt_FromLong(result);
+}
+
+static PyObject*
+summary_setproperty(msiobj* si, PyObject *args)
+{
+    int status;
+    int field;
+    PyObject* data;
+
+    if (!PyArg_ParseTuple(args, "iO:SetProperty", &field, &data))
+	return NULL;
+
+    if (PyString_Check(data)) {
+	status = MsiSummaryInfoSetProperty(si->h, field, VT_LPSTR,
+	    0, NULL, PyString_AsString(data));
+    } else if (PyInt_Check(data)) {
+	status = MsiSummaryInfoSetProperty(si->h, field, VT_I4,
+	    PyInt_AsLong(data), NULL, NULL);
+    } else {
+	PyErr_SetString(PyExc_TypeError, "unsupported type");
+	return NULL;
+    }
+    
+    if (status != ERROR_SUCCESS)
+	return msierror(status);
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+
+static PyObject*
+summary_persist(msiobj* si, PyObject *args)
+{
+    int status;
+
+    status = MsiSummaryInfoPersist(si->h);
+    if (status != ERROR_SUCCESS)
+	return msierror(status);
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyMethodDef summary_methods[] = {
+    { "GetProperty", (PyCFunction)summary_getproperty, METH_VARARGS, 
+	PyDoc_STR("GetProperty(propid) -> value\nWraps MsiSummaryInfoGetProperty")},
+    { "GetPropertyCount", (PyCFunction)summary_getpropertycount, METH_NOARGS, 
+	PyDoc_STR("GetProperty() -> int\nWraps MsiSummaryInfoGetPropertyCount")},
+    { "SetProperty", (PyCFunction)summary_setproperty, METH_VARARGS, 
+	PyDoc_STR("SetProperty(value) -> None\nWraps MsiSummaryInfoProperty")},
+    { "Persist", (PyCFunction)summary_persist, METH_NOARGS, 
+	PyDoc_STR("Persist() -> None\nWraps MsiSummaryInfoPersist")},
+    { NULL, NULL }
+};
+
+static PyTypeObject summary_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0,			/*ob_size*/
+	"_msi.SummaryInformation",		/*tp_name*/
+	sizeof(msiobj),	/*tp_basicsize*/
+	0,			/*tp_itemsize*/
+	/* methods */
+	(destructor)msiobj_dealloc, /*tp_dealloc*/
+	0,			/*tp_print*/
+	0,			/*tp_getattr*/
+	0,			/*tp_setattr*/
+	0,			/*tp_compare*/
+	0,			/*tp_repr*/
+	0,			/*tp_as_number*/
+	0,			/*tp_as_sequence*/
+	0,			/*tp_as_mapping*/
+	0,			/*tp_hash*/
+        0,                      /*tp_call*/
+        0,                      /*tp_str*/
+        PyObject_GenericGetAttr,/*tp_getattro*/
+        PyObject_GenericSetAttr,/*tp_setattro*/
+        0,                      /*tp_as_buffer*/
+        Py_TPFLAGS_DEFAULT,     /*tp_flags*/
+        0,                      /*tp_doc*/
+        0,                      /*tp_traverse*/
+        0,                      /*tp_clear*/
+        0,                      /*tp_richcompare*/
+        0,                      /*tp_weaklistoffset*/
+        0,                      /*tp_iter*/
+        0,                      /*tp_iternext*/
+        summary_methods,        /*tp_methods*/
+        0,                      /*tp_members*/
+        0,                      /*tp_getset*/
+        0,                      /*tp_base*/
+        0,                      /*tp_dict*/
+        0,                      /*tp_descr_get*/
+        0,                      /*tp_descr_set*/
+        0,                      /*tp_dictoffset*/
+        0,                      /*tp_init*/
+        0,                      /*tp_alloc*/
+        0,                      /*tp_new*/
+        0,                      /*tp_free*/
+        0,                      /*tp_is_gc*/
+};
+
+/*************************** View objects **************/
+
+static PyObject*
+view_execute(msiobj *view, PyObject*args)
+{
+    int status;
+    MSIHANDLE params = 0;
+    PyObject *oparams = Py_None;
+
+    if (!PyArg_ParseTuple(args, "O:Execute", &oparams))
+	return NULL;
+
+    if (oparams != Py_None) {
+        if (oparams->ob_type != &record_Type) {
+            PyErr_SetString(PyExc_TypeError, "Execute argument must be a record");
+            return NULL;
+        }
+        params = ((msiobj*)oparams)->h;
+    }
+
+    status = MsiViewExecute(view->h, params);
+    if (status != ERROR_SUCCESS)
+	return msierror(status);
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject*
+view_fetch(msiobj *view, PyObject*args)
+{
+    int status;
+    MSIHANDLE result;
+
+    if ((status = MsiViewFetch(view->h, &result)) != ERROR_SUCCESS)
+	return msierror(status);
+
+    return record_new(result);
+}
+
+static PyObject*
+view_getcolumninfo(msiobj *view, PyObject *args)
+{
+    int status;
+    int kind;
+    MSIHANDLE result;
+
+    if (!PyArg_ParseTuple(args, "i:GetColumnInfo", &kind))
+	return NULL;
+
+    if ((status = MsiViewGetColumnInfo(view->h, kind, &result)) != ERROR_SUCCESS)
+	return msierror(status);
+
+    return record_new(result);
+}
+
+static PyObject*
+view_modify(msiobj *view, PyObject *args)
+{
+    int kind;
+    PyObject *data;
+    int status;
+
+    if (!PyArg_ParseTuple(args, "iO:Modify", &kind, &data))
+	return NULL;
+
+    if (data->ob_type != &record_Type) {
+	PyErr_SetString(PyExc_TypeError, "Modify expects a record object");
+	return NULL;
+    }
+
+    if ((status = MsiViewModify(view->h, kind, ((msiobj*)data)->h)) != ERROR_SUCCESS)
+	return msierror(status);
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject*
+view_close(msiobj *view, PyObject*args)
+{
+    int status;
+
+    if ((status = MsiViewClose(view->h)) != ERROR_SUCCESS)
+	return msierror(status);
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyMethodDef view_methods[] = {
+    { "Execute", (PyCFunction)view_execute, METH_VARARGS, 
+	PyDoc_STR("Execute(params=None) -> None\nWraps MsiViewExecute")},
+    { "GetColumnInfo", (PyCFunction)view_getcolumninfo, METH_VARARGS,
+	PyDoc_STR("GetColumnInfo() -> result\nWraps MsiGetColumnInfo")},
+    { "Fetch", (PyCFunction)view_fetch, METH_NOARGS,
+	PyDoc_STR("Fetch() -> result\nWraps MsiViewFetch")},
+    { "Modify", (PyCFunction)view_modify, METH_VARARGS,
+	PyDoc_STR("Modify(mode,record) -> None\nWraps MsiViewModify")},
+    { "Close", (PyCFunction)view_close, METH_NOARGS,
+	PyDoc_STR("Close() -> result\nWraps MsiViewClose")},
+    { NULL, NULL }
+};
+
+static PyTypeObject msiview_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0,			/*ob_size*/
+	"_msi.View",		/*tp_name*/
+	sizeof(msiobj),	/*tp_basicsize*/
+	0,			/*tp_itemsize*/
+	/* methods */
+	(destructor)msiobj_dealloc, /*tp_dealloc*/
+	0,			/*tp_print*/
+	0,			/*tp_getattr*/
+	0,			/*tp_setattr*/
+	0,			/*tp_compare*/
+	0,			/*tp_repr*/
+	0,			/*tp_as_number*/
+	0,			/*tp_as_sequence*/
+	0,			/*tp_as_mapping*/
+	0,			/*tp_hash*/
+        0,                      /*tp_call*/
+        0,                      /*tp_str*/
+        PyObject_GenericGetAttr,/*tp_getattro*/
+        PyObject_GenericSetAttr,/*tp_setattro*/
+        0,                      /*tp_as_buffer*/
+        Py_TPFLAGS_DEFAULT,     /*tp_flags*/
+        0,                      /*tp_doc*/
+        0,                      /*tp_traverse*/
+        0,                      /*tp_clear*/
+        0,                      /*tp_richcompare*/
+        0,                      /*tp_weaklistoffset*/
+        0,                      /*tp_iter*/
+        0,                      /*tp_iternext*/
+        view_methods,           /*tp_methods*/
+        0,                      /*tp_members*/
+        0,                      /*tp_getset*/
+        0,                      /*tp_base*/
+        0,                      /*tp_dict*/
+        0,                      /*tp_descr_get*/
+        0,                      /*tp_descr_set*/
+        0,                      /*tp_dictoffset*/
+        0,                      /*tp_init*/
+        0,                      /*tp_alloc*/
+        0,                      /*tp_new*/
+        0,                      /*tp_free*/
+        0,                      /*tp_is_gc*/
+};
+
+/*************************** Database objects **************/
+
+static PyObject*
+msidb_openview(msiobj *msidb, PyObject *args)
+{
+    int status;
+    char *sql;
+    MSIHANDLE hView;
+    msiobj *result;
+
+    if (!PyArg_ParseTuple(args, "s:OpenView", &sql))
+	return NULL;
+
+    if ((status = MsiDatabaseOpenView(msidb->h, sql, &hView)) != ERROR_SUCCESS)
+	return msierror(status);
+
+    result = PyObject_NEW(struct msiobj, &msiview_Type);
+    if (!result) {
+	MsiCloseHandle(hView);
+	return NULL;
+    }
+
+    result->h = hView;
+    return (PyObject*)result;
+}
+
+static PyObject*
+msidb_commit(msiobj *msidb, PyObject *args)
+{
+    int status;
+
+    if ((status = MsiDatabaseCommit(msidb->h)) != ERROR_SUCCESS)
+	return msierror(status);
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject*
+msidb_getsummaryinformation(msiobj *db, PyObject *args)
+{
+    int status;
+    int count;
+    MSIHANDLE result;
+    msiobj *oresult;
+
+    if (!PyArg_ParseTuple(args, "i:GetSummaryInformation", &count))
+	return NULL;
+
+    status = MsiGetSummaryInformation(db->h, NULL, count, &result);
+    if (status != ERROR_SUCCESS)
+	return msierror(status);
+
+    oresult = PyObject_NEW(struct msiobj, &summary_Type);
+    if (!result) {
+	MsiCloseHandle(result);
+	return NULL;
+    }
+
+    oresult->h = result;
+    return (PyObject*)oresult;
+}
+
+static PyMethodDef db_methods[] = {
+    { "OpenView", (PyCFunction)msidb_openview, METH_VARARGS, 
+	PyDoc_STR("OpenView(sql) -> viewobj\nWraps MsiDatabaseOpenView")},
+    { "Commit", (PyCFunction)msidb_commit, METH_NOARGS,
+	PyDoc_STR("Commit() -> None\nWraps MsiDatabaseCommit")},
+    { "GetSummaryInformation", (PyCFunction)msidb_getsummaryinformation, METH_VARARGS, 
+	PyDoc_STR("GetSummaryInformation(updateCount) -> viewobj\nWraps MsiGetSummaryInformation")},
+    { NULL, NULL }
+};
+
+static PyTypeObject msidb_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0,			/*ob_size*/
+	"_msi.Database",		/*tp_name*/
+	sizeof(msiobj),	/*tp_basicsize*/
+	0,			/*tp_itemsize*/
+	/* methods */
+	(destructor)msiobj_dealloc, /*tp_dealloc*/
+	0,			/*tp_print*/
+	0,			/*tp_getattr*/
+	0,			/*tp_setattr*/
+	0,			/*tp_compare*/
+	0,			/*tp_repr*/
+	0,			/*tp_as_number*/
+	0,			/*tp_as_sequence*/
+	0,			/*tp_as_mapping*/
+	0,			/*tp_hash*/
+        0,                      /*tp_call*/
+        0,                      /*tp_str*/
+        PyObject_GenericGetAttr,/*tp_getattro*/
+        PyObject_GenericSetAttr,/*tp_setattro*/
+        0,                      /*tp_as_buffer*/
+        Py_TPFLAGS_DEFAULT,     /*tp_flags*/
+        0,                      /*tp_doc*/
+        0,                      /*tp_traverse*/
+        0,                      /*tp_clear*/
+        0,                      /*tp_richcompare*/
+        0,                      /*tp_weaklistoffset*/
+        0,                      /*tp_iter*/
+        0,                      /*tp_iternext*/
+        db_methods,             /*tp_methods*/
+        0,                      /*tp_members*/
+        0,                      /*tp_getset*/
+        0,                      /*tp_base*/
+        0,                      /*tp_dict*/
+        0,                      /*tp_descr_get*/
+        0,                      /*tp_descr_set*/
+        0,                      /*tp_dictoffset*/
+        0,                      /*tp_init*/
+        0,                      /*tp_alloc*/
+        0,                      /*tp_new*/
+        0,                      /*tp_free*/
+        0,                      /*tp_is_gc*/
+};
+
+static PyObject* msiopendb(PyObject *obj, PyObject *args)
+{
+    int status;
+    char *path;
+    int persist;
+    MSIHANDLE h;
+    msiobj *result;
+    
+    if (!PyArg_ParseTuple(args, "si:MSIOpenDatabase", &path, &persist))
+	return NULL;
+
+	status = MsiOpenDatabase(path, (LPCSTR)persist, &h);
+    if (status != ERROR_SUCCESS)
+	return msierror(status);
+
+    result = PyObject_NEW(struct msiobj, &msidb_Type);
+    if (!result) {
+	MsiCloseHandle(h);
+	return NULL;
+    }
+    result->h = h;
+    return (PyObject*)result;
+}
+
+static PyObject*
+createrecord(PyObject *o, PyObject *args)
+{
+    int count;
+    MSIHANDLE h;
+
+    if (!PyArg_ParseTuple(args, "i:CreateRecord", &count))
+	return NULL;
+    
+    h = MsiCreateRecord(count);
+    if (h == 0)
+	return msierror(0);
+
+    return record_new(h);
+}
+
+
+static PyMethodDef msi_methods[] = {
+        {"UuidCreate", (PyCFunction)uuidcreate, METH_NOARGS,
+		PyDoc_STR("UuidCreate() -> string")},
+	{"FCICreate",	(PyCFunction)fcicreate,	METH_VARARGS,
+		PyDoc_STR("fcicreate(cabname,files) -> None")},
+	{"OpenDatabase", (PyCFunction)msiopendb, METH_VARARGS,
+	PyDoc_STR("OpenDatabase(name, flags) -> dbobj\nWraps MsiOpenDatabase")},
+	{"CreateRecord", (PyCFunction)createrecord, METH_VARARGS,
+	PyDoc_STR("OpenDatabase(name, flags) -> dbobj\nWraps MsiCreateRecord")},
+	{NULL,		NULL}		/* sentinel */
+};
+
+static char msi_doc[] = "Documentation";
+
+PyMODINIT_FUNC
+init_msi(void)
+{
+    PyObject *m;
+
+    m = Py_InitModule3("_msi", msi_methods, msi_doc);
+    if (m == NULL)
+	return;
+
+    PyModule_AddIntConstant(m, "MSIDBOPEN_CREATEDIRECT", (int)MSIDBOPEN_CREATEDIRECT);
+    PyModule_AddIntConstant(m, "MSIDBOPEN_CREATE", (int)MSIDBOPEN_CREATE);
+    PyModule_AddIntConstant(m, "MSIDBOPEN_DIRECT", (int)MSIDBOPEN_DIRECT);
+    PyModule_AddIntConstant(m, "MSIDBOPEN_READONLY", (int)MSIDBOPEN_READONLY);
+    PyModule_AddIntConstant(m, "MSIDBOPEN_TRANSACT", (int)MSIDBOPEN_TRANSACT);
+    PyModule_AddIntConstant(m, "MSIDBOPEN_PATCHFILE", (int)MSIDBOPEN_PATCHFILE);
+
+    PyModule_AddIntConstant(m, "MSICOLINFO_NAMES", MSICOLINFO_NAMES);
+    PyModule_AddIntConstant(m, "MSICOLINFO_TYPES", MSICOLINFO_TYPES);
+
+    PyModule_AddIntConstant(m, "MSIMODIFY_SEEK", MSIMODIFY_SEEK);
+    PyModule_AddIntConstant(m, "MSIMODIFY_REFRESH", MSIMODIFY_REFRESH);
+    PyModule_AddIntConstant(m, "MSIMODIFY_INSERT", MSIMODIFY_INSERT);
+    PyModule_AddIntConstant(m, "MSIMODIFY_UPDATE", MSIMODIFY_UPDATE);
+    PyModule_AddIntConstant(m, "MSIMODIFY_ASSIGN", MSIMODIFY_ASSIGN);
+    PyModule_AddIntConstant(m, "MSIMODIFY_REPLACE", MSIMODIFY_REPLACE);
+    PyModule_AddIntConstant(m, "MSIMODIFY_MERGE", MSIMODIFY_MERGE);
+    PyModule_AddIntConstant(m, "MSIMODIFY_DELETE", MSIMODIFY_DELETE);
+    PyModule_AddIntConstant(m, "MSIMODIFY_INSERT_TEMPORARY", MSIMODIFY_INSERT_TEMPORARY);
+    PyModule_AddIntConstant(m, "MSIMODIFY_VALIDATE", MSIMODIFY_VALIDATE);
+    PyModule_AddIntConstant(m, "MSIMODIFY_VALIDATE_NEW", MSIMODIFY_VALIDATE_NEW);
+    PyModule_AddIntConstant(m, "MSIMODIFY_VALIDATE_FIELD", MSIMODIFY_VALIDATE_FIELD);
+    PyModule_AddIntConstant(m, "MSIMODIFY_VALIDATE_DELETE", MSIMODIFY_VALIDATE_DELETE);
+
+    PyModule_AddIntConstant(m, "PID_CODEPAGE", PID_CODEPAGE);
+    PyModule_AddIntConstant(m, "PID_TITLE", PID_TITLE);
+    PyModule_AddIntConstant(m, "PID_SUBJECT", PID_SUBJECT);
+    PyModule_AddIntConstant(m, "PID_AUTHOR", PID_AUTHOR);
+    PyModule_AddIntConstant(m, "PID_KEYWORDS", PID_KEYWORDS);
+    PyModule_AddIntConstant(m, "PID_COMMENTS", PID_COMMENTS);
+    PyModule_AddIntConstant(m, "PID_TEMPLATE", PID_TEMPLATE);
+    PyModule_AddIntConstant(m, "PID_LASTAUTHOR", PID_LASTAUTHOR);
+    PyModule_AddIntConstant(m, "PID_REVNUMBER", PID_REVNUMBER);
+    PyModule_AddIntConstant(m, "PID_LASTPRINTED", PID_LASTPRINTED);
+    PyModule_AddIntConstant(m, "PID_CREATE_DTM", PID_CREATE_DTM);
+    PyModule_AddIntConstant(m, "PID_LASTSAVE_DTM", PID_LASTSAVE_DTM);
+    PyModule_AddIntConstant(m, "PID_PAGECOUNT", PID_PAGECOUNT);
+    PyModule_AddIntConstant(m, "PID_WORDCOUNT", PID_WORDCOUNT);
+    PyModule_AddIntConstant(m, "PID_CHARCOUNT", PID_CHARCOUNT);
+    PyModule_AddIntConstant(m, "PID_APPNAME", PID_APPNAME);
+    PyModule_AddIntConstant(m, "PID_SECURITY", PID_SECURITY);
+
+    MSIError = PyErr_NewException ("_msi.MSIError", NULL, NULL);
+    if (!MSIError)
+	return;
+    PyModule_AddObject(m, "MSIError", MSIError);
+}

Added: vendor/Python/current/PC/_subprocess.c
===================================================================
--- vendor/Python/current/PC/_subprocess.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/_subprocess.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,578 @@
+/*
+ * support routines for subprocess module
+ *
+ * Currently, this extension module is only required when using the
+ * subprocess module on Windows, but in the future, stubs for other
+ * platforms might be added here as well.
+ *
+ * Copyright (c) 2004 by Fredrik Lundh <fredrik at pythonware.com>
+ * Copyright (c) 2004 by Secret Labs AB, http://www.pythonware.com
+ * Copyright (c) 2004 by Peter Astrand <astrand at lysator.liu.se>
+ *
+ * By obtaining, using, and/or copying this software and/or its
+ * associated documentation, you agree that you have read, understood,
+ * and will comply with the following terms and conditions:
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its associated documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice appears in
+ * all copies, and that both that copyright notice and this permission
+ * notice appear in supporting documentation, and that the name of the
+ * authors not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission.
+ *
+ * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+/* Licensed to PSF under a Contributor Agreement. */
+/* See http://www.python.org/2.4/license for licensing details. */
+
+/* TODO: handle unicode command lines? */
+/* TODO: handle unicode environment? */
+
+#include "Python.h"
+
+#define WINDOWS_LEAN_AND_MEAN
+#include "windows.h"
+
+/* -------------------------------------------------------------------- */
+/* handle wrapper.  note that this library uses integers when passing
+   handles to a function, and handle wrappers when returning handles.
+   the wrapper is used to provide Detach and Close methods */
+
+typedef struct {
+	PyObject_HEAD
+	HANDLE handle;
+} sp_handle_object;
+
+staticforward PyTypeObject sp_handle_type;
+
+static PyObject*
+sp_handle_new(HANDLE handle)
+{
+	sp_handle_object* self;
+
+	self = PyObject_NEW(sp_handle_object, &sp_handle_type);
+	if (self == NULL)
+		return NULL;
+
+	self->handle = handle;
+
+	return (PyObject*) self;
+}
+
+static PyObject*
+sp_handle_detach(sp_handle_object* self, PyObject* args)
+{
+	HANDLE handle;
+
+	if (! PyArg_ParseTuple(args, ":Detach"))
+		return NULL;
+
+	handle = self->handle;
+
+	self->handle = NULL;
+
+	/* note: return the current handle, as an integer */
+	return PyInt_FromLong((long) handle);
+}
+
+static PyObject*
+sp_handle_close(sp_handle_object* self, PyObject* args)
+{
+	if (! PyArg_ParseTuple(args, ":Close"))
+		return NULL;
+
+	if (self->handle != INVALID_HANDLE_VALUE) {
+		CloseHandle(self->handle);
+		self->handle = INVALID_HANDLE_VALUE;
+	}
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static void
+sp_handle_dealloc(sp_handle_object* self)
+{
+	if (self->handle != INVALID_HANDLE_VALUE)
+		CloseHandle(self->handle);
+	PyObject_FREE(self);
+}
+
+static PyMethodDef sp_handle_methods[] = {
+	{"Detach", (PyCFunction) sp_handle_detach, METH_VARARGS},
+	{"Close",  (PyCFunction) sp_handle_close,  METH_VARARGS},
+	{NULL, NULL}
+};
+
+static PyObject*
+sp_handle_getattr(sp_handle_object* self, char* name)
+{
+	return Py_FindMethod(sp_handle_methods, (PyObject*) self, name);
+}
+
+static PyObject*
+sp_handle_as_int(sp_handle_object* self)
+{
+	return PyInt_FromLong((long) self->handle);
+}
+
+static PyNumberMethods sp_handle_as_number;
+
+statichere PyTypeObject sp_handle_type = {
+	PyObject_HEAD_INIT(NULL)
+	0,				/*ob_size*/
+	"_subprocess_handle", sizeof(sp_handle_object), 0,
+	(destructor) sp_handle_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc) sp_handle_getattr,/*tp_getattr*/
+	0,				/*tp_setattr*/
+	0,				/*tp_compare*/
+	0,				/*tp_repr*/
+	&sp_handle_as_number,		/*tp_as_number */
+	0,				/*tp_as_sequence */
+	0,				/*tp_as_mapping */
+	0				/*tp_hash*/
+};
+
+/* -------------------------------------------------------------------- */
+/* windows API functions */
+
+static PyObject *
+sp_GetStdHandle(PyObject* self, PyObject* args)
+{
+	HANDLE handle;
+	int std_handle;
+
+	if (! PyArg_ParseTuple(args, "i:GetStdHandle", &std_handle))
+		return NULL;
+
+	Py_BEGIN_ALLOW_THREADS
+	handle = GetStdHandle((DWORD) std_handle);
+	Py_END_ALLOW_THREADS
+
+	if (handle == INVALID_HANDLE_VALUE)
+		return PyErr_SetFromWindowsErr(GetLastError());
+
+	if (! handle) {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+
+	/* note: returns integer, not handle object */
+	return PyInt_FromLong((long) handle);
+}
+
+static PyObject *
+sp_GetCurrentProcess(PyObject* self, PyObject* args)
+{
+	if (! PyArg_ParseTuple(args, ":GetCurrentProcess"))
+		return NULL;
+
+	return sp_handle_new(GetCurrentProcess());
+}
+
+static PyObject *
+sp_DuplicateHandle(PyObject* self, PyObject* args)
+{
+	HANDLE target_handle;
+	BOOL result;
+
+	long source_process_handle;
+	long source_handle;
+	long target_process_handle;
+	int desired_access;
+	int inherit_handle;
+	int options = 0;
+
+	if (! PyArg_ParseTuple(args, "lllii|i:DuplicateHandle",
+	                       &source_process_handle,
+	                       &source_handle,
+	                       &target_process_handle,
+	                       &desired_access,
+	                       &inherit_handle,
+	                       &options))
+		return NULL;
+
+	Py_BEGIN_ALLOW_THREADS
+	result = DuplicateHandle(
+		(HANDLE) source_process_handle,
+		(HANDLE) source_handle,
+		(HANDLE) target_process_handle,
+		&target_handle,
+		desired_access,
+		inherit_handle,
+		options
+	);
+	Py_END_ALLOW_THREADS
+
+	if (! result)
+		return PyErr_SetFromWindowsErr(GetLastError());
+
+	return sp_handle_new(target_handle);
+}
+
+static PyObject *
+sp_CreatePipe(PyObject* self, PyObject* args)
+{
+	HANDLE read_pipe;
+	HANDLE write_pipe;
+	BOOL result;
+
+	PyObject* pipe_attributes; /* ignored */
+	int size;
+
+	if (! PyArg_ParseTuple(args, "Oi:CreatePipe", &pipe_attributes, &size))
+		return NULL;
+
+	Py_BEGIN_ALLOW_THREADS
+	result = CreatePipe(&read_pipe, &write_pipe, NULL, size);
+	Py_END_ALLOW_THREADS
+
+	if (! result)
+		return PyErr_SetFromWindowsErr(GetLastError());
+
+	return Py_BuildValue(
+		"NN", sp_handle_new(read_pipe), sp_handle_new(write_pipe));
+}
+
+/* helpers for createprocess */
+
+static int
+getint(PyObject* obj, char* name)
+{
+	PyObject* value;
+	int ret;
+
+	value = PyObject_GetAttrString(obj, name);
+	if (! value) {
+		PyErr_Clear(); /* FIXME: propagate error? */
+		return 0;
+	}
+	ret = (int) PyInt_AsLong(value);
+	Py_DECREF(value);
+	return ret;
+}
+
+static HANDLE
+gethandle(PyObject* obj, char* name)
+{
+	sp_handle_object* value;
+	HANDLE ret;
+
+	value = (sp_handle_object*) PyObject_GetAttrString(obj, name);
+	if (! value) {
+		PyErr_Clear(); /* FIXME: propagate error? */
+		return NULL;
+	}
+	if (value->ob_type != &sp_handle_type)
+		ret = NULL;
+	else
+		ret = value->handle;
+	Py_DECREF(value);
+	return ret;
+}
+
+static PyObject*
+getenvironment(PyObject* environment)
+{
+	int i, envsize;
+	PyObject* out = NULL;
+	PyObject* keys;
+	PyObject* values;
+	char* p;
+
+	/* convert environment dictionary to windows enviroment string */
+	if (! PyMapping_Check(environment)) {
+		PyErr_SetString(
+		    PyExc_TypeError, "environment must be dictionary or None");
+		return NULL;
+	}
+
+	envsize = PyMapping_Length(environment);
+
+	keys = PyMapping_Keys(environment);
+	values = PyMapping_Values(environment);
+	if (!keys || !values)
+		goto error;
+
+	out = PyString_FromStringAndSize(NULL, 2048);
+	if (! out)
+		goto error;
+
+	p = PyString_AS_STRING(out);
+
+	for (i = 0; i < envsize; i++) {
+		int ksize, vsize, totalsize;
+		PyObject* key = PyList_GET_ITEM(keys, i);
+		PyObject* value = PyList_GET_ITEM(values, i);
+
+		if (! PyString_Check(key) || ! PyString_Check(value)) {
+			PyErr_SetString(PyExc_TypeError,
+				"environment can only contain strings");
+			goto error;
+		}
+		ksize = PyString_GET_SIZE(key);
+		vsize = PyString_GET_SIZE(value);
+		totalsize = (p - PyString_AS_STRING(out)) + ksize + 1 +
+							     vsize + 1 + 1;
+		if (totalsize > PyString_GET_SIZE(out)) {
+			int offset = p - PyString_AS_STRING(out);
+			_PyString_Resize(&out, totalsize + 1024);
+			p = PyString_AS_STRING(out) + offset;
+		}
+		memcpy(p, PyString_AS_STRING(key), ksize);
+		p += ksize;
+		*p++ = '=';
+		memcpy(p, PyString_AS_STRING(value), vsize);
+		p += vsize;
+		*p++ = '\0';
+	}
+
+	/* add trailing null byte */
+	*p++ = '\0';
+	_PyString_Resize(&out, p - PyString_AS_STRING(out));
+
+	/* PyObject_Print(out, stdout, 0); */
+
+	Py_XDECREF(keys);
+	Py_XDECREF(values);
+
+	return out;
+
+ error:
+	Py_XDECREF(out);
+	Py_XDECREF(keys);
+	Py_XDECREF(values);
+	return NULL;
+}
+
+static PyObject *
+sp_CreateProcess(PyObject* self, PyObject* args)
+{
+	BOOL result;
+	PROCESS_INFORMATION pi;
+	STARTUPINFO si;
+	PyObject* environment;
+
+	char* application_name;
+	char* command_line;
+	PyObject* process_attributes; /* ignored */
+	PyObject* thread_attributes; /* ignored */
+	int inherit_handles;
+	int creation_flags;
+	PyObject* env_mapping;
+	char* current_directory;
+	PyObject* startup_info;
+
+	if (! PyArg_ParseTuple(args, "zzOOiiOzO:CreateProcess",
+			       &application_name,
+			       &command_line,
+			       &process_attributes,
+			       &thread_attributes,
+			       &inherit_handles,
+			       &creation_flags,
+			       &env_mapping,
+			       &current_directory,
+			       &startup_info))
+		return NULL;
+
+	ZeroMemory(&si, sizeof(si));
+	si.cb = sizeof(si);
+
+	/* note: we only support a small subset of all SI attributes */
+	si.dwFlags = getint(startup_info, "dwFlags");
+	si.wShowWindow = getint(startup_info, "wShowWindow");
+	si.hStdInput = gethandle(startup_info, "hStdInput");
+	si.hStdOutput = gethandle(startup_info, "hStdOutput");
+	si.hStdError = gethandle(startup_info, "hStdError");
+
+	if (PyErr_Occurred())
+		return NULL;
+
+	if (env_mapping == Py_None)
+		environment = NULL;
+	else {
+		environment = getenvironment(env_mapping);
+		if (! environment)
+			return NULL;
+	}
+
+	Py_BEGIN_ALLOW_THREADS
+	result = CreateProcess(application_name,
+			       command_line,
+			       NULL,
+			       NULL,
+			       inherit_handles,
+			       creation_flags,
+			       environment ? PyString_AS_STRING(environment) : NULL,
+			       current_directory,
+			       &si,
+			       &pi);
+	Py_END_ALLOW_THREADS
+
+	Py_XDECREF(environment);
+
+	if (! result)
+		return PyErr_SetFromWindowsErr(GetLastError());
+
+	return Py_BuildValue("NNii",
+			     sp_handle_new(pi.hProcess),
+			     sp_handle_new(pi.hThread),
+			     pi.dwProcessId,
+			     pi.dwThreadId);
+}
+
+static PyObject *
+sp_TerminateProcess(PyObject* self, PyObject* args)
+{
+	BOOL result;
+
+	long process;
+	int exit_code;
+	if (! PyArg_ParseTuple(args, "li:TerminateProcess", &process,
+			       &exit_code))
+		return NULL;
+
+	result = TerminateProcess((HANDLE) process, exit_code);
+
+	if (! result)
+		return PyErr_SetFromWindowsErr(GetLastError());
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+sp_GetExitCodeProcess(PyObject* self, PyObject* args)
+{
+	DWORD exit_code;
+	BOOL result;
+
+	long process;
+	if (! PyArg_ParseTuple(args, "l:GetExitCodeProcess", &process))
+		return NULL;
+
+	result = GetExitCodeProcess((HANDLE) process, &exit_code);
+
+	if (! result)
+		return PyErr_SetFromWindowsErr(GetLastError());
+
+	return PyInt_FromLong(exit_code);
+}
+
+static PyObject *
+sp_WaitForSingleObject(PyObject* self, PyObject* args)
+{
+	DWORD result;
+
+	long handle;
+	int milliseconds;
+	if (! PyArg_ParseTuple(args, "li:WaitForSingleObject",
+	                  	     &handle,
+	                  	     &milliseconds))
+		return NULL;
+
+	Py_BEGIN_ALLOW_THREADS
+	result = WaitForSingleObject((HANDLE) handle, (DWORD) milliseconds);
+	Py_END_ALLOW_THREADS
+
+	if (result == WAIT_FAILED)
+		return PyErr_SetFromWindowsErr(GetLastError());
+
+	return PyInt_FromLong((int) result);
+}
+
+static PyObject *
+sp_GetVersion(PyObject* self, PyObject* args)
+{
+	if (! PyArg_ParseTuple(args, ":GetVersion"))
+		return NULL;
+
+	return PyInt_FromLong((int) GetVersion());
+}
+
+static PyObject *
+sp_GetModuleFileName(PyObject* self, PyObject* args)
+{
+	BOOL result;
+	long module;
+	TCHAR filename[MAX_PATH];
+
+	if (! PyArg_ParseTuple(args, "l:GetModuleFileName", &module))
+		return NULL;
+
+	result = GetModuleFileName((HMODULE)module, filename, MAX_PATH);
+	filename[MAX_PATH-1] = '\0';
+
+	if (! result)
+		return PyErr_SetFromWindowsErr(GetLastError());
+
+	return PyString_FromString(filename);
+}
+
+static PyMethodDef sp_functions[] = {
+	{"GetStdHandle",	sp_GetStdHandle,	METH_VARARGS},
+	{"GetCurrentProcess",	sp_GetCurrentProcess,	METH_VARARGS},
+	{"DuplicateHandle",	sp_DuplicateHandle,	METH_VARARGS},
+	{"CreatePipe",		sp_CreatePipe,		METH_VARARGS},
+	{"CreateProcess",	sp_CreateProcess,	METH_VARARGS},
+	{"TerminateProcess",	sp_TerminateProcess,	METH_VARARGS},
+	{"GetExitCodeProcess",	sp_GetExitCodeProcess,	METH_VARARGS},
+	{"WaitForSingleObject",	sp_WaitForSingleObject, METH_VARARGS},
+	{"GetVersion",		sp_GetVersion,		METH_VARARGS},
+	{"GetModuleFileName",	sp_GetModuleFileName,	METH_VARARGS},
+	{NULL, NULL}
+};
+
+/* -------------------------------------------------------------------- */
+
+static void
+defint(PyObject* d, const char* name, int value)
+{
+	PyObject* v = PyInt_FromLong((long) value);
+	if (v) {
+		PyDict_SetItemString(d, (char*) name, v);
+		Py_DECREF(v);
+	}
+}
+
+#if PY_VERSION_HEX >= 0x02030000
+PyMODINIT_FUNC
+#else
+DL_EXPORT(void)
+#endif
+init_subprocess()
+{
+	PyObject *d;
+	PyObject *m;
+
+	/* patch up object descriptors */
+	sp_handle_type.ob_type = &PyType_Type;
+	sp_handle_as_number.nb_int = (unaryfunc) sp_handle_as_int;
+
+	m = Py_InitModule("_subprocess", sp_functions);
+	if (m == NULL)
+		return;
+	d = PyModule_GetDict(m);
+
+	/* constants */
+	defint(d, "STD_INPUT_HANDLE", STD_INPUT_HANDLE);
+	defint(d, "STD_OUTPUT_HANDLE", STD_OUTPUT_HANDLE);
+	defint(d, "STD_ERROR_HANDLE", STD_ERROR_HANDLE);
+	defint(d, "DUPLICATE_SAME_ACCESS", DUPLICATE_SAME_ACCESS);
+	defint(d, "STARTF_USESTDHANDLES", STARTF_USESTDHANDLES);
+	defint(d, "STARTF_USESHOWWINDOW", STARTF_USESHOWWINDOW);
+	defint(d, "SW_HIDE", SW_HIDE);
+	defint(d, "INFINITE", INFINITE);
+	defint(d, "WAIT_OBJECT_0", WAIT_OBJECT_0);
+	defint(d, "CREATE_NEW_CONSOLE", CREATE_NEW_CONSOLE);
+}

Added: vendor/Python/current/PC/_winreg.c
===================================================================
--- vendor/Python/current/PC/_winreg.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/_winreg.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1521 @@
+/*
+  _winreg.c
+
+  Windows Registry access module for Python.
+
+  * Simple registry access written by Mark Hammond in win32api
+	module circa 1995.
+  * Bill Tutt expanded the support significantly not long after.
+  * Numerous other people have submitted patches since then.
+  * Ripped from win32api module 03-Feb-2000 by Mark Hammond, and
+    basic Unicode support added.
+
+*/
+
+#include "windows.h"
+#include "Python.h"
+#include "structmember.h"
+#include "malloc.h" /* for alloca */
+
+static BOOL PyHKEY_AsHKEY(PyObject *ob, HKEY *pRes, BOOL bNoneOK);
+static PyObject *PyHKEY_FromHKEY(HKEY h);
+static BOOL PyHKEY_Close(PyObject *obHandle);
+
+static char errNotAHandle[] = "Object is not a handle";
+
+/* The win32api module reports the function name that failed,
+   but this concept is not in the Python core.
+   Hopefully it will one day, and in the meantime I dont
+   want to lose this info...
+*/
+#define PyErr_SetFromWindowsErrWithFunction(rc, fnname) \
+	PyErr_SetFromWindowsErr(rc)
+
+/* Forward declares */
+
+/* Doc strings */
+PyDoc_STRVAR(module_doc,
+"This module provides access to the Windows registry API.\n"
+"\n"
+"Functions:\n"
+"\n"
+"CloseKey() - Closes a registry key.\n"
+"ConnectRegistry() - Establishes a connection to a predefined registry handle\n"
+"                    on another computer.\n"
+"CreateKey() - Creates the specified key, or opens it if it already exists.\n"
+"DeleteKey() - Deletes the specified key.\n"
+"DeleteValue() - Removes a named value from the specified registry key.\n"
+"EnumKey() - Enumerates subkeys of the specified open registry key.\n"
+"EnumValue() - Enumerates values of the specified open registry key.\n"
+"FlushKey() - Writes all the attributes of the specified key to the registry.\n"
+"LoadKey() - Creates a subkey under HKEY_USER or HKEY_LOCAL_MACHINE and stores\n"
+"            registration information from a specified file into that subkey.\n"
+"OpenKey() - Alias for <om win32api.RegOpenKeyEx>\n"
+"OpenKeyEx() - Opens the specified key.\n"
+"QueryValue() - Retrieves the value associated with the unnamed value for a\n"
+"               specified key in the registry.\n"
+"QueryValueEx() - Retrieves the type and data for a specified value name\n"
+"                 associated with an open registry key.\n"
+"QueryInfoKey() - Returns information about the specified key.\n"
+"SaveKey() - Saves the specified key, and all its subkeys a file.\n"
+"SetValue() - Associates a value with a specified key.\n"
+"SetValueEx() - Stores data in the value field of an open registry key.\n"
+"\n"
+"Special objects:\n"
+"\n"
+"HKEYType -- type object for HKEY objects\n"
+"error -- exception raised for Win32 errors\n"
+"\n"
+"Integer constants:\n"
+"Many constants are defined - see the documentation for each function\n"
+"to see what constants are used, and where.");
+
+
+PyDoc_STRVAR(CloseKey_doc,
+"CloseKey(hkey) - Closes a previously opened registry key.\n"
+"\n"
+"The hkey argument specifies a previously opened key.\n"
+"\n"
+"Note that if the key is not closed using this method, it will be\n"
+"closed when the hkey object is destroyed by Python.");
+
+PyDoc_STRVAR(ConnectRegistry_doc,
+"key = ConnectRegistry(computer_name, key) - "
+"Establishes a connection to a predefined registry handle on another computer.\n"
+"\n"
+"computer_name is the name of the remote computer, of the form \\\\computername.\n"
+" If None, the local computer is used.\n"
+"key is the predefined handle to connect to.\n"
+"\n"
+"The return value is the handle of the opened key.\n"
+"If the function fails, an EnvironmentError exception is raised.");
+
+PyDoc_STRVAR(CreateKey_doc,
+"key = CreateKey(key, sub_key) - Creates or opens the specified key.\n"
+"\n"
+"key is an already open key, or one of the predefined HKEY_* constants\n"
+"sub_key is a string that names the key this method opens or creates.\n"
+" If key is one of the predefined keys, sub_key may be None. In that case,\n"
+" the handle returned is the same key handle passed in to the function.\n"
+"\n"
+"If the key already exists, this function opens the existing key\n"
+"\n"
+"The return value is the handle of the opened key.\n"
+"If the function fails, an exception is raised.");
+
+PyDoc_STRVAR(DeleteKey_doc,
+"DeleteKey(key, sub_key) - Deletes the specified key.\n"
+"\n"
+"key is an already open key, or any one of the predefined HKEY_* constants.\n"
+"sub_key is a string that must be a subkey of the key identified by the key parameter.\n"
+" This value must not be None, and the key may not have subkeys.\n"
+"\n"
+"This method can not delete keys with subkeys.\n"
+"\n"
+"If the method succeeds, the entire key, including all of its values,\n"
+"is removed.  If the method fails, an EnvironmentError exception is raised.");
+
+PyDoc_STRVAR(DeleteValue_doc,
+"DeleteValue(key, value) - Removes a named value from a registry key.\n"
+"\n"
+"key is an already open key, or any one of the predefined HKEY_* constants.\n"
+"value is a string that identifies the value to remove.");
+
+PyDoc_STRVAR(EnumKey_doc,
+"string = EnumKey(key, index) - Enumerates subkeys of an open registry key.\n"
+"\n"
+"key is an already open key, or any one of the predefined HKEY_* constants.\n"
+"index is an integer that identifies the index of the key to retrieve.\n"
+"\n"
+"The function retrieves the name of one subkey each time it is called.\n"
+"It is typically called repeatedly until an EnvironmentError exception is\n"
+"raised, indicating no more values are available.");
+
+PyDoc_STRVAR(EnumValue_doc,
+"tuple = EnumValue(key, index) - Enumerates values of an open registry key.\n"
+"key is an already open key, or any one of the predefined HKEY_* constants.\n"
+"index is an integer that identifies the index of the value to retrieve.\n"
+"\n"
+"The function retrieves the name of one subkey each time it is called.\n"
+"It is typically called repeatedly, until an EnvironmentError exception\n"
+"is raised, indicating no more values.\n"
+"\n"
+"The result is a tuple of 3 items:\n"
+"value_name is a string that identifies the value.\n"
+"value_data is an object that holds the value data, and whose type depends\n"
+" on the underlying registry type.\n"
+"data_type is an integer that identifies the type of the value data.");
+
+PyDoc_STRVAR(FlushKey_doc,
+"FlushKey(key) - Writes all the attributes of a key to the registry.\n"
+"\n"
+"key is an already open key, or any one of the predefined HKEY_* constants.\n"
+"\n"
+"It is not necessary to call RegFlushKey to change a key.\n"
+"Registry changes are flushed to disk by the registry using its lazy flusher.\n"
+"Registry changes are also flushed to disk at system shutdown.\n"
+"Unlike CloseKey(), the FlushKey() method returns only when all the data has\n"
+"been written to the registry.\n"
+"An application should only call FlushKey() if it requires absolute certainty that registry changes are on disk.\n"
+"If you don't know whether a FlushKey() call is required, it probably isn't.");
+
+PyDoc_STRVAR(LoadKey_doc,
+"LoadKey(key, sub_key, file_name) - Creates a subkey under the specified key\n"
+"and stores registration information from a specified file into that subkey.\n"
+"\n"
+"key is an already open key, or any one of the predefined HKEY_* constants.\n"
+"sub_key is a string that identifies the sub_key to load\n"
+"file_name is the name of the file to load registry data from.\n"
+" This file must have been created with the SaveKey() function.\n"
+" Under the file allocation table (FAT) file system, the filename may not\n"
+"have an extension.\n"
+"\n"
+"A call to LoadKey() fails if the calling process does not have the\n"
+"SE_RESTORE_PRIVILEGE privilege.\n"
+"\n"
+"If key is a handle returned by ConnectRegistry(), then the path specified\n"
+"in fileName is relative to the remote computer.\n"
+"\n"
+"The docs imply key must be in the HKEY_USER or HKEY_LOCAL_MACHINE tree");
+
+PyDoc_STRVAR(OpenKey_doc,
+"key = OpenKey(key, sub_key, res = 0, sam = KEY_READ) - Opens the specified key.\n"
+"\n"
+"key is an already open key, or any one of the predefined HKEY_* constants.\n"
+"sub_key is a string that identifies the sub_key to open\n"
+"res is a reserved integer, and must be zero.  Default is zero.\n"
+"sam is an integer that specifies an access mask that describes the desired\n"
+" security access for the key.  Default is KEY_READ\n"
+"\n"
+"The result is a new handle to the specified key\n"
+"If the function fails, an EnvironmentError exception is raised.");
+
+PyDoc_STRVAR(OpenKeyEx_doc, "See OpenKey()");
+
+PyDoc_STRVAR(QueryInfoKey_doc,
+"tuple = QueryInfoKey(key) - Returns information about a key.\n"
+"\n"
+"key is an already open key, or any one of the predefined HKEY_* constants.\n"
+"\n"
+"The result is a tuple of 3 items:"
+"An integer that identifies the number of sub keys this key has.\n"
+"An integer that identifies the number of values this key has.\n"
+"A long integer that identifies when the key was last modified (if available)\n"
+" as 100's of nanoseconds since Jan 1, 1600.");
+
+PyDoc_STRVAR(QueryValue_doc,
+"string = QueryValue(key, sub_key) - retrieves the unnamed value for a key.\n"
+"\n"
+"key is an already open key, or any one of the predefined HKEY_* constants.\n"
+"sub_key is a string that holds the name of the subkey with which the value\n"
+" is associated.  If this parameter is None or empty, the function retrieves\n"
+" the value set by the SetValue() method for the key identified by key."
+"\n"
+"Values in the registry have name, type, and data components. This method\n"
+"retrieves the data for a key's first value that has a NULL name.\n"
+"But the underlying API call doesn't return the type, Lame Lame Lame, DONT USE THIS!!!");
+
+PyDoc_STRVAR(QueryValueEx_doc,
+"value,type_id = QueryValueEx(key, value_name) - Retrieves the type and data for a specified value name associated with an open registry key.\n"
+"\n"
+"key is an already open key, or any one of the predefined HKEY_* constants.\n"
+"value_name is a string indicating the value to query");
+
+PyDoc_STRVAR(SaveKey_doc,
+"SaveKey(key, file_name) - Saves the specified key, and all its subkeys to the specified file.\n"
+"\n"
+"key is an already open key, or any one of the predefined HKEY_* constants.\n"
+"file_name is the name of the file to save registry data to.\n"
+" This file cannot already exist. If this filename includes an extension,\n"
+" it cannot be used on file allocation table (FAT) file systems by the\n"
+" LoadKey(), ReplaceKey() or RestoreKey() methods.\n"
+"\n"
+"If key represents a key on a remote computer, the path described by\n"
+"file_name is relative to the remote computer.\n"
+"The caller of this method must possess the SeBackupPrivilege security privilege.\n"
+"This function passes NULL for security_attributes to the API.");
+
+PyDoc_STRVAR(SetValue_doc,
+"SetValue(key, sub_key, type, value) - Associates a value with a specified key.\n"
+"\n"
+"key is an already open key, or any one of the predefined HKEY_* constants.\n"
+"sub_key is a string that names the subkey with which the value is associated.\n"
+"type is an integer that specifies the type of the data.  Currently this\n"
+" must be REG_SZ, meaning only strings are supported.\n"
+"value is a string that specifies the new value.\n"
+"\n"
+"If the key specified by the sub_key parameter does not exist, the SetValue\n"
+"function creates it.\n"
+"\n"
+"Value lengths are limited by available memory. Long values (more than\n"
+"2048 bytes) should be stored as files with the filenames stored in \n"
+"the configuration registry.  This helps the registry perform efficiently.\n"
+"\n"
+"The key identified by the key parameter must have been opened with\n"
+"KEY_SET_VALUE access.");
+
+PyDoc_STRVAR(SetValueEx_doc,
+"SetValueEx(key, value_name, reserved, type, value) - Stores data in the value field of an open registry key.\n"
+"\n"
+"key is an already open key, or any one of the predefined HKEY_* constants.\n"
+"value_name is a string containing the name of the value to set, or None\n"
+"type is an integer that specifies the type of the data.  This should be one of:\n"
+"  REG_BINARY -- Binary data in any form.\n"
+"  REG_DWORD -- A 32-bit number.\n"
+"  REG_DWORD_LITTLE_ENDIAN -- A 32-bit number in little-endian format.\n"
+"  REG_DWORD_BIG_ENDIAN -- A 32-bit number in big-endian format.\n"
+"  REG_EXPAND_SZ -- A null-terminated string that contains unexpanded references\n"
+"                   to environment variables (for example, %PATH%).\n"
+"  REG_LINK -- A Unicode symbolic link.\n"
+"  REG_MULTI_SZ -- An sequence of null-terminated strings, terminated by\n"
+"                  two null characters.  Note that Python handles this\n"
+"                  termination automatically.\n"
+"  REG_NONE -- No defined value type.\n"
+"  REG_RESOURCE_LIST -- A device-driver resource list.\n"
+"  REG_SZ -- A null-terminated string.\n"
+"reserved can be anything - zero is always passed to the API.\n"
+"value is a string that specifies the new value.\n"
+"\n"
+"This method can also set additional value and type information for the\n"
+"specified key.  The key identified by the key parameter must have been\n"
+"opened with KEY_SET_VALUE access.\n"
+"\n"
+"To open the key, use the CreateKeyEx() or OpenKeyEx() methods.\n"
+"\n"
+"Value lengths are limited by available memory. Long values (more than\n"
+"2048 bytes) should be stored as files with the filenames stored in \n"
+"the configuration registry.  This helps the registry perform efficiently.");
+
+/* PyHKEY docstrings */
+PyDoc_STRVAR(PyHKEY_doc,
+"PyHKEY Object - A Python object, representing a win32 registry key.\n"
+"\n"
+"This object wraps a Windows HKEY object, automatically closing it when\n"
+"the object is destroyed.  To guarantee cleanup, you can call either\n"
+"the Close() method on the PyHKEY, or the CloseKey() method.\n"
+"\n"
+"All functions which accept a handle object also accept an integer - \n"
+"however, use of the handle object is encouraged.\n"
+"\n"
+"Functions:\n"
+"Close() - Closes the underlying handle.\n"
+"Detach() - Returns the integer Win32 handle, detaching it from the object\n"
+"\n"
+"Properties:\n"
+"handle - The integer Win32 handle.\n"
+"\n"
+"Operations:\n"
+"__nonzero__ - Handles with an open object return true, otherwise false.\n"
+"__int__ - Converting a handle to an integer returns the Win32 handle.\n"
+"__cmp__ - Handle objects are compared using the handle value.");
+
+
+PyDoc_STRVAR(PyHKEY_Close_doc,
+"key.Close() - Closes the underlying Windows handle.\n"
+"\n"
+"If the handle is already closed, no error is raised.");
+
+PyDoc_STRVAR(PyHKEY_Detach_doc,
+"int = key.Detach() - Detaches the Windows handle from the handle object.\n"
+"\n"
+"The result is the value of the handle before it is detached.  If the\n"
+"handle is already detached, this will return zero.\n"
+"\n"
+"After calling this function, the handle is effectively invalidated,\n"
+"but the handle is not closed.  You would call this function when you\n"
+"need the underlying win32 handle to exist beyond the lifetime of the\n"
+"handle object.\n"
+"On 64 bit windows, the result of this function is a long integer");
+
+
+/************************************************************************
+
+  The PyHKEY object definition
+
+************************************************************************/
+typedef struct {
+	PyObject_VAR_HEAD
+	HKEY hkey;
+} PyHKEYObject;
+
+#define PyHKEY_Check(op) ((op)->ob_type == &PyHKEY_Type)
+
+static char *failMsg = "bad operand type";
+
+static PyObject *
+PyHKEY_unaryFailureFunc(PyObject *ob)
+{
+	PyErr_SetString(PyExc_TypeError, failMsg);
+	return NULL;
+}
+static PyObject *
+PyHKEY_binaryFailureFunc(PyObject *ob1, PyObject *ob2)
+{
+	PyErr_SetString(PyExc_TypeError, failMsg);
+	return NULL;
+}
+static PyObject *
+PyHKEY_ternaryFailureFunc(PyObject *ob1, PyObject *ob2, PyObject *ob3)
+{
+	PyErr_SetString(PyExc_TypeError, failMsg);
+	return NULL;
+}
+
+static void
+PyHKEY_deallocFunc(PyObject *ob)
+{
+	/* Can not call PyHKEY_Close, as the ob->tp_type
+	   has already been cleared, thus causing the type
+	   check to fail!
+	*/
+	PyHKEYObject *obkey = (PyHKEYObject *)ob;
+	if (obkey->hkey)
+		RegCloseKey((HKEY)obkey->hkey);
+	PyObject_DEL(ob);
+}
+
+static int
+PyHKEY_nonzeroFunc(PyObject *ob)
+{
+	return ((PyHKEYObject *)ob)->hkey != 0;
+}
+
+static PyObject *
+PyHKEY_intFunc(PyObject *ob)
+{
+	PyHKEYObject *pyhkey = (PyHKEYObject *)ob;
+	return PyLong_FromVoidPtr(pyhkey->hkey);
+}
+
+static int
+PyHKEY_printFunc(PyObject *ob, FILE *fp, int flags)
+{
+	PyHKEYObject *pyhkey = (PyHKEYObject *)ob;
+	char resBuf[160];
+	wsprintf(resBuf, "<PyHKEY at %p (%p)>",
+		 ob, pyhkey->hkey);
+	fputs(resBuf, fp);
+	return 0;
+}
+
+static PyObject *
+PyHKEY_strFunc(PyObject *ob)
+{
+	PyHKEYObject *pyhkey = (PyHKEYObject *)ob;
+	char resBuf[160];
+	wsprintf(resBuf, "<PyHKEY:%p>", pyhkey->hkey);
+	return PyString_FromString(resBuf);
+}
+
+static int
+PyHKEY_compareFunc(PyObject *ob1, PyObject *ob2)
+{
+	PyHKEYObject *pyhkey1 = (PyHKEYObject *)ob1;
+	PyHKEYObject *pyhkey2 = (PyHKEYObject *)ob2;
+	return pyhkey1 == pyhkey2 ? 0 :
+		 (pyhkey1 < pyhkey2 ? -1 : 1);
+}
+
+static long
+PyHKEY_hashFunc(PyObject *ob)
+{
+	/* Just use the address.
+	   XXX - should we use the handle value?
+	*/
+	return _Py_HashPointer(ob);
+}
+
+
+static PyNumberMethods PyHKEY_NumberMethods =
+{
+	PyHKEY_binaryFailureFunc,	/* nb_add */
+	PyHKEY_binaryFailureFunc,	/* nb_subtract */
+	PyHKEY_binaryFailureFunc,	/* nb_multiply */
+	PyHKEY_binaryFailureFunc,	/* nb_divide */
+	PyHKEY_binaryFailureFunc,	/* nb_remainder */
+	PyHKEY_binaryFailureFunc,	/* nb_divmod */
+	PyHKEY_ternaryFailureFunc,	/* nb_power */
+	PyHKEY_unaryFailureFunc,	/* nb_negative */
+	PyHKEY_unaryFailureFunc,	/* nb_positive */
+	PyHKEY_unaryFailureFunc,	/* nb_absolute */
+	PyHKEY_nonzeroFunc,		/* nb_nonzero */
+	PyHKEY_unaryFailureFunc,	/* nb_invert */
+	PyHKEY_binaryFailureFunc,	/* nb_lshift */
+	PyHKEY_binaryFailureFunc,	/* nb_rshift */
+	PyHKEY_binaryFailureFunc,	/* nb_and */
+	PyHKEY_binaryFailureFunc,	/* nb_xor */
+	PyHKEY_binaryFailureFunc,	/* nb_or */
+	0,		/* nb_coerce (allowed to be zero) */
+	PyHKEY_intFunc,			/* nb_int */
+	PyHKEY_unaryFailureFunc,	/* nb_long */
+	PyHKEY_unaryFailureFunc,	/* nb_float */
+	PyHKEY_unaryFailureFunc,	/* nb_oct */
+	PyHKEY_unaryFailureFunc,	/* nb_hex */
+};
+
+
+/* fwd declare __getattr__ */
+static PyObject *PyHKEY_getattr(PyObject *self, const char *name);
+
+/* The type itself */
+PyTypeObject PyHKEY_Type =
+{
+	PyObject_HEAD_INIT(0) /* fill in type at module init */
+	0,
+	"PyHKEY",
+	sizeof(PyHKEYObject),
+	0,
+	PyHKEY_deallocFunc,		/* tp_dealloc */
+	PyHKEY_printFunc,		/* tp_print */
+	PyHKEY_getattr,			/* tp_getattr */
+	0,				/* tp_setattr */
+	PyHKEY_compareFunc,		/* tp_compare */
+	0,				/* tp_repr */
+	&PyHKEY_NumberMethods,		/* tp_as_number */
+	0,				/* tp_as_sequence */
+	0,				/* tp_as_mapping */
+	PyHKEY_hashFunc,		/* tp_hash */
+	0,				/* tp_call */
+	PyHKEY_strFunc,			/* tp_str */
+	0,				/* tp_getattro */
+	0,				/* tp_setattro */
+	0,				/* tp_as_buffer */
+	0,				/* tp_flags */
+	PyHKEY_doc,			/* tp_doc */
+};
+
+#define OFF(e) offsetof(PyHKEYObject, e)
+
+static struct memberlist PyHKEY_memberlist[] = {
+	{"handle",      T_INT,      OFF(hkey)},
+	{NULL}    /* Sentinel */
+};
+
+/************************************************************************
+
+  The PyHKEY object methods
+
+************************************************************************/
+static PyObject *
+PyHKEY_CloseMethod(PyObject *self, PyObject *args)
+{
+	if (!PyArg_ParseTuple(args, ":Close"))
+		return NULL;
+	if (!PyHKEY_Close(self))
+		return NULL;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+PyHKEY_DetachMethod(PyObject *self, PyObject *args)
+{
+	void* ret;
+	PyHKEYObject *pThis = (PyHKEYObject *)self;
+	if (!PyArg_ParseTuple(args, ":Detach"))
+		return NULL;
+	ret = (void*)pThis->hkey;
+	pThis->hkey = 0;
+	return PyLong_FromVoidPtr(ret);
+}
+
+static struct PyMethodDef PyHKEY_methods[] = {
+	{"Close",  PyHKEY_CloseMethod, METH_VARARGS, PyHKEY_Close_doc},
+	{"Detach", PyHKEY_DetachMethod, METH_VARARGS, PyHKEY_Detach_doc},
+	{NULL}
+};
+
+/*static*/ PyObject *
+PyHKEY_getattr(PyObject *self, const char *name)
+{
+	PyObject *res;
+
+	res = Py_FindMethod(PyHKEY_methods, self, name);
+	if (res != NULL)
+		return res;
+	PyErr_Clear();
+	if (strcmp(name, "handle") == 0)
+		return PyLong_FromVoidPtr(((PyHKEYObject *)self)->hkey);
+	return PyMember_Get((char *)self, PyHKEY_memberlist, name);
+}
+
+/************************************************************************
+   The public PyHKEY API (well, not public yet :-)
+************************************************************************/
+PyObject *
+PyHKEY_New(HKEY hInit)
+{
+	PyHKEYObject *key = PyObject_NEW(PyHKEYObject, &PyHKEY_Type);
+	if (key)
+		key->hkey = hInit;
+	return (PyObject *)key;
+}
+
+BOOL
+PyHKEY_Close(PyObject *ob_handle)
+{
+	LONG rc;
+	PyHKEYObject *key;
+
+	if (!PyHKEY_Check(ob_handle)) {
+		PyErr_SetString(PyExc_TypeError, "bad operand type");
+		return FALSE;
+	}
+	key = (PyHKEYObject *)ob_handle;
+	rc = key->hkey ? RegCloseKey((HKEY)key->hkey) : ERROR_SUCCESS;
+	key->hkey = 0;
+	if (rc != ERROR_SUCCESS)
+		PyErr_SetFromWindowsErrWithFunction(rc, "RegCloseKey");
+	return rc == ERROR_SUCCESS;
+}
+
+BOOL
+PyHKEY_AsHKEY(PyObject *ob, HKEY *pHANDLE, BOOL bNoneOK)
+{
+	if (ob == Py_None) {
+		if (!bNoneOK) {
+			PyErr_SetString(
+				  PyExc_TypeError,
+				  "None is not a valid HKEY in this context");
+			return FALSE;
+		}
+		*pHANDLE = (HKEY)0;
+	}
+	else if (PyHKEY_Check(ob)) {
+		PyHKEYObject *pH = (PyHKEYObject *)ob;
+		*pHANDLE = pH->hkey;
+	}
+	else if (PyInt_Check(ob) || PyLong_Check(ob)) {
+		/* We also support integers */
+		PyErr_Clear();
+		*pHANDLE = (HKEY)PyLong_AsVoidPtr(ob);
+		if (PyErr_Occurred())
+			return FALSE;
+	}
+	else {
+		PyErr_SetString(
+				PyExc_TypeError,
+			"The object is not a PyHKEY object");
+		return FALSE;
+	}
+	return TRUE;
+}
+
+PyObject *
+PyHKEY_FromHKEY(HKEY h)
+{
+	PyHKEYObject *op;
+
+	/* Inline PyObject_New */
+	op = (PyHKEYObject *) PyObject_MALLOC(sizeof(PyHKEYObject));
+	if (op == NULL)
+		return PyErr_NoMemory();
+	PyObject_INIT(op, &PyHKEY_Type);
+	op->hkey = h;
+	return (PyObject *)op;
+}
+
+
+/************************************************************************
+  The module methods
+************************************************************************/
+BOOL
+PyWinObject_CloseHKEY(PyObject *obHandle)
+{
+	BOOL ok;
+	if (PyHKEY_Check(obHandle)) {
+		ok = PyHKEY_Close(obHandle);
+	}
+#if SIZEOF_LONG >= SIZEOF_HKEY
+	else if (PyInt_Check(obHandle)) {
+		long rc = RegCloseKey((HKEY)PyInt_AsLong(obHandle));
+		ok = (rc == ERROR_SUCCESS);
+		if (!ok)
+			PyErr_SetFromWindowsErrWithFunction(rc, "RegCloseKey");
+	}
+#else
+	else if (PyLong_Check(obHandle)) {
+		long rc = RegCloseKey((HKEY)PyLong_AsVoidPtr(obHandle));
+		ok = (rc == ERROR_SUCCESS);
+		if (!ok)
+			PyErr_SetFromWindowsErrWithFunction(rc, "RegCloseKey");
+	}
+#endif
+	else {
+		PyErr_SetString(
+			PyExc_TypeError,
+			"A handle must be a HKEY object or an integer");
+		return FALSE;
+	}
+	return ok;
+}
+
+
+/*
+   Private Helper functions for the registry interfaces
+
+** Note that fixupMultiSZ and countString have both had changes
+** made to support "incorrect strings".  The registry specification
+** calls for strings to be terminated with 2 null bytes.  It seems
+** some commercial packages install strings which dont conform,
+** causing this code to fail - however, "regedit" etc still work
+** with these strings (ie only we dont!).
+*/
+static void
+fixupMultiSZ(char **str, char *data, int len)
+{
+	char *P;
+	int i;
+	char *Q;
+
+	Q = data + len;
+	for (P = data, i = 0; P < Q && *P != '\0'; P++, i++) {
+		str[i] = P;
+		for(; *P != '\0'; P++)
+			;
+	}
+}
+
+static int
+countStrings(char *data, int len)
+{
+	int strings;
+	char *P;
+	char *Q = data + len;
+
+	for (P = data, strings = 0; P < Q && *P != '\0'; P++, strings++)
+		for (; P < Q && *P != '\0'; P++)
+			;
+	return strings;
+}
+
+/* Convert PyObject into Registry data.
+   Allocates space as needed. */
+static BOOL
+Py2Reg(PyObject *value, DWORD typ, BYTE **retDataBuf, DWORD *retDataSize)
+{
+	int i,j;
+	switch (typ) {
+		case REG_DWORD:
+			if (value != Py_None && !PyInt_Check(value))
+				return FALSE;
+			*retDataBuf = (BYTE *)PyMem_NEW(DWORD, sizeof(DWORD));
+			if (*retDataBuf==NULL){
+				PyErr_NoMemory();
+				return FALSE;
+			}
+			*retDataSize = sizeof(DWORD);
+			if (value == Py_None) {
+				DWORD zero = 0;
+				memcpy(*retDataBuf, &zero, sizeof(DWORD));
+			}
+			else
+				memcpy(*retDataBuf,
+				       &PyInt_AS_LONG((PyIntObject *)value),
+				       sizeof(DWORD));
+			break;
+		case REG_SZ:
+		case REG_EXPAND_SZ:
+			{
+			int need_decref = 0;
+			if (value == Py_None)
+				*retDataSize = 1;
+			else {
+				if (PyUnicode_Check(value)) {
+					value = PyUnicode_AsEncodedString(
+						      value,
+						      "mbcs",
+						      NULL);
+					if (value==NULL)
+						return FALSE;
+					need_decref = 1;
+				}
+				if (!PyString_Check(value))
+					return FALSE;
+				*retDataSize = 1 + strlen(
+					PyString_AS_STRING(
+						(PyStringObject *)value));
+			}
+			*retDataBuf = (BYTE *)PyMem_NEW(DWORD, *retDataSize);
+			if (*retDataBuf==NULL){
+				PyErr_NoMemory();
+				return FALSE;
+			}
+			if (value == Py_None)
+				strcpy((char *)*retDataBuf, "");
+			else
+				strcpy((char *)*retDataBuf,
+				       PyString_AS_STRING(
+				       		(PyStringObject *)value));
+			if (need_decref)
+				Py_DECREF(value);
+			break;
+			}
+		case REG_MULTI_SZ:
+			{
+				DWORD size = 0;
+				char *P;
+				PyObject **obs = NULL;
+
+				if (value == Py_None)
+					i = 0;
+				else {
+					if (!PyList_Check(value))
+						return FALSE;
+					i = PyList_Size(value);
+				}
+				obs = malloc(sizeof(PyObject *) * i);
+				memset(obs, 0, sizeof(PyObject *) * i);
+				for (j = 0; j < i; j++)
+				{
+					PyObject *t;
+					t = PyList_GET_ITEM(
+						(PyListObject *)value,j);
+					if (PyString_Check(t)) {
+						obs[j] = t;
+						Py_INCREF(t);
+					} else if (PyUnicode_Check(t)) {
+						obs[j] = PyUnicode_AsEncodedString(
+								t,
+								"mbcs",
+								NULL);
+						if (obs[j]==NULL)
+							goto reg_multi_fail;
+					} else
+						goto reg_multi_fail;
+					size += 1 + strlen(
+						PyString_AS_STRING(
+							(PyStringObject *)obs[j]));
+				}
+
+				*retDataSize = size + 1;
+				*retDataBuf = (BYTE *)PyMem_NEW(char,
+							        *retDataSize);
+				if (*retDataBuf==NULL){
+					PyErr_NoMemory();
+					goto reg_multi_fail;
+				}
+				P = (char *)*retDataBuf;
+
+				for (j = 0; j < i; j++)
+				{
+					PyObject *t;
+					t = obs[j];
+					strcpy(P,
+					       PyString_AS_STRING(
+					       		(PyStringObject *)t));
+					P += 1 + strlen(
+						PyString_AS_STRING(
+							(PyStringObject *)t));
+					Py_DECREF(obs[j]);
+				}
+				/* And doubly-terminate the list... */
+				*P = '\0';
+				free(obs);
+				break;
+			reg_multi_fail:
+				if (obs) {
+					for (j = 0; j < i; j++)
+						Py_XDECREF(obs[j]);
+
+					free(obs);
+				}
+				return FALSE;
+			}
+		case REG_BINARY:
+		/* ALSO handle ALL unknown data types here.  Even if we can't
+		   support it natively, we should handle the bits. */
+		default:
+			if (value == Py_None)
+				*retDataSize = 0;
+			else {
+				void *src_buf;
+				PyBufferProcs *pb = value->ob_type->tp_as_buffer;
+				if (pb==NULL) {
+					PyErr_Format(PyExc_TypeError,
+						"Objects of type '%s' can not "
+						"be used as binary registry values",
+						value->ob_type->tp_name);
+					return FALSE;
+				}
+				*retDataSize = (*pb->bf_getreadbuffer)(value, 0, &src_buf);
+				*retDataBuf = (BYTE *)PyMem_NEW(char,
+								*retDataSize);
+				if (*retDataBuf==NULL){
+					PyErr_NoMemory();
+					return FALSE;
+				}
+				memcpy(*retDataBuf, src_buf, *retDataSize);
+			}
+			break;
+	}
+	return TRUE;
+}
+
+/* Convert Registry data into PyObject*/
+static PyObject *
+Reg2Py(char *retDataBuf, DWORD retDataSize, DWORD typ)
+{
+	PyObject *obData;
+
+	switch (typ) {
+		case REG_DWORD:
+			if (retDataSize == 0)
+				obData = Py_BuildValue("i", 0);
+			else
+				obData = Py_BuildValue("i",
+						       *(int *)retDataBuf);
+			break;
+		case REG_SZ:
+		case REG_EXPAND_SZ:
+			/* retDataBuf may or may not have a trailing NULL in
+			   the buffer. */
+			if (retDataSize && retDataBuf[retDataSize-1] == '\0')
+				--retDataSize;
+			if (retDataSize ==0)
+				retDataBuf = "";
+			obData = PyUnicode_DecodeMBCS(retDataBuf,
+						      retDataSize,
+						      NULL);
+			break;
+		case REG_MULTI_SZ:
+			if (retDataSize == 0)
+				obData = PyList_New(0);
+			else
+			{
+				int index = 0;
+				int s = countStrings(retDataBuf, retDataSize);
+				char **str = (char **)malloc(sizeof(char *)*s);
+				if (str == NULL)
+					return PyErr_NoMemory();
+
+				fixupMultiSZ(str, retDataBuf, retDataSize);
+				obData = PyList_New(s);
+				if (obData == NULL)
+					return NULL;
+				for (index = 0; index < s; index++)
+				{
+					size_t len = _mbstrlen(str[index]);
+					if (len > INT_MAX) {
+						PyErr_SetString(PyExc_OverflowError,
+							"registry string is too long for a Python string");
+						Py_DECREF(obData);
+						return NULL;
+					}
+					PyList_SetItem(obData,
+						       index,
+						       PyUnicode_DecodeMBCS(
+						            (const char *)str[index],
+							   (int)len,
+							    NULL)
+						       );
+				}
+				free(str);
+
+				break;
+			}
+		case REG_BINARY:
+		/* ALSO handle ALL unknown data types here.  Even if we can't
+		   support it natively, we should handle the bits. */
+		default:
+			if (retDataSize == 0) {
+				Py_INCREF(Py_None);
+				obData = Py_None;
+			}
+			else
+				obData = Py_BuildValue("s#",
+					 	       (char *)retDataBuf,
+					 	       retDataSize);
+			break;
+	}
+	if (obData == NULL)
+		return NULL;
+	else
+		return obData;
+}
+
+/* The Python methods */
+
+static PyObject *
+PyCloseKey(PyObject *self, PyObject *args)
+{
+	PyObject *obKey;
+	if (!PyArg_ParseTuple(args, "O:CloseKey", &obKey))
+		return NULL;
+	if (!PyHKEY_Close(obKey))
+		return NULL;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+PyConnectRegistry(PyObject *self, PyObject *args)
+{
+	HKEY hKey;
+	PyObject *obKey;
+	char *szCompName = NULL;
+	HKEY retKey;
+	long rc;
+	if (!PyArg_ParseTuple(args, "zO:ConnectRegistry", &szCompName, &obKey))
+		return NULL;
+	if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE))
+		return NULL;
+	Py_BEGIN_ALLOW_THREADS
+	rc = RegConnectRegistry(szCompName, hKey, &retKey);
+	Py_END_ALLOW_THREADS
+	if (rc != ERROR_SUCCESS)
+		return PyErr_SetFromWindowsErrWithFunction(rc,
+							   "ConnectRegistry");
+	return PyHKEY_FromHKEY(retKey);
+}
+
+static PyObject *
+PyCreateKey(PyObject *self, PyObject *args)
+{
+	HKEY hKey;
+	PyObject *obKey;
+	char *subKey;
+	HKEY retKey;
+	long rc;
+	if (!PyArg_ParseTuple(args, "Oz:CreateKey", &obKey, &subKey))
+		return NULL;
+	if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE))
+		return NULL;
+	rc = RegCreateKey(hKey, subKey, &retKey);
+	if (rc != ERROR_SUCCESS)
+		return PyErr_SetFromWindowsErrWithFunction(rc, "CreateKey");
+	return PyHKEY_FromHKEY(retKey);
+}
+
+static PyObject *
+PyDeleteKey(PyObject *self, PyObject *args)
+{
+	HKEY hKey;
+	PyObject *obKey;
+	char *subKey;
+	long rc;
+	if (!PyArg_ParseTuple(args, "Os:DeleteKey", &obKey, &subKey))
+		return NULL;
+	if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE))
+		return NULL;
+	rc = RegDeleteKey(hKey, subKey );
+	if (rc != ERROR_SUCCESS)
+		return PyErr_SetFromWindowsErrWithFunction(rc, "RegDeleteKey");
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+PyDeleteValue(PyObject *self, PyObject *args)
+{
+	HKEY hKey;
+	PyObject *obKey;
+	char *subKey;
+	long rc;
+	if (!PyArg_ParseTuple(args, "Oz:DeleteValue", &obKey, &subKey))
+		return NULL;
+	if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE))
+		return NULL;
+	Py_BEGIN_ALLOW_THREADS
+	rc = RegDeleteValue(hKey, subKey);
+	Py_END_ALLOW_THREADS
+	if (rc !=ERROR_SUCCESS)
+		return PyErr_SetFromWindowsErrWithFunction(rc,
+							   "RegDeleteValue");
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+PyEnumKey(PyObject *self, PyObject *args)
+{
+	HKEY hKey;
+	PyObject *obKey;
+	int index;
+	long rc;
+	PyObject *retStr;
+	char tmpbuf[256]; /* max key name length is 255 */
+	DWORD len = sizeof(tmpbuf); /* includes NULL terminator */
+
+	if (!PyArg_ParseTuple(args, "Oi:EnumKey", &obKey, &index))
+		return NULL;
+	if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE))
+		return NULL;
+
+	Py_BEGIN_ALLOW_THREADS
+	rc = RegEnumKeyEx(hKey, index, tmpbuf, &len, NULL, NULL, NULL, NULL);
+	Py_END_ALLOW_THREADS
+	if (rc != ERROR_SUCCESS)
+		return PyErr_SetFromWindowsErrWithFunction(rc, "RegEnumKeyEx");
+
+	retStr = PyString_FromStringAndSize(tmpbuf, len);
+	return retStr;  /* can be NULL */
+}
+
+static PyObject *
+PyEnumValue(PyObject *self, PyObject *args)
+{
+	HKEY hKey;
+	PyObject *obKey;
+	int index;
+	long rc;
+	char *retValueBuf;
+	char *retDataBuf;
+	DWORD retValueSize;
+	DWORD retDataSize;
+	DWORD typ;
+	PyObject *obData;
+	PyObject *retVal;
+
+	if (!PyArg_ParseTuple(args, "Oi:EnumValue", &obKey, &index))
+		return NULL;
+	if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE))
+		return NULL;
+
+	if ((rc = RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL,
+				  NULL,
+				  &retValueSize, &retDataSize, NULL, NULL))
+	    != ERROR_SUCCESS)
+		return PyErr_SetFromWindowsErrWithFunction(rc,
+							   "RegQueryInfoKey");
+	++retValueSize;    /* include null terminators */
+	++retDataSize;
+	retValueBuf = (char *)PyMem_Malloc(retValueSize);
+	if (retValueBuf == NULL)
+		return PyErr_NoMemory();
+	retDataBuf = (char *)PyMem_Malloc(retDataSize);
+	if (retDataBuf == NULL) {
+		PyMem_Free(retValueBuf);
+		return PyErr_NoMemory();
+	}
+
+	Py_BEGIN_ALLOW_THREADS
+	rc = RegEnumValue(hKey,
+			  index,
+			  retValueBuf,
+			  &retValueSize,
+			  NULL,
+			  &typ,
+			  (BYTE *)retDataBuf,
+			  &retDataSize);
+	Py_END_ALLOW_THREADS
+
+	if (rc != ERROR_SUCCESS) {
+		retVal = PyErr_SetFromWindowsErrWithFunction(rc,
+							     "PyRegEnumValue");
+		goto fail;
+	}
+	obData = Reg2Py(retDataBuf, retDataSize, typ);
+	if (obData == NULL) {
+		retVal = NULL;
+		goto fail;
+	}
+	retVal = Py_BuildValue("sOi", retValueBuf, obData, typ);
+	Py_DECREF(obData);
+  fail:
+	PyMem_Free(retValueBuf);
+	PyMem_Free(retDataBuf);
+	return retVal;
+}
+
+static PyObject *
+PyFlushKey(PyObject *self, PyObject *args)
+{
+	HKEY hKey;
+	PyObject *obKey;
+	long rc;
+	if (!PyArg_ParseTuple(args, "O:FlushKey", &obKey))
+		return NULL;
+	if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE))
+		return NULL;
+	Py_BEGIN_ALLOW_THREADS
+	rc = RegFlushKey(hKey);
+	Py_END_ALLOW_THREADS
+	if (rc != ERROR_SUCCESS)
+		return PyErr_SetFromWindowsErrWithFunction(rc, "RegFlushKey");
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+static PyObject *
+PyLoadKey(PyObject *self, PyObject *args)
+{
+	HKEY hKey;
+	PyObject *obKey;
+	char *subKey;
+	char *fileName;
+
+	long rc;
+	if (!PyArg_ParseTuple(args, "Oss:LoadKey", &obKey, &subKey, &fileName))
+		return NULL;
+	if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE))
+		return NULL;
+	Py_BEGIN_ALLOW_THREADS
+	rc = RegLoadKey(hKey, subKey, fileName );
+	Py_END_ALLOW_THREADS
+	if (rc != ERROR_SUCCESS)
+		return PyErr_SetFromWindowsErrWithFunction(rc, "RegLoadKey");
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+PyOpenKey(PyObject *self, PyObject *args)
+{
+	HKEY hKey;
+	PyObject *obKey;
+
+	char *subKey;
+	int res = 0;
+	HKEY retKey;
+	long rc;
+	REGSAM sam = KEY_READ;
+	if (!PyArg_ParseTuple(args, "Oz|ii:OpenKey", &obKey, &subKey,
+	                      &res, &sam))
+		return NULL;
+	if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE))
+		return NULL;
+
+	Py_BEGIN_ALLOW_THREADS
+	rc = RegOpenKeyEx(hKey, subKey, res, sam, &retKey);
+	Py_END_ALLOW_THREADS
+	if (rc != ERROR_SUCCESS)
+		return PyErr_SetFromWindowsErrWithFunction(rc, "RegOpenKeyEx");
+	return PyHKEY_FromHKEY(retKey);
+}
+
+
+static PyObject *
+PyQueryInfoKey(PyObject *self, PyObject *args)
+{
+  HKEY hKey;
+  PyObject *obKey;
+  long rc;
+  DWORD nSubKeys, nValues;
+  FILETIME ft;
+  LARGE_INTEGER li;
+  PyObject *l;
+  PyObject *ret;
+  if (!PyArg_ParseTuple(args, "O:QueryInfoKey", &obKey))
+	return NULL;
+  if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE))
+	return NULL;
+  if ((rc = RegQueryInfoKey(hKey, NULL, NULL, 0, &nSubKeys, NULL, NULL,
+			    &nValues,  NULL,  NULL, NULL, &ft))
+      != ERROR_SUCCESS)
+	return PyErr_SetFromWindowsErrWithFunction(rc, "RegQueryInfoKey");
+  li.LowPart = ft.dwLowDateTime;
+  li.HighPart = ft.dwHighDateTime;
+  l = PyLong_FromLongLong(li.QuadPart);
+  if (l == NULL)
+	return NULL;
+  ret = Py_BuildValue("iiO", nSubKeys, nValues, l);
+  Py_DECREF(l);
+  return ret;
+}
+
+static PyObject *
+PyQueryValue(PyObject *self, PyObject *args)
+{
+	HKEY hKey;
+	PyObject *obKey;
+	char *subKey;
+	long rc;
+	PyObject *retStr;
+	char *retBuf;
+	long bufSize = 0;
+
+	if (!PyArg_ParseTuple(args, "Oz:QueryValue", &obKey, &subKey))
+		return NULL;
+
+	if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE))
+		return NULL;
+	if ((rc = RegQueryValue(hKey, subKey, NULL, &bufSize))
+	    != ERROR_SUCCESS)
+		return PyErr_SetFromWindowsErrWithFunction(rc,
+							   "RegQueryValue");
+	retStr = PyString_FromStringAndSize(NULL, bufSize);
+	if (retStr == NULL)
+		return NULL;
+	retBuf = PyString_AS_STRING(retStr);
+	if ((rc = RegQueryValue(hKey, subKey, retBuf, &bufSize))
+	    != ERROR_SUCCESS) {
+		Py_DECREF(retStr);
+		return PyErr_SetFromWindowsErrWithFunction(rc,
+							   "RegQueryValue");
+	}
+	_PyString_Resize(&retStr, strlen(retBuf));
+	return retStr;
+}
+
+static PyObject *
+PyQueryValueEx(PyObject *self, PyObject *args)
+{
+	HKEY hKey;
+	PyObject *obKey;
+	char *valueName;
+
+	long rc;
+	char *retBuf;
+	DWORD bufSize = 0;
+	DWORD typ;
+	PyObject *obData;
+	PyObject *result;
+
+	if (!PyArg_ParseTuple(args, "Oz:QueryValueEx", &obKey, &valueName))
+		return NULL;
+
+	if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE))
+		return NULL;
+	if ((rc = RegQueryValueEx(hKey, valueName,
+				  NULL, NULL, NULL,
+				  &bufSize))
+	    != ERROR_SUCCESS)
+		return PyErr_SetFromWindowsErrWithFunction(rc,
+							   "RegQueryValueEx");
+	retBuf = (char *)PyMem_Malloc(bufSize);
+	if (retBuf == NULL)
+		return PyErr_NoMemory();
+	if ((rc = RegQueryValueEx(hKey, valueName, NULL,
+				  &typ, (BYTE *)retBuf, &bufSize))
+	    != ERROR_SUCCESS) {
+		PyMem_Free(retBuf);
+		return PyErr_SetFromWindowsErrWithFunction(rc,
+							   "RegQueryValueEx");
+	}
+	obData = Reg2Py(retBuf, bufSize, typ);
+	PyMem_Free((void *)retBuf);
+	if (obData == NULL)
+		return NULL;
+	result = Py_BuildValue("Oi", obData, typ);
+	Py_DECREF(obData);
+	return result;
+}
+
+
+static PyObject *
+PySaveKey(PyObject *self, PyObject *args)
+{
+	HKEY hKey;
+	PyObject *obKey;
+	char *fileName;
+	LPSECURITY_ATTRIBUTES pSA = NULL;
+
+	long rc;
+	if (!PyArg_ParseTuple(args, "Os:SaveKey", &obKey, &fileName))
+		return NULL;
+	if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE))
+		return NULL;
+/*  One day we may get security into the core?
+	if (!PyWinObject_AsSECURITY_ATTRIBUTES(obSA, &pSA, TRUE))
+		return NULL;
+*/
+	Py_BEGIN_ALLOW_THREADS
+	rc = RegSaveKey(hKey, fileName, pSA );
+	Py_END_ALLOW_THREADS
+	if (rc != ERROR_SUCCESS)
+		return PyErr_SetFromWindowsErrWithFunction(rc, "RegSaveKey");
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+PySetValue(PyObject *self, PyObject *args)
+{
+	HKEY hKey;
+	PyObject *obKey;
+	char *subKey;
+	char *str;
+	DWORD typ;
+	DWORD len;
+	long rc;
+	PyObject *obStrVal;
+	PyObject *obSubKey;
+	if (!PyArg_ParseTuple(args, "OOiO:SetValue",
+			      &obKey,
+			      &obSubKey,
+			      &typ,
+			      &obStrVal))
+		return NULL;
+	if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE))
+		return NULL;
+	if (typ != REG_SZ) {
+		PyErr_SetString(PyExc_TypeError,
+				"Type must be _winreg.REG_SZ");
+		return NULL;
+	}
+	/* XXX - need Unicode support */
+	str = PyString_AsString(obStrVal);
+	if (str == NULL)
+		return NULL;
+	len = PyString_Size(obStrVal);
+	if (obSubKey == Py_None)
+		subKey = NULL;
+	else {
+		subKey = PyString_AsString(obSubKey);
+		if (subKey == NULL)
+			return NULL;
+	}
+	Py_BEGIN_ALLOW_THREADS
+	rc = RegSetValue(hKey, subKey, REG_SZ, str, len+1);
+	Py_END_ALLOW_THREADS
+	if (rc != ERROR_SUCCESS)
+		return PyErr_SetFromWindowsErrWithFunction(rc, "RegSetValue");
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+PySetValueEx(PyObject *self, PyObject *args)
+{
+	HKEY hKey;
+	PyObject *obKey;
+	char *valueName;
+	PyObject *obRes;
+	PyObject *value;
+	BYTE *data;
+	DWORD len;
+	DWORD typ;
+
+	LONG rc;
+
+	if (!PyArg_ParseTuple(args, "OzOiO:SetValueEx",
+			      &obKey,
+			      &valueName,
+			      &obRes,
+			      &typ,
+			      &value))
+		return NULL;
+	if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE))
+		return NULL;
+	if (!Py2Reg(value, typ, &data, &len))
+	{
+		if (!PyErr_Occurred())
+			PyErr_SetString(PyExc_ValueError,
+				 "Could not convert the data to the specified type.");
+		return NULL;
+	}
+	Py_BEGIN_ALLOW_THREADS
+	rc = RegSetValueEx(hKey, valueName, 0, typ, data, len);
+	Py_END_ALLOW_THREADS
+	PyMem_DEL(data);
+	if (rc != ERROR_SUCCESS)
+		return PyErr_SetFromWindowsErrWithFunction(rc,
+							   "RegSetValueEx");
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static struct PyMethodDef winreg_methods[] = {
+	{"CloseKey",         PyCloseKey,        METH_VARARGS, CloseKey_doc},
+	{"ConnectRegistry",  PyConnectRegistry, METH_VARARGS, ConnectRegistry_doc},
+	{"CreateKey",        PyCreateKey,       METH_VARARGS, CreateKey_doc},
+	{"DeleteKey",        PyDeleteKey,       METH_VARARGS, DeleteKey_doc},
+	{"DeleteValue",      PyDeleteValue,     METH_VARARGS, DeleteValue_doc},
+	{"EnumKey",          PyEnumKey,         METH_VARARGS, EnumKey_doc},
+	{"EnumValue",        PyEnumValue,       METH_VARARGS, EnumValue_doc},
+	{"FlushKey",         PyFlushKey,        METH_VARARGS, FlushKey_doc},
+	{"LoadKey",          PyLoadKey,         METH_VARARGS, LoadKey_doc},
+	{"OpenKey",          PyOpenKey,         METH_VARARGS, OpenKey_doc},
+	{"OpenKeyEx",        PyOpenKey,         METH_VARARGS, OpenKeyEx_doc},
+	{"QueryValue",       PyQueryValue,      METH_VARARGS, QueryValue_doc},
+	{"QueryValueEx",     PyQueryValueEx,    METH_VARARGS, QueryValueEx_doc},
+	{"QueryInfoKey",     PyQueryInfoKey,    METH_VARARGS, QueryInfoKey_doc},
+	{"SaveKey",          PySaveKey,         METH_VARARGS, SaveKey_doc},
+	{"SetValue",         PySetValue,        METH_VARARGS, SetValue_doc},
+	{"SetValueEx",       PySetValueEx,      METH_VARARGS, SetValueEx_doc},
+	NULL,
+};
+
+static void
+insint(PyObject * d, char * name, long value)
+{
+	PyObject *v = PyInt_FromLong(value);
+	if (!v || PyDict_SetItemString(d, name, v))
+		PyErr_Clear();
+	Py_XDECREF(v);
+}
+
+#define ADD_INT(val) insint(d, #val, val)
+
+static void
+inskey(PyObject * d, char * name, HKEY key)
+{
+	PyObject *v = PyLong_FromVoidPtr(key);
+	if (!v || PyDict_SetItemString(d, name, v))
+		PyErr_Clear();
+	Py_XDECREF(v);
+}
+
+#define ADD_KEY(val) inskey(d, #val, val)
+
+PyMODINIT_FUNC init_winreg(void)
+{
+	PyObject *m, *d;
+	m = Py_InitModule3("_winreg", winreg_methods, module_doc);
+	if (m == NULL)
+		return;
+	d = PyModule_GetDict(m);
+	PyHKEY_Type.ob_type = &PyType_Type;
+	PyHKEY_Type.tp_doc = PyHKEY_doc;
+	Py_INCREF(&PyHKEY_Type);
+	if (PyDict_SetItemString(d, "HKEYType",
+				 (PyObject *)&PyHKEY_Type) != 0)
+		return;
+	Py_INCREF(PyExc_WindowsError);
+	if (PyDict_SetItemString(d, "error",
+				 PyExc_WindowsError) != 0)
+		return;
+
+	/* Add the relevant constants */
+	ADD_KEY(HKEY_CLASSES_ROOT);
+	ADD_KEY(HKEY_CURRENT_USER);
+	ADD_KEY(HKEY_LOCAL_MACHINE);
+	ADD_KEY(HKEY_USERS);
+	ADD_KEY(HKEY_PERFORMANCE_DATA);
+#ifdef HKEY_CURRENT_CONFIG
+	ADD_KEY(HKEY_CURRENT_CONFIG);
+#endif
+#ifdef HKEY_DYN_DATA
+	ADD_KEY(HKEY_DYN_DATA);
+#endif
+	ADD_INT(KEY_QUERY_VALUE);
+	ADD_INT(KEY_SET_VALUE);
+	ADD_INT(KEY_CREATE_SUB_KEY);
+	ADD_INT(KEY_ENUMERATE_SUB_KEYS);
+	ADD_INT(KEY_NOTIFY);
+	ADD_INT(KEY_CREATE_LINK);
+	ADD_INT(KEY_READ);
+	ADD_INT(KEY_WRITE);
+	ADD_INT(KEY_EXECUTE);
+	ADD_INT(KEY_ALL_ACCESS);
+	ADD_INT(REG_OPTION_RESERVED);
+	ADD_INT(REG_OPTION_NON_VOLATILE);
+	ADD_INT(REG_OPTION_VOLATILE);
+	ADD_INT(REG_OPTION_CREATE_LINK);
+	ADD_INT(REG_OPTION_BACKUP_RESTORE);
+	ADD_INT(REG_OPTION_OPEN_LINK);
+	ADD_INT(REG_LEGAL_OPTION);
+	ADD_INT(REG_CREATED_NEW_KEY);
+	ADD_INT(REG_OPENED_EXISTING_KEY);
+	ADD_INT(REG_WHOLE_HIVE_VOLATILE);
+	ADD_INT(REG_REFRESH_HIVE);
+	ADD_INT(REG_NO_LAZY_FLUSH);
+	ADD_INT(REG_NOTIFY_CHANGE_NAME);
+	ADD_INT(REG_NOTIFY_CHANGE_ATTRIBUTES);
+	ADD_INT(REG_NOTIFY_CHANGE_LAST_SET);
+	ADD_INT(REG_NOTIFY_CHANGE_SECURITY);
+	ADD_INT(REG_LEGAL_CHANGE_FILTER);
+	ADD_INT(REG_NONE);
+	ADD_INT(REG_SZ);
+	ADD_INT(REG_EXPAND_SZ);
+	ADD_INT(REG_BINARY);
+	ADD_INT(REG_DWORD);
+	ADD_INT(REG_DWORD_LITTLE_ENDIAN);
+	ADD_INT(REG_DWORD_BIG_ENDIAN);
+	ADD_INT(REG_LINK);
+	ADD_INT(REG_MULTI_SZ);
+	ADD_INT(REG_RESOURCE_LIST);
+	ADD_INT(REG_FULL_RESOURCE_DESCRIPTOR);
+	ADD_INT(REG_RESOURCE_REQUIREMENTS_LIST);
+}
+

Added: vendor/Python/current/PC/bdist_wininst/PythonPowered.bmp
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/PC/bdist_wininst/PythonPowered.bmp
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/PC/bdist_wininst/README.txt
===================================================================
--- vendor/Python/current/PC/bdist_wininst/README.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/bdist_wininst/README.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,5 @@
+
+XXX Write description
+XXX Dont't forget to mention upx
+
+XXX Add pointer to this file into PC/README.txt

Added: vendor/Python/current/PC/bdist_wininst/archive.h
===================================================================
--- vendor/Python/current/PC/bdist_wininst/archive.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/bdist_wininst/archive.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,105 @@
+/*
+  IMPORTANT NOTE: IF THIS FILE IS CHANGED, WININST-6.EXE MUST BE RECOMPILED
+  WITH THE MSVC6 WININST.DSW WORKSPACE FILE MANUALLY, AND WININST-7.1.EXE MUST
+  BE RECOMPILED WITH THE MSVC 2003.NET WININST-7.1.VCPROJ FILE MANUALLY.
+
+  IF CHANGES TO THIS FILE ARE CHECKED INTO PYTHON CVS, THE RECOMPILED BINARIES
+  MUST BE CHECKED IN AS WELL!
+*/
+
+#pragma pack(1)
+
+/* zip-archive headers
+ * See: http://www.pkware.com/appnote.html
+ */
+
+struct eof_cdir {
+	long tag;	/* must be 0x06054b50 */
+	short disknum;
+	short firstdisk;
+	short nTotalCDirThis;
+	short nTotalCDir;
+	long nBytesCDir;
+	long ofsCDir;
+	short commentlen;
+};
+
+struct cdir {
+	long tag;	/* must be 0x02014b50 */
+	short version_made;
+	short version_extract;
+	short gp_bitflag;
+	short comp_method;
+	short last_mod_file_time;
+	short last_mod_file_date;
+	long crc32;
+	long comp_size;
+	long uncomp_size;
+	short fname_length;
+	short extra_length;
+	short comment_length;
+	short disknum_start;
+	short int_file_attr;
+	long ext_file_attr;
+	long ofs_local_header;
+};
+
+struct fhdr {
+	long tag;	/* must be 0x04034b50 */
+	short version_needed;
+	short flags;
+	short method;
+	short last_mod_file_time;
+	short last_mod_file_date;
+	long crc32;
+	long comp_size;
+	long uncomp_size;
+	short fname_length;
+	short extra_length;
+};
+
+
+struct meta_data_hdr {
+	int tag;
+	int uncomp_size;
+	int bitmap_size;
+};
+
+#pragma pack()
+
+/* installation scheme */
+
+typedef struct tagSCHEME {
+	char *name;
+	char *prefix;
+} SCHEME;
+
+typedef int (*NOTIFYPROC)(int code, LPSTR text, ...);
+
+extern BOOL
+extract_file(char *dst, char *src, int method, int comp_size,
+	     int uncomp_size, NOTIFYPROC notify);
+
+extern BOOL
+unzip_archive(SCHEME *scheme, char *dirname, char *data,
+	      DWORD size,  NOTIFYPROC notify);
+
+extern char *
+map_new_file(DWORD flags, char *filename, char
+	     *pathname_part, int size,
+	     WORD wFatDate, WORD wFatTime,
+	     NOTIFYPROC callback);
+
+extern BOOL
+ensure_directory (char *pathname, char *new_part,
+		  NOTIFYPROC callback);
+
+/* codes for NOITIFYPROC */
+#define DIR_CREATED 1
+#define CAN_OVERWRITE 2
+#define FILE_CREATED 3
+#define ZLIB_ERROR 4
+#define SYSTEM_ERROR 5
+#define NUM_FILES 6
+#define FILE_OVERWRITTEN 7
+

Added: vendor/Python/current/PC/bdist_wininst/extract.c
===================================================================
--- vendor/Python/current/PC/bdist_wininst/extract.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/bdist_wininst/extract.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,321 @@
+/*
+  IMPORTANT NOTE: IF THIS FILE IS CHANGED, WININST-6.EXE MUST BE RECOMPILED
+  WITH THE MSVC6 WININST.DSW WORKSPACE FILE MANUALLY, AND WININST-7.1.EXE MUST
+  BE RECOMPILED WITH THE MSVC 2003.NET WININST-7.1.VCPROJ FILE MANUALLY.
+
+  IF CHANGES TO THIS FILE ARE CHECKED INTO PYTHON CVS, THE RECOMPILED BINARIES
+  MUST BE CHECKED IN AS WELL!
+*/
+
+#include <windows.h>
+
+#include "zlib.h"
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "archive.h"
+
+/* Convert unix-path to dos-path */
+static void normpath(char *path)
+{
+	while (path && *path) {
+		if (*path == '/')
+			*path = '\\';
+		++path;
+	}
+}
+
+BOOL ensure_directory(char *pathname, char *new_part, NOTIFYPROC notify)
+{
+	while (new_part && *new_part && (new_part = strchr(new_part, '\\'))) {
+		DWORD attr;
+		*new_part = '\0';
+		attr = GetFileAttributes(pathname);
+		if (attr == -1) {
+			/* nothing found */
+			if (!CreateDirectory(pathname, NULL) && notify)
+				notify(SYSTEM_ERROR,
+				       "CreateDirectory (%s)", pathname);
+			else
+				notify(DIR_CREATED, pathname);
+		}
+		if (attr & FILE_ATTRIBUTE_DIRECTORY) {
+			;
+		} else {
+			SetLastError(183);
+			if (notify)
+				notify(SYSTEM_ERROR,
+				       "CreateDirectory (%s)", pathname);
+		}
+		*new_part = '\\';
+		++new_part;
+	}
+	return TRUE;
+}
+
+/* XXX Should better explicitely specify
+ * uncomp_size and file_times instead of pfhdr!
+ */
+char *map_new_file(DWORD flags, char *filename,
+		   char *pathname_part, int size,
+		   WORD wFatDate, WORD wFatTime,
+		   NOTIFYPROC notify)
+{
+	HANDLE hFile, hFileMapping;
+	char *dst;
+	FILETIME ft;
+
+  try_again:
+	if (!flags)
+		flags = CREATE_NEW;
+	hFile = CreateFile(filename,
+			   GENERIC_WRITE | GENERIC_READ,
+			   0, NULL,
+			   flags,
+			   FILE_ATTRIBUTE_NORMAL, NULL);
+	if (hFile == INVALID_HANDLE_VALUE) {
+		DWORD x = GetLastError();
+		switch (x) {
+		case ERROR_FILE_EXISTS:
+			if (notify && notify(CAN_OVERWRITE, filename))
+				hFile = CreateFile(filename,
+						   GENERIC_WRITE|GENERIC_READ,
+						   0, NULL,
+						   CREATE_ALWAYS,
+						   FILE_ATTRIBUTE_NORMAL,
+						   NULL);
+			else {
+				if (notify)
+					notify(FILE_OVERWRITTEN, filename);
+				return NULL;
+			}
+			break;
+		case ERROR_PATH_NOT_FOUND:
+			if (ensure_directory(filename, pathname_part, notify))
+				goto try_again;
+			else
+				return FALSE;
+			break;
+		default:
+			SetLastError(x);
+			break;
+		}
+	}
+	if (hFile == INVALID_HANDLE_VALUE) {
+		if (notify)
+			notify (SYSTEM_ERROR, "CreateFile (%s)", filename);
+		return NULL;
+	}
+
+	if (notify)
+		notify(FILE_CREATED, filename);
+
+	DosDateTimeToFileTime(wFatDate, wFatTime, &ft);
+	SetFileTime(hFile, &ft, &ft, &ft);
+
+
+	if (size == 0) {
+		/* We cannot map a zero-length file (Also it makes
+		   no sense */
+		CloseHandle(hFile);
+		return NULL;
+	}
+
+	hFileMapping = CreateFileMapping(hFile,
+					 NULL, PAGE_READWRITE, 0, size, NULL);
+
+	CloseHandle(hFile);
+
+	if (hFileMapping == INVALID_HANDLE_VALUE) {
+		if (notify)
+			notify(SYSTEM_ERROR,
+			       "CreateFileMapping (%s)", filename);
+		return NULL;
+	}
+
+	dst = MapViewOfFile(hFileMapping,
+			    FILE_MAP_WRITE, 0, 0, 0);
+
+	CloseHandle(hFileMapping);
+
+	if (!dst) {
+		if (notify)
+			notify(SYSTEM_ERROR, "MapViewOfFile (%s)", filename);
+		return NULL;
+	}
+	return dst;
+}
+
+
+BOOL
+extract_file(char *dst, char *src, int method, int comp_size,
+	     int uncomp_size, NOTIFYPROC notify)
+{
+	z_stream zstream;
+	int result;
+
+	if (method == Z_DEFLATED) {
+		int x;
+		memset(&zstream, 0, sizeof(zstream));
+		zstream.next_in = src;
+		zstream.avail_in = comp_size+1;
+		zstream.next_out = dst;
+		zstream.avail_out = uncomp_size;
+
+/* Apparently an undocumented feature of zlib: Set windowsize
+   to negative values to supress the gzip header and be compatible with
+   zip! */
+		result = TRUE;
+		if (Z_OK != (x = inflateInit2(&zstream, -15))) {
+			if (notify)
+				notify(ZLIB_ERROR,
+				       "inflateInit2 returns %d", x);
+			result = FALSE;
+			goto cleanup;
+		}
+		if (Z_STREAM_END != (x = inflate(&zstream, Z_FINISH))) {
+			if (notify)
+				notify(ZLIB_ERROR,
+				       "inflate returns %d", x);
+			result = FALSE;
+		}
+	  cleanup:
+		if (Z_OK != (x = inflateEnd(&zstream))) {
+			if (notify)
+				notify (ZLIB_ERROR,
+					"inflateEnd returns %d", x);
+			result = FALSE;
+		}
+	} else if (method == 0) {
+		memcpy(dst, src, uncomp_size);
+		result = TRUE;
+	} else
+		result = FALSE;
+	UnmapViewOfFile(dst);
+	return result;
+}
+
+/* Open a zip-compatible archive and extract all files
+ * into the specified directory (which is assumed to exist)
+ */
+BOOL
+unzip_archive(SCHEME *scheme, char *dirname, char *data, DWORD size,
+	      NOTIFYPROC notify)
+{
+	int n;
+	char pathname[MAX_PATH];
+	char *new_part;
+
+	/* read the end of central directory record */
+	struct eof_cdir *pe = (struct eof_cdir *)&data[size - sizeof
+						       (struct eof_cdir)];
+
+	int arc_start = size - sizeof (struct eof_cdir) - pe->nBytesCDir -
+		pe->ofsCDir;
+
+	/* set position to start of central directory */
+	int pos = arc_start + pe->ofsCDir;
+
+	/* make sure this is a zip file */
+	if (pe->tag != 0x06054b50)
+		return FALSE;
+    
+	/* Loop through the central directory, reading all entries */
+	for (n = 0; n < pe->nTotalCDir; ++n) {
+		int i;
+		char *fname;
+		char *pcomp;
+		char *dst;
+		struct cdir *pcdir;
+		struct fhdr *pfhdr;
+
+		pcdir = (struct cdir *)&data[pos];
+		pfhdr = (struct fhdr *)&data[pcdir->ofs_local_header +
+					     arc_start];
+
+		if (pcdir->tag != 0x02014b50)
+			return FALSE;
+		if (pfhdr->tag != 0x04034b50)
+			return FALSE;
+		pos += sizeof(struct cdir);
+		fname = (char *)&data[pos]; /* This is not null terminated! */
+		pos += pcdir->fname_length + pcdir->extra_length +
+			pcdir->comment_length;
+
+		pcomp = &data[pcdir->ofs_local_header
+			      + sizeof(struct fhdr)
+			      + arc_start
+			      + pfhdr->fname_length
+			      + pfhdr->extra_length];
+
+		/* dirname is the Python home directory (prefix) */
+		strcpy(pathname, dirname);
+		if (pathname[strlen(pathname)-1] != '\\')
+			strcat(pathname, "\\");
+		new_part = &pathname[lstrlen(pathname)];
+		/* we must now match the first part of the pathname
+		 * in the archive to a component in the installation
+		 * scheme (PURELIB, PLATLIB, HEADERS, SCRIPTS, or DATA)
+		 * and replace this part by the one in the scheme to use
+		 */
+		for (i = 0; scheme[i].name; ++i) {
+			if (0 == strnicmp(scheme[i].name, fname,
+					  strlen(scheme[i].name))) {
+				char *rest;
+				int len;
+				
+				/* length of the replaced part */
+				int namelen = strlen(scheme[i].name);
+				
+				strcat(pathname, scheme[i].prefix);
+				
+				rest = fname + namelen;
+				len = pfhdr->fname_length - namelen;
+				
+				if ((pathname[strlen(pathname)-1] != '\\')
+				    && (pathname[strlen(pathname)-1] != '/'))
+					strcat(pathname, "\\");
+				/* Now that pathname ends with a separator,
+				 * we must make sure rest does not start with
+				 * an additional one.
+				 */
+				if ((rest[0] == '\\') || (rest[0] == '/')) {
+					++rest;
+					--len;
+				}
+
+				strncat(pathname, rest, len);
+				goto Done;
+			}
+		}
+		/* no prefix to replace found, go unchanged */
+		strncat(pathname, fname, pfhdr->fname_length);
+	  Done:
+		normpath(pathname);
+		if (pathname[strlen(pathname)-1] != '\\') {
+			/*
+			 * The local file header (pfhdr) does not always
+			 * contain the compressed and uncompressed sizes of
+			 * the data depending on bit 3 of the flags field.  So
+			 * it seems better to use the data from the central
+			 * directory (pcdir).
+			 */
+			dst = map_new_file(0, pathname, new_part,
+					   pcdir->uncomp_size,
+					   pcdir->last_mod_file_date,
+					   pcdir->last_mod_file_time, notify);
+			if (dst) {
+				if (!extract_file(dst, pcomp, pfhdr->method,
+						  pcdir->comp_size,
+						  pcdir->uncomp_size,
+						  notify))
+					return FALSE;
+			} /* else ??? */
+		}
+		if (notify)
+			notify(NUM_FILES, new_part, (int)pe->nTotalCDir,
+			       (int)n+1);
+	}
+	return TRUE;
+}

Added: vendor/Python/current/PC/bdist_wininst/install.c
===================================================================
--- vendor/Python/current/PC/bdist_wininst/install.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/bdist_wininst/install.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2543 @@
+/*
+  IMPORTANT NOTE: IF THIS FILE IS CHANGED, WININST-6.EXE MUST BE RECOMPILED
+  WITH THE MSVC6 WININST.DSW WORKSPACE FILE MANUALLY, AND WININST-7.1.EXE MUST
+  BE RECOMPILED WITH THE MSVC 2003.NET WININST-7.1.VCPROJ FILE MANUALLY.
+
+  IF CHANGES TO THIS FILE ARE CHECKED INTO PYTHON CVS, THE RECOMPILED BINARIES
+  MUST BE CHECKED IN AS WELL!
+*/
+
+/*
+ * Written by Thomas Heller, May 2000
+ *
+ * $Id: install.c 38414 2005-02-03 20:35:10Z theller $
+ */
+
+/*
+ * Windows Installer program for distutils.
+ *
+ * (a kind of self-extracting zip-file)
+ *
+ * At runtime, the exefile has appended:
+ * - compressed setup-data in ini-format, containing the following sections:
+ *	[metadata]
+ *	author=Greg Ward
+ *	author_email=gward at python.net
+ *	description=Python Distribution Utilities
+ *	licence=Python
+ *	name=Distutils
+ *	url=http://www.python.org/sigs/distutils-sig/
+ *	version=0.9pre
+ *
+ *	[Setup]
+ *	info= text to be displayed in the edit-box
+ *	title= to be displayed by this program
+ *	target_version = if present, python version required
+ *	pyc_compile = if 0, do not compile py to pyc
+ *	pyo_compile = if 0, do not compile py to pyo
+ *
+ * - a struct meta_data_hdr, describing the above
+ * - a zip-file, containing the modules to be installed.
+ *   for the format see http://www.pkware.com/appnote.html
+ *
+ * What does this program do?
+ * - the setup-data is uncompressed and written to a temporary file.
+ * - setup-data is queried with GetPrivateProfile... calls
+ * - [metadata] - info is displayed in the dialog box
+ * - The registry is searched for installations of python
+ * - The user can select the python version to use.
+ * - The python-installation directory (sys.prefix) is displayed
+ * - When the start-button is pressed, files from the zip-archive
+ *   are extracted to the file system. All .py filenames are stored
+ *   in a list.
+ */
+/*
+ * Includes now an uninstaller.
+ */
+
+/*
+ * To Do:
+ *
+ * display some explanation when no python version is found
+ * instead showing the user an empty listbox to select something from.
+ *
+ * Finish the code so that we can use other python installations
+ * additionaly to those found in the registry,
+ * and then #define USE_OTHER_PYTHON_VERSIONS
+ *
+ *  - install a help-button, which will display something meaningful
+ *    to the poor user.
+ *    text to the user
+ *  - should there be a possibility to display a README file
+ *    before starting the installation (if one is present in the archive)
+ *  - more comments about what the code does(?)
+ *
+ *  - evolve this into a full blown installer (???)
+ */
+
+#include <windows.h>
+#include <commctrl.h>
+#include <imagehlp.h>
+#include <objbase.h>
+#include <shlobj.h>
+#include <objidl.h>
+#include "resource.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <malloc.h>
+#include <io.h>
+#include <fcntl.h>
+
+#include "archive.h"
+
+/* Only for debugging!
+   static int dprintf(char *fmt, ...)
+   {
+   char Buffer[4096];
+   va_list marker;
+   int result;
+
+   va_start(marker, fmt);
+   result = wvsprintf(Buffer, fmt, marker);
+   OutputDebugString(Buffer);
+   return result;
+   }
+*/
+
+/* Bah: global variables */
+FILE *logfile;
+
+char modulename[MAX_PATH];
+
+HWND hwndMain;
+HWND hDialog;
+
+char *ini_file;			/* Full pathname of ini-file */
+/* From ini-file */
+char info[4096];		/* [Setup] info= */
+char title[80];			/* [Setup] title=, contains package name
+				   including version: "Distutils-1.0.1" */
+char target_version[10];	/* [Setup] target_version=, required python
+				   version or empty string */
+char build_info[80];		/* [Setup] build_info=, distutils version
+				   and build date */
+
+char meta_name[80];		/* package name without version like
+				   'Distutils' */
+char install_script[MAX_PATH];
+char *pre_install_script; /* run before we install a single file */
+
+
+int py_major, py_minor;		/* Python version selected for installation */
+
+char *arc_data;			/* memory mapped archive */
+DWORD arc_size;			/* number of bytes in archive */
+int exe_size;			/* number of bytes for exe-file portion */
+char python_dir[MAX_PATH];
+char pythondll[MAX_PATH];
+BOOL pyc_compile, pyo_compile;
+/* Either HKLM or HKCU, depending on where Python itself is registered, and
+   the permissions of the current user. */
+HKEY hkey_root = (HKEY)-1;
+
+BOOL success;			/* Installation successfull? */
+char *failure_reason = NULL;
+
+HANDLE hBitmap;
+char *bitmap_bytes;
+
+
+#define WM_NUMFILES WM_USER+1
+/* wParam: 0, lParam: total number of files */
+#define WM_NEXTFILE WM_USER+2
+/* wParam: number of this file */
+/* lParam: points to pathname */
+
+static BOOL notify(int code, char *fmt, ...);
+
+/* Note: If scheme.prefix is nonempty, it must end with a '\'! */
+/* Note: purelib must be the FIRST entry! */
+SCHEME old_scheme[] = {
+	{ "PURELIB", "" },
+	{ "PLATLIB", "" },
+	{ "HEADERS", "" }, /* 'Include/dist_name' part already in archive */
+	{ "SCRIPTS", "Scripts\\" },
+	{ "DATA", "" },
+	{ NULL, NULL },
+};
+
+SCHEME new_scheme[] = {
+	{ "PURELIB", "Lib\\site-packages\\" },
+	{ "PLATLIB", "Lib\\site-packages\\" },
+	{ "HEADERS", "" }, /* 'Include/dist_name' part already in archive */
+	{ "SCRIPTS", "Scripts\\" },
+	{ "DATA", "" },
+	{ NULL, NULL },
+};
+
+static void unescape(char *dst, char *src, unsigned size)
+{
+	char *eon;
+	char ch;
+
+	while (src && *src && (size > 2)) {
+		if (*src == '\\') {
+			switch (*++src) {
+			case 'n':
+				++src;
+				*dst++ = '\r';
+				*dst++ = '\n';
+				size -= 2;
+				break;
+			case 'r':
+				++src;
+				*dst++ = '\r';
+				--size;
+				break;
+			case '0': case '1': case '2': case '3':
+				ch = (char)strtol(src, &eon, 8);
+				if (ch == '\n') {
+					*dst++ = '\r';
+					--size;
+				}
+				*dst++ = ch;
+				--size;
+				src = eon;
+			}
+		} else {
+			*dst++ = *src++;
+			--size;
+		}
+	}
+	*dst = '\0';
+}
+
+static struct tagFile {
+	char *path;
+	struct tagFile *next;
+} *file_list = NULL;
+
+static void set_failure_reason(char *reason)
+{
+    if (failure_reason)
+	free(failure_reason);
+    failure_reason = strdup(reason);
+    success = FALSE;
+}
+static char *get_failure_reason()
+{
+    if (!failure_reason)
+	return "Installation failed.";
+    return failure_reason;
+}
+
+static void add_to_filelist(char *path)
+{
+	struct tagFile *p;
+	p = (struct tagFile *)malloc(sizeof(struct tagFile));
+	p->path = strdup(path);
+	p->next = file_list;
+	file_list = p;
+}
+
+static int do_compile_files(int (__cdecl * PyRun_SimpleString)(char *),
+			     int optimize)
+{
+	struct tagFile *p;
+	int total, n;
+	char Buffer[MAX_PATH + 64];
+	int errors = 0;
+
+	total = 0;
+	p = file_list;
+	while (p) {
+		++total;
+		p = p->next;
+	}
+	SendDlgItemMessage(hDialog, IDC_PROGRESS, PBM_SETRANGE, 0,
+			    MAKELPARAM(0, total));
+	SendDlgItemMessage(hDialog, IDC_PROGRESS, PBM_SETPOS, 0, 0);
+
+	n = 0;
+	p = file_list;
+	while (p) {
+		++n;
+		wsprintf(Buffer,
+			  "import py_compile; py_compile.compile (r'%s')",
+			  p->path);
+		if (PyRun_SimpleString(Buffer)) {
+			++errors;
+		}
+		/* We send the notification even if the files could not
+		 * be created so that the uninstaller will remove them
+		 * in case they are created later.
+		 */
+		wsprintf(Buffer, "%s%c", p->path, optimize ? 'o' : 'c');
+		notify(FILE_CREATED, Buffer);
+
+		SendDlgItemMessage(hDialog, IDC_PROGRESS, PBM_SETPOS, n, 0);
+		SetDlgItemText(hDialog, IDC_INFO, p->path);
+		p = p->next;
+	}
+	return errors;
+}
+
+#define DECLPROC(dll, result, name, args)\
+    typedef result (*__PROC__##name) args;\
+    result (*name)args = (__PROC__##name)GetProcAddress(dll, #name)
+
+
+#define DECLVAR(dll, type, name)\
+    type *name = (type*)GetProcAddress(dll, #name)
+
+typedef void PyObject;
+
+
+/*
+ * Returns number of files which failed to compile,
+ * -1 if python could not be loaded at all
+ */
+static int compile_filelist(HINSTANCE hPython, BOOL optimize_flag)
+{
+	DECLPROC(hPython, void, Py_Initialize, (void));
+	DECLPROC(hPython, void, Py_SetProgramName, (char *));
+	DECLPROC(hPython, void, Py_Finalize, (void));
+	DECLPROC(hPython, int, PyRun_SimpleString, (char *));
+	DECLPROC(hPython, PyObject *, PySys_GetObject, (char *));
+	DECLVAR(hPython, int, Py_OptimizeFlag);
+
+	int errors = 0;
+	struct tagFile *p = file_list;
+
+	if (!p)
+		return 0;
+
+	if (!Py_Initialize || !Py_SetProgramName || !Py_Finalize)
+		return -1;
+
+	if (!PyRun_SimpleString || !PySys_GetObject || !Py_OptimizeFlag)
+		return -1;
+
+	*Py_OptimizeFlag = optimize_flag ? 1 : 0;
+	Py_SetProgramName(modulename);
+	Py_Initialize();
+
+	errors += do_compile_files(PyRun_SimpleString, optimize_flag);
+	Py_Finalize();
+
+	return errors;
+}
+
+typedef PyObject *(*PyCFunction)(PyObject *, PyObject *);
+
+struct PyMethodDef {
+	char	*ml_name;
+	PyCFunction  ml_meth;
+	int		 ml_flags;
+	char	*ml_doc;
+};
+typedef struct PyMethodDef PyMethodDef;
+
+void *(*g_Py_BuildValue)(char *, ...);
+int (*g_PyArg_ParseTuple)(PyObject *, char *, ...);
+
+PyObject *g_PyExc_ValueError;
+PyObject *g_PyExc_OSError;
+
+PyObject *(*g_PyErr_Format)(PyObject *, char *, ...);
+
+#define DEF_CSIDL(name) { name, #name }
+
+struct {
+	int nFolder;
+	char *name;
+} csidl_names[] = {
+	/* Startup menu for all users.
+	   NT only */
+	DEF_CSIDL(CSIDL_COMMON_STARTMENU),
+	/* Startup menu. */
+	DEF_CSIDL(CSIDL_STARTMENU),
+
+/*    DEF_CSIDL(CSIDL_COMMON_APPDATA), */
+/*    DEF_CSIDL(CSIDL_LOCAL_APPDATA), */
+	/* Repository for application-specific data.
+	   Needs Internet Explorer 4.0 */
+	DEF_CSIDL(CSIDL_APPDATA),
+
+	/* The desktop for all users.
+	   NT only */
+	DEF_CSIDL(CSIDL_COMMON_DESKTOPDIRECTORY),
+	/* The desktop. */
+	DEF_CSIDL(CSIDL_DESKTOPDIRECTORY),
+
+	/* Startup folder for all users.
+	   NT only */
+	DEF_CSIDL(CSIDL_COMMON_STARTUP),
+	/* Startup folder. */
+	DEF_CSIDL(CSIDL_STARTUP),
+
+	/* Programs item in the start menu for all users.
+	   NT only */
+	DEF_CSIDL(CSIDL_COMMON_PROGRAMS),
+	/* Program item in the user's start menu. */
+	DEF_CSIDL(CSIDL_PROGRAMS),
+
+/*    DEF_CSIDL(CSIDL_PROGRAM_FILES_COMMON), */
+/*    DEF_CSIDL(CSIDL_PROGRAM_FILES), */
+
+	/* Virtual folder containing fonts. */
+	DEF_CSIDL(CSIDL_FONTS),
+};
+
+#define DIM(a) (sizeof(a) / sizeof((a)[0]))
+
+static PyObject *FileCreated(PyObject *self, PyObject *args)
+{
+	char *path;
+	if (!g_PyArg_ParseTuple(args, "s", &path))
+		return NULL;
+	notify(FILE_CREATED, path);
+	return g_Py_BuildValue("");
+}
+
+static PyObject *DirectoryCreated(PyObject *self, PyObject *args)
+{
+	char *path;
+	if (!g_PyArg_ParseTuple(args, "s", &path))
+		return NULL;
+	notify(DIR_CREATED, path);
+	return g_Py_BuildValue("");
+}
+
+static PyObject *GetSpecialFolderPath(PyObject *self, PyObject *args)
+{
+	char *name;
+	char lpszPath[MAX_PATH];
+	int i;
+	static HRESULT (WINAPI *My_SHGetSpecialFolderPath)(HWND hwnd,
+							   LPTSTR lpszPath,
+							   int nFolder,
+							   BOOL fCreate);
+
+	if (!My_SHGetSpecialFolderPath) {
+		HINSTANCE hLib = LoadLibrary("shell32.dll");
+		if (!hLib) {
+			g_PyErr_Format(g_PyExc_OSError,
+				       "function not available");
+			return NULL;
+		}
+		My_SHGetSpecialFolderPath = (BOOL (WINAPI *)(HWND, LPTSTR,
+							     int, BOOL))
+			GetProcAddress(hLib,
+				       "SHGetSpecialFolderPathA");
+	}
+
+	if (!g_PyArg_ParseTuple(args, "s", &name))
+		return NULL;
+    
+	if (!My_SHGetSpecialFolderPath) {
+		g_PyErr_Format(g_PyExc_OSError, "function not available");
+		return NULL;
+	}
+
+	for (i = 0; i < DIM(csidl_names); ++i) {
+		if (0 == strcmpi(csidl_names[i].name, name)) {
+			int nFolder;
+			nFolder = csidl_names[i].nFolder;
+			if (My_SHGetSpecialFolderPath(NULL, lpszPath,
+						      nFolder, 0))
+				return g_Py_BuildValue("s", lpszPath);
+			else {
+				g_PyErr_Format(g_PyExc_OSError,
+					       "no such folder (%s)", name);
+				return NULL;
+			}
+		
+		}
+	};
+	g_PyErr_Format(g_PyExc_ValueError, "unknown CSIDL (%s)", name);
+	return NULL;
+}
+
+static PyObject *CreateShortcut(PyObject *self, PyObject *args)
+{
+	char *path; /* path and filename */
+	char *description;
+	char *filename;
+
+	char *arguments = NULL;
+	char *iconpath = NULL;
+	int iconindex = 0;
+	char *workdir = NULL;
+
+	WCHAR wszFilename[MAX_PATH];
+
+	IShellLink *ps1 = NULL;
+	IPersistFile *pPf = NULL;
+
+	HRESULT hr;
+
+	hr = CoInitialize(NULL);
+	if (FAILED(hr)) {
+		g_PyErr_Format(g_PyExc_OSError,
+			       "CoInitialize failed, error 0x%x", hr);
+		goto error;
+	}
+
+	if (!g_PyArg_ParseTuple(args, "sss|sssi",
+				&path, &description, &filename,
+				&arguments, &workdir, &iconpath, &iconindex))
+		return NULL;
+
+	hr = CoCreateInstance(&CLSID_ShellLink,
+			      NULL,
+			      CLSCTX_INPROC_SERVER,
+			      &IID_IShellLink,
+			      &ps1);
+	if (FAILED(hr)) {
+		g_PyErr_Format(g_PyExc_OSError,
+			       "CoCreateInstance failed, error 0x%x", hr);
+		goto error;
+	}
+
+	hr = ps1->lpVtbl->QueryInterface(ps1, &IID_IPersistFile,
+					 (void **)&pPf);
+	if (FAILED(hr)) {
+		g_PyErr_Format(g_PyExc_OSError,
+			       "QueryInterface(IPersistFile) error 0x%x", hr);
+		goto error;
+	}
+
+
+	hr = ps1->lpVtbl->SetPath(ps1, path);
+	if (FAILED(hr)) {
+		g_PyErr_Format(g_PyExc_OSError,
+			       "SetPath() failed, error 0x%x", hr);
+		goto error;
+	}
+
+	hr = ps1->lpVtbl->SetDescription(ps1, description);
+	if (FAILED(hr)) {
+		g_PyErr_Format(g_PyExc_OSError,
+			       "SetDescription() failed, error 0x%x", hr);
+		goto error;
+	}
+
+	if (arguments) {
+		hr = ps1->lpVtbl->SetArguments(ps1, arguments);
+		if (FAILED(hr)) {
+			g_PyErr_Format(g_PyExc_OSError,
+				       "SetArguments() error 0x%x", hr);
+			goto error;
+		}
+	}
+
+	if (iconpath) {
+		hr = ps1->lpVtbl->SetIconLocation(ps1, iconpath, iconindex);
+		if (FAILED(hr)) {
+			g_PyErr_Format(g_PyExc_OSError,
+				       "SetIconLocation() error 0x%x", hr);
+			goto error;
+		}
+	}
+
+	if (workdir) {
+		hr = ps1->lpVtbl->SetWorkingDirectory(ps1, workdir);
+		if (FAILED(hr)) {
+			g_PyErr_Format(g_PyExc_OSError,
+				       "SetWorkingDirectory() error 0x%x", hr);
+			goto error;
+		}
+	}
+
+	MultiByteToWideChar(CP_ACP, 0,
+			    filename, -1,
+			    wszFilename, MAX_PATH);
+			
+	hr = pPf->lpVtbl->Save(pPf, wszFilename, TRUE);
+	if (FAILED(hr)) {
+		g_PyErr_Format(g_PyExc_OSError,
+			       "Failed to create shortcut '%s' - error 0x%x", filename, hr);
+		goto error;
+	}
+    
+	pPf->lpVtbl->Release(pPf);
+	ps1->lpVtbl->Release(ps1);
+	CoUninitialize();
+	return g_Py_BuildValue("");
+    
+  error:
+	if (pPf)
+		pPf->lpVtbl->Release(pPf);
+
+	if (ps1)
+		ps1->lpVtbl->Release(ps1);
+
+	CoUninitialize();
+
+	return NULL;
+}
+
+static PyObject *PyMessageBox(PyObject *self, PyObject *args)
+{
+	int rc;
+	char *text, *caption;
+	int flags;
+	if (!g_PyArg_ParseTuple(args, "ssi", &text, &caption, &flags))
+		return NULL;
+	rc = MessageBox(GetFocus(), text, caption, flags);
+	return g_Py_BuildValue("i", rc);
+}
+
+static PyObject *GetRootHKey(PyObject *self)
+{
+	return g_Py_BuildValue("l", hkey_root);
+}
+
+#define METH_VARARGS 0x0001
+#define METH_NOARGS   0x0004
+typedef PyObject *(*PyCFunction)(PyObject *, PyObject *);
+
+PyMethodDef meth[] = {
+	{"create_shortcut", CreateShortcut, METH_VARARGS, NULL},
+	{"get_special_folder_path", GetSpecialFolderPath, METH_VARARGS, NULL},
+	{"get_root_hkey", (PyCFunction)GetRootHKey, METH_NOARGS, NULL},
+	{"file_created", FileCreated, METH_VARARGS, NULL},
+	{"directory_created", DirectoryCreated, METH_VARARGS, NULL},
+	{"message_box", PyMessageBox, METH_VARARGS, NULL},
+};
+
+static HINSTANCE LoadPythonDll(char *fname)
+{
+	char fullpath[_MAX_PATH];
+	LONG size = sizeof(fullpath);
+	char subkey_name[80];
+	char buffer[260 + 12];
+	HINSTANCE h;
+
+	/* make sure PYTHONHOME is set, to that sys.path is initialized correctly */
+	wsprintf(buffer, "PYTHONHOME=%s", python_dir);
+	_putenv(buffer);
+	h = LoadLibrary(fname);
+	if (h)
+		return h;
+	wsprintf(subkey_name,
+		 "SOFTWARE\\Python\\PythonCore\\%d.%d\\InstallPath",
+		 py_major, py_minor);
+	if (ERROR_SUCCESS != RegQueryValue(HKEY_CURRENT_USER, subkey_name,
+					   fullpath, &size))
+		return NULL;
+	strcat(fullpath, "\\");
+	strcat(fullpath, fname);
+	return LoadLibrary(fullpath);
+}
+
+static int prepare_script_environment(HINSTANCE hPython)
+{
+	PyObject *mod;
+	DECLPROC(hPython, PyObject *, PyImport_ImportModule, (char *));
+	DECLPROC(hPython, int, PyObject_SetAttrString, (PyObject *, char *, PyObject *));
+	DECLPROC(hPython, PyObject *, PyObject_GetAttrString, (PyObject *, char *));
+	DECLPROC(hPython, PyObject *, PyCFunction_New, (PyMethodDef *, PyObject *));
+	DECLPROC(hPython, PyObject *, Py_BuildValue, (char *, ...));
+	DECLPROC(hPython, int, PyArg_ParseTuple, (PyObject *, char *, ...));
+	DECLPROC(hPython, PyObject *, PyErr_Format, (PyObject *, char *));
+	if (!PyImport_ImportModule || !PyObject_GetAttrString || 
+	    !PyObject_SetAttrString || !PyCFunction_New)
+		return 1;
+	if (!Py_BuildValue || !PyArg_ParseTuple || !PyErr_Format)
+		return 1;
+
+	mod = PyImport_ImportModule("__builtin__");
+	if (mod) {
+		int i;
+		g_PyExc_ValueError = PyObject_GetAttrString(mod, "ValueError");
+		g_PyExc_OSError = PyObject_GetAttrString(mod, "OSError");
+		for (i = 0; i < DIM(meth); ++i) {
+			PyObject_SetAttrString(mod, meth[i].ml_name,
+					       PyCFunction_New(&meth[i], NULL));
+		}
+	}
+	g_Py_BuildValue = Py_BuildValue;
+	g_PyArg_ParseTuple = PyArg_ParseTuple;
+	g_PyErr_Format = PyErr_Format;
+
+	return 0;
+}
+
+/*
+ * This function returns one of the following error codes:
+ * 1 if the Python-dll does not export the functions we need
+ * 2 if no install-script is specified in pathname
+ * 3 if the install-script file could not be opened
+ * the return value of PyRun_SimpleString() otherwise,
+ * which is 0 if everything is ok, -1 if an exception had occurred
+ * in the install-script.
+ */
+
+static int
+run_installscript(HINSTANCE hPython, char *pathname, int argc, char **argv)
+{
+	DECLPROC(hPython, void, Py_Initialize, (void));
+	DECLPROC(hPython, int, PySys_SetArgv, (int, char **));
+	DECLPROC(hPython, int, PyRun_SimpleString, (char *));
+	DECLPROC(hPython, void, Py_Finalize, (void));
+	DECLPROC(hPython, PyObject *, Py_BuildValue, (char *, ...));
+	DECLPROC(hPython, PyObject *, PyCFunction_New,
+		 (PyMethodDef *, PyObject *));
+	DECLPROC(hPython, int, PyArg_ParseTuple, (PyObject *, char *, ...));
+	DECLPROC(hPython, PyObject *, PyErr_Format, (PyObject *, char *));
+
+	int result = 0;
+	int fh;
+
+	if (!Py_Initialize || !PySys_SetArgv
+	    || !PyRun_SimpleString || !Py_Finalize)
+		return 1;
+	
+	if (!Py_BuildValue || !PyArg_ParseTuple || !PyErr_Format)
+		return 1;
+
+	if (!PyCFunction_New || !PyArg_ParseTuple || !PyErr_Format)
+		return 1;
+
+	if (pathname == NULL || pathname[0] == '\0')
+		return 2;
+
+	fh = open(pathname, _O_RDONLY);
+	if (-1 == fh) {
+		fprintf(stderr, "Could not open postinstall-script %s\n",
+			pathname);
+		return 3;
+	}
+
+	SetDlgItemText(hDialog, IDC_INFO, "Running Script...");
+		
+	Py_Initialize();
+
+	prepare_script_environment(hPython);
+	PySys_SetArgv(argc, argv);
+	result = 3;
+	{
+		struct _stat statbuf;
+		if(0 == _fstat(fh, &statbuf)) {
+			char *script = alloca(statbuf.st_size + 5);
+			int n = read(fh, script, statbuf.st_size);
+			if (n > 0) {
+				script[n] = '\n';
+				script[n+1] = 0;
+				result = PyRun_SimpleString(script);
+			}
+		}
+	}
+	Py_Finalize();
+
+	close(fh);
+
+	return result;
+}
+
+static int do_run_simple_script(HINSTANCE hPython, char *script)
+{
+	int rc;
+	DECLPROC(hPython, void, Py_Initialize, (void));
+	DECLPROC(hPython, void, Py_SetProgramName, (char *));
+	DECLPROC(hPython, void, Py_Finalize, (void));
+	DECLPROC(hPython, int, PyRun_SimpleString, (char *));
+	DECLPROC(hPython, void, PyErr_Print, (void));
+
+	if (!Py_Initialize || !Py_SetProgramName || !Py_Finalize || 
+	    !PyRun_SimpleString || !PyErr_Print)
+		return -1;
+
+	Py_SetProgramName(modulename);
+	Py_Initialize();
+	prepare_script_environment(hPython);
+	rc = PyRun_SimpleString(script);
+	if (rc)
+		PyErr_Print();
+	Py_Finalize();
+	return rc;
+}
+
+static int run_simple_script(char *script)
+{
+	int rc;
+	char *tempname;
+	HINSTANCE hPython;
+	tempname = tempnam(NULL, NULL);
+	freopen(tempname, "a", stderr);
+	freopen(tempname, "a", stdout);
+
+	hPython = LoadPythonDll(pythondll);
+	if (!hPython) {
+		set_failure_reason("Can't load Python for pre-install script");
+		return -1;
+	}
+	rc = do_run_simple_script(hPython, script);
+	FreeLibrary(hPython);
+	fflush(stderr);
+	fclose(stderr);
+	fflush(stdout);
+	fclose(stdout);
+	/* We only care about the output when we fail.  If the script works
+	   OK, then we discard it
+	*/
+	if (rc) {
+		int err_buf_size;
+		char *err_buf;
+		const char *prefix = "Running the pre-installation script failed\r\n";
+		int prefix_len = strlen(prefix);
+		FILE *fp = fopen(tempname, "rb");
+		fseek(fp, 0, SEEK_END);
+		err_buf_size = ftell(fp);
+		fseek(fp, 0, SEEK_SET);
+		err_buf = malloc(prefix_len + err_buf_size + 1);
+		if (err_buf) {
+			int n;
+			strcpy(err_buf, prefix);
+			n = fread(err_buf+prefix_len, 1, err_buf_size, fp);
+			err_buf[prefix_len+n] = '\0';
+			fclose(fp);
+			set_failure_reason(err_buf);
+			free(err_buf);
+		} else {
+			set_failure_reason("Out of memory!");
+		}
+	}
+	remove(tempname);
+	return rc;
+}
+
+
+static BOOL SystemError(int error, char *msg)
+{
+	char Buffer[1024];
+	int n;
+
+	if (error) {
+		LPVOID lpMsgBuf;
+		FormatMessage( 
+			FORMAT_MESSAGE_ALLOCATE_BUFFER | 
+			FORMAT_MESSAGE_FROM_SYSTEM,
+			NULL,
+			error,
+			MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+			(LPSTR)&lpMsgBuf,
+			0,
+			NULL 
+			);
+		strncpy(Buffer, lpMsgBuf, sizeof(Buffer));
+		LocalFree(lpMsgBuf);
+	} else
+		Buffer[0] = '\0';
+	n = lstrlen(Buffer);
+	_snprintf(Buffer+n, sizeof(Buffer)-n, msg);
+	MessageBox(hwndMain, Buffer, "Runtime Error", MB_OK | MB_ICONSTOP);
+	return FALSE;
+}
+
+static BOOL notify (int code, char *fmt, ...)
+{
+	char Buffer[1024];
+	va_list marker;
+	BOOL result = TRUE;
+	int a, b;
+	char *cp;
+
+	va_start(marker, fmt);
+	_vsnprintf(Buffer, sizeof(Buffer), fmt, marker);
+
+	switch (code) {
+/* Questions */
+	case CAN_OVERWRITE:
+		break;
+
+/* Information notification */
+	case DIR_CREATED:
+		if (logfile)
+			fprintf(logfile, "100 Made Dir: %s\n", fmt);
+		break;
+
+	case FILE_CREATED:
+		if (logfile)
+			fprintf(logfile, "200 File Copy: %s\n", fmt);
+		goto add_to_filelist_label;
+		break;
+
+	case FILE_OVERWRITTEN:
+		if (logfile)
+			fprintf(logfile, "200 File Overwrite: %s\n", fmt);
+	  add_to_filelist_label:
+		if ((cp = strrchr(fmt, '.')) && (0 == strcmp (cp, ".py")))
+			add_to_filelist(fmt);
+		break;
+
+/* Error Messages */
+	case ZLIB_ERROR:
+		MessageBox(GetFocus(), Buffer, "Error",
+			    MB_OK | MB_ICONWARNING);
+		break;
+
+	case SYSTEM_ERROR:
+		SystemError(GetLastError(), Buffer);
+		break;
+
+	case NUM_FILES:
+		a = va_arg(marker, int);
+		b = va_arg(marker, int);
+		SendMessage(hDialog, WM_NUMFILES, 0, MAKELPARAM(0, a));
+		SendMessage(hDialog, WM_NEXTFILE, b,(LPARAM)fmt);
+	}
+	va_end(marker);
+    
+	return result;
+}
+
+static char *MapExistingFile(char *pathname, DWORD *psize)
+{
+	HANDLE hFile, hFileMapping;
+	DWORD nSizeLow, nSizeHigh;
+	char *data;
+
+	hFile = CreateFile(pathname,
+			    GENERIC_READ, FILE_SHARE_READ, NULL,
+			    OPEN_EXISTING,
+			    FILE_ATTRIBUTE_NORMAL, NULL);
+	if (hFile == INVALID_HANDLE_VALUE)
+		return NULL;
+	nSizeLow = GetFileSize(hFile, &nSizeHigh);
+	hFileMapping = CreateFileMapping(hFile,
+					  NULL, PAGE_READONLY, 0, 0, NULL);
+	CloseHandle(hFile);
+
+	if (hFileMapping == INVALID_HANDLE_VALUE)
+		return NULL;
+    
+	data = MapViewOfFile(hFileMapping,
+			      FILE_MAP_READ, 0, 0, 0);
+
+	CloseHandle(hFileMapping);
+	*psize = nSizeLow;
+	return data;
+}
+
+
+static void create_bitmap(HWND hwnd)
+{
+	BITMAPFILEHEADER *bfh;
+	BITMAPINFO *bi;
+	HDC hdc;
+
+	if (!bitmap_bytes)
+		return;
+
+	if (hBitmap)
+		return;
+
+	hdc = GetDC(hwnd);
+
+	bfh = (BITMAPFILEHEADER *)bitmap_bytes;
+	bi = (BITMAPINFO *)(bitmap_bytes + sizeof(BITMAPFILEHEADER));
+
+	hBitmap = CreateDIBitmap(hdc,
+				 &bi->bmiHeader,
+				 CBM_INIT,
+				 bitmap_bytes + bfh->bfOffBits,
+				 bi,
+				 DIB_RGB_COLORS);
+	ReleaseDC(hwnd, hdc);
+}
+
+/* Extract everything we need to begin the installation.  Currently this
+   is the INI filename with install data, and the raw pre-install script
+*/
+static BOOL ExtractInstallData(char *data, DWORD size, int *pexe_size,
+			       char **out_ini_file, char **out_preinstall_script)
+{
+	/* read the end of central directory record */
+	struct eof_cdir *pe = (struct eof_cdir *)&data[size - sizeof
+						       (struct eof_cdir)];
+    
+	int arc_start = size - sizeof (struct eof_cdir) - pe->nBytesCDir -
+		pe->ofsCDir;
+
+	int ofs = arc_start - sizeof (struct meta_data_hdr);
+
+	/* read meta_data info */
+	struct meta_data_hdr *pmd = (struct meta_data_hdr *)&data[ofs];
+	char *src, *dst;
+	char *ini_file;
+	char tempdir[MAX_PATH];
+
+	/* ensure that if we fail, we don't have garbage out pointers */
+	*out_ini_file = *out_preinstall_script = NULL;
+
+	if (pe->tag != 0x06054b50) {
+		return FALSE;
+	}
+
+	if (pmd->tag != 0x1234567B) {
+		return SystemError(0,
+			   "Invalid cfgdata magic number (see bdist_wininst.py)");
+	}
+	if (ofs < 0) {
+		return FALSE;
+	}
+
+	if (pmd->bitmap_size) {
+		/* Store pointer to bitmap bytes */
+		bitmap_bytes = (char *)pmd - pmd->uncomp_size - pmd->bitmap_size;
+	}
+
+	*pexe_size = ofs - pmd->uncomp_size - pmd->bitmap_size;
+
+	src = ((char *)pmd) - pmd->uncomp_size;
+	ini_file = malloc(MAX_PATH); /* will be returned, so do not free it */
+	if (!ini_file)
+		return FALSE;
+	if (!GetTempPath(sizeof(tempdir), tempdir)
+	    || !GetTempFileName(tempdir, "~du", 0, ini_file)) {
+		SystemError(GetLastError(),
+			     "Could not create temporary file");
+		return FALSE;
+	}
+    
+	dst = map_new_file(CREATE_ALWAYS, ini_file, NULL, pmd->uncomp_size,
+			    0, 0, NULL/*notify*/);
+	if (!dst)
+		return FALSE;
+	/* Up to the first \0 is the INI file data. */
+	strncpy(dst, src, pmd->uncomp_size);
+	src += strlen(dst) + 1;
+	/* Up to next \0 is the pre-install script */
+	*out_preinstall_script = strdup(src);
+	*out_ini_file = ini_file;
+	UnmapViewOfFile(dst);
+	return TRUE;
+}
+
+static void PumpMessages(void)
+{
+	MSG msg;
+	while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
+		TranslateMessage(&msg);
+		DispatchMessage(&msg);
+	}
+}
+
+LRESULT CALLBACK
+WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+	HDC hdc;
+	HFONT hFont;
+	int h;
+	PAINTSTRUCT ps;
+	switch (msg) {
+	case WM_PAINT:
+		hdc = BeginPaint(hwnd, &ps);
+		h = GetSystemMetrics(SM_CYSCREEN) / 10;
+		hFont = CreateFont(h, 0, 0, 0, 700, TRUE,
+				    0, 0, 0, 0, 0, 0, 0, "Times Roman");
+		hFont = SelectObject(hdc, hFont);
+		SetBkMode(hdc, TRANSPARENT);
+		TextOut(hdc, 15, 15, title, strlen(title));
+		SetTextColor(hdc, RGB(255, 255, 255));
+		TextOut(hdc, 10, 10, title, strlen(title));
+		DeleteObject(SelectObject(hdc, hFont));
+		EndPaint(hwnd, &ps);
+		return 0;
+	}
+	return DefWindowProc(hwnd, msg, wParam, lParam);
+}
+
+static HWND CreateBackground(char *title)
+{
+	WNDCLASS wc;
+	HWND hwnd;
+	char buffer[4096];
+
+	wc.style = CS_VREDRAW | CS_HREDRAW;
+	wc.lpfnWndProc = WindowProc;
+	wc.cbWndExtra = 0;
+	wc.cbClsExtra = 0;
+	wc.hInstance = GetModuleHandle(NULL);
+	wc.hIcon = NULL;
+	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+	wc.hbrBackground = CreateSolidBrush(RGB(0, 0, 128));
+	wc.lpszMenuName = NULL;
+	wc.lpszClassName = "SetupWindowClass";
+
+	if (!RegisterClass(&wc))
+		MessageBox(hwndMain,
+			    "Could not register window class",
+			    "Setup.exe", MB_OK);
+
+	wsprintf(buffer, "Setup %s", title);
+	hwnd = CreateWindow("SetupWindowClass",
+			     buffer,
+			     0,
+			     0, 0,
+			     GetSystemMetrics(SM_CXFULLSCREEN),
+			     GetSystemMetrics(SM_CYFULLSCREEN),
+			     NULL,
+			     NULL,
+			     GetModuleHandle(NULL),
+			     NULL);
+	ShowWindow(hwnd, SW_SHOWMAXIMIZED);
+	UpdateWindow(hwnd);
+	return hwnd;
+}
+
+/*
+ * Center a window on the screen
+ */
+static void CenterWindow(HWND hwnd)
+{
+	RECT rc;
+	int w, h;
+
+	GetWindowRect(hwnd, &rc);
+	w = GetSystemMetrics(SM_CXSCREEN);
+	h = GetSystemMetrics(SM_CYSCREEN);
+	MoveWindow(hwnd,
+		   (w - (rc.right-rc.left))/2,
+		   (h - (rc.bottom-rc.top))/2,
+		    rc.right-rc.left, rc.bottom-rc.top, FALSE);
+}
+
+#include <prsht.h>
+
+BOOL CALLBACK
+IntroDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+	LPNMHDR lpnm;
+	char Buffer[4096];
+
+	switch (msg) {
+	case WM_INITDIALOG:
+		create_bitmap(hwnd);
+		if(hBitmap)
+			SendDlgItemMessage(hwnd, IDC_BITMAP, STM_SETIMAGE,
+					   IMAGE_BITMAP, (LPARAM)hBitmap);
+		CenterWindow(GetParent(hwnd));
+		wsprintf(Buffer,
+			  "This Wizard will install %s on your computer. "
+			  "Click Next to continue "
+			  "or Cancel to exit the Setup Wizard.",
+			  meta_name);
+		SetDlgItemText(hwnd, IDC_TITLE, Buffer);
+		SetDlgItemText(hwnd, IDC_INTRO_TEXT, info);
+		SetDlgItemText(hwnd, IDC_BUILD_INFO, build_info);
+		return FALSE;
+
+	case WM_NOTIFY:
+		lpnm = (LPNMHDR) lParam;
+
+		switch (lpnm->code) {
+		case PSN_SETACTIVE:
+			PropSheet_SetWizButtons(GetParent(hwnd), PSWIZB_NEXT);
+			break;
+
+		case PSN_WIZNEXT:
+			break;
+
+		case PSN_RESET:
+			break;
+		
+		default:
+			break;
+		}
+	}
+	return FALSE;
+}
+
+#ifdef USE_OTHER_PYTHON_VERSIONS
+/* These are really private variables used to communicate
+ * between StatusRoutine and CheckPythonExe
+ */
+char bound_image_dll[_MAX_PATH];
+int bound_image_major;
+int bound_image_minor;
+
+static BOOL __stdcall StatusRoutine(IMAGEHLP_STATUS_REASON reason,
+				    PSTR ImageName,
+				    PSTR DllName,
+				    ULONG Va,
+				    ULONG Parameter)
+{
+	char fname[_MAX_PATH];
+	int int_version;
+
+	switch(reason) {
+	case BindOutOfMemory:
+	case BindRvaToVaFailed:
+	case BindNoRoomInImage:
+	case BindImportProcedureFailed:
+		break;
+
+	case BindImportProcedure:
+	case BindForwarder:
+	case BindForwarderNOT:
+	case BindImageModified:
+	case BindExpandFileHeaders:
+	case BindImageComplete:
+	case BindSymbolsNotUpdated:
+	case BindMismatchedSymbols:
+	case BindImportModuleFailed:
+		break;
+
+	case BindImportModule:
+		if (1 == sscanf(DllName, "python%d", &int_version)) {
+			SearchPath(NULL, DllName, NULL, sizeof(fname),
+				   fname, NULL);
+			strcpy(bound_image_dll, fname);
+			bound_image_major = int_version / 10;
+			bound_image_minor = int_version % 10;
+			OutputDebugString("BOUND ");
+			OutputDebugString(fname);
+			OutputDebugString("\n");
+		}
+		break;
+	}
+	return TRUE;
+}
+
+/*
+ */
+static LPSTR get_sys_prefix(LPSTR exe, LPSTR dll)
+{
+	void (__cdecl * Py_Initialize)(void);
+	void (__cdecl * Py_SetProgramName)(char *);
+	void (__cdecl * Py_Finalize)(void);
+	void* (__cdecl * PySys_GetObject)(char *);
+	void (__cdecl * PySys_SetArgv)(int, char **);
+	char* (__cdecl * Py_GetPrefix)(void);
+	char* (__cdecl * Py_GetPath)(void);
+	HINSTANCE hPython;
+	LPSTR prefix = NULL;
+	int (__cdecl * PyRun_SimpleString)(char *);
+
+	{
+		char Buffer[256];
+		wsprintf(Buffer, "PYTHONHOME=%s", exe);
+		*strrchr(Buffer, '\\') = '\0';
+//	MessageBox(GetFocus(), Buffer, "PYTHONHOME", MB_OK);
+		_putenv(Buffer);
+		_putenv("PYTHONPATH=");
+	}
+
+	hPython = LoadLibrary(dll);
+	if (!hPython)
+		return NULL;
+	Py_Initialize = (void (*)(void))GetProcAddress
+		(hPython,"Py_Initialize");
+
+	PySys_SetArgv = (void (*)(int, char **))GetProcAddress
+		(hPython,"PySys_SetArgv");
+
+	PyRun_SimpleString = (int (*)(char *))GetProcAddress
+		(hPython,"PyRun_SimpleString");
+
+	Py_SetProgramName = (void (*)(char *))GetProcAddress
+		(hPython,"Py_SetProgramName");
+
+	PySys_GetObject = (void* (*)(char *))GetProcAddress
+		(hPython,"PySys_GetObject");
+
+	Py_GetPrefix = (char * (*)(void))GetProcAddress
+		(hPython,"Py_GetPrefix");
+
+	Py_GetPath = (char * (*)(void))GetProcAddress
+		(hPython,"Py_GetPath");
+
+	Py_Finalize = (void (*)(void))GetProcAddress(hPython,
+						      "Py_Finalize");
+	Py_SetProgramName(exe);
+	Py_Initialize();
+	PySys_SetArgv(1, &exe);
+
+	MessageBox(GetFocus(), Py_GetPrefix(), "PREFIX", MB_OK);
+	MessageBox(GetFocus(), Py_GetPath(), "PATH", MB_OK);
+
+	Py_Finalize();
+	FreeLibrary(hPython);
+
+	return prefix;
+}
+
+static BOOL
+CheckPythonExe(LPSTR pathname, LPSTR version, int *pmajor, int *pminor)
+{
+	bound_image_dll[0] = '\0';
+	if (!BindImageEx(BIND_NO_BOUND_IMPORTS | BIND_NO_UPDATE | BIND_ALL_IMAGES,
+			 pathname,
+			 NULL,
+			 NULL,
+			 StatusRoutine))
+		return SystemError(0, "Could not bind image");
+	if (bound_image_dll[0] == '\0')
+		return SystemError(0, "Does not seem to be a python executable");
+	*pmajor = bound_image_major;
+	*pminor = bound_image_minor;
+	if (version && *version) {
+		char core_version[12];
+		wsprintf(core_version, "%d.%d", bound_image_major, bound_image_minor);
+		if (strcmp(version, core_version))
+			return SystemError(0, "Wrong Python version");
+	}
+	get_sys_prefix(pathname, bound_image_dll);
+	return TRUE;
+}
+
+/*
+ * Browse for other python versions. Insert it into the listbox specified
+ * by hwnd. version, if not NULL or empty, is the version required.
+ */
+static BOOL GetOtherPythonVersion(HWND hwnd, LPSTR version)
+{
+	char vers_name[_MAX_PATH + 80];
+	DWORD itemindex;
+	OPENFILENAME of;
+	char pathname[_MAX_PATH];
+	DWORD result;
+
+	strcpy(pathname, "python.exe");
+
+	memset(&of, 0, sizeof(of));
+	of.lStructSize = sizeof(OPENFILENAME);
+	of.hwndOwner = GetParent(hwnd);
+	of.hInstance = NULL;
+	of.lpstrFilter = "python.exe\0python.exe\0";
+	of.lpstrCustomFilter = NULL;
+	of.nMaxCustFilter = 0;
+	of.nFilterIndex = 1;
+	of.lpstrFile = pathname;
+	of.nMaxFile = sizeof(pathname);
+	of.lpstrFileTitle = NULL;
+	of.nMaxFileTitle = 0;
+	of.lpstrInitialDir = NULL;
+	of.lpstrTitle = "Python executable";
+	of.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;
+	of.lpstrDefExt = "exe";
+
+	result = GetOpenFileName(&of);
+	if (result) {
+		int major, minor;
+		if (!CheckPythonExe(pathname, version, &major, &minor)) {
+			return FALSE;
+		}
+		*strrchr(pathname, '\\') = '\0';
+		wsprintf(vers_name, "Python Version %d.%d in %s",
+			  major, minor, pathname);
+		itemindex = SendMessage(hwnd, LB_INSERTSTRING, -1,
+					(LPARAM)(LPSTR)vers_name);
+		SendMessage(hwnd, LB_SETCURSEL, itemindex, 0);
+		SendMessage(hwnd, LB_SETITEMDATA, itemindex,
+			    (LPARAM)(LPSTR)strdup(pathname));
+		return TRUE;
+	}
+	return FALSE;
+}
+#endif /* USE_OTHER_PYTHON_VERSIONS */
+
+typedef struct _InstalledVersionInfo {
+    char prefix[MAX_PATH+1]; // sys.prefix directory.
+    HKEY hkey; // Is this Python in HKCU or HKLM?
+} InstalledVersionInfo;
+
+
+/*
+ * Fill the listbox specified by hwnd with all python versions found
+ * in the registry. version, if not NULL or empty, is the version
+ * required.
+ */
+static BOOL GetPythonVersions(HWND hwnd, HKEY hkRoot, LPSTR version)
+{
+	DWORD index = 0;
+	char core_version[80];
+	HKEY hKey;
+	BOOL result = TRUE;
+	DWORD bufsize;
+
+	if (ERROR_SUCCESS != RegOpenKeyEx(hkRoot,
+					   "Software\\Python\\PythonCore",
+					   0,	KEY_READ, &hKey))
+		return FALSE;
+	bufsize = sizeof(core_version);
+	while (ERROR_SUCCESS == RegEnumKeyEx(hKey, index,
+					      core_version, &bufsize, NULL,
+					      NULL, NULL, NULL)) {
+		char subkey_name[80], vers_name[80];
+		int itemindex;
+		DWORD value_size;
+		HKEY hk;
+
+		bufsize = sizeof(core_version);
+		++index;
+		if (version && *version && strcmp(version, core_version))
+			continue;
+
+		wsprintf(vers_name, "Python Version %s (found in registry)",
+			  core_version);
+		wsprintf(subkey_name,
+			  "Software\\Python\\PythonCore\\%s\\InstallPath",
+			  core_version);
+		if (ERROR_SUCCESS == RegOpenKeyEx(hkRoot, subkey_name, 0, KEY_READ, &hk)) {
+			InstalledVersionInfo *ivi = 
+			      (InstalledVersionInfo *)malloc(sizeof(InstalledVersionInfo));
+			value_size = sizeof(ivi->prefix);
+			if (ivi && 
+			    ERROR_SUCCESS == RegQueryValueEx(hk, NULL, NULL, NULL,
+			                                     ivi->prefix, &value_size)) {
+				itemindex = SendMessage(hwnd, LB_ADDSTRING, 0,
+				                        (LPARAM)(LPSTR)vers_name);
+				ivi->hkey = hkRoot;
+				SendMessage(hwnd, LB_SETITEMDATA, itemindex,
+				            (LPARAM)(LPSTR)ivi);
+			}
+			RegCloseKey(hk);
+		}
+	}
+	RegCloseKey(hKey);
+	return result;
+}
+
+/* Determine if the current user can write to HKEY_LOCAL_MACHINE */
+BOOL HasLocalMachinePrivs()
+{
+		HKEY hKey;
+		DWORD result;
+		static char KeyName[] = 
+			"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
+
+		result = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+					  KeyName,
+					  0,
+					  KEY_CREATE_SUB_KEY,
+					  &hKey);
+		if (result==0)
+			RegCloseKey(hKey);
+		return result==0;
+}
+
+// Check the root registry key to use - either HKLM or HKCU.
+// If Python is installed in HKCU, then our extension also must be installed
+// in HKCU - as Python won't be available for other users, we shouldn't either
+// (and will fail if we are!)
+// If Python is installed in HKLM, then we will also prefer to use HKLM, but
+// this may not be possible - so we silently fall back to HKCU.
+//
+// We assume hkey_root is already set to where Python itself is installed.
+void CheckRootKey(HWND hwnd)
+{
+	if (hkey_root==HKEY_CURRENT_USER) {
+		; // as above, always install ourself in HKCU too.
+	} else if (hkey_root==HKEY_LOCAL_MACHINE) {
+		// Python in HKLM, but we may or may not have permissions there.
+		// Open the uninstall key with 'create' permissions - if this fails,
+		// we don't have permission.
+		if (!HasLocalMachinePrivs())
+			hkey_root = HKEY_CURRENT_USER;
+	} else {
+		MessageBox(hwnd, "Don't know Python's installation type",
+				   "Strange", MB_OK | MB_ICONSTOP);
+		/* Default to wherever they can, but preferring HKLM */
+		hkey_root = HasLocalMachinePrivs() ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
+	}
+}
+
+/* Return the installation scheme depending on Python version number */
+SCHEME *GetScheme(int major, int minor)
+{
+	if (major > 2)
+		return new_scheme;
+	else if((major == 2) && (minor >= 2))
+		return new_scheme;
+	return old_scheme;
+}
+
+BOOL CALLBACK
+SelectPythonDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+	LPNMHDR lpnm;
+
+	switch (msg) {
+	case WM_INITDIALOG:
+		if (hBitmap)
+			SendDlgItemMessage(hwnd, IDC_BITMAP, STM_SETIMAGE,
+					   IMAGE_BITMAP, (LPARAM)hBitmap);
+		GetPythonVersions(GetDlgItem(hwnd, IDC_VERSIONS_LIST),
+				   HKEY_LOCAL_MACHINE, target_version);
+		GetPythonVersions(GetDlgItem(hwnd, IDC_VERSIONS_LIST),
+				   HKEY_CURRENT_USER, target_version);
+		{	/* select the last entry which is the highest python
+			   version found */
+			int count;
+			count = SendDlgItemMessage(hwnd, IDC_VERSIONS_LIST,
+						    LB_GETCOUNT, 0, 0);
+			if (count && count != LB_ERR)
+				SendDlgItemMessage(hwnd, IDC_VERSIONS_LIST, LB_SETCURSEL,
+						    count-1, 0);
+	    
+			/* If a specific Python version is required,
+			 * display a prominent notice showing this fact.
+			 */
+			if (target_version && target_version[0]) {
+				char buffer[4096];
+				wsprintf(buffer,
+					 "Python %s is required for this package. "
+					 "Select installation to use:",
+					 target_version);
+				SetDlgItemText(hwnd, IDC_TITLE, buffer);
+			}
+
+			if (count == 0) {
+				char Buffer[4096];
+				char *msg;
+				if (target_version && target_version[0]) {
+					wsprintf(Buffer,
+						 "Python version %s required, which was not found"
+						 " in the registry.", target_version);
+					msg = Buffer;
+				} else
+					msg = "No Python installation found in the registry.";
+				MessageBox(hwnd, msg, "Cannot install",
+					   MB_OK | MB_ICONSTOP);
+			}
+		}
+		goto UpdateInstallDir;
+		break;
+
+	case WM_COMMAND:
+		switch (LOWORD(wParam)) {
+/*
+  case IDC_OTHERPYTHON:
+  if (GetOtherPythonVersion(GetDlgItem(hwnd, IDC_VERSIONS_LIST),
+  target_version))
+  goto UpdateInstallDir;
+  break;
+*/
+		case IDC_VERSIONS_LIST:
+			switch (HIWORD(wParam)) {
+				int id;
+			case LBN_SELCHANGE:
+			  UpdateInstallDir:
+				PropSheet_SetWizButtons(GetParent(hwnd),
+							PSWIZB_BACK | PSWIZB_NEXT);
+				id = SendDlgItemMessage(hwnd, IDC_VERSIONS_LIST,
+							 LB_GETCURSEL, 0, 0);
+				if (id == LB_ERR) {
+					PropSheet_SetWizButtons(GetParent(hwnd),
+								PSWIZB_BACK);
+					SetDlgItemText(hwnd, IDC_PATH, "");
+					SetDlgItemText(hwnd, IDC_INSTALL_PATH, "");
+					strcpy(python_dir, "");
+					strcpy(pythondll, "");
+				} else {
+					char *pbuf;
+					int result;
+					InstalledVersionInfo *ivi;
+					PropSheet_SetWizButtons(GetParent(hwnd),
+								PSWIZB_BACK | PSWIZB_NEXT);
+					/* Get the python directory */
+                    ivi = (InstalledVersionInfo *)
+                                SendDlgItemMessage(hwnd,
+									IDC_VERSIONS_LIST,
+									LB_GETITEMDATA,
+									id,
+									0);
+                    hkey_root = ivi->hkey;
+					strcpy(python_dir, ivi->prefix);
+					SetDlgItemText(hwnd, IDC_PATH, python_dir);
+					/* retrieve the python version and pythondll to use */
+					result = SendDlgItemMessage(hwnd, IDC_VERSIONS_LIST,
+								     LB_GETTEXTLEN, (WPARAM)id, 0);
+					pbuf = (char *)malloc(result + 1);
+					if (pbuf) {
+						/* guess the name of the python-dll */
+						SendDlgItemMessage(hwnd, IDC_VERSIONS_LIST,
+								    LB_GETTEXT, (WPARAM)id,
+								    (LPARAM)pbuf);
+						result = sscanf(pbuf, "Python Version %d.%d",
+								 &py_major, &py_minor);
+						if (result == 2) {
+#ifdef _DEBUG
+							wsprintf(pythondll, "python%d%d_d.dll",
+								 py_major, py_minor);
+#else
+							wsprintf(pythondll, "python%d%d.dll",
+								 py_major, py_minor);
+#endif
+						}
+						free(pbuf);
+					} else
+						strcpy(pythondll, "");
+					/* retrieve the scheme for this version */
+					{
+						char install_path[_MAX_PATH];
+						SCHEME *scheme = GetScheme(py_major, py_minor);
+						strcpy(install_path, python_dir);
+						if (install_path[strlen(install_path)-1] != '\\')
+							strcat(install_path, "\\");
+						strcat(install_path, scheme[0].prefix);
+						SetDlgItemText(hwnd, IDC_INSTALL_PATH, install_path);
+					}
+				}
+			}
+			break;
+		}
+		return 0;
+
+	case WM_NOTIFY:
+		lpnm = (LPNMHDR) lParam;
+
+		switch (lpnm->code) {
+			int id;
+		case PSN_SETACTIVE:
+			id = SendDlgItemMessage(hwnd, IDC_VERSIONS_LIST,
+						 LB_GETCURSEL, 0, 0);
+			if (id == LB_ERR)
+				PropSheet_SetWizButtons(GetParent(hwnd),
+							PSWIZB_BACK);
+			else
+				PropSheet_SetWizButtons(GetParent(hwnd),
+							PSWIZB_BACK | PSWIZB_NEXT);
+			break;
+
+		case PSN_WIZNEXT:
+			break;
+
+		case PSN_WIZFINISH:
+			break;
+
+		case PSN_RESET:
+			break;
+		
+		default:
+			break;
+		}
+	}
+	return 0;
+}
+
+static BOOL OpenLogfile(char *dir)
+{
+	char buffer[_MAX_PATH+1];
+	time_t ltime;
+	struct tm *now;
+	long result;
+	HKEY hKey, hSubkey;
+	char subkey_name[256];
+	static char KeyName[] = 
+		"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
+	const char *root_name = (hkey_root==HKEY_LOCAL_MACHINE ?
+	                        "HKEY_LOCAL_MACHINE" : "HKEY_CURRENT_USER");
+	DWORD disposition;
+
+	/* Use Create, as the Uninstall subkey may not exist under HKCU.
+	   Use CreateKeyEx, so we can specify a SAM specifying write access
+	*/
+		result = RegCreateKeyEx(hkey_root,
+			      KeyName,
+			      0, /* reserved */
+			      NULL, /* class */
+			      0, /* options */
+			      KEY_CREATE_SUB_KEY, /* sam */
+			      NULL, /* security */
+			      &hKey, /* result key */
+			      NULL); /* disposition */
+	if (result != ERROR_SUCCESS) {
+		if (result == ERROR_ACCESS_DENIED) {
+			/* This should no longer be able to happen - we have already
+			   checked if they have permissions in HKLM, and all users
+			   should have write access to HKCU.
+			*/
+			MessageBox(GetFocus(),
+				   "You do not seem to have sufficient access rights\n"
+				   "on this machine to install this software",
+				   NULL,
+				   MB_OK | MB_ICONSTOP);
+			return FALSE;
+		} else {
+			MessageBox(GetFocus(), KeyName, "Could not open key", MB_OK);
+		}
+	}
+
+	sprintf(buffer, "%s\\%s-wininst.log", dir, meta_name);
+	logfile = fopen(buffer, "a");
+	time(&ltime);
+	now = localtime(&ltime);
+	strftime(buffer, sizeof(buffer),
+		 "*** Installation started %Y/%m/%d %H:%M ***\n",
+		 localtime(&ltime));
+	fprintf(logfile, buffer);
+	fprintf(logfile, "Source: %s\n", modulename);
+
+	/* Root key must be first entry processed by uninstaller. */
+	fprintf(logfile, "999 Root Key: %s\n", root_name);
+
+	sprintf(subkey_name, "%s-py%d.%d", meta_name, py_major, py_minor);
+
+	result = RegCreateKeyEx(hKey, subkey_name,
+				0, NULL, 0,
+				KEY_WRITE,
+				NULL,
+				&hSubkey,
+				&disposition);
+
+	if (result != ERROR_SUCCESS)
+		MessageBox(GetFocus(), subkey_name, "Could not create key", MB_OK);
+
+	RegCloseKey(hKey);
+
+	if (disposition == REG_CREATED_NEW_KEY)
+		fprintf(logfile, "020 Reg DB Key: [%s]%s\n", KeyName, subkey_name);
+
+	sprintf(buffer, "Python %d.%d %s", py_major, py_minor, title);
+
+	result = RegSetValueEx(hSubkey, "DisplayName",
+			       0,
+			       REG_SZ,
+			       buffer,
+			       strlen(buffer)+1);
+
+	if (result != ERROR_SUCCESS)
+		MessageBox(GetFocus(), buffer, "Could not set key value", MB_OK);
+
+	fprintf(logfile, "040 Reg DB Value: [%s\\%s]%s=%s\n",
+		KeyName, subkey_name, "DisplayName", buffer);
+
+	{
+		FILE *fp;
+		sprintf(buffer, "%s\\Remove%s.exe", dir, meta_name);
+		fp = fopen(buffer, "wb");
+		fwrite(arc_data, exe_size, 1, fp);
+		fclose(fp);
+
+		sprintf(buffer, "\"%s\\Remove%s.exe\" -u \"%s\\%s-wininst.log\"",
+			dir, meta_name, dir, meta_name);
+
+		result = RegSetValueEx(hSubkey, "UninstallString",
+				       0,
+				       REG_SZ,
+				       buffer,
+				       strlen(buffer)+1);
+	
+		if (result != ERROR_SUCCESS)
+			MessageBox(GetFocus(), buffer, "Could not set key value", MB_OK);
+
+		fprintf(logfile, "040 Reg DB Value: [%s\\%s]%s=%s\n",
+			KeyName, subkey_name, "UninstallString", buffer);
+	}
+	return TRUE;
+}
+
+static void CloseLogfile(void)
+{
+	char buffer[_MAX_PATH+1];
+	time_t ltime;
+	struct tm *now;
+
+	time(&ltime);
+	now = localtime(&ltime);
+	strftime(buffer, sizeof(buffer),
+		 "*** Installation finished %Y/%m/%d %H:%M ***\n",
+		 localtime(&ltime));
+	fprintf(logfile, buffer);
+	if (logfile)
+		fclose(logfile);
+}
+
+BOOL CALLBACK
+InstallFilesDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+	LPNMHDR lpnm;
+	char Buffer[4096];
+	SCHEME *scheme;
+
+	switch (msg) {
+	case WM_INITDIALOG:
+		if (hBitmap)
+			SendDlgItemMessage(hwnd, IDC_BITMAP, STM_SETIMAGE,
+					   IMAGE_BITMAP, (LPARAM)hBitmap);
+		wsprintf(Buffer,
+			  "Click Next to begin the installation of %s. "
+			  "If you want to review or change any of your "
+			  " installation settings, click Back. "
+			  "Click Cancel to exit the wizard.",
+			  meta_name);
+		SetDlgItemText(hwnd, IDC_TITLE, Buffer);
+		SetDlgItemText(hwnd, IDC_INFO, "Ready to install");
+		break;
+
+	case WM_NUMFILES:
+		SendDlgItemMessage(hwnd, IDC_PROGRESS, PBM_SETRANGE, 0, lParam);
+		PumpMessages();
+		return TRUE;
+
+	case WM_NEXTFILE:
+		SendDlgItemMessage(hwnd, IDC_PROGRESS, PBM_SETPOS, wParam,
+				    0);
+		SetDlgItemText(hwnd, IDC_INFO, (LPSTR)lParam);
+		PumpMessages();
+		return TRUE;
+
+	case WM_NOTIFY:
+		lpnm = (LPNMHDR) lParam;
+
+		switch (lpnm->code) {
+		case PSN_SETACTIVE:
+			PropSheet_SetWizButtons(GetParent(hwnd),
+						PSWIZB_BACK | PSWIZB_NEXT);
+			break;
+
+		case PSN_WIZFINISH:
+			break;
+
+		case PSN_WIZNEXT:
+			/* Handle a Next button click here */
+			hDialog = hwnd;
+			success = TRUE;
+
+			/* Disable the buttons while we work.  Sending CANCELTOCLOSE has
+			  the effect of disabling the cancel button, which is a) as we
+			  do everything synchronously we can't cancel, and b) the next
+			  step is 'finished', when it is too late to cancel anyway.
+			  The next step being 'Finished' means we also don't need to
+			  restore the button state back */
+			PropSheet_SetWizButtons(GetParent(hwnd), 0);
+			SendMessage(GetParent(hwnd), PSM_CANCELTOCLOSE, 0, 0);
+			/* Make sure the installation directory name ends in a */
+			/* backslash */
+			if (python_dir[strlen(python_dir)-1] != '\\')
+				strcat(python_dir, "\\");
+			/* Strip the trailing backslash again */
+			python_dir[strlen(python_dir)-1] = '\0';
+            
+			CheckRootKey(hwnd);
+	    
+			if (!OpenLogfile(python_dir))
+				break;
+
+/*
+ * The scheme we have to use depends on the Python version...
+ if sys.version < "2.2":
+ WINDOWS_SCHEME = {
+ 'purelib': '$base',
+ 'platlib': '$base',
+ 'headers': '$base/Include/$dist_name',
+ 'scripts': '$base/Scripts',
+ 'data'   : '$base',
+ }
+ else:
+ WINDOWS_SCHEME = {
+ 'purelib': '$base/Lib/site-packages',
+ 'platlib': '$base/Lib/site-packages',
+ 'headers': '$base/Include/$dist_name',
+ 'scripts': '$base/Scripts',
+ 'data'   : '$base',
+ }
+*/
+			scheme = GetScheme(py_major, py_minor);
+			/* Run the pre-install script. */
+			if (pre_install_script && *pre_install_script) {
+				SetDlgItemText (hwnd, IDC_TITLE,
+						"Running pre-installation script");
+				run_simple_script(pre_install_script);
+			}
+			if (!success) {
+				break;
+			}
+			/* Extract all files from the archive */
+			SetDlgItemText(hwnd, IDC_TITLE, "Installing files...");
+			if (!unzip_archive (scheme,
+					    python_dir, arc_data,
+					    arc_size, notify))
+				set_failure_reason("Failed to unzip installation files");
+			/* Compile the py-files */
+			if (success && pyc_compile) {
+				int errors;
+				HINSTANCE hPython;
+				SetDlgItemText(hwnd, IDC_TITLE,
+						"Compiling files to .pyc...");
+
+				SetDlgItemText(hDialog, IDC_INFO, "Loading python...");
+				hPython = LoadPythonDll(pythondll);
+				if (hPython) {
+					errors = compile_filelist(hPython, FALSE);
+					FreeLibrary(hPython);
+				}
+				/* Compilation errors are intentionally ignored:
+				 * Python2.0 contains a bug which will result
+				 * in sys.path containing garbage under certain
+				 * circumstances, and an error message will only
+				 * confuse the user.
+				 */
+			}
+			if (success && pyo_compile) {
+				int errors;
+				HINSTANCE hPython;
+				SetDlgItemText(hwnd, IDC_TITLE,
+						"Compiling files to .pyo...");
+
+				SetDlgItemText(hDialog, IDC_INFO, "Loading python...");
+				hPython = LoadPythonDll(pythondll);
+				if (hPython) {
+					errors = compile_filelist(hPython, TRUE);
+					FreeLibrary(hPython);
+				}
+				/* Errors ignored: see above */
+			}
+
+
+			break;
+
+		case PSN_RESET:
+			break;
+		
+		default:
+			break;
+		}
+	}
+	return 0;
+}
+
+
+BOOL CALLBACK
+FinishedDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+	LPNMHDR lpnm;
+
+	switch (msg) {
+	case WM_INITDIALOG:
+		if (hBitmap)
+			SendDlgItemMessage(hwnd, IDC_BITMAP, STM_SETIMAGE,
+					   IMAGE_BITMAP, (LPARAM)hBitmap);
+		if (!success)
+			SetDlgItemText(hwnd, IDC_INFO, get_failure_reason());
+
+		/* async delay: will show the dialog box completely before
+		   the install_script is started */
+		PostMessage(hwnd, WM_USER, 0, 0L);
+		return TRUE;
+
+	case WM_USER:
+
+		if (success && install_script && install_script[0]) {
+			char fname[MAX_PATH];
+			char *tempname;
+			FILE *fp;
+			char buffer[4096];
+			int n;
+			HCURSOR hCursor;
+			HINSTANCE hPython;
+
+			char *argv[3] = {NULL, "-install", NULL};
+
+			SetDlgItemText(hwnd, IDC_TITLE,
+					"Please wait while running postinstall script...");
+			strcpy(fname, python_dir);
+			strcat(fname, "\\Scripts\\");
+			strcat(fname, install_script);
+
+			if (logfile)
+				fprintf(logfile, "300 Run Script: [%s]%s\n", pythondll, fname);
+
+			tempname = tempnam(NULL, NULL);
+
+			if (!freopen(tempname, "a", stderr))
+				MessageBox(GetFocus(), "freopen stderr", NULL, MB_OK);
+			if (!freopen(tempname, "a", stdout))
+				MessageBox(GetFocus(), "freopen stdout", NULL, MB_OK);
+/*
+  if (0 != setvbuf(stdout, NULL, _IONBF, 0))
+  MessageBox(GetFocus(), "setvbuf stdout", NULL, MB_OK);
+*/
+			hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
+
+			argv[0] = fname;
+
+			hPython = LoadPythonDll(pythondll);
+			if (hPython) {
+				int result;
+				result = run_installscript(hPython, fname, 2, argv);
+				if (-1 == result) {
+					fprintf(stderr, "*** run_installscript: internal error 0x%X ***\n", result);
+				}
+				FreeLibrary(hPython);
+			} else {
+				fprintf(stderr, "*** Could not load Python ***");
+			}
+			fflush(stderr);
+			fclose(stderr);
+			fflush(stdout);
+			fclose(stdout);
+	    
+			fp = fopen(tempname, "rb");
+			n = fread(buffer, 1, sizeof(buffer), fp);
+			fclose(fp);
+			remove(tempname);
+	    
+			buffer[n] = '\0';
+	    
+			SetDlgItemText(hwnd, IDC_INFO, buffer);
+			SetDlgItemText(hwnd, IDC_TITLE,
+					"Postinstall script finished.\n"
+					"Click the Finish button to exit the Setup wizard.");
+
+			SetCursor(hCursor);
+			CloseLogfile();
+		}
+
+		return TRUE;
+
+	case WM_NOTIFY:
+		lpnm = (LPNMHDR) lParam;
+
+		switch (lpnm->code) {
+		case PSN_SETACTIVE: /* Enable the Finish button */
+			PropSheet_SetWizButtons(GetParent(hwnd), PSWIZB_FINISH);
+			break;
+
+		case PSN_WIZNEXT:
+			break;
+
+		case PSN_WIZFINISH:
+			break;
+
+		case PSN_RESET:
+			break;
+		
+		default:
+			break;
+		}
+	}
+	return 0;
+}
+
+void RunWizard(HWND hwnd)
+{
+	PROPSHEETPAGE   psp =       {0};
+	HPROPSHEETPAGE  ahpsp[4] =  {0};
+	PROPSHEETHEADER psh =       {0};
+
+	/* Display module information */
+	psp.dwSize =        sizeof(psp);
+	psp.dwFlags =       PSP_DEFAULT|PSP_HIDEHEADER;
+	psp.hInstance =     GetModuleHandle (NULL);
+	psp.lParam =        0;
+	psp.pfnDlgProc =    IntroDlgProc;
+	psp.pszTemplate =   MAKEINTRESOURCE(IDD_INTRO);
+
+	ahpsp[0] =          CreatePropertySheetPage(&psp);
+
+	/* Select python version to use */
+	psp.dwFlags =       PSP_DEFAULT|PSP_HIDEHEADER;
+	psp.pszTemplate =       MAKEINTRESOURCE(IDD_SELECTPYTHON);
+	psp.pfnDlgProc =        SelectPythonDlgProc;
+
+	ahpsp[1] =              CreatePropertySheetPage(&psp);
+
+	/* Install the files */
+	psp.dwFlags =	    PSP_DEFAULT|PSP_HIDEHEADER;
+	psp.pszTemplate =       MAKEINTRESOURCE(IDD_INSTALLFILES);
+	psp.pfnDlgProc =        InstallFilesDlgProc;
+
+	ahpsp[2] =              CreatePropertySheetPage(&psp);
+
+	/* Show success or failure */
+	psp.dwFlags =           PSP_DEFAULT|PSP_HIDEHEADER;
+	psp.pszTemplate =       MAKEINTRESOURCE(IDD_FINISHED);
+	psp.pfnDlgProc =        FinishedDlgProc;
+
+	ahpsp[3] =              CreatePropertySheetPage(&psp);
+
+	/* Create the property sheet */
+	psh.dwSize =            sizeof(psh);
+	psh.hInstance =         GetModuleHandle(NULL);
+	psh.hwndParent =        hwnd;
+	psh.phpage =            ahpsp;
+	psh.dwFlags =           PSH_WIZARD/*97*//*|PSH_WATERMARK|PSH_HEADER*/;
+		psh.pszbmWatermark =    NULL;
+		psh.pszbmHeader =       NULL;
+		psh.nStartPage =        0;
+		psh.nPages =            4;
+
+		PropertySheet(&psh);
+}
+
+int DoInstall(void)
+{
+	char ini_buffer[4096];
+
+	/* Read installation information */
+	GetPrivateProfileString("Setup", "title", "", ini_buffer,
+				 sizeof(ini_buffer), ini_file);
+	unescape(title, ini_buffer, sizeof(title));
+
+	GetPrivateProfileString("Setup", "info", "", ini_buffer,
+				 sizeof(ini_buffer), ini_file);
+	unescape(info, ini_buffer, sizeof(info));
+
+	GetPrivateProfileString("Setup", "build_info", "", build_info,
+				 sizeof(build_info), ini_file);
+
+	pyc_compile = GetPrivateProfileInt("Setup", "target_compile", 1,
+					    ini_file);
+	pyo_compile = GetPrivateProfileInt("Setup", "target_optimize", 1,
+					    ini_file);
+
+	GetPrivateProfileString("Setup", "target_version", "",
+				 target_version, sizeof(target_version),
+				 ini_file);
+
+	GetPrivateProfileString("metadata", "name", "",
+				 meta_name, sizeof(meta_name),
+				 ini_file);
+
+	GetPrivateProfileString("Setup", "install_script", "",
+				 install_script, sizeof(install_script),
+				 ini_file);
+
+
+	hwndMain = CreateBackground(title);
+
+	RunWizard(hwndMain);
+
+	/* Clean up */
+	UnmapViewOfFile(arc_data);
+	if (ini_file)
+		DeleteFile(ini_file);
+
+	if (hBitmap)
+		DeleteObject(hBitmap);
+
+	return 0;
+}
+
+/*********************** uninstall section ******************************/
+
+static int compare(const void *p1, const void *p2)
+{
+	return strcmp(*(char **)p2, *(char **)p1);
+}
+
+/*
+ * Commit suicide (remove the uninstaller itself).
+ *
+ * Create a batch file to first remove the uninstaller
+ * (will succeed after it has finished), then the batch file itself.
+ *
+ * This technique has been demonstrated by Jeff Richter,
+ * MSJ 1/1996
+ */
+void remove_exe(void)
+{
+	char exename[_MAX_PATH];
+	char batname[_MAX_PATH];
+	FILE *fp;
+	STARTUPINFO si;
+	PROCESS_INFORMATION pi;
+
+	GetModuleFileName(NULL, exename, sizeof(exename));
+	sprintf(batname, "%s.bat", exename);
+	fp = fopen(batname, "w");
+	fprintf(fp, ":Repeat\n");
+	fprintf(fp, "del \"%s\"\n", exename);
+	fprintf(fp, "if exist \"%s\" goto Repeat\n", exename);
+	fprintf(fp, "del \"%s\"\n", batname);
+	fclose(fp);
+    
+	ZeroMemory(&si, sizeof(si));
+	si.cb = sizeof(si);
+	si.dwFlags = STARTF_USESHOWWINDOW;
+	si.wShowWindow = SW_HIDE;
+	if (CreateProcess(NULL,
+			  batname,
+			  NULL,
+			  NULL,
+			  FALSE,
+			  CREATE_SUSPENDED | IDLE_PRIORITY_CLASS,
+			  NULL,
+			  "\\",
+			  &si,
+			  &pi)) {
+		SetThreadPriority(pi.hThread, THREAD_PRIORITY_IDLE);
+		SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
+		SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
+		CloseHandle(pi.hProcess);
+		ResumeThread(pi.hThread);
+		CloseHandle(pi.hThread);
+	}
+}
+
+void DeleteRegistryKey(char *string)
+{
+	char *keyname;
+	char *subkeyname;
+	char *delim;
+	HKEY hKey;
+	long result;
+	char *line;
+
+	line = strdup(string); /* so we can change it */
+
+	keyname = strchr(line, '[');
+	if (!keyname)
+		return;
+	++keyname;
+
+	subkeyname = strchr(keyname, ']');
+	if (!subkeyname)
+		return;
+	*subkeyname++='\0';
+	delim = strchr(subkeyname, '\n');
+	if (delim)
+		*delim = '\0';
+
+	result = RegOpenKeyEx(hkey_root,
+			      keyname,
+			      0,
+			      KEY_WRITE,
+			      &hKey);
+    
+	if (result != ERROR_SUCCESS)
+		MessageBox(GetFocus(), string, "Could not open key", MB_OK);
+	else {
+		result = RegDeleteKey(hKey, subkeyname);
+		if (result != ERROR_SUCCESS && result != ERROR_FILE_NOT_FOUND)
+			MessageBox(GetFocus(), string, "Could not delete key", MB_OK);
+		RegCloseKey(hKey);
+	}
+	free(line);
+}
+
+void DeleteRegistryValue(char *string)
+{
+	char *keyname;
+	char *valuename;
+	char *value;
+	HKEY hKey;
+	long result;
+	char *line;
+
+	line = strdup(string); /* so we can change it */
+
+/* Format is 'Reg DB Value: [key]name=value' */
+	keyname = strchr(line, '[');
+	if (!keyname)
+		return;
+	++keyname;
+	valuename = strchr(keyname, ']');
+	if (!valuename)
+		return;
+	*valuename++ = '\0';
+	value = strchr(valuename, '=');
+	if (!value)
+		return;
+
+	*value++ = '\0';
+
+	result = RegOpenKeyEx(hkey_root,
+			      keyname,
+			      0,
+			      KEY_WRITE,
+			      &hKey);
+	if (result != ERROR_SUCCESS)
+		MessageBox(GetFocus(), string, "Could not open key", MB_OK);
+	else {
+		result = RegDeleteValue(hKey, valuename);
+		if (result != ERROR_SUCCESS && result != ERROR_FILE_NOT_FOUND)
+			MessageBox(GetFocus(), string, "Could not delete value", MB_OK);
+		RegCloseKey(hKey);
+	}
+	free(line);
+}
+
+BOOL MyDeleteFile(char *line)
+{
+	char *pathname = strchr(line, ':');
+	if (!pathname)
+		return FALSE;
+	++pathname;
+	while (isspace(*pathname))
+		++pathname;
+	return DeleteFile(pathname);
+}
+
+BOOL MyRemoveDirectory(char *line)
+{
+	char *pathname = strchr(line, ':');
+	if (!pathname)
+		return FALSE;
+	++pathname;
+	while (isspace(*pathname))
+		++pathname;
+	return RemoveDirectory(pathname);
+}
+
+BOOL Run_RemoveScript(char *line)
+{
+	char *dllname;
+	char *scriptname;
+	static char lastscript[MAX_PATH];
+
+/* Format is 'Run Scripts: [pythondll]scriptname' */
+/* XXX Currently, pythondll carries no path!!! */
+	dllname = strchr(line, '[');
+	if (!dllname)
+		return FALSE;
+	++dllname;
+	scriptname = strchr(dllname, ']');
+	if (!scriptname)
+		return FALSE;
+	*scriptname++ = '\0';
+	/* this function may be called more than one time with the same
+	   script, only run it one time */
+	if (strcmp(lastscript, scriptname)) {
+		HINSTANCE hPython;
+		char *argv[3] = {NULL, "-remove", NULL};
+		char buffer[4096];
+		FILE *fp;
+		char *tempname;
+		int n;
+
+		argv[0] = scriptname;
+
+		tempname = tempnam(NULL, NULL);
+
+		if (!freopen(tempname, "a", stderr))
+			MessageBox(GetFocus(), "freopen stderr", NULL, MB_OK);
+		if (!freopen(tempname, "a", stdout))
+			MessageBox(GetFocus(), "freopen stdout", NULL, MB_OK);
+	
+		hPython = LoadLibrary(dllname);
+		if (hPython) {
+			if (0x80000000 == run_installscript(hPython, scriptname, 2, argv))
+				fprintf(stderr, "*** Could not load Python ***");
+			FreeLibrary(hPython);
+		}
+	
+		fflush(stderr);
+		fclose(stderr);
+		fflush(stdout);
+		fclose(stdout);
+	
+		fp = fopen(tempname, "rb");
+		n = fread(buffer, 1, sizeof(buffer), fp);
+		fclose(fp);
+		remove(tempname);
+	
+		buffer[n] = '\0';
+		if (buffer[0])
+			MessageBox(GetFocus(), buffer, "uninstall-script", MB_OK);
+
+		strcpy(lastscript, scriptname);
+	}
+	return TRUE;
+}
+
+int DoUninstall(int argc, char **argv)
+{
+	FILE *logfile;
+	char buffer[4096];
+	int nLines = 0;
+	int i;
+	char *cp;
+	int nFiles = 0;
+	int nDirs = 0;
+	int nErrors = 0;
+	char **lines;
+	int lines_buffer_size = 10;
+    
+	if (argc != 3) {
+		MessageBox(NULL,
+			   "Wrong number of args",
+			   NULL,
+			   MB_OK);
+		return 1; /* Error */
+	}
+	if (strcmp(argv[1], "-u")) {
+		MessageBox(NULL,
+			   "2. arg is not -u",
+			   NULL,
+			   MB_OK);
+		return 1; /* Error */
+	}
+
+	logfile = fopen(argv[2], "r");
+	if (!logfile) {
+		MessageBox(NULL,
+			   "could not open logfile",
+			   NULL,
+			   MB_OK);
+		return 1; /* Error */
+	}
+    
+	lines = (char **)malloc(sizeof(char *) * lines_buffer_size);
+	if (!lines)
+		return SystemError(0, "Out of memory");
+
+	/* Read the whole logfile, realloacting the buffer */
+	while (fgets(buffer, sizeof(buffer), logfile)) {
+		int len = strlen(buffer);
+		/* remove trailing white space */
+		while (isspace(buffer[len-1]))
+			len -= 1;
+		buffer[len] = '\0';
+		lines[nLines++] = strdup(buffer);
+		if (nLines >= lines_buffer_size) {
+			lines_buffer_size += 10;
+			lines = (char **)realloc(lines,
+						 sizeof(char *) * lines_buffer_size);
+			if (!lines)
+				return SystemError(0, "Out of memory");
+		}
+	}
+	fclose(logfile);
+
+	/* Sort all the lines, so that highest 3-digit codes are first */
+	qsort(&lines[0], nLines, sizeof(char *),
+	      compare);
+
+	if (IDYES != MessageBox(NULL,
+				"Are you sure you want to remove\n"
+				"this package from your computer?",
+				"Please confirm",
+				MB_YESNO | MB_ICONQUESTION))
+		return 0;
+
+	hkey_root = HKEY_LOCAL_MACHINE;
+	cp = "";
+	for (i = 0; i < nLines; ++i) {
+		/* Ignore duplicate lines */
+		if (strcmp(cp, lines[i])) {
+			int ign;
+			cp = lines[i];
+			/* Parse the lines */
+			if (2 == sscanf(cp, "%d Root Key: %s", &ign, &buffer)) {
+				if (strcmp(buffer, "HKEY_CURRENT_USER")==0)
+					hkey_root = HKEY_CURRENT_USER;
+				else {
+					// HKLM - check they have permissions.
+					if (!HasLocalMachinePrivs()) {
+						MessageBox(GetFocus(),
+							   "You do not seem to have sufficient access rights\n"
+							   "on this machine to uninstall this software",
+							   NULL,
+							   MB_OK | MB_ICONSTOP);
+						return 1; /* Error */
+					}
+				}
+			} else if (2 == sscanf(cp, "%d Made Dir: %s", &ign, &buffer)) {
+				if (MyRemoveDirectory(cp))
+					++nDirs;
+				else {
+					int code = GetLastError();
+					if (code != 2 && code != 3) { /* file or path not found */
+						++nErrors;
+					}
+				}
+			} else if (2 == sscanf(cp, "%d File Copy: %s", &ign, &buffer)) {
+				if (MyDeleteFile(cp))
+					++nFiles;
+				else {
+					int code = GetLastError();
+					if (code != 2 && code != 3) { /* file or path not found */
+						++nErrors;
+					}
+				}
+			} else if (2 == sscanf(cp, "%d File Overwrite: %s", &ign, &buffer)) {
+				if (MyDeleteFile(cp))
+					++nFiles;
+				else {
+					int code = GetLastError();
+					if (code != 2 && code != 3) { /* file or path not found */
+						++nErrors;
+					}
+				}
+			} else if (2 == sscanf(cp, "%d Reg DB Key: %s", &ign, &buffer)) {
+				DeleteRegistryKey(cp);
+			} else if (2 == sscanf(cp, "%d Reg DB Value: %s", &ign, &buffer)) {
+				DeleteRegistryValue(cp);
+			} else if (2 == sscanf(cp, "%d Run Script: %s", &ign, &buffer)) {
+				Run_RemoveScript(cp);
+			}
+		}
+	}
+
+	if (DeleteFile(argv[2])) {
+		++nFiles;
+	} else {
+		++nErrors;
+		SystemError(GetLastError(), argv[2]);
+	}
+	if (nErrors)
+		wsprintf(buffer,
+			 "%d files and %d directories removed\n"
+			 "%d files or directories could not be removed",
+			 nFiles, nDirs, nErrors);
+	else
+		wsprintf(buffer, "%d files and %d directories removed",
+			 nFiles, nDirs);
+	MessageBox(NULL, buffer, "Uninstall Finished!",
+		   MB_OK | MB_ICONINFORMATION);
+	remove_exe();
+	return 0;
+}
+
+int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst,
+		    LPSTR lpszCmdLine, INT nCmdShow)
+{
+	extern int __argc;
+	extern char **__argv;
+	char *basename;
+
+	GetModuleFileName(NULL, modulename, sizeof(modulename));
+
+	/* Map the executable file to memory */
+	arc_data = MapExistingFile(modulename, &arc_size);
+	if (!arc_data) {
+		SystemError(GetLastError(), "Could not open archive");
+		return 1;
+	}
+
+	/* OK. So this program can act as installer (self-extracting
+	 * zip-file, or as uninstaller when started with '-u logfile'
+	 * command line flags.
+	 *
+	 * The installer is usually started without command line flags,
+	 * and the uninstaller is usually started with the '-u logfile'
+	 * flag. What to do if some innocent user double-clicks the
+	 * exe-file?
+	 * The following implements a defensive strategy...
+	 */
+
+	/* Try to extract the configuration data into a temporary file */
+	if (ExtractInstallData(arc_data, arc_size, &exe_size,
+			       &ini_file, &pre_install_script))
+		return DoInstall();
+
+	if (!ini_file && __argc > 1) {
+		return DoUninstall(__argc, __argv);
+	}
+
+
+	basename = strrchr(modulename, '\\');
+	if (basename)
+		++basename;
+
+	/* Last guess about the purpose of this program */
+	if (basename && (0 == strncmp(basename, "Remove", 6)))
+		SystemError(0, "This program is normally started by windows");
+	else
+		SystemError(0, "Setup program invalid or damaged");
+	return 1;
+}

Added: vendor/Python/current/PC/bdist_wininst/install.rc
===================================================================
--- vendor/Python/current/PC/bdist_wininst/install.rc	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/bdist_wininst/install.rc	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,229 @@
+/*
+  IMPORTANT NOTE: IF THIS FILE IS CHANGED, WININST-6.EXE MUST BE RECOMPILED
+  WITH THE MSVC6 WININST.DSW WORKSPACE FILE MANUALLY, AND WININST-7.1.EXE MUST
+  BE RECOMPILED WITH THE MSVC 2003.NET WININST-7.1.VCPROJ FILE MANUALLY.
+
+  IF CHANGES TO THIS FILE ARE CHECKED INTO PYTHON CVS, THE RECOMPILED BINARIES
+  MUST BE CHECKED IN AS WELL!
+*/
+
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Neutral resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU)
+#ifdef _WIN32
+LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Bitmap
+//
+
+IDB_BITMAP              BITMAP  DISCARDABLE     "PythonPowered.bmp"
+#endif    // Neutral resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// German (Germany) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU)
+#ifdef _WIN32
+LANGUAGE LANG_GERMAN, SUBLANG_GERMAN
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE 
+BEGIN
+    "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE 
+BEGIN
+    "#include ""afxres.h""\r\n"
+    "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE 
+BEGIN
+    "\r\n"
+    "\0"
+END
+
+#endif    // APSTUDIO_INVOKED
+
+#endif    // German (Germany) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_INTRO DIALOGEX 0, 0, 379, 178
+STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "Setup"
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+    LTEXT           "This Wizard will install %s on your computer. Click Next to continue or Cancel to exit the Setup Wizard.",
+                    IDC_TITLE,125,10,247,20,NOT WS_GROUP
+    EDITTEXT        IDC_INTRO_TEXT,125,31,247,131,ES_MULTILINE | ES_READONLY | 
+                    WS_VSCROLL | WS_HSCROLL | NOT WS_TABSTOP
+    CONTROL         110,IDC_BITMAP,"Static",SS_BITMAP | SS_CENTERIMAGE,6,8,
+                    104,163,WS_EX_CLIENTEDGE
+    LTEXT           "",IDC_BUILD_INFO,125,163,247,8
+END
+
+IDD_SELECTPYTHON DIALOGEX 0, 0, 379, 178
+STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "Setup"
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+    LTEXT           "Select python installation to use:",IDC_TITLE,125,10,
+                    247,12,NOT WS_GROUP
+    EDITTEXT        IDC_PATH,191,136,181,14,ES_AUTOHSCROLL | ES_READONLY
+    LTEXT           "Python Directory:",IDC_STATIC,125,137,55,8
+    LISTBOX         IDC_VERSIONS_LIST,125,24,247,106,LBS_SORT | 
+                    LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
+    CONTROL         110,IDC_BITMAP,"Static",SS_BITMAP | SS_CENTERIMAGE,6,8,
+                    104,163,WS_EX_CLIENTEDGE
+    EDITTEXT        IDC_INSTALL_PATH,191,157,181,14,ES_AUTOHSCROLL | 
+                    ES_READONLY
+    LTEXT           "Installation Directory:",IDC_STATIC,125,158,66,8
+    PUSHBUTTON      "Find other ...",IDC_OTHERPYTHON,322,7,50,14,NOT 
+                    WS_VISIBLE
+END
+
+IDD_INSTALLFILES DIALOGEX 0, 0, 379, 178
+STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "Setup"
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+    LTEXT           "Click Next to begin the installation. If you want to review or change any of your installation settings, click Back. Click Cancel to exit the Wizard.",
+                    IDC_TITLE,125,10,246,31,NOT WS_GROUP
+    CONTROL         "Progress1",IDC_PROGRESS,"msctls_progress32",WS_BORDER,
+                    125,157,246,14
+    CTEXT           "Installation progress:",IDC_INFO,125,137,246,8
+    CONTROL         110,IDC_BITMAP,"Static",SS_BITMAP | SS_CENTERIMAGE,6,8,
+                    104,163,WS_EX_CLIENTEDGE
+END
+
+IDD_FINISHED DIALOGEX 0, 0, 379, 178
+STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "Setup"
+FONT 8, "MS Sans Serif"
+BEGIN
+    LTEXT           "Click the Finish button to exit the Setup wizard.",
+                    IDC_TITLE,125,10,247,31,NOT WS_GROUP
+    CONTROL         110,IDC_BITMAP,"Static",SS_BITMAP | SS_CENTERIMAGE,6,8,
+                    104,163,WS_EX_CLIENTEDGE
+    EDITTEXT        IDC_INFO,125,40,247,131,ES_MULTILINE | ES_READONLY | 
+                    WS_VSCROLL | WS_HSCROLL | NOT WS_TABSTOP
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE 
+BEGIN
+    IDD_INTRO, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 372
+        VERTGUIDE, 125
+        VERTGUIDE, 372
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 171
+        HORZGUIDE, 8
+        HORZGUIDE, 31
+    END
+
+    IDD_SELECTPYTHON, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 372
+        VERTGUIDE, 125
+        VERTGUIDE, 372
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 171
+        HORZGUIDE, 8
+        HORZGUIDE, 41
+    END
+
+    IDD_INSTALLFILES, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 372
+        VERTGUIDE, 125
+        VERTGUIDE, 371
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 171
+        HORZGUIDE, 8
+        HORZGUIDE, 41
+    END
+
+    IDD_FINISHED, DIALOG
+    BEGIN
+        LEFTMARGIN, 6
+        RIGHTMARGIN, 372
+        VERTGUIDE, 125
+        VERTGUIDE, 372
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 171
+        HORZGUIDE, 8
+        HORZGUIDE, 41
+    END
+END
+#endif    // APSTUDIO_INVOKED
+
+#endif    // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // not APSTUDIO_INVOKED
+

Added: vendor/Python/current/PC/bdist_wininst/resource.h
===================================================================
--- vendor/Python/current/PC/bdist_wininst/resource.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/bdist_wininst/resource.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,47 @@
+/*
+  IMPORTANT NOTE: IF THIS FILE IS CHANGED, WININST-6.EXE MUST BE RECOMPILED
+  WITH THE MSVC6 WININST.DSW WORKSPACE FILE MANUALLY, AND WININST-7.1.EXE MUST
+  BE RECOMPILED WITH THE MSVC 2003.NET WININST-7.1.VCPROJ FILE MANUALLY.
+
+  IF CHANGES TO THIS FILE ARE CHECKED INTO PYTHON CVS, THE RECOMPILED BINARIES
+  MUST BE CHECKED IN AS WELL!
+*/
+
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by install.rc
+//
+#define IDD_DIALOG1                     101
+#define IDB_BITMAP1                     103
+#define IDD_INTRO                       107
+#define IDD_SELECTPYTHON                108
+#define IDD_INSTALLFILES                109
+#define IDD_FINISHED                    110
+#define IDB_BITMAP                      110
+#define IDC_EDIT1                       1000
+#define IDC_TITLE                       1000
+#define IDC_START                       1001
+#define IDC_PROGRESS                    1003
+#define IDC_INFO                        1004
+#define IDC_PYTHON15                    1006
+#define IDC_PATH                        1007
+#define IDC_PYTHON16                    1008
+#define IDC_INSTALL_PATH                1008
+#define IDC_PYTHON20                    1009
+#define IDC_BROWSE                      1010
+#define IDC_INTRO_TEXT                  1021
+#define IDC_VERSIONS_LIST               1022
+#define IDC_BUILD_INFO                  1024
+#define IDC_BITMAP                      1025
+#define IDC_OTHERPYTHON                 1026
+
+// Next default values for new objects
+// 
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE        112
+#define _APS_NEXT_COMMAND_VALUE         40001
+#define _APS_NEXT_CONTROL_VALUE         1028
+#define _APS_NEXT_SYMED_VALUE           101
+#endif
+#endif

Added: vendor/Python/current/PC/bdist_wininst/wininst-7.1.sln
===================================================================
--- vendor/Python/current/PC/bdist_wininst/wininst-7.1.sln	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/bdist_wininst/wininst-7.1.sln	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,21 @@
+Microsoft Visual Studio Solution File, Format Version 8.00
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wininst", "wininst-7.1.vcproj", "{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}"
+	ProjectSection(ProjectDependencies) = postProject
+	EndProjectSection
+EndProject
+Global
+	GlobalSection(SolutionConfiguration) = preSolution
+		Debug = Debug
+		Release = Release
+	EndGlobalSection
+	GlobalSection(ProjectConfiguration) = postSolution
+		{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Debug.ActiveCfg = Debug|Win32
+		{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Debug.Build.0 = Debug|Win32
+		{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Release.ActiveCfg = Release|Win32
+		{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Release.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+	EndGlobalSection
+	GlobalSection(ExtensibilityAddIns) = postSolution
+	EndGlobalSection
+EndGlobal

Added: vendor/Python/current/PC/bdist_wininst/wininst-7.1.vcproj
===================================================================
--- vendor/Python/current/PC/bdist_wininst/wininst-7.1.vcproj	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/bdist_wininst/wininst-7.1.vcproj	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,214 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="wininst"
+	ProjectGUID="{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}"
+	RootNamespace="wininst"
+	SccProjectName=""
+	SccLocalPath="">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory=".\..\..\lib\distutils\command"
+			IntermediateDirectory=".\temp-release"
+			ConfigurationType="1"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="1"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\..\Include,..\..\..\zlib-1.2.1"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+				StringPooling="TRUE"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				PrecompiledHeaderFile=".\temp-release/wininst.pch"
+				AssemblerListingLocation=".\temp-release/"
+				ObjectFile=".\temp-release/"
+				ProgramDataBaseFileName=".\temp-release/"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="..\..\..\zlib-1.2.1\zlib.lib imagehlp.lib comctl32.lib"
+				OutputFile="..\..\lib\distutils\command/wininst-7.1.exe"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				IgnoreDefaultLibraryNames="LIBC"
+				ProgramDatabaseFile=".\..\..\lib\distutils\command/wininst-6.pdb"
+				SubSystem="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"
+				PreprocessorDefinitions="NDEBUG"
+				MkTypLibCompatible="TRUE"
+				SuppressStartupBanner="TRUE"
+				TargetEnvironment="1"
+				TypeLibraryName=".\..\..\lib\distutils\command/wininst.tlb"
+				HeaderFileName=""/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1031"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\temp-debug"
+			ConfigurationType="1"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\..\Include,..\..\..\zlib-1.2.1"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
+				RuntimeLibrary="2"
+				UsePrecompiledHeader="2"
+				PrecompiledHeaderFile=".\temp-debug/wininst.pch"
+				AssemblerListingLocation=".\temp-debug/"
+				ObjectFile=".\temp-debug/"
+				ProgramDataBaseFileName=".\temp-debug/"
+				BrowseInformation="1"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				DebugInformationFormat="1"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="..\..\..\zlib-1.2.1\zlib.lib imagehlp.lib comctl32.lib"
+				OutputFile="..\..\lib\distutils\command/wininst-7.1_d.exe"
+				LinkIncremental="2"
+				SuppressStartupBanner="TRUE"
+				IgnoreDefaultLibraryNames="LIBC"
+				GenerateDebugInformation="TRUE"
+				SubSystem="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"
+				PreprocessorDefinitions="_DEBUG"
+				MkTypLibCompatible="TRUE"
+				SuppressStartupBanner="TRUE"
+				TargetEnvironment="1"
+				TypeLibraryName=".\./wininst.tlb"
+				HeaderFileName=""/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="_DEBUG"
+				Culture="1031"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
+			<File
+				RelativePath="extract.c">
+				<FileConfiguration
+					Name="Release|Win32">
+					<Tool
+						Name="VCCLCompilerTool"
+						Optimization="1"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32">
+					<Tool
+						Name="VCCLCompilerTool"
+						Optimization="0"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+						BrowseInformation="1"/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="install.c">
+				<FileConfiguration
+					Name="Release|Win32">
+					<Tool
+						Name="VCCLCompilerTool"
+						Optimization="1"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32">
+					<Tool
+						Name="VCCLCompilerTool"
+						Optimization="0"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+						BrowseInformation="1"/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="install.rc">
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl">
+			<File
+				RelativePath="archive.h">
+			</File>
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
+			<File
+				RelativePath="PythonPowered.bmp">
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Added: vendor/Python/current/PC/bdist_wininst/wininst.dsp
===================================================================
--- vendor/Python/current/PC/bdist_wininst/wininst.dsp	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/bdist_wininst/wininst.dsp	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,123 @@
+# Microsoft Developer Studio Project File - Name="wininst" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=wininst - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "wininst.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "wininst.mak" CFG="wininst - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "wininst - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "wininst - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "wininst - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "..\..\lib\distutils\command"
+# PROP Intermediate_Dir "temp-release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /O1 /I "..\..\Include" /I "..\..\..\zlib-1.2.1" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x407 /d "NDEBUG"
+# ADD RSC /l 0x407 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\..\..\zlib-1.2.1\zlib.lib imagehlp.lib comdlg32.lib ole32.lib comctl32.lib kernel32.lib user32.lib gdi32.lib advapi32.lib shell32.lib /nologo /subsystem:windows /machine:I386 /nodefaultlib:"LIBC" /out:"..\..\lib\distutils\command/wininst-6.exe"
+
+!ELSEIF  "$(CFG)" == "wininst - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "."
+# PROP Intermediate_Dir "temp-debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MD /W3 /Z7 /Od /I "..\..\Include" /I "..\..\..\zlib-1.2.1" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /FR /YX /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x407 /d "_DEBUG"
+# ADD RSC /l 0x407 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\..\..\zlib-1.2.1\zlib.lib imagehlp.lib comdlg32.lib ole32.lib comctl32.lib kernel32.lib user32.lib gdi32.lib advapi32.lib shell32.lib /nologo /subsystem:windows /pdb:none /debug /machine:I386 /nodefaultlib:"LIBC" /out:"..\..\lib\distutils\command/wininst-6_d.exe"
+
+!ENDIF 
+
+# Begin Target
+
+# Name "wininst - Win32 Release"
+# Name "wininst - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\extract.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\install.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\install.rc
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\archive.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# Begin Source File
+
+SOURCE=.\PythonPowered.bmp
+# End Source File
+# End Group
+# End Target
+# End Project

Added: vendor/Python/current/PC/bdist_wininst/wininst.dsw
===================================================================
--- vendor/Python/current/PC/bdist_wininst/wininst.dsw	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/bdist_wininst/wininst.dsw	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "wininst"=.\wininst.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+

Added: vendor/Python/current/PC/config.c
===================================================================
--- vendor/Python/current/PC/config.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/config.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,170 @@
+/* Module configuration */
+
+/* This file contains the table of built-in modules.
+   See init_builtin() in import.c. */
+
+#include "Python.h"
+
+extern void initarray(void);
+#ifndef MS_WIN64
+extern void initaudioop(void);
+#endif
+extern void initbinascii(void);
+extern void initcmath(void);
+extern void initerrno(void);
+extern void initgc(void);
+#ifndef MS_WIN64
+extern void initimageop(void);
+#endif
+extern void initmath(void);
+extern void init_md5(void);
+extern void initnt(void);
+extern void initoperator(void);
+#ifndef MS_WIN64
+extern void initrgbimg(void);
+#endif
+extern void initsignal(void);
+extern void init_sha(void);
+extern void init_sha256(void);
+extern void init_sha512(void);
+extern void initstrop(void);
+extern void inittime(void);
+extern void initthread(void);
+extern void initcStringIO(void);
+extern void initcPickle(void);
+#ifdef WIN32
+extern void initmsvcrt(void);
+extern void init_locale(void);
+#endif
+extern void init_codecs(void);
+extern void init_weakref(void);
+extern void init_hotshot(void);
+extern void initxxsubtype(void);
+extern void initzipimport(void);
+extern void init_random(void);
+extern void inititertools(void);
+extern void initcollections(void);
+extern void init_heapq(void);
+extern void init_bisect(void);
+extern void init_symtable(void);
+extern void initmmap(void);
+extern void init_csv(void);
+extern void init_sre(void);
+extern void initparser(void);
+extern void init_winreg(void);
+extern void init_struct(void);
+extern void initdatetime(void);
+extern void init_functools(void);
+extern void initzlib(void);
+
+extern void init_multibytecodec(void);
+extern void init_codecs_cn(void);
+extern void init_codecs_hk(void);
+extern void init_codecs_iso2022(void);
+extern void init_codecs_jp(void);
+extern void init_codecs_kr(void);
+extern void init_codecs_tw(void);
+extern void init_subprocess(void);
+extern void init_lsprof(void);
+extern void init_ast(void);
+extern void init_types(void);
+
+/* tools/freeze/makeconfig.py marker for additional "extern" */
+/* -- ADDMODULE MARKER 1 -- */
+
+extern void PyMarshal_Init(void);
+extern void initimp(void);
+
+struct _inittab _PyImport_Inittab[] = {
+
+        {"array", initarray},
+	{"_ast", init_ast},
+#ifdef MS_WINDOWS
+#ifndef MS_WIN64
+        {"audioop", initaudioop},
+#endif
+#endif
+        {"binascii", initbinascii},
+        {"cmath", initcmath},
+        {"errno", initerrno},
+        {"gc", initgc},
+#ifndef MS_WIN64
+        {"imageop", initimageop},
+#endif
+        {"math", initmath},
+        {"_md5", init_md5},
+        {"nt", initnt}, /* Use the NT os functions, not posix */
+        {"operator", initoperator},
+#ifndef MS_WIN64
+        {"rgbimg", initrgbimg},
+#endif
+        {"signal", initsignal},
+        {"_sha", init_sha},
+        {"_sha256", init_sha256},
+        {"_sha512", init_sha512},
+        {"strop", initstrop},
+        {"time", inittime},
+#ifdef WITH_THREAD
+        {"thread", initthread},
+#endif
+        {"cStringIO", initcStringIO},
+        {"cPickle", initcPickle},
+#ifdef WIN32
+        {"msvcrt", initmsvcrt},
+        {"_locale", init_locale},
+#endif
+	/* XXX Should _subprocess go in a WIN32 block?  not WIN64? */
+	{"_subprocess", init_subprocess},
+
+        {"_codecs", init_codecs},
+	{"_weakref", init_weakref},
+	{"_hotshot", init_hotshot},
+	{"_random", init_random},
+        {"_bisect", init_bisect},
+        {"_heapq", init_heapq},
+	{"_lsprof", init_lsprof},
+	{"itertools", inititertools},
+        {"collections", initcollections},
+	{"_symtable", init_symtable},
+	{"mmap", initmmap},
+	{"_csv", init_csv},
+	{"_sre", init_sre},
+	{"parser", initparser},
+	{"_winreg", init_winreg},
+	{"_struct", init_struct},
+	{"datetime", initdatetime},
+	{"_functools", init_functools},
+
+	{"xxsubtype", initxxsubtype},
+	{"zipimport", initzipimport},
+	{"zlib", initzlib},
+	
+	/* CJK codecs */
+	{"_multibytecodec", init_multibytecodec},
+	{"_codecs_cn", init_codecs_cn},
+	{"_codecs_hk", init_codecs_hk},
+	{"_codecs_iso2022", init_codecs_iso2022},
+	{"_codecs_jp", init_codecs_jp},
+	{"_codecs_kr", init_codecs_kr},
+	{"_codecs_tw", init_codecs_tw},
+
+/* tools/freeze/makeconfig.py marker for additional "_inittab" entries */
+/* -- ADDMODULE MARKER 2 -- */
+
+        /* This module "lives in" with marshal.c */
+        {"marshal", PyMarshal_Init},
+
+        /* This lives it with import.c */
+        {"imp", initimp},
+
+        /* These entries are here for sys.builtin_module_names */
+        {"__main__", NULL},
+        {"__builtin__", NULL},
+        {"sys", NULL},
+	{"exceptions", NULL},
+        
+        {"_types", init_types},
+
+        /* Sentinel */
+        {0, 0}
+};

Added: vendor/Python/current/PC/dl_nt.c
===================================================================
--- vendor/Python/current/PC/dl_nt.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/dl_nt.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,39 @@
+/*
+
+Entry point for the Windows NT DLL.
+
+About the only reason for having this, is so initall() can automatically
+be called, removing that burden (and possible source of frustration if 
+forgotten) from the programmer.
+
+*/
+#include "windows.h"
+
+/* NT and Python share these */
+#include "pyconfig.h"
+#include "Python.h"
+
+char dllVersionBuffer[16] = ""; // a private buffer
+
+// Python Globals
+HMODULE PyWin_DLLhModule = NULL;
+const char *PyWin_DLLVersionString = dllVersionBuffer;
+
+
+BOOL	WINAPI	DllMain (HANDLE hInst, 
+						ULONG ul_reason_for_call,
+						LPVOID lpReserved)
+{
+	switch (ul_reason_for_call)
+	{
+		case DLL_PROCESS_ATTACH:
+			PyWin_DLLhModule = hInst;
+			// 1000 is a magic number I picked out of the air.  Could do with a #define, I spose...
+			LoadString(hInst, 1000, dllVersionBuffer, sizeof(dllVersionBuffer));
+			//initall();
+			break;
+		case DLL_PROCESS_DETACH:
+			break;
+	}
+	return TRUE;
+}

Added: vendor/Python/current/PC/dllbase_nt.txt
===================================================================
--- vendor/Python/current/PC/dllbase_nt.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/dllbase_nt.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,77 @@
+In Win32, DLL's are "pre-linked" using a specified base address.
+When the DLL is loaded, an attempt is made to place it at
+that address.  If that address is already in use, a new base address
+is selected, and the DLL subject to fixups.  Apparently, these
+fixups are very slow, and significant performance gains can be
+made by selecting a good base address.
+
+This document is to allocate base addresses to core Python
+and Python .PYD files, to give a better change of optimal performance.
+This base address is passed to the linker using the /BASE
+command line switch.
+
+
+Python.exe/Pythonw.exe     - 1d000000 - 1e000000 (-1)
+Python.dll                 - 1e000000 - 1e100000 (-1)
+
+Standard Extension Modules 1e100000 - 1e200000  ""
+ - _symtable                 1e100000 - 1e110000    pyd removed in 2.4
+ - bsddb                     1e180000 - 1e188000
+ - _tkinter                  1e190000 - 1e1A0000
+ - parser                    1e1A0000 - 1e1B0000    pyd removed in 2.4
+ - zlib                      1e1B0000 - 1e1C0000
+ - winreg                    1e1C0000 - 1e1D0000    pyd removed in 2.4
+ - _socket                   1e1D0000 - 1e1E0000
+ - _sre                      1e1E0000 - 1e1F0000    pyd removed in 2.4
+ - mmap                      1e1F0000 - 1e1FFFFF    pyd removed in 2.4
+
+More standard extensions 1D100000 - 1e000000
+ - pyexpat                   1D100000 - 1D110000
+ - select                    1D110000 - 1D120000
+ - unicodedata               1D120000 - 1D160000
+ - winsound                  1D160000 - 1D170000
+ - bZ2                       1D170000 - 1D180000
+ - datetime                  1D180000 - 1D190000    pyd removed in 2.4
+ - _csv                      1D190000 - 1D1A0000    pyd removed in 2.4
+ - _ctypes                   1D1A0000 - 1D1B0000
+
+Other extension modules
+ - win32api                  1e200000 - 1e220000
+ - win32ras                  1e220000 - 1e230000
+ - win32lz                   1e230000 - 1e240000
+ - timer                     1e240000 - 1e250000
+ - mmapfile                  1e250000 - 1e260000
+ - win32pipe                 1e260000 - 1e270000
+ - avl                       1e270000 - 1e270000
+ - dbhash                    1e280000 - 1e290000
+ - win32net                  1e290000 - 1e2A0000
+ - win32security             1e2A0000 - 1e2B0000
+ - win32print                1e2B0000 - 1e2c0000
+ - <unused>                  1e2d0000 - 1e2e0000
+ - win32gui                  1e2e0000 - 1e2f0000
+ - _imaging                  1e2f0000 - 1e300000
+ - multiarray                1e300000 - 1e310000
+ - win32help                 1e310000 - 1e320000
+ - win32clipboard            1e320000 - 1e330000
+ - win2kras                  1e330000 - 1e340000
+ - pythoncom                 1e340000 - 1e400000
+ - win32ui                   1e400000 - 1e500000
+ - win32uiole                1e500000 - 1e600000
+ - pywintypes                1e600000 - 1e700000
+ - win32process              1e700000 - 1e800000
+ - odbc                      1e710000 - 1e720000
+ - dbi                       1e720000 - 1e730000
+ - win32file                 1e730000 - 1e740000
+ - win32wnet                 1e740000 - 1e750000
+ - win32com.shell            1e750000 - 1e760000
+ - win32com.internet         1e760000 - 1e770000
+ - win32com.exchange         1e770000 - 1e780000
+ - win32com.exchdapi         1e780000 - 1e790000
+ - win32com.axscript         1e790000 - 1e7a0000
+ - win32com.axdebug          1e7b0000 - 1e7c0000
+ - win32com.adsi             1e7f0000 - 1e800000
+ - win32event                1e810000 - 1e820000
+ - win32evtlog               1e820000 - 1e830000
+ - win32com.axcontrol        1e830000 - 1e840000
+
+

Added: vendor/Python/current/PC/empty.c
===================================================================
--- vendor/Python/current/PC/empty.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/empty.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,6 @@
+#include <windows.h>
+int __stdcall
+WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
+{
+    return 0;
+}
\ No newline at end of file

Added: vendor/Python/current/PC/errmap.h
===================================================================
--- vendor/Python/current/PC/errmap.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/errmap.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,78 @@
+/* Generated file. Do not edit. */
+int winerror_to_errno(int winerror)
+{
+	switch(winerror) {
+		case 2: return 2;
+		case 3: return 2;
+		case 4: return 24;
+		case 5: return 13;
+		case 6: return 9;
+		case 7: return 12;
+		case 8: return 12;
+		case 9: return 12;
+		case 10: return 7;
+		case 11: return 8;
+		case 15: return 2;
+		case 16: return 13;
+		case 17: return 18;
+		case 18: return 2;
+		case 19: return 13;
+		case 20: return 13;
+		case 21: return 13;
+		case 22: return 13;
+		case 23: return 13;
+		case 24: return 13;
+		case 25: return 13;
+		case 26: return 13;
+		case 27: return 13;
+		case 28: return 13;
+		case 29: return 13;
+		case 30: return 13;
+		case 31: return 13;
+		case 32: return 13;
+		case 33: return 13;
+		case 34: return 13;
+		case 35: return 13;
+		case 36: return 13;
+		case 53: return 2;
+		case 65: return 13;
+		case 67: return 2;
+		case 80: return 17;
+		case 82: return 13;
+		case 83: return 13;
+		case 89: return 11;
+		case 108: return 13;
+		case 109: return 32;
+		case 112: return 28;
+		case 114: return 9;
+		case 128: return 10;
+		case 129: return 10;
+		case 130: return 9;
+		case 132: return 13;
+		case 145: return 41;
+		case 158: return 13;
+		case 161: return 2;
+		case 164: return 11;
+		case 167: return 13;
+		case 183: return 17;
+		case 188: return 8;
+		case 189: return 8;
+		case 190: return 8;
+		case 191: return 8;
+		case 192: return 8;
+		case 193: return 8;
+		case 194: return 8;
+		case 195: return 8;
+		case 196: return 8;
+		case 197: return 8;
+		case 198: return 8;
+		case 199: return 8;
+		case 200: return 8;
+		case 201: return 8;
+		case 202: return 8;
+		case 206: return 2;
+		case 215: return 11;
+		case 1816: return 12;
+		default: return EINVAL;
+	}
+}

Added: vendor/Python/current/PC/errmap.mak
===================================================================
--- vendor/Python/current/PC/errmap.mak	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/errmap.mak	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,5 @@
+errmap.h:	generrmap.exe
+	.\generrmap.exe > errmap.h
+
+genermap.exe:	generrmap.c
+	cl generrmap.c

Added: vendor/Python/current/PC/example_nt/example.c
===================================================================
--- vendor/Python/current/PC/example_nt/example.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/example_nt/example.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,20 @@
+#include "Python.h"
+
+static PyObject *
+ex_foo(PyObject *self, PyObject *args)
+{
+	printf("Hello, world\n");
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyMethodDef example_methods[] = {
+	{"foo", ex_foo, METH_VARARGS, "foo() doc string"},
+	{NULL, NULL}
+};
+
+PyMODINIT_FUNC
+initexample(void)
+{
+	Py_InitModule("example", example_methods);
+}

Added: vendor/Python/current/PC/example_nt/example.sln
===================================================================
--- vendor/Python/current/PC/example_nt/example.sln	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/example_nt/example.sln	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,21 @@
+Microsoft Visual Studio Solution File, Format Version 8.00
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example", "example.vcproj", "{A0608D6F-84ED-44AE-A2A6-A3CC7F4A4030}"
+	ProjectSection(ProjectDependencies) = postProject
+	EndProjectSection
+EndProject
+Global
+	GlobalSection(SolutionConfiguration) = preSolution
+		Debug = Debug
+		Release = Release
+	EndGlobalSection
+	GlobalSection(ProjectConfiguration) = postSolution
+		{A0608D6F-84ED-44AE-A2A6-A3CC7F4A4030}.Debug.ActiveCfg = Debug|Win32
+		{A0608D6F-84ED-44AE-A2A6-A3CC7F4A4030}.Debug.Build.0 = Debug|Win32
+		{A0608D6F-84ED-44AE-A2A6-A3CC7F4A4030}.Release.ActiveCfg = Release|Win32
+		{A0608D6F-84ED-44AE-A2A6-A3CC7F4A4030}.Release.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+	EndGlobalSection
+	GlobalSection(ExtensibilityAddIns) = postSolution
+	EndGlobalSection
+EndGlobal

Added: vendor/Python/current/PC/example_nt/example.vcproj
===================================================================
--- vendor/Python/current/PC/example_nt/example.vcproj	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/example_nt/example.vcproj	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,189 @@
+<?xml version="1.0" encoding="windows-1250"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="example"
+	SccProjectName=""
+	SccLocalPath="">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory=".\Release"
+			IntermediateDirectory=".\Release"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+				StringPooling="TRUE"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				PrecompiledHeaderFile=".\Release/example.pch"
+				AssemblerListingLocation=".\Release/"
+				ObjectFile=".\Release/"
+				ProgramDataBaseFileName=".\Release/"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions="/export:initexample"
+				AdditionalDependencies="odbc32.lib odbccp32.lib python25.lib"
+				OutputFile=".\Release/example.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				AdditionalLibraryDirectories="..\PCbuild"
+				ModuleDefinitionFile=""
+				ProgramDatabaseFile=".\Release/example.pdb"
+				SubSystem="2"
+				ImportLibrary=".\Release/example.lib"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"
+				PreprocessorDefinitions="NDEBUG"
+				MkTypLibCompatible="TRUE"
+				SuppressStartupBanner="TRUE"
+				TargetEnvironment="1"
+				TypeLibraryName=".\Release/example.tlb"
+				HeaderFileName=""/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory=".\Debug"
+			IntermediateDirectory=".\Debug"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="2"
+				PrecompiledHeaderFile=".\Debug/example.pch"
+				AssemblerListingLocation=".\Debug/"
+				ObjectFile=".\Debug/"
+				ProgramDataBaseFileName=".\Debug/"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				DebugInformationFormat="4"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions="/export:initexample"
+				AdditionalDependencies="odbc32.lib odbccp32.lib python25_d.lib"
+				OutputFile=".\Debug/example_d.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				AdditionalLibraryDirectories="..\PCbuild"
+				ModuleDefinitionFile=""
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\Debug/example_d.pdb"
+				SubSystem="2"
+				ImportLibrary=".\Debug/example_d.lib"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"
+				PreprocessorDefinitions="_DEBUG"
+				MkTypLibCompatible="TRUE"
+				SuppressStartupBanner="TRUE"
+				TargetEnvironment="1"
+				TypeLibraryName=".\Debug/example.tlb"
+				HeaderFileName=""/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="_DEBUG"
+				Culture="1033"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90">
+			<File
+				RelativePath="example.c">
+				<FileConfiguration
+					Name="Release|Win32">
+					<Tool
+						Name="VCCLCompilerTool"
+						Optimization="2"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;$(NoInherit)"/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32">
+					<Tool
+						Name="VCCLCompilerTool"
+						Optimization="0"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;$(NoInherit)"/>
+				</FileConfiguration>
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;fi;fd">
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe">
+		</Filter>
+		<File
+			RelativePath="readme.txt">
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Added: vendor/Python/current/PC/example_nt/readme.txt
===================================================================
--- vendor/Python/current/PC/example_nt/readme.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/example_nt/readme.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,161 @@
+Example Python extension for Windows NT
+=======================================
+
+This directory contains everything needed (except for the Python
+distribution!) to build a Python extension module using Microsoft VC++
+("Developer Studio") version 7.1.  It has been tested with VC++ 7.1 on 
+Python 2.4.  You can also use earlier versions of VC to build Python 
+extensions, but the sample VC project file (example.dsw in this directory) 
+is in VC 7.1 format. Notice that you need to use the same compiler version
+that was used to build Python itself.
+
+COPY THIS DIRECTORY!
+--------------------
+This "example_nt" directory is a subdirectory of the PC directory, in order
+to keep all the PC-specific files under the same directory.  However, the
+example_nt directory can't actually be used from this location.  You first
+need to copy or move it up one level, so that example_nt is a direct
+sibling of the PC\ and Include\ directories.  Do all your work from within
+this new location -- sorry, but you'll be sorry if you don't.
+
+OPEN THE PROJECT
+----------------
+From VC 7.1, use the
+    File -> Open Solution...
+dialog (*not* the "File -> Open..." dialog!).  Navigate to and select the
+file "example.sln", in the *copy* of the example_nt directory you made
+above.
+Click Open.
+
+BUILD THE EXAMPLE DLL
+---------------------
+In order to check that everything is set up right, try building:
+
+1. Select a configuration.  This step is optional.  Do
+       Build -> Configuration Manager... -> Active Solution Configuration
+   and select either "Release" or "Debug".
+   If you skip this step, you'll use the Debug configuration by default.
+
+2. Build the DLL.  Do
+       Build -> Build Solution
+   This creates all intermediate and result files in a subdirectory which
+   is called either Debug or Release, depending on which configuration you
+   picked in the preceding step.
+
+TESTING THE DEBUG-MODE DLL
+--------------------------
+Once the Debug build has succeeded, bring up a DOS box, and cd to
+example_nt\Debug.  You should now be able to repeat the following session
+("C>" is the DOS prompt, ">>>" is the Python prompt) (note that various
+debug output from Python may not match this screen dump exactly):
+
+    C>..\..\PCbuild\python_d
+    Adding parser accelerators ...
+    Done.
+    Python 2.2c1+ (#28, Dec 14 2001, 18:06:39) [MSC 32 bit (Intel)] on win32
+    Type "help", "copyright", "credits" or "license" for more information.
+    >>> import example
+    [7052 refs]
+    >>> example.foo()
+    Hello, world
+    [7052 refs]
+    >>>
+
+TESTING THE RELEASE-MODE DLL
+----------------------------
+Once the Release build has succeeded, bring up a DOS box, and cd to
+example_nt\Release.  You should now be able to repeat the following session
+("C>" is the DOS prompt, ">>>" is the Python prompt):
+
+    C>..\..\PCbuild\python
+    Python 2.2c1+ (#28, Dec 14 2001, 18:06:04) [MSC 32 bit (Intel)] on win32
+    Type "help", "copyright", "credits" or "license" for more information.
+    >>> import example
+    >>> example.foo()
+    Hello, world
+    >>>
+
+Congratulations!  You've successfully built your first Python extension
+module.
+
+CREATING YOUR OWN PROJECT
+-------------------------
+Choose a name ("spam" is always a winner :-) and create a directory for
+it.  Copy your C sources into it.  Note that the module source file name
+does not necessarily have to match the module name, but the "init" function
+name should match the module name -- i.e. you can only import a module
+"spam" if its init function is called "initspam()", and it should call
+Py_InitModule with the string "spam" as its first argument (use the minimal
+example.c in this directory as a guide).  By convention, it lives in a file
+called "spam.c" or "spammodule.c".  The output file should be called
+"spam.dll" or "spam.pyd" (the latter is supported to avoid confusion with a
+system library "spam.dll" to which your module could be a Python interface)
+in Release mode, or spam_d.dll or spam_d.pyd in Debug mode.
+
+Now your options are:
+
+1) Copy example.sln and example.vcproj, rename them to spam.*, and edit them
+by hand.
+
+or
+
+2) Create a brand new project; instructions are below.
+
+In either case, copy example_nt\example.def to spam\spam.def, and edit the
+new spam.def so its second line contains the string "initspam".  If you
+created a new project yourself, add the file spam.def to the project now.
+(This is an annoying little file with only two lines.  An alternative
+approach is to forget about the .def file, and add the option
+"/export:initspam" somewhere to the Link settings, by manually editing the
+"Project -> Properties -> Linker -> Command Line -> Additional Options" 
+box).
+
+You are now all set to build your extension, unless it requires other
+external libraries, include files, etc.  See Python's Extending and
+Embedding manual for instructions on how to write an extension.
+
+
+CREATING A BRAND NEW PROJECT
+----------------------------
+Use the
+    File -> New -> Project...
+dialog to create a new Project Workspace.  Select "Visual C++ Projects/Win32/
+Win32 Project", enter the name ("spam"), and make sure the "Location" is 
+set to parent of the spam directory you have created (which should be a direct 
+subdirectory of the Python build tree, a sibling of Include and PC).  
+In "Application Settings", select "DLL", and "Empty Project".  Click OK.
+
+You should now create the file spam.def as instructed in the previous
+section. Add the source files (including the .def file) to the project, 
+using "Project", "Add Existing Item".
+
+Now open the
+    Project -> spam properties...
+dialog.  (Impressive, isn't it? :-) You only need to change a few
+settings.  Make sure "All Configurations" is selected from the "Settings
+for:" dropdown list.  Select the "C/C++" tab.  Choose the "General"
+category in the popup menu at the top.  Type the following text in the
+entry box labeled "Addditional Include Directories:"
+
+    ..\Include,..\PC
+
+Then, choose the "General" category in the "Linker" tab, and enter
+    ..\PCbuild
+in the "Additional library Directories" box.
+
+Now you need to add some mode-specific settings (select "Accept"
+when asked to confirm your changes):
+
+Select "Release" in the "Configuration" dropdown list.  Click the
+"Link" tab, choose the "Input" Category, and append "python24.lib" to the
+list in the "Additional Dependencies" box.
+
+Select "Debug" in the "Settings for:" dropdown list, and append
+"python24_d.lib" to the list in the Additional Dependencies" box.  Then
+click on the C/C++ tab, select "Code Generation", and select 
+"Multi-threaded Debug DLL" from the "Runtime library" dropdown list.
+
+Select "Release" again from the "Settings for:" dropdown list.
+Select "Multi-threaded DLL" from the "Use run-time library:" dropdown list.
+
+That's all <wink>.

Added: vendor/Python/current/PC/frozen_dllmain.c
===================================================================
--- vendor/Python/current/PC/frozen_dllmain.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/frozen_dllmain.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,134 @@
+/* FreezeDLLMain.cpp
+
+This is a DLLMain suitable for frozen applications/DLLs on
+a Windows platform.
+
+The general problem is that many Python extension modules may define
+DLL main functions, but when statically linked together to form
+a frozen application, this DLLMain symbol exists multiple times.
+
+The solution is:
+* Each module checks for a frozen build, and if so, defines its DLLMain
+  function as "__declspec(dllexport) DllMain%module%" 
+  (eg, DllMainpythoncom, or DllMainpywintypes)
+
+* The frozen .EXE/.DLL links against this module, which provides
+  the single DllMain.
+
+* This DllMain attempts to locate and call the DllMain for each
+  of the extension modules.
+
+* This code also has hooks to "simulate" DllMain when used from
+  a frozen .EXE.
+
+At this stage, there is a static table of "possibly embedded modules".
+This should change to something better, but it will work OK for now.
+
+Note that this scheme does not handle dependencies in the order
+of DllMain calls - except it does call pywintypes first :-)
+
+As an example of how an extension module with a DllMain should be
+changed, here is a snippet from the pythoncom extension module.
+
+  // end of example code from pythoncom's DllMain.cpp
+  #ifndef BUILD_FREEZE
+  #define DLLMAIN DllMain
+  #define DLLMAIN_DECL
+  #else
+  #define DLLMAIN DllMainpythoncom
+  #define DLLMAIN_DECL __declspec(dllexport)
+  #endif
+
+  extern "C" DLLMAIN_DECL
+  BOOL WINAPI DLLMAIN(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
+  // end of example code from pythoncom's DllMain.cpp
+
+***************************************************************************/
+#include "windows.h"
+
+static char *possibleModules[] = {
+	"pywintypes",
+	"pythoncom",
+	"win32ui",
+	NULL,
+};
+
+BOOL CallModuleDllMain(char *modName, DWORD dwReason);
+
+
+/*
+  Called by a frozen .EXE only, so that built-in extension
+  modules are initialized correctly
+*/
+void PyWinFreeze_ExeInit(void)
+{
+	char **modName;
+	for (modName = possibleModules;*modName;*modName++) {
+/*		printf("Initialising '%s'\n", *modName); */
+		CallModuleDllMain(*modName, DLL_PROCESS_ATTACH);
+	}
+}
+
+/*
+  Called by a frozen .EXE only, so that built-in extension
+  modules are cleaned up 
+*/
+void PyWinFreeze_ExeTerm(void)
+{
+	// Must go backwards
+	char **modName;
+	for (modName = possibleModules+(sizeof(possibleModules) / sizeof(char *))-2;
+	     modName >= possibleModules;
+	     *modName--) {
+/*		printf("Terminating '%s'\n", *modName);*/
+		CallModuleDllMain(*modName, DLL_PROCESS_DETACH);
+	}
+}
+
+BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
+{
+	BOOL ret = TRUE;
+	switch (dwReason) {
+		case DLL_PROCESS_ATTACH: 
+		{
+			char **modName;
+			for (modName = possibleModules;*modName;*modName++) {
+				BOOL ok = CallModuleDllMain(*modName, dwReason);
+				if (!ok)
+					ret = FALSE;
+			}
+			break;
+		}
+		case DLL_PROCESS_DETACH: 
+		{
+			// Must go backwards
+			char **modName;
+			for (modName = possibleModules+(sizeof(possibleModules) / sizeof(char *))-2;
+			     modName >= possibleModules;
+			     *modName--)
+				CallModuleDllMain(*modName, DLL_PROCESS_DETACH);
+			break;
+		}
+	}
+	return ret;
+}
+
+BOOL CallModuleDllMain(char *modName, DWORD dwReason)
+{
+	BOOL (WINAPI * pfndllmain)(HINSTANCE, DWORD, LPVOID);
+
+	char funcName[255];
+	HMODULE hmod = GetModuleHandle(NULL);
+	strcpy(funcName, "_DllMain");
+	strcat(funcName, modName);
+	strcat(funcName, "@12"); // stdcall convention.
+	pfndllmain = (BOOL (WINAPI *)(HINSTANCE, DWORD, LPVOID))GetProcAddress(hmod, funcName);
+	if (pfndllmain==NULL) {
+		/* No function by that name exported - then that module does
+ 		   not appear in our frozen program - return OK
+                */
+		return TRUE;
+	}
+	return (*pfndllmain)(hmod, dwReason, NULL);
+}
+

Added: vendor/Python/current/PC/generrmap.c
===================================================================
--- vendor/Python/current/PC/generrmap.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/generrmap.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,20 @@
+#include <stdio.h>
+#include <errno.h>
+
+/* Extract the mapping of Win32 error codes to errno */
+
+int main()
+{
+	int i;
+	printf("/* Generated file. Do not edit. */\n");
+	printf("int winerror_to_errno(int winerror)\n");
+	printf("{\n\tswitch(winerror) {\n");
+	for(i=1; i < 65000; i++) {
+		_dosmaperr(i);
+		if (errno == EINVAL)
+			continue;
+		printf("\t\tcase %d: return %d;\n", i, errno);
+	}
+	printf("\t\tdefault: return EINVAL;\n");
+	printf("\t}\n}\n");
+}

Added: vendor/Python/current/PC/getpathp.c
===================================================================
--- vendor/Python/current/PC/getpathp.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/getpathp.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,702 @@
+
+/* Return the initial module search path. */
+/* Used by DOS, OS/2, Windows 3.1, Windows 95/98, Windows NT. */
+
+/* ----------------------------------------------------------------
+   PATH RULES FOR WINDOWS:
+   This describes how sys.path is formed on Windows.  It describes the 
+   functionality, not the implementation (ie, the order in which these 
+   are actually fetched is different)
+
+   * Python always adds an empty entry at the start, which corresponds
+     to the current directory.
+
+   * If the PYTHONPATH env. var. exists, its entries are added next.
+
+   * We look in the registry for "application paths" - that is, sub-keys
+     under the main PythonPath registry key.  These are added next (the
+     order of sub-key processing is undefined).
+     HKEY_CURRENT_USER is searched and added first.
+     HKEY_LOCAL_MACHINE is searched and added next.
+     (Note that all known installers only use HKLM, so HKCU is typically
+     empty)
+
+   * We attempt to locate the "Python Home" - if the PYTHONHOME env var
+     is set, we believe it.  Otherwise, we use the path of our host .EXE's
+     to try and locate our "landmark" (lib\\os.py) and deduce our home.
+     - If we DO have a Python Home: The relevant sub-directories (Lib, 
+       plat-win, lib-tk, etc) are based on the Python Home
+     - If we DO NOT have a Python Home, the core Python Path is
+       loaded from the registry.  This is the main PythonPath key, 
+       and both HKLM and HKCU are combined to form the path)
+
+   * Iff - we can not locate the Python Home, have not had a PYTHONPATH
+     specified, and can't locate any Registry entries (ie, we have _nothing_
+     we can assume is a good path), a default path with relative entries is 
+     used (eg. .\Lib;.\plat-win, etc)
+
+
+  The end result of all this is:
+  * When running python.exe, or any other .exe in the main Python directory
+    (either an installed version, or directly from the PCbuild directory),
+    the core path is deduced, and the core paths in the registry are
+    ignored.  Other "application paths" in the registry are always read.
+
+  * When Python is hosted in another exe (different directory, embedded via 
+    COM, etc), the Python Home will not be deduced, so the core path from
+    the registry is used.  Other "application paths" in the registry are 
+    always read.
+
+  * If Python can't find its home and there is no registry (eg, frozen
+    exe, some very strange installation setup) you get a path with
+    some default, but relative, paths.
+
+   ---------------------------------------------------------------- */
+
+
+#include "Python.h"
+#include "osdefs.h"
+
+#ifdef MS_WINDOWS
+#include <windows.h>
+#include <tchar.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif /* HAVE_SYS_TYPES_H */
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif /* HAVE_SYS_STAT_H */
+
+#include <string.h>
+
+/* Search in some common locations for the associated Python libraries.
+ *
+ * Py_GetPath() tries to return a sensible Python module search path.
+ *
+ * The approach is an adaptation for Windows of the strategy used in
+ * ../Modules/getpath.c; it uses the Windows Registry as one of its
+ * information sources.
+ */
+
+#ifndef LANDMARK
+#define LANDMARK "lib\\os.py"
+#endif
+
+static char prefix[MAXPATHLEN+1];
+static char progpath[MAXPATHLEN+1];
+static char dllpath[MAXPATHLEN+1];
+static char *module_search_path = NULL;
+
+
+static int
+is_sep(char ch)	/* determine if "ch" is a separator character */
+{
+#ifdef ALTSEP
+	return ch == SEP || ch == ALTSEP;
+#else
+	return ch == SEP;
+#endif
+}
+
+/* assumes 'dir' null terminated in bounds.  Never writes
+   beyond existing terminator.
+*/
+static void
+reduce(char *dir)
+{
+	size_t i = strlen(dir);
+	while (i > 0 && !is_sep(dir[i]))
+		--i;
+	dir[i] = '\0';
+}
+	
+
+static int
+exists(char *filename)
+{
+	struct stat buf;
+	return stat(filename, &buf) == 0;
+}
+
+/* Assumes 'filename' MAXPATHLEN+1 bytes long - 
+   may extend 'filename' by one character.
+*/
+static int
+ismodule(char *filename)	/* Is module -- check for .pyc/.pyo too */
+{
+	if (exists(filename))
+		return 1;
+
+	/* Check for the compiled version of prefix. */
+	if (strlen(filename) < MAXPATHLEN) {
+		strcat(filename, Py_OptimizeFlag ? "o" : "c");
+		if (exists(filename))
+			return 1;
+	}
+	return 0;
+}
+
+/* Add a path component, by appending stuff to buffer.
+   buffer must have at least MAXPATHLEN + 1 bytes allocated, and contain a
+   NUL-terminated string with no more than MAXPATHLEN characters (not counting
+   the trailing NUL).  It's a fatal error if it contains a string longer than
+   that (callers must be careful!).  If these requirements are met, it's
+   guaranteed that buffer will still be a NUL-terminated string with no more
+   than MAXPATHLEN characters at exit.  If stuff is too long, only as much of
+   stuff as fits will be appended.
+*/
+static void
+join(char *buffer, char *stuff)
+{
+	size_t n, k;
+	if (is_sep(stuff[0]))
+		n = 0;
+	else {
+		n = strlen(buffer);
+		if (n > 0 && !is_sep(buffer[n-1]) && n < MAXPATHLEN)
+			buffer[n++] = SEP;
+	}
+	if (n > MAXPATHLEN)
+		Py_FatalError("buffer overflow in getpathp.c's joinpath()");
+	k = strlen(stuff);
+	if (n + k > MAXPATHLEN)
+		k = MAXPATHLEN - n;
+	strncpy(buffer+n, stuff, k);
+	buffer[n+k] = '\0';
+}
+
+/* gotlandmark only called by search_for_prefix, which ensures
+   'prefix' is null terminated in bounds.  join() ensures
+   'landmark' can not overflow prefix if too long.
+*/
+static int
+gotlandmark(char *landmark)
+{
+	int ok;
+	Py_ssize_t n;
+
+	n = strlen(prefix);
+	join(prefix, landmark);
+	ok = ismodule(prefix);
+	prefix[n] = '\0';
+	return ok;
+}
+
+/* assumes argv0_path is MAXPATHLEN+1 bytes long, already \0 term'd. 
+   assumption provided by only caller, calculate_path() */
+static int
+search_for_prefix(char *argv0_path, char *landmark)
+{
+	/* Search from argv0_path, until landmark is found */
+	strcpy(prefix, argv0_path);
+	do {
+		if (gotlandmark(landmark))
+			return 1;
+		reduce(prefix);
+	} while (prefix[0]);
+	return 0;
+}
+
+#ifdef MS_WINDOWS
+
+/* a string loaded from the DLL at startup.*/
+extern const char *PyWin_DLLVersionString;
+
+
+/* Load a PYTHONPATH value from the registry.
+   Load from either HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER.
+
+   Works in both Unicode and 8bit environments.  Only uses the
+   Ex family of functions so it also works with Windows CE.
+
+   Returns NULL, or a pointer that should be freed.
+
+   XXX - this code is pretty strange, as it used to also
+   work on Win16, where the buffer sizes werent available
+   in advance.  It could be simplied now Win16/Win32s is dead!
+*/
+
+static char *
+getpythonregpath(HKEY keyBase, int skipcore)
+{
+	HKEY newKey = 0;
+	DWORD dataSize = 0;
+	DWORD numKeys = 0;
+	LONG rc;
+	char *retval = NULL;
+	TCHAR *dataBuf = NULL;
+	static const TCHAR keyPrefix[] = _T("Software\\Python\\PythonCore\\");
+	static const TCHAR keySuffix[] = _T("\\PythonPath");
+	size_t versionLen;
+	DWORD index;
+	TCHAR *keyBuf = NULL;
+	TCHAR *keyBufPtr;
+	TCHAR **ppPaths = NULL;
+
+	/* Tried to use sysget("winver") but here is too early :-( */
+	versionLen = _tcslen(PyWin_DLLVersionString);
+	/* Space for all the chars, plus one \0 */
+	keyBuf = keyBufPtr = malloc(sizeof(keyPrefix) + 
+		                    sizeof(TCHAR)*(versionLen-1) + 
+				    sizeof(keySuffix));
+	if (keyBuf==NULL) goto done;
+
+	memcpy(keyBufPtr, keyPrefix, sizeof(keyPrefix)-sizeof(TCHAR));
+	keyBufPtr += sizeof(keyPrefix)/sizeof(TCHAR) - 1;
+	memcpy(keyBufPtr, PyWin_DLLVersionString, versionLen * sizeof(TCHAR));
+	keyBufPtr += versionLen;
+	/* NULL comes with this one! */
+	memcpy(keyBufPtr, keySuffix, sizeof(keySuffix));
+	/* Open the root Python key */
+	rc=RegOpenKeyEx(keyBase,
+	                keyBuf, /* subkey */
+	                0, /* reserved */
+	                KEY_READ,
+	                &newKey);
+	if (rc!=ERROR_SUCCESS) goto done;
+	/* Find out how big our core buffer is, and how many subkeys we have */
+	rc = RegQueryInfoKey(newKey, NULL, NULL, NULL, &numKeys, NULL, NULL, 
+	                NULL, NULL, &dataSize, NULL, NULL);
+	if (rc!=ERROR_SUCCESS) goto done;
+	if (skipcore) dataSize = 0; /* Only count core ones if we want them! */
+	/* Allocate a temp array of char buffers, so we only need to loop 
+	   reading the registry once
+	*/
+	ppPaths = malloc( sizeof(TCHAR *) * numKeys );
+	if (ppPaths==NULL) goto done;
+	memset(ppPaths, 0, sizeof(TCHAR *) * numKeys);
+	/* Loop over all subkeys, allocating a temp sub-buffer. */
+	for(index=0;index<numKeys;index++) {
+		TCHAR keyBuf[MAX_PATH+1];
+		HKEY subKey = 0;
+		DWORD reqdSize = MAX_PATH+1;
+		/* Get the sub-key name */
+		DWORD rc = RegEnumKeyEx(newKey, index, keyBuf, &reqdSize,
+		                        NULL, NULL, NULL, NULL );
+		if (rc!=ERROR_SUCCESS) goto done;
+		/* Open the sub-key */
+		rc=RegOpenKeyEx(newKey,
+						keyBuf, /* subkey */
+						0, /* reserved */
+						KEY_READ,
+						&subKey);
+		if (rc!=ERROR_SUCCESS) goto done;
+		/* Find the value of the buffer size, malloc, then read it */
+		RegQueryValueEx(subKey, NULL, 0, NULL, NULL, &reqdSize);
+		if (reqdSize) {
+			ppPaths[index] = malloc(reqdSize);
+			if (ppPaths[index]) {
+				RegQueryValueEx(subKey, NULL, 0, NULL, 
+				                (LPBYTE)ppPaths[index], 
+				                &reqdSize);
+				dataSize += reqdSize + 1; /* 1 for the ";" */
+			}
+		}
+		RegCloseKey(subKey);
+	}
+
+	/* return null if no path to return */
+	if (dataSize == 0) goto done;
+
+	/* original datasize from RegQueryInfo doesn't include the \0 */
+	dataBuf = malloc((dataSize+1) * sizeof(TCHAR));
+	if (dataBuf) {
+		TCHAR *szCur = dataBuf;
+		DWORD reqdSize = dataSize;
+		/* Copy our collected strings */
+		for (index=0;index<numKeys;index++) {
+			if (index > 0) {
+				*(szCur++) = _T(';');
+				dataSize--;
+			}
+			if (ppPaths[index]) {
+				Py_ssize_t len = _tcslen(ppPaths[index]);
+				_tcsncpy(szCur, ppPaths[index], len);
+				szCur += len;
+				assert(dataSize > (DWORD)len);
+				dataSize -= (DWORD)len;
+			}
+		}
+		if (skipcore)
+			*szCur = '\0';
+		else {
+			/* If we have no values, we dont need a ';' */
+			if (numKeys) {
+				*(szCur++) = _T(';');
+				dataSize--;
+			}
+			/* Now append the core path entries - 
+			   this will include the NULL 
+			*/
+			rc = RegQueryValueEx(newKey, NULL, 0, NULL, 
+			                     (LPBYTE)szCur, &dataSize);
+		}
+		/* And set the result - caller must free 
+		   If MBCS, it is fine as is.  If Unicode, allocate new
+		   buffer and convert.
+		*/
+#ifdef UNICODE
+		retval = (char *)malloc(reqdSize+1);
+		if (retval)
+			WideCharToMultiByte(CP_ACP, 0, 
+					dataBuf, -1, /* source */ 
+					retval, reqdSize+1, /* dest */
+					NULL, NULL);
+		free(dataBuf);
+#else
+		retval = dataBuf;
+#endif
+	}
+done:
+	/* Loop freeing my temp buffers */
+	if (ppPaths) {
+		for(index=0;index<numKeys;index++)
+			if (ppPaths[index]) free(ppPaths[index]);
+		free(ppPaths);
+	}
+	if (newKey)
+		RegCloseKey(newKey);
+	if (keyBuf)
+		free(keyBuf);
+	return retval;
+}
+#endif /* MS_WINDOWS */
+
+static void
+get_progpath(void)
+{
+	extern char *Py_GetProgramName(void);
+	char *path = getenv("PATH");
+	char *prog = Py_GetProgramName();
+
+#ifdef MS_WINDOWS
+	extern HANDLE PyWin_DLLhModule;
+#ifdef UNICODE
+	WCHAR wprogpath[MAXPATHLEN+1];
+	/* Windows documents that GetModuleFileName() will "truncate",
+	   but makes no mention of the null terminator.  Play it safe.
+	   PLUS Windows itself defines MAX_PATH as the same, but anyway...
+	*/
+	wprogpath[MAXPATHLEN]=_T('\0');
+	if (PyWin_DLLhModule &&
+	    GetModuleFileName(PyWin_DLLhModule, wprogpath, MAXPATHLEN)) {
+		WideCharToMultiByte(CP_ACP, 0, 
+		                    wprogpath, -1, 
+		                    dllpath, MAXPATHLEN+1, 
+		                    NULL, NULL);
+	}
+	wprogpath[MAXPATHLEN]=_T('\0');
+	if (GetModuleFileName(NULL, wprogpath, MAXPATHLEN)) {
+		WideCharToMultiByte(CP_ACP, 0, 
+		                    wprogpath, -1, 
+		                    progpath, MAXPATHLEN+1, 
+		                    NULL, NULL);
+		return;
+	}
+#else
+	/* static init of progpath ensures final char remains \0 */
+	if (PyWin_DLLhModule)
+		if (!GetModuleFileName(PyWin_DLLhModule, dllpath, MAXPATHLEN))
+			dllpath[0] = 0;
+	if (GetModuleFileName(NULL, progpath, MAXPATHLEN))
+		return;
+#endif
+#endif
+	if (prog == NULL || *prog == '\0')
+		prog = "python";
+
+	/* If there is no slash in the argv0 path, then we have to
+	 * assume python is on the user's $PATH, since there's no
+	 * other way to find a directory to start the search from.  If
+	 * $PATH isn't exported, you lose.
+	 */
+#ifdef ALTSEP
+	if (strchr(prog, SEP) || strchr(prog, ALTSEP))
+#else
+	if (strchr(prog, SEP))
+#endif
+		strncpy(progpath, prog, MAXPATHLEN);
+	else if (path) {
+		while (1) {
+			char *delim = strchr(path, DELIM);
+
+			if (delim) {
+				size_t len = delim - path;
+				/* ensure we can't overwrite buffer */
+				len = min(MAXPATHLEN,len);
+				strncpy(progpath, path, len);
+				*(progpath + len) = '\0';
+			}
+			else
+				strncpy(progpath, path, MAXPATHLEN);
+
+			/* join() is safe for MAXPATHLEN+1 size buffer */
+			join(progpath, prog);
+			if (exists(progpath))
+				break;
+
+			if (!delim) {
+				progpath[0] = '\0';
+				break;
+			}
+			path = delim + 1;
+		}
+	}
+	else
+		progpath[0] = '\0';
+}
+
+static void
+calculate_path(void)
+{
+	char argv0_path[MAXPATHLEN+1];
+	char *buf;
+	size_t bufsz;
+	char *pythonhome = Py_GetPythonHome();
+	char *envpath = Py_GETENV("PYTHONPATH");
+
+#ifdef MS_WINDOWS
+	int skiphome, skipdefault;
+	char *machinepath = NULL;
+	char *userpath = NULL;
+	char zip_path[MAXPATHLEN+1];
+	size_t len;
+#endif
+
+	get_progpath();
+	/* progpath guaranteed \0 terminated in MAXPATH+1 bytes. */
+	strcpy(argv0_path, progpath);
+	reduce(argv0_path);
+	if (pythonhome == NULL || *pythonhome == '\0') {
+		if (search_for_prefix(argv0_path, LANDMARK))
+			pythonhome = prefix;
+		else
+			pythonhome = NULL;
+	}
+	else
+		strncpy(prefix, pythonhome, MAXPATHLEN);
+
+	if (envpath && *envpath == '\0')
+		envpath = NULL;
+
+
+#ifdef MS_WINDOWS
+	/* Calculate zip archive path */
+	if (dllpath[0])		/* use name of python DLL */
+		strncpy(zip_path, dllpath, MAXPATHLEN);
+	else			/* use name of executable program */
+		strncpy(zip_path, progpath, MAXPATHLEN);
+	zip_path[MAXPATHLEN] = '\0';
+	len = strlen(zip_path);
+	if (len > 4) {
+		zip_path[len-3] = 'z';	/* change ending to "zip" */
+		zip_path[len-2] = 'i';
+		zip_path[len-1] = 'p';
+	}
+	else {
+		zip_path[0] = 0;
+	}
+ 
+	skiphome = pythonhome==NULL ? 0 : 1;
+	machinepath = getpythonregpath(HKEY_LOCAL_MACHINE, skiphome);
+	userpath = getpythonregpath(HKEY_CURRENT_USER, skiphome);
+	/* We only use the default relative PYTHONPATH if we havent
+	   anything better to use! */
+	skipdefault = envpath!=NULL || pythonhome!=NULL || \
+		      machinepath!=NULL || userpath!=NULL;
+#endif
+
+	/* We need to construct a path from the following parts.
+	   (1) the PYTHONPATH environment variable, if set;
+	   (2) for Win32, the zip archive file path;
+	   (3) for Win32, the machinepath and userpath, if set;
+	   (4) the PYTHONPATH config macro, with the leading "."
+	       of each component replaced with pythonhome, if set;
+	   (5) the directory containing the executable (argv0_path).
+	   The length calculation calculates #4 first.
+	   Extra rules:
+	   - If PYTHONHOME is set (in any way) item (3) is ignored.
+	   - If registry values are used, (4) and (5) are ignored.
+	*/
+
+	/* Calculate size of return buffer */
+	if (pythonhome != NULL) {
+		char *p;
+		bufsz = 1;	
+		for (p = PYTHONPATH; *p; p++) {
+			if (*p == DELIM)
+				bufsz++; /* number of DELIM plus one */
+		}
+		bufsz *= strlen(pythonhome);
+	}
+	else
+		bufsz = 0;
+	bufsz += strlen(PYTHONPATH) + 1;
+	bufsz += strlen(argv0_path) + 1;
+#ifdef MS_WINDOWS
+	if (userpath)
+		bufsz += strlen(userpath) + 1;
+	if (machinepath)
+		bufsz += strlen(machinepath) + 1;
+	bufsz += strlen(zip_path) + 1;
+#endif
+	if (envpath != NULL)
+		bufsz += strlen(envpath) + 1;
+
+	module_search_path = buf = malloc(bufsz);
+	if (buf == NULL) {
+		/* We can't exit, so print a warning and limp along */
+		fprintf(stderr, "Can't malloc dynamic PYTHONPATH.\n");
+		if (envpath) {
+			fprintf(stderr, "Using environment $PYTHONPATH.\n");
+			module_search_path = envpath;
+		}
+		else {
+			fprintf(stderr, "Using default static path.\n");
+			module_search_path = PYTHONPATH;
+		}
+#ifdef MS_WINDOWS
+		if (machinepath)
+			free(machinepath);
+		if (userpath)
+			free(userpath);
+#endif /* MS_WINDOWS */
+		return;
+	}
+
+	if (envpath) {
+		strcpy(buf, envpath);
+		buf = strchr(buf, '\0');
+		*buf++ = DELIM;
+	}
+#ifdef MS_WINDOWS
+	if (zip_path[0]) {
+		strcpy(buf, zip_path);
+		buf = strchr(buf, '\0');
+		*buf++ = DELIM;
+	}
+	if (userpath) {
+		strcpy(buf, userpath);
+		buf = strchr(buf, '\0');
+		*buf++ = DELIM;
+		free(userpath);
+	}
+	if (machinepath) {
+		strcpy(buf, machinepath);
+		buf = strchr(buf, '\0');
+		*buf++ = DELIM;
+		free(machinepath);
+	}
+	if (pythonhome == NULL) {
+		if (!skipdefault) {
+			strcpy(buf, PYTHONPATH);
+			buf = strchr(buf, '\0');
+		}
+	}
+#else
+	if (pythonhome == NULL) {
+		strcpy(buf, PYTHONPATH);
+		buf = strchr(buf, '\0');
+	}
+#endif /* MS_WINDOWS */
+	else {
+		char *p = PYTHONPATH;
+		char *q;
+		size_t n;
+		for (;;) {
+			q = strchr(p, DELIM);
+			if (q == NULL)
+				n = strlen(p);
+			else
+				n = q-p;
+			if (p[0] == '.' && is_sep(p[1])) {
+				strcpy(buf, pythonhome);
+				buf = strchr(buf, '\0');
+				p++;
+				n--;
+			}
+			strncpy(buf, p, n);
+			buf += n;
+			if (q == NULL)
+				break;
+			*buf++ = DELIM;
+			p = q+1;
+		}
+	}
+	if (argv0_path) {
+		*buf++ = DELIM;
+		strcpy(buf, argv0_path);
+		buf = strchr(buf, '\0');
+	}
+	*buf = '\0';
+	/* Now to pull one last hack/trick.  If sys.prefix is
+	   empty, then try and find it somewhere on the paths
+	   we calculated.  We scan backwards, as our general policy
+	   is that Python core directories are at the *end* of
+	   sys.path.  We assume that our "lib" directory is
+	   on the path, and that our 'prefix' directory is
+	   the parent of that.
+	*/
+	if (*prefix=='\0') {
+		char lookBuf[MAXPATHLEN+1];
+		char *look = buf - 1; /* 'buf' is at the end of the buffer */
+		while (1) {
+			Py_ssize_t nchars;
+			char *lookEnd = look;
+			/* 'look' will end up one character before the
+			   start of the path in question - even if this
+			   is one character before the start of the buffer
+			*/
+			while (*look != DELIM && look >= module_search_path)
+				look--;
+			nchars = lookEnd-look;
+			strncpy(lookBuf, look+1, nchars);
+			lookBuf[nchars] = '\0';
+			/* Up one level to the parent */
+			reduce(lookBuf);
+			if (search_for_prefix(lookBuf, LANDMARK)) {
+				break;
+			}
+			/* If we are out of paths to search - give up */
+			if (look < module_search_path)
+				break;
+			look--;
+		}
+	}
+}
+
+
+/* External interface */
+
+char *
+Py_GetPath(void)
+{
+	if (!module_search_path)
+		calculate_path();
+	return module_search_path;
+}
+
+char *
+Py_GetPrefix(void)
+{
+	if (!module_search_path)
+		calculate_path();
+	return prefix;
+}
+
+char *
+Py_GetExecPrefix(void)
+{
+	return Py_GetPrefix();
+}
+
+char *
+Py_GetProgramFullPath(void)
+{
+	if (!module_search_path)
+		calculate_path();
+	return progpath;
+}

Added: vendor/Python/current/PC/icons/baselogo.svg
===================================================================
--- vendor/Python/current/PC/icons/baselogo.svg	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/icons/baselogo.svg	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,609 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg version="1.0" width="744.09448" height="1052.3622" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+  <defs>
+    <linearGradient id="pyYellowGradient">
+      <stop  offset="0" style="stop-color:#ffc130;stop-opacity:1"/>
+      <stop  offset="1" style="stop-color:#ffea5b;stop-opacity:1"/>
+    </linearGradient>
+    <linearGradient id="pyBlueGradient">
+      <stop style="stop-color:#426684;stop-opacity:1" offset="0"/>
+      <stop style="stop-color:#357cb5;stop-opacity:1" offset="1"/>
+    </linearGradient>
+    <linearGradient id="pyYellow" xlink:href="#pyYellowGradient" x1="1108.9739" y1="3365.6448" x2="949.80927" y2="3144.1941" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.317715,0,0,0.317715,-172.579,-583.027)"/>
+    <linearGradient id="pyBlue" xlink:href="#pyBlueGradient" x1="607.27795" y1="1841.619" x2="472.67371" y2="1660.6002" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.317715,0,0,0.317715,-71.39343,-151.2348)"/>
+  </defs>
+
+  <g
+     id="layer1">
+    <path
+       d="M 88.126188,110.89374 C 88.126188,99.932569 97.021954,91.036422 107.98312,91.023301 L 147.69781,91.023301 C 158.65898,91.036435 167.55475,99.932569 167.55475,110.88023 L 167.55475,148.11929 C 167.55475,159.08046 158.65898,167.97661 147.69781,167.97661 L 107.98312,167.97661 C 94.281853,167.97661 83.161955,179.0965 83.161955,192.79777 L 83.161955,210.17955 L 68.268873,210.16643 C 57.307706,210.17955 48.411559,201.27028 48.411559,190.30911 L 48.411559,150.59472 C 48.411559,139.64668 57.307706,130.73741 68.268873,130.73741 L 127.84044,130.75054 L 127.84044,125.78631 L 88.126061,125.78631 L 88.126061,110.89361 L 88.126188,110.89374 z M 105.49443,100.96489 C 109.61173,100.96489 112.94774,104.3009 112.94774,108.40504 C 112.94774,112.52196 109.61173,115.85797 105.49443,115.85797 C 101.39066,115.85797 98.041501,112.52196 98.041501,108.40504 C 98.041501,104.3009 101.39063,100.96489 105.49443,100.96489 z "
+       style="fill:#426684;fill-rule:evenodd"
+       id="path6" />
+    <g
+       transform="matrix(0.317715,0,0,0.317715,-71.39343,-151.2348)"
+       style="fill-rule:evenodd"
+       id="_19410248">
+   <g
+   id="g9">
+    <path
+   d="M 1102.42,902.293 C 1160.3365,901.33394 1186.6279,955.8347 1187.0861,1017.668 C 1187.0861,1072.1676 1159.8369,1123.293 1101.4196,1125.21 C 1077.5861,1125.21 1057.1283,1117.9179 1037.17,1105.7513 L 1037.17,1231.8353 L 1002.1279,1219.168 L 1002.6287,939.293 C 1002.1279,939.293 1029.8779,902.7934 1101.9204,901.793 L 1102.42,902.29379 L 1102.42,902.293 z M 1093.6279,1099.917 C 1140.3783,1097.0009 1146.2118,1051.2509 1146.2118,1015.2095 C 1146.2118,980.1674 1140.3783,927.5835 1096.087,925.6678 C 1065.9205,923.70953 1041.5449,937.8343 1036.7118,942.7087 L 1036.7118,1081.4177 C 1048.3787,1088.7098 1071.7527,1101.376 1093.6279,1099.9173 L 1093.6279,1099.917 z "
+   style="fill:#6a6a6a"
+   id="_19410568" />
+
+    <path
+   d="M 1261,1051.25 L 1261,901.791 L 1224.9587,913.9587 L 1224.9587,1061.9577 C 1224.9587,1101.3746 1261.4996,1124.249 1293.6244,1124.249 C 1335.4579,1124.249 1359.3327,1112.5833 1370.0405,1107.7077 C 1370.4988,1113.0416 1370.0405,1111.5829 1370.0405,1116.9581 C 1370.0405,1132.5416 1369.5409,1159.2912 1362.2488,1172.9164 C 1347.6244,1200.6664 1308.7071,1204.5416 1281.4579,1208.4581 L 1287.2902,1230.8329 C 1323.2902,1229.875 1373.9158,1216.2498 1391.9162,1182.1668 C 1402.1658,1162.7081 1403.6245,1125.2081 1403.6245,1100.4168 L 1403.6245,907.16579 L 1368.0828,907.16579 L 1368.0828,1080.9168 C 1356.4159,1088.7085 1335.0001,1099.4164 1315.9997,1099.916 C 1284.3745,1100.4168 1261.0005,1083.3747 1261.0005,1050.7491 L 1261.0005,1051.2499 L 1261,1051.25 z "
+   style="fill:#6a6a6a"
+   id="_19412384" />
+
+    <path
+   d="M 1463.29,930.043 L 1463.29,1069.751 C 1463.29,1106.2506 1491.5396,1127.6675 1538.7483,1123.2927 L 1538.7483,1104.7931 C 1513.9144,1103.7927 1498.8318,1097.0014 1498.8318,1068.7506 L 1498.8318,930.0436 L 1538.7483,930.0436 L 1538.7483,907.168 L 1498.8318,907.168 L 1498.8318,835.1267 L 1463.2901,847.7928 L 1463.2901,907.168 L 1438.957,907.168 L 1438.957,930.0436 L 1463.2901,930.0436 L 1463.29,930.043 z "
+   style="fill:#6a6a6a"
+   id="_19413104" />
+
+    <path
+   d="M 1754.5,1120.33 L 1754.5,971.914 C 1754.5,934.9136 1729.1665,905.7061 1691.2083,905.7061 C 1662.5004,905.7061 1638.1674,914.95531 1616.7504,930.4974 L 1616.7504,781.0804 L 1581.2087,792.2879 L 1581.2087,1120.3299 L 1616.7504,1120.3299 L 1616.7504,955.8309 C 1634.7504,943.1636 1655.2083,930.0392 1677.5831,930.0392 C 1706.2922,930.0392 1718.4587,958.2475 1718.4587,983.0801 L 1718.4587,1120.3301 L 1754.5,1120.3301 L 1754.5,1120.33 z "
+   style="fill:#6a6a6a"
+   id="_19415136" />
+
+    <path
+   d="M 1786.29,1009.88 C 1786.29,1068.7544 1817.4569,1124.254 1883.1652,1124.755 C 1949.3731,1124.2542 1981.4991,1068.7542 1981.4991,1009.88 C 1980.9983,952.4217 1944.9983,902.297 1883.6648,901.796 C 1822.8321,902.29679 1786.29,952.4216 1786.29,1009.88 L 1786.29,1009.88 z M 1824.7491,1009.88 C 1824.7491,971.4221 1834.4979,929.0879 1883.1652,926.1304 C 1928.9152,928.58827 1942.5404,971.4221 1942.5404,1009.88 C 1942.5404,1050.7544 1933.7896,1101.38 1884.1231,1102.8387 C 1838.3731,1102.3379 1825.2487,1050.7544 1825.2487,1009.88 L 1824.7491,1009.88 L 1824.7491,1009.88 z "
+   style="fill:#6a6a6a"
+   id="_19416104" />
+
+    <path
+   d="M 2184.04,1120.33 L 2184.04,957.288 C 2184.04,928.5801 2161.1644,910.0805 2135.3727,904.2471 C 2110.0392,898.41364 2086.207,903.24671 2068.7066,908.1223 C 2046.2893,913.95576 2030.2475,924.2054 2012.2062,937.3298 L 2012.2062,1120.3298 L 2047.7479,1120.3298 L 2047.7479,941.7058 C 2058.9566,933.91407 2076.9566,925.6641 2095.957,925.1633 C 2127.0814,924.66369 2148.4983,942.705 2148.4983,975.2881 L 2148.4983,1120.3301 L 2184.04,1120.3301 L 2184.04,1120.33 z "
+   style="fill:#6a6a6a"
+   id="_19416592" />
+
+   </g>
+
+  </g>
+    <path
+       d="M 167.55462,230.0232 C 167.55462,240.98437 158.65885,249.88051 147.69769,249.89364 L 107.98299,249.89364 C 97.021827,249.88051 88.126061,240.98437 88.126061,230.0367 L 88.126061,192.79765 C 88.126061,181.83648 97.021827,172.94071 107.98299,172.94071 L 147.69769,172.94071 C 161.39896,172.94071 172.51923,161.82043 172.51923,148.11916 L 172.51923,130.73739 L 187.41193,130.75052 C 198.3731,130.73739 207.26925,139.64667 207.26925,150.60784 L 207.26925,190.3222 C 207.26925,201.27025 198.3731,210.17952 187.41193,210.17952 L 127.84037,210.16639 L 127.84037,215.13063 L 167.55475,215.13063 L 167.55475,230.02333 L 167.55462,230.0232 z M 150.17323,239.95205 C 146.06946,239.95205 142.73345,236.61604 142.73345,232.51227 C 142.73345,228.39497 146.06946,225.05897 150.17323,225.05897 C 154.29015,225.05897 157.62615,228.39497 157.62615,232.51227 C 157.62615,236.61604 154.29015,239.95205 150.17323,239.95205 z "
+       style="fill:#d3aa3f;fill-rule:evenodd"
+       id="path17" />
+    <g
+       transform="matrix(0.317715,0,0,0.317715,-71.39343,-151.2348)"
+       style="fill-rule:evenodd"
+       id="g1699">
+      <polygon
+         points="335.222,626.069 334.291,620.493 334.291,615.508 338.458,615.508 338.458,620.493 337.486,626.069 335.222,626.069 "
+         style="fill:#000000;fill-rule:nonzero"
+         id="_19419944" />
+      <path
+         d="M 341.798,634.527 C 341.798,630.52779 342.90942,627.56204 345.13816,625.6392 C 346.99249,624.04117 349.25666,623.23566 351.9295,623.23566 C 354.90233,623.23566 357.33186,624.20889 359.21454,626.16007 C 361.10312,628.10416 362.04092,630.79117 362.04092,634.22227 C 362.04092,637.00613 361.62399,639.19471 360.79013,640.78447 C 359.95745,642.38132 358.7421,643.61793 357.15233,644.49904 C 355.5543,645.38132 353.81808,645.81951 351.9295,645.81951 C 348.90942,645.81951 346.46454,644.85337 344.59604,642.90927 C 342.72872,640.97226 341.79801,638.18014 341.79801,634.52699 L 341.798,634.527 z M 345.56217,634.527 C 345.56217,637.29787 346.16571,639.36834 347.37398,640.74314 C 348.58225,642.12503 350.10351,642.81243 351.92949,642.81243 C 353.74957,642.81243 355.26256,642.11794 356.47083,640.73605 C 357.67319,639.35416 358.27674,637.24235 358.27674,634.41007 C 358.27674,631.73605 357.6732,629.7081 356.45784,628.3333 C 355.24249,626.9585 353.7354,626.2711 351.92949,626.2711 C 350.10351,626.2711 348.58225,626.9585 347.37398,628.32622 C 346.16571,629.69394 345.56217,631.76323 345.56217,634.52701 L 345.56217,634.527 z "
+         style="fill:#000000;fill-rule:nonzero"
+         id="path21" />
+      <path
+         d="M 366.298,645.333 L 366.298,623.7295 L 369.58973,623.7295 L 369.58973,626.99997 C 370.42949,625.4728 371.20784,624.45824 371.92241,623.9728 C 372.63107,623.48619 373.41532,623.23579 374.27044,623.23579 C 375.50587,623.23579 376.75666,623.63264 378.03343,624.41689 L 376.76965,627.81965 C 375.88146,627.28461 374.985,627.02123 374.08973,627.02123 C 373.28422,627.02123 372.56847,627.26453 371.92949,627.74288 C 371.29051,628.2295 370.83933,628.89564 370.56886,629.74957 C 370.15902,631.04878 369.95823,632.47201 369.95823,634.02044 L 369.95823,645.33304 L 366.29799,645.33304 L 366.298,645.333 z "
+         style="fill:#000000;fill-rule:nonzero"
+         id="path23" />
+      <path
+         d="M 380.228,619.722 L 380.228,615.50783 L 383.89414,615.50783 L 383.89414,619.722 L 380.228,619.722 z M 380.228,645.333 L 380.228,623.7295 L 383.89414,623.7295 L 383.89414,645.333 L 380.228,645.333 z "
+         style="fill:#000000;fill-rule:nonzero"
+         id="path25" />
+      <path
+         d="M 388.796,647.125 L 392.3582,647.65295 C 392.50466,648.75019 392.92041,649.54862 393.59481,650.05531 C 394.50426,650.72854 395.74678,651.0687 397.31646,651.0687 C 399.01843,651.0687 400.32355,650.72855 401.24717,650.05531 C 402.17079,649.375 402.78851,648.42303 403.11449,647.20767 C 403.30937,646.45767 403.39323,644.89625 403.37906,642.50688 C 401.78221,644.38838 399.78851,645.33326 397.40032,645.33326 C 394.42749,645.33326 392.12906,644.26436 390.50386,642.1183 C 388.87984,639.97932 388.06016,637.40334 388.06016,634.41043 C 388.06016,632.34704 388.43457,630.44429 389.17748,628.70216 C 389.92748,626.95885 391.01173,625.61122 392.42787,624.66043 C 393.84401,623.71555 395.51055,623.23602 397.42039,623.23602 C 399.96921,623.23602 402.07393,624.27067 403.7263,626.33405 L 403.7263,623.72972 L 407.1078,623.72972 L 407.1078,642.40292 C 407.1078,645.76434 406.76055,648.15253 406.08024,649.55568 C 405.39283,650.95765 404.30977,652.06907 402.82394,652.88166 C 401.33693,653.69426 399.51095,654.1041 397.33772,654.1041 C 394.76055,654.1041 392.67827,653.52064 391.09441,652.36079 C 389.50465,651.20095 388.74047,649.45764 388.79598,647.12496 L 388.796,647.125 z M 391.82317,634.1459 C 391.82317,636.97936 392.38656,639.04866 393.51805,640.34787 C 394.64364,641.65299 396.0527,642.29905 397.74758,642.29905 C 399.42711,642.29905 400.83734,641.65299 401.97593,640.36086 C 403.11451,639.06283 403.68499,637.03488 403.68499,634.26401 C 403.68499,631.61834 403.10153,629.62582 401.92751,628.28527 C 400.75349,626.94472 399.33735,626.27149 397.68499,626.27149 C 396.05979,626.27149 394.6779,626.93054 393.53223,628.25692 C 392.39365,629.57621 391.82317,631.54157 391.82317,634.1459 L 391.82317,634.1459 z "
+         style="fill:#000000;fill-rule:nonzero"
+         id="path27" />
+      <path
+         d="M 412.657,619.722 L 412.657,615.50783 L 416.32314,615.50783 L 416.32314,619.722 L 412.657,619.722 z M 412.657,645.333 L 412.657,623.7295 L 416.32314,623.7295 L 416.32314,645.333 L 412.657,645.333 z "
+         style="fill:#000000;fill-rule:nonzero"
+         id="path29" />
+      <path
+         d="M 421.899,645.333 L 421.899,623.7295 L 425.19073,623.7295 L 425.19073,626.79919 C 426.78167,624.42399 429.07301,623.2358 432.06593,623.2358 C 433.37105,623.2358 434.56514,623.47202 435.65648,623.93737 C 436.75372,624.40982 437.56514,625.02045 438.10727,625.78462 C 438.65648,626.5417 439.03089,627.44407 439.25294,628.4858 C 439.38522,629.16729 439.45491,630.3543 439.45491,632.04919 L 439.45491,645.33309 L 435.78759,645.33309 L 435.78759,632.18739 C 435.78759,630.70156 435.6494,629.58306 435.36475,628.84015 C 435.08011,628.10432 434.57223,627.51377 433.85058,627.07676 C 433.12184,626.63266 432.27381,626.40943 431.29467,626.40943 C 429.73207,626.40943 428.3927,626.91022 427.25294,627.89644 C 426.12144,628.88857 425.55924,630.76416 425.55924,633.53502 L 425.55924,645.33302 L 421.899,645.33302 L 421.899,645.333 z "
+         style="fill:#000000;fill-rule:nonzero"
+         id="path31" />
+      <path
+         d="M 459.17,642.666 C 457.80819,643.81876 456.50307,644.63135 455.25346,645.11088 C 453.99559,645.58332 452.64913,645.81954 451.21173,645.81954 C 448.83653,645.81954 447.01764,645.24316 445.73968,644.08332 C 444.46881,642.92348 443.82984,641.43765 443.82984,639.63883 C 443.82984,638.57584 444.06606,637.61088 444.55149,636.73568 C 445.03102,635.86048 445.66291,635.16009 446.44125,634.63214 C 447.22551,634.10419 448.1007,633.70143 449.07983,633.43096 C 449.7944,633.24317 450.87865,633.05537 452.32904,632.88175 C 455.2877,632.52742 457.46802,632.11049 458.86408,631.61797 C 458.87826,631.11836 458.88534,630.79828 458.88534,630.666 C 458.88534,629.17309 458.5381,628.11836 457.84361,627.51364 C 456.9129,626.68096 455.51684,626.27112 453.67668,626.27112 C 451.95463,626.27112 450.68377,626.56994 449.85699,627.17348 C 449.03731,627.77821 448.43376,628.8471 448.03809,630.38135 L 444.46171,629.88883 C 444.7877,628.36166 445.32274,627.11796 446.06565,626.18017 C 446.80857,625.23647 447.89163,624.50655 449.30187,623.99986 C 450.71093,623.49317 452.34321,623.23569 454.20463,623.23569 C 456.05187,623.23569 457.54479,623.45892 458.69754,623.88884 C 459.8503,624.32703 460.69715,624.86797 461.24636,625.52821 C 461.78731,626.18726 462.1629,627.01404 462.38494,628.02034 C 462.50305,628.64632 462.56565,629.77073 462.56565,631.39593 L 462.56565,636.27743 C 462.56565,639.68727 462.64124,641.84042 462.80187,642.7357 C 462.95423,643.63806 463.26723,644.50617 463.72549,645.33294 L 459.89872,645.33294 C 459.52432,644.57585 459.27392,643.68766 459.16998,642.66601 L 459.17,642.666 z M 458.86409,634.48569 C 457.53063,635.0349 455.53811,635.49317 452.88535,635.87467 C 451.37826,636.08963 450.30818,636.33294 449.69047,636.60341 C 449.06567,636.87506 448.57905,637.27073 448.24598,637.79869 C 447.90583,638.31956 447.7322,638.89593 447.7322,639.53491 C 447.7322,640.51404 448.1078,641.32664 448.84362,641.97861 C 449.57945,642.62467 450.66252,642.95066 452.08693,642.95066 C 453.49599,642.95066 454.75268,642.64593 455.84992,642.02704 C 456.94716,641.40932 457.75976,640.56247 458.27354,639.49239 C 458.66921,638.66679 458.8641,637.44435 458.8641,635.83333 L 458.8641,634.48569 L 458.86409,634.48569 z "
+         style="fill:#000000;fill-rule:nonzero"
+         id="path33" />
+      <polygon
+         points="468.163,645.333 468.163,615.508 471.822,615.508 471.822,645.333 468.163,645.333 "
+         style="fill:#000000;fill-rule:nonzero"
+         id="polygon35" />
+      <polygon
+         points="477.516,626.069 476.585,620.493 476.585,615.508 480.752,615.508 480.752,620.493 479.78,626.069 477.516,626.069 "
+         style="fill:#000000;fill-rule:nonzero"
+         id="polygon37" />
+      <polygon
+         points="496.954,645.333 496.954,615.508 500.613,615.508 500.613,645.333 496.954,645.333 "
+         style="fill:#000000;fill-rule:nonzero"
+         id="polygon39" />
+      <path
+         d="M 504.925,634.527 C 504.925,630.52779 506.03642,627.56204 508.26516,625.6392 C 510.11949,624.04117 512.38366,623.23566 515.0565,623.23566 C 518.02933,623.23566 520.45886,624.20889 522.34154,626.16007 C 524.23012,628.10416 525.16792,630.79117 525.16792,634.22227 C 525.16792,637.00613 524.75099,639.19471 523.91713,640.78447 C 523.08445,642.38132 521.8691,643.61793 520.27933,644.49904 C 518.6813,645.38132 516.94508,645.81951 515.0565,645.81951 C 512.03642,645.81951 509.59154,644.85337 507.72304,642.90927 C 505.85572,640.97226 504.92501,638.18014 504.92501,634.52699 L 504.925,634.527 z M 508.68917,634.527 C 508.68917,637.29787 509.29271,639.36834 510.50098,640.74314 C 511.70925,642.12503 513.23051,642.81243 515.05649,642.81243 C 516.87657,642.81243 518.38956,642.11794 519.59783,640.73605 C 520.80019,639.35416 521.40374,637.24235 521.40374,634.41007 C 521.40374,631.73605 520.8002,629.7081 519.58484,628.3333 C 518.36949,626.9585 516.8624,626.2711 515.05649,626.2711 C 513.23051,626.2711 511.70925,626.9585 510.50098,628.32622 C 509.29271,629.69394 508.68917,631.76323 508.68917,634.52701 L 508.68917,634.527 z "
+         style="fill:#000000;fill-rule:nonzero"
+         id="path41" />
+      <path
+         d="M 528.793,647.125 L 532.3552,647.65295 C 532.50166,648.75019 532.9174,649.54862 533.59181,650.05531 C 534.50126,650.72854 535.74378,651.0687 537.31346,651.0687 C 539.01543,651.0687 540.32055,650.72855 541.24417,650.05531 C 542.16779,649.375 542.78551,648.42303 543.11149,647.20767 C 543.30637,646.45767 543.39023,644.89625 543.37606,642.50688 C 541.77921,644.38838 539.78551,645.33326 537.39732,645.33326 C 534.42449,645.33326 532.12606,644.26436 530.50086,642.1183 C 528.87684,639.97932 528.05716,637.40334 528.05716,634.41043 C 528.05716,632.34704 528.43157,630.44429 529.17448,628.70216 C 529.92448,626.95885 531.00873,625.61122 532.42487,624.66043 C 533.84101,623.71555 535.50755,623.23602 537.41739,623.23602 C 539.96621,623.23602 542.07093,624.27067 543.7233,626.33405 L 543.7233,623.72972 L 547.1048,623.72972 L 547.1048,642.40292 C 547.1048,645.76434 546.75755,648.15253 546.07724,649.55568 C 545.38983,650.95765 544.30677,652.06907 542.82094,652.88166 C 541.33393,653.69426 539.50795,654.1041 537.33472,654.1041 C 534.75755,654.1041 532.67527,653.52064 531.09141,652.36079 C 529.50165,651.20095 528.73747,649.45764 528.79298,647.12496 L 528.793,647.125 z M 531.82017,634.1459 C 531.82017,636.97936 532.38356,639.04866 533.51505,640.34787 C 534.64064,641.65299 536.0497,642.29905 537.74458,642.29905 C 539.42411,642.29905 540.83434,641.65299 541.97293,640.36086 C 543.11151,639.06283 543.68199,637.03488 543.68199,634.26401 C 543.68199,631.61834 543.09852,629.62582 541.92451,628.28527 C 540.75049,626.94472 539.33435,626.27149 537.68199,626.27149 C 536.05679,626.27149 534.6749,626.93054 533.52923,628.25692 C 532.39065,629.57621 531.82017,631.54157 531.82017,634.1459 L 531.82017,634.1459 z "
+         style="fill:#000000;fill-rule:nonzero"
+         id="path43" />
+      <path
+         d="M 551.271,634.527 C 551.271,630.52779 552.38242,627.56204 554.61116,625.6392 C 556.46549,624.04117 558.72966,623.23566 561.4025,623.23566 C 564.37533,623.23566 566.80486,624.20889 568.68754,626.16007 C 570.57612,628.10416 571.51392,630.79117 571.51392,634.22227 C 571.51392,637.00613 571.09699,639.19471 570.26313,640.78447 C 569.43045,642.38132 568.2151,643.61793 566.62533,644.49904 C 565.0273,645.38132 563.29108,645.81951 561.4025,645.81951 C 558.38242,645.81951 555.93754,644.85337 554.06904,642.90927 C 552.20172,640.97226 551.27101,638.18014 551.27101,634.52699 L 551.271,634.527 z M 555.03517,634.527 C 555.03517,637.29787 555.63871,639.36834 556.84698,640.74314 C 558.05525,642.12503 559.57651,642.81243 561.40249,642.81243 C 563.22257,642.81243 564.73556,642.11794 565.94383,640.73605 C 567.14619,639.35416 567.74974,637.24235 567.74974,634.41007 C 567.74974,631.73605 567.1462,629.7081 565.93084,628.3333 C 564.71549,626.9585 563.2084,626.2711 561.40249,626.2711 C 559.57651,626.2711 558.05525,626.9585 556.84698,628.32622 C 555.63871,629.69394 555.03517,631.76323 555.03517,634.52701 L 555.03517,634.527 z "
+         style="fill:#000000;fill-rule:nonzero"
+         id="path45" />
+      <path
+         d="M 588.256,645.333 L 588.256,626.5759 L 585.02687,626.5759 L 585.02687,623.72944 L 588.256,623.72944 L 588.256,621.43101 C 588.256,619.97944 588.38828,618.89636 588.64458,618.19479 C 588.99891,617.24282 589.61781,616.47274 590.506,615.88219 C 591.39537,615.29164 592.63789,614.99991 594.24183,614.99991 C 595.27057,614.99991 596.40915,615.11802 597.65876,615.36841 L 597.11073,618.56329 C 596.35364,618.42392 595.63081,618.35424 594.95049,618.35424 C 593.83907,618.35424 593.05482,618.59046 592.59655,619.06998 C 592.1312,619.54242 591.90206,620.43061 591.90206,621.73573 L 591.90206,623.72943 L 596.11033,623.72943 L 596.11033,626.57589 L 591.90206,626.57589 L 591.90206,645.33299 L 588.256,645.33299 L 588.256,645.333 z "
+         style="fill:#000000;fill-rule:nonzero"
+         id="path47" />
+      <path
+         d="M 598.923,645.333 L 598.923,623.7295 L 602.21473,623.7295 L 602.21473,626.99997 C 603.05449,625.4728 603.83284,624.45824 604.54741,623.9728 C 605.25607,623.48619 606.04032,623.23579 606.89544,623.23579 C 608.13087,623.23579 609.38166,623.63264 610.65843,624.41689 L 609.39465,627.81965 C 608.50646,627.28461 607.61,627.02123 606.71473,627.02123 C 605.90922,627.02123 605.19347,627.26453 604.55449,627.74288 C 603.91551,628.2295 603.46433,628.89564 603.19386,629.74957 C 602.78402,631.04878 602.58323,632.47201 602.58323,634.02044 L 602.58323,645.33304 L 598.92299,645.33304 L 598.923,645.333 z "
+         style="fill:#000000;fill-rule:nonzero"
+         id="path49" />
+      <path
+         d="M 611.471,634.527 C 611.471,630.52779 612.58242,627.56204 614.81116,625.6392 C 616.66549,624.04117 618.92966,623.23566 621.6025,623.23566 C 624.57533,623.23566 627.00486,624.20889 628.88754,626.16007 C 630.77612,628.10416 631.71392,630.79117 631.71392,634.22227 C 631.71392,637.00613 631.29699,639.19471 630.46313,640.78447 C 629.63045,642.38132 628.4151,643.61793 626.82533,644.49904 C 625.2273,645.38132 623.49108,645.81951 621.6025,645.81951 C 618.58242,645.81951 616.13754,644.85337 614.26904,642.90927 C 612.40172,640.97226 611.47101,638.18014 611.47101,634.52699 L 611.471,634.527 z M 615.23517,634.527 C 615.23517,637.29787 615.83871,639.36834 617.04698,640.74314 C 618.25525,642.12503 619.77651,642.81243 621.60249,642.81243 C 623.42257,642.81243 624.93556,642.11794 626.14383,640.73605 C 627.34619,639.35416 627.94974,637.24235 627.94974,634.41007 C 627.94974,631.73605 627.3462,629.7081 626.13084,628.3333 C 624.91549,626.9585 623.4084,626.2711 621.60249,626.2711 C 619.77651,626.2711 618.25525,626.9585 617.04698,628.32622 C 615.83871,629.69394 615.23517,631.76323 615.23517,634.52701 L 615.23517,634.527 z "
+         style="fill:#000000;fill-rule:nonzero"
+         id="path51" />
+      <path
+         d="M 636.012,645.333 L 636.012,623.7295 L 639.28365,623.7295 L 639.28365,626.75667 C 639.96396,625.70195 640.86633,624.84683 641.99192,624.20903 C 643.11633,623.56297 644.40137,623.2358 645.83877,623.2358 C 647.43562,623.2358 648.74783,623.57005 649.76948,624.23619 C 650.79704,624.90351 651.51869,625.82595 651.93562,627.02123 C 653.65058,624.50076 655.87342,623.2358 658.60885,623.2358 C 660.75491,623.2358 662.40019,623.83344 663.55294,625.02045 C 664.7057,626.20864 665.28207,628.03462 665.28207,630.49958 L 665.28207,645.33308 L 661.64427,645.33308 L 661.64427,631.72208 C 661.64427,630.25751 661.52616,629.20161 661.28994,628.55554 C 661.04663,627.91657 660.61553,627.3957 659.99781,627.00003 C 659.37301,626.61145 658.63718,626.40948 657.79624,626.40948 C 656.27616,626.40948 655.01829,626.91735 654.01199,627.93074 C 653.0116,628.93822 652.5049,630.55515 652.5049,632.77798 L 652.5049,645.33308 L 648.84584,645.33308 L 648.84584,631.29918 C 648.84584,629.6669 648.54702,628.44446 647.94938,627.63186 C 647.35293,626.81926 646.37969,626.40942 645.01907,626.40942 C 643.99151,626.40942 643.03954,626.68107 642.16553,627.22911 C 641.29034,627.77123 640.65136,628.56257 640.26277,629.60431 C 639.86592,630.65313 639.67222,632.16022 639.67222,634.12439 L 639.67222,645.33309 L 636.01198,645.33309 L 636.012,645.333 z "
+         style="fill:#000000;fill-rule:nonzero"
+         id="path53" />
+      <path
+         d="M 685.671,645.333 L 682.27533,645.333 L 682.27533,615.5078 L 685.93439,615.5078 L 685.93439,626.146 C 687.48282,624.20899 689.45526,623.23576 691.85053,623.23576 C 693.18399,623.23576 694.44187,623.50741 695.62888,624.04127 C 696.81589,624.57631 697.78794,625.3334 698.55919,626.29836 C 699.32336,627.27041 699.92691,628.43734 700.35801,629.81214 C 700.79502,631.18104 701.01116,632.6456 701.01116,634.20112 C 701.01116,637.90978 700.09344,640.77041 698.26037,642.79128 C 696.43439,644.81215 694.23281,645.81963 691.671,645.81963 C 689.12218,645.81963 687.12257,644.75664 685.671,642.62475 L 685.671,645.33302 L 685.671,645.333 z M 685.62848,634.3676 C 685.62848,636.95776 685.98281,638.82626 686.68439,639.97902 C 687.83715,641.8676 689.39974,642.81248 691.3651,642.81248 C 692.96904,642.81248 694.35093,642.11799 695.51786,640.72193 C 696.68479,639.33295 697.26707,637.26366 697.26707,634.50697 C 697.26707,631.68768 696.70487,629.60421 695.58754,628.26366 C 694.46904,626.92311 693.11549,626.24988 691.53163,626.24988 C 689.92769,626.24988 688.5458,626.94437 687.37887,628.33334 C 686.21194,629.72232 685.62848,631.7361 685.62848,634.36759 L 685.62848,634.3676 z "
+         style="fill:#000000;fill-rule:nonzero"
+         id="path55" />
+      <path
+         d="M 720.254,638.375 L 724.03825,638.84035 C 723.44061,641.05492 722.33746,642.76988 720.72644,643.99232 C 719.10833,645.20767 717.04494,645.81949 714.53864,645.81949 C 711.37919,645.81949 708.87171,644.84627 707.02447,642.90217 C 705.17014,640.95808 704.24652,638.22855 704.24652,634.71477 C 704.24652,631.07579 705.18431,628.2565 707.05282,626.24981 C 708.92723,624.24312 711.35085,623.23564 714.33668,623.23564 C 717.22566,623.23564 719.58668,624.22186 721.41385,626.18721 C 723.24692,628.15256 724.16346,630.92343 724.16346,634.48564 C 724.16346,634.70769 724.15637,635.03486 724.1422,635.46478 L 708.032,635.46478 C 708.16428,637.83998 708.83751,639.65887 710.04578,640.91675 C 711.25405,642.18053 712.75405,642.81242 714.55995,642.81242 C 715.89932,642.81242 717.04499,642.45809 717.99696,641.74943 C 718.94775,641.04785 719.69775,639.92345 720.25405,638.37502 L 720.254,638.375 z M 708.2327,632.45177 L 720.2953,632.45177 C 720.13585,630.63878 719.6705,629.27106 718.91341,628.36752 C 717.74648,626.95846 716.23349,626.2498 714.37916,626.2498 C 712.69845,626.2498 711.28113,626.81201 710.13546,627.9376 C 708.98979,629.06201 708.3579,630.5691 708.2327,632.45177 L 708.2327,632.45177 z "
+         style="fill:#000000;fill-rule:nonzero"
+         id="path57" />
+      <path
+         d="M 736.636,642.056 L 737.16277,645.29222 C 736.13521,645.50718 735.21159,645.6182 734.39899,645.6182 C 733.06671,645.6182 732.03797,645.41033 731.30214,644.98631 C 730.5734,644.56939 730.05962,644.01427 729.7608,643.32686 C 729.46198,642.64655 729.30962,641.20206 729.30962,639.00757 L 729.30962,626.57647 L 726.62143,626.57647 L 726.62143,623.73001 L 729.30962,623.73001 L 729.30962,618.37607 L 732.9545,616.18158 L 732.9545,623.73001 L 736.636,623.73001 L 736.636,626.57647 L 732.9545,626.57647 L 732.9545,639.20837 C 732.9545,640.25719 733.0171,640.92451 733.1423,641.22215 C 733.27458,641.52097 733.48245,641.75719 733.77419,641.9379 C 734.06592,642.11152 734.48285,642.20129 735.02498,642.20129 C 735.43364,642.20129 735.96868,642.15286 736.636,642.05601 L 736.636,642.056 z "
+         style="fill:#000000;fill-rule:nonzero"
+         id="path59" />
+      <path
+         d="M 754.316,642.666 C 752.95419,643.81876 751.64907,644.63135 750.39946,645.11088 C 749.14159,645.58332 747.79513,645.81954 746.35773,645.81954 C 743.98253,645.81954 742.16364,645.24316 740.88568,644.08332 C 739.61481,642.92348 738.97584,641.43765 738.97584,639.63883 C 738.97584,638.57584 739.21206,637.61088 739.69749,636.73568 C 740.17702,635.86048 740.80891,635.16009 741.58725,634.63214 C 742.37151,634.10419 743.2467,633.70143 744.22583,633.43096 C 744.9404,633.24317 746.02465,633.05537 747.47504,632.88175 C 750.4337,632.52742 752.61402,632.11049 754.01008,631.61797 C 754.02426,631.11836 754.03134,630.79828 754.03134,630.666 C 754.03134,629.17309 753.6841,628.11836 752.98961,627.51364 C 752.0589,626.68096 750.66284,626.27112 748.82268,626.27112 C 747.10063,626.27112 745.82977,626.56994 745.00299,627.17348 C 744.18331,627.77821 743.57976,628.8471 743.18409,630.38135 L 739.60771,629.88883 C 739.9337,628.36166 740.46874,627.11796 741.21165,626.18017 C 741.95457,625.23647 743.03763,624.50655 744.44787,623.99986 C 745.85693,623.49317 747.48921,623.23569 749.35063,623.23569 C 751.19787,623.23569 752.69079,623.45892 753.84354,623.88884 C 754.9963,624.32703 755.84315,624.86797 756.39236,625.52821 C 756.93331,626.18726 757.3089,627.01404 757.53094,628.02034 C 757.64905,628.64632 757.71165,629.77073 757.71165,631.39593 L 757.71165,636.27743 C 757.71165,639.68727 757.78724,641.84042 757.94787,642.7357 C 758.10023,643.63806 758.41323,644.50617 758.87149,645.33294 L 755.04472,645.33294 C 754.67032,644.57585 754.41992,643.68766 754.31598,642.66601 L 754.316,642.666 z M 754.01009,634.48569 C 752.67663,635.0349 750.68411,635.49317 748.03135,635.87467 C 746.52426,636.08963 745.45418,636.33294 744.83647,636.60341 C 744.21167,636.87506 743.72505,637.27073 743.39198,637.79869 C 743.05183,638.31956 742.8782,638.89593 742.8782,639.53491 C 742.8782,640.51404 743.25379,641.32664 743.98962,641.97861 C 744.72545,642.62467 745.80852,642.95066 747.23293,642.95066 C 748.64199,642.95066 749.89868,642.64593 750.99592,642.02704 C 752.09316,641.40932 752.90576,640.56247 753.41954,639.49239 C 753.81521,638.66679 754.01009,637.44435 754.01009,635.83333 L 754.01009,634.48569 L 754.01009,634.48569 z "
+         style="fill:#000000;fill-rule:nonzero"
+         id="path61" />
+      <polygon
+         points="764.426,645.333 764.426,641.159 768.6,641.159 768.6,645.333 764.426,645.333 "
+         style="fill:#000000;fill-rule:nonzero"
+         id="polygon63" />
+      <path
+         d="M 774.967,653.61 L 774.967,623.7293 L 778.30007,623.7293 L 778.30007,626.53442 C 779.0855,625.43718 779.97369,624.61159 780.967,624.06237 C 781.95322,623.51434 783.1544,623.2356 784.56464,623.2356 C 786.41188,623.2356 788.03708,623.71513 789.44614,624.66001 C 790.86228,625.61079 791.92527,626.95135 792.64102,628.68048 C 793.36267,630.40961 793.72409,632.30528 793.72409,634.36749 C 793.72409,636.57615 793.32842,638.56867 792.53,640.34032 C 791.73748,642.11079 790.58472,643.46434 789.07173,644.40922 C 787.55756,645.34701 785.96661,645.81946 784.30008,645.81946 C 783.07882,645.81946 781.98748,645.56198 781.01543,645.0482 C 780.04338,644.53442 779.25204,643.88127 778.62724,643.09702 L 778.62724,653.61002 L 774.967,653.61002 L 774.967,653.61 z M 778.27999,634.6521 C 778.27999,637.43005 778.84219,639.48517 779.96779,640.81864 C 781.0922,642.14502 782.45992,642.81234 784.05795,642.81234 C 785.68197,642.81234 787.07803,642.12494 788.23787,640.74305 C 789.39771,639.36825 789.98118,637.23636 789.98118,634.34738 C 789.98118,631.58951 789.41189,629.53439 788.27921,628.15958 C 787.14771,626.79186 785.79299,626.10446 784.22449,626.10446 C 782.66189,626.10446 781.28,626.8332 780.07882,628.29186 C 778.87646,629.74934 778.28,631.87532 778.28,634.6521 L 778.27999,634.6521 z "
+         style="fill:#000000;fill-rule:nonzero"
+         id="path65" />
+      <path
+         d="M 797.974,653.653 L 797.56416,650.21481 C 798.36967,650.43095 799.06416,650.54198 799.6618,650.54198 C 800.47439,650.54198 801.12637,650.40261 801.61298,650.13213 C 802.1055,649.86048 802.50235,649.48607 802.81416,648.99237 C 803.05038,648.63214 803.41888,647.72268 803.93266,646.27111 C 804.00234,646.06206 804.11337,645.77033 804.25864,645.37465 L 796.06415,623.72975 L 800.00903,623.72975 L 804.50903,636.23645 C 805.08541,637.82621 805.61336,639.49275 806.07163,641.24315 C 806.49447,639.56244 806.99525,637.92425 807.57872,636.31912 L 812.19565,623.72973 L 815.85589,623.72973 L 807.64014,645.70173 C 806.75904,648.07574 806.07164,649.70803 805.58502,650.60448 C 804.93187,651.81275 804.18896,652.69385 803.34919,653.25724 C 802.50234,653.81945 801.50195,654.10409 800.33502,654.10409 C 799.62636,654.10409 798.84211,653.95055 797.974,653.65291 L 797.974,653.653 z "
+         style="fill:#000000;fill-rule:nonzero"
+         id="path67" />
+      <path
+         d="M 826.967,642.056 L 827.49377,645.29222 C 826.46621,645.50718 825.54259,645.6182 824.72999,645.6182 C 823.39771,645.6182 822.36897,645.41033 821.63314,644.98631 C 820.9044,644.56939 820.39062,644.01427 820.0918,643.32686 C 819.79298,642.64655 819.64062,641.20206 819.64062,639.00757 L 819.64062,626.57647 L 816.95243,626.57647 L 816.95243,623.73001 L 819.64062,623.73001 L 819.64062,618.37607 L 823.2855,616.18158 L 823.2855,623.73001 L 826.967,623.73001 L 826.967,626.57647 L 823.2855,626.57647 L 823.2855,639.20837 C 823.2855,640.25719 823.3481,640.92451 823.4733,641.22215 C 823.60558,641.52097 823.81345,641.75719 824.10519,641.9379 C 824.39692,642.11152 824.81385,642.20129 825.35598,642.20129 C 825.76464,642.20129 826.29968,642.15286 826.967,642.05601 L 826.967,642.056 z "
+         style="fill:#000000;fill-rule:nonzero"
+         id="path69" />
+      <path
+         d="M 830.549,645.333 L 830.549,615.5078 L 834.20924,615.5078 L 834.20924,626.2086 C 835.91711,624.22907 838.07735,623.23577 840.6805,623.23577 C 842.27853,623.23577 843.66751,623.55585 844.84743,624.18774 C 846.02853,624.81254 846.87538,625.68774 847.38208,626.79916 C 847.88877,627.9094 848.14625,629.52751 848.14625,631.63932 L 848.14625,645.33302 L 844.48011,645.33302 L 844.48011,631.63932 C 844.48011,629.81215 844.08326,628.47869 843.29192,627.64601 C 842.50058,626.81215 841.37499,626.38932 839.9246,626.38932 C 838.84035,626.38932 837.81988,626.67396 836.862,627.23617 C 835.90295,627.79837 835.22263,628.56255 834.81987,629.52751 C 834.41003,630.48656 834.20924,631.81885 834.20924,633.51373 L 834.20924,645.33303 L 830.549,645.33303 L 830.549,645.333 z "
+         style="fill:#000000;fill-rule:nonzero"
+         id="path71" />
+      <path
+         d="M 852.354,634.527 C 852.354,630.52779 853.46542,627.56204 855.69416,625.6392 C 857.54849,624.04117 859.81266,623.23566 862.4855,623.23566 C 865.45833,623.23566 867.88786,624.20889 869.77054,626.16007 C 871.65912,628.10416 872.59692,630.79117 872.59692,634.22227 C 872.59692,637.00613 872.17999,639.19471 871.34613,640.78447 C 870.51345,642.38132 869.2981,643.61793 867.70833,644.49904 C 866.1103,645.38132 864.37408,645.81951 862.4855,645.81951 C 859.46542,645.81951 857.02054,644.85337 855.15204,642.90927 C 853.28472,640.97226 852.35401,638.18014 852.35401,634.52699 L 852.354,634.527 z M 856.11817,634.527 C 856.11817,637.29787 856.72171,639.36834 857.92998,640.74314 C 859.13825,642.12503 860.65951,642.81243 862.48549,642.81243 C 864.30557,642.81243 865.81856,642.11794 867.02683,640.73605 C 868.22919,639.35416 868.83274,637.24235 868.83274,634.41007 C 868.83274,631.73605 868.2292,629.7081 867.01384,628.3333 C 865.79849,626.9585 864.2914,626.2711 862.48549,626.2711 C 860.65951,626.2711 859.13825,626.9585 857.92998,628.32622 C 856.72171,629.69394 856.11817,631.76323 856.11817,634.52701 L 856.11817,634.527 z "
+         style="fill:#000000;fill-rule:nonzero"
+         id="path73" />
+      <path
+         d="M 876.895,645.333 L 876.895,623.7295 L 880.18673,623.7295 L 880.18673,626.79919 C 881.77767,624.42399 884.06901,623.2358 887.06193,623.2358 C 888.36705,623.2358 889.56114,623.47202 890.65248,623.93737 C 891.74972,624.40982 892.56114,625.02045 893.10327,625.78462 C 893.65248,626.5417 894.02689,627.44407 894.24894,628.4858 C 894.38122,629.16729 894.45091,630.3543 894.45091,632.04919 L 894.45091,645.33309 L 890.78359,645.33309 L 890.78359,632.18739 C 890.78359,630.70156 890.6454,629.58306 890.36075,628.84015 C 890.07611,628.10432 889.56823,627.51377 888.84658,627.07676 C 888.11784,626.63266 887.26981,626.40943 886.29067,626.40943 C 884.72807,626.40943 883.3887,626.91022 882.24894,627.89644 C 881.11744,628.88857 880.55524,630.76416 880.55524,633.53502 L 880.55524,645.33302 L 876.895,645.33302 L 876.895,645.333 z "
+         style="fill:#000000;fill-rule:nonzero"
+         id="path75" />
+    </g>
+    <g
+       transform="matrix(0.317715,0,0,0.317715,-71.39343,-151.2348)"
+       style="fill-rule:evenodd"
+       id="_19428312">
+   <path
+   d="M 341.207,1443.54 L 332.98535,1421.9365 L 336.85346,1421.9365 L 341.49165,1434.8731 C 341.99244,1436.2692 342.4507,1437.7207 342.87354,1439.2278 C 343.2007,1438.0892 343.65189,1436.7203 344.23535,1435.1164 L 349.04007,1421.9365 L 352.80424,1421.9365 L 344.62393,1443.54 L 341.207,1443.54 L 341.207,1443.54 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="_19439224" />
+
+   <path
+   d="M 370.825,1436.58 L 374.60925,1437.0454 C 374.01161,1439.2599 372.90846,1440.9749 371.29744,1442.1973 C 369.67933,1443.4127 367.61594,1444.0245 365.10964,1444.0245 C 361.95019,1444.0245 359.44271,1443.0513 357.59547,1441.1072 C 355.74114,1439.1631 354.81752,1436.4336 354.81752,1432.9198 C 354.81752,1429.2808 355.75532,1426.4615 357.62382,1424.4548 C 359.49823,1422.4481 361.92185,1421.4406 364.90768,1421.4406 C 367.79666,1421.4406 370.15768,1422.4269 371.98485,1424.3922 C 373.81792,1426.3576 374.73446,1429.1284 374.73446,1432.6906 C 374.73446,1432.9127 374.72737,1433.2399 374.7132,1433.6698 L 358.603,1433.6698 C 358.73528,1436.045 359.40851,1437.8639 360.61678,1439.1217 C 361.82505,1440.3855 363.32505,1441.0174 365.13095,1441.0174 C 366.47032,1441.0174 367.61599,1440.6631 368.56796,1439.9544 C 369.51875,1439.2529 370.26875,1438.1284 370.82505,1436.58 L 370.825,1436.58 z M 358.8037,1430.6568 L 370.8663,1430.6568 C 370.70685,1428.8438 370.2415,1427.4761 369.48441,1426.5725 C 368.31748,1425.1635 366.80449,1424.4548 364.95016,1424.4548 C 363.26945,1424.4548 361.85213,1425.017 360.70646,1426.1426 C 359.56079,1427.267 358.9289,1428.7741 358.8037,1430.6568 L 358.8037,1430.6568 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path79" />
+
+   <path
+   d="M 379.172,1443.54 L 379.172,1421.9365 L 382.46373,1421.9365 L 382.46373,1425.207 C 383.30349,1423.6798 384.08184,1422.6652 384.79641,1422.1798 C 385.50507,1421.6932 386.28932,1421.4428 387.14444,1421.4428 C 388.37987,1421.4428 389.63066,1421.8396 390.90743,1422.6239 L 389.64365,1426.0267 C 388.75546,1425.4916 387.859,1425.2282 386.96373,1425.2282 C 386.15822,1425.2282 385.44247,1425.4715 384.80349,1425.9499 C 384.16451,1426.4365 383.71333,1427.1026 383.44286,1427.9566 C 383.03302,1429.2558 382.83223,1430.679 382.83223,1432.2274 L 382.83223,1443.54 L 379.17199,1443.54 L 379.172,1443.54 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path81" />
+
+   <path
+   d="M 391.623,1437.09 L 395.24072,1436.5207 C 395.44151,1437.9723 396.01198,1439.0825 396.94151,1439.8609 C 397.86513,1440.6309 399.16434,1441.0207 400.83797,1441.0207 C 402.51868,1441.0207 403.76828,1440.6735 404.58088,1439.9931 C 405.39348,1439.3057 405.80332,1438.4991 405.80332,1437.5825 C 405.80332,1436.7498 405.4419,1436.1038 404.71907,1435.6242 C 404.21946,1435.2983 402.96986,1434.8884 400.97616,1434.3888 C 398.29624,1433.7085 396.42773,1433.125 395.39309,1432.6242 C 394.35844,1432.1317 393.56711,1431.4443 393.03207,1430.5691 C 392.49821,1429.6939 392.22656,1428.729 392.22656,1427.6731 C 392.22656,1426.7081 392.4486,1425.8199 392.89388,1425.0002 C 393.33089,1424.1735 393.93561,1423.4931 394.69152,1422.951 C 395.26199,1422.5353 396.03916,1422.1739 397.01829,1421.8821 C 398.00451,1421.5904 399.06042,1421.4439 400.18483,1421.4439 C 401.87971,1421.4439 403.36554,1421.6943 404.65058,1422.1809 C 405.93444,1422.6664 406.87932,1423.3266 407.48995,1424.1593 C 408.10176,1425.0002 408.51869,1426.1105 408.74782,1427.5065 L 405.17144,1428.0002 C 405.00491,1426.8888 404.53247,1426.0207 403.75412,1425.3959 C 402.97696,1424.7711 401.87262,1424.4581 400.4494,1424.4581 C 398.76869,1424.4581 397.56751,1424.7357 396.85176,1425.292 C 396.13011,1425.8471 395.76869,1426.5002 395.76869,1427.2432 C 395.76869,1427.7215 395.92105,1428.1455 396.21987,1428.5282 C 396.51869,1428.9239 396.98405,1429.2428 397.62302,1429.5073 C 397.99034,1429.6384 399.06751,1429.9514 400.85806,1430.4369 C 403.44822,1431.1313 405.25412,1431.6947 406.2746,1432.1388 C 407.30334,1432.5758 408.10885,1433.2219 408.69232,1434.0617 C 409.27461,1434.9026 409.56634,1435.9443 409.56634,1437.1939 C 409.56634,1438.4164 409.2061,1439.562 408.49744,1440.6451 C 407.78169,1441.7223 406.75413,1442.555 405.41358,1443.1455 C 404.07421,1443.7361 402.55295,1444.0278 400.85807,1444.0278 C 398.04587,1444.0278 395.90689,1443.4443 394.43524,1442.2774 C 392.96241,1441.1105 392.02579,1439.3813 391.62304,1437.09 L 391.623,1437.09 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path83" />
+
+   <path
+   d="M 413.934,1417.93 L 413.934,1413.7158 L 417.60014,1413.7158 L 417.60014,1417.93 L 413.934,1417.93 z M 413.934,1443.541 L 413.934,1421.9375 L 417.60014,1421.9375 L 417.60014,1443.541 L 413.934,1443.541 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path85" />
+
+   <path
+   d="M 421.808,1432.74 C 421.808,1428.7408 422.91942,1425.775 425.14816,1423.8522 C 427.00249,1422.2542 429.26666,1421.4487 431.9395,1421.4487 C 434.91233,1421.4487 437.34186,1422.4219 439.22454,1424.3731 C 441.11312,1426.3172 442.05092,1429.0042 442.05092,1432.4353 C 442.05092,1435.2191 441.63399,1437.4077 440.80013,1438.9975 C 439.96745,1440.5943 438.7521,1441.8309 437.16233,1442.712 C 435.5643,1443.5943 433.82808,1444.0325 431.9395,1444.0325 C 428.91942,1444.0325 426.47454,1443.0664 424.60604,1441.1223 C 422.73872,1439.1853 421.80801,1436.3931 421.80801,1432.74 L 421.808,1432.74 z M 425.57217,1432.74 C 425.57217,1435.5109 426.17571,1437.5813 427.38398,1438.9561 C 428.59225,1440.338 430.11351,1441.0254 431.93949,1441.0254 C 433.75957,1441.0254 435.27256,1440.3309 436.48083,1438.949 C 437.68319,1437.5672 438.28674,1435.4554 438.28674,1432.6231 C 438.28674,1429.949 437.6832,1427.9211 436.46784,1426.5463 C 435.25249,1425.1715 433.7454,1424.4841 431.93949,1424.4841 C 430.11351,1424.4841 428.59225,1425.1715 427.38398,1426.5392 C 426.17571,1427.9069 425.57217,1429.9762 425.57217,1432.74 L 425.57217,1432.74 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path87" />
+
+   <path
+   d="M 446.349,1443.54 L 446.349,1421.9365 L 449.64073,1421.9365 L 449.64073,1425.0062 C 451.23167,1422.631 453.52301,1421.4428 456.51593,1421.4428 C 457.82105,1421.4428 459.01514,1421.679 460.10648,1422.1444 C 461.20372,1422.6168 462.01514,1423.2274 462.55727,1423.9916 C 463.10648,1424.7487 463.48089,1425.6511 463.70294,1426.6928 C 463.83522,1427.3743 463.90491,1428.5613 463.90491,1430.2562 L 463.90491,1443.5401 L 460.23759,1443.5401 L 460.23759,1430.3944 C 460.23759,1428.9086 460.0994,1427.7901 459.81475,1427.0471 C 459.53011,1426.3113 459.02223,1425.7208 458.30058,1425.2838 C 457.57184,1424.8397 456.72381,1424.6164 455.74467,1424.6164 C 454.18207,1424.6164 452.8427,1425.1172 451.70294,1426.1034 C 450.57144,1427.0956 450.00924,1428.9712 450.00924,1431.742 L 450.00924,1443.54 L 446.349,1443.54 L 446.349,1443.54 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path89" />
+
+   <path
+   d="M 481.113,1417.93 L 481.113,1413.7158 L 484.77914,1413.7158 L 484.77914,1417.93 L 481.113,1417.93 z M 481.113,1443.541 L 481.113,1421.9375 L 484.77914,1421.9375 L 484.77914,1443.541 L 481.113,1443.541 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path91" />
+
+   <path
+   d="M 490.355,1443.54 L 490.355,1421.9365 L 493.64673,1421.9365 L 493.64673,1425.0062 C 495.23767,1422.631 497.52901,1421.4428 500.52193,1421.4428 C 501.82705,1421.4428 503.02114,1421.679 504.11248,1422.1444 C 505.20972,1422.6168 506.02114,1423.2274 506.56327,1423.9916 C 507.11248,1424.7487 507.48689,1425.6511 507.70894,1426.6928 C 507.84122,1427.3743 507.91091,1428.5613 507.91091,1430.2562 L 507.91091,1443.5401 L 504.24359,1443.5401 L 504.24359,1430.3944 C 504.24359,1428.9086 504.1054,1427.7901 503.82075,1427.0471 C 503.53611,1426.3113 503.02823,1425.7208 502.30658,1425.2838 C 501.57784,1424.8397 500.72981,1424.6164 499.75067,1424.6164 C 498.18807,1424.6164 496.8487,1425.1172 495.70894,1426.1034 C 494.57744,1427.0956 494.01524,1428.9712 494.01524,1431.742 L 494.01524,1443.54 L 490.355,1443.54 L 490.355,1443.54 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path93" />
+
+   <path
+   d="M 539.264,1443.54 L 539.264,1440.3664 C 537.5762,1442.8113 535.29195,1444.0266 532.40298,1444.0266 C 531.13211,1444.0266 529.93684,1443.7833 528.83369,1443.2967 C 527.72936,1442.8113 526.90967,1442.1924 526.37463,1441.4565 C 525.83368,1440.7136 525.45809,1439.8113 525.24313,1438.7412 C 525.09667,1438.0195 525.02108,1436.8809 525.02108,1435.3184 L 525.02108,1421.9365 L 528.68014,1421.9365 L 528.68014,1433.9152 C 528.68014,1435.8321 528.75691,1437.1159 528.90219,1437.7833 C 529.13841,1438.7482 529.62502,1439.4982 530.36794,1440.0533 C 531.11794,1440.6026 532.04156,1440.873 533.13881,1440.873 C 534.23605,1440.873 535.26361,1440.5955 536.22857,1440.0333 C 537.19353,1439.4711 537.87503,1438.6998 538.2707,1437.7348 C 538.67346,1436.7628 538.87424,1435.3526 538.87424,1433.5124 L 538.87424,1421.9364 L 542.53448,1421.9364 L 542.53448,1443.5399 L 539.26401,1443.5399 L 539.264,1443.54 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path95" />
+
+   <path
+   d="M 546.813,1437.09 L 550.43072,1436.5207 C 550.63151,1437.9723 551.20198,1439.0825 552.13151,1439.8609 C 553.05513,1440.6309 554.35434,1441.0207 556.02797,1441.0207 C 557.70868,1441.0207 558.95828,1440.6735 559.77088,1439.9931 C 560.58348,1439.3057 560.99332,1438.4991 560.99332,1437.5825 C 560.99332,1436.7498 560.6319,1436.1038 559.90907,1435.6242 C 559.40946,1435.2983 558.15986,1434.8884 556.16616,1434.3888 C 553.48624,1433.7085 551.61773,1433.125 550.58309,1432.6242 C 549.54844,1432.1317 548.75711,1431.4443 548.22207,1430.5691 C 547.68821,1429.6939 547.41656,1428.729 547.41656,1427.6731 C 547.41656,1426.7081 547.6386,1425.8199 548.08388,1425.0002 C 548.52089,1424.1735 549.12561,1423.4931 549.88152,1422.951 C 550.45199,1422.5353 551.22916,1422.1739 552.20829,1421.8821 C 553.19451,1421.5904 554.25042,1421.4439 555.37483,1421.4439 C 557.06971,1421.4439 558.55554,1421.6943 559.84058,1422.1809 C 561.12444,1422.6664 562.06932,1423.3266 562.67995,1424.1593 C 563.29176,1425.0002 563.70869,1426.1105 563.93782,1427.5065 L 560.36144,1428.0002 C 560.19491,1426.8888 559.72247,1426.0207 558.94412,1425.3959 C 558.16696,1424.7711 557.06262,1424.4581 555.6394,1424.4581 C 553.95869,1424.4581 552.75751,1424.7357 552.04176,1425.292 C 551.32011,1425.8471 550.95869,1426.5002 550.95869,1427.2432 C 550.95869,1427.7215 551.11105,1428.1455 551.40987,1428.5282 C 551.70869,1428.9239 552.17405,1429.2428 552.81302,1429.5073 C 553.18035,1429.6384 554.25751,1429.9514 556.04806,1430.4369 C 558.63822,1431.1313 560.44412,1431.6947 561.4646,1432.1388 C 562.49334,1432.5758 563.29885,1433.2219 563.88232,1434.0617 C 564.46461,1434.9026 564.75634,1435.9443 564.75634,1437.1939 C 564.75634,1438.4164 564.3961,1439.562 563.68744,1440.6451 C 562.97169,1441.7223 561.94413,1442.555 560.60358,1443.1455 C 559.26421,1443.7361 557.74295,1444.0278 556.04807,1444.0278 C 553.23587,1444.0278 551.09689,1443.4443 549.62524,1442.2774 C 548.15241,1441.1105 547.21579,1439.3813 546.81304,1437.09 L 546.813,1437.09 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path97" />
+
+   <path
+   d="M 583.894,1436.58 L 587.67825,1437.0454 C 587.08061,1439.2599 585.97746,1440.9749 584.36644,1442.1973 C 582.74833,1443.4127 580.68494,1444.0245 578.17864,1444.0245 C 575.01919,1444.0245 572.51171,1443.0513 570.66447,1441.1072 C 568.81014,1439.1631 567.88652,1436.4336 567.88652,1432.9198 C 567.88652,1429.2808 568.82431,1426.4615 570.69282,1424.4548 C 572.56723,1422.4481 574.99085,1421.4406 577.97668,1421.4406 C 580.86566,1421.4406 583.22668,1422.4269 585.05385,1424.3922 C 586.88692,1426.3576 587.80346,1429.1284 587.80346,1432.6906 C 587.80346,1432.9127 587.79637,1433.2399 587.7822,1433.6698 L 571.672,1433.6698 C 571.80428,1436.045 572.47751,1437.8639 573.68578,1439.1217 C 574.89405,1440.3855 576.39405,1441.0174 578.19995,1441.0174 C 579.53932,1441.0174 580.68499,1440.6631 581.63696,1439.9544 C 582.58775,1439.2529 583.33775,1438.1284 583.89405,1436.58 L 583.894,1436.58 z M 571.8727,1430.6568 L 583.9353,1430.6568 C 583.77585,1428.8438 583.3105,1427.4761 582.55341,1426.5725 C 581.38648,1425.1635 579.87349,1424.4548 578.01916,1424.4548 C 576.33845,1424.4548 574.92113,1425.017 573.77546,1426.1426 C 572.62979,1427.267 571.9979,1428.7741 571.8727,1430.6568 L 571.8727,1430.6568 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path99" />
+
+   <path
+   d="M 602.491,1432.74 C 602.491,1428.7408 603.60242,1425.775 605.83116,1423.8522 C 607.68549,1422.2542 609.94966,1421.4487 612.6225,1421.4487 C 615.59533,1421.4487 618.02486,1422.4219 619.90754,1424.3731 C 621.79612,1426.3172 622.73392,1429.0042 622.73392,1432.4353 C 622.73392,1435.2191 622.31699,1437.4077 621.48313,1438.9975 C 620.65045,1440.5943 619.4351,1441.8309 617.84533,1442.712 C 616.2473,1443.5943 614.51108,1444.0325 612.6225,1444.0325 C 609.60242,1444.0325 607.15754,1443.0664 605.28904,1441.1223 C 603.42172,1439.1853 602.49101,1436.3931 602.49101,1432.74 L 602.491,1432.74 z M 606.25517,1432.74 C 606.25517,1435.5109 606.85871,1437.5813 608.06698,1438.9561 C 609.27525,1440.338 610.79651,1441.0254 612.62249,1441.0254 C 614.44257,1441.0254 615.95556,1440.3309 617.16383,1438.949 C 618.36619,1437.5672 618.96974,1435.4554 618.96974,1432.6231 C 618.96974,1429.949 618.3662,1427.9211 617.15084,1426.5463 C 615.93549,1425.1715 614.4284,1424.4841 612.62249,1424.4841 C 610.79651,1424.4841 609.27525,1425.1715 608.06698,1426.5392 C 606.85871,1427.9069 606.25517,1429.9762 606.25517,1432.74 L 606.25517,1432.74 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path101" />
+
+   <path
+   d="M 627.032,1443.54 L 627.032,1421.9365 L 630.32373,1421.9365 L 630.32373,1425.0062 C 631.91467,1422.631 634.20601,1421.4428 637.19893,1421.4428 C 638.50405,1421.4428 639.69814,1421.679 640.78948,1422.1444 C 641.88672,1422.6168 642.69814,1423.2274 643.24027,1423.9916 C 643.78948,1424.7487 644.16389,1425.6511 644.38594,1426.6928 C 644.51822,1427.3743 644.58791,1428.5613 644.58791,1430.2562 L 644.58791,1443.5401 L 640.92059,1443.5401 L 640.92059,1430.3944 C 640.92059,1428.9086 640.7824,1427.7901 640.49775,1427.0471 C 640.21311,1426.3113 639.70523,1425.7208 638.98358,1425.2838 C 638.25484,1424.8397 637.40681,1424.6164 636.42767,1424.6164 C 634.86507,1424.6164 633.5257,1425.1172 632.38594,1426.1034 C 631.25444,1427.0956 630.69224,1428.9712 630.69224,1431.742 L 630.69224,1443.54 L 627.032,1443.54 L 627.032,1443.54 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path103" />
+
+   <path
+   d="M 988.517,1440.88 C 987.15519,1442.0328 985.85007,1442.8454 984.60046,1443.3249 C 983.34259,1443.7973 981.99613,1444.0335 980.55873,1444.0335 C 978.18353,1444.0335 976.36464,1443.4572 975.08668,1442.2973 C 973.81581,1441.1375 973.17684,1439.6517 973.17684,1437.8528 C 973.17684,1436.7898 973.41306,1435.8249 973.89849,1434.9497 C 974.37802,1434.0745 975.00991,1433.3741 975.78825,1432.8461 C 976.57251,1432.3182 977.4477,1431.9154 978.42683,1431.645 C 979.1414,1431.4572 980.22565,1431.2694 981.67604,1431.0957 C 984.6347,1430.7414 986.81502,1430.3245 988.21108,1429.832 C 988.22526,1429.3324 988.23234,1429.0123 988.23234,1428.88 C 988.23234,1427.3871 987.8851,1426.3324 987.19061,1425.7276 C 986.2599,1424.895 984.86384,1424.4851 983.02368,1424.4851 C 981.30163,1424.4851 980.03077,1424.7839 979.20399,1425.3875 C 978.38431,1425.9922 977.78076,1427.0611 977.38509,1428.5954 L 973.80871,1428.1028 C 974.1347,1426.5757 974.66974,1425.332 975.41265,1424.3942 C 976.15557,1423.4505 977.23863,1422.7206 978.64887,1422.2139 C 980.05793,1421.7072 981.69021,1421.4497 983.55163,1421.4497 C 985.39887,1421.4497 986.89179,1421.6729 988.04454,1422.1028 C 989.1973,1422.541 990.04415,1423.082 990.59336,1423.7422 C 991.13431,1424.4013 991.5099,1425.228 991.73194,1426.2343 C 991.85005,1426.8603 991.91265,1427.9847 991.91265,1429.6099 L 991.91265,1434.4914 C 991.91265,1437.9013 991.98824,1440.0544 992.14887,1440.9497 C 992.30123,1441.8521 992.61423,1442.7202 993.07249,1443.5469 L 989.24572,1443.5469 C 988.87132,1442.7899 988.62092,1441.9017 988.51698,1440.88 L 988.517,1440.88 z M 988.21109,1432.6997 C 986.87763,1433.2489 984.88511,1433.7072 982.23235,1434.0887 C 980.72526,1434.3036 979.65518,1434.5469 979.03747,1434.8174 C 978.41267,1435.0891 977.92605,1435.4847 977.59298,1436.0127 C 977.25283,1436.5336 977.0792,1437.1099 977.0792,1437.7489 C 977.0792,1438.728 977.45479,1439.5406 978.19062,1440.1926 C 978.92645,1440.8387 980.00952,1441.1647 981.43393,1441.1647 C 982.84299,1441.1647 984.09968,1440.8599 985.19692,1440.241 C 986.29416,1439.6233 987.10676,1438.7765 987.62054,1437.7064 C 988.01621,1436.8808 988.21109,1435.6584 988.21109,1434.0473 L 988.21109,1432.6997 L 988.21109,1432.6997 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path105" />
+
+   <path
+   d="M 1011.61,1443.54 L 1011.61,1440.8105 C 1010.2423,1442.9565 1008.2285,1444.0266 1005.5687,1444.0266 C 1003.8466,1444.0266 1002.2628,1443.5542 1000.8183,1442.6022 C 999.37378,1441.6585 998.25646,1440.3321 997.45803,1438.6231 C 996.66551,1436.9223 996.26984,1434.9711 996.26984,1432.7553 C 996.26984,1430.6022 996.63126,1428.6439 997.34701,1426.8876 C 998.06866,1425.1302 999.14465,1423.7837 1000.5821,1422.853 C 1002.0206,1421.9152 1003.6317,1421.4427 1005.4092,1421.4427 C 1006.7073,1421.4427 1007.8671,1421.7215 1008.8805,1422.2695 C 1009.9021,1422.8187 1010.7277,1423.5333 1011.3667,1424.4156 L 1011.3667,1413.7148 L 1015.0057,1413.7148 L 1015.0057,1443.54 L 1011.61,1443.54 L 1011.61,1443.54 z M 1000.034,1432.7554 C 1000.034,1435.5263 1000.6175,1437.5956 1001.7844,1438.9633 C 1002.9501,1440.3322 1004.3261,1441.0196 1005.9159,1441.0196 C 1007.5127,1441.0196 1008.8746,1440.3593 1009.9919,1439.0542 C 1011.1104,1437.7479 1011.6726,1435.7483 1011.6726,1433.0613 C 1011.6726,1430.1027 1011.1033,1427.9365 1009.9647,1426.5546 C 1008.8249,1425.1656 1007.423,1424.4782 1005.7494,1424.4782 C 1004.1242,1424.4782 1002.7635,1425.1444 1001.6734,1426.4708 C 1000.582,1427.7971 1000.034,1429.8948 1000.034,1432.7554 L 1000.034,1432.7554 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path107" />
+
+   <path
+   d="M 1020.78,1417.93 L 1020.78,1413.7158 L 1024.4461,1413.7158 L 1024.4461,1417.93 L 1020.78,1417.93 z M 1020.78,1443.541 L 1020.78,1421.9375 L 1024.4461,1421.9375 L 1024.4461,1443.541 L 1020.78,1443.541 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path109" />
+
+   <path
+   d="M 1044.81,1436.58 L 1048.5942,1437.0454 C 1047.9966,1439.2599 1046.8935,1440.9749 1045.2824,1442.1973 C 1043.6643,1443.4127 1041.6009,1444.0245 1039.0946,1444.0245 C 1035.9352,1444.0245 1033.4277,1443.0513 1031.5805,1441.1072 C 1029.7261,1439.1631 1028.8025,1436.4336 1028.8025,1432.9198 C 1028.8025,1429.2808 1029.7403,1426.4615 1031.6088,1424.4548 C 1033.4832,1422.4481 1035.9069,1421.4406 1038.8927,1421.4406 C 1041.7817,1421.4406 1044.1427,1422.4269 1045.9699,1424.3922 C 1047.8029,1426.3576 1048.7195,1429.1284 1048.7195,1432.6906 C 1048.7195,1432.9127 1048.7124,1433.2399 1048.6982,1433.6698 L 1032.588,1433.6698 C 1032.7203,1436.045 1033.3935,1437.8639 1034.6018,1439.1217 C 1035.8101,1440.3855 1037.3101,1441.0174 1039.116,1441.0174 C 1040.4553,1441.0174 1041.601,1440.6631 1042.553,1439.9544 C 1043.5037,1439.2529 1044.2538,1438.1284 1044.8101,1436.58 L 1044.81,1436.58 z M 1032.7887,1430.6568 L 1044.8513,1430.6568 C 1044.6919,1428.8438 1044.2265,1427.4761 1043.4694,1426.5725 C 1042.3025,1425.1635 1040.7895,1424.4548 1038.9352,1424.4548 C 1037.2544,1424.4548 1035.8371,1425.017 1034.6915,1426.1426 C 1033.5458,1427.267 1032.9139,1428.7741 1032.7887,1430.6568 L 1032.7887,1430.6568 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path111" />
+
+   <path
+   d="M 1053.19,1443.54 L 1053.19,1421.9365 L 1056.4817,1421.9365 L 1056.4817,1425.0062 C 1058.0727,1422.631 1060.364,1421.4428 1063.3569,1421.4428 C 1064.662,1421.4428 1065.8561,1421.679 1066.9475,1422.1444 C 1068.0447,1422.6168 1068.8561,1423.2274 1069.3983,1423.9916 C 1069.9475,1424.7487 1070.3219,1425.6511 1070.5439,1426.6928 C 1070.6762,1427.3743 1070.7459,1428.5613 1070.7459,1430.2562 L 1070.7459,1443.5401 L 1067.0786,1443.5401 L 1067.0786,1430.3944 C 1067.0786,1428.9086 1066.9404,1427.7901 1066.6558,1427.0471 C 1066.3711,1426.3113 1065.8632,1425.7208 1065.1416,1425.2838 C 1064.4128,1424.8397 1063.5648,1424.6164 1062.5857,1424.6164 C 1061.0231,1424.6164 1059.6837,1425.1172 1058.5439,1426.1034 C 1057.4124,1427.0956 1056.8502,1428.9712 1056.8502,1431.742 L 1056.8502,1443.54 L 1053.19,1443.54 L 1053.19,1443.54 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path113" />
+
+   <path
+   d="M 1084.36,1440.26 L 1084.8868,1443.4962 C 1083.8592,1443.7112 1082.9356,1443.8222 1082.123,1443.8222 C 1080.7907,1443.8222 1079.762,1443.6143 1079.0261,1443.1903 C 1078.2974,1442.7734 1077.7836,1442.2183 1077.4848,1441.5309 C 1077.186,1440.8505 1077.0336,1439.4061 1077.0336,1437.2116 L 1077.0336,1424.7805 L 1074.3454,1424.7805 L 1074.3454,1421.934 L 1077.0336,1421.934 L 1077.0336,1416.5801 L 1080.6785,1414.3856 L 1080.6785,1421.934 L 1084.36,1421.934 L 1084.36,1424.7805 L 1080.6785,1424.7805 L 1080.6785,1437.4124 C 1080.6785,1438.4612 1080.7411,1439.1285 1080.8663,1439.4262 C 1080.9986,1439.725 1081.2065,1439.9612 1081.4982,1440.1419 C 1081.7899,1440.3155 1082.2068,1440.4053 1082.749,1440.4053 C 1083.1576,1440.4053 1083.6927,1440.3569 1084.36,1440.26 L 1084.36,1440.26 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path115" />
+
+   <polygon
+   points="1098.09,1434.59 1098.09,1430.91 1109.35,1430.91 1109.35,1434.59 1098.09,1434.59 "
+   style="fill:#000000;fill-rule:nonzero"
+   id="polygon117" />
+
+   <path
+   d="M 1138.98,1443.54 L 1138.98,1440.8105 C 1137.6123,1442.9565 1135.5985,1444.0266 1132.9387,1444.0266 C 1131.2166,1444.0266 1129.6328,1443.5542 1128.1883,1442.6022 C 1126.7438,1441.6585 1125.6265,1440.3321 1124.828,1438.6231 C 1124.0355,1436.9223 1123.6398,1434.9711 1123.6398,1432.7553 C 1123.6398,1430.6022 1124.0013,1428.6439 1124.717,1426.8876 C 1125.4387,1425.1302 1126.5147,1423.7837 1127.9521,1422.853 C 1129.3906,1421.9152 1131.0017,1421.4427 1132.7792,1421.4427 C 1134.0773,1421.4427 1135.2371,1421.7215 1136.2505,1422.2695 C 1137.2721,1422.8187 1138.0977,1423.5333 1138.7367,1424.4156 L 1138.7367,1413.7148 L 1142.3757,1413.7148 L 1142.3757,1443.54 L 1138.98,1443.54 L 1138.98,1443.54 z M 1127.404,1432.7554 C 1127.404,1435.5263 1127.9875,1437.5956 1129.1544,1438.9633 C 1130.3201,1440.3322 1131.6961,1441.0196 1133.2859,1441.0196 C 1134.8827,1441.0196 1136.2445,1440.3593 1137.3619,1439.0542 C 1138.4804,1437.7479 1139.0426,1435.7483 1139.0426,1433.0613 C 1139.0426,1430.1027 1138.4733,1427.9365 1137.3347,1426.5546 C 1136.195,1425.1656 1134.793,1424.4782 1133.1194,1424.4782 C 1131.4942,1424.4782 1130.1335,1425.1444 1129.0434,1426.4708 C 1127.952,1427.7971 1127.404,1429.8948 1127.404,1432.7554 L 1127.404,1432.7554 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path119" />
+
+   <path
+   d="M 1148.16,1417.93 L 1148.16,1413.7158 L 1151.8261,1413.7158 L 1151.8261,1417.93 L 1148.16,1417.93 z M 1148.16,1443.541 L 1148.16,1421.9375 L 1151.8261,1421.9375 L 1151.8261,1443.541 L 1148.16,1443.541 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path121" />
+
+   <path
+   d="M 1158.27,1443.54 L 1158.27,1424.7829 L 1155.0409,1424.7829 L 1155.0409,1421.9364 L 1158.27,1421.9364 L 1158.27,1419.638 C 1158.27,1418.1864 1158.4023,1417.1034 1158.6586,1416.4018 C 1159.0129,1415.4498 1159.6318,1414.6797 1160.52,1414.0892 C 1161.4094,1413.4986 1162.6519,1413.2069 1164.2558,1413.2069 C 1165.2846,1413.2069 1166.4232,1413.325 1167.6728,1413.5754 L 1167.1247,1416.7703 C 1166.3676,1416.6309 1165.6448,1416.5612 1164.9645,1416.5612 C 1163.8531,1416.5612 1163.0688,1416.7975 1162.6106,1417.277 C 1162.1452,1417.7494 1161.9161,1418.6376 1161.9161,1419.9427 L 1161.9161,1421.9364 L 1166.1243,1421.9364 L 1166.1243,1424.7829 L 1161.9161,1424.7829 L 1161.9161,1443.54 L 1158.27,1443.54 L 1158.27,1443.54 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path123" />
+
+   <path
+   d="M 1169.09,1443.54 L 1169.09,1424.7829 L 1165.8609,1424.7829 L 1165.8609,1421.9364 L 1169.09,1421.9364 L 1169.09,1419.638 C 1169.09,1418.1864 1169.2223,1417.1034 1169.4786,1416.4018 C 1169.8329,1415.4498 1170.4518,1414.6797 1171.34,1414.0892 C 1172.2294,1413.4986 1173.4719,1413.2069 1175.0758,1413.2069 C 1176.1046,1413.2069 1177.2432,1413.325 1178.4928,1413.5754 L 1177.9447,1416.7703 C 1177.1876,1416.6309 1176.4648,1416.5612 1175.7845,1416.5612 C 1174.6731,1416.5612 1173.8888,1416.7975 1173.4306,1417.277 C 1172.9652,1417.7494 1172.7361,1418.6376 1172.7361,1419.9427 L 1172.7361,1421.9364 L 1176.9443,1421.9364 L 1176.9443,1424.7829 L 1172.7361,1424.7829 L 1172.7361,1443.54 L 1169.09,1443.54 L 1169.09,1443.54 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path125" />
+
+   <path
+   d="M 1194.59,1436.58 L 1198.3742,1437.0454 C 1197.7766,1439.2599 1196.6735,1440.9749 1195.0624,1442.1973 C 1193.4443,1443.4127 1191.3809,1444.0245 1188.8746,1444.0245 C 1185.7152,1444.0245 1183.2077,1443.0513 1181.3605,1441.1072 C 1179.5061,1439.1631 1178.5825,1436.4336 1178.5825,1432.9198 C 1178.5825,1429.2808 1179.5203,1426.4615 1181.3888,1424.4548 C 1183.2632,1422.4481 1185.6869,1421.4406 1188.6727,1421.4406 C 1191.5617,1421.4406 1193.9227,1422.4269 1195.7499,1424.3922 C 1197.5829,1426.3576 1198.4995,1429.1284 1198.4995,1432.6906 C 1198.4995,1432.9127 1198.4924,1433.2399 1198.4782,1433.6698 L 1182.368,1433.6698 C 1182.5003,1436.045 1183.1735,1437.8639 1184.3818,1439.1217 C 1185.5901,1440.3855 1187.0901,1441.0174 1188.896,1441.0174 C 1190.2353,1441.0174 1191.381,1440.6631 1192.333,1439.9544 C 1193.2837,1439.2529 1194.0338,1438.1284 1194.5901,1436.58 L 1194.59,1436.58 z M 1182.5687,1430.6568 L 1194.6313,1430.6568 C 1194.4719,1428.8438 1194.0065,1427.4761 1193.2494,1426.5725 C 1192.0825,1425.1635 1190.5695,1424.4548 1188.7152,1424.4548 C 1187.0344,1424.4548 1185.6171,1425.017 1184.4715,1426.1426 C 1183.3258,1427.267 1182.6939,1428.7741 1182.5687,1430.6568 L 1182.5687,1430.6568 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path127" />
+
+   <path
+   d="M 1202.93,1443.54 L 1202.93,1421.9365 L 1206.2217,1421.9365 L 1206.2217,1425.207 C 1207.0615,1423.6798 1207.8398,1422.6652 1208.5544,1422.1798 C 1209.2631,1421.6932 1210.0473,1421.4428 1210.9024,1421.4428 C 1212.1379,1421.4428 1213.3887,1421.8396 1214.6654,1422.6239 L 1213.4017,1426.0267 C 1212.5135,1425.4916 1211.617,1425.2282 1210.7217,1425.2282 C 1209.9162,1425.2282 1209.2005,1425.4715 1208.5615,1425.9499 C 1207.9225,1426.4365 1207.4713,1427.1026 1207.2009,1427.9566 C 1206.791,1429.2558 1206.5902,1430.679 1206.5902,1432.2274 L 1206.5902,1443.54 L 1202.93,1443.54 L 1202.93,1443.54 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path129" />
+
+   <path
+   d="M 1231.63,1436.58 L 1235.4143,1437.0454 C 1234.8166,1439.2599 1233.7135,1440.9749 1232.1024,1442.1973 C 1230.4843,1443.4127 1228.4209,1444.0245 1225.9146,1444.0245 C 1222.7552,1444.0245 1220.2477,1443.0513 1218.4005,1441.1072 C 1216.5461,1439.1631 1215.6225,1436.4336 1215.6225,1432.9198 C 1215.6225,1429.2808 1216.5603,1426.4615 1218.4288,1424.4548 C 1220.3032,1422.4481 1222.7269,1421.4406 1225.7127,1421.4406 C 1228.6017,1421.4406 1230.9627,1422.4269 1232.7899,1424.3922 C 1234.6229,1426.3576 1235.5395,1429.1284 1235.5395,1432.6906 C 1235.5395,1432.9127 1235.5324,1433.2399 1235.5182,1433.6698 L 1219.408,1433.6698 C 1219.5403,1436.045 1220.2135,1437.8639 1221.4218,1439.1217 C 1222.6301,1440.3855 1224.1301,1441.0174 1225.936,1441.0174 C 1227.2753,1441.0174 1228.421,1440.6631 1229.373,1439.9544 C 1230.3237,1439.2529 1231.0738,1438.1284 1231.6301,1436.58 L 1231.63,1436.58 z M 1219.6087,1430.6568 L 1231.6713,1430.6568 C 1231.5119,1428.8438 1231.0465,1427.4761 1230.2894,1426.5725 C 1229.1225,1425.1635 1227.6095,1424.4548 1225.7552,1424.4548 C 1224.0744,1424.4548 1222.6571,1425.017 1221.5115,1426.1426 C 1220.3658,1427.267 1219.7339,1428.7741 1219.6087,1430.6568 L 1219.6087,1430.6568 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path131" />
+
+   <path
+   d="M 1240.02,1443.54 L 1240.02,1421.9365 L 1243.3117,1421.9365 L 1243.3117,1425.0062 C 1244.9027,1422.631 1247.194,1421.4428 1250.1869,1421.4428 C 1251.492,1421.4428 1252.6861,1421.679 1253.7775,1422.1444 C 1254.8747,1422.6168 1255.6861,1423.2274 1256.2283,1423.9916 C 1256.7775,1424.7487 1257.1519,1425.6511 1257.3739,1426.6928 C 1257.5062,1427.3743 1257.5759,1428.5613 1257.5759,1430.2562 L 1257.5759,1443.5401 L 1253.9086,1443.5401 L 1253.9086,1430.3944 C 1253.9086,1428.9086 1253.7704,1427.7901 1253.4858,1427.0471 C 1253.2011,1426.3113 1252.6932,1425.7208 1251.9716,1425.2838 C 1251.2428,1424.8397 1250.3948,1424.6164 1249.4157,1424.6164 C 1247.8531,1424.6164 1246.5137,1425.1172 1245.3739,1426.1034 C 1244.2424,1427.0956 1243.6802,1428.9712 1243.6802,1431.742 L 1243.6802,1443.54 L 1240.02,1443.54 L 1240.02,1443.54 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path133" />
+
+   <path
+   d="M 1271.19,1440.26 L 1271.7168,1443.4962 C 1270.6892,1443.7112 1269.7656,1443.8222 1268.953,1443.8222 C 1267.6207,1443.8222 1266.592,1443.6143 1265.8561,1443.1903 C 1265.1274,1442.7734 1264.6136,1442.2183 1264.3148,1441.5309 C 1264.016,1440.8505 1263.8636,1439.4061 1263.8636,1437.2116 L 1263.8636,1424.7805 L 1261.1754,1424.7805 L 1261.1754,1421.934 L 1263.8636,1421.934 L 1263.8636,1416.5801 L 1267.5085,1414.3856 L 1267.5085,1421.934 L 1271.19,1421.934 L 1271.19,1424.7805 L 1267.5085,1424.7805 L 1267.5085,1437.4124 C 1267.5085,1438.4612 1267.5711,1439.1285 1267.6963,1439.4262 C 1267.8286,1439.725 1268.0365,1439.9612 1268.3282,1440.1419 C 1268.6199,1440.3155 1269.0368,1440.4053 1269.579,1440.4053 C 1269.9876,1440.4053 1270.5227,1440.3569 1271.19,1440.26 L 1271.19,1440.26 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path135" />
+
+   <path
+   d="M 1300.45,1435.63 L 1304.0465,1436.1024 C 1303.6579,1438.5816 1302.6504,1440.5257 1301.0264,1441.9288 C 1299.4083,1443.332 1297.4146,1444.0335 1295.0536,1444.0335 C 1292.1032,1444.0335 1289.7209,1443.0674 1287.9291,1441.1375 C 1286.1303,1439.2064 1285.228,1436.4355 1285.228,1432.8249 C 1285.228,1430.4922 1285.6165,1428.4501 1286.3878,1426.6997 C 1287.165,1424.9505 1288.339,1423.6371 1289.9217,1422.7631 C 1291.4984,1421.8879 1293.2205,1421.4497 1295.0748,1421.4497 C 1297.4217,1421.4497 1299.3457,1422.0473 1300.8315,1423.2343 C 1302.3244,1424.4225 1303.2835,1426.1032 1303.7063,1428.2906 L 1300.1441,1428.8387 C 1299.8039,1427.3871 1299.2063,1426.2969 1298.3453,1425.5611 C 1297.4843,1424.8324 1296.4425,1424.4639 1295.2201,1424.4639 C 1293.3728,1424.4639 1291.8728,1425.1241 1290.7201,1426.4505 C 1289.5673,1427.7698 1288.991,1429.8603 1288.991,1432.7209 C 1288.991,1435.6229 1289.5472,1437.7347 1290.6646,1439.054 C 1291.776,1440.3662 1293.2276,1441.0265 1295.0193,1441.0265 C 1296.4567,1441.0265 1297.6508,1440.5812 1298.6158,1439.7001 C 1299.5819,1438.8178 1300.1925,1437.4642 1300.45,1435.63 L 1300.45,1435.63 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path137" />
+
+   <path
+   d="M 1321.34,1443.54 L 1321.34,1440.3664 C 1319.6522,1442.8113 1317.3679,1444.0266 1314.479,1444.0266 C 1313.2081,1444.0266 1312.0128,1443.7833 1310.9097,1443.2967 C 1309.8054,1442.8113 1308.9857,1442.1924 1308.4506,1441.4565 C 1307.9097,1440.7136 1307.5341,1439.8113 1307.3191,1438.7412 C 1307.1727,1438.0195 1307.0971,1436.8809 1307.0971,1435.3184 L 1307.0971,1421.9365 L 1310.7561,1421.9365 L 1310.7561,1433.9152 C 1310.7561,1435.8321 1310.8329,1437.1159 1310.9782,1437.7833 C 1311.2144,1438.7482 1311.701,1439.4982 1312.4439,1440.0533 C 1313.1939,1440.6026 1314.1176,1440.873 1315.2148,1440.873 C 1316.3121,1440.873 1317.3396,1440.5955 1318.3046,1440.0333 C 1319.2695,1439.4711 1319.951,1438.6998 1320.3467,1437.7348 C 1320.7495,1436.7628 1320.9502,1435.3526 1320.9502,1433.5124 L 1320.9502,1421.9364 L 1324.6105,1421.9364 L 1324.6105,1443.5399 L 1321.34,1443.5399 L 1321.34,1443.54 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path139" />
+
+   <path
+   d="M 1330.31,1443.54 L 1330.31,1421.9365 L 1333.6017,1421.9365 L 1333.6017,1425.207 C 1334.4415,1423.6798 1335.2198,1422.6652 1335.9344,1422.1798 C 1336.6431,1421.6932 1337.4273,1421.4428 1338.2824,1421.4428 C 1339.5179,1421.4428 1340.7687,1421.8396 1342.0454,1422.6239 L 1340.7816,1426.0267 C 1339.8935,1425.4916 1338.997,1425.2282 1338.1017,1425.2282 C 1337.2962,1425.2282 1336.5805,1425.4715 1335.9415,1425.9499 C 1335.3025,1426.4365 1334.8513,1427.1026 1334.5809,1427.9566 C 1334.171,1429.2558 1333.9702,1430.679 1333.9702,1432.2274 L 1333.9702,1443.54 L 1330.31,1443.54 L 1330.31,1443.54 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path141" />
+
+   <path
+   d="M 1350.23,1443.54 L 1342.0084,1421.9365 L 1345.8765,1421.9365 L 1350.5146,1434.8731 C 1351.0154,1436.2692 1351.4737,1437.7207 1351.8965,1439.2278 C 1352.2237,1438.0892 1352.6749,1436.7203 1353.2584,1435.1164 L 1358.0631,1421.9365 L 1361.8272,1421.9365 L 1353.6469,1443.54 L 1350.23,1443.54 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path143" />
+
+   <path
+   d="M 1379.85,1436.58 L 1383.6342,1437.0454 C 1383.0366,1439.2599 1381.9335,1440.9749 1380.3224,1442.1973 C 1378.7043,1443.4127 1376.6409,1444.0245 1374.1346,1444.0245 C 1370.9752,1444.0245 1368.4677,1443.0513 1366.6205,1441.1072 C 1364.7661,1439.1631 1363.8425,1436.4336 1363.8425,1432.9198 C 1363.8425,1429.2808 1364.7803,1426.4615 1366.6488,1424.4548 C 1368.5232,1422.4481 1370.9469,1421.4406 1373.9327,1421.4406 C 1376.8217,1421.4406 1379.1827,1422.4269 1381.0099,1424.3922 C 1382.8429,1426.3576 1383.7595,1429.1284 1383.7595,1432.6906 C 1383.7595,1432.9127 1383.7524,1433.2399 1383.7382,1433.6698 L 1367.628,1433.6698 C 1367.7603,1436.045 1368.4335,1437.8639 1369.6418,1439.1217 C 1370.8501,1440.3855 1372.3501,1441.0174 1374.156,1441.0174 C 1375.4953,1441.0174 1376.641,1440.6631 1377.593,1439.9544 C 1378.5437,1439.2529 1379.2938,1438.1284 1379.8501,1436.58 L 1379.85,1436.58 z M 1367.8287,1430.6568 L 1379.8913,1430.6568 C 1379.7319,1428.8438 1379.2665,1427.4761 1378.5094,1426.5725 C 1377.3425,1425.1635 1375.8295,1424.4548 1373.9752,1424.4548 C 1372.2944,1424.4548 1370.8771,1425.017 1369.7315,1426.1426 C 1368.5858,1427.267 1367.9539,1428.7741 1367.8287,1430.6568 L 1367.8287,1430.6568 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path145" />
+
+   <path
+   d="M 1386.77,1437.09 L 1390.3877,1436.5207 C 1390.5885,1437.9723 1391.159,1439.0825 1392.0885,1439.8609 C 1393.0121,1440.6309 1394.3113,1441.0207 1395.985,1441.0207 C 1397.6657,1441.0207 1398.9153,1440.6735 1399.7279,1439.9931 C 1400.5405,1439.3057 1400.9503,1438.4991 1400.9503,1437.5825 C 1400.9503,1436.7498 1400.5889,1436.1038 1399.8661,1435.6242 C 1399.3665,1435.2983 1398.1169,1434.8884 1396.1232,1434.3888 C 1393.4432,1433.7085 1391.5747,1433.125 1390.5401,1432.6242 C 1389.5054,1432.1317 1388.7141,1431.4443 1388.1791,1430.5691 C 1387.6452,1429.6939 1387.3736,1428.729 1387.3736,1427.6731 C 1387.3736,1426.7081 1387.5956,1425.8199 1388.0409,1425.0002 C 1388.4779,1424.1735 1389.0826,1423.4931 1389.8385,1422.951 C 1390.409,1422.5353 1391.1862,1422.1739 1392.1653,1421.8821 C 1393.1515,1421.5904 1394.2074,1421.4439 1395.3318,1421.4439 C 1397.0267,1421.4439 1398.5125,1421.6943 1399.7976,1422.1809 C 1401.0814,1422.6664 1402.0263,1423.3266 1402.637,1424.1593 C 1403.2488,1425.0002 1403.6657,1426.1105 1403.8948,1427.5065 L 1400.3184,1428.0002 C 1400.1519,1426.8888 1399.6795,1426.0207 1398.9011,1425.3959 C 1398.124,1424.7711 1397.0196,1424.4581 1395.5964,1424.4581 C 1393.9157,1424.4581 1392.7145,1424.7357 1391.9988,1425.292 C 1391.2771,1425.8471 1390.9157,1426.5002 1390.9157,1427.2432 C 1390.9157,1427.7215 1391.0681,1428.1455 1391.3669,1428.5282 C 1391.6657,1428.9239 1392.131,1429.2428 1392.77,1429.5073 C 1393.1373,1429.6384 1394.2145,1429.9514 1396.0051,1430.4369 C 1398.5952,1431.1313 1400.4011,1431.6947 1401.4216,1432.1388 C 1402.4503,1432.5758 1403.2559,1433.2219 1403.8393,1434.0617 C 1404.4216,1434.9026 1404.7133,1435.9443 1404.7133,1437.1939 C 1404.7133,1438.4164 1404.3531,1439.562 1403.6444,1440.6451 C 1402.9287,1441.7223 1401.9011,1442.555 1400.5606,1443.1455 C 1399.2212,1443.7361 1397.6999,1444.0278 1396.0051,1444.0278 C 1393.1929,1444.0278 1391.0539,1443.4443 1389.5822,1442.2774 C 1388.1094,1441.1105 1387.1728,1439.3813 1386.77,1437.09 L 1386.77,1437.09 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path147" />
+
+   <path
+   d="M 1410.02,1443.54 L 1410.02,1439.366 L 1414.1928,1439.366 L 1414.1928,1443.54 C 1414.1928,1445.0742 1413.9224,1446.3109 1413.3802,1447.2558 C 1412.8322,1448.1924 1411.9712,1448.9223 1410.7972,1449.4432 L 1409.7767,1447.8735 C 1410.548,1447.5333 1411.1172,1447.0325 1411.4846,1446.3806 C 1411.8531,1445.7203 1412.0539,1444.7766 1412.0964,1443.54 L 1410.02,1443.54 L 1410.02,1443.54 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path149" />
+
+   <path
+   d="M 1430.75,1437.09 L 1434.3677,1436.5207 C 1434.5685,1437.9723 1435.139,1439.0825 1436.0685,1439.8609 C 1436.9921,1440.6309 1438.2913,1441.0207 1439.965,1441.0207 C 1441.6457,1441.0207 1442.8953,1440.6735 1443.7079,1439.9931 C 1444.5205,1439.3057 1444.9303,1438.4991 1444.9303,1437.5825 C 1444.9303,1436.7498 1444.5689,1436.1038 1443.8461,1435.6242 C 1443.3465,1435.2983 1442.0969,1434.8884 1440.1032,1434.3888 C 1437.4232,1433.7085 1435.5547,1433.125 1434.5201,1432.6242 C 1433.4854,1432.1317 1432.6941,1431.4443 1432.1591,1430.5691 C 1431.6252,1429.6939 1431.3536,1428.729 1431.3536,1427.6731 C 1431.3536,1426.7081 1431.5756,1425.8199 1432.0209,1425.0002 C 1432.4579,1424.1735 1433.0626,1423.4931 1433.8185,1422.951 C 1434.389,1422.5353 1435.1662,1422.1739 1436.1453,1421.8821 C 1437.1315,1421.5904 1438.1874,1421.4439 1439.3118,1421.4439 C 1441.0067,1421.4439 1442.4925,1421.6943 1443.7776,1422.1809 C 1445.0614,1422.6664 1446.0063,1423.3266 1446.617,1424.1593 C 1447.2288,1425.0002 1447.6457,1426.1105 1447.8748,1427.5065 L 1444.2984,1428.0002 C 1444.1319,1426.8888 1443.6595,1426.0207 1442.8811,1425.3959 C 1442.104,1424.7711 1440.9996,1424.4581 1439.5764,1424.4581 C 1437.8957,1424.4581 1436.6945,1424.7357 1435.9788,1425.292 C 1435.2571,1425.8471 1434.8957,1426.5002 1434.8957,1427.2432 C 1434.8957,1427.7215 1435.0481,1428.1455 1435.3469,1428.5282 C 1435.6457,1428.9239 1436.111,1429.2428 1436.75,1429.5073 C 1437.1173,1429.6384 1438.1945,1429.9514 1439.9851,1430.4369 C 1442.5752,1431.1313 1444.3811,1431.6947 1445.4016,1432.1388 C 1446.4303,1432.5758 1447.2359,1433.2219 1447.8193,1434.0617 C 1448.4016,1434.9026 1448.6933,1435.9443 1448.6933,1437.1939 C 1448.6933,1438.4164 1448.3331,1439.562 1447.6244,1440.6451 C 1446.9087,1441.7223 1445.8811,1442.555 1444.5406,1443.1455 C 1443.2012,1443.7361 1441.6799,1444.0278 1439.9851,1444.0278 C 1437.1729,1444.0278 1435.0339,1443.4443 1433.5622,1442.2774 C 1432.0894,1441.1105 1431.1528,1439.3813 1430.75,1437.09 L 1430.75,1437.09 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path151" />
+
+   <path
+   d="M 1453.05,1451.82 L 1453.05,1421.9393 L 1456.3831,1421.9393 L 1456.3831,1424.7444 C 1457.1685,1423.6472 1458.0567,1422.8216 1459.05,1422.2724 C 1460.0362,1421.7243 1461.2374,1421.4456 1462.6476,1421.4456 C 1464.4949,1421.4456 1466.1201,1421.9251 1467.5291,1422.87 C 1468.9453,1423.8208 1470.0083,1425.1613 1470.724,1426.8905 C 1471.4457,1428.6196 1471.8071,1430.5153 1471.8071,1432.5775 C 1471.8071,1434.7861 1471.4114,1436.7787 1470.613,1438.5503 C 1469.8205,1440.3208 1468.6677,1441.6743 1467.1547,1442.6192 C 1465.6406,1443.557 1464.0496,1444.0295 1462.3831,1444.0295 C 1461.1618,1444.0295 1460.0705,1443.772 1459.0984,1443.2582 C 1458.1264,1442.7444 1457.335,1442.0913 1456.7102,1441.307 L 1456.7102,1451.82 L 1453.05,1451.82 L 1453.05,1451.82 z M 1456.363,1432.8621 C 1456.363,1435.64 1456.9252,1437.6952 1458.0508,1439.0286 C 1459.1752,1440.355 1460.5429,1441.0223 1462.1409,1441.0223 C 1463.765,1441.0223 1465.161,1440.3349 1466.3209,1438.953 C 1467.4807,1437.5782 1468.0642,1435.4464 1468.0642,1432.5574 C 1468.0642,1429.7995 1467.4949,1427.7444 1466.3622,1426.3696 C 1465.2307,1425.0019 1463.876,1424.3145 1462.3075,1424.3145 C 1460.7449,1424.3145 1459.363,1425.0432 1458.1618,1426.5019 C 1456.9595,1427.9593 1456.363,1430.0853 1456.363,1432.8621 L 1456.363,1432.8621 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path153" />
+
+   <path
+   d="M 1490.32,1440.88 C 1488.9582,1442.0328 1487.6531,1442.8454 1486.4035,1443.3249 C 1485.1456,1443.7973 1483.7991,1444.0335 1482.3617,1444.0335 C 1479.9865,1444.0335 1478.1676,1443.4572 1476.8897,1442.2973 C 1475.6188,1441.1375 1474.9798,1439.6517 1474.9798,1437.8528 C 1474.9798,1436.7898 1475.2161,1435.8249 1475.7015,1434.9497 C 1476.181,1434.0745 1476.8129,1433.3741 1477.5913,1432.8461 C 1478.3755,1432.3182 1479.2507,1431.9154 1480.2298,1431.645 C 1480.9444,1431.4572 1482.0287,1431.2694 1483.479,1431.0957 C 1486.4377,1430.7414 1488.618,1430.3245 1490.0141,1429.832 C 1490.0283,1429.3324 1490.0353,1429.0123 1490.0353,1428.88 C 1490.0353,1427.3871 1489.6881,1426.3324 1488.9936,1425.7276 C 1488.0629,1424.895 1486.6668,1424.4851 1484.8267,1424.4851 C 1483.1046,1424.4851 1481.8338,1424.7839 1481.007,1425.3875 C 1480.1873,1425.9922 1479.5838,1427.0611 1479.1881,1428.5954 L 1475.6117,1428.1028 C 1475.9377,1426.5757 1476.4727,1425.332 1477.2157,1424.3942 C 1477.9586,1423.4505 1479.0416,1422.7206 1480.4519,1422.2139 C 1481.8609,1421.7072 1483.4932,1421.4497 1485.3546,1421.4497 C 1487.2019,1421.4497 1488.6948,1421.6729 1489.8475,1422.1028 C 1491.0003,1422.541 1491.8472,1423.082 1492.3964,1423.7422 C 1492.9373,1424.4013 1493.3129,1425.228 1493.5349,1426.2343 C 1493.6531,1426.8603 1493.7157,1427.9847 1493.7157,1429.6099 L 1493.7157,1434.4914 C 1493.7157,1437.9013 1493.7912,1440.0544 1493.9519,1440.9497 C 1494.1042,1441.8521 1494.4172,1442.7202 1494.8755,1443.5469 L 1491.0487,1443.5469 C 1490.6743,1442.7899 1490.4239,1441.9017 1490.32,1440.88 L 1490.32,1440.88 z M 1490.0141,1432.6997 C 1488.6806,1433.2489 1486.6881,1433.7072 1484.0354,1434.0887 C 1482.5283,1434.3036 1481.4582,1434.5469 1480.8405,1434.8174 C 1480.2157,1435.0891 1479.7291,1435.4847 1479.396,1436.0127 C 1479.0558,1436.5336 1478.8822,1437.1099 1478.8822,1437.7489 C 1478.8822,1438.728 1479.2578,1439.5406 1479.9936,1440.1926 C 1480.7295,1440.8387 1481.8125,1441.1647 1483.2369,1441.1647 C 1484.646,1441.1647 1485.9027,1440.8599 1486.9999,1440.241 C 1488.0972,1439.6233 1488.9098,1438.7765 1489.4235,1437.7064 C 1489.8192,1436.8808 1490.0141,1435.6584 1490.0141,1434.0473 L 1490.0141,1432.6997 L 1490.0141,1432.6997 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path155" />
+
+   <path
+   d="M 1513.49,1435.63 L 1517.0865,1436.1024 C 1516.6979,1438.5816 1515.6904,1440.5257 1514.0664,1441.9288 C 1512.4483,1443.332 1510.4546,1444.0335 1508.0936,1444.0335 C 1505.1432,1444.0335 1502.7609,1443.0674 1500.9691,1441.1375 C 1499.1703,1439.2064 1498.268,1436.4355 1498.268,1432.8249 C 1498.268,1430.4922 1498.6565,1428.4501 1499.4278,1426.6997 C 1500.205,1424.9505 1501.379,1423.6371 1502.9617,1422.7631 C 1504.5384,1421.8879 1506.2605,1421.4497 1508.1148,1421.4497 C 1510.4617,1421.4497 1512.3857,1422.0473 1513.8715,1423.2343 C 1515.3644,1424.4225 1516.3235,1426.1032 1516.7463,1428.2906 L 1513.1841,1428.8387 C 1512.8439,1427.3871 1512.2463,1426.2969 1511.3853,1425.5611 C 1510.5243,1424.8324 1509.4825,1424.4639 1508.2601,1424.4639 C 1506.4128,1424.4639 1504.9128,1425.1241 1503.7601,1426.4505 C 1502.6073,1427.7698 1502.031,1429.8603 1502.031,1432.7209 C 1502.031,1435.6229 1502.5872,1437.7347 1503.7046,1439.054 C 1504.816,1440.3662 1506.2676,1441.0265 1508.0593,1441.0265 C 1509.4967,1441.0265 1510.6908,1440.5812 1511.6558,1439.7001 C 1512.6219,1438.8178 1513.2325,1437.4642 1513.49,1435.63 L 1513.49,1435.63 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path157" />
+
+   <path
+   d="M 1520.24,1417.93 L 1520.24,1413.7158 L 1523.9061,1413.7158 L 1523.9061,1417.93 L 1520.24,1417.93 z M 1520.24,1443.541 L 1520.24,1421.9375 L 1523.9061,1421.9375 L 1523.9061,1443.541 L 1520.24,1443.541 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path159" />
+
+   <path
+   d="M 1529.49,1443.54 L 1529.49,1421.9365 L 1532.7817,1421.9365 L 1532.7817,1425.0062 C 1534.3727,1422.631 1536.664,1421.4428 1539.6569,1421.4428 C 1540.962,1421.4428 1542.1561,1421.679 1543.2475,1422.1444 C 1544.3447,1422.6168 1545.1561,1423.2274 1545.6983,1423.9916 C 1546.2475,1424.7487 1546.6219,1425.6511 1546.8439,1426.6928 C 1546.9762,1427.3743 1547.0459,1428.5613 1547.0459,1430.2562 L 1547.0459,1443.5401 L 1543.3786,1443.5401 L 1543.3786,1430.3944 C 1543.3786,1428.9086 1543.2404,1427.7901 1542.9558,1427.0471 C 1542.6711,1426.3113 1542.1632,1425.7208 1541.4416,1425.2838 C 1540.7128,1424.8397 1539.8648,1424.6164 1538.8857,1424.6164 C 1537.3231,1424.6164 1535.9837,1425.1172 1534.8439,1426.1034 C 1533.7124,1427.0956 1533.1502,1428.9712 1533.1502,1431.742 L 1533.1502,1443.54 L 1529.49,1443.54 L 1529.49,1443.54 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path161" />
+
+   <path
+   d="M 1551.99,1445.33 L 1555.5522,1445.858 C 1555.6987,1446.9552 1556.1144,1447.7536 1556.7888,1448.2603 C 1557.6983,1448.9335 1558.9408,1449.2737 1560.5105,1449.2737 C 1562.2124,1449.2737 1563.5176,1448.9335 1564.4412,1448.2603 C 1565.3648,1447.58 1565.9825,1446.628 1566.3085,1445.4127 C 1566.5034,1444.6627 1566.5872,1443.1013 1566.5731,1440.7119 C 1564.9762,1442.5934 1562.9825,1443.5383 1560.5943,1443.5383 C 1557.6215,1443.5383 1555.3231,1442.4694 1553.6979,1440.3233 C 1552.0738,1438.1843 1551.2542,1435.6083 1551.2542,1432.6154 C 1551.2542,1430.552 1551.6286,1428.6493 1552.3715,1426.9072 C 1553.1215,1425.1639 1554.2057,1423.8162 1555.6219,1422.8654 C 1557.038,1421.9206 1558.7045,1421.441 1560.6144,1421.441 C 1563.1632,1421.441 1565.2679,1422.4757 1566.9203,1424.5391 L 1566.9203,1421.9347 L 1570.3018,1421.9347 L 1570.3018,1440.6079 C 1570.3018,1443.9693 1569.9546,1446.3575 1569.2742,1447.7607 C 1568.5868,1449.1627 1567.5038,1450.2741 1566.0179,1451.0867 C 1564.5309,1451.8993 1562.7049,1452.3091 1560.5317,1452.3091 C 1557.9545,1452.3091 1555.8723,1451.7256 1554.2884,1450.5658 C 1552.6986,1449.406 1551.9345,1447.6626 1551.99,1445.33 L 1551.99,1445.33 z M 1555.0172,1432.3509 C 1555.0172,1435.1844 1555.5806,1437.2537 1556.7121,1438.5529 C 1557.8376,1439.858 1559.2467,1440.5041 1560.9416,1440.5041 C 1562.6211,1440.5041 1564.0313,1439.858 1565.1699,1438.5659 C 1566.3085,1437.2678 1566.879,1435.2399 1566.879,1432.469 C 1566.879,1429.8233 1566.2955,1427.8308 1565.1215,1426.4903 C 1563.9475,1425.1497 1562.5314,1424.4765 1560.879,1424.4765 C 1559.2538,1424.4765 1557.8719,1425.1355 1556.7262,1426.4619 C 1555.5877,1427.7812 1555.0172,1429.7466 1555.0172,1432.3509 L 1555.0172,1432.3509 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path163" />
+
+   <path
+   d="M 1576.78,1443.54 L 1576.78,1439.366 L 1580.9528,1439.366 L 1580.9528,1443.54 C 1580.9528,1445.0742 1580.6824,1446.3109 1580.1402,1447.2558 C 1579.5922,1448.1924 1578.7312,1448.9223 1577.5572,1449.4432 L 1576.5367,1447.8735 C 1577.308,1447.5333 1577.8772,1447.0325 1578.2446,1446.3806 C 1578.6131,1445.7203 1578.8139,1444.7766 1578.8564,1443.54 L 1576.78,1443.54 L 1576.78,1443.54 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path165" />
+
+   <path
+   d="M 669.775,1440.26 L 670.30177,1443.4962 C 669.27421,1443.7112 668.35059,1443.8222 667.53799,1443.8222 C 666.20571,1443.8222 665.17697,1443.6143 664.44114,1443.1903 C 663.7124,1442.7734 663.19862,1442.2183 662.8998,1441.5309 C 662.60098,1440.8505 662.44862,1439.4061 662.44862,1437.2116 L 662.44862,1424.7805 L 659.76043,1424.7805 L 659.76043,1421.934 L 662.44862,1421.934 L 662.44862,1416.5801 L 666.0935,1414.3856 L 666.0935,1421.934 L 669.775,1421.934 L 669.775,1424.7805 L 666.0935,1424.7805 L 666.0935,1437.4124 C 666.0935,1438.4612 666.1561,1439.1285 666.2813,1439.4262 C 666.41358,1439.725 666.62145,1439.9612 666.91319,1440.1419 C 667.20492,1440.3155 667.62185,1440.4053 668.16398,1440.4053 C 668.57264,1440.4053 669.10768,1440.3569 669.775,1440.26 L 669.775,1440.26 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path167" />
+
+   <path
+   d="M 673.357,1443.54 L 673.357,1413.7148 L 677.01724,1413.7148 L 677.01724,1424.4156 C 678.72511,1422.4361 680.88535,1421.4428 683.4885,1421.4428 C 685.08653,1421.4428 686.47551,1421.7628 687.65543,1422.3947 C 688.83653,1423.0195 689.68338,1423.8947 690.19008,1425.0062 C 690.69677,1426.1164 690.95425,1427.7345 690.95425,1429.8463 L 690.95425,1443.54 L 687.28811,1443.54 L 687.28811,1429.8463 C 687.28811,1428.0191 686.89126,1426.6857 686.09992,1425.853 C 685.30858,1425.0192 684.18299,1424.5963 682.7326,1424.5963 C 681.64835,1424.5963 680.62788,1424.881 679.67,1425.4432 C 678.71095,1426.0054 678.03063,1426.7695 677.62787,1427.7345 C 677.21803,1428.6936 677.01724,1430.0258 677.01724,1431.7207 L 677.01724,1443.54 L 673.357,1443.54 L 673.357,1443.54 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path169" />
+
+   <path
+   d="M 711.315,1436.58 L 715.09925,1437.0454 C 714.50161,1439.2599 713.39846,1440.9749 711.78744,1442.1973 C 710.16933,1443.4127 708.10594,1444.0245 705.59964,1444.0245 C 702.44019,1444.0245 699.93271,1443.0513 698.08547,1441.1072 C 696.23114,1439.1631 695.30752,1436.4336 695.30752,1432.9198 C 695.30752,1429.2808 696.24532,1426.4615 698.11382,1424.4548 C 699.98823,1422.4481 702.41185,1421.4406 705.39768,1421.4406 C 708.28666,1421.4406 710.64768,1422.4269 712.47485,1424.3922 C 714.30792,1426.3576 715.22446,1429.1284 715.22446,1432.6906 C 715.22446,1432.9127 715.21737,1433.2399 715.2032,1433.6698 L 699.093,1433.6698 C 699.22528,1436.045 699.89851,1437.8639 701.10678,1439.1217 C 702.31505,1440.3855 703.81505,1441.0174 705.62095,1441.0174 C 706.96032,1441.0174 708.10599,1440.6631 709.05796,1439.9544 C 710.00875,1439.2529 710.75875,1438.1284 711.31505,1436.58 L 711.315,1436.58 z M 699.2937,1430.6568 L 711.3563,1430.6568 C 711.19685,1428.8438 710.7315,1427.4761 709.97441,1426.5725 C 708.80748,1425.1635 707.29449,1424.4548 705.44016,1424.4548 C 703.75945,1424.4548 702.34213,1425.017 701.19646,1426.1426 C 700.05079,1427.267 699.4189,1428.7741 699.2937,1430.6568 L 699.2937,1430.6568 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path171" />
+
+   <path
+   d="M 735.266,1443.54 L 728.65537,1421.9365 L 732.43962,1421.9365 L 735.87781,1434.4078 L 737.15458,1439.0472 C 737.21009,1438.811 737.58568,1437.3251 738.27308,1434.5885 L 741.71009,1421.9365 L 745.47426,1421.9365 L 748.71048,1434.4633 L 749.79355,1438.596 L 751.03016,1434.422 L 754.73055,1421.9366 L 758.29394,1421.9366 L 751.53685,1443.5401 L 747.73842,1443.5401 L 744.30023,1430.6023 L 743.46047,1426.9149 L 739.09275,1443.5401 L 735.26598,1443.5401 L 735.266,1443.54 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path173" />
+
+   <path
+   d="M 776.154,1436.58 L 779.93825,1437.0454 C 779.34061,1439.2599 778.23746,1440.9749 776.62644,1442.1973 C 775.00833,1443.4127 772.94494,1444.0245 770.43864,1444.0245 C 767.27919,1444.0245 764.77171,1443.0513 762.92447,1441.1072 C 761.07014,1439.1631 760.14652,1436.4336 760.14652,1432.9198 C 760.14652,1429.2808 761.08431,1426.4615 762.95282,1424.4548 C 764.82723,1422.4481 767.25085,1421.4406 770.23668,1421.4406 C 773.12566,1421.4406 775.48668,1422.4269 777.31385,1424.3922 C 779.14692,1426.3576 780.06346,1429.1284 780.06346,1432.6906 C 780.06346,1432.9127 780.05637,1433.2399 780.0422,1433.6698 L 763.932,1433.6698 C 764.06428,1436.045 764.73751,1437.8639 765.94578,1439.1217 C 767.15405,1440.3855 768.65405,1441.0174 770.45995,1441.0174 C 771.79932,1441.0174 772.94499,1440.6631 773.89696,1439.9544 C 774.84775,1439.2529 775.59775,1438.1284 776.15405,1436.58 L 776.154,1436.58 z M 764.1327,1430.6568 L 776.1953,1430.6568 C 776.03585,1428.8438 775.5705,1427.4761 774.81341,1426.5725 C 773.64648,1425.1635 772.13349,1424.4548 770.27916,1424.4548 C 768.59845,1424.4548 767.18113,1425.017 766.03546,1426.1426 C 764.88979,1427.267 764.2579,1428.7741 764.1327,1430.6568 L 764.1327,1430.6568 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path175" />
+
+   <path
+   d="M 787.918,1443.54 L 784.52233,1443.54 L 784.52233,1413.7148 L 788.18139,1413.7148 L 788.18139,1424.353 C 789.72982,1422.416 791.70226,1421.4428 794.09753,1421.4428 C 795.43099,1421.4428 796.68887,1421.7144 797.87588,1422.2483 C 799.06289,1422.7833 800.03494,1423.5404 800.80619,1424.5054 C 801.57036,1425.4774 802.17391,1426.6443 802.60501,1428.0191 C 803.04202,1429.388 803.25816,1430.8526 803.25816,1432.4081 C 803.25816,1436.1168 802.34044,1438.9774 800.50737,1440.9983 C 798.68139,1443.0192 796.47981,1444.0266 793.918,1444.0266 C 791.36918,1444.0266 789.36957,1442.9636 787.918,1440.8318 L 787.918,1443.54 L 787.918,1443.54 z M 787.87548,1432.5746 C 787.87548,1435.1648 788.22981,1437.0333 788.93139,1438.186 C 790.08415,1440.0746 791.64674,1441.0195 793.6121,1441.0195 C 795.21604,1441.0195 796.59793,1440.325 797.76486,1438.9289 C 798.93179,1437.54 799.51407,1435.4707 799.51407,1432.714 C 799.51407,1429.8947 798.95187,1427.8112 797.83454,1426.4707 C 796.71604,1425.1301 795.36249,1424.4569 793.77863,1424.4569 C 792.17469,1424.4569 790.7928,1425.1514 789.62587,1426.5403 C 788.45894,1427.9293 787.87548,1429.9431 787.87548,1432.5746 L 787.87548,1432.5746 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path177" />
+
+   <path
+   d="M 817.827,1437.09 L 821.44472,1436.5207 C 821.64551,1437.9723 822.21598,1439.0825 823.14551,1439.8609 C 824.06913,1440.6309 825.36834,1441.0207 827.04197,1441.0207 C 828.72268,1441.0207 829.97228,1440.6735 830.78488,1439.9931 C 831.59748,1439.3057 832.00732,1438.4991 832.00732,1437.5825 C 832.00732,1436.7498 831.6459,1436.1038 830.92307,1435.6242 C 830.42346,1435.2983 829.17386,1434.8884 827.18016,1434.3888 C 824.50024,1433.7085 822.63173,1433.125 821.59709,1432.6242 C 820.56244,1432.1317 819.77111,1431.4443 819.23607,1430.5691 C 818.70221,1429.6939 818.43056,1428.729 818.43056,1427.6731 C 818.43056,1426.7081 818.6526,1425.8199 819.09788,1425.0002 C 819.53489,1424.1735 820.13961,1423.4931 820.89552,1422.951 C 821.46599,1422.5353 822.24316,1422.1739 823.22229,1421.8821 C 824.20851,1421.5904 825.26442,1421.4439 826.38883,1421.4439 C 828.08371,1421.4439 829.56954,1421.6943 830.85458,1422.1809 C 832.13844,1422.6664 833.08332,1423.3266 833.69395,1424.1593 C 834.30576,1425.0002 834.72269,1426.1105 834.95182,1427.5065 L 831.37544,1428.0002 C 831.20891,1426.8888 830.73647,1426.0207 829.95812,1425.3959 C 829.18096,1424.7711 828.07662,1424.4581 826.6534,1424.4581 C 824.97269,1424.4581 823.77151,1424.7357 823.05576,1425.292 C 822.33411,1425.8471 821.97269,1426.5002 821.97269,1427.2432 C 821.97269,1427.7215 822.12505,1428.1455 822.42387,1428.5282 C 822.72269,1428.9239 823.18805,1429.2428 823.82702,1429.5073 C 824.19435,1429.6384 825.27151,1429.9514 827.06206,1430.4369 C 829.65222,1431.1313 831.45812,1431.6947 832.4786,1432.1388 C 833.50734,1432.5758 834.31285,1433.2219 834.89632,1434.0617 C 835.47861,1434.9026 835.77034,1435.9443 835.77034,1437.1939 C 835.77034,1438.4164 835.4101,1439.562 834.70144,1440.6451 C 833.98569,1441.7223 832.95813,1442.555 831.61758,1443.1455 C 830.27821,1443.7361 828.75695,1444.0278 827.06207,1444.0278 C 824.24987,1444.0278 822.11089,1443.4443 820.63924,1442.2774 C 819.16641,1441.1105 818.22979,1439.3813 817.82704,1437.09 L 817.827,1437.09 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path179" />
+
+   <path
+   d="M 840.138,1417.93 L 840.138,1413.7158 L 843.80414,1413.7158 L 843.80414,1417.93 L 840.138,1417.93 z M 840.138,1443.541 L 840.138,1421.9375 L 843.80414,1421.9375 L 843.80414,1443.541 L 840.138,1443.541 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path181" />
+
+   <path
+   d="M 857.374,1440.26 L 857.90077,1443.4962 C 856.87321,1443.7112 855.94959,1443.8222 855.13699,1443.8222 C 853.80471,1443.8222 852.77597,1443.6143 852.04014,1443.1903 C 851.3114,1442.7734 850.79762,1442.2183 850.4988,1441.5309 C 850.19998,1440.8505 850.04762,1439.4061 850.04762,1437.2116 L 850.04762,1424.7805 L 847.35943,1424.7805 L 847.35943,1421.934 L 850.04762,1421.934 L 850.04762,1416.5801 L 853.6925,1414.3856 L 853.6925,1421.934 L 857.374,1421.934 L 857.374,1424.7805 L 853.6925,1424.7805 L 853.6925,1437.4124 C 853.6925,1438.4612 853.7551,1439.1285 853.8803,1439.4262 C 854.01258,1439.725 854.22045,1439.9612 854.51219,1440.1419 C 854.80392,1440.3155 855.22085,1440.4053 855.76298,1440.4053 C 856.17164,1440.4053 856.70668,1440.3569 857.374,1440.26 L 857.374,1440.26 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path183" />
+
+   <path
+   d="M 875.741,1436.58 L 879.52525,1437.0454 C 878.92761,1439.2599 877.82446,1440.9749 876.21344,1442.1973 C 874.59533,1443.4127 872.53194,1444.0245 870.02564,1444.0245 C 866.86619,1444.0245 864.35871,1443.0513 862.51147,1441.1072 C 860.65714,1439.1631 859.73352,1436.4336 859.73352,1432.9198 C 859.73352,1429.2808 860.67131,1426.4615 862.53982,1424.4548 C 864.41423,1422.4481 866.83785,1421.4406 869.82368,1421.4406 C 872.71266,1421.4406 875.07368,1422.4269 876.90085,1424.3922 C 878.73392,1426.3576 879.65046,1429.1284 879.65046,1432.6906 C 879.65046,1432.9127 879.64337,1433.2399 879.6292,1433.6698 L 863.519,1433.6698 C 863.65128,1436.045 864.32451,1437.8639 865.53278,1439.1217 C 866.74105,1440.3855 868.24105,1441.0174 870.04695,1441.0174 C 871.38632,1441.0174 872.53199,1440.6631 873.48396,1439.9544 C 874.43475,1439.2529 875.18475,1438.1284 875.74105,1436.58 L 875.741,1436.58 z M 863.7197,1430.6568 L 875.7823,1430.6568 C 875.62285,1428.8438 875.1575,1427.4761 874.40041,1426.5725 C 873.23348,1425.1635 871.72049,1424.4548 869.86616,1424.4548 C 868.18545,1424.4548 866.76813,1425.017 865.62246,1426.1426 C 864.47679,1427.267 863.8449,1428.7741 863.7197,1430.6568 L 863.7197,1430.6568 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path185" />
+
+   <path
+   d="M 899.692,1443.54 L 893.08137,1421.9365 L 896.86562,1421.9365 L 900.30381,1434.4078 L 901.58058,1439.0472 C 901.63609,1438.811 902.01168,1437.3251 902.69908,1434.5885 L 906.13609,1421.9365 L 909.90026,1421.9365 L 913.13648,1434.4633 L 914.21955,1438.596 L 915.45616,1434.422 L 919.15655,1421.9366 L 922.71994,1421.9366 L 915.96285,1443.5401 L 912.16442,1443.5401 L 908.72623,1430.6023 L 907.88647,1426.9149 L 903.51875,1443.5401 L 899.69198,1443.5401 L 899.692,1443.54 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path187" />
+
+   <polygon
+   points="923.046,1444.05 931.691,1413.21 934.622,1413.21 925.997,1444.05 923.046,1444.05 "
+   style="fill:#000000;fill-rule:nonzero"
+   id="polygon189" />
+
+   <path
+   d="M 936.698,1445.33 L 940.2602,1445.858 C 940.40666,1446.9552 940.8224,1447.7536 941.49681,1448.2603 C 942.40626,1448.9335 943.64878,1449.2737 945.21846,1449.2737 C 946.92043,1449.2737 948.22555,1448.9335 949.14917,1448.2603 C 950.07279,1447.58 950.69051,1446.628 951.01649,1445.4127 C 951.21137,1444.6627 951.29523,1443.1013 951.28106,1440.7119 C 949.68421,1442.5934 947.69051,1443.5383 945.30232,1443.5383 C 942.32949,1443.5383 940.03106,1442.4694 938.40586,1440.3233 C 936.78184,1438.1843 935.96216,1435.6083 935.96216,1432.6154 C 935.96216,1430.552 936.33657,1428.6493 937.07948,1426.9072 C 937.82948,1425.1639 938.91373,1423.8162 940.32987,1422.8654 C 941.74601,1421.9206 943.41255,1421.441 945.32239,1421.441 C 947.87121,1421.441 949.97593,1422.4757 951.6283,1424.5391 L 951.6283,1421.9347 L 955.0098,1421.9347 L 955.0098,1440.6079 C 955.0098,1443.9693 954.66255,1446.3575 953.98224,1447.7607 C 953.29483,1449.1627 952.21177,1450.2741 950.72594,1451.0867 C 949.23893,1451.8993 947.41295,1452.3091 945.23972,1452.3091 C 942.66255,1452.3091 940.58027,1451.7256 938.99641,1450.5658 C 937.40665,1449.406 936.64247,1447.6626 936.69798,1445.33 L 936.698,1445.33 z M 939.72517,1432.3509 C 939.72517,1435.1844 940.28856,1437.2537 941.42005,1438.5529 C 942.54564,1439.858 943.9547,1440.5041 945.64958,1440.5041 C 947.32911,1440.5041 948.73934,1439.858 949.87793,1438.5659 C 951.01651,1437.2678 951.58699,1435.2399 951.58699,1432.469 C 951.58699,1429.8233 951.00352,1427.8308 949.82951,1426.4903 C 948.65549,1425.1497 947.23935,1424.4765 945.58699,1424.4765 C 943.96179,1424.4765 942.5799,1425.1355 941.43423,1426.4619 C 940.29565,1427.7812 939.72517,1429.7466 939.72517,1432.3509 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path191" />
+
+   <path
+   d="M 960.503,1443.54 L 960.503,1421.9365 L 963.79473,1421.9365 L 963.79473,1425.207 C 964.63449,1423.6798 965.41284,1422.6652 966.12741,1422.1798 C 966.83607,1421.6932 967.62032,1421.4428 968.47544,1421.4428 C 969.71087,1421.4428 970.96166,1421.8396 972.23843,1422.6239 L 970.97465,1426.0267 C 970.08646,1425.4916 969.19,1425.2282 968.29473,1425.2282 C 967.48922,1425.2282 966.77347,1425.4715 966.13449,1425.9499 C 965.49551,1426.4365 965.04433,1427.1026 964.77386,1427.9566 C 964.36402,1429.2558 964.16323,1430.679 964.16323,1432.2274 L 964.16323,1443.54 L 960.50299,1443.54 L 960.503,1443.54 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path193" />
+
+  </g>
+    <g
+       transform="matrix(0.317715,0,0,0.317715,415.2513,-451.5858)"
+       style="fill-rule:evenodd"
+       id="_19509096">
+   <path
+   d="M 75.3272,2384.22 L 75.853972,2387.4562 C 74.826412,2387.6712 73.902792,2387.7822 73.090192,2387.7822 C 71.757912,2387.7822 70.729172,2387.5743 69.993342,2387.1503 C 69.264602,2386.7334 68.750822,2386.1783 68.452002,2385.4909 C 68.153183,2384.8105 68.000821,2383.3661 68.000821,2381.1716 L 68.000821,2368.7405 L 65.312631,2368.7405 L 65.312631,2365.894 L 68.000821,2365.894 L 68.000821,2360.5401 L 71.645701,2358.3456 L 71.645701,2365.894 L 75.327201,2365.894 L 75.327201,2368.7405 L 71.645701,2368.7405 L 71.645701,2381.3724 C 71.645701,2382.4212 71.708299,2383.0885 71.833496,2383.3862 C 71.965779,2383.685 72.173653,2383.9212 72.465386,2384.1019 C 72.757118,2384.2755 73.174047,2384.3653 73.716176,2384.3653 C 74.124837,2384.3653 74.659877,2384.3169 75.327196,2384.22 L 75.3272,2384.22 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="_19509000" />
+
+   <path
+   d="M 93.6945,2380.54 L 97.47875,2381.0054 C 96.881112,2383.2199 95.77796,2384.9349 94.16694,2386.1573 C 92.54883,2387.3727 90.48544,2387.9845 87.97914,2387.9845 C 84.81969,2387.9845 82.31221,2387.0113 80.46497,2385.0672 C 78.61064,2383.1231 77.68702,2380.3936 77.68702,2376.8798 C 77.68702,2373.2408 78.624815,2370.4215 80.49332,2368.4148 C 82.36773,2366.4081 84.79135,2365.4006 87.77718,2365.4006 C 90.66616,2365.4006 93.02718,2366.3869 94.85435,2368.3522 C 96.68742,2370.3176 97.60396,2373.0884 97.60396,2376.6506 C 97.60396,2376.8727 97.596873,2377.1999 97.5827,2377.6298 L 81.4725,2377.6298 C 81.604783,2380.005 82.278012,2381.8239 83.48628,2383.0817 C 84.69455,2384.3455 86.19455,2384.9774 88.00045,2384.9774 C 89.33982,2384.9774 90.48549,2384.6231 91.43746,2383.9144 C 92.388247,2383.2129 93.13825,2382.0884 93.69455,2380.54 L 93.6945,2380.54 z M 81.6732,2374.6168 L 93.7358,2374.6168 C 93.576351,2372.8038 93.110997,2371.4361 92.35391,2370.5325 C 91.18698,2369.1235 89.67399,2368.4148 87.81966,2368.4148 C 86.13895,2368.4148 84.72163,2368.977 83.57596,2370.1026 C 82.43029,2371.227 81.7984,2372.7341 81.6732,2374.6168 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path197" />
+
+   <path
+   d="M 99.639,2387.5 L 107.53467,2376.2713 L 100.22837,2365.8965 L 104.80514,2365.8965 L 108.12404,2370.9587 C 108.74294,2371.9237 109.24963,2372.7292 109.62404,2373.3823 C 110.22168,2372.487 110.77089,2371.6945 111.27758,2371 L 114.91656,2365.8965 L 119.29136,2365.8965 L 111.82561,2376.0693 L 119.86065,2387.5 L 115.36774,2387.5 L 110.93034,2380.7854 L 109.74924,2378.9724 L 104.07641,2387.5 L 99.63901,2387.5 L 99.639,2387.5 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path199" />
+
+   <path
+   d="M 130.909,2384.22 L 131.43577,2387.4562 C 130.40821,2387.6712 129.48459,2387.7822 128.67199,2387.7822 C 127.33971,2387.7822 126.31097,2387.5743 125.57514,2387.1503 C 124.8464,2386.7334 124.33262,2386.1783 124.0338,2385.4909 C 123.73498,2384.8105 123.58262,2383.3661 123.58262,2381.1716 L 123.58262,2368.7405 L 120.89443,2368.7405 L 120.89443,2365.894 L 123.58262,2365.894 L 123.58262,2360.5401 L 127.2275,2358.3456 L 127.2275,2365.894 L 130.909,2365.894 L 130.909,2368.7405 L 127.2275,2368.7405 L 127.2275,2381.3724 C 127.2275,2382.4212 127.2901,2383.0885 127.4153,2383.3862 C 127.54758,2383.685 127.75545,2383.9212 128.04719,2384.1019 C 128.33892,2384.2755 128.75585,2384.3653 129.29798,2384.3653 C 129.70664,2384.3653 130.24168,2384.3169 130.909,2384.22 L 130.909,2384.22 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path201" />
+
+   <path
+   d="M 146.067,2395.78 L 146.067,2365.8993 L 149.40007,2365.8993 L 149.40007,2368.7044 C 150.1855,2367.6072 151.07369,2366.7816 152.067,2366.2324 C 153.05322,2365.6843 154.2544,2365.4056 155.66464,2365.4056 C 157.51188,2365.4056 159.13708,2365.8851 160.54614,2366.83 C 161.96228,2367.7808 163.02527,2369.1213 163.74102,2370.8505 C 164.46267,2372.5796 164.82409,2374.4753 164.82409,2376.5375 C 164.82409,2378.7461 164.42842,2380.7387 163.63,2382.5103 C 162.83748,2384.2808 161.68472,2385.6343 160.17173,2386.5792 C 158.65756,2387.517 157.06661,2387.9895 155.40008,2387.9895 C 154.17882,2387.9895 153.08748,2387.732 152.11543,2387.2182 C 151.14338,2386.7044 150.35204,2386.0513 149.72724,2385.267 L 149.72724,2395.78 L 146.067,2395.78 L 146.067,2395.78 z M 149.37999,2376.8221 C 149.37999,2379.6001 149.9422,2381.6552 151.06779,2382.9886 C 152.1922,2384.315 153.55992,2384.9823 155.15795,2384.9823 C 156.78197,2384.9823 158.17803,2384.2949 159.33787,2382.9131 C 160.49771,2381.5383 161.08118,2379.4064 161.08118,2376.5174 C 161.08118,2373.7595 160.51189,2371.7044 159.37921,2370.3296 C 158.24771,2368.9619 156.89299,2368.2745 155.32449,2368.2745 C 153.76189,2368.2745 152.38,2369.0032 151.17882,2370.4619 C 149.97646,2371.9193 149.38,2374.0453 149.38,2376.8221 L 149.37999,2376.8221 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path203" />
+
+   <path
+   d="M 169.199,2387.5 L 169.199,2365.8965 L 172.49073,2365.8965 L 172.49073,2369.167 C 173.33049,2367.6398 174.10884,2366.6252 174.82341,2366.1398 C 175.53207,2365.6532 176.31632,2365.4028 177.17144,2365.4028 C 178.40687,2365.4028 179.65766,2365.7996 180.93443,2366.5839 L 179.67065,2369.9867 C 178.78246,2369.4516 177.886,2369.1882 176.99073,2369.1882 C 176.18522,2369.1882 175.46947,2369.4315 174.83049,2369.9099 C 174.19151,2370.3965 173.74033,2371.0626 173.46986,2371.9166 C 173.06002,2373.2158 172.85923,2374.639 172.85923,2376.1874 L 172.85923,2387.5 L 169.19899,2387.5 L 169.199,2387.5 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path205" />
+
+   <path
+   d="M 181.747,2376.69 C 181.747,2372.6908 182.85842,2369.725 185.08716,2367.8022 C 186.94149,2366.2042 189.20566,2365.3987 191.8785,2365.3987 C 194.85133,2365.3987 197.28086,2366.3719 199.16354,2368.3231 C 201.05212,2370.2672 201.98992,2372.9542 201.98992,2376.3853 C 201.98992,2379.1691 201.57299,2381.3577 200.73913,2382.9475 C 199.90645,2384.5443 198.6911,2385.7809 197.10133,2386.662 C 195.5033,2387.5443 193.76708,2387.9825 191.8785,2387.9825 C 188.85842,2387.9825 186.41354,2387.0164 184.54504,2385.0723 C 182.67772,2383.1353 181.74701,2380.3431 181.74701,2376.69 L 181.747,2376.69 z M 185.51117,2376.69 C 185.51117,2379.4609 186.11471,2381.5313 187.32298,2382.9061 C 188.53125,2384.288 190.05251,2384.9754 191.87849,2384.9754 C 193.69857,2384.9754 195.21156,2384.2809 196.41983,2382.8991 C 197.62219,2381.5172 198.22574,2379.4054 198.22574,2376.5731 C 198.22574,2373.8991 197.6222,2371.8711 196.40684,2370.4963 C 195.19149,2369.1215 193.6844,2368.4341 191.87849,2368.4341 C 190.05251,2368.4341 188.53125,2369.1215 187.32298,2370.4892 C 186.11471,2371.8569 185.51117,2373.9262 185.51117,2376.69 L 185.51117,2376.69 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path207" />
+
+   <path
+   d="M 206.288,2395.78 L 206.288,2365.8993 L 209.62107,2365.8993 L 209.62107,2368.7044 C 210.4065,2367.6072 211.29469,2366.7816 212.288,2366.2324 C 213.27422,2365.6843 214.4754,2365.4056 215.88564,2365.4056 C 217.73288,2365.4056 219.35808,2365.8851 220.76714,2366.83 C 222.18328,2367.7808 223.24627,2369.1213 223.96202,2370.8505 C 224.68367,2372.5796 225.04509,2374.4753 225.04509,2376.5375 C 225.04509,2378.7461 224.64942,2380.7387 223.851,2382.5103 C 223.05848,2384.2808 221.90572,2385.6343 220.39273,2386.5792 C 218.87856,2387.517 217.28761,2387.9895 215.62108,2387.9895 C 214.39982,2387.9895 213.30848,2387.732 212.33643,2387.2182 C 211.36438,2386.7044 210.57304,2386.0513 209.94824,2385.267 L 209.94824,2395.78 L 206.288,2395.78 L 206.288,2395.78 z M 209.60099,2376.8221 C 209.60099,2379.6001 210.1632,2381.6552 211.28879,2382.9886 C 212.4132,2384.315 213.78092,2384.9823 215.37895,2384.9823 C 217.00297,2384.9823 218.39903,2384.2949 219.55887,2382.9131 C 220.71871,2381.5383 221.30218,2379.4064 221.30218,2376.5174 C 221.30218,2373.7595 220.73289,2371.7044 219.60021,2370.3296 C 218.46871,2368.9619 217.11399,2368.2745 215.54549,2368.2745 C 213.98289,2368.2745 212.601,2369.0032 211.39982,2370.4619 C 210.19746,2371.9193 209.601,2374.0453 209.601,2376.8221 L 209.60099,2376.8221 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path209" />
+
+   <path
+   d="M 228.093,2376.69 C 228.093,2372.6908 229.20442,2369.725 231.43316,2367.8022 C 233.28749,2366.2042 235.55166,2365.3987 238.2245,2365.3987 C 241.19733,2365.3987 243.62686,2366.3719 245.50954,2368.3231 C 247.39812,2370.2672 248.33592,2372.9542 248.33592,2376.3853 C 248.33592,2379.1691 247.91899,2381.3577 247.08513,2382.9475 C 246.25245,2384.5443 245.0371,2385.7809 243.44733,2386.662 C 241.8493,2387.5443 240.11308,2387.9825 238.2245,2387.9825 C 235.20442,2387.9825 232.75954,2387.0164 230.89104,2385.0723 C 229.02372,2383.1353 228.09301,2380.3431 228.09301,2376.69 L 228.093,2376.69 z M 231.85717,2376.69 C 231.85717,2379.4609 232.46071,2381.5313 233.66898,2382.9061 C 234.87725,2384.288 236.39851,2384.9754 238.22449,2384.9754 C 240.04457,2384.9754 241.55756,2384.2809 242.76583,2382.8991 C 243.96819,2381.5172 244.57174,2379.4054 244.57174,2376.5731 C 244.57174,2373.8991 243.9682,2371.8711 242.75284,2370.4963 C 241.53749,2369.1215 240.0304,2368.4341 238.22449,2368.4341 C 236.39851,2368.4341 234.87725,2369.1215 233.66898,2370.4892 C 232.46071,2371.8569 231.85717,2373.9262 231.85717,2376.69 L 231.85717,2376.69 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path211" />
+
+   <path
+   d="M 252.593,2387.5 L 252.593,2365.8965 L 255.88473,2365.8965 L 255.88473,2369.167 C 256.72449,2367.6398 257.50284,2366.6252 258.21741,2366.1398 C 258.92607,2365.6532 259.71032,2365.4028 260.56544,2365.4028 C 261.80087,2365.4028 263.05166,2365.7996 264.32843,2366.5839 L 263.06465,2369.9867 C 262.17646,2369.4516 261.28,2369.1882 260.38473,2369.1882 C 259.57922,2369.1882 258.86347,2369.4315 258.22449,2369.9099 C 257.58551,2370.3965 257.13433,2371.0626 256.86386,2371.9166 C 256.45402,2373.2158 256.25323,2374.639 256.25323,2376.1874 L 256.25323,2387.5 L 252.59299,2387.5 L 252.593,2387.5 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path213" />
+
+   <path
+   d="M 274.502,2384.22 L 275.02877,2387.4562 C 274.00121,2387.6712 273.07759,2387.7822 272.26499,2387.7822 C 270.93271,2387.7822 269.90397,2387.5743 269.16814,2387.1503 C 268.4394,2386.7334 267.92562,2386.1783 267.6268,2385.4909 C 267.32798,2384.8105 267.17562,2383.3661 267.17562,2381.1716 L 267.17562,2368.7405 L 264.48743,2368.7405 L 264.48743,2365.894 L 267.17562,2365.894 L 267.17562,2360.5401 L 270.8205,2358.3456 L 270.8205,2365.894 L 274.502,2365.894 L 274.502,2368.7405 L 270.8205,2368.7405 L 270.8205,2381.3724 C 270.8205,2382.4212 270.8831,2383.0885 271.0083,2383.3862 C 271.14058,2383.685 271.34845,2383.9212 271.64019,2384.1019 C 271.93192,2384.2755 272.34885,2384.3653 272.89098,2384.3653 C 273.29964,2384.3653 273.83468,2384.3169 274.502,2384.22 L 274.502,2384.22 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path215" />
+
+   <path
+   d="M 278.099,2361.89 L 278.099,2357.6758 L 281.76514,2357.6758 L 281.76514,2361.89 L 278.099,2361.89 z M 278.099,2387.501 L 278.099,2365.8975 L 281.76514,2365.8975 L 281.76514,2387.501 L 278.099,2387.501 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path217" />
+
+   <path
+   d="M 285.973,2376.69 C 285.973,2372.6908 287.08442,2369.725 289.31316,2367.8022 C 291.16749,2366.2042 293.43166,2365.3987 296.1045,2365.3987 C 299.07733,2365.3987 301.50686,2366.3719 303.38954,2368.3231 C 305.27812,2370.2672 306.21592,2372.9542 306.21592,2376.3853 C 306.21592,2379.1691 305.79899,2381.3577 304.96513,2382.9475 C 304.13245,2384.5443 302.9171,2385.7809 301.32733,2386.662 C 299.7293,2387.5443 297.99308,2387.9825 296.1045,2387.9825 C 293.08442,2387.9825 290.63954,2387.0164 288.77104,2385.0723 C 286.90372,2383.1353 285.97301,2380.3431 285.97301,2376.69 L 285.973,2376.69 z M 289.73717,2376.69 C 289.73717,2379.4609 290.34071,2381.5313 291.54898,2382.9061 C 292.75725,2384.288 294.27851,2384.9754 296.10449,2384.9754 C 297.92457,2384.9754 299.43756,2384.2809 300.64583,2382.8991 C 301.84819,2381.5172 302.45174,2379.4054 302.45174,2376.5731 C 302.45174,2373.8991 301.8482,2371.8711 300.63284,2370.4963 C 299.41749,2369.1215 297.9104,2368.4341 296.10449,2368.4341 C 294.27851,2368.4341 292.75725,2369.1215 291.54898,2370.4892 C 290.34071,2371.8569 289.73717,2373.9262 289.73717,2376.69 L 289.73717,2376.69 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path219" />
+
+   <path
+   d="M 310.514,2387.5 L 310.514,2365.8965 L 313.80573,2365.8965 L 313.80573,2368.9662 C 315.39667,2366.591 317.68801,2365.4028 320.68093,2365.4028 C 321.98605,2365.4028 323.18014,2365.639 324.27148,2366.1044 C 325.36872,2366.5768 326.18014,2367.1874 326.72227,2367.9516 C 327.27148,2368.7087 327.64589,2369.6111 327.86794,2370.6528 C 328.00022,2371.3343 328.06991,2372.5213 328.06991,2374.2162 L 328.06991,2387.5001 L 324.40259,2387.5001 L 324.40259,2374.3544 C 324.40259,2372.8686 324.2644,2371.7501 323.97975,2371.0071 C 323.69511,2370.2713 323.18723,2369.6808 322.46558,2369.2438 C 321.73684,2368.7997 320.88881,2368.5764 319.90967,2368.5764 C 318.34707,2368.5764 317.0077,2369.0772 315.86794,2370.0634 C 314.73644,2371.0556 314.17424,2372.9312 314.17424,2375.702 L 314.17424,2387.5 L 310.514,2387.5 L 310.514,2387.5 z "
+   style="fill:#000000;fill-rule:nonzero"
+   id="path221" />
+
+  </g>
+    <path
+       d="M 88.126188,369.03622 C 88.126188,356.61906 103.01889,346.69059 127.84056,346.69059 C 152.66211,346.69059 167.55494,356.61906 167.55494,369.02307 L 167.55494,406.26181 C 167.55494,417.22297 158.65917,426.11874 147.698,426.11874 L 107.98331,426.11874 C 94.282043,426.11874 83.162145,437.23902 83.162145,450.94029 L 83.162145,468.32206 L 68.269064,468.30894 C 55.851904,468.30894 45.923056,453.41586 45.923056,428.59425 C 45.923056,403.7727 55.851904,388.87987 68.269064,388.87987 L 127.84063,388.893 L 127.84063,383.92876 L 88.126252,383.92876 L 88.126252,369.03606 L 88.126188,369.03622 z M 105.49443,359.10775 C 109.61173,359.10775 112.94774,362.44376 112.94774,366.54753 C 112.94774,370.66483 109.61173,374.00045 105.49443,374.00045 C 101.39066,374.00045 98.041501,370.66483 98.041501,366.54753 C 98.041501,362.44376 101.39063,359.10775 105.49443,359.10775 z "
+       style="fill:url(#pyBlue);fill-opacity:1;fill-rule:evenodd"
+       id="path223" />
+    <g
+       transform="matrix(0.317715,0,0,0.317715,-71.39343,-151.2348)"
+       style="fill-rule:evenodd"
+       id="_19487936">
+   <g
+   id="g226">
+    <path
+   d="M 1200.75,1694 C 1269.1252,1692.8331 1300.1244,1757.1665 1300.7079,1830.124 C 1300.7079,1894.4575 1268.5418,1954.749 1199.6259,1957.041 C 1171.459,1957.041 1147.3338,1948.4166 1123.792,1934.0827 L 1123.792,2082.8327 L 1082.418,2067.874 L 1083.0003,1737.625 C 1082.418,1737.625 1115.1676,1694.5833 1200.1683,1693.4163 L 1200.7506,1693.9998 L 1200.75,1694 z M 1190.4177,1927.166 C 1245.5421,1923.7491 1252.4586,1869.7503 1252.4586,1827.2495 C 1252.4586,1785.8743 1245.5421,1723.8745 1193.2925,1721.5835 C 1157.6669,1719.2496 1128.959,1735.9162 1123.2094,1741.667 L 1123.2094,1905.375 C 1137,1913.9581 1164.5834,1928.9167 1190.4177,1927.1663 L 1190.4177,1927.166 z "
+   style="fill:#6a6a6a"
+   id="_19487984" />
+
+    <path
+   d="M 1387.87,1869.75 L 1387.87,1693.416 L 1345.3704,1707.7912 L 1345.3704,1882.3742 C 1345.3704,1928.9155 1388.4535,1955.9155 1426.3704,1955.9155 C 1475.7452,1955.9155 1503.9121,1942.1238 1516.5369,1936.3742 C 1517.1204,1942.6659 1516.5369,1940.9569 1516.5369,1947.2899 C 1516.5369,1965.6655 1515.9534,1997.2493 1507.3704,2013.3324 C 1490.1204,2046.082 1444.1613,2050.6659 1411.9952,2055.2485 L 1418.9117,2081.665 C 1461.4113,2080.5406 1521.1197,2064.4575 1542.3697,2024.2481 C 1554.4536,2001.2485 1556.1614,1957.0398 1556.1614,1927.7485 L 1556.1614,1699.7485 L 1514.2453,1699.7485 L 1514.2453,1904.7905 C 1500.4536,1913.957 1475.2028,1926.6244 1452.7866,1927.1653 C 1415.4531,1927.7488 1387.8697,1907.6653 1387.8697,1869.1661 L 1387.8697,1869.7496 L 1387.87,1869.75 z "
+   style="fill:#6a6a6a"
+   id="_19488200" />
+
+    <path
+   d="M 1626.62,1726.75 L 1626.62,1891.583 C 1626.62,1934.6661 1659.9117,1959.9169 1715.6196,1954.7495 L 1715.6196,1932.9168 C 1686.3283,1931.7912 1668.5361,1923.7491 1668.5361,1890.416 L 1668.5361,1726.749 L 1715.6196,1726.749 L 1715.6196,1699.749 L 1668.5361,1699.749 L 1668.5361,1614.7498 L 1626.62,1629.6671 L 1626.62,1699.749 L 1597.8696,1699.749 L 1597.8696,1726.749 L 1626.62,1726.749 L 1626.62,1726.75 z "
+   style="fill:#6a6a6a"
+   id="_19488488" />
+
+    <path
+   d="M 1970.21,1951.29 L 1970.21,1776.123 C 1970.21,1732.4565 1940.3352,1697.999 1895.5431,1697.999 C 1861.6266,1697.999 1832.9187,1708.9147 1807.6691,1727.2903 L 1807.6691,1550.9993 L 1765.7104,1564.2087 L 1765.7104,1951.2897 L 1807.6691,1951.2897 L 1807.6691,1757.1647 C 1828.9183,1742.2474 1853.0435,1726.7478 1879.46,1726.7478 C 1913.3352,1726.7478 1927.7104,1760.0395 1927.7104,1789.3309 L 1927.7104,1951.2899 L 1970.21,1951.2899 L 1970.21,1951.29 z "
+   style="fill:#6a6a6a"
+   id="_126749024" />
+
+    <path
+   d="M 2007.75,1820.92 C 2007.75,1890.4196 2044.5,1955.92 2122.041,1956.462 C 2200.1662,1955.9199 2238.042,1890.4195 2238.042,1820.92 C 2237.4999,1753.1696 2195.0003,1694.003 2122.625,1693.42 C 2050.8341,1694.0035 2007.751,1753.1696 2007.751,1820.92 L 2007.75,1820.92 z M 2053.1244,1820.92 C 2053.1244,1775.5444 2064.5823,1725.5861 2122.0405,1722.1279 C 2176.0405,1725.0039 2192.1248,1775.5444 2192.1248,1820.92 C 2192.1248,1869.1704 2181.75,1928.92 2123.1661,1930.628 C 2069.2074,1930.0445 2053.7078,1869.1705 2053.7078,1820.92 L 2053.1243,1820.92 L 2053.1244,1820.92 z "
+   style="fill:#6a6a6a"
+   id="_126677456" />
+
+    <path
+   d="M 2477.04,1951.29 L 2477.04,1758.873 C 2477.04,1724.999 2450.0813,1703.1651 2419.6231,1696.2899 C 2389.7483,1689.4147 2361.6239,1695.1655 2340.957,1700.8738 C 2314.4991,1707.7903 2295.5814,1719.8317 2274.3322,1735.3313 L 2274.3322,1951.2903 L 2316.2483,1951.2903 L 2316.2483,1740.4993 C 2329.4566,1731.3327 2350.707,1721.5828 2373.0818,1720.9993 C 2409.8731,1720.4158 2435.1239,1741.6662 2435.1239,1780.1654 L 2435.1239,1951.2904 L 2477.04,1951.2904 L 2477.04,1951.29 z "
+   style="fill:#6a6a6a"
+   id="_126678176" />
+
+   </g>
+
+  </g>
+    <path
+       d="M 167.55462,488.16664 C 167.55462,500.58418 152.66192,510.51265 127.84025,510.51265 C 103.0187,510.51265 88.12587,500.58418 88.12587,488.17979 L 88.12587,450.94105 C 88.12587,439.97988 97.021636,431.08374 107.9828,431.08374 L 147.6975,431.08374 C 161.39877,431.08374 172.51904,419.96384 172.51904,406.26257 L 172.51904,388.8808 L 187.41174,388.89392 C 199.81575,388.89392 209.7446,403.787 209.7446,428.60829 C 209.7446,453.42984 199.81575,468.32298 187.41174,468.32298 L 127.84018,468.30986 L 127.84018,473.2741 L 167.55456,473.2741 L 167.55456,488.1668 L 167.55462,488.16664 z M 150.17323,498.0951 C 146.06946,498.0951 142.73345,494.75948 142.73345,490.65533 C 142.73345,486.53841 146.06946,483.2024 150.17323,483.2024 C 154.29015,483.2024 157.62615,486.53841 157.62615,490.65533 C 157.62615,494.75948 154.29015,498.0951 150.17323,498.0951 z "
+       style="fill:url(#pyYellow);fill-opacity:1;fill-rule:evenodd"
+       id="path234" />
+  </g>
+</svg>

Added: vendor/Python/current/PC/icons/source.xar
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/PC/icons/source.xar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/PC/icons.mak
===================================================================
--- vendor/Python/current/PC/icons.mak	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/icons.mak	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,9 @@
+python_icon.exe:	py.res empty.obj
+	link /out:python_icon.exe /machine:x86 /subsystem:windows py.res empty.obj
+
+py.res:	py.ico pyc.ico pycon.ico icons.rc
+	rc /fo py.res icons.rc
+
+empty.obj:	empty.c
+	cl /c empty.c
+

Added: vendor/Python/current/PC/icons.rc
===================================================================
--- vendor/Python/current/PC/icons.rc	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/icons.rc	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,4 @@
+101 ICON "py.ico"
+102 ICON "pyc.ico"
+103 ICON "pycon.ico"
+

Added: vendor/Python/current/PC/import_nt.c
===================================================================
--- vendor/Python/current/PC/import_nt.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/import_nt.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,86 @@
+/********************************************************************
+
+ import_nt.c 
+
+  Win32 specific import code.
+
+*/
+
+#include "Python.h"
+#include "osdefs.h"
+#include <windows.h>
+#include "importdl.h"
+#include "malloc.h" /* for alloca */
+
+/* a string loaded from the DLL at startup */
+extern const char *PyWin_DLLVersionString;
+
+FILE *PyWin_FindRegisteredModule(const char *moduleName,
+				 struct filedescr **ppFileDesc,
+				 char *pathBuf,
+				 Py_ssize_t pathLen)
+{
+	char *moduleKey;
+	const char keyPrefix[] = "Software\\Python\\PythonCore\\";
+	const char keySuffix[] = "\\Modules\\";
+#ifdef _DEBUG
+	/* In debugging builds, we _must_ have the debug version
+	 * registered.
+	 */
+	const char debugString[] = "\\Debug";
+#else
+	const char debugString[] = "";
+#endif
+	struct filedescr *fdp = NULL;
+	FILE *fp;
+	HKEY keyBase = HKEY_CURRENT_USER;
+	int modNameSize;
+	long regStat;
+
+	/* Calculate the size for the sprintf buffer.
+	 * Get the size of the chars only, plus 1 NULL.
+	 */
+	size_t bufSize = sizeof(keyPrefix)-1 +
+	                 strlen(PyWin_DLLVersionString) +
+	                 sizeof(keySuffix) +
+	                 strlen(moduleName) +
+	                 sizeof(debugString) - 1;
+	/* alloca == no free required, but memory only local to fn,
+	 * also no heap fragmentation!
+	 */
+	moduleKey = alloca(bufSize); 
+	PyOS_snprintf(moduleKey, bufSize,
+		      "Software\\Python\\PythonCore\\%s\\Modules\\%s%s",
+		      PyWin_DLLVersionString, moduleName, debugString);
+
+	assert(pathLen < INT_MAX);
+	modNameSize = (int)pathLen;
+	regStat = RegQueryValue(keyBase, moduleKey, pathBuf, &modNameSize);
+	if (regStat != ERROR_SUCCESS) {
+		/* No user setting - lookup in machine settings */
+		keyBase = HKEY_LOCAL_MACHINE;
+		/* be anal - failure may have reset size param */
+		modNameSize = (int)pathLen;
+		regStat = RegQueryValue(keyBase, moduleKey, 
+		                        pathBuf, &modNameSize);
+
+		if (regStat != ERROR_SUCCESS)
+			return NULL;
+	}
+	/* use the file extension to locate the type entry. */
+	for (fdp = _PyImport_Filetab; fdp->suffix != NULL; fdp++) {
+		size_t extLen = strlen(fdp->suffix);
+		assert(modNameSize >= 0); /* else cast to size_t is wrong */
+		if ((size_t)modNameSize > extLen &&
+		    strnicmp(pathBuf + ((size_t)modNameSize-extLen-1),
+		             fdp->suffix,
+		             extLen) == 0)
+			break;
+	}
+	if (fdp->suffix == NULL)
+		return NULL;
+	fp = fopen(pathBuf, fdp->mode);
+	if (fp != NULL)
+		*ppFileDesc = fdp;
+	return fp;
+}

Added: vendor/Python/current/PC/make_versioninfo.c
===================================================================
--- vendor/Python/current/PC/make_versioninfo.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/make_versioninfo.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,33 @@
+#include <stdio.h>
+#include "patchlevel.h"
+/*
+ * This program prints out an include file containing fields required to build
+ * the version info resource of pythonxx.dll because the resource compiler
+ * cannot do the arithmetic.
+ */
+/*
+ * FIELD3 is the third field of the version number.
+ * This is what we'd like FIELD3 to be:
+ *
+ * #define FIELD3 (PY_MICRO_VERSION*1000 + PY_RELEASE_LEVEL*10 + PY_RELEASE_SERIAL)
+ *
+ * but that neither gives an error nor comes anywhere close to working.
+ *
+ * For 2.4a0,
+ * PY_MICRO_VERSION = 0
+ * PY_RELEASE_LEVEL = 'alpha' = 0xa
+ * PY_RELEASE_SERIAL = 0
+ *
+ * gives FIELD3 = 0*1000 + 10*10 + 0 = 100
+ */
+int main(int argc, char **argv)
+{
+	printf("/* This file created by make_versioninfo.exe */\n");
+	printf("#define FIELD3 %d\n",
+		PY_MICRO_VERSION*1000 + PY_RELEASE_LEVEL*10 + PY_RELEASE_SERIAL);
+	printf("#define MS_DLL_ID \"%d.%d\"\n",
+	       PY_MAJOR_VERSION, PY_MINOR_VERSION);
+	printf("#define PYTHON_DLL_NAME \"python%d%d.dll\"\n",
+	       PY_MAJOR_VERSION, PY_MINOR_VERSION);
+	return 0;
+}

Added: vendor/Python/current/PC/msvcrtmodule.c
===================================================================
--- vendor/Python/current/PC/msvcrtmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/msvcrtmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,235 @@
+/*********************************************************
+
+	msvcrtmodule.c
+
+	A Python interface to the Microsoft Visual C Runtime
+	Library, providing access to those non-portable, but
+	still useful routines.
+
+	Only ever compiled with an MS compiler, so no attempt
+	has been made to avoid MS language extensions, etc...
+
+	This may only work on NT or 95...
+
+	Author: Mark Hammond and Guido van Rossum.
+	Maintenance: Guido van Rossum.
+
+***********************************************************/
+
+#include "Python.h"
+#include "malloc.h"
+#include <io.h>
+#include <conio.h>
+#include <sys/locking.h>
+
+// Force the malloc heap to clean itself up, and free unused blocks
+// back to the OS.  (According to the docs, only works on NT.)
+static PyObject *
+msvcrt_heapmin(PyObject *self, PyObject *args)
+{
+	if (!PyArg_ParseTuple(args, ":heapmin"))
+		return NULL;
+
+	if (_heapmin() != 0)
+		return PyErr_SetFromErrno(PyExc_IOError);
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+// Perform locking operations on a C runtime file descriptor.
+static PyObject *
+msvcrt_locking(PyObject *self, PyObject *args)
+{
+	int fd;
+	int mode;
+	long nbytes;
+	int err;
+
+	if (!PyArg_ParseTuple(args, "iil:locking", &fd, &mode, &nbytes))
+		return NULL;
+
+	Py_BEGIN_ALLOW_THREADS
+	err = _locking(fd, mode, nbytes);
+	Py_END_ALLOW_THREADS
+	if (err != 0)
+		return PyErr_SetFromErrno(PyExc_IOError);
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+// Set the file translation mode for a C runtime file descriptor.
+static PyObject *
+msvcrt_setmode(PyObject *self, PyObject *args)
+{
+	int fd;
+	int flags;
+	if (!PyArg_ParseTuple(args,"ii:setmode", &fd, &flags))
+		return NULL;
+
+	flags = _setmode(fd, flags);
+	if (flags == -1)
+		return PyErr_SetFromErrno(PyExc_IOError);
+
+	return PyInt_FromLong(flags);
+}
+
+// Convert an OS file handle to a C runtime file descriptor.
+static PyObject *
+msvcrt_open_osfhandle(PyObject *self, PyObject *args)
+{
+	long handle;
+	int flags;
+	int fd;
+
+	if (!PyArg_ParseTuple(args, "li:open_osfhandle", &handle, &flags))
+		return NULL;
+
+	fd = _open_osfhandle(handle, flags);
+	if (fd == -1)
+		return PyErr_SetFromErrno(PyExc_IOError);
+
+	return PyInt_FromLong(fd);
+}
+
+// Convert a C runtime file descriptor to an OS file handle.
+static PyObject *
+msvcrt_get_osfhandle(PyObject *self, PyObject *args)
+{
+	int fd;
+	Py_intptr_t handle;
+
+	if (!PyArg_ParseTuple(args,"i:get_osfhandle", &fd))
+		return NULL;
+
+	handle = _get_osfhandle(fd);
+	if (handle == -1)
+		return PyErr_SetFromErrno(PyExc_IOError);
+
+	/* technically 'handle' is not a pointer, but a integer as
+	   large as a pointer, Python's *VoidPtr interface is the
+	   most appropriate here */
+	return PyLong_FromVoidPtr((void*)handle);
+}
+
+/* Console I/O */
+
+static PyObject *
+msvcrt_kbhit(PyObject *self, PyObject *args)
+{
+	int ok;
+
+	if (!PyArg_ParseTuple(args, ":kbhit"))
+		return NULL;
+
+	ok = _kbhit();
+	return PyInt_FromLong(ok);
+}
+
+static PyObject *
+msvcrt_getch(PyObject *self, PyObject *args)
+{
+	int ch;
+	char s[1];
+
+	if (!PyArg_ParseTuple(args, ":getch"))
+		return NULL;
+
+	Py_BEGIN_ALLOW_THREADS
+	ch = _getch();
+	Py_END_ALLOW_THREADS
+	s[0] = ch;
+	return PyString_FromStringAndSize(s, 1);
+}
+
+static PyObject *
+msvcrt_getche(PyObject *self, PyObject *args)
+{
+	int ch;
+	char s[1];
+
+	if (!PyArg_ParseTuple(args, ":getche"))
+		return NULL;
+
+	Py_BEGIN_ALLOW_THREADS
+	ch = _getche();
+	Py_END_ALLOW_THREADS
+	s[0] = ch;
+	return PyString_FromStringAndSize(s, 1);
+}
+
+static PyObject *
+msvcrt_putch(PyObject *self, PyObject *args)
+{
+	char ch;
+
+	if (!PyArg_ParseTuple(args, "c:putch", &ch))
+		return NULL;
+
+	_putch(ch);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+msvcrt_ungetch(PyObject *self, PyObject *args)
+{
+	char ch;
+
+	if (!PyArg_ParseTuple(args, "c:ungetch", &ch))
+		return NULL;
+
+	if (_ungetch(ch) == EOF)
+		return PyErr_SetFromErrno(PyExc_IOError);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+
+static void
+insertint(PyObject *d, char *name, int value)
+{
+	PyObject *v = PyInt_FromLong((long) value);
+	if (v == NULL) {
+		/* Don't bother reporting this error */
+		PyErr_Clear();
+	}
+	else {
+		PyDict_SetItemString(d, name, v);
+		Py_DECREF(v);
+	}
+}
+
+
+/* List of functions exported by this module */
+static struct PyMethodDef msvcrt_functions[] = {
+	{"heapmin",		msvcrt_heapmin, METH_VARARGS},
+	{"locking",             msvcrt_locking, METH_VARARGS},
+	{"setmode",		msvcrt_setmode, METH_VARARGS},
+	{"open_osfhandle",	msvcrt_open_osfhandle, METH_VARARGS},
+	{"get_osfhandle",	msvcrt_get_osfhandle, METH_VARARGS},
+	{"kbhit",		msvcrt_kbhit, METH_VARARGS},
+	{"getch",		msvcrt_getch, METH_VARARGS},
+	{"getche",		msvcrt_getche, METH_VARARGS},
+	{"putch",		msvcrt_putch, METH_VARARGS},
+	{"ungetch",		msvcrt_ungetch, METH_VARARGS},
+	{NULL,			NULL}
+};
+
+PyMODINIT_FUNC
+initmsvcrt(void)
+{
+	PyObject *d;
+	PyObject *m = Py_InitModule("msvcrt", msvcrt_functions);
+	if (m == NULL)
+		return;
+	d = PyModule_GetDict(m);
+
+	/* constants for the locking() function's mode argument */
+	insertint(d, "LK_LOCK", _LK_LOCK);
+	insertint(d, "LK_NBLCK", _LK_NBLCK);
+	insertint(d, "LK_NBRLCK", _LK_NBRLCK);
+	insertint(d, "LK_RLCK", _LK_RLCK);
+	insertint(d, "LK_UNLCK", _LK_UNLCK);
+}


Property changes on: vendor/Python/current/PC/msvcrtmodule.c
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/PC/os2emx/README.os2emx
===================================================================
--- vendor/Python/current/PC/os2emx/README.os2emx	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/os2emx/README.os2emx	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,701 @@
+This is a port of Python 2.5 to OS/2 using the EMX development tools
+=========================================================================
+
+What's new since the previous release
+-------------------------------------
+
+Another day, another version...
+
+
+Licenses and info about Python and EMX
+--------------------------------------
+
+Please read the file README.Python-2.5 included in this package for 
+information about Python 2.5.  This file is the README file from the 
+Python 2.5 source distribution available via http://www.python.org/ 
+and its mirrors.  The file LICENCE.Python-2.5 is the text of the Licence 
+from the Python 2.5 source distribution.
+
+Note that the EMX package that this package depends on is released under 
+the GNU General Public Licence.  Please refer to the documentation 
+accompanying the EMX Runtime libraries for more information about the 
+implications of this.  A copy of version 2 of the GPL is included as the 
+file COPYING.gpl2.
+
+Readline and GDBM are covered by the GNU General Public Licence.  I think 
+Eberhard Mattes' porting changes to BSD DB v1.85 are also GPL'ed (BSD DB 
+itself is BSD Licenced).  ncurses and expat appear to be covered by MIT 
+style licences - please refer to the source distributions for more detail.  
+zlib is distributable under a very free license.  GNU UFC is under the 
+GNU LGPL (see file COPYING.lib).
+
+My patches to the Python-2.x source distributions, and any other packages 
+used in this port, are placed in the public domain.
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the author be held liable for any damages arising from the 
+use of the software.
+
+I do hope however that it proves useful to someone.
+
+
+Other ports
+-----------
+
+There have been ports of previous versions of Python to OS/2.
+
+The best known would be that by Jeff Rush, most recently of version 
+1.5.2.  Jeff used IBM's Visual Age C++ (v3) for his ports, and his 
+patches have been included in the Python 2.5 source distribution.
+
+Andy Zabolotny implemented a port of Python v1.5.2 using the EMX 
+development tools.  His patches against the Python v1.5.2 source 
+distribution have become the core of this port, and without his efforts 
+this port wouldn't exist.  Andy's port also appears to have been 
+compiled with his port of gcc 2.95.2 to EMX, which I have but have 
+chosen not to use for the binary distribution of this port (see item 16 
+of the "YOU HAVE BEEN WARNED" section below).
+
+It is possible to have these earlier ports still usable after installing 
+this port - see the README.os2emx.multiple_versions file, contributed by
+Dr David Mertz, for a suggested approach to achieving this.
+
+
+Software requirements
+---------------------
+
+This package requires the EMX Runtime package, available from the 
+Hobbes (http://hobbes.nmsu.edu/) and LEO (http://archiv.leo.org/) 
+archives of OS/2 software.  I have used EMX version 0.9d fix04 in 
+developing this port.
+
+My development system is running OS/2 v4 with fixpack 12.
+
+3rd party software which has been linked into dynamically loaded modules:
+- ncurses      (see http://dickey.his.com/ for more info, v5.2)
+- GNU Readline (Kai Uwe Rommel's port available from Hobbes or LEO, v2.1)
+- GNU GDBM     (Kai Uwe Rommel's port available from Hobbes or LEO, v1.7.3)
+- zlib         (derived from Hung-Chi Chu's port of v1.1.3, v1.1.4)
+- expat        (distributed with Python, v1.95.6)
+- GNU UFC      (Kai Uwe Rommel's port available from LEO, v2.0.4)
+
+
+About this port
+---------------
+
+I have attempted to make this port as complete and functional as I can, 
+notwithstanding the issues in the "YOU HAVE BEEN WARNED" section below.
+
+Core components:
+
+Python.exe is linked as an a.out executable, ie using EMX method E1 
+to compile & link the executable.  This is so that fork() works (see 
+"YOU HAVE BEEN WARNED" item 1).
+
+Python25.dll is created as a normal OMF DLL, with an OMF import 
+library and module definition file.  There is also an a.out (.a) import 
+library to support linking the DLL to a.out executables.  The DLL 
+requires the EMX runtime DLLs.
+
+This port has been built with complete support for multithreading.
+
+Modules:
+
+With the exception of modules that have a significant code size, or are 
+not recommended or desired for normal use, the standard modules are now 
+built into the core DLL rather than configured as dynamically loadable 
+modules.  This is for both reasons of performance (startup time) and 
+memory use (lots of small DLLs fragment the address space).
+
+I haven't yet changed the building of Python's dynamically loadable 
+modules over to using the DistUtils.
+
+See "YOU HAVE BEEN WARNED" item 3 for notes about the fcntl module, and 
+"YOU HAVE BEEN WARNED" item 10 for notes about the pwd and grp modules.
+
+This port supports case sensitive module import semantics, matching 
+the Windows release.  This can be deactivated by setting the PYTHONCASEOK 
+environment variable (the value doesn't matter) - see "YOU HAVE BEEN WARNED" 
+item 12.
+
+Optional modules:
+
+Where I've been able to locate the required 3rd party packages already 
+ported to OS/2, I've built and included them.
+
+These include ncurses (_curses, _curses_panel), BSD DB (bsddb185), 
+GNU GDBM (gdbm, dbm), zlib (zlib), GNU Readline (readline), and GNU UFC 
+(crypt).
+
+Expat is now included in the Python release sourceball, and the pyexpat 
+module is always built.
+
+I have built these modules statically linked against the 3rd party 
+libraries.  Unfortunately my attempts to use the dll version of GNU 
+readline have been a dismal failure, in that when the dynamically 
+linked readline module is active other modules immediately provoke a 
+core dump when imported.
+
+Only the BSD DB package (part of the BSD package distributed with EMX) 
+needs source modifications to be used for this port, pertaining to use 
+of errno with multithreading.
+
+The other packages, except for ncurses and zlib, needed Makefile changes 
+for multithreading support but no source changes.
+
+The _curses_panel module is a potential problem - see "YOU HAVE BEEN 
+WARNED" item 13.
+
+Upstream source patches:
+
+No updates to the Python 2.5 release have become available.
+
+Eberhard Mattes' EMXFIX04 update to his EMX 0.9d tools suite includes 
+bug fixes for the BSD DB library.  The bsddb module included in this 
+port incorporates these fixes.
+
+Library and other distributed Python code:
+
+The Python standard library lives in the Lib directory.  All the standard 
+library code included with the Python 2.5 source distribution is included 
+in the binary archive, with the exception of the dos-8x3 and tkinter 
+subdirectories which have been omitted to reduce the size of the binary 
+archive - the dos-8x3 components are unnecessary duplicates and Tkinter 
+is not supported by this port (yet).  All the plat-* subdirectories in the 
+source distribution have also been omitted, except for the plat-os2emx 
+subdirectory.
+
+The Tools and Demo directories contain a collection of Python scripts.  
+To reduce the size of the binary archive, the Demo/sgi, Demo/Tix, 
+Demo/tkinter, Tools/audiopy and Tools/IDLE subdirectories have been 
+omitted as not being supported by this port.  The Misc directory has 
+also been omitted.
+
+All subdirectories omitted from the binary archive can be reconstituted 
+from the Python 2.5 source distribution, if desired.
+
+Support for building Python extensions:
+
+The Config subdirectory contains the files describing the configuration 
+of the interpreter and the Makefile, import libraries for the Python DLL, 
+and the module definition file used to create the Python DLL.  The 
+Include subdirectory contains all the standard Python header files 
+needed for building extensions.
+
+As I don't have the Visual Age C++ compiler, I've made no attempt to 
+have this port support extensions built with that compiler.
+
+
+Packaging
+---------
+
+This port is packaged as follows:
+- python-2.5-os2emx-bin-03????.zip  (binaries, library modules)
+- python-2.5-os2emx-src-03????      (patches+makefiles for non-Python code)
+
+As all the Python specific patches for the port are now part of the 
+Python release tarball, only the patches and makefiles involved in 
+building external libraries for optional extensions are included in 
+the source archive.
+
+Documentation for the Python language, as well as the Python 2.5 
+source distibution, can be obtained from the Python website 
+(http://www.python.org/) or the Python project pages at Sourceforge 
+(http://sf.net/projects/python/).
+
+
+Installation
+------------
+
+Obtain and install, as per the included instructions, the EMX runtime 
+package.
+
+Unpack this archive, preserving the subdirectories, in the root directory 
+of the drive where you want Python to live.
+
+Add the Python directory (eg C:\Python25) to the PATH and LIBPATH 
+variables in CONFIG.SYS.
+
+You should then set the PYTHONHOME and PYTHONPATH environment variables 
+in CONFIG.SYS.
+
+PYTHONHOME should be set to Python's top level directory.  PYTHONPATH 
+should be set to the semicolon separated list of principal Python library 
+directories.
+I use:
+  SET PYTHONHOME=F:/Python25
+  SET PYTHONPATH=F:/Python25/Lib;F:/Python25/Lib/plat-os2emx;
+                 F:/Python25/Lib/lib-dynload;F:/Python25/Lib/site-packages
+
+NOTE!:  the PYTHONPATH setting above is linewrapped for this document - it 
+should all be on one line in CONFIG.SYS!
+
+If you wish to use the curses module, you should set the TERM and TERMINFO 
+environment variables appropriately.
+
+If you don't already have ncurses installed, I have included a copy of the 
+EMX subset of the Terminfo database included with the ncurses-5.2 source 
+distribution.  This can be used by setting the TERMINFO environment variable 
+to the path of the Terminfo subdirectory below the Python home directory.
+On my system this looks like:
+  SET TERMINFO=F:/Python25/Terminfo
+
+For the TERM environment variable, I would try one of the following:
+  SET TERM=ansi
+  SET TERM=os2
+  SET TERM=window
+
+You will have to reboot your system for these changes to CONFIG.SYS to take 
+effect.
+
+If you wish to compile all the included Python library modules to bytecode, 
+you can change into the Python home directory and run the COMPILEALL.CMD 
+batch file.
+
+You can execute the regression tests included with the Python 2.5 source 
+distribution by changing to the Python 2.5 home directory and executing the 
+REGRTEST.CMD batch file.  The following tests are known to fail at this 
+time:
+- test_mhlib (I don't know of any port of MH to OS/2);
+- test_strptime (see "YOU HAVE BEEN WARNED" item 22);
+- test_time (see "YOU HAVE BEEN WARNED" item 22);
+- test_posixpath (see "YOU HAVE BEEN WARNED" item 23).
+
+Note that some of the network related tests expect the loopback interface
+(interface "lo", with IP address 127.0.0.1) to be enabled, which from my
+experience is not the default configuration.  Additionally, test_popen2
+expects the "cat" utility (such as found in ports of the GNU tools) to
+be installed.
+
+
+Building from source
+--------------------
+
+With the EMX port now checked into Python's CVS repository, the build 
+infrastructure is part of the Python release sourceball.
+
+Prerequisites
+
+First and foremost, you need an operational EMX development installation - 
+EMX v0.9d with fix04 (the latest at time of writing) & the gcc 2.8.1 
+compiler released by Eberhard Mattes is the recommended setup.
+
+If you have a different version of gcc installed, see "YOU HAVE BEEN 
+WARNED" item 16.
+
+Other items of software required:-
+
+- GNU make (I'm using v3.76.1)
+- rm, cp, mkdir from the GNU file utilities package
+- GNU find
+- GNU sed
+
+Procedure
+
+0. all changes mentioned apply to files in the PC/os2emx subdirectory 
+   of the Python release source tree.  make is also executed from this 
+   directory, so change into this directory before proceeding.
+
+1. decide if you need to change the location of the Python installation.
+   If you wish to do this, set the value of the Makefile variable LIB_DIR 
+   to the directory you wish to use for PYTHONHOME 
+   (eg /usr/local/lib/python2.5).
+
+   If you want Python to find its library without the PYTHONHOME 
+   environment variable set, set the value of the Makefile variable 
+   FIXED_PYHOME to "yes" (uncomment the appropriate line).
+
+2. If you wish the Python executables (python.exe, pythonpm.exe & pgen.exe) 
+   to be installed in a directory other than the PYTHONHOME directory, set 
+   the value of the Makefile variable EXE_DIR to the appropriate directory.
+
+3. If you wish the Python core DLL (python25.dll) to be installed in a 
+   directory other than the directory in which the Python executables are 
+   installed (by default, the PYTHONHOME directory), set the value of the 
+   Makefile variable DLL_DIR to the appropriate directory.  This DLL must 
+   be placed in a directory on the system's LIBPATH, or that gets set 
+   with BEGINLIBPATH or ENDLIBPATH.
+
+4. If you have installed any of the libraries that can be used to build 
+   optional Python modules, set the value of the relevant HAVE_<package> 
+   Makefile variable to "yes".  The Makefile currently supports:
+
+   library               Makefile variable
+   ........................................
+   zlib (1.1.4)          HAVE_ZLIB
+   GNU UltraFast Crypt   HAVE_UFC
+   Tcl/Tk                HAVE_TCLTK (not known to work)
+   GNU Readline          HAVE_GREADLINE
+   BSD DB (v1.85)        HAVE_BSDDB
+   ncurses               HAVE_NCURSES
+   GNU gdbm              HAVE_GDBM
+   libbz2                HAVE_BZ2
+   OpenSSL               HAVE_OPENSSL
+
+   Please note that you need to check that what you have installed 
+   is compatible with Python's build options.  In particular, the 
+   BSD DB v1.85 library needs to be rebuilt with a source patch for 
+   multithread support (doesn't change the library's reentrant status 
+   but allows it to be linked to Python which is multithreaded).  
+   Widely available binary packages of other librarys & DLLs are 
+   not built/linked with multithread support.  Beware!
+
+   Also note that the Makefile currently expects any libraries to be 
+   found with the default library search path.  You may need to add 
+   -L switches to the LDFLAGS Makefile variable if you have installed 
+   libraries in directories not in the default search path (which can 
+   be controlled by the LIBRARY_PATH environment variable used by EMX).
+
+5. make
+
+   It is usually a good idea to redirect the stdout and stderr streams 
+   of the make process to log files, so that you can review any messages. 
+
+6. make test
+
+   This runs the Python regression tests, and completion is a sign of 
+   a usable build.  You should check the list of skipped modules to 
+   ensure that any optional modules you selected have been built; 
+   checking the list of failures against the list of known failures 
+   elsewhere in this document is also prudent.
+
+7. make install
+   >>>>>> NOT YET COMPLETE <<<<<< 
+
+8. change to a directory outside the Python source tree and start Python. 
+   Check the version and build date to confirm satisfactory installation.
+
+
+YOU HAVE BEEN WARNED!!
+----------------------
+
+I know about a number of nasties in this port.
+
+1.  Eberhard Mattes, author of EMX, writes in his documentation that fork() 
+is very inefficient in the OS/2 environment.  It also requires that the 
+executable be linked in a.out format rather than OMF.  Use the os.exec 
+and/or the os.spawn family of functions where possible.
+
+2.  In the absence of GNU Readline, terminating the interpreter requires a 
+control-Z (^Z) followed by a carriage return.  Jeff Rush documented this 
+problem in his Python 1.5.2 port.  With Readline, a control-D (^D) works 
+as per the standard Unix environment.
+
+3.  EMX only has a partial implementation of fcntl().  The fcntl module 
+in this port supports what EMX supports.  If fcntl is important to you, 
+please review the EMX C Library Reference (included in .INF format in the 
+EMXVIEW.ZIP archive as part of the complete EMX development tools suite).
+Because of other side-effects I have modified the test_fcntl.py test 
+script to deactivate the exercising of the missing functionality.
+
+4.  the PyBSDDB3 module has been imported into the Python standard
+library, with the intent of superceding the BSDDB 1.85 module (bsddb).
+As I don't yet have a satisfactory port of Sleepcat's more recent DB
+library (3.3.x/4.0.x/4.1.x), I haven't included a binary of this
+module.  I have left the Python part of the PyBSDDB package in this
+distribution for completeness.
+
+5.  As a consequence of the PyBSDDB3 module being imported, the former 
+BSD DB (bsddb) module, linked against the DB v1.85 library from EMX, 
+has been renamed bsddb185.  The bsddb185 module will not be built by 
+default on most platforms, but in the absence of a PyBSDDB3 module I 
+have retained it in the EMX port.
+
+Version 1.85 of the DB library is widely known to have bugs, although 
+some patches have become available (and are incorporated into the 
+included bsddb185 module).  Unless you have problems with software 
+licenses which would rule out GDBM (and the dbm module because it is 
+linked against the GDBM library) or need it for file format compatibility, 
+you may be better off deleting it and relying on GDBM.
+
+Any code you have which uses the v1.85 bsddb module can be modified to 
+use the renamed module by changing
+
+  import bsddb
+
+to
+
+  import bsddb185 as bsddb
+
+6.  The readline module has been linked against ncurses rather than the 
+termcap library supplied with EMX.
+
+7.  I have configured this port to use "/" as the preferred path separator 
+character, rather than "\" ('\\'), in line with the convention supported 
+by EMX.  Backslashes are still supported of course, and still appear in 
+unexpected places due to outside sources that don't get normalised.
+
+8.  While the DistUtils components are now functional, other 
+packaging/binary handling tools and utilities such as those included in
+the Demo and Tools directories - freeze in particular - are unlikely to 
+work.  If you do get them going, I'd like to know about your success.
+
+9.  I haven't set out to support the [BEGIN|END]LIBPATH functionality 
+supported by one of the earlier ports (Rush's??).  If it works let me know.
+
+10. As a result of the limitations imposed by EMX's library routines, the 
+standard extension module pwd only synthesises a simple passwd database, 
+and the grp module cannot be supported at all.
+
+I have written pure Python substitutes for pwd and grp, which can process 
+real passwd and group files for those applications (such as MailMan) that 
+require more than EMX emulates.  I have placed pwd.py and grp.py in 
+Lib/plat-os2emx, which is usually before Lib/lib-dynload (which contains 
+pwd.pyd) in the PYTHONPATH.  If you have become attached to what pwd.pyd 
+supports, you can put Lib/lib-dynload before Lib/plat-os2emx in PYTHONPATH 
+or delete/rename pwd.py & grp.py.
+
+pwd.py & grp.py support locating their data files by looking in the 
+environment for them in the following sequence:
+pwd.py:  $ETC_PASSWD             (%ETC_PASSWD%)
+         $ETC/passwd             (%ETC%/passwd)
+         $PYTHONHOME/Etc/passwd  (%PYTHONHOME%/Etc/passwd)
+grp.py:  $ETC_GROUP              (%ETC_GROUP%)
+         $ETC/group              (%ETC%/group)
+         $PYTHONHOME/Etc/group   (%PYTHONHOME%/Etc/group)
+
+The ETC_PASSWD and ETC_GROUP environment variables are intended to allow 
+support for multiple passwd/grp files, where other applications may not 
+support as wide a variety of input variations (drive remappings, 
+separators etc).
+
+Both modules support using either the ":" character (Unix standard) or 
+";" (OS/2, DOS, Windows standard) field separator character, and pwd.py 
+implements the following drive letter conversions for the home_directory and 
+shell fields (for the ":" separator only):
+         $x  ->  x:
+         x;  ->  x:
+
+Example versions of passwd and group are in the Etc subdirectory.  The 
+regression tests (test_pwd and test_grp) will fail if valid password and 
+group files cannot be found, but should pass otherwise.
+
+Be aware that Python's pwd & group modules are for reading password and 
+group information only.
+
+11. EMX's termios routines don't support all of the functionality now 
+exposed by the termios module - refer to the EMX documentation to find 
+out what is supported.
+
+12. The case sensitive import semantics introduced in Python 2.1 for other 
+case insensitive but case preserving file/operating systems (Windows etc), 
+have been incorporated into this port, and are active by default.  Setting 
+the PYTHONCASEOK environment variable (to any value) reverts to the 
+previous (case insensitive) semantics.  This can be an issue with some 
+file management utilities that do not preserve the case of file and
+directory names.
+
+13. Because I am statically linking ncurses, the _curses_panel 
+module has potential problems arising from separate library data areas.
+To avoid this, I have configured the _curses_.pyd (imported as 
+"_curses_panel") to import the ncurses symbols it needs from _curses.dll 
+(which is the curses module, but with a .dll extension rather than .pyd 
+so that the dynamic loader can actually import the symbols from it as a 
+DLL).
+
+The site module (Lib/site.py) has code added to tweak BEGINLIBPATH so
+that _curses.dll is found when _curses_panel is imported.  If you have
+problems attempting to use the _curses_panel support please let me know,
+and I'll have another look at this.
+
+14. sys.platform reports "os2emx" instead of "os2".  os.name still 
+reports "os2".  This change was to make it easier to distinguish between 
+the VAC++ build (formerly maintained by Michael Muller) and the EMX build 
+(this port), principally for DistUtils.
+
+15. it appears that the %W substitution in the EMX strftime() routine has 
+an off-by-one bug.  strftime was listed as passing the regression tests 
+in previous releases, but this fact appears to have been an oversight in 
+the regression test suite.  To fix this really requires a portable 
+strftime routine - I'm looking into using one from FreeBSD, but its not 
+ready yet.
+
+16. I have successfully built this port with Andy Zabolotny's ports of 
+pgcc 2.95 and gcc 3.2.1, in addition to EM's gcc 2.8.1.  To use the 
+bsddb185 module with the gcc 3.2.1 build, I had to recompile the DB library 
+with gcc 3.2.1 - I don't know why, but trying to import the module built 
+against a DB library compiled with gcc 2.8.1 would result in a SYS3175 
+error.
+
+I have not attempted to compile Python with any version of gcc prior to 
+v2.8.1.
+
+This release sees the default optimisation change to 
+"-O3 -fomit-frame-pointer -mprobe".  This works fine too for pgcc 2.95 
+but not for gcc 3.2.1.
+
+With gcc 3.2.1, -O3 causes 2 unexpected test failures: test_format and 
+test_unicode.  Both these tests pass if -O2 is instead of -O3 with this 
+compiler, and the performance difference is negligible (in contrast to 
+gcc 2.8.1 and pgcc 2.95, where the performance difference between the 
+2 optimisation settings approaches 10%).
+
+17.  os.spawnv() and os.spawnve() expose EMX's library routines rather 
+than use the emulation in os.py.
+
+In order to make use of some of the features this makes available in 
+the OS/2 environment, you should peruse the relevant EMX documentation 
+(EMXLIB.INF in the EMXVIEW.ZIP archive accompanying the EMX archives 
+on Hobbes or LEO).  Be aware that I have exposed all the "mode" options 
+supported by EMX, but there are combinations that either cannot be 
+practically used by/in Python or have the potential to compromise your 
+system's stability.
+
+18.  pythonpm.exe used to be just python.exe with the WINDOWAPI linker 
+option set in the pythonpm.def file.  In practice, this turns out to do 
+nothing useful.
+
+I have written a replacement which wraps the Python DLL in a genuine 
+Presentation Manager application.  This version actually runs the 
+Python interpreter in a separate thread from the PM shell, in order 
+that PythonPM has a functioning message queue as good PM apps should.
+In its current state, PythonPM's window is hidden.  It can be displayed, 
+although it will have no content as nothing is ever written to the 
+window.  Only the "hide" button is available.  Although the code 
+has support for shutting PythonPM down when the Python interpreter is 
+still busy (via the "control" menu), this is not well tested and given 
+comments I've come across in EMX documentation suggesting that the 
+thread killing operation has problems I would suggest caution in 
+relying on this capability.
+
+PythonPM processes commandline parameters normally.  The standard input, 
+output and error streams are only useful if redirected, as PythonPM's 
+window is not a console in any form and so cannot accept or display 
+anything.  This means that the -i option is ineffective.
+
+Because the Python thread doesn't create its own message queue, creating 
+PM Windows and performing most PM operations is not possible from within 
+this thread.  How this will affect supporting PM extensions (such as 
+Tkinter using a PM port of Tcl/Tk, or wxPython using the PM port of 
+WxWindows) is still being researched.
+
+Note that os.fork() _DOES_NOT_WORK_ in PythonPM - SYS3175s are the result 
+of trying.  os.spawnv() _does_ work.  PythonPM passes all regression tests 
+that the standard Python interpreter (python.exe) passes, with the exception 
+of test_fork1 and test_socket which both attempt to use os.fork().
+
+I very much want feedback on the performance, behaviour and utility of 
+PythonPM.  I would like to add a PM console capability to it, but that 
+will be a non-trivial effort.  I may be able to leverage the code in 
+Illya Vaes' Tcl/Tk port, which would make it easier.
+
+19.  os.chdir() uses EMX's _chdir2(), which supports changing both drive 
+and directory at once.  Similarly, os.getcwd() uses EMX's _getcwd() 
+which returns drive as well as path.
+
+20.  pyconfig.h is installed in the Include subdirectory with all 
+other include files.
+
+21.  the default build explicitly sets the number of file handles 
+available to a Python process to 250.  EMX default is 40, which is 
+insufficient for the tempfile regression test (test_tempfile) which 
+tries to create 100 temporary files.
+
+This setting can be overridden via the EMXOPT environment variable:
+  set EMXOPT=-h250
+is equivalent to the setting currently used.  The emxbind utility (if you 
+have it installed) can also be used to permanently change the setting in 
+python.exe - please refer to the EMX documentation for more information.
+
+22.  a pure python strptime module is now part of the Python standard
+library, superceding a platform specific extension module. This module
+leverages the strftime module, and as a result test_strptime fails
+due to the EMX strftime bug in item 20 above.
+
+23.  test_posixpath attempts to exercise various Posix path related
+functionality.  Most of the sub-tests pass, but the "ismount" and
+"samestat" subtests fail:
+- EMX provides not satisfactory mount point emulation, so "ismount"
+  cannot succeed;
+- EMX documents that successive stat() calls will produce different
+  results, so "samestat" cannot succeed.
+
+test_posixpath should skip these tests on EMX.
+
+24.  I have reports of BitTorrent not working.  It appears that the
+EMX select() emulation, possibly in concert with bugs in the TCP/IP
+stack, runs into problems under the stress imposed by this application.
+I think it suffices to say that BitTorrent is a fair stress test of a
+system's networking capability.
+
+25.  In the absence of an EMX implementation of the link() function, I've 
+implemented a crude Python emulation, in the file 
+Lib/plat-os2emx/_emx_link.py.  This is imported into the os module, and 
+becomes available as os.link() in the normal way.
+
+The emulation copies the source file in binary mode, and will fail if 
+disk space is exhausted. The call fails if the target already exists. 
+There are no guarantees to thread safety with this emulation - beware!
+
+The emulation was written to support a link() based file locking system 
+used in GNU Mailman.
+
+26.  AF_UNIX sockets, otherwise known as Unix domain sockets, are now
+supported.  Unfortunately, there are some traps arising from the
+implementation in IBM's TCP/IP stack:-
+- the path name must start with '\\socket\\' ('/socket/' won't work!),
+  with the length of the full path name less than 108 characters;
+- unlike Unix, the socket endpoints don't exist in the filesystem;
+- by default, sockets are in binary mode.
+
+27.  As of Python 2.4, the mpz, rotor and xreadlines modules have been 
+dropped from the Python source tree.
+
+28.  The subprocess module was added to the standard library relatively
+late in the 2.4 development cycle.  Unfortunately I haven't had the
+round tuits to adapt the module to the EMX environment yet, and
+test_subprocess has a number of failures as a result.
+
+29.  The default stack size for threads has been 64k.  This is proving
+insufficient for some codebases, such as Zope.  The thread stack size
+still defaults to 64k, but this can now be increased via the stack_size()
+function exposed by the threading & thread modules as well as by defining
+THREAD_STACK_SIZE to an appropriate value in the Makefile (which contains
+a commented out definition for 128kB thread stacks).  I have seen
+references to heavy Zope/Plone usage requiring 1MB thread stacks on
+FreeBSD and Linux, but doubt that for most likely usage on OS/2 that
+more than 256kB is necessary.  The size of the required stacks (main 
+and thread) can vary significantly depending on which version of gcc
+is used along with the compiler optimisations selected.  Note that the
+main thread stack size is set during linking and is currently 2MB.
+
+... probably other issues that I've not encountered, or don't remember :-(
+
+If you encounter other difficulties with this port, which can be 
+characterised as peculiar to this port rather than to the Python release,
+I would like to hear about them.  However I cannot promise to be able to do 
+anything to resolve such problems.  See the Contact section below...
+
+
+To do...
+--------
+
+In no particular order of apparent importance or likelihood...
+
+- support Tkinter and/or alternative GUI (wxWindows??)
+
+
+Credits
+-------
+
+In addition to people identified above, I'd like to thank:
+- the BDFL, Guido van Rossum, and crew for Python;
+- Dr David Mertz, for trying out a pre-release of this port;
+- the Python-list/comp.lang.python community;
+- John Poltorak, for input about pwd/grp.
+
+Contact
+-------
+
+Constructive feedback, negative or positive, about this port is welcome 
+and should be addressed to me at the e-mail addresses below.
+
+I have a private mailing list for announcements of fixes & updates to 
+this port.  If you wish to receive such e-mail announcments, please send 
+me an e-mail requesting that you be added to this list.
+
+Andrew MacIntyre
+E-mail: andymac at bullseye.apana.org.au, or andymac at pcug.org.au
+Web:    http://www.andymac.org/
+
+23 July, 2006.

Added: vendor/Python/current/PC/os2emx/config.c
===================================================================
--- vendor/Python/current/PC/os2emx/config.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/os2emx/config.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,182 @@
+/* -*- C -*- ***********************************************
+Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
+The Netherlands.
+
+                        All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the names of Stichting Mathematisch
+Centrum or CWI or Corporation for National Research Initiatives or
+CNRI not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+While CWI is the initial source for this software, a modified version
+is made available by the Corporation for National Research Initiatives
+(CNRI) at the Internet address ftp://ftp.python.org.
+
+STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
+CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+
+******************************************************************/
+
+/* Module configuration */
+
+/* This file contains the table of built-in modules.
+   See init_builtin() in import.c. */
+
+#include "Python.h"
+
+extern void initos2();
+extern void initsignal();
+#ifdef WITH_THREAD
+extern void initthread();
+#endif
+extern void init_codecs();
+extern void init_csv();
+extern void init_locale();
+extern void init_random();
+extern void init_sre();
+extern void init_symtable();
+extern void init_weakref();
+extern void initarray();
+extern void initbinascii();
+extern void initcPickle();
+extern void initcStringIO();
+extern void initcollections();
+extern void initcmath();
+extern void initdatetime();
+extern void initdl();
+extern void initerrno();
+extern void initfcntl();
+extern void init_functools();
+extern void init_heapq();
+extern void initimageop();
+extern void inititertools();
+extern void initmath();
+extern void init_md5();
+extern void initoperator();
+extern void initrgbimg();
+extern void init_sha();
+extern void init_sha256();
+extern void init_sha512();
+extern void initstrop();
+extern void init_struct();
+extern void inittermios();
+extern void inittime();
+extern void inittiming();
+extern void initxxsubtype();
+extern void initzipimport();
+#if !HAVE_DYNAMIC_LOADING
+extern void init_curses();
+extern void init_curses_panel();
+extern void init_hotshot();
+extern void init_testcapi();
+extern void initbsddb185();
+extern void initbz2();
+extern void initfpectl();
+extern void initfpetest();
+extern void initparser();
+extern void initpwd();
+extern void initunicodedata();
+extern void initzlib();
+#ifdef USE_SOCKET
+extern void init_socket();
+extern void initselect();
+#endif
+#endif
+/* -- ADDMODULE MARKER 1 -- */
+
+extern void PyMarshal_Init();
+extern void initimp();
+extern void initgc();
+
+struct _inittab _PyImport_Inittab[] = {
+
+	{"os2", initos2},
+	{"signal", initsignal},
+#ifdef WITH_THREAD
+	{"thread", initthread},
+#endif
+	{"_codecs", init_codecs},
+	{"_csv", init_csv},
+	{"_locale", init_locale},
+	{"_random", init_random},
+	{"_sre", init_sre},
+	{"_symtable", init_symtable},
+	{"_weakref", init_weakref},
+	{"array", initarray},
+	{"binascii", initbinascii},
+	{"cPickle", initcPickle},
+	{"cStringIO", initcStringIO},
+	{"collections", initcollections},
+	{"cmath", initcmath},
+	{"datetime", initdatetime},
+	{"dl", initdl},
+	{"errno", initerrno},
+	{"fcntl", initfcntl},
+	{"_functools", init_functools},
+	{"_heapq", init_heapq},
+	{"imageop", initimageop},
+	{"itertools", inititertools},
+	{"math", initmath},
+	{"_md5", init_md5},
+	{"operator", initoperator},
+	{"rgbimg", initrgbimg},
+	{"_sha", init_sha},
+	{"_sha256", init_sha256},
+	{"_sha512", init_sha512},
+	{"strop", initstrop},
+	{"_struct", init_struct},
+	{"termios", inittermios},
+	{"time", inittime},
+	{"timing", inittiming},
+	{"xxsubtype", initxxsubtype},
+	{"zipimport", initzipimport},
+#if !HAVE_DYNAMIC_LOADING
+	{"_curses", init_curses},
+	{"_curses_panel", init_curses_panel},
+	{"_hotshot", init_hotshot},
+	{"_testcapi", init_testcapi},
+	{"bsddb185", initbsddb185},
+	{"bz2", initbz2},
+	{"fpectl", initfpectl},
+	{"fpetest", initfpetest},
+	{"parser", initparser},
+	{"pwd", initpwd},
+	{"unicodedata", initunicodedata},
+	{"zlib", initzlib},
+#ifdef USE_SOCKET
+	{"_socket", init_socket},
+	{"select", initselect},
+#endif
+#endif
+/* -- ADDMODULE MARKER 2 -- */
+
+	/* This module "lives in" with marshal.c */
+	{"marshal", PyMarshal_Init},
+
+	/* This lives it with import.c */
+	{"imp", initimp},
+
+	/* These entries are here for sys.builtin_module_names */
+	{"__main__", NULL},
+	{"__builtin__", NULL},
+	{"sys", NULL},
+	{"exceptions", NULL},
+
+	/* This lives in gcmodule.c */
+	{"gc", initgc},
+
+	/* Sentinel */
+	{0, 0}
+};

Added: vendor/Python/current/PC/os2emx/dlfcn.c
===================================================================
--- vendor/Python/current/PC/os2emx/dlfcn.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/os2emx/dlfcn.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,223 @@
+/* -*- C -*- ***********************************************
+Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
+The Netherlands.
+
+                        All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the names of Stichting Mathematisch
+Centrum or CWI or Corporation for National Research Initiatives or
+CNRI not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+While CWI is the initial source for this software, a modified version
+is made available by the Corporation for National Research Initiatives
+(CNRI) at the Internet address ftp://ftp.python.org.
+
+STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
+CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+
+******************************************************************/
+
+/* This library implements dlopen() - Unix-like dynamic linking
+ * emulation functions for OS/2 using DosLoadModule() and company.
+ */
+
+#define INCL_DOS
+#define INCL_DOSERRORS
+#define INCL_DOSSESMGR
+#define INCL_WINPROGRAMLIST
+#define INCL_WINFRAMEMGR
+#include <os2.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <malloc.h>
+
+typedef struct _track_rec {
+	char *name;
+	HMODULE handle;
+	void *id;
+	struct _track_rec *next;
+} tDLLchain, *DLLchain;
+
+static DLLchain dlload = NULL;	/* A simple chained list of DLL names */
+static char dlerr [256];	/* last error text string */
+static void *last_id;
+
+static DLLchain find_id(void *id)
+{
+	DLLchain tmp;
+
+	for (tmp = dlload; tmp; tmp = tmp->next)
+		if (id == tmp->id)
+			return tmp;
+
+	return NULL;
+}
+
+/* load a dynamic-link library and return handle */
+void *dlopen(char *filename, int flags)
+{
+	HMODULE hm;
+	DLLchain tmp;
+	char err[256];
+	char *errtxt;
+	int rc = 0, set_chain = 0;
+
+	for (tmp = dlload; tmp; tmp = tmp->next)
+		if (strnicmp(tmp->name, filename, 999) == 0)
+			break;
+
+	if (!tmp)
+	{
+		tmp = (DLLchain) malloc(sizeof(tDLLchain));
+		if (!tmp)
+			goto nomem;
+		tmp->name = strdup(filename);
+		tmp->next = dlload;
+		set_chain = 1;
+	}
+
+	switch (rc = DosLoadModule((PSZ)&err, sizeof(err), filename, &hm))
+	{
+		case NO_ERROR:
+			tmp->handle = hm;
+			if (set_chain)
+			{
+				do
+					last_id++;
+				while ((last_id == 0) || (find_id(last_id)));
+				tmp->id = last_id;
+				dlload = tmp;
+			}
+			return tmp->id;
+		case ERROR_FILE_NOT_FOUND:
+		case ERROR_PATH_NOT_FOUND:
+			errtxt = "module `%s' not found";
+			break;
+		case ERROR_TOO_MANY_OPEN_FILES:
+		case ERROR_NOT_ENOUGH_MEMORY:
+		case ERROR_SHARING_BUFFER_EXCEEDED:
+nomem:
+			errtxt = "out of system resources";
+			break;
+		case ERROR_ACCESS_DENIED:
+			errtxt = "access denied";
+			break;
+		case ERROR_BAD_FORMAT:
+		case ERROR_INVALID_SEGMENT_NUMBER:
+		case ERROR_INVALID_ORDINAL:
+		case ERROR_INVALID_MODULETYPE:
+		case ERROR_INVALID_EXE_SIGNATURE:
+		case ERROR_EXE_MARKED_INVALID:
+		case ERROR_ITERATED_DATA_EXCEEDS_64K:
+		case ERROR_INVALID_MINALLOCSIZE:
+		case ERROR_INVALID_SEGDPL:
+		case ERROR_AUTODATASEG_EXCEEDS_64K:
+		case ERROR_RELOCSRC_CHAIN_EXCEEDS_SEGLIMIT:
+			errtxt = "invalid module format";
+			break;
+		case ERROR_INVALID_NAME:
+			errtxt = "filename doesn't match module name";
+			break;
+		case ERROR_SHARING_VIOLATION:
+		case ERROR_LOCK_VIOLATION:
+			errtxt = "sharing violation";
+			break;
+		case ERROR_INIT_ROUTINE_FAILED:
+			errtxt = "module initialization failed";
+			break;
+		default:
+			errtxt = "cause `%s', error code = %d";
+			break;
+	}
+	snprintf(dlerr, sizeof(dlerr), errtxt, &err, rc);
+	if (tmp)
+	{
+		if (tmp->name)
+			free(tmp->name);
+		free(tmp);
+	}
+	return 0;
+}
+
+/* return a pointer to the `symbol' in DLL */
+void *dlsym(void *handle, char *symbol)
+{
+	int rc = 0;
+	PFN addr;
+	char *errtxt;
+	int symord = 0;
+	DLLchain tmp = find_id(handle);
+
+	if (!tmp)
+		goto inv_handle;
+
+	if (*symbol == '#')
+		symord = atoi(symbol + 1);
+
+	switch (rc = DosQueryProcAddr(tmp->handle, symord, symbol, &addr))
+	{
+		case NO_ERROR:
+			return (void *)addr;
+		case ERROR_INVALID_HANDLE:
+inv_handle:
+			errtxt = "invalid module handle";
+			break;
+		case ERROR_PROC_NOT_FOUND:
+		case ERROR_INVALID_NAME:
+			errtxt = "no symbol `%s' in module";
+			break;
+		default:
+			errtxt = "symbol `%s', error code = %d";
+			break;
+	}
+	snprintf(dlerr, sizeof(dlerr), errtxt, symbol, rc);
+	return NULL;
+}
+
+/* free dynamicaly-linked library */
+int dlclose(void *handle)
+{
+	int rc;
+	DLLchain tmp = find_id(handle);
+
+	if (!tmp)
+		goto inv_handle;
+
+	switch (rc = DosFreeModule(tmp->handle))
+	{
+		case NO_ERROR:
+			free(tmp->name);
+			dlload = tmp->next;
+			free(tmp);
+			return 0;
+		case ERROR_INVALID_HANDLE:
+inv_handle:
+			strcpy(dlerr, "invalid module handle");
+			return -1;
+		case ERROR_INVALID_ACCESS:
+			strcpy(dlerr, "access denied");
+			return -1;
+		default:
+			return -1;
+	}
+}
+
+/* return a string describing last occurred dl error */
+char *dlerror()
+{
+	return dlerr;
+}

Added: vendor/Python/current/PC/os2emx/dlfcn.h
===================================================================
--- vendor/Python/current/PC/os2emx/dlfcn.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/os2emx/dlfcn.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,51 @@
+/* -*- C -*- ***********************************************
+Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
+The Netherlands.
+
+                        All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the names of Stichting Mathematisch
+Centrum or CWI or Corporation for National Research Initiatives or
+CNRI not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+While CWI is the initial source for this software, a modified version
+is made available by the Corporation for National Research Initiatives
+(CNRI) at the Internet address ftp://ftp.python.org.
+
+STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
+CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+
+******************************************************************/
+
+/* This library implements dlopen() - Unix-like dynamic linking
+ * emulation functions for OS/2 using DosLoadModule() and company.
+ */
+
+#ifndef _DLFCN_H
+#define _DLFCN_H
+
+/* load a dynamic-link library and return handle */
+void *dlopen(char *filename, int flags);
+
+/* return a pointer to the `symbol' in DLL */
+void *dlsym(void *handle, char *symbol);
+
+/* free dynamicaly-linked library */
+int dlclose(void *handle);
+
+/* return a string describing last occurred dl error */
+char *dlerror(void);
+
+#endif /* !_DLFCN_H */

Added: vendor/Python/current/PC/os2emx/dllentry.c
===================================================================
--- vendor/Python/current/PC/os2emx/dllentry.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/os2emx/dllentry.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,42 @@
+/*
+ * This is the entry point for the Python 2.3 core DLL.
+ */
+
+#define NULL 0
+
+#define REF(s)	extern void s(); void *____ref_##s = &s;
+
+/* Make references to imported symbols to pull them from static library */
+REF(Py_Main);
+
+#include <signal.h>
+
+extern int _CRT_init(void);
+extern void _CRT_term(void);
+extern void __ctordtorInit(void);
+extern void __ctordtorTerm(void);
+
+unsigned long _DLL_InitTerm(unsigned long mod_handle, unsigned long flag)
+{
+	switch (flag)
+	{
+		case 0:
+			if (_CRT_init())
+				return 0;
+			__ctordtorInit();
+
+			/* Ignore fatal signals */
+			signal(SIGSEGV, SIG_IGN);
+			signal(SIGFPE, SIG_IGN);
+
+			return 1;
+
+		case 1:
+			__ctordtorTerm();
+			_CRT_term();
+			return 1;
+
+		default:
+			return 0;
+	}
+}

Added: vendor/Python/current/PC/os2emx/getpathp.c
===================================================================
--- vendor/Python/current/PC/os2emx/getpathp.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/os2emx/getpathp.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,418 @@
+
+/* Return the initial module search path. */
+/* This version used by OS/2+EMX */
+
+/* ----------------------------------------------------------------
+   PATH RULES FOR OS/2+EMX:
+   This describes how sys.path is formed on OS/2+EMX.  It describes the 
+   functionality, not the implementation (ie, the order in which these 
+   are actually fetched is different)
+
+   * Python always adds an empty entry at the start, which corresponds
+     to the current directory.
+
+   * If the PYTHONPATH env. var. exists, its entries are added next.
+
+   * We attempt to locate the "Python Home" - if the PYTHONHOME env var
+     is set, we believe it.  Otherwise, we use the path of our host .EXE's
+     to try and locate our "landmark" (lib\\os.py) and deduce our home.
+     - If we DO have a Python Home: The relevant sub-directories (Lib, 
+       plat-win, lib-tk, etc) are based on the Python Home
+     - If we DO NOT have a Python Home, the core Python Path is
+       loaded from the registry.  This is the main PythonPath key, 
+       and both HKLM and HKCU are combined to form the path)
+
+   * Iff - we can not locate the Python Home, and have not had a PYTHONPATH
+     specified (ie, we have _nothing_ we can assume is a good path), a
+     default path with relative entries is used (eg. .\Lib;.\plat-win, etc)
+
+
+  The end result of all this is:
+  * When running python.exe, or any other .exe in the main Python directory
+    (either an installed version, or directly from the PCbuild directory),
+    the core path is deduced.
+
+  * When Python is hosted in another exe (different directory, embedded via 
+    COM, etc), the Python Home will not be deduced, so the core path from
+    the registry is used.  Other "application paths "in the registry are 
+    always read.
+
+  * If Python can't find its home and there is no registry (eg, frozen
+    exe, some very strange installation setup) you get a path with
+    some default, but relative, paths.
+
+   ---------------------------------------------------------------- */
+
+
+#include "Python.h"
+#include "osdefs.h"
+
+#ifndef PYOS_OS2
+#error This file only compilable on OS/2
+#endif
+
+#define INCL_DOS
+#include <os2.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <string.h>
+
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+/* Search in some common locations for the associated Python libraries.
+ *
+ * Py_GetPath() tries to return a sensible Python module search path.
+ *
+ * The approach is an adaptation for Windows of the strategy used in
+ * ../Modules/getpath.c; it uses the Windows Registry as one of its
+ * information sources.
+ */
+
+#ifndef LANDMARK
+#if defined(PYCC_GCC)
+#define LANDMARK "lib/os.py"
+#else
+#define LANDMARK "lib\\os.py"
+#endif
+#endif
+
+static char prefix[MAXPATHLEN+1];
+static char progpath[MAXPATHLEN+1];
+static char *module_search_path = NULL;
+
+
+static int
+is_sep(char ch)	/* determine if "ch" is a separator character */
+{
+#ifdef ALTSEP
+	return ch == SEP || ch == ALTSEP;
+#else
+	return ch == SEP;
+#endif
+}
+
+/* assumes 'dir' null terminated in bounds.
+ * Never writes beyond existing terminator.
+ */
+static void
+reduce(char *dir)
+{
+	size_t i = strlen(dir);
+	while (i > 0 && !is_sep(dir[i]))
+		--i;
+	dir[i] = '\0';
+}
+	
+static int
+exists(char *filename)
+{
+	struct stat buf;
+	return stat(filename, &buf) == 0;
+}
+
+/* Is module  (check for .pyc/.pyo too)
+ * Assumes 'filename' MAXPATHLEN+1 bytes long - 
+ * may extend 'filename' by one character.
+ */
+static int
+ismodule(char *filename)
+{
+	if (exists(filename))
+		return 1;
+
+	/* Check for the compiled version of prefix. */
+	if (strlen(filename) < MAXPATHLEN) {
+		strcat(filename, Py_OptimizeFlag ? "o" : "c");
+		if (exists(filename))
+			return 1;
+	}
+	return 0;
+}
+
+/* Add a path component, by appending stuff to buffer.
+   buffer must have at least MAXPATHLEN + 1 bytes allocated, and contain a
+   NUL-terminated string with no more than MAXPATHLEN characters (not counting
+   the trailing NUL).  It's a fatal error if it contains a string longer than
+   that (callers must be careful!).  If these requirements are met, it's
+   guaranteed that buffer will still be a NUL-terminated string with no more
+   than MAXPATHLEN characters at exit.  If stuff is too long, only as much of
+   stuff as fits will be appended.
+*/
+
+static void
+join(char *buffer, char *stuff)
+{
+	size_t n, k;
+	if (is_sep(stuff[0]))
+		n = 0;
+	else {
+		n = strlen(buffer);
+		if (n > 0 && !is_sep(buffer[n-1]) && n < MAXPATHLEN)
+			buffer[n++] = SEP;
+	}
+	if (n > MAXPATHLEN)
+		Py_FatalError("buffer overflow in getpathp.c's joinpath()");
+	k = strlen(stuff);
+	if (n + k > MAXPATHLEN)
+		k = MAXPATHLEN - n;
+	strncpy(buffer+n, stuff, k);
+	buffer[n+k] = '\0';
+}
+
+/* gotlandmark only called by search_for_prefix, which ensures
+ * 'prefix' is null terminated in bounds.  join() ensures
+ * 'landmark' can not overflow prefix if too long.
+ */
+static int
+gotlandmark(char *landmark)
+{
+	int n, ok;
+
+	n = strlen(prefix);
+	join(prefix, landmark);
+	ok = ismodule(prefix);
+	prefix[n] = '\0';
+	return ok;
+}
+
+/* assumes argv0_path is MAXPATHLEN+1 bytes long, already \0 term'd. 
+ * assumption provided by only caller, calculate_path()
+ */
+static int
+search_for_prefix(char *argv0_path, char *landmark)
+{
+	/* Search from argv0_path, until landmark is found */
+	strcpy(prefix, argv0_path);
+	do {
+		if (gotlandmark(landmark))
+			return 1;
+		reduce(prefix);
+	} while (prefix[0]);
+	return 0;
+}
+
+
+static void
+get_progpath(void)
+{
+	extern char *Py_GetProgramName(void);
+	char *path = getenv("PATH");
+	char *prog = Py_GetProgramName();
+
+	PPIB pib;
+	if ((DosGetInfoBlocks(NULL, &pib) == 0) &&
+	    (DosQueryModuleName(pib->pib_hmte, sizeof(progpath), progpath) == 0))
+		return;
+
+	if (prog == NULL || *prog == '\0')
+		prog = "python";
+
+	/* If there is no slash in the argv0 path, then we have to
+	 * assume python is on the user's $PATH, since there's no
+	 * other way to find a directory to start the search from.  If
+	 * $PATH isn't exported, you lose.
+	 */
+#ifdef ALTSEP
+	if (strchr(prog, SEP) || strchr(prog, ALTSEP))
+#else
+	if (strchr(prog, SEP))
+#endif
+		strncpy(progpath, prog, MAXPATHLEN);
+	else if (path) {
+		while (1) {
+			char *delim = strchr(path, DELIM);
+
+			if (delim) {
+				size_t len = delim - path;
+				/* ensure we can't overwrite buffer */
+#if !defined(PYCC_GCC)
+				len = min(MAXPATHLEN,len);
+#else
+				len = MAXPATHLEN < len ? MAXPATHLEN : len;
+#endif
+				strncpy(progpath, path, len);
+				*(progpath + len) = '\0';
+			}
+			else
+				strncpy(progpath, path, MAXPATHLEN);
+
+			/* join() is safe for MAXPATHLEN+1 size buffer */
+			join(progpath, prog);
+			if (exists(progpath))
+				break;
+
+			if (!delim) {
+				progpath[0] = '\0';
+				break;
+			}
+			path = delim + 1;
+		}
+	}
+	else
+		progpath[0] = '\0';
+}
+
+static void
+calculate_path(void)
+{
+	char argv0_path[MAXPATHLEN+1];
+	char *buf;
+	size_t bufsz;
+	char *pythonhome = Py_GetPythonHome();
+	char *envpath = getenv("PYTHONPATH");
+	char zip_path[MAXPATHLEN+1];
+	size_t len;
+
+	get_progpath();
+	/* progpath guaranteed \0 terminated in MAXPATH+1 bytes. */
+	strcpy(argv0_path, progpath);
+	reduce(argv0_path);
+	if (pythonhome == NULL || *pythonhome == '\0') {
+		if (search_for_prefix(argv0_path, LANDMARK))
+			pythonhome = prefix;
+		else
+			pythonhome = NULL;
+	}
+	else
+		strncpy(prefix, pythonhome, MAXPATHLEN);
+
+	if (envpath && *envpath == '\0')
+		envpath = NULL;
+
+	/* Calculate zip archive path */
+	strncpy(zip_path, progpath, MAXPATHLEN);
+	zip_path[MAXPATHLEN] = '\0';
+	len = strlen(zip_path);
+	if (len > 4) {
+		zip_path[len-3] = 'z';  /* change ending to "zip" */
+		zip_path[len-2] = 'i';
+		zip_path[len-1] = 'p';
+	}
+	else {
+		zip_path[0] = 0;
+	}
+
+	/* We need to construct a path from the following parts.
+	 * (1) the PYTHONPATH environment variable, if set;
+	 * (2) the zip archive file path;
+	 * (3) the PYTHONPATH config macro, with the leading "."
+	 *     of each component replaced with pythonhome, if set;
+	 * (4) the directory containing the executable (argv0_path).
+	 * The length calculation calculates #3 first.
+	 */
+
+	/* Calculate size of return buffer */
+	if (pythonhome != NULL) {
+		char *p;
+		bufsz = 1;	
+		for (p = PYTHONPATH; *p; p++) {
+			if (*p == DELIM)
+				bufsz++; /* number of DELIM plus one */
+		}
+		bufsz *= strlen(pythonhome);
+	}
+	else
+		bufsz = 0;
+	bufsz += strlen(PYTHONPATH) + 1;
+	bufsz += strlen(argv0_path) + 1;
+	bufsz += strlen(zip_path) + 1;
+	if (envpath != NULL)
+		bufsz += strlen(envpath) + 1;
+
+	module_search_path = buf = malloc(bufsz);
+	if (buf == NULL) {
+		/* We can't exit, so print a warning and limp along */
+		fprintf(stderr, "Can't malloc dynamic PYTHONPATH.\n");
+		if (envpath) {
+			fprintf(stderr, "Using environment $PYTHONPATH.\n");
+			module_search_path = envpath;
+		}
+		else {
+			fprintf(stderr, "Using default static path.\n");
+			module_search_path = PYTHONPATH;
+		}
+		return;
+	}
+
+	if (envpath) {
+		strcpy(buf, envpath);
+		buf = strchr(buf, '\0');
+		*buf++ = DELIM;
+	}
+	if (zip_path[0]) {
+		strcpy(buf, zip_path);
+		buf = strchr(buf, '\0');
+		*buf++ = DELIM;
+	}
+
+	if (pythonhome == NULL) {
+		strcpy(buf, PYTHONPATH);
+		buf = strchr(buf, '\0');
+	}
+	else {
+		char *p = PYTHONPATH;
+		char *q;
+		size_t n;
+		for (;;) {
+			q = strchr(p, DELIM);
+			if (q == NULL)
+				n = strlen(p);
+			else
+				n = q-p;
+			if (p[0] == '.' && is_sep(p[1])) {
+				strcpy(buf, pythonhome);
+				buf = strchr(buf, '\0');
+				p++;
+				n--;
+			}
+			strncpy(buf, p, n);
+			buf += n;
+			if (q == NULL)
+				break;
+			*buf++ = DELIM;
+			p = q+1;
+		}
+	}
+	if (argv0_path) {
+		*buf++ = DELIM;
+		strcpy(buf, argv0_path);
+		buf = strchr(buf, '\0');
+	}
+	*buf = '\0';
+}
+
+
+/* External interface */
+
+char *
+Py_GetPath(void)
+{
+	if (!module_search_path)
+		calculate_path();
+	return module_search_path;
+}
+
+char *
+Py_GetPrefix(void)
+{
+	if (!module_search_path)
+		calculate_path();
+	return prefix;
+}
+
+char *
+Py_GetExecPrefix(void)
+{
+	return Py_GetPrefix();
+}
+
+char *
+Py_GetProgramFullPath(void)
+{
+	if (!module_search_path)
+		calculate_path();
+	return progpath;
+}

Added: vendor/Python/current/PC/os2emx/pyconfig.h
===================================================================
--- vendor/Python/current/PC/os2emx/pyconfig.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/os2emx/pyconfig.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,331 @@
+#ifndef Py_CONFIG_H
+#define Py_CONFIG_H
+
+/* config.h.
+ * At some time in the past, generated automatically by/from configure.
+ * now maintained manually.
+ */
+
+/* build environment */
+#define PLATFORM	"os2emx"
+#define COMPILER	"[EMX GCC " __VERSION__ "]"
+#define PYOS_OS2	1
+#define PYCC_GCC	1
+
+/* default location(s) */
+#ifndef PREFIX
+#define PREFIX		""
+#endif
+#ifndef PYTHONPATH
+#define PYTHONPATH	"./Lib;./Lib/plat-" PLATFORM \
+			";./Lib/lib-dynload;./Lib/site-packages"
+#endif
+
+/* Debugging */
+#ifndef Py_DEBUG
+/*#define Py_DEBUG 1*/
+#endif
+
+/* if building an extension or wrapper executable,
+ * mark Python API symbols "extern" so that symbols
+ * imported from the Python core DLL aren't duplicated.
+ */
+#ifdef Py_BUILD_CORE
+#  define PyAPI_FUNC(RTYPE)	RTYPE
+#else
+#  define PyAPI_FUNC(RTYPE)	extern RTYPE
+#endif
+#define PyAPI_DATA(RTYPE)	extern RTYPE
+#define PyMODINIT_FUNC	void
+
+/* Use OS/2 flavour of threads */
+#define WITH_THREAD	1
+#define OS2_THREADS	1
+
+/* We want sockets */
+#define TCPIPV4		1
+#define USE_SOCKET	1
+#define socklen_t	int
+#define FD_SETSIZE	1024
+
+/* enable the Python object allocator */
+#define	WITH_PYMALLOC	1
+
+/* enable the GC module */
+#define WITH_CYCLE_GC	1
+
+/* Define if you want documentation strings in extension modules */
+#define WITH_DOC_STRINGS 1
+
+/* Unicode related */
+#define Py_USING_UNICODE 1
+#define PY_UNICODE_TYPE	wchar_t
+#define Py_UNICODE_SIZE SIZEOF_SHORT
+
+/* EMX defines ssize_t */
+#define HAVE_SSIZE_T	1
+
+/* system capabilities */
+#define HAVE_TTYNAME	1
+#define HAVE_WAIT	1
+#define HAVE_GETEGID    1
+#define HAVE_GETEUID    1
+#define HAVE_GETGID     1
+#define HAVE_GETPPID    1
+#define HAVE_GETUID     1
+#define HAVE_OPENDIR    1
+#define HAVE_PIPE       1
+#define HAVE_POPEN      1
+#define HAVE_SYSTEM	1
+#define HAVE_TTYNAME	1
+#define HAVE_DYNAMIC_LOADING	1
+
+/* if port of GDBM installed, it includes NDBM emulation */
+#define HAVE_NDBM_H 1
+
+/* need this for spawnv code in posixmodule (cloned from WIN32 def'n) */
+typedef long intptr_t;
+
+/* we don't have tm_zone but do have the external array tzname */
+#define HAVE_TZNAME 1
+
+/* Define as the return type of signal handlers (int or void). */
+#define RETSIGTYPE void
+
+/* Define if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define if you can safely include both <sys/time.h> and <time.h>. */
+#define TIME_WITH_SYS_TIME 1
+
+/* Define this if you have the type long long. */
+#define HAVE_LONG_LONG 1
+
+/* Define if your compiler supports function prototypes. */
+#define HAVE_PROTOTYPES 1
+
+/* Define if your compiler supports variable length function prototypes
+ * (e.g. void fprintf(FILE *, char *, ...);) *and* <stdarg.h>.
+ */
+#define HAVE_STDARG_PROTOTYPES 1
+
+/* Define if malloc(0) returns a NULL pointer. */
+#define MALLOC_ZERO_RETURNS_NULL 1
+
+/* Define to force use of thread-safe errno, h_errno, and other functions. */
+#define _REENTRANT 1
+
+/* Define if you can safely include both <sys/select.h> and <sys/time.h>
+ * (which you can't on SCO ODT 3.0).
+ */
+#define SYS_SELECT_WITH_SYS_TIME 1
+
+/* The number of bytes in an off_t. */
+#define SIZEOF_OFF_T 4
+
+/* The number of bytes in an time_t. */
+#define SIZEOF_TIME_T 4
+
+/* The number of bytes in a short. */
+#define SIZEOF_SHORT 2
+
+/* The number of bytes in a int. */
+#define SIZEOF_INT 4
+
+/* The number of bytes in a long. */
+#define SIZEOF_LONG 4
+
+/* The number of bytes in a long long. */
+#define SIZEOF_LONG_LONG 8
+
+/* The number of bytes in a void *. */
+#define SIZEOF_VOID_P 4
+
+/* The number of bytes in a size_t. */
+#define SIZEOF_SIZE_T 4
+
+/* Define if you have the alarm function. */
+#define HAVE_ALARM 1
+
+/* Define if you have the clock function. */
+#define HAVE_CLOCK 1
+
+/* Define if you have the dup2 function. */
+#define HAVE_DUP2 1
+
+/* Define if you have the execv function. */
+#define HAVE_EXECV 1
+
+/* Define if you have the spawnv function. */
+#define HAVE_SPAWNV 1
+
+/* Define if you have the flock function. */
+#define HAVE_FLOCK 1
+
+/* Define if you have the fork function. */
+#define HAVE_FORK 1
+
+/* Define if you have the fsync function. */
+#define HAVE_FSYNC 1
+
+/* Define if you have the ftime function. */
+#define HAVE_FTIME 1
+
+/* Define if you have the ftruncate function. */
+#define HAVE_FTRUNCATE 1
+
+/* Define if you have the getcwd function. */
+#define HAVE_GETCWD 1
+
+/* Define if you have the getpeername function. */
+#define HAVE_GETPEERNAME 1
+
+/* Define if you have the getpgrp function. */
+#define HAVE_GETPGRP 1
+
+/* Define if you have the getpid function. */
+#define HAVE_GETPID 1
+
+/* Define if you have the getpwent function. */
+#define HAVE_GETPWENT 1
+
+/* Define if you have the gettimeofday function. */
+#define HAVE_GETTIMEOFDAY 1
+
+/* Define if you have the getwd function. */
+#define HAVE_GETWD 1
+
+/* Define if you have the hypot function. */
+#define HAVE_HYPOT 1
+
+/* Define if you have the kill function. */
+#define HAVE_KILL 1
+
+/* Define if you have the memmove function. */
+#define HAVE_MEMMOVE 1
+
+/* Define if you have the mktime function. */
+#define HAVE_MKTIME 1
+
+/* Define if you have the pause function. */
+#define HAVE_PAUSE 1
+
+/* Define if you have the putenv function. */
+#define HAVE_PUTENV 1
+
+/* Define if you have the select function. */
+#define HAVE_SELECT 1
+
+/* Define if you have the setgid function. */
+#define HAVE_SETGID 1
+
+/* Define if you have the setlocale function. */
+#define HAVE_SETLOCALE 1
+
+/* Define if you have the setpgid function. */
+#define HAVE_SETPGID 1
+
+/* Define if you have the setuid function. */
+#define HAVE_SETUID 1
+
+/* Define if you have the setvbuf function. */
+#define HAVE_SETVBUF 1
+
+/* Define if you have the sigaction function. */
+#define HAVE_SIGACTION 1
+
+/* Define if you have the strerror function. */
+#define HAVE_STRERROR 1
+
+/* Define if you have the strftime function. */
+#define HAVE_STRFTIME 1
+
+/* Define if you have the tcgetpgrp function. */
+#define HAVE_TCGETPGRP 1
+
+/* Define if you have the tcsetpgrp function. */
+#define HAVE_TCSETPGRP 1
+
+/* Define if you have the tmpfile function.  */
+#define HAVE_TMPFILE 1
+
+/* Define if you have the times function. */
+#define HAVE_TIMES 1
+
+/* Define if you have the truncate function. */
+#define HAVE_TRUNCATE 1
+
+/* Define if you have the uname function. */
+#define HAVE_UNAME 1
+
+/* Define if you have the waitpid function. */
+#define HAVE_WAITPID 1
+
+/* Define if you have the <conio.h> header file. */
+#undef HAVE_CONIO_H
+
+/* Define if you have the <direct.h> header file. */
+#undef HAVE_DIRECT_H
+
+/* Define if you have the <dirent.h> header file. */
+#define HAVE_DIRENT_H 1
+
+/* Define if you have the <errno.h> header file. */
+#define HAVE_ERRNO_H 1
+
+/* Define if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define if you have the <io.h> header file. */
+#undef HAVE_IO_H
+
+/* Define if you have the <ncurses.h> header file. */
+#define HAVE_NCURSES_H 1
+
+/* Define to 1 if you have the <process.h> header file. */
+#define HAVE_PROCESS_H 1
+
+/* Define if you have the <signal.h> header file. */
+#define HAVE_SIGNAL_H 1
+
+/* Define if you have the <sys/file.h> header file. */
+#define HAVE_SYS_FILE_H 1
+
+/* Define if you have the <sys/param.h> header file. */
+#define HAVE_SYS_PARAM_H 1
+
+/* Define if you have the <sys/select.h> header file. */
+#define HAVE_SYS_SELECT_H 1
+
+/* Define if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define if you have the <sys/time.h> header file. */
+#define HAVE_SYS_TIME_H 1
+
+/* Define if you have the <sys/times.h> header file. */
+#define HAVE_SYS_TIMES_H 1
+
+/* Define if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define if you have the <sys/un.h> header file. */
+#define HAVE_SYS_UN_H 1
+
+/* Define if you have the <sys/utsname.h> header file. */
+#define HAVE_SYS_UTSNAME_H 1
+
+/* Define if you have the <sys/wait.h> header file. */
+#define HAVE_SYS_WAIT_H 1
+
+/* Define if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define if you have the <utime.h> header file. */
+#define HAVE_UTIME_H 1
+
+/* EMX has an snprintf(). */
+#define HAVE_SNPRINTF 1
+
+#endif /* !Py_CONFIG_H */
+

Added: vendor/Python/current/PC/os2emx/python25.def
===================================================================
--- vendor/Python/current/PC/os2emx/python25.def	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/os2emx/python25.def	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1314 @@
+LIBRARY python25 INITINSTANCE TERMINSTANCE 
+DESCRIPTION "Python 2.5 Core DLL" 
+PROTMODE 
+DATA MULTIPLE NONSHARED 
+EXPORTS 
+
+; From python25_s.lib(config)
+  "_PyImport_Inittab"
+
+; From python25_s.lib(dlfcn)
+;  "dlopen"
+;  "dlsym"
+;  "dlclose"
+;  "dlerror"
+
+; From python25_s.lib(getpathp)
+  "Py_GetProgramFullPath"
+  "Py_GetPrefix"
+  "Py_GetExecPrefix"
+  "Py_GetPath"
+
+; From python25_s.lib(getbuildinfo)
+  "Py_GetBuildInfo"
+  "_Py_svnversion"
+
+; From python25_s.lib(main)
+  "Py_Main"
+  "Py_GetArgcArgv"
+
+; From python25_s.lib(acceler)
+  "PyGrammar_AddAccelerators"
+  "PyGrammar_RemoveAccelerators"
+
+; From python25_s.lib(grammar1)
+  "PyGrammar_FindDFA"
+  "PyGrammar_LabelRepr"
+
+; From python25_s.lib(listnode)
+  "PyNode_ListTree"
+
+; From python25_s.lib(node)
+  "PyNode_New"
+  "PyNode_AddChild"
+  "PyNode_Free"
+
+; From python25_s.lib(parser)
+  "PyParser_AddToken"
+  "PyParser_New"
+  "PyParser_Delete"
+
+; From python25_s.lib(parsetok)
+  "Py_TabcheckFlag"
+  "PyParser_ParseString"
+  "PyParser_ParseStringFlagsFilename"
+  "PyParser_ParseFile"
+  "PyParser_ParseFileFlags"
+  "PyParser_ParseStringFlags"
+
+; From python25_s.lib(bitset)
+  "_Py_newbitset"
+  "_Py_delbitset"
+  "_Py_addbit"
+  "_Py_samebitset"
+  "_Py_mergebitset"
+
+; From python25_s.lib(metagrammar)
+  "_Py_meta_grammar"
+  "Py_meta_grammar"
+
+; From python25_s.lib(tokenizer)
+  "PyToken_OneChar"
+  "PyToken_TwoChars"
+  "PyToken_ThreeChars"
+  "PyTokenizer_FromString"
+  "PyTokenizer_Free"
+  "PyTokenizer_FromFile"
+  "PyTokenizer_Get"
+  "_PyParser_TokenNames"
+
+; From python25_s.lib(myreadline)
+  "_PyOS_ReadlineTState"
+  "PyOS_ReadlineFunctionPointer"
+  "PyOS_StdioReadline"
+  "PyOS_Readline"
+  "PyOS_InputHook"
+
+; From python25_s.lib(abstract)
+  "_PyObject_LengthHint"
+  "PyMapping_Size"
+  "PyObject_CallMethod"
+  "PyObject_GetItem"
+  "PySequence_GetItem"
+  "PyObject_SetItem"
+  "PySequence_SetItem"
+  "PyObject_DelItem"
+  "PySequence_DelItem"
+  "PyNumber_Multiply"
+  "PyNumber_InPlaceAdd"
+  "PyNumber_InPlaceMultiply"
+  "PyNumber_Int"
+  "PyNumber_Long"
+  "PyNumber_Float"
+  "PySequence_Concat"
+  "PySequence_Repeat"
+  "PySequence_InPlaceConcat"
+  "PySequence_InPlaceRepeat"
+  "PySequence_GetSlice"
+  "PySequence_SetSlice"
+  "PySequence_Tuple"
+  "PyObject_GetIter"
+  "PyIter_Next"
+  "PySequence_Fast"
+  "_PySequence_IterSearch"
+  "PyObject_CallFunction"
+  "_PyObject_CallFunction_SizeT"
+  "_PyObject_CallMethod_SizeT"
+  "PyObject_CallMethodObjArgs"
+  "PyObject_CallFunctionObjArgs"
+  "PyObject_Cmp"
+  "PyObject_Call"
+  "PyObject_CallObject"
+  "PyObject_Type"
+  "PyObject_Size"
+  "PyObject_Length"
+  "PyObject_DelItemString"
+  "PyObject_AsCharBuffer"
+  "PyObject_CheckReadBuffer"
+  "PyObject_AsReadBuffer"
+  "PyObject_AsWriteBuffer"
+  "PyNumber_Check"
+  "PyNumber_Add"
+  "PyNumber_Subtract"
+  "PyNumber_Divide"
+  "PyNumber_FloorDivide"
+  "PyNumber_TrueDivide"
+  "PyNumber_Remainder"
+  "PyNumber_Divmod"
+  "PyNumber_Power"
+  "PyNumber_Negative"
+  "PyNumber_Positive"
+  "PyNumber_Absolute"
+  "PyNumber_Invert"
+  "PyNumber_Lshift"
+  "PyNumber_Rshift"
+  "PyNumber_And"
+  "PyNumber_Xor"
+  "PyNumber_Or"
+  "PyNumber_Index"
+  "PyNumber_InPlaceSubtract"
+  "PyNumber_InPlaceDivide"
+  "PyNumber_InPlaceFloorDivide"
+  "PyNumber_InPlaceTrueDivide"
+  "PyNumber_InPlaceRemainder"
+  "PyNumber_InPlacePower"
+  "PyNumber_InPlaceLshift"
+  "PyNumber_InPlaceRshift"
+  "PyNumber_InPlaceAnd"
+  "PyNumber_InPlaceXor"
+  "PyNumber_InPlaceOr"
+  "PySequence_Check"
+  "PySequence_Size"
+  "PySequence_Length"
+  "PySequence_DelSlice"
+  "PySequence_List"
+  "PySequence_Count"
+  "PySequence_Contains"
+  "PySequence_In"
+  "PySequence_Index"
+  "PyMapping_Check"
+  "PyMapping_Length"
+  "PyMapping_HasKeyString"
+  "PyMapping_HasKey"
+  "PyMapping_GetItemString"
+  "PyMapping_SetItemString"
+  "PyObject_IsInstance"
+  "PyObject_IsSubclass"
+
+; From python25_s.lib(boolobject)
+  "PyBool_FromLong"
+  "PyBool_Type"
+  "_Py_ZeroStruct"
+  "_Py_TrueStruct"
+
+; From python25_s.lib(bufferobject)
+  "PyBuffer_FromObject"
+  "PyBuffer_FromReadWriteObject"
+  "PyBuffer_FromMemory"
+  "PyBuffer_FromReadWriteMemory"
+  "PyBuffer_New"
+  "PyBuffer_Type"
+
+; From python25_s.lib(cellobject)
+  "PyCell_New"
+  "PyCell_Get"
+  "PyCell_Set"
+  "PyCell_Type"
+
+; From python25_s.lib(classobject)
+  "PyClass_New"
+  "PyClass_IsSubclass"
+  "PyInstance_New"
+  "PyInstance_NewRaw"
+  "PyMethod_New"
+  "PyMethod_Function"
+  "PyMethod_Self"
+  "PyMethod_Class"
+  "_PyInstance_Lookup"
+  "PyMethod_Fini"
+  "PyClass_Type"
+  "PyInstance_Type"
+  "PyMethod_Type"
+
+; From python25_s.lib(cobject)
+  "PyCObject_FromVoidPtr"
+  "PyCObject_FromVoidPtrAndDesc"
+  "PyCObject_AsVoidPtr"
+  "PyCObject_GetDesc"
+  "PyCObject_Import"
+  "PyCObject_SetVoidPtr"
+  "PyCObject_Type"
+
+; From python25_s.lib(codeobject)
+  "PyCode_New"
+  "PyCode_Addr2Line"
+  "PyCode_CheckLineNumber"
+  "PyCode_Type"
+
+; From python25_s.lib(complexobject)
+  "_Py_c_pow"
+  "_Py_c_sum"
+  "_Py_c_diff"
+  "_Py_c_neg"
+  "_Py_c_prod"
+  "_Py_c_quot"
+  "PyComplex_FromCComplex"
+  "PyComplex_FromDoubles"
+  "PyComplex_RealAsDouble"
+  "PyComplex_ImagAsDouble"
+  "PyComplex_AsCComplex"
+  "PyComplex_Type"
+
+; From python25_s.lib(descrobject)
+  "PyWrapper_New"
+  "PyDescr_NewMethod"
+  "PyDescr_NewClassMethod"
+  "PyDescr_NewMember"
+  "PyDescr_NewGetSet"
+  "PyDescr_NewWrapper"
+  "PyDictProxy_New"
+  "PyWrapperDescr_Type"
+  "PyProperty_Type"
+
+; From python25_s.lib(dictobject)
+  "PyDict_New"
+  "PyDict_GetItem"
+  "PyDict_SetItem"
+  "PyDict_DelItem"
+  "PyDict_Clear"
+  "PyDict_MergeFromSeq2"
+  "PyDict_Merge"
+  "PyDict_Keys"
+  "PyDict_Values"
+  "PyDict_Contains"
+  "PyDict_Next"
+  "PyDict_Items"
+  "PyDict_Size"
+  "PyDict_Copy"
+  "PyDict_Update"
+  "PyDict_GetItemString"
+  "PyDict_SetItemString"
+  "PyDict_DelItemString"
+  "PyDict_Type"
+  "PyDictIterKey_Type"
+  "PyDictIterValue_Type"
+  "PyDictIterItem_Type"
+
+; From python25_s.lib(enumobject)
+  "PyEnum_Type"
+  "PyReversed_Type"
+
+; From python25_s.lib(fileobject)
+  "PyFile_FromString"
+  "Py_UniversalNewlineFread"
+  "PyFile_GetLine"
+  "PyFile_SoftSpace"
+  "PyFile_WriteObject"
+  "PyFile_WriteString"
+  "PyObject_AsFileDescriptor"
+  "Py_UniversalNewlineFgets"
+  "PyFile_SetBufSize"
+  "PyFile_SetEncoding"
+  "PyFile_FromFile"
+  "PyFile_AsFile"
+  "PyFile_Name"
+  "PyFile_Type"
+
+; From python25_s.lib(floatobject)
+  "PyFloat_FromString"
+  "PyFloat_AsDouble"
+  "PyFloat_Fini"
+  "_PyFloat_Pack4"
+  "_PyFloat_Pack8"
+  "_PyFloat_Unpack4"
+  "_PyFloat_Unpack8"
+  "PyFloat_FromDouble"
+  "PyFloat_AsReprString"
+  "PyFloat_AsString"
+  "_PyFloat_Init"
+  "PyFloat_AsStringEx"
+  "PyFloat_Type"
+
+; From python25_s.lib(frameobject)
+  "PyFrame_New"
+  "PyFrame_FastToLocals"
+  "PyFrame_LocalsToFast"
+  "_PyFrame_Init"
+  "PyFrame_Fini"
+  "PyFrame_BlockSetup"
+  "PyFrame_BlockPop"
+  "PyFrame_Type"
+
+; From python25_s.lib(funcobject)
+  "PyFunction_New"
+  "PyFunction_GetCode"
+  "PyFunction_GetGlobals"
+  "PyFunction_GetModule"
+  "PyFunction_GetDefaults"
+  "PyFunction_SetDefaults"
+  "PyFunction_GetClosure"
+  "PyFunction_SetClosure"
+  "PyClassMethod_New"
+  "PyStaticMethod_New"
+  "PyFunction_Type"
+  "PyClassMethod_Type"
+  "PyStaticMethod_Type"
+
+; From python25_s.lib(genobject)
+  "PyGen_New"
+  "PyGen_NeedsFinalizing"
+  "PyGen_Type"
+
+; From python25_s.lib(intobject)
+  "PyInt_AsLong"
+  "PyInt_AsUnsignedLongMask"
+  "PyInt_AsUnsignedLongLongMask"
+  "PyInt_FromString"
+  "PyInt_AsSsize_t"
+  "PyInt_Fini"
+  "PyInt_FromUnicode"
+  "PyInt_FromLong"
+  "PyInt_FromSize_t"
+  "PyInt_FromSsize_t"
+  "PyInt_GetMax"
+  "_PyInt_Init"
+  "PyInt_Type"
+
+; From python25_s.lib(iterobject)
+  "PySeqIter_New"
+  "PyCallIter_New"
+  "PySeqIter_Type"
+  "PyCallIter_Type"
+
+; From python25_s.lib(listobject)
+  "PyList_New"
+  "PyList_Append"
+  "PyList_Size"
+  "PyList_GetItem"
+  "PyList_SetItem"
+  "PyList_Insert"
+  "PyList_GetSlice"
+  "PyList_SetSlice"
+  "PyList_Sort"
+  "PyList_Reverse"
+  "PyList_AsTuple"
+  "_PyList_Extend"
+  "PyList_Fini"
+  "PyList_Type"
+  "PyListIter_Type"
+  "PyListRevIter_Type"
+
+; From python25_s.lib(longobject)
+  "PyLong_FromDouble"
+  "PyLong_AsLong"
+  "_PyLong_AsSsize_t"
+  "PyLong_AsUnsignedLong"
+  "_PyLong_FromByteArray"
+  "_PyLong_AsByteArray"
+  "PyLong_AsDouble"
+  "PyLong_FromLongLong"
+  "PyLong_AsLongLong"
+  "PyLong_FromString"
+  "PyLong_FromLong"
+  "PyLong_FromUnsignedLong"
+  "PyLong_AsUnsignedLongMask"
+  "_PyLong_FromSize_t"
+  "_PyLong_FromSsize_t"
+  "_PyLong_AsScaledDouble"
+  "PyLong_FromVoidPtr"
+  "PyLong_AsVoidPtr"
+  "PyLong_FromUnsignedLongLong"
+  "PyLong_AsUnsignedLongLong"
+  "PyLong_AsUnsignedLongLongMask"
+  "PyLong_FromUnicode"
+  "_PyLong_Sign"
+  "_PyLong_NumBits"
+  "_PyLong_New"
+  "_PyLong_Copy"
+  "PyLong_Type"
+  "_PyLong_DigitValue"
+
+; From python25_s.lib(methodobject)
+  "PyCFunction_Call"
+  "Py_FindMethodInChain"
+  "PyCFunction_GetFunction"
+  "PyCFunction_GetSelf"
+  "PyCFunction_GetFlags"
+  "Py_FindMethod"
+  "PyCFunction_NewEx"
+  "PyCFunction_Fini"
+  "PyCFunction_New"
+  "PyCFunction_Type"
+
+; From python25_s.lib(moduleobject)
+  "PyModule_New"
+  "_PyModule_Clear"
+  "PyModule_GetDict"
+  "PyModule_GetName"
+  "PyModule_GetFilename"
+  "PyModule_Type"
+
+; From python25_s.lib(object)
+  "Py_DivisionWarningFlag"
+  "PyObject_Str"
+  "PyObject_Repr"
+  "_PyObject_Str"
+  "PyObject_Unicode"
+  "PyObject_GetAttr"
+  "PyObject_IsTrue"
+  "PyNumber_CoerceEx"
+  "PyObject_Compare"
+  "PyObject_RichCompare"
+  "_Py_HashDouble"
+  "PyObject_Hash"
+  "PyObject_SetAttr"
+  "PyObject_GenericGetAttr"
+  "PyObject_GenericSetAttr"
+  "PyCallable_Check"
+  "PyObject_Dir"
+  "PyMem_Malloc"
+  "PyMem_Realloc"
+  "PyMem_Free"
+  "PyObject_Print"
+  "_PyObject_Dump"
+  "PyObject_RichCompareBool"
+  "PyObject_GetAttrString"
+  "PyObject_SetAttrString"
+  "PyObject_HasAttrString"
+  "PyObject_HasAttr"
+  "_PyObject_GetDictPtr"
+  "PyObject_SelfIter"
+  "PyObject_Not"
+  "PyNumber_Coerce"
+  "Py_ReprEnter"
+  "Py_ReprLeave"
+  "_Py_HashPointer"
+  "Py_IncRef"
+  "Py_DecRef"
+  "_PyTrash_deposit_object"
+  "_PyTrash_destroy_chain"
+  "PyObject_Init"
+  "PyObject_InitVar"
+  "_PyObject_New"
+  "_PyObject_NewVar"
+  "_PyObject_Del"
+  "_Py_ReadyTypes"
+  "_Py_SwappedOp"
+  "_Py_NotImplementedStruct"
+  "_Py_NoneStruct"
+  "_Py_cobject_hack"
+  "_Py_abstract_hack"
+  "_PyTrash_delete_nesting"
+  "_PyTrash_delete_later"
+
+; From python25_s.lib(obmalloc)
+  "PyObject_Malloc"
+  "PyObject_Free"
+  "PyObject_Realloc"
+
+; From python25_s.lib(rangeobject)
+  "PyRange_Type"
+
+; From python25_s.lib(setobject)
+  "PySet_Pop"
+  "PySet_New"
+  "PyFrozenSet_New"
+  "PySet_Size"
+  "PySet_Clear"
+  "PySet_Contains"
+  "PySet_Discard"
+  "PySet_Add"
+  "_PySet_Next"
+  "_PySet_Update"
+  "PySet_Fini"
+  "PySet_Type"
+  "PyFrozenSet_Type"
+
+; From python25_s.lib(sliceobject)
+  "_PySlice_FromIndices"
+  "PySlice_GetIndices"
+  "PySlice_GetIndicesEx"
+  "PySlice_New"
+  "_Py_EllipsisObject"
+  "PySlice_Type"
+
+; From python25_s.lib(stringobject)
+  "PyString_FromStringAndSize"
+  "PyString_InternInPlace"
+  "PyString_FromString"
+  "PyString_FromFormatV"
+  "PyString_AsString"
+  "_PyString_Resize"
+  "PyString_FromFormat"
+  "PyString_AsDecodedString"
+  "PyString_AsEncodedString"
+  "PyString_DecodeEscape"
+  "PyString_Repr"
+  "PyString_AsStringAndSize"
+  "_PyString_FormatLong"
+  "PyString_Format"
+  "_Py_ReleaseInternedStrings"
+  "PyString_Size"
+  "PyString_Concat"
+  "PyString_ConcatAndDel"
+  "_PyString_Eq"
+  "PyString_InternImmortal"
+  "PyString_InternFromString"
+  "_PyString_Join"
+  "PyString_Decode"
+  "PyString_Encode"
+  "PyString_AsEncodedObject"
+  "PyString_AsDecodedObject"
+  "PyString_Fini"
+  "PyString_Type"
+  "PyBaseString_Type"
+
+; From python25_s.lib(structseq)
+  "PyStructSequence_InitType"
+  "PyStructSequence_New"
+  "PyStructSequence_UnnamedField"
+
+; From python25_s.lib(tupleobject)
+  "PyTuple_New"
+  "PyTuple_Pack"
+  "_PyTuple_Resize"
+  "PyTuple_Size"
+  "PyTuple_GetItem"
+  "PyTuple_SetItem"
+  "PyTuple_GetSlice"
+  "PyTuple_Fini"
+  "PyTuple_Type"
+  "PyTupleIter_Type"
+
+; From python25_s.lib(typeobject)
+  "PyType_IsSubtype"
+  "_PyType_Lookup"
+  "PyType_Ready"
+  "PyType_GenericAlloc"
+  "_PyObject_SlotCompare"
+  "PyType_GenericNew"
+  "PyType_Type"
+  "PyBaseObject_Type"
+  "PySuper_Type"
+
+; From python25_s.lib(unicodeobject)
+  "PyUnicodeUCS2_Resize"
+  "PyUnicodeUCS2_FromOrdinal"
+  "PyUnicodeUCS2_FromObject"
+  "PyUnicodeUCS2_FromEncodedObject"
+  "PyUnicodeUCS2_Decode"
+  "PyUnicodeUCS2_GetDefaultEncoding"
+  "PyUnicodeUCS2_DecodeUTF8"
+  "PyUnicodeUCS2_DecodeLatin1"
+  "PyUnicodeUCS2_DecodeASCII"
+  "PyUnicodeUCS2_AsEncodedString"
+  "PyUnicodeUCS2_AsUTF8String"
+  "PyUnicodeUCS2_AsLatin1String"
+  "PyUnicodeUCS2_AsASCIIString"
+  "PyUnicode_DecodeUTF7"
+  "PyUnicode_EncodeUTF7"
+  "PyUnicodeUCS2_DecodeUTF8Stateful"
+  "PyUnicodeUCS2_EncodeUTF8"
+  "PyUnicodeUCS2_DecodeUTF16Stateful"
+  "PyUnicodeUCS2_AsUTF16String"
+  "PyUnicodeUCS2_DecodeUnicodeEscape"
+  "PyUnicodeUCS2_DecodeRawUnicodeEscape"
+  "PyUnicodeUCS2_EncodeRawUnicodeEscape"
+  "_PyUnicode_DecodeUnicodeInternal"
+  "PyUnicodeUCS2_DecodeCharmap"
+  "PyUnicode_BuildEncodingMap"
+  "PyUnicodeUCS2_EncodeCharmap"
+  "PyUnicodeUCS2_TranslateCharmap"
+  "PyUnicodeUCS2_EncodeDecimal"
+  "PyUnicodeUCS2_Count"
+  "PyUnicodeUCS2_Find"
+  "PyUnicodeUCS2_Join"
+  "PyUnicodeUCS2_Splitlines"
+  "PyUnicodeUCS2_Compare"
+  "PyUnicodeUCS2_Contains"
+  "PyUnicodeUCS2_Concat"
+  "_PyUnicode_XStrip"
+  "PyUnicodeUCS2_Replace"
+  "PyUnicodeUCS2_Split"
+  "PyUnicodeUCS2_RSplit"
+  "PyUnicodeUCS2_Format"
+  "_PyUnicodeUCS2_Init"
+  "_PyUnicodeUCS2_Fini"
+  "PyUnicodeUCS2_FromUnicode"
+  "PyUnicodeUCS2_AsUnicode"
+  "PyUnicodeUCS2_GetSize"
+  "PyUnicodeUCS2_GetMax"
+  "_PyUnicodeUCS2_AsDefaultEncodedString"
+  "PyUnicodeUCS2_SetDefaultEncoding"
+  "PyUnicodeUCS2_Encode"
+  "PyUnicodeUCS2_AsEncodedObject"
+  "PyUnicodeUCS2_DecodeUTF16"
+  "PyUnicodeUCS2_EncodeUTF16"
+  "PyUnicodeUCS2_AsUnicodeEscapeString"
+  "PyUnicodeUCS2_EncodeUnicodeEscape"
+  "PyUnicodeUCS2_AsRawUnicodeEscapeString"
+  "PyUnicodeUCS2_EncodeLatin1"
+  "PyUnicodeUCS2_EncodeASCII"
+  "PyUnicodeUCS2_AsCharmapString"
+  "PyUnicodeUCS2_Partition"
+  "PyUnicodeUCS2_RPartition"
+  "PyUnicodeUCS2_Translate"
+  "PyUnicodeUCS2_Tailmatch"
+  "PyUnicode_AsDecodedObject"
+  "PyUnicode_Type"
+
+; From python25_s.lib(unicodectype)
+  "_PyUnicode_TypeRecords"
+  "_PyUnicodeUCS2_ToNumeric"
+  "_PyUnicodeUCS2_IsLowercase"
+  "_PyUnicodeUCS2_IsUppercase"
+  "_PyUnicodeUCS2_IsTitlecase"
+  "_PyUnicodeUCS2_IsWhitespace"
+  "_PyUnicodeUCS2_IsLinebreak"
+  "_PyUnicodeUCS2_ToLowercase"
+  "_PyUnicodeUCS2_ToUppercase"
+  "_PyUnicodeUCS2_ToTitlecase"
+  "_PyUnicodeUCS2_ToDecimalDigit"
+  "_PyUnicodeUCS2_ToDigit"
+  "_PyUnicodeUCS2_IsDecimalDigit"
+  "_PyUnicodeUCS2_IsDigit"
+  "_PyUnicodeUCS2_IsNumeric"
+  "_PyUnicodeUCS2_IsAlpha"
+
+; From python25_s.lib(weakrefobject)
+  "PyWeakref_NewRef"
+  "PyWeakref_NewProxy"
+  "PyObject_ClearWeakRefs"
+  "PyWeakref_GetObject"
+  "_PyWeakref_GetWeakrefCount"
+  "_PyWeakref_ClearRef"
+  "_PyWeakref_RefType"
+  "_PyWeakref_ProxyType"
+  "_PyWeakref_CallableProxyType"
+
+; From python25_s.lib(Python-ast)
+;  "init_ast"
+  "Module"
+  "Interactive"
+  "Expression"
+  "Suite"
+  "FunctionDef"
+  "ClassDef"
+  "Return"
+  "Delete"
+  "Assign"
+  "AugAssign"
+  "Print"
+  "For"
+  "While"
+  "If"
+  "With"
+  "Raise"
+  "TryExcept"
+  "TryFinally"
+  "Assert"
+  "Import"
+  "ImportFrom"
+  "Exec"
+  "Global"
+  "Expr"
+  "Pass"
+  "Break"
+  "Continue"
+  "BoolOp"
+  "BinOp"
+  "UnaryOp"
+  "Lambda"
+  "IfExp"
+  "Dict"
+  "ListComp"
+  "GeneratorExp"
+  "Yield"
+  "Compare"
+  "Call"
+  "Repr"
+  "Num"
+  "Str"
+  "Attribute"
+  "Subscript"
+  "Name"
+  "List"
+  "Tuple"
+  "Ellipsis"
+  "Slice"
+  "ExtSlice"
+  "Index"
+  "comprehension"
+  "excepthandler"
+  "arguments"
+  "keyword"
+  "alias"
+  "PyAST_mod2obj"
+
+; From python25_s.lib(asdl)
+  "asdl_seq_new"
+  "asdl_int_seq_new"
+
+; From python25_s.lib(ast)
+  "PyAST_FromNode"
+
+; From python25_s.lib(bltinmodule)
+  "_PyBuiltin_Init"
+  "Py_FileSystemDefaultEncoding"
+
+; From python25_s.lib(exceptions)
+  "PyUnicodeEncodeError_GetStart"
+  "PyUnicodeDecodeError_GetStart"
+  "PyUnicodeEncodeError_GetEnd"
+  "PyUnicodeDecodeError_GetEnd"
+  "_PyExc_Init"
+  "PyUnicodeDecodeError_Create"
+  "PyUnicodeEncodeError_Create"
+  "PyUnicodeTranslateError_Create"
+  "PyUnicodeEncodeError_GetEncoding"
+  "PyUnicodeDecodeError_GetEncoding"
+  "PyUnicodeEncodeError_GetObject"
+  "PyUnicodeDecodeError_GetObject"
+  "PyUnicodeTranslateError_GetObject"
+  "PyUnicodeTranslateError_GetStart"
+  "PyUnicodeEncodeError_SetStart"
+  "PyUnicodeDecodeError_SetStart"
+  "PyUnicodeTranslateError_SetStart"
+  "PyUnicodeTranslateError_GetEnd"
+  "PyUnicodeEncodeError_SetEnd"
+  "PyUnicodeDecodeError_SetEnd"
+  "PyUnicodeTranslateError_SetEnd"
+  "PyUnicodeEncodeError_GetReason"
+  "PyUnicodeDecodeError_GetReason"
+  "PyUnicodeTranslateError_GetReason"
+  "PyUnicodeEncodeError_SetReason"
+  "PyUnicodeDecodeError_SetReason"
+  "PyUnicodeTranslateError_SetReason"
+  "_PyExc_Fini"
+  "PyExc_BaseException"
+  "PyExc_Exception"
+  "PyExc_StandardError"
+  "PyExc_TypeError"
+  "PyExc_StopIteration"
+  "PyExc_GeneratorExit"
+  "PyExc_SystemExit"
+  "PyExc_KeyboardInterrupt"
+  "PyExc_ImportError"
+  "PyExc_EnvironmentError"
+  "PyExc_IOError"
+  "PyExc_OSError"
+  "PyExc_EOFError"
+  "PyExc_RuntimeError"
+  "PyExc_NotImplementedError"
+  "PyExc_NameError"
+  "PyExc_UnboundLocalError"
+  "PyExc_AttributeError"
+  "PyExc_IndexError"
+  "PyExc_SyntaxError"
+  "PyExc_IndentationError"
+  "PyExc_TabError"
+  "PyExc_LookupError"
+  "PyExc_KeyError"
+  "PyExc_ValueError"
+  "PyExc_UnicodeError"
+  "PyExc_UnicodeEncodeError"
+  "PyExc_UnicodeDecodeError"
+  "PyExc_UnicodeTranslateError"
+  "PyExc_AssertionError"
+  "PyExc_ArithmeticError"
+  "PyExc_FloatingPointError"
+  "PyExc_OverflowError"
+  "PyExc_ZeroDivisionError"
+  "PyExc_SystemError"
+  "PyExc_ReferenceError"
+  "PyExc_MemoryError"
+  "PyExc_Warning"
+  "PyExc_UserWarning"
+  "PyExc_DeprecationWarning"
+  "PyExc_PendingDeprecationWarning"
+  "PyExc_SyntaxWarning"
+  "PyExc_RuntimeWarning"
+  "PyExc_FutureWarning"
+  "PyExc_ImportWarning"
+  "PyExc_MemoryErrorInst"
+
+; From python25_s.lib(ceval)
+  "PyEval_EvalFrameEx"
+  "PyEval_CallObjectWithKeywords"
+  "PyEval_EvalCodeEx"
+  "PyEval_GetFrame"
+  "PyEval_CallObject"
+  "PyEval_SetProfile"
+  "PyEval_SetTrace"
+  "PyEval_GetBuiltins"
+  "PyEval_GetGlobals"
+  "PyEval_GetLocals"
+  "PyEval_GetRestricted"
+  "PyEval_MergeCompilerFlags"
+  "Py_FlushLine"
+  "Py_AddPendingCall"
+  "Py_MakePendingCalls"
+  "Py_SetRecursionLimit"
+  "Py_GetRecursionLimit"
+  "_Py_CheckRecursiveCall"
+  "PyEval_GetFuncName"
+  "PyEval_GetFuncDesc"
+  "PyEval_GetCallStats"
+  "PyEval_EvalFrame"
+  "PyEval_SaveThread"
+  "PyEval_RestoreThread"
+  "PyEval_ThreadsInitialized"
+  "PyEval_InitThreads"
+  "PyEval_AcquireLock"
+  "PyEval_ReleaseLock"
+  "PyEval_AcquireThread"
+  "PyEval_ReleaseThread"
+  "PyEval_ReInitThreads"
+  "_PyEval_SliceIndex"
+  "PyEval_EvalCode"
+  "_PyEval_CallTracing"
+  "_Py_CheckRecursionLimit"
+  "_Py_CheckInterval"
+  "_Py_Ticker"
+
+; From python25_s.lib(compile)
+  "_Py_Mangle"
+  "PyAST_Compile"
+  "PyNode_Compile"
+  "Py_OptimizeFlag"
+
+; From python25_s.lib(codecs)
+  "_PyCodec_Lookup"
+  "PyCodec_Encode"
+  "PyCodec_Decode"
+  "PyCodec_IgnoreErrors"
+  "PyCodec_ReplaceErrors"
+  "PyCodec_XMLCharRefReplaceErrors"
+  "PyCodec_BackslashReplaceErrors"
+  "PyCodec_Register"
+  "PyCodec_Encoder"
+  "PyCodec_Decoder"
+  "PyCodec_IncrementalEncoder"
+  "PyCodec_IncrementalDecoder"
+  "PyCodec_StreamReader"
+  "PyCodec_StreamWriter"
+  "PyCodec_RegisterError"
+  "PyCodec_LookupError"
+  "PyCodec_StrictErrors"
+
+; From python25_s.lib(errors)
+  "PyErr_SetNone"
+  "PyErr_SetString"
+  "PyErr_GivenExceptionMatches"
+  "PyErr_NormalizeException"
+  "PyErr_Fetch"
+  "PyErr_Clear"
+  "PyErr_NoMemory"
+  "PyErr_SetFromErrnoWithFilenameObject"
+  "PyErr_Format"
+  "PyErr_NewException"
+  "PyErr_WriteUnraisable"
+  "PyErr_SyntaxLocation"
+  "PyErr_ProgramText"
+  "PyErr_SetObject"
+  "PyErr_Occurred"
+  "PyErr_Restore"
+  "PyErr_ExceptionMatches"
+  "PyErr_BadArgument"
+  "PyErr_SetFromErrno"
+  "PyErr_SetFromErrnoWithFilename"
+  "PyErr_BadInternalCall"
+  "_PyErr_BadInternalCall"
+  "PyErr_Warn"
+  "PyErr_WarnExplicit"
+
+; From python25_s.lib(frozen)
+  "PyImport_FrozenModules"
+
+; From python25_s.lib(frozenmain)
+  "Py_FrozenMain"
+
+; From python25_s.lib(future)
+  "PyFuture_FromAST"
+
+; From python25_s.lib(getargs)
+  "PyArg_Parse"
+  "_PyArg_Parse_SizeT"
+  "PyArg_ParseTuple"
+  "_PyArg_ParseTuple_SizeT"
+  "PyArg_ParseTupleAndKeywords"
+  "_PyArg_ParseTupleAndKeywords_SizeT"
+  "PyArg_UnpackTuple"
+  "_PyArg_NoKeywords"
+  "PyArg_VaParse"
+  "PyArg_VaParseTupleAndKeywords"
+  "_PyArg_VaParse_SizeT"
+  "_PyArg_VaParseTupleAndKeywords_SizeT"
+
+; From python25_s.lib(getcompiler)
+  "Py_GetCompiler"
+
+; From python25_s.lib(getcopyright)
+  "Py_GetCopyright"
+
+; From python25_s.lib(getmtime)
+  "PyOS_GetLastModificationTime"
+
+; From python25_s.lib(getplatform)
+  "Py_GetPlatform"
+
+; From python25_s.lib(getversion)
+  "Py_GetVersion"
+
+; From python25_s.lib(graminit)
+  "_PyParser_Grammar"
+
+; From python25_s.lib(import)
+  "_PyImport_Init"
+  "_PyImportHooks_Init"
+  "PyImport_ImportModule"
+  "PyImport_Cleanup"
+  "_PyImport_FixupExtension"
+  "PyImport_AddModule"
+  "PyImport_ExecCodeModuleEx"
+  "PyImport_ImportFrozenModule"
+  "PyImport_ImportModuleEx"
+  "PyImport_ImportModuleLevel"
+  "PyImport_ReloadModule"
+  "PyImport_Import"
+;  "initimp"
+  "_PyImport_Fini"
+  "PyImport_GetMagicNumber"
+  "PyImport_ExecCodeModule"
+  "PyImport_GetModuleDict"
+  "_PyImport_FindModule"
+  "_PyImport_IsScript"
+  "_PyImport_ReInitLock"
+  "_PyImport_FindExtension"
+  "PyImport_AppendInittab"
+  "PyImport_ExtendInittab"
+  "PyImport_Inittab"
+  "_PyImport_Filetab"
+
+; From python25_s.lib(importdl)
+  "_PyImport_LoadDynamicModule"
+
+; From python25_s.lib(marshal)
+  "PyMarshal_ReadLongFromFile"
+  "PyMarshal_WriteObjectToString"
+  "PyMarshal_WriteLongToFile"
+  "PyMarshal_WriteObjectToFile"
+  "PyMarshal_ReadShortFromFile"
+  "PyMarshal_ReadObjectFromFile"
+  "PyMarshal_ReadLastObjectFromFile"
+  "PyMarshal_ReadObjectFromString"
+  "PyMarshal_Init"
+
+; From python25_s.lib(modsupport)
+  "Py_InitModule4"
+  "Py_BuildValue"
+  "_Py_BuildValue_SizeT"
+  "PyEval_CallFunction"
+  "PyEval_CallMethod"
+  "_Py_VaBuildValue_SizeT"
+  "Py_VaBuildValue"
+  "PyModule_AddObject"
+  "PyModule_AddIntConstant"
+  "PyModule_AddStringConstant"
+  "_Py_PackageContext"
+
+; From python25_s.lib(mysnprintf)
+  "PyOS_snprintf"
+  "PyOS_vsnprintf"
+
+; From python25_s.lib(mystrtoul)
+  "PyOS_strtoul"
+  "PyOS_strtol"
+
+; From python25_s.lib(pyarena)
+  "PyArena_New"
+  "PyArena_Free"
+  "PyArena_Malloc"
+  "PyArena_AddPyObject"
+
+; From python25_s.lib(pyfpe)
+  "PyFPE_dummy"
+
+; From python25_s.lib(pystate)
+  "PyInterpreterState_Clear"
+  "PyThreadState_Clear"
+  "_PyThread_CurrentFrames"
+  "PyGILState_Ensure"
+  "PyGILState_Release"
+  "PyInterpreterState_New"
+  "PyInterpreterState_Delete"
+  "PyThreadState_Delete"
+  "PyThreadState_New"
+  "PyThreadState_DeleteCurrent"
+  "PyThreadState_Get"
+  "PyThreadState_Swap"
+  "PyThreadState_GetDict"
+  "PyThreadState_SetAsyncExc"
+  "PyGILState_GetThisThreadState"
+  "PyInterpreterState_Head"
+  "PyInterpreterState_Next"
+  "PyInterpreterState_ThreadHead"
+  "PyThreadState_Next"
+  "_PyGILState_Init"
+  "_PyGILState_Fini"
+  "_PyThreadState_Current"
+  "_PyThreadState_GetFrame"
+
+; From python25_s.lib(pystrtod)
+  "PyOS_ascii_strtod"
+  "PyOS_ascii_formatd"
+  "PyOS_ascii_atof"
+
+; From python25_s.lib(pythonrun)
+  "Py_IgnoreEnvironmentFlag"
+  "Py_DebugFlag"
+  "Py_VerboseFlag"
+  "Py_NoSiteFlag"
+  "Py_InteractiveFlag"
+  "Py_FrozenFlag"
+  "Py_InitializeEx"
+  "Py_FatalError"
+  "Py_NewInterpreter"
+  "PyErr_Print"
+  "PyRun_InteractiveOneFlags"
+  "PyParser_ASTFromFile"
+  "PyRun_SimpleFileExFlags"
+  "PyRun_FileExFlags"
+  "Py_Exit"
+  "PyErr_PrintEx"
+  "PyErr_Display"
+  "Py_SetProgramName"
+  "Py_GetProgramName"
+  "Py_SetPythonHome"
+  "Py_GetPythonHome"
+  "Py_Initialize"
+  "Py_Finalize"
+  "Py_IsInitialized"
+  "Py_EndInterpreter"
+  "PyRun_AnyFileFlags"
+  "Py_FdIsInteractive"
+  "PyRun_InteractiveLoopFlags"
+  "PyRun_AnyFileExFlags"
+  "PyRun_SimpleStringFlags"
+  "PyRun_StringFlags"
+  "PyParser_ASTFromString"
+  "PyParser_SimpleParseStringFlags"
+  "PyParser_SimpleParseFileFlags"
+  "Py_CompileStringFlags"
+  "Py_SymtableString"
+  "Py_AtExit"
+  "PyOS_getsig"
+  "PyOS_setsig"
+  "PyParser_SetError"
+  "PyModule_GetWarningsModule"
+  "PyParser_SimpleParseStringFlagsFilename"
+  "PyParser_SimpleParseStringFilename"
+  "PyParser_SimpleParseFile"
+  "PyParser_SimpleParseString"
+  "PyRun_AnyFile"
+  "PyRun_AnyFileEx"
+  "PyRun_File"
+  "PyRun_FileEx"
+  "PyRun_FileFlags"
+  "PyRun_SimpleFile"
+  "PyRun_SimpleFileEx"
+  "PyRun_String"
+  "PyRun_SimpleString"
+  "Py_CompileString"
+  "PyRun_InteractiveOne"
+  "PyRun_InteractiveLoop"
+  "Py_UseClassExceptionsFlag"
+  "Py_UnicodeFlag"
+  "_Py_QnewFlag"
+
+; From python25_s.lib(structmember)
+  "PyMember_Get"
+  "PyMember_GetOne"
+  "PyMember_SetOne"
+  "PyMember_Set"
+
+; From python25_s.lib(symtable)
+  "PySymtable_Build"
+  "PySymtable_Free"
+  "PyST_GetScope"
+  "PySymtable_Lookup"
+  "PySTEntry_Type"
+
+; From python25_s.lib(sysmodule)
+  "_PySys_Init"
+  "PySys_WriteStderr"
+  "PySys_SetPath"
+  "PySys_SetArgv"
+  "PySys_WriteStdout"
+  "Py_SubversionRevision"
+  "Py_SubversionShortBranch"
+  "PySys_GetObject"
+  "PySys_SetObject"
+  "PySys_GetFile"
+  "PySys_ResetWarnOptions"
+  "PySys_AddWarnOption"
+
+; From python25_s.lib(traceback)
+  "PyTraceBack_Here"
+  "PyTraceBack_Print"
+  "PyTraceBack_Type"
+
+; From python25_s.lib(getopt)
+  "_PyOS_GetOpt"
+  "_PyOS_opterr"
+  "_PyOS_optind"
+  "_PyOS_optarg"
+
+; From python25_s.lib(dynload_shlib)
+  "_PyImport_DynLoadFiletab"
+  "_PyImport_GetDynLoadFunc"
+
+; From python25_s.lib(thread)
+  "PyThread_delete_key_value"
+  "PyThread_init_thread"
+  "PyThread_start_new_thread"
+  "PyThread_exit_thread"
+  "PyThread_get_thread_ident"
+  "PyThread_allocate_lock"
+  "PyThread_free_lock"
+  "PyThread_acquire_lock"
+  "PyThread_release_lock"
+  "PyThread_get_stacksize"
+  "PyThread_set_stacksize"
+  "PyThread_create_key"
+  "PyThread_delete_key"
+  "PyThread_set_key_value"
+  "PyThread_get_key_value"
+  "PyThread__exit_thread"
+
+; From python25_s.lib(gcmodule)
+;  "initgc"
+  "_PyObject_GC_New"
+  "_PyObject_GC_NewVar"
+  "PyGC_Collect"
+  "_PyObject_GC_Resize"
+  "_PyObject_GC_Malloc"
+  "PyObject_GC_Track"
+  "PyObject_GC_UnTrack"
+  "PyObject_GC_Del"
+  "_PyGC_Dump"
+  "_PyObject_GC_Track"
+  "_PyObject_GC_UnTrack"
+  "_PyObject_GC_Del"
+  "_PyGC_generation0"
+
+; From python25_s.lib(signalmodule)
+;  "initsignal"
+  "PyErr_CheckSignals"
+  "PyErr_SetInterrupt"
+  "PyOS_FiniInterrupts"
+  "PyOS_InterruptOccurred"
+  "PyOS_InitInterrupts"
+  "PyOS_AfterFork"
+
+; From python25_s.lib(posixmodule)
+;  "initos2"
+
+; From python25_s.lib(threadmodule)
+;  "initthread"
+
+; From python25_s.lib(arraymodule)
+;  "initarray"
+;  "array_methods"
+
+; From python25_s.lib(binascii)
+;  "initbinascii"
+
+; From python25_s.lib(cmathmodule)
+;  "initcmath"
+
+; From python25_s.lib(_codecsmodule)
+;  "init_codecs"
+
+; From python25_s.lib(collectionsmodule)
+;  "initcollections"
+  "dequeiter_type"
+  "dequereviter_type"
+
+; From python25_s.lib(cPickle)
+;  "initcPickle"
+;  "fast_save_leave"
+
+; From python25_s.lib(cStringIO)
+;  "initcStringIO"
+
+; From python25_s.lib(_csv)
+;  "init_csv"
+
+; From python25_s.lib(datetimemodule)
+;  "initdatetime"
+
+; From python25_s.lib(dlmodule)
+;  "initdl"
+
+; From python25_s.lib(errnomodule)
+;  "initerrno"
+
+; From python25_s.lib(fcntlmodule)
+;  "initfcntl"
+
+; From python25_s.lib(_functoolsmodule)
+;  "init_functools"
+
+; From python25_s.lib(_heapqmodule)
+;  "init_heapq"
+
+; From python25_s.lib(imageop)
+;  "initimageop"
+
+; From python25_s.lib(itertoolsmodule)
+;  "inititertools"
+
+; From python25_s.lib(_localemodule)
+;  "init_locale"
+
+; From python25_s.lib(mathmodule)
+;  "initmath"
+
+; From python25_s.lib(md5)
+  "md5_finish"
+  "md5_init"
+  "md5_append"
+
+; From python25_s.lib(md5module)
+;  "init_md5"
+
+; From python25_s.lib(operator)
+;  "initoperator"
+
+; From python25_s.lib(_randommodule)
+;  "init_random"
+
+; From python25_s.lib(rgbimgmodule)
+;  "initrgbimg"
+
+; From python25_s.lib(shamodule)
+;  "init_sha"
+
+; From python25_s.lib(sha256module)
+;  "init_sha256"
+
+; From python25_s.lib(sha512module)
+;  "init_sha512"
+
+; From python25_s.lib(_sre)
+;  "init_sre"
+
+; From python25_s.lib(stropmodule)
+;  "initstrop"
+
+; From python25_s.lib(_struct)
+;  "init_struct"
+
+; From python25_s.lib(symtablemodule)
+;  "init_symtable"
+
+; From python25_s.lib(termios)
+;  "inittermios"
+
+; From python25_s.lib(timemodule)
+;  "inittime"
+  "_PyTime_DoubleToTimet"
+;  "inittimezone"
+
+; From python25_s.lib(timingmodule)
+;  "inittiming"
+
+; From python25_s.lib(_weakref)
+;  "init_weakref"
+
+; From python25_s.lib(xxsubtype)
+;  "initxxsubtype"
+
+; From python25_s.lib(zipimport)
+;  "initzipimport"

Added: vendor/Python/current/PC/os2emx/pythonpm.c
===================================================================
--- vendor/Python/current/PC/os2emx/pythonpm.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/os2emx/pythonpm.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,124 @@
+/* OS/2 PM main program - creates a hidden window, and starts Python
+ * interpreter in a separate thread, so that Python scripts can be
+ * run in PM process space without a console Window.  The interpreter
+ * is incorporated by linking in the Python DLL.
+ *
+ * As it stands, I don't think this is adequate for supporting Python
+ * GUI modules, as the Python thread doesn't have its own message
+ * queue - which is required of threads that want to create/use
+ * PM windows.
+ *
+ * This code owes a lot to "OS/2 Presentation Manager Programming", by
+ * Charles Petzold.
+ *
+ * Andrew MacIntyre <andymac at bullseye.apana.org.au>, August 2001.
+ * Released under the terms of the Python 2.1.1 licence - see the LICENCE
+ * file in the Python v2.1.1 (or later) source distribution.
+ * Copyright assigned to the Python Software Foundation, 2001.
+ */
+
+#define INCL_DOS
+#define INCL_WIN
+#include <os2.h>
+#include <process.h>
+
+#include "Python.h"
+
+/* use structure to pass command line to Python thread */
+typedef struct
+{
+	int argc;
+	char **argv;
+	HWND Frame;
+	int running;
+} arglist;
+
+/* make this a global to simplify access.
+ * it should only be set from the Python thread, or by the code that
+ * initiates the Python thread when the thread cannot be created.
+ */
+int PythonRC;
+
+extern DL_EXPORT(int) Py_Main(int, char **);
+void PythonThread(void *);
+
+int
+main(int argc, char **argv)
+{
+	ULONG FrameFlags = FCF_TITLEBAR |
+			   FCF_SYSMENU |
+			   FCF_SIZEBORDER |
+			   FCF_HIDEBUTTON |
+			   FCF_SHELLPOSITION |
+			   FCF_TASKLIST;
+	HAB hab;
+	HMQ hmq;
+	HWND Client;
+	QMSG qmsg;
+	arglist args;
+	int python_tid;
+
+	/* init PM and create message queue */
+	hab = WinInitialize(0);
+	hmq = WinCreateMsgQueue(hab, 0);
+
+	/* create a (hidden) Window to house the window procedure */
+	args.Frame = WinCreateStdWindow(HWND_DESKTOP,
+					0,
+					&FrameFlags,
+					NULL,
+					"PythonPM",
+					0L,
+					0,
+					0,
+					&Client);
+
+	/* run Python interpreter in a thread */
+	args.argc = argc;
+	args.argv = argv;
+	args.running = 0;
+	if (-1 == (python_tid = _beginthread(PythonThread, NULL, 1024 * 1024, &args)))
+	{
+		/* couldn't start thread */
+		WinAlarm(HWND_DESKTOP, WA_ERROR);
+		PythonRC = 1;
+	}
+	else
+	{
+		/* process PM messages, until Python exits */
+		while (WinGetMsg(hab, &qmsg, NULLHANDLE, 0, 0))
+			WinDispatchMsg(hab, &qmsg);
+		if (args.running > 0)
+			DosKillThread(python_tid);
+	}
+		
+	/* destroy window, shutdown message queue and PM */
+	WinDestroyWindow(args.Frame);
+	WinDestroyMsgQueue(hmq);
+	WinTerminate(hab);
+
+	return PythonRC;
+}
+
+void PythonThread(void *argl)
+{
+	HAB hab;
+	arglist *args;
+
+	/* PM initialisation */
+	hab = WinInitialize(0);
+
+	/* start Python */
+	args = (arglist *)argl;
+	args->running = 1;
+	PythonRC = Py_Main(args->argc, args->argv);
+
+	/* enter a critical section and send the termination message */
+	DosEnterCritSec();
+	args->running = 0;
+	WinPostMsg(args->Frame, WM_QUIT, NULL, NULL);
+
+	/* shutdown PM and terminate thread */
+	WinTerminate(hab);
+	_endthread();
+}

Added: vendor/Python/current/PC/os2vacpp/_tkinter.def
===================================================================
--- vendor/Python/current/PC/os2vacpp/_tkinter.def	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/os2vacpp/_tkinter.def	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,8 @@
+LIBRARY        _TKINTER INITINSTANCE TERMINSTANCE
+DESCRIPTION    'Python Extension DLL v1.0 for Access to Tcl/Tk Environment'
+PROTMODE
+DATA           MULTIPLE NONSHARED
+
+EXPORTS
+               init_tkinter
+

Added: vendor/Python/current/PC/os2vacpp/config.c
===================================================================
--- vendor/Python/current/PC/os2vacpp/config.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/os2vacpp/config.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,106 @@
+/* -*- C -*- ***********************************************
+Copyright (c) 2000, BeOpen.com.
+Copyright (c) 1995-2000, Corporation for National Research Initiatives.
+Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
+All rights reserved.
+
+See the file "Misc/COPYRIGHT" for information on usage and
+redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+******************************************************************/
+
+/* Module configuration */
+
+/* This file contains the table of built-in modules.
+   See init_builtin() in import.c. */
+
+#include "Python.h"
+
+extern void initarray(void);
+extern void initaudioop(void);
+extern void initbinascii(void);
+extern void initcmath(void);
+extern void initerrno(void);
+extern void initimageop(void);
+extern void initmath(void);
+extern void initmd5(void);
+extern void initnt(void);
+extern void initos2(void);
+extern void initoperator(void);
+extern void initposix(void);
+extern void initrgbimg(void);
+extern void initsignal(void);
+extern void initselect(void);
+extern void init_socket(void);
+extern void initstrop(void);
+extern void initstruct(void);
+extern void inittime(void);
+extern void initthread(void);
+extern void initcStringIO(void);
+extern void initcPickle(void);
+extern void initpcre(void);
+#ifdef WIN32
+extern void initmsvcrt(void);
+#endif
+
+/* -- ADDMODULE MARKER 1 -- */
+
+extern void PyMarshal_Init(void);
+extern void initimp(void);
+
+struct _inittab _PyImport_Inittab[] = {
+
+        {"array", initarray},
+#ifdef M_I386
+        {"audioop", initaudioop},
+#endif
+        {"binascii", initbinascii},
+        {"cmath", initcmath},
+        {"errno", initerrno},
+//        {"imageop", initimageop},
+        {"math", initmath},
+        {"md5", initmd5},
+#if defined(MS_WINDOWS) || defined(__BORLANDC__) || defined(__WATCOMC__)
+        {"nt", initnt}, /* Use the NT os functions, not posix */
+#else
+#if defined(PYOS_OS2)
+        {"os2", initos2},
+#else
+        {"posix", initposix},
+#endif
+#endif
+        {"operator", initoperator},
+//        {"rgbimg", initrgbimg},
+        {"signal", initsignal},
+#ifdef USE_SOCKET
+        {"_socket", init_socket},
+        {"select", initselect},
+#endif
+        {"strop", initstrop},
+        {"struct", initstruct},
+        {"time", inittime},
+#ifdef WITH_THREAD
+        {"thread", initthread},
+#endif
+        {"cStringIO", initcStringIO},
+        {"cPickle", initcPickle},
+        {"pcre", initpcre},
+#ifdef WIN32
+        {"msvcrt", initmsvcrt},
+#endif
+
+/* -- ADDMODULE MARKER 2 -- */
+
+        /* This module "lives in" with marshal.c */
+        {"marshal", PyMarshal_Init},
+
+        /* This lives it with import.c */
+        {"imp", initimp},
+
+        /* These entries are here for sys.builtin_module_names */
+        {"__main__", NULL},
+        {"__builtin__", NULL},
+        {"sys", NULL},
+
+        /* Sentinel */
+        {0, 0}
+};

Added: vendor/Python/current/PC/os2vacpp/getpathp.c
===================================================================
--- vendor/Python/current/PC/os2vacpp/getpathp.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/os2vacpp/getpathp.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,482 @@
+
+/* Return the initial module search path. */
+/* Used by DOS, OS/2, Windows 3.1.  Works on NT too. */
+
+#include "Python.h"
+#include "osdefs.h"
+
+#ifdef MS_WIN32
+#include <windows.h>
+extern BOOL PyWin_IsWin32s(void);
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <string.h>
+
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+/* Search in some common locations for the associated Python libraries.
+ *
+ * Two directories must be found, the platform independent directory
+ * (prefix), containing the common .py and .pyc files, and the platform
+ * dependent directory (exec_prefix), containing the shared library
+ * modules.  Note that prefix and exec_prefix can be the same directory,
+ * but for some installations, they are different.
+ *
+ * Py_GetPath() tries to return a sensible Python module search path.
+ *
+ * First, we look to see if the executable is in a subdirectory of
+ * the Python build directory.  We calculate the full path of the
+ * directory containing the executable as progpath.  We work backwards
+ * along progpath and look for $dir/Modules/Setup.in, a distinctive
+ * landmark.  If found, we use $dir/Lib as $root.  The returned
+ * Python path is the compiled #define PYTHONPATH with all the initial
+ * "./lib" replaced by $root.
+ *
+ * Otherwise, if there is a PYTHONPATH environment variable, we return that.
+ *
+ * Otherwise we try to find $progpath/lib/os.py, and if found, then
+ * root is $progpath/lib, and we return Python path as compiled PYTHONPATH
+ * with all "./lib" replaced by $root (as above).
+ *
+ */
+
+#ifndef LANDMARK
+#define LANDMARK "lib\\os.py"
+#endif
+
+static char prefix[MAXPATHLEN+1];
+static char exec_prefix[MAXPATHLEN+1];
+static char progpath[MAXPATHLEN+1];
+static char *module_search_path = NULL;
+
+
+static int
+is_sep(char ch)	/* determine if "ch" is a separator character */
+{
+#ifdef ALTSEP
+	return ch == SEP || ch == ALTSEP;
+#else
+	return ch == SEP;
+#endif
+}
+
+
+static void
+reduce(char *dir)
+{
+	int i = strlen(dir);
+	while (i > 0 && !is_sep(dir[i]))
+		--i;
+	dir[i] = '\0';
+}
+	
+
+static int
+exists(char *filename)
+{
+	struct stat buf;
+	return stat(filename, &buf) == 0;
+}
+
+
+/* Add a path component, by appending stuff to buffer.
+   buffer must have at least MAXPATHLEN + 1 bytes allocated, and contain a
+   NUL-terminated string with no more than MAXPATHLEN characters (not counting
+   the trailing NUL).  It's a fatal error if it contains a string longer than
+   that (callers must be careful!).  If these requirements are met, it's
+   guaranteed that buffer will still be a NUL-terminated string with no more
+   than MAXPATHLEN characters at exit.  If stuff is too long, only as much of
+   stuff as fits will be appended.
+*/
+static void
+join(char *buffer, char *stuff)
+{
+	int n, k;
+	if (is_sep(stuff[0]))
+		n = 0;
+	else {
+		n = strlen(buffer);
+		if (n > 0 && !is_sep(buffer[n-1]) && n < MAXPATHLEN)
+			buffer[n++] = SEP;
+	}
+	if (n > MAXPATHLEN)
+		Py_FatalError("buffer overflow in getpathp.c's joinpath()");
+	k = strlen(stuff);
+	if (n + k > MAXPATHLEN)
+		k = MAXPATHLEN - n;
+	strncpy(buffer+n, stuff, k);
+	buffer[n+k] = '\0';
+}
+
+
+static int
+search_for_prefix(char *argv0_path, char *landmark)
+{
+	int n;
+
+	/* Search from argv0_path, until root is found */
+	strcpy(prefix, argv0_path);
+	do {
+		n = strlen(prefix);
+		join(prefix, landmark);
+		if (exists(prefix)) {
+			prefix[n] = '\0';
+			return 1;
+		}
+		prefix[n] = '\0';
+		reduce(prefix);
+	} while (prefix[0]);
+	return 0;
+}
+
+#ifdef MS_WIN32
+#include "malloc.h" // for alloca - see comments below!
+extern const char *PyWin_DLLVersionString; // a string loaded from the DLL at startup.
+
+
+/* Load a PYTHONPATH value from the registry.
+   Load from either HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER.
+
+   Returns NULL, or a pointer that should be freed.
+*/
+
+static char *
+getpythonregpath(HKEY keyBase, BOOL bWin32s)
+{
+	HKEY newKey = 0;
+	DWORD nameSize = 0;
+	DWORD dataSize = 0;
+	DWORD numEntries = 0;
+	LONG rc;
+	char *retval = NULL;
+	char *dataBuf;
+	const char keyPrefix[] = "Software\\Python\\PythonCore\\";
+	const char keySuffix[] = "\\PythonPath";
+	int versionLen;
+	char *keyBuf;
+
+	// Tried to use sysget("winver") but here is too early :-(
+	versionLen = strlen(PyWin_DLLVersionString);
+	// alloca == no free required, but memory only local to fn.
+	// also no heap fragmentation!  Am I being silly?
+	keyBuf = alloca(sizeof(keyPrefix)-1 + versionLen + sizeof(keySuffix)); // chars only, plus 1 NULL.
+	// lots of constants here for the compiler to optimize away :-)
+	memcpy(keyBuf, keyPrefix, sizeof(keyPrefix)-1);
+	memcpy(keyBuf+sizeof(keyPrefix)-1, PyWin_DLLVersionString, versionLen);
+	memcpy(keyBuf+sizeof(keyPrefix)-1+versionLen, keySuffix, sizeof(keySuffix)); // NULL comes with this one!
+
+	rc=RegOpenKey(keyBase,
+		      keyBuf,
+		      &newKey);
+	if (rc==ERROR_SUCCESS) {
+		RegQueryInfoKey(newKey, NULL, NULL, NULL, NULL, NULL, NULL, 
+		                &numEntries, &nameSize, &dataSize, NULL, NULL);
+	}
+	if (bWin32s && numEntries==0 && dataSize==0) {
+		/* must hardcode for Win32s */
+		numEntries = 1;
+		dataSize = 511;
+	}
+	if (numEntries) {
+		/* Loop over all subkeys. */
+		/* Win32s doesnt know how many subkeys, so we do
+		   it twice */
+		char keyBuf[MAX_PATH+1];
+		int index = 0;
+		int off = 0;
+		for(index=0;;index++) {
+			long reqdSize = 0;
+			DWORD rc = RegEnumKey(newKey,
+					      index, keyBuf, MAX_PATH+1);
+			if (rc) break;
+			rc = RegQueryValue(newKey, keyBuf, NULL, &reqdSize);
+			if (rc) break;
+			if (bWin32s && reqdSize==0) reqdSize = 512;
+			dataSize += reqdSize + 1; /* 1 for the ";" */
+		}
+		dataBuf = malloc(dataSize+1);
+		if (dataBuf==NULL)
+			return NULL; /* pretty serious?  Raise error? */
+		/* Now loop over, grabbing the paths.
+		   Subkeys before main library */
+		for(index=0;;index++) {
+			int adjust;
+			long reqdSize = dataSize;
+			DWORD rc = RegEnumKey(newKey,
+					      index, keyBuf,MAX_PATH+1);
+			if (rc) break;
+			rc = RegQueryValue(newKey,
+					   keyBuf, dataBuf+off, &reqdSize);
+			if (rc) break;
+			if (reqdSize>1) {
+				/* If Nothing, or only '\0' copied. */
+				adjust = strlen(dataBuf+off);
+				dataSize -= adjust;
+				off += adjust;
+				dataBuf[off++] = ';';
+				dataBuf[off] = '\0';
+				dataSize--;
+			}
+		}
+		/* Additionally, win32s doesnt work as expected, so
+		   the specific strlen() is required for 3.1. */
+		rc = RegQueryValue(newKey, "", dataBuf+off, &dataSize);
+		if (rc==ERROR_SUCCESS) {
+			if (strlen(dataBuf)==0)
+				free(dataBuf);
+			else
+				retval = dataBuf; /* caller will free */
+		}
+		else
+			free(dataBuf);
+	}
+
+	if (newKey)
+		RegCloseKey(newKey);
+	return retval;
+}
+#endif /* MS_WIN32 */
+
+static void
+get_progpath(void)
+{
+	extern char *Py_GetProgramName(void);
+	char *path = getenv("PATH");
+	char *prog = Py_GetProgramName();
+
+#ifdef MS_WIN32
+	if (GetModuleFileName(NULL, progpath, MAXPATHLEN))
+		return;
+#endif
+	if (prog == NULL || *prog == '\0')
+		prog = "python";
+
+	/* If there is no slash in the argv0 path, then we have to
+	 * assume python is on the user's $PATH, since there's no
+	 * other way to find a directory to start the search from.  If
+	 * $PATH isn't exported, you lose.
+	 */
+#ifdef ALTSEP
+	if (strchr(prog, SEP) || strchr(prog, ALTSEP))
+#else
+	if (strchr(prog, SEP))
+#endif
+		strcpy(progpath, prog);
+	else if (path) {
+		while (1) {
+			char *delim = strchr(path, DELIM);
+
+			if (delim) {
+				int len = delim - path;
+				strncpy(progpath, path, len);
+				*(progpath + len) = '\0';
+			}
+			else
+				strcpy(progpath, path);
+
+			join(progpath, prog);
+			if (exists(progpath))
+				break;
+
+			if (!delim) {
+				progpath[0] = '\0';
+				break;
+			}
+			path = delim + 1;
+		}
+	}
+	else
+		progpath[0] = '\0';
+}
+
+static void
+calculate_path(void)
+{
+	char argv0_path[MAXPATHLEN+1];
+	char *buf;
+	int bufsz;
+	char *pythonhome = Py_GetPythonHome();
+	char *envpath = Py_GETENV("PYTHONPATH");
+#ifdef MS_WIN32
+	char *machinepath, *userpath;
+
+	/* Are we running under Windows 3.1(1) Win32s? */
+	if (PyWin_IsWin32s()) {
+		/* Only CLASSES_ROOT is supported */
+		machinepath = getpythonregpath(HKEY_CLASSES_ROOT, TRUE); 
+		userpath = NULL;
+	} else {
+		machinepath = getpythonregpath(HKEY_LOCAL_MACHINE, FALSE);
+		userpath = getpythonregpath(HKEY_CURRENT_USER, FALSE);
+	}
+#endif
+
+	get_progpath();
+	strcpy(argv0_path, progpath);
+	reduce(argv0_path);
+	if (pythonhome == NULL || *pythonhome == '\0') {
+		if (search_for_prefix(argv0_path, LANDMARK))
+			pythonhome = prefix;
+		else
+			pythonhome = NULL;
+	}
+	else {
+        char *delim;
+
+		strcpy(prefix, pythonhome);
+
+        /* Extract Any Optional Trailing EXEC_PREFIX */
+        /* e.g. PYTHONHOME=<prefix>:<exec_prefix>   */
+        delim = strchr(prefix, DELIM);
+        if (delim) {
+            *delim = '\0';
+            strcpy(exec_prefix, delim+1);
+        } else
+            strcpy(exec_prefix, EXEC_PREFIX);
+    }
+
+	if (envpath && *envpath == '\0')
+		envpath = NULL;
+
+	/* We need to construct a path from the following parts:
+	   (1) the PYTHONPATH environment variable, if set;
+	   (2) for Win32, the machinepath and userpath, if set;
+	   (3) the PYTHONPATH config macro, with the leading "."
+	       of each component replaced with pythonhome, if set;
+	   (4) the directory containing the executable (argv0_path).
+	   The length calculation calculates #3 first.
+	*/
+
+	/* Calculate size of return buffer */
+	if (pythonhome != NULL) {
+		char *p;
+		bufsz = 1;	
+		for (p = PYTHONPATH; *p; p++) {
+			if (*p == DELIM)
+				bufsz++; /* number of DELIM plus one */
+		}
+		bufsz *= strlen(pythonhome);
+	}
+	else
+		bufsz = 0;
+	bufsz += strlen(PYTHONPATH) + 1;
+	if (envpath != NULL)
+		bufsz += strlen(envpath) + 1;
+	bufsz += strlen(argv0_path) + 1;
+#ifdef MS_WIN32
+	if (machinepath)
+		bufsz += strlen(machinepath) + 1;
+	if (userpath)
+		bufsz += strlen(userpath) + 1;
+#endif
+
+	module_search_path = buf = malloc(bufsz);
+	if (buf == NULL) {
+		/* We can't exit, so print a warning and limp along */
+		fprintf(stderr, "Can't malloc dynamic PYTHONPATH.\n");
+		if (envpath) {
+			fprintf(stderr, "Using default static $PYTHONPATH.\n");
+			module_search_path = envpath;
+		}
+		else {
+			fprintf(stderr, "Using environment $PYTHONPATH.\n");
+			module_search_path = PYTHONPATH;
+		}
+		return;
+	}
+
+	if (envpath) {
+		strcpy(buf, envpath);
+		buf = strchr(buf, '\0');
+		*buf++ = DELIM;
+	}
+#ifdef MS_WIN32
+	if (machinepath) {
+		strcpy(buf, machinepath);
+		buf = strchr(buf, '\0');
+		*buf++ = DELIM;
+	}
+	if (userpath) {
+		strcpy(buf, userpath);
+		buf = strchr(buf, '\0');
+		*buf++ = DELIM;
+	}
+#endif
+	if (pythonhome == NULL) {
+		strcpy(buf, PYTHONPATH);
+		buf = strchr(buf, '\0');
+	}
+	else {
+		char *p = PYTHONPATH;
+		char *q;
+		int n;
+		for (;;) {
+			q = strchr(p, DELIM);
+			if (q == NULL)
+				n = strlen(p);
+			else
+				n = q-p;
+			if (p[0] == '.' && is_sep(p[1])) {
+				strcpy(buf, pythonhome);
+				buf = strchr(buf, '\0');
+				p++;
+				n--;
+			}
+			strncpy(buf, p, n);
+			buf += n;
+			if (q == NULL)
+				break;
+			*buf++ = DELIM;
+			p = q+1;
+		}
+	}
+	if (argv0_path) {
+		*buf++ = DELIM;
+		strcpy(buf, argv0_path);
+		buf = strchr(buf, '\0');
+	}
+	*buf = '\0';
+}
+
+
+/* External interface */
+
+char *
+Py_GetPath(void)
+{
+	if (!module_search_path)
+		calculate_path();
+
+	return module_search_path;
+}
+
+char *
+Py_GetPrefix(void)
+{
+	if (!module_search_path)
+		calculate_path();
+
+	return prefix;
+}
+
+char *
+Py_GetExecPrefix(void)
+{
+	if (!module_search_path)
+		calculate_path();
+
+	return exec_prefix;
+}
+
+char *
+Py_GetProgramFullPath(void)
+{
+	if (!module_search_path)
+		calculate_path();
+
+	return progpath;
+}

Added: vendor/Python/current/PC/os2vacpp/makefile
===================================================================
--- vendor/Python/current/PC/os2vacpp/makefile	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/os2vacpp/makefile	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1886 @@
+######################################################################
+#
+#          Top-Level Makefile for Building Python for OS/2
+#
+# This makefile was developed for use with IBM's VisualAge C/C++
+# for OS/2 compiler, version 3.0, with Fixpack 8 applied.  It uses
+# version 4.0 of the NMAKE tool that comes with that package.
+#
+# The output of the build is a largish Python23.DLL containing the
+# essential modules of Python and a small Python.exe program to start
+# the interpreter.  When embedding Python within another program, only
+# Python23.DLL is needed.
+#
+# These two binaries can be statically linked with the VisualAge C/C++
+# runtime library (producing larger binaries), or dynamically linked
+# to make smaller ones that require the compiler to be installed on
+# any system Python is used on.  Review the /Gd+ compiler option for
+# how to do this.
+#
+# NOTE: IBM's NMAKE 4.0 is rather dumb, requiring this makefile to
+#       be much more complicated than necessary.  I use OpusMAKE
+#       myself for a much more powerful MAKE tool but not everyone
+#       wishes to buy it.  However, as a result I didn't hook in
+#       the dependencies on the include files as NMAKE has no easy
+#       way to do this without explicitly spelling it all out.
+#
+# History (Most Recent First)
+#
+# 26-Sep-98 jrr Retested and adjusted for building w/Python 1.5.2a1
+# 20-Nov-97 jrr Cleaned Up for Applying to Distribution
+# 29-Oct-97 jrr Modified for Use with Python 1.5 Alpha 4
+# 03-Aug-96 jrr Original for Use with Python 1.4 Release
+#
+######################################################################
+
+###################
+# Places and Things
+###################
+PY_MODULES      = ..\..\Modules
+PY_OBJECTS      = ..\..\Objects
+PY_PARSER       = ..\..\Parser
+PY_PYTHON       = ..\..\Python
+PY_INCLUDE      = ..\..\Include
+PY_INCLUDES     = .;$(PY_INCLUDE);$(PY_MODULES);$(PY_OBJECTS);$(PY_PARSER);$(PY_PYTHON)
+
+# File to Collect Wordy Compiler Output re Errors
+ERRS		= make.out
+
+# Where to Find the IBM TCP/IP Socket Includes and Libraries
+OS2TCPIP        = C:\MPTN
+
+# Where to Find the Tcl/Tk Base Directory for Libs/Includes
+TCLTK		= D:\TclTk
+TCLBASE		= D:\Tcl7.6\OS2
+TKBASE		= D:\Tk4.2\OS2
+
+# Where to Put the .OBJ Files, To Keep Them Out of the Way
+PATHOBJ		= obj
+
+# Search Path for Include Files
+PROJINCLUDE	= .;$(TCLBASE);$(TKBASE);$(OS2TCPIP)\Include;$(PY_INCLUDES)
+
+# Place to Search for Sources re OpusMAKE Dependency Generator (Commercial)
+MKMF_SRCS	= $(PY_MODULES)\*.c $(PY_OBJECTS)\*.c $(PY_PARSER)\*.c $(PY_PYTHON)\*.c
+
+#.HDRPATH.c	:= $(PROJINCLUDE,;= ) $(.HDRPATH.c)
+#.PATH.c         = .;$(PY_MODULES);$(PY_OBJECTS);$(PY_PARSER);$(PY_PYTHON)
+OTHERLIBS	= so32dll.lib tcp32dll.lib # Tcl76.lib Tk42.lib
+
+#################
+# Inference Rules
+#################
+{$(PY_MODULES)\}.c{$(PATHOBJ)\}.obj:	# Compile C Code into a .OBJ File
+	@ Echo Compiling $<
+	@ $(CC) -c $(CFLAGS) -Fo$@ $< >>$(ERRS)
+
+{$(PY_OBJECTS)\}.c{$(PATHOBJ)\}.obj:	# Compile C Code into a .OBJ File
+	@ Echo Compiling $<
+	@ $(CC) -c $(CFLAGS) -Fo$@ $< >>$(ERRS)
+
+{$(PY_PARSER)\}.c{$(PATHOBJ)\}.obj:	# Compile C Code into a .OBJ File
+	@ Echo Compiling $<
+	@ $(CC) -c $(CFLAGS) -Fo$@ $< >>$(ERRS)
+
+{$(PY_PYTHON)\}.c{$(PATHOBJ)\}.obj:	# Compile C Code into a .OBJ File
+	@ Echo Compiling $<
+	@ $(CC) -c $(CFLAGS) -Fo$@ $< >>$(ERRS)
+
+.c{$(PATHOBJ)\}.obj:			# Compile C Code into a .OBJ File
+	@ Echo Compiling $<
+	@ $(CC) -c $(CFLAGS) -Fo$@ $< >>$(ERRS)
+
+###################
+# Python Subsystems
+###################
+
+# PYTHON is the central core, containing the builtins and interpreter.
+PYTHON		=                               \
+                  $(PATHOBJ)\BltinModule.obj    \
+                  $(PATHOBJ)\CEval.obj          \
+                  $(PATHOBJ)\Compile.obj        \
+                  $(PATHOBJ)\Errors.obj         \
+                  $(PATHOBJ)\Frozen.obj         \
+                  $(PATHOBJ)\Getargs.obj        \
+                  $(PATHOBJ)\GetCompiler.obj    \
+                  $(PATHOBJ)\GetCopyright.obj   \
+                  $(PATHOBJ)\GetMTime.obj       \
+                  $(PATHOBJ)\GetOpt.obj         \
+                  $(PATHOBJ)\GetPlatform.obj    \
+                  $(PATHOBJ)\GetVersion.obj     \
+                  $(PATHOBJ)\GramInit.obj       \
+                  $(PATHOBJ)\Import.obj         \
+                  $(PATHOBJ)\ImportDL.obj       \
+                  $(PATHOBJ)\Marshal.obj        \
+                  $(PATHOBJ)\ModSupport.obj     \
+                  $(PATHOBJ)\MyStrtoul.obj      \
+                  $(PATHOBJ)\PyState.obj        \
+                  $(PATHOBJ)\PythonRun.obj      \
+                  $(PATHOBJ)\StructMember.obj   \
+                  $(PATHOBJ)\SysModule.obj      \
+                  $(PATHOBJ)\Thread.obj         \
+                  $(PATHOBJ)\TraceBack.obj      \
+                  $(PATHOBJ)\FrozenMain.obj     \
+                  $(PATHOBJ)\exceptions.obj     \
+                  $(PATHOBJ)\symtable.obj       \
+                  $(PATHOBJ)\codecs.obj         \
+                  $(PATHOBJ)\future.obj         \
+                  $(PATHOBJ)\dynload_os2.obj    \
+                  $(PATHOBJ)\mysnprintf.obj     \
+                  $(PATHOBJ)\iterobject.obj
+
+# Python's Internal Parser
+PARSER		=                              \
+                  $(PATHOBJ)\Acceler.obj       \
+                  $(PATHOBJ)\Grammar1.obj      \
+                  $(PATHOBJ)\ListNode.obj      \
+                  $(PATHOBJ)\Node.obj          \
+                  $(PATHOBJ)\Parser.obj        \
+                  $(PATHOBJ)\ParseTok.obj      \
+                  $(PATHOBJ)\BitSet.obj        \
+                  $(PATHOBJ)\MetaGrammar.obj   \
+                  $(PATHOBJ)\Tokenizer.obj     \
+                  $(PATHOBJ)\MyReadline.obj
+
+# Python Object Types
+OBJECTS		=                              \
+                  $(PATHOBJ)\Abstract.obj      \
+                  $(PATHOBJ)\BoolObject.obj    \
+                  $(PATHOBJ)\BufferObject.obj  \
+                  $(PATHOBJ)\CellObject.obj    \
+                  $(PATHOBJ)\ClassObject.obj   \
+                  $(PATHOBJ)\CObject.obj       \
+                  $(PATHOBJ)\ComplexObject.obj \
+                  $(PATHOBJ)\DescrObject.obj   \
+                  $(PATHOBJ)\DictObject.obj    \
+                  $(PATHOBJ)\EnumObject.obj    \
+                  $(PATHOBJ)\FileObject.obj    \
+                  $(PATHOBJ)\FloatObject.obj   \
+                  $(PATHOBJ)\FrameObject.obj   \
+                  $(PATHOBJ)\FuncObject.obj    \
+                  $(PATHOBJ)\IntObject.obj     \
+                  $(PATHOBJ)\IterObject.obj    \
+                  $(PATHOBJ)\ListObject.obj    \
+                  $(PATHOBJ)\LongObject.obj    \
+                  $(PATHOBJ)\MethodObject.obj  \
+                  $(PATHOBJ)\ModuleObject.obj  \
+                  $(PATHOBJ)\Object.obj        \
+                  $(PATHOBJ)\ObMalloc.obj      \
+                  $(PATHOBJ)\RangeObject.obj   \
+                  $(PATHOBJ)\SliceObject.obj   \
+                  $(PATHOBJ)\StringObject.obj  \
+                  $(PATHOBJ)\StructSeq.obj     \
+                  $(PATHOBJ)\TupleObject.obj   \
+                  $(PATHOBJ)\TypeObject.obj    \
+                  $(PATHOBJ)\UnicodeObject.obj \
+                  $(PATHOBJ)\UnicodeCType.obj  \
+                  $(PATHOBJ)\WeakrefObject.obj
+
+# Extension Modules (Built-In or as Separate DLLs)
+MODULES		=                              \
+                  $(PATHOBJ)\ArrayModule.obj   \
+                  $(PATHOBJ)\BinAscii.obj      \
+                  $(PATHOBJ)\CMathModule.obj   \
+                  $(PATHOBJ)\cPickle.obj       \
+                  $(PATHOBJ)\cStringIO.obj     \
+                  $(PATHOBJ)\ErrnoModule.obj   \
+                  $(PATHOBJ)\GCModule.obj      \
+                  $(PATHOBJ)\GetBuildInfo.obj  \
+                  $(PATHOBJ)\GetPathP.obj      \
+                  $(PATHOBJ)\Main.obj          \
+                  $(PATHOBJ)\MathModule.obj    \
+                  $(PATHOBJ)\MD5c.obj          \
+                  $(PATHOBJ)\MD5Module.obj     \
+                  $(PATHOBJ)\Operator.obj      \
+                  $(PATHOBJ)\PCREModule.obj    \
+                  $(PATHOBJ)\PyPCRE.obj        \
+                  $(PATHOBJ)\PosixModule.obj   \
+                  $(PATHOBJ)\RegexModule.obj   \
+                  $(PATHOBJ)\RegExpr.obj       \
+                  $(PATHOBJ)\SelectModule.obj  \
+                  $(PATHOBJ)\SignalModule.obj  \
+                  $(PATHOBJ)\SocketModule.obj  \
+                  $(PATHOBJ)\StropModule.obj   \
+                  $(PATHOBJ)\StructModule.obj  \
+                  $(PATHOBJ)\TimeModule.obj    \
+                  $(PATHOBJ)\ThreadModule.obj  \
+                  $(PATHOBJ)\YUVConvert.obj
+
+# Standalone Parser Generator Program (Shares Some of Python's Modules)
+PGEN            =                              \
+                  $(PATHOBJ)\PGen.obj          \
+                  $(PATHOBJ)\PGenMain.obj      \
+                  $(PATHOBJ)\MySNPrintf.obj    \
+                  $(PATHOBJ)\Tokenizer_Pgen.obj \
+                  $(PATHOBJ)\PrintGrammar.obj  \
+                  $(PATHOBJ)\Grammar.obj       \
+                  $(PATHOBJ)\FirstSets.obj
+
+##################
+# Macros and Flags
+##################
+_BASE		= /Q /W2 /I$(PROJINCLUDE)
+		# /Q   = Omit IBM Copyright
+		# /W2  = Show Warnings/Errors Only
+
+_GEN		= /G4 /Gm /Gd-
+		# /G4  = Generate Code for 486 (Use 386 for Debugger)
+		# /Gm  = Use Multithread Runtime
+		# /Gd  = Dynamically Load Runtime
+		# /Ms  = Use _System Calling Convention (vs _Optlink)
+		#        (to allow non-VAC++ code to call into Python23.dll)
+
+_OPT		= /O /Gl
+		# /O   = Enable Speed-Optimizations
+		# /Ol  = Pass Code Thru Intermediate Linker
+		# /Gu  = Advise Linker All Ext Data is ID'd
+		# /Gl  = Have Linker Remove Unused Fns
+
+_DBG		= /Wpro- /Ti- /DHAVE_CONFIG_H /DUSE_SOCKET
+                # /Wpro= Generate Compiler Warnings re Missing Prototypes
+		# /Ti  = Embed Debugger/Analyzer Recs
+		# /Tm  = Enable Debug Memory Fns
+		# /Tx  = Request Full Dump Upon Exception
+		# /DHAVE_CONFIG_H = Causes Use of CONFIG.H Settings
+                # /DUSE_SOCKET = Enables Building In of Socket API
+
+_OUT		= 
+		# /Fb  = Embed Browser Recs
+		# /Gh  = Generate Code for Profiler Hooks
+		# /Fl  = Output C/C++ Listing Files
+                # /Lf  = Provide Full (Detailed) Listing Files
+		# /Fm. = Output Linker Map File
+		# /Ft. = Output C++ Template Resolution Files
+
+_MAP		= /FmNoise\$(@R).map
+
+_DLL		= /Ge-
+_EXE		= /Ge
+		# /Ge = Create an EXE, not DLL
+
+CFLAGS		= $(_BASE) $(_GEN) $(_OPT) $(_DBG) $(_OUT) $(_EXE) /Ss
+
+###################
+# Primary Target(s)
+###################
+All:  obj noise PyCore.lib Python23.lib PGen.exe \
+      Python.exe PythonPM.exe Python23.dll # _tkinter.dll
+
+Modules: $(MODULES)
+Objects: $(OBJECTS)
+Parser:  $(PARSER)
+Python:  $(PYTHON)
+
+# Directory to Keep .OBJ Files Out of the Way
+obj:
+	@-mkdir obj >>NUL
+
+# Directory to Keep .MAP and Such Text Files Out of the Way
+noise:
+	@-mkdir noise >>NUL
+
+##############
+#
+##############
+
+# Python Extension DLL: Tcl/Tk Interface
+#_tkinter.dll: $(PATHOBJ)\_tkinter.obj Python23.lib _tkinter.def
+#	@ Echo Linking $@ As DLL
+#	@ $(CC) $(CFLAGS) /B"/NOE" $(_DLL) /Fe$@ $(_MAP) $** $(OTHERLIBS) >>$(ERRS)
+
+#$(PATHOBJ)\_tkinter.obj: $(PY_MODULES)\_tkinter.c
+#	@ Echo Compiling $**
+#	@ $(CC) -c $(CFLAGS) $(_DLL) -Fo$@ $** >>$(ERRS)
+
+# Object Library of All Essential Python Routines
+PyCore.lib: $(MODULES) $(OBJECTS) $(PARSER) $(PYTHON) $(PATHOBJ)\Config.obj
+	@ Echo Adding Updated Object Files to Link Library $@
+	@ ! ILIB $@ /NOLOGO /NOBACKUP -+$? ; >>$(ERRS)
+
+Python23.dll: $(PATHOBJ)\Compile.obj PyCore.lib Python.def
+	@ Echo Linking $@ As DLL
+	@ $(CC) $(CFLAGS) /B"/NOE" $(_DLL) /Fe$@ $(_MAP) $** $(OTHERLIBS) >>$(ERRS)
+#	@ Echo Compressing $@ with LxLite
+#	@ lxlite $@
+
+# IBM Linker Requires One Explicit .OBJ To Build a .DLL from a .LIB
+$(PATHOBJ)\Compile.obj: $(PY_PYTHON)\Compile.c
+	@ Echo Compiling $**
+	@ $(CC) -c $(CFLAGS) $(_DLL) -Fo$@ $** >>$(ERRS)
+
+# Import Library for Using the Python23.dll
+Python23.lib: Python.def
+	@ Echo Making $@
+	@ IMPLIB /NOLOGO /NOIGNORE $@ $** >>$(ERRS)
+	@ ILIB /NOLOGO /CONVFORMAT /NOEXTDICTIONARY /NOBROWSE /NOBACKUP $@; >>$(ERRS)
+
+# Small Command-Line Program to Start Interpreter in Python23.dll
+Python.exe: $(PATHOBJ)\Python.obj Python23.lib
+	@ Echo Linking $@ As EXE
+	@ $(CC) $(CFLAGS) $(_EXE) /B"/PM:VIO /STACK:360000" /Fe$@ $(_MAP) $** $(OTHERLIBS) >>$(ERRS)
+
+# Small PM-GUI Program to Start Interpreter in Python23.dll
+PythonPM.exe: $(PATHOBJ)\Python.obj Python23.lib
+	@ Echo Linking $@ As EXE
+	@ $(CC) $(CFLAGS) $(_EXE) /B"/PM:PM /STACK:360000" /Fe$@ $(_MAP) $** $(OTHERLIBS) >>$(ERRS)
+
+PGen.exe: $(PGEN) PyCore.lib
+	@ Echo Linking $@ As EXE
+	@ $(CC) $(CFLAGS) $(_EXE) /B"/STACK:360000" /Fe$@ $(_MAP) $** $(OTHERLIBS) >>$(ERRS)
+
+#######################
+# Miscellaneous Targets
+#######################
+
+# Remove Intermediate Targets but Leave Executable Binaries
+clean:
+	-- Del /Q $(PATHOBJ)\*.obj		>NUL 2>&1
+	-- Del /Q /Y Noise			>NUL 2>&1
+	-- Del /Q $(ERRS)			>NUL 2>&1
+
+# Remove All Targets, Including Final Binaries
+distclean: clean
+        -- Del /Q PyCore.lib Python23.lib       >NUL 2>&1
+        -- Del /Q Python23.dll Python.exe PGen.exe >NUL 2>&1
+
+release: Python.exe Python23.dll Python23.lib
+	-- @Echo Y | copy /U Python.exe   D:\EXEs
+	-- @Echo Y | copy /U Python23.dll D:\DLLs
+	-- @Echo Y | copy /U Python23.lib E:\Tau\Lib
+	-- @Echo Y | copy /U _tkinter.dll D:\Python
+
+test:
+        python ..\..\lib\test\regrtest.py
+
+# Update Dependencies on Targets (Uses OpusMAKE Commercial Product)
+depend:
+	D:\OpusMake\os2mkmf -c -s
+
+### OPUS MKMF:  Do not remove this line!  Generated dependencies follow.
+
+_tkinter.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h \
+	 $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h \
+	 $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h \
+	 $(PY_INCLUDE)\sliceobject.h $(PY_INCLUDE)\stringobject.h \
+	 $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+almodule.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h \
+	 $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h \
+	 $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h \
+	 $(PY_INCLUDE)\sliceobject.h $(PY_INCLUDE)\stringobject.h \
+	 $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+arraymodule.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h \
+	 $(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h \
+	 pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
+	 $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h \
+	 $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
+	 $(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\methodobject.h \
+	 $(PY_INCLUDE)\modsupport.h $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h \
+	 $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h \
+	 $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h \
+	 $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h \
+	 $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
+	 $(PY_INCLUDE)\tupleobject.h
+
+audioop.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\mymath.h \
+	 $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h \
+	 $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h \
+	 $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h \
+	 $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
+	 $(PY_INCLUDE)\tupleobject.h
+
+binascii.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h \
+	 $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h \
+	 $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h \
+	 $(PY_INCLUDE)\sliceobject.h $(PY_INCLUDE)\stringobject.h \
+	 $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+bsddbmodule.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h \
+	 $(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h \
+	 pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
+	 $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h \
+	 $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
+	 $(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\methodobject.h \
+	 $(PY_INCLUDE)\modsupport.h $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h \
+	 $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h \
+	 $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h \
+	 $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h \
+	 $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
+	 $(PY_INCLUDE)\tupleobject.h
+
+cdmodule.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h \
+	 $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h \
+	 $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h \
+	 $(PY_INCLUDE)\sliceobject.h $(PY_INCLUDE)\stringobject.h \
+	 $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+cgensupport.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h \
+	 $(PY_MODULES)\cgensupport.h $(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h \
+	 $(PY_INCLUDE)\complexobject.h pyconfig.h $(PY_INCLUDE)\dictobject.h \
+	 $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h \
+	 $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h \
+	 $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h \
+	 $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h \
+	 $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h \
+	 $(PY_INCLUDE)\sliceobject.h $(PY_INCLUDE)\stringobject.h \
+	 $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+clmodule.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h \
+	 $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h \
+	 $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h \
+	 $(PY_INCLUDE)\sliceobject.h $(PY_INCLUDE)\stringobject.h \
+	 $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+cmathmodule.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h \
+	 $(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h \
+	 pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
+	 $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h \
+	 $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
+	 $(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\methodobject.h \
+	 $(PY_INCLUDE)\modsupport.h $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h \
+	 $(PY_INCLUDE)\mymath.h $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\object.h \
+	 $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h \
+	 $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h \
+	 $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
+	 $(PY_INCLUDE)\tupleobject.h
+
+cpickle.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\cstringio.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
+	 $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h \
+	 $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
+	 $(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\methodobject.h \
+	 $(PY_INCLUDE)\modsupport.h $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h \
+	 $(PY_INCLUDE)\mymath.h $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\object.h \
+	 $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h \
+	 $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h \
+	 $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
+	 $(PY_INCLUDE)\tupleobject.h
+
+cryptmodule.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h \
+	 $(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h \
+	 pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
+	 $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h \
+	 $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
+	 $(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\methodobject.h \
+	 $(PY_INCLUDE)\modsupport.h $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h \
+	 $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h \
+	 $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h \
+	 $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h \
+	 $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
+	 $(PY_INCLUDE)\tupleobject.h
+
+cstringio.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\cstringio.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
+	 $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h \
+	 $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
+	 $(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\methodobject.h \
+	 $(PY_INCLUDE)\modsupport.h $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h \
+	 $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h \
+	 $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h \
+	 $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h \
+	 $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
+	 $(PY_INCLUDE)\tupleobject.h
+
+cursesmodule.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h \
+	 $(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h \
+	 pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
+	 $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h \
+	 $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
+	 $(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\methodobject.h \
+	 $(PY_INCLUDE)\modsupport.h $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h \
+	 $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h \
+	 $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h \
+	 $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h \
+	 $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
+	 $(PY_INCLUDE)\tupleobject.h
+
+dbmmodule.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h \
+	 $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h \
+	 $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h \
+	 $(PY_INCLUDE)\sliceobject.h $(PY_INCLUDE)\stringobject.h \
+	 $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+dlmodule.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h \
+	 $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h \
+	 $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h \
+	 $(PY_INCLUDE)\sliceobject.h $(PY_INCLUDE)\stringobject.h \
+	 $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+errno.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h \
+	 $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h \
+	 $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h \
+	 $(PY_INCLUDE)\sliceobject.h $(PY_INCLUDE)\stringobject.h \
+	 $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+errnomodule.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h \
+	 $(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h \
+	 pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
+	 $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h \
+	 $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
+	 $(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\methodobject.h \
+	 $(PY_INCLUDE)\modsupport.h $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h \
+	 $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h \
+	 $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h \
+	 $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h \
+	 $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
+	 $(PY_INCLUDE)\tupleobject.h
+
+fcntlmodule.obj: $(PY_INCLUDE)\abstract.h $(OS2TCPIP)\Include\sys\ioctl.h $(PY_INCLUDE)\ceval.h \
+	 $(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h \
+	 pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
+	 $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h \
+	 $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
+	 $(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\methodobject.h \
+	 $(PY_INCLUDE)\modsupport.h $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h \
+	 $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h \
+	 $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h \
+	 $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h \
+	 $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
+	 $(PY_INCLUDE)\tupleobject.h
+
+flmodule.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h \
+	 $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h \
+	 $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h \
+	 $(PY_INCLUDE)\sliceobject.h $(PY_INCLUDE)\stringobject.h \
+	 $(PY_INCLUDE)\structmember.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
+	 $(PY_INCLUDE)\tupleobject.h
+
+fmmodule.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h \
+	 $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h \
+	 $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h \
+	 $(PY_INCLUDE)\sliceobject.h $(PY_INCLUDE)\stringobject.h \
+	 $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+fpectlmodule.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h \
+	 $(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h \
+	 pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
+	 $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h \
+	 $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
+	 $(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\methodobject.h \
+	 $(PY_INCLUDE)\modsupport.h $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h \
+	 $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h \
+	 $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h \
+	 $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h \
+	 $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
+	 $(PY_INCLUDE)\tupleobject.h
+
+fpetestmodule.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h \
+	 $(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h \
+	 pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
+	 $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h \
+	 $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
+	 $(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\methodobject.h \
+	 $(PY_INCLUDE)\modsupport.h $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h \
+	 $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h \
+	 $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h \
+	 $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h \
+	 $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
+	 $(PY_INCLUDE)\tupleobject.h
+
+gdbmmodule.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h \
+	 $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h \
+	 $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h \
+	 $(PY_INCLUDE)\sliceobject.h $(PY_INCLUDE)\stringobject.h \
+	 $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+getbuildinfo.obj: pyconfig.h
+
+getpath.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\osdefs.h \
+	 $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h \
+	 $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h \
+	 $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
+	 $(PY_INCLUDE)\tupleobject.h
+
+glmodule.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_MODULES)\cgensupport.h \
+	 $(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h \
+	 pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
+	 $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h \
+	 $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
+	 $(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\methodobject.h \
+	 $(PY_INCLUDE)\modsupport.h $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h \
+	 $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h \
+	 $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h \
+	 $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h \
+	 $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
+	 $(PY_INCLUDE)\tupleobject.h
+
+grpmodule.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(OS2TCPIP)\Include\grp.h $(PY_INCLUDE)\import.h \
+	 $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
+	 $(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\methodobject.h \
+	 $(PY_INCLUDE)\modsupport.h $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h \
+	 $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h \
+	 $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h \
+	 $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h \
+	 $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
+	 $(PY_INCLUDE)\tupleobject.h
+
+imageop.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h \
+	 $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h \
+	 $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h \
+	 $(PY_INCLUDE)\sliceobject.h $(PY_INCLUDE)\stringobject.h \
+	 $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+imgfile.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h \
+	 $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h \
+	 $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h \
+	 $(PY_INCLUDE)\sliceobject.h $(PY_INCLUDE)\stringobject.h \
+	 $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+main.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h \
+	 $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h \
+	 $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h \
+	 $(PY_INCLUDE)\sliceobject.h $(PY_INCLUDE)\stringobject.h \
+	 $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+mathmodule.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\mymath.h \
+	 $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h \
+	 $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h \
+	 $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h \
+	 $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
+	 $(PY_INCLUDE)\tupleobject.h
+
+md5c.obj: pyconfig.h $(PY_MODULES)\md5.h
+
+md5module.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_MODULES)\md5.h $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h \
+	 $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h \
+	 $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h \
+	 $(PY_INCLUDE)\sliceobject.h $(PY_INCLUDE)\stringobject.h \
+	 $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+mpzmodule.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h \
+	 $(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h \
+	 pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
+	 $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h \
+	 $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
+	 $(PY_INCLUDE)\longintrepr.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h \
+	 $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h \
+	 $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h \
+	 $(PY_INCLUDE)\sliceobject.h $(PY_INCLUDE)\stringobject.h \
+	 $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+nismodule.obj: $(PY_INCLUDE)\abstract.h $(OS2TCPIP)\Include\sys\time.h $(PY_INCLUDE)\ceval.h \
+	 $(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h \
+	 pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
+	 $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h \
+	 $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
+	 $(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\methodobject.h \
+	 $(PY_INCLUDE)\modsupport.h $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h \
+	 $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h \
+	 $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h \
+	 $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h \
+	 $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
+	 $(PY_INCLUDE)\tupleobject.h
+
+operator.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h \
+	 $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h \
+	 $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h \
+	 $(PY_INCLUDE)\sliceobject.h $(PY_INCLUDE)\stringobject.h \
+	 $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+parsermodule.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h \
+	 $(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\compile.h \
+	 $(PY_INCLUDE)\complexobject.h pyconfig.h $(PY_INCLUDE)\dictobject.h \
+	 $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h \
+	 $(PY_INCLUDE)\graminit.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\node.h $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h \
+	 $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h \
+	 $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h \
+	 $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\token.h \
+	 $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+pcremodule.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(PY_MODULES)\pcre-internal.h \
+	 $(PY_MODULES)\pcre.h $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h \
+	 $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h \
+	 $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
+	 $(PY_INCLUDE)\tupleobject.h
+
+posix.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\mytime.h $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h \
+	 $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h \
+	 $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h \
+	 $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
+	 $(PY_INCLUDE)\tupleobject.h
+
+posixmodule.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h \
+	 $(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h \
+	 pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
+	 $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h \
+	 $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
+	 $(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\methodobject.h \
+	 $(PY_INCLUDE)\modsupport.h $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h \
+	 $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\mytime.h $(PY_INCLUDE)\object.h \
+	 $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h \
+	 $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h \
+	 $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
+	 $(PY_INCLUDE)\tupleobject.h
+
+puremodule.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h \
+	 $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h \
+	 $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h \
+	 $(PY_INCLUDE)\sliceobject.h $(PY_INCLUDE)\stringobject.h \
+	 $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+pwdmodule.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(OS2TCPIP)\Include\pwd.h \
+	 $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h \
+	 $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h \
+	 $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
+	 $(PY_INCLUDE)\tupleobject.h
+
+pypcre.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\graminit.h $(PY_INCLUDE)\import.h \
+	 $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
+	 $(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\methodobject.h \
+	 $(PY_INCLUDE)\modsupport.h $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h \
+	 $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h \
+	 $(PY_MODULES)\pcre-internal.h $(PY_MODULES)\pcre.h $(PY_INCLUDE)\pydebug.h \
+	 $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h \
+	 $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h \
+	 $(PY_INCLUDE)\sliceobject.h $(PY_INCLUDE)\stringobject.h \
+	 $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+readline.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h \
+	 $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h \
+	 $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h \
+	 $(PY_INCLUDE)\sliceobject.h $(PY_INCLUDE)\stringobject.h \
+	 $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+resource.obj: $(PY_INCLUDE)\abstract.h $(OS2TCPIP)\Include\sys\time.h $(PY_INCLUDE)\ceval.h \
+	 $(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h \
+	 pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
+	 $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h \
+	 $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
+	 $(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\methodobject.h \
+	 $(PY_INCLUDE)\modsupport.h $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h \
+	 $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h \
+	 $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h \
+	 $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h \
+	 $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
+	 $(PY_INCLUDE)\tupleobject.h
+
+rgbimgmodule.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h \
+	 $(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h \
+	 pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
+	 $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h \
+	 $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
+	 $(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\methodobject.h \
+	 $(PY_INCLUDE)\modsupport.h $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h \
+	 $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h \
+	 $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h \
+	 $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h \
+	 $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
+	 $(PY_INCLUDE)\tupleobject.h
+
+selectmodule.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h \
+	 $(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h \
+	 pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
+	 $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h \
+	 $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
+	 $(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\methodobject.h \
+	 $(PY_INCLUDE)\modsupport.h $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h \
+	 $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\myselect.h $(PY_INCLUDE)\mytime.h \
+	 $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h \
+	 $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h \
+	 $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h \
+	 $(PY_INCLUDE)\sliceobject.h $(PY_INCLUDE)\stringobject.h \
+	 $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+sgimodule.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h \
+	 $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h \
+	 $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h \
+	 $(PY_INCLUDE)\sliceobject.h $(PY_INCLUDE)\stringobject.h \
+	 $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+signalmodule.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h \
+	 $(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h \
+	 pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
+	 $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h \
+	 $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
+	 $(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\methodobject.h \
+	 $(PY_INCLUDE)\modsupport.h $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h \
+	 $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h \
+	 $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h \
+	 $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h \
+	 $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
+	 $(PY_INCLUDE)\tupleobject.h
+
+socketmodule.obj: $(PY_INCLUDE)\abstract.h $(OS2TCPIP)\Include\netinet\in.h \
+	 $(OS2TCPIP)\Include\sys\socket.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\mytime.h $(OS2TCPIP)\Include\netdb.h $(PY_INCLUDE)\object.h \
+	 $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h \
+	 $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h \
+	 $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
+	 $(PY_INCLUDE)\tupleobject.h
+
+soundex.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h \
+	 $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h \
+	 $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h \
+	 $(PY_INCLUDE)\sliceobject.h $(PY_INCLUDE)\stringobject.h \
+	 $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+stdwinmodule.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h \
+	 $(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h \
+	 pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
+	 $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h \
+	 $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
+	 $(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\methodobject.h \
+	 $(PY_INCLUDE)\modsupport.h $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h \
+	 $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h \
+	 $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h \
+	 $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h \
+	 $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
+	 $(PY_INCLUDE)\tupleobject.h
+
+stropmodule.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h \
+	 $(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h \
+	 pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
+	 $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h \
+	 $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
+	 $(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\methodobject.h \
+	 $(PY_INCLUDE)\modsupport.h $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h \
+	 $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h \
+	 $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h \
+	 $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h \
+	 $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
+	 $(PY_INCLUDE)\tupleobject.h
+
+structmodule.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h \
+	 $(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h \
+	 pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
+	 $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h \
+	 $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
+	 $(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\methodobject.h \
+	 $(PY_INCLUDE)\modsupport.h $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h \
+	 $(PY_INCLUDE)\mymath.h $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\object.h \
+	 $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h \
+	 $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h \
+	 $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
+	 $(PY_INCLUDE)\tupleobject.h
+
+sunaudiodev.obj: $(PY_INCLUDE)\abstract.h $(OS2TCPIP)\Include\sys\ioctl.h $(PY_INCLUDE)\ceval.h \
+	 $(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h \
+	 pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
+	 $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h \
+	 $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
+	 $(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\methodobject.h \
+	 $(PY_INCLUDE)\modsupport.h $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h \
+	 $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h \
+	 $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h \
+	 $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h \
+	 $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\structmember.h \
+	 $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+svmodule.obj: $(PY_INCLUDE)\abstract.h $(OS2TCPIP)\Include\sys\time.h $(PY_INCLUDE)\ceval.h \
+	 $(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\compile.h \
+	 $(PY_INCLUDE)\complexobject.h pyconfig.h $(PY_INCLUDE)\dictobject.h \
+	 $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h \
+	 $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h \
+	 $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h \
+	 $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h \
+	 $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h \
+	 $(PY_INCLUDE)\sliceobject.h $(PY_INCLUDE)\stringobject.h \
+	 $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h \
+	 $(PY_MODULES)\yuv.h
+
+syslogmodule.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h \
+	 $(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h \
+	 pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
+	 $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h \
+	 $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
+	 $(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\methodobject.h \
+	 $(PY_INCLUDE)\modsupport.h $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h \
+	 $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h \
+	 $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h \
+	 $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h \
+	 $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(OS2TCPIP)\Include\syslog.h $(PY_INCLUDE)\sysmodule.h \
+	 $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+termios.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h \
+	 $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h \
+	 $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h \
+	 $(PY_INCLUDE)\sliceobject.h $(PY_INCLUDE)\stringobject.h \
+	 $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+threadmodule.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h \
+	 $(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h \
+	 pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
+	 $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h \
+	 $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
+	 $(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\methodobject.h \
+	 $(PY_INCLUDE)\modsupport.h $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h \
+	 $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h \
+	 $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h \
+	 $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h \
+	 $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\thread.h \
+	 $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+timemodule.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\mytime.h $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h \
+	 $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h \
+	 $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h \
+	 $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
+	 $(PY_INCLUDE)\tupleobject.h
+
+timingmodule.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h \
+	 $(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h \
+	 pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
+	 $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h \
+	 $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
+	 $(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\methodobject.h \
+	 $(PY_INCLUDE)\modsupport.h $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h \
+	 $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h \
+	 $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h \
+	 $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h \
+	 $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_MODULES)\timing.h \
+	 $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+xxmodule.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h \
+	 $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h \
+	 $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h \
+	 $(PY_INCLUDE)\sliceobject.h $(PY_INCLUDE)\stringobject.h \
+	 $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+yuvconvert.obj: $(PY_MODULES)\yuv.h
+
+zlibmodule.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h \
+	 $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h \
+	 $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h \
+	 $(PY_INCLUDE)\sliceobject.h $(PY_INCLUDE)\stringobject.h \
+	 $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+abstract.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h \
+	 $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h \
+	 $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h \
+	 $(PY_INCLUDE)\sliceobject.h $(PY_INCLUDE)\stringobject.h \
+	 $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+classobject.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h \
+	 $(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h \
+	 pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
+	 $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h \
+	 $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
+	 $(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\methodobject.h \
+	 $(PY_INCLUDE)\modsupport.h $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h \
+	 $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h \
+	 $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h \
+	 $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h \
+	 $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\structmember.h \
+	 $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+cobject.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h \
+	 $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h \
+	 $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h \
+	 $(PY_INCLUDE)\sliceobject.h $(PY_INCLUDE)\stringobject.h \
+	 $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+complexobject.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h \
+	 $(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h \
+	 pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
+	 $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h \
+	 $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
+	 $(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\methodobject.h \
+	 $(PY_INCLUDE)\modsupport.h $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h \
+	 $(PY_INCLUDE)\mymath.h $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\object.h \
+	 $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h \
+	 $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h \
+	 $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
+	 $(PY_INCLUDE)\tupleobject.h
+
+dictobject.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h \
+	 $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h \
+	 $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h \
+	 $(PY_INCLUDE)\sliceobject.h $(PY_INCLUDE)\stringobject.h \
+	 $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+fileobject.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h \
+	 $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h \
+	 $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h \
+	 $(PY_INCLUDE)\sliceobject.h $(PY_INCLUDE)\stringobject.h \
+	 $(PY_INCLUDE)\structmember.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
+	 $(PY_INCLUDE)\tupleobject.h
+
+floatobject.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h \
+	 $(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h \
+	 pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
+	 $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h \
+	 $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
+	 $(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\methodobject.h \
+	 $(PY_INCLUDE)\modsupport.h $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h \
+	 $(PY_INCLUDE)\mymath.h $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\object.h \
+	 $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h \
+	 $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h \
+	 $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
+	 $(PY_INCLUDE)\tupleobject.h
+
+frameobject.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h \
+	 $(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\compile.h \
+	 $(PY_INCLUDE)\complexobject.h pyconfig.h $(PY_INCLUDE)\dictobject.h \
+	 $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\frameobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h \
+	 $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
+	 $(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\methodobject.h \
+	 $(PY_INCLUDE)\modsupport.h $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h \
+	 $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h \
+	 $(PY_INCLUDE)\opcode.h $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h \
+	 $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h \
+	 $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\structmember.h \
+	 $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+funcobject.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\compile.h $(PY_INCLUDE)\complexobject.h \
+	 pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
+	 $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h \
+	 $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
+	 $(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\methodobject.h \
+	 $(PY_INCLUDE)\modsupport.h $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h \
+	 $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h \
+	 $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h \
+	 $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h \
+	 $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\structmember.h \
+	 $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+intobject.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h \
+	 $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h \
+	 $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h \
+	 $(PY_INCLUDE)\sliceobject.h $(PY_INCLUDE)\stringobject.h \
+	 $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+listobject.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h \
+	 $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h \
+	 $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h \
+	 $(PY_INCLUDE)\sliceobject.h $(PY_INCLUDE)\stringobject.h \
+	 $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+longobject.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h \
+	 $(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h \
+	 pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
+	 $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h \
+	 $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
+	 $(PY_INCLUDE)\longintrepr.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\mymath.h \
+	 $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h \
+	 $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h \
+	 $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h \
+	 $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
+	 $(PY_INCLUDE)\tupleobject.h
+
+methodobject.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h \
+	 $(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h \
+	 pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
+	 $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h \
+	 $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
+	 $(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\methodobject.h \
+	 $(PY_INCLUDE)\modsupport.h $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h \
+	 $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h \
+	 $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h \
+	 $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h \
+	 $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\token.h \
+	 $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+moduleobject.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h \
+	 $(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h \
+	 pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
+	 $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h \
+	 $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
+	 $(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\methodobject.h \
+	 $(PY_INCLUDE)\modsupport.h $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h \
+	 $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h \
+	 $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h \
+	 $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h \
+	 $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
+	 $(PY_INCLUDE)\tupleobject.h
+
+object.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h \
+	 $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h \
+	 $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h \
+	 $(PY_INCLUDE)\sliceobject.h $(PY_INCLUDE)\stringobject.h \
+	 $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+rangeobject.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h \
+	 $(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h \
+	 pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
+	 $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h \
+	 $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
+	 $(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\methodobject.h \
+	 $(PY_INCLUDE)\modsupport.h $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h \
+	 $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h \
+	 $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h \
+	 $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h \
+	 $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
+	 $(PY_INCLUDE)\tupleobject.h
+
+sliceobject.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h \
+	 $(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h \
+	 pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
+	 $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h \
+	 $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
+	 $(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\methodobject.h \
+	 $(PY_INCLUDE)\modsupport.h $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h \
+	 $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h \
+	 $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h \
+	 $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h \
+	 $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
+	 $(PY_INCLUDE)\tupleobject.h
+
+stringobject.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h \
+	 $(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h \
+	 pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
+	 $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h \
+	 $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
+	 $(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\methodobject.h \
+	 $(PY_INCLUDE)\modsupport.h $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h \
+	 $(PY_INCLUDE)\mymath.h $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\object.h \
+	 $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h \
+	 $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h \
+	 $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
+	 $(PY_INCLUDE)\tupleobject.h
+
+tupleobject.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h \
+	 $(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h \
+	 pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
+	 $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h \
+	 $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
+	 $(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\methodobject.h \
+	 $(PY_INCLUDE)\modsupport.h $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h \
+	 $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h \
+	 $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h \
+	 $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h \
+	 $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
+	 $(PY_INCLUDE)\tupleobject.h
+
+typeobject.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h \
+	 $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h \
+	 $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h \
+	 $(PY_INCLUDE)\sliceobject.h $(PY_INCLUDE)\stringobject.h \
+	 $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+xxobject.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h \
+	 $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h \
+	 $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h \
+	 $(PY_INCLUDE)\sliceobject.h $(PY_INCLUDE)\stringobject.h \
+	 $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+acceler.obj: $(PY_INCLUDE)\bitset.h pyconfig.h $(PY_INCLUDE)\grammar.h \
+	 $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\node.h \
+	 $(PY_PARSER)\parser.h $(PY_INCLUDE)\pgenheaders.h $(PY_INCLUDE)\pydebug.h \
+	 $(PY_INCLUDE)\token.h
+
+bitset.obj: $(PY_INCLUDE)\bitset.h pyconfig.h $(PY_INCLUDE)\mymalloc.h \
+	 $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\pgenheaders.h $(PY_INCLUDE)\pydebug.h
+
+firstsets.obj: $(PY_INCLUDE)\bitset.h pyconfig.h $(PY_INCLUDE)\grammar.h \
+	 $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\pgenheaders.h \
+	 $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\token.h
+
+grammar.obj: $(PY_INCLUDE)\bitset.h pyconfig.h \
+	 $(PY_INCLUDE)\grammar.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\pgenheaders.h $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\token.h
+
+grammar1.obj: $(PY_INCLUDE)\bitset.h pyconfig.h \
+	 $(PY_INCLUDE)\grammar.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\pgenheaders.h $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\token.h
+
+intrcheck.obj: pyconfig.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\mymalloc.h \
+	 $(PY_INCLUDE)\myproto.h
+
+listnode.obj: pyconfig.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\node.h $(PY_INCLUDE)\pgenheaders.h $(PY_INCLUDE)\pydebug.h \
+	 $(PY_INCLUDE)\token.h
+
+metagrammar.obj: $(PY_INCLUDE)\bitset.h pyconfig.h $(PY_INCLUDE)\grammar.h \
+	 $(PY_INCLUDE)\metagrammar.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_PARSER)\pgen.h $(PY_INCLUDE)\pgenheaders.h $(PY_INCLUDE)\pydebug.h
+
+myreadline.obj: pyconfig.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\mymalloc.h \
+	 $(PY_INCLUDE)\myproto.h
+
+node.obj: pyconfig.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\node.h \
+	 $(PY_INCLUDE)\pgenheaders.h $(PY_INCLUDE)\pydebug.h
+
+parser.obj: $(PY_INCLUDE)\bitset.h pyconfig.h $(PY_INCLUDE)\errcode.h \
+	 $(PY_INCLUDE)\grammar.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\node.h $(PY_PARSER)\parser.h $(PY_INCLUDE)\pgenheaders.h \
+	 $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\token.h
+
+parsetok.obj: $(PY_INCLUDE)\bitset.h pyconfig.h $(PY_INCLUDE)\errcode.h \
+	 $(PY_INCLUDE)\grammar.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\node.h $(PY_PARSER)\parser.h $(PY_INCLUDE)\parsetok.h \
+	 $(PY_INCLUDE)\pgenheaders.h $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\token.h \
+	 $(PY_PARSER)\tokenizer.h
+
+pgen.obj: $(PY_INCLUDE)\bitset.h pyconfig.h $(PY_INCLUDE)\grammar.h \
+	 $(PY_INCLUDE)\metagrammar.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\node.h $(PY_PARSER)\pgen.h $(PY_INCLUDE)\pgenheaders.h \
+	 $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\token.h
+
+pgenmain.obj: $(PY_INCLUDE)\bitset.h pyconfig.h $(PY_INCLUDE)\grammar.h \
+	 $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\node.h \
+	 $(PY_INCLUDE)\parsetok.h $(PY_PARSER)\pgen.h $(PY_INCLUDE)\pgenheaders.h \
+	 $(PY_INCLUDE)\pydebug.h
+
+printgrammar.obj: $(PY_INCLUDE)\bitset.h pyconfig.h $(PY_INCLUDE)\grammar.h \
+	 $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\pgenheaders.h \
+	 $(PY_INCLUDE)\pydebug.h
+
+tokenizer.obj: pyconfig.h $(PY_INCLUDE)\errcode.h $(PY_INCLUDE)\mymalloc.h \
+	 $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\pgenheaders.h $(PY_INCLUDE)\pydebug.h \
+	 $(PY_INCLUDE)\token.h $(PY_PARSER)\tokenizer.h
+
+atof.obj: pyconfig.h
+
+bltinmodule.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h \
+	 $(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\compile.h \
+	 $(PY_INCLUDE)\complexobject.h pyconfig.h $(PY_INCLUDE)\dictobject.h \
+	 $(PY_INCLUDE)\eval.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\mymath.h \
+	 $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\node.h $(PY_INCLUDE)\object.h \
+	 $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h \
+	 $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h \
+	 $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
+	 $(PY_INCLUDE)\tupleobject.h
+
+ceval.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\compile.h $(PY_INCLUDE)\complexobject.h \
+	 pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\eval.h \
+	 $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\frameobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h \
+	 $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
+	 $(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\methodobject.h \
+	 $(PY_INCLUDE)\modsupport.h $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h \
+	 $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h \
+	 $(PY_INCLUDE)\opcode.h $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h \
+	 $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h \
+	 $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
+	 $(PY_INCLUDE)\tupleobject.h
+
+compile.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\compile.h $(PY_INCLUDE)\complexobject.h \
+	 pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
+	 $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\graminit.h \
+	 $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h \
+	 $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\node.h $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h \
+	 $(PY_INCLUDE)\opcode.h $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h \
+	 $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h \
+	 $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\structmember.h \
+	 $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\token.h $(PY_INCLUDE)\traceback.h \
+	 $(PY_INCLUDE)\tupleobject.h
+
+errors.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h \
+	 $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h \
+	 $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h \
+	 $(PY_INCLUDE)\sliceobject.h $(PY_INCLUDE)\stringobject.h \
+	 $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+fmod.obj: pyconfig.h $(PY_INCLUDE)\mymath.h
+
+frozen.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h \
+	 $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h \
+	 $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h \
+	 $(PY_INCLUDE)\sliceobject.h $(PY_INCLUDE)\stringobject.h \
+	 $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+frozenmain.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h \
+	 $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h \
+	 $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h \
+	 $(PY_INCLUDE)\sliceobject.h $(PY_INCLUDE)\stringobject.h \
+	 $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+getargs.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h \
+	 $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h \
+	 $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h \
+	 $(PY_INCLUDE)\sliceobject.h $(PY_INCLUDE)\stringobject.h \
+	 $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+getcompiler.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h \
+	 $(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h \
+	 pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
+	 $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h \
+	 $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
+	 $(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\methodobject.h \
+	 $(PY_INCLUDE)\modsupport.h $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h \
+	 $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h \
+	 $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h \
+	 $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h \
+	 $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
+	 $(PY_INCLUDE)\tupleobject.h
+
+getcopyright.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h \
+	 $(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h \
+	 pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
+	 $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h \
+	 $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
+	 $(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\methodobject.h \
+	 $(PY_INCLUDE)\modsupport.h $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h \
+	 $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h \
+	 $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h \
+	 $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h \
+	 $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
+	 $(PY_INCLUDE)\tupleobject.h
+
+getmtime.obj: pyconfig.h
+
+getplatform.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h \
+	 $(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h \
+	 pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
+	 $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h \
+	 $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
+	 $(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\methodobject.h \
+	 $(PY_INCLUDE)\modsupport.h $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h \
+	 $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h \
+	 $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h \
+	 $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h \
+	 $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
+	 $(PY_INCLUDE)\tupleobject.h
+
+getversion.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\patchlevel.h \
+	 $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h \
+	 $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h \
+	 $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
+	 $(PY_INCLUDE)\tupleobject.h
+
+graminit.obj: $(PY_INCLUDE)\bitset.h pyconfig.h $(PY_INCLUDE)\grammar.h \
+	 $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\pgenheaders.h \
+	 $(PY_INCLUDE)\pydebug.h
+
+hypot.obj: pyconfig.h $(PY_INCLUDE)\mymath.h $(PY_INCLUDE)\myproto.h
+
+import.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\compile.h $(PY_INCLUDE)\complexobject.h \
+	 pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\errcode.h $(PY_INCLUDE)\eval.h \
+	 $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h \
+	 $(PY_INCLUDE)\import.h $(PY_PYTHON)\importdl.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\marshal.h $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\node.h $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h \
+	 $(PY_INCLUDE)\osdefs.h $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h \
+	 $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h \
+	 $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\token.h \
+	 $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+importdl.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_PYTHON)\importdl.h \
+	 $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
+	 $(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\methodobject.h \
+	 $(PY_INCLUDE)\modsupport.h $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h \
+	 $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h \
+	 $(PY_INCLUDE)\osdefs.h $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h \
+	 $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h \
+	 $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
+	 $(PY_INCLUDE)\tupleobject.h
+
+marshal.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\compile.h $(PY_INCLUDE)\complexobject.h \
+	 pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
+	 $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h \
+	 $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
+	 $(PY_INCLUDE)\longintrepr.h $(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\marshal.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h \
+	 $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h \
+	 $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h \
+	 $(PY_INCLUDE)\sliceobject.h $(PY_INCLUDE)\stringobject.h \
+	 $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+modsupport.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h \
+	 $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h \
+	 $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h \
+	 $(PY_INCLUDE)\sliceobject.h $(PY_INCLUDE)\stringobject.h \
+	 $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+mystrtoul.obj: pyconfig.h
+
+pyfpe.obj: pyconfig.h $(PY_INCLUDE)\pyfpe.h
+
+pystate.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h \
+	 $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h \
+	 $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h \
+	 $(PY_INCLUDE)\sliceobject.h $(PY_INCLUDE)\stringobject.h \
+	 $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+pythonrun.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\bitset.h $(PY_INCLUDE)\ceval.h \
+	 $(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\compile.h \
+	 $(PY_INCLUDE)\complexobject.h pyconfig.h $(PY_INCLUDE)\dictobject.h \
+	 $(PY_INCLUDE)\errcode.h $(PY_INCLUDE)\eval.h $(PY_INCLUDE)\fileobject.h \
+	 $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\grammar.h \
+	 $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h \
+	 $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\marshal.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\node.h $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h \
+	 $(PY_INCLUDE)\parsetok.h $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h \
+	 $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h \
+	 $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
+	 $(PY_INCLUDE)\tupleobject.h
+
+sigcheck.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h \
+	 $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h \
+	 $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h \
+	 $(PY_INCLUDE)\sliceobject.h $(PY_INCLUDE)\stringobject.h \
+	 $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+strdup.obj: pyconfig.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h
+
+strtod.obj: pyconfig.h
+
+structmember.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h \
+	 $(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h \
+	 pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
+	 $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h \
+	 $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
+	 $(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\methodobject.h \
+	 $(PY_INCLUDE)\modsupport.h $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h \
+	 $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h \
+	 $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h \
+	 $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h \
+	 $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\structmember.h \
+	 $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+
+sysmodule.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\osdefs.h \
+	 $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h \
+	 $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h \
+	 $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
+	 $(PY_INCLUDE)\tupleobject.h
+
+thread.obj: pyconfig.h $(PY_INCLUDE)\thread.h
+
+traceback.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
+	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\compile.h $(PY_INCLUDE)\complexobject.h \
+	 pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
+	 $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\frameobject.h \
+	 $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \
+	 $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \
+	 $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \
+	 $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \
+	 $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\osdefs.h \
+	 $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h \
+	 $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h \
+	 $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
+	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\structmember.h \
+	 $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
+

Added: vendor/Python/current/PC/os2vacpp/makefile.omk
===================================================================
--- vendor/Python/current/PC/os2vacpp/makefile.omk	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/os2vacpp/makefile.omk	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1277 @@
+######################################################################
+#
+#          Top-Level Makefile for Building Python for OS/2
+#
+# This makefile was developed for use with IBM's VisualAge C/C++
+# for OS/2 compiler, version 3.0, with Fixpack 8 applied.  It uses
+# the commercial OpusMAKE tool.
+#
+# The output of the build is a largish Python15.DLL containing the
+# essential modules of Python and a small Python.exe program to start
+# the interpreter.  When embedding Python within another program, only
+# Python15.DLL is needed.
+#
+# These two binaries can be statically linked with the VisualAge C/C++
+# runtime library (producing larger binaries), or dynamically linked
+# to make smaller ones that require the compiler to be installed on
+# any system Python is used on.
+#
+# History (Most Recent First)
+#
+# 20-Nov-97 jrr Cleaned Up for Applying to Distribution
+# 29-Oct-97 jrr Modified for Use with Python 1.5 Alpha 4
+# 03-Aug-96 jrr Original for Use with Python 1.4 Release
+#
+######################################################################
+
+###################
+# Places and Things
+###################
+PY_MODULES      = ..\..\Modules
+PY_OBJECTS      = ..\..\Objects
+PY_PARSER       = ..\..\Parser
+PY_PYTHON       = ..\..\Python
+PY_INCLUDE      = ..\..\Include
+PY_INCLUDES     = .;$(PY_INCLUDE);$(PY_MODULES);$(PY_OBJECTS);$(PY_PARSER);$(PY_PYTHON)
+
+# Where to Find the IBM TCP/IP Socket Includes and Libraries
+OS2TCPIP        = C:\MPTN
+
+# Where to Put the .OBJ Files, To Keep Them Out of the Way
+.PATH.obj	= obj
+
+# Search Path for Include Files
+PROJINCLUDE	= .;$(OS2TCPIP)\Include;$(PY_INCLUDES)
+
+# Place to Search for Sources re OpusMAKE Dependency Generator (Commercial)
+MKMF_SRCS	= $(PY_MODULES)\*.c $(PY_OBJECTS)\*.c $(PY_PARSER)\*.c $(PY_PYTHON)\*.c
+
+.HDRPATH.c	:= $(PROJINCLUDE,;= ) $(.HDRPATH.c)
+.PATH.c         = .;$(PY_MODULES);$(PY_OBJECTS);$(PY_PARSER);$(PY_PYTHON)
+OTHERLIBS	= $(OS2TCPIP)\lib\so32dll.lib $(OS2TCPIP)\lib\tcp32dll.lib
+
+#################
+# Inference Rules
+#################
+
+
+###################
+# Python Subsystems
+###################
+
+# PYTHON is the central core, containing the builtins and interpreter.
+PYTHON		=                    \
+                  BltinModule.obj    \
+                  CEval.obj          \
+                  Compile.obj        \
+                  Errors.obj         \
+                  Frozen.obj         \
+                  Getargs.obj        \
+                  GetCompiler.obj    \
+                  GetCopyright.obj   \
+                  GetMTime.obj       \
+                  GetOpt.obj         \
+                  GetPlatform.obj    \
+                  GetVersion.obj     \
+                  GramInit.obj       \
+                  Import.obj         \
+                  ImportDL.obj       \
+                  Marshal.obj        \
+                  ModSupport.obj     \
+                  MyStrtoul.obj      \
+                  PyState.obj        \
+                  PythonRun.obj      \
+                  StructMember.obj   \
+                  SysModule.obj      \
+                  Thread.obj         \
+                  TraceBack.obj      \
+                  FrozenMain.obj
+
+# Omitted Python Elements (and Reason):
+  # atof.c          -- Implementation for Platforms w/o This Function
+  # dup2.c          -- Implementation for Platforms w/o This Function
+  # fmod.c          -- Implementation for Platforms w/o This Function
+  # getcwd.c        -- Implementation for Platforms w/o This Function
+  # hypot.c         -- Implementation for Platforms w/o This Function
+  # memmove.c       -- Implementation for Platforms w/o This Function
+  # strdup.c        -- Implementation for Platforms w/o This Function
+  # strerror.c      -- Implementation for Platforms w/o This Function
+  # strtod.c        -- Implementation for Platforms w/o This Function
+
+  # sigcheck.c      -- Primitive Signal Catcher (SignalModule.c Used Instead)
+  # pyfpe.c         -- Primitive FPE Catcher (Not Referenced by Anyone)
+  # frozenmain.c
+
+# Python's Internal Parser
+PARSER		=                   \
+                  Acceler.obj       \
+                  Grammar1.obj      \
+                  MyReadline.obj    \
+                  Node.obj          \
+                  Parser.obj        \
+                  ParseTok.obj      \
+                  Tokenizer.obj
+
+# Python Object Types
+OBJECTS		=                   \
+                  Abstract.obj      \
+                  ClassObject.obj   \
+                  CObject.obj       \
+                  ComplexObject.obj \
+                  DictObject.obj    \
+                  FileObject.obj    \
+                  FloatObject.obj   \
+                  FrameObject.obj   \
+                  FuncObject.obj    \
+                  IntObject.obj     \
+                  ListObject.obj    \
+                  LongObject.obj    \
+                  MethodObject.obj  \
+                  ModuleObject.obj  \
+                  Object.obj        \
+                  RangeObject.obj   \
+                  SliceObject.obj   \
+                  StringObject.obj  \
+                  TupleObject.obj   \
+                  TypeObject.obj
+
+# Omitted Objects (and Reason):
+  # xxobject.c      -- Template to Create Your Own Object Types
+
+# Extension Modules (Built-In or as Separate DLLs)
+MODULES		=                   \
+                  ArrayModule.obj   \
+                  BinAscii.obj      \
+                  CMathModule.obj   \
+                  cPickle.obj       \
+                  cStringIO.obj     \
+                  ErrnoModule.obj   \
+                  GetBuildInfo.obj  \
+                  GetPathP.obj      \
+                  Main.obj          \
+                  MathModule.obj    \
+                  MD5c.obj          \
+                  MD5Module.obj     \
+                  Operator.obj      \
+                  PosixModule.obj   \
+                  RegexModule.obj   \
+                  RegExpr.obj       \
+                  ReopModule.obj    \
+                  SelectModule.obj  \
+                  SignalModule.obj  \
+                  SocketModule.obj  \
+                  SoundEx.obj       \
+                  StropModule.obj   \
+                  StructModule.obj  \
+                  TimeModule.obj    \
+                  ThreadModule.obj  \
+                  YUVConvert.obj
+
+# Omitted Modules (and Description/Reason):
+  #
+  # Multimedia:
+  # almodule.c      -- Non-OS/2 Audio Channel Facility (?)
+  # cdmodule.c      -- Wrapper of Non-OS/2 CD Audio Functions
+  # audioop.c       -- Various Compute Operations on Audio Samples
+  # imageop.c       -- Various Compute Operations on Video Samples
+  # imgfile.c       -- Wrapper of SGI ImageLib API
+  # rgbimgmodule.c  -- Non-OS/2 Image Read/Write Capability (Primitive)
+  # sunaudiodev.c   -- Wrapper of Sun Audio Device API
+  # clmodule.c      -- Wrapper of SGI Image/Audio Compression API
+
+  # Database:
+  # dbmmodule.c     -- Wrapper of DBM Database API (Generic Flavor)
+  # bsddbmodule.c   -- Wrapper of DBM Database API (BSD Flavor)
+  # gdbmmodule.c    -- Wrapper of DBM Database API (GNU Flavor)
+
+  # Cryptography:
+  # cryptmodule.c   -- Simple Wrapper for crypt() Function
+  # rotormodule.c   -- Implementation of Enigma Crypto Based on Rotors
+
+#                  cgensupport.obj   \
+#                  fcntlmodule.obj   \
+#                  fmmodule.obj      \
+#                  fpectlmodule.obj  \
+#                  fpetestmodule.obj \
+# Unix-Specific    getpath.obj       \
+#                  glmodule.obj      \
+#                  grpmodule.obj     \
+#                  mpzmodule.obj     \
+#                  nismodule.obj     \
+#                  parsermodule.obj  \
+#                  pcremodule.obj    \
+#                  pwdmodule.obj     \
+#                  pypcre.obj        \
+#                  readline.obj      \
+#                  resource.obj      \
+#                  sgimodule.obj     \
+#                  svmodule.obj      \
+#                  syslogmodule.obj  \
+#                  termios.obj       \
+#                  timingmodule.obj  \
+
+  # User Interface:
+#                  _tkinter.obj      \     
+#                  stdwinmodule.obj  \
+#                  cursesmodule.obj  \
+#                  tclNotify.obj     \
+#                  tkappinit.obj     \
+  # flmodule.c      -- Wrapper of FORMS Library (Screen Forms)
+
+  # zlibmodule.c    -- Wrapper of ZLib Compression API (GZip Format)
+  # puremodule.c    -- Wrapper of Purify Debugging API (Probably Non-OS/2)
+  # dlmodule.c      -- Some Wierd Form of Data Processing Module
+  # xxmodule.c      -- Template to Create Your Own Module
+
+#
+# Standalone Parser Generator Program (Shares Some of Python's Modules)
+PGEN            =                   \
+                  PGenMain.obj      \
+                  PGen.obj          \
+                  PrintGrammar.obj  \
+                  ListNode.obj      \
+                  Grammar.obj       \
+                  BitSet.obj        \
+                  FirstSets.obj     \
+                  MetaGrammar.obj
+
+# Omitted Parser Elements (and Reason):
+  # intrcheck.c     -- Not Referenced by Anyone (?)
+
+##################
+# Macros and Flags
+##################
+_BASE		= /Q /W2 /I$(PROJINCLUDE)
+		# /Q   = Omit IBM Copyright
+		# /W2  = Show Warnings/Errors Only
+		# /Fi  = Create Precompiled Headers
+		# /Si  = Utilize Precompiled Headers
+
+_GEN		= /G4 /Gm /Gd /B"/STACK:360000"
+		# /G4  = Generate Code for 486 (Use 386 for Debugger)
+		# /Gm  = Use Multithread Runtime
+		# /Gd  = Dynamically Load Runtime
+		# /Gs  = Remove Code for Stack Probes
+		# /Gx  = Remove C++ Exception-Handling Info
+		# /Tdp = Generate Code for C++ Templates
+		# /Rn  = Generate Code without a Runtime
+		# /B"/STACK:n" = Set Stack Size
+
+_OPT		= /O /Gl
+		# /O   = Enable Speed-Optimizations
+		# /Ol  = Pass Code Thru Intermediate Linker
+		# /Gu  = Advise Linker All Ext Data is ID'd
+		# /Gl  = Have Linker Remove Unused Fns
+
+_DBG		= /DHAVE_CONFIG_H /DUSE_SOCKET
+		# /Ti  = Embed Debugger/Analyzer Recs
+		# /Tm  = Enable Debug Memory Fns
+		# /Tx  = Request Full Dump Upon Exception
+		# /DDEBUG = Enable App-Internal Debugging Code
+                # /DUSE_SOCKET = 
+                # /DUSE_DL_EXPORT = 
+
+_OUT		= 
+		# /Fb  = Embed Browser Recs
+		# /Gh  = Generate Code for Profiler Hooks
+		# /Fl  = Output C/C++ Listing Files
+                # /Lf  = Provide Full (Detailed) Listing Files
+		# /Fm. = Output Linker Map File
+		# /Ft. = Output C++ Template Resolution Files
+
+_MAP		= /FmNoise\$(.TARGET,B,>.map)
+
+_DLL		= /Ge-
+_EXE		= /Ge
+		# /Ge = Create an EXE, not DLL
+
+CFLAGS		= $(_BASE) $(_GEN) $(_OPT) $(_DBG) $(_OUT) $(_EXE) /Ss
+CPPFLAGS	= $(_BASE) $(_GEN) $(_OPT) $(_DBG) $(_OUT) $(_EXE)
+
+###################
+# Primary Target(s)
+###################
+All:  obj noise PyCore.lib Python15.lib Python15.dll Python.exe PGen.exe
+
+##############
+#
+##############
+
+# Object Library of All Essential Python Routines
+PyCore.lib: $(MODULES) $(OBJECTS) $(PARSER) $(PYTHON) Config.obj
+        %do "%.lib"
+
+Python15.dll: Compile.obj PyCore.lib Python.def
+        %do "%.dll" CPPFLAGS+=/B"/NOE" CPPFLAGS+=$(_MAP)
+
+Compile.obj: Compile.c
+        %do ".c.obj" CFLAGS+=$(_DLL)
+
+# Import Library for Using the Python15.dll
+Python15.lib: Python.def
+        %do ".def.lib"
+
+# Small Program to Start Interpreter in Python15.dll
+Python.exe: Python.obj Python15.lib
+        %do "%.exe" CPPFLAGS+=$(_MAP)
+
+#Python.obj: Python.c
+#        %do ".c.obj" CFLAGS+=$(_EXE)
+
+PGen.exe: $(PGEN) PyCore.lib
+        %do "%.exe" CPPFLAGS+=$(_MAP)
+
+#######################
+# Miscellaneous Targets
+#######################
+
+# Remove Intermediate Targets but Leave Executable Binaries
+clean:
+	-- Del /Q $(.PATH.obj)\*.obj		>NUL 2>&1
+	-- Del /Q /Y Noise			>NUL 2>&1
+	-- Del /Q $(ERRS)			>NUL 2>&1
+
+# Remove All Targets, Including Final Binaries
+distclean: clean
+        -- Del /Q PyCore.lib Python15.lib       >NUL 2>&1
+        -- Del /Q Python15.dll Python.exe       >NUL 2>&1
+
+release: Python.exe Python15.dll Python15.lib
+	-- @Echo Y | copy /U $(.SOURCES,M"*.exe") D:\EXEs
+	-- @Echo Y | copy /U $(.SOURCES,M"*.dll") D:\DLLs
+	-- @Echo Y | copy /U $(.SOURCES,M"*.lib") E:\Tau\Lib
+
+test:
+        python ..\..\lib\test\regrtest.py
+
+# Update Dependencies on Targets (Uses OpusMAKE Commercial Product)
+depend:
+	D:\OpusMake\os2mkmf -c -s
+
+### OPUS MKMF:  Do not remove this line!  Generated dependencies follow.
+
+_tkinter.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
+	 traceback.h tupleobject.h
+
+almodule.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
+	 traceback.h tupleobject.h
+
+arraymodule.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
+	 traceback.h tupleobject.h
+
+audioop.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h mymath.h \
+	 myproto.h object.h objimpl.h pydebug.h pyerrors.h pyfpe.h \
+	 pystate.h python.h pythonrun.h rangeobject.h sliceobject.h \
+	 stringobject.h sysmodule.h traceback.h tupleobject.h
+
+binascii.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
+	 traceback.h tupleobject.h
+
+bsddbmodule.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
+	 traceback.h tupleobject.h
+
+cdmodule.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
+	 traceback.h tupleobject.h
+
+cgensupport.obj: abstract.h ceval.h cgensupport.h classobject.h cobject.h \
+	 complexobject.h pyconfig.h dictobject.h fileobject.h floatobject.h \
+	 funcobject.h import.h intobject.h intrcheck.h listobject.h \
+	 longobject.h methodobject.h modsupport.h moduleobject.h mymalloc.h \
+	 myproto.h object.h objimpl.h pydebug.h pyerrors.h pyfpe.h \
+	 pystate.h python.h pythonrun.h rangeobject.h sliceobject.h \
+	 stringobject.h sysmodule.h traceback.h tupleobject.h
+
+clmodule.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
+	 traceback.h tupleobject.h
+
+cmathmodule.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h mymath.h \
+	 myproto.h object.h objimpl.h pydebug.h pyerrors.h pyfpe.h \
+	 pystate.h python.h pythonrun.h rangeobject.h sliceobject.h \
+	 stringobject.h sysmodule.h traceback.h tupleobject.h
+
+cpickle.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h cstringio.h dictobject.h fileobject.h floatobject.h \
+	 funcobject.h import.h intobject.h intrcheck.h listobject.h \
+	 longobject.h methodobject.h modsupport.h moduleobject.h mymalloc.h \
+	 mymath.h myproto.h object.h objimpl.h pydebug.h pyerrors.h pyfpe.h \
+	 pystate.h python.h pythonrun.h rangeobject.h sliceobject.h \
+	 stringobject.h sysmodule.h traceback.h tupleobject.h
+
+cryptmodule.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
+	 traceback.h tupleobject.h
+
+cstringio.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h cstringio.h dictobject.h fileobject.h floatobject.h \
+	 funcobject.h import.h intobject.h intrcheck.h listobject.h \
+	 longobject.h methodobject.h modsupport.h moduleobject.h mymalloc.h \
+	 myproto.h object.h objimpl.h pydebug.h pyerrors.h pyfpe.h \
+	 pystate.h python.h pythonrun.h rangeobject.h sliceobject.h \
+	 stringobject.h sysmodule.h traceback.h tupleobject.h
+
+cursesmodule.obj: abstract.h ceval.h classobject.h cobject.h \
+	 complexobject.h pyconfig.h dictobject.h fileobject.h floatobject.h \
+	 funcobject.h import.h intobject.h intrcheck.h listobject.h \
+	 longobject.h methodobject.h modsupport.h moduleobject.h mymalloc.h \
+	 myproto.h object.h objimpl.h pydebug.h pyerrors.h pyfpe.h \
+	 pystate.h python.h pythonrun.h rangeobject.h sliceobject.h \
+	 stringobject.h sysmodule.h traceback.h tupleobject.h
+
+dbmmodule.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
+	 traceback.h tupleobject.h
+
+dlmodule.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
+	 traceback.h tupleobject.h
+
+errno.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
+	 traceback.h tupleobject.h
+
+errnomodule.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
+	 traceback.h tupleobject.h
+
+fcntlmodule.obj: abstract.h c:\mptn\include\sys\ioctl.h ceval.h \
+	 classobject.h cobject.h complexobject.h pyconfig.h dictobject.h \
+	 fileobject.h floatobject.h funcobject.h import.h intobject.h \
+	 intrcheck.h listobject.h longobject.h methodobject.h modsupport.h \
+	 moduleobject.h mymalloc.h myproto.h object.h objimpl.h pydebug.h \
+	 pyerrors.h pyfpe.h pystate.h python.h pythonrun.h rangeobject.h \
+	 sliceobject.h stringobject.h sysmodule.h traceback.h tupleobject.h
+
+flmodule.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h \
+	 structmember.h sysmodule.h traceback.h tupleobject.h
+
+fmmodule.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
+	 traceback.h tupleobject.h
+
+fpectlmodule.obj: abstract.h ceval.h classobject.h cobject.h \
+	 complexobject.h pyconfig.h dictobject.h fileobject.h floatobject.h \
+	 funcobject.h import.h intobject.h intrcheck.h listobject.h \
+	 longobject.h methodobject.h modsupport.h moduleobject.h mymalloc.h \
+	 myproto.h object.h objimpl.h pydebug.h pyerrors.h pyfpe.h \
+	 pystate.h python.h pythonrun.h rangeobject.h sliceobject.h \
+	 stringobject.h sysmodule.h traceback.h tupleobject.h
+
+fpetestmodule.obj: abstract.h ceval.h classobject.h cobject.h \
+	 complexobject.h pyconfig.h dictobject.h fileobject.h floatobject.h \
+	 funcobject.h import.h intobject.h intrcheck.h listobject.h \
+	 longobject.h methodobject.h modsupport.h moduleobject.h mymalloc.h \
+	 myproto.h object.h objimpl.h pydebug.h pyerrors.h pyfpe.h \
+	 pystate.h python.h pythonrun.h rangeobject.h sliceobject.h \
+	 stringobject.h sysmodule.h traceback.h tupleobject.h
+
+gdbmmodule.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
+	 traceback.h tupleobject.h
+
+getbuildinfo.obj: pyconfig.h
+
+getpath.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h osdefs.h pydebug.h pyerrors.h pyfpe.h pystate.h \
+	 python.h pythonrun.h rangeobject.h sliceobject.h stringobject.h \
+	 sysmodule.h traceback.h tupleobject.h
+
+glmodule.obj: abstract.h ceval.h cgensupport.h classobject.h cobject.h \
+	 complexobject.h pyconfig.h dictobject.h fileobject.h floatobject.h \
+	 funcobject.h import.h intobject.h intrcheck.h listobject.h \
+	 longobject.h methodobject.h modsupport.h moduleobject.h mymalloc.h \
+	 myproto.h object.h objimpl.h pydebug.h pyerrors.h pyfpe.h \
+	 pystate.h python.h pythonrun.h rangeobject.h sliceobject.h \
+	 stringobject.h sysmodule.h traceback.h tupleobject.h
+
+grpmodule.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 grp.h import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
+	 traceback.h tupleobject.h
+
+imageop.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
+	 traceback.h tupleobject.h
+
+imgfile.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
+	 traceback.h tupleobject.h
+
+main.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
+	 traceback.h tupleobject.h
+
+mathmodule.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h mymath.h \
+	 myproto.h object.h objimpl.h pydebug.h pyerrors.h pyfpe.h \
+	 pystate.h python.h pythonrun.h rangeobject.h sliceobject.h \
+	 stringobject.h sysmodule.h traceback.h tupleobject.h
+
+md5c.obj: pyconfig.h md5.h
+
+md5module.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h md5.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
+	 traceback.h tupleobject.h
+
+mpzmodule.obj: abstract.h ceval.h classobject.h cobject.h \
+	 complexobject.h pyconfig.h dictobject.h fileobject.h floatobject.h \
+	 funcobject.h import.h intobject.h intrcheck.h listobject.h \
+	 longintrepr.h longobject.h methodobject.h modsupport.h \
+	 moduleobject.h mymalloc.h myproto.h object.h objimpl.h pydebug.h \
+	 pyerrors.h pyfpe.h pystate.h python.h pythonrun.h rangeobject.h \
+	 sliceobject.h stringobject.h sysmodule.h traceback.h tupleobject.h
+
+nismodule.obj: abstract.h c:\mptn\include\sys\time.h ceval.h classobject.h \
+	 cobject.h complexobject.h pyconfig.h dictobject.h fileobject.h \
+	 floatobject.h funcobject.h import.h intobject.h intrcheck.h \
+	 listobject.h longobject.h methodobject.h modsupport.h \
+	 moduleobject.h mymalloc.h myproto.h object.h objimpl.h pydebug.h \
+	 pyerrors.h pyfpe.h pystate.h python.h pythonrun.h rangeobject.h \
+	 sliceobject.h stringobject.h sysmodule.h traceback.h tupleobject.h
+
+operator.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
+	 traceback.h tupleobject.h
+
+parsermodule.obj: abstract.h ceval.h classobject.h cobject.h compile.h \
+	 complexobject.h pyconfig.h dictobject.h fileobject.h floatobject.h \
+	 funcobject.h graminit.h import.h intobject.h intrcheck.h \
+	 listobject.h longobject.h methodobject.h modsupport.h \
+	 moduleobject.h mymalloc.h myproto.h node.h object.h objimpl.h \
+	 pydebug.h pyerrors.h pyfpe.h pystate.h python.h pythonrun.h \
+	 rangeobject.h sliceobject.h stringobject.h sysmodule.h token.h \
+	 traceback.h tupleobject.h
+
+pcremodule.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pcre-internal.h pcre.h pydebug.h pyerrors.h \
+	 pyfpe.h pystate.h python.h pythonrun.h rangeobject.h sliceobject.h \
+	 stringobject.h sysmodule.h traceback.h tupleobject.h
+
+posix.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 mytime.h object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h \
+	 python.h pythonrun.h rangeobject.h sliceobject.h stringobject.h \
+	 sysmodule.h traceback.h tupleobject.h
+
+posixmodule.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 mytime.h object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h \
+	 python.h pythonrun.h rangeobject.h sliceobject.h stringobject.h \
+	 sysmodule.h traceback.h tupleobject.h
+
+puremodule.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
+	 traceback.h tupleobject.h
+
+pwdmodule.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pwd.h pydebug.h pyerrors.h pyfpe.h pystate.h \
+	 python.h pythonrun.h rangeobject.h sliceobject.h stringobject.h \
+	 sysmodule.h traceback.h tupleobject.h
+
+pypcre.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 graminit.h import.h intobject.h intrcheck.h listobject.h \
+	 longobject.h methodobject.h modsupport.h moduleobject.h mymalloc.h \
+	 myproto.h object.h objimpl.h pcre-internal.h pcre.h pydebug.h \
+	 pyerrors.h pyfpe.h pystate.h python.h pythonrun.h rangeobject.h \
+	 sliceobject.h stringobject.h sysmodule.h traceback.h tupleobject.h
+
+readline.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
+	 traceback.h tupleobject.h
+
+resource.obj: abstract.h c:\mptn\include\sys\time.h ceval.h classobject.h \
+	 cobject.h complexobject.h pyconfig.h dictobject.h fileobject.h \
+	 floatobject.h funcobject.h import.h intobject.h intrcheck.h \
+	 listobject.h longobject.h methodobject.h modsupport.h \
+	 moduleobject.h mymalloc.h myproto.h object.h objimpl.h pydebug.h \
+	 pyerrors.h pyfpe.h pystate.h python.h pythonrun.h rangeobject.h \
+	 sliceobject.h stringobject.h sysmodule.h traceback.h tupleobject.h
+
+rgbimgmodule.obj: abstract.h ceval.h classobject.h cobject.h \
+	 complexobject.h pyconfig.h dictobject.h fileobject.h floatobject.h \
+	 funcobject.h import.h intobject.h intrcheck.h listobject.h \
+	 longobject.h methodobject.h modsupport.h moduleobject.h mymalloc.h \
+	 myproto.h object.h objimpl.h pydebug.h pyerrors.h pyfpe.h \
+	 pystate.h python.h pythonrun.h rangeobject.h sliceobject.h \
+	 stringobject.h sysmodule.h traceback.h tupleobject.h
+
+rotormodule.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h mymath.h \
+	 myproto.h object.h objimpl.h pydebug.h pyerrors.h pyfpe.h \
+	 pystate.h python.h pythonrun.h rangeobject.h sliceobject.h \
+	 stringobject.h sysmodule.h traceback.h tupleobject.h
+
+selectmodule.obj: abstract.h ceval.h classobject.h cobject.h \
+	 complexobject.h pyconfig.h dictobject.h fileobject.h floatobject.h \
+	 funcobject.h import.h intobject.h intrcheck.h listobject.h \
+	 longobject.h methodobject.h modsupport.h moduleobject.h mymalloc.h \
+	 myproto.h myselect.h mytime.h object.h objimpl.h pydebug.h \
+	 pyerrors.h pyfpe.h pystate.h python.h pythonrun.h rangeobject.h \
+	 sliceobject.h stringobject.h sysmodule.h traceback.h tupleobject.h
+
+sgimodule.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
+	 traceback.h tupleobject.h
+
+signalmodule.obj: abstract.h ceval.h classobject.h cobject.h \
+	 complexobject.h pyconfig.h dictobject.h fileobject.h floatobject.h \
+	 funcobject.h import.h intobject.h intrcheck.h listobject.h \
+	 longobject.h methodobject.h modsupport.h moduleobject.h mymalloc.h \
+	 myproto.h object.h objimpl.h pydebug.h pyerrors.h pyfpe.h \
+	 pystate.h python.h pythonrun.h rangeobject.h sliceobject.h \
+	 stringobject.h sysmodule.h traceback.h tupleobject.h
+
+socketmodule.obj: abstract.h c:\mptn\include\netinet\in.h \
+	 c:\mptn\include\sys\socket.h ceval.h classobject.h cobject.h \
+	 complexobject.h pyconfig.h dictobject.h fileobject.h floatobject.h \
+	 funcobject.h import.h intobject.h intrcheck.h listobject.h \
+	 longobject.h methodobject.h modsupport.h moduleobject.h mymalloc.h \
+	 myproto.h mytime.h netdb.h object.h objimpl.h pydebug.h pyerrors.h \
+	 pyfpe.h pystate.h python.h pythonrun.h rangeobject.h sliceobject.h \
+	 stringobject.h sysmodule.h traceback.h tupleobject.h
+
+soundex.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
+	 traceback.h tupleobject.h
+
+stdwinmodule.obj: abstract.h ceval.h classobject.h cobject.h \
+	 complexobject.h pyconfig.h dictobject.h fileobject.h floatobject.h \
+	 funcobject.h import.h intobject.h intrcheck.h listobject.h \
+	 longobject.h methodobject.h modsupport.h moduleobject.h mymalloc.h \
+	 myproto.h object.h objimpl.h pydebug.h pyerrors.h pyfpe.h \
+	 pystate.h python.h pythonrun.h rangeobject.h sliceobject.h \
+	 stringobject.h sysmodule.h traceback.h tupleobject.h
+
+stropmodule.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
+	 traceback.h tupleobject.h
+
+structmodule.obj: abstract.h ceval.h classobject.h cobject.h \
+	 complexobject.h pyconfig.h dictobject.h fileobject.h floatobject.h \
+	 funcobject.h import.h intobject.h intrcheck.h listobject.h \
+	 longobject.h methodobject.h modsupport.h moduleobject.h mymalloc.h \
+	 mymath.h myproto.h object.h objimpl.h pydebug.h pyerrors.h pyfpe.h \
+	 pystate.h python.h pythonrun.h rangeobject.h sliceobject.h \
+	 stringobject.h sysmodule.h traceback.h tupleobject.h
+
+sunaudiodev.obj: abstract.h c:\mptn\include\sys\ioctl.h ceval.h \
+	 classobject.h cobject.h complexobject.h pyconfig.h dictobject.h \
+	 fileobject.h floatobject.h funcobject.h import.h intobject.h \
+	 intrcheck.h listobject.h longobject.h methodobject.h modsupport.h \
+	 moduleobject.h mymalloc.h myproto.h object.h objimpl.h pydebug.h \
+	 pyerrors.h pyfpe.h pystate.h python.h pythonrun.h rangeobject.h \
+	 sliceobject.h stringobject.h structmember.h sysmodule.h \
+	 traceback.h tupleobject.h
+
+svmodule.obj: abstract.h c:\mptn\include\sys\time.h ceval.h classobject.h \
+	 cobject.h compile.h complexobject.h pyconfig.h dictobject.h \
+	 fileobject.h floatobject.h funcobject.h import.h intobject.h \
+	 intrcheck.h listobject.h longobject.h methodobject.h modsupport.h \
+	 moduleobject.h mymalloc.h myproto.h object.h objimpl.h pydebug.h \
+	 pyerrors.h pyfpe.h pystate.h python.h pythonrun.h rangeobject.h \
+	 sliceobject.h stringobject.h sysmodule.h traceback.h tupleobject.h \
+	 yuv.h
+
+syslogmodule.obj: abstract.h ceval.h classobject.h cobject.h \
+	 complexobject.h pyconfig.h dictobject.h fileobject.h floatobject.h \
+	 funcobject.h import.h intobject.h intrcheck.h listobject.h \
+	 longobject.h methodobject.h modsupport.h moduleobject.h mymalloc.h \
+	 myproto.h object.h objimpl.h pydebug.h pyerrors.h pyfpe.h \
+	 pystate.h python.h pythonrun.h rangeobject.h sliceobject.h \
+	 stringobject.h syslog.h sysmodule.h traceback.h tupleobject.h
+
+termios.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
+	 traceback.h tupleobject.h
+
+threadmodule.obj: abstract.h ceval.h classobject.h cobject.h \
+	 complexobject.h pyconfig.h dictobject.h fileobject.h floatobject.h \
+	 funcobject.h import.h intobject.h intrcheck.h listobject.h \
+	 longobject.h methodobject.h modsupport.h moduleobject.h mymalloc.h \
+	 myproto.h object.h objimpl.h pydebug.h pyerrors.h pyfpe.h \
+	 pystate.h python.h pythonrun.h rangeobject.h sliceobject.h \
+	 stringobject.h sysmodule.h thread.h traceback.h tupleobject.h
+
+timemodule.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 mytime.h object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h \
+	 python.h pythonrun.h rangeobject.h sliceobject.h stringobject.h \
+	 sysmodule.h traceback.h tupleobject.h
+
+timingmodule.obj: abstract.h ceval.h classobject.h cobject.h \
+	 complexobject.h pyconfig.h dictobject.h fileobject.h floatobject.h \
+	 funcobject.h import.h intobject.h intrcheck.h listobject.h \
+	 longobject.h methodobject.h modsupport.h moduleobject.h mymalloc.h \
+	 myproto.h object.h objimpl.h pydebug.h pyerrors.h pyfpe.h \
+	 pystate.h python.h pythonrun.h rangeobject.h sliceobject.h \
+	 stringobject.h sysmodule.h timing.h traceback.h tupleobject.h
+
+xxmodule.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
+	 traceback.h tupleobject.h
+
+yuvconvert.obj: yuv.h
+
+zlibmodule.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
+	 traceback.h tupleobject.h
+
+abstract.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
+	 traceback.h tupleobject.h
+
+classobject.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h \
+	 structmember.h sysmodule.h traceback.h tupleobject.h
+
+cobject.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
+	 traceback.h tupleobject.h
+
+complexobject.obj: abstract.h ceval.h classobject.h cobject.h \
+	 complexobject.h pyconfig.h dictobject.h fileobject.h floatobject.h \
+	 funcobject.h import.h intobject.h intrcheck.h listobject.h \
+	 longobject.h methodobject.h modsupport.h moduleobject.h mymalloc.h \
+	 mymath.h myproto.h object.h objimpl.h pydebug.h pyerrors.h pyfpe.h \
+	 pystate.h python.h pythonrun.h rangeobject.h sliceobject.h \
+	 stringobject.h sysmodule.h traceback.h tupleobject.h
+
+dictobject.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
+	 traceback.h tupleobject.h
+
+fileobject.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h \
+	 structmember.h sysmodule.h traceback.h tupleobject.h
+
+floatobject.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h mymath.h \
+	 myproto.h object.h objimpl.h pydebug.h pyerrors.h pyfpe.h \
+	 pystate.h python.h pythonrun.h rangeobject.h sliceobject.h \
+	 stringobject.h sysmodule.h traceback.h tupleobject.h
+
+frameobject.obj: abstract.h ceval.h classobject.h cobject.h compile.h \
+	 complexobject.h pyconfig.h dictobject.h fileobject.h floatobject.h \
+	 frameobject.h funcobject.h import.h intobject.h intrcheck.h \
+	 listobject.h longobject.h methodobject.h modsupport.h \
+	 moduleobject.h mymalloc.h myproto.h object.h objimpl.h opcode.h \
+	 pydebug.h pyerrors.h pyfpe.h pystate.h python.h pythonrun.h \
+	 rangeobject.h sliceobject.h stringobject.h structmember.h \
+	 sysmodule.h traceback.h tupleobject.h
+
+funcobject.obj: abstract.h ceval.h classobject.h cobject.h compile.h \
+	 complexobject.h pyconfig.h dictobject.h fileobject.h floatobject.h \
+	 funcobject.h import.h intobject.h intrcheck.h listobject.h \
+	 longobject.h methodobject.h modsupport.h moduleobject.h mymalloc.h \
+	 myproto.h object.h objimpl.h pydebug.h pyerrors.h pyfpe.h \
+	 pystate.h python.h pythonrun.h rangeobject.h sliceobject.h \
+	 stringobject.h structmember.h sysmodule.h traceback.h \
+	 tupleobject.h
+
+intobject.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
+	 traceback.h tupleobject.h
+
+listobject.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
+	 traceback.h tupleobject.h
+
+longobject.obj: abstract.h ceval.h classobject.h cobject.h \
+	 complexobject.h pyconfig.h dictobject.h fileobject.h floatobject.h \
+	 funcobject.h import.h intobject.h intrcheck.h listobject.h \
+	 longintrepr.h longobject.h methodobject.h modsupport.h \
+	 moduleobject.h mymalloc.h mymath.h myproto.h object.h objimpl.h \
+	 pydebug.h pyerrors.h pyfpe.h pystate.h python.h pythonrun.h \
+	 rangeobject.h sliceobject.h stringobject.h sysmodule.h traceback.h \
+	 tupleobject.h
+
+methodobject.obj: abstract.h ceval.h classobject.h cobject.h \
+	 complexobject.h pyconfig.h dictobject.h fileobject.h floatobject.h \
+	 funcobject.h import.h intobject.h intrcheck.h listobject.h \
+	 longobject.h methodobject.h modsupport.h moduleobject.h mymalloc.h \
+	 myproto.h object.h objimpl.h pydebug.h pyerrors.h pyfpe.h \
+	 pystate.h python.h pythonrun.h rangeobject.h sliceobject.h \
+	 stringobject.h sysmodule.h token.h traceback.h tupleobject.h
+
+moduleobject.obj: abstract.h ceval.h classobject.h cobject.h \
+	 complexobject.h pyconfig.h dictobject.h fileobject.h floatobject.h \
+	 funcobject.h import.h intobject.h intrcheck.h listobject.h \
+	 longobject.h methodobject.h modsupport.h moduleobject.h mymalloc.h \
+	 myproto.h object.h objimpl.h pydebug.h pyerrors.h pyfpe.h \
+	 pystate.h python.h pythonrun.h rangeobject.h sliceobject.h \
+	 stringobject.h sysmodule.h traceback.h tupleobject.h
+
+object.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
+	 traceback.h tupleobject.h
+
+rangeobject.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
+	 traceback.h tupleobject.h
+
+sliceobject.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
+	 traceback.h tupleobject.h
+
+stringobject.obj: abstract.h ceval.h classobject.h cobject.h \
+	 complexobject.h pyconfig.h dictobject.h fileobject.h floatobject.h \
+	 funcobject.h import.h intobject.h intrcheck.h listobject.h \
+	 longobject.h methodobject.h modsupport.h moduleobject.h mymalloc.h \
+	 mymath.h myproto.h object.h objimpl.h pydebug.h pyerrors.h pyfpe.h \
+	 pystate.h python.h pythonrun.h rangeobject.h sliceobject.h \
+	 stringobject.h sysmodule.h traceback.h tupleobject.h
+
+tupleobject.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
+	 traceback.h tupleobject.h
+
+typeobject.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
+	 traceback.h tupleobject.h
+
+xxobject.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
+	 traceback.h tupleobject.h
+
+acceler.obj: bitset.h pyconfig.h grammar.h mymalloc.h myproto.h node.h \
+	 parser.h pgenheaders.h pydebug.h token.h
+
+bitset.obj: bitset.h pyconfig.h mymalloc.h myproto.h pgenheaders.h pydebug.h
+
+firstsets.obj: bitset.h pyconfig.h grammar.h mymalloc.h myproto.h \
+	 pgenheaders.h pydebug.h token.h
+
+grammar.obj: bitset.h pyconfig.h grammar.h mymalloc.h myproto.h \
+	 pgenheaders.h pydebug.h token.h
+
+grammar1.obj: bitset.h pyconfig.h grammar.h mymalloc.h myproto.h \
+	 pgenheaders.h pydebug.h token.h
+
+intrcheck.obj: pyconfig.h intrcheck.h mymalloc.h myproto.h
+
+listnode.obj: pyconfig.h mymalloc.h myproto.h node.h pgenheaders.h pydebug.h \
+	 token.h
+
+metagrammar.obj: bitset.h pyconfig.h grammar.h metagrammar.h mymalloc.h \
+	 myproto.h pgen.h pgenheaders.h pydebug.h
+
+myreadline.obj: pyconfig.h intrcheck.h mymalloc.h myproto.h
+
+node.obj: pyconfig.h mymalloc.h myproto.h node.h pgenheaders.h pydebug.h
+
+parser.obj: bitset.h pyconfig.h errcode.h grammar.h mymalloc.h \
+	 myproto.h node.h parser.h pgenheaders.h pydebug.h token.h
+
+parsetok.obj: bitset.h pyconfig.h errcode.h grammar.h mymalloc.h myproto.h \
+	 node.h parser.h parsetok.h pgenheaders.h pydebug.h token.h \
+	 tokenizer.h
+
+pgen.obj: bitset.h pyconfig.h grammar.h metagrammar.h mymalloc.h \
+	 myproto.h node.h pgen.h pgenheaders.h pydebug.h token.h
+
+pgenmain.obj: bitset.h pyconfig.h grammar.h mymalloc.h myproto.h node.h \
+	 parsetok.h pgen.h pgenheaders.h pydebug.h
+
+printgrammar.obj: bitset.h pyconfig.h grammar.h mymalloc.h myproto.h \
+	 pgenheaders.h pydebug.h
+
+tokenizer.obj: pyconfig.h errcode.h mymalloc.h myproto.h pgenheaders.h \
+	 pydebug.h token.h tokenizer.h
+
+atof.obj: pyconfig.h
+
+bltinmodule.obj: abstract.h ceval.h classobject.h cobject.h compile.h \
+	 complexobject.h pyconfig.h dictobject.h eval.h fileobject.h \
+	 floatobject.h funcobject.h import.h intobject.h intrcheck.h \
+	 listobject.h longobject.h methodobject.h modsupport.h \
+	 moduleobject.h mymalloc.h mymath.h myproto.h node.h object.h \
+	 objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
+	 traceback.h tupleobject.h
+
+ceval.obj: abstract.h ceval.h classobject.h cobject.h compile.h \
+	 complexobject.h pyconfig.h dictobject.h eval.h fileobject.h \
+	 floatobject.h frameobject.h funcobject.h import.h intobject.h \
+	 intrcheck.h listobject.h longobject.h methodobject.h modsupport.h \
+	 moduleobject.h mymalloc.h myproto.h object.h objimpl.h opcode.h \
+	 pydebug.h pyerrors.h pyfpe.h pystate.h python.h pythonrun.h \
+	 rangeobject.h sliceobject.h stringobject.h sysmodule.h traceback.h \
+	 tupleobject.h
+
+compile.obj: abstract.h ceval.h classobject.h cobject.h compile.h \
+	 complexobject.h pyconfig.h dictobject.h fileobject.h floatobject.h \
+	 funcobject.h graminit.h import.h intobject.h intrcheck.h \
+	 listobject.h longobject.h methodobject.h modsupport.h \
+	 moduleobject.h mymalloc.h myproto.h node.h object.h objimpl.h \
+	 opcode.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h \
+	 structmember.h sysmodule.h token.h traceback.h tupleobject.h
+
+errors.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
+	 traceback.h tupleobject.h
+
+fmod.obj: pyconfig.h mymath.h
+
+frozen.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
+	 traceback.h tupleobject.h
+
+frozenmain.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
+	 traceback.h tupleobject.h
+
+getargs.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
+	 traceback.h tupleobject.h
+
+getcompiler.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
+	 traceback.h tupleobject.h
+
+getcopyright.obj: abstract.h ceval.h classobject.h cobject.h \
+	 complexobject.h pyconfig.h dictobject.h fileobject.h floatobject.h \
+	 funcobject.h import.h intobject.h intrcheck.h listobject.h \
+	 longobject.h methodobject.h modsupport.h moduleobject.h mymalloc.h \
+	 myproto.h object.h objimpl.h pydebug.h pyerrors.h pyfpe.h \
+	 pystate.h python.h pythonrun.h rangeobject.h sliceobject.h \
+	 stringobject.h sysmodule.h traceback.h tupleobject.h
+
+getmtime.obj: pyconfig.h
+
+getplatform.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
+	 traceback.h tupleobject.h
+
+getversion.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h patchlevel.h pydebug.h pyerrors.h pyfpe.h \
+	 pystate.h python.h pythonrun.h rangeobject.h sliceobject.h \
+	 stringobject.h sysmodule.h traceback.h tupleobject.h
+
+graminit.obj: bitset.h pyconfig.h grammar.h mymalloc.h myproto.h \
+	 pgenheaders.h pydebug.h
+
+hypot.obj: pyconfig.h mymath.h myproto.h
+
+import.obj: abstract.h ceval.h classobject.h cobject.h compile.h \
+	 complexobject.h pyconfig.h dictobject.h errcode.h eval.h \
+	 fileobject.h floatobject.h funcobject.h import.h importdl.h \
+	 intobject.h intrcheck.h listobject.h longobject.h marshal.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 node.h object.h objimpl.h osdefs.h pydebug.h pyerrors.h pyfpe.h \
+	 pystate.h python.h pythonrun.h rangeobject.h sliceobject.h \
+	 stringobject.h sysmodule.h token.h traceback.h tupleobject.h
+
+importdl.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h importdl.h intobject.h intrcheck.h listobject.h \
+	 longobject.h methodobject.h modsupport.h moduleobject.h mymalloc.h \
+	 myproto.h object.h objimpl.h osdefs.h pydebug.h pyerrors.h pyfpe.h \
+	 pystate.h python.h pythonrun.h rangeobject.h sliceobject.h \
+	 stringobject.h sysmodule.h traceback.h tupleobject.h
+
+marshal.obj: abstract.h ceval.h classobject.h cobject.h compile.h \
+	 complexobject.h pyconfig.h dictobject.h fileobject.h floatobject.h \
+	 funcobject.h import.h intobject.h intrcheck.h listobject.h \
+	 longintrepr.h longobject.h marshal.h methodobject.h modsupport.h \
+	 moduleobject.h mymalloc.h myproto.h object.h objimpl.h pydebug.h \
+	 pyerrors.h pyfpe.h pystate.h python.h pythonrun.h rangeobject.h \
+	 sliceobject.h stringobject.h sysmodule.h traceback.h tupleobject.h
+
+modsupport.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
+	 traceback.h tupleobject.h
+
+mystrtoul.obj: pyconfig.h
+
+pyfpe.obj: pyconfig.h pyfpe.h
+
+pystate.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
+	 traceback.h tupleobject.h
+
+pythonrun.obj: abstract.h bitset.h ceval.h classobject.h cobject.h \
+	 compile.h complexobject.h pyconfig.h dictobject.h errcode.h eval.h \
+	 fileobject.h floatobject.h funcobject.h grammar.h import.h \
+	 intobject.h intrcheck.h listobject.h longobject.h marshal.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 node.h object.h objimpl.h parsetok.h pydebug.h pyerrors.h pyfpe.h \
+	 pystate.h python.h pythonrun.h rangeobject.h sliceobject.h \
+	 stringobject.h sysmodule.h traceback.h tupleobject.h
+
+sigcheck.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
+	 pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
+	 traceback.h tupleobject.h
+
+strdup.obj: pyconfig.h mymalloc.h myproto.h
+
+strtod.obj: pyconfig.h
+
+structmember.obj: abstract.h ceval.h classobject.h cobject.h \
+	 complexobject.h pyconfig.h dictobject.h fileobject.h floatobject.h \
+	 funcobject.h import.h intobject.h intrcheck.h listobject.h \
+	 longobject.h methodobject.h modsupport.h moduleobject.h mymalloc.h \
+	 myproto.h object.h objimpl.h pydebug.h pyerrors.h pyfpe.h \
+	 pystate.h python.h pythonrun.h rangeobject.h sliceobject.h \
+	 stringobject.h structmember.h sysmodule.h traceback.h \
+	 tupleobject.h
+
+sysmodule.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
+	 import.h intobject.h intrcheck.h listobject.h longobject.h \
+	 methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
+	 object.h objimpl.h osdefs.h pydebug.h pyerrors.h pyfpe.h pystate.h \
+	 python.h pythonrun.h rangeobject.h sliceobject.h stringobject.h \
+	 sysmodule.h traceback.h tupleobject.h
+
+thread.obj: pyconfig.h thread.h
+
+traceback.obj: abstract.h ceval.h classobject.h cobject.h compile.h \
+	 complexobject.h pyconfig.h dictobject.h fileobject.h floatobject.h \
+	 frameobject.h funcobject.h import.h intobject.h intrcheck.h \
+	 listobject.h longobject.h methodobject.h modsupport.h \
+	 moduleobject.h mymalloc.h myproto.h object.h objimpl.h osdefs.h \
+	 pydebug.h pyerrors.h pyfpe.h pystate.h python.h pythonrun.h \
+	 rangeobject.h sliceobject.h stringobject.h structmember.h \
+	 sysmodule.h traceback.h tupleobject.h

Added: vendor/Python/current/PC/os2vacpp/pyconfig.h
===================================================================
--- vendor/Python/current/PC/os2vacpp/pyconfig.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/os2vacpp/pyconfig.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,213 @@
+#ifndef Py_CONFIG_H
+#define Py_CONFIG_H
+
+/**********************************************************************
+ * pyconfig.h.  NOT Generated automatically by configure.
+ *
+ * This is a manually maintained version used for the IBM VisualAge
+ * C/C++ compiler on the OS/2 platform.  It is a standard part of
+ * the Python distribution.
+ *
+ * FILESYSTEM DEFINES:
+ * The code specific to a particular way of naming files and
+ * directory paths should be wrapped around one of the following
+ * #defines:
+ *
+ *     DOSFILESYS   PCDOS-Style (for PCDOS, Windows and OS/2)
+ *     MACFILESYS   Macintosh-Style
+ *     UNIXFILESYS  Unix-Style
+ *     AMIGAFILESYS AmigaDOS-Style
+ * 
+ * Because of the different compilers and operating systems in
+ * use on the Intel platform, neither the compiler name nor
+ * the operating system name is sufficient.
+ *
+ * OS/2 DEFINES:
+ * The code specific to OS/2's Program API should be wrapped around
+ *
+ * __TOS_OS2__   Target Operating System, OS/2
+ *
+ * Any code specific to the compiler itself should be wrapped with
+ *
+ * __IBMC__      IBM C Compiler
+ * __IBMCPP__    IBM C++ Compiler
+ *
+ * Note that since the VisualAge C/C++ compiler is also available
+ * for the Windows platform, it may be necessary to use both a
+ * __TOS_OS2__ and a __IBMC__ to select a very specific environment.
+ *
+ **********************************************************************/
+
+/*
+ * Some systems require special declarations for data items imported
+ * or exported from dynamic link libraries.  Note that the definition
+ * of DL_IMPORT covers both cases.  Define USE_DL_IMPORT for the client
+ * of a DLL.  Define USE_DL_EXPORT when making a DLL.
+ */
+
+#include <io.h>
+
+/* Configuration Options for Finding Modules */
+#define PREFIX                 ""
+#define EXEC_PREFIX            ""
+
+/* Provide a default library so writers of extension modules
+ * won't have to explicitly specify it anymore
+ */
+#pragma library("Python24.lib")
+
+/***************************************************/
+/*    32-Bit IBM VisualAge C/C++ v3.0 for OS/2     */
+/*  (Convert Compiler Flags into Useful Switches)  */
+/***************************************************/
+#define PLATFORM    "os2"
+#define COMPILER    "[VisualAge C/C++]"
+#define PYOS_OS2    /* Define Indicator of Operating System */
+#define PYCC_VACPP  /* Define Indicator of C Compiler */
+
+  /* Platform Filesystem */
+#define PYTHONPATH  ".;.\\lib;.\\lib\\plat-win;.\\lib\\lib-tk"
+#define DOSFILESYS  /* OS/2 Uses the DOS File Naming Conventions */
+/* #define IMPORT_8x3_NAMES (let's move up to long filenames) */
+
+  /* Platform CPU-Mode Dependencies */
+#define WORD_BIT                32 /* OS/2 is a 32-Bit Operating System */
+#define LONG_BIT                32
+#define SIZEOF_INT               4 /* Count of Bytes in an (int)            */
+#define SIZEOF_LONG              4 /* Count of Bytes in a (long)            */
+#define SIZEOF_VOID_P            4 /* Count of Bytes in a (void *)          */
+/* #define HAVE_LONG_LONG     1 */ /* VAC++ does not support (long long)    */
+/* #define SIZEOF_LONG_LONG   8 */ /* Count of Bytes in a (long long)       */
+
+/* unicode definines */
+#define Py_USING_UNICODE
+#define PY_UNICODE_TYPE    wchar_t
+#define Py_UNICODE_SIZE SIZEOF_SHORT
+
+/* dynamic loading */
+#define HAVE_DYNAMIC_LOADING 1
+
+/* Define if type char is unsigned and you are not using gcc.  */
+#ifndef __CHAR_UNSIGNED__
+/* #undef __CHAR_UNSIGNED__ */
+#endif
+
+typedef int mode_t;
+typedef int uid_t;
+typedef int gid_t;
+typedef int pid_t;
+
+#if defined(__MULTI__)     /* If Compiler /Gt+ Multithread Option Enabled,  */
+  #define WITH_THREAD            1 /* Enable Threading Throughout Python    */
+  #define OS2_THREADS            1 /* And Use the OS/2 Flavor of Threads    */
+/* #define _REENTRANT 1 */ /* Use thread-safe errno, h_errno, and other fns */
+#endif
+
+  /* Compiler Runtime Library Capabilities */
+#include <ctype.h>
+#include <direct.h>
+/* #undef BAD_STATIC_FORWARD */ /* if compiler botches static fwd decls */
+
+#define STDC_HEADERS             1 /* VAC++ is an ANSI C Compiler           */
+#define HAVE_HYPOT               1 /* hypot()                               */
+#define HAVE_PUTENV              1 /* putenv()                              */
+/* #define VA_LIST_IS_ARRAY   1 */ /* if va_list is an array of some kind   */
+/* #define HAVE_CONIO_H       1 */ /* #include <conio.h>                    */
+#define HAVE_ERRNO_H             1 /* #include <errno.h>                    */
+#define HAVE_SYS_STAT_H          1 /* #include <sys/stat.h>                 */
+#define HAVE_SYS_TYPES_H         1 /* #include <sys/types.h>                */
+
+  /* Variable-Arguments/Prototypes */
+#define HAVE_PROTOTYPES          1 /* VAC++ supports C Function Prototypes  */
+#define HAVE_STDARG_PROTOTYPES   1 /* Our <stdarg.h> has prototypes         */
+
+  /* String/Memory/Locale Operations */
+#define HAVE_MEMMOVE             1 /* memmove()                             */
+#define HAVE_STRERROR            1 /* strerror()                            */
+#define HAVE_SETLOCALE           1 /* setlocale()                           */
+#define MALLOC_ZERO_RETURNS_NULL 1 /* Our malloc(0) returns a NULL ptr      */
+
+  /* Signal Handling */
+#define HAVE_SIGNAL_H            1 /* signal.h                              */
+#define RETSIGTYPE            void /* Return type of handlers (int or void) */
+/* #undef WANT_SIGFPE_HANDLER   */ /* Handle SIGFPE (see Include/pyfpe.h)   */
+/* #define HAVE_ALARM         1 */ /* alarm()                               */
+/* #define HAVE_SIGINTERRUPT  1 */ /* siginterrupt()                        */
+/* #define HAVE_SIGRELSE      1 */ /* sigrelse()                            */
+#define DONT_HAVE_SIG_ALARM      1
+#define DONT_HAVE_SIG_PAUSE      1
+
+  /* Clock/Time Support */
+#define HAVE_FTIME               1 /* We have ftime() in <sys/timeb.h>      */
+#define HAVE_CLOCK               1 /* clock()                               */
+#define HAVE_STRFTIME            1 /* strftime()                            */
+#define HAVE_MKTIME              1 /* mktime()                              */
+#define HAVE_TZNAME              1 /* No tm_zone but do have tzname[]       */
+#define HAVE_TIMES               1 /* #include <sys/times.h>                */
+#define HAVE_SYS_UTIME_H         1 /* #include <sys/utime.h>                */
+/* #define HAVE_UTIME_H       1 */ /* #include <utime.h>                    */
+#define HAVE_SYS_TIME_H          1 /* #include <sys/time.h>                 */
+/* #define TM_IN_SYS_TIME     1 */ /* <sys/time.h> declares struct tm       */
+#define HAVE_GETTIMEOFDAY        1 /* gettimeofday()                        */
+/* #define GETTIMEOFDAY_NO_TZ 1 */ /* gettimeofday() does not have 2nd arg  */
+/* #define HAVE_TIMEGM        1 */ /* timegm()                              */
+#define TIME_WITH_SYS_TIME       1 /* Mix <sys/time.h> and <time.h>         */
+#define SYS_SELECT_WITH_SYS_TIME 1 /* Mix <sys/select.h> and <sys/time.h>   */
+/* #define HAVE_ALTZONE       1 */ /* if <time.h> defines altzone           */
+
+  /* Network/Sockets Support */
+#define HAVE_SYS_SELECT_H       1 /* #include <sys/select.h>                */
+#define BSD_SELECT              1 /* Use BSD versus OS/2 form of select()   */
+#define HAVE_SELECT             1 /* select()                               */
+#define HAVE_GETPEERNAME        1 /* getpeername()                          */
+/* #undef HAVE_GETHOSTNAME_R 1 */ /* gethostname_r()                        */
+
+  /* File I/O */
+#define HAVE_DUP2                1 /* dup2()                                */
+#define HAVE_EXECV               1 /* execv()                               */
+#define HAVE_SETVBUF             1 /* setvbuf()                             */
+#define HAVE_GETCWD              1 /* getcwd()                              */
+#define HAVE_PIPE                1 /* pipe()     [OS/2-specific code added] */
+#define HAVE_IO_H                1 /* #include <io.h>                       */
+#define HAVE_FCNTL_H             1 /* #include <fcntl.h>                    */
+#define HAVE_DIRECT_H            1 /* #include <direct.h>                   */
+/* #define HAVE_FLOCK         1 */ /* flock()                               */
+/* #define HAVE_TRUNCATE      1 */ /* truncate()                            */
+/* #define HAVE_FTRUNCATE     1 */ /* ftruncate()                           */
+/* #define HAVE_LSTAT         1 */ /* lstat()                               */
+/* #define HAVE_DIRENT_H      1 */ /* #include <dirent.h>                   */
+/* #define HAVE_OPENDIR       1 */ /* opendir()                             */
+
+  /* Process Operations */
+#define HAVE_PROCESS_H           1 /* #include <process.h>                  */
+#define HAVE_GETPID              1 /* getpid()                              */
+#define HAVE_SYSTEM              1 /* system()                              */
+#define HAVE_WAIT                1 /* wait()                                */
+#define HAVE_KILL                1 /* kill()     [OS/2-specific code added] */
+#define HAVE_POPEN               1 /* popen()    [OS/2-specific code added] */
+/* #define HAVE_GETPPID       1 */ /* getppid()                             */
+/* #define HAVE_WAITPID       1 */ /* waitpid()                             */
+/* #define HAVE_FORK          1 */ /* fork()                                */
+
+  /* User/Group ID Queries */
+/* #define HAVE_GETEGID       1 */
+/* #define HAVE_GETEUID       1 */
+/* #define HAVE_GETGID        1 */
+/* #define HAVE_GETUID        1 */
+
+  /* Unix-Specific */
+/* #define HAVE_SYS_UN_H            1 /* #include <sys/un.h>                   */
+/* #define HAVE_SYS_UTSNAME_H 1 */ /* #include <sys/utsname.h>              */
+/* #define HAVE_SYS_WAIT_H    1 */ /* #include <sys/wait.h>                 */
+/* #define HAVE_UNISTD_H      1 */ /* #include <unistd.h>                   */
+/* #define HAVE_UNAME         1 */ /* uname ()                              */
+
+/* Define if you want documentation strings in extension modules */
+#define WITH_DOC_STRINGS 1
+
+#ifdef USE_DL_EXPORT
+  #define DL_IMPORT(RTYPE) RTYPE _System
+#endif
+
+#endif /* !Py_CONFIG_H */
+

Added: vendor/Python/current/PC/os2vacpp/python.def
===================================================================
--- vendor/Python/current/PC/os2vacpp/python.def	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/os2vacpp/python.def	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,473 @@
+LIBRARY        PYTHON24 INITINSTANCE TERMINSTANCE
+DESCRIPTION    'Python 2.4 Core DLL'
+PROTMODE
+DATA           MULTIPLE NONSHARED
+
+EXPORTS
+               ; Data
+               PyCFunction_Type
+               PyCObject_Type
+               PyClass_Type
+               PyCode_Type
+               PyComplex_Type
+               PyDict_Type
+               PyExc_ArithmeticError
+               PyExc_AssertionError
+               PyExc_AttributeError
+               PyExc_EOFError
+               PyExc_EnvironmentError
+               PyExc_Exception
+               PyExc_FloatingPointError
+               PyExc_IOError
+               PyExc_ImportError
+               PyExc_IndexError
+               PyExc_KeyError
+               PyExc_KeyboardInterrupt
+               PyExc_LookupError
+               PyExc_MemoryError
+               PyExc_MemoryErrorInst
+               PyExc_NameError
+               PyExc_OSError
+               PyExc_OverflowError
+               PyExc_RuntimeError
+               PyExc_StandardError
+               PyExc_SyntaxError
+               PyExc_SystemError
+               PyExc_SystemExit
+               PyExc_TypeError
+               PyExc_ValueError
+               PyExc_ZeroDivisionError
+               PyFile_Type
+               PyFloat_Type
+               PyFrame_Type
+               PyFunction_Type
+               PyImport_FrozenModules
+               PyImport_Inittab
+               PyInstance_Type
+               PyInt_Type
+               PyList_Type
+               PyLong_Type
+               PyMethod_Type
+               PyModule_Type
+               PyOS_InputHook
+               PyOS_ReadlineFunctionPointer
+               PyRange_Type
+               PySlice_Type
+               PyString_Type
+               PyTraceBack_Type
+               PyTuple_Type
+               PyType_Type
+               Py_DebugFlag
+               Py_FrozenFlag
+               Py_InteractiveFlag
+               Py_NoSiteFlag
+               Py_OptimizeFlag
+               Py_TabcheckFlag
+               Py_UseClassExceptionsFlag
+               Py_VerboseFlag
+               _PyImport_Filetab
+               _PyImport_Inittab
+               _PyParser_Grammar
+               _PyParser_TokenNames
+               _Py_EllipsisObject
+               _Py_NoneStruct
+               _Py_PackageContext
+               _Py_TrueStruct
+               _Py_ZeroStruct
+               _Py_abstract_hack
+               _Py_cobject_hack
+               _Py_re_syntax
+               _Py_re_syntax_table
+
+               ; Code
+               PyArg_Parse
+               PyArg_ParseTuple
+               PyArg_ParseTupleAndKeywords
+               PyArg_VaParse
+               PyCFunction_Fini
+               PyCFunction_GetFlags
+               PyCFunction_GetFunction
+               PyCFunction_GetSelf
+               PyCFunction_New
+               PyCObject_AsVoidPtr
+               PyCObject_FromVoidPtrAndDesc
+               PyCObject_FromVoidPtr
+               PyCObject_GetDesc
+               PyCObject_Import
+               PyCallable_Check
+               PyClass_IsSubclass
+               PyClass_New
+               PyCode_Addr2Line
+               PyCode_New
+               PyComplex_AsCComplex
+               PyComplex_FromCComplex
+               PyComplex_FromDoubles
+               PyComplex_ImagAsDouble
+               PyComplex_RealAsDouble
+               PyDict_Clear
+               PyDict_DelItem
+               PyDict_DelItemString
+               PyDict_GetItem
+               PyDict_GetItemString
+               PyDict_Items
+               PyDict_Keys
+               PyDict_New
+               PyDict_Next
+               PyDict_SetItem
+               PyDict_SetItemString
+               PyDict_Size
+               PyDict_Values
+               PyErr_BadArgument
+               PyErr_BadInternalCall
+               PyErr_CheckSignals
+               PyErr_Clear
+               PyErr_ExceptionMatches
+               PyErr_Fetch
+               PyErr_Format
+               PyErr_GivenExceptionMatches
+               PyErr_NewException
+               PyErr_NoMemory
+               PyErr_NormalizeException
+               PyErr_Occurred
+               PyErr_Print
+               PyErr_PrintEx
+               PyErr_Restore
+               PyErr_SetFromErrno
+               PyErr_SetFromErrnoWithFilename
+               PyErr_SetInterrupt
+               PyErr_SetNone
+               PyErr_SetObject
+               PyErr_SetString
+               PyEval_AcquireLock
+               PyEval_AcquireThread
+               PyEval_CallFunction
+               PyEval_CallMethod
+               PyEval_CallObject
+               PyEval_CallObjectWithKeywords
+               PyEval_EvalCode
+               PyEval_GetBuiltins
+               PyEval_GetFrame
+               PyEval_GetGlobals
+               PyEval_GetLocals
+               PyEval_GetRestricted
+               PyEval_InitThreads
+               PyEval_ReleaseLock
+               PyEval_ReleaseThread
+               PyEval_RestoreThread
+               PyEval_SaveThread
+               PyFile_AsFile
+               PyFile_FromFile
+               PyFile_FromString
+               PyFile_GetLine
+               PyFile_Name
+               PyFile_SetBufSize
+               PyFile_SoftSpace
+               PyFile_WriteObject
+               PyFile_WriteString
+               PyFloat_AsDouble
+               PyFloat_AsString
+               PyFloat_Fini
+               PyFloat_FromDouble
+               PyFrame_BlockPop
+               PyFrame_BlockSetup
+               PyFrame_FastToLocals
+               PyFrame_Fini
+               PyFrame_LocalsToFast
+               PyFrame_New
+               PyFunction_GetCode
+               PyFunction_GetDefaults
+               PyFunction_GetGlobals
+               PyFunction_New
+               PyFunction_SetDefaults
+               PyGrammar_AddAccelerators
+               PyGrammar_FindDFA
+               PyGrammar_LabelRepr
+               PyGrammar_RemoveAccelerators
+               PyImport_AddModule
+               PyImport_AppendInittab
+               PyImport_Cleanup
+               PyImport_ExecCodeModule
+               PyImport_ExecCodeModuleEx
+               PyImport_ExtendInittab
+               PyImport_GetMagicNumber
+               PyImport_GetModuleDict
+               PyImport_Import
+               PyImport_ImportFrozenModule
+               PyImport_ImportModule
+               PyImport_ImportModuleEx
+               PyImport_ReloadModule
+               PyInstance_DoBinOp
+               PyInstance_New
+               PyInt_AsLong
+               PyInt_Fini
+               PyInt_FromLong
+               PyInt_GetMax
+               PyInterpreterState_Clear
+               PyInterpreterState_Delete
+               PyInterpreterState_New
+               PyList_Append
+               PyList_AsTuple
+               PyList_GetItem
+               PyList_GetSlice
+               PyList_Insert
+               PyList_New
+               PyList_Reverse
+               PyList_SetItem
+               PyList_SetSlice
+               PyList_Size
+               PyList_Sort
+               PyLong_AsDouble
+               PyLong_AsLong
+;               PyLong_AsLongLong
+               PyLong_AsUnsignedLong
+;               PyLong_AsUnsignedLongLong
+               PyLong_AsVoidPtr
+               PyLong_FromDouble
+               PyLong_FromLong
+;               PyLong_FromLongLong
+               PyLong_FromString
+               PyLong_FromUnsignedLong
+;               PyLong_FromUnsignedLongLong
+               PyLong_FromVoidPtr
+               PyMapping_Check
+               PyMapping_GetItemString
+               PyMapping_HasKey
+               PyMapping_HasKeyString
+               PyMapping_Length
+               PyMapping_SetItemString
+               PyMarshal_Init
+               PyMarshal_ReadLongFromFile
+               PyMarshal_ReadObjectFromFile
+               PyMarshal_ReadObjectFromString
+               PyMarshal_WriteLongToFile
+               PyMarshal_WriteObjectToFile
+               PyMarshal_WriteObjectToString
+               PyMem_Free
+               PyMem_Malloc
+               PyMem_Realloc
+               PyMember_Get
+               PyMember_Set
+               PyMethod_Class
+               PyMethod_Fini
+               PyMethod_Function
+               PyMethod_New
+               PyMethod_Self
+               PyModule_GetDict
+               PyModule_GetName
+               PyModule_New
+               PyNode_AddChild
+               PyNode_Compile
+               PyNode_Free
+;               PyNode_ListTree
+               PyNode_New
+               PyNumber_Absolute
+               PyNumber_Add
+               PyNumber_And
+               PyNumber_Check
+               PyNumber_Coerce
+               PyNumber_CoerceEx
+               PyNumber_Divide
+               PyNumber_Divmod
+               PyNumber_Float
+               PyNumber_Int
+               PyNumber_Invert
+               PyNumber_Long
+               PyNumber_Lshift
+               PyNumber_Multiply
+               PyNumber_Negative
+               PyNumber_Or
+               PyNumber_Positive
+               PyNumber_Power
+               PyNumber_Remainder
+               PyNumber_Rshift
+               PyNumber_Subtract
+               PyNumber_Xor
+               PyOS_AfterFork
+               PyOS_FiniInterrupts
+               PyOS_GetLastModificationTime
+               PyOS_InitInterrupts
+               PyOS_InterruptOccurred
+               PyOS_Readline
+               PyOS_StdioReadline
+               PyOS_strtol
+               PyOS_strtoul
+               PyObject_CallFunction
+               PyObject_CallMethod
+               PyObject_CallObject
+               PyObject_Cmp
+               PyObject_Compare
+               PyObject_DelItem
+               PyObject_GetAttr
+               PyObject_GetAttrString
+               PyObject_GetItem
+               PyObject_HasAttr
+               PyObject_HasAttrString
+               PyObject_Hash
+               PyObject_IsTrue
+               PyObject_Length
+               PyObject_Not
+               PyObject_Print
+               PyObject_Repr
+               PyObject_SetAttr
+               PyObject_SetAttrString
+               PyObject_SetItem
+               PyObject_Str
+               PyObject_Type
+               PyParser_AddToken
+               PyParser_Delete
+               PyParser_New
+               PyParser_ParseFile
+               PyParser_ParseString
+               PyParser_SimpleParseFile
+               PyParser_SimpleParseString
+               PyRange_New
+               PyRun_AnyFile
+               PyRun_File
+               PyRun_InteractiveLoop
+               PyRun_InteractiveOne
+               PyRun_SimpleFile
+               PyRun_SimpleString
+               PyRun_String
+               PySequence_Check
+               PySequence_Concat
+               PySequence_Contains
+               PySequence_Count
+               PySequence_DelItem
+               PySequence_DelSlice
+               PySequence_GetItem
+               PySequence_GetSlice
+               PySequence_In
+               PySequence_Index
+               PySequence_Length
+               PySequence_List
+               PySequence_Repeat
+               PySequence_SetItem
+               PySequence_SetSlice
+               PySequence_Tuple
+               PySlice_GetIndices
+               PySlice_New
+               PyString_AsString
+               PyString_Concat
+               PyString_ConcatAndDel
+               PyString_Fini
+               PyString_Format
+               PyString_FromString
+               PyString_FromStringAndSize
+               PyString_InternFromString
+               PyString_InternInPlace
+               PyString_Size
+               PySys_GetFile
+               PySys_GetObject
+               PySys_SetArgv
+               PySys_SetObject
+               PySys_SetPath
+               PySys_WriteStderr
+               PySys_WriteStdout
+               PyThreadState_Clear
+               PyThreadState_Delete
+               PyThreadState_Get
+               PyThreadState_GetDict
+               PyThreadState_New
+               PyThreadState_Swap
+               PyThread__exit_thread
+               PyThread_acquire_lock
+               PyThread_allocate_lock
+               PyThread_allocate_sema
+               PyThread_down_sema
+               PyThread_exit_thread
+               PyThread_free_lock
+               PyThread_free_sema
+               PyThread_get_thread_ident
+               PyThread_init_thread
+               PyThread_release_lock
+               PyThread_start_new_thread
+               PyThread_up_sema
+               PyToken_OneChar
+               PyToken_TwoChars
+               PyTokenizer_Free
+               PyTokenizer_FromFile
+               PyTokenizer_FromString
+               PyTokenizer_Get
+               PyTraceBack_Here
+               PyTraceBack_Print
+               PyTuple_Fini
+               PyTuple_GetItem
+               PyTuple_GetSlice
+               PyTuple_New
+               PyTuple_SetItem
+               PyTuple_Size
+               Py_AddPendingCall
+               Py_AtExit
+               Py_BuildValue
+               Py_CompileString
+               Py_EndInterpreter
+               Py_Exit
+               Py_FatalError
+               Py_FdIsInteractive
+               Py_Finalize
+               Py_FindMethod
+               Py_FindMethodInChain
+               Py_FlushLine
+               Py_Free
+               Py_GetArgcArgv
+               Py_GetBuildInfo
+               Py_GetCompiler
+               Py_GetCopyright
+               Py_GetExecPrefix
+               Py_GetPath
+               Py_GetPlatform
+               Py_GetPrefix
+               Py_GetProgramFullPath
+               Py_GetProgramName
+               Py_GetPythonHome
+               Py_GetVersion
+               Py_InitModule4
+               Py_Initialize
+               Py_IsInitialized
+               Py_Main
+               Py_MakePendingCalls
+               Py_Malloc
+               Py_NewInterpreter
+               Py_Realloc
+               Py_ReprEnter
+               Py_ReprLeave
+               Py_SetProgramName
+               Py_SetPythonHome
+               Py_VaBuildValue
+               _PyBuiltin_Fini_1
+               _PyBuiltin_Fini_2
+               _PyBuiltin_Init_1
+               _PyBuiltin_Init_2
+               _PyImport_FindExtension
+               _PyImport_Fini
+               _PyImport_FixupExtension
+               _PyImport_Init
+               _PyImport_LoadDynamicModule
+               _PyLong_New
+               _PyModule_Clear
+               _PyObject_New
+               _PyObject_NewVar
+               _PyString_Resize
+               _PySys_Init
+               _PyTuple_Resize
+               _Py_MD5Final
+               _Py_MD5Init
+               _Py_MD5Update
+;               _Py_addbit
+               _Py_c_diff
+               _Py_c_neg
+               _Py_c_pow
+               _Py_c_prod
+               _Py_c_quot
+               _Py_c_sum
+;               _Py_delbitset
+;               _Py_mergebitset
+;               _Py_meta_grammar
+;               _Py_newbitset
+;               _Py_samebitset
+               PyBuffer_Type
+               PyBuffer_FromObject
+               PyBuffer_FromMemory
+               PyBuffer_FromReadWriteMemory
+               PyBuffer_New
+

Added: vendor/Python/current/PC/os2vacpp/readme.txt
===================================================================
--- vendor/Python/current/PC/os2vacpp/readme.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/os2vacpp/readme.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,119 @@
+IBM VisualAge C/C++ for OS/2
+============================
+
+To build Python for OS/2, change into ./os2vacpp and issue an 'NMAKE'
+command.  This will build a PYTHON15.DLL containing the set of Python
+modules listed in config.c and a small PYTHON.EXE to start the
+interpreter.
+
+By changing the C compiler flag /Gd- in the makefile to /Gd+, you can
+reduce the size of these by causing Python to dynamically link to the
+C runtime DLLs instead of including their bulk in your binaries. 
+However, this means that any system on which you run Python must have
+the VAC++ compiler installed in order to have those DLLs available.
+
+During the build process you may see a couple of harmless warnings:
+
+  From the C Compiler, "No function prototype given for XXX", which
+  comes from the use of K&R parameters within Python for portability.
+
+  From the ILIB librarian, "Module Not Found (XXX)", which comes
+  from its attempt to perform the (-+) operation, which removes and
+  then adds a .OBJ to the library.  The first time a build is done,
+  it obviously cannot remove what is not yet built.
+
+This build includes support for most Python functionality as well as
+TCP/IP sockets.  It omits the Posix ability to 'fork' a process but
+supports threads using OS/2 native capabilities.  I have tried to
+support everything possible but here are a few usage notes.
+
+
+-- os.popen() Usage Warnings
+
+With respect to my implementation of popen() under OS/2:
+
+    import os
+
+    fd = os.popen("pkzip.exe -@ junk.zip", 'wb')
+    fd.write("file1.txt\n")
+    fd.write("file2.txt\n")
+    fd.write("file3.txt\n")
+    fd.write("\x1a")  # Should Not Be Necessary But Is
+    fd.close()
+
+There is a bug, either in the VAC++ compiler or OS/2 itself, where the
+simple closure of the write-side of a pipe -to- a process does not
+send an EOF to that process.  I find I must explicitly write a
+control-Z (EOF) before closing the pipe.  This is not a problem when
+using popen() in read mode.
+
+One other slight difference with my popen() is that I return None
+from the close(), instead of the Unix convention of the return code
+of the spawned program.  I could find no easy way to do this under
+OS/2.
+
+
+-- BEGINLIBPATH/ENDLIBPATH
+
+With respect to environment variables, this OS/2 port supports the
+special-to-OS/2 magic names of 'BEGINLIBPATH' and 'ENDLIBPATH' to
+control where to load conventional DLLs from.  Those names are
+intercepted and converted to calls on the OS/2 kernel APIs and
+are inherited by child processes, whether Python-based or not.
+
+A few new attributes have been added to the os module:
+
+    os.meminstalled  # Count of Bytes of RAM Installed on Machine
+    os.memkernel     # Count of Bytes of RAM Reserved (Non-Swappable)
+    os.memvirtual    # Count of Bytes of Virtual RAM Possible
+    os.timeslice     # Duration of Scheduler Timeslice, in Milliseconds
+    os.maxpathlen    # Maximum Length of a Path Specification, in chars
+    os.maxnamelen    # Maximum Length of a Single Dir/File Name, in chars
+    os.version       # Version of OS/2 Being Run e.g. "4.00"
+    os.revision      # Revision of OS/2 Being Run (usually zero)
+    os.bootdrive     # Drive that System Booted From e.g. "C:"
+                     # (useful to find the CONFIG.SYS used to boot with)
+
+
+-- Using Python as the Default OS/2 Batch Language
+
+Note that OS/2 supports the Unix technique of putting the special
+comment line at the time of scripts e.g. "#!/usr/bin/python" in
+a different syntactic form.  To do this, put your script into a file
+with a .CMD extension and added 'extproc' to the top as follows:
+
+    extproc C:\Python\Python.exe -x
+    import os
+    print "Hello from Python"
+
+The '-x' option tells Python to skip the first line of the file
+while processing the rest as normal Python source.
+
+
+-- Suggested Environment Variable Setup
+
+With respect to the environment variables for Python, I use the
+following setup:
+
+    Set PYTHONHOME=E:\Tau\Projects\Python;D:\DLLs
+    Set PYTHONPATH=.;E:\Tau\Projects\Python\Lib; \
+                     E:\Tau\Projects\Python\Lib\plat-win
+
+The EXEC_PREFIX (optional second pathspec on PYTHONHOME) is where
+you put any Python extension DLLs you may create/obtain.  There
+are none provided with this release.
+
+
+-- Contact Info
+
+Jeff Rush is no longer supporting the VACPP port :-(
+
+I don't have the VACPP compiler, so can't reliably maintain this port. 
+
+Anyone with VACPP who can contribute patches to keep this port buildable
+should upload them to the Python Patch Manager at Sourceforge and 
+assign them to me for review/checkin.
+
+Andrew MacIntyre
+aimacintyre at users.sourceforge.net
+August 18, 2002.

Added: vendor/Python/current/PC/py.ico
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/PC/py.ico
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/PC/pyc.ico
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/PC/pyc.ico
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/PC/pycon.ico
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/PC/pycon.ico
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/PC/pyconfig.h
===================================================================
--- vendor/Python/current/PC/pyconfig.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/pyconfig.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,688 @@
+#ifndef Py_CONFIG_H
+#define Py_CONFIG_H
+
+/* pyconfig.h.  NOT Generated automatically by configure.
+
+This is a manually maintained version used for the Watcom,
+Borland and Microsoft Visual C++ compilers.  It is a
+standard part of the Python distribution.
+
+WINDOWS DEFINES:
+The code specific to Windows should be wrapped around one of
+the following #defines
+
+MS_WIN64 - Code specific to the MS Win64 API
+MS_WIN32 - Code specific to the MS Win32 (and Win64) API (obsolete, this covers all supported APIs)
+MS_WINDOWS - Code specific to Windows, but all versions.
+MS_WINCE - Code specific to Windows CE
+Py_ENABLE_SHARED - Code if the Python core is built as a DLL.
+
+Also note that neither "_M_IX86" or "_MSC_VER" should be used for
+any purpose other than "Windows Intel x86 specific" and "Microsoft
+compiler specific".  Therefore, these should be very rare.
+
+
+NOTE: The following symbols are deprecated:
+NT, WIN32, USE_DL_EXPORT, USE_DL_IMPORT, DL_EXPORT, DL_IMPORT
+MS_CORE_DLL.
+
+*/
+
+#ifdef _WIN32_WCE
+#define MS_WINCE
+#endif
+
+/* Visual Studio 2005 introduces deprecation warnings for
+   "insecure" and POSIX functions. The insecure functions should
+   be replaced by *_s versions (according to Microsoft); the
+   POSIX functions by _* versions (which, according to Microsoft,
+   would be ISO C conforming). Neither renaming is feasible, so
+   we just silence the warnings. */
+
+#ifndef _CRT_SECURE_NO_DEPRECATE
+#define _CRT_SECURE_NO_DEPRECATE 1
+#endif
+#ifndef _CRT_NONSTDC_NO_DEPRECATE
+#define _CRT_NONSTDC_NO_DEPRECATE 1
+#endif
+
+/* Windows CE does not have these */
+#ifndef MS_WINCE
+#define HAVE_IO_H
+#define HAVE_SYS_UTIME_H
+#define HAVE_TEMPNAM
+#define HAVE_TMPFILE
+#define HAVE_TMPNAM
+#define HAVE_CLOCK
+#define HAVE_STRERROR
+#endif
+
+#ifdef HAVE_IO_H
+#include <io.h>
+#endif
+
+#define HAVE_HYPOT
+#define HAVE_STRFTIME
+#define DONT_HAVE_SIG_ALARM
+#define DONT_HAVE_SIG_PAUSE
+#define LONG_BIT	32
+#define WORD_BIT 32
+#define PREFIX ""
+#define EXEC_PREFIX ""
+
+#define MS_WIN32 /* only support win32 and greater. */
+#define MS_WINDOWS
+#ifndef PYTHONPATH
+#	define PYTHONPATH ".\\DLLs;.\\lib;.\\lib\\plat-win;.\\lib\\lib-tk"
+#endif
+#define NT_THREADS
+#define WITH_THREAD
+#ifndef NETSCAPE_PI
+#define USE_SOCKET
+#endif
+
+#ifdef MS_WINCE
+/* Python uses GetVersion() to distinguish between
+ * Windows NT and 9x/ME where OS Unicode support is concerned.
+ * Windows CE supports Unicode in the same way as NT so we
+ * define the missing GetVersion() accordingly.
+ */
+#define GetVersion() (4)
+/* Windows CE does not support environment variables */
+#define getenv(v) (NULL)
+#define environ (NULL)
+#endif
+
+/* Compiler specific defines */
+
+/* ------------------------------------------------------------------------*/
+/* Microsoft C defines _MSC_VER */
+#ifdef _MSC_VER
+
+/* We want COMPILER to expand to a string containing _MSC_VER's *value*.
+ * This is horridly tricky, because the stringization operator only works
+ * on macro arguments, and doesn't evaluate macros passed *as* arguments.
+ * Attempts simpler than the following appear doomed to produce "_MSC_VER"
+ * literally in the string.
+ */
+#define _Py_PASTE_VERSION(SUFFIX) \
+	("[MSC v." _Py_STRINGIZE(_MSC_VER) " " SUFFIX "]")
+/* e.g., this produces, after compile-time string catenation,
+ * 	("[MSC v.1200 32 bit (Intel)]")
+ *
+ * _Py_STRINGIZE(_MSC_VER) expands to
+ * _Py_STRINGIZE1((_MSC_VER)) expands to
+ * _Py_STRINGIZE2(_MSC_VER) but as this call is the result of token-pasting
+ *      it's scanned again for macros and so further expands to (under MSVC 6)
+ * _Py_STRINGIZE2(1200) which then expands to
+ * "1200"
+ */
+#define _Py_STRINGIZE(X) _Py_STRINGIZE1((X))
+#define _Py_STRINGIZE1(X) _Py_STRINGIZE2 ## X
+#define _Py_STRINGIZE2(X) #X
+
+/* MSVC defines _WINxx to differentiate the windows platform types
+
+   Note that for compatibility reasons _WIN32 is defined on Win32
+   *and* on Win64. For the same reasons, in Python, MS_WIN32 is
+   defined on Win32 *and* Win64. Win32 only code must therefore be
+   guarded as follows:
+   	#if defined(MS_WIN32) && !defined(MS_WIN64)
+*/
+#ifdef _WIN64
+#define MS_WIN64
+#endif
+
+/* set the COMPILER */
+#ifdef MS_WIN64
+#ifdef _M_IX86
+#define COMPILER _Py_PASTE_VERSION("64 bit (Intel)")
+#elif defined(_M_IA64)
+#define COMPILER _Py_PASTE_VERSION("64 bit (Itanium)")
+#elif defined(_M_AMD64)
+#define COMPILER _Py_PASTE_VERSION("64 bit (AMD64)")
+#else
+#define COMPILER _Py_PASTE_VERSION("64 bit (Unknown)")
+#endif
+#endif /* MS_WIN64 */
+
+/* _W64 is not defined for VC6 or eVC4 */
+#ifndef _W64
+#define _W64
+#endif
+
+/* Define like size_t, omitting the "unsigned" */
+#ifdef MS_WIN64
+typedef __int64 ssize_t;
+#else
+typedef _W64 int ssize_t;
+#endif
+#define HAVE_SSIZE_T 1
+
+#if defined(MS_WIN32) && !defined(MS_WIN64)
+#ifdef _M_IX86
+#define COMPILER _Py_PASTE_VERSION("32 bit (Intel)")
+#else
+#define COMPILER _Py_PASTE_VERSION("32 bit (Unknown)")
+#endif
+#endif /* MS_WIN32 && !MS_WIN64 */
+
+typedef int pid_t;
+#define hypot _hypot
+
+#include <float.h>
+#define Py_IS_NAN _isnan
+#define Py_IS_INFINITY(X) (!_finite(X) && !_isnan(X))
+#define Py_IS_FINITE(X) _finite(X)
+
+/* Turn off warnings about deprecated C runtime functions in 
+   VisualStudio .NET 2005 */
+#if _MSC_VER >= 1400 && !defined _CRT_SECURE_NO_DEPRECATE
+#define _CRT_SECURE_NO_DEPRECATE
+#endif
+
+#endif /* _MSC_VER */
+
+/* define some ANSI types that are not defined in earlier Win headers */
+#if defined(_MSC_VER) && _MSC_VER >= 1200
+/* This file only exists in VC 6.0 or higher */
+#include <basetsd.h>
+#endif
+
+/* ------------------------------------------------------------------------*/
+/* The Borland compiler defines __BORLANDC__ */
+/* XXX These defines are likely incomplete, but should be easy to fix. */
+#ifdef __BORLANDC__
+#define COMPILER "[Borland]"
+
+#ifdef _WIN32
+/* tested with BCC 5.5 (__BORLANDC__ >= 0x0550)
+ */
+
+typedef int pid_t;
+/* BCC55 seems to understand __declspec(dllimport), it is used in its
+   own header files (winnt.h, ...) - so we can do nothing and get the default*/
+
+#undef HAVE_SYS_UTIME_H
+#define HAVE_UTIME_H
+#define HAVE_DIRENT_H
+
+/* rename a few functions for the Borland compiler */
+#include <io.h>
+#define _chsize chsize
+#define _setmode setmode
+
+#else /* !_WIN32 */
+#error "Only Win32 and later are supported"
+#endif /* !_WIN32 */
+
+#endif /* BORLANDC */
+
+/* ------------------------------------------------------------------------*/
+/* egcs/gnu-win32 defines __GNUC__ and _WIN32 */
+#if defined(__GNUC__) && defined(_WIN32)
+/* XXX These defines are likely incomplete, but should be easy to fix.
+   They should be complete enough to build extension modules. */
+/* Suggested by Rene Liebscher <R.Liebscher at gmx.de> to avoid a GCC 2.91.*
+   bug that requires structure imports.  More recent versions of the
+   compiler don't exhibit this bug.
+*/
+#if (__GNUC__==2) && (__GNUC_MINOR__<=91)
+#warning "Please use an up-to-date version of gcc! (>2.91 recommended)"
+#endif
+
+#define COMPILER "[gcc]"
+#define hypot _hypot
+#define PY_LONG_LONG long long
+#endif /* GNUC */
+
+/* ------------------------------------------------------------------------*/
+/* lcc-win32 defines __LCC__ */
+#if defined(__LCC__)
+/* XXX These defines are likely incomplete, but should be easy to fix.
+   They should be complete enough to build extension modules. */
+
+#define COMPILER "[lcc-win32]"
+typedef int pid_t;
+/* __declspec() is supported here too - do nothing to get the defaults */
+
+#endif /* LCC */
+
+/* ------------------------------------------------------------------------*/
+/* End of compilers - finish up */
+
+#ifndef NO_STDIO_H
+#	include <stdio.h>
+#endif
+
+/* 64 bit ints are usually spelt __int64 unless compiler has overridden */
+#define HAVE_LONG_LONG 1
+#ifndef PY_LONG_LONG
+#	define PY_LONG_LONG __int64
+#endif
+
+/* For Windows the Python core is in a DLL by default.  Test
+Py_NO_ENABLE_SHARED to find out.  Also support MS_NO_COREDLL for b/w compat */
+#if !defined(MS_NO_COREDLL) && !defined(Py_NO_ENABLE_SHARED)
+#	define Py_ENABLE_SHARED 1 /* standard symbol for shared library */
+#	define MS_COREDLL	/* deprecated old symbol */
+#endif /* !MS_NO_COREDLL && ... */
+
+/* Deprecated USE_DL_EXPORT macro - please use Py_BUILD_CORE */
+#ifdef USE_DL_EXPORT
+#	define Py_BUILD_CORE
+#endif /* USE_DL_EXPORT */
+
+/*  All windows compilers that use this header support __declspec */
+#define HAVE_DECLSPEC_DLL
+
+/* For an MSVC DLL, we can nominate the .lib files used by extensions */
+#ifdef MS_COREDLL
+#	ifndef Py_BUILD_CORE /* not building the core - must be an ext */
+#		if defined(_MSC_VER)
+			/* So MSVC users need not specify the .lib file in
+			their Makefile (other compilers are generally
+			taken care of by distutils.) */
+#			ifdef _DEBUG
+#				pragma comment(lib,"python25_d.lib")
+#			else
+#				pragma comment(lib,"python25.lib")
+#			endif /* _DEBUG */
+#		endif /* _MSC_VER */
+#	endif /* Py_BUILD_CORE */
+#endif /* MS_COREDLL */
+
+#if defined(MS_WIN64)
+/* maintain "win32" sys.platform for backward compatibility of Python code,
+   the Win64 API should be close enough to the Win32 API to make this
+   preferable */
+#	define PLATFORM "win32"
+#	define SIZEOF_VOID_P 8
+#	define SIZEOF_TIME_T 8
+#	define SIZEOF_OFF_T 4
+#	define SIZEOF_FPOS_T 8
+#	define SIZEOF_HKEY 8
+#	define SIZEOF_SIZE_T 8
+/* configure.in defines HAVE_LARGEFILE_SUPPORT iff HAVE_LONG_LONG,
+   sizeof(off_t) > sizeof(long), and sizeof(PY_LONG_LONG) >= sizeof(off_t).
+   On Win64 the second condition is not true, but if fpos_t replaces off_t
+   then this is true. The uses of HAVE_LARGEFILE_SUPPORT imply that Win64
+   should define this. */
+#	define HAVE_LARGEFILE_SUPPORT
+#elif defined(MS_WIN32)
+#	define PLATFORM "win32"
+#	define HAVE_LARGEFILE_SUPPORT
+#	define SIZEOF_VOID_P 4
+#	define SIZEOF_OFF_T 4
+#	define SIZEOF_FPOS_T 8
+#	define SIZEOF_HKEY 4
+#	define SIZEOF_SIZE_T 4
+	/* MS VS2005 changes time_t to an 64-bit type on all platforms */
+#	if defined(_MSC_VER) && _MSC_VER >= 1400
+#	define SIZEOF_TIME_T 8
+#	else
+#	define SIZEOF_TIME_T 4
+#	endif
+#endif
+
+#ifdef _DEBUG
+#	define Py_DEBUG
+#endif
+
+
+#ifdef MS_WIN32
+
+#define SIZEOF_SHORT 2
+#define SIZEOF_INT 4
+#define SIZEOF_LONG 4
+#define SIZEOF_LONG_LONG 8
+#define SIZEOF_DOUBLE 8
+#define SIZEOF_FLOAT 4
+
+/* VC 7.1 has them and VC 6.0 does not.  VC 6.0 has a version number of 1200.
+   Microsoft eMbedded Visual C++ 4.0 has a version number of 1201 and doesn't
+   define these.
+   If some compiler does not provide them, modify the #if appropriately. */
+#if defined(_MSC_VER)
+#if _MSC_VER > 1201
+#define HAVE_UINTPTR_T 1
+#define HAVE_INTPTR_T 1
+#else
+/* VC6 & eVC4 don't support the C99 LL suffix for 64-bit integer literals */
+#define Py_LL(x) x##I64
+#endif  /* _MSC_VER > 1200  */
+#endif  /* _MSC_VER */
+
+#endif
+
+/* Fairly standard from here! */
+
+/* Define if on AIX 3.
+   System headers sometimes define this.
+   We just want to avoid a redefinition error message.  */
+#ifndef _ALL_SOURCE
+/* #undef _ALL_SOURCE */
+#endif
+
+/* Define to empty if the keyword does not work.  */
+/* #define const  */
+
+/* Define to 1 if you have the <conio.h> header file. */
+#ifndef MS_WINCE
+#define HAVE_CONIO_H 1
+#endif
+
+/* Define to 1 if you have the <direct.h> header file. */
+#ifndef MS_WINCE
+#define HAVE_DIRECT_H 1
+#endif
+
+/* Define if you have dirent.h.  */
+/* #define DIRENT 1 */
+
+/* Define to the type of elements in the array set by `getgroups'.
+   Usually this is either `int' or `gid_t'.  */
+/* #undef GETGROUPS_T */
+
+/* Define to `int' if <sys/types.h> doesn't define.  */
+/* #undef gid_t */
+
+/* Define if your struct tm has tm_zone.  */
+/* #undef HAVE_TM_ZONE */
+
+/* Define if you don't have tm_zone but do have the external array
+   tzname.  */
+#define HAVE_TZNAME
+
+/* Define to `int' if <sys/types.h> doesn't define.  */
+/* #undef mode_t */
+
+/* Define if you don't have dirent.h, but have ndir.h.  */
+/* #undef NDIR */
+
+/* Define to `long' if <sys/types.h> doesn't define.  */
+/* #undef off_t */
+
+/* Define to `int' if <sys/types.h> doesn't define.  */
+/* #undef pid_t */
+
+/* Define if the system does not provide POSIX.1 features except
+   with this defined.  */
+/* #undef _POSIX_1_SOURCE */
+
+/* Define if you need to in order for stat and other things to work.  */
+/* #undef _POSIX_SOURCE */
+
+/* Define as the return type of signal handlers (int or void).  */
+#define RETSIGTYPE void
+
+/* Define to `unsigned' if <sys/types.h> doesn't define.  */
+/* #undef size_t */
+
+/* Define to `int' if <sys/types.h> doesn't define.  */
+#if _MSC_VER + 0 >= 1300
+/* VC.NET typedefs socklen_t in ws2tcpip.h. */
+#else
+#define socklen_t int
+#endif
+
+/* Define if you have the ANSI C header files.  */
+#define STDC_HEADERS 1
+
+/* Define if you don't have dirent.h, but have sys/dir.h.  */
+/* #undef SYSDIR */
+
+/* Define if you don't have dirent.h, but have sys/ndir.h.  */
+/* #undef SYSNDIR */
+
+/* Define if you can safely include both <sys/time.h> and <time.h>.  */
+/* #undef TIME_WITH_SYS_TIME */
+
+/* Define if your <sys/time.h> declares struct tm.  */
+/* #define TM_IN_SYS_TIME 1 */
+
+/* Define to `int' if <sys/types.h> doesn't define.  */
+/* #undef uid_t */
+
+/* Define if the closedir function returns void instead of int.  */
+/* #undef VOID_CLOSEDIR */
+
+/* Define if getpgrp() must be called as getpgrp(0)
+   and (consequently) setpgrp() as setpgrp(0, 0). */
+/* #undef GETPGRP_HAVE_ARGS */
+
+/* Define this if your time.h defines altzone */
+/* #define HAVE_ALTZONE */
+
+/* Define if you have the putenv function.  */
+#ifndef MS_WINCE
+#define HAVE_PUTENV
+#endif
+
+/* Define if your compiler supports function prototypes */
+#define HAVE_PROTOTYPES
+
+/* Define if  you can safely include both <sys/select.h> and <sys/time.h>
+   (which you can't on SCO ODT 3.0). */
+/* #undef SYS_SELECT_WITH_SYS_TIME */
+
+/* Define if you want documentation strings in extension modules */
+#define WITH_DOC_STRINGS 1
+
+/* Define if you want to compile in rudimentary thread support */
+/* #undef WITH_THREAD */
+
+/* Define if you want to use the GNU readline library */
+/* #define WITH_READLINE 1 */
+
+/* Define if you want to have a Unicode type. */
+#define Py_USING_UNICODE
+
+/* Define as the integral type used for Unicode representation. */
+#define PY_UNICODE_TYPE unsigned short
+
+/* Define as the size of the unicode type. */
+#define Py_UNICODE_SIZE SIZEOF_SHORT
+
+/* Define if you have a useable wchar_t type defined in wchar.h; useable
+   means wchar_t must be 16-bit unsigned type. (see
+   Include/unicodeobject.h). */
+#if Py_UNICODE_SIZE == 2
+#define HAVE_USABLE_WCHAR_T
+
+/* Define to indicate that the Python Unicode representation can be passed
+   as-is to Win32 Wide API.  */
+#define Py_WIN_WIDE_FILENAMES
+#endif
+
+/* Use Python's own small-block memory-allocator. */
+#define WITH_PYMALLOC 1
+
+/* Define if you have clock.  */
+/* #define HAVE_CLOCK */
+
+/* Define when any dynamic module loading is enabled */
+#define HAVE_DYNAMIC_LOADING
+
+/* Define if you have ftime.  */
+#ifndef MS_WINCE
+#define HAVE_FTIME
+#endif
+
+/* Define if you have getpeername.  */
+#define HAVE_GETPEERNAME
+
+/* Define if you have getpgrp.  */
+/* #undef HAVE_GETPGRP */
+
+/* Define if you have getpid.  */
+#ifndef MS_WINCE
+#define HAVE_GETPID
+#endif
+
+/* Define if you have gettimeofday.  */
+/* #undef HAVE_GETTIMEOFDAY */
+
+/* Define if you have getwd.  */
+/* #undef HAVE_GETWD */
+
+/* Define if you have lstat.  */
+/* #undef HAVE_LSTAT */
+
+/* Define if you have the mktime function.  */
+#define HAVE_MKTIME
+
+/* Define if you have nice.  */
+/* #undef HAVE_NICE */
+
+/* Define if you have readlink.  */
+/* #undef HAVE_READLINK */
+
+/* Define if you have select.  */
+/* #undef HAVE_SELECT */
+
+/* Define if you have setpgid.  */
+/* #undef HAVE_SETPGID */
+
+/* Define if you have setpgrp.  */
+/* #undef HAVE_SETPGRP */
+
+/* Define if you have setsid.  */
+/* #undef HAVE_SETSID */
+
+/* Define if you have setvbuf.  */
+#define HAVE_SETVBUF
+
+/* Define if you have siginterrupt.  */
+/* #undef HAVE_SIGINTERRUPT */
+
+/* Define if you have symlink.  */
+/* #undef HAVE_SYMLINK */
+
+/* Define if you have tcgetpgrp.  */
+/* #undef HAVE_TCGETPGRP */
+
+/* Define if you have tcsetpgrp.  */
+/* #undef HAVE_TCSETPGRP */
+
+/* Define if you have times.  */
+/* #undef HAVE_TIMES */
+
+/* Define if you have uname.  */
+/* #undef HAVE_UNAME */
+
+/* Define if you have waitpid.  */
+/* #undef HAVE_WAITPID */
+
+/* Define to 1 if you have the `wcscoll' function. */
+#ifndef MS_WINCE
+#define HAVE_WCSCOLL 1
+#endif
+
+/* Define if you have the <dlfcn.h> header file.  */
+/* #undef HAVE_DLFCN_H */
+
+/* Define to 1 if you have the <errno.h> header file. */
+#ifndef MS_WINCE
+#define HAVE_ERRNO_H 1
+#endif
+
+/* Define if you have the <fcntl.h> header file.  */
+#ifndef MS_WINCE
+#define HAVE_FCNTL_H 1
+#endif
+
+/* Define to 1 if you have the <process.h> header file. */
+#ifndef MS_WINCE
+#define HAVE_PROCESS_H 1
+#endif
+
+/* Define to 1 if you have the <signal.h> header file. */
+#ifndef MS_WINCE
+#define HAVE_SIGNAL_H 1
+#endif
+
+/* Define if you have the <stdarg.h> prototypes.  */
+#define HAVE_STDARG_PROTOTYPES
+
+/* Define if you have the <stddef.h> header file.  */
+#define HAVE_STDDEF_H 1
+
+/* Define if you have the <sys/audioio.h> header file.  */
+/* #undef HAVE_SYS_AUDIOIO_H */
+
+/* Define if you have the <sys/param.h> header file.  */
+/* #define HAVE_SYS_PARAM_H 1 */
+
+/* Define if you have the <sys/select.h> header file.  */
+/* #define HAVE_SYS_SELECT_H 1 */
+
+/* Define to 1 if you have the <sys/stat.h> header file.  */
+#ifndef MS_WINCE
+#define HAVE_SYS_STAT_H 1
+#endif
+
+/* Define if you have the <sys/time.h> header file.  */
+/* #define HAVE_SYS_TIME_H 1 */
+
+/* Define if you have the <sys/times.h> header file.  */
+/* #define HAVE_SYS_TIMES_H 1 */
+
+/* Define to 1 if you have the <sys/types.h> header file.  */
+#ifndef MS_WINCE
+#define HAVE_SYS_TYPES_H 1
+#endif
+
+/* Define if you have the <sys/un.h> header file.  */
+/* #define HAVE_SYS_UN_H 1 */
+
+/* Define if you have the <sys/utime.h> header file.  */
+/* #define HAVE_SYS_UTIME_H 1 */
+
+/* Define if you have the <sys/utsname.h> header file.  */
+/* #define HAVE_SYS_UTSNAME_H 1 */
+
+/* Define if you have the <thread.h> header file.  */
+/* #undef HAVE_THREAD_H */
+
+/* Define if you have the <unistd.h> header file.  */
+/* #define HAVE_UNISTD_H 1 */
+
+/* Define if you have the <utime.h> header file.  */
+/* #define HAVE_UTIME_H 1 */
+
+/* Define if the compiler provides a wchar.h header file. */
+#define HAVE_WCHAR_H 1
+
+/* Define if you have the dl library (-ldl).  */
+/* #undef HAVE_LIBDL */
+
+/* Define if you have the mpc library (-lmpc).  */
+/* #undef HAVE_LIBMPC */
+
+/* Define if you have the nsl library (-lnsl).  */
+#define HAVE_LIBNSL 1
+
+/* Define if you have the seq library (-lseq).  */
+/* #undef HAVE_LIBSEQ */
+
+/* Define if you have the socket library (-lsocket).  */
+#define HAVE_LIBSOCKET 1
+
+/* Define if you have the sun library (-lsun).  */
+/* #undef HAVE_LIBSUN */
+
+/* Define if you have the termcap library (-ltermcap).  */
+/* #undef HAVE_LIBTERMCAP */
+
+/* Define if you have the termlib library (-ltermlib).  */
+/* #undef HAVE_LIBTERMLIB */
+
+/* Define if you have the thread library (-lthread).  */
+/* #undef HAVE_LIBTHREAD */
+
+/* WinSock does not use a bitmask in select, and uses
+   socket handles greater than FD_SETSIZE */
+#define Py_SOCKET_FD_CAN_BE_GE_FD_SETSIZE
+
+#endif /* !Py_CONFIG_H */

Added: vendor/Python/current/PC/python.mk
===================================================================
--- vendor/Python/current/PC/python.mk	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/python.mk	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,5 @@
+project : n:\python\python-1.5.1\pc\wat_os2\pyth_os2.exe n:\python\python-1.&
+5.1\pc\wat_dos\pyth_dos.exe .SYMBOLIC
+
+!include n:\python\python-1.5.1\pc\wat_os2\pyth_os2.mk1
+!include n:\python\python-1.5.1\pc\wat_dos\pyth_dos.mk1

Added: vendor/Python/current/PC/python_exe.rc
===================================================================
--- vendor/Python/current/PC/python_exe.rc	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/python_exe.rc	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1 @@
+1           ICON    DISCARDABLE     "pycon.ico" 

Added: vendor/Python/current/PC/python_nt.rc
===================================================================
--- vendor/Python/current/PC/python_nt.rc	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/python_nt.rc	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,74 @@
+// Resource script for Python core DLL.
+// Currently only holds version information.
+//
+#include "winver.h"
+
+#define MS_WINDOWS
+#include "modsupport.h"
+#include "patchlevel.h"
+#ifdef _DEBUG
+#   include "pythonnt_rc_d.h"
+#else
+#   include "pythonnt_rc.h"
+#endif
+
+/* e.g., 2.1a2
+ * PY_VERSION comes from patchevel.h
+ */
+#define PYTHON_VERSION PY_VERSION "\0"
+
+/* 64-bit version number as comma-separated list of 4 16-bit ints */
+#if PY_MICRO_VERSION > 64
+#   error "PY_MICRO_VERSION > 64"
+#endif
+#if PY_RELEASE_LEVEL > 99
+#   error "PY_RELEASE_LEVEL > 99"
+#endif
+#if PY_RELEASE_SERIAL > 9
+#   error "PY_RELEASE_SERIAL > 9"
+#endif
+#define PYVERSION64 PY_MAJOR_VERSION, PY_MINOR_VERSION, FIELD3, PYTHON_API_VERSION
+
+// String Tables
+STRINGTABLE DISCARDABLE
+BEGIN
+    1000,   MS_DLL_ID
+END
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION PYVERSION64
+ PRODUCTVERSION PYVERSION64
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "000004b0"
+        BEGIN
+            VALUE "CompanyName", "Python Software Foundation\0"
+            VALUE "FileDescription", "Python Core\0"
+            VALUE "FileVersion", PYTHON_VERSION
+            VALUE "InternalName", "Python DLL\0"
+            VALUE "LegalCopyright", "Copyright © 2001-2007 Python Software Foundation. Copyright © 2000 BeOpen.com. Copyright © 1995-2001 CNRI. Copyright © 1991-1995 SMC.\0"
+            VALUE "OriginalFilename", PYTHON_DLL_NAME "\0"
+            VALUE "ProductName", "Python\0"
+            VALUE "ProductVersion", PYTHON_VERSION
+        END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+        VALUE "Translation", 0x0, 1200
+    END
+END

Added: vendor/Python/current/PC/readme.txt
===================================================================
--- vendor/Python/current/PC/readme.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/readme.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,101 @@
+Welcome to the "PC" subdirectory of the Python distribution
+***********************************************************
+
+*** Note: the project files for MS VC++ 7.1 are now in the
+*** PCbuild directory.  See the file readme.txt there for build
+*** instructions.  There is some information below that might
+*** still be relevant.
+
+This "PC" subdirectory contains complete project files to make
+several older PC ports of Python, as well as all the PC-specific
+Python source files.  It should be located in the root of the
+Python distribution, and there should be directories "Modules",
+"Objects", "Python", etc. in the parent directory of this "PC"
+subdirectory.  Be sure to read the documentation in the Python
+distribution.
+
+Python requires library files such as string.py to be available in
+one or more library directories.  The search path of libraries is
+set up when Python starts.  To see the current Python library search
+path, start Python and enter "import sys" and "print sys.path".
+
+All PC ports use this scheme to try to set up a module search path:
+
+  1) The script location; the current directory without script.
+  2) The PYTHONPATH variable, if set.
+  3) For Win32 platforms (NT/95), paths specified in the Registry.
+  4) Default directories lib, lib/win, lib/test, lib/tkinter;
+     these are searched relative to the environment variable
+     PYTHONHOME, if set, or relative to the executable and its
+     ancestors, if a landmark file (Lib/string.py) is found ,
+     or the current directory (not useful).
+  5) The directory containing the executable.
+
+The best installation strategy is to put the Python executable (and
+DLL, for Win32 platforms) in some convenient directory such as
+C:/python, and copy all library files and subdirectories (using XCOPY)
+to C:/python/lib.  Then you don't need to set PYTHONPATH.  Otherwise,
+set the environment variable PYTHONPATH to your Python search path.
+For example,
+   set PYTHONPATH=.;d:\python\lib;d:\python\lib\win;d:\python\lib\dos-8x3
+
+There are several add-in modules to build Python programs which use
+the native Windows operating environment.  The ports here just make
+"QuickWin" and DOS Python versions which support a character-mode
+(console) environment.  Look in www.python.org for Tkinter, PythonWin,
+WPY and wxPython.
+
+To make a Python port, start the Integrated Development Environment
+(IDE) of your compiler, and read in the native "project file"
+(or makefile) provided.  This will enable you to change any source
+files or build settings so you can make custom builds.
+
+pyconfig.h    An important configuration file specific to PC's.
+
+config.c    The list of C modules to include in the Python PC
+            version.  Manually edit this file to add or
+            remove Python modules.
+
+testpy.py   A Python test program.  Run this to test your
+            Python port.  It should produce copious output,
+	    ending in a report on how many tests were OK, how many
+	    failed, and how many were skipped.  Don't worry about
+	    skipped tests (these test unavailable optional features).
+
+
+Additional files and subdirectories for 32-bit Windows
+======================================================
+
+python_nt.rc   Resource compiler input for python15.dll.
+
+dl_nt.c, import_nt.c
+               Additional sources used for 32-bit Windows features.
+
+getpathp.c     Default sys.path calculations (for all PC platforms).
+
+dllbase_nt.txt A (manually maintained) list of base addresses for
+               various DLLs, to avoid run-time relocation.
+
+example_nt     A subdirectory showing how to build an extension as a
+               DLL.
+
+Visual Studio 6.0
+=================
+The subdirectory VC6 contains Visual Studio 6 project files. These
+were originally located in the PCBuild directory, but are no longer
+maintained.
+
+
+IBM VisualAge C/C++ for OS/2
+============================
+
+See os2vacpp/readme.txt.  This platform is supported by Jeff Rush.
+
+
+Note for Windows 3.x and DOS users
+==================================
+
+Neither Windows 3.x nor DOS is supported any more.  The last Python
+version that supported these was Python 1.5.2; the support files were
+present in Python 2.0 but weren't updated, and it is not our intention
+to support these platforms for Python 2.x.

Added: vendor/Python/current/PC/testpy.py
===================================================================
--- vendor/Python/current/PC/testpy.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/testpy.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,32 @@
+import sys
+
+# This is a test module for Python.  It looks in the standard
+# places for various *.py files.  If these are moved, you must
+# change this module too.
+
+try:
+    import os
+except:
+    print """Could not import the standard "os" module.
+  Please check your PYTHONPATH environment variable."""
+    sys.exit(1)
+
+try:
+    import symbol
+except:
+    print """Could not import the standard "symbol" module.  If this is
+  a PC, you should add the dos_8x3 directory to your PYTHONPATH."""
+    sys.exit(1)
+
+import os
+
+for dir in sys.path:
+    file = os.path.join(dir, "os.py")
+    if os.path.isfile(file):
+        test = os.path.join(dir, "test")
+        if os.path.isdir(test):
+            # Add the "test" directory to PYTHONPATH.
+            sys.path = sys.path + [test]
+
+import regrtest # Standard Python tester.
+regrtest.main()

Added: vendor/Python/current/PC/w9xpopen.c
===================================================================
--- vendor/Python/current/PC/w9xpopen.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/w9xpopen.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,112 @@
+/*
+ * w9xpopen.c
+ *
+ * Serves as an intermediate stub Win32 console application to
+ * avoid a hanging pipe when redirecting 16-bit console based
+ * programs (including MS-DOS console based programs and batch
+ * files) on Window 95 and Windows 98.
+ *
+ * This program is to be launched with redirected standard
+ * handles. It will launch the command line specified 16-bit
+ * console based application in the same console, forwarding
+ * its own redirected standard handles to the 16-bit child.
+
+ * AKA solution to the problem described in KB: Q150956.
+ */    
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <stdio.h>
+#include <stdlib.h>  /* for malloc and its friends */
+
+const char *usage =
+"This program is used by Python's os.popen function\n"
+"to work around a limitation in Windows 95/98.  It is\n"
+"not designed to be used as a stand-alone program.";
+
+int main(int argc, char *argv[])
+{
+    BOOL bRet;
+    STARTUPINFO si;
+    PROCESS_INFORMATION pi;
+    DWORD exit_code=0;
+    int cmdlen = 0;
+    int i;
+    char *cmdline, *cmdlinefill;
+
+    if (argc < 2) {
+        if (GetFileType(GetStdHandle(STD_INPUT_HANDLE))==FILE_TYPE_CHAR)
+            /* Attached to a console, and therefore not executed by Python
+               Display a message box for the inquisitive user
+            */
+            MessageBox(NULL, usage, argv[0], MB_OK);
+        else {
+            /* Eeek - executed by Python, but args are screwed!
+               Write an error message to stdout so there is at
+               least some clue for the end user when it appears
+               in their output.
+               A message box would be hidden and blocks the app.
+             */
+            fprintf(stdout, "Internal popen error - no args specified\n%s\n", usage);
+        }
+        return 1;
+    }
+    /* Build up the command-line from the args.
+       Args with a space are quoted, existing quotes are escaped.
+       To keep things simple calculating the buffer size, we assume
+       every character is a quote - ie, we allocate double what we need
+       in the worst case.  As this is only double the command line passed
+       to us, there is a good chance this is reasonably small, so the total 
+       allocation will almost always be < 512 bytes.
+    */
+    for (i=1;i<argc;i++)
+        cmdlen += strlen(argv[i])*2 + 3; /* one space, maybe 2 quotes */
+    cmdline = cmdlinefill = (char *)malloc(cmdlen+1);
+    if (cmdline == NULL)
+        return -1;
+    for (i=1;i<argc;i++) {
+        const char *arglook;
+        int bQuote = strchr(argv[i], ' ') != NULL;
+        if (bQuote)
+            *cmdlinefill++ = '"';
+        /* escape quotes */
+        for (arglook=argv[i];*arglook;arglook++) {
+            if (*arglook=='"')
+                *cmdlinefill++ = '\\';
+            *cmdlinefill++ = *arglook;
+        }
+        if (bQuote)
+            *cmdlinefill++ = '"';
+        *cmdlinefill++ = ' ';
+    }
+    *cmdlinefill = '\0';
+
+    /* Make child process use this app's standard files. */
+    ZeroMemory(&si, sizeof si);
+    si.cb = sizeof si;
+    si.dwFlags = STARTF_USESTDHANDLES;
+    si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
+    si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
+    si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
+
+    bRet = CreateProcess(
+        NULL, cmdline,
+        NULL, NULL,
+        TRUE, 0,
+        NULL, NULL,
+        &si, &pi
+        );
+
+    free(cmdline);
+
+    if (bRet) {
+        if (WaitForSingleObject(pi.hProcess, INFINITE) != WAIT_FAILED) {
+	    GetExitCodeProcess(pi.hProcess, &exit_code);
+	}
+        CloseHandle(pi.hProcess);
+        CloseHandle(pi.hThread);
+        return exit_code;
+    }
+
+    return 1;
+}

Added: vendor/Python/current/PC/winsound.c
===================================================================
--- vendor/Python/current/PC/winsound.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PC/winsound.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,253 @@
+/* Author: Toby Dickenson <htrd90 at zepler.org>
+ *
+ * Copyright (c) 1999 Toby Dickenson
+ *
+ * Permission to use this software in any way is granted without
+ * fee, provided that the copyright notice above appears in all
+ * copies. This software is provided "as is" without any warranty.
+ */
+
+/* Modified by Guido van Rossum */
+/* Beep added by Mark Hammond */
+/* Win9X Beep and platform identification added by Uncle Timmy */
+
+/* Example:
+
+   import winsound
+   import time
+
+   # Play wav file
+   winsound.PlaySound('c:/windows/media/Chord.wav', winsound.SND_FILENAME)
+
+   # Play sound from control panel settings
+   winsound.PlaySound('SystemQuestion', winsound.SND_ALIAS)
+
+   # Play wav file from memory
+   data=open('c:/windows/media/Chimes.wav',"rb").read()
+   winsound.PlaySound(data, winsound.SND_MEMORY)
+
+   # Start playing the first bit of wav file asynchronously
+   winsound.PlaySound('c:/windows/media/Chord.wav',
+                   winsound.SND_FILENAME|winsound.SND_ASYNC)
+   # But dont let it go for too long...
+   time.sleep(0.1)
+   # ...Before stopping it
+   winsound.PlaySound(None, 0)
+*/
+
+#include <windows.h>
+#include <mmsystem.h>
+#include <Python.h>
+#ifdef HAVE_CONIO_H
+#include <conio.h>	/* port functions on Win9x */
+#endif
+
+PyDoc_STRVAR(sound_playsound_doc,
+"PlaySound(sound, flags) - a wrapper around the Windows PlaySound API\n"
+"\n"
+"The sound argument can be a filename, data, or None.\n"
+"For flag values, ored together, see module documentation.");
+
+PyDoc_STRVAR(sound_beep_doc,
+"Beep(frequency, duration) - a wrapper around the Windows Beep API\n"
+"\n"
+"The frequency argument specifies frequency, in hertz, of the sound.\n"
+"This parameter must be in the range 37 through 32,767.\n"
+"The duration argument specifies the number of milliseconds.\n"
+"On WinNT and 2000, the platform Beep API is used directly.  Else funky\n"
+"code doing direct port manipulation is used; it's unknown whether that\n"
+"will work on all systems.");
+
+PyDoc_STRVAR(sound_msgbeep_doc,
+"MessageBeep(x) - call Windows MessageBeep(x). x defaults to MB_OK.");
+
+PyDoc_STRVAR(sound_module_doc,
+"PlaySound(sound, flags) - play a sound\n"
+"SND_FILENAME - sound is a wav file name\n"
+"SND_ALIAS - sound is a registry sound association name\n"
+"SND_LOOP - Play the sound repeatedly; must also specify SND_ASYNC\n"
+"SND_MEMORY - sound is a memory image of a wav file\n"
+"SND_PURGE - stop all instances of the specified sound\n"
+"SND_ASYNC - PlaySound returns immediately\n"
+"SND_NODEFAULT - Do not play a default beep if the sound can not be found\n"
+"SND_NOSTOP - Do not interrupt any sounds currently playing\n"  // Raising RuntimeError if needed
+"SND_NOWAIT - Return immediately if the sound driver is busy\n" // Without any errors
+"\n"
+"Beep(frequency, duration) - Make a beep through the PC speaker.");
+
+static PyObject *
+sound_playsound(PyObject *s, PyObject *args)
+{
+    const char *sound;
+    int flags;
+    int length;
+    int ok;
+
+    if(!PyArg_ParseTuple(args,"z#i:PlaySound",&sound,&length,&flags)) {
+        return NULL;
+    }
+
+    if(flags&SND_ASYNC && flags &SND_MEMORY) {
+	/* Sidestep reference counting headache; unfortunately this also
+	   prevent SND_LOOP from memory. */
+        PyErr_SetString(PyExc_RuntimeError,"Cannot play asynchronously from memory");
+        return NULL;
+    }
+
+    Py_BEGIN_ALLOW_THREADS
+    ok = PlaySound(sound,NULL,flags);
+    Py_END_ALLOW_THREADS
+    if(!ok)
+    {
+        PyErr_SetString(PyExc_RuntimeError,"Failed to play sound");
+        return NULL;
+    }
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+enum OSType {Win9X, WinNT2000};
+static enum OSType whichOS;	/* set by module init */
+
+static PyObject *
+sound_beep(PyObject *self, PyObject *args)
+{
+	int freq;
+	int dur;
+
+	if (!PyArg_ParseTuple(args, "ii:Beep", &freq,  &dur))
+		return NULL;
+
+	if (freq < 37 || freq > 32767) {
+		PyErr_SetString(PyExc_ValueError,
+				"frequency must be in 37 thru 32767");
+		return NULL;
+	}
+
+	/* On NT and 2000, the SDK Beep() function does the whole job.
+	 * But while Beep() exists before NT, it ignores its arguments and
+	 * plays the system default sound.  Sheesh ...
+	 * The Win9X code is mondo bizarre.  I (Tim) pieced it together from
+	 * crap all over the web.  The original IBM PC used some particular
+	 * pieces of hardware (Intel 8255 and 8254 chips) hardwired to
+	 * particular port addresses and running at particular clock speeds,
+	 * and the poor sound card folks have been forced to emulate that in
+	 * all particulars ever since.  But NT and 2000 don't support port
+	 * manipulation.  Don't know about WinME; guessing it's like 98.
+	 */
+
+	if (whichOS == WinNT2000) {
+		BOOL ok;
+		Py_BEGIN_ALLOW_THREADS
+		ok = Beep(freq, dur);
+		Py_END_ALLOW_THREADS
+		if (!ok) {
+			PyErr_SetString(PyExc_RuntimeError,"Failed to beep");
+			return NULL;
+		}
+	}
+#if defined(_M_IX86) && defined(HAVE_CONIO_H)
+	else if (whichOS == Win9X) {
+		int speaker_state;
+		/* Force timer into oscillator mode via timer control port. */
+		_outp(0x43, 0xb6);
+		/* Compute ratio of ancient hardcoded timer frequency to
+		 * frequency we want.  Then feed that ratio (lowest byte
+		 * first) into timer data port.
+		 */
+		freq = 1193180 / freq;
+		_outp(0x42, freq & 0xff);
+		_outp(0x42, (freq >> 8) & 0xff);
+		/* Get speaker control state. */
+		speaker_state = _inp(0x61);
+		/* Turn the speaker on (bit 1)
+		 * and drive speaker from timer (bit 0).
+		 */
+		_outp(0x61, speaker_state | 0x3);
+		/* Let it blast in peace for the duration. */
+		Py_BEGIN_ALLOW_THREADS
+		Sleep(dur);
+		Py_END_ALLOW_THREADS
+		/* Restore speaker control to original state. */
+		_outp(0x61, speaker_state);
+	}
+#endif /* _M_IX86 && HAVE_CONIO_H */
+	else {
+		assert(!"winsound's whichOS has insane value");
+	}
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+sound_msgbeep(PyObject *self, PyObject *args)
+{
+	int x = MB_OK;
+	if (!PyArg_ParseTuple(args, "|i:MessageBeep", &x))
+		return NULL;
+	MessageBeep(x);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static struct PyMethodDef sound_methods[] =
+{
+    {"PlaySound", sound_playsound, METH_VARARGS, sound_playsound_doc},
+    {"Beep",      sound_beep,      METH_VARARGS, sound_beep_doc},
+    {"MessageBeep", sound_msgbeep, METH_VARARGS, sound_msgbeep_doc},
+    {NULL,  NULL}
+};
+
+static void
+add_define(PyObject *dict, const char *key, long value)
+{
+    PyObject *k=PyString_FromString(key);
+    PyObject *v=PyLong_FromLong(value);
+    if(v&&k)
+    {
+        PyDict_SetItem(dict,k,v);
+    }
+    Py_XDECREF(k);
+    Py_XDECREF(v);
+}
+
+#define ADD_DEFINE(tok) add_define(dict,#tok,tok)
+
+PyMODINIT_FUNC
+initwinsound(void)
+{
+	OSVERSIONINFO version;
+
+	PyObject *dict;
+	PyObject *module = Py_InitModule3("winsound",
+					  sound_methods,
+					  sound_module_doc);
+	if (module == NULL)
+		return;
+	dict = PyModule_GetDict(module);
+
+	ADD_DEFINE(SND_ASYNC);
+	ADD_DEFINE(SND_NODEFAULT);
+	ADD_DEFINE(SND_NOSTOP);
+	ADD_DEFINE(SND_NOWAIT);
+	ADD_DEFINE(SND_ALIAS);
+	ADD_DEFINE(SND_FILENAME);
+	ADD_DEFINE(SND_MEMORY);
+	ADD_DEFINE(SND_PURGE);
+	ADD_DEFINE(SND_LOOP);
+	ADD_DEFINE(SND_APPLICATION);
+
+	ADD_DEFINE(MB_OK);
+	ADD_DEFINE(MB_ICONASTERISK);
+	ADD_DEFINE(MB_ICONEXCLAMATION);
+	ADD_DEFINE(MB_ICONHAND);
+	ADD_DEFINE(MB_ICONQUESTION);
+
+	version.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+	GetVersionEx(&version);
+	whichOS = Win9X;
+	if (version.dwPlatformId != VER_PLATFORM_WIN32s &&
+	    version.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS)
+		whichOS = WinNT2000;
+}

Added: vendor/Python/current/PCbuild/Uninstal.wse
===================================================================
--- vendor/Python/current/PCbuild/Uninstal.wse	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild/Uninstal.wse	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,514 @@
+Document Type: WSE
+item: Global
+  Version=8.14
+  Flags=00000100
+  Split=1420
+  Languages=65 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+  Copy Default=1
+  Japanese Font Name=MS Gothic
+  Japanese Font Size=10
+  Start Gradient=0 0 255
+  End Gradient=0 0 0
+  Windows Flags=00000000000000000000101000001000
+  Message Font=MS Sans Serif
+  Font Size=8
+  Disk Label=GLBS
+  Disk Filename=INSTALL
+  Patch Flags=0000000000000001
+  Patch Threshold=200
+  Patch Memory=4096
+  Per-User Version ID=1
+  Crystal Format=10111100101100000010001001001001
+  Step View=&Properties
+end
+item: Remark
+  Text=Note from Tim:  This is a verbatim copy of Wise's Uninstal.wse, altered at the end to write
+end
+item: Remark
+  Text=uninstall info under HKCU instead of HKLM if our DOADMIN var is false.
+end
+item: Remark
+end
+item: Remark
+  Text=     Install Support for uninstalling the application.
+end
+item: Remark
+end
+item: Set Variable
+  Variable=UNINSTALL_PATH
+  Value=%_LOGFILE_PATH_%
+  Flags=00000010
+end
+item: Set Variable
+  Variable=UNINSTALL_PATH
+  Value=%UNINSTALL_PATH%\UNWISE.EXE
+end
+item: Compiler Variable If
+  Variable=_EXE_OS_TYPE_
+  Value=WIN32
+end
+item: Install File
+  Source=%_WISE_%\UNWISE32.EXE
+  Destination=%UNINSTALL_PATH%
+  Flags=0000000000000010
+end
+item: Compiler Variable Else
+end
+item: Install File
+  Source=%_WISE_%\UNWISE.EXE
+  Destination=%UNINSTALL_PATH%
+  Flags=0000000000000010
+end
+item: Compiler Variable End
+end
+item: Remark
+end
+item: Remark
+  Text=     Install Support for multiple languages
+end
+item: Remark
+end
+item: Set Variable
+  Variable=UNINSTALL_LANG
+  Value=%UNINSTALL_PATH%
+  Flags=00000010
+end
+item: Set Variable
+  Variable=UNINSTALL_LANG
+  Value=%UNINSTALL_LANG%\UNWISE.INI
+end
+item: Compiler Variable If
+  Variable=_LANG_LIST_
+  Value=C
+  Flags=00000010
+end
+item: Compiler Variable If
+  Value=%_WISE_%\LANGUAGE\UNWISE.FRA
+  Flags=00000011
+end
+item: If/While Statement
+  Variable=LANG
+  Value=%_LANG_C_NAME_%
+end
+item: Install File
+  Source=%_WISE_%\LANGUAGE\UNWISE.FRA
+  Destination=%UNINSTALL_LANG%
+  Flags=0000000000000010
+end
+item: End Block
+end
+item: Compiler Variable End
+end
+item: Compiler Variable End
+end
+item: Compiler Variable If
+  Variable=_LANG_LIST_
+  Value=D
+  Flags=00000010
+end
+item: Compiler Variable If
+  Value=%_WISE_%\LANGUAGE\UNWISE.FRA
+  Flags=00000011
+end
+item: If/While Statement
+  Variable=LANG
+  Value=%_LANG_D_NAME_%
+end
+item: Install File
+  Source=%_WISE_%\LANGUAGE\UNWISE.FRA
+  Destination=%UNINSTALL_LANG%
+  Flags=0000000000000010
+end
+item: End Block
+end
+item: Compiler Variable End
+end
+item: Compiler Variable End
+end
+item: Compiler Variable If
+  Variable=_LANG_LIST_
+  Value=E
+  Flags=00000010
+end
+item: Compiler Variable If
+  Value=%_WISE_%\LANGUAGE\UNWISE.DEU
+  Flags=00000011
+end
+item: If/While Statement
+  Variable=LANG
+  Value=%_LANG_E_NAME_%
+end
+item: Install File
+  Source=%_WISE_%\LANGUAGE\UNWISE.DEU
+  Destination=%UNINSTALL_LANG%
+  Flags=0000000000000010
+end
+item: End Block
+end
+item: Compiler Variable End
+end
+item: Compiler Variable End
+end
+item: Compiler Variable If
+  Variable=_LANG_LIST_
+  Value=F
+  Flags=00000010
+end
+item: Compiler Variable If
+  Value=%_WISE_%\LANGUAGE\UNWISE.PTG
+  Flags=00000011
+end
+item: If/While Statement
+  Variable=LANG
+  Value=%_LANG_F_NAME_%
+end
+item: Install File
+  Source=%_WISE_%\LANGUAGE\UNWISE.PTG
+  Destination=%UNINSTALL_LANG%
+  Flags=0000000000000010
+end
+item: End Block
+end
+item: Compiler Variable End
+end
+item: Compiler Variable End
+end
+item: Compiler Variable If
+  Variable=_LANG_LIST_
+  Value=G
+  Flags=00000010
+end
+item: Compiler Variable If
+  Value=%_WISE_%\LANGUAGE\UNWISE.ESP
+  Flags=00000011
+end
+item: If/While Statement
+  Variable=LANG
+  Value=%_LANG_G_NAME_%
+end
+item: Install File
+  Source=%_WISE_%\LANGUAGE\UNWISE.ESP
+  Destination=%UNINSTALL_LANG%
+  Flags=0000000000000010
+end
+item: End Block
+end
+item: Compiler Variable End
+end
+item: Compiler Variable End
+end
+item: Compiler Variable If
+  Variable=_LANG_LIST_
+  Value=H
+  Flags=00000010
+end
+item: Compiler Variable If
+  Value=%_WISE_%\LANGUAGE\UNWISE.ESP
+  Flags=00000011
+end
+item: If/While Statement
+  Variable=LANG
+  Value=%_LANG_H_NAME_%
+end
+item: Install File
+  Source=%_WISE_%\LANGUAGE\UNWISE.ESP
+  Destination=%UNINSTALL_LANG%
+  Flags=0000000000000010
+end
+item: End Block
+end
+item: Compiler Variable End
+end
+item: Compiler Variable End
+end
+item: Compiler Variable If
+  Variable=_LANG_LIST_
+  Value=I
+  Flags=00000010
+end
+item: Compiler Variable If
+  Value=%_WISE_%\LANGUAGE\UNWISE.ITA
+  Flags=00000011
+end
+item: If/While Statement
+  Variable=LANG
+  Value=%_LANG_I_NAME_%
+end
+item: Install File
+  Source=%_WISE_%\LANGUAGE\UNWISE.ITA
+  Destination=%UNINSTALL_LANG%
+  Flags=0000000000000010
+end
+item: End Block
+end
+item: Compiler Variable End
+end
+item: Compiler Variable End
+end
+item: Compiler Variable If
+  Variable=_LANG_LIST_
+  Value=J
+  Flags=00000010
+end
+item: Compiler Variable If
+  Value=%_WISE_%\LANGUAGE\UNWISE.DAN
+  Flags=00000011
+end
+item: If/While Statement
+  Variable=LANG
+  Value=%_LANG_J_NAME_%
+end
+item: Install File
+  Source=%_WISE_%\LANGUAGE\UNWISE.DAN
+  Destination=%UNINSTALL_LANG%
+  Flags=0000000000000010
+end
+item: End Block
+end
+item: Compiler Variable End
+end
+item: Compiler Variable End
+end
+item: Compiler Variable If
+  Variable=_LANG_LIST_
+  Value=K
+  Flags=00000010
+end
+item: Compiler Variable If
+  Value=%_WISE_%\LANGUAGE\UNWISE.FIN
+  Flags=00000011
+end
+item: If/While Statement
+  Variable=LANG
+  Value=%_LANG_K_NAME_%
+end
+item: Install File
+  Source=%_WISE_%\LANGUAGE\UNWISE.FIN
+  Destination=%UNINSTALL_LANG%
+  Flags=0000000000000010
+end
+item: End Block
+end
+item: Compiler Variable End
+end
+item: Compiler Variable End
+end
+item: Compiler Variable If
+  Variable=_LANG_LIST_
+  Value=L
+  Flags=00000010
+end
+item: Compiler Variable If
+  Value=%_WISE_%\LANGUAGE\UNWISE.ISL
+  Flags=00000011
+end
+item: If/While Statement
+  Variable=LANG
+  Value=%_LANG_L_NAME_%
+end
+item: Install File
+  Source=%_WISE_%\LANGUAGE\UNWISE.ISL
+  Destination=%UNINSTALL_LANG%
+  Flags=0000000000000010
+end
+item: End Block
+end
+item: Compiler Variable End
+end
+item: Compiler Variable End
+end
+item: Compiler Variable If
+  Variable=_LANG_LIST_
+  Value=M
+  Flags=00000010
+end
+item: Compiler Variable If
+  Value=%_WISE_%\LANGUAGE\UNWISE.NLD
+  Flags=00000011
+end
+item: If/While Statement
+  Variable=LANG
+  Value=%_LANG_M_NAME_%
+end
+item: Install File
+  Source=%_WISE_%\LANGUAGE\UNWISE.NLD
+  Destination=%UNINSTALL_LANG%
+  Flags=0000000000000010
+end
+item: End Block
+end
+item: Compiler Variable End
+end
+item: Compiler Variable End
+end
+item: Compiler Variable If
+  Variable=_LANG_LIST_
+  Value=N
+  Flags=00000010
+end
+item: Compiler Variable If
+  Value=%_WISE_%\LANGUAGE\UNWISE.NOR
+  Flags=00000011
+end
+item: If/While Statement
+  Variable=LANG
+  Value=%_LANG_N_NAME_%
+end
+item: Install File
+  Source=%_WISE_%\LANGUAGE\UNWISE.NOR
+  Destination=%UNINSTALL_LANG%
+  Flags=0000000000000010
+end
+item: End Block
+end
+item: Compiler Variable End
+end
+item: Compiler Variable End
+end
+item: Compiler Variable If
+  Variable=_LANG_LIST_
+  Value=O
+  Flags=00000010
+end
+item: Compiler Variable If
+  Value=%_WISE_%\LANGUAGE\UNWISE.SVE
+  Flags=00000011
+end
+item: If/While Statement
+  Variable=LANG
+  Value=%_LANG_O_NAME_%
+end
+item: Install File
+  Source=%_WISE_%\LANGUAGE\UNWISE.SVE
+  Destination=%UNINSTALL_LANG%
+  Flags=0000000000000010
+end
+item: End Block
+end
+item: Compiler Variable End
+end
+item: Compiler Variable End
+end
+item: Compiler Variable If
+  Variable=_LANG_LIST_
+  Value=P
+  Flags=00000010
+end
+item: Compiler Variable If
+  Value=%_WISE_%\LANGUAGE\UNWISE.JPN
+  Flags=00000011
+end
+item: If/While Statement
+  Variable=LANG
+  Value=%_LANG_P_NAME_%
+end
+item: Install File
+  Source=%_WISE_%\LANGUAGE\UNWISE.JPN
+  Destination=%UNINSTALL_LANG%
+  Flags=0000000000000010
+end
+item: End Block
+end
+item: Compiler Variable End
+end
+item: Compiler Variable End
+end
+item: Remark
+end
+item: Remark
+  Text=     Install the add/remove or uninstall icon
+end
+item: Remark
+end
+item: Set Variable
+  Variable=UNINSTALL_PATH
+  Value=%UNINSTALL_PATH%
+  Flags=00010100
+end
+item: Set Variable
+  Variable=INST_LOG_PATH
+  Value=%_LOGFILE_PATH_%
+  Flags=00010100
+end
+item: Check Configuration
+  Flags=10111011
+end
+item: If/While Statement
+  Variable=DOADMIN
+  Value=1
+end
+item: Remark
+  Text=Write uninstall info under HKLM.  This if/else/end block added by Tim.
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Microsoft\Windows\CurrentVersion\Uninstall\%APPTITLE%
+  New Value=%APPTITLE%
+  Value Name=DisplayName
+  Root=2
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Microsoft\Windows\CurrentVersion\Uninstall\%APPTITLE%
+  New Value=%UNINSTALL_PATH% %INST_LOG_PATH%
+  New Value=
+  Value Name=UninstallString
+  Root=2
+end
+item: Else Statement
+end
+item: Remark
+  Text=The same, but write under HKCU instead.
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Microsoft\Windows\CurrentVersion\Uninstall\%APPTITLE%
+  New Value=%APPTITLE%
+  Value Name=DisplayName
+  Root=1
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Microsoft\Windows\CurrentVersion\Uninstall\%APPTITLE%
+  New Value=%UNINSTALL_PATH% %INST_LOG_PATH%
+  New Value=
+  Value Name=UninstallString
+  Root=1
+end
+item: End Block
+end
+item: Else Statement
+end
+item: Add ProgMan Icon
+  Group=%GROUP%
+  Icon Name=Uninstall %APPTITLE%
+  Command Line=%UNINSTALL_PATH% %INST_LOG_PATH%
+end
+item: End Block
+end
+item: Check Configuration
+  Flags=11110010
+end
+item: If/While Statement
+  Variable=DOBRAND
+  Value=1
+end
+item: Edit Registry
+  Total Keys=2
+  item: Key
+    Key=Software\Microsoft\Windows\CurrentVersion\Uninstall\%APPTITLE%
+    New Value=%COMPANY%
+    Value Name=RegCompany
+    Root=2
+  end
+  item: Key
+    Key=Software\Microsoft\Windows\CurrentVersion\Uninstall\%APPTITLE%
+    New Value=%NAME%
+    Value Name=RegOwner
+    Root=2
+  end
+end
+item: End Block
+end
+item: End Block
+end

Added: vendor/Python/current/PCbuild/_bsddb.vcproj
===================================================================
--- vendor/Python/current/PCbuild/_bsddb.vcproj	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild/_bsddb.vcproj	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,258 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="_bsddb"
+	SccProjectName="_bsddb"
+	SccLocalPath="..">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-debug\_bsddb"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\Include;..\PC;&quot;..\..\db-4.4.20\build_win32&quot;"
+				PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="..\..\db-4.4.20\build_win32\Debug\libdb44sd.lib"
+				OutputFile="./_bsddb_d.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				IgnoreDefaultLibraryNames=""
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./_bsddb_d.pdb"
+				SubSystem="2"
+				BaseAddress="0x1e180000"
+				ImportLibrary=".\./_bsddb_d.lib"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-release\_bsddb"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include;..\PC;&quot;..\..\db-4.4.20\build_win32&quot;"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS"
+				StringPooling="TRUE"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="..\..\db-4.4.20\build_win32\Release\libdb44s.lib"
+				OutputFile="./_bsddb.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				IgnoreDefaultLibraryNames=""
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./_bsddb.pdb"
+				SubSystem="2"
+				BaseAddress="0x1e180000"
+				ImportLibrary=".\./_bsddb.lib"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseItanium|Win32"
+			OutputDirectory="./."
+			IntermediateDirectory=".\ia64-temp-release\_bsddb"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions=" /USECL:MS_ITANIUM /GS-"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include;..\PC;&quot;..\..\db-4.4.20\build_win32&quot;"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS"
+				StringPooling="TRUE"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="FALSE"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions=" /MACHINE:IA64 /USELINK:MS_SDK"
+				AdditionalDependencies="..\..\db-4.4.20\build_win32\Release_IA64\libdb44s.lib"
+				OutputFile="./_bsddb.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				IgnoreDefaultLibraryNames=""
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./_bsddb.pdb"
+				SubSystem="2"
+				BaseAddress="0x1e180000"
+				ImportLibrary=".\./_bsddb.lib"
+				TargetMachine="0"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseAMD64|Win32"
+			OutputDirectory="."
+			IntermediateDirectory="amd64-temp-release\_bsddb"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions=" /USECL:MS_OPTERON /GS-"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include;..\PC;&quot;..\..\db-4.4.20\build_win32&quot;"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS"
+				StringPooling="TRUE"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="FALSE"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions=" /MACHINE:AMD64 /USELINK:MS_SDK"
+				AdditionalDependencies="..\..\db-4.4.20\build_win32\Release_AMD64\libdb44s.lib"
+				OutputFile="./_bsddb.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				IgnoreDefaultLibraryNames=""
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./_bsddb.pdb"
+				SubSystem="2"
+				BaseAddress="0x1e180000"
+				ImportLibrary=".\./_bsddb.lib"
+				TargetMachine="0"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath="..\Modules\_bsddb.c">
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Added: vendor/Python/current/PCbuild/_ctypes.vcproj
===================================================================
--- vendor/Python/current/PCbuild/_ctypes.vcproj	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild/_ctypes.vcproj	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,275 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="_ctypes"
+	ProjectGUID="{F22F40F4-D318-40DC-96B3-88DC81CE0894}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-debug\_ctypes"
+			ConfigurationType="2"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\Include,..\PC,..\Modules\_ctypes\libffi_msvc"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
+				MinimalRebuild="FALSE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="FALSE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions="/EXPORT:DllGetClassObject,PRIVATE /EXPORT:DllCanUnloadNow,PRIVATE"
+				OutputFile="./_ctypes_d.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./_ctypes_d.pdb"
+				SubSystem="0"
+				BaseAddress="0x1D1A0000"
+				ImportLibrary=".\./_ctypes_d.lib"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-release\_ctypes"
+			ConfigurationType="2"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC,..\Modules\_ctypes\libffi_msvc"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+				StringPooling="TRUE"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="FALSE"
+				DebugInformationFormat="0"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions="/EXPORT:DllGetClassObject,PRIVATE /EXPORT:DllCanUnloadNow,PRIVATE"
+				OutputFile="./_ctypes.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				GenerateDebugInformation="FALSE"
+				ProgramDatabaseFile=".\./_ctypes.pdb"
+				SubSystem="0"
+				OptimizeReferences="0"
+				EnableCOMDATFolding="0"
+				BaseAddress="0x1D1A0000"
+				ImportLibrary=".\./_ctypes.lib"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseAMD64|Win32"
+			OutputDirectory="."
+			IntermediateDirectory="amd64-temp-release\_ctypes"
+			ConfigurationType="2"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions=" /USECL:MS_OPTERON"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC,..\Modules\_ctypes\libffi_msvc"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+				StringPooling="TRUE"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="FALSE"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions=" /MACHINE:AMD64 /USELINK:MS_SDK /EXPORT:DllGetClassObject,PRIVATE /EXPORT:DllCanUnloadNow,PRIVATE"
+				OutputFile="./_ctypes.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				GenerateDebugInformation="FALSE"
+				ProgramDatabaseFile=".\./_ctypes.pdb"
+				SubSystem="0"
+				OptimizeReferences="0"
+				EnableCOMDATFolding="0"
+				BaseAddress="0x1D1A0000"
+				ImportLibrary=".\./_ctypes.lib"
+				TargetMachine="0"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseItanium|Win32"
+			OutputDirectory="."
+			IntermediateDirectory="ia64-temp-release\_ctypes"
+			ConfigurationType="2"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions=" /USECL:MS_ITANIUM"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC,..\Modules\_ctypes\libffi_msvc"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+				StringPooling="TRUE"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="FALSE"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions=" /MACHINE:IA64 /USELINK:MS_SDK /EXPORT:DllGetClassObject,PRIVATE /EXPORT:DllCanUnloadNow,PRIVATE"
+				OutputFile="./_ctypes.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				GenerateDebugInformation="FALSE"
+				ProgramDatabaseFile=".\./_ctypes.pdb"
+				SubSystem="0"
+				OptimizeReferences="0"
+				EnableCOMDATFolding="0"
+				BaseAddress="0x1D1A0000"
+				ImportLibrary=".\./_ctypes.lib"
+				TargetMachine="0"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath="..\Modules\_ctypes\_ctypes.c">
+		</File>
+		<File
+			RelativePath="..\Modules\_ctypes\callbacks.c">
+		</File>
+		<File
+			RelativePath="..\Modules\_ctypes\callproc.c">
+		</File>
+		<File
+			RelativePath="..\Modules\_ctypes\cfield.c">
+		</File>
+		<File
+			RelativePath="..\Modules\_ctypes\libffi_msvc\ffi.c">
+		</File>
+		<File
+			RelativePath="..\Modules\_ctypes\malloc_closure.c">
+		</File>
+		<File
+			RelativePath="..\Modules\_ctypes\libffi_msvc\prep_cif.c">
+		</File>
+		<File
+			RelativePath="..\Modules\_ctypes\stgdict.c">
+		</File>
+		<File
+			RelativePath="..\Modules\_ctypes\libffi_msvc\win32.c">
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Added: vendor/Python/current/PCbuild/_ctypes_test.vcproj
===================================================================
--- vendor/Python/current/PCbuild/_ctypes_test.vcproj	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild/_ctypes_test.vcproj	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,242 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="_ctypes_test"
+	ProjectGUID="{8CF334D9-4F82-42EB-97AF-83592C5AFD2F}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-debug\_ctypes_test"
+			ConfigurationType="2"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
+				MinimalRebuild="FALSE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="./_ctypes_test_d.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./_ctypes_test_d.pdb"
+				SubSystem="0"
+				ImportLibrary=".\./_ctypes_test_d.lib"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-release\_ctypes_test"
+			ConfigurationType="2"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+				StringPooling="TRUE"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="0"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="./_ctypes_test.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				GenerateDebugInformation="FALSE"
+				ProgramDatabaseFile=".\./_ctypes_test.pdb"
+				SubSystem="0"
+				OptimizeReferences="0"
+				EnableCOMDATFolding="0"
+				ImportLibrary=".\./_ctypes_test.lib"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseItanium|Win32"
+			OutputDirectory="."
+			IntermediateDirectory="ia64-temp-release\_ctypes_test"
+			ConfigurationType="2"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions=" /USECL:MS_ITANIUM"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
+				MinimalRebuild="FALSE"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="3"
+				BufferSecurityCheck="FALSE"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions=" /MACHINE:IA64 /USELINK:MS_SDK"
+				OutputFile="./_ctypes_test_d.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./_ctypes_test_d.pdb"
+				SubSystem="0"
+				ImportLibrary=".\./_ctypes_test_d.lib"
+				TargetMachine="0"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseAMD64|Win32"
+			OutputDirectory="."
+			IntermediateDirectory="amd64-temp-release\_ctypes_test"
+			ConfigurationType="2"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions=" /USECL:MS_OPTERON"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+				StringPooling="TRUE"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="FALSE"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions=" /MACHINE:AMD64 /USELINK:MS_SDK"
+				OutputFile="./_ctypes_test.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				GenerateDebugInformation="FALSE"
+				ProgramDatabaseFile=".\./_ctypes_test.pdb"
+				SubSystem="0"
+				OptimizeReferences="0"
+				EnableCOMDATFolding="0"
+				ImportLibrary=".\./_ctypes_test.lib"
+				TargetMachine="0"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath="..\Modules\_ctypes\_ctypes_test.c">
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Added: vendor/Python/current/PCbuild/_elementtree.vcproj
===================================================================
--- vendor/Python/current/PCbuild/_elementtree.vcproj	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild/_elementtree.vcproj	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,264 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="_elementtree"
+	ProjectGUID="{1966DDE2-4AB7-4E4E-ACC9-C121E4D37F8E}"
+	SccProjectName="_elementtree"
+	SccLocalPath="..">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-debug\_elementtree"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\Include,..\PC,..\Modules\expat"
+				PreprocessorDefinitions="_DEBUG;HAVE_EXPAT_H;WIN32;_WINDOWS;XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;USE_PYEXPAT_CAPI;XML_STATIC;HAVE_MEMMOVE"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="odbccp32.lib"
+				OutputFile="./_elementtree_d.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./_elementtree_d.pdb"
+				SubSystem="2"
+				BaseAddress="0x1D100000"
+				ImportLibrary=".\./_elementtree_d.lib"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-release\_elementtree"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC,..\Modules\expat"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;USE_PYEXPAT_CAPI;XML_STATIC;HAVE_MEMMOVE"
+				StringPooling="TRUE"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="odbccp32.lib"
+				OutputFile="./_elementtree.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./_elementtree.pdb"
+				SubSystem="2"
+				BaseAddress="0x1D100000"
+				ImportLibrary=".\./_elementtree.lib"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseItanium|Win32"
+			OutputDirectory="./."
+			IntermediateDirectory=".\ia64-temp-release\_elementtree"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions=" /USECL:MS_ITANIUM /GS-"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC,..\Modules\expat"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;USE_PYEXPAT_CAPI;XML_STATIC;HAVE_MEMMOVE"
+				StringPooling="TRUE"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="FALSE"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions=" /MACHINE:IA64 /USELINK:MS_SDK"
+				AdditionalDependencies="odbccp32.lib"
+				OutputFile="./_elementtree.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./_elementtree.pdb"
+				SubSystem="2"
+				BaseAddress="0x1D100000"
+				ImportLibrary=".\./_elementtree.lib"
+				TargetMachine="0"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseAMD64|Win32"
+			OutputDirectory="."
+			IntermediateDirectory="amd64-temp-release\_elementtree"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions=" /USECL:MS_OPTERON /GS-"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC,..\Modules\expat"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;USE_PYEXPAT_CAPI;XML_STATIC;HAVE_MEMMOVE"
+				StringPooling="TRUE"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="FALSE"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions=" /MACHINE:AMD64 /USELINK:MS_SDK"
+				AdditionalDependencies="odbccp32.lib"
+				OutputFile="./_elementtree.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./_elementtree.pdb"
+				SubSystem="2"
+				BaseAddress="0x1D100000"
+				ImportLibrary=".\./_elementtree.lib"
+				TargetMachine="0"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath="..\Modules\_elementtree.c">
+		</File>
+		<File
+			RelativePath="..\Modules\expat\xmlparse.c">
+		</File>
+		<File
+			RelativePath="..\Modules\expat\xmlrole.c">
+		</File>
+		<File
+			RelativePath="..\Modules\expat\xmltok.c">
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Added: vendor/Python/current/PCbuild/_msi.vcproj
===================================================================
--- vendor/Python/current/PCbuild/_msi.vcproj	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild/_msi.vcproj	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,252 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="_msi"
+	ProjectGUID="{2C0BEFB9-70E2-4F80-AC5B-4AB8EE023574}"
+	SccProjectName="_msi"
+	SccLocalPath="..\pc">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-debug\_msi"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="fci.lib msi.lib rpcrt4.lib"
+				OutputFile="./_msi_d.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./_msi_d.pdb"
+				BaseAddress="0x1D160000"
+				ImportLibrary=".\./_msi.lib"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-release\_msi"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL"
+				StringPooling="TRUE"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="fci.lib msi.lib rpcrt4.lib"
+				OutputFile="./_msi.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				ProgramDatabaseFile=".\./_msi.pdb"
+				BaseAddress="0x1D160000"
+				ImportLibrary=".\./_msi.lib"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseItanium|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\ia64-temp-release\_msi"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions=" /USECL:MS_ITANIUM /GS-"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL"
+				StringPooling="TRUE"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="FALSE"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions=" /MACHINE:IA64 /USELINK:MS_SDK"
+				AdditionalDependencies="fci.lib msi.lib rpcrt4.lib bufferoverflowU.lib"
+				OutputFile="./_msi.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				ProgramDatabaseFile=".\./_msi.pdb"
+				BaseAddress="0x1D160000"
+				ImportLibrary=".\./_msi.lib"
+				TargetMachine="0"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseAMD64|Win32"
+			OutputDirectory="."
+			IntermediateDirectory="amd64-temp-release\_msi"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions=" /USECL:MS_OPTERON /GS-"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL"
+				StringPooling="TRUE"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="FALSE"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions=" /MACHINE:AMD64 /USELINK:MS_SDK"
+				AdditionalDependencies="fci.lib msi.lib rpcrt4.lib bufferoverflowU.lib"
+				OutputFile="./_msi.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				ProgramDatabaseFile=".\./_msi.pdb"
+				BaseAddress="0x1D160000"
+				ImportLibrary=".\./_msi.lib"
+				TargetMachine="0"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath="..\PC\_msi.c">
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Added: vendor/Python/current/PCbuild/_socket.vcproj
===================================================================
--- vendor/Python/current/PCbuild/_socket.vcproj	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild/_socket.vcproj	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,254 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="_socket"
+	SccProjectName="_socket"
+	SccLocalPath="..">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-debug\_socket"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib"
+				OutputFile="./_socket_d.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./_socket_d.pdb"
+				SubSystem="2"
+				BaseAddress="0x1e1D0000"
+				ImportLibrary=".\./_socket_d.lib"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-release\_socket"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS"
+				StringPooling="TRUE"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib"
+				OutputFile="./_socket.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./_socket.pdb"
+				SubSystem="2"
+				BaseAddress="0x1e1D0000"
+				ImportLibrary=".\./_socket.lib"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseItanium|Win32"
+			OutputDirectory="./."
+			IntermediateDirectory=".\ia64-temp-release\_socket"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions=" /USECL:MS_ITANIUM /GS-"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS"
+				StringPooling="TRUE"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="FALSE"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions=" /MACHINE:IA64 /USELINK:MS_SDK"
+				AdditionalDependencies="ws2_32.lib"
+				OutputFile="./_socket.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./_socket.pdb"
+				SubSystem="2"
+				BaseAddress="0x1e1D0000"
+				ImportLibrary=".\./_socket.lib"
+				TargetMachine="0"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseAMD64|Win32"
+			OutputDirectory="."
+			IntermediateDirectory="amd64-temp-release\_socket"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions=" /USECL:MS_OPTERON /GS-"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS"
+				StringPooling="TRUE"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="FALSE"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions=" /MACHINE:AMD64 /USELINK:MS_SDK"
+				AdditionalDependencies="ws2_32.lib"
+				OutputFile="./_socket.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./_socket.pdb"
+				SubSystem="2"
+				BaseAddress="0x1e1D0000"
+				ImportLibrary=".\./_socket.lib"
+				TargetMachine="0"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath="..\Modules\socketmodule.c">
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Added: vendor/Python/current/PCbuild/_sqlite3.vcproj
===================================================================
--- vendor/Python/current/PCbuild/_sqlite3.vcproj	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild/_sqlite3.vcproj	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,283 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="_sqlite3"
+	ProjectGUID="{2FF0A312-22F9-4C34-B070-842916DE27A9}"
+	SccProjectName="_sqlite3"
+	SccLocalPath="..">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-debug\_sqlite3"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\Include;..\PC;..\..\sqlite-source-3.3.4"
+				PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS;MODULE_NAME=\&quot;sqlite3\&quot;"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="..\..\sqlite-source-3.3.4\sqlite3.lib"
+				OutputFile="./_sqlite3_d.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				IgnoreDefaultLibraryNames=""
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./_sqlite3_d.pdb"
+				SubSystem="2"
+				BaseAddress="0x1e180000"
+				ImportLibrary=".\./_sqlite3_d.lib"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-release\_sqlite3"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include;..\PC;..\..\sqlite-source-3.3.4"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;MODULE_NAME=\&quot;sqlite3\&quot;"
+				StringPooling="TRUE"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="..\..\sqlite-source-3.3.4\sqlite3.lib"
+				OutputFile="./_sqlite3.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				IgnoreDefaultLibraryNames=""
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./_sqlite3.pdb"
+				SubSystem="2"
+				BaseAddress="0x1e180000"
+				ImportLibrary=".\./_sqlite3.lib"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseItanium|Win32"
+			OutputDirectory="./."
+			IntermediateDirectory=".\ia64-temp-release\_sqlite3"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions=" /USECL:MS_ITANIUM /GS-"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include;..\PC;..\..\sqlite-source-3.3.4"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;MODULE_NAME=\&quot;sqlite3\&quot;"
+				StringPooling="TRUE"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="FALSE"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions=" /MACHINE:IA64 /USELINK:MS_SDK"
+				AdditionalDependencies="..\..\sqlite-source-3.3.4\ia64\sqlite3.lib"
+				OutputFile="./_sqlite3.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				IgnoreDefaultLibraryNames=""
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./_sqlite3.pdb"
+				SubSystem="2"
+				BaseAddress="0x1e180000"
+				ImportLibrary=".\./_sqlite3.lib"
+				TargetMachine="0"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseAMD64|Win32"
+			OutputDirectory="."
+			IntermediateDirectory="amd64-temp-release\_sqlite3"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions=" /USECL:MS_OPTERON /GS-"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include;..\PC;..\..\sqlite-source-3.3.4"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;MODULE_NAME=\&quot;sqlite3\&quot;"
+				StringPooling="TRUE"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="FALSE"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions=" /MACHINE:AMD64 /USELINK:MS_SDK"
+				AdditionalDependencies="..\..\sqlite-source-3.3.4\amd64\sqlite3.lib"
+				OutputFile="./_sqlite3.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				IgnoreDefaultLibraryNames=""
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./_sqlite3.pdb"
+				SubSystem="2"
+				BaseAddress="0x1e180000"
+				ImportLibrary=".\./_sqlite3.lib"
+				TargetMachine="0"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath="..\Modules\_sqlite\cache.c">
+		</File>
+		<File
+			RelativePath="..\Modules\_sqlite\connection.c">
+		</File>
+		<File
+			RelativePath="..\Modules\_sqlite\cursor.c">
+		</File>
+		<File
+			RelativePath="..\Modules\_sqlite\microprotocols.c">
+		</File>
+		<File
+			RelativePath="..\Modules\_sqlite\module.c">
+		</File>
+		<File
+			RelativePath="..\Modules\_sqlite\prepare_protocol.c">
+		</File>
+		<File
+			RelativePath="..\Modules\_sqlite\row.c">
+		</File>
+		<File
+			RelativePath="..\Modules\_sqlite\statement.c">
+		</File>
+		<File
+			RelativePath="..\Modules\_sqlite\util.c">
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Added: vendor/Python/current/PCbuild/_ssl.mak
===================================================================
--- vendor/Python/current/PCbuild/_ssl.mak	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild/_ssl.mak	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,37 @@
+
+!IFDEF DEBUG
+SUFFIX=_d.pyd
+TEMP=x86-temp-debug/
+CFLAGS=/Od /Zi /MDd /LDd /DDEBUG /D_DEBUG /DWIN32
+SSL_LIB_DIR=$(SSL_DIR)/out32.dbg
+!ELSE
+SUFFIX=.pyd
+TEMP=x86-temp-release/
+CFLAGS=/Ox /MD /LD /DWIN32
+SSL_LIB_DIR=$(SSL_DIR)/out32
+!ENDIF
+
+INCLUDES=-I ../Include -I ../PC -I $(SSL_DIR)/inc32
+
+SSL_LIBS=gdi32.lib wsock32.lib user32.lib advapi32.lib /LIBPATH:$(SSL_LIB_DIR) libeay32.lib ssleay32.lib
+SSL_SOURCE=../Modules/_ssl.c 
+
+HASH_LIBS=gdi32.lib user32.lib advapi32.lib /libpath:$(SSL_LIB_DIR) libeay32.lib
+HASH_SOURCE=../Modules/_hashopenssl.c 
+
+all: _ssl$(SUFFIX) _hashlib$(SUFFIX)
+
+# Split compile/link into two steps to better support VSExtComp
+_ssl$(SUFFIX): $(SSL_SOURCE) $(SSL_LIB_DIR)/libeay32.lib $(SSL_LIB_DIR)/ssleay32.lib ../PC/*.h ../Include/*.h
+	@if not exist "$(TEMP)/_ssl/." mkdir "$(TEMP)/_ssl"
+	cl /nologo /c $(SSL_SOURCE) $(CFLAGS) /Fo$(TEMP)\_ssl\$*.obj $(INCLUDES)
+	link /nologo @<<
+             /dll /out:_ssl$(SUFFIX) $(TEMP)\_ssl\$*.obj $(SSL_LIBS)
+<<
+
+_hashlib$(SUFFIX): $(HASH_SOURCE) $(SSL_LIB_DIR)/libeay32.lib ../PC/*.h ../Include/*.h
+    @if not exist "$(TEMP)/_hashlib/." mkdir "$(TEMP)/_hashlib"
+    cl /nologo /c $(HASH_SOURCE) $(CFLAGS) $(EXTRA_CFLAGS) /Fo$(TEMP)\_hashlib\$*.obj $(INCLUDES) 
+    link /nologo @<<
+	/dll /out:_hashlib$(SUFFIX) $(HASH_LIBS) $(TEMP)\_hashlib\$*.obj
+<<

Added: vendor/Python/current/PCbuild/_ssl.vcproj
===================================================================
--- vendor/Python/current/PCbuild/_ssl.vcproj	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild/_ssl.vcproj	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="_ssl"
+	RootNamespace="_ssl"
+	SccProjectName=""
+	SccLocalPath=""
+	Keyword="MakeFileProj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-release\_ssl"
+			ConfigurationType="0"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE">
+			<Tool
+				Name="VCNMakeTool"
+				BuildCommandLine="build_ssl.bat $(ConfigurationName)"
+				ReBuildCommandLine="build_ssl.bat $(ConfigurationName) -a"
+				CleanCommandLine="echo Nothing to do"
+				Output="_ssl.pyd"/>
+		</Configuration>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-debug\_ssl"
+			ConfigurationType="0"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE">
+			<Tool
+				Name="VCNMakeTool"
+				BuildCommandLine="build_ssl.bat $(ConfigurationName)"
+				ReBuildCommandLine="build_ssl.bat $(ConfigurationName) -a"
+				CleanCommandLine="echo Nothing to do"
+				Output="_ssl_d.pyd"/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseItanium|Win32"
+			OutputDirectory="./."
+			IntermediateDirectory=".\ia64-temp-release\_ssl"
+			ConfigurationType="0"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE">
+			<Tool
+				Name="VCNMakeTool"
+				BuildCommandLine="build_ssl.bat $(ConfigurationName)"
+				ReBuildCommandLine="build_ssl.bat $(ConfigurationName) -a"
+				CleanCommandLine="echo Nothing to do"
+				Output="_ssl.pyd"/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseAMD64|Win32"
+			OutputDirectory="."
+			IntermediateDirectory="amd64-temp-release\_ssl"
+			ConfigurationType="0"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE">
+			<Tool
+				Name="VCNMakeTool"
+				BuildCommandLine="build_ssl.bat $(ConfigurationName)"
+				ReBuildCommandLine="build_ssl.bat $(ConfigurationName) -a"
+				CleanCommandLine="echo Nothing to do"
+				Output="_ssl.pyd"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath="..\Modules\_ssl.c">
+		</File>
+		<File
+			RelativePath="..\Modules\_hashopenssl.c">
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Added: vendor/Python/current/PCbuild/_testcapi.vcproj
===================================================================
--- vendor/Python/current/PCbuild/_testcapi.vcproj	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild/_testcapi.vcproj	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,247 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="_testcapi"
+	SccProjectName="_testcapi"
+	SccLocalPath="..">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-release\_testcapi"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MMAP_EXPORTS"
+				StringPooling="TRUE"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="./_testcapi.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				ProgramDatabaseFile=".\./_testcapi.pdb"
+				BaseAddress="0x1e1F0000"
+				ImportLibrary=".\./_testcapi.lib"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-debug\_testcapi"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;MMAP_EXPORTS"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="./_testcapi_d.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./_testcapi_d.pdb"
+				BaseAddress="0x1e1F0000"
+				ImportLibrary=".\./_testcapi_d.lib"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseItanium|Win32"
+			OutputDirectory="./."
+			IntermediateDirectory=".\ia64-temp-release\_testcapi"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions=" /USECL:MS_ITANIUM /GS-"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MMAP_EXPORTS"
+				StringPooling="TRUE"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="FALSE"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions=" /MACHINE:IA64 /USELINK:MS_SDK"
+				OutputFile="./_testcapi.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				ProgramDatabaseFile=".\./_testcapi.pdb"
+				BaseAddress="0x1e1F0000"
+				ImportLibrary=".\./_testcapi.lib"
+				TargetMachine="0"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseAMD64|Win32"
+			OutputDirectory="."
+			IntermediateDirectory="amd64-temp-release\_testcapi"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions=" /USECL:MS_OPTERON /GS-"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MMAP_EXPORTS"
+				StringPooling="TRUE"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="FALSE"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions=" /MACHINE:AMD64 /USELINK:MS_SDK"
+				OutputFile="./_testcapi.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				ProgramDatabaseFile=".\./_testcapi.pdb"
+				BaseAddress="0x1e1F0000"
+				ImportLibrary=".\./_testcapi.lib"
+				TargetMachine="0"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath="..\Modules\_testcapimodule.c">
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Added: vendor/Python/current/PCbuild/_tkinter.vcproj
===================================================================
--- vendor/Python/current/PCbuild/_tkinter.vcproj	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild/_tkinter.vcproj	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,261 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="_tkinter"
+	SccProjectName="_tkinter"
+	SccLocalPath="..\..\..">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-release\_tkinter"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\..\tcltk\include,..\Include,..\PC"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;WITH_APPINIT"
+				StringPooling="TRUE"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="..\..\tcltk\lib\tk84.lib ..\..\tcltk\lib\tcl84.lib odbccp32.lib"
+				OutputFile="./_tkinter.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				AdditionalLibraryDirectories=""
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./_tkinter.pdb"
+				SubSystem="2"
+				BaseAddress="0x1e190000"
+				ImportLibrary=".\./_tkinter.lib"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-debug\_tkinter"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\..\tcltk\include,..\Include,..\PC"
+				PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS;WITH_APPINIT"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="..\..\tcltk\lib\tk84.lib ..\..\tcltk\lib\tcl84.lib odbccp32.lib"
+				OutputFile="./_tkinter_d.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				AdditionalLibraryDirectories=""
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./_tkinter_d.pdb"
+				SubSystem="2"
+				BaseAddress="0x1e190000"
+				ImportLibrary=".\./_tkinter_d.lib"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseItanium|Win32"
+			OutputDirectory="./."
+			IntermediateDirectory=".\ia64-temp-release\_tkinter"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions=" /USECL:MS_ITANIUM /GS-"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\..\tcltk\include,..\Include,..\PC"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;WITH_APPINIT"
+				StringPooling="TRUE"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="FALSE"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions=" /MACHINE:IA64 /USELINK:MS_SDK"
+				AdditionalDependencies="..\..\tcltk\lib\tk84.lib ..\..\tcltk\lib\tcl84.lib odbccp32.lib"
+				OutputFile="./_tkinter.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				AdditionalLibraryDirectories=""
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./_tkinter.pdb"
+				SubSystem="2"
+				BaseAddress="0x1e190000"
+				ImportLibrary=".\./_tkinter.lib"
+				TargetMachine="0"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseAMD64|Win32"
+			OutputDirectory="."
+			IntermediateDirectory="amd64-temp-release\_tkinter"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions=" /USECL:MS_OPTERON /GS-"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\..\tcltk\include,..\Include,..\PC"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;WITH_APPINIT"
+				StringPooling="TRUE"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="FALSE"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions=" /MACHINE:AMD64 /USELINK:MS_SDK"
+				AdditionalDependencies="..\..\tcltk\lib\tk84.lib ..\..\tcltk\lib\tcl84.lib odbccp32.lib"
+				OutputFile="./_tkinter.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				AdditionalLibraryDirectories=""
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./_tkinter.pdb"
+				SubSystem="2"
+				BaseAddress="0x1e190000"
+				ImportLibrary=".\./_tkinter.lib"
+				TargetMachine="0"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath="..\Modules\_tkinter.c">
+		</File>
+		<File
+			RelativePath="..\Modules\tkappinit.c">
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Added: vendor/Python/current/PCbuild/build_ssl.bat
===================================================================
--- vendor/Python/current/PCbuild/build_ssl.bat	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild/build_ssl.bat	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,10 @@
+ at echo off
+if not defined HOST_PYTHON (
+  if %1 EQU Debug (
+    set HOST_PYTHON=python_d.exe
+  ) ELSE (
+    set HOST_PYTHON=python.exe
+  )
+)
+%HOST_PYTHON% build_ssl.py %1 %2
+

Added: vendor/Python/current/PCbuild/build_ssl.py
===================================================================
--- vendor/Python/current/PCbuild/build_ssl.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild/build_ssl.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,181 @@
+# Script for building the _ssl and _hashlib modules for Windows.
+# Uses Perl to setup the OpenSSL environment correctly
+# and build OpenSSL, then invokes a simple nmake session
+# for the actual _ssl.pyd and _hashlib.pyd DLLs.
+
+# THEORETICALLY, you can:
+# * Unpack the latest SSL release one level above your main Python source
+#   directory.  It is likely you will already find the zlib library and
+#   any other external packages there.
+# * Install ActivePerl and ensure it is somewhere on your path.
+# * Run this script from the PCBuild directory.
+#
+# it should configure and build SSL, then build the _ssl and _hashlib
+# Python extensions without intervention.
+
+import os, sys, re
+
+# Find all "foo.exe" files on the PATH.
+def find_all_on_path(filename, extras = None):
+    entries = os.environ["PATH"].split(os.pathsep)
+    ret = []
+    for p in entries:
+        fname = os.path.abspath(os.path.join(p, filename))
+        if os.path.isfile(fname) and fname not in ret:
+            ret.append(fname)
+    if extras:
+        for p in extras:
+            fname = os.path.abspath(os.path.join(p, filename))
+            if os.path.isfile(fname) and fname not in ret:
+                ret.append(fname)
+    return ret
+
+# Find a suitable Perl installation for OpenSSL.
+# cygwin perl does *not* work.  ActivePerl does.
+# Being a Perl dummy, the simplest way I can check is if the "Win32" package
+# is available.
+def find_working_perl(perls):
+    for perl in perls:
+        fh = os.popen(perl + ' -e "use Win32;"')
+        fh.read()
+        rc = fh.close()
+        if rc:
+            continue
+        return perl
+    print "Can not find a suitable PERL:"
+    if perls:
+        print " the following perl interpreters were found:"
+        for p in perls:
+            print " ", p
+        print " None of these versions appear suitable for building OpenSSL"
+    else:
+        print " NO perl interpreters were found on this machine at all!"
+    print " Please install ActivePerl and ensure it appears on your path"
+    print "The Python SSL module was not built"
+    return None
+
+# Locate the best SSL directory given a few roots to look into.
+def find_best_ssl_dir(sources):
+    candidates = []
+    for s in sources:
+        try:
+            # note: do not abspath s; the build will fail if any
+            # higher up directory name has spaces in it.
+            fnames = os.listdir(s)
+        except os.error:
+            fnames = []
+        for fname in fnames:
+            fqn = os.path.join(s, fname)
+            if os.path.isdir(fqn) and fname.startswith("openssl-"):
+                candidates.append(fqn)
+    # Now we have all the candidates, locate the best.
+    best_parts = []
+    best_name = None
+    for c in candidates:
+        parts = re.split("[.-]", os.path.basename(c))[1:]
+        # eg - openssl-0.9.7-beta1 - ignore all "beta" or any other qualifiers
+        if len(parts) >= 4:
+            continue
+        if parts > best_parts:
+            best_parts = parts
+            best_name = c
+    if best_name is not None:
+        print "Found an SSL directory at '%s'" % (best_name,)
+    else:
+        print "Could not find an SSL directory in '%s'" % (sources,)
+    sys.stdout.flush()
+    return best_name
+
+def run_configure(configure, do_script):
+    os.system("perl Configure "+configure)
+    os.system(do_script)
+
+def main():
+    build_all = "-a" in sys.argv
+    if sys.argv[1] == "Release":
+        arch = "x86"
+        debug = False
+        configure = "VC-WIN32"
+        do_script = "ms\\do_masm"
+        makefile = "ms\\nt.mak"
+    elif sys.argv[1] == "Debug":
+        arch = "x86"
+        debug = True
+        configure = "VC-WIN32"
+        do_script = "ms\\do_masm"
+        makefile="ms\\d32.mak"
+    elif sys.argv[1] == "ReleaseItanium":
+        arch = "ia64"
+        debug = False
+        configure = "VC-WIN64I"
+        do_script = "ms\\do_win64i"
+        makefile = "ms\\nt.mak"
+        os.environ["VSEXTCOMP_USECL"] = "MS_ITANIUM"
+    elif sys.argv[1] == "ReleaseAMD64":
+        arch="amd64"
+        debug=False
+        configure = "VC-WIN64A"
+        do_script = "ms\\do_win64a"
+        makefile = "ms\\nt.mak"
+        os.environ["VSEXTCOMP_USECL"] = "MS_OPTERON"
+    make_flags = ""
+    if build_all:
+        make_flags = "-a"
+    # perl should be on the path, but we also look in "\perl" and "c:\\perl"
+    # as "well known" locations
+    perls = find_all_on_path("perl.exe", ["\\perl\\bin", "C:\\perl\\bin"])
+    perl = find_working_perl(perls)
+    if perl is None:
+        sys.exit(1)
+
+    print "Found a working perl at '%s'" % (perl,)
+    sys.stdout.flush()
+    # Look for SSL 2 levels up from pcbuild - ie, same place zlib etc all live.
+    ssl_dir = find_best_ssl_dir(("..\\..",))
+    if ssl_dir is None:
+        sys.exit(1)
+
+    old_cd = os.getcwd()
+    try:
+        os.chdir(ssl_dir)
+        # If the ssl makefiles do not exist, we invoke Perl to generate them.
+        # Due to a bug in this script, the makefile sometimes ended up empty
+        # Force a regeneration if it is.
+        if not os.path.isfile(makefile) or os.path.getsize(makefile)==0:
+            print "Creating the makefiles..."
+            sys.stdout.flush()
+            # Put our working Perl at the front of our path
+            os.environ["PATH"] = os.path.dirname(perl) + \
+                                          os.pathsep + \
+                                          os.environ["PATH"]
+            run_configure(configure, do_script)
+            if arch=="x86" and debug:
+                # the do_masm script in openssl doesn't generate a debug
+                # build makefile so we generate it here:
+                os.system("perl util\mk1mf.pl debug "+configure+" >"+makefile)
+
+        # Now run make.
+        makeCommand = "nmake /nologo PERL=\"%s\" -f \"%s\"" %(perl, makefile)
+        print "Executing ssl makefiles:", makeCommand
+        sys.stdout.flush()
+        rc = os.system(makeCommand)
+        if rc:
+            print "Executing "+makefile+" failed"
+            print rc
+            sys.exit(rc)
+    finally:
+        os.chdir(old_cd)
+    # And finally, we can build the _ssl module itself for Python.
+    defs = "SSL_DIR=\"%s\"" % (ssl_dir,)
+    if debug:
+        defs = defs + " " + "DEBUG=1"
+    if arch in ('amd64', 'ia64'):
+        defs = defs + " EXTRA_CFLAGS=/GS-"
+    makeCommand = 'nmake /nologo -f _ssl.mak ' + defs + " " + make_flags
+    print "Executing:", makeCommand
+    sys.stdout.flush()
+    rc = os.system(makeCommand)
+    sys.exit(rc)
+
+if __name__=='__main__':
+    main()

Added: vendor/Python/current/PCbuild/bz2.vcproj
===================================================================
--- vendor/Python/current/PCbuild/bz2.vcproj	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild/bz2.vcproj	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,271 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="bz2"
+	RootNamespace="bz2"
+	SccProjectName="bz2"
+	SccLocalPath="..">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-debug\bz2"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\Include,..\PC,..\..\bzip2-1.0.3"
+				PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="..\..\bzip2-1.0.3\libbz2.lib"
+				OutputFile="./bz2_d.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				IgnoreDefaultLibraryNames="msvcrt,libc"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./bz2_d.pdb"
+				SubSystem="2"
+				BaseAddress="0x1D170000"
+				ImportLibrary=".\./bz2_d.lib"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				CommandLine="cd ..\..\bzip2-1.0.3
+nmake /nologo /f makefile.msc
+"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-release\bz2"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC,..\..\bzip2-1.0.3"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS"
+				StringPooling="TRUE"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="..\..\bzip2-1.0.3\libbz2.lib"
+				OutputFile="./bz2.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				IgnoreDefaultLibraryNames="libc"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./bz2.pdb"
+				SubSystem="2"
+				BaseAddress="0x1D170000"
+				ImportLibrary=".\./bz2.lib"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				CommandLine="cd ..\..\bzip2-1.0.3
+nmake /nologo /f makefile.msc lib
+"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseItanium|Win32"
+			OutputDirectory="./."
+			IntermediateDirectory=".\ia64-temp-release\bz2"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions=" /USECL:MS_ITANIUM /GS-"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC,..\..\bzip2-1.0.3"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS"
+				StringPooling="TRUE"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="FALSE"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions=" /MACHINE:IA64 /USELINK:MS_SDK"
+				AdditionalDependencies="..\..\bzip2-1.0.3\libbz2.lib"
+				OutputFile="./bz2.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				IgnoreDefaultLibraryNames="libc"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./bz2.pdb"
+				SubSystem="2"
+				BaseAddress="0x1D170000"
+				ImportLibrary=".\./bz2.lib"
+				TargetMachine="0"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				CommandLine="cd ..\..\bzip2-1.0.3
+nmake /nologo /f makefile.msc lib
+"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseAMD64|Win32"
+			OutputDirectory="."
+			IntermediateDirectory="amd64-temp-release\bz2"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions=" /USECL:MS_OPTERON /GS-"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC,..\..\bzip2-1.0.3"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS"
+				StringPooling="TRUE"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="FALSE"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions=" /MACHINE:AMD64 /USELINK:MS_SDK"
+				AdditionalDependencies="..\..\bzip2-1.0.3\libbz2.lib"
+				OutputFile="./bz2.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				IgnoreDefaultLibraryNames="libc"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./bz2.pdb"
+				SubSystem="2"
+				BaseAddress="0x1D170000"
+				ImportLibrary=".\./bz2.lib"
+				TargetMachine="0"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				CommandLine="cd ..\..\bzip2-1.0.3
+nmake /nologo /f makefile.msc lib
+"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath="..\Modules\bz2module.c">
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Added: vendor/Python/current/PCbuild/db.build
===================================================================
--- vendor/Python/current/PCbuild/db.build	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild/db.build	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+<project>
+ <target name="all" description="Build all targets.">
+   <solution configuration="release">
+     <projects>
+       <include name="db_static.vcproj" />
+     </projects>
+   </solution>
+ </target>
+</project>

Added: vendor/Python/current/PCbuild/field3.py
===================================================================
--- vendor/Python/current/PCbuild/field3.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild/field3.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,35 @@
+# An absurd workaround for the lack of arithmetic in MS's resource compiler.
+# After building Python, run this, then paste the output into the appropriate
+# part of PC\python_nt.rc.
+# Example output:
+#
+# * For 2.3a0,
+# * PY_MICRO_VERSION = 0
+# * PY_RELEASE_LEVEL = 'alpha' = 0xA
+# * PY_RELEASE_SERIAL = 1
+# *
+# * and 0*1000 + 10*10 + 1 = 101.
+# */
+# #define FIELD3 101
+
+import sys
+
+major, minor, micro, level, serial = sys.version_info
+levelnum = {'alpha': 0xA,
+            'beta': 0xB,
+            'candidate': 0xC,
+            'final': 0xF,
+           }[level]
+string = sys.version.split()[0] # like '2.3a0'
+
+print " * For %s," % string
+print " * PY_MICRO_VERSION = %d" % micro
+print " * PY_RELEASE_LEVEL = %r = %s" % (level, hex(levelnum))
+print " * PY_RELEASE_SERIAL = %d" % serial
+print " *"
+
+field3 = micro * 1000 + levelnum * 10 + serial
+
+print " * and %d*1000 + %d*10 + %d = %d" % (micro, levelnum, serial, field3)
+print " */"
+print "#define FIELD3", field3

Added: vendor/Python/current/PCbuild/installer.bmp
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/PCbuild/installer.bmp
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/PCbuild/make_buildinfo.c
===================================================================
--- vendor/Python/current/PCbuild/make_buildinfo.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild/make_buildinfo.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,92 @@
+#include <windows.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+
+/* This file creates the getbuildinfo.o object, by first
+   invoking subwcrev.exe (if found), and then invoking cl.exe.
+   As a side effect, it might generate PCBuild\getbuildinfo2.c
+   also. If this isn't a subversion checkout, or subwcrev isn't
+   found, it compiles ..\\Modules\\getbuildinfo.c instead.
+
+   Currently, subwcrev.exe is found from the registry entries
+   of TortoiseSVN.
+
+   No attempt is made to place getbuildinfo.o into the proper
+   binary directory. This isn't necessary, as this tool is
+   invoked as a pre-link step for pythoncore, so that overwrites
+   any previous getbuildinfo.o.
+
+*/
+
+int make_buildinfo2()
+{
+	struct _stat st;
+	HKEY hTortoise;
+	char command[500];
+	DWORD type, size;
+	if (_stat(".svn", &st) < 0)
+		return 0;
+	/* Allow suppression of subwcrev.exe invocation if a no_subwcrev file is present. */
+	if (_stat("no_subwcrev", &st) == 0)
+		return 0;
+	if (RegOpenKey(HKEY_LOCAL_MACHINE, "Software\\TortoiseSVN", &hTortoise) != ERROR_SUCCESS &&
+	    RegOpenKey(HKEY_CURRENT_USER, "Software\\TortoiseSVN", &hTortoise) != ERROR_SUCCESS)
+		/* Tortoise not installed */
+		return 0;
+	command[0] = '"';  /* quote the path to the executable */
+	size = sizeof(command) - 1;
+	if (RegQueryValueEx(hTortoise, "Directory", 0, &type, command+1, &size) != ERROR_SUCCESS ||
+	    type != REG_SZ)
+		/* Registry corrupted */
+		return 0;
+	strcat(command, "bin\\subwcrev.exe");
+	if (_stat(command+1, &st) < 0)
+		/* subwcrev.exe not part of the release */
+		return 0;
+	strcat(command, "\" .. ..\\Modules\\getbuildinfo.c getbuildinfo2.c");
+	puts(command); fflush(stdout);
+	if (system(command) < 0)
+		return 0;
+	return 1;
+}
+
+int main(int argc, char*argv[])
+{
+	char command[500] = "cl.exe -c -D_WIN32 -DUSE_DL_EXPORT -D_WINDOWS -DWIN32 -D_WINDLL ";
+	int do_unlink, result;
+	if (argc != 2) {
+		fprintf(stderr, "make_buildinfo $(ConfigurationName)\n");
+		return EXIT_FAILURE;
+	}
+	if (strcmp(argv[1], "Release") == 0) {
+		strcat(command, "-MD ");
+	}
+	else if (strcmp(argv[1], "Debug") == 0) {
+		strcat(command, "-D_DEBUG -MDd ");
+	}
+	else if (strcmp(argv[1], "ReleaseItanium") == 0) {
+		strcat(command, "-MD /USECL:MS_ITANIUM ");
+	}
+	else if (strcmp(argv[1], "ReleaseAMD64") == 0) {
+		strcat(command, "-MD ");
+		strcat(command, "-MD /USECL:MS_OPTERON ");
+	}
+	else {
+		fprintf(stderr, "unsupported configuration %s\n", argv[1]);
+		return EXIT_FAILURE;
+	}
+
+	if ((do_unlink = make_buildinfo2()))
+		strcat(command, "getbuildinfo2.c -DSUBWCREV ");
+	else
+		strcat(command, "..\\Modules\\getbuildinfo.c");
+	strcat(command, " -Fogetbuildinfo.o -I..\\Include -I..\\PC");
+	puts(command); fflush(stdout);
+	result = system(command);
+	if (do_unlink)
+		unlink("getbuildinfo2.c");
+	if (result < 0)
+		return EXIT_FAILURE;
+	return 0;
+}
\ No newline at end of file

Added: vendor/Python/current/PCbuild/make_buildinfo.vcproj
===================================================================
--- vendor/Python/current/PCbuild/make_buildinfo.vcproj	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild/make_buildinfo.vcproj	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="windows-1250"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="make_buildinfo"
+	ProjectGUID="{C73F0EC1-358B-4177-940F-0846AC8B04CD}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="."
+			IntermediateDirectory=".\x86-temp-release\make_buildinfo"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="5"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="4"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)/make_buildinfo.exe"
+				LinkIncremental="2"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/make_buildinfo.pdb"
+				SubSystem="1"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="."
+			IntermediateDirectory=".\x86-temp-release\make_buildinfo"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+				RuntimeLibrary="4"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)/make_buildinfo.exe"
+				LinkIncremental="1"
+				GenerateDebugInformation="TRUE"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+			<File
+				RelativePath=".\make_buildinfo.c">
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Added: vendor/Python/current/PCbuild/make_versioninfo.vcproj
===================================================================
--- vendor/Python/current/PCbuild/make_versioninfo.vcproj	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild/make_versioninfo.vcproj	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,142 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="make_versioninfo"
+	RootNamespace="make_versioninfo"
+	SccProjectName="make_versioninfo"
+	SccLocalPath="..">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-release\make_versioninfo"
+			ConfigurationType="1"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+				StringPooling="TRUE"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"
+				CommandLine=".\make_versioninfo.exe &gt;..\PC\pythonnt_rc.h
+"
+				Outputs="..\PC\pythonnt_rc.h"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="odbccp32.lib"
+				OutputFile=".\./make_versioninfo.exe"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./make_versioninfo.pdb"
+				SubSystem="1"
+				BaseAddress="0x1d000000"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				CommandLine="$(TargetFileName) &gt; ..\PC\python_nt.h"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-debug\make_versioninfo"
+			ConfigurationType="1"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="2"
+				BrowseInformation="1"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"
+				CommandLine=".\make_versioninfo_d.exe &gt;..\PC\pythonnt_rc_d.h
+"
+				Outputs="..\PC\pythonnt_rc_d.h"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="odbccp32.lib"
+				OutputFile="./make_versioninfo_d.exe"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./make_versioninfo_d.pdb"
+				SubSystem="1"
+				BaseAddress="0x1d000000"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				CommandLine="$(TargetFileName) &gt; ..\PC\python_nt_d.h"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath="..\PC\make_versioninfo.c">
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Added: vendor/Python/current/PCbuild/pcbuild.sln
===================================================================
--- vendor/Python/current/PCbuild/pcbuild.sln	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild/pcbuild.sln	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,286 @@
+Microsoft Visual Studio Solution File, Format Version 8.00
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_bsddb", "_bsddb.vcproj", "{E1DBB220-D64B-423D-A545-539A55AA7FE2}"
+	ProjectSection(ProjectDependencies) = postProject
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_socket", "_socket.vcproj", "{324F66C2-44D0-4D50-B979-F9DAE7FD36DB}"
+	ProjectSection(ProjectDependencies) = postProject
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_ssl", "_ssl.vcproj", "{8E85BA54-8A47-4C8B-B72E-8E17579CC6D7}"
+	ProjectSection(ProjectDependencies) = postProject
+		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9} = {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
+		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058} = {E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testcapi", "_testcapi.vcproj", "{59CBF474-9E06-4C50-9142-C44A118BB447}"
+	ProjectSection(ProjectDependencies) = postProject
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_tkinter", "_tkinter.vcproj", "{5B51DFF7-5DC0-41F8-8791-A4AB7114A151}"
+	ProjectSection(ProjectDependencies) = postProject
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bz2", "bz2.vcproj", "{AC557788-6354-43F7-BE05-C9C8C59A344A}"
+	ProjectSection(ProjectDependencies) = postProject
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "make_versioninfo", "make_versioninfo.vcproj", "{F0E0541E-F17D-430B-97C4-93ADF0DD284E}"
+	ProjectSection(ProjectDependencies) = postProject
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pyexpat", "pyexpat.vcproj", "{7E551393-3C43-47F8-9F3F-5BC368A6C487}"
+	ProjectSection(ProjectDependencies) = postProject
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "python", "python.vcproj", "{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}"
+	ProjectSection(ProjectDependencies) = postProject
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythoncore", "pythoncore.vcproj", "{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}"
+	ProjectSection(ProjectDependencies) = postProject
+		{F0E0541E-F17D-430B-97C4-93ADF0DD284E} = {F0E0541E-F17D-430B-97C4-93ADF0DD284E}
+		{C73F0EC1-358B-4177-940F-0846AC8B04CD} = {C73F0EC1-358B-4177-940F-0846AC8B04CD}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythonw", "pythonw.vcproj", "{F4229CC3-873C-49AE-9729-DD308ED4CD4A}"
+	ProjectSection(ProjectDependencies) = postProject
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "select", "select.vcproj", "{97239A56-DBC0-41D2-BC14-C87D9B97D63B}"
+	ProjectSection(ProjectDependencies) = postProject
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unicodedata", "unicodedata.vcproj", "{FA5FC7EB-C72F-415F-AE42-91DD605ABDDA}"
+	ProjectSection(ProjectDependencies) = postProject
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "w9xpopen", "w9xpopen.vcproj", "{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}"
+	ProjectSection(ProjectDependencies) = postProject
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "winsound", "winsound.vcproj", "{51F35FAE-FB92-4B2C-9187-1542C065AD77}"
+	ProjectSection(ProjectDependencies) = postProject
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_elementtree", "_elementtree.vcproj", "{1966DDE2-4AB7-4E4E-ACC9-C121E4D37F8E}"
+	ProjectSection(ProjectDependencies) = postProject
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "make_buildinfo", "make_buildinfo.vcproj", "{C73F0EC1-358B-4177-940F-0846AC8B04CD}"
+	ProjectSection(ProjectDependencies) = postProject
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_msi", "_msi.vcproj", "{2C0BEFB9-70E2-4F80-AC5B-4AB8EE023574}"
+	ProjectSection(ProjectDependencies) = postProject
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_ctypes", "_ctypes.vcproj", "{F22F40F4-D318-40DC-96B3-88DC81CE0894}"
+	ProjectSection(ProjectDependencies) = postProject
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_ctypes_test", "_ctypes_test.vcproj", "{8CF334D9-4F82-42EB-97AF-83592C5AFD2F}"
+	ProjectSection(ProjectDependencies) = postProject
+		{F22F40F4-D318-40DC-96B3-88DC81CE0894} = {F22F40F4-D318-40DC-96B3-88DC81CE0894}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_sqlite3", "_sqlite3.vcproj", "{2FF0A312-22F9-4C34-B070-842916DE27A9}"
+	ProjectSection(ProjectDependencies) = postProject
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
+	EndProjectSection
+EndProject
+Global
+	GlobalSection(SolutionConfiguration) = preSolution
+		Debug = Debug
+		Release = Release
+		ReleaseAMD64 = ReleaseAMD64
+		ReleaseItanium = ReleaseItanium
+	EndGlobalSection
+	GlobalSection(ProjectConfiguration) = postSolution
+		{E1DBB220-D64B-423D-A545-539A55AA7FE2}.Debug.ActiveCfg = Debug|Win32
+		{E1DBB220-D64B-423D-A545-539A55AA7FE2}.Debug.Build.0 = Debug|Win32
+		{E1DBB220-D64B-423D-A545-539A55AA7FE2}.Release.ActiveCfg = Release|Win32
+		{E1DBB220-D64B-423D-A545-539A55AA7FE2}.Release.Build.0 = Release|Win32
+		{E1DBB220-D64B-423D-A545-539A55AA7FE2}.ReleaseAMD64.ActiveCfg = ReleaseAMD64|Win32
+		{E1DBB220-D64B-423D-A545-539A55AA7FE2}.ReleaseAMD64.Build.0 = ReleaseAMD64|Win32
+		{E1DBB220-D64B-423D-A545-539A55AA7FE2}.ReleaseItanium.ActiveCfg = ReleaseItanium|Win32
+		{E1DBB220-D64B-423D-A545-539A55AA7FE2}.ReleaseItanium.Build.0 = ReleaseItanium|Win32
+		{324F66C2-44D0-4D50-B979-F9DAE7FD36DB}.Debug.ActiveCfg = Debug|Win32
+		{324F66C2-44D0-4D50-B979-F9DAE7FD36DB}.Debug.Build.0 = Debug|Win32
+		{324F66C2-44D0-4D50-B979-F9DAE7FD36DB}.Release.ActiveCfg = Release|Win32
+		{324F66C2-44D0-4D50-B979-F9DAE7FD36DB}.Release.Build.0 = Release|Win32
+		{324F66C2-44D0-4D50-B979-F9DAE7FD36DB}.ReleaseAMD64.ActiveCfg = ReleaseAMD64|Win32
+		{324F66C2-44D0-4D50-B979-F9DAE7FD36DB}.ReleaseAMD64.Build.0 = ReleaseAMD64|Win32
+		{324F66C2-44D0-4D50-B979-F9DAE7FD36DB}.ReleaseItanium.ActiveCfg = ReleaseItanium|Win32
+		{324F66C2-44D0-4D50-B979-F9DAE7FD36DB}.ReleaseItanium.Build.0 = ReleaseItanium|Win32
+		{8E85BA54-8A47-4C8B-B72E-8E17579CC6D7}.Debug.ActiveCfg = Debug|Win32
+		{8E85BA54-8A47-4C8B-B72E-8E17579CC6D7}.Debug.Build.0 = Debug|Win32
+		{8E85BA54-8A47-4C8B-B72E-8E17579CC6D7}.Release.ActiveCfg = Release|Win32
+		{8E85BA54-8A47-4C8B-B72E-8E17579CC6D7}.Release.Build.0 = Release|Win32
+		{8E85BA54-8A47-4C8B-B72E-8E17579CC6D7}.ReleaseAMD64.ActiveCfg = ReleaseAMD64|Win32
+		{8E85BA54-8A47-4C8B-B72E-8E17579CC6D7}.ReleaseAMD64.Build.0 = ReleaseAMD64|Win32
+		{8E85BA54-8A47-4C8B-B72E-8E17579CC6D7}.ReleaseItanium.ActiveCfg = ReleaseItanium|Win32
+		{8E85BA54-8A47-4C8B-B72E-8E17579CC6D7}.ReleaseItanium.Build.0 = ReleaseItanium|Win32
+		{59CBF474-9E06-4C50-9142-C44A118BB447}.Debug.ActiveCfg = Debug|Win32
+		{59CBF474-9E06-4C50-9142-C44A118BB447}.Debug.Build.0 = Debug|Win32
+		{59CBF474-9E06-4C50-9142-C44A118BB447}.Release.ActiveCfg = Release|Win32
+		{59CBF474-9E06-4C50-9142-C44A118BB447}.Release.Build.0 = Release|Win32
+		{59CBF474-9E06-4C50-9142-C44A118BB447}.ReleaseAMD64.ActiveCfg = ReleaseAMD64|Win32
+		{59CBF474-9E06-4C50-9142-C44A118BB447}.ReleaseAMD64.Build.0 = ReleaseAMD64|Win32
+		{59CBF474-9E06-4C50-9142-C44A118BB447}.ReleaseItanium.ActiveCfg = ReleaseItanium|Win32
+		{59CBF474-9E06-4C50-9142-C44A118BB447}.ReleaseItanium.Build.0 = ReleaseItanium|Win32
+		{5B51DFF7-5DC0-41F8-8791-A4AB7114A151}.Debug.ActiveCfg = Debug|Win32
+		{5B51DFF7-5DC0-41F8-8791-A4AB7114A151}.Debug.Build.0 = Debug|Win32
+		{5B51DFF7-5DC0-41F8-8791-A4AB7114A151}.Release.ActiveCfg = Release|Win32
+		{5B51DFF7-5DC0-41F8-8791-A4AB7114A151}.Release.Build.0 = Release|Win32
+		{5B51DFF7-5DC0-41F8-8791-A4AB7114A151}.ReleaseAMD64.ActiveCfg = ReleaseAMD64|Win32
+		{5B51DFF7-5DC0-41F8-8791-A4AB7114A151}.ReleaseAMD64.Build.0 = ReleaseAMD64|Win32
+		{5B51DFF7-5DC0-41F8-8791-A4AB7114A151}.ReleaseItanium.ActiveCfg = ReleaseItanium|Win32
+		{5B51DFF7-5DC0-41F8-8791-A4AB7114A151}.ReleaseItanium.Build.0 = ReleaseItanium|Win32
+		{AC557788-6354-43F7-BE05-C9C8C59A344A}.Debug.ActiveCfg = Debug|Win32
+		{AC557788-6354-43F7-BE05-C9C8C59A344A}.Debug.Build.0 = Debug|Win32
+		{AC557788-6354-43F7-BE05-C9C8C59A344A}.Release.ActiveCfg = Release|Win32
+		{AC557788-6354-43F7-BE05-C9C8C59A344A}.Release.Build.0 = Release|Win32
+		{AC557788-6354-43F7-BE05-C9C8C59A344A}.ReleaseAMD64.ActiveCfg = ReleaseAMD64|Win32
+		{AC557788-6354-43F7-BE05-C9C8C59A344A}.ReleaseAMD64.Build.0 = ReleaseAMD64|Win32
+		{AC557788-6354-43F7-BE05-C9C8C59A344A}.ReleaseItanium.ActiveCfg = ReleaseItanium|Win32
+		{AC557788-6354-43F7-BE05-C9C8C59A344A}.ReleaseItanium.Build.0 = ReleaseItanium|Win32
+		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Debug.ActiveCfg = Debug|Win32
+		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Debug.Build.0 = Debug|Win32
+		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Release.ActiveCfg = Release|Win32
+		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Release.Build.0 = Release|Win32
+		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.ReleaseAMD64.ActiveCfg = Release|Win32
+		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.ReleaseAMD64.Build.0 = Release|Win32
+		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.ReleaseItanium.ActiveCfg = Release|Win32
+		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.ReleaseItanium.Build.0 = Release|Win32
+		{7E551393-3C43-47F8-9F3F-5BC368A6C487}.Debug.ActiveCfg = Debug|Win32
+		{7E551393-3C43-47F8-9F3F-5BC368A6C487}.Debug.Build.0 = Debug|Win32
+		{7E551393-3C43-47F8-9F3F-5BC368A6C487}.Release.ActiveCfg = Release|Win32
+		{7E551393-3C43-47F8-9F3F-5BC368A6C487}.Release.Build.0 = Release|Win32
+		{7E551393-3C43-47F8-9F3F-5BC368A6C487}.ReleaseAMD64.ActiveCfg = ReleaseAMD64|Win32
+		{7E551393-3C43-47F8-9F3F-5BC368A6C487}.ReleaseAMD64.Build.0 = ReleaseAMD64|Win32
+		{7E551393-3C43-47F8-9F3F-5BC368A6C487}.ReleaseItanium.ActiveCfg = ReleaseItanium|Win32
+		{7E551393-3C43-47F8-9F3F-5BC368A6C487}.ReleaseItanium.Build.0 = ReleaseItanium|Win32
+		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug.ActiveCfg = Debug|Win32
+		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug.Build.0 = Debug|Win32
+		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release.ActiveCfg = Release|Win32
+		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release.Build.0 = Release|Win32
+		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.ReleaseAMD64.ActiveCfg = ReleaseAMD64|Win32
+		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.ReleaseAMD64.Build.0 = ReleaseAMD64|Win32
+		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.ReleaseItanium.ActiveCfg = ReleaseItanium|Win32
+		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.ReleaseItanium.Build.0 = ReleaseItanium|Win32
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug.ActiveCfg = Debug|Win32
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug.Build.0 = Debug|Win32
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Release.ActiveCfg = Release|Win32
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Release.Build.0 = Release|Win32
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.ReleaseAMD64.ActiveCfg = ReleaseAMD64|Win32
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.ReleaseAMD64.Build.0 = ReleaseAMD64|Win32
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.ReleaseItanium.ActiveCfg = ReleaseItanium|Win32
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.ReleaseItanium.Build.0 = ReleaseItanium|Win32
+		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug.ActiveCfg = Debug|Win32
+		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug.Build.0 = Debug|Win32
+		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release.ActiveCfg = Release|Win32
+		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release.Build.0 = Release|Win32
+		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.ReleaseAMD64.ActiveCfg = ReleaseAMD64|Win32
+		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.ReleaseAMD64.Build.0 = ReleaseAMD64|Win32
+		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.ReleaseItanium.ActiveCfg = ReleaseItanium|Win32
+		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.ReleaseItanium.Build.0 = ReleaseItanium|Win32
+		{97239A56-DBC0-41D2-BC14-C87D9B97D63B}.Debug.ActiveCfg = Debug|Win32
+		{97239A56-DBC0-41D2-BC14-C87D9B97D63B}.Debug.Build.0 = Debug|Win32
+		{97239A56-DBC0-41D2-BC14-C87D9B97D63B}.Release.ActiveCfg = Release|Win32
+		{97239A56-DBC0-41D2-BC14-C87D9B97D63B}.Release.Build.0 = Release|Win32
+		{97239A56-DBC0-41D2-BC14-C87D9B97D63B}.ReleaseAMD64.ActiveCfg = ReleaseAMD64|Win32
+		{97239A56-DBC0-41D2-BC14-C87D9B97D63B}.ReleaseAMD64.Build.0 = ReleaseAMD64|Win32
+		{97239A56-DBC0-41D2-BC14-C87D9B97D63B}.ReleaseItanium.ActiveCfg = ReleaseItanium|Win32
+		{97239A56-DBC0-41D2-BC14-C87D9B97D63B}.ReleaseItanium.Build.0 = ReleaseItanium|Win32
+		{FA5FC7EB-C72F-415F-AE42-91DD605ABDDA}.Debug.ActiveCfg = Debug|Win32
+		{FA5FC7EB-C72F-415F-AE42-91DD605ABDDA}.Debug.Build.0 = Debug|Win32
+		{FA5FC7EB-C72F-415F-AE42-91DD605ABDDA}.Release.ActiveCfg = Release|Win32
+		{FA5FC7EB-C72F-415F-AE42-91DD605ABDDA}.Release.Build.0 = Release|Win32
+		{FA5FC7EB-C72F-415F-AE42-91DD605ABDDA}.ReleaseAMD64.ActiveCfg = ReleaseAMD64|Win32
+		{FA5FC7EB-C72F-415F-AE42-91DD605ABDDA}.ReleaseAMD64.Build.0 = ReleaseAMD64|Win32
+		{FA5FC7EB-C72F-415F-AE42-91DD605ABDDA}.ReleaseItanium.ActiveCfg = ReleaseItanium|Win32
+		{FA5FC7EB-C72F-415F-AE42-91DD605ABDDA}.ReleaseItanium.Build.0 = ReleaseItanium|Win32
+		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.Debug.ActiveCfg = Debug|Win32
+		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.Debug.Build.0 = Debug|Win32
+		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.Release.ActiveCfg = Release|Win32
+		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.Release.Build.0 = Release|Win32
+		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.ReleaseAMD64.ActiveCfg = Release|Win32
+		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.ReleaseItanium.ActiveCfg = Release|Win32
+		{51F35FAE-FB92-4B2C-9187-1542C065AD77}.Debug.ActiveCfg = Debug|Win32
+		{51F35FAE-FB92-4B2C-9187-1542C065AD77}.Debug.Build.0 = Debug|Win32
+		{51F35FAE-FB92-4B2C-9187-1542C065AD77}.Release.ActiveCfg = Release|Win32
+		{51F35FAE-FB92-4B2C-9187-1542C065AD77}.Release.Build.0 = Release|Win32
+		{51F35FAE-FB92-4B2C-9187-1542C065AD77}.ReleaseAMD64.ActiveCfg = ReleaseAMD64|Win32
+		{51F35FAE-FB92-4B2C-9187-1542C065AD77}.ReleaseAMD64.Build.0 = ReleaseAMD64|Win32
+		{51F35FAE-FB92-4B2C-9187-1542C065AD77}.ReleaseItanium.ActiveCfg = ReleaseItanium|Win32
+		{51F35FAE-FB92-4B2C-9187-1542C065AD77}.ReleaseItanium.Build.0 = ReleaseItanium|Win32
+		{1966DDE2-4AB7-4E4E-ACC9-C121E4D37F8E}.Debug.ActiveCfg = Debug|Win32
+		{1966DDE2-4AB7-4E4E-ACC9-C121E4D37F8E}.Debug.Build.0 = Debug|Win32
+		{1966DDE2-4AB7-4E4E-ACC9-C121E4D37F8E}.Release.ActiveCfg = Release|Win32
+		{1966DDE2-4AB7-4E4E-ACC9-C121E4D37F8E}.Release.Build.0 = Release|Win32
+		{1966DDE2-4AB7-4E4E-ACC9-C121E4D37F8E}.ReleaseAMD64.ActiveCfg = ReleaseAMD64|Win32
+		{1966DDE2-4AB7-4E4E-ACC9-C121E4D37F8E}.ReleaseAMD64.Build.0 = ReleaseAMD64|Win32
+		{1966DDE2-4AB7-4E4E-ACC9-C121E4D37F8E}.ReleaseItanium.ActiveCfg = ReleaseItanium|Win32
+		{1966DDE2-4AB7-4E4E-ACC9-C121E4D37F8E}.ReleaseItanium.Build.0 = ReleaseItanium|Win32
+		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.Debug.ActiveCfg = Debug|Win32
+		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.Debug.Build.0 = Debug|Win32
+		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.Release.ActiveCfg = Release|Win32
+		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.Release.Build.0 = Release|Win32
+		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.ReleaseAMD64.ActiveCfg = Release|Win32
+		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.ReleaseAMD64.Build.0 = Release|Win32
+		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.ReleaseItanium.ActiveCfg = Release|Win32
+		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.ReleaseItanium.Build.0 = Release|Win32
+		{2C0BEFB9-70E2-4F80-AC5B-4AB8EE023574}.Debug.ActiveCfg = Debug|Win32
+		{2C0BEFB9-70E2-4F80-AC5B-4AB8EE023574}.Debug.Build.0 = Debug|Win32
+		{2C0BEFB9-70E2-4F80-AC5B-4AB8EE023574}.Release.ActiveCfg = Release|Win32
+		{2C0BEFB9-70E2-4F80-AC5B-4AB8EE023574}.Release.Build.0 = Release|Win32
+		{2C0BEFB9-70E2-4F80-AC5B-4AB8EE023574}.ReleaseAMD64.ActiveCfg = ReleaseAMD64|Win32
+		{2C0BEFB9-70E2-4F80-AC5B-4AB8EE023574}.ReleaseAMD64.Build.0 = ReleaseAMD64|Win32
+		{2C0BEFB9-70E2-4F80-AC5B-4AB8EE023574}.ReleaseItanium.ActiveCfg = ReleaseItanium|Win32
+		{2C0BEFB9-70E2-4F80-AC5B-4AB8EE023574}.ReleaseItanium.Build.0 = ReleaseItanium|Win32
+		{F22F40F4-D318-40DC-96B3-88DC81CE0894}.Debug.ActiveCfg = Debug|Win32
+		{F22F40F4-D318-40DC-96B3-88DC81CE0894}.Debug.Build.0 = Debug|Win32
+		{F22F40F4-D318-40DC-96B3-88DC81CE0894}.Release.ActiveCfg = Release|Win32
+		{F22F40F4-D318-40DC-96B3-88DC81CE0894}.Release.Build.0 = Release|Win32
+		{F22F40F4-D318-40DC-96B3-88DC81CE0894}.ReleaseAMD64.ActiveCfg = ReleaseAMD64|Win32
+		{F22F40F4-D318-40DC-96B3-88DC81CE0894}.ReleaseItanium.ActiveCfg = ReleaseItanium|Win32
+		{8CF334D9-4F82-42EB-97AF-83592C5AFD2F}.Debug.ActiveCfg = Debug|Win32
+		{8CF334D9-4F82-42EB-97AF-83592C5AFD2F}.Debug.Build.0 = Debug|Win32
+		{8CF334D9-4F82-42EB-97AF-83592C5AFD2F}.Release.ActiveCfg = Release|Win32
+		{8CF334D9-4F82-42EB-97AF-83592C5AFD2F}.Release.Build.0 = Release|Win32
+		{8CF334D9-4F82-42EB-97AF-83592C5AFD2F}.ReleaseAMD64.ActiveCfg = ReleaseAMD64|Win32
+		{8CF334D9-4F82-42EB-97AF-83592C5AFD2F}.ReleaseItanium.ActiveCfg = ReleaseItanium|Win32
+		{2FF0A312-22F9-4C34-B070-842916DE27A9}.Debug.ActiveCfg = Debug|Win32
+		{2FF0A312-22F9-4C34-B070-842916DE27A9}.Debug.Build.0 = Debug|Win32
+		{2FF0A312-22F9-4C34-B070-842916DE27A9}.Release.ActiveCfg = Release|Win32
+		{2FF0A312-22F9-4C34-B070-842916DE27A9}.Release.Build.0 = Release|Win32
+		{2FF0A312-22F9-4C34-B070-842916DE27A9}.ReleaseAMD64.ActiveCfg = ReleaseAMD64|Win32
+		{2FF0A312-22F9-4C34-B070-842916DE27A9}.ReleaseAMD64.Build.0 = ReleaseAMD64|Win32
+		{2FF0A312-22F9-4C34-B070-842916DE27A9}.ReleaseItanium.ActiveCfg = ReleaseItanium|Win32
+		{2FF0A312-22F9-4C34-B070-842916DE27A9}.ReleaseItanium.Build.0 = ReleaseItanium|Win32
+	EndGlobalSection
+	GlobalSection(SolutionItems) = postSolution
+		..\Modules\getbuildinfo.c = ..\Modules\getbuildinfo.c
+		readme.txt = readme.txt
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+	EndGlobalSection
+	GlobalSection(ExtensibilityAddIns) = postSolution
+	EndGlobalSection
+EndGlobal

Added: vendor/Python/current/PCbuild/pyexpat.vcproj
===================================================================
--- vendor/Python/current/PCbuild/pyexpat.vcproj	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild/pyexpat.vcproj	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,263 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="pyexpat"
+	SccProjectName="pyexpat"
+	SccLocalPath="..">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-debug\pyexpat"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\Include,..\PC,..\Modules\expat"
+				PreprocessorDefinitions="_DEBUG;HAVE_EXPAT_H;WIN32;_WINDOWS;XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;XML_STATIC;HAVE_MEMMOVE"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="odbccp32.lib"
+				OutputFile="./pyexpat_d.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./pyexpat_d.pdb"
+				SubSystem="2"
+				BaseAddress="0x1D100000"
+				ImportLibrary=".\./pyexpat_d.lib"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-release\pyexpat"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC,..\Modules\expat"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;XML_STATIC;HAVE_MEMMOVE"
+				StringPooling="TRUE"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="odbccp32.lib"
+				OutputFile="./pyexpat.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./pyexpat.pdb"
+				SubSystem="2"
+				BaseAddress="0x1D100000"
+				ImportLibrary=".\./pyexpat.lib"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseItanium|Win32"
+			OutputDirectory="./."
+			IntermediateDirectory=".\ia64-temp-release\pyexpat"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions=" /USECL:MS_ITANIUM /GS-"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC,..\Modules\expat"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;XML_STATIC;HAVE_MEMMOVE"
+				StringPooling="TRUE"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="FALSE"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions=" /MACHINE:IA64 /USELINK:MS_SDK"
+				AdditionalDependencies="odbccp32.lib"
+				OutputFile="./pyexpat.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./pyexpat.pdb"
+				SubSystem="2"
+				BaseAddress="0x1D100000"
+				ImportLibrary=".\./pyexpat.lib"
+				TargetMachine="0"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseAMD64|Win32"
+			OutputDirectory="."
+			IntermediateDirectory="amd64-temp-release\pyexpat"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions=" /USECL:MS_OPTERON  /GS-"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC,..\Modules\expat"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;XML_STATIC;HAVE_MEMMOVE"
+				StringPooling="TRUE"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="FALSE"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions=" /MACHINE:AMD64 /USELINK:MS_SDK"
+				AdditionalDependencies="odbccp32.lib"
+				OutputFile="./pyexpat.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./pyexpat.pdb"
+				SubSystem="2"
+				BaseAddress="0x1D100000"
+				ImportLibrary=".\./pyexpat.lib"
+				TargetMachine="0"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath="..\Modules\pyexpat.c">
+		</File>
+		<File
+			RelativePath="..\Modules\expat\xmlparse.c">
+		</File>
+		<File
+			RelativePath="..\Modules\expat\xmlrole.c">
+		</File>
+		<File
+			RelativePath="..\Modules\expat\xmltok.c">
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Added: vendor/Python/current/PCbuild/python.build
===================================================================
--- vendor/Python/current/PCbuild/python.build	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild/python.build	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<project>
+ <target name="all" description="Build all targets.">
+   <solution configuration="release">
+     <projects>
+       <include name="make_versioninfo.vcproj" />
+     </projects>
+   </solution>
+   <exec program="make_versioninfo" output="pythonnt_rc.h" />
+
+   <solution configuration="release" solutionfile="pcbuild.sln">
+     <excludeprojects>
+       <include name="_tkinter.vcproj" />
+       <include name="bz2.vcproj" />
+       <include name="_bsddb.vcproj" />
+       <include name="_sqlite3.vcproj" />
+       <include name="_ssl.vcproj" />
+     </excludeprojects>
+   </solution>
+ </target>
+</project>

Added: vendor/Python/current/PCbuild/python.iss
===================================================================
--- vendor/Python/current/PCbuild/python.iss	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild/python.iss	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,346 @@
+; Script generated by the Inno Setup Script Wizard.
+; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
+
+; This is the whole ball of wax for an Inno installer for Python.
+; To use, download Inno Setup from http://www.jrsoftware.org/isdl.htm/,
+; install it, and double-click on this file.  That launches the Inno
+; script compiler.  The GUI is extemely simple, and has only one button
+; you may not recognize instantly:  click it.  You're done.  It builds
+; the installer into PCBuild/Python-2.2a1.exe.  Size and speed of the
+; installer are competitive with the Wise installer; Inno uninstall
+; seems much quicker than Wise (but also feebler, and the uninstall
+; log is in some un(human)readable binary format).
+;
+; What's Done
+; -----------
+; All the usual Windows Python files are installed by this now.
+; All the usual Windows Python Start menu entries are created and
+; work fine.
+; .py, .pyw, .pyc and .pyo extensions are registered.
+;     PROBLEM:  Inno uninstall does not restore their previous registry
+;               associations (if any).  Wise did.  This will make life
+;               difficult for alpha (etc) testers.
+; The Python install is fully functional for "typical" uses.
+;
+; What's Not Done
+; ---------------
+; None of "Mark Hammond's" registry entries are written.
+; No installation of files is done into the system dir:
+;     The MS DLLs aren't handled at all by this yet.
+;     Python22.dll is unpacked into the main Python dir.
+;
+; Inno can't do different things on NT/2000 depending on whether the user
+; has Admin privileges, so I don't know how to "solve" either of those,
+; short of building two installers (one *requiring* Admin privs, the
+; other not doing anything that needs Admin privs).
+;
+; Inno has no concept of variables, so lots of lines in this file need
+; to be fiddled by hand across releases.  Simplest way out:  stick this
+; file in a giant triple-quoted r-string (note that backslashes are
+; required all over the place here -- forward slashes DON'T WORK in
+; Inno), and use %(yadda)s string interpolation to do substitutions; i.e.,
+; write a very simple Python program to *produce* this script.
+
+[Setup]
+AppName=Python and combined Win32 Extensions
+AppVerName=Python 2.2.2 and combined Win32 Extensions 150
+AppId=Python 2.2.2.150
+AppVersion=2.2.2.150
+AppCopyright=Python is Copyright © 2001 Python Software Foundation. Win32 Extensions are Copyright © 1996-2001 Greg Stein and Mark Hammond.
+
+; Default install dir; value of {app} later (unless user overrides).
+; {sd} = system root drive, probably "C:".
+DefaultDirName={sd}\Python22
+;DefaultDirName={pf}\Python
+
+; Start menu folder name; value of {group} later (unless user overrides).
+DefaultGroupName=Python 2.2
+
+; Point SourceDir to one above PCBuild = src.
+; means this script can run unchanged from anyone's CVS tree, no matter
+; what they called the top-level directories.
+SourceDir=.
+OutputDir=..
+OutputBaseFilename=Python-2.2.2-Win32-150-Setup
+
+AppPublisher=PythonLabs at Digital Creations
+AppPublisherURL=http://www.python.org
+AppSupportURL=http://www.python.org
+AppUpdatesURL=http://www.python.org
+
+AlwaysCreateUninstallIcon=true
+ChangesAssociations=true
+UninstallLogMode=new
+AllowNoIcons=true
+AdminPrivilegesRequired=true
+UninstallDisplayIcon={app}\pyc.ico
+WizardDebug=false
+
+; The fewer screens the better; leave these commented.
+
+Compression=bzip
+InfoBeforeFile=LICENSE.txt
+;InfoBeforeFile=Misc\NEWS
+
+; uncomment the following line if you want your installation to run on NT 3.51 too.
+; MinVersion=4,3.51
+
+[Types]
+Name: normal; Description: Select desired components; Flags: iscustom
+
+[Components]
+Name: main; Description: Python and Win32 Extensions; Types: normal
+Name: docs; Description: Python documentation (HTML); Types: normal
+Name: tk; Description: TCL/TK, tkinter, and Idle; Types: normal
+Name: tools; Description: Python utility scripts (Tools\); Types: normal
+Name: test; Description: Python test suite (Lib\test\); Types: normal
+
+[Tasks]
+Name: extensions; Description: Register file associations (.py, .pyw, .pyc, .pyo); Components: main; Check: IsAdminLoggedOn
+
+[Files]
+; Caution:  Using forward slashes instead screws up in amazing ways.
+; Unknown:  By the time Components (and other attrs) are added to these lines, they're
+; going to get awfully long.  But don't see a way to continue logical lines across
+; physical lines.
+
+Source: LICENSE.txt; DestDir: {app}; CopyMode: alwaysoverwrite
+Source: README.txt; DestDir: {app}; CopyMode: alwaysoverwrite
+Source: News.txt; DestDir: {app}; CopyMode: alwaysoverwrite
+Source: *.ico; DestDir: {app}; CopyMode: alwaysoverwrite; Components: main
+
+Source: python.exe; DestDir: {app}; CopyMode: alwaysoverwrite; Components: main
+Source: pythonw.exe; DestDir: {app}; CopyMode: alwaysoverwrite; Components: main
+Source: w9xpopen.exe; DestDir: {app}; CopyMode: alwaysoverwrite; Components: main
+
+
+Source: DLLs\tcl83.dll; DestDir: {app}\DLLs; CopyMode: alwaysoverwrite; Components: tk
+Source: DLLs\tk83.dll; DestDir: {app}\DLLs; CopyMode: alwaysoverwrite; Components: tk
+Source: tcl\*.*; DestDir: {app}\tcl; CopyMode: alwaysoverwrite; Components: tk; Flags: recursesubdirs
+
+Source: sysdir\python22.dll; DestDir: {sys}; CopyMode: alwaysskipifsameorolder; Components: main; Flags: sharedfile restartreplace
+Source: sysdir\PyWinTypes22.dll; DestDir: {sys}; CopyMode: alwaysskipifsameorolder; Components: main; Flags: restartreplace sharedfile
+Source: sysdir\pythoncom22.dll; DestDir: {sys}; CopyMode: alwaysskipifsameorolder; Components: main; Flags: restartreplace sharedfile
+
+Source: DLLs\_socket.pyd; DestDir: {app}\DLLs; CopyMode: alwaysoverwrite; Components: main
+Source: libs\_socket.lib; DestDir: {app}\libs; CopyMode: alwaysoverwrite; Components: main
+
+Source: DLLs\_sre.pyd; DestDir: {app}\DLLs; CopyMode: alwaysoverwrite; Components: main
+Source: libs\_sre.lib; DestDir: {app}\libs; CopyMode: alwaysoverwrite; Components: main
+
+Source: DLLs\_symtable.pyd; DestDir: {app}\DLLs; CopyMode: alwaysoverwrite; Components: main
+Source: libs\_symtable.lib; DestDir: {app}\libs; CopyMode: alwaysoverwrite; Components: main
+
+Source: DLLs\_testcapi.pyd; DestDir: {app}\DLLs; CopyMode: alwaysoverwrite; Components: main
+Source: libs\_testcapi.lib; DestDir: {app}\libs; CopyMode: alwaysoverwrite; Components: main
+
+Source: DLLs\_tkinter.pyd; DestDir: {app}\DLLs; CopyMode: alwaysoverwrite; Components: tk
+Source: libs\_tkinter.lib; DestDir: {app}\libs; CopyMode: alwaysoverwrite; Components: tk
+
+Source: DLLs\bsddb.pyd; DestDir: {app}\DLLs; CopyMode: alwaysoverwrite; Components: main
+Source: libs\bsddb.lib; DestDir: {app}\libs; CopyMode: alwaysoverwrite; Components: main
+
+Source: DLLs\mmap.pyd; DestDir: {app}\DLLs; CopyMode: alwaysoverwrite; Components: main
+Source: libs\mmap.lib; DestDir: {app}\libs; CopyMode: alwaysoverwrite; Components: main
+
+Source: DLLs\parser.pyd; DestDir: {app}\DLLs; CopyMode: alwaysoverwrite; Components: main
+Source: libs\parser.lib; DestDir: {app}\libs; CopyMode: alwaysoverwrite; Components: main
+
+Source: DLLs\pyexpat.pyd; DestDir: {app}\DLLs; CopyMode: alwaysoverwrite; Components: main
+Source: libs\pyexpat.lib; DestDir: {app}\libs; CopyMode: alwaysoverwrite; Components: main
+
+Source: DLLs\select.pyd; DestDir: {app}\DLLs; CopyMode: alwaysoverwrite; Components: main
+Source: libs\select.lib; DestDir: {app}\libs; CopyMode: alwaysoverwrite; Components: main
+
+Source: DLLs\unicodedata.pyd; DestDir: {app}\DLLs; CopyMode: alwaysoverwrite; Components: main
+Source: libs\unicodedata.lib; DestDir: {app}\libs; CopyMode: alwaysoverwrite; Components: main
+
+Source: DLLs\_winreg.pyd; DestDir: {app}\DLLs; CopyMode: alwaysoverwrite; Components: main
+Source: libs\_winreg.lib; DestDir: {app}\libs; CopyMode: alwaysoverwrite; Components: main
+
+Source: DLLs\winsound.pyd; DestDir: {app}\DLLs; CopyMode: alwaysoverwrite; Components: main
+Source: libs\winsound.lib; DestDir: {app}\libs; CopyMode: alwaysoverwrite; Components: main
+
+Source: DLLs\zlib.pyd; DestDir: {app}\DLLs; CopyMode: alwaysoverwrite; Components: main
+Source: libs\zlib.lib; DestDir: {app}\libs; CopyMode: alwaysoverwrite; Components: main
+
+Source: libs\python22.lib; DestDir: {app}\libs; CopyMode: alwaysoverwrite; Components: main
+
+Source: DLLs\expat.dll; DestDir: {app}\DLLs; CopyMode: alwaysoverwrite; Components: main
+
+
+
+Source: Lib\*.py; DestDir: {app}\Lib; CopyMode: alwaysoverwrite; Components: main
+Source: Lib\compiler\*.*; DestDir: {app}\Lib\compiler; CopyMode: alwaysoverwrite; Components: main; Flags: recursesubdirs
+Source: Lib\distutils\*.*; DestDir: {app}\Lib\distutils; CopyMode: alwaysoverwrite; Components: main; Flags: recursesubdirs
+Source: Lib\email\*.*; DestDir: {app}\Lib\email; CopyMode: alwaysoverwrite; Components: main; Flags: recursesubdirs
+Source: Lib\encodings\*.*; DestDir: {app}\Lib\encodings; CopyMode: alwaysoverwrite; Components: main; Flags: recursesubdirs
+Source: Lib\hotshot\*.*; DestDir: {app}\Lib\hotshot; CopyMode: alwaysoverwrite; Components: main; Flags: recursesubdirs
+Source: Lib\lib-old\*.*; DestDir: {app}\Lib\lib-old; CopyMode: alwaysoverwrite; Components: main; Flags: recursesubdirs
+Source: Lib\xml\*.*; DestDir: {app}\Lib\xml; CopyMode: alwaysoverwrite; Components: main; Flags: recursesubdirs
+Source: Lib\hotshot\*.*; DestDir: {app}\Lib\hotshot; CopyMode: alwaysoverwrite; Components: main; Flags: recursesubdirs
+Source: Lib\test\*.*; DestDir: {app}\Lib\test; CopyMode: alwaysoverwrite; Components: test; Flags: recursesubdirs
+
+Source: Lib\site-packages\README.txt; DestDir: {app}\Lib\site-packages; CopyMode: alwaysoverwrite; Components: main
+
+Source: Lib\site-packages\PyWin32.chm; DestDir: {app}\Lib\site-packages; CopyMode: alwaysoverwrite; Components: docs
+Source: Lib\site-packages\win32\*.*; DestDir: {app}\Lib\site-packages\win32; CopyMode: alwaysoverwrite; Components: main; Flags: recursesubdirs
+Source: Lib\site-packages\win32com\*.*; DestDir: {app}\Lib\site-packages\win32com; CopyMode: alwaysoverwrite; Components: main; Flags: recursesubdirs
+Source: Lib\site-packages\win32comext\*.*; DestDir: {app}\Lib\site-packages\win32comext; CopyMode: alwaysoverwrite; Components: main; Flags: recursesubdirs
+
+Source: Lib\lib-tk\*.py; DestDir: {app}\Lib\lib-tk; CopyMode: alwaysoverwrite; Components: tk; Flags: recursesubdirs
+
+Source: include\*.h; DestDir: {app}\include; CopyMode: alwaysoverwrite; Components: main
+
+Source: Tools\idle\*.*; DestDir: {app}\Tools\idle; CopyMode: alwaysoverwrite; Components: tk; Flags: recursesubdirs
+
+Source: Tools\pynche\*.*; DestDir: {app}\Tools\pynche; CopyMode: alwaysoverwrite; Components: tools; Flags: recursesubdirs
+Source: Tools\scripts\*.*; DestDir: {app}\Tools\Scripts; CopyMode: alwaysoverwrite; Components: tools; Flags: recursesubdirs
+Source: Tools\webchecker\*.*; DestDir: {app}\Tools\webchecker; CopyMode: alwaysoverwrite; Components: tools; Flags: recursesubdirs
+Source: Tools\versioncheck\*.*; DestDir: {app}\Tools\versioncheck; CopyMode: alwaysoverwrite; Components: tools; Flags: recursesubdirs
+
+Source: Doc\*.*; DestDir: {app}\Doc; CopyMode: alwaysoverwrite; Flags: recursesubdirs; Components: docs
+
+
+[Icons]
+Name: {group}\Python (command line); Filename: {app}\python.exe; WorkingDir: {app}; Components: main
+Name: {group}\Python Manuals; Filename: {app}\Doc\index.html; WorkingDir: {app}; Components: docs
+Name: {group}\Win32 Extensions Help; Filename: {app}\Lib\site-packages\PyWin32.chm; WorkingDir: {app}\Lib\site-packages; Components: docs
+Name: {group}\Module Docs; Filename: {app}\pythonw.exe; WorkingDir: {app}; Parameters: """{app}\Tools\Scripts\pydoc.pyw"""; Components: tools
+Name: {group}\IDLE (Python GUI); Filename: {app}\pythonw.exe; WorkingDir: {app}; Parameters: """{app}\Tools\idle\idle.pyw"""; Components: tools
+
+[Registry]
+; Register .py
+Tasks: extensions; Root: HKCR; Subkey: .py; ValueType: string; ValueName: ; ValueData: Python File; Flags: uninsdeletevalue
+Tasks: extensions; Root: HKCR; Subkey: .py; ValueType: string; ValueName: Content Type; ValueData: text/plain; Flags: uninsdeletevalue
+Tasks: extensions; Root: HKCR; Subkey: Python File; ValueType: string; ValueName: ; ValueData: Python File; Flags: uninsdeletekey
+Tasks: extensions; Root: HKCR; Subkey: Python File\DefaultIcon; ValueType: string; ValueName: ; ValueData: {app}\Py.ico
+Tasks: extensions; Root: HKCR; Subkey: Python File\shell\open\command; ValueType: string; ValueName: ; ValueData: """{app}\python.exe"" ""%1"" %*"
+
+; Register .pyc
+Tasks: extensions; Root: HKCR; Subkey: .pyc; ValueType: string; ValueName: ; ValueData: Python CompiledFile; Flags: uninsdeletevalue
+Tasks: extensions; Root: HKCR; Subkey: Python CompiledFile; ValueType: string; ValueName: ; ValueData: Compiled Python File; Flags: uninsdeletekey
+Tasks: extensions; Root: HKCR; Subkey: Python CompiledFile\DefaultIcon; ValueType: string; ValueName: ; ValueData: {app}\pyc.ico
+Tasks: extensions; Root: HKCR; Subkey: Python CompiledFile\shell\open\command; ValueType: string; ValueName: ; ValueData: """{app}\python.exe"" ""%1"" %*"
+
+; Register .pyo
+Tasks: extensions; Root: HKCR; Subkey: .pyo; ValueType: string; ValueName: ; ValueData: Python CompiledFile; Flags: uninsdeletevalue
+
+; Register .pyw
+Tasks: extensions; Root: HKCR; Subkey: .pyw; ValueType: string; ValueName: ; ValueData: Python NoConFile; Flags: uninsdeletevalue
+Tasks: extensions; Root: HKCR; Subkey: .pyw; ValueType: string; ValueName: Content Type; ValueData: text/plain; Flags: uninsdeletevalue
+Tasks: extensions; Root: HKCR; Subkey: Python NoConFile; ValueType: string; ValueName: ; ValueData: Python File (no console); Flags: uninsdeletekey
+Tasks: extensions; Root: HKCR; Subkey: Python NoConFile\DefaultIcon; ValueType: string; ValueName: ; ValueData: {app}\Py.ico
+Tasks: extensions; Root: HKCR; Subkey: Python NoConFile\shell\open\command; ValueType: string; ValueName: ; ValueData: """{app}\pythonw.exe"" ""%1"" %*"
+
+
+; Python Registry Keys
+Root: HKLM; Subkey: SOFTWARE\Python; Flags: uninsdeletekeyifempty; Check: IsAdminLoggedOn
+Root: HKLM; Subkey: SOFTWARE\Python\PythonCore; Flags: uninsdeletekeyifempty
+Root: HKLM; Subkey: SOFTWARE\Python\PythonCore\2.2; Flags: uninsdeletekeyifempty
+Root: HKLM; Subkey: SOFTWARE\Python\PythonCore\2.2\PythonPath; ValueData: "{app}\Lib;{app}\DLLs"; Flags: uninsdeletekeyifempty
+Root: HKLM; Subkey: SOFTWARE\Python\PythonCore\2.2\PythonPath\tk; ValueData: {app}\Lib\lib-tk; Flags: uninsdeletekey; Components: tk
+Root: HKLM; Subkey: SOFTWARE\Python\PythonCore\2.2\PythonPath\win32; ValueData: "{app}\lib\site-packages\win32;{app}\lib\site-packages\win32\lib"; Flags: uninsdeletekey
+Root: HKLM; Subkey: SOFTWARE\Python\PythonCore\2.2\PythonPath\win32com; ValueData: C:\Python\lib\site-packages; Flags: uninsdeletekey
+Root: HKLM; Subkey: SOFTWARE\Python\PythonCore\2.2\Modules; Flags: uninsdeletekeyifempty
+Root: HKLM; Subkey: SOFTWARE\Python\PythonCore\2.2\Modules\pythoncom; ValueData: {sys}\pythoncom22.dll; Flags: uninsdeletekey
+Root: HKLM; Subkey: SOFTWARE\Python\PythonCore\2.2\Modules\pywintypes; ValueData: {sys}\PyWinTypes22.dll; Flags: uninsdeletekey
+Root: HKLM; Subkey: SOFTWARE\Python\PythonCore\2.2\InstallPath; ValueData: {app}; Flags: uninsdeletekeyifempty; ValueType: string
+Root: HKLM; Subkey: SOFTWARE\Python\PythonCore\2.2\InstallPath\InstallGroup; ValueData: {group}; Flags: uninsdeletekey
+Root: HKLM; Subkey: SOFTWARE\Python\PythonCore\2.2\Help; Flags: uninsdeletekeyifempty
+Root: HKLM; Subkey: SOFTWARE\Python\PythonCore\2.2\Help\Main Python Documentation; ValueType: string; ValueData: {app}\Doc\index.html; Flags: uninsdeletekey; Components: docs
+Root: HKLM; Subkey: SOFTWARE\Python\PythonCore\2.2\Help\Python Win32 Documentation; ValueType: string; ValueData: {app}\lib\site-packages\PyWin32.chm; Flags: uninsdeletekey; Components: docs
+
+[_ISTool]
+EnableISX=true
+
+
+[Code]
+Program Setup;
+
+Function IsAdminNotLoggedOn(): Boolean;
+begin
+  Result := Not IsAdminLoggedOn();
+end;
+
+begin
+end.
+
+
+
+
+[UninstallDelete]
+Name: {app}\Lib\compiler\*.pyc; Type: files
+Name: {app}\Lib\compiler\*.pyo; Type: files
+Name: {app}\Lib\compiler; Type: dirifempty
+Name: {app}\Lib\distutils\command\*.pyc; Type: files
+Name: {app}\Lib\distutils\command\*.pyo; Type: files
+Name: {app}\Lib\distutils\command; Type: dirifempty
+Name: {app}\Lib\distutils\*.pyc; Type: files
+Name: {app}\Lib\distutils\*.pyo; Type: files
+Name: {app}\Lib\distutils; Type: dirifempty
+Name: {app}\Lib\email\test\*.pyc; Type: files
+Name: {app}\Lib\email\test\*.pyo; Type: files
+Name: {app}\Lib\email\test; Type: dirifempty
+Name: {app}\Lib\email\*.pyc; Type: files
+Name: {app}\Lib\email\*.pyo; Type: files
+Name: {app}\Lib\email; Type: dirifempty
+Name: {app}\Lib\encodings\*.pyc; Type: files
+Name: {app}\Lib\encodings\*.pyo; Type: files
+Name: {app}\Lib\encodings; Type: dirifempty
+Name: {app}\Lib\hotshot\*.pyc; Type: files
+Name: {app}\Lib\hotshot\*.pyo; Type: files
+Name: {app}\Lib\hotshot; Type: dirifempty
+Name: {app}\Lib\lib-old\*.pyc; Type: files
+Name: {app}\Lib\lib-old\*.pyo; Type: files
+Name: {app}\Lib\lib-old; Type: dirifempty
+Name: {app}\Lib\lib-tk\*.pyc; Type: files
+Name: {app}\Lib\lib-tk\*.pyo; Type: files
+Name: {app}\Lib\lib-tk; Type: dirifempty
+Name: {app}\Lib\test\*.pyc; Type: files
+Name: {app}\Lib\test\*.pyo; Type: files
+Name: {app}\Lib\test; Type: dirifempty
+Name: {app}\Lib\xml\dom\*.pyc; Type: files
+Name: {app}\Lib\xml\dom\*.pyo; Type: files
+Name: {app}\Lib\xml\dom; Type: dirifempty
+Name: {app}\Lib\xml\parsers\*.pyc; Type: files
+Name: {app}\Lib\xml\parsers\*.pyo; Type: files
+Name: {app}\Lib\xml\parsers; Type: dirifempty
+Name: {app}\Lib\xml\sax\*.pyc; Type: files
+Name: {app}\Lib\xml\sax\*.pyo; Type: files
+Name: {app}\Lib\xml\sax; Type: dirifempty
+Name: {app}\Lib\xml\*.pyc; Type: files
+Name: {app}\Lib\xml\*.pyo; Type: files
+Name: {app}\Lib\xml; Type: dirifempty
+
+Name: {app}\Lib\site-packages\win32; Type: filesandordirs
+Name: {app}\Lib\site-packages\win32com; Type: filesandordirs
+Name: {app}\Lib\site-packages\win32comext; Type: filesandordirs
+Name: {app}\Lib\site-packages\pythoncom.py*; Type: files
+Name: {app}\Lib\site-packages; Type: dirifempty
+
+Name: {app}\Lib\*.pyc; Type: files
+Name: {app}\Lib; Type: dirifempty
+
+Name: {app}\Tools\pynche\*.pyc; Type: files
+Name: {app}\Tools\pynche\*.pyo; Type: files
+Name: {app}\Tools\pynche; Type: dirifempty
+
+Name: {app}\Tools\idle\*.pyc; Type: files
+Name: {app}\Tools\idle\*.pyo; Type: files
+Name: {app}\Tools\idle; Type: dirifempty
+
+Name: {app}\Tools\scripts\*.pyc; Type: files
+Name: {app}\Tools\scripts\*.pyo; Type: files
+Name: {app}\Tools\scripts; Type: dirifempty
+
+Name: {app}\Tools\versioncheck\*.pyc; Type: files
+Name: {app}\Tools\versioncheck\*.pyo; Type: files
+Name: {app}\Tools\versioncheck; Type: dirifempty
+
+Name: {app}\Tools\webchecker\*.pyc; Type: files
+Name: {app}\Tools\webchecker\*.pyo; Type: files
+Name: {app}\Tools\webchecker; Type: dirifempty
+
+Name: {app}\Tools; Type: dirifempty
+

Added: vendor/Python/current/PCbuild/python.vcproj
===================================================================
--- vendor/Python/current/PCbuild/python.vcproj	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild/python.vcproj	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,274 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="python"
+	SccProjectName="python"
+	SccLocalPath="..">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-release\python"
+			ConfigurationType="1"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+				StringPooling="TRUE"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="odbccp32.lib"
+				OutputFile=".\./python.exe"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./python.pdb"
+				SubSystem="1"
+				StackReserveSize="2000000"
+				BaseAddress="0x1d000000"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-debug\python"
+			ConfigurationType="1"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="2"
+				BrowseInformation="1"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="odbccp32.lib"
+				OutputFile="./python_d.exe"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./python_d.pdb"
+				SubSystem="1"
+				StackReserveSize="2000000"
+				BaseAddress="0x1d000000"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="_DEBUG"
+				Culture="1033"
+				AdditionalIncludeDirectories="..\Include"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseItanium|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\ia64-temp-release\python"
+			ConfigurationType="1"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions=" /USECL:MS_ITANIUM  /GS-"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+				StringPooling="TRUE"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="FALSE"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions=" /MACHINE:IA64 /USELINK:MS_SDK /VSEXTCOMP_VERBOSE"
+				AdditionalDependencies="odbccp32.lib"
+				OutputFile=".\./python.exe"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./python.pdb"
+				SubSystem="1"
+				StackReserveSize="2000000"
+				BaseAddress="0x1d000000"
+				TargetMachine="0"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseAMD64|Win32"
+			OutputDirectory="."
+			IntermediateDirectory="amd64-temp-release\python"
+			ConfigurationType="1"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions=" /USECL:MS_OPTERON"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+				StringPooling="TRUE"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="FALSE"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions=" /MACHINE:AMD64 /USELINK:MS_SDK"
+				AdditionalDependencies="odbccp32.lib"
+				OutputFile=".\./python.exe"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./python.pdb"
+				SubSystem="1"
+				StackReserveSize="2000000"
+				BaseAddress="0x1d000000"
+				TargetMachine="0"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath="..\PC\pycon.ico">
+		</File>
+		<File
+			RelativePath="..\Modules\python.c">
+		</File>
+		<File
+			RelativePath="..\PC\python_exe.rc">
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Added: vendor/Python/current/PCbuild/python20.wse
===================================================================
--- vendor/Python/current/PCbuild/python20.wse	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild/python20.wse	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,3135 @@
+Document Type: WSE
+item: Global
+  Version=9.0
+  Title=Python 2.4a1
+  Flags=00010100
+  Languages=65 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+  Japanese Font Name=MS Gothic
+  Japanese Font Size=10
+  Start Gradient=0 255 0
+  End Gradient=0 128 0
+  Windows Flags=00000100000011010010010100001010
+  Log Pathname=%MAINDIR%\INSTALL.LOG
+  Message Font=MS Sans Serif
+  Font Size=8
+  Pages Modified=00010000011101000000000100000111
+  Extra Pages=00000000000000000000000010110010
+  Disk Filename=SETUP
+  Patch Flags=0000000000001001
+  Patch Threshold=85
+  Patch Memory=4000
+  MIF PDF Version=1.0
+  MIF SMS Version=2.0
+  EXE Filename=Python-2.4a1.exe
+  Dialogs Version=8
+  Version File=2.4a1
+  Version Description=Python Programming Language
+  Version Copyright=©2001-2007 Python Software Foundation
+  Version Company=Python Software Foundation
+  Crystal Format=10111100101100000010001001001001
+  Step View=&All
+  Variable Name1=_WISE_
+  Variable Description1=WISE root directory
+  Variable Default1=C:\Programme\Wise Installation System
+  Variable Flags1=00001000
+  Variable Name2=_TCLDIR_
+  Variable Description2=The directory in which the Tcl/Tk installation
+  Variable Description2=lives.  This must be a sibling of the Python
+  Variable Description2=directory.
+  Variable Default2=tcl84
+  Variable Flags2=00001000
+  Variable Name3=_DOC_
+  Variable Description3=The unpacked HTML doc directory.
+  Variable Default3=..\html
+  Variable Flags3=00001001
+  Variable Name4=_SYS_
+  Variable Description4=System directory (where to find MSVCRT.DLL)
+  Variable Default4=C:\Windows\System
+  Variable Values4=C:\Windows\System
+  Variable Values4=C:\WINNT\System32
+  Variable Values4=C:\Code\MSDLLs
+  Variable Values4=C:\Windows\System32
+  Variable Flags4=00000010
+  Variable Name5=_PYMAJOR_
+  Variable Description5=Python major version number; the 2 in 2.3.
+  Variable Default5=2
+  Variable Flags5=00001000
+  Variable Name6=_PYMINOR_
+  Variable Description6=Python minor version number; the 3 in 2.3
+  Variable Default6=3
+  Variable Flags6=00001000
+  Variable Name7=_DOADMIN_
+  Variable Description7=The initial value for %DOADMIN%.
+  Variable Description7=When 0, we never try to write under HKLM,
+  Variable Description7=and install the Python + MS runtime DLLs in
+  Variable Description7=the Python directory instead of the system dir.
+  Variable Default7=1
+  Variable Values7=1
+  Variable Values7=0
+  Variable Flags7=00001010
+  Variable Name8=_ALIASNAME_
+  Variable Flags8=00001000
+  Variable Name9=_ALIASPATH_
+  Variable Flags9=00001000
+  Variable Name10=_ALIASTYPE_
+  Variable Flags10=00001000
+end
+item: Set Variable
+  Variable=PYVER_STRING
+  Value=2.3
+end
+item: Remark
+end
+item: Remark
+  Text=When the version number changes, set the compiler
+end
+item: Remark
+  Text=vrbls _PYMAJOR_ and  _PYMINOR_.
+end
+item: Remark
+  Text=Nothing in the script below should need fiddling then.
+end
+item: Remark
+  Text=Other things that need fiddling:
+end
+item: Remark
+  Text=    PYVER_STRING above.
+end
+item: Remark
+  Text=    The "Title:" in the upper left corner of the GUI.
+end
+item: Remark
+  Text=    Build Settings and Version Resource on step 6 (Finish) of the Installation Expert
+end
+item: Remark
+  Text=        Be sure to select Steps->All or you may not see these!
+end
+item: Remark
+end
+item: Remark
+  Text=When the version of Tcl/Tk changes, the compiler vrbl
+end
+item: Remark
+  Text=_TCLDIR_ may also need to be changed.
+end
+item: Remark
+end
+item: Set Variable
+  Variable=APPTITLE
+  Value=Python %PYVER_STRING%
+end
+item: Remark
+  Text=PY_VERSION should be major.minor only; used to create the registry key; must match MS_DLL_ID in python_nt.rc
+end
+item: Set Variable
+  Variable=PY_VERSION
+  Value=%_PYMAJOR_%.%_PYMINOR_%
+end
+item: Remark
+  Text=GROUP is the Start menu group name; user can override.
+end
+item: Set Variable
+  Variable=GROUP
+  Value=Python %PY_VERSION%
+  Flags=10000000
+end
+item: Remark
+  Text=MAINDIR is the app directory; user can override.
+end
+item: Set Variable
+  Variable=MAINDIR
+  Value=Python%_PYMAJOR_%%_PYMINOR_%
+end
+item: Remark
+end
+item: Set Variable
+  Variable=DOADMIN
+  Value=%_DOADMIN_%
+end
+item: Remark
+  Text=Give non-admin users a chance to abort.
+end
+item: Check Configuration
+  Flags=10011111
+end
+item: Set Variable
+  Variable=DOADMIN
+  Value=0
+end
+item: Display Message
+  Title=Doing non-admin install
+  Text=The current login does not have Administrator Privileges on this machine.  Python will install its registry information into the per-user area only for the current login, instead of into the per-machine area for every account on this machine.  Some advanced uses of Python may not work as a result (for example, running a Python script as a service).
+  Text=
+  Text=If this is not what you want, please click Cancel to abort this installation, log on as an Administrator, and start the installation again.
+  Flags=00001000
+end
+item: End Block
+end
+item: Remark
+end
+item: Remark
+  Text=BEGIN WIZARD STUFF -----------------------------------------------------------------------------------------------------------------------------
+end
+item: Remark
+  Text=Note from Tim: the "stop" on the next line is actually "pause".
+end
+item: Open/Close INSTALL.LOG
+  Flags=00000001
+end
+item: Remark
+  Text=If the destination system does not have a writable Windows\System directory, system files will be written to the Windows\ directory
+end
+item: Check if File/Dir Exists
+  Pathname=%SYS%
+  Flags=10000100
+end
+item: Set Variable
+  Variable=SYS
+  Value=%WIN%
+end
+item: End Block
+end
+item: Check Configuration
+  Flags=10111011
+end
+item: Get Registry Key Value
+  Variable=COMMON
+  Key=SOFTWARE\Microsoft\Windows\CurrentVersion
+  Default=C:\Program Files\Common Files
+  Value Name=CommonFilesDir
+  Flags=00000100
+end
+item: Get Registry Key Value
+  Variable=PROGRAM_FILES
+  Key=SOFTWARE\Microsoft\Windows\CurrentVersion
+  Default=C:\Program Files
+  Value Name=ProgramFilesDir
+  Flags=00000100
+end
+item: Set Variable
+  Variable=EXPLORER
+  Value=1
+end
+item: End Block
+end
+item: Remark
+  Text=Note from Tim:  The Wizard hardcod "C:" at the start of the replacement text for MAINDIR.
+end
+item: Remark
+  Text=That's not appropriate if the system drive doesn't happen to be C:.
+end
+item: Remark
+  Text=I removed the "C:", and that did the right thing for two people who tested it on non-C: machines,
+end
+item: Remark
+  Text=but it's unclear whether it will always do the right thing.
+end
+item: Set Variable
+  Variable=MAINDIR
+  Value=\%MAINDIR%
+  Flags=00001100
+end
+item: Remark
+  Text=BACKUP is the variable that holds the path that all backup files will be copied to when overwritten
+end
+item: Set Variable
+  Variable=BACKUP
+  Value=%MAINDIR%\BACKUP
+  Flags=10000000
+end
+item: Remark
+  Text=DOBACKUP determines if a backup will be performed.  The possible values are A (do backup) or B (do not do backup)
+end
+item: Set Variable
+  Variable=DOBACKUP
+  Value=A
+end
+item: Remark
+  Text=BRANDING determines if the installation will be branded with a name and company.  By default, this is written to the INST directory (installation media).
+end
+item: Set Variable
+  Variable=BRANDING
+  Value=0
+end
+item: If/While Statement
+  Variable=BRANDING
+  Value=1
+end
+item: Read INI Value
+  Variable=NAME
+  Pathname=%INST%\CUSTDATA.INI
+  Section=Registration
+  Item=Name
+end
+item: Read INI Value
+  Variable=COMPANY
+  Pathname=%INST%\CUSTDATA.INI
+  Section=Registration
+  Item=Company
+end
+item: If/While Statement
+  Variable=NAME
+end
+item: Set Variable
+  Variable=DOBRAND
+  Value=1
+end
+item: Get System Information
+  Variable=NAME
+  Flags=00000110
+end
+item: Get System Information
+  Variable=COMPANY
+  Flags=00000111
+end
+item: End Block
+end
+item: End Block
+end
+item: Remark
+  Text=END WIZARD STUFF -----------------------------------------------------------------------------------------------------------------------------
+end
+item: Remark
+end
+item: Remark
+  Text=Set vrbls for the "Advanced Options" subdialog of Components.
+end
+item: Set Variable
+  Variable=SELECT_ADMIN
+  Value=A
+end
+item: If/While Statement
+  Variable=DOADMIN
+  Value=0
+end
+item: Set Variable
+  Variable=SELECT_ADMIN
+  Value=B
+end
+item: End Block
+end
+item: Remark
+end
+item: Remark
+  Text=TASKS values:
+end
+item: Remark
+  Text=A: Register file extensions
+end
+item: Remark
+  Text=B: Create Start Menu shortcuts
+end
+item: Set Variable
+  Variable=TASKS
+  Value=AB
+end
+item: Remark
+end
+item: Remark
+  Text=COMPONENTS values:
+end
+item: Remark
+  Text=A: interpreter and libraries
+end
+item: Remark
+  Text=B: Tcl/Tk
+end
+item: Remark
+  Text=C: docs
+end
+item: Remark
+  Text=D: tools
+end
+item: Remark
+  Text=E: test suite
+end
+item: Set Variable
+  Variable=COMPONENTS
+  Value=ABCDE
+end
+item: Remark
+end
+item: Remark
+  Text=March thru the user GUI.
+end
+item: Wizard Block
+  Direction Variable=DIRECTION
+  Display Variable=DISPLAY
+  Bitmap Pathname=.\installer.bmp
+  X Position=9
+  Y Position=10
+  Filler Color=11173759
+  Dialog=Select Destination Directory
+  Dialog=Backup Replaced Files
+  Dialog=Select Components
+  Dialog=Select Program Manager Group
+  Variable=
+  Variable=
+  Variable=
+  Variable=TASKS
+  Value=
+  Value=
+  Value=
+  Value=B
+  Compare=0
+  Compare=0
+  Compare=0
+  Compare=3
+  Flags=00000011
+end
+item: If/While Statement
+  Variable=DISPLAY
+  Value=Start Installation
+end
+item: Set Variable
+  Variable=SUMMARY
+  Value=Install directory:  %MAINDIR%%CRLF%
+end
+item: Remark
+end
+item: If/While Statement
+  Variable=SELECT_ADMIN
+  Value=A
+end
+item: Set Variable
+  Variable=SUMMARY
+  Value=%CRLF%Doing admin install.%CRLF%
+  Flags=00000001
+end
+item: Else Statement
+end
+item: Set Variable
+  Variable=SUMMARY
+  Value=%CRLF%Doing non-admin install.%CRLF%
+  Flags=00000001
+end
+item: End Block
+end
+item: Remark
+end
+item: If/While Statement
+  Variable=DOBACKUP
+  Value=A
+end
+item: Set Variable
+  Variable=SUMMARY
+  Value=%CRLF%Make backups, into %BACKUP%%CRLF%
+  Flags=00000001
+end
+item: Else Statement
+end
+item: Set Variable
+  Variable=SUMMARY
+  Value=%CRLF%Don't make backups.%CRLF%
+  Flags=00000001
+end
+item: End Block
+end
+item: Remark
+end
+item: Set Variable
+  Variable=SUMMARY
+  Value=%CRLF%Components:%CRLF%
+  Flags=00000001
+end
+item: If/While Statement
+  Variable=COMPONENTS
+  Value=A
+  Flags=00000010
+end
+item: Set Variable
+  Variable=SUMMARY
+  Value=    Python interpreter and libraries%CRLF%
+  Flags=00000001
+end
+item: End Block
+end
+item: If/While Statement
+  Variable=COMPONENTS
+  Value=B
+  Flags=00000010
+end
+item: Set Variable
+  Variable=SUMMARY
+  Value=    Tcl/Tk (Tkinter, IDLE, pydoc)%CRLF%
+  Flags=00000001
+end
+item: End Block
+end
+item: If/While Statement
+  Variable=COMPONENTS
+  Value=C
+  Flags=00000010
+end
+item: Set Variable
+  Variable=SUMMARY
+  Value=    Python documentation%CRLF%
+  Flags=00000001
+end
+item: End Block
+end
+item: If/While Statement
+  Variable=COMPONENTS
+  Value=D
+  Flags=00000010
+end
+item: Set Variable
+  Variable=SUMMARY
+  Value=    Tool and utility scripts%CRLF%
+  Flags=00000001
+end
+item: End Block
+end
+item: If/While Statement
+  Variable=COMPONENTS
+  Value=E
+  Flags=00000010
+end
+item: Set Variable
+  Variable=SUMMARY
+  Value=    Python test suite%CRLF%
+  Flags=00000001
+end
+item: End Block
+end
+item: Remark
+end
+item: If/While Statement
+  Variable=TASKS
+  Value=A
+  Flags=00000010
+end
+item: Set Variable
+  Variable=SUMMARY
+  Value=%CRLF%Register file extensions.%CRLF%
+  Flags=00000001
+end
+item: Else Statement
+end
+item: Set Variable
+  Variable=SUMMARY
+  Value=%CRLF%Don't register file extensions.%CRLF%
+  Flags=00000001
+end
+item: End Block
+end
+item: Remark
+end
+item: If/While Statement
+  Variable=TASKS
+  Value=B
+  Flags=00000010
+end
+item: Set Variable
+  Variable=SUMMARY
+  Value=%CRLF%Start Menu group:  %GROUP%%CRLF%
+  Flags=00000001
+end
+item: Else Statement
+end
+item: Set Variable
+  Variable=SUMMARY
+  Value=%CRLF%No Start Menu shortcuts.%CRLF%
+  Flags=00000001
+end
+item: End Block
+end
+item: End Block
+end
+item: Remark
+end
+item: Custom Dialog Set
+  Name=Select Destination Directory
+  Display Variable=DISPLAY
+  item: Dialog
+    Title=%APPTITLE% Installation
+    Title French=Installation de %APPTITLE%
+    Title German=Installation von %APPTITLE%
+    Title Spanish=Instalación de %APPTITLE%
+    Title Italian=Installazione di %APPTITLE%
+    Width=339
+    Height=280
+    Font Name=Helv
+    Font Size=8
+    item: Push Button
+      Rectangle=188 234 244 253
+      Variable=DIRECTION
+      Value=N
+      Create Flags=01010000000000010000000000000001
+      Text=&Next >
+      Text French=&Suite >
+      Text German=&Weiter >
+      Text Spanish=&Siguiente >
+      Text Italian=&Avanti >
+    end
+    item: Push Button
+      Rectangle=264 234 320 253
+      Action=3
+      Create Flags=01010000000000010000000000000000
+      Text=&Cancel
+      Text French=&Annuler
+      Text German=&Abbrechen
+      Text Spanish=&Cancelar
+      Text Italian=&Annulla
+    end
+    item: Static
+      Rectangle=10 225 320 226
+      Action=3
+      Create Flags=01010000000000000000000000000111
+    end
+    item: Static
+      Rectangle=108 11 323 33
+      Create Flags=01010000000000000000000000000000
+      Flags=0000000000000001
+      Name=Times New Roman
+      Font Style=-24 0 0 0 700 255 0 0 0 3 2 1 18
+      Text=Select Destination Directory
+      Text French=Sélectionner le répertoire de destination
+      Text German=Zielverzeichnis wählen
+      Text Spanish=Seleccione el directorio de destino
+      Text Italian=Selezionare Directory di destinazione
+    end
+    item: Listbox
+      Rectangle=108 58 321 219
+      Variable=MAINDIR
+      Enabled Color=00000000000000001111111111111111
+      Create Flags=01010000100000010000000101000001
+      Flags=0000110000001010
+      Text=%MAINDIR%
+      Text=
+    end
+    item: Static
+      Rectangle=108 40 313 58
+      Enabled Color=00000000000000001111111111111111
+      Create Flags=01010000000000000000000000000000
+      Text=Please select a directory for the %APPTITLE% files.
+    end
+  end
+  item: Dialog
+    Title=Select Destination Directory
+    Title French=Sélectionner le répertoire de destination
+    Title German=Zielverzeichnis wählen
+    Title Spanish=Seleccione el directorio de destino
+    Title Italian=Selezionare Directory di destinazione
+    Width=276
+    Height=216
+    Font Name=Helv
+    Font Size=8
+    item: Listbox
+      Rectangle=6 6 204 186
+      Variable=MAINDIR
+      Create Flags=01010000100000010000000101000000
+      Flags=0000110000100010
+      Text=%MAINDIR%
+      Text French=%MAINDIR%
+      Text German=%MAINDIR%
+      Text Spanish=%MAINDIR%
+      Text Italian=%MAINDIR%
+    end
+    item: Push Button
+      Rectangle=209 8 265 26
+      Create Flags=01010000000000010000000000000001
+      Text=OK
+      Text French=OK
+      Text German=OK
+      Text Spanish=Aceptar
+      Text Italian=OK
+    end
+    item: Push Button
+      Rectangle=209 31 265 50
+      Variable=MAINDIR
+      Value=%MAINDIR_SAVE%
+      Create Flags=01010000000000010000000000000000
+      Flags=0000000000000001
+      Text=Cancel
+      Text French=Annuler
+      Text German=Abbrechen
+      Text Spanish=Cancelar
+      Text Italian=Annulla
+    end
+  end
+end
+item: Custom Dialog Set
+  Name=Backup Replaced Files
+  Display Variable=DISPLAY
+  item: Dialog
+    Title=%APPTITLE% Installation
+    Title French=Fichiers de Sauvegarde Remplacés
+    Title German=Sicherungskopie von ersetzten Dateien erstellen
+    Title Portuguese=Ficheiros substituídos de segurança
+    Title Spanish=Copias de seguridad de los archivos reemplazados
+    Title Italian=Backup file sostituiti
+    Title Danish=Sikkerhedskopiering af erstattede filer
+    Title Dutch=Vervangen bestanden kopiëren
+    Title Norwegian=Sikkerhetskopiere erstattede filer
+    Title Swedish=Säkerhetskopiera utbytta filer
+    Width=350
+    Height=280
+    Font Name=Helv
+    Font Size=8
+    item: Push Button
+      Rectangle=188 234 244 251
+      Variable=DIRECTION
+      Value=N
+      Create Flags=01010000000000010000000000000001
+      Text=&Next >
+      Text French=&Suivant>
+      Text German=&Weiter>
+      Text Portuguese=&Próximo>
+      Text Spanish=&Siguiente >
+      Text Italian=&Avanti >
+      Text Danish=&Næste>
+      Text Dutch=&Volgende>
+      Text Norwegian=&Neste>
+      Text Swedish=&Nästa >
+    end
+    item: Push Button
+      Rectangle=131 234 188 251
+      Variable=DIRECTION
+      Value=B
+      Create Flags=01010000000000010000000000000000
+      Text=< &Back
+      Text French=<&Retour
+      Text German=<&Zurück
+      Text Portuguese=<&Retornar
+      Text Spanish=<&Retroceder
+      Text Italian=< &Indietro
+      Text Danish=<&Tilbage
+      Text Dutch=<&Terug
+      Text Norwegian=<&Tilbake
+      Text Swedish=< &Tillbaka
+    end
+    item: Push Button
+      Rectangle=278 234 330 251
+      Action=3
+      Create Flags=01010000000000010000000000000000
+      Text=Cancel
+      Text French=Annuler
+      Text German=Abbrechen
+      Text Portuguese=Cancelar
+      Text Spanish=Cancelar
+      Text Italian=Annulla
+      Text Danish=Annuller
+      Text Dutch=Annuleren
+      Text Norwegian=Avbryt
+      Text Swedish=Avbryt
+    end
+    item: Static
+      Rectangle=11 221 329 223
+      Action=3
+      Create Flags=01010000000000000000000000000111
+    end
+    item: Static
+      Rectangle=108 46 320 98
+      Create Flags=01010000000000000000000000000000
+      Text=This installation program can create backup copies of all files replaced during the installation. These files will be used when the software is uninstalled and a rollback is requested.  If backup copies are not created, you will only be able to uninstall the software and not roll the system back to a previous state.
+      Text=
+      Text=Do you want to create backups of replaced files?
+      Text French=Le programme d'installation peut créer des copies de sauvegarde de tous les fichiers remplacés pendant l'installation. Ces fichiers sont utilisés au cas où le logiciel est désinstallé et que l'on procède à la reprise du système. Si les copies de sauvegarde ne sont pas créées, on ne pourra que désinstaller le logiciel sans reprendre le système à un état précédent. Voulez-vous créer une sauvegarde des fichiers remplacés ?
+      Text German=Dieses Installationsprogramm kann Sicherungskopien von allen während der Installation ersetzten Dateien erstellen. Diese Dateien werden zur Rückgängigmachung der Installation und bei Anforderung eines Rollbacks verwendet. Ohne Sicherungskopien ist nur eine Rückgängigmachung der Installation möglich, nicht aber ein Rollback des Systems. Sicherungskopien der ersetzten Dateien erstellen?
+      Text Portuguese=Este programa de instalação pode criar cópias de segurança de todos os ficheiros substituídos durante a instalação. Estes ficheiros serão utilizados quando o programa for desinstalado  e for requisitada uma retomada. Se as cópias de segurança não forem criadas, só poderá desinstalar o programa e não pode retomar  um estado anterior do sistema. Deseja criar cópias de segurança dos ficheiros substituídos?
+      Text Spanish=Este programa de instalación puede crear copias de seguridad de todos los archivos reemplazados durante la instalación. Estos archivos se utilizarán cuando se desinstale el software y se solicite volver al estado anterior. Si no se crean copias de seguridad, únicamente podrá desinstalar el software y no podrá devolver el sistema al estado anterior. ¿Desea crear archivos de seguridad de los archivos reemplazados?
+      Text Italian=Questo programma di installazione può creare copie di backup di tutti i file sostituiti durante l’installazione. Questi file saranno usati quando il software sarà disinstallato e sarà richiesto un ritorno allo stato precedente. Se non crei le copie di backup, potrai solo disinstallare il software, ma non potrai riportare il sistema allo stato precedente. Vuoi creare i file di backup dei file sostituiti?
+      Text Danish=Dette installationsprogram kan oprette sikkerhedskopier af alle filer, som erstattes under installationen. Disse filer benyttes, når softwaren fjernes, og den tidligere systemkonfiguration genetableres. Hvis der ikke oprettes sikkerhedskopier, kan du kun fjerne den installerede software og ikke genetablere den tidligere systemkonfiguration. Vil du oprette sikkerhedskopier af filer, som erstattes?
+      Text Dutch=Dit installatieprogramma kan kopieën maken van alle bestanden die tijdens de installatie worden vervangen. Deze worden dan gebruikt als de software-installatie ongedaan wordt gemaakt en u het systeem wilt laten terugkeren naar de oorspronkelijke staat. Als er geen back-up kopieën worden gemaakt, kunt u de software enkel verwijderen maar het systeem niet in de oorspronkelijke staat terugbrengen. Wilt u een back-up maken van de vervangen bestanden?
+      Text Norwegian=Dette installasjonsprogrammet kan lage sikkerhetskopier av alle filer som blir erstattet under installasjonen. Disse filene vil tas i bruk når programvaren er avinstallert og det er behov for tilbakestilling. Hvis det ikke er laget sikkerhetskopier, kan du kun avinstallere programvaren og ikke stille systemet tilbake til tidligere status. Ønsker du å lage sikkerhetskopier av de filene som blir erstattet nå?
+      Text Swedish=Installationsprogrammet kan skapa säkerhetskopior av alla filer som byts ut under installationen. Dessa filer kan sedan användas när programvaran avinstalleras och du begär rollback. Om du då inte har några säkerhetskopior kan du bara avinstallera programvaran, inte återskapa systemet i dess tidigare skick. Vill du göra säkerhetskopior av de ersatta filerna?
+    end
+    item: Radio Button
+      Rectangle=141 106 265 136
+      Variable=DOBACKUP
+      Create Flags=01010000000000010000000000001001
+      Text=&Yes, make backups
+      Text=N&o, do not make backups
+      Text=
+      Text French=&Oui
+      Text French=N&on
+      Text French=
+      Text German=&Ja
+      Text German=N&ein
+      Text German=
+      Text Portuguese=&Sim
+      Text Portuguese=Nã&o
+      Text Portuguese=
+      Text Spanish=&Sí
+      Text Spanish=N&o
+      Text Spanish=
+      Text Italian=&Sì
+      Text Italian=N&o
+      Text Italian=
+      Text Danish=&Ja
+      Text Danish=&Nej
+      Text Danish=
+      Text Dutch=&Ja
+      Text Dutch=N&ee
+      Text Dutch=
+      Text Norwegian=&Ja
+      Text Norwegian=&Nei
+      Text Norwegian=
+      Text Swedish=&Ja
+      Text Swedish=N&ej
+      Text Swedish=
+    end
+    item: Static
+      Control Name=BACK2
+      Rectangle=108 173 320 208
+      Action=1
+      Create Flags=01010000000000000000000000000111
+      Text=Backup File Destination Directory
+      Text French=Répertoire de destination des fichiers de sauvegarde
+      Text German=Zielverzeichnis für die Sicherungsdatei
+      Text Portuguese=Directório de destino de ficheiro de segurança
+      Text Spanish=Directorio de Destino de los Archivos de Seguridad
+      Text Italian=Directory di destinazione dei file di backup
+      Text Danish=Destinationsbibliotek til sikkerhedskopier
+      Text Dutch=Doeldirectory backup-bestand
+      Text Norwegian=Målkatalog for sikkerhetskopier
+      Text Swedish=Katalog för säkerhetskopierade filer
+    end
+    item: Push Button
+      Control Name=BACK3
+      Rectangle=265 185 318 203
+      Variable=BACKUP_SAVE
+      Value=%BACKUP%
+      Destination Dialog=1
+      Action=2
+      Create Flags=01010000000000010000000000000000
+      Text=B&rowse...
+      Text French=P&arcourir
+      Text German=B&lättern...
+      Text Portuguese=P&rocurar
+      Text Spanish=V&isualizar...
+      Text Italian=Sfoglia...
+      Text Danish=&Gennemse...
+      Text Dutch=B&laderen...
+      Text Norwegian=Bla igjennom
+      Text Swedish=&Bläddra
+    end
+    item: Static
+      Control Name=BACK4
+      Rectangle=129 188 254 200
+      Destination Dialog=2
+      Create Flags=01010000000000000000000000000000
+      Text=%BACKUP%
+      Text French=%BACKUP%
+      Text German=%BACKUP%
+      Text Portuguese=%BACKUP%
+      Text Spanish=%BACKUP%
+      Text Italian=%BACKUP%
+      Text Danish=%BACKUP%
+      Text Dutch=%BACKUP%
+      Text Norwegian=%BACKUP%
+      Text Swedish=%BACKUP%
+    end
+    item: Static
+      Rectangle=108 11 323 36
+      Create Flags=01010000000000000000000000000000
+      Flags=0000000000000001
+      Name=Times New Roman
+      Font Style=-24 0 0 0 700 255 0 0 0 3 2 1 18
+      Text=Backup Replaced Files
+      Text French=Sélectionner les composants
+      Text German=Komponenten auswählen
+      Text Spanish=Seleccione componentes
+      Text Italian=Selezionare i componenti
+    end
+    item: If/While Statement
+      Variable=DOBACKUP
+      Value=B
+    end
+    item: Set Control Attribute
+      Control Name=BACK3
+      Operation=1
+    end
+    item: Set Control Attribute
+      Control Name=BACK4
+      Operation=1
+    end
+    item: Else Statement
+    end
+    item: Set Control Attribute
+      Control Name=BACK3
+    end
+    item: Set Control Attribute
+      Control Name=BACK4
+    end
+    item: End Block
+    end
+  end
+  item: Dialog
+    Title=Select Destination Directory
+    Title French=Choisissez le répertoire de destination
+    Title German=Zielverzeichnis wählen
+    Title Portuguese=Seleccionar Directório de Destino
+    Title Spanish=Seleccione el Directorio de Destino
+    Title Italian=Seleziona Directory di destinazione
+    Title Danish=Vælg Destinationsbibliotek
+    Title Dutch=Kies Doeldirectory
+    Title Norwegian=Velg målkatalog
+    Title Swedish=Välj destinationskalatog
+    Width=276
+    Height=216
+    Font Name=Helv
+    Font Size=8
+    item: Listbox
+      Rectangle=6 3 200 186
+      Variable=BACKUP
+      Create Flags=01010000100000010000000101000000
+      Flags=0000110000100010
+      Text=%BACKUP%
+      Text=
+      Text French=%BACKUP%
+      Text French=
+      Text German=%BACKUP%
+      Text German=
+      Text Portuguese=%BACKUP%
+      Text Portuguese=
+      Text Spanish=%BACKUP%
+      Text Spanish=
+      Text Italian=%BACKUP%
+      Text Italian=
+      Text Danish=%BACKUP%
+      Text Danish=
+      Text Dutch=%BACKUP%
+      Text Dutch=
+      Text Norwegian=%BACKUP%
+      Text Norwegian=
+      Text Swedish=%BACKUP%
+      Text Swedish=
+    end
+    item: Push Button
+      Rectangle=209 8 265 26
+      Create Flags=01010000000000010000000000000001
+      Text=OK
+      Text French=OK
+      Text German=OK
+      Text Portuguese=OK
+      Text Spanish=ACEPTAR
+      Text Italian=OK
+      Text Danish=OK
+      Text Dutch=OK
+      Text Norwegian=OK
+      Text Swedish=OK
+    end
+    item: Push Button
+      Rectangle=209 31 265 50
+      Variable=BACKUP
+      Value=%BACKUP_SAVE%
+      Create Flags=01010000000000010000000000000000
+      Flags=0000000000000001
+      Text=Cancel
+      Text French=Annuler
+      Text German=Abbrechen
+      Text Portuguese=Cancelar
+      Text Spanish=Cancelar
+      Text Italian=Annulla
+      Text Danish=Slet
+      Text Dutch=Annuleren
+      Text Norwegian=Avbryt
+      Text Swedish=Avbryt
+    end
+  end
+end
+item: Custom Dialog Set
+  Name=Select Components
+  Display Variable=DISPLAY
+  item: Dialog
+    Title=%APPTITLE% Installation
+    Title French=Installation de %APPTITLE%
+    Title German=Installation von %APPTITLE%
+    Title Spanish=Instalación de %APPTITLE%
+    Title Italian=Installazione di %APPTITLE%
+    Width=339
+    Height=280
+    Font Name=Helv
+    Font Size=8
+    item: Push Button
+      Rectangle=188 234 244 253
+      Variable=DIRECTION
+      Value=N
+      Create Flags=01010000000000010000000000000001
+      Text=&Next >
+      Text French=&Suite >
+      Text German=&Weiter >
+      Text Spanish=&Siguiente >
+      Text Italian=&Avanti >
+    end
+    item: Push Button
+      Rectangle=131 234 188 253
+      Variable=DIRECTION
+      Value=B
+      Create Flags=01010000000000010000000000000000
+      Text=< &Back
+      Text French=< &Retour
+      Text German=< &Zurück
+      Text Spanish=< &Atrás
+      Text Italian=< &Indietro
+    end
+    item: Push Button
+      Rectangle=264 234 320 253
+      Action=3
+      Create Flags=01010000000000010000000000000000
+      Text=&Cancel
+      Text French=&Annuler
+      Text German=&Abbrechen
+      Text Spanish=&Cancelar
+      Text Italian=&Annulla
+    end
+    item: Checkbox
+      Rectangle=108 66 313 156
+      Variable=COMPONENTS
+      Create Flags=01010000000000010000000000000011
+      Flags=0000000000000110
+      Text=Python interpreter and libraries
+      Text=Tcl/Tk (Tkinter, IDLE, pydoc)
+      Text=Python HTML docs
+      Text=Python utility scripts (Tools/)
+      Text=Python test suite (Lib/test/)
+      Text=
+      Text French=Python interpreter, library and IDLE
+      Text French=Python HTML docs
+      Text French=Python utility scripts (Tools/)
+      Text French=Python test suite (Lib/test/)
+      Text French=
+      Text German=Python interpreter, library and IDLE
+      Text German=Python HTML docs
+      Text German=Python utility scripts (Tools/)
+      Text German=Python test suite (Lib/test/)
+      Text German=
+      Text Spanish=Python interpreter, library and IDLE
+      Text Spanish=Python HTML docs
+      Text Spanish=Python utility scripts (Tools/)
+      Text Spanish=Python test suite (Lib/test/)
+      Text Spanish=
+      Text Italian=Python interpreter, library and IDLE
+      Text Italian=Python HTML docs
+      Text Italian=Python utility scripts (Tools/)
+      Text Italian=Python test suite (Lib/test/)
+      Text Italian=
+    end
+    item: Static
+      Rectangle=108 45 320 63
+      Create Flags=01010000000000000000000000000000
+      Text=Choose which components to install by checking the boxes below.
+      Text French=Choisissez les composants que vous voulez installer en cochant les cases ci-dessous.
+      Text German=Wählen Sie die zu installierenden Komponenten, indem Sie in die entsprechenden Kästchen klicken.
+      Text Spanish=Elija los componentes que desee instalar marcando los cuadros de abajo.
+      Text Italian=Scegliere quali componenti installare selezionando le caselle sottostanti.
+    end
+    item: Push Button
+      Rectangle=188 203 269 220
+      Destination Dialog=1
+      Action=2
+      Enabled Color=00000000000000000000000011111111
+      Create Flags=01010000000000010000000000000000
+      Text=Advanced Options ...
+    end
+    item: Static
+      Rectangle=10 225 320 226
+      Action=3
+      Create Flags=01010000000000000000000000000111
+    end
+    item: Static
+      Rectangle=108 10 323 43
+      Create Flags=01010000000000000000000000000000
+      Flags=0000000000000001
+      Name=Times New Roman
+      Font Style=-24 0 0 0 700 255 0 0 0 3 2 1 18
+      Text=Select Components
+      Text French=Sélectionner les composants
+      Text German=Komponenten auswählen
+      Text Spanish=Seleccione componentes
+      Text Italian=Selezionare i componenti
+    end
+    item: Static
+      Rectangle=251 180 311 193
+      Variable=COMPONENTS
+      Value=MAINDIR
+      Create Flags=01010000000000000000000000000010
+    end
+    item: Static
+      Rectangle=251 168 311 179
+      Variable=COMPONENTS
+      Create Flags=01010000000000000000000000000010
+    end
+    item: Static
+      Rectangle=123 168 234 181
+      Create Flags=01010000000000000000000000000000
+      Text=Disk Space Required:
+      Text French=Espace disque requis :
+      Text German=Notwendiger Speicherplatz:
+      Text Spanish=Espacio requerido en el disco:
+      Text Italian=Spazio su disco necessario:
+    end
+    item: Static
+      Rectangle=123 180 234 193
+      Create Flags=01010000000000000000000000000000
+      Text=Disk Space Remaining:
+      Text French=Espace disque disponible :
+      Text German=Verbleibender Speicherplatz:
+      Text Spanish=Espacio en disco disponible:
+      Text Italian=Spazio su disco disponibile:
+    end
+    item: Static
+      Rectangle=108 158 320 196
+      Action=1
+      Create Flags=01010000000000000000000000000111
+    end
+    item: If/While Statement
+      Variable=DLG_EVENT_TYPE
+      Value=VERIFY
+    end
+    item: Remark
+      Text=If they're installing Tcl/Tk, Tools, or the test suite, doesn't make much sense unless they're installing Python too.
+    end
+    item: If/While Statement
+      Variable=COMPONENTS
+      Value=BDE
+      Flags=00001010
+    end
+    item: If/While Statement
+      Variable=COMPONENTS
+      Value=A
+      Flags=00000011
+    end
+    item: Display Message
+      Title=Are you sure?
+      Text=Installing Tcl/Tk, Tools or the test suite doesn't make much sense unless you install the Python interpreter and libraries too.
+      Text=
+      Text=Click Yes if that's really what you want.
+      Flags=00101101
+    end
+    item: Remark
+      Text=Nothing -- just proceed to the next dialog.
+    end
+    item: Else Statement
+    end
+    item: Remark
+      Text=Return to the dialog.
+    end
+    item: Set Variable
+      Variable=DLG_EVENT_TYPE
+    end
+    item: End Block
+    end
+    item: End Block
+    end
+    item: End Block
+    end
+    item: End Block
+    end
+  end
+  item: Dialog
+    Title=Advanced Options
+    Width=339
+    Height=213
+    Font Name=Helv
+    Font Size=8
+    item: Radio Button
+      Control Name=ADMIN2
+      Rectangle=11 46 90 76
+      Variable=SELECT_ADMIN
+      Enabled Color=00000000000000001111111111111111
+      Create Flags=01010000000000010000000000001001
+      Text=Admin install
+      Text=Non-Admin installl
+      Text=
+    end
+    item: Push Button
+      Rectangle=188 170 244 189
+      Variable=DIRECTION
+      Value=N
+      Create Flags=01010000000000010000000000000001
+      Text=OK
+      Text French=&Suite >
+      Text German=&Weiter >
+      Text Spanish=&Siguiente >
+      Text Italian=&Avanti >
+    end
+    item: Static
+      Rectangle=5 3 326 83
+      Action=1
+      Enabled Color=00000000000000001111111111111111
+      Create Flags=01010000000000000000000000000111
+    end
+    item: Static
+      Control Name=ADMIN1
+      Rectangle=11 11 321 45
+      Enabled Color=00000000000000001111111111111111
+      Create Flags=01010000000000000000000000000000
+      Text=By default, the install records settings in the per-machine area of the registry (HKLM), and installs the Python and C runtime DLLs to %SYS32%.  Choose "Non-Admin install" if you would prefer settings made in the per-user registry (HKCU), and DLLs installed in %MAINDIR%.
+    end
+    item: Static
+      Rectangle=5 90 326 157
+      Action=1
+      Enabled Color=00000000000000001111111111111111
+      Create Flags=01010000000000000000000000000111
+    end
+    item: Checkbox
+      Rectangle=11 121 243 151
+      Variable=TASKS
+      Enabled Color=00000000000000001111111111111111
+      Create Flags=01010000000000010000000000000011
+      Text=Register file extensions (.py, .pyw, .pyc, .pyo)
+      Text=Create Start Menu shortcuts
+      Text=
+    end
+    item: Static
+      Rectangle=11 103 320 121
+      Enabled Color=00000000000000001111111111111111
+      Create Flags=01010000000000000000000000000000
+      Text=Choose tasks to perform by checking the boxes below.
+    end
+    item: If/While Statement
+      Variable=DLG_EVENT_TYPE
+      Value=INIT
+    end
+    item: If/While Statement
+      Variable=DOADMIN
+      Value=1
+    end
+    item: Set Control Attribute
+      Control Name=ADMIN2
+    end
+    item: Else Statement
+    end
+    item: Set Control Text
+      Control Name=ADMIN1
+      Control Text=This section is available only if logged in to an account with Administrator privileges.
+    end
+    item: Set Control Attribute
+      Control Name=ADMIN2
+      Operation=1
+    end
+    item: End Block
+    end
+    item: End Block
+    end
+  end
+end
+item: Custom Dialog Set
+  Name=Select Program Manager Group
+  Display Variable=DISPLAY
+  item: Dialog
+    Title=%APPTITLE% Installation
+    Title French=Installation de %APPTITLE%
+    Title German=Installation von %APPTITLE%
+    Title Spanish=Instalación de %APPTITLE%
+    Title Italian=Installazione di %APPTITLE%
+    Width=339
+    Height=280
+    Font Name=Helv
+    Font Size=8
+    item: Push Button
+      Rectangle=188 234 244 253
+      Variable=DIRECTION
+      Value=N
+      Create Flags=01010000000000010000000000000001
+      Text=&Next >
+      Text French=&Suite >
+      Text German=&Weiter >
+      Text Spanish=&Siguiente >
+      Text Italian=&Avanti >
+    end
+    item: Push Button
+      Rectangle=131 234 188 253
+      Variable=DIRECTION
+      Value=B
+      Create Flags=01010000000000010000000000000000
+      Flags=0000000000000001
+      Text=< &Back
+      Text French=< &Retour
+      Text German=< &Zurück
+      Text Spanish=< &Atrás
+      Text Italian=< &Indietro
+    end
+    item: Push Button
+      Rectangle=264 234 320 253
+      Action=3
+      Create Flags=01010000000000010000000000000000
+      Text=&Cancel
+      Text French=&Annuler
+      Text German=&Abbrechen
+      Text Spanish=&Cancelar
+      Text Italian=&Annulla
+    end
+    item: Static
+      Rectangle=10 225 320 226
+      Action=3
+      Create Flags=01010000000000000000000000000111
+    end
+    item: Static
+      Rectangle=108 10 323 53
+      Create Flags=01010000000000000000000000000000
+      Flags=0000000000000001
+      Name=Times New Roman
+      Font Style=-24 0 0 0 700 255 0 0 0 3 2 1 18
+      Text=Select Start Menu Group
+      Text French=Sélectionner le groupe du Gestionnaire de programme
+      Text German=Bestimmung der Programm-Managergruppe
+      Text Spanish=Seleccione grupo del Administrador de programas
+      Text Italian=Selezionare il gruppo ProgMan
+    end
+    item: Static
+      Rectangle=108 35 320 65
+      Create Flags=01010000000000000000000000000000
+      Text=Enter the name of the Start Menu program group to which to add the %APPTITLE% icons:
+      Text French=Entrez le nom du groupe du Gestionnaire de programme dans lequel vous souhaitez ajouter les icônes de %APPTITLE% :
+      Text German=Geben Sie den Namen der Programmgruppe ein, der das Symbol %APPTITLE% hinzugefügt werden soll:
+      Text Spanish=Escriba el nombre del grupo del Administrador de programas en el que desea agregar los iconos de %APPTITLE%:
+      Text Italian=Inserire il nome del gruppo Program Manager per aggiungere le icone %APPTITLE% a:
+    end
+    item: Combobox
+      Rectangle=108 56 320 219
+      Variable=GROUP
+      Create Flags=01010000001000010000001100000001
+      Flags=0000000000000001
+      Text=%GROUP%
+      Text=
+      Text French=%GROUP%
+      Text German=%GROUP%
+      Text Spanish=%GROUP%
+      Text Italian=%GROUP%
+    end
+  end
+end
+item: Custom Dialog Set
+  Name=Start Installation
+  Display Variable=DISPLAY
+  item: Dialog
+    Title=%APPTITLE% Installation
+    Title French=Installation de %APPTITLE%
+    Title German=Installation von %APPTITLE%
+    Title Spanish=Instalación de %APPTITLE%
+    Title Italian=Installazione di %APPTITLE%
+    Width=339
+    Height=280
+    Font Name=Helv
+    Font Size=8
+    item: Push Button
+      Rectangle=188 234 244 253
+      Variable=DIRECTION
+      Value=N
+      Create Flags=01010000000000010000000000000001
+      Text=&Next >
+      Text French=&Suite >
+      Text German=&Weiter >
+      Text Spanish=&Siguiente >
+      Text Italian=&Avanti >
+    end
+    item: Push Button
+      Rectangle=131 234 188 253
+      Variable=DIRECTION
+      Value=B
+      Create Flags=01010000000000010000000000000000
+      Text=< &Back
+      Text French=< &Retour
+      Text German=< &Zurück
+      Text Spanish=< &Atrás
+      Text Italian=< &Indietro
+    end
+    item: Push Button
+      Rectangle=264 234 320 253
+      Action=3
+      Create Flags=01010000000000010000000000000000
+      Text=&Cancel
+      Text French=&Annuler
+      Text German=&Abbrechen
+      Text Spanish=&Cancelar
+      Text Italian=&Annulla
+    end
+    item: Static
+      Rectangle=10 225 320 226
+      Action=3
+      Create Flags=01010000000000000000000000000111
+    end
+    item: Static
+      Rectangle=108 10 323 53
+      Create Flags=01010000000000000000000000000000
+      Flags=0000000000000001
+      Name=Times New Roman
+      Font Style=-24 0 0 0 700 255 0 0 0 3 2 1 18
+      Text=Ready to Install!
+      Text French=Prêt à installer !
+      Text German=Installationsbereit!
+      Text Spanish=¡Preparado para la instalación!
+      Text Italian=Pronto per l'installazione!
+    end
+    item: Static
+      Rectangle=108 40 320 62
+      Create Flags=01010000000000000000000000000000
+      Text=Click the Next button to install %APPTITLE%, or the Back button to change choices:
+      Text French=Vous êtes maintenant prêt à installer les fichiers %APPTITLE%.
+      Text French=
+      Text French=Cliquez sur le bouton Suite pour commencer l'installation ou sur le bouton Retour pour entrer les informations d'installation à nouveau.
+      Text German=Sie können %APPTITLE% nun installieren.
+      Text German=
+      Text German=Klicken Sie auf "Weiter", um mit der Installation zu beginnen. Klicken Sie auf "Zurück", um die Installationsinformationen neu einzugeben.
+      Text Spanish=Ya está listo para instalar %APPTITLE%.
+      Text Spanish=
+      Text Spanish=Presione el botón Siguiente para comenzar la instalación o presione Atrás para volver a ingresar la información para la instalación.
+      Text Italian=Ora è possibile installare %APPTITLE%.
+      Text Italian=
+      Text Italian=Premere il pulsante Avanti per avviare l'installazione o il pulsante Indietro per reinserire le informazioni di installazione.
+    end
+    item: Editbox
+      Rectangle=108 66 324 219
+      Help Context=16711681
+      Enabled Color=00000000000000001111111111111111
+      Create Flags=01010000100000000001100011000100
+      Text=%SUMMARY%
+    end
+  end
+end
+item: Remark
+end
+item: If/While Statement
+  Variable=DISPLAY
+  Value=Select Destination Directory
+end
+item: Remark
+  Text=User may have changed MAINDIR, so reset BACKUP to match.
+end
+item: Set Variable
+  Variable=BACKUP
+  Value=%MAINDIR%\BACKUP
+end
+item: End Block
+end
+item: Remark
+end
+item: End Block
+end
+item: Remark
+end
+item: Remark
+  Text=BEGIN WIZARD STUFF -----------------------------------------------------------------------------------------------------------------------------
+end
+item: Remark
+  Text=When the BACKUP feature is enabled, the BACKUPDIR is initialized
+end
+item: If/While Statement
+  Variable=DOBACKUP
+  Value=A
+end
+item: Set Variable
+  Variable=BACKUPDIR
+  Value=%BACKUP%
+end
+item: End Block
+end
+item: Remark
+  Text=The BRANDING information is written to the INI file on the installation media.
+end
+item: If/While Statement
+  Variable=BRANDING
+  Value=1
+end
+item: If/While Statement
+  Variable=DOBRAND
+  Value=1
+end
+item: Edit INI File
+  Pathname=%INST%\CUSTDATA.INI
+  Settings=[Registration]
+  Settings=NAME=%NAME%
+  Settings=COMPANY=%COMPANY%
+  Settings=
+end
+item: End Block
+end
+item: End Block
+end
+item: Remark
+  Text=Begin writing to the INSTALL.LOG
+end
+item: Open/Close INSTALL.LOG
+end
+item: Remark
+  Text=Check free disk space calculates free disk space as well as component sizes.
+end
+item: Remark
+  Text=It should be located before all Install File actions.
+end
+item: Check Disk Space
+  Component=COMPONENTS
+end
+item: Remark
+  Text=This include script allows uninstall support
+end
+item: Remark
+  Text=Note from Tim:  this is our own Uninstal.wse, a copy of Wise's except
+end
+item: Remark
+  Text=it writes to HKCU (instead of HKLM) if the user doesn't have admin privs.
+end
+item: Include Script
+  Pathname=.\Uninstal.wse
+end
+item: Remark
+  Text=Note from Tim: these seeming no-ops actually convert to short filenames.
+end
+item: Set Variable
+  Variable=COMMON
+  Value=%COMMON%
+  Flags=00010100
+end
+item: Set Variable
+  Variable=MAINDIR
+  Value=%MAINDIR%
+  Flags=00010100
+end
+item: Remark
+  Text=This IF/THEN/ELSE reads the correct registry entries for shortcut/icon placement
+end
+item: Check Configuration
+  Flags=10111011
+end
+item: Get Registry Key Value
+  Variable=STARTUPDIR
+  Key=Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders
+  Default=%WIN%\Start Menu\Programs\StartUp
+  Value Name=StartUp
+  Flags=00000010
+end
+item: Get Registry Key Value
+  Variable=DESKTOPDIR
+  Key=Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders
+  Default=%WIN%\Desktop
+  Value Name=Desktop
+  Flags=00000010
+end
+item: Get Registry Key Value
+  Variable=STARTMENUDIR
+  Key=Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders
+  Default=%WIN%\Start Menu
+  Value Name=Start Menu
+  Flags=00000010
+end
+item: Get Registry Key Value
+  Variable=GROUPDIR
+  Key=Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders
+  Default=%WIN%\Start Menu\Programs
+  Value Name=Programs
+  Flags=00000010
+end
+item: Get Registry Key Value
+  Variable=CSTARTUPDIR
+  Key=Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders
+  Default=%STARTUPDIR%
+  Value Name=Common Startup
+  Flags=00000100
+end
+item: Get Registry Key Value
+  Variable=CDESKTOPDIR
+  Key=Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders
+  Default=%DESKTOPDIR%
+  Value Name=Common Desktop
+  Flags=00000100
+end
+item: Get Registry Key Value
+  Variable=CSTARTMENUDIR
+  Key=Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders
+  Default=%STARTMENUDIR%
+  Value Name=Common Start Menu
+  Flags=00000100
+end
+item: Get Registry Key Value
+  Variable=CGROUPDIR
+  Key=Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders
+  Default=%GROUPDIR%
+  Value Name=Common Programs
+  Flags=00000100
+end
+item: Else Statement
+end
+item: Remark
+  Text=Note from Tim:  the Wizard left this block empty!
+end
+item: Remark
+  Text=Perhaps it's only relevant on Windows 3.1.
+end
+item: End Block
+end
+item: Remark
+  Text=END WIZARD STUFF -----------------------------------------------------------------------------------------------------------------------------
+end
+item: Remark
+end
+item: If/While Statement
+  Variable=SELECT_ADMIN
+  Value=B
+end
+item: Remark
+  Text=The user chose a non-admin install in "Advanced Options".
+end
+item: Remark
+  Text=This should come after the include of Uninstal.wse above, because
+end
+item: Remark
+  Text=writing uninstall info to HKCU is ineffective except under Win2K.
+end
+item: Set Variable
+  Variable=DOADMIN
+  Value=0
+end
+item: End Block
+end
+item: Remark
+end
+item: Set Variable
+  Variable=CGROUP_SAVE
+  Value=%GROUP%
+end
+item: If/While Statement
+  Variable=TASKS
+  Value=B
+  Flags=00000010
+end
+item: If/While Statement
+  Variable=DOADMIN
+  Value=1
+end
+item: Set Variable
+  Variable=GROUP
+  Value=%CGROUPDIR%\%GROUP%
+end
+item: Else Statement
+end
+item: Set Variable
+  Variable=GROUP
+  Value=%GROUPDIR%\%GROUP%
+end
+item: End Block
+end
+item: End Block
+end
+item: Remark
+end
+item: Remark
+  Text=Long section to install files.
+end
+item: Remark
+end
+item: If/While Statement
+  Variable=DOADMIN
+  Value=1
+end
+item: Set Variable
+  Variable=DLLDEST
+  Value=%SYS32%
+end
+item: Else Statement
+end
+item: Set Variable
+  Variable=DLLDEST
+  Value=%MAINDIR%
+end
+item: End Block
+end
+item: Remark
+end
+item: Remark
+  Text=Install the license even if they deselect everything <wink>.
+end
+item: Install File
+  Source=..\license
+  Destination=%MAINDIR%\LICENSE.txt
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\readme
+  Destination=%MAINDIR%\README.txt
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\misc\news
+  Destination=%MAINDIR%\NEWS.txt
+  Flags=0000000000000010
+end
+item: Remark
+  Text=Icons -- always install so that the uninstaller can use them for its own display.
+end
+item: Install File
+  Source=..\pc\pycon.ico
+  Destination=%MAINDIR%\pycon.ico
+  Flags=0000000010000010
+end
+item: Install File
+  Source=..\pc\pyc.ico
+  Destination=%MAINDIR%\pyc.ico
+  Flags=0000000010000010
+end
+item: Install File
+  Source=..\pc\py.ico
+  Destination=%MAINDIR%\py.ico
+  Flags=0000000010000010
+end
+item: Remark
+end
+item: Remark
+  Text=These arrange to (recursively!) delete all .pyc and .pyo files at uninstall time.
+end
+item: Remark
+  Text=This "does the right thing":  any directories left empty at the end are removed.
+end
+item: Add Text to INSTALL.LOG
+  Text=File Tree: %MAINDIR%\*.pyc
+end
+item: Add Text to INSTALL.LOG
+  Text=File Tree: %MAINDIR%\*.pyo
+end
+item: Remark
+end
+item: Remark
+  Text=A: interpreter and libraries
+end
+item: If/While Statement
+  Variable=COMPONENTS
+  Value=A
+  Flags=00000010
+end
+item: Remark
+  Text=Executables
+end
+item: Install File
+  Source=.\python.exe
+  Destination=%MAINDIR%\python.exe
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\pythonw.exe
+  Destination=%MAINDIR%\pythonw.exe
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\w9xpopen.exe
+  Destination=%MAINDIR%\w9xpopen.exe
+  Flags=0000000000000010
+end
+item: Remark
+end
+item: Remark
+  Text=Extension module DLLs (.pyd); keep in synch with libs directory next
+end
+item: Install File
+  Source=.\_winreg.pyd
+  Destination=%MAINDIR%\DLLs\_winreg.pyd
+  Description=Extension modules
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\_csv.pyd
+  Destination=%MAINDIR%\DLLs\_csv.pyd
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\_sre.pyd
+  Destination=%MAINDIR%\DLLs\_sre.pyd
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\_ssl.pyd
+  Destination=%MAINDIR%\DLLs\_ssl.pyd
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\_symtable.pyd
+  Destination=%MAINDIR%\DLLs\_symtable.pyd
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\_testcapi.pyd
+  Destination=%MAINDIR%\DLLs\_testcapi.pyd
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\_tkinter.pyd
+  Destination=%MAINDIR%\DLLs\_tkinter.pyd
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\_socket.pyd
+  Destination=%MAINDIR%\DLLs\_socket.pyd
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\_bsddb.pyd
+  Destination=%MAINDIR%\DLLs\_bsddb.pyd
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\bz2.pyd
+  Destination=%MAINDIR%\DLLs\bz2.pyd
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\datetime.pyd
+  Destination=%MAINDIR%\DLLs\datetime.pyd
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\mmap.pyd
+  Destination=%MAINDIR%\DLLs\mmap.pyd
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\parser.pyd
+  Destination=%MAINDIR%\DLLs\parser.pyd
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\pyexpat.pyd
+  Destination=%MAINDIR%\DLLs\pyexpat.pyd
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\select.pyd
+  Destination=%MAINDIR%\DLLs\select.pyd
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\unicodedata.pyd
+  Destination=%MAINDIR%\DLLs\unicodedata.pyd
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\winsound.pyd
+  Destination=%MAINDIR%\DLLs\winsound.pyd
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\zlib.pyd
+  Destination=%MAINDIR%\DLLs\zlib.pyd
+  Flags=0000000000000010
+end
+item: Remark
+end
+item: Remark
+  Text=Link libraries (.lib); keep in synch with DLLs above, except that the Python lib lives here.
+end
+item: Install File
+  Source=.\_winreg.lib
+  Destination=%MAINDIR%\libs\_winreg.lib
+  Description=Link library files
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\_csv.lib
+  Destination=%MAINDIR%\libs\_csv.lib
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\_sre.lib
+  Destination=%MAINDIR%\libs\_sre.lib
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\_ssl.lib
+  Destination=%MAINDIR%\libs\_ssl.lib
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\_symtable.lib
+  Destination=%MAINDIR%\libs\_symtable.lib
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\_testcapi.lib
+  Destination=%MAINDIR%\libs\_testcapi.lib
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\_tkinter.lib
+  Destination=%MAINDIR%\libs\_tkinter.lib
+  Description=Extension modules
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\_socket.lib
+  Destination=%MAINDIR%\libs\_socket.lib
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\_bsddb.lib
+  Destination=%MAINDIR%\libs\_bsddb.lib
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\bz2.lib
+  Destination=%MAINDIR%\libs\bz2.lib
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\datetime.lib
+  Destination=%MAINDIR%\libs\datetime.lib
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\mmap.lib
+  Destination=%MAINDIR%\libs\mmap.lib
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\parser.lib
+  Destination=%MAINDIR%\libs\parser.lib
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\pyexpat.lib
+  Destination=%MAINDIR%\libs\pyexpat.lib
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\select.lib
+  Destination=%MAINDIR%\libs\select.lib
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\unicodedata.lib
+  Destination=%MAINDIR%\libs\unicodedata.lib
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\winsound.lib
+  Destination=%MAINDIR%\libs\winsound.lib
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\zlib.lib
+  Destination=%MAINDIR%\libs\zlib.lib
+  Flags=0000000000000010
+end
+item: Remark
+end
+item: Install File
+  Source=.\python%_pymajor_%%_pyminor_%.lib
+  Destination=%MAINDIR%\libs\python%_PYMAJOR_%%_PYMINOR_%.lib
+  Flags=0000000000000010
+end
+item: Remark
+end
+item: Remark
+  Text=Main Python DLL
+end
+item: Remark
+  Text=Tell Wise it's OK to delete the Python DLL at uninstall time,
+end
+item: Remark
+  Text=despite that we (may) write it into a system directory.
+end
+item: Add Text to INSTALL.LOG
+  Text=Non-System File:
+end
+item: Install File
+  Source=.\python%_pymajor_%%_pyminor_%.dll
+  Destination=%DLLDEST%\python%_PYMAJOR_%%_PYMINOR_%.dll
+  Flags=0000000000000010
+end
+item: Remark
+end
+item: Remark
+  Text=Libraries (Lib/)
+end
+item: Install File
+  Source=..\lib\*.py
+  Destination=%MAINDIR%\Lib
+  Description=Library Modules
+  Flags=0000000000000010
+end
+item: Remark
+end
+item: Install File
+  Source=..\lib\bsddb\*.py
+  Destination=%MAINDIR%\Lib\bsddb
+  Description=Berkeley database package
+  Flags=0000000100000010
+end
+item: Remark
+end
+item: Install File
+  Source=..\lib\compiler\*.py
+  Destination=%MAINDIR%\Lib\compiler
+  Description=Python compiler written in Python
+  Flags=0000000000000010
+end
+item: Remark
+end
+item: Install File
+  Source=..\lib\distutils\*.py
+  Destination=%MAINDIR%\Lib\distutils
+  Description=Distribution utility modules
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\lib\distutils\readme
+  Destination=%MAINDIR%\Lib\distutils\README.txt
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\lib\distutils\command\*.py
+  Destination=%MAINDIR%\Lib\distutils\command
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\lib\distutils\command\wininst.exe
+  Destination=%MAINDIR%\Lib\distutils\command\wininst.exe
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\lib\distutils\command\command_template
+  Destination=%MAINDIR%\Lib\distutils\command\command_template
+  Flags=0000000000000010
+end
+item: Remark
+end
+item: Install File
+  Source=..\lib\email\*.py
+  Destination=%MAINDIR%\Lib\email
+  Description=Library email package
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\lib\email\test\*.py
+  Destination=%MAINDIR%\Lib\email\test
+  Description=email tests
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\lib\email\test\data\*.txt
+  Destination=%MAINDIR%\Lib\email\test\data
+  Description=email test data
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\lib\email\test\data\*.gif
+  Destination=%MAINDIR%\Lib\email\test\data
+  Description=email test data
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\lib\email\test\data\*.au
+  Destination=%MAINDIR%\Lib\email\test\data
+  Description=email test data
+  Flags=0000000000000010
+end
+item: Remark
+end
+item: Install File
+  Source=..\lib\encodings\*.py
+  Destination=%MAINDIR%\Lib\encodings
+  Description=Unicode encoding tables
+  Flags=0000000000000010
+end
+item: Remark
+end
+item: Install File
+  Source=..\lib\hotshot\*.py
+  Destination=%MAINDIR%\Lib\hotshot
+  Description=Fast Python profiler
+  Flags=0000000000000010
+end
+item: Remark
+end
+item: Install File
+  Source=..\lib\lib-old\*.py
+  Destination=%MAINDIR%\Lib\lib-old
+  Description=Obsolete modules
+  Flags=0000000000000010
+end
+item: Remark
+end
+item: Install File
+  Source=..\lib\lib-tk\*.py
+  Destination=%MAINDIR%\Lib\lib-tk
+  Description=Tkinter related library modules
+  Flags=0000000000000010
+end
+item: Remark
+end
+item: Install File
+  Source=..\lib\logging\*.py
+  Destination=%MAINDIR%\Lib\logging
+  Description=Logging package
+  Flags=0000000000000010
+end
+item: Remark
+end
+item: Install File
+  Source=..\lib\site-packages\readme
+  Destination=%MAINDIR%\Lib\site-packages\README.txt
+  Description=Site packages
+  Flags=0000000000000010
+end
+item: Remark
+end
+item: Install File
+  Source=..\lib\xml\*.py
+  Destination=%MAINDIR%\Lib\xml
+  Description=XML support packages
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\lib\xml\dom\*.py
+  Destination=%MAINDIR%\Lib\xml\dom
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\lib\xml\parsers\*.py
+  Destination=%MAINDIR%\Lib\xml\parsers
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\lib\xml\sax\*.py
+  Destination=%MAINDIR%\Lib\xml\sax
+  Flags=0000000000000010
+end
+item: Remark
+end
+item: Remark
+  Text=C Include files
+end
+item: Install File
+  Source=..\include\*.h
+  Destination=%MAINDIR%\include
+  Description=Header files
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\pc\pyconfig.h
+  Destination=%MAINDIR%\include\pyconfig.h
+  Description=Header files (pyconfig.h)
+  Flags=0000000000000010
+end
+item: Remark
+end
+item: Remark
+  Text=Microsoft C runtime libraries
+end
+item: Install File
+  Source=%_SYS_%\MSVCIRT.DLL
+  Destination=%DLLDEST%\MSVCIRT.DLL
+  Description=Visual C++ Runtime DLLs
+  Flags=0000011000010011
+end
+item: Install File
+  Source=%_SYS_%\MSVCRT.DLL
+  Destination=%DLLDEST%\MSVCRT.DLL
+  Description=Visual C++ Runtime DLLs
+  Flags=0000011000010011
+end
+item: End Block
+end
+item: Remark
+end
+item: Remark
+  Text=B: Tcl/Tk (Tkinter, IDLE, pydoc)
+end
+item: If/While Statement
+  Variable=COMPONENTS
+  Value=B
+  Flags=00000010
+end
+item: Remark
+  Text=Tcl/Tk
+end
+item: Install File
+  Source=..\..\%_tcldir_%\bin\*.dll
+  Destination=%MAINDIR%\DLLs
+  Description=Tcl/Tk binaries and libraries
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\..\%_tcldir_%\lib\*.*
+  Destination=%MAINDIR%\tcl
+  Description=Tcl/Tk binaries and libraries
+  Flags=0000000100000010
+end
+item: Remark
+end
+item: Remark
+  Text=IDLE
+end
+item: Install File
+  Source=..\Lib\idlelib\*.py
+  Destination=%MAINDIR%\Lib\idlelib
+  Description=Integrated DeveLopment Environment for Python
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\Lib\idlelib\*.txt
+  Destination=%MAINDIR%\Lib\idlelib
+  Description=Integrated DeveLopment Environment for Python
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\Lib\idlelib\*.def
+  Destination=%MAINDIR%\Lib\idlelib
+  Description=Integrated DeveLopment Environment for Python
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\Lib\idlelib\Icons\*
+  Destination=%MAINDIR%\Lib\idlelib\Icons
+  Description=Integrated DeveLopment Environment for Python
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\Tools\scripts\idle
+  Destination=%MAINDIR%\Lib\idlelib\idle.pyw
+  Description=IDLE bootstrap script
+  Flags=0000000000000010
+end
+item: Remark
+end
+item: Remark
+  Text=Windows pydoc driver
+end
+item: Install File
+  Source=..\tools\scripts\*.pyw
+  Destination=%MAINDIR%\Tools\Scripts
+  Description=Windows pydoc driver
+  Flags=0000000000000010
+end
+item: End Block
+end
+item: Remark
+end
+item: Remark
+  Text=C: docs
+end
+item: If/While Statement
+  Variable=COMPONENTS
+  Value=C
+  Flags=00000010
+end
+item: Install File
+  Source=%_DOC_%\*.*
+  Destination=%MAINDIR%\Doc
+  Description=Python Documentation (HTML)
+  Flags=0000000100000010
+end
+item: End Block
+end
+item: Remark
+end
+item: Remark
+  Text=D: tools
+end
+item: If/While Statement
+  Variable=COMPONENTS
+  Value=D
+  Flags=00000010
+end
+item: Install File
+  Source=..\tools\scripts\*.py
+  Destination=%MAINDIR%\Tools\Scripts
+  Description=Utility Scripts
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\tools\scripts\*.doc
+  Destination=%MAINDIR%\Tools\Scripts
+  Description=Utility Scripts
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\tools\scripts\readme
+  Destination=%MAINDIR%\Tools\Scripts\README.txt
+  Description=Utility Scripts
+  Flags=0000000000000010
+end
+item: Remark
+end
+item: Install File
+  Source=..\tools\webchecker\*.py
+  Destination=%MAINDIR%\Tools\webchecker
+  Description=Web checker tool
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\tools\webchecker\readme
+  Destination=%MAINDIR%\Tools\webchecker\README.txt
+  Description=Web checker tool
+  Flags=0000000000000010
+end
+item: Remark
+end
+item: Install File
+  Source=..\tools\versioncheck\*.py
+  Destination=%MAINDIR%\Tools\versioncheck
+  Description=Version checker tool
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\tools\versioncheck\readme
+  Destination=%MAINDIR%\Tools\versioncheck\README.txt
+  Description=Version checker tool
+  Flags=0000000000000010
+end
+item: Remark
+end
+item: Install File
+  Source=..\tools\pynche\*.py
+  Destination=%MAINDIR%\Tools\pynche
+  Description=pynche color editor
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\tools\pynche\*.txt
+  Destination=%MAINDIR%\Tools\pynche
+  Description=pynche color editor
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\tools\pynche\x\*.txt
+  Destination=%MAINDIR%\Tools\pynche\X
+  Description=pynche color editor - X files
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\tools\pynche\readme
+  Destination=%MAINDIR%\Tools\pynche\README.txt
+  Description=pynche color editor - README
+  Flags=0000000100000010
+end
+item: Install File
+  Source=..\tools\pynche\pynche
+  Destination=%MAINDIR%\Tools\pynche\pynche.py
+  Description=pynche color editor - main
+  Flags=0000000100000010
+end
+item: Install File
+  Source=..\tools\pynche\pynche.pyw
+  Destination=%MAINDIR%\Tools\pynche\pynche.pyw
+  Description=pynche color editor - noconsole main
+  Flags=0000000100000010
+end
+item: Remark
+end
+item: Install File
+  Source=..\tools\i18n\*.py
+  Destination=%MAINDIR%\Tools\i18n
+  Description=Internationalization helpers
+  Flags=0000000000000010
+end
+item: End Block
+end
+item: Remark
+end
+item: Remark
+  Text=E: test suite
+end
+item: If/While Statement
+  Variable=COMPONENTS
+  Value=E
+  Flags=00000010
+end
+item: Install File
+  Source=..\lib\test\audiotest.au
+  Destination=%MAINDIR%\Lib\test\audiotest.au
+  Description=Python Test files
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\lib\test\*.uue
+  Destination=%MAINDIR%\Lib\test
+  Description=Python Test files
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\lib\test\*.py
+  Destination=%MAINDIR%\Lib\test
+  Description=Python Test files
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\lib\test\*.xml
+  Destination=%MAINDIR%\Lib\test
+  Description=Python Test files
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\lib\test\*.out
+  Destination=%MAINDIR%\Lib\test
+  Description=Python Test files
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\lib\test\*.bz2
+  Destination=%MAINDIR%\Lib\test
+  Description=Python Test files
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\lib\test\*.tar
+  Destination=%MAINDIR%\Lib\test
+  Description=Python Test files
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\lib\test\*.gz
+  Destination=%MAINDIR%\Lib\test
+  Description=Python Test files
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\lib\test\*.txt
+  Destination=%MAINDIR%\Lib\test
+  Description=Python Test files
+  Flags=0000000000000010
+end
+item: Remark
+end
+item: Install File
+  Source=..\lib\test\output\*.*
+  Destination=%MAINDIR%\Lib\test\output
+  Description=Python Test output files
+  Flags=0000000000000010
+end
+item: End Block
+end
+item: Remark
+end
+item: Remark
+  Text=DONE with file copying.
+end
+item: Remark
+  Text=The rest is registry and Start Menu fiddling.
+end
+item: Remark
+end
+item: If/While Statement
+  Variable=COMPONENTS
+  Value=A
+  Flags=00000010
+end
+item: If/While Statement
+  Variable=TASKS
+  Value=A
+  Flags=00000010
+end
+item: Remark
+  Text=Register file extensions.  As usual, Admin privs get in the way, but with a twist:
+end
+item: Remark
+  Text=You don't need admin privs to write to HKEY_CLASSES_ROOT *except* under Win2K.
+end
+item: Remark
+  Text=On Win2K, a user without Admin privs has to register extensions under HKCU\Software\CLASSES instead.
+end
+item: Remark
+  Text=But while you can *do* that under other flavors of Windows too, it has no useful effect except in Win2K.
+end
+item: Set Variable
+  Variable=USE_HKCR
+  Value=1
+end
+item: Check Configuration
+  Flags=11110010
+end
+item: If/While Statement
+  Variable=DOADMIN
+  Value=0
+end
+item: Set Variable
+  Variable=USE_HKCR
+  Value=0
+end
+item: End Block
+end
+item: End Block
+end
+item: If/While Statement
+  Variable=USE_HKCR
+  Value=1
+end
+item: Remark
+  Text=File types.
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Python.File
+  New Value=Python File
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Python.File\shell\open\command
+  New Value=%MAINDIR%\python.exe "%%1" %%*
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Python.File\DefaultIcon
+  New Value=%MAINDIR%\Py.ico
+end
+item: Remark
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Python.NoConFile
+  New Value=Python File (no console)
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Python.NoConFile\shell\open\command
+  New Value=%MAINDIR%\pythonw.exe "%%1" %%*
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Python.NoConFile\DefaultIcon
+  New Value=%MAINDIR%\Py.ico
+end
+item: Remark
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Python.CompiledFile
+  New Value=Compiled Python File
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Python.CompiledFile\shell\open\command
+  New Value=%MAINDIR%\python.exe "%%1" %%*
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Python.CompiledFile\DefaultIcon
+  New Value=%MAINDIR%\pyc.ico
+end
+item: Remark
+end
+item: Remark
+  Text=File extensions.
+end
+item: Edit Registry
+  Total Keys=1
+  Key=.py
+  New Value=Python.File
+end
+item: Edit Registry
+  Total Keys=1
+  Key=.py
+  New Value=text/plain
+  Value Name=Content Type
+end
+item: Remark
+end
+item: Edit Registry
+  Total Keys=1
+  Key=.pyw
+  New Value=Python.NoConFile
+end
+item: Edit Registry
+  Total Keys=1
+  Key=.pyw
+  New Value=text/plain
+  Value Name=Content Type
+end
+item: Remark
+end
+item: Edit Registry
+  Total Keys=1
+  Key=.pyc
+  New Value=Python.CompiledFile
+end
+item: Edit Registry
+  Total Keys=1
+  Key=.pyo
+  New Value=Python.CompiledFile
+end
+item: Else Statement
+end
+item: Remark
+  Text=File types.
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\CLASSES\Python.File
+  New Value=Python File
+  Root=1
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\CLASSES\Python.File\shell\open\command
+  New Value=%MAINDIR%\python.exe "%%1" %%*
+  Root=1
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\CLASSES\Python.File\DefaultIcon
+  New Value=%MAINDIR%\Py.ico
+  Root=1
+end
+item: Remark
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\CLASSES\Python.NoConFile
+  New Value=Python File (no console)
+  Root=1
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\CLASSES\Python.NoConFile\shell\open\command
+  New Value=%MAINDIR%\pythonw.exe "%%1" %%*
+  Root=1
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\CLASSES\Python.NoConFile\DefaultIcon
+  New Value=%MAINDIR%\Py.ico
+  Root=1
+end
+item: Remark
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\CLASSES\Python.CompiledFile
+  New Value=Compiled Python File
+  Root=1
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\CLASSES\Python.CompiledFile\shell\open\command
+  New Value=%MAINDIR%\python.exe "%%1" %%*
+  Root=1
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\CLASSES\Python.CompiledFile\DefaultIcon
+  New Value=%MAINDIR%\pyc.ico
+  Root=1
+end
+item: Remark
+end
+item: Remark
+  Text=File extensions.
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\CLASSES\.py
+  New Value=Python.File
+  Root=1
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\CLASSES\.py
+  New Value=text/plain
+  Value Name=Content Type
+  Root=1
+end
+item: Remark
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\CLASSES\.pyw
+  New Value=Python.NoConFile
+  Root=1
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\CLASSES\.pyw
+  New Value=text/plain
+  Value Name=Content Type
+  Root=1
+end
+item: Remark
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\CLASSES\.pyc
+  New Value=Python.CompiledFile
+  Root=1
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\CLASSES\.pyo
+  New Value=Python.CompiledFile
+  Root=1
+end
+item: End Block
+end
+item: Remark
+end
+item: Remark
+  Text=If we're installing IDLE, also set an Edit context menu action to use IDLE, for .py and .pyw files.
+end
+item: If/While Statement
+  Variable=COMPONENTS
+  Value=B
+  Flags=00000010
+end
+item: If/While Statement
+  Variable=USE_HKCR
+  Value=1
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Python.NoConFile\shell\Edit with IDLE\command
+  New Value=%MAINDIR%\pythonw.exe %MAINDIR%\Lib\idlelib\idle.pyw -n -e "%%1"
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Python.File\shell\Edit with IDLE\command
+  New Value=%MAINDIR%\pythonw.exe %MAINDIR%\Lib\idlelib\idle.pyw -n -e "%%1"
+end
+item: Else Statement
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\CLASSES\Python.NoConFile\shell\Edit with IDLE\command
+  New Value=%MAINDIR%\pythonw.exe %MAINDIR%\Lib\idlelib\idle.pyw -n -e "%%1"
+  Root=1
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\CLASSES\Python.File\shell\Edit with IDLE\command
+  New Value=%MAINDIR%\pythonw.exe %MAINDIR%\Lib\idlelib\idle.pyw -n -e "%%1"
+  Root=1
+end
+item: End Block
+end
+item: End Block
+end
+item: End Block
+end
+item: Remark
+end
+item: Remark
+  Text=Register Python paths.
+end
+item: Remark
+  Text=Write to HKLM for admin, else HKCU.  Keep these blocks otherwise identical!
+end
+item: If/While Statement
+  Variable=DOADMIN
+  Value=1
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Python\PythonCore\CurrentVersion
+  Root=130
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Python\PythonCore\%PY_VERSION%\InstallPath
+  New Value=%MAINDIR%
+  Root=2
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Python\PythonCore\%PY_VERSION%\InstallPath\InstallGroup
+  New Value=%CGROUP_SAVE%
+  New Value=
+  Root=2
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Python\PythonCore\%PY_VERSION%\PythonPath
+  New Value=%MAINDIR%\Lib;%MAINDIR%\DLLs;%MAINDIR%\Lib\lib-tk
+  New Value=
+  Root=2
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Python\PythonCore\%PY_VERSION%\Modules
+  Root=2
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Microsoft\Windows\CurrentVersion\App Paths\Python.exe
+  New Value=%MAINDIR%\Python.exe
+  Root=2
+end
+item: Else Statement
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Python\PythonCore\CurrentVersion
+  Root=129
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Python\PythonCore\%PY_VERSION%\InstallPath
+  New Value=%MAINDIR%
+  Root=1
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Python\PythonCore\%PY_VERSION%\InstallPath\InstallGroup
+  New Value=%CGROUP_SAVE%
+  New Value=
+  Root=1
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Python\PythonCore\%PY_VERSION%\PythonPath
+  New Value=%MAINDIR%\Lib;%MAINDIR%\DLLs;%MAINDIR%\Lib\lib-tk
+  New Value=
+  Root=1
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Python\PythonCore\%PY_VERSION%\Modules
+  Root=1
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Microsoft\Windows\CurrentVersion\App Paths\Python.exe
+  New Value=%MAINDIR%\Python.exe
+  Root=1
+end
+item: End Block
+end
+item: End Block
+end
+item: Remark
+end
+item: Remark
+  Text=Registry fiddling for docs.
+end
+item: Remark
+  Text=Write to HKLM for admin, else HKCU.  Keep these blocks otherwise identical!
+end
+item: If/While Statement
+  Variable=COMPONENTS
+  Value=C
+  Flags=00000010
+end
+item: If/While Statement
+  Variable=DOADMIN
+  Value=1
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Python\PythonCore\%PY_VERSION%\Help\Main Python Documentation
+  New Value=%MAINDIR%\Doc\index.html
+  Root=2
+end
+item: Else Statement
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Python\PythonCore\%PY_VERSION%\Help\Main Python Documentation
+  New Value=%MAINDIR%\Doc\index.html
+  Root=1
+end
+item: End Block
+end
+item: End Block
+end
+item: Remark
+end
+item: Remark
+  Text=Set the app publisher and URL entries for Win2K add/remove.
+end
+item: Remark
+  Text=It doesn't hurt on other systems.
+end
+item: Remark
+  Text=As usual, write to HKLM or HKCU depending on Admin privs.
+end
+item: Remark
+  Text=CAUTION:  If you set this info on the "Windows 2000" page (step 6) of the
+end
+item: Remark
+  Text=Installation Expert, it only shows up in the "If" block below.  Keep in synch!
+end
+item: If/While Statement
+  Variable=DOADMIN
+  Value=1
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Microsoft\Windows\CurrentVersion\Uninstall\%APPTITLE%
+  New Value=http://www.python.org/
+  Value Name=HelpLink
+  Root=2
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Microsoft\Windows\CurrentVersion\Uninstall\%APPTITLE%
+  New Value=PythonLabs at Zope Corporation
+  Value Name=Publisher
+  Root=2
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Microsoft\Windows\CurrentVersion\Uninstall\%APPTITLE%
+  New Value=http://www.python.org/
+  Value Name=URLInfoAbout
+  Root=2
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Microsoft\Windows\CurrentVersion\Uninstall\%APPTITLE%
+  New Value=%PYVER_STRING%
+  Value Name=DisplayVersion
+  Root=2
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Microsoft\Windows\CurrentVersion\Uninstall\%APPTITLE%
+  New Value=%MAINDIR%\py.ico,-0
+  Value Name=DisplayIcon
+  Root=2
+end
+item: Else Statement
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Microsoft\Windows\CurrentVersion\Uninstall\%APPTITLE%
+  New Value=http://www.python.org/
+  Value Name=HelpLink
+  Root=1
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Microsoft\Windows\CurrentVersion\Uninstall\%APPTITLE%
+  New Value=PythonLabs at Zope Corporation
+  Value Name=Publisher
+  Root=1
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Microsoft\Windows\CurrentVersion\Uninstall\%APPTITLE%
+  New Value=http://www.python.org/
+  Value Name=URLInfoAbout
+  Root=1
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Microsoft\Windows\CurrentVersion\Uninstall\%APPTITLE%
+  New Value=%PYVER_STRING%
+  Value Name=DisplayVersion
+  Root=1
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Microsoft\Windows\CurrentVersion\Uninstall\%APPTITLE%
+  New Value=%MAINDIR%\py.ico,-0
+  Value Name=DisplayIcon
+  Root=1
+end
+item: End Block
+end
+item: Remark
+end
+item: Remark
+  Text=Populate Start Menu group
+end
+item: If/While Statement
+  Variable=TASKS
+  Value=B
+  Flags=00000010
+end
+item: Remark
+  Text=Shortcut to installer no matter what.
+end
+item: Create Shortcut
+  Source=%MAINDIR%\unwise.exe
+  Destination=%GROUP%\Uninstall Python.lnk
+  Working Directory=%MAINDIR%
+  Key Type=1536
+  Flags=00000001
+end
+item: Remark
+end
+item: If/While Statement
+  Variable=COMPONENTS
+  Value=A
+  Flags=00000010
+end
+item: Create Shortcut
+  Source=%MAINDIR%\python.exe
+  Destination=%GROUP%\Python (command line).lnk
+  Working Directory=%MAINDIR%
+  Icon Pathname=%MAINDIR%\pycon.ico
+  Key Type=1536
+  Flags=00000001
+end
+item: End Block
+end
+item: Remark
+end
+item: If/While Statement
+  Variable=COMPONENTS
+  Value=B
+  Flags=00000010
+end
+item: Create Shortcut
+  Source=%MAINDIR%\pythonw.exe
+  Destination=%GROUP%\IDLE (Python GUI).lnk
+  Command Options="%MAINDIR%\Lib\idlelib\idle.pyw"
+  Working Directory=%MAINDIR%
+  Key Type=1536
+  Flags=00000001
+end
+item: Create Shortcut
+  Source=%MAINDIR%\pythonw.exe
+  Destination=%GROUP%\Module Docs.lnk
+  Command Options="%MAINDIR%\Tools\Scripts\pydocgui.pyw"
+  Working Directory=%MAINDIR%
+  Key Type=1536
+  Flags=00000001
+end
+item: End Block
+end
+item: Remark
+end
+item: If/While Statement
+  Variable=COMPONENTS
+  Value=C
+  Flags=00000010
+end
+item: Create Shortcut
+  Source=%MAINDIR%\Doc\index.html
+  Destination=%GROUP%\Python Manuals.lnk
+  Working Directory=%MAINDIR%
+  Key Type=1536
+  Flags=00000001
+end
+item: End Block
+end
+item: End Block
+end
+item: Remark
+end
+item: Remark
+  Text=I don't think we need this, but have always done it.
+end
+item: Self-Register OCXs/DLLs
+  Description=Updating System Configuration, Please Wait...
+end
+item: Remark
+end
+remarked item: Remark
+  Text=Don't enable "Delete in-use files".  Here's what happens:
+end
+remarked item: Remark
+  Text=Install Python; uninstall Python; install Python again.  Reboot the machine.
+end
+remarked item: Remark
+  Text=Now UNWISE.EXE is missing.  I think this is a Wise bug, but so it goes.
+end
+remarked item: Add Text to INSTALL.LOG
+  Text=Delete in-use files: On
+end
+item: Remark
+end
+item: Wizard Block
+  Direction Variable=DIRECTION
+  Display Variable=DISPLAY
+  Bitmap Pathname=.\installer.bmp
+  X Position=9
+  Y Position=10
+  Filler Color=11173759
+  Flags=00000011
+end
+item: Custom Dialog Set
+  Name=Finished
+  Display Variable=DISPLAY
+  item: Dialog
+    Title=%APPTITLE% Installation
+    Title French=Installation de %APPTITLE%
+    Title German=Installation von %APPTITLE%
+    Title Spanish=Instalación de %APPTITLE%
+    Title Italian=Installazione di %APPTITLE%
+    Width=339
+    Height=280
+    Font Name=Helv
+    Font Size=8
+    item: Push Button
+      Rectangle=188 234 244 253
+      Variable=DIRECTION
+      Value=N
+      Create Flags=01010000000000010000000000000001
+      Text=&Finish
+      Text French=&Fin
+      Text German=&Weiter
+      Text Spanish=&Terminar
+      Text Italian=&Fine
+    end
+    item: Push Button
+      Rectangle=264 234 320 253
+      Variable=DISABLED
+      Value=!
+      Action=3
+      Create Flags=01010000000000010000000000000000
+      Text=&Cancel
+      Text French=&Annuler
+      Text German=&Abbrechen
+      Text Spanish=&Cancelar
+      Text Italian=&Annulla
+    end
+    item: Static
+      Rectangle=108 10 323 48
+      Create Flags=01010000000000000000000000000000
+      Flags=0000000000000001
+      Name=Times New Roman
+      Font Style=-24 0 0 0 700 255 0 0 0 3 2 1 18
+      Text=Installation Completed!
+      Text French=Installation terminée !
+      Text German=Die Installation ist abgeschlossen!
+      Text Spanish=¡Instalación terminada!
+      Text Italian=Installazione completata!
+    end
+    item: Static
+      Rectangle=108 44 320 82
+      Create Flags=01010000000000000000000000000000
+      Text=%APPTITLE% has been successfully installed.
+      Text=
+      Text=Press the Finish button to exit this installation.
+      Text French=%APPTITLE% est maintenant installé.
+      Text French=
+      Text French=Cliquez sur le bouton Fin pour quitter l'installation.
+      Text German=%APPTITLE% wurde erfolgreich installiert.
+      Text German=
+      Text German=Klicken Sie auf "Weiter", um die Installation zu beenden.
+      Text Spanish=%APPTITLE% se ha instalado con éxito.
+      Text Spanish=
+      Text Spanish=Presione el botón Terminar para salir de esta instalación.
+      Text Italian=L'installazione %APPTITLE% è stata portata a termine con successo.
+      Text Italian=
+      Text Italian=Premere il pulsante Fine per uscire dall'installazione.
+    end
+    item: Static
+      Rectangle=10 225 320 226
+      Action=3
+      Create Flags=01010000000000000000000000000111
+    end
+    item: Static
+      Rectangle=106 105 312 210
+      Enabled Color=00000000000000001111111111111111
+      Create Flags=01010000000000000000000000000000
+      Text=Special Windows thanks to:
+      Text=
+      Text=Wise Solutions, for the use of InstallMaster 8.1.
+      Text=    http://www.wisesolutions.com/
+      Text=
+      Text=
+      Text=LettError, Erik van Blokland, for the Python for Windows graphic.
+      Text=    http://www.letterror.com/
+      Text=
+      Text=
+      Text=Mark Hammond, without whose years of freely shared Windows expertise, Python for Windows would still be Python for DOS.
+    end
+    item: Static
+      Rectangle=106 95 312 96
+      Action=3
+      Enabled Color=00000000000000001111111111111111
+      Create Flags=01010000000000000000000000001001
+    end
+  end
+end
+item: End Block
+end
+item: New Event
+  Name=Cancel
+end
+item: Remark
+  Text=This include script supports a rollback to preinstallation state if the user chooses to cancel before the installation is complete.
+end
+item: Include Script
+  Pathname=%_WISE_%\INCLUDE\rollback.wse
+end

Added: vendor/Python/current/PCbuild/pythoncore.vcproj
===================================================================
--- vendor/Python/current/PCbuild/pythoncore.vcproj	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild/pythoncore.vcproj	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,799 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="pythoncore"
+	ProjectGUID="{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}"
+	RootNamespace="pythoncore"
+	SccProjectName="pythoncore"
+	SccLocalPath="..">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-release\pythoncore"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions="/Zm200 "
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;USE_DL_EXPORT"
+				StringPooling="TRUE"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="getbuildinfo.o"
+				OutputFile="./python25.dll"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				IgnoreDefaultLibraryNames="libc"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./python25.pdb"
+				SubSystem="2"
+				BaseAddress="0x1e000000"
+				ImportLibrary=".\./python25.lib"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				Description="generate buildinfo"
+				CommandLine="make_buildinfo.exe $(ConfigurationName)"/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"
+				AdditionalIncludeDirectories="..\Include"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-debug\pythoncore"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions="/Zm200 "
+				Optimization="0"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="_DEBUG;USE_DL_EXPORT;WIN32;_WINDOWS"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="getbuildinfo.o"
+				OutputFile="./python25_d.dll"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				IgnoreDefaultLibraryNames="libc"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./python25_d.pdb"
+				SubSystem="2"
+				BaseAddress="0x1e000000"
+				ImportLibrary=".\./python25_d.lib"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				Description="generate buildinfo"
+				CommandLine="make_buildinfo.exe $(ConfigurationName)"/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="_DEBUG"
+				Culture="1033"
+				AdditionalIncludeDirectories="..\Include"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseItanium|Win32"
+			OutputDirectory="./."
+			IntermediateDirectory=".\ia64-temp-release\pythoncore"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions=" /USECL:MS_ITANIUM /GS-"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;USE_DL_EXPORT"
+				StringPooling="TRUE"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="FALSE"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions=" /MACHINE:IA64 /USELINK:MS_SDK"
+				AdditionalDependencies="getbuildinfo.o"
+				OutputFile="./python25.dll"
+				LinkIncremental="1"
+				SuppressStartupBanner="FALSE"
+				IgnoreDefaultLibraryNames="libc"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./python25.pdb"
+				SubSystem="2"
+				BaseAddress="0x1e000000"
+				ImportLibrary=".\./python25.lib"
+				TargetMachine="0"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				Description="generate buildinfo"
+				CommandLine="make_buildinfo.exe $(ConfigurationName)"/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"
+				AdditionalIncludeDirectories="..\Include"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseAMD64|Win32"
+			OutputDirectory="./."
+			IntermediateDirectory=".\amd64-temp-release\pythoncore"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions="/Zm200  /USECL:MS_OPTERON /GS-"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;USE_DL_EXPORT"
+				StringPooling="TRUE"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="FALSE"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions=" /MACHINE:AMD64 /USELINK:MS_SDK"
+				AdditionalDependencies="getbuildinfo.o"
+				OutputFile="./python25.dll"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				IgnoreDefaultLibraryNames="libc"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./python25.pdb"
+				SubSystem="2"
+				BaseAddress="0x1e000000"
+				ImportLibrary=".\./python25.lib"
+				TargetMachine="0"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				Description="generate buildinfo"
+				CommandLine="make_buildinfo.exe $(ConfigurationName)"/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"
+				AdditionalIncludeDirectories="..\Include"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="zlib"
+			Filter="">
+			<File
+				RelativePath="..\Modules\zlib\adler32.c">
+			</File>
+			<File
+				RelativePath="..\Modules\zlib\compress.c">
+			</File>
+			<File
+				RelativePath="..\Modules\zlib\crc32.c">
+			</File>
+			<File
+				RelativePath="..\Modules\zlib\deflate.c">
+			</File>
+			<File
+				RelativePath="..\Modules\zlib\gzio.c">
+			</File>
+			<File
+				RelativePath="..\Modules\zlib\infback.c">
+			</File>
+			<File
+				RelativePath="..\Modules\zlib\inffast.c">
+			</File>
+			<File
+				RelativePath="..\Modules\zlib\inflate.c">
+			</File>
+			<File
+				RelativePath="..\Modules\zlib\inftrees.c">
+			</File>
+			<File
+				RelativePath="..\Modules\zlib\trees.c">
+			</File>
+			<File
+				RelativePath="..\Modules\zlib\uncompr.c">
+			</File>
+			<File
+				RelativePath="..\Modules\zlibmodule.c">
+				<FileConfiguration
+					Name="Release|Win32">
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories="..\Modules\zlib"/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32">
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories="..\Modules\zlib"/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="ReleaseItanium|Win32">
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories="..\Modules\zlib"/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="ReleaseAMD64|Win32">
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories="..\Modules\zlib"/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\Modules\zlib\zutil.c">
+			</File>
+		</Filter>
+		<File
+			RelativePath="..\Modules\_bisectmodule.c">
+		</File>
+		<File
+			RelativePath="..\Modules\cjkcodecs\_codecs_cn.c">
+		</File>
+		<File
+			RelativePath="..\Modules\cjkcodecs\_codecs_hk.c">
+		</File>
+		<File
+			RelativePath="..\Modules\cjkcodecs\_codecs_iso2022.c">
+		</File>
+		<File
+			RelativePath="..\Modules\cjkcodecs\_codecs_jp.c">
+		</File>
+		<File
+			RelativePath="..\Modules\cjkcodecs\_codecs_kr.c">
+		</File>
+		<File
+			RelativePath="..\Modules\cjkcodecs\_codecs_tw.c">
+		</File>
+		<File
+			RelativePath="..\Modules\_codecsmodule.c">
+		</File>
+		<File
+			RelativePath="..\Modules\_csv.c">
+		</File>
+		<File
+			RelativePath="..\Modules\_functoolsmodule.c">
+		</File>
+		<File
+			RelativePath="..\Modules\_heapqmodule.c">
+		</File>
+		<File
+			RelativePath="..\Modules\_hotshot.c">
+		</File>
+		<File
+			RelativePath="..\Modules\_localemodule.c">
+		</File>
+		<File
+			RelativePath="..\Modules\_lsprof.c">
+		</File>
+		<File
+			RelativePath="..\Modules\_randommodule.c">
+		</File>
+		<File
+			RelativePath="..\Modules\_sre.c">
+		</File>
+		<File
+			RelativePath="..\Modules\_struct.c">
+		</File>
+		<File
+			RelativePath="..\Pc\_subprocess.c">
+		</File>
+		<File
+			RelativePath="..\Modules\_typesmodule.c">
+		</File>
+		<File
+			RelativePath="..\Modules\_weakref.c">
+		</File>
+		<File
+			RelativePath="..\Pc\_winreg.c">
+		</File>
+		<File
+			RelativePath="..\Objects\abstract.c">
+		</File>
+		<File
+			RelativePath="..\Parser\acceler.c">
+		</File>
+		<File
+			RelativePath="..\Modules\arraymodule.c">
+		</File>
+		<File
+			RelativePath="..\Python\asdl.c">
+		</File>
+		<File
+			RelativePath="..\Python\ast.c">
+		</File>
+		<File
+			RelativePath="..\Modules\audioop.c">
+		</File>
+		<File
+			RelativePath="..\Modules\binascii.c">
+		</File>
+		<File
+			RelativePath="..\Parser\bitset.c">
+		</File>
+		<File
+			RelativePath="..\Python\bltinmodule.c">
+		</File>
+		<File
+			RelativePath="..\Objects\boolobject.c">
+		</File>
+		<File
+			RelativePath="..\Objects\bufferobject.c">
+		</File>
+		<File
+			RelativePath="..\Objects\cellobject.c">
+		</File>
+		<File
+			RelativePath="..\Python\ceval.c">
+		</File>
+		<File
+			RelativePath="..\Objects\classobject.c">
+		</File>
+		<File
+			RelativePath="..\Modules\cmathmodule.c">
+		</File>
+		<File
+			RelativePath="..\Objects\cobject.c">
+		</File>
+		<File
+			RelativePath="..\Python\codecs.c">
+		</File>
+		<File
+			RelativePath="..\Objects\codeobject.c">
+		</File>
+		<File
+			RelativePath="..\Modules\collectionsmodule.c">
+		</File>
+		<File
+			RelativePath="..\Python\compile.c">
+		</File>
+		<File
+			RelativePath="..\Objects\complexobject.c">
+		</File>
+		<File
+			RelativePath="..\PC\config.c">
+		</File>
+		<File
+			RelativePath="..\Modules\cPickle.c">
+		</File>
+		<File
+			RelativePath="..\Modules\cStringIO.c">
+		</File>
+		<File
+			RelativePath="..\Modules\datetimemodule.c">
+		</File>
+		<File
+			RelativePath="..\Objects\descrobject.c">
+		</File>
+		<File
+			RelativePath="..\Objects\dictobject.c">
+		</File>
+		<File
+			RelativePath="..\PC\dl_nt.c">
+		</File>
+		<File
+			RelativePath="..\Python\dynload_win.c">
+		</File>
+		<File
+			RelativePath="..\Objects\enumobject.c">
+		</File>
+		<File
+			RelativePath="..\Modules\errnomodule.c">
+		</File>
+		<File
+			RelativePath="..\Python\errors.c">
+		</File>
+		<File
+			RelativePath="..\Objects\exceptions.c">
+		</File>
+		<File
+			RelativePath="..\Objects\fileobject.c">
+		</File>
+		<File
+			RelativePath="..\Parser\firstsets.c">
+		</File>
+		<File
+			RelativePath="..\Objects\floatobject.c">
+		</File>
+		<File
+			RelativePath="..\Objects\frameobject.c">
+		</File>
+		<File
+			RelativePath="..\Python\frozen.c">
+		</File>
+		<File
+			RelativePath="..\Objects\funcobject.c">
+		</File>
+		<File
+			RelativePath="..\Python\future.c">
+		</File>
+		<File
+			RelativePath="..\Modules\gcmodule.c">
+		</File>
+		<File
+			RelativePath="..\Objects\genobject.c">
+		</File>
+		<File
+			RelativePath="..\Python\getargs.c">
+		</File>
+		<File
+			RelativePath="..\Python\getcompiler.c">
+		</File>
+		<File
+			RelativePath="..\Python\getcopyright.c">
+		</File>
+		<File
+			RelativePath="..\Python\getmtime.c">
+		</File>
+		<File
+			RelativePath="..\Python\getopt.c">
+		</File>
+		<File
+			RelativePath="..\PC\getpathp.c">
+		</File>
+		<File
+			RelativePath="..\Python\getplatform.c">
+		</File>
+		<File
+			RelativePath="..\Python\getversion.c">
+		</File>
+		<File
+			RelativePath="..\Python\graminit.c">
+		</File>
+		<File
+			RelativePath="..\Parser\grammar.c">
+		</File>
+		<File
+			RelativePath="..\Parser\grammar1.c">
+		</File>
+		<File
+			RelativePath="..\Modules\imageop.c">
+		</File>
+		<File
+			RelativePath="..\Python\import.c">
+		</File>
+		<File
+			RelativePath="..\PC\import_nt.c">
+			<FileConfiguration
+				Name="Release|Win32">
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories="..\Python"/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Debug|Win32">
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories="..\Python"/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="ReleaseItanium|Win32">
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories="..\Python"/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="ReleaseAMD64|Win32">
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories="..\Python"/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\Python\importdl.c">
+		</File>
+		<File
+			RelativePath="..\Objects\intobject.c">
+		</File>
+		<File
+			RelativePath="..\Objects\iterobject.c">
+		</File>
+		<File
+			RelativePath="..\Modules\itertoolsmodule.c">
+		</File>
+		<File
+			RelativePath="..\Parser\listnode.c">
+		</File>
+		<File
+			RelativePath="..\Objects\listobject.c">
+		</File>
+		<File
+			RelativePath="..\Objects\longobject.c">
+		</File>
+		<File
+			RelativePath="..\Modules\main.c">
+		</File>
+		<File
+			RelativePath="..\Python\marshal.c">
+		</File>
+		<File
+			RelativePath="..\Modules\mathmodule.c">
+		</File>
+		<File
+			RelativePath="..\Modules\md5.c">
+		</File>
+		<File
+			RelativePath="..\Modules\md5module.c">
+		</File>
+		<File
+			RelativePath="..\Parser\metagrammar.c">
+		</File>
+		<File
+			RelativePath="..\Objects\methodobject.c">
+		</File>
+		<File
+			RelativePath="..\Modules\mmapmodule.c">
+		</File>
+		<File
+			RelativePath="..\Python\modsupport.c">
+		</File>
+		<File
+			RelativePath="..\Objects\moduleobject.c">
+		</File>
+		<File
+			RelativePath="..\PC\msvcrtmodule.c">
+		</File>
+		<File
+			RelativePath="..\Modules\cjkcodecs\multibytecodec.c">
+		</File>
+		<File
+			RelativePath="..\Parser\myreadline.c">
+		</File>
+		<File
+			RelativePath="..\Python\mysnprintf.c">
+		</File>
+		<File
+			RelativePath="..\Python\mystrtoul.c">
+		</File>
+		<File
+			RelativePath="..\Parser\node.c">
+		</File>
+		<File
+			RelativePath="..\Objects\object.c">
+		</File>
+		<File
+			RelativePath="..\Objects\obmalloc.c">
+		</File>
+		<File
+			RelativePath="..\Modules\operator.c">
+		</File>
+		<File
+			RelativePath="..\Parser\parser.c">
+		</File>
+		<File
+			RelativePath="..\Modules\parsermodule.c">
+		</File>
+		<File
+			RelativePath="..\Parser\parsetok.c">
+		</File>
+		<File
+			RelativePath="..\Modules\posixmodule.c">
+		</File>
+		<File
+			RelativePath="..\Python\pyarena.c">
+		</File>
+		<File
+			RelativePath="..\Python\pyfpe.c">
+		</File>
+		<File
+			RelativePath="..\Python\pystate.c">
+		</File>
+		<File
+			RelativePath="..\Python\pystrtod.c">
+		</File>
+		<File
+			RelativePath="..\Python\Python-ast.c">
+		</File>
+		<File
+			RelativePath="..\PC\python_nt.rc">
+		</File>
+		<File
+			RelativePath="..\Python\pythonrun.c">
+		</File>
+		<File
+			RelativePath="..\Objects\rangeobject.c">
+		</File>
+		<File
+			RelativePath="..\Modules\rgbimgmodule.c">
+		</File>
+		<File
+			RelativePath="..\Modules\rotatingtree.c">
+		</File>
+		<File
+			RelativePath="..\Objects\setobject.c">
+		</File>
+		<File
+			RelativePath="..\Modules\sha256module.c">
+		</File>
+		<File
+			RelativePath="..\Modules\sha512module.c">
+		</File>
+		<File
+			RelativePath="..\Modules\shamodule.c">
+		</File>
+		<File
+			RelativePath="..\Modules\signalmodule.c">
+		</File>
+		<File
+			RelativePath="..\Objects\sliceobject.c">
+		</File>
+		<File
+			RelativePath="..\Objects\stringobject.c">
+		</File>
+		<File
+			RelativePath="..\Modules\stropmodule.c">
+		</File>
+		<File
+			RelativePath="..\Python\structmember.c">
+		</File>
+		<File
+			RelativePath="..\Objects\structseq.c">
+		</File>
+		<File
+			RelativePath="..\Python\symtable.c">
+		</File>
+		<File
+			RelativePath="..\Modules\symtablemodule.c">
+		</File>
+		<File
+			RelativePath="..\Python\sysmodule.c">
+		</File>
+		<File
+			RelativePath="..\Python\thread.c">
+		</File>
+		<File
+			RelativePath="..\Modules\threadmodule.c">
+		</File>
+		<File
+			RelativePath="..\Modules\timemodule.c">
+		</File>
+		<File
+			RelativePath="..\Parser\tokenizer.c">
+		</File>
+		<File
+			RelativePath="..\Python\traceback.c">
+		</File>
+		<File
+			RelativePath="..\Objects\tupleobject.c">
+		</File>
+		<File
+			RelativePath="..\Objects\typeobject.c">
+		</File>
+		<File
+			RelativePath="..\Objects\unicodectype.c">
+		</File>
+		<File
+			RelativePath="..\Objects\unicodeobject.c">
+		</File>
+		<File
+			RelativePath="..\Objects\weakrefobject.c">
+		</File>
+		<File
+			RelativePath="..\Modules\xxsubtype.c">
+		</File>
+		<File
+			RelativePath="..\Modules\yuvconvert.c">
+		</File>
+		<File
+			RelativePath="..\Modules\zipimport.c">
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Added: vendor/Python/current/PCbuild/pythonw.vcproj
===================================================================
--- vendor/Python/current/PCbuild/pythonw.vcproj	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild/pythonw.vcproj	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,261 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="pythonw"
+	SccProjectName="pythonw"
+	SccLocalPath="..\pc">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-debug\pythonw"
+			ConfigurationType="1"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="./pythonw_d.exe"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./pythonw_d.pdb"
+				SubSystem="2"
+				StackReserveSize="2000000"
+				BaseAddress="0x1d000000"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="_DEBUG"
+				Culture="1033"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-release\pythonw"
+			ConfigurationType="1"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+				StringPooling="TRUE"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile=".\./pythonw.exe"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./pythonw.pdb"
+				SubSystem="2"
+				StackReserveSize="2000000"
+				BaseAddress="0x1d000000"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseItanium|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\ia64-temp-release\pythonw"
+			ConfigurationType="1"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions=" /USECL:MS_ITANIUM /GS-"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+				StringPooling="TRUE"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="FALSE"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions=" /MACHINE:IA64 /USELINK:MS_SDK"
+				OutputFile=".\./pythonw.exe"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./pythonw.pdb"
+				SubSystem="2"
+				StackReserveSize="2000000"
+				BaseAddress="0x1d000000"
+				TargetMachine="0"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseAMD64|Win32"
+			OutputDirectory="."
+			IntermediateDirectory="amd64-temp-release\pythonw"
+			ConfigurationType="1"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions=" /USECL:MS_OPTERON"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+				StringPooling="TRUE"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="FALSE"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions=" /MACHINE:AMD64 /USELINK:MS_SDK"
+				OutputFile=".\./pythonw.exe"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./pythonw.pdb"
+				SubSystem="2"
+				StackReserveSize="2000000"
+				BaseAddress="0x1d000000"
+				TargetMachine="0"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath="..\PC\python_exe.rc">
+		</File>
+		<File
+			RelativePath="..\PC\WinMain.c">
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Added: vendor/Python/current/PCbuild/readme.txt
===================================================================
--- vendor/Python/current/PCbuild/readme.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild/readme.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,426 @@
+Building Python using VC++ 7.1
+-------------------------------------
+This directory is used to build Python for Win32 platforms, e.g. Windows
+95, 98 and NT.  It requires Microsoft Visual C++ 7.1
+(a.k.a. Visual Studio .NET 2003).
+(For other Windows platforms and compilers, see ../PC/readme.txt.)
+
+All you need to do is open the workspace "pcbuild.sln" in MSVC++, select
+the Debug or Release setting (using "Solution Configuration" from
+the "Standard" toolbar"), and build the projects.
+
+The proper order to build subprojects:
+
+1) pythoncore (this builds the main Python DLL and library files,
+               python25.{dll, lib} in Release mode)
+              NOTE:  in previous releases, this subproject was
+              named after the release number, e.g. python20.
+
+2) python (this builds the main Python executable,
+           python.exe in Release mode)
+
+3) the other subprojects, as desired or needed (note:  you probably don't
+   want to build most of the other subprojects, unless you're building an
+   entire Python distribution from scratch, or specifically making changes
+   to the subsystems they implement, or are running a Python core buildbot
+   test slave; see SUBPROJECTS below)
+
+When using the Debug setting, the output files have a _d added to
+their name:  python25_d.dll, python_d.exe, parser_d.pyd, and so on.
+
+SUBPROJECTS
+-----------
+These subprojects should build out of the box.  Subprojects other than the
+main ones (pythoncore, python, pythonw) generally build a DLL (renamed to
+.pyd) from a specific module so that users don't have to load the code
+supporting that module unless they import the module.
+
+pythoncore
+    .dll and .lib
+python
+    .exe
+pythonw
+    pythonw.exe, a variant of python.exe that doesn't pop up a DOS box
+_socket
+    socketmodule.c
+_testcapi
+    tests of the Python C API, run via Lib/test/test_capi.py, and
+    implemented by module Modules/_testcapimodule.c
+pyexpat
+    Python wrapper for accelerated XML parsing, which incorporates stable
+    code from the Expat project:  http://sourceforge.net/projects/expat/
+select
+    selectmodule.c
+unicodedata
+    large tables of Unicode data
+winsound
+    play sounds (typically .wav files) under Windows
+
+The following subprojects will generally NOT build out of the box.  They
+wrap code Python doesn't control, and you'll need to download the base
+packages first and unpack them into siblings of PCbuilds's parent
+directory; for example, if your PCbuild is  .......\dist\src\PCbuild\,
+unpack into new subdirectories of dist\.
+
+_tkinter
+    Python wrapper for the Tk windowing system.  Requires building
+    Tcl/Tk first.  Following are instructions for Tcl/Tk 8.4.12.
+
+    Get source
+    ----------
+    In the dist directory, run
+    svn export http://svn.python.org/projects/external/tcl8.4.12
+    svn export http://svn.python.org/projects/external/tk8.4.12
+    svn export http://svn.python.org/projects/external/tix-8.4.0
+
+    Build Tcl first (done here w/ MSVC 7.1 on Windows XP)
+    ---------------
+    Use "Start -> All Programs -> Microsoft Visual Studio .NET 2003
+         -> Visual Studio .NET Tools -> Visual Studio .NET 2003 Command Prompt"
+    to get a shell window with the correct environment settings
+    cd dist\tcl8.4.12\win
+    nmake -f makefile.vc
+    nmake -f makefile.vc INSTALLDIR=..\..\tcltk install
+
+    XXX Should we compile with OPTS=threads?
+
+    Optional:  run tests, via
+        nmake -f makefile.vc test
+
+        On WinXP Pro, wholly up to date as of 30-Aug-2004:
+        all.tcl:        Total   10678   Passed  9969    Skipped 709     Failed  0
+        Sourced 129 Test Files.
+
+    Build Tk
+    --------
+    cd dist\tk8.4.12\win
+    nmake -f makefile.vc TCLDIR=..\..\tcl8.4.12
+    nmake -f makefile.vc TCLDIR=..\..\tcl8.4.12 INSTALLDIR=..\..\tcltk install
+
+    XXX Should we compile with OPTS=threads?
+
+    XXX Our installer copies a lot of stuff out of the Tcl/Tk install
+    XXX directory.  Is all of that really needed for Python use of Tcl/Tk?
+
+    Optional:  run tests, via
+        nmake -f makefile.vc TCLDIR=..\..\tcl8.4.12 test
+
+        On WinXP Pro, wholly up to date as of 30-Aug-2004:
+        all.tcl:        Total   8420    Passed  6826    Skipped 1581    Failed  13
+        Sourced 91 Test Files.
+        Files with failing tests: canvImg.test scrollbar.test textWind.test winWm.test
+
+   Built Tix
+   ---------
+   cd dist\tix-8.4.0\win
+   nmake -f python.mak
+   nmake -f python.mak install
+
+bz2
+    Python wrapper for the libbz2 compression library.  Homepage
+        http://sources.redhat.com/bzip2/
+    Download the source from the python.org copy into the dist
+    directory:
+
+    svn export http://svn.python.org/projects/external/bzip2-1.0.3
+
+    A custom pre-link step in the bz2 project settings should manage to
+    build bzip2-1.0.3\libbz2.lib by magic before bz2.pyd (or bz2_d.pyd) is
+    linked in PCbuild\.
+    However, the bz2 project is not smart enough to remove anything under
+    bzip2-1.0.3\ when you do a clean, so if you want to rebuild bzip2.lib
+    you need to clean up bzip2-1.0.3\ by hand.
+
+    The build step shouldn't yield any warnings or errors, and should end
+    by displaying 6 blocks each terminated with
+        FC: no differences encountered
+
+    All of this managed to build bzip2-1.0.3\libbz2.lib, which the Python
+    project links in.
+
+
+_bsddb
+    To use the version of bsddb that Python is built with by default, invoke
+    (in the dist directory)
+
+     svn export http://svn.python.org/projects/external/db-4.4.20
+
+
+    Then open a VS.NET 2003 shell, and invoke:
+
+       devenv db-4.4.20\build_win32\Berkeley_DB.sln /build Release /project db_static
+
+    and do that a second time for a Debug build too:
+
+       devenv db-4.4.20\build_win32\Berkeley_DB.sln /build Debug /project db_static
+
+    Alternatively, if you want to start with the original sources,
+    go to Sleepycat's download page:
+        http://www.sleepycat.com/downloads/releasehistorybdb.html
+
+    and download version 4.4.20.
+
+    With or without strong cryptography? You can choose either with or
+    without strong cryptography, as per the instructions below.  By
+    default, Python is built and distributed WITHOUT strong crypto.
+
+    Unpack the sources; if you downloaded the non-crypto version, rename
+    the directory from db-4.4.20.NC to db-4.4.20.
+
+    Now apply any patches that apply to your version.
+
+    Open
+        dist\db-4.4.20\docs\index.html
+
+    and follow the "Windows->Building Berkeley DB with Visual C++ .NET"
+    instructions for building the Sleepycat
+    software.  Note that Berkeley_DB.dsw is in the build_win32 subdirectory.
+    Build the "db_static" project, for "Release" mode.
+
+    To run extensive tests, pass "-u bsddb" to regrtest.py.  test_bsddb3.py
+    is then enabled.  Running in verbose mode may be helpful.
+
+    XXX The test_bsddb3 tests don't always pass, on Windows (according to
+    XXX me) or on Linux (according to Barry).  (I had much better luck
+    XXX on Win2K than on Win98SE.)  The common failure mode across platforms
+    XXX is
+    XXX     DBAgainError: (11, 'Resource temporarily unavailable -- unable
+    XXX                         to join the environment')
+    XXX
+    XXX and it appears timing-dependent.  On Win2K I also saw this once:
+    XXX
+    XXX test02_SimpleLocks (bsddb.test.test_thread.HashSimpleThreaded) ...
+    XXX Exception in thread reader 1:
+    XXX Traceback (most recent call last):
+    XXX File "C:\Code\python\lib\threading.py", line 411, in __bootstrap
+    XXX    self.run()
+    XXX File "C:\Code\python\lib\threading.py", line 399, in run
+    XXX    apply(self.__target, self.__args, self.__kwargs)
+    XXX File "C:\Code\python\lib\bsddb\test\test_thread.py", line 268, in
+    XXX                  readerThread
+    XXX    rec = c.next()
+    XXX DBLockDeadlockError: (-30996, 'DB_LOCK_DEADLOCK: Locker killed
+    XXX                                to resolve a deadlock')
+    XXX
+    XXX I'm told that DBLockDeadlockError is expected at times.  It
+    XXX doesn't cause a test to fail when it happens (exceptions in
+    XXX threads are invisible to unittest).
+
+    Building for Win64:
+    - open a VS.NET 2003 command prompt
+    - run the SDK setenv.cmd script, passing /RETAIL and the target
+      architecture (/SRV64 for Itanium, /X64 for AMD64)
+    - build BerkeleyDB with the solution configuration matching the
+      target ("Release IA64" for Itanium, "Release AMD64" for AMD64), e.g.
+    devenv db-4.4.20\build_win32\Berkeley_DB.sln /build "Release AMD64" /project db_static /useenv
+
+_sqlite3
+    Python wrapper for SQLite library.
+    
+    Get the source code through
+    
+    svn export http://svn.python.org/projects/external/sqlite-source-3.3.4
+    
+    To use the extension module in a Python build tree, copy sqlite3.dll into
+    the PCbuild folder.
+
+_ssl
+    Python wrapper for the secure sockets library.
+
+    Get the source code through
+
+    svn export http://svn.python.org/projects/external/openssl-0.9.8a
+
+    Alternatively, get the latest version from http://www.openssl.org.
+    You can (theoretically) use any version of OpenSSL you like - the
+    build process will automatically select the latest version.
+
+    You must also install ActivePerl from
+        http://www.activestate.com/Products/ActivePerl/
+    as this is used by the OpenSSL build process.  Complain to them <wink>.
+
+    The MSVC project simply invokes PCBuild/build_ssl.py to perform
+    the build.  This Python script locates and builds your OpenSSL
+    installation, then invokes a simple makefile to build the final .pyd.
+
+    build_ssl.py attempts to catch the most common errors (such as not
+    being able to find OpenSSL sources, or not being able to find a Perl
+    that works with OpenSSL) and give a reasonable error message.
+    If you have a problem that doesn't seem to be handled correctly
+    (eg, you know you have ActivePerl but we can't find it), please take
+    a peek at build_ssl.py and suggest patches.  Note that build_ssl.py
+    should be able to be run directly from the command-line.
+
+    build_ssl.py/MSVC isn't clever enough to clean OpenSSL - you must do
+    this by hand.
+
+Building for Itanium
+--------------------
+
+The project files support a ReleaseItanium configuration which creates
+Win64/Itanium binaries. For this to work, you need to install the Platform
+SDK, in particular the 64-bit support. This includes an Itanium compiler
+(future releases of the SDK likely include an AMD64 compiler as well).
+In addition, you need the Visual Studio plugin for external C compilers,
+from http://sf.net/projects/vsextcomp. The plugin will wrap cl.exe, to
+locate the proper target compiler, and convert compiler options
+accordingly. The project files require atleast version 0.9.
+
+Building for AMD64
+------------------
+
+The build process for the ReleaseAMD64 configuration is very similar
+to the Itanium configuration; make sure you use the latest version of
+vsextcomp.
+
+Building Python Using the free MS Toolkit Compiler
+--------------------------------------------------
+
+The build process for Visual C++ can be used almost unchanged with the free MS
+Toolkit Compiler. This provides a way of building Python using freely
+available software.
+
+Note that Microsoft have withdrawn the free MS Toolkit Compiler, so this can
+no longer be considered a supported option. The instructions are still
+correct, but you need to already have a copy of the compiler in order to use
+them. Microsoft now supply Visual C++ 2005 Express Edition for free, but this
+is NOT compatible with Visual C++ 7.1 (it uses a different C runtime), and so
+cannot be used to build a version of Python compatible with the standard
+python.org build. If you are interested in using Visual C++ 2005 Express
+Edition, however, you should look at the PCBuild8 directory.
+
+Requirements
+
+    To build Python, the following tools are required:
+
+    * The Visual C++ Toolkit Compiler
+        no longer available for download - see above
+    * A recent Platform SDK
+        from http://www.microsoft.com/downloads/details.aspx?FamilyID=484269e2-3b89-47e3-8eb7-1f2be6d7123a
+    * The .NET 1.1 SDK
+        from http://www.microsoft.com/downloads/details.aspx?FamilyID=9b3a2ca6-3647-4070-9f41-a333c6b9181d
+
+    [Does anyone have better URLs for the last 2 of these?]
+
+    The toolkit compiler is needed as it is an optimising compiler (the
+    compiler supplied with the .NET SDK is a non-optimising version). The
+    platform SDK is needed to provide the Windows header files and libraries
+    (the Windows 2003 Server SP1 edition, typical install, is known to work -
+    other configurations or versions are probably fine as well). The .NET 1.1
+    SDK is needed because it contains a version of msvcrt.dll which links to
+    the msvcr71.dll CRT. Note that the .NET 2.0 SDK is NOT acceptable, as it
+    references msvcr80.dll.
+
+    All of the above items should be installed as normal.
+
+    If you intend to build the openssl (needed for the _ssl extension) you
+    will need the C runtime sources installed as part of the platform SDK.
+
+    In addition, you will need Nant, available from
+    http://nant.sourceforge.net. The 0.85 release candidate 3 version is known
+    to work. This is the latest released version at the time of writing. Later
+    "nightly build" versions are known NOT to work - it is not clear at
+    present whether future released versions will work.
+
+Setting up the environment
+
+    Start a platform SDK "build environment window" from the start menu. The
+    "Windows XP 32-bit retail" version is known to work.
+
+    Add the following directories to your PATH:
+        * The toolkit compiler directory
+        * The SDK "Win64" binaries directory
+	* The Nant directory
+    Add to your INCLUDE environment variable:
+        * The toolkit compiler INCLUDE directory
+    Add to your LIB environment variable:
+        * The toolkit compiler LIB directory
+	* The .NET SDK Visual Studio 2003 VC7\lib directory
+
+    The following commands should set things up as you need them:
+
+        rem Set these values according to where you installed the software
+        set TOOLKIT=C:\Program Files\Microsoft Visual C++ Toolkit 2003
+        set SDK=C:\Program Files\Microsoft Platform SDK
+        set NET=C:\Program Files\Microsoft Visual Studio .NET 2003
+        set NANT=C:\Utils\Nant
+
+        set PATH=%TOOLKIT%\bin;%PATH%;%SDK%\Bin\win64;%NANT%\bin
+        set INCLUDE=%TOOLKIT%\include;%INCLUDE%
+        set LIB=%TOOLKIT%\lib;%NET%\VC7\lib;%LIB%
+
+    The "win64" directory from the SDK is added to supply executables such as
+    "cvtres" and "lib", which are not available elsewhere. The versions in the
+    "win64" directory are 32-bit programs, so they are fine to use here.
+
+    That's it. To build Python (the core only, no binary extensions which
+    depend on external libraries) you just need to issue the command
+
+        nant -buildfile:python.build all
+
+    from within the PCBuild directory.
+
+Extension modules
+
+    To build those extension modules which require external libraries
+    (_tkinter, bz2, _bsddb, _sqlite3, _ssl) you can follow the instructions
+    for the Visual Studio build above, with a few minor modifications. These
+    instructions have only been tested using the sources in the Python
+    subversion repository - building from original sources should work, but
+    has not been tested.
+
+    For each extension module you wish to build, you should remove the
+    associated include line from the excludeprojects section of pc.build.
+
+    The changes required are:
+
+    _tkinter
+        The tix makefile (tix-8.4.0\win\makefile.vc) must be modified to
+	remove references to TOOLS32. The relevant lines should be changed to
+	read:
+            cc32 = cl.exe
+            link32 = link.exe
+            include32 = 
+	The remainder of the build instructions will work as given.
+
+    bz2
+        No changes are needed
+
+    _bsddb
+        The file db.build should be copied from the Python PCBuild directory
+	to the directory db-4.4.20\build_win32.
+
+	The file db_static.vcproj in db-4.4.20\build_win32 should be edited to
+	remove the string "$(SolutionDir)" - this occurs in 2 places, only
+	relevant for 64-bit builds. (The edit is required as otherwise, nant
+	wants to read the solution file, which is not in a suitable form).
+
+	The bsddb library can then be build with the command
+	    nant -buildfile:db.build all
+	run from the db-4.4.20\build_win32 directory.
+
+    _sqlite3
+        No changes are needed. However, in order for the tests to succeed, a
+	copy of sqlite3.dll must be downloaded, and placed alongside
+	python.exe.
+
+    _ssl
+        The documented build process works as written. However, it needs a
+	copy of the file setargv.obj, which is not supplied in the platform
+	SDK. However, the sources are available (in the crt source code). To
+	build setargv.obj, proceed as follows:
+
+        Copy setargv.c, cruntime.h and internal.h from %SDK%\src\crt to a
+	temporary directory.
+	Compile using "cl /c /I. /MD /D_CRTBLD setargv.c"
+	Copy the resulting setargv.obj to somewhere on your LIB environment
+	(%SDK%\lib is a reasonable place).
+
+	With setargv.obj in place, the standard build process should work
+	fine.
+
+YOUR OWN EXTENSION DLLs
+-----------------------
+If you want to create your own extension module DLL, there's an example
+with easy-to-follow instructions in ../PC/example/; read the file
+readme.txt there first.

Added: vendor/Python/current/PCbuild/rmpyc.py
===================================================================
--- vendor/Python/current/PCbuild/rmpyc.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild/rmpyc.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,25 @@
+# Remove all the .pyc and .pyo files under ../Lib.
+
+
+def deltree(root):
+    import os
+    from os.path import join
+
+    npyc = npyo = 0
+    for root, dirs, files in os.walk(root):
+        for name in files:
+            delete = False
+            if name.endswith('.pyc'):
+                delete = True
+                npyc += 1
+            elif name.endswith('.pyo'):
+                delete = True
+                npyo += 1
+
+            if delete:
+                os.remove(join(root, name))
+
+    return npyc, npyo
+
+npyc, npyo = deltree("../Lib")
+print npyc, ".pyc deleted,", npyo, ".pyo deleted"

Added: vendor/Python/current/PCbuild/rt.bat
===================================================================
--- vendor/Python/current/PCbuild/rt.bat	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild/rt.bat	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,52 @@
+ at echo off
+rem Run Tests.  Run the regression test suite.
+rem Usage:  rt [-d] [-O] [-q] regrtest_args
+rem -d   Run Debug build (python_d.exe).  Else release build.
+rem -O   Run python.exe or python_d.exe (see -d) with -O.
+rem -q   "quick" -- normally the tests are run twice, the first time
+rem      after deleting all the .py[co] files reachable from Lib/.
+rem      -q runs the tests just once, and without deleting .py[co] files.
+rem All leading instances of these switches are shifted off, and
+rem whatever remains is passed to regrtest.py.  For example,
+rem     rt -O -d -x test_thread
+rem runs
+rem     python_d -O ../lib/test/regrtest.py -x test_thread
+rem twice, and
+rem     rt -q -g test_binascii
+rem runs
+rem     python_d ../lib/test/regrtest.py -g test_binascii
+rem to generate the expected-output file for binascii quickly.
+rem
+rem Confusing:  if you want to pass a comma-separated list, like
+rem     -u network,largefile
+rem then you have to quote it on the rt line, like
+rem     rt -u "network,largefile"
+
+setlocal
+
+set exe=python
+set qmode=
+set dashO=
+PATH %PATH%;..\..\tcltk\bin
+
+:CheckOpts
+if "%1"=="-O" (set dashO=-O)     & shift & goto CheckOpts
+if "%1"=="-q" (set qmode=yes)    & shift & goto CheckOpts
+if "%1"=="-d" (set exe=python_d) & shift & goto CheckOpts
+
+set cmd=%exe% %dashO% -E -tt ../lib/test/regrtest.py %1 %2 %3 %4 %5 %6 %7 %8 %9
+if defined qmode goto Qmode
+
+echo Deleting .pyc/.pyo files ...
+%exe% rmpyc.py
+
+echo on
+%cmd%
+ at echo off
+
+echo About to run again without deleting .pyc/.pyo first:
+pause
+
+:Qmode
+echo on
+%cmd%


Property changes on: vendor/Python/current/PCbuild/rt.bat
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/PCbuild/select.vcproj
===================================================================
--- vendor/Python/current/PCbuild/select.vcproj	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild/select.vcproj	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,258 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="select"
+	SccProjectName="select"
+	SccLocalPath="..">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-release\select"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS"
+				StringPooling="TRUE"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="wsock32.lib"
+				OutputFile="./select.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				IgnoreDefaultLibraryNames="libc"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./select.pdb"
+				SubSystem="2"
+				BaseAddress="0x1D110000"
+				ImportLibrary=".\./select.lib"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-debug\select"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="wsock32.lib"
+				OutputFile="./select_d.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				IgnoreDefaultLibraryNames="libc,msvcrt"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./select_d.pdb"
+				SubSystem="2"
+				BaseAddress="0x1D110000"
+				ImportLibrary=".\./select_d.lib"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseItanium|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\ia64-temp-release\select"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions=" /USECL:MS_ITANIUM /GS-"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS"
+				StringPooling="TRUE"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="FALSE"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions=" /MACHINE:IA64 /USELINK:MS_SDK"
+				AdditionalDependencies="wsock32.lib"
+				OutputFile="./select.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				IgnoreDefaultLibraryNames="libc"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./select.pdb"
+				SubSystem="2"
+				BaseAddress="0x1D110000"
+				ImportLibrary=".\./select.lib"
+				TargetMachine="0"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseAMD64|Win32"
+			OutputDirectory="."
+			IntermediateDirectory="amd64-temp-release\select"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions=" /USECL:MS_OPTERON"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS"
+				StringPooling="TRUE"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="FALSE"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions=" /MACHINE:AMD64 /USELINK:MS_SDK"
+				AdditionalDependencies="wsock32.lib"
+				OutputFile="./select.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				IgnoreDefaultLibraryNames="libc"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./select.pdb"
+				SubSystem="2"
+				BaseAddress="0x1D110000"
+				ImportLibrary=".\./select.lib"
+				TargetMachine="0"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath="..\Modules\selectmodule.c">
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Added: vendor/Python/current/PCbuild/unicodedata.vcproj
===================================================================
--- vendor/Python/current/PCbuild/unicodedata.vcproj	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild/unicodedata.vcproj	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,247 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="unicodedata"
+	SccProjectName="unicodedata"
+	SccLocalPath="..">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-release\unicodedata"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MMAP_EXPORTS"
+				StringPooling="TRUE"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="./unicodedata.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				ProgramDatabaseFile=".\./unicodedata.pdb"
+				BaseAddress="0x1D120000"
+				ImportLibrary=".\./unicodedata.lib"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-debug\unicodedata"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;MMAP_EXPORTS"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="./unicodedata_d.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./unicodedata_d.pdb"
+				BaseAddress="0x1D120000"
+				ImportLibrary=".\./unicodedata_d.lib"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseItanium|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\ia64-temp-release\unicodedata"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions=" /USECL:MS_ITANIUM /GS-"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MMAP_EXPORTS"
+				StringPooling="TRUE"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="FALSE"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions=" /MACHINE:IA64 /USELINK:MS_SDK"
+				OutputFile="./unicodedata.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				ProgramDatabaseFile=".\./unicodedata.pdb"
+				BaseAddress="0x1D120000"
+				ImportLibrary=".\./unicodedata.lib"
+				TargetMachine="0"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseAMD64|Win32"
+			OutputDirectory="."
+			IntermediateDirectory="amd64-temp-release\unicodedata"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions=" /USECL:MS_OPTERON /GS-"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MMAP_EXPORTS"
+				StringPooling="TRUE"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="FALSE"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions=" /MACHINE:AMD64 /USELINK:MS_SDK"
+				OutputFile="./unicodedata.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				ProgramDatabaseFile=".\./unicodedata.pdb"
+				BaseAddress="0x1D120000"
+				ImportLibrary=".\./unicodedata.lib"
+				TargetMachine="0"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath="..\Modules\unicodedata.c">
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Added: vendor/Python/current/PCbuild/w9xpopen.vcproj
===================================================================
--- vendor/Python/current/PCbuild/w9xpopen.vcproj	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild/w9xpopen.vcproj	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="w9xpopen"
+	SccProjectName=""
+	SccLocalPath="">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-debug\w9xpopen"
+			ConfigurationType="1"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="./w9xpopen_d.exe"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./w9xpopen_d.pdb"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-release\w9xpopen"
+			ConfigurationType="1"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+				StringPooling="TRUE"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile=".\./w9xpopen.exe"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				ProgramDatabaseFile=".\./w9xpopen.pdb"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath="..\PC\w9xpopen.c">
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Added: vendor/Python/current/PCbuild/winsound.vcproj
===================================================================
--- vendor/Python/current/PCbuild/winsound.vcproj	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild/winsound.vcproj	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,251 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="winsound"
+	SccProjectName="winsound"
+	SccLocalPath="..\pc">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-debug\winsound"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;WINSOUND_EXPORTS"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="./winsound_d.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\./winsound_d.pdb"
+				BaseAddress="0x1D160000"
+				ImportLibrary=".\./winsound_d.lib"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-release\winsound"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;WINSOUND_EXPORTS"
+				StringPooling="TRUE"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="./winsound.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				ProgramDatabaseFile=".\./winsound.pdb"
+				BaseAddress="0x1D160000"
+				ImportLibrary=".\./winsound.lib"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseItanium|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\ia64-temp-release\winsound"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions=" /USECL:MS_ITANIUM /GS-"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;WINSOUND_EXPORTS"
+				StringPooling="TRUE"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="FALSE"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions=" /MACHINE:IA64 /USELINK:MS_SDK"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="./winsound.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				ProgramDatabaseFile=".\./winsound.pdb"
+				BaseAddress="0x1D160000"
+				ImportLibrary=".\./winsound.lib"
+				TargetMachine="0"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseAMD64|Win32"
+			OutputDirectory="."
+			IntermediateDirectory="amd64-temp-release\winsound"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions=" /USECL:MS_OPTERON /GS-"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;WINSOUND_EXPORTS"
+				StringPooling="TRUE"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="FALSE"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions=" /MACHINE:AMD64 /USELINK:MS_SDK"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="./winsound.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				ProgramDatabaseFile=".\./winsound.pdb"
+				BaseAddress="0x1D160000"
+				ImportLibrary=".\./winsound.lib"
+				TargetMachine="0"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath="..\PC\winsound.c">
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Added: vendor/Python/current/PCbuild8/Uninstal.wse
===================================================================
--- vendor/Python/current/PCbuild8/Uninstal.wse	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild8/Uninstal.wse	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,514 @@
+Document Type: WSE
+item: Global
+  Version=8.14
+  Flags=00000100
+  Split=1420
+  Languages=65 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+  Copy Default=1
+  Japanese Font Name=MS Gothic
+  Japanese Font Size=10
+  Start Gradient=0 0 255
+  End Gradient=0 0 0
+  Windows Flags=00000000000000000000101000001000
+  Message Font=MS Sans Serif
+  Font Size=8
+  Disk Label=GLBS
+  Disk Filename=INSTALL
+  Patch Flags=0000000000000001
+  Patch Threshold=200
+  Patch Memory=4096
+  Per-User Version ID=1
+  Crystal Format=10111100101100000010001001001001
+  Step View=&Properties
+end
+item: Remark
+  Text=Note from Tim:  This is a verbatim copy of Wise's Uninstal.wse, altered at the end to write
+end
+item: Remark
+  Text=uninstall info under HKCU instead of HKLM if our DOADMIN var is false.
+end
+item: Remark
+end
+item: Remark
+  Text=     Install Support for uninstalling the application.
+end
+item: Remark
+end
+item: Set Variable
+  Variable=UNINSTALL_PATH
+  Value=%_LOGFILE_PATH_%
+  Flags=00000010
+end
+item: Set Variable
+  Variable=UNINSTALL_PATH
+  Value=%UNINSTALL_PATH%\UNWISE.EXE
+end
+item: Compiler Variable If
+  Variable=_EXE_OS_TYPE_
+  Value=WIN32
+end
+item: Install File
+  Source=%_WISE_%\UNWISE32.EXE
+  Destination=%UNINSTALL_PATH%
+  Flags=0000000000000010
+end
+item: Compiler Variable Else
+end
+item: Install File
+  Source=%_WISE_%\UNWISE.EXE
+  Destination=%UNINSTALL_PATH%
+  Flags=0000000000000010
+end
+item: Compiler Variable End
+end
+item: Remark
+end
+item: Remark
+  Text=     Install Support for multiple languages
+end
+item: Remark
+end
+item: Set Variable
+  Variable=UNINSTALL_LANG
+  Value=%UNINSTALL_PATH%
+  Flags=00000010
+end
+item: Set Variable
+  Variable=UNINSTALL_LANG
+  Value=%UNINSTALL_LANG%\UNWISE.INI
+end
+item: Compiler Variable If
+  Variable=_LANG_LIST_
+  Value=C
+  Flags=00000010
+end
+item: Compiler Variable If
+  Value=%_WISE_%\LANGUAGE\UNWISE.FRA
+  Flags=00000011
+end
+item: If/While Statement
+  Variable=LANG
+  Value=%_LANG_C_NAME_%
+end
+item: Install File
+  Source=%_WISE_%\LANGUAGE\UNWISE.FRA
+  Destination=%UNINSTALL_LANG%
+  Flags=0000000000000010
+end
+item: End Block
+end
+item: Compiler Variable End
+end
+item: Compiler Variable End
+end
+item: Compiler Variable If
+  Variable=_LANG_LIST_
+  Value=D
+  Flags=00000010
+end
+item: Compiler Variable If
+  Value=%_WISE_%\LANGUAGE\UNWISE.FRA
+  Flags=00000011
+end
+item: If/While Statement
+  Variable=LANG
+  Value=%_LANG_D_NAME_%
+end
+item: Install File
+  Source=%_WISE_%\LANGUAGE\UNWISE.FRA
+  Destination=%UNINSTALL_LANG%
+  Flags=0000000000000010
+end
+item: End Block
+end
+item: Compiler Variable End
+end
+item: Compiler Variable End
+end
+item: Compiler Variable If
+  Variable=_LANG_LIST_
+  Value=E
+  Flags=00000010
+end
+item: Compiler Variable If
+  Value=%_WISE_%\LANGUAGE\UNWISE.DEU
+  Flags=00000011
+end
+item: If/While Statement
+  Variable=LANG
+  Value=%_LANG_E_NAME_%
+end
+item: Install File
+  Source=%_WISE_%\LANGUAGE\UNWISE.DEU
+  Destination=%UNINSTALL_LANG%
+  Flags=0000000000000010
+end
+item: End Block
+end
+item: Compiler Variable End
+end
+item: Compiler Variable End
+end
+item: Compiler Variable If
+  Variable=_LANG_LIST_
+  Value=F
+  Flags=00000010
+end
+item: Compiler Variable If
+  Value=%_WISE_%\LANGUAGE\UNWISE.PTG
+  Flags=00000011
+end
+item: If/While Statement
+  Variable=LANG
+  Value=%_LANG_F_NAME_%
+end
+item: Install File
+  Source=%_WISE_%\LANGUAGE\UNWISE.PTG
+  Destination=%UNINSTALL_LANG%
+  Flags=0000000000000010
+end
+item: End Block
+end
+item: Compiler Variable End
+end
+item: Compiler Variable End
+end
+item: Compiler Variable If
+  Variable=_LANG_LIST_
+  Value=G
+  Flags=00000010
+end
+item: Compiler Variable If
+  Value=%_WISE_%\LANGUAGE\UNWISE.ESP
+  Flags=00000011
+end
+item: If/While Statement
+  Variable=LANG
+  Value=%_LANG_G_NAME_%
+end
+item: Install File
+  Source=%_WISE_%\LANGUAGE\UNWISE.ESP
+  Destination=%UNINSTALL_LANG%
+  Flags=0000000000000010
+end
+item: End Block
+end
+item: Compiler Variable End
+end
+item: Compiler Variable End
+end
+item: Compiler Variable If
+  Variable=_LANG_LIST_
+  Value=H
+  Flags=00000010
+end
+item: Compiler Variable If
+  Value=%_WISE_%\LANGUAGE\UNWISE.ESP
+  Flags=00000011
+end
+item: If/While Statement
+  Variable=LANG
+  Value=%_LANG_H_NAME_%
+end
+item: Install File
+  Source=%_WISE_%\LANGUAGE\UNWISE.ESP
+  Destination=%UNINSTALL_LANG%
+  Flags=0000000000000010
+end
+item: End Block
+end
+item: Compiler Variable End
+end
+item: Compiler Variable End
+end
+item: Compiler Variable If
+  Variable=_LANG_LIST_
+  Value=I
+  Flags=00000010
+end
+item: Compiler Variable If
+  Value=%_WISE_%\LANGUAGE\UNWISE.ITA
+  Flags=00000011
+end
+item: If/While Statement
+  Variable=LANG
+  Value=%_LANG_I_NAME_%
+end
+item: Install File
+  Source=%_WISE_%\LANGUAGE\UNWISE.ITA
+  Destination=%UNINSTALL_LANG%
+  Flags=0000000000000010
+end
+item: End Block
+end
+item: Compiler Variable End
+end
+item: Compiler Variable End
+end
+item: Compiler Variable If
+  Variable=_LANG_LIST_
+  Value=J
+  Flags=00000010
+end
+item: Compiler Variable If
+  Value=%_WISE_%\LANGUAGE\UNWISE.DAN
+  Flags=00000011
+end
+item: If/While Statement
+  Variable=LANG
+  Value=%_LANG_J_NAME_%
+end
+item: Install File
+  Source=%_WISE_%\LANGUAGE\UNWISE.DAN
+  Destination=%UNINSTALL_LANG%
+  Flags=0000000000000010
+end
+item: End Block
+end
+item: Compiler Variable End
+end
+item: Compiler Variable End
+end
+item: Compiler Variable If
+  Variable=_LANG_LIST_
+  Value=K
+  Flags=00000010
+end
+item: Compiler Variable If
+  Value=%_WISE_%\LANGUAGE\UNWISE.FIN
+  Flags=00000011
+end
+item: If/While Statement
+  Variable=LANG
+  Value=%_LANG_K_NAME_%
+end
+item: Install File
+  Source=%_WISE_%\LANGUAGE\UNWISE.FIN
+  Destination=%UNINSTALL_LANG%
+  Flags=0000000000000010
+end
+item: End Block
+end
+item: Compiler Variable End
+end
+item: Compiler Variable End
+end
+item: Compiler Variable If
+  Variable=_LANG_LIST_
+  Value=L
+  Flags=00000010
+end
+item: Compiler Variable If
+  Value=%_WISE_%\LANGUAGE\UNWISE.ISL
+  Flags=00000011
+end
+item: If/While Statement
+  Variable=LANG
+  Value=%_LANG_L_NAME_%
+end
+item: Install File
+  Source=%_WISE_%\LANGUAGE\UNWISE.ISL
+  Destination=%UNINSTALL_LANG%
+  Flags=0000000000000010
+end
+item: End Block
+end
+item: Compiler Variable End
+end
+item: Compiler Variable End
+end
+item: Compiler Variable If
+  Variable=_LANG_LIST_
+  Value=M
+  Flags=00000010
+end
+item: Compiler Variable If
+  Value=%_WISE_%\LANGUAGE\UNWISE.NLD
+  Flags=00000011
+end
+item: If/While Statement
+  Variable=LANG
+  Value=%_LANG_M_NAME_%
+end
+item: Install File
+  Source=%_WISE_%\LANGUAGE\UNWISE.NLD
+  Destination=%UNINSTALL_LANG%
+  Flags=0000000000000010
+end
+item: End Block
+end
+item: Compiler Variable End
+end
+item: Compiler Variable End
+end
+item: Compiler Variable If
+  Variable=_LANG_LIST_
+  Value=N
+  Flags=00000010
+end
+item: Compiler Variable If
+  Value=%_WISE_%\LANGUAGE\UNWISE.NOR
+  Flags=00000011
+end
+item: If/While Statement
+  Variable=LANG
+  Value=%_LANG_N_NAME_%
+end
+item: Install File
+  Source=%_WISE_%\LANGUAGE\UNWISE.NOR
+  Destination=%UNINSTALL_LANG%
+  Flags=0000000000000010
+end
+item: End Block
+end
+item: Compiler Variable End
+end
+item: Compiler Variable End
+end
+item: Compiler Variable If
+  Variable=_LANG_LIST_
+  Value=O
+  Flags=00000010
+end
+item: Compiler Variable If
+  Value=%_WISE_%\LANGUAGE\UNWISE.SVE
+  Flags=00000011
+end
+item: If/While Statement
+  Variable=LANG
+  Value=%_LANG_O_NAME_%
+end
+item: Install File
+  Source=%_WISE_%\LANGUAGE\UNWISE.SVE
+  Destination=%UNINSTALL_LANG%
+  Flags=0000000000000010
+end
+item: End Block
+end
+item: Compiler Variable End
+end
+item: Compiler Variable End
+end
+item: Compiler Variable If
+  Variable=_LANG_LIST_
+  Value=P
+  Flags=00000010
+end
+item: Compiler Variable If
+  Value=%_WISE_%\LANGUAGE\UNWISE.JPN
+  Flags=00000011
+end
+item: If/While Statement
+  Variable=LANG
+  Value=%_LANG_P_NAME_%
+end
+item: Install File
+  Source=%_WISE_%\LANGUAGE\UNWISE.JPN
+  Destination=%UNINSTALL_LANG%
+  Flags=0000000000000010
+end
+item: End Block
+end
+item: Compiler Variable End
+end
+item: Compiler Variable End
+end
+item: Remark
+end
+item: Remark
+  Text=     Install the add/remove or uninstall icon
+end
+item: Remark
+end
+item: Set Variable
+  Variable=UNINSTALL_PATH
+  Value=%UNINSTALL_PATH%
+  Flags=00010100
+end
+item: Set Variable
+  Variable=INST_LOG_PATH
+  Value=%_LOGFILE_PATH_%
+  Flags=00010100
+end
+item: Check Configuration
+  Flags=10111011
+end
+item: If/While Statement
+  Variable=DOADMIN
+  Value=1
+end
+item: Remark
+  Text=Write uninstall info under HKLM.  This if/else/end block added by Tim.
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Microsoft\Windows\CurrentVersion\Uninstall\%APPTITLE%
+  New Value=%APPTITLE%
+  Value Name=DisplayName
+  Root=2
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Microsoft\Windows\CurrentVersion\Uninstall\%APPTITLE%
+  New Value=%UNINSTALL_PATH% %INST_LOG_PATH%
+  New Value=
+  Value Name=UninstallString
+  Root=2
+end
+item: Else Statement
+end
+item: Remark
+  Text=The same, but write under HKCU instead.
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Microsoft\Windows\CurrentVersion\Uninstall\%APPTITLE%
+  New Value=%APPTITLE%
+  Value Name=DisplayName
+  Root=1
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Microsoft\Windows\CurrentVersion\Uninstall\%APPTITLE%
+  New Value=%UNINSTALL_PATH% %INST_LOG_PATH%
+  New Value=
+  Value Name=UninstallString
+  Root=1
+end
+item: End Block
+end
+item: Else Statement
+end
+item: Add ProgMan Icon
+  Group=%GROUP%
+  Icon Name=Uninstall %APPTITLE%
+  Command Line=%UNINSTALL_PATH% %INST_LOG_PATH%
+end
+item: End Block
+end
+item: Check Configuration
+  Flags=11110010
+end
+item: If/While Statement
+  Variable=DOBRAND
+  Value=1
+end
+item: Edit Registry
+  Total Keys=2
+  item: Key
+    Key=Software\Microsoft\Windows\CurrentVersion\Uninstall\%APPTITLE%
+    New Value=%COMPANY%
+    Value Name=RegCompany
+    Root=2
+  end
+  item: Key
+    Key=Software\Microsoft\Windows\CurrentVersion\Uninstall\%APPTITLE%
+    New Value=%NAME%
+    Value Name=RegOwner
+    Root=2
+  end
+end
+item: End Block
+end
+item: End Block
+end

Added: vendor/Python/current/PCbuild8/_bsddb.vcproj
===================================================================
--- vendor/Python/current/PCbuild8/_bsddb.vcproj	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild8/_bsddb.vcproj	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,385 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="_bsddb"
+	ProjectGUID="{E1DBB220-D64B-423D-A545-539A55AA7FE2}"
+	SccProjectName="_bsddb"
+	SccLocalPath=".."
+	SccProvider="MSSCCI:Perforce SCM"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-debug\_bsddb"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\Include;..\PC;&quot;..\..\db-4.4.20\build_win32&quot;"
+				PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="..\..\db-4.4.20\build_win32\Debug\libdb44sd.lib"
+				OutputFile="./_bsddb_d.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				IgnoreDefaultLibraryNames=""
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=".\./_bsddb_d.pdb"
+				SubSystem="2"
+				BaseAddress="0x1e180000"
+				ImportLibrary=".\./_bsddb_d.lib"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-release\_bsddb"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include;..\PC;&quot;..\..\db-4.4.20\build_win32&quot;"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="..\..\db-4.4.20\build_win32\Release\libdb44s.lib"
+				OutputFile="./_bsddb.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				IgnoreDefaultLibraryNames=""
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=".\./_bsddb.pdb"
+				SubSystem="2"
+				BaseAddress="0x1e180000"
+				ImportLibrary=".\./_bsddb.lib"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseItanium|Win32"
+			OutputDirectory="./."
+			IntermediateDirectory=".\ia64-temp-release\_bsddb"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions=" /USECL:MS_ITANIUM"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include;..\PC;&quot;..\..\db-4.4.20\build_win32&quot;"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS"
+				StringPooling="true"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="false"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions=" /MACHINE:IA64 /USELINK:MS_SDK"
+				AdditionalDependencies="..\..\db-4.4.20\build_win32\Release_IA64\libdb44s.lib"
+				OutputFile="./_bsddb.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				IgnoreDefaultLibraryNames=""
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=".\./_bsddb.pdb"
+				SubSystem="2"
+				BaseAddress="0x1e180000"
+				ImportLibrary=".\./_bsddb.lib"
+				TargetMachine="0"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseAMD64|Win32"
+			OutputDirectory="."
+			IntermediateDirectory="amd64-temp-release\_bsddb"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions=" /USECL:MS_OPTERON /GS-"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include;..\PC;&quot;..\..\db-4.4.20\build_win32&quot;"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS"
+				StringPooling="true"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="false"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions=" /MACHINE:AMD64 /USELINK:MS_SDK"
+				AdditionalDependencies="..\..\db-4.4.20\build_win32\Release_AMD64\libdb44s.lib"
+				OutputFile="./_bsddb.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				IgnoreDefaultLibraryNames=""
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=".\./_bsddb.pdb"
+				SubSystem="2"
+				BaseAddress="0x1e180000"
+				ImportLibrary=".\./_bsddb.lib"
+				TargetMachine="0"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath="..\Modules\_bsddb.c"
+			>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Added: vendor/Python/current/PCbuild8/_ctypes.vcproj
===================================================================
--- vendor/Python/current/PCbuild8/_ctypes.vcproj	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild8/_ctypes.vcproj	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,412 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8,00"
+	Name="_ctypes"
+	ProjectGUID="{F22F40F4-D318-40DC-96B3-88DC81CE0894}"
+	RootNamespace="_ctypes"
+	Keyword="Win32Proj"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(PlatformName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\_ctypes"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\Include,..\PC,..\Modules\_ctypes\libffi_msvc"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
+				MinimalRebuild="false"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="false"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions="/EXPORT:DllGetClassObject,PRIVATE /EXPORT:DllCanUnloadNow,PRIVATE"
+				OutputFile="$(OutDir)\_ctypes_d.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				AdditionalLibraryDirectories="$(OutDir)"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				SubSystem="0"
+				BaseAddress="0x1D1A0000"
+				ImportLibrary=""
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			OutputDirectory="$(PlatformName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\_ctypes"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\Include,..\PC,..\Modules\_ctypes\libffi_msvc"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
+				MinimalRebuild="false"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="false"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions="/EXPORT:DllGetClassObject,PRIVATE /EXPORT:DllCanUnloadNow,PRIVATE"
+				OutputFile="$(OutDir)\_ctypes_d.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				AdditionalLibraryDirectories="$(OutDir)"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				SubSystem="0"
+				BaseAddress="0x1D1A0000"
+				ImportLibrary=""
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(PlatformName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\_ctypes"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				WholeProgramOptimization="true"
+				AdditionalIncludeDirectories="..\Include,..\PC,..\Modules\_ctypes\libffi_msvc"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="false"
+				DebugInformationFormat="0"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions="/EXPORT:DllGetClassObject,PRIVATE /EXPORT:DllCanUnloadNow,PRIVATE"
+				OutputFile="$(OutDir)\_ctypes.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				AdditionalLibraryDirectories="$(OutDir)"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				SubSystem="0"
+				OptimizeReferences="0"
+				EnableCOMDATFolding="0"
+				LinkTimeCodeGeneration="1"
+				BaseAddress="0x1D1A0000"
+				ImportLibrary=""
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			OutputDirectory="$(PlatformName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\_ctypes"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				WholeProgramOptimization="true"
+				AdditionalIncludeDirectories="..\Include,..\PC,..\Modules\_ctypes\libffi_msvc"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="false"
+				DebugInformationFormat="0"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions="/EXPORT:DllGetClassObject,PRIVATE /EXPORT:DllCanUnloadNow,PRIVATE"
+				OutputFile="$(OutDir)\_ctypes.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				AdditionalLibraryDirectories="$(OutDir)"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				SubSystem="0"
+				OptimizeReferences="0"
+				EnableCOMDATFolding="0"
+				LinkTimeCodeGeneration="1"
+				BaseAddress="0x1D1A0000"
+				ImportLibrary=""
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath="..\Modules\_ctypes\_ctypes.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\_ctypes\callbacks.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\_ctypes\callproc.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\_ctypes\cfield.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\_ctypes\libffi_msvc\ffi.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\_ctypes\malloc_closure.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\_ctypes\libffi_msvc\prep_cif.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\_ctypes\stgdict.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\_ctypes\libffi_msvc\win32.c"
+			>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Added: vendor/Python/current/PCbuild8/_ctypes_test.vcproj
===================================================================
--- vendor/Python/current/PCbuild8/_ctypes_test.vcproj	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild8/_ctypes_test.vcproj	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,370 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8,00"
+	Name="_ctypes_test"
+	ProjectGUID="{8CF334D9-4F82-42EB-97AF-83592C5AFD2F}"
+	RootNamespace="_ctypes_test"
+	Keyword="Win32Proj"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(PlatformName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\_ctypes_test"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
+				MinimalRebuild="false"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\_ctypes_test_d.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				AdditionalLibraryDirectories="$(OutDir)"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				SubSystem="0"
+				ImportLibrary=""
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			OutputDirectory="$(PlatformName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\_ctypes_test"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
+				MinimalRebuild="false"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)/_ctypes_test_d.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				AdditionalLibraryDirectories="$(OutDir)"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				SubSystem="0"
+				ImportLibrary=""
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(PlatformName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\_ctypes_test"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="0"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\_ctypes_test.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				AdditionalLibraryDirectories="$(OutDir)"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				SubSystem="0"
+				OptimizeReferences="0"
+				EnableCOMDATFolding="0"
+				ImportLibrary=""
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			OutputDirectory="$(PlatformName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\_ctypes_test"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="0"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\_ctypes_test.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				AdditionalLibraryDirectories="$(OutDir)"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				SubSystem="0"
+				OptimizeReferences="0"
+				EnableCOMDATFolding="0"
+				ImportLibrary=""
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath="..\Modules\_ctypes\_ctypes_test.c"
+			>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Added: vendor/Python/current/PCbuild8/_elementtree.vcproj
===================================================================
--- vendor/Python/current/PCbuild8/_elementtree.vcproj	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild8/_elementtree.vcproj	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,390 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8,00"
+	Name="_elementtree"
+	ProjectGUID="{1966DDE2-4AB7-4E4E-ACC9-C121E4D37F8E}"
+	RootNamespace="_elementtree"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(PlatformName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\_elementtree"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\Include,..\PC,..\Modules\expat"
+				PreprocessorDefinitions="_DEBUG;HAVE_EXPAT_H;WIN32;_WINDOWS;XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;USE_PYEXPAT_CAPI;XML_STATIC;HAVE_MEMMOVE"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="odbccp32.lib"
+				OutputFile="$(OutDir)\_elementtree_d.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				AdditionalLibraryDirectories="$(OutDir)"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				SubSystem="2"
+				BaseAddress="0x1D100000"
+				ImportLibrary=""
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			OutputDirectory="$(PlatformName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\_elementtree"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\Include,..\PC,..\Modules\expat"
+				PreprocessorDefinitions="_DEBUG;HAVE_EXPAT_H;WIN32;_WINDOWS;XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;USE_PYEXPAT_CAPI;XML_STATIC;HAVE_MEMMOVE"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="odbccp32.lib"
+				OutputFile="$(OutDir)\_elementtree_d.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				AdditionalLibraryDirectories="$(OutDir)"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				SubSystem="2"
+				BaseAddress="0x1D100000"
+				ImportLibrary=""
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(PlatformName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\_elementtree"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				WholeProgramOptimization="true"
+				AdditionalIncludeDirectories="..\Include,..\PC,..\Modules\expat"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;USE_PYEXPAT_CAPI;XML_STATIC;HAVE_MEMMOVE"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="odbccp32.lib"
+				OutputFile="$(OutDir)\_elementtree.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				AdditionalLibraryDirectories="$(OutDir)"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				SubSystem="2"
+				LinkTimeCodeGeneration="1"
+				BaseAddress="0x1D100000"
+				ImportLibrary=""
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			OutputDirectory="$(PlatformName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\_elementtree"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				WholeProgramOptimization="true"
+				AdditionalIncludeDirectories="..\Include,..\PC,..\Modules\expat"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;USE_PYEXPAT_CAPI;XML_STATIC;HAVE_MEMMOVE"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="false"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="odbccp32.lib"
+				OutputFile="$(OutDir)\_elementtree.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				AdditionalLibraryDirectories="$(OutDir)"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				SubSystem="2"
+				LinkTimeCodeGeneration="1"
+				BaseAddress="0x1D100000"
+				ImportLibrary=""
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath="..\Modules\_elementtree.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\expat\xmlparse.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\expat\xmlrole.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\expat\xmltok.c"
+			>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Added: vendor/Python/current/PCbuild8/_msi.vcproj
===================================================================
--- vendor/Python/current/PCbuild8/_msi.vcproj	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild8/_msi.vcproj	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,375 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8,00"
+	Name="_msi"
+	ProjectGUID="{2C0BEFB9-70E2-4F80-AC5B-4AB8EE023574}"
+	RootNamespace="_msi"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(PlatformName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\_msi"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="fci.lib msi.lib rpcrt4.lib"
+				OutputFile="$(OutDir)\_msi.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				AdditionalLibraryDirectories="$(OutDir)"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				BaseAddress="0x1D160000"
+				ImportLibrary=""
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			OutputDirectory="$(PlatformName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\_msi"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="fci.lib msi.lib rpcrt4.lib"
+				OutputFile="$(OutDir)\_msi.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				AdditionalLibraryDirectories="$(OutDir)"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				BaseAddress="0x1D160000"
+				ImportLibrary=""
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(PlatformName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\_msi"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="fci.lib msi.lib rpcrt4.lib"
+				OutputFile="$(OutDir)\_msi.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				AdditionalLibraryDirectories="$(OutDir)"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				BaseAddress="0x1D160000"
+				ImportLibrary=""
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			OutputDirectory="$(PlatformName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\_msi"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="fci.lib msi.lib rpcrt4.lib"
+				OutputFile="$(OutDir)\_msi.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				AdditionalLibraryDirectories="$(OutDir)"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				BaseAddress="0x1D160000"
+				ImportLibrary=""
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath="..\PC\_msi.c"
+			>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Added: vendor/Python/current/PCbuild8/_socket.vcproj
===================================================================
--- vendor/Python/current/PCbuild8/_socket.vcproj	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild8/_socket.vcproj	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,381 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="_socket"
+	ProjectGUID="{324F66C2-44D0-4D50-B979-F9DAE7FD36DB}"
+	SccProjectName="_socket"
+	SccLocalPath=".."
+	SccProvider="MSSCCI:Perforce SCM"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-debug\_socket"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib"
+				OutputFile="./_socket_d.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=".\./_socket_d.pdb"
+				SubSystem="2"
+				BaseAddress="0x1e1D0000"
+				ImportLibrary=".\./_socket_d.lib"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-release\_socket"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib"
+				OutputFile="./_socket.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=".\./_socket.pdb"
+				SubSystem="2"
+				BaseAddress="0x1e1D0000"
+				ImportLibrary=".\./_socket.lib"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseItanium|Win32"
+			OutputDirectory="./."
+			IntermediateDirectory=".\ia64-temp-release\_socket"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions=" /USECL:MS_ITANIUM"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS"
+				StringPooling="true"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="false"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions=" /MACHINE:IA64 /USELINK:MS_SDK"
+				AdditionalDependencies="ws2_32.lib"
+				OutputFile="./_socket.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=".\./_socket.pdb"
+				SubSystem="2"
+				BaseAddress="0x1e1D0000"
+				ImportLibrary=".\./_socket.lib"
+				TargetMachine="0"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseAMD64|Win32"
+			OutputDirectory="."
+			IntermediateDirectory="amd64-temp-release\_socket"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions=" /USECL:MS_OPTERON /GS-"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS"
+				StringPooling="true"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="false"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions=" /MACHINE:AMD64 /USELINK:MS_SDK"
+				AdditionalDependencies="ws2_32.lib"
+				OutputFile="./_socket.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=".\./_socket.pdb"
+				SubSystem="2"
+				BaseAddress="0x1e1D0000"
+				ImportLibrary=".\./_socket.lib"
+				TargetMachine="0"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath="..\Modules\socketmodule.c"
+			>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Added: vendor/Python/current/PCbuild8/_sqlite3.vcproj
===================================================================
--- vendor/Python/current/PCbuild8/_sqlite3.vcproj	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild8/_sqlite3.vcproj	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,411 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8,00"
+	Name="_sqlite3"
+	ProjectGUID="{2FF0A312-22F9-4C34-B070-842916DE27A9}"
+	RootNamespace="_sqlite3"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(PlatformName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\_sqlite3"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\Include;..\PC;..\..\sqlite-source-3.3.4"
+				PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS;MODULE_NAME=\&quot;sqlite3\&quot;"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="..\..\sqlite-source-3.3.4\sqlite3.lib"
+				OutputFile="$(OutDir)\_sqlite3_d.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				AdditionalLibraryDirectories="$(OutDir)"
+				IgnoreDefaultLibraryNames=""
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				SubSystem="2"
+				BaseAddress="0x1e180000"
+				ImportLibrary=""
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			OutputDirectory="$(PlatformName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\_sqlite"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\Include;..\PC;..\..\sqlite-source-3.3.4"
+				PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS;MODULE_NAME=\&quot;sqlite3\&quot;"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="..\..\sqlite-source-3.3.4\sqlite3.lib"
+				OutputFile="$(OutDir)\_sqlite3_d.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				AdditionalLibraryDirectories="$(OutDir)"
+				IgnoreDefaultLibraryNames=""
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				SubSystem="2"
+				BaseAddress="0x1e180000"
+				ImportLibrary=""
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(PlatformName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\_sqlite3"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include;..\PC;..\..\sqlite-source-3.3.4"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;MODULE_NAME=\&quot;sqlite3\&quot;"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="..\..\sqlite-source-3.3.4\sqlite3.lib"
+				OutputFile="$(OutDir)\_sqlite3.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				AdditionalLibraryDirectories="$(OutDir)"
+				IgnoreDefaultLibraryNames=""
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				SubSystem="2"
+				BaseAddress="0x1e180000"
+				ImportLibrary=""
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			OutputDirectory="$(PlatformName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\_sqlite3"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include;..\PC;..\..\sqlite-source-3.3.4"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;MODULE_NAME=\&quot;sqlite3\&quot;"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="..\..\sqlite-source-3.3.4\sqlite3.lib"
+				OutputFile="$(OutDir)\_sqlite3.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				AdditionalLibraryDirectories="$(OutDir)"
+				IgnoreDefaultLibraryNames=""
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				SubSystem="2"
+				BaseAddress="0x1e180000"
+				ImportLibrary=""
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath="..\Modules\_sqlite\cache.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\_sqlite\connection.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\_sqlite\cursor.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\_sqlite\microprotocols.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\_sqlite\module.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\_sqlite\prepare_protocol.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\_sqlite\row.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\_sqlite\statement.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\_sqlite\util.c"
+			>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Added: vendor/Python/current/PCbuild8/_ssl.mak
===================================================================
--- vendor/Python/current/PCbuild8/_ssl.mak	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild8/_ssl.mak	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,21 @@
+
+!IFDEF DEBUG
+MODULE=_ssl_d.pyd
+TEMP_DIR=x86-temp-debug/_ssl
+CFLAGS=/Od /Zi /MDd /LDd /DDEBUG /D_DEBUG /DWIN32
+SSL_LIB_DIR=$(SSL_DIR)/out32.dbg
+!ELSE
+MODULE=_ssl.pyd
+TEMP_DIR=x86-temp-release/_ssl
+CFLAGS=/Ox /MD /LD /DWIN32
+SSL_LIB_DIR=$(SSL_DIR)/out32
+!ENDIF
+
+INCLUDES=-I ../Include -I ../PC -I $(SSL_DIR)/inc32
+LIBS=gdi32.lib wsock32.lib user32.lib advapi32.lib /libpath:$(SSL_LIB_DIR) libeay32.lib ssleay32.lib
+
+SOURCE=../Modules/_ssl.c $(SSL_LIB_DIR)/libeay32.lib $(SSL_LIB_DIR)/ssleay32.lib
+
+$(MODULE): $(SOURCE) ../PC/*.h ../Include/*.h
+    @if not exist "$(TEMP_DIR)/." mkdir "$(TEMP_DIR)"
+    cl /nologo $(SOURCE) $(CFLAGS) /Fo$(TEMP_DIR)\$*.obj $(INCLUDES) /link /out:$(MODULE) $(LIBS)

Added: vendor/Python/current/PCbuild8/_ssl.vcproj
===================================================================
--- vendor/Python/current/PCbuild8/_ssl.vcproj	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild8/_ssl.vcproj	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8,00"
+	Name="_ssl"
+	ProjectGUID="{8E85BA54-8A47-4C8B-B72E-8E17579CC6D7}"
+	RootNamespace="_ssl"
+	Keyword="MakeFileProj"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-release\_ssl"
+			ConfigurationType="0"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCNMakeTool"
+				BuildCommandLine="python build_ssl.py"
+				ReBuildCommandLine="python build_ssl.py -a"
+				CleanCommandLine="echo Nothing to do"
+				Output="_ssl.pyd"
+				PreprocessorDefinitions=""
+				IncludeSearchPath=""
+				ForcedIncludes=""
+				AssemblySearchPath=""
+				ForcedUsingAssemblies=""
+				CompileAsManaged=""
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-debug\_ssl"
+			ConfigurationType="0"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCNMakeTool"
+				BuildCommandLine="python_d -u build_ssl.py -d"
+				ReBuildCommandLine="python_d -u build_ssl.py -d -a"
+				CleanCommandLine="echo Nothing to do"
+				Output="_ssl_d.pyd"
+				PreprocessorDefinitions=""
+				IncludeSearchPath=""
+				ForcedIncludes=""
+				AssemblySearchPath=""
+				ForcedUsingAssemblies=""
+				CompileAsManaged=""
+			/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseItanium|Win32"
+			OutputDirectory="./."
+			IntermediateDirectory=".\ia64-temp-release\_ssl"
+			ConfigurationType="0"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCNMakeTool"
+				BuildCommandLine="python build_ssl.py"
+				ReBuildCommandLine="python build_ssl.py -a"
+				CleanCommandLine=""
+				Output="_ssl.pyd"
+				PreprocessorDefinitions=""
+				IncludeSearchPath=""
+				ForcedIncludes=""
+				AssemblySearchPath=""
+				ForcedUsingAssemblies=""
+				CompileAsManaged=""
+			/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseAMD64|Win32"
+			OutputDirectory="."
+			IntermediateDirectory="amd64-temp-release\_ssl"
+			ConfigurationType="0"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCNMakeTool"
+				BuildCommandLine="python build_ssl.py"
+				ReBuildCommandLine="python build_ssl.py -a"
+				CleanCommandLine=""
+				Output="_ssl.pyd"
+				PreprocessorDefinitions=""
+				IncludeSearchPath=""
+				ForcedIncludes=""
+				AssemblySearchPath=""
+				ForcedUsingAssemblies=""
+				CompileAsManaged=""
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath="..\Modules\_ssl.c"
+			>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Added: vendor/Python/current/PCbuild8/_testcapi.vcproj
===================================================================
--- vendor/Python/current/PCbuild8/_testcapi.vcproj	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild8/_testcapi.vcproj	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,374 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="_testcapi"
+	ProjectGUID="{59CBF474-9E06-4C50-9142-C44A118BB447}"
+	SccProjectName="_testcapi"
+	SccLocalPath=".."
+	SccProvider="MSSCCI:Perforce SCM"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-release\_testcapi"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MMAP_EXPORTS"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="./_testcapi.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				ProgramDatabaseFile=".\./_testcapi.pdb"
+				BaseAddress="0x1e1F0000"
+				ImportLibrary=".\./_testcapi.lib"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-debug\_testcapi"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;MMAP_EXPORTS"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="./_testcapi_d.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=".\./_testcapi_d.pdb"
+				BaseAddress="0x1e1F0000"
+				ImportLibrary=".\./_testcapi_d.lib"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseItanium|Win32"
+			OutputDirectory="./."
+			IntermediateDirectory=".\ia64-temp-release\_testcapi"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions=" /USECL:MS_ITANIUM"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MMAP_EXPORTS"
+				StringPooling="true"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="false"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions=" /MACHINE:IA64 /USELINK:MS_SDK"
+				OutputFile="./_testcapi.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				ProgramDatabaseFile=".\./_testcapi.pdb"
+				BaseAddress="0x1e1F0000"
+				ImportLibrary=".\./_testcapi.lib"
+				TargetMachine="0"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseAMD64|Win32"
+			OutputDirectory="."
+			IntermediateDirectory="amd64-temp-release\_testcapi"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions=" /USECL:MS_OPTERON /GS-"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MMAP_EXPORTS"
+				StringPooling="true"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="false"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions=" /MACHINE:AMD64 /USELINK:MS_SDK"
+				OutputFile="./_testcapi.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				ProgramDatabaseFile=".\./_testcapi.pdb"
+				BaseAddress="0x1e1F0000"
+				ImportLibrary=".\./_testcapi.lib"
+				TargetMachine="0"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath="..\Modules\_testcapimodule.c"
+			>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Added: vendor/Python/current/PCbuild8/_tkinter.vcproj
===================================================================
--- vendor/Python/current/PCbuild8/_tkinter.vcproj	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild8/_tkinter.vcproj	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,389 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="_tkinter"
+	ProjectGUID="{5B51DFF7-5DC0-41F8-8791-A4AB7114A151}"
+	SccProjectName="_tkinter"
+	SccLocalPath="..\.."
+	SccProvider="MSSCCI:Perforce SCM"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-release\_tkinter"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\..\tcltk\include,..\Include,..\PC"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;WITH_APPINIT"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="..\..\tcltk\lib\tk84.lib ..\..\tcltk\lib\tcl84.lib odbccp32.lib"
+				OutputFile="./_tkinter.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				AdditionalLibraryDirectories=""
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=".\./_tkinter.pdb"
+				SubSystem="2"
+				BaseAddress="0x1e190000"
+				ImportLibrary=".\./_tkinter.lib"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-debug\_tkinter"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\..\tcltk\include,..\Include,..\PC"
+				PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS;WITH_APPINIT"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="..\..\tcltk\lib\tk84.lib ..\..\tcltk\lib\tcl84.lib odbccp32.lib"
+				OutputFile="./_tkinter_d.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				AdditionalLibraryDirectories=""
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=".\./_tkinter_d.pdb"
+				SubSystem="2"
+				BaseAddress="0x1e190000"
+				ImportLibrary=".\./_tkinter_d.lib"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseItanium|Win32"
+			OutputDirectory="./."
+			IntermediateDirectory=".\ia64-temp-release\_tkinter"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions=" /USECL:MS_ITANIUM"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\..\tcltk\include,..\Include,..\PC"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;WITH_APPINIT"
+				StringPooling="true"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="false"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions=" /MACHINE:IA64 /USELINK:MS_SDK"
+				AdditionalDependencies="..\..\tcltk\lib\tk84.lib ..\..\tcltk\lib\tcl84.lib odbccp32.lib"
+				OutputFile="./_tkinter.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				AdditionalLibraryDirectories=""
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=".\./_tkinter.pdb"
+				SubSystem="2"
+				BaseAddress="0x1e190000"
+				ImportLibrary=".\./_tkinter.lib"
+				TargetMachine="0"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseAMD64|Win32"
+			OutputDirectory="."
+			IntermediateDirectory="amd64-temp-release\_tkinter"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions=" /USECL:MS_OPTERON /GS-"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\..\tcltk\include,..\Include,..\PC"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;WITH_APPINIT"
+				StringPooling="true"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="false"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions=" /MACHINE:AMD64 /USELINK:MS_SDK"
+				AdditionalDependencies="..\..\tcltk\lib\tk84.lib ..\..\tcltk\lib\tcl84.lib odbccp32.lib"
+				OutputFile="./_tkinter.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				AdditionalLibraryDirectories=""
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=".\./_tkinter.pdb"
+				SubSystem="2"
+				BaseAddress="0x1e190000"
+				ImportLibrary=".\./_tkinter.lib"
+				TargetMachine="0"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath="..\Modules\_tkinter.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\tkappinit.c"
+			>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Added: vendor/Python/current/PCbuild8/build_ssl.py
===================================================================
--- vendor/Python/current/PCbuild8/build_ssl.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild8/build_ssl.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,163 @@
+# Script for building the _ssl module for Windows.
+# Uses Perl to setup the OpenSSL environment correctly
+# and build OpenSSL, then invokes a simple nmake session
+# for _ssl.pyd itself.
+
+# THEORETICALLY, you can:
+# * Unpack the latest SSL release one level above your main Python source
+#   directory.  It is likely you will already find the zlib library and
+#   any other external packages there.
+# * Install ActivePerl and ensure it is somewhere on your path.
+# * Run this script from the PCBuild directory.
+#
+# it should configure and build SSL, then build the ssl Python extension
+# without intervention.
+
+import os, sys, re
+
+# Find all "foo.exe" files on the PATH.
+def find_all_on_path(filename, extras = None):
+    entries = os.environ["PATH"].split(os.pathsep)
+    ret = []
+    for p in entries:
+        fname = os.path.abspath(os.path.join(p, filename))
+        if os.path.isfile(fname) and fname not in ret:
+            ret.append(fname)
+    if extras:
+        for p in extras:
+            fname = os.path.abspath(os.path.join(p, filename))
+            if os.path.isfile(fname) and fname not in ret:
+                ret.append(fname)
+    return ret
+
+# Find a suitable Perl installation for OpenSSL.
+# cygwin perl does *not* work.  ActivePerl does.
+# Being a Perl dummy, the simplest way I can check is if the "Win32" package
+# is available.
+def find_working_perl(perls):
+    for perl in perls:
+        fh = os.popen(perl + ' -e "use Win32;"')
+        fh.read()
+        rc = fh.close()
+        if rc:
+            continue
+        return perl
+    print "Can not find a suitable PERL:"
+    if perls:
+        print " the following perl interpreters were found:"
+        for p in perls:
+            print " ", p
+        print " None of these versions appear suitable for building OpenSSL"
+    else:
+        print " NO perl interpreters were found on this machine at all!"
+    print " Please install ActivePerl and ensure it appears on your path"
+    print "The Python SSL module was not built"
+    return None
+
+# Locate the best SSL directory given a few roots to look into.
+def find_best_ssl_dir(sources):
+    candidates = []
+    for s in sources:
+        try:
+            s = os.path.abspath(s)
+            fnames = os.listdir(s)
+        except os.error:
+            fnames = []
+        for fname in fnames:
+            fqn = os.path.join(s, fname)
+            if os.path.isdir(fqn) and fname.startswith("openssl-"):
+                candidates.append(fqn)
+    # Now we have all the candidates, locate the best.
+    best_parts = []
+    best_name = None
+    for c in candidates:
+        parts = re.split("[.-]", os.path.basename(c))[1:]
+        # eg - openssl-0.9.7-beta1 - ignore all "beta" or any other qualifiers
+        if len(parts) >= 4:
+            continue
+        if parts > best_parts:
+            best_parts = parts
+            best_name = c
+    if best_name is not None:
+        print "Found an SSL directory at '%s'" % (best_name,)
+    else:
+        print "Could not find an SSL directory in '%s'" % (sources,)
+    return best_name
+
+def main():
+    debug = "-d" in sys.argv
+    build_all = "-a" in sys.argv
+    make_flags = ""
+    if build_all:
+        make_flags = "-a"
+    # perl should be on the path, but we also look in "\perl" and "c:\\perl"
+    # as "well known" locations
+    perls = find_all_on_path("perl.exe", ["\\perl\\bin", "C:\\perl\\bin"])
+    perl = find_working_perl(perls)
+    if perl is None:
+        sys.exit(1)
+
+    print "Found a working perl at '%s'" % (perl,)
+    # Look for SSL 2 levels up from pcbuild - ie, same place zlib etc all live.
+    ssl_dir = find_best_ssl_dir(("../..",))
+    if ssl_dir is None:
+        sys.exit(1)
+
+    old_cd = os.getcwd()
+    try:
+        os.chdir(ssl_dir)
+        # If the ssl makefiles do not exist, we invoke Perl to generate them.
+        if not os.path.isfile(os.path.join(ssl_dir, "32.mak")) or \
+           not os.path.isfile(os.path.join(ssl_dir, "d32.mak")):
+            print "Creating the makefiles..."
+            # Put our working Perl at the front of our path
+            os.environ["PATH"] = os.path.split(perl)[0] + \
+                                          os.pathsep + \
+                                          os.environ["PATH"]
+            # ms\32all.bat will reconfigure OpenSSL and then try to build
+            # all outputs (debug/nondebug/dll/lib).  So we filter the file
+            # to exclude any "nmake" commands and then execute.
+            tempname = "ms\\32all_py.bat"
+
+            in_bat  = open("ms\\32all.bat")
+            temp_bat = open(tempname,"w")
+            while 1:
+                cmd = in_bat.readline()
+                print 'cmd', repr(cmd)
+                if not cmd: break
+                if cmd.strip()[:5].lower() == "nmake":
+                    continue
+                temp_bat.write(cmd)
+            in_bat.close()
+            temp_bat.close()
+            os.system(tempname)
+            try:
+                os.remove(tempname)
+            except:
+                pass
+
+        # Now run make.
+        print "Executing nmake over the ssl makefiles..."
+        if debug:
+            rc = os.system("nmake /nologo -f d32.mak")
+            if rc:
+                print "Executing d32.mak failed"
+                print rc
+                sys.exit(rc)
+        else:
+            rc = os.system("nmake /nologo -f 32.mak")
+            if rc:
+                print "Executing 32.mak failed"
+                print rc
+                sys.exit(rc)
+    finally:
+        os.chdir(old_cd)
+    # And finally, we can build the _ssl module itself for Python.
+    defs = "SSL_DIR=%s" % (ssl_dir,)
+    if debug:
+        defs = defs + " " + "DEBUG=1"
+    rc = os.system('nmake /nologo -f _ssl.mak ' + defs + " " + make_flags)
+    sys.exit(rc)
+
+if __name__=='__main__':
+    main()

Added: vendor/Python/current/PCbuild8/bz2.vcproj
===================================================================
--- vendor/Python/current/PCbuild8/bz2.vcproj	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild8/bz2.vcproj	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,390 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="bz2"
+	ProjectGUID="{AC557788-6354-43F7-BE05-C9C8C59A344A}"
+	RootNamespace="bz2"
+	SccProjectName="bz2"
+	SccLocalPath=".."
+	SccProvider="MSSCCI:Perforce SCM"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-debug\bz2"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\Include,..\PC,..\..\bzip2-1.0.3"
+				PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				CommandLine="cd ..\..\bzip2-1.0.3&#x0D;&#x0A;nmake /nologo /f makefile.msc&#x0D;&#x0A;"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="..\..\bzip2-1.0.3\libbz2.lib"
+				OutputFile="./bz2_d.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				IgnoreDefaultLibraryNames="msvcrt,libc"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=".\./bz2_d.pdb"
+				SubSystem="2"
+				BaseAddress="0x1D170000"
+				ImportLibrary=".\./bz2_d.lib"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-release\bz2"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC,..\..\bzip2-1.0.3"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				CommandLine="cd ..\..\bzip2-1.0.3&#x0D;&#x0A;nmake /nologo /f makefile.msc lib&#x0D;&#x0A;"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="..\..\bzip2-1.0.3\libbz2.lib"
+				OutputFile="./bz2.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				IgnoreDefaultLibraryNames="libc"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=".\./bz2.pdb"
+				SubSystem="2"
+				BaseAddress="0x1D170000"
+				ImportLibrary=".\./bz2.lib"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseItanium|Win32"
+			OutputDirectory="./."
+			IntermediateDirectory=".\ia64-temp-release\bz2"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions=" /USECL:MS_ITANIUM"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC,..\..\bzip2-1.0.3"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS"
+				StringPooling="true"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="false"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				CommandLine="cd ..\..\bzip2-1.0.3&#x0D;&#x0A;nmake /nologo /f makefile.msc lib&#x0D;&#x0A;"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions=" /MACHINE:IA64 /USELINK:MS_SDK"
+				AdditionalDependencies="..\..\bzip2-1.0.3\libbz2.lib"
+				OutputFile="./bz2.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				IgnoreDefaultLibraryNames="libc"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=".\./bz2.pdb"
+				SubSystem="2"
+				BaseAddress="0x1D170000"
+				ImportLibrary=".\./bz2.lib"
+				TargetMachine="0"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseAMD64|Win32"
+			OutputDirectory="."
+			IntermediateDirectory="amd64-temp-release\bz2"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions=" /USECL:MS_OPTERON /GS-"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC,..\..\bzip2-1.0.3"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS"
+				StringPooling="true"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="false"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				CommandLine="cd ..\..\bzip2-1.0.3&#x0D;&#x0A;nmake /nologo /f makefile.msc lib&#x0D;&#x0A;"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions=" /MACHINE:AMD64 /USELINK:MS_SDK"
+				AdditionalDependencies="..\..\bzip2-1.0.3\libbz2.lib"
+				OutputFile="./bz2.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				IgnoreDefaultLibraryNames="libc"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=".\./bz2.pdb"
+				SubSystem="2"
+				BaseAddress="0x1D170000"
+				ImportLibrary=".\./bz2.lib"
+				TargetMachine="0"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath="..\Modules\bz2module.c"
+			>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Added: vendor/Python/current/PCbuild8/db.build
===================================================================
--- vendor/Python/current/PCbuild8/db.build	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild8/db.build	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+<project>
+ <target name="all" description="Build all targets.">
+   <solution configuration="release">
+     <projects>
+       <include name="db_static.vcproj" />
+     </projects>
+   </solution>
+ </target>
+</project>

Added: vendor/Python/current/PCbuild8/field3.py
===================================================================
--- vendor/Python/current/PCbuild8/field3.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild8/field3.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,35 @@
+# An absurd workaround for the lack of arithmetic in MS's resource compiler.
+# After building Python, run this, then paste the output into the appropriate
+# part of PC\python_nt.rc.
+# Example output:
+#
+# * For 2.3a0,
+# * PY_MICRO_VERSION = 0
+# * PY_RELEASE_LEVEL = 'alpha' = 0xA
+# * PY_RELEASE_SERIAL = 1
+# *
+# * and 0*1000 + 10*10 + 1 = 101.
+# */
+# #define FIELD3 101
+
+import sys
+
+major, minor, micro, level, serial = sys.version_info
+levelnum = {'alpha': 0xA,
+            'beta': 0xB,
+            'candidate': 0xC,
+            'final': 0xF,
+           }[level]
+string = sys.version.split()[0] # like '2.3a0'
+
+print " * For %s," % string
+print " * PY_MICRO_VERSION = %d" % micro
+print " * PY_RELEASE_LEVEL = %r = %s" % (level, hex(levelnum))
+print " * PY_RELEASE_SERIAL = %d" % serial
+print " *"
+
+field3 = micro * 1000 + levelnum * 10 + serial
+
+print " * and %d*1000 + %d*10 + %d = %d" % (micro, levelnum, serial, field3)
+print " */"
+print "#define FIELD3", field3

Added: vendor/Python/current/PCbuild8/installer.bmp
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/PCbuild8/installer.bmp
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/PCbuild8/make_buildinfo.c
===================================================================
--- vendor/Python/current/PCbuild8/make_buildinfo.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild8/make_buildinfo.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,81 @@
+#include <windows.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+
+/* This file creates the getbuildinfo2.c file, by
+   invoking subwcrev.exe (if found).
+   If this isn't a subversion checkout, or subwcrev isn't
+   found, it copies ..\\Modules\\getbuildinfo.c instead.
+
+   A file, getbuildinfo2.h is then updated to define
+   SUBWCREV if it was a subversion checkout.
+
+   getbuildinfo2.c is part of the pythoncore project with
+   getbuildinfo2.h as a forced include.  This helps
+   VisualStudio refrain from unnecessary compiles much of the
+   time.
+
+   Currently, subwcrev.exe is found from the registry entries
+   of TortoiseSVN.
+
+   make_buildinfo.exe is called as a pre-build step for pythoncore.
+
+*/
+
+int make_buildinfo2()
+{
+	struct _stat st;
+	HKEY hTortoise;
+	char command[500];
+	DWORD type, size;
+	if (_stat(".svn", &st) < 0)
+		return 0;
+	/* Allow suppression of subwcrev.exe invocation if a no_subwcrev file is present. */
+	if (_stat("no_subwcrev", &st) == 0)
+		return 0;
+	if (RegOpenKey(HKEY_LOCAL_MACHINE, "Software\\TortoiseSVN", &hTortoise) != ERROR_SUCCESS &&
+	    RegOpenKey(HKEY_CURRENT_USER, "Software\\TortoiseSVN", &hTortoise) != ERROR_SUCCESS)
+		/* Tortoise not installed */
+		return 0;
+	command[0] = '"';  /* quote the path to the executable */
+	size = sizeof(command) - 1;
+	if (RegQueryValueEx(hTortoise, "Directory", 0, &type, command+1, &size) != ERROR_SUCCESS ||
+	    type != REG_SZ)
+		/* Registry corrupted */
+		return 0;
+	strcat_s(command, sizeof(command), "bin\\subwcrev.exe");
+	if (_stat(command+1, &st) < 0)
+		/* subwcrev.exe not part of the release */
+		return 0;
+	strcat_s(command, sizeof(command), "\" .. ..\\Modules\\getbuildinfo.c getbuildinfo2.c");
+	puts(command); fflush(stdout);
+	if (system(command) < 0)
+		return 0;
+	return 1;
+}
+
+int main(int argc, char*argv[])
+{
+	char command[500] = "";
+	int svn;
+	FILE *f;
+
+	if (fopen_s(&f, "getbuildinfo2.h", "w"))
+		return EXIT_FAILURE;
+	/* Get getbuildinfo.c from svn as getbuildinfo2.c */
+	svn = make_buildinfo2();
+	if (svn) {
+		puts("got getbuildinfo2.c from svn.  Updating getbuildinfo2.h");
+		/* yes.  make sure SUBWCREV is defined */
+		fprintf(f, "#define SUBWCREV\n");
+	} else {
+		puts("didn't get getbuildinfo2.c from svn.  Copying from Modules and clearing getbuildinfo2.h");
+		strcat_s(command, sizeof(command), "copy ..\\Modules\\getbuildinfo.c getbuildinfo2.c");
+		puts(command); fflush(stdout);
+		if (system(command) < 0)
+			return EXIT_FAILURE;
+	}
+	fclose(f);
+	return 0;
+}
\ No newline at end of file

Added: vendor/Python/current/PCbuild8/make_buildinfo.vcproj
===================================================================
--- vendor/Python/current/PCbuild8/make_buildinfo.vcproj	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild8/make_buildinfo.vcproj	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="windows-1250"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8,00"
+	Name="make_buildinfo"
+	ProjectGUID="{C73F0EC1-358B-4177-940F-0846AC8B04CD}"
+	RootNamespace="make_buildinfo"
+	Keyword="Win32Proj"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="."
+			IntermediateDirectory=".\x86-temp-release\make_buildinfo"
+			ConfigurationType="1"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="1"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)/make_buildinfo.exe"
+				LinkIncremental="2"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile="$(OutDir)/make_buildinfo.pdb"
+				SubSystem="1"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				Description="Making getbuildinfo2.c"
+				CommandLine="$(TargetPath)"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath=".\make_buildinfo.c"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Added: vendor/Python/current/PCbuild8/make_versioninfo.vcproj
===================================================================
--- vendor/Python/current/PCbuild8/make_versioninfo.vcproj	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild8/make_versioninfo.vcproj	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,204 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8,00"
+	Name="make_versioninfo"
+	ProjectGUID="{F0E0541E-F17D-430B-97C4-93ADF0DD284E}"
+	RootNamespace="make_versioninfo"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-release\make_versioninfo"
+			ConfigurationType="1"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+				CommandLine=".\make_versioninfo.exe &gt;..\PC\pythonnt_rc.h&#x0D;&#x0A;"
+				Outputs="..\PC\pythonnt_rc.h"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="odbccp32.lib"
+				OutputFile=".\./make_versioninfo.exe"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=".\./make_versioninfo.pdb"
+				SubSystem="1"
+				BaseAddress="0x1d000000"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				CommandLine="$(TargetFileName) &gt; ..\PC\python_nt.h"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-debug\make_versioninfo"
+			ConfigurationType="1"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+				CommandLine=".\make_versioninfo_d.exe &gt;..\PC\pythonnt_rc_d.h&#x0D;&#x0A;"
+				Outputs="..\PC\pythonnt_rc_d.h"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				BrowseInformation="1"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="odbccp32.lib"
+				OutputFile="./make_versioninfo_d.exe"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=".\./make_versioninfo_d.pdb"
+				SubSystem="1"
+				BaseAddress="0x1d000000"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				CommandLine="$(TargetFileName) &gt; ..\PC\python_nt_d.h"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath="..\PC\make_versioninfo.c"
+			>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Added: vendor/Python/current/PCbuild8/pcbuild.sln
===================================================================
--- vendor/Python/current/PCbuild8/pcbuild.sln	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild8/pcbuild.sln	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,306 @@
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythoncore", "pythoncore.vcproj", "{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}"
+	ProjectSection(ProjectDependencies) = postProject
+		{F0E0541E-F17D-430B-97C4-93ADF0DD284E} = {F0E0541E-F17D-430B-97C4-93ADF0DD284E}
+		{C73F0EC1-358B-4177-940F-0846AC8B04CD} = {C73F0EC1-358B-4177-940F-0846AC8B04CD}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythonw", "pythonw.vcproj", "{F4229CC3-873C-49AE-9729-DD308ED4CD4A}"
+	ProjectSection(ProjectDependencies) = postProject
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "select", "select.vcproj", "{97239A56-DBC0-41D2-BC14-C87D9B97D63B}"
+	ProjectSection(ProjectDependencies) = postProject
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unicodedata", "unicodedata.vcproj", "{FA5FC7EB-C72F-415F-AE42-91DD605ABDDA}"
+	ProjectSection(ProjectDependencies) = postProject
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "w9xpopen", "w9xpopen.vcproj", "{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "winsound", "winsound.vcproj", "{51F35FAE-FB92-4B2C-9187-1542C065AD77}"
+	ProjectSection(ProjectDependencies) = postProject
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_elementtree", "_elementtree.vcproj", "{1966DDE2-4AB7-4E4E-ACC9-C121E4D37F8E}"
+	ProjectSection(ProjectDependencies) = postProject
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "make_buildinfo", "make_buildinfo.vcproj", "{C73F0EC1-358B-4177-940F-0846AC8B04CD}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_msi", "_msi.vcproj", "{2C0BEFB9-70E2-4F80-AC5B-4AB8EE023574}"
+	ProjectSection(ProjectDependencies) = postProject
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_ctypes", "_ctypes.vcproj", "{F22F40F4-D318-40DC-96B3-88DC81CE0894}"
+	ProjectSection(ProjectDependencies) = postProject
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_ctypes_test", "_ctypes_test.vcproj", "{8CF334D9-4F82-42EB-97AF-83592C5AFD2F}"
+	ProjectSection(ProjectDependencies) = postProject
+		{F22F40F4-D318-40DC-96B3-88DC81CE0894} = {F22F40F4-D318-40DC-96B3-88DC81CE0894}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_sqlite3", "_sqlite3.vcproj", "{2FF0A312-22F9-4C34-B070-842916DE27A9}"
+	ProjectSection(ProjectDependencies) = postProject
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
+	EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8B172265-1F31-4880-A29C-11A4B7A80172}"
+	ProjectSection(SolutionItems) = preProject
+		..\Modules\getbuildinfo.c = ..\Modules\getbuildinfo.c
+		readme.txt = readme.txt
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "python", "python.vcproj", "{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}"
+	ProjectSection(ProjectDependencies) = postProject
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "make_versioninfo", "make_versioninfo.vcproj", "{F0E0541E-F17D-430B-97C4-93ADF0DD284E}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Debug|x64 = Debug|x64
+		PGIRelease|Win32 = PGIRelease|Win32
+		PGIRelease|x64 = PGIRelease|x64
+		PGORelease|Win32 = PGORelease|Win32
+		PGORelease|x64 = PGORelease|x64
+		Release|Win32 = Release|Win32
+		Release|x64 = Release|x64
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug|Win32.ActiveCfg = Debug|Win32
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug|Win32.Build.0 = Debug|Win32
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug|x64.ActiveCfg = Debug|x64
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug|x64.Build.0 = Debug|x64
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGIRelease|Win32.ActiveCfg = PGIRelease|Win32
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGIRelease|Win32.Build.0 = PGIRelease|Win32
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGIRelease|x64.ActiveCfg = PGIRelease|x64
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGIRelease|x64.Build.0 = PGIRelease|x64
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGORelease|Win32.ActiveCfg = PGORelease|Win32
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGORelease|Win32.Build.0 = PGORelease|Win32
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGORelease|x64.ActiveCfg = PGORelease|x64
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGORelease|x64.Build.0 = PGORelease|x64
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Release|Win32.ActiveCfg = Release|Win32
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Release|Win32.Build.0 = Release|Win32
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Release|x64.ActiveCfg = Release|x64
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Release|x64.Build.0 = Release|x64
+		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug|Win32.ActiveCfg = Debug|Win32
+		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug|Win32.Build.0 = Debug|Win32
+		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug|x64.ActiveCfg = Debug|x64
+		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug|x64.Build.0 = Debug|x64
+		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGIRelease|Win32.ActiveCfg = Release|Win32
+		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGIRelease|Win32.Build.0 = Release|Win32
+		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGIRelease|x64.ActiveCfg = Release|x64
+		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGIRelease|x64.Build.0 = Release|x64
+		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGORelease|Win32.ActiveCfg = Release|Win32
+		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGORelease|Win32.Build.0 = Release|Win32
+		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGORelease|x64.ActiveCfg = Release|x64
+		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGORelease|x64.Build.0 = Release|x64
+		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|Win32.ActiveCfg = Release|Win32
+		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|Win32.Build.0 = Release|Win32
+		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|x64.ActiveCfg = Release|x64
+		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|x64.Build.0 = Release|x64
+		{97239A56-DBC0-41D2-BC14-C87D9B97D63B}.Debug|Win32.ActiveCfg = Debug|Win32
+		{97239A56-DBC0-41D2-BC14-C87D9B97D63B}.Debug|Win32.Build.0 = Debug|Win32
+		{97239A56-DBC0-41D2-BC14-C87D9B97D63B}.Debug|x64.ActiveCfg = Debug|x64
+		{97239A56-DBC0-41D2-BC14-C87D9B97D63B}.Debug|x64.Build.0 = Debug|x64
+		{97239A56-DBC0-41D2-BC14-C87D9B97D63B}.PGIRelease|Win32.ActiveCfg = Release|Win32
+		{97239A56-DBC0-41D2-BC14-C87D9B97D63B}.PGIRelease|Win32.Build.0 = Release|Win32
+		{97239A56-DBC0-41D2-BC14-C87D9B97D63B}.PGIRelease|x64.ActiveCfg = Release|x64
+		{97239A56-DBC0-41D2-BC14-C87D9B97D63B}.PGIRelease|x64.Build.0 = Release|x64
+		{97239A56-DBC0-41D2-BC14-C87D9B97D63B}.PGORelease|Win32.ActiveCfg = Release|Win32
+		{97239A56-DBC0-41D2-BC14-C87D9B97D63B}.PGORelease|Win32.Build.0 = Release|Win32
+		{97239A56-DBC0-41D2-BC14-C87D9B97D63B}.PGORelease|x64.ActiveCfg = Release|x64
+		{97239A56-DBC0-41D2-BC14-C87D9B97D63B}.PGORelease|x64.Build.0 = Release|x64
+		{97239A56-DBC0-41D2-BC14-C87D9B97D63B}.Release|Win32.ActiveCfg = Release|Win32
+		{97239A56-DBC0-41D2-BC14-C87D9B97D63B}.Release|Win32.Build.0 = Release|Win32
+		{97239A56-DBC0-41D2-BC14-C87D9B97D63B}.Release|x64.ActiveCfg = Release|x64
+		{97239A56-DBC0-41D2-BC14-C87D9B97D63B}.Release|x64.Build.0 = Release|x64
+		{FA5FC7EB-C72F-415F-AE42-91DD605ABDDA}.Debug|Win32.ActiveCfg = Debug|Win32
+		{FA5FC7EB-C72F-415F-AE42-91DD605ABDDA}.Debug|Win32.Build.0 = Debug|Win32
+		{FA5FC7EB-C72F-415F-AE42-91DD605ABDDA}.Debug|x64.ActiveCfg = Debug|x64
+		{FA5FC7EB-C72F-415F-AE42-91DD605ABDDA}.Debug|x64.Build.0 = Debug|x64
+		{FA5FC7EB-C72F-415F-AE42-91DD605ABDDA}.PGIRelease|Win32.ActiveCfg = Release|Win32
+		{FA5FC7EB-C72F-415F-AE42-91DD605ABDDA}.PGIRelease|Win32.Build.0 = Release|Win32
+		{FA5FC7EB-C72F-415F-AE42-91DD605ABDDA}.PGIRelease|x64.ActiveCfg = Release|x64
+		{FA5FC7EB-C72F-415F-AE42-91DD605ABDDA}.PGIRelease|x64.Build.0 = Release|x64
+		{FA5FC7EB-C72F-415F-AE42-91DD605ABDDA}.PGORelease|Win32.ActiveCfg = Release|Win32
+		{FA5FC7EB-C72F-415F-AE42-91DD605ABDDA}.PGORelease|Win32.Build.0 = Release|Win32
+		{FA5FC7EB-C72F-415F-AE42-91DD605ABDDA}.PGORelease|x64.ActiveCfg = Release|x64
+		{FA5FC7EB-C72F-415F-AE42-91DD605ABDDA}.PGORelease|x64.Build.0 = Release|x64
+		{FA5FC7EB-C72F-415F-AE42-91DD605ABDDA}.Release|Win32.ActiveCfg = Release|Win32
+		{FA5FC7EB-C72F-415F-AE42-91DD605ABDDA}.Release|Win32.Build.0 = Release|Win32
+		{FA5FC7EB-C72F-415F-AE42-91DD605ABDDA}.Release|x64.ActiveCfg = Release|x64
+		{FA5FC7EB-C72F-415F-AE42-91DD605ABDDA}.Release|x64.Build.0 = Release|x64
+		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.Debug|Win32.ActiveCfg = Debug|Win32
+		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.Debug|Win32.Build.0 = Debug|Win32
+		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.Debug|x64.ActiveCfg = Debug|x64
+		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.Debug|x64.Build.0 = Debug|x64
+		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.PGIRelease|Win32.ActiveCfg = Release|Win32
+		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.PGIRelease|Win32.Build.0 = Release|Win32
+		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.PGIRelease|x64.ActiveCfg = Release|x64
+		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.PGIRelease|x64.Build.0 = Release|x64
+		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.PGORelease|Win32.ActiveCfg = Release|Win32
+		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.PGORelease|Win32.Build.0 = Release|Win32
+		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.PGORelease|x64.ActiveCfg = Release|x64
+		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.PGORelease|x64.Build.0 = Release|x64
+		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.Release|Win32.ActiveCfg = Release|Win32
+		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.Release|Win32.Build.0 = Release|Win32
+		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.Release|x64.ActiveCfg = Release|x64
+		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.Release|x64.Build.0 = Release|x64
+		{51F35FAE-FB92-4B2C-9187-1542C065AD77}.Debug|Win32.ActiveCfg = Debug|Win32
+		{51F35FAE-FB92-4B2C-9187-1542C065AD77}.Debug|Win32.Build.0 = Debug|Win32
+		{51F35FAE-FB92-4B2C-9187-1542C065AD77}.Debug|x64.ActiveCfg = Debug|x64
+		{51F35FAE-FB92-4B2C-9187-1542C065AD77}.Debug|x64.Build.0 = Debug|x64
+		{51F35FAE-FB92-4B2C-9187-1542C065AD77}.PGIRelease|Win32.ActiveCfg = Release|Win32
+		{51F35FAE-FB92-4B2C-9187-1542C065AD77}.PGIRelease|Win32.Build.0 = Release|Win32
+		{51F35FAE-FB92-4B2C-9187-1542C065AD77}.PGIRelease|x64.ActiveCfg = Release|x64
+		{51F35FAE-FB92-4B2C-9187-1542C065AD77}.PGIRelease|x64.Build.0 = Release|x64
+		{51F35FAE-FB92-4B2C-9187-1542C065AD77}.PGORelease|Win32.ActiveCfg = Release|Win32
+		{51F35FAE-FB92-4B2C-9187-1542C065AD77}.PGORelease|Win32.Build.0 = Release|Win32
+		{51F35FAE-FB92-4B2C-9187-1542C065AD77}.PGORelease|x64.ActiveCfg = Release|x64
+		{51F35FAE-FB92-4B2C-9187-1542C065AD77}.PGORelease|x64.Build.0 = Release|x64
+		{51F35FAE-FB92-4B2C-9187-1542C065AD77}.Release|Win32.ActiveCfg = Release|Win32
+		{51F35FAE-FB92-4B2C-9187-1542C065AD77}.Release|Win32.Build.0 = Release|Win32
+		{51F35FAE-FB92-4B2C-9187-1542C065AD77}.Release|x64.ActiveCfg = Release|x64
+		{51F35FAE-FB92-4B2C-9187-1542C065AD77}.Release|x64.Build.0 = Release|x64
+		{1966DDE2-4AB7-4E4E-ACC9-C121E4D37F8E}.Debug|Win32.ActiveCfg = Debug|Win32
+		{1966DDE2-4AB7-4E4E-ACC9-C121E4D37F8E}.Debug|Win32.Build.0 = Debug|Win32
+		{1966DDE2-4AB7-4E4E-ACC9-C121E4D37F8E}.Debug|x64.ActiveCfg = Debug|x64
+		{1966DDE2-4AB7-4E4E-ACC9-C121E4D37F8E}.Debug|x64.Build.0 = Debug|x64
+		{1966DDE2-4AB7-4E4E-ACC9-C121E4D37F8E}.PGIRelease|Win32.ActiveCfg = Release|Win32
+		{1966DDE2-4AB7-4E4E-ACC9-C121E4D37F8E}.PGIRelease|Win32.Build.0 = Release|Win32
+		{1966DDE2-4AB7-4E4E-ACC9-C121E4D37F8E}.PGIRelease|x64.ActiveCfg = Release|x64
+		{1966DDE2-4AB7-4E4E-ACC9-C121E4D37F8E}.PGIRelease|x64.Build.0 = Release|x64
+		{1966DDE2-4AB7-4E4E-ACC9-C121E4D37F8E}.PGORelease|Win32.ActiveCfg = Release|Win32
+		{1966DDE2-4AB7-4E4E-ACC9-C121E4D37F8E}.PGORelease|Win32.Build.0 = Release|Win32
+		{1966DDE2-4AB7-4E4E-ACC9-C121E4D37F8E}.PGORelease|x64.ActiveCfg = Release|x64
+		{1966DDE2-4AB7-4E4E-ACC9-C121E4D37F8E}.PGORelease|x64.Build.0 = Release|x64
+		{1966DDE2-4AB7-4E4E-ACC9-C121E4D37F8E}.Release|Win32.ActiveCfg = Release|Win32
+		{1966DDE2-4AB7-4E4E-ACC9-C121E4D37F8E}.Release|Win32.Build.0 = Release|Win32
+		{1966DDE2-4AB7-4E4E-ACC9-C121E4D37F8E}.Release|x64.ActiveCfg = Release|x64
+		{1966DDE2-4AB7-4E4E-ACC9-C121E4D37F8E}.Release|x64.Build.0 = Release|x64
+		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.Debug|Win32.ActiveCfg = Debug|Win32
+		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.Debug|Win32.Build.0 = Debug|Win32
+		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.Debug|x64.ActiveCfg = Debug|Win32
+		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.Debug|x64.Build.0 = Debug|Win32
+		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGIRelease|Win32.ActiveCfg = Debug|Win32
+		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGIRelease|Win32.Build.0 = Debug|Win32
+		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGIRelease|x64.ActiveCfg = Debug|Win32
+		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGORelease|Win32.ActiveCfg = Debug|Win32
+		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGORelease|Win32.Build.0 = Debug|Win32
+		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGORelease|x64.ActiveCfg = Debug|Win32
+		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.Release|Win32.ActiveCfg = Debug|Win32
+		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.Release|Win32.Build.0 = Debug|Win32
+		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.Release|x64.ActiveCfg = Debug|Win32
+		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.Release|x64.Build.0 = Debug|Win32
+		{2C0BEFB9-70E2-4F80-AC5B-4AB8EE023574}.Debug|Win32.ActiveCfg = Debug|Win32
+		{2C0BEFB9-70E2-4F80-AC5B-4AB8EE023574}.Debug|Win32.Build.0 = Debug|Win32
+		{2C0BEFB9-70E2-4F80-AC5B-4AB8EE023574}.Debug|x64.ActiveCfg = Debug|x64
+		{2C0BEFB9-70E2-4F80-AC5B-4AB8EE023574}.Debug|x64.Build.0 = Debug|x64
+		{2C0BEFB9-70E2-4F80-AC5B-4AB8EE023574}.PGIRelease|Win32.ActiveCfg = Release|Win32
+		{2C0BEFB9-70E2-4F80-AC5B-4AB8EE023574}.PGIRelease|Win32.Build.0 = Release|Win32
+		{2C0BEFB9-70E2-4F80-AC5B-4AB8EE023574}.PGIRelease|x64.ActiveCfg = Release|x64
+		{2C0BEFB9-70E2-4F80-AC5B-4AB8EE023574}.PGIRelease|x64.Build.0 = Release|x64
+		{2C0BEFB9-70E2-4F80-AC5B-4AB8EE023574}.PGORelease|Win32.ActiveCfg = Release|Win32
+		{2C0BEFB9-70E2-4F80-AC5B-4AB8EE023574}.PGORelease|Win32.Build.0 = Release|Win32
+		{2C0BEFB9-70E2-4F80-AC5B-4AB8EE023574}.PGORelease|x64.ActiveCfg = Release|x64
+		{2C0BEFB9-70E2-4F80-AC5B-4AB8EE023574}.PGORelease|x64.Build.0 = Release|x64
+		{2C0BEFB9-70E2-4F80-AC5B-4AB8EE023574}.Release|Win32.ActiveCfg = Release|Win32
+		{2C0BEFB9-70E2-4F80-AC5B-4AB8EE023574}.Release|Win32.Build.0 = Release|Win32
+		{2C0BEFB9-70E2-4F80-AC5B-4AB8EE023574}.Release|x64.ActiveCfg = Release|x64
+		{2C0BEFB9-70E2-4F80-AC5B-4AB8EE023574}.Release|x64.Build.0 = Release|x64
+		{F22F40F4-D318-40DC-96B3-88DC81CE0894}.Debug|Win32.ActiveCfg = Debug|Win32
+		{F22F40F4-D318-40DC-96B3-88DC81CE0894}.Debug|Win32.Build.0 = Debug|Win32
+		{F22F40F4-D318-40DC-96B3-88DC81CE0894}.Debug|x64.ActiveCfg = Debug|x64
+		{F22F40F4-D318-40DC-96B3-88DC81CE0894}.Debug|x64.Build.0 = Debug|x64
+		{F22F40F4-D318-40DC-96B3-88DC81CE0894}.PGIRelease|Win32.ActiveCfg = Release|Win32
+		{F22F40F4-D318-40DC-96B3-88DC81CE0894}.PGIRelease|Win32.Build.0 = Release|Win32
+		{F22F40F4-D318-40DC-96B3-88DC81CE0894}.PGIRelease|x64.ActiveCfg = Release|x64
+		{F22F40F4-D318-40DC-96B3-88DC81CE0894}.PGIRelease|x64.Build.0 = Release|x64
+		{F22F40F4-D318-40DC-96B3-88DC81CE0894}.PGORelease|Win32.ActiveCfg = Release|Win32
+		{F22F40F4-D318-40DC-96B3-88DC81CE0894}.PGORelease|Win32.Build.0 = Release|Win32
+		{F22F40F4-D318-40DC-96B3-88DC81CE0894}.PGORelease|x64.ActiveCfg = Release|x64
+		{F22F40F4-D318-40DC-96B3-88DC81CE0894}.PGORelease|x64.Build.0 = Release|x64
+		{F22F40F4-D318-40DC-96B3-88DC81CE0894}.Release|Win32.ActiveCfg = Release|Win32
+		{F22F40F4-D318-40DC-96B3-88DC81CE0894}.Release|Win32.Build.0 = Release|Win32
+		{F22F40F4-D318-40DC-96B3-88DC81CE0894}.Release|x64.ActiveCfg = Release|x64
+		{8CF334D9-4F82-42EB-97AF-83592C5AFD2F}.Debug|Win32.ActiveCfg = Debug|Win32
+		{8CF334D9-4F82-42EB-97AF-83592C5AFD2F}.Debug|Win32.Build.0 = Debug|Win32
+		{8CF334D9-4F82-42EB-97AF-83592C5AFD2F}.Debug|x64.ActiveCfg = Debug|x64
+		{8CF334D9-4F82-42EB-97AF-83592C5AFD2F}.Debug|x64.Build.0 = Debug|x64
+		{8CF334D9-4F82-42EB-97AF-83592C5AFD2F}.PGIRelease|Win32.ActiveCfg = Release|Win32
+		{8CF334D9-4F82-42EB-97AF-83592C5AFD2F}.PGIRelease|Win32.Build.0 = Release|Win32
+		{8CF334D9-4F82-42EB-97AF-83592C5AFD2F}.PGIRelease|x64.ActiveCfg = Release|x64
+		{8CF334D9-4F82-42EB-97AF-83592C5AFD2F}.PGIRelease|x64.Build.0 = Release|x64
+		{8CF334D9-4F82-42EB-97AF-83592C5AFD2F}.PGORelease|Win32.ActiveCfg = Release|Win32
+		{8CF334D9-4F82-42EB-97AF-83592C5AFD2F}.PGORelease|Win32.Build.0 = Release|Win32
+		{8CF334D9-4F82-42EB-97AF-83592C5AFD2F}.PGORelease|x64.ActiveCfg = Release|x64
+		{8CF334D9-4F82-42EB-97AF-83592C5AFD2F}.PGORelease|x64.Build.0 = Release|x64
+		{8CF334D9-4F82-42EB-97AF-83592C5AFD2F}.Release|Win32.ActiveCfg = Release|Win32
+		{8CF334D9-4F82-42EB-97AF-83592C5AFD2F}.Release|Win32.Build.0 = Release|Win32
+		{8CF334D9-4F82-42EB-97AF-83592C5AFD2F}.Release|x64.ActiveCfg = Release|x64
+		{8CF334D9-4F82-42EB-97AF-83592C5AFD2F}.Release|x64.Build.0 = Release|x64
+		{2FF0A312-22F9-4C34-B070-842916DE27A9}.Debug|Win32.ActiveCfg = Debug|Win32
+		{2FF0A312-22F9-4C34-B070-842916DE27A9}.Debug|Win32.Build.0 = Debug|Win32
+		{2FF0A312-22F9-4C34-B070-842916DE27A9}.Debug|x64.ActiveCfg = Debug|x64
+		{2FF0A312-22F9-4C34-B070-842916DE27A9}.Debug|x64.Build.0 = Debug|x64
+		{2FF0A312-22F9-4C34-B070-842916DE27A9}.PGIRelease|Win32.ActiveCfg = Release|Win32
+		{2FF0A312-22F9-4C34-B070-842916DE27A9}.PGIRelease|Win32.Build.0 = Release|Win32
+		{2FF0A312-22F9-4C34-B070-842916DE27A9}.PGIRelease|x64.ActiveCfg = Release|x64
+		{2FF0A312-22F9-4C34-B070-842916DE27A9}.PGIRelease|x64.Build.0 = Release|x64
+		{2FF0A312-22F9-4C34-B070-842916DE27A9}.PGORelease|Win32.ActiveCfg = Release|Win32
+		{2FF0A312-22F9-4C34-B070-842916DE27A9}.PGORelease|Win32.Build.0 = Release|Win32
+		{2FF0A312-22F9-4C34-B070-842916DE27A9}.PGORelease|x64.ActiveCfg = Release|x64
+		{2FF0A312-22F9-4C34-B070-842916DE27A9}.PGORelease|x64.Build.0 = Release|x64
+		{2FF0A312-22F9-4C34-B070-842916DE27A9}.Release|Win32.ActiveCfg = Release|Win32
+		{2FF0A312-22F9-4C34-B070-842916DE27A9}.Release|Win32.Build.0 = Release|Win32
+		{2FF0A312-22F9-4C34-B070-842916DE27A9}.Release|x64.ActiveCfg = Release|x64
+		{2FF0A312-22F9-4C34-B070-842916DE27A9}.Release|x64.Build.0 = Release|x64
+		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug|Win32.ActiveCfg = Debug|Win32
+		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug|Win32.Build.0 = Debug|Win32
+		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug|x64.ActiveCfg = Debug|x64
+		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug|x64.Build.0 = Debug|x64
+		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGIRelease|Win32.ActiveCfg = Release|Win32
+		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGIRelease|Win32.Build.0 = Release|Win32
+		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGIRelease|x64.ActiveCfg = Release|x64
+		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGIRelease|x64.Build.0 = Release|x64
+		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGORelease|Win32.ActiveCfg = Release|Win32
+		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGORelease|Win32.Build.0 = Release|Win32
+		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGORelease|x64.ActiveCfg = Release|x64
+		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGORelease|x64.Build.0 = Release|x64
+		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|Win32.ActiveCfg = Release|Win32
+		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|Win32.Build.0 = Release|Win32
+		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|x64.ActiveCfg = Release|x64
+		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|x64.Build.0 = Release|x64
+		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Debug|Win32.ActiveCfg = Debug|Win32
+		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Debug|Win32.Build.0 = Debug|Win32
+		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Debug|x64.ActiveCfg = Debug|Win32
+		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Debug|x64.Build.0 = Debug|Win32
+		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGIRelease|Win32.ActiveCfg = Release|Win32
+		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGIRelease|Win32.Build.0 = Release|Win32
+		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGIRelease|x64.ActiveCfg = Release|Win32
+		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGORelease|Win32.ActiveCfg = Release|Win32
+		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGORelease|Win32.Build.0 = Release|Win32
+		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGORelease|x64.ActiveCfg = Release|Win32
+		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Release|Win32.ActiveCfg = Release|Win32
+		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Release|Win32.Build.0 = Release|Win32
+		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Release|x64.ActiveCfg = Release|Win32
+		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Release|x64.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal

Added: vendor/Python/current/PCbuild8/pyexpat.vcproj
===================================================================
--- vendor/Python/current/PCbuild8/pyexpat.vcproj	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild8/pyexpat.vcproj	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,393 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="pyexpat"
+	ProjectGUID="{7E551393-3C43-47F8-9F3F-5BC368A6C487}"
+	SccProjectName="pyexpat"
+	SccLocalPath=".."
+	SccProvider="MSSCCI:Perforce SCM"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-debug\pyexpat"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\Include,..\PC,..\Modules\expat"
+				PreprocessorDefinitions="_DEBUG;HAVE_EXPAT_H;WIN32;_WINDOWS;XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;XML_STATIC;HAVE_MEMMOVE"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="odbccp32.lib"
+				OutputFile="./pyexpat_d.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=".\./pyexpat_d.pdb"
+				SubSystem="2"
+				BaseAddress="0x1D100000"
+				ImportLibrary=".\./pyexpat_d.lib"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory=".\."
+			IntermediateDirectory=".\x86-temp-release\pyexpat"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC,..\Modules\expat"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;XML_STATIC;HAVE_MEMMOVE"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="odbccp32.lib"
+				OutputFile="./pyexpat.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=".\./pyexpat.pdb"
+				SubSystem="2"
+				BaseAddress="0x1D100000"
+				ImportLibrary=".\./pyexpat.lib"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseItanium|Win32"
+			OutputDirectory="./."
+			IntermediateDirectory=".\ia64-temp-release\pyexpat"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions=" /USECL:MS_ITANIUM"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC,..\Modules\expat"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;XML_STATIC;HAVE_MEMMOVE"
+				StringPooling="true"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="false"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions=" /MACHINE:IA64 /USELINK:MS_SDK"
+				AdditionalDependencies="odbccp32.lib"
+				OutputFile="./pyexpat.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=".\./pyexpat.pdb"
+				SubSystem="2"
+				BaseAddress="0x1D100000"
+				ImportLibrary=".\./pyexpat.lib"
+				TargetMachine="0"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseAMD64|Win32"
+			OutputDirectory="."
+			IntermediateDirectory="amd64-temp-release\pyexpat"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions=" /USECL:MS_OPTERON"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC,..\Modules\expat"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;XML_STATIC;HAVE_MEMMOVE"
+				StringPooling="true"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="false"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions=" /MACHINE:AMD64 /USELINK:MS_SDK"
+				AdditionalDependencies="odbccp32.lib"
+				OutputFile="./pyexpat.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=".\./pyexpat.pdb"
+				SubSystem="2"
+				BaseAddress="0x1D100000"
+				ImportLibrary=".\./pyexpat.lib"
+				TargetMachine="0"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath="..\Modules\pyexpat.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\expat\xmlparse.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\expat\xmlrole.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\expat\xmltok.c"
+			>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Added: vendor/Python/current/PCbuild8/python.build
===================================================================
--- vendor/Python/current/PCbuild8/python.build	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild8/python.build	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<project>
+ <target name="all" description="Build all targets.">
+   <solution configuration="release">
+     <projects>
+       <include name="make_versioninfo.vcproj" />
+     </projects>
+   </solution>
+   <exec program="make_versioninfo" output="pythonnt_rc.h" />
+
+   <solution configuration="release" solutionfile="pcbuild.sln">
+     <excludeprojects>
+       <include name="_tkinter.vcproj" />
+       <include name="bz2.vcproj" />
+       <include name="_bsddb.vcproj" />
+       <include name="_sqlite3.vcproj" />
+       <include name="_ssl.vcproj" />
+     </excludeprojects>
+   </solution>
+ </target>
+</project>

Added: vendor/Python/current/PCbuild8/python.iss
===================================================================
--- vendor/Python/current/PCbuild8/python.iss	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild8/python.iss	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,346 @@
+; Script generated by the Inno Setup Script Wizard.
+; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
+
+; This is the whole ball of wax for an Inno installer for Python.
+; To use, download Inno Setup from http://www.jrsoftware.org/isdl.htm/,
+; install it, and double-click on this file.  That launches the Inno
+; script compiler.  The GUI is extemely simple, and has only one button
+; you may not recognize instantly:  click it.  You're done.  It builds
+; the installer into PCBuild/Python-2.2a1.exe.  Size and speed of the
+; installer are competitive with the Wise installer; Inno uninstall
+; seems much quicker than Wise (but also feebler, and the uninstall
+; log is in some un(human)readable binary format).
+;
+; What's Done
+; -----------
+; All the usual Windows Python files are installed by this now.
+; All the usual Windows Python Start menu entries are created and
+; work fine.
+; .py, .pyw, .pyc and .pyo extensions are registered.
+;     PROBLEM:  Inno uninstall does not restore their previous registry
+;               associations (if any).  Wise did.  This will make life
+;               difficult for alpha (etc) testers.
+; The Python install is fully functional for "typical" uses.
+;
+; What's Not Done
+; ---------------
+; None of "Mark Hammond's" registry entries are written.
+; No installation of files is done into the system dir:
+;     The MS DLLs aren't handled at all by this yet.
+;     Python22.dll is unpacked into the main Python dir.
+;
+; Inno can't do different things on NT/2000 depending on whether the user
+; has Admin privileges, so I don't know how to "solve" either of those,
+; short of building two installers (one *requiring* Admin privs, the
+; other not doing anything that needs Admin privs).
+;
+; Inno has no concept of variables, so lots of lines in this file need
+; to be fiddled by hand across releases.  Simplest way out:  stick this
+; file in a giant triple-quoted r-string (note that backslashes are
+; required all over the place here -- forward slashes DON'T WORK in
+; Inno), and use %(yadda)s string interpolation to do substitutions; i.e.,
+; write a very simple Python program to *produce* this script.
+
+[Setup]
+AppName=Python and combined Win32 Extensions
+AppVerName=Python 2.2.2 and combined Win32 Extensions 150
+AppId=Python 2.2.2.150
+AppVersion=2.2.2.150
+AppCopyright=Python is Copyright © 2001 Python Software Foundation. Win32 Extensions are Copyright © 1996-2001 Greg Stein and Mark Hammond.
+
+; Default install dir; value of {app} later (unless user overrides).
+; {sd} = system root drive, probably "C:".
+DefaultDirName={sd}\Python22
+;DefaultDirName={pf}\Python
+
+; Start menu folder name; value of {group} later (unless user overrides).
+DefaultGroupName=Python 2.2
+
+; Point SourceDir to one above PCBuild = src.
+; means this script can run unchanged from anyone's CVS tree, no matter
+; what they called the top-level directories.
+SourceDir=.
+OutputDir=..
+OutputBaseFilename=Python-2.2.2-Win32-150-Setup
+
+AppPublisher=PythonLabs at Digital Creations
+AppPublisherURL=http://www.python.org
+AppSupportURL=http://www.python.org
+AppUpdatesURL=http://www.python.org
+
+AlwaysCreateUninstallIcon=true
+ChangesAssociations=true
+UninstallLogMode=new
+AllowNoIcons=true
+AdminPrivilegesRequired=true
+UninstallDisplayIcon={app}\pyc.ico
+WizardDebug=false
+
+; The fewer screens the better; leave these commented.
+
+Compression=bzip
+InfoBeforeFile=LICENSE.txt
+;InfoBeforeFile=Misc\NEWS
+
+; uncomment the following line if you want your installation to run on NT 3.51 too.
+; MinVersion=4,3.51
+
+[Types]
+Name: normal; Description: Select desired components; Flags: iscustom
+
+[Components]
+Name: main; Description: Python and Win32 Extensions; Types: normal
+Name: docs; Description: Python documentation (HTML); Types: normal
+Name: tk; Description: TCL/TK, tkinter, and Idle; Types: normal
+Name: tools; Description: Python utility scripts (Tools\); Types: normal
+Name: test; Description: Python test suite (Lib\test\); Types: normal
+
+[Tasks]
+Name: extensions; Description: Register file associations (.py, .pyw, .pyc, .pyo); Components: main; Check: IsAdminLoggedOn
+
+[Files]
+; Caution:  Using forward slashes instead screws up in amazing ways.
+; Unknown:  By the time Components (and other attrs) are added to these lines, they're
+; going to get awfully long.  But don't see a way to continue logical lines across
+; physical lines.
+
+Source: LICENSE.txt; DestDir: {app}; CopyMode: alwaysoverwrite
+Source: README.txt; DestDir: {app}; CopyMode: alwaysoverwrite
+Source: News.txt; DestDir: {app}; CopyMode: alwaysoverwrite
+Source: *.ico; DestDir: {app}; CopyMode: alwaysoverwrite; Components: main
+
+Source: python.exe; DestDir: {app}; CopyMode: alwaysoverwrite; Components: main
+Source: pythonw.exe; DestDir: {app}; CopyMode: alwaysoverwrite; Components: main
+Source: w9xpopen.exe; DestDir: {app}; CopyMode: alwaysoverwrite; Components: main
+
+
+Source: DLLs\tcl83.dll; DestDir: {app}\DLLs; CopyMode: alwaysoverwrite; Components: tk
+Source: DLLs\tk83.dll; DestDir: {app}\DLLs; CopyMode: alwaysoverwrite; Components: tk
+Source: tcl\*.*; DestDir: {app}\tcl; CopyMode: alwaysoverwrite; Components: tk; Flags: recursesubdirs
+
+Source: sysdir\python22.dll; DestDir: {sys}; CopyMode: alwaysskipifsameorolder; Components: main; Flags: sharedfile restartreplace
+Source: sysdir\PyWinTypes22.dll; DestDir: {sys}; CopyMode: alwaysskipifsameorolder; Components: main; Flags: restartreplace sharedfile
+Source: sysdir\pythoncom22.dll; DestDir: {sys}; CopyMode: alwaysskipifsameorolder; Components: main; Flags: restartreplace sharedfile
+
+Source: DLLs\_socket.pyd; DestDir: {app}\DLLs; CopyMode: alwaysoverwrite; Components: main
+Source: libs\_socket.lib; DestDir: {app}\libs; CopyMode: alwaysoverwrite; Components: main
+
+Source: DLLs\_sre.pyd; DestDir: {app}\DLLs; CopyMode: alwaysoverwrite; Components: main
+Source: libs\_sre.lib; DestDir: {app}\libs; CopyMode: alwaysoverwrite; Components: main
+
+Source: DLLs\_symtable.pyd; DestDir: {app}\DLLs; CopyMode: alwaysoverwrite; Components: main
+Source: libs\_symtable.lib; DestDir: {app}\libs; CopyMode: alwaysoverwrite; Components: main
+
+Source: DLLs\_testcapi.pyd; DestDir: {app}\DLLs; CopyMode: alwaysoverwrite; Components: main
+Source: libs\_testcapi.lib; DestDir: {app}\libs; CopyMode: alwaysoverwrite; Components: main
+
+Source: DLLs\_tkinter.pyd; DestDir: {app}\DLLs; CopyMode: alwaysoverwrite; Components: tk
+Source: libs\_tkinter.lib; DestDir: {app}\libs; CopyMode: alwaysoverwrite; Components: tk
+
+Source: DLLs\bsddb.pyd; DestDir: {app}\DLLs; CopyMode: alwaysoverwrite; Components: main
+Source: libs\bsddb.lib; DestDir: {app}\libs; CopyMode: alwaysoverwrite; Components: main
+
+Source: DLLs\mmap.pyd; DestDir: {app}\DLLs; CopyMode: alwaysoverwrite; Components: main
+Source: libs\mmap.lib; DestDir: {app}\libs; CopyMode: alwaysoverwrite; Components: main
+
+Source: DLLs\parser.pyd; DestDir: {app}\DLLs; CopyMode: alwaysoverwrite; Components: main
+Source: libs\parser.lib; DestDir: {app}\libs; CopyMode: alwaysoverwrite; Components: main
+
+Source: DLLs\pyexpat.pyd; DestDir: {app}\DLLs; CopyMode: alwaysoverwrite; Components: main
+Source: libs\pyexpat.lib; DestDir: {app}\libs; CopyMode: alwaysoverwrite; Components: main
+
+Source: DLLs\select.pyd; DestDir: {app}\DLLs; CopyMode: alwaysoverwrite; Components: main
+Source: libs\select.lib; DestDir: {app}\libs; CopyMode: alwaysoverwrite; Components: main
+
+Source: DLLs\unicodedata.pyd; DestDir: {app}\DLLs; CopyMode: alwaysoverwrite; Components: main
+Source: libs\unicodedata.lib; DestDir: {app}\libs; CopyMode: alwaysoverwrite; Components: main
+
+Source: DLLs\_winreg.pyd; DestDir: {app}\DLLs; CopyMode: alwaysoverwrite; Components: main
+Source: libs\_winreg.lib; DestDir: {app}\libs; CopyMode: alwaysoverwrite; Components: main
+
+Source: DLLs\winsound.pyd; DestDir: {app}\DLLs; CopyMode: alwaysoverwrite; Components: main
+Source: libs\winsound.lib; DestDir: {app}\libs; CopyMode: alwaysoverwrite; Components: main
+
+Source: DLLs\zlib.pyd; DestDir: {app}\DLLs; CopyMode: alwaysoverwrite; Components: main
+Source: libs\zlib.lib; DestDir: {app}\libs; CopyMode: alwaysoverwrite; Components: main
+
+Source: libs\python22.lib; DestDir: {app}\libs; CopyMode: alwaysoverwrite; Components: main
+
+Source: DLLs\expat.dll; DestDir: {app}\DLLs; CopyMode: alwaysoverwrite; Components: main
+
+
+
+Source: Lib\*.py; DestDir: {app}\Lib; CopyMode: alwaysoverwrite; Components: main
+Source: Lib\compiler\*.*; DestDir: {app}\Lib\compiler; CopyMode: alwaysoverwrite; Components: main; Flags: recursesubdirs
+Source: Lib\distutils\*.*; DestDir: {app}\Lib\distutils; CopyMode: alwaysoverwrite; Components: main; Flags: recursesubdirs
+Source: Lib\email\*.*; DestDir: {app}\Lib\email; CopyMode: alwaysoverwrite; Components: main; Flags: recursesubdirs
+Source: Lib\encodings\*.*; DestDir: {app}\Lib\encodings; CopyMode: alwaysoverwrite; Components: main; Flags: recursesubdirs
+Source: Lib\hotshot\*.*; DestDir: {app}\Lib\hotshot; CopyMode: alwaysoverwrite; Components: main; Flags: recursesubdirs
+Source: Lib\lib-old\*.*; DestDir: {app}\Lib\lib-old; CopyMode: alwaysoverwrite; Components: main; Flags: recursesubdirs
+Source: Lib\xml\*.*; DestDir: {app}\Lib\xml; CopyMode: alwaysoverwrite; Components: main; Flags: recursesubdirs
+Source: Lib\hotshot\*.*; DestDir: {app}\Lib\hotshot; CopyMode: alwaysoverwrite; Components: main; Flags: recursesubdirs
+Source: Lib\test\*.*; DestDir: {app}\Lib\test; CopyMode: alwaysoverwrite; Components: test; Flags: recursesubdirs
+
+Source: Lib\site-packages\README.txt; DestDir: {app}\Lib\site-packages; CopyMode: alwaysoverwrite; Components: main
+
+Source: Lib\site-packages\PyWin32.chm; DestDir: {app}\Lib\site-packages; CopyMode: alwaysoverwrite; Components: docs
+Source: Lib\site-packages\win32\*.*; DestDir: {app}\Lib\site-packages\win32; CopyMode: alwaysoverwrite; Components: main; Flags: recursesubdirs
+Source: Lib\site-packages\win32com\*.*; DestDir: {app}\Lib\site-packages\win32com; CopyMode: alwaysoverwrite; Components: main; Flags: recursesubdirs
+Source: Lib\site-packages\win32comext\*.*; DestDir: {app}\Lib\site-packages\win32comext; CopyMode: alwaysoverwrite; Components: main; Flags: recursesubdirs
+
+Source: Lib\lib-tk\*.py; DestDir: {app}\Lib\lib-tk; CopyMode: alwaysoverwrite; Components: tk; Flags: recursesubdirs
+
+Source: include\*.h; DestDir: {app}\include; CopyMode: alwaysoverwrite; Components: main
+
+Source: Tools\idle\*.*; DestDir: {app}\Tools\idle; CopyMode: alwaysoverwrite; Components: tk; Flags: recursesubdirs
+
+Source: Tools\pynche\*.*; DestDir: {app}\Tools\pynche; CopyMode: alwaysoverwrite; Components: tools; Flags: recursesubdirs
+Source: Tools\scripts\*.*; DestDir: {app}\Tools\Scripts; CopyMode: alwaysoverwrite; Components: tools; Flags: recursesubdirs
+Source: Tools\webchecker\*.*; DestDir: {app}\Tools\webchecker; CopyMode: alwaysoverwrite; Components: tools; Flags: recursesubdirs
+Source: Tools\versioncheck\*.*; DestDir: {app}\Tools\versioncheck; CopyMode: alwaysoverwrite; Components: tools; Flags: recursesubdirs
+
+Source: Doc\*.*; DestDir: {app}\Doc; CopyMode: alwaysoverwrite; Flags: recursesubdirs; Components: docs
+
+
+[Icons]
+Name: {group}\Python (command line); Filename: {app}\python.exe; WorkingDir: {app}; Components: main
+Name: {group}\Python Manuals; Filename: {app}\Doc\index.html; WorkingDir: {app}; Components: docs
+Name: {group}\Win32 Extensions Help; Filename: {app}\Lib\site-packages\PyWin32.chm; WorkingDir: {app}\Lib\site-packages; Components: docs
+Name: {group}\Module Docs; Filename: {app}\pythonw.exe; WorkingDir: {app}; Parameters: """{app}\Tools\Scripts\pydoc.pyw"""; Components: tools
+Name: {group}\IDLE (Python GUI); Filename: {app}\pythonw.exe; WorkingDir: {app}; Parameters: """{app}\Tools\idle\idle.pyw"""; Components: tools
+
+[Registry]
+; Register .py
+Tasks: extensions; Root: HKCR; Subkey: .py; ValueType: string; ValueName: ; ValueData: Python File; Flags: uninsdeletevalue
+Tasks: extensions; Root: HKCR; Subkey: .py; ValueType: string; ValueName: Content Type; ValueData: text/plain; Flags: uninsdeletevalue
+Tasks: extensions; Root: HKCR; Subkey: Python File; ValueType: string; ValueName: ; ValueData: Python File; Flags: uninsdeletekey
+Tasks: extensions; Root: HKCR; Subkey: Python File\DefaultIcon; ValueType: string; ValueName: ; ValueData: {app}\Py.ico
+Tasks: extensions; Root: HKCR; Subkey: Python File\shell\open\command; ValueType: string; ValueName: ; ValueData: """{app}\python.exe"" ""%1"" %*"
+
+; Register .pyc
+Tasks: extensions; Root: HKCR; Subkey: .pyc; ValueType: string; ValueName: ; ValueData: Python CompiledFile; Flags: uninsdeletevalue
+Tasks: extensions; Root: HKCR; Subkey: Python CompiledFile; ValueType: string; ValueName: ; ValueData: Compiled Python File; Flags: uninsdeletekey
+Tasks: extensions; Root: HKCR; Subkey: Python CompiledFile\DefaultIcon; ValueType: string; ValueName: ; ValueData: {app}\pyc.ico
+Tasks: extensions; Root: HKCR; Subkey: Python CompiledFile\shell\open\command; ValueType: string; ValueName: ; ValueData: """{app}\python.exe"" ""%1"" %*"
+
+; Register .pyo
+Tasks: extensions; Root: HKCR; Subkey: .pyo; ValueType: string; ValueName: ; ValueData: Python CompiledFile; Flags: uninsdeletevalue
+
+; Register .pyw
+Tasks: extensions; Root: HKCR; Subkey: .pyw; ValueType: string; ValueName: ; ValueData: Python NoConFile; Flags: uninsdeletevalue
+Tasks: extensions; Root: HKCR; Subkey: .pyw; ValueType: string; ValueName: Content Type; ValueData: text/plain; Flags: uninsdeletevalue
+Tasks: extensions; Root: HKCR; Subkey: Python NoConFile; ValueType: string; ValueName: ; ValueData: Python File (no console); Flags: uninsdeletekey
+Tasks: extensions; Root: HKCR; Subkey: Python NoConFile\DefaultIcon; ValueType: string; ValueName: ; ValueData: {app}\Py.ico
+Tasks: extensions; Root: HKCR; Subkey: Python NoConFile\shell\open\command; ValueType: string; ValueName: ; ValueData: """{app}\pythonw.exe"" ""%1"" %*"
+
+
+; Python Registry Keys
+Root: HKLM; Subkey: SOFTWARE\Python; Flags: uninsdeletekeyifempty; Check: IsAdminLoggedOn
+Root: HKLM; Subkey: SOFTWARE\Python\PythonCore; Flags: uninsdeletekeyifempty
+Root: HKLM; Subkey: SOFTWARE\Python\PythonCore\2.2; Flags: uninsdeletekeyifempty
+Root: HKLM; Subkey: SOFTWARE\Python\PythonCore\2.2\PythonPath; ValueData: "{app}\Lib;{app}\DLLs"; Flags: uninsdeletekeyifempty
+Root: HKLM; Subkey: SOFTWARE\Python\PythonCore\2.2\PythonPath\tk; ValueData: {app}\Lib\lib-tk; Flags: uninsdeletekey; Components: tk
+Root: HKLM; Subkey: SOFTWARE\Python\PythonCore\2.2\PythonPath\win32; ValueData: "{app}\lib\site-packages\win32;{app}\lib\site-packages\win32\lib"; Flags: uninsdeletekey
+Root: HKLM; Subkey: SOFTWARE\Python\PythonCore\2.2\PythonPath\win32com; ValueData: C:\Python\lib\site-packages; Flags: uninsdeletekey
+Root: HKLM; Subkey: SOFTWARE\Python\PythonCore\2.2\Modules; Flags: uninsdeletekeyifempty
+Root: HKLM; Subkey: SOFTWARE\Python\PythonCore\2.2\Modules\pythoncom; ValueData: {sys}\pythoncom22.dll; Flags: uninsdeletekey
+Root: HKLM; Subkey: SOFTWARE\Python\PythonCore\2.2\Modules\pywintypes; ValueData: {sys}\PyWinTypes22.dll; Flags: uninsdeletekey
+Root: HKLM; Subkey: SOFTWARE\Python\PythonCore\2.2\InstallPath; ValueData: {app}; Flags: uninsdeletekeyifempty; ValueType: string
+Root: HKLM; Subkey: SOFTWARE\Python\PythonCore\2.2\InstallPath\InstallGroup; ValueData: {group}; Flags: uninsdeletekey
+Root: HKLM; Subkey: SOFTWARE\Python\PythonCore\2.2\Help; Flags: uninsdeletekeyifempty
+Root: HKLM; Subkey: SOFTWARE\Python\PythonCore\2.2\Help\Main Python Documentation; ValueType: string; ValueData: {app}\Doc\index.html; Flags: uninsdeletekey; Components: docs
+Root: HKLM; Subkey: SOFTWARE\Python\PythonCore\2.2\Help\Python Win32 Documentation; ValueType: string; ValueData: {app}\lib\site-packages\PyWin32.chm; Flags: uninsdeletekey; Components: docs
+
+[_ISTool]
+EnableISX=true
+
+
+[Code]
+Program Setup;
+
+Function IsAdminNotLoggedOn(): Boolean;
+begin
+  Result := Not IsAdminLoggedOn();
+end;
+
+begin
+end.
+
+
+
+
+[UninstallDelete]
+Name: {app}\Lib\compiler\*.pyc; Type: files
+Name: {app}\Lib\compiler\*.pyo; Type: files
+Name: {app}\Lib\compiler; Type: dirifempty
+Name: {app}\Lib\distutils\command\*.pyc; Type: files
+Name: {app}\Lib\distutils\command\*.pyo; Type: files
+Name: {app}\Lib\distutils\command; Type: dirifempty
+Name: {app}\Lib\distutils\*.pyc; Type: files
+Name: {app}\Lib\distutils\*.pyo; Type: files
+Name: {app}\Lib\distutils; Type: dirifempty
+Name: {app}\Lib\email\test\*.pyc; Type: files
+Name: {app}\Lib\email\test\*.pyo; Type: files
+Name: {app}\Lib\email\test; Type: dirifempty
+Name: {app}\Lib\email\*.pyc; Type: files
+Name: {app}\Lib\email\*.pyo; Type: files
+Name: {app}\Lib\email; Type: dirifempty
+Name: {app}\Lib\encodings\*.pyc; Type: files
+Name: {app}\Lib\encodings\*.pyo; Type: files
+Name: {app}\Lib\encodings; Type: dirifempty
+Name: {app}\Lib\hotshot\*.pyc; Type: files
+Name: {app}\Lib\hotshot\*.pyo; Type: files
+Name: {app}\Lib\hotshot; Type: dirifempty
+Name: {app}\Lib\lib-old\*.pyc; Type: files
+Name: {app}\Lib\lib-old\*.pyo; Type: files
+Name: {app}\Lib\lib-old; Type: dirifempty
+Name: {app}\Lib\lib-tk\*.pyc; Type: files
+Name: {app}\Lib\lib-tk\*.pyo; Type: files
+Name: {app}\Lib\lib-tk; Type: dirifempty
+Name: {app}\Lib\test\*.pyc; Type: files
+Name: {app}\Lib\test\*.pyo; Type: files
+Name: {app}\Lib\test; Type: dirifempty
+Name: {app}\Lib\xml\dom\*.pyc; Type: files
+Name: {app}\Lib\xml\dom\*.pyo; Type: files
+Name: {app}\Lib\xml\dom; Type: dirifempty
+Name: {app}\Lib\xml\parsers\*.pyc; Type: files
+Name: {app}\Lib\xml\parsers\*.pyo; Type: files
+Name: {app}\Lib\xml\parsers; Type: dirifempty
+Name: {app}\Lib\xml\sax\*.pyc; Type: files
+Name: {app}\Lib\xml\sax\*.pyo; Type: files
+Name: {app}\Lib\xml\sax; Type: dirifempty
+Name: {app}\Lib\xml\*.pyc; Type: files
+Name: {app}\Lib\xml\*.pyo; Type: files
+Name: {app}\Lib\xml; Type: dirifempty
+
+Name: {app}\Lib\site-packages\win32; Type: filesandordirs
+Name: {app}\Lib\site-packages\win32com; Type: filesandordirs
+Name: {app}\Lib\site-packages\win32comext; Type: filesandordirs
+Name: {app}\Lib\site-packages\pythoncom.py*; Type: files
+Name: {app}\Lib\site-packages; Type: dirifempty
+
+Name: {app}\Lib\*.pyc; Type: files
+Name: {app}\Lib; Type: dirifempty
+
+Name: {app}\Tools\pynche\*.pyc; Type: files
+Name: {app}\Tools\pynche\*.pyo; Type: files
+Name: {app}\Tools\pynche; Type: dirifempty
+
+Name: {app}\Tools\idle\*.pyc; Type: files
+Name: {app}\Tools\idle\*.pyo; Type: files
+Name: {app}\Tools\idle; Type: dirifempty
+
+Name: {app}\Tools\scripts\*.pyc; Type: files
+Name: {app}\Tools\scripts\*.pyo; Type: files
+Name: {app}\Tools\scripts; Type: dirifempty
+
+Name: {app}\Tools\versioncheck\*.pyc; Type: files
+Name: {app}\Tools\versioncheck\*.pyo; Type: files
+Name: {app}\Tools\versioncheck; Type: dirifempty
+
+Name: {app}\Tools\webchecker\*.pyc; Type: files
+Name: {app}\Tools\webchecker\*.pyo; Type: files
+Name: {app}\Tools\webchecker; Type: dirifempty
+
+Name: {app}\Tools; Type: dirifempty
+

Added: vendor/Python/current/PCbuild8/python.vcproj
===================================================================
--- vendor/Python/current/PCbuild8/python.vcproj	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild8/python.vcproj	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,399 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8,00"
+	Name="python"
+	ProjectGUID="{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}"
+	RootNamespace="python"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(PlatformName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\python"
+			ConfigurationType="1"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="odbccp32.lib"
+				OutputFile="$(OutDir)\python.exe"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				AdditionalLibraryDirectories="$(OutDir)"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				SubSystem="1"
+				StackReserveSize="2000000"
+				BaseAddress="0x1d000000"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			OutputDirectory="$(PlatformName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\python"
+			ConfigurationType="1"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="odbccp32.lib"
+				OutputFile="$(OutDir)\python.exe"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				AdditionalLibraryDirectories="$(OutDir)"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				SubSystem="1"
+				StackReserveSize="2000000"
+				BaseAddress="0x1d000000"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(PlatformName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\python"
+			ConfigurationType="1"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				BrowseInformation="1"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="_DEBUG"
+				Culture="1033"
+				AdditionalIncludeDirectories="..\Include"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="odbccp32.lib"
+				OutputFile="$(OutDir)\python_d.exe"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				AdditionalLibraryDirectories="$(OutDir)"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				SubSystem="1"
+				StackReserveSize="2000000"
+				BaseAddress="0x1d000000"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			OutputDirectory="$(PlatformName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\python"
+			ConfigurationType="1"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				BrowseInformation="1"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="_DEBUG"
+				Culture="1033"
+				AdditionalIncludeDirectories="..\Include"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="odbccp32.lib python25_d.lib"
+				OutputFile="$(OutDir)\python_d.exe"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				AdditionalLibraryDirectories="$(OutDir)"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				SubSystem="1"
+				StackReserveSize="2000000"
+				BaseAddress="0x1d000000"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath="..\PC\pycon.ico"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\python.c"
+			>
+		</File>
+		<File
+			RelativePath="..\PC\python_exe.rc"
+			>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Added: vendor/Python/current/PCbuild8/python20.wse
===================================================================
--- vendor/Python/current/PCbuild8/python20.wse	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild8/python20.wse	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,3135 @@
+Document Type: WSE
+item: Global
+  Version=9.0
+  Title=Python 2.4a1
+  Flags=00010100
+  Languages=65 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+  Japanese Font Name=MS Gothic
+  Japanese Font Size=10
+  Start Gradient=0 255 0
+  End Gradient=0 128 0
+  Windows Flags=00000100000011010010010100001010
+  Log Pathname=%MAINDIR%\INSTALL.LOG
+  Message Font=MS Sans Serif
+  Font Size=8
+  Pages Modified=00010000011101000000000100000111
+  Extra Pages=00000000000000000000000010110010
+  Disk Filename=SETUP
+  Patch Flags=0000000000001001
+  Patch Threshold=85
+  Patch Memory=4000
+  MIF PDF Version=1.0
+  MIF SMS Version=2.0
+  EXE Filename=Python-2.4a1.exe
+  Dialogs Version=8
+  Version File=2.4a1
+  Version Description=Python Programming Language
+  Version Copyright=©2001-2007 Python Software Foundation
+  Version Company=Python Software Foundation
+  Crystal Format=10111100101100000010001001001001
+  Step View=&All
+  Variable Name1=_WISE_
+  Variable Description1=WISE root directory
+  Variable Default1=C:\Programme\Wise Installation System
+  Variable Flags1=00001000
+  Variable Name2=_TCLDIR_
+  Variable Description2=The directory in which the Tcl/Tk installation
+  Variable Description2=lives.  This must be a sibling of the Python
+  Variable Description2=directory.
+  Variable Default2=tcl84
+  Variable Flags2=00001000
+  Variable Name3=_DOC_
+  Variable Description3=The unpacked HTML doc directory.
+  Variable Default3=..\html
+  Variable Flags3=00001001
+  Variable Name4=_SYS_
+  Variable Description4=System directory (where to find MSVCRT.DLL)
+  Variable Default4=C:\Windows\System
+  Variable Values4=C:\Windows\System
+  Variable Values4=C:\WINNT\System32
+  Variable Values4=C:\Code\MSDLLs
+  Variable Values4=C:\Windows\System32
+  Variable Flags4=00000010
+  Variable Name5=_PYMAJOR_
+  Variable Description5=Python major version number; the 2 in 2.3.
+  Variable Default5=2
+  Variable Flags5=00001000
+  Variable Name6=_PYMINOR_
+  Variable Description6=Python minor version number; the 3 in 2.3
+  Variable Default6=3
+  Variable Flags6=00001000
+  Variable Name7=_DOADMIN_
+  Variable Description7=The initial value for %DOADMIN%.
+  Variable Description7=When 0, we never try to write under HKLM,
+  Variable Description7=and install the Python + MS runtime DLLs in
+  Variable Description7=the Python directory instead of the system dir.
+  Variable Default7=1
+  Variable Values7=1
+  Variable Values7=0
+  Variable Flags7=00001010
+  Variable Name8=_ALIASNAME_
+  Variable Flags8=00001000
+  Variable Name9=_ALIASPATH_
+  Variable Flags9=00001000
+  Variable Name10=_ALIASTYPE_
+  Variable Flags10=00001000
+end
+item: Set Variable
+  Variable=PYVER_STRING
+  Value=2.3
+end
+item: Remark
+end
+item: Remark
+  Text=When the version number changes, set the compiler
+end
+item: Remark
+  Text=vrbls _PYMAJOR_ and  _PYMINOR_.
+end
+item: Remark
+  Text=Nothing in the script below should need fiddling then.
+end
+item: Remark
+  Text=Other things that need fiddling:
+end
+item: Remark
+  Text=    PYVER_STRING above.
+end
+item: Remark
+  Text=    The "Title:" in the upper left corner of the GUI.
+end
+item: Remark
+  Text=    Build Settings and Version Resource on step 6 (Finish) of the Installation Expert
+end
+item: Remark
+  Text=        Be sure to select Steps->All or you may not see these!
+end
+item: Remark
+end
+item: Remark
+  Text=When the version of Tcl/Tk changes, the compiler vrbl
+end
+item: Remark
+  Text=_TCLDIR_ may also need to be changed.
+end
+item: Remark
+end
+item: Set Variable
+  Variable=APPTITLE
+  Value=Python %PYVER_STRING%
+end
+item: Remark
+  Text=PY_VERSION should be major.minor only; used to create the registry key; must match MS_DLL_ID in python_nt.rc
+end
+item: Set Variable
+  Variable=PY_VERSION
+  Value=%_PYMAJOR_%.%_PYMINOR_%
+end
+item: Remark
+  Text=GROUP is the Start menu group name; user can override.
+end
+item: Set Variable
+  Variable=GROUP
+  Value=Python %PY_VERSION%
+  Flags=10000000
+end
+item: Remark
+  Text=MAINDIR is the app directory; user can override.
+end
+item: Set Variable
+  Variable=MAINDIR
+  Value=Python%_PYMAJOR_%%_PYMINOR_%
+end
+item: Remark
+end
+item: Set Variable
+  Variable=DOADMIN
+  Value=%_DOADMIN_%
+end
+item: Remark
+  Text=Give non-admin users a chance to abort.
+end
+item: Check Configuration
+  Flags=10011111
+end
+item: Set Variable
+  Variable=DOADMIN
+  Value=0
+end
+item: Display Message
+  Title=Doing non-admin install
+  Text=The current login does not have Administrator Privileges on this machine.  Python will install its registry information into the per-user area only for the current login, instead of into the per-machine area for every account on this machine.  Some advanced uses of Python may not work as a result (for example, running a Python script as a service).
+  Text=
+  Text=If this is not what you want, please click Cancel to abort this installation, log on as an Administrator, and start the installation again.
+  Flags=00001000
+end
+item: End Block
+end
+item: Remark
+end
+item: Remark
+  Text=BEGIN WIZARD STUFF -----------------------------------------------------------------------------------------------------------------------------
+end
+item: Remark
+  Text=Note from Tim: the "stop" on the next line is actually "pause".
+end
+item: Open/Close INSTALL.LOG
+  Flags=00000001
+end
+item: Remark
+  Text=If the destination system does not have a writable Windows\System directory, system files will be written to the Windows\ directory
+end
+item: Check if File/Dir Exists
+  Pathname=%SYS%
+  Flags=10000100
+end
+item: Set Variable
+  Variable=SYS
+  Value=%WIN%
+end
+item: End Block
+end
+item: Check Configuration
+  Flags=10111011
+end
+item: Get Registry Key Value
+  Variable=COMMON
+  Key=SOFTWARE\Microsoft\Windows\CurrentVersion
+  Default=C:\Program Files\Common Files
+  Value Name=CommonFilesDir
+  Flags=00000100
+end
+item: Get Registry Key Value
+  Variable=PROGRAM_FILES
+  Key=SOFTWARE\Microsoft\Windows\CurrentVersion
+  Default=C:\Program Files
+  Value Name=ProgramFilesDir
+  Flags=00000100
+end
+item: Set Variable
+  Variable=EXPLORER
+  Value=1
+end
+item: End Block
+end
+item: Remark
+  Text=Note from Tim:  The Wizard hardcod "C:" at the start of the replacement text for MAINDIR.
+end
+item: Remark
+  Text=That's not appropriate if the system drive doesn't happen to be C:.
+end
+item: Remark
+  Text=I removed the "C:", and that did the right thing for two people who tested it on non-C: machines,
+end
+item: Remark
+  Text=but it's unclear whether it will always do the right thing.
+end
+item: Set Variable
+  Variable=MAINDIR
+  Value=\%MAINDIR%
+  Flags=00001100
+end
+item: Remark
+  Text=BACKUP is the variable that holds the path that all backup files will be copied to when overwritten
+end
+item: Set Variable
+  Variable=BACKUP
+  Value=%MAINDIR%\BACKUP
+  Flags=10000000
+end
+item: Remark
+  Text=DOBACKUP determines if a backup will be performed.  The possible values are A (do backup) or B (do not do backup)
+end
+item: Set Variable
+  Variable=DOBACKUP
+  Value=A
+end
+item: Remark
+  Text=BRANDING determines if the installation will be branded with a name and company.  By default, this is written to the INST directory (installation media).
+end
+item: Set Variable
+  Variable=BRANDING
+  Value=0
+end
+item: If/While Statement
+  Variable=BRANDING
+  Value=1
+end
+item: Read INI Value
+  Variable=NAME
+  Pathname=%INST%\CUSTDATA.INI
+  Section=Registration
+  Item=Name
+end
+item: Read INI Value
+  Variable=COMPANY
+  Pathname=%INST%\CUSTDATA.INI
+  Section=Registration
+  Item=Company
+end
+item: If/While Statement
+  Variable=NAME
+end
+item: Set Variable
+  Variable=DOBRAND
+  Value=1
+end
+item: Get System Information
+  Variable=NAME
+  Flags=00000110
+end
+item: Get System Information
+  Variable=COMPANY
+  Flags=00000111
+end
+item: End Block
+end
+item: End Block
+end
+item: Remark
+  Text=END WIZARD STUFF -----------------------------------------------------------------------------------------------------------------------------
+end
+item: Remark
+end
+item: Remark
+  Text=Set vrbls for the "Advanced Options" subdialog of Components.
+end
+item: Set Variable
+  Variable=SELECT_ADMIN
+  Value=A
+end
+item: If/While Statement
+  Variable=DOADMIN
+  Value=0
+end
+item: Set Variable
+  Variable=SELECT_ADMIN
+  Value=B
+end
+item: End Block
+end
+item: Remark
+end
+item: Remark
+  Text=TASKS values:
+end
+item: Remark
+  Text=A: Register file extensions
+end
+item: Remark
+  Text=B: Create Start Menu shortcuts
+end
+item: Set Variable
+  Variable=TASKS
+  Value=AB
+end
+item: Remark
+end
+item: Remark
+  Text=COMPONENTS values:
+end
+item: Remark
+  Text=A: interpreter and libraries
+end
+item: Remark
+  Text=B: Tcl/Tk
+end
+item: Remark
+  Text=C: docs
+end
+item: Remark
+  Text=D: tools
+end
+item: Remark
+  Text=E: test suite
+end
+item: Set Variable
+  Variable=COMPONENTS
+  Value=ABCDE
+end
+item: Remark
+end
+item: Remark
+  Text=March thru the user GUI.
+end
+item: Wizard Block
+  Direction Variable=DIRECTION
+  Display Variable=DISPLAY
+  Bitmap Pathname=.\installer.bmp
+  X Position=9
+  Y Position=10
+  Filler Color=11173759
+  Dialog=Select Destination Directory
+  Dialog=Backup Replaced Files
+  Dialog=Select Components
+  Dialog=Select Program Manager Group
+  Variable=
+  Variable=
+  Variable=
+  Variable=TASKS
+  Value=
+  Value=
+  Value=
+  Value=B
+  Compare=0
+  Compare=0
+  Compare=0
+  Compare=3
+  Flags=00000011
+end
+item: If/While Statement
+  Variable=DISPLAY
+  Value=Start Installation
+end
+item: Set Variable
+  Variable=SUMMARY
+  Value=Install directory:  %MAINDIR%%CRLF%
+end
+item: Remark
+end
+item: If/While Statement
+  Variable=SELECT_ADMIN
+  Value=A
+end
+item: Set Variable
+  Variable=SUMMARY
+  Value=%CRLF%Doing admin install.%CRLF%
+  Flags=00000001
+end
+item: Else Statement
+end
+item: Set Variable
+  Variable=SUMMARY
+  Value=%CRLF%Doing non-admin install.%CRLF%
+  Flags=00000001
+end
+item: End Block
+end
+item: Remark
+end
+item: If/While Statement
+  Variable=DOBACKUP
+  Value=A
+end
+item: Set Variable
+  Variable=SUMMARY
+  Value=%CRLF%Make backups, into %BACKUP%%CRLF%
+  Flags=00000001
+end
+item: Else Statement
+end
+item: Set Variable
+  Variable=SUMMARY
+  Value=%CRLF%Don't make backups.%CRLF%
+  Flags=00000001
+end
+item: End Block
+end
+item: Remark
+end
+item: Set Variable
+  Variable=SUMMARY
+  Value=%CRLF%Components:%CRLF%
+  Flags=00000001
+end
+item: If/While Statement
+  Variable=COMPONENTS
+  Value=A
+  Flags=00000010
+end
+item: Set Variable
+  Variable=SUMMARY
+  Value=    Python interpreter and libraries%CRLF%
+  Flags=00000001
+end
+item: End Block
+end
+item: If/While Statement
+  Variable=COMPONENTS
+  Value=B
+  Flags=00000010
+end
+item: Set Variable
+  Variable=SUMMARY
+  Value=    Tcl/Tk (Tkinter, IDLE, pydoc)%CRLF%
+  Flags=00000001
+end
+item: End Block
+end
+item: If/While Statement
+  Variable=COMPONENTS
+  Value=C
+  Flags=00000010
+end
+item: Set Variable
+  Variable=SUMMARY
+  Value=    Python documentation%CRLF%
+  Flags=00000001
+end
+item: End Block
+end
+item: If/While Statement
+  Variable=COMPONENTS
+  Value=D
+  Flags=00000010
+end
+item: Set Variable
+  Variable=SUMMARY
+  Value=    Tool and utility scripts%CRLF%
+  Flags=00000001
+end
+item: End Block
+end
+item: If/While Statement
+  Variable=COMPONENTS
+  Value=E
+  Flags=00000010
+end
+item: Set Variable
+  Variable=SUMMARY
+  Value=    Python test suite%CRLF%
+  Flags=00000001
+end
+item: End Block
+end
+item: Remark
+end
+item: If/While Statement
+  Variable=TASKS
+  Value=A
+  Flags=00000010
+end
+item: Set Variable
+  Variable=SUMMARY
+  Value=%CRLF%Register file extensions.%CRLF%
+  Flags=00000001
+end
+item: Else Statement
+end
+item: Set Variable
+  Variable=SUMMARY
+  Value=%CRLF%Don't register file extensions.%CRLF%
+  Flags=00000001
+end
+item: End Block
+end
+item: Remark
+end
+item: If/While Statement
+  Variable=TASKS
+  Value=B
+  Flags=00000010
+end
+item: Set Variable
+  Variable=SUMMARY
+  Value=%CRLF%Start Menu group:  %GROUP%%CRLF%
+  Flags=00000001
+end
+item: Else Statement
+end
+item: Set Variable
+  Variable=SUMMARY
+  Value=%CRLF%No Start Menu shortcuts.%CRLF%
+  Flags=00000001
+end
+item: End Block
+end
+item: End Block
+end
+item: Remark
+end
+item: Custom Dialog Set
+  Name=Select Destination Directory
+  Display Variable=DISPLAY
+  item: Dialog
+    Title=%APPTITLE% Installation
+    Title French=Installation de %APPTITLE%
+    Title German=Installation von %APPTITLE%
+    Title Spanish=Instalación de %APPTITLE%
+    Title Italian=Installazione di %APPTITLE%
+    Width=339
+    Height=280
+    Font Name=Helv
+    Font Size=8
+    item: Push Button
+      Rectangle=188 234 244 253
+      Variable=DIRECTION
+      Value=N
+      Create Flags=01010000000000010000000000000001
+      Text=&Next >
+      Text French=&Suite >
+      Text German=&Weiter >
+      Text Spanish=&Siguiente >
+      Text Italian=&Avanti >
+    end
+    item: Push Button
+      Rectangle=264 234 320 253
+      Action=3
+      Create Flags=01010000000000010000000000000000
+      Text=&Cancel
+      Text French=&Annuler
+      Text German=&Abbrechen
+      Text Spanish=&Cancelar
+      Text Italian=&Annulla
+    end
+    item: Static
+      Rectangle=10 225 320 226
+      Action=3
+      Create Flags=01010000000000000000000000000111
+    end
+    item: Static
+      Rectangle=108 11 323 33
+      Create Flags=01010000000000000000000000000000
+      Flags=0000000000000001
+      Name=Times New Roman
+      Font Style=-24 0 0 0 700 255 0 0 0 3 2 1 18
+      Text=Select Destination Directory
+      Text French=Sélectionner le répertoire de destination
+      Text German=Zielverzeichnis wählen
+      Text Spanish=Seleccione el directorio de destino
+      Text Italian=Selezionare Directory di destinazione
+    end
+    item: Listbox
+      Rectangle=108 58 321 219
+      Variable=MAINDIR
+      Enabled Color=00000000000000001111111111111111
+      Create Flags=01010000100000010000000101000001
+      Flags=0000110000001010
+      Text=%MAINDIR%
+      Text=
+    end
+    item: Static
+      Rectangle=108 40 313 58
+      Enabled Color=00000000000000001111111111111111
+      Create Flags=01010000000000000000000000000000
+      Text=Please select a directory for the %APPTITLE% files.
+    end
+  end
+  item: Dialog
+    Title=Select Destination Directory
+    Title French=Sélectionner le répertoire de destination
+    Title German=Zielverzeichnis wählen
+    Title Spanish=Seleccione el directorio de destino
+    Title Italian=Selezionare Directory di destinazione
+    Width=276
+    Height=216
+    Font Name=Helv
+    Font Size=8
+    item: Listbox
+      Rectangle=6 6 204 186
+      Variable=MAINDIR
+      Create Flags=01010000100000010000000101000000
+      Flags=0000110000100010
+      Text=%MAINDIR%
+      Text French=%MAINDIR%
+      Text German=%MAINDIR%
+      Text Spanish=%MAINDIR%
+      Text Italian=%MAINDIR%
+    end
+    item: Push Button
+      Rectangle=209 8 265 26
+      Create Flags=01010000000000010000000000000001
+      Text=OK
+      Text French=OK
+      Text German=OK
+      Text Spanish=Aceptar
+      Text Italian=OK
+    end
+    item: Push Button
+      Rectangle=209 31 265 50
+      Variable=MAINDIR
+      Value=%MAINDIR_SAVE%
+      Create Flags=01010000000000010000000000000000
+      Flags=0000000000000001
+      Text=Cancel
+      Text French=Annuler
+      Text German=Abbrechen
+      Text Spanish=Cancelar
+      Text Italian=Annulla
+    end
+  end
+end
+item: Custom Dialog Set
+  Name=Backup Replaced Files
+  Display Variable=DISPLAY
+  item: Dialog
+    Title=%APPTITLE% Installation
+    Title French=Fichiers de Sauvegarde Remplacés
+    Title German=Sicherungskopie von ersetzten Dateien erstellen
+    Title Portuguese=Ficheiros substituídos de segurança
+    Title Spanish=Copias de seguridad de los archivos reemplazados
+    Title Italian=Backup file sostituiti
+    Title Danish=Sikkerhedskopiering af erstattede filer
+    Title Dutch=Vervangen bestanden kopiëren
+    Title Norwegian=Sikkerhetskopiere erstattede filer
+    Title Swedish=Säkerhetskopiera utbytta filer
+    Width=350
+    Height=280
+    Font Name=Helv
+    Font Size=8
+    item: Push Button
+      Rectangle=188 234 244 251
+      Variable=DIRECTION
+      Value=N
+      Create Flags=01010000000000010000000000000001
+      Text=&Next >
+      Text French=&Suivant>
+      Text German=&Weiter>
+      Text Portuguese=&Próximo>
+      Text Spanish=&Siguiente >
+      Text Italian=&Avanti >
+      Text Danish=&Næste>
+      Text Dutch=&Volgende>
+      Text Norwegian=&Neste>
+      Text Swedish=&Nästa >
+    end
+    item: Push Button
+      Rectangle=131 234 188 251
+      Variable=DIRECTION
+      Value=B
+      Create Flags=01010000000000010000000000000000
+      Text=< &Back
+      Text French=<&Retour
+      Text German=<&Zurück
+      Text Portuguese=<&Retornar
+      Text Spanish=<&Retroceder
+      Text Italian=< &Indietro
+      Text Danish=<&Tilbage
+      Text Dutch=<&Terug
+      Text Norwegian=<&Tilbake
+      Text Swedish=< &Tillbaka
+    end
+    item: Push Button
+      Rectangle=278 234 330 251
+      Action=3
+      Create Flags=01010000000000010000000000000000
+      Text=Cancel
+      Text French=Annuler
+      Text German=Abbrechen
+      Text Portuguese=Cancelar
+      Text Spanish=Cancelar
+      Text Italian=Annulla
+      Text Danish=Annuller
+      Text Dutch=Annuleren
+      Text Norwegian=Avbryt
+      Text Swedish=Avbryt
+    end
+    item: Static
+      Rectangle=11 221 329 223
+      Action=3
+      Create Flags=01010000000000000000000000000111
+    end
+    item: Static
+      Rectangle=108 46 320 98
+      Create Flags=01010000000000000000000000000000
+      Text=This installation program can create backup copies of all files replaced during the installation. These files will be used when the software is uninstalled and a rollback is requested.  If backup copies are not created, you will only be able to uninstall the software and not roll the system back to a previous state.
+      Text=
+      Text=Do you want to create backups of replaced files?
+      Text French=Le programme d'installation peut créer des copies de sauvegarde de tous les fichiers remplacés pendant l'installation. Ces fichiers sont utilisés au cas où le logiciel est désinstallé et que l'on procède à la reprise du système. Si les copies de sauvegarde ne sont pas créées, on ne pourra que désinstaller le logiciel sans reprendre le système à un état précédent. Voulez-vous créer une sauvegarde des fichiers remplacés ?
+      Text German=Dieses Installationsprogramm kann Sicherungskopien von allen während der Installation ersetzten Dateien erstellen. Diese Dateien werden zur Rückgängigmachung der Installation und bei Anforderung eines Rollbacks verwendet. Ohne Sicherungskopien ist nur eine Rückgängigmachung der Installation möglich, nicht aber ein Rollback des Systems. Sicherungskopien der ersetzten Dateien erstellen?
+      Text Portuguese=Este programa de instalação pode criar cópias de segurança de todos os ficheiros substituídos durante a instalação. Estes ficheiros serão utilizados quando o programa for desinstalado  e for requisitada uma retomada. Se as cópias de segurança não forem criadas, só poderá desinstalar o programa e não pode retomar  um estado anterior do sistema. Deseja criar cópias de segurança dos ficheiros substituídos?
+      Text Spanish=Este programa de instalación puede crear copias de seguridad de todos los archivos reemplazados durante la instalación. Estos archivos se utilizarán cuando se desinstale el software y se solicite volver al estado anterior. Si no se crean copias de seguridad, únicamente podrá desinstalar el software y no podrá devolver el sistema al estado anterior. ¿Desea crear archivos de seguridad de los archivos reemplazados?
+      Text Italian=Questo programma di installazione può creare copie di backup di tutti i file sostituiti durante l’installazione. Questi file saranno usati quando il software sarà disinstallato e sarà richiesto un ritorno allo stato precedente. Se non crei le copie di backup, potrai solo disinstallare il software, ma non potrai riportare il sistema allo stato precedente. Vuoi creare i file di backup dei file sostituiti?
+      Text Danish=Dette installationsprogram kan oprette sikkerhedskopier af alle filer, som erstattes under installationen. Disse filer benyttes, når softwaren fjernes, og den tidligere systemkonfiguration genetableres. Hvis der ikke oprettes sikkerhedskopier, kan du kun fjerne den installerede software og ikke genetablere den tidligere systemkonfiguration. Vil du oprette sikkerhedskopier af filer, som erstattes?
+      Text Dutch=Dit installatieprogramma kan kopieën maken van alle bestanden die tijdens de installatie worden vervangen. Deze worden dan gebruikt als de software-installatie ongedaan wordt gemaakt en u het systeem wilt laten terugkeren naar de oorspronkelijke staat. Als er geen back-up kopieën worden gemaakt, kunt u de software enkel verwijderen maar het systeem niet in de oorspronkelijke staat terugbrengen. Wilt u een back-up maken van de vervangen bestanden?
+      Text Norwegian=Dette installasjonsprogrammet kan lage sikkerhetskopier av alle filer som blir erstattet under installasjonen. Disse filene vil tas i bruk når programvaren er avinstallert og det er behov for tilbakestilling. Hvis det ikke er laget sikkerhetskopier, kan du kun avinstallere programvaren og ikke stille systemet tilbake til tidligere status. Ønsker du å lage sikkerhetskopier av de filene som blir erstattet nå?
+      Text Swedish=Installationsprogrammet kan skapa säkerhetskopior av alla filer som byts ut under installationen. Dessa filer kan sedan användas när programvaran avinstalleras och du begär rollback. Om du då inte har några säkerhetskopior kan du bara avinstallera programvaran, inte återskapa systemet i dess tidigare skick. Vill du göra säkerhetskopior av de ersatta filerna?
+    end
+    item: Radio Button
+      Rectangle=141 106 265 136
+      Variable=DOBACKUP
+      Create Flags=01010000000000010000000000001001
+      Text=&Yes, make backups
+      Text=N&o, do not make backups
+      Text=
+      Text French=&Oui
+      Text French=N&on
+      Text French=
+      Text German=&Ja
+      Text German=N&ein
+      Text German=
+      Text Portuguese=&Sim
+      Text Portuguese=Nã&o
+      Text Portuguese=
+      Text Spanish=&Sí
+      Text Spanish=N&o
+      Text Spanish=
+      Text Italian=&Sì
+      Text Italian=N&o
+      Text Italian=
+      Text Danish=&Ja
+      Text Danish=&Nej
+      Text Danish=
+      Text Dutch=&Ja
+      Text Dutch=N&ee
+      Text Dutch=
+      Text Norwegian=&Ja
+      Text Norwegian=&Nei
+      Text Norwegian=
+      Text Swedish=&Ja
+      Text Swedish=N&ej
+      Text Swedish=
+    end
+    item: Static
+      Control Name=BACK2
+      Rectangle=108 173 320 208
+      Action=1
+      Create Flags=01010000000000000000000000000111
+      Text=Backup File Destination Directory
+      Text French=Répertoire de destination des fichiers de sauvegarde
+      Text German=Zielverzeichnis für die Sicherungsdatei
+      Text Portuguese=Directório de destino de ficheiro de segurança
+      Text Spanish=Directorio de Destino de los Archivos de Seguridad
+      Text Italian=Directory di destinazione dei file di backup
+      Text Danish=Destinationsbibliotek til sikkerhedskopier
+      Text Dutch=Doeldirectory backup-bestand
+      Text Norwegian=Målkatalog for sikkerhetskopier
+      Text Swedish=Katalog för säkerhetskopierade filer
+    end
+    item: Push Button
+      Control Name=BACK3
+      Rectangle=265 185 318 203
+      Variable=BACKUP_SAVE
+      Value=%BACKUP%
+      Destination Dialog=1
+      Action=2
+      Create Flags=01010000000000010000000000000000
+      Text=B&rowse...
+      Text French=P&arcourir
+      Text German=B&lättern...
+      Text Portuguese=P&rocurar
+      Text Spanish=V&isualizar...
+      Text Italian=Sfoglia...
+      Text Danish=&Gennemse...
+      Text Dutch=B&laderen...
+      Text Norwegian=Bla igjennom
+      Text Swedish=&Bläddra
+    end
+    item: Static
+      Control Name=BACK4
+      Rectangle=129 188 254 200
+      Destination Dialog=2
+      Create Flags=01010000000000000000000000000000
+      Text=%BACKUP%
+      Text French=%BACKUP%
+      Text German=%BACKUP%
+      Text Portuguese=%BACKUP%
+      Text Spanish=%BACKUP%
+      Text Italian=%BACKUP%
+      Text Danish=%BACKUP%
+      Text Dutch=%BACKUP%
+      Text Norwegian=%BACKUP%
+      Text Swedish=%BACKUP%
+    end
+    item: Static
+      Rectangle=108 11 323 36
+      Create Flags=01010000000000000000000000000000
+      Flags=0000000000000001
+      Name=Times New Roman
+      Font Style=-24 0 0 0 700 255 0 0 0 3 2 1 18
+      Text=Backup Replaced Files
+      Text French=Sélectionner les composants
+      Text German=Komponenten auswählen
+      Text Spanish=Seleccione componentes
+      Text Italian=Selezionare i componenti
+    end
+    item: If/While Statement
+      Variable=DOBACKUP
+      Value=B
+    end
+    item: Set Control Attribute
+      Control Name=BACK3
+      Operation=1
+    end
+    item: Set Control Attribute
+      Control Name=BACK4
+      Operation=1
+    end
+    item: Else Statement
+    end
+    item: Set Control Attribute
+      Control Name=BACK3
+    end
+    item: Set Control Attribute
+      Control Name=BACK4
+    end
+    item: End Block
+    end
+  end
+  item: Dialog
+    Title=Select Destination Directory
+    Title French=Choisissez le répertoire de destination
+    Title German=Zielverzeichnis wählen
+    Title Portuguese=Seleccionar Directório de Destino
+    Title Spanish=Seleccione el Directorio de Destino
+    Title Italian=Seleziona Directory di destinazione
+    Title Danish=Vælg Destinationsbibliotek
+    Title Dutch=Kies Doeldirectory
+    Title Norwegian=Velg målkatalog
+    Title Swedish=Välj destinationskalatog
+    Width=276
+    Height=216
+    Font Name=Helv
+    Font Size=8
+    item: Listbox
+      Rectangle=6 3 200 186
+      Variable=BACKUP
+      Create Flags=01010000100000010000000101000000
+      Flags=0000110000100010
+      Text=%BACKUP%
+      Text=
+      Text French=%BACKUP%
+      Text French=
+      Text German=%BACKUP%
+      Text German=
+      Text Portuguese=%BACKUP%
+      Text Portuguese=
+      Text Spanish=%BACKUP%
+      Text Spanish=
+      Text Italian=%BACKUP%
+      Text Italian=
+      Text Danish=%BACKUP%
+      Text Danish=
+      Text Dutch=%BACKUP%
+      Text Dutch=
+      Text Norwegian=%BACKUP%
+      Text Norwegian=
+      Text Swedish=%BACKUP%
+      Text Swedish=
+    end
+    item: Push Button
+      Rectangle=209 8 265 26
+      Create Flags=01010000000000010000000000000001
+      Text=OK
+      Text French=OK
+      Text German=OK
+      Text Portuguese=OK
+      Text Spanish=ACEPTAR
+      Text Italian=OK
+      Text Danish=OK
+      Text Dutch=OK
+      Text Norwegian=OK
+      Text Swedish=OK
+    end
+    item: Push Button
+      Rectangle=209 31 265 50
+      Variable=BACKUP
+      Value=%BACKUP_SAVE%
+      Create Flags=01010000000000010000000000000000
+      Flags=0000000000000001
+      Text=Cancel
+      Text French=Annuler
+      Text German=Abbrechen
+      Text Portuguese=Cancelar
+      Text Spanish=Cancelar
+      Text Italian=Annulla
+      Text Danish=Slet
+      Text Dutch=Annuleren
+      Text Norwegian=Avbryt
+      Text Swedish=Avbryt
+    end
+  end
+end
+item: Custom Dialog Set
+  Name=Select Components
+  Display Variable=DISPLAY
+  item: Dialog
+    Title=%APPTITLE% Installation
+    Title French=Installation de %APPTITLE%
+    Title German=Installation von %APPTITLE%
+    Title Spanish=Instalación de %APPTITLE%
+    Title Italian=Installazione di %APPTITLE%
+    Width=339
+    Height=280
+    Font Name=Helv
+    Font Size=8
+    item: Push Button
+      Rectangle=188 234 244 253
+      Variable=DIRECTION
+      Value=N
+      Create Flags=01010000000000010000000000000001
+      Text=&Next >
+      Text French=&Suite >
+      Text German=&Weiter >
+      Text Spanish=&Siguiente >
+      Text Italian=&Avanti >
+    end
+    item: Push Button
+      Rectangle=131 234 188 253
+      Variable=DIRECTION
+      Value=B
+      Create Flags=01010000000000010000000000000000
+      Text=< &Back
+      Text French=< &Retour
+      Text German=< &Zurück
+      Text Spanish=< &Atrás
+      Text Italian=< &Indietro
+    end
+    item: Push Button
+      Rectangle=264 234 320 253
+      Action=3
+      Create Flags=01010000000000010000000000000000
+      Text=&Cancel
+      Text French=&Annuler
+      Text German=&Abbrechen
+      Text Spanish=&Cancelar
+      Text Italian=&Annulla
+    end
+    item: Checkbox
+      Rectangle=108 66 313 156
+      Variable=COMPONENTS
+      Create Flags=01010000000000010000000000000011
+      Flags=0000000000000110
+      Text=Python interpreter and libraries
+      Text=Tcl/Tk (Tkinter, IDLE, pydoc)
+      Text=Python HTML docs
+      Text=Python utility scripts (Tools/)
+      Text=Python test suite (Lib/test/)
+      Text=
+      Text French=Python interpreter, library and IDLE
+      Text French=Python HTML docs
+      Text French=Python utility scripts (Tools/)
+      Text French=Python test suite (Lib/test/)
+      Text French=
+      Text German=Python interpreter, library and IDLE
+      Text German=Python HTML docs
+      Text German=Python utility scripts (Tools/)
+      Text German=Python test suite (Lib/test/)
+      Text German=
+      Text Spanish=Python interpreter, library and IDLE
+      Text Spanish=Python HTML docs
+      Text Spanish=Python utility scripts (Tools/)
+      Text Spanish=Python test suite (Lib/test/)
+      Text Spanish=
+      Text Italian=Python interpreter, library and IDLE
+      Text Italian=Python HTML docs
+      Text Italian=Python utility scripts (Tools/)
+      Text Italian=Python test suite (Lib/test/)
+      Text Italian=
+    end
+    item: Static
+      Rectangle=108 45 320 63
+      Create Flags=01010000000000000000000000000000
+      Text=Choose which components to install by checking the boxes below.
+      Text French=Choisissez les composants que vous voulez installer en cochant les cases ci-dessous.
+      Text German=Wählen Sie die zu installierenden Komponenten, indem Sie in die entsprechenden Kästchen klicken.
+      Text Spanish=Elija los componentes que desee instalar marcando los cuadros de abajo.
+      Text Italian=Scegliere quali componenti installare selezionando le caselle sottostanti.
+    end
+    item: Push Button
+      Rectangle=188 203 269 220
+      Destination Dialog=1
+      Action=2
+      Enabled Color=00000000000000000000000011111111
+      Create Flags=01010000000000010000000000000000
+      Text=Advanced Options ...
+    end
+    item: Static
+      Rectangle=10 225 320 226
+      Action=3
+      Create Flags=01010000000000000000000000000111
+    end
+    item: Static
+      Rectangle=108 10 323 43
+      Create Flags=01010000000000000000000000000000
+      Flags=0000000000000001
+      Name=Times New Roman
+      Font Style=-24 0 0 0 700 255 0 0 0 3 2 1 18
+      Text=Select Components
+      Text French=Sélectionner les composants
+      Text German=Komponenten auswählen
+      Text Spanish=Seleccione componentes
+      Text Italian=Selezionare i componenti
+    end
+    item: Static
+      Rectangle=251 180 311 193
+      Variable=COMPONENTS
+      Value=MAINDIR
+      Create Flags=01010000000000000000000000000010
+    end
+    item: Static
+      Rectangle=251 168 311 179
+      Variable=COMPONENTS
+      Create Flags=01010000000000000000000000000010
+    end
+    item: Static
+      Rectangle=123 168 234 181
+      Create Flags=01010000000000000000000000000000
+      Text=Disk Space Required:
+      Text French=Espace disque requis :
+      Text German=Notwendiger Speicherplatz:
+      Text Spanish=Espacio requerido en el disco:
+      Text Italian=Spazio su disco necessario:
+    end
+    item: Static
+      Rectangle=123 180 234 193
+      Create Flags=01010000000000000000000000000000
+      Text=Disk Space Remaining:
+      Text French=Espace disque disponible :
+      Text German=Verbleibender Speicherplatz:
+      Text Spanish=Espacio en disco disponible:
+      Text Italian=Spazio su disco disponibile:
+    end
+    item: Static
+      Rectangle=108 158 320 196
+      Action=1
+      Create Flags=01010000000000000000000000000111
+    end
+    item: If/While Statement
+      Variable=DLG_EVENT_TYPE
+      Value=VERIFY
+    end
+    item: Remark
+      Text=If they're installing Tcl/Tk, Tools, or the test suite, doesn't make much sense unless they're installing Python too.
+    end
+    item: If/While Statement
+      Variable=COMPONENTS
+      Value=BDE
+      Flags=00001010
+    end
+    item: If/While Statement
+      Variable=COMPONENTS
+      Value=A
+      Flags=00000011
+    end
+    item: Display Message
+      Title=Are you sure?
+      Text=Installing Tcl/Tk, Tools or the test suite doesn't make much sense unless you install the Python interpreter and libraries too.
+      Text=
+      Text=Click Yes if that's really what you want.
+      Flags=00101101
+    end
+    item: Remark
+      Text=Nothing -- just proceed to the next dialog.
+    end
+    item: Else Statement
+    end
+    item: Remark
+      Text=Return to the dialog.
+    end
+    item: Set Variable
+      Variable=DLG_EVENT_TYPE
+    end
+    item: End Block
+    end
+    item: End Block
+    end
+    item: End Block
+    end
+    item: End Block
+    end
+  end
+  item: Dialog
+    Title=Advanced Options
+    Width=339
+    Height=213
+    Font Name=Helv
+    Font Size=8
+    item: Radio Button
+      Control Name=ADMIN2
+      Rectangle=11 46 90 76
+      Variable=SELECT_ADMIN
+      Enabled Color=00000000000000001111111111111111
+      Create Flags=01010000000000010000000000001001
+      Text=Admin install
+      Text=Non-Admin installl
+      Text=
+    end
+    item: Push Button
+      Rectangle=188 170 244 189
+      Variable=DIRECTION
+      Value=N
+      Create Flags=01010000000000010000000000000001
+      Text=OK
+      Text French=&Suite >
+      Text German=&Weiter >
+      Text Spanish=&Siguiente >
+      Text Italian=&Avanti >
+    end
+    item: Static
+      Rectangle=5 3 326 83
+      Action=1
+      Enabled Color=00000000000000001111111111111111
+      Create Flags=01010000000000000000000000000111
+    end
+    item: Static
+      Control Name=ADMIN1
+      Rectangle=11 11 321 45
+      Enabled Color=00000000000000001111111111111111
+      Create Flags=01010000000000000000000000000000
+      Text=By default, the install records settings in the per-machine area of the registry (HKLM), and installs the Python and C runtime DLLs to %SYS32%.  Choose "Non-Admin install" if you would prefer settings made in the per-user registry (HKCU), and DLLs installed in %MAINDIR%.
+    end
+    item: Static
+      Rectangle=5 90 326 157
+      Action=1
+      Enabled Color=00000000000000001111111111111111
+      Create Flags=01010000000000000000000000000111
+    end
+    item: Checkbox
+      Rectangle=11 121 243 151
+      Variable=TASKS
+      Enabled Color=00000000000000001111111111111111
+      Create Flags=01010000000000010000000000000011
+      Text=Register file extensions (.py, .pyw, .pyc, .pyo)
+      Text=Create Start Menu shortcuts
+      Text=
+    end
+    item: Static
+      Rectangle=11 103 320 121
+      Enabled Color=00000000000000001111111111111111
+      Create Flags=01010000000000000000000000000000
+      Text=Choose tasks to perform by checking the boxes below.
+    end
+    item: If/While Statement
+      Variable=DLG_EVENT_TYPE
+      Value=INIT
+    end
+    item: If/While Statement
+      Variable=DOADMIN
+      Value=1
+    end
+    item: Set Control Attribute
+      Control Name=ADMIN2
+    end
+    item: Else Statement
+    end
+    item: Set Control Text
+      Control Name=ADMIN1
+      Control Text=This section is available only if logged in to an account with Administrator privileges.
+    end
+    item: Set Control Attribute
+      Control Name=ADMIN2
+      Operation=1
+    end
+    item: End Block
+    end
+    item: End Block
+    end
+  end
+end
+item: Custom Dialog Set
+  Name=Select Program Manager Group
+  Display Variable=DISPLAY
+  item: Dialog
+    Title=%APPTITLE% Installation
+    Title French=Installation de %APPTITLE%
+    Title German=Installation von %APPTITLE%
+    Title Spanish=Instalación de %APPTITLE%
+    Title Italian=Installazione di %APPTITLE%
+    Width=339
+    Height=280
+    Font Name=Helv
+    Font Size=8
+    item: Push Button
+      Rectangle=188 234 244 253
+      Variable=DIRECTION
+      Value=N
+      Create Flags=01010000000000010000000000000001
+      Text=&Next >
+      Text French=&Suite >
+      Text German=&Weiter >
+      Text Spanish=&Siguiente >
+      Text Italian=&Avanti >
+    end
+    item: Push Button
+      Rectangle=131 234 188 253
+      Variable=DIRECTION
+      Value=B
+      Create Flags=01010000000000010000000000000000
+      Flags=0000000000000001
+      Text=< &Back
+      Text French=< &Retour
+      Text German=< &Zurück
+      Text Spanish=< &Atrás
+      Text Italian=< &Indietro
+    end
+    item: Push Button
+      Rectangle=264 234 320 253
+      Action=3
+      Create Flags=01010000000000010000000000000000
+      Text=&Cancel
+      Text French=&Annuler
+      Text German=&Abbrechen
+      Text Spanish=&Cancelar
+      Text Italian=&Annulla
+    end
+    item: Static
+      Rectangle=10 225 320 226
+      Action=3
+      Create Flags=01010000000000000000000000000111
+    end
+    item: Static
+      Rectangle=108 10 323 53
+      Create Flags=01010000000000000000000000000000
+      Flags=0000000000000001
+      Name=Times New Roman
+      Font Style=-24 0 0 0 700 255 0 0 0 3 2 1 18
+      Text=Select Start Menu Group
+      Text French=Sélectionner le groupe du Gestionnaire de programme
+      Text German=Bestimmung der Programm-Managergruppe
+      Text Spanish=Seleccione grupo del Administrador de programas
+      Text Italian=Selezionare il gruppo ProgMan
+    end
+    item: Static
+      Rectangle=108 35 320 65
+      Create Flags=01010000000000000000000000000000
+      Text=Enter the name of the Start Menu program group to which to add the %APPTITLE% icons:
+      Text French=Entrez le nom du groupe du Gestionnaire de programme dans lequel vous souhaitez ajouter les icônes de %APPTITLE% :
+      Text German=Geben Sie den Namen der Programmgruppe ein, der das Symbol %APPTITLE% hinzugefügt werden soll:
+      Text Spanish=Escriba el nombre del grupo del Administrador de programas en el que desea agregar los iconos de %APPTITLE%:
+      Text Italian=Inserire il nome del gruppo Program Manager per aggiungere le icone %APPTITLE% a:
+    end
+    item: Combobox
+      Rectangle=108 56 320 219
+      Variable=GROUP
+      Create Flags=01010000001000010000001100000001
+      Flags=0000000000000001
+      Text=%GROUP%
+      Text=
+      Text French=%GROUP%
+      Text German=%GROUP%
+      Text Spanish=%GROUP%
+      Text Italian=%GROUP%
+    end
+  end
+end
+item: Custom Dialog Set
+  Name=Start Installation
+  Display Variable=DISPLAY
+  item: Dialog
+    Title=%APPTITLE% Installation
+    Title French=Installation de %APPTITLE%
+    Title German=Installation von %APPTITLE%
+    Title Spanish=Instalación de %APPTITLE%
+    Title Italian=Installazione di %APPTITLE%
+    Width=339
+    Height=280
+    Font Name=Helv
+    Font Size=8
+    item: Push Button
+      Rectangle=188 234 244 253
+      Variable=DIRECTION
+      Value=N
+      Create Flags=01010000000000010000000000000001
+      Text=&Next >
+      Text French=&Suite >
+      Text German=&Weiter >
+      Text Spanish=&Siguiente >
+      Text Italian=&Avanti >
+    end
+    item: Push Button
+      Rectangle=131 234 188 253
+      Variable=DIRECTION
+      Value=B
+      Create Flags=01010000000000010000000000000000
+      Text=< &Back
+      Text French=< &Retour
+      Text German=< &Zurück
+      Text Spanish=< &Atrás
+      Text Italian=< &Indietro
+    end
+    item: Push Button
+      Rectangle=264 234 320 253
+      Action=3
+      Create Flags=01010000000000010000000000000000
+      Text=&Cancel
+      Text French=&Annuler
+      Text German=&Abbrechen
+      Text Spanish=&Cancelar
+      Text Italian=&Annulla
+    end
+    item: Static
+      Rectangle=10 225 320 226
+      Action=3
+      Create Flags=01010000000000000000000000000111
+    end
+    item: Static
+      Rectangle=108 10 323 53
+      Create Flags=01010000000000000000000000000000
+      Flags=0000000000000001
+      Name=Times New Roman
+      Font Style=-24 0 0 0 700 255 0 0 0 3 2 1 18
+      Text=Ready to Install!
+      Text French=Prêt à installer !
+      Text German=Installationsbereit!
+      Text Spanish=¡Preparado para la instalación!
+      Text Italian=Pronto per l'installazione!
+    end
+    item: Static
+      Rectangle=108 40 320 62
+      Create Flags=01010000000000000000000000000000
+      Text=Click the Next button to install %APPTITLE%, or the Back button to change choices:
+      Text French=Vous êtes maintenant prêt à installer les fichiers %APPTITLE%.
+      Text French=
+      Text French=Cliquez sur le bouton Suite pour commencer l'installation ou sur le bouton Retour pour entrer les informations d'installation à nouveau.
+      Text German=Sie können %APPTITLE% nun installieren.
+      Text German=
+      Text German=Klicken Sie auf "Weiter", um mit der Installation zu beginnen. Klicken Sie auf "Zurück", um die Installationsinformationen neu einzugeben.
+      Text Spanish=Ya está listo para instalar %APPTITLE%.
+      Text Spanish=
+      Text Spanish=Presione el botón Siguiente para comenzar la instalación o presione Atrás para volver a ingresar la información para la instalación.
+      Text Italian=Ora è possibile installare %APPTITLE%.
+      Text Italian=
+      Text Italian=Premere il pulsante Avanti per avviare l'installazione o il pulsante Indietro per reinserire le informazioni di installazione.
+    end
+    item: Editbox
+      Rectangle=108 66 324 219
+      Help Context=16711681
+      Enabled Color=00000000000000001111111111111111
+      Create Flags=01010000100000000001100011000100
+      Text=%SUMMARY%
+    end
+  end
+end
+item: Remark
+end
+item: If/While Statement
+  Variable=DISPLAY
+  Value=Select Destination Directory
+end
+item: Remark
+  Text=User may have changed MAINDIR, so reset BACKUP to match.
+end
+item: Set Variable
+  Variable=BACKUP
+  Value=%MAINDIR%\BACKUP
+end
+item: End Block
+end
+item: Remark
+end
+item: End Block
+end
+item: Remark
+end
+item: Remark
+  Text=BEGIN WIZARD STUFF -----------------------------------------------------------------------------------------------------------------------------
+end
+item: Remark
+  Text=When the BACKUP feature is enabled, the BACKUPDIR is initialized
+end
+item: If/While Statement
+  Variable=DOBACKUP
+  Value=A
+end
+item: Set Variable
+  Variable=BACKUPDIR
+  Value=%BACKUP%
+end
+item: End Block
+end
+item: Remark
+  Text=The BRANDING information is written to the INI file on the installation media.
+end
+item: If/While Statement
+  Variable=BRANDING
+  Value=1
+end
+item: If/While Statement
+  Variable=DOBRAND
+  Value=1
+end
+item: Edit INI File
+  Pathname=%INST%\CUSTDATA.INI
+  Settings=[Registration]
+  Settings=NAME=%NAME%
+  Settings=COMPANY=%COMPANY%
+  Settings=
+end
+item: End Block
+end
+item: End Block
+end
+item: Remark
+  Text=Begin writing to the INSTALL.LOG
+end
+item: Open/Close INSTALL.LOG
+end
+item: Remark
+  Text=Check free disk space calculates free disk space as well as component sizes.
+end
+item: Remark
+  Text=It should be located before all Install File actions.
+end
+item: Check Disk Space
+  Component=COMPONENTS
+end
+item: Remark
+  Text=This include script allows uninstall support
+end
+item: Remark
+  Text=Note from Tim:  this is our own Uninstal.wse, a copy of Wise's except
+end
+item: Remark
+  Text=it writes to HKCU (instead of HKLM) if the user doesn't have admin privs.
+end
+item: Include Script
+  Pathname=.\Uninstal.wse
+end
+item: Remark
+  Text=Note from Tim: these seeming no-ops actually convert to short filenames.
+end
+item: Set Variable
+  Variable=COMMON
+  Value=%COMMON%
+  Flags=00010100
+end
+item: Set Variable
+  Variable=MAINDIR
+  Value=%MAINDIR%
+  Flags=00010100
+end
+item: Remark
+  Text=This IF/THEN/ELSE reads the correct registry entries for shortcut/icon placement
+end
+item: Check Configuration
+  Flags=10111011
+end
+item: Get Registry Key Value
+  Variable=STARTUPDIR
+  Key=Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders
+  Default=%WIN%\Start Menu\Programs\StartUp
+  Value Name=StartUp
+  Flags=00000010
+end
+item: Get Registry Key Value
+  Variable=DESKTOPDIR
+  Key=Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders
+  Default=%WIN%\Desktop
+  Value Name=Desktop
+  Flags=00000010
+end
+item: Get Registry Key Value
+  Variable=STARTMENUDIR
+  Key=Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders
+  Default=%WIN%\Start Menu
+  Value Name=Start Menu
+  Flags=00000010
+end
+item: Get Registry Key Value
+  Variable=GROUPDIR
+  Key=Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders
+  Default=%WIN%\Start Menu\Programs
+  Value Name=Programs
+  Flags=00000010
+end
+item: Get Registry Key Value
+  Variable=CSTARTUPDIR
+  Key=Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders
+  Default=%STARTUPDIR%
+  Value Name=Common Startup
+  Flags=00000100
+end
+item: Get Registry Key Value
+  Variable=CDESKTOPDIR
+  Key=Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders
+  Default=%DESKTOPDIR%
+  Value Name=Common Desktop
+  Flags=00000100
+end
+item: Get Registry Key Value
+  Variable=CSTARTMENUDIR
+  Key=Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders
+  Default=%STARTMENUDIR%
+  Value Name=Common Start Menu
+  Flags=00000100
+end
+item: Get Registry Key Value
+  Variable=CGROUPDIR
+  Key=Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders
+  Default=%GROUPDIR%
+  Value Name=Common Programs
+  Flags=00000100
+end
+item: Else Statement
+end
+item: Remark
+  Text=Note from Tim:  the Wizard left this block empty!
+end
+item: Remark
+  Text=Perhaps it's only relevant on Windows 3.1.
+end
+item: End Block
+end
+item: Remark
+  Text=END WIZARD STUFF -----------------------------------------------------------------------------------------------------------------------------
+end
+item: Remark
+end
+item: If/While Statement
+  Variable=SELECT_ADMIN
+  Value=B
+end
+item: Remark
+  Text=The user chose a non-admin install in "Advanced Options".
+end
+item: Remark
+  Text=This should come after the include of Uninstal.wse above, because
+end
+item: Remark
+  Text=writing uninstall info to HKCU is ineffective except under Win2K.
+end
+item: Set Variable
+  Variable=DOADMIN
+  Value=0
+end
+item: End Block
+end
+item: Remark
+end
+item: Set Variable
+  Variable=CGROUP_SAVE
+  Value=%GROUP%
+end
+item: If/While Statement
+  Variable=TASKS
+  Value=B
+  Flags=00000010
+end
+item: If/While Statement
+  Variable=DOADMIN
+  Value=1
+end
+item: Set Variable
+  Variable=GROUP
+  Value=%CGROUPDIR%\%GROUP%
+end
+item: Else Statement
+end
+item: Set Variable
+  Variable=GROUP
+  Value=%GROUPDIR%\%GROUP%
+end
+item: End Block
+end
+item: End Block
+end
+item: Remark
+end
+item: Remark
+  Text=Long section to install files.
+end
+item: Remark
+end
+item: If/While Statement
+  Variable=DOADMIN
+  Value=1
+end
+item: Set Variable
+  Variable=DLLDEST
+  Value=%SYS32%
+end
+item: Else Statement
+end
+item: Set Variable
+  Variable=DLLDEST
+  Value=%MAINDIR%
+end
+item: End Block
+end
+item: Remark
+end
+item: Remark
+  Text=Install the license even if they deselect everything <wink>.
+end
+item: Install File
+  Source=..\license
+  Destination=%MAINDIR%\LICENSE.txt
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\readme
+  Destination=%MAINDIR%\README.txt
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\misc\news
+  Destination=%MAINDIR%\NEWS.txt
+  Flags=0000000000000010
+end
+item: Remark
+  Text=Icons -- always install so that the uninstaller can use them for its own display.
+end
+item: Install File
+  Source=..\pc\pycon.ico
+  Destination=%MAINDIR%\pycon.ico
+  Flags=0000000010000010
+end
+item: Install File
+  Source=..\pc\pyc.ico
+  Destination=%MAINDIR%\pyc.ico
+  Flags=0000000010000010
+end
+item: Install File
+  Source=..\pc\py.ico
+  Destination=%MAINDIR%\py.ico
+  Flags=0000000010000010
+end
+item: Remark
+end
+item: Remark
+  Text=These arrange to (recursively!) delete all .pyc and .pyo files at uninstall time.
+end
+item: Remark
+  Text=This "does the right thing":  any directories left empty at the end are removed.
+end
+item: Add Text to INSTALL.LOG
+  Text=File Tree: %MAINDIR%\*.pyc
+end
+item: Add Text to INSTALL.LOG
+  Text=File Tree: %MAINDIR%\*.pyo
+end
+item: Remark
+end
+item: Remark
+  Text=A: interpreter and libraries
+end
+item: If/While Statement
+  Variable=COMPONENTS
+  Value=A
+  Flags=00000010
+end
+item: Remark
+  Text=Executables
+end
+item: Install File
+  Source=.\python.exe
+  Destination=%MAINDIR%\python.exe
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\pythonw.exe
+  Destination=%MAINDIR%\pythonw.exe
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\w9xpopen.exe
+  Destination=%MAINDIR%\w9xpopen.exe
+  Flags=0000000000000010
+end
+item: Remark
+end
+item: Remark
+  Text=Extension module DLLs (.pyd); keep in synch with libs directory next
+end
+item: Install File
+  Source=.\_winreg.pyd
+  Destination=%MAINDIR%\DLLs\_winreg.pyd
+  Description=Extension modules
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\_csv.pyd
+  Destination=%MAINDIR%\DLLs\_csv.pyd
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\_sre.pyd
+  Destination=%MAINDIR%\DLLs\_sre.pyd
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\_ssl.pyd
+  Destination=%MAINDIR%\DLLs\_ssl.pyd
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\_symtable.pyd
+  Destination=%MAINDIR%\DLLs\_symtable.pyd
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\_testcapi.pyd
+  Destination=%MAINDIR%\DLLs\_testcapi.pyd
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\_tkinter.pyd
+  Destination=%MAINDIR%\DLLs\_tkinter.pyd
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\_socket.pyd
+  Destination=%MAINDIR%\DLLs\_socket.pyd
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\_bsddb.pyd
+  Destination=%MAINDIR%\DLLs\_bsddb.pyd
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\bz2.pyd
+  Destination=%MAINDIR%\DLLs\bz2.pyd
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\datetime.pyd
+  Destination=%MAINDIR%\DLLs\datetime.pyd
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\mmap.pyd
+  Destination=%MAINDIR%\DLLs\mmap.pyd
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\parser.pyd
+  Destination=%MAINDIR%\DLLs\parser.pyd
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\pyexpat.pyd
+  Destination=%MAINDIR%\DLLs\pyexpat.pyd
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\select.pyd
+  Destination=%MAINDIR%\DLLs\select.pyd
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\unicodedata.pyd
+  Destination=%MAINDIR%\DLLs\unicodedata.pyd
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\winsound.pyd
+  Destination=%MAINDIR%\DLLs\winsound.pyd
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\zlib.pyd
+  Destination=%MAINDIR%\DLLs\zlib.pyd
+  Flags=0000000000000010
+end
+item: Remark
+end
+item: Remark
+  Text=Link libraries (.lib); keep in synch with DLLs above, except that the Python lib lives here.
+end
+item: Install File
+  Source=.\_winreg.lib
+  Destination=%MAINDIR%\libs\_winreg.lib
+  Description=Link library files
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\_csv.lib
+  Destination=%MAINDIR%\libs\_csv.lib
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\_sre.lib
+  Destination=%MAINDIR%\libs\_sre.lib
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\_ssl.lib
+  Destination=%MAINDIR%\libs\_ssl.lib
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\_symtable.lib
+  Destination=%MAINDIR%\libs\_symtable.lib
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\_testcapi.lib
+  Destination=%MAINDIR%\libs\_testcapi.lib
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\_tkinter.lib
+  Destination=%MAINDIR%\libs\_tkinter.lib
+  Description=Extension modules
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\_socket.lib
+  Destination=%MAINDIR%\libs\_socket.lib
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\_bsddb.lib
+  Destination=%MAINDIR%\libs\_bsddb.lib
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\bz2.lib
+  Destination=%MAINDIR%\libs\bz2.lib
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\datetime.lib
+  Destination=%MAINDIR%\libs\datetime.lib
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\mmap.lib
+  Destination=%MAINDIR%\libs\mmap.lib
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\parser.lib
+  Destination=%MAINDIR%\libs\parser.lib
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\pyexpat.lib
+  Destination=%MAINDIR%\libs\pyexpat.lib
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\select.lib
+  Destination=%MAINDIR%\libs\select.lib
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\unicodedata.lib
+  Destination=%MAINDIR%\libs\unicodedata.lib
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\winsound.lib
+  Destination=%MAINDIR%\libs\winsound.lib
+  Flags=0000000000000010
+end
+item: Install File
+  Source=.\zlib.lib
+  Destination=%MAINDIR%\libs\zlib.lib
+  Flags=0000000000000010
+end
+item: Remark
+end
+item: Install File
+  Source=.\python%_pymajor_%%_pyminor_%.lib
+  Destination=%MAINDIR%\libs\python%_PYMAJOR_%%_PYMINOR_%.lib
+  Flags=0000000000000010
+end
+item: Remark
+end
+item: Remark
+  Text=Main Python DLL
+end
+item: Remark
+  Text=Tell Wise it's OK to delete the Python DLL at uninstall time,
+end
+item: Remark
+  Text=despite that we (may) write it into a system directory.
+end
+item: Add Text to INSTALL.LOG
+  Text=Non-System File:
+end
+item: Install File
+  Source=.\python%_pymajor_%%_pyminor_%.dll
+  Destination=%DLLDEST%\python%_PYMAJOR_%%_PYMINOR_%.dll
+  Flags=0000000000000010
+end
+item: Remark
+end
+item: Remark
+  Text=Libraries (Lib/)
+end
+item: Install File
+  Source=..\lib\*.py
+  Destination=%MAINDIR%\Lib
+  Description=Library Modules
+  Flags=0000000000000010
+end
+item: Remark
+end
+item: Install File
+  Source=..\lib\bsddb\*.py
+  Destination=%MAINDIR%\Lib\bsddb
+  Description=Berkeley database package
+  Flags=0000000100000010
+end
+item: Remark
+end
+item: Install File
+  Source=..\lib\compiler\*.py
+  Destination=%MAINDIR%\Lib\compiler
+  Description=Python compiler written in Python
+  Flags=0000000000000010
+end
+item: Remark
+end
+item: Install File
+  Source=..\lib\distutils\*.py
+  Destination=%MAINDIR%\Lib\distutils
+  Description=Distribution utility modules
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\lib\distutils\readme
+  Destination=%MAINDIR%\Lib\distutils\README.txt
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\lib\distutils\command\*.py
+  Destination=%MAINDIR%\Lib\distutils\command
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\lib\distutils\command\wininst.exe
+  Destination=%MAINDIR%\Lib\distutils\command\wininst.exe
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\lib\distutils\command\command_template
+  Destination=%MAINDIR%\Lib\distutils\command\command_template
+  Flags=0000000000000010
+end
+item: Remark
+end
+item: Install File
+  Source=..\lib\email\*.py
+  Destination=%MAINDIR%\Lib\email
+  Description=Library email package
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\lib\email\test\*.py
+  Destination=%MAINDIR%\Lib\email\test
+  Description=email tests
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\lib\email\test\data\*.txt
+  Destination=%MAINDIR%\Lib\email\test\data
+  Description=email test data
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\lib\email\test\data\*.gif
+  Destination=%MAINDIR%\Lib\email\test\data
+  Description=email test data
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\lib\email\test\data\*.au
+  Destination=%MAINDIR%\Lib\email\test\data
+  Description=email test data
+  Flags=0000000000000010
+end
+item: Remark
+end
+item: Install File
+  Source=..\lib\encodings\*.py
+  Destination=%MAINDIR%\Lib\encodings
+  Description=Unicode encoding tables
+  Flags=0000000000000010
+end
+item: Remark
+end
+item: Install File
+  Source=..\lib\hotshot\*.py
+  Destination=%MAINDIR%\Lib\hotshot
+  Description=Fast Python profiler
+  Flags=0000000000000010
+end
+item: Remark
+end
+item: Install File
+  Source=..\lib\lib-old\*.py
+  Destination=%MAINDIR%\Lib\lib-old
+  Description=Obsolete modules
+  Flags=0000000000000010
+end
+item: Remark
+end
+item: Install File
+  Source=..\lib\lib-tk\*.py
+  Destination=%MAINDIR%\Lib\lib-tk
+  Description=Tkinter related library modules
+  Flags=0000000000000010
+end
+item: Remark
+end
+item: Install File
+  Source=..\lib\logging\*.py
+  Destination=%MAINDIR%\Lib\logging
+  Description=Logging package
+  Flags=0000000000000010
+end
+item: Remark
+end
+item: Install File
+  Source=..\lib\site-packages\readme
+  Destination=%MAINDIR%\Lib\site-packages\README.txt
+  Description=Site packages
+  Flags=0000000000000010
+end
+item: Remark
+end
+item: Install File
+  Source=..\lib\xml\*.py
+  Destination=%MAINDIR%\Lib\xml
+  Description=XML support packages
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\lib\xml\dom\*.py
+  Destination=%MAINDIR%\Lib\xml\dom
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\lib\xml\parsers\*.py
+  Destination=%MAINDIR%\Lib\xml\parsers
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\lib\xml\sax\*.py
+  Destination=%MAINDIR%\Lib\xml\sax
+  Flags=0000000000000010
+end
+item: Remark
+end
+item: Remark
+  Text=C Include files
+end
+item: Install File
+  Source=..\include\*.h
+  Destination=%MAINDIR%\include
+  Description=Header files
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\pc\pyconfig.h
+  Destination=%MAINDIR%\include\pyconfig.h
+  Description=Header files (pyconfig.h)
+  Flags=0000000000000010
+end
+item: Remark
+end
+item: Remark
+  Text=Microsoft C runtime libraries
+end
+item: Install File
+  Source=%_SYS_%\MSVCIRT.DLL
+  Destination=%DLLDEST%\MSVCIRT.DLL
+  Description=Visual C++ Runtime DLLs
+  Flags=0000011000010011
+end
+item: Install File
+  Source=%_SYS_%\MSVCRT.DLL
+  Destination=%DLLDEST%\MSVCRT.DLL
+  Description=Visual C++ Runtime DLLs
+  Flags=0000011000010011
+end
+item: End Block
+end
+item: Remark
+end
+item: Remark
+  Text=B: Tcl/Tk (Tkinter, IDLE, pydoc)
+end
+item: If/While Statement
+  Variable=COMPONENTS
+  Value=B
+  Flags=00000010
+end
+item: Remark
+  Text=Tcl/Tk
+end
+item: Install File
+  Source=..\..\%_tcldir_%\bin\*.dll
+  Destination=%MAINDIR%\DLLs
+  Description=Tcl/Tk binaries and libraries
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\..\%_tcldir_%\lib\*.*
+  Destination=%MAINDIR%\tcl
+  Description=Tcl/Tk binaries and libraries
+  Flags=0000000100000010
+end
+item: Remark
+end
+item: Remark
+  Text=IDLE
+end
+item: Install File
+  Source=..\Lib\idlelib\*.py
+  Destination=%MAINDIR%\Lib\idlelib
+  Description=Integrated DeveLopment Environment for Python
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\Lib\idlelib\*.txt
+  Destination=%MAINDIR%\Lib\idlelib
+  Description=Integrated DeveLopment Environment for Python
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\Lib\idlelib\*.def
+  Destination=%MAINDIR%\Lib\idlelib
+  Description=Integrated DeveLopment Environment for Python
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\Lib\idlelib\Icons\*
+  Destination=%MAINDIR%\Lib\idlelib\Icons
+  Description=Integrated DeveLopment Environment for Python
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\Tools\scripts\idle
+  Destination=%MAINDIR%\Lib\idlelib\idle.pyw
+  Description=IDLE bootstrap script
+  Flags=0000000000000010
+end
+item: Remark
+end
+item: Remark
+  Text=Windows pydoc driver
+end
+item: Install File
+  Source=..\tools\scripts\*.pyw
+  Destination=%MAINDIR%\Tools\Scripts
+  Description=Windows pydoc driver
+  Flags=0000000000000010
+end
+item: End Block
+end
+item: Remark
+end
+item: Remark
+  Text=C: docs
+end
+item: If/While Statement
+  Variable=COMPONENTS
+  Value=C
+  Flags=00000010
+end
+item: Install File
+  Source=%_DOC_%\*.*
+  Destination=%MAINDIR%\Doc
+  Description=Python Documentation (HTML)
+  Flags=0000000100000010
+end
+item: End Block
+end
+item: Remark
+end
+item: Remark
+  Text=D: tools
+end
+item: If/While Statement
+  Variable=COMPONENTS
+  Value=D
+  Flags=00000010
+end
+item: Install File
+  Source=..\tools\scripts\*.py
+  Destination=%MAINDIR%\Tools\Scripts
+  Description=Utility Scripts
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\tools\scripts\*.doc
+  Destination=%MAINDIR%\Tools\Scripts
+  Description=Utility Scripts
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\tools\scripts\readme
+  Destination=%MAINDIR%\Tools\Scripts\README.txt
+  Description=Utility Scripts
+  Flags=0000000000000010
+end
+item: Remark
+end
+item: Install File
+  Source=..\tools\webchecker\*.py
+  Destination=%MAINDIR%\Tools\webchecker
+  Description=Web checker tool
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\tools\webchecker\readme
+  Destination=%MAINDIR%\Tools\webchecker\README.txt
+  Description=Web checker tool
+  Flags=0000000000000010
+end
+item: Remark
+end
+item: Install File
+  Source=..\tools\versioncheck\*.py
+  Destination=%MAINDIR%\Tools\versioncheck
+  Description=Version checker tool
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\tools\versioncheck\readme
+  Destination=%MAINDIR%\Tools\versioncheck\README.txt
+  Description=Version checker tool
+  Flags=0000000000000010
+end
+item: Remark
+end
+item: Install File
+  Source=..\tools\pynche\*.py
+  Destination=%MAINDIR%\Tools\pynche
+  Description=pynche color editor
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\tools\pynche\*.txt
+  Destination=%MAINDIR%\Tools\pynche
+  Description=pynche color editor
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\tools\pynche\x\*.txt
+  Destination=%MAINDIR%\Tools\pynche\X
+  Description=pynche color editor - X files
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\tools\pynche\readme
+  Destination=%MAINDIR%\Tools\pynche\README.txt
+  Description=pynche color editor - README
+  Flags=0000000100000010
+end
+item: Install File
+  Source=..\tools\pynche\pynche
+  Destination=%MAINDIR%\Tools\pynche\pynche.py
+  Description=pynche color editor - main
+  Flags=0000000100000010
+end
+item: Install File
+  Source=..\tools\pynche\pynche.pyw
+  Destination=%MAINDIR%\Tools\pynche\pynche.pyw
+  Description=pynche color editor - noconsole main
+  Flags=0000000100000010
+end
+item: Remark
+end
+item: Install File
+  Source=..\tools\i18n\*.py
+  Destination=%MAINDIR%\Tools\i18n
+  Description=Internationalization helpers
+  Flags=0000000000000010
+end
+item: End Block
+end
+item: Remark
+end
+item: Remark
+  Text=E: test suite
+end
+item: If/While Statement
+  Variable=COMPONENTS
+  Value=E
+  Flags=00000010
+end
+item: Install File
+  Source=..\lib\test\audiotest.au
+  Destination=%MAINDIR%\Lib\test\audiotest.au
+  Description=Python Test files
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\lib\test\*.uue
+  Destination=%MAINDIR%\Lib\test
+  Description=Python Test files
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\lib\test\*.py
+  Destination=%MAINDIR%\Lib\test
+  Description=Python Test files
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\lib\test\*.xml
+  Destination=%MAINDIR%\Lib\test
+  Description=Python Test files
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\lib\test\*.out
+  Destination=%MAINDIR%\Lib\test
+  Description=Python Test files
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\lib\test\*.bz2
+  Destination=%MAINDIR%\Lib\test
+  Description=Python Test files
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\lib\test\*.tar
+  Destination=%MAINDIR%\Lib\test
+  Description=Python Test files
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\lib\test\*.gz
+  Destination=%MAINDIR%\Lib\test
+  Description=Python Test files
+  Flags=0000000000000010
+end
+item: Install File
+  Source=..\lib\test\*.txt
+  Destination=%MAINDIR%\Lib\test
+  Description=Python Test files
+  Flags=0000000000000010
+end
+item: Remark
+end
+item: Install File
+  Source=..\lib\test\output\*.*
+  Destination=%MAINDIR%\Lib\test\output
+  Description=Python Test output files
+  Flags=0000000000000010
+end
+item: End Block
+end
+item: Remark
+end
+item: Remark
+  Text=DONE with file copying.
+end
+item: Remark
+  Text=The rest is registry and Start Menu fiddling.
+end
+item: Remark
+end
+item: If/While Statement
+  Variable=COMPONENTS
+  Value=A
+  Flags=00000010
+end
+item: If/While Statement
+  Variable=TASKS
+  Value=A
+  Flags=00000010
+end
+item: Remark
+  Text=Register file extensions.  As usual, Admin privs get in the way, but with a twist:
+end
+item: Remark
+  Text=You don't need admin privs to write to HKEY_CLASSES_ROOT *except* under Win2K.
+end
+item: Remark
+  Text=On Win2K, a user without Admin privs has to register extensions under HKCU\Software\CLASSES instead.
+end
+item: Remark
+  Text=But while you can *do* that under other flavors of Windows too, it has no useful effect except in Win2K.
+end
+item: Set Variable
+  Variable=USE_HKCR
+  Value=1
+end
+item: Check Configuration
+  Flags=11110010
+end
+item: If/While Statement
+  Variable=DOADMIN
+  Value=0
+end
+item: Set Variable
+  Variable=USE_HKCR
+  Value=0
+end
+item: End Block
+end
+item: End Block
+end
+item: If/While Statement
+  Variable=USE_HKCR
+  Value=1
+end
+item: Remark
+  Text=File types.
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Python.File
+  New Value=Python File
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Python.File\shell\open\command
+  New Value=%MAINDIR%\python.exe "%%1" %%*
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Python.File\DefaultIcon
+  New Value=%MAINDIR%\Py.ico
+end
+item: Remark
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Python.NoConFile
+  New Value=Python File (no console)
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Python.NoConFile\shell\open\command
+  New Value=%MAINDIR%\pythonw.exe "%%1" %%*
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Python.NoConFile\DefaultIcon
+  New Value=%MAINDIR%\Py.ico
+end
+item: Remark
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Python.CompiledFile
+  New Value=Compiled Python File
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Python.CompiledFile\shell\open\command
+  New Value=%MAINDIR%\python.exe "%%1" %%*
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Python.CompiledFile\DefaultIcon
+  New Value=%MAINDIR%\pyc.ico
+end
+item: Remark
+end
+item: Remark
+  Text=File extensions.
+end
+item: Edit Registry
+  Total Keys=1
+  Key=.py
+  New Value=Python.File
+end
+item: Edit Registry
+  Total Keys=1
+  Key=.py
+  New Value=text/plain
+  Value Name=Content Type
+end
+item: Remark
+end
+item: Edit Registry
+  Total Keys=1
+  Key=.pyw
+  New Value=Python.NoConFile
+end
+item: Edit Registry
+  Total Keys=1
+  Key=.pyw
+  New Value=text/plain
+  Value Name=Content Type
+end
+item: Remark
+end
+item: Edit Registry
+  Total Keys=1
+  Key=.pyc
+  New Value=Python.CompiledFile
+end
+item: Edit Registry
+  Total Keys=1
+  Key=.pyo
+  New Value=Python.CompiledFile
+end
+item: Else Statement
+end
+item: Remark
+  Text=File types.
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\CLASSES\Python.File
+  New Value=Python File
+  Root=1
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\CLASSES\Python.File\shell\open\command
+  New Value=%MAINDIR%\python.exe "%%1" %%*
+  Root=1
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\CLASSES\Python.File\DefaultIcon
+  New Value=%MAINDIR%\Py.ico
+  Root=1
+end
+item: Remark
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\CLASSES\Python.NoConFile
+  New Value=Python File (no console)
+  Root=1
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\CLASSES\Python.NoConFile\shell\open\command
+  New Value=%MAINDIR%\pythonw.exe "%%1" %%*
+  Root=1
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\CLASSES\Python.NoConFile\DefaultIcon
+  New Value=%MAINDIR%\Py.ico
+  Root=1
+end
+item: Remark
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\CLASSES\Python.CompiledFile
+  New Value=Compiled Python File
+  Root=1
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\CLASSES\Python.CompiledFile\shell\open\command
+  New Value=%MAINDIR%\python.exe "%%1" %%*
+  Root=1
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\CLASSES\Python.CompiledFile\DefaultIcon
+  New Value=%MAINDIR%\pyc.ico
+  Root=1
+end
+item: Remark
+end
+item: Remark
+  Text=File extensions.
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\CLASSES\.py
+  New Value=Python.File
+  Root=1
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\CLASSES\.py
+  New Value=text/plain
+  Value Name=Content Type
+  Root=1
+end
+item: Remark
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\CLASSES\.pyw
+  New Value=Python.NoConFile
+  Root=1
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\CLASSES\.pyw
+  New Value=text/plain
+  Value Name=Content Type
+  Root=1
+end
+item: Remark
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\CLASSES\.pyc
+  New Value=Python.CompiledFile
+  Root=1
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\CLASSES\.pyo
+  New Value=Python.CompiledFile
+  Root=1
+end
+item: End Block
+end
+item: Remark
+end
+item: Remark
+  Text=If we're installing IDLE, also set an Edit context menu action to use IDLE, for .py and .pyw files.
+end
+item: If/While Statement
+  Variable=COMPONENTS
+  Value=B
+  Flags=00000010
+end
+item: If/While Statement
+  Variable=USE_HKCR
+  Value=1
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Python.NoConFile\shell\Edit with IDLE\command
+  New Value=%MAINDIR%\pythonw.exe %MAINDIR%\Lib\idlelib\idle.pyw -n -e "%%1"
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Python.File\shell\Edit with IDLE\command
+  New Value=%MAINDIR%\pythonw.exe %MAINDIR%\Lib\idlelib\idle.pyw -n -e "%%1"
+end
+item: Else Statement
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\CLASSES\Python.NoConFile\shell\Edit with IDLE\command
+  New Value=%MAINDIR%\pythonw.exe %MAINDIR%\Lib\idlelib\idle.pyw -n -e "%%1"
+  Root=1
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\CLASSES\Python.File\shell\Edit with IDLE\command
+  New Value=%MAINDIR%\pythonw.exe %MAINDIR%\Lib\idlelib\idle.pyw -n -e "%%1"
+  Root=1
+end
+item: End Block
+end
+item: End Block
+end
+item: End Block
+end
+item: Remark
+end
+item: Remark
+  Text=Register Python paths.
+end
+item: Remark
+  Text=Write to HKLM for admin, else HKCU.  Keep these blocks otherwise identical!
+end
+item: If/While Statement
+  Variable=DOADMIN
+  Value=1
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Python\PythonCore\CurrentVersion
+  Root=130
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Python\PythonCore\%PY_VERSION%\InstallPath
+  New Value=%MAINDIR%
+  Root=2
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Python\PythonCore\%PY_VERSION%\InstallPath\InstallGroup
+  New Value=%CGROUP_SAVE%
+  New Value=
+  Root=2
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Python\PythonCore\%PY_VERSION%\PythonPath
+  New Value=%MAINDIR%\Lib;%MAINDIR%\DLLs;%MAINDIR%\Lib\lib-tk
+  New Value=
+  Root=2
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Python\PythonCore\%PY_VERSION%\Modules
+  Root=2
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Microsoft\Windows\CurrentVersion\App Paths\Python.exe
+  New Value=%MAINDIR%\Python.exe
+  Root=2
+end
+item: Else Statement
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Python\PythonCore\CurrentVersion
+  Root=129
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Python\PythonCore\%PY_VERSION%\InstallPath
+  New Value=%MAINDIR%
+  Root=1
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Python\PythonCore\%PY_VERSION%\InstallPath\InstallGroup
+  New Value=%CGROUP_SAVE%
+  New Value=
+  Root=1
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Python\PythonCore\%PY_VERSION%\PythonPath
+  New Value=%MAINDIR%\Lib;%MAINDIR%\DLLs;%MAINDIR%\Lib\lib-tk
+  New Value=
+  Root=1
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Python\PythonCore\%PY_VERSION%\Modules
+  Root=1
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Microsoft\Windows\CurrentVersion\App Paths\Python.exe
+  New Value=%MAINDIR%\Python.exe
+  Root=1
+end
+item: End Block
+end
+item: End Block
+end
+item: Remark
+end
+item: Remark
+  Text=Registry fiddling for docs.
+end
+item: Remark
+  Text=Write to HKLM for admin, else HKCU.  Keep these blocks otherwise identical!
+end
+item: If/While Statement
+  Variable=COMPONENTS
+  Value=C
+  Flags=00000010
+end
+item: If/While Statement
+  Variable=DOADMIN
+  Value=1
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Python\PythonCore\%PY_VERSION%\Help\Main Python Documentation
+  New Value=%MAINDIR%\Doc\index.html
+  Root=2
+end
+item: Else Statement
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Python\PythonCore\%PY_VERSION%\Help\Main Python Documentation
+  New Value=%MAINDIR%\Doc\index.html
+  Root=1
+end
+item: End Block
+end
+item: End Block
+end
+item: Remark
+end
+item: Remark
+  Text=Set the app publisher and URL entries for Win2K add/remove.
+end
+item: Remark
+  Text=It doesn't hurt on other systems.
+end
+item: Remark
+  Text=As usual, write to HKLM or HKCU depending on Admin privs.
+end
+item: Remark
+  Text=CAUTION:  If you set this info on the "Windows 2000" page (step 6) of the
+end
+item: Remark
+  Text=Installation Expert, it only shows up in the "If" block below.  Keep in synch!
+end
+item: If/While Statement
+  Variable=DOADMIN
+  Value=1
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Microsoft\Windows\CurrentVersion\Uninstall\%APPTITLE%
+  New Value=http://www.python.org/
+  Value Name=HelpLink
+  Root=2
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Microsoft\Windows\CurrentVersion\Uninstall\%APPTITLE%
+  New Value=PythonLabs at Zope Corporation
+  Value Name=Publisher
+  Root=2
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Microsoft\Windows\CurrentVersion\Uninstall\%APPTITLE%
+  New Value=http://www.python.org/
+  Value Name=URLInfoAbout
+  Root=2
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Microsoft\Windows\CurrentVersion\Uninstall\%APPTITLE%
+  New Value=%PYVER_STRING%
+  Value Name=DisplayVersion
+  Root=2
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Microsoft\Windows\CurrentVersion\Uninstall\%APPTITLE%
+  New Value=%MAINDIR%\py.ico,-0
+  Value Name=DisplayIcon
+  Root=2
+end
+item: Else Statement
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Microsoft\Windows\CurrentVersion\Uninstall\%APPTITLE%
+  New Value=http://www.python.org/
+  Value Name=HelpLink
+  Root=1
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Microsoft\Windows\CurrentVersion\Uninstall\%APPTITLE%
+  New Value=PythonLabs at Zope Corporation
+  Value Name=Publisher
+  Root=1
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Microsoft\Windows\CurrentVersion\Uninstall\%APPTITLE%
+  New Value=http://www.python.org/
+  Value Name=URLInfoAbout
+  Root=1
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Microsoft\Windows\CurrentVersion\Uninstall\%APPTITLE%
+  New Value=%PYVER_STRING%
+  Value Name=DisplayVersion
+  Root=1
+end
+item: Edit Registry
+  Total Keys=1
+  Key=Software\Microsoft\Windows\CurrentVersion\Uninstall\%APPTITLE%
+  New Value=%MAINDIR%\py.ico,-0
+  Value Name=DisplayIcon
+  Root=1
+end
+item: End Block
+end
+item: Remark
+end
+item: Remark
+  Text=Populate Start Menu group
+end
+item: If/While Statement
+  Variable=TASKS
+  Value=B
+  Flags=00000010
+end
+item: Remark
+  Text=Shortcut to installer no matter what.
+end
+item: Create Shortcut
+  Source=%MAINDIR%\unwise.exe
+  Destination=%GROUP%\Uninstall Python.lnk
+  Working Directory=%MAINDIR%
+  Key Type=1536
+  Flags=00000001
+end
+item: Remark
+end
+item: If/While Statement
+  Variable=COMPONENTS
+  Value=A
+  Flags=00000010
+end
+item: Create Shortcut
+  Source=%MAINDIR%\python.exe
+  Destination=%GROUP%\Python (command line).lnk
+  Working Directory=%MAINDIR%
+  Icon Pathname=%MAINDIR%\pycon.ico
+  Key Type=1536
+  Flags=00000001
+end
+item: End Block
+end
+item: Remark
+end
+item: If/While Statement
+  Variable=COMPONENTS
+  Value=B
+  Flags=00000010
+end
+item: Create Shortcut
+  Source=%MAINDIR%\pythonw.exe
+  Destination=%GROUP%\IDLE (Python GUI).lnk
+  Command Options="%MAINDIR%\Lib\idlelib\idle.pyw"
+  Working Directory=%MAINDIR%
+  Key Type=1536
+  Flags=00000001
+end
+item: Create Shortcut
+  Source=%MAINDIR%\pythonw.exe
+  Destination=%GROUP%\Module Docs.lnk
+  Command Options="%MAINDIR%\Tools\Scripts\pydocgui.pyw"
+  Working Directory=%MAINDIR%
+  Key Type=1536
+  Flags=00000001
+end
+item: End Block
+end
+item: Remark
+end
+item: If/While Statement
+  Variable=COMPONENTS
+  Value=C
+  Flags=00000010
+end
+item: Create Shortcut
+  Source=%MAINDIR%\Doc\index.html
+  Destination=%GROUP%\Python Manuals.lnk
+  Working Directory=%MAINDIR%
+  Key Type=1536
+  Flags=00000001
+end
+item: End Block
+end
+item: End Block
+end
+item: Remark
+end
+item: Remark
+  Text=I don't think we need this, but have always done it.
+end
+item: Self-Register OCXs/DLLs
+  Description=Updating System Configuration, Please Wait...
+end
+item: Remark
+end
+remarked item: Remark
+  Text=Don't enable "Delete in-use files".  Here's what happens:
+end
+remarked item: Remark
+  Text=Install Python; uninstall Python; install Python again.  Reboot the machine.
+end
+remarked item: Remark
+  Text=Now UNWISE.EXE is missing.  I think this is a Wise bug, but so it goes.
+end
+remarked item: Add Text to INSTALL.LOG
+  Text=Delete in-use files: On
+end
+item: Remark
+end
+item: Wizard Block
+  Direction Variable=DIRECTION
+  Display Variable=DISPLAY
+  Bitmap Pathname=.\installer.bmp
+  X Position=9
+  Y Position=10
+  Filler Color=11173759
+  Flags=00000011
+end
+item: Custom Dialog Set
+  Name=Finished
+  Display Variable=DISPLAY
+  item: Dialog
+    Title=%APPTITLE% Installation
+    Title French=Installation de %APPTITLE%
+    Title German=Installation von %APPTITLE%
+    Title Spanish=Instalación de %APPTITLE%
+    Title Italian=Installazione di %APPTITLE%
+    Width=339
+    Height=280
+    Font Name=Helv
+    Font Size=8
+    item: Push Button
+      Rectangle=188 234 244 253
+      Variable=DIRECTION
+      Value=N
+      Create Flags=01010000000000010000000000000001
+      Text=&Finish
+      Text French=&Fin
+      Text German=&Weiter
+      Text Spanish=&Terminar
+      Text Italian=&Fine
+    end
+    item: Push Button
+      Rectangle=264 234 320 253
+      Variable=DISABLED
+      Value=!
+      Action=3
+      Create Flags=01010000000000010000000000000000
+      Text=&Cancel
+      Text French=&Annuler
+      Text German=&Abbrechen
+      Text Spanish=&Cancelar
+      Text Italian=&Annulla
+    end
+    item: Static
+      Rectangle=108 10 323 48
+      Create Flags=01010000000000000000000000000000
+      Flags=0000000000000001
+      Name=Times New Roman
+      Font Style=-24 0 0 0 700 255 0 0 0 3 2 1 18
+      Text=Installation Completed!
+      Text French=Installation terminée !
+      Text German=Die Installation ist abgeschlossen!
+      Text Spanish=¡Instalación terminada!
+      Text Italian=Installazione completata!
+    end
+    item: Static
+      Rectangle=108 44 320 82
+      Create Flags=01010000000000000000000000000000
+      Text=%APPTITLE% has been successfully installed.
+      Text=
+      Text=Press the Finish button to exit this installation.
+      Text French=%APPTITLE% est maintenant installé.
+      Text French=
+      Text French=Cliquez sur le bouton Fin pour quitter l'installation.
+      Text German=%APPTITLE% wurde erfolgreich installiert.
+      Text German=
+      Text German=Klicken Sie auf "Weiter", um die Installation zu beenden.
+      Text Spanish=%APPTITLE% se ha instalado con éxito.
+      Text Spanish=
+      Text Spanish=Presione el botón Terminar para salir de esta instalación.
+      Text Italian=L'installazione %APPTITLE% è stata portata a termine con successo.
+      Text Italian=
+      Text Italian=Premere il pulsante Fine per uscire dall'installazione.
+    end
+    item: Static
+      Rectangle=10 225 320 226
+      Action=3
+      Create Flags=01010000000000000000000000000111
+    end
+    item: Static
+      Rectangle=106 105 312 210
+      Enabled Color=00000000000000001111111111111111
+      Create Flags=01010000000000000000000000000000
+      Text=Special Windows thanks to:
+      Text=
+      Text=Wise Solutions, for the use of InstallMaster 8.1.
+      Text=    http://www.wisesolutions.com/
+      Text=
+      Text=
+      Text=LettError, Erik van Blokland, for the Python for Windows graphic.
+      Text=    http://www.letterror.com/
+      Text=
+      Text=
+      Text=Mark Hammond, without whose years of freely shared Windows expertise, Python for Windows would still be Python for DOS.
+    end
+    item: Static
+      Rectangle=106 95 312 96
+      Action=3
+      Enabled Color=00000000000000001111111111111111
+      Create Flags=01010000000000000000000000001001
+    end
+  end
+end
+item: End Block
+end
+item: New Event
+  Name=Cancel
+end
+item: Remark
+  Text=This include script supports a rollback to preinstallation state if the user chooses to cancel before the installation is complete.
+end
+item: Include Script
+  Pathname=%_WISE_%\INCLUDE\rollback.wse
+end

Added: vendor/Python/current/PCbuild8/pythoncore.vcproj
===================================================================
--- vendor/Python/current/PCbuild8/pythoncore.vcproj	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild8/pythoncore.vcproj	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1938 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8,00"
+	Name="pythoncore"
+	ProjectGUID="{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}"
+	RootNamespace="pythoncore"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(PlatformName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\pythoncore"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+				CommandLine=""
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions="/Zm200 "
+				Optimization="2"
+				WholeProgramOptimization="true"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;USE_DL_EXPORT;_CRT_SECURE_NO_DEPRECATE"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"
+				AdditionalIncludeDirectories="..\Include"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				CommandLine=""
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\python25.dll"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				IgnoreDefaultLibraryNames="libc"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				SubSystem="2"
+				LinkTimeCodeGeneration="1"
+				BaseAddress="0x1e000000"
+				ImportLibrary=""
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			OutputDirectory="$(PlatformName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\pythoncore"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+				CommandLine=""
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions="/Zm200 "
+				Optimization="2"
+				WholeProgramOptimization="true"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;USE_DL_EXPORT;_CRT_SECURE_NO_DEPRECATE"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="false"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"
+				AdditionalIncludeDirectories="..\Include"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				CommandLine=""
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\python25.dll"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				IgnoreDefaultLibraryNames="libc"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				SubSystem="2"
+				LinkTimeCodeGeneration="1"
+				BaseAddress="0x1e000000"
+				ImportLibrary=""
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(PlatformName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\pythoncore"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions="/Zm200 "
+				Optimization="0"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="_DEBUG;USE_DL_EXPORT;WIN32;_WINDOWS;_CRT_SECURE_NO_DEPRECATE"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="_DEBUG"
+				Culture="1033"
+				AdditionalIncludeDirectories="..\Include"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				Description="generate buildinfo"
+				CommandLine="make_buildinfo.exe $(ConfigurationName)"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\python25_d.dll"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				IgnoreDefaultLibraryNames="libc"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				SubSystem="2"
+				BaseAddress="0x1e000000"
+				ImportLibrary=""
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			OutputDirectory="$(PlatformName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\pythoncore"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions="/Zm200 "
+				Optimization="0"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="_DEBUG;USE_DL_EXPORT;WIN32;_WINDOWS;_CRT_SECURE_NO_DEPRECATE"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="_DEBUG"
+				Culture="1033"
+				AdditionalIncludeDirectories="..\Include"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				CommandLine=""
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\python25_d.dll"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				IgnoreDefaultLibraryNames="libc"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				SubSystem="2"
+				BaseAddress="0x1e000000"
+				ImportLibrary=""
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGIRelease|Win32"
+			OutputDirectory="$(PlatformName)\$(ConfigurationName)\pythoncore"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\pythoncore"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+				Description="Get getbuildinfo2.c"
+				CommandLine="make_buildinfo.exe"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions="/Zm200 "
+				Optimization="2"
+				WholeProgramOptimization="true"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;USE_DL_EXPORT;_CRT_SECURE_NO_DEPRECATE"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"
+				AdditionalIncludeDirectories="..\Include"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				CommandLine=""
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)/python25.dll"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				IgnoreDefaultLibraryNames="libc"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				SubSystem="2"
+				LinkTimeCodeGeneration="2"
+				BaseAddress="0x1e000000"
+				ImportLibrary=""
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				CommandLine=""
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGIRelease|x64"
+			OutputDirectory="$(PlatformName)\$(ConfigurationName)\pythoncore"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\pythoncore"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+				Description="Get getbuildinfo2.c"
+				CommandLine="make_buildinfo.exe"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions="/Zm200 "
+				Optimization="2"
+				WholeProgramOptimization="true"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;USE_DL_EXPORT;_CRT_SECURE_NO_DEPRECATE"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"
+				AdditionalIncludeDirectories="..\Include"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				CommandLine=""
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)/python25.dll"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				IgnoreDefaultLibraryNames="libc"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				SubSystem="2"
+				LinkTimeCodeGeneration="2"
+				BaseAddress="0x1e000000"
+				ImportLibrary=""
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				CommandLine=""
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGORelease|Win32"
+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+			IntermediateDirectory="$(PlatformName)\PGIRelease\pythoncore"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			BuildLogFile="$(OutDir)\BuildLog.htm"
+			ExcludeBuckets="7"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions="/Zm200 "
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				WholeProgramOptimization="true"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;USE_DL_EXPORT;_CRT_SECURE_NO_DEPRECATE"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"
+				AdditionalIncludeDirectories="..\Include"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				CommandLine="copy $(PlatformName)\python.exe $(IntDir)&#x0D;&#x0A;echo running pybench.py -n 1 -C 1 --with-gc ...&#x0D;&#x0A;$(IntDir)\python.exe ../Tools/pybench/pybench.py -n 1 -C 1 --with-gc&#x0D;&#x0A;"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\python25.dll"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				IgnoreDefaultLibraryNames="libc"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				SubSystem="2"
+				LinkTimeCodeGeneration="3"
+				ProfileGuidedDatabase="$(IntDir)\$(TargetName).pgd"
+				BaseAddress="0x1e000000"
+				ImportLibrary=""
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGORelease|x64"
+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\pythoncore"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			BuildLogFile="$(OutDir)\BuildLog.htm"
+			ExcludeBuckets="7"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions="/Zm200 "
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				WholeProgramOptimization="true"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;USE_DL_EXPORT;_CRT_SECURE_NO_DEPRECATE"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"
+				AdditionalIncludeDirectories="..\Include"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				CommandLine="copy $(PlatformName)\python.exe $(IntDir)&#x0D;&#x0A;echo running pybench.py -n 1 -C 1 --with-gc ...&#x0D;&#x0A;$(IntDir)\python.exe ../Tools/pybench/pybench.py -n 1 -C 1 --with-gc&#x0D;&#x0A;"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\python25.dll"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				IgnoreDefaultLibraryNames="libc"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				SubSystem="2"
+				LinkTimeCodeGeneration="3"
+				ProfileGuidedDatabase="$(IntDir)\$(TargetName).pgd"
+				BaseAddress="0x1e000000"
+				ImportLibrary=""
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="zlib"
+			>
+			<File
+				RelativePath="..\Modules\zlib\adler32.c"
+				>
+			</File>
+			<File
+				RelativePath="..\Modules\zlib\compress.c"
+				>
+			</File>
+			<File
+				RelativePath="..\Modules\zlib\crc32.c"
+				>
+			</File>
+			<File
+				RelativePath="..\Modules\zlib\deflate.c"
+				>
+			</File>
+			<File
+				RelativePath="..\Modules\zlib\gzio.c"
+				>
+			</File>
+			<File
+				RelativePath="..\Modules\zlib\infback.c"
+				>
+			</File>
+			<File
+				RelativePath="..\Modules\zlib\inffast.c"
+				>
+			</File>
+			<File
+				RelativePath="..\Modules\zlib\inflate.c"
+				>
+			</File>
+			<File
+				RelativePath="..\Modules\zlib\inftrees.c"
+				>
+			</File>
+			<File
+				RelativePath="..\Modules\zlib\trees.c"
+				>
+			</File>
+			<File
+				RelativePath="..\Modules\zlib\uncompr.c"
+				>
+			</File>
+			<File
+				RelativePath="..\Modules\zlibmodule.c"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories="..\Modules\zlib"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories="..\Modules\zlib"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories="..\Modules\zlib"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories="..\Modules\zlib"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="PGIRelease|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories="..\Modules\zlib"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="PGIRelease|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories="..\Modules\zlib"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="PGORelease|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories="..\Modules\zlib"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="PGORelease|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories="..\Modules\zlib"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\Modules\zlib\zutil.c"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="include files"
+			>
+			<File
+				RelativePath="..\Include\abstract.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\asdl.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\ast.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\bitset.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\boolobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\bufferobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\cellobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\ceval.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\classobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\cobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\code.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\codecs.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\compile.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\complexobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\cStringIO.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\datetime.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\descrobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\dictobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\enumobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\errcode.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\eval.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\fileobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\floatobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\frameobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\funcobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\genobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\graminit.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\grammar.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\import.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\intobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\intrcheck.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\iterobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\listobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\longintrepr.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\longobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\marshal.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\metagrammar.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\methodobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\modsupport.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\moduleobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\node.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\object.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\objimpl.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\opcode.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\osdefs.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\parsetok.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\patchlevel.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\pgen.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\pgenheaders.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\py_curses.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\pyarena.h"
+				>
+			</File>
+			<File
+				RelativePath="..\PC\pyconfig.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\pydebug.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\pyerrors.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\pyexpat.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\pyfpe.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\pygetopt.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\pymactoolbox.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\pymem.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\pyport.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\pystate.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\pystrtod.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\Python-ast.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\Python.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\pythonrun.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\pythread.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\rangeobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\setobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\sliceobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\stringobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\structmember.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\structseq.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\symtable.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\sysmodule.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\timefuncs.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\token.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\traceback.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\tupleobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\ucnhash.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\unicodeobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Include\weakrefobject.h"
+				>
+			</File>
+		</Filter>
+		<File
+			RelativePath="..\Modules\_bisectmodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\cjkcodecs\_codecs_cn.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\cjkcodecs\_codecs_hk.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\cjkcodecs\_codecs_iso2022.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\cjkcodecs\_codecs_jp.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\cjkcodecs\_codecs_kr.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\cjkcodecs\_codecs_tw.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\_codecsmodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\_csv.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\_functoolsmodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\_heapqmodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\_hotshot.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\_localemodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\_lsprof.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\_randommodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\_sre.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\_struct.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Pc\_subprocess.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\_typesmodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\_weakref.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Pc\_winreg.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\abstract.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Parser\acceler.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\arraymodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\asdl.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\ast.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\audioop.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\binascii.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Parser\bitset.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\bltinmodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\boolobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\bufferobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\cellobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\ceval.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\classobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\cmathmodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\cobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\codecs.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\codeobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\collectionsmodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\compile.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\complexobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\PC\config.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\cPickle.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\cStringIO.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\datetimemodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\descrobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\dictobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\PC\dl_nt.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\dynload_win.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\enumobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\errnomodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\errors.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\exceptions.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\fileobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Parser\firstsets.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\floatobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\frameobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\frozen.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\funcobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\future.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\gcmodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\genobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\getargs.c"
+			>
+		</File>
+		<File
+			RelativePath=".\getbuildinfo2.c"
+			>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					ForcedIncludeFiles="getbuildinfo2.h"
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|x64"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					ForcedIncludeFiles="getbuildinfo2.h"
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					ForcedIncludeFiles="getbuildinfo2.h"
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Debug|x64"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					ForcedIncludeFiles="getbuildinfo2.h"
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="PGIRelease|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					ForcedIncludeFiles="getbuildinfo2.h"
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="PGIRelease|x64"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					ForcedIncludeFiles="getbuildinfo2.h"
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="PGORelease|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					ForcedIncludeFiles="getbuildinfo2.h"
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="PGORelease|x64"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					ForcedIncludeFiles="getbuildinfo2.h"
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\Python\getcompiler.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\getcopyright.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\getmtime.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\getopt.c"
+			>
+		</File>
+		<File
+			RelativePath="..\PC\getpathp.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\getplatform.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\getversion.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\graminit.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Parser\grammar.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Parser\grammar1.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\imageop.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\import.c"
+			>
+		</File>
+		<File
+			RelativePath="..\PC\import_nt.c"
+			>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories="..\Python"
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|x64"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories="..\Python"
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories="..\Python"
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Debug|x64"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories="..\Python"
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="PGIRelease|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories="..\Python"
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="PGIRelease|x64"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories="..\Python"
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="PGORelease|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories="..\Python"
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="PGORelease|x64"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories="..\Python"
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\Python\importdl.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\intobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\iterobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\itertoolsmodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Parser\listnode.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\listobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\longobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\main.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\marshal.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\mathmodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\md5.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\md5module.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Parser\metagrammar.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\methodobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\mmapmodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\modsupport.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\moduleobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\PC\msvcrtmodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\cjkcodecs\multibytecodec.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Parser\myreadline.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\mysnprintf.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\mystrtoul.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Parser\node.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\object.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\obmalloc.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\operator.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Parser\parser.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\parsermodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Parser\parsetok.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\posixmodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\pyarena.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\pyfpe.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\pystate.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\pystrtod.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\Python-ast.c"
+			>
+		</File>
+		<File
+			RelativePath="..\PC\python_nt.rc"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\pythonrun.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\rangeobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\rgbimgmodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\rotatingtree.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\setobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\sha256module.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\sha512module.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\sha512module.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\shamodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\signalmodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\signalmodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\sliceobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\stringobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\stropmodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\structmember.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\structseq.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\symtable.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\symtablemodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\sysmodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\thread.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\threadmodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\timemodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Parser\tokenizer.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\traceback.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\tupleobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\typeobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\unicodectype.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\unicodeobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\weakrefobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\xxsubtype.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\yuvconvert.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\zipimport.c"
+			>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Added: vendor/Python/current/PCbuild8/pythoncore_pgo.vcproj
===================================================================
--- vendor/Python/current/PCbuild8/pythoncore_pgo.vcproj	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild8/pythoncore_pgo.vcproj	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,781 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8,00"
+	Name="pythoncore_pgo"
+	ProjectGUID="{8B59C1FF-2439-4BE9-9F24-84D4982D28D4}"
+	RootNamespace="pythoncore_pgo"
+	Keyword="Win32Proj"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(ProjectName)"
+			IntermediateDirectory=".\x86-temp-release\$(ProjectName)"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions="/Zm200 "
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				WholeProgramOptimization="true"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;USE_DL_EXPORT;_CRT_SECURE_NO_DEPRECATE"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"
+				AdditionalIncludeDirectories="..\Include"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				Description="Generate buildinfo &amp; profile guided optimizations (please be patient)"
+				CommandLine="make_buildinfo.exe $(ConfigurationName)&#x0D;&#x0A;link @$(ProjectName)_link.txt&#x0D;&#x0A;$(OutDir)\python ../Tools/pybench/pybench.py -n 1&#x0D;&#x0A;"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="getbuildinfo.o"
+				OutputFile="$(OutDir)/python25.dll"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				IgnoreDefaultLibraryNames="libc"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile="$(OutDir)/python25.pdb"
+				SubSystem="2"
+				LinkTimeCodeGeneration="3"
+				BaseAddress="0x1e000000"
+				ImportLibrary="$(OutDir)/python25.lib"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="zlib"
+			>
+			<File
+				RelativePath="..\Modules\zlib\adler32.c"
+				>
+			</File>
+			<File
+				RelativePath="..\Modules\zlib\compress.c"
+				>
+			</File>
+			<File
+				RelativePath="..\Modules\zlib\crc32.c"
+				>
+			</File>
+			<File
+				RelativePath="..\Modules\zlib\deflate.c"
+				>
+			</File>
+			<File
+				RelativePath="..\Modules\zlib\gzio.c"
+				>
+			</File>
+			<File
+				RelativePath="..\Modules\zlib\infback.c"
+				>
+			</File>
+			<File
+				RelativePath="..\Modules\zlib\inffast.c"
+				>
+			</File>
+			<File
+				RelativePath="..\Modules\zlib\inflate.c"
+				>
+			</File>
+			<File
+				RelativePath="..\Modules\zlib\inftrees.c"
+				>
+			</File>
+			<File
+				RelativePath="..\Modules\zlib\trees.c"
+				>
+			</File>
+			<File
+				RelativePath="..\Modules\zlib\uncompr.c"
+				>
+			</File>
+			<File
+				RelativePath="..\Modules\zlibmodule.c"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories="..\Modules\zlib"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\Modules\zlib\zutil.c"
+				>
+			</File>
+		</Filter>
+		<File
+			RelativePath="..\Modules\_bisectmodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\cjkcodecs\_codecs_cn.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\cjkcodecs\_codecs_hk.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\cjkcodecs\_codecs_iso2022.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\cjkcodecs\_codecs_jp.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\cjkcodecs\_codecs_kr.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\cjkcodecs\_codecs_tw.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\_codecsmodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\_csv.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\_functoolsmodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\_heapqmodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\_hotshot.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\_localemodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\_lsprof.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\_randommodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\_sre.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\_struct.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Pc\_subprocess.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\_weakref.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Pc\_winreg.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\abstract.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Parser\acceler.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\arraymodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\asdl.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\ast.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\audioop.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\binascii.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Parser\bitset.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\bltinmodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\boolobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\bufferobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\cellobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\ceval.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\classobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\cmathmodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\cobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\codecs.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\codeobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\collectionsmodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\compile.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\complexobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\PC\config.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\cPickle.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\cStringIO.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\datetimemodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\descrobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\dictobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\PC\dl_nt.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\dynload_win.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\enumobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\errnomodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\errors.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\exceptions.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\fileobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Parser\firstsets.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\floatobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\frameobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\frozen.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\funcobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\future.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\gcmodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\genobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\getargs.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\getcompiler.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\getcopyright.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\getmtime.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\getopt.c"
+			>
+		</File>
+		<File
+			RelativePath="..\PC\getpathp.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\getplatform.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\getversion.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\graminit.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Parser\grammar.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Parser\grammar1.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\imageop.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\import.c"
+			>
+		</File>
+		<File
+			RelativePath="..\PC\import_nt.c"
+			>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					AdditionalIncludeDirectories="..\Python"
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\Python\importdl.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\intobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\iterobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\itertoolsmodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Parser\listnode.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\listobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\longobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\main.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\marshal.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\mathmodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\md5.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\md5module.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Parser\metagrammar.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\methodobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\mmapmodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\modsupport.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\moduleobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\PC\msvcrtmodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\cjkcodecs\multibytecodec.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Parser\myreadline.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\mysnprintf.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\mystrtoul.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Parser\node.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\object.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\obmalloc.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\operator.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Parser\parser.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\parsermodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Parser\parsetok.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\posixmodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\pyarena.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\pyfpe.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\pystate.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\pystrtod.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\Python-ast.c"
+			>
+		</File>
+		<File
+			RelativePath="..\PCbuild8\python.exe"
+			>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCustomBuildTool"
+					CommandLine="xcopy $(InputFileName)* $(OutDir) /F /I /Y&#x0D;&#x0A;"
+					Outputs="$(OutDir)\$(InputFileName)"
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\PC\python_nt.rc"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\pythonrun.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\rangeobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\rgbimgmodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\rotatingtree.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\setobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\sha256module.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\sha512module.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\sha512module.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\shamodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\signalmodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\signalmodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\sliceobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\stringobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\stropmodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\structmember.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\structseq.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\symtable.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\symtablemodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\sysmodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\thread.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\threadmodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\timemodule.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Parser\tokenizer.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Python\traceback.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\tupleobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\typeobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\unicodectype.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\unicodeobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Objects\weakrefobject.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\xxsubtype.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\yuvconvert.c"
+			>
+		</File>
+		<File
+			RelativePath="..\Modules\zipimport.c"
+			>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Added: vendor/Python/current/PCbuild8/pythoncore_pgo_link.txt
===================================================================
--- vendor/Python/current/PCbuild8/pythoncore_pgo_link.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild8/pythoncore_pgo_link.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,311 @@
+/OUT:".\pythoncore_pgo/python25.dll" /INCREMENTAL:NO /DLL /MANIFEST /MANIFESTFILE:".\x86-temp-release\pythoncore_pgo\python25.dll.intermediate.manifest" /NODEFAULTLIB:"libc" /DEBUG /PDB:".\pythoncore_pgo/python25.pdb" /SUBSYSTEM:WINDOWS /LTCG:PGINSTRUMENT /PGD:".\pythoncore_pgo\python25.pgd" /BASE:"0x1e000000" /IMPLIB:"pythoncore_pgo/python25.lib" /MACHINE:X86 getbuildinfo.o kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib
+
+".\x86-temp-release\pythoncore_pgo\adler32.obj"
+
+".\x86-temp-release\pythoncore_pgo\compress.obj"
+
+".\x86-temp-release\pythoncore_pgo\crc32.obj"
+
+".\x86-temp-release\pythoncore_pgo\deflate.obj"
+
+".\x86-temp-release\pythoncore_pgo\gzio.obj"
+
+".\x86-temp-release\pythoncore_pgo\infback.obj"
+
+".\x86-temp-release\pythoncore_pgo\inffast.obj"
+
+".\x86-temp-release\pythoncore_pgo\inflate.obj"
+
+".\x86-temp-release\pythoncore_pgo\inftrees.obj"
+
+".\x86-temp-release\pythoncore_pgo\trees.obj"
+
+".\x86-temp-release\pythoncore_pgo\uncompr.obj"
+
+".\x86-temp-release\pythoncore_pgo\zlibmodule.obj"
+
+".\x86-temp-release\pythoncore_pgo\zutil.obj"
+
+".\x86-temp-release\pythoncore_pgo\_bisectmodule.obj"
+
+".\x86-temp-release\pythoncore_pgo\_codecs_cn.obj"
+
+".\x86-temp-release\pythoncore_pgo\_codecs_hk.obj"
+
+".\x86-temp-release\pythoncore_pgo\_codecs_iso2022.obj"
+
+".\x86-temp-release\pythoncore_pgo\_codecs_jp.obj"
+
+".\x86-temp-release\pythoncore_pgo\_codecs_kr.obj"
+
+".\x86-temp-release\pythoncore_pgo\_codecs_tw.obj"
+
+".\x86-temp-release\pythoncore_pgo\_codecsmodule.obj"
+
+".\x86-temp-release\pythoncore_pgo\_csv.obj"
+
+".\x86-temp-release\pythoncore_pgo\_functoolsmodule.obj"
+
+".\x86-temp-release\pythoncore_pgo\_heapqmodule.obj"
+
+".\x86-temp-release\pythoncore_pgo\_hotshot.obj"
+
+".\x86-temp-release\pythoncore_pgo\_localemodule.obj"
+
+".\x86-temp-release\pythoncore_pgo\_lsprof.obj"
+
+".\x86-temp-release\pythoncore_pgo\_randommodule.obj"
+
+".\x86-temp-release\pythoncore_pgo\_sre.obj"
+
+".\x86-temp-release\pythoncore_pgo\_struct.obj"
+
+".\x86-temp-release\pythoncore_pgo\_subprocess.obj"
+
+".\x86-temp-release\pythoncore_pgo\_weakref.obj"
+
+".\x86-temp-release\pythoncore_pgo\_winreg.obj"
+
+".\x86-temp-release\pythoncore_pgo\abstract.obj"
+
+".\x86-temp-release\pythoncore_pgo\acceler.obj"
+
+".\x86-temp-release\pythoncore_pgo\arraymodule.obj"
+
+".\x86-temp-release\pythoncore_pgo\asdl.obj"
+
+".\x86-temp-release\pythoncore_pgo\ast.obj"
+
+".\x86-temp-release\pythoncore_pgo\audioop.obj"
+
+".\x86-temp-release\pythoncore_pgo\binascii.obj"
+
+".\x86-temp-release\pythoncore_pgo\bitset.obj"
+
+".\x86-temp-release\pythoncore_pgo\bltinmodule.obj"
+
+".\x86-temp-release\pythoncore_pgo\boolobject.obj"
+
+".\x86-temp-release\pythoncore_pgo\bufferobject.obj"
+
+".\x86-temp-release\pythoncore_pgo\cellobject.obj"
+
+".\x86-temp-release\pythoncore_pgo\ceval.obj"
+
+".\x86-temp-release\pythoncore_pgo\classobject.obj"
+
+".\x86-temp-release\pythoncore_pgo\cmathmodule.obj"
+
+".\x86-temp-release\pythoncore_pgo\cobject.obj"
+
+".\x86-temp-release\pythoncore_pgo\codecs.obj"
+
+".\x86-temp-release\pythoncore_pgo\codeobject.obj"
+
+".\x86-temp-release\pythoncore_pgo\collectionsmodule.obj"
+
+".\x86-temp-release\pythoncore_pgo\compile.obj"
+
+".\x86-temp-release\pythoncore_pgo\complexobject.obj"
+
+".\x86-temp-release\pythoncore_pgo\config.obj"
+
+".\x86-temp-release\pythoncore_pgo\cPickle.obj"
+
+".\x86-temp-release\pythoncore_pgo\cStringIO.obj"
+
+".\x86-temp-release\pythoncore_pgo\datetimemodule.obj"
+
+".\x86-temp-release\pythoncore_pgo\descrobject.obj"
+
+".\x86-temp-release\pythoncore_pgo\dictobject.obj"
+
+".\x86-temp-release\pythoncore_pgo\dl_nt.obj"
+
+".\x86-temp-release\pythoncore_pgo\dynload_win.obj"
+
+".\x86-temp-release\pythoncore_pgo\enumobject.obj"
+
+".\x86-temp-release\pythoncore_pgo\errnomodule.obj"
+
+".\x86-temp-release\pythoncore_pgo\errors.obj"
+
+".\x86-temp-release\pythoncore_pgo\exceptions.obj"
+
+".\x86-temp-release\pythoncore_pgo\fileobject.obj"
+
+".\x86-temp-release\pythoncore_pgo\firstsets.obj"
+
+".\x86-temp-release\pythoncore_pgo\floatobject.obj"
+
+".\x86-temp-release\pythoncore_pgo\frameobject.obj"
+
+".\x86-temp-release\pythoncore_pgo\frozen.obj"
+
+".\x86-temp-release\pythoncore_pgo\funcobject.obj"
+
+".\x86-temp-release\pythoncore_pgo\future.obj"
+
+".\x86-temp-release\pythoncore_pgo\gcmodule.obj"
+
+".\x86-temp-release\pythoncore_pgo\genobject.obj"
+
+".\x86-temp-release\pythoncore_pgo\getargs.obj"
+
+".\x86-temp-release\pythoncore_pgo\getcompiler.obj"
+
+".\x86-temp-release\pythoncore_pgo\getcopyright.obj"
+
+".\x86-temp-release\pythoncore_pgo\getmtime.obj"
+
+".\x86-temp-release\pythoncore_pgo\getopt.obj"
+
+".\x86-temp-release\pythoncore_pgo\getpathp.obj"
+
+".\x86-temp-release\pythoncore_pgo\getplatform.obj"
+
+".\x86-temp-release\pythoncore_pgo\getversion.obj"
+
+".\x86-temp-release\pythoncore_pgo\graminit.obj"
+
+".\x86-temp-release\pythoncore_pgo\grammar.obj"
+
+".\x86-temp-release\pythoncore_pgo\grammar1.obj"
+
+".\x86-temp-release\pythoncore_pgo\imageop.obj"
+
+".\x86-temp-release\pythoncore_pgo\import.obj"
+
+".\x86-temp-release\pythoncore_pgo\import_nt.obj"
+
+".\x86-temp-release\pythoncore_pgo\importdl.obj"
+
+".\x86-temp-release\pythoncore_pgo\intobject.obj"
+
+".\x86-temp-release\pythoncore_pgo\iterobject.obj"
+
+".\x86-temp-release\pythoncore_pgo\itertoolsmodule.obj"
+
+".\x86-temp-release\pythoncore_pgo\listnode.obj"
+
+".\x86-temp-release\pythoncore_pgo\listobject.obj"
+
+".\x86-temp-release\pythoncore_pgo\longobject.obj"
+
+".\x86-temp-release\pythoncore_pgo\main.obj"
+
+".\x86-temp-release\pythoncore_pgo\marshal.obj"
+
+".\x86-temp-release\pythoncore_pgo\mathmodule.obj"
+
+".\x86-temp-release\pythoncore_pgo\md5.obj"
+
+".\x86-temp-release\pythoncore_pgo\md5module.obj"
+
+".\x86-temp-release\pythoncore_pgo\metagrammar.obj"
+
+".\x86-temp-release\pythoncore_pgo\methodobject.obj"
+
+".\x86-temp-release\pythoncore_pgo\mmapmodule.obj"
+
+".\x86-temp-release\pythoncore_pgo\modsupport.obj"
+
+".\x86-temp-release\pythoncore_pgo\moduleobject.obj"
+
+".\x86-temp-release\pythoncore_pgo\msvcrtmodule.obj"
+
+".\x86-temp-release\pythoncore_pgo\multibytecodec.obj"
+
+".\x86-temp-release\pythoncore_pgo\myreadline.obj"
+
+".\x86-temp-release\pythoncore_pgo\mysnprintf.obj"
+
+".\x86-temp-release\pythoncore_pgo\mystrtoul.obj"
+
+".\x86-temp-release\pythoncore_pgo\node.obj"
+
+".\x86-temp-release\pythoncore_pgo\object.obj"
+
+".\x86-temp-release\pythoncore_pgo\obmalloc.obj"
+
+".\x86-temp-release\pythoncore_pgo\operator.obj"
+
+".\x86-temp-release\pythoncore_pgo\parser.obj"
+
+".\x86-temp-release\pythoncore_pgo\parsermodule.obj"
+
+".\x86-temp-release\pythoncore_pgo\parsetok.obj"
+
+".\x86-temp-release\pythoncore_pgo\posixmodule.obj"
+
+".\x86-temp-release\pythoncore_pgo\pyarena.obj"
+
+".\x86-temp-release\pythoncore_pgo\pyfpe.obj"
+
+".\x86-temp-release\pythoncore_pgo\pystate.obj"
+
+".\x86-temp-release\pythoncore_pgo\pystrtod.obj"
+
+".\x86-temp-release\pythoncore_pgo\Python-ast.obj"
+
+".\x86-temp-release\pythoncore_pgo\python_nt.res"
+
+".\x86-temp-release\pythoncore_pgo\pythonrun.obj"
+
+".\x86-temp-release\pythoncore_pgo\rangeobject.obj"
+
+".\x86-temp-release\pythoncore_pgo\rgbimgmodule.obj"
+
+".\x86-temp-release\pythoncore_pgo\rotatingtree.obj"
+
+".\x86-temp-release\pythoncore_pgo\setobject.obj"
+
+".\x86-temp-release\pythoncore_pgo\sha256module.obj"
+
+".\x86-temp-release\pythoncore_pgo\sha512module.obj"
+
+".\x86-temp-release\pythoncore_pgo\shamodule.obj"
+
+".\x86-temp-release\pythoncore_pgo\signalmodule.obj"
+
+".\x86-temp-release\pythoncore_pgo\sliceobject.obj"
+
+".\x86-temp-release\pythoncore_pgo\stringobject.obj"
+
+".\x86-temp-release\pythoncore_pgo\stropmodule.obj"
+
+".\x86-temp-release\pythoncore_pgo\structmember.obj"
+
+".\x86-temp-release\pythoncore_pgo\structseq.obj"
+
+".\x86-temp-release\pythoncore_pgo\symtable.obj"
+
+".\x86-temp-release\pythoncore_pgo\symtablemodule.obj"
+
+".\x86-temp-release\pythoncore_pgo\sysmodule.obj"
+
+".\x86-temp-release\pythoncore_pgo\thread.obj"
+
+".\x86-temp-release\pythoncore_pgo\threadmodule.obj"
+
+".\x86-temp-release\pythoncore_pgo\timemodule.obj"
+
+".\x86-temp-release\pythoncore_pgo\tokenizer.obj"
+
+".\x86-temp-release\pythoncore_pgo\traceback.obj"
+
+".\x86-temp-release\pythoncore_pgo\tupleobject.obj"
+
+".\x86-temp-release\pythoncore_pgo\typeobject.obj"
+
+".\x86-temp-release\pythoncore_pgo\unicodectype.obj"
+
+".\x86-temp-release\pythoncore_pgo\unicodeobject.obj"
+
+".\x86-temp-release\pythoncore_pgo\weakrefobject.obj"
+
+".\x86-temp-release\pythoncore_pgo\xxsubtype.obj"
+
+".\x86-temp-release\pythoncore_pgo\yuvconvert.obj"
+
+".\x86-temp-release\pythoncore_pgo\zipimport.obj"

Added: vendor/Python/current/PCbuild8/pythonw.vcproj
===================================================================
--- vendor/Python/current/PCbuild8/pythonw.vcproj	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild8/pythonw.vcproj	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,383 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8,00"
+	Name="pythonw"
+	ProjectGUID="{F4229CC3-873C-49AE-9729-DD308ED4CD4A}"
+	RootNamespace="pythonw"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(PlatformName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\pythonw"
+			ConfigurationType="1"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="_DEBUG"
+				Culture="1033"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\pythonw_d.exe"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				AdditionalLibraryDirectories="$(OutDir)"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				SubSystem="2"
+				StackReserveSize="2000000"
+				BaseAddress="0x1d000000"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			OutputDirectory="$(PlatformName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\pythonw"
+			ConfigurationType="1"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="_DEBUG"
+				Culture="1033"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\pythonw_d.exe"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				AdditionalLibraryDirectories="$(OutDir)"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				SubSystem="2"
+				StackReserveSize="2000000"
+				BaseAddress="0x1d000000"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(PlatformName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\pythonw"
+			ConfigurationType="1"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\pythonw.exe"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				AdditionalLibraryDirectories="$(OutDir)"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				SubSystem="2"
+				StackReserveSize="2000000"
+				BaseAddress="0x1d000000"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			OutputDirectory="$(PlatformName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\pythonw"
+			ConfigurationType="1"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\pythonw.exe"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				AdditionalLibraryDirectories="$(OutDir)"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				SubSystem="2"
+				StackReserveSize="2000000"
+				BaseAddress="0x1d000000"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath="..\PC\python_exe.rc"
+			>
+		</File>
+		<File
+			RelativePath="..\PC\WinMain.c"
+			>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Added: vendor/Python/current/PCbuild8/readme.txt
===================================================================
--- vendor/Python/current/PCbuild8/readme.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild8/readme.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,441 @@
+Building Python using VC++ 8.0
+-------------------------------------
+This directory is used to build Python for Win32 platforms, e.g. Windows
+95, 98 and NT.  It requires Microsoft Visual C++ 8.0
+(a.k.a. Visual Studio 2005).
+(For other Windows platforms and compilers, see ../PC/readme.txt.)
+
+All you need to do is open the workspace "pcbuild.sln" in VisualStudio 2005,
+select the platform, select the Debug or Release setting
+(using "Solution Configuration" from the "Standard" toolbar"), and build the
+solution.
+
+The proper order to build subprojects:
+
+1) pythoncore (this builds the main Python DLL and library files,
+               python25.{dll, lib} in Release mode)
+              NOTE:  in previous releases, this subproject was
+              named after the release number, e.g. python20.
+
+2) python (this builds the main Python executable,
+           python.exe in Release mode)
+
+3) the other subprojects, as desired or needed (note:  you probably don't
+   want to build most of the other subprojects, unless you're building an
+   entire Python distribution from scratch, or specifically making changes
+   to the subsystems they implement, or are running a Python core buildbot
+   test slave; see SUBPROJECTS below)
+
+Binary files go into PCBuild8\Win32 or \x64 directories and don't
+interfere with each other.
+
+When using the Debug setting, the output files have a _d added to
+their name:  python25_d.dll, python_d.exe, parser_d.pyd, and so on.
+
+Profile guided Optimization:
+
+There are two special configurations for the pythoncore project and
+the solution.  These are PGIRelease and PGORelease.  They are for
+creating profile-guided optimized versions of python.dll.
+The former creates the instrumented binaries, and the latter
+runs python.exe with the instrumented python.dll on the performance
+testsuite, and creates a new, optimized, python.dll in
+PCBuild8\Win32\PGORelease, or in the x64 folder.  Note that although
+we can cross-compile x64 binaries on a 32 bit machine, we cannot
+create the PGO binaries, since they require actually running the code.
+
+To create the PGO binaries, first build the Release configuration, then
+build the PGIRelease configuration and finally build the PGORelease
+configuration.  The last stage can take a while to complete as the
+testsuite runs.
+Note that the profile runs are stored in files such as
+Win32\PGIRelease\pythoncore\python25!1.pgc which may
+need to be cleared for fresh builds.
+
+SUBPROJECTS
+-----------
+These subprojects should build out of the box.  Subprojects other than the
+main ones (pythoncore, python, pythonw) generally build a DLL (renamed to
+.pyd) from a specific module so that users don't have to load the code
+supporting that module unless they import the module.
+
+pythoncore
+    .dll and .lib
+python
+    .exe
+pythonw
+    pythonw.exe, a variant of python.exe that doesn't pop up a DOS box
+_socket
+    socketmodule.c
+_testcapi
+    tests of the Python C API, run via Lib/test/test_capi.py, and
+    implemented by module Modules/_testcapimodule.c
+pyexpat
+    Python wrapper for accelerated XML parsing, which incorporates stable
+    code from the Expat project:  http://sourceforge.net/projects/expat/
+select
+    selectmodule.c
+unicodedata
+    large tables of Unicode data
+winsound
+    play sounds (typically .wav files) under Windows
+
+The following subprojects will generally NOT build out of the box.  They
+wrap code Python doesn't control, and you'll need to download the base
+packages first and unpack them into siblings of PCbuilds's parent
+directory; for example, if your PCbuild is  .......\dist\src\PCbuild\,
+unpack into new subdirectories of dist\.
+
+_tkinter
+    Python wrapper for the Tk windowing system.  Requires building
+    Tcl/Tk first.  Following are instructions for Tcl/Tk 8.4.12.
+
+    Get source
+    ----------
+    In the dist directory, run
+    svn export http://svn.python.org/projects/external/tcl8.4.12
+    svn export http://svn.python.org/projects/external/tk8.4.12
+    svn export http://svn.python.org/projects/external/tix-8.4.0
+
+    Build Tcl first (done here w/ MSVC 7.1 on Windows XP)
+    ---------------
+    Use "Start -> All Programs -> Microsoft Visual Studio .NET 2003
+         -> Visual Studio .NET Tools -> Visual Studio .NET 2003 Command Prompt"
+    to get a shell window with the correct environment settings
+    cd dist\tcl8.4.12\win
+    nmake -f makefile.vc
+    nmake -f makefile.vc INSTALLDIR=..\..\tcltk install
+
+    XXX Should we compile with OPTS=threads?
+
+    Optional:  run tests, via
+        nmake -f makefile.vc test
+
+        On WinXP Pro, wholly up to date as of 30-Aug-2004:
+        all.tcl:        Total   10678   Passed  9969    Skipped 709     Failed  0
+        Sourced 129 Test Files.
+
+    Build Tk
+    --------
+    cd dist\tk8.4.12\win
+    nmake -f makefile.vc TCLDIR=..\..\tcl8.4.12
+    nmake -f makefile.vc TCLDIR=..\..\tcl8.4.12 INSTALLDIR=..\..\tcltk install
+
+    XXX Should we compile with OPTS=threads?
+
+    XXX Our installer copies a lot of stuff out of the Tcl/Tk install
+    XXX directory.  Is all of that really needed for Python use of Tcl/Tk?
+
+    Optional:  run tests, via
+        nmake -f makefile.vc TCLDIR=..\..\tcl8.4.12 test
+
+        On WinXP Pro, wholly up to date as of 30-Aug-2004:
+        all.tcl:        Total   8420    Passed  6826    Skipped 1581    Failed  13
+        Sourced 91 Test Files.
+        Files with failing tests: canvImg.test scrollbar.test textWind.test winWm.test
+
+   Built Tix
+   ---------
+   cd dist\tix-8.4.0\win
+   nmake -f python.mak
+   nmake -f python.mak install
+
+bz2
+    Python wrapper for the libbz2 compression library.  Homepage
+        http://sources.redhat.com/bzip2/
+    Download the source from the python.org copy into the dist
+    directory:
+
+    svn export http://svn.python.org/projects/external/bzip2-1.0.3
+
+    A custom pre-link step in the bz2 project settings should manage to
+    build bzip2-1.0.3\libbz2.lib by magic before bz2.pyd (or bz2_d.pyd) is
+    linked in PCbuild\.
+    However, the bz2 project is not smart enough to remove anything under
+    bzip2-1.0.3\ when you do a clean, so if you want to rebuild bzip2.lib
+    you need to clean up bzip2-1.0.3\ by hand.
+
+    The build step shouldn't yield any warnings or errors, and should end
+    by displaying 6 blocks each terminated with
+        FC: no differences encountered
+
+    All of this managed to build bzip2-1.0.3\libbz2.lib, which the Python
+    project links in.
+
+
+_bsddb
+    To use the version of bsddb that Python is built with by default, invoke
+    (in the dist directory)
+
+     svn export http://svn.python.org/projects/external/db-4.4.20
+
+
+    Then open a VS.NET 2003 shell, and invoke:
+
+       devenv db-4.4.20\build_win32\Berkeley_DB.sln /build Release /project db_static
+
+    and do that a second time for a Debug build too:
+
+       devenv db-4.4.20\build_win32\Berkeley_DB.sln /build Debug /project db_static
+
+    Alternatively, if you want to start with the original sources,
+    go to Sleepycat's download page:
+        http://www.sleepycat.com/downloads/releasehistorybdb.html
+
+    and download version 4.4.20.
+
+    With or without strong cryptography? You can choose either with or
+    without strong cryptography, as per the instructions below.  By
+    default, Python is built and distributed WITHOUT strong crypto.
+
+    Unpack the sources; if you downloaded the non-crypto version, rename
+    the directory from db-4.4.20.NC to db-4.4.20.
+
+    Now apply any patches that apply to your version.
+
+    Open
+        dist\db-4.4.20\docs\index.html
+
+    and follow the "Windows->Building Berkeley DB with Visual C++ .NET"
+    instructions for building the Sleepycat
+    software.  Note that Berkeley_DB.dsw is in the build_win32 subdirectory.
+    Build the "db_static" project, for "Release" mode.
+
+    To run extensive tests, pass "-u bsddb" to regrtest.py.  test_bsddb3.py
+    is then enabled.  Running in verbose mode may be helpful.
+
+    XXX The test_bsddb3 tests don't always pass, on Windows (according to
+    XXX me) or on Linux (according to Barry).  (I had much better luck
+    XXX on Win2K than on Win98SE.)  The common failure mode across platforms
+    XXX is
+    XXX     DBAgainError: (11, 'Resource temporarily unavailable -- unable
+    XXX                         to join the environment')
+    XXX
+    XXX and it appears timing-dependent.  On Win2K I also saw this once:
+    XXX
+    XXX test02_SimpleLocks (bsddb.test.test_thread.HashSimpleThreaded) ...
+    XXX Exception in thread reader 1:
+    XXX Traceback (most recent call last):
+    XXX File "C:\Code\python\lib\threading.py", line 411, in __bootstrap
+    XXX    self.run()
+    XXX File "C:\Code\python\lib\threading.py", line 399, in run
+    XXX    apply(self.__target, self.__args, self.__kwargs)
+    XXX File "C:\Code\python\lib\bsddb\test\test_thread.py", line 268, in
+    XXX                  readerThread
+    XXX    rec = c.next()
+    XXX DBLockDeadlockError: (-30996, 'DB_LOCK_DEADLOCK: Locker killed
+    XXX                                to resolve a deadlock')
+    XXX
+    XXX I'm told that DBLockDeadlockError is expected at times.  It
+    XXX doesn't cause a test to fail when it happens (exceptions in
+    XXX threads are invisible to unittest).
+
+    Building for Win64:
+    - open a VS.NET 2003 command prompt
+    - run the SDK setenv.cmd script, passing /RETAIL and the target
+      architecture (/SRV64 for Itanium, /X64 for AMD64)
+    - build BerkeleyDB with the solution configuration matching the
+      target ("Release IA64" for Itanium, "Release AMD64" for AMD64), e.g.
+    devenv db-4.4.20\build_win32\Berkeley_DB.sln /build "Release AMD64" /project db_static /useenv
+
+_sqlite3
+    Python wrapper for SQLite library.
+    
+    Get the source code through
+    
+    svn export http://svn.python.org/projects/external/sqlite-source-3.3.4
+    
+    To use the extension module in a Python build tree, copy sqlite3.dll into
+    the PCbuild folder.
+
+_ssl
+    Python wrapper for the secure sockets library.
+
+    Get the source code through
+
+    svn export http://svn.python.org/projects/external/openssl-0.9.8a
+
+    Alternatively, get the latest version from http://www.openssl.org.
+    You can (theoretically) use any version of OpenSSL you like - the
+    build process will automatically select the latest version.
+
+    You must also install ActivePerl from
+        http://www.activestate.com/Products/ActivePerl/
+    as this is used by the OpenSSL build process.  Complain to them <wink>.
+
+    The MSVC project simply invokes PCBuild/build_ssl.py to perform
+    the build.  This Python script locates and builds your OpenSSL
+    installation, then invokes a simple makefile to build the final .pyd.
+
+    build_ssl.py attempts to catch the most common errors (such as not
+    being able to find OpenSSL sources, or not being able to find a Perl
+    that works with OpenSSL) and give a reasonable error message.
+    If you have a problem that doesn't seem to be handled correctly
+    (eg, you know you have ActivePerl but we can't find it), please take
+    a peek at build_ssl.py and suggest patches.  Note that build_ssl.py
+    should be able to be run directly from the command-line.
+
+    build_ssl.py/MSVC isn't clever enough to clean OpenSSL - you must do
+    this by hand.
+
+Building for Itanium
+--------------------
+
+The project files support a ReleaseItanium configuration which creates
+Win64/Itanium binaries. For this to work, you need to install the Platform
+SDK, in particular the 64-bit support. This includes an Itanium compiler
+(future releases of the SDK likely include an AMD64 compiler as well).
+In addition, you need the Visual Studio plugin for external C compilers,
+from http://sf.net/projects/vsextcomp. The plugin will wrap cl.exe, to
+locate the proper target compiler, and convert compiler options
+accordingly. The project files require atleast version 0.8.
+
+Building for AMD64
+------------------
+
+The build process for the ReleaseAMD64 configuration is very similar
+to the Itanium configuration; make sure you use the latest version of
+vsextcomp.
+
+Building Python Using the free MS Toolkit Compiler
+--------------------------------------------------
+
+The build process for Visual C++ can be used almost unchanged with the free MS
+Toolkit Compiler. This provides a way of building Python using freely
+available software.
+
+Requirements
+
+    To build Python, the following tools are required:
+
+    * The Visual C++ Toolkit Compiler
+        from http://msdn.microsoft.com/visualc/vctoolkit2003/
+    * A recent Platform SDK
+        from http://www.microsoft.com/downloads/details.aspx?FamilyID=484269e2-3b89-47e3-8eb7-1f2be6d7123a
+    * The .NET 1.1 SDK
+        from http://www.microsoft.com/downloads/details.aspx?FamilyID=9b3a2ca6-3647-4070-9f41-a333c6b9181d
+
+    [Does anyone have better URLs for the last 2 of these?]
+
+    The toolkit compiler is needed as it is an optimising compiler (the
+    compiler supplied with the .NET SDK is a non-optimising version). The
+    platform SDK is needed to provide the Windows header files and libraries
+    (the Windows 2003 Server SP1 edition, typical install, is known to work -
+    other configurations or versions are probably fine as well). The .NET 1.1
+    SDK is needed because it contains a version of msvcrt.dll which links to
+    the msvcr71.dll CRT. Note that the .NET 2.0 SDK is NOT acceptable, as it
+    references msvcr80.dll.
+
+    All of the above items should be installed as normal.
+
+    If you intend to build the openssl (needed for the _ssl extension) you
+    will need the C runtime sources installed as part of the platform SDK.
+
+    In addition, you will need Nant, available from
+    http://nant.sourceforge.net. The 0.85 release candidate 3 version is known
+    to work. This is the latest released version at the time of writing. Later
+    "nightly build" versions are known NOT to work - it is not clear at
+    present whether future released versions will work.
+
+Setting up the environment
+
+    Start a platform SDK "build environment window" from the start menu. The
+    "Windows XP 32-bit retail" version is known to work.
+
+    Add the following directories to your PATH:
+        * The toolkit compiler directory
+        * The SDK "Win64" binaries directory
+	* The Nant directory
+    Add to your INCLUDE environment variable:
+        * The toolkit compiler INCLUDE directory
+    Add to your LIB environment variable:
+        * The toolkit compiler LIB directory
+	* The .NET SDK Visual Studio 2003 VC7\lib directory
+
+    The following commands should set things up as you need them:
+
+        rem Set these values according to where you installed the software
+        set TOOLKIT=C:\Program Files\Microsoft Visual C++ Toolkit 2003
+        set SDK=C:\Program Files\Microsoft Platform SDK
+        set NET=C:\Program Files\Microsoft Visual Studio .NET 2003
+        set NANT=C:\Utils\Nant
+
+        set PATH=%TOOLKIT%\bin;%PATH%;%SDK%\Bin\win64;%NANT%\bin
+        set INCLUDE=%TOOLKIT%\include;%INCLUDE%
+        set LIB=%TOOLKIT%\lib;%NET%\VC7\lib;%LIB%
+
+    The "win64" directory from the SDK is added to supply executables such as
+    "cvtres" and "lib", which are not available elsewhere. The versions in the
+    "win64" directory are 32-bit programs, so they are fine to use here.
+
+    That's it. To build Python (the core only, no binary extensions which
+    depend on external libraries) you just need to issue the command
+
+        nant -buildfile:python.build all
+
+    from within the PCBuild directory.
+
+Extension modules
+
+    To build those extension modules which require external libraries
+    (_tkinter, bz2, _bsddb, _sqlite3, _ssl) you can follow the instructions
+    for the Visual Studio build above, with a few minor modifications. These
+    instructions have only been tested using the sources in the Python
+    subversion repository - building from original sources should work, but
+    has not been tested.
+
+    For each extension module you wish to build, you should remove the
+    associated include line from the excludeprojects section of pc.build.
+
+    The changes required are:
+
+    _tkinter
+        The tix makefile (tix-8.4.0\win\makefile.vc) must be modified to
+	remove references to TOOLS32. The relevant lines should be changed to
+	read:
+            cc32 = cl.exe
+            link32 = link.exe
+            include32 = 
+	The remainder of the build instructions will work as given.
+
+    bz2
+        No changes are needed
+
+    _bsddb
+        The file db.build should be copied from the Python PCBuild directory
+	to the directory db-4.4.20\build_win32.
+
+	The file db_static.vcproj in db-4.4.20\build_win32 should be edited to
+	remove the string "$(SolutionDir)" - this occurs in 2 places, only
+	relevant for 64-bit builds. (The edit is required as otherwise, nant
+	wants to read the solution file, which is not in a suitable form).
+
+	The bsddb library can then be build with the command
+	    nant -buildfile:db.build all
+	run from the db-4.4.20\build_win32 directory.
+
+    _sqlite3
+        No changes are needed. However, in order for the tests to succeed, a
+	copy of sqlite3.dll must be downloaded, and placed alongside
+	python.exe.
+
+    _ssl
+        The documented build process works as written. However, it needs a
+	copy of the file setargv.obj, which is not supplied in the platform
+	SDK. However, the sources are available (in the crt source code). To
+	build setargv.obj, proceed as follows:
+
+        Copy setargv.c, cruntime.h and internal.h from %SDK%\src\crt to a
+	temporary directory.
+	Compile using "cl /c /I. /MD /D_CRTBLD setargv.c"
+	Copy the resulting setargv.obj to somewhere on your LIB environment
+	(%SDK%\lib is a reasonable place).
+
+	With setargv.obj in place, the standard build process should work
+	fine.
+
+YOUR OWN EXTENSION DLLs
+-----------------------
+If you want to create your own extension module DLL, there's an example
+with easy-to-follow instructions in ../PC/example/; read the file
+readme.txt there first.

Added: vendor/Python/current/PCbuild8/rmpyc.py
===================================================================
--- vendor/Python/current/PCbuild8/rmpyc.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild8/rmpyc.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,25 @@
+# Remove all the .pyc and .pyo files under ../Lib.
+
+
+def deltree(root):
+    import os
+    from os.path import join
+
+    npyc = npyo = 0
+    for root, dirs, files in os.walk(root):
+        for name in files:
+            delete = False
+            if name.endswith('.pyc'):
+                delete = True
+                npyc += 1
+            elif name.endswith('.pyo'):
+                delete = True
+                npyo += 1
+
+            if delete:
+                os.remove(join(root, name))
+
+    return npyc, npyo
+
+npyc, npyo = deltree("../Lib")
+print npyc, ".pyc deleted,", npyo, ".pyo deleted"

Added: vendor/Python/current/PCbuild8/rt.bat
===================================================================
--- vendor/Python/current/PCbuild8/rt.bat	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild8/rt.bat	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,52 @@
+ at echo off
+rem Run Tests.  Run the regression test suite.
+rem Usage:  rt [-d] [-O] [-q] regrtest_args
+rem -d   Run Debug build (python_d.exe).  Else release build.
+rem -O   Run python.exe or python_d.exe (see -d) with -O.
+rem -q   "quick" -- normally the tests are run twice, the first time
+rem      after deleting all the .py[co] files reachable from Lib/.
+rem      -q runs the tests just once, and without deleting .py[co] files.
+rem All leading instances of these switches are shifted off, and
+rem whatever remains is passed to regrtest.py.  For example,
+rem     rt -O -d -x test_thread
+rem runs
+rem     python_d -O ../lib/test/regrtest.py -x test_thread
+rem twice, and
+rem     rt -q -g test_binascii
+rem runs
+rem     python_d ../lib/test/regrtest.py -g test_binascii
+rem to generate the expected-output file for binascii quickly.
+rem
+rem Confusing:  if you want to pass a comma-separated list, like
+rem     -u network,largefile
+rem then you have to quote it on the rt line, like
+rem     rt -u "network,largefile"
+
+setlocal
+
+set exe=python
+set qmode=
+set dashO=
+PATH %PATH%;..\..\tcltk\bin
+
+:CheckOpts
+if "%1"=="-O" (set dashO=-O)     & shift & goto CheckOpts
+if "%1"=="-q" (set qmode=yes)    & shift & goto CheckOpts
+if "%1"=="-d" (set exe=python_d) & shift & goto CheckOpts
+
+set cmd=%exe% %dashO% -E -tt ../lib/test/regrtest.py %1 %2 %3 %4 %5 %6 %7 %8 %9
+if defined qmode goto Qmode
+
+echo Deleting .pyc/.pyo files ...
+%exe% rmpyc.py
+
+echo on
+%cmd%
+ at echo off
+
+echo About to run again without deleting .pyc/.pyo first:
+pause
+
+:Qmode
+echo on
+%cmd%

Added: vendor/Python/current/PCbuild8/select.vcproj
===================================================================
--- vendor/Python/current/PCbuild8/select.vcproj	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild8/select.vcproj	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,379 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8,00"
+	Name="select"
+	ProjectGUID="{97239A56-DBC0-41D2-BC14-C87D9B97D63B}"
+	RootNamespace="select"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(PlatformName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\select"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="wsock32.lib"
+				OutputFile="$(OutDir)\select.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				AdditionalLibraryDirectories="$(OutDir)"
+				IgnoreDefaultLibraryNames="libc"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				SubSystem="2"
+				BaseAddress="0x1D110000"
+				ImportLibrary=""
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			OutputDirectory="$(PlatformName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\select"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="wsock32.lib"
+				OutputFile="$(OutDir)\select.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				AdditionalLibraryDirectories="$(OutDir)"
+				IgnoreDefaultLibraryNames="libc"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				SubSystem="2"
+				BaseAddress="0x1D110000"
+				ImportLibrary=""
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(PlatformName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\select"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="wsock32.lib"
+				OutputFile="$(OutDir)\select_d.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				AdditionalLibraryDirectories="$(OutDir)"
+				IgnoreDefaultLibraryNames="libc,msvcrt"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				SubSystem="2"
+				BaseAddress="0x1D110000"
+				ImportLibrary=""
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			OutputDirectory="$(PlatformName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\select"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="wsock32.lib"
+				OutputFile="$(OutDir)\select_d.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				AdditionalLibraryDirectories="$(OutDir)"
+				IgnoreDefaultLibraryNames="libc,msvcrt"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				SubSystem="2"
+				BaseAddress="0x1D110000"
+				ImportLibrary=""
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath="..\Modules\selectmodule.c"
+			>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Added: vendor/Python/current/PCbuild8/unicodedata.vcproj
===================================================================
--- vendor/Python/current/PCbuild8/unicodedata.vcproj	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild8/unicodedata.vcproj	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,371 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8,00"
+	Name="unicodedata"
+	ProjectGUID="{FA5FC7EB-C72F-415F-AE42-91DD605ABDDA}"
+	RootNamespace="unicodedata"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(PlatformName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\unicodedata"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MMAP_EXPORTS"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\unicodedata.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				AdditionalLibraryDirectories="$(OutDir)"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				BaseAddress="0x1D120000"
+				ImportLibrary=""
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			OutputDirectory="$(PlatformName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\unicodedata"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MMAP_EXPORTS"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\unicodedata.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				AdditionalLibraryDirectories="$(OutDir)"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				BaseAddress="0x1D120000"
+				ImportLibrary=""
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(PlatformName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\unicodedata"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;MMAP_EXPORTS"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\unicodedata_d.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				AdditionalLibraryDirectories="$(OutDir)"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				BaseAddress="0x1D120000"
+				ImportLibrary=""
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			OutputDirectory="$(PlatformName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\unicodedata"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;MMAP_EXPORTS"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\unicodedata_d.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				AdditionalLibraryDirectories="$(OutDir)"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				BaseAddress="0x1D120000"
+				ImportLibrary=""
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath="..\Modules\unicodedata.c"
+			>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Added: vendor/Python/current/PCbuild8/w9xpopen.vcproj
===================================================================
--- vendor/Python/current/PCbuild8/w9xpopen.vcproj	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild8/w9xpopen.vcproj	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,353 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8,00"
+	Name="w9xpopen"
+	ProjectGUID="{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}"
+	RootNamespace="w9xpopen"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(PlatformName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\w9xpopen"
+			ConfigurationType="1"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\w9xpopen_d.exe"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				AdditionalLibraryDirectories="$(OutDir)"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			OutputDirectory="$(PlatformName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\w9xpopen"
+			ConfigurationType="1"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\w9xpopen_d.exe"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(PlatformName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\w9xpopen"
+			ConfigurationType="1"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\w9xpopen.exe"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				AdditionalLibraryDirectories="$(OutDir)"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			OutputDirectory="$(PlatformName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\w9xpopen"
+			ConfigurationType="1"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\w9xpopen.exe"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath="..\PC\w9xpopen.c"
+			>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Added: vendor/Python/current/PCbuild8/winsound.vcproj
===================================================================
--- vendor/Python/current/PCbuild8/winsound.vcproj	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/PCbuild8/winsound.vcproj	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,375 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8,00"
+	Name="winsound"
+	ProjectGUID="{51F35FAE-FB92-4B2C-9187-1542C065AD77}"
+	RootNamespace="winsound"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(PlatformName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\winsound"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;WINSOUND_EXPORTS"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)\winsound_d.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				AdditionalLibraryDirectories="$(OutDir)"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				BaseAddress="0x1D160000"
+				ImportLibrary=""
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			OutputDirectory="$(PlatformName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\winsound"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;WINSOUND_EXPORTS"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)\winsound_d.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				AdditionalLibraryDirectories="$(OutDir)"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				BaseAddress="0x1D160000"
+				ImportLibrary=""
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(PlatformName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\winsound"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;WINSOUND_EXPORTS"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)\winsound.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				AdditionalLibraryDirectories="$(OutDir)"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				BaseAddress="0x1D160000"
+				ImportLibrary=""
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			OutputDirectory="$(PlatformName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\winsound"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\Include,..\PC"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;WINSOUND_EXPORTS"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)\winsound.pyd"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				AdditionalLibraryDirectories="$(OutDir)"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=""
+				BaseAddress="0x1D160000"
+				ImportLibrary=""
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath="..\PC\winsound.c"
+			>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Added: vendor/Python/current/Parser/Python.asdl
===================================================================
--- vendor/Python/current/Parser/Python.asdl	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Parser/Python.asdl	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,115 @@
+-- ASDL's five builtin types are identifier, int, string, object, bool
+
+module Python version "$Revision: 43614 $"
+{
+	mod = Module(stmt* body)
+	    | Interactive(stmt* body)
+	    | Expression(expr body)
+
+	    -- not really an actual node but useful in Jython's typesystem.
+	    | Suite(stmt* body)
+
+	stmt = FunctionDef(identifier name, arguments args, 
+                           stmt* body, expr* decorators)
+	      | ClassDef(identifier name, expr* bases, stmt* body)
+	      | Return(expr? value)
+
+	      | Delete(expr* targets)
+	      | Assign(expr* targets, expr value)
+	      | AugAssign(expr target, operator op, expr value)
+
+	      -- not sure if bool is allowed, can always use int
+ 	      | Print(expr? dest, expr* values, bool nl)
+
+	      -- use 'orelse' because else is a keyword in target languages
+	      | For(expr target, expr iter, stmt* body, stmt* orelse)
+	      | While(expr test, stmt* body, stmt* orelse)
+	      | If(expr test, stmt* body, stmt* orelse)
+	      | With(expr context_expr, expr? optional_vars, stmt* body)
+
+	      -- 'type' is a bad name
+	      | Raise(expr? type, expr? inst, expr? tback)
+	      | TryExcept(stmt* body, excepthandler* handlers, stmt* orelse)
+	      | TryFinally(stmt* body, stmt* finalbody)
+	      | Assert(expr test, expr? msg)
+
+	      | Import(alias* names)
+	      | ImportFrom(identifier module, alias* names, int? level)
+
+	      -- Doesn't capture requirement that locals must be
+	      -- defined if globals is
+	      -- still supports use as a function!
+	      | Exec(expr body, expr? globals, expr? locals)
+
+	      | Global(identifier* names)
+	      | Expr(expr value)
+	      | Pass | Break | Continue
+
+	      -- XXX Jython will be different
+	      -- col_offset is the byte offset in the utf8 string the parser uses
+	      attributes (int lineno, int col_offset)
+
+	      -- BoolOp() can use left & right?
+	expr = BoolOp(boolop op, expr* values)
+	     | BinOp(expr left, operator op, expr right)
+	     | UnaryOp(unaryop op, expr operand)
+	     | Lambda(arguments args, expr body)
+	     | IfExp(expr test, expr body, expr orelse)
+	     | Dict(expr* keys, expr* values)
+	     | ListComp(expr elt, comprehension* generators)
+	     | GeneratorExp(expr elt, comprehension* generators)
+	     -- the grammar constrains where yield expressions can occur
+	     | Yield(expr? value)
+	     -- need sequences for compare to distinguish between
+	     -- x < 4 < 3 and (x < 4) < 3
+	     | Compare(expr left, cmpop* ops, expr* comparators)
+	     | Call(expr func, expr* args, keyword* keywords,
+			 expr? starargs, expr? kwargs)
+	     | Repr(expr value)
+	     | Num(object n) -- a number as a PyObject.
+	     | Str(string s) -- need to specify raw, unicode, etc?
+	     -- other literals? bools?
+
+	     -- the following expression can appear in assignment context
+	     | Attribute(expr value, identifier attr, expr_context ctx)
+	     | Subscript(expr value, slice slice, expr_context ctx)
+	     | Name(identifier id, expr_context ctx)
+	     | List(expr* elts, expr_context ctx) 
+	     | Tuple(expr *elts, expr_context ctx)
+
+	      -- col_offset is the byte offset in the utf8 string the parser uses
+	      attributes (int lineno, int col_offset)
+
+	expr_context = Load | Store | Del | AugLoad | AugStore | Param
+
+	slice = Ellipsis | Slice(expr? lower, expr? upper, expr? step) 
+	      | ExtSlice(slice* dims) 
+	      | Index(expr value) 
+
+	boolop = And | Or 
+
+	operator = Add | Sub | Mult | Div | Mod | Pow | LShift 
+                 | RShift | BitOr | BitXor | BitAnd | FloorDiv
+
+	unaryop = Invert | Not | UAdd | USub
+
+	cmpop = Eq | NotEq | Lt | LtE | Gt | GtE | Is | IsNot | In | NotIn
+
+	comprehension = (expr target, expr iter, expr* ifs)
+
+	-- not sure what to call the first argument for raise and except
+	-- TODO(jhylton): Figure out if there is a better way to handle
+	--                lineno and col_offset fields, particularly when
+        --                ast is exposed to Python.
+	excepthandler = (expr? type, expr? name, stmt* body, int lineno,
+	                 int col_offset)
+
+	arguments = (expr* args, identifier? vararg, 
+		     identifier? kwarg, expr* defaults)
+
+        -- keyword arguments supplied to call
+        keyword = (identifier arg, expr value)
+
+        -- import name with optional 'as' alias.
+        alias = (identifier name, identifier? asname)
+}

Added: vendor/Python/current/Parser/acceler.c
===================================================================
--- vendor/Python/current/Parser/acceler.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Parser/acceler.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,125 @@
+
+/* Parser accelerator module */
+
+/* The parser as originally conceived had disappointing performance.
+   This module does some precomputation that speeds up the selection
+   of a DFA based upon a token, turning a search through an array
+   into a simple indexing operation.  The parser now cannot work
+   without the accelerators installed.  Note that the accelerators
+   are installed dynamically when the parser is initialized, they
+   are not part of the static data structure written on graminit.[ch]
+   by the parser generator. */
+
+#include "pgenheaders.h"
+#include "grammar.h"
+#include "node.h"
+#include "token.h"
+#include "parser.h"
+
+/* Forward references */
+static void fixdfa(grammar *, dfa *);
+static void fixstate(grammar *, state *);
+
+void
+PyGrammar_AddAccelerators(grammar *g)
+{
+	dfa *d;
+	int i;
+	d = g->g_dfa;
+	for (i = g->g_ndfas; --i >= 0; d++)
+		fixdfa(g, d);
+	g->g_accel = 1;
+}
+
+void
+PyGrammar_RemoveAccelerators(grammar *g)
+{
+	dfa *d;
+	int i;
+	g->g_accel = 0;
+	d = g->g_dfa;
+	for (i = g->g_ndfas; --i >= 0; d++) {
+		state *s;
+		int j;
+		s = d->d_state;
+		for (j = 0; j < d->d_nstates; j++, s++) {
+			if (s->s_accel)
+				PyObject_FREE(s->s_accel);
+			s->s_accel = NULL;
+		}
+	}
+}
+
+static void
+fixdfa(grammar *g, dfa *d)
+{
+	state *s;
+	int j;
+	s = d->d_state;
+	for (j = 0; j < d->d_nstates; j++, s++)
+		fixstate(g, s);
+}
+
+static void
+fixstate(grammar *g, state *s)
+{
+	arc *a;
+	int k;
+	int *accel;
+	int nl = g->g_ll.ll_nlabels;
+	s->s_accept = 0;
+	accel = (int *) PyObject_MALLOC(nl * sizeof(int));
+	if (accel == NULL) {
+		fprintf(stderr, "no mem to build parser accelerators\n");
+		exit(1);
+	}
+	for (k = 0; k < nl; k++)
+		accel[k] = -1;
+	a = s->s_arc;
+	for (k = s->s_narcs; --k >= 0; a++) {
+		int lbl = a->a_lbl;
+		label *l = &g->g_ll.ll_label[lbl];
+		int type = l->lb_type;
+		if (a->a_arrow >= (1 << 7)) {
+			printf("XXX too many states!\n");
+			continue;
+		}
+		if (ISNONTERMINAL(type)) {
+			dfa *d1 = PyGrammar_FindDFA(g, type);
+			int ibit;
+			if (type - NT_OFFSET >= (1 << 7)) {
+				printf("XXX too high nonterminal number!\n");
+				continue;
+			}
+			for (ibit = 0; ibit < g->g_ll.ll_nlabels; ibit++) {
+				if (testbit(d1->d_first, ibit)) {
+					if (accel[ibit] != -1)
+						printf("XXX ambiguity!\n");
+					accel[ibit] = a->a_arrow | (1 << 7) |
+						((type - NT_OFFSET) << 8);
+				}
+			}
+		}
+		else if (lbl == EMPTY)
+			s->s_accept = 1;
+		else if (lbl >= 0 && lbl < nl)
+			accel[lbl] = a->a_arrow;
+	}
+	while (nl > 0 && accel[nl-1] == -1)
+		nl--;
+	for (k = 0; k < nl && accel[k] == -1;)
+		k++;
+	if (k < nl) {
+		int i;
+		s->s_accel = (int *) PyObject_MALLOC((nl-k) * sizeof(int));
+		if (s->s_accel == NULL) {
+			fprintf(stderr, "no mem to add parser accelerators\n");
+			exit(1);
+		}
+		s->s_lower = k;
+		s->s_upper = nl;
+		for (i = 0; k < nl; i++, k++)
+			s->s_accel[i] = accel[k];
+	}
+	PyObject_FREE(accel);
+}

Added: vendor/Python/current/Parser/asdl.py
===================================================================
--- vendor/Python/current/Parser/asdl.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Parser/asdl.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,415 @@
+"""An implementation of the Zephyr Abstract Syntax Definition Language.
+
+See http://asdl.sourceforge.net/ and
+http://www.cs.princeton.edu/~danwang/Papers/dsl97/dsl97-abstract.html.
+
+Only supports top level module decl, not view.  I'm guessing that view
+is intended to support the browser and I'm not interested in the
+browser.
+
+Changes for Python: Add support for module versions
+"""
+
+#__metaclass__ = type
+
+import os
+import traceback
+
+import spark
+
+class Token:
+    # spark seems to dispatch in the parser based on a token's
+    # type attribute
+    def __init__(self, type, lineno):
+        self.type = type
+        self.lineno = lineno
+
+    def __str__(self):
+        return self.type
+
+    def __repr__(self):
+        return str(self)
+
+class Id(Token):
+    def __init__(self, value, lineno):
+        self.type = 'Id'
+        self.value = value
+        self.lineno = lineno
+
+    def __str__(self):
+        return self.value
+
+class String(Token):
+    def __init__(self, value, lineno):
+        self.type = 'String'
+        self.value = value
+        self.lineno = lineno
+
+class ASDLSyntaxError:
+
+    def __init__(self, lineno, token=None, msg=None):
+        self.lineno = lineno
+        self.token = token
+        self.msg = msg
+
+    def __str__(self):
+        if self.msg is None:
+            return "Error at '%s', line %d" % (self.token, self.lineno)
+        else:
+            return "%s, line %d" % (self.msg, self.lineno)
+
+class ASDLScanner(spark.GenericScanner, object):
+
+    def tokenize(self, input):
+        self.rv = []
+        self.lineno = 1
+        super(ASDLScanner, self).tokenize(input)
+        return self.rv
+
+    def t_id(self, s):
+        r"[\w\.]+"
+        # XXX doesn't distinguish upper vs. lower, which is
+        # significant for ASDL.
+        self.rv.append(Id(s, self.lineno))
+
+    def t_string(self, s):
+        r'"[^"]*"'
+        self.rv.append(String(s, self.lineno))
+
+    def t_xxx(self, s): # not sure what this production means
+        r"<="
+        self.rv.append(Token(s, self.lineno))
+
+    def t_punctuation(self, s):
+        r"[\{\}\*\=\|\(\)\,\?\:]"
+        self.rv.append(Token(s, self.lineno))
+
+    def t_comment(self, s):
+        r"\-\-[^\n]*"
+        pass
+
+    def t_newline(self, s):
+        r"\n"
+        self.lineno += 1
+
+    def t_whitespace(self, s):
+        r"[ \t]+"
+        pass
+
+    def t_default(self, s):
+        r" . +"
+        raise ValueError, "unmatched input: %s" % `s`
+
+class ASDLParser(spark.GenericParser, object):
+    def __init__(self):
+        super(ASDLParser, self).__init__("module")
+
+    def typestring(self, tok):
+        return tok.type
+
+    def error(self, tok):
+        raise ASDLSyntaxError(tok.lineno, tok)
+
+    def p_module_0(self, (module, name, version, _0, _1)):
+        " module ::= Id Id version { } "
+        if module.value != "module":
+            raise ASDLSyntaxError(module.lineno,
+                                  msg="expected 'module', found %s" % module)
+        return Module(name, None, version)
+
+    def p_module(self, (module, name, version, _0, definitions, _1)):
+        " module ::= Id Id version { definitions } "
+        if module.value != "module":
+            raise ASDLSyntaxError(module.lineno,
+                                  msg="expected 'module', found %s" % module)
+        return Module(name, definitions, version)
+
+    def p_version(self, (version, V)):
+        "version ::= Id String"
+        if version.value != "version":
+            raise ASDLSyntaxError(version.lineno,
+                                msg="expected 'version', found %" % version)
+        return V
+
+    def p_definition_0(self, (definition,)):
+        " definitions ::= definition "
+        return definition
+
+    def p_definition_1(self, (definitions, definition)):
+        " definitions ::= definition definitions "
+        return definitions + definition
+
+    def p_definition(self, (id, _, type)):
+        " definition ::= Id = type "
+        return [Type(id, type)]
+
+    def p_type_0(self, (product,)):
+        " type ::= product "
+        return product
+
+    def p_type_1(self, (sum,)):
+        " type ::= sum "
+        return Sum(sum)
+
+    def p_type_2(self, (sum, id, _0, attributes, _1)):
+        " type ::= sum Id ( fields ) "
+        if id.value != "attributes":
+            raise ASDLSyntaxError(id.lineno,
+                                  msg="expected attributes, found %s" % id)
+        if attributes:
+            attributes.reverse()
+        return Sum(sum, attributes)
+
+    def p_product(self, (_0, fields, _1)):
+        " product ::= ( fields ) "
+        # XXX can't I just construct things in the right order?
+        fields.reverse()
+        return Product(fields)
+
+    def p_sum_0(self, (constructor,)):
+        " sum ::= constructor """
+        return [constructor]
+
+    def p_sum_1(self, (constructor, _, sum)):
+        " sum ::= constructor | sum "
+        return [constructor] + sum
+
+    def p_sum_2(self, (constructor, _, sum)):
+        " sum ::= constructor | sum "
+        return [constructor] + sum
+
+    def p_constructor_0(self, (id,)):
+        " constructor ::= Id "
+        return Constructor(id)
+
+    def p_constructor_1(self, (id, _0, fields, _1)):
+        " constructor ::= Id ( fields ) "
+        # XXX can't I just construct things in the right order?
+        fields.reverse()
+        return Constructor(id, fields)
+
+    def p_fields_0(self, (field,)):
+        " fields ::= field "
+        return [field]
+
+    def p_fields_1(self, (field, _, fields)):
+        " fields ::= field , fields "
+        return fields + [field]
+
+    def p_field_0(self, (type,)):
+        " field ::= Id "
+        return Field(type)
+
+    def p_field_1(self, (type, name)):
+        " field ::= Id Id "
+        return Field(type, name)
+
+    def p_field_2(self, (type, _, name)):
+        " field ::= Id * Id "
+        return Field(type, name, seq=1)
+
+    def p_field_3(self, (type, _, name)):
+        " field ::= Id ? Id "
+        return Field(type, name, opt=1)
+
+    def p_field_4(self, (type, _)):
+        " field ::= Id * "
+        return Field(type, seq=1)
+
+    def p_field_5(self, (type, _)):
+        " field ::= Id ? "
+        return Field(type, opt=1)
+
+builtin_types = ("identifier", "string", "int", "bool", "object")
+
+# below is a collection of classes to capture the AST of an AST :-)
+# not sure if any of the methods are useful yet, but I'm adding them
+# piecemeal as they seem helpful
+
+class AST:
+    pass # a marker class
+
+class Module(AST):
+    def __init__(self, name, dfns, version):
+        self.name = name
+        self.dfns = dfns
+        self.version = version
+        self.types = {} # maps type name to value (from dfns)
+        for type in dfns:
+            self.types[type.name.value] = type.value
+
+    def __repr__(self):
+        return "Module(%s, %s)" % (self.name, self.dfns)
+
+class Type(AST):
+    def __init__(self, name, value):
+        self.name = name
+        self.value = value
+
+    def __repr__(self):
+        return "Type(%s, %s)" % (self.name, self.value)
+
+class Constructor(AST):
+    def __init__(self, name, fields=None):
+        self.name = name
+        self.fields = fields or []
+
+    def __repr__(self):
+        return "Constructor(%s, %s)" % (self.name, self.fields)
+
+class Field(AST):
+    def __init__(self, type, name=None, seq=0, opt=0):
+        self.type = type
+        self.name = name
+        self.seq = seq
+        self.opt = opt
+
+    def __repr__(self):
+        if self.seq:
+            extra = ", seq=1"
+        elif self.opt:
+            extra = ", opt=1"
+        else:
+            extra = ""
+        if self.name is None:
+            return "Field(%s%s)" % (self.type, extra)
+        else:
+            return "Field(%s, %s%s)" % (self.type, self.name, extra)
+
+class Sum(AST):
+    def __init__(self, types, attributes=None):
+        self.types = types
+        self.attributes = attributes or []
+
+    def __repr__(self):
+        if self.attributes is None:
+            return "Sum(%s)" % self.types
+        else:
+            return "Sum(%s, %s)" % (self.types, self.attributes)
+
+class Product(AST):
+    def __init__(self, fields):
+        self.fields = fields
+
+    def __repr__(self):
+        return "Product(%s)" % self.fields
+
+class VisitorBase(object):
+
+    def __init__(self, skip=0):
+        self.cache = {}
+        self.skip = skip
+
+    def visit(self, object, *args):
+        meth = self._dispatch(object)
+        if meth is None:
+            return
+        try:
+            meth(object, *args)
+        except Exception, err:
+            print "Error visiting", repr(object)
+            print err
+            traceback.print_exc()
+            # XXX hack
+            if hasattr(self, 'file'):
+                self.file.flush()
+            os._exit(1)
+
+    def _dispatch(self, object):
+        assert isinstance(object, AST), repr(object)
+        klass = object.__class__
+        meth = self.cache.get(klass)
+        if meth is None:
+            methname = "visit" + klass.__name__
+            if self.skip:
+                meth = getattr(self, methname, None)
+            else:
+                meth = getattr(self, methname)
+            self.cache[klass] = meth
+        return meth
+
+class Check(VisitorBase):
+
+    def __init__(self):
+        super(Check, self).__init__(skip=1)
+        self.cons = {}
+        self.errors = 0
+        self.types = {}
+
+    def visitModule(self, mod):
+        for dfn in mod.dfns:
+            self.visit(dfn)
+
+    def visitType(self, type):
+        self.visit(type.value, str(type.name))
+
+    def visitSum(self, sum, name):
+        for t in sum.types:
+            self.visit(t, name)
+
+    def visitConstructor(self, cons, name):
+        key = str(cons.name)
+        conflict = self.cons.get(key)
+        if conflict is None:
+            self.cons[key] = name
+        else:
+            print "Redefinition of constructor %s" % key
+            print "Defined in %s and %s" % (conflict, name)
+            self.errors += 1
+        for f in cons.fields:
+            self.visit(f, key)
+
+    def visitField(self, field, name):
+        key = str(field.type)
+        l = self.types.setdefault(key, [])
+        l.append(name)
+
+    def visitProduct(self, prod, name):
+        for f in prod.fields:
+            self.visit(f, name)
+
+def check(mod):
+    v = Check()
+    v.visit(mod)
+
+    for t in v.types:
+        if not mod.types.has_key(t) and not t in builtin_types:
+            v.errors += 1
+            uses = ", ".join(v.types[t])
+            print "Undefined type %s, used in %s" % (t, uses)
+
+    return not v.errors
+
+def parse(file):
+    scanner = ASDLScanner()
+    parser = ASDLParser()
+
+    buf = open(file).read()
+    tokens = scanner.tokenize(buf)
+    try:
+        return parser.parse(tokens)
+    except ASDLSyntaxError, err:
+        print err
+        lines = buf.split("\n")
+        print lines[err.lineno - 1] # lines starts at 0, files at 1
+
+if __name__ == "__main__":
+    import glob
+    import sys
+
+    if len(sys.argv) > 1:
+        files = sys.argv[1:]
+    else:
+        testdir = "tests"
+        files = glob.glob(testdir + "/*.asdl")
+
+    for file in files:
+        print file
+        mod = parse(file)
+        print "module", mod.name
+        print len(mod.dfns), "definitions"
+        if not check(mod):
+            print "Check failed"
+        else:
+            for dfn in mod.dfns:
+                print dfn.type

Added: vendor/Python/current/Parser/asdl_c.py
===================================================================
--- vendor/Python/current/Parser/asdl_c.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Parser/asdl_c.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,782 @@
+#! /usr/bin/env python
+"""Generate C code from an ASDL description."""
+
+# TO DO
+# handle fields that have a type but no name
+
+import os, sys, traceback
+
+import asdl
+
+TABSIZE = 8
+MAX_COL = 80
+
+def get_c_type(name):
+    """Return a string for the C name of the type.
+
+    This function special cases the default types provided by asdl:
+    identifier, string, int, bool.
+    """
+    # XXX ack!  need to figure out where Id is useful and where string
+    if isinstance(name, asdl.Id):
+        name = name.value
+    if name in asdl.builtin_types:
+        return name
+    else:
+        return "%s_ty" % name
+
+def reflow_lines(s, depth):
+    """Reflow the line s indented depth tabs.
+
+    Return a sequence of lines where no line extends beyond MAX_COL
+    when properly indented.  The first line is properly indented based
+    exclusively on depth * TABSIZE.  All following lines -- these are
+    the reflowed lines generated by this function -- start at the same
+    column as the first character beyond the opening { in the first
+    line.
+    """
+    size = MAX_COL - depth * TABSIZE
+    if len(s) < size:
+        return [s]
+
+    lines = []
+    cur = s
+    padding = ""
+    while len(cur) > size:
+        i = cur.rfind(' ', 0, size)
+        # XXX this should be fixed for real
+        if i == -1 and 'GeneratorExp' in cur:
+            i = size + 3
+        assert i != -1, "Impossible line %d to reflow: %s" % (size, `s`)
+        lines.append(padding + cur[:i])
+        if len(lines) == 1:
+            # find new size based on brace
+            j = cur.find('{', 0, i)
+            if j >= 0:
+                j += 2 # account for the brace and the space after it
+                size -= j
+                padding = " " * j
+            else:
+                j = cur.find('(', 0, i)
+                if j >= 0:
+                    j += 1 # account for the paren (no space after it)
+                    size -= j
+                    padding = " " * j
+        cur = cur[i+1:]
+    else:
+        lines.append(padding + cur)
+    return lines
+
+def is_simple(sum):
+    """Return True if a sum is a simple.
+
+    A sum is simple if its types have no fields, e.g.
+    unaryop = Invert | Not | UAdd | USub
+    """
+
+    for t in sum.types:
+        if t.fields:
+            return False
+    return True
+
+class EmitVisitor(asdl.VisitorBase):
+    """Visit that emits lines"""
+
+    def __init__(self, file):
+        self.file = file
+        super(EmitVisitor, self).__init__()
+
+    def emit(self, s, depth, reflow=1):
+        # XXX reflow long lines?
+        if reflow:
+            lines = reflow_lines(s, depth)
+        else:
+            lines = [s]
+        for line in lines:
+            line = (" " * TABSIZE * depth) + line + "\n"
+            self.file.write(line)
+
+class TypeDefVisitor(EmitVisitor):
+    def visitModule(self, mod):
+        for dfn in mod.dfns:
+            self.visit(dfn)
+
+    def visitType(self, type, depth=0):
+        self.visit(type.value, type.name, depth)
+
+    def visitSum(self, sum, name, depth):
+        if is_simple(sum):
+            self.simple_sum(sum, name, depth)
+        else:
+            self.sum_with_constructors(sum, name, depth)
+
+    def simple_sum(self, sum, name, depth):
+        enum = []
+        for i in range(len(sum.types)):
+            type = sum.types[i]
+            enum.append("%s=%d" % (type.name, i + 1))
+        enums = ", ".join(enum)
+        ctype = get_c_type(name)
+        s = "typedef enum _%s { %s } %s;" % (name, enums, ctype)
+        self.emit(s, depth)
+        self.emit("", depth)
+
+    def sum_with_constructors(self, sum, name, depth):
+        ctype = get_c_type(name)
+        s = "typedef struct _%(name)s *%(ctype)s;" % locals()
+        self.emit(s, depth)
+        self.emit("", depth)
+
+    def visitProduct(self, product, name, depth):
+        ctype = get_c_type(name)
+        s = "typedef struct _%(name)s *%(ctype)s;" % locals()
+        self.emit(s, depth)
+        self.emit("", depth)
+
+class StructVisitor(EmitVisitor):
+    """Visitor to generate typdefs for AST."""
+
+    def visitModule(self, mod):
+        for dfn in mod.dfns:
+            self.visit(dfn)
+
+    def visitType(self, type, depth=0):
+        self.visit(type.value, type.name, depth)
+
+    def visitSum(self, sum, name, depth):
+        if not is_simple(sum):
+            self.sum_with_constructors(sum, name, depth)
+
+    def sum_with_constructors(self, sum, name, depth):
+        def emit(s, depth=depth):
+            self.emit(s % sys._getframe(1).f_locals, depth)
+        enum = []
+        for i in range(len(sum.types)):
+            type = sum.types[i]
+            enum.append("%s_kind=%d" % (type.name, i + 1))
+
+        emit("enum _%(name)s_kind {" + ", ".join(enum) + "};")
+
+        emit("struct _%(name)s {")
+        emit("enum _%(name)s_kind kind;", depth + 1)
+        emit("union {", depth + 1)
+        for t in sum.types:
+            self.visit(t, depth + 2)
+        emit("} v;", depth + 1)
+        for field in sum.attributes:
+            # rudimentary attribute handling
+            type = str(field.type)
+            assert type in asdl.builtin_types, type
+            emit("%s %s;" % (type, field.name), depth + 1);
+        emit("};")
+        emit("")
+
+    def visitConstructor(self, cons, depth):
+        if cons.fields:
+            self.emit("struct {", depth)
+            for f in cons.fields:
+                self.visit(f, depth + 1)
+            self.emit("} %s;" % cons.name, depth)
+            self.emit("", depth)
+        else:
+            # XXX not sure what I want here, nothing is probably fine
+            pass
+
+    def visitField(self, field, depth):
+        # XXX need to lookup field.type, because it might be something
+        # like a builtin...
+        ctype = get_c_type(field.type)
+        name = field.name
+        if field.seq:
+            if field.type.value in ('cmpop',):
+                self.emit("asdl_int_seq *%(name)s;" % locals(), depth)
+            else:
+                self.emit("asdl_seq *%(name)s;" % locals(), depth)
+        else:
+            self.emit("%(ctype)s %(name)s;" % locals(), depth)
+
+    def visitProduct(self, product, name, depth):
+        self.emit("struct _%(name)s {" % locals(), depth)
+        for f in product.fields:
+            self.visit(f, depth + 1)
+        self.emit("};", depth)
+        self.emit("", depth)
+
+class PrototypeVisitor(EmitVisitor):
+    """Generate function prototypes for the .h file"""
+
+    def visitModule(self, mod):
+        for dfn in mod.dfns:
+            self.visit(dfn)
+
+    def visitType(self, type):
+        self.visit(type.value, type.name)
+
+    def visitSum(self, sum, name):
+        if is_simple(sum):
+            pass # XXX
+        else:
+            for t in sum.types:
+                self.visit(t, name, sum.attributes)
+
+    def get_args(self, fields):
+        """Return list of C argument into, one for each field.
+
+        Argument info is 3-tuple of a C type, variable name, and flag
+        that is true if type can be NULL.
+        """
+        args = []
+        unnamed = {}
+        for f in fields:
+            if f.name is None:
+                name = f.type
+                c = unnamed[name] = unnamed.get(name, 0) + 1
+                if c > 1:
+                    name = "name%d" % (c - 1)
+            else:
+                name = f.name
+            # XXX should extend get_c_type() to handle this
+            if f.seq:
+                if f.type.value in ('cmpop',):
+                    ctype = "asdl_int_seq *"
+                else:
+                    ctype = "asdl_seq *"
+            else:
+                ctype = get_c_type(f.type)
+            args.append((ctype, name, f.opt or f.seq))
+        return args
+
+    def visitConstructor(self, cons, type, attrs):
+        args = self.get_args(cons.fields)
+        attrs = self.get_args(attrs)
+        ctype = get_c_type(type)
+        self.emit_function(cons.name, ctype, args, attrs)
+
+    def emit_function(self, name, ctype, args, attrs, union=1):
+        args = args + attrs
+        if args:
+            argstr = ", ".join(["%s %s" % (atype, aname)
+                                for atype, aname, opt in args])
+            argstr += ", PyArena *arena"
+        else:
+            argstr = "PyArena *arena"
+        margs = "a0"
+        for i in range(1, len(args)+1):
+            margs += ", a%d" % i
+        self.emit("#define %s(%s) _Py_%s(%s)" % (name, margs, name, margs), 0,
+                reflow = 0)
+        self.emit("%s _Py_%s(%s);" % (ctype, name, argstr), 0)
+
+    def visitProduct(self, prod, name):
+        self.emit_function(name, get_c_type(name),
+                           self.get_args(prod.fields), [], union=0)
+
+class FunctionVisitor(PrototypeVisitor):
+    """Visitor to generate constructor functions for AST."""
+
+    def emit_function(self, name, ctype, args, attrs, union=1):
+        def emit(s, depth=0, reflow=1):
+            self.emit(s, depth, reflow)
+        argstr = ", ".join(["%s %s" % (atype, aname)
+                            for atype, aname, opt in args + attrs])
+        if argstr:
+            argstr += ", PyArena *arena"
+        else:
+            argstr = "PyArena *arena"
+        self.emit("%s" % ctype, 0)
+        emit("%s(%s)" % (name, argstr))
+        emit("{")
+        emit("%s p;" % ctype, 1)
+        for argtype, argname, opt in args:
+            # XXX hack alert: false is allowed for a bool
+            if not opt and not (argtype == "bool" or argtype == "int"):
+                emit("if (!%s) {" % argname, 1)
+                emit("PyErr_SetString(PyExc_ValueError,", 2)
+                msg = "field %s is required for %s" % (argname, name)
+                emit('                "%s");' % msg,
+                     2, reflow=0)
+                emit('return NULL;', 2)
+                emit('}', 1)
+
+        emit("p = (%s)PyArena_Malloc(arena, sizeof(*p));" % ctype, 1);
+        emit("if (!p) {", 1)
+        emit("PyErr_NoMemory();", 2)
+        emit("return NULL;", 2)
+        emit("}", 1)
+        if union:
+            self.emit_body_union(name, args, attrs)
+        else:
+            self.emit_body_struct(name, args, attrs)
+        emit("return p;", 1)
+        emit("}")
+        emit("")
+
+    def emit_body_union(self, name, args, attrs):
+        def emit(s, depth=0, reflow=1):
+            self.emit(s, depth, reflow)
+        emit("p->kind = %s_kind;" % name, 1)
+        for argtype, argname, opt in args:
+            emit("p->v.%s.%s = %s;" % (name, argname, argname), 1)
+        for argtype, argname, opt in attrs:
+            emit("p->%s = %s;" % (argname, argname), 1)
+
+    def emit_body_struct(self, name, args, attrs):
+        def emit(s, depth=0, reflow=1):
+            self.emit(s, depth, reflow)
+        for argtype, argname, opt in args:
+            emit("p->%s = %s;" % (argname, argname), 1)
+        assert not attrs
+
+class PickleVisitor(EmitVisitor):
+
+    def visitModule(self, mod):
+        for dfn in mod.dfns:
+            self.visit(dfn)
+
+    def visitType(self, type):
+        self.visit(type.value, type.name)
+
+    def visitSum(self, sum, name):
+        pass
+
+    def visitProduct(self, sum, name):
+        pass
+
+    def visitConstructor(self, cons, name):
+        pass
+
+    def visitField(self, sum):
+        pass
+
+class MarshalPrototypeVisitor(PickleVisitor):
+
+    def prototype(self, sum, name):
+        ctype = get_c_type(name)
+        self.emit("static int marshal_write_%s(PyObject **, int *, %s);"
+                  % (name, ctype), 0)
+
+    visitProduct = visitSum = prototype
+
+class PyTypesDeclareVisitor(PickleVisitor):
+
+    def visitProduct(self, prod, name):
+        self.emit("static PyTypeObject *%s_type;" % name, 0)
+        self.emit("static PyObject* ast2obj_%s(void*);" % name, 0)
+        if prod.fields:
+            self.emit("static char *%s_fields[]={" % name,0)
+            for f in prod.fields:
+                self.emit('"%s",' % f.name, 1)
+            self.emit("};", 0)
+
+    def visitSum(self, sum, name):
+        self.emit("static PyTypeObject *%s_type;" % name, 0)
+        if sum.attributes:
+            self.emit("static char *%s_attributes[] = {" % name, 0)
+            for a in sum.attributes:
+                self.emit('"%s",' % a.name, 1)
+            self.emit("};", 0)
+        ptype = "void*"
+        if is_simple(sum):
+            ptype = get_c_type(name)
+            tnames = []
+            for t in sum.types:
+                tnames.append(str(t.name)+"_singleton")
+            tnames = ", *".join(tnames)
+            self.emit("static PyObject *%s;" % tnames, 0)
+        self.emit("static PyObject* ast2obj_%s(%s);" % (name, ptype), 0)
+        for t in sum.types:
+            self.visitConstructor(t, name)
+
+    def visitConstructor(self, cons, name):
+        self.emit("static PyTypeObject *%s_type;" % cons.name, 0)
+        if cons.fields:
+            self.emit("static char *%s_fields[]={" % cons.name, 0)
+            for t in cons.fields:
+                self.emit('"%s",' % t.name, 1)
+            self.emit("};",0)
+
+class PyTypesVisitor(PickleVisitor):
+
+    def visitModule(self, mod):
+        self.emit("""
+static PyTypeObject* make_type(char *type, PyTypeObject* base, char**fields, int num_fields)
+{
+    PyObject *fnames, *result;
+    int i;
+    if (num_fields) {
+        fnames = PyTuple_New(num_fields);
+        if (!fnames) return NULL;
+    } else {
+        fnames = Py_None;
+        Py_INCREF(Py_None);
+    }
+    for(i=0; i < num_fields; i++) {
+        PyObject *field = PyString_FromString(fields[i]);
+        if (!field) {
+            Py_DECREF(fnames);
+            return NULL;
+        }
+        PyTuple_SET_ITEM(fnames, i, field);
+    }
+    result = PyObject_CallFunction((PyObject*)&PyType_Type, "s(O){sOss}",
+                    type, base, "_fields", fnames, "__module__", "_ast");
+    Py_DECREF(fnames);
+    return (PyTypeObject*)result;
+}
+
+static int add_attributes(PyTypeObject* type, char**attrs, int num_fields)
+{
+    int i, result;
+    PyObject *s, *l = PyList_New(num_fields);
+    if (!l) return 0;
+    for(i = 0; i < num_fields; i++) {
+        s = PyString_FromString(attrs[i]);
+        if (!s) {
+            Py_DECREF(l);
+            return 0;
+        }
+        PyList_SET_ITEM(l, i, s);
+    }
+    result = PyObject_SetAttrString((PyObject*)type, "_attributes", l) >= 0;
+    Py_DECREF(l);
+    return result;
+}
+
+static PyObject* ast2obj_list(asdl_seq *seq, PyObject* (*func)(void*))
+{
+    int i, n = asdl_seq_LEN(seq);
+    PyObject *result = PyList_New(n);
+    PyObject *value;
+    if (!result)
+        return NULL;
+    for (i = 0; i < n; i++) {
+        value = func(asdl_seq_GET(seq, i));
+        if (!value) {
+            Py_DECREF(result);
+            return NULL;
+        }
+        PyList_SET_ITEM(result, i, value);
+    }
+    return result;
+}
+
+static PyObject* ast2obj_object(void *o)
+{
+    if (!o)
+        o = Py_None;
+    Py_INCREF((PyObject*)o);
+    return (PyObject*)o;
+}
+#define ast2obj_identifier ast2obj_object
+#define ast2obj_string ast2obj_object
+static PyObject* ast2obj_bool(bool b)
+{
+    return PyBool_FromLong(b);
+}
+
+static PyObject* ast2obj_int(bool b)
+{
+    return PyInt_FromLong(b);
+}
+""", 0, reflow=False)
+
+        self.emit("static int init_types(void)",0)
+        self.emit("{", 0)
+        self.emit("static int initialized;", 1)
+        self.emit("if (initialized) return 1;", 1)
+        self.emit('AST_type = make_type("AST", &PyBaseObject_Type, NULL, 0);', 1)
+        for dfn in mod.dfns:
+            self.visit(dfn)
+        self.emit("initialized = 1;", 1)
+        self.emit("return 1;", 1);
+        self.emit("}", 0)
+
+    def visitProduct(self, prod, name):
+        if prod.fields:
+            fields = name.value+"_fields"
+        else:
+            fields = "NULL"
+        self.emit('%s_type = make_type("%s", AST_type, %s, %d);' %
+                        (name, name, fields, len(prod.fields)), 1)
+        self.emit("if (!%s_type) return 0;" % name, 1)
+
+    def visitSum(self, sum, name):
+        self.emit('%s_type = make_type("%s", AST_type, NULL, 0);' % (name, name), 1)
+        self.emit("if (!%s_type) return 0;" % name, 1)
+        if sum.attributes:
+            self.emit("if (!add_attributes(%s_type, %s_attributes, %d)) return 0;" %
+                            (name, name, len(sum.attributes)), 1)
+        else:
+            self.emit("if (!add_attributes(%s_type, NULL, 0)) return 0;" % name, 1)
+        simple = is_simple(sum)
+        for t in sum.types:
+            self.visitConstructor(t, name, simple)
+
+    def visitConstructor(self, cons, name, simple):
+        if cons.fields:
+            fields = cons.name.value+"_fields"
+        else:
+            fields = "NULL"
+        self.emit('%s_type = make_type("%s", %s_type, %s, %d);' %
+                            (cons.name, cons.name, name, fields, len(cons.fields)), 1)
+        self.emit("if (!%s_type) return 0;" % cons.name, 1)
+        if simple:
+            self.emit("%s_singleton = PyType_GenericNew(%s_type, NULL, NULL);" %
+                             (cons.name, cons.name), 1)
+            self.emit("if (!%s_singleton) return 0;" % cons.name, 1)
+
+class ASTModuleVisitor(PickleVisitor):
+
+    def visitModule(self, mod):
+        self.emit("PyMODINIT_FUNC", 0)
+        self.emit("init_ast(void)", 0)
+        self.emit("{", 0)
+        self.emit("PyObject *m, *d;", 1)
+        self.emit("if (!init_types()) return;", 1)
+        self.emit('m = Py_InitModule3("_ast", NULL, NULL);', 1)
+        self.emit("if (!m) return;", 1)
+        self.emit("d = PyModule_GetDict(m);", 1)
+        self.emit('if (PyDict_SetItemString(d, "AST", (PyObject*)AST_type) < 0) return;', 1)
+        self.emit('if (PyModule_AddIntConstant(m, "PyCF_ONLY_AST", PyCF_ONLY_AST) < 0)', 1)
+        self.emit("return;", 2)
+        # Value of version: "$Revision: 53490 $"
+        self.emit('if (PyModule_AddStringConstant(m, "__version__", "%s") < 0)' % mod.version.value[12:-3], 1)
+        self.emit("return;", 2)
+        for dfn in mod.dfns:
+            self.visit(dfn)
+        self.emit("}", 0)
+
+    def visitProduct(self, prod, name):
+        self.addObj(name)
+
+    def visitSum(self, sum, name):
+        self.addObj(name)
+        for t in sum.types:
+            self.visitConstructor(t, name)
+
+    def visitConstructor(self, cons, name):
+        self.addObj(cons.name)
+
+    def addObj(self, name):
+        self.emit('if (PyDict_SetItemString(d, "%s", (PyObject*)%s_type) < 0) return;' % (name, name), 1)
+
+_SPECIALIZED_SEQUENCES = ('stmt', 'expr')
+
+def find_sequence(fields, doing_specialization):
+    """Return True if any field uses a sequence."""
+    for f in fields:
+        if f.seq:
+            if not doing_specialization:
+                return True
+            if str(f.type) not in _SPECIALIZED_SEQUENCES:
+                return True
+    return False
+
+def has_sequence(types, doing_specialization):
+    for t in types:
+        if find_sequence(t.fields, doing_specialization):
+            return True
+    return False
+
+
+class StaticVisitor(PickleVisitor):
+    CODE = '''Very simple, always emit this static code.  Overide CODE'''
+
+    def visit(self, object):
+        self.emit(self.CODE, 0, reflow=False)
+
+class ObjVisitor(PickleVisitor):
+
+    def func_begin(self, name):
+        ctype = get_c_type(name)
+        self.emit("PyObject*", 0)
+        self.emit("ast2obj_%s(void* _o)" % (name), 0)
+        self.emit("{", 0)
+        self.emit("%s o = (%s)_o;" % (ctype, ctype), 1)
+        self.emit("PyObject *result = NULL, *value = NULL;", 1)
+        self.emit('if (!o) {', 1)
+        self.emit("Py_INCREF(Py_None);", 2)
+        self.emit('return Py_None;', 2)
+        self.emit("}", 1)
+        self.emit('', 0)
+
+    def func_end(self):
+        self.emit("return result;", 1)
+        self.emit("failed:", 0)
+        self.emit("Py_XDECREF(value);", 1)
+        self.emit("Py_XDECREF(result);", 1)
+        self.emit("return NULL;", 1)
+        self.emit("}", 0)
+        self.emit("", 0)
+
+    def visitSum(self, sum, name):
+        if is_simple(sum):
+            self.simpleSum(sum, name)
+            return
+        self.func_begin(name)
+        self.emit("switch (o->kind) {", 1)
+        for i in range(len(sum.types)):
+            t = sum.types[i]
+            self.visitConstructor(t, i + 1, name)
+        self.emit("}", 1)
+        for a in sum.attributes:
+            self.emit("value = ast2obj_%s(o->%s);" % (a.type, a.name), 1)
+            self.emit("if (!value) goto failed;", 1)
+            self.emit('if (PyObject_SetAttrString(result, "%s", value) < 0)' % a.name, 1)
+            self.emit('goto failed;', 2)
+            self.emit('Py_DECREF(value);', 1)
+        self.func_end()
+
+    def simpleSum(self, sum, name):
+        self.emit("PyObject* ast2obj_%s(%s_ty o)" % (name, name), 0)
+        self.emit("{", 0)
+        self.emit("switch(o) {", 1)
+        for t in sum.types:
+            self.emit("case %s:" % t.name, 2)
+            self.emit("Py_INCREF(%s_singleton);" % t.name, 3)
+            self.emit("return %s_singleton;" % t.name, 3)
+        self.emit("}", 1)
+        self.emit("return NULL; /* cannot happen */", 1)
+        self.emit("}", 0)
+
+    def visitProduct(self, prod, name):
+        self.func_begin(name)
+        self.emit("result = PyType_GenericNew(%s_type, NULL, NULL);" % name, 1);
+        self.emit("if (!result) return NULL;", 1)
+        for field in prod.fields:
+            self.visitField(field, name, 1, True)
+        self.func_end()
+
+    def visitConstructor(self, cons, enum, name):
+        self.emit("case %s_kind:" % cons.name, 1)
+        self.emit("result = PyType_GenericNew(%s_type, NULL, NULL);" % cons.name, 2);
+        self.emit("if (!result) goto failed;", 2)
+        for f in cons.fields:
+            self.visitField(f, cons.name, 2, False)
+        self.emit("break;", 2)
+
+    def visitField(self, field, name, depth, product):
+        def emit(s, d):
+            self.emit(s, depth + d)
+        if product:
+            value = "o->%s" % field.name
+        else:
+            value = "o->v.%s.%s" % (name, field.name)
+        self.set(field, value, depth)
+        emit("if (!value) goto failed;", 0)
+        emit('if (PyObject_SetAttrString(result, "%s", value) == -1)' % field.name, 0)
+        emit("goto failed;", 1)
+        emit("Py_DECREF(value);", 0)
+
+    def emitSeq(self, field, value, depth, emit):
+        emit("seq = %s;" % value, 0)
+        emit("n = asdl_seq_LEN(seq);", 0)
+        emit("value = PyList_New(n);", 0)
+        emit("if (!value) goto failed;", 0)
+        emit("for (i = 0; i < n; i++) {", 0)
+        self.set("value", field, "asdl_seq_GET(seq, i)", depth + 1)
+        emit("if (!value1) goto failed;", 1)
+        emit("PyList_SET_ITEM(value, i, value1);", 1)
+        emit("value1 = NULL;", 1)
+        emit("}", 0)
+
+    def set(self, field, value, depth):
+        if field.seq:
+            # XXX should really check for is_simple, but that requires a symbol table
+            if field.type.value == "cmpop":
+                # While the sequence elements are stored as void*,
+                # ast2obj_cmpop expects an enum
+                self.emit("{", depth)
+                self.emit("int i, n = asdl_seq_LEN(%s);" % value, depth+1)
+                self.emit("value = PyList_New(n);", depth+1)
+                self.emit("if (!value) goto failed;", depth+1)
+                self.emit("for(i = 0; i < n; i++)", depth+1)
+                # This cannot fail, so no need for error handling
+                self.emit("PyList_SET_ITEM(value, i, ast2obj_cmpop((cmpop_ty)asdl_seq_GET(%s, i)));" % value,
+                          depth+2, reflow=False)
+                self.emit("}", depth)
+            else:
+                self.emit("value = ast2obj_list(%s, ast2obj_%s);" % (value, field.type), depth)
+        else:
+            ctype = get_c_type(field.type)
+            self.emit("value = ast2obj_%s(%s);" % (field.type, value), depth, reflow=False)
+
+
+class PartingShots(StaticVisitor):
+
+    CODE = """
+PyObject* PyAST_mod2obj(mod_ty t)
+{
+    init_types();
+    return ast2obj_mod(t);
+}
+"""
+
+class ChainOfVisitors:
+    def __init__(self, *visitors):
+        self.visitors = visitors
+
+    def visit(self, object):
+        for v in self.visitors:
+            v.visit(object)
+            v.emit("", 0)
+
+def main(srcfile):
+    argv0 = sys.argv[0]
+    components = argv0.split(os.sep)
+    argv0 = os.sep.join(components[-2:])
+    auto_gen_msg = '/* File automatically generated by %s */\n' % argv0
+    mod = asdl.parse(srcfile)
+    if not asdl.check(mod):
+        sys.exit(1)
+    if INC_DIR:
+        p = "%s/%s-ast.h" % (INC_DIR, mod.name)
+        f = open(p, "wb")
+        print >> f, auto_gen_msg
+        print >> f, '#include "asdl.h"\n'
+        c = ChainOfVisitors(TypeDefVisitor(f),
+                            StructVisitor(f),
+                            PrototypeVisitor(f),
+                            )
+        c.visit(mod)
+        print >>f, "PyObject* PyAST_mod2obj(mod_ty t);"
+        f.close()
+
+    if SRC_DIR:
+        p = os.path.join(SRC_DIR, str(mod.name) + "-ast.c")
+        f = open(p, "wb")
+        print >> f, auto_gen_msg
+        print >> f, '#include "Python.h"'
+        print >> f, '#include "%s-ast.h"' % mod.name
+        print >> f
+        print >>f, "static PyTypeObject* AST_type;"
+        v = ChainOfVisitors(
+            PyTypesDeclareVisitor(f),
+            PyTypesVisitor(f),
+            FunctionVisitor(f),
+            ObjVisitor(f),
+            ASTModuleVisitor(f),
+            PartingShots(f),
+            )
+        v.visit(mod)
+        f.close()
+
+if __name__ == "__main__":
+    import sys
+    import getopt
+
+    INC_DIR = ''
+    SRC_DIR = ''
+    opts, args = getopt.getopt(sys.argv[1:], "h:c:")
+    if len(opts) != 1:
+        print "Must specify exactly one output file"
+        sys.exit(1)
+    for o, v in opts:
+        if o == '-h':
+            INC_DIR = v
+        if o == '-c':
+            SRC_DIR = v
+    if len(args) != 1:
+        print "Must specify single input file"
+        sys.exit(1)
+    main(args[0])


Property changes on: vendor/Python/current/Parser/asdl_c.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Parser/bitset.c
===================================================================
--- vendor/Python/current/Parser/bitset.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Parser/bitset.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,66 @@
+
+/* Bitset primitives used by the parser generator */
+
+#include "pgenheaders.h"
+#include "bitset.h"
+
+bitset
+newbitset(int nbits)
+{
+	int nbytes = NBYTES(nbits);
+	bitset ss = (char *)PyObject_MALLOC(sizeof(BYTE) *  nbytes);
+	
+	if (ss == NULL)
+		Py_FatalError("no mem for bitset");
+	
+	ss += nbytes;
+	while (--nbytes >= 0)
+		*--ss = 0;
+	return ss;
+}
+
+void
+delbitset(bitset ss)
+{
+	PyObject_FREE(ss);
+}
+
+int
+addbit(bitset ss, int ibit)
+{
+	int ibyte = BIT2BYTE(ibit);
+	BYTE mask = BIT2MASK(ibit);
+	
+	if (ss[ibyte] & mask)
+		return 0; /* Bit already set */
+	ss[ibyte] |= mask;
+	return 1;
+}
+
+#if 0 /* Now a macro */
+int
+testbit(bitset ss, int ibit)
+{
+	return (ss[BIT2BYTE(ibit)] & BIT2MASK(ibit)) != 0;
+}
+#endif
+
+int
+samebitset(bitset ss1, bitset ss2, int nbits)
+{
+	int i;
+	
+	for (i = NBYTES(nbits); --i >= 0; )
+		if (*ss1++ != *ss2++)
+			return 0;
+	return 1;
+}
+
+void
+mergebitset(bitset ss1, bitset ss2, int nbits)
+{
+	int i;
+	
+	for (i = NBYTES(nbits); --i >= 0; )
+		*ss1++ |= *ss2++;
+}

Added: vendor/Python/current/Parser/firstsets.c
===================================================================
--- vendor/Python/current/Parser/firstsets.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Parser/firstsets.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,113 @@
+
+/* Computation of FIRST stets */
+
+#include "pgenheaders.h"
+#include "grammar.h"
+#include "token.h"
+
+extern int Py_DebugFlag;
+
+/* Forward */
+static void calcfirstset(grammar *, dfa *);
+
+void
+addfirstsets(grammar *g)
+{
+	int i;
+	dfa *d;
+
+	if (Py_DebugFlag)
+		printf("Adding FIRST sets ...\n");
+	for (i = 0; i < g->g_ndfas; i++) {
+		d = &g->g_dfa[i];
+		if (d->d_first == NULL)
+			calcfirstset(g, d);
+	}
+}
+
+static void
+calcfirstset(grammar *g, dfa *d)
+{
+	int i, j;
+	state *s;
+	arc *a;
+	int nsyms;
+	int *sym;
+	int nbits;
+	static bitset dummy;
+	bitset result;
+	int type;
+	dfa *d1;
+	label *l0;
+	
+	if (Py_DebugFlag)
+		printf("Calculate FIRST set for '%s'\n", d->d_name);
+	
+	if (dummy == NULL)
+		dummy = newbitset(1);
+	if (d->d_first == dummy) {
+		fprintf(stderr, "Left-recursion for '%s'\n", d->d_name);
+		return;
+	}
+	if (d->d_first != NULL) {
+		fprintf(stderr, "Re-calculating FIRST set for '%s' ???\n",
+			d->d_name);
+	}
+	d->d_first = dummy;
+	
+	l0 = g->g_ll.ll_label;
+	nbits = g->g_ll.ll_nlabels;
+	result = newbitset(nbits);
+	
+	sym = (int *)PyObject_MALLOC(sizeof(int));
+	if (sym == NULL)
+		Py_FatalError("no mem for new sym in calcfirstset");
+	nsyms = 1;
+	sym[0] = findlabel(&g->g_ll, d->d_type, (char *)NULL);
+	
+	s = &d->d_state[d->d_initial];
+	for (i = 0; i < s->s_narcs; i++) {
+		a = &s->s_arc[i];
+		for (j = 0; j < nsyms; j++) {
+			if (sym[j] == a->a_lbl)
+				break;
+		}
+		if (j >= nsyms) { /* New label */
+			sym = (int *)PyObject_REALLOC(sym, 
+                                                sizeof(int) * (nsyms + 1));
+			if (sym == NULL)
+				Py_FatalError(
+				    "no mem to resize sym in calcfirstset");
+			sym[nsyms++] = a->a_lbl;
+			type = l0[a->a_lbl].lb_type;
+			if (ISNONTERMINAL(type)) {
+				d1 = PyGrammar_FindDFA(g, type);
+				if (d1->d_first == dummy) {
+					fprintf(stderr,
+						"Left-recursion below '%s'\n",
+						d->d_name);
+				}
+				else {
+					if (d1->d_first == NULL)
+						calcfirstset(g, d1);
+					mergebitset(result,
+						    d1->d_first, nbits);
+				}
+			}
+			else if (ISTERMINAL(type)) {
+				addbit(result, a->a_lbl);
+			}
+		}
+	}
+	d->d_first = result;
+	if (Py_DebugFlag) {
+		printf("FIRST set for '%s': {", d->d_name);
+		for (i = 0; i < nbits; i++) {
+			if (testbit(result, i))
+				printf(" %s", PyGrammar_LabelRepr(&l0[i]));
+		}
+		printf(" }\n");
+	}
+
+	PyObject_FREE(sym);
+}

Added: vendor/Python/current/Parser/grammar.c
===================================================================
--- vendor/Python/current/Parser/grammar.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Parser/grammar.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,254 @@
+
+/* Grammar implementation */
+
+#include "Python.h"
+#include "pgenheaders.h"
+
+#include <ctype.h>
+
+#include "token.h"
+#include "grammar.h"
+
+#ifdef RISCOS
+#include <unixlib.h>
+#endif
+
+extern int Py_DebugFlag;
+
+grammar *
+newgrammar(int start)
+{
+	grammar *g;
+	
+	g = (grammar *)PyObject_MALLOC(sizeof(grammar));
+	if (g == NULL)
+		Py_FatalError("no mem for new grammar");
+	g->g_ndfas = 0;
+	g->g_dfa = NULL;
+	g->g_start = start;
+	g->g_ll.ll_nlabels = 0;
+	g->g_ll.ll_label = NULL;
+	g->g_accel = 0;
+	return g;
+}
+
+dfa *
+adddfa(grammar *g, int type, char *name)
+{
+	dfa *d;
+	
+	g->g_dfa = (dfa *)PyObject_REALLOC(g->g_dfa, 
+                                            sizeof(dfa) * (g->g_ndfas + 1));
+	if (g->g_dfa == NULL)
+		Py_FatalError("no mem to resize dfa in adddfa");
+	d = &g->g_dfa[g->g_ndfas++];
+	d->d_type = type;
+	d->d_name = strdup(name);
+	d->d_nstates = 0;
+	d->d_state = NULL;
+	d->d_initial = -1;
+	d->d_first = NULL;
+	return d; /* Only use while fresh! */
+}
+
+int
+addstate(dfa *d)
+{
+	state *s;
+	
+	d->d_state = (state *)PyObject_REALLOC(d->d_state,
+				      sizeof(state) * (d->d_nstates + 1));
+	if (d->d_state == NULL)
+		Py_FatalError("no mem to resize state in addstate");
+	s = &d->d_state[d->d_nstates++];
+	s->s_narcs = 0;
+	s->s_arc = NULL;
+	s->s_lower = 0;
+	s->s_upper = 0;
+	s->s_accel = NULL;
+	s->s_accept = 0;
+	return s - d->d_state;
+}
+
+void
+addarc(dfa *d, int from, int to, int lbl)
+{
+	state *s;
+	arc *a;
+	
+	assert(0 <= from && from < d->d_nstates);
+	assert(0 <= to && to < d->d_nstates);
+	
+	s = &d->d_state[from];
+	s->s_arc = (arc *)PyObject_REALLOC(s->s_arc, sizeof(arc) * (s->s_narcs + 1));
+	if (s->s_arc == NULL)
+		Py_FatalError("no mem to resize arc list in addarc");
+	a = &s->s_arc[s->s_narcs++];
+	a->a_lbl = lbl;
+	a->a_arrow = to;
+}
+
+int
+addlabel(labellist *ll, int type, char *str)
+{
+	int i;
+	label *lb;
+	
+	for (i = 0; i < ll->ll_nlabels; i++) {
+		if (ll->ll_label[i].lb_type == type &&
+			strcmp(ll->ll_label[i].lb_str, str) == 0)
+			return i;
+	}
+	ll->ll_label = (label *)PyObject_REALLOC(ll->ll_label,
+					sizeof(label) * (ll->ll_nlabels + 1));
+	if (ll->ll_label == NULL)
+		Py_FatalError("no mem to resize labellist in addlabel");
+	lb = &ll->ll_label[ll->ll_nlabels++];
+	lb->lb_type = type;
+	lb->lb_str = strdup(str);
+	if (Py_DebugFlag)
+		printf("Label @ %8p, %d: %s\n", ll, ll->ll_nlabels,
+		       PyGrammar_LabelRepr(lb));
+	return lb - ll->ll_label;
+}
+
+/* Same, but rather dies than adds */
+
+int
+findlabel(labellist *ll, int type, char *str)
+{
+	int i;
+	
+	for (i = 0; i < ll->ll_nlabels; i++) {
+		if (ll->ll_label[i].lb_type == type /*&&
+			strcmp(ll->ll_label[i].lb_str, str) == 0*/)
+			return i;
+	}
+	fprintf(stderr, "Label %d/'%s' not found\n", type, str);
+	Py_FatalError("grammar.c:findlabel()");
+	return 0; /* Make gcc -Wall happy */
+}
+
+/* Forward */
+static void translabel(grammar *, label *);
+
+void
+translatelabels(grammar *g)
+{
+	int i;
+
+#ifdef Py_DEBUG
+	printf("Translating labels ...\n");
+#endif
+	/* Don't translate EMPTY */
+	for (i = EMPTY+1; i < g->g_ll.ll_nlabels; i++)
+		translabel(g, &g->g_ll.ll_label[i]);
+}
+
+static void
+translabel(grammar *g, label *lb)
+{
+	int i;
+	
+	if (Py_DebugFlag)
+		printf("Translating label %s ...\n", PyGrammar_LabelRepr(lb));
+	
+	if (lb->lb_type == NAME) {
+		for (i = 0; i < g->g_ndfas; i++) {
+			if (strcmp(lb->lb_str, g->g_dfa[i].d_name) == 0) {
+				if (Py_DebugFlag)
+					printf(
+					    "Label %s is non-terminal %d.\n",
+					    lb->lb_str,
+					    g->g_dfa[i].d_type);
+				lb->lb_type = g->g_dfa[i].d_type;
+				free(lb->lb_str);
+				lb->lb_str = NULL;
+				return;
+			}
+		}
+		for (i = 0; i < (int)N_TOKENS; i++) {
+			if (strcmp(lb->lb_str, _PyParser_TokenNames[i]) == 0) {
+				if (Py_DebugFlag)
+					printf("Label %s is terminal %d.\n",
+						lb->lb_str, i);
+				lb->lb_type = i;
+				free(lb->lb_str);
+				lb->lb_str = NULL;
+				return;
+			}
+		}
+		printf("Can't translate NAME label '%s'\n", lb->lb_str);
+		return;
+	}
+	
+	if (lb->lb_type == STRING) {
+		if (isalpha(Py_CHARMASK(lb->lb_str[1])) ||
+		    lb->lb_str[1] == '_') {
+			char *p;
+			char *src;
+			char *dest;
+			size_t name_len;
+			if (Py_DebugFlag)
+				printf("Label %s is a keyword\n", lb->lb_str);
+			lb->lb_type = NAME;
+			src = lb->lb_str + 1;
+			p = strchr(src, '\'');
+			if (p)
+				name_len = p - src;
+			else
+				name_len = strlen(src);
+			dest = (char *)malloc(name_len + 1);
+			if (!dest) {
+				printf("Can't alloc dest '%s'\n", src);
+				return;
+			}
+			strncpy(dest, src, name_len);
+			dest[name_len] = '\0';
+			free(lb->lb_str);
+			lb->lb_str = dest;
+		}
+		else if (lb->lb_str[2] == lb->lb_str[0]) {
+			int type = (int) PyToken_OneChar(lb->lb_str[1]);
+			if (type != OP) {
+				lb->lb_type = type;
+				free(lb->lb_str);
+				lb->lb_str = NULL;
+			}
+			else
+				printf("Unknown OP label %s\n",
+					lb->lb_str);
+		}
+		else if (lb->lb_str[2] && lb->lb_str[3] == lb->lb_str[0]) {
+			int type = (int) PyToken_TwoChars(lb->lb_str[1],
+						   lb->lb_str[2]);
+			if (type != OP) {
+				lb->lb_type = type;
+				free(lb->lb_str);
+				lb->lb_str = NULL;
+			}
+			else
+				printf("Unknown OP label %s\n",
+					lb->lb_str);
+		}
+		else if (lb->lb_str[2] && lb->lb_str[3] && lb->lb_str[4] == lb->lb_str[0]) {
+			int type = (int) PyToken_ThreeChars(lb->lb_str[1],
+							    lb->lb_str[2],
+							    lb->lb_str[3]);
+			if (type != OP) {
+				lb->lb_type = type;
+				free(lb->lb_str);
+				lb->lb_str = NULL;
+			}
+			else
+				printf("Unknown OP label %s\n",
+					lb->lb_str);
+		}
+		else
+			printf("Can't translate STRING label %s\n",
+				lb->lb_str);
+	}
+	else
+		printf("Can't translate label '%s'\n",
+		       PyGrammar_LabelRepr(lb));
+}

Added: vendor/Python/current/Parser/grammar.mak
===================================================================
--- vendor/Python/current/Parser/grammar.mak	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Parser/grammar.mak	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,45 @@
+# This manages to rebuild graminit.{h, c} under MSVC 6 (Windows), via
+#
+#     nmake /f grammar.mak
+#
+# You may also need to copy python23.dll into this directory, or get
+# it on your search path.
+#
+# The intermediate files can be nuked afterwards:
+#
+#     nmake /f grammar.mak clean
+#
+# I don't understand the maze of preprocessor #define's on Windows, and
+# as a result this requires linking with python23.lib, so it's of no use
+# for bootstrapping (the cause appears to be a useless-- in this
+# particular case --pragma in PC\pyconfig.h, which demands that
+# python23.lib get linked in).
+
+LIBS= ..\PCbuild\python25.lib
+
+CFLAGS= /I ..\Include /I ..\PC /D MS_NO_COREDLL /D PGEN /MD
+
+GRAMMAR_H= ..\Include\graminit.h
+GRAMMAR_C= ..\Python\graminit.c
+GRAMMAR_INPUT= ..\Grammar\Grammar
+
+PGEN= pgen.exe
+
+POBJS= acceler.obj grammar1.obj listnode.obj node.obj parser.obj \
+       parsetok.obj tokenizer.obj bitset.obj metagrammar.obj
+
+PARSER_OBJS= $(POBJS) myreadline.obj
+
+PGOBJS= firstsets.obj grammar.obj pgen.obj printgrammar.obj pgenmain.obj
+
+PGENOBJS= $(POBJS) $(PGOBJS)
+
+$(GRAMMAR_H) $(GRAMMAR_C): $(PGEN) $(GRAMMAR_INPUT)
+		$(PGEN) $(GRAMMAR_INPUT) $(GRAMMAR_H) $(GRAMMAR_C)
+
+$(PGEN):	$(PGENOBJS)
+		$(CC) $(PGENOBJS) $(LIBS) /Fe$(PGEN)
+
+clean:
+        del *.obj
+        del $(PGEN)

Added: vendor/Python/current/Parser/grammar1.c
===================================================================
--- vendor/Python/current/Parser/grammar1.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Parser/grammar1.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,57 @@
+
+/* Grammar subroutines needed by parser */
+
+#include "Python.h"
+#include "pgenheaders.h"
+#include "grammar.h"
+#include "token.h"
+
+/* Return the DFA for the given type */
+
+dfa *
+PyGrammar_FindDFA(grammar *g, register int type)
+{
+	register dfa *d;
+#if 1
+	/* Massive speed-up */
+	d = &g->g_dfa[type - NT_OFFSET];
+	assert(d->d_type == type);
+	return d;
+#else
+	/* Old, slow version */
+	register int i;
+	
+	for (i = g->g_ndfas, d = g->g_dfa; --i >= 0; d++) {
+		if (d->d_type == type)
+			return d;
+	}
+	assert(0);
+	/* NOTREACHED */
+#endif
+}
+
+char *
+PyGrammar_LabelRepr(label *lb)
+{
+	static char buf[100];
+	
+	if (lb->lb_type == ENDMARKER)
+		return "EMPTY";
+	else if (ISNONTERMINAL(lb->lb_type)) {
+		if (lb->lb_str == NULL) {
+			PyOS_snprintf(buf, sizeof(buf), "NT%d", lb->lb_type);
+			return buf;
+		}
+		else
+			return lb->lb_str;
+	}
+	else {
+		if (lb->lb_str == NULL)
+			return _PyParser_TokenNames[lb->lb_type];
+		else {
+			PyOS_snprintf(buf, sizeof(buf), "%.32s(%.32s)",
+				_PyParser_TokenNames[lb->lb_type], lb->lb_str);
+			return buf;
+		}
+	}
+}

Added: vendor/Python/current/Parser/intrcheck.c
===================================================================
--- vendor/Python/current/Parser/intrcheck.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Parser/intrcheck.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,176 @@
+
+/* Check for interrupts */
+
+#include "Python.h"
+
+#ifdef QUICKWIN
+
+#include <io.h>
+
+void
+PyOS_InitInterrupts(void)
+{
+}
+
+void
+PyOS_FiniInterrupts(void)
+{
+}
+
+int
+PyOS_InterruptOccurred(void)
+{
+	_wyield();
+}
+
+#define OK
+
+#endif /* QUICKWIN */
+
+#if defined(_M_IX86) && !defined(__QNX__)
+#include <io.h>
+#endif
+
+#if defined(MSDOS) && !defined(QUICKWIN)
+
+#ifdef __GNUC__
+
+/* This is for DJGPP's GO32 extender.  I don't know how to trap
+ * control-C  (There's no API for ctrl-C, and I don't want to mess with
+ * the interrupt vectors.)  However, this DOES catch control-break.
+ * --Amrit
+ */
+
+#include <go32.h>
+
+void
+PyOS_InitInterrupts(void)
+{
+	_go32_want_ctrl_break(1 /* TRUE */);
+}
+
+void
+PyOS_FiniInterrupts(void)
+{
+}
+
+int
+PyOS_InterruptOccurred(void)
+{
+	return _go32_was_ctrl_break_hit();
+}
+
+#else /* !__GNUC__ */
+
+/* This might work for MS-DOS (untested though): */
+
+void
+PyOS_InitInterrupts(void)
+{
+}
+
+void
+PyOS_FiniInterrupts(void)
+{
+}
+
+int
+PyOS_InterruptOccurred(void)
+{
+	int interrupted = 0;
+	while (kbhit()) {
+		if (getch() == '\003')
+			interrupted = 1;
+	}
+	return interrupted;
+}
+
+#endif /* __GNUC__ */
+
+#define OK
+
+#endif /* MSDOS && !QUICKWIN */
+
+
+#ifndef OK
+
+/* Default version -- for real operating systems and for Standard C */
+
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+
+static int interrupted;
+
+void
+PyErr_SetInterrupt(void)
+{
+	interrupted = 1;
+}
+
+extern int PyErr_CheckSignals(void);
+
+static int
+checksignals_witharg(void * arg)
+{
+	return PyErr_CheckSignals();
+}
+
+static void
+intcatcher(int sig)
+{
+	extern void Py_Exit(int);
+	static char message[] =
+"python: to interrupt a truly hanging Python program, interrupt once more.\n";
+	switch (interrupted++) {
+	case 0:
+		break;
+	case 1:
+#ifdef RISCOS
+		fprintf(stderr, message);
+#else
+		write(2, message, strlen(message));
+#endif
+		break;
+	case 2:
+		interrupted = 0;
+		Py_Exit(1);
+		break;
+	}
+	PyOS_setsig(SIGINT, intcatcher);
+	Py_AddPendingCall(checksignals_witharg, NULL);
+}
+
+static void (*old_siginthandler)(int) = SIG_DFL;
+
+void
+PyOS_InitInterrupts(void)
+{
+	if ((old_siginthandler = PyOS_setsig(SIGINT, SIG_IGN)) != SIG_IGN)
+		PyOS_setsig(SIGINT, intcatcher);
+}
+
+void
+PyOS_FiniInterrupts(void)
+{
+	PyOS_setsig(SIGINT, old_siginthandler);
+}
+
+int
+PyOS_InterruptOccurred(void)
+{
+	if (!interrupted)
+		return 0;
+	interrupted = 0;
+	return 1;
+}
+
+#endif /* !OK */
+
+void
+PyOS_AfterFork(void)
+{
+#ifdef WITH_THREAD
+	PyEval_ReInitThreads();
+#endif
+}

Added: vendor/Python/current/Parser/listnode.c
===================================================================
--- vendor/Python/current/Parser/listnode.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Parser/listnode.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,66 @@
+
+/* List a node on a file */
+
+#include "pgenheaders.h"
+#include "token.h"
+#include "node.h"
+
+/* Forward */
+static void list1node(FILE *, node *);
+static void listnode(FILE *, node *);
+
+void
+PyNode_ListTree(node *n)
+{
+	listnode(stdout, n);
+}
+
+static int level, atbol;
+
+static void
+listnode(FILE *fp, node *n)
+{
+	level = 0;
+	atbol = 1;
+	list1node(fp, n);
+}
+
+static void
+list1node(FILE *fp, node *n)
+{
+	if (n == 0)
+		return;
+	if (ISNONTERMINAL(TYPE(n))) {
+		int i;
+		for (i = 0; i < NCH(n); i++)
+			list1node(fp, CHILD(n, i));
+	}
+	else if (ISTERMINAL(TYPE(n))) {
+		switch (TYPE(n)) {
+		case INDENT:
+			++level;
+			break;
+		case DEDENT:
+			--level;
+			break;
+		default:
+			if (atbol) {
+				int i;
+				for (i = 0; i < level; ++i)
+					fprintf(fp, "\t");
+				atbol = 0;
+			}
+			if (TYPE(n) == NEWLINE) {
+				if (STR(n) != NULL)
+					fprintf(fp, "%s", STR(n));
+				fprintf(fp, "\n");
+				atbol = 1;
+			}
+			else
+				fprintf(fp, "%s ", STR(n));
+			break;
+		}
+	}
+	else
+		fprintf(fp, "? ");
+}

Added: vendor/Python/current/Parser/metagrammar.c
===================================================================
--- vendor/Python/current/Parser/metagrammar.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Parser/metagrammar.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,159 @@
+
+#include "pgenheaders.h"
+#include "metagrammar.h"
+#include "grammar.h"
+#include "pgen.h"
+static arc arcs_0_0[3] = {
+	{2, 0},
+	{3, 0},
+	{4, 1},
+};
+static arc arcs_0_1[1] = {
+	{0, 1},
+};
+static state states_0[2] = {
+	{3, arcs_0_0},
+	{1, arcs_0_1},
+};
+static arc arcs_1_0[1] = {
+	{5, 1},
+};
+static arc arcs_1_1[1] = {
+	{6, 2},
+};
+static arc arcs_1_2[1] = {
+	{7, 3},
+};
+static arc arcs_1_3[1] = {
+	{3, 4},
+};
+static arc arcs_1_4[1] = {
+	{0, 4},
+};
+static state states_1[5] = {
+	{1, arcs_1_0},
+	{1, arcs_1_1},
+	{1, arcs_1_2},
+	{1, arcs_1_3},
+	{1, arcs_1_4},
+};
+static arc arcs_2_0[1] = {
+	{8, 1},
+};
+static arc arcs_2_1[2] = {
+	{9, 0},
+	{0, 1},
+};
+static state states_2[2] = {
+	{1, arcs_2_0},
+	{2, arcs_2_1},
+};
+static arc arcs_3_0[1] = {
+	{10, 1},
+};
+static arc arcs_3_1[2] = {
+	{10, 1},
+	{0, 1},
+};
+static state states_3[2] = {
+	{1, arcs_3_0},
+	{2, arcs_3_1},
+};
+static arc arcs_4_0[2] = {
+	{11, 1},
+	{13, 2},
+};
+static arc arcs_4_1[1] = {
+	{7, 3},
+};
+static arc arcs_4_2[3] = {
+	{14, 4},
+	{15, 4},
+	{0, 2},
+};
+static arc arcs_4_3[1] = {
+	{12, 4},
+};
+static arc arcs_4_4[1] = {
+	{0, 4},
+};
+static state states_4[5] = {
+	{2, arcs_4_0},
+	{1, arcs_4_1},
+	{3, arcs_4_2},
+	{1, arcs_4_3},
+	{1, arcs_4_4},
+};
+static arc arcs_5_0[3] = {
+	{5, 1},
+	{16, 1},
+	{17, 2},
+};
+static arc arcs_5_1[1] = {
+	{0, 1},
+};
+static arc arcs_5_2[1] = {
+	{7, 3},
+};
+static arc arcs_5_3[1] = {
+	{18, 1},
+};
+static state states_5[4] = {
+	{3, arcs_5_0},
+	{1, arcs_5_1},
+	{1, arcs_5_2},
+	{1, arcs_5_3},
+};
+static dfa dfas[6] = {
+	{256, "MSTART", 0, 2, states_0,
+	 "\070\000\000"},
+	{257, "RULE", 0, 5, states_1,
+	 "\040\000\000"},
+	{258, "RHS", 0, 2, states_2,
+	 "\040\010\003"},
+	{259, "ALT", 0, 2, states_3,
+	 "\040\010\003"},
+	{260, "ITEM", 0, 5, states_4,
+	 "\040\010\003"},
+	{261, "ATOM", 0, 4, states_5,
+	 "\040\000\003"},
+};
+static label labels[19] = {
+	{0, "EMPTY"},
+	{256, 0},
+	{257, 0},
+	{4, 0},
+	{0, 0},
+	{1, 0},
+	{11, 0},
+	{258, 0},
+	{259, 0},
+	{18, 0},
+	{260, 0},
+	{9, 0},
+	{10, 0},
+	{261, 0},
+	{16, 0},
+	{14, 0},
+	{3, 0},
+	{7, 0},
+	{8, 0},
+};
+static grammar _PyParser_Grammar = {
+	6,
+	dfas,
+	{19, labels},
+	256
+};
+
+grammar *
+meta_grammar(void)
+{
+	return &_PyParser_Grammar;
+}
+
+grammar *
+Py_meta_grammar(void)
+{
+  return meta_grammar();
+}

Added: vendor/Python/current/Parser/myreadline.c
===================================================================
--- vendor/Python/current/Parser/myreadline.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Parser/myreadline.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,219 @@
+
+/* Readline interface for tokenizer.c and [raw_]input() in bltinmodule.c.
+   By default, or when stdin is not a tty device, we have a super
+   simple my_readline function using fgets.
+   Optionally, we can use the GNU readline library.
+   my_readline() has a different return value from GNU readline():
+   - NULL if an interrupt occurred or if an error occurred
+   - a malloc'ed empty string if EOF was read
+   - a malloc'ed string ending in \n normally
+*/
+
+#include "Python.h"
+#ifdef MS_WINDOWS
+#define WIN32_LEAN_AND_MEAN
+#include "windows.h"
+#endif /* MS_WINDOWS */
+
+#ifdef __VMS
+extern char* vms__StdioReadline(FILE *sys_stdin, FILE *sys_stdout, char *prompt);
+#endif
+
+
+PyThreadState* _PyOS_ReadlineTState;
+
+#ifdef WITH_THREAD
+#include "pythread.h"
+static PyThread_type_lock _PyOS_ReadlineLock = NULL;
+#endif
+
+int (*PyOS_InputHook)(void) = NULL;
+
+#ifdef RISCOS
+int Py_RISCOSWimpFlag;
+#endif
+
+/* This function restarts a fgets() after an EINTR error occurred
+   except if PyOS_InterruptOccurred() returns true. */
+
+static int
+my_fgets(char *buf, int len, FILE *fp)
+{
+	char *p;
+	for (;;) {
+		if (PyOS_InputHook != NULL)
+			(void)(PyOS_InputHook)();
+		errno = 0;
+		p = fgets(buf, len, fp);
+		if (p != NULL)
+			return 0; /* No error */
+#ifdef MS_WINDOWS
+		/* In the case of a Ctrl+C or some other external event 
+		   interrupting the operation:
+		   Win2k/NT: ERROR_OPERATION_ABORTED is the most recent Win32 
+		   error code (and feof() returns TRUE).
+		   Win9x: Ctrl+C seems to have no effect on fgets() returning
+		   early - the signal handler is called, but the fgets()
+		   only returns "normally" (ie, when Enter hit or feof())
+		*/
+		if (GetLastError()==ERROR_OPERATION_ABORTED) {
+			/* Signals come asynchronously, so we sleep a brief 
+			   moment before checking if the handler has been 
+			   triggered (we cant just return 1 before the 
+			   signal handler has been called, as the later 
+			   signal may be treated as a separate interrupt).
+			*/
+			Sleep(1);
+			if (PyOS_InterruptOccurred()) {
+				return 1; /* Interrupt */
+			}
+			/* Either the sleep wasn't long enough (need a
+			   short loop retrying?) or not interrupted at all
+			   (in which case we should revisit the whole thing!)
+			   Logging some warning would be nice.  assert is not
+			   viable as under the debugger, the various dialogs
+			   mean the condition is not true.
+			*/
+		}
+#endif /* MS_WINDOWS */
+		if (feof(fp)) {
+			return -1; /* EOF */
+		}
+#ifdef EINTR
+		if (errno == EINTR) {
+			int s;
+#ifdef WITH_THREAD
+			PyEval_RestoreThread(_PyOS_ReadlineTState);
+#endif
+			s = PyErr_CheckSignals();
+#ifdef WITH_THREAD
+			PyEval_SaveThread();
+#endif
+			if (s < 0) {
+				return 1;
+			}
+		}
+#endif
+		if (PyOS_InterruptOccurred()) {
+			return 1; /* Interrupt */
+		}
+		return -2; /* Error */
+	}
+	/* NOTREACHED */
+}
+
+
+/* Readline implementation using fgets() */
+
+char *
+PyOS_StdioReadline(FILE *sys_stdin, FILE *sys_stdout, char *prompt)
+{
+	size_t n;
+	char *p;
+	n = 100;
+	if ((p = (char *)PyMem_MALLOC(n)) == NULL)
+		return NULL;
+	fflush(sys_stdout);
+#ifndef RISCOS
+	if (prompt)
+		fprintf(stderr, "%s", prompt);
+#else
+	if (prompt) {
+		if(Py_RISCOSWimpFlag)
+			fprintf(stderr, "\x0cr%s\x0c", prompt);
+		else
+			fprintf(stderr, "%s", prompt);
+	}
+#endif
+	fflush(stderr);
+	switch (my_fgets(p, (int)n, sys_stdin)) {
+	case 0: /* Normal case */
+		break;
+	case 1: /* Interrupt */
+		PyMem_FREE(p);
+		return NULL;
+	case -1: /* EOF */
+	case -2: /* Error */
+	default: /* Shouldn't happen */
+		*p = '\0';
+		break;
+	}
+	n = strlen(p);
+	while (n > 0 && p[n-1] != '\n') {
+		size_t incr = n+2;
+		p = (char *)PyMem_REALLOC(p, n + incr);
+		if (p == NULL)
+			return NULL;
+		if (incr > INT_MAX) {
+			PyErr_SetString(PyExc_OverflowError, "input line too long");
+		}
+		if (my_fgets(p+n, (int)incr, sys_stdin) != 0)
+			break;
+		n += strlen(p+n);
+	}
+	return (char *)PyMem_REALLOC(p, n+1);
+}
+
+
+/* By initializing this function pointer, systems embedding Python can
+   override the readline function.
+
+   Note: Python expects in return a buffer allocated with PyMem_Malloc. */
+
+char *(*PyOS_ReadlineFunctionPointer)(FILE *, FILE *, char *);
+
+
+/* Interface used by tokenizer.c and bltinmodule.c */
+
+char *
+PyOS_Readline(FILE *sys_stdin, FILE *sys_stdout, char *prompt)
+{
+	char *rv;
+
+	if (_PyOS_ReadlineTState == PyThreadState_GET()) {
+		PyErr_SetString(PyExc_RuntimeError,
+				"can't re-enter readline");
+		return NULL;
+	}
+	
+
+	if (PyOS_ReadlineFunctionPointer == NULL) {
+#ifdef __VMS
+                PyOS_ReadlineFunctionPointer = vms__StdioReadline;
+#else
+                PyOS_ReadlineFunctionPointer = PyOS_StdioReadline;
+#endif
+	}
+	
+#ifdef WITH_THREAD
+	if (_PyOS_ReadlineLock == NULL) {
+		_PyOS_ReadlineLock = PyThread_allocate_lock();		
+	}
+#endif
+
+	_PyOS_ReadlineTState = PyThreadState_GET();
+	Py_BEGIN_ALLOW_THREADS
+#ifdef WITH_THREAD
+	PyThread_acquire_lock(_PyOS_ReadlineLock, 1);
+#endif
+
+        /* This is needed to handle the unlikely case that the
+         * interpreter is in interactive mode *and* stdin/out are not
+         * a tty.  This can happen, for example if python is run like
+         * this: python -i < test1.py
+         */
+        if (!isatty (fileno (sys_stdin)) || !isatty (fileno (sys_stdout)))
+                rv = PyOS_StdioReadline (sys_stdin, sys_stdout, prompt);
+        else
+                rv = (*PyOS_ReadlineFunctionPointer)(sys_stdin, sys_stdout,
+                                                     prompt);
+	Py_END_ALLOW_THREADS
+
+#ifdef WITH_THREAD
+	PyThread_release_lock(_PyOS_ReadlineLock);
+#endif
+
+	_PyOS_ReadlineTState = NULL;
+
+	return rv;
+}

Added: vendor/Python/current/Parser/node.c
===================================================================
--- vendor/Python/current/Parser/node.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Parser/node.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,135 @@
+/* Parse tree node implementation */
+
+#include "Python.h"
+#include "node.h"
+#include "errcode.h"
+
+node *
+PyNode_New(int type)
+{
+	node *n = (node *) PyObject_MALLOC(1 * sizeof(node));
+	if (n == NULL)
+		return NULL;
+	n->n_type = type;
+	n->n_str = NULL;
+	n->n_lineno = 0;
+	n->n_nchildren = 0;
+	n->n_child = NULL;
+	return n;
+}
+
+/* See comments at XXXROUNDUP below.  Returns -1 on overflow. */
+static int
+fancy_roundup(int n)
+{
+	/* Round up to the closest power of 2 >= n. */
+	int result = 256;
+	assert(n > 128);
+	while (result < n) {
+		result <<= 1;
+		if (result <= 0)
+			return -1;
+	}
+	return result;
+}
+
+/* A gimmick to make massive numbers of reallocs quicker.  The result is
+ * a number >= the input.  In PyNode_AddChild, it's used like so, when
+ * we're about to add child number current_size + 1:
+ *
+ *     if XXXROUNDUP(current_size) < XXXROUNDUP(current_size + 1):
+ *         allocate space for XXXROUNDUP(current_size + 1) total children
+ *     else:
+ *         we already have enough space
+ *
+ * Since a node starts out empty, we must have
+ *
+ *     XXXROUNDUP(0) < XXXROUNDUP(1)
+ *
+ * so that we allocate space for the first child.  One-child nodes are very
+ * common (presumably that would change if we used a more abstract form
+ * of syntax tree), so to avoid wasting memory it's desirable that
+ * XXXROUNDUP(1) == 1.  That in turn forces XXXROUNDUP(0) == 0.
+ *
+ * Else for 2 <= n <= 128, we round up to the closest multiple of 4.  Why 4?
+ * Rounding up to a multiple of an exact power of 2 is very efficient, and
+ * most nodes with more than one child have <= 4 kids.
+ *
+ * Else we call fancy_roundup() to grow proportionately to n.  We've got an
+ * extreme case then (like test_longexp.py), and on many platforms doing
+ * anything less than proportional growth leads to exorbitant runtime
+ * (e.g., MacPython), or extreme fragmentation of user address space (e.g.,
+ * Win98).
+ *
+ * In a run of compileall across the 2.3a0 Lib directory, Andrew MacIntyre
+ * reported that, with this scheme, 89% of PyObject_REALLOC calls in
+ * PyNode_AddChild passed 1 for the size, and 9% passed 4.  So this usually
+ * wastes very little memory, but is very effective at sidestepping
+ * platform-realloc disasters on vulnerable platforms.
+ *
+ * Note that this would be straightforward if a node stored its current
+ * capacity.  The code is tricky to avoid that.
+ */
+#define XXXROUNDUP(n) ((n) <= 1 ? (n) : 		\
+		       (n) <= 128 ? (((n) + 3) & ~3) :	\
+		       fancy_roundup(n))
+
+
+int
+PyNode_AddChild(register node *n1, int type, char *str, int lineno, int col_offset)
+{
+	const int nch = n1->n_nchildren;
+	int current_capacity;
+	int required_capacity;
+	node *n;
+
+	if (nch == INT_MAX || nch < 0)
+		return E_OVERFLOW;
+
+	current_capacity = XXXROUNDUP(nch);
+	required_capacity = XXXROUNDUP(nch + 1);
+	if (current_capacity < 0 || required_capacity < 0)
+		return E_OVERFLOW;
+	if (current_capacity < required_capacity) {
+		n = n1->n_child;
+		n = (node *) PyObject_REALLOC(n,
+					      required_capacity * sizeof(node));
+		if (n == NULL)
+			return E_NOMEM;
+		n1->n_child = n;
+	}
+
+	n = &n1->n_child[n1->n_nchildren++];
+	n->n_type = type;
+	n->n_str = str;
+	n->n_lineno = lineno;
+	n->n_col_offset = col_offset;
+	n->n_nchildren = 0;
+	n->n_child = NULL;
+	return 0;
+}
+
+/* Forward */
+static void freechildren(node *);
+
+
+void
+PyNode_Free(node *n)
+{
+	if (n != NULL) {
+		freechildren(n);
+		PyObject_FREE(n);
+	}
+}
+
+static void
+freechildren(node *n)
+{
+	int i;
+	for (i = NCH(n); --i >= 0; )
+		freechildren(CHILD(n, i));
+	if (n->n_child != NULL)
+		PyObject_FREE(n->n_child);
+	if (STR(n) != NULL)
+		PyObject_FREE(STR(n));
+}

Added: vendor/Python/current/Parser/parser.c
===================================================================
--- vendor/Python/current/Parser/parser.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Parser/parser.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,433 @@
+
+/* Parser implementation */
+
+/* For a description, see the comments at end of this file */
+
+/* XXX To do: error recovery */
+
+#include "Python.h"
+#include "pgenheaders.h"
+#include "token.h"
+#include "grammar.h"
+#include "node.h"
+#include "parser.h"
+#include "errcode.h"
+
+
+#ifdef Py_DEBUG
+extern int Py_DebugFlag;
+#define D(x) if (!Py_DebugFlag); else x
+#else
+#define D(x)
+#endif
+
+
+/* STACK DATA TYPE */
+
+static void s_reset(stack *);
+
+static void
+s_reset(stack *s)
+{
+	s->s_top = &s->s_base[MAXSTACK];
+}
+
+#define s_empty(s) ((s)->s_top == &(s)->s_base[MAXSTACK])
+
+static int
+s_push(register stack *s, dfa *d, node *parent)
+{
+	register stackentry *top;
+	if (s->s_top == s->s_base) {
+		fprintf(stderr, "s_push: parser stack overflow\n");
+		return E_NOMEM;
+	}
+	top = --s->s_top;
+	top->s_dfa = d;
+	top->s_parent = parent;
+	top->s_state = 0;
+	return 0;
+}
+
+#ifdef Py_DEBUG
+
+static void
+s_pop(register stack *s)
+{
+	if (s_empty(s))
+		Py_FatalError("s_pop: parser stack underflow -- FATAL");
+	s->s_top++;
+}
+
+#else /* !Py_DEBUG */
+
+#define s_pop(s) (s)->s_top++
+
+#endif
+
+
+/* PARSER CREATION */
+
+parser_state *
+PyParser_New(grammar *g, int start)
+{
+	parser_state *ps;
+	
+	if (!g->g_accel)
+		PyGrammar_AddAccelerators(g);
+	ps = (parser_state *)PyMem_MALLOC(sizeof(parser_state));
+	if (ps == NULL)
+		return NULL;
+	ps->p_grammar = g;
+#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
+	ps->p_flags = 0;
+#endif
+	ps->p_tree = PyNode_New(start);
+	if (ps->p_tree == NULL) {
+		PyMem_FREE(ps);
+		return NULL;
+	}
+	s_reset(&ps->p_stack);
+	(void) s_push(&ps->p_stack, PyGrammar_FindDFA(g, start), ps->p_tree);
+	return ps;
+}
+
+void
+PyParser_Delete(parser_state *ps)
+{
+	/* NB If you want to save the parse tree,
+	   you must set p_tree to NULL before calling delparser! */
+	PyNode_Free(ps->p_tree);
+	PyMem_FREE(ps);
+}
+
+
+/* PARSER STACK OPERATIONS */
+
+static int
+shift(register stack *s, int type, char *str, int newstate, int lineno, int col_offset)
+{
+	int err;
+	assert(!s_empty(s));
+	err = PyNode_AddChild(s->s_top->s_parent, type, str, lineno, col_offset);
+	if (err)
+		return err;
+	s->s_top->s_state = newstate;
+	return 0;
+}
+
+static int
+push(register stack *s, int type, dfa *d, int newstate, int lineno, int col_offset)
+{
+	int err;
+	register node *n;
+	n = s->s_top->s_parent;
+	assert(!s_empty(s));
+	err = PyNode_AddChild(n, type, (char *)NULL, lineno, col_offset);
+	if (err)
+		return err;
+	s->s_top->s_state = newstate;
+	return s_push(s, d, CHILD(n, NCH(n)-1));
+}
+
+
+/* PARSER PROPER */
+
+static int
+classify(parser_state *ps, int type, char *str)
+{
+	grammar *g = ps->p_grammar;
+	register int n = g->g_ll.ll_nlabels;
+	
+	if (type == NAME) {
+		register char *s = str;
+		register label *l = g->g_ll.ll_label;
+		register int i;
+		for (i = n; i > 0; i--, l++) {
+			if (l->lb_type != NAME || l->lb_str == NULL ||
+			    l->lb_str[0] != s[0] ||
+			    strcmp(l->lb_str, s) != 0)
+				continue;
+#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
+			if (!(ps->p_flags & CO_FUTURE_WITH_STATEMENT)) {
+				if (s[0] == 'w' && strcmp(s, "with") == 0)
+					break; /* not a keyword yet */
+				else if (s[0] == 'a' && strcmp(s, "as") == 0)
+					break; /* not a keyword yet */
+			}
+#endif
+			D(printf("It's a keyword\n"));
+			return n - i;
+		}
+	}
+	
+	{
+		register label *l = g->g_ll.ll_label;
+		register int i;
+		for (i = n; i > 0; i--, l++) {
+			if (l->lb_type == type && l->lb_str == NULL) {
+				D(printf("It's a token we know\n"));
+				return n - i;
+			}
+		}
+	}
+	
+	D(printf("Illegal token\n"));
+	return -1;
+}
+
+#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
+static void
+future_hack(parser_state *ps)
+{
+	node *n = ps->p_stack.s_top->s_parent;
+	node *ch, *cch;
+	int i;
+
+	/* from __future__ import ..., must have at least 4 children */
+	n = CHILD(n, 0);
+	if (NCH(n) < 4)
+		return;
+	ch = CHILD(n, 0);
+	if (STR(ch) == NULL || strcmp(STR(ch), "from") != 0)
+		return;
+	ch = CHILD(n, 1);
+	if (NCH(ch) == 1 && STR(CHILD(ch, 0)) &&
+	    strcmp(STR(CHILD(ch, 0)), "__future__") != 0)
+		return;
+	ch = CHILD(n, 3);
+	/* ch can be a star, a parenthesis or import_as_names */
+	if (TYPE(ch) == STAR)
+		return;
+	if (TYPE(ch) == LPAR)
+		ch = CHILD(n, 4);
+	
+	for (i = 0; i < NCH(ch); i += 2) {
+		cch = CHILD(ch, i);
+		if (NCH(cch) >= 1 && TYPE(CHILD(cch, 0)) == NAME &&
+		    strcmp(STR(CHILD(cch, 0)), "with_statement") == 0) {
+			ps->p_flags |= CO_FUTURE_WITH_STATEMENT;
+			break;
+		}
+	}
+}
+#endif /* future keyword */
+
+int
+PyParser_AddToken(register parser_state *ps, register int type, char *str,
+	          int lineno, int col_offset, int *expected_ret)
+{
+	register int ilabel;
+	int err;
+	
+	D(printf("Token %s/'%s' ... ", _PyParser_TokenNames[type], str));
+	
+	/* Find out which label this token is */
+	ilabel = classify(ps, type, str);
+	if (ilabel < 0)
+		return E_SYNTAX;
+	
+	/* Loop until the token is shifted or an error occurred */
+	for (;;) {
+		/* Fetch the current dfa and state */
+		register dfa *d = ps->p_stack.s_top->s_dfa;
+		register state *s = &d->d_state[ps->p_stack.s_top->s_state];
+		
+		D(printf(" DFA '%s', state %d:",
+			d->d_name, ps->p_stack.s_top->s_state));
+		
+		/* Check accelerator */
+		if (s->s_lower <= ilabel && ilabel < s->s_upper) {
+			register int x = s->s_accel[ilabel - s->s_lower];
+			if (x != -1) {
+				if (x & (1<<7)) {
+					/* Push non-terminal */
+					int nt = (x >> 8) + NT_OFFSET;
+					int arrow = x & ((1<<7)-1);
+					dfa *d1 = PyGrammar_FindDFA(
+						ps->p_grammar, nt);
+					if ((err = push(&ps->p_stack, nt, d1,
+						arrow, lineno, col_offset)) > 0) {
+						D(printf(" MemError: push\n"));
+						return err;
+					}
+					D(printf(" Push ...\n"));
+					continue;
+				}
+				
+				/* Shift the token */
+				if ((err = shift(&ps->p_stack, type, str,
+						x, lineno, col_offset)) > 0) {
+					D(printf(" MemError: shift.\n"));
+					return err;
+				}
+				D(printf(" Shift.\n"));
+				/* Pop while we are in an accept-only state */
+				while (s = &d->d_state
+						[ps->p_stack.s_top->s_state],
+					s->s_accept && s->s_narcs == 1) {
+					D(printf("  DFA '%s', state %d: "
+						 "Direct pop.\n",
+						 d->d_name,
+						 ps->p_stack.s_top->s_state));
+#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
+					if (d->d_name[0] == 'i' &&
+					    strcmp(d->d_name,
+						   "import_stmt") == 0)
+						future_hack(ps);
+#endif
+					s_pop(&ps->p_stack);
+					if (s_empty(&ps->p_stack)) {
+						D(printf("  ACCEPT.\n"));
+						return E_DONE;
+					}
+					d = ps->p_stack.s_top->s_dfa;
+				}
+				return E_OK;
+			}
+		}
+		
+		if (s->s_accept) {
+#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
+			if (d->d_name[0] == 'i' &&
+			    strcmp(d->d_name, "import_stmt") == 0)
+				future_hack(ps);
+#endif
+			/* Pop this dfa and try again */
+			s_pop(&ps->p_stack);
+			D(printf(" Pop ...\n"));
+			if (s_empty(&ps->p_stack)) {
+				D(printf(" Error: bottom of stack.\n"));
+				return E_SYNTAX;
+			}
+			continue;
+		}
+		
+		/* Stuck, report syntax error */
+		D(printf(" Error.\n"));
+		if (expected_ret) {
+			if (s->s_lower == s->s_upper - 1) {
+				/* Only one possible expected token */
+				*expected_ret = ps->p_grammar->
+				    g_ll.ll_label[s->s_lower].lb_type;
+			}
+			else 
+		        	*expected_ret = -1;
+		}
+		return E_SYNTAX;
+	}
+}
+
+
+#ifdef Py_DEBUG
+
+/* DEBUG OUTPUT */
+
+void
+dumptree(grammar *g, node *n)
+{
+	int i;
+	
+	if (n == NULL)
+		printf("NIL");
+	else {
+		label l;
+		l.lb_type = TYPE(n);
+		l.lb_str = STR(n);
+		printf("%s", PyGrammar_LabelRepr(&l));
+		if (ISNONTERMINAL(TYPE(n))) {
+			printf("(");
+			for (i = 0; i < NCH(n); i++) {
+				if (i > 0)
+					printf(",");
+				dumptree(g, CHILD(n, i));
+			}
+			printf(")");
+		}
+	}
+}
+
+void
+showtree(grammar *g, node *n)
+{
+	int i;
+	
+	if (n == NULL)
+		return;
+	if (ISNONTERMINAL(TYPE(n))) {
+		for (i = 0; i < NCH(n); i++)
+			showtree(g, CHILD(n, i));
+	}
+	else if (ISTERMINAL(TYPE(n))) {
+		printf("%s", _PyParser_TokenNames[TYPE(n)]);
+		if (TYPE(n) == NUMBER || TYPE(n) == NAME)
+			printf("(%s)", STR(n));
+		printf(" ");
+	}
+	else
+		printf("? ");
+}
+
+void
+printtree(parser_state *ps)
+{
+	if (Py_DebugFlag) {
+		printf("Parse tree:\n");
+		dumptree(ps->p_grammar, ps->p_tree);
+		printf("\n");
+		printf("Tokens:\n");
+		showtree(ps->p_grammar, ps->p_tree);
+		printf("\n");
+	}
+	printf("Listing:\n");
+	PyNode_ListTree(ps->p_tree);
+	printf("\n");
+}
+
+#endif /* Py_DEBUG */
+
+/*
+
+Description
+-----------
+
+The parser's interface is different than usual: the function addtoken()
+must be called for each token in the input.  This makes it possible to
+turn it into an incremental parsing system later.  The parsing system
+constructs a parse tree as it goes.
+
+A parsing rule is represented as a Deterministic Finite-state Automaton
+(DFA).  A node in a DFA represents a state of the parser; an arc represents
+a transition.  Transitions are either labeled with terminal symbols or
+with non-terminals.  When the parser decides to follow an arc labeled
+with a non-terminal, it is invoked recursively with the DFA representing
+the parsing rule for that as its initial state; when that DFA accepts,
+the parser that invoked it continues.  The parse tree constructed by the
+recursively called parser is inserted as a child in the current parse tree.
+
+The DFA's can be constructed automatically from a more conventional
+language description.  An extended LL(1) grammar (ELL(1)) is suitable.
+Certain restrictions make the parser's life easier: rules that can produce
+the empty string should be outlawed (there are other ways to put loops
+or optional parts in the language).  To avoid the need to construct
+FIRST sets, we can require that all but the last alternative of a rule
+(really: arc going out of a DFA's state) must begin with a terminal
+symbol.
+
+As an example, consider this grammar:
+
+expr:	term (OP term)*
+term:	CONSTANT | '(' expr ')'
+
+The DFA corresponding to the rule for expr is:
+
+------->.---term-->.------->
+	^          |
+	|          |
+	\----OP----/
+
+The parse tree generated for the input a+b is:
+
+(expr: (term: (NAME: a)), (OP: +), (term: (NAME: b)))
+
+*/

Added: vendor/Python/current/Parser/parser.h
===================================================================
--- vendor/Python/current/Parser/parser.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Parser/parser.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,42 @@
+#ifndef Py_PARSER_H
+#define Py_PARSER_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Parser interface */
+
+#define MAXSTACK 500
+
+typedef struct {
+	int		 s_state;	/* State in current DFA */
+	dfa		*s_dfa;		/* Current DFA */
+	struct _node	*s_parent;	/* Where to add next node */
+} stackentry;
+
+typedef struct {
+	stackentry	*s_top;		/* Top entry */
+	stackentry	 s_base[MAXSTACK];/* Array of stack entries */
+					/* NB The stack grows down */
+} stack;
+
+typedef struct {
+	stack	 	p_stack;	/* Stack of parser states */
+	grammar		*p_grammar;	/* Grammar to use */
+	node		*p_tree;	/* Top of parse tree */
+#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
+	unsigned long	p_flags;	/* see co_flags in Include/code.h */
+#endif
+} parser_state;
+
+parser_state *PyParser_New(grammar *g, int start);
+void PyParser_Delete(parser_state *ps);
+int PyParser_AddToken(parser_state *ps, int type, char *str, int lineno, int col_offset,
+                      int *expected_ret);
+void PyGrammar_AddAccelerators(grammar *g);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_PARSER_H */

Added: vendor/Python/current/Parser/parsetok.c
===================================================================
--- vendor/Python/current/Parser/parsetok.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Parser/parsetok.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,260 @@
+
+/* Parser-tokenizer link implementation */
+
+#include "pgenheaders.h"
+#include "tokenizer.h"
+#include "node.h"
+#include "grammar.h"
+#include "parser.h"
+#include "parsetok.h"
+#include "errcode.h"
+#include "graminit.h"
+
+int Py_TabcheckFlag;
+
+
+/* Forward */
+static node *parsetok(struct tok_state *, grammar *, int, perrdetail *, int);
+static void initerr(perrdetail *err_ret, const char* filename);
+
+/* Parse input coming from a string.  Return error code, print some errors. */
+node *
+PyParser_ParseString(const char *s, grammar *g, int start, perrdetail *err_ret)
+{
+	return PyParser_ParseStringFlagsFilename(s, NULL, g, start, err_ret, 0);
+}
+
+node *
+PyParser_ParseStringFlags(const char *s, grammar *g, int start,
+		          perrdetail *err_ret, int flags)
+{
+	return PyParser_ParseStringFlagsFilename(s, NULL,
+						 g, start, err_ret, flags);
+}
+
+node *
+PyParser_ParseStringFlagsFilename(const char *s, const char *filename,
+			  grammar *g, int start,
+		          perrdetail *err_ret, int flags)
+{
+	struct tok_state *tok;
+
+	initerr(err_ret, filename);
+
+	if ((tok = PyTokenizer_FromString(s)) == NULL) {
+		err_ret->error = PyErr_Occurred() ? E_DECODE : E_NOMEM;
+		return NULL;
+	}
+
+        tok->filename = filename ? filename : "<string>";
+	if (Py_TabcheckFlag || Py_VerboseFlag) {
+		tok->altwarning = (tok->filename != NULL);
+		if (Py_TabcheckFlag >= 2)
+			tok->alterror++;
+	}
+
+	return parsetok(tok, g, start, err_ret, flags);
+}
+
+/* Parse input coming from a file.  Return error code, print some errors. */
+
+node *
+PyParser_ParseFile(FILE *fp, const char *filename, grammar *g, int start,
+		   char *ps1, char *ps2, perrdetail *err_ret)
+{
+	return PyParser_ParseFileFlags(fp, filename, g, start, ps1, ps2,
+				       err_ret, 0);
+}
+
+node *
+PyParser_ParseFileFlags(FILE *fp, const char *filename, grammar *g, int start,
+			char *ps1, char *ps2, perrdetail *err_ret, int flags)
+{
+	struct tok_state *tok;
+
+	initerr(err_ret, filename);
+
+	if ((tok = PyTokenizer_FromFile(fp, ps1, ps2)) == NULL) {
+		err_ret->error = E_NOMEM;
+		return NULL;
+	}
+	tok->filename = filename;
+	if (Py_TabcheckFlag || Py_VerboseFlag) {
+		tok->altwarning = (filename != NULL);
+		if (Py_TabcheckFlag >= 2)
+			tok->alterror++;
+	}
+
+
+	return parsetok(tok, g, start, err_ret, flags);
+}
+
+/* Parse input coming from the given tokenizer structure.
+   Return error code. */
+
+static char with_msg[] =
+"%s:%d: Warning: 'with' will become a reserved keyword in Python 2.6\n";
+
+static char as_msg[] =
+"%s:%d: Warning: 'as' will become a reserved keyword in Python 2.6\n";
+
+static void
+warn(const char *msg, const char *filename, int lineno)
+{
+	if (filename == NULL)
+		filename = "<string>";
+	PySys_WriteStderr(msg, filename, lineno);
+}
+
+static node *
+parsetok(struct tok_state *tok, grammar *g, int start, perrdetail *err_ret,
+	 int flags)
+{
+	parser_state *ps;
+	node *n;
+	int started = 0, handling_import = 0, handling_with = 0;
+
+	if ((ps = PyParser_New(g, start)) == NULL) {
+		fprintf(stderr, "no mem for new parser\n");
+		err_ret->error = E_NOMEM;
+		PyTokenizer_Free(tok);
+		return NULL;
+	}
+#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
+	if (flags & PyPARSE_WITH_IS_KEYWORD)
+		ps->p_flags |= CO_FUTURE_WITH_STATEMENT;
+#endif
+
+	for (;;) {
+		char *a, *b;
+		int type;
+		size_t len;
+		char *str;
+		int col_offset;
+
+		type = PyTokenizer_Get(tok, &a, &b);
+		if (type == ERRORTOKEN) {
+			err_ret->error = tok->done;
+			break;
+		}
+		if (type == ENDMARKER && started) {
+			type = NEWLINE; /* Add an extra newline */
+			handling_with = handling_import = 0;
+			started = 0;
+			/* Add the right number of dedent tokens,
+			   except if a certain flag is given --
+			   codeop.py uses this. */
+			if (tok->indent &&
+			    !(flags & PyPARSE_DONT_IMPLY_DEDENT))
+			{
+				tok->pendin = -tok->indent;
+				tok->indent = 0;
+			}
+		}
+		else
+			started = 1;
+		len = b - a; /* XXX this may compute NULL - NULL */
+		str = (char *) PyObject_MALLOC(len + 1);
+		if (str == NULL) {
+			fprintf(stderr, "no mem for next token\n");
+			err_ret->error = E_NOMEM;
+			break;
+		}
+		if (len > 0)
+			strncpy(str, a, len);
+		str[len] = '\0';
+
+#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
+		/* This is only necessary to support the "as" warning, but
+		   we don't want to warn about "as" in import statements. */
+		if (type == NAME &&
+		    len == 6 && str[0] == 'i' && strcmp(str, "import") == 0)
+			handling_import = 1;
+
+		/* Warn about with as NAME */
+		if (type == NAME &&
+		    !(ps->p_flags & CO_FUTURE_WITH_STATEMENT)) {
+		    if (len == 4 && str[0] == 'w' && strcmp(str, "with") == 0)
+			warn(with_msg, err_ret->filename, tok->lineno);
+		    else if (!(handling_import || handling_with) &&
+		             len == 2 && str[0] == 'a' &&
+			     strcmp(str, "as") == 0)
+			warn(as_msg, err_ret->filename, tok->lineno);
+		}
+		else if (type == NAME &&
+			 (ps->p_flags & CO_FUTURE_WITH_STATEMENT) &&
+			 len == 4 && str[0] == 'w' && strcmp(str, "with") == 0)
+			handling_with = 1;
+#endif
+		if (a >= tok->line_start)
+			col_offset = a - tok->line_start;
+		else
+			col_offset = -1;
+			
+		if ((err_ret->error =
+		     PyParser_AddToken(ps, (int)type, str, tok->lineno, col_offset,
+				       &(err_ret->expected))) != E_OK) {
+			if (err_ret->error != E_DONE) {
+				PyObject_FREE(str);
+				err_ret->token = type;
+			}				
+			break;
+		}
+	}
+
+	if (err_ret->error == E_DONE) {
+		n = ps->p_tree;
+		ps->p_tree = NULL;
+	}
+	else
+		n = NULL;
+
+	PyParser_Delete(ps);
+
+	if (n == NULL) {
+		if (tok->lineno <= 1 && tok->done == E_EOF)
+			err_ret->error = E_EOF;
+		err_ret->lineno = tok->lineno;
+		if (tok->buf != NULL) {
+			size_t len;
+			assert(tok->cur - tok->buf < INT_MAX);
+			err_ret->offset = (int)(tok->cur - tok->buf);
+			len = tok->inp - tok->buf;
+			err_ret->text = (char *) PyObject_MALLOC(len + 1);
+			if (err_ret->text != NULL) {
+				if (len > 0)
+					strncpy(err_ret->text, tok->buf, len);
+				err_ret->text[len] = '\0';
+			}
+		}
+	} else if (tok->encoding != NULL) {
+		node* r = PyNode_New(encoding_decl);
+		if (!r) {
+			err_ret->error = E_NOMEM;
+			n = NULL;
+			goto done;
+		}
+		r->n_str = tok->encoding;
+		r->n_nchildren = 1;
+		r->n_child = n;
+		tok->encoding = NULL;
+		n = r;
+	}
+
+done:
+	PyTokenizer_Free(tok);
+
+	return n;
+}
+
+static void
+initerr(perrdetail *err_ret, const char *filename)
+{
+	err_ret->error = E_OK;
+	err_ret->filename = filename;
+	err_ret->lineno = 0;
+	err_ret->offset = 0;
+	err_ret->text = NULL;
+	err_ret->token = -1;
+	err_ret->expected = -1;
+}

Added: vendor/Python/current/Parser/pgen.c
===================================================================
--- vendor/Python/current/Parser/pgen.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Parser/pgen.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,706 @@
+/* Parser generator */
+
+/* For a description, see the comments at end of this file */
+
+#include "Python.h"
+#include "pgenheaders.h"
+#include "token.h"
+#include "node.h"
+#include "grammar.h"
+#include "metagrammar.h"
+#include "pgen.h"
+
+extern int Py_DebugFlag;
+extern int Py_IgnoreEnvironmentFlag; /* needed by Py_GETENV */
+
+
+/* PART ONE -- CONSTRUCT NFA -- Cf. Algorithm 3.2 from [Aho&Ullman 77] */
+
+typedef struct _nfaarc {
+	int	ar_label;
+	int	ar_arrow;
+} nfaarc;
+
+typedef struct _nfastate {
+	int	st_narcs;
+	nfaarc	*st_arc;
+} nfastate;
+
+typedef struct _nfa {
+	int		nf_type;
+	char		*nf_name;
+	int		nf_nstates;
+	nfastate	*nf_state;
+	int		nf_start, nf_finish;
+} nfa;
+
+/* Forward */
+static void compile_rhs(labellist *ll,
+			nfa *nf, node *n, int *pa, int *pb);
+static void compile_alt(labellist *ll,
+			nfa *nf, node *n, int *pa, int *pb);
+static void compile_item(labellist *ll,
+			 nfa *nf, node *n, int *pa, int *pb);
+static void compile_atom(labellist *ll,
+			 nfa *nf, node *n, int *pa, int *pb);
+
+static int
+addnfastate(nfa *nf)
+{
+	nfastate *st;
+	
+	nf->nf_state = (nfastate *)PyObject_REALLOC(nf->nf_state, 
+                                    sizeof(nfastate) * (nf->nf_nstates + 1));
+	if (nf->nf_state == NULL)
+		Py_FatalError("out of mem");
+	st = &nf->nf_state[nf->nf_nstates++];
+	st->st_narcs = 0;
+	st->st_arc = NULL;
+	return st - nf->nf_state;
+}
+
+static void
+addnfaarc(nfa *nf, int from, int to, int lbl)
+{
+	nfastate *st;
+	nfaarc *ar;
+	
+	st = &nf->nf_state[from];
+	st->st_arc = (nfaarc *)PyObject_REALLOC(st->st_arc,
+				      sizeof(nfaarc) * (st->st_narcs + 1));
+	if (st->st_arc == NULL)
+		Py_FatalError("out of mem");
+	ar = &st->st_arc[st->st_narcs++];
+	ar->ar_label = lbl;
+	ar->ar_arrow = to;
+}
+
+static nfa *
+newnfa(char *name)
+{
+	nfa *nf;
+	static int type = NT_OFFSET; /* All types will be disjunct */
+	
+	nf = (nfa *)PyObject_MALLOC(sizeof(nfa));
+	if (nf == NULL)
+		Py_FatalError("no mem for new nfa");
+	nf->nf_type = type++;
+	nf->nf_name = name; /* XXX strdup(name) ??? */
+	nf->nf_nstates = 0;
+	nf->nf_state = NULL;
+	nf->nf_start = nf->nf_finish = -1;
+	return nf;
+}
+
+typedef struct _nfagrammar {
+	int		gr_nnfas;
+	nfa		**gr_nfa;
+	labellist	gr_ll;
+} nfagrammar;
+
+/* Forward */
+static void compile_rule(nfagrammar *gr, node *n);
+
+static nfagrammar *
+newnfagrammar(void)
+{
+	nfagrammar *gr;
+	
+	gr = (nfagrammar *)PyObject_MALLOC(sizeof(nfagrammar));
+	if (gr == NULL)
+		Py_FatalError("no mem for new nfa grammar");
+	gr->gr_nnfas = 0;
+	gr->gr_nfa = NULL;
+	gr->gr_ll.ll_nlabels = 0;
+	gr->gr_ll.ll_label = NULL;
+	addlabel(&gr->gr_ll, ENDMARKER, "EMPTY");
+	return gr;
+}
+
+static nfa *
+addnfa(nfagrammar *gr, char *name)
+{
+	nfa *nf;
+	
+	nf = newnfa(name);
+	gr->gr_nfa = (nfa **)PyObject_REALLOC(gr->gr_nfa,
+				      sizeof(nfa) * (gr->gr_nnfas + 1));
+	if (gr->gr_nfa == NULL)
+		Py_FatalError("out of mem");
+	gr->gr_nfa[gr->gr_nnfas++] = nf;
+	addlabel(&gr->gr_ll, NAME, nf->nf_name);
+	return nf;
+}
+
+#ifdef Py_DEBUG
+
+static char REQNFMT[] = "metacompile: less than %d children\n";
+
+#define REQN(i, count) \
+ 	if (i < count) { \
+		fprintf(stderr, REQNFMT, count); \
+		Py_FatalError("REQN"); \
+	} else
+
+#else
+#define REQN(i, count)	/* empty */
+#endif
+
+static nfagrammar *
+metacompile(node *n)
+{
+	nfagrammar *gr;
+	int i;
+
+	if (Py_DebugFlag)
+		printf("Compiling (meta-) parse tree into NFA grammar\n");
+	gr = newnfagrammar();
+	REQ(n, MSTART);
+	i = n->n_nchildren - 1; /* Last child is ENDMARKER */
+	n = n->n_child;
+	for (; --i >= 0; n++) {
+		if (n->n_type != NEWLINE)
+			compile_rule(gr, n);
+	}
+	return gr;
+}
+
+static void
+compile_rule(nfagrammar *gr, node *n)
+{
+	nfa *nf;
+	
+	REQ(n, RULE);
+	REQN(n->n_nchildren, 4);
+	n = n->n_child;
+	REQ(n, NAME);
+	nf = addnfa(gr, n->n_str);
+	n++;
+	REQ(n, COLON);
+	n++;
+	REQ(n, RHS);
+	compile_rhs(&gr->gr_ll, nf, n, &nf->nf_start, &nf->nf_finish);
+	n++;
+	REQ(n, NEWLINE);
+}
+
+static void
+compile_rhs(labellist *ll, nfa *nf, node *n, int *pa, int *pb)
+{
+	int i;
+	int a, b;
+	
+	REQ(n, RHS);
+	i = n->n_nchildren;
+	REQN(i, 1);
+	n = n->n_child;
+	REQ(n, ALT);
+	compile_alt(ll, nf, n, pa, pb);
+	if (--i <= 0)
+		return;
+	n++;
+	a = *pa;
+	b = *pb;
+	*pa = addnfastate(nf);
+	*pb = addnfastate(nf);
+	addnfaarc(nf, *pa, a, EMPTY);
+	addnfaarc(nf, b, *pb, EMPTY);
+	for (; --i >= 0; n++) {
+		REQ(n, VBAR);
+		REQN(i, 1);
+		--i;
+		n++;
+		REQ(n, ALT);
+		compile_alt(ll, nf, n, &a, &b);
+		addnfaarc(nf, *pa, a, EMPTY);
+		addnfaarc(nf, b, *pb, EMPTY);
+	}
+}
+
+static void
+compile_alt(labellist *ll, nfa *nf, node *n, int *pa, int *pb)
+{
+	int i;
+	int a, b;
+	
+	REQ(n, ALT);
+	i = n->n_nchildren;
+	REQN(i, 1);
+	n = n->n_child;
+	REQ(n, ITEM);
+	compile_item(ll, nf, n, pa, pb);
+	--i;
+	n++;
+	for (; --i >= 0; n++) {
+		REQ(n, ITEM);
+		compile_item(ll, nf, n, &a, &b);
+		addnfaarc(nf, *pb, a, EMPTY);
+		*pb = b;
+	}
+}
+
+static void
+compile_item(labellist *ll, nfa *nf, node *n, int *pa, int *pb)
+{
+	int i;
+	int a, b;
+	
+	REQ(n, ITEM);
+	i = n->n_nchildren;
+	REQN(i, 1);
+	n = n->n_child;
+	if (n->n_type == LSQB) {
+		REQN(i, 3);
+		n++;
+		REQ(n, RHS);
+		*pa = addnfastate(nf);
+		*pb = addnfastate(nf);
+		addnfaarc(nf, *pa, *pb, EMPTY);
+		compile_rhs(ll, nf, n, &a, &b);
+		addnfaarc(nf, *pa, a, EMPTY);
+		addnfaarc(nf, b, *pb, EMPTY);
+		REQN(i, 1);
+		n++;
+		REQ(n, RSQB);
+	}
+	else {
+		compile_atom(ll, nf, n, pa, pb);
+		if (--i <= 0)
+			return;
+		n++;
+		addnfaarc(nf, *pb, *pa, EMPTY);
+		if (n->n_type == STAR)
+			*pb = *pa;
+		else
+			REQ(n, PLUS);
+	}
+}
+
+static void
+compile_atom(labellist *ll, nfa *nf, node *n, int *pa, int *pb)
+{
+	int i;
+	
+	REQ(n, ATOM);
+	i = n->n_nchildren;
+	REQN(i, 1);
+	n = n->n_child;
+	if (n->n_type == LPAR) {
+		REQN(i, 3);
+		n++;
+		REQ(n, RHS);
+		compile_rhs(ll, nf, n, pa, pb);
+		n++;
+		REQ(n, RPAR);
+	}
+	else if (n->n_type == NAME || n->n_type == STRING) {
+		*pa = addnfastate(nf);
+		*pb = addnfastate(nf);
+		addnfaarc(nf, *pa, *pb, addlabel(ll, n->n_type, n->n_str));
+	}
+	else
+		REQ(n, NAME);
+}
+
+static void
+dumpstate(labellist *ll, nfa *nf, int istate)
+{
+	nfastate *st;
+	int i;
+	nfaarc *ar;
+	
+	printf("%c%2d%c",
+		istate == nf->nf_start ? '*' : ' ',
+		istate,
+		istate == nf->nf_finish ? '.' : ' ');
+	st = &nf->nf_state[istate];
+	ar = st->st_arc;
+	for (i = 0; i < st->st_narcs; i++) {
+		if (i > 0)
+			printf("\n    ");
+		printf("-> %2d  %s", ar->ar_arrow,
+			PyGrammar_LabelRepr(&ll->ll_label[ar->ar_label]));
+		ar++;
+	}
+	printf("\n");
+}
+
+static void
+dumpnfa(labellist *ll, nfa *nf)
+{
+	int i;
+	
+	printf("NFA '%s' has %d states; start %d, finish %d\n",
+		nf->nf_name, nf->nf_nstates, nf->nf_start, nf->nf_finish);
+	for (i = 0; i < nf->nf_nstates; i++)
+		dumpstate(ll, nf, i);
+}
+
+
+/* PART TWO -- CONSTRUCT DFA -- Algorithm 3.1 from [Aho&Ullman 77] */
+
+static void
+addclosure(bitset ss, nfa *nf, int istate)
+{
+	if (addbit(ss, istate)) {
+		nfastate *st = &nf->nf_state[istate];
+		nfaarc *ar = st->st_arc;
+		int i;
+		
+		for (i = st->st_narcs; --i >= 0; ) {
+			if (ar->ar_label == EMPTY)
+				addclosure(ss, nf, ar->ar_arrow);
+			ar++;
+		}
+	}
+}
+
+typedef struct _ss_arc {
+	bitset	sa_bitset;
+	int	sa_arrow;
+	int	sa_label;
+} ss_arc;
+
+typedef struct _ss_state {
+	bitset	ss_ss;
+	int	ss_narcs;
+	struct _ss_arc	*ss_arc;
+	int	ss_deleted;
+	int	ss_finish;
+	int	ss_rename;
+} ss_state;
+
+typedef struct _ss_dfa {
+	int	sd_nstates;
+	ss_state *sd_state;
+} ss_dfa;
+
+/* Forward */
+static void printssdfa(int xx_nstates, ss_state *xx_state, int nbits,
+		       labellist *ll, char *msg);
+static void simplify(int xx_nstates, ss_state *xx_state);
+static void convert(dfa *d, int xx_nstates, ss_state *xx_state);
+
+static void
+makedfa(nfagrammar *gr, nfa *nf, dfa *d)
+{
+	int nbits = nf->nf_nstates;
+	bitset ss;
+	int xx_nstates;
+	ss_state *xx_state, *yy;
+	ss_arc *zz;
+	int istate, jstate, iarc, jarc, ibit;
+	nfastate *st;
+	nfaarc *ar;
+	
+	ss = newbitset(nbits);
+	addclosure(ss, nf, nf->nf_start);
+	xx_state = (ss_state *)PyObject_MALLOC(sizeof(ss_state));
+	if (xx_state == NULL)
+		Py_FatalError("no mem for xx_state in makedfa");
+	xx_nstates = 1;
+	yy = &xx_state[0];
+	yy->ss_ss = ss;
+	yy->ss_narcs = 0;
+	yy->ss_arc = NULL;
+	yy->ss_deleted = 0;
+	yy->ss_finish = testbit(ss, nf->nf_finish);
+	if (yy->ss_finish)
+		printf("Error: nonterminal '%s' may produce empty.\n",
+			nf->nf_name);
+	
+	/* This algorithm is from a book written before
+	   the invention of structured programming... */
+
+	/* For each unmarked state... */
+	for (istate = 0; istate < xx_nstates; ++istate) {
+		size_t size;
+		yy = &xx_state[istate];
+		ss = yy->ss_ss;
+		/* For all its states... */
+		for (ibit = 0; ibit < nf->nf_nstates; ++ibit) {
+			if (!testbit(ss, ibit))
+				continue;
+			st = &nf->nf_state[ibit];
+			/* For all non-empty arcs from this state... */
+			for (iarc = 0; iarc < st->st_narcs; iarc++) {
+				ar = &st->st_arc[iarc];
+				if (ar->ar_label == EMPTY)
+					continue;
+				/* Look up in list of arcs from this state */
+				for (jarc = 0; jarc < yy->ss_narcs; ++jarc) {
+					zz = &yy->ss_arc[jarc];
+					if (ar->ar_label == zz->sa_label)
+						goto found;
+				}
+				/* Add new arc for this state */
+				size = sizeof(ss_arc) * (yy->ss_narcs + 1);
+				yy->ss_arc = (ss_arc *)PyObject_REALLOC(
+                                                            yy->ss_arc, size);
+				if (yy->ss_arc == NULL)
+					Py_FatalError("out of mem");
+				zz = &yy->ss_arc[yy->ss_narcs++];
+				zz->sa_label = ar->ar_label;
+				zz->sa_bitset = newbitset(nbits);
+				zz->sa_arrow = -1;
+			 found:	;
+				/* Add destination */
+				addclosure(zz->sa_bitset, nf, ar->ar_arrow);
+			}
+		}
+		/* Now look up all the arrow states */
+		for (jarc = 0; jarc < xx_state[istate].ss_narcs; jarc++) {
+			zz = &xx_state[istate].ss_arc[jarc];
+			for (jstate = 0; jstate < xx_nstates; jstate++) {
+				if (samebitset(zz->sa_bitset,
+					xx_state[jstate].ss_ss, nbits)) {
+					zz->sa_arrow = jstate;
+					goto done;
+				}
+			}
+			size = sizeof(ss_state) * (xx_nstates + 1);
+			xx_state = (ss_state *)PyObject_REALLOC(xx_state, 
+                                                                    size);
+			if (xx_state == NULL)
+				Py_FatalError("out of mem");
+			zz->sa_arrow = xx_nstates;
+			yy = &xx_state[xx_nstates++];
+			yy->ss_ss = zz->sa_bitset;
+			yy->ss_narcs = 0;
+			yy->ss_arc = NULL;
+			yy->ss_deleted = 0;
+			yy->ss_finish = testbit(yy->ss_ss, nf->nf_finish);
+		 done:	;
+		}
+	}
+	
+	if (Py_DebugFlag)
+		printssdfa(xx_nstates, xx_state, nbits, &gr->gr_ll,
+						"before minimizing");
+	
+	simplify(xx_nstates, xx_state);
+	
+	if (Py_DebugFlag)
+		printssdfa(xx_nstates, xx_state, nbits, &gr->gr_ll,
+						"after minimizing");
+	
+	convert(d, xx_nstates, xx_state);
+	
+	/* XXX cleanup */
+}
+
+static void
+printssdfa(int xx_nstates, ss_state *xx_state, int nbits,
+	   labellist *ll, char *msg)
+{
+	int i, ibit, iarc;
+	ss_state *yy;
+	ss_arc *zz;
+	
+	printf("Subset DFA %s\n", msg);
+	for (i = 0; i < xx_nstates; i++) {
+		yy = &xx_state[i];
+		if (yy->ss_deleted)
+			continue;
+		printf(" Subset %d", i);
+		if (yy->ss_finish)
+			printf(" (finish)");
+		printf(" { ");
+		for (ibit = 0; ibit < nbits; ibit++) {
+			if (testbit(yy->ss_ss, ibit))
+				printf("%d ", ibit);
+		}
+		printf("}\n");
+		for (iarc = 0; iarc < yy->ss_narcs; iarc++) {
+			zz = &yy->ss_arc[iarc];
+			printf("  Arc to state %d, label %s\n",
+				zz->sa_arrow,
+				PyGrammar_LabelRepr(
+					&ll->ll_label[zz->sa_label]));
+		}
+	}
+}
+
+
+/* PART THREE -- SIMPLIFY DFA */
+
+/* Simplify the DFA by repeatedly eliminating states that are
+   equivalent to another oner.  This is NOT Algorithm 3.3 from
+   [Aho&Ullman 77].  It does not always finds the minimal DFA,
+   but it does usually make a much smaller one...  (For an example
+   of sub-optimal behavior, try S: x a b+ | y a b+.)
+*/
+
+static int
+samestate(ss_state *s1, ss_state *s2)
+{
+	int i;
+	
+	if (s1->ss_narcs != s2->ss_narcs || s1->ss_finish != s2->ss_finish)
+		return 0;
+	for (i = 0; i < s1->ss_narcs; i++) {
+		if (s1->ss_arc[i].sa_arrow != s2->ss_arc[i].sa_arrow ||
+			s1->ss_arc[i].sa_label != s2->ss_arc[i].sa_label)
+			return 0;
+	}
+	return 1;
+}
+
+static void
+renamestates(int xx_nstates, ss_state *xx_state, int from, int to)
+{
+	int i, j;
+	
+	if (Py_DebugFlag)
+		printf("Rename state %d to %d.\n", from, to);
+	for (i = 0; i < xx_nstates; i++) {
+		if (xx_state[i].ss_deleted)
+			continue;
+		for (j = 0; j < xx_state[i].ss_narcs; j++) {
+			if (xx_state[i].ss_arc[j].sa_arrow == from)
+				xx_state[i].ss_arc[j].sa_arrow = to;
+		}
+	}
+}
+
+static void
+simplify(int xx_nstates, ss_state *xx_state)
+{
+	int changes;
+	int i, j;
+	
+	do {
+		changes = 0;
+		for (i = 1; i < xx_nstates; i++) {
+			if (xx_state[i].ss_deleted)
+				continue;
+			for (j = 0; j < i; j++) {
+				if (xx_state[j].ss_deleted)
+					continue;
+				if (samestate(&xx_state[i], &xx_state[j])) {
+					xx_state[i].ss_deleted++;
+					renamestates(xx_nstates, xx_state,
+						     i, j);
+					changes++;
+					break;
+				}
+			}
+		}
+	} while (changes);
+}
+
+
+/* PART FOUR -- GENERATE PARSING TABLES */
+
+/* Convert the DFA into a grammar that can be used by our parser */
+
+static void
+convert(dfa *d, int xx_nstates, ss_state *xx_state)
+{
+	int i, j;
+	ss_state *yy;
+	ss_arc *zz;
+	
+	for (i = 0; i < xx_nstates; i++) {
+		yy = &xx_state[i];
+		if (yy->ss_deleted)
+			continue;
+		yy->ss_rename = addstate(d);
+	}
+	
+	for (i = 0; i < xx_nstates; i++) {
+		yy = &xx_state[i];
+		if (yy->ss_deleted)
+			continue;
+		for (j = 0; j < yy->ss_narcs; j++) {
+			zz = &yy->ss_arc[j];
+			addarc(d, yy->ss_rename,
+				xx_state[zz->sa_arrow].ss_rename,
+				zz->sa_label);
+		}
+		if (yy->ss_finish)
+			addarc(d, yy->ss_rename, yy->ss_rename, 0);
+	}
+	
+	d->d_initial = 0;
+}
+
+
+/* PART FIVE -- GLUE IT ALL TOGETHER */
+
+static grammar *
+maketables(nfagrammar *gr)
+{
+	int i;
+	nfa *nf;
+	dfa *d;
+	grammar *g;
+	
+	if (gr->gr_nnfas == 0)
+		return NULL;
+	g = newgrammar(gr->gr_nfa[0]->nf_type);
+			/* XXX first rule must be start rule */
+	g->g_ll = gr->gr_ll;
+	
+	for (i = 0; i < gr->gr_nnfas; i++) {
+		nf = gr->gr_nfa[i];
+		if (Py_DebugFlag) {
+			printf("Dump of NFA for '%s' ...\n", nf->nf_name);
+			dumpnfa(&gr->gr_ll, nf);
+			printf("Making DFA for '%s' ...\n", nf->nf_name);
+		}
+		d = adddfa(g, nf->nf_type, nf->nf_name);
+		makedfa(gr, gr->gr_nfa[i], d);
+	}
+	
+	return g;
+}
+
+grammar *
+pgen(node *n)
+{
+	nfagrammar *gr;
+	grammar *g;
+	
+	gr = metacompile(n);
+	g = maketables(gr);
+	translatelabels(g);
+	addfirstsets(g);
+	return g;
+}
+
+grammar *
+Py_pgen(node *n)
+{
+  return pgen(n);
+}
+
+/*
+
+Description
+-----------
+
+Input is a grammar in extended BNF (using * for repetition, + for
+at-least-once repetition, [] for optional parts, | for alternatives and
+() for grouping).  This has already been parsed and turned into a parse
+tree.
+
+Each rule is considered as a regular expression in its own right.
+It is turned into a Non-deterministic Finite Automaton (NFA), which
+is then turned into a Deterministic Finite Automaton (DFA), which is then
+optimized to reduce the number of states.  See [Aho&Ullman 77] chapter 3,
+or similar compiler books (this technique is more often used for lexical
+analyzers).
+
+The DFA's are used by the parser as parsing tables in a special way
+that's probably unique.  Before they are usable, the FIRST sets of all
+non-terminals are computed.
+
+Reference
+---------
+
+[Aho&Ullman 77]
+	Aho&Ullman, Principles of Compiler Design, Addison-Wesley 1977
+	(first edition)
+
+*/

Added: vendor/Python/current/Parser/pgenmain.c
===================================================================
--- vendor/Python/current/Parser/pgenmain.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Parser/pgenmain.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,173 @@
+
+/* Parser generator main program */
+
+/* This expects a filename containing the grammar as argv[1] (UNIX)
+   or asks the console for such a file name (THINK C).
+   It writes its output on two files in the current directory:
+   - "graminit.c" gets the grammar as a bunch of initialized data
+   - "graminit.h" gets the grammar's non-terminals as #defines.
+   Error messages and status info during the generation process are
+   written to stdout, or sometimes to stderr. */
+
+/* XXX TO DO:
+   - check for duplicate definitions of names (instead of fatal err)
+*/
+
+#include "Python.h"
+#include "pgenheaders.h"
+#include "grammar.h"
+#include "node.h"
+#include "parsetok.h"
+#include "pgen.h"
+
+int Py_DebugFlag;
+int Py_VerboseFlag;
+int Py_IgnoreEnvironmentFlag;
+
+/* Forward */
+grammar *getgrammar(char *filename);
+
+void
+Py_Exit(int sts)
+{
+	exit(sts);
+}
+
+int
+main(int argc, char **argv)
+{
+	grammar *g;
+	FILE *fp;
+	char *filename, *graminit_h, *graminit_c;
+	
+	if (argc != 4) {
+		fprintf(stderr,
+			"usage: %s grammar graminit.h graminit.c\n", argv[0]);
+		Py_Exit(2);
+	}
+	filename = argv[1];
+	graminit_h = argv[2];
+	graminit_c = argv[3];
+	g = getgrammar(filename);
+	fp = fopen(graminit_c, "w");
+	if (fp == NULL) {
+		perror(graminit_c);
+		Py_Exit(1);
+	}
+	if (Py_DebugFlag)
+		printf("Writing %s ...\n", graminit_c);
+	printgrammar(g, fp);
+	fclose(fp);
+	fp = fopen(graminit_h, "w");
+	if (fp == NULL) {
+		perror(graminit_h);
+		Py_Exit(1);
+	}
+	if (Py_DebugFlag)
+		printf("Writing %s ...\n", graminit_h);
+	printnonterminals(g, fp);
+	fclose(fp);
+	Py_Exit(0);
+	return 0; /* Make gcc -Wall happy */
+}
+
+grammar *
+getgrammar(char *filename)
+{
+	FILE *fp;
+	node *n;
+	grammar *g0, *g;
+	perrdetail err;
+	
+	fp = fopen(filename, "r");
+	if (fp == NULL) {
+		perror(filename);
+		Py_Exit(1);
+	}
+	g0 = meta_grammar();
+	n = PyParser_ParseFile(fp, filename, g0, g0->g_start,
+		      (char *)NULL, (char *)NULL, &err);
+	fclose(fp);
+	if (n == NULL) {
+		fprintf(stderr, "Parsing error %d, line %d.\n",
+			err.error, err.lineno);
+		if (err.text != NULL) {
+			size_t i;
+			fprintf(stderr, "%s", err.text);
+			i = strlen(err.text);
+			if (i == 0 || err.text[i-1] != '\n')
+				fprintf(stderr, "\n");
+			for (i = 0; i < err.offset; i++) {
+				if (err.text[i] == '\t')
+					putc('\t', stderr);
+				else
+					putc(' ', stderr);
+			}
+			fprintf(stderr, "^\n");
+			PyObject_FREE(err.text);
+		}
+		Py_Exit(1);
+	}
+	g = pgen(n);
+	if (g == NULL) {
+		printf("Bad grammar.\n");
+		Py_Exit(1);
+	}
+	return g;
+}
+
+/* Can't happen in pgen */
+PyObject*
+PyErr_Occurred()
+{
+	return 0;
+}
+
+void
+Py_FatalError(const char *msg)
+{
+	fprintf(stderr, "pgen: FATAL ERROR: %s\n", msg);
+	Py_Exit(1);
+}
+
+/* No-nonsense my_readline() for tokenizer.c */
+
+char *
+PyOS_Readline(FILE *sys_stdin, FILE *sys_stdout, char *prompt)
+{
+	size_t n = 1000;
+	char *p = (char *)PyMem_MALLOC(n);
+	char *q;
+	if (p == NULL)
+		return NULL;
+	fprintf(stderr, "%s", prompt);
+	q = fgets(p, n, sys_stdin);
+	if (q == NULL) {
+		*p = '\0';
+		return p;
+	}
+	n = strlen(p);
+	if (n > 0 && p[n-1] != '\n')
+		p[n-1] = '\n';
+	return (char *)PyMem_REALLOC(p, n+1);
+}
+
+/* No-nonsense fgets */
+char *
+Py_UniversalNewlineFgets(char *buf, int n, FILE *stream, PyObject *fobj)
+{
+	return fgets(buf, n, stream);
+}
+
+
+#include <stdarg.h>
+
+void
+PySys_WriteStderr(const char *format, ...)
+{
+	va_list va;
+
+	va_start(va, format);
+	vfprintf(stderr, format, va);
+	va_end(va);
+}

Added: vendor/Python/current/Parser/printgrammar.c
===================================================================
--- vendor/Python/current/Parser/printgrammar.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Parser/printgrammar.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,113 @@
+
+/* Print a bunch of C initializers that represent a grammar */
+
+#include "pgenheaders.h"
+#include "grammar.h"
+
+/* Forward */
+static void printarcs(int, dfa *, FILE *);
+static void printstates(grammar *, FILE *);
+static void printdfas(grammar *, FILE *);
+static void printlabels(grammar *, FILE *);
+
+void
+printgrammar(grammar *g, FILE *fp)
+{
+	fprintf(fp, "#include \"pgenheaders.h\"\n");
+	fprintf(fp, "#include \"grammar.h\"\n");
+	printdfas(g, fp);
+	printlabels(g, fp);
+	fprintf(fp, "grammar _PyParser_Grammar = {\n");
+	fprintf(fp, "\t%d,\n", g->g_ndfas);
+	fprintf(fp, "\tdfas,\n");
+	fprintf(fp, "\t{%d, labels},\n", g->g_ll.ll_nlabels);
+	fprintf(fp, "\t%d\n", g->g_start);
+	fprintf(fp, "};\n");
+}
+
+void
+printnonterminals(grammar *g, FILE *fp)
+{
+	dfa *d;
+	int i;
+	
+	d = g->g_dfa;
+	for (i = g->g_ndfas; --i >= 0; d++)
+		fprintf(fp, "#define %s %d\n", d->d_name, d->d_type);
+}
+
+static void
+printarcs(int i, dfa *d, FILE *fp)
+{
+	arc *a;
+	state *s;
+	int j, k;
+	
+	s = d->d_state;
+	for (j = 0; j < d->d_nstates; j++, s++) {
+		fprintf(fp, "static arc arcs_%d_%d[%d] = {\n",
+			i, j, s->s_narcs);
+		a = s->s_arc;
+		for (k = 0; k < s->s_narcs; k++, a++)
+			fprintf(fp, "\t{%d, %d},\n", a->a_lbl, a->a_arrow);
+		fprintf(fp, "};\n");
+	}
+}
+
+static void
+printstates(grammar *g, FILE *fp)
+{
+	state *s;
+	dfa *d;
+	int i, j;
+	
+	d = g->g_dfa;
+	for (i = 0; i < g->g_ndfas; i++, d++) {
+		printarcs(i, d, fp);
+		fprintf(fp, "static state states_%d[%d] = {\n",
+			i, d->d_nstates);
+		s = d->d_state;
+		for (j = 0; j < d->d_nstates; j++, s++)
+			fprintf(fp, "\t{%d, arcs_%d_%d},\n",
+				s->s_narcs, i, j);
+		fprintf(fp, "};\n");
+	}
+}
+
+static void
+printdfas(grammar *g, FILE *fp)
+{
+	dfa *d;
+	int i, j;
+	
+	printstates(g, fp);
+	fprintf(fp, "static dfa dfas[%d] = {\n", g->g_ndfas);
+	d = g->g_dfa;
+	for (i = 0; i < g->g_ndfas; i++, d++) {
+		fprintf(fp, "\t{%d, \"%s\", %d, %d, states_%d,\n",
+			d->d_type, d->d_name, d->d_initial, d->d_nstates, i);
+		fprintf(fp, "\t \"");
+		for (j = 0; j < NBYTES(g->g_ll.ll_nlabels); j++)
+			fprintf(fp, "\\%03o", d->d_first[j] & 0xff);
+		fprintf(fp, "\"},\n");
+	}
+	fprintf(fp, "};\n");
+}
+
+static void
+printlabels(grammar *g, FILE *fp)
+{
+	label *l;
+	int i;
+	
+	fprintf(fp, "static label labels[%d] = {\n", g->g_ll.ll_nlabels);
+	l = g->g_ll.ll_label;
+	for (i = g->g_ll.ll_nlabels; --i >= 0; l++) {
+		if (l->lb_str == NULL)
+			fprintf(fp, "\t{%d, 0},\n", l->lb_type);
+		else
+			fprintf(fp, "\t{%d, \"%s\"},\n",
+				l->lb_type, l->lb_str);
+	}
+	fprintf(fp, "};\n");
+}

Added: vendor/Python/current/Parser/spark.py
===================================================================
--- vendor/Python/current/Parser/spark.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Parser/spark.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,840 @@
+#  Copyright (c) 1998-2002 John Aycock
+#
+#  Permission is hereby granted, free of charge, to any person obtaining
+#  a copy of this software and associated documentation files (the
+#  "Software"), to deal in the Software without restriction, including
+#  without limitation the rights to use, copy, modify, merge, publish,
+#  distribute, sublicense, and/or sell copies of the Software, and to
+#  permit persons to whom the Software is furnished to do so, subject to
+#  the following conditions:
+#
+#  The above copyright notice and this permission notice shall be
+#  included in all copies or substantial portions of the Software.
+#
+#  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+#  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+#  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+#  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+#  CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+#  TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+#  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+__version__ = 'SPARK-0.7 (pre-alpha-5)'
+
+import re
+import sys
+import string
+
+def _namelist(instance):
+    namelist, namedict, classlist = [], {}, [instance.__class__]
+    for c in classlist:
+        for b in c.__bases__:
+            classlist.append(b)
+        for name in c.__dict__.keys():
+            if not namedict.has_key(name):
+                namelist.append(name)
+                namedict[name] = 1
+    return namelist
+
+class GenericScanner:
+    def __init__(self, flags=0):
+        pattern = self.reflect()
+        self.re = re.compile(pattern, re.VERBOSE|flags)
+
+        self.index2func = {}
+        for name, number in self.re.groupindex.items():
+            self.index2func[number-1] = getattr(self, 't_' + name)
+
+    def makeRE(self, name):
+        doc = getattr(self, name).__doc__
+        rv = '(?P<%s>%s)' % (name[2:], doc)
+        return rv
+
+    def reflect(self):
+        rv = []
+        for name in _namelist(self):
+            if name[:2] == 't_' and name != 't_default':
+                rv.append(self.makeRE(name))
+
+        rv.append(self.makeRE('t_default'))
+        return string.join(rv, '|')
+
+    def error(self, s, pos):
+        print "Lexical error at position %s" % pos
+        raise SystemExit
+
+    def tokenize(self, s):
+        pos = 0
+        n = len(s)
+        while pos < n:
+            m = self.re.match(s, pos)
+            if m is None:
+                self.error(s, pos)
+
+            groups = m.groups()
+            for i in range(len(groups)):
+                if groups[i] and self.index2func.has_key(i):
+                    self.index2func[i](groups[i])
+            pos = m.end()
+
+    def t_default(self, s):
+        r'( . | \n )+'
+        print "Specification error: unmatched input"
+        raise SystemExit
+
+#
+#  Extracted from GenericParser and made global so that [un]picking works.
+#
+class _State:
+    def __init__(self, stateno, items):
+        self.T, self.complete, self.items = [], [], items
+        self.stateno = stateno
+
+class GenericParser:
+    #
+    #  An Earley parser, as per J. Earley, "An Efficient Context-Free
+    #  Parsing Algorithm", CACM 13(2), pp. 94-102.  Also J. C. Earley,
+    #  "An Efficient Context-Free Parsing Algorithm", Ph.D. thesis,
+    #  Carnegie-Mellon University, August 1968.  New formulation of
+    #  the parser according to J. Aycock, "Practical Earley Parsing
+    #  and the SPARK Toolkit", Ph.D. thesis, University of Victoria,
+    #  2001, and J. Aycock and R. N. Horspool, "Practical Earley
+    #  Parsing", unpublished paper, 2001.
+    #
+
+    def __init__(self, start):
+        self.rules = {}
+        self.rule2func = {}
+        self.rule2name = {}
+        self.collectRules()
+        self.augment(start)
+        self.ruleschanged = 1
+
+    _NULLABLE = '\e_'
+    _START = 'START'
+    _BOF = '|-'
+
+    #
+    #  When pickling, take the time to generate the full state machine;
+    #  some information is then extraneous, too.  Unfortunately we
+    #  can't save the rule2func map.
+    #
+    def __getstate__(self):
+        if self.ruleschanged:
+            #
+            #  XXX - duplicated from parse()
+            #
+            self.computeNull()
+            self.newrules = {}
+            self.new2old = {}
+            self.makeNewRules()
+            self.ruleschanged = 0
+            self.edges, self.cores = {}, {}
+            self.states = { 0: self.makeState0() }
+            self.makeState(0, self._BOF)
+        #
+        #  XXX - should find a better way to do this..
+        #
+        changes = 1
+        while changes:
+            changes = 0
+            for k, v in self.edges.items():
+                if v is None:
+                    state, sym = k
+                    if self.states.has_key(state):
+                        self.goto(state, sym)
+                        changes = 1
+        rv = self.__dict__.copy()
+        for s in self.states.values():
+            del s.items
+        del rv['rule2func']
+        del rv['nullable']
+        del rv['cores']
+        return rv
+
+    def __setstate__(self, D):
+        self.rules = {}
+        self.rule2func = {}
+        self.rule2name = {}
+        self.collectRules()
+        start = D['rules'][self._START][0][1][1]        # Blech.
+        self.augment(start)
+        D['rule2func'] = self.rule2func
+        D['makeSet'] = self.makeSet_fast
+        self.__dict__ = D
+
+    #
+    #  A hook for GenericASTBuilder and GenericASTMatcher.  Mess
+    #  thee not with this; nor shall thee toucheth the _preprocess
+    #  argument to addRule.
+    #
+    def preprocess(self, rule, func):       return rule, func
+
+    def addRule(self, doc, func, _preprocess=1):
+        fn = func
+        rules = string.split(doc)
+
+        index = []
+        for i in range(len(rules)):
+            if rules[i] == '::=':
+                index.append(i-1)
+        index.append(len(rules))
+
+        for i in range(len(index)-1):
+            lhs = rules[index[i]]
+            rhs = rules[index[i]+2:index[i+1]]
+            rule = (lhs, tuple(rhs))
+
+            if _preprocess:
+                rule, fn = self.preprocess(rule, func)
+
+            if self.rules.has_key(lhs):
+                self.rules[lhs].append(rule)
+            else:
+                self.rules[lhs] = [ rule ]
+            self.rule2func[rule] = fn
+            self.rule2name[rule] = func.__name__[2:]
+        self.ruleschanged = 1
+
+    def collectRules(self):
+        for name in _namelist(self):
+            if name[:2] == 'p_':
+                func = getattr(self, name)
+                doc = func.__doc__
+                self.addRule(doc, func)
+
+    def augment(self, start):
+        rule = '%s ::= %s %s' % (self._START, self._BOF, start)
+        self.addRule(rule, lambda args: args[1], 0)
+
+    def computeNull(self):
+        self.nullable = {}
+        tbd = []
+
+        for rulelist in self.rules.values():
+            lhs = rulelist[0][0]
+            self.nullable[lhs] = 0
+            for rule in rulelist:
+                rhs = rule[1]
+                if len(rhs) == 0:
+                    self.nullable[lhs] = 1
+                    continue
+                #
+                #  We only need to consider rules which
+                #  consist entirely of nonterminal symbols.
+                #  This should be a savings on typical
+                #  grammars.
+                #
+                for sym in rhs:
+                    if not self.rules.has_key(sym):
+                        break
+                else:
+                    tbd.append(rule)
+        changes = 1
+        while changes:
+            changes = 0
+            for lhs, rhs in tbd:
+                if self.nullable[lhs]:
+                    continue
+                for sym in rhs:
+                    if not self.nullable[sym]:
+                        break
+                else:
+                    self.nullable[lhs] = 1
+                    changes = 1
+
+    def makeState0(self):
+        s0 = _State(0, [])
+        for rule in self.newrules[self._START]:
+            s0.items.append((rule, 0))
+        return s0
+
+    def finalState(self, tokens):
+        #
+        #  Yuck.
+        #
+        if len(self.newrules[self._START]) == 2 and len(tokens) == 0:
+            return 1
+        start = self.rules[self._START][0][1][1]
+        return self.goto(1, start)
+
+    def makeNewRules(self):
+        worklist = []
+        for rulelist in self.rules.values():
+            for rule in rulelist:
+                worklist.append((rule, 0, 1, rule))
+
+        for rule, i, candidate, oldrule in worklist:
+            lhs, rhs = rule
+            n = len(rhs)
+            while i < n:
+                sym = rhs[i]
+                if not self.rules.has_key(sym) or \
+                   not self.nullable[sym]:
+                    candidate = 0
+                    i = i + 1
+                    continue
+
+                newrhs = list(rhs)
+                newrhs[i] = self._NULLABLE+sym
+                newrule = (lhs, tuple(newrhs))
+                worklist.append((newrule, i+1,
+                                 candidate, oldrule))
+                candidate = 0
+                i = i + 1
+            else:
+                if candidate:
+                    lhs = self._NULLABLE+lhs
+                    rule = (lhs, rhs)
+                if self.newrules.has_key(lhs):
+                    self.newrules[lhs].append(rule)
+                else:
+                    self.newrules[lhs] = [ rule ]
+                self.new2old[rule] = oldrule
+
+    def typestring(self, token):
+        return None
+
+    def error(self, token):
+        print "Syntax error at or near `%s' token" % token
+        raise SystemExit
+
+    def parse(self, tokens):
+        sets = [ [(1,0), (2,0)] ]
+        self.links = {}
+
+        if self.ruleschanged:
+            self.computeNull()
+            self.newrules = {}
+            self.new2old = {}
+            self.makeNewRules()
+            self.ruleschanged = 0
+            self.edges, self.cores = {}, {}
+            self.states = { 0: self.makeState0() }
+            self.makeState(0, self._BOF)
+
+        for i in xrange(len(tokens)):
+            sets.append([])
+
+            if sets[i] == []:
+                break
+            self.makeSet(tokens[i], sets, i)
+        else:
+            sets.append([])
+            self.makeSet(None, sets, len(tokens))
+
+        #_dump(tokens, sets, self.states)
+
+        finalitem = (self.finalState(tokens), 0)
+        if finalitem not in sets[-2]:
+            if len(tokens) > 0:
+                self.error(tokens[i-1])
+            else:
+                self.error(None)
+
+        return self.buildTree(self._START, finalitem,
+                              tokens, len(sets)-2)
+
+    def isnullable(self, sym):
+        #
+        #  For symbols in G_e only.  If we weren't supporting 1.5,
+        #  could just use sym.startswith().
+        #
+        return self._NULLABLE == sym[0:len(self._NULLABLE)]
+
+    def skip(self, (lhs, rhs), pos=0):
+        n = len(rhs)
+        while pos < n:
+            if not self.isnullable(rhs[pos]):
+                break
+            pos = pos + 1
+        return pos
+
+    def makeState(self, state, sym):
+        assert sym is not None
+        #
+        #  Compute \epsilon-kernel state's core and see if
+        #  it exists already.
+        #
+        kitems = []
+        for rule, pos in self.states[state].items:
+            lhs, rhs = rule
+            if rhs[pos:pos+1] == (sym,):
+                kitems.append((rule, self.skip(rule, pos+1)))
+        core = kitems
+
+        core.sort()
+        tcore = tuple(core)
+        if self.cores.has_key(tcore):
+            return self.cores[tcore]
+        #
+        #  Nope, doesn't exist.  Compute it and the associated
+        #  \epsilon-nonkernel state together; we'll need it right away.
+        #
+        k = self.cores[tcore] = len(self.states)
+        K, NK = _State(k, kitems), _State(k+1, [])
+        self.states[k] = K
+        predicted = {}
+
+        edges = self.edges
+        rules = self.newrules
+        for X in K, NK:
+            worklist = X.items
+            for item in worklist:
+                rule, pos = item
+                lhs, rhs = rule
+                if pos == len(rhs):
+                    X.complete.append(rule)
+                    continue
+
+                nextSym = rhs[pos]
+                key = (X.stateno, nextSym)
+                if not rules.has_key(nextSym):
+                    if not edges.has_key(key):
+                        edges[key] = None
+                        X.T.append(nextSym)
+                else:
+                    edges[key] = None
+                    if not predicted.has_key(nextSym):
+                        predicted[nextSym] = 1
+                        for prule in rules[nextSym]:
+                            ppos = self.skip(prule)
+                            new = (prule, ppos)
+                            NK.items.append(new)
+            #
+            #  Problem: we know K needs generating, but we
+            #  don't yet know about NK.  Can't commit anything
+            #  regarding NK to self.edges until we're sure.  Should
+            #  we delay committing on both K and NK to avoid this
+            #  hacky code?  This creates other problems..
+            #
+            if X is K:
+                edges = {}
+
+        if NK.items == []:
+            return k
+
+        #
+        #  Check for \epsilon-nonkernel's core.  Unfortunately we
+        #  need to know the entire set of predicted nonterminals
+        #  to do this without accidentally duplicating states.
+        #
+        core = predicted.keys()
+        core.sort()
+        tcore = tuple(core)
+        if self.cores.has_key(tcore):
+            self.edges[(k, None)] = self.cores[tcore]
+            return k
+
+        nk = self.cores[tcore] = self.edges[(k, None)] = NK.stateno
+        self.edges.update(edges)
+        self.states[nk] = NK
+        return k
+
+    def goto(self, state, sym):
+        key = (state, sym)
+        if not self.edges.has_key(key):
+            #
+            #  No transitions from state on sym.
+            #
+            return None
+
+        rv = self.edges[key]
+        if rv is None:
+            #
+            #  Target state isn't generated yet.  Remedy this.
+            #
+            rv = self.makeState(state, sym)
+            self.edges[key] = rv
+        return rv
+
+    def gotoT(self, state, t):
+        return [self.goto(state, t)]
+
+    def gotoST(self, state, st):
+        rv = []
+        for t in self.states[state].T:
+            if st == t:
+                rv.append(self.goto(state, t))
+        return rv
+
+    def add(self, set, item, i=None, predecessor=None, causal=None):
+        if predecessor is None:
+            if item not in set:
+                set.append(item)
+        else:
+            key = (item, i)
+            if item not in set:
+                self.links[key] = []
+                set.append(item)
+            self.links[key].append((predecessor, causal))
+
+    def makeSet(self, token, sets, i):
+        cur, next = sets[i], sets[i+1]
+
+        ttype = token is not None and self.typestring(token) or None
+        if ttype is not None:
+            fn, arg = self.gotoT, ttype
+        else:
+            fn, arg = self.gotoST, token
+
+        for item in cur:
+            ptr = (item, i)
+            state, parent = item
+            add = fn(state, arg)
+            for k in add:
+                if k is not None:
+                    self.add(next, (k, parent), i+1, ptr)
+                    nk = self.goto(k, None)
+                    if nk is not None:
+                        self.add(next, (nk, i+1))
+
+            if parent == i:
+                continue
+
+            for rule in self.states[state].complete:
+                lhs, rhs = rule
+                for pitem in sets[parent]:
+                    pstate, pparent = pitem
+                    k = self.goto(pstate, lhs)
+                    if k is not None:
+                        why = (item, i, rule)
+                        pptr = (pitem, parent)
+                        self.add(cur, (k, pparent),
+                                 i, pptr, why)
+                        nk = self.goto(k, None)
+                        if nk is not None:
+                            self.add(cur, (nk, i))
+
+    def makeSet_fast(self, token, sets, i):
+        #
+        #  Call *only* when the entire state machine has been built!
+        #  It relies on self.edges being filled in completely, and
+        #  then duplicates and inlines code to boost speed at the
+        #  cost of extreme ugliness.
+        #
+        cur, next = sets[i], sets[i+1]
+        ttype = token is not None and self.typestring(token) or None
+
+        for item in cur:
+            ptr = (item, i)
+            state, parent = item
+            if ttype is not None:
+                k = self.edges.get((state, ttype), None)
+                if k is not None:
+                    #self.add(next, (k, parent), i+1, ptr)
+                    #INLINED --v
+                    new = (k, parent)
+                    key = (new, i+1)
+                    if new not in next:
+                        self.links[key] = []
+                        next.append(new)
+                    self.links[key].append((ptr, None))
+                    #INLINED --^
+                    #nk = self.goto(k, None)
+                    nk = self.edges.get((k, None), None)
+                    if nk is not None:
+                        #self.add(next, (nk, i+1))
+                        #INLINED --v
+                        new = (nk, i+1)
+                        if new not in next:
+                            next.append(new)
+                        #INLINED --^
+            else:
+                add = self.gotoST(state, token)
+                for k in add:
+                    if k is not None:
+                        self.add(next, (k, parent), i+1, ptr)
+                        #nk = self.goto(k, None)
+                        nk = self.edges.get((k, None), None)
+                        if nk is not None:
+                            self.add(next, (nk, i+1))
+
+            if parent == i:
+                continue
+
+            for rule in self.states[state].complete:
+                lhs, rhs = rule
+                for pitem in sets[parent]:
+                    pstate, pparent = pitem
+                    #k = self.goto(pstate, lhs)
+                    k = self.edges.get((pstate, lhs), None)
+                    if k is not None:
+                        why = (item, i, rule)
+                        pptr = (pitem, parent)
+                        #self.add(cur, (k, pparent),
+                        #        i, pptr, why)
+                        #INLINED --v
+                        new = (k, pparent)
+                        key = (new, i)
+                        if new not in cur:
+                            self.links[key] = []
+                            cur.append(new)
+                        self.links[key].append((pptr, why))
+                        #INLINED --^
+                        #nk = self.goto(k, None)
+                        nk = self.edges.get((k, None), None)
+                        if nk is not None:
+                            #self.add(cur, (nk, i))
+                            #INLINED --v
+                            new = (nk, i)
+                            if new not in cur:
+                                cur.append(new)
+                            #INLINED --^
+
+    def predecessor(self, key, causal):
+        for p, c in self.links[key]:
+            if c == causal:
+                return p
+        assert 0
+
+    def causal(self, key):
+        links = self.links[key]
+        if len(links) == 1:
+            return links[0][1]
+        choices = []
+        rule2cause = {}
+        for p, c in links:
+            rule = c[2]
+            choices.append(rule)
+            rule2cause[rule] = c
+        return rule2cause[self.ambiguity(choices)]
+
+    def deriveEpsilon(self, nt):
+        if len(self.newrules[nt]) > 1:
+            rule = self.ambiguity(self.newrules[nt])
+        else:
+            rule = self.newrules[nt][0]
+        #print rule
+
+        rhs = rule[1]
+        attr = [None] * len(rhs)
+
+        for i in range(len(rhs)-1, -1, -1):
+            attr[i] = self.deriveEpsilon(rhs[i])
+        return self.rule2func[self.new2old[rule]](attr)
+
+    def buildTree(self, nt, item, tokens, k):
+        state, parent = item
+
+        choices = []
+        for rule in self.states[state].complete:
+            if rule[0] == nt:
+                choices.append(rule)
+        rule = choices[0]
+        if len(choices) > 1:
+            rule = self.ambiguity(choices)
+        #print rule
+
+        rhs = rule[1]
+        attr = [None] * len(rhs)
+
+        for i in range(len(rhs)-1, -1, -1):
+            sym = rhs[i]
+            if not self.newrules.has_key(sym):
+                if sym != self._BOF:
+                    attr[i] = tokens[k-1]
+                    key = (item, k)
+                    item, k = self.predecessor(key, None)
+            #elif self.isnullable(sym):
+            elif self._NULLABLE == sym[0:len(self._NULLABLE)]:
+                attr[i] = self.deriveEpsilon(sym)
+            else:
+                key = (item, k)
+                why = self.causal(key)
+                attr[i] = self.buildTree(sym, why[0],
+                                         tokens, why[1])
+                item, k = self.predecessor(key, why)
+        return self.rule2func[self.new2old[rule]](attr)
+
+    def ambiguity(self, rules):
+        #
+        #  XXX - problem here and in collectRules() if the same rule
+        #        appears in >1 method.  Also undefined results if rules
+        #        causing the ambiguity appear in the same method.
+        #
+        sortlist = []
+        name2index = {}
+        for i in range(len(rules)):
+            lhs, rhs = rule = rules[i]
+            name = self.rule2name[self.new2old[rule]]
+            sortlist.append((len(rhs), name))
+            name2index[name] = i
+        sortlist.sort()
+        list = map(lambda (a,b): b, sortlist)
+        return rules[name2index[self.resolve(list)]]
+
+    def resolve(self, list):
+        #
+        #  Resolve ambiguity in favor of the shortest RHS.
+        #  Since we walk the tree from the top down, this
+        #  should effectively resolve in favor of a "shift".
+        #
+        return list[0]
+
+#
+#  GenericASTBuilder automagically constructs a concrete/abstract syntax tree
+#  for a given input.  The extra argument is a class (not an instance!)
+#  which supports the "__setslice__" and "__len__" methods.
+#
+#  XXX - silently overrides any user code in methods.
+#
+
+class GenericASTBuilder(GenericParser):
+    def __init__(self, AST, start):
+        GenericParser.__init__(self, start)
+        self.AST = AST
+
+    def preprocess(self, rule, func):
+        rebind = lambda lhs, self=self: \
+                        lambda args, lhs=lhs, self=self: \
+                                self.buildASTNode(args, lhs)
+        lhs, rhs = rule
+        return rule, rebind(lhs)
+
+    def buildASTNode(self, args, lhs):
+        children = []
+        for arg in args:
+            if isinstance(arg, self.AST):
+                children.append(arg)
+            else:
+                children.append(self.terminal(arg))
+        return self.nonterminal(lhs, children)
+
+    def terminal(self, token):      return token
+
+    def nonterminal(self, type, args):
+        rv = self.AST(type)
+        rv[:len(args)] = args
+        return rv
+
+#
+#  GenericASTTraversal is a Visitor pattern according to Design Patterns.  For
+#  each node it attempts to invoke the method n_<node type>, falling
+#  back onto the default() method if the n_* can't be found.  The preorder
+#  traversal also looks for an exit hook named n_<node type>_exit (no default
+#  routine is called if it's not found).  To prematurely halt traversal
+#  of a subtree, call the prune() method -- this only makes sense for a
+#  preorder traversal.  Node type is determined via the typestring() method.
+#
+
+class GenericASTTraversalPruningException:
+    pass
+
+class GenericASTTraversal:
+    def __init__(self, ast):
+        self.ast = ast
+
+    def typestring(self, node):
+        return node.type
+
+    def prune(self):
+        raise GenericASTTraversalPruningException
+
+    def preorder(self, node=None):
+        if node is None:
+            node = self.ast
+
+        try:
+            name = 'n_' + self.typestring(node)
+            if hasattr(self, name):
+                func = getattr(self, name)
+                func(node)
+            else:
+                self.default(node)
+        except GenericASTTraversalPruningException:
+            return
+
+        for kid in node:
+            self.preorder(kid)
+
+        name = name + '_exit'
+        if hasattr(self, name):
+            func = getattr(self, name)
+            func(node)
+
+    def postorder(self, node=None):
+        if node is None:
+            node = self.ast
+
+        for kid in node:
+            self.postorder(kid)
+
+        name = 'n_' + self.typestring(node)
+        if hasattr(self, name):
+            func = getattr(self, name)
+            func(node)
+        else:
+            self.default(node)
+
+
+    def default(self, node):
+        pass
+
+#
+#  GenericASTMatcher.  AST nodes must have "__getitem__" and "__cmp__"
+#  implemented.
+#
+#  XXX - makes assumptions about how GenericParser walks the parse tree.
+#
+
+class GenericASTMatcher(GenericParser):
+    def __init__(self, start, ast):
+        GenericParser.__init__(self, start)
+        self.ast = ast
+
+    def preprocess(self, rule, func):
+        rebind = lambda func, self=self: \
+                        lambda args, func=func, self=self: \
+                                self.foundMatch(args, func)
+        lhs, rhs = rule
+        rhslist = list(rhs)
+        rhslist.reverse()
+
+        return (lhs, tuple(rhslist)), rebind(func)
+
+    def foundMatch(self, args, func):
+        func(args[-1])
+        return args[-1]
+
+    def match_r(self, node):
+        self.input.insert(0, node)
+        children = 0
+
+        for child in node:
+            if children == 0:
+                self.input.insert(0, '(')
+            children = children + 1
+            self.match_r(child)
+
+        if children > 0:
+            self.input.insert(0, ')')
+
+    def match(self, ast=None):
+        if ast is None:
+            ast = self.ast
+        self.input = []
+
+        self.match_r(ast)
+        self.parse(self.input)
+
+    def resolve(self, list):
+        #
+        #  Resolve ambiguity in favor of the longest RHS.
+        #
+        return list[-1]
+
+def _dump(tokens, sets, states):
+    for i in range(len(sets)):
+        print 'set', i
+        for item in sets[i]:
+            print '\t', item
+            for (lhs, rhs), pos in states[item[0]].items:
+                print '\t\t', lhs, '::=',
+                print string.join(rhs[:pos]),
+                print '.',
+                print string.join(rhs[pos:])
+        if i < len(tokens):
+            print
+            print 'token', str(tokens[i])
+            print

Added: vendor/Python/current/Parser/tokenizer.c
===================================================================
--- vendor/Python/current/Parser/tokenizer.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Parser/tokenizer.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1535 @@
+
+/* Tokenizer implementation */
+
+#include "Python.h"
+#include "pgenheaders.h"
+
+#include <ctype.h>
+#include <assert.h>
+
+#include "tokenizer.h"
+#include "errcode.h"
+
+#ifndef PGEN
+#include "unicodeobject.h"
+#include "stringobject.h"
+#include "fileobject.h"
+#include "codecs.h"
+#include "abstract.h"
+#endif /* PGEN */
+
+extern char *PyOS_Readline(FILE *, FILE *, char *);
+/* Return malloc'ed string including trailing \n;
+   empty malloc'ed string for EOF;
+   NULL if interrupted */
+
+/* Don't ever change this -- it would break the portability of Python code */
+#define TABSIZE 8
+
+/* Convert a possibly signed character to a nonnegative int */
+/* XXX This assumes characters are 8 bits wide */
+#ifdef __CHAR_UNSIGNED__
+#define Py_CHARMASK(c)		(c)
+#else
+#define Py_CHARMASK(c)		((c) & 0xff)
+#endif
+
+/* Forward */
+static struct tok_state *tok_new(void);
+static int tok_nextc(struct tok_state *tok);
+static void tok_backup(struct tok_state *tok, int c);
+
+/* Token names */
+
+char *_PyParser_TokenNames[] = {
+	"ENDMARKER",
+	"NAME",
+	"NUMBER",
+	"STRING",
+	"NEWLINE",
+	"INDENT",
+	"DEDENT",
+	"LPAR",
+	"RPAR",
+	"LSQB",
+	"RSQB",
+	"COLON",
+	"COMMA",
+	"SEMI",
+	"PLUS",
+	"MINUS",
+	"STAR",
+	"SLASH",
+	"VBAR",
+	"AMPER",
+	"LESS",
+	"GREATER",
+	"EQUAL",
+	"DOT",
+	"PERCENT",
+	"BACKQUOTE",
+	"LBRACE",
+	"RBRACE",
+	"EQEQUAL",
+	"NOTEQUAL",
+	"LESSEQUAL",
+	"GREATEREQUAL",
+	"TILDE",
+	"CIRCUMFLEX",
+	"LEFTSHIFT",
+	"RIGHTSHIFT",
+	"DOUBLESTAR",
+	"PLUSEQUAL",
+	"MINEQUAL",
+	"STAREQUAL",
+	"SLASHEQUAL",
+	"PERCENTEQUAL",
+	"AMPEREQUAL",
+	"VBAREQUAL",
+	"CIRCUMFLEXEQUAL",
+	"LEFTSHIFTEQUAL",
+	"RIGHTSHIFTEQUAL",
+	"DOUBLESTAREQUAL",
+	"DOUBLESLASH",
+	"DOUBLESLASHEQUAL",
+	"AT",
+	/* This table must match the #defines in token.h! */
+	"OP",
+	"<ERRORTOKEN>",
+	"<N_TOKENS>"
+};
+
+
+/* Create and initialize a new tok_state structure */
+
+static struct tok_state *
+tok_new(void)
+{
+	struct tok_state *tok = (struct tok_state *)PyMem_MALLOC(
+                                                sizeof(struct tok_state));
+	if (tok == NULL)
+		return NULL;
+	tok->buf = tok->cur = tok->end = tok->inp = tok->start = NULL;
+	tok->done = E_OK;
+	tok->fp = NULL;
+	tok->tabsize = TABSIZE;
+	tok->indent = 0;
+	tok->indstack[0] = 0;
+	tok->atbol = 1;
+	tok->pendin = 0;
+	tok->prompt = tok->nextprompt = NULL;
+	tok->lineno = 0;
+	tok->level = 0;
+	tok->filename = NULL;
+	tok->altwarning = 0;
+	tok->alterror = 0;
+	tok->alttabsize = 1;
+	tok->altindstack[0] = 0;
+	tok->decoding_state = 0;
+	tok->decoding_erred = 0;
+	tok->read_coding_spec = 0;
+	tok->encoding = NULL;
+        tok->cont_line = 0;
+#ifndef PGEN
+	tok->decoding_readline = NULL;
+	tok->decoding_buffer = NULL;
+#endif
+	return tok;
+}
+
+#ifdef PGEN
+
+static char *
+decoding_fgets(char *s, int size, struct tok_state *tok)
+{
+	return fgets(s, size, tok->fp);
+}
+
+static int
+decoding_feof(struct tok_state *tok)
+{
+	return feof(tok->fp);
+}
+
+static const char *
+decode_str(const char *str, struct tok_state *tok)
+{
+	return str;
+}
+
+#else /* PGEN */
+
+static char *
+error_ret(struct tok_state *tok) /* XXX */
+{
+	tok->decoding_erred = 1;
+	if (tok->fp != NULL && tok->buf != NULL) /* see PyTokenizer_Free */
+		PyMem_FREE(tok->buf);
+	tok->buf = NULL;
+	return NULL;		/* as if it were EOF */
+}
+
+static char *
+new_string(const char *s, Py_ssize_t len)
+{
+	char* result = (char *)PyMem_MALLOC(len + 1);
+	if (result != NULL) {
+		memcpy(result, s, len);
+		result[len] = '\0';
+	}
+	return result;
+}
+
+static char *
+get_normal_name(char *s)	/* for utf-8 and latin-1 */
+{
+	char buf[13];
+	int i;
+	for (i = 0; i < 12; i++) {
+		int c = s[i];
+		if (c == '\0') break;
+		else if (c == '_') buf[i] = '-';
+		else buf[i] = tolower(c);
+	}
+	buf[i] = '\0';
+	if (strcmp(buf, "utf-8") == 0 ||
+	    strncmp(buf, "utf-8-", 6) == 0) return "utf-8";
+	else if (strcmp(buf, "latin-1") == 0 ||
+		 strcmp(buf, "iso-8859-1") == 0 ||
+		 strcmp(buf, "iso-latin-1") == 0 ||
+		 strncmp(buf, "latin-1-", 8) == 0 ||
+		 strncmp(buf, "iso-8859-1-", 11) == 0 ||
+		 strncmp(buf, "iso-latin-1-", 12) == 0) return "iso-8859-1";
+	else return s;
+}
+
+/* Return the coding spec in S, or NULL if none is found.  */
+
+static char *
+get_coding_spec(const char *s, Py_ssize_t size)
+{
+	Py_ssize_t i;
+	/* Coding spec must be in a comment, and that comment must be
+         * the only statement on the source code line. */
+        for (i = 0; i < size - 6; i++) {
+		if (s[i] == '#')
+			break;
+		if (s[i] != ' ' && s[i] != '\t' && s[i] != '\014')
+			return NULL;
+	}
+	for (; i < size - 6; i++) { /* XXX inefficient search */
+		const char* t = s + i;
+		if (strncmp(t, "coding", 6) == 0) {
+			const char* begin = NULL;
+			t += 6;
+			if (t[0] != ':' && t[0] != '=')
+				continue;
+			do {
+				t++;
+			} while (t[0] == '\x20' || t[0] == '\t');
+
+			begin = t;
+			while (isalnum(Py_CHARMASK(t[0])) ||
+			       t[0] == '-' || t[0] == '_' || t[0] == '.')
+				t++;
+
+			if (begin < t) {
+				char* r = new_string(begin, t - begin);
+				char* q = get_normal_name(r);
+				if (r != q) {
+					PyMem_FREE(r);
+					r = new_string(q, strlen(q));
+				}
+				return r;
+			}
+		}
+	}
+	return NULL;
+}
+
+/* Check whether the line contains a coding spec. If it does,
+   invoke the set_readline function for the new encoding.
+   This function receives the tok_state and the new encoding.
+   Return 1 on success, 0 on failure.  */
+
+static int
+check_coding_spec(const char* line, Py_ssize_t size, struct tok_state *tok,
+		  int set_readline(struct tok_state *, const char *))
+{
+	char * cs;
+	int r = 1;
+
+        if (tok->cont_line)
+		/* It's a continuation line, so it can't be a coding spec. */
+		return 1;
+	cs = get_coding_spec(line, size);
+	if (cs != NULL) {
+		tok->read_coding_spec = 1;
+		if (tok->encoding == NULL) {
+			assert(tok->decoding_state == 1); /* raw */
+			if (strcmp(cs, "utf-8") == 0 ||
+			    strcmp(cs, "iso-8859-1") == 0) {
+				tok->encoding = cs;
+			} else {
+#ifdef Py_USING_UNICODE
+				r = set_readline(tok, cs);
+				if (r) {
+					tok->encoding = cs;
+					tok->decoding_state = -1;
+				}
+				else
+					PyMem_FREE(cs);
+#else
+                                /* Without Unicode support, we cannot
+                                   process the coding spec. Since there
+                                   won't be any Unicode literals, that
+                                   won't matter. */
+				PyMem_FREE(cs);
+#endif
+			}
+		} else {	/* then, compare cs with BOM */
+			r = (strcmp(tok->encoding, cs) == 0);
+			PyMem_FREE(cs);
+		}
+	}
+	if (!r) {
+		cs = tok->encoding;
+		if (!cs)
+			cs = "with BOM";
+		PyErr_Format(PyExc_SyntaxError, "encoding problem: %s", cs);
+	}
+	return r;
+}
+
+/* See whether the file starts with a BOM. If it does,
+   invoke the set_readline function with the new encoding.
+   Return 1 on success, 0 on failure.  */
+
+static int
+check_bom(int get_char(struct tok_state *),
+	  void unget_char(int, struct tok_state *),
+	  int set_readline(struct tok_state *, const char *),
+	  struct tok_state *tok)
+{
+	int ch = get_char(tok);
+	tok->decoding_state = 1;
+	if (ch == EOF) {
+		return 1;
+	} else if (ch == 0xEF) {
+		ch = get_char(tok); if (ch != 0xBB) goto NON_BOM;
+		ch = get_char(tok); if (ch != 0xBF) goto NON_BOM;
+#if 0
+	/* Disable support for UTF-16 BOMs until a decision
+	   is made whether this needs to be supported.  */
+	} else if (ch == 0xFE) {
+		ch = get_char(tok); if (ch != 0xFF) goto NON_BOM;
+		if (!set_readline(tok, "utf-16-be")) return 0;
+		tok->decoding_state = -1;
+	} else if (ch == 0xFF) {
+		ch = get_char(tok); if (ch != 0xFE) goto NON_BOM;
+		if (!set_readline(tok, "utf-16-le")) return 0;
+		tok->decoding_state = -1;
+#endif
+	} else {
+		unget_char(ch, tok);
+		return 1;
+	}
+	if (tok->encoding != NULL)
+		PyMem_FREE(tok->encoding);
+	tok->encoding = new_string("utf-8", 5);	/* resulting is in utf-8 */
+	return 1;
+  NON_BOM:
+	/* any token beginning with '\xEF', '\xFE', '\xFF' is a bad token */
+	unget_char(0xFF, tok);	/* XXX this will cause a syntax error */
+	return 1;
+}
+
+/* Read a line of text from TOK into S, using the stream in TOK.
+   Return NULL on failure, else S.
+
+   On entry, tok->decoding_buffer will be one of:
+     1) NULL: need to call tok->decoding_readline to get a new line
+     2) PyUnicodeObject *: decoding_feof has called tok->decoding_readline and
+           stored the result in tok->decoding_buffer
+     3) PyStringObject *: previous call to fp_readl did not have enough room
+           (in the s buffer) to copy entire contents of the line read
+           by tok->decoding_readline.  tok->decoding_buffer has the overflow.
+           In this case, fp_readl is called in a loop (with an expanded buffer)
+           until the buffer ends with a '\n' (or until the end of the file is
+           reached): see tok_nextc and its calls to decoding_fgets.
+*/
+
+static char *
+fp_readl(char *s, int size, struct tok_state *tok)
+{
+#ifndef Py_USING_UNICODE
+	/* In a non-Unicode built, this should never be called. */
+	Py_FatalError("fp_readl should not be called in this build.");
+	return NULL; /* Keep compiler happy (not reachable) */
+#else
+	PyObject* utf8 = NULL;
+	PyObject* buf = tok->decoding_buffer;
+	char *str;
+	Py_ssize_t utf8len;
+
+	/* Ask for one less byte so we can terminate it */
+	assert(size > 0);
+	size--;
+
+	if (buf == NULL) {
+		buf = PyObject_CallObject(tok->decoding_readline, NULL);
+		if (buf == NULL)
+			return error_ret(tok);
+	} else {
+		tok->decoding_buffer = NULL;
+		if (PyString_CheckExact(buf))
+			utf8 = buf;
+	}
+	if (utf8 == NULL) {
+		utf8 = PyUnicode_AsUTF8String(buf);
+		Py_DECREF(buf);
+		if (utf8 == NULL)
+			return error_ret(tok);
+	}
+	str = PyString_AsString(utf8);
+	utf8len = PyString_GET_SIZE(utf8);
+	if (utf8len > size) {
+		tok->decoding_buffer = PyString_FromStringAndSize(str+size, utf8len-size);
+		if (tok->decoding_buffer == NULL) {
+			Py_DECREF(utf8);
+			return error_ret(tok);
+		}
+		utf8len = size;
+	}
+	memcpy(s, str, utf8len);
+	s[utf8len] = '\0';
+	Py_DECREF(utf8);
+	if (utf8len == 0) return NULL; /* EOF */
+	return s;
+#endif
+}
+
+/* Set the readline function for TOK to a StreamReader's
+   readline function. The StreamReader is named ENC.
+
+   This function is called from check_bom and check_coding_spec.
+
+   ENC is usually identical to the future value of tok->encoding,
+   except for the (currently unsupported) case of UTF-16.
+
+   Return 1 on success, 0 on failure. */
+
+static int
+fp_setreadl(struct tok_state *tok, const char* enc)
+{
+	PyObject *reader, *stream, *readline;
+
+	/* XXX: constify filename argument. */
+	stream = PyFile_FromFile(tok->fp, (char*)tok->filename, "rb", NULL);
+	if (stream == NULL)
+		return 0;
+
+	reader = PyCodec_StreamReader(enc, stream, NULL);
+	Py_DECREF(stream);
+	if (reader == NULL)
+		return 0;
+
+	readline = PyObject_GetAttrString(reader, "readline");
+	Py_DECREF(reader);
+	if (readline == NULL)
+		return 0;
+
+	tok->decoding_readline = readline;
+	return 1;
+}
+
+/* Fetch the next byte from TOK. */
+
+static int fp_getc(struct tok_state *tok) {
+	return getc(tok->fp);
+}
+
+/* Unfetch the last byte back into TOK.  */
+
+static void fp_ungetc(int c, struct tok_state *tok) {
+	ungetc(c, tok->fp);
+}
+
+/* Read a line of input from TOK. Determine encoding
+   if necessary.  */
+
+static char *
+decoding_fgets(char *s, int size, struct tok_state *tok)
+{
+	char *line = NULL;
+	int badchar = 0;
+	for (;;) {
+		if (tok->decoding_state < 0) {
+			/* We already have a codec associated with
+			   this input. */
+			line = fp_readl(s, size, tok);
+			break;
+		} else if (tok->decoding_state > 0) {
+			/* We want a 'raw' read. */
+			line = Py_UniversalNewlineFgets(s, size,
+							tok->fp, NULL);
+			break;
+		} else {
+			/* We have not yet determined the encoding.
+			   If an encoding is found, use the file-pointer
+			   reader functions from now on. */
+			if (!check_bom(fp_getc, fp_ungetc, fp_setreadl, tok))
+				return error_ret(tok);
+			assert(tok->decoding_state != 0);
+		}
+	}
+	if (line != NULL && tok->lineno < 2 && !tok->read_coding_spec) {
+		if (!check_coding_spec(line, strlen(line), tok, fp_setreadl)) {
+			return error_ret(tok);
+		}
+	}
+#ifndef PGEN
+	/* The default encoding is ASCII, so make sure we don't have any
+           non-ASCII bytes in it. */
+	if (line && !tok->encoding) {
+		unsigned char *c;
+		for (c = (unsigned char *)line; *c; c++)
+			if (*c > 127) {
+				badchar = *c;
+				break;
+			}
+	}
+	if (badchar) {
+		char buf[500];
+		/* Need to add 1 to the line number, since this line
+		   has not been counted, yet.  */
+		sprintf(buf,
+			"Non-ASCII character '\\x%.2x' "
+			"in file %.200s on line %i, "
+			"but no encoding declared; "
+			"see http://www.python.org/peps/pep-0263.html for details",
+			badchar, tok->filename, tok->lineno + 1);
+		PyErr_SetString(PyExc_SyntaxError, buf);
+		return error_ret(tok);
+	}
+#endif
+	return line;
+}
+
+static int
+decoding_feof(struct tok_state *tok)
+{
+	if (tok->decoding_state >= 0) {
+		return feof(tok->fp);
+	} else {
+		PyObject* buf = tok->decoding_buffer;
+		if (buf == NULL) {
+			buf = PyObject_CallObject(tok->decoding_readline, NULL);
+			if (buf == NULL) {
+				error_ret(tok);
+				return 1;
+			} else {
+				tok->decoding_buffer = buf;
+			}
+		}
+		return PyObject_Length(buf) == 0;
+	}
+}
+
+/* Fetch a byte from TOK, using the string buffer. */
+
+static int
+buf_getc(struct tok_state *tok) {
+	return Py_CHARMASK(*tok->str++);
+}
+
+/* Unfetch a byte from TOK, using the string buffer. */
+
+static void
+buf_ungetc(int c, struct tok_state *tok) {
+	tok->str--;
+	assert(Py_CHARMASK(*tok->str) == c);	/* tok->cur may point to read-only segment */
+}
+
+/* Set the readline function for TOK to ENC. For the string-based
+   tokenizer, this means to just record the encoding. */
+
+static int
+buf_setreadl(struct tok_state *tok, const char* enc) {
+	tok->enc = enc;
+	return 1;
+}
+
+/* Return a UTF-8 encoding Python string object from the
+   C byte string STR, which is encoded with ENC. */
+
+#ifdef Py_USING_UNICODE
+static PyObject *
+translate_into_utf8(const char* str, const char* enc) {
+	PyObject *utf8;
+	PyObject* buf = PyUnicode_Decode(str, strlen(str), enc, NULL);
+	if (buf == NULL)
+		return NULL;
+	utf8 = PyUnicode_AsUTF8String(buf);
+	Py_DECREF(buf);
+	return utf8;
+}
+#endif
+
+/* Decode a byte string STR for use as the buffer of TOK.
+   Look for encoding declarations inside STR, and record them
+   inside TOK.  */
+
+static const char *
+decode_str(const char *str, struct tok_state *tok)
+{
+	PyObject* utf8 = NULL;
+	const char *s;
+	int lineno = 0;
+	tok->enc = NULL;
+	tok->str = str;
+	if (!check_bom(buf_getc, buf_ungetc, buf_setreadl, tok))
+		return error_ret(tok);
+	str = tok->str;		/* string after BOM if any */
+	assert(str);
+#ifdef Py_USING_UNICODE
+	if (tok->enc != NULL) {
+		utf8 = translate_into_utf8(str, tok->enc);
+		if (utf8 == NULL)
+			return error_ret(tok);
+		str = PyString_AsString(utf8);
+	}
+#endif
+	for (s = str;; s++) {
+		if (*s == '\0') break;
+		else if (*s == '\n') {
+			lineno++;
+			if (lineno == 2) break;
+		}
+	}
+	tok->enc = NULL;
+	if (!check_coding_spec(str, s - str, tok, buf_setreadl))
+		return error_ret(tok);
+#ifdef Py_USING_UNICODE
+	if (tok->enc != NULL) {
+		assert(utf8 == NULL);
+		utf8 = translate_into_utf8(str, tok->enc);
+		if (utf8 == NULL) {
+			PyErr_Format(PyExc_SyntaxError,
+				"unknown encoding: %s", tok->enc);
+			return error_ret(tok);
+		}
+		str = PyString_AsString(utf8);
+	}
+#endif
+	assert(tok->decoding_buffer == NULL);
+	tok->decoding_buffer = utf8; /* CAUTION */
+	return str;
+}
+
+#endif /* PGEN */
+
+/* Set up tokenizer for string */
+
+struct tok_state *
+PyTokenizer_FromString(const char *str)
+{
+	struct tok_state *tok = tok_new();
+	if (tok == NULL)
+		return NULL;
+	str = (char *)decode_str(str, tok);
+	if (str == NULL) {
+		PyTokenizer_Free(tok);
+		return NULL;
+	}
+
+	/* XXX: constify members. */
+	tok->buf = tok->cur = tok->end = tok->inp = (char*)str;
+	return tok;
+}
+
+
+/* Set up tokenizer for file */
+
+struct tok_state *
+PyTokenizer_FromFile(FILE *fp, char *ps1, char *ps2)
+{
+	struct tok_state *tok = tok_new();
+	if (tok == NULL)
+		return NULL;
+	if ((tok->buf = (char *)PyMem_MALLOC(BUFSIZ)) == NULL) {
+		PyTokenizer_Free(tok);
+		return NULL;
+	}
+	tok->cur = tok->inp = tok->buf;
+	tok->end = tok->buf + BUFSIZ;
+	tok->fp = fp;
+	tok->prompt = ps1;
+	tok->nextprompt = ps2;
+	return tok;
+}
+
+
+/* Free a tok_state structure */
+
+void
+PyTokenizer_Free(struct tok_state *tok)
+{
+	if (tok->encoding != NULL)
+		PyMem_FREE(tok->encoding);
+#ifndef PGEN
+	Py_XDECREF(tok->decoding_readline);
+	Py_XDECREF(tok->decoding_buffer);
+#endif
+	if (tok->fp != NULL && tok->buf != NULL)
+		PyMem_FREE(tok->buf);
+	PyMem_FREE(tok);
+}
+
+#if !defined(PGEN) && defined(Py_USING_UNICODE)
+static int
+tok_stdin_decode(struct tok_state *tok, char **inp)
+{
+	PyObject *enc, *sysstdin, *decoded, *utf8;
+	const char *encoding;
+	char *converted;
+
+	if (PySys_GetFile((char *)"stdin", NULL) != stdin)
+		return 0;
+	sysstdin = PySys_GetObject("stdin");
+	if (sysstdin == NULL || !PyFile_Check(sysstdin))
+		return 0;
+
+	enc = ((PyFileObject *)sysstdin)->f_encoding;
+	if (enc == NULL || !PyString_Check(enc))
+		return 0;
+	Py_INCREF(enc);
+
+	encoding = PyString_AsString(enc);
+	decoded = PyUnicode_Decode(*inp, strlen(*inp), encoding, NULL);
+	if (decoded == NULL)
+		goto error_clear;
+
+	utf8 = PyUnicode_AsEncodedString(decoded, "utf-8", NULL);
+	Py_DECREF(decoded);
+	if (utf8 == NULL)
+		goto error_clear;
+
+	assert(PyString_Check(utf8));
+	converted = new_string(PyString_AS_STRING(utf8),
+			       PyString_GET_SIZE(utf8));
+	Py_DECREF(utf8);
+	if (converted == NULL)
+		goto error_nomem;
+
+	PyMem_FREE(*inp);
+	*inp = converted;
+	if (tok->encoding != NULL)
+		PyMem_FREE(tok->encoding);
+	tok->encoding = new_string(encoding, strlen(encoding));
+	if (tok->encoding == NULL)
+		goto error_nomem;
+
+	Py_DECREF(enc);
+	return 0;
+
+error_nomem:
+	Py_DECREF(enc);
+	tok->done = E_NOMEM;
+	return -1;
+
+error_clear:
+	/* Fallback to iso-8859-1: for backward compatibility */
+	Py_DECREF(enc);
+	PyErr_Clear();
+	return 0;
+}
+#endif
+
+/* Get next char, updating state; error code goes into tok->done */
+
+static int
+tok_nextc(register struct tok_state *tok)
+{
+	for (;;) {
+		if (tok->cur != tok->inp) {
+			return Py_CHARMASK(*tok->cur++); /* Fast path */
+		}
+		if (tok->done != E_OK)
+			return EOF;
+		if (tok->fp == NULL) {
+			char *end = strchr(tok->inp, '\n');
+			if (end != NULL)
+				end++;
+			else {
+				end = strchr(tok->inp, '\0');
+				if (end == tok->inp) {
+					tok->done = E_EOF;
+					return EOF;
+				}
+			}
+			if (tok->start == NULL)
+				tok->buf = tok->cur;
+			tok->line_start = tok->cur;
+			tok->lineno++;
+			tok->inp = end;
+			return Py_CHARMASK(*tok->cur++);
+		}
+		if (tok->prompt != NULL) {
+			char *newtok = PyOS_Readline(stdin, stdout, tok->prompt);
+			if (tok->nextprompt != NULL)
+				tok->prompt = tok->nextprompt;
+			if (newtok == NULL)
+				tok->done = E_INTR;
+			else if (*newtok == '\0') {
+				PyMem_FREE(newtok);
+				tok->done = E_EOF;
+			}
+#if !defined(PGEN) && defined(Py_USING_UNICODE)
+			else if (tok_stdin_decode(tok, &newtok) != 0)
+				PyMem_FREE(newtok);
+#endif
+			else if (tok->start != NULL) {
+				size_t start = tok->start - tok->buf;
+				size_t oldlen = tok->cur - tok->buf;
+				size_t newlen = oldlen + strlen(newtok);
+				char *buf = tok->buf;
+				buf = (char *)PyMem_REALLOC(buf, newlen+1);
+				tok->lineno++;
+				if (buf == NULL) {
+					PyMem_FREE(tok->buf);
+					tok->buf = NULL;
+					PyMem_FREE(newtok);
+					tok->done = E_NOMEM;
+					return EOF;
+				}
+				tok->buf = buf;
+				tok->cur = tok->buf + oldlen;
+				tok->line_start = tok->cur;
+				strcpy(tok->buf + oldlen, newtok);
+				PyMem_FREE(newtok);
+				tok->inp = tok->buf + newlen;
+				tok->end = tok->inp + 1;
+				tok->start = tok->buf + start;
+			}
+			else {
+				tok->lineno++;
+				if (tok->buf != NULL)
+					PyMem_FREE(tok->buf);
+				tok->buf = newtok;
+				tok->line_start = tok->buf;
+				tok->cur = tok->buf;
+				tok->line_start = tok->buf;
+				tok->inp = strchr(tok->buf, '\0');
+				tok->end = tok->inp + 1;
+			}
+		}
+		else {
+			int done = 0;
+			Py_ssize_t cur = 0;
+			char *pt;
+			if (tok->start == NULL) {
+				if (tok->buf == NULL) {
+					tok->buf = (char *)
+						PyMem_MALLOC(BUFSIZ);
+					if (tok->buf == NULL) {
+						tok->done = E_NOMEM;
+						return EOF;
+					}
+					tok->end = tok->buf + BUFSIZ;
+				}
+				if (decoding_fgets(tok->buf, (int)(tok->end - tok->buf),
+					  tok) == NULL) {
+					tok->done = E_EOF;
+					done = 1;
+				}
+				else {
+					tok->done = E_OK;
+					tok->inp = strchr(tok->buf, '\0');
+					done = tok->inp[-1] == '\n';
+				}
+			}
+			else {
+				cur = tok->cur - tok->buf;
+				if (decoding_feof(tok)) {
+					tok->done = E_EOF;
+					done = 1;
+				}
+				else
+					tok->done = E_OK;
+			}
+			tok->lineno++;
+			/* Read until '\n' or EOF */
+			while (!done) {
+				Py_ssize_t curstart = tok->start == NULL ? -1 :
+					          tok->start - tok->buf;
+				Py_ssize_t curvalid = tok->inp - tok->buf;
+				Py_ssize_t newsize = curvalid + BUFSIZ;
+				char *newbuf = tok->buf;
+				newbuf = (char *)PyMem_REALLOC(newbuf,
+							       newsize);
+				if (newbuf == NULL) {
+					tok->done = E_NOMEM;
+					tok->cur = tok->inp;
+					return EOF;
+				}
+				tok->buf = newbuf;
+				tok->inp = tok->buf + curvalid;
+				tok->end = tok->buf + newsize;
+				tok->start = curstart < 0 ? NULL :
+					     tok->buf + curstart;
+				if (decoding_fgets(tok->inp,
+					       (int)(tok->end - tok->inp),
+					       tok) == NULL) {
+					/* Break out early on decoding
+					   errors, as tok->buf will be NULL
+					 */
+					if (tok->decoding_erred)
+						return EOF;
+					/* Last line does not end in \n,
+					   fake one */
+					strcpy(tok->inp, "\n");
+				}
+				tok->inp = strchr(tok->inp, '\0');
+				done = tok->inp[-1] == '\n';
+			}
+			if (tok->buf != NULL) {
+				tok->cur = tok->buf + cur;
+				tok->line_start = tok->cur;
+				/* replace "\r\n" with "\n" */
+				/* For Mac leave the \r, giving syntax error */
+				pt = tok->inp - 2;
+				if (pt >= tok->buf && *pt == '\r') {
+					*pt++ = '\n';
+					*pt = '\0';
+					tok->inp = pt;
+				}
+			}
+		}
+		if (tok->done != E_OK) {
+			if (tok->prompt != NULL)
+				PySys_WriteStderr("\n");
+			tok->cur = tok->inp;
+			return EOF;
+		}
+	}
+	/*NOTREACHED*/
+}
+
+
+/* Back-up one character */
+
+static void
+tok_backup(register struct tok_state *tok, register int c)
+{
+	if (c != EOF) {
+		if (--tok->cur < tok->buf)
+			Py_FatalError("tok_backup: begin of buffer");
+		if (*tok->cur != c)
+			*tok->cur = c;
+	}
+}
+
+
+/* Return the token corresponding to a single character */
+
+int
+PyToken_OneChar(int c)
+{
+	switch (c) {
+	case '(':	return LPAR;
+	case ')':	return RPAR;
+	case '[':	return LSQB;
+	case ']':	return RSQB;
+	case ':':	return COLON;
+	case ',':	return COMMA;
+	case ';':	return SEMI;
+	case '+':	return PLUS;
+	case '-':	return MINUS;
+	case '*':	return STAR;
+	case '/':	return SLASH;
+	case '|':	return VBAR;
+	case '&':	return AMPER;
+	case '<':	return LESS;
+	case '>':	return GREATER;
+	case '=':	return EQUAL;
+	case '.':	return DOT;
+	case '%':	return PERCENT;
+	case '`':	return BACKQUOTE;
+	case '{':	return LBRACE;
+	case '}':	return RBRACE;
+	case '^':	return CIRCUMFLEX;
+	case '~':	return TILDE;
+	case '@':       return AT;
+	default:	return OP;
+	}
+}
+
+
+int
+PyToken_TwoChars(int c1, int c2)
+{
+	switch (c1) {
+	case '=':
+		switch (c2) {
+		case '=':	return EQEQUAL;
+		}
+		break;
+	case '!':
+		switch (c2) {
+		case '=':	return NOTEQUAL;
+		}
+		break;
+	case '<':
+		switch (c2) {
+		case '>':	return NOTEQUAL;
+		case '=':	return LESSEQUAL;
+		case '<':	return LEFTSHIFT;
+		}
+		break;
+	case '>':
+		switch (c2) {
+		case '=':	return GREATEREQUAL;
+		case '>':	return RIGHTSHIFT;
+		}
+		break;
+	case '+':
+		switch (c2) {
+		case '=':	return PLUSEQUAL;
+		}
+		break;
+	case '-':
+		switch (c2) {
+		case '=':	return MINEQUAL;
+		}
+		break;
+	case '*':
+		switch (c2) {
+		case '*':	return DOUBLESTAR;
+		case '=':	return STAREQUAL;
+		}
+		break;
+	case '/':
+		switch (c2) {
+		case '/':	return DOUBLESLASH;
+		case '=':	return SLASHEQUAL;
+		}
+		break;
+	case '|':
+		switch (c2) {
+		case '=':	return VBAREQUAL;
+		}
+		break;
+	case '%':
+		switch (c2) {
+		case '=':	return PERCENTEQUAL;
+		}
+		break;
+	case '&':
+		switch (c2) {
+		case '=':	return AMPEREQUAL;
+		}
+		break;
+	case '^':
+		switch (c2) {
+		case '=':	return CIRCUMFLEXEQUAL;
+		}
+		break;
+	}
+	return OP;
+}
+
+int
+PyToken_ThreeChars(int c1, int c2, int c3)
+{
+	switch (c1) {
+	case '<':
+		switch (c2) {
+		case '<':
+			switch (c3) {
+			case '=':
+				return LEFTSHIFTEQUAL;
+			}
+			break;
+		}
+		break;
+	case '>':
+		switch (c2) {
+		case '>':
+			switch (c3) {
+			case '=':
+				return RIGHTSHIFTEQUAL;
+			}
+			break;
+		}
+		break;
+	case '*':
+		switch (c2) {
+		case '*':
+			switch (c3) {
+			case '=':
+				return DOUBLESTAREQUAL;
+			}
+			break;
+		}
+		break;
+	case '/':
+		switch (c2) {
+		case '/':
+			switch (c3) {
+			case '=':
+				return DOUBLESLASHEQUAL;
+			}
+			break;
+		}
+		break;
+	}
+	return OP;
+}
+
+static int
+indenterror(struct tok_state *tok)
+{
+	if (tok->alterror) {
+		tok->done = E_TABSPACE;
+		tok->cur = tok->inp;
+		return 1;
+	}
+	if (tok->altwarning) {
+		PySys_WriteStderr("%s: inconsistent use of tabs and spaces "
+                                  "in indentation\n", tok->filename);
+		tok->altwarning = 0;
+	}
+	return 0;
+}
+
+
+/* Get next token, after space stripping etc. */
+
+static int
+tok_get(register struct tok_state *tok, char **p_start, char **p_end)
+{
+	register int c;
+	int blankline;
+
+	*p_start = *p_end = NULL;
+  nextline:
+	tok->start = NULL;
+	blankline = 0;
+
+	/* Get indentation level */
+	if (tok->atbol) {
+		register int col = 0;
+		register int altcol = 0;
+		tok->atbol = 0;
+		for (;;) {
+			c = tok_nextc(tok);
+			if (c == ' ')
+				col++, altcol++;
+			else if (c == '\t') {
+				col = (col/tok->tabsize + 1) * tok->tabsize;
+				altcol = (altcol/tok->alttabsize + 1)
+					* tok->alttabsize;
+			}
+			else if (c == '\014') /* Control-L (formfeed) */
+				col = altcol = 0; /* For Emacs users */
+			else
+				break;
+		}
+		tok_backup(tok, c);
+		if (c == '#' || c == '\n') {
+			/* Lines with only whitespace and/or comments
+			   shouldn't affect the indentation and are
+			   not passed to the parser as NEWLINE tokens,
+			   except *totally* empty lines in interactive
+			   mode, which signal the end of a command group. */
+			if (col == 0 && c == '\n' && tok->prompt != NULL)
+				blankline = 0; /* Let it through */
+			else
+				blankline = 1; /* Ignore completely */
+			/* We can't jump back right here since we still
+			   may need to skip to the end of a comment */
+		}
+		if (!blankline && tok->level == 0) {
+			if (col == tok->indstack[tok->indent]) {
+				/* No change */
+				if (altcol != tok->altindstack[tok->indent]) {
+					if (indenterror(tok))
+						return ERRORTOKEN;
+				}
+			}
+			else if (col > tok->indstack[tok->indent]) {
+				/* Indent -- always one */
+				if (tok->indent+1 >= MAXINDENT) {
+					tok->done = E_TOODEEP;
+					tok->cur = tok->inp;
+					return ERRORTOKEN;
+				}
+				if (altcol <= tok->altindstack[tok->indent]) {
+					if (indenterror(tok))
+						return ERRORTOKEN;
+				}
+				tok->pendin++;
+				tok->indstack[++tok->indent] = col;
+				tok->altindstack[tok->indent] = altcol;
+			}
+			else /* col < tok->indstack[tok->indent] */ {
+				/* Dedent -- any number, must be consistent */
+				while (tok->indent > 0 &&
+					col < tok->indstack[tok->indent]) {
+					tok->pendin--;
+					tok->indent--;
+				}
+				if (col != tok->indstack[tok->indent]) {
+					tok->done = E_DEDENT;
+					tok->cur = tok->inp;
+					return ERRORTOKEN;
+				}
+				if (altcol != tok->altindstack[tok->indent]) {
+					if (indenterror(tok))
+						return ERRORTOKEN;
+				}
+			}
+		}
+	}
+
+	tok->start = tok->cur;
+
+	/* Return pending indents/dedents */
+	if (tok->pendin != 0) {
+		if (tok->pendin < 0) {
+			tok->pendin++;
+			return DEDENT;
+		}
+		else {
+			tok->pendin--;
+			return INDENT;
+		}
+	}
+
+ again:
+	tok->start = NULL;
+	/* Skip spaces */
+	do {
+		c = tok_nextc(tok);
+	} while (c == ' ' || c == '\t' || c == '\014');
+
+	/* Set start of current token */
+	tok->start = tok->cur - 1;
+
+	/* Skip comment, while looking for tab-setting magic */
+	if (c == '#') {
+		static char *tabforms[] = {
+			"tab-width:",		/* Emacs */
+			":tabstop=",		/* vim, full form */
+			":ts=",			/* vim, abbreviated form */
+			"set tabsize=",		/* will vi never die? */
+		/* more templates can be added here to support other editors */
+		};
+		char cbuf[80];
+		char *tp, **cp;
+		tp = cbuf;
+		do {
+			*tp++ = c = tok_nextc(tok);
+		} while (c != EOF && c != '\n' &&
+			 (size_t)(tp - cbuf + 1) < sizeof(cbuf));
+		*tp = '\0';
+		for (cp = tabforms;
+		     cp < tabforms + sizeof(tabforms)/sizeof(tabforms[0]);
+		     cp++) {
+			if ((tp = strstr(cbuf, *cp))) {
+				int newsize = atoi(tp + strlen(*cp));
+
+				if (newsize >= 1 && newsize <= 40) {
+					tok->tabsize = newsize;
+					if (Py_VerboseFlag)
+					    PySys_WriteStderr(
+						"Tab size set to %d\n",
+						newsize);
+				}
+			}
+		}
+		while (c != EOF && c != '\n')
+			c = tok_nextc(tok);
+	}
+
+	/* Check for EOF and errors now */
+	if (c == EOF) {
+		return tok->done == E_EOF ? ENDMARKER : ERRORTOKEN;
+	}
+
+	/* Identifier (most frequent token!) */
+	if (isalpha(c) || c == '_') {
+		/* Process r"", u"" and ur"" */
+		switch (c) {
+		case 'r':
+		case 'R':
+			c = tok_nextc(tok);
+			if (c == '"' || c == '\'')
+				goto letter_quote;
+			break;
+		case 'u':
+		case 'U':
+			c = tok_nextc(tok);
+			if (c == 'r' || c == 'R')
+				c = tok_nextc(tok);
+			if (c == '"' || c == '\'')
+				goto letter_quote;
+			break;
+		}
+		while (isalnum(c) || c == '_') {
+			c = tok_nextc(tok);
+		}
+		tok_backup(tok, c);
+		*p_start = tok->start;
+		*p_end = tok->cur;
+		return NAME;
+	}
+
+	/* Newline */
+	if (c == '\n') {
+		tok->atbol = 1;
+		if (blankline || tok->level > 0)
+			goto nextline;
+		*p_start = tok->start;
+		*p_end = tok->cur - 1; /* Leave '\n' out of the string */
+                tok->cont_line = 0;
+		return NEWLINE;
+	}
+
+	/* Period or number starting with period? */
+	if (c == '.') {
+		c = tok_nextc(tok);
+		if (isdigit(c)) {
+			goto fraction;
+		}
+		else {
+			tok_backup(tok, c);
+			*p_start = tok->start;
+			*p_end = tok->cur;
+			return DOT;
+		}
+	}
+
+	/* Number */
+	if (isdigit(c)) {
+		if (c == '0') {
+			/* Hex or octal -- maybe. */
+			c = tok_nextc(tok);
+			if (c == '.')
+				goto fraction;
+#ifndef WITHOUT_COMPLEX
+			if (c == 'j' || c == 'J')
+				goto imaginary;
+#endif
+			if (c == 'x' || c == 'X') {
+				/* Hex */
+				do {
+					c = tok_nextc(tok);
+				} while (isxdigit(c));
+			}
+			else {
+				int found_decimal = 0;
+				/* Octal; c is first char of it */
+				/* There's no 'isoctdigit' macro, sigh */
+				while ('0' <= c && c < '8') {
+					c = tok_nextc(tok);
+				}
+				if (isdigit(c)) {
+					found_decimal = 1;
+					do {
+						c = tok_nextc(tok);
+					} while (isdigit(c));
+				}
+				if (c == '.')
+					goto fraction;
+				else if (c == 'e' || c == 'E')
+					goto exponent;
+#ifndef WITHOUT_COMPLEX
+				else if (c == 'j' || c == 'J')
+					goto imaginary;
+#endif
+				else if (found_decimal) {
+					tok->done = E_TOKEN;
+					tok_backup(tok, c);
+					return ERRORTOKEN;
+				}
+			}
+			if (c == 'l' || c == 'L')
+				c = tok_nextc(tok);
+		}
+		else {
+			/* Decimal */
+			do {
+				c = tok_nextc(tok);
+			} while (isdigit(c));
+			if (c == 'l' || c == 'L')
+				c = tok_nextc(tok);
+			else {
+				/* Accept floating point numbers. */
+				if (c == '.') {
+		fraction:
+					/* Fraction */
+					do {
+						c = tok_nextc(tok);
+					} while (isdigit(c));
+				}
+				if (c == 'e' || c == 'E') {
+		exponent:
+					/* Exponent part */
+					c = tok_nextc(tok);
+					if (c == '+' || c == '-')
+						c = tok_nextc(tok);
+					if (!isdigit(c)) {
+						tok->done = E_TOKEN;
+						tok_backup(tok, c);
+						return ERRORTOKEN;
+					}
+					do {
+						c = tok_nextc(tok);
+					} while (isdigit(c));
+				}
+#ifndef WITHOUT_COMPLEX
+				if (c == 'j' || c == 'J')
+					/* Imaginary part */
+		imaginary:
+					c = tok_nextc(tok);
+#endif
+			}
+		}
+		tok_backup(tok, c);
+		*p_start = tok->start;
+		*p_end = tok->cur;
+		return NUMBER;
+	}
+
+  letter_quote:
+	/* String */
+	if (c == '\'' || c == '"') {
+		Py_ssize_t quote2 = tok->cur - tok->start + 1;
+		int quote = c;
+		int triple = 0;
+		int tripcount = 0;
+		for (;;) {
+			c = tok_nextc(tok);
+			if (c == '\n') {
+				if (!triple) {
+					tok->done = E_EOLS;
+					tok_backup(tok, c);
+					return ERRORTOKEN;
+				}
+				tripcount = 0;
+                                tok->cont_line = 1; /* multiline string. */
+			}
+			else if (c == EOF) {
+				if (triple)
+					tok->done = E_EOFS;
+				else
+					tok->done = E_EOLS;
+				tok->cur = tok->inp;
+				return ERRORTOKEN;
+			}
+			else if (c == quote) {
+				tripcount++;
+				if (tok->cur - tok->start == quote2) {
+					c = tok_nextc(tok);
+					if (c == quote) {
+						triple = 1;
+						tripcount = 0;
+						continue;
+					}
+					tok_backup(tok, c);
+				}
+				if (!triple || tripcount == 3)
+					break;
+			}
+			else if (c == '\\') {
+				tripcount = 0;
+				c = tok_nextc(tok);
+				if (c == EOF) {
+					tok->done = E_EOLS;
+					tok->cur = tok->inp;
+					return ERRORTOKEN;
+				}
+			}
+			else
+				tripcount = 0;
+		}
+		*p_start = tok->start;
+		*p_end = tok->cur;
+		return STRING;
+	}
+
+	/* Line continuation */
+	if (c == '\\') {
+		c = tok_nextc(tok);
+		if (c != '\n') {
+			tok->done = E_LINECONT;
+			tok->cur = tok->inp;
+			return ERRORTOKEN;
+		}
+                tok->cont_line = 1;
+		goto again; /* Read next line */
+	}
+
+	/* Check for two-character token */
+	{
+		int c2 = tok_nextc(tok);
+		int token = PyToken_TwoChars(c, c2);
+		if (token != OP) {
+			int c3 = tok_nextc(tok);
+			int token3 = PyToken_ThreeChars(c, c2, c3);
+			if (token3 != OP) {
+				token = token3;
+			} else {
+				tok_backup(tok, c3);
+			}
+			*p_start = tok->start;
+			*p_end = tok->cur;
+			return token;
+		}
+		tok_backup(tok, c2);
+	}
+
+	/* Keep track of parentheses nesting level */
+	switch (c) {
+	case '(':
+	case '[':
+	case '{':
+		tok->level++;
+		break;
+	case ')':
+	case ']':
+	case '}':
+		tok->level--;
+		break;
+	}
+
+	/* Punctuation character */
+	*p_start = tok->start;
+	*p_end = tok->cur;
+	return PyToken_OneChar(c);
+}
+
+int
+PyTokenizer_Get(struct tok_state *tok, char **p_start, char **p_end)
+{
+	int result = tok_get(tok, p_start, p_end);
+	if (tok->decoding_erred) {
+		result = ERRORTOKEN;
+		tok->done = E_DECODE;
+	}
+	return result;
+}
+
+#ifdef Py_DEBUG
+
+void
+tok_dump(int type, char *start, char *end)
+{
+	printf("%s", _PyParser_TokenNames[type]);
+	if (type == NAME || type == NUMBER || type == STRING || type == OP)
+		printf("(%.*s)", (int)(end - start), start);
+}
+
+#endif

Added: vendor/Python/current/Parser/tokenizer.h
===================================================================
--- vendor/Python/current/Parser/tokenizer.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Parser/tokenizer.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,65 @@
+#ifndef Py_TOKENIZER_H
+#define Py_TOKENIZER_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "object.h"
+
+/* Tokenizer interface */
+
+#include "token.h"	/* For token types */
+
+#define MAXINDENT 100	/* Max indentation level */
+
+/* Tokenizer state */
+struct tok_state {
+	/* Input state; buf <= cur <= inp <= end */
+	/* NB an entire line is held in the buffer */
+	char *buf;	/* Input buffer, or NULL; malloc'ed if fp != NULL */
+	char *cur;	/* Next character in buffer */
+	char *inp;	/* End of data in buffer */
+	char *end;	/* End of input buffer if buf != NULL */
+	char *start;	/* Start of current token if not NULL */
+	int done;	/* E_OK normally, E_EOF at EOF, otherwise error code */
+	/* NB If done != E_OK, cur must be == inp!!! */
+	FILE *fp;	/* Rest of input; NULL if tokenizing a string */
+	int tabsize;	/* Tab spacing */
+	int indent;	/* Current indentation index */
+	int indstack[MAXINDENT];	/* Stack of indents */
+	int atbol;	/* Nonzero if at begin of new line */
+	int pendin;	/* Pending indents (if > 0) or dedents (if < 0) */
+	char *prompt, *nextprompt;	/* For interactive prompting */
+	int lineno;	/* Current line number */
+	int level;	/* () [] {} Parentheses nesting level */
+			/* Used to allow free continuations inside them */
+	/* Stuff for checking on different tab sizes */
+	const char *filename;	/* For error messages */
+	int altwarning;	/* Issue warning if alternate tabs don't match */
+	int alterror;	/* Issue error if alternate tabs don't match */
+	int alttabsize;	/* Alternate tab spacing */
+	int altindstack[MAXINDENT];	/* Stack of alternate indents */
+	/* Stuff for PEP 0263 */
+	int decoding_state;	/* -1:decoding, 0:init, 1:raw */
+	int decoding_erred;	/* whether erred in decoding  */
+	int read_coding_spec;	/* whether 'coding:...' has been read  */
+	char *encoding;
+	int cont_line;          /* whether we are in a continuation line. */
+	const char* line_start;	/* pointer to start of current line */
+#ifndef PGEN
+	PyObject *decoding_readline; /* codecs.open(...).readline */
+	PyObject *decoding_buffer;
+#endif
+	const char* enc;
+	const char* str;
+};
+
+extern struct tok_state *PyTokenizer_FromString(const char *);
+extern struct tok_state *PyTokenizer_FromFile(FILE *, char *, char *);
+extern void PyTokenizer_Free(struct tok_state *);
+extern int PyTokenizer_Get(struct tok_state *, char **, char **);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_TOKENIZER_H */

Added: vendor/Python/current/Parser/tokenizer_pgen.c
===================================================================
--- vendor/Python/current/Parser/tokenizer_pgen.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Parser/tokenizer_pgen.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2 @@
+#define PGEN
+#include "tokenizer.c"

Added: vendor/Python/current/Python/Python-ast.c
===================================================================
--- vendor/Python/current/Python/Python-ast.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/Python-ast.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,3202 @@
+/* File automatically generated by Parser/asdl_c.py */
+
+#include "Python.h"
+#include "Python-ast.h"
+
+static PyTypeObject* AST_type;
+static PyTypeObject *mod_type;
+static PyObject* ast2obj_mod(void*);
+static PyTypeObject *Module_type;
+static char *Module_fields[]={
+        "body",
+};
+static PyTypeObject *Interactive_type;
+static char *Interactive_fields[]={
+        "body",
+};
+static PyTypeObject *Expression_type;
+static char *Expression_fields[]={
+        "body",
+};
+static PyTypeObject *Suite_type;
+static char *Suite_fields[]={
+        "body",
+};
+static PyTypeObject *stmt_type;
+static char *stmt_attributes[] = {
+        "lineno",
+        "col_offset",
+};
+static PyObject* ast2obj_stmt(void*);
+static PyTypeObject *FunctionDef_type;
+static char *FunctionDef_fields[]={
+        "name",
+        "args",
+        "body",
+        "decorators",
+};
+static PyTypeObject *ClassDef_type;
+static char *ClassDef_fields[]={
+        "name",
+        "bases",
+        "body",
+};
+static PyTypeObject *Return_type;
+static char *Return_fields[]={
+        "value",
+};
+static PyTypeObject *Delete_type;
+static char *Delete_fields[]={
+        "targets",
+};
+static PyTypeObject *Assign_type;
+static char *Assign_fields[]={
+        "targets",
+        "value",
+};
+static PyTypeObject *AugAssign_type;
+static char *AugAssign_fields[]={
+        "target",
+        "op",
+        "value",
+};
+static PyTypeObject *Print_type;
+static char *Print_fields[]={
+        "dest",
+        "values",
+        "nl",
+};
+static PyTypeObject *For_type;
+static char *For_fields[]={
+        "target",
+        "iter",
+        "body",
+        "orelse",
+};
+static PyTypeObject *While_type;
+static char *While_fields[]={
+        "test",
+        "body",
+        "orelse",
+};
+static PyTypeObject *If_type;
+static char *If_fields[]={
+        "test",
+        "body",
+        "orelse",
+};
+static PyTypeObject *With_type;
+static char *With_fields[]={
+        "context_expr",
+        "optional_vars",
+        "body",
+};
+static PyTypeObject *Raise_type;
+static char *Raise_fields[]={
+        "type",
+        "inst",
+        "tback",
+};
+static PyTypeObject *TryExcept_type;
+static char *TryExcept_fields[]={
+        "body",
+        "handlers",
+        "orelse",
+};
+static PyTypeObject *TryFinally_type;
+static char *TryFinally_fields[]={
+        "body",
+        "finalbody",
+};
+static PyTypeObject *Assert_type;
+static char *Assert_fields[]={
+        "test",
+        "msg",
+};
+static PyTypeObject *Import_type;
+static char *Import_fields[]={
+        "names",
+};
+static PyTypeObject *ImportFrom_type;
+static char *ImportFrom_fields[]={
+        "module",
+        "names",
+        "level",
+};
+static PyTypeObject *Exec_type;
+static char *Exec_fields[]={
+        "body",
+        "globals",
+        "locals",
+};
+static PyTypeObject *Global_type;
+static char *Global_fields[]={
+        "names",
+};
+static PyTypeObject *Expr_type;
+static char *Expr_fields[]={
+        "value",
+};
+static PyTypeObject *Pass_type;
+static PyTypeObject *Break_type;
+static PyTypeObject *Continue_type;
+static PyTypeObject *expr_type;
+static char *expr_attributes[] = {
+        "lineno",
+        "col_offset",
+};
+static PyObject* ast2obj_expr(void*);
+static PyTypeObject *BoolOp_type;
+static char *BoolOp_fields[]={
+        "op",
+        "values",
+};
+static PyTypeObject *BinOp_type;
+static char *BinOp_fields[]={
+        "left",
+        "op",
+        "right",
+};
+static PyTypeObject *UnaryOp_type;
+static char *UnaryOp_fields[]={
+        "op",
+        "operand",
+};
+static PyTypeObject *Lambda_type;
+static char *Lambda_fields[]={
+        "args",
+        "body",
+};
+static PyTypeObject *IfExp_type;
+static char *IfExp_fields[]={
+        "test",
+        "body",
+        "orelse",
+};
+static PyTypeObject *Dict_type;
+static char *Dict_fields[]={
+        "keys",
+        "values",
+};
+static PyTypeObject *ListComp_type;
+static char *ListComp_fields[]={
+        "elt",
+        "generators",
+};
+static PyTypeObject *GeneratorExp_type;
+static char *GeneratorExp_fields[]={
+        "elt",
+        "generators",
+};
+static PyTypeObject *Yield_type;
+static char *Yield_fields[]={
+        "value",
+};
+static PyTypeObject *Compare_type;
+static char *Compare_fields[]={
+        "left",
+        "ops",
+        "comparators",
+};
+static PyTypeObject *Call_type;
+static char *Call_fields[]={
+        "func",
+        "args",
+        "keywords",
+        "starargs",
+        "kwargs",
+};
+static PyTypeObject *Repr_type;
+static char *Repr_fields[]={
+        "value",
+};
+static PyTypeObject *Num_type;
+static char *Num_fields[]={
+        "n",
+};
+static PyTypeObject *Str_type;
+static char *Str_fields[]={
+        "s",
+};
+static PyTypeObject *Attribute_type;
+static char *Attribute_fields[]={
+        "value",
+        "attr",
+        "ctx",
+};
+static PyTypeObject *Subscript_type;
+static char *Subscript_fields[]={
+        "value",
+        "slice",
+        "ctx",
+};
+static PyTypeObject *Name_type;
+static char *Name_fields[]={
+        "id",
+        "ctx",
+};
+static PyTypeObject *List_type;
+static char *List_fields[]={
+        "elts",
+        "ctx",
+};
+static PyTypeObject *Tuple_type;
+static char *Tuple_fields[]={
+        "elts",
+        "ctx",
+};
+static PyTypeObject *expr_context_type;
+static PyObject *Load_singleton, *Store_singleton, *Del_singleton,
+*AugLoad_singleton, *AugStore_singleton, *Param_singleton;
+static PyObject* ast2obj_expr_context(expr_context_ty);
+static PyTypeObject *Load_type;
+static PyTypeObject *Store_type;
+static PyTypeObject *Del_type;
+static PyTypeObject *AugLoad_type;
+static PyTypeObject *AugStore_type;
+static PyTypeObject *Param_type;
+static PyTypeObject *slice_type;
+static PyObject* ast2obj_slice(void*);
+static PyTypeObject *Ellipsis_type;
+static PyTypeObject *Slice_type;
+static char *Slice_fields[]={
+        "lower",
+        "upper",
+        "step",
+};
+static PyTypeObject *ExtSlice_type;
+static char *ExtSlice_fields[]={
+        "dims",
+};
+static PyTypeObject *Index_type;
+static char *Index_fields[]={
+        "value",
+};
+static PyTypeObject *boolop_type;
+static PyObject *And_singleton, *Or_singleton;
+static PyObject* ast2obj_boolop(boolop_ty);
+static PyTypeObject *And_type;
+static PyTypeObject *Or_type;
+static PyTypeObject *operator_type;
+static PyObject *Add_singleton, *Sub_singleton, *Mult_singleton,
+*Div_singleton, *Mod_singleton, *Pow_singleton, *LShift_singleton,
+*RShift_singleton, *BitOr_singleton, *BitXor_singleton, *BitAnd_singleton,
+*FloorDiv_singleton;
+static PyObject* ast2obj_operator(operator_ty);
+static PyTypeObject *Add_type;
+static PyTypeObject *Sub_type;
+static PyTypeObject *Mult_type;
+static PyTypeObject *Div_type;
+static PyTypeObject *Mod_type;
+static PyTypeObject *Pow_type;
+static PyTypeObject *LShift_type;
+static PyTypeObject *RShift_type;
+static PyTypeObject *BitOr_type;
+static PyTypeObject *BitXor_type;
+static PyTypeObject *BitAnd_type;
+static PyTypeObject *FloorDiv_type;
+static PyTypeObject *unaryop_type;
+static PyObject *Invert_singleton, *Not_singleton, *UAdd_singleton,
+*USub_singleton;
+static PyObject* ast2obj_unaryop(unaryop_ty);
+static PyTypeObject *Invert_type;
+static PyTypeObject *Not_type;
+static PyTypeObject *UAdd_type;
+static PyTypeObject *USub_type;
+static PyTypeObject *cmpop_type;
+static PyObject *Eq_singleton, *NotEq_singleton, *Lt_singleton, *LtE_singleton,
+*Gt_singleton, *GtE_singleton, *Is_singleton, *IsNot_singleton, *In_singleton,
+*NotIn_singleton;
+static PyObject* ast2obj_cmpop(cmpop_ty);
+static PyTypeObject *Eq_type;
+static PyTypeObject *NotEq_type;
+static PyTypeObject *Lt_type;
+static PyTypeObject *LtE_type;
+static PyTypeObject *Gt_type;
+static PyTypeObject *GtE_type;
+static PyTypeObject *Is_type;
+static PyTypeObject *IsNot_type;
+static PyTypeObject *In_type;
+static PyTypeObject *NotIn_type;
+static PyTypeObject *comprehension_type;
+static PyObject* ast2obj_comprehension(void*);
+static char *comprehension_fields[]={
+        "target",
+        "iter",
+        "ifs",
+};
+static PyTypeObject *excepthandler_type;
+static PyObject* ast2obj_excepthandler(void*);
+static char *excepthandler_fields[]={
+        "type",
+        "name",
+        "body",
+        "lineno",
+        "col_offset",
+};
+static PyTypeObject *arguments_type;
+static PyObject* ast2obj_arguments(void*);
+static char *arguments_fields[]={
+        "args",
+        "vararg",
+        "kwarg",
+        "defaults",
+};
+static PyTypeObject *keyword_type;
+static PyObject* ast2obj_keyword(void*);
+static char *keyword_fields[]={
+        "arg",
+        "value",
+};
+static PyTypeObject *alias_type;
+static PyObject* ast2obj_alias(void*);
+static char *alias_fields[]={
+        "name",
+        "asname",
+};
+
+
+static PyTypeObject* make_type(char *type, PyTypeObject* base, char**fields, int num_fields)
+{
+    PyObject *fnames, *result;
+    int i;
+    if (num_fields) {
+        fnames = PyTuple_New(num_fields);
+        if (!fnames) return NULL;
+    } else {
+        fnames = Py_None;
+        Py_INCREF(Py_None);
+    }
+    for(i=0; i < num_fields; i++) {
+        PyObject *field = PyString_FromString(fields[i]);
+        if (!field) {
+            Py_DECREF(fnames);
+            return NULL;
+        }
+        PyTuple_SET_ITEM(fnames, i, field);
+    }
+    result = PyObject_CallFunction((PyObject*)&PyType_Type, "s(O){sOss}",
+                    type, base, "_fields", fnames, "__module__", "_ast");
+    Py_DECREF(fnames);
+    return (PyTypeObject*)result;
+}
+
+static int add_attributes(PyTypeObject* type, char**attrs, int num_fields)
+{
+    int i, result;
+    PyObject *s, *l = PyList_New(num_fields);
+    if (!l) return 0;
+    for(i = 0; i < num_fields; i++) {
+        s = PyString_FromString(attrs[i]);
+        if (!s) {
+            Py_DECREF(l);
+            return 0;
+        }
+        PyList_SET_ITEM(l, i, s);
+    }
+    result = PyObject_SetAttrString((PyObject*)type, "_attributes", l) >= 0;
+    Py_DECREF(l);
+    return result;
+}
+
+static PyObject* ast2obj_list(asdl_seq *seq, PyObject* (*func)(void*))
+{
+    int i, n = asdl_seq_LEN(seq);
+    PyObject *result = PyList_New(n);
+    PyObject *value;
+    if (!result)
+        return NULL;
+    for (i = 0; i < n; i++) {
+        value = func(asdl_seq_GET(seq, i));
+        if (!value) {
+            Py_DECREF(result);
+            return NULL;
+        }
+        PyList_SET_ITEM(result, i, value);
+    }
+    return result;
+}
+
+static PyObject* ast2obj_object(void *o)
+{
+    if (!o)
+        o = Py_None;
+    Py_INCREF((PyObject*)o);
+    return (PyObject*)o;
+}
+#define ast2obj_identifier ast2obj_object
+#define ast2obj_string ast2obj_object
+static PyObject* ast2obj_bool(bool b)
+{
+    return PyBool_FromLong(b);
+}
+
+static PyObject* ast2obj_int(bool b)
+{
+    return PyInt_FromLong(b);
+}
+
+static int init_types(void)
+{
+        static int initialized;
+        if (initialized) return 1;
+        AST_type = make_type("AST", &PyBaseObject_Type, NULL, 0);
+        mod_type = make_type("mod", AST_type, NULL, 0);
+        if (!mod_type) return 0;
+        if (!add_attributes(mod_type, NULL, 0)) return 0;
+        Module_type = make_type("Module", mod_type, Module_fields, 1);
+        if (!Module_type) return 0;
+        Interactive_type = make_type("Interactive", mod_type,
+                                     Interactive_fields, 1);
+        if (!Interactive_type) return 0;
+        Expression_type = make_type("Expression", mod_type, Expression_fields,
+                                    1);
+        if (!Expression_type) return 0;
+        Suite_type = make_type("Suite", mod_type, Suite_fields, 1);
+        if (!Suite_type) return 0;
+        stmt_type = make_type("stmt", AST_type, NULL, 0);
+        if (!stmt_type) return 0;
+        if (!add_attributes(stmt_type, stmt_attributes, 2)) return 0;
+        FunctionDef_type = make_type("FunctionDef", stmt_type,
+                                     FunctionDef_fields, 4);
+        if (!FunctionDef_type) return 0;
+        ClassDef_type = make_type("ClassDef", stmt_type, ClassDef_fields, 3);
+        if (!ClassDef_type) return 0;
+        Return_type = make_type("Return", stmt_type, Return_fields, 1);
+        if (!Return_type) return 0;
+        Delete_type = make_type("Delete", stmt_type, Delete_fields, 1);
+        if (!Delete_type) return 0;
+        Assign_type = make_type("Assign", stmt_type, Assign_fields, 2);
+        if (!Assign_type) return 0;
+        AugAssign_type = make_type("AugAssign", stmt_type, AugAssign_fields, 3);
+        if (!AugAssign_type) return 0;
+        Print_type = make_type("Print", stmt_type, Print_fields, 3);
+        if (!Print_type) return 0;
+        For_type = make_type("For", stmt_type, For_fields, 4);
+        if (!For_type) return 0;
+        While_type = make_type("While", stmt_type, While_fields, 3);
+        if (!While_type) return 0;
+        If_type = make_type("If", stmt_type, If_fields, 3);
+        if (!If_type) return 0;
+        With_type = make_type("With", stmt_type, With_fields, 3);
+        if (!With_type) return 0;
+        Raise_type = make_type("Raise", stmt_type, Raise_fields, 3);
+        if (!Raise_type) return 0;
+        TryExcept_type = make_type("TryExcept", stmt_type, TryExcept_fields, 3);
+        if (!TryExcept_type) return 0;
+        TryFinally_type = make_type("TryFinally", stmt_type, TryFinally_fields,
+                                    2);
+        if (!TryFinally_type) return 0;
+        Assert_type = make_type("Assert", stmt_type, Assert_fields, 2);
+        if (!Assert_type) return 0;
+        Import_type = make_type("Import", stmt_type, Import_fields, 1);
+        if (!Import_type) return 0;
+        ImportFrom_type = make_type("ImportFrom", stmt_type, ImportFrom_fields,
+                                    3);
+        if (!ImportFrom_type) return 0;
+        Exec_type = make_type("Exec", stmt_type, Exec_fields, 3);
+        if (!Exec_type) return 0;
+        Global_type = make_type("Global", stmt_type, Global_fields, 1);
+        if (!Global_type) return 0;
+        Expr_type = make_type("Expr", stmt_type, Expr_fields, 1);
+        if (!Expr_type) return 0;
+        Pass_type = make_type("Pass", stmt_type, NULL, 0);
+        if (!Pass_type) return 0;
+        Break_type = make_type("Break", stmt_type, NULL, 0);
+        if (!Break_type) return 0;
+        Continue_type = make_type("Continue", stmt_type, NULL, 0);
+        if (!Continue_type) return 0;
+        expr_type = make_type("expr", AST_type, NULL, 0);
+        if (!expr_type) return 0;
+        if (!add_attributes(expr_type, expr_attributes, 2)) return 0;
+        BoolOp_type = make_type("BoolOp", expr_type, BoolOp_fields, 2);
+        if (!BoolOp_type) return 0;
+        BinOp_type = make_type("BinOp", expr_type, BinOp_fields, 3);
+        if (!BinOp_type) return 0;
+        UnaryOp_type = make_type("UnaryOp", expr_type, UnaryOp_fields, 2);
+        if (!UnaryOp_type) return 0;
+        Lambda_type = make_type("Lambda", expr_type, Lambda_fields, 2);
+        if (!Lambda_type) return 0;
+        IfExp_type = make_type("IfExp", expr_type, IfExp_fields, 3);
+        if (!IfExp_type) return 0;
+        Dict_type = make_type("Dict", expr_type, Dict_fields, 2);
+        if (!Dict_type) return 0;
+        ListComp_type = make_type("ListComp", expr_type, ListComp_fields, 2);
+        if (!ListComp_type) return 0;
+        GeneratorExp_type = make_type("GeneratorExp", expr_type,
+                                      GeneratorExp_fields, 2);
+        if (!GeneratorExp_type) return 0;
+        Yield_type = make_type("Yield", expr_type, Yield_fields, 1);
+        if (!Yield_type) return 0;
+        Compare_type = make_type("Compare", expr_type, Compare_fields, 3);
+        if (!Compare_type) return 0;
+        Call_type = make_type("Call", expr_type, Call_fields, 5);
+        if (!Call_type) return 0;
+        Repr_type = make_type("Repr", expr_type, Repr_fields, 1);
+        if (!Repr_type) return 0;
+        Num_type = make_type("Num", expr_type, Num_fields, 1);
+        if (!Num_type) return 0;
+        Str_type = make_type("Str", expr_type, Str_fields, 1);
+        if (!Str_type) return 0;
+        Attribute_type = make_type("Attribute", expr_type, Attribute_fields, 3);
+        if (!Attribute_type) return 0;
+        Subscript_type = make_type("Subscript", expr_type, Subscript_fields, 3);
+        if (!Subscript_type) return 0;
+        Name_type = make_type("Name", expr_type, Name_fields, 2);
+        if (!Name_type) return 0;
+        List_type = make_type("List", expr_type, List_fields, 2);
+        if (!List_type) return 0;
+        Tuple_type = make_type("Tuple", expr_type, Tuple_fields, 2);
+        if (!Tuple_type) return 0;
+        expr_context_type = make_type("expr_context", AST_type, NULL, 0);
+        if (!expr_context_type) return 0;
+        if (!add_attributes(expr_context_type, NULL, 0)) return 0;
+        Load_type = make_type("Load", expr_context_type, NULL, 0);
+        if (!Load_type) return 0;
+        Load_singleton = PyType_GenericNew(Load_type, NULL, NULL);
+        if (!Load_singleton) return 0;
+        Store_type = make_type("Store", expr_context_type, NULL, 0);
+        if (!Store_type) return 0;
+        Store_singleton = PyType_GenericNew(Store_type, NULL, NULL);
+        if (!Store_singleton) return 0;
+        Del_type = make_type("Del", expr_context_type, NULL, 0);
+        if (!Del_type) return 0;
+        Del_singleton = PyType_GenericNew(Del_type, NULL, NULL);
+        if (!Del_singleton) return 0;
+        AugLoad_type = make_type("AugLoad", expr_context_type, NULL, 0);
+        if (!AugLoad_type) return 0;
+        AugLoad_singleton = PyType_GenericNew(AugLoad_type, NULL, NULL);
+        if (!AugLoad_singleton) return 0;
+        AugStore_type = make_type("AugStore", expr_context_type, NULL, 0);
+        if (!AugStore_type) return 0;
+        AugStore_singleton = PyType_GenericNew(AugStore_type, NULL, NULL);
+        if (!AugStore_singleton) return 0;
+        Param_type = make_type("Param", expr_context_type, NULL, 0);
+        if (!Param_type) return 0;
+        Param_singleton = PyType_GenericNew(Param_type, NULL, NULL);
+        if (!Param_singleton) return 0;
+        slice_type = make_type("slice", AST_type, NULL, 0);
+        if (!slice_type) return 0;
+        if (!add_attributes(slice_type, NULL, 0)) return 0;
+        Ellipsis_type = make_type("Ellipsis", slice_type, NULL, 0);
+        if (!Ellipsis_type) return 0;
+        Slice_type = make_type("Slice", slice_type, Slice_fields, 3);
+        if (!Slice_type) return 0;
+        ExtSlice_type = make_type("ExtSlice", slice_type, ExtSlice_fields, 1);
+        if (!ExtSlice_type) return 0;
+        Index_type = make_type("Index", slice_type, Index_fields, 1);
+        if (!Index_type) return 0;
+        boolop_type = make_type("boolop", AST_type, NULL, 0);
+        if (!boolop_type) return 0;
+        if (!add_attributes(boolop_type, NULL, 0)) return 0;
+        And_type = make_type("And", boolop_type, NULL, 0);
+        if (!And_type) return 0;
+        And_singleton = PyType_GenericNew(And_type, NULL, NULL);
+        if (!And_singleton) return 0;
+        Or_type = make_type("Or", boolop_type, NULL, 0);
+        if (!Or_type) return 0;
+        Or_singleton = PyType_GenericNew(Or_type, NULL, NULL);
+        if (!Or_singleton) return 0;
+        operator_type = make_type("operator", AST_type, NULL, 0);
+        if (!operator_type) return 0;
+        if (!add_attributes(operator_type, NULL, 0)) return 0;
+        Add_type = make_type("Add", operator_type, NULL, 0);
+        if (!Add_type) return 0;
+        Add_singleton = PyType_GenericNew(Add_type, NULL, NULL);
+        if (!Add_singleton) return 0;
+        Sub_type = make_type("Sub", operator_type, NULL, 0);
+        if (!Sub_type) return 0;
+        Sub_singleton = PyType_GenericNew(Sub_type, NULL, NULL);
+        if (!Sub_singleton) return 0;
+        Mult_type = make_type("Mult", operator_type, NULL, 0);
+        if (!Mult_type) return 0;
+        Mult_singleton = PyType_GenericNew(Mult_type, NULL, NULL);
+        if (!Mult_singleton) return 0;
+        Div_type = make_type("Div", operator_type, NULL, 0);
+        if (!Div_type) return 0;
+        Div_singleton = PyType_GenericNew(Div_type, NULL, NULL);
+        if (!Div_singleton) return 0;
+        Mod_type = make_type("Mod", operator_type, NULL, 0);
+        if (!Mod_type) return 0;
+        Mod_singleton = PyType_GenericNew(Mod_type, NULL, NULL);
+        if (!Mod_singleton) return 0;
+        Pow_type = make_type("Pow", operator_type, NULL, 0);
+        if (!Pow_type) return 0;
+        Pow_singleton = PyType_GenericNew(Pow_type, NULL, NULL);
+        if (!Pow_singleton) return 0;
+        LShift_type = make_type("LShift", operator_type, NULL, 0);
+        if (!LShift_type) return 0;
+        LShift_singleton = PyType_GenericNew(LShift_type, NULL, NULL);
+        if (!LShift_singleton) return 0;
+        RShift_type = make_type("RShift", operator_type, NULL, 0);
+        if (!RShift_type) return 0;
+        RShift_singleton = PyType_GenericNew(RShift_type, NULL, NULL);
+        if (!RShift_singleton) return 0;
+        BitOr_type = make_type("BitOr", operator_type, NULL, 0);
+        if (!BitOr_type) return 0;
+        BitOr_singleton = PyType_GenericNew(BitOr_type, NULL, NULL);
+        if (!BitOr_singleton) return 0;
+        BitXor_type = make_type("BitXor", operator_type, NULL, 0);
+        if (!BitXor_type) return 0;
+        BitXor_singleton = PyType_GenericNew(BitXor_type, NULL, NULL);
+        if (!BitXor_singleton) return 0;
+        BitAnd_type = make_type("BitAnd", operator_type, NULL, 0);
+        if (!BitAnd_type) return 0;
+        BitAnd_singleton = PyType_GenericNew(BitAnd_type, NULL, NULL);
+        if (!BitAnd_singleton) return 0;
+        FloorDiv_type = make_type("FloorDiv", operator_type, NULL, 0);
+        if (!FloorDiv_type) return 0;
+        FloorDiv_singleton = PyType_GenericNew(FloorDiv_type, NULL, NULL);
+        if (!FloorDiv_singleton) return 0;
+        unaryop_type = make_type("unaryop", AST_type, NULL, 0);
+        if (!unaryop_type) return 0;
+        if (!add_attributes(unaryop_type, NULL, 0)) return 0;
+        Invert_type = make_type("Invert", unaryop_type, NULL, 0);
+        if (!Invert_type) return 0;
+        Invert_singleton = PyType_GenericNew(Invert_type, NULL, NULL);
+        if (!Invert_singleton) return 0;
+        Not_type = make_type("Not", unaryop_type, NULL, 0);
+        if (!Not_type) return 0;
+        Not_singleton = PyType_GenericNew(Not_type, NULL, NULL);
+        if (!Not_singleton) return 0;
+        UAdd_type = make_type("UAdd", unaryop_type, NULL, 0);
+        if (!UAdd_type) return 0;
+        UAdd_singleton = PyType_GenericNew(UAdd_type, NULL, NULL);
+        if (!UAdd_singleton) return 0;
+        USub_type = make_type("USub", unaryop_type, NULL, 0);
+        if (!USub_type) return 0;
+        USub_singleton = PyType_GenericNew(USub_type, NULL, NULL);
+        if (!USub_singleton) return 0;
+        cmpop_type = make_type("cmpop", AST_type, NULL, 0);
+        if (!cmpop_type) return 0;
+        if (!add_attributes(cmpop_type, NULL, 0)) return 0;
+        Eq_type = make_type("Eq", cmpop_type, NULL, 0);
+        if (!Eq_type) return 0;
+        Eq_singleton = PyType_GenericNew(Eq_type, NULL, NULL);
+        if (!Eq_singleton) return 0;
+        NotEq_type = make_type("NotEq", cmpop_type, NULL, 0);
+        if (!NotEq_type) return 0;
+        NotEq_singleton = PyType_GenericNew(NotEq_type, NULL, NULL);
+        if (!NotEq_singleton) return 0;
+        Lt_type = make_type("Lt", cmpop_type, NULL, 0);
+        if (!Lt_type) return 0;
+        Lt_singleton = PyType_GenericNew(Lt_type, NULL, NULL);
+        if (!Lt_singleton) return 0;
+        LtE_type = make_type("LtE", cmpop_type, NULL, 0);
+        if (!LtE_type) return 0;
+        LtE_singleton = PyType_GenericNew(LtE_type, NULL, NULL);
+        if (!LtE_singleton) return 0;
+        Gt_type = make_type("Gt", cmpop_type, NULL, 0);
+        if (!Gt_type) return 0;
+        Gt_singleton = PyType_GenericNew(Gt_type, NULL, NULL);
+        if (!Gt_singleton) return 0;
+        GtE_type = make_type("GtE", cmpop_type, NULL, 0);
+        if (!GtE_type) return 0;
+        GtE_singleton = PyType_GenericNew(GtE_type, NULL, NULL);
+        if (!GtE_singleton) return 0;
+        Is_type = make_type("Is", cmpop_type, NULL, 0);
+        if (!Is_type) return 0;
+        Is_singleton = PyType_GenericNew(Is_type, NULL, NULL);
+        if (!Is_singleton) return 0;
+        IsNot_type = make_type("IsNot", cmpop_type, NULL, 0);
+        if (!IsNot_type) return 0;
+        IsNot_singleton = PyType_GenericNew(IsNot_type, NULL, NULL);
+        if (!IsNot_singleton) return 0;
+        In_type = make_type("In", cmpop_type, NULL, 0);
+        if (!In_type) return 0;
+        In_singleton = PyType_GenericNew(In_type, NULL, NULL);
+        if (!In_singleton) return 0;
+        NotIn_type = make_type("NotIn", cmpop_type, NULL, 0);
+        if (!NotIn_type) return 0;
+        NotIn_singleton = PyType_GenericNew(NotIn_type, NULL, NULL);
+        if (!NotIn_singleton) return 0;
+        comprehension_type = make_type("comprehension", AST_type,
+                                       comprehension_fields, 3);
+        if (!comprehension_type) return 0;
+        excepthandler_type = make_type("excepthandler", AST_type,
+                                       excepthandler_fields, 5);
+        if (!excepthandler_type) return 0;
+        arguments_type = make_type("arguments", AST_type, arguments_fields, 4);
+        if (!arguments_type) return 0;
+        keyword_type = make_type("keyword", AST_type, keyword_fields, 2);
+        if (!keyword_type) return 0;
+        alias_type = make_type("alias", AST_type, alias_fields, 2);
+        if (!alias_type) return 0;
+        initialized = 1;
+        return 1;
+}
+
+mod_ty
+Module(asdl_seq * body, PyArena *arena)
+{
+        mod_ty p;
+        p = (mod_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = Module_kind;
+        p->v.Module.body = body;
+        return p;
+}
+
+mod_ty
+Interactive(asdl_seq * body, PyArena *arena)
+{
+        mod_ty p;
+        p = (mod_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = Interactive_kind;
+        p->v.Interactive.body = body;
+        return p;
+}
+
+mod_ty
+Expression(expr_ty body, PyArena *arena)
+{
+        mod_ty p;
+        if (!body) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field body is required for Expression");
+                return NULL;
+        }
+        p = (mod_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = Expression_kind;
+        p->v.Expression.body = body;
+        return p;
+}
+
+mod_ty
+Suite(asdl_seq * body, PyArena *arena)
+{
+        mod_ty p;
+        p = (mod_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = Suite_kind;
+        p->v.Suite.body = body;
+        return p;
+}
+
+stmt_ty
+FunctionDef(identifier name, arguments_ty args, asdl_seq * body, asdl_seq *
+            decorators, int lineno, int col_offset, PyArena *arena)
+{
+        stmt_ty p;
+        if (!name) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field name is required for FunctionDef");
+                return NULL;
+        }
+        if (!args) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field args is required for FunctionDef");
+                return NULL;
+        }
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = FunctionDef_kind;
+        p->v.FunctionDef.name = name;
+        p->v.FunctionDef.args = args;
+        p->v.FunctionDef.body = body;
+        p->v.FunctionDef.decorators = decorators;
+        p->lineno = lineno;
+        p->col_offset = col_offset;
+        return p;
+}
+
+stmt_ty
+ClassDef(identifier name, asdl_seq * bases, asdl_seq * body, int lineno, int
+         col_offset, PyArena *arena)
+{
+        stmt_ty p;
+        if (!name) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field name is required for ClassDef");
+                return NULL;
+        }
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = ClassDef_kind;
+        p->v.ClassDef.name = name;
+        p->v.ClassDef.bases = bases;
+        p->v.ClassDef.body = body;
+        p->lineno = lineno;
+        p->col_offset = col_offset;
+        return p;
+}
+
+stmt_ty
+Return(expr_ty value, int lineno, int col_offset, PyArena *arena)
+{
+        stmt_ty p;
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = Return_kind;
+        p->v.Return.value = value;
+        p->lineno = lineno;
+        p->col_offset = col_offset;
+        return p;
+}
+
+stmt_ty
+Delete(asdl_seq * targets, int lineno, int col_offset, PyArena *arena)
+{
+        stmt_ty p;
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = Delete_kind;
+        p->v.Delete.targets = targets;
+        p->lineno = lineno;
+        p->col_offset = col_offset;
+        return p;
+}
+
+stmt_ty
+Assign(asdl_seq * targets, expr_ty value, int lineno, int col_offset, PyArena
+       *arena)
+{
+        stmt_ty p;
+        if (!value) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field value is required for Assign");
+                return NULL;
+        }
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = Assign_kind;
+        p->v.Assign.targets = targets;
+        p->v.Assign.value = value;
+        p->lineno = lineno;
+        p->col_offset = col_offset;
+        return p;
+}
+
+stmt_ty
+AugAssign(expr_ty target, operator_ty op, expr_ty value, int lineno, int
+          col_offset, PyArena *arena)
+{
+        stmt_ty p;
+        if (!target) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field target is required for AugAssign");
+                return NULL;
+        }
+        if (!op) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field op is required for AugAssign");
+                return NULL;
+        }
+        if (!value) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field value is required for AugAssign");
+                return NULL;
+        }
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = AugAssign_kind;
+        p->v.AugAssign.target = target;
+        p->v.AugAssign.op = op;
+        p->v.AugAssign.value = value;
+        p->lineno = lineno;
+        p->col_offset = col_offset;
+        return p;
+}
+
+stmt_ty
+Print(expr_ty dest, asdl_seq * values, bool nl, int lineno, int col_offset,
+      PyArena *arena)
+{
+        stmt_ty p;
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = Print_kind;
+        p->v.Print.dest = dest;
+        p->v.Print.values = values;
+        p->v.Print.nl = nl;
+        p->lineno = lineno;
+        p->col_offset = col_offset;
+        return p;
+}
+
+stmt_ty
+For(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq * orelse, int
+    lineno, int col_offset, PyArena *arena)
+{
+        stmt_ty p;
+        if (!target) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field target is required for For");
+                return NULL;
+        }
+        if (!iter) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field iter is required for For");
+                return NULL;
+        }
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = For_kind;
+        p->v.For.target = target;
+        p->v.For.iter = iter;
+        p->v.For.body = body;
+        p->v.For.orelse = orelse;
+        p->lineno = lineno;
+        p->col_offset = col_offset;
+        return p;
+}
+
+stmt_ty
+While(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno, int
+      col_offset, PyArena *arena)
+{
+        stmt_ty p;
+        if (!test) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field test is required for While");
+                return NULL;
+        }
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = While_kind;
+        p->v.While.test = test;
+        p->v.While.body = body;
+        p->v.While.orelse = orelse;
+        p->lineno = lineno;
+        p->col_offset = col_offset;
+        return p;
+}
+
+stmt_ty
+If(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno, int
+   col_offset, PyArena *arena)
+{
+        stmt_ty p;
+        if (!test) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field test is required for If");
+                return NULL;
+        }
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = If_kind;
+        p->v.If.test = test;
+        p->v.If.body = body;
+        p->v.If.orelse = orelse;
+        p->lineno = lineno;
+        p->col_offset = col_offset;
+        return p;
+}
+
+stmt_ty
+With(expr_ty context_expr, expr_ty optional_vars, asdl_seq * body, int lineno,
+     int col_offset, PyArena *arena)
+{
+        stmt_ty p;
+        if (!context_expr) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field context_expr is required for With");
+                return NULL;
+        }
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = With_kind;
+        p->v.With.context_expr = context_expr;
+        p->v.With.optional_vars = optional_vars;
+        p->v.With.body = body;
+        p->lineno = lineno;
+        p->col_offset = col_offset;
+        return p;
+}
+
+stmt_ty
+Raise(expr_ty type, expr_ty inst, expr_ty tback, int lineno, int col_offset,
+      PyArena *arena)
+{
+        stmt_ty p;
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = Raise_kind;
+        p->v.Raise.type = type;
+        p->v.Raise.inst = inst;
+        p->v.Raise.tback = tback;
+        p->lineno = lineno;
+        p->col_offset = col_offset;
+        return p;
+}
+
+stmt_ty
+TryExcept(asdl_seq * body, asdl_seq * handlers, asdl_seq * orelse, int lineno,
+          int col_offset, PyArena *arena)
+{
+        stmt_ty p;
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = TryExcept_kind;
+        p->v.TryExcept.body = body;
+        p->v.TryExcept.handlers = handlers;
+        p->v.TryExcept.orelse = orelse;
+        p->lineno = lineno;
+        p->col_offset = col_offset;
+        return p;
+}
+
+stmt_ty
+TryFinally(asdl_seq * body, asdl_seq * finalbody, int lineno, int col_offset,
+           PyArena *arena)
+{
+        stmt_ty p;
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = TryFinally_kind;
+        p->v.TryFinally.body = body;
+        p->v.TryFinally.finalbody = finalbody;
+        p->lineno = lineno;
+        p->col_offset = col_offset;
+        return p;
+}
+
+stmt_ty
+Assert(expr_ty test, expr_ty msg, int lineno, int col_offset, PyArena *arena)
+{
+        stmt_ty p;
+        if (!test) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field test is required for Assert");
+                return NULL;
+        }
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = Assert_kind;
+        p->v.Assert.test = test;
+        p->v.Assert.msg = msg;
+        p->lineno = lineno;
+        p->col_offset = col_offset;
+        return p;
+}
+
+stmt_ty
+Import(asdl_seq * names, int lineno, int col_offset, PyArena *arena)
+{
+        stmt_ty p;
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = Import_kind;
+        p->v.Import.names = names;
+        p->lineno = lineno;
+        p->col_offset = col_offset;
+        return p;
+}
+
+stmt_ty
+ImportFrom(identifier module, asdl_seq * names, int level, int lineno, int
+           col_offset, PyArena *arena)
+{
+        stmt_ty p;
+        if (!module) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field module is required for ImportFrom");
+                return NULL;
+        }
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = ImportFrom_kind;
+        p->v.ImportFrom.module = module;
+        p->v.ImportFrom.names = names;
+        p->v.ImportFrom.level = level;
+        p->lineno = lineno;
+        p->col_offset = col_offset;
+        return p;
+}
+
+stmt_ty
+Exec(expr_ty body, expr_ty globals, expr_ty locals, int lineno, int col_offset,
+     PyArena *arena)
+{
+        stmt_ty p;
+        if (!body) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field body is required for Exec");
+                return NULL;
+        }
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = Exec_kind;
+        p->v.Exec.body = body;
+        p->v.Exec.globals = globals;
+        p->v.Exec.locals = locals;
+        p->lineno = lineno;
+        p->col_offset = col_offset;
+        return p;
+}
+
+stmt_ty
+Global(asdl_seq * names, int lineno, int col_offset, PyArena *arena)
+{
+        stmt_ty p;
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = Global_kind;
+        p->v.Global.names = names;
+        p->lineno = lineno;
+        p->col_offset = col_offset;
+        return p;
+}
+
+stmt_ty
+Expr(expr_ty value, int lineno, int col_offset, PyArena *arena)
+{
+        stmt_ty p;
+        if (!value) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field value is required for Expr");
+                return NULL;
+        }
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = Expr_kind;
+        p->v.Expr.value = value;
+        p->lineno = lineno;
+        p->col_offset = col_offset;
+        return p;
+}
+
+stmt_ty
+Pass(int lineno, int col_offset, PyArena *arena)
+{
+        stmt_ty p;
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = Pass_kind;
+        p->lineno = lineno;
+        p->col_offset = col_offset;
+        return p;
+}
+
+stmt_ty
+Break(int lineno, int col_offset, PyArena *arena)
+{
+        stmt_ty p;
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = Break_kind;
+        p->lineno = lineno;
+        p->col_offset = col_offset;
+        return p;
+}
+
+stmt_ty
+Continue(int lineno, int col_offset, PyArena *arena)
+{
+        stmt_ty p;
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = Continue_kind;
+        p->lineno = lineno;
+        p->col_offset = col_offset;
+        return p;
+}
+
+expr_ty
+BoolOp(boolop_ty op, asdl_seq * values, int lineno, int col_offset, PyArena
+       *arena)
+{
+        expr_ty p;
+        if (!op) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field op is required for BoolOp");
+                return NULL;
+        }
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = BoolOp_kind;
+        p->v.BoolOp.op = op;
+        p->v.BoolOp.values = values;
+        p->lineno = lineno;
+        p->col_offset = col_offset;
+        return p;
+}
+
+expr_ty
+BinOp(expr_ty left, operator_ty op, expr_ty right, int lineno, int col_offset,
+      PyArena *arena)
+{
+        expr_ty p;
+        if (!left) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field left is required for BinOp");
+                return NULL;
+        }
+        if (!op) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field op is required for BinOp");
+                return NULL;
+        }
+        if (!right) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field right is required for BinOp");
+                return NULL;
+        }
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = BinOp_kind;
+        p->v.BinOp.left = left;
+        p->v.BinOp.op = op;
+        p->v.BinOp.right = right;
+        p->lineno = lineno;
+        p->col_offset = col_offset;
+        return p;
+}
+
+expr_ty
+UnaryOp(unaryop_ty op, expr_ty operand, int lineno, int col_offset, PyArena
+        *arena)
+{
+        expr_ty p;
+        if (!op) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field op is required for UnaryOp");
+                return NULL;
+        }
+        if (!operand) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field operand is required for UnaryOp");
+                return NULL;
+        }
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = UnaryOp_kind;
+        p->v.UnaryOp.op = op;
+        p->v.UnaryOp.operand = operand;
+        p->lineno = lineno;
+        p->col_offset = col_offset;
+        return p;
+}
+
+expr_ty
+Lambda(arguments_ty args, expr_ty body, int lineno, int col_offset, PyArena
+       *arena)
+{
+        expr_ty p;
+        if (!args) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field args is required for Lambda");
+                return NULL;
+        }
+        if (!body) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field body is required for Lambda");
+                return NULL;
+        }
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = Lambda_kind;
+        p->v.Lambda.args = args;
+        p->v.Lambda.body = body;
+        p->lineno = lineno;
+        p->col_offset = col_offset;
+        return p;
+}
+
+expr_ty
+IfExp(expr_ty test, expr_ty body, expr_ty orelse, int lineno, int col_offset,
+      PyArena *arena)
+{
+        expr_ty p;
+        if (!test) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field test is required for IfExp");
+                return NULL;
+        }
+        if (!body) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field body is required for IfExp");
+                return NULL;
+        }
+        if (!orelse) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field orelse is required for IfExp");
+                return NULL;
+        }
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = IfExp_kind;
+        p->v.IfExp.test = test;
+        p->v.IfExp.body = body;
+        p->v.IfExp.orelse = orelse;
+        p->lineno = lineno;
+        p->col_offset = col_offset;
+        return p;
+}
+
+expr_ty
+Dict(asdl_seq * keys, asdl_seq * values, int lineno, int col_offset, PyArena
+     *arena)
+{
+        expr_ty p;
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = Dict_kind;
+        p->v.Dict.keys = keys;
+        p->v.Dict.values = values;
+        p->lineno = lineno;
+        p->col_offset = col_offset;
+        return p;
+}
+
+expr_ty
+ListComp(expr_ty elt, asdl_seq * generators, int lineno, int col_offset,
+         PyArena *arena)
+{
+        expr_ty p;
+        if (!elt) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field elt is required for ListComp");
+                return NULL;
+        }
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = ListComp_kind;
+        p->v.ListComp.elt = elt;
+        p->v.ListComp.generators = generators;
+        p->lineno = lineno;
+        p->col_offset = col_offset;
+        return p;
+}
+
+expr_ty
+GeneratorExp(expr_ty elt, asdl_seq * generators, int lineno, int col_offset,
+             PyArena *arena)
+{
+        expr_ty p;
+        if (!elt) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field elt is required for GeneratorExp");
+                return NULL;
+        }
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = GeneratorExp_kind;
+        p->v.GeneratorExp.elt = elt;
+        p->v.GeneratorExp.generators = generators;
+        p->lineno = lineno;
+        p->col_offset = col_offset;
+        return p;
+}
+
+expr_ty
+Yield(expr_ty value, int lineno, int col_offset, PyArena *arena)
+{
+        expr_ty p;
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = Yield_kind;
+        p->v.Yield.value = value;
+        p->lineno = lineno;
+        p->col_offset = col_offset;
+        return p;
+}
+
+expr_ty
+Compare(expr_ty left, asdl_int_seq * ops, asdl_seq * comparators, int lineno,
+        int col_offset, PyArena *arena)
+{
+        expr_ty p;
+        if (!left) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field left is required for Compare");
+                return NULL;
+        }
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = Compare_kind;
+        p->v.Compare.left = left;
+        p->v.Compare.ops = ops;
+        p->v.Compare.comparators = comparators;
+        p->lineno = lineno;
+        p->col_offset = col_offset;
+        return p;
+}
+
+expr_ty
+Call(expr_ty func, asdl_seq * args, asdl_seq * keywords, expr_ty starargs,
+     expr_ty kwargs, int lineno, int col_offset, PyArena *arena)
+{
+        expr_ty p;
+        if (!func) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field func is required for Call");
+                return NULL;
+        }
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = Call_kind;
+        p->v.Call.func = func;
+        p->v.Call.args = args;
+        p->v.Call.keywords = keywords;
+        p->v.Call.starargs = starargs;
+        p->v.Call.kwargs = kwargs;
+        p->lineno = lineno;
+        p->col_offset = col_offset;
+        return p;
+}
+
+expr_ty
+Repr(expr_ty value, int lineno, int col_offset, PyArena *arena)
+{
+        expr_ty p;
+        if (!value) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field value is required for Repr");
+                return NULL;
+        }
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = Repr_kind;
+        p->v.Repr.value = value;
+        p->lineno = lineno;
+        p->col_offset = col_offset;
+        return p;
+}
+
+expr_ty
+Num(object n, int lineno, int col_offset, PyArena *arena)
+{
+        expr_ty p;
+        if (!n) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field n is required for Num");
+                return NULL;
+        }
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = Num_kind;
+        p->v.Num.n = n;
+        p->lineno = lineno;
+        p->col_offset = col_offset;
+        return p;
+}
+
+expr_ty
+Str(string s, int lineno, int col_offset, PyArena *arena)
+{
+        expr_ty p;
+        if (!s) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field s is required for Str");
+                return NULL;
+        }
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = Str_kind;
+        p->v.Str.s = s;
+        p->lineno = lineno;
+        p->col_offset = col_offset;
+        return p;
+}
+
+expr_ty
+Attribute(expr_ty value, identifier attr, expr_context_ty ctx, int lineno, int
+          col_offset, PyArena *arena)
+{
+        expr_ty p;
+        if (!value) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field value is required for Attribute");
+                return NULL;
+        }
+        if (!attr) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field attr is required for Attribute");
+                return NULL;
+        }
+        if (!ctx) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field ctx is required for Attribute");
+                return NULL;
+        }
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = Attribute_kind;
+        p->v.Attribute.value = value;
+        p->v.Attribute.attr = attr;
+        p->v.Attribute.ctx = ctx;
+        p->lineno = lineno;
+        p->col_offset = col_offset;
+        return p;
+}
+
+expr_ty
+Subscript(expr_ty value, slice_ty slice, expr_context_ty ctx, int lineno, int
+          col_offset, PyArena *arena)
+{
+        expr_ty p;
+        if (!value) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field value is required for Subscript");
+                return NULL;
+        }
+        if (!slice) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field slice is required for Subscript");
+                return NULL;
+        }
+        if (!ctx) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field ctx is required for Subscript");
+                return NULL;
+        }
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = Subscript_kind;
+        p->v.Subscript.value = value;
+        p->v.Subscript.slice = slice;
+        p->v.Subscript.ctx = ctx;
+        p->lineno = lineno;
+        p->col_offset = col_offset;
+        return p;
+}
+
+expr_ty
+Name(identifier id, expr_context_ty ctx, int lineno, int col_offset, PyArena
+     *arena)
+{
+        expr_ty p;
+        if (!id) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field id is required for Name");
+                return NULL;
+        }
+        if (!ctx) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field ctx is required for Name");
+                return NULL;
+        }
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = Name_kind;
+        p->v.Name.id = id;
+        p->v.Name.ctx = ctx;
+        p->lineno = lineno;
+        p->col_offset = col_offset;
+        return p;
+}
+
+expr_ty
+List(asdl_seq * elts, expr_context_ty ctx, int lineno, int col_offset, PyArena
+     *arena)
+{
+        expr_ty p;
+        if (!ctx) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field ctx is required for List");
+                return NULL;
+        }
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = List_kind;
+        p->v.List.elts = elts;
+        p->v.List.ctx = ctx;
+        p->lineno = lineno;
+        p->col_offset = col_offset;
+        return p;
+}
+
+expr_ty
+Tuple(asdl_seq * elts, expr_context_ty ctx, int lineno, int col_offset, PyArena
+      *arena)
+{
+        expr_ty p;
+        if (!ctx) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field ctx is required for Tuple");
+                return NULL;
+        }
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = Tuple_kind;
+        p->v.Tuple.elts = elts;
+        p->v.Tuple.ctx = ctx;
+        p->lineno = lineno;
+        p->col_offset = col_offset;
+        return p;
+}
+
+slice_ty
+Ellipsis(PyArena *arena)
+{
+        slice_ty p;
+        p = (slice_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = Ellipsis_kind;
+        return p;
+}
+
+slice_ty
+Slice(expr_ty lower, expr_ty upper, expr_ty step, PyArena *arena)
+{
+        slice_ty p;
+        p = (slice_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = Slice_kind;
+        p->v.Slice.lower = lower;
+        p->v.Slice.upper = upper;
+        p->v.Slice.step = step;
+        return p;
+}
+
+slice_ty
+ExtSlice(asdl_seq * dims, PyArena *arena)
+{
+        slice_ty p;
+        p = (slice_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = ExtSlice_kind;
+        p->v.ExtSlice.dims = dims;
+        return p;
+}
+
+slice_ty
+Index(expr_ty value, PyArena *arena)
+{
+        slice_ty p;
+        if (!value) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field value is required for Index");
+                return NULL;
+        }
+        p = (slice_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = Index_kind;
+        p->v.Index.value = value;
+        return p;
+}
+
+comprehension_ty
+comprehension(expr_ty target, expr_ty iter, asdl_seq * ifs, PyArena *arena)
+{
+        comprehension_ty p;
+        if (!target) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field target is required for comprehension");
+                return NULL;
+        }
+        if (!iter) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field iter is required for comprehension");
+                return NULL;
+        }
+        p = (comprehension_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->target = target;
+        p->iter = iter;
+        p->ifs = ifs;
+        return p;
+}
+
+excepthandler_ty
+excepthandler(expr_ty type, expr_ty name, asdl_seq * body, int lineno, int
+              col_offset, PyArena *arena)
+{
+        excepthandler_ty p;
+        p = (excepthandler_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->type = type;
+        p->name = name;
+        p->body = body;
+        p->lineno = lineno;
+        p->col_offset = col_offset;
+        return p;
+}
+
+arguments_ty
+arguments(asdl_seq * args, identifier vararg, identifier kwarg, asdl_seq *
+          defaults, PyArena *arena)
+{
+        arguments_ty p;
+        p = (arguments_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->args = args;
+        p->vararg = vararg;
+        p->kwarg = kwarg;
+        p->defaults = defaults;
+        return p;
+}
+
+keyword_ty
+keyword(identifier arg, expr_ty value, PyArena *arena)
+{
+        keyword_ty p;
+        if (!arg) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field arg is required for keyword");
+                return NULL;
+        }
+        if (!value) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field value is required for keyword");
+                return NULL;
+        }
+        p = (keyword_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->arg = arg;
+        p->value = value;
+        return p;
+}
+
+alias_ty
+alias(identifier name, identifier asname, PyArena *arena)
+{
+        alias_ty p;
+        if (!name) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field name is required for alias");
+                return NULL;
+        }
+        p = (alias_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->name = name;
+        p->asname = asname;
+        return p;
+}
+
+
+PyObject*
+ast2obj_mod(void* _o)
+{
+        mod_ty o = (mod_ty)_o;
+        PyObject *result = NULL, *value = NULL;
+        if (!o) {
+                Py_INCREF(Py_None);
+                return Py_None;
+        }
+
+        switch (o->kind) {
+        case Module_kind:
+                result = PyType_GenericNew(Module_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_list(o->v.Module.body, ast2obj_stmt);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "body", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
+        case Interactive_kind:
+                result = PyType_GenericNew(Interactive_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_list(o->v.Interactive.body, ast2obj_stmt);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "body", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
+        case Expression_kind:
+                result = PyType_GenericNew(Expression_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_expr(o->v.Expression.body);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "body", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
+        case Suite_kind:
+                result = PyType_GenericNew(Suite_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_list(o->v.Suite.body, ast2obj_stmt);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "body", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
+        }
+        return result;
+failed:
+        Py_XDECREF(value);
+        Py_XDECREF(result);
+        return NULL;
+}
+
+PyObject*
+ast2obj_stmt(void* _o)
+{
+        stmt_ty o = (stmt_ty)_o;
+        PyObject *result = NULL, *value = NULL;
+        if (!o) {
+                Py_INCREF(Py_None);
+                return Py_None;
+        }
+
+        switch (o->kind) {
+        case FunctionDef_kind:
+                result = PyType_GenericNew(FunctionDef_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_identifier(o->v.FunctionDef.name);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "name", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_arguments(o->v.FunctionDef.args);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "args", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_list(o->v.FunctionDef.body, ast2obj_stmt);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "body", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_list(o->v.FunctionDef.decorators, ast2obj_expr);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "decorators", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
+        case ClassDef_kind:
+                result = PyType_GenericNew(ClassDef_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_identifier(o->v.ClassDef.name);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "name", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_list(o->v.ClassDef.bases, ast2obj_expr);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "bases", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_list(o->v.ClassDef.body, ast2obj_stmt);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "body", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
+        case Return_kind:
+                result = PyType_GenericNew(Return_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_expr(o->v.Return.value);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "value", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
+        case Delete_kind:
+                result = PyType_GenericNew(Delete_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_list(o->v.Delete.targets, ast2obj_expr);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "targets", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
+        case Assign_kind:
+                result = PyType_GenericNew(Assign_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_list(o->v.Assign.targets, ast2obj_expr);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "targets", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_expr(o->v.Assign.value);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "value", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
+        case AugAssign_kind:
+                result = PyType_GenericNew(AugAssign_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_expr(o->v.AugAssign.target);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "target", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_operator(o->v.AugAssign.op);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "op", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_expr(o->v.AugAssign.value);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "value", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
+        case Print_kind:
+                result = PyType_GenericNew(Print_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_expr(o->v.Print.dest);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "dest", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_list(o->v.Print.values, ast2obj_expr);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "values", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_bool(o->v.Print.nl);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "nl", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
+        case For_kind:
+                result = PyType_GenericNew(For_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_expr(o->v.For.target);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "target", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_expr(o->v.For.iter);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "iter", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_list(o->v.For.body, ast2obj_stmt);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "body", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_list(o->v.For.orelse, ast2obj_stmt);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "orelse", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
+        case While_kind:
+                result = PyType_GenericNew(While_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_expr(o->v.While.test);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "test", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_list(o->v.While.body, ast2obj_stmt);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "body", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_list(o->v.While.orelse, ast2obj_stmt);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "orelse", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
+        case If_kind:
+                result = PyType_GenericNew(If_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_expr(o->v.If.test);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "test", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_list(o->v.If.body, ast2obj_stmt);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "body", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_list(o->v.If.orelse, ast2obj_stmt);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "orelse", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
+        case With_kind:
+                result = PyType_GenericNew(With_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_expr(o->v.With.context_expr);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "context_expr", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_expr(o->v.With.optional_vars);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "optional_vars", value) ==
+                    -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_list(o->v.With.body, ast2obj_stmt);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "body", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
+        case Raise_kind:
+                result = PyType_GenericNew(Raise_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_expr(o->v.Raise.type);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "type", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_expr(o->v.Raise.inst);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "inst", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_expr(o->v.Raise.tback);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "tback", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
+        case TryExcept_kind:
+                result = PyType_GenericNew(TryExcept_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_list(o->v.TryExcept.body, ast2obj_stmt);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "body", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_list(o->v.TryExcept.handlers,
+                                     ast2obj_excepthandler);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "handlers", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_list(o->v.TryExcept.orelse, ast2obj_stmt);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "orelse", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
+        case TryFinally_kind:
+                result = PyType_GenericNew(TryFinally_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_list(o->v.TryFinally.body, ast2obj_stmt);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "body", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_list(o->v.TryFinally.finalbody, ast2obj_stmt);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "finalbody", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
+        case Assert_kind:
+                result = PyType_GenericNew(Assert_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_expr(o->v.Assert.test);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "test", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_expr(o->v.Assert.msg);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "msg", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
+        case Import_kind:
+                result = PyType_GenericNew(Import_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_list(o->v.Import.names, ast2obj_alias);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "names", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
+        case ImportFrom_kind:
+                result = PyType_GenericNew(ImportFrom_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_identifier(o->v.ImportFrom.module);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "module", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_list(o->v.ImportFrom.names, ast2obj_alias);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "names", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_int(o->v.ImportFrom.level);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "level", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
+        case Exec_kind:
+                result = PyType_GenericNew(Exec_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_expr(o->v.Exec.body);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "body", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_expr(o->v.Exec.globals);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "globals", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_expr(o->v.Exec.locals);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "locals", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
+        case Global_kind:
+                result = PyType_GenericNew(Global_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_list(o->v.Global.names, ast2obj_identifier);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "names", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
+        case Expr_kind:
+                result = PyType_GenericNew(Expr_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_expr(o->v.Expr.value);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "value", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
+        case Pass_kind:
+                result = PyType_GenericNew(Pass_type, NULL, NULL);
+                if (!result) goto failed;
+                break;
+        case Break_kind:
+                result = PyType_GenericNew(Break_type, NULL, NULL);
+                if (!result) goto failed;
+                break;
+        case Continue_kind:
+                result = PyType_GenericNew(Continue_type, NULL, NULL);
+                if (!result) goto failed;
+                break;
+        }
+        value = ast2obj_int(o->lineno);
+        if (!value) goto failed;
+        if (PyObject_SetAttrString(result, "lineno", value) < 0)
+                goto failed;
+        Py_DECREF(value);
+        value = ast2obj_int(o->col_offset);
+        if (!value) goto failed;
+        if (PyObject_SetAttrString(result, "col_offset", value) < 0)
+                goto failed;
+        Py_DECREF(value);
+        return result;
+failed:
+        Py_XDECREF(value);
+        Py_XDECREF(result);
+        return NULL;
+}
+
+PyObject*
+ast2obj_expr(void* _o)
+{
+        expr_ty o = (expr_ty)_o;
+        PyObject *result = NULL, *value = NULL;
+        if (!o) {
+                Py_INCREF(Py_None);
+                return Py_None;
+        }
+
+        switch (o->kind) {
+        case BoolOp_kind:
+                result = PyType_GenericNew(BoolOp_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_boolop(o->v.BoolOp.op);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "op", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_list(o->v.BoolOp.values, ast2obj_expr);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "values", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
+        case BinOp_kind:
+                result = PyType_GenericNew(BinOp_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_expr(o->v.BinOp.left);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "left", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_operator(o->v.BinOp.op);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "op", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_expr(o->v.BinOp.right);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "right", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
+        case UnaryOp_kind:
+                result = PyType_GenericNew(UnaryOp_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_unaryop(o->v.UnaryOp.op);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "op", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_expr(o->v.UnaryOp.operand);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "operand", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
+        case Lambda_kind:
+                result = PyType_GenericNew(Lambda_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_arguments(o->v.Lambda.args);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "args", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_expr(o->v.Lambda.body);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "body", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
+        case IfExp_kind:
+                result = PyType_GenericNew(IfExp_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_expr(o->v.IfExp.test);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "test", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_expr(o->v.IfExp.body);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "body", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_expr(o->v.IfExp.orelse);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "orelse", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
+        case Dict_kind:
+                result = PyType_GenericNew(Dict_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_list(o->v.Dict.keys, ast2obj_expr);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "keys", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_list(o->v.Dict.values, ast2obj_expr);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "values", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
+        case ListComp_kind:
+                result = PyType_GenericNew(ListComp_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_expr(o->v.ListComp.elt);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "elt", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_list(o->v.ListComp.generators,
+                                     ast2obj_comprehension);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "generators", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
+        case GeneratorExp_kind:
+                result = PyType_GenericNew(GeneratorExp_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_expr(o->v.GeneratorExp.elt);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "elt", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_list(o->v.GeneratorExp.generators,
+                                     ast2obj_comprehension);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "generators", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
+        case Yield_kind:
+                result = PyType_GenericNew(Yield_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_expr(o->v.Yield.value);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "value", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
+        case Compare_kind:
+                result = PyType_GenericNew(Compare_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_expr(o->v.Compare.left);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "left", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                {
+                        int i, n = asdl_seq_LEN(o->v.Compare.ops);
+                        value = PyList_New(n);
+                        if (!value) goto failed;
+                        for(i = 0; i < n; i++)
+                                PyList_SET_ITEM(value, i, ast2obj_cmpop((cmpop_ty)asdl_seq_GET(o->v.Compare.ops, i)));
+                }
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "ops", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_list(o->v.Compare.comparators, ast2obj_expr);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "comparators", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
+        case Call_kind:
+                result = PyType_GenericNew(Call_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_expr(o->v.Call.func);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "func", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_list(o->v.Call.args, ast2obj_expr);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "args", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_list(o->v.Call.keywords, ast2obj_keyword);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "keywords", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_expr(o->v.Call.starargs);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "starargs", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_expr(o->v.Call.kwargs);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "kwargs", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
+        case Repr_kind:
+                result = PyType_GenericNew(Repr_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_expr(o->v.Repr.value);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "value", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
+        case Num_kind:
+                result = PyType_GenericNew(Num_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_object(o->v.Num.n);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "n", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
+        case Str_kind:
+                result = PyType_GenericNew(Str_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_string(o->v.Str.s);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "s", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
+        case Attribute_kind:
+                result = PyType_GenericNew(Attribute_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_expr(o->v.Attribute.value);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "value", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_identifier(o->v.Attribute.attr);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "attr", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_expr_context(o->v.Attribute.ctx);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "ctx", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
+        case Subscript_kind:
+                result = PyType_GenericNew(Subscript_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_expr(o->v.Subscript.value);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "value", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_slice(o->v.Subscript.slice);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "slice", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_expr_context(o->v.Subscript.ctx);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "ctx", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
+        case Name_kind:
+                result = PyType_GenericNew(Name_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_identifier(o->v.Name.id);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "id", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_expr_context(o->v.Name.ctx);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "ctx", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
+        case List_kind:
+                result = PyType_GenericNew(List_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_list(o->v.List.elts, ast2obj_expr);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "elts", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_expr_context(o->v.List.ctx);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "ctx", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
+        case Tuple_kind:
+                result = PyType_GenericNew(Tuple_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_list(o->v.Tuple.elts, ast2obj_expr);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "elts", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_expr_context(o->v.Tuple.ctx);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "ctx", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
+        }
+        value = ast2obj_int(o->lineno);
+        if (!value) goto failed;
+        if (PyObject_SetAttrString(result, "lineno", value) < 0)
+                goto failed;
+        Py_DECREF(value);
+        value = ast2obj_int(o->col_offset);
+        if (!value) goto failed;
+        if (PyObject_SetAttrString(result, "col_offset", value) < 0)
+                goto failed;
+        Py_DECREF(value);
+        return result;
+failed:
+        Py_XDECREF(value);
+        Py_XDECREF(result);
+        return NULL;
+}
+
+PyObject* ast2obj_expr_context(expr_context_ty o)
+{
+        switch(o) {
+                case Load:
+                        Py_INCREF(Load_singleton);
+                        return Load_singleton;
+                case Store:
+                        Py_INCREF(Store_singleton);
+                        return Store_singleton;
+                case Del:
+                        Py_INCREF(Del_singleton);
+                        return Del_singleton;
+                case AugLoad:
+                        Py_INCREF(AugLoad_singleton);
+                        return AugLoad_singleton;
+                case AugStore:
+                        Py_INCREF(AugStore_singleton);
+                        return AugStore_singleton;
+                case Param:
+                        Py_INCREF(Param_singleton);
+                        return Param_singleton;
+        }
+        return NULL; /* cannot happen */
+}
+PyObject*
+ast2obj_slice(void* _o)
+{
+        slice_ty o = (slice_ty)_o;
+        PyObject *result = NULL, *value = NULL;
+        if (!o) {
+                Py_INCREF(Py_None);
+                return Py_None;
+        }
+
+        switch (o->kind) {
+        case Ellipsis_kind:
+                result = PyType_GenericNew(Ellipsis_type, NULL, NULL);
+                if (!result) goto failed;
+                break;
+        case Slice_kind:
+                result = PyType_GenericNew(Slice_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_expr(o->v.Slice.lower);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "lower", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_expr(o->v.Slice.upper);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "upper", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_expr(o->v.Slice.step);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "step", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
+        case ExtSlice_kind:
+                result = PyType_GenericNew(ExtSlice_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_list(o->v.ExtSlice.dims, ast2obj_slice);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "dims", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
+        case Index_kind:
+                result = PyType_GenericNew(Index_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_expr(o->v.Index.value);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "value", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
+        }
+        return result;
+failed:
+        Py_XDECREF(value);
+        Py_XDECREF(result);
+        return NULL;
+}
+
+PyObject* ast2obj_boolop(boolop_ty o)
+{
+        switch(o) {
+                case And:
+                        Py_INCREF(And_singleton);
+                        return And_singleton;
+                case Or:
+                        Py_INCREF(Or_singleton);
+                        return Or_singleton;
+        }
+        return NULL; /* cannot happen */
+}
+PyObject* ast2obj_operator(operator_ty o)
+{
+        switch(o) {
+                case Add:
+                        Py_INCREF(Add_singleton);
+                        return Add_singleton;
+                case Sub:
+                        Py_INCREF(Sub_singleton);
+                        return Sub_singleton;
+                case Mult:
+                        Py_INCREF(Mult_singleton);
+                        return Mult_singleton;
+                case Div:
+                        Py_INCREF(Div_singleton);
+                        return Div_singleton;
+                case Mod:
+                        Py_INCREF(Mod_singleton);
+                        return Mod_singleton;
+                case Pow:
+                        Py_INCREF(Pow_singleton);
+                        return Pow_singleton;
+                case LShift:
+                        Py_INCREF(LShift_singleton);
+                        return LShift_singleton;
+                case RShift:
+                        Py_INCREF(RShift_singleton);
+                        return RShift_singleton;
+                case BitOr:
+                        Py_INCREF(BitOr_singleton);
+                        return BitOr_singleton;
+                case BitXor:
+                        Py_INCREF(BitXor_singleton);
+                        return BitXor_singleton;
+                case BitAnd:
+                        Py_INCREF(BitAnd_singleton);
+                        return BitAnd_singleton;
+                case FloorDiv:
+                        Py_INCREF(FloorDiv_singleton);
+                        return FloorDiv_singleton;
+        }
+        return NULL; /* cannot happen */
+}
+PyObject* ast2obj_unaryop(unaryop_ty o)
+{
+        switch(o) {
+                case Invert:
+                        Py_INCREF(Invert_singleton);
+                        return Invert_singleton;
+                case Not:
+                        Py_INCREF(Not_singleton);
+                        return Not_singleton;
+                case UAdd:
+                        Py_INCREF(UAdd_singleton);
+                        return UAdd_singleton;
+                case USub:
+                        Py_INCREF(USub_singleton);
+                        return USub_singleton;
+        }
+        return NULL; /* cannot happen */
+}
+PyObject* ast2obj_cmpop(cmpop_ty o)
+{
+        switch(o) {
+                case Eq:
+                        Py_INCREF(Eq_singleton);
+                        return Eq_singleton;
+                case NotEq:
+                        Py_INCREF(NotEq_singleton);
+                        return NotEq_singleton;
+                case Lt:
+                        Py_INCREF(Lt_singleton);
+                        return Lt_singleton;
+                case LtE:
+                        Py_INCREF(LtE_singleton);
+                        return LtE_singleton;
+                case Gt:
+                        Py_INCREF(Gt_singleton);
+                        return Gt_singleton;
+                case GtE:
+                        Py_INCREF(GtE_singleton);
+                        return GtE_singleton;
+                case Is:
+                        Py_INCREF(Is_singleton);
+                        return Is_singleton;
+                case IsNot:
+                        Py_INCREF(IsNot_singleton);
+                        return IsNot_singleton;
+                case In:
+                        Py_INCREF(In_singleton);
+                        return In_singleton;
+                case NotIn:
+                        Py_INCREF(NotIn_singleton);
+                        return NotIn_singleton;
+        }
+        return NULL; /* cannot happen */
+}
+PyObject*
+ast2obj_comprehension(void* _o)
+{
+        comprehension_ty o = (comprehension_ty)_o;
+        PyObject *result = NULL, *value = NULL;
+        if (!o) {
+                Py_INCREF(Py_None);
+                return Py_None;
+        }
+
+        result = PyType_GenericNew(comprehension_type, NULL, NULL);
+        if (!result) return NULL;
+        value = ast2obj_expr(o->target);
+        if (!value) goto failed;
+        if (PyObject_SetAttrString(result, "target", value) == -1)
+                goto failed;
+        Py_DECREF(value);
+        value = ast2obj_expr(o->iter);
+        if (!value) goto failed;
+        if (PyObject_SetAttrString(result, "iter", value) == -1)
+                goto failed;
+        Py_DECREF(value);
+        value = ast2obj_list(o->ifs, ast2obj_expr);
+        if (!value) goto failed;
+        if (PyObject_SetAttrString(result, "ifs", value) == -1)
+                goto failed;
+        Py_DECREF(value);
+        return result;
+failed:
+        Py_XDECREF(value);
+        Py_XDECREF(result);
+        return NULL;
+}
+
+PyObject*
+ast2obj_excepthandler(void* _o)
+{
+        excepthandler_ty o = (excepthandler_ty)_o;
+        PyObject *result = NULL, *value = NULL;
+        if (!o) {
+                Py_INCREF(Py_None);
+                return Py_None;
+        }
+
+        result = PyType_GenericNew(excepthandler_type, NULL, NULL);
+        if (!result) return NULL;
+        value = ast2obj_expr(o->type);
+        if (!value) goto failed;
+        if (PyObject_SetAttrString(result, "type", value) == -1)
+                goto failed;
+        Py_DECREF(value);
+        value = ast2obj_expr(o->name);
+        if (!value) goto failed;
+        if (PyObject_SetAttrString(result, "name", value) == -1)
+                goto failed;
+        Py_DECREF(value);
+        value = ast2obj_list(o->body, ast2obj_stmt);
+        if (!value) goto failed;
+        if (PyObject_SetAttrString(result, "body", value) == -1)
+                goto failed;
+        Py_DECREF(value);
+        value = ast2obj_int(o->lineno);
+        if (!value) goto failed;
+        if (PyObject_SetAttrString(result, "lineno", value) == -1)
+                goto failed;
+        Py_DECREF(value);
+        value = ast2obj_int(o->col_offset);
+        if (!value) goto failed;
+        if (PyObject_SetAttrString(result, "col_offset", value) == -1)
+                goto failed;
+        Py_DECREF(value);
+        return result;
+failed:
+        Py_XDECREF(value);
+        Py_XDECREF(result);
+        return NULL;
+}
+
+PyObject*
+ast2obj_arguments(void* _o)
+{
+        arguments_ty o = (arguments_ty)_o;
+        PyObject *result = NULL, *value = NULL;
+        if (!o) {
+                Py_INCREF(Py_None);
+                return Py_None;
+        }
+
+        result = PyType_GenericNew(arguments_type, NULL, NULL);
+        if (!result) return NULL;
+        value = ast2obj_list(o->args, ast2obj_expr);
+        if (!value) goto failed;
+        if (PyObject_SetAttrString(result, "args", value) == -1)
+                goto failed;
+        Py_DECREF(value);
+        value = ast2obj_identifier(o->vararg);
+        if (!value) goto failed;
+        if (PyObject_SetAttrString(result, "vararg", value) == -1)
+                goto failed;
+        Py_DECREF(value);
+        value = ast2obj_identifier(o->kwarg);
+        if (!value) goto failed;
+        if (PyObject_SetAttrString(result, "kwarg", value) == -1)
+                goto failed;
+        Py_DECREF(value);
+        value = ast2obj_list(o->defaults, ast2obj_expr);
+        if (!value) goto failed;
+        if (PyObject_SetAttrString(result, "defaults", value) == -1)
+                goto failed;
+        Py_DECREF(value);
+        return result;
+failed:
+        Py_XDECREF(value);
+        Py_XDECREF(result);
+        return NULL;
+}
+
+PyObject*
+ast2obj_keyword(void* _o)
+{
+        keyword_ty o = (keyword_ty)_o;
+        PyObject *result = NULL, *value = NULL;
+        if (!o) {
+                Py_INCREF(Py_None);
+                return Py_None;
+        }
+
+        result = PyType_GenericNew(keyword_type, NULL, NULL);
+        if (!result) return NULL;
+        value = ast2obj_identifier(o->arg);
+        if (!value) goto failed;
+        if (PyObject_SetAttrString(result, "arg", value) == -1)
+                goto failed;
+        Py_DECREF(value);
+        value = ast2obj_expr(o->value);
+        if (!value) goto failed;
+        if (PyObject_SetAttrString(result, "value", value) == -1)
+                goto failed;
+        Py_DECREF(value);
+        return result;
+failed:
+        Py_XDECREF(value);
+        Py_XDECREF(result);
+        return NULL;
+}
+
+PyObject*
+ast2obj_alias(void* _o)
+{
+        alias_ty o = (alias_ty)_o;
+        PyObject *result = NULL, *value = NULL;
+        if (!o) {
+                Py_INCREF(Py_None);
+                return Py_None;
+        }
+
+        result = PyType_GenericNew(alias_type, NULL, NULL);
+        if (!result) return NULL;
+        value = ast2obj_identifier(o->name);
+        if (!value) goto failed;
+        if (PyObject_SetAttrString(result, "name", value) == -1)
+                goto failed;
+        Py_DECREF(value);
+        value = ast2obj_identifier(o->asname);
+        if (!value) goto failed;
+        if (PyObject_SetAttrString(result, "asname", value) == -1)
+                goto failed;
+        Py_DECREF(value);
+        return result;
+failed:
+        Py_XDECREF(value);
+        Py_XDECREF(result);
+        return NULL;
+}
+
+
+PyMODINIT_FUNC
+init_ast(void)
+{
+        PyObject *m, *d;
+        if (!init_types()) return;
+        m = Py_InitModule3("_ast", NULL, NULL);
+        if (!m) return;
+        d = PyModule_GetDict(m);
+        if (PyDict_SetItemString(d, "AST", (PyObject*)AST_type) < 0) return;
+        if (PyModule_AddIntConstant(m, "PyCF_ONLY_AST", PyCF_ONLY_AST) < 0)
+                return;
+        if (PyModule_AddStringConstant(m, "__version__", "43614") < 0)
+                return;
+        if (PyDict_SetItemString(d, "mod", (PyObject*)mod_type) < 0) return;
+        if (PyDict_SetItemString(d, "Module", (PyObject*)Module_type) < 0)
+            return;
+        if (PyDict_SetItemString(d, "Interactive", (PyObject*)Interactive_type)
+            < 0) return;
+        if (PyDict_SetItemString(d, "Expression", (PyObject*)Expression_type) <
+            0) return;
+        if (PyDict_SetItemString(d, "Suite", (PyObject*)Suite_type) < 0) return;
+        if (PyDict_SetItemString(d, "stmt", (PyObject*)stmt_type) < 0) return;
+        if (PyDict_SetItemString(d, "FunctionDef", (PyObject*)FunctionDef_type)
+            < 0) return;
+        if (PyDict_SetItemString(d, "ClassDef", (PyObject*)ClassDef_type) < 0)
+            return;
+        if (PyDict_SetItemString(d, "Return", (PyObject*)Return_type) < 0)
+            return;
+        if (PyDict_SetItemString(d, "Delete", (PyObject*)Delete_type) < 0)
+            return;
+        if (PyDict_SetItemString(d, "Assign", (PyObject*)Assign_type) < 0)
+            return;
+        if (PyDict_SetItemString(d, "AugAssign", (PyObject*)AugAssign_type) <
+            0) return;
+        if (PyDict_SetItemString(d, "Print", (PyObject*)Print_type) < 0) return;
+        if (PyDict_SetItemString(d, "For", (PyObject*)For_type) < 0) return;
+        if (PyDict_SetItemString(d, "While", (PyObject*)While_type) < 0) return;
+        if (PyDict_SetItemString(d, "If", (PyObject*)If_type) < 0) return;
+        if (PyDict_SetItemString(d, "With", (PyObject*)With_type) < 0) return;
+        if (PyDict_SetItemString(d, "Raise", (PyObject*)Raise_type) < 0) return;
+        if (PyDict_SetItemString(d, "TryExcept", (PyObject*)TryExcept_type) <
+            0) return;
+        if (PyDict_SetItemString(d, "TryFinally", (PyObject*)TryFinally_type) <
+            0) return;
+        if (PyDict_SetItemString(d, "Assert", (PyObject*)Assert_type) < 0)
+            return;
+        if (PyDict_SetItemString(d, "Import", (PyObject*)Import_type) < 0)
+            return;
+        if (PyDict_SetItemString(d, "ImportFrom", (PyObject*)ImportFrom_type) <
+            0) return;
+        if (PyDict_SetItemString(d, "Exec", (PyObject*)Exec_type) < 0) return;
+        if (PyDict_SetItemString(d, "Global", (PyObject*)Global_type) < 0)
+            return;
+        if (PyDict_SetItemString(d, "Expr", (PyObject*)Expr_type) < 0) return;
+        if (PyDict_SetItemString(d, "Pass", (PyObject*)Pass_type) < 0) return;
+        if (PyDict_SetItemString(d, "Break", (PyObject*)Break_type) < 0) return;
+        if (PyDict_SetItemString(d, "Continue", (PyObject*)Continue_type) < 0)
+            return;
+        if (PyDict_SetItemString(d, "expr", (PyObject*)expr_type) < 0) return;
+        if (PyDict_SetItemString(d, "BoolOp", (PyObject*)BoolOp_type) < 0)
+            return;
+        if (PyDict_SetItemString(d, "BinOp", (PyObject*)BinOp_type) < 0) return;
+        if (PyDict_SetItemString(d, "UnaryOp", (PyObject*)UnaryOp_type) < 0)
+            return;
+        if (PyDict_SetItemString(d, "Lambda", (PyObject*)Lambda_type) < 0)
+            return;
+        if (PyDict_SetItemString(d, "IfExp", (PyObject*)IfExp_type) < 0) return;
+        if (PyDict_SetItemString(d, "Dict", (PyObject*)Dict_type) < 0) return;
+        if (PyDict_SetItemString(d, "ListComp", (PyObject*)ListComp_type) < 0)
+            return;
+        if (PyDict_SetItemString(d, "GeneratorExp",
+            (PyObject*)GeneratorExp_type) < 0) return;
+        if (PyDict_SetItemString(d, "Yield", (PyObject*)Yield_type) < 0) return;
+        if (PyDict_SetItemString(d, "Compare", (PyObject*)Compare_type) < 0)
+            return;
+        if (PyDict_SetItemString(d, "Call", (PyObject*)Call_type) < 0) return;
+        if (PyDict_SetItemString(d, "Repr", (PyObject*)Repr_type) < 0) return;
+        if (PyDict_SetItemString(d, "Num", (PyObject*)Num_type) < 0) return;
+        if (PyDict_SetItemString(d, "Str", (PyObject*)Str_type) < 0) return;
+        if (PyDict_SetItemString(d, "Attribute", (PyObject*)Attribute_type) <
+            0) return;
+        if (PyDict_SetItemString(d, "Subscript", (PyObject*)Subscript_type) <
+            0) return;
+        if (PyDict_SetItemString(d, "Name", (PyObject*)Name_type) < 0) return;
+        if (PyDict_SetItemString(d, "List", (PyObject*)List_type) < 0) return;
+        if (PyDict_SetItemString(d, "Tuple", (PyObject*)Tuple_type) < 0) return;
+        if (PyDict_SetItemString(d, "expr_context",
+            (PyObject*)expr_context_type) < 0) return;
+        if (PyDict_SetItemString(d, "Load", (PyObject*)Load_type) < 0) return;
+        if (PyDict_SetItemString(d, "Store", (PyObject*)Store_type) < 0) return;
+        if (PyDict_SetItemString(d, "Del", (PyObject*)Del_type) < 0) return;
+        if (PyDict_SetItemString(d, "AugLoad", (PyObject*)AugLoad_type) < 0)
+            return;
+        if (PyDict_SetItemString(d, "AugStore", (PyObject*)AugStore_type) < 0)
+            return;
+        if (PyDict_SetItemString(d, "Param", (PyObject*)Param_type) < 0) return;
+        if (PyDict_SetItemString(d, "slice", (PyObject*)slice_type) < 0) return;
+        if (PyDict_SetItemString(d, "Ellipsis", (PyObject*)Ellipsis_type) < 0)
+            return;
+        if (PyDict_SetItemString(d, "Slice", (PyObject*)Slice_type) < 0) return;
+        if (PyDict_SetItemString(d, "ExtSlice", (PyObject*)ExtSlice_type) < 0)
+            return;
+        if (PyDict_SetItemString(d, "Index", (PyObject*)Index_type) < 0) return;
+        if (PyDict_SetItemString(d, "boolop", (PyObject*)boolop_type) < 0)
+            return;
+        if (PyDict_SetItemString(d, "And", (PyObject*)And_type) < 0) return;
+        if (PyDict_SetItemString(d, "Or", (PyObject*)Or_type) < 0) return;
+        if (PyDict_SetItemString(d, "operator", (PyObject*)operator_type) < 0)
+            return;
+        if (PyDict_SetItemString(d, "Add", (PyObject*)Add_type) < 0) return;
+        if (PyDict_SetItemString(d, "Sub", (PyObject*)Sub_type) < 0) return;
+        if (PyDict_SetItemString(d, "Mult", (PyObject*)Mult_type) < 0) return;
+        if (PyDict_SetItemString(d, "Div", (PyObject*)Div_type) < 0) return;
+        if (PyDict_SetItemString(d, "Mod", (PyObject*)Mod_type) < 0) return;
+        if (PyDict_SetItemString(d, "Pow", (PyObject*)Pow_type) < 0) return;
+        if (PyDict_SetItemString(d, "LShift", (PyObject*)LShift_type) < 0)
+            return;
+        if (PyDict_SetItemString(d, "RShift", (PyObject*)RShift_type) < 0)
+            return;
+        if (PyDict_SetItemString(d, "BitOr", (PyObject*)BitOr_type) < 0) return;
+        if (PyDict_SetItemString(d, "BitXor", (PyObject*)BitXor_type) < 0)
+            return;
+        if (PyDict_SetItemString(d, "BitAnd", (PyObject*)BitAnd_type) < 0)
+            return;
+        if (PyDict_SetItemString(d, "FloorDiv", (PyObject*)FloorDiv_type) < 0)
+            return;
+        if (PyDict_SetItemString(d, "unaryop", (PyObject*)unaryop_type) < 0)
+            return;
+        if (PyDict_SetItemString(d, "Invert", (PyObject*)Invert_type) < 0)
+            return;
+        if (PyDict_SetItemString(d, "Not", (PyObject*)Not_type) < 0) return;
+        if (PyDict_SetItemString(d, "UAdd", (PyObject*)UAdd_type) < 0) return;
+        if (PyDict_SetItemString(d, "USub", (PyObject*)USub_type) < 0) return;
+        if (PyDict_SetItemString(d, "cmpop", (PyObject*)cmpop_type) < 0) return;
+        if (PyDict_SetItemString(d, "Eq", (PyObject*)Eq_type) < 0) return;
+        if (PyDict_SetItemString(d, "NotEq", (PyObject*)NotEq_type) < 0) return;
+        if (PyDict_SetItemString(d, "Lt", (PyObject*)Lt_type) < 0) return;
+        if (PyDict_SetItemString(d, "LtE", (PyObject*)LtE_type) < 0) return;
+        if (PyDict_SetItemString(d, "Gt", (PyObject*)Gt_type) < 0) return;
+        if (PyDict_SetItemString(d, "GtE", (PyObject*)GtE_type) < 0) return;
+        if (PyDict_SetItemString(d, "Is", (PyObject*)Is_type) < 0) return;
+        if (PyDict_SetItemString(d, "IsNot", (PyObject*)IsNot_type) < 0) return;
+        if (PyDict_SetItemString(d, "In", (PyObject*)In_type) < 0) return;
+        if (PyDict_SetItemString(d, "NotIn", (PyObject*)NotIn_type) < 0) return;
+        if (PyDict_SetItemString(d, "comprehension",
+            (PyObject*)comprehension_type) < 0) return;
+        if (PyDict_SetItemString(d, "excepthandler",
+            (PyObject*)excepthandler_type) < 0) return;
+        if (PyDict_SetItemString(d, "arguments", (PyObject*)arguments_type) <
+            0) return;
+        if (PyDict_SetItemString(d, "keyword", (PyObject*)keyword_type) < 0)
+            return;
+        if (PyDict_SetItemString(d, "alias", (PyObject*)alias_type) < 0) return;
+}
+
+
+PyObject* PyAST_mod2obj(mod_ty t)
+{
+    init_types();
+    return ast2obj_mod(t);
+}
+
+

Added: vendor/Python/current/Python/asdl.c
===================================================================
--- vendor/Python/current/Python/asdl.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/asdl.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,36 @@
+#include "Python.h"
+#include "asdl.h"
+
+asdl_seq *
+asdl_seq_new(int size, PyArena *arena)
+{
+	asdl_seq *seq = NULL;
+	size_t n = sizeof(asdl_seq) +
+			(size ? (sizeof(void *) * (size - 1)) : 0);
+
+	seq = (asdl_seq *)PyArena_Malloc(arena, n);
+	if (!seq) {
+		PyErr_NoMemory();
+		return NULL;
+	}
+	memset(seq, 0, n);
+	seq->size = size;
+	return seq;
+}
+
+asdl_int_seq *
+asdl_int_seq_new(int size, PyArena *arena)
+{
+	asdl_int_seq *seq = NULL;
+	size_t n = sizeof(asdl_seq) +
+			(size ? (sizeof(int) * (size - 1)) : 0);
+
+	seq = (asdl_int_seq *)PyArena_Malloc(arena, n);
+	if (!seq) {
+		PyErr_NoMemory();
+		return NULL;
+	}
+	memset(seq, 0, n);
+	seq->size = size;
+	return seq;
+}

Added: vendor/Python/current/Python/ast.c
===================================================================
--- vendor/Python/current/Python/ast.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/ast.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,3292 @@
+/*
+ * This file includes functions to transform a concrete syntax tree (CST) to
+ * an abstract syntax tree (AST).  The main function is PyAST_FromNode().
+ *
+ */
+#include "Python.h"
+#include "Python-ast.h"
+#include "grammar.h"
+#include "node.h"
+#include "pyarena.h"
+#include "ast.h"
+#include "token.h"
+#include "parsetok.h"
+#include "graminit.h"
+
+#include <assert.h>
+
+/* XXX TO DO
+   - re-indent this file (should be done)
+   - internal error checking (freeing memory, etc.)
+   - syntax errors
+*/
+
+/* Data structure used internally */
+struct compiling {
+    char *c_encoding; /* source encoding */
+    PyArena *c_arena; /* arena for allocating memeory */
+};
+
+static asdl_seq *seq_for_testlist(struct compiling *, const node *);
+static expr_ty ast_for_expr(struct compiling *, const node *);
+static stmt_ty ast_for_stmt(struct compiling *, const node *);
+static asdl_seq *ast_for_suite(struct compiling *, const node *);
+static asdl_seq *ast_for_exprlist(struct compiling *, const node *, expr_context_ty);
+static expr_ty ast_for_testlist(struct compiling *, const node *);
+static expr_ty ast_for_testlist_gexp(struct compiling *, const node *);
+
+/* Note different signature for ast_for_call */
+static expr_ty ast_for_call(struct compiling *, const node *, expr_ty);
+
+static PyObject *parsenumber(const char *);
+static PyObject *parsestr(const char *s, const char *encoding);
+static PyObject *parsestrplus(struct compiling *, const node *n);
+
+#ifndef LINENO
+#define LINENO(n)	((n)->n_lineno)
+#endif
+
+static identifier
+new_identifier(const char* n, PyArena *arena) {
+    PyObject* id = PyString_InternFromString(n);
+    PyArena_AddPyObject(arena, id);
+    return id;
+}
+
+#define NEW_IDENTIFIER(n) new_identifier(STR(n), c->c_arena)
+
+/* This routine provides an invalid object for the syntax error.
+   The outermost routine must unpack this error and create the
+   proper object.  We do this so that we don't have to pass
+   the filename to everything function.
+
+   XXX Maybe we should just pass the filename...
+*/
+
+static int
+ast_error(const node *n, const char *errstr)
+{
+    PyObject *u = Py_BuildValue("zi", errstr, LINENO(n));
+    if (!u)
+	return 0;
+    PyErr_SetObject(PyExc_SyntaxError, u);
+    Py_DECREF(u);
+    return 0;
+}
+
+static void
+ast_error_finish(const char *filename)
+{
+    PyObject *type, *value, *tback, *errstr, *loc, *tmp;
+    long lineno;
+
+    assert(PyErr_Occurred());
+    if (!PyErr_ExceptionMatches(PyExc_SyntaxError))
+	return;
+
+    PyErr_Fetch(&type, &value, &tback);
+    errstr = PyTuple_GetItem(value, 0);
+    if (!errstr)
+	return;
+    Py_INCREF(errstr);
+    lineno = PyInt_AsLong(PyTuple_GetItem(value, 1));
+    if (lineno == -1) {
+	Py_DECREF(errstr);
+	return;
+    }
+    Py_DECREF(value);
+
+    loc = PyErr_ProgramText(filename, lineno);
+    if (!loc) {
+	Py_INCREF(Py_None);
+	loc = Py_None;
+    }
+    tmp = Py_BuildValue("(zlOO)", filename, lineno, Py_None, loc);
+    Py_DECREF(loc);
+    if (!tmp) {
+	Py_DECREF(errstr);
+	return;
+    }
+    value = PyTuple_Pack(2, errstr, tmp);
+    Py_DECREF(errstr);
+    Py_DECREF(tmp);
+    if (!value)
+	return;
+    PyErr_Restore(type, value, tback);
+}
+
+/* num_stmts() returns number of contained statements.
+
+   Use this routine to determine how big a sequence is needed for
+   the statements in a parse tree.  Its raison d'etre is this bit of
+   grammar:
+
+   stmt: simple_stmt | compound_stmt
+   simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
+
+   A simple_stmt can contain multiple small_stmt elements joined
+   by semicolons.  If the arg is a simple_stmt, the number of
+   small_stmt elements is returned.
+*/
+
+static int
+num_stmts(const node *n)
+{
+    int i, l;
+    node *ch;
+
+    switch (TYPE(n)) {
+        case single_input:
+            if (TYPE(CHILD(n, 0)) == NEWLINE)
+                return 0;
+            else
+                return num_stmts(CHILD(n, 0));
+        case file_input:
+            l = 0;
+            for (i = 0; i < NCH(n); i++) {
+                ch = CHILD(n, i);
+                if (TYPE(ch) == stmt)
+                    l += num_stmts(ch);
+            }
+            return l;
+        case stmt:
+            return num_stmts(CHILD(n, 0));
+        case compound_stmt:
+            return 1;
+        case simple_stmt:
+            return NCH(n) / 2; /* Divide by 2 to remove count of semi-colons */
+        case suite:
+            if (NCH(n) == 1)
+                return num_stmts(CHILD(n, 0));
+            else {
+                l = 0;
+                for (i = 2; i < (NCH(n) - 1); i++)
+                    l += num_stmts(CHILD(n, i));
+                return l;
+            }
+        default: {
+            char buf[128];
+
+            sprintf(buf, "Non-statement found: %d %d\n",
+                    TYPE(n), NCH(n));
+            Py_FatalError(buf);
+        }
+    }
+    assert(0);
+    return 0;
+}
+
+/* Transform the CST rooted at node * to the appropriate AST
+*/
+
+mod_ty
+PyAST_FromNode(const node *n, PyCompilerFlags *flags, const char *filename,
+               PyArena *arena)
+{
+    int i, j, k, num;
+    asdl_seq *stmts = NULL;
+    stmt_ty s;
+    node *ch;
+    struct compiling c;
+
+    if (flags && flags->cf_flags & PyCF_SOURCE_IS_UTF8) {
+        c.c_encoding = "utf-8";
+        if (TYPE(n) == encoding_decl) {
+                ast_error(n, "encoding declaration in Unicode string");
+                goto error;
+        }
+    } else if (TYPE(n) == encoding_decl) {
+        c.c_encoding = STR(n);
+        n = CHILD(n, 0);
+    } else {
+        c.c_encoding = NULL;
+    }
+    c.c_arena = arena;
+
+    k = 0;
+    switch (TYPE(n)) {
+        case file_input:
+            stmts = asdl_seq_new(num_stmts(n), arena);
+            if (!stmts)
+                    return NULL;
+            for (i = 0; i < NCH(n) - 1; i++) {
+                ch = CHILD(n, i);
+                if (TYPE(ch) == NEWLINE)
+                    continue;
+                REQ(ch, stmt);
+                num = num_stmts(ch);
+                if (num == 1) {
+                    s = ast_for_stmt(&c, ch);
+                    if (!s)
+                        goto error;
+                    asdl_seq_SET(stmts, k++, s);
+                }
+                else {
+                    ch = CHILD(ch, 0);
+                    REQ(ch, simple_stmt);
+                    for (j = 0; j < num; j++) {
+                        s = ast_for_stmt(&c, CHILD(ch, j * 2));
+                        if (!s)
+                            goto error;
+                        asdl_seq_SET(stmts, k++, s);
+                    }
+                }
+            }
+            return Module(stmts, arena);
+        case eval_input: {
+            expr_ty testlist_ast;
+
+            /* XXX Why not gen_for here? */
+            testlist_ast = ast_for_testlist(&c, CHILD(n, 0));
+            if (!testlist_ast)
+                goto error;
+            return Expression(testlist_ast, arena);
+        }
+        case single_input:
+            if (TYPE(CHILD(n, 0)) == NEWLINE) {
+                stmts = asdl_seq_new(1, arena);
+                if (!stmts)
+		    goto error;
+                asdl_seq_SET(stmts, 0, Pass(n->n_lineno, n->n_col_offset,
+                                            arena));
+                return Interactive(stmts, arena);
+            }
+            else {
+                n = CHILD(n, 0);
+                num = num_stmts(n);
+                stmts = asdl_seq_new(num, arena);
+                if (!stmts)
+		    goto error;
+                if (num == 1) {
+		    s = ast_for_stmt(&c, n);
+		    if (!s)
+			goto error;
+                    asdl_seq_SET(stmts, 0, s);
+                }
+                else {
+                    /* Only a simple_stmt can contain multiple statements. */
+                    REQ(n, simple_stmt);
+                    for (i = 0; i < NCH(n); i += 2) {
+                        if (TYPE(CHILD(n, i)) == NEWLINE)
+                            break;
+                        s = ast_for_stmt(&c, CHILD(n, i));
+                        if (!s)
+                            goto error;
+                        asdl_seq_SET(stmts, i / 2, s);
+                    }
+                }
+
+                return Interactive(stmts, arena);
+            }
+        default:
+            goto error;
+    }
+ error:
+    ast_error_finish(filename);
+    return NULL;
+}
+
+/* Return the AST repr. of the operator represented as syntax (|, ^, etc.)
+*/
+
+static operator_ty
+get_operator(const node *n)
+{
+    switch (TYPE(n)) {
+        case VBAR:
+            return BitOr;
+        case CIRCUMFLEX:
+            return BitXor;
+        case AMPER:
+            return BitAnd;
+        case LEFTSHIFT:
+            return LShift;
+        case RIGHTSHIFT:
+            return RShift;
+        case PLUS:
+            return Add;
+        case MINUS:
+            return Sub;
+        case STAR:
+            return Mult;
+        case SLASH:
+            return Div;
+        case DOUBLESLASH:
+            return FloorDiv;
+        case PERCENT:
+            return Mod;
+        default:
+            return (operator_ty)0;
+    }
+}
+
+/* Set the context ctx for expr_ty e, recursively traversing e.
+
+   Only sets context for expr kinds that "can appear in assignment context"
+   (according to ../Parser/Python.asdl).  For other expr kinds, it sets
+   an appropriate syntax error and returns false.
+*/
+
+static int
+set_context(expr_ty e, expr_context_ty ctx, const node *n)
+{
+    asdl_seq *s = NULL;
+    /* If a particular expression type can't be used for assign / delete,
+       set expr_name to its name and an error message will be generated.
+    */
+    const char* expr_name = NULL;
+
+    /* The ast defines augmented store and load contexts, but the
+       implementation here doesn't actually use them.  The code may be
+       a little more complex than necessary as a result.  It also means
+       that expressions in an augmented assignment have a Store context.
+       Consider restructuring so that augmented assignment uses
+       set_context(), too.
+    */
+    assert(ctx != AugStore && ctx != AugLoad);
+
+    switch (e->kind) {
+        case Attribute_kind:
+	    if (ctx == Store &&
+		    !strcmp(PyString_AS_STRING(e->v.Attribute.attr), "None")) {
+		    return ast_error(n, "assignment to None");
+	    }
+	    e->v.Attribute.ctx = ctx;
+	    break;
+        case Subscript_kind:
+	    e->v.Subscript.ctx = ctx;
+	    break;
+        case Name_kind:
+	    if (ctx == Store &&
+		!strcmp(PyString_AS_STRING(e->v.Name.id), "None")) {
+		    return ast_error(n, "assignment to None");
+	    }
+	    e->v.Name.ctx = ctx;
+	    break;
+        case List_kind:
+	    e->v.List.ctx = ctx;
+	    s = e->v.List.elts;
+	    break;
+        case Tuple_kind:
+            if (asdl_seq_LEN(e->v.Tuple.elts) == 0) 
+                return ast_error(n, "can't assign to ()");
+	    e->v.Tuple.ctx = ctx;
+	    s = e->v.Tuple.elts;
+	    break;
+        case Lambda_kind:
+            expr_name = "lambda";
+            break;
+        case Call_kind:
+            expr_name = "function call";
+	    break;
+        case BoolOp_kind:
+        case BinOp_kind:
+        case UnaryOp_kind:
+            expr_name = "operator";
+            break;
+        case GeneratorExp_kind:
+            expr_name = "generator expression";
+            break;
+        case Yield_kind:
+            expr_name = "yield expression";
+            break;
+        case ListComp_kind:
+            expr_name = "list comprehension";
+            break;
+        case Dict_kind:
+        case Num_kind:
+        case Str_kind:
+            expr_name = "literal";
+            break;
+        case Compare_kind:
+            expr_name = "comparison";
+            break;
+        case Repr_kind:
+            expr_name = "repr";
+            break;
+        case IfExp_kind:
+            expr_name = "conditional expression";
+            break;
+        default:
+            PyErr_Format(PyExc_SystemError, 
+                         "unexpected expression in assignment %d (line %d)", 
+                         e->kind, e->lineno);
+            return 0;
+    }
+    /* Check for error string set by switch */
+    if (expr_name) {
+        char buf[300];
+        PyOS_snprintf(buf, sizeof(buf),
+                      "can't %s %s",
+                      ctx == Store ? "assign to" : "delete",
+                      expr_name);
+        return ast_error(n, buf);
+    }
+
+    /* If the LHS is a list or tuple, we need to set the assignment
+       context for all the contained elements.  
+    */
+    if (s) {
+	int i;
+
+	for (i = 0; i < asdl_seq_LEN(s); i++) {
+	    if (!set_context((expr_ty)asdl_seq_GET(s, i), ctx, n))
+		return 0;
+	}
+    }
+    return 1;
+}
+
+static operator_ty
+ast_for_augassign(const node *n)
+{
+    REQ(n, augassign);
+    n = CHILD(n, 0);
+    switch (STR(n)[0]) {
+        case '+':
+            return Add;
+        case '-':
+            return Sub;
+        case '/':
+            if (STR(n)[1] == '/')
+                return FloorDiv;
+            else
+                return Div;
+        case '%':
+            return Mod;
+        case '<':
+            return LShift;
+        case '>':
+            return RShift;
+        case '&':
+            return BitAnd;
+        case '^':
+            return BitXor;
+        case '|':
+            return BitOr;
+        case '*':
+            if (STR(n)[1] == '*')
+                return Pow;
+            else
+                return Mult;
+        default:
+            PyErr_Format(PyExc_SystemError, "invalid augassign: %s", STR(n));
+            return (operator_ty)0;
+    }
+}
+
+static cmpop_ty
+ast_for_comp_op(const node *n)
+{
+    /* comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'
+               |'is' 'not'
+    */
+    REQ(n, comp_op);
+    if (NCH(n) == 1) {
+	n = CHILD(n, 0);
+	switch (TYPE(n)) {
+            case LESS:
+                return Lt;
+            case GREATER:
+                return Gt;
+            case EQEQUAL:			/* == */
+                return Eq;
+            case LESSEQUAL:
+                return LtE;
+            case GREATEREQUAL:
+                return GtE;
+            case NOTEQUAL:
+                return NotEq;
+            case NAME:
+                if (strcmp(STR(n), "in") == 0)
+                    return In;
+                if (strcmp(STR(n), "is") == 0)
+                    return Is;
+            default:
+                PyErr_Format(PyExc_SystemError, "invalid comp_op: %s",
+                             STR(n));
+                return (cmpop_ty)0;
+	}
+    }
+    else if (NCH(n) == 2) {
+	/* handle "not in" and "is not" */
+	switch (TYPE(CHILD(n, 0))) {
+            case NAME:
+                if (strcmp(STR(CHILD(n, 1)), "in") == 0)
+                    return NotIn;
+                if (strcmp(STR(CHILD(n, 0)), "is") == 0)
+                    return IsNot;
+            default:
+                PyErr_Format(PyExc_SystemError, "invalid comp_op: %s %s",
+                             STR(CHILD(n, 0)), STR(CHILD(n, 1)));
+                return (cmpop_ty)0;
+	}
+    }
+    PyErr_Format(PyExc_SystemError, "invalid comp_op: has %d children",
+                 NCH(n));
+    return (cmpop_ty)0;
+}
+
+static asdl_seq *
+seq_for_testlist(struct compiling *c, const node *n)
+{
+    /* testlist: test (',' test)* [','] */
+    asdl_seq *seq;
+    expr_ty expression;
+    int i;
+    assert(TYPE(n) == testlist
+	   || TYPE(n) == listmaker
+	   || TYPE(n) == testlist_gexp
+	   || TYPE(n) == testlist_safe
+	   || TYPE(n) == testlist1
+	   );
+
+    seq = asdl_seq_new((NCH(n) + 1) / 2, c->c_arena);
+    if (!seq)
+        return NULL;
+
+    for (i = 0; i < NCH(n); i += 2) {
+        assert(TYPE(CHILD(n, i)) == test || TYPE(CHILD(n, i)) == old_test);
+
+        expression = ast_for_expr(c, CHILD(n, i));
+        if (!expression)
+            return NULL;
+
+        assert(i / 2 < seq->size);
+        asdl_seq_SET(seq, i / 2, expression);
+    }
+    return seq;
+}
+
+static expr_ty
+compiler_complex_args(struct compiling *c, const node *n)
+{
+    int i, len = (NCH(n) + 1) / 2;
+    expr_ty result;
+    asdl_seq *args = asdl_seq_new(len, c->c_arena);
+    if (!args)
+        return NULL;
+
+    /* fpdef: NAME | '(' fplist ')'
+       fplist: fpdef (',' fpdef)* [',']
+    */
+    REQ(n, fplist);
+    for (i = 0; i < len; i++) {
+        const node *fpdef_node = CHILD(n, 2*i);
+        const node *child;
+        expr_ty arg;
+set_name:
+        /* fpdef_node is either a NAME or an fplist */
+        child = CHILD(fpdef_node, 0);
+        if (TYPE(child) == NAME) {
+    		if (!strcmp(STR(child), "None")) {
+	    		ast_error(child, "assignment to None");
+		    	return NULL;
+		    }   
+            arg = Name(NEW_IDENTIFIER(child), Store, LINENO(child),
+                       child->n_col_offset, c->c_arena);
+	    }
+        else {
+            assert(TYPE(fpdef_node) == fpdef);
+            /* fpdef_node[0] is not a name, so it must be a '(', get CHILD[1] */
+            child = CHILD(fpdef_node, 1);
+            assert(TYPE(child) == fplist);
+            /* NCH == 1 means we have (x), we need to elide the extra parens */
+            if (NCH(child) == 1) {
+                fpdef_node = CHILD(child, 0);
+                assert(TYPE(fpdef_node) == fpdef);
+                goto set_name;
+            }
+            arg = compiler_complex_args(c, child);
+        }
+        asdl_seq_SET(args, i, arg);
+    }
+
+    result = Tuple(args, Store, LINENO(n), n->n_col_offset, c->c_arena);
+    if (!set_context(result, Store, n))
+        return NULL;
+    return result;
+}
+
+
+/* Create AST for argument list. */
+
+static arguments_ty
+ast_for_arguments(struct compiling *c, const node *n)
+{
+    /* parameters: '(' [varargslist] ')'
+       varargslist: (fpdef ['=' test] ',')* ('*' NAME [',' '**' NAME]
+            | '**' NAME) | fpdef ['=' test] (',' fpdef ['=' test])* [',']
+    */
+    int i, j, k, n_args = 0, n_defaults = 0, found_default = 0;
+    asdl_seq *args, *defaults;
+    identifier vararg = NULL, kwarg = NULL;
+    node *ch;
+
+    if (TYPE(n) == parameters) {
+	if (NCH(n) == 2) /* () as argument list */
+	    return arguments(NULL, NULL, NULL, NULL, c->c_arena);
+	n = CHILD(n, 1);
+    }
+    REQ(n, varargslist);
+
+    /* first count the number of normal args & defaults */
+    for (i = 0; i < NCH(n); i++) {
+	ch = CHILD(n, i);
+	if (TYPE(ch) == fpdef)
+	    n_args++;
+	if (TYPE(ch) == EQUAL)
+	    n_defaults++;
+    }
+    args = (n_args ? asdl_seq_new(n_args, c->c_arena) : NULL);
+    if (!args && n_args)
+    	return NULL; /* Don't need to goto error; no objects allocated */
+    defaults = (n_defaults ? asdl_seq_new(n_defaults, c->c_arena) : NULL);
+    if (!defaults && n_defaults)
+    	return NULL; /* Don't need to goto error; no objects allocated */
+
+    /* fpdef: NAME | '(' fplist ')'
+       fplist: fpdef (',' fpdef)* [',']
+    */
+    i = 0;
+    j = 0;  /* index for defaults */
+    k = 0;  /* index for args */
+    while (i < NCH(n)) {
+	ch = CHILD(n, i);
+	switch (TYPE(ch)) {
+            case fpdef:
+            handle_fpdef:
+                /* XXX Need to worry about checking if TYPE(CHILD(n, i+1)) is
+                   anything other than EQUAL or a comma? */
+                /* XXX Should NCH(n) check be made a separate check? */
+                if (i + 1 < NCH(n) && TYPE(CHILD(n, i + 1)) == EQUAL) {
+                    expr_ty expression = ast_for_expr(c, CHILD(n, i + 2));
+                    if (!expression)
+                            goto error;
+                    assert(defaults != NULL);
+                    asdl_seq_SET(defaults, j++, expression);
+                    i += 2;
+		    found_default = 1;
+                }
+		else if (found_default) {
+		    ast_error(n, 
+			     "non-default argument follows default argument");
+		    goto error;
+		}
+                if (NCH(ch) == 3) {
+		    ch = CHILD(ch, 1);
+		    /* def foo((x)): is not complex, special case. */
+		    if (NCH(ch) != 1) {
+			/* We have complex arguments, setup for unpacking. */
+			asdl_seq_SET(args, k++, compiler_complex_args(c, ch));
+		    } else {
+			/* def foo((x)): setup for checking NAME below. */
+			/* Loop because there can be many parens and tuple
+			   upacking mixed in. */
+			ch = CHILD(ch, 0);
+			assert(TYPE(ch) == fpdef);
+			goto handle_fpdef;
+		    }
+                }
+                if (TYPE(CHILD(ch, 0)) == NAME) {
+		    expr_ty name;
+		    if (!strcmp(STR(CHILD(ch, 0)), "None")) {
+			    ast_error(CHILD(ch, 0), "assignment to None");
+			    goto error;
+		    }
+                    name = Name(NEW_IDENTIFIER(CHILD(ch, 0)),
+                                Param, LINENO(ch), ch->n_col_offset,
+                                c->c_arena);
+                    if (!name)
+                        goto error;
+                    asdl_seq_SET(args, k++, name);
+					 
+		}
+                i += 2; /* the name and the comma */
+                break;
+            case STAR:
+		if (!strcmp(STR(CHILD(n, i+1)), "None")) {
+			ast_error(CHILD(n, i+1), "assignment to None");
+			goto error;
+		}
+                vararg = NEW_IDENTIFIER(CHILD(n, i+1));
+                i += 3;
+                break;
+            case DOUBLESTAR:
+		if (!strcmp(STR(CHILD(n, i+1)), "None")) {
+			ast_error(CHILD(n, i+1), "assignment to None");
+			goto error;
+		}
+                kwarg = NEW_IDENTIFIER(CHILD(n, i+1));
+                i += 3;
+                break;
+            default:
+                PyErr_Format(PyExc_SystemError,
+                             "unexpected node in varargslist: %d @ %d",
+                             TYPE(ch), i);
+                goto error;
+	}
+    }
+
+    return arguments(args, vararg, kwarg, defaults, c->c_arena);
+
+ error:
+    Py_XDECREF(vararg);
+    Py_XDECREF(kwarg);
+    return NULL;
+}
+
+static expr_ty
+ast_for_dotted_name(struct compiling *c, const node *n)
+{
+    expr_ty e;
+    identifier id;
+    int lineno, col_offset;
+    int i;
+
+    REQ(n, dotted_name);
+
+    lineno = LINENO(n);
+    col_offset = n->n_col_offset;
+
+    id = NEW_IDENTIFIER(CHILD(n, 0));
+    if (!id)
+        return NULL;
+    e = Name(id, Load, lineno, col_offset, c->c_arena);
+    if (!e)
+	return NULL;
+
+    for (i = 2; i < NCH(n); i+=2) {
+        id = NEW_IDENTIFIER(CHILD(n, i));
+	if (!id)
+	    return NULL;
+	e = Attribute(e, id, Load, lineno, col_offset, c->c_arena);
+	if (!e)
+	    return NULL;
+    }
+
+    return e;
+}
+
+static expr_ty
+ast_for_decorator(struct compiling *c, const node *n)
+{
+    /* decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE */
+    expr_ty d = NULL;
+    expr_ty name_expr;
+    
+    REQ(n, decorator);
+    REQ(CHILD(n, 0), AT);
+    REQ(RCHILD(n, -1), NEWLINE);
+    
+    name_expr = ast_for_dotted_name(c, CHILD(n, 1));
+    if (!name_expr)
+	return NULL;
+	
+    if (NCH(n) == 3) { /* No arguments */
+	d = name_expr;
+	name_expr = NULL;
+    }
+    else if (NCH(n) == 5) { /* Call with no arguments */
+	d = Call(name_expr, NULL, NULL, NULL, NULL, LINENO(n),
+                 n->n_col_offset, c->c_arena);
+	if (!d)
+	    return NULL;
+	name_expr = NULL;
+    }
+    else {
+	d = ast_for_call(c, CHILD(n, 3), name_expr);
+	if (!d)
+	    return NULL;
+	name_expr = NULL;
+    }
+
+    return d;
+}
+
+static asdl_seq*
+ast_for_decorators(struct compiling *c, const node *n)
+{
+    asdl_seq* decorator_seq;
+    expr_ty d;
+    int i;
+    
+    REQ(n, decorators);
+    decorator_seq = asdl_seq_new(NCH(n), c->c_arena);
+    if (!decorator_seq)
+        return NULL;
+	
+    for (i = 0; i < NCH(n); i++) {
+        d = ast_for_decorator(c, CHILD(n, i));
+	    if (!d)
+	        return NULL;
+	    asdl_seq_SET(decorator_seq, i, d);
+    }
+    return decorator_seq;
+}
+
+static stmt_ty
+ast_for_funcdef(struct compiling *c, const node *n)
+{
+    /* funcdef: 'def' [decorators] NAME parameters ':' suite */
+    identifier name;
+    arguments_ty args;
+    asdl_seq *body;
+    asdl_seq *decorator_seq = NULL;
+    int name_i;
+
+    REQ(n, funcdef);
+
+    if (NCH(n) == 6) { /* decorators are present */
+	decorator_seq = ast_for_decorators(c, CHILD(n, 0));
+	if (!decorator_seq)
+	    return NULL;
+	name_i = 2;
+    }
+    else {
+	name_i = 1;
+    }
+
+    name = NEW_IDENTIFIER(CHILD(n, name_i));
+    if (!name)
+	return NULL;
+    else if (!strcmp(STR(CHILD(n, name_i)), "None")) {
+	ast_error(CHILD(n, name_i), "assignment to None");
+	return NULL;
+    }
+    args = ast_for_arguments(c, CHILD(n, name_i + 1));
+    if (!args)
+	return NULL;
+    body = ast_for_suite(c, CHILD(n, name_i + 3));
+    if (!body)
+	return NULL;
+
+    return FunctionDef(name, args, body, decorator_seq, LINENO(n),
+                       n->n_col_offset, c->c_arena);
+}
+
+static expr_ty
+ast_for_lambdef(struct compiling *c, const node *n)
+{
+    /* lambdef: 'lambda' [varargslist] ':' test */
+    arguments_ty args;
+    expr_ty expression;
+
+    if (NCH(n) == 3) {
+        args = arguments(NULL, NULL, NULL, NULL, c->c_arena);
+        if (!args)
+            return NULL;
+        expression = ast_for_expr(c, CHILD(n, 2));
+        if (!expression)
+            return NULL;
+    }
+    else {
+        args = ast_for_arguments(c, CHILD(n, 1));
+        if (!args)
+            return NULL;
+        expression = ast_for_expr(c, CHILD(n, 3));
+        if (!expression)
+            return NULL;
+    }
+
+    return Lambda(args, expression, LINENO(n), n->n_col_offset, c->c_arena);
+}
+
+static expr_ty
+ast_for_ifexpr(struct compiling *c, const node *n)
+{
+    /* test: or_test 'if' or_test 'else' test */ 
+    expr_ty expression, body, orelse;
+
+    assert(NCH(n) == 5);
+    body = ast_for_expr(c, CHILD(n, 0));
+    if (!body)
+    	return NULL;
+    expression = ast_for_expr(c, CHILD(n, 2));
+    if (!expression)
+    	return NULL;
+    orelse = ast_for_expr(c, CHILD(n, 4));
+    if (!orelse)
+	return NULL;
+    return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
+                 c->c_arena);
+}
+
+/* Count the number of 'for' loop in a list comprehension.
+
+   Helper for ast_for_listcomp().
+*/
+
+static int
+count_list_fors(const node *n)
+{
+    int n_fors = 0;
+    node *ch = CHILD(n, 1);
+
+ count_list_for:
+    n_fors++;
+    REQ(ch, list_for);
+    if (NCH(ch) == 5)
+	ch = CHILD(ch, 4);
+    else
+	return n_fors;
+ count_list_iter:
+    REQ(ch, list_iter);
+    ch = CHILD(ch, 0);
+    if (TYPE(ch) == list_for)
+	goto count_list_for;
+    else if (TYPE(ch) == list_if) {
+        if (NCH(ch) == 3) {
+            ch = CHILD(ch, 2);
+            goto count_list_iter;
+        }
+        else
+            return n_fors;
+    }
+
+    /* Should never be reached */
+    PyErr_SetString(PyExc_SystemError, "logic error in count_list_fors");
+    return -1;
+}
+
+/* Count the number of 'if' statements in a list comprehension.
+
+   Helper for ast_for_listcomp().
+*/
+
+static int
+count_list_ifs(const node *n)
+{
+    int n_ifs = 0;
+
+ count_list_iter:
+    REQ(n, list_iter);
+    if (TYPE(CHILD(n, 0)) == list_for)
+	return n_ifs;
+    n = CHILD(n, 0);
+    REQ(n, list_if);
+    n_ifs++;
+    if (NCH(n) == 2)
+	return n_ifs;
+    n = CHILD(n, 2);
+    goto count_list_iter;
+}
+
+static expr_ty
+ast_for_listcomp(struct compiling *c, const node *n)
+{
+    /* listmaker: test ( list_for | (',' test)* [','] )
+       list_for: 'for' exprlist 'in' testlist_safe [list_iter]
+       list_iter: list_for | list_if
+       list_if: 'if' test [list_iter]
+       testlist_safe: test [(',' test)+ [',']]
+    */
+    expr_ty elt;
+    asdl_seq *listcomps;
+    int i, n_fors;
+    node *ch;
+
+    REQ(n, listmaker);
+    assert(NCH(n) > 1);
+
+    elt = ast_for_expr(c, CHILD(n, 0));
+    if (!elt)
+        return NULL;
+
+    n_fors = count_list_fors(n);
+    if (n_fors == -1)
+        return NULL;
+
+    listcomps = asdl_seq_new(n_fors, c->c_arena);
+    if (!listcomps)
+    	return NULL;
+
+    ch = CHILD(n, 1);
+    for (i = 0; i < n_fors; i++) {
+	comprehension_ty lc;
+	asdl_seq *t;
+        expr_ty expression;
+        node *for_ch;
+
+	REQ(ch, list_for);
+
+        for_ch = CHILD(ch, 1);
+        t = ast_for_exprlist(c, for_ch, Store);
+        if (!t)
+            return NULL;
+        expression = ast_for_testlist(c, CHILD(ch, 3));
+        if (!expression)
+            return NULL;
+
+        /* Check the # of children rather than the length of t, since
+           [x for x, in ... ] has 1 element in t, but still requires a Tuple. */
+	if (NCH(for_ch) == 1)
+	    lc = comprehension((expr_ty)asdl_seq_GET(t, 0), expression, NULL,
+                               c->c_arena);
+	else
+	    lc = comprehension(Tuple(t, Store, LINENO(ch), ch->n_col_offset,
+                                     c->c_arena),
+                               expression, NULL, c->c_arena);
+        if (!lc)
+            return NULL;
+
+	if (NCH(ch) == 5) {
+	    int j, n_ifs;
+	    asdl_seq *ifs;
+	    expr_ty list_for_expr;
+
+	    ch = CHILD(ch, 4);
+	    n_ifs = count_list_ifs(ch);
+            if (n_ifs == -1)
+                return NULL;
+
+	    ifs = asdl_seq_new(n_ifs, c->c_arena);
+	    if (!ifs)
+		return NULL;
+
+	    for (j = 0; j < n_ifs; j++) {
+            REQ(ch, list_iter);
+		    ch = CHILD(ch, 0);
+		    REQ(ch, list_if);
+            
+		    list_for_expr = ast_for_expr(c, CHILD(ch, 1));
+		    if (!list_for_expr)
+		        return NULL;
+
+    		asdl_seq_SET(ifs, j, list_for_expr);
+    		if (NCH(ch) == 3)
+	    	    ch = CHILD(ch, 2);
+	        }
+	        /* on exit, must guarantee that ch is a list_for */
+	        if (TYPE(ch) == list_iter)
+		        ch = CHILD(ch, 0);
+            lc->ifs = ifs;
+	    }
+	    asdl_seq_SET(listcomps, i, lc);
+    }
+
+    return ListComp(elt, listcomps, LINENO(n), n->n_col_offset, c->c_arena);
+}
+
+/*
+   Count the number of 'for' loops in a generator expression.
+
+   Helper for ast_for_genexp().
+*/
+
+static int
+count_gen_fors(const node *n)
+{
+	int n_fors = 0;
+	node *ch = CHILD(n, 1);
+
+ count_gen_for:
+	n_fors++;
+	REQ(ch, gen_for);
+	if (NCH(ch) == 5)
+		ch = CHILD(ch, 4);
+	else
+		return n_fors;
+ count_gen_iter:
+	REQ(ch, gen_iter);
+	ch = CHILD(ch, 0);
+	if (TYPE(ch) == gen_for)
+		goto count_gen_for;
+	else if (TYPE(ch) == gen_if) {
+		if (NCH(ch) == 3) {
+			ch = CHILD(ch, 2);
+			goto count_gen_iter;
+		}
+		else
+		    return n_fors;
+	}
+
+	/* Should never be reached */
+	PyErr_SetString(PyExc_SystemError,
+			"logic error in count_gen_fors");
+	return -1;
+}
+
+/* Count the number of 'if' statements in a generator expression.
+
+   Helper for ast_for_genexp().
+*/
+
+static int
+count_gen_ifs(const node *n)
+{
+	int n_ifs = 0;
+
+	while (1) {
+		REQ(n, gen_iter);
+		if (TYPE(CHILD(n, 0)) == gen_for)
+			return n_ifs;
+		n = CHILD(n, 0);
+		REQ(n, gen_if);
+		n_ifs++;
+		if (NCH(n) == 2)
+			return n_ifs;
+		n = CHILD(n, 2);
+	}
+}
+
+/* TODO(jhylton): Combine with list comprehension code? */
+static expr_ty
+ast_for_genexp(struct compiling *c, const node *n)
+{
+    /* testlist_gexp: test ( gen_for | (',' test)* [','] )
+       argument: [test '='] test [gen_for]	 # Really [keyword '='] test */
+    expr_ty elt;
+    asdl_seq *genexps;
+    int i, n_fors;
+    node *ch;
+    
+    assert(TYPE(n) == (testlist_gexp) || TYPE(n) == (argument));
+    assert(NCH(n) > 1);
+    
+    elt = ast_for_expr(c, CHILD(n, 0));
+    if (!elt)
+        return NULL;
+    
+    n_fors = count_gen_fors(n);
+    if (n_fors == -1)
+        return NULL;
+
+    genexps = asdl_seq_new(n_fors, c->c_arena);
+    if (!genexps)
+        return NULL;
+
+    ch = CHILD(n, 1);
+    for (i = 0; i < n_fors; i++) {
+        comprehension_ty ge;
+        asdl_seq *t;
+        expr_ty expression;
+        node *for_ch;
+        
+        REQ(ch, gen_for);
+        
+        for_ch = CHILD(ch, 1);
+        t = ast_for_exprlist(c, for_ch, Store);
+        if (!t)
+            return NULL;
+        expression = ast_for_expr(c, CHILD(ch, 3));
+        if (!expression)
+            return NULL;
+
+        /* Check the # of children rather than the length of t, since
+           (x for x, in ...) has 1 element in t, but still requires a Tuple. */
+        if (NCH(for_ch) == 1)
+            ge = comprehension((expr_ty)asdl_seq_GET(t, 0), expression,
+                               NULL, c->c_arena);
+        else
+            ge = comprehension(Tuple(t, Store, LINENO(ch), ch->n_col_offset,
+                                     c->c_arena),
+                               expression, NULL, c->c_arena);
+
+        if (!ge)
+            return NULL;
+
+        if (NCH(ch) == 5) {
+            int j, n_ifs;
+            asdl_seq *ifs;
+            
+            ch = CHILD(ch, 4);
+            n_ifs = count_gen_ifs(ch);
+            if (n_ifs == -1)
+                return NULL;
+
+            ifs = asdl_seq_new(n_ifs, c->c_arena);
+            if (!ifs)
+                return NULL;
+
+            for (j = 0; j < n_ifs; j++) {
+                REQ(ch, gen_iter);
+                ch = CHILD(ch, 0);
+                REQ(ch, gen_if);
+                
+                expression = ast_for_expr(c, CHILD(ch, 1));
+                if (!expression)
+                    return NULL;
+                asdl_seq_SET(ifs, j, expression);
+                if (NCH(ch) == 3)
+                    ch = CHILD(ch, 2);
+            }
+            /* on exit, must guarantee that ch is a gen_for */
+            if (TYPE(ch) == gen_iter)
+                ch = CHILD(ch, 0);
+            ge->ifs = ifs;
+        }
+        asdl_seq_SET(genexps, i, ge);
+    }
+    
+    return GeneratorExp(elt, genexps, LINENO(n), n->n_col_offset, c->c_arena);
+}
+
+static expr_ty
+ast_for_atom(struct compiling *c, const node *n)
+{
+    /* atom: '(' [yield_expr|testlist_gexp] ')' | '[' [listmaker] ']'
+       | '{' [dictmaker] '}' | '`' testlist '`' | NAME | NUMBER | STRING+
+    */
+    node *ch = CHILD(n, 0);
+    
+    switch (TYPE(ch)) {
+    case NAME:
+	/* All names start in Load context, but may later be
+	   changed. */
+	return Name(NEW_IDENTIFIER(ch), Load, LINENO(n), n->n_col_offset, c->c_arena);
+    case STRING: {
+	PyObject *str = parsestrplus(c, n);
+	if (!str)
+	    return NULL;
+
+	PyArena_AddPyObject(c->c_arena, str);
+	return Str(str, LINENO(n), n->n_col_offset, c->c_arena);
+    }
+    case NUMBER: {
+	PyObject *pynum = parsenumber(STR(ch));
+	if (!pynum)
+	    return NULL;
+
+	PyArena_AddPyObject(c->c_arena, pynum);
+	return Num(pynum, LINENO(n), n->n_col_offset, c->c_arena);
+    }
+    case LPAR: /* some parenthesized expressions */
+	ch = CHILD(n, 1);
+	
+	if (TYPE(ch) == RPAR)
+	    return Tuple(NULL, Load, LINENO(n), n->n_col_offset, c->c_arena);
+	
+	if (TYPE(ch) == yield_expr)
+	    return ast_for_expr(c, ch);
+	
+	if ((NCH(ch) > 1) && (TYPE(CHILD(ch, 1)) == gen_for))
+	    return ast_for_genexp(c, ch);
+	
+	return ast_for_testlist_gexp(c, ch);
+    case LSQB: /* list (or list comprehension) */
+	ch = CHILD(n, 1);
+	
+	if (TYPE(ch) == RSQB)
+	    return List(NULL, Load, LINENO(n), n->n_col_offset, c->c_arena);
+	
+	REQ(ch, listmaker);
+	if (NCH(ch) == 1 || TYPE(CHILD(ch, 1)) == COMMA) {
+	    asdl_seq *elts = seq_for_testlist(c, ch);
+	    if (!elts)
+		return NULL;
+
+	    return List(elts, Load, LINENO(n), n->n_col_offset, c->c_arena);
+	}
+	else
+	    return ast_for_listcomp(c, ch);
+    case LBRACE: {
+	/* dictmaker: test ':' test (',' test ':' test)* [','] */
+	int i, size;
+	asdl_seq *keys, *values;
+	
+	ch = CHILD(n, 1);
+	size = (NCH(ch) + 1) / 4; /* +1 in case no trailing comma */
+	keys = asdl_seq_new(size, c->c_arena);
+	if (!keys)
+	    return NULL;
+	
+	values = asdl_seq_new(size, c->c_arena);
+	if (!values)
+	    return NULL;
+	
+	for (i = 0; i < NCH(ch); i += 4) {
+	    expr_ty expression;
+	    
+	    expression = ast_for_expr(c, CHILD(ch, i));
+	    if (!expression)
+		return NULL;
+
+	    asdl_seq_SET(keys, i / 4, expression);
+
+	    expression = ast_for_expr(c, CHILD(ch, i + 2));
+	    if (!expression)
+		return NULL;
+
+	    asdl_seq_SET(values, i / 4, expression);
+	}
+	return Dict(keys, values, LINENO(n), n->n_col_offset, c->c_arena);
+    }
+    case BACKQUOTE: { /* repr */
+	expr_ty expression = ast_for_testlist(c, CHILD(n, 1));
+	if (!expression)
+	    return NULL;
+
+	return Repr(expression, LINENO(n), n->n_col_offset, c->c_arena);
+    }
+    default:
+	PyErr_Format(PyExc_SystemError, "unhandled atom %d", TYPE(ch));
+	return NULL;
+    }
+}
+
+static slice_ty
+ast_for_slice(struct compiling *c, const node *n)
+{
+    node *ch;
+    expr_ty lower = NULL, upper = NULL, step = NULL;
+
+    REQ(n, subscript);
+
+    /*
+       subscript: '.' '.' '.' | test | [test] ':' [test] [sliceop]
+       sliceop: ':' [test]
+    */
+    ch = CHILD(n, 0);
+    if (TYPE(ch) == DOT)
+	return Ellipsis(c->c_arena);
+
+    if (NCH(n) == 1 && TYPE(ch) == test) {
+        /* 'step' variable hold no significance in terms of being used over
+           other vars */
+        step = ast_for_expr(c, ch); 
+        if (!step)
+            return NULL;
+            
+	return Index(step, c->c_arena);
+    }
+
+    if (TYPE(ch) == test) {
+	lower = ast_for_expr(c, ch);
+        if (!lower)
+            return NULL;
+    }
+
+    /* If there's an upper bound it's in the second or third position. */
+    if (TYPE(ch) == COLON) {
+	if (NCH(n) > 1) {
+	    node *n2 = CHILD(n, 1);
+
+	    if (TYPE(n2) == test) {
+		upper = ast_for_expr(c, n2);
+                if (!upper)
+                    return NULL;
+            }
+	}
+    } else if (NCH(n) > 2) {
+	node *n2 = CHILD(n, 2);
+
+	if (TYPE(n2) == test) {
+	    upper = ast_for_expr(c, n2);
+            if (!upper)
+                return NULL;
+        }
+    }
+
+    ch = CHILD(n, NCH(n) - 1);
+    if (TYPE(ch) == sliceop) {
+        if (NCH(ch) == 1) {
+            /* No expression, so step is None */
+            ch = CHILD(ch, 0);
+            step = Name(new_identifier("None", c->c_arena), Load,
+                        LINENO(ch), ch->n_col_offset, c->c_arena);
+            if (!step)
+                return NULL;
+        } else {
+            ch = CHILD(ch, 1);
+            if (TYPE(ch) == test) {
+                step = ast_for_expr(c, ch);
+                if (!step)
+                    return NULL;
+            }
+        }
+    }
+
+    return Slice(lower, upper, step, c->c_arena);
+}
+
+static expr_ty
+ast_for_binop(struct compiling *c, const node *n)
+{
+	/* Must account for a sequence of expressions.
+	   How should A op B op C by represented?  
+	   BinOp(BinOp(A, op, B), op, C).
+	*/
+
+	int i, nops;
+	expr_ty expr1, expr2, result;
+        operator_ty newoperator;
+
+        expr1 = ast_for_expr(c, CHILD(n, 0));
+        if (!expr1)
+            return NULL;
+
+        expr2 = ast_for_expr(c, CHILD(n, 2));
+        if (!expr2)
+            return NULL;
+
+        newoperator = get_operator(CHILD(n, 1));
+        if (!newoperator)
+            return NULL;
+
+	result = BinOp(expr1, newoperator, expr2, LINENO(n), n->n_col_offset,
+                       c->c_arena);
+	if (!result)
+            return NULL;
+
+	nops = (NCH(n) - 1) / 2;
+	for (i = 1; i < nops; i++) {
+		expr_ty tmp_result, tmp;
+		const node* next_oper = CHILD(n, i * 2 + 1);
+
+		newoperator = get_operator(next_oper);
+                if (!newoperator)
+                    return NULL;
+
+                tmp = ast_for_expr(c, CHILD(n, i * 2 + 2));
+                if (!tmp)
+                    return NULL;
+
+                tmp_result = BinOp(result, newoperator, tmp, 
+				   LINENO(next_oper), next_oper->n_col_offset,
+                                   c->c_arena);
+		if (!tmp) 
+			return NULL;
+		result = tmp_result;
+	}
+	return result;
+}
+
+static expr_ty
+ast_for_trailer(struct compiling *c, const node *n, expr_ty left_expr)
+{
+    /* trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME 
+       subscriptlist: subscript (',' subscript)* [',']
+       subscript: '.' '.' '.' | test | [test] ':' [test] [sliceop]
+     */
+    REQ(n, trailer);
+    if (TYPE(CHILD(n, 0)) == LPAR) {
+        if (NCH(n) == 2)
+            return Call(left_expr, NULL, NULL, NULL, NULL, LINENO(n),
+                        n->n_col_offset, c->c_arena);
+        else
+            return ast_for_call(c, CHILD(n, 1), left_expr);
+    }
+    else if (TYPE(CHILD(n, 0)) == DOT ) {
+        return Attribute(left_expr, NEW_IDENTIFIER(CHILD(n, 1)), Load,
+                         LINENO(n), n->n_col_offset, c->c_arena);
+    }
+    else {
+        REQ(CHILD(n, 0), LSQB);
+        REQ(CHILD(n, 2), RSQB);
+        n = CHILD(n, 1);
+        if (NCH(n) == 1) {
+            slice_ty slc = ast_for_slice(c, CHILD(n, 0));
+            if (!slc)
+                return NULL;
+            return Subscript(left_expr, slc, Load, LINENO(n), n->n_col_offset,
+                             c->c_arena);
+        }
+        else {
+            /* The grammar is ambiguous here. The ambiguity is resolved 
+               by treating the sequence as a tuple literal if there are
+               no slice features.
+            */
+            int j;
+            slice_ty slc;
+            expr_ty e;
+            bool simple = true;
+            asdl_seq *slices, *elts;
+            slices = asdl_seq_new((NCH(n) + 1) / 2, c->c_arena);
+            if (!slices)
+                return NULL;
+            for (j = 0; j < NCH(n); j += 2) {
+                slc = ast_for_slice(c, CHILD(n, j));
+                if (!slc)
+                    return NULL;
+                if (slc->kind != Index_kind)
+                    simple = false;
+                asdl_seq_SET(slices, j / 2, slc);
+            }
+            if (!simple) {
+                return Subscript(left_expr, ExtSlice(slices, c->c_arena),
+                                 Load, LINENO(n), n->n_col_offset, c->c_arena);
+            }
+            /* extract Index values and put them in a Tuple */
+            elts = asdl_seq_new(asdl_seq_LEN(slices), c->c_arena);
+            if (!elts)
+                return NULL;
+            for (j = 0; j < asdl_seq_LEN(slices); ++j) {
+                slc = (slice_ty)asdl_seq_GET(slices, j);
+                assert(slc->kind == Index_kind  && slc->v.Index.value);
+                asdl_seq_SET(elts, j, slc->v.Index.value);
+            }
+            e = Tuple(elts, Load, LINENO(n), n->n_col_offset, c->c_arena);
+            if (!e)
+                return NULL;
+            return Subscript(left_expr, Index(e, c->c_arena),
+                             Load, LINENO(n), n->n_col_offset, c->c_arena);
+        }
+    }
+}
+
+static expr_ty
+ast_for_factor(struct compiling *c, const node *n)
+{
+    node *pfactor, *ppower, *patom, *pnum;
+    expr_ty expression;
+
+    /* If the unary - operator is applied to a constant, don't generate
+       a UNARY_NEGATIVE opcode.  Just store the approriate value as a
+       constant.  The peephole optimizer already does something like
+       this but it doesn't handle the case where the constant is
+       (sys.maxint - 1).  In that case, we want a PyIntObject, not a
+       PyLongObject.
+    */
+    if (TYPE(CHILD(n, 0)) == MINUS
+        && NCH(n) == 2
+        && TYPE((pfactor = CHILD(n, 1))) == factor
+        && NCH(pfactor) == 1
+        && TYPE((ppower = CHILD(pfactor, 0))) == power
+        && NCH(ppower) == 1
+        && TYPE((patom = CHILD(ppower, 0))) == atom
+        && TYPE((pnum = CHILD(patom, 0))) == NUMBER) {
+        char *s = PyObject_MALLOC(strlen(STR(pnum)) + 2);
+        if (s == NULL)
+            return NULL;
+        s[0] = '-';
+        strcpy(s + 1, STR(pnum));
+        PyObject_FREE(STR(pnum));
+        STR(pnum) = s;
+        return ast_for_atom(c, patom);
+    }
+
+    expression = ast_for_expr(c, CHILD(n, 1));
+    if (!expression)
+        return NULL;
+
+    switch (TYPE(CHILD(n, 0))) {
+        case PLUS:
+            return UnaryOp(UAdd, expression, LINENO(n), n->n_col_offset,
+                           c->c_arena);
+        case MINUS:
+            return UnaryOp(USub, expression, LINENO(n), n->n_col_offset,
+                           c->c_arena);
+        case TILDE:
+            return UnaryOp(Invert, expression, LINENO(n),
+                           n->n_col_offset, c->c_arena);
+    }
+    PyErr_Format(PyExc_SystemError, "unhandled factor: %d",
+                 TYPE(CHILD(n, 0)));
+    return NULL;
+}
+
+static expr_ty
+ast_for_power(struct compiling *c, const node *n)
+{
+    /* power: atom trailer* ('**' factor)*
+     */
+    int i;
+    expr_ty e, tmp;
+    REQ(n, power);
+    e = ast_for_atom(c, CHILD(n, 0));
+    if (!e)
+        return NULL;
+    if (NCH(n) == 1)
+        return e;
+    for (i = 1; i < NCH(n); i++) {
+        node *ch = CHILD(n, i);
+        if (TYPE(ch) != trailer)
+            break;
+        tmp = ast_for_trailer(c, ch, e);
+        if (!tmp)
+            return NULL;
+	tmp->lineno = e->lineno;
+	tmp->col_offset = e->col_offset;
+        e = tmp;
+    }
+    if (TYPE(CHILD(n, NCH(n) - 1)) == factor) {
+        expr_ty f = ast_for_expr(c, CHILD(n, NCH(n) - 1));
+        if (!f)
+            return NULL;
+        tmp = BinOp(e, Pow, f, LINENO(n), n->n_col_offset, c->c_arena);
+        if (!tmp)
+            return NULL;
+        e = tmp;
+    }
+    return e;
+}
+
+/* Do not name a variable 'expr'!  Will cause a compile error.
+*/
+
+static expr_ty
+ast_for_expr(struct compiling *c, const node *n)
+{
+    /* handle the full range of simple expressions
+       test: or_test ['if' or_test 'else' test] | lambdef
+       or_test: and_test ('or' and_test)* 
+       and_test: not_test ('and' not_test)*
+       not_test: 'not' not_test | comparison
+       comparison: expr (comp_op expr)*
+       expr: xor_expr ('|' xor_expr)*
+       xor_expr: and_expr ('^' and_expr)*
+       and_expr: shift_expr ('&' shift_expr)*
+       shift_expr: arith_expr (('<<'|'>>') arith_expr)*
+       arith_expr: term (('+'|'-') term)*
+       term: factor (('*'|'/'|'%'|'//') factor)*
+       factor: ('+'|'-'|'~') factor | power
+       power: atom trailer* ('**' factor)*
+
+       As well as modified versions that exist for backward compatibility,
+       to explicitly allow:
+       [ x for x in lambda: 0, lambda: 1 ]
+       (which would be ambiguous without these extra rules)
+       
+       old_test: or_test | old_lambdef
+       old_lambdef: 'lambda' [vararglist] ':' old_test
+
+    */
+
+    asdl_seq *seq;
+    int i;
+
+ loop:
+    switch (TYPE(n)) {
+        case test:
+        case old_test:
+            if (TYPE(CHILD(n, 0)) == lambdef ||
+                TYPE(CHILD(n, 0)) == old_lambdef)
+                return ast_for_lambdef(c, CHILD(n, 0));
+            else if (NCH(n) > 1)
+                return ast_for_ifexpr(c, n);
+	    /* Fallthrough */
+	case or_test:
+        case and_test:
+            if (NCH(n) == 1) {
+                n = CHILD(n, 0);
+                goto loop;
+            }
+            seq = asdl_seq_new((NCH(n) + 1) / 2, c->c_arena);
+            if (!seq)
+                return NULL;
+            for (i = 0; i < NCH(n); i += 2) {
+                expr_ty e = ast_for_expr(c, CHILD(n, i));
+                if (!e)
+                    return NULL;
+                asdl_seq_SET(seq, i / 2, e);
+            }
+            if (!strcmp(STR(CHILD(n, 1)), "and"))
+                return BoolOp(And, seq, LINENO(n), n->n_col_offset,
+                              c->c_arena);
+            assert(!strcmp(STR(CHILD(n, 1)), "or"));
+            return BoolOp(Or, seq, LINENO(n), n->n_col_offset, c->c_arena);
+        case not_test:
+            if (NCH(n) == 1) {
+                n = CHILD(n, 0);
+                goto loop;
+            }
+            else {
+                expr_ty expression = ast_for_expr(c, CHILD(n, 1));
+                if (!expression)
+                    return NULL;
+
+                return UnaryOp(Not, expression, LINENO(n), n->n_col_offset,
+                               c->c_arena);
+            }
+        case comparison:
+            if (NCH(n) == 1) {
+                n = CHILD(n, 0);
+                goto loop;
+            }
+            else {
+                expr_ty expression;
+                asdl_int_seq *ops;
+		asdl_seq *cmps;
+                ops = asdl_int_seq_new(NCH(n) / 2, c->c_arena);
+                if (!ops)
+                    return NULL;
+                cmps = asdl_seq_new(NCH(n) / 2, c->c_arena);
+                if (!cmps) {
+                    return NULL;
+                }
+                for (i = 1; i < NCH(n); i += 2) {
+                    cmpop_ty newoperator;
+
+                    newoperator = ast_for_comp_op(CHILD(n, i));
+                    if (!newoperator) {
+                        return NULL;
+		    }
+
+                    expression = ast_for_expr(c, CHILD(n, i + 1));
+                    if (!expression) {
+                        return NULL;
+		    }
+                        
+                    asdl_seq_SET(ops, i / 2, newoperator);
+                    asdl_seq_SET(cmps, i / 2, expression);
+                }
+                expression = ast_for_expr(c, CHILD(n, 0));
+                if (!expression) {
+                    return NULL;
+		}
+                    
+                return Compare(expression, ops, cmps, LINENO(n),
+                               n->n_col_offset, c->c_arena);
+            }
+            break;
+
+        /* The next five cases all handle BinOps.  The main body of code
+           is the same in each case, but the switch turned inside out to
+           reuse the code for each type of operator.
+         */
+        case expr:
+        case xor_expr:
+        case and_expr:
+        case shift_expr:
+        case arith_expr:
+        case term:
+            if (NCH(n) == 1) {
+                n = CHILD(n, 0);
+                goto loop;
+            }
+            return ast_for_binop(c, n);
+        case yield_expr: {
+	    expr_ty exp = NULL;
+	    if (NCH(n) == 2) {
+		exp = ast_for_testlist(c, CHILD(n, 1));
+		if (!exp)
+		    return NULL;
+	    }
+	    return Yield(exp, LINENO(n), n->n_col_offset, c->c_arena);
+	}
+        case factor:
+            if (NCH(n) == 1) {
+                n = CHILD(n, 0);
+                goto loop;
+            }
+	    return ast_for_factor(c, n);
+        case power:
+            return ast_for_power(c, n);
+        default:
+            PyErr_Format(PyExc_SystemError, "unhandled expr: %d", TYPE(n));
+            return NULL;
+    }
+    /* should never get here unless if error is set */
+    return NULL;
+}
+
+static expr_ty
+ast_for_call(struct compiling *c, const node *n, expr_ty func)
+{
+    /*
+      arglist: (argument ',')* (argument [',']| '*' test [',' '**' test]
+               | '**' test)
+      argument: [test '='] test [gen_for]	 # Really [keyword '='] test
+    */
+
+    int i, nargs, nkeywords, ngens;
+    asdl_seq *args;
+    asdl_seq *keywords;
+    expr_ty vararg = NULL, kwarg = NULL;
+
+    REQ(n, arglist);
+
+    nargs = 0;
+    nkeywords = 0;
+    ngens = 0;
+    for (i = 0; i < NCH(n); i++) {
+	node *ch = CHILD(n, i);
+	if (TYPE(ch) == argument) {
+	    if (NCH(ch) == 1)
+		nargs++;
+	    else if (TYPE(CHILD(ch, 1)) == gen_for)
+		ngens++;
+            else
+		nkeywords++;
+	}
+    }
+    if (ngens > 1 || (ngens && (nargs || nkeywords))) {
+        ast_error(n, "Generator expression must be parenthesized "
+		  "if not sole argument");
+	return NULL;
+    }
+
+    if (nargs + nkeywords + ngens > 255) {
+      ast_error(n, "more than 255 arguments");
+      return NULL;
+    }
+
+    args = asdl_seq_new(nargs + ngens, c->c_arena);
+    if (!args)
+        return NULL;
+    keywords = asdl_seq_new(nkeywords, c->c_arena);
+    if (!keywords)
+        return NULL;
+    nargs = 0;
+    nkeywords = 0;
+    for (i = 0; i < NCH(n); i++) {
+	node *ch = CHILD(n, i);
+	if (TYPE(ch) == argument) {
+	    expr_ty e;
+	    if (NCH(ch) == 1) {
+		if (nkeywords) {
+		    ast_error(CHILD(ch, 0),
+			      "non-keyword arg after keyword arg");
+		    return NULL;
+		}
+		e = ast_for_expr(c, CHILD(ch, 0));
+                if (!e)
+                    return NULL;
+		asdl_seq_SET(args, nargs++, e);
+	    }  
+	    else if (TYPE(CHILD(ch, 1)) == gen_for) {
+        	e = ast_for_genexp(c, ch);
+                if (!e)
+                    return NULL;
+		asdl_seq_SET(args, nargs++, e);
+            }
+	    else {
+		keyword_ty kw;
+		identifier key;
+
+		/* CHILD(ch, 0) is test, but must be an identifier? */ 
+		e = ast_for_expr(c, CHILD(ch, 0));
+                if (!e)
+                    return NULL;
+                /* f(lambda x: x[0] = 3) ends up getting parsed with
+                 * LHS test = lambda x: x[0], and RHS test = 3.
+                 * SF bug 132313 points out that complaining about a keyword
+                 * then is very confusing.
+                 */
+                if (e->kind == Lambda_kind) {
+                  ast_error(CHILD(ch, 0), "lambda cannot contain assignment");
+                  return NULL;
+                } else if (e->kind != Name_kind) {
+                  ast_error(CHILD(ch, 0), "keyword can't be an expression");
+                  return NULL;
+                }
+		key = e->v.Name.id;
+		e = ast_for_expr(c, CHILD(ch, 2));
+                if (!e)
+                    return NULL;
+		kw = keyword(key, e, c->c_arena);
+                if (!kw)
+                    return NULL;
+		asdl_seq_SET(keywords, nkeywords++, kw);
+	    }
+	}
+	else if (TYPE(ch) == STAR) {
+	    vararg = ast_for_expr(c, CHILD(n, i+1));
+	    i++;
+	}
+	else if (TYPE(ch) == DOUBLESTAR) {
+	    kwarg = ast_for_expr(c, CHILD(n, i+1));
+	    i++;
+	}
+    }
+
+    return Call(func, args, keywords, vararg, kwarg, func->lineno, func->col_offset, c->c_arena);
+}
+
+static expr_ty
+ast_for_testlist(struct compiling *c, const node* n)
+{
+    /* testlist_gexp: test (',' test)* [','] */
+    /* testlist: test (',' test)* [','] */
+    /* testlist_safe: test (',' test)+ [','] */
+    /* testlist1: test (',' test)* */
+    assert(NCH(n) > 0);
+    if (TYPE(n) == testlist_gexp) {
+        if (NCH(n) > 1)
+            assert(TYPE(CHILD(n, 1)) != gen_for);
+    }
+    else {
+        assert(TYPE(n) == testlist ||
+               TYPE(n) == testlist_safe ||
+               TYPE(n) == testlist1);
+    }
+    if (NCH(n) == 1)
+	return ast_for_expr(c, CHILD(n, 0));
+    else {
+        asdl_seq *tmp = seq_for_testlist(c, n);
+        if (!tmp)
+            return NULL;
+	return Tuple(tmp, Load, LINENO(n), n->n_col_offset, c->c_arena);
+    }
+}
+
+static expr_ty
+ast_for_testlist_gexp(struct compiling *c, const node* n)
+{
+    /* testlist_gexp: test ( gen_for | (',' test)* [','] ) */
+    /* argument: test [ gen_for ] */
+    assert(TYPE(n) == testlist_gexp || TYPE(n) == argument);
+    if (NCH(n) > 1 && TYPE(CHILD(n, 1)) == gen_for)
+	return ast_for_genexp(c, n);
+    return ast_for_testlist(c, n);
+}
+
+/* like ast_for_testlist() but returns a sequence */
+static asdl_seq*
+ast_for_class_bases(struct compiling *c, const node* n)
+{
+    /* testlist: test (',' test)* [','] */
+    assert(NCH(n) > 0);
+    REQ(n, testlist);
+    if (NCH(n) == 1) {
+        expr_ty base;
+        asdl_seq *bases = asdl_seq_new(1, c->c_arena);
+        if (!bases)
+            return NULL;
+        base = ast_for_expr(c, CHILD(n, 0));
+        if (!base)
+            return NULL;
+        asdl_seq_SET(bases, 0, base);
+        return bases;
+    }
+
+    return seq_for_testlist(c, n);
+}
+
+static stmt_ty
+ast_for_expr_stmt(struct compiling *c, const node *n)
+{
+    REQ(n, expr_stmt);
+    /* expr_stmt: testlist (augassign (yield_expr|testlist) 
+                | ('=' (yield_expr|testlist))*)
+       testlist: test (',' test)* [',']
+       augassign: '+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^='
+	        | '<<=' | '>>=' | '**=' | '//='
+       test: ... here starts the operator precendence dance
+     */
+
+    if (NCH(n) == 1) {
+	expr_ty e = ast_for_testlist(c, CHILD(n, 0));
+        if (!e)
+            return NULL;
+
+	return Expr(e, LINENO(n), n->n_col_offset, c->c_arena);
+    }
+    else if (TYPE(CHILD(n, 1)) == augassign) {
+        expr_ty expr1, expr2;
+        operator_ty newoperator;
+	node *ch = CHILD(n, 0);
+
+	expr1 = ast_for_testlist(c, ch);
+        if (!expr1)
+            return NULL;
+        /* TODO(nas): Remove duplicated error checks (set_context does it) */
+        switch (expr1->kind) {
+            case GeneratorExp_kind:
+                ast_error(ch, "augmented assignment to generator "
+                          "expression not possible");
+                return NULL;
+            case Yield_kind:
+                ast_error(ch, "augmented assignment to yield "
+                          "expression not possible");
+                return NULL;
+            case Name_kind: {
+                const char *var_name = PyString_AS_STRING(expr1->v.Name.id);
+                if (var_name[0] == 'N' && !strcmp(var_name, "None")) {
+                    ast_error(ch, "assignment to None");
+                    return NULL;
+                }
+                break;
+            }
+            case Attribute_kind:
+            case Subscript_kind:
+                break;
+            default:
+                ast_error(ch, "illegal expression for augmented "
+                          "assignment");
+                return NULL;
+        }
+	if (!set_context(expr1, Store, ch))
+		return NULL;
+
+	ch = CHILD(n, 2);
+	if (TYPE(ch) == testlist)
+	    expr2 = ast_for_testlist(c, ch);
+	else
+	    expr2 = ast_for_expr(c, ch);
+        if (!expr2)
+            return NULL;
+
+        newoperator = ast_for_augassign(CHILD(n, 1));
+        if (!newoperator)
+            return NULL;
+
+	return AugAssign(expr1, newoperator, expr2, LINENO(n), n->n_col_offset, c->c_arena);
+    }
+    else {
+	int i;
+	asdl_seq *targets;
+	node *value;
+        expr_ty expression;
+
+	/* a normal assignment */
+	REQ(CHILD(n, 1), EQUAL);
+	targets = asdl_seq_new(NCH(n) / 2, c->c_arena);
+	if (!targets)
+	    return NULL;
+	for (i = 0; i < NCH(n) - 2; i += 2) {
+	    expr_ty e;
+	    node *ch = CHILD(n, i);
+	    if (TYPE(ch) == yield_expr) {
+		ast_error(ch, "assignment to yield expression not possible");
+		return NULL;
+	    }
+	    e = ast_for_testlist(c, ch);
+
+	    /* set context to assign */
+	    if (!e) 
+	      return NULL;
+
+	    if (!set_context(e, Store, CHILD(n, i)))
+	      return NULL;
+
+	    asdl_seq_SET(targets, i / 2, e);
+	}
+	value = CHILD(n, NCH(n) - 1);
+	if (TYPE(value) == testlist)
+	    expression = ast_for_testlist(c, value);
+	else
+	    expression = ast_for_expr(c, value);
+	if (!expression)
+	    return NULL;
+	return Assign(targets, expression, LINENO(n), n->n_col_offset, c->c_arena);
+    }
+}
+
+static stmt_ty
+ast_for_print_stmt(struct compiling *c, const node *n)
+{
+    /* print_stmt: 'print' ( [ test (',' test)* [','] ]
+                             | '>>' test [ (',' test)+ [','] ] )
+     */
+    expr_ty dest = NULL, expression;
+    asdl_seq *seq;
+    bool nl;
+    int i, j, start = 1;
+
+    REQ(n, print_stmt);
+    if (NCH(n) >= 2 && TYPE(CHILD(n, 1)) == RIGHTSHIFT) {
+	dest = ast_for_expr(c, CHILD(n, 2));
+        if (!dest)
+            return NULL;
+	    start = 4;
+    }
+    seq = asdl_seq_new((NCH(n) + 1 - start) / 2, c->c_arena);
+    if (!seq)
+    	return NULL;
+    for (i = start, j = 0; i < NCH(n); i += 2, ++j) {
+        expression = ast_for_expr(c, CHILD(n, i));
+        if (!expression)
+            return NULL;
+    	asdl_seq_SET(seq, j, expression);
+    }
+    nl = (TYPE(CHILD(n, NCH(n) - 1)) == COMMA) ? false : true;
+    return Print(dest, seq, nl, LINENO(n), n->n_col_offset, c->c_arena);
+}
+
+static asdl_seq *
+ast_for_exprlist(struct compiling *c, const node *n, expr_context_ty context)
+{
+    asdl_seq *seq;
+    int i;
+    expr_ty e;
+
+    REQ(n, exprlist);
+
+    seq = asdl_seq_new((NCH(n) + 1) / 2, c->c_arena);
+    if (!seq)
+	return NULL;
+    for (i = 0; i < NCH(n); i += 2) {
+	e = ast_for_expr(c, CHILD(n, i));
+	if (!e)
+	    return NULL;
+	asdl_seq_SET(seq, i / 2, e);
+	if (context && !set_context(e, context, CHILD(n, i)))
+	    return NULL;
+    }
+    return seq;
+}
+
+static stmt_ty
+ast_for_del_stmt(struct compiling *c, const node *n)
+{
+    asdl_seq *expr_list;
+    
+    /* del_stmt: 'del' exprlist */
+    REQ(n, del_stmt);
+
+    expr_list = ast_for_exprlist(c, CHILD(n, 1), Del);
+    if (!expr_list)
+        return NULL;
+    return Delete(expr_list, LINENO(n), n->n_col_offset, c->c_arena);
+}
+
+static stmt_ty
+ast_for_flow_stmt(struct compiling *c, const node *n)
+{
+    /*
+      flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt
+                 | yield_stmt
+      break_stmt: 'break'
+      continue_stmt: 'continue'
+      return_stmt: 'return' [testlist]
+      yield_stmt: yield_expr
+      yield_expr: 'yield' testlist
+      raise_stmt: 'raise' [test [',' test [',' test]]]
+    */
+    node *ch;
+
+    REQ(n, flow_stmt);
+    ch = CHILD(n, 0);
+    switch (TYPE(ch)) {
+        case break_stmt:
+            return Break(LINENO(n), n->n_col_offset, c->c_arena);
+        case continue_stmt:
+            return Continue(LINENO(n), n->n_col_offset, c->c_arena);
+        case yield_stmt: { /* will reduce to yield_expr */
+	    expr_ty exp = ast_for_expr(c, CHILD(ch, 0));
+	    if (!exp)
+		return NULL;
+            return Expr(exp, LINENO(n), n->n_col_offset, c->c_arena);
+        }
+        case return_stmt:
+            if (NCH(ch) == 1)
+                return Return(NULL, LINENO(n), n->n_col_offset, c->c_arena);
+            else {
+                expr_ty expression = ast_for_testlist(c, CHILD(ch, 1));
+                if (!expression)
+                    return NULL;
+                return Return(expression, LINENO(n), n->n_col_offset, c->c_arena);
+            }
+        case raise_stmt:
+            if (NCH(ch) == 1)
+                return Raise(NULL, NULL, NULL, LINENO(n), n->n_col_offset, c->c_arena);
+            else if (NCH(ch) == 2) {
+                expr_ty expression = ast_for_expr(c, CHILD(ch, 1));
+                if (!expression)
+                    return NULL;
+                return Raise(expression, NULL, NULL, LINENO(n), n->n_col_offset, c->c_arena);
+            }
+            else if (NCH(ch) == 4) {
+                expr_ty expr1, expr2;
+
+                expr1 = ast_for_expr(c, CHILD(ch, 1));
+                if (!expr1)
+                    return NULL;
+                expr2 = ast_for_expr(c, CHILD(ch, 3));
+                if (!expr2)
+                    return NULL;
+
+                return Raise(expr1, expr2, NULL, LINENO(n), n->n_col_offset, c->c_arena);
+            }
+            else if (NCH(ch) == 6) {
+                expr_ty expr1, expr2, expr3;
+
+                expr1 = ast_for_expr(c, CHILD(ch, 1));
+                if (!expr1)
+                    return NULL;
+                expr2 = ast_for_expr(c, CHILD(ch, 3));
+                if (!expr2)
+                    return NULL;
+                expr3 = ast_for_expr(c, CHILD(ch, 5));
+                if (!expr3)
+                    return NULL;
+                    
+                return Raise(expr1, expr2, expr3, LINENO(n), n->n_col_offset, c->c_arena);
+            }
+        default:
+            PyErr_Format(PyExc_SystemError,
+                         "unexpected flow_stmt: %d", TYPE(ch));
+            return NULL;
+    }
+
+    PyErr_SetString(PyExc_SystemError, "unhandled flow statement");
+    return NULL;
+}
+
+static alias_ty
+alias_for_import_name(struct compiling *c, const node *n)
+{
+    /*
+      import_as_name: NAME ['as' NAME]
+      dotted_as_name: dotted_name ['as' NAME]
+      dotted_name: NAME ('.' NAME)*
+    */
+    PyObject *str;
+
+ loop:
+    switch (TYPE(n)) {
+        case import_as_name:
+            str = NULL;
+            if (NCH(n) == 3) {
+                if (strcmp(STR(CHILD(n, 1)), "as") != 0) {
+                    ast_error(n, "must use 'as' in import");
+                    return NULL;
+                }
+                str = NEW_IDENTIFIER(CHILD(n, 2));
+            }
+            return alias(NEW_IDENTIFIER(CHILD(n, 0)), str, c->c_arena);
+        case dotted_as_name:
+            if (NCH(n) == 1) {
+                n = CHILD(n, 0);
+                goto loop;
+            }
+            else {
+                alias_ty a = alias_for_import_name(c, CHILD(n, 0));
+                if (!a)
+                    return NULL;
+                if (strcmp(STR(CHILD(n, 1)), "as") != 0) {
+                    ast_error(n, "must use 'as' in import");
+                    return NULL;
+                }
+                assert(!a->asname);
+                a->asname = NEW_IDENTIFIER(CHILD(n, 2));
+                return a;
+            }
+            break;
+        case dotted_name:
+            if (NCH(n) == 1)
+                return alias(NEW_IDENTIFIER(CHILD(n, 0)), NULL, c->c_arena);
+            else {
+                /* Create a string of the form "a.b.c" */
+                int i;
+                size_t len;
+                char *s;
+
+                len = 0;
+                for (i = 0; i < NCH(n); i += 2)
+                    /* length of string plus one for the dot */
+                    len += strlen(STR(CHILD(n, i))) + 1;
+                len--; /* the last name doesn't have a dot */
+                str = PyString_FromStringAndSize(NULL, len);
+                if (!str)
+                    return NULL;
+                s = PyString_AS_STRING(str);
+                if (!s)
+                    return NULL;
+                for (i = 0; i < NCH(n); i += 2) {
+                    char *sch = STR(CHILD(n, i));
+                    strcpy(s, STR(CHILD(n, i)));
+                    s += strlen(sch);
+                    *s++ = '.';
+                }
+                --s;
+                *s = '\0';
+                PyString_InternInPlace(&str);
+		PyArena_AddPyObject(c->c_arena, str);
+                return alias(str, NULL, c->c_arena);
+            }
+            break;
+        case STAR:
+	    str = PyString_InternFromString("*");
+	    PyArena_AddPyObject(c->c_arena, str);
+            return alias(str, NULL, c->c_arena);
+        default:
+            PyErr_Format(PyExc_SystemError,
+                         "unexpected import name: %d", TYPE(n));
+            return NULL;
+    }
+
+    PyErr_SetString(PyExc_SystemError, "unhandled import name condition");
+    return NULL;
+}
+
+static stmt_ty
+ast_for_import_stmt(struct compiling *c, const node *n)
+{
+    /*
+      import_stmt: import_name | import_from
+      import_name: 'import' dotted_as_names
+      import_from: 'from' ('.'* dotted_name | '.') 'import'
+                          ('*' | '(' import_as_names ')' | import_as_names)
+    */
+    int lineno;
+    int col_offset;
+    int i;
+    asdl_seq *aliases;
+
+    REQ(n, import_stmt);
+    lineno = LINENO(n);
+    col_offset = n->n_col_offset;
+    n = CHILD(n, 0);
+    if (TYPE(n) == import_name) {
+        n = CHILD(n, 1);
+	REQ(n, dotted_as_names);
+	aliases = asdl_seq_new((NCH(n) + 1) / 2, c->c_arena);
+	if (!aliases)
+		return NULL;
+	for (i = 0; i < NCH(n); i += 2) {
+            alias_ty import_alias = alias_for_import_name(c, CHILD(n, i));
+            if (!import_alias)
+                return NULL;
+	    asdl_seq_SET(aliases, i / 2, import_alias);
+        }
+	return Import(aliases, lineno, col_offset, c->c_arena);
+    }
+    else if (TYPE(n) == import_from) {
+        int n_children;
+	int idx, ndots = 0;
+	alias_ty mod = NULL;
+	identifier modname;
+	
+       /* Count the number of dots (for relative imports) and check for the
+          optional module name */
+	for (idx = 1; idx < NCH(n); idx++) {
+	    if (TYPE(CHILD(n, idx)) == dotted_name) {
+	    	mod = alias_for_import_name(c, CHILD(n, idx));
+	    	idx++;
+	    	break;
+	    } else if (TYPE(CHILD(n, idx)) != DOT) {
+	        break;
+	    }
+	    ndots++;
+	}
+	idx++; /* skip over the 'import' keyword */
+        switch (TYPE(CHILD(n, idx))) {
+        case STAR:
+            /* from ... import * */
+	    n = CHILD(n, idx);
+	    n_children = 1;
+	    if (ndots) {
+	        ast_error(n, "'import *' not allowed with 'from .'");
+	        return NULL;
+	    }
+	    break;
+	case LPAR:
+	    /* from ... import (x, y, z) */
+	    n = CHILD(n, idx + 1);
+	    n_children = NCH(n);
+	    break;
+	case import_as_names:
+	    /* from ... import x, y, z */
+	    n = CHILD(n, idx);
+	    n_children = NCH(n);
+            if (n_children % 2 == 0) {
+                ast_error(n, "trailing comma not allowed without"
+                             " surrounding parentheses");
+                return NULL;
+            }
+	    break;
+	default:
+	    ast_error(n, "Unexpected node-type in from-import");
+	    return NULL;
+	}
+
+	aliases = asdl_seq_new((n_children + 1) / 2, c->c_arena);
+	if (!aliases)
+            return NULL;
+
+        /* handle "from ... import *" special b/c there's no children */
+        if (TYPE(n) == STAR) {
+            alias_ty import_alias = alias_for_import_name(c, n);
+            if (!import_alias)
+                return NULL;
+	        asdl_seq_SET(aliases, 0, import_alias);
+        }
+        else {
+    	    for (i = 0; i < NCH(n); i += 2) {
+                alias_ty import_alias = alias_for_import_name(c, CHILD(n, i));
+                if (!import_alias)
+                    return NULL;
+	            asdl_seq_SET(aliases, i / 2, import_alias);
+            }
+        }
+        if (mod != NULL)
+            modname = mod->name;
+        else
+            modname = new_identifier("", c->c_arena);
+        return ImportFrom(modname, aliases, ndots, lineno, col_offset,
+                          c->c_arena);
+    }
+    PyErr_Format(PyExc_SystemError,
+                 "unknown import statement: starts with command '%s'",
+                 STR(CHILD(n, 0)));
+    return NULL;
+}
+
+static stmt_ty
+ast_for_global_stmt(struct compiling *c, const node *n)
+{
+    /* global_stmt: 'global' NAME (',' NAME)* */
+    identifier name;
+    asdl_seq *s;
+    int i;
+
+    REQ(n, global_stmt);
+    s = asdl_seq_new(NCH(n) / 2, c->c_arena);
+    if (!s)
+    	return NULL;
+    for (i = 1; i < NCH(n); i += 2) {
+	name = NEW_IDENTIFIER(CHILD(n, i));
+	if (!name)
+	    return NULL;
+	asdl_seq_SET(s, i / 2, name);
+    }
+    return Global(s, LINENO(n), n->n_col_offset, c->c_arena);
+}
+
+static stmt_ty
+ast_for_exec_stmt(struct compiling *c, const node *n)
+{
+    expr_ty expr1, globals = NULL, locals = NULL;
+    int n_children = NCH(n);
+    if (n_children != 2 && n_children != 4 && n_children != 6) {
+        PyErr_Format(PyExc_SystemError,
+                     "poorly formed 'exec' statement: %d parts to statement",
+                     n_children);
+        return NULL;
+    }
+
+    /* exec_stmt: 'exec' expr ['in' test [',' test]] */
+    REQ(n, exec_stmt);
+    expr1 = ast_for_expr(c, CHILD(n, 1));
+    if (!expr1)
+        return NULL;
+    if (n_children >= 4) {
+        globals = ast_for_expr(c, CHILD(n, 3));
+        if (!globals)
+            return NULL;
+    }
+    if (n_children == 6) {
+        locals = ast_for_expr(c, CHILD(n, 5));
+        if (!locals)
+            return NULL;
+    }
+
+    return Exec(expr1, globals, locals, LINENO(n), n->n_col_offset, c->c_arena);
+}
+
+static stmt_ty
+ast_for_assert_stmt(struct compiling *c, const node *n)
+{
+    /* assert_stmt: 'assert' test [',' test] */
+    REQ(n, assert_stmt);
+    if (NCH(n) == 2) {
+        expr_ty expression = ast_for_expr(c, CHILD(n, 1));
+        if (!expression)
+            return NULL;
+	return Assert(expression, NULL, LINENO(n), n->n_col_offset, c->c_arena);
+    }
+    else if (NCH(n) == 4) {
+        expr_ty expr1, expr2;
+
+        expr1 = ast_for_expr(c, CHILD(n, 1));
+        if (!expr1)
+            return NULL;
+        expr2 = ast_for_expr(c, CHILD(n, 3));
+        if (!expr2)
+            return NULL;
+            
+	return Assert(expr1, expr2, LINENO(n), n->n_col_offset, c->c_arena);
+    }
+    PyErr_Format(PyExc_SystemError,
+                 "improper number of parts to 'assert' statement: %d",
+                 NCH(n));
+    return NULL;
+}
+
+static asdl_seq *
+ast_for_suite(struct compiling *c, const node *n)
+{
+    /* suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT */
+    asdl_seq *seq;
+    stmt_ty s;
+    int i, total, num, end, pos = 0;
+    node *ch;
+
+    REQ(n, suite);
+
+    total = num_stmts(n);
+    seq = asdl_seq_new(total, c->c_arena);
+    if (!seq)
+    	return NULL;
+    if (TYPE(CHILD(n, 0)) == simple_stmt) {
+	n = CHILD(n, 0);
+	/* simple_stmt always ends with a NEWLINE,
+	   and may have a trailing SEMI 
+	*/
+	end = NCH(n) - 1;
+	if (TYPE(CHILD(n, end - 1)) == SEMI)
+	    end--;
+        /* loop by 2 to skip semi-colons */
+	for (i = 0; i < end; i += 2) {
+	    ch = CHILD(n, i);
+	    s = ast_for_stmt(c, ch);
+	    if (!s)
+		return NULL;
+	    asdl_seq_SET(seq, pos++, s);
+	}
+    }
+    else {
+	for (i = 2; i < (NCH(n) - 1); i++) {
+	    ch = CHILD(n, i);
+	    REQ(ch, stmt);
+	    num = num_stmts(ch);
+	    if (num == 1) {
+		/* small_stmt or compound_stmt with only one child */
+		s = ast_for_stmt(c, ch);
+		if (!s)
+		    return NULL;
+		asdl_seq_SET(seq, pos++, s);
+	    }
+	    else {
+		int j;
+		ch = CHILD(ch, 0);
+		REQ(ch, simple_stmt);
+		for (j = 0; j < NCH(ch); j += 2) {
+		    /* statement terminates with a semi-colon ';' */
+		    if (NCH(CHILD(ch, j)) == 0) {
+			assert((j + 1) == NCH(ch));
+			break;
+		    }
+		    s = ast_for_stmt(c, CHILD(ch, j));
+		    if (!s)
+			return NULL;
+		    asdl_seq_SET(seq, pos++, s);
+		}
+	    }
+	}
+    }
+    assert(pos == seq->size);
+    return seq;
+}
+
+static stmt_ty
+ast_for_if_stmt(struct compiling *c, const node *n)
+{
+    /* if_stmt: 'if' test ':' suite ('elif' test ':' suite)*
+       ['else' ':' suite]
+    */
+    char *s;
+
+    REQ(n, if_stmt);
+
+    if (NCH(n) == 4) {
+        expr_ty expression;
+        asdl_seq *suite_seq;
+
+        expression = ast_for_expr(c, CHILD(n, 1));
+        if (!expression)
+            return NULL;
+        suite_seq = ast_for_suite(c, CHILD(n, 3)); 
+        if (!suite_seq)
+            return NULL;
+            
+	return If(expression, suite_seq, NULL, LINENO(n), n->n_col_offset, c->c_arena);
+    }
+
+    s = STR(CHILD(n, 4));
+    /* s[2], the third character in the string, will be
+       's' for el_s_e, or
+       'i' for el_i_f
+    */
+    if (s[2] == 's') {
+        expr_ty expression;
+        asdl_seq *seq1, *seq2;
+
+        expression = ast_for_expr(c, CHILD(n, 1));
+        if (!expression)
+            return NULL;
+        seq1 = ast_for_suite(c, CHILD(n, 3));
+        if (!seq1)
+            return NULL;
+        seq2 = ast_for_suite(c, CHILD(n, 6));
+        if (!seq2)
+            return NULL;
+
+	return If(expression, seq1, seq2, LINENO(n), n->n_col_offset, c->c_arena);
+    }
+    else if (s[2] == 'i') {
+	int i, n_elif, has_else = 0;
+	expr_ty expression;
+	asdl_seq *suite_seq;
+	asdl_seq *orelse = NULL;
+	n_elif = NCH(n) - 4;
+        /* must reference the child n_elif+1 since 'else' token is third,
+           not fourth, child from the end. */
+	if (TYPE(CHILD(n, (n_elif + 1))) == NAME
+	    && STR(CHILD(n, (n_elif + 1)))[2] == 's') {
+	    has_else = 1;
+	    n_elif -= 3;
+	}
+	n_elif /= 4;
+
+	if (has_else) {
+            asdl_seq *suite_seq2;
+
+	    orelse = asdl_seq_new(1, c->c_arena);
+	    if (!orelse)
+		return NULL;
+            expression = ast_for_expr(c, CHILD(n, NCH(n) - 6));
+            if (!expression)
+                return NULL;
+            suite_seq = ast_for_suite(c, CHILD(n, NCH(n) - 4));
+            if (!suite_seq)
+                return NULL;
+            suite_seq2 = ast_for_suite(c, CHILD(n, NCH(n) - 1));
+            if (!suite_seq2)
+                return NULL;
+
+	    asdl_seq_SET(orelse, 0, If(expression, suite_seq, suite_seq2, 
+				       LINENO(CHILD(n, NCH(n) - 6)), CHILD(n, NCH(n) - 6)->n_col_offset,
+                                       c->c_arena));
+	    /* the just-created orelse handled the last elif */
+	    n_elif--;
+	}
+
+	for (i = 0; i < n_elif; i++) {
+	    int off = 5 + (n_elif - i - 1) * 4;
+	    asdl_seq *newobj = asdl_seq_new(1, c->c_arena);
+	    if (!newobj)
+		return NULL;
+            expression = ast_for_expr(c, CHILD(n, off));
+            if (!expression)
+                return NULL;
+            suite_seq = ast_for_suite(c, CHILD(n, off + 2));
+            if (!suite_seq)
+                return NULL;
+
+	    asdl_seq_SET(newobj, 0,
+			 If(expression, suite_seq, orelse, 
+			    LINENO(CHILD(n, off)), CHILD(n, off)->n_col_offset, c->c_arena));
+	    orelse = newobj;
+	}
+	expression = ast_for_expr(c, CHILD(n, 1));
+	if (!expression)
+		return NULL;
+	suite_seq = ast_for_suite(c, CHILD(n, 3));
+	if (!suite_seq)
+		return NULL;
+	return If(expression, suite_seq, orelse,
+			  LINENO(n), n->n_col_offset, c->c_arena);
+    }
+
+    PyErr_Format(PyExc_SystemError,
+                 "unexpected token in 'if' statement: %s", s);
+    return NULL;
+}
+
+static stmt_ty
+ast_for_while_stmt(struct compiling *c, const node *n)
+{
+    /* while_stmt: 'while' test ':' suite ['else' ':' suite] */
+    REQ(n, while_stmt);
+
+    if (NCH(n) == 4) {
+        expr_ty expression;
+        asdl_seq *suite_seq;
+
+        expression = ast_for_expr(c, CHILD(n, 1));
+        if (!expression)
+            return NULL;
+        suite_seq = ast_for_suite(c, CHILD(n, 3));
+        if (!suite_seq)
+            return NULL;
+	return While(expression, suite_seq, NULL, LINENO(n), n->n_col_offset, c->c_arena);
+    }
+    else if (NCH(n) == 7) {
+        expr_ty expression;
+        asdl_seq *seq1, *seq2;
+
+        expression = ast_for_expr(c, CHILD(n, 1));
+        if (!expression)
+            return NULL;
+        seq1 = ast_for_suite(c, CHILD(n, 3));
+        if (!seq1)
+            return NULL;
+        seq2 = ast_for_suite(c, CHILD(n, 6));
+        if (!seq2)
+            return NULL;
+
+	return While(expression, seq1, seq2, LINENO(n), n->n_col_offset, c->c_arena);
+    }
+
+    PyErr_Format(PyExc_SystemError,
+                 "wrong number of tokens for 'while' statement: %d",
+                 NCH(n));
+    return NULL;
+}
+
+static stmt_ty
+ast_for_for_stmt(struct compiling *c, const node *n)
+{
+    asdl_seq *_target, *seq = NULL, *suite_seq;
+    expr_ty expression;
+    expr_ty target;
+    const node *node_target;
+    /* for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite] */
+    REQ(n, for_stmt);
+
+    if (NCH(n) == 9) {
+	seq = ast_for_suite(c, CHILD(n, 8));
+        if (!seq)
+            return NULL;
+    }
+
+    node_target = CHILD(n, 1);
+    _target = ast_for_exprlist(c, node_target, Store);
+    if (!_target)
+        return NULL;
+    /* Check the # of children rather than the length of _target, since
+       for x, in ... has 1 element in _target, but still requires a Tuple. */
+    if (NCH(node_target) == 1)
+	target = (expr_ty)asdl_seq_GET(_target, 0);
+    else
+	target = Tuple(_target, Store, LINENO(n), n->n_col_offset, c->c_arena);
+
+    expression = ast_for_testlist(c, CHILD(n, 3));
+    if (!expression)
+        return NULL;
+    suite_seq = ast_for_suite(c, CHILD(n, 5));
+    if (!suite_seq)
+        return NULL;
+
+    return For(target, expression, suite_seq, seq, LINENO(n), n->n_col_offset,
+               c->c_arena);
+}
+
+static excepthandler_ty
+ast_for_except_clause(struct compiling *c, const node *exc, node *body)
+{
+    /* except_clause: 'except' [test [',' test]] */
+    REQ(exc, except_clause);
+    REQ(body, suite);
+
+    if (NCH(exc) == 1) {
+        asdl_seq *suite_seq = ast_for_suite(c, body);
+        if (!suite_seq)
+            return NULL;
+
+	return excepthandler(NULL, NULL, suite_seq, LINENO(exc),
+                             exc->n_col_offset, c->c_arena);
+    }
+    else if (NCH(exc) == 2) {
+        expr_ty expression;
+        asdl_seq *suite_seq;
+
+        expression = ast_for_expr(c, CHILD(exc, 1));
+        if (!expression)
+            return NULL;
+        suite_seq = ast_for_suite(c, body);
+        if (!suite_seq)
+            return NULL;
+
+	return excepthandler(expression, NULL, suite_seq, LINENO(exc),
+                             exc->n_col_offset, c->c_arena);
+    }
+    else if (NCH(exc) == 4) {
+        asdl_seq *suite_seq;
+        expr_ty expression;
+	expr_ty e = ast_for_expr(c, CHILD(exc, 3));
+	if (!e)
+            return NULL;
+	if (!set_context(e, Store, CHILD(exc, 3)))
+            return NULL;
+        expression = ast_for_expr(c, CHILD(exc, 1));
+        if (!expression)
+            return NULL;
+        suite_seq = ast_for_suite(c, body);
+        if (!suite_seq)
+            return NULL;
+
+	return excepthandler(expression, e, suite_seq, LINENO(exc),
+                             exc->n_col_offset, c->c_arena);
+    }
+
+    PyErr_Format(PyExc_SystemError,
+                 "wrong number of children for 'except' clause: %d",
+                 NCH(exc));
+    return NULL;
+}
+
+static stmt_ty
+ast_for_try_stmt(struct compiling *c, const node *n)
+{
+    const int nch = NCH(n);
+    int n_except = (nch - 3)/3;
+    asdl_seq *body, *orelse = NULL, *finally = NULL;
+
+    REQ(n, try_stmt);
+
+    body = ast_for_suite(c, CHILD(n, 2));
+    if (body == NULL)
+        return NULL;
+
+    if (TYPE(CHILD(n, nch - 3)) == NAME) {
+        if (strcmp(STR(CHILD(n, nch - 3)), "finally") == 0) {
+            if (nch >= 9 && TYPE(CHILD(n, nch - 6)) == NAME) {
+                /* we can assume it's an "else",
+                   because nch >= 9 for try-else-finally and
+                   it would otherwise have a type of except_clause */
+                orelse = ast_for_suite(c, CHILD(n, nch - 4));
+                if (orelse == NULL)
+                    return NULL;
+                n_except--;
+            }
+
+            finally = ast_for_suite(c, CHILD(n, nch - 1));
+            if (finally == NULL)
+                return NULL;
+            n_except--;
+        }
+        else {
+            /* we can assume it's an "else",
+               otherwise it would have a type of except_clause */
+            orelse = ast_for_suite(c, CHILD(n, nch - 1));
+            if (orelse == NULL)
+                return NULL;
+            n_except--;
+        }
+    }
+    else if (TYPE(CHILD(n, nch - 3)) != except_clause) {
+        ast_error(n, "malformed 'try' statement");
+        return NULL;
+    }
+    
+    if (n_except > 0) {
+	int i;
+	stmt_ty except_st;
+        /* process except statements to create a try ... except */
+        asdl_seq *handlers = asdl_seq_new(n_except, c->c_arena);
+        if (handlers == NULL)
+            return NULL;
+
+        for (i = 0; i < n_except; i++) {
+            excepthandler_ty e = ast_for_except_clause(c, CHILD(n, 3 + i * 3),
+                                                       CHILD(n, 5 + i * 3));
+            if (!e)
+                return NULL;
+            asdl_seq_SET(handlers, i, e);
+        }
+
+	except_st = TryExcept(body, handlers, orelse, LINENO(n),
+                              n->n_col_offset, c->c_arena);
+        if (!finally)
+	    return except_st;
+
+        /* if a 'finally' is present too, we nest the TryExcept within a
+           TryFinally to emulate try ... except ... finally */
+	body = asdl_seq_new(1, c->c_arena);
+	if (body == NULL)
+	    return NULL;
+	asdl_seq_SET(body, 0, except_st);
+    }
+
+    /* must be a try ... finally (except clauses are in body, if any exist) */
+    assert(finally != NULL);
+    return TryFinally(body, finally, LINENO(n), n->n_col_offset, c->c_arena);
+}
+
+static expr_ty
+ast_for_with_var(struct compiling *c, const node *n)
+{
+    REQ(n, with_var);
+    if (strcmp(STR(CHILD(n, 0)), "as") != 0) {
+        ast_error(n, "expected \"with [expr] as [var]\"");
+        return NULL;
+    }
+    return ast_for_expr(c, CHILD(n, 1));
+}
+
+/* with_stmt: 'with' test [ with_var ] ':' suite */
+static stmt_ty
+ast_for_with_stmt(struct compiling *c, const node *n)
+{
+    expr_ty context_expr, optional_vars = NULL;
+    int suite_index = 3;    /* skip 'with', test, and ':' */
+    asdl_seq *suite_seq;
+
+    assert(TYPE(n) == with_stmt);
+    context_expr = ast_for_expr(c, CHILD(n, 1));
+    if (!context_expr)
+        return NULL;
+    if (TYPE(CHILD(n, 2)) == with_var) {
+        optional_vars = ast_for_with_var(c, CHILD(n, 2));
+
+        if (!optional_vars) {
+            return NULL;
+        }
+	if (!set_context(optional_vars, Store, n)) {
+	    return NULL;
+	}
+        suite_index = 4;
+    }
+
+    suite_seq = ast_for_suite(c, CHILD(n, suite_index));
+    if (!suite_seq) {
+        return NULL;
+    }
+    return With(context_expr, optional_vars, suite_seq, LINENO(n), 
+		n->n_col_offset, c->c_arena);
+}
+
+static stmt_ty
+ast_for_classdef(struct compiling *c, const node *n)
+{
+    /* classdef: 'class' NAME ['(' testlist ')'] ':' suite */
+    asdl_seq *bases, *s;
+    
+    REQ(n, classdef);
+
+    if (!strcmp(STR(CHILD(n, 1)), "None")) {
+	    ast_error(n, "assignment to None");
+	    return NULL;
+    }
+
+    if (NCH(n) == 4) {
+        s = ast_for_suite(c, CHILD(n, 3));
+        if (!s)
+            return NULL;
+	return ClassDef(NEW_IDENTIFIER(CHILD(n, 1)), NULL, s, LINENO(n),
+                        n->n_col_offset, c->c_arena);
+    }
+    /* check for empty base list */
+    if (TYPE(CHILD(n,3)) == RPAR) {
+	s = ast_for_suite(c, CHILD(n,5));
+	if (!s)
+		return NULL;
+	return ClassDef(NEW_IDENTIFIER(CHILD(n, 1)), NULL, s, LINENO(n),
+                        n->n_col_offset, c->c_arena);
+    }
+
+    /* else handle the base class list */
+    bases = ast_for_class_bases(c, CHILD(n, 3));
+    if (!bases)
+        return NULL;
+
+    s = ast_for_suite(c, CHILD(n, 6));
+    if (!s)
+        return NULL;
+    return ClassDef(NEW_IDENTIFIER(CHILD(n, 1)), bases, s, LINENO(n),
+                    n->n_col_offset, c->c_arena);
+}
+
+static stmt_ty
+ast_for_stmt(struct compiling *c, const node *n)
+{
+    if (TYPE(n) == stmt) {
+	assert(NCH(n) == 1);
+	n = CHILD(n, 0);
+    }
+    if (TYPE(n) == simple_stmt) {
+	assert(num_stmts(n) == 1);
+	n = CHILD(n, 0);
+    }
+    if (TYPE(n) == small_stmt) {
+	REQ(n, small_stmt);
+	n = CHILD(n, 0);
+	/* small_stmt: expr_stmt | print_stmt  | del_stmt | pass_stmt
+	             | flow_stmt | import_stmt | global_stmt | exec_stmt
+                     | assert_stmt
+	*/
+	switch (TYPE(n)) {
+            case expr_stmt:
+                return ast_for_expr_stmt(c, n);
+            case print_stmt:
+                return ast_for_print_stmt(c, n);
+            case del_stmt:
+                return ast_for_del_stmt(c, n);
+            case pass_stmt:
+                return Pass(LINENO(n), n->n_col_offset, c->c_arena);
+            case flow_stmt:
+                return ast_for_flow_stmt(c, n);
+            case import_stmt:
+                return ast_for_import_stmt(c, n);
+            case global_stmt:
+                return ast_for_global_stmt(c, n);
+            case exec_stmt:
+                return ast_for_exec_stmt(c, n);
+            case assert_stmt:
+                return ast_for_assert_stmt(c, n);
+            default:
+                PyErr_Format(PyExc_SystemError,
+                             "unhandled small_stmt: TYPE=%d NCH=%d\n",
+                             TYPE(n), NCH(n));
+                return NULL;
+        }
+    }
+    else {
+        /* compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt
+	                | funcdef | classdef
+	*/
+	node *ch = CHILD(n, 0);
+	REQ(n, compound_stmt);
+	switch (TYPE(ch)) {
+            case if_stmt:
+                return ast_for_if_stmt(c, ch);
+            case while_stmt:
+                return ast_for_while_stmt(c, ch);
+            case for_stmt:
+                return ast_for_for_stmt(c, ch);
+            case try_stmt:
+                return ast_for_try_stmt(c, ch);
+            case with_stmt:
+                return ast_for_with_stmt(c, ch);
+            case funcdef:
+                return ast_for_funcdef(c, ch);
+            case classdef:
+                return ast_for_classdef(c, ch);
+            default:
+                PyErr_Format(PyExc_SystemError,
+                             "unhandled small_stmt: TYPE=%d NCH=%d\n",
+                             TYPE(n), NCH(n));
+                return NULL;
+	}
+    }
+}
+
+static PyObject *
+parsenumber(const char *s)
+{
+	const char *end;
+	long x;
+	double dx;
+#ifndef WITHOUT_COMPLEX
+	Py_complex c;
+	int imflag;
+#endif
+
+	errno = 0;
+	end = s + strlen(s) - 1;
+#ifndef WITHOUT_COMPLEX
+	imflag = *end == 'j' || *end == 'J';
+#endif
+	if (*end == 'l' || *end == 'L')
+		return PyLong_FromString((char *)s, (char **)0, 0);
+	if (s[0] == '0') {
+		x = (long) PyOS_strtoul((char *)s, (char **)&end, 0);
+ 		if (x < 0 && errno == 0) {
+	 			return PyLong_FromString((char *)s,
+							 (char **)0,
+							 0);
+		}
+	}
+	else
+		x = PyOS_strtol((char *)s, (char **)&end, 0);
+	if (*end == '\0') {
+		if (errno != 0)
+			return PyLong_FromString((char *)s, (char **)0, 0);
+		return PyInt_FromLong(x);
+	}
+	/* XXX Huge floats may silently fail */
+#ifndef WITHOUT_COMPLEX
+	if (imflag) {
+		c.real = 0.;
+		PyFPE_START_PROTECT("atof", return 0)
+		c.imag = PyOS_ascii_atof(s);
+		PyFPE_END_PROTECT(c)
+		return PyComplex_FromCComplex(c);
+	}
+	else
+#endif
+	{
+		PyFPE_START_PROTECT("atof", return 0)
+		dx = PyOS_ascii_atof(s);
+		PyFPE_END_PROTECT(dx)
+		return PyFloat_FromDouble(dx);
+	}
+}
+
+static PyObject *
+decode_utf8(const char **sPtr, const char *end, char* encoding)
+{
+#ifndef Py_USING_UNICODE
+	Py_FatalError("decode_utf8 should not be called in this build.");
+        return NULL;
+#else
+	PyObject *u, *v;
+	char *s, *t;
+	t = s = (char *)*sPtr;
+	/* while (s < end && *s != '\\') s++; */ /* inefficient for u".." */
+	while (s < end && (*s & 0x80)) s++;
+	*sPtr = s;
+	u = PyUnicode_DecodeUTF8(t, s - t, NULL);
+	if (u == NULL)
+		return NULL;
+	v = PyUnicode_AsEncodedString(u, encoding, NULL);
+	Py_DECREF(u);
+	return v;
+#endif
+}
+
+static PyObject *
+decode_unicode(const char *s, size_t len, int rawmode, const char *encoding)
+{
+	PyObject *v, *u;
+	char *buf;
+	char *p;
+	const char *end;
+	if (encoding == NULL) {
+	     	buf = (char *)s;
+		u = NULL;
+	} else if (strcmp(encoding, "iso-8859-1") == 0) {
+	     	buf = (char *)s;
+		u = NULL;
+	} else {
+		/* "\XX" may become "\u005c\uHHLL" (12 bytes) */
+		u = PyString_FromStringAndSize((char *)NULL, len * 4);
+		if (u == NULL)
+			return NULL;
+		p = buf = PyString_AsString(u);
+		end = s + len;
+		while (s < end) {
+			if (*s == '\\') {
+				*p++ = *s++;
+				if (*s & 0x80) {
+					strcpy(p, "u005c");
+					p += 5;
+				}
+			}
+			if (*s & 0x80) { /* XXX inefficient */
+				PyObject *w;
+				char *r;
+				Py_ssize_t rn, i;
+				w = decode_utf8(&s, end, "utf-16-be");
+				if (w == NULL) {
+					Py_DECREF(u);
+					return NULL;
+				}
+				r = PyString_AsString(w);
+				rn = PyString_Size(w);
+				assert(rn % 2 == 0);
+				for (i = 0; i < rn; i += 2) {
+					sprintf(p, "\\u%02x%02x",
+						r[i + 0] & 0xFF,
+						r[i + 1] & 0xFF);
+					p += 6;
+				}
+				Py_DECREF(w);
+			} else {
+				*p++ = *s++;
+			}
+		}
+		len = p - buf;
+		s = buf;
+	}
+	if (rawmode)
+		v = PyUnicode_DecodeRawUnicodeEscape(s, len, NULL);
+	else
+		v = PyUnicode_DecodeUnicodeEscape(s, len, NULL);
+	Py_XDECREF(u);
+	return v;
+}
+
+/* s is a Python string literal, including the bracketing quote characters,
+ * and r &/or u prefixes (if any), and embedded escape sequences (if any).
+ * parsestr parses it, and returns the decoded Python string object.
+ */
+static PyObject *
+parsestr(const char *s, const char *encoding)
+{
+	size_t len;
+	int quote = Py_CHARMASK(*s);
+	int rawmode = 0;
+	int need_encoding;
+	int unicode = 0;
+
+	if (isalpha(quote) || quote == '_') {
+		if (quote == 'u' || quote == 'U') {
+			quote = *++s;
+			unicode = 1;
+		}
+		if (quote == 'r' || quote == 'R') {
+			quote = *++s;
+			rawmode = 1;
+		}
+	}
+	if (quote != '\'' && quote != '\"') {
+		PyErr_BadInternalCall();
+		return NULL;
+	}
+	s++;
+	len = strlen(s);
+	if (len > INT_MAX) {
+		PyErr_SetString(PyExc_OverflowError, 
+				"string to parse is too long");
+		return NULL;
+	}
+	if (s[--len] != quote) {
+		PyErr_BadInternalCall();
+		return NULL;
+	}
+	if (len >= 4 && s[0] == quote && s[1] == quote) {
+		s += 2;
+		len -= 2;
+		if (s[--len] != quote || s[--len] != quote) {
+			PyErr_BadInternalCall();
+			return NULL;
+		}
+	}
+#ifdef Py_USING_UNICODE
+	if (unicode || Py_UnicodeFlag) {
+		return decode_unicode(s, len, rawmode, encoding);
+	}
+#endif
+	need_encoding = (encoding != NULL &&
+			 strcmp(encoding, "utf-8") != 0 &&
+			 strcmp(encoding, "iso-8859-1") != 0);
+	if (rawmode || strchr(s, '\\') == NULL) {
+		if (need_encoding) {
+#ifndef Py_USING_UNICODE
+			/* This should not happen - we never see any other
+			   encoding. */
+			Py_FatalError(
+                            "cannot deal with encodings in this build.");
+#else
+			PyObject *v, *u = PyUnicode_DecodeUTF8(s, len, NULL);
+			if (u == NULL)
+				return NULL;
+			v = PyUnicode_AsEncodedString(u, encoding, NULL);
+			Py_DECREF(u);
+			return v;
+#endif
+		} else {
+			return PyString_FromStringAndSize(s, len);
+		}
+	}
+
+	return PyString_DecodeEscape(s, len, NULL, unicode,
+				     need_encoding ? encoding : NULL);
+}
+
+/* Build a Python string object out of a STRING atom.  This takes care of
+ * compile-time literal catenation, calling parsestr() on each piece, and
+ * pasting the intermediate results together.
+ */
+static PyObject *
+parsestrplus(struct compiling *c, const node *n)
+{
+	PyObject *v;
+	int i;
+	REQ(CHILD(n, 0), STRING);
+	if ((v = parsestr(STR(CHILD(n, 0)), c->c_encoding)) != NULL) {
+		/* String literal concatenation */
+		for (i = 1; i < NCH(n); i++) {
+			PyObject *s;
+			s = parsestr(STR(CHILD(n, i)), c->c_encoding);
+			if (s == NULL)
+				goto onError;
+			if (PyString_Check(v) && PyString_Check(s)) {
+				PyString_ConcatAndDel(&v, s);
+				if (v == NULL)
+				    goto onError;
+			}
+#ifdef Py_USING_UNICODE
+			else {
+				PyObject *temp = PyUnicode_Concat(v, s);
+				Py_DECREF(s);
+				Py_DECREF(v);
+				v = temp;
+				if (v == NULL)
+				    goto onError;
+			}
+#endif
+		}
+	}
+	return v;
+
+ onError:
+	Py_XDECREF(v);
+	return NULL;
+}

Added: vendor/Python/current/Python/atof.c
===================================================================
--- vendor/Python/current/Python/atof.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/atof.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,50 @@
+
+/* Just in case you haven't got an atof() around...
+   This one doesn't check for bad syntax or overflow,
+   and is slow and inaccurate.
+   But it's good enough for the occasional string literal... */
+
+#include "pyconfig.h"
+
+#include <ctype.h>
+
+double atof(char *s)
+{
+	double a = 0.0;
+	int e = 0;
+	int c;
+	while ((c = *s++) != '\0' && isdigit(c)) {
+		a = a*10.0 + (c - '0');
+	}
+	if (c == '.') {
+		while ((c = *s++) != '\0' && isdigit(c)) {
+			a = a*10.0 + (c - '0');
+			e = e-1;
+		}
+	}
+	if (c == 'e' || c == 'E') {
+		int sign = 1;
+		int i = 0;
+		c = *s++;
+		if (c == '+')
+			c = *s++;
+		else if (c == '-') {
+			c = *s++;
+			sign = -1;
+		}
+		while (isdigit(c)) {
+			i = i*10 + (c - '0');
+			c = *s++;
+		}
+		e += i*sign;
+	}
+	while (e > 0) {
+		a *= 10.0;
+		e--;
+	}
+	while (e < 0) {
+		a *= 0.1;
+		e++;
+	}
+	return a;
+}

Added: vendor/Python/current/Python/bltinmodule.c
===================================================================
--- vendor/Python/current/Python/bltinmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/bltinmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2620 @@
+/* Built-in functions */
+
+#include "Python.h"
+
+#include "node.h"
+#include "code.h"
+#include "eval.h"
+
+#include <ctype.h>
+
+#ifdef RISCOS
+#include "unixstuff.h"
+#endif
+
+/* The default encoding used by the platform file system APIs
+   Can remain NULL for all platforms that don't have such a concept
+*/
+#if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T)
+const char *Py_FileSystemDefaultEncoding = "mbcs";
+#elif defined(__APPLE__)
+const char *Py_FileSystemDefaultEncoding = "utf-8";
+#else
+const char *Py_FileSystemDefaultEncoding = NULL; /* use default */
+#endif
+
+/* Forward */
+static PyObject *filterstring(PyObject *, PyObject *);
+#ifdef Py_USING_UNICODE
+static PyObject *filterunicode(PyObject *, PyObject *);
+#endif
+static PyObject *filtertuple (PyObject *, PyObject *);
+
+static PyObject *
+builtin___import__(PyObject *self, PyObject *args, PyObject *kwds)
+{
+	static char *kwlist[] = {"name", "globals", "locals", "fromlist",
+				 "level", 0};
+	char *name;
+	PyObject *globals = NULL;
+	PyObject *locals = NULL;
+	PyObject *fromlist = NULL;
+	int level = -1;
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|OOOi:__import__",
+			kwlist, &name, &globals, &locals, &fromlist, &level))
+		return NULL;
+	return PyImport_ImportModuleLevel(name, globals, locals,
+					  fromlist, level);
+}
+
+PyDoc_STRVAR(import_doc,
+"__import__(name, globals={}, locals={}, fromlist=[], level=-1) -> module\n\
+\n\
+Import a module.  The globals are only used to determine the context;\n\
+they are not modified.  The locals are currently unused.  The fromlist\n\
+should be a list of names to emulate ``from name import ...'', or an\n\
+empty list to emulate ``import name''.\n\
+When importing a module from a package, note that __import__('A.B', ...)\n\
+returns package A when fromlist is empty, but its submodule B when\n\
+fromlist is not empty.  Level is used to determine whether to perform \n\
+absolute or relative imports.  -1 is the original strategy of attempting\n\
+both absolute and relative imports, 0 is absolute, a positive number\n\
+is the number of parent directories to search relative to the current module.");
+
+
+static PyObject *
+builtin_abs(PyObject *self, PyObject *v)
+{
+	return PyNumber_Absolute(v);
+}
+
+PyDoc_STRVAR(abs_doc,
+"abs(number) -> number\n\
+\n\
+Return the absolute value of the argument.");
+
+static PyObject *
+builtin_all(PyObject *self, PyObject *v)
+{
+	PyObject *it, *item;
+
+	it = PyObject_GetIter(v);
+	if (it == NULL)
+		return NULL;
+
+	while ((item = PyIter_Next(it)) != NULL) {
+		int cmp = PyObject_IsTrue(item);
+		Py_DECREF(item);
+		if (cmp < 0) {
+			Py_DECREF(it);
+			return NULL;
+		}
+		if (cmp == 0) {
+			Py_DECREF(it);
+			Py_RETURN_FALSE;
+		}
+	}
+	Py_DECREF(it);
+	if (PyErr_Occurred())
+		return NULL;
+	Py_RETURN_TRUE;
+}
+
+PyDoc_STRVAR(all_doc,
+"all(iterable) -> bool\n\
+\n\
+Return True if bool(x) is True for all values x in the iterable.");
+
+static PyObject *
+builtin_any(PyObject *self, PyObject *v)
+{
+	PyObject *it, *item;
+
+	it = PyObject_GetIter(v);
+	if (it == NULL)
+		return NULL;
+
+	while ((item = PyIter_Next(it)) != NULL) {
+		int cmp = PyObject_IsTrue(item);
+		Py_DECREF(item);
+		if (cmp < 0) {
+			Py_DECREF(it);
+			return NULL;
+		}
+		if (cmp == 1) {
+			Py_DECREF(it);
+			Py_RETURN_TRUE;
+		}
+	}
+	Py_DECREF(it);
+	if (PyErr_Occurred())
+		return NULL;
+	Py_RETURN_FALSE;
+}
+
+PyDoc_STRVAR(any_doc,
+"any(iterable) -> bool\n\
+\n\
+Return True if bool(x) is True for any x in the iterable.");
+
+static PyObject *
+builtin_apply(PyObject *self, PyObject *args)
+{
+	PyObject *func, *alist = NULL, *kwdict = NULL;
+	PyObject *t = NULL, *retval = NULL;
+
+	if (!PyArg_UnpackTuple(args, "apply", 1, 3, &func, &alist, &kwdict))
+		return NULL;
+	if (alist != NULL) {
+		if (!PyTuple_Check(alist)) {
+			if (!PySequence_Check(alist)) {
+				PyErr_Format(PyExc_TypeError,
+				     "apply() arg 2 expected sequence, found %s",
+					     alist->ob_type->tp_name);
+				return NULL;
+			}
+			t = PySequence_Tuple(alist);
+			if (t == NULL)
+				return NULL;
+			alist = t;
+		}
+	}
+	if (kwdict != NULL && !PyDict_Check(kwdict)) {
+		PyErr_Format(PyExc_TypeError,
+			     "apply() arg 3 expected dictionary, found %s",
+			     kwdict->ob_type->tp_name);
+		goto finally;
+	}
+	retval = PyEval_CallObjectWithKeywords(func, alist, kwdict);
+  finally:
+	Py_XDECREF(t);
+	return retval;
+}
+
+PyDoc_STRVAR(apply_doc,
+"apply(object[, args[, kwargs]]) -> value\n\
+\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.\n\
+\n\
+Deprecated since release 2.3. Instead, use the extended call syntax:\n\
+    function(*args, **keywords).");
+
+
+static PyObject *
+builtin_callable(PyObject *self, PyObject *v)
+{
+	return PyBool_FromLong((long)PyCallable_Check(v));
+}
+
+PyDoc_STRVAR(callable_doc,
+"callable(object) -> bool\n\
+\n\
+Return whether the object is callable (i.e., some kind of function).\n\
+Note that classes are callable, as are instances with a __call__() method.");
+
+
+static PyObject *
+builtin_filter(PyObject *self, PyObject *args)
+{
+	PyObject *func, *seq, *result, *it, *arg;
+	Py_ssize_t len;   /* guess for result list size */
+	register Py_ssize_t j;
+
+	if (!PyArg_UnpackTuple(args, "filter", 2, 2, &func, &seq))
+		return NULL;
+
+	/* Strings and tuples return a result of the same type. */
+	if (PyString_Check(seq))
+		return filterstring(func, seq);
+#ifdef Py_USING_UNICODE
+	if (PyUnicode_Check(seq))
+		return filterunicode(func, seq);
+#endif
+	if (PyTuple_Check(seq))
+		return filtertuple(func, seq);
+
+	/* Pre-allocate argument list tuple. */
+	arg = PyTuple_New(1);
+	if (arg == NULL)
+		return NULL;
+
+	/* Get iterator. */
+	it = PyObject_GetIter(seq);
+	if (it == NULL)
+		goto Fail_arg;
+
+	/* Guess a result list size. */
+	len = _PyObject_LengthHint(seq);
+	if (len < 0) {
+		if (!PyErr_ExceptionMatches(PyExc_TypeError)  &&
+		    !PyErr_ExceptionMatches(PyExc_AttributeError)) {
+			goto Fail_it;
+		}
+		PyErr_Clear();
+		len = 8;	/* arbitrary */
+	}
+
+	/* Get a result list. */
+	if (PyList_Check(seq) && seq->ob_refcnt == 1) {
+		/* Eww - can modify the list in-place. */
+		Py_INCREF(seq);
+		result = seq;
+	}
+	else {
+		result = PyList_New(len);
+		if (result == NULL)
+			goto Fail_it;
+	}
+
+	/* Build the result list. */
+	j = 0;
+	for (;;) {
+		PyObject *item;
+		int ok;
+
+		item = PyIter_Next(it);
+		if (item == NULL) {
+			if (PyErr_Occurred())
+				goto Fail_result_it;
+			break;
+		}
+
+		if (func == (PyObject *)&PyBool_Type || func == Py_None) {
+			ok = PyObject_IsTrue(item);
+		}
+		else {
+			PyObject *good;
+			PyTuple_SET_ITEM(arg, 0, item);
+			good = PyObject_Call(func, arg, NULL);
+			PyTuple_SET_ITEM(arg, 0, NULL);
+			if (good == NULL) {
+				Py_DECREF(item);
+				goto Fail_result_it;
+			}
+			ok = PyObject_IsTrue(good);
+			Py_DECREF(good);
+		}
+		if (ok) {
+			if (j < len)
+				PyList_SET_ITEM(result, j, item);
+			else {
+				int status = PyList_Append(result, item);
+				Py_DECREF(item);
+				if (status < 0)
+					goto Fail_result_it;
+			}
+			++j;
+		}
+		else
+			Py_DECREF(item);
+	}
+
+
+	/* Cut back result list if len is too big. */
+	if (j < len && PyList_SetSlice(result, j, len, NULL) < 0)
+		goto Fail_result_it;
+
+	Py_DECREF(it);
+	Py_DECREF(arg);
+	return result;
+
+Fail_result_it:
+	Py_DECREF(result);
+Fail_it:
+	Py_DECREF(it);
+Fail_arg:
+	Py_DECREF(arg);
+	return NULL;
+}
+
+PyDoc_STRVAR(filter_doc,
+"filter(function or None, sequence) -> list, tuple, or string\n"
+"\n"
+"Return those items of sequence for which function(item) is true.  If\n"
+"function is None, return the items that are true.  If sequence is a tuple\n"
+"or string, return the same type, else return a list.");
+
+static PyObject *
+builtin_chr(PyObject *self, PyObject *args)
+{
+	long x;
+	char s[1];
+
+	if (!PyArg_ParseTuple(args, "l:chr", &x))
+		return NULL;
+	if (x < 0 || x >= 256) {
+		PyErr_SetString(PyExc_ValueError,
+				"chr() arg not in range(256)");
+		return NULL;
+	}
+	s[0] = (char)x;
+	return PyString_FromStringAndSize(s, 1);
+}
+
+PyDoc_STRVAR(chr_doc,
+"chr(i) -> character\n\
+\n\
+Return a string of one character with ordinal i; 0 <= i < 256.");
+
+
+#ifdef Py_USING_UNICODE
+static PyObject *
+builtin_unichr(PyObject *self, PyObject *args)
+{
+	long x;
+
+	if (!PyArg_ParseTuple(args, "l:unichr", &x))
+		return NULL;
+
+	return PyUnicode_FromOrdinal(x);
+}
+
+PyDoc_STRVAR(unichr_doc,
+"unichr(i) -> Unicode character\n\
+\n\
+Return a Unicode string of one character with ordinal i; 0 <= i <= 0x10ffff.");
+#endif
+
+
+static PyObject *
+builtin_cmp(PyObject *self, PyObject *args)
+{
+	PyObject *a, *b;
+	int c;
+
+	if (!PyArg_UnpackTuple(args, "cmp", 2, 2, &a, &b))
+		return NULL;
+	if (PyObject_Cmp(a, b, &c) < 0)
+		return NULL;
+	return PyInt_FromLong((long)c);
+}
+
+PyDoc_STRVAR(cmp_doc,
+"cmp(x, y) -> integer\n\
+\n\
+Return negative if x<y, zero if x==y, positive if x>y.");
+
+
+static PyObject *
+builtin_coerce(PyObject *self, PyObject *args)
+{
+	PyObject *v, *w;
+	PyObject *res;
+
+	if (!PyArg_UnpackTuple(args, "coerce", 2, 2, &v, &w))
+		return NULL;
+	if (PyNumber_Coerce(&v, &w) < 0)
+		return NULL;
+	res = PyTuple_Pack(2, v, w);
+	Py_DECREF(v);
+	Py_DECREF(w);
+	return res;
+}
+
+PyDoc_STRVAR(coerce_doc,
+"coerce(x, y) -> (x1, y1)\n\
+\n\
+Return a tuple consisting of the two numeric arguments converted to\n\
+a common type, using the same rules as used by arithmetic operations.\n\
+If coercion is not possible, raise TypeError.");
+
+static PyObject *
+builtin_compile(PyObject *self, PyObject *args)
+{
+	char *str;
+	char *filename;
+	char *startstr;
+	int start;
+	int dont_inherit = 0;
+	int supplied_flags = 0;
+	PyCompilerFlags cf;
+	PyObject *result = NULL, *cmd, *tmp = NULL;
+	Py_ssize_t length;
+
+	if (!PyArg_ParseTuple(args, "Oss|ii:compile", &cmd, &filename,
+			      &startstr, &supplied_flags, &dont_inherit))
+		return NULL;
+
+	cf.cf_flags = supplied_flags;
+
+#ifdef Py_USING_UNICODE
+	if (PyUnicode_Check(cmd)) {
+		tmp = PyUnicode_AsUTF8String(cmd);
+		if (tmp == NULL)
+			return NULL;
+		cmd = tmp;
+		cf.cf_flags |= PyCF_SOURCE_IS_UTF8;
+	}
+#endif
+	if (PyObject_AsReadBuffer(cmd, (const void **)&str, &length))
+		return NULL;
+	if ((size_t)length != strlen(str)) {
+		PyErr_SetString(PyExc_TypeError,
+				"compile() expected string without null bytes");
+		goto cleanup;
+	}
+
+	if (strcmp(startstr, "exec") == 0)
+		start = Py_file_input;
+	else if (strcmp(startstr, "eval") == 0)
+		start = Py_eval_input;
+	else if (strcmp(startstr, "single") == 0)
+		start = Py_single_input;
+	else {
+		PyErr_SetString(PyExc_ValueError,
+		   "compile() arg 3 must be 'exec' or 'eval' or 'single'");
+		goto cleanup;
+	}
+
+	if (supplied_flags &
+	    ~(PyCF_MASK | PyCF_MASK_OBSOLETE | PyCF_DONT_IMPLY_DEDENT | PyCF_ONLY_AST))
+	{
+		PyErr_SetString(PyExc_ValueError,
+				"compile(): unrecognised flags");
+		goto cleanup;
+	}
+	/* XXX Warn if (supplied_flags & PyCF_MASK_OBSOLETE) != 0? */
+
+	if (!dont_inherit) {
+		PyEval_MergeCompilerFlags(&cf);
+	}
+	result = Py_CompileStringFlags(str, filename, start, &cf);
+cleanup:
+	Py_XDECREF(tmp);
+	return result;
+}
+
+PyDoc_STRVAR(compile_doc,
+"compile(source, filename, mode[, flags[, dont_inherit]]) -> code object\n\
+\n\
+Compile the source string (a Python module, statement or expression)\n\
+into a code object that can be executed by the exec statement or eval().\n\
+The filename will be used for run-time error messages.\n\
+The mode must be 'exec' to compile a module, 'single' to compile a\n\
+single (interactive) statement, or 'eval' to compile an expression.\n\
+The flags argument, if present, controls which future statements influence\n\
+the compilation of the code.\n\
+The dont_inherit argument, if non-zero, stops the compilation inheriting\n\
+the effects of any future statements in effect in the code calling\n\
+compile; if absent or zero these statements do influence the compilation,\n\
+in addition to any features explicitly specified.");
+
+static PyObject *
+builtin_dir(PyObject *self, PyObject *args)
+{
+	PyObject *arg = NULL;
+
+	if (!PyArg_UnpackTuple(args, "dir", 0, 1, &arg))
+		return NULL;
+	return PyObject_Dir(arg);
+}
+
+PyDoc_STRVAR(dir_doc,
+"dir([object]) -> list of strings\n"
+"\n"
+"Return an alphabetized list of names comprising (some of) the attributes\n"
+"of the given object, and of attributes reachable from it:\n"
+"\n"
+"No argument:  the names in the current scope.\n"
+"Module object:  the module attributes.\n"
+"Type or class object:  its attributes, and recursively the attributes of\n"
+"    its bases.\n"
+"Otherwise:  its attributes, its class's attributes, and recursively the\n"
+"    attributes of its class's base classes.");
+
+static PyObject *
+builtin_divmod(PyObject *self, PyObject *args)
+{
+	PyObject *v, *w;
+
+	if (!PyArg_UnpackTuple(args, "divmod", 2, 2, &v, &w))
+		return NULL;
+	return PyNumber_Divmod(v, w);
+}
+
+PyDoc_STRVAR(divmod_doc,
+"divmod(x, y) -> (div, mod)\n\
+\n\
+Return the tuple ((x-x%y)/y, x%y).  Invariant: div*y + mod == x.");
+
+
+static PyObject *
+builtin_eval(PyObject *self, PyObject *args)
+{
+	PyObject *cmd, *result, *tmp = NULL;
+	PyObject *globals = Py_None, *locals = Py_None;
+	char *str;
+	PyCompilerFlags cf;
+
+	if (!PyArg_UnpackTuple(args, "eval", 1, 3, &cmd, &globals, &locals))
+		return NULL;
+	if (locals != Py_None && !PyMapping_Check(locals)) {
+		PyErr_SetString(PyExc_TypeError, "locals must be a mapping");
+		return NULL;
+	}
+	if (globals != Py_None && !PyDict_Check(globals)) {
+		PyErr_SetString(PyExc_TypeError, PyMapping_Check(globals) ?
+			"globals must be a real dict; try eval(expr, {}, mapping)"
+			: "globals must be a dict");
+		return NULL;
+	}
+	if (globals == Py_None) {
+		globals = PyEval_GetGlobals();
+		if (locals == Py_None)
+			locals = PyEval_GetLocals();
+	}
+	else if (locals == Py_None)
+		locals = globals;
+
+	if (globals == NULL || locals == NULL) {
+		PyErr_SetString(PyExc_TypeError, 
+			"eval must be given globals and locals "
+			"when called without a frame");
+		return NULL;
+	}
+
+	if (PyDict_GetItemString(globals, "__builtins__") == NULL) {
+		if (PyDict_SetItemString(globals, "__builtins__",
+					 PyEval_GetBuiltins()) != 0)
+			return NULL;
+	}
+
+	if (PyCode_Check(cmd)) {
+		if (PyCode_GetNumFree((PyCodeObject *)cmd) > 0) {
+			PyErr_SetString(PyExc_TypeError,
+		"code object passed to eval() may not contain free variables");
+			return NULL;
+		}
+		return PyEval_EvalCode((PyCodeObject *) cmd, globals, locals);
+	}
+
+	if (!PyString_Check(cmd) &&
+	    !PyUnicode_Check(cmd)) {
+		PyErr_SetString(PyExc_TypeError,
+			   "eval() arg 1 must be a string or code object");
+		return NULL;
+	}
+	cf.cf_flags = 0;
+
+#ifdef Py_USING_UNICODE
+	if (PyUnicode_Check(cmd)) {
+		tmp = PyUnicode_AsUTF8String(cmd);
+		if (tmp == NULL)
+			return NULL;
+		cmd = tmp;
+		cf.cf_flags |= PyCF_SOURCE_IS_UTF8;
+	}
+#endif
+	if (PyString_AsStringAndSize(cmd, &str, NULL)) {
+		Py_XDECREF(tmp);
+		return NULL;
+	}
+	while (*str == ' ' || *str == '\t')
+		str++;
+
+	(void)PyEval_MergeCompilerFlags(&cf);
+	result = PyRun_StringFlags(str, Py_eval_input, globals, locals, &cf);
+	Py_XDECREF(tmp);
+	return result;
+}
+
+PyDoc_STRVAR(eval_doc,
+"eval(source[, globals[, locals]]) -> value\n\
+\n\
+Evaluate the source in the context of globals and locals.\n\
+The source may be a string representing a Python expression\n\
+or a code object as returned by compile().\n\
+The globals must be a dictionary and locals can be any mapping,\n\
+defaulting to the current globals and locals.\n\
+If only globals is given, locals defaults to it.\n");
+
+
+static PyObject *
+builtin_execfile(PyObject *self, PyObject *args)
+{
+	char *filename;
+	PyObject *globals = Py_None, *locals = Py_None;
+	PyObject *res;
+	FILE* fp = NULL;
+	PyCompilerFlags cf;
+	int exists;
+
+	if (!PyArg_ParseTuple(args, "s|O!O:execfile",
+			&filename,
+			&PyDict_Type, &globals,
+			&locals))
+		return NULL;
+	if (locals != Py_None && !PyMapping_Check(locals)) {
+		PyErr_SetString(PyExc_TypeError, "locals must be a mapping");
+		return NULL;
+	}
+	if (globals == Py_None) {
+		globals = PyEval_GetGlobals();
+		if (locals == Py_None)
+			locals = PyEval_GetLocals();
+	}
+	else if (locals == Py_None)
+		locals = globals;
+	if (PyDict_GetItemString(globals, "__builtins__") == NULL) {
+		if (PyDict_SetItemString(globals, "__builtins__",
+					 PyEval_GetBuiltins()) != 0)
+			return NULL;
+	}
+
+	exists = 0;
+	/* Test for existence or directory. */
+#if defined(PLAN9)
+	{
+		Dir *d;
+
+		if ((d = dirstat(filename))!=nil) {
+			if(d->mode & DMDIR)
+				werrstr("is a directory");
+			else
+				exists = 1;
+			free(d);
+		}
+	}
+#elif defined(RISCOS)
+	if (object_exists(filename)) {
+		if (isdir(filename))
+			errno = EISDIR;
+		else
+			exists = 1;
+	}
+#else	/* standard Posix */
+	{
+		struct stat s;
+		if (stat(filename, &s) == 0) {
+			if (S_ISDIR(s.st_mode))
+#				if defined(PYOS_OS2) && defined(PYCC_VACPP)
+					errno = EOS2ERR;
+#				else
+					errno = EISDIR;
+#				endif
+			else
+				exists = 1;
+		}
+	}
+#endif
+
+        if (exists) {
+		Py_BEGIN_ALLOW_THREADS
+		fp = fopen(filename, "r" PY_STDIOTEXTMODE);
+		Py_END_ALLOW_THREADS
+
+		if (fp == NULL) {
+			exists = 0;
+		}
+        }
+
+	if (!exists) {
+		PyErr_SetFromErrnoWithFilename(PyExc_IOError, filename);
+		return NULL;
+	}
+	cf.cf_flags = 0;
+	if (PyEval_MergeCompilerFlags(&cf))
+		res = PyRun_FileExFlags(fp, filename, Py_file_input, globals,
+				   locals, 1, &cf);
+	else
+		res = PyRun_FileEx(fp, filename, Py_file_input, globals,
+				   locals, 1);
+	return res;
+}
+
+PyDoc_STRVAR(execfile_doc,
+"execfile(filename[, globals[, locals]])\n\
+\n\
+Read and execute a Python script from a file.\n\
+The globals and locals are dictionaries, defaulting to the current\n\
+globals and locals.  If only globals is given, locals defaults to it.");
+
+
+static PyObject *
+builtin_getattr(PyObject *self, PyObject *args)
+{
+	PyObject *v, *result, *dflt = NULL;
+	PyObject *name;
+
+	if (!PyArg_UnpackTuple(args, "getattr", 2, 3, &v, &name, &dflt))
+		return NULL;
+#ifdef Py_USING_UNICODE
+	if (PyUnicode_Check(name)) {
+		name = _PyUnicode_AsDefaultEncodedString(name, NULL);
+		if (name == NULL)
+			return NULL;
+	}
+#endif
+
+	if (!PyString_Check(name)) {
+		PyErr_SetString(PyExc_TypeError,
+				"getattr(): attribute name must be string");
+		return NULL;
+	}
+	result = PyObject_GetAttr(v, name);
+	if (result == NULL && dflt != NULL &&
+	    PyErr_ExceptionMatches(PyExc_AttributeError))
+	{
+		PyErr_Clear();
+		Py_INCREF(dflt);
+		result = dflt;
+	}
+	return result;
+}
+
+PyDoc_STRVAR(getattr_doc,
+"getattr(object, name[, default]) -> value\n\
+\n\
+Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.\n\
+When a default argument is given, it is returned when the attribute doesn't\n\
+exist; without it, an exception is raised in that case.");
+
+
+static PyObject *
+builtin_globals(PyObject *self)
+{
+	PyObject *d;
+
+	d = PyEval_GetGlobals();
+	Py_XINCREF(d);
+	return d;
+}
+
+PyDoc_STRVAR(globals_doc,
+"globals() -> dictionary\n\
+\n\
+Return the dictionary containing the current scope's global variables.");
+
+
+static PyObject *
+builtin_hasattr(PyObject *self, PyObject *args)
+{
+	PyObject *v;
+	PyObject *name;
+
+	if (!PyArg_UnpackTuple(args, "hasattr", 2, 2, &v, &name))
+		return NULL;
+#ifdef Py_USING_UNICODE
+	if (PyUnicode_Check(name)) {
+		name = _PyUnicode_AsDefaultEncodedString(name, NULL);
+		if (name == NULL)
+			return NULL;
+	}
+#endif
+
+	if (!PyString_Check(name)) {
+		PyErr_SetString(PyExc_TypeError,
+				"hasattr(): attribute name must be string");
+		return NULL;
+	}
+	v = PyObject_GetAttr(v, name);
+	if (v == NULL) {
+		PyErr_Clear();
+		Py_INCREF(Py_False);
+		return Py_False;
+	}
+	Py_DECREF(v);
+	Py_INCREF(Py_True);
+	return Py_True;
+}
+
+PyDoc_STRVAR(hasattr_doc,
+"hasattr(object, name) -> bool\n\
+\n\
+Return whether the object has an attribute with the given name.\n\
+(This is done by calling getattr(object, name) and catching exceptions.)");
+
+
+static PyObject *
+builtin_id(PyObject *self, PyObject *v)
+{
+	return PyLong_FromVoidPtr(v);
+}
+
+PyDoc_STRVAR(id_doc,
+"id(object) -> integer\n\
+\n\
+Return the identity of an object.  This is guaranteed to be unique among\n\
+simultaneously existing objects.  (Hint: it's the object's memory address.)");
+
+
+static PyObject *
+builtin_map(PyObject *self, PyObject *args)
+{
+	typedef struct {
+		PyObject *it;	/* the iterator object */
+		int saw_StopIteration;  /* bool:  did the iterator end? */
+	} sequence;
+
+	PyObject *func, *result;
+	sequence *seqs = NULL, *sqp;
+	Py_ssize_t n, len;
+	register int i, j;
+
+	n = PyTuple_Size(args);
+	if (n < 2) {
+		PyErr_SetString(PyExc_TypeError,
+				"map() requires at least two args");
+		return NULL;
+	}
+
+	func = PyTuple_GetItem(args, 0);
+	n--;
+
+	if (func == Py_None && n == 1) {
+		/* map(None, S) is the same as list(S). */
+		return PySequence_List(PyTuple_GetItem(args, 1));
+	}
+
+	/* Get space for sequence descriptors.  Must NULL out the iterator
+	 * pointers so that jumping to Fail_2 later doesn't see trash.
+	 */
+	if ((seqs = PyMem_NEW(sequence, n)) == NULL) {
+		PyErr_NoMemory();
+		return NULL;
+	}
+	for (i = 0; i < n; ++i) {
+		seqs[i].it = (PyObject*)NULL;
+		seqs[i].saw_StopIteration = 0;
+	}
+
+	/* Do a first pass to obtain iterators for the arguments, and set len
+	 * to the largest of their lengths.
+	 */
+	len = 0;
+	for (i = 0, sqp = seqs; i < n; ++i, ++sqp) {
+		PyObject *curseq;
+		Py_ssize_t curlen;
+
+		/* Get iterator. */
+		curseq = PyTuple_GetItem(args, i+1);
+		sqp->it = PyObject_GetIter(curseq);
+		if (sqp->it == NULL) {
+			static char errmsg[] =
+			    "argument %d to map() must support iteration";
+			char errbuf[sizeof(errmsg) + 25];
+			PyOS_snprintf(errbuf, sizeof(errbuf), errmsg, i+2);
+			PyErr_SetString(PyExc_TypeError, errbuf);
+			goto Fail_2;
+		}
+
+		/* Update len. */
+		curlen = _PyObject_LengthHint(curseq);
+		if (curlen < 0) {
+			if (!PyErr_ExceptionMatches(PyExc_TypeError)  &&
+			    !PyErr_ExceptionMatches(PyExc_AttributeError)) {
+				goto Fail_2;
+			}
+			PyErr_Clear();
+			curlen = 8;  /* arbitrary */
+		}
+		if (curlen > len)
+			len = curlen;
+	}
+
+	/* Get space for the result list. */
+	if ((result = (PyObject *) PyList_New(len)) == NULL)
+		goto Fail_2;
+
+	/* Iterate over the sequences until all have stopped. */
+	for (i = 0; ; ++i) {
+		PyObject *alist, *item=NULL, *value;
+		int numactive = 0;
+
+		if (func == Py_None && n == 1)
+			alist = NULL;
+		else if ((alist = PyTuple_New(n)) == NULL)
+			goto Fail_1;
+
+		for (j = 0, sqp = seqs; j < n; ++j, ++sqp) {
+			if (sqp->saw_StopIteration) {
+				Py_INCREF(Py_None);
+				item = Py_None;
+			}
+			else {
+				item = PyIter_Next(sqp->it);
+				if (item)
+					++numactive;
+				else {
+					if (PyErr_Occurred()) {
+						Py_XDECREF(alist);
+						goto Fail_1;
+					}
+					Py_INCREF(Py_None);
+					item = Py_None;
+					sqp->saw_StopIteration = 1;
+				}
+			}
+			if (alist)
+				PyTuple_SET_ITEM(alist, j, item);
+			else
+				break;
+		}
+
+		if (!alist)
+			alist = item;
+
+		if (numactive == 0) {
+			Py_DECREF(alist);
+			break;
+		}
+
+		if (func == Py_None)
+			value = alist;
+		else {
+			value = PyEval_CallObject(func, alist);
+			Py_DECREF(alist);
+			if (value == NULL)
+				goto Fail_1;
+		}
+		if (i >= len) {
+			int status = PyList_Append(result, value);
+			Py_DECREF(value);
+			if (status < 0)
+				goto Fail_1;
+		}
+		else if (PyList_SetItem(result, i, value) < 0)
+		 	goto Fail_1;
+	}
+
+	if (i < len && PyList_SetSlice(result, i, len, NULL) < 0)
+		goto Fail_1;
+
+	goto Succeed;
+
+Fail_1:
+	Py_DECREF(result);
+Fail_2:
+	result = NULL;
+Succeed:
+	assert(seqs);
+	for (i = 0; i < n; ++i)
+		Py_XDECREF(seqs[i].it);
+	PyMem_DEL(seqs);
+	return result;
+}
+
+PyDoc_STRVAR(map_doc,
+"map(function, sequence[, sequence, ...]) -> list\n\
+\n\
+Return a list of the results of applying the function to the items of\n\
+the argument sequence(s).  If more than one sequence is given, the\n\
+function is called with an argument list consisting of the corresponding\n\
+item of each sequence, substituting None for missing values when not all\n\
+sequences have the same length.  If the function is None, return a list of\n\
+the items of the sequence (or a list of tuples if more than one sequence).");
+
+
+static PyObject *
+builtin_setattr(PyObject *self, PyObject *args)
+{
+	PyObject *v;
+	PyObject *name;
+	PyObject *value;
+
+	if (!PyArg_UnpackTuple(args, "setattr", 3, 3, &v, &name, &value))
+		return NULL;
+	if (PyObject_SetAttr(v, name, value) != 0)
+		return NULL;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(setattr_doc,
+"setattr(object, name, value)\n\
+\n\
+Set a named attribute on an object; setattr(x, 'y', v) is equivalent to\n\
+``x.y = v''.");
+
+
+static PyObject *
+builtin_delattr(PyObject *self, PyObject *args)
+{
+	PyObject *v;
+	PyObject *name;
+
+	if (!PyArg_UnpackTuple(args, "delattr", 2, 2, &v, &name))
+		return NULL;
+	if (PyObject_SetAttr(v, name, (PyObject *)NULL) != 0)
+		return NULL;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(delattr_doc,
+"delattr(object, name)\n\
+\n\
+Delete a named attribute on an object; delattr(x, 'y') is equivalent to\n\
+``del x.y''.");
+
+
+static PyObject *
+builtin_hash(PyObject *self, PyObject *v)
+{
+	long x;
+
+	x = PyObject_Hash(v);
+	if (x == -1)
+		return NULL;
+	return PyInt_FromLong(x);
+}
+
+PyDoc_STRVAR(hash_doc,
+"hash(object) -> integer\n\
+\n\
+Return a hash value for the object.  Two objects with the same value have\n\
+the same hash value.  The reverse is not necessarily true, but likely.");
+
+
+static PyObject *
+builtin_hex(PyObject *self, PyObject *v)
+{
+	PyNumberMethods *nb;
+	PyObject *res;
+
+	if ((nb = v->ob_type->tp_as_number) == NULL ||
+	    nb->nb_hex == NULL) {
+		PyErr_SetString(PyExc_TypeError,
+			   "hex() argument can't be converted to hex");
+		return NULL;
+	}
+	res = (*nb->nb_hex)(v);
+	if (res && !PyString_Check(res)) {
+		PyErr_Format(PyExc_TypeError,
+			     "__hex__ returned non-string (type %.200s)",
+			     res->ob_type->tp_name);
+		Py_DECREF(res);
+		return NULL;
+	}
+	return res;
+}
+
+PyDoc_STRVAR(hex_doc,
+"hex(number) -> string\n\
+\n\
+Return the hexadecimal representation of an integer or long integer.");
+
+
+static PyObject *builtin_raw_input(PyObject *, PyObject *);
+
+static PyObject *
+builtin_input(PyObject *self, PyObject *args)
+{
+	PyObject *line;
+	char *str;
+	PyObject *res;
+	PyObject *globals, *locals;
+	PyCompilerFlags cf;
+
+	line = builtin_raw_input(self, args);
+	if (line == NULL)
+		return line;
+	if (!PyArg_Parse(line, "s;embedded '\\0' in input line", &str))
+		return NULL;
+	while (*str == ' ' || *str == '\t')
+			str++;
+	globals = PyEval_GetGlobals();
+	locals = PyEval_GetLocals();
+	if (PyDict_GetItemString(globals, "__builtins__") == NULL) {
+		if (PyDict_SetItemString(globals, "__builtins__",
+					 PyEval_GetBuiltins()) != 0)
+			return NULL;
+	}
+	cf.cf_flags = 0;
+	PyEval_MergeCompilerFlags(&cf);
+	res = PyRun_StringFlags(str, Py_eval_input, globals, locals, &cf);
+	Py_DECREF(line);
+	return res;
+}
+
+PyDoc_STRVAR(input_doc,
+"input([prompt]) -> value\n\
+\n\
+Equivalent to eval(raw_input(prompt)).");
+
+
+static PyObject *
+builtin_intern(PyObject *self, PyObject *args)
+{
+	PyObject *s;
+	if (!PyArg_ParseTuple(args, "S:intern", &s))
+		return NULL;
+	if (!PyString_CheckExact(s)) {
+		PyErr_SetString(PyExc_TypeError,
+				"can't intern subclass of string");
+		return NULL;
+	}
+	Py_INCREF(s);
+	PyString_InternInPlace(&s);
+	return s;
+}
+
+PyDoc_STRVAR(intern_doc,
+"intern(string) -> string\n\
+\n\
+``Intern'' the given string.  This enters the string in the (global)\n\
+table of interned strings whose purpose is to speed up dictionary lookups.\n\
+Return the string itself or the previously interned string object with the\n\
+same value.");
+
+
+static PyObject *
+builtin_iter(PyObject *self, PyObject *args)
+{
+	PyObject *v, *w = NULL;
+
+	if (!PyArg_UnpackTuple(args, "iter", 1, 2, &v, &w))
+		return NULL;
+	if (w == NULL)
+		return PyObject_GetIter(v);
+	if (!PyCallable_Check(v)) {
+		PyErr_SetString(PyExc_TypeError,
+				"iter(v, w): v must be callable");
+		return NULL;
+	}
+	return PyCallIter_New(v, w);
+}
+
+PyDoc_STRVAR(iter_doc,
+"iter(collection) -> iterator\n\
+iter(callable, sentinel) -> iterator\n\
+\n\
+Get an iterator from an object.  In the first form, the argument must\n\
+supply its own iterator, or be a sequence.\n\
+In the second form, the callable is called until it returns the sentinel.");
+
+
+static PyObject *
+builtin_len(PyObject *self, PyObject *v)
+{
+	Py_ssize_t res;
+
+	res = PyObject_Size(v);
+	if (res < 0 && PyErr_Occurred())
+		return NULL;
+	return PyInt_FromSsize_t(res);
+}
+
+PyDoc_STRVAR(len_doc,
+"len(object) -> integer\n\
+\n\
+Return the number of items of a sequence or mapping.");
+
+
+static PyObject *
+builtin_locals(PyObject *self)
+{
+	PyObject *d;
+
+	d = PyEval_GetLocals();
+	Py_XINCREF(d);
+	return d;
+}
+
+PyDoc_STRVAR(locals_doc,
+"locals() -> dictionary\n\
+\n\
+Update and return a dictionary containing the current scope's local variables.");
+
+
+static PyObject *
+min_max(PyObject *args, PyObject *kwds, int op)
+{
+	PyObject *v, *it, *item, *val, *maxitem, *maxval, *keyfunc=NULL;
+	const char *name = op == Py_LT ? "min" : "max";
+
+	if (PyTuple_Size(args) > 1)
+		v = args;
+	else if (!PyArg_UnpackTuple(args, (char *)name, 1, 1, &v))
+		return NULL;
+
+	if (kwds != NULL && PyDict_Check(kwds) && PyDict_Size(kwds)) {
+		keyfunc = PyDict_GetItemString(kwds, "key");
+		if (PyDict_Size(kwds)!=1  ||  keyfunc == NULL) {
+			PyErr_Format(PyExc_TypeError,
+				"%s() got an unexpected keyword argument", name);
+			return NULL;
+		}
+	}
+
+	it = PyObject_GetIter(v);
+	if (it == NULL)
+		return NULL;
+
+	maxitem = NULL; /* the result */
+	maxval = NULL;  /* the value associated with the result */
+	while (( item = PyIter_Next(it) )) {
+		/* get the value from the key function */
+		if (keyfunc != NULL) {
+			val = PyObject_CallFunctionObjArgs(keyfunc, item, NULL);
+			if (val == NULL)
+				goto Fail_it_item;
+		}
+		/* no key function; the value is the item */
+		else {
+			val = item;
+			Py_INCREF(val);
+		}
+
+		/* maximum value and item are unset; set them */
+		if (maxval == NULL) {
+			maxitem = item;
+			maxval = val;
+		}
+		/* maximum value and item are set; update them as necessary */
+		else {
+			int cmp = PyObject_RichCompareBool(val, maxval, op);
+			if (cmp < 0)
+				goto Fail_it_item_and_val;
+			else if (cmp > 0) {
+				Py_DECREF(maxval);
+				Py_DECREF(maxitem);
+				maxval = val;
+				maxitem = item;
+			}
+			else {
+				Py_DECREF(item);
+				Py_DECREF(val);
+			}
+		}
+	}
+	if (PyErr_Occurred())
+		goto Fail_it;
+	if (maxval == NULL) {
+		PyErr_Format(PyExc_ValueError,
+			     "%s() arg is an empty sequence", name);
+		assert(maxitem == NULL);
+	}
+	else
+		Py_DECREF(maxval);
+	Py_DECREF(it);
+	return maxitem;
+
+Fail_it_item_and_val:
+	Py_DECREF(val);
+Fail_it_item:
+	Py_DECREF(item);
+Fail_it:
+	Py_XDECREF(maxval);
+	Py_XDECREF(maxitem);
+	Py_DECREF(it);
+	return NULL;
+}
+
+static PyObject *
+builtin_min(PyObject *self, PyObject *args, PyObject *kwds)
+{
+	return min_max(args, kwds, Py_LT);
+}
+
+PyDoc_STRVAR(min_doc,
+"min(iterable[, key=func]) -> value\n\
+min(a, b, c, ...[, key=func]) -> value\n\
+\n\
+With a single iterable argument, return its smallest item.\n\
+With two or more arguments, return the smallest argument.");
+
+
+static PyObject *
+builtin_max(PyObject *self, PyObject *args, PyObject *kwds)
+{
+	return min_max(args, kwds, Py_GT);
+}
+
+PyDoc_STRVAR(max_doc,
+"max(iterable[, key=func]) -> value\n\
+max(a, b, c, ...[, key=func]) -> value\n\
+\n\
+With a single iterable argument, return its largest item.\n\
+With two or more arguments, return the largest argument.");
+
+
+static PyObject *
+builtin_oct(PyObject *self, PyObject *v)
+{
+	PyNumberMethods *nb;
+	PyObject *res;
+
+	if (v == NULL || (nb = v->ob_type->tp_as_number) == NULL ||
+	    nb->nb_oct == NULL) {
+		PyErr_SetString(PyExc_TypeError,
+			   "oct() argument can't be converted to oct");
+		return NULL;
+	}
+	res = (*nb->nb_oct)(v);
+	if (res && !PyString_Check(res)) {
+		PyErr_Format(PyExc_TypeError,
+			     "__oct__ returned non-string (type %.200s)",
+			     res->ob_type->tp_name);
+		Py_DECREF(res);
+		return NULL;
+	}
+	return res;
+}
+
+PyDoc_STRVAR(oct_doc,
+"oct(number) -> string\n\
+\n\
+Return the octal representation of an integer or long integer.");
+
+
+static PyObject *
+builtin_open(PyObject *self, PyObject *args, PyObject *kwds)
+{
+	return PyObject_Call((PyObject*)&PyFile_Type, args, kwds);
+}
+
+PyDoc_STRVAR(open_doc,
+"open(name[, mode[, buffering]]) -> file object\n\
+\n\
+Open a file using the file() type, returns a file object.");
+
+
+static PyObject *
+builtin_ord(PyObject *self, PyObject* obj)
+{
+	long ord;
+	Py_ssize_t size;
+
+	if (PyString_Check(obj)) {
+		size = PyString_GET_SIZE(obj);
+		if (size == 1) {
+			ord = (long)((unsigned char)*PyString_AS_STRING(obj));
+			return PyInt_FromLong(ord);
+		}
+#ifdef Py_USING_UNICODE
+	} else if (PyUnicode_Check(obj)) {
+		size = PyUnicode_GET_SIZE(obj);
+		if (size == 1) {
+			ord = (long)*PyUnicode_AS_UNICODE(obj);
+			return PyInt_FromLong(ord);
+		}
+#endif
+	} else {
+		PyErr_Format(PyExc_TypeError,
+			     "ord() expected string of length 1, but " \
+			     "%.200s found", obj->ob_type->tp_name);
+		return NULL;
+	}
+
+	PyErr_Format(PyExc_TypeError,
+		     "ord() expected a character, "
+		     "but string of length %zd found",
+		     size);
+	return NULL;
+}
+
+PyDoc_STRVAR(ord_doc,
+"ord(c) -> integer\n\
+\n\
+Return the integer ordinal of a one-character string.");
+
+
+static PyObject *
+builtin_pow(PyObject *self, PyObject *args)
+{
+	PyObject *v, *w, *z = Py_None;
+
+	if (!PyArg_UnpackTuple(args, "pow", 2, 3, &v, &w, &z))
+		return NULL;
+	return PyNumber_Power(v, w, z);
+}
+
+PyDoc_STRVAR(pow_doc,
+"pow(x, y[, z]) -> number\n\
+\n\
+With two arguments, equivalent to x**y.  With three arguments,\n\
+equivalent to (x**y) % z, but may be more efficient (e.g. for longs).");
+
+
+
+/* Return number of items in range (lo, hi, step), when arguments are
+ * PyInt or PyLong objects.  step > 0 required.  Return a value < 0 if
+ * & only if the true value is too large to fit in a signed long.
+ * Arguments MUST return 1 with either PyInt_Check() or
+ * PyLong_Check().  Return -1 when there is an error.
+ */
+static long
+get_len_of_range_longs(PyObject *lo, PyObject *hi, PyObject *step)
+{
+	/* -------------------------------------------------------------
+	Algorithm is equal to that of get_len_of_range(), but it operates
+	on PyObjects (which are assumed to be PyLong or PyInt objects).
+	---------------------------------------------------------------*/
+	long n;
+	PyObject *diff = NULL;
+	PyObject *one = NULL;
+	PyObject *tmp1 = NULL, *tmp2 = NULL, *tmp3 = NULL;
+		/* holds sub-expression evaluations */
+
+	/* if (lo >= hi), return length of 0. */
+	if (PyObject_Compare(lo, hi) >= 0)
+		return 0;
+
+	if ((one = PyLong_FromLong(1L)) == NULL)
+		goto Fail;
+
+	if ((tmp1 = PyNumber_Subtract(hi, lo)) == NULL)
+		goto Fail;
+
+	if ((diff = PyNumber_Subtract(tmp1, one)) == NULL)
+		goto Fail;
+
+	if ((tmp2 = PyNumber_FloorDivide(diff, step)) == NULL)
+		goto Fail;
+
+	if ((tmp3 = PyNumber_Add(tmp2, one)) == NULL)
+		goto Fail;
+
+	n = PyLong_AsLong(tmp3);
+	if (PyErr_Occurred()) {  /* Check for Overflow */
+		PyErr_Clear();
+		goto Fail;
+	}
+
+	Py_DECREF(tmp3);
+	Py_DECREF(tmp2);
+	Py_DECREF(diff);
+	Py_DECREF(tmp1);
+	Py_DECREF(one);
+	return n;
+
+  Fail:
+	Py_XDECREF(tmp3);
+	Py_XDECREF(tmp2);
+	Py_XDECREF(diff);
+	Py_XDECREF(tmp1);
+	Py_XDECREF(one);
+	return -1;
+}
+
+/* An extension of builtin_range() that handles the case when PyLong
+ * arguments are given. */
+static PyObject *
+handle_range_longs(PyObject *self, PyObject *args)
+{
+	PyObject *ilow;
+	PyObject *ihigh = NULL;
+	PyObject *istep = NULL;
+
+	PyObject *curnum = NULL;
+	PyObject *v = NULL;
+	long bign;
+	int i, n;
+	int cmp_result;
+
+	PyObject *zero = PyLong_FromLong(0);
+
+	if (zero == NULL)
+		return NULL;
+
+	if (!PyArg_UnpackTuple(args, "range", 1, 3, &ilow, &ihigh, &istep)) {
+		Py_DECREF(zero);
+		return NULL;
+	}
+
+	/* Figure out which way we were called, supply defaults, and be
+	 * sure to incref everything so that the decrefs at the end
+	 * are correct.
+	 */
+	assert(ilow != NULL);
+	if (ihigh == NULL) {
+		/* only 1 arg -- it's the upper limit */
+		ihigh = ilow;
+		ilow = NULL;
+	}
+	assert(ihigh != NULL);
+	Py_INCREF(ihigh);
+
+	/* ihigh correct now; do ilow */
+	if (ilow == NULL)
+		ilow = zero;
+	Py_INCREF(ilow);
+
+	/* ilow and ihigh correct now; do istep */
+	if (istep == NULL) {
+		istep = PyLong_FromLong(1L);
+		if (istep == NULL)
+			goto Fail;
+	}
+	else {
+		Py_INCREF(istep);
+	}
+
+	if (!PyInt_Check(ilow) && !PyLong_Check(ilow)) {
+		PyErr_Format(PyExc_TypeError,
+			     "range() integer start argument expected, got %s.",
+			     ilow->ob_type->tp_name);
+		goto Fail;
+	}
+
+	if (!PyInt_Check(ihigh) && !PyLong_Check(ihigh)) {
+		PyErr_Format(PyExc_TypeError,
+			     "range() integer end argument expected, got %s.",
+			     ihigh->ob_type->tp_name);
+		goto Fail;
+	}
+
+	if (!PyInt_Check(istep) && !PyLong_Check(istep)) {
+		PyErr_Format(PyExc_TypeError,
+			     "range() integer step argument expected, got %s.",
+			     istep->ob_type->tp_name);
+		goto Fail;
+	}
+
+	if (PyObject_Cmp(istep, zero, &cmp_result) == -1)
+		goto Fail;
+	if (cmp_result == 0) {
+		PyErr_SetString(PyExc_ValueError,
+				"range() step argument must not be zero");
+		goto Fail;
+	}
+
+	if (cmp_result > 0)
+		bign = get_len_of_range_longs(ilow, ihigh, istep);
+	else {
+		PyObject *neg_istep = PyNumber_Negative(istep);
+		if (neg_istep == NULL)
+			goto Fail;
+		bign = get_len_of_range_longs(ihigh, ilow, neg_istep);
+		Py_DECREF(neg_istep);
+	}
+
+	n = (int)bign;
+	if (bign < 0 || (long)n != bign) {
+		PyErr_SetString(PyExc_OverflowError,
+				"range() result has too many items");
+		goto Fail;
+	}
+
+	v = PyList_New(n);
+	if (v == NULL)
+		goto Fail;
+
+	curnum = ilow;
+	Py_INCREF(curnum);
+
+	for (i = 0; i < n; i++) {
+		PyObject *w = PyNumber_Long(curnum);
+		PyObject *tmp_num;
+		if (w == NULL)
+			goto Fail;
+
+		PyList_SET_ITEM(v, i, w);
+
+		tmp_num = PyNumber_Add(curnum, istep);
+		if (tmp_num == NULL)
+			goto Fail;
+
+		Py_DECREF(curnum);
+		curnum = tmp_num;
+	}
+	Py_DECREF(ilow);
+	Py_DECREF(ihigh);
+	Py_DECREF(istep);
+	Py_DECREF(zero);
+	Py_DECREF(curnum);
+	return v;
+
+  Fail:
+	Py_DECREF(ilow);
+	Py_DECREF(ihigh);
+	Py_XDECREF(istep);
+	Py_DECREF(zero);
+	Py_XDECREF(curnum);
+	Py_XDECREF(v);
+	return NULL;
+}
+
+/* Return number of items in range/xrange (lo, hi, step).  step > 0
+ * required.  Return a value < 0 if & only if the true value is too
+ * large to fit in a signed long.
+ */
+static long
+get_len_of_range(long lo, long hi, long step)
+{
+	/* -------------------------------------------------------------
+	If lo >= hi, the range is empty.
+	Else if n values are in the range, the last one is
+	lo + (n-1)*step, which must be <= hi-1.  Rearranging,
+	n <= (hi - lo - 1)/step + 1, so taking the floor of the RHS gives
+	the proper value.  Since lo < hi in this case, hi-lo-1 >= 0, so
+	the RHS is non-negative and so truncation is the same as the
+	floor.  Letting M be the largest positive long, the worst case
+	for the RHS numerator is hi=M, lo=-M-1, and then
+	hi-lo-1 = M-(-M-1)-1 = 2*M.  Therefore unsigned long has enough
+	precision to compute the RHS exactly.
+	---------------------------------------------------------------*/
+	long n = 0;
+	if (lo < hi) {
+		unsigned long uhi = (unsigned long)hi;
+		unsigned long ulo = (unsigned long)lo;
+		unsigned long diff = uhi - ulo - 1;
+		n = (long)(diff / (unsigned long)step + 1);
+	}
+	return n;
+}
+
+static PyObject *
+builtin_range(PyObject *self, PyObject *args)
+{
+	long ilow = 0, ihigh = 0, istep = 1;
+	long bign;
+	int i, n;
+
+	PyObject *v;
+
+	if (PyTuple_Size(args) <= 1) {
+		if (!PyArg_ParseTuple(args,
+				"l;range() requires 1-3 int arguments",
+				&ihigh)) {
+			PyErr_Clear();
+			return handle_range_longs(self, args);
+		}
+	}
+	else {
+		if (!PyArg_ParseTuple(args,
+				"ll|l;range() requires 1-3 int arguments",
+				&ilow, &ihigh, &istep)) {
+			PyErr_Clear();
+			return handle_range_longs(self, args);
+		}
+	}
+	if (istep == 0) {
+		PyErr_SetString(PyExc_ValueError,
+				"range() step argument must not be zero");
+		return NULL;
+	}
+	if (istep > 0)
+		bign = get_len_of_range(ilow, ihigh, istep);
+	else
+		bign = get_len_of_range(ihigh, ilow, -istep);
+	n = (int)bign;
+	if (bign < 0 || (long)n != bign) {
+		PyErr_SetString(PyExc_OverflowError,
+				"range() result has too many items");
+		return NULL;
+	}
+	v = PyList_New(n);
+	if (v == NULL)
+		return NULL;
+	for (i = 0; i < n; i++) {
+		PyObject *w = PyInt_FromLong(ilow);
+		if (w == NULL) {
+			Py_DECREF(v);
+			return NULL;
+		}
+		PyList_SET_ITEM(v, i, w);
+		ilow += istep;
+	}
+	return v;
+}
+
+PyDoc_STRVAR(range_doc,
+"range([start,] stop[, step]) -> list of integers\n\
+\n\
+Return a list containing an arithmetic progression of integers.\n\
+range(i, j) returns [i, i+1, i+2, ..., j-1]; start (!) defaults to 0.\n\
+When step is given, it specifies the increment (or decrement).\n\
+For example, range(4) returns [0, 1, 2, 3].  The end point is omitted!\n\
+These are exactly the valid indices for a list of 4 elements.");
+
+
+static PyObject *
+builtin_raw_input(PyObject *self, PyObject *args)
+{
+	PyObject *v = NULL;
+	PyObject *fin = PySys_GetObject("stdin");
+	PyObject *fout = PySys_GetObject("stdout");
+
+	if (!PyArg_UnpackTuple(args, "[raw_]input", 0, 1, &v))
+		return NULL;
+
+	if (fin == NULL) {
+		PyErr_SetString(PyExc_RuntimeError, "[raw_]input: lost sys.stdin");
+		return NULL;
+	}
+	if (fout == NULL) {
+		PyErr_SetString(PyExc_RuntimeError, "[raw_]input: lost sys.stdout");
+		return NULL;
+	}
+	if (PyFile_SoftSpace(fout, 0)) {
+		if (PyFile_WriteString(" ", fout) != 0)
+			return NULL;
+	}
+	if (PyFile_AsFile(fin) && PyFile_AsFile(fout)
+            && isatty(fileno(PyFile_AsFile(fin)))
+            && isatty(fileno(PyFile_AsFile(fout)))) {
+		PyObject *po;
+		char *prompt;
+		char *s;
+		PyObject *result;
+		if (v != NULL) {
+			po = PyObject_Str(v);
+			if (po == NULL)
+				return NULL;
+			prompt = PyString_AsString(po);
+			if (prompt == NULL)
+				return NULL;
+		}
+		else {
+			po = NULL;
+			prompt = "";
+		}
+		s = PyOS_Readline(PyFile_AsFile(fin), PyFile_AsFile(fout),
+                                  prompt);
+		Py_XDECREF(po);
+		if (s == NULL) {
+			if (!PyErr_Occurred())
+				PyErr_SetNone(PyExc_KeyboardInterrupt);
+			return NULL;
+		}
+		if (*s == '\0') {
+			PyErr_SetNone(PyExc_EOFError);
+			result = NULL;
+		}
+		else { /* strip trailing '\n' */
+			size_t len = strlen(s);
+			if (len > PY_SSIZE_T_MAX) {
+				PyErr_SetString(PyExc_OverflowError,
+						"[raw_]input: input too long");
+				result = NULL;
+			}
+			else {
+				result = PyString_FromStringAndSize(s, len-1);
+			}
+		}
+		PyMem_FREE(s);
+		return result;
+	}
+	if (v != NULL) {
+		if (PyFile_WriteObject(v, fout, Py_PRINT_RAW) != 0)
+			return NULL;
+	}
+	return PyFile_GetLine(fin, -1);
+}
+
+PyDoc_STRVAR(raw_input_doc,
+"raw_input([prompt]) -> string\n\
+\n\
+Read a string from standard input.  The trailing newline is stripped.\n\
+If the user hits EOF (Unix: Ctl-D, Windows: Ctl-Z+Return), raise EOFError.\n\
+On Unix, GNU readline is used if enabled.  The prompt string, if given,\n\
+is printed without a trailing newline before reading.");
+
+
+static PyObject *
+builtin_reduce(PyObject *self, PyObject *args)
+{
+	PyObject *seq, *func, *result = NULL, *it;
+
+	if (!PyArg_UnpackTuple(args, "reduce", 2, 3, &func, &seq, &result))
+		return NULL;
+	if (result != NULL)
+		Py_INCREF(result);
+
+	it = PyObject_GetIter(seq);
+	if (it == NULL) {
+		PyErr_SetString(PyExc_TypeError,
+		    "reduce() arg 2 must support iteration");
+		Py_XDECREF(result);
+		return NULL;
+	}
+
+	if ((args = PyTuple_New(2)) == NULL)
+		goto Fail;
+
+	for (;;) {
+		PyObject *op2;
+
+		if (args->ob_refcnt > 1) {
+			Py_DECREF(args);
+			if ((args = PyTuple_New(2)) == NULL)
+				goto Fail;
+		}
+
+		op2 = PyIter_Next(it);
+		if (op2 == NULL) {
+			if (PyErr_Occurred())
+				goto Fail;
+ 			break;
+		}
+
+		if (result == NULL)
+			result = op2;
+		else {
+			PyTuple_SetItem(args, 0, result);
+			PyTuple_SetItem(args, 1, op2);
+			if ((result = PyEval_CallObject(func, args)) == NULL)
+				goto Fail;
+		}
+	}
+
+	Py_DECREF(args);
+
+	if (result == NULL)
+		PyErr_SetString(PyExc_TypeError,
+			   "reduce() of empty sequence with no initial value");
+
+	Py_DECREF(it);
+	return result;
+
+Fail:
+	Py_XDECREF(args);
+	Py_XDECREF(result);
+	Py_DECREF(it);
+	return NULL;
+}
+
+PyDoc_STRVAR(reduce_doc,
+"reduce(function, sequence[, initial]) -> value\n\
+\n\
+Apply a function of two arguments cumulatively to the items of a sequence,\n\
+from left to right, so as to reduce the sequence to a single value.\n\
+For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates\n\
+((((1+2)+3)+4)+5).  If initial is present, it is placed before the items\n\
+of the sequence in the calculation, and serves as a default when the\n\
+sequence is empty.");
+
+
+static PyObject *
+builtin_reload(PyObject *self, PyObject *v)
+{
+	return PyImport_ReloadModule(v);
+}
+
+PyDoc_STRVAR(reload_doc,
+"reload(module) -> module\n\
+\n\
+Reload the module.  The module must have been successfully imported before.");
+
+
+static PyObject *
+builtin_repr(PyObject *self, PyObject *v)
+{
+	return PyObject_Repr(v);
+}
+
+PyDoc_STRVAR(repr_doc,
+"repr(object) -> string\n\
+\n\
+Return the canonical string representation of the object.\n\
+For most object types, eval(repr(object)) == object.");
+
+
+static PyObject *
+builtin_round(PyObject *self, PyObject *args, PyObject *kwds)
+{
+	double number;
+	double f;
+	int ndigits = 0;
+	int i;
+	static char *kwlist[] = {"number", "ndigits", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwds, "d|i:round",
+                kwlist, &number, &ndigits))
+                return NULL;
+	f = 1.0;
+	i = abs(ndigits);
+	while  (--i >= 0)
+		f = f*10.0;
+	if (ndigits < 0)
+		number /= f;
+	else
+		number *= f;
+	if (number >= 0.0)
+		number = floor(number + 0.5);
+	else
+		number = ceil(number - 0.5);
+	if (ndigits < 0)
+		number *= f;
+	else
+		number /= f;
+	return PyFloat_FromDouble(number);
+}
+
+PyDoc_STRVAR(round_doc,
+"round(number[, ndigits]) -> floating point number\n\
+\n\
+Round a number to a given precision in decimal digits (default 0 digits).\n\
+This always returns a floating point number.  Precision may be negative.");
+
+static PyObject *
+builtin_sorted(PyObject *self, PyObject *args, PyObject *kwds)
+{
+	PyObject *newlist, *v, *seq, *compare=NULL, *keyfunc=NULL, *newargs;
+	PyObject *callable;
+	static char *kwlist[] = {"iterable", "cmp", "key", "reverse", 0};
+	int reverse;
+
+	/* args 1-4 should match listsort in Objects/listobject.c */
+	if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|OOi:sorted",
+		kwlist, &seq, &compare, &keyfunc, &reverse))
+		return NULL;
+
+	newlist = PySequence_List(seq);
+	if (newlist == NULL)
+		return NULL;
+
+	callable = PyObject_GetAttrString(newlist, "sort");
+	if (callable == NULL) {
+		Py_DECREF(newlist);
+		return NULL;
+	}
+
+	newargs = PyTuple_GetSlice(args, 1, 4);
+	if (newargs == NULL) {
+		Py_DECREF(newlist);
+		Py_DECREF(callable);
+		return NULL;
+	}
+
+	v = PyObject_Call(callable, newargs, kwds);
+	Py_DECREF(newargs);
+	Py_DECREF(callable);
+	if (v == NULL) {
+		Py_DECREF(newlist);
+		return NULL;
+	}
+	Py_DECREF(v);
+	return newlist;
+}
+
+PyDoc_STRVAR(sorted_doc,
+"sorted(iterable, cmp=None, key=None, reverse=False) --> new sorted list");
+
+static PyObject *
+builtin_vars(PyObject *self, PyObject *args)
+{
+	PyObject *v = NULL;
+	PyObject *d;
+
+	if (!PyArg_UnpackTuple(args, "vars", 0, 1, &v))
+		return NULL;
+	if (v == NULL) {
+		d = PyEval_GetLocals();
+		if (d == NULL) {
+			if (!PyErr_Occurred())
+				PyErr_SetString(PyExc_SystemError,
+						"vars(): no locals!?");
+		}
+		else
+			Py_INCREF(d);
+	}
+	else {
+		d = PyObject_GetAttrString(v, "__dict__");
+		if (d == NULL) {
+			PyErr_SetString(PyExc_TypeError,
+			    "vars() argument must have __dict__ attribute");
+			return NULL;
+		}
+	}
+	return d;
+}
+
+PyDoc_STRVAR(vars_doc,
+"vars([object]) -> dictionary\n\
+\n\
+Without arguments, equivalent to locals().\n\
+With an argument, equivalent to object.__dict__.");
+
+
+static PyObject*
+builtin_sum(PyObject *self, PyObject *args)
+{
+	PyObject *seq;
+	PyObject *result = NULL;
+	PyObject *temp, *item, *iter;
+
+	if (!PyArg_UnpackTuple(args, "sum", 1, 2, &seq, &result))
+		return NULL;
+
+	iter = PyObject_GetIter(seq);
+	if (iter == NULL)
+		return NULL;
+
+	if (result == NULL) {
+		result = PyInt_FromLong(0);
+		if (result == NULL) {
+			Py_DECREF(iter);
+			return NULL;
+		}
+	} else {
+		/* reject string values for 'start' parameter */
+		if (PyObject_TypeCheck(result, &PyBaseString_Type)) {
+			PyErr_SetString(PyExc_TypeError,
+				"sum() can't sum strings [use ''.join(seq) instead]");
+			Py_DECREF(iter);
+			return NULL;
+		}
+		Py_INCREF(result);
+	}
+
+	for(;;) {
+		item = PyIter_Next(iter);
+		if (item == NULL) {
+			/* error, or end-of-sequence */
+			if (PyErr_Occurred()) {
+				Py_DECREF(result);
+				result = NULL;
+			}
+			break;
+		}
+		temp = PyNumber_Add(result, item);
+		Py_DECREF(result);
+		Py_DECREF(item);
+		result = temp;
+		if (result == NULL)
+			break;
+	}
+	Py_DECREF(iter);
+	return result;
+}
+
+PyDoc_STRVAR(sum_doc,
+"sum(sequence, start=0) -> value\n\
+\n\
+Returns the sum of a sequence of numbers (NOT strings) plus the value\n\
+of parameter 'start'.  When the sequence is empty, returns start.");
+
+
+static PyObject *
+builtin_isinstance(PyObject *self, PyObject *args)
+{
+	PyObject *inst;
+	PyObject *cls;
+	int retval;
+
+	if (!PyArg_UnpackTuple(args, "isinstance", 2, 2, &inst, &cls))
+		return NULL;
+
+	retval = PyObject_IsInstance(inst, cls);
+	if (retval < 0)
+		return NULL;
+	return PyBool_FromLong(retval);
+}
+
+PyDoc_STRVAR(isinstance_doc,
+"isinstance(object, class-or-type-or-tuple) -> bool\n\
+\n\
+Return whether an object is an instance of a class or of a subclass thereof.\n\
+With a type as second argument, return whether that is the object's type.\n\
+The form using a tuple, isinstance(x, (A, B, ...)), is a shortcut for\n\
+isinstance(x, A) or isinstance(x, B) or ... (etc.).");
+
+
+static PyObject *
+builtin_issubclass(PyObject *self, PyObject *args)
+{
+	PyObject *derived;
+	PyObject *cls;
+	int retval;
+
+	if (!PyArg_UnpackTuple(args, "issubclass", 2, 2, &derived, &cls))
+		return NULL;
+
+	retval = PyObject_IsSubclass(derived, cls);
+	if (retval < 0)
+		return NULL;
+	return PyBool_FromLong(retval);
+}
+
+PyDoc_STRVAR(issubclass_doc,
+"issubclass(C, B) -> bool\n\
+\n\
+Return whether class C is a subclass (i.e., a derived class) of class B.\n\
+When using a tuple as the second argument issubclass(X, (A, B, ...)),\n\
+is a shortcut for issubclass(X, A) or issubclass(X, B) or ... (etc.).");
+
+
+static PyObject*
+builtin_zip(PyObject *self, PyObject *args)
+{
+	PyObject *ret;
+	const Py_ssize_t itemsize = PySequence_Length(args);
+	Py_ssize_t i;
+	PyObject *itlist;  /* tuple of iterators */
+	Py_ssize_t len;	   /* guess at result length */
+
+	if (itemsize == 0)
+		return PyList_New(0);
+
+	/* args must be a tuple */
+	assert(PyTuple_Check(args));
+
+	/* Guess at result length:  the shortest of the input lengths.
+	   If some argument refuses to say, we refuse to guess too, lest
+	   an argument like xrange(sys.maxint) lead us astray.*/
+	len = -1;	/* unknown */
+	for (i = 0; i < itemsize; ++i) {
+		PyObject *item = PyTuple_GET_ITEM(args, i);
+		Py_ssize_t thislen = _PyObject_LengthHint(item);
+		if (thislen < 0) {
+			if (!PyErr_ExceptionMatches(PyExc_TypeError)  &&
+			    !PyErr_ExceptionMatches(PyExc_AttributeError)) {
+				return NULL;
+			}
+			PyErr_Clear();
+			len = -1;
+			break;
+		}
+		else if (len < 0 || thislen < len)
+			len = thislen;
+	}
+
+	/* allocate result list */
+	if (len < 0)
+		len = 10;	/* arbitrary */
+	if ((ret = PyList_New(len)) == NULL)
+		return NULL;
+
+	/* obtain iterators */
+	itlist = PyTuple_New(itemsize);
+	if (itlist == NULL)
+		goto Fail_ret;
+	for (i = 0; i < itemsize; ++i) {
+		PyObject *item = PyTuple_GET_ITEM(args, i);
+		PyObject *it = PyObject_GetIter(item);
+		if (it == NULL) {
+			if (PyErr_ExceptionMatches(PyExc_TypeError))
+				PyErr_Format(PyExc_TypeError,
+				    "zip argument #%zd must support iteration",
+				    i+1);
+			goto Fail_ret_itlist;
+		}
+		PyTuple_SET_ITEM(itlist, i, it);
+	}
+
+	/* build result into ret list */
+	for (i = 0; ; ++i) {
+		int j;
+		PyObject *next = PyTuple_New(itemsize);
+		if (!next)
+			goto Fail_ret_itlist;
+
+		for (j = 0; j < itemsize; j++) {
+			PyObject *it = PyTuple_GET_ITEM(itlist, j);
+			PyObject *item = PyIter_Next(it);
+			if (!item) {
+				if (PyErr_Occurred()) {
+					Py_DECREF(ret);
+					ret = NULL;
+				}
+				Py_DECREF(next);
+				Py_DECREF(itlist);
+				goto Done;
+			}
+			PyTuple_SET_ITEM(next, j, item);
+		}
+
+		if (i < len)
+			PyList_SET_ITEM(ret, i, next);
+		else {
+			int status = PyList_Append(ret, next);
+			Py_DECREF(next);
+			++len;
+			if (status < 0)
+				goto Fail_ret_itlist;
+		}
+	}
+
+Done:
+	if (ret != NULL && i < len) {
+		/* The list is too big. */
+		if (PyList_SetSlice(ret, i, len, NULL) < 0)
+			return NULL;
+	}
+	return ret;
+
+Fail_ret_itlist:
+	Py_DECREF(itlist);
+Fail_ret:
+	Py_DECREF(ret);
+	return NULL;
+}
+
+
+PyDoc_STRVAR(zip_doc,
+"zip(seq1 [, seq2 [...]]) -> [(seq1[0], seq2[0] ...), (...)]\n\
+\n\
+Return a list of tuples, where each tuple contains the i-th element\n\
+from each of the argument sequences.  The returned list is truncated\n\
+in length to the length of the shortest argument sequence.");
+
+
+static PyMethodDef builtin_methods[] = {
+ 	{"__import__",	(PyCFunction)builtin___import__, METH_VARARGS | METH_KEYWORDS, import_doc},
+ 	{"abs",		builtin_abs,        METH_O, abs_doc},
+ 	{"all",		builtin_all,        METH_O, all_doc},
+ 	{"any",		builtin_any,        METH_O, any_doc},
+ 	{"apply",	builtin_apply,      METH_VARARGS, apply_doc},
+ 	{"callable",	builtin_callable,   METH_O, callable_doc},
+ 	{"chr",		builtin_chr,        METH_VARARGS, chr_doc},
+ 	{"cmp",		builtin_cmp,        METH_VARARGS, cmp_doc},
+ 	{"coerce",	builtin_coerce,     METH_VARARGS, coerce_doc},
+ 	{"compile",	builtin_compile,    METH_VARARGS, compile_doc},
+ 	{"delattr",	builtin_delattr,    METH_VARARGS, delattr_doc},
+ 	{"dir",		builtin_dir,        METH_VARARGS, dir_doc},
+ 	{"divmod",	builtin_divmod,     METH_VARARGS, divmod_doc},
+ 	{"eval",	builtin_eval,       METH_VARARGS, eval_doc},
+ 	{"execfile",	builtin_execfile,   METH_VARARGS, execfile_doc},
+ 	{"filter",	builtin_filter,     METH_VARARGS, filter_doc},
+ 	{"getattr",	builtin_getattr,    METH_VARARGS, getattr_doc},
+ 	{"globals",	(PyCFunction)builtin_globals,    METH_NOARGS, globals_doc},
+ 	{"hasattr",	builtin_hasattr,    METH_VARARGS, hasattr_doc},
+ 	{"hash",	builtin_hash,       METH_O, hash_doc},
+ 	{"hex",		builtin_hex,        METH_O, hex_doc},
+ 	{"id",		builtin_id,         METH_O, id_doc},
+ 	{"input",	builtin_input,      METH_VARARGS, input_doc},
+ 	{"intern",	builtin_intern,     METH_VARARGS, intern_doc},
+ 	{"isinstance",  builtin_isinstance, METH_VARARGS, isinstance_doc},
+ 	{"issubclass",  builtin_issubclass, METH_VARARGS, issubclass_doc},
+ 	{"iter",	builtin_iter,       METH_VARARGS, iter_doc},
+ 	{"len",		builtin_len,        METH_O, len_doc},
+ 	{"locals",	(PyCFunction)builtin_locals,     METH_NOARGS, locals_doc},
+ 	{"map",		builtin_map,        METH_VARARGS, map_doc},
+ 	{"max",		(PyCFunction)builtin_max,        METH_VARARGS | METH_KEYWORDS, max_doc},
+ 	{"min",		(PyCFunction)builtin_min,        METH_VARARGS | METH_KEYWORDS, min_doc},
+ 	{"oct",		builtin_oct,        METH_O, oct_doc},
+ 	{"open",	(PyCFunction)builtin_open,       METH_VARARGS | METH_KEYWORDS, open_doc},
+ 	{"ord",		builtin_ord,        METH_O, ord_doc},
+ 	{"pow",		builtin_pow,        METH_VARARGS, pow_doc},
+ 	{"range",	builtin_range,      METH_VARARGS, range_doc},
+ 	{"raw_input",	builtin_raw_input,  METH_VARARGS, raw_input_doc},
+ 	{"reduce",	builtin_reduce,     METH_VARARGS, reduce_doc},
+ 	{"reload",	builtin_reload,     METH_O, reload_doc},
+ 	{"repr",	builtin_repr,       METH_O, repr_doc},
+ 	{"round",	(PyCFunction)builtin_round,      METH_VARARGS | METH_KEYWORDS, round_doc},
+ 	{"setattr",	builtin_setattr,    METH_VARARGS, setattr_doc},
+ 	{"sorted",	(PyCFunction)builtin_sorted,     METH_VARARGS | METH_KEYWORDS, sorted_doc},
+ 	{"sum",		builtin_sum,        METH_VARARGS, sum_doc},
+#ifdef Py_USING_UNICODE
+ 	{"unichr",	builtin_unichr,     METH_VARARGS, unichr_doc},
+#endif
+ 	{"vars",	builtin_vars,       METH_VARARGS, vars_doc},
+  	{"zip",         builtin_zip,        METH_VARARGS, zip_doc},
+	{NULL,		NULL},
+};
+
+PyDoc_STRVAR(builtin_doc,
+"Built-in functions, exceptions, and other objects.\n\
+\n\
+Noteworthy: None is the `nil' object; Ellipsis represents `...' in slices.");
+
+PyObject *
+_PyBuiltin_Init(void)
+{
+	PyObject *mod, *dict, *debug;
+	mod = Py_InitModule4("__builtin__", builtin_methods,
+			     builtin_doc, (PyObject *)NULL,
+			     PYTHON_API_VERSION);
+	if (mod == NULL)
+		return NULL;
+	dict = PyModule_GetDict(mod);
+
+#ifdef Py_TRACE_REFS
+	/* __builtin__ exposes a number of statically allocated objects
+	 * that, before this code was added in 2.3, never showed up in
+	 * the list of "all objects" maintained by Py_TRACE_REFS.  As a
+	 * result, programs leaking references to None and False (etc)
+	 * couldn't be diagnosed by examining sys.getobjects(0).
+	 */
+#define ADD_TO_ALL(OBJECT) _Py_AddToAllObjects((PyObject *)(OBJECT), 0)
+#else
+#define ADD_TO_ALL(OBJECT) (void)0
+#endif
+
+#define SETBUILTIN(NAME, OBJECT) \
+	if (PyDict_SetItemString(dict, NAME, (PyObject *)OBJECT) < 0)	\
+		return NULL;						\
+	ADD_TO_ALL(OBJECT)
+
+	SETBUILTIN("None",		Py_None);
+	SETBUILTIN("Ellipsis",		Py_Ellipsis);
+	SETBUILTIN("NotImplemented",	Py_NotImplemented);
+	SETBUILTIN("False",		Py_False);
+	SETBUILTIN("True",		Py_True);
+	SETBUILTIN("basestring",	&PyBaseString_Type);
+	SETBUILTIN("bool",		&PyBool_Type);
+	SETBUILTIN("buffer",		&PyBuffer_Type);
+	SETBUILTIN("classmethod",	&PyClassMethod_Type);
+#ifndef WITHOUT_COMPLEX
+	SETBUILTIN("complex",		&PyComplex_Type);
+#endif
+	SETBUILTIN("dict",		&PyDict_Type);
+ 	SETBUILTIN("enumerate",		&PyEnum_Type);
+	SETBUILTIN("file",		&PyFile_Type);
+	SETBUILTIN("float",		&PyFloat_Type);
+	SETBUILTIN("frozenset",		&PyFrozenSet_Type);
+	SETBUILTIN("property",		&PyProperty_Type);
+	SETBUILTIN("int",		&PyInt_Type);
+	SETBUILTIN("list",		&PyList_Type);
+	SETBUILTIN("long",		&PyLong_Type);
+	SETBUILTIN("object",		&PyBaseObject_Type);
+	SETBUILTIN("reversed",		&PyReversed_Type);
+	SETBUILTIN("set",		&PySet_Type);
+	SETBUILTIN("slice",		&PySlice_Type);
+	SETBUILTIN("staticmethod",	&PyStaticMethod_Type);
+	SETBUILTIN("str",		&PyString_Type);
+	SETBUILTIN("super",		&PySuper_Type);
+	SETBUILTIN("tuple",		&PyTuple_Type);
+	SETBUILTIN("type",		&PyType_Type);
+	SETBUILTIN("xrange",		&PyRange_Type);
+#ifdef Py_USING_UNICODE
+	SETBUILTIN("unicode",		&PyUnicode_Type);
+#endif
+	debug = PyBool_FromLong(Py_OptimizeFlag == 0);
+	if (PyDict_SetItemString(dict, "__debug__", debug) < 0) {
+		Py_XDECREF(debug);
+		return NULL;
+	}
+	Py_XDECREF(debug);
+
+	return mod;
+#undef ADD_TO_ALL
+#undef SETBUILTIN
+}
+
+/* Helper for filter(): filter a tuple through a function */
+
+static PyObject *
+filtertuple(PyObject *func, PyObject *tuple)
+{
+	PyObject *result;
+	Py_ssize_t i, j;
+	Py_ssize_t len = PyTuple_Size(tuple);
+
+	if (len == 0) {
+		if (PyTuple_CheckExact(tuple))
+			Py_INCREF(tuple);
+		else
+			tuple = PyTuple_New(0);
+		return tuple;
+	}
+
+	if ((result = PyTuple_New(len)) == NULL)
+		return NULL;
+
+	for (i = j = 0; i < len; ++i) {
+		PyObject *item, *good;
+		int ok;
+
+		if (tuple->ob_type->tp_as_sequence &&
+		    tuple->ob_type->tp_as_sequence->sq_item) {
+			item = tuple->ob_type->tp_as_sequence->sq_item(tuple, i);
+			if (item == NULL)
+				goto Fail_1;
+		} else {
+			PyErr_SetString(PyExc_TypeError, "filter(): unsubscriptable tuple");
+			goto Fail_1;
+		}
+		if (func == Py_None) {
+			Py_INCREF(item);
+			good = item;
+		}
+		else {
+			PyObject *arg = PyTuple_Pack(1, item);
+			if (arg == NULL) {
+				Py_DECREF(item);
+				goto Fail_1;
+			}
+			good = PyEval_CallObject(func, arg);
+			Py_DECREF(arg);
+			if (good == NULL) {
+				Py_DECREF(item);
+				goto Fail_1;
+			}
+		}
+		ok = PyObject_IsTrue(good);
+		Py_DECREF(good);
+		if (ok) {
+			if (PyTuple_SetItem(result, j++, item) < 0)
+				goto Fail_1;
+		}
+		else
+			Py_DECREF(item);
+	}
+
+	if (_PyTuple_Resize(&result, j) < 0)
+		return NULL;
+
+	return result;
+
+Fail_1:
+	Py_DECREF(result);
+	return NULL;
+}
+
+
+/* Helper for filter(): filter a string through a function */
+
+static PyObject *
+filterstring(PyObject *func, PyObject *strobj)
+{
+	PyObject *result;
+	Py_ssize_t i, j;
+	Py_ssize_t len = PyString_Size(strobj);
+	Py_ssize_t outlen = len;
+
+	if (func == Py_None) {
+		/* If it's a real string we can return the original,
+		 * as no character is ever false and __getitem__
+		 * does return this character. If it's a subclass
+		 * we must go through the __getitem__ loop */
+		if (PyString_CheckExact(strobj)) {
+			Py_INCREF(strobj);
+			return strobj;
+		}
+	}
+	if ((result = PyString_FromStringAndSize(NULL, len)) == NULL)
+		return NULL;
+
+	for (i = j = 0; i < len; ++i) {
+		PyObject *item;
+		int ok;
+
+		item = (*strobj->ob_type->tp_as_sequence->sq_item)(strobj, i);
+		if (item == NULL)
+			goto Fail_1;
+		if (func==Py_None) {
+			ok = 1;
+		} else {
+			PyObject *arg, *good;
+			arg = PyTuple_Pack(1, item);
+			if (arg == NULL) {
+				Py_DECREF(item);
+				goto Fail_1;
+			}
+			good = PyEval_CallObject(func, arg);
+			Py_DECREF(arg);
+			if (good == NULL) {
+				Py_DECREF(item);
+				goto Fail_1;
+			}
+			ok = PyObject_IsTrue(good);
+			Py_DECREF(good);
+		}
+		if (ok) {
+			Py_ssize_t reslen;
+			if (!PyString_Check(item)) {
+				PyErr_SetString(PyExc_TypeError, "can't filter str to str:"
+					" __getitem__ returned different type");
+				Py_DECREF(item);
+				goto Fail_1;
+			}
+			reslen = PyString_GET_SIZE(item);
+			if (reslen == 1) {
+				PyString_AS_STRING(result)[j++] =
+					PyString_AS_STRING(item)[0];
+			} else {
+				/* do we need more space? */
+				Py_ssize_t need = j + reslen + len-i-1;
+				if (need > outlen) {
+					/* overallocate, to avoid reallocations */
+					if (need<2*outlen)
+						need = 2*outlen;
+					if (_PyString_Resize(&result, need)) {
+						Py_DECREF(item);
+						return NULL;
+					}
+					outlen = need;
+				}
+				memcpy(
+					PyString_AS_STRING(result) + j,
+					PyString_AS_STRING(item),
+					reslen
+				);
+				j += reslen;
+			}
+		}
+		Py_DECREF(item);
+	}
+
+	if (j < outlen)
+		_PyString_Resize(&result, j);
+
+	return result;
+
+Fail_1:
+	Py_DECREF(result);
+	return NULL;
+}
+
+#ifdef Py_USING_UNICODE
+/* Helper for filter(): filter a Unicode object through a function */
+
+static PyObject *
+filterunicode(PyObject *func, PyObject *strobj)
+{
+	PyObject *result;
+	register Py_ssize_t i, j;
+	Py_ssize_t len = PyUnicode_GetSize(strobj);
+	Py_ssize_t outlen = len;
+
+	if (func == Py_None) {
+		/* If it's a real string we can return the original,
+		 * as no character is ever false and __getitem__
+		 * does return this character. If it's a subclass
+		 * we must go through the __getitem__ loop */
+		if (PyUnicode_CheckExact(strobj)) {
+			Py_INCREF(strobj);
+			return strobj;
+		}
+	}
+	if ((result = PyUnicode_FromUnicode(NULL, len)) == NULL)
+		return NULL;
+
+	for (i = j = 0; i < len; ++i) {
+		PyObject *item, *arg, *good;
+		int ok;
+
+		item = (*strobj->ob_type->tp_as_sequence->sq_item)(strobj, i);
+		if (item == NULL)
+			goto Fail_1;
+		if (func == Py_None) {
+			ok = 1;
+		} else {
+			arg = PyTuple_Pack(1, item);
+			if (arg == NULL) {
+				Py_DECREF(item);
+				goto Fail_1;
+			}
+			good = PyEval_CallObject(func, arg);
+			Py_DECREF(arg);
+			if (good == NULL) {
+				Py_DECREF(item);
+				goto Fail_1;
+			}
+			ok = PyObject_IsTrue(good);
+			Py_DECREF(good);
+		}
+		if (ok) {
+			Py_ssize_t reslen;
+			if (!PyUnicode_Check(item)) {
+				PyErr_SetString(PyExc_TypeError,
+				"can't filter unicode to unicode:"
+				" __getitem__ returned different type");
+				Py_DECREF(item);
+				goto Fail_1;
+			}
+			reslen = PyUnicode_GET_SIZE(item);
+			if (reslen == 1)
+				PyUnicode_AS_UNICODE(result)[j++] =
+					PyUnicode_AS_UNICODE(item)[0];
+			else {
+				/* do we need more space? */
+				Py_ssize_t need = j + reslen + len - i - 1;
+				if (need > outlen) {
+					/* overallocate,
+					   to avoid reallocations */
+					if (need < 2 * outlen)
+						need = 2 * outlen;
+					if (PyUnicode_Resize(
+						&result, need) < 0) {
+						Py_DECREF(item);
+						goto Fail_1;
+					}
+					outlen = need;
+				}
+				memcpy(PyUnicode_AS_UNICODE(result) + j,
+				       PyUnicode_AS_UNICODE(item),
+				       reslen*sizeof(Py_UNICODE));
+				j += reslen;
+			}
+		}
+		Py_DECREF(item);
+	}
+
+	if (j < outlen)
+		PyUnicode_Resize(&result, j);
+
+	return result;
+
+Fail_1:
+	Py_DECREF(result);
+	return NULL;
+}
+#endif

Added: vendor/Python/current/Python/ceval.c
===================================================================
--- vendor/Python/current/Python/ceval.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/ceval.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,4351 @@
+
+/* Execute compiled code */
+
+/* XXX TO DO:
+   XXX speed up searching for keywords by using a dictionary
+   XXX document it!
+   */
+
+/* enable more aggressive intra-module optimizations, where available */
+#define PY_LOCAL_AGGRESSIVE
+
+#include "Python.h"
+
+#include "code.h"
+#include "frameobject.h"
+#include "eval.h"
+#include "opcode.h"
+#include "structmember.h"
+
+#include <ctype.h>
+
+#ifndef WITH_TSC
+
+#define READ_TIMESTAMP(var)
+
+#else
+
+typedef unsigned long long uint64;
+
+#if defined(__ppc__) /* <- Don't know if this is the correct symbol; this
+			   section should work for GCC on any PowerPC platform,
+			   irrespective of OS.  POWER?  Who knows :-) */
+
+#define READ_TIMESTAMP(var) ppc_getcounter(&var)
+
+static void
+ppc_getcounter(uint64 *v)
+{
+	register unsigned long tbu, tb, tbu2;
+
+  loop:
+	asm volatile ("mftbu %0" : "=r" (tbu) );
+	asm volatile ("mftb  %0" : "=r" (tb)  );
+	asm volatile ("mftbu %0" : "=r" (tbu2));
+	if (__builtin_expect(tbu != tbu2, 0)) goto loop;
+
+	/* The slightly peculiar way of writing the next lines is
+	   compiled better by GCC than any other way I tried. */
+	((long*)(v))[0] = tbu;
+	((long*)(v))[1] = tb;
+}
+
+#else /* this is for linux/x86 (and probably any other GCC/x86 combo) */
+
+#define READ_TIMESTAMP(val) \
+     __asm__ __volatile__("rdtsc" : "=A" (val))
+
+#endif
+
+void dump_tsc(int opcode, int ticked, uint64 inst0, uint64 inst1,
+	      uint64 loop0, uint64 loop1, uint64 intr0, uint64 intr1)
+{
+	uint64 intr, inst, loop;
+	PyThreadState *tstate = PyThreadState_Get();
+	if (!tstate->interp->tscdump)
+		return;
+	intr = intr1 - intr0;
+	inst = inst1 - inst0 - intr;
+	loop = loop1 - loop0 - intr;
+	fprintf(stderr, "opcode=%03d t=%d inst=%06lld loop=%06lld\n",
+		opcode, ticked, inst, loop);
+}
+
+#endif
+
+/* Turn this on if your compiler chokes on the big switch: */
+/* #define CASE_TOO_BIG 1 */
+
+#ifdef Py_DEBUG
+/* For debugging the interpreter: */
+#define LLTRACE  1	/* Low-level trace feature */
+#define CHECKEXC 1	/* Double-check exception checking */
+#endif
+
+typedef PyObject *(*callproc)(PyObject *, PyObject *, PyObject *);
+
+/* Forward declarations */
+#ifdef WITH_TSC
+static PyObject * call_function(PyObject ***, int, uint64*, uint64*);
+#else
+static PyObject * call_function(PyObject ***, int);
+#endif
+static PyObject * fast_function(PyObject *, PyObject ***, int, int, int);
+static PyObject * do_call(PyObject *, PyObject ***, int, int);
+static PyObject * ext_do_call(PyObject *, PyObject ***, int, int, int);
+static PyObject * update_keyword_args(PyObject *, int, PyObject ***,PyObject *);
+static PyObject * update_star_args(int, int, PyObject *, PyObject ***);
+static PyObject * load_args(PyObject ***, int);
+#define CALL_FLAG_VAR 1
+#define CALL_FLAG_KW 2
+
+#ifdef LLTRACE
+static int lltrace;
+static int prtrace(PyObject *, char *);
+#endif
+static int call_trace(Py_tracefunc, PyObject *, PyFrameObject *,
+		      int, PyObject *);
+static void call_trace_protected(Py_tracefunc, PyObject *,
+				 PyFrameObject *, int, PyObject *);
+static void call_exc_trace(Py_tracefunc, PyObject *, PyFrameObject *);
+static int maybe_call_line_trace(Py_tracefunc, PyObject *,
+				  PyFrameObject *, int *, int *, int *);
+
+static PyObject * apply_slice(PyObject *, PyObject *, PyObject *);
+static int assign_slice(PyObject *, PyObject *,
+			PyObject *, PyObject *);
+static PyObject * cmp_outcome(int, PyObject *, PyObject *);
+static PyObject * import_from(PyObject *, PyObject *);
+static int import_all_from(PyObject *, PyObject *);
+static PyObject * build_class(PyObject *, PyObject *, PyObject *);
+static int exec_statement(PyFrameObject *,
+			  PyObject *, PyObject *, PyObject *);
+static void set_exc_info(PyThreadState *, PyObject *, PyObject *, PyObject *);
+static void reset_exc_info(PyThreadState *);
+static void format_exc_check_arg(PyObject *, char *, PyObject *);
+static PyObject * string_concatenate(PyObject *, PyObject *,
+				    PyFrameObject *, unsigned char *);
+
+#define NAME_ERROR_MSG \
+	"name '%.200s' is not defined"
+#define GLOBAL_NAME_ERROR_MSG \
+	"global name '%.200s' is not defined"
+#define UNBOUNDLOCAL_ERROR_MSG \
+	"local variable '%.200s' referenced before assignment"
+#define UNBOUNDFREE_ERROR_MSG \
+	"free variable '%.200s' referenced before assignment" \
+        " in enclosing scope"
+
+/* Dynamic execution profile */
+#ifdef DYNAMIC_EXECUTION_PROFILE
+#ifdef DXPAIRS
+static long dxpairs[257][256];
+#define dxp dxpairs[256]
+#else
+static long dxp[256];
+#endif
+#endif
+
+/* Function call profile */
+#ifdef CALL_PROFILE
+#define PCALL_NUM 11
+static int pcall[PCALL_NUM];
+
+#define PCALL_ALL 0
+#define PCALL_FUNCTION 1
+#define PCALL_FAST_FUNCTION 2
+#define PCALL_FASTER_FUNCTION 3
+#define PCALL_METHOD 4
+#define PCALL_BOUND_METHOD 5
+#define PCALL_CFUNCTION 6
+#define PCALL_TYPE 7
+#define PCALL_GENERATOR 8
+#define PCALL_OTHER 9
+#define PCALL_POP 10
+
+/* Notes about the statistics
+
+   PCALL_FAST stats
+
+   FAST_FUNCTION means no argument tuple needs to be created.
+   FASTER_FUNCTION means that the fast-path frame setup code is used.
+
+   If there is a method call where the call can be optimized by changing
+   the argument tuple and calling the function directly, it gets recorded
+   twice.
+
+   As a result, the relationship among the statistics appears to be
+   PCALL_ALL == PCALL_FUNCTION + PCALL_METHOD - PCALL_BOUND_METHOD +
+                PCALL_CFUNCTION + PCALL_TYPE + PCALL_GENERATOR + PCALL_OTHER
+   PCALL_FUNCTION > PCALL_FAST_FUNCTION > PCALL_FASTER_FUNCTION
+   PCALL_METHOD > PCALL_BOUND_METHOD
+*/
+
+#define PCALL(POS) pcall[POS]++
+
+PyObject *
+PyEval_GetCallStats(PyObject *self)
+{
+	return Py_BuildValue("iiiiiiiiiii",
+			     pcall[0], pcall[1], pcall[2], pcall[3],
+			     pcall[4], pcall[5], pcall[6], pcall[7],
+			     pcall[8], pcall[9], pcall[10]);
+}
+#else
+#define PCALL(O)
+
+PyObject *
+PyEval_GetCallStats(PyObject *self)
+{
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+#endif
+
+
+#ifdef WITH_THREAD
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#include "pythread.h"
+
+static PyThread_type_lock interpreter_lock = 0; /* This is the GIL */
+static long main_thread = 0;
+
+int
+PyEval_ThreadsInitialized(void)
+{
+	return interpreter_lock != 0;
+}
+
+void
+PyEval_InitThreads(void)
+{
+	if (interpreter_lock)
+		return;
+	interpreter_lock = PyThread_allocate_lock();
+	PyThread_acquire_lock(interpreter_lock, 1);
+	main_thread = PyThread_get_thread_ident();
+}
+
+void
+PyEval_AcquireLock(void)
+{
+	PyThread_acquire_lock(interpreter_lock, 1);
+}
+
+void
+PyEval_ReleaseLock(void)
+{
+	PyThread_release_lock(interpreter_lock);
+}
+
+void
+PyEval_AcquireThread(PyThreadState *tstate)
+{
+	if (tstate == NULL)
+		Py_FatalError("PyEval_AcquireThread: NULL new thread state");
+	/* Check someone has called PyEval_InitThreads() to create the lock */
+	assert(interpreter_lock);
+	PyThread_acquire_lock(interpreter_lock, 1);
+	if (PyThreadState_Swap(tstate) != NULL)
+		Py_FatalError(
+			"PyEval_AcquireThread: non-NULL old thread state");
+}
+
+void
+PyEval_ReleaseThread(PyThreadState *tstate)
+{
+	if (tstate == NULL)
+		Py_FatalError("PyEval_ReleaseThread: NULL thread state");
+	if (PyThreadState_Swap(NULL) != tstate)
+		Py_FatalError("PyEval_ReleaseThread: wrong thread state");
+	PyThread_release_lock(interpreter_lock);
+}
+
+/* This function is called from PyOS_AfterFork to ensure that newly
+   created child processes don't hold locks referring to threads which
+   are not running in the child process.  (This could also be done using
+   pthread_atfork mechanism, at least for the pthreads implementation.) */
+
+void
+PyEval_ReInitThreads(void)
+{
+	if (!interpreter_lock)
+		return;
+	/*XXX Can't use PyThread_free_lock here because it does too
+	  much error-checking.  Doing this cleanly would require
+	  adding a new function to each thread_*.h.  Instead, just
+	  create a new lock and waste a little bit of memory */
+	interpreter_lock = PyThread_allocate_lock();
+	PyThread_acquire_lock(interpreter_lock, 1);
+	main_thread = PyThread_get_thread_ident();
+}
+#endif
+
+/* Functions save_thread and restore_thread are always defined so
+   dynamically loaded modules needn't be compiled separately for use
+   with and without threads: */
+
+PyThreadState *
+PyEval_SaveThread(void)
+{
+	PyThreadState *tstate = PyThreadState_Swap(NULL);
+	if (tstate == NULL)
+		Py_FatalError("PyEval_SaveThread: NULL tstate");
+#ifdef WITH_THREAD
+	if (interpreter_lock)
+		PyThread_release_lock(interpreter_lock);
+#endif
+	return tstate;
+}
+
+void
+PyEval_RestoreThread(PyThreadState *tstate)
+{
+	if (tstate == NULL)
+		Py_FatalError("PyEval_RestoreThread: NULL tstate");
+#ifdef WITH_THREAD
+	if (interpreter_lock) {
+		int err = errno;
+		PyThread_acquire_lock(interpreter_lock, 1);
+		errno = err;
+	}
+#endif
+	PyThreadState_Swap(tstate);
+}
+
+
+/* Mechanism whereby asynchronously executing callbacks (e.g. UNIX
+   signal handlers or Mac I/O completion routines) can schedule calls
+   to a function to be called synchronously.
+   The synchronous function is called with one void* argument.
+   It should return 0 for success or -1 for failure -- failure should
+   be accompanied by an exception.
+
+   If registry succeeds, the registry function returns 0; if it fails
+   (e.g. due to too many pending calls) it returns -1 (without setting
+   an exception condition).
+
+   Note that because registry may occur from within signal handlers,
+   or other asynchronous events, calling malloc() is unsafe!
+
+#ifdef WITH_THREAD
+   Any thread can schedule pending calls, but only the main thread
+   will execute them.
+#endif
+
+   XXX WARNING!  ASYNCHRONOUSLY EXECUTING CODE!
+   There are two possible race conditions:
+   (1) nested asynchronous registry calls;
+   (2) registry calls made while pending calls are being processed.
+   While (1) is very unlikely, (2) is a real possibility.
+   The current code is safe against (2), but not against (1).
+   The safety against (2) is derived from the fact that only one
+   thread (the main thread) ever takes things out of the queue.
+
+   XXX Darn!  With the advent of thread state, we should have an array
+   of pending calls per thread in the thread state!  Later...
+*/
+
+#define NPENDINGCALLS 32
+static struct {
+	int (*func)(void *);
+	void *arg;
+} pendingcalls[NPENDINGCALLS];
+static volatile int pendingfirst = 0;
+static volatile int pendinglast = 0;
+static volatile int things_to_do = 0;
+
+int
+Py_AddPendingCall(int (*func)(void *), void *arg)
+{
+	static volatile int busy = 0;
+	int i, j;
+	/* XXX Begin critical section */
+	/* XXX If you want this to be safe against nested
+	   XXX asynchronous calls, you'll have to work harder! */
+	if (busy)
+		return -1;
+	busy = 1;
+	i = pendinglast;
+	j = (i + 1) % NPENDINGCALLS;
+	if (j == pendingfirst) {
+		busy = 0;
+		return -1; /* Queue full */
+	}
+	pendingcalls[i].func = func;
+	pendingcalls[i].arg = arg;
+	pendinglast = j;
+
+	_Py_Ticker = 0;
+	things_to_do = 1; /* Signal main loop */
+	busy = 0;
+	/* XXX End critical section */
+	return 0;
+}
+
+int
+Py_MakePendingCalls(void)
+{
+	static int busy = 0;
+#ifdef WITH_THREAD
+	if (main_thread && PyThread_get_thread_ident() != main_thread)
+		return 0;
+#endif
+	if (busy)
+		return 0;
+	busy = 1;
+	things_to_do = 0;
+	for (;;) {
+		int i;
+		int (*func)(void *);
+		void *arg;
+		i = pendingfirst;
+		if (i == pendinglast)
+			break; /* Queue empty */
+		func = pendingcalls[i].func;
+		arg = pendingcalls[i].arg;
+		pendingfirst = (i + 1) % NPENDINGCALLS;
+		if (func(arg) < 0) {
+			busy = 0;
+			things_to_do = 1; /* We're not done yet */
+			return -1;
+		}
+	}
+	busy = 0;
+	return 0;
+}
+
+
+/* The interpreter's recursion limit */
+
+#ifndef Py_DEFAULT_RECURSION_LIMIT
+#define Py_DEFAULT_RECURSION_LIMIT 1000
+#endif
+static int recursion_limit = Py_DEFAULT_RECURSION_LIMIT;
+int _Py_CheckRecursionLimit = Py_DEFAULT_RECURSION_LIMIT;
+
+int
+Py_GetRecursionLimit(void)
+{
+	return recursion_limit;
+}
+
+void
+Py_SetRecursionLimit(int new_limit)
+{
+	recursion_limit = new_limit;
+        _Py_CheckRecursionLimit = recursion_limit;
+}
+
+/* the macro Py_EnterRecursiveCall() only calls _Py_CheckRecursiveCall()
+   if the recursion_depth reaches _Py_CheckRecursionLimit.
+   If USE_STACKCHECK, the macro decrements _Py_CheckRecursionLimit
+   to guarantee that _Py_CheckRecursiveCall() is regularly called.
+   Without USE_STACKCHECK, there is no need for this. */
+int
+_Py_CheckRecursiveCall(char *where)
+{
+	PyThreadState *tstate = PyThreadState_GET();
+
+#ifdef USE_STACKCHECK
+	if (PyOS_CheckStack()) {
+		--tstate->recursion_depth;
+		PyErr_SetString(PyExc_MemoryError, "Stack overflow");
+		return -1;
+	}
+#endif
+	if (tstate->recursion_depth > recursion_limit) {
+		--tstate->recursion_depth;
+		PyErr_Format(PyExc_RuntimeError,
+			     "maximum recursion depth exceeded%s",
+			     where);
+		return -1;
+	}
+        _Py_CheckRecursionLimit = recursion_limit;
+	return 0;
+}
+
+/* Status code for main loop (reason for stack unwind) */
+enum why_code {
+		WHY_NOT =	0x0001,	/* No error */
+		WHY_EXCEPTION = 0x0002,	/* Exception occurred */
+		WHY_RERAISE =	0x0004,	/* Exception re-raised by 'finally' */
+		WHY_RETURN =	0x0008,	/* 'return' statement */
+		WHY_BREAK =	0x0010,	/* 'break' statement */
+		WHY_CONTINUE =	0x0020,	/* 'continue' statement */
+		WHY_YIELD =	0x0040	/* 'yield' operator */
+};
+
+static enum why_code do_raise(PyObject *, PyObject *, PyObject *);
+static int unpack_iterable(PyObject *, int, PyObject **);
+
+/* for manipulating the thread switch and periodic "stuff" - used to be
+   per thread, now just a pair o' globals */
+int _Py_CheckInterval = 100;
+volatile int _Py_Ticker = 100;
+
+PyObject *
+PyEval_EvalCode(PyCodeObject *co, PyObject *globals, PyObject *locals)
+{
+	/* XXX raise SystemError if globals is NULL */
+	return PyEval_EvalCodeEx(co,
+			  globals, locals,
+			  (PyObject **)NULL, 0,
+			  (PyObject **)NULL, 0,
+			  (PyObject **)NULL, 0,
+			  NULL);
+}
+
+
+/* Interpreter main loop */
+
+PyObject *
+PyEval_EvalFrame(PyFrameObject *f) {
+	/* This is for backward compatibility with extension modules that
+           used this API; core interpreter code should call PyEval_EvalFrameEx() */
+	return PyEval_EvalFrameEx(f, 0);
+}
+
+PyObject *
+PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
+{
+#ifdef DXPAIRS
+	int lastopcode = 0;
+#endif
+	register PyObject **stack_pointer;   /* Next free slot in value stack */
+	register unsigned char *next_instr;
+	register int opcode;	/* Current opcode */
+	register int oparg;	/* Current opcode argument, if any */
+	register enum why_code why; /* Reason for block stack unwind */
+	register int err;	/* Error status -- nonzero if error */
+	register PyObject *x;	/* Result object -- NULL if error */
+	register PyObject *v;	/* Temporary objects popped off stack */
+	register PyObject *w;
+	register PyObject *u;
+	register PyObject *t;
+	register PyObject *stream = NULL;    /* for PRINT opcodes */
+	register PyObject **fastlocals, **freevars;
+	PyObject *retval = NULL;	/* Return value */
+	PyThreadState *tstate = PyThreadState_GET();
+	PyCodeObject *co;
+
+	/* when tracing we set things up so that
+
+               not (instr_lb <= current_bytecode_offset < instr_ub)
+
+	   is true when the line being executed has changed.  The
+           initial values are such as to make this false the first
+           time it is tested. */
+	int instr_ub = -1, instr_lb = 0, instr_prev = -1;
+
+	unsigned char *first_instr;
+	PyObject *names;
+	PyObject *consts;
+#if defined(Py_DEBUG) || defined(LLTRACE)
+	/* Make it easier to find out where we are with a debugger */
+	char *filename;
+#endif
+
+/* Tuple access macros */
+
+#ifndef Py_DEBUG
+#define GETITEM(v, i) PyTuple_GET_ITEM((PyTupleObject *)(v), (i))
+#else
+#define GETITEM(v, i) PyTuple_GetItem((v), (i))
+#endif
+
+#ifdef WITH_TSC
+/* Use Pentium timestamp counter to mark certain events:
+   inst0 -- beginning of switch statement for opcode dispatch
+   inst1 -- end of switch statement (may be skipped)
+   loop0 -- the top of the mainloop
+   loop1 -- place where control returns again to top of mainloop
+            (may be skipped)
+   intr1 -- beginning of long interruption
+   intr2 -- end of long interruption
+
+   Many opcodes call out to helper C functions.  In some cases, the
+   time in those functions should be counted towards the time for the
+   opcode, but not in all cases.  For example, a CALL_FUNCTION opcode
+   calls another Python function; there's no point in charge all the
+   bytecode executed by the called function to the caller.
+
+   It's hard to make a useful judgement statically.  In the presence
+   of operator overloading, it's impossible to tell if a call will
+   execute new Python code or not.
+
+   It's a case-by-case judgement.  I'll use intr1 for the following
+   cases:
+
+   EXEC_STMT
+   IMPORT_STAR
+   IMPORT_FROM
+   CALL_FUNCTION (and friends)
+
+ */
+	uint64 inst0, inst1, loop0, loop1, intr0 = 0, intr1 = 0;
+	int ticked = 0;
+
+	READ_TIMESTAMP(inst0);
+	READ_TIMESTAMP(inst1);
+	READ_TIMESTAMP(loop0);
+	READ_TIMESTAMP(loop1);
+
+	/* shut up the compiler */
+	opcode = 0;
+#endif
+
+/* Code access macros */
+
+#define INSTR_OFFSET()	((int)(next_instr - first_instr))
+#define NEXTOP()	(*next_instr++)
+#define NEXTARG()	(next_instr += 2, (next_instr[-1]<<8) + next_instr[-2])
+#define PEEKARG()	((next_instr[2]<<8) + next_instr[1])
+#define JUMPTO(x)	(next_instr = first_instr + (x))
+#define JUMPBY(x)	(next_instr += (x))
+
+/* OpCode prediction macros
+	Some opcodes tend to come in pairs thus making it possible to predict
+	the second code when the first is run.  For example, COMPARE_OP is often
+	followed by JUMP_IF_FALSE or JUMP_IF_TRUE.  And, those opcodes are often
+	followed by a POP_TOP.
+
+	Verifying the prediction costs a single high-speed test of register
+	variable against a constant.  If the pairing was good, then the
+	processor has a high likelihood of making its own successful branch
+	prediction which results in a nearly zero overhead transition to the
+	next opcode.
+
+	A successful prediction saves a trip through the eval-loop including
+	its two unpredictable branches, the HASARG test and the switch-case.
+
+        If collecting opcode statistics, turn off prediction so that
+	statistics are accurately maintained (the predictions bypass
+	the opcode frequency counter updates).
+*/
+
+#ifdef DYNAMIC_EXECUTION_PROFILE
+#define PREDICT(op)		if (0) goto PRED_##op
+#else
+#define PREDICT(op)		if (*next_instr == op) goto PRED_##op
+#endif
+
+#define PREDICTED(op)		PRED_##op: next_instr++
+#define PREDICTED_WITH_ARG(op)	PRED_##op: oparg = PEEKARG(); next_instr += 3
+
+/* Stack manipulation macros */
+
+/* The stack can grow at most MAXINT deep, as co_nlocals and
+   co_stacksize are ints. */
+#define STACK_LEVEL()	((int)(stack_pointer - f->f_valuestack))
+#define EMPTY()		(STACK_LEVEL() == 0)
+#define TOP()		(stack_pointer[-1])
+#define SECOND()	(stack_pointer[-2])
+#define THIRD() 	(stack_pointer[-3])
+#define FOURTH()	(stack_pointer[-4])
+#define SET_TOP(v)	(stack_pointer[-1] = (v))
+#define SET_SECOND(v)	(stack_pointer[-2] = (v))
+#define SET_THIRD(v)	(stack_pointer[-3] = (v))
+#define SET_FOURTH(v)	(stack_pointer[-4] = (v))
+#define BASIC_STACKADJ(n)	(stack_pointer += n)
+#define BASIC_PUSH(v)	(*stack_pointer++ = (v))
+#define BASIC_POP()	(*--stack_pointer)
+
+#ifdef LLTRACE
+#define PUSH(v)		{ (void)(BASIC_PUSH(v), \
+                               lltrace && prtrace(TOP(), "push")); \
+                               assert(STACK_LEVEL() <= co->co_stacksize); }
+#define POP()		((void)(lltrace && prtrace(TOP(), "pop")), BASIC_POP())
+#define STACKADJ(n)	{ (void)(BASIC_STACKADJ(n), \
+                               lltrace && prtrace(TOP(), "stackadj")); \
+                               assert(STACK_LEVEL() <= co->co_stacksize); }
+#define EXT_POP(STACK_POINTER) (lltrace && prtrace(*(STACK_POINTER), "ext_pop"), *--(STACK_POINTER))
+#else
+#define PUSH(v)		BASIC_PUSH(v)
+#define POP()		BASIC_POP()
+#define STACKADJ(n)	BASIC_STACKADJ(n)
+#define EXT_POP(STACK_POINTER) (*--(STACK_POINTER))
+#endif
+
+/* Local variable macros */
+
+#define GETLOCAL(i)	(fastlocals[i])
+
+/* The SETLOCAL() macro must not DECREF the local variable in-place and
+   then store the new value; it must copy the old value to a temporary
+   value, then store the new value, and then DECREF the temporary value.
+   This is because it is possible that during the DECREF the frame is
+   accessed by other code (e.g. a __del__ method or gc.collect()) and the
+   variable would be pointing to already-freed memory. */
+#define SETLOCAL(i, value)	do { PyObject *tmp = GETLOCAL(i); \
+				     GETLOCAL(i) = value; \
+                                     Py_XDECREF(tmp); } while (0)
+
+/* Start of code */
+
+	if (f == NULL)
+		return NULL;
+
+	/* push frame */
+	if (Py_EnterRecursiveCall(""))
+		return NULL;
+
+	tstate->frame = f;
+
+	if (tstate->use_tracing) {
+		if (tstate->c_tracefunc != NULL) {
+			/* tstate->c_tracefunc, if defined, is a
+			   function that will be called on *every* entry
+			   to a code block.  Its return value, if not
+			   None, is a function that will be called at
+			   the start of each executed line of code.
+			   (Actually, the function must return itself
+			   in order to continue tracing.)  The trace
+			   functions are called with three arguments:
+			   a pointer to the current frame, a string
+			   indicating why the function is called, and
+			   an argument which depends on the situation.
+			   The global trace function is also called
+			   whenever an exception is detected. */
+			if (call_trace(tstate->c_tracefunc, tstate->c_traceobj,
+				       f, PyTrace_CALL, Py_None)) {
+				/* Trace function raised an error */
+				goto exit_eval_frame;
+			}
+		}
+		if (tstate->c_profilefunc != NULL) {
+			/* Similar for c_profilefunc, except it needn't
+			   return itself and isn't called for "line" events */
+			if (call_trace(tstate->c_profilefunc,
+				       tstate->c_profileobj,
+				       f, PyTrace_CALL, Py_None)) {
+				/* Profile function raised an error */
+				goto exit_eval_frame;
+			}
+		}
+	}
+
+	co = f->f_code;
+	names = co->co_names;
+	consts = co->co_consts;
+	fastlocals = f->f_localsplus;
+	freevars = f->f_localsplus + co->co_nlocals;
+	first_instr = (unsigned char*) PyString_AS_STRING(co->co_code);
+	/* An explanation is in order for the next line.
+
+	   f->f_lasti now refers to the index of the last instruction
+	   executed.  You might think this was obvious from the name, but
+	   this wasn't always true before 2.3!  PyFrame_New now sets
+	   f->f_lasti to -1 (i.e. the index *before* the first instruction)
+	   and YIELD_VALUE doesn't fiddle with f_lasti any more.  So this
+	   does work.  Promise. */
+	next_instr = first_instr + f->f_lasti + 1;
+	stack_pointer = f->f_stacktop;
+	assert(stack_pointer != NULL);
+	f->f_stacktop = NULL;	/* remains NULL unless yield suspends frame */
+
+#ifdef LLTRACE
+	lltrace = PyDict_GetItemString(f->f_globals, "__lltrace__") != NULL;
+#endif
+#if defined(Py_DEBUG) || defined(LLTRACE)
+	filename = PyString_AsString(co->co_filename);
+#endif
+
+	why = WHY_NOT;
+	err = 0;
+	x = Py_None;	/* Not a reference, just anything non-NULL */
+	w = NULL;
+
+	if (throwflag) { /* support for generator.throw() */
+		why = WHY_EXCEPTION;
+		goto on_error;
+	}
+
+	for (;;) {
+#ifdef WITH_TSC
+		if (inst1 == 0) {
+			/* Almost surely, the opcode executed a break
+			   or a continue, preventing inst1 from being set
+			   on the way out of the loop.
+			*/
+			READ_TIMESTAMP(inst1);
+			loop1 = inst1;
+		}
+		dump_tsc(opcode, ticked, inst0, inst1, loop0, loop1,
+			 intr0, intr1);
+		ticked = 0;
+		inst1 = 0;
+		intr0 = 0;
+		intr1 = 0;
+		READ_TIMESTAMP(loop0);
+#endif
+		assert(stack_pointer >= f->f_valuestack); /* else underflow */
+		assert(STACK_LEVEL() <= co->co_stacksize);  /* else overflow */
+
+		/* Do periodic things.  Doing this every time through
+		   the loop would add too much overhead, so we do it
+		   only every Nth instruction.  We also do it if
+		   ``things_to_do'' is set, i.e. when an asynchronous
+		   event needs attention (e.g. a signal handler or
+		   async I/O handler); see Py_AddPendingCall() and
+		   Py_MakePendingCalls() above. */
+
+		if (--_Py_Ticker < 0) {
+                        if (*next_instr == SETUP_FINALLY) {
+                                /* Make the last opcode before
+                                   a try: finally: block uninterruptable. */
+                                goto fast_next_opcode;
+                        }
+			_Py_Ticker = _Py_CheckInterval;
+			tstate->tick_counter++;
+#ifdef WITH_TSC
+			ticked = 1;
+#endif
+			if (things_to_do) {
+				if (Py_MakePendingCalls() < 0) {
+					why = WHY_EXCEPTION;
+					goto on_error;
+				}
+				if (things_to_do)
+					/* MakePendingCalls() didn't succeed.
+					   Force early re-execution of this
+					   "periodic" code, possibly after
+					   a thread switch */
+					_Py_Ticker = 0;
+			}
+#ifdef WITH_THREAD
+			if (interpreter_lock) {
+				/* Give another thread a chance */
+
+				if (PyThreadState_Swap(NULL) != tstate)
+					Py_FatalError("ceval: tstate mix-up");
+				PyThread_release_lock(interpreter_lock);
+
+				/* Other threads may run now */
+
+				PyThread_acquire_lock(interpreter_lock, 1);
+				if (PyThreadState_Swap(tstate) != NULL)
+					Py_FatalError("ceval: orphan tstate");
+
+				/* Check for thread interrupts */
+
+				if (tstate->async_exc != NULL) {
+					x = tstate->async_exc;
+					tstate->async_exc = NULL;
+					PyErr_SetNone(x);
+					Py_DECREF(x);
+					why = WHY_EXCEPTION;
+					goto on_error;
+				}
+			}
+#endif
+		}
+
+	fast_next_opcode:
+		f->f_lasti = INSTR_OFFSET();
+
+		/* line-by-line tracing support */
+
+		if (tstate->c_tracefunc != NULL && !tstate->tracing) {
+			/* see maybe_call_line_trace
+			   for expository comments */
+			f->f_stacktop = stack_pointer;
+
+			err = maybe_call_line_trace(tstate->c_tracefunc,
+						    tstate->c_traceobj,
+						    f, &instr_lb, &instr_ub,
+						    &instr_prev);
+			/* Reload possibly changed frame fields */
+			JUMPTO(f->f_lasti);
+			if (f->f_stacktop != NULL) {
+				stack_pointer = f->f_stacktop;
+				f->f_stacktop = NULL;
+			}
+			if (err) {
+				/* trace function raised an exception */
+				goto on_error;
+			}
+		}
+
+		/* Extract opcode and argument */
+
+		opcode = NEXTOP();
+		oparg = 0;   /* allows oparg to be stored in a register because
+			it doesn't have to be remembered across a full loop */
+		if (HAS_ARG(opcode))
+			oparg = NEXTARG();
+	  dispatch_opcode:
+#ifdef DYNAMIC_EXECUTION_PROFILE
+#ifdef DXPAIRS
+		dxpairs[lastopcode][opcode]++;
+		lastopcode = opcode;
+#endif
+		dxp[opcode]++;
+#endif
+
+#ifdef LLTRACE
+		/* Instruction tracing */
+
+		if (lltrace) {
+			if (HAS_ARG(opcode)) {
+				printf("%d: %d, %d\n",
+				       f->f_lasti, opcode, oparg);
+			}
+			else {
+				printf("%d: %d\n",
+				       f->f_lasti, opcode);
+			}
+		}
+#endif
+
+		/* Main switch on opcode */
+		READ_TIMESTAMP(inst0);
+
+		switch (opcode) {
+
+		/* BEWARE!
+		   It is essential that any operation that fails sets either
+		   x to NULL, err to nonzero, or why to anything but WHY_NOT,
+		   and that no operation that succeeds does this! */
+
+		/* case STOP_CODE: this is an error! */
+
+		case NOP:
+			goto fast_next_opcode;
+
+		case LOAD_FAST:
+			x = GETLOCAL(oparg);
+			if (x != NULL) {
+				Py_INCREF(x);
+				PUSH(x);
+				goto fast_next_opcode;
+			}
+			format_exc_check_arg(PyExc_UnboundLocalError,
+				UNBOUNDLOCAL_ERROR_MSG,
+				PyTuple_GetItem(co->co_varnames, oparg));
+			break;
+
+		case LOAD_CONST:
+			x = GETITEM(consts, oparg);
+			Py_INCREF(x);
+			PUSH(x);
+			goto fast_next_opcode;
+
+		PREDICTED_WITH_ARG(STORE_FAST);
+		case STORE_FAST:
+			v = POP();
+			SETLOCAL(oparg, v);
+			goto fast_next_opcode;
+
+		PREDICTED(POP_TOP);
+		case POP_TOP:
+			v = POP();
+			Py_DECREF(v);
+			goto fast_next_opcode;
+
+		case ROT_TWO:
+			v = TOP();
+			w = SECOND();
+			SET_TOP(w);
+			SET_SECOND(v);
+			goto fast_next_opcode;
+
+		case ROT_THREE:
+			v = TOP();
+			w = SECOND();
+			x = THIRD();
+			SET_TOP(w);
+			SET_SECOND(x);
+			SET_THIRD(v);
+			goto fast_next_opcode;
+
+		case ROT_FOUR:
+			u = TOP();
+			v = SECOND();
+			w = THIRD();
+			x = FOURTH();
+			SET_TOP(v);
+			SET_SECOND(w);
+			SET_THIRD(x);
+			SET_FOURTH(u);
+			goto fast_next_opcode;
+
+		case DUP_TOP:
+			v = TOP();
+			Py_INCREF(v);
+			PUSH(v);
+			goto fast_next_opcode;
+
+		case DUP_TOPX:
+			if (oparg == 2) {
+				x = TOP();
+				Py_INCREF(x);
+				w = SECOND();
+				Py_INCREF(w);
+				STACKADJ(2);
+				SET_TOP(x);
+				SET_SECOND(w);
+				goto fast_next_opcode;
+			} else if (oparg == 3) {
+				x = TOP();
+				Py_INCREF(x);
+				w = SECOND();
+				Py_INCREF(w);
+				v = THIRD();
+				Py_INCREF(v);
+				STACKADJ(3);
+				SET_TOP(x);
+				SET_SECOND(w);
+				SET_THIRD(v);
+				goto fast_next_opcode;
+			}
+			Py_FatalError("invalid argument to DUP_TOPX"
+				      " (bytecode corruption?)");
+			break;
+
+		case UNARY_POSITIVE:
+			v = TOP();
+			x = PyNumber_Positive(v);
+			Py_DECREF(v);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case UNARY_NEGATIVE:
+			v = TOP();
+			x = PyNumber_Negative(v);
+			Py_DECREF(v);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case UNARY_NOT:
+			v = TOP();
+			err = PyObject_IsTrue(v);
+			Py_DECREF(v);
+			if (err == 0) {
+				Py_INCREF(Py_True);
+				SET_TOP(Py_True);
+				continue;
+			}
+			else if (err > 0) {
+				Py_INCREF(Py_False);
+				SET_TOP(Py_False);
+				err = 0;
+				continue;
+			}
+			STACKADJ(-1);
+			break;
+
+		case UNARY_CONVERT:
+			v = TOP();
+			x = PyObject_Repr(v);
+			Py_DECREF(v);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case UNARY_INVERT:
+			v = TOP();
+			x = PyNumber_Invert(v);
+			Py_DECREF(v);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case BINARY_POWER:
+			w = POP();
+			v = TOP();
+			x = PyNumber_Power(v, w, Py_None);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case BINARY_MULTIPLY:
+			w = POP();
+			v = TOP();
+			x = PyNumber_Multiply(v, w);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case BINARY_DIVIDE:
+			if (!_Py_QnewFlag) {
+				w = POP();
+				v = TOP();
+				x = PyNumber_Divide(v, w);
+				Py_DECREF(v);
+				Py_DECREF(w);
+				SET_TOP(x);
+				if (x != NULL) continue;
+				break;
+			}
+			/* -Qnew is in effect:	fall through to
+			   BINARY_TRUE_DIVIDE */
+		case BINARY_TRUE_DIVIDE:
+			w = POP();
+			v = TOP();
+			x = PyNumber_TrueDivide(v, w);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case BINARY_FLOOR_DIVIDE:
+			w = POP();
+			v = TOP();
+			x = PyNumber_FloorDivide(v, w);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case BINARY_MODULO:
+			w = POP();
+			v = TOP();
+			x = PyNumber_Remainder(v, w);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case BINARY_ADD:
+			w = POP();
+			v = TOP();
+			if (PyInt_CheckExact(v) && PyInt_CheckExact(w)) {
+				/* INLINE: int + int */
+				register long a, b, i;
+				a = PyInt_AS_LONG(v);
+				b = PyInt_AS_LONG(w);
+				i = a + b;
+				if ((i^a) < 0 && (i^b) < 0)
+					goto slow_add;
+				x = PyInt_FromLong(i);
+			}
+			else if (PyString_CheckExact(v) &&
+				 PyString_CheckExact(w)) {
+				x = string_concatenate(v, w, f, next_instr);
+				/* string_concatenate consumed the ref to v */
+				goto skip_decref_vx;
+			}
+			else {
+			  slow_add:
+				x = PyNumber_Add(v, w);
+			}
+			Py_DECREF(v);
+		  skip_decref_vx:
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case BINARY_SUBTRACT:
+			w = POP();
+			v = TOP();
+			if (PyInt_CheckExact(v) && PyInt_CheckExact(w)) {
+				/* INLINE: int - int */
+				register long a, b, i;
+				a = PyInt_AS_LONG(v);
+				b = PyInt_AS_LONG(w);
+				i = a - b;
+				if ((i^a) < 0 && (i^~b) < 0)
+					goto slow_sub;
+				x = PyInt_FromLong(i);
+			}
+			else {
+			  slow_sub:
+				x = PyNumber_Subtract(v, w);
+			}
+			Py_DECREF(v);
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case BINARY_SUBSCR:
+			w = POP();
+			v = TOP();
+			if (PyList_CheckExact(v) && PyInt_CheckExact(w)) {
+				/* INLINE: list[int] */
+				Py_ssize_t i = PyInt_AsSsize_t(w);
+				if (i < 0)
+					i += PyList_GET_SIZE(v);
+				if (i >= 0 && i < PyList_GET_SIZE(v)) {
+					x = PyList_GET_ITEM(v, i);
+					Py_INCREF(x);
+				}
+				else
+					goto slow_get;
+			}
+			else
+			  slow_get:
+				x = PyObject_GetItem(v, w);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case BINARY_LSHIFT:
+			w = POP();
+			v = TOP();
+			x = PyNumber_Lshift(v, w);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case BINARY_RSHIFT:
+			w = POP();
+			v = TOP();
+			x = PyNumber_Rshift(v, w);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case BINARY_AND:
+			w = POP();
+			v = TOP();
+			x = PyNumber_And(v, w);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case BINARY_XOR:
+			w = POP();
+			v = TOP();
+			x = PyNumber_Xor(v, w);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case BINARY_OR:
+			w = POP();
+			v = TOP();
+			x = PyNumber_Or(v, w);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case LIST_APPEND:
+			w = POP();
+			v = POP();
+			err = PyList_Append(v, w);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			if (err == 0) {
+				PREDICT(JUMP_ABSOLUTE);
+				continue;
+			}
+			break;
+
+		case INPLACE_POWER:
+			w = POP();
+			v = TOP();
+			x = PyNumber_InPlacePower(v, w, Py_None);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case INPLACE_MULTIPLY:
+			w = POP();
+			v = TOP();
+			x = PyNumber_InPlaceMultiply(v, w);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case INPLACE_DIVIDE:
+			if (!_Py_QnewFlag) {
+				w = POP();
+				v = TOP();
+				x = PyNumber_InPlaceDivide(v, w);
+				Py_DECREF(v);
+				Py_DECREF(w);
+				SET_TOP(x);
+				if (x != NULL) continue;
+				break;
+			}
+			/* -Qnew is in effect:	fall through to
+			   INPLACE_TRUE_DIVIDE */
+		case INPLACE_TRUE_DIVIDE:
+			w = POP();
+			v = TOP();
+			x = PyNumber_InPlaceTrueDivide(v, w);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case INPLACE_FLOOR_DIVIDE:
+			w = POP();
+			v = TOP();
+			x = PyNumber_InPlaceFloorDivide(v, w);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case INPLACE_MODULO:
+			w = POP();
+			v = TOP();
+			x = PyNumber_InPlaceRemainder(v, w);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case INPLACE_ADD:
+			w = POP();
+			v = TOP();
+			if (PyInt_CheckExact(v) && PyInt_CheckExact(w)) {
+				/* INLINE: int + int */
+				register long a, b, i;
+				a = PyInt_AS_LONG(v);
+				b = PyInt_AS_LONG(w);
+				i = a + b;
+				if ((i^a) < 0 && (i^b) < 0)
+					goto slow_iadd;
+				x = PyInt_FromLong(i);
+			}
+			else if (PyString_CheckExact(v) &&
+				 PyString_CheckExact(w)) {
+				x = string_concatenate(v, w, f, next_instr);
+				/* string_concatenate consumed the ref to v */
+				goto skip_decref_v;
+			}
+			else {
+			  slow_iadd:
+				x = PyNumber_InPlaceAdd(v, w);
+			}
+			Py_DECREF(v);
+		  skip_decref_v:
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case INPLACE_SUBTRACT:
+			w = POP();
+			v = TOP();
+			if (PyInt_CheckExact(v) && PyInt_CheckExact(w)) {
+				/* INLINE: int - int */
+				register long a, b, i;
+				a = PyInt_AS_LONG(v);
+				b = PyInt_AS_LONG(w);
+				i = a - b;
+				if ((i^a) < 0 && (i^~b) < 0)
+					goto slow_isub;
+				x = PyInt_FromLong(i);
+			}
+			else {
+			  slow_isub:
+				x = PyNumber_InPlaceSubtract(v, w);
+			}
+			Py_DECREF(v);
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case INPLACE_LSHIFT:
+			w = POP();
+			v = TOP();
+			x = PyNumber_InPlaceLshift(v, w);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case INPLACE_RSHIFT:
+			w = POP();
+			v = TOP();
+			x = PyNumber_InPlaceRshift(v, w);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case INPLACE_AND:
+			w = POP();
+			v = TOP();
+			x = PyNumber_InPlaceAnd(v, w);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case INPLACE_XOR:
+			w = POP();
+			v = TOP();
+			x = PyNumber_InPlaceXor(v, w);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case INPLACE_OR:
+			w = POP();
+			v = TOP();
+			x = PyNumber_InPlaceOr(v, w);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case SLICE+0:
+		case SLICE+1:
+		case SLICE+2:
+		case SLICE+3:
+			if ((opcode-SLICE) & 2)
+				w = POP();
+			else
+				w = NULL;
+			if ((opcode-SLICE) & 1)
+				v = POP();
+			else
+				v = NULL;
+			u = TOP();
+			x = apply_slice(u, v, w);
+			Py_DECREF(u);
+			Py_XDECREF(v);
+			Py_XDECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case STORE_SLICE+0:
+		case STORE_SLICE+1:
+		case STORE_SLICE+2:
+		case STORE_SLICE+3:
+			if ((opcode-STORE_SLICE) & 2)
+				w = POP();
+			else
+				w = NULL;
+			if ((opcode-STORE_SLICE) & 1)
+				v = POP();
+			else
+				v = NULL;
+			u = POP();
+			t = POP();
+			err = assign_slice(u, v, w, t); /* u[v:w] = t */
+			Py_DECREF(t);
+			Py_DECREF(u);
+			Py_XDECREF(v);
+			Py_XDECREF(w);
+			if (err == 0) continue;
+			break;
+
+		case DELETE_SLICE+0:
+		case DELETE_SLICE+1:
+		case DELETE_SLICE+2:
+		case DELETE_SLICE+3:
+			if ((opcode-DELETE_SLICE) & 2)
+				w = POP();
+			else
+				w = NULL;
+			if ((opcode-DELETE_SLICE) & 1)
+				v = POP();
+			else
+				v = NULL;
+			u = POP();
+			err = assign_slice(u, v, w, (PyObject *)NULL);
+							/* del u[v:w] */
+			Py_DECREF(u);
+			Py_XDECREF(v);
+			Py_XDECREF(w);
+			if (err == 0) continue;
+			break;
+
+		case STORE_SUBSCR:
+			w = TOP();
+			v = SECOND();
+			u = THIRD();
+			STACKADJ(-3);
+			/* v[w] = u */
+			err = PyObject_SetItem(v, w, u);
+			Py_DECREF(u);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			if (err == 0) continue;
+			break;
+
+		case DELETE_SUBSCR:
+			w = TOP();
+			v = SECOND();
+			STACKADJ(-2);
+			/* del v[w] */
+			err = PyObject_DelItem(v, w);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			if (err == 0) continue;
+			break;
+
+		case PRINT_EXPR:
+			v = POP();
+			w = PySys_GetObject("displayhook");
+			if (w == NULL) {
+				PyErr_SetString(PyExc_RuntimeError,
+						"lost sys.displayhook");
+				err = -1;
+				x = NULL;
+			}
+			if (err == 0) {
+				x = PyTuple_Pack(1, v);
+				if (x == NULL)
+					err = -1;
+			}
+			if (err == 0) {
+				w = PyEval_CallObject(w, x);
+				Py_XDECREF(w);
+				if (w == NULL)
+					err = -1;
+			}
+			Py_DECREF(v);
+			Py_XDECREF(x);
+			break;
+
+		case PRINT_ITEM_TO:
+			w = stream = POP();
+			/* fall through to PRINT_ITEM */
+
+		case PRINT_ITEM:
+			v = POP();
+			if (stream == NULL || stream == Py_None) {
+				w = PySys_GetObject("stdout");
+				if (w == NULL) {
+					PyErr_SetString(PyExc_RuntimeError,
+							"lost sys.stdout");
+					err = -1;
+				}
+			}
+			/* PyFile_SoftSpace() can exececute arbitrary code
+			   if sys.stdout is an instance with a __getattr__.
+			   If __getattr__ raises an exception, w will
+			   be freed, so we need to prevent that temporarily. */
+			Py_XINCREF(w);
+			if (w != NULL && PyFile_SoftSpace(w, 0))
+				err = PyFile_WriteString(" ", w);
+			if (err == 0)
+				err = PyFile_WriteObject(v, w, Py_PRINT_RAW);
+			if (err == 0) {
+			    /* XXX move into writeobject() ? */
+			    if (PyString_Check(v)) {
+				char *s = PyString_AS_STRING(v);
+				Py_ssize_t len = PyString_GET_SIZE(v);
+				if (len == 0 ||
+				    !isspace(Py_CHARMASK(s[len-1])) ||
+				    s[len-1] == ' ')
+					PyFile_SoftSpace(w, 1);
+			    }
+#ifdef Py_USING_UNICODE
+			    else if (PyUnicode_Check(v)) {
+				Py_UNICODE *s = PyUnicode_AS_UNICODE(v);
+				Py_ssize_t len = PyUnicode_GET_SIZE(v);
+				if (len == 0 ||
+				    !Py_UNICODE_ISSPACE(s[len-1]) ||
+				    s[len-1] == ' ')
+				    PyFile_SoftSpace(w, 1);
+			    }
+#endif
+			    else
+			    	PyFile_SoftSpace(w, 1);
+			}
+			Py_XDECREF(w);
+			Py_DECREF(v);
+			Py_XDECREF(stream);
+			stream = NULL;
+			if (err == 0)
+				continue;
+			break;
+
+		case PRINT_NEWLINE_TO:
+			w = stream = POP();
+			/* fall through to PRINT_NEWLINE */
+
+		case PRINT_NEWLINE:
+			if (stream == NULL || stream == Py_None) {
+				w = PySys_GetObject("stdout");
+				if (w == NULL)
+					PyErr_SetString(PyExc_RuntimeError,
+							"lost sys.stdout");
+			}
+			if (w != NULL) {
+				err = PyFile_WriteString("\n", w);
+				if (err == 0)
+					PyFile_SoftSpace(w, 0);
+			}
+			Py_XDECREF(stream);
+			stream = NULL;
+			break;
+
+
+#ifdef CASE_TOO_BIG
+		default: switch (opcode) {
+#endif
+		case RAISE_VARARGS:
+			u = v = w = NULL;
+			switch (oparg) {
+			case 3:
+				u = POP(); /* traceback */
+				/* Fallthrough */
+			case 2:
+				v = POP(); /* value */
+				/* Fallthrough */
+			case 1:
+				w = POP(); /* exc */
+			case 0: /* Fallthrough */
+				why = do_raise(w, v, u);
+				break;
+			default:
+				PyErr_SetString(PyExc_SystemError,
+					   "bad RAISE_VARARGS oparg");
+				why = WHY_EXCEPTION;
+				break;
+			}
+			break;
+
+		case LOAD_LOCALS:
+			if ((x = f->f_locals) != NULL) {
+				Py_INCREF(x);
+				PUSH(x);
+				continue;
+			}
+			PyErr_SetString(PyExc_SystemError, "no locals");
+			break;
+
+		case RETURN_VALUE:
+			retval = POP();
+			why = WHY_RETURN;
+			goto fast_block_end;
+
+		case YIELD_VALUE:
+			retval = POP();
+			f->f_stacktop = stack_pointer;
+			why = WHY_YIELD;
+			goto fast_yield;
+
+		case EXEC_STMT:
+			w = TOP();
+			v = SECOND();
+			u = THIRD();
+			STACKADJ(-3);
+			READ_TIMESTAMP(intr0);
+			err = exec_statement(f, u, v, w);
+			READ_TIMESTAMP(intr1);
+			Py_DECREF(u);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			break;
+
+		case POP_BLOCK:
+			{
+				PyTryBlock *b = PyFrame_BlockPop(f);
+				while (STACK_LEVEL() > b->b_level) {
+					v = POP();
+					Py_DECREF(v);
+				}
+			}
+			continue;
+
+		case END_FINALLY:
+			v = POP();
+			if (PyInt_Check(v)) {
+				why = (enum why_code) PyInt_AS_LONG(v);
+				assert(why != WHY_YIELD);
+				if (why == WHY_RETURN ||
+				    why == WHY_CONTINUE)
+					retval = POP();
+			}
+			else if (PyExceptionClass_Check(v) || PyString_Check(v)) {
+				w = POP();
+				u = POP();
+				PyErr_Restore(v, w, u);
+				why = WHY_RERAISE;
+				break;
+			}
+			else if (v != Py_None) {
+				PyErr_SetString(PyExc_SystemError,
+					"'finally' pops bad exception");
+				why = WHY_EXCEPTION;
+			}
+			Py_DECREF(v);
+			break;
+
+		case BUILD_CLASS:
+			u = TOP();
+			v = SECOND();
+			w = THIRD();
+			STACKADJ(-2);
+			x = build_class(u, v, w);
+			SET_TOP(x);
+			Py_DECREF(u);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			break;
+
+		case STORE_NAME:
+			w = GETITEM(names, oparg);
+			v = POP();
+			if ((x = f->f_locals) != NULL) {
+				if (PyDict_CheckExact(x))
+					err = PyDict_SetItem(x, w, v);
+				else
+					err = PyObject_SetItem(x, w, v);
+				Py_DECREF(v);
+				if (err == 0) continue;
+				break;
+			}
+			PyErr_Format(PyExc_SystemError,
+				     "no locals found when storing %s",
+				     PyObject_REPR(w));
+			break;
+
+		case DELETE_NAME:
+			w = GETITEM(names, oparg);
+			if ((x = f->f_locals) != NULL) {
+				if ((err = PyObject_DelItem(x, w)) != 0)
+					format_exc_check_arg(PyExc_NameError,
+								NAME_ERROR_MSG ,w);
+				break;
+			}
+			PyErr_Format(PyExc_SystemError,
+				     "no locals when deleting %s",
+				     PyObject_REPR(w));
+			break;
+
+		PREDICTED_WITH_ARG(UNPACK_SEQUENCE);
+		case UNPACK_SEQUENCE:
+			v = POP();
+			if (PyTuple_CheckExact(v) && PyTuple_GET_SIZE(v) == oparg) {
+				PyObject **items = ((PyTupleObject *)v)->ob_item;
+				while (oparg--) {
+					w = items[oparg];
+					Py_INCREF(w);
+					PUSH(w);
+				}
+				Py_DECREF(v);
+				continue;
+			} else if (PyList_CheckExact(v) && PyList_GET_SIZE(v) == oparg) {
+				PyObject **items = ((PyListObject *)v)->ob_item;
+				while (oparg--) {
+					w = items[oparg];
+					Py_INCREF(w);
+					PUSH(w);
+				}
+			} else if (unpack_iterable(v, oparg,
+						 stack_pointer + oparg)) {
+				stack_pointer += oparg;
+			} else {
+				/* unpack_iterable() raised an exception */
+				why = WHY_EXCEPTION;
+			}
+			Py_DECREF(v);
+			break;
+
+		case STORE_ATTR:
+			w = GETITEM(names, oparg);
+			v = TOP();
+			u = SECOND();
+			STACKADJ(-2);
+			err = PyObject_SetAttr(v, w, u); /* v.w = u */
+			Py_DECREF(v);
+			Py_DECREF(u);
+			if (err == 0) continue;
+			break;
+
+		case DELETE_ATTR:
+			w = GETITEM(names, oparg);
+			v = POP();
+			err = PyObject_SetAttr(v, w, (PyObject *)NULL);
+							/* del v.w */
+			Py_DECREF(v);
+			break;
+
+		case STORE_GLOBAL:
+			w = GETITEM(names, oparg);
+			v = POP();
+			err = PyDict_SetItem(f->f_globals, w, v);
+			Py_DECREF(v);
+			if (err == 0) continue;
+			break;
+
+		case DELETE_GLOBAL:
+			w = GETITEM(names, oparg);
+			if ((err = PyDict_DelItem(f->f_globals, w)) != 0)
+				format_exc_check_arg(
+				    PyExc_NameError, GLOBAL_NAME_ERROR_MSG, w);
+			break;
+
+		case LOAD_NAME:
+			w = GETITEM(names, oparg);
+			if ((v = f->f_locals) == NULL) {
+				PyErr_Format(PyExc_SystemError,
+					     "no locals when loading %s",
+					     PyObject_REPR(w));
+				break;
+			}
+			if (PyDict_CheckExact(v)) {
+				x = PyDict_GetItem(v, w);
+				Py_XINCREF(x);
+			}
+			else {
+				x = PyObject_GetItem(v, w);
+				if (x == NULL && PyErr_Occurred()) {
+					if (!PyErr_ExceptionMatches(PyExc_KeyError))
+						break;
+					PyErr_Clear();
+				}
+			}
+			if (x == NULL) {
+				x = PyDict_GetItem(f->f_globals, w);
+				if (x == NULL) {
+					x = PyDict_GetItem(f->f_builtins, w);
+					if (x == NULL) {
+						format_exc_check_arg(
+							    PyExc_NameError,
+							    NAME_ERROR_MSG ,w);
+						break;
+					}
+				}
+				Py_INCREF(x);
+			}
+			PUSH(x);
+			continue;
+
+		case LOAD_GLOBAL:
+			w = GETITEM(names, oparg);
+			if (PyString_CheckExact(w)) {
+				/* Inline the PyDict_GetItem() calls.
+				   WARNING: this is an extreme speed hack.
+				   Do not try this at home. */
+				long hash = ((PyStringObject *)w)->ob_shash;
+				if (hash != -1) {
+					PyDictObject *d;
+					PyDictEntry *e;
+					d = (PyDictObject *)(f->f_globals);
+					e = d->ma_lookup(d, w, hash);
+					if (e == NULL) {
+						x = NULL;
+						break;
+					}
+					x = e->me_value;
+					if (x != NULL) {
+						Py_INCREF(x);
+						PUSH(x);
+						continue;
+					}
+					d = (PyDictObject *)(f->f_builtins);
+					e = d->ma_lookup(d, w, hash);
+					if (e == NULL) {
+						x = NULL;
+						break;
+					}
+					x = e->me_value;
+					if (x != NULL) {
+						Py_INCREF(x);
+						PUSH(x);
+						continue;
+					}
+					goto load_global_error;
+				}
+			}
+			/* This is the un-inlined version of the code above */
+			x = PyDict_GetItem(f->f_globals, w);
+			if (x == NULL) {
+				x = PyDict_GetItem(f->f_builtins, w);
+				if (x == NULL) {
+				  load_global_error:
+					format_exc_check_arg(
+						    PyExc_NameError,
+						    GLOBAL_NAME_ERROR_MSG, w);
+					break;
+				}
+			}
+			Py_INCREF(x);
+			PUSH(x);
+			continue;
+
+		case DELETE_FAST:
+			x = GETLOCAL(oparg);
+			if (x != NULL) {
+				SETLOCAL(oparg, NULL);
+				continue;
+			}
+			format_exc_check_arg(
+				PyExc_UnboundLocalError,
+				UNBOUNDLOCAL_ERROR_MSG,
+				PyTuple_GetItem(co->co_varnames, oparg)
+				);
+			break;
+
+		case LOAD_CLOSURE:
+			x = freevars[oparg];
+			Py_INCREF(x);
+			PUSH(x);
+			if (x != NULL) continue;
+			break;
+
+		case LOAD_DEREF:
+			x = freevars[oparg];
+			w = PyCell_Get(x);
+			if (w != NULL) {
+				PUSH(w);
+				continue;
+			}
+			err = -1;
+			/* Don't stomp existing exception */
+			if (PyErr_Occurred())
+				break;
+			if (oparg < PyTuple_GET_SIZE(co->co_cellvars)) {
+				v = PyTuple_GET_ITEM(co->co_cellvars,
+						       oparg);
+			       format_exc_check_arg(
+				       PyExc_UnboundLocalError,
+				       UNBOUNDLOCAL_ERROR_MSG,
+				       v);
+			} else {
+			       v = PyTuple_GET_ITEM(
+					      co->co_freevars,
+					      oparg - PyTuple_GET_SIZE(co->co_cellvars));
+			       format_exc_check_arg(
+				       PyExc_NameError,
+				       UNBOUNDFREE_ERROR_MSG,
+				       v);
+			}
+			break;
+
+		case STORE_DEREF:
+			w = POP();
+			x = freevars[oparg];
+			PyCell_Set(x, w);
+			Py_DECREF(w);
+			continue;
+
+		case BUILD_TUPLE:
+			x = PyTuple_New(oparg);
+			if (x != NULL) {
+				for (; --oparg >= 0;) {
+					w = POP();
+					PyTuple_SET_ITEM(x, oparg, w);
+				}
+				PUSH(x);
+				continue;
+			}
+			break;
+
+		case BUILD_LIST:
+			x =  PyList_New(oparg);
+			if (x != NULL) {
+				for (; --oparg >= 0;) {
+					w = POP();
+					PyList_SET_ITEM(x, oparg, w);
+				}
+				PUSH(x);
+				continue;
+			}
+			break;
+
+		case BUILD_MAP:
+			x = PyDict_New();
+			PUSH(x);
+			if (x != NULL) continue;
+			break;
+
+		case LOAD_ATTR:
+			w = GETITEM(names, oparg);
+			v = TOP();
+			x = PyObject_GetAttr(v, w);
+			Py_DECREF(v);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case COMPARE_OP:
+			w = POP();
+			v = TOP();
+			if (PyInt_CheckExact(w) && PyInt_CheckExact(v)) {
+				/* INLINE: cmp(int, int) */
+				register long a, b;
+				register int res;
+				a = PyInt_AS_LONG(v);
+				b = PyInt_AS_LONG(w);
+				switch (oparg) {
+				case PyCmp_LT: res = a <  b; break;
+				case PyCmp_LE: res = a <= b; break;
+				case PyCmp_EQ: res = a == b; break;
+				case PyCmp_NE: res = a != b; break;
+				case PyCmp_GT: res = a >  b; break;
+				case PyCmp_GE: res = a >= b; break;
+				case PyCmp_IS: res = v == w; break;
+				case PyCmp_IS_NOT: res = v != w; break;
+				default: goto slow_compare;
+				}
+				x = res ? Py_True : Py_False;
+				Py_INCREF(x);
+			}
+			else {
+			  slow_compare:
+				x = cmp_outcome(oparg, v, w);
+			}
+			Py_DECREF(v);
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x == NULL) break;
+			PREDICT(JUMP_IF_FALSE);
+			PREDICT(JUMP_IF_TRUE);
+			continue;
+
+		case IMPORT_NAME:
+			w = GETITEM(names, oparg);
+			x = PyDict_GetItemString(f->f_builtins, "__import__");
+			if (x == NULL) {
+				PyErr_SetString(PyExc_ImportError,
+						"__import__ not found");
+				break;
+			}
+			v = POP();
+			u = TOP();
+			if (PyInt_AsLong(u) != -1 || PyErr_Occurred())
+				w = PyTuple_Pack(5,
+					    w,
+					    f->f_globals,
+					    f->f_locals == NULL ?
+						  Py_None : f->f_locals,
+					    v,
+					    u);
+			else
+				w = PyTuple_Pack(4,
+					    w,
+					    f->f_globals,
+					    f->f_locals == NULL ?
+						  Py_None : f->f_locals,
+					    v);
+			Py_DECREF(v);
+			Py_DECREF(u);
+			if (w == NULL) {
+				u = POP();
+				x = NULL;
+				break;
+			}
+			READ_TIMESTAMP(intr0);
+			x = PyEval_CallObject(x, w);
+			READ_TIMESTAMP(intr1);
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case IMPORT_STAR:
+			v = POP();
+			PyFrame_FastToLocals(f);
+			if ((x = f->f_locals) == NULL) {
+				PyErr_SetString(PyExc_SystemError,
+					"no locals found during 'import *'");
+				break;
+			}
+			READ_TIMESTAMP(intr0);
+			err = import_all_from(x, v);
+			READ_TIMESTAMP(intr1);
+			PyFrame_LocalsToFast(f, 0);
+			Py_DECREF(v);
+			if (err == 0) continue;
+			break;
+
+		case IMPORT_FROM:
+			w = GETITEM(names, oparg);
+			v = TOP();
+			READ_TIMESTAMP(intr0);
+			x = import_from(v, w);
+			READ_TIMESTAMP(intr1);
+			PUSH(x);
+			if (x != NULL) continue;
+			break;
+
+		case JUMP_FORWARD:
+			JUMPBY(oparg);
+			goto fast_next_opcode;
+
+		PREDICTED_WITH_ARG(JUMP_IF_FALSE);
+		case JUMP_IF_FALSE:
+			w = TOP();
+			if (w == Py_True) {
+				PREDICT(POP_TOP);
+				goto fast_next_opcode;
+			}
+			if (w == Py_False) {
+				JUMPBY(oparg);
+				goto fast_next_opcode;
+			}
+			err = PyObject_IsTrue(w);
+			if (err > 0)
+				err = 0;
+			else if (err == 0)
+				JUMPBY(oparg);
+			else
+				break;
+			continue;
+
+		PREDICTED_WITH_ARG(JUMP_IF_TRUE);
+		case JUMP_IF_TRUE:
+			w = TOP();
+			if (w == Py_False) {
+				PREDICT(POP_TOP);
+				goto fast_next_opcode;
+			}
+			if (w == Py_True) {
+				JUMPBY(oparg);
+				goto fast_next_opcode;
+			}
+			err = PyObject_IsTrue(w);
+			if (err > 0) {
+				err = 0;
+				JUMPBY(oparg);
+			}
+			else if (err == 0)
+				;
+			else
+				break;
+			continue;
+
+		PREDICTED_WITH_ARG(JUMP_ABSOLUTE);
+		case JUMP_ABSOLUTE:
+			JUMPTO(oparg);
+			continue;
+
+		case GET_ITER:
+			/* before: [obj]; after [getiter(obj)] */
+			v = TOP();
+			x = PyObject_GetIter(v);
+			Py_DECREF(v);
+			if (x != NULL) {
+				SET_TOP(x);
+				PREDICT(FOR_ITER);
+				continue;
+			}
+			STACKADJ(-1);
+			break;
+
+		PREDICTED_WITH_ARG(FOR_ITER);
+		case FOR_ITER:
+			/* before: [iter]; after: [iter, iter()] *or* [] */
+			v = TOP();
+			x = (*v->ob_type->tp_iternext)(v);
+			if (x != NULL) {
+				PUSH(x);
+				PREDICT(STORE_FAST);
+				PREDICT(UNPACK_SEQUENCE);
+				continue;
+			}
+			if (PyErr_Occurred()) {
+				if (!PyErr_ExceptionMatches(PyExc_StopIteration))
+					break;
+				PyErr_Clear();
+			}
+			/* iterator ended normally */
+ 			x = v = POP();
+			Py_DECREF(v);
+			JUMPBY(oparg);
+			continue;
+
+		case BREAK_LOOP:
+			why = WHY_BREAK;
+			goto fast_block_end;
+
+		case CONTINUE_LOOP:
+			retval = PyInt_FromLong(oparg);
+			if (!retval) {
+				x = NULL;
+				break;
+			}
+			why = WHY_CONTINUE;
+			goto fast_block_end;
+
+		case SETUP_LOOP:
+		case SETUP_EXCEPT:
+		case SETUP_FINALLY:
+			/* NOTE: If you add any new block-setup opcodes that are not try/except/finally
+			   handlers, you may need to update the PyGen_NeedsFinalizing() function. */
+
+			PyFrame_BlockSetup(f, opcode, INSTR_OFFSET() + oparg,
+					   STACK_LEVEL());
+			continue;
+
+		case WITH_CLEANUP:
+		{
+			/* TOP is the context.__exit__ bound method.
+			   Below that are 1-3 values indicating how/why
+			   we entered the finally clause:
+			   - SECOND = None
+			   - (SECOND, THIRD) = (WHY_{RETURN,CONTINUE}), retval
+			   - SECOND = WHY_*; no retval below it
+			   - (SECOND, THIRD, FOURTH) = exc_info()
+			   In the last case, we must call
+			     TOP(SECOND, THIRD, FOURTH)
+			   otherwise we must call
+			     TOP(None, None, None)
+
+			   In addition, if the stack represents an exception,
+			   *and* the function call returns a 'true' value, we
+			   "zap" this information, to prevent END_FINALLY from
+			   re-raising the exception.  (But non-local gotos
+			   should still be resumed.)
+			*/
+
+			x = TOP();
+			u = SECOND();
+			if (PyInt_Check(u) || u == Py_None) {
+				u = v = w = Py_None;
+			}
+			else {
+				v = THIRD();
+				w = FOURTH();
+			}
+			/* XXX Not the fastest way to call it... */
+			x = PyObject_CallFunctionObjArgs(x, u, v, w, NULL);
+			if (x == NULL)
+				break; /* Go to error exit */
+			if (u != Py_None && PyObject_IsTrue(x)) {
+				/* There was an exception and a true return */
+				Py_DECREF(x);
+				x = TOP(); /* Again */
+				STACKADJ(-3);
+				Py_INCREF(Py_None);
+				SET_TOP(Py_None);
+				Py_DECREF(x);
+				Py_DECREF(u);
+				Py_DECREF(v);
+				Py_DECREF(w);
+			} else {
+				/* Let END_FINALLY do its thing */
+				Py_DECREF(x);
+				x = POP();
+				Py_DECREF(x);
+			}
+			break;
+		}
+
+		case CALL_FUNCTION:
+		{
+			PyObject **sp;
+			PCALL(PCALL_ALL);
+			sp = stack_pointer;
+#ifdef WITH_TSC
+			x = call_function(&sp, oparg, &intr0, &intr1);
+#else
+			x = call_function(&sp, oparg);
+#endif
+			stack_pointer = sp;
+			PUSH(x);
+			if (x != NULL)
+				continue;
+			break;
+		}
+
+		case CALL_FUNCTION_VAR:
+		case CALL_FUNCTION_KW:
+		case CALL_FUNCTION_VAR_KW:
+		{
+		    int na = oparg & 0xff;
+		    int nk = (oparg>>8) & 0xff;
+		    int flags = (opcode - CALL_FUNCTION) & 3;
+		    int n = na + 2 * nk;
+		    PyObject **pfunc, *func, **sp;
+		    PCALL(PCALL_ALL);
+		    if (flags & CALL_FLAG_VAR)
+			    n++;
+		    if (flags & CALL_FLAG_KW)
+			    n++;
+		    pfunc = stack_pointer - n - 1;
+		    func = *pfunc;
+
+		    if (PyMethod_Check(func)
+			&& PyMethod_GET_SELF(func) != NULL) {
+			    PyObject *self = PyMethod_GET_SELF(func);
+			    Py_INCREF(self);
+			    func = PyMethod_GET_FUNCTION(func);
+			    Py_INCREF(func);
+			    Py_DECREF(*pfunc);
+			    *pfunc = self;
+			    na++;
+			    n++;
+		    } else
+			    Py_INCREF(func);
+		    sp = stack_pointer;
+		    READ_TIMESTAMP(intr0);
+		    x = ext_do_call(func, &sp, flags, na, nk);
+		    READ_TIMESTAMP(intr1);
+		    stack_pointer = sp;
+		    Py_DECREF(func);
+
+		    while (stack_pointer > pfunc) {
+			    w = POP();
+			    Py_DECREF(w);
+		    }
+		    PUSH(x);
+		    if (x != NULL)
+			    continue;
+		    break;
+		}
+
+		case MAKE_FUNCTION:
+			v = POP(); /* code object */
+			x = PyFunction_New(v, f->f_globals);
+			Py_DECREF(v);
+			/* XXX Maybe this should be a separate opcode? */
+			if (x != NULL && oparg > 0) {
+				v = PyTuple_New(oparg);
+				if (v == NULL) {
+					Py_DECREF(x);
+					x = NULL;
+					break;
+				}
+				while (--oparg >= 0) {
+					w = POP();
+					PyTuple_SET_ITEM(v, oparg, w);
+				}
+				err = PyFunction_SetDefaults(x, v);
+				Py_DECREF(v);
+			}
+			PUSH(x);
+			break;
+
+		case MAKE_CLOSURE:
+		{
+			v = POP(); /* code object */
+			x = PyFunction_New(v, f->f_globals);
+			Py_DECREF(v);
+			if (x != NULL) {
+				v = POP();
+				err = PyFunction_SetClosure(x, v);
+				Py_DECREF(v);
+			}
+			if (x != NULL && oparg > 0) {
+				v = PyTuple_New(oparg);
+				if (v == NULL) {
+					Py_DECREF(x);
+					x = NULL;
+					break;
+				}
+				while (--oparg >= 0) {
+					w = POP();
+					PyTuple_SET_ITEM(v, oparg, w);
+				}
+				err = PyFunction_SetDefaults(x, v);
+				Py_DECREF(v);
+			}
+			PUSH(x);
+			break;
+		}
+
+		case BUILD_SLICE:
+			if (oparg == 3)
+				w = POP();
+			else
+				w = NULL;
+			v = POP();
+			u = TOP();
+			x = PySlice_New(u, v, w);
+			Py_DECREF(u);
+			Py_DECREF(v);
+			Py_XDECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case EXTENDED_ARG:
+			opcode = NEXTOP();
+			oparg = oparg<<16 | NEXTARG();
+			goto dispatch_opcode;
+
+		default:
+			fprintf(stderr,
+				"XXX lineno: %d, opcode: %d\n",
+				PyCode_Addr2Line(f->f_code, f->f_lasti),
+				opcode);
+			PyErr_SetString(PyExc_SystemError, "unknown opcode");
+			why = WHY_EXCEPTION;
+			break;
+
+#ifdef CASE_TOO_BIG
+		}
+#endif
+
+		} /* switch */
+
+	    on_error:
+
+		READ_TIMESTAMP(inst1);
+
+		/* Quickly continue if no error occurred */
+
+		if (why == WHY_NOT) {
+			if (err == 0 && x != NULL) {
+#ifdef CHECKEXC
+				/* This check is expensive! */
+				if (PyErr_Occurred())
+					fprintf(stderr,
+						"XXX undetected error\n");
+				else {
+#endif
+					READ_TIMESTAMP(loop1);
+					continue; /* Normal, fast path */
+#ifdef CHECKEXC
+				}
+#endif
+			}
+			why = WHY_EXCEPTION;
+			x = Py_None;
+			err = 0;
+		}
+
+		/* Double-check exception status */
+
+		if (why == WHY_EXCEPTION || why == WHY_RERAISE) {
+			if (!PyErr_Occurred()) {
+				PyErr_SetString(PyExc_SystemError,
+					"error return without exception set");
+				why = WHY_EXCEPTION;
+			}
+		}
+#ifdef CHECKEXC
+		else {
+			/* This check is expensive! */
+			if (PyErr_Occurred()) {
+				char buf[1024];
+				sprintf(buf, "Stack unwind with exception "
+					"set and why=%d", why);
+				Py_FatalError(buf);
+			}
+		}
+#endif
+
+		/* Log traceback info if this is a real exception */
+
+		if (why == WHY_EXCEPTION) {
+			PyTraceBack_Here(f);
+
+			if (tstate->c_tracefunc != NULL)
+				call_exc_trace(tstate->c_tracefunc,
+					       tstate->c_traceobj, f);
+		}
+
+		/* For the rest, treat WHY_RERAISE as WHY_EXCEPTION */
+
+		if (why == WHY_RERAISE)
+			why = WHY_EXCEPTION;
+
+		/* Unwind stacks if a (pseudo) exception occurred */
+
+fast_block_end:
+		while (why != WHY_NOT && f->f_iblock > 0) {
+			PyTryBlock *b = PyFrame_BlockPop(f);
+
+			assert(why != WHY_YIELD);
+			if (b->b_type == SETUP_LOOP && why == WHY_CONTINUE) {
+				/* For a continue inside a try block,
+				   don't pop the block for the loop. */
+				PyFrame_BlockSetup(f, b->b_type, b->b_handler,
+						   b->b_level);
+				why = WHY_NOT;
+				JUMPTO(PyInt_AS_LONG(retval));
+				Py_DECREF(retval);
+				break;
+			}
+
+			while (STACK_LEVEL() > b->b_level) {
+				v = POP();
+				Py_XDECREF(v);
+			}
+			if (b->b_type == SETUP_LOOP && why == WHY_BREAK) {
+				why = WHY_NOT;
+				JUMPTO(b->b_handler);
+				break;
+			}
+			if (b->b_type == SETUP_FINALLY ||
+			    (b->b_type == SETUP_EXCEPT &&
+			     why == WHY_EXCEPTION)) {
+				if (why == WHY_EXCEPTION) {
+					PyObject *exc, *val, *tb;
+					PyErr_Fetch(&exc, &val, &tb);
+					if (val == NULL) {
+						val = Py_None;
+						Py_INCREF(val);
+					}
+					/* Make the raw exception data
+					   available to the handler,
+					   so a program can emulate the
+					   Python main loop.  Don't do
+					   this for 'finally'. */
+					if (b->b_type == SETUP_EXCEPT) {
+						PyErr_NormalizeException(
+							&exc, &val, &tb);
+						set_exc_info(tstate,
+							     exc, val, tb);
+					}
+					if (tb == NULL) {
+						Py_INCREF(Py_None);
+						PUSH(Py_None);
+					} else
+						PUSH(tb);
+					PUSH(val);
+					PUSH(exc);
+				}
+				else {
+					if (why & (WHY_RETURN | WHY_CONTINUE))
+						PUSH(retval);
+					v = PyInt_FromLong((long)why);
+					PUSH(v);
+				}
+				why = WHY_NOT;
+				JUMPTO(b->b_handler);
+				break;
+			}
+		} /* unwind stack */
+
+		/* End the loop if we still have an error (or return) */
+
+		if (why != WHY_NOT)
+			break;
+		READ_TIMESTAMP(loop1);
+
+	} /* main loop */
+
+	assert(why != WHY_YIELD);
+	/* Pop remaining stack entries. */
+	while (!EMPTY()) {
+		v = POP();
+		Py_XDECREF(v);
+	}
+
+	if (why != WHY_RETURN)
+		retval = NULL;
+
+fast_yield:
+	if (tstate->use_tracing) {
+		if (tstate->c_tracefunc) {
+			if (why == WHY_RETURN || why == WHY_YIELD) {
+				if (call_trace(tstate->c_tracefunc,
+					       tstate->c_traceobj, f,
+					       PyTrace_RETURN, retval)) {
+					Py_XDECREF(retval);
+					retval = NULL;
+					why = WHY_EXCEPTION;
+				}
+			}
+			else if (why == WHY_EXCEPTION) {
+				call_trace_protected(tstate->c_tracefunc,
+						     tstate->c_traceobj, f,
+						     PyTrace_RETURN, NULL);
+			}
+		}
+		if (tstate->c_profilefunc) {
+			if (why == WHY_EXCEPTION)
+				call_trace_protected(tstate->c_profilefunc,
+						     tstate->c_profileobj, f,
+						     PyTrace_RETURN, NULL);
+			else if (call_trace(tstate->c_profilefunc,
+					    tstate->c_profileobj, f,
+					    PyTrace_RETURN, retval)) {
+				Py_XDECREF(retval);
+				retval = NULL;
+				why = WHY_EXCEPTION;
+			}
+		}
+	}
+
+	if (tstate->frame->f_exc_type != NULL)
+		reset_exc_info(tstate);
+	else {
+		assert(tstate->frame->f_exc_value == NULL);
+		assert(tstate->frame->f_exc_traceback == NULL);
+	}
+
+	/* pop frame */
+    exit_eval_frame:
+	Py_LeaveRecursiveCall();
+	tstate->frame = f->f_back;
+
+	return retval;
+}
+
+/* This is gonna seem *real weird*, but if you put some other code between
+   PyEval_EvalFrame() and PyEval_EvalCodeEx() you will need to adjust
+   the test in the if statements in Misc/gdbinit (pystack and pystackv). */
+
+PyObject *
+PyEval_EvalCodeEx(PyCodeObject *co, PyObject *globals, PyObject *locals,
+	   PyObject **args, int argcount, PyObject **kws, int kwcount,
+	   PyObject **defs, int defcount, PyObject *closure)
+{
+	register PyFrameObject *f;
+	register PyObject *retval = NULL;
+	register PyObject **fastlocals, **freevars;
+	PyThreadState *tstate = PyThreadState_GET();
+	PyObject *x, *u;
+
+	if (globals == NULL) {
+		PyErr_SetString(PyExc_SystemError,
+				"PyEval_EvalCodeEx: NULL globals");
+		return NULL;
+	}
+
+	assert(tstate != NULL);
+	assert(globals != NULL);
+	f = PyFrame_New(tstate, co, globals, locals);
+	if (f == NULL)
+		return NULL;
+
+	fastlocals = f->f_localsplus;
+	freevars = f->f_localsplus + co->co_nlocals;
+
+	if (co->co_argcount > 0 ||
+	    co->co_flags & (CO_VARARGS | CO_VARKEYWORDS)) {
+		int i;
+		int n = argcount;
+		PyObject *kwdict = NULL;
+		if (co->co_flags & CO_VARKEYWORDS) {
+			kwdict = PyDict_New();
+			if (kwdict == NULL)
+				goto fail;
+			i = co->co_argcount;
+			if (co->co_flags & CO_VARARGS)
+				i++;
+			SETLOCAL(i, kwdict);
+		}
+		if (argcount > co->co_argcount) {
+			if (!(co->co_flags & CO_VARARGS)) {
+				PyErr_Format(PyExc_TypeError,
+				    "%.200s() takes %s %d "
+				    "%sargument%s (%d given)",
+				    PyString_AsString(co->co_name),
+				    defcount ? "at most" : "exactly",
+				    co->co_argcount,
+				    kwcount ? "non-keyword " : "",
+				    co->co_argcount == 1 ? "" : "s",
+				    argcount);
+				goto fail;
+			}
+			n = co->co_argcount;
+		}
+		for (i = 0; i < n; i++) {
+			x = args[i];
+			Py_INCREF(x);
+			SETLOCAL(i, x);
+		}
+		if (co->co_flags & CO_VARARGS) {
+			u = PyTuple_New(argcount - n);
+			if (u == NULL)
+				goto fail;
+			SETLOCAL(co->co_argcount, u);
+			for (i = n; i < argcount; i++) {
+				x = args[i];
+				Py_INCREF(x);
+				PyTuple_SET_ITEM(u, i-n, x);
+			}
+		}
+		for (i = 0; i < kwcount; i++) {
+			PyObject *keyword = kws[2*i];
+			PyObject *value = kws[2*i + 1];
+			int j;
+			if (keyword == NULL || !PyString_Check(keyword)) {
+				PyErr_Format(PyExc_TypeError,
+				    "%.200s() keywords must be strings",
+				    PyString_AsString(co->co_name));
+				goto fail;
+			}
+			/* XXX slow -- speed up using dictionary? */
+			for (j = 0; j < co->co_argcount; j++) {
+				PyObject *nm = PyTuple_GET_ITEM(
+					co->co_varnames, j);
+				int cmp = PyObject_RichCompareBool(
+					keyword, nm, Py_EQ);
+				if (cmp > 0)
+					break;
+				else if (cmp < 0)
+					goto fail;
+			}
+			/* Check errors from Compare */
+			if (PyErr_Occurred())
+				goto fail;
+			if (j >= co->co_argcount) {
+				if (kwdict == NULL) {
+					PyErr_Format(PyExc_TypeError,
+					    "%.200s() got an unexpected "
+					    "keyword argument '%.400s'",
+					    PyString_AsString(co->co_name),
+					    PyString_AsString(keyword));
+					goto fail;
+				}
+				PyDict_SetItem(kwdict, keyword, value);
+			}
+			else {
+				if (GETLOCAL(j) != NULL) {
+					PyErr_Format(PyExc_TypeError,
+					     "%.200s() got multiple "
+					     "values for keyword "
+					     "argument '%.400s'",
+					     PyString_AsString(co->co_name),
+					     PyString_AsString(keyword));
+					goto fail;
+				}
+				Py_INCREF(value);
+				SETLOCAL(j, value);
+			}
+		}
+		if (argcount < co->co_argcount) {
+			int m = co->co_argcount - defcount;
+			for (i = argcount; i < m; i++) {
+				if (GETLOCAL(i) == NULL) {
+					PyErr_Format(PyExc_TypeError,
+					    "%.200s() takes %s %d "
+					    "%sargument%s (%d given)",
+					    PyString_AsString(co->co_name),
+					    ((co->co_flags & CO_VARARGS) ||
+					     defcount) ? "at least"
+						       : "exactly",
+					    m, kwcount ? "non-keyword " : "",
+					    m == 1 ? "" : "s", i);
+					goto fail;
+				}
+			}
+			if (n > m)
+				i = n - m;
+			else
+				i = 0;
+			for (; i < defcount; i++) {
+				if (GETLOCAL(m+i) == NULL) {
+					PyObject *def = defs[i];
+					Py_INCREF(def);
+					SETLOCAL(m+i, def);
+				}
+			}
+		}
+	}
+	else {
+		if (argcount > 0 || kwcount > 0) {
+			PyErr_Format(PyExc_TypeError,
+				     "%.200s() takes no arguments (%d given)",
+				     PyString_AsString(co->co_name),
+				     argcount + kwcount);
+			goto fail;
+		}
+	}
+	/* Allocate and initialize storage for cell vars, and copy free
+	   vars into frame.  This isn't too efficient right now. */
+	if (PyTuple_GET_SIZE(co->co_cellvars)) {
+		int i, j, nargs, found;
+		char *cellname, *argname;
+		PyObject *c;
+
+		nargs = co->co_argcount;
+		if (co->co_flags & CO_VARARGS)
+			nargs++;
+		if (co->co_flags & CO_VARKEYWORDS)
+			nargs++;
+
+		/* Initialize each cell var, taking into account
+		   cell vars that are initialized from arguments.
+
+		   Should arrange for the compiler to put cellvars
+		   that are arguments at the beginning of the cellvars
+		   list so that we can march over it more efficiently?
+		*/
+		for (i = 0; i < PyTuple_GET_SIZE(co->co_cellvars); ++i) {
+			cellname = PyString_AS_STRING(
+				PyTuple_GET_ITEM(co->co_cellvars, i));
+			found = 0;
+			for (j = 0; j < nargs; j++) {
+				argname = PyString_AS_STRING(
+					PyTuple_GET_ITEM(co->co_varnames, j));
+				if (strcmp(cellname, argname) == 0) {
+					c = PyCell_New(GETLOCAL(j));
+					if (c == NULL)
+						goto fail;
+					GETLOCAL(co->co_nlocals + i) = c;
+					found = 1;
+					break;
+				}
+			}
+			if (found == 0) {
+				c = PyCell_New(NULL);
+				if (c == NULL)
+					goto fail;
+				SETLOCAL(co->co_nlocals + i, c);
+			}
+		}
+	}
+	if (PyTuple_GET_SIZE(co->co_freevars)) {
+		int i;
+		for (i = 0; i < PyTuple_GET_SIZE(co->co_freevars); ++i) {
+			PyObject *o = PyTuple_GET_ITEM(closure, i);
+			Py_INCREF(o);
+			freevars[PyTuple_GET_SIZE(co->co_cellvars) + i] = o;
+		}
+	}
+
+	if (co->co_flags & CO_GENERATOR) {
+		/* Don't need to keep the reference to f_back, it will be set
+		 * when the generator is resumed. */
+		Py_XDECREF(f->f_back);
+		f->f_back = NULL;
+
+		PCALL(PCALL_GENERATOR);
+
+		/* Create a new generator that owns the ready to run frame
+		 * and return that as the value. */
+		return PyGen_New(f);
+	}
+
+        retval = PyEval_EvalFrameEx(f,0);
+
+  fail: /* Jump here from prelude on failure */
+
+	/* decref'ing the frame can cause __del__ methods to get invoked,
+	   which can call back into Python.  While we're done with the
+	   current Python frame (f), the associated C stack is still in use,
+	   so recursion_depth must be boosted for the duration.
+	*/
+	assert(tstate != NULL);
+	++tstate->recursion_depth;
+        Py_DECREF(f);
+	--tstate->recursion_depth;
+	return retval;
+}
+
+
+/* Implementation notes for set_exc_info() and reset_exc_info():
+
+- Below, 'exc_ZZZ' stands for 'exc_type', 'exc_value' and
+  'exc_traceback'.  These always travel together.
+
+- tstate->curexc_ZZZ is the "hot" exception that is set by
+  PyErr_SetString(), cleared by PyErr_Clear(), and so on.
+
+- Once an exception is caught by an except clause, it is transferred
+  from tstate->curexc_ZZZ to tstate->exc_ZZZ, from which sys.exc_info()
+  can pick it up.  This is the primary task of set_exc_info().
+  XXX That can't be right:  set_exc_info() doesn't look at tstate->curexc_ZZZ.
+
+- Now let me explain the complicated dance with frame->f_exc_ZZZ.
+
+  Long ago, when none of this existed, there were just a few globals:
+  one set corresponding to the "hot" exception, and one set
+  corresponding to sys.exc_ZZZ.  (Actually, the latter weren't C
+  globals; they were simply stored as sys.exc_ZZZ.  For backwards
+  compatibility, they still are!)  The problem was that in code like
+  this:
+
+     try:
+	"something that may fail"
+     except "some exception":
+	"do something else first"
+	"print the exception from sys.exc_ZZZ."
+
+  if "do something else first" invoked something that raised and caught
+  an exception, sys.exc_ZZZ were overwritten.  That was a frequent
+  cause of subtle bugs.  I fixed this by changing the semantics as
+  follows:
+
+    - Within one frame, sys.exc_ZZZ will hold the last exception caught
+      *in that frame*.
+
+    - But initially, and as long as no exception is caught in a given
+      frame, sys.exc_ZZZ will hold the last exception caught in the
+      previous frame (or the frame before that, etc.).
+
+  The first bullet fixed the bug in the above example.  The second
+  bullet was for backwards compatibility: it was (and is) common to
+  have a function that is called when an exception is caught, and to
+  have that function access the caught exception via sys.exc_ZZZ.
+  (Example: traceback.print_exc()).
+
+  At the same time I fixed the problem that sys.exc_ZZZ weren't
+  thread-safe, by introducing sys.exc_info() which gets it from tstate;
+  but that's really a separate improvement.
+
+  The reset_exc_info() function in ceval.c restores the tstate->exc_ZZZ
+  variables to what they were before the current frame was called.  The
+  set_exc_info() function saves them on the frame so that
+  reset_exc_info() can restore them.  The invariant is that
+  frame->f_exc_ZZZ is NULL iff the current frame never caught an
+  exception (where "catching" an exception applies only to successful
+  except clauses); and if the current frame ever caught an exception,
+  frame->f_exc_ZZZ is the exception that was stored in tstate->exc_ZZZ
+  at the start of the current frame.
+
+*/
+
+static void
+set_exc_info(PyThreadState *tstate,
+	     PyObject *type, PyObject *value, PyObject *tb)
+{
+	PyFrameObject *frame = tstate->frame;
+	PyObject *tmp_type, *tmp_value, *tmp_tb;
+
+	assert(type != NULL);
+	assert(frame != NULL);
+	if (frame->f_exc_type == NULL) {
+		assert(frame->f_exc_value == NULL);
+		assert(frame->f_exc_traceback == NULL);
+		/* This frame didn't catch an exception before. */
+		/* Save previous exception of this thread in this frame. */
+		if (tstate->exc_type == NULL) {
+			/* XXX Why is this set to Py_None? */
+			Py_INCREF(Py_None);
+			tstate->exc_type = Py_None;
+		}
+		Py_INCREF(tstate->exc_type);
+		Py_XINCREF(tstate->exc_value);
+		Py_XINCREF(tstate->exc_traceback);
+		frame->f_exc_type = tstate->exc_type;
+		frame->f_exc_value = tstate->exc_value;
+		frame->f_exc_traceback = tstate->exc_traceback;
+	}
+	/* Set new exception for this thread. */
+	tmp_type = tstate->exc_type;
+	tmp_value = tstate->exc_value;
+	tmp_tb = tstate->exc_traceback;
+	Py_INCREF(type);
+	Py_XINCREF(value);
+	Py_XINCREF(tb);
+	tstate->exc_type = type;
+	tstate->exc_value = value;
+	tstate->exc_traceback = tb;
+	Py_XDECREF(tmp_type);
+	Py_XDECREF(tmp_value);
+	Py_XDECREF(tmp_tb);
+	/* For b/w compatibility */
+	PySys_SetObject("exc_type", type);
+	PySys_SetObject("exc_value", value);
+	PySys_SetObject("exc_traceback", tb);
+}
+
+static void
+reset_exc_info(PyThreadState *tstate)
+{
+	PyFrameObject *frame;
+	PyObject *tmp_type, *tmp_value, *tmp_tb;
+
+	/* It's a precondition that the thread state's frame caught an
+	 * exception -- verify in a debug build.
+	 */
+	assert(tstate != NULL);
+	frame = tstate->frame;
+	assert(frame != NULL);
+	assert(frame->f_exc_type != NULL);
+
+	/* Copy the frame's exception info back to the thread state. */
+	tmp_type = tstate->exc_type;
+	tmp_value = tstate->exc_value;
+	tmp_tb = tstate->exc_traceback;
+	Py_INCREF(frame->f_exc_type);
+	Py_XINCREF(frame->f_exc_value);
+	Py_XINCREF(frame->f_exc_traceback);
+	tstate->exc_type = frame->f_exc_type;
+	tstate->exc_value = frame->f_exc_value;
+	tstate->exc_traceback = frame->f_exc_traceback;
+	Py_XDECREF(tmp_type);
+	Py_XDECREF(tmp_value);
+	Py_XDECREF(tmp_tb);
+
+	/* For b/w compatibility */
+	PySys_SetObject("exc_type", frame->f_exc_type);
+	PySys_SetObject("exc_value", frame->f_exc_value);
+	PySys_SetObject("exc_traceback", frame->f_exc_traceback);
+
+	/* Clear the frame's exception info. */
+	tmp_type = frame->f_exc_type;
+	tmp_value = frame->f_exc_value;
+	tmp_tb = frame->f_exc_traceback;
+	frame->f_exc_type = NULL;
+	frame->f_exc_value = NULL;
+	frame->f_exc_traceback = NULL;
+	Py_DECREF(tmp_type);
+	Py_XDECREF(tmp_value);
+	Py_XDECREF(tmp_tb);
+}
+
+/* Logic for the raise statement (too complicated for inlining).
+   This *consumes* a reference count to each of its arguments. */
+static enum why_code
+do_raise(PyObject *type, PyObject *value, PyObject *tb)
+{
+	if (type == NULL) {
+		/* Reraise */
+		PyThreadState *tstate = PyThreadState_GET();
+		type = tstate->exc_type == NULL ? Py_None : tstate->exc_type;
+		value = tstate->exc_value;
+		tb = tstate->exc_traceback;
+		Py_XINCREF(type);
+		Py_XINCREF(value);
+		Py_XINCREF(tb);
+	}
+
+	/* We support the following forms of raise:
+	   raise <class>, <classinstance>
+	   raise <class>, <argument tuple>
+	   raise <class>, None
+	   raise <class>, <argument>
+	   raise <classinstance>, None
+	   raise <string>, <object>
+	   raise <string>, None
+
+	   An omitted second argument is the same as None.
+
+	   In addition, raise <tuple>, <anything> is the same as
+	   raising the tuple's first item (and it better have one!);
+	   this rule is applied recursively.
+
+	   Finally, an optional third argument can be supplied, which
+	   gives the traceback to be substituted (useful when
+	   re-raising an exception after examining it).  */
+
+	/* First, check the traceback argument, replacing None with
+	   NULL. */
+	if (tb == Py_None) {
+		Py_DECREF(tb);
+		tb = NULL;
+	}
+	else if (tb != NULL && !PyTraceBack_Check(tb)) {
+		PyErr_SetString(PyExc_TypeError,
+			   "raise: arg 3 must be a traceback or None");
+		goto raise_error;
+	}
+
+	/* Next, replace a missing value with None */
+	if (value == NULL) {
+		value = Py_None;
+		Py_INCREF(value);
+	}
+
+	/* Next, repeatedly, replace a tuple exception with its first item */
+	while (PyTuple_Check(type) && PyTuple_Size(type) > 0) {
+		PyObject *tmp = type;
+		type = PyTuple_GET_ITEM(type, 0);
+		Py_INCREF(type);
+		Py_DECREF(tmp);
+	}
+
+	if (PyString_CheckExact(type)) {
+		/* Raising builtin string is deprecated but still allowed --
+		 * do nothing.  Raising an instance of a new-style str
+		 * subclass is right out. */
+		if (PyErr_Warn(PyExc_DeprecationWarning,
+			   "raising a string exception is deprecated"))
+			goto raise_error;
+	}
+	else if (PyExceptionClass_Check(type))
+		PyErr_NormalizeException(&type, &value, &tb);
+
+	else if (PyExceptionInstance_Check(type)) {
+		/* Raising an instance.  The value should be a dummy. */
+		if (value != Py_None) {
+			PyErr_SetString(PyExc_TypeError,
+			  "instance exception may not have a separate value");
+			goto raise_error;
+		}
+		else {
+			/* Normalize to raise <class>, <instance> */
+			Py_DECREF(value);
+			value = type;
+			type = PyExceptionInstance_Class(type);
+			Py_INCREF(type);
+		}
+	}
+	else {
+		/* Not something you can raise.  You get an exception
+		   anyway, just not what you specified :-) */
+		PyErr_Format(PyExc_TypeError,
+			     "exceptions must be classes, instances, or "
+			     "strings (deprecated), not %s",
+			     type->ob_type->tp_name);
+		goto raise_error;
+	}
+	PyErr_Restore(type, value, tb);
+	if (tb == NULL)
+		return WHY_EXCEPTION;
+	else
+		return WHY_RERAISE;
+ raise_error:
+	Py_XDECREF(value);
+	Py_XDECREF(type);
+	Py_XDECREF(tb);
+	return WHY_EXCEPTION;
+}
+
+/* Iterate v argcnt times and store the results on the stack (via decreasing
+   sp).  Return 1 for success, 0 if error. */
+
+static int
+unpack_iterable(PyObject *v, int argcnt, PyObject **sp)
+{
+	int i = 0;
+	PyObject *it;  /* iter(v) */
+	PyObject *w;
+
+	assert(v != NULL);
+
+	it = PyObject_GetIter(v);
+	if (it == NULL)
+		goto Error;
+
+	for (; i < argcnt; i++) {
+		w = PyIter_Next(it);
+		if (w == NULL) {
+			/* Iterator done, via error or exhaustion. */
+			if (!PyErr_Occurred()) {
+				PyErr_Format(PyExc_ValueError,
+					"need more than %d value%s to unpack",
+					i, i == 1 ? "" : "s");
+			}
+			goto Error;
+		}
+		*--sp = w;
+	}
+
+	/* We better have exhausted the iterator now. */
+	w = PyIter_Next(it);
+	if (w == NULL) {
+		if (PyErr_Occurred())
+			goto Error;
+		Py_DECREF(it);
+		return 1;
+	}
+	Py_DECREF(w);
+	PyErr_SetString(PyExc_ValueError, "too many values to unpack");
+	/* fall through */
+Error:
+	for (; i > 0; i--, sp++)
+		Py_DECREF(*sp);
+	Py_XDECREF(it);
+	return 0;
+}
+
+
+#ifdef LLTRACE
+static int
+prtrace(PyObject *v, char *str)
+{
+	printf("%s ", str);
+	if (PyObject_Print(v, stdout, 0) != 0)
+		PyErr_Clear(); /* Don't know what else to do */
+	printf("\n");
+	return 1;
+}
+#endif
+
+static void
+call_exc_trace(Py_tracefunc func, PyObject *self, PyFrameObject *f)
+{
+	PyObject *type, *value, *traceback, *arg;
+	int err;
+	PyErr_Fetch(&type, &value, &traceback);
+	if (value == NULL) {
+		value = Py_None;
+		Py_INCREF(value);
+	}
+	arg = PyTuple_Pack(3, type, value, traceback);
+	if (arg == NULL) {
+		PyErr_Restore(type, value, traceback);
+		return;
+	}
+	err = call_trace(func, self, f, PyTrace_EXCEPTION, arg);
+	Py_DECREF(arg);
+	if (err == 0)
+		PyErr_Restore(type, value, traceback);
+	else {
+		Py_XDECREF(type);
+		Py_XDECREF(value);
+		Py_XDECREF(traceback);
+	}
+}
+
+static void
+call_trace_protected(Py_tracefunc func, PyObject *obj, PyFrameObject *frame,
+		     int what, PyObject *arg)
+{
+	PyObject *type, *value, *traceback;
+	int err;
+	PyErr_Fetch(&type, &value, &traceback);
+	err = call_trace(func, obj, frame, what, arg);
+	if (err == 0)
+		PyErr_Restore(type, value, traceback);
+	else {
+		Py_XDECREF(type);
+		Py_XDECREF(value);
+		Py_XDECREF(traceback);
+	}
+}
+
+static int
+call_trace(Py_tracefunc func, PyObject *obj, PyFrameObject *frame,
+	   int what, PyObject *arg)
+{
+	register PyThreadState *tstate = frame->f_tstate;
+	int result;
+	if (tstate->tracing)
+		return 0;
+	tstate->tracing++;
+	tstate->use_tracing = 0;
+	result = func(obj, frame, what, arg);
+	tstate->use_tracing = ((tstate->c_tracefunc != NULL)
+			       || (tstate->c_profilefunc != NULL));
+	tstate->tracing--;
+	return result;
+}
+
+PyObject *
+_PyEval_CallTracing(PyObject *func, PyObject *args)
+{
+	PyFrameObject *frame = PyEval_GetFrame();
+	PyThreadState *tstate = frame->f_tstate;
+	int save_tracing = tstate->tracing;
+	int save_use_tracing = tstate->use_tracing;
+	PyObject *result;
+
+	tstate->tracing = 0;
+	tstate->use_tracing = ((tstate->c_tracefunc != NULL)
+			       || (tstate->c_profilefunc != NULL));
+	result = PyObject_Call(func, args, NULL);
+	tstate->tracing = save_tracing;
+	tstate->use_tracing = save_use_tracing;
+	return result;
+}
+
+static int
+maybe_call_line_trace(Py_tracefunc func, PyObject *obj,
+		      PyFrameObject *frame, int *instr_lb, int *instr_ub,
+		      int *instr_prev)
+{
+	int result = 0;
+
+        /* If the last instruction executed isn't in the current
+           instruction window, reset the window.  If the last
+           instruction happens to fall at the start of a line or if it
+           represents a jump backwards, call the trace function.
+        */
+	if ((frame->f_lasti < *instr_lb || frame->f_lasti >= *instr_ub)) {
+                int line;
+                PyAddrPair bounds;
+
+                line = PyCode_CheckLineNumber(frame->f_code, frame->f_lasti,
+                                              &bounds);
+                if (line >= 0) {
+			frame->f_lineno = line;
+			result = call_trace(func, obj, frame,
+					    PyTrace_LINE, Py_None);
+                }
+                *instr_lb = bounds.ap_lower;
+                *instr_ub = bounds.ap_upper;
+	}
+	else if (frame->f_lasti <= *instr_prev) {
+		result = call_trace(func, obj, frame, PyTrace_LINE, Py_None);
+	}
+	*instr_prev = frame->f_lasti;
+	return result;
+}
+
+void
+PyEval_SetProfile(Py_tracefunc func, PyObject *arg)
+{
+	PyThreadState *tstate = PyThreadState_GET();
+	PyObject *temp = tstate->c_profileobj;
+	Py_XINCREF(arg);
+	tstate->c_profilefunc = NULL;
+	tstate->c_profileobj = NULL;
+	/* Must make sure that tracing is not ignored if 'temp' is freed */
+	tstate->use_tracing = tstate->c_tracefunc != NULL;
+	Py_XDECREF(temp);
+	tstate->c_profilefunc = func;
+	tstate->c_profileobj = arg;
+	/* Flag that tracing or profiling is turned on */
+	tstate->use_tracing = (func != NULL) || (tstate->c_tracefunc != NULL);
+}
+
+void
+PyEval_SetTrace(Py_tracefunc func, PyObject *arg)
+{
+	PyThreadState *tstate = PyThreadState_GET();
+	PyObject *temp = tstate->c_traceobj;
+	Py_XINCREF(arg);
+	tstate->c_tracefunc = NULL;
+	tstate->c_traceobj = NULL;
+	/* Must make sure that profiling is not ignored if 'temp' is freed */
+	tstate->use_tracing = tstate->c_profilefunc != NULL;
+	Py_XDECREF(temp);
+	tstate->c_tracefunc = func;
+	tstate->c_traceobj = arg;
+	/* Flag that tracing or profiling is turned on */
+	tstate->use_tracing = ((func != NULL)
+			       || (tstate->c_profilefunc != NULL));
+}
+
+PyObject *
+PyEval_GetBuiltins(void)
+{
+	PyFrameObject *current_frame = PyEval_GetFrame();
+	if (current_frame == NULL)
+		return PyThreadState_GET()->interp->builtins;
+	else
+		return current_frame->f_builtins;
+}
+
+PyObject *
+PyEval_GetLocals(void)
+{
+	PyFrameObject *current_frame = PyEval_GetFrame();
+	if (current_frame == NULL)
+		return NULL;
+	PyFrame_FastToLocals(current_frame);
+	return current_frame->f_locals;
+}
+
+PyObject *
+PyEval_GetGlobals(void)
+{
+	PyFrameObject *current_frame = PyEval_GetFrame();
+	if (current_frame == NULL)
+		return NULL;
+	else
+		return current_frame->f_globals;
+}
+
+PyFrameObject *
+PyEval_GetFrame(void)
+{
+	PyThreadState *tstate = PyThreadState_GET();
+	return _PyThreadState_GetFrame(tstate);
+}
+
+int
+PyEval_GetRestricted(void)
+{
+	PyFrameObject *current_frame = PyEval_GetFrame();
+	return current_frame == NULL ? 0 : PyFrame_IsRestricted(current_frame);
+}
+
+int
+PyEval_MergeCompilerFlags(PyCompilerFlags *cf)
+{
+	PyFrameObject *current_frame = PyEval_GetFrame();
+	int result = cf->cf_flags != 0;
+
+	if (current_frame != NULL) {
+		const int codeflags = current_frame->f_code->co_flags;
+		const int compilerflags = codeflags & PyCF_MASK;
+		if (compilerflags) {
+			result = 1;
+			cf->cf_flags |= compilerflags;
+		}
+#if 0 /* future keyword */
+		if (codeflags & CO_GENERATOR_ALLOWED) {
+			result = 1;
+			cf->cf_flags |= CO_GENERATOR_ALLOWED;
+		}
+#endif
+	}
+	return result;
+}
+
+int
+Py_FlushLine(void)
+{
+	PyObject *f = PySys_GetObject("stdout");
+	if (f == NULL)
+		return 0;
+	if (!PyFile_SoftSpace(f, 0))
+		return 0;
+	return PyFile_WriteString("\n", f);
+}
+
+
+/* External interface to call any callable object.
+   The arg must be a tuple or NULL. */
+
+#undef PyEval_CallObject
+/* for backward compatibility: export this interface */
+
+PyObject *
+PyEval_CallObject(PyObject *func, PyObject *arg)
+{
+	return PyEval_CallObjectWithKeywords(func, arg, (PyObject *)NULL);
+}
+#define PyEval_CallObject(func,arg) \
+        PyEval_CallObjectWithKeywords(func, arg, (PyObject *)NULL)
+
+PyObject *
+PyEval_CallObjectWithKeywords(PyObject *func, PyObject *arg, PyObject *kw)
+{
+	PyObject *result;
+
+	if (arg == NULL) {
+		arg = PyTuple_New(0);
+		if (arg == NULL)
+			return NULL;
+	}
+	else if (!PyTuple_Check(arg)) {
+		PyErr_SetString(PyExc_TypeError,
+				"argument list must be a tuple");
+		return NULL;
+	}
+	else
+		Py_INCREF(arg);
+
+	if (kw != NULL && !PyDict_Check(kw)) {
+		PyErr_SetString(PyExc_TypeError,
+				"keyword list must be a dictionary");
+		Py_DECREF(arg);
+		return NULL;
+	}
+
+	result = PyObject_Call(func, arg, kw);
+	Py_DECREF(arg);
+	return result;
+}
+
+const char *
+PyEval_GetFuncName(PyObject *func)
+{
+	if (PyMethod_Check(func))
+		return PyEval_GetFuncName(PyMethod_GET_FUNCTION(func));
+	else if (PyFunction_Check(func))
+		return PyString_AsString(((PyFunctionObject*)func)->func_name);
+	else if (PyCFunction_Check(func))
+		return ((PyCFunctionObject*)func)->m_ml->ml_name;
+	else if (PyClass_Check(func))
+		return PyString_AsString(((PyClassObject*)func)->cl_name);
+	else if (PyInstance_Check(func)) {
+		return PyString_AsString(
+			((PyInstanceObject*)func)->in_class->cl_name);
+	} else {
+		return func->ob_type->tp_name;
+	}
+}
+
+const char *
+PyEval_GetFuncDesc(PyObject *func)
+{
+	if (PyMethod_Check(func))
+		return "()";
+	else if (PyFunction_Check(func))
+		return "()";
+	else if (PyCFunction_Check(func))
+		return "()";
+	else if (PyClass_Check(func))
+		return " constructor";
+	else if (PyInstance_Check(func)) {
+		return " instance";
+	} else {
+		return " object";
+	}
+}
+
+static void
+err_args(PyObject *func, int flags, int nargs)
+{
+	if (flags & METH_NOARGS)
+		PyErr_Format(PyExc_TypeError,
+			     "%.200s() takes no arguments (%d given)",
+			     ((PyCFunctionObject *)func)->m_ml->ml_name,
+			     nargs);
+	else
+		PyErr_Format(PyExc_TypeError,
+			     "%.200s() takes exactly one argument (%d given)",
+			     ((PyCFunctionObject *)func)->m_ml->ml_name,
+			     nargs);
+}
+
+#define C_TRACE(x, call) \
+if (tstate->use_tracing && tstate->c_profilefunc) { \
+	if (call_trace(tstate->c_profilefunc, \
+		tstate->c_profileobj, \
+		tstate->frame, PyTrace_C_CALL, \
+		func)) { \
+		x = NULL; \
+	} \
+	else { \
+		x = call; \
+		if (tstate->c_profilefunc != NULL) { \
+			if (x == NULL) { \
+				call_trace_protected(tstate->c_profilefunc, \
+					tstate->c_profileobj, \
+					tstate->frame, PyTrace_C_EXCEPTION, \
+					func); \
+				/* XXX should pass (type, value, tb) */ \
+			} else { \
+				if (call_trace(tstate->c_profilefunc, \
+					tstate->c_profileobj, \
+					tstate->frame, PyTrace_C_RETURN, \
+					func)) { \
+					Py_DECREF(x); \
+					x = NULL; \
+				} \
+			} \
+		} \
+	} \
+} else { \
+	x = call; \
+	}
+
+static PyObject *
+call_function(PyObject ***pp_stack, int oparg
+#ifdef WITH_TSC
+		, uint64* pintr0, uint64* pintr1
+#endif
+		)
+{
+	int na = oparg & 0xff;
+	int nk = (oparg>>8) & 0xff;
+	int n = na + 2 * nk;
+	PyObject **pfunc = (*pp_stack) - n - 1;
+	PyObject *func = *pfunc;
+	PyObject *x, *w;
+
+	/* Always dispatch PyCFunction first, because these are
+	   presumed to be the most frequent callable object.
+	*/
+	if (PyCFunction_Check(func) && nk == 0) {
+		int flags = PyCFunction_GET_FLAGS(func);
+		PyThreadState *tstate = PyThreadState_GET();
+
+		PCALL(PCALL_CFUNCTION);
+		if (flags & (METH_NOARGS | METH_O)) {
+			PyCFunction meth = PyCFunction_GET_FUNCTION(func);
+			PyObject *self = PyCFunction_GET_SELF(func);
+			if (flags & METH_NOARGS && na == 0) {
+				C_TRACE(x, (*meth)(self,NULL));
+			}
+			else if (flags & METH_O && na == 1) {
+				PyObject *arg = EXT_POP(*pp_stack);
+				C_TRACE(x, (*meth)(self,arg));
+				Py_DECREF(arg);
+			}
+			else {
+				err_args(func, flags, na);
+				x = NULL;
+			}
+		}
+		else {
+			PyObject *callargs;
+			callargs = load_args(pp_stack, na);
+			READ_TIMESTAMP(*pintr0);
+			C_TRACE(x, PyCFunction_Call(func,callargs,NULL));
+			READ_TIMESTAMP(*pintr1);
+			Py_XDECREF(callargs);
+		}
+	} else {
+		if (PyMethod_Check(func) && PyMethod_GET_SELF(func) != NULL) {
+			/* optimize access to bound methods */
+			PyObject *self = PyMethod_GET_SELF(func);
+			PCALL(PCALL_METHOD);
+			PCALL(PCALL_BOUND_METHOD);
+			Py_INCREF(self);
+			func = PyMethod_GET_FUNCTION(func);
+			Py_INCREF(func);
+			Py_DECREF(*pfunc);
+			*pfunc = self;
+			na++;
+			n++;
+		} else
+			Py_INCREF(func);
+		READ_TIMESTAMP(*pintr0);
+		if (PyFunction_Check(func))
+			x = fast_function(func, pp_stack, n, na, nk);
+		else
+			x = do_call(func, pp_stack, na, nk);
+		READ_TIMESTAMP(*pintr1);
+		Py_DECREF(func);
+	}
+
+	/* Clear the stack of the function object.  Also removes
+           the arguments in case they weren't consumed already
+           (fast_function() and err_args() leave them on the stack).
+	 */
+	while ((*pp_stack) > pfunc) {
+		w = EXT_POP(*pp_stack);
+		Py_DECREF(w);
+		PCALL(PCALL_POP);
+	}
+	return x;
+}
+
+/* The fast_function() function optimize calls for which no argument
+   tuple is necessary; the objects are passed directly from the stack.
+   For the simplest case -- a function that takes only positional
+   arguments and is called with only positional arguments -- it
+   inlines the most primitive frame setup code from
+   PyEval_EvalCodeEx(), which vastly reduces the checks that must be
+   done before evaluating the frame.
+*/
+
+static PyObject *
+fast_function(PyObject *func, PyObject ***pp_stack, int n, int na, int nk)
+{
+	PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func);
+	PyObject *globals = PyFunction_GET_GLOBALS(func);
+	PyObject *argdefs = PyFunction_GET_DEFAULTS(func);
+	PyObject **d = NULL;
+	int nd = 0;
+
+	PCALL(PCALL_FUNCTION);
+	PCALL(PCALL_FAST_FUNCTION);
+	if (argdefs == NULL && co->co_argcount == n && nk==0 &&
+	    co->co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) {
+		PyFrameObject *f;
+		PyObject *retval = NULL;
+		PyThreadState *tstate = PyThreadState_GET();
+		PyObject **fastlocals, **stack;
+		int i;
+
+		PCALL(PCALL_FASTER_FUNCTION);
+		assert(globals != NULL);
+		/* XXX Perhaps we should create a specialized
+		   PyFrame_New() that doesn't take locals, but does
+		   take builtins without sanity checking them.
+		*/
+		assert(tstate != NULL);
+		f = PyFrame_New(tstate, co, globals, NULL);
+		if (f == NULL)
+			return NULL;
+
+		fastlocals = f->f_localsplus;
+		stack = (*pp_stack) - n;
+
+		for (i = 0; i < n; i++) {
+			Py_INCREF(*stack);
+			fastlocals[i] = *stack++;
+		}
+		retval = PyEval_EvalFrameEx(f,0);
+		++tstate->recursion_depth;
+		Py_DECREF(f);
+		--tstate->recursion_depth;
+		return retval;
+	}
+	if (argdefs != NULL) {
+		d = &PyTuple_GET_ITEM(argdefs, 0);
+		nd = ((PyTupleObject *)argdefs)->ob_size;
+	}
+	return PyEval_EvalCodeEx(co, globals,
+				 (PyObject *)NULL, (*pp_stack)-n, na,
+				 (*pp_stack)-2*nk, nk, d, nd,
+				 PyFunction_GET_CLOSURE(func));
+}
+
+static PyObject *
+update_keyword_args(PyObject *orig_kwdict, int nk, PyObject ***pp_stack,
+                    PyObject *func)
+{
+	PyObject *kwdict = NULL;
+	if (orig_kwdict == NULL)
+		kwdict = PyDict_New();
+	else {
+		kwdict = PyDict_Copy(orig_kwdict);
+		Py_DECREF(orig_kwdict);
+	}
+	if (kwdict == NULL)
+		return NULL;
+	while (--nk >= 0) {
+		int err;
+		PyObject *value = EXT_POP(*pp_stack);
+		PyObject *key = EXT_POP(*pp_stack);
+		if (PyDict_GetItem(kwdict, key) != NULL) {
+                        PyErr_Format(PyExc_TypeError,
+                                     "%.200s%s got multiple values "
+                                     "for keyword argument '%.200s'",
+				     PyEval_GetFuncName(func),
+				     PyEval_GetFuncDesc(func),
+				     PyString_AsString(key));
+			Py_DECREF(key);
+			Py_DECREF(value);
+			Py_DECREF(kwdict);
+			return NULL;
+		}
+		err = PyDict_SetItem(kwdict, key, value);
+		Py_DECREF(key);
+		Py_DECREF(value);
+		if (err) {
+			Py_DECREF(kwdict);
+			return NULL;
+		}
+	}
+	return kwdict;
+}
+
+static PyObject *
+update_star_args(int nstack, int nstar, PyObject *stararg,
+		 PyObject ***pp_stack)
+{
+	PyObject *callargs, *w;
+
+	callargs = PyTuple_New(nstack + nstar);
+	if (callargs == NULL) {
+		return NULL;
+	}
+	if (nstar) {
+		int i;
+		for (i = 0; i < nstar; i++) {
+			PyObject *a = PyTuple_GET_ITEM(stararg, i);
+			Py_INCREF(a);
+			PyTuple_SET_ITEM(callargs, nstack + i, a);
+		}
+	}
+	while (--nstack >= 0) {
+		w = EXT_POP(*pp_stack);
+		PyTuple_SET_ITEM(callargs, nstack, w);
+	}
+	return callargs;
+}
+
+static PyObject *
+load_args(PyObject ***pp_stack, int na)
+{
+	PyObject *args = PyTuple_New(na);
+	PyObject *w;
+
+	if (args == NULL)
+		return NULL;
+	while (--na >= 0) {
+		w = EXT_POP(*pp_stack);
+		PyTuple_SET_ITEM(args, na, w);
+	}
+	return args;
+}
+
+static PyObject *
+do_call(PyObject *func, PyObject ***pp_stack, int na, int nk)
+{
+	PyObject *callargs = NULL;
+	PyObject *kwdict = NULL;
+	PyObject *result = NULL;
+
+	if (nk > 0) {
+		kwdict = update_keyword_args(NULL, nk, pp_stack, func);
+		if (kwdict == NULL)
+			goto call_fail;
+	}
+	callargs = load_args(pp_stack, na);
+	if (callargs == NULL)
+		goto call_fail;
+#ifdef CALL_PROFILE
+	/* At this point, we have to look at the type of func to
+	   update the call stats properly.  Do it here so as to avoid
+	   exposing the call stats machinery outside ceval.c
+	*/
+	if (PyFunction_Check(func))
+		PCALL(PCALL_FUNCTION);
+	else if (PyMethod_Check(func))
+		PCALL(PCALL_METHOD);
+	else if (PyType_Check(func))
+		PCALL(PCALL_TYPE);
+	else
+		PCALL(PCALL_OTHER);
+#endif
+	result = PyObject_Call(func, callargs, kwdict);
+ call_fail:
+	Py_XDECREF(callargs);
+	Py_XDECREF(kwdict);
+	return result;
+}
+
+static PyObject *
+ext_do_call(PyObject *func, PyObject ***pp_stack, int flags, int na, int nk)
+{
+	int nstar = 0;
+	PyObject *callargs = NULL;
+	PyObject *stararg = NULL;
+	PyObject *kwdict = NULL;
+	PyObject *result = NULL;
+
+	if (flags & CALL_FLAG_KW) {
+		kwdict = EXT_POP(*pp_stack);
+		if (!(kwdict && PyDict_Check(kwdict))) {
+			PyErr_Format(PyExc_TypeError,
+				     "%s%s argument after ** "
+				     "must be a dictionary",
+				     PyEval_GetFuncName(func),
+				     PyEval_GetFuncDesc(func));
+			goto ext_call_fail;
+		}
+	}
+	if (flags & CALL_FLAG_VAR) {
+		stararg = EXT_POP(*pp_stack);
+		if (!PyTuple_Check(stararg)) {
+			PyObject *t = NULL;
+			t = PySequence_Tuple(stararg);
+			if (t == NULL) {
+				if (PyErr_ExceptionMatches(PyExc_TypeError)) {
+					PyErr_Format(PyExc_TypeError,
+						     "%s%s argument after * "
+						     "must be a sequence",
+						     PyEval_GetFuncName(func),
+						     PyEval_GetFuncDesc(func));
+				}
+				goto ext_call_fail;
+			}
+			Py_DECREF(stararg);
+			stararg = t;
+		}
+		nstar = PyTuple_GET_SIZE(stararg);
+	}
+	if (nk > 0) {
+		kwdict = update_keyword_args(kwdict, nk, pp_stack, func);
+		if (kwdict == NULL)
+			goto ext_call_fail;
+	}
+	callargs = update_star_args(na, nstar, stararg, pp_stack);
+	if (callargs == NULL)
+		goto ext_call_fail;
+#ifdef CALL_PROFILE
+	/* At this point, we have to look at the type of func to
+	   update the call stats properly.  Do it here so as to avoid
+	   exposing the call stats machinery outside ceval.c
+	*/
+	if (PyFunction_Check(func))
+		PCALL(PCALL_FUNCTION);
+	else if (PyMethod_Check(func))
+		PCALL(PCALL_METHOD);
+	else if (PyType_Check(func))
+		PCALL(PCALL_TYPE);
+	else
+		PCALL(PCALL_OTHER);
+#endif
+	result = PyObject_Call(func, callargs, kwdict);
+      ext_call_fail:
+	Py_XDECREF(callargs);
+	Py_XDECREF(kwdict);
+	Py_XDECREF(stararg);
+	return result;
+}
+
+/* Extract a slice index from a PyInt or PyLong or an object with the
+   nb_index slot defined, and store in *pi.
+   Silently reduce values larger than PY_SSIZE_T_MAX to PY_SSIZE_T_MAX,
+   and silently boost values less than -PY_SSIZE_T_MAX-1 to -PY_SSIZE_T_MAX-1.
+   Return 0 on error, 1 on success.
+*/
+/* Note:  If v is NULL, return success without storing into *pi.  This
+   is because_PyEval_SliceIndex() is called by apply_slice(), which can be
+   called by the SLICE opcode with v and/or w equal to NULL.
+*/
+int
+_PyEval_SliceIndex(PyObject *v, Py_ssize_t *pi)
+{
+	if (v != NULL) {
+		Py_ssize_t x;
+		if (PyInt_Check(v)) {
+			/* XXX(nnorwitz): I think PyInt_AS_LONG is correct,
+			   however, it looks like it should be AsSsize_t.
+			   There should be a comment here explaining why.
+			*/
+			x = PyInt_AS_LONG(v);
+		}
+		else if (PyIndex_Check(v)) {
+			x = PyNumber_AsSsize_t(v, NULL);
+			if (x == -1 && PyErr_Occurred())
+				return 0;
+		}
+		else {
+			PyErr_SetString(PyExc_TypeError,
+					"slice indices must be integers or "
+					"None or have an __index__ method");
+			return 0;
+		}
+		*pi = x;
+	}
+	return 1;
+}
+
+#undef ISINDEX
+#define ISINDEX(x) ((x) == NULL || \
+		    PyInt_Check(x) || PyLong_Check(x) || PyIndex_Check(x))
+
+static PyObject *
+apply_slice(PyObject *u, PyObject *v, PyObject *w) /* return u[v:w] */
+{
+	PyTypeObject *tp = u->ob_type;
+	PySequenceMethods *sq = tp->tp_as_sequence;
+
+	if (sq && sq->sq_slice && ISINDEX(v) && ISINDEX(w)) {
+		Py_ssize_t ilow = 0, ihigh = PY_SSIZE_T_MAX;
+		if (!_PyEval_SliceIndex(v, &ilow))
+			return NULL;
+		if (!_PyEval_SliceIndex(w, &ihigh))
+			return NULL;
+		return PySequence_GetSlice(u, ilow, ihigh);
+	}
+	else {
+		PyObject *slice = PySlice_New(v, w, NULL);
+		if (slice != NULL) {
+			PyObject *res = PyObject_GetItem(u, slice);
+			Py_DECREF(slice);
+			return res;
+		}
+		else
+			return NULL;
+	}
+}
+
+static int
+assign_slice(PyObject *u, PyObject *v, PyObject *w, PyObject *x)
+	/* u[v:w] = x */
+{
+	PyTypeObject *tp = u->ob_type;
+	PySequenceMethods *sq = tp->tp_as_sequence;
+
+	if (sq && sq->sq_ass_slice && ISINDEX(v) && ISINDEX(w)) {
+		Py_ssize_t ilow = 0, ihigh = PY_SSIZE_T_MAX;
+		if (!_PyEval_SliceIndex(v, &ilow))
+			return -1;
+		if (!_PyEval_SliceIndex(w, &ihigh))
+			return -1;
+		if (x == NULL)
+			return PySequence_DelSlice(u, ilow, ihigh);
+		else
+			return PySequence_SetSlice(u, ilow, ihigh, x);
+	}
+	else {
+		PyObject *slice = PySlice_New(v, w, NULL);
+		if (slice != NULL) {
+			int res;
+			if (x != NULL)
+				res = PyObject_SetItem(u, slice, x);
+			else
+				res = PyObject_DelItem(u, slice);
+			Py_DECREF(slice);
+			return res;
+		}
+		else
+			return -1;
+	}
+}
+
+static PyObject *
+cmp_outcome(int op, register PyObject *v, register PyObject *w)
+{
+	int res = 0;
+	switch (op) {
+	case PyCmp_IS:
+		res = (v == w);
+		break;
+	case PyCmp_IS_NOT:
+		res = (v != w);
+		break;
+	case PyCmp_IN:
+		res = PySequence_Contains(w, v);
+		if (res < 0)
+			return NULL;
+		break;
+	case PyCmp_NOT_IN:
+		res = PySequence_Contains(w, v);
+		if (res < 0)
+			return NULL;
+		res = !res;
+		break;
+	case PyCmp_EXC_MATCH:
+		res = PyErr_GivenExceptionMatches(v, w);
+		break;
+	default:
+		return PyObject_RichCompare(v, w, op);
+	}
+	v = res ? Py_True : Py_False;
+	Py_INCREF(v);
+	return v;
+}
+
+static PyObject *
+import_from(PyObject *v, PyObject *name)
+{
+	PyObject *x;
+
+	x = PyObject_GetAttr(v, name);
+	if (x == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) {
+		PyErr_Format(PyExc_ImportError,
+			     "cannot import name %.230s",
+			     PyString_AsString(name));
+	}
+	return x;
+}
+
+static int
+import_all_from(PyObject *locals, PyObject *v)
+{
+	PyObject *all = PyObject_GetAttrString(v, "__all__");
+	PyObject *dict, *name, *value;
+	int skip_leading_underscores = 0;
+	int pos, err;
+
+	if (all == NULL) {
+		if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+			return -1; /* Unexpected error */
+		PyErr_Clear();
+		dict = PyObject_GetAttrString(v, "__dict__");
+		if (dict == NULL) {
+			if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+				return -1;
+			PyErr_SetString(PyExc_ImportError,
+			"from-import-* object has no __dict__ and no __all__");
+			return -1;
+		}
+		all = PyMapping_Keys(dict);
+		Py_DECREF(dict);
+		if (all == NULL)
+			return -1;
+		skip_leading_underscores = 1;
+	}
+
+	for (pos = 0, err = 0; ; pos++) {
+		name = PySequence_GetItem(all, pos);
+		if (name == NULL) {
+			if (!PyErr_ExceptionMatches(PyExc_IndexError))
+				err = -1;
+			else
+				PyErr_Clear();
+			break;
+		}
+		if (skip_leading_underscores &&
+		    PyString_Check(name) &&
+		    PyString_AS_STRING(name)[0] == '_')
+		{
+			Py_DECREF(name);
+			continue;
+		}
+		value = PyObject_GetAttr(v, name);
+		if (value == NULL)
+			err = -1;
+		else if (PyDict_CheckExact(locals))
+			err = PyDict_SetItem(locals, name, value);
+		else
+			err = PyObject_SetItem(locals, name, value);
+		Py_DECREF(name);
+		Py_XDECREF(value);
+		if (err != 0)
+			break;
+	}
+	Py_DECREF(all);
+	return err;
+}
+
+static PyObject *
+build_class(PyObject *methods, PyObject *bases, PyObject *name)
+{
+	PyObject *metaclass = NULL, *result, *base;
+
+	if (PyDict_Check(methods))
+		metaclass = PyDict_GetItemString(methods, "__metaclass__");
+	if (metaclass != NULL)
+		Py_INCREF(metaclass);
+	else if (PyTuple_Check(bases) && PyTuple_GET_SIZE(bases) > 0) {
+		base = PyTuple_GET_ITEM(bases, 0);
+		metaclass = PyObject_GetAttrString(base, "__class__");
+		if (metaclass == NULL) {
+			PyErr_Clear();
+			metaclass = (PyObject *)base->ob_type;
+			Py_INCREF(metaclass);
+		}
+	}
+	else {
+		PyObject *g = PyEval_GetGlobals();
+		if (g != NULL && PyDict_Check(g))
+			metaclass = PyDict_GetItemString(g, "__metaclass__");
+		if (metaclass == NULL)
+			metaclass = (PyObject *) &PyClass_Type;
+		Py_INCREF(metaclass);
+	}
+	result = PyObject_CallFunctionObjArgs(metaclass, name, bases, methods, NULL);
+	Py_DECREF(metaclass);
+	if (result == NULL && PyErr_ExceptionMatches(PyExc_TypeError)) {
+		/* A type error here likely means that the user passed
+		   in a base that was not a class (such the random module
+		   instead of the random.random type).  Help them out with
+		   by augmenting the error message with more information.*/
+
+		PyObject *ptype, *pvalue, *ptraceback;
+
+		PyErr_Fetch(&ptype, &pvalue, &ptraceback);
+		if (PyString_Check(pvalue)) {
+			PyObject *newmsg;
+			newmsg = PyString_FromFormat(
+				"Error when calling the metaclass bases\n    %s",
+				PyString_AS_STRING(pvalue));
+			if (newmsg != NULL) {
+				Py_DECREF(pvalue);
+				pvalue = newmsg;
+			}
+		}
+		PyErr_Restore(ptype, pvalue, ptraceback);
+	}
+	return result;
+}
+
+static int
+exec_statement(PyFrameObject *f, PyObject *prog, PyObject *globals,
+	       PyObject *locals)
+{
+	int n;
+	PyObject *v;
+	int plain = 0;
+
+	if (PyTuple_Check(prog) && globals == Py_None && locals == Py_None &&
+	    ((n = PyTuple_Size(prog)) == 2 || n == 3)) {
+		/* Backward compatibility hack */
+		globals = PyTuple_GetItem(prog, 1);
+		if (n == 3)
+			locals = PyTuple_GetItem(prog, 2);
+		prog = PyTuple_GetItem(prog, 0);
+	}
+	if (globals == Py_None) {
+		globals = PyEval_GetGlobals();
+		if (locals == Py_None) {
+			locals = PyEval_GetLocals();
+			plain = 1;
+		}
+		if (!globals || !locals) {
+			PyErr_SetString(PyExc_SystemError,
+					"globals and locals cannot be NULL");
+			return -1;
+		}
+	}
+	else if (locals == Py_None)
+		locals = globals;
+	if (!PyString_Check(prog) &&
+	    !PyUnicode_Check(prog) &&
+	    !PyCode_Check(prog) &&
+	    !PyFile_Check(prog)) {
+		PyErr_SetString(PyExc_TypeError,
+			"exec: arg 1 must be a string, file, or code object");
+		return -1;
+	}
+	if (!PyDict_Check(globals)) {
+		PyErr_SetString(PyExc_TypeError,
+		    "exec: arg 2 must be a dictionary or None");
+		return -1;
+	}
+	if (!PyMapping_Check(locals)) {
+		PyErr_SetString(PyExc_TypeError,
+		    "exec: arg 3 must be a mapping or None");
+		return -1;
+	}
+	if (PyDict_GetItemString(globals, "__builtins__") == NULL)
+		PyDict_SetItemString(globals, "__builtins__", f->f_builtins);
+	if (PyCode_Check(prog)) {
+		if (PyCode_GetNumFree((PyCodeObject *)prog) > 0) {
+			PyErr_SetString(PyExc_TypeError,
+		"code object passed to exec may not contain free variables");
+			return -1;
+		}
+		v = PyEval_EvalCode((PyCodeObject *) prog, globals, locals);
+	}
+	else if (PyFile_Check(prog)) {
+		FILE *fp = PyFile_AsFile(prog);
+		char *name = PyString_AsString(PyFile_Name(prog));
+		PyCompilerFlags cf;
+		if (name == NULL)
+			return -1;
+		cf.cf_flags = 0;
+		if (PyEval_MergeCompilerFlags(&cf))
+			v = PyRun_FileFlags(fp, name, Py_file_input, globals,
+					    locals, &cf);
+		else
+			v = PyRun_File(fp, name, Py_file_input, globals,
+				       locals);
+	}
+	else {
+		PyObject *tmp = NULL;
+		char *str;
+		PyCompilerFlags cf;
+		cf.cf_flags = 0;
+#ifdef Py_USING_UNICODE
+		if (PyUnicode_Check(prog)) {
+			tmp = PyUnicode_AsUTF8String(prog);
+			if (tmp == NULL)
+				return -1;
+			prog = tmp;
+			cf.cf_flags |= PyCF_SOURCE_IS_UTF8;
+		}
+#endif
+		if (PyString_AsStringAndSize(prog, &str, NULL))
+			return -1;
+		if (PyEval_MergeCompilerFlags(&cf))
+			v = PyRun_StringFlags(str, Py_file_input, globals,
+					      locals, &cf);
+		else
+			v = PyRun_String(str, Py_file_input, globals, locals);
+		Py_XDECREF(tmp);
+	}
+	if (plain)
+		PyFrame_LocalsToFast(f, 0);
+	if (v == NULL)
+		return -1;
+	Py_DECREF(v);
+	return 0;
+}
+
+static void
+format_exc_check_arg(PyObject *exc, char *format_str, PyObject *obj)
+{
+	char *obj_str;
+
+	if (!obj)
+		return;
+
+	obj_str = PyString_AsString(obj);
+	if (!obj_str)
+		return;
+
+	PyErr_Format(exc, format_str, obj_str);
+}
+
+static PyObject *
+string_concatenate(PyObject *v, PyObject *w,
+		   PyFrameObject *f, unsigned char *next_instr)
+{
+	/* This function implements 'variable += expr' when both arguments
+	   are strings. */
+	Py_ssize_t v_len = PyString_GET_SIZE(v);
+	Py_ssize_t w_len = PyString_GET_SIZE(w);
+	Py_ssize_t new_len = v_len + w_len;
+	if (new_len < 0) {
+		PyErr_SetString(PyExc_OverflowError,
+				"strings are too large to concat");
+		return NULL;
+	}
+
+	if (v->ob_refcnt == 2) {
+		/* In the common case, there are 2 references to the value
+		 * stored in 'variable' when the += is performed: one on the
+		 * value stack (in 'v') and one still stored in the 'variable'.
+		 * We try to delete the variable now to reduce the refcnt to 1.
+		 */
+		switch (*next_instr) {
+		case STORE_FAST:
+		{
+			int oparg = PEEKARG();
+			PyObject **fastlocals = f->f_localsplus;
+			if (GETLOCAL(oparg) == v)
+				SETLOCAL(oparg, NULL);
+			break;
+		}
+		case STORE_DEREF:
+		{
+			PyObject **freevars = f->f_localsplus + f->f_code->co_nlocals;
+			PyObject *c = freevars[PEEKARG()];
+			if (PyCell_GET(c) == v)
+				PyCell_Set(c, NULL);
+			break;
+		}
+		case STORE_NAME:
+		{
+			PyObject *names = f->f_code->co_names;
+			PyObject *name = GETITEM(names, PEEKARG());
+			PyObject *locals = f->f_locals;
+			if (PyDict_CheckExact(locals) &&
+			    PyDict_GetItem(locals, name) == v) {
+				if (PyDict_DelItem(locals, name) != 0) {
+					PyErr_Clear();
+				}
+			}
+			break;
+		}
+		}
+	}
+
+	if (v->ob_refcnt == 1 && !PyString_CHECK_INTERNED(v)) {
+		/* Now we own the last reference to 'v', so we can resize it
+		 * in-place.
+		 */
+		if (_PyString_Resize(&v, new_len) != 0) {
+			/* XXX if _PyString_Resize() fails, 'v' has been
+			 * deallocated so it cannot be put back into 'variable'.
+			 * The MemoryError is raised when there is no value in
+			 * 'variable', which might (very remotely) be a cause
+			 * of incompatibilities.
+			 */
+			return NULL;
+		}
+		/* copy 'w' into the newly allocated area of 'v' */
+		memcpy(PyString_AS_STRING(v) + v_len,
+		       PyString_AS_STRING(w), w_len);
+		return v;
+	}
+	else {
+		/* When in-place resizing is not an option. */
+		PyString_Concat(&v, w);
+		return v;
+	}
+}
+
+#ifdef DYNAMIC_EXECUTION_PROFILE
+
+static PyObject *
+getarray(long a[256])
+{
+	int i;
+	PyObject *l = PyList_New(256);
+	if (l == NULL) return NULL;
+	for (i = 0; i < 256; i++) {
+		PyObject *x = PyInt_FromLong(a[i]);
+		if (x == NULL) {
+			Py_DECREF(l);
+			return NULL;
+		}
+		PyList_SetItem(l, i, x);
+	}
+	for (i = 0; i < 256; i++)
+		a[i] = 0;
+	return l;
+}
+
+PyObject *
+_Py_GetDXProfile(PyObject *self, PyObject *args)
+{
+#ifndef DXPAIRS
+	return getarray(dxp);
+#else
+	int i;
+	PyObject *l = PyList_New(257);
+	if (l == NULL) return NULL;
+	for (i = 0; i < 257; i++) {
+		PyObject *x = getarray(dxpairs[i]);
+		if (x == NULL) {
+			Py_DECREF(l);
+			return NULL;
+		}
+		PyList_SetItem(l, i, x);
+	}
+	return l;
+#endif
+}
+
+#endif

Added: vendor/Python/current/Python/codecs.c
===================================================================
--- vendor/Python/current/Python/codecs.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/codecs.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,860 @@
+/* ------------------------------------------------------------------------
+
+   Python Codec Registry and support functions
+
+Written by Marc-Andre Lemburg (mal at lemburg.com).
+
+Copyright (c) Corporation for National Research Initiatives.
+
+   ------------------------------------------------------------------------ */
+
+#include "Python.h"
+#include <ctype.h>
+
+/* --- Codec Registry ----------------------------------------------------- */
+
+/* Import the standard encodings package which will register the first
+   codec search function. 
+
+   This is done in a lazy way so that the Unicode implementation does
+   not downgrade startup time of scripts not needing it.
+
+   ImportErrors are silently ignored by this function. Only one try is
+   made.
+
+*/
+
+static int _PyCodecRegistry_Init(void); /* Forward */
+
+int PyCodec_Register(PyObject *search_function)
+{
+    PyInterpreterState *interp = PyThreadState_GET()->interp;
+    if (interp->codec_search_path == NULL && _PyCodecRegistry_Init())
+	goto onError;
+    if (search_function == NULL) {
+	PyErr_BadArgument();
+	goto onError;
+    }
+    if (!PyCallable_Check(search_function)) {
+	PyErr_SetString(PyExc_TypeError, "argument must be callable");
+	goto onError;
+    }
+    return PyList_Append(interp->codec_search_path, search_function);
+
+ onError:
+    return -1;
+}
+
+/* Convert a string to a normalized Python string: all characters are
+   converted to lower case, spaces are replaced with underscores. */
+
+static
+PyObject *normalizestring(const char *string)
+{
+    register size_t i;
+    size_t len = strlen(string);
+    char *p;
+    PyObject *v;
+    
+    if (len > PY_SSIZE_T_MAX) {
+	PyErr_SetString(PyExc_OverflowError, "string is too large");
+	return NULL;
+    }
+	
+    v = PyString_FromStringAndSize(NULL, len);
+    if (v == NULL)
+	return NULL;
+    p = PyString_AS_STRING(v);
+    for (i = 0; i < len; i++) {
+        register char ch = string[i];
+        if (ch == ' ')
+            ch = '-';
+        else
+            ch = tolower(Py_CHARMASK(ch));
+	p[i] = ch;
+    }
+    return v;
+}
+
+/* Lookup the given encoding and return a tuple providing the codec
+   facilities.
+
+   The encoding string is looked up converted to all lower-case
+   characters. This makes encodings looked up through this mechanism
+   effectively case-insensitive.
+
+   If no codec is found, a LookupError is set and NULL returned. 
+
+   As side effect, this tries to load the encodings package, if not
+   yet done. This is part of the lazy load strategy for the encodings
+   package.
+
+*/
+
+PyObject *_PyCodec_Lookup(const char *encoding)
+{
+    PyInterpreterState *interp;
+    PyObject *result, *args = NULL, *v;
+    Py_ssize_t i, len;
+
+    if (encoding == NULL) {
+	PyErr_BadArgument();
+	goto onError;
+    }
+
+    interp = PyThreadState_GET()->interp;
+    if (interp->codec_search_path == NULL && _PyCodecRegistry_Init())
+	goto onError;
+
+    /* Convert the encoding to a normalized Python string: all
+       characters are converted to lower case, spaces and hyphens are
+       replaced with underscores. */
+    v = normalizestring(encoding);
+    if (v == NULL)
+	goto onError;
+    PyString_InternInPlace(&v);
+
+    /* First, try to lookup the name in the registry dictionary */
+    result = PyDict_GetItem(interp->codec_search_cache, v);
+    if (result != NULL) {
+	Py_INCREF(result);
+	Py_DECREF(v);
+	return result;
+    }
+    
+    /* Next, scan the search functions in order of registration */
+    args = PyTuple_New(1);
+    if (args == NULL)
+	goto onError;
+    PyTuple_SET_ITEM(args,0,v);
+
+    len = PyList_Size(interp->codec_search_path);
+    if (len < 0)
+	goto onError;
+    if (len == 0) {
+	PyErr_SetString(PyExc_LookupError,
+			"no codec search functions registered: "
+			"can't find encoding");
+	goto onError;
+    }
+
+    for (i = 0; i < len; i++) {
+	PyObject *func;
+	
+	func = PyList_GetItem(interp->codec_search_path, i);
+	if (func == NULL)
+	    goto onError;
+	result = PyEval_CallObject(func, args);
+	if (result == NULL)
+	    goto onError;
+	if (result == Py_None) {
+	    Py_DECREF(result);
+	    continue;
+	}
+	if (!PyTuple_Check(result) || PyTuple_GET_SIZE(result) != 4) {
+	    PyErr_SetString(PyExc_TypeError,
+			    "codec search functions must return 4-tuples");
+	    Py_DECREF(result);
+	    goto onError;
+	}
+	break;
+    }
+    if (i == len) {
+	/* XXX Perhaps we should cache misses too ? */
+	PyErr_Format(PyExc_LookupError,
+                     "unknown encoding: %s", encoding);
+	goto onError;
+    }
+
+    /* Cache and return the result */
+    PyDict_SetItem(interp->codec_search_cache, v, result);
+    Py_DECREF(args);
+    return result;
+
+ onError:
+    Py_XDECREF(args);
+    return NULL;
+}
+
+static
+PyObject *args_tuple(PyObject *object,
+		     const char *errors)
+{
+    PyObject *args;
+    
+    args = PyTuple_New(1 + (errors != NULL));
+    if (args == NULL)
+	return NULL;
+    Py_INCREF(object);
+    PyTuple_SET_ITEM(args,0,object);
+    if (errors) {
+	PyObject *v;
+	
+	v = PyString_FromString(errors);
+	if (v == NULL) {
+	    Py_DECREF(args);
+	    return NULL;
+	}
+	PyTuple_SET_ITEM(args, 1, v);
+    }
+    return args;
+}
+
+/* Helper function to get a codec item */
+
+static
+PyObject *codec_getitem(const char *encoding, int index)
+{
+    PyObject *codecs;
+    PyObject *v;
+
+    codecs = _PyCodec_Lookup(encoding);
+    if (codecs == NULL)
+	return NULL;
+    v = PyTuple_GET_ITEM(codecs, index);
+    Py_DECREF(codecs);
+    Py_INCREF(v);
+    return v;
+}
+
+/* Helper function to create an incremental codec. */
+
+static
+PyObject *codec_getincrementalcodec(const char *encoding,
+				    const char *errors,
+				    const char *attrname)
+{
+    PyObject *codecs, *ret, *inccodec;
+
+    codecs = _PyCodec_Lookup(encoding);
+    if (codecs == NULL)
+	return NULL;
+    inccodec = PyObject_GetAttrString(codecs, attrname);
+    Py_DECREF(codecs);
+    if (inccodec == NULL)
+	return NULL;
+    if (errors)
+	ret = PyObject_CallFunction(inccodec, "s", errors);
+    else
+	ret = PyObject_CallFunction(inccodec, NULL);
+    Py_DECREF(inccodec);
+    return ret;
+}
+
+/* Helper function to create a stream codec. */
+
+static
+PyObject *codec_getstreamcodec(const char *encoding,
+			       PyObject *stream,
+			       const char *errors,
+			       const int index)
+{
+    PyObject *codecs, *streamcodec, *codeccls;
+
+    codecs = _PyCodec_Lookup(encoding);
+    if (codecs == NULL)
+	return NULL;
+
+    codeccls = PyTuple_GET_ITEM(codecs, index);
+    if (errors != NULL)
+	streamcodec = PyObject_CallFunction(codeccls, "Os", stream, errors);
+    else
+	streamcodec = PyObject_CallFunction(codeccls, "O", stream);
+    Py_DECREF(codecs);
+    return streamcodec;
+}
+
+/* Convenience APIs to query the Codec registry. 
+   
+   All APIs return a codec object with incremented refcount.
+   
+ */
+
+PyObject *PyCodec_Encoder(const char *encoding)
+{
+    return codec_getitem(encoding, 0);
+}
+
+PyObject *PyCodec_Decoder(const char *encoding)
+{
+    return codec_getitem(encoding, 1);
+}
+
+PyObject *PyCodec_IncrementalEncoder(const char *encoding,
+				     const char *errors)
+{
+    return codec_getincrementalcodec(encoding, errors, "incrementalencoder");
+}
+
+PyObject *PyCodec_IncrementalDecoder(const char *encoding,
+				     const char *errors)
+{
+    return codec_getincrementalcodec(encoding, errors, "incrementaldecoder");
+}
+
+PyObject *PyCodec_StreamReader(const char *encoding,
+			       PyObject *stream,
+			       const char *errors)
+{
+    return codec_getstreamcodec(encoding, stream, errors, 2);
+}
+
+PyObject *PyCodec_StreamWriter(const char *encoding,
+			       PyObject *stream,
+			       const char *errors)
+{
+    return codec_getstreamcodec(encoding, stream, errors, 3);
+}
+
+/* Encode an object (e.g. an Unicode object) using the given encoding
+   and return the resulting encoded object (usually a Python string).
+
+   errors is passed to the encoder factory as argument if non-NULL. */
+
+PyObject *PyCodec_Encode(PyObject *object,
+			 const char *encoding,
+			 const char *errors)
+{
+    PyObject *encoder = NULL;
+    PyObject *args = NULL, *result = NULL;
+    PyObject *v;
+
+    encoder = PyCodec_Encoder(encoding);
+    if (encoder == NULL)
+	goto onError;
+
+    args = args_tuple(object, errors);
+    if (args == NULL)
+	goto onError;
+    
+    result = PyEval_CallObject(encoder,args);
+    if (result == NULL)
+	goto onError;
+
+    if (!PyTuple_Check(result) || 
+	PyTuple_GET_SIZE(result) != 2) {
+	PyErr_SetString(PyExc_TypeError,
+			"encoder must return a tuple (object,integer)");
+	goto onError;
+    }
+    v = PyTuple_GET_ITEM(result,0);
+    Py_INCREF(v);
+    /* We don't check or use the second (integer) entry. */
+
+    Py_DECREF(args);
+    Py_DECREF(encoder);
+    Py_DECREF(result);
+    return v;
+	
+ onError:
+    Py_XDECREF(result);
+    Py_XDECREF(args);
+    Py_XDECREF(encoder);
+    return NULL;
+}
+
+/* Decode an object (usually a Python string) using the given encoding
+   and return an equivalent object (e.g. an Unicode object).
+
+   errors is passed to the decoder factory as argument if non-NULL. */
+
+PyObject *PyCodec_Decode(PyObject *object,
+			 const char *encoding,
+			 const char *errors)
+{
+    PyObject *decoder = NULL;
+    PyObject *args = NULL, *result = NULL;
+    PyObject *v;
+
+    decoder = PyCodec_Decoder(encoding);
+    if (decoder == NULL)
+	goto onError;
+
+    args = args_tuple(object, errors);
+    if (args == NULL)
+	goto onError;
+    
+    result = PyEval_CallObject(decoder,args);
+    if (result == NULL)
+	goto onError;
+    if (!PyTuple_Check(result) || 
+	PyTuple_GET_SIZE(result) != 2) {
+	PyErr_SetString(PyExc_TypeError,
+			"decoder must return a tuple (object,integer)");
+	goto onError;
+    }
+    v = PyTuple_GET_ITEM(result,0);
+    Py_INCREF(v);
+    /* We don't check or use the second (integer) entry. */
+
+    Py_DECREF(args);
+    Py_DECREF(decoder);
+    Py_DECREF(result);
+    return v;
+	
+ onError:
+    Py_XDECREF(args);
+    Py_XDECREF(decoder);
+    Py_XDECREF(result);
+    return NULL;
+}
+
+/* Register the error handling callback function error under the name
+   name. This function will be called by the codec when it encounters
+   an unencodable characters/undecodable bytes and doesn't know the
+   callback name, when name is specified as the error parameter
+   in the call to the encode/decode function.
+   Return 0 on success, -1 on error */
+int PyCodec_RegisterError(const char *name, PyObject *error)
+{
+    PyInterpreterState *interp = PyThreadState_GET()->interp;
+    if (interp->codec_search_path == NULL && _PyCodecRegistry_Init())
+	return -1;
+    if (!PyCallable_Check(error)) {
+	PyErr_SetString(PyExc_TypeError, "handler must be callable");
+	return -1;
+    }
+    return PyDict_SetItemString(interp->codec_error_registry,
+	    			(char *)name, error);
+}
+
+/* Lookup the error handling callback function registered under the
+   name error. As a special case NULL can be passed, in which case
+   the error handling callback for strict encoding will be returned. */
+PyObject *PyCodec_LookupError(const char *name)
+{
+    PyObject *handler = NULL;
+
+    PyInterpreterState *interp = PyThreadState_GET()->interp;
+    if (interp->codec_search_path == NULL && _PyCodecRegistry_Init())
+	return NULL;
+
+    if (name==NULL)
+	name = "strict";
+    handler = PyDict_GetItemString(interp->codec_error_registry, (char *)name);
+    if (!handler)
+	PyErr_Format(PyExc_LookupError, "unknown error handler name '%.400s'", name);
+    else
+	Py_INCREF(handler);
+    return handler;
+}
+
+static void wrong_exception_type(PyObject *exc)
+{
+    PyObject *type = PyObject_GetAttrString(exc, "__class__");
+    if (type != NULL) {
+	PyObject *name = PyObject_GetAttrString(type, "__name__");
+	Py_DECREF(type);
+	if (name != NULL) {
+	    PyObject *string = PyObject_Str(name);
+	    Py_DECREF(name);
+	    if (string != NULL) {
+	        PyErr_Format(PyExc_TypeError,
+		    "don't know how to handle %.400s in error callback",
+		    PyString_AS_STRING(string));
+	        Py_DECREF(string);
+	    }
+	}
+    }
+}
+
+PyObject *PyCodec_StrictErrors(PyObject *exc)
+{
+    if (PyExceptionInstance_Check(exc))
+        PyErr_SetObject(PyExceptionInstance_Class(exc), exc);
+    else
+	PyErr_SetString(PyExc_TypeError, "codec must pass exception instance");
+    return NULL;
+}
+
+
+#ifdef Py_USING_UNICODE
+PyObject *PyCodec_IgnoreErrors(PyObject *exc)
+{
+    Py_ssize_t end;
+    if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) {
+	if (PyUnicodeEncodeError_GetEnd(exc, &end))
+	    return NULL;
+    }
+    else if (PyObject_IsInstance(exc, PyExc_UnicodeDecodeError)) {
+	if (PyUnicodeDecodeError_GetEnd(exc, &end))
+	    return NULL;
+    }
+    else if (PyObject_IsInstance(exc, PyExc_UnicodeTranslateError)) {
+	if (PyUnicodeTranslateError_GetEnd(exc, &end))
+	    return NULL;
+    }
+    else {
+	wrong_exception_type(exc);
+	return NULL;
+    }
+    /* ouch: passing NULL, 0, pos gives None instead of u'' */
+    return Py_BuildValue("(u#n)", &end, 0, end);
+}
+
+
+PyObject *PyCodec_ReplaceErrors(PyObject *exc)
+{
+    PyObject *restuple;
+    Py_ssize_t start;
+    Py_ssize_t end;
+    Py_ssize_t i;
+
+    if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) {
+	PyObject *res;
+	Py_UNICODE *p;
+	if (PyUnicodeEncodeError_GetStart(exc, &start))
+	    return NULL;
+	if (PyUnicodeEncodeError_GetEnd(exc, &end))
+	    return NULL;
+	res = PyUnicode_FromUnicode(NULL, end-start);
+	if (res == NULL)
+	    return NULL;
+	for (p = PyUnicode_AS_UNICODE(res), i = start;
+	    i<end; ++p, ++i)
+	    *p = '?';
+	restuple = Py_BuildValue("(On)", res, end);
+	Py_DECREF(res);
+	return restuple;
+    }
+    else if (PyObject_IsInstance(exc, PyExc_UnicodeDecodeError)) {
+	Py_UNICODE res = Py_UNICODE_REPLACEMENT_CHARACTER;
+	if (PyUnicodeDecodeError_GetEnd(exc, &end))
+	    return NULL;
+	return Py_BuildValue("(u#n)", &res, 1, end);
+    }
+    else if (PyObject_IsInstance(exc, PyExc_UnicodeTranslateError)) {
+	PyObject *res;
+	Py_UNICODE *p;
+	if (PyUnicodeTranslateError_GetStart(exc, &start))
+	    return NULL;
+	if (PyUnicodeTranslateError_GetEnd(exc, &end))
+	    return NULL;
+	res = PyUnicode_FromUnicode(NULL, end-start);
+	if (res == NULL)
+	    return NULL;
+	for (p = PyUnicode_AS_UNICODE(res), i = start;
+	    i<end; ++p, ++i)
+	    *p = Py_UNICODE_REPLACEMENT_CHARACTER;
+	restuple = Py_BuildValue("(On)", res, end);
+	Py_DECREF(res);
+	return restuple;
+    }
+    else {
+	wrong_exception_type(exc);
+	return NULL;
+    }
+}
+
+PyObject *PyCodec_XMLCharRefReplaceErrors(PyObject *exc)
+{
+    if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) {
+	PyObject *restuple;
+	PyObject *object;
+	Py_ssize_t start;
+	Py_ssize_t end;
+	PyObject *res;
+	Py_UNICODE *p;
+	Py_UNICODE *startp;
+	Py_UNICODE *outp;
+	int ressize;
+	if (PyUnicodeEncodeError_GetStart(exc, &start))
+	    return NULL;
+	if (PyUnicodeEncodeError_GetEnd(exc, &end))
+	    return NULL;
+	if (!(object = PyUnicodeEncodeError_GetObject(exc)))
+	    return NULL;
+	startp = PyUnicode_AS_UNICODE(object);
+	for (p = startp+start, ressize = 0; p < startp+end; ++p) {
+	    if (*p<10)
+		ressize += 2+1+1;
+	    else if (*p<100)
+		ressize += 2+2+1;
+	    else if (*p<1000)
+		ressize += 2+3+1;
+	    else if (*p<10000)
+		ressize += 2+4+1;
+#ifndef Py_UNICODE_WIDE
+	    else
+		ressize += 2+5+1;
+#else
+	    else if (*p<100000)
+		ressize += 2+5+1;
+	    else if (*p<1000000)
+		ressize += 2+6+1;
+	    else
+		ressize += 2+7+1;
+#endif
+	}
+	/* allocate replacement */
+	res = PyUnicode_FromUnicode(NULL, ressize);
+	if (res == NULL) {
+	    Py_DECREF(object);
+	    return NULL;
+	}
+	/* generate replacement */
+	for (p = startp+start, outp = PyUnicode_AS_UNICODE(res);
+	    p < startp+end; ++p) {
+	    Py_UNICODE c = *p;
+	    int digits;
+	    int base;
+	    *outp++ = '&';
+	    *outp++ = '#';
+	    if (*p<10) {
+		digits = 1;
+		base = 1;
+	    }
+	    else if (*p<100) {
+		digits = 2;
+		base = 10;
+	    }
+	    else if (*p<1000) {
+		digits = 3;
+		base = 100;
+	    }
+	    else if (*p<10000) {
+		digits = 4;
+		base = 1000;
+	    }
+#ifndef Py_UNICODE_WIDE
+	    else {
+		digits = 5;
+		base = 10000;
+	    }
+#else
+	    else if (*p<100000) {
+		digits = 5;
+		base = 10000;
+	    }
+	    else if (*p<1000000) {
+		digits = 6;
+		base = 100000;
+	    }
+	    else {
+		digits = 7;
+		base = 1000000;
+	    }
+#endif
+	    while (digits-->0) {
+		*outp++ = '0' + c/base;
+		c %= base;
+		base /= 10;
+	    }
+	    *outp++ = ';';
+	}
+	restuple = Py_BuildValue("(On)", res, end);
+	Py_DECREF(res);
+	Py_DECREF(object);
+	return restuple;
+    }
+    else {
+	wrong_exception_type(exc);
+	return NULL;
+    }
+}
+
+static Py_UNICODE hexdigits[] = {
+    '0', '1', '2', '3', '4', '5', '6', '7',
+    '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
+};
+
+PyObject *PyCodec_BackslashReplaceErrors(PyObject *exc)
+{
+    if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) {
+	PyObject *restuple;
+	PyObject *object;
+	Py_ssize_t start;
+	Py_ssize_t end;
+	PyObject *res;
+	Py_UNICODE *p;
+	Py_UNICODE *startp;
+	Py_UNICODE *outp;
+	int ressize;
+	if (PyUnicodeEncodeError_GetStart(exc, &start))
+	    return NULL;
+	if (PyUnicodeEncodeError_GetEnd(exc, &end))
+	    return NULL;
+	if (!(object = PyUnicodeEncodeError_GetObject(exc)))
+	    return NULL;
+	startp = PyUnicode_AS_UNICODE(object);
+	for (p = startp+start, ressize = 0; p < startp+end; ++p) {
+#ifdef Py_UNICODE_WIDE
+	    if (*p >= 0x00010000)
+		ressize += 1+1+8;
+	    else
+#endif
+	    if (*p >= 0x100) {
+		ressize += 1+1+4;
+	    }
+	    else
+		ressize += 1+1+2;
+	}
+	res = PyUnicode_FromUnicode(NULL, ressize);
+	if (res==NULL)
+	    return NULL;
+	for (p = startp+start, outp = PyUnicode_AS_UNICODE(res);
+	    p < startp+end; ++p) {
+	    Py_UNICODE c = *p;
+	    *outp++ = '\\';
+#ifdef Py_UNICODE_WIDE
+	    if (c >= 0x00010000) {
+		*outp++ = 'U';
+		*outp++ = hexdigits[(c>>28)&0xf];
+		*outp++ = hexdigits[(c>>24)&0xf];
+		*outp++ = hexdigits[(c>>20)&0xf];
+		*outp++ = hexdigits[(c>>16)&0xf];
+		*outp++ = hexdigits[(c>>12)&0xf];
+		*outp++ = hexdigits[(c>>8)&0xf];
+	    }
+	    else
+#endif
+	    if (c >= 0x100) {
+		*outp++ = 'u';
+		*outp++ = hexdigits[(c>>12)&0xf];
+		*outp++ = hexdigits[(c>>8)&0xf];
+	    }
+	    else
+		*outp++ = 'x';
+	    *outp++ = hexdigits[(c>>4)&0xf];
+	    *outp++ = hexdigits[c&0xf];
+	}
+
+	restuple = Py_BuildValue("(On)", res, end);
+	Py_DECREF(res);
+	Py_DECREF(object);
+	return restuple;
+    }
+    else {
+	wrong_exception_type(exc);
+	return NULL;
+    }
+}
+#endif
+
+static PyObject *strict_errors(PyObject *self, PyObject *exc)
+{
+    return PyCodec_StrictErrors(exc);
+}
+
+
+#ifdef Py_USING_UNICODE
+static PyObject *ignore_errors(PyObject *self, PyObject *exc)
+{
+    return PyCodec_IgnoreErrors(exc);
+}
+
+
+static PyObject *replace_errors(PyObject *self, PyObject *exc)
+{
+    return PyCodec_ReplaceErrors(exc);
+}
+
+
+static PyObject *xmlcharrefreplace_errors(PyObject *self, PyObject *exc)
+{
+    return PyCodec_XMLCharRefReplaceErrors(exc);
+}
+
+
+static PyObject *backslashreplace_errors(PyObject *self, PyObject *exc)
+{
+    return PyCodec_BackslashReplaceErrors(exc);
+}
+#endif
+
+static int _PyCodecRegistry_Init(void)
+{
+    static struct {
+	char *name;
+	PyMethodDef def;
+    } methods[] =
+    {
+	{
+	    "strict",
+	    {
+		"strict_errors",
+		strict_errors,
+		METH_O
+	    }
+	},
+#ifdef Py_USING_UNICODE
+	{
+	    "ignore",
+	    {
+		"ignore_errors",
+		ignore_errors,
+		METH_O
+	    }
+	},
+	{
+	    "replace",
+	    {
+		"replace_errors",
+		replace_errors,
+		METH_O
+	    }
+	},
+	{
+	    "xmlcharrefreplace",
+	    {
+		"xmlcharrefreplace_errors",
+		xmlcharrefreplace_errors,
+		METH_O
+	    }
+	},
+	{
+	    "backslashreplace",
+	    {
+		"backslashreplace_errors",
+		backslashreplace_errors,
+		METH_O
+	    }
+	}
+#endif
+    };
+
+    PyInterpreterState *interp = PyThreadState_GET()->interp;
+    PyObject *mod;
+    unsigned i;
+
+    if (interp->codec_search_path != NULL)
+	return 0;
+
+    interp->codec_search_path = PyList_New(0);
+    interp->codec_search_cache = PyDict_New();
+    interp->codec_error_registry = PyDict_New();
+
+    if (interp->codec_error_registry) {
+	for (i = 0; i < sizeof(methods)/sizeof(methods[0]); ++i) {
+	    PyObject *func = PyCFunction_New(&methods[i].def, NULL);
+	    int res;
+	    if (!func)
+		Py_FatalError("can't initialize codec error registry");
+	    res = PyCodec_RegisterError(methods[i].name, func);
+	    Py_DECREF(func);
+	    if (res)
+		Py_FatalError("can't initialize codec error registry");
+	}
+    }
+
+    if (interp->codec_search_path == NULL ||
+	interp->codec_search_cache == NULL ||
+	interp->codec_error_registry == NULL)
+	Py_FatalError("can't initialize codec registry");
+
+    mod = PyImport_ImportModuleLevel("encodings", NULL, NULL, NULL, 0);
+    if (mod == NULL) {
+	if (PyErr_ExceptionMatches(PyExc_ImportError)) {
+	    /* Ignore ImportErrors... this is done so that
+	       distributions can disable the encodings package. Note
+	       that other errors are not masked, e.g. SystemErrors
+	       raised to inform the user of an error in the Python
+	       configuration are still reported back to the user. */
+	    PyErr_Clear();
+	    return 0;
+	}
+	return -1;
+    }
+    Py_DECREF(mod);
+    return 0;
+}

Added: vendor/Python/current/Python/compile.c
===================================================================
--- vendor/Python/current/Python/compile.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/compile.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,4570 @@
+/*
+ * This file compiles an abstract syntax tree (AST) into Python bytecode.
+ *
+ * The primary entry point is PyAST_Compile(), which returns a
+ * PyCodeObject.  The compiler makes several passes to build the code
+ * object:
+ *   1. Checks for future statements.  See future.c
+ *   2. Builds a symbol table.	See symtable.c.
+ *   3. Generate code for basic blocks.	 See compiler_mod() in this file.
+ *   4. Assemble the basic blocks into final code.  See assemble() in
+ *   this file.	 
+ *
+ * Note that compiler_mod() suggests module, but the module ast type
+ * (mod_ty) has cases for expressions and interactive statements.
+ *
+ * CAUTION: The VISIT_* macros abort the current function when they
+ * encounter a problem. So don't invoke them when there is memory
+ * which needs to be released. Code blocks are OK, as the compiler
+ * structure takes care of releasing those.
+ */
+
+#include "Python.h"
+
+#include "Python-ast.h"
+#include "node.h"
+#include "pyarena.h"
+#include "ast.h"
+#include "code.h"
+#include "compile.h"
+#include "symtable.h"
+#include "opcode.h"
+
+int Py_OptimizeFlag = 0;
+
+/*
+  ISSUES:
+
+  opcode_stack_effect() function should be reviewed since stack depth bugs
+  could be really hard to find later.
+
+  Dead code is being generated (i.e. after unconditional jumps).
+    XXX(nnorwitz): not sure this is still true
+*/
+
+#define DEFAULT_BLOCK_SIZE 16
+#define DEFAULT_BLOCKS 8
+#define DEFAULT_CODE_SIZE 128
+#define DEFAULT_LNOTAB_SIZE 16
+
+struct instr {
+	unsigned i_jabs : 1;
+	unsigned i_jrel : 1;
+	unsigned i_hasarg : 1;
+	unsigned char i_opcode;
+	int i_oparg;
+	struct basicblock_ *i_target; /* target block (if jump instruction) */
+	int i_lineno;
+};
+
+typedef struct basicblock_ {
+    /* Each basicblock in a compilation unit is linked via b_list in the
+       reverse order that the block are allocated.  b_list points to the next
+       block, not to be confused with b_next, which is next by control flow. */
+	struct basicblock_ *b_list;
+	/* number of instructions used */
+	int b_iused;
+	/* length of instruction array (b_instr) */
+	int b_ialloc;
+	/* pointer to an array of instructions, initially NULL */
+	struct instr *b_instr;
+	/* If b_next is non-NULL, it is a pointer to the next
+	   block reached by normal control flow. */
+	struct basicblock_ *b_next;
+	/* b_seen is used to perform a DFS of basicblocks. */
+	unsigned b_seen : 1;
+	/* b_return is true if a RETURN_VALUE opcode is inserted. */
+	unsigned b_return : 1;
+	/* depth of stack upon entry of block, computed by stackdepth() */
+	int b_startdepth;
+	/* instruction offset for block, computed by assemble_jump_offsets() */
+	int b_offset;
+} basicblock;
+
+/* fblockinfo tracks the current frame block.
+
+A frame block is used to handle loops, try/except, and try/finally.
+It's called a frame block to distinguish it from a basic block in the
+compiler IR.
+*/
+
+enum fblocktype { LOOP, EXCEPT, FINALLY_TRY, FINALLY_END };
+
+struct fblockinfo {
+	enum fblocktype fb_type;
+	basicblock *fb_block;
+};
+
+/* The following items change on entry and exit of code blocks.
+   They must be saved and restored when returning to a block.
+*/
+struct compiler_unit {
+	PySTEntryObject *u_ste;
+
+	PyObject *u_name;
+	/* The following fields are dicts that map objects to
+	   the index of them in co_XXX.	 The index is used as
+	   the argument for opcodes that refer to those collections.
+	*/
+	PyObject *u_consts;    /* all constants */
+	PyObject *u_names;     /* all names */
+	PyObject *u_varnames;  /* local variables */
+	PyObject *u_cellvars;  /* cell variables */
+	PyObject *u_freevars;  /* free variables */
+
+	PyObject *u_private;	/* for private name mangling */
+
+	int u_argcount;	   /* number of arguments for block */ 
+    /* Pointer to the most recently allocated block.  By following b_list
+       members, you can reach all early allocated blocks. */
+	basicblock *u_blocks;
+	basicblock *u_curblock; /* pointer to current block */
+	int u_tmpname;	   /* temporary variables for list comps */
+
+	int u_nfblocks;
+	struct fblockinfo u_fblock[CO_MAXBLOCKS];
+
+	int u_firstlineno; /* the first lineno of the block */
+	int u_lineno;	   /* the lineno for the current stmt */
+	bool u_lineno_set; /* boolean to indicate whether instr
+			      has been generated with current lineno */
+};
+
+/* This struct captures the global state of a compilation.  
+
+The u pointer points to the current compilation unit, while units
+for enclosing blocks are stored in c_stack.	The u and c_stack are
+managed by compiler_enter_scope() and compiler_exit_scope().
+*/
+
+struct compiler {
+	const char *c_filename;
+	struct symtable *c_st;
+	PyFutureFeatures *c_future; /* pointer to module's __future__ */
+	PyCompilerFlags *c_flags;
+
+	int c_interactive;	 /* true if in interactive mode */
+	int c_nestlevel;
+
+	struct compiler_unit *u; /* compiler state for current block */
+	PyObject *c_stack;	 /* Python list holding compiler_unit ptrs */
+	char *c_encoding;	 /* source encoding (a borrowed reference) */
+	PyArena *c_arena;	 /* pointer to memory allocation arena */
+};
+
+struct assembler {
+	PyObject *a_bytecode;  /* string containing bytecode */
+	int a_offset;	       /* offset into bytecode */
+	int a_nblocks;	       /* number of reachable blocks */
+	basicblock **a_postorder; /* list of blocks in dfs postorder */
+	PyObject *a_lnotab;    /* string containing lnotab */
+	int a_lnotab_off;      /* offset into lnotab */
+	int a_lineno;	       /* last lineno of emitted instruction */
+	int a_lineno_off;      /* bytecode offset of last lineno */
+};
+
+static int compiler_enter_scope(struct compiler *, identifier, void *, int);
+static void compiler_free(struct compiler *);
+static basicblock *compiler_new_block(struct compiler *);
+static int compiler_next_instr(struct compiler *, basicblock *);
+static int compiler_addop(struct compiler *, int);
+static int compiler_addop_o(struct compiler *, int, PyObject *, PyObject *);
+static int compiler_addop_i(struct compiler *, int, int);
+static int compiler_addop_j(struct compiler *, int, basicblock *, int);
+static basicblock *compiler_use_new_block(struct compiler *);
+static int compiler_error(struct compiler *, const char *);
+static int compiler_nameop(struct compiler *, identifier, expr_context_ty);
+
+static PyCodeObject *compiler_mod(struct compiler *, mod_ty);
+static int compiler_visit_stmt(struct compiler *, stmt_ty);
+static int compiler_visit_keyword(struct compiler *, keyword_ty);
+static int compiler_visit_expr(struct compiler *, expr_ty);
+static int compiler_augassign(struct compiler *, stmt_ty);
+static int compiler_visit_slice(struct compiler *, slice_ty,
+				expr_context_ty);
+
+static int compiler_push_fblock(struct compiler *, enum fblocktype,
+				basicblock *);
+static void compiler_pop_fblock(struct compiler *, enum fblocktype,
+				basicblock *);
+/* Returns true if there is a loop on the fblock stack. */
+static int compiler_in_loop(struct compiler *);
+
+static int inplace_binop(struct compiler *, operator_ty);
+static int expr_constant(expr_ty e);
+
+static int compiler_with(struct compiler *, stmt_ty);
+
+static PyCodeObject *assemble(struct compiler *, int addNone);
+static PyObject *__doc__;
+
+PyObject *
+_Py_Mangle(PyObject *privateobj, PyObject *ident)
+{
+	/* Name mangling: __private becomes _classname__private.
+	   This is independent from how the name is used. */
+	const char *p, *name = PyString_AsString(ident);
+	char *buffer;
+	size_t nlen, plen;
+	if (privateobj == NULL || !PyString_Check(privateobj) ||
+	    name == NULL || name[0] != '_' || name[1] != '_') {
+		Py_INCREF(ident);
+		return ident;
+	}
+	p = PyString_AsString(privateobj);
+	nlen = strlen(name);
+	if (name[nlen-1] == '_' && name[nlen-2] == '_') {
+		Py_INCREF(ident);
+		return ident; /* Don't mangle __whatever__ */
+	}
+	/* Strip leading underscores from class name */
+	while (*p == '_')
+		p++;
+	if (*p == '\0') {
+		Py_INCREF(ident);
+		return ident; /* Don't mangle if class is just underscores */
+	}
+	plen = strlen(p);
+	ident = PyString_FromStringAndSize(NULL, 1 + nlen + plen);
+	if (!ident)
+		return 0;
+	/* ident = "_" + p[:plen] + name # i.e. 1+plen+nlen bytes */
+	buffer = PyString_AS_STRING(ident);
+	buffer[0] = '_';
+	strncpy(buffer+1, p, plen);
+	strcpy(buffer+1+plen, name);
+	return ident;
+}
+
+static int
+compiler_init(struct compiler *c)
+{
+	memset(c, 0, sizeof(struct compiler));
+
+	c->c_stack = PyList_New(0);
+	if (!c->c_stack)
+		return 0;
+
+	return 1;
+}
+
+PyCodeObject *
+PyAST_Compile(mod_ty mod, const char *filename, PyCompilerFlags *flags,
+	      PyArena *arena)
+{
+	struct compiler c;
+	PyCodeObject *co = NULL;
+	PyCompilerFlags local_flags;
+	int merged;
+
+	if (!__doc__) {
+		__doc__ = PyString_InternFromString("__doc__");
+		if (!__doc__)
+			return NULL;
+	}
+
+	if (!compiler_init(&c))
+		return NULL;
+	c.c_filename = filename;
+	c.c_arena = arena;
+	c.c_future = PyFuture_FromAST(mod, filename);
+	if (c.c_future == NULL)
+		goto finally;
+	if (!flags) {
+		local_flags.cf_flags = 0;
+		flags = &local_flags;
+	}
+	merged = c.c_future->ff_features | flags->cf_flags;
+	c.c_future->ff_features = merged;
+	flags->cf_flags = merged;
+	c.c_flags = flags;
+	c.c_nestlevel = 0;
+
+	c.c_st = PySymtable_Build(mod, filename, c.c_future);
+	if (c.c_st == NULL) {
+		if (!PyErr_Occurred())
+			PyErr_SetString(PyExc_SystemError, "no symtable");
+		goto finally;
+	}
+
+	/* XXX initialize to NULL for now, need to handle */
+	c.c_encoding = NULL;
+
+	co = compiler_mod(&c, mod);
+
+ finally:
+	compiler_free(&c);
+	assert(co || PyErr_Occurred());
+	return co;
+}
+
+PyCodeObject *
+PyNode_Compile(struct _node *n, const char *filename)
+{
+	PyCodeObject *co = NULL;
+	mod_ty mod;
+	PyArena *arena = PyArena_New();
+	if (!arena)
+		return NULL;
+	mod = PyAST_FromNode(n, NULL, filename, arena);
+	if (mod)
+		co = PyAST_Compile(mod, filename, NULL, arena);
+	PyArena_Free(arena);
+	return co;
+}
+
+static void
+compiler_free(struct compiler *c)
+{
+	if (c->c_st)
+		PySymtable_Free(c->c_st);
+	if (c->c_future)
+		PyObject_Free(c->c_future);
+	Py_DECREF(c->c_stack);
+}
+
+static PyObject *
+list2dict(PyObject *list)
+{
+	Py_ssize_t i, n;
+	PyObject *v, *k;
+	PyObject *dict = PyDict_New();
+	if (!dict) return NULL;
+
+	n = PyList_Size(list);
+	for (i = 0; i < n; i++) {
+		v = PyInt_FromLong(i);
+		if (!v) {
+			Py_DECREF(dict);
+			return NULL;
+		}
+		k = PyList_GET_ITEM(list, i);
+		k = PyTuple_Pack(2, k, k->ob_type);
+		if (k == NULL || PyDict_SetItem(dict, k, v) < 0) {
+			Py_XDECREF(k);
+			Py_DECREF(v);
+			Py_DECREF(dict);
+			return NULL;
+		}
+		Py_DECREF(k);
+		Py_DECREF(v);
+	}
+	return dict;
+}
+
+/* Return new dict containing names from src that match scope(s).
+
+src is a symbol table dictionary.  If the scope of a name matches
+either scope_type or flag is set, insert it into the new dict.	The
+values are integers, starting at offset and increasing by one for
+each key.
+*/
+
+static PyObject *
+dictbytype(PyObject *src, int scope_type, int flag, int offset)
+{
+	Py_ssize_t pos = 0, i = offset, scope;
+	PyObject *k, *v, *dest = PyDict_New();
+
+	assert(offset >= 0);
+	if (dest == NULL)
+		return NULL;
+
+	while (PyDict_Next(src, &pos, &k, &v)) {
+		/* XXX this should probably be a macro in symtable.h */
+		assert(PyInt_Check(v));
+		scope = (PyInt_AS_LONG(v) >> SCOPE_OFF) & SCOPE_MASK;
+
+		if (scope == scope_type || PyInt_AS_LONG(v) & flag) {
+			PyObject *tuple, *item = PyInt_FromLong(i);
+			if (item == NULL) {
+				Py_DECREF(dest);
+				return NULL;
+			}
+			i++;
+			tuple = PyTuple_Pack(2, k, k->ob_type);
+			if (!tuple || PyDict_SetItem(dest, tuple, item) < 0) {
+				Py_DECREF(item);
+				Py_DECREF(dest);
+				Py_XDECREF(tuple);
+				return NULL;
+			}
+			Py_DECREF(item);
+			Py_DECREF(tuple);
+		}
+	}
+	return dest;
+}
+
+/* Begin: Peephole optimizations ----------------------------------------- */
+
+#define GETARG(arr, i) ((int)((arr[i+2]<<8) + arr[i+1]))
+#define UNCONDITIONAL_JUMP(op)	(op==JUMP_ABSOLUTE || op==JUMP_FORWARD)
+#define ABSOLUTE_JUMP(op) (op==JUMP_ABSOLUTE || op==CONTINUE_LOOP)
+#define GETJUMPTGT(arr, i) (GETARG(arr,i) + (ABSOLUTE_JUMP(arr[i]) ? 0 : i+3))
+#define SETARG(arr, i, val) arr[i+2] = val>>8; arr[i+1] = val & 255
+#define CODESIZE(op)  (HAS_ARG(op) ? 3 : 1)
+#define ISBASICBLOCK(blocks, start, bytes) \
+	(blocks[start]==blocks[start+bytes-1])
+
+/* Replace LOAD_CONST c1. LOAD_CONST c2 ... LOAD_CONST cn BUILD_TUPLE n
+   with	   LOAD_CONST (c1, c2, ... cn).
+   The consts table must still be in list form so that the
+   new constant (c1, c2, ... cn) can be appended.
+   Called with codestr pointing to the first LOAD_CONST.
+   Bails out with no change if one or more of the LOAD_CONSTs is missing. 
+   Also works for BUILD_LIST when followed by an "in" or "not in" test.
+*/
+static int
+tuple_of_constants(unsigned char *codestr, int n, PyObject *consts)
+{
+	PyObject *newconst, *constant;
+	Py_ssize_t i, arg, len_consts;
+
+	/* Pre-conditions */
+	assert(PyList_CheckExact(consts));
+	assert(codestr[n*3] == BUILD_TUPLE || codestr[n*3] == BUILD_LIST);
+	assert(GETARG(codestr, (n*3)) == n);
+	for (i=0 ; i<n ; i++)
+		assert(codestr[i*3] == LOAD_CONST);
+
+	/* Buildup new tuple of constants */
+	newconst = PyTuple_New(n);
+	if (newconst == NULL)
+		return 0;
+	len_consts = PyList_GET_SIZE(consts);
+	for (i=0 ; i<n ; i++) {
+		arg = GETARG(codestr, (i*3));
+		assert(arg < len_consts);
+		constant = PyList_GET_ITEM(consts, arg);
+		Py_INCREF(constant);
+		PyTuple_SET_ITEM(newconst, i, constant);
+	}
+
+	/* Append folded constant onto consts */
+	if (PyList_Append(consts, newconst)) {
+		Py_DECREF(newconst);
+		return 0;
+	}
+	Py_DECREF(newconst);
+
+	/* Write NOPs over old LOAD_CONSTS and
+	   add a new LOAD_CONST newconst on top of the BUILD_TUPLE n */
+	memset(codestr, NOP, n*3);
+	codestr[n*3] = LOAD_CONST;
+	SETARG(codestr, (n*3), len_consts);
+	return 1;
+}
+
+/* Replace LOAD_CONST c1. LOAD_CONST c2 BINOP
+   with	   LOAD_CONST binop(c1,c2)
+   The consts table must still be in list form so that the
+   new constant can be appended.
+   Called with codestr pointing to the first LOAD_CONST. 
+   Abandons the transformation if the folding fails (i.e.  1+'a').  
+   If the new constant is a sequence, only folds when the size
+   is below a threshold value.	That keeps pyc files from
+   becoming large in the presence of code like:	 (None,)*1000.
+*/
+static int
+fold_binops_on_constants(unsigned char *codestr, PyObject *consts)
+{
+	PyObject *newconst, *v, *w;
+	Py_ssize_t len_consts, size;
+	int opcode;
+
+	/* Pre-conditions */
+	assert(PyList_CheckExact(consts));
+	assert(codestr[0] == LOAD_CONST);
+	assert(codestr[3] == LOAD_CONST);
+
+	/* Create new constant */
+	v = PyList_GET_ITEM(consts, GETARG(codestr, 0));
+	w = PyList_GET_ITEM(consts, GETARG(codestr, 3));
+	opcode = codestr[6];
+	switch (opcode) {
+		case BINARY_POWER:
+			newconst = PyNumber_Power(v, w, Py_None);
+			break;
+		case BINARY_MULTIPLY:
+			newconst = PyNumber_Multiply(v, w);
+			break;
+		case BINARY_DIVIDE:
+			/* Cannot fold this operation statically since
+                           the result can depend on the run-time presence
+                           of the -Qnew flag */
+			return 0;
+		case BINARY_TRUE_DIVIDE:
+			newconst = PyNumber_TrueDivide(v, w);
+			break;
+		case BINARY_FLOOR_DIVIDE:
+			newconst = PyNumber_FloorDivide(v, w);
+			break;
+		case BINARY_MODULO:
+			newconst = PyNumber_Remainder(v, w);
+			break;
+		case BINARY_ADD:
+			newconst = PyNumber_Add(v, w);
+			break;
+		case BINARY_SUBTRACT:
+			newconst = PyNumber_Subtract(v, w);
+			break;
+		case BINARY_SUBSCR:
+			newconst = PyObject_GetItem(v, w);
+			break;
+		case BINARY_LSHIFT:
+			newconst = PyNumber_Lshift(v, w);
+			break;
+		case BINARY_RSHIFT:
+			newconst = PyNumber_Rshift(v, w);
+			break;
+		case BINARY_AND:
+			newconst = PyNumber_And(v, w);
+			break;
+		case BINARY_XOR:
+			newconst = PyNumber_Xor(v, w);
+			break;
+		case BINARY_OR:
+			newconst = PyNumber_Or(v, w);
+			break;
+		default:
+			/* Called with an unknown opcode */
+			PyErr_Format(PyExc_SystemError,
+			     "unexpected binary operation %d on a constant",
+				     opcode);
+			return 0;
+	}
+	if (newconst == NULL) {
+		PyErr_Clear();
+		return 0;
+	}
+	size = PyObject_Size(newconst);
+	if (size == -1)
+		PyErr_Clear();
+	else if (size > 20) {
+		Py_DECREF(newconst);
+		return 0;
+	}
+
+	/* Append folded constant into consts table */
+	len_consts = PyList_GET_SIZE(consts);
+	if (PyList_Append(consts, newconst)) {
+		Py_DECREF(newconst);
+		return 0;
+	}
+	Py_DECREF(newconst);
+
+	/* Write NOP NOP NOP NOP LOAD_CONST newconst */
+	memset(codestr, NOP, 4);
+	codestr[4] = LOAD_CONST;
+	SETARG(codestr, 4, len_consts);
+	return 1;
+}
+
+static int
+fold_unaryops_on_constants(unsigned char *codestr, PyObject *consts)
+{
+	PyObject *newconst=NULL, *v;
+	Py_ssize_t len_consts;
+	int opcode;
+
+	/* Pre-conditions */
+	assert(PyList_CheckExact(consts));
+	assert(codestr[0] == LOAD_CONST);
+
+	/* Create new constant */
+	v = PyList_GET_ITEM(consts, GETARG(codestr, 0));
+	opcode = codestr[3];
+	switch (opcode) {
+		case UNARY_NEGATIVE:
+			/* Preserve the sign of -0.0 */
+			if (PyObject_IsTrue(v) == 1)
+				newconst = PyNumber_Negative(v);
+			break;
+		case UNARY_CONVERT:
+			newconst = PyObject_Repr(v);
+			break;
+		case UNARY_INVERT:
+			newconst = PyNumber_Invert(v);
+			break;
+		default:
+			/* Called with an unknown opcode */
+			PyErr_Format(PyExc_SystemError,
+			     "unexpected unary operation %d on a constant",
+				     opcode);
+			return 0;
+	}
+	if (newconst == NULL) {
+		PyErr_Clear();
+		return 0;
+	}
+
+	/* Append folded constant into consts table */
+	len_consts = PyList_GET_SIZE(consts);
+	if (PyList_Append(consts, newconst)) {
+		Py_DECREF(newconst);
+		return 0;
+	}
+	Py_DECREF(newconst);
+
+	/* Write NOP LOAD_CONST newconst */
+	codestr[0] = NOP;
+	codestr[1] = LOAD_CONST;
+	SETARG(codestr, 1, len_consts);
+	return 1;
+}
+
+static unsigned int *
+markblocks(unsigned char *code, int len)
+{
+	unsigned int *blocks = (unsigned int *)PyMem_Malloc(len*sizeof(int));
+	int i,j, opcode, blockcnt = 0;
+
+	if (blocks == NULL) {
+		PyErr_NoMemory();
+		return NULL;
+	}
+	memset(blocks, 0, len*sizeof(int));
+
+	/* Mark labels in the first pass */
+	for (i=0 ; i<len ; i+=CODESIZE(opcode)) {
+		opcode = code[i];
+		switch (opcode) {
+			case FOR_ITER:
+			case JUMP_FORWARD:
+			case JUMP_IF_FALSE:
+			case JUMP_IF_TRUE:
+			case JUMP_ABSOLUTE:
+			case CONTINUE_LOOP:
+			case SETUP_LOOP:
+			case SETUP_EXCEPT:
+			case SETUP_FINALLY:
+				j = GETJUMPTGT(code, i);
+				blocks[j] = 1;
+				break;
+		}
+	}
+	/* Build block numbers in the second pass */
+	for (i=0 ; i<len ; i++) {
+		blockcnt += blocks[i];	/* increment blockcnt over labels */
+		blocks[i] = blockcnt;
+	}
+	return blocks;
+}
+
+/* Perform basic peephole optimizations to components of a code object.
+   The consts object should still be in list form to allow new constants 
+   to be appended.
+
+   To keep the optimizer simple, it bails out (does nothing) for code
+   containing extended arguments or that has a length over 32,700.  That 
+   allows us to avoid overflow and sign issues.	 Likewise, it bails when
+   the lineno table has complex encoding for gaps >= 255.
+
+   Optimizations are restricted to simple transformations occuring within a
+   single basic block.	All transformations keep the code size the same or 
+   smaller.  For those that reduce size, the gaps are initially filled with 
+   NOPs.  Later those NOPs are removed and the jump addresses retargeted in 
+   a single pass.  Line numbering is adjusted accordingly. */
+
+static PyObject *
+optimize_code(PyObject *code, PyObject* consts, PyObject *names,
+              PyObject *lineno_obj)
+{
+	Py_ssize_t i, j, codelen;
+	int nops, h, adj;
+	int tgt, tgttgt, opcode;
+	unsigned char *codestr = NULL;
+	unsigned char *lineno;
+	int *addrmap = NULL;
+	int new_line, cum_orig_line, last_line, tabsiz;
+	int cumlc=0, lastlc=0;	/* Count runs of consecutive LOAD_CONSTs */
+	unsigned int *blocks = NULL;
+	char *name;
+
+	/* Bail out if an exception is set */
+	if (PyErr_Occurred())
+		goto exitUnchanged;
+
+	/* Bypass optimization when the lineno table is too complex */
+	assert(PyString_Check(lineno_obj));
+	lineno = (unsigned char*)PyString_AS_STRING(lineno_obj);
+	tabsiz = PyString_GET_SIZE(lineno_obj);
+	if (memchr(lineno, 255, tabsiz) != NULL)
+		goto exitUnchanged;
+
+	/* Avoid situations where jump retargeting could overflow */
+	assert(PyString_Check(code));
+	codelen = PyString_Size(code);
+	if (codelen > 32700)
+		goto exitUnchanged;
+
+	/* Make a modifiable copy of the code string */
+	codestr = (unsigned char *)PyMem_Malloc(codelen);
+	if (codestr == NULL)
+		goto exitUnchanged;
+	codestr = (unsigned char *)memcpy(codestr, 
+                                        PyString_AS_STRING(code), codelen);
+
+	/* Verify that RETURN_VALUE terminates the codestring.	This allows
+	   the various transformation patterns to look ahead several
+	   instructions without additional checks to make sure they are not
+	   looking beyond the end of the code string.
+	*/
+	if (codestr[codelen-1] != RETURN_VALUE)
+		goto exitUnchanged;
+
+	/* Mapping to new jump targets after NOPs are removed */
+	addrmap = (int *)PyMem_Malloc(codelen * sizeof(int));
+	if (addrmap == NULL)
+		goto exitUnchanged;
+
+	blocks = markblocks(codestr, codelen);
+	if (blocks == NULL)
+		goto exitUnchanged;
+	assert(PyList_Check(consts));
+
+	for (i=0 ; i<codelen ; i += CODESIZE(codestr[i])) {
+		opcode = codestr[i];
+
+		lastlc = cumlc;
+		cumlc = 0;
+
+		switch (opcode) {
+
+			/* Replace UNARY_NOT JUMP_IF_FALSE POP_TOP with 
+			   with	   JUMP_IF_TRUE POP_TOP */
+			case UNARY_NOT:
+				if (codestr[i+1] != JUMP_IF_FALSE  ||
+				    codestr[i+4] != POP_TOP  ||
+				    !ISBASICBLOCK(blocks,i,5))
+					continue;
+				tgt = GETJUMPTGT(codestr, (i+1));
+				if (codestr[tgt] != POP_TOP)
+					continue;
+				j = GETARG(codestr, i+1) + 1;
+				codestr[i] = JUMP_IF_TRUE;
+				SETARG(codestr, i, j);
+				codestr[i+3] = POP_TOP;
+				codestr[i+4] = NOP;
+				break;
+
+				/* not a is b -->  a is not b
+				   not a in b -->  a not in b
+				   not a is not b -->  a is b
+				   not a not in b -->  a in b
+				*/
+			case COMPARE_OP:
+				j = GETARG(codestr, i);
+				if (j < 6  ||  j > 9  ||
+				    codestr[i+3] != UNARY_NOT  || 
+				    !ISBASICBLOCK(blocks,i,4))
+					continue;
+				SETARG(codestr, i, (j^1));
+				codestr[i+3] = NOP;
+				break;
+
+				/* Replace LOAD_GLOBAL/LOAD_NAME None
+                                   with LOAD_CONST None */
+			case LOAD_NAME:
+			case LOAD_GLOBAL:
+				j = GETARG(codestr, i);
+				name = PyString_AsString(PyTuple_GET_ITEM(names, j));
+				if (name == NULL  ||  strcmp(name, "None") != 0)
+					continue;
+				for (j=0 ; j < PyList_GET_SIZE(consts) ; j++) {
+					if (PyList_GET_ITEM(consts, j) == Py_None)
+						break;
+				}
+				if (j == PyList_GET_SIZE(consts)) {
+					if (PyList_Append(consts, Py_None) == -1)
+					        goto exitUnchanged;                                        
+				}
+				assert(PyList_GET_ITEM(consts, j) == Py_None);
+				codestr[i] = LOAD_CONST;
+				SETARG(codestr, i, j);
+				cumlc = lastlc + 1;
+				break;
+
+				/* Skip over LOAD_CONST trueconst
+                                   JUMP_IF_FALSE xx  POP_TOP */
+			case LOAD_CONST:
+				cumlc = lastlc + 1;
+				j = GETARG(codestr, i);
+				if (codestr[i+3] != JUMP_IF_FALSE  ||
+				    codestr[i+6] != POP_TOP  ||
+				    !ISBASICBLOCK(blocks,i,7)  ||
+				    !PyObject_IsTrue(PyList_GET_ITEM(consts, j)))
+					continue;
+				memset(codestr+i, NOP, 7);
+				cumlc = 0;
+				break;
+
+				/* Try to fold tuples of constants (includes a case for lists
+				   which are only used for "in" and "not in" tests).
+				   Skip over BUILD_SEQN 1 UNPACK_SEQN 1.
+				   Replace BUILD_SEQN 2 UNPACK_SEQN 2 with ROT2.
+				   Replace BUILD_SEQN 3 UNPACK_SEQN 3 with ROT3 ROT2. */
+			case BUILD_TUPLE:
+			case BUILD_LIST:
+				j = GETARG(codestr, i);
+				h = i - 3 * j;
+				if (h >= 0  &&
+				    j <= lastlc	 &&
+				    ((opcode == BUILD_TUPLE && 
+				      ISBASICBLOCK(blocks, h, 3*(j+1))) ||
+				     (opcode == BUILD_LIST && 
+				      codestr[i+3]==COMPARE_OP && 
+				      ISBASICBLOCK(blocks, h, 3*(j+2)) &&
+				      (GETARG(codestr,i+3)==6 ||
+				       GETARG(codestr,i+3)==7))) &&
+				    tuple_of_constants(&codestr[h], j, consts)) {
+					assert(codestr[i] == LOAD_CONST);
+					cumlc = 1;
+					break;
+				}
+				if (codestr[i+3] != UNPACK_SEQUENCE  ||
+				    !ISBASICBLOCK(blocks,i,6) ||
+				    j != GETARG(codestr, i+3))
+					continue;
+				if (j == 1) {
+					memset(codestr+i, NOP, 6);
+				} else if (j == 2) {
+					codestr[i] = ROT_TWO;
+					memset(codestr+i+1, NOP, 5);
+				} else if (j == 3) {
+					codestr[i] = ROT_THREE;
+					codestr[i+1] = ROT_TWO;
+					memset(codestr+i+2, NOP, 4);
+				}
+				break;
+
+				/* Fold binary ops on constants.
+				   LOAD_CONST c1 LOAD_CONST c2 BINOP -->  LOAD_CONST binop(c1,c2) */
+			case BINARY_POWER:
+			case BINARY_MULTIPLY:
+			case BINARY_TRUE_DIVIDE:
+			case BINARY_FLOOR_DIVIDE:
+			case BINARY_MODULO:
+			case BINARY_ADD:
+			case BINARY_SUBTRACT:
+			case BINARY_SUBSCR:
+			case BINARY_LSHIFT:
+			case BINARY_RSHIFT:
+			case BINARY_AND:
+			case BINARY_XOR:
+			case BINARY_OR:
+				if (lastlc >= 2	 &&
+				    ISBASICBLOCK(blocks, i-6, 7)  &&
+				    fold_binops_on_constants(&codestr[i-6], consts)) {
+					i -= 2;
+					assert(codestr[i] == LOAD_CONST);
+					cumlc = 1;
+				}
+				break;
+
+				/* Fold unary ops on constants.
+				   LOAD_CONST c1  UNARY_OP -->	LOAD_CONST unary_op(c) */
+			case UNARY_NEGATIVE:
+			case UNARY_CONVERT:
+			case UNARY_INVERT:
+				if (lastlc >= 1	 &&
+				    ISBASICBLOCK(blocks, i-3, 4)  &&
+				    fold_unaryops_on_constants(&codestr[i-3], consts))	{
+					i -= 2;
+					assert(codestr[i] == LOAD_CONST);
+					cumlc = 1;
+				}
+				break;
+
+				/* Simplify conditional jump to conditional jump where the
+				   result of the first test implies the success of a similar
+				   test or the failure of the opposite test.
+				   Arises in code like:
+				   "if a and b:"
+				   "if a or b:"
+				   "a and b or c"
+				   "(a and b) and c"
+				   x:JUMP_IF_FALSE y   y:JUMP_IF_FALSE z  -->  x:JUMP_IF_FALSE z
+				   x:JUMP_IF_FALSE y   y:JUMP_IF_TRUE z	 -->  x:JUMP_IF_FALSE y+3
+				   where y+3 is the instruction following the second test.
+				*/
+			case JUMP_IF_FALSE:
+			case JUMP_IF_TRUE:
+				tgt = GETJUMPTGT(codestr, i);
+				j = codestr[tgt];
+				if (j == JUMP_IF_FALSE	||  j == JUMP_IF_TRUE) {
+					if (j == opcode) {
+						tgttgt = GETJUMPTGT(codestr, tgt) - i - 3;
+						SETARG(codestr, i, tgttgt);
+					} else {
+						tgt -= i;
+						SETARG(codestr, i, tgt);
+					}
+					break;
+				}
+				/* Intentional fallthrough */  
+
+				/* Replace jumps to unconditional jumps */
+			case FOR_ITER:
+			case JUMP_FORWARD:
+			case JUMP_ABSOLUTE:
+			case CONTINUE_LOOP:
+			case SETUP_LOOP:
+			case SETUP_EXCEPT:
+			case SETUP_FINALLY:
+				tgt = GETJUMPTGT(codestr, i);
+				if (!UNCONDITIONAL_JUMP(codestr[tgt]))
+					continue;
+				tgttgt = GETJUMPTGT(codestr, tgt);
+				if (opcode == JUMP_FORWARD) /* JMP_ABS can go backwards */
+					opcode = JUMP_ABSOLUTE;
+				if (!ABSOLUTE_JUMP(opcode))
+					tgttgt -= i + 3;     /* Calc relative jump addr */
+				if (tgttgt < 0)		  /* No backward relative jumps */
+					continue;
+				codestr[i] = opcode;
+				SETARG(codestr, i, tgttgt);
+				break;
+
+			case EXTENDED_ARG:
+				goto exitUnchanged;
+
+				/* Replace RETURN LOAD_CONST None RETURN with just RETURN */
+			case RETURN_VALUE:
+				if (i+4 >= codelen  ||
+				    codestr[i+4] != RETURN_VALUE	 ||
+				    !ISBASICBLOCK(blocks,i,5))
+					continue;
+				memset(codestr+i+1, NOP, 4);
+				break;
+		}
+	}
+
+	/* Fixup linenotab */
+	for (i=0, nops=0 ; i<codelen ; i += CODESIZE(codestr[i])) {
+		addrmap[i] = i - nops;
+		if (codestr[i] == NOP)
+			nops++;
+	}
+	cum_orig_line = 0;
+	last_line = 0;
+	for (i=0 ; i < tabsiz ; i+=2) {
+		cum_orig_line += lineno[i];
+		new_line = addrmap[cum_orig_line];
+		assert (new_line - last_line < 255);
+		lineno[i] =((unsigned char)(new_line - last_line));
+		last_line = new_line;
+	}
+
+	/* Remove NOPs and fixup jump targets */
+	for (i=0, h=0 ; i<codelen ; ) {
+		opcode = codestr[i];
+		switch (opcode) {
+			case NOP:
+				i++;
+				continue;
+
+			case JUMP_ABSOLUTE:
+			case CONTINUE_LOOP:
+				j = addrmap[GETARG(codestr, i)];
+				SETARG(codestr, i, j);
+				break;
+
+			case FOR_ITER:
+			case JUMP_FORWARD:
+			case JUMP_IF_FALSE:
+			case JUMP_IF_TRUE:
+			case SETUP_LOOP:
+			case SETUP_EXCEPT:
+			case SETUP_FINALLY:
+				j = addrmap[GETARG(codestr, i) + i + 3] - addrmap[i] - 3;
+				SETARG(codestr, i, j);
+				break;
+		}
+		adj = CODESIZE(opcode);
+		while (adj--)
+			codestr[h++] = codestr[i++];
+	}
+	assert(h + nops == codelen);
+
+	code = PyString_FromStringAndSize((char *)codestr, h);
+	PyMem_Free(addrmap);
+	PyMem_Free(codestr);
+	PyMem_Free(blocks);
+	return code;
+
+ exitUnchanged:
+	if (blocks != NULL)
+		PyMem_Free(blocks);
+	if (addrmap != NULL)
+		PyMem_Free(addrmap);
+	if (codestr != NULL)
+		PyMem_Free(codestr);
+	Py_INCREF(code);
+	return code;
+}
+
+/* End: Peephole optimizations ----------------------------------------- */
+
+/*
+
+Leave this debugging code for just a little longer.
+
+static void
+compiler_display_symbols(PyObject *name, PyObject *symbols)
+{
+PyObject *key, *value;
+int flags;
+Py_ssize_t pos = 0;
+
+fprintf(stderr, "block %s\n", PyString_AS_STRING(name));
+while (PyDict_Next(symbols, &pos, &key, &value)) {
+flags = PyInt_AsLong(value);
+fprintf(stderr, "var %s:", PyString_AS_STRING(key));
+if (flags & DEF_GLOBAL)
+fprintf(stderr, " declared_global");
+if (flags & DEF_LOCAL)
+fprintf(stderr, " local");
+if (flags & DEF_PARAM)
+fprintf(stderr, " param");
+if (flags & DEF_STAR)
+fprintf(stderr, " stararg");
+if (flags & DEF_DOUBLESTAR)
+fprintf(stderr, " starstar");
+if (flags & DEF_INTUPLE)
+fprintf(stderr, " tuple");
+if (flags & DEF_FREE)
+fprintf(stderr, " free");
+if (flags & DEF_FREE_GLOBAL)
+fprintf(stderr, " global");
+if (flags & DEF_FREE_CLASS)
+fprintf(stderr, " free/class");
+if (flags & DEF_IMPORT)
+fprintf(stderr, " import");
+fprintf(stderr, "\n");
+}
+	fprintf(stderr, "\n");
+}
+*/
+
+static void
+compiler_unit_check(struct compiler_unit *u)
+{
+	basicblock *block;
+	for (block = u->u_blocks; block != NULL; block = block->b_list) {
+		assert(block != (void *)0xcbcbcbcb);
+		assert(block != (void *)0xfbfbfbfb);
+		assert(block != (void *)0xdbdbdbdb);
+		if (block->b_instr != NULL) {
+			assert(block->b_ialloc > 0);
+			assert(block->b_iused > 0);
+			assert(block->b_ialloc >= block->b_iused);
+		}
+		else {
+			assert (block->b_iused == 0);
+			assert (block->b_ialloc == 0);
+		}
+	}
+}
+
+static void
+compiler_unit_free(struct compiler_unit *u)
+{
+	basicblock *b, *next;
+
+	compiler_unit_check(u);
+	b = u->u_blocks;
+	while (b != NULL) {
+		if (b->b_instr)
+			PyObject_Free((void *)b->b_instr);
+		next = b->b_list;
+		PyObject_Free((void *)b);
+		b = next;
+	}
+	Py_CLEAR(u->u_ste);
+	Py_CLEAR(u->u_name);
+	Py_CLEAR(u->u_consts);
+	Py_CLEAR(u->u_names);
+	Py_CLEAR(u->u_varnames);
+	Py_CLEAR(u->u_freevars);
+	Py_CLEAR(u->u_cellvars);
+	Py_CLEAR(u->u_private);
+	PyObject_Free(u);
+}
+
+static int
+compiler_enter_scope(struct compiler *c, identifier name, void *key,
+		     int lineno)
+{
+	struct compiler_unit *u;
+
+	u = (struct compiler_unit *)PyObject_Malloc(sizeof(
+                                                struct compiler_unit));
+	if (!u) {
+		PyErr_NoMemory();
+		return 0;
+	}
+	memset(u, 0, sizeof(struct compiler_unit));
+	u->u_argcount = 0;
+	u->u_ste = PySymtable_Lookup(c->c_st, key);
+	if (!u->u_ste) {
+		compiler_unit_free(u);
+		return 0;
+	}
+	Py_INCREF(name);
+	u->u_name = name;
+	u->u_varnames = list2dict(u->u_ste->ste_varnames);
+	u->u_cellvars = dictbytype(u->u_ste->ste_symbols, CELL, 0, 0);
+	if (!u->u_varnames || !u->u_cellvars) {
+		compiler_unit_free(u);
+		return 0;
+	}
+
+	u->u_freevars = dictbytype(u->u_ste->ste_symbols, FREE, DEF_FREE_CLASS,
+				   PyDict_Size(u->u_cellvars));
+	if (!u->u_freevars) {
+		compiler_unit_free(u);
+		return 0;
+	}
+
+	u->u_blocks = NULL;
+	u->u_tmpname = 0;
+	u->u_nfblocks = 0;
+	u->u_firstlineno = lineno;
+	u->u_lineno = 0;
+	u->u_lineno_set = false;
+	u->u_consts = PyDict_New();
+	if (!u->u_consts) {
+		compiler_unit_free(u);
+		return 0;
+	}
+	u->u_names = PyDict_New();
+	if (!u->u_names) {
+		compiler_unit_free(u);
+		return 0;
+	}
+
+	u->u_private = NULL;
+
+	/* Push the old compiler_unit on the stack. */
+	if (c->u) {
+		PyObject *wrapper = PyCObject_FromVoidPtr(c->u, NULL);
+		if (!wrapper || PyList_Append(c->c_stack, wrapper) < 0) {
+			Py_XDECREF(wrapper);
+			compiler_unit_free(u);
+			return 0;
+		}
+		Py_DECREF(wrapper);
+		u->u_private = c->u->u_private;
+		Py_XINCREF(u->u_private);
+	}
+	c->u = u;
+
+	c->c_nestlevel++;
+	if (compiler_use_new_block(c) == NULL)
+		return 0;
+
+	return 1;
+}
+
+static void
+compiler_exit_scope(struct compiler *c)
+{
+	int n;
+	PyObject *wrapper;
+
+	c->c_nestlevel--;
+	compiler_unit_free(c->u);
+	/* Restore c->u to the parent unit. */
+	n = PyList_GET_SIZE(c->c_stack) - 1;
+	if (n >= 0) {
+		wrapper = PyList_GET_ITEM(c->c_stack, n);
+		c->u = (struct compiler_unit *)PyCObject_AsVoidPtr(wrapper);
+		/* we are deleting from a list so this really shouldn't fail */
+		if (PySequence_DelItem(c->c_stack, n) < 0)
+			Py_FatalError("compiler_exit_scope()");
+		compiler_unit_check(c->u);
+	}
+	else
+		c->u = NULL;
+
+}
+
+/* Allocate a new "anonymous" local variable.
+   Used by list comprehensions and with statements.
+*/
+
+static PyObject *
+compiler_new_tmpname(struct compiler *c)
+{
+	char tmpname[256];
+	PyOS_snprintf(tmpname, sizeof(tmpname), "_[%d]", ++c->u->u_tmpname);
+	return PyString_FromString(tmpname);
+}
+
+/* Allocate a new block and return a pointer to it.
+   Returns NULL on error.
+*/
+
+static basicblock *
+compiler_new_block(struct compiler *c)
+{
+	basicblock *b;
+	struct compiler_unit *u;
+
+	u = c->u;
+	b = (basicblock *)PyObject_Malloc(sizeof(basicblock));
+	if (b == NULL) {
+		PyErr_NoMemory();
+		return NULL;
+	}
+	memset((void *)b, 0, sizeof(basicblock));
+    /* Extend the singly linked list of blocks with new block. */
+	b->b_list = u->u_blocks;
+	u->u_blocks = b;
+	return b;
+}
+
+static basicblock *
+compiler_use_new_block(struct compiler *c)
+{
+	basicblock *block = compiler_new_block(c);
+	if (block == NULL)
+		return NULL;
+	c->u->u_curblock = block;
+	return block;
+}
+
+static basicblock *
+compiler_next_block(struct compiler *c)
+{
+	basicblock *block = compiler_new_block(c);
+	if (block == NULL)
+		return NULL;
+	c->u->u_curblock->b_next = block;
+	c->u->u_curblock = block;
+	return block;
+}
+
+static basicblock *
+compiler_use_next_block(struct compiler *c, basicblock *block)
+{
+	assert(block != NULL);
+	c->u->u_curblock->b_next = block;
+	c->u->u_curblock = block;
+	return block;
+}
+
+/* Returns the offset of the next instruction in the current block's
+   b_instr array.  Resizes the b_instr as necessary.
+   Returns -1 on failure.
+ */
+
+static int
+compiler_next_instr(struct compiler *c, basicblock *b)
+{
+	assert(b != NULL);
+	if (b->b_instr == NULL) {
+		b->b_instr = (struct instr *)PyObject_Malloc(
+                                 sizeof(struct instr) * DEFAULT_BLOCK_SIZE);
+		if (b->b_instr == NULL) {
+			PyErr_NoMemory();
+			return -1;
+		}
+		b->b_ialloc = DEFAULT_BLOCK_SIZE;
+		memset((char *)b->b_instr, 0,
+		       sizeof(struct instr) * DEFAULT_BLOCK_SIZE);
+	}
+	else if (b->b_iused == b->b_ialloc) {
+		struct instr *tmp;
+		size_t oldsize, newsize;
+		oldsize = b->b_ialloc * sizeof(struct instr);
+		newsize = oldsize << 1;
+		if (newsize == 0) {
+			PyErr_NoMemory();
+			return -1;
+		}
+		b->b_ialloc <<= 1;
+		tmp = (struct instr *)PyObject_Realloc(
+                                                (void *)b->b_instr, newsize);
+		if (tmp == NULL) {
+			PyErr_NoMemory();
+			return -1;
+		}
+		b->b_instr = tmp;
+		memset((char *)b->b_instr + oldsize, 0, newsize - oldsize);
+	}
+	return b->b_iused++;
+}
+
+/* Set the i_lineno member of the instruction at offse off if the
+   line number for the current expression/statement (?) has not
+   already been set.  If it has been set, the call has no effect.
+
+   Every time a new node is b
+   */
+
+static void
+compiler_set_lineno(struct compiler *c, int off)
+{
+	basicblock *b;
+	if (c->u->u_lineno_set)
+		return;
+	c->u->u_lineno_set = true;
+	b = c->u->u_curblock;
+	b->b_instr[off].i_lineno = c->u->u_lineno;
+}
+
+static int
+opcode_stack_effect(int opcode, int oparg)
+{
+	switch (opcode) {
+		case POP_TOP:
+			return -1;
+		case ROT_TWO:
+		case ROT_THREE:
+			return 0;
+		case DUP_TOP:
+			return 1;
+		case ROT_FOUR:
+			return 0;
+
+		case UNARY_POSITIVE:
+		case UNARY_NEGATIVE:
+		case UNARY_NOT:
+		case UNARY_CONVERT:
+		case UNARY_INVERT:
+			return 0;
+
+		case LIST_APPEND:
+			return -2;
+
+		case BINARY_POWER:
+		case BINARY_MULTIPLY:
+		case BINARY_DIVIDE:
+		case BINARY_MODULO:
+		case BINARY_ADD:
+		case BINARY_SUBTRACT:
+		case BINARY_SUBSCR:
+		case BINARY_FLOOR_DIVIDE:
+		case BINARY_TRUE_DIVIDE:
+			return -1;
+		case INPLACE_FLOOR_DIVIDE:
+		case INPLACE_TRUE_DIVIDE:
+			return -1;
+
+		case SLICE+0:
+			return 1;
+		case SLICE+1:
+			return 0;
+		case SLICE+2:
+			return 0;
+		case SLICE+3:
+			return -1;
+
+		case STORE_SLICE+0:
+			return -2;
+		case STORE_SLICE+1:
+			return -3;
+		case STORE_SLICE+2:
+			return -3;
+		case STORE_SLICE+3:
+			return -4;
+
+		case DELETE_SLICE+0:
+			return -1;
+		case DELETE_SLICE+1:
+			return -2;
+		case DELETE_SLICE+2:
+			return -2;
+		case DELETE_SLICE+3:
+			return -3;
+
+		case INPLACE_ADD:
+		case INPLACE_SUBTRACT:
+		case INPLACE_MULTIPLY:
+		case INPLACE_DIVIDE:
+		case INPLACE_MODULO:
+			return -1;
+		case STORE_SUBSCR:
+			return -3;
+		case DELETE_SUBSCR:
+			return -2;
+
+		case BINARY_LSHIFT:
+		case BINARY_RSHIFT:
+		case BINARY_AND:
+		case BINARY_XOR:
+		case BINARY_OR:
+			return -1;
+		case INPLACE_POWER:
+			return -1;
+		case GET_ITER:
+			return 0;
+
+		case PRINT_EXPR:
+			return -1;
+		case PRINT_ITEM:
+			return -1;
+		case PRINT_NEWLINE:
+			return 0;
+		case PRINT_ITEM_TO:
+			return -2;
+		case PRINT_NEWLINE_TO:
+			return -1;
+		case INPLACE_LSHIFT:
+		case INPLACE_RSHIFT:
+		case INPLACE_AND:
+		case INPLACE_XOR:
+		case INPLACE_OR:
+			return -1;
+		case BREAK_LOOP:
+			return 0;
+		case WITH_CLEANUP:
+			return -1; /* XXX Sometimes more */
+		case LOAD_LOCALS:
+			return 1;
+		case RETURN_VALUE:
+			return -1;
+		case IMPORT_STAR:
+			return -1;
+		case EXEC_STMT:
+			return -3;
+		case YIELD_VALUE:
+			return 0;
+
+		case POP_BLOCK:
+			return 0;
+		case END_FINALLY:
+			return -1; /* or -2 or -3 if exception occurred */
+		case BUILD_CLASS:
+			return -2;
+
+		case STORE_NAME:
+			return -1;
+		case DELETE_NAME:
+			return 0;
+		case UNPACK_SEQUENCE:
+			return oparg-1;
+		case FOR_ITER:
+			return 1;
+
+		case STORE_ATTR:
+			return -2;
+		case DELETE_ATTR:
+			return -1;
+		case STORE_GLOBAL:
+			return -1;
+		case DELETE_GLOBAL:
+			return 0;
+		case DUP_TOPX:
+			return oparg;
+		case LOAD_CONST:
+			return 1;
+		case LOAD_NAME:
+			return 1;
+		case BUILD_TUPLE:
+		case BUILD_LIST:
+			return 1-oparg;
+		case BUILD_MAP:
+			return 1;
+		case LOAD_ATTR:
+			return 0;
+		case COMPARE_OP:
+			return -1;
+		case IMPORT_NAME:
+			return 0;
+		case IMPORT_FROM:
+			return 1;
+
+		case JUMP_FORWARD:
+		case JUMP_IF_FALSE:
+		case JUMP_IF_TRUE:
+		case JUMP_ABSOLUTE:
+			return 0;
+
+		case LOAD_GLOBAL:
+			return 1;
+
+		case CONTINUE_LOOP:
+			return 0;
+		case SETUP_LOOP:
+			return 0;
+		case SETUP_EXCEPT:
+		case SETUP_FINALLY:
+			return 3; /* actually pushed by an exception */
+
+		case LOAD_FAST:
+			return 1;
+		case STORE_FAST:
+			return -1;
+		case DELETE_FAST:
+			return 0;
+
+		case RAISE_VARARGS:
+			return -oparg;
+#define NARGS(o) (((o) % 256) + 2*((o) / 256))
+		case CALL_FUNCTION:
+			return -NARGS(oparg);
+		case CALL_FUNCTION_VAR:
+		case CALL_FUNCTION_KW:
+			return -NARGS(oparg)-1;
+		case CALL_FUNCTION_VAR_KW:
+			return -NARGS(oparg)-2;
+#undef NARGS
+		case MAKE_FUNCTION:
+			return -oparg;
+		case BUILD_SLICE:
+			if (oparg == 3)
+				return -2;
+			else
+				return -1;
+
+		case MAKE_CLOSURE:
+			return -oparg;
+		case LOAD_CLOSURE:
+			return 1;
+		case LOAD_DEREF:
+			return 1;
+		case STORE_DEREF:
+			return -1;
+		default:
+			fprintf(stderr, "opcode = %d\n", opcode);
+			Py_FatalError("opcode_stack_effect()");
+
+	}
+	return 0; /* not reachable */
+}
+
+/* Add an opcode with no argument.
+   Returns 0 on failure, 1 on success.
+*/
+
+static int
+compiler_addop(struct compiler *c, int opcode)
+{
+	basicblock *b;
+	struct instr *i;
+	int off;
+	off = compiler_next_instr(c, c->u->u_curblock);
+	if (off < 0)
+		return 0;
+	b = c->u->u_curblock;
+	i = &b->b_instr[off];
+	i->i_opcode = opcode;
+	i->i_hasarg = 0;
+	if (opcode == RETURN_VALUE)
+		b->b_return = 1;
+	compiler_set_lineno(c, off);
+	return 1;
+}
+
+static int
+compiler_add_o(struct compiler *c, PyObject *dict, PyObject *o)
+{
+	PyObject *t, *v;
+	Py_ssize_t arg;
+
+	/* necessary to make sure types aren't coerced (e.g., int and long) */
+	t = PyTuple_Pack(2, o, o->ob_type);
+	if (t == NULL)
+	    return -1;
+
+	v = PyDict_GetItem(dict, t);
+	if (!v) {
+		arg = PyDict_Size(dict);
+		v = PyInt_FromLong(arg);
+		if (!v) {
+			Py_DECREF(t);
+			return -1;
+		}
+		if (PyDict_SetItem(dict, t, v) < 0) {
+			Py_DECREF(t);
+			Py_DECREF(v);
+			return -1;
+		}
+		Py_DECREF(v);
+	}
+	else
+		arg = PyInt_AsLong(v);
+	Py_DECREF(t);
+	return arg;
+}
+
+static int
+compiler_addop_o(struct compiler *c, int opcode, PyObject *dict,
+		     PyObject *o)
+{
+    int arg = compiler_add_o(c, dict, o);
+    if (arg < 0)
+	return 0;
+    return compiler_addop_i(c, opcode, arg);
+}
+
+static int
+compiler_addop_name(struct compiler *c, int opcode, PyObject *dict,
+		    PyObject *o)
+{
+    int arg;
+    PyObject *mangled = _Py_Mangle(c->u->u_private, o);
+    if (!mangled)
+	return 0;
+    arg = compiler_add_o(c, dict, mangled);
+    Py_DECREF(mangled);
+    if (arg < 0)
+	return 0;
+    return compiler_addop_i(c, opcode, arg);
+}
+
+/* Add an opcode with an integer argument.
+   Returns 0 on failure, 1 on success.
+*/
+
+static int
+compiler_addop_i(struct compiler *c, int opcode, int oparg)
+{
+	struct instr *i;
+	int off;
+	off = compiler_next_instr(c, c->u->u_curblock);
+	if (off < 0)
+		return 0;
+	i = &c->u->u_curblock->b_instr[off];
+	i->i_opcode = opcode;
+	i->i_oparg = oparg;
+	i->i_hasarg = 1;
+	compiler_set_lineno(c, off);
+	return 1;
+}
+
+static int
+compiler_addop_j(struct compiler *c, int opcode, basicblock *b, int absolute)
+{
+	struct instr *i;
+	int off;
+
+	assert(b != NULL);
+	off = compiler_next_instr(c, c->u->u_curblock);
+	if (off < 0)
+		return 0;
+	i = &c->u->u_curblock->b_instr[off];
+	i->i_opcode = opcode;
+	i->i_target = b;
+	i->i_hasarg = 1;
+	if (absolute)
+		i->i_jabs = 1;
+	else
+		i->i_jrel = 1;
+	compiler_set_lineno(c, off);
+	return 1;
+}
+
+/* The distinction between NEW_BLOCK and NEXT_BLOCK is subtle.	(I'd
+   like to find better names.)	NEW_BLOCK() creates a new block and sets
+   it as the current block.  NEXT_BLOCK() also creates an implicit jump
+   from the current block to the new block.
+*/
+
+/* XXX The returns inside these macros make it impossible to decref
+   objects created in the local function.
+*/
+
+
+#define NEW_BLOCK(C) { \
+	if (compiler_use_new_block((C)) == NULL) \
+		return 0; \
+}
+
+#define NEXT_BLOCK(C) { \
+	if (compiler_next_block((C)) == NULL) \
+		return 0; \
+}
+
+#define ADDOP(C, OP) { \
+	if (!compiler_addop((C), (OP))) \
+		return 0; \
+}
+
+#define ADDOP_IN_SCOPE(C, OP) { \
+	if (!compiler_addop((C), (OP))) { \
+		compiler_exit_scope(c); \
+		return 0; \
+	} \
+}
+
+#define ADDOP_O(C, OP, O, TYPE) { \
+	if (!compiler_addop_o((C), (OP), (C)->u->u_ ## TYPE, (O))) \
+		return 0; \
+}
+
+#define ADDOP_NAME(C, OP, O, TYPE) { \
+	if (!compiler_addop_name((C), (OP), (C)->u->u_ ## TYPE, (O))) \
+		return 0; \
+}
+
+#define ADDOP_I(C, OP, O) { \
+	if (!compiler_addop_i((C), (OP), (O))) \
+		return 0; \
+}
+
+#define ADDOP_JABS(C, OP, O) { \
+	if (!compiler_addop_j((C), (OP), (O), 1)) \
+		return 0; \
+}
+
+#define ADDOP_JREL(C, OP, O) { \
+	if (!compiler_addop_j((C), (OP), (O), 0)) \
+		return 0; \
+}
+
+/* VISIT and VISIT_SEQ takes an ASDL type as their second argument.  They use
+   the ASDL name to synthesize the name of the C type and the visit function.
+*/
+
+#define VISIT(C, TYPE, V) {\
+	if (!compiler_visit_ ## TYPE((C), (V))) \
+		return 0; \
+}
+
+#define VISIT_IN_SCOPE(C, TYPE, V) {\
+	if (!compiler_visit_ ## TYPE((C), (V))) { \
+		compiler_exit_scope(c); \
+		return 0; \
+	} \
+}
+
+#define VISIT_SLICE(C, V, CTX) {\
+	if (!compiler_visit_slice((C), (V), (CTX))) \
+		return 0; \
+}
+
+#define VISIT_SEQ(C, TYPE, SEQ) { \
+	int _i; \
+	asdl_seq *seq = (SEQ); /* avoid variable capture */ \
+	for (_i = 0; _i < asdl_seq_LEN(seq); _i++) { \
+		TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, _i); \
+		if (!compiler_visit_ ## TYPE((C), elt)) \
+			return 0; \
+	} \
+}
+
+#define VISIT_SEQ_IN_SCOPE(C, TYPE, SEQ) { \
+	int _i; \
+	asdl_seq *seq = (SEQ); /* avoid variable capture */ \
+	for (_i = 0; _i < asdl_seq_LEN(seq); _i++) { \
+		TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, _i); \
+		if (!compiler_visit_ ## TYPE((C), elt)) { \
+			compiler_exit_scope(c); \
+			return 0; \
+		} \
+	} \
+}
+
+static int
+compiler_isdocstring(stmt_ty s)
+{
+    if (s->kind != Expr_kind)
+	return 0;
+    return s->v.Expr.value->kind == Str_kind;
+}
+
+/* Compile a sequence of statements, checking for a docstring. */
+
+static int
+compiler_body(struct compiler *c, asdl_seq *stmts)
+{
+	int i = 0;
+	stmt_ty st;
+
+	if (!asdl_seq_LEN(stmts))
+		return 1;
+	st = (stmt_ty)asdl_seq_GET(stmts, 0);
+	if (compiler_isdocstring(st)) {
+		i = 1;
+		VISIT(c, expr, st->v.Expr.value);
+		if (!compiler_nameop(c, __doc__, Store))
+			return 0;
+	}
+	for (; i < asdl_seq_LEN(stmts); i++)
+	    VISIT(c, stmt, (stmt_ty)asdl_seq_GET(stmts, i));
+	return 1;
+}
+
+static PyCodeObject *
+compiler_mod(struct compiler *c, mod_ty mod)
+{
+	PyCodeObject *co;
+	int addNone = 1;
+	static PyObject *module;
+	if (!module) {
+		module = PyString_FromString("<module>");
+		if (!module)
+			return NULL;
+	}
+	/* Use 0 for firstlineno initially, will fixup in assemble(). */
+	if (!compiler_enter_scope(c, module, mod, 0))
+		return NULL;
+	switch (mod->kind) {
+	case Module_kind: 
+		if (!compiler_body(c, mod->v.Module.body)) {
+			compiler_exit_scope(c);
+			return 0;
+		}
+		break;
+	case Interactive_kind:
+		c->c_interactive = 1;
+		VISIT_SEQ_IN_SCOPE(c, stmt, 
+                                        mod->v.Interactive.body);
+		break;
+	case Expression_kind:
+		VISIT_IN_SCOPE(c, expr, mod->v.Expression.body);
+		addNone = 0;
+		break;
+	case Suite_kind:
+		PyErr_SetString(PyExc_SystemError,
+				"suite should not be possible");
+		return 0;
+	default:
+		PyErr_Format(PyExc_SystemError,
+			     "module kind %d should not be possible",
+			     mod->kind);
+		return 0;
+	}
+	co = assemble(c, addNone);
+	compiler_exit_scope(c);
+	return co;
+}
+
+/* The test for LOCAL must come before the test for FREE in order to
+   handle classes where name is both local and free.  The local var is
+   a method and the free var is a free var referenced within a method.
+*/
+
+static int
+get_ref_type(struct compiler *c, PyObject *name)
+{
+	int scope = PyST_GetScope(c->u->u_ste, name);
+	if (scope == 0) {
+	    char buf[350];
+	    PyOS_snprintf(buf, sizeof(buf),
+			  "unknown scope for %.100s in %.100s(%s) in %s\n"
+			  "symbols: %s\nlocals: %s\nglobals: %s\n",
+			  PyString_AS_STRING(name), 
+			  PyString_AS_STRING(c->u->u_name), 
+			  PyObject_REPR(c->u->u_ste->ste_id),
+			  c->c_filename,
+			  PyObject_REPR(c->u->u_ste->ste_symbols),
+			  PyObject_REPR(c->u->u_varnames),
+			  PyObject_REPR(c->u->u_names)
+		);
+	    Py_FatalError(buf);
+	}
+
+	return scope;
+}
+
+static int
+compiler_lookup_arg(PyObject *dict, PyObject *name)
+{
+    PyObject *k, *v;
+    k = PyTuple_Pack(2, name, name->ob_type);
+    if (k == NULL)
+	return -1;
+    v = PyDict_GetItem(dict, k);
+    Py_DECREF(k);
+    if (v == NULL)
+	return -1;
+    return PyInt_AS_LONG(v);
+}
+
+static int
+compiler_make_closure(struct compiler *c, PyCodeObject *co, int args)
+{
+	int i, free = PyCode_GetNumFree(co);
+	if (free == 0) {
+	    ADDOP_O(c, LOAD_CONST, (PyObject*)co, consts);
+	    ADDOP_I(c, MAKE_FUNCTION, args);
+	    return 1;
+	}
+	for (i = 0; i < free; ++i) {
+		/* Bypass com_addop_varname because it will generate
+		   LOAD_DEREF but LOAD_CLOSURE is needed. 
+		*/
+		PyObject *name = PyTuple_GET_ITEM(co->co_freevars, i);
+		int arg, reftype;
+
+		/* Special case: If a class contains a method with a
+		   free variable that has the same name as a method,
+		   the name will be considered free *and* local in the
+		   class.  It should be handled by the closure, as
+		   well as by the normal name loookup logic.
+		*/
+		reftype = get_ref_type(c, name);
+		if (reftype == CELL)
+			arg = compiler_lookup_arg(c->u->u_cellvars, name);
+		else /* (reftype == FREE) */
+			arg = compiler_lookup_arg(c->u->u_freevars, name);
+		if (arg == -1) {
+			printf("lookup %s in %s %d %d\n"
+				"freevars of %s: %s\n",
+				PyObject_REPR(name), 
+				PyString_AS_STRING(c->u->u_name), 
+				reftype, arg,
+				PyString_AS_STRING(co->co_name),
+				PyObject_REPR(co->co_freevars));
+			Py_FatalError("compiler_make_closure()");
+		}
+		ADDOP_I(c, LOAD_CLOSURE, arg);
+	}
+	ADDOP_I(c, BUILD_TUPLE, free);
+	ADDOP_O(c, LOAD_CONST, (PyObject*)co, consts);
+	ADDOP_I(c, MAKE_CLOSURE, args);
+	return 1;
+}
+
+static int
+compiler_decorators(struct compiler *c, asdl_seq* decos)
+{
+	int i;
+
+	if (!decos)
+		return 1;
+
+	for (i = 0; i < asdl_seq_LEN(decos); i++) {
+		VISIT(c, expr, (expr_ty)asdl_seq_GET(decos, i));
+	}
+	return 1;
+}
+
+static int
+compiler_arguments(struct compiler *c, arguments_ty args)
+{
+	int i;
+	int n = asdl_seq_LEN(args->args);
+	/* Correctly handle nested argument lists */
+	for (i = 0; i < n; i++) {
+		expr_ty arg = (expr_ty)asdl_seq_GET(args->args, i);
+		if (arg->kind == Tuple_kind) {
+			PyObject *id = PyString_FromFormat(".%d", i);
+			if (id == NULL) {
+				return 0;
+			}
+			if (!compiler_nameop(c, id, Load)) {
+				Py_DECREF(id);
+				return 0;
+			}
+			Py_DECREF(id);
+			VISIT(c, expr, arg);
+		}
+	}
+	return 1;
+}
+
+static int
+compiler_function(struct compiler *c, stmt_ty s)
+{
+	PyCodeObject *co;
+	PyObject *first_const = Py_None;
+	arguments_ty args = s->v.FunctionDef.args;
+	asdl_seq* decos = s->v.FunctionDef.decorators;
+	stmt_ty st;
+	int i, n, docstring;
+
+	assert(s->kind == FunctionDef_kind);
+
+	if (!compiler_decorators(c, decos))
+		return 0;
+	if (args->defaults)
+		VISIT_SEQ(c, expr, args->defaults);
+	if (!compiler_enter_scope(c, s->v.FunctionDef.name, (void *)s,
+				  s->lineno))
+		return 0;
+
+	st = (stmt_ty)asdl_seq_GET(s->v.FunctionDef.body, 0);
+	docstring = compiler_isdocstring(st);
+	if (docstring)
+	    first_const = st->v.Expr.value->v.Str.s;
+	if (compiler_add_o(c, c->u->u_consts, first_const) < 0)	 {
+	    compiler_exit_scope(c);
+	    return 0;
+	}
+
+	/* unpack nested arguments */
+	compiler_arguments(c, args);
+
+	c->u->u_argcount = asdl_seq_LEN(args->args);
+	n = asdl_seq_LEN(s->v.FunctionDef.body);
+	/* if there was a docstring, we need to skip the first statement */
+	for (i = docstring; i < n; i++) {
+		st = (stmt_ty)asdl_seq_GET(s->v.FunctionDef.body, i);
+		VISIT_IN_SCOPE(c, stmt, st);
+	}
+	co = assemble(c, 1);
+	compiler_exit_scope(c);
+	if (co == NULL)
+		return 0;
+
+	compiler_make_closure(c, co, asdl_seq_LEN(args->defaults));
+	Py_DECREF(co);
+
+	for (i = 0; i < asdl_seq_LEN(decos); i++) {
+		ADDOP_I(c, CALL_FUNCTION, 1);
+	}
+
+	return compiler_nameop(c, s->v.FunctionDef.name, Store);
+}
+
+static int
+compiler_class(struct compiler *c, stmt_ty s)
+{
+	int n;
+	PyCodeObject *co;
+	PyObject *str;
+	/* push class name on stack, needed by BUILD_CLASS */
+	ADDOP_O(c, LOAD_CONST, s->v.ClassDef.name, consts);
+	/* push the tuple of base classes on the stack */
+	n = asdl_seq_LEN(s->v.ClassDef.bases);
+	if (n > 0)
+		VISIT_SEQ(c, expr, s->v.ClassDef.bases);
+	ADDOP_I(c, BUILD_TUPLE, n);
+	if (!compiler_enter_scope(c, s->v.ClassDef.name, (void *)s,
+				  s->lineno))
+		return 0;
+	c->u->u_private = s->v.ClassDef.name;
+	Py_INCREF(c->u->u_private);
+	str = PyString_InternFromString("__name__");
+	if (!str || !compiler_nameop(c, str, Load)) {
+		Py_XDECREF(str);
+		compiler_exit_scope(c);
+		return 0;
+	}
+	
+	Py_DECREF(str);
+	str = PyString_InternFromString("__module__");
+	if (!str || !compiler_nameop(c, str, Store)) {
+		Py_XDECREF(str);
+		compiler_exit_scope(c);
+		return 0;
+	}
+	Py_DECREF(str);
+
+	if (!compiler_body(c, s->v.ClassDef.body)) {
+		compiler_exit_scope(c);
+		return 0;
+	}
+
+	ADDOP_IN_SCOPE(c, LOAD_LOCALS);
+	ADDOP_IN_SCOPE(c, RETURN_VALUE);
+	co = assemble(c, 1);
+	compiler_exit_scope(c);
+	if (co == NULL)
+		return 0;
+
+	compiler_make_closure(c, co, 0);
+	Py_DECREF(co);
+
+	ADDOP_I(c, CALL_FUNCTION, 0);
+	ADDOP(c, BUILD_CLASS);
+	if (!compiler_nameop(c, s->v.ClassDef.name, Store))
+		return 0;
+	return 1;
+}
+
+static int
+compiler_ifexp(struct compiler *c, expr_ty e)
+{
+	basicblock *end, *next;
+	
+	assert(e->kind == IfExp_kind);
+	end = compiler_new_block(c);
+	if (end == NULL)
+		return 0;
+	next = compiler_new_block(c);
+	if (next == NULL)
+		return 0;
+	VISIT(c, expr, e->v.IfExp.test);
+	ADDOP_JREL(c, JUMP_IF_FALSE, next);
+	ADDOP(c, POP_TOP);
+	VISIT(c, expr, e->v.IfExp.body);
+	ADDOP_JREL(c, JUMP_FORWARD, end);
+	compiler_use_next_block(c, next);
+	ADDOP(c, POP_TOP);
+	VISIT(c, expr, e->v.IfExp.orelse);
+	compiler_use_next_block(c, end);
+	return 1;
+}
+
+static int
+compiler_lambda(struct compiler *c, expr_ty e)
+{
+	PyCodeObject *co;
+	static identifier name;
+	arguments_ty args = e->v.Lambda.args;
+	assert(e->kind == Lambda_kind);
+
+	if (!name) {
+		name = PyString_InternFromString("<lambda>");
+		if (!name)
+			return 0;
+	}
+
+	if (args->defaults)
+		VISIT_SEQ(c, expr, args->defaults);
+	if (!compiler_enter_scope(c, name, (void *)e, e->lineno))
+		return 0;
+
+	/* unpack nested arguments */
+	compiler_arguments(c, args);
+	
+	c->u->u_argcount = asdl_seq_LEN(args->args);
+	VISIT_IN_SCOPE(c, expr, e->v.Lambda.body);
+	ADDOP_IN_SCOPE(c, RETURN_VALUE);
+	co = assemble(c, 1);
+	compiler_exit_scope(c);
+	if (co == NULL)
+		return 0;
+
+	compiler_make_closure(c, co, asdl_seq_LEN(args->defaults));
+	Py_DECREF(co);
+
+	return 1;
+}
+
+static int
+compiler_print(struct compiler *c, stmt_ty s)
+{
+	int i, n;
+	bool dest;
+
+	assert(s->kind == Print_kind);
+	n = asdl_seq_LEN(s->v.Print.values);
+	dest = false;
+	if (s->v.Print.dest) {
+		VISIT(c, expr, s->v.Print.dest);
+		dest = true;
+	}
+	for (i = 0; i < n; i++) {
+		expr_ty e = (expr_ty)asdl_seq_GET(s->v.Print.values, i);
+		if (dest) {
+			ADDOP(c, DUP_TOP);
+			VISIT(c, expr, e);
+			ADDOP(c, ROT_TWO);
+			ADDOP(c, PRINT_ITEM_TO);
+		}
+		else {
+			VISIT(c, expr, e);
+			ADDOP(c, PRINT_ITEM);
+		}
+	}
+	if (s->v.Print.nl) {
+		if (dest)
+			ADDOP(c, PRINT_NEWLINE_TO)
+		else
+			ADDOP(c, PRINT_NEWLINE)
+	}
+	else if (dest)
+		ADDOP(c, POP_TOP);
+	return 1;
+}
+
+static int
+compiler_if(struct compiler *c, stmt_ty s)
+{
+	basicblock *end, *next;
+	int constant;
+	assert(s->kind == If_kind);
+	end = compiler_new_block(c);
+	if (end == NULL)
+		return 0;
+	next = compiler_new_block(c);
+	if (next == NULL)
+	    return 0;
+	
+	constant = expr_constant(s->v.If.test);
+	/* constant = 0: "if 0"
+	 * constant = 1: "if 1", "if 2", ...
+	 * constant = -1: rest */
+	if (constant == 0) {
+		if (s->v.If.orelse)
+			VISIT_SEQ(c, stmt, s->v.If.orelse);
+	} else if (constant == 1) {
+		VISIT_SEQ(c, stmt, s->v.If.body);
+	} else {
+		VISIT(c, expr, s->v.If.test);
+		ADDOP_JREL(c, JUMP_IF_FALSE, next);
+		ADDOP(c, POP_TOP);
+		VISIT_SEQ(c, stmt, s->v.If.body);
+		ADDOP_JREL(c, JUMP_FORWARD, end);
+		compiler_use_next_block(c, next);
+		ADDOP(c, POP_TOP);
+		if (s->v.If.orelse)
+	    		VISIT_SEQ(c, stmt, s->v.If.orelse);
+	}
+	compiler_use_next_block(c, end);
+	return 1;
+}
+
+static int
+compiler_for(struct compiler *c, stmt_ty s)
+{
+	basicblock *start, *cleanup, *end;
+
+	start = compiler_new_block(c);
+	cleanup = compiler_new_block(c);
+	end = compiler_new_block(c);
+	if (start == NULL || end == NULL || cleanup == NULL)
+		return 0;
+	ADDOP_JREL(c, SETUP_LOOP, end);
+	if (!compiler_push_fblock(c, LOOP, start))
+		return 0;
+	VISIT(c, expr, s->v.For.iter);
+	ADDOP(c, GET_ITER);
+	compiler_use_next_block(c, start);
+	/* XXX(nnorwitz): is there a better way to handle this?
+	   for loops are special, we want to be able to trace them
+	   each time around, so we need to set an extra line number. */
+	c->u->u_lineno_set = false;
+	ADDOP_JREL(c, FOR_ITER, cleanup);
+	VISIT(c, expr, s->v.For.target);
+	VISIT_SEQ(c, stmt, s->v.For.body);
+	ADDOP_JABS(c, JUMP_ABSOLUTE, start);
+	compiler_use_next_block(c, cleanup);
+	ADDOP(c, POP_BLOCK);
+	compiler_pop_fblock(c, LOOP, start);
+	VISIT_SEQ(c, stmt, s->v.For.orelse);
+	compiler_use_next_block(c, end);
+	return 1;
+}
+
+static int
+compiler_while(struct compiler *c, stmt_ty s)
+{
+	basicblock *loop, *orelse, *end, *anchor = NULL;
+	int constant = expr_constant(s->v.While.test);
+
+	if (constant == 0)
+		return 1;
+	loop = compiler_new_block(c);
+	end = compiler_new_block(c);
+	if (constant == -1) {
+		anchor = compiler_new_block(c);
+		if (anchor == NULL)
+			return 0;
+	}
+	if (loop == NULL || end == NULL)
+		return 0;
+	if (s->v.While.orelse) {
+		orelse = compiler_new_block(c);
+		if (orelse == NULL)
+			return 0;
+	}
+	else
+		orelse = NULL;
+
+	ADDOP_JREL(c, SETUP_LOOP, end);
+	compiler_use_next_block(c, loop);
+	if (!compiler_push_fblock(c, LOOP, loop))
+		return 0;
+	if (constant == -1) {
+		VISIT(c, expr, s->v.While.test);
+		ADDOP_JREL(c, JUMP_IF_FALSE, anchor);
+		ADDOP(c, POP_TOP);
+	}
+	VISIT_SEQ(c, stmt, s->v.While.body);
+	ADDOP_JABS(c, JUMP_ABSOLUTE, loop);
+
+	/* XXX should the two POP instructions be in a separate block
+	   if there is no else clause ?
+	*/
+
+	if (constant == -1) {
+		compiler_use_next_block(c, anchor);
+		ADDOP(c, POP_TOP);
+		ADDOP(c, POP_BLOCK);
+	}
+	compiler_pop_fblock(c, LOOP, loop);
+	if (orelse != NULL) /* what if orelse is just pass? */
+		VISIT_SEQ(c, stmt, s->v.While.orelse);
+	compiler_use_next_block(c, end);
+
+	return 1;
+}
+
+static int
+compiler_continue(struct compiler *c)
+{
+	static const char LOOP_ERROR_MSG[] = "'continue' not properly in loop";
+	static const char IN_FINALLY_ERROR_MSG[] = 
+			"'continue' not supported inside 'finally' clause";
+	int i;
+
+	if (!c->u->u_nfblocks)
+		return compiler_error(c, LOOP_ERROR_MSG);
+	i = c->u->u_nfblocks - 1;
+	switch (c->u->u_fblock[i].fb_type) {
+	case LOOP:
+		ADDOP_JABS(c, JUMP_ABSOLUTE, c->u->u_fblock[i].fb_block);
+		break;
+	case EXCEPT:
+	case FINALLY_TRY:
+		while (--i >= 0 && c->u->u_fblock[i].fb_type != LOOP) {
+			/* Prevent try: ... finally:
+			      try: continue ...  or
+			      try: ... except: continue */
+			if (c->u->u_fblock[i].fb_type == FINALLY_END)
+				return compiler_error(c, IN_FINALLY_ERROR_MSG);
+		}
+		if (i == -1)
+			return compiler_error(c, LOOP_ERROR_MSG);
+		ADDOP_JABS(c, CONTINUE_LOOP, c->u->u_fblock[i].fb_block);
+		break;
+	case FINALLY_END:
+		return compiler_error(c, IN_FINALLY_ERROR_MSG);
+	}
+
+	return 1;
+}
+
+/* Code generated for "try: <body> finally: <finalbody>" is as follows:
+   
+		SETUP_FINALLY	L
+		<code for body>
+		POP_BLOCK
+		LOAD_CONST	<None>
+	L:	<code for finalbody>
+		END_FINALLY
+   
+   The special instructions use the block stack.  Each block
+   stack entry contains the instruction that created it (here
+   SETUP_FINALLY), the level of the value stack at the time the
+   block stack entry was created, and a label (here L).
+   
+   SETUP_FINALLY:
+	Pushes the current value stack level and the label
+	onto the block stack.
+   POP_BLOCK:
+	Pops en entry from the block stack, and pops the value
+	stack until its level is the same as indicated on the
+	block stack.  (The label is ignored.)
+   END_FINALLY:
+	Pops a variable number of entries from the *value* stack
+	and re-raises the exception they specify.  The number of
+	entries popped depends on the (pseudo) exception type.
+   
+   The block stack is unwound when an exception is raised:
+   when a SETUP_FINALLY entry is found, the exception is pushed
+   onto the value stack (and the exception condition is cleared),
+   and the interpreter jumps to the label gotten from the block
+   stack.
+*/
+
+static int
+compiler_try_finally(struct compiler *c, stmt_ty s)
+{
+	basicblock *body, *end;
+	body = compiler_new_block(c);
+	end = compiler_new_block(c);
+	if (body == NULL || end == NULL)
+		return 0;
+
+	ADDOP_JREL(c, SETUP_FINALLY, end);
+	compiler_use_next_block(c, body);
+	if (!compiler_push_fblock(c, FINALLY_TRY, body))
+		return 0;
+	VISIT_SEQ(c, stmt, s->v.TryFinally.body);
+	ADDOP(c, POP_BLOCK);
+	compiler_pop_fblock(c, FINALLY_TRY, body);
+
+	ADDOP_O(c, LOAD_CONST, Py_None, consts);
+	compiler_use_next_block(c, end);
+	if (!compiler_push_fblock(c, FINALLY_END, end))
+		return 0;
+	VISIT_SEQ(c, stmt, s->v.TryFinally.finalbody);
+	ADDOP(c, END_FINALLY);
+	compiler_pop_fblock(c, FINALLY_END, end);
+
+	return 1;
+}
+
+/*
+   Code generated for "try: S except E1, V1: S1 except E2, V2: S2 ...":
+   (The contents of the value stack is shown in [], with the top
+   at the right; 'tb' is trace-back info, 'val' the exception's
+   associated value, and 'exc' the exception.)
+   
+   Value stack		Label	Instruction	Argument
+   []				SETUP_EXCEPT	L1
+   []				<code for S>
+   []				POP_BLOCK
+   []				JUMP_FORWARD	L0
+   
+   [tb, val, exc]	L1:	DUP				)
+   [tb, val, exc, exc]		<evaluate E1>			)
+   [tb, val, exc, exc, E1]	COMPARE_OP	EXC_MATCH	) only if E1
+   [tb, val, exc, 1-or-0]	JUMP_IF_FALSE	L2		)
+   [tb, val, exc, 1]		POP				)
+   [tb, val, exc]		POP
+   [tb, val]			<assign to V1>	(or POP if no V1)
+   [tb]				POP
+   []				<code for S1>
+				JUMP_FORWARD	L0
+   
+   [tb, val, exc, 0]	L2:	POP
+   [tb, val, exc]		DUP
+   .............................etc.......................
+
+   [tb, val, exc, 0]	Ln+1:	POP
+   [tb, val, exc]		END_FINALLY	# re-raise exception
+   
+   []			L0:	<next statement>
+   
+   Of course, parts are not generated if Vi or Ei is not present.
+*/
+static int
+compiler_try_except(struct compiler *c, stmt_ty s)
+{
+	basicblock *body, *orelse, *except, *end;
+	int i, n;
+
+	body = compiler_new_block(c);
+	except = compiler_new_block(c);
+	orelse = compiler_new_block(c);
+	end = compiler_new_block(c);
+	if (body == NULL || except == NULL || orelse == NULL || end == NULL)
+		return 0;
+	ADDOP_JREL(c, SETUP_EXCEPT, except);
+	compiler_use_next_block(c, body);
+	if (!compiler_push_fblock(c, EXCEPT, body))
+		return 0;
+	VISIT_SEQ(c, stmt, s->v.TryExcept.body);
+	ADDOP(c, POP_BLOCK);
+	compiler_pop_fblock(c, EXCEPT, body);
+	ADDOP_JREL(c, JUMP_FORWARD, orelse);
+	n = asdl_seq_LEN(s->v.TryExcept.handlers);
+	compiler_use_next_block(c, except);
+	for (i = 0; i < n; i++) {
+		excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET(
+						s->v.TryExcept.handlers, i);
+		if (!handler->type && i < n-1)
+		    return compiler_error(c, "default 'except:' must be last");
+        c->u->u_lineno_set = false;
+        c->u->u_lineno = handler->lineno;
+		except = compiler_new_block(c);
+		if (except == NULL)
+			return 0;
+		if (handler->type) {
+			ADDOP(c, DUP_TOP);
+			VISIT(c, expr, handler->type);
+			ADDOP_I(c, COMPARE_OP, PyCmp_EXC_MATCH);
+			ADDOP_JREL(c, JUMP_IF_FALSE, except);
+			ADDOP(c, POP_TOP);
+		}
+		ADDOP(c, POP_TOP);
+		if (handler->name) {
+			VISIT(c, expr, handler->name);
+		}
+		else {
+			ADDOP(c, POP_TOP);
+		}
+		ADDOP(c, POP_TOP);
+		VISIT_SEQ(c, stmt, handler->body);
+		ADDOP_JREL(c, JUMP_FORWARD, end);
+		compiler_use_next_block(c, except);
+		if (handler->type)
+			ADDOP(c, POP_TOP);
+	}
+	ADDOP(c, END_FINALLY);
+	compiler_use_next_block(c, orelse);
+	VISIT_SEQ(c, stmt, s->v.TryExcept.orelse);
+	compiler_use_next_block(c, end);
+	return 1;
+}
+
+static int
+compiler_import_as(struct compiler *c, identifier name, identifier asname)
+{
+	/* The IMPORT_NAME opcode was already generated.  This function
+	   merely needs to bind the result to a name.
+
+	   If there is a dot in name, we need to split it and emit a 
+	   LOAD_ATTR for each name.
+	*/
+	const char *src = PyString_AS_STRING(name);
+	const char *dot = strchr(src, '.');
+	if (dot) {
+		/* Consume the base module name to get the first attribute */
+		src = dot + 1;
+		while (dot) {
+			/* NB src is only defined when dot != NULL */
+			PyObject *attr;
+			dot = strchr(src, '.');
+			attr = PyString_FromStringAndSize(src, 
+					    dot ? dot - src : strlen(src));
+			if (!attr)
+				return -1;
+			ADDOP_O(c, LOAD_ATTR, attr, names);
+			Py_DECREF(attr);
+			src = dot + 1;
+		}
+	}
+	return compiler_nameop(c, asname, Store);
+}
+
+static int
+compiler_import(struct compiler *c, stmt_ty s)
+{
+	/* The Import node stores a module name like a.b.c as a single
+	   string.  This is convenient for all cases except
+	     import a.b.c as d
+	   where we need to parse that string to extract the individual
+	   module names.  
+	   XXX Perhaps change the representation to make this case simpler?
+	 */
+	int i, n = asdl_seq_LEN(s->v.Import.names);
+
+	for (i = 0; i < n; i++) {
+		alias_ty alias = (alias_ty)asdl_seq_GET(s->v.Import.names, i);
+		int r;
+		PyObject *level;
+
+		if (c->c_flags && (c->c_flags->cf_flags & CO_FUTURE_ABSOLUTE_IMPORT))
+			level = PyInt_FromLong(0);
+		else
+			level = PyInt_FromLong(-1);
+
+		if (level == NULL)
+			return 0;
+
+		ADDOP_O(c, LOAD_CONST, level, consts);
+		Py_DECREF(level);
+		ADDOP_O(c, LOAD_CONST, Py_None, consts);
+		ADDOP_NAME(c, IMPORT_NAME, alias->name, names);
+
+		if (alias->asname) {
+			r = compiler_import_as(c, alias->name, alias->asname);
+			if (!r)
+			    return r;
+		}
+		else {
+			identifier tmp = alias->name;
+			const char *base = PyString_AS_STRING(alias->name);
+			char *dot = strchr(base, '.');
+			if (dot)
+				tmp = PyString_FromStringAndSize(base, 
+								 dot - base);
+			r = compiler_nameop(c, tmp, Store);
+			if (dot) {
+				Py_DECREF(tmp);
+			}
+			if (!r)
+				return r;
+		}
+	}
+	return 1;
+}
+
+static int
+compiler_from_import(struct compiler *c, stmt_ty s)
+{
+	int i, n = asdl_seq_LEN(s->v.ImportFrom.names);
+
+	PyObject *names = PyTuple_New(n);
+	PyObject *level;
+	
+	if (!names)
+		return 0;
+
+	if (s->v.ImportFrom.level == 0 && c->c_flags &&
+	    !(c->c_flags->cf_flags & CO_FUTURE_ABSOLUTE_IMPORT))
+		level = PyInt_FromLong(-1);
+	else
+		level = PyInt_FromLong(s->v.ImportFrom.level);
+
+	if (!level) {
+		Py_DECREF(names);
+		return 0;
+	}
+
+	/* build up the names */
+	for (i = 0; i < n; i++) {
+		alias_ty alias = (alias_ty)asdl_seq_GET(s->v.ImportFrom.names, i);
+		Py_INCREF(alias->name);
+		PyTuple_SET_ITEM(names, i, alias->name);
+	}
+
+	if (s->lineno > c->c_future->ff_lineno) {
+		if (!strcmp(PyString_AS_STRING(s->v.ImportFrom.module),
+			    "__future__")) {
+			Py_DECREF(level);
+			Py_DECREF(names);
+			return compiler_error(c, 
+				      "from __future__ imports must occur "
+				      "at the beginning of the file");
+
+		}
+	}
+
+	ADDOP_O(c, LOAD_CONST, level, consts);
+	Py_DECREF(level);
+	ADDOP_O(c, LOAD_CONST, names, consts);
+	Py_DECREF(names);
+	ADDOP_NAME(c, IMPORT_NAME, s->v.ImportFrom.module, names);
+	for (i = 0; i < n; i++) {
+		alias_ty alias = (alias_ty)asdl_seq_GET(s->v.ImportFrom.names, i);
+		identifier store_name;
+
+		if (i == 0 && *PyString_AS_STRING(alias->name) == '*') {
+			assert(n == 1);
+			ADDOP(c, IMPORT_STAR);
+			return 1;
+		}
+		    
+		ADDOP_NAME(c, IMPORT_FROM, alias->name, names);
+		store_name = alias->name;
+		if (alias->asname)
+			store_name = alias->asname;
+
+		if (!compiler_nameop(c, store_name, Store)) {
+			Py_DECREF(names);
+			return 0;
+		}
+	}
+	/* remove imported module */
+	ADDOP(c, POP_TOP);
+	return 1;
+}
+
+static int
+compiler_assert(struct compiler *c, stmt_ty s)
+{
+	static PyObject *assertion_error = NULL;
+	basicblock *end;
+
+	if (Py_OptimizeFlag)
+		return 1;
+	if (assertion_error == NULL) {
+		assertion_error = PyString_FromString("AssertionError");
+		if (assertion_error == NULL)
+			return 0;
+	}
+	VISIT(c, expr, s->v.Assert.test);
+	end = compiler_new_block(c);
+	if (end == NULL)
+		return 0;
+	ADDOP_JREL(c, JUMP_IF_TRUE, end);
+	ADDOP(c, POP_TOP);
+	ADDOP_O(c, LOAD_GLOBAL, assertion_error, names);
+	if (s->v.Assert.msg) {
+		VISIT(c, expr, s->v.Assert.msg);
+		ADDOP_I(c, RAISE_VARARGS, 2);
+	}
+	else {
+		ADDOP_I(c, RAISE_VARARGS, 1);
+	}
+	compiler_use_next_block(c, end);
+	ADDOP(c, POP_TOP);
+	return 1;
+}
+
+static int
+compiler_visit_stmt(struct compiler *c, stmt_ty s)
+{
+	int i, n;
+
+    /* Always assign a lineno to the next instruction for a stmt. */
+	c->u->u_lineno = s->lineno;
+	c->u->u_lineno_set = false;
+
+	switch (s->kind) {
+	case FunctionDef_kind:
+		return compiler_function(c, s);
+	case ClassDef_kind:
+		return compiler_class(c, s);
+	case Return_kind:
+		if (c->u->u_ste->ste_type != FunctionBlock)
+			return compiler_error(c, "'return' outside function");
+		if (s->v.Return.value) {
+			VISIT(c, expr, s->v.Return.value);
+		}
+		else
+			ADDOP_O(c, LOAD_CONST, Py_None, consts);
+		ADDOP(c, RETURN_VALUE);
+		break;
+	case Delete_kind:
+		VISIT_SEQ(c, expr, s->v.Delete.targets)
+		break;
+	case Assign_kind:
+		n = asdl_seq_LEN(s->v.Assign.targets);
+		VISIT(c, expr, s->v.Assign.value);
+		for (i = 0; i < n; i++) {
+			if (i < n - 1)
+				ADDOP(c, DUP_TOP);
+			VISIT(c, expr,
+			      (expr_ty)asdl_seq_GET(s->v.Assign.targets, i));
+		}
+		break;
+	case AugAssign_kind:
+		return compiler_augassign(c, s);
+	case Print_kind:
+		return compiler_print(c, s);
+	case For_kind:
+		return compiler_for(c, s);
+	case While_kind:
+		return compiler_while(c, s);
+	case If_kind:
+		return compiler_if(c, s);
+	case Raise_kind:
+		n = 0;
+		if (s->v.Raise.type) {
+			VISIT(c, expr, s->v.Raise.type);
+			n++;
+			if (s->v.Raise.inst) {
+				VISIT(c, expr, s->v.Raise.inst);
+				n++;
+				if (s->v.Raise.tback) {
+					VISIT(c, expr, s->v.Raise.tback);
+					n++;
+				}
+			}
+		}
+		ADDOP_I(c, RAISE_VARARGS, n);
+		break;
+	case TryExcept_kind:
+		return compiler_try_except(c, s);
+	case TryFinally_kind:
+		return compiler_try_finally(c, s);
+	case Assert_kind:
+		return compiler_assert(c, s);
+	case Import_kind:
+		return compiler_import(c, s);
+	case ImportFrom_kind:
+		return compiler_from_import(c, s);
+	case Exec_kind:
+		VISIT(c, expr, s->v.Exec.body);
+		if (s->v.Exec.globals) {
+			VISIT(c, expr, s->v.Exec.globals);
+			if (s->v.Exec.locals) {
+				VISIT(c, expr, s->v.Exec.locals);
+			} else {
+				ADDOP(c, DUP_TOP);
+			}
+		} else {
+			ADDOP_O(c, LOAD_CONST, Py_None, consts);
+			ADDOP(c, DUP_TOP);
+		}
+		ADDOP(c, EXEC_STMT);
+		break;
+	case Global_kind:
+		break;
+	case Expr_kind:
+		if (c->c_interactive && c->c_nestlevel <= 1) {
+			VISIT(c, expr, s->v.Expr.value);
+			ADDOP(c, PRINT_EXPR);
+		}
+		else if (s->v.Expr.value->kind != Str_kind &&
+			 s->v.Expr.value->kind != Num_kind) {
+			VISIT(c, expr, s->v.Expr.value);
+			ADDOP(c, POP_TOP);
+		}
+		break;
+	case Pass_kind:
+		break;
+	case Break_kind:
+                if (!compiler_in_loop(c))
+			return compiler_error(c, "'break' outside loop");
+		ADDOP(c, BREAK_LOOP);
+		break;
+	case Continue_kind:
+		return compiler_continue(c);
+	case With_kind:
+		return compiler_with(c, s);
+	}
+	return 1;
+}
+
+static int
+unaryop(unaryop_ty op)
+{
+	switch (op) {
+	case Invert:
+		return UNARY_INVERT;
+	case Not:
+		return UNARY_NOT;
+	case UAdd:
+		return UNARY_POSITIVE;
+	case USub:
+		return UNARY_NEGATIVE;
+	}
+	return 0;
+}
+
+static int
+binop(struct compiler *c, operator_ty op)
+{
+	switch (op) {
+	case Add:
+		return BINARY_ADD;
+	case Sub:
+		return BINARY_SUBTRACT;
+	case Mult:
+		return BINARY_MULTIPLY;
+	case Div:
+		if (c->c_flags && c->c_flags->cf_flags & CO_FUTURE_DIVISION)
+			return BINARY_TRUE_DIVIDE;
+		else
+			return BINARY_DIVIDE;
+	case Mod:
+		return BINARY_MODULO;
+	case Pow:
+		return BINARY_POWER;
+	case LShift:
+		return BINARY_LSHIFT;
+	case RShift:
+		return BINARY_RSHIFT;
+	case BitOr:
+		return BINARY_OR;
+	case BitXor:
+		return BINARY_XOR;
+	case BitAnd:
+		return BINARY_AND;
+	case FloorDiv:
+		return BINARY_FLOOR_DIVIDE;
+	}
+	return 0;
+}
+
+static int
+cmpop(cmpop_ty op)
+{
+	switch (op) {
+	case Eq:
+		return PyCmp_EQ;
+	case NotEq:
+		return PyCmp_NE;
+	case Lt:
+		return PyCmp_LT;
+	case LtE:
+		return PyCmp_LE;
+	case Gt:
+		return PyCmp_GT;
+	case GtE:
+		return PyCmp_GE;
+	case Is:
+		return PyCmp_IS;
+	case IsNot:
+		return PyCmp_IS_NOT;
+	case In:
+		return PyCmp_IN;
+	case NotIn:
+		return PyCmp_NOT_IN;
+	}
+	return PyCmp_BAD;
+}
+
+static int
+inplace_binop(struct compiler *c, operator_ty op)
+{
+	switch (op) {
+	case Add:
+		return INPLACE_ADD;
+	case Sub:
+		return INPLACE_SUBTRACT;
+	case Mult:
+		return INPLACE_MULTIPLY;
+	case Div:
+		if (c->c_flags && c->c_flags->cf_flags & CO_FUTURE_DIVISION)
+			return INPLACE_TRUE_DIVIDE;
+		else
+			return INPLACE_DIVIDE;
+	case Mod:
+		return INPLACE_MODULO;
+	case Pow:
+		return INPLACE_POWER;
+	case LShift:
+		return INPLACE_LSHIFT;
+	case RShift:
+		return INPLACE_RSHIFT;
+	case BitOr:
+		return INPLACE_OR;
+	case BitXor:
+		return INPLACE_XOR;
+	case BitAnd:
+		return INPLACE_AND;
+	case FloorDiv:
+		return INPLACE_FLOOR_DIVIDE;
+	}
+	PyErr_Format(PyExc_SystemError,
+		     "inplace binary op %d should not be possible", op);
+	return 0;
+}
+
+static int
+compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx)
+{
+	int op, scope, arg;
+	enum { OP_FAST, OP_GLOBAL, OP_DEREF, OP_NAME } optype;
+
+	PyObject *dict = c->u->u_names;
+	PyObject *mangled;
+	/* XXX AugStore isn't used anywhere! */
+
+	/* First check for assignment to __debug__. Param? */
+	if ((ctx == Store || ctx == AugStore || ctx == Del)
+	    && !strcmp(PyString_AS_STRING(name), "__debug__")) {
+		return compiler_error(c, "can not assign to __debug__");
+	}
+
+	mangled = _Py_Mangle(c->u->u_private, name);
+	if (!mangled)
+		return 0;
+
+	op = 0;
+	optype = OP_NAME;
+	scope = PyST_GetScope(c->u->u_ste, mangled);
+	switch (scope) {
+	case FREE:
+		dict = c->u->u_freevars;
+		optype = OP_DEREF;
+		break;
+	case CELL:
+		dict = c->u->u_cellvars;
+		optype = OP_DEREF;
+		break;
+	case LOCAL:
+		if (c->u->u_ste->ste_type == FunctionBlock)
+			optype = OP_FAST;
+		break;
+	case GLOBAL_IMPLICIT:
+		if (c->u->u_ste->ste_type == FunctionBlock &&
+			!c->u->u_ste->ste_unoptimized)
+			optype = OP_GLOBAL;
+		break;
+	case GLOBAL_EXPLICIT:
+		optype = OP_GLOBAL;
+		break;
+	default:
+		/* scope can be 0 */
+		break;
+	}
+
+	/* XXX Leave assert here, but handle __doc__ and the like better */
+	assert(scope || PyString_AS_STRING(name)[0] == '_');
+
+	switch (optype) {
+	case OP_DEREF:
+		switch (ctx) {
+		case Load: op = LOAD_DEREF; break;
+		case Store: op = STORE_DEREF; break;
+		case AugLoad:
+		case AugStore:
+			break;
+		case Del:
+			PyErr_Format(PyExc_SyntaxError,
+				     "can not delete variable '%s' referenced "
+				     "in nested scope",
+				     PyString_AS_STRING(name));
+			Py_DECREF(mangled);
+			return 0;
+		case Param:
+		default:
+			PyErr_SetString(PyExc_SystemError,
+					"param invalid for deref variable");
+			return 0;
+		}
+		break;
+	case OP_FAST:
+		switch (ctx) {
+		case Load: op = LOAD_FAST; break;
+		case Store: op = STORE_FAST; break;
+		case Del: op = DELETE_FAST; break;
+		case AugLoad:
+		case AugStore:
+			break;
+		case Param:
+		default:
+			PyErr_SetString(PyExc_SystemError,
+					"param invalid for local variable");
+			return 0;
+		}
+		ADDOP_O(c, op, mangled, varnames);
+		Py_DECREF(mangled);
+		return 1;
+	case OP_GLOBAL:
+		switch (ctx) {
+		case Load: op = LOAD_GLOBAL; break;
+		case Store: op = STORE_GLOBAL; break;
+		case Del: op = DELETE_GLOBAL; break;
+		case AugLoad:
+		case AugStore:
+			break;
+		case Param:
+		default:
+			PyErr_SetString(PyExc_SystemError,
+					"param invalid for global variable");
+			return 0;
+		}
+		break;
+	case OP_NAME:
+		switch (ctx) {
+		case Load: op = LOAD_NAME; break;
+		case Store: op = STORE_NAME; break;
+		case Del: op = DELETE_NAME; break;
+		case AugLoad:
+		case AugStore:
+			break;
+		case Param:
+		default:
+			PyErr_SetString(PyExc_SystemError,
+					"param invalid for name variable");
+			return 0;
+		}
+		break;
+	}
+
+	assert(op);
+	arg = compiler_add_o(c, dict, mangled);
+	Py_DECREF(mangled);
+	if (arg < 0)
+		return 0;
+	return compiler_addop_i(c, op, arg);
+}
+
+static int
+compiler_boolop(struct compiler *c, expr_ty e)
+{
+	basicblock *end;
+	int jumpi, i, n;
+	asdl_seq *s;
+
+	assert(e->kind == BoolOp_kind);
+	if (e->v.BoolOp.op == And)
+		jumpi = JUMP_IF_FALSE;
+	else
+		jumpi = JUMP_IF_TRUE;
+	end = compiler_new_block(c);
+	if (end == NULL)
+		return 0;
+	s = e->v.BoolOp.values;
+	n = asdl_seq_LEN(s) - 1;
+	assert(n >= 0);
+	for (i = 0; i < n; ++i) {
+		VISIT(c, expr, (expr_ty)asdl_seq_GET(s, i));
+		ADDOP_JREL(c, jumpi, end);
+		ADDOP(c, POP_TOP)
+	}
+	VISIT(c, expr, (expr_ty)asdl_seq_GET(s, n));
+	compiler_use_next_block(c, end);
+	return 1;
+}
+
+static int
+compiler_list(struct compiler *c, expr_ty e)
+{
+	int n = asdl_seq_LEN(e->v.List.elts);
+	if (e->v.List.ctx == Store) {
+		ADDOP_I(c, UNPACK_SEQUENCE, n);
+	}
+	VISIT_SEQ(c, expr, e->v.List.elts);
+	if (e->v.List.ctx == Load) {
+		ADDOP_I(c, BUILD_LIST, n);
+	}
+	return 1;
+}
+
+static int
+compiler_tuple(struct compiler *c, expr_ty e)
+{
+	int n = asdl_seq_LEN(e->v.Tuple.elts);
+	if (e->v.Tuple.ctx == Store) {
+		ADDOP_I(c, UNPACK_SEQUENCE, n);
+	}
+	VISIT_SEQ(c, expr, e->v.Tuple.elts);
+	if (e->v.Tuple.ctx == Load) {
+		ADDOP_I(c, BUILD_TUPLE, n);
+	}
+	return 1;
+}
+
+static int
+compiler_compare(struct compiler *c, expr_ty e)
+{
+	int i, n;
+	basicblock *cleanup = NULL;
+
+	/* XXX the logic can be cleaned up for 1 or multiple comparisons */
+	VISIT(c, expr, e->v.Compare.left);
+	n = asdl_seq_LEN(e->v.Compare.ops);
+	assert(n > 0);
+	if (n > 1) {
+		cleanup = compiler_new_block(c);
+		if (cleanup == NULL)
+		    return 0;
+		VISIT(c, expr, 
+                        (expr_ty)asdl_seq_GET(e->v.Compare.comparators, 0));
+	}
+	for (i = 1; i < n; i++) {
+		ADDOP(c, DUP_TOP);
+		ADDOP(c, ROT_THREE);
+		ADDOP_I(c, COMPARE_OP,
+			cmpop((cmpop_ty)(asdl_seq_GET(
+                                                  e->v.Compare.ops, i - 1))));
+		ADDOP_JREL(c, JUMP_IF_FALSE, cleanup);
+		NEXT_BLOCK(c);
+		ADDOP(c, POP_TOP);
+		if (i < (n - 1))
+		    VISIT(c, expr, 
+                            (expr_ty)asdl_seq_GET(e->v.Compare.comparators, i));
+	}
+	VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, n - 1));
+	ADDOP_I(c, COMPARE_OP,
+	       cmpop((cmpop_ty)(asdl_seq_GET(e->v.Compare.ops, n - 1))));
+	if (n > 1) {
+		basicblock *end = compiler_new_block(c);
+		if (end == NULL)
+		    return 0;
+		ADDOP_JREL(c, JUMP_FORWARD, end);
+		compiler_use_next_block(c, cleanup);
+		ADDOP(c, ROT_TWO);
+		ADDOP(c, POP_TOP);
+		compiler_use_next_block(c, end);
+	}
+	return 1;
+}
+#undef CMPCAST
+
+static int
+compiler_call(struct compiler *c, expr_ty e)
+{
+	int n, code = 0;
+
+	VISIT(c, expr, e->v.Call.func);
+	n = asdl_seq_LEN(e->v.Call.args);
+	VISIT_SEQ(c, expr, e->v.Call.args);
+	if (e->v.Call.keywords) {
+		VISIT_SEQ(c, keyword, e->v.Call.keywords);
+		n |= asdl_seq_LEN(e->v.Call.keywords) << 8;
+	}
+	if (e->v.Call.starargs) {
+		VISIT(c, expr, e->v.Call.starargs);
+		code |= 1;
+	}
+	if (e->v.Call.kwargs) {
+		VISIT(c, expr, e->v.Call.kwargs);
+		code |= 2;
+	}
+	switch (code) {
+	case 0:
+		ADDOP_I(c, CALL_FUNCTION, n);
+		break;
+	case 1:
+		ADDOP_I(c, CALL_FUNCTION_VAR, n);
+		break;
+	case 2:
+		ADDOP_I(c, CALL_FUNCTION_KW, n);
+		break;
+	case 3:
+		ADDOP_I(c, CALL_FUNCTION_VAR_KW, n);
+		break;
+	}
+	return 1;
+}
+
+static int
+compiler_listcomp_generator(struct compiler *c, PyObject *tmpname,
+			    asdl_seq *generators, int gen_index, 
+			    expr_ty elt)
+{
+	/* generate code for the iterator, then each of the ifs,
+	   and then write to the element */
+
+	comprehension_ty l;
+	basicblock *start, *anchor, *skip, *if_cleanup;
+	int i, n;
+
+	start = compiler_new_block(c);
+	skip = compiler_new_block(c);
+	if_cleanup = compiler_new_block(c);
+	anchor = compiler_new_block(c);
+
+	if (start == NULL || skip == NULL || if_cleanup == NULL ||
+		anchor == NULL)
+	    return 0;
+
+	l = (comprehension_ty)asdl_seq_GET(generators, gen_index);
+	VISIT(c, expr, l->iter);
+	ADDOP(c, GET_ITER);
+	compiler_use_next_block(c, start);
+	ADDOP_JREL(c, FOR_ITER, anchor);
+	NEXT_BLOCK(c);
+	VISIT(c, expr, l->target);
+
+	/* XXX this needs to be cleaned up...a lot! */
+	n = asdl_seq_LEN(l->ifs);
+	for (i = 0; i < n; i++) {
+		expr_ty e = (expr_ty)asdl_seq_GET(l->ifs, i);
+		VISIT(c, expr, e);
+		ADDOP_JREL(c, JUMP_IF_FALSE, if_cleanup);
+		NEXT_BLOCK(c);
+		ADDOP(c, POP_TOP);
+	} 
+
+	if (++gen_index < asdl_seq_LEN(generators))
+	    if (!compiler_listcomp_generator(c, tmpname, 
+					     generators, gen_index, elt))
+		return 0;
+
+	/* only append after the last for generator */
+	if (gen_index >= asdl_seq_LEN(generators)) {
+	    if (!compiler_nameop(c, tmpname, Load))
+		return 0;
+	    VISIT(c, expr, elt);
+	    ADDOP(c, LIST_APPEND);
+
+	    compiler_use_next_block(c, skip);
+	}
+	for (i = 0; i < n; i++) {
+		ADDOP_I(c, JUMP_FORWARD, 1);
+		if (i == 0)
+		    compiler_use_next_block(c, if_cleanup);
+		ADDOP(c, POP_TOP);
+	} 
+	ADDOP_JABS(c, JUMP_ABSOLUTE, start);
+	compiler_use_next_block(c, anchor);
+	/* delete the append method added to locals */
+	if (gen_index == 1)
+	    if (!compiler_nameop(c, tmpname, Del))
+		return 0;
+	
+	return 1;
+}
+
+static int
+compiler_listcomp(struct compiler *c, expr_ty e)
+{
+	identifier tmp;
+	int rc = 0;
+	static identifier append;
+	asdl_seq *generators = e->v.ListComp.generators;
+
+	assert(e->kind == ListComp_kind);
+	if (!append) {
+		append = PyString_InternFromString("append");
+		if (!append)
+			return 0;
+	}
+	tmp = compiler_new_tmpname(c);
+	if (!tmp)
+		return 0;
+	ADDOP_I(c, BUILD_LIST, 0);
+	ADDOP(c, DUP_TOP);
+	if (compiler_nameop(c, tmp, Store))
+	    rc = compiler_listcomp_generator(c, tmp, generators, 0, 
+					     e->v.ListComp.elt);
+	Py_DECREF(tmp);
+	return rc;
+}
+
+static int
+compiler_genexp_generator(struct compiler *c,
+			  asdl_seq *generators, int gen_index, 
+			  expr_ty elt)
+{
+	/* generate code for the iterator, then each of the ifs,
+	   and then write to the element */
+
+	comprehension_ty ge;
+	basicblock *start, *anchor, *skip, *if_cleanup, *end;
+	int i, n;
+
+	start = compiler_new_block(c);
+	skip = compiler_new_block(c);
+	if_cleanup = compiler_new_block(c);
+	anchor = compiler_new_block(c);
+	end = compiler_new_block(c);
+
+	if (start == NULL || skip == NULL || if_cleanup == NULL ||
+	    anchor == NULL || end == NULL)
+		return 0;
+
+	ge = (comprehension_ty)asdl_seq_GET(generators, gen_index);
+	ADDOP_JREL(c, SETUP_LOOP, end);
+	if (!compiler_push_fblock(c, LOOP, start))
+		return 0;
+
+	if (gen_index == 0) {
+		/* Receive outermost iter as an implicit argument */
+		c->u->u_argcount = 1;
+		ADDOP_I(c, LOAD_FAST, 0);
+	}
+	else {
+		/* Sub-iter - calculate on the fly */
+		VISIT(c, expr, ge->iter);
+		ADDOP(c, GET_ITER);
+	}
+	compiler_use_next_block(c, start);
+	ADDOP_JREL(c, FOR_ITER, anchor);
+	NEXT_BLOCK(c);
+	VISIT(c, expr, ge->target);
+
+	/* XXX this needs to be cleaned up...a lot! */
+	n = asdl_seq_LEN(ge->ifs);
+	for (i = 0; i < n; i++) {
+		expr_ty e = (expr_ty)asdl_seq_GET(ge->ifs, i);
+		VISIT(c, expr, e);
+		ADDOP_JREL(c, JUMP_IF_FALSE, if_cleanup);
+		NEXT_BLOCK(c);
+		ADDOP(c, POP_TOP);
+	} 
+
+	if (++gen_index < asdl_seq_LEN(generators))
+		if (!compiler_genexp_generator(c, generators, gen_index, elt))
+			return 0;
+
+	/* only append after the last 'for' generator */
+	if (gen_index >= asdl_seq_LEN(generators)) {
+		VISIT(c, expr, elt);
+		ADDOP(c, YIELD_VALUE);
+		ADDOP(c, POP_TOP);
+
+		compiler_use_next_block(c, skip);
+	}
+	for (i = 0; i < n; i++) {
+		ADDOP_I(c, JUMP_FORWARD, 1);
+		if (i == 0)
+			compiler_use_next_block(c, if_cleanup);
+
+		ADDOP(c, POP_TOP);
+	} 
+	ADDOP_JABS(c, JUMP_ABSOLUTE, start);
+	compiler_use_next_block(c, anchor);
+	ADDOP(c, POP_BLOCK);
+	compiler_pop_fblock(c, LOOP, start);
+	compiler_use_next_block(c, end);
+
+	return 1;
+}
+
+static int
+compiler_genexp(struct compiler *c, expr_ty e)
+{
+	static identifier name;
+	PyCodeObject *co;
+	expr_ty outermost_iter = ((comprehension_ty)
+				 (asdl_seq_GET(e->v.GeneratorExp.generators,
+					       0)))->iter;
+
+	if (!name) {
+		name = PyString_FromString("<genexpr>");
+		if (!name)
+			return 0;
+	}
+
+	if (!compiler_enter_scope(c, name, (void *)e, e->lineno))
+		return 0;
+	compiler_genexp_generator(c, e->v.GeneratorExp.generators, 0,
+				  e->v.GeneratorExp.elt);
+	co = assemble(c, 1);
+	compiler_exit_scope(c);
+	if (co == NULL)
+		return 0;
+
+	compiler_make_closure(c, co, 0);
+	Py_DECREF(co);
+
+	VISIT(c, expr, outermost_iter);
+	ADDOP(c, GET_ITER);
+	ADDOP_I(c, CALL_FUNCTION, 1);
+
+	return 1;
+}
+
+static int
+compiler_visit_keyword(struct compiler *c, keyword_ty k)
+{
+	ADDOP_O(c, LOAD_CONST, k->arg, consts);
+	VISIT(c, expr, k->value);
+	return 1;
+}
+
+/* Test whether expression is constant.	 For constants, report
+   whether they are true or false.
+
+   Return values: 1 for true, 0 for false, -1 for non-constant.
+ */
+
+static int
+expr_constant(expr_ty e)
+{
+	switch (e->kind) {
+	case Num_kind:
+		return PyObject_IsTrue(e->v.Num.n);
+	case Str_kind:
+		return PyObject_IsTrue(e->v.Str.s);
+	case Name_kind:
+		/* __debug__ is not assignable, so we can optimize
+		 * it away in if and while statements */
+		if (strcmp(PyString_AS_STRING(e->v.Name.id),
+		           "__debug__") == 0)
+			   return ! Py_OptimizeFlag;
+		/* fall through */
+	default:
+		return -1;
+	}
+}
+
+/*
+   Implements the with statement from PEP 343.
+
+   The semantics outlined in that PEP are as follows:  
+
+   with EXPR as VAR:
+       BLOCK
+  
+   It is implemented roughly as:
+  
+   context = EXPR
+   exit = context.__exit__  # not calling it
+   value = context.__enter__()
+   try:
+       VAR = value  # if VAR present in the syntax
+       BLOCK
+   finally:
+       if an exception was raised:
+	   exc = copy of (exception, instance, traceback)
+       else:
+	   exc = (None, None, None)
+       exit(*exc)
+ */
+static int
+compiler_with(struct compiler *c, stmt_ty s)
+{
+    static identifier enter_attr, exit_attr;
+    basicblock *block, *finally;
+    identifier tmpexit, tmpvalue = NULL;
+
+    assert(s->kind == With_kind);
+
+    if (!enter_attr) {
+	enter_attr = PyString_InternFromString("__enter__");
+	if (!enter_attr)
+	    return 0;
+    }
+    if (!exit_attr) {
+	exit_attr = PyString_InternFromString("__exit__");
+	if (!exit_attr)
+	    return 0;
+    }
+
+    block = compiler_new_block(c);
+    finally = compiler_new_block(c);
+    if (!block || !finally)
+	return 0;
+
+    /* Create a temporary variable to hold context.__exit__ */
+    tmpexit = compiler_new_tmpname(c);
+    if (tmpexit == NULL)
+	return 0;
+    PyArena_AddPyObject(c->c_arena, tmpexit);
+
+    if (s->v.With.optional_vars) {
+	/* Create a temporary variable to hold context.__enter__().
+	   We need to do this rather than preserving it on the stack
+	   because SETUP_FINALLY remembers the stack level.
+	   We need to do the assignment *inside* the try/finally
+	   so that context.__exit__() is called when the assignment
+	   fails.  But we need to call context.__enter__() *before*
+	   the try/finally so that if it fails we won't call
+	   context.__exit__().
+	*/
+	tmpvalue = compiler_new_tmpname(c);
+	if (tmpvalue == NULL)
+	    return 0;
+	PyArena_AddPyObject(c->c_arena, tmpvalue);
+    }
+
+    /* Evaluate EXPR */
+    VISIT(c, expr, s->v.With.context_expr);
+
+    /* Squirrel away context.__exit__  */
+    ADDOP(c, DUP_TOP);
+    ADDOP_O(c, LOAD_ATTR, exit_attr, names);
+    if (!compiler_nameop(c, tmpexit, Store))
+	return 0;
+
+    /* Call context.__enter__() */
+    ADDOP_O(c, LOAD_ATTR, enter_attr, names);
+    ADDOP_I(c, CALL_FUNCTION, 0);
+
+    if (s->v.With.optional_vars) {
+	/* Store it in tmpvalue */
+	if (!compiler_nameop(c, tmpvalue, Store))
+	    return 0;
+    }
+    else {
+	/* Discard result from context.__enter__() */
+	ADDOP(c, POP_TOP);
+    }
+
+    /* Start the try block */
+    ADDOP_JREL(c, SETUP_FINALLY, finally);
+
+    compiler_use_next_block(c, block);
+    if (!compiler_push_fblock(c, FINALLY_TRY, block)) {
+	return 0;
+    }
+
+    if (s->v.With.optional_vars) {
+	/* Bind saved result of context.__enter__() to VAR */
+	if (!compiler_nameop(c, tmpvalue, Load) ||
+	    !compiler_nameop(c, tmpvalue, Del))
+	  return 0;
+	VISIT(c, expr, s->v.With.optional_vars);
+    }
+
+    /* BLOCK code */
+    VISIT_SEQ(c, stmt, s->v.With.body);
+
+    /* End of try block; start the finally block */
+    ADDOP(c, POP_BLOCK);
+    compiler_pop_fblock(c, FINALLY_TRY, block);
+
+    ADDOP_O(c, LOAD_CONST, Py_None, consts);
+    compiler_use_next_block(c, finally);
+    if (!compiler_push_fblock(c, FINALLY_END, finally))
+	return 0;
+
+    /* Finally block starts; push tmpexit and issue our magic opcode. */
+    if (!compiler_nameop(c, tmpexit, Load) ||
+	!compiler_nameop(c, tmpexit, Del))
+	return 0;
+    ADDOP(c, WITH_CLEANUP);
+
+    /* Finally block ends. */
+    ADDOP(c, END_FINALLY);
+    compiler_pop_fblock(c, FINALLY_END, finally);
+    return 1;
+}
+
+static int
+compiler_visit_expr(struct compiler *c, expr_ty e)
+{
+	int i, n;
+
+    /* If expr e has a different line number than the last expr/stmt,
+       set a new line number for the next instruction.
+       */
+	if (e->lineno > c->u->u_lineno) {
+		c->u->u_lineno = e->lineno;
+		c->u->u_lineno_set = false;
+	}
+	switch (e->kind) {
+	case BoolOp_kind:
+		return compiler_boolop(c, e);
+	case BinOp_kind:
+		VISIT(c, expr, e->v.BinOp.left);
+		VISIT(c, expr, e->v.BinOp.right);
+		ADDOP(c, binop(c, e->v.BinOp.op));
+		break;
+	case UnaryOp_kind:
+		VISIT(c, expr, e->v.UnaryOp.operand);
+		ADDOP(c, unaryop(e->v.UnaryOp.op));
+		break;
+	case Lambda_kind:
+		return compiler_lambda(c, e);
+	case IfExp_kind:
+		return compiler_ifexp(c, e);
+	case Dict_kind:
+		/* XXX get rid of arg? */
+		ADDOP_I(c, BUILD_MAP, 0);
+		n = asdl_seq_LEN(e->v.Dict.values);
+		/* We must arrange things just right for STORE_SUBSCR.
+		   It wants the stack to look like (value) (dict) (key) */
+		for (i = 0; i < n; i++) {
+			ADDOP(c, DUP_TOP);
+			VISIT(c, expr, 
+                                (expr_ty)asdl_seq_GET(e->v.Dict.values, i));
+			ADDOP(c, ROT_TWO);
+			VISIT(c, expr, 
+                                (expr_ty)asdl_seq_GET(e->v.Dict.keys, i));
+			ADDOP(c, STORE_SUBSCR);
+		}
+		break;
+	case ListComp_kind:
+		return compiler_listcomp(c, e);
+	case GeneratorExp_kind:
+		return compiler_genexp(c, e);
+	case Yield_kind:
+		if (c->u->u_ste->ste_type != FunctionBlock)
+			return compiler_error(c, "'yield' outside function");
+		/*
+		for (i = 0; i < c->u->u_nfblocks; i++) {
+			if (c->u->u_fblock[i].fb_type == FINALLY_TRY)
+				return compiler_error(
+					c, "'yield' not allowed in a 'try' "
+					"block with a 'finally' clause");
+		}
+		*/
+		if (e->v.Yield.value) {
+			VISIT(c, expr, e->v.Yield.value);
+		}
+		else {
+			ADDOP_O(c, LOAD_CONST, Py_None, consts);
+		}
+		ADDOP(c, YIELD_VALUE);
+		break;
+	case Compare_kind:
+		return compiler_compare(c, e);
+	case Call_kind:
+		return compiler_call(c, e);
+	case Repr_kind:
+		VISIT(c, expr, e->v.Repr.value);
+		ADDOP(c, UNARY_CONVERT);
+		break;
+	case Num_kind:
+		ADDOP_O(c, LOAD_CONST, e->v.Num.n, consts);
+		break;
+	case Str_kind:
+		ADDOP_O(c, LOAD_CONST, e->v.Str.s, consts);
+		break;
+	/* The following exprs can be assignment targets. */
+	case Attribute_kind:
+		if (e->v.Attribute.ctx != AugStore)
+			VISIT(c, expr, e->v.Attribute.value);
+		switch (e->v.Attribute.ctx) {
+		case AugLoad:
+			ADDOP(c, DUP_TOP);
+			/* Fall through to load */
+		case Load:
+			ADDOP_NAME(c, LOAD_ATTR, e->v.Attribute.attr, names);
+			break;
+		case AugStore:
+			ADDOP(c, ROT_TWO);
+			/* Fall through to save */
+		case Store:
+			ADDOP_NAME(c, STORE_ATTR, e->v.Attribute.attr, names);
+			break;
+		case Del:
+			ADDOP_NAME(c, DELETE_ATTR, e->v.Attribute.attr, names);
+			break;
+		case Param:
+		default:
+			PyErr_SetString(PyExc_SystemError,
+					"param invalid in attribute expression");
+			return 0;
+		}
+		break;
+	case Subscript_kind:
+		switch (e->v.Subscript.ctx) {
+		case AugLoad:
+			VISIT(c, expr, e->v.Subscript.value);
+			VISIT_SLICE(c, e->v.Subscript.slice, AugLoad);
+			break;
+		case Load:
+			VISIT(c, expr, e->v.Subscript.value);
+			VISIT_SLICE(c, e->v.Subscript.slice, Load);
+			break;
+		case AugStore:
+			VISIT_SLICE(c, e->v.Subscript.slice, AugStore);
+			break;
+		case Store:
+			VISIT(c, expr, e->v.Subscript.value);
+			VISIT_SLICE(c, e->v.Subscript.slice, Store);
+			break;
+		case Del:
+			VISIT(c, expr, e->v.Subscript.value);
+			VISIT_SLICE(c, e->v.Subscript.slice, Del);
+			break;
+		case Param:
+		default:
+			PyErr_SetString(PyExc_SystemError,
+				"param invalid in subscript expression");
+			return 0;
+		}
+		break;
+	case Name_kind:
+		return compiler_nameop(c, e->v.Name.id, e->v.Name.ctx);
+	/* child nodes of List and Tuple will have expr_context set */
+	case List_kind:
+		return compiler_list(c, e);
+	case Tuple_kind:
+		return compiler_tuple(c, e);
+	}
+	return 1;
+}
+
+static int
+compiler_augassign(struct compiler *c, stmt_ty s)
+{
+	expr_ty e = s->v.AugAssign.target;
+	expr_ty auge;
+
+	assert(s->kind == AugAssign_kind);
+
+	switch (e->kind) {
+	case Attribute_kind:
+		auge = Attribute(e->v.Attribute.value, e->v.Attribute.attr,
+				 AugLoad, e->lineno, e->col_offset, c->c_arena);
+		if (auge == NULL)
+		    return 0;
+		VISIT(c, expr, auge);
+		VISIT(c, expr, s->v.AugAssign.value);
+		ADDOP(c, inplace_binop(c, s->v.AugAssign.op));
+		auge->v.Attribute.ctx = AugStore;
+		VISIT(c, expr, auge);
+		break;
+	case Subscript_kind:
+		auge = Subscript(e->v.Subscript.value, e->v.Subscript.slice,
+				 AugLoad, e->lineno, e->col_offset, c->c_arena);
+		if (auge == NULL)
+		    return 0;
+		VISIT(c, expr, auge);
+		VISIT(c, expr, s->v.AugAssign.value);
+		ADDOP(c, inplace_binop(c, s->v.AugAssign.op));
+		auge->v.Subscript.ctx = AugStore;
+		VISIT(c, expr, auge);
+		break;
+	case Name_kind:
+		if (!compiler_nameop(c, e->v.Name.id, Load))
+		    return 0;
+		VISIT(c, expr, s->v.AugAssign.value);
+		ADDOP(c, inplace_binop(c, s->v.AugAssign.op));
+		return compiler_nameop(c, e->v.Name.id, Store);
+	default:
+		PyErr_Format(PyExc_SystemError, 
+			"invalid node type (%d) for augmented assignment",
+			e->kind);
+		return 0;
+	}
+	return 1;
+}
+
+static int
+compiler_push_fblock(struct compiler *c, enum fblocktype t, basicblock *b)
+{
+	struct fblockinfo *f;
+	if (c->u->u_nfblocks >= CO_MAXBLOCKS) {
+		PyErr_SetString(PyExc_SystemError,
+				"too many statically nested blocks");
+		return 0;
+	}
+	f = &c->u->u_fblock[c->u->u_nfblocks++];
+	f->fb_type = t;
+	f->fb_block = b;
+	return 1;
+}
+
+static void
+compiler_pop_fblock(struct compiler *c, enum fblocktype t, basicblock *b)
+{
+	struct compiler_unit *u = c->u;
+	assert(u->u_nfblocks > 0);
+	u->u_nfblocks--;
+	assert(u->u_fblock[u->u_nfblocks].fb_type == t);
+	assert(u->u_fblock[u->u_nfblocks].fb_block == b);
+}
+
+static int
+compiler_in_loop(struct compiler *c) {
+        int i;
+        struct compiler_unit *u = c->u;
+        for (i = 0; i < u->u_nfblocks; ++i) {
+                if (u->u_fblock[i].fb_type == LOOP)
+                        return 1;
+        }
+        return 0;
+}
+/* Raises a SyntaxError and returns 0.
+   If something goes wrong, a different exception may be raised.
+*/
+
+static int
+compiler_error(struct compiler *c, const char *errstr)
+{
+	PyObject *loc;
+	PyObject *u = NULL, *v = NULL;
+
+	loc = PyErr_ProgramText(c->c_filename, c->u->u_lineno);
+	if (!loc) {
+		Py_INCREF(Py_None);
+		loc = Py_None;
+	}
+	u = Py_BuildValue("(ziOO)", c->c_filename, c->u->u_lineno,
+			  Py_None, loc);
+	if (!u)
+		goto exit;
+	v = Py_BuildValue("(zO)", errstr, u);
+	if (!v)
+		goto exit;
+	PyErr_SetObject(PyExc_SyntaxError, v);
+ exit:
+	Py_DECREF(loc);
+	Py_XDECREF(u);
+	Py_XDECREF(v);
+	return 0;
+}
+
+static int
+compiler_handle_subscr(struct compiler *c, const char *kind, 
+		       expr_context_ty ctx) 
+{
+	int op = 0;
+
+	/* XXX this code is duplicated */
+	switch (ctx) {
+		case AugLoad: /* fall through to Load */
+		case Load:    op = BINARY_SUBSCR; break;
+		case AugStore:/* fall through to Store */
+		case Store:   op = STORE_SUBSCR; break;
+		case Del:     op = DELETE_SUBSCR; break;
+		case Param:
+			PyErr_Format(PyExc_SystemError, 
+				     "invalid %s kind %d in subscript\n", 
+				     kind, ctx);
+			return 0;
+	}
+	if (ctx == AugLoad) {
+		ADDOP_I(c, DUP_TOPX, 2);
+	}
+	else if (ctx == AugStore) {
+		ADDOP(c, ROT_THREE);
+	}
+	ADDOP(c, op);
+	return 1;
+}
+
+static int
+compiler_slice(struct compiler *c, slice_ty s, expr_context_ty ctx)
+{
+	int n = 2;
+	assert(s->kind == Slice_kind);
+
+	/* only handles the cases where BUILD_SLICE is emitted */
+	if (s->v.Slice.lower) {
+		VISIT(c, expr, s->v.Slice.lower);
+	}
+	else {
+		ADDOP_O(c, LOAD_CONST, Py_None, consts);
+	}
+		
+	if (s->v.Slice.upper) {
+		VISIT(c, expr, s->v.Slice.upper);
+	}
+	else {
+		ADDOP_O(c, LOAD_CONST, Py_None, consts);
+	}
+
+	if (s->v.Slice.step) {
+		n++;
+		VISIT(c, expr, s->v.Slice.step);
+	}
+	ADDOP_I(c, BUILD_SLICE, n);
+	return 1;
+}
+
+static int
+compiler_simple_slice(struct compiler *c, slice_ty s, expr_context_ty ctx)
+{
+	int op = 0, slice_offset = 0, stack_count = 0;
+
+	assert(s->v.Slice.step == NULL);
+	if (s->v.Slice.lower) {
+		slice_offset++;
+		stack_count++;
+		if (ctx != AugStore) 
+			VISIT(c, expr, s->v.Slice.lower);
+	}
+	if (s->v.Slice.upper) {
+		slice_offset += 2;
+		stack_count++;
+		if (ctx != AugStore) 
+			VISIT(c, expr, s->v.Slice.upper);
+	}
+
+	if (ctx == AugLoad) {
+		switch (stack_count) {
+		case 0: ADDOP(c, DUP_TOP); break;
+		case 1: ADDOP_I(c, DUP_TOPX, 2); break;
+		case 2: ADDOP_I(c, DUP_TOPX, 3); break;
+		}
+	}
+	else if (ctx == AugStore) {
+		switch (stack_count) {
+		case 0: ADDOP(c, ROT_TWO); break;
+		case 1: ADDOP(c, ROT_THREE); break;
+		case 2: ADDOP(c, ROT_FOUR); break;
+		}
+	}
+
+	switch (ctx) {
+	case AugLoad: /* fall through to Load */
+	case Load: op = SLICE; break;
+	case AugStore:/* fall through to Store */
+	case Store: op = STORE_SLICE; break;
+	case Del: op = DELETE_SLICE; break;
+	case Param:
+	default:
+		PyErr_SetString(PyExc_SystemError,
+				"param invalid in simple slice");
+		return 0;
+	}
+
+	ADDOP(c, op + slice_offset);
+	return 1;
+}
+
+static int
+compiler_visit_nested_slice(struct compiler *c, slice_ty s, 
+			    expr_context_ty ctx)
+{
+	switch (s->kind) {
+	case Ellipsis_kind:
+		ADDOP_O(c, LOAD_CONST, Py_Ellipsis, consts);
+		break;
+	case Slice_kind:
+		return compiler_slice(c, s, ctx);
+	case Index_kind:
+		VISIT(c, expr, s->v.Index.value);
+		break;
+	case ExtSlice_kind:
+	default:
+		PyErr_SetString(PyExc_SystemError,
+				"extended slice invalid in nested slice");
+		return 0;
+	}
+	return 1;
+}
+
+
+static int
+compiler_visit_slice(struct compiler *c, slice_ty s, expr_context_ty ctx)
+{
+	char * kindname = NULL;
+	switch (s->kind) {
+	case Index_kind:
+		kindname = "index";
+		if (ctx != AugStore) {
+			VISIT(c, expr, s->v.Index.value);
+		}
+		break;
+	case Ellipsis_kind:
+		kindname = "ellipsis";
+		if (ctx != AugStore) {
+			ADDOP_O(c, LOAD_CONST, Py_Ellipsis, consts);
+		}
+		break;
+	case Slice_kind:
+		kindname = "slice";
+		if (!s->v.Slice.step) 
+			return compiler_simple_slice(c, s, ctx);
+		if (ctx != AugStore) {
+			if (!compiler_slice(c, s, ctx))
+				return 0;
+		}
+		break;
+	case ExtSlice_kind:
+		kindname = "extended slice";
+		if (ctx != AugStore) {
+			int i, n = asdl_seq_LEN(s->v.ExtSlice.dims);
+			for (i = 0; i < n; i++) {
+				slice_ty sub = (slice_ty)asdl_seq_GET(
+                                        s->v.ExtSlice.dims, i);
+				if (!compiler_visit_nested_slice(c, sub, ctx))
+					return 0;
+			}
+			ADDOP_I(c, BUILD_TUPLE, n);
+		}
+		break;
+	default:
+		PyErr_Format(PyExc_SystemError,
+			     "invalid subscript kind %d", s->kind);
+		return 0;
+	}
+	return compiler_handle_subscr(c, kindname, ctx);
+}
+
+/* do depth-first search of basic block graph, starting with block.
+   post records the block indices in post-order.
+
+   XXX must handle implicit jumps from one block to next
+*/
+
+static void
+dfs(struct compiler *c, basicblock *b, struct assembler *a)
+{
+	int i;
+	struct instr *instr = NULL;
+
+	if (b->b_seen)
+		return;
+	b->b_seen = 1;
+	if (b->b_next != NULL)
+		dfs(c, b->b_next, a);
+	for (i = 0; i < b->b_iused; i++) {
+		instr = &b->b_instr[i];
+		if (instr->i_jrel || instr->i_jabs)
+			dfs(c, instr->i_target, a);
+	}
+	a->a_postorder[a->a_nblocks++] = b;
+}
+
+static int
+stackdepth_walk(struct compiler *c, basicblock *b, int depth, int maxdepth)
+{
+	int i;
+	struct instr *instr;
+	if (b->b_seen || b->b_startdepth >= depth)
+		return maxdepth;
+	b->b_seen = 1;
+	b->b_startdepth = depth;
+	for (i = 0; i < b->b_iused; i++) {
+		instr = &b->b_instr[i];
+		depth += opcode_stack_effect(instr->i_opcode, instr->i_oparg);
+		if (depth > maxdepth)
+			maxdepth = depth;
+		assert(depth >= 0); /* invalid code or bug in stackdepth() */
+		if (instr->i_jrel || instr->i_jabs) {
+			maxdepth = stackdepth_walk(c, instr->i_target,
+						   depth, maxdepth);
+			if (instr->i_opcode == JUMP_ABSOLUTE ||
+			    instr->i_opcode == JUMP_FORWARD) {
+				goto out; /* remaining code is dead */
+			}
+		}
+	}
+	if (b->b_next)
+		maxdepth = stackdepth_walk(c, b->b_next, depth, maxdepth);
+out:
+	b->b_seen = 0;
+	return maxdepth;
+}
+
+/* Find the flow path that needs the largest stack.  We assume that
+ * cycles in the flow graph have no net effect on the stack depth.
+ */
+static int
+stackdepth(struct compiler *c)
+{
+	basicblock *b, *entryblock;
+	entryblock = NULL;
+	for (b = c->u->u_blocks; b != NULL; b = b->b_list) {
+		b->b_seen = 0;
+		b->b_startdepth = INT_MIN;
+		entryblock = b;
+	}
+	if (!entryblock)
+		return 0;
+	return stackdepth_walk(c, entryblock, 0, 0);
+}
+
+static int
+assemble_init(struct assembler *a, int nblocks, int firstlineno)
+{
+	memset(a, 0, sizeof(struct assembler));
+	a->a_lineno = firstlineno;
+	a->a_bytecode = PyString_FromStringAndSize(NULL, DEFAULT_CODE_SIZE);
+	if (!a->a_bytecode)
+		return 0;
+	a->a_lnotab = PyString_FromStringAndSize(NULL, DEFAULT_LNOTAB_SIZE);
+	if (!a->a_lnotab)
+		return 0;
+	a->a_postorder = (basicblock **)PyObject_Malloc(
+					    sizeof(basicblock *) * nblocks);
+	if (!a->a_postorder) {
+		PyErr_NoMemory();
+		return 0;
+	}
+	return 1;
+}
+
+static void
+assemble_free(struct assembler *a)
+{
+	Py_XDECREF(a->a_bytecode);
+	Py_XDECREF(a->a_lnotab);
+	if (a->a_postorder)
+		PyObject_Free(a->a_postorder);
+}
+
+/* Return the size of a basic block in bytes. */
+
+static int
+instrsize(struct instr *instr)
+{
+	if (!instr->i_hasarg)
+		return 1;
+	if (instr->i_oparg > 0xffff)
+		return 6;
+	return 3;
+}
+
+static int
+blocksize(basicblock *b)
+{
+	int i;
+	int size = 0;
+
+	for (i = 0; i < b->b_iused; i++)
+		size += instrsize(&b->b_instr[i]);
+	return size;
+}
+
+/* All about a_lnotab.
+
+c_lnotab is an array of unsigned bytes disguised as a Python string.
+It is used to map bytecode offsets to source code line #s (when needed
+for tracebacks).
+
+The array is conceptually a list of
+    (bytecode offset increment, line number increment)
+pairs.	The details are important and delicate, best illustrated by example:
+
+    byte code offset	source code line number
+	0		    1
+	6		    2
+       50		    7
+      350		  307
+      361		  308
+
+The first trick is that these numbers aren't stored, only the increments
+from one row to the next (this doesn't really work, but it's a start):
+
+    0, 1,  6, 1,  44, 5,  300, 300,  11, 1
+
+The second trick is that an unsigned byte can't hold negative values, or
+values larger than 255, so (a) there's a deep assumption that byte code
+offsets and their corresponding line #s both increase monotonically, and (b)
+if at least one column jumps by more than 255 from one row to the next, more
+than one pair is written to the table. In case #b, there's no way to know
+from looking at the table later how many were written.	That's the delicate
+part.  A user of c_lnotab desiring to find the source line number
+corresponding to a bytecode address A should do something like this
+
+    lineno = addr = 0
+    for addr_incr, line_incr in c_lnotab:
+	addr += addr_incr
+	if addr > A:
+	    return lineno
+	lineno += line_incr
+
+In order for this to work, when the addr field increments by more than 255,
+the line # increment in each pair generated must be 0 until the remaining addr
+increment is < 256.  So, in the example above, assemble_lnotab (it used
+to be called com_set_lineno) should not (as was actually done until 2.2)
+expand 300, 300 to 255, 255, 45, 45, 
+            but to 255,   0, 45, 255, 0, 45.
+*/
+
+static int
+assemble_lnotab(struct assembler *a, struct instr *i)
+{
+	int d_bytecode, d_lineno;
+	int len;
+	unsigned char *lnotab;
+
+	d_bytecode = a->a_offset - a->a_lineno_off;
+	d_lineno = i->i_lineno - a->a_lineno;
+
+	assert(d_bytecode >= 0);
+	assert(d_lineno >= 0);
+
+	/* XXX(nnorwitz): is there a better way to handle this?
+	   for loops are special, we want to be able to trace them
+	   each time around, so we need to set an extra line number. */
+	if (d_lineno == 0 && i->i_opcode != FOR_ITER)
+		return 1;
+
+	if (d_bytecode > 255) {
+		int j, nbytes, ncodes = d_bytecode / 255;
+		nbytes = a->a_lnotab_off + 2 * ncodes;
+		len = PyString_GET_SIZE(a->a_lnotab);
+		if (nbytes >= len) {
+			if (len * 2 < nbytes)
+				len = nbytes;
+			else
+				len *= 2;
+			if (_PyString_Resize(&a->a_lnotab, len) < 0)
+				return 0;
+		}
+		lnotab = (unsigned char *)
+			   PyString_AS_STRING(a->a_lnotab) + a->a_lnotab_off;
+		for (j = 0; j < ncodes; j++) {
+			*lnotab++ = 255;
+			*lnotab++ = 0;
+		}
+		d_bytecode -= ncodes * 255;
+		a->a_lnotab_off += ncodes * 2;
+	}
+	assert(d_bytecode <= 255);
+	if (d_lineno > 255) {
+		int j, nbytes, ncodes = d_lineno / 255;
+		nbytes = a->a_lnotab_off + 2 * ncodes;
+		len = PyString_GET_SIZE(a->a_lnotab);
+		if (nbytes >= len) {
+			if (len * 2 < nbytes)
+				len = nbytes;
+			else
+				len *= 2;
+			if (_PyString_Resize(&a->a_lnotab, len) < 0)
+				return 0;
+		}
+		lnotab = (unsigned char *)
+			   PyString_AS_STRING(a->a_lnotab) + a->a_lnotab_off;
+		*lnotab++ = d_bytecode;
+		*lnotab++ = 255;
+		d_bytecode = 0;
+		for (j = 1; j < ncodes; j++) {
+			*lnotab++ = 0;
+			*lnotab++ = 255;
+		}
+		d_lineno -= ncodes * 255;
+		a->a_lnotab_off += ncodes * 2;
+	}
+
+	len = PyString_GET_SIZE(a->a_lnotab);
+	if (a->a_lnotab_off + 2 >= len) {
+		if (_PyString_Resize(&a->a_lnotab, len * 2) < 0)
+			return 0;
+	}
+	lnotab = (unsigned char *)
+			PyString_AS_STRING(a->a_lnotab) + a->a_lnotab_off;
+
+	a->a_lnotab_off += 2;
+	if (d_bytecode) {
+		*lnotab++ = d_bytecode;
+		*lnotab++ = d_lineno;
+	}
+	else {	/* First line of a block; def stmt, etc. */
+		*lnotab++ = 0;
+		*lnotab++ = d_lineno;
+	}
+	a->a_lineno = i->i_lineno;
+	a->a_lineno_off = a->a_offset;
+	return 1;
+}
+
+/* assemble_emit()
+   Extend the bytecode with a new instruction.
+   Update lnotab if necessary.
+*/
+
+static int
+assemble_emit(struct assembler *a, struct instr *i)
+{
+	int size, arg = 0, ext = 0;
+	Py_ssize_t len = PyString_GET_SIZE(a->a_bytecode);
+	char *code;
+
+	size = instrsize(i);
+	if (i->i_hasarg) {
+		arg = i->i_oparg;
+		ext = arg >> 16;
+	}
+	if (i->i_lineno && !assemble_lnotab(a, i))
+		return 0;
+	if (a->a_offset + size >= len) {
+		if (_PyString_Resize(&a->a_bytecode, len * 2) < 0)
+		    return 0;
+	}
+	code = PyString_AS_STRING(a->a_bytecode) + a->a_offset;
+	a->a_offset += size;
+	if (size == 6) {
+		assert(i->i_hasarg);
+		*code++ = (char)EXTENDED_ARG;
+		*code++ = ext & 0xff;
+		*code++ = ext >> 8;
+		arg &= 0xffff;
+	}
+	*code++ = i->i_opcode;
+	if (i->i_hasarg) {
+		assert(size == 3 || size == 6);
+		*code++ = arg & 0xff;
+		*code++ = arg >> 8;
+	}
+	return 1;
+}
+
+static void
+assemble_jump_offsets(struct assembler *a, struct compiler *c)
+{
+	basicblock *b;
+	int bsize, totsize, extended_arg_count, last_extended_arg_count = 0;
+	int i;
+
+	/* Compute the size of each block and fixup jump args.
+	   Replace block pointer with position in bytecode. */
+start:
+	totsize = 0;
+	for (i = a->a_nblocks - 1; i >= 0; i--) {
+		b = a->a_postorder[i];
+		bsize = blocksize(b);
+		b->b_offset = totsize;
+		totsize += bsize;
+	}
+	extended_arg_count = 0;
+	for (b = c->u->u_blocks; b != NULL; b = b->b_list) {
+		bsize = b->b_offset;
+		for (i = 0; i < b->b_iused; i++) {
+			struct instr *instr = &b->b_instr[i];
+			/* Relative jumps are computed relative to
+			   the instruction pointer after fetching
+			   the jump instruction.
+			*/
+			bsize += instrsize(instr);
+			if (instr->i_jabs)
+				instr->i_oparg = instr->i_target->b_offset;
+			else if (instr->i_jrel) {
+				int delta = instr->i_target->b_offset - bsize;
+				instr->i_oparg = delta;
+			}
+			else
+				continue;
+			if (instr->i_oparg > 0xffff)
+				extended_arg_count++;
+		}
+	}
+
+	/* XXX: This is an awful hack that could hurt performance, but
+		on the bright side it should work until we come up
+		with a better solution.
+
+		In the meantime, should the goto be dropped in favor
+		of a loop?
+
+		The issue is that in the first loop blocksize() is called
+		which calls instrsize() which requires i_oparg be set
+		appropriately.	There is a bootstrap problem because
+		i_oparg is calculated in the second loop above.
+
+		So we loop until we stop seeing new EXTENDED_ARGs.
+		The only EXTENDED_ARGs that could be popping up are
+		ones in jump instructions.  So this should converge
+		fairly quickly.
+	*/
+	if (last_extended_arg_count != extended_arg_count) {
+		last_extended_arg_count = extended_arg_count;
+		goto start;
+	}
+}
+
+static PyObject *
+dict_keys_inorder(PyObject *dict, int offset)
+{
+	PyObject *tuple, *k, *v;
+	Py_ssize_t i, pos = 0, size = PyDict_Size(dict);
+
+	tuple = PyTuple_New(size);
+	if (tuple == NULL)
+		return NULL;
+	while (PyDict_Next(dict, &pos, &k, &v)) {
+		i = PyInt_AS_LONG(v);
+		k = PyTuple_GET_ITEM(k, 0);
+		Py_INCREF(k);
+		assert((i - offset) < size);
+		assert((i - offset) >= 0);
+		PyTuple_SET_ITEM(tuple, i - offset, k);
+	}
+	return tuple;
+}
+
+static int
+compute_code_flags(struct compiler *c)
+{
+	PySTEntryObject *ste = c->u->u_ste;
+	int flags = 0, n;
+	if (ste->ste_type != ModuleBlock)
+		flags |= CO_NEWLOCALS;
+	if (ste->ste_type == FunctionBlock) {
+		if (!ste->ste_unoptimized)
+			flags |= CO_OPTIMIZED;
+		if (ste->ste_nested)
+			flags |= CO_NESTED;
+		if (ste->ste_generator)
+			flags |= CO_GENERATOR;
+	}
+	if (ste->ste_varargs)
+		flags |= CO_VARARGS;
+	if (ste->ste_varkeywords)
+		flags |= CO_VARKEYWORDS;
+	if (ste->ste_generator)
+		flags |= CO_GENERATOR;
+
+	/* (Only) inherit compilerflags in PyCF_MASK */
+	flags |= (c->c_flags->cf_flags & PyCF_MASK);
+
+	n = PyDict_Size(c->u->u_freevars);
+	if (n < 0)
+	    return -1;
+	if (n == 0) {
+	    n = PyDict_Size(c->u->u_cellvars);
+	    if (n < 0)
+		return -1;
+	    if (n == 0) {
+		flags |= CO_NOFREE;
+	    }
+	}
+
+	return flags;
+}
+
+static PyCodeObject *
+makecode(struct compiler *c, struct assembler *a)
+{
+	PyObject *tmp;
+	PyCodeObject *co = NULL;
+	PyObject *consts = NULL;
+	PyObject *names = NULL;
+	PyObject *varnames = NULL;
+	PyObject *filename = NULL;
+	PyObject *name = NULL;
+	PyObject *freevars = NULL;
+	PyObject *cellvars = NULL;
+	PyObject *bytecode = NULL;
+	int nlocals, flags;
+
+	tmp = dict_keys_inorder(c->u->u_consts, 0);
+	if (!tmp)
+		goto error;
+	consts = PySequence_List(tmp); /* optimize_code requires a list */
+	Py_DECREF(tmp);
+
+	names = dict_keys_inorder(c->u->u_names, 0);
+	varnames = dict_keys_inorder(c->u->u_varnames, 0);
+	if (!consts || !names || !varnames)
+		goto error;
+      
+	cellvars = dict_keys_inorder(c->u->u_cellvars, 0);
+	if (!cellvars)
+	    goto error;
+	freevars = dict_keys_inorder(c->u->u_freevars, PyTuple_Size(cellvars));
+	if (!freevars)
+	    goto error;
+	filename = PyString_FromString(c->c_filename);
+	if (!filename)
+		goto error;
+
+	nlocals = PyDict_Size(c->u->u_varnames);
+	flags = compute_code_flags(c);
+	if (flags < 0)
+		goto error;
+
+	bytecode = optimize_code(a->a_bytecode, consts, names, a->a_lnotab);
+	if (!bytecode)
+		goto error;
+
+	tmp = PyList_AsTuple(consts); /* PyCode_New requires a tuple */
+	if (!tmp)
+		goto error;
+	Py_DECREF(consts);
+	consts = tmp;
+
+	co = PyCode_New(c->u->u_argcount, nlocals, stackdepth(c), flags,
+			bytecode, consts, names, varnames,
+			freevars, cellvars,
+			filename, c->u->u_name,
+			c->u->u_firstlineno,
+			a->a_lnotab);
+ error:
+	Py_XDECREF(consts);
+	Py_XDECREF(names);
+	Py_XDECREF(varnames);
+	Py_XDECREF(filename);
+	Py_XDECREF(name);
+	Py_XDECREF(freevars);
+	Py_XDECREF(cellvars);
+	Py_XDECREF(bytecode);
+	return co;
+}
+
+
+/* For debugging purposes only */
+#if 0
+static void
+dump_instr(const struct instr *i)
+{
+	const char *jrel = i->i_jrel ? "jrel " : "";
+	const char *jabs = i->i_jabs ? "jabs " : "";
+	char arg[128];
+
+	*arg = '\0';
+	if (i->i_hasarg)
+		sprintf(arg, "arg: %d ", i->i_oparg);
+
+	fprintf(stderr, "line: %d, opcode: %d %s%s%s\n", 
+			i->i_lineno, i->i_opcode, arg, jabs, jrel);
+}
+
+static void
+dump_basicblock(const basicblock *b)
+{
+	const char *seen = b->b_seen ? "seen " : "";
+	const char *b_return = b->b_return ? "return " : "";
+	fprintf(stderr, "used: %d, depth: %d, offset: %d %s%s\n",
+		b->b_iused, b->b_startdepth, b->b_offset, seen, b_return);
+	if (b->b_instr) {
+		int i;
+		for (i = 0; i < b->b_iused; i++) {
+			fprintf(stderr, "  [%02d] ", i);
+			dump_instr(b->b_instr + i);
+		}
+	}
+}
+#endif
+
+static PyCodeObject *
+assemble(struct compiler *c, int addNone)
+{
+	basicblock *b, *entryblock;
+	struct assembler a;
+	int i, j, nblocks;
+	PyCodeObject *co = NULL;
+
+	/* Make sure every block that falls off the end returns None.
+	   XXX NEXT_BLOCK() isn't quite right, because if the last
+	   block ends with a jump or return b_next shouldn't set.
+	 */
+	if (!c->u->u_curblock->b_return) {
+		NEXT_BLOCK(c);
+		if (addNone)
+			ADDOP_O(c, LOAD_CONST, Py_None, consts);
+		ADDOP(c, RETURN_VALUE);
+	}
+
+	nblocks = 0;
+	entryblock = NULL;
+	for (b = c->u->u_blocks; b != NULL; b = b->b_list) {
+		nblocks++;
+		entryblock = b; 
+	}
+
+	/* Set firstlineno if it wasn't explicitly set. */
+	if (!c->u->u_firstlineno) {
+		if (entryblock && entryblock->b_instr)
+			c->u->u_firstlineno = entryblock->b_instr->i_lineno;
+		else
+			c->u->u_firstlineno = 1;
+	}
+	if (!assemble_init(&a, nblocks, c->u->u_firstlineno))
+		goto error;
+	dfs(c, entryblock, &a);
+
+	/* Can't modify the bytecode after computing jump offsets. */
+	assemble_jump_offsets(&a, c);
+
+	/* Emit code in reverse postorder from dfs. */
+	for (i = a.a_nblocks - 1; i >= 0; i--) {
+		b = a.a_postorder[i];
+		for (j = 0; j < b->b_iused; j++)
+			if (!assemble_emit(&a, &b->b_instr[j]))
+				goto error;
+	}
+
+	if (_PyString_Resize(&a.a_lnotab, a.a_lnotab_off) < 0)
+		goto error;
+	if (_PyString_Resize(&a.a_bytecode, a.a_offset) < 0)
+		goto error;
+
+	co = makecode(c, &a);
+ error:
+	assemble_free(&a);
+	return co;
+}

Added: vendor/Python/current/Python/dup2.c
===================================================================
--- vendor/Python/current/Python/dup2.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/dup2.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,30 @@
+/*
+ * Public domain dup2() lookalike
+ * by Curtis Jackson @ AT&T Technologies, Burlington, NC
+ * electronic address:  burl!rcj
+ *
+ * dup2 performs the following functions:
+ *
+ * Check to make sure that fd1 is a valid open file descriptor.
+ * Check to see if fd2 is already open; if so, close it.
+ * Duplicate fd1 onto fd2; checking to make sure fd2 is a valid fd.
+ * Return fd2 if all went well; return BADEXIT otherwise.
+ */
+
+#include <fcntl.h>
+
+#define BADEXIT -1
+
+int
+dup2(int fd1, int fd2)
+{
+	if (fd1 != fd2) {
+		if (fcntl(fd1, F_GETFL) < 0)
+			return BADEXIT;
+		if (fcntl(fd2, F_GETFL) >= 0)
+			close(fd2);
+		if (fcntl(fd1, F_DUPFD, fd2) < 0)
+			return BADEXIT;
+	}
+	return fd2;
+}

Added: vendor/Python/current/Python/dynload_aix.c
===================================================================
--- vendor/Python/current/Python/dynload_aix.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/dynload_aix.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,183 @@
+
+/* Support for dynamic loading of extension modules */
+
+#include "Python.h"
+#include "importdl.h"
+
+#include <ctype.h>	/*  for isdigit()	  */
+#include <errno.h>	/*  for global errno      */
+#include <string.h>	/*  for strerror()        */
+#include <stdlib.h>	/*  for malloc(), free()  */
+#include <sys/ldr.h>
+
+
+#ifdef AIX_GENUINE_CPLUSPLUS
+#include "/usr/lpp/xlC/include/load.h"
+#define aix_load loadAndInit
+#else
+#define aix_load load
+#endif
+
+
+extern char *Py_GetProgramName(void);
+
+typedef struct Module {
+	struct Module *next;
+	void          *entry;
+} Module, *ModulePtr;
+
+const struct filedescr _PyImport_DynLoadFiletab[] = {
+	{".so", "rb", C_EXTENSION},
+	{"module.so", "rb", C_EXTENSION},
+	{0, 0}
+};
+
+static int
+aix_getoldmodules(void **modlistptr)
+{
+	register ModulePtr       modptr, prevmodptr;
+	register struct ld_info  *ldiptr;
+	register char            *ldibuf;
+	register int             errflag, bufsize = 1024;
+	register unsigned int    offset;
+	char *progname = Py_GetProgramName();
+	
+	/*
+	-- Get the list of loaded modules into ld_info structures.
+	*/
+	if ((ldibuf = malloc(bufsize)) == NULL) {
+		PyErr_SetString(PyExc_ImportError, strerror(errno));
+		return -1;
+	}
+	while ((errflag = loadquery(L_GETINFO, ldibuf, bufsize)) == -1
+	       && errno == ENOMEM) {
+		free(ldibuf);
+		bufsize += 1024;
+		if ((ldibuf = malloc(bufsize)) == NULL) {
+			PyErr_SetString(PyExc_ImportError, strerror(errno));
+			return -1;
+		}
+	}
+	if (errflag == -1) {
+		PyErr_SetString(PyExc_ImportError, strerror(errno));
+		return -1;
+	}
+	/*
+	-- Make the modules list from the ld_info structures.
+	*/
+	ldiptr = (struct ld_info *)ldibuf;
+	prevmodptr = NULL;
+	do {
+		if (strstr(progname, ldiptr->ldinfo_filename) == NULL &&
+		    strstr(ldiptr->ldinfo_filename, "python") == NULL) {
+			/*
+			-- Extract only the modules belonging to the main
+			-- executable + those containing "python" as a
+			-- substring (like the "python[version]" binary or
+			-- "libpython[version].a" in case it's a shared lib).
+			*/
+			offset = (unsigned int)ldiptr->ldinfo_next;
+			ldiptr = (struct ld_info *)((char*)ldiptr + offset);
+			continue;
+		}
+		if ((modptr = (ModulePtr)malloc(sizeof(Module))) == NULL) {
+			PyErr_SetString(PyExc_ImportError, strerror(errno));
+			while (*modlistptr) {
+				modptr = (ModulePtr)*modlistptr;
+				*modlistptr = (void *)modptr->next;
+				free(modptr);
+			}
+			return -1;
+		}
+		modptr->entry = ldiptr->ldinfo_dataorg;
+		modptr->next  = NULL;
+		if (prevmodptr == NULL)
+			*modlistptr = (void *)modptr;
+		else
+			prevmodptr->next = modptr;
+		prevmodptr = modptr;
+		offset = (unsigned int)ldiptr->ldinfo_next;
+		ldiptr = (struct ld_info *)((char*)ldiptr + offset);
+	} while (offset);
+	free(ldibuf);
+	return 0;
+}
+
+
+static void
+aix_loaderror(const char *pathname)
+{
+
+	char *message[1024], errbuf[1024];
+	register int i,j;
+
+	struct errtab { 
+		int errNo;
+		char *errstr;
+	} load_errtab[] = {
+		{L_ERROR_TOOMANY,	"too many errors, rest skipped."},
+		{L_ERROR_NOLIB,		"can't load library:"},
+		{L_ERROR_UNDEF,		"can't find symbol in library:"},
+		{L_ERROR_RLDBAD,
+		 "RLD index out of range or bad relocation type:"},
+		{L_ERROR_FORMAT,	"not a valid, executable xcoff file:"},
+		{L_ERROR_MEMBER,
+		 "file not an archive or does not contain requested member:"},
+		{L_ERROR_TYPE,		"symbol table mismatch:"},
+		{L_ERROR_ALIGN,		"text alignment in file is wrong."},
+		{L_ERROR_SYSTEM,	"System error:"},
+		{L_ERROR_ERRNO,		NULL}
+	};
+
+#define LOAD_ERRTAB_LEN	(sizeof(load_errtab)/sizeof(load_errtab[0]))
+#define ERRBUF_APPEND(s) strncat(errbuf, s, sizeof(errbuf)-strlen(errbuf)-1)
+
+	PyOS_snprintf(errbuf, sizeof(errbuf), "from module %.200s ", pathname);
+
+	if (!loadquery(L_GETMESSAGES, &message[0], sizeof(message))) {
+		ERRBUF_APPEND(strerror(errno));
+		ERRBUF_APPEND("\n");
+	}
+	for(i = 0; message[i] && *message[i]; i++) {
+		int nerr = atoi(message[i]);
+		for (j=0; j<LOAD_ERRTAB_LEN ; j++) {
+		    if (nerr == load_errtab[j].errNo && load_errtab[j].errstr)
+			ERRBUF_APPEND(load_errtab[j].errstr);
+		}
+		while (isdigit(Py_CHARMASK(*message[i]))) message[i]++ ; 
+		ERRBUF_APPEND(message[i]);
+		ERRBUF_APPEND("\n");
+	}
+	errbuf[strlen(errbuf)-1] = '\0';	/* trim off last newline */
+	PyErr_SetString(PyExc_ImportError, errbuf); 
+	return; 
+}
+
+
+dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
+				    const char *pathname, FILE *fp)
+{
+	dl_funcptr p;
+
+	/*
+	-- Invoke load() with L_NOAUTODEFER leaving the imported symbols
+	-- of the shared module unresolved. Thus we have to resolve them
+	-- explicitly with loadbind. The new module is loaded, then we
+	-- resolve its symbols using the list of already loaded modules
+	-- (only those that belong to the python executable). Get these
+	-- with loadquery(L_GETINFO).
+	*/
+
+	static void *staticmodlistptr = NULL;
+
+	if (!staticmodlistptr)
+		if (aix_getoldmodules(&staticmodlistptr) == -1)
+			return NULL;
+	p = (dl_funcptr) aix_load((char *)pathname, L_NOAUTODEFER, 0);
+	if (p == NULL) {
+		aix_loaderror(pathname);
+		return NULL;
+	}
+
+	return p;
+}

Added: vendor/Python/current/Python/dynload_atheos.c
===================================================================
--- vendor/Python/current/Python/dynload_atheos.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/dynload_atheos.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,47 @@
+
+/* Support for dynamic loading of extension modules */
+
+#include <atheos/image.h>
+#include <errno.h>
+
+#include "Python.h"
+#include "importdl.h"
+
+
+const struct filedescr _PyImport_DynLoadFiletab[] = {
+	{".so", "rb", C_EXTENSION},
+	{"module.so", "rb", C_EXTENSION},
+	{0, 0}
+};
+
+dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
+				    const char *pathname, FILE *fp)
+{
+	void *p;
+	int lib;
+	char funcname[258];
+
+	if (Py_VerboseFlag)
+		printf("load_library %s\n", pathname);
+
+	lib = load_library(pathname, 0);
+	if (lib < 0) {
+		char buf[512];
+		if (Py_VerboseFlag)
+			perror(pathname);
+		PyOS_snprintf(buf, sizeof(buf), "Failed to load %.200s: %.200s",
+			      pathname, strerror(errno));
+		PyErr_SetString(PyExc_ImportError, buf);
+		return NULL;
+	}
+	PyOS_snprintf(funcname, sizeof(funcname), "init%.200s", shortname);
+	if (Py_VerboseFlag)
+		printf("get_symbol_address %s\n", funcname);
+	if (get_symbol_address(lib, funcname, -1, &p) < 0) {
+		p = NULL;
+		if (Py_VerboseFlag)
+			perror(funcname);
+	}
+
+	return (dl_funcptr) p;
+}

Added: vendor/Python/current/Python/dynload_beos.c
===================================================================
--- vendor/Python/current/Python/dynload_beos.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/dynload_beos.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,254 @@
+
+/* Support for dynamic loading of extension modules */
+
+#include <kernel/image.h>
+#include <kernel/OS.h>
+#include <stdlib.h>
+
+#include "Python.h"
+#include "importdl.h"
+
+const struct filedescr _PyImport_DynLoadFiletab[] = {
+	{".so", "rb", C_EXTENSION},
+	{"module.so", "rb", C_EXTENSION},
+	{0, 0}
+};
+
+#if defined(MAXPATHLEN) && !defined(_SYS_PARAM_H)
+#undef MAXPATHLEN
+#endif
+
+#ifdef WITH_THREAD
+#include "pythread.h"
+static PyThread_type_lock beos_dyn_lock;
+#endif
+
+static PyObject *beos_dyn_images = NULL;
+
+/* ----------------------------------------------------------------------
+ * BeOS dynamic loading support
+ *
+ * This uses shared libraries, but BeOS has its own way of doing things
+ * (much easier than dlfnc.h, from the look of things).  We'll use a
+ * Python Dictionary object to store the images_ids so we can be very
+ * nice and unload them when we exit.
+ *
+ * Note that this is thread-safe.  Probably irrelevent, because of losing
+ * systems... Python probably disables threads while loading modules.
+ * Note the use of "probably"!  Better to be safe than sorry. [chrish]
+ *
+ * As of 1.5.1 this should also work properly when you've configured
+ * Python without thread support; the 1.5 version required it, which wasn't
+ * very friendly.  Note that I haven't tested it without threading... why
+ * would you want to avoid threads on BeOS? [chrish]
+ *
+ * As of 1.5.2, the PyImport_BeImageID() function has been removed; Donn
+ * tells me it's not necessary anymore because of PyCObject_Import().
+ * [chrish]
+ */
+
+/* Whack an item; the item is an image_id in disguise, so we'll call
+ * unload_add_on() for it.
+ */
+static void beos_nuke_dyn( PyObject *item )
+{
+	status_t retval;
+
+	if( item ) {
+		image_id id = (image_id)PyInt_AsLong( item );
+		
+		retval = unload_add_on( id );
+	}
+}
+
+/* atexit() handler that'll call unload_add_on() for every item in the
+ * dictionary.
+ */
+static void beos_cleanup_dyn( void )
+{
+	if( beos_dyn_images ) {
+		int idx;
+		int list_size;
+		PyObject *id_list;
+
+#ifdef WITH_THREAD
+		PyThread_acquire_lock( beos_dyn_lock, 1 );
+#endif
+
+		id_list = PyDict_Values( beos_dyn_images );
+
+		list_size = PyList_Size( id_list );
+		for( idx = 0; idx < list_size; idx++ ) {
+			PyObject *the_item;
+			
+			the_item = PyList_GetItem( id_list, idx );
+			beos_nuke_dyn( the_item );
+		}
+
+		PyDict_Clear( beos_dyn_images );
+
+#ifdef WITH_THREAD
+		PyThread_free_lock( beos_dyn_lock );
+#endif
+	}
+}
+
+/*
+ * Initialize our dictionary, and the dictionary mutex.
+ */
+static void beos_init_dyn( void )
+{
+	/* We're protected from a race condition here by the atomic init_count
+	 * variable.
+	 */
+	static int32 init_count = 0;
+	int32 val;
+
+	val = atomic_add( &init_count, 1 );
+	if( beos_dyn_images == NULL && val == 0 ) {
+		beos_dyn_images = PyDict_New();
+#ifdef WITH_THREAD
+		beos_dyn_lock = PyThread_allocate_lock();
+#endif
+		atexit( beos_cleanup_dyn );
+	}
+}
+
+/*
+ * Add an image_id to the dictionary; the module name of the loaded image
+ * is the key.  Note that if the key is already in the dict, we unload
+ * that image; this should allow reload() to work on dynamically loaded
+ * modules (super-keen!).
+ */
+static void beos_add_dyn( char *name, image_id id )
+{
+	int retval;
+	PyObject *py_id;
+
+	if( beos_dyn_images == NULL ) {
+		beos_init_dyn();
+	}
+
+#ifdef WITH_THREAD
+	retval = PyThread_acquire_lock( beos_dyn_lock, 1 );
+#endif
+
+	/* If there's already an object with this key in the dictionary,
+	 * we're doing a reload(), so let's nuke it.
+	 */
+	py_id = PyDict_GetItemString( beos_dyn_images, name );
+	if( py_id ) {
+		beos_nuke_dyn( py_id );
+		retval = PyDict_DelItemString( beos_dyn_images, name );
+	}
+
+	py_id = PyInt_FromLong( (long)id );
+	if( py_id ) {
+		retval = PyDict_SetItemString( beos_dyn_images, name, py_id );
+	}
+
+#ifdef WITH_THREAD
+	PyThread_release_lock( beos_dyn_lock );
+#endif
+}
+
+
+
+dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
+				    const char *pathname, FILE *fp)
+{
+	dl_funcptr p;
+	image_id the_id;
+	status_t retval;
+	char fullpath[PATH_MAX];
+	char funcname[258];
+
+	if( Py_VerboseFlag ) {
+		printf( "load_add_on( %s )\n", pathname );
+	}
+
+	/* Hmm, this old bug appears to have regenerated itself; if the
+	 * path isn't absolute, load_add_on() will fail.  Reported to Be
+	 * April 21, 1998.
+	 */
+	if( pathname[0] != '/' ) {
+		(void)getcwd( fullpath, PATH_MAX );
+		(void)strncat( fullpath, "/", PATH_MAX );
+		(void)strncat( fullpath, pathname, PATH_MAX );
+			
+		if( Py_VerboseFlag ) {
+			printf( "load_add_on( %s )\n", fullpath );
+		}
+	} else {
+		(void)strcpy( fullpath, pathname );
+	}
+
+	the_id = load_add_on( fullpath );
+	if( the_id < B_NO_ERROR ) {
+		/* It's too bad load_add_on() doesn't set errno or something...
+		 */
+		char buff[256];  /* hate hard-coded string sizes... */
+
+		if( Py_VerboseFlag ) {
+			printf( "load_add_on( %s ) failed", fullpath );
+		}
+
+		if( the_id == B_ERROR )
+			PyOS_snprintf( buff, sizeof(buff),
+				       "BeOS: Failed to load %.200s",
+				       fullpath );
+		else
+			PyOS_snprintf( buff, sizeof(buff), 
+				       "Unknown error loading %.200s", 
+				       fullpath );
+
+		PyErr_SetString( PyExc_ImportError, buff );
+		return NULL;
+	}
+
+	PyOS_snprintf(funcname, sizeof(funcname), "init%.200s", shortname);
+	if( Py_VerboseFlag ) {
+		printf( "get_image_symbol( %s )\n", funcname );
+	}
+
+	retval = get_image_symbol( the_id, funcname, B_SYMBOL_TYPE_TEXT, &p );
+	if( retval != B_NO_ERROR || p == NULL ) {
+		/* That's bad, we can't find that symbol in the module...
+		 */
+		char buff[256];  /* hate hard-coded string sizes... */
+
+		if( Py_VerboseFlag ) {
+			printf( "get_image_symbol( %s ) failed", funcname );
+		}
+
+		switch( retval ) {
+		case B_BAD_IMAGE_ID:
+			PyOS_snprintf( buff, sizeof(buff),
+			       "can't load init function for dynamic module: "
+		               "Invalid image ID for %.180s", fullpath );
+			break;
+		case B_BAD_INDEX:
+			PyOS_snprintf( buff, sizeof(buff),
+			       "can't load init function for dynamic module: "
+		               "Bad index for %.180s", funcname );
+			break;
+		default:
+			PyOS_snprintf( buff, sizeof(buff),
+			       "can't load init function for dynamic module: "
+		               "Unknown error looking up %.180s", funcname );
+			break;
+		}
+
+		retval = unload_add_on( the_id );
+
+		PyErr_SetString( PyExc_ImportError, buff );
+		return NULL;
+	}
+
+	/* Save the module name and image ID for later so we can clean up
+	 * gracefully.
+	 */
+	beos_add_dyn( fqname, the_id );
+
+	return p;
+}

Added: vendor/Python/current/Python/dynload_dl.c
===================================================================
--- vendor/Python/current/Python/dynload_dl.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/dynload_dl.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,26 @@
+
+/* Support for dynamic loading of extension modules */
+
+#include "dl.h"
+
+#include "Python.h"
+#include "importdl.h"
+
+
+extern char *Py_GetProgramName(void);
+
+const struct filedescr _PyImport_DynLoadFiletab[] = {
+	{".o", "rb", C_EXTENSION},
+	{"module.o", "rb", C_EXTENSION},
+	{0, 0}
+};
+
+
+dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
+				    const char *pathname, FILE *fp)
+{
+	char funcname[258];
+
+	PyOS_snprintf(funcname, sizeof(funcname), "init%.200s", shortname);
+	return dl_loadmod(Py_GetProgramName(), pathname, funcname);
+}

Added: vendor/Python/current/Python/dynload_hpux.c
===================================================================
--- vendor/Python/current/Python/dynload_hpux.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/dynload_hpux.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,58 @@
+
+/* Support for dynamic loading of extension modules */
+
+#include "dl.h"
+#include <errno.h>
+
+#include "Python.h"
+#include "importdl.h"
+
+#if defined(__hp9000s300)
+#define FUNCNAME_PATTERN "_init%.200s"
+#else
+#define FUNCNAME_PATTERN "init%.200s"
+#endif
+
+const struct filedescr _PyImport_DynLoadFiletab[] = {
+	{SHLIB_EXT, "rb", C_EXTENSION},
+	{"module"SHLIB_EXT, "rb", C_EXTENSION},
+	{0, 0}
+};
+
+dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
+				    const char *pathname, FILE *fp)
+{
+	dl_funcptr p;
+	shl_t lib;
+	int flags;
+	char funcname[258];
+
+	flags = BIND_FIRST | BIND_DEFERRED;
+	if (Py_VerboseFlag) {
+		flags = BIND_FIRST | BIND_IMMEDIATE |
+			BIND_NONFATAL | BIND_VERBOSE;
+		printf("shl_load %s\n",pathname);
+	}
+	lib = shl_load(pathname, flags, 0);
+	/* XXX Chuck Blake once wrote that 0 should be BIND_NOSTART? */
+	if (lib == NULL) {
+		char buf[256];
+		if (Py_VerboseFlag)
+			perror(pathname);
+		PyOS_snprintf(buf, sizeof(buf), "Failed to load %.200s",
+			      pathname);
+		PyErr_SetString(PyExc_ImportError, buf);
+		return NULL;
+	}
+	PyOS_snprintf(funcname, sizeof(funcname), FUNCNAME_PATTERN, shortname);
+	if (Py_VerboseFlag)
+		printf("shl_findsym %s\n", funcname);
+	if (shl_findsym(&lib, funcname, TYPE_UNDEFINED, (void *) &p) == -1) {
+		shl_unload(lib);
+		p = NULL;
+	}
+	if (p == NULL && Py_VerboseFlag)
+		perror(funcname);
+
+	return p;
+}

Added: vendor/Python/current/Python/dynload_next.c
===================================================================
--- vendor/Python/current/Python/dynload_next.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/dynload_next.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,114 @@
+
+/* Support for dynamic loading of extension modules on Mac OS X
+** All references to "NeXT" are for historical reasons.
+*/
+
+#include "Python.h"
+#include "importdl.h"
+
+#include <mach-o/dyld.h>
+
+const struct filedescr _PyImport_DynLoadFiletab[] = {
+	{".so", "rb", C_EXTENSION},
+	{"module.so", "rb", C_EXTENSION},
+	{0, 0}
+};
+
+/*
+** Python modules are Mach-O MH_BUNDLE files. The best way to load these
+** is each in a private namespace, so you can load, say, a module bar and a
+** module foo.bar. If we load everything in the global namespace the two
+** initbar() symbols will conflict.
+** However, it seems some extension packages depend upon being able to access
+** each others' global symbols. There seems to be no way to eat our cake and
+** have it, so the USE_DYLD_GLOBAL_NAMESPACE define determines which behaviour
+** you get.
+*/
+
+#ifdef USE_DYLD_GLOBAL_NAMESPACE
+#define LINKOPTIONS NSLINKMODULE_OPTION_BINDNOW|NSLINKMODULE_OPTION_RETURN_ON_ERROR
+#else
+#define LINKOPTIONS NSLINKMODULE_OPTION_BINDNOW| \
+	NSLINKMODULE_OPTION_RETURN_ON_ERROR|NSLINKMODULE_OPTION_PRIVATE
+#endif
+dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
+					const char *pathname, FILE *fp)
+{
+	dl_funcptr p = NULL;
+	char funcname[258];
+	NSObjectFileImageReturnCode rc;
+	NSObjectFileImage image;
+	NSModule newModule;
+	NSSymbol theSym;
+	const char *errString;
+	char errBuf[512];
+
+	PyOS_snprintf(funcname, sizeof(funcname), "_init%.200s", shortname);
+
+#ifdef USE_DYLD_GLOBAL_NAMESPACE
+	if (NSIsSymbolNameDefined(funcname)) {
+		theSym = NSLookupAndBindSymbol(funcname);
+		p = (dl_funcptr)NSAddressOfSymbol(theSym);
+		return p;
+	}
+#endif
+	rc = NSCreateObjectFileImageFromFile(pathname, &image);
+	switch(rc) {
+		default:
+		case NSObjectFileImageFailure:
+		case NSObjectFileImageFormat:
+			/* for these a message is printed on stderr by dyld */
+			errString = "Can't create object file image";
+		break;
+		case NSObjectFileImageSuccess:
+			errString = NULL;
+			break;
+		case NSObjectFileImageInappropriateFile:
+			errString = "Inappropriate file type for dynamic loading";
+			break;
+		case NSObjectFileImageArch:
+			errString = "Wrong CPU type in object file";
+			break;
+		case NSObjectFileImageAccess:
+			errString = "Can't read object file (no access)";
+			break;
+	}
+	if (errString == NULL) {
+		newModule = NSLinkModule(image, pathname, LINKOPTIONS);
+		if (newModule == NULL) {
+			int errNo;
+			const char *fileName, *moreErrorStr;
+			NSLinkEditErrors c;
+			NSLinkEditError( &c, &errNo, &fileName, &moreErrorStr );
+			PyOS_snprintf(errBuf, 512, "Failure linking new module: %s: %s", 
+					fileName, moreErrorStr);
+			errString = errBuf;
+		}
+	}
+	if (errString != NULL) {
+		PyErr_SetString(PyExc_ImportError, errString);
+		return NULL;
+	}
+#ifdef USE_DYLD_GLOBAL_NAMESPACE
+	if (!NSIsSymbolNameDefined(funcname)) {
+		/* UnlinkModule() isn't implemented in current versions, but calling it does no harm */
+		/* NSUnLinkModule(newModule, FALSE); removed: causes problems for ObjC code */
+		PyErr_Format(PyExc_ImportError,
+				 "Loaded module does not contain symbol %.200s",
+				 funcname);
+		return NULL;
+	}
+	theSym = NSLookupAndBindSymbol(funcname);
+#else
+	theSym = NSLookupSymbolInModule(newModule, funcname);
+	if ( theSym == NULL ) {
+		/* NSUnLinkModule(newModule, FALSE); removed: causes problems for ObjC code */
+		PyErr_Format(PyExc_ImportError,
+				 "Loaded module does not contain symbol %.200s",
+				 funcname);
+		return NULL;
+	}
+#endif
+	p = (dl_funcptr)NSAddressOfSymbol(theSym);
+	return p;
+}

Added: vendor/Python/current/Python/dynload_os2.c
===================================================================
--- vendor/Python/current/Python/dynload_os2.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/dynload_os2.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,46 @@
+
+/* Support for dynamic loading of extension modules */
+
+#define  INCL_DOSERRORS
+#define  INCL_DOSMODULEMGR
+#include <os2.h>
+
+#include "Python.h"
+#include "importdl.h"
+
+
+const struct filedescr _PyImport_DynLoadFiletab[] = {
+	{".pyd", "rb", C_EXTENSION},
+	{".dll", "rb", C_EXTENSION},
+	{0, 0}
+};
+
+dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
+				    const char *pathname, FILE *fp)
+{
+	dl_funcptr p;
+	APIRET  rc;
+	HMODULE hDLL;
+	char failreason[256];
+	char funcname[258];
+
+	rc = DosLoadModule(failreason,
+			   sizeof(failreason),
+			   pathname,
+			   &hDLL);
+
+	if (rc != NO_ERROR) {
+		char errBuf[256];
+		PyOS_snprintf(errBuf, sizeof(errBuf),
+			      "DLL load failed, rc = %d: %.200s",
+			      rc, failreason);
+		PyErr_SetString(PyExc_ImportError, errBuf);
+		return NULL;
+	}
+
+	PyOS_snprintf(funcname, sizeof(funcname), "init%.200s", shortname);
+	rc = DosQueryProcAddr(hDLL, 0L, funcname, &p);
+	if (rc != NO_ERROR)
+		p = NULL; /* Signify Failure to Acquire Entrypoint */
+	return p;
+}

Added: vendor/Python/current/Python/dynload_shlib.c
===================================================================
--- vendor/Python/current/Python/dynload_shlib.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/dynload_shlib.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,143 @@
+
+/* Support for dynamic loading of extension modules */
+
+#include "Python.h"
+#include "importdl.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#if defined(__NetBSD__)
+#include <sys/param.h>
+#if (NetBSD < 199712)
+#include <nlist.h>
+#include <link.h>
+#define dlerror() "error in dynamic linking"
+#endif
+#endif /* NetBSD */
+
+#ifdef HAVE_DLFCN_H
+#include <dlfcn.h>
+#else
+#if defined(PYOS_OS2) && defined(PYCC_GCC)
+#include "dlfcn.h"
+#endif
+#endif
+
+#if (defined(__OpenBSD__) || defined(__NetBSD__)) && !defined(__ELF__)
+#define LEAD_UNDERSCORE "_"
+#else
+#define LEAD_UNDERSCORE ""
+#endif
+
+
+const struct filedescr _PyImport_DynLoadFiletab[] = {
+#ifdef __CYGWIN__
+	{".dll", "rb", C_EXTENSION},
+	{"module.dll", "rb", C_EXTENSION},
+#else
+#if defined(PYOS_OS2) && defined(PYCC_GCC)
+	{".pyd", "rb", C_EXTENSION},
+	{".dll", "rb", C_EXTENSION},
+#else
+#ifdef __VMS
+        {".exe", "rb", C_EXTENSION},
+        {".EXE", "rb", C_EXTENSION},
+        {"module.exe", "rb", C_EXTENSION},
+        {"MODULE.EXE", "rb", C_EXTENSION},
+#else
+	{".so", "rb", C_EXTENSION},
+	{"module.so", "rb", C_EXTENSION},
+#endif
+#endif
+#endif
+	{0, 0}
+};
+
+static struct {
+	dev_t dev;
+#ifdef __VMS
+	ino_t ino[3];
+#else
+	ino_t ino;
+#endif
+	void *handle;
+} handles[128];
+static int nhandles = 0;
+
+
+dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
+				    const char *pathname, FILE *fp)
+{
+	dl_funcptr p;
+	void *handle;
+	char funcname[258];
+	char pathbuf[260];
+        int dlopenflags=0;
+
+	if (strchr(pathname, '/') == NULL) {
+		/* Prefix bare filename with "./" */
+		PyOS_snprintf(pathbuf, sizeof(pathbuf), "./%-.255s", pathname);
+		pathname = pathbuf;
+	}
+
+	PyOS_snprintf(funcname, sizeof(funcname), 
+		      LEAD_UNDERSCORE "init%.200s", shortname);
+
+	if (fp != NULL) {
+		int i;
+		struct stat statb;
+		fstat(fileno(fp), &statb);
+		for (i = 0; i < nhandles; i++) {
+			if (statb.st_dev == handles[i].dev &&
+			    statb.st_ino == handles[i].ino) {
+				p = (dl_funcptr) dlsym(handles[i].handle,
+						       funcname);
+				return p;
+			}
+		}
+		if (nhandles < 128) {
+			handles[nhandles].dev = statb.st_dev;
+#ifdef __VMS
+			handles[nhandles].ino[0] = statb.st_ino[0];
+			handles[nhandles].ino[1] = statb.st_ino[1];
+			handles[nhandles].ino[2] = statb.st_ino[2];
+#else
+			handles[nhandles].ino = statb.st_ino;
+#endif
+		}
+	}
+
+#if !(defined(PYOS_OS2) && defined(PYCC_GCC))
+        dlopenflags = PyThreadState_GET()->interp->dlopenflags;
+#endif
+
+	if (Py_VerboseFlag)
+		PySys_WriteStderr("dlopen(\"%s\", %x);\n", pathname, 
+				  dlopenflags);
+
+#ifdef __VMS
+	/* VMS currently don't allow a pathname, use a logical name instead */
+	/* Concatenate 'python_module_' and shortname */
+	/* so "import vms.bar" will use the logical python_module_bar */
+	/* As C module use only one name space this is probably not a */
+	/* important limitation */
+	PyOS_snprintf(pathbuf, sizeof(pathbuf), "python_module_%-.200s", 
+		      shortname);
+	pathname = pathbuf;
+#endif
+
+	handle = dlopen(pathname, dlopenflags);
+
+	if (handle == NULL) {
+		const char *error = dlerror();
+		if (error == NULL)
+			error = "unknown dlopen() error";
+		PyErr_SetString(PyExc_ImportError, error);
+		return NULL;
+	}
+	if (fp != NULL && nhandles < 128)
+		handles[nhandles++].handle = handle;
+	p = (dl_funcptr) dlsym(handle, funcname);
+	return p;
+}

Added: vendor/Python/current/Python/dynload_stub.c
===================================================================
--- vendor/Python/current/Python/dynload_stub.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/dynload_stub.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,11 @@
+
+/* This module provides the necessary stubs for when dynamic loading is
+   not present. */
+
+#include "Python.h"
+#include "importdl.h"
+
+
+const struct filedescr _PyImport_DynLoadFiletab[] = {
+	{0, 0}
+};

Added: vendor/Python/current/Python/dynload_win.c
===================================================================
--- vendor/Python/current/Python/dynload_win.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/dynload_win.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,263 @@
+
+/* Support for dynamic loading of extension modules */
+
+#include <windows.h>
+#ifdef HAVE_DIRECT_H
+#include <direct.h>
+#endif
+#include <ctype.h>
+
+#include "Python.h"
+#include "importdl.h"
+
+const struct filedescr _PyImport_DynLoadFiletab[] = {
+#ifdef _DEBUG
+	{"_d.pyd", "rb", C_EXTENSION},
+	/* Temporarily disable .dll, to avoid conflicts between sqlite3.dll
+	   and the sqlite3 package. If this needs to be reverted for 2.5,
+	   some other solution for the naming conflict must be found.
+	{"_d.dll", "rb", C_EXTENSION},
+	*/
+#else
+	{".pyd", "rb", C_EXTENSION},
+	/* Likewise
+	{".dll", "rb", C_EXTENSION},
+	*/
+#endif
+	{0, 0}
+};
+
+
+/* Case insensitive string compare, to avoid any dependencies on particular
+   C RTL implementations */
+
+static int strcasecmp (char *string1, char *string2)
+{ 
+	int first, second;
+
+	do {
+		first  = tolower(*string1);
+		second = tolower(*string2);
+		string1++;
+		string2++;
+	} while (first && first == second);
+
+	return (first - second);
+} 
+
+
+/* Function to return the name of the "python" DLL that the supplied module
+   directly imports.  Looks through the list of imported modules and
+   returns the first entry that starts with "python" (case sensitive) and
+   is followed by nothing but numbers until the separator (period).
+
+   Returns a pointer to the import name, or NULL if no matching name was
+   located.
+
+   This function parses through the PE header for the module as loaded in
+   memory by the system loader.  The PE header is accessed as documented by
+   Microsoft in the MSDN PE and COFF specification (2/99), and handles
+   both PE32 and PE32+.  It only worries about the direct import table and
+   not the delay load import table since it's unlikely an extension is
+   going to be delay loading Python (after all, it's already loaded).
+
+   If any magic values are not found (e.g., the PE header or optional
+   header magic), then this function simply returns NULL. */
+
+#define DWORD_AT(mem) (*(DWORD *)(mem))
+#define WORD_AT(mem)  (*(WORD *)(mem))
+
+static char *GetPythonImport (HINSTANCE hModule)
+{
+	unsigned char *dllbase, *import_data, *import_name;
+	DWORD pe_offset, opt_offset;
+	WORD opt_magic;
+	int num_dict_off, import_off;
+
+	/* Safety check input */
+	if (hModule == NULL) {
+		return NULL;
+	}
+
+	/* Module instance is also the base load address.  First portion of
+	   memory is the MS-DOS loader, which holds the offset to the PE
+	   header (from the load base) at 0x3C */
+	dllbase = (unsigned char *)hModule;
+	pe_offset = DWORD_AT(dllbase + 0x3C);
+
+	/* The PE signature must be "PE\0\0" */
+	if (memcmp(dllbase+pe_offset,"PE\0\0",4)) {
+		return NULL;
+	}
+
+	/* Following the PE signature is the standard COFF header (20
+	   bytes) and then the optional header.  The optional header starts
+	   with a magic value of 0x10B for PE32 or 0x20B for PE32+ (PE32+
+	   uses 64-bits for some fields).  It might also be 0x107 for a ROM
+	   image, but we don't process that here.
+
+	   The optional header ends with a data dictionary that directly
+	   points to certain types of data, among them the import entries
+	   (in the second table entry). Based on the header type, we
+	   determine offsets for the data dictionary count and the entry
+	   within the dictionary pointing to the imports. */
+
+	opt_offset = pe_offset + 4 + 20;
+	opt_magic = WORD_AT(dllbase+opt_offset);
+	if (opt_magic == 0x10B) {
+		/* PE32 */
+		num_dict_off = 92;
+		import_off   = 104;
+	} else if (opt_magic == 0x20B) {
+		/* PE32+ */
+		num_dict_off = 108;
+		import_off   = 120;
+	} else {
+		/* Unsupported */
+		return NULL;
+	}
+
+	/* Now if an import table exists, offset to it and walk the list of
+	   imports.  The import table is an array (ending when an entry has
+	   empty values) of structures (20 bytes each), which contains (at
+	   offset 12) a relative address (to the module base) at which a
+	   string constant holding the import name is located. */
+
+	if (DWORD_AT(dllbase + opt_offset + num_dict_off) >= 2) {
+		/* We have at least 2 tables - the import table is the second
+		   one.  But still it may be that the table size is zero */
+		if (0 == DWORD_AT(dllbase + opt_offset + import_off + sizeof(DWORD)))
+			return NULL;
+		import_data = dllbase + DWORD_AT(dllbase +
+						 opt_offset +
+						 import_off);
+		while (DWORD_AT(import_data)) {
+			import_name = dllbase + DWORD_AT(import_data+12);
+			if (strlen(import_name) >= 6 &&
+			    !strncmp(import_name,"python",6)) {
+				char *pch;
+
+				/* Ensure python prefix is followed only
+				   by numbers to the end of the basename */
+				pch = import_name + 6;
+#ifdef _DEBUG
+				while (*pch && pch[0] != '_' && pch[1] != 'd' && pch[2] != '.') {
+#else
+				while (*pch && *pch != '.') {
+#endif
+					if (*pch >= '0' && *pch <= '9') {
+						pch++;
+					} else {
+						pch = NULL;
+						break;
+					}
+				}
+	    
+				if (pch) {
+					/* Found it - return the name */
+					return import_name;
+				}
+			}
+			import_data += 20;
+		}
+	}
+
+	return NULL;
+}
+
+
+dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
+				    const char *pathname, FILE *fp)
+{
+	dl_funcptr p;
+	char funcname[258], *import_python;
+
+	PyOS_snprintf(funcname, sizeof(funcname), "init%.200s", shortname);
+
+	{
+		HINSTANCE hDLL = NULL;
+		char pathbuf[260];
+		LPTSTR dummy;
+		/* We use LoadLibraryEx so Windows looks for dependent DLLs 
+		    in directory of pathname first.  However, Windows95
+		    can sometimes not work correctly unless the absolute
+		    path is used.  If GetFullPathName() fails, the LoadLibrary
+		    will certainly fail too, so use its error code */
+		if (GetFullPathName(pathname,
+				    sizeof(pathbuf),
+				    pathbuf,
+				    &dummy))
+			/* XXX This call doesn't exist in Windows CE */
+			hDLL = LoadLibraryEx(pathname, NULL,
+					     LOAD_WITH_ALTERED_SEARCH_PATH);
+		if (hDLL==NULL){
+			char errBuf[256];
+			unsigned int errorCode;
+
+			/* Get an error string from Win32 error code */
+			char theInfo[256]; /* Pointer to error text
+					      from system */
+			int theLength; /* Length of error text */
+
+			errorCode = GetLastError();
+
+			theLength = FormatMessage(
+				FORMAT_MESSAGE_FROM_SYSTEM, /* flags */
+				NULL, /* message source */
+				errorCode, /* the message (error) ID */
+				0, /* default language environment */
+				(LPTSTR) theInfo, /* the buffer */
+				sizeof(theInfo), /* the buffer size */
+				NULL); /* no additional format args. */
+
+			/* Problem: could not get the error message.
+			   This should not happen if called correctly. */
+			if (theLength == 0) {
+				PyOS_snprintf(errBuf, sizeof(errBuf),
+				      "DLL load failed with error code %d",
+					      errorCode);
+			} else {
+				size_t len;
+				/* For some reason a \r\n
+				   is appended to the text */
+				if (theLength >= 2 &&
+				    theInfo[theLength-2] == '\r' &&
+				    theInfo[theLength-1] == '\n') {
+					theLength -= 2;
+					theInfo[theLength] = '\0';
+				}
+				strcpy(errBuf, "DLL load failed: ");
+				len = strlen(errBuf);
+				strncpy(errBuf+len, theInfo,
+					sizeof(errBuf)-len);
+				errBuf[sizeof(errBuf)-1] = '\0';
+			}
+			PyErr_SetString(PyExc_ImportError, errBuf);
+			return NULL;
+		} else {
+			char buffer[256];
+
+#ifdef _DEBUG
+			PyOS_snprintf(buffer, sizeof(buffer), "python%d%d_d.dll",
+#else
+			PyOS_snprintf(buffer, sizeof(buffer), "python%d%d.dll",
+#endif
+				      PY_MAJOR_VERSION,PY_MINOR_VERSION);
+			import_python = GetPythonImport(hDLL);
+
+			if (import_python &&
+			    strcasecmp(buffer,import_python)) {
+				PyOS_snprintf(buffer, sizeof(buffer),
+					      "Module use of %.150s conflicts "
+					      "with this version of Python.",
+					      import_python);
+				PyErr_SetString(PyExc_ImportError,buffer);
+				FreeLibrary(hDLL);
+				return NULL;
+			}
+		}
+		p = GetProcAddress(hDLL, funcname);
+	}
+
+	return p;
+}

Added: vendor/Python/current/Python/errors.c
===================================================================
--- vendor/Python/current/Python/errors.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/errors.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,822 @@
+
+/* Error handling */
+
+#include "Python.h"
+
+#ifndef __STDC__
+#ifndef MS_WINDOWS
+extern char *strerror(int);
+#endif
+#endif
+
+#ifdef MS_WINDOWS
+#include "windows.h"
+#include "winbase.h"
+#endif
+
+#include <ctype.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+void
+PyErr_Restore(PyObject *type, PyObject *value, PyObject *traceback)
+{
+	PyThreadState *tstate = PyThreadState_GET();
+	PyObject *oldtype, *oldvalue, *oldtraceback;
+
+	if (traceback != NULL && !PyTraceBack_Check(traceback)) {
+		/* XXX Should never happen -- fatal error instead? */
+		/* Well, it could be None. */
+		Py_DECREF(traceback);
+		traceback = NULL;
+	}
+
+	/* Save these in locals to safeguard against recursive
+	   invocation through Py_XDECREF */
+	oldtype = tstate->curexc_type;
+	oldvalue = tstate->curexc_value;
+	oldtraceback = tstate->curexc_traceback;
+
+	tstate->curexc_type = type;
+	tstate->curexc_value = value;
+	tstate->curexc_traceback = traceback;
+
+	Py_XDECREF(oldtype);
+	Py_XDECREF(oldvalue);
+	Py_XDECREF(oldtraceback);
+}
+
+void
+PyErr_SetObject(PyObject *exception, PyObject *value)
+{
+	Py_XINCREF(exception);
+	Py_XINCREF(value);
+	PyErr_Restore(exception, value, (PyObject *)NULL);
+}
+
+void
+PyErr_SetNone(PyObject *exception)
+{
+	PyErr_SetObject(exception, (PyObject *)NULL);
+}
+
+void
+PyErr_SetString(PyObject *exception, const char *string)
+{
+	PyObject *value = PyString_FromString(string);
+	PyErr_SetObject(exception, value);
+	Py_XDECREF(value);
+}
+
+
+PyObject *
+PyErr_Occurred(void)
+{
+	PyThreadState *tstate = PyThreadState_GET();
+
+	return tstate->curexc_type;
+}
+
+
+int
+PyErr_GivenExceptionMatches(PyObject *err, PyObject *exc)
+{
+	if (err == NULL || exc == NULL) {
+		/* maybe caused by "import exceptions" that failed early on */
+		return 0;
+	}
+	if (PyTuple_Check(exc)) {
+		Py_ssize_t i, n;
+		n = PyTuple_Size(exc);
+		for (i = 0; i < n; i++) {
+			/* Test recursively */
+		     if (PyErr_GivenExceptionMatches(
+			     err, PyTuple_GET_ITEM(exc, i)))
+		     {
+			     return 1;
+		     }
+		}
+		return 0;
+	}
+	/* err might be an instance, so check its class. */
+	if (PyExceptionInstance_Check(err))
+		err = PyExceptionInstance_Class(err);
+
+	if (PyExceptionClass_Check(err) && PyExceptionClass_Check(exc)) {
+		/* problems here!?  not sure PyObject_IsSubclass expects to
+		   be called with an exception pending... */
+		return PyObject_IsSubclass(err, exc);
+	}
+
+	return err == exc;
+}
+
+
+int
+PyErr_ExceptionMatches(PyObject *exc)
+{
+	return PyErr_GivenExceptionMatches(PyErr_Occurred(), exc);
+}
+
+
+/* Used in many places to normalize a raised exception, including in
+   eval_code2(), do_raise(), and PyErr_Print()
+*/
+void
+PyErr_NormalizeException(PyObject **exc, PyObject **val, PyObject **tb)
+{
+	PyObject *type = *exc;
+	PyObject *value = *val;
+	PyObject *inclass = NULL;
+	PyObject *initial_tb = NULL;
+
+	if (type == NULL) {
+		/* There was no exception, so nothing to do. */
+		return;
+	}
+
+	/* If PyErr_SetNone() was used, the value will have been actually
+	   set to NULL.
+	*/
+	if (!value) {
+		value = Py_None;
+		Py_INCREF(value);
+	}
+
+	if (PyExceptionInstance_Check(value))
+		inclass = PyExceptionInstance_Class(value);
+
+	/* Normalize the exception so that if the type is a class, the
+	   value will be an instance.
+	*/
+	if (PyExceptionClass_Check(type)) {
+		/* if the value was not an instance, or is not an instance
+		   whose class is (or is derived from) type, then use the
+		   value as an argument to instantiation of the type
+		   class.
+		*/
+		if (!inclass || !PyObject_IsSubclass(inclass, type)) {
+			PyObject *args, *res;
+
+			if (value == Py_None)
+				args = PyTuple_New(0);
+			else if (PyTuple_Check(value)) {
+				Py_INCREF(value);
+				args = value;
+			}
+			else
+				args = PyTuple_Pack(1, value);
+
+			if (args == NULL)
+				goto finally;
+			res = PyEval_CallObject(type, args);
+			Py_DECREF(args);
+			if (res == NULL)
+				goto finally;
+			Py_DECREF(value);
+			value = res;
+		}
+		/* if the class of the instance doesn't exactly match the
+		   class of the type, believe the instance
+		*/
+		else if (inclass != type) {
+ 			Py_DECREF(type);
+			type = inclass;
+			Py_INCREF(type);
+		}
+	}
+	*exc = type;
+	*val = value;
+	return;
+finally:
+	Py_DECREF(type);
+	Py_DECREF(value);
+	/* If the new exception doesn't set a traceback and the old
+	   exception had a traceback, use the old traceback for the
+	   new exception.  It's better than nothing.
+	*/
+	initial_tb = *tb;
+	PyErr_Fetch(exc, val, tb);
+	if (initial_tb != NULL) {
+		if (*tb == NULL)
+			*tb = initial_tb;
+		else
+			Py_DECREF(initial_tb);
+	}
+	/* normalize recursively */
+	PyErr_NormalizeException(exc, val, tb);
+}
+
+
+void
+PyErr_Fetch(PyObject **p_type, PyObject **p_value, PyObject **p_traceback)
+{
+	PyThreadState *tstate = PyThreadState_GET();
+
+	*p_type = tstate->curexc_type;
+	*p_value = tstate->curexc_value;
+	*p_traceback = tstate->curexc_traceback;
+
+	tstate->curexc_type = NULL;
+	tstate->curexc_value = NULL;
+	tstate->curexc_traceback = NULL;
+}
+
+void
+PyErr_Clear(void)
+{
+	PyErr_Restore(NULL, NULL, NULL);
+}
+
+/* Convenience functions to set a type error exception and return 0 */
+
+int
+PyErr_BadArgument(void)
+{
+	PyErr_SetString(PyExc_TypeError,
+			"bad argument type for built-in operation");
+	return 0;
+}
+
+PyObject *
+PyErr_NoMemory(void)
+{
+	if (PyErr_ExceptionMatches(PyExc_MemoryError))
+		/* already current */
+		return NULL;
+
+	/* raise the pre-allocated instance if it still exists */
+	if (PyExc_MemoryErrorInst)
+		PyErr_SetObject(PyExc_MemoryError, PyExc_MemoryErrorInst);
+	else
+		/* this will probably fail since there's no memory and hee,
+		   hee, we have to instantiate this class
+		*/
+		PyErr_SetNone(PyExc_MemoryError);
+
+	return NULL;
+}
+
+PyObject *
+PyErr_SetFromErrnoWithFilenameObject(PyObject *exc, PyObject *filenameObject)
+{
+	PyObject *v;
+	char *s;
+	int i = errno;
+#ifdef PLAN9
+	char errbuf[ERRMAX];
+#endif
+#ifdef MS_WINDOWS
+	char *s_buf = NULL;
+	char s_small_buf[28]; /* Room for "Windows Error 0xFFFFFFFF" */
+#endif
+#ifdef EINTR
+	if (i == EINTR && PyErr_CheckSignals())
+		return NULL;
+#endif
+#ifdef PLAN9
+	rerrstr(errbuf, sizeof errbuf);
+	s = errbuf;
+#else
+	if (i == 0)
+		s = "Error"; /* Sometimes errno didn't get set */
+	else
+#ifndef MS_WINDOWS
+		s = strerror(i);
+#else
+	{
+		/* Note that the Win32 errors do not lineup with the
+		   errno error.  So if the error is in the MSVC error
+		   table, we use it, otherwise we assume it really _is_
+		   a Win32 error code
+		*/
+		if (i > 0 && i < _sys_nerr) {
+			s = _sys_errlist[i];
+		}
+		else {
+			int len = FormatMessage(
+				FORMAT_MESSAGE_ALLOCATE_BUFFER |
+				FORMAT_MESSAGE_FROM_SYSTEM |
+				FORMAT_MESSAGE_IGNORE_INSERTS,
+				NULL,	/* no message source */
+				i,
+				MAKELANGID(LANG_NEUTRAL,
+					   SUBLANG_DEFAULT),
+				           /* Default language */
+				(LPTSTR) &s_buf,
+				0,	/* size not used */
+				NULL);	/* no args */
+			if (len==0) {
+				/* Only ever seen this in out-of-mem
+				   situations */
+				sprintf(s_small_buf, "Windows Error 0x%X", i);
+				s = s_small_buf;
+				s_buf = NULL;
+			} else {
+				s = s_buf;
+				/* remove trailing cr/lf and dots */
+				while (len > 0 && (s[len-1] <= ' ' || s[len-1] == '.'))
+					s[--len] = '\0';
+			}
+		}
+	}
+#endif /* Unix/Windows */
+#endif /* PLAN 9*/
+	if (filenameObject != NULL)
+		v = Py_BuildValue("(isO)", i, s, filenameObject);
+	else
+		v = Py_BuildValue("(is)", i, s);
+	if (v != NULL) {
+		PyErr_SetObject(exc, v);
+		Py_DECREF(v);
+	}
+#ifdef MS_WINDOWS
+	LocalFree(s_buf);
+#endif
+	return NULL;
+}
+
+
+PyObject *
+PyErr_SetFromErrnoWithFilename(PyObject *exc, char *filename)
+{
+	PyObject *name = filename ? PyString_FromString(filename) : NULL;
+	PyObject *result = PyErr_SetFromErrnoWithFilenameObject(exc, name);
+	Py_XDECREF(name);
+	return result;
+}
+
+#ifdef Py_WIN_WIDE_FILENAMES
+PyObject *
+PyErr_SetFromErrnoWithUnicodeFilename(PyObject *exc, Py_UNICODE *filename)
+{
+	PyObject *name = filename ?
+	                 PyUnicode_FromUnicode(filename, wcslen(filename)) :
+	                 NULL;
+	PyObject *result = PyErr_SetFromErrnoWithFilenameObject(exc, name);
+	Py_XDECREF(name);
+	return result;
+}
+#endif /* Py_WIN_WIDE_FILENAMES */
+
+PyObject *
+PyErr_SetFromErrno(PyObject *exc)
+{
+	return PyErr_SetFromErrnoWithFilenameObject(exc, NULL);
+}
+
+#ifdef MS_WINDOWS
+/* Windows specific error code handling */
+PyObject *PyErr_SetExcFromWindowsErrWithFilenameObject(
+	PyObject *exc,
+	int ierr,
+	PyObject *filenameObject)
+{
+	int len;
+	char *s;
+	char *s_buf = NULL; /* Free via LocalFree */
+	char s_small_buf[28]; /* Room for "Windows Error 0xFFFFFFFF" */
+	PyObject *v;
+	DWORD err = (DWORD)ierr;
+	if (err==0) err = GetLastError();
+	len = FormatMessage(
+		/* Error API error */
+		FORMAT_MESSAGE_ALLOCATE_BUFFER |
+		FORMAT_MESSAGE_FROM_SYSTEM |
+		FORMAT_MESSAGE_IGNORE_INSERTS,
+		NULL,	/* no message source */
+		err,
+		MAKELANGID(LANG_NEUTRAL,
+		SUBLANG_DEFAULT), /* Default language */
+		(LPTSTR) &s_buf,
+		0,	/* size not used */
+		NULL);	/* no args */
+	if (len==0) {
+		/* Only seen this in out of mem situations */
+		sprintf(s_small_buf, "Windows Error 0x%X", err);
+		s = s_small_buf;
+		s_buf = NULL;
+	} else {
+		s = s_buf;
+		/* remove trailing cr/lf and dots */
+		while (len > 0 && (s[len-1] <= ' ' || s[len-1] == '.'))
+			s[--len] = '\0';
+	}
+	if (filenameObject != NULL)
+		v = Py_BuildValue("(isO)", err, s, filenameObject);
+	else
+		v = Py_BuildValue("(is)", err, s);
+	if (v != NULL) {
+		PyErr_SetObject(exc, v);
+		Py_DECREF(v);
+	}
+	LocalFree(s_buf);
+	return NULL;
+}
+
+PyObject *PyErr_SetExcFromWindowsErrWithFilename(
+	PyObject *exc,
+	int ierr,
+	const char *filename)
+{
+	PyObject *name = filename ? PyString_FromString(filename) : NULL;
+	PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObject(exc,
+	                                                             ierr,
+	                                                             name);
+	Py_XDECREF(name);
+	return ret;
+}
+
+#ifdef Py_WIN_WIDE_FILENAMES
+PyObject *PyErr_SetExcFromWindowsErrWithUnicodeFilename(
+	PyObject *exc,
+	int ierr,
+	const Py_UNICODE *filename)
+{
+	PyObject *name = filename ?
+	                 PyUnicode_FromUnicode(filename, wcslen(filename)) :
+	                 NULL;
+	PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObject(exc,
+	                                                             ierr,
+	                                                             name);
+	Py_XDECREF(name);
+	return ret;
+}
+#endif /* Py_WIN_WIDE_FILENAMES */
+
+PyObject *PyErr_SetExcFromWindowsErr(PyObject *exc, int ierr)
+{
+	return PyErr_SetExcFromWindowsErrWithFilename(exc, ierr, NULL);
+}
+
+PyObject *PyErr_SetFromWindowsErr(int ierr)
+{
+	return PyErr_SetExcFromWindowsErrWithFilename(PyExc_WindowsError,
+						      ierr, NULL);
+}
+PyObject *PyErr_SetFromWindowsErrWithFilename(
+	int ierr,
+	const char *filename)
+{
+	PyObject *name = filename ? PyString_FromString(filename) : NULL;
+	PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObject(
+						      PyExc_WindowsError,
+						      ierr, name);
+	Py_XDECREF(name);
+	return result;
+}
+
+#ifdef Py_WIN_WIDE_FILENAMES
+PyObject *PyErr_SetFromWindowsErrWithUnicodeFilename(
+	int ierr,
+	const Py_UNICODE *filename)
+{
+	PyObject *name = filename ?
+	                 PyUnicode_FromUnicode(filename, wcslen(filename)) :
+	                 NULL;
+	PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObject(
+						      PyExc_WindowsError,
+						      ierr, name);
+	Py_XDECREF(name);
+	return result;
+}
+#endif /* Py_WIN_WIDE_FILENAMES */
+#endif /* MS_WINDOWS */
+
+void
+_PyErr_BadInternalCall(char *filename, int lineno)
+{
+	PyErr_Format(PyExc_SystemError,
+		     "%s:%d: bad argument to internal function",
+		     filename, lineno);
+}
+
+/* Remove the preprocessor macro for PyErr_BadInternalCall() so that we can
+   export the entry point for existing object code: */
+#undef PyErr_BadInternalCall
+void
+PyErr_BadInternalCall(void)
+{
+	PyErr_Format(PyExc_SystemError,
+		     "bad argument to internal function");
+}
+#define PyErr_BadInternalCall() _PyErr_BadInternalCall(__FILE__, __LINE__)
+
+
+
+PyObject *
+PyErr_Format(PyObject *exception, const char *format, ...)
+{
+	va_list vargs;
+	PyObject* string;
+
+#ifdef HAVE_STDARG_PROTOTYPES
+	va_start(vargs, format);
+#else
+	va_start(vargs);
+#endif
+
+	string = PyString_FromFormatV(format, vargs);
+	PyErr_SetObject(exception, string);
+	Py_XDECREF(string);
+	va_end(vargs);
+	return NULL;
+}
+
+
+
+PyObject *
+PyErr_NewException(char *name, PyObject *base, PyObject *dict)
+{
+	char *dot;
+	PyObject *modulename = NULL;
+	PyObject *classname = NULL;
+	PyObject *mydict = NULL;
+	PyObject *bases = NULL;
+	PyObject *result = NULL;
+	dot = strrchr(name, '.');
+	if (dot == NULL) {
+		PyErr_SetString(PyExc_SystemError,
+			"PyErr_NewException: name must be module.class");
+		return NULL;
+	}
+	if (base == NULL)
+		base = PyExc_Exception;
+	if (dict == NULL) {
+		dict = mydict = PyDict_New();
+		if (dict == NULL)
+			goto failure;
+	}
+	if (PyDict_GetItemString(dict, "__module__") == NULL) {
+		modulename = PyString_FromStringAndSize(name,
+						     (Py_ssize_t)(dot-name));
+		if (modulename == NULL)
+			goto failure;
+		if (PyDict_SetItemString(dict, "__module__", modulename) != 0)
+			goto failure;
+	}
+	if (PyTuple_Check(base)) {
+		bases = base;
+		/* INCREF as we create a new ref in the else branch */
+		Py_INCREF(bases);
+	} else {
+		bases = PyTuple_Pack(1, base);
+		if (bases == NULL)
+			goto failure;
+	}
+	/* Create a real new-style class. */
+	result = PyObject_CallFunction((PyObject *)&PyType_Type, "sOO",
+				       dot+1, bases, dict);
+  failure:
+	Py_XDECREF(bases);
+	Py_XDECREF(mydict);
+	Py_XDECREF(classname);
+	Py_XDECREF(modulename);
+	return result;
+}
+
+/* Call when an exception has occurred but there is no way for Python
+   to handle it.  Examples: exception in __del__ or during GC. */
+void
+PyErr_WriteUnraisable(PyObject *obj)
+{
+	PyObject *f, *t, *v, *tb;
+	PyErr_Fetch(&t, &v, &tb);
+	f = PySys_GetObject("stderr");
+	if (f != NULL) {
+		PyFile_WriteString("Exception ", f);
+		if (t) {
+			PyObject* moduleName;
+			char* className = NULL;
+			if (PyExceptionClass_Check(t))
+				className = PyExceptionClass_Name(t);
+			else if (PyString_Check(t))
+				className = PyString_AS_STRING(t);
+
+			if (className != NULL) {
+				char *dot = strrchr(className, '.');
+				if (dot != NULL)
+					className = dot+1;
+			}
+
+			moduleName = PyObject_GetAttrString(t, "__module__");
+			if (moduleName == NULL)
+				PyFile_WriteString("<unknown>", f);
+			else {
+				char* modstr = PyString_AsString(moduleName);
+				if (modstr)
+				{
+					PyFile_WriteString(modstr, f);
+					PyFile_WriteString(".", f);
+				}
+			}
+			if (className == NULL)
+				PyFile_WriteString("<unknown>", f);
+			else
+				PyFile_WriteString(className, f);
+			if (v && v != Py_None) {
+				PyFile_WriteString(": ", f);
+				PyFile_WriteObject(v, f, 0);
+			}
+			Py_XDECREF(moduleName);
+		}
+		PyFile_WriteString(" in ", f);
+		PyFile_WriteObject(obj, f, 0);
+		PyFile_WriteString(" ignored\n", f);
+		PyErr_Clear(); /* Just in case */
+	}
+	Py_XDECREF(t);
+	Py_XDECREF(v);
+	Py_XDECREF(tb);
+}
+
+extern PyObject *PyModule_GetWarningsModule(void);
+
+/* Function to issue a warning message; may raise an exception. */
+int
+PyErr_WarnEx(PyObject *category, const char *message, Py_ssize_t stack_level)
+{
+	PyObject *dict, *func = NULL;
+	PyObject *warnings_module = PyModule_GetWarningsModule();
+
+	if (warnings_module != NULL) {
+		dict = PyModule_GetDict(warnings_module);
+		if (dict != NULL)
+			func = PyDict_GetItemString(dict, "warn");
+	}
+	if (func == NULL) {
+		PySys_WriteStderr("warning: %s\n", message);
+		return 0;
+	}
+	else {
+		PyObject *res;
+
+		if (category == NULL)
+			category = PyExc_RuntimeWarning;
+		res = PyObject_CallFunction(func, "sOn",
+					    message, category, stack_level);
+		if (res == NULL)
+			return -1;
+		Py_DECREF(res);
+		return 0;
+	}
+}
+
+/* PyErr_Warn is only for backwards compatability and will be removed.
+   Use PyErr_WarnEx instead. */
+
+#undef PyErr_Warn
+
+PyAPI_FUNC(int)
+PyErr_Warn(PyObject *category, char *message)
+{
+	return PyErr_WarnEx(category, message, 1);
+}
+
+/* Warning with explicit origin */
+int
+PyErr_WarnExplicit(PyObject *category, const char *message,
+		   const char *filename, int lineno,
+		   const char *module, PyObject *registry)
+{
+	PyObject *mod, *dict, *func = NULL;
+
+	mod = PyImport_ImportModule("warnings");
+	if (mod != NULL) {
+		dict = PyModule_GetDict(mod);
+		func = PyDict_GetItemString(dict, "warn_explicit");
+		Py_DECREF(mod);
+	}
+	if (func == NULL) {
+		PySys_WriteStderr("warning: %s\n", message);
+		return 0;
+	}
+	else {
+		PyObject *res;
+
+		if (category == NULL)
+			category = PyExc_RuntimeWarning;
+		if (registry == NULL)
+			registry = Py_None;
+		res = PyObject_CallFunction(func, "sOsizO", message, category,
+					    filename, lineno, module, registry);
+		if (res == NULL)
+			return -1;
+		Py_DECREF(res);
+		return 0;
+	}
+}
+
+
+/* Set file and line information for the current exception.
+   If the exception is not a SyntaxError, also sets additional attributes
+   to make printing of exceptions believe it is a syntax error. */
+
+void
+PyErr_SyntaxLocation(const char *filename, int lineno)
+{
+	PyObject *exc, *v, *tb, *tmp;
+
+	/* add attributes for the line number and filename for the error */
+	PyErr_Fetch(&exc, &v, &tb);
+	PyErr_NormalizeException(&exc, &v, &tb);
+	/* XXX check that it is, indeed, a syntax error. It might not
+	 * be, though. */
+	tmp = PyInt_FromLong(lineno);
+	if (tmp == NULL)
+		PyErr_Clear();
+	else {
+		if (PyObject_SetAttrString(v, "lineno", tmp))
+			PyErr_Clear();
+		Py_DECREF(tmp);
+	}
+	if (filename != NULL) {
+		tmp = PyString_FromString(filename);
+		if (tmp == NULL)
+			PyErr_Clear();
+		else {
+			if (PyObject_SetAttrString(v, "filename", tmp))
+				PyErr_Clear();
+			Py_DECREF(tmp);
+		}
+
+		tmp = PyErr_ProgramText(filename, lineno);
+		if (tmp) {
+			if (PyObject_SetAttrString(v, "text", tmp))
+				PyErr_Clear();
+			Py_DECREF(tmp);
+		}
+	}
+	if (PyObject_SetAttrString(v, "offset", Py_None)) {
+		PyErr_Clear();
+	}
+	if (exc != PyExc_SyntaxError) {
+		if (!PyObject_HasAttrString(v, "msg")) {
+			tmp = PyObject_Str(v);
+			if (tmp) {
+				if (PyObject_SetAttrString(v, "msg", tmp))
+					PyErr_Clear();
+				Py_DECREF(tmp);
+			} else {
+				PyErr_Clear();
+			}
+		}
+		if (!PyObject_HasAttrString(v, "print_file_and_line")) {
+			if (PyObject_SetAttrString(v, "print_file_and_line",
+						   Py_None))
+				PyErr_Clear();
+		}
+	}
+	PyErr_Restore(exc, v, tb);
+}
+
+/* com_fetch_program_text will attempt to load the line of text that
+   the exception refers to.  If it fails, it will return NULL but will
+   not set an exception.
+
+   XXX The functionality of this function is quite similar to the
+   functionality in tb_displayline() in traceback.c.
+*/
+
+PyObject *
+PyErr_ProgramText(const char *filename, int lineno)
+{
+	FILE *fp;
+	int i;
+	char linebuf[1000];
+
+	if (filename == NULL || *filename == '\0' || lineno <= 0)
+		return NULL;
+	fp = fopen(filename, "r" PY_STDIOTEXTMODE);
+	if (fp == NULL)
+		return NULL;
+	for (i = 0; i < lineno; i++) {
+		char *pLastChar = &linebuf[sizeof(linebuf) - 2];
+		do {
+			*pLastChar = '\0';
+			if (Py_UniversalNewlineFgets(linebuf, sizeof linebuf, fp, NULL) == NULL)
+				break;
+			/* fgets read *something*; if it didn't get as
+			   far as pLastChar, it must have found a newline
+			   or hit the end of the file; if pLastChar is \n,
+			   it obviously found a newline; else we haven't
+			   yet seen a newline, so must continue */
+		} while (*pLastChar != '\0' && *pLastChar != '\n');
+	}
+	fclose(fp);
+	if (i == lineno) {
+		char *p = linebuf;
+		while (*p == ' ' || *p == '\t' || *p == '\014')
+			p++;
+		return PyString_FromString(p);
+	}
+	return NULL;
+}
+
+#ifdef __cplusplus
+}
+#endif
+

Added: vendor/Python/current/Python/fmod.c
===================================================================
--- vendor/Python/current/Python/fmod.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/fmod.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,27 @@
+
+/* Portable fmod(x, y) implementation for systems that don't have it */
+
+#include "pyconfig.h"
+
+#include "pyport.h"
+#include <errno.h>
+
+double
+fmod(double x, double y)
+{
+	double i, f;
+	
+	if (y == 0.0) {
+		errno = EDOM;
+		return 0.0;
+	}
+	
+	/* return f such that x = i*y + f for some integer i
+	   such that |f| < |y| and f has the same sign as x */
+	
+	i = floor(x/y);
+	f = x - i*y;
+	if ((x < 0.0) != (y < 0.0))
+		f = f-y;
+	return f;
+}

Added: vendor/Python/current/Python/frozen.c
===================================================================
--- vendor/Python/current/Python/frozen.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/frozen.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,38 @@
+
+/* Dummy frozen modules initializer */
+
+#include "Python.h"
+
+/* In order to test the support for frozen modules, by default we
+   define a single frozen module, __hello__.  Loading it will print
+   some famous words... */
+
+/* To regenerate this data after the bytecode or marshal format has changed,
+   go to ../Tools/freeze/ and freeze the hello.py file; then copy and paste
+   the appropriate bytes from M___main__.c. */
+
+static unsigned char M___hello__[] = {
+	99,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,
+	0,115,9,0,0,0,100,0,0,71,72,100,1,0,83,40,
+	2,0,0,0,115,14,0,0,0,72,101,108,108,111,32,119,
+	111,114,108,100,46,46,46,78,40,0,0,0,0,40,0,0,
+	0,0,40,0,0,0,0,40,0,0,0,0,115,8,0,0,
+	0,104,101,108,108,111,46,112,121,115,1,0,0,0,63,1,
+	0,0,0,115,0,0,0,0,
+};
+
+#define SIZE (int)sizeof(M___hello__)
+
+static struct _frozen _PyImport_FrozenModules[] = {
+	/* Test module */
+	{"__hello__", M___hello__, SIZE},
+	/* Test package (negative size indicates package-ness) */
+	{"__phello__", M___hello__, -SIZE},
+	{"__phello__.spam", M___hello__, SIZE},
+	{0, 0, 0} /* sentinel */
+};
+
+/* Embedding apps may change this pointer to point to their favorite
+   collection of frozen modules: */
+
+struct _frozen *PyImport_FrozenModules = _PyImport_FrozenModules;

Added: vendor/Python/current/Python/frozenmain.c
===================================================================
--- vendor/Python/current/Python/frozenmain.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/frozenmain.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,68 @@
+
+/* Python interpreter main program for frozen scripts */
+
+#include "Python.h"
+
+#ifdef MS_WINDOWS
+extern void PyWinFreeze_ExeInit(void);
+extern void PyWinFreeze_ExeTerm(void);
+extern int PyInitFrozenExtensions(void);
+#endif
+
+/* Main program */
+
+int
+Py_FrozenMain(int argc, char **argv)
+{
+	char *p;
+	int n, sts;
+	int inspect = 0;
+	int unbuffered = 0;
+
+	Py_FrozenFlag = 1; /* Suppress errors from getpath.c */
+
+	if ((p = Py_GETENV("PYTHONINSPECT")) && *p != '\0')
+		inspect = 1;
+	if ((p = Py_GETENV("PYTHONUNBUFFERED")) && *p != '\0')
+		unbuffered = 1;
+
+	if (unbuffered) {
+		setbuf(stdin, (char *)NULL);
+		setbuf(stdout, (char *)NULL);
+		setbuf(stderr, (char *)NULL);
+	}
+
+#ifdef MS_WINDOWS
+	PyInitFrozenExtensions();
+#endif /* MS_WINDOWS */
+	Py_SetProgramName(argv[0]);
+	Py_Initialize();
+#ifdef MS_WINDOWS
+	PyWinFreeze_ExeInit();
+#endif
+
+	if (Py_VerboseFlag)
+		fprintf(stderr, "Python %s\n%s\n",
+			Py_GetVersion(), Py_GetCopyright());
+
+	PySys_SetArgv(argc, argv);
+
+	n = PyImport_ImportFrozenModule("__main__");
+	if (n == 0)
+		Py_FatalError("__main__ not frozen");
+	if (n < 0) {
+		PyErr_Print();
+		sts = 1;
+	}
+	else
+		sts = 0;
+
+	if (inspect && isatty((int)fileno(stdin)))
+		sts = PyRun_AnyFile(stdin, "<stdin>") != 0;
+
+#ifdef MS_WINDOWS
+	PyWinFreeze_ExeTerm();
+#endif
+	Py_Finalize();
+	return sts;
+}

Added: vendor/Python/current/Python/future.c
===================================================================
--- vendor/Python/current/Python/future.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/future.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,136 @@
+#include "Python.h"
+#include "Python-ast.h"
+#include "node.h"
+#include "token.h"
+#include "graminit.h"
+#include "code.h"
+#include "compile.h"
+#include "symtable.h"
+
+#define UNDEFINED_FUTURE_FEATURE "future feature %.100s is not defined"
+
+static int
+future_check_features(PyFutureFeatures *ff, stmt_ty s, const char *filename)
+{
+	int i;
+	asdl_seq *names;
+
+	assert(s->kind == ImportFrom_kind);
+
+	names = s->v.ImportFrom.names;
+	for (i = 0; i < asdl_seq_LEN(names); i++) {
+                alias_ty name = (alias_ty)asdl_seq_GET(names, i);
+		const char *feature = PyString_AsString(name->name);
+		if (!feature)
+			return 0;
+		if (strcmp(feature, FUTURE_NESTED_SCOPES) == 0) {
+			continue;
+		} else if (strcmp(feature, FUTURE_GENERATORS) == 0) {
+			continue;
+		} else if (strcmp(feature, FUTURE_DIVISION) == 0) {
+			ff->ff_features |= CO_FUTURE_DIVISION;
+		} else if (strcmp(feature, FUTURE_ABSOLUTE_IMPORT) == 0) {
+			ff->ff_features |= CO_FUTURE_ABSOLUTE_IMPORT;
+		} else if (strcmp(feature, FUTURE_WITH_STATEMENT) == 0) {
+			ff->ff_features |= CO_FUTURE_WITH_STATEMENT;
+		} else if (strcmp(feature, "braces") == 0) {
+			PyErr_SetString(PyExc_SyntaxError,
+					"not a chance");
+			PyErr_SyntaxLocation(filename, s->lineno);
+			return 0;
+		} else {
+			PyErr_Format(PyExc_SyntaxError,
+				     UNDEFINED_FUTURE_FEATURE, feature);
+			PyErr_SyntaxLocation(filename, s->lineno);
+			return 0;
+		}
+	}
+	return 1;
+}
+
+static int
+future_parse(PyFutureFeatures *ff, mod_ty mod, const char *filename)
+{
+	int i, found_docstring = 0, done = 0, prev_line = 0;
+
+	static PyObject *future;
+	if (!future) {
+		future = PyString_InternFromString("__future__");
+		if (!future)
+			return 0;
+	}
+
+	if (!(mod->kind == Module_kind || mod->kind == Interactive_kind))
+		return 1;
+
+	/* A subsequent pass will detect future imports that don't
+	   appear at the beginning of the file.  There's one case,
+	   however, that is easier to handl here: A series of imports
+	   joined by semi-colons, where the first import is a future
+	   statement but some subsequent import has the future form
+	   but is preceded by a regular import.
+	*/
+	   
+
+	for (i = 0; i < asdl_seq_LEN(mod->v.Module.body); i++) {
+		stmt_ty s = (stmt_ty)asdl_seq_GET(mod->v.Module.body, i);
+
+		if (done && s->lineno > prev_line)
+			return 1;
+		prev_line = s->lineno;
+
+		/* The tests below will return from this function unless it is
+		   still possible to find a future statement.  The only things
+		   that can precede a future statement are another future
+		   statement and a doc string.
+		*/
+
+		if (s->kind == ImportFrom_kind) {
+			if (s->v.ImportFrom.module == future) {
+				if (done) {
+					PyErr_SetString(PyExc_SyntaxError,
+							ERR_LATE_FUTURE);
+					PyErr_SyntaxLocation(filename, 
+							     s->lineno);
+					return 0;
+				}
+				if (!future_check_features(ff, s, filename))
+					return 0;
+				ff->ff_lineno = s->lineno;
+			}
+			else
+				done = 1;
+		}
+		else if (s->kind == Expr_kind && !found_docstring) {
+			expr_ty e = s->v.Expr.value;
+			if (e->kind != Str_kind)
+				done = 1;
+			else
+				found_docstring = 1;
+		}
+		else
+			done = 1;
+	}
+	return 1;
+}
+
+
+PyFutureFeatures *
+PyFuture_FromAST(mod_ty mod, const char *filename)
+{
+	PyFutureFeatures *ff;
+
+	ff = (PyFutureFeatures *)PyObject_Malloc(sizeof(PyFutureFeatures));
+	if (ff == NULL) {
+		PyErr_NoMemory();
+		return NULL;
+	}
+	ff->ff_features = 0;
+	ff->ff_lineno = -1;
+
+	if (!future_parse(ff, mod, filename)) {
+		PyObject_Free(ff);
+		return NULL;
+	}
+	return ff;
+}

Added: vendor/Python/current/Python/getargs.c
===================================================================
--- vendor/Python/current/Python/getargs.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/getargs.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1771 @@
+
+/* New getargs implementation */
+
+#include "Python.h"
+
+#include <ctype.h>
+
+
+#ifdef __cplusplus
+extern "C" { 
+#endif
+int PyArg_Parse(PyObject *, const char *, ...);
+int PyArg_ParseTuple(PyObject *, const char *, ...);
+int PyArg_VaParse(PyObject *, const char *, va_list);
+
+int PyArg_ParseTupleAndKeywords(PyObject *, PyObject *,
+				const char *, char **, ...);
+int PyArg_VaParseTupleAndKeywords(PyObject *, PyObject *,
+				const char *, char **, va_list);
+
+#ifdef HAVE_DECLSPEC_DLL
+/* Export functions */
+PyAPI_FUNC(int) _PyArg_Parse_SizeT(PyObject *, char *, ...);
+PyAPI_FUNC(int) _PyArg_ParseTuple_SizeT(PyObject *, char *, ...);
+PyAPI_FUNC(int) _PyArg_ParseTupleAndKeywords_SizeT(PyObject *, PyObject *,
+                                                  const char *, char **, ...);
+PyAPI_FUNC(PyObject *) _Py_BuildValue_SizeT(const char *, ...);
+PyAPI_FUNC(int) _PyArg_VaParse_SizeT(PyObject *, char *, va_list);
+PyAPI_FUNC(int) _PyArg_VaParseTupleAndKeywords_SizeT(PyObject *, PyObject *,
+                                              const char *, char **, va_list);
+#endif
+
+#define FLAG_COMPAT 1
+#define FLAG_SIZE_T 2
+
+
+/* Forward */
+static int vgetargs1(PyObject *, const char *, va_list *, int);
+static void seterror(int, const char *, int *, const char *, const char *);
+static char *convertitem(PyObject *, const char **, va_list *, int, int *, 
+                         char *, size_t, PyObject **);
+static char *converttuple(PyObject *, const char **, va_list *, int,
+			  int *, char *, size_t, int, PyObject **);
+static char *convertsimple(PyObject *, const char **, va_list *, int, char *,
+			   size_t, PyObject **);
+static Py_ssize_t convertbuffer(PyObject *, void **p, char **);
+
+static int vgetargskeywords(PyObject *, PyObject *,
+			    const char *, char **, va_list *, int);
+static char *skipitem(const char **, va_list *, int);
+
+int
+PyArg_Parse(PyObject *args, const char *format, ...)
+{
+	int retval;
+	va_list va;
+	
+	va_start(va, format);
+	retval = vgetargs1(args, format, &va, FLAG_COMPAT);
+	va_end(va);
+	return retval;
+}
+
+int
+_PyArg_Parse_SizeT(PyObject *args, char *format, ...)
+{
+	int retval;
+	va_list va;
+	
+	va_start(va, format);
+	retval = vgetargs1(args, format, &va, FLAG_COMPAT|FLAG_SIZE_T);
+	va_end(va);
+	return retval;
+}
+
+
+int
+PyArg_ParseTuple(PyObject *args, const char *format, ...)
+{
+	int retval;
+	va_list va;
+	
+	va_start(va, format);
+	retval = vgetargs1(args, format, &va, 0);
+	va_end(va);
+	return retval;
+}
+
+int
+_PyArg_ParseTuple_SizeT(PyObject *args, char *format, ...)
+{
+	int retval;
+	va_list va;
+	
+	va_start(va, format);
+	retval = vgetargs1(args, format, &va, FLAG_SIZE_T);
+	va_end(va);
+	return retval;
+}
+
+
+int
+PyArg_VaParse(PyObject *args, const char *format, va_list va)
+{
+	va_list lva;
+
+#ifdef VA_LIST_IS_ARRAY
+	memcpy(lva, va, sizeof(va_list));
+#else
+#ifdef __va_copy
+	__va_copy(lva, va);
+#else
+	lva = va;
+#endif
+#endif
+
+	return vgetargs1(args, format, &lva, 0);
+}
+
+int
+_PyArg_VaParse_SizeT(PyObject *args, char *format, va_list va)
+{
+	va_list lva;
+
+#ifdef VA_LIST_IS_ARRAY
+	memcpy(lva, va, sizeof(va_list));
+#else
+#ifdef __va_copy
+	__va_copy(lva, va);
+#else
+	lva = va;
+#endif
+#endif
+
+	return vgetargs1(args, format, &lva, FLAG_SIZE_T);
+}
+
+
+/* Handle cleanup of allocated memory in case of exception */
+
+static int
+addcleanup(void *ptr, PyObject **freelist)
+{
+	PyObject *cobj;
+	if (!*freelist) {
+		*freelist = PyList_New(0);
+		if (!*freelist) {
+			PyMem_FREE(ptr);
+			return -1;
+		}
+	}
+	cobj = PyCObject_FromVoidPtr(ptr, NULL);
+	if (!cobj) {
+		PyMem_FREE(ptr);
+		return -1;
+	}
+	if(PyList_Append(*freelist, cobj)) {
+                PyMem_FREE(ptr);
+		Py_DECREF(cobj);
+		return -1;
+	}
+        Py_DECREF(cobj);
+	return 0;
+}
+
+static int
+cleanreturn(int retval, PyObject *freelist)
+{
+	if(freelist) {
+		if((retval) == 0) {
+			Py_ssize_t len = PyList_GET_SIZE(freelist), i;
+			for (i = 0; i < len; i++)
+                                PyMem_FREE(PyCObject_AsVoidPtr(
+                                		PyList_GET_ITEM(freelist, i)));
+		}
+		Py_DECREF(freelist);
+	}
+	return retval;
+}
+
+
+static int
+vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
+{
+	char msgbuf[256];
+	int levels[32];
+	const char *fname = NULL;
+	const char *message = NULL;
+	int min = -1;
+	int max = 0;
+	int level = 0;
+	int endfmt = 0;
+	const char *formatsave = format;
+	Py_ssize_t i, len;
+	char *msg;
+	PyObject *freelist = NULL;
+	int compat = flags & FLAG_COMPAT;
+
+	assert(compat || (args != (PyObject*)NULL));
+	flags = flags & ~FLAG_COMPAT;
+
+	while (endfmt == 0) {
+		int c = *format++;
+		switch (c) {
+		case '(':
+			if (level == 0)
+				max++;
+			level++;
+			if (level >= 30)
+				Py_FatalError("too many tuple nesting levels "
+					      "in argument format string");
+			break;
+		case ')':
+			if (level == 0)
+				Py_FatalError("excess ')' in getargs format");
+			else
+				level--;
+			break;
+		case '\0':
+			endfmt = 1;
+			break;
+		case ':':
+			fname = format;
+			endfmt = 1;
+			break;
+		case ';':
+			message = format;
+			endfmt = 1;
+			break;
+		default:
+			if (level == 0) {
+				if (c == 'O')
+					max++;
+				else if (isalpha(Py_CHARMASK(c))) {
+					if (c != 'e') /* skip encoded */
+						max++;
+				} else if (c == '|')
+					min = max;
+			}
+			break;
+		}
+	}
+	
+	if (level != 0)
+		Py_FatalError(/* '(' */ "missing ')' in getargs format");
+	
+	if (min < 0)
+		min = max;
+	
+	format = formatsave;
+	
+	if (compat) {
+		if (max == 0) {
+			if (args == NULL)
+				return 1;
+			PyOS_snprintf(msgbuf, sizeof(msgbuf),
+				      "%.200s%s takes no arguments",
+				      fname==NULL ? "function" : fname,
+				      fname==NULL ? "" : "()");
+			PyErr_SetString(PyExc_TypeError, msgbuf);
+			return 0;
+		}
+		else if (min == 1 && max == 1) {
+			if (args == NULL) {
+				PyOS_snprintf(msgbuf, sizeof(msgbuf),
+				      "%.200s%s takes at least one argument",
+					      fname==NULL ? "function" : fname,
+					      fname==NULL ? "" : "()");
+				PyErr_SetString(PyExc_TypeError, msgbuf);
+				return 0;
+			}
+			msg = convertitem(args, &format, p_va, flags, levels, 
+					  msgbuf, sizeof(msgbuf), &freelist);
+			if (msg == NULL)
+				return cleanreturn(1, freelist);
+			seterror(levels[0], msg, levels+1, fname, message);
+			return cleanreturn(0, freelist);
+		}
+		else {
+			PyErr_SetString(PyExc_SystemError,
+			    "old style getargs format uses new features");
+			return 0;
+		}
+	}
+	
+	if (!PyTuple_Check(args)) {
+		PyErr_SetString(PyExc_SystemError,
+		    "new style getargs format but argument is not a tuple");
+		return 0;
+	}
+	
+	len = PyTuple_GET_SIZE(args);
+	
+	if (len < min || max < len) {
+		if (message == NULL) {
+			PyOS_snprintf(msgbuf, sizeof(msgbuf),
+				      "%.150s%s takes %s %d argument%s "
+				      "(%ld given)",
+				      fname==NULL ? "function" : fname,
+				      fname==NULL ? "" : "()",
+				      min==max ? "exactly"
+				      : len < min ? "at least" : "at most",
+				      len < min ? min : max,
+				      (len < min ? min : max) == 1 ? "" : "s",
+				      Py_SAFE_DOWNCAST(len, Py_ssize_t, long));
+			message = msgbuf;
+		}
+		PyErr_SetString(PyExc_TypeError, message);
+		return 0;
+	}
+	
+	for (i = 0; i < len; i++) {
+		if (*format == '|')
+			format++;
+		msg = convertitem(PyTuple_GET_ITEM(args, i), &format, p_va,
+				  flags, levels, msgbuf, 
+				  sizeof(msgbuf), &freelist);
+		if (msg) {
+			seterror(i+1, msg, levels, fname, message);
+			return cleanreturn(0, freelist);
+		}
+	}
+
+	if (*format != '\0' && !isalpha(Py_CHARMASK(*format)) &&
+	    *format != '(' &&
+	    *format != '|' && *format != ':' && *format != ';') {
+		PyErr_Format(PyExc_SystemError,
+			     "bad format string: %.200s", formatsave);
+		return cleanreturn(0, freelist);
+	}
+	
+	return cleanreturn(1, freelist);
+}
+
+
+
+static void
+seterror(int iarg, const char *msg, int *levels, const char *fname,
+         const char *message)
+{
+	char buf[512];
+	int i;
+	char *p = buf;
+
+	if (PyErr_Occurred())
+		return;
+	else if (message == NULL) {
+		if (fname != NULL) {
+			PyOS_snprintf(p, sizeof(buf), "%.200s() ", fname);
+			p += strlen(p);
+		}
+		if (iarg != 0) {
+			PyOS_snprintf(p, sizeof(buf) - (p - buf),
+				      "argument %d", iarg);
+			i = 0;
+			p += strlen(p);
+			while (levels[i] > 0 && i < 32 && (int)(p-buf) < 220) {
+				PyOS_snprintf(p, sizeof(buf) - (p - buf),
+					      ", item %d", levels[i]-1);
+				p += strlen(p);
+				i++;
+			}
+		}
+		else {
+			PyOS_snprintf(p, sizeof(buf) - (p - buf), "argument");
+			p += strlen(p);
+		}
+		PyOS_snprintf(p, sizeof(buf) - (p - buf), " %.256s", msg);
+		message = buf;
+	}
+	PyErr_SetString(PyExc_TypeError, message);
+}
+
+
+/* Convert a tuple argument.
+   On entry, *p_format points to the character _after_ the opening '('.
+   On successful exit, *p_format points to the closing ')'.
+   If successful:
+      *p_format and *p_va are updated,
+      *levels and *msgbuf are untouched,
+      and NULL is returned.
+   If the argument is invalid:
+      *p_format is unchanged,
+      *p_va is undefined,
+      *levels is a 0-terminated list of item numbers,
+      *msgbuf contains an error message, whose format is:
+         "must be <typename1>, not <typename2>", where:
+            <typename1> is the name of the expected type, and
+            <typename2> is the name of the actual type,
+      and msgbuf is returned.
+*/
+
+static char *
+converttuple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
+             int *levels, char *msgbuf, size_t bufsize, int toplevel, 
+             PyObject **freelist)
+{
+	int level = 0;
+	int n = 0;
+	const char *format = *p_format;
+	int i;
+	
+	for (;;) {
+		int c = *format++;
+		if (c == '(') {
+			if (level == 0)
+				n++;
+			level++;
+		}
+		else if (c == ')') {
+			if (level == 0)
+				break;
+			level--;
+		}
+		else if (c == ':' || c == ';' || c == '\0')
+			break;
+		else if (level == 0 && isalpha(Py_CHARMASK(c)))
+			n++;
+	}
+	
+	if (!PySequence_Check(arg) || PyString_Check(arg)) {
+		levels[0] = 0;
+		PyOS_snprintf(msgbuf, bufsize,
+			      toplevel ? "expected %d arguments, not %.50s" :
+			              "must be %d-item sequence, not %.50s",
+			      n, 
+			      arg == Py_None ? "None" : arg->ob_type->tp_name);
+		return msgbuf;
+	}
+	
+	if ((i = PySequence_Size(arg)) != n) {
+		levels[0] = 0;
+		PyOS_snprintf(msgbuf, bufsize,
+			      toplevel ? "expected %d arguments, not %d" :
+			             "must be sequence of length %d, not %d",
+			      n, i);
+		return msgbuf;
+	}
+
+	format = *p_format;
+	for (i = 0; i < n; i++) {
+		char *msg;
+		PyObject *item;
+		item = PySequence_GetItem(arg, i);
+		if (item == NULL) {
+			PyErr_Clear();
+			levels[0] = i+1;
+			levels[1] = 0;
+			strncpy(msgbuf, "is not retrievable", bufsize);
+			return msgbuf;
+		}
+		msg = convertitem(item, &format, p_va, flags, levels+1, 
+				  msgbuf, bufsize, freelist);
+		/* PySequence_GetItem calls tp->sq_item, which INCREFs */
+		Py_XDECREF(item);
+		if (msg != NULL) {
+			levels[0] = i+1;
+			return msg;
+		}
+	}
+
+	*p_format = format;
+	return NULL;
+}
+
+
+/* Convert a single item. */
+
+static char *
+convertitem(PyObject *arg, const char **p_format, va_list *p_va, int flags,
+            int *levels, char *msgbuf, size_t bufsize, PyObject **freelist)
+{
+	char *msg;
+	const char *format = *p_format;
+	
+	if (*format == '(' /* ')' */) {
+		format++;
+		msg = converttuple(arg, &format, p_va, flags, levels, msgbuf, 
+				   bufsize, 0, freelist);
+		if (msg == NULL)
+			format++;
+	}
+	else {
+		msg = convertsimple(arg, &format, p_va, flags, 
+				    msgbuf, bufsize, freelist);
+		if (msg != NULL)
+			levels[0] = 0;
+	}
+	if (msg == NULL)
+		*p_format = format;
+	return msg;
+}
+
+
+
+#define UNICODE_DEFAULT_ENCODING(arg) \
+        _PyUnicode_AsDefaultEncodedString(arg, NULL)
+
+/* Format an error message generated by convertsimple(). */
+
+static char *
+converterr(const char *expected, PyObject *arg, char *msgbuf, size_t bufsize)
+{
+	assert(expected != NULL);
+	assert(arg != NULL); 
+	PyOS_snprintf(msgbuf, bufsize,
+		      "must be %.50s, not %.50s", expected,
+		      arg == Py_None ? "None" : arg->ob_type->tp_name);
+	return msgbuf;
+}
+
+#define CONV_UNICODE "(unicode conversion error)"
+
+/* explicitly check for float arguments when integers are expected.  For now
+ * signal a warning.  Returns true if an exception was raised. */
+static int
+float_argument_error(PyObject *arg)
+{
+	if (PyFloat_Check(arg) &&
+	    PyErr_Warn(PyExc_DeprecationWarning,
+		       "integer argument expected, got float" ))
+		return 1;
+	else
+		return 0;
+}
+
+/* Convert a non-tuple argument.  Return NULL if conversion went OK,
+   or a string with a message describing the failure.  The message is
+   formatted as "must be <desired type>, not <actual type>".
+   When failing, an exception may or may not have been raised.
+   Don't call if a tuple is expected.
+
+   When you add new format codes, please don't forget poor skipitem() below.
+*/
+
+static char *
+convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
+              char *msgbuf, size_t bufsize, PyObject **freelist)
+{
+	/* For # codes */
+#define FETCH_SIZE	int *q=NULL;Py_ssize_t *q2=NULL;\
+	if (flags & FLAG_SIZE_T) q2=va_arg(*p_va, Py_ssize_t*); \
+	else q=va_arg(*p_va, int*);
+#define STORE_SIZE(s)   if (flags & FLAG_SIZE_T) *q2=s; else *q=s;
+#define BUFFER_LEN      ((flags & FLAG_SIZE_T) ? *q2:*q)
+
+	const char *format = *p_format;
+	char c = *format++;
+#ifdef Py_USING_UNICODE
+	PyObject *uarg;
+#endif
+	
+	switch (c) {
+	
+	case 'b': { /* unsigned byte -- very short int */
+		char *p = va_arg(*p_va, char *);
+		long ival;
+		if (float_argument_error(arg))
+			return converterr("integer<b>", arg, msgbuf, bufsize);
+		ival = PyInt_AsLong(arg);
+		if (ival == -1 && PyErr_Occurred())
+			return converterr("integer<b>", arg, msgbuf, bufsize);
+		else if (ival < 0) {
+			PyErr_SetString(PyExc_OverflowError,
+			"unsigned byte integer is less than minimum");
+			return converterr("integer<b>", arg, msgbuf, bufsize);
+		}
+		else if (ival > UCHAR_MAX) {
+			PyErr_SetString(PyExc_OverflowError,
+			"unsigned byte integer is greater than maximum");
+			return converterr("integer<b>", arg, msgbuf, bufsize);
+		}
+		else
+			*p = (unsigned char) ival;
+		break;
+	}
+	
+	case 'B': {/* byte sized bitfield - both signed and unsigned
+		      values allowed */  
+		char *p = va_arg(*p_va, char *);
+		long ival;
+		if (float_argument_error(arg))
+			return converterr("integer<B>", arg, msgbuf, bufsize);
+		ival = PyInt_AsUnsignedLongMask(arg);
+		if (ival == -1 && PyErr_Occurred())
+			return converterr("integer<B>", arg, msgbuf, bufsize);
+		else
+			*p = (unsigned char) ival;
+		break;
+	}
+	
+	case 'h': {/* signed short int */
+		short *p = va_arg(*p_va, short *);
+		long ival;
+		if (float_argument_error(arg))
+			return converterr("integer<h>", arg, msgbuf, bufsize);
+		ival = PyInt_AsLong(arg);
+		if (ival == -1 && PyErr_Occurred())
+			return converterr("integer<h>", arg, msgbuf, bufsize);
+		else if (ival < SHRT_MIN) {
+			PyErr_SetString(PyExc_OverflowError,
+			"signed short integer is less than minimum");
+			return converterr("integer<h>", arg, msgbuf, bufsize);
+		}
+		else if (ival > SHRT_MAX) {
+			PyErr_SetString(PyExc_OverflowError,
+			"signed short integer is greater than maximum");
+			return converterr("integer<h>", arg, msgbuf, bufsize);
+		}
+		else
+			*p = (short) ival;
+		break;
+	}
+	
+	case 'H': { /* short int sized bitfield, both signed and
+		       unsigned allowed */ 
+		unsigned short *p = va_arg(*p_va, unsigned short *);
+		long ival;
+		if (float_argument_error(arg))
+			return converterr("integer<H>", arg, msgbuf, bufsize);
+		ival = PyInt_AsUnsignedLongMask(arg);
+		if (ival == -1 && PyErr_Occurred())
+			return converterr("integer<H>", arg, msgbuf, bufsize);
+		else
+			*p = (unsigned short) ival;
+		break;
+	}
+
+	case 'i': {/* signed int */
+		int *p = va_arg(*p_va, int *);
+		long ival;
+		if (float_argument_error(arg))
+			return converterr("integer<i>", arg, msgbuf, bufsize);
+		ival = PyInt_AsLong(arg);
+		if (ival == -1 && PyErr_Occurred())
+			return converterr("integer<i>", arg, msgbuf, bufsize);
+		else if (ival > INT_MAX) {
+			PyErr_SetString(PyExc_OverflowError,
+				"signed integer is greater than maximum");
+			return converterr("integer<i>", arg, msgbuf, bufsize);
+		}
+		else if (ival < INT_MIN) {
+			PyErr_SetString(PyExc_OverflowError,
+				"signed integer is less than minimum");
+			return converterr("integer<i>", arg, msgbuf, bufsize);
+		}
+		else
+			*p = ival;
+		break;
+	}
+
+	case 'I': { /* int sized bitfield, both signed and
+		       unsigned allowed */ 
+		unsigned int *p = va_arg(*p_va, unsigned int *);
+		unsigned int ival;
+		if (float_argument_error(arg))
+			return converterr("integer<I>", arg, msgbuf, bufsize);
+		ival = (unsigned int)PyInt_AsUnsignedLongMask(arg);
+		if (ival == (unsigned int)-1 && PyErr_Occurred())
+			return converterr("integer<I>", arg, msgbuf, bufsize);
+		else
+			*p = ival;
+		break;
+	}
+	
+	case 'n': /* Py_ssize_t */
+#if SIZEOF_SIZE_T != SIZEOF_LONG
+	{
+		Py_ssize_t *p = va_arg(*p_va, Py_ssize_t *);
+		Py_ssize_t ival;
+		if (float_argument_error(arg))
+			return converterr("integer<n>", arg, msgbuf, bufsize);
+		ival = PyInt_AsSsize_t(arg);
+		if (ival == -1 && PyErr_Occurred())
+			return converterr("integer<n>", arg, msgbuf, bufsize);
+		*p = ival;
+		break;
+	}
+#endif
+	/* Fall through from 'n' to 'l' if Py_ssize_t is int */
+	case 'l': {/* long int */
+		long *p = va_arg(*p_va, long *);
+		long ival;
+		if (float_argument_error(arg))
+			return converterr("integer<l>", arg, msgbuf, bufsize);
+		ival = PyInt_AsLong(arg);
+		if (ival == -1 && PyErr_Occurred())
+			return converterr("integer<l>", arg, msgbuf, bufsize);
+		else
+			*p = ival;
+		break;
+	}
+
+	case 'k': { /* long sized bitfield */
+		unsigned long *p = va_arg(*p_va, unsigned long *);
+		unsigned long ival;
+		if (PyInt_Check(arg))
+			ival = PyInt_AsUnsignedLongMask(arg);
+		else if (PyLong_Check(arg))
+			ival = PyLong_AsUnsignedLongMask(arg);
+		else
+			return converterr("integer<k>", arg, msgbuf, bufsize);
+		*p = ival;
+		break;
+	}
+	
+#ifdef HAVE_LONG_LONG
+	case 'L': {/* PY_LONG_LONG */
+		PY_LONG_LONG *p = va_arg( *p_va, PY_LONG_LONG * );
+		PY_LONG_LONG ival = PyLong_AsLongLong( arg );
+		if( ival == (PY_LONG_LONG)-1 && PyErr_Occurred() ) {
+			return converterr("long<L>", arg, msgbuf, bufsize);
+		} else {
+			*p = ival;
+		}
+		break;
+	}
+
+	case 'K': { /* long long sized bitfield */
+		unsigned PY_LONG_LONG *p = va_arg(*p_va, unsigned PY_LONG_LONG *);
+		unsigned PY_LONG_LONG ival;
+		if (PyInt_Check(arg))
+			ival = PyInt_AsUnsignedLongMask(arg);
+		else if (PyLong_Check(arg))
+			ival = PyLong_AsUnsignedLongLongMask(arg);
+		else
+			return converterr("integer<K>", arg, msgbuf, bufsize);
+		*p = ival;
+		break;
+	}
+#endif
+	
+	case 'f': {/* float */
+		float *p = va_arg(*p_va, float *);
+		double dval = PyFloat_AsDouble(arg);
+		if (PyErr_Occurred())
+			return converterr("float<f>", arg, msgbuf, bufsize);
+		else
+			*p = (float) dval;
+		break;
+	}
+	
+	case 'd': {/* double */
+		double *p = va_arg(*p_va, double *);
+		double dval = PyFloat_AsDouble(arg);
+		if (PyErr_Occurred())
+			return converterr("float<d>", arg, msgbuf, bufsize);
+		else
+			*p = dval;
+		break;
+	}
+	
+#ifndef WITHOUT_COMPLEX
+	case 'D': {/* complex double */
+		Py_complex *p = va_arg(*p_va, Py_complex *);
+		Py_complex cval;
+		cval = PyComplex_AsCComplex(arg);
+		if (PyErr_Occurred())
+			return converterr("complex<D>", arg, msgbuf, bufsize);
+		else
+			*p = cval;
+		break;
+	}
+#endif /* WITHOUT_COMPLEX */
+	
+	case 'c': {/* char */
+		char *p = va_arg(*p_va, char *);
+		if (PyString_Check(arg) && PyString_Size(arg) == 1)
+			*p = PyString_AS_STRING(arg)[0];
+		else
+			return converterr("char", arg, msgbuf, bufsize);
+		break;
+	}
+	
+	case 's': {/* string */
+		if (*format == '#') {
+			void **p = (void **)va_arg(*p_va, char **);
+			FETCH_SIZE;
+			
+			if (PyString_Check(arg)) {
+				*p = PyString_AS_STRING(arg);
+				STORE_SIZE(PyString_GET_SIZE(arg));
+			}
+#ifdef Py_USING_UNICODE
+			else if (PyUnicode_Check(arg)) {
+				uarg = UNICODE_DEFAULT_ENCODING(arg);
+				if (uarg == NULL)
+					return converterr(CONV_UNICODE,
+							  arg, msgbuf, bufsize);
+				*p = PyString_AS_STRING(uarg);
+				STORE_SIZE(PyString_GET_SIZE(uarg));
+			}
+#endif
+			else { /* any buffer-like object */
+				char *buf;
+				Py_ssize_t count = convertbuffer(arg, p, &buf);
+				if (count < 0)
+					return converterr(buf, arg, msgbuf, bufsize);
+				STORE_SIZE(count);
+			}
+			format++;
+		} else {
+			char **p = va_arg(*p_va, char **);
+			
+			if (PyString_Check(arg))
+				*p = PyString_AS_STRING(arg);
+#ifdef Py_USING_UNICODE
+			else if (PyUnicode_Check(arg)) {
+				uarg = UNICODE_DEFAULT_ENCODING(arg);
+				if (uarg == NULL)
+					return converterr(CONV_UNICODE,
+							  arg, msgbuf, bufsize);
+				*p = PyString_AS_STRING(uarg);
+			}
+#endif
+			else
+				return converterr("string", arg, msgbuf, bufsize);
+			if ((Py_ssize_t)strlen(*p) != PyString_Size(arg))
+				return converterr("string without null bytes",
+						  arg, msgbuf, bufsize);
+		}
+		break;
+	}
+
+	case 'z': {/* string, may be NULL (None) */
+		if (*format == '#') { /* any buffer-like object */
+			void **p = (void **)va_arg(*p_va, char **);
+			FETCH_SIZE;
+			
+			if (arg == Py_None) {
+				*p = 0;
+				STORE_SIZE(0);
+			}
+			else if (PyString_Check(arg)) {
+				*p = PyString_AS_STRING(arg);
+				STORE_SIZE(PyString_GET_SIZE(arg));
+			}
+#ifdef Py_USING_UNICODE
+			else if (PyUnicode_Check(arg)) {
+				uarg = UNICODE_DEFAULT_ENCODING(arg);
+				if (uarg == NULL)
+					return converterr(CONV_UNICODE,
+							  arg, msgbuf, bufsize);
+				*p = PyString_AS_STRING(uarg);
+				STORE_SIZE(PyString_GET_SIZE(uarg));
+			}
+#endif
+			else { /* any buffer-like object */
+				char *buf;
+				Py_ssize_t count = convertbuffer(arg, p, &buf);
+				if (count < 0)
+					return converterr(buf, arg, msgbuf, bufsize);
+				STORE_SIZE(count);
+			}
+			format++;
+		} else {
+			char **p = va_arg(*p_va, char **);
+			
+			if (arg == Py_None)
+				*p = 0;
+			else if (PyString_Check(arg))
+				*p = PyString_AS_STRING(arg);
+#ifdef Py_USING_UNICODE
+			else if (PyUnicode_Check(arg)) {
+				uarg = UNICODE_DEFAULT_ENCODING(arg);
+				if (uarg == NULL)
+					return converterr(CONV_UNICODE,
+							  arg, msgbuf, bufsize);
+				*p = PyString_AS_STRING(uarg);
+			}
+#endif
+			else
+				return converterr("string or None", 
+						  arg, msgbuf, bufsize);
+			if (*format == '#') {
+				FETCH_SIZE;
+				assert(0); /* XXX redundant with if-case */
+				if (arg == Py_None)
+					*q = 0;
+				else
+					*q = PyString_Size(arg);
+				format++;
+			}
+			else if (*p != NULL &&
+				 (Py_ssize_t)strlen(*p) != PyString_Size(arg))
+				return converterr(
+					"string without null bytes or None", 
+					arg, msgbuf, bufsize);
+		}
+		break;
+	}
+	
+	case 'e': {/* encoded string */
+		char **buffer;
+		const char *encoding;
+		PyObject *s;
+		int size, recode_strings;
+
+		/* Get 'e' parameter: the encoding name */
+		encoding = (const char *)va_arg(*p_va, const char *);
+#ifdef Py_USING_UNICODE
+		if (encoding == NULL)
+			encoding = PyUnicode_GetDefaultEncoding();
+#endif
+			
+		/* Get output buffer parameter:
+		   's' (recode all objects via Unicode) or
+		   't' (only recode non-string objects) 
+		*/
+		if (*format == 's')
+			recode_strings = 1;
+		else if (*format == 't')
+			recode_strings = 0;
+		else
+			return converterr(
+				"(unknown parser marker combination)",
+				arg, msgbuf, bufsize);
+		buffer = (char **)va_arg(*p_va, char **);
+		format++;
+		if (buffer == NULL)
+			return converterr("(buffer is NULL)", 
+					  arg, msgbuf, bufsize);
+			
+		/* Encode object */
+		if (!recode_strings && PyString_Check(arg)) {
+			s = arg;
+			Py_INCREF(s);
+		}
+		else {
+#ifdef Py_USING_UNICODE
+		    	PyObject *u;
+
+			/* Convert object to Unicode */
+			u = PyUnicode_FromObject(arg);
+			if (u == NULL)
+				return converterr(
+					"string or unicode or text buffer", 
+					arg, msgbuf, bufsize);
+			
+			/* Encode object; use default error handling */
+			s = PyUnicode_AsEncodedString(u,
+						      encoding,
+						      NULL);
+			Py_DECREF(u);
+			if (s == NULL)
+				return converterr("(encoding failed)",
+						  arg, msgbuf, bufsize);
+			if (!PyString_Check(s)) {
+				Py_DECREF(s);
+				return converterr(
+					"(encoder failed to return a string)",
+					arg, msgbuf, bufsize);
+			}
+#else
+			return converterr("string<e>", arg, msgbuf, bufsize);
+#endif
+		}
+		size = PyString_GET_SIZE(s);
+
+		/* Write output; output is guaranteed to be 0-terminated */
+		if (*format == '#') { 
+			/* Using buffer length parameter '#':
+				   
+			   - if *buffer is NULL, a new buffer of the
+			   needed size is allocated and the data
+			   copied into it; *buffer is updated to point
+			   to the new buffer; the caller is
+			   responsible for PyMem_Free()ing it after
+			   usage 
+
+			   - if *buffer is not NULL, the data is
+			   copied to *buffer; *buffer_len has to be
+			   set to the size of the buffer on input;
+			   buffer overflow is signalled with an error;
+			   buffer has to provide enough room for the
+			   encoded string plus the trailing 0-byte
+			   
+			   - in both cases, *buffer_len is updated to
+			   the size of the buffer /excluding/ the
+			   trailing 0-byte 
+			   
+			*/
+			FETCH_SIZE;
+
+			format++;
+			if (q == NULL && q2 == NULL) {
+				Py_DECREF(s);
+				return converterr(
+					"(buffer_len is NULL)",
+					arg, msgbuf, bufsize);
+			}
+			if (*buffer == NULL) {
+				*buffer = PyMem_NEW(char, size + 1);
+				if (*buffer == NULL) {
+					Py_DECREF(s);
+					return converterr(
+						"(memory error)",
+						arg, msgbuf, bufsize);
+				}
+				if(addcleanup(*buffer, freelist)) {
+					Py_DECREF(s);
+					return converterr(
+						"(cleanup problem)",
+						arg, msgbuf, bufsize);
+				}
+			} else {
+				if (size + 1 > BUFFER_LEN) {
+					Py_DECREF(s);
+					return converterr(
+						"(buffer overflow)", 
+						arg, msgbuf, bufsize);
+				}
+			}
+			memcpy(*buffer,
+			       PyString_AS_STRING(s),
+			       size + 1);
+			STORE_SIZE(size);
+		} else {
+			/* Using a 0-terminated buffer:
+				   
+			   - the encoded string has to be 0-terminated
+			   for this variant to work; if it is not, an
+			   error raised 
+
+			   - a new buffer of the needed size is
+			   allocated and the data copied into it;
+			   *buffer is updated to point to the new
+			   buffer; the caller is responsible for
+			   PyMem_Free()ing it after usage
+
+			*/
+			if ((Py_ssize_t)strlen(PyString_AS_STRING(s))
+								!= size) {
+				Py_DECREF(s);
+				return converterr(
+					"(encoded string without NULL bytes)",
+					arg, msgbuf, bufsize);
+			}
+			*buffer = PyMem_NEW(char, size + 1);
+			if (*buffer == NULL) {
+				Py_DECREF(s);
+				return converterr("(memory error)",
+						  arg, msgbuf, bufsize);
+			}
+			if(addcleanup(*buffer, freelist)) {
+				Py_DECREF(s);
+				return converterr("(cleanup problem)",
+						arg, msgbuf, bufsize);
+			}
+			memcpy(*buffer,
+			       PyString_AS_STRING(s),
+			       size + 1);
+		}
+		Py_DECREF(s);
+		break;
+	}
+
+#ifdef Py_USING_UNICODE
+	case 'u': {/* raw unicode buffer (Py_UNICODE *) */
+		if (*format == '#') { /* any buffer-like object */
+			void **p = (void **)va_arg(*p_va, char **);
+			FETCH_SIZE;
+			if (PyUnicode_Check(arg)) {
+			    	*p = PyUnicode_AS_UNICODE(arg);
+				STORE_SIZE(PyUnicode_GET_SIZE(arg));
+			}
+			else {
+				return converterr("cannot convert raw buffers",
+						  arg, msgbuf, bufsize);
+			}
+			format++;
+		} else {
+			Py_UNICODE **p = va_arg(*p_va, Py_UNICODE **);
+			if (PyUnicode_Check(arg))
+				*p = PyUnicode_AS_UNICODE(arg);
+			else
+				return converterr("unicode", arg, msgbuf, bufsize);
+		}
+		break;
+	}
+#endif
+
+	case 'S': { /* string object */
+		PyObject **p = va_arg(*p_va, PyObject **);
+		if (PyString_Check(arg))
+			*p = arg;
+		else
+			return converterr("string", arg, msgbuf, bufsize);
+		break;
+	}
+	
+#ifdef Py_USING_UNICODE
+	case 'U': { /* Unicode object */
+		PyObject **p = va_arg(*p_va, PyObject **);
+		if (PyUnicode_Check(arg))
+			*p = arg;
+		else
+			return converterr("unicode", arg, msgbuf, bufsize);
+		break;
+	}
+#endif
+	
+	case 'O': { /* object */
+		PyTypeObject *type;
+		PyObject **p;
+		if (*format == '!') {
+			type = va_arg(*p_va, PyTypeObject*);
+			p = va_arg(*p_va, PyObject **);
+			format++;
+			if (PyType_IsSubtype(arg->ob_type, type))
+				*p = arg;
+			else
+				return converterr(type->tp_name, arg, msgbuf, bufsize);
+
+		}
+		else if (*format == '?') {
+			inquiry pred = va_arg(*p_va, inquiry);
+			p = va_arg(*p_va, PyObject **);
+			format++;
+			if ((*pred)(arg)) 
+				*p = arg;
+			else
+				return converterr("(unspecified)", 
+						  arg, msgbuf, bufsize);
+				
+		}
+		else if (*format == '&') {
+			typedef int (*converter)(PyObject *, void *);
+			converter convert = va_arg(*p_va, converter);
+			void *addr = va_arg(*p_va, void *);
+			format++;
+			if (! (*convert)(arg, addr))
+				return converterr("(unspecified)", 
+						  arg, msgbuf, bufsize);
+		}
+		else {
+			p = va_arg(*p_va, PyObject **);
+			*p = arg;
+		}
+		break;
+	}
+		
+		
+	case 'w': { /* memory buffer, read-write access */
+		void **p = va_arg(*p_va, void **);
+		PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
+		int count;
+			
+		if (pb == NULL || 
+		    pb->bf_getwritebuffer == NULL ||
+		    pb->bf_getsegcount == NULL)
+			return converterr("read-write buffer", arg, msgbuf, bufsize);
+		if ((*pb->bf_getsegcount)(arg, NULL) != 1)
+			return converterr("single-segment read-write buffer", 
+					  arg, msgbuf, bufsize);
+		if ((count = pb->bf_getwritebuffer(arg, 0, p)) < 0)
+			return converterr("(unspecified)", arg, msgbuf, bufsize);
+		if (*format == '#') {
+			FETCH_SIZE;
+			STORE_SIZE(count);
+			format++;
+		}
+		break;
+	}
+		
+	case 't': { /* 8-bit character buffer, read-only access */
+		char **p = va_arg(*p_va, char **);
+		PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
+		int count;
+		
+		if (*format++ != '#')
+			return converterr(
+				"invalid use of 't' format character", 
+				arg, msgbuf, bufsize);
+		if (!PyType_HasFeature(arg->ob_type,
+				       Py_TPFLAGS_HAVE_GETCHARBUFFER) ||
+		    pb == NULL || pb->bf_getcharbuffer == NULL ||
+		    pb->bf_getsegcount == NULL)
+			return converterr(
+				"string or read-only character buffer",
+				arg, msgbuf, bufsize);
+
+		if (pb->bf_getsegcount(arg, NULL) != 1)
+			return converterr(
+				"string or single-segment read-only buffer",
+				arg, msgbuf, bufsize);
+
+		count = pb->bf_getcharbuffer(arg, 0, p);
+		if (count < 0)
+			return converterr("(unspecified)", arg, msgbuf, bufsize);
+		{
+			FETCH_SIZE;
+			STORE_SIZE(count);
+		}
+		break;
+	}
+
+	default:
+		return converterr("impossible<bad format char>", arg, msgbuf, bufsize);
+	
+	}
+	
+	*p_format = format;
+	return NULL;
+}
+
+static Py_ssize_t
+convertbuffer(PyObject *arg, void **p, char **errmsg)
+{
+	PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
+	Py_ssize_t count;
+	if (pb == NULL ||
+	    pb->bf_getreadbuffer == NULL ||
+	    pb->bf_getsegcount == NULL) {
+		*errmsg = "string or read-only buffer";
+		return -1;
+	}
+	if ((*pb->bf_getsegcount)(arg, NULL) != 1) {
+		*errmsg = "string or single-segment read-only buffer";
+		return -1;
+	}
+	if ((count = (*pb->bf_getreadbuffer)(arg, 0, p)) < 0) {
+		*errmsg = "(unspecified)";
+	}
+	return count;
+}
+
+/* Support for keyword arguments donated by
+   Geoff Philbrick <philbric at delphi.hks.com> */
+
+/* Return false (0) for error, else true. */
+int
+PyArg_ParseTupleAndKeywords(PyObject *args,
+			    PyObject *keywords,
+			    const char *format, 
+			    char **kwlist, ...)
+{
+	int retval;
+	va_list va;
+
+	if ((args == NULL || !PyTuple_Check(args)) ||
+	    (keywords != NULL && !PyDict_Check(keywords)) ||
+	    format == NULL ||
+	    kwlist == NULL)
+	{
+		PyErr_BadInternalCall();
+		return 0;
+	}
+
+	va_start(va, kwlist);
+	retval = vgetargskeywords(args, keywords, format, kwlist, &va, 0);	
+	va_end(va);
+	return retval;
+}
+
+int
+_PyArg_ParseTupleAndKeywords_SizeT(PyObject *args,
+				  PyObject *keywords,
+				  const char *format, 
+				  char **kwlist, ...)
+{
+	int retval;
+	va_list va;
+
+	if ((args == NULL || !PyTuple_Check(args)) ||
+	    (keywords != NULL && !PyDict_Check(keywords)) ||
+	    format == NULL ||
+	    kwlist == NULL)
+	{
+		PyErr_BadInternalCall();
+		return 0;
+	}
+
+	va_start(va, kwlist);
+	retval = vgetargskeywords(args, keywords, format, 
+				  kwlist, &va, FLAG_SIZE_T);
+	va_end(va);
+	return retval;
+}
+
+
+int
+PyArg_VaParseTupleAndKeywords(PyObject *args,
+                              PyObject *keywords,
+                              const char *format, 
+                              char **kwlist, va_list va)
+{
+	int retval;
+	va_list lva;
+
+	if ((args == NULL || !PyTuple_Check(args)) ||
+	    (keywords != NULL && !PyDict_Check(keywords)) ||
+	    format == NULL ||
+	    kwlist == NULL)
+	{
+		PyErr_BadInternalCall();
+		return 0;
+	}
+
+#ifdef VA_LIST_IS_ARRAY
+	memcpy(lva, va, sizeof(va_list));
+#else
+#ifdef __va_copy
+	__va_copy(lva, va);
+#else
+	lva = va;
+#endif
+#endif
+
+	retval = vgetargskeywords(args, keywords, format, kwlist, &lva, 0);	
+	return retval;
+}
+
+int
+_PyArg_VaParseTupleAndKeywords_SizeT(PyObject *args,
+				    PyObject *keywords,
+				    const char *format, 
+				    char **kwlist, va_list va)
+{
+	int retval;
+	va_list lva;
+
+	if ((args == NULL || !PyTuple_Check(args)) ||
+	    (keywords != NULL && !PyDict_Check(keywords)) ||
+	    format == NULL ||
+	    kwlist == NULL)
+	{
+		PyErr_BadInternalCall();
+		return 0;
+	}
+
+#ifdef VA_LIST_IS_ARRAY
+	memcpy(lva, va, sizeof(va_list));
+#else
+#ifdef __va_copy
+	__va_copy(lva, va);
+#else
+	lva = va;
+#endif
+#endif
+
+	retval = vgetargskeywords(args, keywords, format, 
+				  kwlist, &lva, FLAG_SIZE_T);
+	return retval;
+}
+
+
+static int
+vgetargskeywords(PyObject *args, PyObject *keywords, const char *format,
+	         char **kwlist, va_list *p_va, int flags)
+{
+	char msgbuf[512];
+	int levels[32];
+	const char *fname, *message;
+	int min, max;
+	const char *formatsave;
+	int i, len, nargs, nkeywords;
+	const char *msg;
+	char **p;
+	PyObject *freelist = NULL;
+
+	assert(args != NULL && PyTuple_Check(args));
+	assert(keywords == NULL || PyDict_Check(keywords));
+	assert(format != NULL);
+	assert(kwlist != NULL);
+	assert(p_va != NULL);
+
+	/* Search the format:
+	   message <- error msg, if any (else NULL).
+	   fname <- routine name, if any (else NULL).
+	   min <- # of required arguments, or -1 if all are required.
+	   max <- most arguments (required + optional).
+	   Check that kwlist has a non-NULL entry for each arg.
+	   Raise error if a tuple arg spec is found.
+	*/
+	fname = message = NULL;
+	formatsave = format;
+	p = kwlist;
+	min = -1;
+	max = 0;
+	while ((i = *format++) != '\0') {
+		if (isalpha(Py_CHARMASK(i)) && i != 'e') {
+			max++;
+			if (*p == NULL) {
+				PyErr_SetString(PyExc_RuntimeError,
+					"more argument specifiers than "
+					"keyword list entries");
+				return 0;
+			}
+			p++;
+		}
+		else if (i == '|')
+			min = max;
+		else if (i == ':') {
+			fname = format;
+			break;
+		}
+		else if (i == ';') {
+			message = format;
+			break;
+		}
+		else if (i == '(') {
+			PyErr_SetString(PyExc_RuntimeError,
+				"tuple found in format when using keyword "
+				"arguments");
+			return 0;
+		}
+	}
+	format = formatsave;
+	if (*p != NULL) {
+		PyErr_SetString(PyExc_RuntimeError,
+			"more keyword list entries than "
+			"argument specifiers");
+		return 0;
+	}
+	if (min < 0) {
+		/* All arguments are required. */
+		min = max;
+	}
+
+	nargs = PyTuple_GET_SIZE(args);
+	nkeywords = keywords == NULL ? 0 : PyDict_Size(keywords);
+
+	/* make sure there are no duplicate values for an argument;
+	   its not clear when to use the term "keyword argument vs. 
+	   keyword parameter in messages */
+	if (nkeywords > 0) {
+		for (i = 0; i < nargs; i++) {
+			const char *thiskw = kwlist[i];
+			if (thiskw == NULL)
+				break;
+			if (PyDict_GetItemString(keywords, thiskw)) {
+				PyErr_Format(PyExc_TypeError,
+					"keyword parameter '%s' was given "
+					"by position and by name",
+					thiskw);
+				return 0;
+			}
+			else if (PyErr_Occurred())
+				return 0;
+		}
+	}
+
+	/* required arguments missing from args can be supplied by keyword 
+	   arguments; set len to the number of positional arguments, and,
+	   if that's less than the minimum required, add in the number of
+	   required arguments that are supplied by keywords */
+	len = nargs;
+	if (nkeywords > 0 && nargs < min) {
+		for (i = nargs; i < min; i++) {
+			if (PyDict_GetItemString(keywords, kwlist[i]))
+				len++;
+			else if (PyErr_Occurred())
+				return 0;
+		}
+	}
+
+	/* make sure we got an acceptable number of arguments; the message
+	   is a little confusing with keywords since keyword arguments
+	   which are supplied, but don't match the required arguments
+	   are not included in the "%d given" part of the message 
+	   XXX and this isn't a bug!? */
+	if (len < min || max < len) {
+		if (message == NULL) {
+			PyOS_snprintf(msgbuf, sizeof(msgbuf),
+				      "%.200s%s takes %s %d argument%s "
+				      "(%d given)",
+				      fname==NULL ? "function" : fname,
+				      fname==NULL ? "" : "()",
+				      min==max ? "exactly"
+			              : len < min ? "at least" : "at most",
+				      len < min ? min : max,
+				      (len < min ? min : max) == 1 ? "" : "s",
+				      len);
+			message = msgbuf;
+		}
+		PyErr_SetString(PyExc_TypeError, message);
+		return 0;
+	}
+
+	/* convert the positional arguments */
+	for (i = 0; i < nargs; i++) {
+		if (*format == '|')
+			format++;
+		msg = convertitem(PyTuple_GET_ITEM(args, i), &format, p_va,
+				  flags, levels, msgbuf, sizeof(msgbuf), 
+				  &freelist);
+		if (msg) {
+			seterror(i+1, msg, levels, fname, message);
+			return cleanreturn(0, freelist);
+		}
+	}
+
+	/* handle no keyword parameters in call */	
+	if (nkeywords == 0)
+		return cleanreturn(1, freelist);
+
+	/* convert the keyword arguments; this uses the format 
+	   string where it was left after processing args */
+	for (i = nargs; i < max; i++) {
+		PyObject *item;
+		if (*format == '|')
+			format++;
+		item = PyDict_GetItemString(keywords, kwlist[i]);
+		if (item != NULL) {
+			Py_INCREF(item);
+			msg = convertitem(item, &format, p_va, flags, levels, 
+					  msgbuf, sizeof(msgbuf), &freelist);
+			Py_DECREF(item);
+			if (msg) {
+				seterror(i+1, msg, levels, fname, message);
+				return cleanreturn(0, freelist);
+			}
+			--nkeywords;
+			if (nkeywords == 0)
+				break;
+		}
+		else if (PyErr_Occurred())
+			return cleanreturn(0, freelist);
+		else {
+			msg = skipitem(&format, p_va, flags);
+			if (msg) {
+				levels[0] = 0;
+				seterror(i+1, msg, levels, fname, message);
+				return cleanreturn(0, freelist);
+			}
+		}
+	}
+
+	/* make sure there are no extraneous keyword arguments */
+	if (nkeywords > 0) {
+		PyObject *key, *value;
+		Py_ssize_t pos = 0;
+		while (PyDict_Next(keywords, &pos, &key, &value)) {
+			int match = 0;
+			char *ks;
+			if (!PyString_Check(key)) {
+				PyErr_SetString(PyExc_TypeError, 
+					        "keywords must be strings");
+				return cleanreturn(0, freelist);
+			}
+			ks = PyString_AsString(key);
+			for (i = 0; i < max; i++) {
+				if (!strcmp(ks, kwlist[i])) {
+					match = 1;
+					break;
+				}
+			}
+			if (!match) {
+				PyErr_Format(PyExc_TypeError,
+					     "'%s' is an invalid keyword "
+					     "argument for this function",
+					     ks);
+				return cleanreturn(0, freelist);
+			}
+		}
+	}
+
+	return cleanreturn(1, freelist);
+}
+
+
+static char *
+skipitem(const char **p_format, va_list *p_va, int flags)
+{
+        const char *format = *p_format;
+	char c = *format++;
+	
+	switch (c) {
+
+	/* simple codes
+	 * The individual types (second arg of va_arg) are irrelevant */
+
+	case 'b': /* byte -- very short int */
+	case 'B': /* byte as bitfield */
+	case 'h': /* short int */
+	case 'H': /* short int as bitfield */
+	case 'i': /* int */
+	case 'I': /* int sized bitfield */
+	case 'l': /* long int */
+	case 'k': /* long int sized bitfield */
+#ifdef HAVE_LONG_LONG
+	case 'L': /* PY_LONG_LONG */
+	case 'K': /* PY_LONG_LONG sized bitfield */
+#endif
+	case 'f': /* float */
+	case 'd': /* double */
+#ifndef WITHOUT_COMPLEX
+	case 'D': /* complex double */
+#endif
+	case 'c': /* char */
+		{
+			(void) va_arg(*p_va, void *);
+			break;
+		}
+
+	case 'n': /* Py_ssize_t */
+		{
+			(void) va_arg(*p_va, Py_ssize_t *);
+			break;
+		}
+	
+	/* string codes */
+		
+	case 'e': /* string with encoding */
+		{
+			(void) va_arg(*p_va, const char *);
+			if (!(*format == 's' || *format == 't'))
+				/* after 'e', only 's' and 't' is allowed */
+				goto err;
+			format++;
+			/* explicit fallthrough to string cases */
+		}
+	
+	case 's': /* string */
+	case 'z': /* string or None */
+#ifdef Py_USING_UNICODE
+	case 'u': /* unicode string */
+#endif
+	case 't': /* buffer, read-only */
+	case 'w': /* buffer, read-write */
+		{
+			(void) va_arg(*p_va, char **);
+			if (*format == '#') {
+				if (flags & FLAG_SIZE_T)
+					(void) va_arg(*p_va, Py_ssize_t *);
+				else
+					(void) va_arg(*p_va, int *);
+				format++;
+			}
+			break;
+		}
+
+	/* object codes */
+
+	case 'S': /* string object */
+#ifdef Py_USING_UNICODE
+	case 'U': /* unicode string object */
+#endif
+		{
+			(void) va_arg(*p_va, PyObject **);
+			break;
+		}
+	
+	case 'O': /* object */
+		{
+			if (*format == '!') {
+				format++;
+				(void) va_arg(*p_va, PyTypeObject*);
+				(void) va_arg(*p_va, PyObject **);
+			}
+#if 0
+/* I don't know what this is for */
+			else if (*format == '?') {
+				inquiry pred = va_arg(*p_va, inquiry);
+				format++;
+				if ((*pred)(arg)) {
+					(void) va_arg(*p_va, PyObject **);
+				}
+			}
+#endif
+			else if (*format == '&') {
+				typedef int (*converter)(PyObject *, void *);
+				(void) va_arg(*p_va, converter);
+				(void) va_arg(*p_va, void *);
+				format++;
+			}
+			else {
+				(void) va_arg(*p_va, PyObject **);
+			}
+			break;
+		}
+	
+	default:
+err:
+		return "impossible<bad format char>";
+	
+	}
+
+	/* The "(...)" format code for tuples is not handled here because
+	 * it is not allowed with keyword args. */
+	
+	*p_format = format;
+	return NULL;
+}
+
+
+int
+PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, ...)
+{
+	Py_ssize_t i, l;
+	PyObject **o;
+	va_list vargs;
+
+#ifdef HAVE_STDARG_PROTOTYPES
+	va_start(vargs, max);
+#else
+	va_start(vargs);
+#endif
+
+	assert(min >= 0);
+	assert(min <= max);
+	if (!PyTuple_Check(args)) {
+		PyErr_SetString(PyExc_SystemError,
+		    "PyArg_UnpackTuple() argument list is not a tuple");
+		return 0;
+	}	
+	l = PyTuple_GET_SIZE(args);
+	if (l < min) {
+		if (name != NULL)
+			PyErr_Format(
+			    PyExc_TypeError,
+			    "%s expected %s%zd arguments, got %zd", 
+			    name, (min == max ? "" : "at least "), min, l);
+		else
+			PyErr_Format(
+			    PyExc_TypeError,
+			    "unpacked tuple should have %s%zd elements,"
+			    " but has %zd", 
+			    (min == max ? "" : "at least "), min, l);
+		va_end(vargs);
+		return 0;
+	}
+	if (l > max) {
+		if (name != NULL)
+			PyErr_Format(
+			    PyExc_TypeError,
+			    "%s expected %s%zd arguments, got %zd", 
+			    name, (min == max ? "" : "at most "), max, l);
+		else
+			PyErr_Format(
+			    PyExc_TypeError,
+			    "unpacked tuple should have %s%zd elements,"
+			    " but has %zd", 
+			    (min == max ? "" : "at most "), max, l);
+		va_end(vargs);
+		return 0;
+	}
+	for (i = 0; i < l; i++) {
+		o = va_arg(vargs, PyObject **);
+		*o = PyTuple_GET_ITEM(args, i);
+	}
+	va_end(vargs);
+	return 1;
+}
+
+
+/* For type constructors that don't take keyword args
+ *
+ * Sets a TypeError and returns 0 if the kwds dict is 
+ * not emtpy, returns 1 otherwise
+ */
+int
+_PyArg_NoKeywords(const char *funcname, PyObject *kw)
+{
+	if (kw == NULL)
+		return 1;
+	if (!PyDict_CheckExact(kw)) {
+		PyErr_BadInternalCall();
+		return 0;
+	}
+	if (PyDict_Size(kw) == 0)
+		return 1;
+	
+	PyErr_Format(PyExc_TypeError, "%s does not take keyword arguments", 
+			funcname);
+	return 0;
+}
+#ifdef __cplusplus
+};
+#endif

Added: vendor/Python/current/Python/getcompiler.c
===================================================================
--- vendor/Python/current/Python/getcompiler.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/getcompiler.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,28 @@
+
+/* Return the compiler identification, if possible. */
+
+#include "Python.h"
+
+#ifndef COMPILER
+
+#ifdef __GNUC__
+#define COMPILER "\n[GCC " __VERSION__ "]"
+#endif
+
+#endif /* !COMPILER */
+
+#ifndef COMPILER
+
+#ifdef __cplusplus
+#define COMPILER "[C++]"
+#else
+#define COMPILER "[C]"
+#endif
+
+#endif /* !COMPILER */
+
+const char *
+Py_GetCompiler(void)
+{
+	return COMPILER;
+}

Added: vendor/Python/current/Python/getcopyright.c
===================================================================
--- vendor/Python/current/Python/getcopyright.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/getcopyright.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,23 @@
+/* Return the copyright string.  This is updated manually. */
+
+#include "Python.h"
+
+static char cprt[] = 
+"\
+Copyright (c) 2001-2007 Python Software Foundation.\n\
+All Rights Reserved.\n\
+\n\
+Copyright (c) 2000 BeOpen.com.\n\
+All Rights Reserved.\n\
+\n\
+Copyright (c) 1995-2001 Corporation for National Research Initiatives.\n\
+All Rights Reserved.\n\
+\n\
+Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam.\n\
+All Rights Reserved.";
+
+const char *
+Py_GetCopyright(void)
+{
+	return cprt;
+}

Added: vendor/Python/current/Python/getcwd.c
===================================================================
--- vendor/Python/current/Python/getcwd.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/getcwd.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,83 @@
+
+/* Two PD getcwd() implementations.
+   Author: Guido van Rossum, CWI Amsterdam, Jan 1991, <guido at cwi.nl>. */
+
+#include <stdio.h>
+#include <errno.h>
+
+#ifdef HAVE_GETWD
+
+/* Version for BSD systems -- use getwd() */
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#ifndef MAXPATHLEN
+#if defined(PATH_MAX) && PATH_MAX > 1024
+#define MAXPATHLEN PATH_MAX
+#else
+#define MAXPATHLEN 1024
+#endif
+#endif
+
+extern char *getwd(char *);
+
+char *
+getcwd(char *buf, int size)
+{
+	char localbuf[MAXPATHLEN+1];
+	char *ret;
+	
+	if (size <= 0) {
+		errno = EINVAL;
+		return NULL;
+	}
+	ret = getwd(localbuf);
+	if (ret != NULL && strlen(localbuf) >= (size_t)size) {
+		errno = ERANGE;
+		return NULL;
+	}
+	if (ret == NULL) {
+		errno = EACCES; /* Most likely error */
+		return NULL;
+	}
+	strncpy(buf, localbuf, size);
+	return buf;
+}
+
+#else /* !HAVE_GETWD */
+
+/* Version for really old UNIX systems -- use pipe from pwd */
+
+#ifndef PWD_CMD
+#define PWD_CMD "/bin/pwd"
+#endif
+
+char *
+getcwd(char *buf, int size)
+{
+	FILE *fp;
+	char *p;
+	int sts;
+	if (size <= 0) {
+		errno = EINVAL;
+		return NULL;
+	}
+	if ((fp = popen(PWD_CMD, "r")) == NULL)
+		return NULL;
+	if (fgets(buf, size, fp) == NULL || (sts = pclose(fp)) != 0) {
+		errno = EACCES; /* Most likely error */
+		return NULL;
+	}
+	for (p = buf; *p != '\n'; p++) {
+		if (*p == '\0') {
+			errno = ERANGE;
+			return NULL;
+		}
+	}
+	*p = '\0';
+	return buf;
+}
+
+#endif /* !HAVE_GETWD */

Added: vendor/Python/current/Python/getmtime.c
===================================================================
--- vendor/Python/current/Python/getmtime.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/getmtime.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,26 @@
+
+/* Subroutine to get the last modification time of a file */
+
+/* (A separate file because this may be OS dependent) */
+
+#include "Python.h"
+#include "pyconfig.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+time_t
+PyOS_GetLastModificationTime(char *path, FILE *fp)
+{
+	struct stat st;
+	if (fstat(fileno(fp), &st) != 0)
+		return -1;
+	else
+		return st.st_mtime;
+}
+
+#ifdef __cplusplus
+}
+#endif
+

Added: vendor/Python/current/Python/getopt.c
===================================================================
--- vendor/Python/current/Python/getopt.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/getopt.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,115 @@
+/*---------------------------------------------------------------------------*
+ * <RCS keywords>
+ *
+ * C++ Library
+ *
+ * Copyright 1992-1994, David Gottner
+ *
+ *                    All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and its 
+ * documentation for any purpose and without fee is hereby granted, 
+ * provided that the above copyright notice, this permission notice and
+ * the following disclaimer notice appear unmodified in all copies.
+ *
+ * I DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL I
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
+ * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA, OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Nevertheless, I would like to know about bugs in this library or
+ * suggestions for improvment.  Send bug reports and feedback to
+ * davegottner at delphi.com.
+ *---------------------------------------------------------------------------*/
+
+/* Modified to support --help and --version, as well as /? on Windows
+ * by Georg Brandl. */
+
+#include <stdio.h>
+#include <string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int _PyOS_opterr = 1;          /* generate error messages */
+int _PyOS_optind = 1;          /* index into argv array   */
+char *_PyOS_optarg = NULL;     /* optional argument       */
+
+int _PyOS_GetOpt(int argc, char **argv, char *optstring)
+{
+	static char *opt_ptr = "";
+	char *ptr;
+	int option;
+
+	if (*opt_ptr == '\0') {
+
+		if (_PyOS_optind >= argc)
+			return -1;
+#ifdef MS_WINDOWS
+		else if (strcmp(argv[_PyOS_optind], "/?") == 0) {
+			++_PyOS_optind;
+			return 'h';
+		}
+#endif
+
+		else if (argv[_PyOS_optind][0] != '-' ||
+		         argv[_PyOS_optind][1] == '\0' /* lone dash */ )
+			return -1;
+
+		else if (strcmp(argv[_PyOS_optind], "--") == 0) {
+			++_PyOS_optind;
+			return -1;
+		}
+
+		else if (strcmp(argv[_PyOS_optind], "--help") == 0) {
+			++_PyOS_optind;
+			return 'h';
+		}
+
+		else if (strcmp(argv[_PyOS_optind], "--version") == 0) {
+			++_PyOS_optind;
+			return 'V';
+		}
+
+
+		opt_ptr = &argv[_PyOS_optind++][1]; 
+	}
+
+	if ( (option = *opt_ptr++) == '\0')
+		return -1;
+	
+	if ((ptr = strchr(optstring, option)) == NULL) {
+		if (_PyOS_opterr)
+			fprintf(stderr, "Unknown option: -%c\n", option);
+
+		return '_';
+	}
+
+	if (*(ptr + 1) == ':') {
+		if (*opt_ptr != '\0') {
+			_PyOS_optarg  = opt_ptr;
+			opt_ptr = "";
+		}
+
+		else {
+			if (_PyOS_optind >= argc) {
+				if (_PyOS_opterr)
+					fprintf(stderr,
+			    "Argument expected for the -%c option\n", option);
+				return '_';
+			}
+
+			_PyOS_optarg = argv[_PyOS_optind++];
+		}
+	}
+
+	return option;
+}
+
+#ifdef __cplusplus
+}
+#endif
+

Added: vendor/Python/current/Python/getplatform.c
===================================================================
--- vendor/Python/current/Python/getplatform.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/getplatform.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,12 @@
+
+#include "Python.h"
+
+#ifndef PLATFORM
+#define PLATFORM "unknown"
+#endif
+
+const char *
+Py_GetPlatform(void)
+{
+	return PLATFORM;
+}

Added: vendor/Python/current/Python/getversion.c
===================================================================
--- vendor/Python/current/Python/getversion.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/getversion.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,15 @@
+
+/* Return the full version string. */
+
+#include "Python.h"
+
+#include "patchlevel.h"
+
+const char *
+Py_GetVersion(void)
+{
+	static char version[250];
+	PyOS_snprintf(version, sizeof(version), "%.80s (%.80s) %.80s", 
+		      PY_VERSION, Py_GetBuildInfo(), Py_GetCompiler());
+	return version;
+}

Added: vendor/Python/current/Python/graminit.c
===================================================================
--- vendor/Python/current/Python/graminit.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/graminit.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2129 @@
+#include "pgenheaders.h"
+#include "grammar.h"
+static arc arcs_0_0[3] = {
+	{2, 1},
+	{3, 1},
+	{4, 2},
+};
+static arc arcs_0_1[1] = {
+	{0, 1},
+};
+static arc arcs_0_2[1] = {
+	{2, 1},
+};
+static state states_0[3] = {
+	{3, arcs_0_0},
+	{1, arcs_0_1},
+	{1, arcs_0_2},
+};
+static arc arcs_1_0[3] = {
+	{2, 0},
+	{6, 0},
+	{7, 1},
+};
+static arc arcs_1_1[1] = {
+	{0, 1},
+};
+static state states_1[2] = {
+	{3, arcs_1_0},
+	{1, arcs_1_1},
+};
+static arc arcs_2_0[1] = {
+	{9, 1},
+};
+static arc arcs_2_1[2] = {
+	{2, 1},
+	{7, 2},
+};
+static arc arcs_2_2[1] = {
+	{0, 2},
+};
+static state states_2[3] = {
+	{1, arcs_2_0},
+	{2, arcs_2_1},
+	{1, arcs_2_2},
+};
+static arc arcs_3_0[1] = {
+	{11, 1},
+};
+static arc arcs_3_1[1] = {
+	{12, 2},
+};
+static arc arcs_3_2[2] = {
+	{13, 3},
+	{2, 4},
+};
+static arc arcs_3_3[2] = {
+	{14, 5},
+	{15, 6},
+};
+static arc arcs_3_4[1] = {
+	{0, 4},
+};
+static arc arcs_3_5[1] = {
+	{15, 6},
+};
+static arc arcs_3_6[1] = {
+	{2, 4},
+};
+static state states_3[7] = {
+	{1, arcs_3_0},
+	{1, arcs_3_1},
+	{2, arcs_3_2},
+	{2, arcs_3_3},
+	{1, arcs_3_4},
+	{1, arcs_3_5},
+	{1, arcs_3_6},
+};
+static arc arcs_4_0[1] = {
+	{10, 1},
+};
+static arc arcs_4_1[2] = {
+	{10, 1},
+	{0, 1},
+};
+static state states_4[2] = {
+	{1, arcs_4_0},
+	{2, arcs_4_1},
+};
+static arc arcs_5_0[2] = {
+	{16, 1},
+	{18, 2},
+};
+static arc arcs_5_1[1] = {
+	{18, 2},
+};
+static arc arcs_5_2[1] = {
+	{19, 3},
+};
+static arc arcs_5_3[1] = {
+	{20, 4},
+};
+static arc arcs_5_4[1] = {
+	{21, 5},
+};
+static arc arcs_5_5[1] = {
+	{22, 6},
+};
+static arc arcs_5_6[1] = {
+	{0, 6},
+};
+static state states_5[7] = {
+	{2, arcs_5_0},
+	{1, arcs_5_1},
+	{1, arcs_5_2},
+	{1, arcs_5_3},
+	{1, arcs_5_4},
+	{1, arcs_5_5},
+	{1, arcs_5_6},
+};
+static arc arcs_6_0[1] = {
+	{13, 1},
+};
+static arc arcs_6_1[2] = {
+	{23, 2},
+	{15, 3},
+};
+static arc arcs_6_2[1] = {
+	{15, 3},
+};
+static arc arcs_6_3[1] = {
+	{0, 3},
+};
+static state states_6[4] = {
+	{1, arcs_6_0},
+	{2, arcs_6_1},
+	{1, arcs_6_2},
+	{1, arcs_6_3},
+};
+static arc arcs_7_0[3] = {
+	{24, 1},
+	{28, 2},
+	{29, 3},
+};
+static arc arcs_7_1[3] = {
+	{25, 4},
+	{27, 5},
+	{0, 1},
+};
+static arc arcs_7_2[1] = {
+	{19, 6},
+};
+static arc arcs_7_3[1] = {
+	{19, 7},
+};
+static arc arcs_7_4[1] = {
+	{26, 8},
+};
+static arc arcs_7_5[4] = {
+	{24, 1},
+	{28, 2},
+	{29, 3},
+	{0, 5},
+};
+static arc arcs_7_6[2] = {
+	{27, 9},
+	{0, 6},
+};
+static arc arcs_7_7[1] = {
+	{0, 7},
+};
+static arc arcs_7_8[2] = {
+	{27, 5},
+	{0, 8},
+};
+static arc arcs_7_9[1] = {
+	{29, 3},
+};
+static state states_7[10] = {
+	{3, arcs_7_0},
+	{3, arcs_7_1},
+	{1, arcs_7_2},
+	{1, arcs_7_3},
+	{1, arcs_7_4},
+	{4, arcs_7_5},
+	{2, arcs_7_6},
+	{1, arcs_7_7},
+	{2, arcs_7_8},
+	{1, arcs_7_9},
+};
+static arc arcs_8_0[2] = {
+	{19, 1},
+	{13, 2},
+};
+static arc arcs_8_1[1] = {
+	{0, 1},
+};
+static arc arcs_8_2[1] = {
+	{30, 3},
+};
+static arc arcs_8_3[1] = {
+	{15, 1},
+};
+static state states_8[4] = {
+	{2, arcs_8_0},
+	{1, arcs_8_1},
+	{1, arcs_8_2},
+	{1, arcs_8_3},
+};
+static arc arcs_9_0[1] = {
+	{24, 1},
+};
+static arc arcs_9_1[2] = {
+	{27, 2},
+	{0, 1},
+};
+static arc arcs_9_2[2] = {
+	{24, 1},
+	{0, 2},
+};
+static state states_9[3] = {
+	{1, arcs_9_0},
+	{2, arcs_9_1},
+	{2, arcs_9_2},
+};
+static arc arcs_10_0[2] = {
+	{3, 1},
+	{4, 1},
+};
+static arc arcs_10_1[1] = {
+	{0, 1},
+};
+static state states_10[2] = {
+	{2, arcs_10_0},
+	{1, arcs_10_1},
+};
+static arc arcs_11_0[1] = {
+	{31, 1},
+};
+static arc arcs_11_1[2] = {
+	{32, 2},
+	{2, 3},
+};
+static arc arcs_11_2[2] = {
+	{31, 1},
+	{2, 3},
+};
+static arc arcs_11_3[1] = {
+	{0, 3},
+};
+static state states_11[4] = {
+	{1, arcs_11_0},
+	{2, arcs_11_1},
+	{2, arcs_11_2},
+	{1, arcs_11_3},
+};
+static arc arcs_12_0[9] = {
+	{33, 1},
+	{34, 1},
+	{35, 1},
+	{36, 1},
+	{37, 1},
+	{38, 1},
+	{39, 1},
+	{40, 1},
+	{41, 1},
+};
+static arc arcs_12_1[1] = {
+	{0, 1},
+};
+static state states_12[2] = {
+	{9, arcs_12_0},
+	{1, arcs_12_1},
+};
+static arc arcs_13_0[1] = {
+	{9, 1},
+};
+static arc arcs_13_1[3] = {
+	{42, 2},
+	{25, 3},
+	{0, 1},
+};
+static arc arcs_13_2[2] = {
+	{43, 4},
+	{9, 4},
+};
+static arc arcs_13_3[2] = {
+	{43, 5},
+	{9, 5},
+};
+static arc arcs_13_4[1] = {
+	{0, 4},
+};
+static arc arcs_13_5[2] = {
+	{25, 3},
+	{0, 5},
+};
+static state states_13[6] = {
+	{1, arcs_13_0},
+	{3, arcs_13_1},
+	{2, arcs_13_2},
+	{2, arcs_13_3},
+	{1, arcs_13_4},
+	{2, arcs_13_5},
+};
+static arc arcs_14_0[12] = {
+	{44, 1},
+	{45, 1},
+	{46, 1},
+	{47, 1},
+	{48, 1},
+	{49, 1},
+	{50, 1},
+	{51, 1},
+	{52, 1},
+	{53, 1},
+	{54, 1},
+	{55, 1},
+};
+static arc arcs_14_1[1] = {
+	{0, 1},
+};
+static state states_14[2] = {
+	{12, arcs_14_0},
+	{1, arcs_14_1},
+};
+static arc arcs_15_0[1] = {
+	{56, 1},
+};
+static arc arcs_15_1[3] = {
+	{26, 2},
+	{57, 3},
+	{0, 1},
+};
+static arc arcs_15_2[2] = {
+	{27, 4},
+	{0, 2},
+};
+static arc arcs_15_3[1] = {
+	{26, 5},
+};
+static arc arcs_15_4[2] = {
+	{26, 2},
+	{0, 4},
+};
+static arc arcs_15_5[2] = {
+	{27, 6},
+	{0, 5},
+};
+static arc arcs_15_6[1] = {
+	{26, 7},
+};
+static arc arcs_15_7[2] = {
+	{27, 8},
+	{0, 7},
+};
+static arc arcs_15_8[2] = {
+	{26, 7},
+	{0, 8},
+};
+static state states_15[9] = {
+	{1, arcs_15_0},
+	{3, arcs_15_1},
+	{2, arcs_15_2},
+	{1, arcs_15_3},
+	{2, arcs_15_4},
+	{2, arcs_15_5},
+	{1, arcs_15_6},
+	{2, arcs_15_7},
+	{2, arcs_15_8},
+};
+static arc arcs_16_0[1] = {
+	{58, 1},
+};
+static arc arcs_16_1[1] = {
+	{59, 2},
+};
+static arc arcs_16_2[1] = {
+	{0, 2},
+};
+static state states_16[3] = {
+	{1, arcs_16_0},
+	{1, arcs_16_1},
+	{1, arcs_16_2},
+};
+static arc arcs_17_0[1] = {
+	{60, 1},
+};
+static arc arcs_17_1[1] = {
+	{0, 1},
+};
+static state states_17[2] = {
+	{1, arcs_17_0},
+	{1, arcs_17_1},
+};
+static arc arcs_18_0[5] = {
+	{61, 1},
+	{62, 1},
+	{63, 1},
+	{64, 1},
+	{65, 1},
+};
+static arc arcs_18_1[1] = {
+	{0, 1},
+};
+static state states_18[2] = {
+	{5, arcs_18_0},
+	{1, arcs_18_1},
+};
+static arc arcs_19_0[1] = {
+	{66, 1},
+};
+static arc arcs_19_1[1] = {
+	{0, 1},
+};
+static state states_19[2] = {
+	{1, arcs_19_0},
+	{1, arcs_19_1},
+};
+static arc arcs_20_0[1] = {
+	{67, 1},
+};
+static arc arcs_20_1[1] = {
+	{0, 1},
+};
+static state states_20[2] = {
+	{1, arcs_20_0},
+	{1, arcs_20_1},
+};
+static arc arcs_21_0[1] = {
+	{68, 1},
+};
+static arc arcs_21_1[2] = {
+	{9, 2},
+	{0, 1},
+};
+static arc arcs_21_2[1] = {
+	{0, 2},
+};
+static state states_21[3] = {
+	{1, arcs_21_0},
+	{2, arcs_21_1},
+	{1, arcs_21_2},
+};
+static arc arcs_22_0[1] = {
+	{43, 1},
+};
+static arc arcs_22_1[1] = {
+	{0, 1},
+};
+static state states_22[2] = {
+	{1, arcs_22_0},
+	{1, arcs_22_1},
+};
+static arc arcs_23_0[1] = {
+	{69, 1},
+};
+static arc arcs_23_1[2] = {
+	{26, 2},
+	{0, 1},
+};
+static arc arcs_23_2[2] = {
+	{27, 3},
+	{0, 2},
+};
+static arc arcs_23_3[1] = {
+	{26, 4},
+};
+static arc arcs_23_4[2] = {
+	{27, 5},
+	{0, 4},
+};
+static arc arcs_23_5[1] = {
+	{26, 6},
+};
+static arc arcs_23_6[1] = {
+	{0, 6},
+};
+static state states_23[7] = {
+	{1, arcs_23_0},
+	{2, arcs_23_1},
+	{2, arcs_23_2},
+	{1, arcs_23_3},
+	{2, arcs_23_4},
+	{1, arcs_23_5},
+	{1, arcs_23_6},
+};
+static arc arcs_24_0[2] = {
+	{70, 1},
+	{71, 1},
+};
+static arc arcs_24_1[1] = {
+	{0, 1},
+};
+static state states_24[2] = {
+	{2, arcs_24_0},
+	{1, arcs_24_1},
+};
+static arc arcs_25_0[1] = {
+	{72, 1},
+};
+static arc arcs_25_1[1] = {
+	{73, 2},
+};
+static arc arcs_25_2[1] = {
+	{0, 2},
+};
+static state states_25[3] = {
+	{1, arcs_25_0},
+	{1, arcs_25_1},
+	{1, arcs_25_2},
+};
+static arc arcs_26_0[1] = {
+	{74, 1},
+};
+static arc arcs_26_1[2] = {
+	{75, 2},
+	{12, 3},
+};
+static arc arcs_26_2[3] = {
+	{75, 2},
+	{12, 3},
+	{72, 4},
+};
+static arc arcs_26_3[1] = {
+	{72, 4},
+};
+static arc arcs_26_4[3] = {
+	{28, 5},
+	{13, 6},
+	{76, 5},
+};
+static arc arcs_26_5[1] = {
+	{0, 5},
+};
+static arc arcs_26_6[1] = {
+	{76, 7},
+};
+static arc arcs_26_7[1] = {
+	{15, 5},
+};
+static state states_26[8] = {
+	{1, arcs_26_0},
+	{2, arcs_26_1},
+	{3, arcs_26_2},
+	{1, arcs_26_3},
+	{3, arcs_26_4},
+	{1, arcs_26_5},
+	{1, arcs_26_6},
+	{1, arcs_26_7},
+};
+static arc arcs_27_0[1] = {
+	{19, 1},
+};
+static arc arcs_27_1[3] = {
+	{78, 2},
+	{19, 2},
+	{0, 1},
+};
+static arc arcs_27_2[1] = {
+	{19, 3},
+};
+static arc arcs_27_3[1] = {
+	{0, 3},
+};
+static state states_27[4] = {
+	{1, arcs_27_0},
+	{3, arcs_27_1},
+	{1, arcs_27_2},
+	{1, arcs_27_3},
+};
+static arc arcs_28_0[1] = {
+	{12, 1},
+};
+static arc arcs_28_1[3] = {
+	{78, 2},
+	{19, 2},
+	{0, 1},
+};
+static arc arcs_28_2[1] = {
+	{19, 3},
+};
+static arc arcs_28_3[1] = {
+	{0, 3},
+};
+static state states_28[4] = {
+	{1, arcs_28_0},
+	{3, arcs_28_1},
+	{1, arcs_28_2},
+	{1, arcs_28_3},
+};
+static arc arcs_29_0[1] = {
+	{77, 1},
+};
+static arc arcs_29_1[2] = {
+	{27, 2},
+	{0, 1},
+};
+static arc arcs_29_2[2] = {
+	{77, 1},
+	{0, 2},
+};
+static state states_29[3] = {
+	{1, arcs_29_0},
+	{2, arcs_29_1},
+	{2, arcs_29_2},
+};
+static arc arcs_30_0[1] = {
+	{79, 1},
+};
+static arc arcs_30_1[2] = {
+	{27, 0},
+	{0, 1},
+};
+static state states_30[2] = {
+	{1, arcs_30_0},
+	{2, arcs_30_1},
+};
+static arc arcs_31_0[1] = {
+	{19, 1},
+};
+static arc arcs_31_1[2] = {
+	{75, 0},
+	{0, 1},
+};
+static state states_31[2] = {
+	{1, arcs_31_0},
+	{2, arcs_31_1},
+};
+static arc arcs_32_0[1] = {
+	{80, 1},
+};
+static arc arcs_32_1[1] = {
+	{19, 2},
+};
+static arc arcs_32_2[2] = {
+	{27, 1},
+	{0, 2},
+};
+static state states_32[3] = {
+	{1, arcs_32_0},
+	{1, arcs_32_1},
+	{2, arcs_32_2},
+};
+static arc arcs_33_0[1] = {
+	{81, 1},
+};
+static arc arcs_33_1[1] = {
+	{82, 2},
+};
+static arc arcs_33_2[2] = {
+	{83, 3},
+	{0, 2},
+};
+static arc arcs_33_3[1] = {
+	{26, 4},
+};
+static arc arcs_33_4[2] = {
+	{27, 5},
+	{0, 4},
+};
+static arc arcs_33_5[1] = {
+	{26, 6},
+};
+static arc arcs_33_6[1] = {
+	{0, 6},
+};
+static state states_33[7] = {
+	{1, arcs_33_0},
+	{1, arcs_33_1},
+	{2, arcs_33_2},
+	{1, arcs_33_3},
+	{2, arcs_33_4},
+	{1, arcs_33_5},
+	{1, arcs_33_6},
+};
+static arc arcs_34_0[1] = {
+	{84, 1},
+};
+static arc arcs_34_1[1] = {
+	{26, 2},
+};
+static arc arcs_34_2[2] = {
+	{27, 3},
+	{0, 2},
+};
+static arc arcs_34_3[1] = {
+	{26, 4},
+};
+static arc arcs_34_4[1] = {
+	{0, 4},
+};
+static state states_34[5] = {
+	{1, arcs_34_0},
+	{1, arcs_34_1},
+	{2, arcs_34_2},
+	{1, arcs_34_3},
+	{1, arcs_34_4},
+};
+static arc arcs_35_0[7] = {
+	{85, 1},
+	{86, 1},
+	{87, 1},
+	{88, 1},
+	{89, 1},
+	{17, 1},
+	{90, 1},
+};
+static arc arcs_35_1[1] = {
+	{0, 1},
+};
+static state states_35[2] = {
+	{7, arcs_35_0},
+	{1, arcs_35_1},
+};
+static arc arcs_36_0[1] = {
+	{91, 1},
+};
+static arc arcs_36_1[1] = {
+	{26, 2},
+};
+static arc arcs_36_2[1] = {
+	{21, 3},
+};
+static arc arcs_36_3[1] = {
+	{22, 4},
+};
+static arc arcs_36_4[3] = {
+	{92, 1},
+	{93, 5},
+	{0, 4},
+};
+static arc arcs_36_5[1] = {
+	{21, 6},
+};
+static arc arcs_36_6[1] = {
+	{22, 7},
+};
+static arc arcs_36_7[1] = {
+	{0, 7},
+};
+static state states_36[8] = {
+	{1, arcs_36_0},
+	{1, arcs_36_1},
+	{1, arcs_36_2},
+	{1, arcs_36_3},
+	{3, arcs_36_4},
+	{1, arcs_36_5},
+	{1, arcs_36_6},
+	{1, arcs_36_7},
+};
+static arc arcs_37_0[1] = {
+	{94, 1},
+};
+static arc arcs_37_1[1] = {
+	{26, 2},
+};
+static arc arcs_37_2[1] = {
+	{21, 3},
+};
+static arc arcs_37_3[1] = {
+	{22, 4},
+};
+static arc arcs_37_4[2] = {
+	{93, 5},
+	{0, 4},
+};
+static arc arcs_37_5[1] = {
+	{21, 6},
+};
+static arc arcs_37_6[1] = {
+	{22, 7},
+};
+static arc arcs_37_7[1] = {
+	{0, 7},
+};
+static state states_37[8] = {
+	{1, arcs_37_0},
+	{1, arcs_37_1},
+	{1, arcs_37_2},
+	{1, arcs_37_3},
+	{2, arcs_37_4},
+	{1, arcs_37_5},
+	{1, arcs_37_6},
+	{1, arcs_37_7},
+};
+static arc arcs_38_0[1] = {
+	{95, 1},
+};
+static arc arcs_38_1[1] = {
+	{59, 2},
+};
+static arc arcs_38_2[1] = {
+	{83, 3},
+};
+static arc arcs_38_3[1] = {
+	{9, 4},
+};
+static arc arcs_38_4[1] = {
+	{21, 5},
+};
+static arc arcs_38_5[1] = {
+	{22, 6},
+};
+static arc arcs_38_6[2] = {
+	{93, 7},
+	{0, 6},
+};
+static arc arcs_38_7[1] = {
+	{21, 8},
+};
+static arc arcs_38_8[1] = {
+	{22, 9},
+};
+static arc arcs_38_9[1] = {
+	{0, 9},
+};
+static state states_38[10] = {
+	{1, arcs_38_0},
+	{1, arcs_38_1},
+	{1, arcs_38_2},
+	{1, arcs_38_3},
+	{1, arcs_38_4},
+	{1, arcs_38_5},
+	{2, arcs_38_6},
+	{1, arcs_38_7},
+	{1, arcs_38_8},
+	{1, arcs_38_9},
+};
+static arc arcs_39_0[1] = {
+	{96, 1},
+};
+static arc arcs_39_1[1] = {
+	{21, 2},
+};
+static arc arcs_39_2[1] = {
+	{22, 3},
+};
+static arc arcs_39_3[2] = {
+	{97, 4},
+	{98, 5},
+};
+static arc arcs_39_4[1] = {
+	{21, 6},
+};
+static arc arcs_39_5[1] = {
+	{21, 7},
+};
+static arc arcs_39_6[1] = {
+	{22, 8},
+};
+static arc arcs_39_7[1] = {
+	{22, 9},
+};
+static arc arcs_39_8[4] = {
+	{97, 4},
+	{93, 10},
+	{98, 5},
+	{0, 8},
+};
+static arc arcs_39_9[1] = {
+	{0, 9},
+};
+static arc arcs_39_10[1] = {
+	{21, 11},
+};
+static arc arcs_39_11[1] = {
+	{22, 12},
+};
+static arc arcs_39_12[2] = {
+	{98, 5},
+	{0, 12},
+};
+static state states_39[13] = {
+	{1, arcs_39_0},
+	{1, arcs_39_1},
+	{1, arcs_39_2},
+	{2, arcs_39_3},
+	{1, arcs_39_4},
+	{1, arcs_39_5},
+	{1, arcs_39_6},
+	{1, arcs_39_7},
+	{4, arcs_39_8},
+	{1, arcs_39_9},
+	{1, arcs_39_10},
+	{1, arcs_39_11},
+	{2, arcs_39_12},
+};
+static arc arcs_40_0[1] = {
+	{99, 1},
+};
+static arc arcs_40_1[1] = {
+	{26, 2},
+};
+static arc arcs_40_2[2] = {
+	{100, 3},
+	{21, 4},
+};
+static arc arcs_40_3[1] = {
+	{21, 4},
+};
+static arc arcs_40_4[1] = {
+	{22, 5},
+};
+static arc arcs_40_5[1] = {
+	{0, 5},
+};
+static state states_40[6] = {
+	{1, arcs_40_0},
+	{1, arcs_40_1},
+	{2, arcs_40_2},
+	{1, arcs_40_3},
+	{1, arcs_40_4},
+	{1, arcs_40_5},
+};
+static arc arcs_41_0[2] = {
+	{78, 1},
+	{19, 1},
+};
+static arc arcs_41_1[1] = {
+	{82, 2},
+};
+static arc arcs_41_2[1] = {
+	{0, 2},
+};
+static state states_41[3] = {
+	{2, arcs_41_0},
+	{1, arcs_41_1},
+	{1, arcs_41_2},
+};
+static arc arcs_42_0[1] = {
+	{101, 1},
+};
+static arc arcs_42_1[2] = {
+	{26, 2},
+	{0, 1},
+};
+static arc arcs_42_2[2] = {
+	{27, 3},
+	{0, 2},
+};
+static arc arcs_42_3[1] = {
+	{26, 4},
+};
+static arc arcs_42_4[1] = {
+	{0, 4},
+};
+static state states_42[5] = {
+	{1, arcs_42_0},
+	{2, arcs_42_1},
+	{2, arcs_42_2},
+	{1, arcs_42_3},
+	{1, arcs_42_4},
+};
+static arc arcs_43_0[2] = {
+	{3, 1},
+	{2, 2},
+};
+static arc arcs_43_1[1] = {
+	{0, 1},
+};
+static arc arcs_43_2[1] = {
+	{102, 3},
+};
+static arc arcs_43_3[1] = {
+	{6, 4},
+};
+static arc arcs_43_4[2] = {
+	{6, 4},
+	{103, 1},
+};
+static state states_43[5] = {
+	{2, arcs_43_0},
+	{1, arcs_43_1},
+	{1, arcs_43_2},
+	{1, arcs_43_3},
+	{2, arcs_43_4},
+};
+static arc arcs_44_0[1] = {
+	{105, 1},
+};
+static arc arcs_44_1[2] = {
+	{27, 2},
+	{0, 1},
+};
+static arc arcs_44_2[1] = {
+	{105, 3},
+};
+static arc arcs_44_3[2] = {
+	{27, 4},
+	{0, 3},
+};
+static arc arcs_44_4[2] = {
+	{105, 3},
+	{0, 4},
+};
+static state states_44[5] = {
+	{1, arcs_44_0},
+	{2, arcs_44_1},
+	{1, arcs_44_2},
+	{2, arcs_44_3},
+	{2, arcs_44_4},
+};
+static arc arcs_45_0[2] = {
+	{106, 1},
+	{107, 1},
+};
+static arc arcs_45_1[1] = {
+	{0, 1},
+};
+static state states_45[2] = {
+	{2, arcs_45_0},
+	{1, arcs_45_1},
+};
+static arc arcs_46_0[1] = {
+	{108, 1},
+};
+static arc arcs_46_1[2] = {
+	{23, 2},
+	{21, 3},
+};
+static arc arcs_46_2[1] = {
+	{21, 3},
+};
+static arc arcs_46_3[1] = {
+	{105, 4},
+};
+static arc arcs_46_4[1] = {
+	{0, 4},
+};
+static state states_46[5] = {
+	{1, arcs_46_0},
+	{2, arcs_46_1},
+	{1, arcs_46_2},
+	{1, arcs_46_3},
+	{1, arcs_46_4},
+};
+static arc arcs_47_0[2] = {
+	{106, 1},
+	{109, 2},
+};
+static arc arcs_47_1[2] = {
+	{91, 3},
+	{0, 1},
+};
+static arc arcs_47_2[1] = {
+	{0, 2},
+};
+static arc arcs_47_3[1] = {
+	{106, 4},
+};
+static arc arcs_47_4[1] = {
+	{93, 5},
+};
+static arc arcs_47_5[1] = {
+	{26, 2},
+};
+static state states_47[6] = {
+	{2, arcs_47_0},
+	{2, arcs_47_1},
+	{1, arcs_47_2},
+	{1, arcs_47_3},
+	{1, arcs_47_4},
+	{1, arcs_47_5},
+};
+static arc arcs_48_0[1] = {
+	{110, 1},
+};
+static arc arcs_48_1[2] = {
+	{111, 0},
+	{0, 1},
+};
+static state states_48[2] = {
+	{1, arcs_48_0},
+	{2, arcs_48_1},
+};
+static arc arcs_49_0[1] = {
+	{112, 1},
+};
+static arc arcs_49_1[2] = {
+	{113, 0},
+	{0, 1},
+};
+static state states_49[2] = {
+	{1, arcs_49_0},
+	{2, arcs_49_1},
+};
+static arc arcs_50_0[2] = {
+	{114, 1},
+	{115, 2},
+};
+static arc arcs_50_1[1] = {
+	{112, 2},
+};
+static arc arcs_50_2[1] = {
+	{0, 2},
+};
+static state states_50[3] = {
+	{2, arcs_50_0},
+	{1, arcs_50_1},
+	{1, arcs_50_2},
+};
+static arc arcs_51_0[1] = {
+	{82, 1},
+};
+static arc arcs_51_1[2] = {
+	{116, 0},
+	{0, 1},
+};
+static state states_51[2] = {
+	{1, arcs_51_0},
+	{2, arcs_51_1},
+};
+static arc arcs_52_0[10] = {
+	{117, 1},
+	{118, 1},
+	{119, 1},
+	{120, 1},
+	{121, 1},
+	{122, 1},
+	{123, 1},
+	{83, 1},
+	{114, 2},
+	{124, 3},
+};
+static arc arcs_52_1[1] = {
+	{0, 1},
+};
+static arc arcs_52_2[1] = {
+	{83, 1},
+};
+static arc arcs_52_3[2] = {
+	{114, 1},
+	{0, 3},
+};
+static state states_52[4] = {
+	{10, arcs_52_0},
+	{1, arcs_52_1},
+	{1, arcs_52_2},
+	{2, arcs_52_3},
+};
+static arc arcs_53_0[1] = {
+	{125, 1},
+};
+static arc arcs_53_1[2] = {
+	{126, 0},
+	{0, 1},
+};
+static state states_53[2] = {
+	{1, arcs_53_0},
+	{2, arcs_53_1},
+};
+static arc arcs_54_0[1] = {
+	{127, 1},
+};
+static arc arcs_54_1[2] = {
+	{128, 0},
+	{0, 1},
+};
+static state states_54[2] = {
+	{1, arcs_54_0},
+	{2, arcs_54_1},
+};
+static arc arcs_55_0[1] = {
+	{129, 1},
+};
+static arc arcs_55_1[2] = {
+	{130, 0},
+	{0, 1},
+};
+static state states_55[2] = {
+	{1, arcs_55_0},
+	{2, arcs_55_1},
+};
+static arc arcs_56_0[1] = {
+	{131, 1},
+};
+static arc arcs_56_1[3] = {
+	{132, 0},
+	{57, 0},
+	{0, 1},
+};
+static state states_56[2] = {
+	{1, arcs_56_0},
+	{3, arcs_56_1},
+};
+static arc arcs_57_0[1] = {
+	{133, 1},
+};
+static arc arcs_57_1[3] = {
+	{134, 0},
+	{135, 0},
+	{0, 1},
+};
+static state states_57[2] = {
+	{1, arcs_57_0},
+	{3, arcs_57_1},
+};
+static arc arcs_58_0[1] = {
+	{136, 1},
+};
+static arc arcs_58_1[5] = {
+	{28, 0},
+	{137, 0},
+	{138, 0},
+	{139, 0},
+	{0, 1},
+};
+static state states_58[2] = {
+	{1, arcs_58_0},
+	{5, arcs_58_1},
+};
+static arc arcs_59_0[4] = {
+	{134, 1},
+	{135, 1},
+	{140, 1},
+	{141, 2},
+};
+static arc arcs_59_1[1] = {
+	{136, 2},
+};
+static arc arcs_59_2[1] = {
+	{0, 2},
+};
+static state states_59[3] = {
+	{4, arcs_59_0},
+	{1, arcs_59_1},
+	{1, arcs_59_2},
+};
+static arc arcs_60_0[1] = {
+	{142, 1},
+};
+static arc arcs_60_1[3] = {
+	{143, 1},
+	{29, 2},
+	{0, 1},
+};
+static arc arcs_60_2[1] = {
+	{136, 3},
+};
+static arc arcs_60_3[1] = {
+	{0, 3},
+};
+static state states_60[4] = {
+	{1, arcs_60_0},
+	{3, arcs_60_1},
+	{1, arcs_60_2},
+	{1, arcs_60_3},
+};
+static arc arcs_61_0[7] = {
+	{13, 1},
+	{145, 2},
+	{148, 3},
+	{151, 4},
+	{19, 5},
+	{153, 5},
+	{154, 6},
+};
+static arc arcs_61_1[3] = {
+	{43, 7},
+	{144, 7},
+	{15, 5},
+};
+static arc arcs_61_2[2] = {
+	{146, 8},
+	{147, 5},
+};
+static arc arcs_61_3[2] = {
+	{149, 9},
+	{150, 5},
+};
+static arc arcs_61_4[1] = {
+	{152, 10},
+};
+static arc arcs_61_5[1] = {
+	{0, 5},
+};
+static arc arcs_61_6[2] = {
+	{154, 6},
+	{0, 6},
+};
+static arc arcs_61_7[1] = {
+	{15, 5},
+};
+static arc arcs_61_8[1] = {
+	{147, 5},
+};
+static arc arcs_61_9[1] = {
+	{150, 5},
+};
+static arc arcs_61_10[1] = {
+	{151, 5},
+};
+static state states_61[11] = {
+	{7, arcs_61_0},
+	{3, arcs_61_1},
+	{2, arcs_61_2},
+	{2, arcs_61_3},
+	{1, arcs_61_4},
+	{1, arcs_61_5},
+	{2, arcs_61_6},
+	{1, arcs_61_7},
+	{1, arcs_61_8},
+	{1, arcs_61_9},
+	{1, arcs_61_10},
+};
+static arc arcs_62_0[1] = {
+	{26, 1},
+};
+static arc arcs_62_1[3] = {
+	{155, 2},
+	{27, 3},
+	{0, 1},
+};
+static arc arcs_62_2[1] = {
+	{0, 2},
+};
+static arc arcs_62_3[2] = {
+	{26, 4},
+	{0, 3},
+};
+static arc arcs_62_4[2] = {
+	{27, 3},
+	{0, 4},
+};
+static state states_62[5] = {
+	{1, arcs_62_0},
+	{3, arcs_62_1},
+	{1, arcs_62_2},
+	{2, arcs_62_3},
+	{2, arcs_62_4},
+};
+static arc arcs_63_0[1] = {
+	{26, 1},
+};
+static arc arcs_63_1[3] = {
+	{156, 2},
+	{27, 3},
+	{0, 1},
+};
+static arc arcs_63_2[1] = {
+	{0, 2},
+};
+static arc arcs_63_3[2] = {
+	{26, 4},
+	{0, 3},
+};
+static arc arcs_63_4[2] = {
+	{27, 3},
+	{0, 4},
+};
+static state states_63[5] = {
+	{1, arcs_63_0},
+	{3, arcs_63_1},
+	{1, arcs_63_2},
+	{2, arcs_63_3},
+	{2, arcs_63_4},
+};
+static arc arcs_64_0[1] = {
+	{108, 1},
+};
+static arc arcs_64_1[2] = {
+	{23, 2},
+	{21, 3},
+};
+static arc arcs_64_2[1] = {
+	{21, 3},
+};
+static arc arcs_64_3[1] = {
+	{26, 4},
+};
+static arc arcs_64_4[1] = {
+	{0, 4},
+};
+static state states_64[5] = {
+	{1, arcs_64_0},
+	{2, arcs_64_1},
+	{1, arcs_64_2},
+	{1, arcs_64_3},
+	{1, arcs_64_4},
+};
+static arc arcs_65_0[3] = {
+	{13, 1},
+	{145, 2},
+	{75, 3},
+};
+static arc arcs_65_1[2] = {
+	{14, 4},
+	{15, 5},
+};
+static arc arcs_65_2[1] = {
+	{157, 6},
+};
+static arc arcs_65_3[1] = {
+	{19, 5},
+};
+static arc arcs_65_4[1] = {
+	{15, 5},
+};
+static arc arcs_65_5[1] = {
+	{0, 5},
+};
+static arc arcs_65_6[1] = {
+	{147, 5},
+};
+static state states_65[7] = {
+	{3, arcs_65_0},
+	{2, arcs_65_1},
+	{1, arcs_65_2},
+	{1, arcs_65_3},
+	{1, arcs_65_4},
+	{1, arcs_65_5},
+	{1, arcs_65_6},
+};
+static arc arcs_66_0[1] = {
+	{158, 1},
+};
+static arc arcs_66_1[2] = {
+	{27, 2},
+	{0, 1},
+};
+static arc arcs_66_2[2] = {
+	{158, 1},
+	{0, 2},
+};
+static state states_66[3] = {
+	{1, arcs_66_0},
+	{2, arcs_66_1},
+	{2, arcs_66_2},
+};
+static arc arcs_67_0[3] = {
+	{75, 1},
+	{26, 2},
+	{21, 3},
+};
+static arc arcs_67_1[1] = {
+	{75, 4},
+};
+static arc arcs_67_2[2] = {
+	{21, 3},
+	{0, 2},
+};
+static arc arcs_67_3[3] = {
+	{26, 5},
+	{159, 6},
+	{0, 3},
+};
+static arc arcs_67_4[1] = {
+	{75, 6},
+};
+static arc arcs_67_5[2] = {
+	{159, 6},
+	{0, 5},
+};
+static arc arcs_67_6[1] = {
+	{0, 6},
+};
+static state states_67[7] = {
+	{3, arcs_67_0},
+	{1, arcs_67_1},
+	{2, arcs_67_2},
+	{3, arcs_67_3},
+	{1, arcs_67_4},
+	{2, arcs_67_5},
+	{1, arcs_67_6},
+};
+static arc arcs_68_0[1] = {
+	{21, 1},
+};
+static arc arcs_68_1[2] = {
+	{26, 2},
+	{0, 1},
+};
+static arc arcs_68_2[1] = {
+	{0, 2},
+};
+static state states_68[3] = {
+	{1, arcs_68_0},
+	{2, arcs_68_1},
+	{1, arcs_68_2},
+};
+static arc arcs_69_0[1] = {
+	{82, 1},
+};
+static arc arcs_69_1[2] = {
+	{27, 2},
+	{0, 1},
+};
+static arc arcs_69_2[2] = {
+	{82, 1},
+	{0, 2},
+};
+static state states_69[3] = {
+	{1, arcs_69_0},
+	{2, arcs_69_1},
+	{2, arcs_69_2},
+};
+static arc arcs_70_0[1] = {
+	{26, 1},
+};
+static arc arcs_70_1[2] = {
+	{27, 2},
+	{0, 1},
+};
+static arc arcs_70_2[2] = {
+	{26, 1},
+	{0, 2},
+};
+static state states_70[3] = {
+	{1, arcs_70_0},
+	{2, arcs_70_1},
+	{2, arcs_70_2},
+};
+static arc arcs_71_0[1] = {
+	{26, 1},
+};
+static arc arcs_71_1[1] = {
+	{21, 2},
+};
+static arc arcs_71_2[1] = {
+	{26, 3},
+};
+static arc arcs_71_3[2] = {
+	{27, 4},
+	{0, 3},
+};
+static arc arcs_71_4[2] = {
+	{26, 1},
+	{0, 4},
+};
+static state states_71[5] = {
+	{1, arcs_71_0},
+	{1, arcs_71_1},
+	{1, arcs_71_2},
+	{2, arcs_71_3},
+	{2, arcs_71_4},
+};
+static arc arcs_72_0[1] = {
+	{160, 1},
+};
+static arc arcs_72_1[1] = {
+	{19, 2},
+};
+static arc arcs_72_2[2] = {
+	{13, 3},
+	{21, 4},
+};
+static arc arcs_72_3[2] = {
+	{9, 5},
+	{15, 6},
+};
+static arc arcs_72_4[1] = {
+	{22, 7},
+};
+static arc arcs_72_5[1] = {
+	{15, 6},
+};
+static arc arcs_72_6[1] = {
+	{21, 4},
+};
+static arc arcs_72_7[1] = {
+	{0, 7},
+};
+static state states_72[8] = {
+	{1, arcs_72_0},
+	{1, arcs_72_1},
+	{2, arcs_72_2},
+	{2, arcs_72_3},
+	{1, arcs_72_4},
+	{1, arcs_72_5},
+	{1, arcs_72_6},
+	{1, arcs_72_7},
+};
+static arc arcs_73_0[3] = {
+	{161, 1},
+	{28, 2},
+	{29, 3},
+};
+static arc arcs_73_1[2] = {
+	{27, 4},
+	{0, 1},
+};
+static arc arcs_73_2[1] = {
+	{26, 5},
+};
+static arc arcs_73_3[1] = {
+	{26, 6},
+};
+static arc arcs_73_4[4] = {
+	{161, 1},
+	{28, 2},
+	{29, 3},
+	{0, 4},
+};
+static arc arcs_73_5[2] = {
+	{27, 7},
+	{0, 5},
+};
+static arc arcs_73_6[1] = {
+	{0, 6},
+};
+static arc arcs_73_7[1] = {
+	{29, 3},
+};
+static state states_73[8] = {
+	{3, arcs_73_0},
+	{2, arcs_73_1},
+	{1, arcs_73_2},
+	{1, arcs_73_3},
+	{4, arcs_73_4},
+	{2, arcs_73_5},
+	{1, arcs_73_6},
+	{1, arcs_73_7},
+};
+static arc arcs_74_0[1] = {
+	{26, 1},
+};
+static arc arcs_74_1[3] = {
+	{156, 2},
+	{25, 3},
+	{0, 1},
+};
+static arc arcs_74_2[1] = {
+	{0, 2},
+};
+static arc arcs_74_3[1] = {
+	{26, 2},
+};
+static state states_74[4] = {
+	{1, arcs_74_0},
+	{3, arcs_74_1},
+	{1, arcs_74_2},
+	{1, arcs_74_3},
+};
+static arc arcs_75_0[2] = {
+	{155, 1},
+	{163, 1},
+};
+static arc arcs_75_1[1] = {
+	{0, 1},
+};
+static state states_75[2] = {
+	{2, arcs_75_0},
+	{1, arcs_75_1},
+};
+static arc arcs_76_0[1] = {
+	{95, 1},
+};
+static arc arcs_76_1[1] = {
+	{59, 2},
+};
+static arc arcs_76_2[1] = {
+	{83, 3},
+};
+static arc arcs_76_3[1] = {
+	{104, 4},
+};
+static arc arcs_76_4[2] = {
+	{162, 5},
+	{0, 4},
+};
+static arc arcs_76_5[1] = {
+	{0, 5},
+};
+static state states_76[6] = {
+	{1, arcs_76_0},
+	{1, arcs_76_1},
+	{1, arcs_76_2},
+	{1, arcs_76_3},
+	{2, arcs_76_4},
+	{1, arcs_76_5},
+};
+static arc arcs_77_0[1] = {
+	{91, 1},
+};
+static arc arcs_77_1[1] = {
+	{105, 2},
+};
+static arc arcs_77_2[2] = {
+	{162, 3},
+	{0, 2},
+};
+static arc arcs_77_3[1] = {
+	{0, 3},
+};
+static state states_77[4] = {
+	{1, arcs_77_0},
+	{1, arcs_77_1},
+	{2, arcs_77_2},
+	{1, arcs_77_3},
+};
+static arc arcs_78_0[2] = {
+	{156, 1},
+	{165, 1},
+};
+static arc arcs_78_1[1] = {
+	{0, 1},
+};
+static state states_78[2] = {
+	{2, arcs_78_0},
+	{1, arcs_78_1},
+};
+static arc arcs_79_0[1] = {
+	{95, 1},
+};
+static arc arcs_79_1[1] = {
+	{59, 2},
+};
+static arc arcs_79_2[1] = {
+	{83, 3},
+};
+static arc arcs_79_3[1] = {
+	{106, 4},
+};
+static arc arcs_79_4[2] = {
+	{164, 5},
+	{0, 4},
+};
+static arc arcs_79_5[1] = {
+	{0, 5},
+};
+static state states_79[6] = {
+	{1, arcs_79_0},
+	{1, arcs_79_1},
+	{1, arcs_79_2},
+	{1, arcs_79_3},
+	{2, arcs_79_4},
+	{1, arcs_79_5},
+};
+static arc arcs_80_0[1] = {
+	{91, 1},
+};
+static arc arcs_80_1[1] = {
+	{105, 2},
+};
+static arc arcs_80_2[2] = {
+	{164, 3},
+	{0, 2},
+};
+static arc arcs_80_3[1] = {
+	{0, 3},
+};
+static state states_80[4] = {
+	{1, arcs_80_0},
+	{1, arcs_80_1},
+	{2, arcs_80_2},
+	{1, arcs_80_3},
+};
+static arc arcs_81_0[1] = {
+	{26, 1},
+};
+static arc arcs_81_1[2] = {
+	{27, 0},
+	{0, 1},
+};
+static state states_81[2] = {
+	{1, arcs_81_0},
+	{2, arcs_81_1},
+};
+static arc arcs_82_0[1] = {
+	{19, 1},
+};
+static arc arcs_82_1[1] = {
+	{0, 1},
+};
+static state states_82[2] = {
+	{1, arcs_82_0},
+	{1, arcs_82_1},
+};
+static arc arcs_83_0[1] = {
+	{167, 1},
+};
+static arc arcs_83_1[2] = {
+	{9, 2},
+	{0, 1},
+};
+static arc arcs_83_2[1] = {
+	{0, 2},
+};
+static state states_83[3] = {
+	{1, arcs_83_0},
+	{2, arcs_83_1},
+	{1, arcs_83_2},
+};
+static dfa dfas[84] = {
+	{256, "single_input", 0, 3, states_0,
+	 "\004\050\014\000\000\000\000\025\074\005\023\310\011\020\004\000\300\020\222\006\201"},
+	{257, "file_input", 0, 2, states_1,
+	 "\204\050\014\000\000\000\000\025\074\005\023\310\011\020\004\000\300\020\222\006\201"},
+	{258, "eval_input", 0, 3, states_2,
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\020\004\000\300\020\222\006\000"},
+	{259, "decorator", 0, 7, states_3,
+	 "\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+	{260, "decorators", 0, 2, states_4,
+	 "\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+	{261, "funcdef", 0, 7, states_5,
+	 "\000\010\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+	{262, "parameters", 0, 4, states_6,
+	 "\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+	{263, "varargslist", 0, 10, states_7,
+	 "\000\040\010\060\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+	{264, "fpdef", 0, 4, states_8,
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+	{265, "fplist", 0, 3, states_9,
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+	{266, "stmt", 0, 2, states_10,
+	 "\000\050\014\000\000\000\000\025\074\005\023\310\011\020\004\000\300\020\222\006\201"},
+	{267, "simple_stmt", 0, 4, states_11,
+	 "\000\040\010\000\000\000\000\025\074\005\023\000\000\020\004\000\300\020\222\006\200"},
+	{268, "small_stmt", 0, 2, states_12,
+	 "\000\040\010\000\000\000\000\025\074\005\023\000\000\020\004\000\300\020\222\006\200"},
+	{269, "expr_stmt", 0, 6, states_13,
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\020\004\000\300\020\222\006\000"},
+	{270, "augassign", 0, 2, states_14,
+	 "\000\000\000\000\000\360\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+	{271, "print_stmt", 0, 9, states_15,
+	 "\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+	{272, "del_stmt", 0, 3, states_16,
+	 "\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+	{273, "pass_stmt", 0, 2, states_17,
+	 "\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+	{274, "flow_stmt", 0, 2, states_18,
+	 "\000\000\000\000\000\000\000\000\074\000\000\000\000\000\000\000\000\000\000\000\200"},
+	{275, "break_stmt", 0, 2, states_19,
+	 "\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000"},
+	{276, "continue_stmt", 0, 2, states_20,
+	 "\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000"},
+	{277, "return_stmt", 0, 3, states_21,
+	 "\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000\000\000\000"},
+	{278, "yield_stmt", 0, 2, states_22,
+	 "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\200"},
+	{279, "raise_stmt", 0, 7, states_23,
+	 "\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000"},
+	{280, "import_stmt", 0, 2, states_24,
+	 "\000\000\000\000\000\000\000\000\000\005\000\000\000\000\000\000\000\000\000\000\000"},
+	{281, "import_name", 0, 3, states_25,
+	 "\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000"},
+	{282, "import_from", 0, 8, states_26,
+	 "\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000"},
+	{283, "import_as_name", 0, 4, states_27,
+	 "\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+	{284, "dotted_as_name", 0, 4, states_28,
+	 "\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+	{285, "import_as_names", 0, 3, states_29,
+	 "\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+	{286, "dotted_as_names", 0, 2, states_30,
+	 "\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+	{287, "dotted_name", 0, 2, states_31,
+	 "\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+	{288, "global_stmt", 0, 3, states_32,
+	 "\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000"},
+	{289, "exec_stmt", 0, 7, states_33,
+	 "\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000"},
+	{290, "assert_stmt", 0, 5, states_34,
+	 "\000\000\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000\000"},
+	{291, "compound_stmt", 0, 2, states_35,
+	 "\000\010\004\000\000\000\000\000\000\000\000\310\011\000\000\000\000\000\000\000\001"},
+	{292, "if_stmt", 0, 8, states_36,
+	 "\000\000\000\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\000\000"},
+	{293, "while_stmt", 0, 8, states_37,
+	 "\000\000\000\000\000\000\000\000\000\000\000\100\000\000\000\000\000\000\000\000\000"},
+	{294, "for_stmt", 0, 10, states_38,
+	 "\000\000\000\000\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\000"},
+	{295, "try_stmt", 0, 13, states_39,
+	 "\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000"},
+	{296, "with_stmt", 0, 6, states_40,
+	 "\000\000\000\000\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\000"},
+	{297, "with_var", 0, 3, states_41,
+	 "\000\000\010\000\000\000\000\000\000\100\000\000\000\000\000\000\000\000\000\000\000"},
+	{298, "except_clause", 0, 5, states_42,
+	 "\000\000\000\000\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000"},
+	{299, "suite", 0, 5, states_43,
+	 "\004\040\010\000\000\000\000\025\074\005\023\000\000\020\004\000\300\020\222\006\200"},
+	{300, "testlist_safe", 0, 5, states_44,
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\020\004\000\300\020\222\006\000"},
+	{301, "old_test", 0, 2, states_45,
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\020\004\000\300\020\222\006\000"},
+	{302, "old_lambdef", 0, 5, states_46,
+	 "\000\000\000\000\000\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000"},
+	{303, "test", 0, 6, states_47,
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\020\004\000\300\020\222\006\000"},
+	{304, "or_test", 0, 2, states_48,
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\004\000\300\020\222\006\000"},
+	{305, "and_test", 0, 2, states_49,
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\004\000\300\020\222\006\000"},
+	{306, "not_test", 0, 3, states_50,
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\004\000\300\020\222\006\000"},
+	{307, "comparison", 0, 2, states_51,
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\300\020\222\006\000"},
+	{308, "comp_op", 0, 4, states_52,
+	 "\000\000\000\000\000\000\000\000\000\000\010\000\000\000\344\037\000\000\000\000\000"},
+	{309, "expr", 0, 2, states_53,
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\300\020\222\006\000"},
+	{310, "xor_expr", 0, 2, states_54,
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\300\020\222\006\000"},
+	{311, "and_expr", 0, 2, states_55,
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\300\020\222\006\000"},
+	{312, "shift_expr", 0, 2, states_56,
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\300\020\222\006\000"},
+	{313, "arith_expr", 0, 2, states_57,
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\300\020\222\006\000"},
+	{314, "term", 0, 2, states_58,
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\300\020\222\006\000"},
+	{315, "factor", 0, 3, states_59,
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\300\020\222\006\000"},
+	{316, "power", 0, 4, states_60,
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\222\006\000"},
+	{317, "atom", 0, 11, states_61,
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\222\006\000"},
+	{318, "listmaker", 0, 5, states_62,
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\020\004\000\300\020\222\006\000"},
+	{319, "testlist_gexp", 0, 5, states_63,
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\020\004\000\300\020\222\006\000"},
+	{320, "lambdef", 0, 5, states_64,
+	 "\000\000\000\000\000\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000"},
+	{321, "trailer", 0, 7, states_65,
+	 "\000\040\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\000\002\000\000"},
+	{322, "subscriptlist", 0, 3, states_66,
+	 "\000\040\050\000\000\000\000\000\000\010\000\000\000\020\004\000\300\020\222\006\000"},
+	{323, "subscript", 0, 7, states_67,
+	 "\000\040\050\000\000\000\000\000\000\010\000\000\000\020\004\000\300\020\222\006\000"},
+	{324, "sliceop", 0, 3, states_68,
+	 "\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+	{325, "exprlist", 0, 3, states_69,
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\300\020\222\006\000"},
+	{326, "testlist", 0, 3, states_70,
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\020\004\000\300\020\222\006\000"},
+	{327, "dictmaker", 0, 5, states_71,
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\020\004\000\300\020\222\006\000"},
+	{328, "classdef", 0, 8, states_72,
+	 "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001"},
+	{329, "arglist", 0, 8, states_73,
+	 "\000\040\010\060\000\000\000\000\000\000\000\000\000\020\004\000\300\020\222\006\000"},
+	{330, "argument", 0, 4, states_74,
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\020\004\000\300\020\222\006\000"},
+	{331, "list_iter", 0, 2, states_75,
+	 "\000\000\000\000\000\000\000\000\000\000\000\210\000\000\000\000\000\000\000\000\000"},
+	{332, "list_for", 0, 6, states_76,
+	 "\000\000\000\000\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\000"},
+	{333, "list_if", 0, 4, states_77,
+	 "\000\000\000\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\000\000"},
+	{334, "gen_iter", 0, 2, states_78,
+	 "\000\000\000\000\000\000\000\000\000\000\000\210\000\000\000\000\000\000\000\000\000"},
+	{335, "gen_for", 0, 6, states_79,
+	 "\000\000\000\000\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\000"},
+	{336, "gen_if", 0, 4, states_80,
+	 "\000\000\000\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\000\000"},
+	{337, "testlist1", 0, 2, states_81,
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\020\004\000\300\020\222\006\000"},
+	{338, "encoding_decl", 0, 2, states_82,
+	 "\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+	{339, "yield_expr", 0, 3, states_83,
+	 "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\200"},
+};
+static label labels[168] = {
+	{0, "EMPTY"},
+	{256, 0},
+	{4, 0},
+	{267, 0},
+	{291, 0},
+	{257, 0},
+	{266, 0},
+	{0, 0},
+	{258, 0},
+	{326, 0},
+	{259, 0},
+	{50, 0},
+	{287, 0},
+	{7, 0},
+	{329, 0},
+	{8, 0},
+	{260, 0},
+	{261, 0},
+	{1, "def"},
+	{1, 0},
+	{262, 0},
+	{11, 0},
+	{299, 0},
+	{263, 0},
+	{264, 0},
+	{22, 0},
+	{303, 0},
+	{12, 0},
+	{16, 0},
+	{36, 0},
+	{265, 0},
+	{268, 0},
+	{13, 0},
+	{269, 0},
+	{271, 0},
+	{272, 0},
+	{273, 0},
+	{274, 0},
+	{280, 0},
+	{288, 0},
+	{289, 0},
+	{290, 0},
+	{270, 0},
+	{339, 0},
+	{37, 0},
+	{38, 0},
+	{39, 0},
+	{40, 0},
+	{41, 0},
+	{42, 0},
+	{43, 0},
+	{44, 0},
+	{45, 0},
+	{46, 0},
+	{47, 0},
+	{49, 0},
+	{1, "print"},
+	{35, 0},
+	{1, "del"},
+	{325, 0},
+	{1, "pass"},
+	{275, 0},
+	{276, 0},
+	{277, 0},
+	{279, 0},
+	{278, 0},
+	{1, "break"},
+	{1, "continue"},
+	{1, "return"},
+	{1, "raise"},
+	{281, 0},
+	{282, 0},
+	{1, "import"},
+	{286, 0},
+	{1, "from"},
+	{23, 0},
+	{285, 0},
+	{283, 0},
+	{1, "as"},
+	{284, 0},
+	{1, "global"},
+	{1, "exec"},
+	{309, 0},
+	{1, "in"},
+	{1, "assert"},
+	{292, 0},
+	{293, 0},
+	{294, 0},
+	{295, 0},
+	{296, 0},
+	{328, 0},
+	{1, "if"},
+	{1, "elif"},
+	{1, "else"},
+	{1, "while"},
+	{1, "for"},
+	{1, "try"},
+	{298, 0},
+	{1, "finally"},
+	{1, "with"},
+	{297, 0},
+	{1, "except"},
+	{5, 0},
+	{6, 0},
+	{300, 0},
+	{301, 0},
+	{304, 0},
+	{302, 0},
+	{1, "lambda"},
+	{320, 0},
+	{305, 0},
+	{1, "or"},
+	{306, 0},
+	{1, "and"},
+	{1, "not"},
+	{307, 0},
+	{308, 0},
+	{20, 0},
+	{21, 0},
+	{28, 0},
+	{31, 0},
+	{30, 0},
+	{29, 0},
+	{29, 0},
+	{1, "is"},
+	{310, 0},
+	{18, 0},
+	{311, 0},
+	{33, 0},
+	{312, 0},
+	{19, 0},
+	{313, 0},
+	{34, 0},
+	{314, 0},
+	{14, 0},
+	{15, 0},
+	{315, 0},
+	{17, 0},
+	{24, 0},
+	{48, 0},
+	{32, 0},
+	{316, 0},
+	{317, 0},
+	{321, 0},
+	{319, 0},
+	{9, 0},
+	{318, 0},
+	{10, 0},
+	{26, 0},
+	{327, 0},
+	{27, 0},
+	{25, 0},
+	{337, 0},
+	{2, 0},
+	{3, 0},
+	{332, 0},
+	{335, 0},
+	{322, 0},
+	{323, 0},
+	{324, 0},
+	{1, "class"},
+	{330, 0},
+	{331, 0},
+	{333, 0},
+	{334, 0},
+	{336, 0},
+	{338, 0},
+	{1, "yield"},
+};
+grammar _PyParser_Grammar = {
+	84,
+	dfas,
+	{168, labels},
+	256
+};

Added: vendor/Python/current/Python/hypot.c
===================================================================
--- vendor/Python/current/Python/hypot.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/hypot.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,23 @@
+/* hypot() replacement */
+
+#include "pyconfig.h"
+#include "pyport.h"
+
+double hypot(double x, double y)
+{
+	double yx;
+
+	x = fabs(x);
+	y = fabs(y);
+	if (x < y) {
+		double temp = x;
+		x = y;
+		y = temp;
+	}
+	if (x == 0.)
+		return 0.;
+	else {
+		yx = y/x;
+		return x*sqrt(1.+yx*yx);
+	}
+}

Added: vendor/Python/current/Python/import.c
===================================================================
--- vendor/Python/current/Python/import.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/import.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,3160 @@
+
+/* Module definition and import implementation */
+
+#include "Python.h"
+
+#include "Python-ast.h"
+#include "pyarena.h"
+#include "pythonrun.h"
+#include "errcode.h"
+#include "marshal.h"
+#include "code.h"
+#include "compile.h"
+#include "eval.h"
+#include "osdefs.h"
+#include "importdl.h"
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef __cplusplus
+extern "C" { 
+#endif
+
+extern time_t PyOS_GetLastModificationTime(char *, FILE *);
+						/* In getmtime.c */
+
+/* Magic word to reject .pyc files generated by other Python versions.
+   It should change for each incompatible change to the bytecode.
+
+   The value of CR and LF is incorporated so if you ever read or write
+   a .pyc file in text mode the magic number will be wrong; also, the
+   Apple MPW compiler swaps their values, botching string constants.
+
+   The magic numbers must be spaced apart atleast 2 values, as the
+   -U interpeter flag will cause MAGIC+1 being used. They have been
+   odd numbers for some time now.
+
+   There were a variety of old schemes for setting the magic number.
+   The current working scheme is to increment the previous value by
+   10.
+
+   Known values:
+       Python 1.5:   20121
+       Python 1.5.1: 20121
+       Python 1.5.2: 20121
+       Python 1.6:   50428
+       Python 2.0:   50823
+       Python 2.0.1: 50823
+       Python 2.1:   60202
+       Python 2.1.1: 60202
+       Python 2.1.2: 60202
+       Python 2.2:   60717
+       Python 2.3a0: 62011
+       Python 2.3a0: 62021
+       Python 2.3a0: 62011 (!)
+       Python 2.4a0: 62041
+       Python 2.4a3: 62051
+       Python 2.4b1: 62061
+       Python 2.5a0: 62071
+       Python 2.5a0: 62081 (ast-branch)
+       Python 2.5a0: 62091 (with)
+       Python 2.5a0: 62092 (changed WITH_CLEANUP opcode)
+       Python 2.5b3: 62101 (fix wrong code: for x, in ...)
+       Python 2.5b3: 62111 (fix wrong code: x += yield)
+       Python 2.5c1: 62121 (fix wrong lnotab with for loops and
+       			    storing constants that should have been removed)
+       Python 2.5c2: 62131 (fix wrong code: for x, in ... in listcomp/genexp)
+.
+*/
+#define MAGIC (62131 | ((long)'\r'<<16) | ((long)'\n'<<24))
+
+/* Magic word as global; note that _PyImport_Init() can change the
+   value of this global to accommodate for alterations of how the
+   compiler works which are enabled by command line switches. */
+static long pyc_magic = MAGIC;
+
+/* See _PyImport_FixupExtension() below */
+static PyObject *extensions = NULL;
+
+/* This table is defined in config.c: */
+extern struct _inittab _PyImport_Inittab[];
+
+struct _inittab *PyImport_Inittab = _PyImport_Inittab;
+
+/* these tables define the module suffixes that Python recognizes */
+struct filedescr * _PyImport_Filetab = NULL;
+
+#ifdef RISCOS
+static const struct filedescr _PyImport_StandardFiletab[] = {
+	{"/py", "U", PY_SOURCE},
+	{"/pyc", "rb", PY_COMPILED},
+	{0, 0}
+};
+#else
+static const struct filedescr _PyImport_StandardFiletab[] = {
+	{".py", "U", PY_SOURCE},
+#ifdef MS_WINDOWS
+	{".pyw", "U", PY_SOURCE},
+#endif
+	{".pyc", "rb", PY_COMPILED},
+	{0, 0}
+};
+#endif
+
+static PyTypeObject NullImporterType;	/* Forward reference */
+
+/* Initialize things */
+
+void
+_PyImport_Init(void)
+{
+	const struct filedescr *scan;
+	struct filedescr *filetab;
+	int countD = 0;
+	int countS = 0;
+
+	/* prepare _PyImport_Filetab: copy entries from
+	   _PyImport_DynLoadFiletab and _PyImport_StandardFiletab.
+	 */
+	for (scan = _PyImport_DynLoadFiletab; scan->suffix != NULL; ++scan)
+		++countD;
+	for (scan = _PyImport_StandardFiletab; scan->suffix != NULL; ++scan)
+		++countS;
+	filetab = PyMem_NEW(struct filedescr, countD + countS + 1);
+	if (filetab == NULL)
+		Py_FatalError("Can't initialize import file table.");
+	memcpy(filetab, _PyImport_DynLoadFiletab,
+	       countD * sizeof(struct filedescr));
+	memcpy(filetab + countD, _PyImport_StandardFiletab,
+	       countS * sizeof(struct filedescr));
+	filetab[countD + countS].suffix = NULL;
+
+	_PyImport_Filetab = filetab;
+
+	if (Py_OptimizeFlag) {
+		/* Replace ".pyc" with ".pyo" in _PyImport_Filetab */
+		for (; filetab->suffix != NULL; filetab++) {
+#ifndef RISCOS
+			if (strcmp(filetab->suffix, ".pyc") == 0)
+				filetab->suffix = ".pyo";
+#else
+			if (strcmp(filetab->suffix, "/pyc") == 0)
+				filetab->suffix = "/pyo";
+#endif
+		}
+	}
+
+	if (Py_UnicodeFlag) {
+		/* Fix the pyc_magic so that byte compiled code created
+		   using the all-Unicode method doesn't interfere with
+		   code created in normal operation mode. */
+		pyc_magic = MAGIC + 1;
+	}
+}
+
+void
+_PyImportHooks_Init(void)
+{
+	PyObject *v, *path_hooks = NULL, *zimpimport;
+	int err = 0;
+
+	/* adding sys.path_hooks and sys.path_importer_cache, setting up
+	   zipimport */
+	if (PyType_Ready(&NullImporterType) < 0)
+		goto error;
+
+	if (Py_VerboseFlag)
+		PySys_WriteStderr("# installing zipimport hook\n");
+
+	v = PyList_New(0);
+	if (v == NULL)
+		goto error;
+	err = PySys_SetObject("meta_path", v);
+	Py_DECREF(v);
+	if (err)
+		goto error;
+	v = PyDict_New();
+	if (v == NULL)
+		goto error;
+	err = PySys_SetObject("path_importer_cache", v);
+	Py_DECREF(v);
+	if (err)
+		goto error;
+	path_hooks = PyList_New(0);
+	if (path_hooks == NULL)
+		goto error;
+	err = PySys_SetObject("path_hooks", path_hooks);
+	if (err) {
+  error:
+		PyErr_Print();
+		Py_FatalError("initializing sys.meta_path, sys.path_hooks, "
+			      "path_importer_cache, or NullImporter failed"
+			      );
+	}
+
+	zimpimport = PyImport_ImportModule("zipimport");
+	if (zimpimport == NULL) {
+		PyErr_Clear(); /* No zip import module -- okay */
+		if (Py_VerboseFlag)
+			PySys_WriteStderr("# can't import zipimport\n");
+	}
+	else {
+		PyObject *zipimporter = PyObject_GetAttrString(zimpimport,
+							       "zipimporter");
+		Py_DECREF(zimpimport);
+		if (zipimporter == NULL) {
+			PyErr_Clear(); /* No zipimporter object -- okay */
+			if (Py_VerboseFlag)
+				PySys_WriteStderr(
+				    "# can't import zipimport.zipimporter\n");
+		}
+		else {
+			/* sys.path_hooks.append(zipimporter) */
+			err = PyList_Append(path_hooks, zipimporter);
+			Py_DECREF(zipimporter);
+			if (err)
+				goto error;
+			if (Py_VerboseFlag)
+				PySys_WriteStderr(
+					"# installed zipimport hook\n");
+		}
+	}
+	Py_DECREF(path_hooks);
+}
+
+void
+_PyImport_Fini(void)
+{
+	Py_XDECREF(extensions);
+	extensions = NULL;
+	PyMem_DEL(_PyImport_Filetab);
+	_PyImport_Filetab = NULL;
+}
+
+
+/* Locking primitives to prevent parallel imports of the same module
+   in different threads to return with a partially loaded module.
+   These calls are serialized by the global interpreter lock. */
+
+#ifdef WITH_THREAD
+
+#include "pythread.h"
+
+static PyThread_type_lock import_lock = 0;
+static long import_lock_thread = -1;
+static int import_lock_level = 0;
+
+static void
+lock_import(void)
+{
+	long me = PyThread_get_thread_ident();
+	if (me == -1)
+		return; /* Too bad */
+	if (import_lock == NULL) {
+		import_lock = PyThread_allocate_lock();
+		if (import_lock == NULL)
+			return;  /* Nothing much we can do. */
+	}
+	if (import_lock_thread == me) {
+		import_lock_level++;
+		return;
+	}
+	if (import_lock_thread != -1 || !PyThread_acquire_lock(import_lock, 0))
+	{
+		PyThreadState *tstate = PyEval_SaveThread();
+		PyThread_acquire_lock(import_lock, 1);
+		PyEval_RestoreThread(tstate);
+	}
+	import_lock_thread = me;
+	import_lock_level = 1;
+}
+
+static int
+unlock_import(void)
+{
+	long me = PyThread_get_thread_ident();
+	if (me == -1 || import_lock == NULL)
+		return 0; /* Too bad */
+	if (import_lock_thread != me)
+		return -1;
+	import_lock_level--;
+	if (import_lock_level == 0) {
+		import_lock_thread = -1;
+		PyThread_release_lock(import_lock);
+	}
+	return 1;
+}
+
+/* This function is called from PyOS_AfterFork to ensure that newly
+   created child processes do not share locks with the parent. */
+
+void
+_PyImport_ReInitLock(void)
+{
+#ifdef _AIX
+	if (import_lock != NULL)
+		import_lock = PyThread_allocate_lock();
+#endif
+}
+
+#else
+
+#define lock_import()
+#define unlock_import() 0
+
+#endif
+
+static PyObject *
+imp_lock_held(PyObject *self, PyObject *noargs)
+{
+#ifdef WITH_THREAD
+	return PyBool_FromLong(import_lock_thread != -1);
+#else
+	return PyBool_FromLong(0);
+#endif
+}
+
+static PyObject *
+imp_acquire_lock(PyObject *self, PyObject *noargs)
+{
+#ifdef WITH_THREAD
+	lock_import();
+#endif
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+imp_release_lock(PyObject *self, PyObject *noargs)
+{
+#ifdef WITH_THREAD
+	if (unlock_import() < 0) {
+		PyErr_SetString(PyExc_RuntimeError,
+				"not holding the import lock");
+		return NULL;
+	}
+#endif
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static void
+imp_modules_reloading_clear (void)
+{
+	PyInterpreterState *interp = PyThreadState_Get()->interp;
+	if (interp->modules_reloading == NULL)
+		return;
+	PyDict_Clear(interp->modules_reloading);
+	return;
+}
+
+/* Helper for sys */
+
+PyObject *
+PyImport_GetModuleDict(void)
+{
+	PyInterpreterState *interp = PyThreadState_GET()->interp;
+	if (interp->modules == NULL)
+		Py_FatalError("PyImport_GetModuleDict: no module dictionary!");
+	return interp->modules;
+}
+
+
+/* List of names to clear in sys */
+static char* sys_deletes[] = {
+	"path", "argv", "ps1", "ps2", "exitfunc",
+	"exc_type", "exc_value", "exc_traceback",
+	"last_type", "last_value", "last_traceback",
+	"path_hooks", "path_importer_cache", "meta_path",
+	NULL
+};
+
+static char* sys_files[] = {
+	"stdin", "__stdin__",
+	"stdout", "__stdout__",
+	"stderr", "__stderr__",
+	NULL
+};
+
+
+/* Un-initialize things, as good as we can */
+
+void
+PyImport_Cleanup(void)
+{
+	Py_ssize_t pos, ndone;
+	char *name;
+	PyObject *key, *value, *dict;
+	PyInterpreterState *interp = PyThreadState_GET()->interp;
+	PyObject *modules = interp->modules;
+
+	if (modules == NULL)
+		return; /* Already done */
+
+	/* Delete some special variables first.  These are common
+	   places where user values hide and people complain when their
+	   destructors fail.  Since the modules containing them are
+	   deleted *last* of all, they would come too late in the normal
+	   destruction order.  Sigh. */
+
+	value = PyDict_GetItemString(modules, "__builtin__");
+	if (value != NULL && PyModule_Check(value)) {
+		dict = PyModule_GetDict(value);
+		if (Py_VerboseFlag)
+			PySys_WriteStderr("# clear __builtin__._\n");
+		PyDict_SetItemString(dict, "_", Py_None);
+	}
+	value = PyDict_GetItemString(modules, "sys");
+	if (value != NULL && PyModule_Check(value)) {
+		char **p;
+		PyObject *v;
+		dict = PyModule_GetDict(value);
+		for (p = sys_deletes; *p != NULL; p++) {
+			if (Py_VerboseFlag)
+				PySys_WriteStderr("# clear sys.%s\n", *p);
+			PyDict_SetItemString(dict, *p, Py_None);
+		}
+		for (p = sys_files; *p != NULL; p+=2) {
+			if (Py_VerboseFlag)
+				PySys_WriteStderr("# restore sys.%s\n", *p);
+			v = PyDict_GetItemString(dict, *(p+1));
+			if (v == NULL)
+				v = Py_None;
+			PyDict_SetItemString(dict, *p, v);
+		}
+	}
+
+	/* First, delete __main__ */
+	value = PyDict_GetItemString(modules, "__main__");
+	if (value != NULL && PyModule_Check(value)) {
+		if (Py_VerboseFlag)
+			PySys_WriteStderr("# cleanup __main__\n");
+		_PyModule_Clear(value);
+		PyDict_SetItemString(modules, "__main__", Py_None);
+	}
+
+	/* The special treatment of __builtin__ here is because even
+	   when it's not referenced as a module, its dictionary is
+	   referenced by almost every module's __builtins__.  Since
+	   deleting a module clears its dictionary (even if there are
+	   references left to it), we need to delete the __builtin__
+	   module last.  Likewise, we don't delete sys until the very
+	   end because it is implicitly referenced (e.g. by print).
+
+	   Also note that we 'delete' modules by replacing their entry
+	   in the modules dict with None, rather than really deleting
+	   them; this avoids a rehash of the modules dictionary and
+	   also marks them as "non existent" so they won't be
+	   re-imported. */
+
+	/* Next, repeatedly delete modules with a reference count of
+	   one (skipping __builtin__ and sys) and delete them */
+	do {
+		ndone = 0;
+		pos = 0;
+		while (PyDict_Next(modules, &pos, &key, &value)) {
+			if (value->ob_refcnt != 1)
+				continue;
+			if (PyString_Check(key) && PyModule_Check(value)) {
+				name = PyString_AS_STRING(key);
+				if (strcmp(name, "__builtin__") == 0)
+					continue;
+				if (strcmp(name, "sys") == 0)
+					continue;
+				if (Py_VerboseFlag)
+					PySys_WriteStderr(
+						"# cleanup[1] %s\n", name);
+				_PyModule_Clear(value);
+				PyDict_SetItem(modules, key, Py_None);
+				ndone++;
+			}
+		}
+	} while (ndone > 0);
+
+	/* Next, delete all modules (still skipping __builtin__ and sys) */
+	pos = 0;
+	while (PyDict_Next(modules, &pos, &key, &value)) {
+		if (PyString_Check(key) && PyModule_Check(value)) {
+			name = PyString_AS_STRING(key);
+			if (strcmp(name, "__builtin__") == 0)
+				continue;
+			if (strcmp(name, "sys") == 0)
+				continue;
+			if (Py_VerboseFlag)
+				PySys_WriteStderr("# cleanup[2] %s\n", name);
+			_PyModule_Clear(value);
+			PyDict_SetItem(modules, key, Py_None);
+		}
+	}
+
+	/* Next, delete sys and __builtin__ (in that order) */
+	value = PyDict_GetItemString(modules, "sys");
+	if (value != NULL && PyModule_Check(value)) {
+		if (Py_VerboseFlag)
+			PySys_WriteStderr("# cleanup sys\n");
+		_PyModule_Clear(value);
+		PyDict_SetItemString(modules, "sys", Py_None);
+	}
+	value = PyDict_GetItemString(modules, "__builtin__");
+	if (value != NULL && PyModule_Check(value)) {
+		if (Py_VerboseFlag)
+			PySys_WriteStderr("# cleanup __builtin__\n");
+		_PyModule_Clear(value);
+		PyDict_SetItemString(modules, "__builtin__", Py_None);
+	}
+
+	/* Finally, clear and delete the modules directory */
+	PyDict_Clear(modules);
+	interp->modules = NULL;
+	Py_DECREF(modules);
+	Py_CLEAR(interp->modules_reloading);
+}
+
+
+/* Helper for pythonrun.c -- return magic number */
+
+long
+PyImport_GetMagicNumber(void)
+{
+	return pyc_magic;
+}
+
+
+/* Magic for extension modules (built-in as well as dynamically
+   loaded).  To prevent initializing an extension module more than
+   once, we keep a static dictionary 'extensions' keyed by module name
+   (for built-in modules) or by filename (for dynamically loaded
+   modules), containing these modules.  A copy of the module's
+   dictionary is stored by calling _PyImport_FixupExtension()
+   immediately after the module initialization function succeeds.  A
+   copy can be retrieved from there by calling
+   _PyImport_FindExtension(). */
+
+PyObject *
+_PyImport_FixupExtension(char *name, char *filename)
+{
+	PyObject *modules, *mod, *dict, *copy;
+	if (extensions == NULL) {
+		extensions = PyDict_New();
+		if (extensions == NULL)
+			return NULL;
+	}
+	modules = PyImport_GetModuleDict();
+	mod = PyDict_GetItemString(modules, name);
+	if (mod == NULL || !PyModule_Check(mod)) {
+		PyErr_Format(PyExc_SystemError,
+		  "_PyImport_FixupExtension: module %.200s not loaded", name);
+		return NULL;
+	}
+	dict = PyModule_GetDict(mod);
+	if (dict == NULL)
+		return NULL;
+	copy = PyDict_Copy(dict);
+	if (copy == NULL)
+		return NULL;
+	PyDict_SetItemString(extensions, filename, copy);
+	Py_DECREF(copy);
+	return copy;
+}
+
+PyObject *
+_PyImport_FindExtension(char *name, char *filename)
+{
+	PyObject *dict, *mod, *mdict;
+	if (extensions == NULL)
+		return NULL;
+	dict = PyDict_GetItemString(extensions, filename);
+	if (dict == NULL)
+		return NULL;
+	mod = PyImport_AddModule(name);
+	if (mod == NULL)
+		return NULL;
+	mdict = PyModule_GetDict(mod);
+	if (mdict == NULL)
+		return NULL;
+	if (PyDict_Update(mdict, dict))
+		return NULL;
+	if (Py_VerboseFlag)
+		PySys_WriteStderr("import %s # previously loaded (%s)\n",
+			name, filename);
+	return mod;
+}
+
+
+/* Get the module object corresponding to a module name.
+   First check the modules dictionary if there's one there,
+   if not, create a new one and insert it in the modules dictionary.
+   Because the former action is most common, THIS DOES NOT RETURN A
+   'NEW' REFERENCE! */
+
+PyObject *
+PyImport_AddModule(const char *name)
+{
+	PyObject *modules = PyImport_GetModuleDict();
+	PyObject *m;
+
+	if ((m = PyDict_GetItemString(modules, name)) != NULL &&
+	    PyModule_Check(m))
+		return m;
+	m = PyModule_New(name);
+	if (m == NULL)
+		return NULL;
+	if (PyDict_SetItemString(modules, name, m) != 0) {
+		Py_DECREF(m);
+		return NULL;
+	}
+	Py_DECREF(m); /* Yes, it still exists, in modules! */
+
+	return m;
+}
+
+/* Remove name from sys.modules, if it's there. */
+static void
+_RemoveModule(const char *name)
+{
+	PyObject *modules = PyImport_GetModuleDict();
+	if (PyDict_GetItemString(modules, name) == NULL)
+		return;
+	if (PyDict_DelItemString(modules, name) < 0)
+		Py_FatalError("import:  deleting existing key in"
+			      "sys.modules failed");
+}
+
+/* Execute a code object in a module and return the module object
+ * WITH INCREMENTED REFERENCE COUNT.  If an error occurs, name is
+ * removed from sys.modules, to avoid leaving damaged module objects
+ * in sys.modules.  The caller may wish to restore the original
+ * module object (if any) in this case; PyImport_ReloadModule is an
+ * example.
+ */
+PyObject *
+PyImport_ExecCodeModule(char *name, PyObject *co)
+{
+	return PyImport_ExecCodeModuleEx(name, co, (char *)NULL);
+}
+
+PyObject *
+PyImport_ExecCodeModuleEx(char *name, PyObject *co, char *pathname)
+{
+	PyObject *modules = PyImport_GetModuleDict();
+	PyObject *m, *d, *v;
+
+	m = PyImport_AddModule(name);
+	if (m == NULL)
+		return NULL;
+	/* If the module is being reloaded, we get the old module back
+	   and re-use its dict to exec the new code. */
+	d = PyModule_GetDict(m);
+	if (PyDict_GetItemString(d, "__builtins__") == NULL) {
+		if (PyDict_SetItemString(d, "__builtins__",
+					 PyEval_GetBuiltins()) != 0)
+			goto error;
+	}
+	/* Remember the filename as the __file__ attribute */
+	v = NULL;
+	if (pathname != NULL) {
+		v = PyString_FromString(pathname);
+		if (v == NULL)
+			PyErr_Clear();
+	}
+	if (v == NULL) {
+		v = ((PyCodeObject *)co)->co_filename;
+		Py_INCREF(v);
+	}
+	if (PyDict_SetItemString(d, "__file__", v) != 0)
+		PyErr_Clear(); /* Not important enough to report */
+	Py_DECREF(v);
+
+	v = PyEval_EvalCode((PyCodeObject *)co, d, d);
+	if (v == NULL)
+		goto error;
+	Py_DECREF(v);
+
+	if ((m = PyDict_GetItemString(modules, name)) == NULL) {
+		PyErr_Format(PyExc_ImportError,
+			     "Loaded module %.200s not found in sys.modules",
+			     name);
+		return NULL;
+	}
+
+	Py_INCREF(m);
+
+	return m;
+
+  error:
+	_RemoveModule(name);
+	return NULL;
+}
+
+
+/* Given a pathname for a Python source file, fill a buffer with the
+   pathname for the corresponding compiled file.  Return the pathname
+   for the compiled file, or NULL if there's no space in the buffer.
+   Doesn't set an exception. */
+
+static char *
+make_compiled_pathname(char *pathname, char *buf, size_t buflen)
+{
+	size_t len = strlen(pathname);
+	if (len+2 > buflen)
+		return NULL;
+
+#ifdef MS_WINDOWS
+	/* Treat .pyw as if it were .py.  The case of ".pyw" must match
+	   that used in _PyImport_StandardFiletab. */
+	if (len >= 4 && strcmp(&pathname[len-4], ".pyw") == 0)
+		--len;	/* pretend 'w' isn't there */
+#endif
+	memcpy(buf, pathname, len);
+	buf[len] = Py_OptimizeFlag ? 'o' : 'c';
+	buf[len+1] = '\0';
+
+	return buf;
+}
+
+
+/* Given a pathname for a Python source file, its time of last
+   modification, and a pathname for a compiled file, check whether the
+   compiled file represents the same version of the source.  If so,
+   return a FILE pointer for the compiled file, positioned just after
+   the header; if not, return NULL.
+   Doesn't set an exception. */
+
+static FILE *
+check_compiled_module(char *pathname, time_t mtime, char *cpathname)
+{
+	FILE *fp;
+	long magic;
+	long pyc_mtime;
+
+	fp = fopen(cpathname, "rb");
+	if (fp == NULL)
+		return NULL;
+	magic = PyMarshal_ReadLongFromFile(fp);
+	if (magic != pyc_magic) {
+		if (Py_VerboseFlag)
+			PySys_WriteStderr("# %s has bad magic\n", cpathname);
+		fclose(fp);
+		return NULL;
+	}
+	pyc_mtime = PyMarshal_ReadLongFromFile(fp);
+	if (pyc_mtime != mtime) {
+		if (Py_VerboseFlag)
+			PySys_WriteStderr("# %s has bad mtime\n", cpathname);
+		fclose(fp);
+		return NULL;
+	}
+	if (Py_VerboseFlag)
+		PySys_WriteStderr("# %s matches %s\n", cpathname, pathname);
+	return fp;
+}
+
+
+/* Read a code object from a file and check it for validity */
+
+static PyCodeObject *
+read_compiled_module(char *cpathname, FILE *fp)
+{
+	PyObject *co;
+
+	co = PyMarshal_ReadLastObjectFromFile(fp);
+	if (co == NULL)
+		return NULL;
+	if (!PyCode_Check(co)) {
+		PyErr_Format(PyExc_ImportError,
+			     "Non-code object in %.200s", cpathname);
+		Py_DECREF(co);
+		return NULL;
+	}
+	return (PyCodeObject *)co;
+}
+
+
+/* Load a module from a compiled file, execute it, and return its
+   module object WITH INCREMENTED REFERENCE COUNT */
+
+static PyObject *
+load_compiled_module(char *name, char *cpathname, FILE *fp)
+{
+	long magic;
+	PyCodeObject *co;
+	PyObject *m;
+
+	magic = PyMarshal_ReadLongFromFile(fp);
+	if (magic != pyc_magic) {
+		PyErr_Format(PyExc_ImportError,
+			     "Bad magic number in %.200s", cpathname);
+		return NULL;
+	}
+	(void) PyMarshal_ReadLongFromFile(fp);
+	co = read_compiled_module(cpathname, fp);
+	if (co == NULL)
+		return NULL;
+	if (Py_VerboseFlag)
+		PySys_WriteStderr("import %s # precompiled from %s\n",
+			name, cpathname);
+	m = PyImport_ExecCodeModuleEx(name, (PyObject *)co, cpathname);
+	Py_DECREF(co);
+
+	return m;
+}
+
+/* Parse a source file and return the corresponding code object */
+
+static PyCodeObject *
+parse_source_module(const char *pathname, FILE *fp)
+{
+	PyCodeObject *co = NULL;
+	mod_ty mod;
+	PyArena *arena = PyArena_New();
+	if (arena == NULL)
+		return NULL;
+
+	mod = PyParser_ASTFromFile(fp, pathname, Py_file_input, 0, 0, 0, 
+				   NULL, arena);
+	if (mod) {
+		co = PyAST_Compile(mod, pathname, NULL, arena);
+	}
+	PyArena_Free(arena);
+	return co;
+}
+
+
+/* Helper to open a bytecode file for writing in exclusive mode */
+
+static FILE *
+open_exclusive(char *filename)
+{
+#if defined(O_EXCL)&&defined(O_CREAT)&&defined(O_WRONLY)&&defined(O_TRUNC)
+	/* Use O_EXCL to avoid a race condition when another process tries to
+	   write the same file.  When that happens, our open() call fails,
+	   which is just fine (since it's only a cache).
+	   XXX If the file exists and is writable but the directory is not
+	   writable, the file will never be written.  Oh well.
+	*/
+	int fd;
+	(void) unlink(filename);
+	fd = open(filename, O_EXCL|O_CREAT|O_WRONLY|O_TRUNC
+#ifdef O_BINARY
+				|O_BINARY   /* necessary for Windows */
+#endif
+#ifdef __VMS
+                        , 0666, "ctxt=bin", "shr=nil"
+#else
+                        , 0666
+#endif
+		  );
+	if (fd < 0)
+		return NULL;
+	return fdopen(fd, "wb");
+#else
+	/* Best we can do -- on Windows this can't happen anyway */
+	return fopen(filename, "wb");
+#endif
+}
+
+
+/* Write a compiled module to a file, placing the time of last
+   modification of its source into the header.
+   Errors are ignored, if a write error occurs an attempt is made to
+   remove the file. */
+
+static void
+write_compiled_module(PyCodeObject *co, char *cpathname, time_t mtime)
+{
+	FILE *fp;
+
+	fp = open_exclusive(cpathname);
+	if (fp == NULL) {
+		if (Py_VerboseFlag)
+			PySys_WriteStderr(
+				"# can't create %s\n", cpathname);
+		return;
+	}
+	PyMarshal_WriteLongToFile(pyc_magic, fp, Py_MARSHAL_VERSION);
+	/* First write a 0 for mtime */
+	PyMarshal_WriteLongToFile(0L, fp, Py_MARSHAL_VERSION);
+	PyMarshal_WriteObjectToFile((PyObject *)co, fp, Py_MARSHAL_VERSION);
+	if (fflush(fp) != 0 || ferror(fp)) {
+		if (Py_VerboseFlag)
+			PySys_WriteStderr("# can't write %s\n", cpathname);
+		/* Don't keep partial file */
+		fclose(fp);
+		(void) unlink(cpathname);
+		return;
+	}
+	/* Now write the true mtime */
+	fseek(fp, 4L, 0);
+	assert(mtime < LONG_MAX);
+	PyMarshal_WriteLongToFile((long)mtime, fp, Py_MARSHAL_VERSION);
+	fflush(fp);
+	fclose(fp);
+	if (Py_VerboseFlag)
+		PySys_WriteStderr("# wrote %s\n", cpathname);
+}
+
+
+/* Load a source module from a given file and return its module
+   object WITH INCREMENTED REFERENCE COUNT.  If there's a matching
+   byte-compiled file, use that instead. */
+
+static PyObject *
+load_source_module(char *name, char *pathname, FILE *fp)
+{
+	time_t mtime;
+	FILE *fpc;
+	char buf[MAXPATHLEN+1];
+	char *cpathname;
+	PyCodeObject *co;
+	PyObject *m;
+
+	mtime = PyOS_GetLastModificationTime(pathname, fp);
+	if (mtime == (time_t)(-1)) {
+		PyErr_Format(PyExc_RuntimeError,
+			     "unable to get modification time from '%s'",
+			     pathname);
+		return NULL;
+	}
+#if SIZEOF_TIME_T > 4
+	/* Python's .pyc timestamp handling presumes that the timestamp fits
+	   in 4 bytes. This will be fine until sometime in the year 2038,
+	   when a 4-byte signed time_t will overflow.
+	 */
+	if (mtime >> 32) {
+		PyErr_SetString(PyExc_OverflowError,
+			"modification time overflows a 4 byte field");
+		return NULL;
+	}
+#endif
+	cpathname = make_compiled_pathname(pathname, buf,
+					   (size_t)MAXPATHLEN + 1);
+	if (cpathname != NULL &&
+	    (fpc = check_compiled_module(pathname, mtime, cpathname))) {
+		co = read_compiled_module(cpathname, fpc);
+		fclose(fpc);
+		if (co == NULL)
+			return NULL;
+		if (Py_VerboseFlag)
+			PySys_WriteStderr("import %s # precompiled from %s\n",
+				name, cpathname);
+		pathname = cpathname;
+	}
+	else {
+		co = parse_source_module(pathname, fp);
+		if (co == NULL)
+			return NULL;
+		if (Py_VerboseFlag)
+			PySys_WriteStderr("import %s # from %s\n",
+				name, pathname);
+		if (cpathname)
+			write_compiled_module(co, cpathname, mtime);
+	}
+	m = PyImport_ExecCodeModuleEx(name, (PyObject *)co, pathname);
+	Py_DECREF(co);
+
+	return m;
+}
+
+
+/* Forward */
+static PyObject *load_module(char *, FILE *, char *, int, PyObject *);
+static struct filedescr *find_module(char *, char *, PyObject *,
+				     char *, size_t, FILE **, PyObject **);
+static struct _frozen *find_frozen(char *name);
+
+/* Load a package and return its module object WITH INCREMENTED
+   REFERENCE COUNT */
+
+static PyObject *
+load_package(char *name, char *pathname)
+{
+	PyObject *m, *d;
+	PyObject *file = NULL;
+	PyObject *path = NULL;
+	int err;
+	char buf[MAXPATHLEN+1];
+	FILE *fp = NULL;
+	struct filedescr *fdp;
+
+	m = PyImport_AddModule(name);
+	if (m == NULL)
+		return NULL;
+	if (Py_VerboseFlag)
+		PySys_WriteStderr("import %s # directory %s\n",
+			name, pathname);
+	d = PyModule_GetDict(m);
+	file = PyString_FromString(pathname);
+	if (file == NULL)
+		goto error;
+	path = Py_BuildValue("[O]", file);
+	if (path == NULL)
+		goto error;
+	err = PyDict_SetItemString(d, "__file__", file);
+	if (err == 0)
+		err = PyDict_SetItemString(d, "__path__", path);
+	if (err != 0)
+		goto error;
+	buf[0] = '\0';
+	fdp = find_module(name, "__init__", path, buf, sizeof(buf), &fp, NULL);
+	if (fdp == NULL) {
+		if (PyErr_ExceptionMatches(PyExc_ImportError)) {
+			PyErr_Clear();
+			Py_INCREF(m);
+		}
+		else
+			m = NULL;
+		goto cleanup;
+	}
+	m = load_module(name, fp, buf, fdp->type, NULL);
+	if (fp != NULL)
+		fclose(fp);
+	goto cleanup;
+
+  error:
+  	m = NULL;
+  cleanup:
+	Py_XDECREF(path);
+	Py_XDECREF(file);
+	return m;
+}
+
+
+/* Helper to test for built-in module */
+
+static int
+is_builtin(char *name)
+{
+	int i;
+	for (i = 0; PyImport_Inittab[i].name != NULL; i++) {
+		if (strcmp(name, PyImport_Inittab[i].name) == 0) {
+			if (PyImport_Inittab[i].initfunc == NULL)
+				return -1;
+			else
+				return 1;
+		}
+	}
+	return 0;
+}
+
+
+/* Return an importer object for a sys.path/pkg.__path__ item 'p',
+   possibly by fetching it from the path_importer_cache dict. If it
+   wasn't yet cached, traverse path_hooks until it a hook is found
+   that can handle the path item. Return None if no hook could;
+   this tells our caller it should fall back to the builtin
+   import mechanism. Cache the result in path_importer_cache.
+   Returns a borrowed reference. */
+
+static PyObject *
+get_path_importer(PyObject *path_importer_cache, PyObject *path_hooks,
+		  PyObject *p)
+{
+	PyObject *importer;
+	Py_ssize_t j, nhooks;
+
+	/* These conditions are the caller's responsibility: */
+	assert(PyList_Check(path_hooks));
+	assert(PyDict_Check(path_importer_cache));
+
+	nhooks = PyList_Size(path_hooks);
+	if (nhooks < 0)
+		return NULL; /* Shouldn't happen */
+
+	importer = PyDict_GetItem(path_importer_cache, p);
+	if (importer != NULL)
+		return importer;
+
+	/* set path_importer_cache[p] to None to avoid recursion */
+	if (PyDict_SetItem(path_importer_cache, p, Py_None) != 0)
+		return NULL;
+
+	for (j = 0; j < nhooks; j++) {
+		PyObject *hook = PyList_GetItem(path_hooks, j);
+		if (hook == NULL)
+			return NULL;
+		importer = PyObject_CallFunctionObjArgs(hook, p, NULL);
+		if (importer != NULL)
+			break;
+
+		if (!PyErr_ExceptionMatches(PyExc_ImportError)) {
+			return NULL;
+		}
+		PyErr_Clear();
+	}
+	if (importer == NULL) {
+		importer = PyObject_CallFunctionObjArgs(
+			(PyObject *)&NullImporterType, p, NULL
+		);
+		if (importer == NULL) {
+			if (PyErr_ExceptionMatches(PyExc_ImportError)) {
+				PyErr_Clear();
+				return Py_None;
+			}
+		}
+	}
+	if (importer != NULL) {
+		int err = PyDict_SetItem(path_importer_cache, p, importer);
+		Py_DECREF(importer);
+		if (err != 0)
+			return NULL;
+	}
+	return importer;
+}
+
+/* Search the path (default sys.path) for a module.  Return the
+   corresponding filedescr struct, and (via return arguments) the
+   pathname and an open file.  Return NULL if the module is not found. */
+
+#ifdef MS_COREDLL
+extern FILE *PyWin_FindRegisteredModule(const char *, struct filedescr **,
+					char *, Py_ssize_t);
+#endif
+
+static int case_ok(char *, Py_ssize_t, Py_ssize_t, char *);
+static int find_init_module(char *); /* Forward */
+static struct filedescr importhookdescr = {"", "", IMP_HOOK};
+
+static struct filedescr *
+find_module(char *fullname, char *subname, PyObject *path, char *buf,
+	    size_t buflen, FILE **p_fp, PyObject **p_loader)
+{
+	Py_ssize_t i, npath;
+	size_t len, namelen;
+	struct filedescr *fdp = NULL;
+	char *filemode;
+	FILE *fp = NULL;
+	PyObject *path_hooks, *path_importer_cache;
+#ifndef RISCOS
+	struct stat statbuf;
+#endif
+	static struct filedescr fd_frozen = {"", "", PY_FROZEN};
+	static struct filedescr fd_builtin = {"", "", C_BUILTIN};
+	static struct filedescr fd_package = {"", "", PKG_DIRECTORY};
+	char name[MAXPATHLEN+1];
+#if defined(PYOS_OS2)
+	size_t saved_len;
+	size_t saved_namelen;
+	char *saved_buf = NULL;
+#endif
+	if (p_loader != NULL)
+		*p_loader = NULL;
+
+	if (strlen(subname) > MAXPATHLEN) {
+		PyErr_SetString(PyExc_OverflowError,
+				"module name is too long");
+		return NULL;
+	}
+	strcpy(name, subname);
+
+	/* sys.meta_path import hook */
+	if (p_loader != NULL) {
+		PyObject *meta_path;
+
+		meta_path = PySys_GetObject("meta_path");
+		if (meta_path == NULL || !PyList_Check(meta_path)) {
+			PyErr_SetString(PyExc_ImportError,
+					"sys.meta_path must be a list of "
+					"import hooks");
+			return NULL;
+		}
+		Py_INCREF(meta_path);  /* zap guard */
+		npath = PyList_Size(meta_path);
+		for (i = 0; i < npath; i++) {
+			PyObject *loader;
+			PyObject *hook = PyList_GetItem(meta_path, i);
+			loader = PyObject_CallMethod(hook, "find_module",
+						     "sO", fullname,
+						     path != NULL ?
+						     path : Py_None);
+			if (loader == NULL) {
+				Py_DECREF(meta_path);
+				return NULL;  /* true error */
+			}
+			if (loader != Py_None) {
+				/* a loader was found */
+				*p_loader = loader;
+				Py_DECREF(meta_path);
+				return &importhookdescr;
+			}
+			Py_DECREF(loader);
+		}
+		Py_DECREF(meta_path);
+	}
+
+	if (path != NULL && PyString_Check(path)) {
+		/* The only type of submodule allowed inside a "frozen"
+		   package are other frozen modules or packages. */
+		if (PyString_Size(path) + 1 + strlen(name) >= (size_t)buflen) {
+			PyErr_SetString(PyExc_ImportError,
+					"full frozen module name too long");
+			return NULL;
+		}
+		strcpy(buf, PyString_AsString(path));
+		strcat(buf, ".");
+		strcat(buf, name);
+		strcpy(name, buf);
+		if (find_frozen(name) != NULL) {
+			strcpy(buf, name);
+			return &fd_frozen;
+		}
+		PyErr_Format(PyExc_ImportError,
+			     "No frozen submodule named %.200s", name);
+		return NULL;
+	}
+	if (path == NULL) {
+		if (is_builtin(name)) {
+			strcpy(buf, name);
+			return &fd_builtin;
+		}
+		if ((find_frozen(name)) != NULL) {
+			strcpy(buf, name);
+			return &fd_frozen;
+		}
+
+#ifdef MS_COREDLL
+		fp = PyWin_FindRegisteredModule(name, &fdp, buf, buflen);
+		if (fp != NULL) {
+			*p_fp = fp;
+			return fdp;
+		}
+#endif
+		path = PySys_GetObject("path");
+	}
+	if (path == NULL || !PyList_Check(path)) {
+		PyErr_SetString(PyExc_ImportError,
+				"sys.path must be a list of directory names");
+		return NULL;
+	}
+
+	path_hooks = PySys_GetObject("path_hooks");
+	if (path_hooks == NULL || !PyList_Check(path_hooks)) {
+		PyErr_SetString(PyExc_ImportError,
+				"sys.path_hooks must be a list of "
+				"import hooks");
+		return NULL;
+	}
+	path_importer_cache = PySys_GetObject("path_importer_cache");
+	if (path_importer_cache == NULL ||
+	    !PyDict_Check(path_importer_cache)) {
+		PyErr_SetString(PyExc_ImportError,
+				"sys.path_importer_cache must be a dict");
+		return NULL;
+	}
+
+	npath = PyList_Size(path);
+	namelen = strlen(name);
+	for (i = 0; i < npath; i++) {
+		PyObject *copy = NULL;
+		PyObject *v = PyList_GetItem(path, i);
+		if (!v)
+			return NULL;
+#ifdef Py_USING_UNICODE
+		if (PyUnicode_Check(v)) {
+			copy = PyUnicode_Encode(PyUnicode_AS_UNICODE(v),
+				PyUnicode_GET_SIZE(v), Py_FileSystemDefaultEncoding, NULL);
+			if (copy == NULL)
+				return NULL;
+			v = copy;
+		}
+		else
+#endif
+		if (!PyString_Check(v))
+			continue;
+		len = PyString_GET_SIZE(v);
+		if (len + 2 + namelen + MAXSUFFIXSIZE >= buflen) {
+			Py_XDECREF(copy);
+			continue; /* Too long */
+		}
+		strcpy(buf, PyString_AS_STRING(v));
+		if (strlen(buf) != len) {
+			Py_XDECREF(copy);
+			continue; /* v contains '\0' */
+		}
+
+		/* sys.path_hooks import hook */
+		if (p_loader != NULL) {
+			PyObject *importer;
+
+			importer = get_path_importer(path_importer_cache,
+						     path_hooks, v);
+			if (importer == NULL) {
+				Py_XDECREF(copy);
+				return NULL;
+			}
+			/* Note: importer is a borrowed reference */
+			if (importer != Py_None) {
+				PyObject *loader;
+				loader = PyObject_CallMethod(importer,
+							     "find_module",
+							     "s", fullname);
+				Py_XDECREF(copy);
+				if (loader == NULL)
+					return NULL;  /* error */
+				if (loader != Py_None) {
+					/* a loader was found */
+					*p_loader = loader;
+					return &importhookdescr;
+				}
+				Py_DECREF(loader);
+				continue;
+			}
+		}
+		/* no hook was found, use builtin import */
+
+		if (len > 0 && buf[len-1] != SEP
+#ifdef ALTSEP
+		    && buf[len-1] != ALTSEP
+#endif
+		    )
+			buf[len++] = SEP;
+		strcpy(buf+len, name);
+		len += namelen;
+
+		/* Check for package import (buf holds a directory name,
+		   and there's an __init__ module in that directory */
+#ifdef HAVE_STAT
+		if (stat(buf, &statbuf) == 0 &&         /* it exists */
+		    S_ISDIR(statbuf.st_mode) &&         /* it's a directory */
+		    case_ok(buf, len, namelen, name)) { /* case matches */
+			if (find_init_module(buf)) { /* and has __init__.py */
+				Py_XDECREF(copy);
+				return &fd_package;
+			}
+			else {
+				char warnstr[MAXPATHLEN+80];
+				sprintf(warnstr, "Not importing directory "
+					"'%.*s': missing __init__.py", 
+					MAXPATHLEN, buf);
+				if (PyErr_Warn(PyExc_ImportWarning,
+					       warnstr)) {
+					Py_XDECREF(copy);
+					return NULL;
+				}
+			}
+		}
+#else
+		/* XXX How are you going to test for directories? */
+#ifdef RISCOS
+		if (isdir(buf) &&
+		    case_ok(buf, len, namelen, name)) {
+			if (find_init_module(buf)) {
+				Py_XDECREF(copy);
+				return &fd_package;
+			}
+			else {
+				char warnstr[MAXPATHLEN+80];
+				sprintf(warnstr, "Not importing directory "
+					"'%.*s': missing __init__.py", 
+					MAXPATHLEN, buf);
+				if (PyErr_Warn(PyExc_ImportWarning,
+					       warnstr)) {
+					Py_XDECREF(copy);
+					return NULL;
+				}
+		}
+#endif
+#endif
+#if defined(PYOS_OS2)
+		/* take a snapshot of the module spec for restoration
+		 * after the 8 character DLL hackery
+		 */
+		saved_buf = strdup(buf);
+		saved_len = len;
+		saved_namelen = namelen;
+#endif /* PYOS_OS2 */
+		for (fdp = _PyImport_Filetab; fdp->suffix != NULL; fdp++) {
+#if defined(PYOS_OS2)
+			/* OS/2 limits DLLs to 8 character names (w/o
+			   extension)
+			 * so if the name is longer than that and its a
+			 * dynamically loaded module we're going to try,
+			 * truncate the name before trying
+			 */
+			if (strlen(subname) > 8) {
+				/* is this an attempt to load a C extension? */
+				const struct filedescr *scan;
+				scan = _PyImport_DynLoadFiletab;
+				while (scan->suffix != NULL) {
+					if (!strcmp(scan->suffix, fdp->suffix))
+						break;
+					else
+						scan++;
+				}
+				if (scan->suffix != NULL) {
+					/* yes, so truncate the name */
+					namelen = 8;
+					len -= strlen(subname) - namelen;
+					buf[len] = '\0';
+				}
+			}
+#endif /* PYOS_OS2 */
+			strcpy(buf+len, fdp->suffix);
+			if (Py_VerboseFlag > 1)
+				PySys_WriteStderr("# trying %s\n", buf);
+			filemode = fdp->mode;
+			if (filemode[0] == 'U')
+				filemode = "r" PY_STDIOTEXTMODE;
+			fp = fopen(buf, filemode);
+			if (fp != NULL) {
+				if (case_ok(buf, len, namelen, name))
+					break;
+				else {	 /* continue search */
+					fclose(fp);
+					fp = NULL;
+				}
+			}
+#if defined(PYOS_OS2)
+			/* restore the saved snapshot */
+			strcpy(buf, saved_buf);
+			len = saved_len;
+			namelen = saved_namelen;
+#endif
+		}
+#if defined(PYOS_OS2)
+		/* don't need/want the module name snapshot anymore */
+		if (saved_buf)
+		{
+			free(saved_buf);
+			saved_buf = NULL;
+		}
+#endif
+		Py_XDECREF(copy);
+		if (fp != NULL)
+			break;
+	}
+	if (fp == NULL) {
+		PyErr_Format(PyExc_ImportError,
+			     "No module named %.200s", name);
+		return NULL;
+	}
+	*p_fp = fp;
+	return fdp;
+}
+
+/* Helpers for main.c
+ *  Find the source file corresponding to a named module
+ */
+struct filedescr *
+_PyImport_FindModule(const char *name, PyObject *path, char *buf,
+	    size_t buflen, FILE **p_fp, PyObject **p_loader)
+{
+	return find_module((char *) name, (char *) name, path,
+			   buf, buflen, p_fp, p_loader);
+}
+
+PyAPI_FUNC(int) _PyImport_IsScript(struct filedescr * fd)
+{
+	return fd->type == PY_SOURCE || fd->type == PY_COMPILED;
+}
+
+/* case_ok(char* buf, Py_ssize_t len, Py_ssize_t namelen, char* name)
+ * The arguments here are tricky, best shown by example:
+ *    /a/b/c/d/e/f/g/h/i/j/k/some_long_module_name.py\0
+ *    ^                      ^                   ^    ^
+ *    |--------------------- buf ---------------------|
+ *    |------------------- len ------------------|
+ *                           |------ name -------|
+ *                           |----- namelen -----|
+ * buf is the full path, but len only counts up to (& exclusive of) the
+ * extension.  name is the module name, also exclusive of extension.
+ *
+ * We've already done a successful stat() or fopen() on buf, so know that
+ * there's some match, possibly case-insensitive.
+ *
+ * case_ok() is to return 1 if there's a case-sensitive match for
+ * name, else 0.  case_ok() is also to return 1 if envar PYTHONCASEOK
+ * exists.
+ *
+ * case_ok() is used to implement case-sensitive import semantics even
+ * on platforms with case-insensitive filesystems.  It's trivial to implement
+ * for case-sensitive filesystems.  It's pretty much a cross-platform
+ * nightmare for systems with case-insensitive filesystems.
+ */
+
+/* First we may need a pile of platform-specific header files; the sequence
+ * of #if's here should match the sequence in the body of case_ok().
+ */
+#if defined(MS_WINDOWS)
+#include <windows.h>
+
+#elif defined(DJGPP)
+#include <dir.h>
+
+#elif (defined(__MACH__) && defined(__APPLE__) || defined(__CYGWIN__)) && defined(HAVE_DIRENT_H)
+#include <sys/types.h>
+#include <dirent.h>
+
+#elif defined(PYOS_OS2)
+#define INCL_DOS
+#define INCL_DOSERRORS
+#define INCL_NOPMAPI
+#include <os2.h>
+
+#elif defined(RISCOS)
+#include "oslib/osfscontrol.h"
+#endif
+
+static int
+case_ok(char *buf, Py_ssize_t len, Py_ssize_t namelen, char *name)
+{
+/* Pick a platform-specific implementation; the sequence of #if's here should
+ * match the sequence just above.
+ */
+
+/* MS_WINDOWS */
+#if defined(MS_WINDOWS)
+	WIN32_FIND_DATA data;
+	HANDLE h;
+
+	if (Py_GETENV("PYTHONCASEOK") != NULL)
+		return 1;
+
+	h = FindFirstFile(buf, &data);
+	if (h == INVALID_HANDLE_VALUE) {
+		PyErr_Format(PyExc_NameError,
+		  "Can't find file for module %.100s\n(filename %.300s)",
+		  name, buf);
+		return 0;
+	}
+	FindClose(h);
+	return strncmp(data.cFileName, name, namelen) == 0;
+
+/* DJGPP */
+#elif defined(DJGPP)
+	struct ffblk ffblk;
+	int done;
+
+	if (Py_GETENV("PYTHONCASEOK") != NULL)
+		return 1;
+
+	done = findfirst(buf, &ffblk, FA_ARCH|FA_RDONLY|FA_HIDDEN|FA_DIREC);
+	if (done) {
+		PyErr_Format(PyExc_NameError,
+		  "Can't find file for module %.100s\n(filename %.300s)",
+		  name, buf);
+		return 0;
+	}
+	return strncmp(ffblk.ff_name, name, namelen) == 0;
+
+/* new-fangled macintosh (macosx) or Cygwin */
+#elif (defined(__MACH__) && defined(__APPLE__) || defined(__CYGWIN__)) && defined(HAVE_DIRENT_H)
+	DIR *dirp;
+	struct dirent *dp;
+	char dirname[MAXPATHLEN + 1];
+	const int dirlen = len - namelen - 1; /* don't want trailing SEP */
+
+	if (Py_GETENV("PYTHONCASEOK") != NULL)
+		return 1;
+
+	/* Copy the dir component into dirname; substitute "." if empty */
+	if (dirlen <= 0) {
+		dirname[0] = '.';
+		dirname[1] = '\0';
+	}
+	else {
+		assert(dirlen <= MAXPATHLEN);
+		memcpy(dirname, buf, dirlen);
+		dirname[dirlen] = '\0';
+	}
+	/* Open the directory and search the entries for an exact match. */
+	dirp = opendir(dirname);
+	if (dirp) {
+		char *nameWithExt = buf + len - namelen;
+		while ((dp = readdir(dirp)) != NULL) {
+			const int thislen =
+#ifdef _DIRENT_HAVE_D_NAMELEN
+						dp->d_namlen;
+#else
+						strlen(dp->d_name);
+#endif
+			if (thislen >= namelen &&
+			    strcmp(dp->d_name, nameWithExt) == 0) {
+				(void)closedir(dirp);
+				return 1; /* Found */
+			}
+		}
+		(void)closedir(dirp);
+	}
+	return 0 ; /* Not found */
+
+/* RISC OS */
+#elif defined(RISCOS)
+	char canon[MAXPATHLEN+1]; /* buffer for the canonical form of the path */
+	char buf2[MAXPATHLEN+2];
+	char *nameWithExt = buf+len-namelen;
+	int canonlen;
+	os_error *e;
+
+	if (Py_GETENV("PYTHONCASEOK") != NULL)
+		return 1;
+
+	/* workaround:
+	   append wildcard, otherwise case of filename wouldn't be touched */
+	strcpy(buf2, buf);
+	strcat(buf2, "*");
+
+	e = xosfscontrol_canonicalise_path(buf2,canon,0,0,MAXPATHLEN+1,&canonlen);
+	canonlen = MAXPATHLEN+1-canonlen;
+	if (e || canonlen<=0 || canonlen>(MAXPATHLEN+1) )
+		return 0;
+	if (strcmp(nameWithExt, canon+canonlen-strlen(nameWithExt))==0)
+		return 1; /* match */
+
+	return 0;
+
+/* OS/2 */
+#elif defined(PYOS_OS2)
+	HDIR hdir = 1;
+	ULONG srchcnt = 1;
+	FILEFINDBUF3 ffbuf;
+	APIRET rc;
+
+	if (getenv("PYTHONCASEOK") != NULL)
+		return 1;
+
+	rc = DosFindFirst(buf,
+			  &hdir,
+			  FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
+			  &ffbuf, sizeof(ffbuf),
+			  &srchcnt,
+			  FIL_STANDARD);
+	if (rc != NO_ERROR)
+		return 0;
+	return strncmp(ffbuf.achName, name, namelen) == 0;
+
+/* assuming it's a case-sensitive filesystem, so there's nothing to do! */
+#else
+	return 1;
+
+#endif
+}
+
+
+#ifdef HAVE_STAT
+/* Helper to look for __init__.py or __init__.py[co] in potential package */
+static int
+find_init_module(char *buf)
+{
+	const size_t save_len = strlen(buf);
+	size_t i = save_len;
+	char *pname;  /* pointer to start of __init__ */
+	struct stat statbuf;
+
+/*	For calling case_ok(buf, len, namelen, name):
+ *	/a/b/c/d/e/f/g/h/i/j/k/some_long_module_name.py\0
+ *	^                      ^                   ^    ^
+ *	|--------------------- buf ---------------------|
+ *	|------------------- len ------------------|
+ *	                       |------ name -------|
+ *	                       |----- namelen -----|
+ */
+	if (save_len + 13 >= MAXPATHLEN)
+		return 0;
+	buf[i++] = SEP;
+	pname = buf + i;
+	strcpy(pname, "__init__.py");
+	if (stat(buf, &statbuf) == 0) {
+		if (case_ok(buf,
+			    save_len + 9,	/* len("/__init__") */
+		            8,   		/* len("__init__") */
+		            pname)) {
+			buf[save_len] = '\0';
+			return 1;
+		}
+	}
+	i += strlen(pname);
+	strcpy(buf+i, Py_OptimizeFlag ? "o" : "c");
+	if (stat(buf, &statbuf) == 0) {
+		if (case_ok(buf,
+			    save_len + 9,	/* len("/__init__") */
+		            8,   		/* len("__init__") */
+		            pname)) {
+			buf[save_len] = '\0';
+			return 1;
+		}
+	}
+	buf[save_len] = '\0';
+	return 0;
+}
+
+#else
+
+#ifdef RISCOS
+static int
+find_init_module(buf)
+	char *buf;
+{
+	int save_len = strlen(buf);
+	int i = save_len;
+
+	if (save_len + 13 >= MAXPATHLEN)
+		return 0;
+	buf[i++] = SEP;
+	strcpy(buf+i, "__init__/py");
+	if (isfile(buf)) {
+		buf[save_len] = '\0';
+		return 1;
+	}
+
+	if (Py_OptimizeFlag)
+		strcpy(buf+i, "o");
+	else
+		strcpy(buf+i, "c");
+	if (isfile(buf)) {
+		buf[save_len] = '\0';
+		return 1;
+	}
+	buf[save_len] = '\0';
+	return 0;
+}
+#endif /*RISCOS*/
+
+#endif /* HAVE_STAT */
+
+
+static int init_builtin(char *); /* Forward */
+
+/* Load an external module using the default search path and return
+   its module object WITH INCREMENTED REFERENCE COUNT */
+
+static PyObject *
+load_module(char *name, FILE *fp, char *buf, int type, PyObject *loader)
+{
+	PyObject *modules;
+	PyObject *m;
+	int err;
+
+	/* First check that there's an open file (if we need one)  */
+	switch (type) {
+	case PY_SOURCE:
+	case PY_COMPILED:
+		if (fp == NULL) {
+			PyErr_Format(PyExc_ValueError,
+			   "file object required for import (type code %d)",
+				     type);
+			return NULL;
+		}
+	}
+
+	switch (type) {
+
+	case PY_SOURCE:
+		m = load_source_module(name, buf, fp);
+		break;
+
+	case PY_COMPILED:
+		m = load_compiled_module(name, buf, fp);
+		break;
+
+#ifdef HAVE_DYNAMIC_LOADING
+	case C_EXTENSION:
+		m = _PyImport_LoadDynamicModule(name, buf, fp);
+		break;
+#endif
+
+	case PKG_DIRECTORY:
+		m = load_package(name, buf);
+		break;
+
+	case C_BUILTIN:
+	case PY_FROZEN:
+		if (buf != NULL && buf[0] != '\0')
+			name = buf;
+		if (type == C_BUILTIN)
+			err = init_builtin(name);
+		else
+			err = PyImport_ImportFrozenModule(name);
+		if (err < 0)
+			return NULL;
+		if (err == 0) {
+			PyErr_Format(PyExc_ImportError,
+				     "Purported %s module %.200s not found",
+				     type == C_BUILTIN ?
+						"builtin" : "frozen",
+				     name);
+			return NULL;
+		}
+		modules = PyImport_GetModuleDict();
+		m = PyDict_GetItemString(modules, name);
+		if (m == NULL) {
+			PyErr_Format(
+				PyExc_ImportError,
+				"%s module %.200s not properly initialized",
+				type == C_BUILTIN ?
+					"builtin" : "frozen",
+				name);
+			return NULL;
+		}
+		Py_INCREF(m);
+		break;
+
+	case IMP_HOOK: {
+		if (loader == NULL) {
+			PyErr_SetString(PyExc_ImportError,
+					"import hook without loader");
+			return NULL;
+		}
+		m = PyObject_CallMethod(loader, "load_module", "s", name);
+		break;
+	}
+
+	default:
+		PyErr_Format(PyExc_ImportError,
+			     "Don't know how to import %.200s (type code %d)",
+			      name, type);
+		m = NULL;
+
+	}
+
+	return m;
+}
+
+
+/* Initialize a built-in module.
+   Return 1 for succes, 0 if the module is not found, and -1 with
+   an exception set if the initialization failed. */
+
+static int
+init_builtin(char *name)
+{
+	struct _inittab *p;
+
+	if (_PyImport_FindExtension(name, name) != NULL)
+		return 1;
+
+	for (p = PyImport_Inittab; p->name != NULL; p++) {
+		if (strcmp(name, p->name) == 0) {
+			if (p->initfunc == NULL) {
+				PyErr_Format(PyExc_ImportError,
+				    "Cannot re-init internal module %.200s",
+				    name);
+				return -1;
+			}
+			if (Py_VerboseFlag)
+				PySys_WriteStderr("import %s # builtin\n", name);
+			(*p->initfunc)();
+			if (PyErr_Occurred())
+				return -1;
+			if (_PyImport_FixupExtension(name, name) == NULL)
+				return -1;
+			return 1;
+		}
+	}
+	return 0;
+}
+
+
+/* Frozen modules */
+
+static struct _frozen *
+find_frozen(char *name)
+{
+	struct _frozen *p;
+
+	for (p = PyImport_FrozenModules; ; p++) {
+		if (p->name == NULL)
+			return NULL;
+		if (strcmp(p->name, name) == 0)
+			break;
+	}
+	return p;
+}
+
+static PyObject *
+get_frozen_object(char *name)
+{
+	struct _frozen *p = find_frozen(name);
+	int size;
+
+	if (p == NULL) {
+		PyErr_Format(PyExc_ImportError,
+			     "No such frozen object named %.200s",
+			     name);
+		return NULL;
+	}
+	if (p->code == NULL) {
+		PyErr_Format(PyExc_ImportError,
+			     "Excluded frozen object named %.200s",
+			     name);
+		return NULL;
+	}
+	size = p->size;
+	if (size < 0)
+		size = -size;
+	return PyMarshal_ReadObjectFromString((char *)p->code, size);
+}
+
+/* Initialize a frozen module.
+   Return 1 for succes, 0 if the module is not found, and -1 with
+   an exception set if the initialization failed.
+   This function is also used from frozenmain.c */
+
+int
+PyImport_ImportFrozenModule(char *name)
+{
+	struct _frozen *p = find_frozen(name);
+	PyObject *co;
+	PyObject *m;
+	int ispackage;
+	int size;
+
+	if (p == NULL)
+		return 0;
+	if (p->code == NULL) {
+		PyErr_Format(PyExc_ImportError,
+			     "Excluded frozen object named %.200s",
+			     name);
+		return -1;
+	}
+	size = p->size;
+	ispackage = (size < 0);
+	if (ispackage)
+		size = -size;
+	if (Py_VerboseFlag)
+		PySys_WriteStderr("import %s # frozen%s\n",
+			name, ispackage ? " package" : "");
+	co = PyMarshal_ReadObjectFromString((char *)p->code, size);
+	if (co == NULL)
+		return -1;
+	if (!PyCode_Check(co)) {
+		PyErr_Format(PyExc_TypeError,
+			     "frozen object %.200s is not a code object",
+			     name);
+		goto err_return;
+	}
+	if (ispackage) {
+		/* Set __path__ to the package name */
+		PyObject *d, *s;
+		int err;
+		m = PyImport_AddModule(name);
+		if (m == NULL)
+			goto err_return;
+		d = PyModule_GetDict(m);
+		s = PyString_InternFromString(name);
+		if (s == NULL)
+			goto err_return;
+		err = PyDict_SetItemString(d, "__path__", s);
+		Py_DECREF(s);
+		if (err != 0)
+			goto err_return;
+	}
+	m = PyImport_ExecCodeModuleEx(name, co, "<frozen>");
+	if (m == NULL)
+		goto err_return;
+	Py_DECREF(co);
+	Py_DECREF(m);
+	return 1;
+err_return:
+	Py_DECREF(co);
+	return -1;
+}
+
+
+/* Import a module, either built-in, frozen, or external, and return
+   its module object WITH INCREMENTED REFERENCE COUNT */
+
+PyObject *
+PyImport_ImportModule(const char *name)
+{
+	PyObject *pname;
+	PyObject *result;
+
+	pname = PyString_FromString(name);
+	if (pname == NULL)
+		return NULL;
+	result = PyImport_Import(pname);
+	Py_DECREF(pname);
+	return result;
+}
+
+/* Forward declarations for helper routines */
+static PyObject *get_parent(PyObject *globals, char *buf,
+			    Py_ssize_t *p_buflen, int level);
+static PyObject *load_next(PyObject *mod, PyObject *altmod,
+			   char **p_name, char *buf, Py_ssize_t *p_buflen);
+static int mark_miss(char *name);
+static int ensure_fromlist(PyObject *mod, PyObject *fromlist,
+			   char *buf, Py_ssize_t buflen, int recursive);
+static PyObject * import_submodule(PyObject *mod, char *name, char *fullname);
+
+/* The Magnum Opus of dotted-name import :-) */
+
+static PyObject *
+import_module_level(char *name, PyObject *globals, PyObject *locals,
+		    PyObject *fromlist, int level)
+{
+	char buf[MAXPATHLEN+1];
+	Py_ssize_t buflen = 0;
+	PyObject *parent, *head, *next, *tail;
+
+	parent = get_parent(globals, buf, &buflen, level);
+	if (parent == NULL)
+		return NULL;
+
+	head = load_next(parent, Py_None, &name, buf, &buflen);
+	if (head == NULL)
+		return NULL;
+
+	tail = head;
+	Py_INCREF(tail);
+	while (name) {
+		next = load_next(tail, tail, &name, buf, &buflen);
+		Py_DECREF(tail);
+		if (next == NULL) {
+			Py_DECREF(head);
+			return NULL;
+		}
+		tail = next;
+	}
+	if (tail == Py_None) {
+		/* If tail is Py_None, both get_parent and load_next found
+		   an empty module name: someone called __import__("") or
+		   doctored faulty bytecode */
+		Py_DECREF(tail);
+		Py_DECREF(head);
+		PyErr_SetString(PyExc_ValueError,
+				"Empty module name");
+		return NULL;
+	}
+
+	if (fromlist != NULL) {
+		if (fromlist == Py_None || !PyObject_IsTrue(fromlist))
+			fromlist = NULL;
+	}
+
+	if (fromlist == NULL) {
+		Py_DECREF(tail);
+		return head;
+	}
+
+	Py_DECREF(head);
+	if (!ensure_fromlist(tail, fromlist, buf, buflen, 0)) {
+		Py_DECREF(tail);
+		return NULL;
+	}
+
+	return tail;
+}
+
+/* For DLL compatibility */
+#undef PyImport_ImportModuleEx
+PyObject *
+PyImport_ImportModuleEx(char *name, PyObject *globals, PyObject *locals,
+			PyObject *fromlist)
+{
+	PyObject *result;
+	lock_import();
+	result = import_module_level(name, globals, locals, fromlist, -1);
+	if (unlock_import() < 0) {
+		Py_XDECREF(result);
+		PyErr_SetString(PyExc_RuntimeError,
+				"not holding the import lock");
+		return NULL;
+	}
+	return result;
+}
+#define PyImport_ImportModuleEx(n, g, l, f) \
+	PyImport_ImportModuleLevel(n, g, l, f, -1);
+
+PyObject *
+PyImport_ImportModuleLevel(char *name, PyObject *globals, PyObject *locals,
+			 PyObject *fromlist, int level)
+{
+	PyObject *result;
+	lock_import();
+	result = import_module_level(name, globals, locals, fromlist, level);
+	if (unlock_import() < 0) {
+		Py_XDECREF(result);
+		PyErr_SetString(PyExc_RuntimeError,
+				"not holding the import lock");
+		return NULL;
+	}
+	return result;
+}
+
+/* Return the package that an import is being performed in.  If globals comes
+   from the module foo.bar.bat (not itself a package), this returns the
+   sys.modules entry for foo.bar.  If globals is from a package's __init__.py,
+   the package's entry in sys.modules is returned, as a borrowed reference.
+
+   The *name* of the returned package is returned in buf, with the length of
+   the name in *p_buflen.
+
+   If globals doesn't come from a package or a module in a package, or a
+   corresponding entry is not found in sys.modules, Py_None is returned.
+*/
+static PyObject *
+get_parent(PyObject *globals, char *buf, Py_ssize_t *p_buflen, int level)
+{
+	static PyObject *namestr = NULL;
+	static PyObject *pathstr = NULL;
+	PyObject *modname, *modpath, *modules, *parent;
+
+	if (globals == NULL || !PyDict_Check(globals) || !level)
+		return Py_None;
+
+	if (namestr == NULL) {
+		namestr = PyString_InternFromString("__name__");
+		if (namestr == NULL)
+			return NULL;
+	}
+	if (pathstr == NULL) {
+		pathstr = PyString_InternFromString("__path__");
+		if (pathstr == NULL)
+			return NULL;
+	}
+
+	*buf = '\0';
+	*p_buflen = 0;
+	modname = PyDict_GetItem(globals, namestr);
+	if (modname == NULL || !PyString_Check(modname))
+		return Py_None;
+
+	modpath = PyDict_GetItem(globals, pathstr);
+	if (modpath != NULL) {
+		Py_ssize_t len = PyString_GET_SIZE(modname);
+		if (len > MAXPATHLEN) {
+			PyErr_SetString(PyExc_ValueError,
+					"Module name too long");
+			return NULL;
+		}
+		strcpy(buf, PyString_AS_STRING(modname));
+	}
+	else {
+		char *start = PyString_AS_STRING(modname);
+		char *lastdot = strrchr(start, '.');
+		size_t len;
+		if (lastdot == NULL && level > 0) {
+			PyErr_SetString(PyExc_ValueError,
+				"Attempted relative import in non-package");
+			return NULL;
+		}
+		if (lastdot == NULL)
+			return Py_None;
+		len = lastdot - start;
+		if (len >= MAXPATHLEN) {
+			PyErr_SetString(PyExc_ValueError,
+					"Module name too long");
+			return NULL;
+		}
+		strncpy(buf, start, len);
+		buf[len] = '\0';
+	}
+
+	while (--level > 0) {
+		char *dot = strrchr(buf, '.');
+		if (dot == NULL) {
+			PyErr_SetString(PyExc_ValueError,
+				"Attempted relative import beyond "
+				"toplevel package");
+			return NULL;
+		}
+		*dot = '\0';
+	}
+	*p_buflen = strlen(buf);
+
+	modules = PyImport_GetModuleDict();
+	parent = PyDict_GetItemString(modules, buf);
+	if (parent == NULL)
+		PyErr_Format(PyExc_SystemError,
+				"Parent module '%.200s' not loaded", buf);
+	return parent;
+	/* We expect, but can't guarantee, if parent != None, that:
+	   - parent.__name__ == buf
+	   - parent.__dict__ is globals
+	   If this is violated...  Who cares? */
+}
+
+/* altmod is either None or same as mod */
+static PyObject *
+load_next(PyObject *mod, PyObject *altmod, char **p_name, char *buf,
+	  Py_ssize_t *p_buflen)
+{
+	char *name = *p_name;
+	char *dot = strchr(name, '.');
+	size_t len;
+	char *p;
+	PyObject *result;
+
+	if (strlen(name) == 0) {
+		/* completely empty module name should only happen in
+		   'from . import' (or '__import__("")')*/
+		Py_INCREF(mod);
+		*p_name = NULL;
+		return mod;
+	}
+
+	if (dot == NULL) {
+		*p_name = NULL;
+		len = strlen(name);
+	}
+	else {
+		*p_name = dot+1;
+		len = dot-name;
+	}
+	if (len == 0) {
+		PyErr_SetString(PyExc_ValueError,
+				"Empty module name");
+		return NULL;
+	}
+
+	p = buf + *p_buflen;
+	if (p != buf)
+		*p++ = '.';
+	if (p+len-buf >= MAXPATHLEN) {
+		PyErr_SetString(PyExc_ValueError,
+				"Module name too long");
+		return NULL;
+	}
+	strncpy(p, name, len);
+	p[len] = '\0';
+	*p_buflen = p+len-buf;
+
+	result = import_submodule(mod, p, buf);
+	if (result == Py_None && altmod != mod) {
+		Py_DECREF(result);
+		/* Here, altmod must be None and mod must not be None */
+		result = import_submodule(altmod, p, p);
+		if (result != NULL && result != Py_None) {
+			if (mark_miss(buf) != 0) {
+				Py_DECREF(result);
+				return NULL;
+			}
+			strncpy(buf, name, len);
+			buf[len] = '\0';
+			*p_buflen = len;
+		}
+	}
+	if (result == NULL)
+		return NULL;
+
+	if (result == Py_None) {
+		Py_DECREF(result);
+		PyErr_Format(PyExc_ImportError,
+			     "No module named %.200s", name);
+		return NULL;
+	}
+
+	return result;
+}
+
+static int
+mark_miss(char *name)
+{
+	PyObject *modules = PyImport_GetModuleDict();
+	return PyDict_SetItemString(modules, name, Py_None);
+}
+
+static int
+ensure_fromlist(PyObject *mod, PyObject *fromlist, char *buf, Py_ssize_t buflen,
+		int recursive)
+{
+	int i;
+
+	if (!PyObject_HasAttrString(mod, "__path__"))
+		return 1;
+
+	for (i = 0; ; i++) {
+		PyObject *item = PySequence_GetItem(fromlist, i);
+		int hasit;
+		if (item == NULL) {
+			if (PyErr_ExceptionMatches(PyExc_IndexError)) {
+				PyErr_Clear();
+				return 1;
+			}
+			return 0;
+		}
+		if (!PyString_Check(item)) {
+			PyErr_SetString(PyExc_TypeError,
+					"Item in ``from list'' not a string");
+			Py_DECREF(item);
+			return 0;
+		}
+		if (PyString_AS_STRING(item)[0] == '*') {
+			PyObject *all;
+			Py_DECREF(item);
+			/* See if the package defines __all__ */
+			if (recursive)
+				continue; /* Avoid endless recursion */
+			all = PyObject_GetAttrString(mod, "__all__");
+			if (all == NULL)
+				PyErr_Clear();
+			else {
+				int ret = ensure_fromlist(mod, all, buf, buflen, 1);
+				Py_DECREF(all);
+				if (!ret)
+					return 0;
+			}
+			continue;
+		}
+		hasit = PyObject_HasAttr(mod, item);
+		if (!hasit) {
+			char *subname = PyString_AS_STRING(item);
+			PyObject *submod;
+			char *p;
+			if (buflen + strlen(subname) >= MAXPATHLEN) {
+				PyErr_SetString(PyExc_ValueError,
+						"Module name too long");
+				Py_DECREF(item);
+				return 0;
+			}
+			p = buf + buflen;
+			*p++ = '.';
+			strcpy(p, subname);
+			submod = import_submodule(mod, subname, buf);
+			Py_XDECREF(submod);
+			if (submod == NULL) {
+				Py_DECREF(item);
+				return 0;
+			}
+		}
+		Py_DECREF(item);
+	}
+
+	/* NOTREACHED */
+}
+
+static int
+add_submodule(PyObject *mod, PyObject *submod, char *fullname, char *subname,
+	      PyObject *modules)
+{
+	if (mod == Py_None)
+		return 1;
+	/* Irrespective of the success of this load, make a
+	   reference to it in the parent package module.  A copy gets
+	   saved in the modules dictionary under the full name, so get a
+	   reference from there, if need be.  (The exception is when the
+	   load failed with a SyntaxError -- then there's no trace in
+	   sys.modules.  In that case, of course, do nothing extra.) */
+	if (submod == NULL) {
+		submod = PyDict_GetItemString(modules, fullname);
+		if (submod == NULL)
+			return 1;
+	}
+	if (PyModule_Check(mod)) {
+		/* We can't use setattr here since it can give a
+		 * spurious warning if the submodule name shadows a
+		 * builtin name */
+		PyObject *dict = PyModule_GetDict(mod);
+		if (!dict)
+			return 0;
+		if (PyDict_SetItemString(dict, subname, submod) < 0)
+			return 0;
+	}
+	else {
+		if (PyObject_SetAttrString(mod, subname, submod) < 0)
+			return 0;
+	}
+	return 1;
+}
+
+static PyObject *
+import_submodule(PyObject *mod, char *subname, char *fullname)
+{
+	PyObject *modules = PyImport_GetModuleDict();
+	PyObject *m = NULL;
+
+	/* Require:
+	   if mod == None: subname == fullname
+	   else: mod.__name__ + "." + subname == fullname
+	*/
+
+	if ((m = PyDict_GetItemString(modules, fullname)) != NULL) {
+		Py_INCREF(m);
+	}
+	else {
+		PyObject *path, *loader = NULL;
+		char buf[MAXPATHLEN+1];
+		struct filedescr *fdp;
+		FILE *fp = NULL;
+
+		if (mod == Py_None)
+			path = NULL;
+		else {
+			path = PyObject_GetAttrString(mod, "__path__");
+			if (path == NULL) {
+				PyErr_Clear();
+				Py_INCREF(Py_None);
+				return Py_None;
+			}
+		}
+
+		buf[0] = '\0';
+		fdp = find_module(fullname, subname, path, buf, MAXPATHLEN+1,
+				  &fp, &loader);
+		Py_XDECREF(path);
+		if (fdp == NULL) {
+			if (!PyErr_ExceptionMatches(PyExc_ImportError))
+				return NULL;
+			PyErr_Clear();
+			Py_INCREF(Py_None);
+			return Py_None;
+		}
+		m = load_module(fullname, fp, buf, fdp->type, loader);
+		Py_XDECREF(loader);
+		if (fp)
+			fclose(fp);
+		if (!add_submodule(mod, m, fullname, subname, modules)) {
+			Py_XDECREF(m);
+			m = NULL;
+		}
+	}
+
+	return m;
+}
+
+
+/* Re-import a module of any kind and return its module object, WITH
+   INCREMENTED REFERENCE COUNT */
+
+PyObject *
+PyImport_ReloadModule(PyObject *m)
+{
+	PyInterpreterState *interp = PyThreadState_Get()->interp;
+	PyObject *modules_reloading = interp->modules_reloading;
+	PyObject *modules = PyImport_GetModuleDict();
+	PyObject *path = NULL, *loader = NULL, *existing_m = NULL;
+	char *name, *subname;
+	char buf[MAXPATHLEN+1];
+	struct filedescr *fdp;
+	FILE *fp = NULL;
+	PyObject *newm;
+    
+	if (modules_reloading == NULL) {
+		Py_FatalError("PyImport_ReloadModule: "
+							"no modules_reloading dictionary!");
+		return NULL;
+	}
+
+	if (m == NULL || !PyModule_Check(m)) {
+		PyErr_SetString(PyExc_TypeError,
+				"reload() argument must be module");
+		return NULL;
+	}
+	name = PyModule_GetName(m);
+	if (name == NULL)
+		return NULL;
+	if (m != PyDict_GetItemString(modules, name)) {
+		PyErr_Format(PyExc_ImportError,
+			     "reload(): module %.200s not in sys.modules",
+			     name);
+		return NULL;
+	}
+	if ((existing_m = PyDict_GetItemString(modules_reloading, name)) != NULL) {
+		/* Due to a recursive reload, this module is already being reloaded. */
+		Py_INCREF(existing_m);
+		return existing_m;
+	}
+ 	PyDict_SetItemString(modules_reloading, name, m);
+
+	subname = strrchr(name, '.');
+	if (subname == NULL)
+		subname = name;
+	else {
+		PyObject *parentname, *parent;
+		parentname = PyString_FromStringAndSize(name, (subname-name));
+		if (parentname == NULL) {
+			imp_modules_reloading_clear();
+			return NULL;
+		}
+		parent = PyDict_GetItem(modules, parentname);
+		if (parent == NULL) {
+			PyErr_Format(PyExc_ImportError,
+			    "reload(): parent %.200s not in sys.modules",
+			    PyString_AS_STRING(parentname));
+			Py_DECREF(parentname);
+			imp_modules_reloading_clear();
+			return NULL;
+		}
+		Py_DECREF(parentname);
+		subname++;
+		path = PyObject_GetAttrString(parent, "__path__");
+		if (path == NULL)
+			PyErr_Clear();
+	}
+	buf[0] = '\0';
+	fdp = find_module(name, subname, path, buf, MAXPATHLEN+1, &fp, &loader);
+	Py_XDECREF(path);
+
+	if (fdp == NULL) {
+		Py_XDECREF(loader);
+		imp_modules_reloading_clear();
+		return NULL;
+	}
+
+	newm = load_module(name, fp, buf, fdp->type, loader);
+	Py_XDECREF(loader);
+
+	if (fp)
+		fclose(fp);
+	if (newm == NULL) {
+		/* load_module probably removed name from modules because of
+		 * the error.  Put back the original module object.  We're
+		 * going to return NULL in this case regardless of whether
+		 * replacing name succeeds, so the return value is ignored.
+		 */
+		PyDict_SetItemString(modules, name, m);
+	}
+	imp_modules_reloading_clear();
+	return newm;
+}
+
+
+/* Higher-level import emulator which emulates the "import" statement
+   more accurately -- it invokes the __import__() function from the
+   builtins of the current globals.  This means that the import is
+   done using whatever import hooks are installed in the current
+   environment, e.g. by "rexec".
+   A dummy list ["__doc__"] is passed as the 4th argument so that
+   e.g. PyImport_Import(PyString_FromString("win32com.client.gencache"))
+   will return <module "gencache"> instead of <module "win32com">. */
+
+PyObject *
+PyImport_Import(PyObject *module_name)
+{
+	static PyObject *silly_list = NULL;
+	static PyObject *builtins_str = NULL;
+	static PyObject *import_str = NULL;
+	PyObject *globals = NULL;
+	PyObject *import = NULL;
+	PyObject *builtins = NULL;
+	PyObject *r = NULL;
+
+	/* Initialize constant string objects */
+	if (silly_list == NULL) {
+		import_str = PyString_InternFromString("__import__");
+		if (import_str == NULL)
+			return NULL;
+		builtins_str = PyString_InternFromString("__builtins__");
+		if (builtins_str == NULL)
+			return NULL;
+		silly_list = Py_BuildValue("[s]", "__doc__");
+		if (silly_list == NULL)
+			return NULL;
+	}
+
+	/* Get the builtins from current globals */
+	globals = PyEval_GetGlobals();
+	if (globals != NULL) {
+	        Py_INCREF(globals);
+		builtins = PyObject_GetItem(globals, builtins_str);
+		if (builtins == NULL)
+			goto err;
+	}
+	else {
+		/* No globals -- use standard builtins, and fake globals */
+		PyErr_Clear();
+
+		builtins = PyImport_ImportModuleLevel("__builtin__",
+						      NULL, NULL, NULL, 0);
+		if (builtins == NULL)
+			return NULL;
+		globals = Py_BuildValue("{OO}", builtins_str, builtins);
+		if (globals == NULL)
+			goto err;
+	}
+
+	/* Get the __import__ function from the builtins */
+	if (PyDict_Check(builtins)) {
+		import = PyObject_GetItem(builtins, import_str);
+		if (import == NULL)
+			PyErr_SetObject(PyExc_KeyError, import_str);
+	}
+	else
+		import = PyObject_GetAttr(builtins, import_str);
+	if (import == NULL)
+		goto err;
+
+	/* Call the _import__ function with the proper argument list */
+	r = PyObject_CallFunctionObjArgs(import, module_name, globals,
+					 globals, silly_list, NULL);
+
+  err:
+	Py_XDECREF(globals);
+	Py_XDECREF(builtins);
+	Py_XDECREF(import);
+
+	return r;
+}
+
+
+/* Module 'imp' provides Python access to the primitives used for
+   importing modules.
+*/
+
+static PyObject *
+imp_get_magic(PyObject *self, PyObject *noargs)
+{
+	char buf[4];
+
+	buf[0] = (char) ((pyc_magic >>  0) & 0xff);
+	buf[1] = (char) ((pyc_magic >>  8) & 0xff);
+	buf[2] = (char) ((pyc_magic >> 16) & 0xff);
+	buf[3] = (char) ((pyc_magic >> 24) & 0xff);
+
+	return PyString_FromStringAndSize(buf, 4);
+}
+
+static PyObject *
+imp_get_suffixes(PyObject *self, PyObject *noargs)
+{
+	PyObject *list;
+	struct filedescr *fdp;
+
+	list = PyList_New(0);
+	if (list == NULL)
+		return NULL;
+	for (fdp = _PyImport_Filetab; fdp->suffix != NULL; fdp++) {
+		PyObject *item = Py_BuildValue("ssi",
+				       fdp->suffix, fdp->mode, fdp->type);
+		if (item == NULL) {
+			Py_DECREF(list);
+			return NULL;
+		}
+		if (PyList_Append(list, item) < 0) {
+			Py_DECREF(list);
+			Py_DECREF(item);
+			return NULL;
+		}
+		Py_DECREF(item);
+	}
+	return list;
+}
+
+static PyObject *
+call_find_module(char *name, PyObject *path)
+{
+	extern int fclose(FILE *);
+	PyObject *fob, *ret;
+	struct filedescr *fdp;
+	char pathname[MAXPATHLEN+1];
+	FILE *fp = NULL;
+
+	pathname[0] = '\0';
+	if (path == Py_None)
+		path = NULL;
+	fdp = find_module(NULL, name, path, pathname, MAXPATHLEN+1, &fp, NULL);
+	if (fdp == NULL)
+		return NULL;
+	if (fp != NULL) {
+		fob = PyFile_FromFile(fp, pathname, fdp->mode, fclose);
+		if (fob == NULL) {
+			fclose(fp);
+			return NULL;
+		}
+	}
+	else {
+		fob = Py_None;
+		Py_INCREF(fob);
+	}
+	ret = Py_BuildValue("Os(ssi)",
+		      fob, pathname, fdp->suffix, fdp->mode, fdp->type);
+	Py_DECREF(fob);
+	return ret;
+}
+
+static PyObject *
+imp_find_module(PyObject *self, PyObject *args)
+{
+	char *name;
+	PyObject *path = NULL;
+	if (!PyArg_ParseTuple(args, "s|O:find_module", &name, &path))
+		return NULL;
+	return call_find_module(name, path);
+}
+
+static PyObject *
+imp_init_builtin(PyObject *self, PyObject *args)
+{
+	char *name;
+	int ret;
+	PyObject *m;
+	if (!PyArg_ParseTuple(args, "s:init_builtin", &name))
+		return NULL;
+	ret = init_builtin(name);
+	if (ret < 0)
+		return NULL;
+	if (ret == 0) {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+	m = PyImport_AddModule(name);
+	Py_XINCREF(m);
+	return m;
+}
+
+static PyObject *
+imp_init_frozen(PyObject *self, PyObject *args)
+{
+	char *name;
+	int ret;
+	PyObject *m;
+	if (!PyArg_ParseTuple(args, "s:init_frozen", &name))
+		return NULL;
+	ret = PyImport_ImportFrozenModule(name);
+	if (ret < 0)
+		return NULL;
+	if (ret == 0) {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+	m = PyImport_AddModule(name);
+	Py_XINCREF(m);
+	return m;
+}
+
+static PyObject *
+imp_get_frozen_object(PyObject *self, PyObject *args)
+{
+	char *name;
+
+	if (!PyArg_ParseTuple(args, "s:get_frozen_object", &name))
+		return NULL;
+	return get_frozen_object(name);
+}
+
+static PyObject *
+imp_is_builtin(PyObject *self, PyObject *args)
+{
+	char *name;
+	if (!PyArg_ParseTuple(args, "s:is_builtin", &name))
+		return NULL;
+	return PyInt_FromLong(is_builtin(name));
+}
+
+static PyObject *
+imp_is_frozen(PyObject *self, PyObject *args)
+{
+	char *name;
+	struct _frozen *p;
+	if (!PyArg_ParseTuple(args, "s:is_frozen", &name))
+		return NULL;
+	p = find_frozen(name);
+	return PyBool_FromLong((long) (p == NULL ? 0 : p->size));
+}
+
+static FILE *
+get_file(char *pathname, PyObject *fob, char *mode)
+{
+	FILE *fp;
+	if (fob == NULL) {
+		if (mode[0] == 'U')
+			mode = "r" PY_STDIOTEXTMODE;
+		fp = fopen(pathname, mode);
+		if (fp == NULL)
+			PyErr_SetFromErrno(PyExc_IOError);
+	}
+	else {
+		fp = PyFile_AsFile(fob);
+		if (fp == NULL)
+			PyErr_SetString(PyExc_ValueError,
+					"bad/closed file object");
+	}
+	return fp;
+}
+
+static PyObject *
+imp_load_compiled(PyObject *self, PyObject *args)
+{
+	char *name;
+	char *pathname;
+	PyObject *fob = NULL;
+	PyObject *m;
+	FILE *fp;
+	if (!PyArg_ParseTuple(args, "ss|O!:load_compiled", &name, &pathname,
+			      &PyFile_Type, &fob))
+		return NULL;
+	fp = get_file(pathname, fob, "rb");
+	if (fp == NULL)
+		return NULL;
+	m = load_compiled_module(name, pathname, fp);
+	if (fob == NULL)
+		fclose(fp);
+	return m;
+}
+
+#ifdef HAVE_DYNAMIC_LOADING
+
+static PyObject *
+imp_load_dynamic(PyObject *self, PyObject *args)
+{
+	char *name;
+	char *pathname;
+	PyObject *fob = NULL;
+	PyObject *m;
+	FILE *fp = NULL;
+	if (!PyArg_ParseTuple(args, "ss|O!:load_dynamic", &name, &pathname,
+			      &PyFile_Type, &fob))
+		return NULL;
+	if (fob) {
+		fp = get_file(pathname, fob, "r");
+		if (fp == NULL)
+			return NULL;
+	}
+	m = _PyImport_LoadDynamicModule(name, pathname, fp);
+	return m;
+}
+
+#endif /* HAVE_DYNAMIC_LOADING */
+
+static PyObject *
+imp_load_source(PyObject *self, PyObject *args)
+{
+	char *name;
+	char *pathname;
+	PyObject *fob = NULL;
+	PyObject *m;
+	FILE *fp;
+	if (!PyArg_ParseTuple(args, "ss|O!:load_source", &name, &pathname,
+			      &PyFile_Type, &fob))
+		return NULL;
+	fp = get_file(pathname, fob, "r");
+	if (fp == NULL)
+		return NULL;
+	m = load_source_module(name, pathname, fp);
+	if (fob == NULL)
+		fclose(fp);
+	return m;
+}
+
+static PyObject *
+imp_load_module(PyObject *self, PyObject *args)
+{
+	char *name;
+	PyObject *fob;
+	char *pathname;
+	char *suffix; /* Unused */
+	char *mode;
+	int type;
+	FILE *fp;
+
+	if (!PyArg_ParseTuple(args, "sOs(ssi):load_module",
+			      &name, &fob, &pathname,
+			      &suffix, &mode, &type))
+		return NULL;
+	if (*mode) {
+		/* Mode must start with 'r' or 'U' and must not contain '+'.
+		   Implicit in this test is the assumption that the mode
+		   may contain other modifiers like 'b' or 't'. */
+
+		if (!(*mode == 'r' || *mode == 'U') || strchr(mode, '+')) {
+			PyErr_Format(PyExc_ValueError,
+				     "invalid file open mode %.200s", mode);
+			return NULL;
+		}
+	}
+	if (fob == Py_None)
+		fp = NULL;
+	else {
+		if (!PyFile_Check(fob)) {
+			PyErr_SetString(PyExc_ValueError,
+				"load_module arg#2 should be a file or None");
+			return NULL;
+		}
+		fp = get_file(pathname, fob, mode);
+		if (fp == NULL)
+			return NULL;
+	}
+	return load_module(name, fp, pathname, type, NULL);
+}
+
+static PyObject *
+imp_load_package(PyObject *self, PyObject *args)
+{
+	char *name;
+	char *pathname;
+	if (!PyArg_ParseTuple(args, "ss:load_package", &name, &pathname))
+		return NULL;
+	return load_package(name, pathname);
+}
+
+static PyObject *
+imp_new_module(PyObject *self, PyObject *args)
+{
+	char *name;
+	if (!PyArg_ParseTuple(args, "s:new_module", &name))
+		return NULL;
+	return PyModule_New(name);
+}
+
+/* Doc strings */
+
+PyDoc_STRVAR(doc_imp,
+"This module provides the components needed to build your own\n\
+__import__ function.  Undocumented functions are obsolete.");
+
+PyDoc_STRVAR(doc_find_module,
+"find_module(name, [path]) -> (file, filename, (suffix, mode, type))\n\
+Search for a module.  If path is omitted or None, search for a\n\
+built-in, frozen or special module and continue search in sys.path.\n\
+The module name cannot contain '.'; to search for a submodule of a\n\
+package, pass the submodule name and the package's __path__.");
+
+PyDoc_STRVAR(doc_load_module,
+"load_module(name, file, filename, (suffix, mode, type)) -> module\n\
+Load a module, given information returned by find_module().\n\
+The module name must include the full package name, if any.");
+
+PyDoc_STRVAR(doc_get_magic,
+"get_magic() -> string\n\
+Return the magic number for .pyc or .pyo files.");
+
+PyDoc_STRVAR(doc_get_suffixes,
+"get_suffixes() -> [(suffix, mode, type), ...]\n\
+Return a list of (suffix, mode, type) tuples describing the files\n\
+that find_module() looks for.");
+
+PyDoc_STRVAR(doc_new_module,
+"new_module(name) -> module\n\
+Create a new module.  Do not enter it in sys.modules.\n\
+The module name must include the full package name, if any.");
+
+PyDoc_STRVAR(doc_lock_held,
+"lock_held() -> boolean\n\
+Return True if the import lock is currently held, else False.\n\
+On platforms without threads, return False.");
+
+PyDoc_STRVAR(doc_acquire_lock,
+"acquire_lock() -> None\n\
+Acquires the interpreter's import lock for the current thread.\n\
+This lock should be used by import hooks to ensure thread-safety\n\
+when importing modules.\n\
+On platforms without threads, this function does nothing.");
+
+PyDoc_STRVAR(doc_release_lock,
+"release_lock() -> None\n\
+Release the interpreter's import lock.\n\
+On platforms without threads, this function does nothing.");
+
+static PyMethodDef imp_methods[] = {
+	{"find_module",	 imp_find_module,  METH_VARARGS, doc_find_module},
+	{"get_magic",	 imp_get_magic,	   METH_NOARGS,  doc_get_magic},
+	{"get_suffixes", imp_get_suffixes, METH_NOARGS,  doc_get_suffixes},
+	{"load_module",	 imp_load_module,  METH_VARARGS, doc_load_module},
+	{"new_module",	 imp_new_module,   METH_VARARGS, doc_new_module},
+	{"lock_held",	 imp_lock_held,	   METH_NOARGS,  doc_lock_held},
+	{"acquire_lock", imp_acquire_lock, METH_NOARGS,  doc_acquire_lock},
+	{"release_lock", imp_release_lock, METH_NOARGS,  doc_release_lock},
+	/* The rest are obsolete */
+	{"get_frozen_object",	imp_get_frozen_object,	METH_VARARGS},
+	{"init_builtin",	imp_init_builtin,	METH_VARARGS},
+	{"init_frozen",		imp_init_frozen,	METH_VARARGS},
+	{"is_builtin",		imp_is_builtin,		METH_VARARGS},
+	{"is_frozen",		imp_is_frozen,		METH_VARARGS},
+	{"load_compiled",	imp_load_compiled,	METH_VARARGS},
+#ifdef HAVE_DYNAMIC_LOADING
+	{"load_dynamic",	imp_load_dynamic,	METH_VARARGS},
+#endif
+	{"load_package",	imp_load_package,	METH_VARARGS},
+	{"load_source",		imp_load_source,	METH_VARARGS},
+	{NULL,			NULL}		/* sentinel */
+};
+
+static int
+setint(PyObject *d, char *name, int value)
+{
+	PyObject *v;
+	int err;
+
+	v = PyInt_FromLong((long)value);
+	err = PyDict_SetItemString(d, name, v);
+	Py_XDECREF(v);
+	return err;
+}
+
+typedef struct {
+    PyObject_HEAD
+} NullImporter;
+
+static int
+NullImporter_init(NullImporter *self, PyObject *args, PyObject *kwds)
+{
+	char *path;
+
+	if (!_PyArg_NoKeywords("NullImporter()", kwds))
+		return -1;
+
+	if (!PyArg_ParseTuple(args, "s:NullImporter",
+			      &path))
+		return -1;
+
+	if (strlen(path) == 0) {
+		PyErr_SetString(PyExc_ImportError, "empty pathname");
+		return -1;
+	} else {
+#ifndef RISCOS
+		struct stat statbuf;
+		int rv;
+
+		rv = stat(path, &statbuf);
+		if (rv == 0) {
+			/* it exists */
+			if (S_ISDIR(statbuf.st_mode)) {
+				/* it's a directory */
+				PyErr_SetString(PyExc_ImportError,
+						"existing directory");
+				return -1;
+			}
+		}
+#else
+		if (object_exists(path)) {
+			/* it exists */
+			if (isdir(path)) {
+				/* it's a directory */
+				PyErr_SetString(PyExc_ImportError,
+						"existing directory");
+				return -1;
+			}
+		}
+#endif
+	}
+	return 0;
+}
+
+static PyObject *
+NullImporter_find_module(NullImporter *self, PyObject *args)
+{
+	Py_RETURN_NONE;
+}
+
+static PyMethodDef NullImporter_methods[] = {
+	{"find_module", (PyCFunction)NullImporter_find_module, METH_VARARGS,
+	 "Always return None"
+	},
+	{NULL}  /* Sentinel */
+};
+
+
+static PyTypeObject NullImporterType = {
+	PyObject_HEAD_INIT(NULL)
+	0,                         /*ob_size*/
+	"imp.NullImporter",        /*tp_name*/
+	sizeof(NullImporter),      /*tp_basicsize*/
+	0,                         /*tp_itemsize*/
+	0,                         /*tp_dealloc*/
+	0,                         /*tp_print*/
+	0,                         /*tp_getattr*/
+	0,                         /*tp_setattr*/
+	0,                         /*tp_compare*/
+	0,                         /*tp_repr*/
+	0,                         /*tp_as_number*/
+	0,                         /*tp_as_sequence*/
+	0,                         /*tp_as_mapping*/
+	0,                         /*tp_hash */
+	0,                         /*tp_call*/
+	0,                         /*tp_str*/
+	0,                         /*tp_getattro*/
+	0,                         /*tp_setattro*/
+	0,                         /*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT,        /*tp_flags*/
+	"Null importer object",    /* tp_doc */
+	0,	                   /* tp_traverse */
+	0,	                   /* tp_clear */
+	0,	                   /* tp_richcompare */
+	0,	                   /* tp_weaklistoffset */
+	0,	                   /* tp_iter */
+	0,	                   /* tp_iternext */
+	NullImporter_methods,      /* tp_methods */
+	0,                         /* tp_members */
+	0,                         /* tp_getset */
+	0,                         /* tp_base */
+	0,                         /* tp_dict */
+	0,                         /* tp_descr_get */
+	0,                         /* tp_descr_set */
+	0,                         /* tp_dictoffset */
+	(initproc)NullImporter_init,      /* tp_init */
+	0,                         /* tp_alloc */
+	PyType_GenericNew          /* tp_new */
+};
+
+
+PyMODINIT_FUNC
+initimp(void)
+{
+	PyObject *m, *d;
+
+	if (PyType_Ready(&NullImporterType) < 0)
+		goto failure;
+
+	m = Py_InitModule4("imp", imp_methods, doc_imp,
+			   NULL, PYTHON_API_VERSION);
+	if (m == NULL)
+		goto failure;
+	d = PyModule_GetDict(m);
+	if (d == NULL)
+		goto failure;
+
+	if (setint(d, "SEARCH_ERROR", SEARCH_ERROR) < 0) goto failure;
+	if (setint(d, "PY_SOURCE", PY_SOURCE) < 0) goto failure;
+	if (setint(d, "PY_COMPILED", PY_COMPILED) < 0) goto failure;
+	if (setint(d, "C_EXTENSION", C_EXTENSION) < 0) goto failure;
+	if (setint(d, "PY_RESOURCE", PY_RESOURCE) < 0) goto failure;
+	if (setint(d, "PKG_DIRECTORY", PKG_DIRECTORY) < 0) goto failure;
+	if (setint(d, "C_BUILTIN", C_BUILTIN) < 0) goto failure;
+	if (setint(d, "PY_FROZEN", PY_FROZEN) < 0) goto failure;
+	if (setint(d, "PY_CODERESOURCE", PY_CODERESOURCE) < 0) goto failure;
+	if (setint(d, "IMP_HOOK", IMP_HOOK) < 0) goto failure;
+
+	Py_INCREF(&NullImporterType);
+	PyModule_AddObject(m, "NullImporter", (PyObject *)&NullImporterType);
+  failure:
+	;
+}
+
+
+/* API for embedding applications that want to add their own entries
+   to the table of built-in modules.  This should normally be called
+   *before* Py_Initialize().  When the table resize fails, -1 is
+   returned and the existing table is unchanged.
+
+   After a similar function by Just van Rossum. */
+
+int
+PyImport_ExtendInittab(struct _inittab *newtab)
+{
+	static struct _inittab *our_copy = NULL;
+	struct _inittab *p;
+	int i, n;
+
+	/* Count the number of entries in both tables */
+	for (n = 0; newtab[n].name != NULL; n++)
+		;
+	if (n == 0)
+		return 0; /* Nothing to do */
+	for (i = 0; PyImport_Inittab[i].name != NULL; i++)
+		;
+
+	/* Allocate new memory for the combined table */
+	p = our_copy;
+	PyMem_RESIZE(p, struct _inittab, i+n+1);
+	if (p == NULL)
+		return -1;
+
+	/* Copy the tables into the new memory */
+	if (our_copy != PyImport_Inittab)
+		memcpy(p, PyImport_Inittab, (i+1) * sizeof(struct _inittab));
+	PyImport_Inittab = our_copy = p;
+	memcpy(p+i, newtab, (n+1) * sizeof(struct _inittab));
+
+	return 0;
+}
+
+/* Shorthand to add a single entry given a name and a function */
+
+int
+PyImport_AppendInittab(char *name, void (*initfunc)(void))
+{
+	struct _inittab newtab[2];
+
+	memset(newtab, '\0', sizeof newtab);
+
+	newtab[0].name = name;
+	newtab[0].initfunc = initfunc;
+
+	return PyImport_ExtendInittab(newtab);
+}
+
+#ifdef __cplusplus
+}
+#endif

Added: vendor/Python/current/Python/importdl.c
===================================================================
--- vendor/Python/current/Python/importdl.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/importdl.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,78 @@
+
+/* Support for dynamic loading of extension modules */
+
+#include "Python.h"
+
+/* ./configure sets HAVE_DYNAMIC_LOADING if dynamic loading of modules is
+   supported on this platform. configure will then compile and link in one
+   of the dynload_*.c files, as appropriate. We will call a function in
+   those modules to get a function pointer to the module's init function.
+*/
+#ifdef HAVE_DYNAMIC_LOADING
+
+#include "importdl.h"
+
+extern dl_funcptr _PyImport_GetDynLoadFunc(const char *name,
+					   const char *shortname,
+					   const char *pathname, FILE *fp);
+
+
+
+PyObject *
+_PyImport_LoadDynamicModule(char *name, char *pathname, FILE *fp)
+{
+	PyObject *m;
+	char *lastdot, *shortname, *packagecontext, *oldcontext;
+	dl_funcptr p;
+
+	if ((m = _PyImport_FindExtension(name, pathname)) != NULL) {
+		Py_INCREF(m);
+		return m;
+	}
+	lastdot = strrchr(name, '.');
+	if (lastdot == NULL) {
+		packagecontext = NULL;
+		shortname = name;
+	}
+	else {
+		packagecontext = name;
+		shortname = lastdot+1;
+	}
+
+	p = _PyImport_GetDynLoadFunc(name, shortname, pathname, fp);
+	if (PyErr_Occurred())
+		return NULL;
+	if (p == NULL) {
+		PyErr_Format(PyExc_ImportError,
+		   "dynamic module does not define init function (init%.200s)",
+			     shortname);
+		return NULL;
+	}
+        oldcontext = _Py_PackageContext;
+	_Py_PackageContext = packagecontext;
+	(*p)();
+	_Py_PackageContext = oldcontext;
+	if (PyErr_Occurred())
+		return NULL;
+
+	m = PyDict_GetItemString(PyImport_GetModuleDict(), name);
+	if (m == NULL) {
+		PyErr_SetString(PyExc_SystemError,
+				"dynamic module not initialized properly");
+		return NULL;
+	}
+	/* Remember the filename as the __file__ attribute */
+	if (PyModule_AddStringConstant(m, "__file__", pathname) < 0)
+		PyErr_Clear(); /* Not important enough to report */
+
+	if (_PyImport_FixupExtension(name, pathname) == NULL)
+		return NULL;
+	if (Py_VerboseFlag)
+		PySys_WriteStderr(
+			"import %s # dynamically loaded from %s\n",
+			name, pathname);
+	Py_INCREF(m);
+	return m;
+}
+
+#endif /* HAVE_DYNAMIC_LOADING */

Added: vendor/Python/current/Python/importdl.h
===================================================================
--- vendor/Python/current/Python/importdl.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/importdl.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,53 @@
+#ifndef Py_IMPORTDL_H
+#define Py_IMPORTDL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Definitions for dynamic loading of extension modules */
+enum filetype {
+	SEARCH_ERROR,
+	PY_SOURCE,
+	PY_COMPILED,
+	C_EXTENSION,
+	PY_RESOURCE, /* Mac only */
+	PKG_DIRECTORY,
+	C_BUILTIN,
+	PY_FROZEN,
+	PY_CODERESOURCE, /* Mac only */
+	IMP_HOOK
+};
+
+struct filedescr {
+	char *suffix;
+	char *mode;
+	enum filetype type;
+};
+extern struct filedescr * _PyImport_Filetab;
+extern const struct filedescr _PyImport_DynLoadFiletab[];
+
+extern PyObject *_PyImport_LoadDynamicModule(char *name, char *pathname,
+					     FILE *);
+
+/* Max length of module suffix searched for -- accommodates "module.slb" */
+#define MAXSUFFIXSIZE 12
+
+#ifdef MS_WINDOWS
+#include <windows.h>
+typedef FARPROC dl_funcptr;
+#else
+#if defined(PYOS_OS2) && !defined(PYCC_GCC)
+#include <os2def.h>
+typedef int (* APIENTRY dl_funcptr)();
+#else
+typedef void (*dl_funcptr)(void);
+#endif
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_IMPORTDL_H */

Added: vendor/Python/current/Python/mactoolboxglue.c
===================================================================
--- vendor/Python/current/Python/mactoolboxglue.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/mactoolboxglue.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,470 @@
+/***********************************************************
+Copyright 1991-1997 by Stichting Mathematisch Centrum, Amsterdam,
+The Netherlands.
+
+                        All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its 
+documentation for any purpose and without fee is hereby granted, 
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in 
+supporting documentation, and that the names of Stichting Mathematisch
+Centrum or CWI not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior permission.
+
+STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
+THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
+FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+******************************************************************/
+
+
+#include "Python.h"
+#include "pymactoolbox.h"
+#include <arpa/inet.h>	/* for ntohl, htonl */
+
+
+/* Like strerror() but for Mac OS error numbers */
+char *
+PyMac_StrError(int err)
+{
+	static char buf[256];
+	PyObject *m;
+	PyObject *rv;
+
+	m = PyImport_ImportModule("MacOS");
+	if (!m) {
+		if (Py_VerboseFlag)
+			PyErr_Print();
+		PyErr_Clear();
+		rv = NULL;
+	}
+	else {
+		rv = PyObject_CallMethod(m, "GetErrorString", "i", err);
+		if (!rv)
+			PyErr_Clear();
+	}
+	if (!rv) {
+		buf[0] = '\0';
+	}
+	else {
+		char *input = PyString_AsString(rv);
+		if (!input) {
+			PyErr_Clear();
+			buf[0] = '\0';
+		} else {
+			strncpy(buf, input, sizeof(buf) - 1);
+			buf[sizeof(buf) - 1] = '\0';
+		}
+		Py_DECREF(rv);
+	}
+	Py_XDECREF(m);
+	return buf;
+}
+
+/* Exception object shared by all Mac specific modules for Mac OS errors */
+PyObject *PyMac_OSErrException;
+
+/* Initialize and return PyMac_OSErrException */
+PyObject *
+PyMac_GetOSErrException(void)
+{
+	if (PyMac_OSErrException == NULL)
+		PyMac_OSErrException = PyErr_NewException("MacOS.Error", NULL, NULL);
+	return PyMac_OSErrException;
+}
+
+/* Set a MAC-specific error from errno, and return NULL; return None if no error */
+PyObject * 
+PyErr_Mac(PyObject *eobj, int err)
+{
+	char *msg;
+	PyObject *v;
+	
+	if (err == 0 && !PyErr_Occurred()) {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+	if (err == -1 && PyErr_Occurred())
+		return NULL;
+	msg = PyMac_StrError(err);
+	v = Py_BuildValue("(is)", err, msg);
+	PyErr_SetObject(eobj, v);
+	Py_DECREF(v);
+	return NULL;
+}
+
+/* Call PyErr_Mac with PyMac_OSErrException */
+PyObject *
+PyMac_Error(OSErr err)
+{
+	return PyErr_Mac(PyMac_GetOSErrException(), err);
+}
+
+
+OSErr
+PyMac_GetFullPathname(FSSpec *fss, char *path, int len)
+{
+	PyObject *fs, *exc;
+	PyObject *rv = NULL;
+	char *input;
+	OSErr err = noErr;
+
+	*path = '\0';
+
+	fs = PyMac_BuildFSSpec(fss);
+	if (!fs)
+		goto error;
+
+	rv = PyObject_CallMethod(fs, "as_pathname", "");
+	if (!rv)
+		goto error;
+
+	input = PyString_AsString(rv);
+	if (!input)
+		goto error;
+
+	strncpy(path, input, len - 1);
+	path[len - 1] = '\0';
+
+	Py_XDECREF(rv);
+	Py_XDECREF(fs);
+	return err;
+
+  error:
+	exc = PyErr_Occurred();
+	if (exc  && PyErr_GivenExceptionMatches(exc,
+						PyMac_GetOSErrException())) {
+		PyObject *args = PyObject_GetAttrString(exc, "args");
+		if (args) {
+			char *ignore;
+			PyArg_ParseTuple(args, "is", &err, &ignore);
+			Py_XDECREF(args);
+		}
+	}
+	if (err == noErr)
+		err = -1;
+	PyErr_Clear();
+	Py_XDECREF(rv);
+	Py_XDECREF(fs);
+	return err;
+}
+
+/* Convert a 4-char string object argument to an OSType value */
+int
+PyMac_GetOSType(PyObject *v, OSType *pr)
+{
+	uint32_t tmp;
+	if (!PyString_Check(v) || PyString_Size(v) != 4) {
+		PyErr_SetString(PyExc_TypeError,
+			"OSType arg must be string of 4 chars");
+		return 0;
+	}
+	memcpy((char *)&tmp, PyString_AsString(v), 4);
+	*pr = (OSType)ntohl(tmp);
+	return 1;
+}
+
+/* Convert an OSType value to a 4-char string object */
+PyObject *
+PyMac_BuildOSType(OSType t)
+{
+	uint32_t tmp = htonl((uint32_t)t);
+	return PyString_FromStringAndSize((char *)&tmp, 4);
+}
+
+/* Convert an NumVersion value to a 4-element tuple */
+PyObject *
+PyMac_BuildNumVersion(NumVersion t)
+{
+	return Py_BuildValue("(hhhh)", t.majorRev, t.minorAndBugRev, t.stage, t.nonRelRev);
+}
+
+
+/* Convert a Python string object to a Str255 */
+int
+PyMac_GetStr255(PyObject *v, Str255 pbuf)
+{
+	int len;
+	if (!PyString_Check(v) || (len = PyString_Size(v)) > 255) {
+		PyErr_SetString(PyExc_TypeError,
+			"Str255 arg must be string of at most 255 chars");
+		return 0;
+	}
+	pbuf[0] = len;
+	memcpy((char *)(pbuf+1), PyString_AsString(v), len);
+	return 1;
+}
+
+/* Convert a Str255 to a Python string object */
+PyObject *
+PyMac_BuildStr255(Str255 s)
+{
+	if ( s == NULL ) {
+		PyErr_SetString(PyExc_SystemError, "Str255 pointer is NULL");
+		return NULL;
+	}
+	return PyString_FromStringAndSize((char *)&s[1], (int)s[0]);
+}
+
+PyObject *
+PyMac_BuildOptStr255(Str255 s)
+{
+	if ( s == NULL ) {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+	return PyString_FromStringAndSize((char *)&s[1], (int)s[0]);
+}
+
+
+
+/* Convert a Python object to a Rect.
+   The object must be a (left, top, right, bottom) tuple.
+   (This differs from the order in the struct but is consistent with
+   the arguments to SetRect(), and also with STDWIN). */
+int
+PyMac_GetRect(PyObject *v, Rect *r)
+{
+	return PyArg_Parse(v, "(hhhh)", &r->left, &r->top, &r->right, &r->bottom);
+}
+
+/* Convert a Rect to a Python object */
+PyObject *
+PyMac_BuildRect(Rect *r)
+{
+	return Py_BuildValue("(hhhh)", r->left, r->top, r->right, r->bottom);
+}
+
+
+/* Convert a Python object to a Point.
+   The object must be a (h, v) tuple.
+   (This differs from the order in the struct but is consistent with
+   the arguments to SetPoint(), and also with STDWIN). */
+int
+PyMac_GetPoint(PyObject *v, Point *p)
+{
+	return PyArg_Parse(v, "(hh)", &p->h, &p->v);
+}
+
+/* Convert a Point to a Python object */
+PyObject *
+PyMac_BuildPoint(Point p)
+{
+	return Py_BuildValue("(hh)", p.h, p.v);
+}
+
+
+/* Convert a Python object to an EventRecord.
+   The object must be a (what, message, when, (v, h), modifiers) tuple. */
+int
+PyMac_GetEventRecord(PyObject *v, EventRecord *e)
+{
+	return PyArg_Parse(v, "(Hkk(hh)H)",
+	                   &e->what,
+	                   &e->message,
+	                   &e->when,
+	                   &e->where.h,
+	                   &e->where.v,                   
+	                   &e->modifiers);
+}
+
+/* Convert a Rect to an EventRecord object */
+PyObject *
+PyMac_BuildEventRecord(EventRecord *e)
+{
+	return Py_BuildValue("(hll(hh)h)",
+	                     e->what,
+	                     e->message,
+	                     e->when,
+	                     e->where.h,
+	                     e->where.v,
+	                     e->modifiers);
+}
+
+/* Convert Python object to Fixed */
+int
+PyMac_GetFixed(PyObject *v, Fixed *f)
+{
+	double d;
+	
+	if( !PyArg_Parse(v, "d", &d))
+		return 0;
+	*f = (Fixed)(d * 0x10000);
+	return 1;
+}
+
+/* Convert a Fixed to a Python object */
+PyObject *
+PyMac_BuildFixed(Fixed f)
+{
+	double d;
+	
+	d = f;
+	d = d / 0x10000;
+	return Py_BuildValue("d", d);
+}
+
+/* Convert wide to/from Python int or (hi, lo) tuple. XXXX Should use Python longs */
+int
+PyMac_Getwide(PyObject *v, wide *rv)
+{
+	if (PyInt_Check(v)) {
+		rv->hi = 0;
+		rv->lo = PyInt_AsLong(v);
+		if( rv->lo & 0x80000000 )
+			rv->hi = -1;
+		return 1;
+	}
+	return PyArg_Parse(v, "(kk)", &rv->hi, &rv->lo);
+}
+
+
+PyObject *
+PyMac_Buildwide(wide *w)
+{
+	if ( (w->hi == 0 && (w->lo & 0x80000000) == 0) ||
+	     (w->hi == -1 && (w->lo & 0x80000000) ) )
+		return PyInt_FromLong(w->lo);
+	return Py_BuildValue("(ll)", w->hi, w->lo);
+}
+
+#ifdef USE_TOOLBOX_OBJECT_GLUE
+/*
+** Glue together the toolbox objects.
+**
+** Because toolbox modules interdepend on each other, they use each others
+** object types, on MacOSX/MachO this leads to the situation that they
+** cannot be dynamically loaded (or they would all have to be lumped into
+** a single .so, but this would be bad for extensibility).
+**
+** This file defines wrappers for all the _New and _Convert functions,
+** which are the Py_BuildValue and PyArg_ParseTuple helpers. The wrappers
+** check an indirection function pointer, and if it isn't filled in yet
+** they import the appropriate module, whose init routine should fill in
+** the pointer.
+*/
+
+#define GLUE_NEW(object, routinename, module) \
+PyObject *(*PyMacGluePtr_##routinename)(object); \
+\
+PyObject *routinename(object cobj) { \
+    if (!PyMacGluePtr_##routinename) { \
+       if (!PyImport_ImportModule(module)) return NULL; \
+       if (!PyMacGluePtr_##routinename) { \
+           PyErr_SetString(PyExc_ImportError, "Module did not provide routine: " module ": " #routinename); \
+           return NULL; \
+       } \
+    } \
+    return (*PyMacGluePtr_##routinename)(cobj); \
+}
+
+#define GLUE_CONVERT(object, routinename, module) \
+int (*PyMacGluePtr_##routinename)(PyObject *, object *); \
+\
+int routinename(PyObject *pyobj, object *cobj) { \
+    if (!PyMacGluePtr_##routinename) { \
+       if (!PyImport_ImportModule(module)) return 0; \
+       if (!PyMacGluePtr_##routinename) { \
+           PyErr_SetString(PyExc_ImportError, "Module did not provide routine: " module ": " #routinename); \
+           return 0; \
+       } \
+    } \
+    return (*PyMacGluePtr_##routinename)(pyobj, cobj); \
+}
+
+GLUE_NEW(FSSpec *, PyMac_BuildFSSpec, "Carbon.File")
+GLUE_CONVERT(FSSpec, PyMac_GetFSSpec, "Carbon.File")
+GLUE_NEW(FSRef *, PyMac_BuildFSRef, "Carbon.File")
+GLUE_CONVERT(FSRef, PyMac_GetFSRef, "Carbon.File")
+
+GLUE_NEW(AppleEvent *, AEDesc_New, "Carbon.AE") /* XXXX Why by address? */
+GLUE_NEW(AppleEvent *, AEDesc_NewBorrowed, "Carbon.AE")
+GLUE_CONVERT(AppleEvent, AEDesc_Convert, "Carbon.AE")
+
+GLUE_NEW(Component, CmpObj_New, "Carbon.Cm")
+GLUE_CONVERT(Component, CmpObj_Convert, "Carbon.Cm")
+GLUE_NEW(ComponentInstance, CmpInstObj_New, "Carbon.Cm")
+GLUE_CONVERT(ComponentInstance, CmpInstObj_Convert, "Carbon.Cm")
+
+GLUE_NEW(ControlHandle, CtlObj_New, "Carbon.Ctl")
+GLUE_CONVERT(ControlHandle, CtlObj_Convert, "Carbon.Ctl")
+
+GLUE_NEW(DialogPtr, DlgObj_New, "Carbon.Dlg")
+GLUE_CONVERT(DialogPtr, DlgObj_Convert, "Carbon.Dlg")
+GLUE_NEW(DialogPtr, DlgObj_WhichDialog, "Carbon.Dlg")
+
+GLUE_NEW(DragReference, DragObj_New, "Carbon.Drag")
+GLUE_CONVERT(DragReference, DragObj_Convert, "Carbon.Drag")
+
+GLUE_NEW(ListHandle, ListObj_New, "Carbon.List")
+GLUE_CONVERT(ListHandle, ListObj_Convert, "Carbon.List")
+
+GLUE_NEW(MenuHandle, MenuObj_New, "Carbon.Menu")
+GLUE_CONVERT(MenuHandle, MenuObj_Convert, "Carbon.Menu")
+
+GLUE_NEW(GrafPtr, GrafObj_New, "Carbon.Qd")
+GLUE_CONVERT(GrafPtr, GrafObj_Convert, "Carbon.Qd")
+GLUE_NEW(BitMapPtr, BMObj_New, "Carbon.Qd")
+GLUE_CONVERT(BitMapPtr, BMObj_Convert, "Carbon.Qd")
+GLUE_NEW(RGBColor *, QdRGB_New, "Carbon.Qd") /* XXXX Why? */
+GLUE_CONVERT(RGBColor, QdRGB_Convert, "Carbon.Qd")
+
+GLUE_NEW(GWorldPtr, GWorldObj_New, "Carbon.Qdoffs")
+GLUE_CONVERT(GWorldPtr, GWorldObj_Convert, "Carbon.Qdoffs")
+
+GLUE_NEW(Track, TrackObj_New, "Carbon.Qt")
+GLUE_CONVERT(Track, TrackObj_Convert, "Carbon.Qt")
+GLUE_NEW(Movie, MovieObj_New, "Carbon.Qt")
+GLUE_CONVERT(Movie, MovieObj_Convert, "Carbon.Qt")
+GLUE_NEW(MovieController, MovieCtlObj_New, "Carbon.Qt")
+GLUE_CONVERT(MovieController, MovieCtlObj_Convert, "Carbon.Qt")
+GLUE_NEW(TimeBase, TimeBaseObj_New, "Carbon.Qt")
+GLUE_CONVERT(TimeBase, TimeBaseObj_Convert, "Carbon.Qt")
+GLUE_NEW(UserData, UserDataObj_New, "Carbon.Qt")
+GLUE_CONVERT(UserData, UserDataObj_Convert, "Carbon.Qt")
+GLUE_NEW(Media, MediaObj_New, "Carbon.Qt")
+GLUE_CONVERT(Media, MediaObj_Convert, "Carbon.Qt")
+
+GLUE_NEW(Handle, ResObj_New, "Carbon.Res")
+GLUE_CONVERT(Handle, ResObj_Convert, "Carbon.Res")
+GLUE_NEW(Handle, OptResObj_New, "Carbon.Res")
+GLUE_CONVERT(Handle, OptResObj_Convert, "Carbon.Res")
+
+GLUE_NEW(TEHandle, TEObj_New, "Carbon.TE")
+GLUE_CONVERT(TEHandle, TEObj_Convert, "Carbon.TE")
+
+GLUE_NEW(WindowPtr, WinObj_New, "Carbon.Win")
+GLUE_CONVERT(WindowPtr, WinObj_Convert, "Carbon.Win")
+GLUE_NEW(WindowPtr, WinObj_WhichWindow, "Carbon.Win")
+
+GLUE_CONVERT(CFTypeRef, CFObj_Convert, "Carbon.CF")
+GLUE_NEW(CFTypeRef, CFObj_New, "Carbon.CF")
+
+GLUE_CONVERT(CFTypeRef, CFTypeRefObj_Convert, "Carbon.CF")
+GLUE_NEW(CFTypeRef, CFTypeRefObj_New, "Carbon.CF")
+
+GLUE_CONVERT(CFStringRef, CFStringRefObj_Convert, "Carbon.CF")
+GLUE_NEW(CFStringRef, CFStringRefObj_New, "Carbon.CF")
+GLUE_CONVERT(CFMutableStringRef, CFMutableStringRefObj_Convert, "Carbon.CF")
+GLUE_NEW(CFMutableStringRef, CFMutableStringRefObj_New, "Carbon.CF")
+
+GLUE_CONVERT(CFArrayRef, CFArrayRefObj_Convert, "Carbon.CF")
+GLUE_NEW(CFArrayRef, CFArrayRefObj_New, "Carbon.CF")
+GLUE_CONVERT(CFMutableArrayRef, CFMutableArrayRefObj_Convert, "Carbon.CF")
+GLUE_NEW(CFMutableArrayRef, CFMutableArrayRefObj_New, "Carbon.CF")
+
+GLUE_CONVERT(CFDictionaryRef, CFDictionaryRefObj_Convert, "Carbon.CF")
+GLUE_NEW(CFDictionaryRef, CFDictionaryRefObj_New, "Carbon.CF")
+GLUE_CONVERT(CFMutableDictionaryRef, CFMutableDictionaryRefObj_Convert, "Carbon.CF")
+GLUE_NEW(CFMutableDictionaryRef, CFMutableDictionaryRefObj_New, "Carbon.CF")
+
+GLUE_CONVERT(CFURLRef, CFURLRefObj_Convert, "Carbon.CF")
+GLUE_CONVERT(CFURLRef, OptionalCFURLRefObj_Convert, "Carbon.CF")
+GLUE_NEW(CFURLRef, CFURLRefObj_New, "Carbon.CF")
+
+#endif /* USE_TOOLBOX_OBJECT_GLUE */

Added: vendor/Python/current/Python/marshal.c
===================================================================
--- vendor/Python/current/Python/marshal.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/marshal.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1155 @@
+
+/* Write Python objects to files and read them back.
+   This is intended for writing and reading compiled Python code only;
+   a true persistent storage facility would be much harder, since
+   it would have to take circular links and sharing into account. */
+
+#define PY_SSIZE_T_CLEAN
+
+#include "Python.h"
+#include "longintrepr.h"
+#include "code.h"
+#include "marshal.h"
+
+/* High water mark to determine when the marshalled object is dangerously deep
+ * and risks coring the interpreter.  When the object stack gets this deep,
+ * raise an exception instead of continuing.
+ */
+#define MAX_MARSHAL_STACK_DEPTH 5000
+
+#define TYPE_NULL		'0'
+#define TYPE_NONE		'N'
+#define TYPE_FALSE		'F'
+#define TYPE_TRUE		'T'
+#define TYPE_STOPITER		'S'
+#define TYPE_ELLIPSIS   	'.'
+#define TYPE_INT		'i'
+#define TYPE_INT64		'I'
+#define TYPE_FLOAT		'f'
+#define TYPE_BINARY_FLOAT	'g'
+#define TYPE_COMPLEX		'x'
+#define TYPE_BINARY_COMPLEX	'y'
+#define TYPE_LONG		'l'
+#define TYPE_STRING		's'
+#define TYPE_INTERNED		't'
+#define TYPE_STRINGREF		'R'
+#define TYPE_TUPLE		'('
+#define TYPE_LIST		'['
+#define TYPE_DICT		'{'
+#define TYPE_CODE		'c'
+#define TYPE_UNICODE		'u'
+#define TYPE_UNKNOWN		'?'
+#define TYPE_SET		'<'
+#define TYPE_FROZENSET  	'>'
+
+typedef struct {
+	FILE *fp;
+	int error;
+	int depth;
+	/* If fp == NULL, the following are valid: */
+	PyObject *str;
+	char *ptr;
+	char *end;
+	PyObject *strings; /* dict on marshal, list on unmarshal */
+	int version;
+} WFILE;
+
+#define w_byte(c, p) if (((p)->fp)) putc((c), (p)->fp); \
+		      else if ((p)->ptr != (p)->end) *(p)->ptr++ = (c); \
+			   else w_more(c, p)
+
+static void
+w_more(int c, WFILE *p)
+{
+	Py_ssize_t size, newsize;
+	if (p->str == NULL)
+		return; /* An error already occurred */
+	size = PyString_Size(p->str);
+	newsize = size + 1024;
+	if (_PyString_Resize(&p->str, newsize) != 0) {
+		p->ptr = p->end = NULL;
+	}
+	else {
+		p->ptr = PyString_AS_STRING((PyStringObject *)p->str) + size;
+		p->end =
+			PyString_AS_STRING((PyStringObject *)p->str) + newsize;
+		*p->ptr++ = Py_SAFE_DOWNCAST(c, int, char);
+	}
+}
+
+static void
+w_string(char *s, int n, WFILE *p)
+{
+	if (p->fp != NULL) {
+		fwrite(s, 1, n, p->fp);
+	}
+	else {
+		while (--n >= 0) {
+			w_byte(*s, p);
+			s++;
+		}
+	}
+}
+
+static void
+w_short(int x, WFILE *p)
+{
+	w_byte((char)( x      & 0xff), p);
+	w_byte((char)((x>> 8) & 0xff), p);
+}
+
+static void
+w_long(long x, WFILE *p)
+{
+	w_byte((char)( x      & 0xff), p);
+	w_byte((char)((x>> 8) & 0xff), p);
+	w_byte((char)((x>>16) & 0xff), p);
+	w_byte((char)((x>>24) & 0xff), p);
+}
+
+#if SIZEOF_LONG > 4
+static void
+w_long64(long x, WFILE *p)
+{
+	w_long(x, p);
+	w_long(x>>32, p);
+}
+#endif
+
+static void
+w_object(PyObject *v, WFILE *p)
+{
+	Py_ssize_t i, n;
+
+	p->depth++;
+
+	if (p->depth > MAX_MARSHAL_STACK_DEPTH) {
+		p->error = 2;
+	}
+	else if (v == NULL) {
+		w_byte(TYPE_NULL, p);
+	}
+	else if (v == Py_None) {
+		w_byte(TYPE_NONE, p);
+	}
+	else if (v == PyExc_StopIteration) {
+		w_byte(TYPE_STOPITER, p);
+	}
+	else if (v == Py_Ellipsis) {
+	        w_byte(TYPE_ELLIPSIS, p);
+	}
+	else if (v == Py_False) {
+	        w_byte(TYPE_FALSE, p);
+	}
+	else if (v == Py_True) {
+	        w_byte(TYPE_TRUE, p);
+	}
+	else if (PyInt_Check(v)) {
+		long x = PyInt_AS_LONG((PyIntObject *)v);
+#if SIZEOF_LONG > 4
+		long y = Py_ARITHMETIC_RIGHT_SHIFT(long, x, 31);
+		if (y && y != -1) {
+			w_byte(TYPE_INT64, p);
+			w_long64(x, p);
+		}
+		else
+#endif
+			{
+			w_byte(TYPE_INT, p);
+			w_long(x, p);
+		}
+	}
+	else if (PyLong_Check(v)) {
+		PyLongObject *ob = (PyLongObject *)v;
+		w_byte(TYPE_LONG, p);
+		n = ob->ob_size;
+		w_long((long)n, p);
+		if (n < 0)
+			n = -n;
+		for (i = 0; i < n; i++)
+			w_short(ob->ob_digit[i], p);
+	}
+	else if (PyFloat_Check(v)) {
+		if (p->version > 1) {
+			unsigned char buf[8];
+			if (_PyFloat_Pack8(PyFloat_AsDouble(v), 
+					   buf, 1) < 0) {
+				p->error = 1;
+				return;
+			}
+			w_byte(TYPE_BINARY_FLOAT, p);
+			w_string((char*)buf, 8, p);
+		}
+		else {
+			char buf[256]; /* Plenty to format any double */
+			PyFloat_AsReprString(buf, (PyFloatObject *)v);
+			n = strlen(buf);
+			w_byte(TYPE_FLOAT, p);
+			w_byte((int)n, p);
+			w_string(buf, (int)n, p);
+		}
+	}
+#ifndef WITHOUT_COMPLEX
+	else if (PyComplex_Check(v)) {
+		if (p->version > 1) {
+			unsigned char buf[8];
+			if (_PyFloat_Pack8(PyComplex_RealAsDouble(v),
+					   buf, 1) < 0) {
+				p->error = 1;
+				return;
+			}
+			w_byte(TYPE_BINARY_COMPLEX, p);
+			w_string((char*)buf, 8, p);
+			if (_PyFloat_Pack8(PyComplex_ImagAsDouble(v), 
+					   buf, 1) < 0) {
+				p->error = 1;
+				return;
+			}
+			w_string((char*)buf, 8, p);
+		}
+		else {
+			char buf[256]; /* Plenty to format any double */
+			PyFloatObject *temp;
+			w_byte(TYPE_COMPLEX, p);
+			temp = (PyFloatObject*)PyFloat_FromDouble(
+				PyComplex_RealAsDouble(v));
+			if (!temp) {
+				p->error = 1;
+				return;
+			}
+			PyFloat_AsReprString(buf, temp);
+			Py_DECREF(temp);
+			n = strlen(buf);
+			w_byte((int)n, p);
+			w_string(buf, (int)n, p);
+			temp = (PyFloatObject*)PyFloat_FromDouble(
+				PyComplex_ImagAsDouble(v));
+			if (!temp) {
+				p->error = 1;
+				return;
+			}
+			PyFloat_AsReprString(buf, temp);
+			Py_DECREF(temp);
+			n = strlen(buf);
+			w_byte((int)n, p);
+			w_string(buf, (int)n, p);
+		}
+	}
+#endif
+	else if (PyString_Check(v)) {
+		if (p->strings && PyString_CHECK_INTERNED(v)) {
+			PyObject *o = PyDict_GetItem(p->strings, v);
+			if (o) {
+				long w = PyInt_AsLong(o);
+				w_byte(TYPE_STRINGREF, p);
+				w_long(w, p);
+				goto exit;
+			}
+			else {
+				o = PyInt_FromSsize_t(PyDict_Size(p->strings));
+				PyDict_SetItem(p->strings, v, o);
+				Py_DECREF(o);
+				w_byte(TYPE_INTERNED, p);
+			}
+		}
+		else {
+			w_byte(TYPE_STRING, p);
+		}
+		n = PyString_GET_SIZE(v);
+		if (n > INT_MAX) {
+			/* huge strings are not supported */
+			p->depth--;
+			p->error = 1;
+			return;
+		}
+		w_long((long)n, p);
+		w_string(PyString_AS_STRING(v), (int)n, p);
+	}
+#ifdef Py_USING_UNICODE
+	else if (PyUnicode_Check(v)) {
+	        PyObject *utf8;
+		utf8 = PyUnicode_AsUTF8String(v);
+		if (utf8 == NULL) {
+			p->depth--;
+			p->error = 1;
+			return;
+		}
+		w_byte(TYPE_UNICODE, p);
+		n = PyString_GET_SIZE(utf8);
+		if (n > INT_MAX) {
+			p->depth--;
+			p->error = 1;
+			return;
+		}
+		w_long((long)n, p);
+		w_string(PyString_AS_STRING(utf8), (int)n, p);
+		Py_DECREF(utf8);
+	}
+#endif
+	else if (PyTuple_Check(v)) {
+		w_byte(TYPE_TUPLE, p);
+		n = PyTuple_Size(v);
+		w_long((long)n, p);
+		for (i = 0; i < n; i++) {
+			w_object(PyTuple_GET_ITEM(v, i), p);
+		}
+	}
+	else if (PyList_Check(v)) {
+		w_byte(TYPE_LIST, p);
+		n = PyList_GET_SIZE(v);
+		w_long((long)n, p);
+		for (i = 0; i < n; i++) {
+			w_object(PyList_GET_ITEM(v, i), p);
+		}
+	}
+	else if (PyDict_Check(v)) {
+		Py_ssize_t pos;
+		PyObject *key, *value;
+		w_byte(TYPE_DICT, p);
+		/* This one is NULL object terminated! */
+		pos = 0;
+		while (PyDict_Next(v, &pos, &key, &value)) {
+			w_object(key, p);
+			w_object(value, p);
+		}
+		w_object((PyObject *)NULL, p);
+	}
+	else if (PyAnySet_Check(v)) {
+		PyObject *value, *it;
+
+		if (PyObject_TypeCheck(v, &PySet_Type))
+			w_byte(TYPE_SET, p);
+		else
+			w_byte(TYPE_FROZENSET, p);
+		n = PyObject_Size(v);
+		if (n == -1) {
+			p->depth--;
+			p->error = 1;
+			return;
+		}
+		w_long((long)n, p);
+		it = PyObject_GetIter(v);
+		if (it == NULL) {
+			p->depth--;
+			p->error = 1;
+			return;
+		}
+		while ((value = PyIter_Next(it)) != NULL) {
+			w_object(value, p);
+			Py_DECREF(value);
+		}
+		Py_DECREF(it);
+		if (PyErr_Occurred()) {
+			p->depth--;
+			p->error = 1;
+			return;
+		}
+	}
+	else if (PyCode_Check(v)) {
+		PyCodeObject *co = (PyCodeObject *)v;
+		w_byte(TYPE_CODE, p);
+		w_long(co->co_argcount, p);
+		w_long(co->co_nlocals, p);
+		w_long(co->co_stacksize, p);
+		w_long(co->co_flags, p);
+		w_object(co->co_code, p);
+		w_object(co->co_consts, p);
+		w_object(co->co_names, p);
+		w_object(co->co_varnames, p);
+		w_object(co->co_freevars, p);
+		w_object(co->co_cellvars, p);
+		w_object(co->co_filename, p);
+		w_object(co->co_name, p);
+		w_long(co->co_firstlineno, p);
+		w_object(co->co_lnotab, p);
+	}
+	else if (PyObject_CheckReadBuffer(v)) {
+		/* Write unknown buffer-style objects as a string */
+		char *s;
+		PyBufferProcs *pb = v->ob_type->tp_as_buffer;
+		w_byte(TYPE_STRING, p);
+		n = (*pb->bf_getreadbuffer)(v, 0, (void **)&s);
+		if (n > INT_MAX) {
+			p->depth--;
+			p->error = 1;
+			return;
+		}
+		w_long((long)n, p);
+		w_string(s, (int)n, p);
+	}
+	else {
+		w_byte(TYPE_UNKNOWN, p);
+		p->error = 1;
+	}
+   exit:
+	p->depth--;
+}
+
+/* version currently has no effect for writing longs. */
+void
+PyMarshal_WriteLongToFile(long x, FILE *fp, int version)
+{
+	WFILE wf;
+	wf.fp = fp;
+	wf.error = 0;
+	wf.depth = 0;
+	wf.strings = NULL;
+	wf.version = version;
+	w_long(x, &wf);
+}
+
+void
+PyMarshal_WriteObjectToFile(PyObject *x, FILE *fp, int version)
+{
+	WFILE wf;
+	wf.fp = fp;
+	wf.error = 0;
+	wf.depth = 0;
+	wf.strings = (version > 0) ? PyDict_New() : NULL;
+	wf.version = version;
+	w_object(x, &wf);
+	Py_XDECREF(wf.strings);
+}
+
+typedef WFILE RFILE; /* Same struct with different invariants */
+
+#define rs_byte(p) (((p)->ptr != (p)->end) ? (unsigned char)*(p)->ptr++ : EOF)
+
+#define r_byte(p) ((p)->fp ? getc((p)->fp) : rs_byte(p))
+
+static int
+r_string(char *s, int n, RFILE *p)
+{
+	if (p->fp != NULL)
+		/* The result fits into int because it must be <=n. */
+		return (int)fread(s, 1, n, p->fp);
+	if (p->end - p->ptr < n)
+		n = (int)(p->end - p->ptr);
+	memcpy(s, p->ptr, n);
+	p->ptr += n;
+	return n;
+}
+
+static int
+r_short(RFILE *p)
+{
+	register short x;
+	x = r_byte(p);
+	x |= r_byte(p) << 8;
+	/* Sign-extension, in case short greater than 16 bits */
+	x |= -(x & 0x8000);
+	return x;
+}
+
+static long
+r_long(RFILE *p)
+{
+	register long x;
+	register FILE *fp = p->fp;
+	if (fp) {
+		x = getc(fp);
+		x |= (long)getc(fp) << 8;
+		x |= (long)getc(fp) << 16;
+		x |= (long)getc(fp) << 24;
+	}
+	else {
+		x = rs_byte(p);
+		x |= (long)rs_byte(p) << 8;
+		x |= (long)rs_byte(p) << 16;
+		x |= (long)rs_byte(p) << 24;
+	}
+#if SIZEOF_LONG > 4
+	/* Sign extension for 64-bit machines */
+	x |= -(x & 0x80000000L);
+#endif
+	return x;
+}
+
+/* r_long64 deals with the TYPE_INT64 code.  On a machine with
+   sizeof(long) > 4, it returns a Python int object, else a Python long
+   object.  Note that w_long64 writes out TYPE_INT if 32 bits is enough,
+   so there's no inefficiency here in returning a PyLong on 32-bit boxes
+   for everything written via TYPE_INT64 (i.e., if an int is written via
+   TYPE_INT64, it *needs* more than 32 bits).
+*/
+static PyObject *
+r_long64(RFILE *p)
+{
+	long lo4 = r_long(p);
+	long hi4 = r_long(p);
+#if SIZEOF_LONG > 4
+	long x = (hi4 << 32) | (lo4 & 0xFFFFFFFFL);
+	return PyInt_FromLong(x);
+#else
+	unsigned char buf[8];
+	int one = 1;
+	int is_little_endian = (int)*(char*)&one;
+	if (is_little_endian) {
+		memcpy(buf, &lo4, 4);
+		memcpy(buf+4, &hi4, 4);
+	}
+	else {
+		memcpy(buf, &hi4, 4);
+		memcpy(buf+4, &lo4, 4);
+	}
+	return _PyLong_FromByteArray(buf, 8, is_little_endian, 1);
+#endif
+}
+
+static PyObject *
+r_object(RFILE *p)
+{
+	/* NULL is a valid return value, it does not necessarily means that
+	   an exception is set. */
+	PyObject *v, *v2, *v3;
+	long i, n;
+	int type = r_byte(p);
+
+	switch (type) {
+
+	case EOF:
+		PyErr_SetString(PyExc_EOFError,
+				"EOF read where object expected");
+		return NULL;
+
+	case TYPE_NULL:
+		return NULL;
+
+	case TYPE_NONE:
+		Py_INCREF(Py_None);
+		return Py_None;
+
+	case TYPE_STOPITER:
+		Py_INCREF(PyExc_StopIteration);
+		return PyExc_StopIteration;
+
+	case TYPE_ELLIPSIS:
+		Py_INCREF(Py_Ellipsis);
+		return Py_Ellipsis;
+
+	case TYPE_FALSE:
+		Py_INCREF(Py_False);
+		return Py_False;
+
+	case TYPE_TRUE:
+		Py_INCREF(Py_True);
+		return Py_True;
+
+	case TYPE_INT:
+		return PyInt_FromLong(r_long(p));
+
+	case TYPE_INT64:
+		return r_long64(p);
+
+	case TYPE_LONG:
+		{
+			int size;
+			PyLongObject *ob;
+			n = r_long(p);
+			if (n < -INT_MAX || n > INT_MAX) {
+				PyErr_SetString(PyExc_ValueError,
+						"bad marshal data");
+				return NULL;
+			}
+			size = n<0 ? -n : n;
+			ob = _PyLong_New(size);
+			if (ob == NULL)
+				return NULL;
+			ob->ob_size = n;
+			for (i = 0; i < size; i++) {
+				int digit = r_short(p);
+				if (digit < 0) {
+					Py_DECREF(ob);
+					PyErr_SetString(PyExc_ValueError,
+							"bad marshal data");
+					return NULL;
+				}
+				ob->ob_digit[i] = digit;
+			}
+			return (PyObject *)ob;
+		}
+
+	case TYPE_FLOAT:
+		{
+			char buf[256];
+			double dx;
+			n = r_byte(p);
+			if (n == EOF || r_string(buf, (int)n, p) != n) {
+				PyErr_SetString(PyExc_EOFError,
+					"EOF read where object expected");
+				return NULL;
+			}
+			buf[n] = '\0';
+			PyFPE_START_PROTECT("atof", return 0)
+			dx = PyOS_ascii_atof(buf);
+			PyFPE_END_PROTECT(dx)
+			return PyFloat_FromDouble(dx);
+		}
+
+	case TYPE_BINARY_FLOAT:
+		{
+			unsigned char buf[8];
+			double x;
+			if (r_string((char*)buf, 8, p) != 8) {
+				PyErr_SetString(PyExc_EOFError,
+					"EOF read where object expected");
+				return NULL;
+			}
+			x = _PyFloat_Unpack8(buf, 1);
+			if (x == -1.0 && PyErr_Occurred()) {
+				return NULL;
+			}
+			return PyFloat_FromDouble(x);
+		}
+
+#ifndef WITHOUT_COMPLEX
+	case TYPE_COMPLEX:
+		{
+			char buf[256];
+			Py_complex c;
+			n = r_byte(p);
+			if (n == EOF || r_string(buf, (int)n, p) != n) {
+				PyErr_SetString(PyExc_EOFError,
+					"EOF read where object expected");
+				return NULL;
+			}
+			buf[n] = '\0';
+			PyFPE_START_PROTECT("atof", return 0)
+			c.real = PyOS_ascii_atof(buf);
+			PyFPE_END_PROTECT(c)
+			n = r_byte(p);
+			if (n == EOF || r_string(buf, (int)n, p) != n) {
+				PyErr_SetString(PyExc_EOFError,
+					"EOF read where object expected");
+				return NULL;
+			}
+			buf[n] = '\0';
+			PyFPE_START_PROTECT("atof", return 0)
+			c.imag = PyOS_ascii_atof(buf);
+			PyFPE_END_PROTECT(c)
+			return PyComplex_FromCComplex(c);
+		}
+
+	case TYPE_BINARY_COMPLEX:
+		{
+			unsigned char buf[8];
+			Py_complex c;
+			if (r_string((char*)buf, 8, p) != 8) {
+				PyErr_SetString(PyExc_EOFError,
+					"EOF read where object expected");
+				return NULL;
+			}
+			c.real = _PyFloat_Unpack8(buf, 1);
+			if (c.real == -1.0 && PyErr_Occurred()) {
+				return NULL;
+			}
+			if (r_string((char*)buf, 8, p) != 8) {
+				PyErr_SetString(PyExc_EOFError,
+					"EOF read where object expected");
+				return NULL;
+			}
+			c.imag = _PyFloat_Unpack8(buf, 1);
+			if (c.imag == -1.0 && PyErr_Occurred()) {
+				return NULL;
+			}
+			return PyComplex_FromCComplex(c);
+		}
+#endif
+
+	case TYPE_INTERNED:
+	case TYPE_STRING:
+		n = r_long(p);
+		if (n < 0 || n > INT_MAX) {
+			PyErr_SetString(PyExc_ValueError, "bad marshal data");
+			return NULL;
+		}
+		v = PyString_FromStringAndSize((char *)NULL, n);
+		if (v == NULL)
+			return v;
+		if (r_string(PyString_AS_STRING(v), (int)n, p) != n) {
+			Py_DECREF(v);
+			PyErr_SetString(PyExc_EOFError,
+					"EOF read where object expected");
+			return NULL;
+		}
+		if (type == TYPE_INTERNED) {
+			PyString_InternInPlace(&v);
+			PyList_Append(p->strings, v);
+		}
+		return v;
+
+	case TYPE_STRINGREF:
+		n = r_long(p);
+		if (n < 0 || n >= PyList_GET_SIZE(p->strings)) {
+			PyErr_SetString(PyExc_ValueError, "bad marshal data");
+			return NULL;
+		}
+		v = PyList_GET_ITEM(p->strings, n);
+		Py_INCREF(v);
+		return v;
+
+#ifdef Py_USING_UNICODE
+	case TYPE_UNICODE:
+	    {
+		char *buffer;
+
+		n = r_long(p);
+		if (n < 0 || n > INT_MAX) {
+			PyErr_SetString(PyExc_ValueError, "bad marshal data");
+			return NULL;
+		}
+		buffer = PyMem_NEW(char, n);
+		if (buffer == NULL)
+			return PyErr_NoMemory();
+		if (r_string(buffer, (int)n, p) != n) {
+			PyMem_DEL(buffer);
+			PyErr_SetString(PyExc_EOFError,
+				"EOF read where object expected");
+			return NULL;
+		}
+		v = PyUnicode_DecodeUTF8(buffer, n, NULL);
+		PyMem_DEL(buffer);
+		return v;
+	    }
+#endif
+
+	case TYPE_TUPLE:
+		n = r_long(p);
+		if (n < 0 || n > INT_MAX) {
+			PyErr_SetString(PyExc_ValueError, "bad marshal data");
+			return NULL;
+		}
+		v = PyTuple_New((int)n);
+		if (v == NULL)
+			return v;
+		for (i = 0; i < n; i++) {
+			v2 = r_object(p);
+			if ( v2 == NULL ) {
+				if (!PyErr_Occurred())
+					PyErr_SetString(PyExc_TypeError,
+						"NULL object in marshal data");
+				Py_DECREF(v);
+				v = NULL;
+				break;
+			}
+			PyTuple_SET_ITEM(v, (int)i, v2);
+		}
+		return v;
+
+	case TYPE_LIST:
+		n = r_long(p);
+		if (n < 0 || n > INT_MAX) {
+			PyErr_SetString(PyExc_ValueError, "bad marshal data");
+			return NULL;
+		}
+		v = PyList_New((int)n);
+		if (v == NULL)
+			return v;
+		for (i = 0; i < n; i++) {
+			v2 = r_object(p);
+			if ( v2 == NULL ) {
+				if (!PyErr_Occurred())
+					PyErr_SetString(PyExc_TypeError,
+						"NULL object in marshal data");
+				Py_DECREF(v);
+				v = NULL;
+				break;
+			}
+			PyList_SetItem(v, (int)i, v2);
+		}
+		return v;
+
+	case TYPE_DICT:
+		v = PyDict_New();
+		if (v == NULL)
+			return NULL;
+		for (;;) {
+			PyObject *key, *val;
+			key = r_object(p);
+			if (key == NULL)
+				break;
+			val = r_object(p);
+			if (val != NULL)
+				PyDict_SetItem(v, key, val);
+			Py_DECREF(key);
+			Py_XDECREF(val);
+		}
+		if (PyErr_Occurred()) {
+			Py_DECREF(v);
+			v = NULL;
+		}
+		return v;
+
+	case TYPE_SET:
+	case TYPE_FROZENSET:
+		n = r_long(p);
+		if (n < 0) {
+			PyErr_SetString(PyExc_ValueError, "bad marshal data");
+			return NULL;
+		}
+		v = PyTuple_New((int)n);
+		if (v == NULL)
+			return v;
+		for (i = 0; i < n; i++) {
+			v2 = r_object(p);
+			if ( v2 == NULL ) {
+				if (!PyErr_Occurred())
+					PyErr_SetString(PyExc_TypeError,
+						"NULL object in marshal data");
+				Py_DECREF(v);
+				v = NULL;
+				break;
+			}
+			PyTuple_SET_ITEM(v, (int)i, v2);
+		}
+		if (v == NULL)
+			return v;
+		if (type == TYPE_SET)
+			v3 = PySet_New(v);
+		else
+			v3 = PyFrozenSet_New(v);
+		Py_DECREF(v);
+		return v3;
+
+	case TYPE_CODE:
+		if (PyEval_GetRestricted()) {
+			PyErr_SetString(PyExc_RuntimeError,
+				"cannot unmarshal code objects in "
+				"restricted execution mode");
+			return NULL;
+		}
+		else {
+			int argcount;
+			int nlocals;
+			int stacksize;
+			int flags;
+			PyObject *code = NULL;
+			PyObject *consts = NULL;
+			PyObject *names = NULL;
+			PyObject *varnames = NULL;
+			PyObject *freevars = NULL;
+			PyObject *cellvars = NULL;
+			PyObject *filename = NULL;
+			PyObject *name = NULL;
+			int firstlineno;
+			PyObject *lnotab = NULL;
+			
+			v = NULL;
+
+                        /* XXX ignore long->int overflows for now */
+			argcount = (int)r_long(p);
+			nlocals = (int)r_long(p);
+			stacksize = (int)r_long(p);
+			flags = (int)r_long(p);
+			code = r_object(p);
+			if (code == NULL)
+				goto code_error;
+			consts = r_object(p);
+			if (consts == NULL)
+				goto code_error;
+			names = r_object(p);
+			if (names == NULL)
+				goto code_error;
+			varnames = r_object(p);
+			if (varnames == NULL)
+				goto code_error;
+			freevars = r_object(p);
+			if (freevars == NULL)
+				goto code_error;
+			cellvars = r_object(p);
+			if (cellvars == NULL)
+				goto code_error;
+			filename = r_object(p);
+			if (filename == NULL)
+				goto code_error;
+			name = r_object(p);
+			if (name == NULL)
+				goto code_error;
+			firstlineno = (int)r_long(p);
+			lnotab = r_object(p);
+			if (lnotab == NULL)
+				goto code_error;
+
+			v = (PyObject *) PyCode_New(
+					argcount, nlocals, stacksize, flags,
+					code, consts, names, varnames,
+					freevars, cellvars, filename, name,
+					firstlineno, lnotab);
+
+		  code_error:
+			Py_XDECREF(code);
+			Py_XDECREF(consts);
+			Py_XDECREF(names);
+			Py_XDECREF(varnames);
+			Py_XDECREF(freevars);
+			Py_XDECREF(cellvars);
+			Py_XDECREF(filename);
+			Py_XDECREF(name);
+			Py_XDECREF(lnotab);
+
+		}
+		return v;
+
+	default:
+		/* Bogus data got written, which isn't ideal.
+		   This will let you keep working and recover. */
+		PyErr_SetString(PyExc_ValueError, "bad marshal data");
+		return NULL;
+
+	}
+}
+
+static PyObject *
+read_object(RFILE *p)
+{
+	PyObject *v;
+	if (PyErr_Occurred()) {
+		fprintf(stderr, "XXX readobject called with exception set\n");
+		return NULL;
+	}
+	v = r_object(p);
+	if (v == NULL && !PyErr_Occurred())
+		PyErr_SetString(PyExc_TypeError, "NULL object in marshal data");
+	return v;
+}
+
+int
+PyMarshal_ReadShortFromFile(FILE *fp)
+{
+	RFILE rf;
+	assert(fp);
+	rf.fp = fp;
+	rf.strings = NULL;
+	rf.end = rf.ptr = NULL;
+	return r_short(&rf);
+}
+
+long
+PyMarshal_ReadLongFromFile(FILE *fp)
+{
+	RFILE rf;
+	rf.fp = fp;
+	rf.strings = NULL;
+	return r_long(&rf);
+}
+
+#ifdef HAVE_FSTAT
+/* Return size of file in bytes; < 0 if unknown. */
+static off_t
+getfilesize(FILE *fp)
+{
+	struct stat st;
+	if (fstat(fileno(fp), &st) != 0)
+		return -1;
+	else
+		return st.st_size;
+}
+#endif
+
+/* If we can get the size of the file up-front, and it's reasonably small,
+ * read it in one gulp and delegate to ...FromString() instead.  Much quicker
+ * than reading a byte at a time from file; speeds .pyc imports.
+ * CAUTION:  since this may read the entire remainder of the file, don't
+ * call it unless you know you're done with the file.
+ */
+PyObject *
+PyMarshal_ReadLastObjectFromFile(FILE *fp)
+{
+/* 75% of 2.1's .pyc files can exploit SMALL_FILE_LIMIT.
+ * REASONABLE_FILE_LIMIT is by defn something big enough for Tkinter.pyc.
+ */
+#define SMALL_FILE_LIMIT (1L << 14)
+#define REASONABLE_FILE_LIMIT (1L << 18)
+#ifdef HAVE_FSTAT
+	off_t filesize;
+#endif
+#ifdef HAVE_FSTAT
+	filesize = getfilesize(fp);
+	if (filesize > 0) {
+		char buf[SMALL_FILE_LIMIT];
+		char* pBuf = NULL;
+		if (filesize <= SMALL_FILE_LIMIT)
+			pBuf = buf;
+		else if (filesize <= REASONABLE_FILE_LIMIT)
+			pBuf = (char *)PyMem_MALLOC(filesize);
+		if (pBuf != NULL) {
+			PyObject* v;
+			size_t n;
+			/* filesize must fit into an int, because it
+			   is smaller than REASONABLE_FILE_LIMIT */
+			n = fread(pBuf, 1, (int)filesize, fp);
+			v = PyMarshal_ReadObjectFromString(pBuf, n);
+			if (pBuf != buf)
+				PyMem_FREE(pBuf);
+			return v;
+		}
+
+	}
+#endif
+	/* We don't have fstat, or we do but the file is larger than
+	 * REASONABLE_FILE_LIMIT or malloc failed -- read a byte at a time.
+	 */
+	return PyMarshal_ReadObjectFromFile(fp);
+
+#undef SMALL_FILE_LIMIT
+#undef REASONABLE_FILE_LIMIT
+}
+
+PyObject *
+PyMarshal_ReadObjectFromFile(FILE *fp)
+{
+	RFILE rf;
+	PyObject *result;
+	rf.fp = fp;
+	rf.strings = PyList_New(0);
+	result = r_object(&rf);
+	Py_DECREF(rf.strings);
+	return result;
+}
+
+PyObject *
+PyMarshal_ReadObjectFromString(char *str, Py_ssize_t len)
+{
+	RFILE rf;
+	PyObject *result;
+	rf.fp = NULL;
+	rf.ptr = str;
+	rf.end = str + len;
+	rf.strings = PyList_New(0);
+	result = r_object(&rf);
+	Py_DECREF(rf.strings);
+	return result;
+}
+
+PyObject *
+PyMarshal_WriteObjectToString(PyObject *x, int version)
+{
+	WFILE wf;
+	wf.fp = NULL;
+	wf.str = PyString_FromStringAndSize((char *)NULL, 50);
+	if (wf.str == NULL)
+		return NULL;
+	wf.ptr = PyString_AS_STRING((PyStringObject *)wf.str);
+	wf.end = wf.ptr + PyString_Size(wf.str);
+	wf.error = 0;
+	wf.depth = 0;
+	wf.version = version;
+	wf.strings = (version > 0) ? PyDict_New() : NULL;
+	w_object(x, &wf);
+	Py_XDECREF(wf.strings);
+	if (wf.str != NULL) {
+		char *base = PyString_AS_STRING((PyStringObject *)wf.str);
+		if (wf.ptr - base > PY_SSIZE_T_MAX) {
+			Py_DECREF(wf.str);
+			PyErr_SetString(PyExc_OverflowError,
+					"too much marshall data for a string");
+			return NULL;
+		}
+		_PyString_Resize(&wf.str, (Py_ssize_t)(wf.ptr - base));
+	}
+	if (wf.error) {
+		Py_XDECREF(wf.str);
+		PyErr_SetString(PyExc_ValueError,
+				(wf.error==1)?"unmarshallable object"
+				:"object too deeply nested to marshal");
+		return NULL;
+	}
+	return wf.str;
+}
+
+/* And an interface for Python programs... */
+
+static PyObject *
+marshal_dump(PyObject *self, PyObject *args)
+{
+	WFILE wf;
+	PyObject *x;
+	PyObject *f;
+	int version = Py_MARSHAL_VERSION;
+	if (!PyArg_ParseTuple(args, "OO|i:dump", &x, &f, &version))
+		return NULL;
+	if (!PyFile_Check(f)) {
+		PyErr_SetString(PyExc_TypeError,
+				"marshal.dump() 2nd arg must be file");
+		return NULL;
+	}
+	wf.fp = PyFile_AsFile(f);
+	wf.str = NULL;
+	wf.ptr = wf.end = NULL;
+	wf.error = 0;
+	wf.depth = 0;
+	wf.strings = (version > 0) ? PyDict_New() : 0;
+	wf.version = version;
+	w_object(x, &wf);
+	Py_XDECREF(wf.strings);
+	if (wf.error) {
+		PyErr_SetString(PyExc_ValueError,
+				(wf.error==1)?"unmarshallable object"
+				:"object too deeply nested to marshal");
+		return NULL;
+	}
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+marshal_load(PyObject *self, PyObject *f)
+{
+	RFILE rf;
+	PyObject *result;
+	if (!PyFile_Check(f)) {
+		PyErr_SetString(PyExc_TypeError,
+				"marshal.load() arg must be file");
+		return NULL;
+	}
+	rf.fp = PyFile_AsFile(f);
+	rf.strings = PyList_New(0);
+	result = read_object(&rf);
+	Py_DECREF(rf.strings);
+	return result;
+}
+
+static PyObject *
+marshal_dumps(PyObject *self, PyObject *args)
+{
+	PyObject *x;
+	int version = Py_MARSHAL_VERSION;
+	if (!PyArg_ParseTuple(args, "O|i:dumps", &x, &version))
+		return NULL;
+	return PyMarshal_WriteObjectToString(x, version);
+}
+
+static PyObject *
+marshal_loads(PyObject *self, PyObject *args)
+{
+	RFILE rf;
+	char *s;
+	Py_ssize_t n;
+	PyObject* result;
+	if (!PyArg_ParseTuple(args, "s#:loads", &s, &n))
+		return NULL;
+	rf.fp = NULL;
+	rf.ptr = s;
+	rf.end = s + n;
+	rf.strings = PyList_New(0);
+	result = read_object(&rf);
+	Py_DECREF(rf.strings);
+	return result;
+}
+
+static PyMethodDef marshal_methods[] = {
+	{"dump",	marshal_dump,	METH_VARARGS},
+	{"load",	marshal_load,	METH_O},
+	{"dumps",	marshal_dumps,	METH_VARARGS},
+	{"loads",	marshal_loads,	METH_VARARGS},
+	{NULL,		NULL}		/* sentinel */
+};
+
+PyMODINIT_FUNC
+PyMarshal_Init(void)
+{
+	PyObject *mod = Py_InitModule("marshal", marshal_methods);
+	if (mod == NULL)
+		return;
+	PyModule_AddIntConstant(mod, "version", Py_MARSHAL_VERSION);
+}

Added: vendor/Python/current/Python/memmove.c
===================================================================
--- vendor/Python/current/Python/memmove.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/memmove.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,25 @@
+
+/* A perhaps slow but I hope correct implementation of memmove */
+
+extern char *memcpy(char *, char *, int);
+
+char *
+memmove(char *dst, char *src, int n)
+{
+	char *realdst = dst;
+	if (n <= 0)
+		return dst;
+	if (src >= dst+n || dst >= src+n)
+		return memcpy(dst, src, n);
+	if (src > dst) {
+		while (--n >= 0)
+			*dst++ = *src++;
+	}
+	else if (src < dst) {
+		src += n;
+		dst += n;
+		while (--n >= 0)
+			*--dst = *--src;
+	}
+	return realdst;
+}

Added: vendor/Python/current/Python/modsupport.c
===================================================================
--- vendor/Python/current/Python/modsupport.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/modsupport.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,631 @@
+
+/* Module support implementation */
+
+#include "Python.h"
+
+#define FLAG_SIZE_T 1
+typedef double va_double;
+
+static PyObject *va_build_value(const char *, va_list, int);
+
+/* Package context -- the full module name for package imports */
+char *_Py_PackageContext = NULL;
+
+/* Py_InitModule4() parameters:
+   - name is the module name
+   - methods is the list of top-level functions
+   - doc is the documentation string
+   - passthrough is passed as self to functions defined in the module
+   - api_version is the value of PYTHON_API_VERSION at the time the
+     module was compiled
+
+   Return value is a borrowed reference to the module object; or NULL
+   if an error occurred (in Python 1.4 and before, errors were fatal).
+   Errors may still leak memory.
+*/
+
+static char api_version_warning[] =
+"Python C API version mismatch for module %.100s:\
+ This Python has API version %d, module %.100s has version %d.";
+
+PyObject *
+Py_InitModule4(const char *name, PyMethodDef *methods, const char *doc,
+	       PyObject *passthrough, int module_api_version)
+{
+	PyObject *m, *d, *v, *n;
+	PyMethodDef *ml;
+	if (!Py_IsInitialized())
+	    Py_FatalError("Interpreter not initialized (version mismatch?)");
+	if (module_api_version != PYTHON_API_VERSION) {
+		char message[512];
+		PyOS_snprintf(message, sizeof(message), 
+			      api_version_warning, name, 
+			      PYTHON_API_VERSION, name, 
+			      module_api_version);
+		if (PyErr_Warn(PyExc_RuntimeWarning, message)) 
+			return NULL;
+	}
+	/* Make sure name is fully qualified.
+
+	   This is a bit of a hack: when the shared library is loaded,
+	   the module name is "package.module", but the module calls
+	   Py_InitModule*() with just "module" for the name.  The shared
+	   library loader squirrels away the true name of the module in
+	   _Py_PackageContext, and Py_InitModule*() will substitute this
+	   (if the name actually matches).
+	*/
+	if (_Py_PackageContext != NULL) {
+		char *p = strrchr(_Py_PackageContext, '.');
+		if (p != NULL && strcmp(name, p+1) == 0) {
+			name = _Py_PackageContext;
+			_Py_PackageContext = NULL;
+		}
+	}
+	if ((m = PyImport_AddModule(name)) == NULL)
+		return NULL;
+	d = PyModule_GetDict(m);
+	if (methods != NULL) {
+		n = PyString_FromString(name);
+		if (n == NULL)
+			return NULL;
+		for (ml = methods; ml->ml_name != NULL; ml++) {
+			if ((ml->ml_flags & METH_CLASS) ||
+			    (ml->ml_flags & METH_STATIC)) {
+				PyErr_SetString(PyExc_ValueError,
+						"module functions cannot set"
+						" METH_CLASS or METH_STATIC");
+				Py_DECREF(n);
+				return NULL;
+			}
+			v = PyCFunction_NewEx(ml, passthrough, n);
+			if (v == NULL) {
+				Py_DECREF(n);
+				return NULL;
+			}
+			if (PyDict_SetItemString(d, ml->ml_name, v) != 0) {
+				Py_DECREF(v);
+				Py_DECREF(n);
+				return NULL;
+			}
+			Py_DECREF(v);
+		}
+		Py_DECREF(n);
+	}
+	if (doc != NULL) {
+		v = PyString_FromString(doc);
+		if (v == NULL || PyDict_SetItemString(d, "__doc__", v) != 0) {
+			Py_XDECREF(v);
+			return NULL;
+		}
+		Py_DECREF(v);
+	}
+	return m;
+}
+
+
+/* Helper for mkvalue() to scan the length of a format */
+
+static int
+countformat(const char *format, int endchar)
+{
+	int count = 0;
+	int level = 0;
+	while (level > 0 || *format != endchar) {
+		switch (*format) {
+		case '\0':
+			/* Premature end */
+			PyErr_SetString(PyExc_SystemError,
+					"unmatched paren in format");
+			return -1;
+		case '(':
+		case '[':
+		case '{':
+			if (level == 0)
+				count++;
+			level++;
+			break;
+		case ')':
+		case ']':
+		case '}':
+			level--;
+			break;
+		case '#':
+		case '&':
+		case ',':
+		case ':':
+		case ' ':
+		case '\t':
+			break;
+		default:
+			if (level == 0)
+				count++;
+		}
+		format++;
+	}
+	return count;
+}
+
+
+/* Generic function to create a value -- the inverse of getargs() */
+/* After an original idea and first implementation by Steven Miale */
+
+static PyObject *do_mktuple(const char**, va_list *, int, int, int);
+static PyObject *do_mklist(const char**, va_list *, int, int, int);
+static PyObject *do_mkdict(const char**, va_list *, int, int, int);
+static PyObject *do_mkvalue(const char**, va_list *, int);
+
+
+static PyObject *
+do_mkdict(const char **p_format, va_list *p_va, int endchar, int n, int flags)
+{
+	PyObject *d;
+	int i;
+	int itemfailed = 0;
+	if (n < 0)
+		return NULL;
+	if ((d = PyDict_New()) == NULL)
+		return NULL;
+	/* Note that we can't bail immediately on error as this will leak
+	   refcounts on any 'N' arguments. */
+	for (i = 0; i < n; i+= 2) {
+		PyObject *k, *v;
+		int err;
+		k = do_mkvalue(p_format, p_va, flags);
+		if (k == NULL) {
+			itemfailed = 1;
+			Py_INCREF(Py_None);
+			k = Py_None;
+		}
+		v = do_mkvalue(p_format, p_va, flags);
+		if (v == NULL) {
+			itemfailed = 1;
+			Py_INCREF(Py_None);
+			v = Py_None;
+		}
+		err = PyDict_SetItem(d, k, v);
+		Py_DECREF(k);
+		Py_DECREF(v);
+		if (err < 0 || itemfailed) {
+			Py_DECREF(d);
+			return NULL;
+		}
+	}
+	if (d != NULL && **p_format != endchar) {
+		Py_DECREF(d);
+		d = NULL;
+		PyErr_SetString(PyExc_SystemError,
+				"Unmatched paren in format");
+	}
+	else if (endchar)
+		++*p_format;
+	return d;
+}
+
+static PyObject *
+do_mklist(const char **p_format, va_list *p_va, int endchar, int n, int flags)
+{
+	PyObject *v;
+	int i;
+	int itemfailed = 0;
+	if (n < 0)
+		return NULL;
+	v = PyList_New(n);
+	if (v == NULL)
+		return NULL;
+	/* Note that we can't bail immediately on error as this will leak
+	   refcounts on any 'N' arguments. */
+	for (i = 0; i < n; i++) {
+		PyObject *w = do_mkvalue(p_format, p_va, flags);
+		if (w == NULL) {
+			itemfailed = 1;
+			Py_INCREF(Py_None);
+			w = Py_None;
+		}
+		PyList_SET_ITEM(v, i, w);
+	}
+
+	if (itemfailed) {
+		/* do_mkvalue() should have already set an error */
+		Py_DECREF(v);
+		return NULL;
+	}
+	if (**p_format != endchar) {
+		Py_DECREF(v);
+		PyErr_SetString(PyExc_SystemError,
+				"Unmatched paren in format");
+		return NULL;
+	}
+	if (endchar)
+		++*p_format;
+	return v;
+}
+
+#ifdef Py_USING_UNICODE
+static int
+_ustrlen(Py_UNICODE *u)
+{
+	int i = 0;
+	Py_UNICODE *v = u;
+	while (*v != 0) { i++; v++; } 
+	return i;
+}
+#endif
+
+static PyObject *
+do_mktuple(const char **p_format, va_list *p_va, int endchar, int n, int flags)
+{
+	PyObject *v;
+	int i;
+	int itemfailed = 0;
+	if (n < 0)
+		return NULL;
+	if ((v = PyTuple_New(n)) == NULL)
+		return NULL;
+	/* Note that we can't bail immediately on error as this will leak
+	   refcounts on any 'N' arguments. */
+	for (i = 0; i < n; i++) {
+		PyObject *w = do_mkvalue(p_format, p_va, flags);
+		if (w == NULL) {
+			itemfailed = 1;
+			Py_INCREF(Py_None);
+			w = Py_None;
+		}
+		PyTuple_SET_ITEM(v, i, w);
+	}
+	if (itemfailed) {
+		/* do_mkvalue() should have already set an error */
+		Py_DECREF(v);
+		return NULL;
+	}
+	if (**p_format != endchar) {
+		Py_DECREF(v);
+		PyErr_SetString(PyExc_SystemError,
+				"Unmatched paren in format");
+		return NULL;
+	}
+	if (endchar)
+		++*p_format;
+	return v;
+}
+
+static PyObject *
+do_mkvalue(const char **p_format, va_list *p_va, int flags)
+{
+	for (;;) {
+		switch (*(*p_format)++) {
+		case '(':
+			return do_mktuple(p_format, p_va, ')',
+					  countformat(*p_format, ')'), flags);
+
+		case '[':
+			return do_mklist(p_format, p_va, ']',
+					 countformat(*p_format, ']'), flags);
+
+		case '{':
+			return do_mkdict(p_format, p_va, '}',
+					 countformat(*p_format, '}'), flags);
+
+		case 'b':
+		case 'B':
+		case 'h':
+		case 'i':
+			return PyInt_FromLong((long)va_arg(*p_va, int));
+			
+		case 'H':
+			return PyInt_FromLong((long)va_arg(*p_va, unsigned int));
+
+		case 'I':
+		{
+			unsigned int n;
+			n = va_arg(*p_va, unsigned int);
+			if (n > (unsigned long)PyInt_GetMax())
+				return PyLong_FromUnsignedLong((unsigned long)n);
+			else
+				return PyInt_FromLong(n);
+		}
+		
+		case 'n':
+#if SIZEOF_SIZE_T!=SIZEOF_LONG
+			return PyInt_FromSsize_t(va_arg(*p_va, Py_ssize_t));
+#endif
+			/* Fall through from 'n' to 'l' if Py_ssize_t is long */
+		case 'l':
+			return PyInt_FromLong(va_arg(*p_va, long));
+
+		case 'k':
+		{
+			unsigned long n;
+			n = va_arg(*p_va, unsigned long);
+			if (n > (unsigned long)PyInt_GetMax())
+				return PyLong_FromUnsignedLong(n);
+			else
+				return PyInt_FromLong(n);
+		}
+
+#ifdef HAVE_LONG_LONG
+		case 'L':
+			return PyLong_FromLongLong((PY_LONG_LONG)va_arg(*p_va, PY_LONG_LONG));
+
+		case 'K':
+			return PyLong_FromUnsignedLongLong((PY_LONG_LONG)va_arg(*p_va, unsigned PY_LONG_LONG));
+#endif
+#ifdef Py_USING_UNICODE
+		case 'u':
+		{
+			PyObject *v;
+			Py_UNICODE *u = va_arg(*p_va, Py_UNICODE *);
+			Py_ssize_t n;	
+			if (**p_format == '#') {
+				++*p_format;
+				if (flags & FLAG_SIZE_T)
+					n = va_arg(*p_va, Py_ssize_t);
+				else
+					n = va_arg(*p_va, int);
+			}
+			else
+				n = -1;
+			if (u == NULL) {
+				v = Py_None;
+				Py_INCREF(v);
+			}
+			else {
+				if (n < 0)
+					n = _ustrlen(u);
+				v = PyUnicode_FromUnicode(u, n);
+			}
+			return v;
+		}
+#endif
+		case 'f':
+		case 'd':
+			return PyFloat_FromDouble(
+				(double)va_arg(*p_va, va_double));
+
+#ifndef WITHOUT_COMPLEX
+		case 'D':
+			return PyComplex_FromCComplex(
+				*((Py_complex *)va_arg(*p_va, Py_complex *)));
+#endif /* WITHOUT_COMPLEX */
+
+		case 'c':
+		{
+			char p[1];
+			p[0] = (char)va_arg(*p_va, int);
+			return PyString_FromStringAndSize(p, 1);
+		}
+
+		case 's':
+		case 'z':
+		{
+			PyObject *v;
+			char *str = va_arg(*p_va, char *);
+			Py_ssize_t n;
+			if (**p_format == '#') {
+				++*p_format;
+				if (flags & FLAG_SIZE_T)
+					n = va_arg(*p_va, Py_ssize_t);
+				else
+					n = va_arg(*p_va, int);
+			}
+			else
+				n = -1;
+			if (str == NULL) {
+				v = Py_None;
+				Py_INCREF(v);
+			}
+			else {
+				if (n < 0) {
+					size_t m = strlen(str);
+					if (m > PY_SSIZE_T_MAX) {
+						PyErr_SetString(PyExc_OverflowError,
+							"string too long for Python string");
+						return NULL;
+					}
+					n = (Py_ssize_t)m;
+				}
+				v = PyString_FromStringAndSize(str, n);
+			}
+			return v;
+		}
+
+		case 'N':
+		case 'S':
+		case 'O':
+		if (**p_format == '&') {
+			typedef PyObject *(*converter)(void *);
+			converter func = va_arg(*p_va, converter);
+			void *arg = va_arg(*p_va, void *);
+			++*p_format;
+			return (*func)(arg);
+		}
+		else {
+			PyObject *v;
+			v = va_arg(*p_va, PyObject *);
+			if (v != NULL) {
+				if (*(*p_format - 1) != 'N')
+					Py_INCREF(v);
+			}
+			else if (!PyErr_Occurred())
+				/* If a NULL was passed
+				 * because a call that should
+				 * have constructed a value
+				 * failed, that's OK, and we
+				 * pass the error on; but if
+				 * no error occurred it's not
+				 * clear that the caller knew
+				 * what she was doing. */
+				PyErr_SetString(PyExc_SystemError,
+					"NULL object passed to Py_BuildValue");
+			return v;
+		}
+
+		case ':':
+		case ',':
+		case ' ':
+		case '\t':
+			break;
+
+		default:
+			PyErr_SetString(PyExc_SystemError,
+				"bad format char passed to Py_BuildValue");
+			return NULL;
+
+		}
+	}
+}
+
+
+PyObject *
+Py_BuildValue(const char *format, ...)
+{
+	va_list va;
+	PyObject* retval;
+	va_start(va, format);
+	retval = va_build_value(format, va, 0);
+	va_end(va);
+	return retval;
+}
+
+PyObject *
+_Py_BuildValue_SizeT(const char *format, ...)
+{
+	va_list va;
+	PyObject* retval;
+	va_start(va, format);
+	retval = va_build_value(format, va, FLAG_SIZE_T);
+	va_end(va);
+	return retval;
+}
+
+PyObject *
+Py_VaBuildValue(const char *format, va_list va)
+{
+	return va_build_value(format, va, 0);
+}
+
+PyObject *
+_Py_VaBuildValue_SizeT(const char *format, va_list va)
+{
+	return va_build_value(format, va, FLAG_SIZE_T);
+}
+
+static PyObject *
+va_build_value(const char *format, va_list va, int flags)
+{
+	const char *f = format;
+	int n = countformat(f, '\0');
+	va_list lva;
+
+#ifdef VA_LIST_IS_ARRAY
+	memcpy(lva, va, sizeof(va_list));
+#else
+#ifdef __va_copy
+	__va_copy(lva, va);
+#else
+	lva = va;
+#endif
+#endif
+
+	if (n < 0)
+		return NULL;
+	if (n == 0) {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+	if (n == 1)
+		return do_mkvalue(&f, &lva, flags);
+	return do_mktuple(&f, &lva, '\0', n, flags);
+}
+
+
+PyObject *
+PyEval_CallFunction(PyObject *obj, const char *format, ...)
+{
+	va_list vargs;
+	PyObject *args;
+	PyObject *res;
+
+	va_start(vargs, format);
+
+	args = Py_VaBuildValue(format, vargs);
+	va_end(vargs);
+
+	if (args == NULL)
+		return NULL;
+
+	res = PyEval_CallObject(obj, args);
+	Py_DECREF(args);
+
+	return res;
+}
+
+
+PyObject *
+PyEval_CallMethod(PyObject *obj, const char *methodname, const char *format, ...)
+{
+	va_list vargs;
+	PyObject *meth;
+	PyObject *args;
+	PyObject *res;
+
+	meth = PyObject_GetAttrString(obj, methodname);
+	if (meth == NULL)
+		return NULL;
+
+	va_start(vargs, format);
+
+	args = Py_VaBuildValue(format, vargs);
+	va_end(vargs);
+
+	if (args == NULL) {
+		Py_DECREF(meth);
+		return NULL;
+	}
+
+	res = PyEval_CallObject(meth, args);
+	Py_DECREF(meth);
+	Py_DECREF(args);
+
+	return res;
+}
+
+int
+PyModule_AddObject(PyObject *m, const char *name, PyObject *o)
+{
+	PyObject *dict;
+	if (!PyModule_Check(m)) {
+		PyErr_SetString(PyExc_TypeError,
+			    "PyModule_AddObject() needs module as first arg");
+		return -1;
+	}
+	if (!o) {
+		if (!PyErr_Occurred())
+			PyErr_SetString(PyExc_TypeError,
+					"PyModule_AddObject() needs non-NULL value");
+		return -1;
+	}
+
+	dict = PyModule_GetDict(m);
+	if (dict == NULL) {
+		/* Internal error -- modules must have a dict! */
+		PyErr_Format(PyExc_SystemError, "module '%s' has no __dict__",
+			     PyModule_GetName(m));
+		return -1;
+	}
+	if (PyDict_SetItemString(dict, name, o))
+		return -1;
+	Py_DECREF(o);
+	return 0;
+}
+
+int 
+PyModule_AddIntConstant(PyObject *m, const char *name, long value)
+{
+	return PyModule_AddObject(m, name, PyInt_FromLong(value));
+}
+
+int 
+PyModule_AddStringConstant(PyObject *m, const char *name, const char *value)
+{
+	return PyModule_AddObject(m, name, PyString_FromString(value));
+}

Added: vendor/Python/current/Python/mysnprintf.c
===================================================================
--- vendor/Python/current/Python/mysnprintf.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/mysnprintf.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,93 @@
+#include "Python.h"
+#include <ctype.h>
+
+/* snprintf() wrappers.  If the platform has vsnprintf, we use it, else we
+   emulate it in a half-hearted way.  Even if the platform has it, we wrap
+   it because platforms differ in what vsnprintf does in case the buffer
+   is too small:  C99 behavior is to return the number of characters that
+   would have been written had the buffer not been too small, and to set
+   the last byte of the buffer to \0.  At least MS _vsnprintf returns a
+   negative value instead, and fills the entire buffer with non-\0 data.
+
+   The wrappers ensure that str[size-1] is always \0 upon return.
+
+   PyOS_snprintf and PyOS_vsnprintf never write more than size bytes
+   (including the trailing '\0') into str.
+
+   If the platform doesn't have vsnprintf, and the buffer size needed to
+   avoid truncation exceeds size by more than 512, Python aborts with a
+   Py_FatalError.
+
+   Return value (rv):
+
+	When 0 <= rv < size, the output conversion was unexceptional, and
+	rv characters were written to str (excluding a trailing \0 byte at
+	str[rv]).
+
+	When rv >= size, output conversion was truncated, and a buffer of
+	size rv+1 would have been needed to avoid truncation.  str[size-1]
+	is \0 in this case.
+
+	When rv < 0, "something bad happened".  str[size-1] is \0 in this
+	case too, but the rest of str is unreliable.  It could be that
+	an error in format codes was detected by libc, or on platforms
+	with a non-C99 vsnprintf simply that the buffer wasn't big enough
+	to avoid truncation, or on platforms without any vsnprintf that
+	PyMem_Malloc couldn't obtain space for a temp buffer.
+
+   CAUTION:  Unlike C99, str != NULL and size > 0 are required.
+*/
+
+int
+PyOS_snprintf(char *str, size_t size, const  char  *format, ...)
+{
+	int rc;
+	va_list va;
+
+	va_start(va, format);
+	rc = PyOS_vsnprintf(str, size, format, va);
+	va_end(va);
+	return rc;
+}
+
+int
+PyOS_vsnprintf(char *str, size_t size, const char  *format, va_list va)
+{
+	int len;  /* # bytes written, excluding \0 */
+#ifndef HAVE_SNPRINTF
+	char *buffer;
+#endif
+	assert(str != NULL);
+	assert(size > 0);
+	assert(format != NULL);
+
+#ifdef HAVE_SNPRINTF
+	len = vsnprintf(str, size, format, va);
+#else
+	/* Emulate it. */
+	buffer = PyMem_MALLOC(size + 512);
+	if (buffer == NULL) {
+		len = -666;
+		goto Done;
+	}
+
+	len = vsprintf(buffer, format, va);
+	if (len < 0)
+		/* ignore the error */;
+
+	else if ((size_t)len >= size + 512)
+		Py_FatalError("Buffer overflow in PyOS_snprintf/PyOS_vsnprintf");
+
+	else {
+		const size_t to_copy = (size_t)len < size ?
+					(size_t)len : size - 1;
+		assert(to_copy < size);
+		memcpy(str, buffer, to_copy);
+		str[to_copy] = '\0';
+	}
+	PyMem_FREE(buffer);
+Done:
+#endif
+	str[size-1] = '\0';
+	return len;
+}

Added: vendor/Python/current/Python/mystrtoul.c
===================================================================
--- vendor/Python/current/Python/mystrtoul.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/mystrtoul.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,232 @@
+
+#include "Python.h"
+
+#if defined(__sgi) && defined(WITH_THREAD) && !defined(_SGI_MP_SOURCE)
+#define _SGI_MP_SOURCE
+#endif
+
+/* Convert a possibly signed character to a nonnegative int */
+/* XXX This assumes characters are 8 bits wide */
+#ifdef __CHAR_UNSIGNED__
+#define Py_CHARMASK(c)		(c)
+#else
+#define Py_CHARMASK(c)		((c) & 0xff)
+#endif
+
+/* strtol and strtoul, renamed to avoid conflicts */
+
+
+#include <ctype.h>
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+/* Static overflow check values for bases 2 through 36.
+ * smallmax[base] is the largest unsigned long i such that
+ * i * base doesn't overflow unsigned long.
+ */
+static unsigned long smallmax[] = {
+	0, /* bases 0 and 1 are invalid */
+	0,
+	ULONG_MAX / 2,
+	ULONG_MAX / 3,
+	ULONG_MAX / 4,
+	ULONG_MAX / 5,
+	ULONG_MAX / 6,
+	ULONG_MAX / 7,
+	ULONG_MAX / 8,
+	ULONG_MAX / 9,
+	ULONG_MAX / 10,
+	ULONG_MAX / 11,
+	ULONG_MAX / 12,
+	ULONG_MAX / 13,
+	ULONG_MAX / 14,
+	ULONG_MAX / 15,
+	ULONG_MAX / 16,
+	ULONG_MAX / 17,
+	ULONG_MAX / 18,
+	ULONG_MAX / 19,
+	ULONG_MAX / 20,
+	ULONG_MAX / 21,
+	ULONG_MAX / 22,
+	ULONG_MAX / 23,
+	ULONG_MAX / 24,
+	ULONG_MAX / 25,
+	ULONG_MAX / 26,
+	ULONG_MAX / 27,
+	ULONG_MAX / 28,
+	ULONG_MAX / 29,
+	ULONG_MAX / 30,
+	ULONG_MAX / 31,
+	ULONG_MAX / 32,
+	ULONG_MAX / 33,
+	ULONG_MAX / 34,
+	ULONG_MAX / 35,
+	ULONG_MAX / 36,
+};
+
+/* maximum digits that can't ever overflow for bases 2 through 36,
+ * calculated by [int(math.floor(math.log(2**32, i))) for i in range(2, 37)].
+ * Note that this is pessimistic if sizeof(long) > 4.
+ */
+#if SIZEOF_LONG == 4
+static int digitlimit[] = {
+	0,  0, 32, 20, 16, 13, 12, 11, 10, 10,  /*  0 -  9 */
+	9,  9,  8,  8,  8,  8,  8,  7,  7,  7,  /* 10 - 19 */
+	7,  7,  7,  7,  6,  6,  6,  6,  6,  6,  /* 20 - 29 */
+	6,  6,  6,  6,  6,  6,  6};             /* 30 - 36 */
+#elif SIZEOF_LONG == 8
+/* [int(math.floor(math.log(2**64, i))) for i in range(2, 37)] */
+static int digitlimit[] = {
+	 0,   0, 64, 40, 32, 27, 24, 22, 21, 20,  /*  0 -  9 */
+	19,  18, 17, 17, 16, 16, 16, 15, 15, 15,  /* 10 - 19 */
+	14,  14, 14, 14, 13, 13, 13, 13, 13, 13,  /* 20 - 29 */
+	13,  12, 12, 12, 12, 12, 12};             /* 30 - 36 */
+#else
+#error "Need table for SIZEOF_LONG"
+#endif
+
+/*
+**	strtoul
+**		This is a general purpose routine for converting
+**		an ascii string to an integer in an arbitrary base.
+**		Leading white space is ignored.  If 'base' is zero
+**		it looks for a leading 0, 0x or 0X to tell which
+**		base.  If these are absent it defaults to 10.
+**		Base must be 0 or between 2 and 36 (inclusive).
+**		If 'ptr' is non-NULL it will contain a pointer to
+**		the end of the scan.
+**		Errors due to bad pointers will probably result in
+**		exceptions - we don't check for them.
+*/
+unsigned long
+PyOS_strtoul(register char *str, char **ptr, int base)
+{
+	register unsigned long result = 0; /* return value of the function */
+	register int c;	 	/* current input character */
+	register int ovlimit; 	/* required digits to overflow */
+
+	/* skip leading white space */
+	while (*str && isspace(Py_CHARMASK(*str)))
+		++str;
+
+	/* check for leading 0 or 0x for auto-base or base 16 */
+	switch (base) {
+		case 0:		/* look for leading 0, 0x or 0X */
+			if (*str == '0') {
+				++str;
+				if (*str == 'x' || *str == 'X') {
+					++str;
+					base = 16;
+				}
+				else
+					base = 8;
+			}
+			else
+				base = 10;
+			break;
+
+		case 16:	/* skip leading 0x or 0X */
+			if (*str == '0') {
+				++str;
+				if (*str == 'x' || *str == 'X')
+					++str;
+			}
+			break;
+	}
+
+	/* catch silly bases */
+	if (base < 2 || base > 36) {
+		if (ptr)
+			*ptr = str;
+		return 0;
+	}
+
+	/* skip leading zeroes */
+	while (*str == '0')
+		++str;
+
+	/* base is guaranteed to be in [2, 36] at this point */
+	ovlimit = digitlimit[base];
+
+	/* do the conversion until non-digit character encountered */
+	while ((c = _PyLong_DigitValue[Py_CHARMASK(*str)]) < base) {
+		if (ovlimit > 0) /* no overflow check required */
+			result = result * base + c;
+		else { /* requires overflow check */
+			register unsigned long temp_result;
+
+			if (ovlimit < 0) /* guaranteed overflow */
+				goto overflowed;
+
+			/* there could be an overflow */
+			/* check overflow just from shifting */
+			if (result > smallmax[base])
+				goto overflowed;
+
+			result *= base;
+
+			/* check overflow from the digit's value */
+			temp_result = result + c;
+			if (temp_result < result)
+				goto overflowed;
+
+			result = temp_result;
+		}
+
+		++str;
+		--ovlimit;
+	}
+
+	/* set pointer to point to the last character scanned */
+	if (ptr)
+		*ptr = str;
+
+	return result;
+
+overflowed:
+	if (ptr) {
+		/* spool through remaining digit characters */
+		while (_PyLong_DigitValue[Py_CHARMASK(*str)] < base)
+			++str;
+		*ptr = str;
+	}
+	errno = ERANGE;
+	return (unsigned long)-1;
+}
+
+/* Checking for overflow in PyOS_strtol is a PITA; see comments
+ * about PY_ABS_LONG_MIN in longobject.c.
+ */
+#define PY_ABS_LONG_MIN		(0-(unsigned long)LONG_MIN)
+
+long
+PyOS_strtol(char *str, char **ptr, int base)
+{
+	long result;
+	unsigned long uresult;
+	char sign;
+
+	while (*str && isspace(Py_CHARMASK(*str)))
+		str++;
+
+	sign = *str;
+	if (sign == '+' || sign == '-')
+		str++;
+
+	uresult = PyOS_strtoul(str, ptr, base);
+
+	if (uresult <= (unsigned long)LONG_MAX) {
+		result = (long)uresult;
+		if (sign == '-')
+			result = -result;
+	}
+	else if (sign == '-' && uresult == PY_ABS_LONG_MIN) {
+		result = LONG_MIN;
+	}
+	else {
+		errno = ERANGE;
+		result = LONG_MAX;
+	}
+	return result;
+}

Added: vendor/Python/current/Python/pyarena.c
===================================================================
--- vendor/Python/current/Python/pyarena.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/pyarena.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,220 @@
+#include "Python.h"
+#include "pyarena.h"
+
+/* A simple arena block structure.
+
+   Measurements with standard library modules suggest the average
+   allocation is about 20 bytes and that most compiles use a single
+   block.
+
+   TODO(jhylton): Think about a realloc API, maybe just for the last
+   allocation?
+*/
+
+#define DEFAULT_BLOCK_SIZE 8192
+#define ALIGNMENT		8
+#define ALIGNMENT_MASK		(ALIGNMENT - 1)
+#define ROUNDUP(x)		(((x) + ALIGNMENT_MASK) & ~ALIGNMENT_MASK)
+
+typedef struct _block {
+	/* Total number of bytes owned by this block available to pass out.
+	 * Read-only after initialization.  The first such byte starts at
+	 * ab_mem.
+	 */
+	size_t ab_size;
+
+	/* Total number of bytes already passed out.  The next byte available
+	 * to pass out starts at ab_mem + ab_offset.
+	 */
+	size_t ab_offset;
+
+	/* An arena maintains a singly-linked, NULL-terminated list of
+	 * all blocks owned by the arena.  These are linked via the
+	 * ab_next member.
+	 */
+	struct _block *ab_next;
+
+	/* Pointer to the first allocatable byte owned by this block.  Read-
+	 * only after initialization.
+	 */
+	void *ab_mem;
+} block;
+
+/* The arena manages two kinds of memory, blocks of raw memory
+   and a list of PyObject* pointers.  PyObjects are decrefed
+   when the arena is freed.
+*/
+
+struct _arena {
+        /* Pointer to the first block allocated for the arena, never NULL.
+           It is used only to find the first block when the arena is
+           being freed.
+         */
+	block *a_head;
+
+        /* Pointer to the block currently used for allocation.  It's
+           ab_next field should be NULL.  If it is not-null after a
+           call to block_alloc(), it means a new block has been allocated
+           and a_cur should be reset to point it.
+         */
+	block *a_cur;
+
+        /* A Python list object containing references to all the PyObject
+           pointers associated with this area.  They will be DECREFed
+           when the arena is freed.
+        */
+        PyObject *a_objects;
+
+#if defined(Py_DEBUG)
+        /* Debug output */
+        size_t total_allocs;
+        size_t total_size;
+        size_t total_blocks;
+        size_t total_block_size;
+        size_t total_big_blocks;
+#endif
+};
+
+static block *
+block_new(size_t size)
+{
+	/* Allocate header and block as one unit.
+	   ab_mem points just past header. */
+	block *b = (block *)malloc(sizeof(block) + size);
+	if (!b)
+		return NULL;
+	b->ab_size = size;
+	b->ab_mem = (void *)(b + 1);
+	b->ab_next = NULL;
+	b->ab_offset = ROUNDUP((Py_uintptr_t)(b->ab_mem)) - 
+	  (Py_uintptr_t)(b->ab_mem);
+	return b;
+}
+
+static void
+block_free(block *b) {
+	while (b) {
+		block *next = b->ab_next;
+		free(b);
+		b = next;
+	}
+}
+
+static void *
+block_alloc(block *b, size_t size)
+{
+	void *p;
+	assert(b);
+	size = ROUNDUP(size);
+	if (b->ab_offset + size > b->ab_size) {
+		/* If we need to allocate more memory than will fit in
+		   the default block, allocate a one-off block that is
+		   exactly the right size. */
+		/* TODO(jhylton): Think about space waste at end of block */
+		block *newbl = block_new(
+				size < DEFAULT_BLOCK_SIZE ?
+				DEFAULT_BLOCK_SIZE : size);
+		if (!newbl)
+			return NULL;
+		assert(!b->ab_next);
+		b->ab_next = newbl;
+		b = newbl;
+	}
+
+	assert(b->ab_offset + size <= b->ab_size);
+	p = (void *)(((char *)b->ab_mem) + b->ab_offset);
+	b->ab_offset += size;
+	return p;
+}
+
+PyArena *
+PyArena_New()
+{
+	PyArena* arena = (PyArena *)malloc(sizeof(PyArena));
+	if (!arena)
+		return (PyArena*)PyErr_NoMemory();
+
+	arena->a_head = block_new(DEFAULT_BLOCK_SIZE);
+	arena->a_cur = arena->a_head;
+        if (!arena->a_head) {
+                free((void *)arena);
+                return (PyArena*)PyErr_NoMemory();
+        }
+        arena->a_objects = PyList_New(0);
+        if (!arena->a_objects) {
+                block_free(arena->a_head);
+                free((void *)arena);
+                return (PyArena*)PyErr_NoMemory();
+        }
+#if defined(Py_DEBUG)
+        arena->total_allocs = 0;
+        arena->total_size = 0;
+        arena->total_blocks = 1;
+        arena->total_block_size = DEFAULT_BLOCK_SIZE;
+        arena->total_big_blocks = 0;
+#endif
+	return arena;
+}
+
+void
+PyArena_Free(PyArena *arena)
+{
+        int r;
+	assert(arena);
+#if defined(Py_DEBUG)
+        /*
+        fprintf(stderr,
+                "alloc=%d size=%d blocks=%d block_size=%d big=%d objects=%d\n",
+                arena->total_allocs, arena->total_size, arena->total_blocks,
+                arena->total_block_size, arena->total_big_blocks,
+                PyList_Size(arena->a_objects));
+        */
+#endif
+	block_free(arena->a_head);
+	/* This property normally holds, except when the code being compiled
+	   is sys.getobjects(0), in which case there will be two references.
+        assert(arena->a_objects->ob_refcnt == 1);
+	*/
+
+        /* Clear all the elements from the list.  This is necessary
+           to guarantee that they will be DECREFed. */
+        r = PyList_SetSlice(arena->a_objects,
+                            0, PyList_GET_SIZE(arena->a_objects), NULL);
+        assert(r == 0);
+        assert(PyList_GET_SIZE(arena->a_objects) == 0);
+        Py_DECREF(arena->a_objects);
+	free(arena);
+}
+
+void *
+PyArena_Malloc(PyArena *arena, size_t size)
+{
+	void *p = block_alloc(arena->a_cur, size);
+	if (!p)
+		return PyErr_NoMemory();
+#if defined(Py_DEBUG)
+        arena->total_allocs++;
+        arena->total_size += size;
+#endif
+	/* Reset cur if we allocated a new block. */
+	if (arena->a_cur->ab_next) {
+		arena->a_cur = arena->a_cur->ab_next;
+#if defined(Py_DEBUG)
+                arena->total_blocks++;
+                arena->total_block_size += arena->a_cur->ab_size;
+                if (arena->a_cur->ab_size > DEFAULT_BLOCK_SIZE)
+                        ++arena->total_big_blocks;
+#endif
+	}
+	return p;
+}
+
+int
+PyArena_AddPyObject(PyArena *arena, PyObject *obj)
+{
+        int r = PyList_Append(arena->a_objects, obj);
+        if (r >= 0) {
+                Py_DECREF(obj);
+        }
+        return r;
+}

Added: vendor/Python/current/Python/pyfpe.c
===================================================================
--- vendor/Python/current/Python/pyfpe.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/pyfpe.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,23 @@
+#include "pyconfig.h"
+#include "pyfpe.h"
+/* 
+ * The signal handler for SIGFPE is actually declared in an external
+ * module fpectl, or as preferred by the user.  These variable
+ * definitions are required in order to compile Python without
+ * getting missing externals, but to actually handle SIGFPE requires
+ * defining a handler and enabling generation of SIGFPE.
+ */
+
+#ifdef WANT_SIGFPE_HANDLER
+jmp_buf PyFPE_jbuf;
+int PyFPE_counter = 0;
+#endif
+
+/* Have this outside the above #ifdef, since some picky ANSI compilers issue a 
+   warning when compiling an empty file. */
+
+double
+PyFPE_dummy(void *dummy)
+{
+	return 1.0;
+}

Added: vendor/Python/current/Python/pystate.c
===================================================================
--- vendor/Python/current/Python/pystate.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/pystate.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,632 @@
+
+/* Thread and interpreter state structures and their interfaces */
+
+#include "Python.h"
+
+/* --------------------------------------------------------------------------
+CAUTION
+
+Always use malloc() and free() directly in this file.  A number of these
+functions are advertised as safe to call when the GIL isn't held, and in
+a debug build Python redirects (e.g.) PyMem_NEW (etc) to Python's debugging
+obmalloc functions.  Those aren't thread-safe (they rely on the GIL to avoid
+the expense of doing their own locking).
+-------------------------------------------------------------------------- */
+
+#ifdef HAVE_DLOPEN
+#ifdef HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+#ifndef RTLD_LAZY
+#define RTLD_LAZY 1
+#endif
+#endif
+
+
+#ifdef WITH_THREAD
+#include "pythread.h"
+static PyThread_type_lock head_mutex = NULL; /* Protects interp->tstate_head */
+#define HEAD_INIT() (void)(head_mutex || (head_mutex = PyThread_allocate_lock()))
+#define HEAD_LOCK() PyThread_acquire_lock(head_mutex, WAIT_LOCK)
+#define HEAD_UNLOCK() PyThread_release_lock(head_mutex)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* The single PyInterpreterState used by this process'
+   GILState implementation
+*/
+static PyInterpreterState *autoInterpreterState = NULL;
+static int autoTLSkey = 0;
+#else
+#define HEAD_INIT() /* Nothing */
+#define HEAD_LOCK() /* Nothing */
+#define HEAD_UNLOCK() /* Nothing */
+#endif
+
+static PyInterpreterState *interp_head = NULL;
+
+PyThreadState *_PyThreadState_Current = NULL;
+PyThreadFrameGetter _PyThreadState_GetFrame = NULL;
+
+#ifdef WITH_THREAD
+static void _PyGILState_NoteThreadState(PyThreadState* tstate);
+#endif
+
+
+PyInterpreterState *
+PyInterpreterState_New(void)
+{
+	PyInterpreterState *interp = (PyInterpreterState *)
+				     malloc(sizeof(PyInterpreterState));
+
+	if (interp != NULL) {
+		HEAD_INIT();
+#ifdef WITH_THREAD
+		if (head_mutex == NULL)
+			Py_FatalError("Can't initialize threads for interpreter");
+#endif
+		interp->modules = NULL;
+		interp->modules_reloading = NULL;
+		interp->sysdict = NULL;
+		interp->builtins = NULL;
+		interp->tstate_head = NULL;
+		interp->codec_search_path = NULL;
+		interp->codec_search_cache = NULL;
+		interp->codec_error_registry = NULL;
+#ifdef HAVE_DLOPEN
+#ifdef RTLD_NOW
+                interp->dlopenflags = RTLD_NOW;
+#else
+		interp->dlopenflags = RTLD_LAZY;
+#endif
+#endif
+#ifdef WITH_TSC
+		interp->tscdump = 0;
+#endif
+
+		HEAD_LOCK();
+		interp->next = interp_head;
+		interp_head = interp;
+		HEAD_UNLOCK();
+	}
+
+	return interp;
+}
+
+
+void
+PyInterpreterState_Clear(PyInterpreterState *interp)
+{
+	PyThreadState *p;
+	HEAD_LOCK();
+	for (p = interp->tstate_head; p != NULL; p = p->next)
+		PyThreadState_Clear(p);
+	HEAD_UNLOCK();
+	Py_CLEAR(interp->codec_search_path);
+	Py_CLEAR(interp->codec_search_cache);
+	Py_CLEAR(interp->codec_error_registry);
+	Py_CLEAR(interp->modules);
+	Py_CLEAR(interp->modules_reloading);
+	Py_CLEAR(interp->sysdict);
+	Py_CLEAR(interp->builtins);
+}
+
+
+static void
+zapthreads(PyInterpreterState *interp)
+{
+	PyThreadState *p;
+	/* No need to lock the mutex here because this should only happen
+	   when the threads are all really dead (XXX famous last words). */
+	while ((p = interp->tstate_head) != NULL) {
+		PyThreadState_Delete(p);
+	}
+}
+
+
+void
+PyInterpreterState_Delete(PyInterpreterState *interp)
+{
+	PyInterpreterState **p;
+	zapthreads(interp);
+	HEAD_LOCK();
+	for (p = &interp_head; ; p = &(*p)->next) {
+		if (*p == NULL)
+			Py_FatalError(
+				"PyInterpreterState_Delete: invalid interp");
+		if (*p == interp)
+			break;
+	}
+	if (interp->tstate_head != NULL)
+		Py_FatalError("PyInterpreterState_Delete: remaining threads");
+	*p = interp->next;
+	HEAD_UNLOCK();
+	free(interp);
+}
+
+
+/* Default implementation for _PyThreadState_GetFrame */
+static struct _frame *
+threadstate_getframe(PyThreadState *self)
+{
+	return self->frame;
+}
+
+PyThreadState *
+PyThreadState_New(PyInterpreterState *interp)
+{
+	PyThreadState *tstate = (PyThreadState *)malloc(sizeof(PyThreadState));
+
+	if (_PyThreadState_GetFrame == NULL)
+		_PyThreadState_GetFrame = threadstate_getframe;
+
+	if (tstate != NULL) {
+		tstate->interp = interp;
+
+		tstate->frame = NULL;
+		tstate->recursion_depth = 0;
+		tstate->tracing = 0;
+		tstate->use_tracing = 0;
+		tstate->tick_counter = 0;
+		tstate->gilstate_counter = 0;
+		tstate->async_exc = NULL;
+#ifdef WITH_THREAD
+		tstate->thread_id = PyThread_get_thread_ident();
+#else
+		tstate->thread_id = 0;
+#endif
+
+		tstate->dict = NULL;
+
+		tstate->curexc_type = NULL;
+		tstate->curexc_value = NULL;
+		tstate->curexc_traceback = NULL;
+
+		tstate->exc_type = NULL;
+		tstate->exc_value = NULL;
+		tstate->exc_traceback = NULL;
+
+		tstate->c_profilefunc = NULL;
+		tstate->c_tracefunc = NULL;
+		tstate->c_profileobj = NULL;
+		tstate->c_traceobj = NULL;
+
+#ifdef WITH_THREAD
+		_PyGILState_NoteThreadState(tstate);
+#endif
+
+		HEAD_LOCK();
+		tstate->next = interp->tstate_head;
+		interp->tstate_head = tstate;
+		HEAD_UNLOCK();
+	}
+
+	return tstate;
+}
+
+
+void
+PyThreadState_Clear(PyThreadState *tstate)
+{
+	if (Py_VerboseFlag && tstate->frame != NULL)
+		fprintf(stderr,
+		  "PyThreadState_Clear: warning: thread still has a frame\n");
+
+	Py_CLEAR(tstate->frame);
+
+	Py_CLEAR(tstate->dict);
+	Py_CLEAR(tstate->async_exc);
+
+	Py_CLEAR(tstate->curexc_type);
+	Py_CLEAR(tstate->curexc_value);
+	Py_CLEAR(tstate->curexc_traceback);
+
+	Py_CLEAR(tstate->exc_type);
+	Py_CLEAR(tstate->exc_value);
+	Py_CLEAR(tstate->exc_traceback);
+
+	tstate->c_profilefunc = NULL;
+	tstate->c_tracefunc = NULL;
+	Py_CLEAR(tstate->c_profileobj);
+	Py_CLEAR(tstate->c_traceobj);
+}
+
+
+/* Common code for PyThreadState_Delete() and PyThreadState_DeleteCurrent() */
+static void
+tstate_delete_common(PyThreadState *tstate)
+{
+	PyInterpreterState *interp;
+	PyThreadState **p;
+	if (tstate == NULL)
+		Py_FatalError("PyThreadState_Delete: NULL tstate");
+	interp = tstate->interp;
+	if (interp == NULL)
+		Py_FatalError("PyThreadState_Delete: NULL interp");
+	HEAD_LOCK();
+	for (p = &interp->tstate_head; ; p = &(*p)->next) {
+		if (*p == NULL)
+			Py_FatalError(
+				"PyThreadState_Delete: invalid tstate");
+		if (*p == tstate)
+			break;
+	}
+	*p = tstate->next;
+	HEAD_UNLOCK();
+	free(tstate);
+}
+
+
+void
+PyThreadState_Delete(PyThreadState *tstate)
+{
+	if (tstate == _PyThreadState_Current)
+		Py_FatalError("PyThreadState_Delete: tstate is still current");
+	tstate_delete_common(tstate);
+#ifdef WITH_THREAD
+	if (autoTLSkey && PyThread_get_key_value(autoTLSkey) == tstate)
+		PyThread_delete_key_value(autoTLSkey);
+#endif /* WITH_THREAD */
+}
+
+
+#ifdef WITH_THREAD
+void
+PyThreadState_DeleteCurrent()
+{
+	PyThreadState *tstate = _PyThreadState_Current;
+	if (tstate == NULL)
+		Py_FatalError(
+			"PyThreadState_DeleteCurrent: no current tstate");
+	_PyThreadState_Current = NULL;
+	tstate_delete_common(tstate);
+	if (autoTLSkey && PyThread_get_key_value(autoTLSkey) == tstate)
+		PyThread_delete_key_value(autoTLSkey);
+	PyEval_ReleaseLock();
+}
+#endif /* WITH_THREAD */
+
+
+PyThreadState *
+PyThreadState_Get(void)
+{
+	if (_PyThreadState_Current == NULL)
+		Py_FatalError("PyThreadState_Get: no current thread");
+
+	return _PyThreadState_Current;
+}
+
+
+PyThreadState *
+PyThreadState_Swap(PyThreadState *newts)
+{
+	PyThreadState *oldts = _PyThreadState_Current;
+
+	_PyThreadState_Current = newts;
+	/* It should not be possible for more than one thread state
+	   to be used for a thread.  Check this the best we can in debug
+	   builds.
+	*/
+#if defined(Py_DEBUG) && defined(WITH_THREAD)
+	if (newts) {
+		/* This can be called from PyEval_RestoreThread(). Similar
+		   to it, we need to ensure errno doesn't change.
+		*/
+		int err = errno;
+		PyThreadState *check = PyGILState_GetThisThreadState();
+		if (check && check->interp == newts->interp && check != newts)
+			Py_FatalError("Invalid thread state for this thread");
+		errno = err;
+	}
+#endif
+	return oldts;
+}
+
+/* An extension mechanism to store arbitrary additional per-thread state.
+   PyThreadState_GetDict() returns a dictionary that can be used to hold such
+   state; the caller should pick a unique key and store its state there.  If
+   PyThreadState_GetDict() returns NULL, an exception has *not* been raised
+   and the caller should assume no per-thread state is available. */
+
+PyObject *
+PyThreadState_GetDict(void)
+{
+	if (_PyThreadState_Current == NULL)
+		return NULL;
+
+	if (_PyThreadState_Current->dict == NULL) {
+		PyObject *d;
+		_PyThreadState_Current->dict = d = PyDict_New();
+		if (d == NULL)
+			PyErr_Clear();
+	}
+	return _PyThreadState_Current->dict;
+}
+
+
+/* Asynchronously raise an exception in a thread.
+   Requested by Just van Rossum and Alex Martelli.
+   To prevent naive misuse, you must write your own extension
+   to call this, or use ctypes.  Must be called with the GIL held.
+   Returns the number of tstates modified (normally 1, but 0 if `id` didn't
+   match any known thread id).  Can be called with exc=NULL to clear an
+   existing async exception.  This raises no exceptions. */
+
+int
+PyThreadState_SetAsyncExc(long id, PyObject *exc) {
+	PyThreadState *tstate = PyThreadState_GET();
+	PyInterpreterState *interp = tstate->interp;
+	PyThreadState *p;
+
+	/* Although the GIL is held, a few C API functions can be called
+	 * without the GIL held, and in particular some that create and
+	 * destroy thread and interpreter states.  Those can mutate the
+	 * list of thread states we're traversing, so to prevent that we lock
+	 * head_mutex for the duration.
+	 */
+	HEAD_LOCK();
+	for (p = interp->tstate_head; p != NULL; p = p->next) {
+		if (p->thread_id == id) {
+			/* Tricky:  we need to decref the current value
+			 * (if any) in p->async_exc, but that can in turn
+			 * allow arbitrary Python code to run, including
+			 * perhaps calls to this function.  To prevent
+			 * deadlock, we need to release head_mutex before
+			 * the decref.
+			 */
+			PyObject *old_exc = p->async_exc;
+			Py_XINCREF(exc);
+			p->async_exc = exc;
+			HEAD_UNLOCK();
+			Py_XDECREF(old_exc);
+			return 1;
+		}
+	}
+	HEAD_UNLOCK();
+	return 0;
+}
+
+
+/* Routines for advanced debuggers, requested by David Beazley.
+   Don't use unless you know what you are doing! */
+
+PyInterpreterState *
+PyInterpreterState_Head(void)
+{
+	return interp_head;
+}
+
+PyInterpreterState *
+PyInterpreterState_Next(PyInterpreterState *interp) {
+	return interp->next;
+}
+
+PyThreadState *
+PyInterpreterState_ThreadHead(PyInterpreterState *interp) {
+	return interp->tstate_head;
+}
+
+PyThreadState *
+PyThreadState_Next(PyThreadState *tstate) {
+	return tstate->next;
+}
+
+/* The implementation of sys._current_frames().  This is intended to be
+   called with the GIL held, as it will be when called via
+   sys._current_frames().  It's possible it would work fine even without
+   the GIL held, but haven't thought enough about that.
+*/
+PyObject *
+_PyThread_CurrentFrames(void)
+{
+	PyObject *result;
+	PyInterpreterState *i;
+
+	result = PyDict_New();
+	if (result == NULL)
+		return NULL;
+
+	/* for i in all interpreters:
+	 *     for t in all of i's thread states:
+	 *          if t's frame isn't NULL, map t's id to its frame
+	 * Because these lists can mutute even when the GIL is held, we
+	 * need to grab head_mutex for the duration.
+	 */
+	HEAD_LOCK();
+	for (i = interp_head; i != NULL; i = i->next) {
+		PyThreadState *t;
+		for (t = i->tstate_head; t != NULL; t = t->next) {
+			PyObject *id;
+			int stat;
+			struct _frame *frame = t->frame;
+			if (frame == NULL)
+				continue;
+			id = PyInt_FromLong(t->thread_id);
+			if (id == NULL)
+				goto Fail;
+			stat = PyDict_SetItem(result, id, (PyObject *)frame);
+			Py_DECREF(id);
+			if (stat < 0)
+				goto Fail;
+		}
+	}
+	HEAD_UNLOCK();
+	return result;
+
+ Fail:
+ 	HEAD_UNLOCK();
+ 	Py_DECREF(result);
+ 	return NULL;
+}
+
+/* Python "auto thread state" API. */
+#ifdef WITH_THREAD
+
+/* Keep this as a static, as it is not reliable!  It can only
+   ever be compared to the state for the *current* thread.
+   * If not equal, then it doesn't matter that the actual
+     value may change immediately after comparison, as it can't
+     possibly change to the current thread's state.
+   * If equal, then the current thread holds the lock, so the value can't
+     change until we yield the lock.
+*/
+static int
+PyThreadState_IsCurrent(PyThreadState *tstate)
+{
+	/* Must be the tstate for this thread */
+	assert(PyGILState_GetThisThreadState()==tstate);
+	/* On Windows at least, simple reads and writes to 32 bit values
+	   are atomic.
+	*/
+	return tstate == _PyThreadState_Current;
+}
+
+/* Internal initialization/finalization functions called by
+   Py_Initialize/Py_Finalize
+*/
+void
+_PyGILState_Init(PyInterpreterState *i, PyThreadState *t)
+{
+	assert(i && t); /* must init with valid states */
+	autoTLSkey = PyThread_create_key();
+	autoInterpreterState = i;
+	assert(PyThread_get_key_value(autoTLSkey) == NULL);
+	assert(t->gilstate_counter == 0);
+
+	_PyGILState_NoteThreadState(t);
+}
+
+void
+_PyGILState_Fini(void)
+{
+	PyThread_delete_key(autoTLSkey);
+	autoTLSkey = 0;
+	autoInterpreterState = NULL;
+}
+
+/* When a thread state is created for a thread by some mechanism other than
+   PyGILState_Ensure, it's important that the GILState machinery knows about
+   it so it doesn't try to create another thread state for the thread (this is
+   a better fix for SF bug #1010677 than the first one attempted).
+*/
+static void
+_PyGILState_NoteThreadState(PyThreadState* tstate)
+{
+	/* If autoTLSkey is 0, this must be the very first threadstate created
+	   in Py_Initialize().  Don't do anything for now (we'll be back here
+	   when _PyGILState_Init is called). */
+	if (!autoTLSkey)
+		return;
+
+	/* Stick the thread state for this thread in thread local storage.
+
+	   The only situation where you can legitimately have more than one
+	   thread state for an OS level thread is when there are multiple
+	   interpreters, when:
+
+	       a) You shouldn't really be using the PyGILState_ APIs anyway,
+	          and:
+
+	       b) The slightly odd way PyThread_set_key_value works (see
+	          comments by its implementation) means that the first thread
+	          state created for that given OS level thread will "win",
+	          which seems reasonable behaviour.
+	*/
+	if (PyThread_set_key_value(autoTLSkey, (void *)tstate) < 0)
+		Py_FatalError("Couldn't create autoTLSkey mapping");
+
+	/* PyGILState_Release must not try to delete this thread state. */
+	tstate->gilstate_counter = 1;
+}
+
+/* The public functions */
+PyThreadState *
+PyGILState_GetThisThreadState(void)
+{
+	if (autoInterpreterState == NULL || autoTLSkey == 0)
+		return NULL;
+	return (PyThreadState *)PyThread_get_key_value(autoTLSkey);
+}
+
+PyGILState_STATE
+PyGILState_Ensure(void)
+{
+	int current;
+	PyThreadState *tcur;
+	/* Note that we do not auto-init Python here - apart from
+	   potential races with 2 threads auto-initializing, pep-311
+	   spells out other issues.  Embedders are expected to have
+	   called Py_Initialize() and usually PyEval_InitThreads().
+	*/
+	assert(autoInterpreterState); /* Py_Initialize() hasn't been called! */
+	tcur = (PyThreadState *)PyThread_get_key_value(autoTLSkey);
+	if (tcur == NULL) {
+		/* Create a new thread state for this thread */
+		tcur = PyThreadState_New(autoInterpreterState);
+		if (tcur == NULL)
+			Py_FatalError("Couldn't create thread-state for new thread");
+		/* This is our thread state!  We'll need to delete it in the
+		   matching call to PyGILState_Release(). */
+		tcur->gilstate_counter = 0;
+		current = 0; /* new thread state is never current */
+	}
+	else
+		current = PyThreadState_IsCurrent(tcur);
+	if (current == 0)
+		PyEval_RestoreThread(tcur);
+	/* Update our counter in the thread-state - no need for locks:
+	   - tcur will remain valid as we hold the GIL.
+	   - the counter is safe as we are the only thread "allowed"
+	     to modify this value
+	*/
+	++tcur->gilstate_counter;
+	return current ? PyGILState_LOCKED : PyGILState_UNLOCKED;
+}
+
+void
+PyGILState_Release(PyGILState_STATE oldstate)
+{
+	PyThreadState *tcur = (PyThreadState *)PyThread_get_key_value(
+                                                                autoTLSkey);
+	if (tcur == NULL)
+		Py_FatalError("auto-releasing thread-state, "
+		              "but no thread-state for this thread");
+	/* We must hold the GIL and have our thread state current */
+	/* XXX - remove the check - the assert should be fine,
+	   but while this is very new (April 2003), the extra check
+	   by release-only users can't hurt.
+	*/
+	if (! PyThreadState_IsCurrent(tcur))
+		Py_FatalError("This thread state must be current when releasing");
+	assert(PyThreadState_IsCurrent(tcur));
+	--tcur->gilstate_counter;
+	assert(tcur->gilstate_counter >= 0); /* illegal counter value */
+
+	/* If we're going to destroy this thread-state, we must
+	 * clear it while the GIL is held, as destructors may run.
+	 */
+	if (tcur->gilstate_counter == 0) {
+		/* can't have been locked when we created it */
+		assert(oldstate == PyGILState_UNLOCKED);
+		PyThreadState_Clear(tcur);
+		/* Delete the thread-state.  Note this releases the GIL too!
+		 * It's vital that the GIL be held here, to avoid shutdown
+		 * races; see bugs 225673 and 1061968 (that nasty bug has a
+		 * habit of coming back).
+		 */
+		PyThreadState_DeleteCurrent();
+	}
+	/* Release the lock if necessary */
+	else if (oldstate == PyGILState_UNLOCKED)
+		PyEval_SaveThread();
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* WITH_THREAD */
+
+

Added: vendor/Python/current/Python/pystrtod.c
===================================================================
--- vendor/Python/current/Python/pystrtod.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/pystrtod.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,248 @@
+/* -*- Mode: C; c-file-style: "python" -*- */
+
+#include <Python.h>
+#include <locale.h>
+
+/* ascii character tests (as opposed to locale tests) */
+#define ISSPACE(c)  ((c) == ' ' || (c) == '\f' || (c) == '\n' || \
+                     (c) == '\r' || (c) == '\t' || (c) == '\v')
+#define ISDIGIT(c)  ((c) >= '0' && (c) <= '9')
+#define ISXDIGIT(c) (ISDIGIT(c) || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F'))
+
+
+/**
+ * PyOS_ascii_strtod:
+ * @nptr:    the string to convert to a numeric value.
+ * @endptr:  if non-%NULL, it returns the character after
+ *           the last character used in the conversion.
+ * 
+ * Converts a string to a #gdouble value.
+ * This function behaves like the standard strtod() function
+ * does in the C locale. It does this without actually
+ * changing the current locale, since that would not be
+ * thread-safe.
+ *
+ * This function is typically used when reading configuration
+ * files or other non-user input that should be locale independent.
+ * To handle input from the user you should normally use the
+ * locale-sensitive system strtod() function.
+ *
+ * If the correct value would cause overflow, plus or minus %HUGE_VAL
+ * is returned (according to the sign of the value), and %ERANGE is
+ * stored in %errno. If the correct value would cause underflow,
+ * zero is returned and %ERANGE is stored in %errno.
+ * If memory allocation fails, %ENOMEM is stored in %errno.
+ * 
+ * This function resets %errno before calling strtod() so that
+ * you can reliably detect overflow and underflow.
+ *
+ * Return value: the #gdouble value.
+ **/
+double
+PyOS_ascii_strtod(const char *nptr, char **endptr)
+{
+	char *fail_pos;
+	double val = -1.0;
+	struct lconv *locale_data;
+	const char *decimal_point;
+	size_t decimal_point_len;
+	const char *p, *decimal_point_pos;
+	const char *end = NULL; /* Silence gcc */
+
+	assert(nptr != NULL);
+
+	fail_pos = NULL;
+
+	locale_data = localeconv();
+	decimal_point = locale_data->decimal_point;
+	decimal_point_len = strlen(decimal_point);
+
+	assert(decimal_point_len != 0);
+
+	decimal_point_pos = NULL;
+	if (decimal_point[0] != '.' || 
+	    decimal_point[1] != 0)
+	{
+		p = nptr;
+		  /* Skip leading space */
+		while (ISSPACE(*p))
+			p++;
+
+		  /* Skip leading optional sign */
+		if (*p == '+' || *p == '-')
+			p++;
+
+		while (ISDIGIT(*p))
+			p++;
+
+		if (*p == '.')
+		{
+			decimal_point_pos = p++;
+
+			while (ISDIGIT(*p))
+				p++;
+
+			if (*p == 'e' || *p == 'E')
+				p++;
+			if (*p == '+' || *p == '-')
+				p++;
+			while (ISDIGIT(*p))
+				p++;
+			end = p;
+		}
+		else if (strncmp(p, decimal_point, decimal_point_len) == 0)
+		{
+			/* Python bug #1417699 */
+			*endptr = (char*)nptr;
+			errno = EINVAL;
+			return val;
+		}
+		/* For the other cases, we need not convert the decimal point */
+	}
+
+	/* Set errno to zero, so that we can distinguish zero results
+	   and underflows */
+	errno = 0;
+
+	if (decimal_point_pos)
+	{
+		char *copy, *c;
+
+		/* We need to convert the '.' to the locale specific decimal point */
+		copy = (char *)PyMem_MALLOC(end - nptr + 1 + decimal_point_len);
+		if (copy == NULL) {
+			if (endptr)
+				*endptr = (char *)nptr;
+			errno = ENOMEM;
+			return val;
+		}
+
+		c = copy;
+		memcpy(c, nptr, decimal_point_pos - nptr);
+		c += decimal_point_pos - nptr;
+		memcpy(c, decimal_point, decimal_point_len);
+		c += decimal_point_len;
+		memcpy(c, decimal_point_pos + 1, end - (decimal_point_pos + 1));
+		c += end - (decimal_point_pos + 1);
+		*c = 0;
+
+		val = strtod(copy, &fail_pos);
+
+		if (fail_pos)
+		{
+			if (fail_pos > decimal_point_pos)
+				fail_pos = (char *)nptr + (fail_pos - copy) - (decimal_point_len - 1);
+			else
+				fail_pos = (char *)nptr + (fail_pos - copy);
+		}
+
+		PyMem_FREE(copy);
+
+	}
+	else {
+		unsigned i = 0;
+		if (nptr[i] == '-')
+			i++;
+		if (nptr[i] == '0' && (nptr[i+1] == 'x' || nptr[i+1] == 'X'))
+			fail_pos = (char*)nptr;
+		else
+			val = strtod(nptr, &fail_pos);
+	}
+
+	if (endptr)
+		*endptr = fail_pos;
+
+	return val;
+}
+
+
+/**
+ * PyOS_ascii_formatd:
+ * @buffer: A buffer to place the resulting string in
+ * @buf_len: The length of the buffer.
+ * @format: The printf()-style format to use for the
+ *          code to use for converting. 
+ * @d: The #gdouble to convert
+ *
+ * Converts a #gdouble to a string, using the '.' as
+ * decimal point. To format the number you pass in
+ * a printf()-style format string. Allowed conversion
+ * specifiers are 'e', 'E', 'f', 'F', 'g' and 'G'. 
+ * 
+ * Return value: The pointer to the buffer with the converted string.
+ **/
+char *
+PyOS_ascii_formatd(char       *buffer, 
+		   size_t      buf_len, 
+		   const char *format, 
+		   double      d)
+{
+	struct lconv *locale_data;
+	const char *decimal_point;
+	size_t decimal_point_len, rest_len;
+	char *p;
+	char format_char;
+
+/* 	g_return_val_if_fail (buffer != NULL, NULL); */
+/* 	g_return_val_if_fail (format[0] == '%', NULL); */
+/* 	g_return_val_if_fail (strpbrk (format + 1, "'l%") == NULL, NULL); */
+
+	format_char = format[strlen(format) - 1];
+
+/* 	g_return_val_if_fail (format_char == 'e' || format_char == 'E' || */
+/* 			      format_char == 'f' || format_char == 'F' || */
+/* 			      format_char == 'g' || format_char == 'G', */
+/* 			      NULL); */
+
+	if (format[0] != '%')
+		return NULL;
+
+	if (strpbrk(format + 1, "'l%"))
+		return NULL;
+
+	if (!(format_char == 'e' || format_char == 'E' || 
+	      format_char == 'f' || format_char == 'F' || 
+	      format_char == 'g' || format_char == 'G'))
+		return NULL;
+
+
+	PyOS_snprintf(buffer, buf_len, format, d);
+
+	locale_data = localeconv();
+	decimal_point = locale_data->decimal_point;
+	decimal_point_len = strlen(decimal_point);
+
+	assert(decimal_point_len != 0);
+
+	if (decimal_point[0] != '.' || 
+	    decimal_point[1] != 0)
+	{
+		p = buffer;
+
+		if (*p == '+' || *p == '-')
+			p++;
+
+		while (isdigit((unsigned char)*p))
+			p++;
+
+		if (strncmp(p, decimal_point, decimal_point_len) == 0)
+		{
+			*p = '.';
+			p++;
+			if (decimal_point_len > 1) {
+				rest_len = strlen(p + (decimal_point_len - 1));
+				memmove(p, p + (decimal_point_len - 1), 
+					rest_len);
+				p[rest_len] = 0;
+			}
+		}
+	}
+
+	return buffer;
+}
+
+double
+PyOS_ascii_atof(const char *nptr)
+{
+	return PyOS_ascii_strtod(nptr, NULL);
+}

Added: vendor/Python/current/Python/pythonrun.c
===================================================================
--- vendor/Python/current/Python/pythonrun.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/pythonrun.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1857 @@
+
+/* Python interpreter top-level routines, including init/exit */
+
+#include "Python.h"
+
+#include "Python-ast.h"
+#include "grammar.h"
+#include "node.h"
+#include "token.h"
+#include "parsetok.h"
+#include "errcode.h"
+#include "code.h"
+#include "compile.h"
+#include "symtable.h"
+#include "pyarena.h"
+#include "ast.h"
+#include "eval.h"
+#include "marshal.h"
+
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+
+#ifdef HAVE_LANGINFO_H
+#include <locale.h>
+#include <langinfo.h>
+#endif
+
+#ifdef MS_WINDOWS
+#undef BYTE
+#include "windows.h"
+#endif
+
+#ifndef Py_REF_DEBUG
+#define PRINT_TOTAL_REFS()
+#else /* Py_REF_DEBUG */
+#define PRINT_TOTAL_REFS() fprintf(stderr,				\
+				   "[%" PY_FORMAT_SIZE_T "d refs]\n",	\
+				   _Py_GetRefTotal())
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern char *Py_GetPath(void);
+
+extern grammar _PyParser_Grammar; /* From graminit.c */
+
+/* Forward */
+static void initmain(void);
+static void initsite(void);
+static PyObject *run_mod(mod_ty, const char *, PyObject *, PyObject *,
+			  PyCompilerFlags *, PyArena *);
+static PyObject *run_pyc_file(FILE *, const char *, PyObject *, PyObject *,
+			      PyCompilerFlags *);
+static void err_input(perrdetail *);
+static void initsigs(void);
+static void call_sys_exitfunc(void);
+static void call_ll_exitfuncs(void);
+extern void _PyUnicode_Init(void);
+extern void _PyUnicode_Fini(void);
+
+#ifdef WITH_THREAD
+extern void _PyGILState_Init(PyInterpreterState *, PyThreadState *);
+extern void _PyGILState_Fini(void);
+#endif /* WITH_THREAD */
+
+int Py_DebugFlag; /* Needed by parser.c */
+int Py_VerboseFlag; /* Needed by import.c */
+int Py_InteractiveFlag; /* Needed by Py_FdIsInteractive() below */
+int Py_NoSiteFlag; /* Suppress 'import site' */
+int Py_UseClassExceptionsFlag = 1; /* Needed by bltinmodule.c: deprecated */
+int Py_FrozenFlag; /* Needed by getpath.c */
+int Py_UnicodeFlag = 0; /* Needed by compile.c */
+int Py_IgnoreEnvironmentFlag; /* e.g. PYTHONPATH, PYTHONHOME */
+/* _XXX Py_QnewFlag should go away in 2.3.  It's true iff -Qnew is passed,
+  on the command line, and is used in 2.2 by ceval.c to make all "/" divisions
+  true divisions (which they will be in 2.3). */
+int _Py_QnewFlag = 0;
+
+/* Reference to 'warnings' module, to avoid importing it
+   on the fly when the import lock may be held.  See 683658/771097
+*/
+static PyObject *warnings_module = NULL;
+
+/* Returns a borrowed reference to the 'warnings' module, or NULL.
+   If the module is returned, it is guaranteed to have been obtained
+   without acquiring the import lock
+*/
+PyObject *PyModule_GetWarningsModule(void)
+{
+	PyObject *typ, *val, *tb;
+	PyObject *all_modules;
+	/* If we managed to get the module at init time, just use it */
+	if (warnings_module)
+		return warnings_module;
+	/* If it wasn't available at init time, it may be available
+	   now in sys.modules (common scenario is frozen apps: import
+	   at init time fails, but the frozen init code sets up sys.path
+	   correctly, then does an implicit import of warnings for us
+	*/
+	/* Save and restore any exceptions */
+	PyErr_Fetch(&typ, &val, &tb);
+
+	all_modules = PySys_GetObject("modules");
+	if (all_modules) {
+		warnings_module = PyDict_GetItemString(all_modules, "warnings");
+		/* We keep a ref in the global */
+		Py_XINCREF(warnings_module);
+	}
+	PyErr_Restore(typ, val, tb);
+	return warnings_module;
+}
+
+static int initialized = 0;
+
+/* API to access the initialized flag -- useful for esoteric use */
+
+int
+Py_IsInitialized(void)
+{
+	return initialized;
+}
+
+/* Global initializations.  Can be undone by Py_Finalize().  Don't
+   call this twice without an intervening Py_Finalize() call.  When
+   initializations fail, a fatal error is issued and the function does
+   not return.  On return, the first thread and interpreter state have
+   been created.
+
+   Locking: you must hold the interpreter lock while calling this.
+   (If the lock has not yet been initialized, that's equivalent to
+   having the lock, but you cannot use multiple threads.)
+
+*/
+
+static int
+add_flag(int flag, const char *envs)
+{
+	int env = atoi(envs);
+	if (flag < env)
+		flag = env;
+	if (flag < 1)
+		flag = 1;
+	return flag;
+}
+
+void
+Py_InitializeEx(int install_sigs)
+{
+	PyInterpreterState *interp;
+	PyThreadState *tstate;
+	PyObject *bimod, *sysmod;
+	char *p;
+#if defined(Py_USING_UNICODE) && defined(HAVE_LANGINFO_H) && defined(CODESET)
+	char *codeset;
+	char *saved_locale;
+	PyObject *sys_stream, *sys_isatty;
+#endif
+	extern void _Py_ReadyTypes(void);
+
+	if (initialized)
+		return;
+	initialized = 1;
+
+	if ((p = Py_GETENV("PYTHONDEBUG")) && *p != '\0')
+		Py_DebugFlag = add_flag(Py_DebugFlag, p);
+	if ((p = Py_GETENV("PYTHONVERBOSE")) && *p != '\0')
+		Py_VerboseFlag = add_flag(Py_VerboseFlag, p);
+	if ((p = Py_GETENV("PYTHONOPTIMIZE")) && *p != '\0')
+		Py_OptimizeFlag = add_flag(Py_OptimizeFlag, p);
+
+	interp = PyInterpreterState_New();
+	if (interp == NULL)
+		Py_FatalError("Py_Initialize: can't make first interpreter");
+
+	tstate = PyThreadState_New(interp);
+	if (tstate == NULL)
+		Py_FatalError("Py_Initialize: can't make first thread");
+	(void) PyThreadState_Swap(tstate);
+
+	_Py_ReadyTypes();
+
+	if (!_PyFrame_Init())
+		Py_FatalError("Py_Initialize: can't init frames");
+
+	if (!_PyInt_Init())
+		Py_FatalError("Py_Initialize: can't init ints");
+
+	_PyFloat_Init();
+
+	interp->modules = PyDict_New();
+	if (interp->modules == NULL)
+		Py_FatalError("Py_Initialize: can't make modules dictionary");
+	interp->modules_reloading = PyDict_New();
+	if (interp->modules_reloading == NULL)
+		Py_FatalError("Py_Initialize: can't make modules_reloading dictionary");
+
+#ifdef Py_USING_UNICODE
+	/* Init Unicode implementation; relies on the codec registry */
+	_PyUnicode_Init();
+#endif
+
+	bimod = _PyBuiltin_Init();
+	if (bimod == NULL)
+		Py_FatalError("Py_Initialize: can't initialize __builtin__");
+	interp->builtins = PyModule_GetDict(bimod);
+	if (interp->builtins == NULL)
+		Py_FatalError("Py_Initialize: can't initialize builtins dict");
+	Py_INCREF(interp->builtins);
+
+	sysmod = _PySys_Init();
+	if (sysmod == NULL)
+		Py_FatalError("Py_Initialize: can't initialize sys");
+	interp->sysdict = PyModule_GetDict(sysmod);
+	if (interp->sysdict == NULL)
+		Py_FatalError("Py_Initialize: can't initialize sys dict");
+	Py_INCREF(interp->sysdict);
+	_PyImport_FixupExtension("sys", "sys");
+	PySys_SetPath(Py_GetPath());
+	PyDict_SetItemString(interp->sysdict, "modules",
+			     interp->modules);
+
+	_PyImport_Init();
+
+	/* initialize builtin exceptions */
+	_PyExc_Init();
+	_PyImport_FixupExtension("exceptions", "exceptions");
+
+	/* phase 2 of builtins */
+	_PyImport_FixupExtension("__builtin__", "__builtin__");
+
+	_PyImportHooks_Init();
+
+	if (install_sigs)
+		initsigs(); /* Signal handling stuff, including initintr() */
+
+	initmain(); /* Module __main__ */
+	if (!Py_NoSiteFlag)
+		initsite(); /* Module site */
+
+	/* auto-thread-state API, if available */
+#ifdef WITH_THREAD
+	_PyGILState_Init(interp, tstate);
+#endif /* WITH_THREAD */
+
+	warnings_module = PyImport_ImportModule("warnings");
+	if (!warnings_module)
+		PyErr_Clear();
+
+#if defined(Py_USING_UNICODE) && defined(HAVE_LANGINFO_H) && defined(CODESET)
+	/* On Unix, set the file system encoding according to the
+	   user's preference, if the CODESET names a well-known
+	   Python codec, and Py_FileSystemDefaultEncoding isn't
+	   initialized by other means. Also set the encoding of
+	   stdin and stdout if these are terminals.  */
+
+	saved_locale = strdup(setlocale(LC_CTYPE, NULL));
+	setlocale(LC_CTYPE, "");
+	codeset = nl_langinfo(CODESET);
+	if (codeset && *codeset) {
+		PyObject *enc = PyCodec_Encoder(codeset);
+		if (enc) {
+			codeset = strdup(codeset);
+			Py_DECREF(enc);
+		} else {
+			codeset = NULL;
+			PyErr_Clear();
+		}
+	} else
+		codeset = NULL;
+	setlocale(LC_CTYPE, saved_locale);
+	free(saved_locale);
+
+	if (codeset) {
+		sys_stream = PySys_GetObject("stdin");
+		sys_isatty = PyObject_CallMethod(sys_stream, "isatty", "");
+		if (!sys_isatty)
+			PyErr_Clear();
+		if(sys_isatty && PyObject_IsTrue(sys_isatty) &&
+		   PyFile_Check(sys_stream)) {
+			if (!PyFile_SetEncoding(sys_stream, codeset))
+				Py_FatalError("Cannot set codeset of stdin");
+		}
+		Py_XDECREF(sys_isatty);
+
+		sys_stream = PySys_GetObject("stdout");
+		sys_isatty = PyObject_CallMethod(sys_stream, "isatty", "");
+		if (!sys_isatty)
+			PyErr_Clear();
+		if(sys_isatty && PyObject_IsTrue(sys_isatty) &&
+		   PyFile_Check(sys_stream)) {
+			if (!PyFile_SetEncoding(sys_stream, codeset))
+				Py_FatalError("Cannot set codeset of stdout");
+		}
+		Py_XDECREF(sys_isatty);
+
+		sys_stream = PySys_GetObject("stderr");
+		sys_isatty = PyObject_CallMethod(sys_stream, "isatty", "");
+		if (!sys_isatty)
+			PyErr_Clear();
+		if(sys_isatty && PyObject_IsTrue(sys_isatty) &&
+		   PyFile_Check(sys_stream)) {
+			if (!PyFile_SetEncoding(sys_stream, codeset))
+				Py_FatalError("Cannot set codeset of stderr");
+		}
+		Py_XDECREF(sys_isatty);
+
+		if (!Py_FileSystemDefaultEncoding)
+			Py_FileSystemDefaultEncoding = codeset;
+		else
+			free(codeset);
+	}
+#endif
+}
+
+void
+Py_Initialize(void)
+{
+	Py_InitializeEx(1);
+}
+
+
+#ifdef COUNT_ALLOCS
+extern void dump_counts(FILE*);
+#endif
+
+/* Undo the effect of Py_Initialize().
+
+   Beware: if multiple interpreter and/or thread states exist, these
+   are not wiped out; only the current thread and interpreter state
+   are deleted.  But since everything else is deleted, those other
+   interpreter and thread states should no longer be used.
+
+   (XXX We should do better, e.g. wipe out all interpreters and
+   threads.)
+
+   Locking: as above.
+
+*/
+
+void
+Py_Finalize(void)
+{
+	PyInterpreterState *interp;
+	PyThreadState *tstate;
+
+	if (!initialized)
+		return;
+
+	/* The interpreter is still entirely intact at this point, and the
+	 * exit funcs may be relying on that.  In particular, if some thread
+	 * or exit func is still waiting to do an import, the import machinery
+	 * expects Py_IsInitialized() to return true.  So don't say the
+	 * interpreter is uninitialized until after the exit funcs have run.
+	 * Note that Threading.py uses an exit func to do a join on all the
+	 * threads created thru it, so this also protects pending imports in
+	 * the threads created via Threading.
+	 */
+	call_sys_exitfunc();
+	initialized = 0;
+
+	/* Get current thread state and interpreter pointer */
+	tstate = PyThreadState_GET();
+	interp = tstate->interp;
+
+	/* Disable signal handling */
+	PyOS_FiniInterrupts();
+
+	/* drop module references we saved */
+	Py_XDECREF(warnings_module);
+	warnings_module = NULL;
+
+	/* Collect garbage.  This may call finalizers; it's nice to call these
+	 * before all modules are destroyed.
+	 * XXX If a __del__ or weakref callback is triggered here, and tries to
+	 * XXX import a module, bad things can happen, because Python no
+	 * XXX longer believes it's initialized.
+	 * XXX     Fatal Python error: Interpreter not initialized (version mismatch?)
+	 * XXX is easy to provoke that way.  I've also seen, e.g.,
+	 * XXX     Exception exceptions.ImportError: 'No module named sha'
+	 * XXX         in <function callback at 0x008F5718> ignored
+	 * XXX but I'm unclear on exactly how that one happens.  In any case,
+	 * XXX I haven't seen a real-life report of either of these.
+	 */
+	PyGC_Collect();
+#ifdef COUNT_ALLOCS
+	/* With COUNT_ALLOCS, it helps to run GC multiple times:
+	   each collection might release some types from the type
+	   list, so they become garbage. */
+	while (PyGC_Collect() > 0)
+		/* nothing */;
+#endif
+
+	/* Destroy all modules */
+	PyImport_Cleanup();
+
+	/* Collect final garbage.  This disposes of cycles created by
+	 * new-style class definitions, for example.
+	 * XXX This is disabled because it caused too many problems.  If
+	 * XXX a __del__ or weakref callback triggers here, Python code has
+	 * XXX a hard time running, because even the sys module has been
+	 * XXX cleared out (sys.stdout is gone, sys.excepthook is gone, etc).
+	 * XXX One symptom is a sequence of information-free messages
+	 * XXX coming from threads (if a __del__ or callback is invoked,
+	 * XXX other threads can execute too, and any exception they encounter
+	 * XXX triggers a comedy of errors as subsystem after subsystem
+	 * XXX fails to find what it *expects* to find in sys to help report
+	 * XXX the exception and consequent unexpected failures).  I've also
+	 * XXX seen segfaults then, after adding print statements to the
+	 * XXX Python code getting called.
+	 */
+#if 0
+	PyGC_Collect();
+#endif
+
+	/* Destroy the database used by _PyImport_{Fixup,Find}Extension */
+	_PyImport_Fini();
+
+	/* Debugging stuff */
+#ifdef COUNT_ALLOCS
+	dump_counts(stdout);
+#endif
+
+	PRINT_TOTAL_REFS();
+
+#ifdef Py_TRACE_REFS
+	/* Display all objects still alive -- this can invoke arbitrary
+	 * __repr__ overrides, so requires a mostly-intact interpreter.
+	 * Alas, a lot of stuff may still be alive now that will be cleaned
+	 * up later.
+	 */
+	if (Py_GETENV("PYTHONDUMPREFS"))
+		_Py_PrintReferences(stderr);
+#endif /* Py_TRACE_REFS */
+
+	/* Cleanup auto-thread-state */
+#ifdef WITH_THREAD
+	_PyGILState_Fini();
+#endif /* WITH_THREAD */
+
+	/* Clear interpreter state */
+	PyInterpreterState_Clear(interp);
+
+	/* Now we decref the exception classes.  After this point nothing
+	   can raise an exception.  That's okay, because each Fini() method
+	   below has been checked to make sure no exceptions are ever
+	   raised.
+	*/
+
+	_PyExc_Fini();
+
+	/* Delete current thread */
+	PyThreadState_Swap(NULL);
+	PyInterpreterState_Delete(interp);
+
+	/* Sundry finalizers */
+	PyMethod_Fini();
+	PyFrame_Fini();
+	PyCFunction_Fini();
+	PyTuple_Fini();
+	PyList_Fini();
+	PySet_Fini();
+	PyString_Fini();
+	PyInt_Fini();
+	PyFloat_Fini();
+
+#ifdef Py_USING_UNICODE
+	/* Cleanup Unicode implementation */
+	_PyUnicode_Fini();
+#endif
+
+	/* XXX Still allocated:
+	   - various static ad-hoc pointers to interned strings
+	   - int and float free list blocks
+	   - whatever various modules and libraries allocate
+	*/
+
+	PyGrammar_RemoveAccelerators(&_PyParser_Grammar);
+
+#ifdef Py_TRACE_REFS
+	/* Display addresses (& refcnts) of all objects still alive.
+	 * An address can be used to find the repr of the object, printed
+	 * above by _Py_PrintReferences.
+	 */
+	if (Py_GETENV("PYTHONDUMPREFS"))
+		_Py_PrintReferenceAddresses(stderr);
+#endif /* Py_TRACE_REFS */
+#ifdef PYMALLOC_DEBUG
+	if (Py_GETENV("PYTHONMALLOCSTATS"))
+		_PyObject_DebugMallocStats();
+#endif
+
+	call_ll_exitfuncs();
+}
+
+/* Create and initialize a new interpreter and thread, and return the
+   new thread.  This requires that Py_Initialize() has been called
+   first.
+
+   Unsuccessful initialization yields a NULL pointer.  Note that *no*
+   exception information is available even in this case -- the
+   exception information is held in the thread, and there is no
+   thread.
+
+   Locking: as above.
+
+*/
+
+PyThreadState *
+Py_NewInterpreter(void)
+{
+	PyInterpreterState *interp;
+	PyThreadState *tstate, *save_tstate;
+	PyObject *bimod, *sysmod;
+
+	if (!initialized)
+		Py_FatalError("Py_NewInterpreter: call Py_Initialize first");
+
+	interp = PyInterpreterState_New();
+	if (interp == NULL)
+		return NULL;
+
+	tstate = PyThreadState_New(interp);
+	if (tstate == NULL) {
+		PyInterpreterState_Delete(interp);
+		return NULL;
+	}
+
+	save_tstate = PyThreadState_Swap(tstate);
+
+	/* XXX The following is lax in error checking */
+
+	interp->modules = PyDict_New();
+	interp->modules_reloading = PyDict_New();
+
+	bimod = _PyImport_FindExtension("__builtin__", "__builtin__");
+	if (bimod != NULL) {
+		interp->builtins = PyModule_GetDict(bimod);
+		if (interp->builtins == NULL)
+			goto handle_error;
+		Py_INCREF(interp->builtins);
+	}
+	sysmod = _PyImport_FindExtension("sys", "sys");
+	if (bimod != NULL && sysmod != NULL) {
+		interp->sysdict = PyModule_GetDict(sysmod);
+		if (interp->sysdict == NULL)
+			goto handle_error;
+		Py_INCREF(interp->sysdict);
+		PySys_SetPath(Py_GetPath());
+		PyDict_SetItemString(interp->sysdict, "modules",
+				     interp->modules);
+		_PyImportHooks_Init();
+		initmain();
+		if (!Py_NoSiteFlag)
+			initsite();
+	}
+
+	if (!PyErr_Occurred())
+		return tstate;
+
+handle_error:
+	/* Oops, it didn't work.  Undo it all. */
+
+	PyErr_Print();
+	PyThreadState_Clear(tstate);
+	PyThreadState_Swap(save_tstate);
+	PyThreadState_Delete(tstate);
+	PyInterpreterState_Delete(interp);
+
+	return NULL;
+}
+
+/* Delete an interpreter and its last thread.  This requires that the
+   given thread state is current, that the thread has no remaining
+   frames, and that it is its interpreter's only remaining thread.
+   It is a fatal error to violate these constraints.
+
+   (Py_Finalize() doesn't have these constraints -- it zaps
+   everything, regardless.)
+
+   Locking: as above.
+
+*/
+
+void
+Py_EndInterpreter(PyThreadState *tstate)
+{
+	PyInterpreterState *interp = tstate->interp;
+
+	if (tstate != PyThreadState_GET())
+		Py_FatalError("Py_EndInterpreter: thread is not current");
+	if (tstate->frame != NULL)
+		Py_FatalError("Py_EndInterpreter: thread still has a frame");
+	if (tstate != interp->tstate_head || tstate->next != NULL)
+		Py_FatalError("Py_EndInterpreter: not the last thread");
+
+	PyImport_Cleanup();
+	PyInterpreterState_Clear(interp);
+	PyThreadState_Swap(NULL);
+	PyInterpreterState_Delete(interp);
+}
+
+static char *progname = "python";
+
+void
+Py_SetProgramName(char *pn)
+{
+	if (pn && *pn)
+		progname = pn;
+}
+
+char *
+Py_GetProgramName(void)
+{
+	return progname;
+}
+
+static char *default_home = NULL;
+
+void
+Py_SetPythonHome(char *home)
+{
+	default_home = home;
+}
+
+char *
+Py_GetPythonHome(void)
+{
+	char *home = default_home;
+	if (home == NULL && !Py_IgnoreEnvironmentFlag)
+		home = Py_GETENV("PYTHONHOME");
+	return home;
+}
+
+/* Create __main__ module */
+
+static void
+initmain(void)
+{
+	PyObject *m, *d;
+	m = PyImport_AddModule("__main__");
+	if (m == NULL)
+		Py_FatalError("can't create __main__ module");
+	d = PyModule_GetDict(m);
+	if (PyDict_GetItemString(d, "__builtins__") == NULL) {
+		PyObject *bimod = PyImport_ImportModule("__builtin__");
+		if (bimod == NULL ||
+		    PyDict_SetItemString(d, "__builtins__", bimod) != 0)
+			Py_FatalError("can't add __builtins__ to __main__");
+		Py_DECREF(bimod);
+	}
+}
+
+/* Import the site module (not into __main__ though) */
+
+static void
+initsite(void)
+{
+	PyObject *m, *f;
+	m = PyImport_ImportModule("site");
+	if (m == NULL) {
+		f = PySys_GetObject("stderr");
+		if (Py_VerboseFlag) {
+			PyFile_WriteString(
+				"'import site' failed; traceback:\n", f);
+			PyErr_Print();
+		}
+		else {
+			PyFile_WriteString(
+			  "'import site' failed; use -v for traceback\n", f);
+			PyErr_Clear();
+		}
+	}
+	else {
+		Py_DECREF(m);
+	}
+}
+
+/* Parse input from a file and execute it */
+
+int
+PyRun_AnyFileExFlags(FILE *fp, const char *filename, int closeit,
+		     PyCompilerFlags *flags)
+{
+	if (filename == NULL)
+		filename = "???";
+	if (Py_FdIsInteractive(fp, filename)) {
+		int err = PyRun_InteractiveLoopFlags(fp, filename, flags);
+		if (closeit)
+			fclose(fp);
+		return err;
+	}
+	else
+		return PyRun_SimpleFileExFlags(fp, filename, closeit, flags);
+}
+
+int
+PyRun_InteractiveLoopFlags(FILE *fp, const char *filename, PyCompilerFlags *flags)
+{
+	PyObject *v;
+	int ret;
+	PyCompilerFlags local_flags;
+
+	if (flags == NULL) {
+		flags = &local_flags;
+		local_flags.cf_flags = 0;
+	}
+	v = PySys_GetObject("ps1");
+	if (v == NULL) {
+		PySys_SetObject("ps1", v = PyString_FromString(">>> "));
+		Py_XDECREF(v);
+	}
+	v = PySys_GetObject("ps2");
+	if (v == NULL) {
+		PySys_SetObject("ps2", v = PyString_FromString("... "));
+		Py_XDECREF(v);
+	}
+	for (;;) {
+		ret = PyRun_InteractiveOneFlags(fp, filename, flags);
+		PRINT_TOTAL_REFS();
+		if (ret == E_EOF)
+			return 0;
+		/*
+		if (ret == E_NOMEM)
+			return -1;
+		*/
+	}
+}
+
+/* compute parser flags based on compiler flags */
+#define PARSER_FLAGS(flags) \
+	((flags) ? ((((flags)->cf_flags & PyCF_DONT_IMPLY_DEDENT) ? \
+		      PyPARSE_DONT_IMPLY_DEDENT : 0) \
+		    | ((flags)->cf_flags & CO_FUTURE_WITH_STATEMENT ? \
+		       PyPARSE_WITH_IS_KEYWORD : 0)) : 0)
+
+int
+PyRun_InteractiveOneFlags(FILE *fp, const char *filename, PyCompilerFlags *flags)
+{
+	PyObject *m, *d, *v, *w;
+	mod_ty mod;
+	PyArena *arena;
+	char *ps1 = "", *ps2 = "";
+	int errcode = 0;
+
+	v = PySys_GetObject("ps1");
+	if (v != NULL) {
+		v = PyObject_Str(v);
+		if (v == NULL)
+			PyErr_Clear();
+		else if (PyString_Check(v))
+			ps1 = PyString_AsString(v);
+	}
+	w = PySys_GetObject("ps2");
+	if (w != NULL) {
+		w = PyObject_Str(w);
+		if (w == NULL)
+			PyErr_Clear();
+		else if (PyString_Check(w))
+			ps2 = PyString_AsString(w);
+	}
+	arena = PyArena_New();
+	if (arena == NULL) {
+		Py_XDECREF(v);
+		Py_XDECREF(w);
+		return -1;
+	}
+	mod = PyParser_ASTFromFile(fp, filename,
+				   Py_single_input, ps1, ps2,
+				   flags, &errcode, arena);
+	Py_XDECREF(v);
+	Py_XDECREF(w);
+	if (mod == NULL) {
+		PyArena_Free(arena);
+		if (errcode == E_EOF) {
+			PyErr_Clear();
+			return E_EOF;
+		}
+		PyErr_Print();
+		return -1;
+	}
+	m = PyImport_AddModule("__main__");
+	if (m == NULL) {
+		PyArena_Free(arena);
+		return -1;
+	}
+	d = PyModule_GetDict(m);
+	v = run_mod(mod, filename, d, d, flags, arena);
+	PyArena_Free(arena);
+	if (v == NULL) {
+		PyErr_Print();
+		return -1;
+	}
+	Py_DECREF(v);
+	if (Py_FlushLine())
+		PyErr_Clear();
+	return 0;
+}
+
+/* Check whether a file maybe a pyc file: Look at the extension,
+   the file type, and, if we may close it, at the first few bytes. */
+
+static int
+maybe_pyc_file(FILE *fp, const char* filename, const char* ext, int closeit)
+{
+	if (strcmp(ext, ".pyc") == 0 || strcmp(ext, ".pyo") == 0)
+		return 1;
+
+	/* Only look into the file if we are allowed to close it, since
+	   it then should also be seekable. */
+	if (closeit) {
+		/* Read only two bytes of the magic. If the file was opened in
+		   text mode, the bytes 3 and 4 of the magic (\r\n) might not
+		   be read as they are on disk. */
+		unsigned int halfmagic = PyImport_GetMagicNumber() & 0xFFFF;
+		unsigned char buf[2];
+		/* Mess:  In case of -x, the stream is NOT at its start now,
+		   and ungetc() was used to push back the first newline,
+		   which makes the current stream position formally undefined,
+		   and a x-platform nightmare.
+		   Unfortunately, we have no direct way to know whether -x
+		   was specified.  So we use a terrible hack:  if the current
+		   stream position is not 0, we assume -x was specified, and
+		   give up.  Bug 132850 on SourceForge spells out the
+		   hopelessness of trying anything else (fseek and ftell
+		   don't work predictably x-platform for text-mode files).
+		*/
+		int ispyc = 0;
+		if (ftell(fp) == 0) {
+			if (fread(buf, 1, 2, fp) == 2 &&
+			    ((unsigned int)buf[1]<<8 | buf[0]) == halfmagic)
+				ispyc = 1;
+			rewind(fp);
+		}
+		return ispyc;
+	}
+	return 0;
+}
+
+int
+PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit,
+			PyCompilerFlags *flags)
+{
+	PyObject *m, *d, *v;
+	const char *ext;
+
+	m = PyImport_AddModule("__main__");
+	if (m == NULL)
+		return -1;
+	d = PyModule_GetDict(m);
+	if (PyDict_GetItemString(d, "__file__") == NULL) {
+		PyObject *f = PyString_FromString(filename);
+		if (f == NULL)
+			return -1;
+		if (PyDict_SetItemString(d, "__file__", f) < 0) {
+			Py_DECREF(f);
+			return -1;
+		}
+		Py_DECREF(f);
+	}
+	ext = filename + strlen(filename) - 4;
+	if (maybe_pyc_file(fp, filename, ext, closeit)) {
+		/* Try to run a pyc file. First, re-open in binary */
+		if (closeit)
+			fclose(fp);
+		if ((fp = fopen(filename, "rb")) == NULL) {
+			fprintf(stderr, "python: Can't reopen .pyc file\n");
+			return -1;
+		}
+		/* Turn on optimization if a .pyo file is given */
+		if (strcmp(ext, ".pyo") == 0)
+			Py_OptimizeFlag = 1;
+		v = run_pyc_file(fp, filename, d, d, flags);
+	} else {
+		v = PyRun_FileExFlags(fp, filename, Py_file_input, d, d,
+				      closeit, flags);
+	}
+	if (v == NULL) {
+		PyErr_Print();
+		return -1;
+	}
+	Py_DECREF(v);
+	if (Py_FlushLine())
+		PyErr_Clear();
+	return 0;
+}
+
+int
+PyRun_SimpleStringFlags(const char *command, PyCompilerFlags *flags)
+{
+	PyObject *m, *d, *v;
+	m = PyImport_AddModule("__main__");
+	if (m == NULL)
+		return -1;
+	d = PyModule_GetDict(m);
+	v = PyRun_StringFlags(command, Py_file_input, d, d, flags);
+	if (v == NULL) {
+		PyErr_Print();
+		return -1;
+	}
+	Py_DECREF(v);
+	if (Py_FlushLine())
+		PyErr_Clear();
+	return 0;
+}
+
+static int
+parse_syntax_error(PyObject *err, PyObject **message, const char **filename,
+		   int *lineno, int *offset, const char **text)
+{
+	long hold;
+	PyObject *v;
+
+	/* old style errors */
+	if (PyTuple_Check(err))
+		return PyArg_ParseTuple(err, "O(ziiz)", message, filename,
+					lineno, offset, text);
+
+	/* new style errors.  `err' is an instance */
+
+	if (! (v = PyObject_GetAttrString(err, "msg")))
+		goto finally;
+	*message = v;
+
+	if (!(v = PyObject_GetAttrString(err, "filename")))
+		goto finally;
+	if (v == Py_None)
+		*filename = NULL;
+	else if (! (*filename = PyString_AsString(v)))
+		goto finally;
+
+	Py_DECREF(v);
+	if (!(v = PyObject_GetAttrString(err, "lineno")))
+		goto finally;
+	hold = PyInt_AsLong(v);
+	Py_DECREF(v);
+	v = NULL;
+	if (hold < 0 && PyErr_Occurred())
+		goto finally;
+	*lineno = (int)hold;
+
+	if (!(v = PyObject_GetAttrString(err, "offset")))
+		goto finally;
+	if (v == Py_None) {
+		*offset = -1;
+		Py_DECREF(v);
+		v = NULL;
+	} else {
+		hold = PyInt_AsLong(v);
+		Py_DECREF(v);
+		v = NULL;
+		if (hold < 0 && PyErr_Occurred())
+			goto finally;
+		*offset = (int)hold;
+	}
+
+	if (!(v = PyObject_GetAttrString(err, "text")))
+		goto finally;
+	if (v == Py_None)
+		*text = NULL;
+	else if (! (*text = PyString_AsString(v)))
+		goto finally;
+	Py_DECREF(v);
+	return 1;
+
+finally:
+	Py_XDECREF(v);
+	return 0;
+}
+
+void
+PyErr_Print(void)
+{
+	PyErr_PrintEx(1);
+}
+
+static void
+print_error_text(PyObject *f, int offset, const char *text)
+{
+	char *nl;
+	if (offset >= 0) {
+		if (offset > 0 && offset == (int)strlen(text))
+			offset--;
+		for (;;) {
+			nl = strchr(text, '\n');
+			if (nl == NULL || nl-text >= offset)
+				break;
+			offset -= (int)(nl+1-text);
+			text = nl+1;
+		}
+		while (*text == ' ' || *text == '\t') {
+			text++;
+			offset--;
+		}
+	}
+	PyFile_WriteString("    ", f);
+	PyFile_WriteString(text, f);
+	if (*text == '\0' || text[strlen(text)-1] != '\n')
+		PyFile_WriteString("\n", f);
+	if (offset == -1)
+		return;
+	PyFile_WriteString("    ", f);
+	offset--;
+	while (offset > 0) {
+		PyFile_WriteString(" ", f);
+		offset--;
+	}
+	PyFile_WriteString("^\n", f);
+}
+
+static void
+handle_system_exit(void)
+{
+	PyObject *exception, *value, *tb;
+	int exitcode = 0;
+
+	PyErr_Fetch(&exception, &value, &tb);
+	if (Py_FlushLine())
+		PyErr_Clear();
+	fflush(stdout);
+	if (value == NULL || value == Py_None)
+		goto done;
+	if (PyExceptionInstance_Check(value)) {
+		/* The error code should be in the `code' attribute. */
+		PyObject *code = PyObject_GetAttrString(value, "code");
+		if (code) {
+			Py_DECREF(value);
+			value = code;
+			if (value == Py_None)
+				goto done;
+		}
+		/* If we failed to dig out the 'code' attribute,
+		   just let the else clause below print the error. */
+	}
+	if (PyInt_Check(value))
+		exitcode = (int)PyInt_AsLong(value);
+	else {
+		PyObject_Print(value, stderr, Py_PRINT_RAW);
+		PySys_WriteStderr("\n");
+		exitcode = 1;
+	}
+ done:
+	/* Restore and clear the exception info, in order to properly decref
+	 * the exception, value, and traceback.	 If we just exit instead,
+	 * these leak, which confuses PYTHONDUMPREFS output, and may prevent
+	 * some finalizers from running.
+	 */
+	PyErr_Restore(exception, value, tb);
+	PyErr_Clear();
+	Py_Exit(exitcode);
+	/* NOTREACHED */
+}
+
+void
+PyErr_PrintEx(int set_sys_last_vars)
+{
+	PyObject *exception, *v, *tb, *hook;
+
+	if (PyErr_ExceptionMatches(PyExc_SystemExit)) {
+		handle_system_exit();
+	}
+	PyErr_Fetch(&exception, &v, &tb);
+	if (exception == NULL)
+		return;
+	PyErr_NormalizeException(&exception, &v, &tb);
+	if (exception == NULL)
+		return;
+        /* Now we know v != NULL too */
+	if (set_sys_last_vars) {
+		PySys_SetObject("last_type", exception);
+		PySys_SetObject("last_value", v);
+		PySys_SetObject("last_traceback", tb);
+	}
+	hook = PySys_GetObject("excepthook");
+	if (hook) {
+		PyObject *args = PyTuple_Pack(3,
+		    exception, v, tb ? tb : Py_None);
+		PyObject *result = PyEval_CallObject(hook, args);
+		if (result == NULL) {
+			PyObject *exception2, *v2, *tb2;
+			if (PyErr_ExceptionMatches(PyExc_SystemExit)) {
+				handle_system_exit();
+			}
+			PyErr_Fetch(&exception2, &v2, &tb2);
+			PyErr_NormalizeException(&exception2, &v2, &tb2);
+			/* It should not be possible for exception2 or v2
+			   to be NULL. However PyErr_Display() can't
+			   tolerate NULLs, so just be safe. */
+			if (exception2 == NULL) {
+				exception2 = Py_None;
+				Py_INCREF(exception2);
+			}
+			if (v2 == NULL) {
+				v2 = Py_None;
+				Py_INCREF(v2);
+			}
+			if (Py_FlushLine())
+				PyErr_Clear();
+			fflush(stdout);
+			PySys_WriteStderr("Error in sys.excepthook:\n");
+			PyErr_Display(exception2, v2, tb2);
+			PySys_WriteStderr("\nOriginal exception was:\n");
+			PyErr_Display(exception, v, tb);
+			Py_DECREF(exception2);
+			Py_DECREF(v2);
+			Py_XDECREF(tb2);
+		}
+		Py_XDECREF(result);
+		Py_XDECREF(args);
+	} else {
+		PySys_WriteStderr("sys.excepthook is missing\n");
+		PyErr_Display(exception, v, tb);
+	}
+	Py_XDECREF(exception);
+	Py_XDECREF(v);
+	Py_XDECREF(tb);
+}
+
+void
+PyErr_Display(PyObject *exception, PyObject *value, PyObject *tb)
+{
+	int err = 0;
+	PyObject *f = PySys_GetObject("stderr");
+	Py_INCREF(value);
+	if (f == NULL)
+		fprintf(stderr, "lost sys.stderr\n");
+	else {
+		if (Py_FlushLine())
+			PyErr_Clear();
+		fflush(stdout);
+		if (tb && tb != Py_None)
+			err = PyTraceBack_Print(tb, f);
+		if (err == 0 &&
+		    PyObject_HasAttrString(value, "print_file_and_line"))
+		{
+			PyObject *message;
+			const char *filename, *text;
+			int lineno, offset;
+			if (!parse_syntax_error(value, &message, &filename,
+						&lineno, &offset, &text))
+				PyErr_Clear();
+			else {
+				char buf[10];
+				PyFile_WriteString("  File \"", f);
+				if (filename == NULL)
+					PyFile_WriteString("<string>", f);
+				else
+					PyFile_WriteString(filename, f);
+				PyFile_WriteString("\", line ", f);
+				PyOS_snprintf(buf, sizeof(buf), "%d", lineno);
+				PyFile_WriteString(buf, f);
+				PyFile_WriteString("\n", f);
+				if (text != NULL)
+					print_error_text(f, offset, text);
+				Py_DECREF(value);
+				value = message;
+				/* Can't be bothered to check all those
+				   PyFile_WriteString() calls */
+				if (PyErr_Occurred())
+					err = -1;
+			}
+		}
+		if (err) {
+			/* Don't do anything else */
+		}
+		else if (PyExceptionClass_Check(exception)) {
+			PyObject* moduleName;
+			char* className = PyExceptionClass_Name(exception);
+			if (className != NULL) {
+				char *dot = strrchr(className, '.');
+				if (dot != NULL)
+					className = dot+1;
+			}
+
+			moduleName = PyObject_GetAttrString(exception, "__module__");
+			if (moduleName == NULL)
+				err = PyFile_WriteString("<unknown>", f);
+			else {
+				char* modstr = PyString_AsString(moduleName);
+				if (modstr && strcmp(modstr, "exceptions"))
+				{
+					err = PyFile_WriteString(modstr, f);
+					err += PyFile_WriteString(".", f);
+				}
+				Py_DECREF(moduleName);
+			}
+			if (err == 0) {
+				if (className == NULL)
+				      err = PyFile_WriteString("<unknown>", f);
+				else
+				      err = PyFile_WriteString(className, f);
+			}
+		}
+		else
+			err = PyFile_WriteObject(exception, f, Py_PRINT_RAW);
+		if (err == 0 && (value != Py_None)) {
+			PyObject *s = PyObject_Str(value);
+			/* only print colon if the str() of the
+			   object is not the empty string
+			*/
+			if (s == NULL)
+				err = -1;
+			else if (!PyString_Check(s) ||
+				 PyString_GET_SIZE(s) != 0)
+				err = PyFile_WriteString(": ", f);
+			if (err == 0)
+			  err = PyFile_WriteObject(s, f, Py_PRINT_RAW);
+			Py_XDECREF(s);
+		}
+		if (err == 0)
+			err = PyFile_WriteString("\n", f);
+	}
+	Py_DECREF(value);
+	/* If an error happened here, don't show it.
+	   XXX This is wrong, but too many callers rely on this behavior. */
+	if (err != 0)
+		PyErr_Clear();
+}
+
+PyObject *
+PyRun_StringFlags(const char *str, int start, PyObject *globals,
+		  PyObject *locals, PyCompilerFlags *flags)
+{
+	PyObject *ret = NULL;
+	mod_ty mod;
+	PyArena *arena = PyArena_New();
+	if (arena == NULL)
+		return NULL;
+	
+	mod = PyParser_ASTFromString(str, "<string>", start, flags, arena);
+	if (mod != NULL)
+		ret = run_mod(mod, "<string>", globals, locals, flags, arena);
+	PyArena_Free(arena);
+	return ret;
+}
+
+PyObject *
+PyRun_FileExFlags(FILE *fp, const char *filename, int start, PyObject *globals,
+		  PyObject *locals, int closeit, PyCompilerFlags *flags)
+{
+	PyObject *ret;
+	mod_ty mod;
+	PyArena *arena = PyArena_New();
+	if (arena == NULL)
+		return NULL;
+	
+	mod = PyParser_ASTFromFile(fp, filename, start, 0, 0,
+				   flags, NULL, arena);
+	if (closeit)
+		fclose(fp);
+	if (mod == NULL) {
+		PyArena_Free(arena);
+		return NULL;
+	}
+	ret = run_mod(mod, filename, globals, locals, flags, arena);
+	PyArena_Free(arena);
+	return ret;
+}
+
+static PyObject *
+run_mod(mod_ty mod, const char *filename, PyObject *globals, PyObject *locals,
+	 PyCompilerFlags *flags, PyArena *arena)
+{
+	PyCodeObject *co;
+	PyObject *v;
+	co = PyAST_Compile(mod, filename, flags, arena);
+	if (co == NULL)
+		return NULL;
+	v = PyEval_EvalCode(co, globals, locals);
+	Py_DECREF(co);
+	return v;
+}
+
+static PyObject *
+run_pyc_file(FILE *fp, const char *filename, PyObject *globals,
+	     PyObject *locals, PyCompilerFlags *flags)
+{
+	PyCodeObject *co;
+	PyObject *v;
+	long magic;
+	long PyImport_GetMagicNumber(void);
+
+	magic = PyMarshal_ReadLongFromFile(fp);
+	if (magic != PyImport_GetMagicNumber()) {
+		PyErr_SetString(PyExc_RuntimeError,
+			   "Bad magic number in .pyc file");
+		return NULL;
+	}
+	(void) PyMarshal_ReadLongFromFile(fp);
+	v = PyMarshal_ReadLastObjectFromFile(fp);
+	fclose(fp);
+	if (v == NULL || !PyCode_Check(v)) {
+		Py_XDECREF(v);
+		PyErr_SetString(PyExc_RuntimeError,
+			   "Bad code object in .pyc file");
+		return NULL;
+	}
+	co = (PyCodeObject *)v;
+	v = PyEval_EvalCode(co, globals, locals);
+	if (v && flags)
+		flags->cf_flags |= (co->co_flags & PyCF_MASK);
+	Py_DECREF(co);
+	return v;
+}
+
+PyObject *
+Py_CompileStringFlags(const char *str, const char *filename, int start,
+		      PyCompilerFlags *flags)
+{
+	PyCodeObject *co;
+	mod_ty mod;
+	PyArena *arena = PyArena_New();
+	if (arena == NULL)
+		return NULL;
+
+	mod = PyParser_ASTFromString(str, filename, start, flags, arena);
+	if (mod == NULL) {
+		PyArena_Free(arena);
+		return NULL;
+	}
+	if (flags && (flags->cf_flags & PyCF_ONLY_AST)) {
+		PyObject *result = PyAST_mod2obj(mod);
+		PyArena_Free(arena);
+		return result;
+	}
+	co = PyAST_Compile(mod, filename, flags, arena);
+	PyArena_Free(arena);
+	return (PyObject *)co;
+}
+
+struct symtable *
+Py_SymtableString(const char *str, const char *filename, int start)
+{
+	struct symtable *st;
+	mod_ty mod;
+	PyArena *arena = PyArena_New();
+	if (arena == NULL)
+		return NULL;
+
+	mod = PyParser_ASTFromString(str, filename, start, NULL, arena);
+	if (mod == NULL) {
+		PyArena_Free(arena);
+		return NULL;
+	}
+	st = PySymtable_Build(mod, filename, 0);
+	PyArena_Free(arena);
+	return st;
+}
+
+/* Preferred access to parser is through AST. */
+mod_ty
+PyParser_ASTFromString(const char *s, const char *filename, int start,
+		       PyCompilerFlags *flags, PyArena *arena)
+{
+	mod_ty mod;
+	perrdetail err;
+	node *n = PyParser_ParseStringFlagsFilename(s, filename,
+					&_PyParser_Grammar, start, &err,
+					PARSER_FLAGS(flags));
+	if (n) {
+		mod = PyAST_FromNode(n, flags, filename, arena);
+		PyNode_Free(n);
+		return mod;
+	}
+	else {
+		err_input(&err);
+		return NULL;
+	}
+}
+
+mod_ty
+PyParser_ASTFromFile(FILE *fp, const char *filename, int start, char *ps1,
+		     char *ps2, PyCompilerFlags *flags, int *errcode,
+		     PyArena *arena)
+{
+	mod_ty mod;
+	perrdetail err;
+	node *n = PyParser_ParseFileFlags(fp, filename, &_PyParser_Grammar,
+				start, ps1, ps2, &err, PARSER_FLAGS(flags));
+	if (n) {
+		mod = PyAST_FromNode(n, flags, filename, arena);
+		PyNode_Free(n);
+		return mod;
+	}
+	else {
+		err_input(&err);
+		if (errcode)
+			*errcode = err.error;
+		return NULL;
+	}
+}
+
+/* Simplified interface to parsefile -- return node or set exception */
+
+node *
+PyParser_SimpleParseFileFlags(FILE *fp, const char *filename, int start, int flags)
+{
+	perrdetail err;
+	node *n = PyParser_ParseFileFlags(fp, filename, &_PyParser_Grammar,
+					  start, NULL, NULL, &err, flags);
+	if (n == NULL)
+		err_input(&err);
+
+	return n;
+}
+
+/* Simplified interface to parsestring -- return node or set exception */
+
+node *
+PyParser_SimpleParseStringFlags(const char *str, int start, int flags)
+{
+	perrdetail err;
+	node *n = PyParser_ParseStringFlags(str, &_PyParser_Grammar,
+					    start, &err, flags);
+	if (n == NULL)
+		err_input(&err);
+	return n;
+}
+
+node *
+PyParser_SimpleParseStringFlagsFilename(const char *str, const char *filename,
+					int start, int flags)
+{
+	perrdetail err;
+	node *n = PyParser_ParseStringFlagsFilename(str, filename,
+				&_PyParser_Grammar, start, &err, flags);
+	if (n == NULL)
+		err_input(&err);
+	return n;
+}
+
+node *
+PyParser_SimpleParseStringFilename(const char *str, const char *filename, int start)
+{
+	return PyParser_SimpleParseStringFlagsFilename(str, filename, start, 0);
+}
+
+/* May want to move a more generalized form of this to parsetok.c or
+   even parser modules. */
+
+void
+PyParser_SetError(perrdetail *err)
+{
+	err_input(err);
+}
+
+/* Set the error appropriate to the given input error code (see errcode.h) */
+
+static void
+err_input(perrdetail *err)
+{
+	PyObject *v, *w, *errtype;
+	PyObject* u = NULL;
+	char *msg = NULL;
+	errtype = PyExc_SyntaxError;
+	switch (err->error) {
+	case E_SYNTAX:
+		errtype = PyExc_IndentationError;
+		if (err->expected == INDENT)
+			msg = "expected an indented block";
+		else if (err->token == INDENT)
+			msg = "unexpected indent";
+		else if (err->token == DEDENT)
+			msg = "unexpected unindent";
+		else {
+			errtype = PyExc_SyntaxError;
+			msg = "invalid syntax";
+		}
+		break;
+	case E_TOKEN:
+		msg = "invalid token";
+		break;
+	case E_EOFS:
+		msg = "EOF while scanning triple-quoted string";
+		break;
+	case E_EOLS:
+		msg = "EOL while scanning single-quoted string";
+		break;
+	case E_INTR:
+		if (!PyErr_Occurred())
+			PyErr_SetNone(PyExc_KeyboardInterrupt);
+		return;
+	case E_NOMEM:
+		PyErr_NoMemory();
+		return;
+	case E_EOF:
+		msg = "unexpected EOF while parsing";
+		break;
+	case E_TABSPACE:
+		errtype = PyExc_TabError;
+		msg = "inconsistent use of tabs and spaces in indentation";
+		break;
+	case E_OVERFLOW:
+		msg = "expression too long";
+		break;
+	case E_DEDENT:
+		errtype = PyExc_IndentationError;
+		msg = "unindent does not match any outer indentation level";
+		break;
+	case E_TOODEEP:
+		errtype = PyExc_IndentationError;
+		msg = "too many levels of indentation";
+		break;
+	case E_DECODE: {
+		PyObject *type, *value, *tb;
+		PyErr_Fetch(&type, &value, &tb);
+		if (value != NULL) {
+			u = PyObject_Str(value);
+			if (u != NULL) {
+				msg = PyString_AsString(u);
+			}
+		}
+		if (msg == NULL)
+			msg = "unknown decode error";
+		Py_XDECREF(type);
+		Py_XDECREF(value);
+		Py_XDECREF(tb);
+		break;
+	}
+	case E_LINECONT:
+		msg = "unexpected character after line continuation character";
+		break;
+	default:
+		fprintf(stderr, "error=%d\n", err->error);
+		msg = "unknown parsing error";
+		break;
+	}
+	v = Py_BuildValue("(ziiz)", err->filename,
+			  err->lineno, err->offset, err->text);
+	if (err->text != NULL) {
+		PyObject_FREE(err->text);
+		err->text = NULL;
+	}
+	w = NULL;
+	if (v != NULL)
+		w = Py_BuildValue("(sO)", msg, v);
+	Py_XDECREF(u);
+	Py_XDECREF(v);
+	PyErr_SetObject(errtype, w);
+	Py_XDECREF(w);
+}
+
+/* Print fatal error message and abort */
+
+void
+Py_FatalError(const char *msg)
+{
+	fprintf(stderr, "Fatal Python error: %s\n", msg);
+#ifdef MS_WINDOWS
+	OutputDebugString("Fatal Python error: ");
+	OutputDebugString(msg);
+	OutputDebugString("\n");
+#ifdef _DEBUG
+	DebugBreak();
+#endif
+#endif /* MS_WINDOWS */
+	abort();
+}
+
+/* Clean up and exit */
+
+#ifdef WITH_THREAD
+#include "pythread.h"
+#endif
+
+#define NEXITFUNCS 32
+static void (*exitfuncs[NEXITFUNCS])(void);
+static int nexitfuncs = 0;
+
+int Py_AtExit(void (*func)(void))
+{
+	if (nexitfuncs >= NEXITFUNCS)
+		return -1;
+	exitfuncs[nexitfuncs++] = func;
+	return 0;
+}
+
+static void
+call_sys_exitfunc(void)
+{
+	PyObject *exitfunc = PySys_GetObject("exitfunc");
+
+	if (exitfunc) {
+		PyObject *res;
+		Py_INCREF(exitfunc);
+		PySys_SetObject("exitfunc", (PyObject *)NULL);
+		res = PyEval_CallObject(exitfunc, (PyObject *)NULL);
+		if (res == NULL) {
+			if (!PyErr_ExceptionMatches(PyExc_SystemExit)) {
+				PySys_WriteStderr("Error in sys.exitfunc:\n");
+			}
+			PyErr_Print();
+		}
+		Py_DECREF(exitfunc);
+	}
+
+	if (Py_FlushLine())
+		PyErr_Clear();
+}
+
+static void
+call_ll_exitfuncs(void)
+{
+	while (nexitfuncs > 0)
+		(*exitfuncs[--nexitfuncs])();
+
+	fflush(stdout);
+	fflush(stderr);
+}
+
+void
+Py_Exit(int sts)
+{
+	Py_Finalize();
+
+	exit(sts);
+}
+
+static void
+initsigs(void)
+{
+#ifdef SIGPIPE
+	PyOS_setsig(SIGPIPE, SIG_IGN);
+#endif
+#ifdef SIGXFZ
+	PyOS_setsig(SIGXFZ, SIG_IGN);
+#endif
+#ifdef SIGXFSZ
+	PyOS_setsig(SIGXFSZ, SIG_IGN);
+#endif
+	PyOS_InitInterrupts(); /* May imply initsignal() */
+}
+
+
+/*
+ * The file descriptor fd is considered ``interactive'' if either
+ *   a) isatty(fd) is TRUE, or
+ *   b) the -i flag was given, and the filename associated with
+ *      the descriptor is NULL or "<stdin>" or "???".
+ */
+int
+Py_FdIsInteractive(FILE *fp, const char *filename)
+{
+	if (isatty((int)fileno(fp)))
+		return 1;
+	if (!Py_InteractiveFlag)
+		return 0;
+	return (filename == NULL) ||
+	       (strcmp(filename, "<stdin>") == 0) ||
+	       (strcmp(filename, "???") == 0);
+}
+
+
+#if defined(USE_STACKCHECK)
+#if defined(WIN32) && defined(_MSC_VER)
+
+/* Stack checking for Microsoft C */
+
+#include <malloc.h>
+#include <excpt.h>
+
+/*
+ * Return non-zero when we run out of memory on the stack; zero otherwise.
+ */
+int
+PyOS_CheckStack(void)
+{
+	__try {
+		/* alloca throws a stack overflow exception if there's
+		   not enough space left on the stack */
+		alloca(PYOS_STACK_MARGIN * sizeof(void*));
+		return 0;
+	} __except (EXCEPTION_EXECUTE_HANDLER) {
+		/* just ignore all errors */
+	}
+	return 1;
+}
+
+#endif /* WIN32 && _MSC_VER */
+
+/* Alternate implementations can be added here... */
+
+#endif /* USE_STACKCHECK */
+
+
+/* Wrappers around sigaction() or signal(). */
+
+PyOS_sighandler_t
+PyOS_getsig(int sig)
+{
+#ifdef HAVE_SIGACTION
+	struct sigaction context;
+	if (sigaction(sig, NULL, &context) == -1)
+		return SIG_ERR;
+	return context.sa_handler;
+#else
+	PyOS_sighandler_t handler;
+/* Special signal handling for the secure CRT in Visual Studio 2005 */
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+	switch (sig) {
+	/* Only these signals are valid */
+	case SIGINT:
+	case SIGILL:
+	case SIGFPE:
+	case SIGSEGV:
+	case SIGTERM:
+	case SIGBREAK:
+	case SIGABRT:
+		break;
+	/* Don't call signal() with other values or it will assert */
+	default:
+		return SIG_ERR;
+	}
+#endif /* _MSC_VER && _MSC_VER >= 1400 */
+	handler = signal(sig, SIG_IGN);
+	if (handler != SIG_ERR)
+		signal(sig, handler);
+	return handler;
+#endif
+}
+
+PyOS_sighandler_t
+PyOS_setsig(int sig, PyOS_sighandler_t handler)
+{
+#ifdef HAVE_SIGACTION
+	struct sigaction context, ocontext;
+	context.sa_handler = handler;
+	sigemptyset(&context.sa_mask);
+	context.sa_flags = 0;
+	if (sigaction(sig, &context, &ocontext) == -1)
+		return SIG_ERR;
+	return ocontext.sa_handler;
+#else
+	PyOS_sighandler_t oldhandler;
+	oldhandler = signal(sig, handler);
+#ifdef HAVE_SIGINTERRUPT
+	siginterrupt(sig, 1);
+#endif
+	return oldhandler;
+#endif
+}
+
+/* Deprecated C API functions still provided for binary compatiblity */
+
+#undef PyParser_SimpleParseFile
+PyAPI_FUNC(node *)
+PyParser_SimpleParseFile(FILE *fp, const char *filename, int start)
+{
+	return PyParser_SimpleParseFileFlags(fp, filename, start, 0);
+}
+
+#undef PyParser_SimpleParseString
+PyAPI_FUNC(node *)
+PyParser_SimpleParseString(const char *str, int start)
+{
+	return PyParser_SimpleParseStringFlags(str, start, 0);
+}
+
+#undef PyRun_AnyFile
+PyAPI_FUNC(int)
+PyRun_AnyFile(FILE *fp, const char *name)
+{
+	return PyRun_AnyFileExFlags(fp, name, 0, NULL);
+}
+
+#undef PyRun_AnyFileEx
+PyAPI_FUNC(int)
+PyRun_AnyFileEx(FILE *fp, const char *name, int closeit)
+{
+	return PyRun_AnyFileExFlags(fp, name, closeit, NULL);
+}
+
+#undef PyRun_AnyFileFlags
+PyAPI_FUNC(int)
+PyRun_AnyFileFlags(FILE *fp, const char *name, PyCompilerFlags *flags)
+{
+	return PyRun_AnyFileExFlags(fp, name, 0, flags);
+}
+
+#undef PyRun_File
+PyAPI_FUNC(PyObject *)
+PyRun_File(FILE *fp, const char *p, int s, PyObject *g, PyObject *l)
+{
+        return PyRun_FileExFlags(fp, p, s, g, l, 0, NULL);
+}
+
+#undef PyRun_FileEx
+PyAPI_FUNC(PyObject *)
+PyRun_FileEx(FILE *fp, const char *p, int s, PyObject *g, PyObject *l, int c)
+{
+        return PyRun_FileExFlags(fp, p, s, g, l, c, NULL);
+}
+
+#undef PyRun_FileFlags
+PyAPI_FUNC(PyObject *)
+PyRun_FileFlags(FILE *fp, const char *p, int s, PyObject *g, PyObject *l,
+		PyCompilerFlags *flags)
+{
+        return PyRun_FileExFlags(fp, p, s, g, l, 0, flags);
+}
+
+#undef PyRun_SimpleFile
+PyAPI_FUNC(int)
+PyRun_SimpleFile(FILE *f, const char *p)
+{
+	return PyRun_SimpleFileExFlags(f, p, 0, NULL);
+}
+
+#undef PyRun_SimpleFileEx
+PyAPI_FUNC(int)
+PyRun_SimpleFileEx(FILE *f, const char *p, int c)
+{
+	return PyRun_SimpleFileExFlags(f, p, c, NULL);
+}
+
+
+#undef PyRun_String
+PyAPI_FUNC(PyObject *)
+PyRun_String(const char *str, int s, PyObject *g, PyObject *l)
+{
+	return PyRun_StringFlags(str, s, g, l, NULL);
+}
+
+#undef PyRun_SimpleString
+PyAPI_FUNC(int)
+PyRun_SimpleString(const char *s)
+{
+	return PyRun_SimpleStringFlags(s, NULL);
+}
+
+#undef Py_CompileString
+PyAPI_FUNC(PyObject *)
+Py_CompileString(const char *str, const char *p, int s)
+{
+	return Py_CompileStringFlags(str, p, s, NULL);
+}
+
+#undef PyRun_InteractiveOne
+PyAPI_FUNC(int)
+PyRun_InteractiveOne(FILE *f, const char *p)
+{
+	return PyRun_InteractiveOneFlags(f, p, NULL);
+}
+
+#undef PyRun_InteractiveLoop
+PyAPI_FUNC(int)
+PyRun_InteractiveLoop(FILE *f, const char *p)
+{
+	return PyRun_InteractiveLoopFlags(f, p, NULL);
+}
+
+#ifdef __cplusplus
+}
+#endif
+

Added: vendor/Python/current/Python/sigcheck.c
===================================================================
--- vendor/Python/current/Python/sigcheck.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/sigcheck.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,19 @@
+
+/* Sigcheck is similar to intrcheck() but sets an exception when an
+   interrupt occurs.  It can't be in the intrcheck.c file since that
+   file (and the whole directory it is in) doesn't know about objects
+   or exceptions.  It can't be in errors.c because it can be
+   overridden (at link time) by a more powerful version implemented in
+   signalmodule.c. */
+
+#include "Python.h"
+
+/* ARGSUSED */
+int
+PyErr_CheckSignals(void)
+{
+	if (!PyOS_InterruptOccurred())
+		return 0;
+	PyErr_SetNone(PyExc_KeyboardInterrupt);
+	return -1;
+}

Added: vendor/Python/current/Python/strdup.c
===================================================================
--- vendor/Python/current/Python/strdup.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/strdup.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,14 @@
+/* strdup() replacement (from stdwin, if you must know) */
+
+#include "pgenheaders.h"
+
+char *
+strdup(const char *str)
+{
+	if (str != NULL) {
+		register char *copy = malloc(strlen(str) + 1);
+		if (copy != NULL)
+			return strcpy(copy, str);
+	}
+	return NULL;
+}

Added: vendor/Python/current/Python/strerror.c
===================================================================
--- vendor/Python/current/Python/strerror.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/strerror.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,19 @@
+
+/* PD implementation of strerror() for systems that don't have it.
+   Author: Guido van Rossum, CWI Amsterdam, Oct. 1990, <guido at cwi.nl>. */
+
+#include <stdio.h>
+#include "Python.h"
+
+extern int sys_nerr;
+extern char *sys_errlist[];
+
+char *
+strerror(int err)
+{
+	static char buf[20];
+	if (err >= 0 && err < sys_nerr)
+		return sys_errlist[err];
+	PyOS_snprintf(buf, sizeof(buf), "Unknown errno %d", err);
+	return buf;
+}

Added: vendor/Python/current/Python/strtod.c
===================================================================
--- vendor/Python/current/Python/strtod.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/strtod.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,156 @@
+#include "pyconfig.h"
+
+/* comp.sources.misc strtod(), as posted in comp.lang.tcl,
+   with bugfix for "123000.0" and acceptance of space after 'e' sign nuked.
+
+   ************************************************************
+   * YOU MUST EDIT THE MACHINE-DEPENDENT DEFINITIONS BELOW!!! *
+   ************************************************************
+*/
+
+/*  File   : stdtod.c (Modified version of str2dbl.c)
+    Author : Richard A. O'Keefe @ Quintus Computer Systems, Inc.
+    Updated: Tuesday August 2nd, 1988
+    Defines: double strtod (char *str, char**ptr)
+*/
+
+/*  This is an implementation of the strtod() function described in the 
+    System V manuals, with a different name to avoid linker problems.
+    All that str2dbl() does itself is check that the argument is well-formed
+    and is in range.  It leaves the work of conversion to atof(), which is
+    assumed to exist and deliver correct results (if they can be represented).
+
+    There are two reasons why this should be provided to the net:
+    (a) some UNIX systems do not yet have strtod(), or do not have it
+        available in the BSD "universe" (but they do have atof()).
+    (b) some of the UNIX systems that *do* have it get it wrong.
+	(some crash with large arguments, some assign the wrong *ptr value).
+    There is a reason why *we* are providing it: we need a correct version
+    of strtod(), and if we give this one away maybe someone will look for
+    mistakes in it and fix them for us (:-).
+*/
+    
+/*  The following constants are machine-specific.  MD{MIN,MAX}EXPT are
+    integers and MD{MIN,MAX}FRAC are strings such that
+	0.${MDMAXFRAC}e${MDMAXEXPT} is the largest representable double,
+	0.${MDMINFRAC}e${MDMINEXPT} is the smallest representable +ve double
+    MD{MIN,MAX}FRAC must not have any trailing zeros.
+    The values here are for IEEE-754 64-bit floats.
+    It is not perfectly clear to me whether an IEEE infinity should be
+    returned for overflow, nor what a portable way of writing one is,
+    so HUGE is just 0.MAXFRAC*10**MAXEXPT (this seems still to be the
+    UNIX convention).
+
+    I do know about <values.h>, but the whole point of this file is that
+    we can't always trust that stuff to be there or to be correct.
+*/
+static	int	MDMINEXPT	= {-323};
+static	char	MDMINFRAC[]	= "494065645841246544";
+static	double	ZERO		= 0.0;
+
+static	int	MDMAXEXPT	= { 309};
+static	char	MDMAXFRAC[]	= "17976931348623157";
+static	double	HUGE		= 1.7976931348623157e308;
+
+extern	double	atof(const char *);		/* Only called when result known to be ok */
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+extern	int	errno;
+
+double strtod(char *str, char **ptr)
+{
+	int sign, scale, dotseen;
+	int esign, expt;
+	char *save;
+	register char *sp, *dp;
+	register int c;
+	char *buforg, *buflim;
+	char buffer[64];		/* 45-digit significant + */
+					/* 13-digit exponent */
+	sp = str;
+	while (*sp == ' ') sp++;
+	sign = 1;
+	if (*sp == '-') sign -= 2, sp++;
+	dotseen = 0, scale = 0;
+	dp = buffer;	
+	*dp++ = '0'; *dp++ = '.';
+	buforg = dp, buflim = buffer+48;
+	for (save = sp; c = *sp; sp++)
+	    if (c == '.') {
+		if (dotseen) break;
+		dotseen++;
+	    } else
+	    if ((unsigned)(c-'0') > (unsigned)('9'-'0')) {
+		break;
+	    } else
+	    if (c == '0') {
+		if (dp != buforg) {
+		    /* This is not the first digit, so we want to keep it */
+		    if (dp < buflim) *dp++ = c;
+		    if (!dotseen) scale++;
+		} else {
+		    /* No non-zero digits seen yet */
+		    /* If a . has been seen, scale must be adjusted */
+		    if (dotseen) scale--;
+		}
+	    } else {
+		/* This is a nonzero digit, so we want to keep it */
+		if (dp < buflim) *dp++ = c;
+		/* If it precedes a ., scale must be adjusted */
+		if (!dotseen) scale++;
+	    }
+	if (sp == save) {
+	    if (ptr) *ptr = str;
+	    errno = EDOM;		/* what should this be? */
+	    return ZERO;
+	}
+	
+	while (dp > buforg && dp[-1] == '0') --dp;
+	if (dp == buforg) *dp++ = '0';
+	*dp = '\0';
+	/*  Now the contents of buffer are
+	    +--+--------+-+--------+
+	    |0.|fraction|\|leftover|
+	    +--+--------+-+--------+
+			 ^dp points here
+	    where fraction begins with 0 iff it is "0", and has at most
+	    45 digits in it, and leftover is at least 16 characters.
+	*/
+	save = sp, expt = 0, esign = 1;
+	do {
+	    c = *sp++;
+	    if (c != 'e' && c != 'E') break;
+	    c = *sp++;
+	    if (c == '-') esign -= 2, c = *sp++; else
+	    if (c == '+' /* || c == ' ' */ ) c = *sp++;
+	    if ((unsigned)(c-'0') > (unsigned)('9'-'0')) break;
+	    while (c == '0') c = *sp++;
+	    for (; (unsigned)(c-'0') <= (unsigned)('9'-'0'); c = *sp++)
+		expt = expt*10 + c-'0';	    
+	    if (esign < 0) expt = -expt;
+	    save = sp-1;
+	} while (0);
+	if (ptr) *ptr = save;
+	expt += scale;
+	/*  Now the number is sign*0.fraction*10**expt  */
+	errno = ERANGE;
+	if (expt > MDMAXEXPT) {
+	    return HUGE*sign;
+	} else
+	if (expt == MDMAXEXPT) {
+	    if (strcmp(buforg, MDMAXFRAC) > 0) return HUGE*sign;
+	} else
+	if (expt < MDMINEXPT) {
+	    return ZERO*sign;
+	} else
+	if (expt == MDMINEXPT) {
+	    if (strcmp(buforg, MDMINFRAC) < 0) return ZERO*sign;
+	}
+	/*  We have now established that the number can be  */
+	/*  represented without overflow or underflow  */
+	(void) sprintf(dp, "E%d", expt);
+	errno = 0;
+	return atof(buffer)*sign;
+}

Added: vendor/Python/current/Python/structmember.c
===================================================================
--- vendor/Python/current/Python/structmember.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/structmember.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,312 @@
+
+/* Map C struct members to Python object attributes */
+
+#include "Python.h"
+
+#include "structmember.h"
+
+static PyObject *
+listmembers(struct memberlist *mlist)
+{
+	int i, n;
+	PyObject *v;
+	for (n = 0; mlist[n].name != NULL; n++)
+		;
+	v = PyList_New(n);
+	if (v != NULL) {
+		for (i = 0; i < n; i++)
+			PyList_SetItem(v, i,
+				       PyString_FromString(mlist[i].name));
+		if (PyErr_Occurred()) {
+			Py_DECREF(v);
+			v = NULL;
+		}
+		else {
+			PyList_Sort(v);
+		}
+	}
+	return v;
+}
+
+PyObject *
+PyMember_Get(const char *addr, struct memberlist *mlist, const char *name)
+{
+	struct memberlist *l;
+
+	if (strcmp(name, "__members__") == 0)
+		return listmembers(mlist);
+	for (l = mlist; l->name != NULL; l++) {
+		if (strcmp(l->name, name) == 0) {
+			PyMemberDef copy;
+			copy.name = l->name;
+			copy.type = l->type;
+			copy.offset = l->offset;
+			copy.flags = l->flags;
+			copy.doc = NULL;
+			return PyMember_GetOne(addr, &copy);
+		}
+	}
+	PyErr_SetString(PyExc_AttributeError, name);
+	return NULL;
+}
+
+PyObject *
+PyMember_GetOne(const char *addr, PyMemberDef *l)
+{
+	PyObject *v;
+	if ((l->flags & READ_RESTRICTED) &&
+	    PyEval_GetRestricted()) {
+		PyErr_SetString(PyExc_RuntimeError, "restricted attribute");
+		return NULL;
+	}
+	addr += l->offset;
+	switch (l->type) {
+	case T_BYTE:
+		v = PyInt_FromLong(*(char*)addr);
+		break;
+	case T_UBYTE:
+		v = PyLong_FromUnsignedLong(*(unsigned char*)addr);
+		break;
+	case T_SHORT:
+		v = PyInt_FromLong(*(short*)addr);
+		break;
+	case T_USHORT:
+		v = PyLong_FromUnsignedLong(*(unsigned short*)addr);
+		break;
+	case T_INT:
+		v = PyInt_FromLong(*(int*)addr);
+		break;
+	case T_UINT:
+		v = PyLong_FromUnsignedLong(*(unsigned int*)addr);
+		break;
+	case T_LONG:
+		v = PyInt_FromLong(*(long*)addr);
+		break;
+	case T_ULONG:
+		v = PyLong_FromUnsignedLong(*(unsigned long*)addr);
+		break;
+	case T_FLOAT:
+		v = PyFloat_FromDouble((double)*(float*)addr);
+		break;
+	case T_DOUBLE:
+		v = PyFloat_FromDouble(*(double*)addr);
+		break;
+	case T_STRING:
+		if (*(char**)addr == NULL) {
+			Py_INCREF(Py_None);
+			v = Py_None;
+		}
+		else
+			v = PyString_FromString(*(char**)addr);
+		break;
+	case T_STRING_INPLACE:
+		v = PyString_FromString((char*)addr);
+		break;
+	case T_CHAR:
+		v = PyString_FromStringAndSize((char*)addr, 1);
+		break;
+	case T_OBJECT:
+		v = *(PyObject **)addr;
+		if (v == NULL)
+			v = Py_None;
+		Py_INCREF(v);
+		break;
+	case T_OBJECT_EX:
+		v = *(PyObject **)addr;
+		if (v == NULL)
+			PyErr_SetString(PyExc_AttributeError, l->name);
+		Py_XINCREF(v);
+		break;
+#ifdef HAVE_LONG_LONG
+	case T_LONGLONG:
+		v = PyLong_FromLongLong(*(PY_LONG_LONG *)addr);
+		break;
+	case T_ULONGLONG:
+		v = PyLong_FromUnsignedLongLong(*(unsigned PY_LONG_LONG *)addr);
+		break;
+#endif /* HAVE_LONG_LONG */
+	default:
+		PyErr_SetString(PyExc_SystemError, "bad memberdescr type");
+		v = NULL;
+	}
+	return v;
+}
+
+int
+PyMember_Set(char *addr, struct memberlist *mlist, const char *name, PyObject *v)
+{
+	struct memberlist *l;
+
+	for (l = mlist; l->name != NULL; l++) {
+		if (strcmp(l->name, name) == 0) {
+			PyMemberDef copy;
+			copy.name = l->name;
+			copy.type = l->type;
+			copy.offset = l->offset;
+			copy.flags = l->flags;
+			copy.doc = NULL;
+			return PyMember_SetOne(addr, &copy, v);
+		}
+	}
+
+	PyErr_SetString(PyExc_AttributeError, name);
+	return -1;
+}
+
+int
+PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
+{
+	PyObject *oldv;
+
+	if ((l->flags & READONLY) || l->type == T_STRING)
+	{
+		PyErr_SetString(PyExc_TypeError, "readonly attribute");
+		return -1;
+	}
+	if ((l->flags & WRITE_RESTRICTED) && PyEval_GetRestricted()) {
+		PyErr_SetString(PyExc_RuntimeError, "restricted attribute");
+		return -1;
+	}
+	if (v == NULL && l->type != T_OBJECT_EX && l->type != T_OBJECT) {
+		PyErr_SetString(PyExc_TypeError,
+				"can't delete numeric/char attribute");
+		return -1;
+	}
+	addr += l->offset;
+	switch (l->type) {
+	case T_BYTE:{
+		long long_val;
+		long_val = PyInt_AsLong(v);
+		if ((long_val == -1) && PyErr_Occurred())
+			return -1;
+		*(char*)addr = (char)long_val;
+		break;
+		}
+	case T_UBYTE:{
+		long long_val;
+		long_val = PyInt_AsLong(v);
+		if ((long_val == -1) && PyErr_Occurred())
+			return -1;
+		*(unsigned char*)addr = (unsigned char)long_val;
+		break;
+		}
+	case T_SHORT:{
+		long long_val;
+		long_val = PyInt_AsLong(v);
+		if ((long_val == -1) && PyErr_Occurred())
+			return -1;
+		*(short*)addr = (short)long_val;
+		break;
+		}
+	case T_USHORT:{
+		long long_val;
+		long_val = PyInt_AsLong(v);
+		if ((long_val == -1) && PyErr_Occurred())
+			return -1;
+		*(unsigned short*)addr = (unsigned short)long_val;
+		break;
+		}
+  	case T_INT:{
+		long long_val;
+		long_val = PyInt_AsLong(v);
+		if ((long_val == -1) && PyErr_Occurred())
+			return -1;
+		*(int *)addr = (int)long_val;
+		break;
+		}
+	case T_UINT:{
+		unsigned long ulong_val;
+		ulong_val = PyLong_AsUnsignedLong(v);
+		if ((ulong_val == (unsigned int)-1) && PyErr_Occurred()) {
+			/* XXX: For compatibility, accept negative int values
+			   as well. */
+			PyErr_Clear();
+			ulong_val = PyLong_AsLong(v);
+			if ((ulong_val == (unsigned int)-1) && PyErr_Occurred())
+				return -1;
+		}
+		*(unsigned int *)addr = (unsigned int)ulong_val;
+		break;
+		}
+	case T_LONG:{
+		*(long*)addr = PyLong_AsLong(v);
+		if ((*(long*)addr == -1) && PyErr_Occurred())
+			return -1;
+		break;
+		}
+	case T_ULONG:{
+		*(unsigned long*)addr = PyLong_AsUnsignedLong(v);
+		if ((*(unsigned long*)addr == (unsigned long)-1)
+		    && PyErr_Occurred()) {
+			/* XXX: For compatibility, accept negative int values
+			   as well. */
+			PyErr_Clear();
+			*(unsigned long*)addr = PyLong_AsLong(v);
+			if ((*(unsigned long*)addr == (unsigned int)-1) && PyErr_Occurred())
+				return -1;
+		}
+		break;
+		}
+	case T_FLOAT:{
+		double double_val;
+		double_val = PyFloat_AsDouble(v);
+		if ((double_val == -1) && PyErr_Occurred())
+			return -1;
+		*(float*)addr = (float)double_val;
+		break;
+		}
+	case T_DOUBLE:
+		*(double*)addr = PyFloat_AsDouble(v);
+		if ((*(double*)addr == -1) && PyErr_Occurred())
+			return -1;
+		break;
+	case T_OBJECT:
+	case T_OBJECT_EX:
+		Py_XINCREF(v);
+		oldv = *(PyObject **)addr;
+		*(PyObject **)addr = v;
+		Py_XDECREF(oldv);
+		break;
+	case T_CHAR:
+		if (PyString_Check(v) && PyString_Size(v) == 1) {
+			*(char*)addr = PyString_AsString(v)[0];
+		}
+		else {
+			PyErr_BadArgument();
+			return -1;
+		}
+		break;
+#ifdef HAVE_LONG_LONG
+	case T_LONGLONG:
+		if (!PyLong_Check(v)) {
+			PyErr_BadArgument();
+			return -1;
+		} else {
+                        PY_LONG_LONG value;
+                        *(PY_LONG_LONG*)addr = value = PyLong_AsLongLong(v);
+                        if ((value == -1) && PyErr_Occurred()) {
+                                return -1;
+                        }
+                }
+                break;
+	case T_ULONGLONG:
+                if (!PyLong_Check(v)) {
+                        PyErr_BadArgument();
+                        return -1;
+                } else {
+                        unsigned PY_LONG_LONG value;
+                        *(unsigned PY_LONG_LONG*)addr = value = PyLong_AsUnsignedLongLong(v);
+                        if ((value == (unsigned PY_LONG_LONG)-1) &&
+			    PyErr_Occurred()) {
+                                return -1;
+                        }
+                }
+                break;
+#endif /* HAVE_LONG_LONG */
+	default:
+		PyErr_Format(PyExc_SystemError,
+			     "bad memberdescr type for %s", l->name);
+		return -1;
+	}
+	return 0;
+}

Added: vendor/Python/current/Python/symtable.c
===================================================================
--- vendor/Python/current/Python/symtable.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/symtable.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1425 @@
+#include "Python.h"
+#include "Python-ast.h"
+#include "code.h"
+#include "symtable.h"
+#include "structmember.h"
+
+/* error strings used for warnings */
+#define GLOBAL_AFTER_ASSIGN \
+"name '%.400s' is assigned to before global declaration"
+
+#define GLOBAL_AFTER_USE \
+"name '%.400s' is used prior to global declaration"
+
+#define IMPORT_STAR_WARNING "import * only allowed at module level"
+
+#define RETURN_VAL_IN_GENERATOR \
+    "'return' with argument inside generator"
+
+/* XXX(nnorwitz): change name since static? */
+static PySTEntryObject *
+PySTEntry_New(struct symtable *st, identifier name, _Py_block_ty block,
+	      void *key, int lineno)
+{
+	PySTEntryObject *ste = NULL;
+	PyObject *k;
+
+	k = PyLong_FromVoidPtr(key);
+	if (k == NULL)
+		goto fail;
+	ste = (PySTEntryObject *)PyObject_New(PySTEntryObject,
+					      &PySTEntry_Type);
+	ste->ste_table = st;
+	ste->ste_id = k;
+	ste->ste_tmpname = 0;
+
+	ste->ste_name = name;
+	Py_INCREF(name);
+
+	ste->ste_symbols = NULL;
+	ste->ste_varnames = NULL;
+	ste->ste_children = NULL;
+
+	ste->ste_symbols = PyDict_New();
+	if (ste->ste_symbols == NULL)
+	    goto fail;
+
+	ste->ste_varnames = PyList_New(0);
+	if (ste->ste_varnames == NULL)
+	    goto fail;
+
+	ste->ste_children = PyList_New(0);
+	if (ste->ste_children == NULL)
+	    goto fail;
+
+	ste->ste_type = block;
+	ste->ste_unoptimized = 0;
+	ste->ste_nested = 0;
+	ste->ste_free = 0;
+	ste->ste_varargs = 0;
+	ste->ste_varkeywords = 0;
+	ste->ste_opt_lineno = 0;
+	ste->ste_tmpname = 0;
+	ste->ste_lineno = lineno;
+
+	if (st->st_cur != NULL &&
+	    (st->st_cur->ste_nested ||
+	     st->st_cur->ste_type == FunctionBlock))
+		ste->ste_nested = 1;
+	ste->ste_child_free = 0;
+	ste->ste_generator = 0;
+	ste->ste_returns_value = 0;
+
+	if (PyDict_SetItem(st->st_symbols, ste->ste_id, (PyObject *)ste) < 0)
+	    goto fail;
+	
+	return ste;
+ fail:
+	Py_XDECREF(ste);
+	return NULL;
+}
+
+static PyObject *
+ste_repr(PySTEntryObject *ste)
+{
+	char buf[256];
+
+	PyOS_snprintf(buf, sizeof(buf),
+		      "<symtable entry %.100s(%ld), line %d>",
+		      PyString_AS_STRING(ste->ste_name),
+		      PyInt_AS_LONG(ste->ste_id), ste->ste_lineno);
+	return PyString_FromString(buf);
+}
+
+static void
+ste_dealloc(PySTEntryObject *ste)
+{
+	ste->ste_table = NULL;
+	Py_XDECREF(ste->ste_id);
+	Py_XDECREF(ste->ste_name);
+	Py_XDECREF(ste->ste_symbols);
+	Py_XDECREF(ste->ste_varnames);
+	Py_XDECREF(ste->ste_children);
+	PyObject_Del(ste);
+}
+
+#define OFF(x) offsetof(PySTEntryObject, x)
+
+static PyMemberDef ste_memberlist[] = {
+	{"id",       T_OBJECT, OFF(ste_id), READONLY},
+	{"name",     T_OBJECT, OFF(ste_name), READONLY},
+	{"symbols",  T_OBJECT, OFF(ste_symbols), READONLY},
+	{"varnames", T_OBJECT, OFF(ste_varnames), READONLY},
+	{"children", T_OBJECT, OFF(ste_children), READONLY},
+	{"type",     T_INT,    OFF(ste_type), READONLY},
+	{"lineno",   T_INT,    OFF(ste_lineno), READONLY},
+	{NULL}
+};
+
+PyTypeObject PySTEntry_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,
+	"symtable entry",
+	sizeof(PySTEntryObject),
+	0,
+	(destructor)ste_dealloc,                /* tp_dealloc */
+	0,                                      /* tp_print */
+	0,			               /* tp_getattr */
+	0,					/* tp_setattr */
+	0,			                /* tp_compare */
+	(reprfunc)ste_repr,			/* tp_repr */
+	0,					/* tp_as_number */
+	0,			                /* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT,	                /* tp_flags */
+ 	0,					/* tp_doc */
+	0,					/* tp_traverse */
+	0,					/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	0,					/* tp_methods */
+	ste_memberlist,				/* tp_members */
+	0,					/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	0,					/* tp_init */
+	0,					/* tp_alloc */
+	0,					/* tp_new */
+};
+
+static int symtable_analyze(struct symtable *st);
+static int symtable_warn(struct symtable *st, char *msg, int lineno);
+static int symtable_enter_block(struct symtable *st, identifier name, 
+				_Py_block_ty block, void *ast, int lineno);
+static int symtable_exit_block(struct symtable *st, void *ast);
+static int symtable_visit_stmt(struct symtable *st, stmt_ty s);
+static int symtable_visit_expr(struct symtable *st, expr_ty s);
+static int symtable_visit_genexp(struct symtable *st, expr_ty s);
+static int symtable_visit_arguments(struct symtable *st, arguments_ty);
+static int symtable_visit_excepthandler(struct symtable *st, excepthandler_ty);
+static int symtable_visit_alias(struct symtable *st, alias_ty);
+static int symtable_visit_comprehension(struct symtable *st, comprehension_ty);
+static int symtable_visit_keyword(struct symtable *st, keyword_ty);
+static int symtable_visit_slice(struct symtable *st, slice_ty);
+static int symtable_visit_params(struct symtable *st, asdl_seq *args, int top);
+static int symtable_visit_params_nested(struct symtable *st, asdl_seq *args);
+static int symtable_implicit_arg(struct symtable *st, int pos);
+
+
+static identifier top = NULL, lambda = NULL, genexpr = NULL;
+
+#define GET_IDENTIFIER(VAR) \
+	((VAR) ? (VAR) : ((VAR) = PyString_InternFromString(# VAR)))
+
+#define DUPLICATE_ARGUMENT \
+"duplicate argument '%s' in function definition"
+
+static struct symtable *
+symtable_new(void)
+{
+	struct symtable *st;
+
+	st = (struct symtable *)PyMem_Malloc(sizeof(struct symtable));
+	if (st == NULL)
+		return NULL;
+
+	st->st_filename = NULL;
+	st->st_symbols = NULL;
+
+	if ((st->st_stack = PyList_New(0)) == NULL)
+		goto fail;
+	if ((st->st_symbols = PyDict_New()) == NULL)
+		goto fail; 
+	st->st_cur = NULL;
+	st->st_tmpname = 0;
+	st->st_private = NULL;
+	return st;
+ fail:
+	PySymtable_Free(st);
+	return NULL;
+}
+
+struct symtable *
+PySymtable_Build(mod_ty mod, const char *filename, PyFutureFeatures *future)
+{
+	struct symtable *st = symtable_new();
+	asdl_seq *seq;
+	int i;
+
+	if (st == NULL)
+		return st;
+	st->st_filename = filename;
+	st->st_future = future;
+	if (!symtable_enter_block(st, GET_IDENTIFIER(top), ModuleBlock, 
+			     (void *)mod, 0)) {
+		PySymtable_Free(st);
+		return NULL;
+	}
+
+	st->st_top = st->st_cur;
+	st->st_cur->ste_unoptimized = OPT_TOPLEVEL;
+	/* Any other top-level initialization? */
+	switch (mod->kind) {
+	case Module_kind:
+		seq = mod->v.Module.body;
+		for (i = 0; i < asdl_seq_LEN(seq); i++)
+			if (!symtable_visit_stmt(st, 
+                                    (stmt_ty)asdl_seq_GET(seq, i)))
+				goto error;
+		break;
+	case Expression_kind:
+		if (!symtable_visit_expr(st, mod->v.Expression.body))
+			goto error;
+		break;
+	case Interactive_kind:
+		seq = mod->v.Interactive.body;
+		for (i = 0; i < asdl_seq_LEN(seq); i++)
+			if (!symtable_visit_stmt(st, 
+                                    (stmt_ty)asdl_seq_GET(seq, i)))
+				goto error;
+		break;
+	case Suite_kind:
+		PyErr_SetString(PyExc_RuntimeError,
+				"this compiler does not handle Suites");
+		goto error;
+	}
+	if (!symtable_exit_block(st, (void *)mod)) {
+		PySymtable_Free(st);
+		return NULL;
+	}
+	if (symtable_analyze(st))
+		return st;
+	PySymtable_Free(st);
+	return NULL;
+ error:
+	(void) symtable_exit_block(st, (void *)mod);
+	PySymtable_Free(st);
+	return NULL;
+}
+
+void
+PySymtable_Free(struct symtable *st)
+{
+	Py_XDECREF(st->st_symbols);
+	Py_XDECREF(st->st_stack);
+	PyMem_Free((void *)st);
+}
+
+PySTEntryObject *
+PySymtable_Lookup(struct symtable *st, void *key)
+{
+	PyObject *k, *v;
+
+	k = PyLong_FromVoidPtr(key);
+	if (k == NULL)
+		return NULL;
+	v = PyDict_GetItem(st->st_symbols, k);
+	if (v) {
+		assert(PySTEntry_Check(v));
+		Py_INCREF(v);
+	}
+	else {
+		PyErr_SetString(PyExc_KeyError,
+				"unknown symbol table entry");
+	}
+
+	Py_DECREF(k);
+	return (PySTEntryObject *)v;
+}
+
+int 
+PyST_GetScope(PySTEntryObject *ste, PyObject *name)
+{
+	PyObject *v = PyDict_GetItem(ste->ste_symbols, name);
+	if (!v)
+		return 0;
+	assert(PyInt_Check(v));
+	return (PyInt_AS_LONG(v) >> SCOPE_OFF) & SCOPE_MASK;
+}
+
+
+/* Analyze raw symbol information to determine scope of each name.
+
+   The next several functions are helpers for PySymtable_Analyze(),
+   which determines whether a name is local, global, or free.  In addition, 
+   it determines which local variables are cell variables; they provide
+   bindings that are used for free variables in enclosed blocks.  
+
+   There are also two kinds of free variables, implicit and explicit.  An 
+   explicit global is declared with the global statement.  An implicit
+   global is a free variable for which the compiler has found no binding
+   in an enclosing function scope.  The implicit global is either a global
+   or a builtin.  Python's module and class blocks use the xxx_NAME opcodes
+   to handle these names to implement slightly odd semantics.  In such a
+   block, the name is treated as global until it is assigned to; then it
+   is treated as a local.
+
+   The symbol table requires two passes to determine the scope of each name.
+   The first pass collects raw facts from the AST: the name is a parameter 
+   here, the name is used by not defined here, etc.  The second pass analyzes
+   these facts during a pass over the PySTEntryObjects created during pass 1.
+
+   When a function is entered during the second pass, the parent passes
+   the set of all name bindings visible to its children.  These bindings 
+   are used to determine if the variable is free or an implicit global.
+   After doing the local analysis, it analyzes each of its child blocks
+   using an updated set of name bindings.  
+
+   The children update the free variable set.  If a local variable is free 
+   in a child, the variable is marked as a cell.  The current function must 
+   provide runtime storage for the variable that may outlive the function's 
+   frame.  Cell variables are removed from the free set before the analyze
+   function returns to its parent.
+   
+   The sets of bound and free variables are implemented as dictionaries
+   mapping strings to None.
+*/
+
+#define SET_SCOPE(DICT, NAME, I) { \
+	PyObject *o = PyInt_FromLong(I); \
+	if (!o) \
+		return 0; \
+	if (PyDict_SetItem((DICT), (NAME), o) < 0) { \
+		Py_DECREF(o); \
+		return 0; \
+	} \
+	Py_DECREF(o); \
+}
+
+/* Decide on scope of name, given flags.
+
+   The dicts passed in as arguments are modified as necessary.
+   ste is passed so that flags can be updated.
+*/
+
+static int 
+analyze_name(PySTEntryObject *ste, PyObject *dict, PyObject *name, long flags,
+	     PyObject *bound, PyObject *local, PyObject *free, 
+	     PyObject *global)
+{
+	if (flags & DEF_GLOBAL) {
+		if (flags & DEF_PARAM) {
+			PyErr_Format(PyExc_SyntaxError,
+				     "name '%s' is local and global",
+				     PyString_AS_STRING(name));
+			return 0;
+		}
+		SET_SCOPE(dict, name, GLOBAL_EXPLICIT);
+		if (PyDict_SetItem(global, name, Py_None) < 0)
+			return 0;
+		if (bound && PyDict_GetItem(bound, name)) {
+			if (PyDict_DelItem(bound, name) < 0)
+				return 0;
+		}
+		return 1;
+	}
+	if (flags & DEF_BOUND) {
+		SET_SCOPE(dict, name, LOCAL);
+		if (PyDict_SetItem(local, name, Py_None) < 0)
+			return 0;
+		if (PyDict_GetItem(global, name)) {
+			if (PyDict_DelItem(global, name) < 0)
+				return 0;
+		}
+		return 1;
+	}
+	/* If an enclosing block has a binding for this name, it
+	   is a free variable rather than a global variable.
+	   Note that having a non-NULL bound implies that the block
+	   is nested.
+	*/
+	if (bound && PyDict_GetItem(bound, name)) {
+		SET_SCOPE(dict, name, FREE);
+		ste->ste_free = 1;
+		if (PyDict_SetItem(free, name, Py_None) < 0)
+			return 0;
+		return 1;
+	}
+	/* If a parent has a global statement, then call it global
+	   explicit?  It could also be global implicit.
+	 */
+	else if (global && PyDict_GetItem(global, name)) {
+		SET_SCOPE(dict, name, GLOBAL_EXPLICIT);
+		return 1;
+	}
+	else {
+		if (ste->ste_nested)
+			ste->ste_free = 1;
+		SET_SCOPE(dict, name, GLOBAL_IMPLICIT);
+		return 1;
+	}
+	return 0; /* Can't get here */
+}
+
+#undef SET_SCOPE
+
+/* If a name is defined in free and also in locals, then this block
+   provides the binding for the free variable.  The name should be
+   marked CELL in this block and removed from the free list.
+
+   Note that the current block's free variables are included in free.
+   That's safe because no name can be free and local in the same scope.
+*/
+
+static int
+analyze_cells(PyObject *scope, PyObject *free)
+{
+        PyObject *name, *v, *w;
+	int success = 0;
+	Py_ssize_t pos = 0;
+
+	w = PyInt_FromLong(CELL);
+	if (!w)
+		return 0;
+	while (PyDict_Next(scope, &pos, &name, &v)) {
+		long flags;
+		assert(PyInt_Check(v));
+		flags = PyInt_AS_LONG(v);
+		if (flags != LOCAL)
+			continue;
+		if (!PyDict_GetItem(free, name))
+			continue;
+		/* Replace LOCAL with CELL for this name, and remove
+		   from free. It is safe to replace the value of name 
+		   in the dict, because it will not cause a resize.
+		 */
+		if (PyDict_SetItem(scope, name, w) < 0)
+			goto error;
+		if (!PyDict_DelItem(free, name) < 0)
+			goto error;
+	}
+	success = 1;
+ error:
+	Py_DECREF(w);
+	return success;
+}
+
+/* Check for illegal statements in unoptimized namespaces */
+static int
+check_unoptimized(const PySTEntryObject* ste) {
+	char buf[300];
+	const char* trailer;
+
+	if (ste->ste_type != FunctionBlock || !ste->ste_unoptimized
+	    || !(ste->ste_free || ste->ste_child_free))
+		return 1;
+
+	trailer = (ste->ste_child_free ? 
+		       "contains a nested function with free variables" :
+			       "is a nested function");
+
+	switch (ste->ste_unoptimized) {
+	case OPT_TOPLEVEL: /* exec / import * at top-level is fine */
+	case OPT_EXEC: /* qualified exec is fine */
+		return 1;
+	case OPT_IMPORT_STAR:
+		PyOS_snprintf(buf, sizeof(buf), 
+			      "import * is not allowed in function '%.100s' "
+			      "because it is %s",
+			      PyString_AS_STRING(ste->ste_name), trailer);
+		break;
+	case OPT_BARE_EXEC:
+		PyOS_snprintf(buf, sizeof(buf),
+			      "unqualified exec is not allowed in function "
+			      "'%.100s' it %s",
+			      PyString_AS_STRING(ste->ste_name), trailer);
+		break;
+	default:
+		PyOS_snprintf(buf, sizeof(buf), 
+			      "function '%.100s' uses import * and bare exec, "
+			      "which are illegal because it %s",
+			      PyString_AS_STRING(ste->ste_name), trailer);
+		break;
+	}
+
+	PyErr_SetString(PyExc_SyntaxError, buf);
+	PyErr_SyntaxLocation(ste->ste_table->st_filename, 
+			     ste->ste_opt_lineno);
+	return 0;
+}
+
+/* Enter the final scope information into the st_symbols dict. 
+ * 
+ * All arguments are dicts.  Modifies symbols, others are read-only.
+*/
+static int
+update_symbols(PyObject *symbols, PyObject *scope, 
+               PyObject *bound, PyObject *free, int classflag)
+{
+	PyObject *name, *v, *u, *w, *free_value = NULL;
+	Py_ssize_t pos = 0;
+
+	while (PyDict_Next(symbols, &pos, &name, &v)) {
+		long i, flags;
+		assert(PyInt_Check(v));
+		flags = PyInt_AS_LONG(v);
+		w = PyDict_GetItem(scope, name);
+		assert(w && PyInt_Check(w));
+		i = PyInt_AS_LONG(w);
+		flags |= (i << SCOPE_OFF);
+		u = PyInt_FromLong(flags);
+		if (!u)
+			return 0;
+		if (PyDict_SetItem(symbols, name, u) < 0) {
+			Py_DECREF(u);
+			return 0;
+		}
+		Py_DECREF(u);
+	}
+
+        free_value = PyInt_FromLong(FREE << SCOPE_OFF);
+        if (!free_value)
+		return 0;
+
+        /* add a free variable when it's only use is for creating a closure */
+        pos = 0;
+	while (PyDict_Next(free, &pos, &name, &v)) {
+		PyObject *o = PyDict_GetItem(symbols, name);
+
+		if (o) {
+			/* It could be a free variable in a method of
+			   the class that has the same name as a local
+			   or global in the class scope.
+			*/
+			if  (classflag && 
+			     PyInt_AS_LONG(o) & (DEF_BOUND | DEF_GLOBAL)) {
+				long i = PyInt_AS_LONG(o) | DEF_FREE_CLASS;
+				o = PyInt_FromLong(i);
+				if (!o) {
+					Py_DECREF(free_value);
+					return 0;
+				}
+				if (PyDict_SetItem(symbols, name, o) < 0) {
+					Py_DECREF(o);
+					Py_DECREF(free_value);
+					return 0;
+				}
+				Py_DECREF(o);
+			}
+			/* else it's not free, probably a cell */
+			continue;
+		}
+		if (!PyDict_GetItem(bound, name))
+			continue;       /* it's a global */
+
+		if (PyDict_SetItem(symbols, name, free_value) < 0) {
+			Py_DECREF(free_value);
+			return 0;
+		}
+        }
+        Py_DECREF(free_value);
+	return 1;
+}   
+
+/* Make final symbol table decisions for block of ste.
+   Arguments:
+   ste -- current symtable entry (input/output)
+   bound -- set of variables bound in enclosing scopes (input)
+   free -- set of free variables in enclosed scopes (output)
+   globals -- set of declared global variables in enclosing scopes (input)
+*/
+
+static int
+analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free, 
+	      PyObject *global)
+{
+	PyObject *name, *v, *local = NULL, *scope = NULL, *newbound = NULL;
+	PyObject *newglobal = NULL, *newfree = NULL;
+	int i, success = 0;
+	Py_ssize_t pos = 0;
+
+	local = PyDict_New();
+	if (!local)
+		goto error;
+	scope = PyDict_New();
+	if (!scope)
+		goto error;
+	newglobal = PyDict_New();
+	if (!newglobal)
+		goto error;
+	newfree = PyDict_New();
+	if (!newfree)
+		goto error;
+	newbound = PyDict_New();
+	if (!newbound)
+		goto error;
+
+	if (ste->ste_type == ClassBlock) {
+		/* make a copy of globals before calling analyze_name(),
+		   because global statements in the class have no effect
+		   on nested functions.
+		*/
+		if (PyDict_Update(newglobal, global) < 0)
+			goto error;
+		if (bound)
+			if (PyDict_Update(newbound, bound) < 0)
+				goto error;
+	}
+
+	assert(PySTEntry_Check(ste));
+	assert(PyDict_Check(ste->ste_symbols));
+	while (PyDict_Next(ste->ste_symbols, &pos, &name, &v)) {
+		long flags = PyInt_AS_LONG(v);
+		if (!analyze_name(ste, scope, name, flags, bound, local, free,
+				  global))
+			goto error;
+	}
+
+	if (ste->ste_type != ClassBlock) {
+		if (ste->ste_type == FunctionBlock) {
+			if (PyDict_Update(newbound, local) < 0)
+				goto error;
+		}
+		if (bound) {
+			if (PyDict_Update(newbound, bound) < 0)
+				goto error;
+		}
+		if (PyDict_Update(newglobal, global) < 0)
+			goto error;
+	}
+
+	/* Recursively call analyze_block() on each child block */
+	for (i = 0; i < PyList_GET_SIZE(ste->ste_children); ++i) {
+		PyObject *c = PyList_GET_ITEM(ste->ste_children, i);
+		PySTEntryObject* entry;
+		assert(c && PySTEntry_Check(c));
+		entry = (PySTEntryObject*)c;
+		if (!analyze_block(entry, newbound, newfree, newglobal))
+			goto error;
+		if (entry->ste_free || entry->ste_child_free)
+			ste->ste_child_free = 1;
+	}
+
+	if (ste->ste_type == FunctionBlock && !analyze_cells(scope, newfree))
+		goto error;
+	if (!update_symbols(ste->ste_symbols, scope, bound, newfree,
+			    ste->ste_type == ClassBlock))
+		goto error;
+	if (!check_unoptimized(ste))
+		goto error;
+
+	if (PyDict_Update(free, newfree) < 0)
+		goto error;
+	success = 1;
+ error:
+	Py_XDECREF(local);
+	Py_XDECREF(scope);
+	Py_XDECREF(newbound);
+	Py_XDECREF(newglobal);
+	Py_XDECREF(newfree);
+	if (!success)
+		assert(PyErr_Occurred());
+	return success;
+}
+
+static int
+symtable_analyze(struct symtable *st)
+{
+	PyObject *free, *global;
+	int r;
+
+	free = PyDict_New();
+	if (!free)
+	    return 0;
+	global = PyDict_New();
+	if (!global) {
+	    Py_DECREF(free);
+	    return 0;
+	}
+	r = analyze_block(st->st_top, NULL, free, global);
+	Py_DECREF(free);
+	Py_DECREF(global);
+	return r;
+}
+
+
+static int
+symtable_warn(struct symtable *st, char *msg, int lineno)
+{
+	if (PyErr_WarnExplicit(PyExc_SyntaxWarning, msg, st->st_filename,
+			       lineno, NULL, NULL) < 0)	{
+		if (PyErr_ExceptionMatches(PyExc_SyntaxWarning)) {
+			PyErr_SetString(PyExc_SyntaxError, msg);
+			PyErr_SyntaxLocation(st->st_filename, 
+					     st->st_cur->ste_lineno);
+		}
+		return 0;
+	}
+	return 1;
+}
+
+/* symtable_enter_block() gets a reference via PySTEntry_New().
+   This reference is released when the block is exited, via the DECREF
+   in symtable_exit_block().
+*/
+
+static int
+symtable_exit_block(struct symtable *st, void *ast)
+{
+	Py_ssize_t end;
+
+	Py_CLEAR(st->st_cur);
+	end = PyList_GET_SIZE(st->st_stack) - 1;
+	if (end >= 0) {
+		st->st_cur = (PySTEntryObject *)PyList_GET_ITEM(st->st_stack, 
+								end);
+		if (st->st_cur == NULL)
+			return 0;
+		Py_INCREF(st->st_cur);
+		if (PySequence_DelItem(st->st_stack, end) < 0)
+			return 0;
+	}
+	return 1;
+}
+
+static int
+symtable_enter_block(struct symtable *st, identifier name, _Py_block_ty block, 
+		     void *ast, int lineno)
+{
+	PySTEntryObject *prev = NULL;
+
+	if (st->st_cur) {
+		prev = st->st_cur;
+		if (PyList_Append(st->st_stack, (PyObject *)st->st_cur) < 0) {
+			return 0;
+		}
+		Py_DECREF(st->st_cur);
+	}
+	st->st_cur = PySTEntry_New(st, name, block, ast, lineno);
+	if (st->st_cur == NULL)
+		return 0;
+	if (name == GET_IDENTIFIER(top))
+		st->st_global = st->st_cur->ste_symbols;
+	if (prev) {
+		if (PyList_Append(prev->ste_children, 
+				  (PyObject *)st->st_cur) < 0) {
+			return 0;
+		}
+	}
+	return 1;
+}
+
+static long
+symtable_lookup(struct symtable *st, PyObject *name)
+{
+	PyObject *o;
+	PyObject *mangled = _Py_Mangle(st->st_private, name);
+	if (!mangled)
+		return 0;
+	o = PyDict_GetItem(st->st_cur->ste_symbols, mangled);
+	Py_DECREF(mangled);
+	if (!o)
+		return 0;
+	return PyInt_AsLong(o);
+}
+
+static int
+symtable_add_def(struct symtable *st, PyObject *name, int flag) 
+{
+	PyObject *o;
+	PyObject *dict;
+	long val;
+	PyObject *mangled = _Py_Mangle(st->st_private, name);
+
+	if (!mangled)
+		return 0;
+	dict = st->st_cur->ste_symbols;
+	if ((o = PyDict_GetItem(dict, mangled))) {
+	    val = PyInt_AS_LONG(o);
+	    if ((flag & DEF_PARAM) && (val & DEF_PARAM)) {
+		    /* Is it better to use 'mangled' or 'name' here? */
+		    PyErr_Format(PyExc_SyntaxError, DUPLICATE_ARGUMENT,
+				 PyString_AsString(name));
+		    PyErr_SyntaxLocation(st->st_filename,
+				       st->st_cur->ste_lineno);
+		    goto error;
+	    }
+	    val |= flag;
+	} else
+	    val = flag;
+	o = PyInt_FromLong(val);
+        if (o == NULL)
+	    goto error;
+	if (PyDict_SetItem(dict, mangled, o) < 0) {
+		Py_DECREF(o);
+		goto error;
+	}
+	Py_DECREF(o);
+
+	if (flag & DEF_PARAM) {
+		if (PyList_Append(st->st_cur->ste_varnames, mangled) < 0)
+			goto error;
+	} else	if (flag & DEF_GLOBAL) {
+		/* XXX need to update DEF_GLOBAL for other flags too;
+		   perhaps only DEF_FREE_GLOBAL */
+		val = flag;
+		if ((o = PyDict_GetItem(st->st_global, mangled))) {
+			val |= PyInt_AS_LONG(o);
+		}
+		o = PyInt_FromLong(val);
+		if (o == NULL)
+			goto error;
+		if (PyDict_SetItem(st->st_global, mangled, o) < 0) {
+			Py_DECREF(o);
+			goto error;
+		}
+		Py_DECREF(o);
+	}
+	Py_DECREF(mangled);
+	return 1;
+
+error:
+	Py_DECREF(mangled);
+	return 0;
+}
+
+/* VISIT, VISIT_SEQ and VIST_SEQ_TAIL take an ASDL type as their second argument.
+   They use the ASDL name to synthesize the name of the C type and the visit
+   function. 
+   
+   VISIT_SEQ_TAIL permits the start of an ASDL sequence to be skipped, which is
+   useful if the first node in the sequence requires special treatment.
+*/
+
+#define VISIT(ST, TYPE, V) \
+	if (!symtable_visit_ ## TYPE((ST), (V))) \
+		return 0; 
+
+#define VISIT_IN_BLOCK(ST, TYPE, V, S) \
+	if (!symtable_visit_ ## TYPE((ST), (V))) { \
+		symtable_exit_block((ST), (S)); \
+		return 0; \
+	}
+
+#define VISIT_SEQ(ST, TYPE, SEQ) { \
+	int i; \
+	asdl_seq *seq = (SEQ); /* avoid variable capture */ \
+	for (i = 0; i < asdl_seq_LEN(seq); i++) { \
+		TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, i); \
+		if (!symtable_visit_ ## TYPE((ST), elt)) \
+			return 0; \
+	} \
+}
+
+#define VISIT_SEQ_IN_BLOCK(ST, TYPE, SEQ, S) { \
+	int i; \
+	asdl_seq *seq = (SEQ); /* avoid variable capture */ \
+	for (i = 0; i < asdl_seq_LEN(seq); i++) { \
+		TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, i); \
+		if (!symtable_visit_ ## TYPE((ST), elt)) { \
+			symtable_exit_block((ST), (S)); \
+			return 0; \
+		} \
+	} \
+}
+
+#define VISIT_SEQ_TAIL(ST, TYPE, SEQ, START) { \
+	int i; \
+	asdl_seq *seq = (SEQ); /* avoid variable capture */ \
+	for (i = (START); i < asdl_seq_LEN(seq); i++) { \
+		TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, i); \
+		if (!symtable_visit_ ## TYPE((ST), elt)) \
+			return 0; \
+	} \
+}
+
+#define VISIT_SEQ_TAIL_IN_BLOCK(ST, TYPE, SEQ, START, S) { \
+	int i; \
+	asdl_seq *seq = (SEQ); /* avoid variable capture */ \
+	for (i = (START); i < asdl_seq_LEN(seq); i++) { \
+		TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, i); \
+		if (!symtable_visit_ ## TYPE((ST), elt)) { \
+			symtable_exit_block((ST), (S)); \
+			return 0; \
+		} \
+	} \
+}
+
+static int
+symtable_new_tmpname(struct symtable *st)
+{
+	char tmpname[256];
+	identifier tmp;
+
+	PyOS_snprintf(tmpname, sizeof(tmpname), "_[%d]",
+		      ++st->st_cur->ste_tmpname);
+	tmp = PyString_InternFromString(tmpname);
+	if (!tmp)
+		return 0;
+	if (!symtable_add_def(st, tmp, DEF_LOCAL))
+		return 0;
+	Py_DECREF(tmp);
+	return 1;
+}
+
+static int
+symtable_visit_stmt(struct symtable *st, stmt_ty s)
+{
+	switch (s->kind) {
+        case FunctionDef_kind:
+		if (!symtable_add_def(st, s->v.FunctionDef.name, DEF_LOCAL))
+			return 0;
+		if (s->v.FunctionDef.args->defaults)
+			VISIT_SEQ(st, expr, s->v.FunctionDef.args->defaults);
+		if (s->v.FunctionDef.decorators)
+			VISIT_SEQ(st, expr, s->v.FunctionDef.decorators);
+		if (!symtable_enter_block(st, s->v.FunctionDef.name, 
+					  FunctionBlock, (void *)s, s->lineno))
+			return 0;
+		VISIT_IN_BLOCK(st, arguments, s->v.FunctionDef.args, s);
+		VISIT_SEQ_IN_BLOCK(st, stmt, s->v.FunctionDef.body, s);
+		if (!symtable_exit_block(st, s))
+			return 0;
+		break;
+        case ClassDef_kind: {
+		PyObject *tmp;
+		if (!symtable_add_def(st, s->v.ClassDef.name, DEF_LOCAL))
+			return 0;
+		VISIT_SEQ(st, expr, s->v.ClassDef.bases);
+		if (!symtable_enter_block(st, s->v.ClassDef.name, ClassBlock, 
+					  (void *)s, s->lineno))
+			return 0;
+		tmp = st->st_private;
+		st->st_private = s->v.ClassDef.name;
+		VISIT_SEQ_IN_BLOCK(st, stmt, s->v.ClassDef.body, s);
+		st->st_private = tmp;
+		if (!symtable_exit_block(st, s))
+			return 0;
+		break;
+	}
+        case Return_kind:
+		if (s->v.Return.value) {
+			VISIT(st, expr, s->v.Return.value);
+			st->st_cur->ste_returns_value = 1;
+			if (st->st_cur->ste_generator) {
+				PyErr_SetString(PyExc_SyntaxError,
+					RETURN_VAL_IN_GENERATOR);
+			        PyErr_SyntaxLocation(st->st_filename,
+				             s->lineno);
+				return 0;
+			}
+		}
+		break;
+        case Delete_kind:
+		VISIT_SEQ(st, expr, s->v.Delete.targets);
+		break;
+        case Assign_kind:
+		VISIT_SEQ(st, expr, s->v.Assign.targets);
+		VISIT(st, expr, s->v.Assign.value);
+		break;
+        case AugAssign_kind:
+		VISIT(st, expr, s->v.AugAssign.target);
+		VISIT(st, expr, s->v.AugAssign.value);
+		break;
+        case Print_kind:
+		if (s->v.Print.dest)
+			VISIT(st, expr, s->v.Print.dest);
+		VISIT_SEQ(st, expr, s->v.Print.values);
+		break;
+        case For_kind:
+		VISIT(st, expr, s->v.For.target);
+		VISIT(st, expr, s->v.For.iter);
+		VISIT_SEQ(st, stmt, s->v.For.body);
+		if (s->v.For.orelse)
+			VISIT_SEQ(st, stmt, s->v.For.orelse);
+		break;
+        case While_kind:
+		VISIT(st, expr, s->v.While.test);
+		VISIT_SEQ(st, stmt, s->v.While.body);
+		if (s->v.While.orelse)
+			VISIT_SEQ(st, stmt, s->v.While.orelse);
+		break;
+        case If_kind:
+		/* XXX if 0: and lookup_yield() hacks */
+		VISIT(st, expr, s->v.If.test);
+		VISIT_SEQ(st, stmt, s->v.If.body);
+		if (s->v.If.orelse)
+			VISIT_SEQ(st, stmt, s->v.If.orelse);
+		break;
+        case Raise_kind:
+		if (s->v.Raise.type) {
+			VISIT(st, expr, s->v.Raise.type);
+			if (s->v.Raise.inst) {
+				VISIT(st, expr, s->v.Raise.inst);
+				if (s->v.Raise.tback)
+					VISIT(st, expr, s->v.Raise.tback);
+			}
+		}
+		break;
+        case TryExcept_kind:
+		VISIT_SEQ(st, stmt, s->v.TryExcept.body);
+		VISIT_SEQ(st, stmt, s->v.TryExcept.orelse);
+		VISIT_SEQ(st, excepthandler, s->v.TryExcept.handlers);
+		break;
+        case TryFinally_kind:
+		VISIT_SEQ(st, stmt, s->v.TryFinally.body);
+		VISIT_SEQ(st, stmt, s->v.TryFinally.finalbody);
+		break;
+        case Assert_kind:
+		VISIT(st, expr, s->v.Assert.test);
+		if (s->v.Assert.msg)
+			VISIT(st, expr, s->v.Assert.msg);
+		break;
+        case Import_kind:
+		VISIT_SEQ(st, alias, s->v.Import.names);
+		/* XXX Don't have the lineno available inside
+		   visit_alias */
+		if (st->st_cur->ste_unoptimized && !st->st_cur->ste_opt_lineno)
+			st->st_cur->ste_opt_lineno = s->lineno;
+		break;
+        case ImportFrom_kind:
+		VISIT_SEQ(st, alias, s->v.ImportFrom.names);
+		/* XXX Don't have the lineno available inside
+		   visit_alias */
+		if (st->st_cur->ste_unoptimized && !st->st_cur->ste_opt_lineno)
+			st->st_cur->ste_opt_lineno = s->lineno;
+		break;
+        case Exec_kind:
+		VISIT(st, expr, s->v.Exec.body);
+		if (!st->st_cur->ste_opt_lineno)
+			st->st_cur->ste_opt_lineno = s->lineno;
+		if (s->v.Exec.globals) {
+			st->st_cur->ste_unoptimized |= OPT_EXEC;
+			VISIT(st, expr, s->v.Exec.globals);
+			if (s->v.Exec.locals) 
+				VISIT(st, expr, s->v.Exec.locals);
+		} else {
+			st->st_cur->ste_unoptimized |= OPT_BARE_EXEC;
+		}
+		break;
+        case Global_kind: {
+		int i;
+		asdl_seq *seq = s->v.Global.names;
+		for (i = 0; i < asdl_seq_LEN(seq); i++) {
+			identifier name = (identifier)asdl_seq_GET(seq, i);
+			char *c_name = PyString_AS_STRING(name);
+			long cur = symtable_lookup(st, name);
+			if (cur < 0)
+				return 0;
+			if (cur & (DEF_LOCAL | USE)) {
+				char buf[256];
+				if (cur & DEF_LOCAL) 
+					PyOS_snprintf(buf, sizeof(buf),
+						      GLOBAL_AFTER_ASSIGN,
+						      c_name);
+				else
+					PyOS_snprintf(buf, sizeof(buf),
+						      GLOBAL_AFTER_USE,
+						      c_name);
+				if (!symtable_warn(st, buf, s->lineno))
+                                    return 0;
+			}
+			if (!symtable_add_def(st, name, DEF_GLOBAL))
+				return 0;
+		}
+		break;
+	}
+        case Expr_kind:
+		VISIT(st, expr, s->v.Expr.value);
+		break;
+        case Pass_kind:
+        case Break_kind:
+        case Continue_kind:
+		/* nothing to do here */
+		break;
+        case With_kind:
+		if (!symtable_new_tmpname(st))
+			return 0;
+                VISIT(st, expr, s->v.With.context_expr);
+                if (s->v.With.optional_vars) {
+			if (!symtable_new_tmpname(st))
+				return 0;
+                        VISIT(st, expr, s->v.With.optional_vars);
+                }
+                VISIT_SEQ(st, stmt, s->v.With.body);
+                break;
+	}
+	return 1;
+}
+
+static int 
+symtable_visit_expr(struct symtable *st, expr_ty e)
+{
+	switch (e->kind) {
+        case BoolOp_kind:
+		VISIT_SEQ(st, expr, e->v.BoolOp.values);
+		break;
+        case BinOp_kind:
+		VISIT(st, expr, e->v.BinOp.left);
+		VISIT(st, expr, e->v.BinOp.right);
+		break;
+        case UnaryOp_kind:
+		VISIT(st, expr, e->v.UnaryOp.operand);
+		break;
+        case Lambda_kind: {
+		if (!symtable_add_def(st, GET_IDENTIFIER(lambda), DEF_LOCAL))
+			return 0;
+		if (e->v.Lambda.args->defaults)
+			VISIT_SEQ(st, expr, e->v.Lambda.args->defaults);
+		/* XXX how to get line numbers for expressions */
+		if (!symtable_enter_block(st, GET_IDENTIFIER(lambda),
+                                          FunctionBlock, (void *)e, 0))
+			return 0;
+		VISIT_IN_BLOCK(st, arguments, e->v.Lambda.args, (void*)e);
+		VISIT_IN_BLOCK(st, expr, e->v.Lambda.body, (void*)e);
+		if (!symtable_exit_block(st, (void *)e))
+			return 0;
+		break;
+	}
+	case IfExp_kind:
+		VISIT(st, expr, e->v.IfExp.test);
+		VISIT(st, expr, e->v.IfExp.body);
+		VISIT(st, expr, e->v.IfExp.orelse);
+		break;
+        case Dict_kind:
+		VISIT_SEQ(st, expr, e->v.Dict.keys);
+		VISIT_SEQ(st, expr, e->v.Dict.values);
+		break;
+        case ListComp_kind:
+		if (!symtable_new_tmpname(st))
+			return 0;
+		VISIT(st, expr, e->v.ListComp.elt);
+		VISIT_SEQ(st, comprehension, e->v.ListComp.generators);
+		break;
+        case GeneratorExp_kind:
+		if (!symtable_visit_genexp(st, e))
+			return 0;
+		break;
+        case Yield_kind:
+		if (e->v.Yield.value)
+			VISIT(st, expr, e->v.Yield.value);
+                st->st_cur->ste_generator = 1;
+		if (st->st_cur->ste_returns_value) {
+			PyErr_SetString(PyExc_SyntaxError,
+				RETURN_VAL_IN_GENERATOR);
+		        PyErr_SyntaxLocation(st->st_filename,
+			             e->lineno);
+			return 0;
+		}
+		break;
+        case Compare_kind:
+		VISIT(st, expr, e->v.Compare.left);
+		VISIT_SEQ(st, expr, e->v.Compare.comparators);
+		break;
+        case Call_kind:
+		VISIT(st, expr, e->v.Call.func);
+		VISIT_SEQ(st, expr, e->v.Call.args);
+		VISIT_SEQ(st, keyword, e->v.Call.keywords);
+		if (e->v.Call.starargs)
+			VISIT(st, expr, e->v.Call.starargs);
+		if (e->v.Call.kwargs)
+			VISIT(st, expr, e->v.Call.kwargs);
+		break;
+        case Repr_kind:
+		VISIT(st, expr, e->v.Repr.value);
+		break;
+        case Num_kind:
+        case Str_kind:
+		/* Nothing to do here. */
+		break;
+	/* The following exprs can be assignment targets. */
+        case Attribute_kind:
+		VISIT(st, expr, e->v.Attribute.value);
+		break;
+        case Subscript_kind:
+		VISIT(st, expr, e->v.Subscript.value);
+		VISIT(st, slice, e->v.Subscript.slice);
+		break;
+        case Name_kind:
+		if (!symtable_add_def(st, e->v.Name.id, 
+				      e->v.Name.ctx == Load ? USE : DEF_LOCAL))
+			return 0;
+		break;
+	/* child nodes of List and Tuple will have expr_context set */
+        case List_kind:
+		VISIT_SEQ(st, expr, e->v.List.elts);
+		break;
+        case Tuple_kind:
+		VISIT_SEQ(st, expr, e->v.Tuple.elts);
+		break;
+	}
+	return 1;
+}
+
+static int
+symtable_implicit_arg(struct symtable *st, int pos)
+{
+	PyObject *id = PyString_FromFormat(".%d", pos);
+	if (id == NULL)
+		return 0;
+	if (!symtable_add_def(st, id, DEF_PARAM)) {
+		Py_DECREF(id);
+		return 0;
+	}
+	Py_DECREF(id);
+	return 1;
+}
+
+static int 
+symtable_visit_params(struct symtable *st, asdl_seq *args, int toplevel)
+{
+	int i;
+	
+        /* go through all the toplevel arguments first */
+	for (i = 0; i < asdl_seq_LEN(args); i++) {
+		expr_ty arg = (expr_ty)asdl_seq_GET(args, i);
+		if (arg->kind == Name_kind) {
+			assert(arg->v.Name.ctx == Param ||
+                               (arg->v.Name.ctx == Store && !toplevel));
+			if (!symtable_add_def(st, arg->v.Name.id, DEF_PARAM))
+				return 0;
+		}
+		else if (arg->kind == Tuple_kind) {
+			assert(arg->v.Tuple.ctx == Store);
+			if (toplevel) {
+				if (!symtable_implicit_arg(st, i))
+					return 0;
+			}
+		}
+		else {
+		        PyErr_SetString(PyExc_SyntaxError,
+					"invalid expression in parameter list");
+		        PyErr_SyntaxLocation(st->st_filename,
+				             st->st_cur->ste_lineno);
+			return 0;
+		}
+	}
+
+	if (!toplevel) {
+		if (!symtable_visit_params_nested(st, args))
+			return 0;
+	}
+
+	return 1;
+}
+
+static int
+symtable_visit_params_nested(struct symtable *st, asdl_seq *args)
+{
+	int i;
+	for (i = 0; i < asdl_seq_LEN(args); i++) {
+		expr_ty arg = (expr_ty)asdl_seq_GET(args, i);
+		if (arg->kind == Tuple_kind &&
+		    !symtable_visit_params(st, arg->v.Tuple.elts, 0))
+			return 0;
+	}
+	
+	return 1;
+}
+
+static int 
+symtable_visit_arguments(struct symtable *st, arguments_ty a)
+{
+	/* skip default arguments inside function block
+	   XXX should ast be different?
+	*/
+	if (a->args && !symtable_visit_params(st, a->args, 1))
+		return 0;
+	if (a->vararg) {
+		if (!symtable_add_def(st, a->vararg, DEF_PARAM))
+			return 0;
+		st->st_cur->ste_varargs = 1;
+	}
+	if (a->kwarg) {
+		if (!symtable_add_def(st, a->kwarg, DEF_PARAM))
+			return 0;
+		st->st_cur->ste_varkeywords = 1;
+	}
+	if (a->args && !symtable_visit_params_nested(st, a->args))
+		return 0;
+	return 1;
+}
+
+
+static int 
+symtable_visit_excepthandler(struct symtable *st, excepthandler_ty eh)
+{
+	if (eh->type)
+		VISIT(st, expr, eh->type);
+	if (eh->name)
+		VISIT(st, expr, eh->name);
+	VISIT_SEQ(st, stmt, eh->body);
+	return 1;
+}
+
+
+static int 
+symtable_visit_alias(struct symtable *st, alias_ty a)
+{
+	/* Compute store_name, the name actually bound by the import
+	   operation.  It is diferent than a->name when a->name is a
+	   dotted package name (e.g. spam.eggs) 
+	*/
+	PyObject *store_name;
+	PyObject *name = (a->asname == NULL) ? a->name : a->asname;
+	const char *base = PyString_AS_STRING(name);
+	char *dot = strchr(base, '.');
+	if (dot) {
+		store_name = PyString_FromStringAndSize(base, dot - base);
+		if (!store_name)
+			return 0;
+	}
+	else {
+		store_name = name;
+		Py_INCREF(store_name);
+	}
+	if (strcmp(PyString_AS_STRING(name), "*")) {
+		int r = symtable_add_def(st, store_name, DEF_IMPORT); 
+		Py_DECREF(store_name);
+		return r;
+	}
+	else {
+            if (st->st_cur->ste_type != ModuleBlock) {
+                int lineno = st->st_cur->ste_lineno;
+                if (!symtable_warn(st, IMPORT_STAR_WARNING, lineno)) {
+                    Py_DECREF(store_name);
+                    return 0;
+		}
+            }
+	    st->st_cur->ste_unoptimized |= OPT_IMPORT_STAR;
+	    Py_DECREF(store_name);
+	    return 1;
+	}
+}
+
+
+static int 
+symtable_visit_comprehension(struct symtable *st, comprehension_ty lc)
+{
+	VISIT(st, expr, lc->target);
+	VISIT(st, expr, lc->iter);
+	VISIT_SEQ(st, expr, lc->ifs);
+	return 1;
+}
+
+
+static int 
+symtable_visit_keyword(struct symtable *st, keyword_ty k)
+{
+	VISIT(st, expr, k->value);
+	return 1;
+}
+
+
+static int 
+symtable_visit_slice(struct symtable *st, slice_ty s)
+{
+	switch (s->kind) {
+	case Slice_kind:
+		if (s->v.Slice.lower)
+			VISIT(st, expr, s->v.Slice.lower)
+		if (s->v.Slice.upper)
+			VISIT(st, expr, s->v.Slice.upper)
+		if (s->v.Slice.step)
+			VISIT(st, expr, s->v.Slice.step)
+		break;
+	case ExtSlice_kind:
+		VISIT_SEQ(st, slice, s->v.ExtSlice.dims)
+		break;
+	case Index_kind:
+		VISIT(st, expr, s->v.Index.value)
+		break;
+	case Ellipsis_kind:
+		break;
+	}
+	return 1;
+}
+
+static int 
+symtable_visit_genexp(struct symtable *st, expr_ty e)
+{
+	comprehension_ty outermost = ((comprehension_ty)
+			 (asdl_seq_GET(e->v.GeneratorExp.generators, 0)));
+	/* Outermost iterator is evaluated in current scope */
+	VISIT(st, expr, outermost->iter);
+	/* Create generator scope for the rest */
+	if (!symtable_enter_block(st, GET_IDENTIFIER(genexpr),
+				  FunctionBlock, (void *)e, 0)) {
+		return 0;
+	}
+	st->st_cur->ste_generator = 1;
+	/* Outermost iter is received as an argument */
+	if (!symtable_implicit_arg(st, 0)) {
+		symtable_exit_block(st, (void *)e);
+		return 0;
+	}
+	VISIT_IN_BLOCK(st, expr, outermost->target, (void*)e);
+	VISIT_SEQ_IN_BLOCK(st, expr, outermost->ifs, (void*)e);
+	VISIT_SEQ_TAIL_IN_BLOCK(st, comprehension,
+				e->v.GeneratorExp.generators, 1, (void*)e);
+	VISIT_IN_BLOCK(st, expr, e->v.GeneratorExp.elt, (void*)e);
+	if (!symtable_exit_block(st, (void *)e))
+		return 0;
+	return 1;
+}

Added: vendor/Python/current/Python/sysmodule.c
===================================================================
--- vendor/Python/current/Python/sysmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/sysmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1468 @@
+
+/* System module */
+
+/*
+Various bits of information used by the interpreter are collected in
+module 'sys'.
+Function member:
+- exit(sts): raise SystemExit
+Data members:
+- stdin, stdout, stderr: standard file objects
+- modules: the table of modules (dictionary)
+- path: module search path (list of strings)
+- argv: script arguments (list of strings)
+- ps1, ps2: optional primary and secondary prompts (strings)
+*/
+
+#include "Python.h"
+#include "code.h"
+#include "frameobject.h"
+#include "eval.h"
+
+#include "osdefs.h"
+
+#ifdef MS_WINDOWS
+#define WIN32_LEAN_AND_MEAN
+#include "windows.h"
+#endif /* MS_WINDOWS */
+
+#ifdef MS_COREDLL
+extern void *PyWin_DLLhModule;
+/* A string loaded from the DLL at startup: */
+extern const char *PyWin_DLLVersionString;
+#endif
+
+#ifdef __VMS
+#include <unixlib.h>
+#endif
+
+#ifdef MS_WINDOWS
+#include <windows.h>
+#endif
+
+#ifdef HAVE_LANGINFO_H
+#include <locale.h>
+#include <langinfo.h>
+#endif
+
+PyObject *
+PySys_GetObject(char *name)
+{
+	PyThreadState *tstate = PyThreadState_GET();
+	PyObject *sd = tstate->interp->sysdict;
+	if (sd == NULL)
+		return NULL;
+	return PyDict_GetItemString(sd, name);
+}
+
+FILE *
+PySys_GetFile(char *name, FILE *def)
+{
+	FILE *fp = NULL;
+	PyObject *v = PySys_GetObject(name);
+	if (v != NULL && PyFile_Check(v))
+		fp = PyFile_AsFile(v);
+	if (fp == NULL)
+		fp = def;
+	return fp;
+}
+
+int
+PySys_SetObject(char *name, PyObject *v)
+{
+	PyThreadState *tstate = PyThreadState_GET();
+	PyObject *sd = tstate->interp->sysdict;
+	if (v == NULL) {
+		if (PyDict_GetItemString(sd, name) == NULL)
+			return 0;
+		else
+			return PyDict_DelItemString(sd, name);
+	}
+	else
+		return PyDict_SetItemString(sd, name, v);
+}
+
+static PyObject *
+sys_displayhook(PyObject *self, PyObject *o)
+{
+	PyObject *outf;
+	PyInterpreterState *interp = PyThreadState_GET()->interp;
+	PyObject *modules = interp->modules;
+	PyObject *builtins = PyDict_GetItemString(modules, "__builtin__");
+
+	if (builtins == NULL) {
+		PyErr_SetString(PyExc_RuntimeError, "lost __builtin__");
+		return NULL;
+	}
+
+	/* Print value except if None */
+	/* After printing, also assign to '_' */
+	/* Before, set '_' to None to avoid recursion */
+	if (o == Py_None) {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+	if (PyObject_SetAttrString(builtins, "_", Py_None) != 0)
+		return NULL;
+	if (Py_FlushLine() != 0)
+		return NULL;
+	outf = PySys_GetObject("stdout");
+	if (outf == NULL) {
+		PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
+		return NULL;
+	}
+	if (PyFile_WriteObject(o, outf, 0) != 0)
+		return NULL;
+	PyFile_SoftSpace(outf, 1);
+	if (Py_FlushLine() != 0)
+		return NULL;
+	if (PyObject_SetAttrString(builtins, "_", o) != 0)
+		return NULL;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(displayhook_doc,
+"displayhook(object) -> None\n"
+"\n"
+"Print an object to sys.stdout and also save it in __builtin__.\n"
+);
+
+static PyObject *
+sys_excepthook(PyObject* self, PyObject* args)
+{
+	PyObject *exc, *value, *tb;
+	if (!PyArg_UnpackTuple(args, "excepthook", 3, 3, &exc, &value, &tb))
+		return NULL;
+	PyErr_Display(exc, value, tb);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(excepthook_doc,
+"excepthook(exctype, value, traceback) -> None\n"
+"\n"
+"Handle an exception by displaying it with a traceback on sys.stderr.\n"
+);
+
+static PyObject *
+sys_exc_info(PyObject *self, PyObject *noargs)
+{
+	PyThreadState *tstate;
+	tstate = PyThreadState_GET();
+	return Py_BuildValue(
+		"(OOO)",
+		tstate->exc_type != NULL ? tstate->exc_type : Py_None,
+		tstate->exc_value != NULL ? tstate->exc_value : Py_None,
+		tstate->exc_traceback != NULL ?
+			tstate->exc_traceback : Py_None);
+}
+
+PyDoc_STRVAR(exc_info_doc,
+"exc_info() -> (type, value, traceback)\n\
+\n\
+Return information about the most recent exception caught by an except\n\
+clause in the current stack frame or in an older stack frame."
+);
+
+static PyObject *
+sys_exc_clear(PyObject *self, PyObject *noargs)
+{
+	PyThreadState *tstate = PyThreadState_GET();
+	PyObject *tmp_type, *tmp_value, *tmp_tb;
+	tmp_type = tstate->exc_type;
+	tmp_value = tstate->exc_value;
+	tmp_tb = tstate->exc_traceback;
+	tstate->exc_type = NULL;
+	tstate->exc_value = NULL;
+	tstate->exc_traceback = NULL;
+	Py_XDECREF(tmp_type);
+	Py_XDECREF(tmp_value);
+	Py_XDECREF(tmp_tb);
+	/* For b/w compatibility */
+	PySys_SetObject("exc_type", Py_None);
+	PySys_SetObject("exc_value", Py_None);
+	PySys_SetObject("exc_traceback", Py_None);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(exc_clear_doc,
+"exc_clear() -> None\n\
+\n\
+Clear global information on the current exception.  Subsequent calls to\n\
+exc_info() will return (None,None,None) until another exception is raised\n\
+in the current thread or the execution stack returns to a frame where\n\
+another exception is being handled."
+);
+
+static PyObject *
+sys_exit(PyObject *self, PyObject *args)
+{
+	PyObject *exit_code = 0;
+	if (!PyArg_UnpackTuple(args, "exit", 0, 1, &exit_code))
+		return NULL;
+	/* Raise SystemExit so callers may catch it or clean up. */
+	PyErr_SetObject(PyExc_SystemExit, exit_code);
+	return NULL;
+}
+
+PyDoc_STRVAR(exit_doc,
+"exit([status])\n\
+\n\
+Exit the interpreter by raising SystemExit(status).\n\
+If the status is omitted or None, it defaults to zero (i.e., success).\n\
+If the status is numeric, it will be used as the system exit status.\n\
+If it is another kind of object, it will be printed and the system\n\
+exit status will be one (i.e., failure)."
+);
+
+#ifdef Py_USING_UNICODE
+
+static PyObject *
+sys_getdefaultencoding(PyObject *self)
+{
+	return PyString_FromString(PyUnicode_GetDefaultEncoding());
+}
+
+PyDoc_STRVAR(getdefaultencoding_doc,
+"getdefaultencoding() -> string\n\
+\n\
+Return the current default string encoding used by the Unicode \n\
+implementation."
+);
+
+static PyObject *
+sys_setdefaultencoding(PyObject *self, PyObject *args)
+{
+	char *encoding;
+	if (!PyArg_ParseTuple(args, "s:setdefaultencoding", &encoding))
+		return NULL;
+	if (PyUnicode_SetDefaultEncoding(encoding))
+	    	return NULL;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(setdefaultencoding_doc,
+"setdefaultencoding(encoding)\n\
+\n\
+Set the current default string encoding used by the Unicode implementation."
+);
+
+static PyObject *
+sys_getfilesystemencoding(PyObject *self)
+{
+	if (Py_FileSystemDefaultEncoding)
+		return PyString_FromString(Py_FileSystemDefaultEncoding);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(getfilesystemencoding_doc,
+"getfilesystemencoding() -> string\n\
+\n\
+Return the encoding used to convert Unicode filenames in\n\
+operating system filenames."
+);
+
+#endif
+
+/*
+ * Cached interned string objects used for calling the profile and
+ * trace functions.  Initialized by trace_init().
+ */
+static PyObject *whatstrings[7] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL};
+
+static int
+trace_init(void)
+{
+	static char *whatnames[7] = {"call", "exception", "line", "return",
+					"c_call", "c_exception", "c_return"};
+	PyObject *name;
+	int i;
+	for (i = 0; i < 7; ++i) {
+		if (whatstrings[i] == NULL) {
+			name = PyString_InternFromString(whatnames[i]);
+			if (name == NULL)
+				return -1;
+			whatstrings[i] = name;
+                }
+	}
+	return 0;
+}
+
+
+static PyObject *
+call_trampoline(PyThreadState *tstate, PyObject* callback,
+		PyFrameObject *frame, int what, PyObject *arg)
+{
+	PyObject *args = PyTuple_New(3);
+	PyObject *whatstr;
+	PyObject *result;
+
+	if (args == NULL)
+		return NULL;
+	Py_INCREF(frame);
+	whatstr = whatstrings[what];
+	Py_INCREF(whatstr);
+	if (arg == NULL)
+		arg = Py_None;
+	Py_INCREF(arg);
+	PyTuple_SET_ITEM(args, 0, (PyObject *)frame);
+	PyTuple_SET_ITEM(args, 1, whatstr);
+	PyTuple_SET_ITEM(args, 2, arg);
+
+	/* call the Python-level function */
+	PyFrame_FastToLocals(frame);
+	result = PyEval_CallObject(callback, args);
+	PyFrame_LocalsToFast(frame, 1);
+	if (result == NULL)
+		PyTraceBack_Here(frame);
+
+	/* cleanup */
+	Py_DECREF(args);
+	return result;
+}
+
+static int
+profile_trampoline(PyObject *self, PyFrameObject *frame,
+		   int what, PyObject *arg)
+{
+	PyThreadState *tstate = frame->f_tstate;
+	PyObject *result;
+
+	if (arg == NULL)
+		arg = Py_None;
+	result = call_trampoline(tstate, self, frame, what, arg);
+	if (result == NULL) {
+		PyEval_SetProfile(NULL, NULL);
+		return -1;
+	}
+	Py_DECREF(result);
+	return 0;
+}
+
+static int
+trace_trampoline(PyObject *self, PyFrameObject *frame,
+		 int what, PyObject *arg)
+{
+	PyThreadState *tstate = frame->f_tstate;
+	PyObject *callback;
+	PyObject *result;
+
+	if (what == PyTrace_CALL)
+		callback = self;
+	else
+		callback = frame->f_trace;
+	if (callback == NULL)
+		return 0;
+	result = call_trampoline(tstate, callback, frame, what, arg);
+	if (result == NULL) {
+		PyEval_SetTrace(NULL, NULL);
+		Py_XDECREF(frame->f_trace);
+		frame->f_trace = NULL;
+		return -1;
+	}
+	if (result != Py_None) {
+		PyObject *temp = frame->f_trace;
+		frame->f_trace = NULL;
+		Py_XDECREF(temp);
+		frame->f_trace = result;
+	}
+	else {
+		Py_DECREF(result);
+	}
+	return 0;
+}
+
+static PyObject *
+sys_settrace(PyObject *self, PyObject *args)
+{
+	if (trace_init() == -1)
+		return NULL;
+	if (args == Py_None)
+		PyEval_SetTrace(NULL, NULL);
+	else
+		PyEval_SetTrace(trace_trampoline, args);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(settrace_doc,
+"settrace(function)\n\
+\n\
+Set the global debug tracing function.  It will be called on each\n\
+function call.  See the debugger chapter in the library manual."
+);
+
+static PyObject *
+sys_setprofile(PyObject *self, PyObject *args)
+{
+	if (trace_init() == -1)
+		return NULL;
+	if (args == Py_None)
+		PyEval_SetProfile(NULL, NULL);
+	else
+		PyEval_SetProfile(profile_trampoline, args);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(setprofile_doc,
+"setprofile(function)\n\
+\n\
+Set the profiling function.  It will be called on each function call\n\
+and return.  See the profiler chapter in the library manual."
+);
+
+static PyObject *
+sys_setcheckinterval(PyObject *self, PyObject *args)
+{
+	if (!PyArg_ParseTuple(args, "i:setcheckinterval", &_Py_CheckInterval))
+		return NULL;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(setcheckinterval_doc,
+"setcheckinterval(n)\n\
+\n\
+Tell the Python interpreter to check for asynchronous events every\n\
+n instructions.  This also affects how often thread switches occur."
+);
+
+static PyObject *
+sys_getcheckinterval(PyObject *self, PyObject *args)
+{
+	return PyInt_FromLong(_Py_CheckInterval);
+}
+
+PyDoc_STRVAR(getcheckinterval_doc,
+"getcheckinterval() -> current check interval; see setcheckinterval()."
+);
+
+#ifdef WITH_TSC
+static PyObject *
+sys_settscdump(PyObject *self, PyObject *args)
+{
+	int bool;
+	PyThreadState *tstate = PyThreadState_Get();
+
+	if (!PyArg_ParseTuple(args, "i:settscdump", &bool))
+		return NULL;
+	if (bool)
+		tstate->interp->tscdump = 1;
+	else
+		tstate->interp->tscdump = 0;
+	Py_INCREF(Py_None);
+	return Py_None;
+
+}
+
+PyDoc_STRVAR(settscdump_doc,
+"settscdump(bool)\n\
+\n\
+If true, tell the Python interpreter to dump VM measurements to\n\
+stderr.  If false, turn off dump.  The measurements are based on the\n\
+processor's time-stamp counter."
+);
+#endif /* TSC */
+
+static PyObject *
+sys_setrecursionlimit(PyObject *self, PyObject *args)
+{
+	int new_limit;
+	if (!PyArg_ParseTuple(args, "i:setrecursionlimit", &new_limit))
+		return NULL;
+	if (new_limit <= 0) {
+		PyErr_SetString(PyExc_ValueError,
+				"recursion limit must be positive");
+		return NULL;
+	}
+	Py_SetRecursionLimit(new_limit);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(setrecursionlimit_doc,
+"setrecursionlimit(n)\n\
+\n\
+Set the maximum depth of the Python interpreter stack to n.  This\n\
+limit prevents infinite recursion from causing an overflow of the C\n\
+stack and crashing Python.  The highest possible limit is platform-\n\
+dependent."
+);
+
+static PyObject *
+sys_getrecursionlimit(PyObject *self)
+{
+	return PyInt_FromLong(Py_GetRecursionLimit());
+}
+
+PyDoc_STRVAR(getrecursionlimit_doc,
+"getrecursionlimit()\n\
+\n\
+Return the current value of the recursion limit, the maximum depth\n\
+of the Python interpreter stack.  This limit prevents infinite\n\
+recursion from causing an overflow of the C stack and crashing Python."
+);
+
+#ifdef MS_WINDOWS
+PyDoc_STRVAR(getwindowsversion_doc,
+"getwindowsversion()\n\
+\n\
+Return information about the running version of Windows.\n\
+The result is a tuple of (major, minor, build, platform, text)\n\
+All elements are numbers, except text which is a string.\n\
+Platform may be 0 for win32s, 1 for Windows 9x/ME, 2 for Windows NT/2000/XP\n\
+"
+);
+
+static PyObject *
+sys_getwindowsversion(PyObject *self)
+{
+	OSVERSIONINFO ver;
+	ver.dwOSVersionInfoSize = sizeof(ver);
+	if (!GetVersionEx(&ver))
+		return PyErr_SetFromWindowsErr(0);
+	return Py_BuildValue("HHHHs",
+	                     ver.dwMajorVersion,
+	                     ver.dwMinorVersion,
+	                     ver.dwBuildNumber,
+	                     ver.dwPlatformId,
+	                     ver.szCSDVersion);
+}
+
+#endif /* MS_WINDOWS */
+
+#ifdef HAVE_DLOPEN
+static PyObject *
+sys_setdlopenflags(PyObject *self, PyObject *args)
+{
+	int new_val;
+        PyThreadState *tstate = PyThreadState_GET();
+	if (!PyArg_ParseTuple(args, "i:setdlopenflags", &new_val))
+		return NULL;
+        if (!tstate)
+		return NULL;
+        tstate->interp->dlopenflags = new_val;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(setdlopenflags_doc,
+"setdlopenflags(n) -> None\n\
+\n\
+Set the flags that will be used for dlopen() calls. Among other\n\
+things, this will enable a lazy resolving of symbols when importing\n\
+a module, if called as sys.setdlopenflags(0)\n\
+To share symbols across extension modules, call as\n\
+sys.setdlopenflags(dl.RTLD_NOW|dl.RTLD_GLOBAL)"
+);
+
+static PyObject *
+sys_getdlopenflags(PyObject *self, PyObject *args)
+{
+        PyThreadState *tstate = PyThreadState_GET();
+        if (!tstate)
+		return NULL;
+        return PyInt_FromLong(tstate->interp->dlopenflags);
+}
+
+PyDoc_STRVAR(getdlopenflags_doc,
+"getdlopenflags() -> int\n\
+\n\
+Return the current value of the flags that are used for dlopen()\n\
+calls. The flag constants are defined in the dl module."
+);
+#endif
+
+#ifdef USE_MALLOPT
+/* Link with -lmalloc (or -lmpc) on an SGI */
+#include <malloc.h>
+
+static PyObject *
+sys_mdebug(PyObject *self, PyObject *args)
+{
+	int flag;
+	if (!PyArg_ParseTuple(args, "i:mdebug", &flag))
+		return NULL;
+	mallopt(M_DEBUG, flag);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+#endif /* USE_MALLOPT */
+
+static PyObject *
+sys_getrefcount(PyObject *self, PyObject *arg)
+{
+	return PyInt_FromSsize_t(arg->ob_refcnt);
+}
+
+#ifdef Py_REF_DEBUG
+static PyObject *
+sys_gettotalrefcount(PyObject *self)
+{
+	return PyInt_FromSsize_t(_Py_GetRefTotal());
+}
+#endif /* Py_REF_DEBUG */
+
+PyDoc_STRVAR(getrefcount_doc,
+"getrefcount(object) -> integer\n\
+\n\
+Return the reference count of object.  The count returned is generally\n\
+one higher than you might expect, because it includes the (temporary)\n\
+reference as an argument to getrefcount()."
+);
+
+#ifdef COUNT_ALLOCS
+static PyObject *
+sys_getcounts(PyObject *self)
+{
+	extern PyObject *get_counts(void);
+
+	return get_counts();
+}
+#endif
+
+PyDoc_STRVAR(getframe_doc,
+"_getframe([depth]) -> frameobject\n\
+\n\
+Return a frame object from the call stack.  If optional integer depth is\n\
+given, return the frame object that many calls below the top of the stack.\n\
+If that is deeper than the call stack, ValueError is raised.  The default\n\
+for depth is zero, returning the frame at the top of the call stack.\n\
+\n\
+This function should be used for internal and specialized\n\
+purposes only."
+);
+
+static PyObject *
+sys_getframe(PyObject *self, PyObject *args)
+{
+	PyFrameObject *f = PyThreadState_GET()->frame;
+	int depth = -1;
+
+	if (!PyArg_ParseTuple(args, "|i:_getframe", &depth))
+		return NULL;
+
+	while (depth > 0 && f != NULL) {
+		f = f->f_back;
+		--depth;
+	}
+	if (f == NULL) {
+		PyErr_SetString(PyExc_ValueError,
+				"call stack is not deep enough");
+		return NULL;
+	}
+	Py_INCREF(f);
+	return (PyObject*)f;
+}
+
+PyDoc_STRVAR(current_frames_doc,
+"_current_frames() -> dictionary\n\
+\n\
+Return a dictionary mapping each current thread T's thread id to T's\n\
+current stack frame.\n\
+\n\
+This function should be used for specialized purposes only."
+);
+
+static PyObject *
+sys_current_frames(PyObject *self, PyObject *noargs)
+{
+	return _PyThread_CurrentFrames();
+}
+
+PyDoc_STRVAR(call_tracing_doc,
+"call_tracing(func, args) -> object\n\
+\n\
+Call func(*args), while tracing is enabled.  The tracing state is\n\
+saved, and restored afterwards.  This is intended to be called from\n\
+a debugger from a checkpoint, to recursively debug some other code."
+);
+
+static PyObject *
+sys_call_tracing(PyObject *self, PyObject *args)
+{
+	PyObject *func, *funcargs;
+	if (!PyArg_UnpackTuple(args, "call_tracing", 2, 2, &func, &funcargs))
+		return NULL;
+	return _PyEval_CallTracing(func, funcargs);
+}
+
+PyDoc_STRVAR(callstats_doc,
+"callstats() -> tuple of integers\n\
+\n\
+Return a tuple of function call statistics, if CALL_PROFILE was defined\n\
+when Python was built.  Otherwise, return None.\n\
+\n\
+When enabled, this function returns detailed, implementation-specific\n\
+details about the number of function calls executed. The return value is\n\
+a 11-tuple where the entries in the tuple are counts of:\n\
+0. all function calls\n\
+1. calls to PyFunction_Type objects\n\
+2. PyFunction calls that do not create an argument tuple\n\
+3. PyFunction calls that do not create an argument tuple\n\
+   and bypass PyEval_EvalCodeEx()\n\
+4. PyMethod calls\n\
+5. PyMethod calls on bound methods\n\
+6. PyType calls\n\
+7. PyCFunction calls\n\
+8. generator calls\n\
+9. All other calls\n\
+10. Number of stack pops performed by call_function()"
+);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef Py_TRACE_REFS
+/* Defined in objects.c because it uses static globals if that file */
+extern PyObject *_Py_GetObjects(PyObject *, PyObject *);
+#endif
+
+#ifdef DYNAMIC_EXECUTION_PROFILE
+/* Defined in ceval.c because it uses static globals if that file */
+extern PyObject *_Py_GetDXProfile(PyObject *,  PyObject *);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+static PyMethodDef sys_methods[] = {
+	/* Might as well keep this in alphabetic order */
+	{"callstats", (PyCFunction)PyEval_GetCallStats, METH_NOARGS,
+	 callstats_doc},
+	{"_current_frames", sys_current_frames, METH_NOARGS,
+	 current_frames_doc},
+	{"displayhook",	sys_displayhook, METH_O, displayhook_doc},
+	{"exc_info",	sys_exc_info, METH_NOARGS, exc_info_doc},
+	{"exc_clear",	sys_exc_clear, METH_NOARGS, exc_clear_doc},
+	{"excepthook",	sys_excepthook, METH_VARARGS, excepthook_doc},
+	{"exit",	sys_exit, METH_VARARGS, exit_doc},
+#ifdef Py_USING_UNICODE
+	{"getdefaultencoding", (PyCFunction)sys_getdefaultencoding,
+	 METH_NOARGS, getdefaultencoding_doc},
+#endif
+#ifdef HAVE_DLOPEN
+	{"getdlopenflags", (PyCFunction)sys_getdlopenflags, METH_NOARGS,
+	 getdlopenflags_doc},
+#endif
+#ifdef COUNT_ALLOCS
+	{"getcounts",	(PyCFunction)sys_getcounts, METH_NOARGS},
+#endif
+#ifdef DYNAMIC_EXECUTION_PROFILE
+	{"getdxp",	_Py_GetDXProfile, METH_VARARGS},
+#endif
+#ifdef Py_USING_UNICODE
+	{"getfilesystemencoding", (PyCFunction)sys_getfilesystemencoding,
+	 METH_NOARGS, getfilesystemencoding_doc},
+#endif
+#ifdef Py_TRACE_REFS
+	{"getobjects",	_Py_GetObjects, METH_VARARGS},
+#endif
+#ifdef Py_REF_DEBUG
+	{"gettotalrefcount", (PyCFunction)sys_gettotalrefcount, METH_NOARGS},
+#endif
+	{"getrefcount",	(PyCFunction)sys_getrefcount, METH_O, getrefcount_doc},
+	{"getrecursionlimit", (PyCFunction)sys_getrecursionlimit, METH_NOARGS,
+	 getrecursionlimit_doc},
+	{"_getframe", sys_getframe, METH_VARARGS, getframe_doc},
+#ifdef MS_WINDOWS
+	{"getwindowsversion", (PyCFunction)sys_getwindowsversion, METH_NOARGS,
+	 getwindowsversion_doc},
+#endif /* MS_WINDOWS */
+#ifdef USE_MALLOPT
+	{"mdebug",	sys_mdebug, METH_VARARGS},
+#endif
+#ifdef Py_USING_UNICODE
+	{"setdefaultencoding", sys_setdefaultencoding, METH_VARARGS,
+	 setdefaultencoding_doc},
+#endif
+	{"setcheckinterval",	sys_setcheckinterval, METH_VARARGS,
+	 setcheckinterval_doc},
+	{"getcheckinterval",	sys_getcheckinterval, METH_NOARGS,
+	 getcheckinterval_doc},
+#ifdef HAVE_DLOPEN
+	{"setdlopenflags", sys_setdlopenflags, METH_VARARGS,
+	 setdlopenflags_doc},
+#endif
+	{"setprofile",	sys_setprofile, METH_O, setprofile_doc},
+	{"setrecursionlimit", sys_setrecursionlimit, METH_VARARGS,
+	 setrecursionlimit_doc},
+#ifdef WITH_TSC
+	{"settscdump", sys_settscdump, METH_VARARGS, settscdump_doc},
+#endif
+	{"settrace",	sys_settrace, METH_O, settrace_doc},
+	{"call_tracing", sys_call_tracing, METH_VARARGS, call_tracing_doc},
+	{NULL,		NULL}		/* sentinel */
+};
+
+static PyObject *
+list_builtin_module_names(void)
+{
+	PyObject *list = PyList_New(0);
+	int i;
+	if (list == NULL)
+		return NULL;
+	for (i = 0; PyImport_Inittab[i].name != NULL; i++) {
+		PyObject *name = PyString_FromString(
+			PyImport_Inittab[i].name);
+		if (name == NULL)
+			break;
+		PyList_Append(list, name);
+		Py_DECREF(name);
+	}
+	if (PyList_Sort(list) != 0) {
+		Py_DECREF(list);
+		list = NULL;
+	}
+	if (list) {
+		PyObject *v = PyList_AsTuple(list);
+		Py_DECREF(list);
+		list = v;
+	}
+	return list;
+}
+
+static PyObject *warnoptions = NULL;
+
+void
+PySys_ResetWarnOptions(void)
+{
+	if (warnoptions == NULL || !PyList_Check(warnoptions))
+		return;
+	PyList_SetSlice(warnoptions, 0, PyList_GET_SIZE(warnoptions), NULL);
+}
+
+void
+PySys_AddWarnOption(char *s)
+{
+	PyObject *str;
+
+	if (warnoptions == NULL || !PyList_Check(warnoptions)) {
+		Py_XDECREF(warnoptions);
+		warnoptions = PyList_New(0);
+		if (warnoptions == NULL)
+			return;
+	}
+	str = PyString_FromString(s);
+	if (str != NULL) {
+		PyList_Append(warnoptions, str);
+		Py_DECREF(str);
+	}
+}
+
+/* XXX This doc string is too long to be a single string literal in VC++ 5.0.
+   Two literals concatenated works just fine.  If you have a K&R compiler
+   or other abomination that however *does* understand longer strings,
+   get rid of the !!! comment in the middle and the quotes that surround it. */
+PyDoc_VAR(sys_doc) =
+PyDoc_STR(
+"This module provides access to some objects used or maintained by the\n\
+interpreter and to functions that interact strongly with the interpreter.\n\
+\n\
+Dynamic objects:\n\
+\n\
+argv -- command line arguments; argv[0] is the script pathname if known\n\
+path -- module search path; path[0] is the script directory, else ''\n\
+modules -- dictionary of loaded modules\n\
+\n\
+displayhook -- called to show results in an interactive session\n\
+excepthook -- called to handle any uncaught exception other than SystemExit\n\
+  To customize printing in an interactive session or to install a custom\n\
+  top-level exception handler, assign other functions to replace these.\n\
+\n\
+exitfunc -- if sys.exitfunc exists, this routine is called when Python exits\n\
+  Assigning to sys.exitfunc is deprecated; use the atexit module instead.\n\
+\n\
+stdin -- standard input file object; used by raw_input() and input()\n\
+stdout -- standard output file object; used by the print statement\n\
+stderr -- standard error object; used for error messages\n\
+  By assigning other file objects (or objects that behave like files)\n\
+  to these, it is possible to redirect all of the interpreter's I/O.\n\
+\n\
+last_type -- type of last uncaught exception\n\
+last_value -- value of last uncaught exception\n\
+last_traceback -- traceback of last uncaught exception\n\
+  These three are only available in an interactive session after a\n\
+  traceback has been printed.\n\
+\n\
+exc_type -- type of exception currently being handled\n\
+exc_value -- value of exception currently being handled\n\
+exc_traceback -- traceback of exception currently being handled\n\
+  The function exc_info() should be used instead of these three,\n\
+  because it is thread-safe.\n\
+"
+)
+/* concatenating string here */
+PyDoc_STR(
+"\n\
+Static objects:\n\
+\n\
+maxint -- the largest supported integer (the smallest is -maxint-1)\n\
+maxunicode -- the largest supported character\n\
+builtin_module_names -- tuple of module names built into this interpreter\n\
+version -- the version of this interpreter as a string\n\
+version_info -- version information as a tuple\n\
+hexversion -- version information encoded as a single integer\n\
+copyright -- copyright notice pertaining to this interpreter\n\
+platform -- platform identifier\n\
+executable -- pathname of this Python interpreter\n\
+prefix -- prefix used to find the Python library\n\
+exec_prefix -- prefix used to find the machine-specific Python library\n\
+"
+)
+#ifdef MS_WINDOWS
+/* concatenating string here */
+PyDoc_STR(
+"dllhandle -- [Windows only] integer handle of the Python DLL\n\
+winver -- [Windows only] version number of the Python DLL\n\
+"
+)
+#endif /* MS_WINDOWS */
+PyDoc_STR(
+"__stdin__ -- the original stdin; don't touch!\n\
+__stdout__ -- the original stdout; don't touch!\n\
+__stderr__ -- the original stderr; don't touch!\n\
+__displayhook__ -- the original displayhook; don't touch!\n\
+__excepthook__ -- the original excepthook; don't touch!\n\
+\n\
+Functions:\n\
+\n\
+displayhook() -- print an object to the screen, and save it in __builtin__._\n\
+excepthook() -- print an exception and its traceback to sys.stderr\n\
+exc_info() -- return thread-safe information about the current exception\n\
+exc_clear() -- clear the exception state for the current thread\n\
+exit() -- exit the interpreter by raising SystemExit\n\
+getdlopenflags() -- returns flags to be used for dlopen() calls\n\
+getrefcount() -- return the reference count for an object (plus one :-)\n\
+getrecursionlimit() -- return the max recursion depth for the interpreter\n\
+setcheckinterval() -- control how often the interpreter checks for events\n\
+setdlopenflags() -- set the flags to be used for dlopen() calls\n\
+setprofile() -- set the global profiling function\n\
+setrecursionlimit() -- set the max recursion depth for the interpreter\n\
+settrace() -- set the global debug tracing function\n\
+"
+)
+/* end of sys_doc */ ;
+
+static int
+_check_and_flush (FILE *stream)
+{
+  int prev_fail = ferror (stream);
+  return fflush (stream) || prev_fail ? EOF : 0;
+}
+
+/* Subversion branch and revision management */
+static const char _patchlevel_revision[] = PY_PATCHLEVEL_REVISION;
+static const char headurl[] = "$HeadURL: svn+ssh://pythondev@svn.python.org/python/tags/r251/Python/sysmodule.c $";
+static int svn_initialized;
+static char patchlevel_revision[50]; /* Just the number */
+static char branch[50];
+static char shortbranch[50];
+static const char *svn_revision;
+
+static void
+svnversion_init(void)
+{
+	const char *python, *br_start, *br_end, *br_end2, *svnversion;
+	Py_ssize_t len;
+	int istag;
+
+	if (svn_initialized)
+		return;
+
+	python = strstr(headurl, "/python/");
+	if (!python)
+		Py_FatalError("subversion keywords missing");
+
+	br_start = python + 8;
+	br_end = strchr(br_start, '/');
+	assert(br_end);
+
+	/* Works even for trunk,
+	   as we are in trunk/Python/sysmodule.c */
+	br_end2 = strchr(br_end+1, '/');
+
+	istag = strncmp(br_start, "tags", 4) == 0;
+	if (strncmp(br_start, "trunk", 5) == 0) {
+		strcpy(branch, "trunk");
+		strcpy(shortbranch, "trunk");
+
+	}
+	else if (istag || strncmp(br_start, "branches", 8) == 0) {
+		len = br_end2 - br_start;
+		strncpy(branch, br_start, len);
+		branch[len] = '\0';
+
+		len = br_end2 - (br_end + 1);
+		strncpy(shortbranch, br_end + 1, len);
+		shortbranch[len] = '\0';
+	}
+	else {
+		Py_FatalError("bad HeadURL");
+		return;
+	}
+
+
+	svnversion = _Py_svnversion();
+	if (strcmp(svnversion, "exported") != 0)
+		svn_revision = svnversion;
+	else if (istag) {
+		len = strlen(_patchlevel_revision);
+		strncpy(patchlevel_revision, _patchlevel_revision + 11,
+			len - 13);
+		patchlevel_revision[len - 13] = '\0';
+		svn_revision = patchlevel_revision;
+	}
+	else
+		svn_revision = "";
+
+	svn_initialized = 1;
+}
+
+/* Return svnversion output if available.
+   Else return Revision of patchlevel.h if on branch.
+   Else return empty string */
+const char*
+Py_SubversionRevision()
+{
+	svnversion_init();
+	return svn_revision;
+}
+
+const char*
+Py_SubversionShortBranch()
+{
+	svnversion_init();
+	return shortbranch;
+}
+
+PyObject *
+_PySys_Init(void)
+{
+	PyObject *m, *v, *sysdict;
+	PyObject *sysin, *sysout, *syserr;
+	char *s;
+#ifdef MS_WINDOWS
+	char buf[128];
+#endif
+
+	m = Py_InitModule3("sys", sys_methods, sys_doc);
+	if (m == NULL)
+		return NULL;
+	sysdict = PyModule_GetDict(m);
+
+	{
+		/* XXX: does this work on Win/Win64? (see posix_fstat) */
+		struct stat sb;
+		if (fstat(fileno(stdin), &sb) == 0 &&
+		    S_ISDIR(sb.st_mode)) {
+			/* There's nothing more we can do. */
+			/* Py_FatalError() will core dump, so just exit. */
+			PySys_WriteStderr("Python error: <stdin> is a directory, cannot continue\n");
+			exit(EXIT_FAILURE);
+		}
+	}
+
+	/* Closing the standard FILE* if sys.std* goes aways causes problems
+	 * for embedded Python usages. Closing them when somebody explicitly
+	 * invokes .close() might be possible, but the FAQ promises they get
+	 * never closed. However, we still need to get write errors when
+	 * writing fails (e.g. because stdout is redirected), so we flush the
+	 * streams and check for errors before the file objects are deleted.
+	 * On OS X, fflush()ing stdin causes an error, so we exempt stdin
+	 * from that procedure.
+	 */
+	sysin = PyFile_FromFile(stdin, "<stdin>", "r", NULL);
+	sysout = PyFile_FromFile(stdout, "<stdout>", "w", _check_and_flush);
+	syserr = PyFile_FromFile(stderr, "<stderr>", "w", _check_and_flush);
+	if (PyErr_Occurred())
+		return NULL;
+#ifdef MS_WINDOWS
+	if(isatty(_fileno(stdin)) && PyFile_Check(sysin)) {
+		sprintf(buf, "cp%d", GetConsoleCP());
+		if (!PyFile_SetEncoding(sysin, buf))
+			return NULL;
+	}
+	if(isatty(_fileno(stdout)) && PyFile_Check(sysout)) {
+		sprintf(buf, "cp%d", GetConsoleOutputCP());
+		if (!PyFile_SetEncoding(sysout, buf))
+			return NULL;
+	}
+	if(isatty(_fileno(stderr)) && PyFile_Check(syserr)) {
+		sprintf(buf, "cp%d", GetConsoleOutputCP());
+		if (!PyFile_SetEncoding(syserr, buf))
+			return NULL;
+	}
+#endif
+
+	PyDict_SetItemString(sysdict, "stdin", sysin);
+	PyDict_SetItemString(sysdict, "stdout", sysout);
+	PyDict_SetItemString(sysdict, "stderr", syserr);
+	/* Make backup copies for cleanup */
+	PyDict_SetItemString(sysdict, "__stdin__", sysin);
+	PyDict_SetItemString(sysdict, "__stdout__", sysout);
+	PyDict_SetItemString(sysdict, "__stderr__", syserr);
+	PyDict_SetItemString(sysdict, "__displayhook__",
+                             PyDict_GetItemString(sysdict, "displayhook"));
+	PyDict_SetItemString(sysdict, "__excepthook__",
+                             PyDict_GetItemString(sysdict, "excepthook"));
+	Py_XDECREF(sysin);
+	Py_XDECREF(sysout);
+	Py_XDECREF(syserr);
+	PyDict_SetItemString(sysdict, "version",
+			     v = PyString_FromString(Py_GetVersion()));
+	Py_XDECREF(v);
+	PyDict_SetItemString(sysdict, "hexversion",
+			     v = PyInt_FromLong(PY_VERSION_HEX));
+	Py_XDECREF(v);
+	svnversion_init();
+	v = Py_BuildValue("(ssz)", "CPython", branch, svn_revision);
+	PyDict_SetItemString(sysdict, "subversion", v);
+	Py_XDECREF(v);
+	/*
+	 * These release level checks are mutually exclusive and cover
+	 * the field, so don't get too fancy with the pre-processor!
+	 */
+#if PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_ALPHA
+	s = "alpha";
+#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_BETA
+	s = "beta";
+#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_GAMMA
+	s = "candidate";
+#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_FINAL
+	s = "final";
+#endif
+
+#define SET_SYS_FROM_STRING(key, value)			\
+	v = value;					\
+	if (v != NULL)					\
+		PyDict_SetItemString(sysdict, key, v);	\
+	Py_XDECREF(v)
+
+	SET_SYS_FROM_STRING("version_info",
+			    Py_BuildValue("iiisi", PY_MAJOR_VERSION,
+					       PY_MINOR_VERSION,
+					       PY_MICRO_VERSION, s,
+					       PY_RELEASE_SERIAL));
+	SET_SYS_FROM_STRING("api_version",
+			    PyInt_FromLong(PYTHON_API_VERSION));
+	SET_SYS_FROM_STRING("copyright",
+			    PyString_FromString(Py_GetCopyright()));
+	SET_SYS_FROM_STRING("platform",
+			    PyString_FromString(Py_GetPlatform()));
+	SET_SYS_FROM_STRING("executable",
+			    PyString_FromString(Py_GetProgramFullPath()));
+	SET_SYS_FROM_STRING("prefix",
+			    PyString_FromString(Py_GetPrefix()));
+	SET_SYS_FROM_STRING("exec_prefix",
+		   	    PyString_FromString(Py_GetExecPrefix()));
+	SET_SYS_FROM_STRING("maxint",
+			    PyInt_FromLong(PyInt_GetMax()));
+#ifdef Py_USING_UNICODE
+	SET_SYS_FROM_STRING("maxunicode",
+			    PyInt_FromLong(PyUnicode_GetMax()));
+#endif
+	SET_SYS_FROM_STRING("builtin_module_names",
+			    list_builtin_module_names());
+	{
+		/* Assumes that longs are at least 2 bytes long.
+		   Should be safe! */
+		unsigned long number = 1;
+		char *value;
+
+		s = (char *) &number;
+		if (s[0] == 0)
+			value = "big";
+		else
+			value = "little";
+		SET_SYS_FROM_STRING("byteorder",
+				    PyString_FromString(value));
+	}
+#ifdef MS_COREDLL
+	SET_SYS_FROM_STRING("dllhandle",
+			    PyLong_FromVoidPtr(PyWin_DLLhModule));
+	SET_SYS_FROM_STRING("winver",
+			    PyString_FromString(PyWin_DLLVersionString));
+#endif
+#undef SET_SYS_FROM_STRING
+	if (warnoptions == NULL) {
+		warnoptions = PyList_New(0);
+	}
+	else {
+		Py_INCREF(warnoptions);
+	}
+	if (warnoptions != NULL) {
+		PyDict_SetItemString(sysdict, "warnoptions", warnoptions);
+	}
+
+	if (PyErr_Occurred())
+		return NULL;
+	return m;
+}
+
+static PyObject *
+makepathobject(char *path, int delim)
+{
+	int i, n;
+	char *p;
+	PyObject *v, *w;
+
+	n = 1;
+	p = path;
+	while ((p = strchr(p, delim)) != NULL) {
+		n++;
+		p++;
+	}
+	v = PyList_New(n);
+	if (v == NULL)
+		return NULL;
+	for (i = 0; ; i++) {
+		p = strchr(path, delim);
+		if (p == NULL)
+			p = strchr(path, '\0'); /* End of string */
+		w = PyString_FromStringAndSize(path, (Py_ssize_t) (p - path));
+		if (w == NULL) {
+			Py_DECREF(v);
+			return NULL;
+		}
+		PyList_SetItem(v, i, w);
+		if (*p == '\0')
+			break;
+		path = p+1;
+	}
+	return v;
+}
+
+void
+PySys_SetPath(char *path)
+{
+	PyObject *v;
+	if ((v = makepathobject(path, DELIM)) == NULL)
+		Py_FatalError("can't create sys.path");
+	if (PySys_SetObject("path", v) != 0)
+		Py_FatalError("can't assign sys.path");
+	Py_DECREF(v);
+}
+
+static PyObject *
+makeargvobject(int argc, char **argv)
+{
+	PyObject *av;
+	if (argc <= 0 || argv == NULL) {
+		/* Ensure at least one (empty) argument is seen */
+		static char *empty_argv[1] = {""};
+		argv = empty_argv;
+		argc = 1;
+	}
+	av = PyList_New(argc);
+	if (av != NULL) {
+		int i;
+		for (i = 0; i < argc; i++) {
+#ifdef __VMS
+			PyObject *v;
+
+			/* argv[0] is the script pathname if known */
+			if (i == 0) {
+				char* fn = decc$translate_vms(argv[0]);
+				if ((fn == (char *)0) || fn == (char *)-1)
+					v = PyString_FromString(argv[0]);
+				else
+					v = PyString_FromString(
+						decc$translate_vms(argv[0]));
+			} else
+				v = PyString_FromString(argv[i]);
+#else
+			PyObject *v = PyString_FromString(argv[i]);
+#endif
+			if (v == NULL) {
+				Py_DECREF(av);
+				av = NULL;
+				break;
+			}
+			PyList_SetItem(av, i, v);
+		}
+	}
+	return av;
+}
+
+void
+PySys_SetArgv(int argc, char **argv)
+{
+#if defined(HAVE_REALPATH)
+	char fullpath[MAXPATHLEN];
+#elif defined(MS_WINDOWS)
+	char fullpath[MAX_PATH];
+#endif
+	PyObject *av = makeargvobject(argc, argv);
+	PyObject *path = PySys_GetObject("path");
+	if (av == NULL)
+		Py_FatalError("no mem for sys.argv");
+	if (PySys_SetObject("argv", av) != 0)
+		Py_FatalError("can't assign sys.argv");
+	if (path != NULL) {
+		char *argv0 = argv[0];
+		char *p = NULL;
+		Py_ssize_t n = 0;
+		PyObject *a;
+#ifdef HAVE_READLINK
+		char link[MAXPATHLEN+1];
+		char argv0copy[2*MAXPATHLEN+1];
+		int nr = 0;
+		if (argc > 0 && argv0 != NULL && strcmp(argv0, "-c") != 0)
+			nr = readlink(argv0, link, MAXPATHLEN);
+		if (nr > 0) {
+			/* It's a symlink */
+			link[nr] = '\0';
+			if (link[0] == SEP)
+				argv0 = link; /* Link to absolute path */
+			else if (strchr(link, SEP) == NULL)
+				; /* Link without path */
+			else {
+				/* Must join(dirname(argv0), link) */
+				char *q = strrchr(argv0, SEP);
+				if (q == NULL)
+					argv0 = link; /* argv0 without path */
+				else {
+					/* Must make a copy */
+					strcpy(argv0copy, argv0);
+					q = strrchr(argv0copy, SEP);
+					strcpy(q+1, link);
+					argv0 = argv0copy;
+				}
+			}
+		}
+#endif /* HAVE_READLINK */
+#if SEP == '\\' /* Special case for MS filename syntax */
+		if (argc > 0 && argv0 != NULL && strcmp(argv0, "-c") != 0) {
+			char *q;
+#ifdef MS_WINDOWS
+			char *ptemp;
+			if (GetFullPathName(argv0,
+					   sizeof(fullpath),
+					   fullpath,
+					   &ptemp)) {
+				argv0 = fullpath;
+			}
+#endif
+			p = strrchr(argv0, SEP);
+			/* Test for alternate separator */
+			q = strrchr(p ? p : argv0, '/');
+			if (q != NULL)
+				p = q;
+			if (p != NULL) {
+				n = p + 1 - argv0;
+				if (n > 1 && p[-1] != ':')
+					n--; /* Drop trailing separator */
+			}
+		}
+#else /* All other filename syntaxes */
+		if (argc > 0 && argv0 != NULL && strcmp(argv0, "-c") != 0) {
+#if defined(HAVE_REALPATH)
+			if (realpath(argv0, fullpath)) {
+				argv0 = fullpath;
+			}
+#endif
+			p = strrchr(argv0, SEP);
+		}
+		if (p != NULL) {
+#ifndef RISCOS
+			n = p + 1 - argv0;
+#else /* don't include trailing separator */
+			n = p - argv0;
+#endif /* RISCOS */
+#if SEP == '/' /* Special case for Unix filename syntax */
+			if (n > 1)
+				n--; /* Drop trailing separator */
+#endif /* Unix */
+		}
+#endif /* All others */
+		a = PyString_FromStringAndSize(argv0, n);
+		if (a == NULL)
+			Py_FatalError("no mem for sys.path insertion");
+		if (PyList_Insert(path, 0, a) < 0)
+			Py_FatalError("sys.path.insert(0) failed");
+		Py_DECREF(a);
+	}
+	Py_DECREF(av);
+}
+
+
+/* APIs to write to sys.stdout or sys.stderr using a printf-like interface.
+   Adapted from code submitted by Just van Rossum.
+
+   PySys_WriteStdout(format, ...)
+   PySys_WriteStderr(format, ...)
+
+      The first function writes to sys.stdout; the second to sys.stderr.  When
+      there is a problem, they write to the real (C level) stdout or stderr;
+      no exceptions are raised.
+
+      Both take a printf-style format string as their first argument followed
+      by a variable length argument list determined by the format string.
+
+      *** WARNING ***
+
+      The format should limit the total size of the formatted output string to
+      1000 bytes.  In particular, this means that no unrestricted "%s" formats
+      should occur; these should be limited using "%.<N>s where <N> is a
+      decimal number calculated so that <N> plus the maximum size of other
+      formatted text does not exceed 1000 bytes.  Also watch out for "%f",
+      which can print hundreds of digits for very large numbers.
+
+ */
+
+static void
+mywrite(char *name, FILE *fp, const char *format, va_list va)
+{
+	PyObject *file;
+	PyObject *error_type, *error_value, *error_traceback;
+
+	PyErr_Fetch(&error_type, &error_value, &error_traceback);
+	file = PySys_GetObject(name);
+	if (file == NULL || PyFile_AsFile(file) == fp)
+		vfprintf(fp, format, va);
+	else {
+		char buffer[1001];
+		const int written = PyOS_vsnprintf(buffer, sizeof(buffer),
+						   format, va);
+		if (PyFile_WriteString(buffer, file) != 0) {
+			PyErr_Clear();
+			fputs(buffer, fp);
+		}
+		if (written < 0 || (size_t)written >= sizeof(buffer)) {
+			const char *truncated = "... truncated";
+			if (PyFile_WriteString(truncated, file) != 0) {
+				PyErr_Clear();
+				fputs(truncated, fp);
+			}
+		}
+	}
+	PyErr_Restore(error_type, error_value, error_traceback);
+}
+
+void
+PySys_WriteStdout(const char *format, ...)
+{
+	va_list va;
+
+	va_start(va, format);
+	mywrite("stdout", stdout, format, va);
+	va_end(va);
+}
+
+void
+PySys_WriteStderr(const char *format, ...)
+{
+	va_list va;
+
+	va_start(va, format);
+	mywrite("stderr", stderr, format, va);
+	va_end(va);
+}

Added: vendor/Python/current/Python/thread.c
===================================================================
--- vendor/Python/current/Python/thread.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/thread.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,384 @@
+
+/* Thread package.
+   This is intended to be usable independently from Python.
+   The implementation for system foobar is in a file thread_foobar.h
+   which is included by this file dependent on config settings.
+   Stuff shared by all thread_*.h files is collected here. */
+
+#include "Python.h"
+
+
+#ifndef _POSIX_THREADS
+/* This means pthreads are not implemented in libc headers, hence the macro
+   not present in unistd.h. But they still can be implemented as an external
+   library (e.g. gnu pth in pthread emulation) */
+# ifdef HAVE_PTHREAD_H
+#  include <pthread.h> /* _POSIX_THREADS */
+# endif
+#endif
+
+#ifndef DONT_HAVE_STDIO_H
+#include <stdio.h>
+#endif
+
+#include <stdlib.h>
+
+#ifdef __sgi
+#ifndef HAVE_PTHREAD_H /* XXX Need to check in configure.in */
+#undef _POSIX_THREADS
+#endif
+#endif
+
+#include "pythread.h"
+
+#ifndef _POSIX_THREADS
+
+#ifdef __sgi
+#define SGI_THREADS
+#endif
+
+#ifdef HAVE_THREAD_H
+#define SOLARIS_THREADS
+#endif
+
+#if defined(sun) && !defined(SOLARIS_THREADS)
+#define SUN_LWP
+#endif
+
+/* Check if we're running on HP-UX and _SC_THREADS is defined. If so, then
+   enough of the Posix threads package is implimented to support python 
+   threads.
+
+   This is valid for HP-UX 11.23 running on an ia64 system. If needed, add
+   a check of __ia64 to verify that we're running on a ia64 system instead
+   of a pa-risc system.
+*/
+#ifdef __hpux
+#ifdef _SC_THREADS
+#define _POSIX_THREADS
+#endif
+#endif
+
+#endif /* _POSIX_THREADS */
+
+
+#ifdef Py_DEBUG
+static int thread_debug = 0;
+#define dprintf(args)	(void)((thread_debug & 1) && printf args)
+#define d2printf(args)	((thread_debug & 8) && printf args)
+#else
+#define dprintf(args)
+#define d2printf(args)
+#endif
+
+static int initialized;
+
+static void PyThread__init_thread(void); /* Forward */
+
+void
+PyThread_init_thread(void)
+{
+#ifdef Py_DEBUG
+	char *p = getenv("THREADDEBUG");
+
+	if (p) {
+		if (*p)
+			thread_debug = atoi(p);
+		else
+			thread_debug = 1;
+	}
+#endif /* Py_DEBUG */
+	if (initialized)
+		return;
+	initialized = 1;
+	dprintf(("PyThread_init_thread called\n"));
+	PyThread__init_thread();
+}
+
+/* Support for runtime thread stack size tuning.
+   A value of 0 means using the platform's default stack size
+   or the size specified by the THREAD_STACK_SIZE macro. */
+static size_t _pythread_stacksize = 0;
+
+#ifdef SGI_THREADS
+#include "thread_sgi.h"
+#endif
+
+#ifdef SOLARIS_THREADS
+#include "thread_solaris.h"
+#endif
+
+#ifdef SUN_LWP
+#include "thread_lwp.h"
+#endif
+
+#ifdef HAVE_PTH
+#include "thread_pth.h"
+#undef _POSIX_THREADS
+#endif
+
+#ifdef _POSIX_THREADS
+#include "thread_pthread.h"
+#endif
+
+#ifdef C_THREADS
+#include "thread_cthread.h"
+#endif
+
+#ifdef NT_THREADS
+#include "thread_nt.h"
+#endif
+
+#ifdef OS2_THREADS
+#include "thread_os2.h"
+#endif
+
+#ifdef BEOS_THREADS
+#include "thread_beos.h"
+#endif
+
+#ifdef WINCE_THREADS
+#include "thread_wince.h"
+#endif
+
+#ifdef PLAN9_THREADS
+#include "thread_plan9.h"
+#endif
+
+#ifdef ATHEOS_THREADS
+#include "thread_atheos.h"
+#endif
+
+/*
+#ifdef FOOBAR_THREADS
+#include "thread_foobar.h"
+#endif
+*/
+
+/* return the current thread stack size */
+size_t
+PyThread_get_stacksize(void)
+{
+	return _pythread_stacksize;
+}
+
+/* Only platforms defining a THREAD_SET_STACKSIZE() macro
+   in thread_<platform>.h support changing the stack size.
+   Return 0 if stack size is valid,
+          -1 if stack size value is invalid,
+          -2 if setting stack size is not supported. */
+int
+PyThread_set_stacksize(size_t size)
+{
+#if defined(THREAD_SET_STACKSIZE)
+	return THREAD_SET_STACKSIZE(size);
+#else
+	return -2;
+#endif
+}
+
+#ifndef Py_HAVE_NATIVE_TLS
+/* If the platform has not supplied a platform specific
+   TLS implementation, provide our own.
+
+   This code stolen from "thread_sgi.h", where it was the only
+   implementation of an existing Python TLS API.
+*/
+/* ------------------------------------------------------------------------
+Per-thread data ("key") support.
+
+Use PyThread_create_key() to create a new key.  This is typically shared
+across threads.
+
+Use PyThread_set_key_value(thekey, value) to associate void* value with
+thekey in the current thread.  Each thread has a distinct mapping of thekey
+to a void* value.  Caution:  if the current thread already has a mapping
+for thekey, value is ignored.
+
+Use PyThread_get_key_value(thekey) to retrieve the void* value associated
+with thekey in the current thread.  This returns NULL if no value is
+associated with thekey in the current thread.
+
+Use PyThread_delete_key_value(thekey) to forget the current thread's associated
+value for thekey.  PyThread_delete_key(thekey) forgets the values associated
+with thekey across *all* threads.
+
+While some of these functions have error-return values, none set any
+Python exception.
+
+None of the functions does memory management on behalf of the void* values.
+You need to allocate and deallocate them yourself.  If the void* values
+happen to be PyObject*, these functions don't do refcount operations on
+them either.
+
+The GIL does not need to be held when calling these functions; they supply
+their own locking.  This isn't true of PyThread_create_key(), though (see
+next paragraph).
+
+There's a hidden assumption that PyThread_create_key() will be called before
+any of the other functions are called.  There's also a hidden assumption
+that calls to PyThread_create_key() are serialized externally.
+------------------------------------------------------------------------ */
+
+/* A singly-linked list of struct key objects remembers all the key->value
+ * associations.  File static keyhead heads the list.  keymutex is used
+ * to enforce exclusion internally.
+ */
+struct key {
+	/* Next record in the list, or NULL if this is the last record. */
+	struct key *next;
+
+	/* The thread id, according to PyThread_get_thread_ident(). */
+	long id;
+
+	/* The key and its associated value. */
+	int key;
+	void *value;
+};
+
+static struct key *keyhead = NULL;
+static PyThread_type_lock keymutex = NULL;
+static int nkeys = 0;  /* PyThread_create_key() hands out nkeys+1 next */
+
+/* Internal helper.
+ * If the current thread has a mapping for key, the appropriate struct key*
+ * is returned.  NB:  value is ignored in this case!
+ * If there is no mapping for key in the current thread, then:
+ *     If value is NULL, NULL is returned.
+ *     Else a mapping of key to value is created for the current thread,
+ *     and a pointer to a new struct key* is returned; except that if
+ *     malloc() can't find room for a new struct key*, NULL is returned.
+ * So when value==NULL, this acts like a pure lookup routine, and when
+ * value!=NULL, this acts like dict.setdefault(), returning an existing
+ * mapping if one exists, else creating a new mapping.
+ *
+ * Caution:  this used to be too clever, trying to hold keymutex only
+ * around the "p->next = keyhead; keyhead = p" pair.  That allowed
+ * another thread to mutate the list, via key deletion, concurrent with
+ * find_key() crawling over the list.  Hilarity ensued.  For example, when
+ * the for-loop here does "p = p->next", p could end up pointing at a
+ * record that PyThread_delete_key_value() was concurrently free()'ing.
+ * That could lead to anything, from failing to find a key that exists, to
+ * segfaults.  Now we lock the whole routine.
+ */
+static struct key *
+find_key(int key, void *value)
+{
+	struct key *p;
+	long id = PyThread_get_thread_ident();
+
+	if (!keymutex)
+		return NULL;
+	PyThread_acquire_lock(keymutex, 1);
+	for (p = keyhead; p != NULL; p = p->next) {
+		if (p->id == id && p->key == key)
+			goto Done;
+	}
+	if (value == NULL) {
+		assert(p == NULL);
+		goto Done;
+	}
+	p = (struct key *)malloc(sizeof(struct key));
+	if (p != NULL) {
+		p->id = id;
+		p->key = key;
+		p->value = value;
+		p->next = keyhead;
+		keyhead = p;
+	}
+ Done:
+	PyThread_release_lock(keymutex);
+	return p;
+}
+
+/* Return a new key.  This must be called before any other functions in
+ * this family, and callers must arrange to serialize calls to this
+ * function.  No violations are detected.
+ */
+int
+PyThread_create_key(void)
+{
+	/* All parts of this function are wrong if it's called by multiple
+	 * threads simultaneously.
+	 */
+	if (keymutex == NULL)
+		keymutex = PyThread_allocate_lock();
+	return ++nkeys;
+}
+
+/* Forget the associations for key across *all* threads. */
+void
+PyThread_delete_key(int key)
+{
+	struct key *p, **q;
+
+	PyThread_acquire_lock(keymutex, 1);
+	q = &keyhead;
+	while ((p = *q) != NULL) {
+		if (p->key == key) {
+			*q = p->next;
+			free((void *)p);
+			/* NB This does *not* free p->value! */
+		}
+		else
+			q = &p->next;
+	}
+	PyThread_release_lock(keymutex);
+}
+
+/* Confusing:  If the current thread has an association for key,
+ * value is ignored, and 0 is returned.  Else an attempt is made to create
+ * an association of key to value for the current thread.  0 is returned
+ * if that succeeds, but -1 is returned if there's not enough memory
+ * to create the association.  value must not be NULL.
+ */
+int
+PyThread_set_key_value(int key, void *value)
+{
+	struct key *p;
+
+	assert(value != NULL);
+	p = find_key(key, value);
+	if (p == NULL)
+		return -1;
+	else
+		return 0;
+}
+
+/* Retrieve the value associated with key in the current thread, or NULL
+ * if the current thread doesn't have an association for key.
+ */
+void *
+PyThread_get_key_value(int key)
+{
+	struct key *p = find_key(key, NULL);
+
+	if (p == NULL)
+		return NULL;
+	else
+		return p->value;
+}
+
+/* Forget the current thread's association for key, if any. */
+void
+PyThread_delete_key_value(int key)
+{
+	long id = PyThread_get_thread_ident();
+	struct key *p, **q;
+
+	PyThread_acquire_lock(keymutex, 1);
+	q = &keyhead;
+	while ((p = *q) != NULL) {
+		if (p->key == key && p->id == id) {
+			*q = p->next;
+			free((void *)p);
+			/* NB This does *not* free p->value! */
+			break;
+		}
+		else
+			q = &p->next;
+	}
+	PyThread_release_lock(keymutex);
+}
+
+#endif /* Py_HAVE_NATIVE_TLS */

Added: vendor/Python/current/Python/thread_atheos.h
===================================================================
--- vendor/Python/current/Python/thread_atheos.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/thread_atheos.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,300 @@
+/* Threading for AtheOS.
+   Based on thread_beos.h. */
+
+#include <atheos/threads.h>
+#include <atheos/semaphore.h>
+#include <atheos/atomic.h>
+#include <errno.h>
+#include <string.h>
+
+/* Missing decl from threads.h */
+extern int exit_thread(int);
+
+
+/* Undefine FASTLOCK to play with simple semaphores. */
+#define FASTLOCK
+
+
+#ifdef FASTLOCK
+
+/* Use an atomic counter and a semaphore for maximum speed. */
+typedef struct fastmutex {
+	sem_id sem;
+	atomic_t count;
+} fastmutex_t;
+
+
+static int fastmutex_create(const char *name, fastmutex_t * mutex);
+static int fastmutex_destroy(fastmutex_t * mutex);
+static int fastmutex_lock(fastmutex_t * mutex);
+static int fastmutex_timedlock(fastmutex_t * mutex, bigtime_t timeout);
+static int fastmutex_unlock(fastmutex_t * mutex);
+
+
+static int fastmutex_create(const char *name, fastmutex_t * mutex)
+{
+	mutex->count = 0;
+	mutex->sem = create_semaphore(name, 0, 0);
+	return (mutex->sem < 0) ? -1 : 0;
+}
+
+
+static int fastmutex_destroy(fastmutex_t * mutex)
+{
+	if (fastmutex_timedlock(mutex, 0) == 0 || errno == EWOULDBLOCK) {
+		return delete_semaphore(mutex->sem);
+	}
+	return 0;
+}
+
+
+static int fastmutex_lock(fastmutex_t * mutex)
+{
+	atomic_t prev = atomic_add(&mutex->count, 1);
+	if (prev > 0)
+		return lock_semaphore(mutex->sem);
+	return 0;
+}
+
+
+static int fastmutex_timedlock(fastmutex_t * mutex, bigtime_t timeout)
+{
+	atomic_t prev = atomic_add(&mutex->count, 1);
+	if (prev > 0)
+		return lock_semaphore_x(mutex->sem, 1, 0, timeout);
+	return 0;
+}
+
+
+static int fastmutex_unlock(fastmutex_t * mutex)
+{
+	atomic_t prev = atomic_add(&mutex->count, -1);
+	if (prev > 1)
+		return unlock_semaphore(mutex->sem);
+	return 0;
+}
+
+
+#endif				/* FASTLOCK */
+
+
+/*
+ * Initialization.
+ *
+ */
+static void PyThread__init_thread(void)
+{
+	/* Do nothing. */
+	return;
+}
+
+
+/*
+ * Thread support.
+ *
+ */
+
+static atomic_t thread_count = 0;
+
+long PyThread_start_new_thread(void (*func) (void *), void *arg)
+{
+	status_t success = -1;
+	thread_id tid;
+	char name[OS_NAME_LENGTH];
+	atomic_t this_thread;
+
+	dprintf(("PyThread_start_new_thread called\n"));
+
+	this_thread = atomic_add(&thread_count, 1);
+	PyOS_snprintf(name, sizeof(name), "python thread (%d)", this_thread);
+
+	tid = spawn_thread(name, func, NORMAL_PRIORITY, 0, arg);
+	if (tid < 0) {
+		dprintf(("PyThread_start_new_thread spawn_thread failed: %s\n", strerror(errno)));
+	} else {
+		success = resume_thread(tid);
+		if (success < 0) {
+			dprintf(("PyThread_start_new_thread resume_thread failed: %s\n", strerror(errno)));
+		}
+	}
+
+	return (success < 0 ? -1 : tid);
+}
+
+
+long PyThread_get_thread_ident(void)
+{
+	return get_thread_id(NULL);
+}
+
+
+static void do_PyThread_exit_thread(int no_cleanup)
+{
+	dprintf(("PyThread_exit_thread called\n"));
+
+	/* Thread-safe way to read a variable without a mutex: */
+	if (atomic_add(&thread_count, 0) == 0) {
+		/* No threads around, so exit main(). */
+		if (no_cleanup)
+			_exit(0);
+		else
+			exit(0);
+	} else {
+		/* We're a thread */
+		exit_thread(0);
+	}
+}
+
+
+void PyThread_exit_thread(void)
+{
+	do_PyThread_exit_thread(0);
+}
+
+
+void PyThread__exit_thread(void)
+{
+	do_PyThread_exit_thread(1);
+}
+
+
+#ifndef NO_EXIT_PROG
+static void do_PyThread_exit_prog(int status, int no_cleanup)
+{
+	dprintf(("PyThread_exit_prog(%d) called\n", status));
+
+	/* No need to do anything, the threads get torn down if main()exits. */
+	if (no_cleanup)
+		_exit(status);
+	else
+		exit(status);
+}
+
+
+void PyThread_exit_prog(int status)
+{
+	do_PyThread_exit_prog(status, 0);
+}
+
+
+void PyThread__exit_prog(int status)
+{
+	do_PyThread_exit_prog(status, 1);
+}
+#endif				/* NO_EXIT_PROG */
+
+
+/*
+ * Lock support.
+ *
+ */
+
+static atomic_t lock_count = 0;
+
+PyThread_type_lock PyThread_allocate_lock(void)
+{
+#ifdef FASTLOCK
+	fastmutex_t *lock;
+#else
+	sem_id sema;
+#endif
+	char name[OS_NAME_LENGTH];
+	atomic_t this_lock;
+
+	dprintf(("PyThread_allocate_lock called\n"));
+
+#ifdef FASTLOCK
+	lock = (fastmutex_t *) malloc(sizeof(fastmutex_t));
+	if (lock == NULL) {
+		dprintf(("PyThread_allocate_lock failed: out of memory\n"));
+		return (PyThread_type_lock) NULL;
+	}
+#endif
+	this_lock = atomic_add(&lock_count, 1);
+	PyOS_snprintf(name, sizeof(name), "python lock (%d)", this_lock);
+
+#ifdef FASTLOCK
+	if (fastmutex_create(name, lock) < 0) {
+		dprintf(("PyThread_allocate_lock failed: %s\n",
+			 strerror(errno)));
+		free(lock);
+		lock = NULL;
+	}
+	dprintf(("PyThread_allocate_lock()-> %p\n", lock));
+	return (PyThread_type_lock) lock;
+#else
+	sema = create_semaphore(name, 1, 0);
+	if (sema < 0) {
+		dprintf(("PyThread_allocate_lock failed: %s\n",
+			 strerror(errno)));
+		sema = 0;
+	}
+	dprintf(("PyThread_allocate_lock()-> %p\n", sema));
+	return (PyThread_type_lock) sema;
+#endif
+}
+
+
+void PyThread_free_lock(PyThread_type_lock lock)
+{
+	dprintf(("PyThread_free_lock(%p) called\n", lock));
+
+#ifdef FASTLOCK
+	if (fastmutex_destroy((fastmutex_t *) lock) < 0) {
+		dprintf(("PyThread_free_lock(%p) failed: %s\n", lock,
+			 strerror(errno)));
+	}
+	free(lock);
+#else
+	if (delete_semaphore((sem_id) lock) < 0) {
+		dprintf(("PyThread_free_lock(%p) failed: %s\n", lock,
+			 strerror(errno)));
+	}
+#endif
+}
+
+
+int PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
+{
+	int retval;
+
+	dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock,
+		 waitflag));
+
+#ifdef FASTLOCK
+	if (waitflag)
+		retval = fastmutex_lock((fastmutex_t *) lock);
+	else
+		retval = fastmutex_timedlock((fastmutex_t *) lock, 0);
+#else
+	if (waitflag)
+		retval = lock_semaphore((sem_id) lock);
+	else
+		retval = lock_semaphore_x((sem_id) lock, 1, 0, 0);
+#endif
+	if (retval < 0) {
+		dprintf(("PyThread_acquire_lock(%p, %d) failed: %s\n",
+			 lock, waitflag, strerror(errno)));
+	}
+	dprintf(("PyThread_acquire_lock(%p, %d)-> %d\n", lock, waitflag,
+		 retval));
+	return retval < 0 ? 0 : 1;
+}
+
+
+void PyThread_release_lock(PyThread_type_lock lock)
+{
+	dprintf(("PyThread_release_lock(%p) called\n", lock));
+
+#ifdef FASTLOCK
+	if (fastmutex_unlock((fastmutex_t *) lock) < 0) {
+		dprintf(("PyThread_release_lock(%p) failed: %s\n", lock,
+			 strerror(errno)));
+	}
+#else
+	if (unlock_semaphore((sem_id) lock) < 0) {
+		dprintf(("PyThread_release_lock(%p) failed: %s\n", lock,
+			 strerror(errno)));
+	}
+#endif
+}

Added: vendor/Python/current/Python/thread_beos.h
===================================================================
--- vendor/Python/current/Python/thread_beos.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/thread_beos.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,287 @@
+#include <kernel/OS.h>
+#include <support/SupportDefs.h>
+#include <errno.h>
+
+/* ----------------------------------------------------------------------
+ * Fast locking mechanism described by Benoit Schillings (benoit at be.com)
+ * in the Be Developer's Newsletter, Issue #26 (http://www.be.com/).
+ */
+typedef struct benaphore {
+	sem_id _sem;
+	int32  _atom;
+} benaphore_t;
+
+static status_t benaphore_create( const char *name, benaphore_t *ben );
+static status_t benaphore_destroy( benaphore_t *ben );
+static status_t benaphore_lock( benaphore_t *ben );
+static status_t benaphore_timedlock( benaphore_t *ben, bigtime_t micros );
+static status_t benaphore_unlock( benaphore_t *ben );
+
+static status_t benaphore_create( const char *name, benaphore_t *ben )
+{
+	if( ben != NULL ) {
+		ben->_atom = 0;
+		ben->_sem = create_sem( 0, name );
+		
+		if( ben->_sem < B_NO_ERROR ) {
+			return B_BAD_SEM_ID;
+		}
+	} else {
+		return EFAULT;
+	}
+	
+	return EOK;
+}
+
+static status_t benaphore_destroy( benaphore_t *ben )
+{
+	if( ben->_sem >= B_NO_ERROR ) {
+		status_t retval = benaphore_timedlock( ben, 0 );
+		
+		if( retval == EOK || retval == EWOULDBLOCK ) {
+			status_t del_retval = delete_sem( ben->_sem );
+			
+			return del_retval;
+		}
+	}
+
+	return B_BAD_SEM_ID;
+}
+
+static status_t benaphore_lock( benaphore_t *ben )
+{
+	int32 prev = atomic_add( &(ben->_atom), 1 );
+	
+	if( prev > 0 ) {
+		return acquire_sem( ben->_sem );
+	}
+	
+	return EOK;
+}
+
+static status_t benaphore_timedlock( benaphore_t *ben, bigtime_t micros )
+{
+	int32 prev = atomic_add( &(ben->_atom), 1 );
+	
+	if( prev > 0 ) {
+		status_t retval = acquire_sem_etc( ben->_sem, 1, B_TIMEOUT, micros );
+		
+		switch( retval ) {
+		case B_WOULD_BLOCK:	/* Fall through... */
+		case B_TIMED_OUT:
+			return EWOULDBLOCK;
+			break;
+		case B_OK:
+			return EOK;
+			break;
+		default:
+			return retval;
+			break;
+		}
+	}
+	
+	return EOK;
+}
+
+static status_t benaphore_unlock( benaphore_t *ben )
+{
+	int32 prev = atomic_add( &(ben->_atom), -1 );
+	
+	if( prev > 1 ) {
+		return release_sem( ben->_sem );
+	}
+	
+	return EOK;
+}
+
+/* ----------------------------------------------------------------------
+ * Initialization.
+ */
+static void PyThread__init_thread( void )
+{
+	/* Do nothing. */
+	return;
+}
+
+/* ----------------------------------------------------------------------
+ * Thread support.
+ *
+ * Only ANSI C, renamed functions here; you can't use K&R on BeOS,
+ * and there's no legacy thread module to support.
+ */
+
+static int32 thread_count = 0;
+
+long PyThread_start_new_thread( void (*func)(void *), void *arg )
+{
+	status_t success = 0;
+	thread_id tid;
+	char name[B_OS_NAME_LENGTH];
+	int32 this_thread;
+
+	dprintf(("PyThread_start_new_thread called\n"));
+
+	/* We are so very thread-safe... */
+	this_thread = atomic_add( &thread_count, 1 );
+	PyOS_snprintf(name, sizeof(name),
+		      "python thread (%d)", this_thread );
+
+	tid = spawn_thread( (thread_func)func, name,
+	                    B_NORMAL_PRIORITY, arg );
+	if( tid > B_NO_ERROR ) {
+		success = resume_thread( tid );
+	}
+
+	return ( success == B_NO_ERROR ? tid : -1 );
+}
+
+long PyThread_get_thread_ident( void )
+{
+	/* Presumed to return the current thread's ID... */
+	thread_id tid;
+	tid = find_thread( NULL );
+	
+	return ( tid != B_NAME_NOT_FOUND ? tid : -1 );
+}
+
+static void do_PyThread_exit_thread( int no_cleanup )
+{
+	int32 threads;
+
+	dprintf(("PyThread_exit_thread called\n"));
+
+	/* Thread-safe way to read a variable without a mutex: */
+	threads = atomic_add( &thread_count, 0 );
+
+	if( threads == 0 ) {
+		/* No threads around, so exit main(). */
+		if( no_cleanup ) {
+			_exit(0);
+		} else {
+			exit(0);
+		}
+	} else {
+		/* Oh, we're a thread, let's try to exit gracefully... */
+		exit_thread( B_NO_ERROR );
+	}
+}
+
+void PyThread_exit_thread( void )
+{
+	do_PyThread_exit_thread(0);
+}
+
+void PyThread__exit_thread( void )
+{
+	do_PyThread_exit_thread(1);
+}
+
+#ifndef NO_EXIT_PROG
+static void do_PyThread_exit_prog( int status, int no_cleanup )
+{
+	dprintf(("PyThread_exit_prog(%d) called\n", status));
+
+	/* No need to do anything, the threads get torn down if main() exits. */
+
+	if (no_cleanup) {
+		_exit(status);
+	} else {
+		exit(status);
+	}
+}
+
+void PyThread_exit_prog( int status )
+{
+	do_PyThread_exit_prog(status, 0);
+}
+
+void PyThread__exit_prog( int status )
+{
+	do_PyThread_exit_prog(status, 1);
+}
+#endif /* NO_EXIT_PROG */
+
+/* ----------------------------------------------------------------------
+ * Lock support.
+ */
+
+static int32 lock_count = 0;
+
+PyThread_type_lock PyThread_allocate_lock( void )
+{
+	benaphore_t *lock;
+	status_t retval;
+	char name[B_OS_NAME_LENGTH];
+	int32 this_lock;
+	
+	dprintf(("PyThread_allocate_lock called\n"));
+
+	lock = (benaphore_t *)malloc( sizeof( benaphore_t ) );
+	if( lock == NULL ) {
+		/* TODO: that's bad, raise MemoryError */
+		return (PyThread_type_lock)NULL;
+	}
+
+	this_lock = atomic_add( &lock_count, 1 );
+	PyOS_snprintf(name, sizeof(name), "python lock (%d)", this_lock);
+
+	retval = benaphore_create( name, lock );
+	if( retval != EOK ) {
+		/* TODO: that's bad, raise an exception */
+		return (PyThread_type_lock)NULL;
+	}
+
+	dprintf(("PyThread_allocate_lock() -> %p\n", lock));
+	return (PyThread_type_lock) lock;
+}
+
+void PyThread_free_lock( PyThread_type_lock lock )
+{
+	status_t retval;
+
+	dprintf(("PyThread_free_lock(%p) called\n", lock));
+	
+	retval = benaphore_destroy( (benaphore_t *)lock );
+	if( retval != EOK ) {
+		/* TODO: that's bad, raise an exception */
+		return;
+	}
+}
+
+int PyThread_acquire_lock( PyThread_type_lock lock, int waitflag )
+{
+	int success;
+	status_t retval;
+
+	dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
+
+	if( waitflag ) {
+		retval = benaphore_lock( (benaphore_t *)lock );
+	} else {
+		retval = benaphore_timedlock( (benaphore_t *)lock, 0 );
+	}
+	
+	if( retval == EOK ) {
+		success = 1;
+	} else {
+		success = 0;
+		
+		/* TODO: that's bad, raise an exception */
+	}
+
+	dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
+	return success;
+}
+
+void PyThread_release_lock( PyThread_type_lock lock )
+{
+	status_t retval;
+	
+	dprintf(("PyThread_release_lock(%p) called\n", lock));
+	
+	retval = benaphore_unlock( (benaphore_t *)lock );
+	if( retval != EOK ) {
+		/* TODO: that's bad, raise an exception */
+		return;
+	}
+}

Added: vendor/Python/current/Python/thread_cthread.h
===================================================================
--- vendor/Python/current/Python/thread_cthread.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/thread_cthread.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,156 @@
+
+#ifdef MACH_C_THREADS
+#include <mach/cthreads.h>
+#endif
+
+#ifdef HURD_C_THREADS
+#include <cthreads.h>
+#endif
+
+/*
+ * Initialization.
+ */
+static void
+PyThread__init_thread(void)
+{
+#ifndef HURD_C_THREADS
+	/* Roland McGrath said this should not be used since this is
+	done while linking to threads */
+	cthread_init(); 
+#else
+/* do nothing */
+	;
+#endif
+}
+
+/*
+ * Thread support.
+ */
+long
+PyThread_start_new_thread(void (*func)(void *), void *arg)
+{
+	int success = 0;	/* init not needed when SOLARIS_THREADS and */
+				/* C_THREADS implemented properly */
+
+	dprintf(("PyThread_start_new_thread called\n"));
+	if (!initialized)
+		PyThread_init_thread();
+	/* looks like solaris detaches the thread to never rejoin
+	 * so well do it here
+	 */
+	cthread_detach(cthread_fork((cthread_fn_t) func, arg));
+	return success < 0 ? -1 : 0;
+}
+
+long
+PyThread_get_thread_ident(void)
+{
+	if (!initialized)
+		PyThread_init_thread();
+	return (long) cthread_self();
+}
+
+static void
+do_PyThread_exit_thread(int no_cleanup)
+{
+	dprintf(("PyThread_exit_thread called\n"));
+	if (!initialized)
+		if (no_cleanup)
+			_exit(0);
+		else
+			exit(0);
+	cthread_exit(0);
+}
+
+void
+PyThread_exit_thread(void)
+{
+	do_PyThread_exit_thread(0);
+}
+
+void
+PyThread__exit_thread(void)
+{
+	do_PyThread_exit_thread(1);
+}
+
+#ifndef NO_EXIT_PROG
+static
+void do_PyThread_exit_prog(int status, int no_cleanup)
+{
+	dprintf(("PyThread_exit_prog(%d) called\n", status));
+	if (!initialized)
+		if (no_cleanup)
+			_exit(status);
+		else
+			exit(status);
+	if (no_cleanup)
+		_exit(status);
+	else
+		exit(status);
+}
+
+void
+PyThread_exit_prog(int status)
+{
+	do_PyThread_exit_prog(status, 0);
+}
+
+void
+PyThread__exit_prog(int status)
+{
+	do_PyThread_exit_prog(status, 1);
+}
+#endif /* NO_EXIT_PROG */
+
+/*
+ * Lock support.
+ */
+PyThread_type_lock
+PyThread_allocate_lock(void)
+{
+	mutex_t lock;
+
+	dprintf(("PyThread_allocate_lock called\n"));
+	if (!initialized)
+		PyThread_init_thread();
+
+	lock = mutex_alloc();
+	if (mutex_init(lock)) {
+		perror("mutex_init");
+		free((void *) lock);
+		lock = 0;
+	}
+	dprintf(("PyThread_allocate_lock() -> %p\n", lock));
+	return (PyThread_type_lock) lock;
+}
+
+void
+PyThread_free_lock(PyThread_type_lock lock)
+{
+	dprintf(("PyThread_free_lock(%p) called\n", lock));
+	mutex_free(lock);
+}
+
+int
+PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
+{
+	int success = FALSE;
+
+	dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
+	if (waitflag) { 	/* blocking */
+		mutex_lock((mutex_t)lock);
+		success = TRUE;
+	} else {		/* non blocking */
+		success = mutex_try_lock((mutex_t)lock);
+	}
+	dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
+	return success;
+}
+
+void
+PyThread_release_lock(PyThread_type_lock lock)
+{
+	dprintf(("PyThread_release_lock(%p) called\n", lock));
+	mutex_unlock((mutex_t )lock);
+}

Added: vendor/Python/current/Python/thread_foobar.h
===================================================================
--- vendor/Python/current/Python/thread_foobar.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/thread_foobar.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,115 @@
+
+/*
+ * Initialization.
+ */
+static void
+PyThread__init_thread(void)
+{
+}
+
+/*
+ * Thread support.
+ */
+long
+PyThread_start_new_thread(void (*func)(void *), void *arg)
+{
+	int success = 0;	/* init not needed when SOLARIS_THREADS and */
+				/* C_THREADS implemented properly */
+
+	dprintf(("PyThread_start_new_thread called\n"));
+	if (!initialized)
+		PyThread_init_thread();
+	return success < 0 ? -1 : 0;
+}
+
+long
+PyThread_get_thread_ident(void)
+{
+	if (!initialized)
+		PyThread_init_thread();
+}
+
+static
+void do_PyThread_exit_thread(int no_cleanup)
+{
+	dprintf(("PyThread_exit_thread called\n"));
+	if (!initialized)
+		if (no_cleanup)
+			_exit(0);
+		else
+			exit(0);
+}
+
+void
+PyThread_exit_thread(void)
+{
+	do_PyThread_exit_thread(0);
+}
+
+void
+PyThread__exit_thread(void)
+{
+	do_PyThread_exit_thread(1);
+}
+
+#ifndef NO_EXIT_PROG
+static
+void do_PyThread_exit_prog(int status, int no_cleanup)
+{
+	dprintf(("PyThread_exit_prog(%d) called\n", status));
+	if (!initialized)
+		if (no_cleanup)
+			_exit(status);
+		else
+			exit(status);
+}
+
+void
+PyThread_exit_prog(int status)
+{
+	do_PyThread_exit_prog(status, 0);
+}
+
+void
+PyThread__exit_prog(int status)
+{
+	do_PyThread_exit_prog(status, 1);
+}
+#endif /* NO_EXIT_PROG */
+
+/*
+ * Lock support.
+ */
+PyThread_type_lock
+PyThread_allocate_lock(void)
+{
+
+	dprintf(("PyThread_allocate_lock called\n"));
+	if (!initialized)
+		PyThread_init_thread();
+
+	dprintf(("PyThread_allocate_lock() -> %p\n", lock));
+	return (PyThread_type_lock) lock;
+}
+
+void
+PyThread_free_lock(PyThread_type_lock lock)
+{
+	dprintf(("PyThread_free_lock(%p) called\n", lock));
+}
+
+int
+PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
+{
+	int success;
+
+	dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
+	dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
+	return success;
+}
+
+void
+PyThread_release_lock(PyThread_type_lock lock)
+{
+	dprintf(("PyThread_release_lock(%p) called\n", lock));
+}

Added: vendor/Python/current/Python/thread_lwp.h
===================================================================
--- vendor/Python/current/Python/thread_lwp.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/thread_lwp.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,149 @@
+
+#include <stdlib.h>
+#include <lwp/lwp.h>
+#include <lwp/stackdep.h>
+
+#define STACKSIZE	1000	/* stacksize for a thread */
+#define NSTACKS		2	/* # stacks to be put in cache initially */
+
+struct lock {
+	int lock_locked;
+	cv_t lock_condvar;
+	mon_t lock_monitor;
+};
+
+
+/*
+ * Initialization.
+ */
+static void PyThread__init_thread(void)
+{
+	lwp_setstkcache(STACKSIZE, NSTACKS);
+}
+
+/*
+ * Thread support.
+ */
+
+
+long PyThread_start_new_thread(void (*func)(void *), void *arg)
+{
+	thread_t tid;
+	int success;
+	dprintf(("PyThread_start_new_thread called\n"));
+	if (!initialized)
+		PyThread_init_thread();
+	success = lwp_create(&tid, func, MINPRIO, 0, lwp_newstk(), 1, arg);
+	return success < 0 ? -1 : 0;
+}
+
+long PyThread_get_thread_ident(void)
+{
+	thread_t tid;
+	if (!initialized)
+		PyThread_init_thread();
+	if (lwp_self(&tid) < 0)
+		return -1;
+	return tid.thread_id;
+}
+
+static void do_PyThread_exit_thread(int no_cleanup)
+{
+	dprintf(("PyThread_exit_thread called\n"));
+	if (!initialized)
+		if (no_cleanup)
+			_exit(0);
+		else
+			exit(0);
+	lwp_destroy(SELF);
+}
+
+void PyThread_exit_thread(void)
+{
+	do_PyThread_exit_thread(0);
+}
+
+void PyThread__exit_thread(void)
+{
+	do_PyThread_exit_thread(1);
+}
+
+#ifndef NO_EXIT_PROG
+static void do_PyThread_exit_prog(int status, int no_cleanup)
+{
+	dprintf(("PyThread_exit_prog(%d) called\n", status));
+	if (!initialized)
+		if (no_cleanup)
+			_exit(status);
+		else
+			exit(status);
+	pod_exit(status);
+}
+
+void PyThread_exit_prog(int status)
+{
+	do_PyThread_exit_prog(status, 0);
+}
+
+void PyThread__exit_prog(int status)
+{
+	do_PyThread_exit_prog(status, 1);
+}
+#endif /* NO_EXIT_PROG */
+
+/*
+ * Lock support.
+ */
+PyThread_type_lock PyThread_allocate_lock(void)
+{
+	struct lock *lock;
+	extern char *malloc(size_t);
+
+	dprintf(("PyThread_allocate_lock called\n"));
+	if (!initialized)
+		PyThread_init_thread();
+
+	lock = (struct lock *) malloc(sizeof(struct lock));
+	lock->lock_locked = 0;
+	(void) mon_create(&lock->lock_monitor);
+	(void) cv_create(&lock->lock_condvar, lock->lock_monitor);
+	dprintf(("PyThread_allocate_lock() -> %p\n", lock));
+	return (PyThread_type_lock) lock;
+}
+
+void PyThread_free_lock(PyThread_type_lock lock)
+{
+	dprintf(("PyThread_free_lock(%p) called\n", lock));
+	mon_destroy(((struct lock *) lock)->lock_monitor);
+	free((char *) lock);
+}
+
+int PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
+{
+	int success;
+
+	dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
+	success = 0;
+
+	(void) mon_enter(((struct lock *) lock)->lock_monitor);
+	if (waitflag)
+		while (((struct lock *) lock)->lock_locked)
+			cv_wait(((struct lock *) lock)->lock_condvar);
+	if (!((struct lock *) lock)->lock_locked) {
+		success = 1;
+		((struct lock *) lock)->lock_locked = 1;
+	}
+	cv_broadcast(((struct lock *) lock)->lock_condvar);
+	mon_exit(((struct lock *) lock)->lock_monitor);
+	dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
+	return success;
+}
+
+void PyThread_release_lock(PyThread_type_lock lock)
+{
+	dprintf(("PyThread_release_lock(%p) called\n", lock));
+	(void) mon_enter(((struct lock *) lock)->lock_monitor);
+	((struct lock *) lock)->lock_locked = 0;
+	cv_broadcast(((struct lock *) lock)->lock_condvar);
+	mon_exit(((struct lock *) lock)->lock_monitor);
+}

Added: vendor/Python/current/Python/thread_nt.h
===================================================================
--- vendor/Python/current/Python/thread_nt.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/thread_nt.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,364 @@
+
+/* This code implemented by Dag.Gruneau at elsa.preseco.comm.se */
+/* Fast NonRecursiveMutex support by Yakov Markovitch, markovitch at iso.ru */
+/* Eliminated some memory leaks, gsw at agere.com */
+
+#include <windows.h>
+#include <limits.h>
+#ifdef HAVE_PROCESS_H
+#include <process.h>
+#endif
+
+typedef struct NRMUTEX {
+	LONG   owned ;
+	DWORD  thread_id ;
+	HANDLE hevent ;
+} NRMUTEX, *PNRMUTEX ;
+
+typedef PVOID WINAPI interlocked_cmp_xchg_t(PVOID *dest, PVOID exc, PVOID comperand) ;
+
+/* Sorry mate, but we haven't got InterlockedCompareExchange in Win95! */
+static PVOID WINAPI
+interlocked_cmp_xchg(PVOID *dest, PVOID exc, PVOID comperand)
+{
+	static LONG spinlock = 0 ;
+	PVOID result ;
+	DWORD dwSleep = 0;
+
+	/* Acqire spinlock (yielding control to other threads if cant aquire for the moment) */
+	while(InterlockedExchange(&spinlock, 1))
+	{
+		// Using Sleep(0) can cause a priority inversion.
+		// Sleep(0) only yields the processor if there's
+		// another thread of the same priority that's
+		// ready to run.  If a high-priority thread is
+		// trying to acquire the lock, which is held by
+		// a low-priority thread, then the low-priority
+		// thread may never get scheduled and hence never
+		// free the lock.  NT attempts to avoid priority
+		// inversions by temporarily boosting the priority
+		// of low-priority runnable threads, but the problem
+		// can still occur if there's a medium-priority
+		// thread that's always runnable.  If Sleep(1) is used,
+		// then the thread unconditionally yields the CPU.  We
+		// only do this for the second and subsequent even
+		// iterations, since a millisecond is a long time to wait
+		// if the thread can be scheduled in again sooner
+		// (~100,000 instructions).
+		// Avoid priority inversion: 0, 1, 0, 1,...
+		Sleep(dwSleep);
+		dwSleep = !dwSleep;
+	}
+	result = *dest ;
+	if (result == comperand)
+		*dest = exc ;
+	/* Release spinlock */
+	spinlock = 0 ;
+	return result ;
+} ;
+
+static interlocked_cmp_xchg_t *ixchg;
+
+BOOL
+InitializeNonRecursiveMutex(PNRMUTEX mutex)
+{
+	if (!ixchg)
+	{
+		/* Sorely, Win95 has no InterlockedCompareExchange API (Win98 has), so we have to use emulation */
+		HANDLE kernel = GetModuleHandle("kernel32.dll") ;
+		if (!kernel || (ixchg = (interlocked_cmp_xchg_t *)GetProcAddress(kernel, "InterlockedCompareExchange")) == NULL)
+			ixchg = interlocked_cmp_xchg ;
+	}
+
+	mutex->owned = -1 ;  /* No threads have entered NonRecursiveMutex */
+	mutex->thread_id = 0 ;
+	mutex->hevent = CreateEvent(NULL, FALSE, FALSE, NULL) ;
+	return mutex->hevent != NULL ;	/* TRUE if the mutex is created */
+}
+
+#ifdef InterlockedCompareExchange
+#undef InterlockedCompareExchange
+#endif
+#define InterlockedCompareExchange(dest,exchange,comperand) (ixchg((dest), (exchange), (comperand)))
+
+VOID
+DeleteNonRecursiveMutex(PNRMUTEX mutex)
+{
+	/* No in-use check */
+	CloseHandle(mutex->hevent) ;
+	mutex->hevent = NULL ; /* Just in case */
+}
+
+DWORD
+EnterNonRecursiveMutex(PNRMUTEX mutex, BOOL wait)
+{
+	/* Assume that the thread waits successfully */
+	DWORD ret ;
+
+	/* InterlockedIncrement(&mutex->owned) == 0 means that no thread currently owns the mutex */
+	if (!wait)
+	{
+		if (InterlockedCompareExchange((PVOID *)&mutex->owned, (PVOID)0, (PVOID)-1) != (PVOID)-1)
+			return WAIT_TIMEOUT ;
+		ret = WAIT_OBJECT_0 ;
+	}
+	else
+		ret = InterlockedIncrement(&mutex->owned) ?
+			/* Some thread owns the mutex, let's wait... */
+			WaitForSingleObject(mutex->hevent, INFINITE) : WAIT_OBJECT_0 ;
+
+	mutex->thread_id = GetCurrentThreadId() ; /* We own it */
+	return ret ;
+}
+
+BOOL
+LeaveNonRecursiveMutex(PNRMUTEX mutex)
+{
+	/* We don't own the mutex */
+	mutex->thread_id = 0 ;
+	return
+		InterlockedDecrement(&mutex->owned) < 0 ||
+		SetEvent(mutex->hevent) ; /* Other threads are waiting, wake one on them up */
+}
+
+PNRMUTEX
+AllocNonRecursiveMutex(void)
+{
+	PNRMUTEX mutex = (PNRMUTEX)malloc(sizeof(NRMUTEX)) ;
+	if (mutex && !InitializeNonRecursiveMutex(mutex))
+	{
+		free(mutex) ;
+		mutex = NULL ;
+	}
+	return mutex ;
+}
+
+void
+FreeNonRecursiveMutex(PNRMUTEX mutex)
+{
+	if (mutex)
+	{
+		DeleteNonRecursiveMutex(mutex) ;
+		free(mutex) ;
+	}
+}
+
+long PyThread_get_thread_ident(void);
+
+/*
+ * Initialization of the C package, should not be needed.
+ */
+static void
+PyThread__init_thread(void)
+{
+}
+
+/*
+ * Thread support.
+ */
+
+typedef struct {
+	void (*func)(void*);
+	void *arg;
+	long id;
+	HANDLE done;
+} callobj;
+
+static int
+bootstrap(void *call)
+{
+	callobj *obj = (callobj*)call;
+	/* copy callobj since other thread might free it before we're done */
+	void (*func)(void*) = obj->func;
+	void *arg = obj->arg;
+
+	obj->id = PyThread_get_thread_ident();
+	ReleaseSemaphore(obj->done, 1, NULL);
+	func(arg);
+	return 0;
+}
+
+long
+PyThread_start_new_thread(void (*func)(void *), void *arg)
+{
+	Py_uintptr_t rv;
+	callobj obj;
+
+	dprintf(("%ld: PyThread_start_new_thread called\n",
+		 PyThread_get_thread_ident()));
+	if (!initialized)
+		PyThread_init_thread();
+
+	obj.id = -1;	/* guilty until proved innocent */
+	obj.func = func;
+	obj.arg = arg;
+	obj.done = CreateSemaphore(NULL, 0, 1, NULL);
+	if (obj.done == NULL)
+		return -1;
+
+	rv = _beginthread(bootstrap, _pythread_stacksize, &obj);
+	if (rv == (Py_uintptr_t)-1) {
+		/* I've seen errno == EAGAIN here, which means "there are
+		 * too many threads".
+		 */
+		dprintf(("%ld: PyThread_start_new_thread failed: %p errno %d\n",
+		         PyThread_get_thread_ident(), rv, errno));
+		obj.id = -1;
+	}
+	else {
+		dprintf(("%ld: PyThread_start_new_thread succeeded: %p\n",
+		         PyThread_get_thread_ident(), rv));
+		/* wait for thread to initialize, so we can get its id */
+		WaitForSingleObject(obj.done, INFINITE);
+		assert(obj.id != -1);
+	}
+	CloseHandle((HANDLE)obj.done);
+	return obj.id;
+}
+
+/*
+ * Return the thread Id instead of an handle. The Id is said to uniquely identify the
+ * thread in the system
+ */
+long
+PyThread_get_thread_ident(void)
+{
+	if (!initialized)
+		PyThread_init_thread();
+
+	return GetCurrentThreadId();
+}
+
+static void
+do_PyThread_exit_thread(int no_cleanup)
+{
+	dprintf(("%ld: PyThread_exit_thread called\n", PyThread_get_thread_ident()));
+	if (!initialized)
+		if (no_cleanup)
+			_exit(0);
+		else
+			exit(0);
+	_endthread();
+}
+
+void
+PyThread_exit_thread(void)
+{
+	do_PyThread_exit_thread(0);
+}
+
+void
+PyThread__exit_thread(void)
+{
+	do_PyThread_exit_thread(1);
+}
+
+#ifndef NO_EXIT_PROG
+static void
+do_PyThread_exit_prog(int status, int no_cleanup)
+{
+	dprintf(("PyThread_exit_prog(%d) called\n", status));
+	if (!initialized)
+		if (no_cleanup)
+			_exit(status);
+		else
+			exit(status);
+}
+
+void
+PyThread_exit_prog(int status)
+{
+	do_PyThread_exit_prog(status, 0);
+}
+
+void
+PyThread__exit_prog(int status)
+{
+	do_PyThread_exit_prog(status, 1);
+}
+#endif /* NO_EXIT_PROG */
+
+/*
+ * Lock support. It has too be implemented as semaphores.
+ * I [Dag] tried to implement it with mutex but I could find a way to
+ * tell whether a thread already own the lock or not.
+ */
+PyThread_type_lock
+PyThread_allocate_lock(void)
+{
+	PNRMUTEX aLock;
+
+	dprintf(("PyThread_allocate_lock called\n"));
+	if (!initialized)
+		PyThread_init_thread();
+
+	aLock = AllocNonRecursiveMutex() ;
+
+	dprintf(("%ld: PyThread_allocate_lock() -> %p\n", PyThread_get_thread_ident(), aLock));
+
+	return (PyThread_type_lock) aLock;
+}
+
+void
+PyThread_free_lock(PyThread_type_lock aLock)
+{
+	dprintf(("%ld: PyThread_free_lock(%p) called\n", PyThread_get_thread_ident(),aLock));
+
+	FreeNonRecursiveMutex(aLock) ;
+}
+
+/*
+ * Return 1 on success if the lock was acquired
+ *
+ * and 0 if the lock was not acquired. This means a 0 is returned
+ * if the lock has already been acquired by this thread!
+ */
+int
+PyThread_acquire_lock(PyThread_type_lock aLock, int waitflag)
+{
+	int success ;
+
+	dprintf(("%ld: PyThread_acquire_lock(%p, %d) called\n", PyThread_get_thread_ident(),aLock, waitflag));
+
+	success = aLock && EnterNonRecursiveMutex((PNRMUTEX) aLock, (waitflag ? INFINITE : 0)) == WAIT_OBJECT_0 ;
+
+	dprintf(("%ld: PyThread_acquire_lock(%p, %d) -> %d\n", PyThread_get_thread_ident(),aLock, waitflag, success));
+
+	return success;
+}
+
+void
+PyThread_release_lock(PyThread_type_lock aLock)
+{
+	dprintf(("%ld: PyThread_release_lock(%p) called\n", PyThread_get_thread_ident(),aLock));
+
+	if (!(aLock && LeaveNonRecursiveMutex((PNRMUTEX) aLock)))
+		dprintf(("%ld: Could not PyThread_release_lock(%p) error: %l\n", PyThread_get_thread_ident(), aLock, GetLastError()));
+}
+
+/* minimum/maximum thread stack sizes supported */
+#define THREAD_MIN_STACKSIZE	0x8000		/* 32kB */
+#define THREAD_MAX_STACKSIZE	0x10000000	/* 256MB */
+
+/* set the thread stack size.
+ * Return 0 if size is valid, -1 otherwise.
+ */
+static int
+_pythread_nt_set_stacksize(size_t size)
+{
+	/* set to default */
+	if (size == 0) {
+		_pythread_stacksize = 0;
+		return 0;
+	}
+
+	/* valid range? */
+	if (size >= THREAD_MIN_STACKSIZE && size < THREAD_MAX_STACKSIZE) {
+		_pythread_stacksize = size;
+		return 0;
+	}
+
+	return -1;
+}
+
+#define THREAD_SET_STACKSIZE(x)	_pythread_nt_set_stacksize(x)

Added: vendor/Python/current/Python/thread_os2.h
===================================================================
--- vendor/Python/current/Python/thread_os2.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/thread_os2.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,307 @@
+/* This code implemented by cvale at netcom.com */
+
+#define INCL_DOSPROCESS
+#define INCL_DOSSEMAPHORES
+#include "os2.h"
+#include "limits.h"
+
+#include "process.h"
+
+#if defined(PYCC_GCC)
+#include <sys/builtin.h>
+#include <sys/fmutex.h>
+#else
+long PyThread_get_thread_ident(void);
+#endif
+
+/* default thread stack size of 64kB */
+#if !defined(THREAD_STACK_SIZE)
+#define	THREAD_STACK_SIZE	0x10000
+#endif
+
+#define OS2_STACKSIZE(x)	(x ? x : THREAD_STACK_SIZE)
+
+/*
+ * Initialization of the C package, should not be needed.
+ */
+static void
+PyThread__init_thread(void)
+{
+}
+
+/*
+ * Thread support.
+ */
+long
+PyThread_start_new_thread(void (*func)(void *), void *arg)
+{
+	int thread_id;
+
+	thread_id = _beginthread(func,
+				NULL,
+				OS2_STACKSIZE(_pythread_stacksize),
+				arg);
+
+	if (thread_id == -1) {
+		dprintf(("_beginthread failed. return %ld\n", errno));
+	}
+
+	return thread_id;
+}
+
+long
+PyThread_get_thread_ident(void)
+{
+#if !defined(PYCC_GCC)
+	PPIB pib;
+	PTIB tib;
+#endif
+
+	if (!initialized)
+		PyThread_init_thread();
+
+#if defined(PYCC_GCC)
+	return _gettid();
+#else
+	DosGetInfoBlocks(&tib, &pib);
+	return tib->tib_ptib2->tib2_ultid;
+#endif
+}
+
+static void
+do_PyThread_exit_thread(int no_cleanup)
+{
+	dprintf(("%ld: PyThread_exit_thread called\n",
+		 PyThread_get_thread_ident()));
+	if (!initialized)
+		if (no_cleanup)
+			_exit(0);
+		else
+			exit(0);
+	_endthread();
+}
+
+void 
+PyThread_exit_thread(void)
+{
+	do_PyThread_exit_thread(0);
+}
+
+void 
+PyThread__exit_thread(void)
+{
+	do_PyThread_exit_thread(1);
+}
+
+#ifndef NO_EXIT_PROG
+static void 
+do_PyThread_exit_prog(int status, int no_cleanup)
+{
+	dprintf(("PyThread_exit_prog(%d) called\n", status));
+	if (!initialized)
+		if (no_cleanup)
+			_exit(status);
+		else
+			exit(status);
+}
+
+void 
+PyThread_exit_prog(int status)
+{
+	do_PyThread_exit_prog(status, 0);
+}
+
+void 
+PyThread__exit_prog(int status)
+{
+	do_PyThread_exit_prog(status, 1);
+}
+#endif /* NO_EXIT_PROG */
+
+/*
+ * Lock support.  This is implemented with an event semaphore and critical
+ * sections to make it behave more like a posix mutex than its OS/2 
+ * counterparts.
+ */
+
+typedef struct os2_lock_t {
+	int is_set;
+	HEV changed;
+} *type_os2_lock;
+
+PyThread_type_lock 
+PyThread_allocate_lock(void)
+{
+#if defined(PYCC_GCC)
+	_fmutex *sem = malloc(sizeof(_fmutex));
+	if (!initialized)
+		PyThread_init_thread();
+	dprintf(("%ld: PyThread_allocate_lock() -> %lx\n",
+		 PyThread_get_thread_ident(),
+		 (long)sem));
+	if (_fmutex_create(sem, 0)) {
+		free(sem);
+		sem = NULL;
+	}
+	return (PyThread_type_lock)sem;
+#else
+	APIRET rc;
+	type_os2_lock lock = (type_os2_lock)malloc(sizeof(struct os2_lock_t));
+
+	dprintf(("PyThread_allocate_lock called\n"));
+	if (!initialized)
+		PyThread_init_thread();
+
+	lock->is_set = 0;
+
+	DosCreateEventSem(NULL, &lock->changed, 0, 0);
+
+	dprintf(("%ld: PyThread_allocate_lock() -> %p\n", 
+		 PyThread_get_thread_ident(), 
+        	 lock->changed));
+
+	return (PyThread_type_lock)lock;
+#endif
+}
+
+void 
+PyThread_free_lock(PyThread_type_lock aLock)
+{
+#if !defined(PYCC_GCC)
+	type_os2_lock lock = (type_os2_lock)aLock;
+#endif
+
+	dprintf(("%ld: PyThread_free_lock(%p) called\n",
+		 PyThread_get_thread_ident(),aLock));
+
+#if defined(PYCC_GCC)
+	if (aLock) {
+		_fmutex_close((_fmutex *)aLock);
+		free((_fmutex *)aLock);
+	}
+#else
+	DosCloseEventSem(lock->changed);
+	free(aLock);
+#endif
+}
+
+/*
+ * Return 1 on success if the lock was acquired
+ *
+ * and 0 if the lock was not acquired.
+ */
+int 
+PyThread_acquire_lock(PyThread_type_lock aLock, int waitflag)
+{
+#if !defined(PYCC_GCC)
+	int   done = 0;
+	ULONG count;
+	PID   pid = 0;
+	TID   tid = 0;
+	type_os2_lock lock = (type_os2_lock)aLock;
+#endif
+
+	dprintf(("%ld: PyThread_acquire_lock(%p, %d) called\n",
+		 PyThread_get_thread_ident(),
+		 aLock,
+		 waitflag));
+
+#if defined(PYCC_GCC)
+	/* always successful if the lock doesn't exist */
+	if (aLock &&
+	    _fmutex_request((_fmutex *)aLock, waitflag ? 0 : _FMR_NOWAIT))
+		return 0;
+#else
+	while (!done) {
+		/* if the lock is currently set, we have to wait for
+		 * the state to change
+		 */
+		if (lock->is_set) {
+			if (!waitflag)
+				return 0;
+			DosWaitEventSem(lock->changed, SEM_INDEFINITE_WAIT);
+		}
+
+		/* enter a critical section and try to get the semaphore.  If
+		 * it is still locked, we will try again.
+		 */
+		if (DosEnterCritSec())
+			return 0;
+
+		if (!lock->is_set) {
+			lock->is_set = 1;
+			DosResetEventSem(lock->changed, &count);
+			done = 1;
+		}
+
+		DosExitCritSec();
+	}
+#endif
+
+	return 1;
+}
+
+void
+PyThread_release_lock(PyThread_type_lock aLock)
+{
+#if !defined(PYCC_GCC)
+	type_os2_lock lock = (type_os2_lock)aLock;
+#endif
+
+	dprintf(("%ld: PyThread_release_lock(%p) called\n",
+		 PyThread_get_thread_ident(),
+		 aLock));
+
+#if defined(PYCC_GCC)
+	if (aLock)
+		_fmutex_release((_fmutex *)aLock);
+#else
+	if (!lock->is_set) {
+		dprintf(("%ld: Could not PyThread_release_lock(%p) error: %l\n",
+			 PyThread_get_thread_ident(),
+			 aLock,
+			 GetLastError()));
+		return;
+	}
+
+	if (DosEnterCritSec()) {
+		dprintf(("%ld: Could not PyThread_release_lock(%p) error: %l\n",
+			 PyThread_get_thread_ident(),
+			 aLock,
+			 GetLastError()));
+		return;
+	}
+
+	lock->is_set = 0;
+	DosPostEventSem(lock->changed);
+
+	DosExitCritSec();
+#endif
+}
+
+/* minimum/maximum thread stack sizes supported */
+#define THREAD_MIN_STACKSIZE	0x8000		/* 32kB */
+#define THREAD_MAX_STACKSIZE	0x2000000	/* 32MB */
+
+/* set the thread stack size.
+ * Return 0 if size is valid, -1 otherwise.
+ */
+static int
+_pythread_os2_set_stacksize(size_t size)
+{
+	/* set to default */
+	if (size == 0) {
+		_pythread_stacksize = 0;
+		return 0;
+	}
+
+	/* valid range? */
+	if (size >= THREAD_MIN_STACKSIZE && size < THREAD_MAX_STACKSIZE) {
+		_pythread_stacksize = size;
+		return 0;
+	}
+
+	return -1;
+}
+
+#define THREAD_SET_STACKSIZE(x)	_pythread_os2_set_stacksize(x)

Added: vendor/Python/current/Python/thread_pth.h
===================================================================
--- vendor/Python/current/Python/thread_pth.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/thread_pth.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,213 @@
+
+/* GNU pth threads interface
+   http://www.gnu.org/software/pth
+   2000-05-03 Andy Dustman <andy at dustman.net>
+
+   Adapted from Posix threads interface 
+   12 May 1997 -- david arnold <davida at pobox.com>
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <pth.h>
+
+/* A pth mutex isn't sufficient to model the Python lock type
+ * because pth mutexes can be acquired multiple times by the
+ * same thread.
+ *
+ * The pth_lock struct implements a Python lock as a "locked?" bit
+ * and a <condition, mutex> pair.  In general, if the bit can be acquired
+ * instantly, it is, else the pair is used to block the thread until the
+ * bit is cleared.
+ */
+
+typedef struct {
+	char             locked; /* 0=unlocked, 1=locked */
+	/* a <cond, mutex> pair to handle an acquire of a locked lock */
+	pth_cond_t   lock_released;
+	pth_mutex_t  mut;
+} pth_lock;
+
+#define CHECK_STATUS(name)  if (status == -1) { printf("%d ", status); perror(name); error = 1; }
+
+pth_attr_t PyThread_attr;
+
+/*
+ * Initialization.
+ */
+
+static void PyThread__init_thread(void)
+{
+	pth_init();
+	PyThread_attr = pth_attr_new();
+	pth_attr_set(PyThread_attr, PTH_ATTR_STACK_SIZE, 1<<18);
+	pth_attr_set(PyThread_attr, PTH_ATTR_JOINABLE, FALSE);
+}
+
+/*
+ * Thread support.
+ */
+
+
+long PyThread_start_new_thread(void (*func)(void *), void *arg)
+{
+	pth_t th;
+	dprintf(("PyThread_start_new_thread called\n"));
+	if (!initialized)
+		PyThread_init_thread();
+
+	th = pth_spawn(PyThread_attr,
+				 (void* (*)(void *))func,
+				 (void *)arg
+				 );
+
+	return th;
+}
+
+long PyThread_get_thread_ident(void)
+{
+	volatile pth_t threadid;
+	if (!initialized)
+		PyThread_init_thread();
+	/* Jump through some hoops for Alpha OSF/1 */
+	threadid = pth_self();
+	return (long) *(long *) &threadid;
+}
+
+static void do_PyThread_exit_thread(int no_cleanup)
+{
+	dprintf(("PyThread_exit_thread called\n"));
+	if (!initialized) {
+		if (no_cleanup)
+			_exit(0);
+		else
+			exit(0);
+	}
+}
+
+void PyThread_exit_thread(void)
+{
+	do_PyThread_exit_thread(0);
+}
+
+void PyThread__exit_thread(void)
+{
+	do_PyThread_exit_thread(1);
+}
+
+#ifndef NO_EXIT_PROG
+static void do_PyThread_exit_prog(int status, int no_cleanup)
+{
+	dprintf(("PyThread_exit_prog(%d) called\n", status));
+	if (!initialized)
+		if (no_cleanup)
+			_exit(status);
+		else
+			exit(status);
+}
+
+void PyThread_exit_prog(int status)
+{
+	do_PyThread_exit_prog(status, 0);
+}
+
+void PyThread__exit_prog(int status)
+{
+	do_PyThread_exit_prog(status, 1);
+}
+#endif /* NO_EXIT_PROG */
+
+/*
+ * Lock support.
+ */
+PyThread_type_lock PyThread_allocate_lock(void)
+{
+	pth_lock *lock;
+	int status, error = 0;
+
+	dprintf(("PyThread_allocate_lock called\n"));
+	if (!initialized)
+		PyThread_init_thread();
+
+	lock = (pth_lock *) malloc(sizeof(pth_lock));
+        memset((void *)lock, '\0', sizeof(pth_lock));
+	if (lock) {
+		lock->locked = 0;
+		status = pth_mutex_init(&lock->mut);
+		CHECK_STATUS("pth_mutex_init");
+		status = pth_cond_init(&lock->lock_released);
+		CHECK_STATUS("pth_cond_init");
+		if (error) {
+			free((void *)lock);
+			lock = NULL;
+		}
+	}
+	dprintf(("PyThread_allocate_lock() -> %p\n", lock));
+	return (PyThread_type_lock) lock;
+}
+
+void PyThread_free_lock(PyThread_type_lock lock)
+{
+	pth_lock *thelock = (pth_lock *)lock;
+
+	dprintf(("PyThread_free_lock(%p) called\n", lock));
+
+	free((void *)thelock);
+}
+
+int PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
+{
+	int success;
+	pth_lock *thelock = (pth_lock *)lock;
+	int status, error = 0;
+
+	dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
+
+	status = pth_mutex_acquire(&thelock->mut, !waitflag, NULL);
+	CHECK_STATUS("pth_mutex_acquire[1]");
+	success = thelock->locked == 0;
+        if (success) thelock->locked = 1;
+        status = pth_mutex_release( &thelock->mut );
+        CHECK_STATUS("pth_mutex_release[1]");
+
+        if ( !success && waitflag ) {
+                /* continue trying until we get the lock */
+
+                /* mut must be locked by me -- part of the condition
+                 * protocol */
+                status = pth_mutex_acquire( &thelock->mut, !waitflag, NULL );
+                CHECK_STATUS("pth_mutex_acquire[2]");
+                while ( thelock->locked ) {
+                        status = pth_cond_await(&thelock->lock_released,
+                                                &thelock->mut, NULL);
+                        CHECK_STATUS("pth_cond_await");
+                }
+                thelock->locked = 1;
+                status = pth_mutex_release( &thelock->mut );
+                CHECK_STATUS("pth_mutex_release[2]");
+                success = 1;
+        }
+        if (error) success = 0;
+        dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
+	return success;
+}
+
+void PyThread_release_lock(PyThread_type_lock lock)
+{
+        pth_lock *thelock = (pth_lock *)lock;
+        int status, error = 0;
+
+        dprintf(("PyThread_release_lock(%p) called\n", lock));
+
+        status = pth_mutex_acquire( &thelock->mut, 0, NULL );
+        CHECK_STATUS("pth_mutex_acquire[3]");
+
+        thelock->locked = 0;
+
+        status = pth_mutex_release( &thelock->mut );
+        CHECK_STATUS("pth_mutex_release[3]");
+
+        /* wake up someone (anyone, if any) waiting on the lock */
+        status = pth_cond_notify( &thelock->lock_released, 0 );
+        CHECK_STATUS("pth_cond_notify");
+}

Added: vendor/Python/current/Python/thread_pthread.h
===================================================================
--- vendor/Python/current/Python/thread_pthread.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/thread_pthread.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,533 @@
+
+/* Posix threads interface */
+
+#include <stdlib.h>
+#include <string.h>
+#if defined(__APPLE__) || defined(HAVE_PTHREAD_DESTRUCTOR)
+#define destructor xxdestructor
+#endif
+#include <pthread.h>
+#if defined(__APPLE__) || defined(HAVE_PTHREAD_DESTRUCTOR)
+#undef destructor
+#endif
+#include <signal.h>
+
+/* The POSIX spec requires that use of pthread_attr_setstacksize
+   be conditional on _POSIX_THREAD_ATTR_STACKSIZE being defined. */
+#ifdef _POSIX_THREAD_ATTR_STACKSIZE
+#ifndef THREAD_STACK_SIZE
+#define	THREAD_STACK_SIZE	0	/* use default stack size */
+#endif
+/* for safety, ensure a viable minimum stacksize */
+#define	THREAD_STACK_MIN	0x8000	/* 32kB */
+#else  /* !_POSIX_THREAD_ATTR_STACKSIZE */
+#ifdef THREAD_STACK_SIZE
+#error "THREAD_STACK_SIZE defined but _POSIX_THREAD_ATTR_STACKSIZE undefined"
+#endif
+#endif
+
+/* The POSIX spec says that implementations supporting the sem_*
+   family of functions must indicate this by defining
+   _POSIX_SEMAPHORES. */   
+#ifdef _POSIX_SEMAPHORES
+/* On FreeBSD 4.x, _POSIX_SEMAPHORES is defined empty, so 
+   we need to add 0 to make it work there as well. */
+#if (_POSIX_SEMAPHORES+0) == -1
+#define HAVE_BROKEN_POSIX_SEMAPHORES
+#else
+#include <semaphore.h>
+#include <errno.h>
+#endif
+#endif
+
+/* Before FreeBSD 5.4, system scope threads was very limited resource
+   in default setting.  So the process scope is preferred to get
+   enough number of threads to work. */
+#ifdef __FreeBSD__
+#include <osreldate.h>
+#if __FreeBSD_version >= 500000 && __FreeBSD_version < 504101
+#undef PTHREAD_SYSTEM_SCHED_SUPPORTED
+#endif
+#endif
+
+#if !defined(pthread_attr_default)
+#  define pthread_attr_default ((pthread_attr_t *)NULL)
+#endif
+#if !defined(pthread_mutexattr_default)
+#  define pthread_mutexattr_default ((pthread_mutexattr_t *)NULL)
+#endif
+#if !defined(pthread_condattr_default)
+#  define pthread_condattr_default ((pthread_condattr_t *)NULL)
+#endif
+
+
+/* Whether or not to use semaphores directly rather than emulating them with
+ * mutexes and condition variables:
+ */
+#if defined(_POSIX_SEMAPHORES) && !defined(HAVE_BROKEN_POSIX_SEMAPHORES)
+#  define USE_SEMAPHORES
+#else
+#  undef USE_SEMAPHORES
+#endif
+
+
+/* On platforms that don't use standard POSIX threads pthread_sigmask()
+ * isn't present.  DEC threads uses sigprocmask() instead as do most
+ * other UNIX International compliant systems that don't have the full
+ * pthread implementation.
+ */
+#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
+#  define SET_THREAD_SIGMASK pthread_sigmask
+#else
+#  define SET_THREAD_SIGMASK sigprocmask
+#endif
+
+
+/* A pthread mutex isn't sufficient to model the Python lock type
+ * because, according to Draft 5 of the docs (P1003.4a/D5), both of the
+ * following are undefined:
+ *  -> a thread tries to lock a mutex it already has locked
+ *  -> a thread tries to unlock a mutex locked by a different thread
+ * pthread mutexes are designed for serializing threads over short pieces
+ * of code anyway, so wouldn't be an appropriate implementation of
+ * Python's locks regardless.
+ *
+ * The pthread_lock struct implements a Python lock as a "locked?" bit
+ * and a <condition, mutex> pair.  In general, if the bit can be acquired
+ * instantly, it is, else the pair is used to block the thread until the
+ * bit is cleared.     9 May 1994 tim at ksr.com
+ */
+
+typedef struct {
+	char             locked; /* 0=unlocked, 1=locked */
+	/* a <cond, mutex> pair to handle an acquire of a locked lock */
+	pthread_cond_t   lock_released;
+	pthread_mutex_t  mut;
+} pthread_lock;
+
+#define CHECK_STATUS(name)  if (status != 0) { perror(name); error = 1; }
+
+/*
+ * Initialization.
+ */
+
+#ifdef _HAVE_BSDI
+static
+void _noop(void)
+{
+}
+
+static void
+PyThread__init_thread(void)
+{
+	/* DO AN INIT BY STARTING THE THREAD */
+	static int dummy = 0;
+	pthread_t thread1;
+	pthread_create(&thread1, NULL, (void *) _noop, &dummy);
+	pthread_join(thread1, NULL);
+}
+
+#else /* !_HAVE_BSDI */
+
+static void
+PyThread__init_thread(void)
+{
+#if defined(_AIX) && defined(__GNUC__)
+	pthread_init();
+#endif
+}
+
+#endif /* !_HAVE_BSDI */
+
+/*
+ * Thread support.
+ */
+
+
+long
+PyThread_start_new_thread(void (*func)(void *), void *arg)
+{
+	pthread_t th;
+	int status;
+#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
+	pthread_attr_t attrs;
+#endif
+#if defined(THREAD_STACK_SIZE)
+	size_t	tss;
+#endif
+
+	dprintf(("PyThread_start_new_thread called\n"));
+	if (!initialized)
+		PyThread_init_thread();
+
+#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
+	if (pthread_attr_init(&attrs) != 0)
+		return -1;
+#endif
+#if defined(THREAD_STACK_SIZE)
+	tss = (_pythread_stacksize != 0) ? _pythread_stacksize
+					 : THREAD_STACK_SIZE;
+	if (tss != 0) {
+		if (pthread_attr_setstacksize(&attrs, tss) != 0) {
+			pthread_attr_destroy(&attrs);
+			return -1;
+		}
+	}
+#endif
+#if defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
+        pthread_attr_setscope(&attrs, PTHREAD_SCOPE_SYSTEM);
+#endif
+
+	status = pthread_create(&th, 
+#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
+				 &attrs,
+#else
+				 (pthread_attr_t*)NULL,
+#endif
+				 (void* (*)(void *))func,
+				 (void *)arg
+				 );
+
+#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
+	pthread_attr_destroy(&attrs);
+#endif
+	if (status != 0)
+            return -1;
+
+        pthread_detach(th);
+
+#if SIZEOF_PTHREAD_T <= SIZEOF_LONG
+	return (long) th;
+#else
+	return (long) *(long *) &th;
+#endif
+}
+
+/* XXX This implementation is considered (to quote Tim Peters) "inherently
+   hosed" because:
+     - It does not guarantee the promise that a non-zero integer is returned.
+     - The cast to long is inherently unsafe.
+     - It is not clear that the 'volatile' (for AIX?) and ugly casting in the
+       latter return statement (for Alpha OSF/1) are any longer necessary.
+*/
+long 
+PyThread_get_thread_ident(void)
+{
+	volatile pthread_t threadid;
+	if (!initialized)
+		PyThread_init_thread();
+	/* Jump through some hoops for Alpha OSF/1 */
+	threadid = pthread_self();
+#if SIZEOF_PTHREAD_T <= SIZEOF_LONG
+	return (long) threadid;
+#else
+	return (long) *(long *) &threadid;
+#endif
+}
+
+static void 
+do_PyThread_exit_thread(int no_cleanup)
+{
+	dprintf(("PyThread_exit_thread called\n"));
+	if (!initialized) {
+		if (no_cleanup)
+			_exit(0);
+		else
+			exit(0);
+	}
+}
+
+void 
+PyThread_exit_thread(void)
+{
+	do_PyThread_exit_thread(0);
+}
+
+void 
+PyThread__exit_thread(void)
+{
+	do_PyThread_exit_thread(1);
+}
+
+#ifndef NO_EXIT_PROG
+static void 
+do_PyThread_exit_prog(int status, int no_cleanup)
+{
+	dprintf(("PyThread_exit_prog(%d) called\n", status));
+	if (!initialized)
+		if (no_cleanup)
+			_exit(status);
+		else
+			exit(status);
+}
+
+void 
+PyThread_exit_prog(int status)
+{
+	do_PyThread_exit_prog(status, 0);
+}
+
+void 
+PyThread__exit_prog(int status)
+{
+	do_PyThread_exit_prog(status, 1);
+}
+#endif /* NO_EXIT_PROG */
+
+#ifdef USE_SEMAPHORES
+
+/*
+ * Lock support.
+ */
+
+PyThread_type_lock 
+PyThread_allocate_lock(void)
+{
+	sem_t *lock;
+	int status, error = 0;
+
+	dprintf(("PyThread_allocate_lock called\n"));
+	if (!initialized)
+		PyThread_init_thread();
+
+	lock = (sem_t *)malloc(sizeof(sem_t));
+
+	if (lock) {
+		status = sem_init(lock,0,1);
+		CHECK_STATUS("sem_init");
+
+		if (error) {
+			free((void *)lock);
+			lock = NULL;
+		}
+	}
+
+	dprintf(("PyThread_allocate_lock() -> %p\n", lock));
+	return (PyThread_type_lock)lock;
+}
+
+void 
+PyThread_free_lock(PyThread_type_lock lock)
+{
+	sem_t *thelock = (sem_t *)lock;
+	int status, error = 0;
+
+	dprintf(("PyThread_free_lock(%p) called\n", lock));
+
+	if (!thelock)
+		return;
+
+	status = sem_destroy(thelock);
+	CHECK_STATUS("sem_destroy");
+
+	free((void *)thelock);
+}
+
+/*
+ * As of February 2002, Cygwin thread implementations mistakenly report error
+ * codes in the return value of the sem_ calls (like the pthread_ functions).
+ * Correct implementations return -1 and put the code in errno. This supports
+ * either.
+ */
+static int
+fix_status(int status)
+{
+	return (status == -1) ? errno : status;
+}
+
+int 
+PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
+{
+	int success;
+	sem_t *thelock = (sem_t *)lock;
+	int status, error = 0;
+
+	dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
+
+	do {
+		if (waitflag)
+			status = fix_status(sem_wait(thelock));
+		else
+			status = fix_status(sem_trywait(thelock));
+	} while (status == EINTR); /* Retry if interrupted by a signal */
+
+	if (waitflag) {
+		CHECK_STATUS("sem_wait");
+	} else if (status != EAGAIN) {
+		CHECK_STATUS("sem_trywait");
+	}
+	
+	success = (status == 0) ? 1 : 0;
+
+	dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
+	return success;
+}
+
+void 
+PyThread_release_lock(PyThread_type_lock lock)
+{
+	sem_t *thelock = (sem_t *)lock;
+	int status, error = 0;
+
+	dprintf(("PyThread_release_lock(%p) called\n", lock));
+
+	status = sem_post(thelock);
+	CHECK_STATUS("sem_post");
+}
+
+#else /* USE_SEMAPHORES */
+
+/*
+ * Lock support.
+ */
+PyThread_type_lock 
+PyThread_allocate_lock(void)
+{
+	pthread_lock *lock;
+	int status, error = 0;
+
+	dprintf(("PyThread_allocate_lock called\n"));
+	if (!initialized)
+		PyThread_init_thread();
+
+	lock = (pthread_lock *) malloc(sizeof(pthread_lock));
+	if (lock) {
+		memset((void *)lock, '\0', sizeof(pthread_lock));
+		lock->locked = 0;
+
+		status = pthread_mutex_init(&lock->mut,
+					    pthread_mutexattr_default);
+		CHECK_STATUS("pthread_mutex_init");
+
+		status = pthread_cond_init(&lock->lock_released,
+					   pthread_condattr_default);
+		CHECK_STATUS("pthread_cond_init");
+
+		if (error) {
+			free((void *)lock);
+			lock = 0;
+		}
+	}
+
+	dprintf(("PyThread_allocate_lock() -> %p\n", lock));
+	return (PyThread_type_lock) lock;
+}
+
+void 
+PyThread_free_lock(PyThread_type_lock lock)
+{
+	pthread_lock *thelock = (pthread_lock *)lock;
+	int status, error = 0;
+
+	dprintf(("PyThread_free_lock(%p) called\n", lock));
+
+	status = pthread_mutex_destroy( &thelock->mut );
+	CHECK_STATUS("pthread_mutex_destroy");
+
+	status = pthread_cond_destroy( &thelock->lock_released );
+	CHECK_STATUS("pthread_cond_destroy");
+
+	free((void *)thelock);
+}
+
+int 
+PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
+{
+	int success;
+	pthread_lock *thelock = (pthread_lock *)lock;
+	int status, error = 0;
+
+	dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
+
+	status = pthread_mutex_lock( &thelock->mut );
+	CHECK_STATUS("pthread_mutex_lock[1]");
+	success = thelock->locked == 0;
+
+	if ( !success && waitflag ) {
+		/* continue trying until we get the lock */
+
+		/* mut must be locked by me -- part of the condition
+		 * protocol */
+		while ( thelock->locked ) {
+			status = pthread_cond_wait(&thelock->lock_released,
+						   &thelock->mut);
+			CHECK_STATUS("pthread_cond_wait");
+		}
+		success = 1;
+	}
+	if (success) thelock->locked = 1;
+	status = pthread_mutex_unlock( &thelock->mut );
+	CHECK_STATUS("pthread_mutex_unlock[1]");
+
+	if (error) success = 0;
+	dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
+	return success;
+}
+
+void 
+PyThread_release_lock(PyThread_type_lock lock)
+{
+	pthread_lock *thelock = (pthread_lock *)lock;
+	int status, error = 0;
+
+	dprintf(("PyThread_release_lock(%p) called\n", lock));
+
+	status = pthread_mutex_lock( &thelock->mut );
+	CHECK_STATUS("pthread_mutex_lock[3]");
+
+	thelock->locked = 0;
+
+	status = pthread_mutex_unlock( &thelock->mut );
+	CHECK_STATUS("pthread_mutex_unlock[3]");
+
+	/* wake up someone (anyone, if any) waiting on the lock */
+	status = pthread_cond_signal( &thelock->lock_released );
+	CHECK_STATUS("pthread_cond_signal");
+}
+
+#endif /* USE_SEMAPHORES */
+
+/* set the thread stack size.
+ * Return 0 if size is valid, -1 if size is invalid,
+ * -2 if setting stack size is not supported.
+ */
+static int
+_pythread_pthread_set_stacksize(size_t size)
+{
+#if defined(THREAD_STACK_SIZE)
+	pthread_attr_t attrs;
+	size_t tss_min;
+	int rc = 0;
+#endif
+
+	/* set to default */
+	if (size == 0) {
+		_pythread_stacksize = 0;
+		return 0;
+	}
+
+#if defined(THREAD_STACK_SIZE)
+#if defined(PTHREAD_STACK_MIN)
+	tss_min = PTHREAD_STACK_MIN > THREAD_STACK_MIN ? PTHREAD_STACK_MIN
+						       : THREAD_STACK_MIN;
+#else
+	tss_min = THREAD_STACK_MIN;
+#endif
+	if (size >= tss_min) {
+		/* validate stack size by setting thread attribute */
+		if (pthread_attr_init(&attrs) == 0) {
+			rc = pthread_attr_setstacksize(&attrs, size);
+			pthread_attr_destroy(&attrs);
+			if (rc == 0) {
+				_pythread_stacksize = size;
+				return 0;
+			}
+		}
+	}
+	return -1;
+#else
+	return -2;
+#endif
+}
+
+#define THREAD_SET_STACKSIZE(x)	_pythread_pthread_set_stacksize(x)

Added: vendor/Python/current/Python/thread_sgi.h
===================================================================
--- vendor/Python/current/Python/thread_sgi.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/thread_sgi.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,375 @@
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/prctl.h>
+#include <ulocks.h>
+#include <errno.h>
+
+#define HDR_SIZE	2680	/* sizeof(ushdr_t) */
+#define MAXPROC		100	/* max # of threads that can be started */
+
+static usptr_t *shared_arena;
+static ulock_t count_lock;	/* protection for some variables */
+static ulock_t wait_lock;	/* lock used to wait for other threads */
+static int waiting_for_threads;	/* protected by count_lock */
+static int nthreads;		/* protected by count_lock */
+static int exit_status;
+#ifndef NO_EXIT_PROG
+static int do_exit;		/* indicates that the program is to exit */
+#endif
+static int exiting;		/* we're already exiting (for maybe_exit) */
+static pid_t my_pid;		/* PID of main thread */
+static struct pidlist {
+	pid_t parent;
+	pid_t child;
+} pidlist[MAXPROC];	/* PIDs of other threads; protected by count_lock */
+static int maxpidindex;		/* # of PIDs in pidlist */
+
+#ifndef NO_EXIT_PROG
+/*
+ * This routine is called as a signal handler when another thread
+ * exits.  When that happens, we must see whether we have to exit as
+ * well (because of an PyThread_exit_prog()) or whether we should continue on.
+ */
+static void exit_sig(void)
+{
+	d2printf(("exit_sig called\n"));
+	if (exiting && getpid() == my_pid) {
+		d2printf(("already exiting\n"));
+		return;
+	}
+	if (do_exit) {
+		d2printf(("exiting in exit_sig\n"));
+#ifdef Py_DEBUG
+		if ((thread_debug & 8) == 0)
+			thread_debug &= ~1; /* don't produce debug messages */
+#endif
+		PyThread_exit_thread();
+	}
+}
+
+/*
+ * This routine is called when a process calls exit().  If that wasn't
+ * done from the library, we do as if an PyThread_exit_prog() was intended.
+ */
+static void maybe_exit(void)
+{
+	dprintf(("maybe_exit called\n"));
+	if (exiting) {
+		dprintf(("already exiting\n"));
+		return;
+	}
+	PyThread_exit_prog(0);
+}
+#endif /* NO_EXIT_PROG */
+
+/*
+ * Initialization.
+ */
+static void PyThread__init_thread(void)
+{
+#ifndef NO_EXIT_PROG
+	struct sigaction s;
+#endif /* NO_EXIT_PROG */
+#ifdef USE_DL
+	long addr, size;
+#endif /* USE_DL */
+
+
+#ifdef USE_DL
+	if ((size = usconfig(CONF_INITSIZE, 64*1024)) < 0)
+		perror("usconfig - CONF_INITSIZE (check)");
+	if (usconfig(CONF_INITSIZE, size) < 0)
+		perror("usconfig - CONF_INITSIZE (reset)");
+	addr = (long) dl_getrange(size + HDR_SIZE);
+	dprintf(("trying to use addr %p-%p for shared arena\n", addr, addr+size));
+	errno = 0;
+	if ((addr = usconfig(CONF_ATTACHADDR, addr)) < 0 && errno != 0)
+		perror("usconfig - CONF_ATTACHADDR (set)");
+#endif /* USE_DL */
+	if (usconfig(CONF_INITUSERS, 16) < 0)
+		perror("usconfig - CONF_INITUSERS");
+	my_pid = getpid();	/* so that we know which is the main thread */
+#ifndef NO_EXIT_PROG
+	atexit(maybe_exit);
+	s.sa_handler = exit_sig;
+	sigemptyset(&s.sa_mask);
+	/*sigaddset(&s.sa_mask, SIGUSR1);*/
+	s.sa_flags = 0;
+	sigaction(SIGUSR1, &s, 0);
+	if (prctl(PR_SETEXITSIG, SIGUSR1) < 0)
+		perror("prctl - PR_SETEXITSIG");
+#endif /* NO_EXIT_PROG */
+	if (usconfig(CONF_ARENATYPE, US_SHAREDONLY) < 0)
+		perror("usconfig - CONF_ARENATYPE");
+	usconfig(CONF_LOCKTYPE, US_DEBUG); /* XXX */
+#ifdef Py_DEBUG
+	if (thread_debug & 4)
+		usconfig(CONF_LOCKTYPE, US_DEBUGPLUS);
+	else if (thread_debug & 2)
+		usconfig(CONF_LOCKTYPE, US_DEBUG);
+#endif /* Py_DEBUG */
+	if ((shared_arena = usinit(tmpnam(0))) == 0)
+		perror("usinit");
+#ifdef USE_DL
+	if (usconfig(CONF_ATTACHADDR, addr) < 0) /* reset address */
+		perror("usconfig - CONF_ATTACHADDR (reset)");
+#endif /* USE_DL */
+	if ((count_lock = usnewlock(shared_arena)) == NULL)
+		perror("usnewlock (count_lock)");
+	(void) usinitlock(count_lock);
+	if ((wait_lock = usnewlock(shared_arena)) == NULL)
+		perror("usnewlock (wait_lock)");
+	dprintf(("arena start: %p, arena size: %ld\n",  shared_arena, (long) usconfig(CONF_GETSIZE, shared_arena)));
+}
+
+/*
+ * Thread support.
+ */
+
+static void clean_threads(void)
+{
+	int i, j;
+	pid_t mypid, pid;
+
+	/* clean up any exited threads */
+	mypid = getpid();
+	i = 0;
+	while (i < maxpidindex) {
+		if (pidlist[i].parent == mypid && (pid = pidlist[i].child) > 0) {
+			pid = waitpid(pid, 0, WNOHANG);
+			if (pid > 0) {
+				/* a thread has exited */
+				pidlist[i] = pidlist[--maxpidindex];
+				/* remove references to children of dead proc */
+				for (j = 0; j < maxpidindex; j++)
+					if (pidlist[j].parent == pid)
+						pidlist[j].child = -1;
+				continue; /* don't increment i */
+			}
+		}
+		i++;
+	}
+	/* clean up the list */
+	i = 0;
+	while (i < maxpidindex) {
+		if (pidlist[i].child == -1) {
+			pidlist[i] = pidlist[--maxpidindex];
+			continue; /* don't increment i */
+		}
+		i++;
+	}
+}
+
+long PyThread_start_new_thread(void (*func)(void *), void *arg)
+{
+#ifdef USE_DL
+	long addr, size;
+	static int local_initialized = 0;
+#endif /* USE_DL */
+	int success = 0;	/* init not needed when SOLARIS_THREADS and */
+				/* C_THREADS implemented properly */
+
+	dprintf(("PyThread_start_new_thread called\n"));
+	if (!initialized)
+		PyThread_init_thread();
+	switch (ussetlock(count_lock)) {
+	case 0: return 0;
+	case -1: perror("ussetlock (count_lock)");
+	}
+	if (maxpidindex >= MAXPROC)
+		success = -1;
+	else {
+#ifdef USE_DL
+		if (!local_initialized) {
+			if ((size = usconfig(CONF_INITSIZE, 64*1024)) < 0)
+				perror("usconfig - CONF_INITSIZE (check)");
+			if (usconfig(CONF_INITSIZE, size) < 0)
+				perror("usconfig - CONF_INITSIZE (reset)");
+			addr = (long) dl_getrange(size + HDR_SIZE);
+			dprintf(("trying to use addr %p-%p for sproc\n",
+				 addr, addr+size));
+			errno = 0;
+			if ((addr = usconfig(CONF_ATTACHADDR, addr)) < 0 &&
+			    errno != 0)
+				perror("usconfig - CONF_ATTACHADDR (set)");
+		}
+#endif /* USE_DL */
+		clean_threads();
+		if ((success = sproc(func, PR_SALL, arg)) < 0)
+			perror("sproc");
+#ifdef USE_DL
+		if (!local_initialized) {
+			if (usconfig(CONF_ATTACHADDR, addr) < 0)
+				/* reset address */
+				perror("usconfig - CONF_ATTACHADDR (reset)");
+			local_initialized = 1;
+		}
+#endif /* USE_DL */
+		if (success >= 0) {
+			nthreads++;
+			pidlist[maxpidindex].parent = getpid();
+			pidlist[maxpidindex++].child = success;
+			dprintf(("pidlist[%d] = %d\n",
+				 maxpidindex-1, success));
+		}
+	}
+	if (usunsetlock(count_lock) < 0)
+		perror("usunsetlock (count_lock)");
+	return success;
+}
+
+long PyThread_get_thread_ident(void)
+{
+	return getpid();
+}
+
+static void do_PyThread_exit_thread(int no_cleanup)
+{
+	dprintf(("PyThread_exit_thread called\n"));
+	if (!initialized)
+		if (no_cleanup)
+			_exit(0);
+		else
+			exit(0);
+	if (ussetlock(count_lock) < 0)
+		perror("ussetlock (count_lock)");
+	nthreads--;
+	if (getpid() == my_pid) {
+		/* main thread; wait for other threads to exit */
+		exiting = 1;
+#ifndef NO_EXIT_PROG
+		if (do_exit) {
+			int i;
+
+			/* notify other threads */
+			clean_threads();
+			if (nthreads >= 0) {
+				dprintf(("kill other threads\n"));
+				for (i = 0; i < maxpidindex; i++)
+					if (pidlist[i].child > 0)
+						(void) kill(pidlist[i].child,
+							    SIGKILL);
+				_exit(exit_status);
+			}
+		}
+#endif /* NO_EXIT_PROG */
+		waiting_for_threads = 1;
+		if (ussetlock(wait_lock) < 0)
+			perror("ussetlock (wait_lock)");
+		for (;;) {
+			if (nthreads < 0) {
+				dprintf(("really exit (%d)\n", exit_status));
+				if (no_cleanup)
+					_exit(exit_status);
+				else
+					exit(exit_status);
+			}
+			if (usunsetlock(count_lock) < 0)
+				perror("usunsetlock (count_lock)");
+			dprintf(("waiting for other threads (%d)\n", nthreads));
+			if (ussetlock(wait_lock) < 0)
+				perror("ussetlock (wait_lock)");
+			if (ussetlock(count_lock) < 0)
+				perror("ussetlock (count_lock)");
+		}
+	}
+	/* not the main thread */
+	if (waiting_for_threads) {
+		dprintf(("main thread is waiting\n"));
+		if (usunsetlock(wait_lock) < 0)
+			perror("usunsetlock (wait_lock)");
+	}
+#ifndef NO_EXIT_PROG
+	else if (do_exit)
+		(void) kill(my_pid, SIGUSR1);
+#endif /* NO_EXIT_PROG */
+	if (usunsetlock(count_lock) < 0)
+		perror("usunsetlock (count_lock)");
+	_exit(0);
+}
+
+void PyThread_exit_thread(void)
+{
+	do_PyThread_exit_thread(0);
+}
+
+void PyThread__exit_thread(void)
+{
+	do_PyThread_exit_thread(1);
+}
+
+#ifndef NO_EXIT_PROG
+static void do_PyThread_exit_prog(int status, int no_cleanup)
+{
+	dprintf(("PyThread_exit_prog(%d) called\n", status));
+	if (!initialized)
+		if (no_cleanup)
+			_exit(status);
+		else
+			exit(status);
+	do_exit = 1;
+	exit_status = status;
+	do_PyThread_exit_thread(no_cleanup);
+}
+
+void PyThread_exit_prog(int status)
+{
+	do_PyThread_exit_prog(status, 0);
+}
+
+void PyThread__exit_prog(int status)
+{
+	do_PyThread_exit_prog(status, 1);
+}
+#endif /* NO_EXIT_PROG */
+
+/*
+ * Lock support.
+ */
+PyThread_type_lock PyThread_allocate_lock(void)
+{
+	ulock_t lock;
+
+	dprintf(("PyThread_allocate_lock called\n"));
+	if (!initialized)
+		PyThread_init_thread();
+
+	if ((lock = usnewlock(shared_arena)) == NULL)
+		perror("usnewlock");
+	(void) usinitlock(lock);
+	dprintf(("PyThread_allocate_lock() -> %p\n", lock));
+	return (PyThread_type_lock) lock;
+}
+
+void PyThread_free_lock(PyThread_type_lock lock)
+{
+	dprintf(("PyThread_free_lock(%p) called\n", lock));
+	usfreelock((ulock_t) lock, shared_arena);
+}
+
+int PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
+{
+	int success;
+
+	dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
+	errno = 0;		/* clear it just in case */
+	if (waitflag)
+		success = ussetlock((ulock_t) lock);
+	else
+		success = uscsetlock((ulock_t) lock, 1); /* Try it once */
+	if (success < 0)
+		perror(waitflag ? "ussetlock" : "uscsetlock");
+	dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
+	return success;
+}
+
+void PyThread_release_lock(PyThread_type_lock lock)
+{
+	dprintf(("PyThread_release_lock(%p) called\n", lock));
+	if (usunsetlock((ulock_t) lock) < 0)
+		perror("usunsetlock");
+}

Added: vendor/Python/current/Python/thread_solaris.h
===================================================================
--- vendor/Python/current/Python/thread_solaris.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/thread_solaris.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,174 @@
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include </usr/include/thread.h>
+#undef _POSIX_THREADS
+
+
+/*
+ * Initialization.
+ */
+static void PyThread__init_thread(void)
+{
+}
+
+/*
+ * Thread support.
+ */
+struct func_arg {
+	void (*func)(void *);
+	void *arg;
+};
+
+static void *
+new_func(void *funcarg)
+{
+	void (*func)(void *);
+	void *arg;
+
+	func = ((struct func_arg *) funcarg)->func;
+	arg = ((struct func_arg *) funcarg)->arg;
+	free(funcarg);
+	(*func)(arg);
+	return 0;
+}
+
+
+long
+PyThread_start_new_thread(void (*func)(void *), void *arg)
+{
+	thread_t tid;
+	struct func_arg *funcarg;
+
+	dprintf(("PyThread_start_new_thread called\n"));
+	if (!initialized)
+		PyThread_init_thread();
+	funcarg = (struct func_arg *) malloc(sizeof(struct func_arg));
+	funcarg->func = func;
+	funcarg->arg = arg;
+	if (thr_create(0, 0, new_func, funcarg,
+		       THR_DETACHED | THR_NEW_LWP, &tid)) {
+		perror("thr_create");
+		free((void *) funcarg);
+		return -1;
+	}
+	return tid;
+}
+
+long
+PyThread_get_thread_ident(void)
+{
+	if (!initialized)
+		PyThread_init_thread();
+	return thr_self();
+}
+
+static void 
+do_PyThread_exit_thread(int no_cleanup)
+{
+	dprintf(("PyThread_exit_thread called\n"));
+	if (!initialized)
+		if (no_cleanup)
+			_exit(0);
+		else
+			exit(0);
+	thr_exit(0);
+}
+
+void 
+PyThread_exit_thread(void)
+{
+	do_PyThread_exit_thread(0);
+}
+
+void 
+PyThread__exit_thread(void)
+{
+	do_PyThread_exit_thread(1);
+}
+
+#ifndef NO_EXIT_PROG
+static void 
+do_PyThread_exit_prog(int status, int no_cleanup)
+{
+	dprintf(("PyThread_exit_prog(%d) called\n", status));
+	if (!initialized)
+		if (no_cleanup)
+			_exit(status);
+		else
+			exit(status);
+	if (no_cleanup)
+		_exit(status);
+	else
+		exit(status);
+}
+
+void 
+PyThread_exit_prog(int status)
+{
+	do_PyThread_exit_prog(status, 0);
+}
+
+void 
+PyThread__exit_prog(int status)
+{
+	do_PyThread_exit_prog(status, 1);
+}
+#endif /* NO_EXIT_PROG */
+
+/*
+ * Lock support.
+ */
+PyThread_type_lock 
+PyThread_allocate_lock(void)
+{
+	mutex_t *lock;
+
+	dprintf(("PyThread_allocate_lock called\n"));
+	if (!initialized)
+		PyThread_init_thread();
+
+	lock = (mutex_t *) malloc(sizeof(mutex_t));
+	if (mutex_init(lock, USYNC_THREAD, 0)) {
+		perror("mutex_init");
+		free((void *) lock);
+		lock = 0;
+	}
+	dprintf(("PyThread_allocate_lock() -> %p\n", lock));
+	return (PyThread_type_lock) lock;
+}
+
+void 
+PyThread_free_lock(PyThread_type_lock lock)
+{
+	dprintf(("PyThread_free_lock(%p) called\n", lock));
+	mutex_destroy((mutex_t *) lock);
+	free((void *) lock);
+}
+
+int 
+PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
+{
+	int success;
+
+	dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
+	if (waitflag)
+		success = mutex_lock((mutex_t *) lock);
+	else
+		success = mutex_trylock((mutex_t *) lock);
+	if (success < 0)
+		perror(waitflag ? "mutex_lock" : "mutex_trylock");
+	else
+		success = !success; /* solaris does it the other way round */
+	dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
+	return success;
+}
+
+void 
+PyThread_release_lock(PyThread_type_lock lock)
+{
+	dprintf(("PyThread_release_lock(%p) called\n", lock));
+	if (mutex_unlock((mutex_t *) lock))
+		perror("mutex_unlock");
+}

Added: vendor/Python/current/Python/thread_wince.h
===================================================================
--- vendor/Python/current/Python/thread_wince.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/thread_wince.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,171 @@
+
+/* This code implemented by Mark Hammond (MHammond at skippinet.com.au) */
+
+#include <windows.h>
+#include <limits.h>
+#include <pydebug.h>
+
+long PyThread_get_thread_ident(void);
+
+/*
+ * Change all headers to pure ANSI as no one will use K&R style on an
+ * NT
+ */
+
+/*
+ * Initialization of the C package, should not be needed.
+ */
+static void PyThread__init_thread(void)
+{
+}
+
+/*
+ * Thread support.
+ */
+long PyThread_start_new_thread(void (*func)(void *), void *arg)
+{
+	long rv;
+	int success = -1;
+
+	dprintf(("%ld: PyThread_start_new_thread called\n", PyThread_get_thread_ident()));
+	if (!initialized)
+		PyThread_init_thread();
+
+	rv = _beginthread(func, 0, arg); /* use default stack size */
+ 
+	if (rv != -1) {
+		success = 0;
+		dprintf(("%ld: PyThread_start_new_thread succeeded:\n", PyThread_get_thread_ident()));
+	}
+
+	return success;
+}
+
+/*
+ * Return the thread Id instead of an handle. The Id is said to uniquely identify the
+ * thread in the system
+ */
+long PyThread_get_thread_ident(void)
+{
+	if (!initialized)
+		PyThread_init_thread();
+        
+	return GetCurrentThreadId();
+}
+
+static void do_PyThread_exit_thread(int no_cleanup)
+{
+	dprintf(("%ld: do_PyThread_exit_thread called\n", PyThread_get_thread_ident()));
+	if (!initialized)
+		if (no_cleanup)
+			exit(0); /* XXX - was _exit()!! */
+		else
+			exit(0);
+	_endthread();
+}
+
+void PyThread_exit_thread(void)
+{
+	do_PyThread_exit_thread(0);
+}
+
+void PyThread__exit_thread(void)
+{
+	do_PyThread_exit_thread(1);
+}
+
+#ifndef NO_EXIT_PROG
+static void do_PyThread_exit_prog(int status, int no_cleanup)
+{
+	dprintf(("PyThread_exit_prog(%d) called\n", status));
+	if (!initialized)
+		if (no_cleanup)
+			_exit(status);
+		else
+			exit(status);
+}
+
+void PyThread_exit_prog(int status)
+{
+	do_PyThread_exit_prog(status, 0);
+}
+
+void PyThread__exit_prog(int status)
+{
+	do_PyThread_exit_prog(status, 1);
+}
+#endif /* NO_EXIT_PROG */
+
+/*
+ * Lock support. It has to be implemented using Mutexes, as
+ * CE doesnt support semaphores.  Therefore we use some hacks to
+ * simulate the non reentrant requirements of Python locks
+ */
+PyThread_type_lock PyThread_allocate_lock(void)
+{
+    HANDLE aLock;
+
+    dprintf(("PyThread_allocate_lock called\n"));
+    if (!initialized)
+        PyThread_init_thread();
+
+    aLock = CreateEvent(NULL,           /* Security attributes      */
+                        0,              /* Manual-Reset               */
+						1,              /* Is initially signalled  */
+                        NULL);          /* Name of event            */
+
+    dprintf(("%ld: PyThread_allocate_lock() -> %p\n", PyThread_get_thread_ident(), aLock));
+
+    return (PyThread_type_lock) aLock;
+}
+
+void PyThread_free_lock(PyThread_type_lock aLock)
+{
+    dprintf(("%ld: PyThread_free_lock(%p) called\n", PyThread_get_thread_ident(),aLock));
+
+    CloseHandle(aLock);
+}
+
+/*
+ * Return 1 on success if the lock was acquired
+ *
+ * and 0 if the lock was not acquired. This means a 0 is returned
+ * if the lock has already been acquired by this thread!
+ */
+int PyThread_acquire_lock(PyThread_type_lock aLock, int waitflag)
+{
+    int success = 1;
+    DWORD waitResult;
+
+    dprintf(("%ld: PyThread_acquire_lock(%p, %d) called\n", PyThread_get_thread_ident(),aLock, waitflag));
+
+#ifndef DEBUG
+    waitResult = WaitForSingleObject(aLock, (waitflag ? INFINITE : 0));
+#else
+	/* To aid in debugging, we regularly wake up.  This allows us to
+	break into the debugger */
+	while (TRUE) {
+		waitResult = WaitForSingleObject(aLock, waitflag ? 3000 : 0);
+		if (waitflag==0 || (waitflag && waitResult == WAIT_OBJECT_0))
+			break;
+	}
+#endif
+
+    if (waitResult != WAIT_OBJECT_0) {
+		success = 0;    /* We failed */
+    }
+
+	dprintf(("%ld: PyThread_acquire_lock(%p, %d) -> %d\n", PyThread_get_thread_ident(),aLock, waitflag, success));
+
+	return success;
+}
+
+void PyThread_release_lock(PyThread_type_lock aLock)
+{
+    dprintf(("%ld: PyThread_release_lock(%p) called\n", PyThread_get_thread_ident(),aLock));
+
+    if (!SetEvent(aLock))
+        dprintf(("%ld: Could not PyThread_release_lock(%p) error: %l\n", PyThread_get_thread_ident(), aLock, GetLastError()));
+}
+
+

Added: vendor/Python/current/Python/traceback.c
===================================================================
--- vendor/Python/current/Python/traceback.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Python/traceback.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,262 @@
+
+/* Traceback implementation */
+
+#include "Python.h"
+
+#include "code.h"
+#include "frameobject.h"
+#include "structmember.h"
+#include "osdefs.h"
+#include "traceback.h"
+
+#define OFF(x) offsetof(PyTracebackObject, x)
+
+static struct memberlist tb_memberlist[] = {
+	{"tb_next",	T_OBJECT,	OFF(tb_next)},
+	{"tb_frame",	T_OBJECT,	OFF(tb_frame)},
+	{"tb_lasti",	T_INT,		OFF(tb_lasti)},
+	{"tb_lineno",	T_INT,		OFF(tb_lineno)},
+	{NULL}	/* Sentinel */
+};
+
+static PyObject *
+tb_getattr(PyTracebackObject *tb, char *name)
+{
+	return PyMember_Get((char *)tb, tb_memberlist, name);
+}
+
+static void
+tb_dealloc(PyTracebackObject *tb)
+{
+	PyObject_GC_UnTrack(tb);
+	Py_TRASHCAN_SAFE_BEGIN(tb)
+	Py_XDECREF(tb->tb_next);
+	Py_XDECREF(tb->tb_frame);
+	PyObject_GC_Del(tb);
+	Py_TRASHCAN_SAFE_END(tb)
+}
+
+static int
+tb_traverse(PyTracebackObject *tb, visitproc visit, void *arg)
+{
+	Py_VISIT(tb->tb_next);
+	Py_VISIT(tb->tb_frame);
+	return 0;
+}
+
+static void
+tb_clear(PyTracebackObject *tb)
+{
+	Py_CLEAR(tb->tb_next);
+	Py_CLEAR(tb->tb_frame);
+}
+
+PyTypeObject PyTraceBack_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,
+	"traceback",
+	sizeof(PyTracebackObject),
+	0,
+	(destructor)tb_dealloc, /*tp_dealloc*/
+	0,		/*tp_print*/
+	(getattrfunc)tb_getattr, /*tp_getattr*/
+	0,		/*tp_setattr*/
+	0,		/*tp_compare*/
+	0,		/*tp_repr*/
+	0,		/*tp_as_number*/
+	0,		/*tp_as_sequence*/
+	0,		/*tp_as_mapping*/
+	0,		/* tp_hash */
+	0,		/* tp_call */
+	0,		/* tp_str */
+	0,		/* tp_getattro */
+	0,		/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+	0,             				/* tp_doc */
+ 	(traverseproc)tb_traverse,		/* tp_traverse */
+	(inquiry)tb_clear,			/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	0,					/* tp_methods */
+	0,			/* tp_members */
+	0,			/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+};
+
+static PyTracebackObject *
+newtracebackobject(PyTracebackObject *next, PyFrameObject *frame)
+{
+	PyTracebackObject *tb;
+	if ((next != NULL && !PyTraceBack_Check(next)) ||
+			frame == NULL || !PyFrame_Check(frame)) {
+		PyErr_BadInternalCall();
+		return NULL;
+	}
+	tb = PyObject_GC_New(PyTracebackObject, &PyTraceBack_Type);
+	if (tb != NULL) {
+		Py_XINCREF(next);
+		tb->tb_next = next;
+		Py_XINCREF(frame);
+		tb->tb_frame = frame;
+		tb->tb_lasti = frame->f_lasti;
+		tb->tb_lineno = PyCode_Addr2Line(frame->f_code, 
+						 frame->f_lasti);
+		PyObject_GC_Track(tb);
+	}
+	return tb;
+}
+
+int
+PyTraceBack_Here(PyFrameObject *frame)
+{
+	PyThreadState *tstate = PyThreadState_GET();
+	PyTracebackObject *oldtb = (PyTracebackObject *) tstate->curexc_traceback;
+	PyTracebackObject *tb = newtracebackobject(oldtb, frame);
+	if (tb == NULL)
+		return -1;
+	tstate->curexc_traceback = (PyObject *)tb;
+	Py_XDECREF(oldtb);
+	return 0;
+}
+
+static int
+tb_displayline(PyObject *f, char *filename, int lineno, char *name)
+{
+	int err = 0;
+	FILE *xfp;
+	char linebuf[2000];
+	int i;
+	if (filename == NULL || name == NULL)
+		return -1;
+	/* This is needed by Emacs' compile command */
+#define FMT "  File \"%.500s\", line %d, in %.500s\n"
+	xfp = fopen(filename, "r" PY_STDIOTEXTMODE);
+	if (xfp == NULL) {
+		/* Search tail of filename in sys.path before giving up */
+		PyObject *path;
+		char *tail = strrchr(filename, SEP);
+		if (tail == NULL)
+			tail = filename;
+		else
+			tail++;
+		path = PySys_GetObject("path");
+		if (path != NULL && PyList_Check(path)) {
+			Py_ssize_t _npath = PyList_Size(path);
+			int npath = Py_SAFE_DOWNCAST(_npath, Py_ssize_t, int);
+			size_t taillen = strlen(tail);
+			char namebuf[MAXPATHLEN+1];
+			for (i = 0; i < npath; i++) {
+				PyObject *v = PyList_GetItem(path, i);
+				if (v == NULL) {
+					PyErr_Clear();
+					break;
+				}
+				if (PyString_Check(v)) {
+					size_t len;
+					len = PyString_GET_SIZE(v);
+					if (len + 1 + taillen >= MAXPATHLEN)
+						continue; /* Too long */
+					strcpy(namebuf, PyString_AsString(v));
+					if (strlen(namebuf) != len)
+						continue; /* v contains '\0' */
+					if (len > 0 && namebuf[len-1] != SEP)
+						namebuf[len++] = SEP;
+					strcpy(namebuf+len, tail);
+					xfp = fopen(namebuf, "r" PY_STDIOTEXTMODE);
+					if (xfp != NULL) {
+						filename = namebuf;
+						break;
+					}
+				}
+			}
+		}
+	}
+	PyOS_snprintf(linebuf, sizeof(linebuf), FMT, filename, lineno, name);
+	err = PyFile_WriteString(linebuf, f);
+	if (xfp == NULL)
+		return err;
+	else if (err != 0) {
+		fclose(xfp);
+		return err;
+	}
+	for (i = 0; i < lineno; i++) {
+		char* pLastChar = &linebuf[sizeof(linebuf)-2];
+		do {
+			*pLastChar = '\0';
+			if (Py_UniversalNewlineFgets(linebuf, sizeof linebuf, xfp, NULL) == NULL)
+				break;
+			/* fgets read *something*; if it didn't get as
+			   far as pLastChar, it must have found a newline
+			   or hit the end of the file;	if pLastChar is \n,
+			   it obviously found a newline; else we haven't
+			   yet seen a newline, so must continue */
+		} while (*pLastChar != '\0' && *pLastChar != '\n');
+	}
+	if (i == lineno) {
+		char *p = linebuf;
+		while (*p == ' ' || *p == '\t' || *p == '\014')
+			p++;
+		err = PyFile_WriteString("    ", f);
+		if (err == 0) {
+			err = PyFile_WriteString(p, f);
+			if (err == 0 && strchr(p, '\n') == NULL)
+				err = PyFile_WriteString("\n", f);
+		}
+	}
+	fclose(xfp);
+	return err;
+}
+
+static int
+tb_printinternal(PyTracebackObject *tb, PyObject *f, int limit)
+{
+	int err = 0;
+	int depth = 0;
+	PyTracebackObject *tb1 = tb;
+	while (tb1 != NULL) {
+		depth++;
+		tb1 = tb1->tb_next;
+	}
+	while (tb != NULL && err == 0) {
+		if (depth <= limit) {
+			err = tb_displayline(f,
+			    PyString_AsString(
+				    tb->tb_frame->f_code->co_filename),
+			    tb->tb_lineno,
+			    PyString_AsString(tb->tb_frame->f_code->co_name));
+		}
+		depth--;
+		tb = tb->tb_next;
+		if (err == 0)
+			err = PyErr_CheckSignals();
+	}
+	return err;
+}
+
+int
+PyTraceBack_Print(PyObject *v, PyObject *f)
+{
+	int err;
+	PyObject *limitv;
+	int limit = 1000;
+	if (v == NULL)
+		return 0;
+	if (!PyTraceBack_Check(v)) {
+		PyErr_BadInternalCall();
+		return -1;
+	}
+	limitv = PySys_GetObject("tracebacklimit");
+	if (limitv && PyInt_Check(limitv)) {
+		limit = PyInt_AsLong(limitv);
+		if (limit <= 0)
+			return 0;
+	}
+	err = PyFile_WriteString("Traceback (most recent call last):\n", f);
+	if (!err)
+		err = tb_printinternal((PyTracebackObject *)v, f, limit);
+	return err;
+}

Added: vendor/Python/current/README
===================================================================
--- vendor/Python/current/README	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/README	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1297 @@
+This is Python version 2.5.1
+============================
+
+Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Python Software 
+Foundation. 
+All rights reserved.
+
+Copyright (c) 2000 BeOpen.com.
+All rights reserved.
+
+Copyright (c) 1995-2001 Corporation for National Research Initiatives.
+All rights reserved.
+
+Copyright (c) 1991-1995 Stichting Mathematisch Centrum.
+All rights reserved.
+
+
+License information
+-------------------
+
+See the file "LICENSE" for information on the history of this
+software, terms & conditions for usage, and a DISCLAIMER OF ALL
+WARRANTIES.
+
+This Python distribution contains no GNU General Public Licensed
+(GPLed) code so it may be used in proprietary projects just like prior
+Python distributions.  There are interfaces to some GNU code but these
+are entirely optional.
+
+All trademarks referenced herein are property of their respective
+holders.
+
+
+What's new in this release?
+---------------------------
+
+See the file "Misc/NEWS".
+
+
+If you don't read instructions
+------------------------------
+
+Congratulations on getting this far. :-)
+
+To start building right away (on UNIX): type "./configure" in the
+current directory and when it finishes, type "make".  This creates an
+executable "./python"; to install in /usr/local, first do "su root"
+and then "make install".
+
+The section `Build instructions' below is still recommended reading.
+
+
+What is Python anyway?
+----------------------
+
+Python is an interpreted, interactive object-oriented programming
+language suitable (amongst other uses) for distributed application
+development, scripting, numeric computing and system testing.  Python
+is often compared to Tcl, Perl, Java, JavaScript, Visual Basic or
+Scheme.  To find out more about what Python can do for you, point your
+browser to http://www.python.org/.
+
+
+How do I learn Python?
+----------------------
+
+The official tutorial is still a good place to start; see
+http://docs.python.org/ for online and downloadable versions, as well
+as a list of other introductions, and reference documentation.
+
+There's a quickly growing set of books on Python.  See
+http://wiki.python.org/moin/PythonBooks for a list.
+
+
+Documentation
+-------------
+
+All documentation is provided online in a variety of formats.  In
+order of importance for new users: Tutorial, Library Reference,
+Language Reference, Extending & Embedding, and the Python/C API.  The
+Library Reference is especially of immense value since much of
+Python's power is described there, including the built-in data types
+and functions!
+
+All documentation is also available online at the Python web site
+(http://docs.python.org/, see below).  It is available online for
+occasional reference, or can be downloaded in many formats for faster
+access.  The documentation is available in HTML, PostScript, PDF, and
+LaTeX formats; the LaTeX version is primarily for documentation
+authors, translators, and people with special formatting requirements.
+
+Unfortunately, new-style classes (new in Python 2.2) have not yet been
+integrated into Python's standard documentation.  A collection of
+pointers to what has been written is at:
+
+    http://www.python.org/doc/newstyle.html
+
+
+Web sites
+---------
+
+New Python releases and related technologies are published at
+http://www.python.org/.  Come visit us!
+
+There's also a Python community web site at
+http://starship.python.net/.
+
+
+Newsgroups and Mailing Lists
+----------------------------
+
+Read comp.lang.python, a high-volume discussion newsgroup about
+Python, or comp.lang.python.announce, a low-volume moderated newsgroup
+for Python-related announcements.  These are also accessible as
+mailing lists: see http://www.python.org/community/lists.html for an
+overview of these and many other Python-related mailing lists.
+
+Archives are accessible via the Google Groups Usenet archive; see
+http://groups.google.com/.  The mailing lists are also archived, see
+http://www.python.org/community/lists.html for details.
+
+
+Bug reports
+-----------
+
+To report or search for bugs, please use the Python Bug
+Tracker at http://sourceforge.net/bugs/?group_id=5470.
+
+
+Patches and contributions
+-------------------------
+
+To submit a patch or other contribution, please use the Python Patch
+Manager at http://sourceforge.net/patch/?group_id=5470.  Guidelines
+for patch submission may be found at http://www.python.org/patches/.
+
+If you have a proposal to change Python, it's best to submit a Python
+Enhancement Proposal (PEP) first.  All current PEPs, as well as
+guidelines for submitting a new PEP, are listed at
+http://www.python.org/peps/.
+
+
+Questions
+---------
+
+For help, if you can't find it in the manuals or on the web site, it's
+best to post to the comp.lang.python or the Python mailing list (see
+above).  If you specifically don't want to involve the newsgroup or
+mailing list, send questions to help at python.org (a group of volunteers
+who answer questions as they can).  The newsgroup is the most
+efficient way to ask public questions.
+
+
+Build instructions
+==================
+
+Before you can build Python, you must first configure it.
+Fortunately, the configuration and build process has been automated
+for Unix and Linux installations, so all you usually have to do is
+type a few commands and sit back.  There are some platforms where
+things are not quite as smooth; see the platform specific notes below.
+If you want to build for multiple platforms sharing the same source
+tree, see the section on VPATH below.
+
+Start by running the script "./configure", which determines your
+system configuration and creates the Makefile.  (It takes a minute or
+two -- please be patient!)  You may want to pass options to the
+configure script -- see the section below on configuration options and
+variables.  When it's done, you are ready to run make.
+
+To build Python, you normally type "make" in the toplevel directory.
+If you have changed the configuration, the Makefile may have to be
+rebuilt.  In this case you may have to run make again to correctly
+build your desired target.  The interpreter executable is built in the
+top level directory.
+
+Once you have built a Python interpreter, see the subsections below on
+testing and installation.  If you run into trouble, see the next
+section.
+
+Previous versions of Python used a manual configuration process that
+involved editing the file Modules/Setup.  While this file still exists
+and manual configuration is still supported, it is rarely needed any
+more: almost all modules are automatically built as appropriate under
+guidance of the setup.py script, which is run by Make after the
+interpreter has been built.
+
+
+Troubleshooting
+---------------
+
+See also the platform specific notes in the next section.
+
+If you run into other trouble, see the FAQ
+(http://www.python.org/doc/faq) for hints on what can go wrong, and
+how to fix it.
+
+If you rerun the configure script with different options, remove all
+object files by running "make clean" before rebuilding.  Believe it or
+not, "make clean" sometimes helps to clean up other inexplicable
+problems as well.  Try it before sending in a bug report!
+
+If the configure script fails or doesn't seem to find things that
+should be there, inspect the config.log file.
+
+If you get a warning for every file about the -Olimit option being no
+longer supported, you can ignore it.  There's no foolproof way to know
+whether this option is needed; all we can do is test whether it is
+accepted without error.  On some systems, e.g. older SGI compilers, it
+is essential for performance (specifically when compiling ceval.c,
+which has more basic blocks than the default limit of 1000).  If the
+warning bothers you, edit the Makefile to remove "-Olimit 1500" from
+the OPT variable.
+
+If you get failures in test_long, or sys.maxint gets set to -1, you
+are probably experiencing compiler bugs, usually related to
+optimization.  This is a common problem with some versions of gcc, and
+some vendor-supplied compilers, which can sometimes be worked around
+by turning off optimization.  Consider switching to stable versions
+(gcc 2.95.2, gcc 3.x, or contact your vendor.)
+
+From Python 2.0 onward, all Python C code is ANSI C.  Compiling using
+old K&R-C-only compilers is no longer possible.  ANSI C compilers are
+available for all modern systems, either in the form of updated
+compilers from the vendor, or one of the free compilers (gcc).
+
+If "make install" fails mysteriously during the "compiling the library"
+step, make sure that you don't have any of the PYTHONPATH or PYTHONHOME
+environment variables set, as they may interfere with the newly built
+executable which is compiling the library.
+
+Unsupported systems
+-------------------
+
+A number of features are not supported in Python 2.5 anymore. Some
+support code is still present, but will be removed in Python 2.6. 
+If you still need to use current Python versions on these systems,
+please send a message to python-dev at python.org indicating that you
+volunteer to support this system. For a more detailed discussion 
+regarding no-longer-supported and resupporting platforms, as well
+as a list of platforms that became or will be unsupported, see PEP 11.
+
+More specifically, the following systems are not supported any
+longer:
+- SunOS 4
+- DYNIX
+- dgux
+- Minix
+- NeXT
+- Irix 4 and --with-sgi-dl
+- Linux 1
+- Systems defining __d6_pthread_create (configure.in)
+- Systems defining PY_PTHREAD_D4, PY_PTHREAD_D6,
+  or PY_PTHREAD_D7 in thread_pthread.h
+- Systems using --with-dl-dld
+- Systems using --without-universal-newlines
+- MacOS 9
+
+The following systems are still supported in Python 2.5, but
+support will be dropped in 2.6:
+- Systems using --with-wctype-functions
+- Win9x, WinME
+
+Warning on install in Windows 98 and Windows Me
+-----------------------------------------------
+
+Following Microsoft's closing of Extended Support for
+Windows 98/ME (July 11, 2006), Python 2.6 will stop
+supporting these platforms. Python development and
+maintainability becomes easier (and more reliable) when
+platform specific code targeting OSes with few users
+and no dedicated expert developers is taken out. The
+vendor also warns that the OS versions listed above
+"can expose customers to security risks" and recommends
+upgrade.
+
+Platform specific notes
+-----------------------
+
+(Some of these may no longer apply.  If you find you can build Python
+on these platforms without the special directions mentioned here,
+submit a documentation bug report to SourceForge (see Bug Reports
+above) so we can remove them!)
+
+GCC 4.1,
+GCC 4.2: There is a known incompatibility between Python and GCC,
+         where GCC 4.1 and later uses an interpretation of C 
+         different to earlier GCC releases in an area where the C 
+         specification has undefined behaviour (namely, integer arithmetic 
+         involving -sys.maxint-1).
+
+	 As a consequence, compiling Python with GCC 4.1/4.2 is not
+	 recommended. It is likely that this problem will be resolved
+	 in future Python releases. As a work-around, it seems that
+	 adding -fwrapv to the compiler options restores the earlier
+	 GCC behaviour.
+
+Unix platforms: If your vendor still ships (and you still use) Berkeley DB
+        1.85 you will need to edit Modules/Setup to build the bsddb185
+        module and add a line to sitecustomize.py which makes it the
+        default.  In Modules/Setup a line like
+
+            bsddb185 bsddbmodule.c
+
+        should work.  (You may need to add -I, -L or -l flags to direct the
+        compiler and linker to your include files and libraries.)
+
+XXX I think this next bit is out of date:
+
+64-bit platforms: The modules audioop, imageop and rgbimg don't work.
+        The setup.py script disables them on 64-bit installations.
+        Don't try to enable them in the Modules/Setup file.  They
+        contain code that is quite wordsize sensitive.  (If you have a
+        fix, let us know!)
+
+Solaris: When using Sun's C compiler with threads, at least on Solaris
+        2.5.1, you need to add the "-mt" compiler option (the simplest
+        way is probably to specify the compiler with this option as
+        the "CC" environment variable when running the configure
+        script).
+
+        When using GCC on Solaris, beware of binutils 2.13 or GCC
+        versions built using it.  This mistakenly enables the
+        -zcombreloc option which creates broken shared libraries on
+        Solaris.  binutils 2.12 works, and the binutils maintainers
+        are aware of the problem.  Binutils 2.13.1 only partially
+        fixed things.  It appears that 2.13.2 solves the problem
+        completely.  This problem is known to occur with Solaris 2.7
+        and 2.8, but may also affect earlier and later versions of the
+        OS.
+
+        When the dynamic loader complains about errors finding shared
+        libraries, such as
+
+        ld.so.1: ./python: fatal: libstdc++.so.5: open failed:
+        No such file or directory
+
+        you need to first make sure that the library is available on
+        your system. Then, you need to instruct the dynamic loader how
+        to find it. You can choose any of the following strategies:
+
+        1. When compiling Python, set LD_RUN_PATH to the directories
+           containing missing libraries.
+        2. When running Python, set LD_LIBRARY_PATH to these directories.
+        3. Use crle(8) to extend the search path of the loader.
+        4. Modify the installed GCC specs file, adding -R options into the
+           *link: section.
+
+        The complex object fails to compile on Solaris 10 with gcc 3.4 (at
+        least up to 3.4.3).  To work around it, define Py_HUGE_VAL as
+        HUGE_VAL(), e.g.:
+
+          make CPPFLAGS='-D"Py_HUGE_VAL=HUGE_VAL()" -I. -I$(srcdir)/Include'
+          ./python setup.py CPPFLAGS='-D"Py_HUGE_VAL=HUGE_VAL()"'
+
+Linux:  A problem with threads and fork() was tracked down to a bug in
+        the pthreads code in glibc version 2.0.5; glibc version 2.0.7
+        solves the problem.  This causes the popen2 test to fail;
+        problem and solution reported by Pablo Bleyer.
+
+Red Hat Linux: Red Hat 9 built Python2.2 in UCS-4 mode and hacked
+        Tcl to support it. To compile Python2.3 with Tkinter, you will
+        need to pass --enable-unicode=ucs4 flag to ./configure.
+
+        There's an executable /usr/bin/python which is Python
+        1.5.2 on most older Red Hat installations; several key Red Hat tools
+        require this version.  Python 2.1.x may be installed as
+        /usr/bin/python2.  The Makefile installs Python as
+        /usr/local/bin/python, which may or may not take precedence
+        over /usr/bin/python, depending on how you have set up $PATH.
+
+FreeBSD 3.x and probably platforms with NCurses that use libmytinfo or
+        similar: When using cursesmodule, the linking is not done in
+        the correct order with the defaults.  Remove "-ltermcap" from
+        the readline entry in Setup, and use as curses entry: "curses
+        cursesmodule.c -lmytinfo -lncurses -ltermcap" - "mytinfo" (so
+        called on FreeBSD) should be the name of the auxiliary library
+        required on your platform.  Normally, it would be linked
+        automatically, but not necessarily in the correct order.
+
+BSDI:   BSDI versions before 4.1 have known problems with threads,
+        which can cause strange errors in a number of modules (for
+        instance, the 'test_signal' test script will hang forever.)
+        Turning off threads (with --with-threads=no) or upgrading to
+        BSDI 4.1 solves this problem.
+
+DEC Unix: Run configure with --with-dec-threads, or with
+        --with-threads=no if no threads are desired (threads are on by
+        default).  When using GCC, it is possible to get an internal
+        compiler error if optimization is used.  This was reported for
+        GCC 2.7.2.3 on selectmodule.c.  Manually compile the affected
+        file without optimization to solve the problem.
+
+DEC Ultrix: compile with GCC to avoid bugs in the native compiler,
+        and pass SHELL=/bin/sh5 to Make when installing.
+
+AIX:    A complete overhaul of the shared library support is now in
+        place.  See Misc/AIX-NOTES for some notes on how it's done.
+        (The optimizer bug reported at this place in previous releases
+        has been worked around by a minimal code change.) If you get
+        errors about pthread_* functions, during compile or during
+        testing, try setting CC to a thread-safe (reentrant) compiler,
+        like "cc_r".  For full C++ module support, set CC="xlC_r" (or
+        CC="xlC" without thread support).
+
+AIX 5.3: To build a 64-bit version with IBM's compiler, I used the
+        following:
+
+        export PATH=/usr/bin:/usr/vacpp/bin
+        ./configure --with-gcc="xlc_r -q64" --with-cxx="xlC_r -q64" \
+                    --disable-ipv6 AR="ar -X64"
+        make
+
+HP-UX:  When using threading, you may have to add -D_REENTRANT to the
+        OPT variable in the top-level Makefile; reported by Pat Knight,
+        this seems to make a difference (at least for HP-UX 10.20)
+        even though pyconfig.h defines it. This seems unnecessary when
+        using HP/UX 11 and later - threading seems to work "out of the
+        box".
+
+HP-UX ia64: When building on the ia64 (Itanium) platform using HP's
+        compiler, some experience has shown that the compiler's
+        optimiser produces a completely broken version of python
+        (see http://www.python.org/sf/814976). To work around this,
+        edit the Makefile and remove -O from the OPT line.
+
+        To build a 64-bit executable on an Itanium 2 system using HP's
+        compiler, use these environment variables:
+
+                CC=cc
+                CXX=aCC
+                BASECFLAGS="+DD64"
+                LDFLAGS="+DD64 -lxnet"
+
+        and call configure as:
+
+                ./configure --without-gcc
+
+        then *unset* the environment variables again before running
+        make.  (At least one of these flags causes the build to fail
+        if it remains set.)  You still have to edit the Makefile and
+        remove -O from the OPT line.
+
+HP PA-RISC 2.0: A recent bug report (http://www.python.org/sf/546117)
+        suggests that the C compiler in this 64-bit system has bugs
+        in the optimizer that break Python.  Compiling without
+        optimization solves the problems.
+
+SCO:    The following apply to SCO 3 only; Python builds out of the box
+        on SCO 5 (or so we've heard).
+
+        1) Everything works much better if you add -U__STDC__ to the
+        defs.  This is because all the SCO header files are broken.
+        Anything that isn't mentioned in the C standard is
+        conditionally excluded when __STDC__ is defined.
+
+        2) Due to the U.S. export restrictions, SCO broke the crypt
+        stuff out into a separate library, libcrypt_i.a so the LIBS
+        needed be set to:
+
+                LIBS=' -lsocket -lcrypt_i'
+
+UnixWare: There are known bugs in the math library of the system, as well as
+        problems in the handling of threads (calling fork in one
+        thread may interrupt system calls in others). Therefore, test_math and
+        tests involving threads will fail until those problems are fixed.
+
+QNX:    Chris Herborth (chrish at qnx.com) writes:
+        configure works best if you use GNU bash; a port is available on
+        ftp.qnx.com in /usr/free.  I used the following process to build,
+        test and install Python 1.5.x under QNX:
+
+        1) CONFIG_SHELL=/usr/local/bin/bash CC=cc RANLIB=: \
+            ./configure --verbose --without-gcc --with-libm=""
+
+        2) edit Modules/Setup to activate everything that makes sense for
+           your system... tested here at QNX with the following modules:
+
+                array, audioop, binascii, cPickle, cStringIO, cmath,
+                crypt, curses, errno, fcntl, gdbm, grp, imageop,
+                _locale, math, md5, new, operator, parser, pcre,
+                posix, pwd, readline, regex, reop, rgbimg, rotor,
+                select, signal, socket, soundex, strop, struct,
+                syslog, termios, time, timing, zlib, audioop, imageop, rgbimg
+
+        3) make SHELL=/usr/local/bin/bash
+
+           or, if you feel the need for speed:
+
+           make SHELL=/usr/local/bin/bash OPT="-5 -Oil+nrt"
+
+        4) make SHELL=/usr/local/bin/bash test
+
+           Using GNU readline 2.2 seems to behave strangely, but I
+           think that's a problem with my readline 2.2 port.  :-\
+
+        5) make SHELL=/usr/local/bin/bash install
+
+        If you get SIGSEGVs while running Python (I haven't yet, but
+        I've only run small programs and the test cases), you're
+        probably running out of stack; the default 32k could be a
+        little tight.  To increase the stack size, edit the Makefile
+        to read: LDFLAGS = -N 48k
+
+BeOS:   See Misc/BeOS-NOTES for notes about compiling/installing
+        Python on BeOS R3 or later.  Note that only the PowerPC
+        platform is supported for R3; both PowerPC and x86 are
+        supported for R4.
+
+Cray T3E: Mark Hadfield (m.hadfield at niwa.co.nz) writes:
+        Python can be built satisfactorily on a Cray T3E but based on
+        my experience with the NIWA T3E (2002-05-22, version 2.2.1)
+        there are a few bugs and gotchas. For more information see a
+        thread on comp.lang.python in May 2002 entitled "Building
+        Python on Cray T3E".
+
+        1) Use Cray's cc and not gcc. The latter was reported not to
+           work by Konrad Hinsen. It may work now, but it may not.
+
+        2) To set sys.platform to something sensible, pass the
+           following environment variable to the configure script:
+
+             MACHDEP=unicosmk
+
+        2) Run configure with option "--enable-unicode=ucs4".
+
+        3) The Cray T3E does not support dynamic linking, so extension
+           modules have to be built by adding (or uncommenting) lines
+           in Modules/Setup. The minimum set of modules is
+
+             posix, new, _sre, unicodedata
+
+           On NIWA's vanilla T3E system the following have also been
+           included successfully:
+
+             _codecs, _locale, _socket, _symtable, _testcapi, _weakref
+             array, binascii, cmath, cPickle, crypt, cStringIO, dbm
+             errno, fcntl, grp, math, md5, operator, parser, pcre, pwd
+             regex, rotor, select, struct, strop, syslog, termios
+             time, timing, xreadlines
+
+        4) Once the python executable and library have been built, make
+           will execute setup.py, which will attempt to build remaining
+           extensions and link them dynamically. Each of these attempts
+           will fail but should not halt the make process. This is
+           normal.
+
+        5) Running "make test" uses a lot of resources and causes
+           problems on our system. You might want to try running tests
+           singly or in small groups.
+
+SGI:    SGI's standard "make" utility (/bin/make or /usr/bin/make)
+        does not check whether a command actually changed the file it
+        is supposed to build.  This means that whenever you say "make"
+        it will redo the link step.  The remedy is to use SGI's much
+        smarter "smake" utility (/usr/sbin/smake), or GNU make.  If
+        you set the first line of the Makefile to #!/usr/sbin/smake
+        smake will be invoked by make (likewise for GNU make).
+
+        WARNING: There are bugs in the optimizer of some versions of
+        SGI's compilers that can cause bus errors or other strange
+        behavior, especially on numerical operations.  To avoid this,
+        try building with "make OPT=".
+
+OS/2:   If you are running Warp3 or Warp4 and have IBM's VisualAge C/C++
+        compiler installed, just change into the pc\os2vacpp directory
+        and type NMAKE.  Threading and sockets are supported by default
+        in the resulting binaries of PYTHON15.DLL and PYTHON.EXE.
+
+Monterey (64-bit AIX): The current Monterey C compiler (Visual Age)
+        uses the OBJECT_MODE={32|64} environment variable to set the
+        compilation mode to either 32-bit or 64-bit (32-bit mode is
+        the default).  Presumably you want 64-bit compilation mode for
+        this 64-bit OS.  As a result you must first set OBJECT_MODE=64
+        in your environment before configuring (./configure) or
+        building (make) Python on Monterey.
+
+Reliant UNIX: The thread support does not compile on Reliant UNIX, and
+        there is a (minor) problem in the configure script for that
+        platform as well.  This should be resolved in time for a
+        future release.
+
+MacOSX: The tests will crash on both 10.1 and 10.2 with SEGV in
+        test_re and test_sre due to the small default stack size.  If
+        you set the stack size to 2048 before doing a "make test" the
+        failure can be avoided.  If you're using the tcsh or csh shells,
+        use "limit stacksize 2048" and for the bash shell (the default
+        as of OSX 10.3), use "ulimit -s 2048".
+
+        On naked Darwin you may want to add the configure option
+        "--disable-toolbox-glue" to disable the glue code for the Carbon
+        interface modules. The modules themselves are currently only built
+        if you add the --enable-framework option, see below.
+
+        On a clean OSX /usr/local does not exist. Do a
+        "sudo mkdir -m 775 /usr/local"
+        before you do a make install. It is probably not a good idea to
+        do "sudo make install" which installs everything as superuser,
+        as this may later cause problems when installing distutils-based
+        additions.
+
+        Some people have reported problems building Python after using "fink"
+        to install additional unix software. Disabling fink (remove all 
+        references to /sw from your .profile or .login) should solve this.
+
+        You may want to try the configure option "--enable-framework"
+        which installs Python as a framework. The location can be set
+        as argument to the --enable-framework option (default
+        /Library/Frameworks). A framework install is probably needed if you
+        want to use any Aqua-based GUI toolkit (whether Tkinter, wxPython,
+        Carbon, Cocoa or anything else).
+
+	You may also want to try the configure option "--enable-universalsdk"
+	which builds Python as a universal binary with support for the 
+	i386 and PPC architectures. This requires Xcode 2.1 or later to build.
+
+        See Mac/OSX/README for more information on framework and 
+	universal builds.
+
+Cygwin: With recent (relative to the time of writing, 2001-12-19)
+        Cygwin installations, there are problems with the interaction
+        of dynamic linking and fork().  This manifests itself in build
+        failures during the execution of setup.py.
+
+        There are two workarounds that both enable Python (albeit
+        without threading support) to build and pass all tests on
+        NT/2000 (and most likely XP as well, though reports of testing
+        on XP would be appreciated).
+
+        The workarounds:
+
+        (a) the band-aid fix is to link the _socket module statically
+        rather than dynamically (which is the default).
+
+        To do this, run "./configure --with-threads=no" including any
+        other options you need (--prefix, etc.).  Then in Modules/Setup
+        uncomment the lines:
+
+        #SSL=/usr/local/ssl
+        #_socket socketmodule.c \
+        #       -DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl \
+        #       -L$(SSL)/lib -lssl -lcrypto
+
+        and remove "local/" from the SSL variable.  Finally, just run
+        "make"!
+
+        (b) The "proper" fix is to rebase the Cygwin DLLs to prevent
+        base address conflicts.  Details on how to do this can be
+        found in the following mail:
+
+           http://sources.redhat.com/ml/cygwin/2001-12/msg00894.html
+
+        It is hoped that a version of this solution will be
+        incorporated into the Cygwin distribution fairly soon.
+
+        Two additional problems:
+
+        (1) Threading support should still be disabled due to a known
+        bug in Cygwin pthreads that causes test_threadedtempfile to
+        hang.
+
+        (2) The _curses module does not build.  This is a known
+        Cygwin ncurses problem that should be resolved the next time
+        that this package is released.
+
+        On older versions of Cygwin, test_poll may hang and test_strftime
+        may fail.
+
+        The situation on 9X/Me is not accurately known at present.
+        Some time ago, there were reports that the following
+        regression tests failed:
+
+            test_pwd
+            test_select (hang)
+            test_socket
+
+        Due to the test_select hang on 9X/Me, one should run the
+        regression test using the following:
+
+            make TESTOPTS='-l -x test_select' test
+
+        News regarding these platforms with more recent Cygwin
+        versions would be appreciated!
+
+AtheOS: From Octavian Cerna <tavy at ylabs.com>:
+
+        Before building:
+
+            Make sure you have shared versions of the libraries you
+            want to use with Python. You will have to compile them
+            yourself, or download precompiled packages.
+
+            Recommended libraries:
+
+                ncurses-4.2
+                readline-4.2a
+                zlib-1.1.4
+
+        Build:
+
+            $ ./configure --prefix=/usr/python
+            $ make
+
+            Python is always built as a shared library, otherwise
+            dynamic loading would not work.
+
+        Testing:
+
+            $ make test
+
+        Install:
+
+            # make install
+            # pkgmanager -a /usr/python
+
+
+        AtheOS issues:
+
+            - large file support: due to a stdio bug in glibc/libio,
+              access to large files may not work correctly.  fseeko()
+              tries to seek to a negative offset.  ftello() returns a
+              negative offset, it looks like a 32->64bit
+              sign-extension issue.  The lowlevel functions (open,
+              lseek, etc) are OK.
+            - sockets: AF_UNIX is defined in the C library and in
+              Python, but not implemented in the system.
+            - select: poll is available in the C library, but does not
+              work (It does not return POLLNVAL for bad fds and
+              hangs).
+            - posix: statvfs and fstatvfs always return ENOSYS.
+            - disabled modules:
+                - mmap: not yet implemented in AtheOS
+                - nis: broken (on an unconfigured system
+                  yp_get_default_domain() returns junk instead of
+                  error)
+                - dl: dynamic loading doesn't work via dlopen()
+                - resource: getrimit and setrlimit are not yet
+                  implemented
+
+            - if you are getting segmentation faults, you probably are
+              low on memory.  AtheOS doesn't handle very well an
+              out-of-memory condition and simply SEGVs the process.
+
+        Tested on:
+
+            AtheOS-0.3.7
+            gcc-2.95
+            binutils-2.10
+            make-3.78
+
+
+Configuring the bsddb and dbm modules
+-------------------------------------
+
+Beginning with Python version 2.3, the PyBsddb package
+<http://pybsddb.sf.net/> was adopted into Python as the bsddb package,
+exposing a set of package-level functions which provide
+backwards-compatible behavior.  Only versions 3.3 through 4.4 of
+Sleepycat's libraries provide the necessary API, so older versions
+aren't supported through this interface.  The old bsddb module has
+been retained as bsddb185, though it is not built by default.  Users
+wishing to use it will have to tweak Modules/Setup to build it.  The
+dbm module will still be built against the Sleepycat libraries if
+other preferred alternatives (ndbm, gdbm) are not found.
+
+Building the sqlite3 module
+---------------------------
+
+To build the sqlite3 module, you'll need the sqlite3 or libsqlite3
+packages installed, including the header files. Many modern operating
+systems distribute the headers in a separate package to the library -
+often it will be the same name as the main package, but with a -dev or
+-devel suffix. 
+
+The version of pysqlite2 that's including in Python needs sqlite3 3.0.8
+or later. setup.py attempts to check that it can find a correct version.
+
+Configuring threads
+-------------------
+
+As of Python 2.0, threads are enabled by default.  If you wish to
+compile without threads, or if your thread support is broken, pass the
+--with-threads=no switch to configure.  Unfortunately, on some
+platforms, additional compiler and/or linker options are required for
+threads to work properly.  Below is a table of those options,
+collected by Bill Janssen.  We would love to automate this process
+more, but the information below is not enough to write a patch for the
+configure.in file, so manual intervention is required.  If you patch
+the configure.in file and are confident that the patch works, please
+send in the patch.  (Don't bother patching the configure script itself
+-- it is regenerated each time the configure.in file changes.)
+
+Compiler switches for threads
+.............................
+
+The definition of _REENTRANT should be configured automatically, if
+that does not work on your system, or if _REENTRANT is defined
+incorrectly, please report that as a bug.
+
+    OS/Compiler/threads                     Switches for use with threads
+    (POSIX is draft 10, DCE is draft 4)     compile & link
+
+    SunOS 5.{1-5}/{gcc,SunPro cc}/solaris   -mt
+    SunOS 5.5/{gcc,SunPro cc}/POSIX         (nothing)
+    DEC OSF/1 3.x/cc/DCE                    -threads
+            (butenhof at zko.dec.com)
+    Digital UNIX 4.x/cc/DCE                 -threads
+            (butenhof at zko.dec.com)
+    Digital UNIX 4.x/cc/POSIX               -pthread
+            (butenhof at zko.dec.com)
+    AIX 4.1.4/cc_r/d7                       (nothing)
+            (buhrt at iquest.net)
+    AIX 4.1.4/cc_r4/DCE                     (nothing)
+            (buhrt at iquest.net)
+    IRIX 6.2/cc/POSIX                       (nothing)
+            (robertl at cwi.nl)
+
+
+Linker (ld) libraries and flags for threads
+...........................................
+
+    OS/threads                          Libraries/switches for use with threads
+
+    SunOS 5.{1-5}/solaris               -lthread
+    SunOS 5.5/POSIX                     -lpthread
+    DEC OSF/1 3.x/DCE                   -lpthreads -lmach -lc_r -lc
+            (butenhof at zko.dec.com)
+    Digital UNIX 4.x/DCE                -lpthreads -lpthread -lmach -lexc -lc
+            (butenhof at zko.dec.com)
+    Digital UNIX 4.x/POSIX              -lpthread -lmach -lexc -lc
+            (butenhof at zko.dec.com)
+    AIX 4.1.4/{draft7,DCE}              (nothing)
+            (buhrt at iquest.net)
+    IRIX 6.2/POSIX                      -lpthread
+            (jph at emilia.engr.sgi.com)
+
+
+Building a shared libpython
+---------------------------
+
+Starting with Python 2.3, the majority of the interpreter can be built
+into a shared library, which can then be used by the interpreter
+executable, and by applications embedding Python. To enable this feature,
+configure with --enable-shared.
+
+If you enable this feature, the same object files will be used to create
+a static library.  In particular, the static library will contain object
+files using position-independent code (PIC) on platforms where PIC flags
+are needed for the shared library.
+
+
+Configuring additional built-in modules
+---------------------------------------
+
+Starting with Python 2.1, the setup.py script at the top of the source
+distribution attempts to detect which modules can be built and
+automatically compiles them.  Autodetection doesn't always work, so
+you can still customize the configuration by editing the Modules/Setup
+file; but this should be considered a last resort.  The rest of this
+section only applies if you decide to edit the Modules/Setup file.
+You also need this to enable static linking of certain modules (which
+is needed to enable profiling on some systems).
+
+This file is initially copied from Setup.dist by the configure script;
+if it does not exist yet, create it by copying Modules/Setup.dist
+yourself (configure will never overwrite it).  Never edit Setup.dist
+-- always edit Setup or Setup.local (see below).  Read the comments in
+the file for information on what kind of edits are allowed.  When you
+have edited Setup in the Modules directory, the interpreter will
+automatically be rebuilt the next time you run make (in the toplevel
+directory).
+
+Many useful modules can be built on any Unix system, but some optional
+modules can't be reliably autodetected.  Often the quickest way to
+determine whether a particular module works or not is to see if it
+will build: enable it in Setup, then if you get compilation or link
+errors, disable it -- you're either missing support or need to adjust
+the compilation and linking parameters for that module.
+
+On SGI IRIX, there are modules that interface to many SGI specific
+system libraries, e.g. the GL library and the audio hardware.  These
+modules will not be built by the setup.py script.
+
+In addition to the file Setup, you can also edit the file Setup.local.
+(the makesetup script processes both).  You may find it more
+convenient to edit Setup.local and leave Setup alone.  Then, when
+installing a new Python version, you can copy your old Setup.local
+file.
+
+
+Setting the optimization/debugging options
+------------------------------------------
+
+If you want or need to change the optimization/debugging options for
+the C compiler, assign to the OPT variable on the toplevel make
+command; e.g. "make OPT=-g" will build a debugging version of Python
+on most platforms.  The default is OPT=-O; a value for OPT in the
+environment when the configure script is run overrides this default
+(likewise for CC; and the initial value for LIBS is used as the base
+set of libraries to link with).
+
+When compiling with GCC, the default value of OPT will also include
+the -Wall and -Wstrict-prototypes options.
+
+Additional debugging code to help debug memory management problems can
+be enabled by using the --with-pydebug option to the configure script.
+
+For flags that change binary compatibility, use the EXTRA_CFLAGS
+variable.
+
+
+Profiling
+---------
+
+If you want C profiling turned on, the easiest way is to run configure
+with the CC environment variable to the necessary compiler
+invocation.  For example, on Linux, this works for profiling using
+gprof(1):
+
+    CC="gcc -pg" ./configure
+
+Note that on Linux, gprof apparently does not work for shared
+libraries.  The Makefile/Setup mechanism can be used to compile and
+link most extension modules statically.
+
+
+Testing
+-------
+
+To test the interpreter, type "make test" in the top-level directory.
+This runs the test set twice (once with no compiled files, once with
+the compiled files left by the previous test run).  The test set
+produces some output.  You can generally ignore the messages about
+skipped tests due to optional features which can't be imported.
+If a message is printed about a failed test or a traceback or core
+dump is produced, something is wrong.  On some Linux systems (those
+that are not yet using glibc 6), test_strftime fails due to a
+non-standard implementation of strftime() in the C library. Please
+ignore this, or upgrade to glibc version 6.
+
+IMPORTANT: If the tests fail and you decide to mail a bug report,
+*don't* include the output of "make test".  It is useless.  Run the
+failing test manually, as follows:
+
+        ./python ./Lib/test/test_whatever.py
+
+(substituting the top of the source tree for '.' if you built in a
+different directory).  This runs the test in verbose mode.
+
+
+Installing
+----------
+
+To install the Python binary, library modules, shared library modules
+(see below), include files, configuration files, and the manual page,
+just type
+
+        make install
+
+This will install all platform-independent files in subdirectories of
+the directory given with the --prefix option to configure or to the
+`prefix' Make variable (default /usr/local).  All binary and other
+platform-specific files will be installed in subdirectories if the
+directory given by --exec-prefix or the `exec_prefix' Make variable
+(defaults to the --prefix directory) is given.
+
+If DESTDIR is set, it will be taken as the root directory of the
+installation, and files will be installed into $(DESTDIR)$(prefix),
+$(DESTDIR)$(exec_prefix), etc.
+
+All subdirectories created will have Python's version number in their
+name, e.g. the library modules are installed in
+"/usr/local/lib/python<version>/" by default, where <version> is the
+<major>.<minor> release number (e.g. "2.1").  The Python binary is
+installed as "python<version>" and a hard link named "python" is
+created.  The only file not installed with a version number in its
+name is the manual page, installed as "/usr/local/man/man1/python.1"
+by default.
+
+If you have a previous installation of Python that you don't
+want to replace yet, use
+
+        make altinstall
+
+This installs the same set of files as "make install" except it
+doesn't create the hard link to "python<version>" named "python" and
+it doesn't install the manual page at all.
+
+The only thing you may have to install manually is the Python mode for
+Emacs found in Misc/python-mode.el.  (But then again, more recent
+versions of Emacs may already have it.)  Follow the instructions that
+came with Emacs for installation of site-specific files.
+
+On Mac OS X, if you have configured Python with --enable-framework, you
+should use "make frameworkinstall" to do the installation. Note that this
+installs the Python executable in a place that is not normally on your
+PATH, you may want to set up a symlink in /usr/local/bin.
+
+
+Configuration options and variables
+-----------------------------------
+
+Some special cases are handled by passing options to the configure
+script.
+
+WARNING: if you rerun the configure script with different options, you
+must run "make clean" before rebuilding.  Exceptions to this rule:
+after changing --prefix or --exec-prefix, all you need to do is remove
+Modules/getpath.o.
+
+--with(out)-gcc: The configure script uses gcc (the GNU C compiler) if
+        it finds it.  If you don't want this, or if this compiler is
+        installed but broken on your platform, pass the option
+        --without-gcc.  You can also pass "CC=cc" (or whatever the
+        name of the proper C compiler is) in the environment, but the
+        advantage of using --without-gcc is that this option is
+        remembered by the config.status script for its --recheck
+        option.
+
+--prefix, --exec-prefix: If you want to install the binaries and the
+        Python library somewhere else than in /usr/local/{bin,lib},
+        you can pass the option --prefix=DIRECTORY; the interpreter
+        binary will be installed as DIRECTORY/bin/python and the
+        library files as DIRECTORY/lib/python/*.  If you pass
+        --exec-prefix=DIRECTORY (as well) this overrides the
+        installation prefix for architecture-dependent files (like the
+        interpreter binary).  Note that --prefix=DIRECTORY also
+        affects the default module search path (sys.path), when
+        Modules/config.c is compiled.  Passing make the option
+        prefix=DIRECTORY (and/or exec_prefix=DIRECTORY) overrides the
+        prefix set at configuration time; this may be more convenient
+        than re-running the configure script if you change your mind
+        about the install prefix.
+
+--with-readline: This option is no longer supported.  GNU
+        readline is automatically enabled by setup.py when present.
+
+--with-threads: On most Unix systems, you can now use multiple
+        threads, and support for this is enabled by default.  To
+        disable this, pass --with-threads=no.  If the library required
+        for threads lives in a peculiar place, you can use
+        --with-thread=DIRECTORY.  IMPORTANT: run "make clean" after
+        changing (either enabling or disabling) this option, or you
+        will get link errors!  Note: for DEC Unix use
+        --with-dec-threads instead.
+
+--with-sgi-dl: On SGI IRIX 4, dynamic loading of extension modules is
+        supported by the "dl" library by Jack Jansen, which is
+        ftp'able from ftp://ftp.cwi.nl/pub/dynload/dl-1.6.tar.Z.
+        This is enabled (after you've ftp'ed and compiled the dl
+        library) by passing --with-sgi-dl=DIRECTORY where DIRECTORY
+        is the absolute pathname of the dl library.  (Don't bother on
+        IRIX 5, it already has dynamic linking using SunOS style
+        shared libraries.)  THIS OPTION IS UNSUPPORTED.
+
+--with-dl-dld: Dynamic loading of modules is rumored to be supported
+        on some other systems: VAX (Ultrix), Sun3 (SunOS 3.4), Sequent
+        Symmetry (Dynix), and Atari ST.  This is done using a
+        combination of the GNU dynamic loading package
+        (ftp://ftp.cwi.nl/pub/dynload/dl-dld-1.1.tar.Z) and an
+        emulation of the SGI dl library mentioned above (the emulation
+        can be found at
+        ftp://ftp.cwi.nl/pub/dynload/dld-3.2.3.tar.Z).  To
+        enable this, ftp and compile both libraries, then call
+        configure, passing it the option
+        --with-dl-dld=DL_DIRECTORY,DLD_DIRECTORY where DL_DIRECTORY is
+        the absolute pathname of the dl emulation library and
+        DLD_DIRECTORY is the absolute pathname of the GNU dld library.
+        (Don't bother on SunOS 4 or 5, they already have dynamic
+        linking using shared libraries.)  THIS OPTION IS UNSUPPORTED.
+
+--with-libm, --with-libc: It is possible to specify alternative
+        versions for the Math library (default -lm) and the C library
+        (default the empty string) using the options
+        --with-libm=STRING and --with-libc=STRING, respectively.  For
+        example, if your system requires that you pass -lc_s to the C
+        compiler to use the shared C library, you can pass
+        --with-libc=-lc_s. These libraries are passed after all other
+        libraries, the C library last.
+
+--with-libs='libs': Add 'libs' to the LIBS that the python interpreter
+        is linked against.
+
+--with-cxx-main=<compiler>: If you plan to use C++ extension modules,
+        then -- on some platforms -- you need to compile python's main()
+        function with the C++ compiler. With this option, make will use
+        <compiler> to compile main() *and* to link the python executable.
+        It is likely that the resulting executable depends on the C++
+        runtime library of <compiler>. (The default is --without-cxx-main.)
+
+        There are platforms that do not require you to build Python
+        with a C++ compiler in order to use C++ extension modules.
+        E.g., x86 Linux with ELF shared binaries and GCC 3.x, 4.x is such
+        a platform. We recommend that you configure Python
+        --without-cxx-main on those platforms because a mismatch
+        between the C++ compiler version used to build Python and to
+        build a C++ extension module is likely to cause a crash at
+        runtime.
+
+        The Python installation also stores the variable CXX that
+        determines, e.g., the C++ compiler distutils calls by default
+        to build C++ extensions. If you set CXX on the configure command
+        line to any string of non-zero length, then configure won't
+        change CXX. If you do not preset CXX but pass
+        --with-cxx-main=<compiler>, then configure sets CXX=<compiler>.
+        In all other cases, configure looks for a C++ compiler by
+        some common names (c++, g++, gcc, CC, cxx, cc++, cl) and sets
+        CXX to the first compiler it finds. If it does not find any
+        C++ compiler, then it sets CXX="".
+
+        Similarly, if you want to change the command used to link the
+        python executable, then set LINKCC on the configure command line.
+
+
+--with-pydebug:  Enable additional debugging code to help track down
+        memory management problems.  This allows printing a list of all
+        live objects when the interpreter terminates.
+
+--with(out)-universal-newlines: enable reading of text files with
+        foreign newline convention (default: enabled). In other words,
+        any of \r, \n or \r\n is acceptable as end-of-line character.
+        If enabled import and execfile will automatically accept any newline
+        in files. Python code can open a file with open(file, 'U') to
+        read it in universal newline mode. THIS OPTION IS UNSUPPORTED.
+
+--with-tsc: Profile using the Pentium timestamping counter (TSC).
+
+--with-system-ffi:  Build the _ctypes extension module using an ffi
+	library installed on the system.
+
+
+Building for multiple architectures (using the VPATH feature)
+-------------------------------------------------------------
+
+If your file system is shared between multiple architectures, it
+usually is not necessary to make copies of the sources for each
+architecture you want to support.  If the make program supports the
+VPATH feature, you can create an empty build directory for each
+architecture, and in each directory run the configure script (on the
+appropriate machine with the appropriate options).  This creates the
+necessary subdirectories and the Makefiles therein.  The Makefiles
+contain a line VPATH=... which points to a directory containing the
+actual sources.  (On SGI systems, use "smake -J1" instead of "make" if
+you use VPATH -- don't try gnumake.)
+
+For example, the following is all you need to build a minimal Python
+in /usr/tmp/python (assuming ~guido/src/python is the toplevel
+directory and you want to build in /usr/tmp/python):
+
+        $ mkdir /usr/tmp/python
+        $ cd /usr/tmp/python
+        $ ~guido/src/python/configure
+        [...]
+        $ make
+        [...]
+        $
+
+Note that configure copies the original Setup file to the build
+directory if it finds no Setup file there.  This means that you can
+edit the Setup file for each architecture independently.  For this
+reason, subsequent changes to the original Setup file are not tracked
+automatically, as they might overwrite local changes.  To force a copy
+of a changed original Setup file, delete the target Setup file.  (The
+makesetup script supports multiple input files, so if you want to be
+fancy you can change the rules to create an empty Setup.local if it
+doesn't exist and run it with arguments $(srcdir)/Setup Setup.local;
+however this assumes that you only need to add modules.)
+
+
+Building on non-UNIX systems
+----------------------------
+
+For Windows (2000/NT/ME/98/95), assuming you have MS VC++ 7.1, the
+project files are in PCbuild, the workspace is pcbuild.dsw.  See
+PCbuild\readme.txt for detailed instructions.
+
+For other non-Unix Windows compilers, in particular MS VC++ 6.0 and
+for OS/2, enter the directory "PC" and read the file "readme.txt".
+
+For the Mac, a separate source distribution will be made available,
+for use with the CodeWarrior compiler.  If you are interested in Mac
+development, join the PythonMac Special Interest Group
+(http://www.python.org/sigs/pythonmac-sig/, or send email to
+pythonmac-sig-request at python.org).
+
+Of course, there are also binary distributions available for these
+platforms -- see http://www.python.org/.
+
+To port Python to a new non-UNIX system, you will have to fake the
+effect of running the configure script manually (for Mac and PC, this
+has already been done for you).  A good start is to copy the file
+pyconfig.h.in to pyconfig.h and edit the latter to reflect the actual
+configuration of your system.  Most symbols must simply be defined as
+1 only if the corresponding feature is present and can be left alone
+otherwise; however the *_t type symbols must be defined as some
+variant of int if they need to be defined at all.
+
+For all platforms, it's important that the build arrange to define the
+preprocessor symbol NDEBUG on the compiler command line in a release
+build of Python (else assert() calls remain in the code, hurting
+release-build performance).  The Unix, Windows and Mac builds already
+do this.
+
+
+Miscellaneous issues
+====================
+
+Emacs mode
+----------
+
+There's an excellent Emacs editing mode for Python code; see the file
+Misc/python-mode.el.  Originally written by the famous Tim Peters, it
+is now maintained by the equally famous Barry Warsaw (it's no
+coincidence that they now both work on the same team).  The latest
+version, along with various other contributed Python-related Emacs
+goodies, is online at http://www.python.org/emacs/python-mode.  And
+if you are planning to edit the Python C code, please pick up the
+latest version of CC Mode http://www.python.org/emacs/cc-mode; it
+contains a "python" style used throughout most of the Python C source
+files.  (Newer versions of Emacs or XEmacs may already come with the
+latest version of python-mode.)
+
+
+Tkinter
+-------
+
+The setup.py script automatically configures this when it detects a
+usable Tcl/Tk installation.  This requires Tcl/Tk version 8.0 or
+higher.
+
+For more Tkinter information, see the Tkinter Resource page:
+http://www.python.org/topics/tkinter/
+
+There are demos in the Demo/tkinter directory.
+
+Note that there's a Python module called "Tkinter" (capital T) which
+lives in Lib/lib-tk/Tkinter.py, and a C module called "_tkinter"
+(lower case t and leading underscore) which lives in
+Modules/_tkinter.c.  Demos and normal Tk applications import only the
+Python Tkinter module -- only the latter imports the C _tkinter
+module.  In order to find the C _tkinter module, it must be compiled
+and linked into the Python interpreter -- the setup.py script does
+this.  In order to find the Python Tkinter module, sys.path must be
+set correctly -- normal installation takes care of this.
+
+
+Distribution structure
+----------------------
+
+Most subdirectories have their own README files.  Most files have
+comments.
+
+BeOS/           Files specific to the BeOS port
+Demo/           Demonstration scripts, modules and programs
+Doc/            Documentation sources (LaTeX)
+Grammar/        Input for the parser generator
+Include/        Public header files
+LICENSE         Licensing information
+Lib/            Python library modules
+Mac/            Macintosh specific resources
+Makefile.pre.in Source from which config.status creates the Makefile.pre
+Misc/           Miscellaneous useful files
+Modules/        Implementation of most built-in modules
+Objects/        Implementation of most built-in object types
+PC/             Files specific to PC ports (DOS, Windows, OS/2)
+PCbuild/        Build directory for Microsoft Visual C++
+Parser/         The parser and tokenizer and their input handling
+Python/         The byte-compiler and interpreter
+README          The file you're reading now
+Tools/          Some useful programs written in Python
+pyconfig.h.in   Source from which pyconfig.h is created (GNU autoheader output)
+configure       Configuration shell script (GNU autoconf output)
+configure.in    Configuration specification (input for GNU autoconf)
+install-sh      Shell script used to install files
+setup.py        Python script used to build extension modules
+
+The following files will (may) be created in the toplevel directory by
+the configuration and build processes:
+
+Makefile        Build rules
+Makefile.pre    Build rules before running Modules/makesetup
+buildno         Keeps track of the build number
+config.cache    Cache of configuration variables
+pyconfig.h      Configuration header
+config.log      Log from last configure run
+config.status   Status from last run of the configure script
+getbuildinfo.o  Object file from Modules/getbuildinfo.c
+libpython<version>.a    The library archive
+python          The executable interpreter
+tags, TAGS      Tags files for vi and Emacs
+
+
+That's all, folks!
+------------------
+
+
+--Guido van Rossum (home page: http://www.python.org/~guido/)

Added: vendor/Python/current/RISCOS/Modules/config.c
===================================================================
--- vendor/Python/current/RISCOS/Modules/config.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/RISCOS/Modules/config.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,73 @@
+/* -*- C -*- ***********************************************
+Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
+The Netherlands.
+
+                        All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the names of Stichting Mathematisch
+Centrum or CWI or Corporation for National Research Initiatives or
+CNRI not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+While CWI is the initial source for this software, a modified version
+is made available by the Corporation for National Research Initiatives
+(CNRI) at the Internet address ftp://ftp.python.org.
+
+STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
+CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+
+******************************************************************/
+
+/* Module configuration */
+
+/* !!! !!! !!! This file is edited by the makesetup script !!! !!! !!! */
+
+/* This file contains the table of built-in modules.
+   See init_builtin() in import.c. */
+
+#include "Python.h"
+
+
+/* -- ADDMODULE MARKER 1 -- */
+
+extern void PyMarshal_Init(void);
+extern void initimp(void);
+extern void initgc(void);
+extern void initriscos(void);
+extern void initswi(void);
+
+struct _inittab _PyImport_Inittab[] = {
+
+	{"riscos", initriscos},
+
+/* -- ADDMODULE MARKER 2 -- */
+
+	/* This module "lives in" with marshal.c */
+	{"marshal", PyMarshal_Init},
+
+	/* This lives it with import.c */
+	{"imp", initimp},
+
+	/* These entries are here for sys.builtin_module_names */
+	{"__main__", NULL},
+	{"__builtin__", NULL},
+	{"sys", NULL},
+	{"exceptions", NULL},
+
+	/* This lives in gcmodule.c */
+	{"gc", initgc},
+
+	/* Sentinel */
+	{0, 0}
+};

Added: vendor/Python/current/RISCOS/Modules/drawfmodule.c
===================================================================
--- vendor/Python/current/RISCOS/Modules/drawfmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/RISCOS/Modules/drawfmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,664 @@
+/* drawf  DrawFile functions */
+
+#include "oslib/os.h"
+#include "oslib/osfile.h"
+#include "oslib/drawfile.h"
+#include "Python.h"
+
+#include <limits.h>
+
+#define PyDrawF_Check(op) ((op)->ob_type == &PyDrawFType)
+#define HDRSIZE 40
+#define GRPHDRSIZE 36
+#define DRAWTYPE 0xaff
+#define NEXT(d) ((drawfile_object*)((char*)(d)+(d)->size))
+
+typedef struct
+{ PyObject_HEAD
+  drawfile_diagram *drawf;
+  int size; /*length in bytes*/
+  int nobjs;  /* no of objects */
+} PyDrawFObject;
+
+typedef struct dheader
+{  char tag [4];
+   int major_version;
+   int minor_version;
+   char source [12];
+   os_box bbox;
+} dheader;
+
+static PyObject *DrawFError; /* Exception drawf.error */
+static os_error *e;
+static PyTypeObject PyDrawFType;
+
+static dheader header=
+{ {'D','r','a','w'},
+  201,0,
+  {'P','y','t','h','o','n',' ',' ',' ',' ',' ',' '},
+  {INT_MAX,INT_MAX,INT_MIN,INT_MIN}
+};
+
+static PyObject *drawf_oserror(void)
+{ PyErr_SetString(DrawFError,e->errmess);
+  return 0;
+}
+
+static PyObject *drawf_error(char *s)
+{ PyErr_SetString(DrawFError,s);
+  return 0;
+}
+
+/* DrawFile commands */
+
+static void countobjs(PyDrawFObject *pd)
+{ int k=0,q;
+  drawfile_diagram *dd=pd->drawf;
+  drawfile_object *d=dd->objects;
+  char *end=(char*)dd+pd->size;
+  pd->nobjs=-1;
+  while((char*)d<end)
+  { k++;
+    q=d->size;
+    if(q<=0||q&3) return ;
+    d=NEXT(d);
+  }
+  if ((char*)d==end) pd->nobjs=k;
+}
+
+static drawfile_object *findobj(PyDrawFObject *pd,Py_ssize_t n)
+{ drawfile_diagram *dd=pd->drawf;
+  drawfile_object *d=dd->objects;
+  for(;n>0;n--) d=NEXT(d);
+  return d;
+}
+
+static PyDrawFObject* new(int size)
+{ PyDrawFObject *b=PyObject_NEW(PyDrawFObject,&PyDrawFType);
+  if(!b) return NULL;
+  size+=HDRSIZE;
+  b->drawf=malloc(size);
+  if(!b->drawf)
+  { Py_DECREF(b);
+    return (PyDrawFObject*)PyErr_NoMemory();
+  }
+  b->size=size;
+  return b;
+}
+
+static void extend(os_box *b,os_box *c)
+{ if(b->x0>c->x0) b->x0=c->x0;
+  if(b->y0>c->y0) b->y0=c->y0;
+  if(b->x1<c->x1) b->x1=c->x1;
+  if(b->y1<c->y1) b->y1=c->y1;
+}
+
+static PyObject *DrawF_New(PyObject *self,PyObject *args)
+{ PyDrawFObject *b;
+  if(!PyArg_ParseTuple(args,"")) return NULL;
+  b=new(0);
+  if(!b) return NULL;
+  *((dheader*)b->drawf)=header;
+  b->nobjs=0;
+  return (PyObject *)b;
+}
+
+static PyObject *DrawF_Load(PyObject *self,PyObject *args)
+{ int size;
+  char *fname;
+  PyDrawFObject *b;
+  fileswitch_object_type ot;
+  if(!PyArg_ParseTuple(args,"s",&fname)) return NULL;
+  e=xosfile_read_no_path(fname,&ot,0,0,&size,0);
+  if(e) return drawf_oserror();
+  size-=HDRSIZE;
+  if(ot!=osfile_IS_FILE||size<0||size&3) return drawf_error("Bad draw file");
+  b=new(size);
+  if(!b) return NULL;
+  e=xosfile_load_stamped_no_path(fname,(byte*)(b->drawf),0,0,0,0,0);
+  if(e)
+  { Py_DECREF(b);
+    return drawf_oserror();
+  }
+  countobjs(b);
+  if(b->nobjs>=0) return (PyObject *)b;
+  Py_DECREF(b);
+  return drawf_error("Corrupt draw file");
+}
+
+
+static PyObject *DrawF_Save(PyDrawFObject *self,PyObject *arg)
+{ char *fname;
+  if(!PyArg_ParseTuple(arg,"s",&fname)) return NULL;
+  e=xosfile_save_stamped(fname,DRAWTYPE,
+  (byte*)(self->drawf),(byte*)(self->drawf)+self->size);
+  if (e) return drawf_oserror();
+  Py_INCREF(Py_None);return Py_None;
+}
+
+static PyObject *DrawF_Render(PyDrawFObject *self,PyObject *arg)
+{ int flags,trans,clip,flat;
+  if(!PyArg_ParseTuple(arg,"iiii",&flags,&trans,&clip,&flat)) return NULL;
+  e=xdrawfile_render((drawfile_render_flags)flags,self->drawf,self->size,
+  (os_trfm*)trans,(os_box*)clip,flat);
+  if(e) return drawf_oserror();
+  Py_INCREF(Py_None);return Py_None;
+}
+
+static PyObject *DrawF_Path(PyDrawFObject *self,PyObject *arg)
+{ PyObject *pl;
+  PyObject *dp=0;
+  os_colour fill;
+  os_colour outline;
+  int width,start=0;
+  drawfile_path_style style;
+  int size=40;
+  int n,i,element_count;
+  drawfile_diagram *diag;
+  drawfile_object *dobj;
+  drawfile_path *dpath;
+  draw_path *thepath;
+  draw_line_style line_style;
+  draw_dash_pattern *dash_pattern=0;
+  os_box *box;
+  long *pe;
+  if(!PyArg_ParseTuple(arg,"O!(iiii)|O!i",&PyList_Type,&pl,(int*)&fill,
+     (int*)&outline,&width,(int*)&style,&PyTuple_Type,&dp,&start)) return NULL;
+  if(dp)
+  { element_count=PyTuple_Size(dp);
+    size+=4*element_count+8;
+    style.flags|=drawfile_PATH_DASHED;
+  }
+  else style.flags&=~drawfile_PATH_DASHED;
+  n=PyList_Size(pl);
+  size+=4*n+8;
+  for(i=0;i<n;i++) if(!PyInt_Check(PyList_GetItem(pl,i))) size+=4;
+  diag=realloc(self->drawf,self->size+size);
+  if(!diag) return PyErr_NoMemory();
+  self->drawf=diag;
+  dobj=(drawfile_object*)((char*)diag+self->size);
+  dobj->type=drawfile_TYPE_PATH;
+  dobj->size=size;
+  dpath=&dobj->data.path;
+  self->size+=size;
+  self->nobjs++;
+  box=&dpath->bbox;
+  dpath->fill=fill;dpath->outline=outline;
+  dpath->width=width;dpath->style=style;
+  pe=(long*)&(dpath->path);
+  if(dp)
+  { dash_pattern=&(((drawfile_path_with_pattern*)dpath)->pattern);
+    dash_pattern->start=start;
+    dash_pattern->element_count=element_count;
+    for(i=0;i<element_count;i++)
+    { dash_pattern->elements[i]=(int)PyInt_AsLong(PyTuple_GetItem(dp,i));
+    }
+    pe+=element_count+2;
+  }
+  thepath=(draw_path*)pe;
+  *pe++=draw_MOVE_TO;
+  for(i=0;i<n;i++)
+  { PyObject *p=PyList_GetItem(pl,i);
+    if(PyInt_Check(p))
+      *pe++=PyInt_AsLong(p);
+    else
+    {
+      *pe++=PyInt_AsLong(PyTuple_GetItem(p,0));
+      *pe++=PyInt_AsLong(PyTuple_GetItem(p,1));
+    }
+  }
+  *pe=draw_END_PATH;
+  line_style.join_style=style.flags&3;
+  line_style.end_cap_style=(style.flags&3)>>2;
+  line_style.start_cap_style=(style.flags&3)>>4;
+  line_style.reserved=0;
+  line_style.mitre_limit=10;
+  line_style.start_cap_width=style.cap_width;
+  line_style.end_cap_width=style.cap_width;
+  line_style.start_cap_length=style.cap_length;
+  line_style.end_cap_length=style.cap_length;
+  e=xdraw_process_path(thepath,0x70000000,0,0,width,&line_style,dash_pattern,
+  (draw_output_path)((char*)box+0x80000000),0);
+  if(e) return drawf_oserror();
+
+  /* draw_process_path seems to have a bug:
+     If the bounding box size is zero, it returns 0x7FFFFFFF, ..., 0x80000000 instead of the
+     correct size. */
+  if (box->x0==0x7FFFFFFF)
+  {
+      /* path has zero extension, so forget it; it would be invisible anyway */
+      self->size-=size;
+      self->nobjs--;
+      diag=realloc(self->drawf,self->size);
+      if(!diag) return PyErr_NoMemory();
+      self->drawf=diag;
+  }
+  else
+      extend(&(diag->bbox),box);
+  Py_INCREF(Py_None);return Py_None;
+}
+
+static PyObject *DrawF_Text(PyDrawFObject *self,PyObject *arg)
+{ os_colour fill,bg_hint;
+  drawfile_text_style style;
+  int xsize,ysize,x,y;
+  int size,len;
+  char *text;
+  drawfile_diagram *diag;
+  drawfile_object *dobj;
+  drawfile_text *dtext;
+  os_box *box;
+  if(!PyArg_ParseTuple(arg,"(ii)s(iiiii)",&x,&y,&text,
+     (int*)&fill,(int*)&bg_hint,(int*)&style,&xsize,&ysize)) return NULL;
+  len=strlen(text);
+  size=((len+4)&(~3))+52;
+  diag=realloc(self->drawf,self->size+size);
+  if(!diag) return PyErr_NoMemory();
+  self->drawf=diag;
+  dobj=(drawfile_object*)((char*)diag+self->size);
+  dobj->type=drawfile_TYPE_TEXT;
+  dobj->size=size;
+  dtext=&dobj->data.text;
+  self->size+=size;
+  self->nobjs++;
+  dtext->fill=fill;
+  dtext->bg_hint=bg_hint;
+  dtext->style=style;
+  dtext->xsize=xsize;
+  dtext->ysize=ysize;
+  dtext->base.x=x;
+  dtext->base.y=y;
+  memset(dtext->text,0,(len+4)&(~3));
+  sprintf(dtext->text,"%s",text);
+  box=&(dtext->bbox);
+  box->x0=x;box->y0=y;box->x1=x+len*xsize;box->y1=y+ysize;
+  extend(&(diag->bbox),box);
+  Py_INCREF(Py_None);return Py_None;
+}
+
+static PyObject *DrawF_TText(PyDrawFObject *self,PyObject *arg)
+{ os_colour fill,bg_hint;
+  drawfile_text_style style;
+  int xsize,ysize,x,y;
+  int t1,t2,t3,t4,t5,t6;
+  int size,len;
+  char *text;
+  drawfile_diagram *diag;
+  drawfile_object *dobj;
+  drawfile_trfm_text *dtext;
+  os_box *box;
+  t1=1<<16;t2=0;
+  t3=0;t4=1<<16;
+  t5=t6=0;
+  if(!PyArg_ParseTuple(arg,"(ii)s(iiiii)|(iiiiii)",&x,&y,&text,
+     (int*)&fill,(int*)&bg_hint,(int*)&style,&xsize,&ysize,&t1,&t2,&t3,&t4,&t5,&t6)) return NULL;
+  len=strlen(text);
+  size=((len+4)&(~3))+52+28;
+  diag=realloc(self->drawf,self->size+size);
+  if(!diag) return PyErr_NoMemory();
+  self->drawf=diag;
+  dobj=(drawfile_object*)((char*)diag+self->size);
+  dobj->type=drawfile_TYPE_TRFM_TEXT;
+  dobj->size=size;
+  dtext=&dobj->data.trfm_text;
+  self->size+=size;
+  self->nobjs++;
+  dtext->trfm.entries[0][0]=t1;
+  dtext->trfm.entries[0][1]=t2;
+  dtext->trfm.entries[1][0]=t3;
+  dtext->trfm.entries[1][1]=t4;
+  dtext->trfm.entries[2][0]=t5;
+  dtext->trfm.entries[2][1]=t6;
+  dtext->flags=0;
+  dtext->fill=fill;
+  dtext->bg_hint=bg_hint;
+  dtext->style=style;
+  dtext->xsize=xsize;
+  dtext->ysize=ysize;
+  dtext->base.x=x;
+  dtext->base.y=y;
+  memset(dtext->text,0,(len+4)&(~3));
+  sprintf(dtext->text,"%s",text);
+  box=&(dtext->bbox);
+  box->x0=x;box->y0=y;box->x1=x+len*xsize;box->y1=y+ysize;
+  extend(&(diag->bbox),box);
+  Py_INCREF(Py_None);return Py_None;
+}
+
+static PyObject *DrawF_FontTable(PyDrawFObject *self,PyObject *arg)
+{ int size=8,n=0;
+  PyObject *d,*key,*value;
+  drawfile_diagram *diag;
+  drawfile_object *dobj;
+  char *dtable;
+  if(!PyArg_ParseTuple(arg,"O!",&PyDict_Type,&d)) return NULL;
+  while(PyDict_Next(d,&n,&key,&value))
+  { int m=PyString_Size(value);
+    if(m<0||!PyInt_Check(key)) return NULL;
+    size+=m+2;
+  }
+  size=(size+3)&(~3);
+  diag=realloc(self->drawf,self->size+size);
+  if(!diag) return PyErr_NoMemory();
+  self->drawf=diag;
+  dobj=(drawfile_object*)((char*)diag+self->size);
+  dobj->type=drawfile_TYPE_FONT_TABLE;
+  dobj->size=size;
+  dtable=(char*)(&dobj->data.font_table);
+  self->size+=size;
+  self->nobjs++;
+  memset(dtable,0,size-8);
+  n=0;
+  while(PyDict_Next(d,&n,&key,&value))
+  { int m=PyString_Size(value);
+    *dtable=(char)PyInt_AsLong(key);
+    strcpy(dtable+1,PyString_AsString(value));
+    dtable+=m+2;
+  }
+  Py_INCREF(Py_None);return Py_None;
+}
+
+static PyObject *DrawF_Group(PyDrawFObject *self,PyObject *arg)
+{ int size,n;
+  PyDrawFObject *g;
+  char *name="";
+  drawfile_diagram *diag;
+  drawfile_object *dobj;
+  drawfile_group *dgroup;
+  if(!PyArg_ParseTuple(arg,"O!|s",&PyDrawFType,(PyObject*)&g,&name))
+       return NULL;
+  size=g->size-4;
+  diag=realloc(self->drawf,self->size+size);
+  if(!diag) return PyErr_NoMemory();
+  self->drawf=diag;
+  self->nobjs++;
+  dobj=(drawfile_object*)((char*)diag+self->size);
+  self->size+=size;
+  dobj->type=drawfile_TYPE_GROUP;
+  dobj->size=g->size-4;
+  dgroup=&dobj->data.group;
+  dgroup->bbox=g->drawf->bbox;
+  memset(dgroup->name,' ',12);
+  n=strlen(name);
+  if(n>12) n=12;
+  memcpy(dgroup->name,name,n);
+  memcpy((char*)dgroup->objects,(char*)g->drawf+40,g->size-40);
+  extend(&(diag->bbox),&(dgroup->bbox));
+  Py_INCREF(Py_None);return Py_None;
+}
+
+static PyObject *DrawF_Find(PyDrawFObject *self,PyObject *arg)
+{ int x,y,n=0;
+  int r=-1;
+  drawfile_object *d;
+  if(!PyArg_ParseTuple(arg,"ii|i",&x,&y,&n)) return NULL;
+  if(n<self->nobjs&&n>=0)
+  { d=findobj(self,n);
+    while(n<self->nobjs)
+    { if(x>=d->data.text.bbox.x0&&x<=d->data.text.bbox.x1&&
+         y>=d->data.text.bbox.y0&&y<=d->data.text.bbox.y1) { r=n;break;}
+      n++;
+      d=NEXT(d);
+    }
+  }
+  return PyInt_FromLong(r);
+}
+
+
+static PyObject *DrawF_Box(PyDrawFObject *self,PyObject *arg)
+{ int n=-1;
+  os_box *box;
+  if(!PyArg_ParseTuple(arg,"|i",&n)) return NULL;
+  if(n>=self->nobjs|n<0) box=&(self->drawf->bbox);
+  else box=&(findobj(self,n)->data.text.bbox);
+  return Py_BuildValue("iiii",box->x0,box->y0,box->x1,box->y1);
+}
+
+static void SetBlock(drawfile_object *d,int size,int type,int offset,int value)
+{ char *end=(char*)d+size;
+  printf("s%d t%d o%d v%d\n",size,type,offset,value);
+  for(;(char*)d<end;d=NEXT(d))
+    if(d->type==type) ((int*)(d))[offset]=value;
+    else if(d->type==drawfile_TYPE_GROUP)
+           SetBlock((drawfile_object*)&d->data.group.objects,
+                    d->size,type,offset,value);
+  printf("SetBlock Done\n");
+}
+
+static PyObject *SetWord(PyDrawFObject *self,PyObject *arg,int type,int offset)
+{ int n=PyTuple_Size(arg);
+  int m,value,q;
+  PyObject *par;
+  drawfile_object *e,*d=self->drawf->objects;
+  if(n==0) return  drawf_error("Value Required");
+  par=PyTuple_GetItem(arg,0);
+  if(!PyInt_Check(par))
+  { PyErr_SetString(PyExc_TypeError,"Int Required");
+    return 0;
+  }
+  value=(int)PyInt_AsLong(par);
+  if(n==1) SetBlock(d,self->size-HDRSIZE,type,offset,value);
+  else
+  { for(m=1;m<n;m++)
+    { par=PyTuple_GetItem(arg,m);
+      if(!PyInt_Check(par))
+      { PyErr_SetString(PyExc_TypeError,"Int Required");
+        return 0;
+      }
+      q=(int)PyInt_AsLong(par);
+      if(q<0||q>=self->nobjs)
+      { PyErr_SetString(PyExc_ValueError,"Object out of range");
+        return 0;
+      }
+      e=d;
+      for(;q>0;q--) e=NEXT(e);
+      if(e->type==type)
+      { ((int*)(e))[offset]=value;
+      }
+      else if(e->type==drawfile_TYPE_GROUP)
+             SetBlock((drawfile_object*)&e->data.group.objects,
+                      e->size-GRPHDRSIZE,type,offset,value);
+    }
+  }
+  Py_INCREF(Py_None);return Py_None;
+}
+
+static PyObject *DrawF_PathFill(PyDrawFObject *self,PyObject *arg)
+{ return SetWord(self,arg,drawfile_TYPE_PATH,6);
+}
+
+static PyObject *DrawF_PathColour(PyDrawFObject *self,PyObject *arg)
+{ return SetWord(self,arg,drawfile_TYPE_PATH,7);
+}
+
+static PyObject *DrawF_TextColour(PyDrawFObject *self,PyObject *arg)
+{ return SetWord(self,arg,drawfile_TYPE_TEXT,6);
+}
+
+static PyObject *DrawF_TextBackground(PyDrawFObject *self,PyObject *arg)
+{ return SetWord(self,arg,drawfile_TYPE_TEXT,7);
+}
+
+static struct PyMethodDef PyDrawF_Methods[]=
+{
+  { "render",(PyCFunction)DrawF_Render,1},
+  { "save",(PyCFunction)DrawF_Save,1},
+  { "path",(PyCFunction)DrawF_Path,1},
+  { "text",(PyCFunction)DrawF_Text,1},
+  { "ttext",(PyCFunction)DrawF_TText,1},
+  { "fonttable",(PyCFunction)DrawF_FontTable,1},
+  { "group",(PyCFunction)DrawF_Group,1},
+  { "find",(PyCFunction)DrawF_Find,1},
+  { "box",(PyCFunction)DrawF_Box,1},
+  { "pathfill",(PyCFunction)DrawF_PathFill,1},
+  { "pathcolour",(PyCFunction)DrawF_PathColour,1},
+  { "textcolour",(PyCFunction)DrawF_TextColour,1},
+  { "textbackground",(PyCFunction)DrawF_TextBackground,1},
+  { NULL,NULL}		/* sentinel */
+};
+
+static int drawf_len(PyDrawFObject *b)
+{ return b->nobjs;
+}
+
+static PyObject *drawf_concat(PyDrawFObject *b,PyDrawFObject *c)
+{ int size=b->size+c->size-2*HDRSIZE;
+  PyDrawFObject *p=new(size);
+  drawfile_diagram *dd;
+  drawfile_object *d;
+  int n;
+  if(!p) return NULL;
+  dd=p->drawf;
+  d=(drawfile_object*)((char*)dd+b->size);
+  memcpy((char*)dd,(char*)(b->drawf),b->size);
+  memcpy(d,(char*)(c->drawf)+HDRSIZE,c->size-HDRSIZE);
+  p->nobjs=b->nobjs+c->nobjs;
+  for(n=c->nobjs;n>0;n--)
+  { extend(&(dd->bbox),&(d->data.path.bbox));
+    d=NEXT(d);
+  }
+  return (PyObject*)p;
+}
+
+static PyObject *drawf_repeat(PyDrawFObject *b,Py_ssize_t i)
+{ PyErr_SetString(PyExc_IndexError,"drawf repetition not implemented");
+  return NULL;
+}
+
+static PyObject *drawf_item(PyDrawFObject *b,Py_ssize_t i)
+{ PyDrawFObject *c;
+  Py_ssize_t size;
+  drawfile_diagram *dd;
+  drawfile_object *d;
+  if(i<0||i>=b->nobjs)
+  { PyErr_SetString(PyExc_IndexError,"drawf index out of range");
+    return NULL;
+  }
+  d=findobj(b,i);
+  size=(char*)findobj(b,i+1)-(char*)d;
+  c=new(size);
+  if(!c) return NULL;
+  dd=c->drawf;
+  *((dheader*)dd)=header;
+  memcpy(dd->objects,d,size);
+  c->nobjs=1;
+  extend(&(dd->bbox),&(d->data.path.bbox));
+  return (PyObject*)c;
+}
+
+static PyObject *drawf_slice(PyDrawFObject *b,Py_ssize_t i,Py_ssize_t j)
+{ PyDrawFObject *c;
+  Py_ssize_t size,n;
+  drawfile_diagram *dd;
+  drawfile_object *d;
+  if(i<0||j>b->nobjs)
+  { PyErr_SetString(PyExc_IndexError,"drawf index out of range");
+    return NULL;
+  }
+  d=findobj(b,i);
+  size=(char*)findobj(b,j)-(char*)d;
+  c=new(size);
+  if(!c) return NULL;
+  dd=c->drawf;
+  *((dheader*)dd)=header;
+  memcpy(dd->objects,d,size);
+  c->nobjs=j-i;
+  for(n=j-i;n>0;n--)
+  { extend(&(dd->bbox),&(d->data.path.bbox));
+    d=NEXT(d);
+  }
+  return (PyObject*)c;
+}
+
+static int drawf_ass_item(PyDrawFObject *b,Py_ssize_t i,PyObject *v)
+{ PyErr_SetString(PyExc_IndexError,"drawf ass not implemented");
+  return NULL;
+}
+/*{ if(i<0||4*i>=b->length)
+  { PyErr_SetString(PyExc_IndexError,"drawf index out of range");
+    return -1;
+  }
+  if(!PyInt_Check(v))
+  { PyErr_SetString(PyExc_TypeError,"drawf item must be integer");
+    return -1;
+  }
+  ((long*)(b->drawf))[i]=PyInt_AsLong(v);
+  return 0;
+}
+*/
+
+static int drawf_ass_slice(PyDrawFObject *b,Py_ssize_t i,Py_ssize_t j,PyObject *v)
+{ PyErr_SetString(PyExc_IndexError,"drawf ass_slice not implemented");
+  return NULL;
+}
+
+static PySequenceMethods drawf_as_sequence=
+{ (inquiry)drawf_len,
+  (binaryfunc)drawf_concat,
+  (ssizeargfunc)drawf_repeat,
+  (ssizeargfunc)drawf_item,
+  (ssizessizeargfunc)drawf_slice,
+  (ssizeobjargproc)drawf_ass_item,
+  (ssizessizeobjargproc)drawf_ass_slice,
+};
+
+static PyObject *PyDrawF_GetAttr(PyDrawFObject *s,char *name)
+{
+  if (!strcmp(name, "size")) return PyInt_FromLong((long)s->size);
+  if (!strcmp(name, "start")) return PyInt_FromLong((long)s->drawf);
+  if (!strcmp(name, "__members__"))
+  { PyObject *list = PyList_New(2);
+    if (list)
+    { PyList_SetItem(list, 0, PyString_FromString("size"));
+      PyList_SetItem(list, 1, PyString_FromString("start"));
+      if (PyErr_Occurred()) { Py_DECREF(list);list = NULL;}
+    }
+    return list;
+  }
+  return Py_FindMethod(PyDrawF_Methods, (PyObject*) s,name);
+}
+
+static void PyDrawF_Dealloc(PyDrawFObject *b)
+{
+    if (b->drawf)
+        ;
+    else
+        PyMem_DEL(b->drawf);
+  PyMem_DEL(b);
+}
+
+static PyTypeObject PyDrawFType=
+{ PyObject_HEAD_INIT(&PyType_Type)
+  0,				/*ob_size*/
+  "drawf",			/*tp_name*/
+  sizeof(PyDrawFObject),	/*tp_size*/
+  0,				/*tp_itemsize*/
+	/* methods */
+  (destructor)PyDrawF_Dealloc,	/*tp_dealloc*/
+  0,				/*tp_print*/
+  (getattrfunc)PyDrawF_GetAttr,	/*tp_getattr*/
+  0,				/*tp_setattr*/
+  0,				/*tp_compare*/
+  0,				/*tp_repr*/
+  0,				/*tp_as_number*/
+  &drawf_as_sequence,		/*tp_as_sequence*/
+  0,				/*tp_as_mapping*/
+  0,                            /*tp_hash*/
+};
+
+
+
+static PyMethodDef DrawFMethods[]=
+{
+  { "load",DrawF_Load,1},
+  { "new",DrawF_New,1},
+  { NULL,NULL}		 /* Sentinel */
+};
+
+void initdrawf()
+{ PyObject *m, *d;
+  m = Py_InitModule("drawf", DrawFMethods);
+  d = PyModule_GetDict(m);
+  DrawFError=PyString_FromString("drawf.error");
+  PyDict_SetItemString(d,"error",DrawFError);
+}

Added: vendor/Python/current/RISCOS/Modules/getpath_riscos.c
===================================================================
--- vendor/Python/current/RISCOS/Modules/getpath_riscos.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/RISCOS/Modules/getpath_riscos.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,60 @@
+#include "Python.h"
+#include "osdefs.h"
+
+static char *prefix, *exec_prefix, *progpath, *module_search_path=NULL;
+
+static void
+calculate_path()
+{ 
+	char *pypath = getenv("Python$Path");
+	if (pypath) {
+		int pathlen = strlen(pypath);
+		module_search_path = malloc(pathlen + 1);
+		if (module_search_path) 
+			strncpy(module_search_path, pypath, pathlen + 1);
+		else {
+			fprintf(stderr, 
+				"Not enough memory for dynamic PYTHONPATH.\n"
+				"Using default static PYTHONPATH.\n");
+		}
+	}
+	if (!module_search_path) 
+		module_search_path = "<Python$Dir>.Lib";
+	prefix = "<Python$Dir>";
+	exec_prefix = prefix;
+	progpath = Py_GetProgramName();
+}
+
+/* External interface */
+
+char *
+Py_GetPath()
+{
+	if (!module_search_path)
+		calculate_path();
+	return module_search_path;
+}
+
+char *
+Py_GetPrefix()
+{
+	if (!module_search_path)
+		calculate_path();
+	return prefix;
+}
+
+char *
+Py_GetExecPrefix()
+{
+	if (!module_search_path)
+		calculate_path();
+	return exec_prefix;
+}
+
+char *
+Py_GetProgramFullPath()
+{
+	if (!module_search_path)
+		calculate_path();
+	return progpath;
+}

Added: vendor/Python/current/RISCOS/Modules/riscosmodule.c
===================================================================
--- vendor/Python/current/RISCOS/Modules/riscosmodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/RISCOS/Modules/riscosmodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,603 @@
+/* RISCOS module implementation */
+
+#include "oslib/osfscontrol.h"
+#include "oslib/osgbpb.h"
+#include "oslib/os.h"
+#include "oslib/osfile.h"
+#include "unixstuff.h"
+
+#include <sys/fcntl.h>
+
+#include "Python.h"
+#include "structseq.h"
+
+#include <errno.h>
+
+static os_error *e;
+
+/*static PyObject *RiscosError;*/ /* Exception riscos.error */
+
+static PyObject *riscos_error(char *s)
+{
+	PyErr_SetString(PyExc_OSError, s);
+	return NULL;
+}
+
+static PyObject *riscos_oserror(void)
+{
+	return riscos_error(e->errmess);
+}
+
+
+/* RISCOS file commands */
+
+static PyObject *
+riscos_remove(PyObject *self, PyObject *args)
+{
+    char *path1;
+	if (!PyArg_ParseTuple(args, "s:remove", &path1)) return NULL;
+	if (remove(path1)) return PyErr_SetFromErrno(PyExc_OSError);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+riscos_rename(PyObject *self, PyObject *args)
+{
+	char *path1, *path2;
+	if (!PyArg_ParseTuple(args, "ss:rename", &path1, &path2))
+        return NULL;
+	if (rename(path1,path2)) return PyErr_SetFromErrno(PyExc_OSError);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+riscos_system(PyObject *self, PyObject *args)
+{
+	char *command;
+	if (!PyArg_ParseTuple(args, "s:system", &command)) return NULL;
+	return PyInt_FromLong(system(command));
+}
+
+static PyObject *
+riscos_chdir(PyObject *self, PyObject *args)
+{
+	char *path;
+	if (!PyArg_ParseTuple(args, "s:chdir", &path)) return NULL;
+	e=xosfscontrol_dir(path);
+	if(e) return riscos_oserror();
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+canon(char *path)
+{
+  int len;
+  PyObject *obj;
+  char *buf;
+  e=xosfscontrol_canonicalise_path(path,0,0,0,0,&len);
+  if(e) return riscos_oserror();
+  obj=PyString_FromStringAndSize(NULL,-len);
+  if(obj==NULL) return NULL;
+  buf=PyString_AsString(obj);
+  e=xosfscontrol_canonicalise_path(path,buf,0,0,1-len,&len);
+  if(len!=1) return riscos_error("Error expanding path");
+  if(!e) return obj;
+  Py_DECREF(obj);
+  return riscos_oserror();
+}
+
+static PyObject *
+riscos_getcwd(PyObject *self, PyObject *unused)
+{
+    return canon("@");
+}
+
+static PyObject *
+riscos_expand(PyObject *self, PyObject *args)
+{
+	char *path;
+	if (!PyArg_ParseTuple(args, "s:expand", &path)) return NULL;
+        return canon(path);
+}
+
+static PyObject *
+riscos_mkdir(PyObject *self, PyObject *args)
+{
+	char *path;
+    int mode;
+    if (!PyArg_ParseTuple(args, "s|i:mkdir", &path, &mode)) return NULL;
+    e=xosfile_create_dir(path,0);
+    if(e) return riscos_oserror();
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+riscos_listdir(PyObject *self, PyObject *args)
+{
+	char *path,buf[256];
+    PyObject *d, *v;
+    int c=0,count;
+	if (!PyArg_ParseTuple(args, "s:listdir", &path)) return NULL;
+	d=PyList_New(0);
+	if(!d) return NULL;
+	for(;;)
+	{ e=xosgbpb_dir_entries(path,(osgbpb_string_list*)buf,
+	                             1,c,256,0,&count,&c);
+	  if(e)
+	  { Py_DECREF(d);return riscos_oserror();
+	  }
+	  if(count)
+	  { v=PyString_FromString(buf);
+	    if(!v) { Py_DECREF(d);return 0;}
+	    if(PyList_Append(d,v)) {Py_DECREF(d);Py_DECREF(v);return 0;}
+	  }
+	  if(c==-1) break;
+	}
+	return d;
+}
+
+PyDoc_STRVAR(stat_result__doc__,
+"stat_result: Result from stat or lstat.\n\n\
+This object may be accessed either as a tuple of\n\
+  (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
+or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
+\n\
+RiscOS: The fields st_ftype, st_attrs, and st_obtype are also available.\n\
+\n\
+See os.stat for more information.");
+
+static PyStructSequence_Field stat_result_fields[] = {
+        { "st_mode",  "protection bits" },
+        { "st_ino",   "inode" },
+        { "st_dev",   "device" },
+        { "st_nlink", "number of hard links" },
+        { "st_uid",   "user ID of owner" },
+        { "st_gid",   "group ID of owner" },
+        { "st_size",  "total size, in bytes" },
+        { "st_atime", "time of last access" },
+        { "st_mtime", "time of last modification" },
+        { "st_ctime", "time of last change" },
+	{ "st_ftype", "file type" },
+	{ "st_attrs", "attributes" },
+	{ "st_obtype", "object type" },
+	{ 0 }
+};
+
+static PyStructSequence_Desc stat_result_desc = {
+	"riscos.stat_result",
+	stat_result__doc__,
+	stat_result_fields,
+	13
+};
+
+static PyTypeObject StatResultType;
+
+static PyObject *
+riscos_stat(PyObject *self, PyObject *args)
+{	
+	PyObject *v;
+	char *path;
+        int ob,len;
+        bits t=0;
+        bits ld,ex,at,ft,mode;
+	if (!PyArg_ParseTuple(args, "s:stat", &path)) return NULL;
+	e=xosfile_read_stamped_no_path(path,&ob,&ld,&ex,&len,&at,&ft);
+	if(e) return riscos_oserror();
+	switch (ob)
+	{ case osfile_IS_FILE:mode=0100000;break;  /* OCTAL */
+	  case osfile_IS_DIR:mode=040000;break;
+	  case osfile_IS_IMAGE:mode=0140000;break;
+	  default:return riscos_error("Not found");
+	}
+	if(ft!=-1) t=unixtime(ld,ex);
+	mode|=(at&7)<<6;
+	mode|=((at&112)*9)>>4;
+
+	v = PyStructSequence_New(&StatResultType);
+
+	PyStructSequence_SET_ITEM(v, 0, 
+				  PyInt_FromLong((long) mode)); /*st_mode*/
+	PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) 0)); /*st_ino*/
+	PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) 0)); /*st_dev*/
+	PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) 0)); /*st_nlink*/
+	PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) 0)); /*st_uid*/
+	PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) 0)); /*st_gid*/
+	PyStructSequence_SET_ITEM(v, 6, 
+				  PyInt_FromLong((long) len)); /*st_size*/
+	PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) t)); /*st_atime*/
+	PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) t)); /*st_mtime*/
+	PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) t)); /*st_ctime*/
+	PyStructSequence_SET_ITEM(v, 10, 
+				  PyInt_FromLong((long) ft)); /*file type*/
+	PyStructSequence_SET_ITEM(v, 11, 
+				  PyInt_FromLong((long) at)); /*attributes*/
+	PyStructSequence_SET_ITEM(v, 12, 
+				  PyInt_FromLong((long) ob)); /*object type*/
+
+        if (PyErr_Occurred()) {
+                Py_DECREF(v);
+                return NULL;
+        }
+
+        return v;
+}
+
+static PyObject *
+riscos_chmod(PyObject *self,PyObject *args)
+{
+	char *path;
+    bits mode;
+    bits attr;
+    attr=(mode&0x700)>>8;
+    attr|=(mode&7)<<4;
+	if (!PyArg_ParseTuple(args, "si:chmod", &path,(int*)&mode)) return NULL;
+        e=xosfile_write_attr(path,attr);
+        if(e) return riscos_oserror();
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+
+static PyObject *
+riscos_utime(PyObject *self, PyObject *args)
+{
+	char *path;
+	long atime, mtime;
+	PyObject* arg;
+
+	if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
+		return NULL;
+
+	if (arg == Py_None) {
+		/* optional time values not given */
+		Py_BEGIN_ALLOW_THREADS
+		e=xosfile_stamp(path);
+		Py_END_ALLOW_THREADS
+        	if(e) return riscos_oserror();
+	}
+	else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) {
+		PyErr_SetString(PyExc_TypeError,
+				"utime() arg 2 must be a tuple (atime, mtime)");
+		return NULL;
+	}
+	else {
+	        /* catalogue info*/
+	        fileswitch_object_type obj_type;
+	        bits load_addr, exec_addr;
+	        int size;
+	        fileswitch_attr attr;
+
+		/* read old catalogue info */
+		Py_BEGIN_ALLOW_THREADS
+		e=xosfile_read_no_path(path, &obj_type, &load_addr, &exec_addr, &size, &attr);
+		Py_END_ALLOW_THREADS
+	        if(e) return riscos_oserror();
+
+		/* check if load and exec address really contain filetype and date */
+		if ( (load_addr & 0xFFF00000U) != 0xFFF00000U)
+			return riscos_error("can't set date for object with load and exec addresses");
+
+	        /* convert argument mtime to RISC OS load and exec address */
+	        if(acorntime(&exec_addr, &load_addr, (time_t) mtime))
+	        	return riscos_oserror();
+
+		/* write new load and exec address */
+		Py_BEGIN_ALLOW_THREADS
+		e = xosfile_write(path, load_addr, exec_addr, attr);
+		Py_END_ALLOW_THREADS
+	        if(e) return riscos_oserror();
+	}
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+riscos_settype(PyObject *self, PyObject *args)
+{
+	char *path,*name;
+    int type;
+	if (!PyArg_ParseTuple(args, "si:settype", &path,&type))
+	{
+      PyErr_Clear();
+	  if (!PyArg_ParseTuple(args, "ss:settype", &path,&name)) return NULL;
+	  e=xosfscontrol_file_type_from_string(name,(bits*)&type);
+	  if(e) return riscos_oserror();
+	}
+    e=xosfile_set_type(path,type);
+    if(e) return riscos_oserror();
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject *
+riscos_getenv(PyObject *self, PyObject *args)
+{
+  char *name,*value;
+  if(!PyArg_ParseTuple(args,"s:getenv",&name)) return NULL;
+  value=getenv(name);
+  if(value) return PyString_FromString(value);
+  Py_INCREF(Py_None);
+  return Py_None;
+}
+
+static PyObject *
+riscos_putenv(PyObject *self, PyObject *args)
+{
+  char *name,*value;
+  int len;
+  os_var_type type=os_VARTYPE_LITERAL_STRING;
+  if(!PyArg_ParseTuple(args,"ss|i:putenv",&name,&value,&type)) return NULL;
+  if(type!=os_VARTYPE_STRING&&type!=os_VARTYPE_MACRO&&type!=os_VARTYPE_EXPANDED
+                            &&type!=os_VARTYPE_LITERAL_STRING)
+    return riscos_error("Bad putenv type");
+  len=strlen(value);
+  if(type!=os_VARTYPE_LITERAL_STRING) len++;
+                          /* Other types need null terminator! */
+  e=xos_set_var_val(name,(byte*)value,len,0,type,0,0);
+  if(e) return riscos_oserror();
+  Py_INCREF(Py_None);
+  return Py_None;
+}
+
+static PyObject *
+riscos_delenv(PyObject *self, PyObject *args)
+{
+  char *name;
+  if(!PyArg_ParseTuple(args,"s:delenv",&name)) return NULL;
+  e=xos_set_var_val(name,NULL,-1,0,0,0,0);
+  if(e) return riscos_oserror();
+  Py_INCREF(Py_None);
+  return Py_None;
+}
+
+static PyObject *
+riscos_getenvdict(PyObject *self, PyObject *args)
+{
+  PyObject *dict;
+  char value[257];
+  char *which="*";
+  int size;
+  char *context=NULL;
+  if(!PyArg_ParseTuple(args,"|s:getenvdict",&which)) return NULL;
+  dict = PyDict_New();
+  if (!dict) return NULL;
+  /* XXX This part ignores errors */
+  while(!xos_read_var_val(which,value,sizeof(value)-1,(int)context,
+         os_VARTYPE_EXPANDED,&size,(int *)&context,0))
+  { PyObject *v;
+    value[size]='\0';
+    v = PyString_FromString(value);
+    if (v == NULL) continue;
+    PyDict_SetItemString(dict, context, v);
+    Py_DECREF(v);
+  }
+  return dict;
+}
+
+static PyMethodDef riscos_methods[] = {
+
+	{"unlink",	riscos_remove, METH_VARARGS},
+    {"remove",  riscos_remove, METH_VARARGS},
+	{"rename",	riscos_rename, METH_VARARGS},
+	{"system",	riscos_system, METH_VARARGS},
+	{"rmdir",	riscos_remove, METH_VARARGS},
+	{"chdir",	riscos_chdir,  METH_VARARGS},
+	{"getcwd",	riscos_getcwd, METH_NOARGS},
+	{"expand",  riscos_expand, METH_VARARGS},
+	{"mkdir",	riscos_mkdir,  METH_VARARGS},
+	{"listdir",	riscos_listdir, METH_VARARGS},
+	{"stat",	riscos_stat,   METH_VARARGS},
+	{"lstat",	riscos_stat,   METH_VARARGS},
+    {"chmod",	riscos_chmod,  METH_VARARGS},
+	{"utime",	riscos_utime,  METH_VARARGS},
+	{"settype",	riscos_settype, METH_VARARGS},
+	{"getenv",  riscos_getenv, METH_VARARGS},
+	{"putenv",  riscos_putenv, METH_VARARGS},
+	{"delenv",  riscos_delenv, METH_VARARGS},
+	{"getenvdict", riscos_getenvdict, METH_VARARGS},
+	{NULL,		NULL}		 /* Sentinel */
+};
+
+static int
+ins(PyObject *module, char *symbol, long value)
+{
+	return PyModule_AddIntConstant(module, symbol, value);
+}
+
+
+static int
+all_ins(PyObject *d)
+{
+#ifdef F_OK
+        if (ins(d, "F_OK", (long)F_OK)) return -1;
+#endif
+#ifdef R_OK
+        if (ins(d, "R_OK", (long)R_OK)) return -1;
+#endif
+#ifdef W_OK
+        if (ins(d, "W_OK", (long)W_OK)) return -1;
+#endif
+#ifdef X_OK
+        if (ins(d, "X_OK", (long)X_OK)) return -1;
+#endif
+#ifdef NGROUPS_MAX
+        if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
+#endif
+#ifdef TMP_MAX
+        if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
+#endif
+#ifdef WCONTINUED
+        if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
+#endif
+#ifdef WNOHANG
+        if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
+#endif
+#ifdef WUNTRACED
+        if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
+#endif
+#ifdef O_RDONLY
+        if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
+#endif
+#ifdef O_WRONLY
+        if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
+#endif
+#ifdef O_RDWR
+        if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
+#endif
+#ifdef O_NDELAY
+        if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
+#endif
+#ifdef O_NONBLOCK
+        if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
+#endif
+#ifdef O_APPEND
+        if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
+#endif
+#ifdef O_DSYNC
+        if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
+#endif
+#ifdef O_RSYNC
+        if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
+#endif
+#ifdef O_SYNC
+        if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
+#endif
+#ifdef O_NOCTTY
+        if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
+#endif
+#ifdef O_CREAT
+        if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
+#endif
+#ifdef O_EXCL
+        if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
+#endif
+#ifdef O_TRUNC
+        if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
+#endif
+#ifdef O_BINARY
+        if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
+#endif
+#ifdef O_TEXT
+        if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
+#endif
+#ifdef O_LARGEFILE
+        if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
+#endif
+
+/* MS Windows */
+#ifdef O_NOINHERIT
+	/* Don't inherit in child processes. */
+        if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
+#endif
+#ifdef _O_SHORT_LIVED
+	/* Optimize for short life (keep in memory). */
+	/* MS forgot to define this one with a non-underscore form too. */
+        if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
+#endif
+#ifdef O_TEMPORARY
+	/* Automatically delete when last handle is closed. */
+        if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
+#endif
+#ifdef O_RANDOM
+	/* Optimize for random access. */
+        if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
+#endif
+#ifdef O_SEQUENTIAL
+	/* Optimize for sequential access. */
+        if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
+#endif
+
+/* GNU extensions. */
+#ifdef O_DIRECT
+        /* Direct disk access. */
+        if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
+#endif
+#ifdef O_DIRECTORY
+        /* Must be a directory.	 */
+        if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
+#endif
+#ifdef O_NOFOLLOW
+        /* Do not follow links.	 */
+        if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
+#endif
+
+	/* These come from sysexits.h */
+#ifdef EX_OK
+	if (ins(d, "EX_OK", (long)EX_OK)) return -1;
+#endif /* EX_OK */
+#ifdef EX_USAGE
+	if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
+#endif /* EX_USAGE */
+#ifdef EX_DATAERR
+	if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
+#endif /* EX_DATAERR */
+#ifdef EX_NOINPUT
+	if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
+#endif /* EX_NOINPUT */
+#ifdef EX_NOUSER
+	if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
+#endif /* EX_NOUSER */
+#ifdef EX_NOHOST
+	if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
+#endif /* EX_NOHOST */
+#ifdef EX_UNAVAILABLE
+	if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
+#endif /* EX_UNAVAILABLE */
+#ifdef EX_SOFTWARE
+	if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
+#endif /* EX_SOFTWARE */
+#ifdef EX_OSERR
+	if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
+#endif /* EX_OSERR */
+#ifdef EX_OSFILE
+	if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
+#endif /* EX_OSFILE */
+#ifdef EX_CANTCREAT
+	if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
+#endif /* EX_CANTCREAT */
+#ifdef EX_IOERR
+	if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
+#endif /* EX_IOERR */
+#ifdef EX_TEMPFAIL
+	if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
+#endif /* EX_TEMPFAIL */
+#ifdef EX_PROTOCOL
+	if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
+#endif /* EX_PROTOCOL */
+#ifdef EX_NOPERM
+	if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
+#endif /* EX_NOPERM */
+#ifdef EX_CONFIG
+	if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
+#endif /* EX_CONFIG */
+#ifdef EX_NOTFOUND
+	if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
+#endif /* EX_NOTFOUND */
+
+        return 0;
+}
+
+
+void
+initriscos()
+{
+	PyObject *m, *d, *stat_m;
+
+	m = Py_InitModule("riscos", riscos_methods);
+
+	if (all_ins(m))
+		return;
+
+	d = PyModule_GetDict(m);
+
+	Py_INCREF(PyExc_OSError);
+	PyModule_AddObject(m, "error", PyExc_OSError);
+
+	PyStructSequence_InitType(&StatResultType, &stat_result_desc);
+	PyDict_SetItemString(d, "stat_result", (PyObject*) &StatResultType);
+}

Added: vendor/Python/current/RISCOS/Modules/swimodule.c
===================================================================
--- vendor/Python/current/RISCOS/Modules/swimodule.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/RISCOS/Modules/swimodule.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,575 @@
+/* swi
+
+   RISC OS swi functions
+
+ 1.00               Chris Stretch
+
+
+ 1.01  12 May 1999  Laurence Tratt
+
+   * Changed swi.error to be a class based exception rather than string based
+   * Added swi.ArgError which is generated for errors when the user passes invalid arguments to
+       functions etc
+   * Added "errnum" attribute to swi.error, so one can now check to see what the error number was
+
+ 1.02  03 March 2002 Dietmar Schwertberger
+   * Added string, integer, integers, tuple and tuples
+*/
+
+#include "oslib/os.h"
+#include <kernel.h>
+#include "Python.h"
+
+
+#define PyBlock_Check(op) ((op)->ob_type == &PyBlockType)
+
+
+static PyObject *SwiError; /* Exception swi.error */
+static PyObject *ArgError; /* Exception swi.ArgError */
+static os_error *e;
+
+static PyObject *swi_oserror(void)
+{ PyErr_SetString(SwiError,e->errmess);
+  PyObject_SetAttrString(PyErr_Occurred(), "errnum", PyInt_FromLong(e->errnum));
+  return 0;
+}
+
+static PyObject *swi_error(char *s)
+{ PyErr_SetString(ArgError,s);
+  return 0;
+}
+
+typedef struct
+{ PyObject_HEAD
+  void *block;
+  int length; /*length in bytes*/
+  int heap;
+} PyBlockObject;
+
+static PyTypeObject PyBlockType;
+
+/* block commands */
+
+static PyObject *PyBlock_New(PyObject *self,PyObject *args)
+{ int size;
+  PyBlockObject *b;
+  PyObject *init=0;
+  if(!PyArg_ParseTuple(args,"i|O",&size,&init)) return NULL;
+  if(size<1) size=1;
+  b=PyObject_NEW(PyBlockObject,&PyBlockType);
+  if(!b) return NULL;
+  b->block=malloc(4*size);
+  if(!b->block)
+  { Py_DECREF(b);
+    return PyErr_NoMemory();
+  }
+  b->length=4*size;
+  b->heap=1;
+  if(init)
+  { if(PyString_Check(init))
+    { int n=PyString_Size(init);
+      if (n>4*size) n=4*size;
+      memcpy(b->block,PyString_AsString(init),n);
+      memset((char*)b->block+n,0,4*size-n);
+    }
+    else
+    { int n,k;
+      long *p=(long*)b->block;
+      if(!PyList_Check(init)) goto fail;
+      n=PyList_Size(init);
+      if (n>size) n=size;
+      for(k=0;k<n;k++)
+      { PyObject *q=PyList_GetItem(init,k);
+        if(!PyInt_Check(q)) goto fail;
+        p[k]=PyInt_AsLong(q);
+      }
+      for(;k<size;k++) p[k]=0;
+    }
+  }
+  return (PyObject *)b;
+  fail:PyErr_SetString(PyExc_TypeError,
+     "block initialiser must be string or list of integers");
+  Py_DECREF(b);
+  return NULL;
+}
+
+static PyObject *PyRegister(PyObject *self,PyObject *args)
+{ int size,ptr;
+  PyBlockObject *b;
+  if(!PyArg_ParseTuple(args,"ii",&size,&ptr)) return NULL;
+  if(size<1) size=1;
+  b=PyObject_NEW(PyBlockObject,&PyBlockType);
+  if(!b) return NULL;
+  b->block=(void*)ptr;
+  b->length=4*size;
+  b->heap=0;
+  return (PyObject *)b;
+}
+
+static PyObject *PyBlock_ToString(PyBlockObject *self,PyObject *arg)
+{ int s=0,e=self->length;
+  if(!PyArg_ParseTuple(arg,"|ii",&s,&e)) return NULL;
+  if(s<0||e>self->length||s>e)
+  { PyErr_SetString(PyExc_IndexError,"block index out of range");
+    return NULL;
+  }
+  return PyString_FromStringAndSize((char*)self->block+s,e-s);
+}
+
+static PyObject *PyBlock_NullString(PyBlockObject *self,PyObject *arg)
+{ int s=0,e=self->length,i;
+  char *p=(char*)self->block;
+  if(!PyArg_ParseTuple(arg,"|ii",&s,&e)) return NULL;
+  if(s<0||e>self->length||s>e)
+  { PyErr_SetString(PyExc_IndexError,"block index out of range");
+    return NULL;
+  }
+  for(i=s;i<e;i++) if(p[i]==0) break;
+  return PyString_FromStringAndSize((char*)self->block+s,i-s);
+}
+
+static PyObject *PyBlock_CtrlString(PyBlockObject *self,PyObject *arg)
+{ int s=0,e=self->length,i;
+  char *p=(char*)self->block;
+  if(!PyArg_ParseTuple(arg,"|ii",&s,&e)) return NULL;
+  if(s<0||e>self->length||s>e)
+  { PyErr_SetString(PyExc_IndexError,"block index out of range");
+    return NULL;
+  }
+  for(i=s;i<e;i++) if(p[i]<32) break;
+  return PyString_FromStringAndSize((char*)self->block+s,i-s);
+}
+
+static PyObject *PyBlock_PadString(PyBlockObject *self,PyObject *arg)
+{ int s=0,e=self->length,n,m;
+  char *str;
+  char c;
+  char *p=(char*)self->block;
+  if(!PyArg_ParseTuple(arg,"s#c|ii",&str,&n,&c,&s,&e)) return NULL;
+  if(s<0||e>self->length||s>e)
+  { PyErr_SetString(PyExc_IndexError,"block index out of range");
+    return NULL;
+  }
+  m=e-s;
+  if(n>m) n=m;
+  memcpy(p+s,str,n);memset(p+s+n,c,m-n);
+  Py_INCREF(Py_None);return Py_None;
+}
+
+static PyObject *PyBlock_BitSet(PyBlockObject *self,PyObject *arg)
+{ int i,x,y;
+  int *p=(int*)self->block;
+  if(!PyArg_ParseTuple(arg,"iii",&i,&x,&y)) return NULL;
+  if(i<0||i>=self->length/4)
+  { PyErr_SetString(PyExc_IndexError,"block index out of range");
+    return NULL;
+  }
+  p[i]=(p[i]&y)^x;
+  Py_INCREF(Py_None);return Py_None;
+}
+
+static PyObject *PyBlock_Resize(PyBlockObject *self,PyObject *arg)
+{ int n;
+  if(!PyArg_ParseTuple(arg,"i",&n)) return NULL;
+  if(n<1) n=1;
+  if(self->heap)
+  { void *v=realloc(self->block,4*n);
+    if (!v) return PyErr_NoMemory();
+    self->block=v;
+  }
+  self->length=4*n;
+  Py_INCREF(Py_None);return Py_None;
+}
+
+static PyObject *PyBlock_ToFile(PyBlockObject *self,PyObject *arg)
+{ int s=0,e=self->length/4;
+  PyObject *f;
+  FILE *fp;
+  if(!PyArg_ParseTuple(arg,"O|ii",&f,&s,&e)) return NULL;
+  fp=PyFile_AsFile(f);
+  if (!fp)
+  { PyErr_SetString(PyExc_TypeError, "arg must be open file");
+    return NULL;
+  }
+  fwrite((int*)(self->block)+s,4,e-s,fp);
+  Py_INCREF(Py_None);return Py_None;
+}
+
+static struct PyMethodDef PyBlock_Methods[]=
+{ { "tostring",(PyCFunction)PyBlock_ToString,1},
+  { "padstring",(PyCFunction)PyBlock_PadString,1},
+  { "nullstring",(PyCFunction)PyBlock_NullString,1},
+  { "ctrlstring",(PyCFunction)PyBlock_CtrlString,1},
+  { "bitset",(PyCFunction)PyBlock_BitSet,1},
+  { "resize",(PyCFunction)PyBlock_Resize,1},
+  { "tofile",(PyCFunction)PyBlock_ToFile,1},
+  { NULL,NULL}		/* sentinel */
+};
+
+static int block_len(PyBlockObject *b)
+{ return b->length/4;
+}
+
+static PyObject *block_concat(PyBlockObject *b,PyBlockObject *c)
+{ PyErr_SetString(PyExc_IndexError,"block concatenation not implemented");
+  return NULL;
+}
+
+static PyObject *block_repeat(PyBlockObject *b,Py_ssize_t i)
+{ PyErr_SetString(PyExc_IndexError,"block repetition not implemented");
+  return NULL;
+}
+
+static PyObject *block_item(PyBlockObject *b,Py_ssize_t i)
+{ if(i<0||4*i>=b->length)
+  { PyErr_SetString(PyExc_IndexError,"block index out of range");
+    return NULL;
+  }
+  return PyInt_FromLong(((long*)(b->block))[i]);
+}
+
+static PyObject *block_slice(PyBlockObject *b,Py_ssize_t i,Py_ssize_t j)
+{ Py_ssize_t n,k;
+  long *p=b->block;
+  PyObject *result;
+  if(j>b->length/4) j=b->length/4;
+  if(i<0||i>j)
+  { PyErr_SetString(PyExc_IndexError,"block index out of range");
+    return NULL;
+  }
+  n=j-i;
+  result=PyList_New(n);
+  for(k=0;k<n;k++) PyList_SetItem(result,k,PyInt_FromSsize_t(p[i+k]));
+  return result;
+}
+
+static int block_ass_item(PyBlockObject *b,Py_ssize_t i,PyObject *v)
+{ if(i<0||i>=b->length/4)
+  { PyErr_SetString(PyExc_IndexError,"block index out of range");
+    return -1;
+  }
+  if(!PyInt_Check(v))
+  { PyErr_SetString(PyExc_TypeError,"block item must be integer");
+    return -1;
+  }
+  ((long*)(b->block))[i]=PyInt_AsLong(v);
+  return 0;
+}
+
+static int block_ass_slice(PyBlockObject *b,Py_ssize_t i,Py_ssize_t j,PyObject *v)
+{ Py_ssize_t n,k;
+  long *p=b->block;
+  if(j>b->length/4) j=b->length/4;
+  if(i<0||i>j)
+  { PyErr_SetString(PyExc_IndexError,"block index out of range");
+    return -1;
+  }
+  if(!PyList_Check(v)) goto fail;
+  n=PyList_Size(v);
+  if(n>j-i) n=j-i;
+  for(k=0;k<n;k++)
+  { PyObject *q=PyList_GetItem(v,k);
+    if(!PyInt_Check(q)) goto fail;
+    p[i+k]=PyInt_AsLong(q);
+  }
+  for(;k<j-i;k++) p[i+k]=0;
+  return 0;
+  fail:PyErr_SetString(PyExc_TypeError,"block slice must be integer list");
+  return -1;
+}
+
+static PySequenceMethods block_as_sequence=
+{ (inquiry)block_len,		/*sq_length*/
+  (binaryfunc)block_concat,		/*sq_concat*/
+  (ssizeargfunc)block_repeat,		/*sq_repeat*/
+  (ssizeargfunc)block_item,		/*sq_item*/
+  (ssizessizeargfunc)block_slice,		/*sq_slice*/
+  (ssizeobjargproc)block_ass_item,	/*sq_ass_item*/
+  (ssizessizeobjargproc)block_ass_slice,	/*sq_ass_slice*/
+};
+
+static PyObject *PyBlock_GetAttr(PyBlockObject *s,char *name)
+{
+  if (!strcmp(name, "length")) return PyInt_FromLong((long)s->length);
+  if (!strcmp(name, "start")) return PyInt_FromLong((long)s->block);
+  if (!strcmp(name,"end")) return PyInt_FromLong(((long)(s->block)+s->length));
+  if (!strcmp(name, "__members__"))
+  { PyObject *list = PyList_New(3);
+    if (list)
+    { PyList_SetItem(list, 0, PyString_FromString("length"));
+      PyList_SetItem(list, 1, PyString_FromString("start"));
+      PyList_SetItem(list, 2, PyString_FromString("end"));
+      if (PyErr_Occurred()) { Py_DECREF(list);list = NULL;}
+    }
+    return list;
+  }
+  return Py_FindMethod(PyBlock_Methods, (PyObject*) s,name);
+}
+
+static void PyBlock_Dealloc(PyBlockObject *b)
+{
+    if(b->heap) {
+        if (b->heap)
+            ;
+        else
+            PyMem_DEL(b->block);
+    }
+  PyMem_DEL(b);
+}
+
+static PyTypeObject PyBlockType=
+{ PyObject_HEAD_INIT(&PyType_Type)
+  0,				/*ob_size*/
+  "block",			/*tp_name*/
+  sizeof(PyBlockObject),	/*tp_size*/
+  0,				/*tp_itemsize*/
+	/* methods */
+  (destructor)PyBlock_Dealloc,	/*tp_dealloc*/
+  0,				/*tp_print*/
+  (getattrfunc)PyBlock_GetAttr,	/*tp_getattr*/
+  0,				/*tp_setattr*/
+  0,				/*tp_compare*/
+  0,				/*tp_repr*/
+  0,				/*tp_as_number*/
+  &block_as_sequence,		/*tp_as_sequence*/
+  0,				/*tp_as_mapping*/
+  0,                            /*tp_hash*/
+};
+
+/* swi commands */
+
+static PyObject *swi_swi(PyObject *self,PyObject *args)
+{ PyObject *name,*format,*result,*v;
+  int swino,carry,rno=0,j,n;
+  char *swiname,*fmt,*outfmt;
+  _kernel_swi_regs r;
+  PyBlockObject *ao;
+  if(args==NULL||!PyTuple_Check(args)||(n=PyTuple_Size(args))<2)
+  { PyErr_BadArgument(); return NULL;}
+  name=PyTuple_GetItem(args,0);
+  if(!PyArg_Parse(name,"i",&swino))
+  { PyErr_Clear();
+    if(!PyArg_Parse(name,"s",&swiname)) return NULL;
+    e=xos_swi_number_from_string(swiname,&swino);
+    if(e) return swi_oserror();
+  }
+  format=PyTuple_GetItem(args,1);
+  if(!PyArg_Parse(format,"s",&fmt)) return NULL;
+  j=2;
+  for(;;fmt++)
+  { switch(*fmt)
+    { case '.': rno++;continue;
+      case ';':case 0: goto swicall;
+      case '0':case '1':case '2':case '3':case '4':
+      case '5':case '6':case '7':case '8':case '9':
+        r.r[rno++]=*fmt-'0';continue;
+      case '-':r.r[rno++]=-1;continue;
+    }
+    if(j>=n) return swi_error("Too few arguments");
+    v=PyTuple_GetItem(args,j++);
+    switch(*fmt)
+    { case 'i':if(!PyArg_Parse(v,"i",&r.r[rno])) return NULL;
+               break;
+      case 's':if(!PyArg_Parse(v,"s",(char**)(&r.r[rno]))) return NULL;
+               break;
+      case 'b':if(!PyArg_Parse(v,"O",(PyObject**)&ao)) return NULL;
+               if(!PyBlock_Check(v)) return swi_error("Not a block");
+               r.r[rno]=(int)(ao->block);
+               break;
+      case 'e':if(!PyArg_Parse(v,"O",(PyObject**)&ao)) return NULL;
+               if(!PyBlock_Check(v)) return swi_error("Not a block");
+               r.r[rno]=(int)(ao->block)+ao->length;
+               break;
+      default:return swi_error("Odd format character");
+    }
+    rno++;
+  }
+  swicall:e=(os_error*)_kernel_swi_c(swino,&r,&r,&carry);
+  if(e) return swi_oserror();
+  if(*fmt==0) { Py_INCREF(Py_None);return Py_None;}
+  n=0;
+  for(outfmt=++fmt;*outfmt;outfmt++)  switch(*outfmt)
+  { case 'i':case 's':case '*':n++;break;
+    case '.':break;
+    default:return swi_error("Odd format character");
+  }
+  if(n==0) { Py_INCREF(Py_None);return Py_None;}
+  if(n!=1)
+  { result=PyTuple_New(n);
+    if(!result) return NULL;
+  }
+  rno=0;j=0;
+  for(;*fmt;fmt++)
+  {  switch(*fmt)
+    { case 'i':v=PyInt_FromLong((long)r.r[rno++]); break;
+      case 's':v=PyString_FromString((char*)(r.r[rno++])); break;
+      case '.':rno++; continue;
+      case '*':v=PyInt_FromLong((long)carry); break;
+    }
+    if(!v) goto fail;
+    if(n==1) return v;
+    PyTuple_SetItem(result,j,v);
+    j++;
+  }
+  return result;
+  fail:Py_DECREF(result);return 0;
+}
+
+static PyObject *swi_string(PyObject *self, PyObject *arg)
+{ char *s;
+  int l=-1;
+  if(!PyArg_ParseTuple(arg,"i|i",(unsigned int *)&s, &l)) return NULL;
+  if (l==-1)
+    l = strlen(s);
+  return PyString_FromStringAndSize((char*)s, l);
+}
+
+static char swi_string__doc__[] =
+"string(address[, length]) -> string\n\
+Read a null terminated string from the given address.";
+
+
+static PyObject *swi_integer(PyObject *self, PyObject *arg)
+{ int *i;
+
+  if(!PyArg_ParseTuple(arg,"i",(unsigned int *)&i))
+    return NULL;
+  return PyInt_FromLong(*i);
+}
+
+static char swi_integer__doc__[] =
+"integer(address) -> string\n\
+Read an integer from the given address.";
+
+
+static PyObject *swi_integers(PyObject *self, PyObject *arg)
+{ int *i;
+  int c=-1;
+  PyObject *result, *result1;
+  
+  if(!PyArg_ParseTuple(arg,"i|i",(unsigned int *)&i, &c)) return NULL;
+  result=PyList_New(0);
+  if (result) {
+    while ( c>0 || (c==-1 && *i) ) {
+      result1 = PyInt_FromLong((long)*i);
+      if (!result1) {
+        Py_DECREF(result);
+        return NULL;
+      }
+      if (PyList_Append(result, result1)!=0) {
+        Py_DECREF(result);
+        Py_DECREF(result1);
+        return NULL;
+      };
+      i++;
+      if (c!=-1)
+        c--;
+    }
+  }
+  return result;
+}
+
+static char swi_integers__doc__[] =
+"integers(address[, count]) -> string\n\
+Either read a null terminated list of integers or\n\
+a list of given length from the given address.";
+
+
+static PyObject *swi_tuples(PyObject *self, PyObject *arg)
+{
+  unsigned char *i;         /* points to current */
+  int c=-1, l=4, j, zero;         /* count, length, index */
+  PyObject *result, *result1, *result11;
+  
+  if(!PyArg_ParseTuple(arg,"i|ii",(unsigned int *)&i, &l, &c)) return NULL;
+  result=PyList_New(0);
+  if (result) {
+    while (c) {
+      result1 = PyTuple_New(l);
+      if (!result1) {
+        Py_DECREF(result);
+        return NULL;
+      }
+      zero = (c==-1); /* check for zeros? */
+      for(j=0;j<l;j++) {
+        if (zero && *i)
+          zero = 0;   /* non-zero found */
+        result11 = PyInt_FromLong((long)(*i));
+        if (!result11) {
+          Py_DECREF(result);
+          return NULL;
+        }
+        PyTuple_SetItem(result1, j, result11);
+        i++;
+      }
+      if (c==-1 && zero) {
+        Py_DECREF(result1);
+        c = 0;
+        break;
+      }
+      if (PyList_Append(result, result1)!=0) {
+        Py_DECREF(result1);
+        Py_DECREF(result);
+        return NULL;
+      }
+      if (c!=-1)
+        c--;
+    }
+  }
+  return result;
+}
+
+static char swi_tuples__doc__[] =
+"tuples(address[, length=4[, count]]) -> string\n\
+Either read a null terminated list of byte tuples or\n\
+a list of given length from the given address.";
+
+
+static PyObject *swi_tuple(PyObject *self, PyObject *arg)
+{
+  unsigned char *i;         /* points to current */
+  int c=1, j;
+  PyObject *result, *result1;
+  
+  if(!PyArg_ParseTuple(arg,"i|i",(unsigned int *)&i, &c)) return NULL;
+  result = PyTuple_New(c);
+  if (!result)
+    return NULL;
+  for(j=0;j<c;j++) {
+    result1 = PyInt_FromLong((long)(i[j]));
+    if (!result1) {
+      Py_DECREF(result);
+      return NULL;
+    }
+    PyTuple_SetItem(result, j, result1);
+  }
+  return result;
+}
+
+static char swi_tuple__doc__[] =
+"tuple(address[, count=1]]) -> tuple\n\
+Read count bytes from given address.";
+
+
+static PyMethodDef SwiMethods[]=
+{ { "swi", swi_swi, METH_VARARGS},
+  { "block", PyBlock_New, METH_VARARGS},
+  { "register", PyRegister, METH_VARARGS},
+  { "string", swi_string, METH_VARARGS, swi_string__doc__},
+  { "integer", swi_integer, METH_VARARGS, swi_integer__doc__},
+  { "integers", swi_integers, METH_VARARGS, swi_integers__doc__},
+  { "tuples", swi_tuples, METH_VARARGS, swi_tuples__doc__},
+  { "tuple", swi_tuple, METH_VARARGS, swi_tuple__doc__},
+  { NULL,NULL,0,NULL}		 /* Sentinel */
+};
+
+
+void initswi()
+{ PyObject *m, *d;
+  m = Py_InitModule("swi", SwiMethods);
+  d = PyModule_GetDict(m);
+  SwiError=PyErr_NewException("swi.error", NULL, NULL);
+  PyDict_SetItemString(d,"error",SwiError);
+  ArgError=PyErr_NewException("swi.ArgError", NULL, NULL);
+  PyDict_SetItemString(d,"ArgError",ArgError);
+}

Added: vendor/Python/current/RISCOS/Python/dynload_riscos.c
===================================================================
--- vendor/Python/current/RISCOS/Python/dynload_riscos.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/RISCOS/Python/dynload_riscos.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,63 @@
+/***********************************************************
+Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
+The Netherlands.
+
+                        All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the names of Stichting Mathematisch
+Centrum or CWI or Corporation for National Research Initiatives or
+CNRI not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+While CWI is the initial source for this software, a modified version
+is made available by the Corporation for National Research Initiatives
+(CNRI) at the Internet address ftp://ftp.python.org.
+
+STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
+CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+
+******************************************************************/
+
+/* This module provides the necessary stubs for when dynamic loading is
+   not present. */
+
+#include "Python.h"
+#include "importdl.h"
+
+#include "dlk.h"
+
+
+const struct filedescr _PyImport_DynLoadFiletab[] = {
+	{"/pyd", "rb", C_EXTENSION},
+	{0, 0}
+};
+
+void dynload_init_dummy()
+{
+}
+
+dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
+				    char *pathname, FILE *fp)
+{
+	int err;
+	char errstr[256];
+	void (*init_function)(void);
+
+	err = dlk_load_no_init(pathname, &init_function);
+	if (err) {
+	    PyOS_snprintf(errstr, sizeof(errstr), "dlk failure %d", err);
+	    PyErr_SetString(PyExc_ImportError, errstr);
+	}
+	return init_function;
+}

Added: vendor/Python/current/RISCOS/Python/getcwd_riscos.c
===================================================================
--- vendor/Python/current/RISCOS/Python/getcwd_riscos.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/RISCOS/Python/getcwd_riscos.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,5 @@
+char *getcwd(char *buf, int size)
+{
+  buf[0] = '\0';
+  return buf;
+}

Added: vendor/Python/current/RISCOS/Python/getmtime_riscos.c
===================================================================
--- vendor/Python/current/RISCOS/Python/getmtime_riscos.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/RISCOS/Python/getmtime_riscos.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,20 @@
+#include <stdio.h>
+
+#define __swi
+#include "oslib/osfile.h"
+
+long PyOS_GetLastModificationTime(char *path, FILE *fp)
+{
+  int obj;
+  bits load, exec, ftype;
+
+  if (xosfile_read_stamped_no_path(path, &obj, &load, &exec, 0, 0, &ftype)) return -1;
+  if (obj != osfile_IS_FILE) return -1;
+  if (ftype == osfile_TYPE_UNTYPED) return -1;
+
+  load &= 0xFF;
+  load -= 51;
+  if (exec < 1855548004U) load--;
+  exec -= 1855548004U;
+  return exec/100+42949672*load+(95*load)/100;
+}

Added: vendor/Python/current/RISCOS/README
===================================================================
--- vendor/Python/current/RISCOS/README	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/RISCOS/README	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,36 @@
+This directory contains files for the RISC OS port of Python.
+For more information about RISC OS see http://www.riscos.com/ .
+
+This port is currently being maintained by Dietmar Schwertberger,
+dietmar at schwertberger.de .
+
+On http://www.schwertberger.de you may find compiled versions and libraries
+as well as RISC OS specific documentation and extensions.
+
+
+==========================================================================
+Compiling:
+
+1. Extract Files from archive directory 'Python-...' to a directory named
+   '!Python'.
+2. Use a tool like Rename to change filenames from '*/[ch]' into '[ch].*'.
+3. Create missing directories with 'amu cdirs'.
+4. Build with 'amu'.
+
+I've only tested Acorn/Norcroft C/C++ 5.30 and amu.
+
+Python now uses the 32 bit libraries from Pace as well as the 32 bit
+version of OSLib.
+
+You will also need some additional libraries:
+
+  DLK (patched version)
+    http://www.schwertberger.de
+  OSLib
+    http://www.mk-net.demon.co.uk/oslib
+  
+  zlib (optional)
+    ftp://ftp.freesoftware.com/pub/infozip/zlib/
+  expat (optional)
+    http://sourceforge.net/projects/expat/
+    (makefile and config.h available from http://www.schwertberger.de/riscos_expat.zip

Added: vendor/Python/current/RISCOS/pyconfig.h
===================================================================
--- vendor/Python/current/RISCOS/pyconfig.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/RISCOS/pyconfig.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,718 @@
+/* RISCOS/pyconfig.h: Python configuration for RISC OS  */
+
+#ifndef Py_PYCONFIG_H
+#define Py_PYCONFIG_H
+
+/* Define if on AIX 3.
+   System headers sometimes define this.
+   We just want to avoid a redefinition error message.  */
+#ifndef _ALL_SOURCE
+#undef _ALL_SOURCE
+#endif
+
+/* Define if type char is unsigned and you are not using gcc.  */
+#ifndef __CHAR_UNSIGNED__
+#undef __CHAR_UNSIGNED__
+#endif
+
+/* Define to empty if the keyword does not work.  */
+#undef const
+
+/* Define to `int' if <sys/types.h> doesn't define.  */
+#undef gid_t
+
+/* Define if your struct tm has tm_zone.  */
+#undef HAVE_TM_ZONE
+
+/* Define if you don't have tm_zone but do have the external array
+   tzname.  */
+#undef HAVE_TZNAME
+
+/* Define to `int' if <sys/types.h> doesn't define.  */
+#undef mode_t
+
+/* Define to `long' if <sys/types.h> doesn't define.  */
+#undef off_t
+
+/* Define to `int' if <sys/types.h> doesn't define.  */
+#undef pid_t
+
+/* Define if the system does not provide POSIX.1 features except
+   with this defined.  */
+#undef _POSIX_1_SOURCE
+
+/* Define if you need to in order for stat and other things to work.  */
+#undef _POSIX_SOURCE
+
+/* Define as the return type of signal handlers (int or void).  */
+#define RETSIGTYPE void
+
+/* Define to `unsigned' if <sys/types.h> doesn't define.  */
+#undef size_t
+
+/* Define if you have the ANSI C header files.  */
+#define STDC_HEADERS 1
+
+/* Define if you can safely include both <sys/time.h> and <time.h>.  */
+#undef TIME_WITH_SYS_TIME
+
+/* Define if your <sys/time.h> declares struct tm.  */
+#define TM_IN_SYS_TIME 1
+
+/* Define to `int' if <sys/types.h> doesn't define.  */
+#undef uid_t
+
+/* Define if your processor stores words with the most significant
+   byte first (like Motorola and SPARC, unlike Intel and VAX).  */
+#undef WORDS_BIGENDIAN
+
+/* Define for AIX if your compiler is a genuine IBM xlC/xlC_r
+   and you want support for AIX C++ shared extension modules. */
+#undef AIX_GENUINE_CPLUSPLUS
+
+/* Define if your compiler botches static forward declarations
+   (as it does on SCI ODT 3.0) */
+#undef BAD_STATIC_FORWARD
+
+/* Define this if you have BeOS threads */
+#undef BEOS_THREADS
+
+/* Define if you have the Mach cthreads package */
+#undef C_THREADS
+
+/* Define to `long' if <time.h> doesn't define.  */
+#undef clock_t
+
+/* Defined on Solaris to see additional function prototypes. */
+#undef __EXTENSIONS__
+
+/* This must be set to 64 on some systems to enable large file support */
+#undef _FILE_OFFSET_BITS
+
+/* Define if getpgrp() must be called as getpgrp(0). */
+#undef GETPGRP_HAVE_ARG
+
+/* Define if gettimeofday() does not have second (timezone) argument
+   This is the case on Motorola V4 (R40V4.2) */
+#undef GETTIMEOFDAY_NO_TZ
+
+/* Define this if your time.h defines altzone */
+#undef HAVE_ALTZONE
+
+/* Define if --enable-ipv6 is specified */
+#undef ENABLE_IPV6
+
+/* Define if sockaddr has sa_len member */
+#undef HAVE_SOCKADDR_SA_LEN
+
+/* struct addrinfo (netdb.h) */
+#undef HAVE_ADDRINFO
+
+/* struct sockaddr_storage (sys/socket.h) */
+#undef HAVE_SOCKADDR_STORAGE
+
+/* Defined when any dynamic module loading is enabled */
+#define HAVE_DYNAMIC_LOADING 1
+
+/* Define this if you have flockfile(), getc_unlocked(), and funlockfile() */
+#undef HAVE_GETC_UNLOCKED
+
+/* Define this if you have some version of gethostbyname_r() */
+#undef HAVE_GETHOSTBYNAME_R
+
+/* Define this if you have the 3-arg version of gethostbyname_r() */
+#undef HAVE_GETHOSTBYNAME_R_3_ARG
+
+/* Define this if you have the 5-arg version of gethostbyname_r() */
+#undef HAVE_GETHOSTBYNAME_R_5_ARG
+
+/* Define this if you have the 6-arg version of gethostbyname_r() */
+#undef HAVE_GETHOSTBYNAME_R_6_ARG
+
+/* Defined to enable large file support when an off_t is bigger than a long
+   and long long is available and at least as big as an off_t. You may need
+   to add some flags for configuration and compilation to enable this mode.
+   E.g, for Solaris 2.7:
+   CFLAGS="-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64" OPT="-O2 $CFLAGS" \
+ configure
+*/
+#undef HAVE_LARGEFILE_SUPPORT
+
+/* Define this if you have the type long long */
+#define HAVE_LONG_LONG
+
+/* Define if your compiler supports function prototypes */
+#define HAVE_PROTOTYPES 1
+
+/* Define if you have GNU PTH threads */
+#undef HAVE_PTH
+
+/* Define if you have readline 4.2 */
+#undef HAVE_RL_COMPLETION_MATCHES
+
+/* Define if your compiler supports variable length function prototypes
+   (e.g. void fprintf(FILE *, char *, ...);) *and* <stdarg.h> */
+#define HAVE_STDARG_PROTOTYPES 1
+
+/* Define this if you have the type uintptr_t */
+#undef HAVE_UINTPTR_T
+
+/* Define if you have a useable wchar_t type defined in wchar.h; useable
+   means wchar_t must be 16-bit unsigned type. (see
+   Include/unicodeobject.h). */
+#undef HAVE_USABLE_WCHAR_T
+
+/* Define if the compiler provides a wchar.h header file. */
+#undef HAVE_WCHAR_H
+
+/* This must be defined on some systems to enable large file support */
+#undef _LARGEFILE_SOURCE
+
+/* Define if you want to have a Unicode type. */
+#define Py_USING_UNICODE 1
+
+/* Define as the integral type used for Unicode representation. */
+#define PY_UNICODE_TYPE unsigned short
+
+/* Define as the size of the unicode type. */
+#define Py_UNICODE_SIZE 2
+
+/* Define if nice() returns success/failure instead of the new priority. */
+#undef HAVE_BROKEN_NICE
+
+/* Define if you have POSIX threads */
+#undef _POSIX_THREADS
+
+/* Define if you want to build an interpreter with many run-time checks  */
+#undef Py_DEBUG
+
+/* Define to force use of thread-safe errno, h_errno, and other functions */
+#undef _REENTRANT
+
+/* Define if setpgrp() must be called as setpgrp(0, 0). */
+#undef SETPGRP_HAVE_ARG
+
+/* Define to empty if the keyword does not work.  */
+#undef signed
+
+/* Define if i>>j for signed int i does not extend the sign bit
+   when i < 0
+*/
+#undef SIGNED_RIGHT_SHIFT_ZERO_FILLS
+
+/* The number of bytes in an off_t. */
+#define SIZEOF_OFF_T 4
+
+/* The number of bytes in a time_t. */
+#define SIZEOF_TIME_T 4
+
+/* The number of bytes in a pthread_t. */
+#undef SIZEOF_PTHREAD_T
+
+/* Define to `int' if <sys/types.h> doesn't define.  */
+#define socklen_t int
+
+/* Define if  you can safely include both <sys/select.h> and <sys/time.h>
+   (which you can't on SCO ODT 3.0). */
+#undef SYS_SELECT_WITH_SYS_TIME
+
+/* Define if a va_list is an array of some kind */
+#define VA_LIST_IS_ARRAY 1
+
+/* Define to empty if the keyword does not work.  */
+#undef volatile
+
+/* Define if you want SIGFPE handled (see Include/pyfpe.h). */
+#undef WANT_SIGFPE_HANDLER
+
+/* Define if you want wctype.h functions to be used instead of the
+   one supplied by Python itself. (see Include/unicodectype.h). */
+#undef WANT_WCTYPE_FUNCTIONS
+
+/* Define if you want documentation strings in extension modules */
+#define WITH_DOC_STRINGS 1
+
+/* Define if you want to use the new-style (Openstep, Rhapsody, MacOS)
+   dynamic linker (dyld) instead of the old-style (NextStep) dynamic
+   linker (rld). Dyld is necessary to support frameworks. */
+#undef WITH_DYLD
+
+/* Define if you want to compile in Python-specific mallocs */
+#define WITH_PYMALLOC 1
+
+/* Define if you want to produce an OpenStep/Rhapsody framework
+   (shared library plus accessory files). */
+#undef WITH_NEXT_FRAMEWORK
+
+/* Define if you want to use MacPython modules on MacOSX in unix-Python */
+#undef USE_TOOLBOX_OBJECT_GLUE
+
+/* Define if you want to compile in rudimentary thread support */
+#undef WITH_THREAD
+
+/* The number of bytes in a char.  */
+#define SIZEOF_CHAR 1
+
+/* The number of bytes in a double.  */
+#define SIZEOF_DOUBLE 8
+
+/* The number of bytes in a float.  */
+#define SIZEOF_FLOAT 4
+
+/* The number of bytes in a fpos_t.  */
+#undef SIZEOF_FPOS_T
+
+/* The number of bytes in a int.  */
+#define SIZEOF_INT 4
+
+/* The number of bytes in a long.  */
+#define SIZEOF_LONG 4
+
+/* The number of bytes in a long long.  */
+#define SIZEOF_LONG_LONG 8
+
+/* The number of bytes in a short.  */
+#define SIZEOF_SHORT 2
+
+/* The number of bytes in a uintptr_t.  */
+#undef SIZEOF_UINTPTR_T
+
+/* The number of bytes in a void *.  */
+#define SIZEOF_VOID_P 4
+
+/* The number of bytes in a wchar_t.  */
+#undef SIZEOF_WCHAR_T
+
+/* Define if you have the _getpty function.  */
+#undef HAVE__GETPTY
+
+/* Define if you have the alarm function.  */
+#undef HAVE_ALARM
+
+/* Define if you have the chown function.  */
+#undef HAVE_CHOWN
+
+/* Define if you have the clock function.  */
+#define HAVE_CLOCK 1
+
+/* Define if you have the confstr function.  */
+#undef HAVE_CONFSTR
+
+/* Define if you have the ctermid function.  */
+#undef HAVE_CTERMID
+
+/* Define if you have the ctermid_r function.  */
+#undef HAVE_CTERMID_R
+
+/* Define if you have the dlopen function.  */
+#undef HAVE_DLOPEN
+
+/* Define if you have the dup2 function.  */
+#undef HAVE_DUP2
+
+/* Define if you have the execv function.  */
+#undef HAVE_EXECV
+
+/* Define if you have the fdatasync function.  */
+#undef HAVE_FDATASYNC
+
+/* Define if you have the flock function.  */
+#undef HAVE_FLOCK
+
+/* Define if you have the fork function.  */
+#undef HAVE_FORK
+
+/* Define if you have the forkpty function.  */
+#undef HAVE_FORKPTY
+
+/* Define if you have the fpathconf function.  */
+#undef HAVE_FPATHCONF
+
+/* Define if you have the fseek64 function.  */
+#undef HAVE_FSEEK64
+
+/* Define if you have the fseeko function.  */
+#undef HAVE_FSEEKO
+
+/* Define if you have the fstatvfs function.  */
+#undef HAVE_FSTATVFS
+
+/* Define if you have the fsync function.  */
+#undef HAVE_FSYNC
+
+/* Define if you have the ftell64 function.  */
+#undef HAVE_FTELL64
+
+/* Define if you have the ftello function.  */
+#undef HAVE_FTELLO
+
+/* Define if you have the ftime function.  */
+#undef HAVE_FTIME
+
+/* Define if you have the ftruncate function.  */
+#undef HAVE_FTRUNCATE
+
+/* Define if you have the gai_strerror function.  */
+#undef HAVE_GAI_STRERROR
+
+/* Define if you have the getaddrinfo function.  */
+#undef HAVE_GETADDRINFO
+
+/* Define if you have the getcwd function.  */
+#undef HAVE_GETCWD
+
+/* Define if you have the getgroups function.  */
+#undef HAVE_GETGROUPS
+
+/* Define if you have the gethostbyname function.  */
+#undef HAVE_GETHOSTBYNAME
+
+/* Define if you have the getlogin function.  */
+#undef HAVE_GETLOGIN
+
+/* Define if you have the getnameinfo function.  */
+#undef HAVE_GETNAMEINFO
+
+/* Define if you have the getpeername function.  */
+#define HAVE_GETPEERNAME
+
+/* Define if you have the getpgid function.  */
+#undef HAVE_GETPGID
+
+/* Define if you have the getpgrp function.  */
+#undef HAVE_GETPGRP
+
+/* Define if you have the getpid function.  */
+#undef HAVE_GETPID
+
+/* Define if you have the getpriority function.  */
+#undef HAVE_GETPRIORITY
+
+/* Define if you have the getpwent function.  */
+#undef HAVE_GETPWENT
+
+/* Define if you have the gettimeofday function.  */
+#undef HAVE_GETTIMEOFDAY
+
+/* Define if you have the getwd function.  */
+#undef HAVE_GETWD
+
+/* Define if you have the hstrerror function.  */
+#undef HAVE_HSTRERROR
+
+/* Define if you have the hypot function.  */
+#define HAVE_HYPOT
+
+/* Define if you have the inet_pton function.  */
+#define HAVE_INET_PTON 1
+
+/* Define if you have the kill function.  */
+#undef HAVE_KILL
+
+/* Define if you have the link function.  */
+#undef HAVE_LINK
+
+/* Define if you have the lstat function.  */
+#undef HAVE_LSTAT
+
+/* Define if you have the memmove function.  */
+#define HAVE_MEMMOVE 1
+
+/* Define if you have the mkfifo function.  */
+#undef HAVE_MKFIFO
+
+/* Define if you have the mktime function.  */
+#define HAVE_MKTIME 1
+
+/* Define if you have the mremap function.  */
+#undef HAVE_MREMAP
+
+/* Define if you have the nice function.  */
+#undef HAVE_NICE
+
+/* Define if you have the openpty function.  */
+#undef HAVE_OPENPTY
+
+/* Define if you have the pathconf function.  */
+#undef HAVE_PATHCONF
+
+/* Define if you have the pause function.  */
+#undef HAVE_PAUSE
+
+/* Define if you have the plock function.  */
+#undef HAVE_PLOCK
+
+/* Define if you have the poll function.  */
+#undef HAVE_POLL
+
+/* Define if you have the pthread_init function.  */
+#undef HAVE_PTHREAD_INIT
+
+/* Define if you have the putenv function.  */
+#undef HAVE_PUTENV
+
+/* Define if you have the readlink function.  */
+#undef HAVE_READLINK
+
+/* Define if you have the select function.  */
+#undef HAVE_SELECT
+
+/* Define if you have the setegid function.  */
+#undef HAVE_SETEGID
+
+/* Define if you have the seteuid function.  */
+#undef HAVE_SETEUID
+
+/* Define if you have the setgid function.  */
+#undef HAVE_SETGID
+
+/* Define if you have the setlocale function.  */
+#define HAVE_SETLOCALE 1
+
+/* Define if you have the setpgid function.  */
+#undef HAVE_SETPGID
+
+/* Define if you have the setpgrp function.  */
+#undef HAVE_SETPGRP
+
+/* Define if you have the setregid function.  */
+#undef HAVE_SETREGID
+
+/* Define if you have the setreuid function.  */
+#undef HAVE_SETREUID
+
+/* Define if you have the setsid function.  */
+#undef HAVE_SETSID
+
+/* Define if you have the setuid function.  */
+#undef HAVE_SETUID
+
+/* Define if you have the setvbuf function.  */
+#undef HAVE_SETVBUF
+
+/* Define if you have the sigaction function.  */
+#undef HAVE_SIGACTION
+
+/* Define if you have the siginterrupt function.  */
+#undef HAVE_SIGINTERRUPT
+
+/* Define if you have the sigrelse function.  */
+#undef HAVE_SIGRELSE
+
+/* Define if you have the snprintf function.  */
+#undef HAVE_SNPRINTF
+
+/* Define if you have the statvfs function.  */
+#undef HAVE_STATVFS
+
+/* Define if you have the strdup function.  */
+#define HAVE_STRDUP 1
+
+/* Define if you have the strerror function.  */
+#define HAVE_STRERROR 1
+
+/* Define if you have the strftime function.  */
+#define HAVE_STRFTIME 1
+
+/* Define if you have the symlink function.  */
+#undef HAVE_SYMLINK
+
+/* Define if you have the sysconf function.  */
+#undef HAVE_SYSCONF
+
+/* Define if you have the tcgetpgrp function.  */
+#undef HAVE_TCGETPGRP
+
+/* Define if you have the tcsetpgrp function.  */
+#undef HAVE_TCSETPGRP
+
+/* Define if you have the tempnam function.  */
+#undef HAVE_TEMPNAM
+
+/* Define if you have the timegm function.  */
+#undef HAVE_TIMEGM
+
+/* Define if you have the times function.  */
+#undef HAVE_TIMES
+
+/* Define if you have the tmpfile function.  */
+#undef HAVE_TMPFILE
+
+/* Define if you have the tmpnam function.  */
+#undef HAVE_TMPNAM
+
+/* Define if you have the tmpnam_r function.  */
+#undef HAVE_TMPNAM_R
+
+/* Define if you have the truncate function.  */
+#undef HAVE_TRUNCATE
+
+/* Define if you have the uname function.  */
+#undef HAVE_UNAME
+
+/* Define if you have the waitpid function.  */
+#undef HAVE_WAITPID
+
+/* Define if you have the <conio.h> header file. */
+#undef HAVE_CONIO_H
+
+/* Define if you have the <db.h> header file.  */
+#undef HAVE_DB_H
+
+/* Define if you have the <db1/ndbm.h> header file.  */
+#undef HAVE_DB1_NDBM_H
+
+/* Define if you have the <db_185.h> header file.  */
+#undef HAVE_DB_185_H
+
+/* Define if you have the <direct.h> header file. */
+#undef HAVE_DIRECT_H
+
+/* Define if you have the <dirent.h> header file.  */
+#undef HAVE_DIRENT_H
+
+/* Define if you have the <dlfcn.h> header file.  */
+#undef HAVE_DLFCN_H
+
+/* Define if you have the <errno.h> header file. */
+#define HAVE_ERRNO_H 1
+
+/* Define if you have the <fcntl.h> header file.  */
+#undef HAVE_FCNTL_H
+
+/* Define if you have the <gdbm/ndbm.h> header file.  */
+#undef HAVE_GDBM_NDBM_H
+
+/* Define if you have the <io.h> header file.  */
+#undef HAVE_IO_H
+
+/* Define if you have the <langinfo.h> header file.  */
+#undef HAVE_LANGINFO_H
+
+/* Define if you have the <libutil.h> header file.  */
+#undef HAVE_LIBUTIL_H
+
+/* Define if you have the <ncurses.h> header file.  */
+#undef HAVE_NCURSES_H
+
+/* Define if you have the <ndbm.h> header file.  */
+#undef HAVE_NDBM_H
+
+/* Define if you have the <ndir.h> header file.  */
+#undef HAVE_NDIR_H
+
+/* Define if you have the <netpacket/packet.h> header file.  */
+#undef HAVE_NETPACKET_PACKET_H
+
+/* Define if you have the <poll.h> header file.  */
+#undef HAVE_POLL_H
+
+/* Define if you have the <process.h> header file.  */
+#undef HAVE_PROCESS_H
+
+/* Define if you have the <pthread.h> header file.  */
+#undef HAVE_PTHREAD_H
+
+/* Define if you have the <pty.h> header file.  */
+#undef HAVE_PTY_H
+
+/* Define if you have the <signal.h> header file.  */
+#define HAVE_SIGNAL_H
+
+/* Define if you have the <sys/audioio.h> header file.  */
+#undef HAVE_SYS_AUDIOIO_H
+
+/* Define if you have the <sys/dir.h> header file.  */
+#undef HAVE_SYS_DIR_H
+
+/* Define if you have the <sys/file.h> header file.  */
+#undef HAVE_SYS_FILE_H
+
+/* Define if you have the <sys/lock.h> header file.  */
+#undef HAVE_SYS_LOCK_H
+
+/* Define if you have the <sys/modem.h> header file.  */
+#undef HAVE_SYS_MODEM_H
+
+/* Define if you have the <sys/ndir.h> header file.  */
+#undef HAVE_SYS_NDIR_H
+
+/* Define if you have the <sys/param.h> header file.  */
+#undef HAVE_SYS_PARAM_H
+
+/* Define if you have the <sys/poll.h> header file.  */
+#undef HAVE_SYS_POLL_H
+
+/* Define if you have the <sys/resource.h> header file.  */
+#undef HAVE_SYS_RESOURCE_H
+
+/* Define if you have the <sys/select.h> header file.  */
+#undef HAVE_SYS_SELECT_H
+
+/* Define if you have the <sys/socket.h> header file.  */
+#undef HAVE_SYS_SOCKET_H
+
+/* Define if you have the <sys/stat.h> header file.  */
+#define HAVE_SYS_STAT_H 1
+
+/* Define if you have the <sys/time.h> header file.  */
+#undef HAVE_SYS_TIME_H
+
+/* Define if you have the <sys/times.h> header file.  */
+#undef HAVE_SYS_TIMES_H
+
+/* Define if you have the <sys/types.h> header file.  */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define if you have the <sys/un.h> header file.  */
+#undef HAVE_SYS_UN_H
+
+/* Define if you have the <sys/utsname.h> header file.  */
+#undef HAVE_SYS_UTSNAME_H
+
+/* Define if you have the <sys/wait.h> header file.  */
+#undef HAVE_SYS_WAIT_H
+
+/* Define if you have the <termios.h> header file.  */
+#undef HAVE_TERMIOS_H
+
+/* Define if you have the <thread.h> header file.  */
+#undef HAVE_THREAD_H
+
+/* Define if you have the <unistd.h> header file.  */
+#define HAVE_UNISTD_H 1
+
+/* Define if you have the <utime.h> header file.  */
+#undef HAVE_UTIME_H
+
+/* Define if you have the dl library (-ldl).  */
+#undef HAVE_LIBDL
+
+/* Define if you have the dld library (-ldld).  */
+#undef HAVE_LIBDLD
+
+/* Define if you have the ieee library (-lieee).  */
+#undef HAVE_LIBIEEE
+
+#ifdef __CYGWIN__
+#ifdef USE_DL_IMPORT
+#define DL_IMPORT(RTYPE) __declspec(dllimport) RTYPE
+#define DL_EXPORT(RTYPE) __declspec(dllexport) RTYPE
+#else
+#define DL_IMPORT(RTYPE) __declspec(dllexport) RTYPE
+#define DL_EXPORT(RTYPE) __declspec(dllexport) RTYPE
+#endif
+#endif
+
+/* Define the macros needed if on a UnixWare 7.x system. */
+#if defined(__USLC__) && defined(__SCO_VERSION__)
+#define STRICT_SYSV_CURSES /* Don't use ncurses extensions */
+#endif
+
+
+#define DONT_HAVE_FSTAT 1
+#define DONT_HAVE_STAT  1
+
+#define PLATFORM "riscos"
+
+#endif /* Py_PYCONFIG_H */

Added: vendor/Python/current/RISCOS/sleep.c
===================================================================
--- vendor/Python/current/RISCOS/sleep.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/RISCOS/sleep.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,41 @@
+#include "oslib/osmodule.h"
+#include <stdio.h>
+#include "kernel.h"
+#include <limits.h>
+#include <errno.h>
+#include "oslib/taskwindow.h"
+#include "Python.h"
+
+
+int riscos_sleep(double delay)
+{
+	os_t starttime, endtime, time; /* monotonic times (centiseconds) */
+	int *pollword, ret;
+	osbool claimed;
+
+        /* calculate end time */
+	starttime = os_read_monotonic_time();
+	if (starttime + 100.0*delay >INT_MAX)
+		endtime = INT_MAX;
+	else
+		endtime = (os_t)(starttime + 100.0*delay);
+
+	/* allocate (in RMA) and set pollword for xupcall_sleep */
+	pollword = osmodule_alloc(4);
+	*pollword = 1;
+
+	time = starttime;
+	ret = 0;
+	while ( time<endtime && time>=starttime ) {
+		xupcall_sleep (pollword, &claimed);
+		if (PyErr_CheckSignals()) {
+			ret = 1;
+			break;
+		}
+		time = os_read_monotonic_time();
+	}
+
+	/* deallocate pollword */
+	osmodule_free(pollword);
+	return ret;
+}

Added: vendor/Python/current/RISCOS/support/!Boot
===================================================================
--- vendor/Python/current/RISCOS/support/!Boot	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/RISCOS/support/!Boot	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,22 @@
+set Python$Dir <Obey$Dir>
+set PythonApp$Path <Obey$Dir>.
+
+IconSprites <Obey$Dir>.!Sprites
+
+<Obey$Dir>.AddToPath Python$Path PythonApp:Lib
+<Obey$Dir>.AddToPath Python$Path PythonApp:Lib.plat-riscos
+<Obey$Dir>.AddToPath Python$Path PythonApp:Lib.site-packages
+set Alias$@RunType_ae5 TaskWindow |"python %%*0|" -name |"Python|" -quit -wimpslot 1248k
+| -display
+set File$Type_ae5 Python
+
+| load modules for 32 bit compatibility
+RMEnsure UtilityModule 3.10 Error This application requires RISC OS 3.10 or later
+RMEnsure UtilityModule 3.70 RMEnsure CallASWI 0.02 RMLoad System:Modules.CallASWI
+RMEnsure UtilityModule 3.70 RMEnsure CallASWI 0.02 Error This application requires CallASWI 0.02 or later
+RMEnsure FPEmulator 4.03 RMLoad System:Modules.FPEmulator
+RMEnsure FPEmulator 4.03 Error This application requires FPEmulator 4.03 or later
+RMEnsure SharedCLibrary 5.17 RMLoad System:Modules.CLib
+RMEnsure SharedCLibrary 5.34 Error This application requires SharedCLibrary 5.34 or later
+
+set Alias$Python Run <Python$Dir>.python23 %*0
\ No newline at end of file

Added: vendor/Python/current/RISCOS/support/!Run
===================================================================
--- vendor/Python/current/RISCOS/support/!Run	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/RISCOS/support/!Run	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2 @@
+<Obey$Dir>.!Boot
+TaskWindow "python" -name "Python" -quit -display -wimpslot 1248k
\ No newline at end of file

Added: vendor/Python/current/RISCOS/support/!Sprites
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/RISCOS/support/!Sprites
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/RISCOS/support/!Sprites22
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/RISCOS/support/!Sprites22
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/RISCOS/support/AddToPath
===================================================================
(Binary files differ)


Property changes on: vendor/Python/current/RISCOS/support/AddToPath
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: vendor/Python/current/RISCOS/unixstuff.c
===================================================================
--- vendor/Python/current/RISCOS/unixstuff.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/RISCOS/unixstuff.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,74 @@
+/* Fudge unix isatty and fileno for RISCOS */
+
+#include "unixstuff.h"
+#include <math.h>
+#include <time.h>
+#include "oslib/osfile.h"
+
+int fileno(FILE *f)
+{ return (int)f;
+}
+
+int isatty(int fn)
+{ return (fn==fileno(stdin));
+}
+
+bits unixtime(bits ld,bits ex)
+{ ld&=0xFF;
+  ld-=51;
+  if(ex<1855547904U) ld--;
+  ex-=1855548004U;
+  return ex/100+42949673U*ld-ld/25;
+}
+
+
+/* from RISC OS infozip, preserves filetype in ld */
+int acorntime(bits *ex, bits *ld, time_t utime)
+{
+   unsigned timlo;      /* 3 lower bytes of acorn file-time plus carry byte */
+   unsigned timhi;      /* 2 high bytes of acorn file-time */
+
+   timlo = ((unsigned)utime & 0x00ffffffU) * 100 + 0x00996a00U;
+   timhi = ((unsigned)utime >> 24);
+   timhi = timhi * 100 + 0x0000336eU + (timlo >> 24);
+   if (timhi & 0xffff0000U)
+       return 1;        /* calculation overflow, do not change time */
+
+   /* insert the five time bytes into loadaddr and execaddr variables */
+   *ex = (timlo & 0x00ffffffU) | ((timhi & 0x000000ffU) << 24);
+   *ld = (*ld & 0xffffff00U)   | ((timhi >> 8) & 0x000000ffU);
+
+   return 0;            /* subject to future extension to signal overflow */
+}
+
+
+int isdir(char *fn)
+{ int ob;
+  if(xosfile_read_stamped_no_path(fn,&ob,0,0,0,0,0)) return 0;
+  switch (ob)
+  {   case osfile_IS_DIR:return 1;
+    case osfile_IS_IMAGE:return 1;
+  }
+  return 0;
+}
+
+int isfile(char *fn)
+{ int ob;
+  if(xosfile_read_stamped_no_path(fn,&ob,0,0,0,0,0)) return 0;
+  switch (ob)
+  {  case osfile_IS_FILE:return 1;
+    case osfile_IS_IMAGE:return 1;
+  }
+  return 0;
+}
+
+int object_exists(char *fn)
+{ int ob;
+  if(xosfile_read_stamped_no_path(fn,&ob,0,0,0,0,0)) return 0;
+  switch (ob)
+  {  case osfile_IS_FILE:return 1;
+      case osfile_IS_DIR:return 1;
+    case osfile_IS_IMAGE:return 1;
+  }
+  return 0;
+}

Added: vendor/Python/current/RISCOS/unixstuff.h
===================================================================
--- vendor/Python/current/RISCOS/unixstuff.h	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/RISCOS/unixstuff.h	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,14 @@
+/* Fudge unix isatty and fileno for RISCOS */
+
+#include <stdio.h>
+#include <time.h>
+
+int fileno(FILE *f);
+int isatty(int fn);
+unsigned int unixtime(unsigned int ld,unsigned int ex);
+int acorntime(unsigned int *ex, unsigned int *ld, time_t ut);
+
+int isdir(char *fn);
+int isfile(char *fn);
+int object_exists(char *fn);
+

Added: vendor/Python/current/Tools/README
===================================================================
--- vendor/Python/current/Tools/README	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/README	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,47 @@
+This directory contains a number of Python programs that are useful
+while building or extending Python.
+
+audiopy		Audiopy is a program to control the Solaris audio
+		device, allowing you to choose both the input and
+		output devices, and to set the output volume, that can
+		be run either as a command-line script, or as a
+		Tkinter application.
+
+bgen		Generate complete extension modules from a
+		description.  Still under development!
+
+compiler	Tools used to maintain the compiler package in the
+		standard library.
+
+faqwiz		FAQ Wizard.
+		See http://www.python.org/cgi-bin/faqw.py
+		for a live example.
+
+freeze		Create a stand-alone executable from a Python program.
+
+i18n		Tools for internationalization. pygettext.py 
+		parses Python source code and generates .pot files,
+		and msgfmt.py generates a binary message catalog 
+		from a catalog in text format.
+
+modulator	Interactively generate boiler plate for an extension
+		module.	 Works easiest if you have Tk.
+
+pynche		A Tkinter-based color editor.
+
+scripts		A number of useful single-file programs, e.g. tabnanny.py
+		(by Tim Peters), which checks for inconsistent mixing
+		of tabs and spaces.
+
+unicode		Tools used to generate unicode database files for
+		Python 2.0 (by Fredrik Lundh).
+
+versioncheck	A tool to automate checking whether you have the latest
+		version of a package (by Jack Jansen).
+
+webchecker	A link checker for web sites.
+
+world		Script to take a list of Internet addresses and print
+		out where in the world those addresses originate from,
+		based on the top-level domain country code found in
+		the address. 

Added: vendor/Python/current/Tools/audiopy/README
===================================================================
--- vendor/Python/current/Tools/audiopy/README	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/audiopy/README	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,112 @@
+audiopy - a program to control the Solaris audio device.
+
+Contact: Barry Warsaw
+Email:   bwarsaw at python.org
+Version: 1.1
+
+Introduction
+
+    Audiopy is a program to control the Solaris audio device, allowing
+    you to choose both the input and output devices, and to set the
+    output volume.  It can be run either as a standalone command-line
+    script, or as a Tkinter based GUI application.
+
+    Note that your version of Python must have been built with the
+    sunaudiodev module enabled.  It is not enabled by default however!
+    You will need to edit your Modules/Setup file, uncomment the
+    sunaudiodev module spec line and rebuild Python.
+
+    Using audiopy, you can select one of three possible input devices:
+    the microphone, the line-in jack, or the CD in.  These choices are
+    mutually exclusive; you can only have one active input device at
+    any one time (this is enforced by the underlying device).  Some
+    input devices may not be supported on all Solaris machines.
+
+    You can also choose to enable any of the three possible output
+    devices: the headphone jack, the speakers, or the line-out jack.
+    You can enable any combination of these three devices.
+
+    You can also set the output gain (volume) level.
+
+Running as a GUI
+
+    Simply start audiopy with no arguments to start it as a Tkinter
+    based GUI application.  It will pop up a window with two sections:
+    the top portion contains three radio buttons indicating your
+    selected input device; the middle portion contains three
+    checkboxes indicating your selected output devices; the bottom
+    portion contains a slider that changes the output gain.
+
+    Note the underlined characters in the button labels.  These
+    indicate keyboard accelerators so that pressing Alt+character you
+    can select that device.  For example, Alt-s toggles the Speaker
+    device.  The Alt accelerators are the same as those you'd use in
+    as the short-form command line switches (see below).
+
+    Alt-q is also an accelerator for selecting Quit from the File
+    menu.
+
+    Unsupported devices will appear dimmed out in the GUI.  When run
+    as a GUI, audiopy monitors the audio device and automatically
+    updates its display if the state of the device is changed by some
+    other means.  With Python versions before 1.5.2 this is done by
+    occasionally polling the device, but in Python 1.5.2 no polling is
+    necessary (you don't really need to know this, but I thought I'd
+    plug 1.5.2 :-).
+    
+Running as a Command Line Program
+
+    You can run audiopy from the command line to select any
+    combination of input or output device, by using the command line
+    options.  Actually, any option forces audiopy to run as a command
+    line program and not display its GUI.
+
+    Options have the general form
+
+        --device[={0,1}]
+        -d[-{0,1}]
+
+    meaning there is both a long-form and short-form of the switch,
+    where `device' or `d' is one of the following:
+
+        (input)
+            microphone -- m
+            linein     -- i
+            cd         -- c
+
+        (output)
+            headphones -- p
+            speaker    -- s
+            lineout    -- o
+
+    When no value is given, the switch just toggles the specified
+    device.  With a value, 0 turns the device off and 1 turns the
+    device on.  Any other value is an error.
+
+    For example, to turn the speakers off, turn the headphones on, and 
+    toggle the cd input device, run audiopy from the command line like 
+    so:
+
+    % ./audiopy -s=0 -p=1 -c
+
+    Audiopy understands these other command line options:
+
+    --gain volume
+    -g volume
+        Sets the output volume to the specified gain level.  This must 
+        be an integer between MIN_GAIN and MAX_GAIN (usually [0..255], 
+        but use the -h option to find the exact values).
+
+    --version
+    -v
+        Print the version number and exit
+
+    --help
+    -h
+        Print a help message and exit
+        
+
+
+Local Variables:
+indent-tabs-mode: nil
+End:

Added: vendor/Python/current/Tools/audiopy/audiopy
===================================================================
--- vendor/Python/current/Tools/audiopy/audiopy	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/audiopy/audiopy	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,507 @@
+#! /usr/bin/env python
+
+"""audiopy -- a program to control the Solaris audio device.
+
+Contact: Barry Warsaw
+Email:   bwarsaw at python.org
+Version: %(__version__)s
+
+When no arguments are given, this pops up a graphical window which lets you
+choose the audio input and output devices, and set the output volume.
+
+This program can be driven via the command line, and when done so, no window
+pops up.  Most options have the general form:
+
+    --device[={0,1}]
+    -d[={0,1}]
+        Set the I/O device.  With no value, it toggles the specified device.
+        With a value, 0 turns the device off and 1 turns the device on.
+
+The list of devices and their short options are:
+
+ (input)
+    microphone  -- m
+    linein      -- i
+    cd          -- c
+
+ (output)
+    headphones  -- p
+    speaker     -- s
+    lineout     -- o
+
+Other options are:
+
+    --gain volume
+    -g volume
+        Sets the output gain to the specified volume, which must be an integer
+        in the range [%(MIN_GAIN)s..%(MAX_GAIN)s]
+
+    --version
+    -v
+        Print the version number and exit.
+
+    --help
+    -h
+        Print this message and exit.
+"""
+
+import sys
+import os
+import errno
+import sunaudiodev
+from SUNAUDIODEV import *
+
+# Milliseconds between interrupt checks
+KEEPALIVE_TIMER = 500
+
+__version__ = '1.1'
+
+
+
+class MainWindow:
+    def __init__(self, device):
+        from Tkinter import *
+        self.__helpwin = None
+        self.__devctl = device
+        info = device.getinfo()
+        #
+        self.__tkroot = tkroot = Tk(className='Audiopy')
+        tkroot.withdraw()
+        # create the menubar
+        menubar = Menu(tkroot)
+        filemenu = Menu(menubar, tearoff=0)
+        filemenu.add_command(label='Quit',
+                             command=self.__quit,
+                             accelerator='Alt-Q',
+                             underline=0)
+        helpmenu = Menu(menubar, name='help', tearoff=0)
+        helpmenu.add_command(label='About Audiopy...',
+                             command=self.__popup_about,
+                             underline=0)
+        helpmenu.add_command(label='Help...',
+                             command=self.__popup_using,
+                             underline=0)
+        menubar.add_cascade(label='File',
+                            menu=filemenu,
+                            underline=0)
+        menubar.add_cascade(label='Help',
+                            menu=helpmenu,
+                            underline=0)
+        # now create the top level window
+        root = self.__root = Toplevel(tkroot, class_='Audiopy', menu=menubar)
+        root.protocol('WM_DELETE_WINDOW', self.__quit)
+        root.title('audiopy ' + __version__)
+        root.iconname('audiopy ' + __version__)
+        root.tk.createtimerhandler(KEEPALIVE_TIMER, self.__keepalive)
+        #
+        buttons = []
+        #
+        # where does input come from?
+        frame = Frame(root, bd=1, relief=RAISED)
+        frame.grid(row=1, column=0, sticky='NSEW')
+        label = Label(frame, text='Input From:')
+        label.grid(row=0, column=0, sticky=E)
+        self.__inputvar = IntVar()
+        ##
+        btn = Radiobutton(frame,
+                          text='None',
+                          variable=self.__inputvar,
+                          value=0,
+                          command=self.__pushtodev,
+                          underline=0)
+        btn.grid(row=0, column=1, sticky=W)
+        root.bind('<Alt-n>', self.__none)
+        root.bind('<Alt-N>', self.__none)
+        if not info.i_avail_ports & MICROPHONE:
+            btn.configure(state=DISABLED)
+        buttons.append(btn)
+        ##
+        btn = Radiobutton(frame,
+                          text='Microphone',
+                          variable=self.__inputvar,
+                          value=MICROPHONE,
+                          command=self.__pushtodev,
+                          underline=0)
+        btn.grid(row=1, column=1, sticky=W)
+        root.bind('<Alt-m>', self.__mic)
+        root.bind('<Alt-M>', self.__mic)
+        if not info.i_avail_ports & MICROPHONE:
+            btn.configure(state=DISABLED)
+        buttons.append(btn)
+        ##
+        btn = Radiobutton(frame,
+                          text='Line In',
+                          variable=self.__inputvar,
+                          value=LINE_IN,
+                          command=self.__pushtodev,
+                          underline=5)
+        btn.grid(row=2, column=1, sticky=W)
+        root.bind('<Alt-i>', self.__linein)
+        root.bind('<Alt-I>', self.__linein)
+        if not info.i_avail_ports & LINE_IN:
+            btn.configure(state=DISABLED)
+        buttons.append(btn)
+        ## if SUNAUDIODEV was built on an older version of Solaris, the CD
+        ## input device won't exist
+        try:
+            btn = Radiobutton(frame,
+                              text='CD',
+                              variable=self.__inputvar,
+                              value=CD,
+                              command=self.__pushtodev,
+                              underline=0)
+            btn.grid(row=3, column=1, sticky=W)
+            root.bind('<Alt-c>', self.__cd)
+            root.bind('<Alt-C>', self.__cd)
+            if not info.i_avail_ports & CD:
+                btn.configure(state=DISABLED)
+            buttons.append(btn)
+        except NameError:
+            pass
+        #
+        # where does output go to?
+        frame = Frame(root, bd=1, relief=RAISED)
+        frame.grid(row=2, column=0, sticky='NSEW')
+        label = Label(frame, text='Output To:')
+        label.grid(row=0, column=0, sticky=E)
+        self.__spkvar = IntVar()
+        btn = Checkbutton(frame,
+                          text='Speaker',
+                          variable=self.__spkvar,
+                          onvalue=SPEAKER,
+                          command=self.__pushtodev,
+                          underline=0)
+        btn.grid(row=0, column=1, sticky=W)
+        root.bind('<Alt-s>', self.__speaker)
+        root.bind('<Alt-S>', self.__speaker)
+        if not info.o_avail_ports & SPEAKER:
+            btn.configure(state=DISABLED)
+        buttons.append(btn)
+        ##
+        self.__headvar = IntVar()
+        btn = Checkbutton(frame,
+                          text='Headphones',
+                          variable=self.__headvar,
+                          onvalue=HEADPHONE,
+                          command=self.__pushtodev,
+                          underline=4)
+        btn.grid(row=1, column=1, sticky=W)
+        root.bind('<Alt-p>', self.__headphones)
+        root.bind('<Alt-P>', self.__headphones)
+        if not info.o_avail_ports & HEADPHONE:
+            btn.configure(state=DISABLED)
+        buttons.append(btn)
+        ##
+        self.__linevar = IntVar()
+        btn = Checkbutton(frame,
+                          variable=self.__linevar,
+                          onvalue=LINE_OUT,
+                          text='Line Out',
+                          command=self.__pushtodev,
+                          underline=0)
+        btn.grid(row=2, column=1, sticky=W)
+        root.bind('<Alt-l>', self.__lineout)
+        root.bind('<Alt-L>', self.__lineout)
+        if not info.o_avail_ports & LINE_OUT:
+            btn.configure(state=DISABLED)
+        buttons.append(btn)
+        #
+        # Fix up widths
+        widest = 0
+        for b in buttons:
+            width = b['width']
+            if width > widest:
+                widest = width
+        for b in buttons:
+            b.configure(width=widest)
+        # root bindings
+        root.bind('<Alt-q>', self.__quit)
+        root.bind('<Alt-Q>', self.__quit)
+        #
+        # Volume
+        frame = Frame(root, bd=1, relief=RAISED)
+        frame.grid(row=3, column=0, sticky='NSEW')
+        label = Label(frame, text='Output Volume:')
+        label.grid(row=0, column=0, sticky=W)
+        self.__scalevar = IntVar()
+        self.__scale = Scale(frame,
+                             orient=HORIZONTAL,
+                             from_=MIN_GAIN,
+                             to=MAX_GAIN,
+                             length=200,
+                             variable=self.__scalevar,
+                             command=self.__volume)
+        self.__scale.grid(row=1, column=0, sticky=EW)
+        #
+        # do we need to poll for changes?
+        self.__needtopoll = 1
+        try:
+            fd = self.__devctl.fileno()
+            self.__needtopoll = 0
+        except AttributeError:
+            pass
+        else:
+            import fcntl
+            import signal
+            import STROPTS
+            # set up the signal handler
+            signal.signal(signal.SIGPOLL, self.__update)
+            fcntl.ioctl(fd, STROPTS.I_SETSIG, STROPTS.S_MSG)
+            self.__update()
+        
+    def __quit(self, event=None):
+        self.__devctl.close()
+        self.__root.quit()
+
+    def __popup_about(self, event=None):
+        import tkMessageBox
+        tkMessageBox.showinfo('About Audiopy ' + __version__,
+                              '''\
+Audiopy %s
+Control the Solaris audio device
+
+For information
+Contact: Barry A. Warsaw
+Email:   bwarsaw at python.org''' % __version__)
+
+    def __popup_using(self, event=None):
+        if not self.__helpwin:
+            self.__helpwin = Helpwin(self.__tkroot, self.__quit)
+        self.__helpwin.deiconify()
+            
+
+    def __keepalive(self):
+        # Exercise the Python interpreter regularly so keyboard interrupts get
+        # through.
+        self.__tkroot.tk.createtimerhandler(KEEPALIVE_TIMER, self.__keepalive)
+        if self.__needtopoll:
+            self.__update()
+
+    def __update(self, num=None, frame=None):
+        # It's possible (although I have never seen it) to get an interrupted
+        # system call during the getinfo() call.  If so, and we're polling,
+        # don't sweat it because we'll come around again later.  Otherwise,
+        # we'll give it a couple of tries and then give up until next time.
+        tries = 0
+        while 1:
+            try:
+                info = self.__devctl.getinfo()
+                break
+            except sunaudiodev.error:
+                if self.__needtopoll or tries > 3:
+                    return
+                tries = tries + 1
+        # input
+        self.__inputvar.set(info.i_port)
+        # output
+        self.__spkvar.set(info.o_port & SPEAKER)
+        self.__headvar.set(info.o_port & HEADPHONE)
+        self.__linevar.set(info.o_port & LINE_OUT)
+        # volume
+        self.__scalevar.set(info.o_gain)
+
+    def __pushtodev(self, event=None):
+        info = self.__devctl.getinfo()
+        info.o_port = self.__spkvar.get() + \
+                      self.__headvar.get() + \
+                      self.__linevar.get()
+        info.i_port = self.__inputvar.get()
+        info.o_gain = self.__scalevar.get()
+        try:
+            self.__devctl.setinfo(info)
+        except sunaudiodev.error, msg:
+            # TBD: what to do?  it's probably temporary.
+            pass
+
+    def __getset(self, var, onvalue):
+        if var.get() == onvalue:
+            var.set(0)
+        else:
+            var.set(onvalue)
+        self.__pushtodev()
+
+    def __none(self, event=None):
+        self.__inputvar.set(0)
+        self.__pushtodev()
+
+    def __mic(self, event=None):
+        self.__getset(self.__inputvar, MICROPHONE)
+
+    def __linein(self, event=None):
+        self.__getset(self.__inputvar, LINE_IN)
+
+    def __cd(self, event=None):
+        self.__getset(self.__inputvar, CD)
+
+    def __speaker(self, event=None):
+        self.__getset(self.__spkvar, SPEAKER)
+
+    def __headphones(self, event=None):
+        self.__getset(self.__headvar, HEADPHONE)
+
+    def __lineout(self, event=None):
+        self.__getset(self.__linevar, LINE_OUT)
+
+    def __volume(self, event=None):
+        self.__pushtodev()
+
+    def start(self):
+        self.__keepalive()
+        self.__tkroot.mainloop()
+
+
+
+class Helpwin:
+    def __init__(self, master, quitfunc):
+        from Tkinter import *
+        self.__root = root = Toplevel(master, class_='Audiopy')
+        root.protocol('WM_DELETE_WINDOW', self.__withdraw)
+        root.title('Audiopy Help Window')
+        root.iconname('Audiopy Help Window')
+        root.bind('<Alt-q>', quitfunc)
+        root.bind('<Alt-Q>', quitfunc)
+        root.bind('<Alt-w>', self.__withdraw)
+        root.bind('<Alt-W>', self.__withdraw)
+
+        # more elaborate help is available in the README file
+        readmefile = os.path.join(sys.path[0], 'README')
+        try:
+            fp = None
+            try:
+                fp = open(readmefile)
+                contents = fp.read()
+                # wax the last page, it contains Emacs cruft
+                i = contents.rfind('\f')
+                if i > 0:
+                    contents = contents[:i].rstrip()
+            finally:
+                if fp:
+                    fp.close()
+        except IOError:
+            sys.stderr.write("Couldn't open audiopy's README, "
+                             'using docstring instead.\n')
+            contents = __doc__ % globals()
+
+        self.__text = text = Text(root, relief=SUNKEN,
+                                  width=80, height=24)
+        text.insert(0.0, contents)
+        scrollbar = Scrollbar(root)
+        scrollbar.pack(fill=Y, side=RIGHT)
+        text.pack(fill=BOTH, expand=YES)
+        text.configure(yscrollcommand=(scrollbar, 'set'))
+        scrollbar.configure(command=(text, 'yview'))
+
+    def __withdraw(self, event=None):
+        self.__root.withdraw()
+
+    def deiconify(self):
+        self.__root.deiconify()
+
+
+
+
+def usage(code, msg=''):
+    print __doc__ % globals()
+    if msg:
+        print msg
+    sys.exit(code)
+
+
+def main():
+    #
+    # Open up the audio control device and query for the current output
+    # device
+    device = sunaudiodev.open('control')
+
+    if len(sys.argv) == 1:
+        # GUI
+        w = MainWindow(device)
+        try:
+            w.start()
+        except KeyboardInterrupt:
+            pass
+        return
+
+    # spec:    LONG OPT, SHORT OPT, 0=input,1=output, MASK
+    options = [('--microphone', '-m', 0, MICROPHONE),
+               ('--linein',     '-i', 0, LINE_IN),
+               ('--headphones', '-p', 1, HEADPHONE),
+               ('--speaker',    '-s', 1, SPEAKER),
+               ('--lineout',    '-o', 1, LINE_OUT),
+               ]
+    # See the comment above about `CD'
+    try:
+        options.append(('--cd',         '-c', 0, CD))
+    except NameError:
+        pass
+
+    info = device.getinfo()
+    # first get the existing values
+    i = 0
+    while i < len(sys.argv)-1:
+        i = i + 1
+        arg = sys.argv[i]
+        if arg in ('-h', '--help'):
+            usage(0)
+            # does not return
+        elif arg in ('-g', '--gain'):
+            gainspec = '<missing>'
+            try:
+                gainspec = sys.argv[i+1]
+                gain = int(gainspec)
+            except (ValueError, IndexError):
+                usage(1, 'Bad gain specification: ' + gainspec)
+            info.o_gain = gain
+            i = i + 1
+            continue
+        elif arg in ('-v', '--version'):
+            print '''\
+audiopy -- a program to control the Solaris audio device.
+Contact: Barry Warsaw
+Email:   bwarsaw at python.org
+Version: %s''' % __version__            
+            sys.exit(0)
+        for long, short, io, mask in options:
+            if arg in (long, short):
+                # toggle the option
+                if io == 0: 
+                    info.i_port = info.i_port ^ mask
+                else:
+                    info.o_port = info.o_port ^ mask
+                break
+            val = None
+            try:
+                if arg[:len(long)+1] == long+'=':
+                    val = int(arg[len(long)+1:])
+                elif arg[:len(short)+1] == short+'=':
+                    val = int(arg[len(short)+1:])
+            except ValueError:
+                usage(1, msg='Invalid option: ' + arg)
+                # does not return
+            if val == 0:
+                if io == 0:
+                    info.i_port = info.i_port & ~mask
+                else:
+                    info.o_port = info.o_port & ~mask
+                break
+            elif val == 1:
+                if io == 0:
+                    info.i_port = info.i_port | mask
+                else:
+                    info.o_port = info.o_port | mask
+                break
+            # else keep trying next option
+        else:
+            usage(1, msg='Invalid option: ' + arg)
+    # now set the values
+    try:
+        device.setinfo(info)
+    except sunaudiodev.error, (code, msg):
+        if code <> errno.EINVAL:
+            raise
+    device.close()
+            
+
+
+if __name__ == '__main__':
+    main()


Property changes on: vendor/Python/current/Tools/audiopy/audiopy
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/bgen/README
===================================================================
--- vendor/Python/current/Tools/bgen/README	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/bgen/README	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,7 @@
+BGEN -- Automatic Generation of Extension Modules
+=================================================
+
+This directory contains BGEN -- a package that helps in generating
+complete source code for Python extension module.  For examples of its
+use, see the Mac Python source distribution (available separately
+from the Python ftp archives).  Note that BGEN is not Mac specific!

Added: vendor/Python/current/Tools/bgen/bgen/bgen.py
===================================================================
--- vendor/Python/current/Tools/bgen/bgen/bgen.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/bgen/bgen/bgen.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,12 @@
+"Export everything in the various bgen submodules."
+
+from bgenType import *
+from bgenVariable import *
+from bgenBuffer import *
+from bgenStackBuffer import *
+from bgenHeapBuffer import *
+from bgenStringBuffer import *
+from bgenOutput import *
+from bgenGenerator import *
+from bgenModule import *
+from bgenObjectDefinition import *

Added: vendor/Python/current/Tools/bgen/bgen/bgenBuffer.py
===================================================================
--- vendor/Python/current/Tools/bgen/bgen/bgenBuffer.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/bgen/bgen/bgenBuffer.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,301 @@
+"""Buffers are character arrays that may contain null bytes.
+
+There are a number of variants depending on:
+- how the buffer is allocated (for output buffers), and
+- whether and how the size is passed into and/or out of the called function.
+"""
+
+
+from bgenType import Type, InputOnlyMixIn, OutputOnlyMixIn, InputOnlyType, OutputOnlyType
+from bgenOutput import *
+
+
+# Map common types to their format characters
+type2format = {
+    'long': 'l',
+    'int': 'i',
+    'short': 'h',
+    'char': 'b',
+    'unsigned long': 'l',
+    'unsigned int': 'i',
+    'unsigned short': 'h',
+    'unsigned char': 'b',
+}
+
+
+# ----- PART 1: Fixed character buffers -----
+
+
+class FixedInputOutputBufferType(InputOnlyType):
+
+    """Fixed buffer -- passed as (inbuffer, outbuffer)."""
+
+    def __init__(self, size, datatype = 'char', sizetype = 'int', sizeformat = None):
+        self.typeName = "Buffer"
+        self.size = str(size)
+        self.datatype = datatype
+        self.sizetype = sizetype
+        self.sizeformat = sizeformat or type2format[sizetype]
+        self.label_needed = 0
+
+    def getArgDeclarations(self, name, reference=False, constmode=False, outmode=False):
+        if reference:
+            raise RuntimeError, "Cannot pass buffer types by reference"
+        return (self.getBufferDeclarations(name, constmode, outmode) +
+                self.getSizeDeclarations(name, outmode))
+
+    def getBufferDeclarations(self, name, constmode=False, outmode=False):
+        return self.getInputBufferDeclarations(name, constmode) + \
+                self.getOutputBufferDeclarations(name, constmode, outmode)
+
+    def getInputBufferDeclarations(self, name, constmode=False):
+        if constmode:
+            const = "const "
+        else:
+            const = ""
+        return ["%s%s *%s__in__" % (const, self.datatype, name)]
+
+    def getOutputBufferDeclarations(self, name, constmode=False, outmode=False):
+        if constmode:
+            raise RuntimeError, "Cannot use const output buffer"
+        if outmode:
+            out = "*"
+        else:
+            out = ""
+        return ["%s%s %s__out__[%s]" % (self.datatype, out, name, self.size)]
+
+    def getSizeDeclarations(self, name, outmode=False):
+        if outmode:
+            out = "*"
+        else:
+            out = ""
+        return ["%s%s %s__len__" %(self.sizetype, out, name)]
+
+    def getAuxDeclarations(self, name):
+        return ["int %s__in_len__" %(name)]
+
+    def getargsFormat(self):
+        return "s#"
+
+    def getargsArgs(self, name):
+        return "&%s__in__, &%s__in_len__" % (name, name)
+
+    def getargsCheck(self, name):
+        Output("if (%s__in_len__ != %s)", name, self.size)
+        OutLbrace()
+        Output('PyErr_SetString(PyExc_TypeError, "buffer length should be %s");',
+               self.size)
+        Output("goto %s__error__;", name)
+        self.label_needed = 1
+        OutRbrace()
+        self.transferSize(name)
+
+    def transferSize(self, name):
+        Output("%s__len__ = %s__in_len__;", name, name)
+
+    def passOutput(self, name):
+        return "%s__in__, %s__out__" % (name, name)
+
+    def mkvalueFormat(self):
+        return "s#"
+
+    def mkvalueArgs(self, name):
+        return "%s__out__, (int)%s" % (name, self.size)
+
+    def cleanup(self, name):
+        if self.label_needed:
+            DedentLevel()
+            Output(" %s__error__: ;", name)
+            IndentLevel()
+
+
+class FixedCombinedInputOutputBufferType(FixedInputOutputBufferType):
+
+    """Like fixed buffer -- but same parameter is input and output."""
+
+    def passOutput(self, name):
+        return "(%s *)memcpy(%s__out__, %s__in__, %s)" % \
+            (self.datatype, name,   name,     self.size)
+
+
+class InputOnlyBufferMixIn(InputOnlyMixIn):
+
+    def getOutputBufferDeclarations(self, name, constmode=False, outmode=False):
+        return []
+
+
+class OutputOnlyBufferMixIn(OutputOnlyMixIn):
+
+    def getInputBufferDeclarations(self, name, constmode=False):
+        return []
+
+class OptionalInputBufferMixIn:
+
+    """Add to input buffers if the buffer may be omitted: pass None in Python
+    and the C code will get a NULL pointer and zero size"""
+
+    def getargsFormat(self):
+        return "z#"
+
+
+class FixedInputBufferType(InputOnlyBufferMixIn, FixedInputOutputBufferType):
+
+    """Fixed size input buffer -- passed without size information.
+
+    Instantiate with the size as parameter.
+    """
+
+    def passInput(self, name):
+        return "%s__in__" % name
+
+class OptionalFixedInputBufferType(OptionalInputBufferMixIn, FixedInputBufferType):
+    pass
+
+class FixedOutputBufferType(OutputOnlyBufferMixIn, FixedInputOutputBufferType):
+
+    """Fixed size output buffer -- passed without size information.
+
+    Instantiate with the size as parameter.
+    """
+
+    def passOutput(self, name):
+        return "%s__out__" % name
+
+
+class VarInputBufferType(FixedInputBufferType):
+
+    """Variable size input buffer -- passed as (buffer, size).
+
+    Instantiate without size parameter.
+    """
+
+    def __init__(self, datatype = 'char', sizetype = 'int', sizeformat = None):
+        FixedInputBufferType.__init__(self, "0", datatype, sizetype, sizeformat)
+
+    def getargsCheck(self, name):
+        Output("%s__len__ = %s__in_len__;", name, name)
+
+    def passInput(self, name):
+        return "%s__in__, %s__len__" % (name, name)
+
+class ReverseInputBufferMixin:
+    """ Mixin for input buffers that are passed as (size, buffer) """
+
+    def passInput(self, name):
+        return "%s__len__, %s__in__" % (name, name)
+
+class OptionalVarInputBufferType(OptionalInputBufferMixIn, VarInputBufferType):
+    pass
+
+# ----- PART 2: Structure buffers -----
+
+
+class StructInputOutputBufferType(FixedInputOutputBufferType):
+
+    """Structure buffer -- passed as a structure pointer.
+
+    Instantiate with the struct type as parameter.
+    """
+
+    def __init__(self, type):
+        FixedInputOutputBufferType.__init__(self, "sizeof(%s)" % type)
+        self.typeName = self.type = type
+
+    def getInputBufferDeclarations(self, name, constmode=False):
+        if constmode:
+            const = "const "
+        else:
+            const = ""
+        return ["%s%s *%s__in__" % (const, self.type, name)]
+
+    def getSizeDeclarations(self, name, outmode=False):
+        return []
+
+    def getAuxDeclarations(self, name):
+        return ["int %s__in_len__" % (name)]
+
+    def getOutputBufferDeclarations(self, name, constmode=False, outmode=False):
+        if constmode:
+            raise RuntimeError, "Cannot use const output buffer"
+        if outmode:
+            out = "*"
+        else:
+            out = ""
+        return ["%s%s %s__out__" % (self.type, out, name)]
+
+    def getargsArgs(self, name):
+        return "(char **)&%s__in__, &%s__in_len__" % (name, name)
+
+    def transferSize(self, name):
+        pass
+
+    def passInput(self, name):
+        return "%s__in__" % name
+
+    def passOutput(self, name):
+        return "%s__in__, &%s__out__" % (name, name)
+
+    def mkvalueArgs(self, name):
+        return "(char *)&%s__out__, (int)%s" % (name, self.size)
+
+
+class StructCombinedInputOutputBufferType(StructInputOutputBufferType):
+
+    """Like structure buffer -- but same parameter is input and output."""
+
+    def passOutput(self, name):
+        return "(%s *)memcpy((char *)%s__out__, (char *)%s__in__, %s)" % \
+            (self.type,          name,              name,     self.size)
+
+
+class StructInputBufferType(InputOnlyBufferMixIn, StructInputOutputBufferType):
+
+    """Fixed size input buffer -- passed as a pointer to a structure.
+
+    Instantiate with the struct type as parameter.
+    """
+
+
+class StructByValueBufferType(StructInputBufferType):
+
+    """Fixed size input buffer -- passed as a structure BY VALUE.
+
+    Instantiate with the struct type as parameter.
+    """
+
+    def passInput(self, name):
+        return "*%s__in__" % name
+
+
+class StructOutputBufferType(OutputOnlyBufferMixIn, StructInputOutputBufferType):
+
+    """Fixed size output buffer -- passed as a pointer to a structure.
+
+    Instantiate with the struct type as parameter.
+    """
+
+    def getSizeDeclarations(self, name, outmode=False):
+        return []
+
+    def getAuxDeclarations(self, name):
+        return []
+
+    def passOutput(self, name):
+        return "&%s__out__" % name
+
+
+class ArrayOutputBufferType(OutputOnlyBufferMixIn, StructInputOutputBufferType):
+
+    """Fixed size output buffer -- declared as a typedef, passed as an array.
+
+    Instantiate with the struct type as parameter.
+    """
+
+    def getSizeDeclarations(self, name, outmode=False):
+        return []
+
+    def getAuxDeclarations(self, name):
+        return []
+
+    def passOutput(self, name):
+        return "%s__out__" % name

Added: vendor/Python/current/Tools/bgen/bgen/bgenGenerator.py
===================================================================
--- vendor/Python/current/Tools/bgen/bgen/bgenGenerator.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/bgen/bgen/bgenGenerator.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,302 @@
+from bgenOutput import *
+from bgenType import *
+from bgenVariable import *
+
+
+Error = "bgenGenerator.Error"
+
+DEBUG=0
+
+# Strings to specify argument transfer modes in generator calls
+IN = "in"
+OUT = "out"
+INOUT = IN_OUT = "in-out"
+
+
+class BaseFunctionGenerator:
+
+    def __init__(self, name, condition=None, callname=None, modifiers=None):
+        if DEBUG: print "<--", name
+        self.name = name
+        if callname:
+            self.callname = callname
+        else:
+            self.callname = name
+        self.prefix = name
+        self.objecttype = "PyObject" # Type of _self argument to function
+        self.condition = condition
+        self.modifiers = modifiers
+
+    def setprefix(self, prefix):
+        self.prefix = prefix
+
+    def checkgenerate(self):
+        return True
+
+    def generate(self):
+        if not self.checkgenerate():
+            return
+        if DEBUG: print "-->", self.name
+        if self.condition:
+            Output()
+            Output(self.condition)
+        self.functionheader()
+        self.functionbody()
+        self.functiontrailer()
+        if self.condition:
+            Output("#endif")
+
+    def functionheader(self):
+        Output()
+        Output("static PyObject *%s_%s(%s *_self, PyObject *_args)",
+               self.prefix, self.name, self.objecttype)
+        OutLbrace()
+        Output("PyObject *_res = NULL;")
+
+    def functionbody(self):
+        Output("/* XXX To be provided */")
+
+    def functiontrailer(self):
+        OutRbrace()
+
+    def reference(self, name = None):
+        if not self.checkgenerate():
+            return
+        if name is None:
+            name = self.name
+        docstring = self.docstring()
+        if self.condition:
+            Output()
+            Output(self.condition)
+        Output("{\"%s\", (PyCFunction)%s_%s, 1,", name, self.prefix, self.name)
+        Output(" PyDoc_STR(%s)},", stringify(docstring))
+        if self.condition:
+            Output("#endif")
+
+    def docstring(self):
+        return None
+
+    def __cmp__(self, other):
+        if not hasattr(other, 'name'):
+            return cmp(id(self), id(other))
+        return cmp(self.name, other.name)
+
+_stringify_map = {'\n': '\\n', '\t': '\\t', '\r': '\\r', '\b': '\\b',
+                  '\e': '\\e', '\a': '\\a', '\f': '\\f', '"': '\\"'}
+def stringify(str):
+    if str is None: return "NULL"
+    res = '"'
+    map = _stringify_map
+    for c in str:
+        if map.has_key(c): res = res + map[c]
+        elif ' ' <= c <= '~': res = res + c
+        else: res = res + '\\%03o' % ord(c)
+    res = res + '"'
+    return res
+
+
+class ManualGenerator(BaseFunctionGenerator):
+
+    def __init__(self, name, body, condition=None):
+        BaseFunctionGenerator.__init__(self, name, condition=condition)
+        self.body = body
+
+    def functionbody(self):
+        Output("%s", self.body)
+
+    def setselftype(self, selftype, itselftype):
+        self.objecttype = selftype
+        self.itselftype = itselftype
+
+
+class FunctionGenerator(BaseFunctionGenerator):
+
+    def __init__(self, returntype, name, *argumentList, **conditionlist):
+        BaseFunctionGenerator.__init__(self, name, **conditionlist)
+        self.returntype = returntype
+        self.argumentList = []
+        self.setreturnvar()
+        self.parseArgumentList(argumentList)
+        self.prefix     = "XXX"    # Will be changed by setprefix() call
+        self.itselftype = None     # Type of _self->ob_itself, if defined
+
+    def setreturnvar(self):
+        if self.returntype:
+            self.rv = self.makereturnvar()
+            self.argumentList.append(self.rv)
+        else:
+            self.rv = None
+
+    def makereturnvar(self):
+        return Variable(self.returntype, "_rv", OutMode)
+
+    def setselftype(self, selftype, itselftype):
+        self.objecttype = selftype
+        self.itselftype = itselftype
+
+    def parseArgumentList(self, argumentList):
+        iarg = 0
+        for type, name, mode in argumentList:
+            iarg = iarg + 1
+            if name is None: name = "_arg%d" % iarg
+            arg = Variable(type, name, mode)
+            self.argumentList.append(arg)
+
+    def docstring(self):
+        input = []
+        output = []
+        for arg in self.argumentList:
+            if arg.flags == ErrorMode or arg.flags == SelfMode:
+                continue
+            if arg.type == None:
+                str = 'void'
+            else:
+                if hasattr(arg.type, 'typeName'):
+                    typeName = arg.type.typeName
+                    if typeName is None: # Suppressed type
+                        continue
+                else:
+                    typeName = "?"
+                    print "Nameless type", arg.type
+
+                str = typeName + ' ' + arg.name
+            if arg.mode in (InMode, InOutMode):
+                input.append(str)
+            if arg.mode in (InOutMode, OutMode):
+                output.append(str)
+        if not input:
+            instr = "()"
+        else:
+            instr = "(%s)" % ", ".join(input)
+        if not output or output == ["void"]:
+            outstr = "None"
+        else:
+            outstr = "(%s)" % ", ".join(output)
+        return instr + " -> " + outstr
+
+    def functionbody(self):
+        self.declarations()
+        self.precheck()
+        self.getargs()
+        self.callit()
+        self.checkit()
+        self.returnvalue()
+
+    def declarations(self):
+        for arg in self.argumentList:
+            arg.declare()
+
+    def getargs(self):
+        sep = ",\n" + ' '*len("if (!PyArg_ParseTuple(")
+        fmt, lst = self.getargsFormatArgs(sep)
+        Output("if (!PyArg_ParseTuple(_args, \"%s\"%s))", fmt, lst)
+        IndentLevel()
+        Output("return NULL;")
+        DedentLevel()
+        for arg in self.argumentList:
+            if arg.flags == SelfMode:
+                continue
+            if arg.mode in (InMode, InOutMode):
+                arg.getargsCheck()
+
+    def getargsFormatArgs(self, sep):
+        fmt = ""
+        lst = ""
+        for arg in self.argumentList:
+            if arg.flags == SelfMode:
+                continue
+            if arg.mode in (InMode, InOutMode):
+                arg.getargsPreCheck()
+                fmt = fmt + arg.getargsFormat()
+                args = arg.getargsArgs()
+                if args:
+                    lst = lst + sep + args
+        return fmt, lst
+
+    def precheck(self):
+        pass
+
+    def beginallowthreads(self):
+        pass
+
+    def endallowthreads(self):
+        pass
+
+    def callit(self):
+        args = ""
+        s = "%s%s(" % (self.getrvforcallit(), self.callname)
+        sep = ",\n" + ' '*len(s)
+        for arg in self.argumentList:
+            if arg is self.rv:
+                continue
+            s = arg.passArgument()
+            if args: s = sep + s
+            args = args + s
+        self.beginallowthreads()
+        Output("%s%s(%s);",
+               self.getrvforcallit(), self.callname, args)
+        self.endallowthreads()
+
+    def getrvforcallit(self):
+        if self.rv:
+            return "%s = " % self.rv.name
+        else:
+            return ""
+
+    def checkit(self):
+        for arg in self.argumentList:
+            arg.errorCheck()
+
+    def returnvalue(self):
+        sep = ",\n" + ' '*len("return Py_BuildValue(")
+        fmt, lst = self.mkvalueFormatArgs(sep)
+        if fmt == "":
+            Output("Py_INCREF(Py_None);")
+            Output("_res = Py_None;");
+        else:
+            Output("_res = Py_BuildValue(\"%s\"%s);", fmt, lst)
+        tmp = self.argumentList[:]
+        tmp.reverse()
+        for arg in tmp:
+            if not arg: continue
+            arg.cleanup()
+        Output("return _res;")
+
+    def mkvalueFormatArgs(self, sep):
+        fmt = ""
+        lst = ""
+        for arg in self.argumentList:
+            if not arg: continue
+            if arg.flags == ErrorMode: continue
+            if arg.mode in (OutMode, InOutMode):
+                arg.mkvaluePreCheck()
+                fmt = fmt + arg.mkvalueFormat()
+                lst = lst + sep + arg.mkvalueArgs()
+        return fmt, lst
+
+class MethodGenerator(FunctionGenerator):
+
+    def parseArgumentList(self, args):
+        a0, args = args[0], args[1:]
+        t0, n0, m0 = a0
+        if m0 != InMode:
+            raise ValueError, "method's 'self' must be 'InMode'"
+        self.itself = Variable(t0, "_self->ob_itself", SelfMode)
+        self.argumentList.append(self.itself)
+        FunctionGenerator.parseArgumentList(self, args)
+
+def _test():
+    void = None
+    eggs = FunctionGenerator(void, "eggs",
+                 (stringptr, 'cmd', InMode),
+                 (int, 'x', InMode),
+                 (double, 'y', InOutMode),
+                 (int, 'status', ErrorMode),
+                 )
+    eggs.setprefix("spam")
+    print "/* START */"
+    eggs.generate()
+
+
+if __name__ == "__main__":
+    _test()

Added: vendor/Python/current/Tools/bgen/bgen/bgenGeneratorGroup.py
===================================================================
--- vendor/Python/current/Tools/bgen/bgen/bgenGeneratorGroup.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/bgen/bgen/bgenGeneratorGroup.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,40 @@
+from bgenOutput import *
+
+class GeneratorGroup:
+
+    def __init__(self, prefix):
+        self.prefix = prefix
+        self.generators = []
+
+    def add(self, g, dupcheck=0):
+        if dupcheck:
+            if g in self.generators:
+                print 'DUP', g.name
+                return
+        g.setprefix(self.prefix)
+        self.generators.append(g)
+
+    def generate(self):
+        for g in self.generators:
+            g.generate()
+        Output()
+        Output("static PyMethodDef %s_methods[] = {", self.prefix)
+        IndentLevel()
+        for g in self.generators:
+            g.reference()
+        Output("{NULL, NULL, 0}")
+        DedentLevel()
+        Output("};")
+
+
+def _test():
+    void = None
+    from bgenGenerator import FunctionGenerator
+    group = GeneratorGroup("spam")
+    eggs = FunctionGenerator(void, "eggs")
+    group.add(eggs)
+    print "/* START */"
+    group.generate()
+
+if __name__ == "__main__":
+    _test()

Added: vendor/Python/current/Tools/bgen/bgen/bgenHeapBuffer.py
===================================================================
--- vendor/Python/current/Tools/bgen/bgen/bgenHeapBuffer.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/bgen/bgen/bgenHeapBuffer.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,145 @@
+# Buffers allocated on the heap
+
+from bgenOutput import *
+from bgenType import OutputOnlyMixIn
+from bgenBuffer import FixedInputOutputBufferType
+
+
+class HeapInputOutputBufferType(FixedInputOutputBufferType):
+
+    """Input-output buffer allocated on the heap -- passed as (inbuffer, outbuffer, size).
+
+    Instantiate without parameters.
+    Call from Python with input buffer.
+    """
+
+    def __init__(self, datatype = 'char', sizetype = 'int', sizeformat = None):
+        FixedInputOutputBufferType.__init__(self, "0", datatype, sizetype, sizeformat)
+
+    def getOutputBufferDeclarations(self, name, constmode=False, outmode=False):
+        if constmode:
+            raise RuntimeError, "Cannot use const output buffer"
+        if outmode:
+            out = "*"
+        else:
+            out = ""
+        return ["%s%s *%s__out__" % (self.datatype, out, name)]
+
+    def getargsCheck(self, name):
+        Output("if ((%s__out__ = malloc(%s__in_len__)) == NULL)", name, name)
+        OutLbrace()
+        Output('PyErr_NoMemory();')
+        Output("goto %s__error__;", name)
+        self.label_needed = 1
+        OutRbrace()
+        Output("%s__len__ = %s__in_len__;", name, name)
+
+    def passOutput(self, name):
+        return "%s__in__, %s__out__, (%s)%s__len__" % \
+            (name, name, self.sizetype, name)
+
+    def mkvalueArgs(self, name):
+        return "%s__out__, (int)%s__len__" % (name, name)
+
+    def cleanup(self, name):
+        Output("free(%s__out__);", name)
+        FixedInputOutputBufferType.cleanup(self, name)
+
+
+class VarHeapInputOutputBufferType(HeapInputOutputBufferType):
+
+    """same as base class, but passed as (inbuffer, outbuffer, &size)"""
+
+    def passOutput(self, name):
+        return "%s__in__, %s__out__, &%s__len__" % (name, name, name)
+
+
+class HeapCombinedInputOutputBufferType(HeapInputOutputBufferType):
+
+    """same as base class, but passed as (inoutbuffer, size)"""
+
+    def passOutput(self, name):
+        return "(%s *)memcpy(%s__out__, %s__in__, %s__len__)" % \
+            (self.datatype, name,   name,     name)
+
+
+class VarHeapCombinedInputOutputBufferType(HeapInputOutputBufferType):
+
+    """same as base class, but passed as (inoutbuffer, &size)"""
+
+    def passOutput(self, name):
+        return "(%s *)memcpy(%s__out__, %s__in__, &%s__len__)" % \
+            (self.datatype, name,   name,      name)
+
+
+class HeapOutputBufferType(OutputOnlyMixIn, HeapInputOutputBufferType):
+
+    """Output buffer allocated on the heap -- passed as (buffer, size).
+
+    Instantiate without parameters.
+    Call from Python with buffer size.
+    """
+
+    def getInputBufferDeclarations(self, name, constmode=False):
+        return []
+
+    def getargsFormat(self):
+        return "i"
+
+    def getargsArgs(self, name):
+        return "&%s__in_len__" % name
+
+    def passOutput(self, name):
+        return "%s__out__, %s__len__" % (name, name)
+
+
+class VarHeapOutputBufferType(HeapOutputBufferType):
+
+    """Output buffer allocated on the heap -- passed as (buffer, &size).
+
+    Instantiate without parameters.
+    Call from Python with buffer size.
+    """
+
+    def passOutput(self, name):
+        return "%s__out__, &%s__len__" % (name, name)
+
+
+class VarVarHeapOutputBufferType(VarHeapOutputBufferType):
+
+    """Output buffer allocated on the heap -- passed as (buffer, size, &size).
+
+    Instantiate without parameters.
+    Call from Python with buffer size.
+    """
+
+    def passOutput(self, name):
+        return "%s__out__, %s__len__, &%s__len__" % (name, name, name)
+
+class MallocHeapOutputBufferType(HeapOutputBufferType):
+    """Output buffer allocated by the called function -- passed as (&buffer, &size).
+
+    Instantiate without parameters.
+    Call from Python without parameters.
+    """
+
+    def getargsCheck(self, name):
+        Output("%s__out__ = NULL;", name)
+
+    def getAuxDeclarations(self, name):
+        return []
+
+    def passOutput(self, name):
+        return "&%s__out__, &%s__len__" % (name, name)
+
+    def getargsFormat(self):
+        return ""
+
+    def getargsArgs(self, name):
+        return None
+
+    def mkvalueFormat(self):
+        return "z#"
+
+    def cleanup(self, name):
+        Output("if( %s__out__ ) free(%s__out__);", name, name)

Added: vendor/Python/current/Tools/bgen/bgen/bgenModule.py
===================================================================
--- vendor/Python/current/Tools/bgen/bgen/bgenModule.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/bgen/bgen/bgenModule.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,94 @@
+from bgenOutput import *
+from bgenGeneratorGroup import GeneratorGroup
+
+class Module(GeneratorGroup):
+
+    def __init__(self, name, prefix = None,
+             includestuff = None,
+             finalstuff = None,
+             initstuff = None,
+             variablestuff = None,
+             longname = None):
+        GeneratorGroup.__init__(self, prefix or name)
+        self.name = name
+        if longname:
+            self.longname = longname
+        else:
+            self.longname = name
+        self.includestuff = includestuff
+        self.initstuff = initstuff
+        self.finalstuff = finalstuff
+        self.variablestuff = variablestuff
+        self.typeobjects = []
+
+    def addobject(self, od):
+        self.generators.append(od)
+        self.typeobjects.append(od)
+        od.setmodulename(self.longname)
+
+    def generate(self):
+        OutHeader1("Module " + self.name)
+        Output("#include \"Python.h\"")
+        Output()
+
+        if self.includestuff:
+            Output()
+            Output("%s", self.includestuff)
+
+        self.declareModuleVariables()
+
+        GeneratorGroup.generate(self)
+
+        if self.finalstuff:
+            Output()
+            Output("%s", self.finalstuff)
+
+        Output()
+        Output("void init%s(void)", self.name)
+        OutLbrace()
+        Output("PyObject *m;")
+        Output("PyObject *d;")
+        Output()
+
+        if self.initstuff:
+            Output("%s", self.initstuff)
+            Output()
+
+        Output("m = Py_InitModule(\"%s\", %s_methods);",
+               self.name, self.prefix)
+        Output("d = PyModule_GetDict(m);")
+        self.createModuleVariables()
+        OutRbrace()
+        OutHeader1("End module " + self.name)
+
+    def declareModuleVariables(self):
+        self.errorname = self.prefix + "_Error"
+        Output("static PyObject *%s;", self.errorname)
+
+    def createModuleVariables(self):
+        Output("""%s = %s;""", self.errorname, self.exceptionInitializer())
+        Output("""if (%s == NULL ||""", self.errorname)
+        Output("""    PyDict_SetItemString(d, "Error", %s) != 0)""",
+                                                       self.errorname)
+        IndentLevel()
+        Output("""return;""")
+        DedentLevel()
+        for tp in self.typeobjects:
+            tp.outputTypeObjectInitializer()
+        if self.variablestuff:
+            Output("%s", self.variablestuff)
+            Output()
+
+    def exceptionInitializer(self):
+        return """PyErr_NewException("%s.Error", NULL, NULL)""" % self.name
+
+
+def _test():
+    from bgenGenerator import FunctionGenerator
+    m = Module("spam", "", "#include <stdio.h>")
+    g = FunctionGenerator(None, "bacon")
+    m.add(g)
+    m.generate()
+
+if __name__ == "__main__":
+    _test()

Added: vendor/Python/current/Tools/bgen/bgen/bgenObjectDefinition.py
===================================================================
--- vendor/Python/current/Tools/bgen/bgen/bgenObjectDefinition.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/bgen/bgen/bgenObjectDefinition.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,512 @@
+from bgenOutput import *
+from bgenGeneratorGroup import GeneratorGroup
+
+class ObjectDefinition(GeneratorGroup):
+    "Spit out code that together defines a new Python object type"
+    basechain = "NULL"
+    tp_flags = "Py_TPFLAGS_DEFAULT"
+    basetype = None
+    argref = ""    # set to "*" if arg to <type>_New should be pointer
+    argconst = ""   # set to "const " if arg to <type>_New should be const
+
+    def __init__(self, name, prefix, itselftype):
+        """ObjectDefinition constructor.  May be extended, but do not override.
+
+        - name: the object's official name, e.g. 'SndChannel'.
+        - prefix: the prefix used for the object's functions and data, e.g. 'SndCh'.
+        - itselftype: the C type actually contained in the object, e.g. 'SndChannelPtr'.
+
+        XXX For official Python data types, rules for the 'Py' prefix are a problem.
+        """
+
+        GeneratorGroup.__init__(self, prefix or name)
+        self.name = name
+        self.itselftype = itselftype
+        self.objecttype = name + 'Object'
+        self.typename = name + '_Type'
+        self.static = "static " # set to "" to make <type>_New and <type>_Convert public
+        self.modulename = None
+        if hasattr(self, "assertions"):
+            self.assertions()
+
+    def add(self, g, dupcheck=0):
+        g.setselftype(self.objecttype, self.itselftype)
+        GeneratorGroup.add(self, g, dupcheck)
+
+    def reference(self):
+        # In case we are referenced from a module
+        pass
+
+    def setmodulename(self, name):
+        self.modulename = name
+
+    def generate(self):
+        # XXX This should use long strings and %(varname)s substitution!
+
+        OutHeader2("Object type " + self.name)
+
+        self.outputCheck()
+
+        Output("typedef struct %s {", self.objecttype)
+        IndentLevel()
+        Output("PyObject_HEAD")
+        self.outputStructMembers()
+        DedentLevel()
+        Output("} %s;", self.objecttype)
+
+        self.outputNew()
+
+        self.outputConvert()
+
+        self.outputDealloc()
+
+        GeneratorGroup.generate(self)
+
+        Output()
+        self.outputMethodChain()
+
+        self.outputGetattr()
+
+        self.outputSetattr()
+
+        self.outputCompare()
+
+        self.outputRepr()
+
+        self.outputHash()
+
+        self.outputPEP253Hooks()
+
+        self.outputTypeObject()
+
+        OutHeader2("End object type " + self.name)
+
+    def outputCheck(self):
+        sf = self.static and "static "
+        Output("%sPyTypeObject %s;", sf, self.typename)
+        Output()
+        Output("#define %s_Check(x) ((x)->ob_type == &%s || PyObject_TypeCheck((x), &%s))",
+               self.prefix, self.typename, self.typename)
+        Output()
+
+    def outputMethodChain(self):
+        Output("%sPyMethodChain %s_chain = { %s_methods, %s };",
+                self.static,    self.prefix, self.prefix, self.basechain)
+
+    def outputStructMembers(self):
+        Output("%s ob_itself;", self.itselftype)
+
+    def outputNew(self):
+        Output()
+        Output("%sPyObject *%s_New(%s%s %sitself)", self.static, self.prefix,
+                self.argconst, self.itselftype, self.argref)
+        OutLbrace()
+        Output("%s *it;", self.objecttype)
+        self.outputCheckNewArg()
+        Output("it = PyObject_NEW(%s, &%s);", self.objecttype, self.typename)
+        Output("if (it == NULL) return NULL;")
+        if self.basetype:
+            Output("/* XXXX Should we tp_init or tp_new our basetype? */")
+        self.outputInitStructMembers()
+        Output("return (PyObject *)it;")
+        OutRbrace()
+
+    def outputInitStructMembers(self):
+        Output("it->ob_itself = %sitself;", self.argref)
+
+    def outputCheckNewArg(self):
+        "Override this method to apply additional checks/conversions"
+
+    def outputConvert(self):
+        Output()
+        Output("%sint %s_Convert(PyObject *v, %s *p_itself)", self.static, self.prefix,
+                self.itselftype)
+        OutLbrace()
+        self.outputCheckConvertArg()
+        Output("if (!%s_Check(v))", self.prefix)
+        OutLbrace()
+        Output('PyErr_SetString(PyExc_TypeError, "%s required");', self.name)
+        Output("return 0;")
+        OutRbrace()
+        Output("*p_itself = ((%s *)v)->ob_itself;", self.objecttype)
+        Output("return 1;")
+        OutRbrace()
+
+    def outputCheckConvertArg(self):
+        "Override this method to apply additional conversions"
+
+    def outputDealloc(self):
+        Output()
+        Output("static void %s_dealloc(%s *self)", self.prefix, self.objecttype)
+        OutLbrace()
+        self.outputCleanupStructMembers()
+        if self.basetype:
+            Output("%s.tp_dealloc((PyObject *)self);", self.basetype)
+        elif hasattr(self, 'output_tp_free'):
+            # This is a new-style object with tp_free slot
+            Output("self->ob_type->tp_free((PyObject *)self);")
+        else:
+            Output("PyObject_Free((PyObject *)self);")
+        OutRbrace()
+
+    def outputCleanupStructMembers(self):
+        self.outputFreeIt("self->ob_itself")
+
+    def outputFreeIt(self, name):
+        Output("/* Cleanup of %s goes here */", name)
+
+    def outputGetattr(self):
+        Output()
+        Output("static PyObject *%s_getattr(%s *self, char *name)", self.prefix, self.objecttype)
+        OutLbrace()
+        self.outputGetattrBody()
+        OutRbrace()
+
+    def outputGetattrBody(self):
+        self.outputGetattrHook()
+        Output("return Py_FindMethodInChain(&%s_chain, (PyObject *)self, name);",
+               self.prefix)
+
+    def outputGetattrHook(self):
+        pass
+
+    def outputSetattr(self):
+        Output()
+        Output("#define %s_setattr NULL", self.prefix)
+
+    def outputCompare(self):
+        Output()
+        Output("#define %s_compare NULL", self.prefix)
+
+    def outputRepr(self):
+        Output()
+        Output("#define %s_repr NULL", self.prefix)
+
+    def outputHash(self):
+        Output()
+        Output("#define %s_hash NULL", self.prefix)
+
+    def outputTypeObject(self):
+        sf = self.static and "static "
+        Output()
+        Output("%sPyTypeObject %s = {", sf, self.typename)
+        IndentLevel()
+        Output("PyObject_HEAD_INIT(NULL)")
+        Output("0, /*ob_size*/")
+        if self.modulename:
+            Output("\"%s.%s\", /*tp_name*/", self.modulename, self.name)
+        else:
+            Output("\"%s\", /*tp_name*/", self.name)
+        Output("sizeof(%s), /*tp_basicsize*/", self.objecttype)
+        Output("0, /*tp_itemsize*/")
+        Output("/* methods */")
+        Output("(destructor) %s_dealloc, /*tp_dealloc*/", self.prefix)
+        Output("0, /*tp_print*/")
+        Output("(getattrfunc) %s_getattr, /*tp_getattr*/", self.prefix)
+        Output("(setattrfunc) %s_setattr, /*tp_setattr*/", self.prefix)
+        Output("(cmpfunc) %s_compare, /*tp_compare*/", self.prefix)
+        Output("(reprfunc) %s_repr, /*tp_repr*/", self.prefix)
+        Output("(PyNumberMethods *)0, /* tp_as_number */")
+        Output("(PySequenceMethods *)0, /* tp_as_sequence */")
+        Output("(PyMappingMethods *)0, /* tp_as_mapping */")
+        Output("(hashfunc) %s_hash, /*tp_hash*/", self.prefix)
+        DedentLevel()
+        Output("};")
+
+    def outputTypeObjectInitializer(self):
+        Output("""%s.ob_type = &PyType_Type;""", self.typename)
+        if self.basetype:
+            Output("%s.tp_base = &%s;", self.typename, self.basetype)
+        Output("if (PyType_Ready(&%s) < 0) return;", self.typename)
+        Output("""Py_INCREF(&%s);""", self.typename)
+        Output("PyModule_AddObject(m, \"%s\", (PyObject *)&%s);", self.name, self.typename);
+        self.outputTypeObjectInitializerCompat()
+
+    def outputTypeObjectInitializerCompat(self):
+        Output("/* Backward-compatible name */")
+        Output("""Py_INCREF(&%s);""", self.typename);
+        Output("PyModule_AddObject(m, \"%sType\", (PyObject *)&%s);", self.name, self.typename);
+
+    def outputPEP253Hooks(self):
+        pass
+
+class PEP252Mixin:
+    getsetlist = []
+
+    def assertions(self):
+        # Check that various things aren't overridden. If they are it could
+        # signify a bgen-client that has been partially converted to PEP252.
+        assert self.outputGetattr.im_func == PEP252Mixin.outputGetattr.im_func
+        assert self.outputSetattr.im_func == PEP252Mixin.outputSetattr.im_func
+        assert self.outputGetattrBody == None
+        assert self.outputGetattrHook == None
+        assert self.basechain == "NULL"
+
+    def outputGetattr(self):
+        pass
+
+    outputGetattrBody = None
+
+    outputGetattrHook = None
+
+    def outputSetattr(self):
+        pass
+
+    def outputMethodChain(self):
+        # This is a good place to output the getters and setters
+        self.outputGetSetList()
+
+    def outputHook(self, name):
+        methodname = "outputHook_" + name
+        if hasattr(self, methodname):
+            func = getattr(self, methodname)
+            func()
+        else:
+            Output("0, /*%s*/", name)
+
+    def outputTypeObject(self):
+        sf = self.static and "static "
+        Output()
+        Output("%sPyTypeObject %s = {", sf, self.typename)
+        IndentLevel()
+        Output("PyObject_HEAD_INIT(NULL)")
+        Output("0, /*ob_size*/")
+        if self.modulename:
+            Output("\"%s.%s\", /*tp_name*/", self.modulename, self.name)
+        else:
+            Output("\"%s\", /*tp_name*/", self.name)
+        Output("sizeof(%s), /*tp_basicsize*/", self.objecttype)
+        Output("0, /*tp_itemsize*/")
+
+        Output("/* methods */")
+        Output("(destructor) %s_dealloc, /*tp_dealloc*/", self.prefix)
+        Output("0, /*tp_print*/")
+        Output("(getattrfunc)0, /*tp_getattr*/")
+        Output("(setattrfunc)0, /*tp_setattr*/")
+        Output("(cmpfunc) %s_compare, /*tp_compare*/", self.prefix)
+        Output("(reprfunc) %s_repr, /*tp_repr*/", self.prefix)
+
+        Output("(PyNumberMethods *)0, /* tp_as_number */")
+        Output("(PySequenceMethods *)0, /* tp_as_sequence */")
+        Output("(PyMappingMethods *)0, /* tp_as_mapping */")
+
+        Output("(hashfunc) %s_hash, /*tp_hash*/", self.prefix)
+        self.outputHook("tp_call")
+        Output("0, /*tp_str*/")
+        Output("PyObject_GenericGetAttr, /*tp_getattro*/")
+        Output("PyObject_GenericSetAttr, /*tp_setattro */")
+
+        self.outputHook("tp_as_buffer")
+        Output("%s, /* tp_flags */", self.tp_flags)
+        self.outputHook("tp_doc")
+        self.outputHook("tp_traverse")
+        self.outputHook("tp_clear")
+        self.outputHook("tp_richcompare")
+        self.outputHook("tp_weaklistoffset")
+        self.outputHook("tp_iter")
+        self.outputHook("tp_iternext")
+        Output("%s_methods, /* tp_methods */", self.prefix)
+        self.outputHook("tp_members")
+        Output("%s_getsetlist, /*tp_getset*/", self.prefix)
+        self.outputHook("tp_base")
+        self.outputHook("tp_dict")
+        self.outputHook("tp_descr_get")
+        self.outputHook("tp_descr_set")
+        self.outputHook("tp_dictoffset")
+        self.outputHook("tp_init")
+        self.outputHook("tp_alloc")
+        self.outputHook("tp_new")
+        self.outputHook("tp_free")
+        DedentLevel()
+        Output("};")
+
+    def outputGetSetList(self):
+        if self.getsetlist:
+            for name, get, set, doc in self.getsetlist:
+                if get:
+                    self.outputGetter(name, get)
+                else:
+                    Output("#define %s_get_%s NULL", self.prefix, name)
+                    Output()
+                if set:
+                    self.outputSetter(name, set)
+                else:
+                    Output("#define %s_set_%s NULL", self.prefix, name)
+                    Output()
+
+            Output("static PyGetSetDef %s_getsetlist[] = {", self.prefix)
+            IndentLevel()
+            for name, get, set, doc in self.getsetlist:
+                if doc:
+                    doc = '"' + doc + '"'
+                else:
+                    doc = "NULL"
+                Output("{\"%s\", (getter)%s_get_%s, (setter)%s_set_%s, %s},",
+                    name, self.prefix, name, self.prefix, name, doc)
+            Output("{NULL, NULL, NULL, NULL},")
+            DedentLevel()
+            Output("};")
+        else:
+            Output("#define %s_getsetlist NULL", self.prefix)
+        Output()
+
+    def outputGetter(self, name, code):
+        Output("static PyObject *%s_get_%s(%s *self, void *closure)",
+            self.prefix, name, self.objecttype)
+        OutLbrace()
+        Output(code)
+        OutRbrace()
+        Output()
+
+    def outputSetter(self, name, code):
+        Output("static int %s_set_%s(%s *self, PyObject *v, void *closure)",
+            self.prefix, name, self.objecttype)
+        OutLbrace()
+        Output(code)
+        Output("return 0;")
+        OutRbrace()
+        Output()
+
+class PEP253Mixin(PEP252Mixin):
+    tp_flags = "Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE"
+
+    def outputHook_tp_init(self):
+        Output("%s_tp_init, /* tp_init */", self.prefix)
+
+    def outputHook_tp_alloc(self):
+        Output("%s_tp_alloc, /* tp_alloc */", self.prefix)
+
+    def outputHook_tp_new(self):
+        Output("%s_tp_new, /* tp_new */", self.prefix)
+
+    def outputHook_tp_free(self):
+        Output("%s_tp_free, /* tp_free */", self.prefix)
+
+    def output_tp_initBody_basecall(self):
+        """If a type shares its init call with its base type set output_tp_initBody
+        to output_tp_initBody_basecall"""
+        if self.basetype:
+            Output("if (%s.tp_init)", self.basetype)
+            OutLbrace()
+            Output("if ( (*%s.tp_init)(_self, _args, _kwds) < 0) return -1;", self.basetype)
+            OutRbrace()
+
+    output_tp_initBody = None
+
+    def output_tp_init(self):
+        if self.output_tp_initBody:
+            Output("static int %s_tp_init(PyObject *_self, PyObject *_args, PyObject *_kwds)", self.prefix)
+            OutLbrace()
+            self.output_tp_initBody()
+            OutRbrace()
+        else:
+            Output("#define %s_tp_init 0", self.prefix)
+        Output()
+
+    output_tp_allocBody = None
+
+    def output_tp_alloc(self):
+        if self.output_tp_allocBody:
+            Output("static PyObject *%s_tp_alloc(PyTypeObject *type, int nitems)",
+                self.prefix)
+            OutLbrace()
+            self.output_tp_allocBody()
+            OutRbrace()
+        else:
+            Output("#define %s_tp_alloc PyType_GenericAlloc", self.prefix)
+        Output()
+
+    def output_tp_newBody(self):
+        Output("PyObject *_self;");
+        Output("%s itself;", self.itselftype);
+        Output("char *kw[] = {\"itself\", 0};")
+        Output()
+        Output("if (!PyArg_ParseTupleAndKeywords(_args, _kwds, \"O&\", kw, %s_Convert, &itself)) return NULL;",
+            self.prefix);
+        if self.basetype:
+            Output("if (%s.tp_new)", self.basetype)
+            OutLbrace()
+            Output("if ( (*%s.tp_new)(type, _args, _kwds) == NULL) return NULL;", self.basetype)
+            Dedent()
+            Output("} else {")
+            Indent()
+            Output("if ((_self = type->tp_alloc(type, 0)) == NULL) return NULL;")
+            OutRbrace()
+        else:
+            Output("if ((_self = type->tp_alloc(type, 0)) == NULL) return NULL;")
+        Output("((%s *)_self)->ob_itself = itself;", self.objecttype)
+        Output("return _self;")
+
+    def output_tp_new(self):
+        if self.output_tp_newBody:
+            Output("static PyObject *%s_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)", self.prefix)
+            OutLbrace()
+            self.output_tp_newBody()
+            OutRbrace()
+        else:
+            Output("#define %s_tp_new PyType_GenericNew", self.prefix)
+        Output()
+
+    output_tp_freeBody = None
+
+    def output_tp_free(self):
+        if self.output_tp_freeBody:
+            Output("static void %s_tp_free(PyObject *self)", self.prefix)
+            OutLbrace()
+            self.output_tp_freeBody()
+            OutRbrace()
+        else:
+            Output("#define %s_tp_free PyObject_Del", self.prefix)
+        Output()
+
+    def outputPEP253Hooks(self):
+        self.output_tp_init()
+        self.output_tp_alloc()
+        self.output_tp_new()
+        self.output_tp_free()
+
+class GlobalObjectDefinition(ObjectDefinition):
+    """Like ObjectDefinition but exports some parts.
+
+    XXX Should also somehow generate a .h file for them.
+    """
+
+    def __init__(self, name, prefix = None, itselftype = None):
+        ObjectDefinition.__init__(self, name, prefix or name, itselftype or name)
+        self.static = ""
+
+class ObjectIdentityMixin:
+    """A mixin class for objects that makes the identity of ob_itself
+    govern comparisons and dictionary lookups. Useful if the C object can
+    be returned by library calls and it is difficult (or impossible) to find
+    the corresponding Python objects. With this you can create Python object
+    wrappers on the fly"""
+
+    def outputCompare(self):
+        Output()
+        Output("static int %s_compare(%s *self, %s *other)", self.prefix, self.objecttype,
+                self.objecttype)
+        OutLbrace()
+        Output("unsigned long v, w;")
+        Output()
+        Output("if (!%s_Check((PyObject *)other))", self.prefix)
+        OutLbrace()
+        Output("v=(unsigned long)self;")
+        Output("w=(unsigned long)other;")
+        OutRbrace()
+        Output("else")
+        OutLbrace()
+        Output("v=(unsigned long)self->ob_itself;")
+        Output("w=(unsigned long)other->ob_itself;")
+        OutRbrace()
+        Output("if( v < w ) return -1;")
+        Output("if( v > w ) return 1;")
+        Output("return 0;")
+        OutRbrace()
+
+    def outputHash(self):
+        Output()
+        Output("static long %s_hash(%s *self)", self.prefix, self.objecttype)
+        OutLbrace()
+        Output("return (long)self->ob_itself;")
+        OutRbrace()

Added: vendor/Python/current/Tools/bgen/bgen/bgenOutput.py
===================================================================
--- vendor/Python/current/Tools/bgen/bgen/bgenOutput.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/bgen/bgen/bgenOutput.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,219 @@
+"""Output primitives for the binding generator classes.
+
+This should really be a class, but then everybody would be passing
+the output object to each other.  I chose for the simpler approach
+of a module with a global variable.  Use SetOutputFile() or
+SetOutputFileName() to change the output file.
+"""
+
+_NeedClose = 0
+
+def SetOutputFile(file = None, needclose = 0):
+    """Call this with an open file object to make it the output file.
+
+    Call it without arguments to close the current file (if necessary)
+    and reset it to sys.stdout.
+    If the second argument is true, the new file will be explicitly closed
+    on a subsequence call.
+    """
+    global _File, _NeedClose
+    if _NeedClose:
+        tmp = _File
+        _NeedClose = 0
+        _File = None
+        tmp.close()
+    if file is None:
+        import sys
+        file = sys.stdout
+    _File = file
+    _NeedClose = file and needclose
+
+def SetOutputFileName(filename = None):
+    """Call this with a filename to make it the output file.
+
+    Call it without arguments to close the current file (if necessary)
+    and reset it to sys.stdout.
+    """
+    SetOutputFile()
+    if filename:
+        SetOutputFile(open(filename, 'w'), 1)
+
+SetOutputFile() # Initialize _File
+
+_Level = 0      # Indentation level
+
+def GetLevel():
+    """Return the current indentation level."""
+    return _Level
+
+def SetLevel(level):
+    """Set the current indentation level.
+
+    This does no type or range checking -- use at own risk.
+    """
+    global _Level
+    _Level = level
+
+def Output(format = "", *args):
+    VaOutput(format, args)
+
+def VaOutput(format, args):
+    """Call this with a format string and argument tuple for the format.
+
+    A newline is always added.  Each line in the output is indented
+    to the proper indentation level -- even if the result of the
+    format expansion contains embedded newlines.  Exception: lines
+    beginning with '#' are not indented -- these are assumed to be
+    C preprprocessor lines.
+    """
+    text = format % args
+    if _Level > 0:
+        indent = '\t' * _Level
+        lines = text.split('\n')
+        for i in range(len(lines)):
+            if lines[i] and lines[i][0] != '#':
+                lines[i] = indent + lines[i]
+        text = '\n'.join(lines)
+    _File.write(text + '\n')
+
+def IndentLevel(by = 1):
+    """Increment the indentation level by one.
+
+    When called with an argument, adds it to the indentation level.
+    """
+    global _Level
+    if _Level+by < 0:
+        raise Error, "indentation underflow (internal error)"
+    _Level = _Level + by
+
+def DedentLevel(by = 1):
+    """Decrement the indentation level by one.
+
+    When called with an argument, subtracts it from the indentation level.
+    """
+    IndentLevel(-by)
+
+def OutIndent(format = "", *args):
+    """Combine Output() followed by IndentLevel().
+
+    If no text is given, acts like lone IndentLevel().
+    """
+    if format: VaOutput(format, args)
+    IndentLevel()
+
+def OutDedent(format = "", *args):
+    """Combine Output() followed by DedentLevel().
+
+    If no text is given, acts like loneDedentLevel().
+    """
+    if format: VaOutput(format, args)
+    DedentLevel()
+
+def OutLbrace(format = "", *args):
+    """Like Output, but add a '{' and increase the indentation level.
+
+    If no text is given a lone '{' is output.
+    """
+    if format:
+        format = format + " {"
+    else:
+        format = "{"
+    VaOutput(format, args)
+    IndentLevel()
+
+def OutRbrace():
+    """Decrease the indentation level and output a '}' on a line by itself."""
+    DedentLevel()
+    Output("}")
+
+def OutHeader(text, dash):
+    """Output a header comment using a given dash character."""
+    n = 64 - len(text)
+    Output()
+    Output("/* %s %s %s */", dash * (n/2), text, dash * (n - n/2))
+    Output()
+
+def OutHeader1(text):
+    """Output a level 1 header comment (uses '=' dashes)."""
+    OutHeader(text, "=")
+
+def OutHeader2(text):
+    """Output a level 2 header comment (uses '-' dashes)."""
+    OutHeader(text, "-")
+
+def Out(text):
+    """Output multiline text that's internally indented.
+
+    Pass this a multiline character string.  The whitespace before the
+    first nonblank line of the string will be subtracted from all lines.
+    The lines are then output using Output(), but without interpretation
+    of formatting (if you need formatting you can do it before the call).
+    Recommended use:
+
+        Out('''
+            int main(argc, argv)
+                int argc;
+                char *argv;
+            {
+                printf("Hello, world\\n");
+                exit(0);
+            }
+        ''')
+
+    Caveat: the indentation must be consistent -- if you use three tabs
+    in the first line, (up to) three tabs are removed from following lines,
+    but a line beginning with 24 spaces is not trimmed at all.  Don't use
+    this as a feature.
+    """
+    # (Don't you love using triple quotes *inside* triple quotes? :-)
+
+    lines = text.split('\n')
+    indent = ""
+    for line in lines:
+        if line.strip():
+            for c in line:
+                if not c.isspace():
+                    break
+                indent = indent + c
+            break
+    n = len(indent)
+    for line in lines:
+        if line[:n] == indent:
+            line = line[n:]
+        else:
+            for c in indent:
+                if line[:1] <> c: break
+                line = line[1:]
+        VaOutput("%s", line)
+
+
+def _test():
+    """Test program.  Run when the module is run as a script."""
+    OutHeader1("test bgenOutput")
+    Out("""
+        #include <Python.h>
+        #include <stdio.h>
+
+        main(argc, argv)
+            int argc;
+            char **argv;
+        {
+            int i;
+    """)
+    IndentLevel()
+    Output("""\
+/* Here are a few comment lines.
+   Just to test indenting multiple lines.
+
+   End of the comment lines. */
+""")
+    Output("for (i = 0; i < argc; i++)")
+    OutLbrace()
+    Output('printf("argv[%%d] = %%s\\n", i, argv[i]);')
+    OutRbrace()
+    Output("exit(0)")
+    OutRbrace()
+    OutHeader2("end test")
+
+if __name__ == '__main__':
+    _test()

Added: vendor/Python/current/Tools/bgen/bgen/bgenStackBuffer.py
===================================================================
--- vendor/Python/current/Tools/bgen/bgen/bgenStackBuffer.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/bgen/bgen/bgenStackBuffer.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,62 @@
+"""Buffers allocated on the stack."""
+
+
+from bgenBuffer import FixedInputBufferType, FixedOutputBufferType
+
+
+class StackOutputBufferType(FixedOutputBufferType):
+
+    """Fixed output buffer allocated on the stack -- passed as (buffer, size).
+
+    Instantiate with the buffer size as parameter.
+    """
+
+    def passOutput(self, name):
+        return "%s__out__, %s" % (name, self.size)
+
+
+class VarStackOutputBufferType(StackOutputBufferType):
+
+    """Output buffer allocated on the stack -- passed as (buffer, &size).
+
+    Instantiate with the buffer size as parameter.
+    """
+
+    def getSizeDeclarations(self, name):
+        return []
+
+    def getAuxDeclarations(self, name):
+        return ["int %s__len__ = %s" % (name, self.size)]
+
+    def passOutput(self, name):
+        return "%s__out__, &%s__len__" % (name, name)
+
+    def mkvalueArgs(self, name):
+        return "%s__out__, (int)%s__len__" % (name, name)
+
+
+class VarVarStackOutputBufferType(VarStackOutputBufferType):
+
+    """Output buffer allocated on the stack -- passed as (buffer, size, &size).
+
+    Instantiate with the buffer size as parameter.
+    """
+
+    def passOutput(self, name):
+        return "%s__out__, %s__len__, &%s__len__" % (name, name, name)
+
+
+class ReturnVarStackOutputBufferType(VarStackOutputBufferType):
+
+    """Output buffer allocated on the stack -- passed as (buffer, size) -> size.
+
+    Instantiate with the buffer size as parameter.
+    The function's return value is the size.
+    (XXX Should have a way to suppress returning it separately, too.)
+    """
+
+    def passOutput(self, name):
+        return "%s__out__, %s__len__" % (name, name)
+
+    def mkvalueArgs(self, name):
+        return "%s__out__, (int)_rv" % name

Added: vendor/Python/current/Tools/bgen/bgen/bgenStringBuffer.py
===================================================================
--- vendor/Python/current/Tools/bgen/bgen/bgenStringBuffer.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/bgen/bgen/bgenStringBuffer.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,67 @@
+"""Buffers used to hold null-terminated strings."""
+
+
+from bgenBuffer import FixedOutputBufferType
+from bgenStackBuffer import StackOutputBufferType
+from bgenHeapBuffer import HeapOutputBufferType
+
+
+class StringBufferMixIn:
+
+    """Mix-in class to create various string buffer types.
+
+    Strings are character arrays terminated by a null byte.
+    (For input, this is also covered by stringptr.)
+    For output, there are again three variants:
+    - Fixed: size is a constant given in the documentation; or
+    - Stack: size is passed to the C function but we decide on a size at
+      code generation time so we can still allocate on the heap); or
+    - Heap: size is passed to the C function and we let the Python caller
+      pass a size.
+    (Note that this doesn't cover output parameters in which a string
+    pointer is returned.  These are actually easier (no allocation) but far
+    less common.  I'll write the classes when there is demand.)
+    """
+
+    def getSizeDeclarations(self, name):
+        return []
+
+    def getAuxDeclarations(self, name):
+        return []
+
+    def getargsFormat(self):
+        return "s"
+
+    def getargsArgs(self, name):
+        return "&%s__in__" % name
+
+    def mkvalueFormat(self):
+        return "s"
+
+    def mkvalueArgs(self, name):
+        return "%s__out__" % name
+
+
+class FixedOutputStringType(StringBufferMixIn, FixedOutputBufferType):
+
+    """Null-terminated output string -- passed without size.
+
+    Instantiate with buffer size as parameter.
+    """
+
+
+class StackOutputStringType(StringBufferMixIn, StackOutputBufferType):
+
+    """Null-terminated output string -- passed as (buffer, size).
+
+    Instantiate with buffer size as parameter.
+    """
+
+
+class HeapOutputStringType(StringBufferMixIn, HeapOutputBufferType):
+
+    """Null-terminated output string -- passed as (buffer, size).
+
+    Instantiate without parameters.
+    Call from Python with buffer size.
+    """

Added: vendor/Python/current/Tools/bgen/bgen/bgenType.py
===================================================================
--- vendor/Python/current/Tools/bgen/bgen/bgenType.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/bgen/bgen/bgenType.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,328 @@
+"""Type classes and a modest collection of standard types."""
+
+
+from bgenOutput import *
+
+
+class Type:
+
+    """Define the various things you can do with a C type.
+
+    Most methods are intended to be extended or overridden.
+    """
+
+    def __init__(self, typeName, fmt):
+        """Call with the C name and getargs format for the type.
+
+        Example: int = Type("int", "i")
+        """
+        self.typeName = typeName
+        self.fmt = fmt
+
+    def declare(self, name, reference=False):
+        """Declare a variable of the type with a given name.
+
+        Example: int.declare('spam') prints "int spam;"
+        """
+        for decl in self.getArgDeclarations(name, reference):
+            Output("%s;", decl)
+        for decl in self.getAuxDeclarations(name):
+            Output("%s;", decl)
+
+    def getArgDeclarations(self, name, reference=False, constmode=False, outmode=False):
+        """Return the main part of the declarations for this type: the items
+        that will be passed as arguments in the C/C++ function call."""
+        if reference:
+            ref = "&"
+        else:
+            ref = ""
+        if constmode:
+            const = "const "
+        else:
+            const = ""
+        if outmode:
+            out = "*"
+        else:
+            out = ""
+        return ["%s%s%s%s %s" % (const, self.typeName, ref, out, name)]
+
+    def getAuxDeclarations(self, name):
+        """Return any auxiliary declarations needed for implementing this
+        type, such as helper variables used to hold sizes, etc. These declarations
+        are not part of the C/C++ function call interface."""
+        return []
+
+    def getargs(self):
+        return self.getargsFormat(), self.getargsArgs()
+
+    def getargsFormat(self):
+        """Return the format for this type for use with PyArg_Parse().
+
+        Example: int.getargsFormat() returns the string "i".
+        (getargs is a very old name for PyArg_Parse, hence the name of this method).
+        """
+        return self.fmt
+
+    def getargsArgs(self, name):
+        """Return an argument for use with PyArg_Parse().
+
+        Example: int.getargsArgs("spam") returns the string "&spam".
+        """
+        return "&" + name
+
+    def getargsPreCheck(self, name):
+        """Perform any actions needed before calling getargs().
+
+        This could include declaring temporary variables and such.
+        """
+
+    def getargsCheck(self, name):
+        """Perform any needed post-[new]getargs() checks.
+
+        This is type-dependent; the default does not check for errors.
+        An example would be a check for a maximum string length, or it
+        could do post-getargs() copying or conversion."""
+
+    def passInput(self, name):
+        """Return an argument for passing a variable into a call.
+
+        Example: int.passInput("spam") returns the string "spam".
+        """
+        return name
+
+    def passOutput(self, name):
+        """Return an argument for returning a variable out of a call.
+
+        Example: int.passOutput("spam") returns the string "&spam".
+        """
+        return "&" + name
+
+    def passReference(self, name):
+        """Return an argument for C++ pass-by-reference.
+        Default is to call passInput().
+        """
+        return self.passInput(name)
+
+    def errorCheck(self, name):
+        """Check for an error returned in the variable.
+
+        This is type-dependent; the default does not check for errors.
+        An example would be a check for a NULL pointer.
+        If an error is found, the generated routine should
+        raise an exception and return NULL.
+
+        XXX There should be a way to add error clean-up code.
+        """
+        Output("/* XXX no err check for %s %s */", self.typeName, name)
+
+    def mkvalue(self):
+        return self.mkvalueFormat(), self.mkvalueArgs()
+
+    def mkvalueFormat(self):
+        """Return the format for this type for use with Py_BuildValue().
+
+        This is normally the same as getargsFormat() but it is
+        a separate function to allow future divergence.
+        (mkvalue is a very old name for Py_BuildValue, hence the name of this
+        method).
+        """
+        return self.getargsFormat()
+
+    def mkvalueArgs(self, name):
+        """Return an argument for use with Py_BuildValue().
+
+        Example: int.mkvalueArgs("spam") returns the string "spam".
+        """
+        return name
+
+    def mkvaluePreCheck(self, name):
+        """Perform any actions needed before calling mkvalue().
+
+        This could include declaring temporary variables and such.
+        """
+
+    def cleanup(self, name):
+        """Clean up if necessary.
+
+        This is normally empty; it may deallocate buffers etc.
+        """
+        pass
+
+class ByAddressType(Type):
+    "Simple type that is also passed by address for input"
+
+    def passInput(self, name):
+        return "&%s" % name
+
+
+
+# Sometimes it's useful to define a type that's only usable as input or output parameter
+
+class InputOnlyMixIn:
+
+    "Mix-in class to boobytrap passOutput"
+
+    def passOutput(self, name):
+        raise RuntimeError, "Type '%s' can only be used for input parameters" % self.typeName
+
+class InputOnlyType(InputOnlyMixIn, Type):
+
+    "Same as Type, but only usable for input parameters -- passOutput is boobytrapped"
+
+class OutputOnlyMixIn:
+
+    "Mix-in class to boobytrap passInput"
+
+    def passInput(self, name):
+        raise RuntimeError, "Type '%s' can only be used for output parameters" % self.typeName
+
+class OutputOnlyType(OutputOnlyMixIn, Type):
+
+    "Same as Type, but only usable for output parameters -- passInput is boobytrapped"
+
+
+# A modest collection of standard C types.
+void = None
+char = Type("char", "c")
+short = Type("short", "h")
+unsigned_short = Type("unsigned short", "H")
+int = Type("int", "i")
+long = Type("long", "l")
+unsigned_long = Type("unsigned long", "l")
+float = Type("float", "f")
+double = Type("double", "d")
+
+
+# The most common use of character pointers is a null-terminated string.
+# For input, this is easy.  For output, and for other uses of char *,
+# see the module bgenBuffer.
+stringptr = InputOnlyType("char*", "s")
+unicodestringptr = InputOnlyType("wchar_t *", "u")
+
+
+# Some Python related types.
+objectptr = Type("PyObject*", "O")
+stringobjectptr = Type("PyStringObject*", "S")
+# Etc.
+
+
+class FakeType(InputOnlyType):
+
+    """A type that is not represented in the Python version of the interface.
+
+    Instantiate with a value to pass in the call.
+    """
+
+    def __init__(self, substitute):
+        self.substitute = substitute
+        self.typeName = None    # Don't show this argument in __doc__ string
+
+    def getArgDeclarations(self, name, reference=False, constmode=False, outmode=False):
+        return []
+
+    def getAuxDeclarations(self, name, reference=False):
+        return []
+
+    def getargsFormat(self):
+        return ""
+
+    def getargsArgs(self, name):
+        return None
+
+    def passInput(self, name):
+        return self.substitute
+
+
+class OpaqueType(Type):
+
+    """A type represented by an opaque object type, always passed by address.
+
+    Instantiate with the type name and the names of the new and convert procs.
+    If fewer than three arguments are passed, the second argument is used
+    to derive the new and convert procs by appending _New and _Convert; it
+    defaults to the first argument.
+    """
+
+    def __init__(self, name, arg = None, extra = None):
+        self.typeName = name
+        if extra is None:
+             # Two arguments (name, usetype) or one (name)
+            arg = arg or name
+            self.new = arg + '_New'
+            self.convert = arg + '_Convert'
+        else:
+            # Three arguments (name, new, convert)
+            self.new = arg
+            self.convert = extra
+
+    def getargsFormat(self):
+        return "O&"
+
+    def getargsArgs(self, name):
+        return "%s, &%s" % (self.convert, name)
+
+    def passInput(self, name):
+        return "&%s" % name
+
+    def mkvalueFormat(self):
+        return "O&"
+
+    def mkvalueArgs(self, name):
+        return "%s, &%s" % (self.new, name)
+
+
+class OpaqueByValueType(OpaqueType):
+
+    """A type represented by an opaque object type, on input passed BY VALUE.
+
+    Instantiate with the type name, and optionally an object type name whose
+    New/Convert functions will be used.
+    """
+
+    def passInput(self, name):
+        return name
+
+    def mkvalueArgs(self, name):
+        return "%s, %s" % (self.new, name)
+
+class OpaqueByRefType(OpaqueType):
+    """An opaque object type, passed by reference.
+
+    Instantiate with the type name, and optionally an object type name whose
+    New/Convert functions will be used.
+    """
+
+    def passInput(self, name):
+        return name
+
+#    def passOutput(self, name):
+#        return name
+
+    def mkvalueFormat(self):
+        return "O"
+
+    def mkvalueArgs(self, name):
+        return "%s(%s)" % (self.new, name)
+
+class OpaqueByValueStructType(OpaqueByValueType):
+    """Similar to OpaqueByValueType, but we also pass this to mkvalue by
+    address, in stead of by value.
+    """
+
+    def mkvalueArgs(self, name):
+        return "%s, &%s" % (self.new, name)
+
+
+class OpaqueArrayType(OpaqueByValueType):
+
+    """A type represented by an opaque object type, with ARRAY passing semantics.
+
+    Instantiate with the type name, and optional an object type name whose
+    New/Convert functions will be used.
+    """
+
+    def getargsArgs(self, name):
+        return "%s, %s" % (self.convert, name)
+
+    def passOutput(self, name):
+        return name

Added: vendor/Python/current/Tools/bgen/bgen/bgenVariable.py
===================================================================
--- vendor/Python/current/Tools/bgen/bgen/bgenVariable.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/bgen/bgen/bgenVariable.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,112 @@
+"""Variables, arguments and argument transfer modes etc."""
+
+
+# Values to represent argument transfer modes
+InMode    = 1 # input-only argument
+OutMode   = 2 # output-only argument
+InOutMode = 3 # input-output argument
+ModeMask  = 3 # bits to keep for mode
+
+
+# Special cases for mode/flags argument
+# XXX This is still a mess!
+SelfMode   =  4+InMode  # this is 'self' -- don't declare it
+ReturnMode =  8+OutMode # this is the function return value
+ErrorMode  = 16+OutMode # this is an error status -- turn it into an exception
+RefMode    = 32
+ConstMode  = 64
+
+class Variable:
+
+    """A Variable holds a type, a name, a transfer mode and flags.
+
+    Most of its methods call the correponding type method with the
+    variable name.
+    """
+
+    def __init__(self, type, name = None, flags = InMode):
+        """Call with a type, a name and flags.
+
+        If name is None, it muse be set later.
+        flags defaults to InMode.
+        """
+        self.type = type
+        self.name = name
+        self.flags = flags
+        self.mode = flags & ModeMask
+
+    def declare(self):
+        """Declare the variable if necessary.
+
+        If it is "self", it is not declared.
+        """
+        if self.flags == ReturnMode+RefMode:
+            self.type.declare(self.name, reference=True)
+        elif self.flags != SelfMode:
+            self.type.declare(self.name)
+
+    def getArgDeclarations(self, fullmodes=False):
+        refmode = (self.flags & RefMode)
+        constmode = False
+        outmode = False
+        if fullmodes:
+            constmode = (self.flags & ConstMode)
+            outmode = (self.flags & OutMode)
+        return self.type.getArgDeclarations(self.name,
+                reference=refmode, constmode=constmode, outmode=outmode)
+
+    def getAuxDeclarations(self):
+        return self.type.getAuxDeclarations(self.name)
+
+    def getargsFormat(self):
+        """Call the type's getargsFormatmethod."""
+        return self.type.getargsFormat()
+
+    def getargsArgs(self):
+        """Call the type's getargsArgsmethod."""
+        return self.type.getargsArgs(self.name)
+
+    def getargsCheck(self):
+        return self.type.getargsCheck(self.name)
+
+    def getargsPreCheck(self):
+        return self.type.getargsPreCheck(self.name)
+
+    def passArgument(self):
+        """Return the string required to pass the variable as argument.
+
+        For "in" arguments, return the variable name.
+        For "out" and "in out" arguments,
+        return its name prefixed with "&".
+        """
+        if self.mode == InMode:
+            return self.type.passInput(self.name)
+        if self.mode & RefMode:
+            return self.type.passReference(self.name)
+        if self.mode in (OutMode, InOutMode):
+            return self.type.passOutput(self.name)
+        # XXX Shouldn't get here
+        return "/*mode?*/" + self.type.passInput(self.name)
+
+    def errorCheck(self):
+        """Check for an error if necessary.
+
+        This only generates code if the variable's mode is ErrorMode.
+        """
+        if self.flags == ErrorMode:
+            self.type.errorCheck(self.name)
+
+    def mkvalueFormat (self):
+        """Call the type's mkvalueFormat method."""
+        return self.type.mkvalueFormat()
+
+    def mkvalueArgs(self):
+        """Call the type's mkvalueArgs method."""
+        return self.type.mkvalueArgs(self.name)
+
+    def mkvaluePreCheck(self):
+        return self.type.mkvaluePreCheck(self.name)
+
+    def cleanup(self):
+        """Call the type's cleanup method."""
+        return self.type.cleanup(self.name)

Added: vendor/Python/current/Tools/bgen/bgen/macsupport.py
===================================================================
--- vendor/Python/current/Tools/bgen/bgen/macsupport.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/bgen/bgen/macsupport.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,197 @@
+"""\
+Augment the "bgen" package with definitions that are useful on the Apple Macintosh.
+
+Intended usage is "from macsupport import *" -- this implies all bgen's goodies.
+"""
+
+
+# Import everything from bgen (for ourselves as well as for re-export)
+from bgen import *
+
+
+# Simple types
+Boolean = Type("Boolean", "b")
+SignedByte = Type("SignedByte", "b")
+Size = Type("Size", "l")
+Style = Type("Style", "b")
+StyleParameter = Type("StyleParameter", "h")
+CharParameter = Type("CharParameter", "h")
+TextEncoding = Type("TextEncoding", "l")
+ByteCount = Type("ByteCount", "l")
+Duration = Type("Duration", "l")
+ByteOffset = Type("ByteOffset", "l")
+OptionBits = Type("OptionBits", "l")
+ItemCount = Type("ItemCount", "l")
+PBVersion = Type("PBVersion", "l")
+ScriptCode = Type("ScriptCode", "h")
+LangCode = Type("LangCode", "h")
+RegionCode = Type("RegionCode", "h")
+
+UInt8 = Type("UInt8", "b")
+SInt8 = Type("SInt8", "b")
+UInt16 = Type("UInt16", "H")
+SInt16 = Type("SInt16", "h")
+UInt32 = Type("UInt32", "l")
+SInt32 = Type("SInt32", "l")
+Float32 = Type("Float32", "f")
+
+wide = OpaqueByValueType("wide", "PyMac_Buildwide", "PyMac_Getwide")
+wide_ptr = OpaqueType("wide", "PyMac_Buildwide", "PyMac_Getwide")
+
+# Pascal strings
+ConstStr255Param = OpaqueArrayType("Str255", "PyMac_BuildStr255", "PyMac_GetStr255")
+Str255 = OpaqueArrayType("Str255", "PyMac_BuildStr255", "PyMac_GetStr255")
+StringPtr = OpaqueByValueType("StringPtr", "PyMac_BuildStr255", "PyMac_GetStr255")
+ConstStringPtr = StringPtr
+
+# File System Specifications
+FSSpec_ptr = OpaqueType("FSSpec", "PyMac_BuildFSSpec", "PyMac_GetFSSpec")
+FSSpec = OpaqueByValueStructType("FSSpec", "PyMac_BuildFSSpec", "PyMac_GetFSSpec")
+FSRef_ptr = OpaqueType("FSRef", "PyMac_BuildFSRef", "PyMac_GetFSRef")
+FSRef = OpaqueByValueStructType("FSRef", "PyMac_BuildFSRef", "PyMac_GetFSRef")
+
+# OSType and ResType: 4-byte character strings
+def OSTypeType(typename):
+    return OpaqueByValueType(typename, "PyMac_BuildOSType", "PyMac_GetOSType")
+OSType = OSTypeType("OSType")
+ResType = OSTypeType("ResType")
+FourCharCode = OSTypeType("FourCharCode")
+
+# Version numbers
+NumVersion = OpaqueByValueType("NumVersion", "PyMac_BuildNumVersion", "BUG")
+
+# Handles (always resources in our case)
+Handle = OpaqueByValueType("Handle", "ResObj")
+MenuHandle = OpaqueByValueType("MenuHandle", "MenuObj")
+MenuRef = MenuHandle
+ControlHandle = OpaqueByValueType("ControlHandle", "CtlObj")
+ControlRef = ControlHandle
+
+# Windows and Dialogs
+WindowPtr = OpaqueByValueType("WindowPtr", "WinObj")
+WindowRef = WindowPtr
+DialogPtr = OpaqueByValueType("DialogPtr", "DlgObj")
+DialogRef = DialogPtr
+ExistingWindowPtr = OpaqueByValueType("WindowPtr", "WinObj_WhichWindow", "BUG")
+ExistingDialogPtr = OpaqueByValueType("DialogPtr", "DlgObj_WhichDialog", "BUG")
+
+# NULL pointer passed in as optional storage -- not present in Python version
+NullStorage = FakeType("(void *)0")
+
+# More standard datatypes
+Fixed = OpaqueByValueType("Fixed", "PyMac_BuildFixed", "PyMac_GetFixed")
+
+# Quickdraw data types
+Rect = Rect_ptr = OpaqueType("Rect", "PyMac_BuildRect", "PyMac_GetRect")
+Point = OpaqueByValueType("Point", "PyMac_BuildPoint", "PyMac_GetPoint")
+Point_ptr = OpaqueType("Point", "PyMac_BuildPoint", "PyMac_GetPoint")
+
+# Event records
+EventRecord = OpaqueType("EventRecord", "PyMac_BuildEventRecord", "PyMac_GetEventRecord")
+EventRecord_ptr = EventRecord
+
+# CoreFoundation datatypes
+CFTypeRef = OpaqueByValueType("CFTypeRef", "CFTypeRefObj")
+CFStringRef = OpaqueByValueType("CFStringRef", "CFStringRefObj")
+CFMutableStringRef = OpaqueByValueType("CFMutableStringRef", "CFMutableStringRefObj")
+CFArrayRef = OpaqueByValueType("CFArrayRef", "CFArrayRefObj")
+CFMutableArrayRef = OpaqueByValueType("CFMutableArrayRef", "CFMutableArrayRefObj")
+CFDictionaryRef = OpaqueByValueType("CFDictionaryRef", "CFDictionaryRefObj")
+CFMutableDictionaryRef = OpaqueByValueType("CFMutableDictionaryRef", "CFMutableDictionaryRefObj")
+CFURLRef = OpaqueByValueType("CFURLRef", "CFURLRefObj")
+OptionalCFURLRef = OpaqueByValueType("CFURLRef", "OptionalCFURLRefObj")
+
+# OSErr is special because it is turned into an exception
+# (Could do this with less code using a variant of mkvalue("O&")?)
+class OSErrType(Type):
+    def errorCheck(self, name):
+        Output("if (%s != noErr) return PyMac_Error(%s);", name, name)
+        self.used = 1
+OSErr = OSErrType("OSErr", 'h')
+OSStatus = OSErrType("OSStatus", 'l')
+
+
+# Various buffer types
+
+InBuffer = VarInputBufferType('char', 'long', 'l')      # (buf, len)
+UcharInBuffer  = VarInputBufferType('unsigned char', 'long', 'l')       # (buf, len)
+OptionalInBuffer = OptionalVarInputBufferType('char', 'long', 'l')      # (buf, len)
+
+InOutBuffer = HeapInputOutputBufferType('char', 'long', 'l')    # (inbuf, outbuf, len)
+VarInOutBuffer = VarHeapInputOutputBufferType('char', 'long', 'l') # (inbuf, outbuf, &len)
+
+OutBuffer = HeapOutputBufferType('char', 'long', 'l')       # (buf, len)
+VarOutBuffer = VarHeapOutputBufferType('char', 'long', 'l') # (buf, &len)
+VarVarOutBuffer = VarVarHeapOutputBufferType('char', 'long', 'l') # (buf, len, &len)
+
+# Unicode arguments sometimes have reversed len, buffer (don't understand why Apple did this...)
+class VarUnicodeInputBufferType(VarInputBufferType):
+
+    def getargsFormat(self):
+        return "u#"
+
+class VarUnicodeReverseInputBufferType(ReverseInputBufferMixin, VarUnicodeInputBufferType):
+    pass
+
+UnicodeInBuffer = VarUnicodeInputBufferType('UniChar', 'UniCharCount', 'l')
+UnicodeReverseInBuffer = VarUnicodeReverseInputBufferType('UniChar', 'UniCharCount', 'l')
+UniChar_ptr = InputOnlyType("UniCharPtr", "u")
+
+
+# Predefine various pieces of program text to be passed to Module() later:
+
+# Stuff added immediately after the system include files
+includestuff = """
+#include "pymactoolbox.h"
+
+/* Macro to test whether a weak-loaded CFM function exists */
+#define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL )  {\\
+        PyErr_SetString(PyExc_NotImplementedError, \\
+        "Not available in this shared library/OS version"); \\
+        return NULL; \\
+    }} while(0)
+
+"""
+
+# Stuff added just before the module's init function
+finalstuff = """
+"""
+
+# Stuff added inside the module's init function
+initstuff = """
+"""
+
+
+# Generator classes with a twist -- if the function returns OSErr,
+# its mode is manipulated so that it turns into an exception or disappears
+# (and its name is changed to _err, for documentation purposes).
+# This requires that the OSErr type (defined above) has a non-trivial
+# errorCheck method.
+class OSErrMixIn:
+    "Mix-in class to treat OSErr/OSStatus return values special"
+    def makereturnvar(self):
+        if self.returntype.__class__ == OSErrType:
+            return Variable(self.returntype, "_err", ErrorMode)
+        else:
+            return Variable(self.returntype, "_rv", OutMode)
+
+class OSErrFunctionGenerator(OSErrMixIn, FunctionGenerator): pass
+class OSErrMethodGenerator(OSErrMixIn, MethodGenerator): pass
+
+class WeakLinkMixIn:
+    "Mix-in to test the function actually exists (!= NULL) before calling"
+
+    def precheck(self):
+        Output('#ifndef %s', self.name)
+        Output('PyMac_PRECHECK(%s);', self.name)
+        Output('#endif')
+
+class WeakLinkFunctionGenerator(WeakLinkMixIn, FunctionGenerator): pass
+class WeakLinkMethodGenerator(WeakLinkMixIn, MethodGenerator): pass
+class OSErrWeakLinkFunctionGenerator(OSErrMixIn, WeakLinkMixIn, FunctionGenerator): pass
+class OSErrWeakLinkMethodGenerator(OSErrMixIn, WeakLinkMixIn, MethodGenerator): pass
+
+class MacModule(Module):
+    "Subclass which gets the exception initializer from macglue.c"
+    def exceptionInitializer(self):
+        return "PyMac_GetOSErrException()"

Added: vendor/Python/current/Tools/bgen/bgen/scantools.py
===================================================================
--- vendor/Python/current/Tools/bgen/bgen/scantools.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/bgen/bgen/scantools.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,849 @@
+"""\
+
+Tools for scanning header files in search of function prototypes.
+
+Often, the function prototypes in header files contain enough information
+to automatically generate (or reverse-engineer) interface specifications
+from them.  The conventions used are very vendor specific, but once you've
+figured out what they are they are often a great help, and it sure beats
+manually entering the interface specifications.  (These are needed to generate
+the glue used to access the functions from Python.)
+
+In order to make this class useful, almost every component can be overridden.
+The defaults are (currently) tuned to scanning Apple Macintosh header files,
+although most Mac specific details are contained in header-specific subclasses.
+"""
+
+import re
+import sys
+import os
+import fnmatch
+from types import *
+try:
+    import MacOS
+except ImportError:
+    MacOS = None
+
+try:
+    from bgenlocations import CREATOR, INCLUDEDIR
+except ImportError:
+    CREATOR = None
+    INCLUDEDIR = os.curdir
+
+Error = "scantools.Error"
+
+BEGINHTMLREPORT="""<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+<style type="text/css">
+.unmatched {  }
+.commentstripping { color: grey; text-decoration: line-through }
+.comment { text-decoration: line-through }
+.notcomment { color: black }
+.incomplete { color: maroon }
+.constant { color: green }
+.pyconstant { background-color: yellow }
+.blconstant { background-color: yellow; color: red }
+.declaration { color: blue }
+.pydeclaration { background-color: yellow }
+.type { font-style: italic }
+.name { font-weight: bold }
+.value { font-style: italic }
+.arglist { text-decoration: underline }
+.blacklisted { background-color: yellow; color: red }
+</style>
+<title>Bgen scan report</title>
+</head>
+<body>
+<h1>Bgen scan report</h1>
+<h2>Legend</h2>
+<p>This scan report is intended to help you debug the regular expressions
+used by the bgen scanner. It consists of the original ".h" header file(s)
+marked up to show you what the regular expressions in the bgen parser matched
+for each line. NOTE: comments in the original source files may or may not be
+shown.</p>
+<p>The typographic conventions of this file are as follows:</p>
+<dl>
+<dt>comment stripping</dt>
+<dd><pre><span class="commentstripping"><span class="notcomment">comment stripping is </span><span class="comment">/* marked up */</span><span class="notcomment"> and the line is repeated if needed</span></span></pre>
+<p>If anything here does not appear to happen correctly look at
+<tt>comment1_pat</tt> and <tt>comment2_pat</tt>.</p>
+</dd>
+<dt>constant definitions</dt>
+<dd><pre><span class="constant">#define <span class="name">name</span> <span class="value">value</span></pre>
+<p>Highlights name and value of the constant. Governed by <tt>sym_pat</tt>.</p>
+</dd>
+<dt>function declaration</dt>
+<dd><pre><span class="declaration"><span class="type">char *</span><span class="name">rindex</span><span class="arglist">(<span class="type">const char *</span><span class="name">s</span>, <span class="type">int </span><span class="name">c</span>)</span>;</span></pre>
+<p>Highlights type, name and argument list. <tt>type_pat</tt>,
+<tt>name_pat</tt> and <tt>args_pat</tt> are combined into <tt>whole_pat</tt>, which
+is what is used here.</p></dd>
+</dd>
+<dt>incomplete match for function declaration</dt>
+<dd><pre><span class="incomplete"><span class="type">char *</span>foo;</span></pre>
+<p>The beginning of this looked promising, but it did not match a function declaration.
+In other words, it matched <tt>head_pat</tt> but not <tt>whole_pat</tt>. If the next
+declaration has also been gobbled up you need to look at <tt>end_pat</tt>.</p>
+</dd>
+<dt>unrecognized input</dt>
+<dd><pre><span class="unmatched">#include "type.h"</span></pre>
+<p>If there are function declarations the scanner has missed (i.e. things
+are in this class but you want them to be declarations) you need to adapt
+<tt>head_pat</tt>.
+</dd>
+</dl>
+<h2>Output</h2>
+<pre>
+<span class="unmatched">
+"""
+ENDHTMLREPORT="""</span>
+</pre>
+</body>
+</html>
+"""
+
+class Scanner:
+
+    # Set to 1 in subclass to debug your scanner patterns.
+    debug = 0
+
+    def __init__(self, input = None, output = None, defsoutput = None):
+        self.initsilent()
+        self.initblacklists()
+        self.initrepairinstructions()
+        self.initpaths()
+        self.initfiles()
+        self.initpatterns()
+        self.compilepatterns()
+        self.initosspecifics()
+        self.initusedtypes()
+        if output:
+            self.setoutput(output, defsoutput)
+        if input:
+            self.setinput(input)
+
+    def initusedtypes(self):
+        self.usedtypes = {}
+
+    def typeused(self, type, mode):
+        if not self.usedtypes.has_key(type):
+            self.usedtypes[type] = {}
+        self.usedtypes[type][mode] = None
+
+    def reportusedtypes(self):
+        types = self.usedtypes.keys()
+        types.sort()
+        for type in types:
+            modes = self.usedtypes[type].keys()
+            modes.sort()
+            self.report("%s %s", type, " ".join(modes))
+
+    def gentypetest(self, file):
+        fp = open(file, "w")
+        fp.write("types=[\n")
+        types = self.usedtypes.keys()
+        types.sort()
+        for type in types:
+            fp.write("\t'%s',\n"%type)
+        fp.write("]\n")
+        fp.write("""missing=0
+for t in types:
+    try:
+        tt = eval(t)
+    except NameError:
+        print "** Missing type:", t
+        missing = 1
+if missing: raise "Missing Types"
+""")
+        fp.close()
+
+    def initsilent(self):
+        self.silent = 1
+
+    def error(self, format, *args):
+        if self.silent >= 0:
+            print format%args
+
+    def report(self, format, *args):
+        if not self.silent:
+            print format%args
+
+    def writeinitialdefs(self):
+        pass
+
+    def initblacklists(self):
+        self.blacklistnames = self.makeblacklistnames()
+        self.blacklisttypes = ["unknown", "-"] + self.makeblacklisttypes()
+        self.greydictnames = self.greylist2dict(self.makegreylist())
+
+    def greylist2dict(self, list):
+        rv = {}
+        for define, namelist in list:
+            for name in namelist:
+                rv[name] = define
+        return rv
+
+    def makeblacklistnames(self):
+        return []
+
+    def makeblacklisttypes(self):
+        return []
+
+    def makegreylist(self):
+        return []
+
+    def initrepairinstructions(self):
+        self.repairinstructions = self.makerepairinstructions()
+        self.inherentpointertypes = self.makeinherentpointertypes()
+
+    def makerepairinstructions(self):
+        """Parse the repair file into repair instructions.
+
+        The file format is simple:
+        1) use \ to split a long logical line in multiple physical lines
+        2) everything after the first # on a line is ignored (as comment)
+        3) empty lines are ignored
+        4) remaining lines must have exactly 3 colon-separated fields:
+           functionpattern : argumentspattern : argumentsreplacement
+        5) all patterns use shell style pattern matching
+        6) an empty functionpattern means the same as *
+        7) the other two fields are each comma-separated lists of triples
+        8) a triple is a space-separated list of 1-3 words
+        9) a triple with less than 3 words is padded at the end with "*" words
+        10) when used as a pattern, a triple matches the type, name, and mode
+            of an argument, respectively
+        11) when used as a replacement, the words of a triple specify
+            replacements for the corresponding words of the argument,
+            with "*" as a word by itself meaning leave the original word
+            (no other uses of "*" is allowed)
+        12) the replacement need not have the same number of triples
+            as the pattern
+        """
+        f = self.openrepairfile()
+        if not f: return []
+        print "Reading repair file", repr(f.name), "..."
+        list = []
+        lineno = 0
+        while 1:
+            line = f.readline()
+            if not line: break
+            lineno = lineno + 1
+            startlineno = lineno
+            while line[-2:] == '\\\n':
+                line = line[:-2] + ' ' + f.readline()
+                lineno = lineno + 1
+            i = line.find('#')
+            if i >= 0: line = line[:i]
+            words = [s.strip() for s in line.split(':')]
+            if words == ['']: continue
+            if len(words) <> 3:
+                print "Line", startlineno,
+                print ": bad line (not 3 colon-separated fields)"
+                print repr(line)
+                continue
+            [fpat, pat, rep] = words
+            if not fpat: fpat = "*"
+            if not pat:
+                print "Line", startlineno,
+                print "Empty pattern"
+                print repr(line)
+                continue
+            patparts = [s.strip() for s in pat.split(',')]
+            repparts = [s.strip() for s in rep.split(',')]
+            patterns = []
+            for p in patparts:
+                if not p:
+                    print "Line", startlineno,
+                    print "Empty pattern part"
+                    print repr(line)
+                    continue
+                pattern = p.split()
+                if len(pattern) > 3:
+                    print "Line", startlineno,
+                    print "Pattern part has > 3 words"
+                    print repr(line)
+                    pattern = pattern[:3]
+                else:
+                    while len(pattern) < 3:
+                        pattern.append("*")
+                patterns.append(pattern)
+            replacements = []
+            for p in repparts:
+                if not p:
+                    print "Line", startlineno,
+                    print "Empty replacement part"
+                    print repr(line)
+                    continue
+                replacement = p.split()
+                if len(replacement) > 3:
+                    print "Line", startlineno,
+                    print "Pattern part has > 3 words"
+                    print repr(line)
+                    replacement = replacement[:3]
+                else:
+                    while len(replacement) < 3:
+                        replacement.append("*")
+                replacements.append(replacement)
+            list.append((fpat, patterns, replacements))
+        return list
+
+    def makeinherentpointertypes(self):
+        return []
+
+    def openrepairfile(self, filename = "REPAIR"):
+        try:
+            return open(filename, "rU")
+        except IOError, msg:
+            print repr(filename), ":", msg
+            print "Cannot open repair file -- assume no repair needed"
+            return None
+
+    def initfiles(self):
+        self.specmine = 0
+        self.defsmine = 0
+        self.scanmine = 0
+        self.htmlmine = 0
+        self.specfile = sys.stdout
+        self.defsfile = None
+        self.scanfile = sys.stdin
+        self.htmlfile = None
+        self.lineno = 0
+        self.line = ""
+
+    def initpaths(self):
+        self.includepath = [os.curdir, INCLUDEDIR]
+
+    def initpatterns(self):
+        self.head_pat = r"^EXTERN_API[^_]"
+        self.tail_pat = r"[;={}]"
+        self.type_pat = r"EXTERN_API" + \
+                        r"[ \t\n]*\([ \t\n]*" + \
+                        r"(?P<type>[a-zA-Z0-9_* \t]*[a-zA-Z0-9_*])" + \
+                        r"[ \t\n]*\)[ \t\n]*"
+        self.name_pat = r"(?P<name>[a-zA-Z0-9_]+)[ \t\n]*"
+        self.args_pat = r"\((?P<args>([^\(;=\)]+|\([^\(;=\)]*\))*)\)"
+        self.whole_pat = self.type_pat + self.name_pat + self.args_pat
+        self.sym_pat = r"^[ \t]*(?P<name>[a-zA-Z0-9_]+)[ \t]*=" + \
+                       r"[ \t]*(?P<defn>[-0-9_a-zA-Z'\"\(][^\t\n,;}]*),?"
+        self.asplit_pat = r"^(?P<type>.*[^a-zA-Z0-9_])(?P<name>[a-zA-Z0-9_]+)(?P<array>\[\])?$"
+        self.comment1_pat = r"(?P<rest>.*)//.*"
+        # note that the next pattern only removes comments that are wholly within one line
+        self.comment2_pat = r"(?P<rest1>.*)/\*.*\*/(?P<rest2>.*)"
+
+    def compilepatterns(self):
+        for name in dir(self):
+            if name[-4:] == "_pat":
+                pat = getattr(self, name)
+                prog = re.compile(pat)
+                setattr(self, name[:-4], prog)
+
+    def initosspecifics(self):
+        if MacOS and CREATOR:
+            self.filetype = 'TEXT'
+            self.filecreator = CREATOR
+        else:
+            self.filetype = self.filecreator = None
+
+    def setfiletype(self, filename):
+        if MacOS and (self.filecreator or self.filetype):
+            creator, type = MacOS.GetCreatorAndType(filename)
+            if self.filecreator: creator = self.filecreator
+            if self.filetype: type = self.filetype
+            MacOS.SetCreatorAndType(filename, creator, type)
+
+    def close(self):
+        self.closefiles()
+
+    def closefiles(self):
+        self.closespec()
+        self.closedefs()
+        self.closescan()
+        self.closehtml()
+
+    def closespec(self):
+        tmp = self.specmine and self.specfile
+        self.specfile = None
+        if tmp: tmp.close()
+
+    def closedefs(self):
+        tmp = self.defsmine and self.defsfile
+        self.defsfile = None
+        if tmp: tmp.close()
+
+    def closescan(self):
+        tmp = self.scanmine and self.scanfile
+        self.scanfile = None
+        if tmp: tmp.close()
+
+    def closehtml(self):
+        if self.htmlfile: self.htmlfile.write(ENDHTMLREPORT)
+        tmp = self.htmlmine and self.htmlfile
+        self.htmlfile = None
+        if tmp: tmp.close()
+
+    def setoutput(self, spec, defs = None):
+        self.closespec()
+        self.closedefs()
+        if spec:
+            if type(spec) == StringType:
+                file = self.openoutput(spec)
+                mine = 1
+            else:
+                file = spec
+                mine = 0
+            self.specfile = file
+            self.specmine = mine
+        if defs:
+            if type(defs) == StringType:
+                file = self.openoutput(defs)
+                mine = 1
+            else:
+                file = defs
+                mine = 0
+            self.defsfile = file
+            self.defsmine = mine
+
+    def sethtmloutput(self, htmlfile):
+        self.closehtml()
+        if htmlfile:
+            if type(htmlfile) == StringType:
+                file = self.openoutput(htmlfile)
+                mine = 1
+            else:
+                file = htmlfile
+                mine = 0
+            self.htmlfile = file
+            self.htmlmine = mine
+            self.htmlfile.write(BEGINHTMLREPORT)
+
+    def openoutput(self, filename):
+        try:
+            file = open(filename, 'w')
+        except IOError, arg:
+            raise IOError, (filename, arg)
+        self.setfiletype(filename)
+        return file
+
+    def setinput(self, scan = sys.stdin):
+        if not type(scan) in (TupleType, ListType):
+            scan = [scan]
+        self.allscaninputs = scan
+        self._nextinput()
+
+    def _nextinput(self):
+        if not self.allscaninputs:
+            return 0
+        scan = self.allscaninputs[0]
+        self.allscaninputs = self.allscaninputs[1:]
+        self.closescan()
+        if scan:
+            if type(scan) == StringType:
+                file = self.openinput(scan)
+                mine = 1
+            else:
+                file = scan
+                mine = 0
+            self.scanfile = file
+            self.scanmine = mine
+        self.lineno = 0
+        return 1
+
+    def openinput(self, filename):
+        if not os.path.isabs(filename):
+            for dir in self.includepath:
+                fullname = os.path.join(dir, filename)
+                #self.report("trying full name %r", fullname)
+                try:
+                    return open(fullname, 'rU')
+                except IOError:
+                    pass
+        # If not on the path, or absolute, try default open()
+        try:
+            return open(filename, 'rU')
+        except IOError, arg:
+            raise IOError, (arg, filename)
+
+    def getline(self):
+        if not self.scanfile:
+            raise Error, "input file not set"
+        self.line = self.scanfile.readline()
+        if not self.line:
+            if self._nextinput():
+                return self.getline()
+            raise EOFError
+        self.lineno = self.lineno + 1
+        return self.line
+
+    def scan(self):
+        if not self.scanfile:
+            self.error("No input file has been specified")
+            return
+        inputname = self.scanfile.name
+        self.report("scanfile = %r", inputname)
+        if not self.specfile:
+            self.report("(No interface specifications will be written)")
+        else:
+            self.report("specfile = %r", self.specfile.name)
+            self.specfile.write("# Generated from %r\n\n" % (inputname,))
+        if not self.defsfile:
+            self.report("(No symbol definitions will be written)")
+        else:
+            self.report("defsfile = %r", (self.defsfile.name,))
+            self.defsfile.write("# Generated from %r\n\n" % (os.path.split(inputname)[1],))
+            self.writeinitialdefs()
+        self.alreadydone = []
+        try:
+            while 1:
+                try: line = self.getline()
+                except EOFError: break
+                if self.debug:
+                    self.report("LINE: %r" % (line,))
+                match = self.comment1.match(line)
+                if match:
+                    self.htmlreport(line, klass='commentstripping', ranges=[(
+                        match.start('rest'), match.end('rest'), 'notcomment')])
+                    line = match.group('rest')
+                    if self.debug:
+                        self.report("\tafter comment1: %r" % (line,))
+                match = self.comment2.match(line)
+                while match:
+                    if match:
+                        self.htmlreport(line, klass='commentstripping', ranges=[
+                            (match.start('rest1'), match.end('rest1'), 'notcomment'),
+                            (match.start('rest2'), match.end('rest2'), 'notcomment')])
+                    line = match.group('rest1')+match.group('rest2')
+                    if self.debug:
+                        self.report("\tafter comment2: %r" % (line,))
+                    match = self.comment2.match(line)
+                if self.defsfile:
+                    match = self.sym.match(line)
+                    if match:
+                        if self.debug:
+                            self.report("\tmatches sym.")
+                        self.dosymdef(match, line)
+                        continue
+                match = self.head.match(line)
+                if match:
+                    if self.debug:
+                        self.report("\tmatches head.")
+                    self.dofuncspec()
+                    continue
+                self.htmlreport(line, klass='unmatched')
+        except EOFError:
+            self.error("Uncaught EOF error")
+        self.reportusedtypes()
+
+    def dosymdef(self, match, line):
+        name, defn = match.group('name', 'defn')
+        self.htmlreport(line, klass='constant', ranges=[
+            (match.start('name'), match.end('name'), 'name'),
+            (match.start('defn'), match.end('defn'), 'value')])
+        defn = escape8bit(defn)
+        if self.debug:
+            self.report("\tsym: name=%r, defn=%r" % (name, defn))
+        if not name in self.blacklistnames:
+            oline = "%s = %s\n" % (name, defn)
+            self.defsfile.write(oline)
+            self.htmlreport(oline, klass="pyconstant")
+        else:
+            self.defsfile.write("# %s = %s\n" % (name, defn))
+            self.htmlreport("** no output: name is blacklisted", klass="blconstant")
+        # XXXX No way to handle greylisted names
+
+    def dofuncspec(self):
+        raw = self.line
+        while not self.tail.search(raw):
+            line = self.getline()
+            if self.debug:
+                self.report("* CONTINUATION LINE: %r" % (line,))
+            match = self.comment1.match(line)
+            if match:
+                line = match.group('rest')
+                if self.debug:
+                    self.report("\tafter comment1: %r" % (line,))
+            match = self.comment2.match(line)
+            while match:
+                line = match.group('rest1')+match.group('rest2')
+                if self.debug:
+                    self.report("\tafter comment1: %r" % (line,))
+                match = self.comment2.match(line)
+            raw = raw + line
+        if self.debug:
+            self.report("* WHOLE LINE: %r" % (raw,))
+        self.processrawspec(raw)
+        return raw
+
+    def processrawspec(self, raw):
+        match = self.whole.search(raw)
+        if not match:
+            self.report("Bad raw spec: %r", raw)
+            if self.debug:
+                match = self.type.search(raw)
+                if not match:
+                    self.report("(Type already doesn't match)")
+                    self.htmlreport(raw, klass='incomplete', ranges=[(
+                        match.start('type'), match.end('type'), 'type')])
+                else:
+                    self.report("(but type matched)")
+                    self.htmlreport(raw, klass='incomplete')
+            return
+        type, name, args = match.group('type', 'name', 'args')
+        ranges=[
+                (match.start('type'), match.end('type'), 'type'),
+                (match.start('name'), match.end('name'), 'name'),
+                (match.start('args'), match.end('args'), 'arglist')]
+        self.htmlreport(raw, klass='declaration', ranges=ranges)
+        modifiers = self.getmodifiers(match)
+        type = self.pythonizename(type)
+        name = self.pythonizename(name)
+        if self.checkduplicate(name):
+            self.htmlreport("*** no output generated: duplicate name", klass="blacklisted")
+            return
+        self.report("==> %s %s <==", type, name)
+        if self.blacklisted(type, name):
+            self.htmlreport("*** no output generated: function name or return type blacklisted", klass="blacklisted")
+            self.report("*** %s %s blacklisted", type, name)
+            return
+        returnlist = [(type, name, 'ReturnMode')]
+        returnlist = self.repairarglist(name, returnlist)
+        [(type, name, returnmode)] = returnlist
+        arglist = self.extractarglist(args)
+        arglist = self.repairarglist(name, arglist)
+        if self.unmanageable(type, name, arglist):
+            self.htmlreport("*** no output generated: some argument blacklisted", klass="blacklisted")
+            ##for arg in arglist:
+            ##  self.report("    %r", arg)
+            self.report("*** %s %s unmanageable", type, name)
+            return
+        if modifiers:
+            self.generate(type, name, arglist, modifiers)
+        else:
+            self.generate(type, name, arglist)
+
+    def getmodifiers(self, match):
+        return []
+
+    def checkduplicate(self, name):
+        if name in self.alreadydone:
+            self.report("Name has already been defined: %r", name)
+            return True
+        self.alreadydone.append(name)
+        return False
+
+    def pythonizename(self, name):
+        name = re.sub("\*", " ptr", name)
+        name = name.strip()
+        name = re.sub("[ \t]+", "_", name)
+        return name
+
+    def extractarglist(self, args):
+        args = args.strip()
+        if not args or args == "void":
+            return []
+        parts = [s.strip() for s in args.split(",")]
+        arglist = []
+        for part in parts:
+            arg = self.extractarg(part)
+            arglist.append(arg)
+        return arglist
+
+    def extractarg(self, part):
+        mode = "InMode"
+        part = part.strip()
+        match = self.asplit.match(part)
+        if not match:
+            self.error("Indecipherable argument: %r", part)
+            return ("unknown", part, mode)
+        type, name, array = match.group('type', 'name', 'array')
+        if array:
+            # array matches an optional [] after the argument name
+            type = type + " ptr "
+        type = self.pythonizename(type)
+        return self.modifyarg(type, name, mode)
+
+    def modifyarg(self, type, name, mode):
+        if type[:6] == "const_":
+            type = type[6:]
+        elif type[-4:] == "_ptr":
+            type = type[:-4]
+            mode = "OutMode"
+        elif type in self.inherentpointertypes:
+            mode = "OutMode"
+        if type[-4:] == "_far":
+            type = type[:-4]
+        return type, name, mode
+
+    def repairarglist(self, functionname, arglist):
+        arglist = arglist[:]
+        i = 0
+        while i < len(arglist):
+            for item in self.repairinstructions:
+                if len(item) == 2:
+                    pattern, replacement = item
+                    functionpat = "*"
+                else:
+                    functionpat, pattern, replacement = item
+                if not fnmatch.fnmatchcase(functionname, functionpat):
+                    continue
+                n = len(pattern)
+                if i+n > len(arglist): continue
+                current = arglist[i:i+n]
+                for j in range(n):
+                    if not self.matcharg(pattern[j], current[j]):
+                        break
+                else: # All items of the pattern match
+                    new = self.substituteargs(
+                            pattern, replacement, current)
+                    if new is not None:
+                        arglist[i:i+n] = new
+                        i = i+len(new) # No recursive substitutions
+                        break
+            else: # No patterns match
+                i = i+1
+        return arglist
+
+    def matcharg(self, patarg, arg):
+        return len(filter(None, map(fnmatch.fnmatchcase, arg, patarg))) == 3
+
+    def substituteargs(self, pattern, replacement, old):
+        new = []
+        for k in range(len(replacement)):
+            item = replacement[k]
+            newitem = [item[0], item[1], item[2]]
+            for i in range(3):
+                if item[i] == '*':
+                    newitem[i] = old[k][i]
+                elif item[i][:1] == '$':
+                    index = int(item[i][1:]) - 1
+                    newitem[i] = old[index][i]
+            new.append(tuple(newitem))
+        ##self.report("old: %r", old)
+        ##self.report("new: %r", new)
+        return new
+
+    def generate(self, tp, name, arglist, modifiers=[]):
+
+        self.typeused(tp, 'return')
+        if modifiers:
+            classname, listname = self.destination(tp, name, arglist, modifiers)
+        else:
+            classname, listname = self.destination(tp, name, arglist)
+        if not classname or not listname:
+            self.htmlreport("*** no output generated: self.destination() returned None", klass="blacklisted")
+            return
+        if not self.specfile:
+            self.htmlreport("*** no output generated: no output file specified", klass="blacklisted")
+            return
+        self.specfile.write("f = %s(%s, %r,\n" % (classname, tp, name))
+        for atype, aname, amode in arglist:
+            self.typeused(atype, amode)
+            self.specfile.write("    (%s, %r, %s),\n" %
+                                (atype, aname, amode))
+        if self.greydictnames.has_key(name):
+            self.specfile.write("    condition=%r,\n"%(self.greydictnames[name],))
+        self.generatemodifiers(classname, name, modifiers)
+        self.specfile.write(")\n")
+        self.specfile.write("%s.append(f)\n\n" % listname)
+        if self.htmlfile:
+            oline = "Adding to %s:\n%s(returntype=%s, name=%r" % (listname, classname, tp, name)
+            for atype, aname, amode in arglist:
+                oline += ",\n    (%s, %r, %s)" % (atype, aname, amode)
+            oline += ")\n"
+            self.htmlreport(oline, klass="pydeclaration")
+
+    def destination(self, type, name, arglist):
+        return "FunctionGenerator", "functions"
+
+    def generatemodifiers(self, classname, name, modifiers):
+        pass
+
+    def blacklisted(self, type, name):
+        if type in self.blacklisttypes:
+            ##self.report("return type %s is blacklisted", type)
+            return 1
+        if name in self.blacklistnames:
+            ##self.report("function name %s is blacklisted", name)
+            return 1
+        return 0
+
+    def unmanageable(self, type, name, arglist):
+        for atype, aname, amode in arglist:
+            if atype in self.blacklisttypes:
+                self.report("argument type %s is blacklisted", atype)
+                return 1
+        return 0
+
+    def htmlreport(self, line, klass=None, ranges=None):
+        if not self.htmlfile: return
+        if ranges is None:
+            ranges = []
+        if klass:
+            ranges.insert(0, (0, len(line), klass))
+        oline = ''
+        i = 0
+        for c in line:
+            for b, e, name in ranges:
+                if b == i:
+                    oline += '<span class="%s">' % name
+                if e == i:
+                    oline += '</span>'
+            i += 1
+
+            if c == '<': oline += '&lt;'
+            elif c == '>': oline += '&gt;'
+            else: oline += c
+        for b, e, name in ranges:
+            if b >= i:
+                oline += '<span class="%s">' % name
+            if e >= i:
+                oline += '</span>'
+        if not line or line[-1] != '\n':
+            oline += '\n'
+        self.htmlfile.write(oline)
+
+class Scanner_PreUH3(Scanner):
+    """Scanner for Universal Headers before release 3"""
+    def initpatterns(self):
+        Scanner.initpatterns(self)
+        self.head_pat = "^extern pascal[ \t]+" # XXX Mac specific!
+        self.type_pat = "pascal[ \t\n]+(?P<type>[a-zA-Z0-9_ \t]*[a-zA-Z0-9_])[ \t\n]+"
+        self.whole_pat = self.type_pat + self.name_pat + self.args_pat
+        self.sym_pat = "^[ \t]*(?P<name>[a-zA-Z0-9_]+)[ \t]*=" + \
+                       "[ \t]*(?P<defn>[-0-9'\"][^\t\n,;}]*),?"
+
+class Scanner_OSX(Scanner):
+    """Scanner for modern (post UH3.3) Universal Headers """
+    def initpatterns(self):
+        Scanner.initpatterns(self)
+        self.head_pat = "^EXTERN_API(_C)?"
+        self.type_pat = "EXTERN_API(_C)?" + \
+                        "[ \t\n]*\([ \t\n]*" + \
+                        "(?P<type>[a-zA-Z0-9_* \t]*[a-zA-Z0-9_*])" + \
+                        "[ \t\n]*\)[ \t\n]*"
+        self.whole_pat = self.type_pat + self.name_pat + self.args_pat
+        self.sym_pat = "^[ \t]*(?P<name>[a-zA-Z0-9_]+)[ \t]*=" + \
+                       "[ \t]*(?P<defn>[-0-9_a-zA-Z'\"\(][^\t\n,;}]*),?"
+
+_8bit = re.compile(r"[\200-\377]")
+
+def escape8bit(s):
+    if _8bit.search(s) is not None:
+        out = []
+        for c in s:
+            o = ord(c)
+            if o >= 128:
+                out.append("\\" + hex(o)[1:])
+            else:
+                out.append(c)
+        s = "".join(out)
+    return s
+
+def test():
+    input = "D:Development:THINK C:Mac #includes:Apple #includes:AppleEvents.h"
+    output = "@aespecs.py"
+    defsoutput = "@aedefs.py"
+    s = Scanner(input, output, defsoutput)
+    s.scan()
+
+if __name__ == '__main__':
+    test()

Added: vendor/Python/current/Tools/buildbot/build.bat
===================================================================
--- vendor/Python/current/Tools/buildbot/build.bat	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/buildbot/build.bat	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,5 @@
+ at rem Used by the buildbot "compile" step.
+cmd /c Tools\buildbot\external.bat
+call "%VS71COMNTOOLS%vsvars32.bat"
+cmd /q/c Tools\buildbot\kill_python.bat
+devenv.com /useenv /build Debug PCbuild\pcbuild.sln

Added: vendor/Python/current/Tools/buildbot/clean.bat
===================================================================
--- vendor/Python/current/Tools/buildbot/clean.bat	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/buildbot/clean.bat	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,6 @@
+ at rem Used by the buildbot "clean" step.
+call "%VS71COMNTOOLS%vsvars32.bat"
+cd PCbuild
+ at echo Deleting .pyc/.pyo files ...
+python_d.exe rmpyc.py
+devenv.com /clean Debug pcbuild.sln

Added: vendor/Python/current/Tools/buildbot/external.bat
===================================================================
--- vendor/Python/current/Tools/buildbot/external.bat	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/buildbot/external.bat	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,36 @@
+ at rem Fetches (and builds if necessary) external dependencies
+
+ at rem Assume we start inside the Python source directory
+cd ..
+call "%VS71COMNTOOLS%vsvars32.bat"
+
+ at rem bzip
+if not exist bzip2-1.0.3 svn export http://svn.python.org/projects/external/bzip2-1.0.3
+
+ at rem Sleepycat db
+if not exist db-4.4.20 svn export http://svn.python.org/projects/external/db-4.4.20
+if not exist db-4.4.20\build_win32\debug\libdb44sd.lib (
+   devenv db-4.4.20\build_win32\Berkeley_DB.sln /build Debug /project db_static
+)
+
+ at rem OpenSSL
+if not exist openssl-0.9.8a svn export http://svn.python.org/projects/external/openssl-0.9.8a
+
+ at rem tcltk
+if not exist tcl8.4.12 (
+   if exist tcltk rd /s/q tcltk
+   svn export http://svn.python.org/projects/external/tcl8.4.12
+   svn export http://svn.python.org/projects/external/tk8.4.12
+   cd tcl8.4.12\win
+   nmake -f makefile.vc
+   nmake -f makefile.vc INSTALLDIR=..\..\tcltk install
+   cd ..\..
+   cd tk8.4.12\win
+   nmake -f makefile.vc TCLDIR=..\..\tcl8.4.12
+   nmake -f makefile.vc TCLDIR=..\..\tcl8.4.12 INSTALLDIR=..\..\tcltk install
+   cd ..\..
+)
+
+ at rem sqlite
+if not exist sqlite-source-3.3.4 svn export http://svn.python.org/projects/external/sqlite-source-3.3.4
+if not exist build\PCbuild\sqlite3.dll copy sqlite-source-3.3.4\sqlite3.dll build\PCbuild

Added: vendor/Python/current/Tools/buildbot/kill_python.bat
===================================================================
--- vendor/Python/current/Tools/buildbot/kill_python.bat	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/buildbot/kill_python.bat	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,3 @@
+cd Tools\buildbot
+nmake /C /S /f kill_python.mak
+kill_python.exe

Added: vendor/Python/current/Tools/buildbot/kill_python.c
===================================================================
--- vendor/Python/current/Tools/buildbot/kill_python.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/buildbot/kill_python.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,68 @@
+/* This program looks for processes which have build\PCbuild\python.exe
+   in their path and terminates them. */
+#include <windows.h>
+#include <psapi.h>
+#include <stdio.h>
+
+int main()
+{
+	DWORD pids[1024], cbNeeded;
+	int i, num_processes;
+	if (!EnumProcesses(pids, sizeof(pids), &cbNeeded)) {
+		printf("EnumProcesses failed\n");
+		return 1;
+	}
+	num_processes = cbNeeded/sizeof(pids[0]);
+	for (i = 0; i < num_processes; i++) {
+		HANDLE hProcess;
+		char path[MAX_PATH];
+		HMODULE mods[1024];
+		int k, num_mods;
+		hProcess = OpenProcess(PROCESS_QUERY_INFORMATION 
+					| PROCESS_VM_READ 
+					|  PROCESS_TERMINATE ,
+					FALSE, pids[i]);
+		if (!hProcess)
+			/* process not accessible */
+			continue;
+		if (!EnumProcessModules(hProcess, mods, sizeof(mods), &cbNeeded)) {
+			/* For unknown reasons, this sometimes returns ERROR_PARTIAL_COPY;
+			   this apparently means we are not supposed to read the process. */
+			if (GetLastError() == ERROR_PARTIAL_COPY) {
+				CloseHandle(hProcess);
+				continue;
+			}
+			printf("EnumProcessModules failed: %d\n", GetLastError());
+			return 1;
+		}
+		if (!GetModuleFileNameEx(hProcess, NULL, path, sizeof(path))) {
+			printf("GetProcessImageFileName failed\n");
+			return 1;
+		}
+
+		_strlwr(path);
+		/* printf("%s\n", path); */
+
+		/* Check if we are running a buildbot version of Python.
+
+		   On Windows, this will always be a debug build from the
+		   PCbuild directory.  build\\PCbuild\\python_d.exe
+		   
+		   On Cygwin, the pathname is similar to other Unixes.
+		   Use \\build\\python.exe to ensure we don't match
+		   PCbuild\\python.exe which could be a normal instance
+		   of Python running on vanilla Windows.
+		*/
+		if ((strstr(path, "build\\pcbuild\\python_d.exe") != NULL) ||
+		    (strstr(path, "\\build\\python.exe") != NULL)) {
+			printf("Terminating %s (pid %d)\n", path, pids[i]);
+			if (!TerminateProcess(hProcess, 1)) {
+				printf("Termination failed: %d\n", GetLastError());
+				return 1;
+			}
+			return 0;
+		}
+
+		CloseHandle(hProcess);
+	}
+}

Added: vendor/Python/current/Tools/buildbot/kill_python.mak
===================================================================
--- vendor/Python/current/Tools/buildbot/kill_python.mak	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/buildbot/kill_python.mak	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2 @@
+kill_python.exe:	kill_python.c
+		cl -nologo -o kill_python.exe kill_python.c psapi.lib

Added: vendor/Python/current/Tools/buildbot/test.bat
===================================================================
--- vendor/Python/current/Tools/buildbot/test.bat	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/buildbot/test.bat	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,3 @@
+ at rem Used by the buildbot "test" step.
+cd PCbuild
+call rt.bat -d -q -uall -rw

Added: vendor/Python/current/Tools/compiler/ACKS
===================================================================
--- vendor/Python/current/Tools/compiler/ACKS	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/compiler/ACKS	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,8 @@
+Fred L. Drake, Jr.
+Mark Hammond
+Shane Hathaway
+Neil Schemenauer
+Evan Simpson
+Greg Stein
+Bill Tutt
+Moshe Zadka

Added: vendor/Python/current/Tools/compiler/README
===================================================================
--- vendor/Python/current/Tools/compiler/README	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/compiler/README	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,18 @@
+This directory contains support tools for the Python compiler package,
+which is now part of the standard library.
+
+compile.py	Demo that compiles a Python module into a .pyc file
+		using the pure-Python compiler code.
+
+demo.py		Prints the names of all the methods defined in a module,
+		as a demonstration of walking through the abstract syntax
+		tree produced by the parser.
+
+dumppyc.py	Dumps the contents of a .pyc file, printing 
+		the attributes of the code object followed by a 
+		code disassembly.
+
+regrtest.py	Runs the Python test suite using bytecode generated 
+		by the pure-Python compiler code instead of the
+		builtin compiler.
+

Added: vendor/Python/current/Tools/compiler/ast.txt
===================================================================
--- vendor/Python/current/Tools/compiler/ast.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/compiler/ast.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,104 @@
+# This file describes the nodes of the AST in ast.py.  The module is
+# generated by astgen.py.  
+# The descriptions use the following special notation to describe
+# properties of the children:
+#    *   this child is not a node
+#    !   this child is a sequence that contains nodes in it
+#    &   this child may be set to None
+#  = ... a default value for the node constructor (optional args)
+#
+# If you add node types here, please be sure to update the list of 
+# Node types in Doc/lib/asttable.tex.
+Module: doc*, node
+Stmt: nodes!
+Decorators: nodes!
+Function: decorators&, name*, argnames*, defaults!, flags*, doc*, code
+Lambda: argnames*, defaults!, flags*, code
+Class: name*, bases!, doc*, code
+Pass: 
+Break: 
+Continue: 
+For: assign, list, body, else_&
+While: test, body, else_&
+With: expr, vars&, body
+If: tests!, else_&
+IfExp: test, then, else_
+Exec: expr, locals&, globals&
+From: modname*, names*, level*
+Import: names*
+Raise: expr1&, expr2&, expr3&
+TryFinally: body, final
+TryExcept: body, handlers!, else_&
+Return: value
+Yield: value
+Const: value*
+Print: nodes!, dest&
+Printnl: nodes!, dest&
+Discard: expr
+AugAssign: node, op*, expr
+Assign: nodes!, expr
+AssTuple: nodes!
+AssList: nodes!
+AssName: name*, flags*
+AssAttr: expr, attrname*, flags*
+ListComp: expr, quals!
+ListCompFor: assign, list, ifs!
+ListCompIf: test
+GenExpr: code
+GenExprInner: expr, quals!
+GenExprFor: assign, iter, ifs!
+GenExprIf: test
+List: nodes!
+Dict: items!
+Not: expr
+Compare: expr, ops!
+Name: name*
+Global: names*
+Backquote: expr
+Getattr: expr, attrname*
+CallFunc: node, args!, star_args& = None, dstar_args& = None
+Keyword: name*, expr
+Subscript: expr, flags*, subs!
+Ellipsis: 
+Sliceobj: nodes!
+Slice: expr, flags*, lower&, upper&
+Assert: test, fail&
+Tuple: nodes!
+Or: nodes!
+And: nodes!
+Bitor: nodes!
+Bitxor: nodes!
+Bitand: nodes!
+LeftShift: (left, right)
+RightShift: (left, right)
+Add: (left, right)
+Sub: (left, right)
+Mul: (left, right)
+Div: (left, right)
+Mod: (left, right)
+Power: (left, right)
+FloorDiv: (left, right)
+UnaryAdd: expr
+UnarySub: expr
+Invert: expr
+
+init(Function):
+    self.varargs = self.kwargs = None
+    if flags & CO_VARARGS:
+        self.varargs = 1
+    if flags & CO_VARKEYWORDS:
+        self.kwargs = 1
+
+init(Lambda):
+    self.varargs = self.kwargs = None
+    if flags & CO_VARARGS:
+        self.varargs = 1
+    if flags & CO_VARKEYWORDS:
+        self.kwargs = 1
+
+init(GenExpr):
+    self.argnames = ['[outmost-iterable]']
+    self.varargs = self.kwargs = None
+
+init(GenExprFor):
+    self.is_outmost = False

Added: vendor/Python/current/Tools/compiler/astgen.py
===================================================================
--- vendor/Python/current/Tools/compiler/astgen.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/compiler/astgen.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,289 @@
+"""Generate ast module from specification
+
+This script generates the ast module from a simple specification,
+which makes it easy to accomodate changes in the grammar.  This
+approach would be quite reasonable if the grammar changed often.
+Instead, it is rather complex to generate the appropriate code.  And
+the Node interface has changed more often than the grammar.
+"""
+
+import fileinput
+import getopt
+import re
+import sys
+from StringIO import StringIO
+
+SPEC = "ast.txt"
+COMMA = ", "
+
+def load_boilerplate(file):
+    f = open(file)
+    buf = f.read()
+    f.close()
+    i = buf.find('### ''PROLOGUE')
+    j = buf.find('### ''EPILOGUE')
+    pro = buf[i+12:j].strip()
+    epi = buf[j+12:].strip()
+    return pro, epi
+
+def strip_default(arg):
+    """Return the argname from an 'arg = default' string"""
+    i = arg.find('=')
+    if i == -1:
+        return arg
+    t = arg[:i].strip()
+    return t
+
+P_NODE = 1
+P_OTHER = 2
+P_NESTED = 3
+P_NONE = 4
+
+class NodeInfo:
+    """Each instance describes a specific AST node"""
+    def __init__(self, name, args):
+        self.name = name
+        self.args = args.strip()
+        self.argnames = self.get_argnames()
+        self.argprops = self.get_argprops()
+        self.nargs = len(self.argnames)
+        self.init = []
+
+    def get_argnames(self):
+        if '(' in self.args:
+            i = self.args.find('(')
+            j = self.args.rfind(')')
+            args = self.args[i+1:j]
+        else:
+            args = self.args
+        return [strip_default(arg.strip())
+                for arg in args.split(',') if arg]
+
+    def get_argprops(self):
+        """Each argument can have a property like '*' or '!'
+
+        XXX This method modifies the argnames in place!
+        """
+        d = {}
+        hardest_arg = P_NODE
+        for i in range(len(self.argnames)):
+            arg = self.argnames[i]
+            if arg.endswith('*'):
+                arg = self.argnames[i] = arg[:-1]
+                d[arg] = P_OTHER
+                hardest_arg = max(hardest_arg, P_OTHER)
+            elif arg.endswith('!'):
+                arg = self.argnames[i] = arg[:-1]
+                d[arg] = P_NESTED
+                hardest_arg = max(hardest_arg, P_NESTED)
+            elif arg.endswith('&'):
+                arg = self.argnames[i] = arg[:-1]
+                d[arg] = P_NONE
+                hardest_arg = max(hardest_arg, P_NONE)
+            else:
+                d[arg] = P_NODE
+        self.hardest_arg = hardest_arg
+
+        if hardest_arg > P_NODE:
+            self.args = self.args.replace('*', '')
+            self.args = self.args.replace('!', '')
+            self.args = self.args.replace('&', '')
+
+        return d
+
+    def gen_source(self):
+        buf = StringIO()
+        print >> buf, "class %s(Node):" % self.name
+        self._gen_init(buf)
+        print >> buf
+        self._gen_getChildren(buf)
+        print >> buf
+        self._gen_getChildNodes(buf)
+        print >> buf
+        self._gen_repr(buf)
+        buf.seek(0, 0)
+        return buf.read()
+
+    def _gen_init(self, buf):
+        if self.args:
+            print >> buf, "    def __init__(self, %s, lineno=None):" % self.args
+        else:
+            print >> buf, "    def __init__(self, lineno=None):"
+        if self.argnames:
+            for name in self.argnames:
+                print >> buf, "        self.%s = %s" % (name, name)
+        print >> buf, "        self.lineno = lineno"
+        # Copy the lines in self.init, indented four spaces.  The rstrip()
+        # business is to get rid of the four spaces if line happens to be
+        # empty, so that reindent.py is happy with the output.
+        for line in self.init:
+            print >> buf, ("    " + line).rstrip()
+
+    def _gen_getChildren(self, buf):
+        print >> buf, "    def getChildren(self):"
+        if len(self.argnames) == 0:
+            print >> buf, "        return ()"
+        else:
+            if self.hardest_arg < P_NESTED:
+                clist = COMMA.join(["self.%s" % c
+                                    for c in self.argnames])
+                if self.nargs == 1:
+                    print >> buf, "        return %s," % clist
+                else:
+                    print >> buf, "        return %s" % clist
+            else:
+                if len(self.argnames) == 1:
+                    print >> buf, "        return tuple(flatten(self.%s))" % self.argnames[0]
+                else:
+                    print >> buf, "        children = []"
+                    template = "        children.%s(%sself.%s%s)"
+                    for name in self.argnames:
+                        if self.argprops[name] == P_NESTED:
+                            print >> buf, template % ("extend", "flatten(",
+                                                      name, ")")
+                        else:
+                            print >> buf, template % ("append", "", name, "")
+                    print >> buf, "        return tuple(children)"
+
+    def _gen_getChildNodes(self, buf):
+        print >> buf, "    def getChildNodes(self):"
+        if len(self.argnames) == 0:
+            print >> buf, "        return ()"
+        else:
+            if self.hardest_arg < P_NESTED:
+                clist = ["self.%s" % c
+                         for c in self.argnames
+                         if self.argprops[c] == P_NODE]
+                if len(clist) == 0:
+                    print >> buf, "        return ()"
+                elif len(clist) == 1:
+                    print >> buf, "        return %s," % clist[0]
+                else:
+                    print >> buf, "        return %s" % COMMA.join(clist)
+            else:
+                print >> buf, "        nodelist = []"
+                template = "        nodelist.%s(%sself.%s%s)"
+                for name in self.argnames:
+                    if self.argprops[name] == P_NONE:
+                        tmp = ("        if self.%s is not None:\n"
+                               "            nodelist.append(self.%s)")
+                        print >> buf, tmp % (name, name)
+                    elif self.argprops[name] == P_NESTED:
+                        print >> buf, template % ("extend", "flatten_nodes(",
+                                                  name, ")")
+                    elif self.argprops[name] == P_NODE:
+                        print >> buf, template % ("append", "", name, "")
+                print >> buf, "        return tuple(nodelist)"
+
+    def _gen_repr(self, buf):
+        print >> buf, "    def __repr__(self):"
+        if self.argnames:
+            fmt = COMMA.join(["%s"] * self.nargs)
+            if '(' in self.args:
+                fmt = '(%s)' % fmt
+            vals = ["repr(self.%s)" % name for name in self.argnames]
+            vals = COMMA.join(vals)
+            if self.nargs == 1:
+                vals = vals + ","
+            print >> buf, '        return "%s(%s)" %% (%s)' % \
+                  (self.name, fmt, vals)
+        else:
+            print >> buf, '        return "%s()"' % self.name
+
+rx_init = re.compile('init\((.*)\):')
+
+def parse_spec(file):
+    classes = {}
+    cur = None
+    for line in fileinput.input(file):
+        if line.strip().startswith('#'):
+            continue
+        mo = rx_init.search(line)
+        if mo is None:
+            if cur is None:
+                # a normal entry
+                try:
+                    name, args = line.split(':')
+                except ValueError:
+                    continue
+                classes[name] = NodeInfo(name, args)
+                cur = None
+            else:
+                # some code for the __init__ method
+                cur.init.append(line)
+        else:
+            # some extra code for a Node's __init__ method
+            name = mo.group(1)
+            cur = classes[name]
+    return sorted(classes.values(), key=lambda n: n.name)
+
+def main():
+    prologue, epilogue = load_boilerplate(sys.argv[-1])
+    print prologue
+    print
+    classes = parse_spec(SPEC)
+    for info in classes:
+        print info.gen_source()
+    print epilogue
+
+if __name__ == "__main__":
+    main()
+    sys.exit(0)
+
+### PROLOGUE
+"""Python abstract syntax node definitions
+
+This file is automatically generated by Tools/compiler/astgen.py
+"""
+from consts import CO_VARARGS, CO_VARKEYWORDS
+
+def flatten(seq):
+    l = []
+    for elt in seq:
+        t = type(elt)
+        if t is tuple or t is list:
+            for elt2 in flatten(elt):
+                l.append(elt2)
+        else:
+            l.append(elt)
+    return l
+
+def flatten_nodes(seq):
+    return [n for n in flatten(seq) if isinstance(n, Node)]
+
+nodes = {}
+
+class Node:
+    """Abstract base class for ast nodes."""
+    def getChildren(self):
+        pass # implemented by subclasses
+    def __iter__(self):
+        for n in self.getChildren():
+            yield n
+    def asList(self): # for backwards compatibility
+        return self.getChildren()
+    def getChildNodes(self):
+        pass # implemented by subclasses
+
+class EmptyNode(Node):
+    pass
+
+class Expression(Node):
+    # Expression is an artificial node class to support "eval"
+    nodes["expression"] = "Expression"
+    def __init__(self, node):
+        self.node = node
+
+    def getChildren(self):
+        return self.node,
+
+    def getChildNodes(self):
+        return self.node,
+
+    def __repr__(self):
+        return "Expression(%s)" % (repr(self.node))
+
+### EPILOGUE
+for name, obj in globals().items():
+    if isinstance(obj, type) and issubclass(obj, Node):
+        nodes[name.lower()] = obj

Added: vendor/Python/current/Tools/compiler/compile.py
===================================================================
--- vendor/Python/current/Tools/compiler/compile.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/compiler/compile.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,51 @@
+import sys
+import getopt
+
+from compiler import compileFile, visitor
+
+import profile
+
+def main():
+    VERBOSE = 0
+    DISPLAY = 0
+    PROFILE = 0
+    CONTINUE = 0
+    opts, args = getopt.getopt(sys.argv[1:], 'vqdcp')
+    for k, v in opts:
+        if k == '-v':
+            VERBOSE = 1
+            visitor.ASTVisitor.VERBOSE = visitor.ASTVisitor.VERBOSE + 1
+        if k == '-q':
+            if sys.platform[:3]=="win":
+                f = open('nul', 'wb') # /dev/null fails on Windows...
+            else:
+                f = open('/dev/null', 'wb')
+            sys.stdout = f
+        if k == '-d':
+            DISPLAY = 1
+        if k == '-c':
+            CONTINUE = 1
+        if k == '-p':
+            PROFILE = 1
+    if not args:
+        print "no files to compile"
+    else:
+        for filename in args:
+            if VERBOSE:
+                print filename
+            try:
+                if PROFILE:
+                    profile.run('compileFile(%r, %r)' % (filename, DISPLAY),
+                                filename + ".prof")
+                else:
+                    compileFile(filename, DISPLAY)
+
+            except SyntaxError, err:
+                print err
+                if err.lineno is not None:
+                    print err.lineno
+                if not CONTINUE:
+                    sys.exit(-1)
+
+if __name__ == "__main__":
+    main()

Added: vendor/Python/current/Tools/compiler/demo.py
===================================================================
--- vendor/Python/current/Tools/compiler/demo.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/compiler/demo.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,38 @@
+#! /usr/bin/env python
+
+"""Print names of all methods defined in module
+
+This script demonstrates use of the visitor interface of the compiler
+package.
+"""
+
+import compiler
+
+class MethodFinder:
+    """Print the names of all the methods
+
+    Each visit method takes two arguments, the node and its current
+    scope.  The scope is the name of the current class or None.
+    """
+
+    def visitClass(self, node, scope=None):
+        self.visit(node.code, node.name)
+
+    def visitFunction(self, node, scope=None):
+        if scope is not None:
+            print "%s.%s" % (scope, node.name)
+        self.visit(node.code, None)
+
+def main(files):
+    mf = MethodFinder()
+    for file in files:
+        f = open(file)
+        buf = f.read()
+        f.close()
+        ast = compiler.parse(buf)
+        compiler.walk(ast, mf)
+
+if __name__ == "__main__":
+    import sys
+
+    main(sys.argv[1:])


Property changes on: vendor/Python/current/Tools/compiler/demo.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/compiler/dumppyc.py
===================================================================
--- vendor/Python/current/Tools/compiler/dumppyc.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/compiler/dumppyc.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,47 @@
+#! /usr/bin/env python
+
+import marshal
+import os
+import dis
+import types
+
+def dump(obj):
+    print obj
+    for attr in dir(obj):
+        if attr.startswith('co_'):
+            val = getattr(obj, attr)
+            print "\t", attr, repr(val)
+
+def loadCode(path):
+    f = open(path)
+    f.read(8)
+    co = marshal.load(f)
+    f.close()
+    return co
+
+def walk(co, match=None):
+    if match is None or co.co_name == match:
+        dump(co)
+        print
+        dis.dis(co)
+    for obj in co.co_consts:
+        if type(obj) == types.CodeType:
+            walk(obj, match)
+
+def load(filename, codename=None):
+    co = loadCode(filename)
+    walk(co, codename)
+
+if __name__ == "__main__":
+    import sys
+    if len(sys.argv) == 3:
+        filename, codename = sys.argv[1:]
+    else:
+        filename = sys.argv[1]
+        codename = None
+    if filename.endswith('.py'):
+        buf = open(filename).read()
+        co = compile(buf, filename, "exec")
+        walk(co)
+    else:
+        load(filename, codename)


Property changes on: vendor/Python/current/Tools/compiler/dumppyc.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/compiler/regrtest.py
===================================================================
--- vendor/Python/current/Tools/compiler/regrtest.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/compiler/regrtest.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,78 @@
+"""Run the Python regression test using the compiler
+
+This test runs the standard Python test suite using bytecode generated
+by this compiler instead of by the builtin compiler.
+
+The regression test is run with the interpreter in verbose mode so
+that import problems can be observed easily.
+"""
+
+from compiler import compileFile
+
+import os
+import sys
+import test
+import tempfile
+
+def copy_test_suite():
+    dest = tempfile.mkdtemp()
+    os.system("cp -r %s/* %s" % (test.__path__[0], dest))
+    print "Creating copy of test suite in", dest
+    return dest
+
+def copy_library():
+    dest = tempfile.mkdtemp()
+    libdir = os.path.split(test.__path__[0])[0]
+    print "Found standard library in", libdir
+    print "Creating copy of standard library in", dest
+    os.system("cp -r %s/* %s" % (libdir, dest))
+    return dest
+
+def compile_files(dir):
+    print "Compiling", dir, "\n\t",
+    line_len = 10
+    for file in os.listdir(dir):
+        base, ext = os.path.splitext(file)
+        if ext == '.py':
+            source = os.path.join(dir, file)
+            line_len = line_len + len(file) + 1
+            if line_len > 75:
+                print "\n\t",
+                line_len = len(source) + 9
+            print file,
+            try:
+                compileFile(source)
+            except SyntaxError, err:
+                print err
+                continue
+            # make sure the .pyc file is not over-written
+            os.chmod(source + "c", 444)
+        elif file == 'CVS':
+            pass
+        else:
+            path = os.path.join(dir, file)
+            if os.path.isdir(path):
+                print
+                print
+                compile_files(path)
+                print "\t",
+                line_len = 10
+    print
+
+def run_regrtest(lib_dir):
+    test_dir = os.path.join(lib_dir, "test")
+    os.chdir(test_dir)
+    os.system("PYTHONPATH=%s %s -v regrtest.py" % (lib_dir, sys.executable))
+
+def cleanup(dir):
+    os.system("rm -rf %s" % dir)
+
+def main():
+    lib_dir = copy_library()
+    compile_files(lib_dir)
+    run_regrtest(lib_dir)
+    raw_input("Cleanup?")
+    cleanup(lib_dir)
+
+if __name__ == "__main__":
+    main()

Added: vendor/Python/current/Tools/compiler/stacktest.py
===================================================================
--- vendor/Python/current/Tools/compiler/stacktest.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/compiler/stacktest.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,43 @@
+import compiler
+import dis
+import types
+
+def extract_code_objects(co):
+    l = [co]
+    for const in co.co_consts:
+        if type(const) == types.CodeType:
+            l.append(const)
+    return l
+
+def compare(a, b):
+    if not (a.co_name == "?" or a.co_name.startswith('<lambda')):
+        assert a.co_name == b.co_name, (a, b)
+    if a.co_stacksize != b.co_stacksize:
+        print "stack mismatch %s: %d vs. %d" % (a.co_name,
+                                                a.co_stacksize,
+                                                b.co_stacksize)
+        if a.co_stacksize > b.co_stacksize:
+            print "good code"
+            dis.dis(a)
+            print "bad code"
+            dis.dis(b)
+            assert 0
+
+def main(files):
+    for file in files:
+        print file
+        buf = open(file).read()
+        try:
+            co1 = compile(buf, file, "exec")
+        except SyntaxError:
+            print "skipped"
+            continue
+        co2 = compiler.compile(buf, file, "exec")
+        co1l = extract_code_objects(co1)
+        co2l = extract_code_objects(co2)
+        for a, b in zip(co1l, co2l):
+            compare(a, b)
+
+if __name__ == "__main__":
+    import sys
+    main(sys.argv[1:])

Added: vendor/Python/current/Tools/faqwiz/README
===================================================================
--- vendor/Python/current/Tools/faqwiz/README	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/faqwiz/README	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,114 @@
+FAQ Wizard
+----------
+
+Author: Guido van Rossum <guido at python.org>
+Version: 1.0
+Date:  6 April 1998
+
+
+This is a CGI program that maintains a user-editable FAQ.  It uses RCS
+to keep track of changes to individual FAQ entries.  It is fully
+configurable; everything you might want to change when using this
+program to maintain some other FAQ than the Python FAQ is contained in
+the configuration module, faqconf.py.
+
+Note that the bulk of the code is not an executable script; it's an
+importable module.  The actual script in cgi-bin is minimal.
+
+Files:
+
+faqw.py		executable script to be edited and installed in cgi-bin
+faqwiz.py	main module, lives in same directory as FAQ entry files
+faqconf.py	main configuration module
+faqcust.py	additional local customization module (optional)
+move-faqwiz.sh  Script to move faqwiz entries.
+
+
+What's New?
+-----------
+
+Version 1.0 corrects some minor bugs and uses tab-agnostic
+indentation; it is otherwise unchanged from version 0.9.0.
+
+Version 0.9.0 uses the re module (Perl style regular expressions) for
+all its regular expression needs, instead of the regex and regsub
+modules (Emacs style).  This affects the syntax for regular
+expressions entered by the user as search strings (with "regular
+expression" checked), hence the version number jump.
+
+
+Setup Information
+-----------------
+
+This assumes you are familiar with Python, with your http server, and
+with running CGI scripts under your http server.  You need Python 1.5
+or better.
+
+Select a place where the Python modules that constitute the FAQ wizard
+will live (the directory where you unpacked it is an obvious choice).
+This will be called the SRCDIR.  This directory should not be writable
+by other users of your system (since they would be able to execute
+arbitrary code by invoking the FAQ wizard's CGI script).
+
+Create a dedicated working directory, preferably one that's not
+directly reachable from your http server.  This will be called the
+FAQDIR.  Create a subdirectory named RCS.  Make both the working
+directory and the RCS subdirectory wrld-writable.  (This is essential,
+since the FAQ wizard runs as use nobody, and needs to create
+additional files here!)
+
+Edit faqconf.py to reflect your setup.  You only need to edit the top
+part, up till the line of all dashes.  The comments should guide you
+in your edits.  (Actually, you can also choose to add your changes to
+faqcust.py and leave faqconf.py alone.  This is essential if you are
+maintaining multiple FAQs; see below.)
+
+Don't forget to edit the SECTION_TITLES variables to reflect the set
+of section titles for your FAQ!
+
+Next, edit faqw.py to reflect the pathname of your Python interpreter
+and the values for SRCDIR and FAQDIR that you just chose.  Then
+install faqw.py in your cgi-bin directory.  Make sure that it is
+world-executable.  You should now be able to connect to the FAQ wizard
+by entering the following URL in your web client (subsituting the
+appropriate host and port for "your.web.server", and perhaps
+specifying a different directory for "cgi-bin" if local conventions so
+dictate):
+
+	http://your.web.server/cgi-bin/faqw.py
+
+If you are unable to get this working, check your server's error_log
+file.  The documentation for Python's cgi module in the Python Library
+Reference Manual gives plentyu additional information about installing
+and debugging CGI scripts, including setup debugging.  This
+documentation is repeated in the doc string in the cgi module; try
+``import cgi; print cgi.__doc__''.
+
+Assuming this works, you should now be able to add the first entry to
+your FAQ using the FAQ wizard interface.  This creates a file
+faq01.001.htp in your working directory and an RCS revision history
+file faq01.001.htp,v in the RCS subdirectory.  You can now exercise
+the other FAQ wizard features (search, index, whole FAQ, what's new,
+roulette, and so on).
+
+
+Maintaining Multiple FAQs
+-------------------------
+
+If you have multiple FAQs, you need a separate FAQDIR per FAQ, and a
+different customization file per FAQ.  The easiest thing to do would
+be to have the faqcust.py for each FAQ live in the FAQDIR for that
+FAQ, but that creates some security concerns, since the FAQDIR must be
+world writable: *if* someone who breaks into your system (or a
+legitimate user) manages to edit the faqcust.py file they can get
+arbitrary code to execute through the FAQ wizard.  Therefore, you will
+need a more complex setup.
+
+The best way is probably to have a directory that is only writable by
+you for each FAQ, where you place the copy of faqcust.py for that FAQ,
+and have a world-writable subdirectory DATA for the data.  You then
+set FAQDIR to point to the DATA directory and change the faqw.py
+bootstrap script to add FAQDIR/.. to sys.path (in front of SRCDIR, so
+the dummy faqcust.py from SRCDIR is ignored).
+
+--Guido van Rossum (home page: http://www.python.org/~guido/)

Added: vendor/Python/current/Tools/faqwiz/faqconf.py
===================================================================
--- vendor/Python/current/Tools/faqwiz/faqconf.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/faqwiz/faqconf.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,577 @@
+"""FAQ Wizard customization module.
+
+Edit this file to customize the FAQ Wizard.  For normal purposes, you
+should only have to change the FAQ section titles and the small group
+of parameters below it.
+
+"""
+
+# Titles of FAQ sections
+
+SECTION_TITLES = {
+    # SectionNumber : SectionTitle; need at least one entry
+    1: "General information and availability",
+}
+
+# Parameters you definitely want to change
+
+SHORTNAME = "Generic"                   # FAQ name with "FAQ" omitted
+PASSWORD = ""                           # Password for editing
+OWNERNAME = "FAQ owner"                 # Name for feedback
+OWNEREMAIL = "nobody at anywhere.org"      # Email for feedback
+HOMEURL = "http://www.python.org"       # Related home page
+HOMENAME = "Python home"                # Name of related home page
+RCSBINDIR = "/usr/local/bin/"           # Directory containing RCS commands
+                                        # (must end in a slash)
+
+# Parameters you can normally leave alone
+
+MAXHITS = 10                            # Max #hits to be shown directly
+COOKIE_LIFETIME = 28*24*3600            # Cookie expiration in seconds
+                                        # (28*24*3600 = 28 days = 4 weeks)
+PROCESS_PREFORMAT = 1                   # toggle whether preformatted text
+                                        # will replace urls and emails with
+                                        # HTML links
+
+# Markers appended to title to indicate recently change
+# (may contain HTML, e.g. <IMG>); and corresponding
+
+MARK_VERY_RECENT = " **"                # Changed very recently
+MARK_RECENT = " *"                      # Changed recently
+DT_VERY_RECENT = 24*3600                # 24 hours
+DT_RECENT = 7*24*3600                   # 7 days
+
+EXPLAIN_MARKS = """
+<P>(Entries marked with ** were changed within the last 24 hours;
+entries marked with * were changed within the last 7 days.)
+<P>
+"""
+
+# Version -- don't change unless you edit faqwiz.py
+
+WIZVERSION = "1.0.4"                    # FAQ Wizard version
+
+import os, sys
+if os.name in ['nt',]:
+    # On NT we'll probably be running python from a batch file,
+    # so sys.argv[0] is not helpful
+    FAQCGI = 'faq.bat'                  # Relative URL of the FAQ cgi script
+    # LOGNAME is not typically set on NT
+    os.environ[ 'LOGNAME' ] = "FAQWizard"
+else:
+    # This parameter is normally overwritten with a dynamic value
+    FAQCGI = 'faqw.py'                  # Relative URL of the FAQ cgi script
+    FAQCGI = os.path.basename(sys.argv[0]) or FAQCGI
+del os, sys
+
+# Perl (re module) style regular expression to recognize FAQ entry
+# files: group(1) should be the section number, group(2) should be the
+# question number.  Both should be fixed width so simple-minded
+# sorting yields the right order.
+
+OKFILENAME = r"^faq(\d\d)\.(\d\d\d)\.htp$"
+
+# Format to construct a FAQ entry file name
+
+NEWFILENAME = "faq%02d.%03d.htp"
+
+# Load local customizations on top of the previous parameters
+
+try:
+    from faqcust import *
+except ImportError:
+    pass
+
+# Calculated parameter names
+
+COOKIE_NAME = SHORTNAME + "-FAQ-Wizard" # Name used for Netscape cookie
+FAQNAME = SHORTNAME + " FAQ"            # Name of the FAQ
+
+# ----------------------------------------------------------------------
+
+# Anything below this point normally needn't be changed; you would
+# change this if you were to create e.g. a French translation or if
+# you just aren't happy with the text generated by the FAQ Wizard.
+
+# Most strings here are subject to substitution (string%dictionary)
+
+# RCS commands
+
+import os
+if os.name in ['nt', ]:
+    SH_RLOG = RCSBINDIR + "rlog %(file)s < NUL"
+    SH_RLOG_H = RCSBINDIR + "rlog -h %(file)s  < NUL"
+    SH_RDIFF = RCSBINDIR + "rcsdiff -r%(prev)s -r%(rev)s %(file)s < NUL"
+    SH_REVISION = RCSBINDIR + "co -p%(rev)s %(file)s < NUL"
+    ### Have to use co -l, or the file is not marked rw on NT
+    SH_LOCK = RCSBINDIR + "co -l %(file)s < NUL"
+    SH_CHECKIN =  RCSBINDIR + "ci -u %(file)s < %(tfn)s"
+else:
+    SH_RLOG = RCSBINDIR + "rlog %(file)s </dev/null 2>&1"
+    SH_RLOG_H = RCSBINDIR + "rlog -h %(file)s </dev/null 2>&1"
+    SH_RDIFF = RCSBINDIR + "rcsdiff -r%(prev)s -r%(rev)s %(file)s </dev/null 2>&1"
+    SH_REVISION = RCSBINDIR + "co -p%(rev)s %(file)s </dev/null 2>&1"
+    SH_LOCK = RCSBINDIR + "rcs -l %(file)s </dev/null 2>&1"
+    SH_CHECKIN =  RCSBINDIR + "ci -u %(file)s <%(tfn)s 2>&1"
+del os
+
+# Titles for various output pages (not subject to substitution)
+
+T_HOME = FAQNAME + " Wizard " + WIZVERSION
+T_ERROR = "Sorry, an error occurred"
+T_ROULETTE = FAQNAME + " Roulette"
+T_ALL = "The Whole " + FAQNAME
+T_INDEX = FAQNAME + " Index"
+T_SEARCH = FAQNAME + " Search Results"
+T_RECENT = "What's New in the " + FAQNAME
+T_SHOW = FAQNAME + " Entry"
+T_LOG = "RCS log for %s entry" % FAQNAME
+T_REVISION = "RCS revision for %s entry" % FAQNAME
+T_DIFF = "RCS diff for %s entry" % FAQNAME
+T_ADD = "Add an entry to the " + FAQNAME
+T_DELETE = "Deleting an entry from the " + FAQNAME
+T_EDIT = FAQNAME + " Edit Wizard"
+T_REVIEW = T_EDIT + " - Review Changes"
+T_COMMITTED = T_EDIT + " - Changes Committed"
+T_COMMITFAILED = T_EDIT + " - Commit Failed"
+T_CANTCOMMIT = T_EDIT + " - Commit Rejected"
+T_HELP = T_EDIT + " - Help"
+
+# Generic prologue and epilogue
+
+PROLOGUE = '''
+<HTML>
+<HEAD>
+<TITLE>%(title)s</TITLE>
+</HEAD>
+
+<BODY
+      BGCOLOR="#FFFFFF"
+      TEXT="#000000"
+      LINK="#AA0000"
+      VLINK="#906A6A">
+<H1>%(title)s</H1>
+'''
+
+EPILOGUE = '''
+<HR>
+<A HREF="%(HOMEURL)s">%(HOMENAME)s</A> /
+<A HREF="%(FAQCGI)s?req=home">%(FAQNAME)s Wizard %(WIZVERSION)s</A> /
+Feedback to <A HREF="mailto:%(OWNEREMAIL)s">%(OWNERNAME)s</A>
+
+</BODY>
+</HTML>
+'''
+
+# Home page
+
+HOME = """
+<H2>Search the %(FAQNAME)s:</H2>
+
+<BLOCKQUOTE>
+
+<FORM ACTION="%(FAQCGI)s">
+    <INPUT TYPE=text NAME=query>
+    <INPUT TYPE=submit VALUE="Search"><BR>
+    <INPUT TYPE=radio NAME=querytype VALUE=simple CHECKED>
+        Simple string
+        /
+    <INPUT TYPE=radio NAME=querytype VALUE=regex>
+        Regular expression
+        /<BR>
+    <INPUT TYPE=radio NAME=querytype VALUE=anykeywords>
+        Keywords (any)
+        /
+    <INPUT TYPE=radio NAME=querytype VALUE=allkeywords>
+        Keywords (all)
+        <BR>
+    <INPUT TYPE=radio NAME=casefold VALUE=yes CHECKED>
+        Fold case
+        /
+    <INPUT TYPE=radio NAME=casefold VALUE=no>
+        Case sensitive
+        <BR>
+    <INPUT TYPE=hidden NAME=req VALUE=search>
+</FORM>
+
+</BLOCKQUOTE>
+
+<HR>
+
+<H2>Other forms of %(FAQNAME)s access:</H2>
+
+<UL>
+<LI><A HREF="%(FAQCGI)s?req=index">FAQ index</A>
+<LI><A HREF="%(FAQCGI)s?req=all">The whole FAQ</A>
+<LI><A HREF="%(FAQCGI)s?req=recent">What's new in the FAQ?</A>
+<LI><A HREF="%(FAQCGI)s?req=roulette">FAQ roulette</A>
+<LI><A HREF="%(FAQCGI)s?req=add">Add a FAQ entry</A>
+<LI><A HREF="%(FAQCGI)s?req=delete">Delete a FAQ entry</A>
+</UL>
+"""
+
+# Index formatting
+
+INDEX_SECTION = """
+<P>
+<HR>
+<H2>%(sec)s. %(title)s</H2>
+<UL>
+"""
+
+INDEX_ADDSECTION = """
+<P>
+<LI><A HREF="%(FAQCGI)s?req=new&amp;section=%(sec)s">Add new entry</A>
+(at this point)
+"""
+
+INDEX_ENDSECTION = """
+</UL>
+"""
+
+INDEX_ENTRY = """\
+<LI><A HREF="%(FAQCGI)s?req=show&amp;file=%(file)s">%(title)s</A>
+"""
+
+LOCAL_ENTRY = """\
+<LI><A HREF="#%(sec)s.%(num)s">%(title)s</A>
+"""
+
+# Entry formatting
+
+ENTRY_HEADER1 = """
+<HR>
+<H2><A NAME="%(sec)s.%(num)s">%(title)s</A>\
+"""
+
+ENTRY_HEADER2 = """\
+</H2>
+"""
+
+ENTRY_FOOTER = """
+<A HREF="%(FAQCGI)s?req=edit&amp;file=%(file)s">Edit this entry</A> /
+<A HREF="%(FAQCGI)s?req=log&amp;file=%(file)s">Log info</A>
+"""
+
+ENTRY_LOGINFO = """
+/ Last changed on %(last_changed_date)s by
+<A HREF="mailto:%(last_changed_email)s">%(last_changed_author)s</A>
+"""
+
+# Search
+
+NO_HITS = """
+No hits.
+"""
+
+ONE_HIT = """
+Your search matched the following entry:
+"""
+
+FEW_HITS = """
+Your search matched the following %(count)s entries:
+"""
+
+MANY_HITS = """
+Your search matched more than %(MAXHITS)s entries.
+The %(count)s matching entries are presented here ordered by section:
+"""
+
+# RCS log and diff
+
+LOG = """
+Click on a revision line to see the diff between that revision and the
+previous one.
+"""
+
+REVISIONLINK = """\
+<A HREF="%(FAQCGI)s?req=revision&amp;file=%(file)s&amp;rev=%(rev)s"
+>%(line)s</A>\
+"""
+DIFFLINK = """\
+ (<A HREF="%(FAQCGI)s?req=diff&amp;file=%(file)s&amp;\
+prev=%(prev)s&amp;rev=%(rev)s"
+>diff -r%(prev)s -r%(rev)s</A>)\
+"""
+
+# Recently changed entries
+
+NO_RECENT = """
+<HR>
+No %(FAQNAME)s entries were changed in the last %(period)s.
+"""
+
+VIEW_MENU = """
+<HR>
+View entries changed in the last...
+<UL>
+<LI><A HREF="%(FAQCGI)s?req=recent&amp;days=1">24 hours</A>
+<LI><A HREF="%(FAQCGI)s?req=recent&amp;days=2">2 days</A>
+<LI><A HREF="%(FAQCGI)s?req=recent&amp;days=3">3 days</A>
+<LI><A HREF="%(FAQCGI)s?req=recent&amp;days=7">week</A>
+<LI><A HREF="%(FAQCGI)s?req=recent&amp;days=28">4 weeks</A>
+<LI><A HREF="%(FAQCGI)s?req=recent&amp;days=365250">millennium</A>
+</UL>
+"""
+
+ONE_RECENT = VIEW_MENU + """
+The following %(FAQNAME)s entry was changed in the last %(period)s:
+"""
+
+SOME_RECENT = VIEW_MENU + """
+The following %(count)s %(FAQNAME)s entries were changed
+in the last %(period)s, most recently changed shown first:
+"""
+
+TAIL_RECENT = VIEW_MENU
+
+# Last changed banner on "all" (strftime format)
+LAST_CHANGED = "Last changed on %c %Z"
+
+# "Compat" command prologue (this has no <BODY> tag)
+COMPAT = """
+<H1>The whole %(FAQNAME)s</H1>
+See also the <A HREF="%(FAQCGI)s?req=home">%(FAQNAME)s Wizard</A>.
+<P>
+"""
+
+# Editing
+
+EDITHEAD = """
+<A HREF="%(FAQCGI)s?req=help">Click for Help</A>
+"""
+
+REVIEWHEAD = EDITHEAD
+
+
+EDITFORM1 = """
+<FORM ACTION="%(FAQCGI)s" METHOD=POST>
+<INPUT TYPE=hidden NAME=req VALUE=review>
+<INPUT TYPE=hidden NAME=file VALUE=%(file)s>
+<INPUT TYPE=hidden NAME=editversion VALUE=%(editversion)s>
+<HR>
+"""
+
+EDITFORM2 = """
+Title: <INPUT TYPE=text SIZE=70 NAME=title VALUE="%(title)s"><BR>
+<TEXTAREA COLS=72 ROWS=20 NAME=body>%(body)s
+</TEXTAREA><BR>
+Log message (reason for the change):<BR>
+<TEXTAREA COLS=72 ROWS=5 NAME=log>%(log)s
+</TEXTAREA><BR>
+Please provide the following information for logging purposes:
+<TABLE FRAME=none COLS=2>
+    <TR>
+        <TD>Name:
+        <TD><INPUT TYPE=text SIZE=40 NAME=author VALUE="%(author)s">
+    <TR>
+        <TD>Email:
+        <TD><INPUT TYPE=text SIZE=40 NAME=email VALUE="%(email)s">
+    <TR>
+        <TD>Password:
+        <TD><INPUT TYPE=password SIZE=20 NAME=password VALUE="%(password)s">
+</TABLE>
+
+<INPUT TYPE=submit NAME=review VALUE="Preview Edit">
+Click this button to preview your changes.
+"""
+
+EDITFORM3 = """
+</FORM>
+"""
+
+COMMIT = """
+<INPUT TYPE=submit NAME=commit VALUE="Commit">
+Click this button to commit your changes.
+<HR>
+"""
+
+NOCOMMIT_HEAD = """
+To commit your changes, please correct the following errors in the
+form below and click the Preview Edit button.
+<UL>
+"""
+NOCOMMIT_TAIL = """
+</UL>
+<HR>
+"""
+
+CANTCOMMIT_HEAD = """
+Some required information is missing:
+<UL>
+"""
+NEED_PASSWD = "<LI>You must provide the correct password.\n"
+NEED_AUTHOR = "<LI>You must enter your name.\n"
+NEED_EMAIL = "<LI>You must enter your email address.\n"
+NEED_LOG = "<LI>You must enter a log message.\n"
+CANTCOMMIT_TAIL = """
+</UL>
+Please use your browser's Back command to correct the form and commit
+again.
+"""
+
+NEWCONFLICT = """
+<P>
+You are creating a new entry, but the entry number specified is not
+correct.
+<P>
+The two most common causes of this problem are:
+<UL>
+<LI>After creating the entry yourself, you went back in your browser,
+    edited the entry some more, and clicked Commit again.
+<LI>Someone else started creating a new entry in the same section and
+    committed before you did.
+</UL>
+(It is also possible that the last entry in the section was physically
+deleted, but this should not happen except through manual intervention
+by the FAQ maintainer.)
+<P>
+<A HREF="%(FAQCGI)s?req=new&amp;section=%(sec)s">Click here to try
+again.</A>
+<P>
+"""
+
+VERSIONCONFLICT = """
+<P>
+You edited version %(editversion)s but the current version is %(version)s.
+<P>
+The two most common causes of this problem are:
+<UL>
+<LI>After committing a change, you went back in your browser,
+    edited the entry some more, and clicked Commit again.
+<LI>Someone else started editing the same entry and committed
+    before you did.
+</UL>
+<P>
+<A HREF="%(FAQCGI)s?req=show&amp;file=%(file)s">Click here to reload
+the entry and try again.</A>
+<P>
+"""
+
+CANTWRITE = """
+Can't write file %(file)s (%(why)s).
+"""
+
+FILEHEADER = """\
+Title: %(title)s
+Last-Changed-Date: %(date)s
+Last-Changed-Author: %(author)s
+Last-Changed-Email: %(email)s
+Last-Changed-Remote-Host: %(REMOTE_HOST)s
+Last-Changed-Remote-Address: %(REMOTE_ADDR)s
+"""
+
+LOGHEADER = """\
+Last-Changed-Date: %(date)s
+Last-Changed-Author: %(author)s
+Last-Changed-Email: %(email)s
+Last-Changed-Remote-Host: %(REMOTE_HOST)s
+Last-Changed-Remote-Address: %(REMOTE_ADDR)s
+
+%(log)s
+"""
+
+COMMITTED = """
+Your changes have been committed.
+"""
+
+COMMITFAILED = """
+Exit status %(sts)s.
+"""
+
+# Add/Delete
+
+ADD_HEAD = """
+At the moment, new entries can only be added at the end of a section.
+This is because the entry numbers are also their
+unique identifiers -- it's a bad idea to renumber entries.
+<P>
+Click on the section to which you want to add a new entry:
+<UL>
+"""
+
+ADD_SECTION = """\
+<LI><A HREF="%(FAQCGI)s?req=new&amp;section=%(section)s">%(section)s. %(title)s</A>
+"""
+
+ADD_TAIL = """
+</UL>
+"""
+
+ROULETTE = """
+<P>Hit your browser's Reload button to play again.<P>
+"""
+
+DELETE = """
+At the moment, there's no direct way to delete entries.
+This is because the entry numbers are also their
+unique identifiers -- it's a bad idea to renumber entries.
+<P>
+If you really think an entry needs to be deleted,
+change the title to "(deleted)" and make the body
+empty (keep the entry number in the title though).
+"""
+
+# Help file for the FAQ Edit Wizard
+
+HELP = """
+Using the %(FAQNAME)s Edit Wizard speaks mostly for itself.  Here are
+some answers to questions you are likely to ask:
+
+<P><HR>
+
+<H2>I can review an entry but I can't commit it.</H2>
+
+The commit button only appears if the following conditions are met:
+
+<UL>
+
+<LI>The Name field is not empty.
+
+<LI>The Email field contains at least an @ character.
+
+<LI>The Log message box is not empty.
+
+<LI>The Password field contains the proper password.
+
+</UL>
+
+<P><HR>
+
+<H2>What is the password?</H2>
+
+At the moment, only PSA members will be told the password.  This is a
+good time to join the PSA!  See <A
+HREF="http://www.python.org/psa/">the PSA home page</A>.
+
+<P><HR>
+
+<H2>Can I use HTML in the FAQ entry?</H2>
+
+Yes, if you include it in &lt;HTML&rt; and &lt;/HTML&gt; tags.
+<P>
+Also, if you include a URL or an email address in the text it will
+automatigally become an anchor of the right type.  Also, *word*
+is made italic (but only for single alphabetic words).
+
+<P><HR>
+
+<H2>How do I delineate paragraphs?</H2>
+
+Use blank lines to separate paragraphs.
+
+<P><HR>
+
+<H2>How do I enter example text?</H2>
+
+Any line that begins with a space or tab is assumed to be part of
+literal text.  Blocks of literal text delineated by blank lines are
+placed inside &lt;PRE&gt;...&lt;/PRE&gt;.
+"""
+
+# Load local customizations again, in case they set some other variables
+
+try:
+    from faqcust import *
+except ImportError:
+    pass

Added: vendor/Python/current/Tools/faqwiz/faqcust.py
===================================================================
--- vendor/Python/current/Tools/faqwiz/faqcust.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/faqwiz/faqcust.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1 @@
+# Add your customizations here -- modified copies of what's in faqconf.py.

Added: vendor/Python/current/Tools/faqwiz/faqw.py
===================================================================
--- vendor/Python/current/Tools/faqwiz/faqw.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/faqwiz/faqw.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,33 @@
+#! /usr/local/bin/python
+
+"""FAQ wizard bootstrap."""
+
+# This is a longer version of the bootstrap script given at the end of
+# faqwin.py; it prints timing statistics at the end of the regular CGI
+# script's output (so you can monitor how it is doing).
+
+# This script should be placed in your cgi-bin directory and made
+# executable.
+
+# You need to edit the first line and the lines that define FAQDIR and
+# SRCDIR, below: change /usr/local/bin/python to where your Python
+# interpreter lives, change the value for FAQDIR to where your FAQ
+# lives, and change the value for SRCDIR to where your faqwiz.py
+# module lives.  The faqconf.py and faqcust.py files live there, too.
+
+import os
+t1 = os.times() # If this doesn't work, just get rid of the timing code!
+try:
+    FAQDIR = "/usr/people/guido/python/FAQ"
+    SRCDIR = "/usr/people/guido/python/src/Tools/faqwiz"
+    import os, sys, time, operator
+    os.chdir(FAQDIR)
+    sys.path.insert(0, SRCDIR)
+    import faqwiz
+except SystemExit, n:
+    sys.exit(n)
+except:
+    t, v, tb = sys.exc_info()
+    print
+    import cgi
+    cgi.print_exception(t, v, tb)


Property changes on: vendor/Python/current/Tools/faqwiz/faqw.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/faqwiz/faqwiz.py
===================================================================
--- vendor/Python/current/Tools/faqwiz/faqwiz.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/faqwiz/faqwiz.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,841 @@
+"""Generic FAQ Wizard.
+
+This is a CGI program that maintains a user-editable FAQ.  It uses RCS
+to keep track of changes to individual FAQ entries.  It is fully
+configurable; everything you might want to change when using this
+program to maintain some other FAQ than the Python FAQ is contained in
+the configuration module, faqconf.py.
+
+Note that this is not an executable script; it's an importable module.
+The actual script to place in cgi-bin is faqw.py.
+
+"""
+
+import sys, time, os, stat, re, cgi, faqconf
+from faqconf import *                   # This imports all uppercase names
+now = time.time()
+
+class FileError:
+    def __init__(self, file):
+        self.file = file
+
+class InvalidFile(FileError):
+    pass
+
+class NoSuchSection(FileError):
+    def __init__(self, section):
+        FileError.__init__(self, NEWFILENAME %(section, 1))
+        self.section = section
+
+class NoSuchFile(FileError):
+    def __init__(self, file, why=None):
+        FileError.__init__(self, file)
+        self.why = why
+
+def escape(s):
+    s = s.replace('&', '&amp;')
+    s = s.replace('<', '&lt;')
+    s = s.replace('>', '&gt;')
+    return s
+
+def escapeq(s):
+    s = escape(s)
+    s = s.replace('"', '&quot;')
+    return s
+
+def _interpolate(format, args, kw):
+    try:
+        quote = kw['_quote']
+    except KeyError:
+        quote = 1
+    d = (kw,) + args + (faqconf.__dict__,)
+    m = MagicDict(d, quote)
+    return format % m
+
+def interpolate(format, *args, **kw):
+    return _interpolate(format, args, kw)
+
+def emit(format, *args, **kw):
+    try:
+        f = kw['_file']
+    except KeyError:
+        f = sys.stdout
+    f.write(_interpolate(format, args, kw))
+
+translate_prog = None
+
+def translate(text, pre=0):
+    global translate_prog
+    if not translate_prog:
+        translate_prog = prog = re.compile(
+            r'\b(http|ftp|https)://\S+(\b|/)|\b[-.\w]+@[-.\w]+')
+    else:
+        prog = translate_prog
+    i = 0
+    list = []
+    while 1:
+        m = prog.search(text, i)
+        if not m:
+            break
+        j = m.start()
+        list.append(escape(text[i:j]))
+        i = j
+        url = m.group(0)
+        while url[-1] in '();:,.?\'"<>':
+            url = url[:-1]
+        i = i + len(url)
+        url = escape(url)
+        if not pre or (pre and PROCESS_PREFORMAT):
+            if ':' in url:
+                repl = '<A HREF="%s">%s</A>' % (url, url)
+            else:
+                repl = '<A HREF="mailto:%s">%s</A>' % (url, url)
+        else:
+            repl = url
+        list.append(repl)
+    j = len(text)
+    list.append(escape(text[i:j]))
+    return ''.join(list)
+
+def emphasize(line):
+    return re.sub(r'\*([a-zA-Z]+)\*', r'<I>\1</I>', line)
+
+revparse_prog = None
+
+def revparse(rev):
+    global revparse_prog
+    if not revparse_prog:
+        revparse_prog = re.compile(r'^(\d{1,3})\.(\d{1,4})$')
+    m = revparse_prog.match(rev)
+    if not m:
+        return None
+    [major, minor] = map(int, m.group(1, 2))
+    return major, minor
+
+logon = 0
+def log(text):
+    if logon:
+        logfile = open("logfile", "a")
+        logfile.write(text + "\n")
+        logfile.close()
+
+def load_cookies():
+    if not os.environ.has_key('HTTP_COOKIE'):
+        return {}
+    raw = os.environ['HTTP_COOKIE']
+    words = [s.strip() for s in raw.split(';')]
+    cookies = {}
+    for word in words:
+        i = word.find('=')
+        if i >= 0:
+            key, value = word[:i], word[i+1:]
+            cookies[key] = value
+    return cookies
+
+def load_my_cookie():
+    cookies = load_cookies()
+    try:
+        value = cookies[COOKIE_NAME]
+    except KeyError:
+        return {}
+    import urllib
+    value = urllib.unquote(value)
+    words = value.split('/')
+    while len(words) < 3:
+        words.append('')
+    author = '/'.join(words[:-2])
+    email = words[-2]
+    password = words[-1]
+    return {'author': author,
+            'email': email,
+            'password': password}
+
+def send_my_cookie(ui):
+    name = COOKIE_NAME
+    value = "%s/%s/%s" % (ui.author, ui.email, ui.password)
+    import urllib
+    value = urllib.quote(value)
+    then = now + COOKIE_LIFETIME
+    gmt = time.gmtime(then)
+    path = os.environ.get('SCRIPT_NAME', '/cgi-bin/')
+    print "Set-Cookie: %s=%s; path=%s;" % (name, value, path),
+    print time.strftime("expires=%a, %d-%b-%y %X GMT", gmt)
+
+class MagicDict:
+
+    def __init__(self, d, quote):
+        self.__d = d
+        self.__quote = quote
+
+    def __getitem__(self, key):
+        for d in self.__d:
+            try:
+                value = d[key]
+                if value:
+                    value = str(value)
+                    if self.__quote:
+                        value = escapeq(value)
+                    return value
+            except KeyError:
+                pass
+        return ''
+
+class UserInput:
+
+    def __init__(self):
+        self.__form = cgi.FieldStorage()
+        #log("\n\nbody: " + self.body)
+
+    def __getattr__(self, name):
+        if name[0] == '_':
+            raise AttributeError
+        try:
+            value = self.__form[name].value
+        except (TypeError, KeyError):
+            value = ''
+        else:
+            value = value.strip()
+        setattr(self, name, value)
+        return value
+
+    def __getitem__(self, key):
+        return getattr(self, key)
+
+class FaqEntry:
+
+    def __init__(self, fp, file, sec_num):
+        self.file = file
+        self.sec, self.num = sec_num
+        if fp:
+            import rfc822
+            self.__headers = rfc822.Message(fp)
+            self.body = fp.read().strip()
+        else:
+            self.__headers = {'title': "%d.%d. " % sec_num}
+            self.body = ''
+
+    def __getattr__(self, name):
+        if name[0] == '_':
+            raise AttributeError
+        key = '-'.join(name.split('_'))
+        try:
+            value = self.__headers[key]
+        except KeyError:
+            value = ''
+        setattr(self, name, value)
+        return value
+
+    def __getitem__(self, key):
+        return getattr(self, key)
+
+    def load_version(self):
+        command = interpolate(SH_RLOG_H, self)
+        p = os.popen(command)
+        version = ''
+        while 1:
+            line = p.readline()
+            if not line:
+                break
+            if line[:5] == 'head:':
+                version = line[5:].strip()
+        p.close()
+        self.version = version
+
+    def getmtime(self):
+        if not self.last_changed_date:
+            return 0
+        try:
+            return os.stat(self.file)[stat.ST_MTIME]
+        except os.error:
+            return 0
+
+    def emit_marks(self):
+        mtime = self.getmtime()
+        if mtime >= now - DT_VERY_RECENT:
+            emit(MARK_VERY_RECENT, self)
+        elif mtime >= now - DT_RECENT:
+            emit(MARK_RECENT, self)
+
+    def show(self, edit=1):
+        emit(ENTRY_HEADER1, self)
+        self.emit_marks()
+        emit(ENTRY_HEADER2, self)
+        pre = 0
+        raw = 0
+        for line in self.body.split('\n'):
+            # Allow the user to insert raw html into a FAQ answer
+            # (Skip Montanaro, with changes by Guido)
+            tag = line.rstrip().lower()
+            if tag == '<html>':
+                raw = 1
+                continue
+            if tag == '</html>':
+                raw = 0
+                continue
+            if raw:
+                print line
+                continue
+            if not line.strip():
+                if pre:
+                    print '</PRE>'
+                    pre = 0
+                else:
+                    print '<P>'
+            else:
+                if not line[0].isspace():
+                    if pre:
+                        print '</PRE>'
+                        pre = 0
+                else:
+                    if not pre:
+                        print '<PRE>'
+                        pre = 1
+                if '/' in line or '@' in line:
+                    line = translate(line, pre)
+                elif '<' in line or '&' in line:
+                    line = escape(line)
+                if not pre and '*' in line:
+                    line = emphasize(line)
+                print line
+        if pre:
+            print '</PRE>'
+            pre = 0
+        if edit:
+            print '<P>'
+            emit(ENTRY_FOOTER, self)
+            if self.last_changed_date:
+                emit(ENTRY_LOGINFO, self)
+        print '<P>'
+
+class FaqDir:
+
+    entryclass = FaqEntry
+
+    __okprog = re.compile(OKFILENAME)
+
+    def __init__(self, dir=os.curdir):
+        self.__dir = dir
+        self.__files = None
+
+    def __fill(self):
+        if self.__files is not None:
+            return
+        self.__files = files = []
+        okprog = self.__okprog
+        for file in os.listdir(self.__dir):
+            if self.__okprog.match(file):
+                files.append(file)
+        files.sort()
+
+    def good(self, file):
+        return self.__okprog.match(file)
+
+    def parse(self, file):
+        m = self.good(file)
+        if not m:
+            return None
+        sec, num = m.group(1, 2)
+        return int(sec), int(num)
+
+    def list(self):
+        # XXX Caller shouldn't modify result
+        self.__fill()
+        return self.__files
+
+    def open(self, file):
+        sec_num = self.parse(file)
+        if not sec_num:
+            raise InvalidFile(file)
+        try:
+            fp = open(file)
+        except IOError, msg:
+            raise NoSuchFile(file, msg)
+        try:
+            return self.entryclass(fp, file, sec_num)
+        finally:
+            fp.close()
+
+    def show(self, file, edit=1):
+        self.open(file).show(edit=edit)
+
+    def new(self, section):
+        if not SECTION_TITLES.has_key(section):
+            raise NoSuchSection(section)
+        maxnum = 0
+        for file in self.list():
+            sec, num = self.parse(file)
+            if sec == section:
+                maxnum = max(maxnum, num)
+        sec_num = (section, maxnum+1)
+        file = NEWFILENAME % sec_num
+        return self.entryclass(None, file, sec_num)
+
+class FaqWizard:
+
+    def __init__(self):
+        self.ui = UserInput()
+        self.dir = FaqDir()
+
+    def go(self):
+        print 'Content-type: text/html'
+        req = self.ui.req or 'home'
+        mname = 'do_%s' % req
+        try:
+            meth = getattr(self, mname)
+        except AttributeError:
+            self.error("Bad request type %r." % (req,))
+        else:
+            try:
+                meth()
+            except InvalidFile, exc:
+                self.error("Invalid entry file name %s" % exc.file)
+            except NoSuchFile, exc:
+                self.error("No entry with file name %s" % exc.file)
+            except NoSuchSection, exc:
+                self.error("No section number %s" % exc.section)
+        self.epilogue()
+
+    def error(self, message, **kw):
+        self.prologue(T_ERROR)
+        emit(message, kw)
+
+    def prologue(self, title, entry=None, **kw):
+        emit(PROLOGUE, entry, kwdict=kw, title=escape(title))
+
+    def epilogue(self):
+        emit(EPILOGUE)
+
+    def do_home(self):
+        self.prologue(T_HOME)
+        emit(HOME)
+
+    def do_debug(self):
+        self.prologue("FAQ Wizard Debugging")
+        form = cgi.FieldStorage()
+        cgi.print_form(form)
+        cgi.print_environ(os.environ)
+        cgi.print_directory()
+        cgi.print_arguments()
+
+    def do_search(self):
+        query = self.ui.query
+        if not query:
+            self.error("Empty query string!")
+            return
+        if self.ui.querytype == 'simple':
+            query = re.escape(query)
+            queries = [query]
+        elif self.ui.querytype in ('anykeywords', 'allkeywords'):
+            words = filter(None, re.split('\W+', query))
+            if not words:
+                self.error("No keywords specified!")
+                return
+            words = map(lambda w: r'\b%s\b' % w, words)
+            if self.ui.querytype[:3] == 'any':
+                queries = ['|'.join(words)]
+            else:
+                # Each of the individual queries must match
+                queries = words
+        else:
+            # Default to regular expression
+            queries = [query]
+        self.prologue(T_SEARCH)
+        progs = []
+        for query in queries:
+            if self.ui.casefold == 'no':
+                p = re.compile(query)
+            else:
+                p = re.compile(query, re.IGNORECASE)
+            progs.append(p)
+        hits = []
+        for file in self.dir.list():
+            try:
+                entry = self.dir.open(file)
+            except FileError:
+                constants
+            for p in progs:
+                if not p.search(entry.title) and not p.search(entry.body):
+                    break
+            else:
+                hits.append(file)
+        if not hits:
+            emit(NO_HITS, self.ui, count=0)
+        elif len(hits) <= MAXHITS:
+            if len(hits) == 1:
+                emit(ONE_HIT, count=1)
+            else:
+                emit(FEW_HITS, count=len(hits))
+            self.format_all(hits, headers=0)
+        else:
+            emit(MANY_HITS, count=len(hits))
+            self.format_index(hits)
+
+    def do_all(self):
+        self.prologue(T_ALL)
+        files = self.dir.list()
+        self.last_changed(files)
+        self.format_index(files, localrefs=1)
+        self.format_all(files)
+
+    def do_compat(self):
+        files = self.dir.list()
+        emit(COMPAT)
+        self.last_changed(files)
+        self.format_index(files, localrefs=1)
+        self.format_all(files, edit=0)
+        sys.exit(0)                     # XXX Hack to suppress epilogue
+
+    def last_changed(self, files):
+        latest = 0
+        for file in files:
+            entry = self.dir.open(file)
+            if entry:
+                mtime = mtime = entry.getmtime()
+                if mtime > latest:
+                    latest = mtime
+        print time.strftime(LAST_CHANGED, time.localtime(latest))
+        emit(EXPLAIN_MARKS)
+
+    def format_all(self, files, edit=1, headers=1):
+        sec = 0
+        for file in files:
+            try:
+                entry = self.dir.open(file)
+            except NoSuchFile:
+                continue
+            if headers and entry.sec != sec:
+                sec = entry.sec
+                try:
+                    title = SECTION_TITLES[sec]
+                except KeyError:
+                    title = "Untitled"
+                emit("\n<HR>\n<H1>%(sec)s. %(title)s</H1>\n",
+                     sec=sec, title=title)
+            entry.show(edit=edit)
+
+    def do_index(self):
+        self.prologue(T_INDEX)
+        files = self.dir.list()
+        self.last_changed(files)
+        self.format_index(files, add=1)
+
+    def format_index(self, files, add=0, localrefs=0):
+        sec = 0
+        for file in files:
+            try:
+                entry = self.dir.open(file)
+            except NoSuchFile:
+                continue
+            if entry.sec != sec:
+                if sec:
+                    if add:
+                        emit(INDEX_ADDSECTION, sec=sec)
+                    emit(INDEX_ENDSECTION, sec=sec)
+                sec = entry.sec
+                try:
+                    title = SECTION_TITLES[sec]
+                except KeyError:
+                    title = "Untitled"
+                emit(INDEX_SECTION, sec=sec, title=title)
+            if localrefs:
+                emit(LOCAL_ENTRY, entry)
+            else:
+                emit(INDEX_ENTRY, entry)
+            entry.emit_marks()
+        if sec:
+            if add:
+                emit(INDEX_ADDSECTION, sec=sec)
+            emit(INDEX_ENDSECTION, sec=sec)
+
+    def do_recent(self):
+        if not self.ui.days:
+            days = 1
+        else:
+            days = float(self.ui.days)
+        try:
+            cutoff = now - days * 24 * 3600
+        except OverflowError:
+            cutoff = 0
+        list = []
+        for file in self.dir.list():
+            entry = self.dir.open(file)
+            if not entry:
+                continue
+            mtime = entry.getmtime()
+            if mtime >= cutoff:
+                list.append((mtime, file))
+        list.sort()
+        list.reverse()
+        self.prologue(T_RECENT)
+        if days <= 1:
+            period = "%.2g hours" % (days*24)
+        else:
+            period = "%.6g days" % days
+        if not list:
+            emit(NO_RECENT, period=period)
+        elif len(list) == 1:
+            emit(ONE_RECENT, period=period)
+        else:
+            emit(SOME_RECENT, period=period, count=len(list))
+        self.format_all(map(lambda (mtime, file): file, list), headers=0)
+        emit(TAIL_RECENT)
+
+    def do_roulette(self):
+        import random
+        files = self.dir.list()
+        if not files:
+            self.error("No entries.")
+            return
+        file = random.choice(files)
+        self.prologue(T_ROULETTE)
+        emit(ROULETTE)
+        self.dir.show(file)
+
+    def do_help(self):
+        self.prologue(T_HELP)
+        emit(HELP)
+
+    def do_show(self):
+        entry = self.dir.open(self.ui.file)
+        self.prologue(T_SHOW)
+        entry.show()
+
+    def do_add(self):
+        self.prologue(T_ADD)
+        emit(ADD_HEAD)
+        sections = SECTION_TITLES.items()
+        sections.sort()
+        for section, title in sections:
+            emit(ADD_SECTION, section=section, title=title)
+        emit(ADD_TAIL)
+
+    def do_delete(self):
+        self.prologue(T_DELETE)
+        emit(DELETE)
+
+    def do_log(self):
+        entry = self.dir.open(self.ui.file)
+        self.prologue(T_LOG, entry)
+        emit(LOG, entry)
+        self.rlog(interpolate(SH_RLOG, entry), entry)
+
+    def rlog(self, command, entry=None):
+        output = os.popen(command).read()
+        sys.stdout.write('<PRE>')
+        athead = 0
+        lines = output.split('\n')
+        while lines and not lines[-1]:
+            del lines[-1]
+        if lines:
+            line = lines[-1]
+            if line[:1] == '=' and len(line) >= 40 and \
+               line == line[0]*len(line):
+                del lines[-1]
+        headrev = None
+        for line in lines:
+            if entry and athead and line[:9] == 'revision ':
+                rev = line[9:].split()
+                mami = revparse(rev)
+                if not mami:
+                    print line
+                else:
+                    emit(REVISIONLINK, entry, rev=rev, line=line)
+                    if mami[1] > 1:
+                        prev = "%d.%d" % (mami[0], mami[1]-1)
+                        emit(DIFFLINK, entry, prev=prev, rev=rev)
+                    if headrev:
+                        emit(DIFFLINK, entry, prev=rev, rev=headrev)
+                    else:
+                        headrev = rev
+                    print
+                athead = 0
+            else:
+                athead = 0
+                if line[:1] == '-' and len(line) >= 20 and \
+                   line == len(line) * line[0]:
+                    athead = 1
+                    sys.stdout.write('<HR>')
+                else:
+                    print line
+        print '</PRE>'
+
+    def do_revision(self):
+        entry = self.dir.open(self.ui.file)
+        rev = self.ui.rev
+        mami = revparse(rev)
+        if not mami:
+            self.error("Invalid revision number: %r." % (rev,))
+        self.prologue(T_REVISION, entry)
+        self.shell(interpolate(SH_REVISION, entry, rev=rev))
+
+    def do_diff(self):
+        entry = self.dir.open(self.ui.file)
+        prev = self.ui.prev
+        rev = self.ui.rev
+        mami = revparse(rev)
+        if not mami:
+            self.error("Invalid revision number: %r." % (rev,))
+        if prev:
+            if not revparse(prev):
+                self.error("Invalid previous revision number: %r." % (prev,))
+        else:
+            prev = '%d.%d' % (mami[0], mami[1])
+        self.prologue(T_DIFF, entry)
+        self.shell(interpolate(SH_RDIFF, entry, rev=rev, prev=prev))
+
+    def shell(self, command):
+        output = os.popen(command).read()
+        sys.stdout.write('<PRE>')
+        print escape(output)
+        print '</PRE>'
+
+    def do_new(self):
+        entry = self.dir.new(section=int(self.ui.section))
+        entry.version = '*new*'
+        self.prologue(T_EDIT)
+        emit(EDITHEAD)
+        emit(EDITFORM1, entry, editversion=entry.version)
+        emit(EDITFORM2, entry, load_my_cookie())
+        emit(EDITFORM3)
+        entry.show(edit=0)
+
+    def do_edit(self):
+        entry = self.dir.open(self.ui.file)
+        entry.load_version()
+        self.prologue(T_EDIT)
+        emit(EDITHEAD)
+        emit(EDITFORM1, entry, editversion=entry.version)
+        emit(EDITFORM2, entry, load_my_cookie())
+        emit(EDITFORM3)
+        entry.show(edit=0)
+
+    def do_review(self):
+        send_my_cookie(self.ui)
+        if self.ui.editversion == '*new*':
+            sec, num = self.dir.parse(self.ui.file)
+            entry = self.dir.new(section=sec)
+            entry.version = "*new*"
+            if entry.file != self.ui.file:
+                self.error("Commit version conflict!")
+                emit(NEWCONFLICT, self.ui, sec=sec, num=num)
+                return
+        else:
+            entry = self.dir.open(self.ui.file)
+            entry.load_version()
+        # Check that the FAQ entry number didn't change
+        if self.ui.title.split()[:1] != entry.title.split()[:1]:
+            self.error("Don't change the entry number please!")
+            return
+        # Check that the edited version is the current version
+        if entry.version != self.ui.editversion:
+            self.error("Commit version conflict!")
+            emit(VERSIONCONFLICT, entry, self.ui)
+            return
+        commit_ok = ((not PASSWORD
+                      or self.ui.password == PASSWORD)
+                     and self.ui.author
+                     and '@' in self.ui.email
+                     and self.ui.log)
+        if self.ui.commit:
+            if not commit_ok:
+                self.cantcommit()
+            else:
+                self.commit(entry)
+            return
+        self.prologue(T_REVIEW)
+        emit(REVIEWHEAD)
+        entry.body = self.ui.body
+        entry.title = self.ui.title
+        entry.show(edit=0)
+        emit(EDITFORM1, self.ui, entry)
+        if commit_ok:
+            emit(COMMIT)
+        else:
+            emit(NOCOMMIT_HEAD)
+            self.errordetail()
+            emit(NOCOMMIT_TAIL)
+        emit(EDITFORM2, self.ui, entry, load_my_cookie())
+        emit(EDITFORM3)
+
+    def cantcommit(self):
+        self.prologue(T_CANTCOMMIT)
+        print CANTCOMMIT_HEAD
+        self.errordetail()
+        print CANTCOMMIT_TAIL
+
+    def errordetail(self):
+        if PASSWORD and self.ui.password != PASSWORD:
+            emit(NEED_PASSWD)
+        if not self.ui.log:
+            emit(NEED_LOG)
+        if not self.ui.author:
+            emit(NEED_AUTHOR)
+        if not self.ui.email:
+            emit(NEED_EMAIL)
+
+    def commit(self, entry):
+        file = entry.file
+        # Normalize line endings in body
+        if '\r' in self.ui.body:
+            self.ui.body = re.sub('\r\n?', '\n', self.ui.body)
+        # Normalize whitespace in title
+        self.ui.title = ' '.join(self.ui.title.split())
+        # Check that there were any changes
+        if self.ui.body == entry.body and self.ui.title == entry.title:
+            self.error("You didn't make any changes!")
+            return
+
+        # need to lock here because otherwise the file exists and is not writable (on NT)
+        command = interpolate(SH_LOCK, file=file)
+        p = os.popen(command)
+        output = p.read()
+
+        try:
+            os.unlink(file)
+        except os.error:
+            pass
+        try:
+            f = open(file, 'w')
+        except IOError, why:
+            self.error(CANTWRITE, file=file, why=why)
+            return
+        date = time.ctime(now)
+        emit(FILEHEADER, self.ui, os.environ, date=date, _file=f, _quote=0)
+        f.write('\n')
+        f.write(self.ui.body)
+        f.write('\n')
+        f.close()
+
+        import tempfile
+        tf = tempfile.NamedTemporaryFile()
+        emit(LOGHEADER, self.ui, os.environ, date=date, _file=tf)
+        tf.flush()
+        tf.seek(0)
+
+        command = interpolate(SH_CHECKIN, file=file, tfn=tf.name)
+        log("\n\n" + command)
+        p = os.popen(command)
+        output = p.read()
+        sts = p.close()
+        log("output: " + output)
+        log("done: " + str(sts))
+        log("TempFile:\n" + tf.read() + "end")
+
+        if not sts:
+            self.prologue(T_COMMITTED)
+            emit(COMMITTED)
+        else:
+            self.error(T_COMMITFAILED)
+            emit(COMMITFAILED, sts=sts)
+        print '<PRE>%s</PRE>' % escape(output)
+
+        try:
+            os.unlink(tf.name)
+        except os.error:
+            pass
+
+        entry = self.dir.open(file)
+        entry.show()
+
+wiz = FaqWizard()
+wiz.go()

Added: vendor/Python/current/Tools/faqwiz/move-faqwiz.sh
===================================================================
--- vendor/Python/current/Tools/faqwiz/move-faqwiz.sh	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/faqwiz/move-faqwiz.sh	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,49 @@
+#!/bin/sh
+#
+# Christian Reis <kiko at async.com.br>
+#
+# Moves 
+# 
+# Example:
+#
+#   blackjesus:~> ./move-faqwiz.sh 2\.1 3\.2
+#   Moving FAQ question 02.001 to 03.002
+
+if [ x$2 == x ]; then
+    echo "Need 2 args: original_version final_version."
+    exit 2
+fi
+
+if [ ! -d data -o ! -d data/RCS ]; then
+    echo "Run this inside the faqwiz data/ directory's parent dir."
+    exit 2
+fi
+
+function cut_n_pad() {
+    t=`echo $1 | cut -d. -f $2`
+    export $3=`echo $t | awk "{ tmp = \\$0; l = length(tmp); for (i = 0; i < $2-l+1; i++) { tmp = "0".tmp } print tmp  }"`
+}
+
+cut_n_pad $1 1 prefix1
+cut_n_pad $1 2 suffix1
+cut_n_pad $2 1 prefix2
+cut_n_pad $2 2 suffix2
+tmpfile=tmp$RANDOM.tmp
+file1=faq$prefix1.$suffix1.htp
+file2=faq$prefix2.$suffix2.htp
+
+echo "Moving FAQ question $prefix1.$suffix1 to $prefix2.$suffix2" 
+
+sed -e "s/$1\./$2\./g" data/$file1 > ${tmpfile}1
+sed -e "s/$1\./$2\./g" data/RCS/$file1,v > ${tmpfile}2
+
+if [ -f data/$file2 ]; then
+    echo "Target FAQ exists. Won't clobber."
+    exit 2
+fi
+
+mv ${tmpfile}1 data/$file2
+mv ${tmpfile}2 data/RCS/$file2,v
+mv data/$file1 data/$file1.orig
+mv data/RCS/$file1,v data/RCS/$file1,v.orig
+


Property changes on: vendor/Python/current/Tools/faqwiz/move-faqwiz.sh
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/framer/README.txt
===================================================================
--- vendor/Python/current/Tools/framer/README.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/framer/README.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,8 @@
+framer is a tool to generate boilerplate code for C extension types.
+
+The boilerplate is generated from a specification object written in
+Python.  The specification uses the class statement to describe the
+extension module and any extension types it contains.  From the
+specification, framer can generate all the boilerplate C code,
+including function definitions, argument handling code, and type
+objects.

Added: vendor/Python/current/Tools/framer/TODO.txt
===================================================================
--- vendor/Python/current/Tools/framer/TODO.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/framer/TODO.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,6 @@
+Add spec for getsets.
+Generate a distutils setup script.
+Handle operator overloading.
+Generate traverse and clear methods for GC.
+Handle mapping, sequence, buffer protocols.
+Finish the todo list.

Added: vendor/Python/current/Tools/framer/example.py
===================================================================
--- vendor/Python/current/Tools/framer/example.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/framer/example.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,126 @@
+"""Generate the skeleton for cStringIO as an example of framer."""
+
+from framer.bases import Module, Type
+from framer.member import member
+
+class cStringIO(Module):
+    """A simple fast partial StringIO replacement.
+
+    This module provides a simple useful replacement for the StringIO
+    module that is written in C.  It does not provide the full
+    generality of StringIO, but it provides enough for most
+    applications and is especially useful in conjunction with the
+    pickle module.
+
+    Usage:
+
+    from cStringIO import StringIO
+
+    an_output_stream = StringIO()
+    an_output_stream.write(some_stuff)
+    ...
+    value = an_output_stream.getvalue()
+
+    an_input_stream = StringIO(a_string)
+    spam = an_input_stream.readline()
+    spam = an_input_stream.read(5)
+    an_input_stream.seek(0)             # OK, start over
+    spam = an_input_stream.read()       # and read it all
+    """
+
+    __file__ = "cStringIO.c"
+
+    def StringIO(o):
+        """Return a StringIO-like stream for reading or writing"""
+    StringIO.pyarg = "|O"
+
+    class InputType(Type):
+        "Simple type for treating strings as input file streams"
+
+        abbrev = "input"
+
+        struct = """\
+        typedef struct {
+                PyObject_HEAD
+                char *buf;
+                int pos;
+                int size;
+                PyObject *pbuf;
+        } InputObject;
+        """
+
+        def flush(self):
+            """Does nothing"""
+
+        def getvalue(self):
+            """Get the string value.
+
+            If use_pos is specified and is a true value, then the
+            string returned will include only the text up to the
+            current file position.
+            """
+
+        def isatty(self):
+            """Always returns False"""
+
+        def read(self, s):
+            """Return s characters or the rest of the string."""
+        read.pyarg = "|i"
+
+        def readline(self):
+            """Read one line."""
+
+        def readlines(self, hint):
+            """Read all lines."""
+        readlines.pyarg = "|i"
+
+        def reset(self):
+            """Reset the file position to the beginning."""
+
+        def tell(self):
+            """Get the current position."""
+
+        def truncate(self, pos):
+            """Truncate the file at the current position."""
+        truncate.pyarg = "|i"
+
+        def seek(self, position, mode=0):
+            """Set the current position.
+
+            The optional mode argument can be 0 for absolute, 1 for relative,
+            and 2 for relative to EOF.  The default is absolute.
+            """
+        seek.pyarg = "i|i"
+
+        def close(self):
+            pass
+
+    class OutputType(InputType):
+        "Simple type for output strings."
+
+        abbrev = "output"
+
+        struct = """\
+        typedef struct {
+                PyObject_HEAD
+                char *buf;
+                int pos;
+                int size;
+                int softspace;
+        } OutputObject;
+        """
+
+        softspace = member()
+
+        def close(self):
+            """Explicitly release resources."""
+
+        def write(self, s):
+            """Write a string to the file."""
+            # XXX Hack: writing None resets the buffer
+
+        def writelines(self, lines):
+            """Write each string in lines."""
+
+
+cStringIO.gen()

Added: vendor/Python/current/Tools/framer/framer/__init__.py
===================================================================
--- vendor/Python/current/Tools/framer/framer/__init__.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/framer/framer/__init__.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,6 @@
+"""A tool to generate basic framework for C extension types.
+
+The basic ideas is the same as modulator, but the code generates code
+using many of the new features introduced in Python 2.2.  It also
+takes a more declarative approach to generating code.
+"""

Added: vendor/Python/current/Tools/framer/framer/bases.py
===================================================================
--- vendor/Python/current/Tools/framer/framer/bases.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/framer/framer/bases.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,220 @@
+"""Provides the Module and Type base classes that user code inherits from."""
+
+__all__ = ["Module", "Type", "member"]
+
+from framer import struct, template
+from framer.function import Function, Method
+from framer.member import member
+from framer.slots import *
+from framer.util import cstring, unindent
+
+from types import FunctionType
+
+def sortitems(dict):
+    L = dict.items()
+    L.sort()
+    return L
+
+# The Module and Type classes are implemented using metaclasses,
+# because most of the methods are class methods.  It is easier to use
+# metaclasses than the cumbersome classmethod() builtin.  They have
+# class methods because they are exposed to user code as base classes.
+
+class BaseMetaclass(type):
+    """Shared infrastructure for generating modules and types."""
+
+    # just methoddef so far
+
+    def dump_methoddef(self, f, functions, vars):
+        def p(templ, vars=vars): # helper function to generate output
+            print >> f, templ % vars
+
+        if not functions:
+            return
+        p(template.methoddef_start)
+        for name, func in sortitems(functions):
+            if func.__doc__:
+                p(template.methoddef_def_doc, func.vars)
+            else:
+                p(template.methoddef_def, func.vars)
+        p(template.methoddef_end)
+
+class ModuleMetaclass(BaseMetaclass):
+    """Provides methods for Module class."""
+
+    def gen(self):
+        self.analyze()
+        self.initvars()
+        f = open(self.__filename, "w")
+        self.dump(f)
+        f.close()
+
+    def analyze(self):
+        self.name = getattr(self, "abbrev", self.__name__)
+        self.__functions = {}
+        self.__types = {}
+        self.__members = False
+
+        for name, obj in self.__dict__.iteritems():
+            if isinstance(obj, FunctionType):
+                self.__functions[name] = Function(obj, self)
+            elif isinstance(obj, TypeMetaclass):
+                obj._TypeMetaclass__module = self.name
+                obj.analyze()
+                self.__types[name] = obj
+                if obj.has_members():
+                    self.__members = True
+
+    def initvars(self):
+        v = self.__vars = {}
+        filename = getattr(self, "__file__", None)
+        if filename is None:
+            filename = self.__name__ + "module.c"
+        self.__filename = v["FileName"] = filename
+        name = v["ModuleName"] = self.__name__
+        v["MethodDefName"] = "%s_methods" % name
+        v["ModuleDocstring"] = cstring(unindent(self.__doc__))
+
+    def dump(self, f):
+        def p(templ, vars=self.__vars): # helper function to generate output
+            print >> f, templ % vars
+
+        p(template.module_start)
+        if self.__members:
+            p(template.member_include)
+        print >> f
+
+        if self.__doc__:
+            p(template.module_doc)
+
+        for name, type in sortitems(self.__types):
+            type.dump(f)
+
+        for name, func  in sortitems(self.__functions):
+            func.dump(f)
+
+        self.dump_methoddef(f, self.__functions, self.__vars)
+
+        p(template.module_init_start)
+        for name, type in sortitems(self.__types):
+            type.dump_init(f)
+
+        p("}")
+
+class Module:
+    __metaclass__ = ModuleMetaclass
+
+class TypeMetaclass(BaseMetaclass):
+
+    def dump(self, f):
+        self.initvars()
+
+        # defined after initvars() so that __vars is defined
+        def p(templ, vars=self.__vars):
+            print >> f, templ % vars
+
+        if self.struct is not None:
+            print >> f, unindent(self.struct, False)
+
+        if self.__doc__:
+            p(template.docstring)
+
+        for name, func in sortitems(self.__methods):
+            func.dump(f)
+
+        self.dump_methoddef(f, self.__methods, self.__vars)
+        self.dump_memberdef(f)
+        self.dump_slots(f)
+
+    def has_members(self):
+        if self.__members:
+            return True
+        else:
+            return False
+
+    def analyze(self):
+        # called by ModuleMetaclass analyze()
+        self.name = getattr(self, "abbrev", self.__name__)
+        src = getattr(self, "struct", None)
+        if src is not None:
+            self.__struct = struct.parse(src)
+        else:
+            self.__struct = None
+        self.__methods = {}
+        self.__members = {}
+        for cls in self.__mro__:
+            for k, v in cls.__dict__.iteritems():
+                if isinstance(v, FunctionType):
+                    self.__methods[k] = Method(v, self)
+                if isinstance(v, member):
+                    self.__members[k] = v
+                    assert self.__struct is not None
+                    v.register(k, self.__struct)
+        self.analyze_slots()
+
+    def analyze_slots(self):
+        self.__slots = {}
+        for s in Slots:
+            if s.special is not None:
+                meth = self.__methods.get(s.special)
+                if meth is not None:
+                    self.__slots[s] = meth
+        self.__slots[TP_NAME] = '"%s.%s"' % (self.__module, self.__name__)
+        if self.__doc__:
+            self.__slots[TP_DOC] = "%s_doc" % self.name
+        if self.__struct is not None:
+            self.__slots[TP_BASICSIZE] = "sizeof(%s)" % self.__struct.name
+            self.__slots[TP_DEALLOC] = "%s_dealloc" % self.name
+        if self.__methods:
+            self.__slots[TP_METHODS] = "%s_methods" % self.name
+        if self.__members:
+            self.__slots[TP_MEMBERS] = "%s_members" % self.name
+
+    def initvars(self):
+        v = self.__vars = {}
+        v["TypeName"] = self.__name__
+        v["CTypeName"] = "Py%s_Type" % self.__name__
+        v["MethodDefName"] = self.__slots[TP_METHODS]
+        if self.__doc__:
+            v["DocstringVar"] = self.__slots[TP_DOC]
+            v["Docstring"] = cstring(unindent(self.__doc__))
+        if self.__struct is not None:
+            v["StructName"] = self.__struct.name
+        if self.__members:
+            v["MemberDefName"] = self.__slots[TP_MEMBERS]
+
+    def dump_memberdef(self, f):
+        def p(templ, vars=self.__vars):
+            print >> f, templ % vars
+
+        if not self.__members:
+            return
+        p(template.memberdef_start)
+        for name, slot in sortitems(self.__members):
+            slot.dump(f)
+        p(template.memberdef_end)
+
+    def dump_slots(self, f):
+        def p(templ, vars=self.__vars):
+            print >> f, templ % vars
+
+        if self.struct:
+            p(template.dealloc_func, {"name" : self.__slots[TP_DEALLOC]})
+
+        p(template.type_struct_start)
+        for s in Slots[:-5]: # XXX
+            val = self.__slots.get(s, s.default)
+            ntabs = 4 - (4 + len(val)) / 8
+            line = "        %s,%s/* %s */" % (val, "\t" * ntabs, s.name)
+            print >> f, line
+        p(template.type_struct_end)
+
+    def dump_init(self, f):
+        def p(templ):
+            print >> f, templ % self.__vars
+
+        p(template.type_init_type)
+        p(template.module_add_type)
+
+class Type:
+    __metaclass__ = TypeMetaclass

Added: vendor/Python/current/Tools/framer/framer/function.py
===================================================================
--- vendor/Python/current/Tools/framer/framer/function.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/framer/framer/function.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,173 @@
+"""Functions."""
+
+from framer import template
+from framer.util import cstring, unindent
+
+METH_O = "METH_O"
+METH_NOARGS = "METH_NOARGS"
+METH_VARARGS = "METH_VARARGS"
+
+def parsefmt(fmt):
+    for c in fmt:
+        if c == '|':
+            continue
+        yield c
+
+class Argument:
+
+    def __init__(self, name):
+        self.name = name
+        self.ctype = "PyObject *"
+        self.default = None
+
+    def __str__(self):
+        return "%s%s" % (self.ctype, self.name)
+
+    def setfmt(self, code):
+        self.ctype = self._codes[code]
+        if self.ctype[-1] != "*":
+            self.ctype += " "
+
+    _codes = {"O": "PyObject *",
+              "i": "int",
+              }
+
+    def decl(self):
+        if self.default is None:
+            return str(self) + ";"
+        else:
+            return "%s = %s;" % (self, self.default)
+
+class _ArgumentList(object):
+
+    # these instance variables should be initialized by subclasses
+    ml_meth = None
+    fmt = None
+
+    def __init__(self, args):
+        self.args = map(Argument, args)
+
+    def __len__(self):
+        return len(self.args)
+
+    def __getitem__(self, i):
+        return self.args[i]
+
+    def dump_decls(self, f):
+        pass
+
+class NoArgs(_ArgumentList):
+
+    def __init__(self, args):
+        assert len(args) == 0
+        super(NoArgs, self).__init__(args)
+        self.ml_meth = METH_NOARGS
+
+    def c_args(self):
+        return "PyObject *self"
+
+class OneArg(_ArgumentList):
+
+    def __init__(self, args):
+        assert len(args) == 1
+        super(OneArg, self).__init__(args)
+        self.ml_meth = METH_O
+
+    def c_args(self):
+        return "PyObject *self, %s" % self.args[0]
+
+class VarArgs(_ArgumentList):
+
+    def __init__(self, args, fmt=None):
+        super(VarArgs, self).__init__(args)
+        self.ml_meth = METH_VARARGS
+        if fmt is not None:
+            self.fmt = fmt
+            i = 0
+            for code in parsefmt(fmt):
+                self.args[i].setfmt(code)
+                i += 1
+
+    def c_args(self):
+        return "PyObject *self, PyObject *args"
+
+    def targets(self):
+        return ", ".join(["&%s" % a.name for a in self.args])
+
+    def dump_decls(self, f):
+        for a in self.args:
+            print >> f, "        %s" % a.decl()
+
+def ArgumentList(func, method):
+    code = func.func_code
+    args = code.co_varnames[:code.co_argcount]
+    if method:
+        args = args[1:]
+    pyarg = getattr(func, "pyarg", None)
+    if pyarg is not None:
+        args = VarArgs(args, pyarg)
+        if func.func_defaults:
+            L = list(func.func_defaults)
+            ndefault = len(L)
+            i = len(args) - ndefault
+            while L:
+                args[i].default = L.pop(0)
+        return args
+    else:
+        if len(args) == 0:
+            return NoArgs(args)
+        elif len(args) == 1:
+            return OneArg(args)
+        else:
+            return VarArgs(args)
+
+class Function:
+
+    method = False
+
+    def __init__(self, func, parent):
+        self._func = func
+        self._parent = parent
+        self.analyze()
+        self.initvars()
+
+    def dump(self, f):
+        def p(templ, vars=None): # helper function to generate output
+            if vars is None:
+                vars = self.vars
+            print >> f, templ % vars
+
+        if self.__doc__:
+            p(template.docstring)
+
+        d = {"name" : self.vars["CName"],
+             "args" : self.args.c_args(),
+             }
+        p(template.funcdef_start, d)
+
+        self.args.dump_decls(f)
+
+        if self.args.ml_meth == METH_VARARGS:
+            p(template.varargs)
+
+        p(template.funcdef_end)
+
+    def analyze(self):
+        self.__doc__ = self._func.__doc__
+        self.args = ArgumentList(self._func, self.method)
+
+    def initvars(self):
+        v = self.vars = {}
+        v["PythonName"] = self._func.__name__
+        s = v["CName"] = "%s_%s" % (self._parent.name, self._func.__name__)
+        v["DocstringVar"] = s + "_doc"
+        v["MethType"] = self.args.ml_meth
+        if self.__doc__:
+            v["Docstring"] = cstring(unindent(self.__doc__))
+        if self.args.fmt is not None:
+            v["ArgParse"] = self.args.fmt
+            v["ArgTargets"] = self.args.targets()
+
+class Method(Function):
+
+    method = True

Added: vendor/Python/current/Tools/framer/framer/member.py
===================================================================
--- vendor/Python/current/Tools/framer/framer/member.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/framer/framer/member.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,73 @@
+from framer import template
+from framer.util import cstring, unindent
+
+T_SHORT = "T_SHORT"
+T_INT = "T_INT"
+T_LONG = "T_LONG"
+T_FLOAT = "T_FLOAT"
+T_DOUBLE = "T_DOUBLE"
+T_STRING = "T_STRING"
+T_OBJECT = "T_OBJECT"
+T_CHAR = "T_CHAR"
+T_BYTE = "T_BYTE"
+T_UBYTE = "T_UBYTE"
+T_UINT = "T_UINT"
+T_ULONG = "T_ULONG"
+T_STRING_INPLACE = "T_STRING_INPLACE"
+T_OBJECT_EX = "T_OBJECT_EX"
+
+RO = READONLY = "READONLY"
+READ_RESTRICTED = "READ_RESTRICTED"
+WRITE_RESTRICTED = "WRITE_RESTRICTED"
+RESTRICT = "RESTRICTED"
+
+c2t = {"int" : T_INT,
+       "unsigned int" : T_UINT,
+       "long" : T_LONG,
+       "unsigned long" : T_LONG,
+       "float" : T_FLOAT,
+       "double" : T_DOUBLE,
+       "char *" : T_CHAR,
+       "PyObject *" : T_OBJECT,
+       }
+
+class member(object):
+
+    def __init__(self, cname=None, type=None, flags=None, doc=None):
+        self.type = type
+        self.flags = flags
+        self.cname = cname
+        self.doc = doc
+        self.name = None
+        self.struct = None
+
+    def register(self, name, struct):
+        self.name = name
+        self.struct = struct
+        self.initvars()
+
+    def initvars(self):
+        v = self.vars = {}
+        v["PythonName"] = self.name
+        if self.cname is not None:
+            v["CName"] = self.cname
+        else:
+            v["CName"] = self.name
+        v["Flags"] = self.flags or "0"
+        v["Type"] = self.get_type()
+        if self.doc is not None:
+            v["Docstring"] = cstring(unindent(self.doc))
+        v["StructName"] = self.struct.name
+
+    def get_type(self):
+        """Deduce type code from struct specification if not defined"""
+        if self.type is not None:
+            return self.type
+        ctype = self.struct.get_type(self.name)
+        return c2t[ctype]
+
+    def dump(self, f):
+        if self.doc is None:
+            print >> f, template.memberdef_def % self.vars
+        else:
+            print >> f, template.memberdef_def_doc % self.vars

Added: vendor/Python/current/Tools/framer/framer/slots.py
===================================================================
--- vendor/Python/current/Tools/framer/framer/slots.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/framer/framer/slots.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,64 @@
+"""Descriptions of all the slots in Python's type objects."""
+
+class Slot(object):
+    def __init__(self, name, cast=None, special=None, default="0"):
+        self.name = name
+        self.cast = cast
+        self.special = special
+        self.default = default
+
+Slots = (Slot("ob_size"),
+         Slot("tp_name"),
+         Slot("tp_basicsize"),
+         Slot("tp_itemsize"),
+         Slot("tp_dealloc", "destructor"),
+         Slot("tp_print", "printfunc"),
+         Slot("tp_getattr", "getattrfunc"),
+         Slot("tp_setattr", "setattrfunc"),
+         Slot("tp_compare", "cmpfunc", "__cmp__"),
+         Slot("tp_repr", "reprfunc", "__repr__"),
+         Slot("tp_as_number"),
+         Slot("tp_as_sequence"),
+         Slot("tp_as_mapping"),
+         Slot("tp_hash", "hashfunc", "__hash__"),
+         Slot("tp_call", "ternaryfunc", "__call__"),
+         Slot("tp_str", "reprfunc", "__str__"),
+         Slot("tp_getattro", "getattrofunc", "__getattr__", # XXX
+              "PyObject_GenericGetAttr"),
+         Slot("tp_setattro", "setattrofunc", "__setattr__"),
+         Slot("tp_as_buffer"),
+         Slot("tp_flags", default="Py_TPFLAGS_DEFAULT"),
+         Slot("tp_doc"),
+         Slot("tp_traverse", "traverseprox"),
+         Slot("tp_clear", "inquiry"),
+         Slot("tp_richcompare", "richcmpfunc"),
+         Slot("tp_weaklistoffset"),
+         Slot("tp_iter", "getiterfunc", "__iter__"),
+         Slot("tp_iternext", "iternextfunc", "__next__"), # XXX
+         Slot("tp_methods"),
+         Slot("tp_members"),
+         Slot("tp_getset"),
+         Slot("tp_base"),
+         Slot("tp_dict"),
+         Slot("tp_descr_get", "descrgetfunc"),
+         Slot("tp_descr_set", "descrsetfunc"),
+         Slot("tp_dictoffset"),
+         Slot("tp_init", "initproc", "__init__"),
+         Slot("tp_alloc", "allocfunc"),
+         Slot("tp_new", "newfunc"),
+         Slot("tp_free", "freefunc"),
+         Slot("tp_is_gc", "inquiry"),
+         Slot("tp_bases"),
+         Slot("tp_mro"),
+         Slot("tp_cache"),
+         Slot("tp_subclasses"),
+         Slot("tp_weaklist"),
+         )
+
+# give some slots symbolic names
+TP_NAME = Slots[1]
+TP_BASICSIZE = Slots[2]
+TP_DEALLOC = Slots[4]
+TP_DOC = Slots[20]
+TP_METHODS = Slots[27]
+TP_MEMBERS = Slots[28]

Added: vendor/Python/current/Tools/framer/framer/struct.py
===================================================================
--- vendor/Python/current/Tools/framer/framer/struct.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/framer/framer/struct.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,52 @@
+"""Rudimentary parser for C struct definitions."""
+
+import re
+
+PyObject_HEAD = "PyObject_HEAD"
+PyObject_VAR_HEAD = "PyObject_VAR_HEAD"
+
+rx_name = re.compile("} (\w+);")
+
+class Struct:
+    def __init__(self, name, head, members):
+        self.name = name
+        self.head = head
+        self.members = members
+
+    def get_type(self, name):
+        for _name, type in self.members:
+            if name == _name:
+                return type
+        raise ValueError, "no member named %s" % name
+
+def parse(s):
+    """Parse a C struct definition.
+
+    The parser is very restricted in what it will accept.
+    """
+
+    lines = filter(None, s.split("\n")) # get non-empty lines
+    assert lines[0].strip() == "typedef struct {"
+    pyhead = lines[1].strip()
+    assert (pyhead.startswith("PyObject") and
+            pyhead.endswith("HEAD"))
+    members = []
+    for line in lines[2:]:
+        line = line.strip()
+        if line.startswith("}"):
+            break
+
+        assert line.endswith(";")
+        line = line[:-1]
+        words = line.split()
+        name = words[-1]
+        type = " ".join(words[:-1])
+        if name[0] == "*":
+            name = name[1:]
+            type += " *"
+        members.append((name, type))
+    name = None
+    mo = rx_name.search(line)
+    assert mo is not None
+    name = mo.group(1)
+    return Struct(name, pyhead, members)

Added: vendor/Python/current/Tools/framer/framer/structparse.py
===================================================================
--- vendor/Python/current/Tools/framer/framer/structparse.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/framer/framer/structparse.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,46 @@
+"""Rudimentary parser for C struct definitions."""
+
+import re
+
+PyObject_HEAD = "PyObject_HEAD"
+PyObject_VAR_HEAD = "PyObject_VAR_HEAD"
+
+rx_name = re.compile("} (\w+);")
+
+class Struct:
+    def __init__(self, name, head, members):
+        self.name = name
+        self.head = head
+        self.members = members
+
+def parse(s):
+    """Parse a C struct definition.
+
+    The parser is very restricted in what it will accept.
+    """
+
+    lines = filter(None, s.split("\n")) # get non-empty lines
+    assert lines[0].strip() == "typedef struct {"
+    pyhead = lines[1].strip()
+    assert (pyhead.startswith("PyObject") and
+            pyhead.endswith("HEAD"))
+    members = []
+    for line in lines[2:]:
+        line = line.strip()
+        if line.startswith("}"):
+            break
+
+        assert line.endswith(";")
+        line = line[:-1]
+        words = line.split()
+        name = words[-1]
+        type = " ".join(words[:-1])
+        if name[0] == "*":
+            name = name[1:]
+            type += " *"
+        members.append((name, type))
+    name = None
+    mo = rx_name.search(line)
+    assert mo is not None
+    name = mo.group(1)
+    return Struct(name, pyhead, members)

Added: vendor/Python/current/Tools/framer/framer/template.py
===================================================================
--- vendor/Python/current/Tools/framer/framer/template.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/framer/framer/template.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,102 @@
+"""framer's C code templates.
+
+Templates use the following variables:
+
+FileName: name of the file that contains the C source code
+ModuleName: name of the module, as in "import ModuleName"
+ModuleDocstring: C string containing the module doc string
+"""
+
+module_start = '#include "Python.h"'
+member_include = '#include "structmember.h"'
+
+module_doc = """\
+PyDoc_STRVAR(%(ModuleName)s_doc,
+%(ModuleDocstring)s);
+"""
+
+methoddef_start = """\
+static struct PyMethodDef %(MethodDefName)s[] = {"""
+
+methoddef_def = """\
+        {"%(PythonName)s", (PyCFunction)%(CName)s, %(MethType)s},"""
+
+methoddef_def_doc = """\
+        {"%(PythonName)s", (PyCFunction)%(CName)s, %(MethType)s,
+         %(DocstringVar)s},"""
+
+methoddef_end = """\
+        {NULL, NULL}
+};
+"""
+
+memberdef_start = """\
+#define OFF(X) offsetof(%(StructName)s, X)
+
+static struct PyMemberDef %(MemberDefName)s[] = {"""
+
+memberdef_def_doc = """\
+        {"%(PythonName)s", %(Type)s, OFF(%(CName)s), %(Flags)s,
+         %(Docstring)s},"""
+
+memberdef_def = """\
+        {"%(PythonName)s", %(Type)s, OFF(%(CName)s), %(Flags)s},"""
+
+memberdef_end = """\
+        {NULL}
+};
+
+#undef OFF
+"""
+
+dealloc_func = """static void
+%(name)s(PyObject *ob)
+{
+}
+"""
+
+docstring = """\
+PyDoc_STRVAR(%(DocstringVar)s,
+%(Docstring)s);
+"""
+
+funcdef_start = """\
+static PyObject *
+%(name)s(%(args)s)
+{"""
+
+funcdef_end = """\
+}
+"""
+
+varargs = """\
+        if (!PyArg_ParseTuple(args, \"%(ArgParse)s:%(PythonName)s\",
+                              %(ArgTargets)s))
+                return NULL;"""
+
+module_init_start = """\
+PyMODINIT_FUNC
+init%(ModuleName)s(void)
+{
+        PyObject *mod;
+
+        mod = Py_InitModule3("%(ModuleName)s", %(MethodDefName)s,
+                             %(ModuleName)s_doc);
+        if (mod == NULL)
+                return;
+"""
+
+type_init_type = "        %(CTypeName)s.ob_type = &PyType_Type;"
+module_add_type = """\
+        if (!PyObject_SetAttrString(mod, "%(TypeName)s",
+                                    (PyObject *)&%(CTypeName)s))
+                return;
+"""
+
+type_struct_start = """\
+static PyTypeObject %(CTypeName)s = {
+        PyObject_HEAD_INIT(0)"""
+
+type_struct_end = """\
+};
+"""

Added: vendor/Python/current/Tools/framer/framer/util.py
===================================================================
--- vendor/Python/current/Tools/framer/framer/util.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/framer/framer/util.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,35 @@
+def cstring(s, width=70):
+    """Return C string representation of a Python string.
+
+    width specifies the maximum width of any line of the C string.
+    """
+    L = []
+    for l in s.split("\n"):
+        if len(l) < width:
+            L.append(r'"%s\n"' % l)
+
+    return "\n".join(L)
+
+def unindent(s, skipfirst=True):
+    """Return an unindented version of a docstring.
+
+    Removes indentation on lines following the first one, using the
+    leading whitespace of the first indented line that is not blank
+    to determine the indentation.
+    """
+
+    lines = s.split("\n")
+    if skipfirst:
+        first = lines.pop(0)
+        L = [first]
+    else:
+        L = []
+    indent = None
+    for l in lines:
+        ls = l.strip()
+        if ls:
+            indent = len(l) - len(ls)
+            break
+    L += [l[indent:] for l in lines]
+
+    return "\n".join(L)

Added: vendor/Python/current/Tools/freeze/README
===================================================================
--- vendor/Python/current/Tools/freeze/README	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/freeze/README	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,296 @@
+THE FREEZE SCRIPT
+=================
+
+(Directions for Windows are at the end of this file.)
+
+
+What is Freeze?
+---------------
+
+Freeze make it possible to ship arbitrary Python programs to people
+who don't have Python.  The shipped file (called a "frozen" version of
+your Python program) is an executable, so this only works if your
+platform is compatible with that on the receiving end (this is usually
+a matter of having the same major operating system revision and CPU
+type).
+
+The shipped file contains a Python interpreter and large portions of
+the Python run-time.  Some measures have been taken to avoid linking
+unneeded modules, but the resulting binary is usually not small.
+
+The Python source code of your program (and of the library modules
+written in Python that it uses) is not included in the binary --
+instead, the compiled byte-code (the instruction stream used
+internally by the interpreter) is incorporated.  This gives some
+protection of your Python source code, though not much -- a
+disassembler for Python byte-code is available in the standard Python
+library.  At least someone running "strings" on your binary won't see
+the source.
+
+
+How does Freeze know which modules to include?
+----------------------------------------------
+
+Previous versions of Freeze used a pretty simple-minded algorithm to
+find the modules that your program uses, essentially searching for
+lines starting with the word "import".  It was pretty easy to trick it
+into making mistakes, either missing valid import statements, or
+mistaking string literals (e.g. doc strings) for import statements.
+
+This has been remedied: Freeze now uses the regular Python parser to
+parse the program (and all its modules) and scans the generated byte
+code for IMPORT instructions.  It may still be confused -- it will not
+know about calls to the __import__ built-in function, or about import
+statements constructed on the fly and executed using the 'exec'
+statement, and it will consider import statements even when they are
+unreachable (e.g. "if 0: import foobar").
+
+This new version of Freeze also knows about Python's new package
+import mechanism, and uses exactly the same rules to find imported
+modules and packages.  One exception: if you write 'from package
+import *', Python will look into the __all__ variable of the package
+to determine which modules are to be imported, while Freeze will do a
+directory listing.
+
+One tricky issue: Freeze assumes that the Python interpreter and
+environment you're using to run Freeze is the same one that would be
+used to run your program, which should also be the same whose sources
+and installed files you will learn about in the next section.  In
+particular, your PYTHONPATH setting should be the same as for running
+your program locally.  (Tip: if the program doesn't run when you type
+"python hello.py" there's little chance of getting the frozen version
+to run.)
+
+
+How do I use Freeze?
+--------------------
+
+Normally, you should be able to use it as follows:
+
+	python freeze.py hello.py
+
+where hello.py is your program and freeze.py is the main file of
+Freeze (in actuality, you'll probably specify an absolute pathname
+such as /usr/joe/python/Tools/freeze/freeze.py).
+
+
+What do I do next?
+------------------
+
+Freeze creates a number of files: frozen.c, config.c and Makefile,
+plus one file for each Python module that gets included named
+M_<module>.c.  To produce the frozen version of your program, you can
+simply type "make".  This should produce a binary file.  If the
+filename argument to Freeze was "hello.py", the binary will be called
+"hello".
+
+Note: you can use the -o option to freeze to specify an alternative
+directory where these files are created. This makes it easier to
+clean up after you've shipped the frozen binary.  You should invoke
+"make" in the given directory.
+
+
+Freezing Tkinter programs
+-------------------------
+
+Unfortunately, it is currently not possible to freeze programs that
+use Tkinter without a Tcl/Tk installation. The best way to ship a
+frozen Tkinter program is to decide in advance where you are going
+to place the Tcl and Tk library files in the distributed setup, and
+then declare these directories in your frozen Python program using
+the TCL_LIBRARY, TK_LIBRARY and TIX_LIBRARY environment variables.
+
+For example, assume you will ship your frozen program in the directory 
+<root>/bin/windows-x86 and will place your Tcl library files 
+in <root>/lib/tcl8.2 and your Tk library files in <root>/lib/tk8.2. Then
+placing the following lines in your frozen Python script before importing
+Tkinter or Tix would set the environment correctly for Tcl/Tk/Tix:
+
+import os
+import os.path
+RootDir = os.path.dirname(os.path.dirname(os.getcwd()))
+
+import sys
+if sys.platform == "win32":
+   sys.path = ['', '..\\..\\lib\\python-2.0']
+   os.environ['TCL_LIBRARY'] = RootDir + '\\lib\\tcl8.2'
+   os.environ['TK_LIBRARY'] = RootDir + '\\lib\\tk8.2'
+   os.environ['TIX_LIBRARY'] = RootDir + '\\lib\\tix8.1'
+elif sys.platform == "linux2":
+   sys.path = ['', '../../lib/python-2.0']
+   os.environ['TCL_LIBRARY'] = RootDir + '/lib/tcl8.2'
+   os.environ['TK_LIBRARY'] = RootDir + '/lib/tk8.2'
+   os.environ['TIX_LIBRARY'] = RootDir + '/lib/tix8.1'
+elif sys.platform == "solaris":
+   sys.path = ['', '../../lib/python-2.0']
+   os.environ['TCL_LIBRARY'] = RootDir + '/lib/tcl8.2'
+   os.environ['TK_LIBRARY'] = RootDir + '/lib/tk8.2'
+   os.environ['TIX_LIBRARY'] = RootDir + '/lib/tix8.1'
+
+This also adds <root>/lib/python-2.0 to your Python path
+for any Python files such as _tkinter.pyd you may need.
+
+Note that the dynamic libraries (such as tcl82.dll tk82.dll python20.dll
+under Windows, or libtcl8.2.so and libtcl8.2.so under Unix) are required
+at program load time, and are searched by the operating system loader
+before Python can be started. Under Windows, the environment
+variable PATH is consulted, and under Unix, it may be the
+environment variable LD_LIBRARY_PATH and/or the system
+shared library cache (ld.so). An additional preferred directory for
+finding the dynamic libraries is built into the .dll or .so files at
+compile time - see the LIB_RUNTIME_DIR variable in the Tcl makefile. 
+The OS must find the dynamic libraries or your frozen program won't start. 
+Usually I make sure that the .so or .dll files are in the same directory
+as the executable, but this may not be foolproof.
+
+A workaround to installing your Tcl library files with your frozen
+executable would be possible, in which the Tcl/Tk library files are
+incorporated in a frozen Python module as string literals and written
+to a temporary location when the program runs; this is currently left
+as an exercise for the reader.  An easier approach is to freeze the
+Tcl/Tk/Tix code into the dynamic libraries using the Tcl ET code,
+or the Tix Stand-Alone-Module code. Of course, you can also simply 
+require that Tcl/Tk is required on the target installation, but be 
+careful that the version corresponds.
+
+There are some caveats using frozen Tkinter applications:
+	Under Windows if you use the -s windows option, writing
+to stdout or stderr is an error.
+	The Tcl [info nameofexecutable] will be set to where the
+program was frozen, not where it is run from.
+	The global variables argc and argv do not exist.
+
+
+A warning about shared library modules
+--------------------------------------
+
+When your Python installation uses shared library modules such as 
+_tkinter.pyd, these will not be incorporated in the frozen program.
+ Again, the frozen program will work when you test it, but it won't
+ work when you ship it to a site without a Python installation.
+
+Freeze prints a warning when this is the case at the end of the
+freezing process:
+
+	Warning: unknown modules remain: ...
+
+When this occurs, the best thing to do is usually to rebuild Python
+using static linking only. Or use the approach described in the previous
+section to declare a library path using sys.path, and place the modules
+such as _tkinter.pyd there.
+
+
+Troubleshooting
+---------------
+
+If you have trouble using Freeze for a large program, it's probably
+best to start playing with a really simple program first (like the file
+hello.py).  If you can't get that to work there's something
+fundamentally wrong -- perhaps you haven't installed Python.  To do a
+proper install, you should do "make install" in the Python root
+directory.
+
+
+Usage under Windows 95 or NT
+----------------------------
+
+Under Windows 95 or NT, you *must* use the -p option and point it to
+the top of the Python source tree.
+
+WARNING: the resulting executable is not self-contained; it requires
+the Python DLL, currently PYTHON20.DLL (it does not require the
+standard library of .py files though).  It may also require one or
+more extension modules loaded from .DLL or .PYD files; the module
+names are printed in the warning message about remaining unknown
+modules.
+
+The driver script generates a Makefile that works with the Microsoft
+command line C compiler (CL).  To compile, run "nmake"; this will
+build a target "hello.exe" if the source was "hello.py".  Only the
+files frozenmain.c and frozen.c are used; no config.c is generated or
+used, since the standard DLL is used.
+
+In order for this to work, you must have built Python using the VC++
+(Developer Studio) 5.0 compiler.  The provided project builds
+python20.lib in the subdirectory pcbuild\Release of thje Python source
+tree, and this is where the generated Makefile expects it to be.  If
+this is not the case, you can edit the Makefile or (probably better)
+winmakemakefile.py (e.g., if you are using the 4.2 compiler, the
+python20.lib file is generated in the subdirectory vc40 of the Python
+source tree).
+
+It is possible to create frozen programs that don't have a console
+window, by specifying the option '-s windows'. See the Usage below.
+
+Usage
+-----
+
+Here is a list of all of the options (taken from freeze.__doc__):
+
+usage: freeze [options...] script [module]...
+
+Options:
+-p prefix:    This is the prefix used when you ran ``make install''
+              in the Python build directory.
+              (If you never ran this, freeze won't work.)
+              The default is whatever sys.prefix evaluates to.
+              It can also be the top directory of the Python source
+              tree; then -P must point to the build tree.
+
+-P exec_prefix: Like -p but this is the 'exec_prefix', used to
+                install objects etc.  The default is whatever sys.exec_prefix
+                evaluates to, or the -p argument if given.
+                If -p points to the Python source tree, -P must point
+                to the build tree, if different.
+
+-e extension: A directory containing additional .o files that
+              may be used to resolve modules.  This directory
+              should also have a Setup file describing the .o files.
+              On Windows, the name of a .INI file describing one
+              or more extensions is passed.
+              More than one -e option may be given.
+
+-o dir:       Directory where the output files are created; default '.'.
+
+-m:           Additional arguments are module names instead of filenames.
+
+-a package=dir: Additional directories to be added to the package's
+                __path__.  Used to simulate directories added by the
+                package at runtime (eg, by OpenGL and win32com).
+                More than one -a option may be given for each package.
+
+-l file:      Pass the file to the linker (windows only)
+
+-d:           Debugging mode for the module finder.
+
+-q:           Make the module finder totally quiet.
+
+-h:           Print this help message.
+
+-x module     Exclude the specified module.
+
+-i filename:  Include a file with additional command line options.  Used
+              to prevent command lines growing beyond the capabilities of
+              the shell/OS.  All arguments specified in filename
+              are read and the -i option replaced with the parsed
+              params (note - quoting args in this file is NOT supported)
+
+-s subsystem: Specify the subsystem (For Windows only.); 
+              'console' (default), 'windows', 'service' or 'com_dll'
+              
+-w:           Toggle Windows (NT or 95) behavior.
+              (For debugging only -- on a win32 platform, win32 behavior
+              is automatic.)
+
+Arguments:
+
+script:       The Python script to be executed by the resulting binary.
+
+module ...:   Additional Python modules (referenced by pathname)
+              that will be included in the resulting binary.  These
+              may be .py or .pyc files.  If -m is specified, these are
+              module names that are search in the path instead.
+
+
+
+--Guido van Rossum (home page: http://www.python.org/~guido/)

Added: vendor/Python/current/Tools/freeze/bkfile.py
===================================================================
--- vendor/Python/current/Tools/freeze/bkfile.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/freeze/bkfile.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,47 @@
+_orig_open = open
+
+class _BkFile:
+    def __init__(self, file, mode, bufsize):
+        import os
+        self.__filename = file
+        self.__backup = file + '~'
+        try:
+            os.unlink(self.__backup)
+        except os.error:
+            pass
+        try:
+            os.rename(file, self.__backup)
+        except os.error:
+            self.__backup = None
+        self.__file = _orig_open(file, mode, bufsize)
+        self.closed = self.__file.closed
+        self.fileno = self.__file.fileno
+        self.flush = self.__file.flush
+        self.isatty = self.__file.isatty
+        self.mode = self.__file.mode
+        self.name = self.__file.name
+        self.read = self.__file.read
+        self.readinto = self.__file.readinto
+        self.readline = self.__file.readline
+        self.readlines = self.__file.readlines
+        self.seek = self.__file.seek
+        self.softspace = self.__file.softspace
+        self.tell = self.__file.tell
+        self.truncate = self.__file.truncate
+        self.write = self.__file.write
+        self.writelines = self.__file.writelines
+
+    def close(self):
+        self.__file.close()
+        if self.__backup is None:
+            return
+        import filecmp
+        if filecmp.cmp(self.__backup, self.__filename, shallow = 0):
+            import os
+            os.unlink(self.__filename)
+            os.rename(self.__backup, self.__filename)
+
+def open(file, mode = 'r', bufsize = -1):
+    if 'w' not in mode:
+        return _orig_open(file, mode, bufsize)
+    return _BkFile(file, mode, bufsize)

Added: vendor/Python/current/Tools/freeze/checkextensions.py
===================================================================
--- vendor/Python/current/Tools/freeze/checkextensions.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/freeze/checkextensions.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,90 @@
+# Check for a module in a set of extension directories.
+# An extension directory should contain a Setup file
+# and one or more .o files or a lib.a file.
+
+import os
+import parsesetup
+
+def checkextensions(unknown, extensions):
+    files = []
+    modules = []
+    edict = {}
+    for e in extensions:
+        setup = os.path.join(e, 'Setup')
+        liba = os.path.join(e, 'lib.a')
+        if not os.path.isfile(liba):
+            liba = None
+        edict[e] = parsesetup.getsetupinfo(setup), liba
+    for mod in unknown:
+        for e in extensions:
+            (mods, vars), liba = edict[e]
+            if not mods.has_key(mod):
+                continue
+            modules.append(mod)
+            if liba:
+                # If we find a lib.a, use it, ignore the
+                # .o files, and use *all* libraries for
+                # *all* modules in the Setup file
+                if liba in files:
+                    break
+                files.append(liba)
+                for m in mods.keys():
+                    files = files + select(e, mods, vars,
+                                           m, 1)
+                break
+            files = files + select(e, mods, vars, mod, 0)
+            break
+    return files, modules
+
+def select(e, mods, vars, mod, skipofiles):
+    files = []
+    for w in mods[mod]:
+        w = treatword(w)
+        if not w:
+            continue
+        w = expandvars(w, vars)
+        for w in w.split():
+            if skipofiles and w[-2:] == '.o':
+                continue
+            # Assume $var expands to absolute pathname
+            if w[0] not in ('-', '$') and w[-2:] in ('.o', '.a'):
+                w = os.path.join(e, w)
+            if w[:2] in ('-L', '-R') and w[2:3] != '$':
+                w = w[:2] + os.path.join(e, w[2:])
+            files.append(w)
+    return files
+
+cc_flags = ['-I', '-D', '-U']
+cc_exts = ['.c', '.C', '.cc', '.c++']
+
+def treatword(w):
+    if w[:2] in cc_flags:
+        return None
+    if w[:1] == '-':
+        return w # Assume loader flag
+    head, tail = os.path.split(w)
+    base, ext = os.path.splitext(tail)
+    if ext in cc_exts:
+        tail = base + '.o'
+        w = os.path.join(head, tail)
+    return w
+
+def expandvars(str, vars):
+    i = 0
+    while i < len(str):
+        i = k = str.find('$', i)
+        if i < 0:
+            break
+        i = i+1
+        var = str[i:i+1]
+        i = i+1
+        if var == '(':
+            j = str.find(')', i)
+            if j < 0:
+                break
+            var = str[i:j]
+            i = j+1
+        if vars.has_key(var):
+            str = str[:k] + vars[var] + str[i:]
+            i = k
+    return str

Added: vendor/Python/current/Tools/freeze/checkextensions_win32.py
===================================================================
--- vendor/Python/current/Tools/freeze/checkextensions_win32.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/freeze/checkextensions_win32.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,188 @@
+"""Extension management for Windows.
+
+Under Windows it is unlikely the .obj files are of use, as special compiler options
+are needed (primarily to toggle the behavior of "public" symbols.
+
+I dont consider it worth parsing the MSVC makefiles for compiler options.  Even if
+we get it just right, a specific freeze application may have specific compiler
+options anyway (eg, to enable or disable specific functionality)
+
+So my basic stragtegy is:
+
+* Have some Windows INI files which "describe" one or more extension modules.
+  (Freeze comes with a default one for all known modules - but you can specify
+  your own).
+* This description can include:
+  - The MSVC .dsp file for the extension.  The .c source file names
+    are extraced from there.
+  - Specific compiler/linker options
+  - Flag to indicate if Unicode compilation is expected.
+
+At the moment the name and location of this INI file is hardcoded,
+but an obvious enhancement would be to provide command line options.
+"""
+
+import os, sys
+try:
+    import win32api
+except ImportError:
+    win32api = None # User has already been warned
+
+class CExtension:
+    """An abstraction of an extension implemented in C/C++
+    """
+    def __init__(self, name, sourceFiles):
+        self.name = name
+        # A list of strings defining additional compiler options.
+        self.sourceFiles = sourceFiles
+        # A list of special compiler options to be applied to
+        # all source modules in this extension.
+        self.compilerOptions = []
+        # A list of .lib files the final .EXE will need.
+        self.linkerLibs = []
+
+    def GetSourceFiles(self):
+        return self.sourceFiles
+
+    def AddCompilerOption(self, option):
+        self.compilerOptions.append(option)
+    def GetCompilerOptions(self):
+        return self.compilerOptions
+
+    def AddLinkerLib(self, lib):
+        self.linkerLibs.append(lib)
+    def GetLinkerLibs(self):
+        return self.linkerLibs
+
+def checkextensions(unknown, extra_inis, prefix):
+    # Create a table of frozen extensions
+
+    defaultMapName = os.path.join( os.path.split(sys.argv[0])[0], "extensions_win32.ini")
+    if not os.path.isfile(defaultMapName):
+        sys.stderr.write("WARNING: %s can not be found - standard extensions may not be found\n" % defaultMapName)
+    else:
+        # must go on end, so other inis can override.
+        extra_inis.append(defaultMapName)
+
+    ret = []
+    for mod in unknown:
+        for ini in extra_inis:
+#                       print "Looking for", mod, "in", win32api.GetFullPathName(ini),"...",
+            defn = get_extension_defn( mod, ini, prefix )
+            if defn is not None:
+#                               print "Yay - found it!"
+                ret.append( defn )
+                break
+#                       print "Nope!"
+        else: # For not broken!
+            sys.stderr.write("No definition of module %s in any specified map file.\n" % (mod))
+
+    return ret
+
+def get_extension_defn(moduleName, mapFileName, prefix):
+    if win32api is None: return None
+    os.environ['PYTHONPREFIX'] = prefix
+    dsp = win32api.GetProfileVal(moduleName, "dsp", "", mapFileName)
+    if dsp=="":
+        return None
+
+    # We allow environment variables in the file name
+    dsp = win32api.ExpandEnvironmentStrings(dsp)
+    # If the path to the .DSP file is not absolute, assume it is relative
+    # to the description file.
+    if not os.path.isabs(dsp):
+        dsp = os.path.join( os.path.split(mapFileName)[0], dsp)
+    # Parse it to extract the source files.
+    sourceFiles = parse_dsp(dsp)
+    if sourceFiles is None:
+        return None
+
+    module = CExtension(moduleName, sourceFiles)
+    # Put the path to the DSP into the environment so entries can reference it.
+    os.environ['dsp_path'] = os.path.split(dsp)[0]
+    os.environ['ini_path'] = os.path.split(mapFileName)[0]
+
+    cl_options = win32api.GetProfileVal(moduleName, "cl", "", mapFileName)
+    if cl_options:
+        module.AddCompilerOption(win32api.ExpandEnvironmentStrings(cl_options))
+
+    exclude = win32api.GetProfileVal(moduleName, "exclude", "", mapFileName)
+    exclude = exclude.split()
+
+    if win32api.GetProfileVal(moduleName, "Unicode", 0, mapFileName):
+        module.AddCompilerOption('/D UNICODE /D _UNICODE')
+
+    libs = win32api.GetProfileVal(moduleName, "libs", "", mapFileName).split()
+    for lib in libs:
+        module.AddLinkerLib(win32api.ExpandEnvironmentStrings(lib))
+
+    for exc in exclude:
+        if exc in module.sourceFiles:
+            modules.sourceFiles.remove(exc)
+
+    return module
+
+# Given an MSVC DSP file, locate C source files it uses
+# returns a list of source files.
+def parse_dsp(dsp):
+#       print "Processing", dsp
+    # For now, only support
+    ret = []
+    dsp_path, dsp_name = os.path.split(dsp)
+    try:
+        lines = open(dsp, "r").readlines()
+    except IOError, msg:
+        sys.stderr.write("%s: %s\n" % (dsp, msg))
+        return None
+    for line in lines:
+        fields = line.strip().split("=", 2)
+        if fields[0]=="SOURCE":
+            if os.path.splitext(fields[1])[1].lower() in ['.cpp', '.c']:
+                ret.append( win32api.GetFullPathName(os.path.join(dsp_path, fields[1] ) ) )
+    return ret
+
+def write_extension_table(fname, modules):
+    fp = open(fname, "w")
+    try:
+        fp.write (ext_src_header)
+        # Write fn protos
+        for module in modules:
+            # bit of a hack for .pyd's as part of packages.
+            name = module.name.split('.')[-1]
+            fp.write('extern void init%s(void);\n' % (name) )
+        # Write the table
+        fp.write (ext_tab_header)
+        for module in modules:
+            name = module.name.split('.')[-1]
+            fp.write('\t{"%s", init%s},\n' % (name, name) )
+
+        fp.write (ext_tab_footer)
+        fp.write(ext_src_footer)
+    finally:
+        fp.close()
+
+
+ext_src_header = """\
+#include "Python.h"
+"""
+
+ext_tab_header = """\
+
+static struct _inittab extensions[] = {
+"""
+
+ext_tab_footer = """\
+        /* Sentinel */
+        {0, 0}
+};
+"""
+
+ext_src_footer = """\
+extern DL_IMPORT(int) PyImport_ExtendInittab(struct _inittab *newtab);
+
+int PyInitFrozenExtensions()
+{
+        return PyImport_ExtendInittab(extensions);
+}
+
+"""

Added: vendor/Python/current/Tools/freeze/extensions_win32.ini
===================================================================
--- vendor/Python/current/Tools/freeze/extensions_win32.ini	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/freeze/extensions_win32.ini	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,171 @@
+; This is a list of modules generally build as .pyd files.
+;
+; Each section contains enough information about a module for
+; freeze to include the module as a static, built-in module
+; in a frozen .EXE/.DLL.
+
+; This is all setup for all the win32 extension modules
+; released by Mark Hammond.
+; You must ensure that the environment variable PYTHONEX is set 
+; to point to the root win32 extensions directory
+
+; PYTHONPREFIX must point to the Python build root directory
+; (the *parent* of PCbuild); normally the freeze script takes
+; care of this.
+
+
+
+
+
+;--------------------------------------------------------------
+;
+; Standard Python extension modules
+;
+
+; Here are some of the standard Python extensions modules.
+; If you need others, add them here
+
+[_socket]
+dsp=%PYTHONPREFIX%\PCBuild\_socket.dsp
+
+[_sre]
+dsp=%PYTHONPREFIX%\PCBuild\_sre.dsp
+
+[unicodedata]
+dsp=%PYTHONPREFIX%\PCBuild\unicodedata.dsp
+
+[mmap]
+dsp=%PYTHONPREFIX%\PCBuild\mmap.dsp
+
+[winsound]
+dsp=%PYTHONPREFIX%\PCBuild\winsound.dsp
+libs=winmm.lib
+
+[parser]
+dsp=%PYTHONPREFIX%\PCBuild\parser.dsp
+
+[select]
+dsp=%PYTHONPREFIX%\PCBuild\select.dsp
+
+[zlib]
+dsp=%PYTHONPREFIX%\PCBuild\zlib.dsp
+cl=/I %PYTHONPREFIX%\..\zlib-1.1.4 /D _WINDOWS /D WIN32 
+libs=%PYTHONPREFIX%\..\zlib-1.1.4\zlib.lib /nodefaultlib:libc
+
+[_winreg]
+dsp=%PYTHONPREFIX%\PCBuild\winreg.dsp
+libs=advapi32.lib
+
+
+;--------------------------------------------------------------
+;
+; Win32 Projects.
+;
+[perfmon]
+dsp=%PYTHONEX%\win32\perfmon.dsp
+cl=/I %PYTHONEX%\win32\src
+Unicode=1
+
+[pywintypes]
+dsp=%PYTHONEX%\win32\pywintypes.dsp
+cl=/I %PYTHONEX%\win32\src
+libs=ole32.lib oleaut32.lib
+
+[win32api]
+dsp=%PYTHONEX%\win32\win32api.dsp
+cl=/I %PYTHONEX%\win32\src
+libs=kernel32.lib user32.lib shell32.lib advapi32.lib
+
+[win32service]
+dsp=%PYTHONEX%\win32\win32service.dsp
+cl=/I %PYTHONEX%\win32\src
+Unicode=1
+libs=advapi32.lib
+
+[win32evtlog]
+dsp=%PYTHONEX%\win32\win32evtlog.dsp
+cl=/I %PYTHONEX%\win32\src
+
+[win32process]
+dsp=%PYTHONEX%\win32\win32process.dsp
+cl=/I %PYTHONEX%\win32\src
+
+[win32event]
+dsp=%PYTHONEX%\win32\win32event.dsp
+cl=/I %PYTHONEX%\win32\src
+
+[win32file]
+dsp=%PYTHONEX%\win32\win32file.dsp 
+cl=/I %PYTHONEX%\win32\src
+
+[win32net]
+dsp=%PYTHONEX%\win32\win32net.dsp
+cl=/I %PYTHONEX%\win32\src
+libs=netapi32.lib
+
+[win32pdh]
+dsp=%PYTHONEX%\win32\win32pdh.dsp
+cl=/I %PYTHONEX%\win32\src
+
+[win32pipe]
+dsp=%PYTHONEX%\win32\win32pipe.dsp 
+cl=/I %PYTHONEX%\win32\src
+
+[win32security]
+dsp=%PYTHONEX%\win32\win32security.dsp
+cl=/I %PYTHONEX%\win32\src
+
+[win32service]
+dsp=%PYTHONEX%\win32\win32service.dsp
+cl=/I %PYTHONEX%\win32\src
+
+[win32trace]
+dsp=%PYTHONEX%\win32\win32trace.dsp
+cl=/I %PYTHONEX%\win32\src
+
+;--------------------------------------------------------------
+;
+; COM Projects.
+;
+
+[pythoncom]
+dsp=%PYTHONEX%\com\win32com.dsp
+cl=/I %PYTHONEX%\com\win32com\src\include /I %PYTHONEX%\win32\src
+libs=uuid.lib
+
+[win32com.axcontrol.axcontrol]
+dsp=%PYTHONEX%\com\axcontrol.dsp
+cl=/I %PYTHONEX%\win32\src /I %PYTHONEX%\com\win32com\src\include
+
+[win32com.axscript.axscript]
+dsp=%PYTHONEX%\com\Active Scripting.dsp
+cl=/I %PYTHONEX%\win32\src /I %PYTHONEX%\com\win32com\src\include
+
+[win32com.axdebug.axdebug]
+dsp=%PYTHONEX%\com\Active Debugging.dsp
+cl=/I %PYTHONEX%\win32\src /I %PYTHONEX%\com\win32com\src\include
+
+[win32com.mapi.mapi]
+dsp=%PYTHONEX%\com\mapi.dsp
+cl=/I %PYTHONEX%\win32\src /I %PYTHONEX%\com\win32com\src\include
+libs=MBLOGON.lib ADDRLKUP.LIB mapi32.lib version.lib
+
+[win32com.mapi.exchange]
+dsp=%PYTHONEX%\com\exchange.dsp
+cl=/I %PYTHONEX%\win32\src /I %PYTHONEX%\com\win32com\src\include
+libs=MBLOGON.lib ADDRLKUP.LIB exchinst.lib EDKCFG.LIB EDKUTILS.LIB EDKMAPI.LIB mapi32.lib version.lib
+
+[win32com.mapi.exchdapi]
+dsp=%PYTHONEX%\com\exchdapi.dsp
+cl=/I %PYTHONEX%\win32\src /I %PYTHONEX%\com\win32com\src\include
+libs=DAPI.LIB
+
+[servicemanager]
+dsp=%PYTHONEX%\win32\PythonService EXE.dsp
+Unicode = 1
+
+; Pythonwin
+[win32ui]
+dsp=%PYTHONEX%\Pythonwin\win32ui.dsp
+cl=/D _AFXDLL /D FREEZE_WIN32UI /GX /I %PYTHONEX%\win32\src
+libs=mfc42.lib

Added: vendor/Python/current/Tools/freeze/freeze.py
===================================================================
--- vendor/Python/current/Tools/freeze/freeze.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/freeze/freeze.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,497 @@
+#! /usr/bin/env python
+
+"""Freeze a Python script into a binary.
+
+usage: freeze [options...] script [module]...
+
+Options:
+-p prefix:    This is the prefix used when you ran ``make install''
+              in the Python build directory.
+              (If you never ran this, freeze won't work.)
+              The default is whatever sys.prefix evaluates to.
+              It can also be the top directory of the Python source
+              tree; then -P must point to the build tree.
+
+-P exec_prefix: Like -p but this is the 'exec_prefix', used to
+                install objects etc.  The default is whatever sys.exec_prefix
+                evaluates to, or the -p argument if given.
+                If -p points to the Python source tree, -P must point
+                to the build tree, if different.
+
+-e extension: A directory containing additional .o files that
+              may be used to resolve modules.  This directory
+              should also have a Setup file describing the .o files.
+              On Windows, the name of a .INI file describing one
+              or more extensions is passed.
+              More than one -e option may be given.
+
+-o dir:       Directory where the output files are created; default '.'.
+
+-m:           Additional arguments are module names instead of filenames.
+
+-a package=dir: Additional directories to be added to the package's
+                __path__.  Used to simulate directories added by the
+                package at runtime (eg, by OpenGL and win32com).
+                More than one -a option may be given for each package.
+
+-l file:      Pass the file to the linker (windows only)
+
+-d:           Debugging mode for the module finder.
+
+-q:           Make the module finder totally quiet.
+
+-h:           Print this help message.
+
+-x module     Exclude the specified module. It will still be imported
+              by the frozen binary if it exists on the host system.
+
+-X module     Like -x, except the module can never be imported by
+              the frozen binary.
+
+-E:           Freeze will fail if any modules can't be found (that
+              were not excluded using -x or -X).
+
+-i filename:  Include a file with additional command line options.  Used
+              to prevent command lines growing beyond the capabilities of
+              the shell/OS.  All arguments specified in filename
+              are read and the -i option replaced with the parsed
+              params (note - quoting args in this file is NOT supported)
+
+-s subsystem: Specify the subsystem (For Windows only.);
+              'console' (default), 'windows', 'service' or 'com_dll'
+
+-w:           Toggle Windows (NT or 95) behavior.
+              (For debugging only -- on a win32 platform, win32 behavior
+              is automatic.)
+
+-r prefix=f:  Replace path prefix.
+              Replace prefix with f in the source path references
+              contained in the resulting binary.
+
+Arguments:
+
+script:       The Python script to be executed by the resulting binary.
+
+module ...:   Additional Python modules (referenced by pathname)
+              that will be included in the resulting binary.  These
+              may be .py or .pyc files.  If -m is specified, these are
+              module names that are search in the path instead.
+
+NOTES:
+
+In order to use freeze successfully, you must have built Python and
+installed it ("make install").
+
+The script should not use modules provided only as shared libraries;
+if it does, the resulting binary is not self-contained.
+"""
+
+
+# Import standard modules
+
+import modulefinder
+import getopt
+import os
+import sys
+
+
+# Import the freeze-private modules
+
+import checkextensions
+import makeconfig
+import makefreeze
+import makemakefile
+import parsesetup
+import bkfile
+
+
+# Main program
+
+def main():
+    # overridable context
+    prefix = None                       # settable with -p option
+    exec_prefix = None                  # settable with -P option
+    extensions = []
+    exclude = []                        # settable with -x option
+    addn_link = []      # settable with -l, but only honored under Windows.
+    path = sys.path[:]
+    modargs = 0
+    debug = 1
+    odir = ''
+    win = sys.platform[:3] == 'win'
+    replace_paths = []                  # settable with -r option
+    error_if_any_missing = 0
+
+    # default the exclude list for each platform
+    if win: exclude = exclude + [
+        'dos', 'dospath', 'mac', 'macpath', 'macfs', 'MACFS', 'posix',
+        'os2', 'ce', 'riscos', 'riscosenviron', 'riscospath',
+        ]
+
+    fail_import = exclude[:]
+
+    # output files
+    frozen_c = 'frozen.c'
+    config_c = 'config.c'
+    target = 'a.out'                    # normally derived from script name
+    makefile = 'Makefile'
+    subsystem = 'console'
+
+    # parse command line by first replacing any "-i" options with the
+    # file contents.
+    pos = 1
+    while pos < len(sys.argv)-1:
+        # last option can not be "-i", so this ensures "pos+1" is in range!
+        if sys.argv[pos] == '-i':
+            try:
+                options = open(sys.argv[pos+1]).read().split()
+            except IOError, why:
+                usage("File name '%s' specified with the -i option "
+                      "can not be read - %s" % (sys.argv[pos+1], why) )
+            # Replace the '-i' and the filename with the read params.
+            sys.argv[pos:pos+2] = options
+            pos = pos + len(options) - 1 # Skip the name and the included args.
+        pos = pos + 1
+
+    # Now parse the command line with the extras inserted.
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], 'r:a:dEe:hmo:p:P:qs:wX:x:l:')
+    except getopt.error, msg:
+        usage('getopt error: ' + str(msg))
+
+    # proces option arguments
+    for o, a in opts:
+        if o == '-h':
+            print __doc__
+            return
+        if o == '-d':
+            debug = debug + 1
+        if o == '-e':
+            extensions.append(a)
+        if o == '-m':
+            modargs = 1
+        if o == '-o':
+            odir = a
+        if o == '-p':
+            prefix = a
+        if o == '-P':
+            exec_prefix = a
+        if o == '-q':
+            debug = 0
+        if o == '-w':
+            win = not win
+        if o == '-s':
+            if not win:
+                usage("-s subsystem option only on Windows")
+            subsystem = a
+        if o == '-x':
+            exclude.append(a)
+        if o == '-X':
+            exclude.append(a)
+            fail_import.append(a)
+        if o == '-E':
+            error_if_any_missing = 1
+        if o == '-l':
+            addn_link.append(a)
+        if o == '-a':
+            apply(modulefinder.AddPackagePath, tuple(a.split("=", 2)))
+        if o == '-r':
+            f,r = a.split("=", 2)
+            replace_paths.append( (f,r) )
+
+    # modules that are imported by the Python runtime
+    implicits = []
+    for module in ('site', 'warnings',):
+        if module not in exclude:
+            implicits.append(module)
+
+    # default prefix and exec_prefix
+    if not exec_prefix:
+        if prefix:
+            exec_prefix = prefix
+        else:
+            exec_prefix = sys.exec_prefix
+    if not prefix:
+        prefix = sys.prefix
+
+    # determine whether -p points to the Python source tree
+    ishome = os.path.exists(os.path.join(prefix, 'Python', 'ceval.c'))
+
+    # locations derived from options
+    version = sys.version[:3]
+    if win:
+        extensions_c = 'frozen_extensions.c'
+    if ishome:
+        print "(Using Python source directory)"
+        binlib = exec_prefix
+        incldir = os.path.join(prefix, 'Include')
+        config_h_dir = exec_prefix
+        config_c_in = os.path.join(prefix, 'Modules', 'config.c.in')
+        frozenmain_c = os.path.join(prefix, 'Python', 'frozenmain.c')
+        makefile_in = os.path.join(exec_prefix, 'Makefile')
+        if win:
+            frozendllmain_c = os.path.join(exec_prefix, 'Pc\\frozen_dllmain.c')
+    else:
+        binlib = os.path.join(exec_prefix,
+                              'lib', 'python%s' % version, 'config')
+        incldir = os.path.join(prefix, 'include', 'python%s' % version)
+        config_h_dir = os.path.join(exec_prefix, 'include',
+                                    'python%s' % version)
+        config_c_in = os.path.join(binlib, 'config.c.in')
+        frozenmain_c = os.path.join(binlib, 'frozenmain.c')
+        makefile_in = os.path.join(binlib, 'Makefile')
+        frozendllmain_c = os.path.join(binlib, 'frozen_dllmain.c')
+    supp_sources = []
+    defines = []
+    includes = ['-I' + incldir, '-I' + config_h_dir]
+
+    # sanity check of directories and files
+    check_dirs = [prefix, exec_prefix, binlib, incldir]
+    if not win:
+        # These are not directories on Windows.
+        check_dirs = check_dirs + extensions
+    for dir in check_dirs:
+        if not os.path.exists(dir):
+            usage('needed directory %s not found' % dir)
+        if not os.path.isdir(dir):
+            usage('%s: not a directory' % dir)
+    if win:
+        files = supp_sources + extensions # extensions are files on Windows.
+    else:
+        files = [config_c_in, makefile_in] + supp_sources
+    for file in supp_sources:
+        if not os.path.exists(file):
+            usage('needed file %s not found' % file)
+        if not os.path.isfile(file):
+            usage('%s: not a plain file' % file)
+    if not win:
+        for dir in extensions:
+            setup = os.path.join(dir, 'Setup')
+            if not os.path.exists(setup):
+                usage('needed file %s not found' % setup)
+            if not os.path.isfile(setup):
+                usage('%s: not a plain file' % setup)
+
+    # check that enough arguments are passed
+    if not args:
+        usage('at least one filename argument required')
+
+    # check that file arguments exist
+    for arg in args:
+        if arg == '-m':
+            break
+        # if user specified -m on the command line before _any_
+        # file names, then nothing should be checked (as the
+        # very first file should be a module name)
+        if modargs:
+            break
+        if not os.path.exists(arg):
+            usage('argument %s not found' % arg)
+        if not os.path.isfile(arg):
+            usage('%s: not a plain file' % arg)
+
+    # process non-option arguments
+    scriptfile = args[0]
+    modules = args[1:]
+
+    # derive target name from script name
+    base = os.path.basename(scriptfile)
+    base, ext = os.path.splitext(base)
+    if base:
+        if base != scriptfile:
+            target = base
+        else:
+            target = base + '.bin'
+
+    # handle -o option
+    base_frozen_c = frozen_c
+    base_config_c = config_c
+    base_target = target
+    if odir and not os.path.isdir(odir):
+        try:
+            os.mkdir(odir)
+            print "Created output directory", odir
+        except os.error, msg:
+            usage('%s: mkdir failed (%s)' % (odir, str(msg)))
+    base = ''
+    if odir:
+        base = os.path.join(odir, '')
+        frozen_c = os.path.join(odir, frozen_c)
+        config_c = os.path.join(odir, config_c)
+        target = os.path.join(odir, target)
+        makefile = os.path.join(odir, makefile)
+        if win: extensions_c = os.path.join(odir, extensions_c)
+
+    # Handle special entry point requirements
+    # (on Windows, some frozen programs do not use __main__, but
+    # import the module directly.  Eg, DLLs, Services, etc
+    custom_entry_point = None  # Currently only used on Windows
+    python_entry_is_main = 1   # Is the entry point called __main__?
+    # handle -s option on Windows
+    if win:
+        import winmakemakefile
+        try:
+            custom_entry_point, python_entry_is_main = \
+                winmakemakefile.get_custom_entry_point(subsystem)
+        except ValueError, why:
+            usage(why)
+
+
+    # Actual work starts here...
+
+    # collect all modules of the program
+    dir = os.path.dirname(scriptfile)
+    path[0] = dir
+    mf = modulefinder.ModuleFinder(path, debug, exclude, replace_paths)
+
+    if win and subsystem=='service':
+        # If a Windows service, then add the "built-in" module.
+        mod = mf.add_module("servicemanager")
+        mod.__file__="dummy.pyd" # really built-in to the resulting EXE
+
+    for mod in implicits:
+        mf.import_hook(mod)
+    for mod in modules:
+        if mod == '-m':
+            modargs = 1
+            continue
+        if modargs:
+            if mod[-2:] == '.*':
+                mf.import_hook(mod[:-2], None, ["*"])
+            else:
+                mf.import_hook(mod)
+        else:
+            mf.load_file(mod)
+
+    # Add the main script as either __main__, or the actual module name.
+    if python_entry_is_main:
+        mf.run_script(scriptfile)
+    else:
+        mf.load_file(scriptfile)
+
+    if debug > 0:
+        mf.report()
+        print
+    dict = mf.modules
+
+    if error_if_any_missing:
+        missing = mf.any_missing()
+        if missing:
+            sys.exit("There are some missing modules: %r" % missing)
+
+    # generate output for frozen modules
+    files = makefreeze.makefreeze(base, dict, debug, custom_entry_point,
+                                  fail_import)
+
+    # look for unfrozen modules (builtin and of unknown origin)
+    builtins = []
+    unknown = []
+    mods = dict.keys()
+    mods.sort()
+    for mod in mods:
+        if dict[mod].__code__:
+            continue
+        if not dict[mod].__file__:
+            builtins.append(mod)
+        else:
+            unknown.append(mod)
+
+    # search for unknown modules in extensions directories (not on Windows)
+    addfiles = []
+    frozen_extensions = [] # Windows list of modules.
+    if unknown or (not win and builtins):
+        if not win:
+            addfiles, addmods = \
+                      checkextensions.checkextensions(unknown+builtins,
+                                                      extensions)
+            for mod in addmods:
+                if mod in unknown:
+                    unknown.remove(mod)
+                    builtins.append(mod)
+        else:
+            # Do the windows thang...
+            import checkextensions_win32
+            # Get a list of CExtension instances, each describing a module
+            # (including its source files)
+            frozen_extensions = checkextensions_win32.checkextensions(
+                unknown, extensions, prefix)
+            for mod in frozen_extensions:
+                unknown.remove(mod.name)
+
+    # report unknown modules
+    if unknown:
+        sys.stderr.write('Warning: unknown modules remain: %s\n' %
+                         ' '.join(unknown))
+
+    # windows gets different treatment
+    if win:
+        # Taking a shortcut here...
+        import winmakemakefile, checkextensions_win32
+        checkextensions_win32.write_extension_table(extensions_c,
+                                                    frozen_extensions)
+        # Create a module definition for the bootstrap C code.
+        xtras = [frozenmain_c, os.path.basename(frozen_c),
+                 frozendllmain_c, os.path.basename(extensions_c)] + files
+        maindefn = checkextensions_win32.CExtension( '__main__', xtras )
+        frozen_extensions.append( maindefn )
+        outfp = open(makefile, 'w')
+        try:
+            winmakemakefile.makemakefile(outfp,
+                                         locals(),
+                                         frozen_extensions,
+                                         os.path.basename(target))
+        finally:
+            outfp.close()
+        return
+
+    # generate config.c and Makefile
+    builtins.sort()
+    infp = open(config_c_in)
+    outfp = bkfile.open(config_c, 'w')
+    try:
+        makeconfig.makeconfig(infp, outfp, builtins)
+    finally:
+        outfp.close()
+    infp.close()
+
+    cflags = ['$(OPT)']
+    cppflags = defines + includes
+    libs = [os.path.join(binlib, 'libpython$(VERSION).a')]
+
+    somevars = {}
+    if os.path.exists(makefile_in):
+        makevars = parsesetup.getmakevars(makefile_in)
+        for key in makevars.keys():
+            somevars[key] = makevars[key]
+
+    somevars['CFLAGS'] = ' '.join(cflags) # override
+    somevars['CPPFLAGS'] = ' '.join(cppflags) # override
+    files = [base_config_c, base_frozen_c] + \
+            files + supp_sources +  addfiles + libs + \
+            ['$(MODLIBS)', '$(LIBS)', '$(SYSLIBS)']
+
+    outfp = bkfile.open(makefile, 'w')
+    try:
+        makemakefile.makemakefile(outfp, somevars, files, base_target)
+    finally:
+        outfp.close()
+
+    # Done!
+
+    if odir:
+        print 'Now run "make" in', odir,
+        print 'to build the target:', base_target
+    else:
+        print 'Now run "make" to build the target:', base_target
+
+
+# Print usage message and exit
+
+def usage(msg):
+    sys.stdout = sys.stderr
+    print "Error:", msg
+    print "Use ``%s -h'' for help" % sys.argv[0]
+    sys.exit(2)
+
+
+main()


Property changes on: vendor/Python/current/Tools/freeze/freeze.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/freeze/hello.py
===================================================================
--- vendor/Python/current/Tools/freeze/hello.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/freeze/hello.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1 @@
+print 'Hello world...'

Added: vendor/Python/current/Tools/freeze/makeconfig.py
===================================================================
--- vendor/Python/current/Tools/freeze/makeconfig.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/freeze/makeconfig.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,61 @@
+import re
+
+
+# Write the config.c file
+
+never = ['marshal', '__main__', '__builtin__', 'sys', 'exceptions']
+
+def makeconfig(infp, outfp, modules, with_ifdef=0):
+    m1 = re.compile('-- ADDMODULE MARKER 1 --')
+    m2 = re.compile('-- ADDMODULE MARKER 2 --')
+    while 1:
+        line = infp.readline()
+        if not line: break
+        outfp.write(line)
+        if m1 and m1.search(line):
+            m1 = None
+            for mod in modules:
+                if mod in never:
+                    continue
+                if with_ifdef:
+                    outfp.write("#ifndef init%s\n"%mod)
+                outfp.write('extern void init%s(void);\n' % mod)
+                if with_ifdef:
+                    outfp.write("#endif\n")
+        elif m2 and m2.search(line):
+            m2 = None
+            for mod in modules:
+                if mod in never:
+                    continue
+                outfp.write('\t{"%s", init%s},\n' %
+                            (mod, mod))
+    if m1:
+        sys.stderr.write('MARKER 1 never found\n')
+    elif m2:
+        sys.stderr.write('MARKER 2 never found\n')
+
+
+# Test program.
+
+def test():
+    import sys
+    if not sys.argv[3:]:
+        print 'usage: python makeconfig.py config.c.in outputfile',
+        print 'modulename ...'
+        sys.exit(2)
+    if sys.argv[1] == '-':
+        infp = sys.stdin
+    else:
+        infp = open(sys.argv[1])
+    if sys.argv[2] == '-':
+        outfp = sys.stdout
+    else:
+        outfp = open(sys.argv[2], 'w')
+    makeconfig(infp, outfp, sys.argv[3:])
+    if outfp != sys.stdout:
+        outfp.close()
+    if infp != sys.stdin:
+        infp.close()
+
+if __name__ == '__main__':
+    test()

Added: vendor/Python/current/Tools/freeze/makefreeze.py
===================================================================
--- vendor/Python/current/Tools/freeze/makefreeze.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/freeze/makefreeze.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,90 @@
+import marshal
+import bkfile
+
+
+# Write a file containing frozen code for the modules in the dictionary.
+
+header = """
+#include "Python.h"
+
+static struct _frozen _PyImport_FrozenModules[] = {
+"""
+trailer = """\
+    {0, 0, 0} /* sentinel */
+};
+"""
+
+# if __debug__ == 0 (i.e. -O option given), set Py_OptimizeFlag in frozen app.
+default_entry_point = """
+int
+main(int argc, char **argv)
+{
+        extern int Py_FrozenMain(int, char **);
+""" + ((not __debug__ and """
+        Py_OptimizeFlag++;
+""") or "")  + """
+        PyImport_FrozenModules = _PyImport_FrozenModules;
+        return Py_FrozenMain(argc, argv);
+}
+
+"""
+
+def makefreeze(base, dict, debug=0, entry_point=None, fail_import=()):
+    if entry_point is None: entry_point = default_entry_point
+    done = []
+    files = []
+    mods = dict.keys()
+    mods.sort()
+    for mod in mods:
+        m = dict[mod]
+        mangled = "__".join(mod.split("."))
+        if m.__code__:
+            file = 'M_' + mangled + '.c'
+            outfp = bkfile.open(base + file, 'w')
+            files.append(file)
+            if debug:
+                print "freezing", mod, "..."
+            str = marshal.dumps(m.__code__)
+            size = len(str)
+            if m.__path__:
+                # Indicate package by negative size
+                size = -size
+            done.append((mod, mangled, size))
+            writecode(outfp, mangled, str)
+            outfp.close()
+    if debug:
+        print "generating table of frozen modules"
+    outfp = bkfile.open(base + 'frozen.c', 'w')
+    for mod, mangled, size in done:
+        outfp.write('extern unsigned char M_%s[];\n' % mangled)
+    outfp.write(header)
+    for mod, mangled, size in done:
+        outfp.write('\t{"%s", M_%s, %d},\n' % (mod, mangled, size))
+    outfp.write('\n')
+    # The following modules have a NULL code pointer, indicating
+    # that the prozen program should not search for them on the host
+    # system. Importing them will *always* raise an ImportError.
+    # The zero value size is never used.
+    for mod in fail_import:
+        outfp.write('\t{"%s", NULL, 0},\n' % (mod,))
+    outfp.write(trailer)
+    outfp.write(entry_point)
+    outfp.close()
+    return files
+
+
+
+# Write a C initializer for a module containing the frozen python code.
+# The array is called M_<mod>.
+
+def writecode(outfp, mod, str):
+    outfp.write('unsigned char M_%s[] = {' % mod)
+    for i in range(0, len(str), 16):
+        outfp.write('\n\t')
+        for c in str[i:i+16]:
+            outfp.write('%d,' % ord(c))
+    outfp.write('\n};\n')
+
+## def writecode(outfp, mod, str):
+##     outfp.write('unsigned char M_%s[%d] = "%s";\n' % (mod, len(str),
+##     '\\"'.join(map(lambda s: repr(s)[1:-1], str.split('"')))))

Added: vendor/Python/current/Tools/freeze/makemakefile.py
===================================================================
--- vendor/Python/current/Tools/freeze/makemakefile.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/freeze/makemakefile.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,29 @@
+# Write the actual Makefile.
+
+import os
+
+def makemakefile(outfp, makevars, files, target):
+    outfp.write("# Makefile generated by freeze.py script\n\n")
+
+    keys = makevars.keys()
+    keys.sort()
+    for key in keys:
+        outfp.write("%s=%s\n" % (key, makevars[key]))
+    outfp.write("\nall: %s\n\n" % target)
+
+    deps = []
+    for i in range(len(files)):
+        file = files[i]
+        if file[-2:] == '.c':
+            base = os.path.basename(file)
+            dest = base[:-2] + '.o'
+            outfp.write("%s: %s\n" % (dest, file))
+            outfp.write("\t$(CC) $(CFLAGS) $(CPPFLAGS) -c %s\n" % file)
+            files[i] = dest
+            deps.append(dest)
+
+    outfp.write("\n%s: %s\n" % (target, ' '.join(deps)))
+    outfp.write("\t$(LINKCC) $(LDFLAGS) $(LINKFORSHARED) %s -o %s $(LDLAST)\n" %
+                (' '.join(files), target))
+
+    outfp.write("\nclean:\n\t-rm -f *.o %s\n" % target)

Added: vendor/Python/current/Tools/freeze/parsesetup.py
===================================================================
--- vendor/Python/current/Tools/freeze/parsesetup.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/freeze/parsesetup.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,112 @@
+# Parse Makefiles and Python Setup(.in) files.
+
+import re
+
+
+# Extract variable definitions from a Makefile.
+# Return a dictionary mapping names to values.
+# May raise IOError.
+
+makevardef = re.compile('^([a-zA-Z0-9_]+)[ \t]*=(.*)')
+
+def getmakevars(filename):
+    variables = {}
+    fp = open(filename)
+    pendingline = ""
+    try:
+        while 1:
+            line = fp.readline()
+            if pendingline:
+                line = pendingline + line
+                pendingline = ""
+            if not line:
+                break
+            if line.endswith('\\\n'):
+                pendingline = line[:-2]
+            matchobj = makevardef.match(line)
+            if not matchobj:
+                continue
+            (name, value) = matchobj.group(1, 2)
+            # Strip trailing comment
+            i = value.find('#')
+            if i >= 0:
+                value = value[:i]
+            value = value.strip()
+            variables[name] = value
+    finally:
+        fp.close()
+    return variables
+
+
+# Parse a Python Setup(.in) file.
+# Return two dictionaries, the first mapping modules to their
+# definitions, the second mapping variable names to their values.
+# May raise IOError.
+
+setupvardef = re.compile('^([a-zA-Z0-9_]+)=(.*)')
+
+def getsetupinfo(filename):
+    modules = {}
+    variables = {}
+    fp = open(filename)
+    pendingline = ""
+    try:
+        while 1:
+            line = fp.readline()
+            if pendingline:
+                line = pendingline + line
+                pendingline = ""
+            if not line:
+                break
+            # Strip comments
+            i = line.find('#')
+            if i >= 0:
+                line = line[:i]
+            if line.endswith('\\\n'):
+                pendingline = line[:-2]
+                continue
+            matchobj = setupvardef.match(line)
+            if matchobj:
+                (name, value) = matchobj.group(1, 2)
+                variables[name] = value.strip()
+            else:
+                words = line.split()
+                if words:
+                    modules[words[0]] = words[1:]
+    finally:
+        fp.close()
+    return modules, variables
+
+
+# Test the above functions.
+
+def test():
+    import sys
+    import os
+    if not sys.argv[1:]:
+        print 'usage: python parsesetup.py Makefile*|Setup* ...'
+        sys.exit(2)
+    for arg in sys.argv[1:]:
+        base = os.path.basename(arg)
+        if base[:8] == 'Makefile':
+            print 'Make style parsing:', arg
+            v = getmakevars(arg)
+            prdict(v)
+        elif base[:5] == 'Setup':
+            print 'Setup style parsing:', arg
+            m, v = getsetupinfo(arg)
+            prdict(m)
+            prdict(v)
+        else:
+            print arg, 'is neither a Makefile nor a Setup file'
+            print '(name must begin with "Makefile" or "Setup")'
+
+def prdict(d):
+    keys = d.keys()
+    keys.sort()
+    for key in keys:
+        value = d[key]
+        print "%-15s" % key, str(value)
+
+if __name__ == '__main__':
+    test()

Added: vendor/Python/current/Tools/freeze/win32.html
===================================================================
--- vendor/Python/current/Tools/freeze/win32.html	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/freeze/win32.html	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,119 @@
+<HTML>
+<HEAD>
+<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
+<META NAME="Generator" CONTENT="Microsoft Word 97">
+<TITLE>win32</TITLE>
+<META NAME="Version" CONTENT="8.0.3410">
+<META NAME="Date" CONTENT="10/11/96">
+<META NAME="Template" CONTENT="D:\Program Files\Microsoft Office\Office\HTML.DOT">
+</HEAD>
+<BODY TEXT="#000000" BGCOLOR="#ffffff">
+
+<H1>Freeze for Win32</H1>
+<P>This document describes how to use Freeze for the Win32 platform.  </P>
+<P>Freeze itself is a Python tool for creating stand-alone executables from Python source code.  This document does not attempt to document freeze itself - only the win32 specific changes.</P>
+<H2>Frozen programs under Win32</H2>
+<P>Frozen programs under Win32 can (theoretically) freeze any type of program supported by Python on Win32 - At the moment, Console .EXE and NT Service .EXE programs are supported.  GUI Python programs and COM .EXE programs are very nearly all ready to go.</P>
+<H3>Program Dependencies</H3>
+<P>The person freezing the program has control over what external DLLs are required by a frozen program.  The following dependencies are supported:</P>
+<H4>Minimal frozen programs</H4>
+<P>These programs freeze only .py files in your program.  All external DLLs are required at run-time.  This includes all .pyd/.dll modules used by your program, Python20.dll, and msvcrt.dll.  </P>
+<P>A small Python program would typically create a .EXE around 300kb.</P>
+<H4>Frozen Extension programs</H4>
+<B><I><P>Note:</B></I> For Python1.5.1, you must get a patch from Guido to import.c for this to work.</P>
+<P>These programs also freeze in the sources from all .pyd and .dll files used at runtime.  This means the resulting .EXE is only dependent on Python20.dll and msvcrt.dll.</P>
+<P>A small Python program using win32api, win32con and one or 2 other win32 extensions would typically create a .EXE around 400kb.</P>
+<H4>Completely frozen programs</H4>
+<P>Completely stand-alone programs, as is the default on Unix systems.  These are currently not supported, mainly as the size of a decent Python program gets very large.  However, by tweaking the existing Unix support, this would not be difficult to do.</P>
+<H2>Freezing Extension Modules</H2>
+<P>By default, a file in the main "freeze" directory called "extensions_win32.ini" is used to obtain information about frozen extensions.  A typical entry is:</P>
+<CODE><P>[win32api]</P>
+<P>dsp=%PYTHONEX%\win32\win32api.dsp</P>
+<P>cl=/I %PYTHONEX%\win32\src</P>
+<P>libs=kernel32.lib user32.lib shell32.lib advapi32.lib</P>
+</CODE><P>&nbsp;</P>
+<P>This entry indicates that the win32api extension module is defined in the MSVC project file "<CODE>%PYTHONEX%\win32\win32api.dsp</CODE>".  Note the use of<CODE> </CODE>"<CODE>%PYTHONEX%" </CODE>- most strings are substituted with environment variables. In this case, it is assumed variable PYTHONEX points to the main "Python Extensions" source directory (which is assumed to be in the same structure as the release of the extension sources).</P>
+<P>An entry in a .INI file can also control specific compiler options, and also the .lib files necessary to be linked with the application.</P>
+<H3>Freezing Extension Module Considerations</H3>
+<P>To prevent freezing extension modules, simply exclude that module using the freeze "-x" switch.</P>
+<P>Occasionally, it will be necessary to explicitly include dependent modules.  For example, many win32 modules are dependent on the "pywintypes" module - for example, the win32api module.  In this case, the module may be explicitly included using the freeze "-m" option.</P>
+<H3>Freezing win32com and PythonCOM</H3>
+<P>PythonCOM.dll can be frozen as long as you are not implementing COM Servers.  Ie, you can freeze programs which control other applications, but can not implement programs that are themselves controlled by other applications.</P>
+<P>If you use any of the win32com .pyd extensions (ex, axscript, mapi, internet, axcontrol), then you will need to specify an additional "-a" option to point to the win32comext directory.  There is an example below.</P>
+<P>The use of the "win32com.client.gencache" module is not supported (although could be quite easily??)</P>
+<H2>Examples</H2>
+<P>Before we start, we must:</P>
+<CODE><P>D:\temp\delme&gt;set PYTHONEX=d:\src\pythonex</P>
+</CODE><H3>Helloworld.py</H3>
+<H4>Source Code</H4><DIR>
+<DIR>
+
+<CODE><P>import sys</P>
+<P>&nbsp;</P>
+<P>print " ".join( ["Hello", "world"] + sys.argv[1:] )</P></DIR>
+</DIR>
+
+</CODE><H4>Command Line used</H4><DIR>
+<DIR>
+
+<FONT FACE="Courier New" SIZE=2><P>\src\python-1.5.1\tools\freeze\freeze.py helloworld.py</P>
+<P>nmake</P></DIR>
+</DIR>
+
+</FONT><P>Resulting helloworld.exe: 114,688 bytes.</P>
+<H3>Helloworld2.py</H3>
+<P>Uses win32api.  Demonstrates requirement for pywintypes, and difference between freezing extensions and not.</P>
+<H4>Source Code</H4><DIR>
+<DIR>
+
+<P>import win32api</P>
+<P>print "Hello from", win32api.GetComputerName()</P></DIR>
+</DIR>
+
+<H4>Command Line used</H4>
+<P>By default, win32api will be frozen in with the .EXE.  If you do not provide the "pywintypes" inclusion, then the link step will fail looking for all the pywintypes modules.</P><DIR>
+<DIR>
+
+<FONT FACE="Courier New" SIZE=2><P>\src\python-1.5.1\tools\freeze\freeze.py helloworld2.py -m pywintypes</P>
+<P>nmake</P></DIR>
+</DIR>
+
+</FONT><P>Resulting helloworld2.exe: 167,936 bytes</P>
+<P>Simply adding win32con to the mix gives an EXE of size: 352,768 bytes.</P>
+<H4>Command Line used</H4>
+<P>Using this build, we are dependent at runtime on the win32api.pyd and pywintypes15.dll files.</P><DIR>
+<DIR>
+
+<P>\src\python-1.5.1\tools\freeze\freeze.py -x win32api helloworld.py</P></DIR>
+</DIR>
+
+<P>Resulting helloworld2.exe: 114,688</P>
+<P>Adding win32con to this build results in a size of: 252,928</P>
+<H3>Testmapi.py</H3>
+<P>Uses MAPI, a PythonCOM extension, and win32api.</P>
+<H4>Source Code</H4>
+<P>from win32com.mapi import mapi</P>
+<P>import win32api</P>
+<P>mapi.MAPIInitialize( (mapi.MAPI_INIT_VERSION, 0) )</P>
+<P>print "Hello from", win32api.GetComputerName()</P>
+<P>mapi.MAPIUninitialize()</P>
+<H4>Command Line used</H4>
+<P>As it does not import pythoncom or pywintypes itself, they must be specified.  As it uses the win32comext directory, -a must be used.  If you have built the win32com extensions from sources, then the second -a is required.</P><DIR>
+<DIR>
+
+<CODE><P>\src\python-1.5.1\tools\freeze\freeze.py -a win32com=%PYTHONEX%\com\win32comext -a win32com.mapi=%PYTHONEX%\com\build\release testmapi.py -m pywintypes -m pythoncom</P></DIR>
+</DIR>
+
+</CODE><P>Resulting testmapi.exe: 352,768 bytes</P>
+<H3>PipeTestService.py</H3>
+<P>This is a standard Python demo in the Win32 extensions.  It can be found in the "win32\demos\service" directory.</P>
+<H4>Command Line used</H4>
+<P>This will create a native NT Service EXE, dependent only on the main Python20.dll.  All other modules are built-in to the final .EXE</P><DIR>
+<DIR>
+
+<CODE><P>\src\python-1.5.1\tools\freeze\freeze.py -s service %PYTHONEX%\win32\demos\service\pipeTestService.py</P></DIR>
+</DIR>
+
+<P>Resulting pipeTestService.exe: </CODE><FONT FACE="Courier New" SIZE=2>533,504 bytes.</P></FONT></BODY>
+</HTML>
+

Added: vendor/Python/current/Tools/freeze/winmakemakefile.py
===================================================================
--- vendor/Python/current/Tools/freeze/winmakemakefile.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/freeze/winmakemakefile.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,146 @@
+import sys, os
+
+# Template used then the program is a GUI program
+WINMAINTEMPLATE = """
+#include <windows.h>
+
+int WINAPI WinMain(
+    HINSTANCE hInstance,      // handle to current instance
+    HINSTANCE hPrevInstance,  // handle to previous instance
+    LPSTR lpCmdLine,          // pointer to command line
+    int nCmdShow              // show state of window
+    )
+{
+    extern int Py_FrozenMain(int, char **);
+    PyImport_FrozenModules = _PyImport_FrozenModules;
+    return Py_FrozenMain(__argc, __argv);
+}
+"""
+
+SERVICETEMPLATE = """
+extern int PythonService_main(int, char **);
+
+int main( int argc, char **argv)
+{
+    PyImport_FrozenModules = _PyImport_FrozenModules;
+    return PythonService_main(argc, argv);
+}
+"""
+
+subsystem_details = {
+    # -s flag        : (C entry point template), (is it __main__?), (is it a DLL?)
+    'console'        : (None,                    1,                 0),
+    'windows'        : (WINMAINTEMPLATE,         1,                 0),
+    'service'        : (SERVICETEMPLATE,         0,                 0),
+    'com_dll'        : ("",                      0,                 1),
+}
+
+def get_custom_entry_point(subsystem):
+    try:
+        return subsystem_details[subsystem][:2]
+    except KeyError:
+        raise ValueError, "The subsystem %s is not known" % subsystem
+
+
+def makemakefile(outfp, vars, files, target):
+    save = sys.stdout
+    try:
+        sys.stdout = outfp
+        realwork(vars, files, target)
+    finally:
+        sys.stdout = save
+
+def realwork(vars, moddefns, target):
+    version_suffix = "%r%r" % sys.version_info[:2]
+    print "# Makefile for Microsoft Visual C++ generated by freeze.py script"
+    print
+    print 'target = %s' % target
+    print 'pythonhome = %s' % vars['prefix']
+    print
+    print 'DEBUG=0 # Set to 1 to use the _d versions of Python.'
+    print '!IF $(DEBUG)'
+    print 'debug_suffix=_d'
+    print 'c_debug=/Zi /Od /DDEBUG /D_DEBUG'
+    print 'l_debug=/DEBUG'
+    print 'temp_dir=Build\\Debug'
+    print '!ELSE'
+    print 'debug_suffix='
+    print 'c_debug=/Ox'
+    print 'l_debug='
+    print 'temp_dir=Build\\Release'
+    print '!ENDIF'
+    print
+
+    print '# The following line assumes you have built Python using the standard instructions'
+    print '# Otherwise fix the following line to point to the library.'
+    print 'pythonlib = "$(pythonhome)/pcbuild/python%s$(debug_suffix).lib"' % version_suffix
+    print
+
+    # We only ever write one "entry point" symbol - either
+    # "main" or "WinMain".  Therefore, there is no need to
+    # pass a subsystem switch to the linker as it works it
+    # out all by itself.  However, the subsystem _does_ determine
+    # the file extension and additional linker flags.
+    target_link_flags = ""
+    target_ext = ".exe"
+    if subsystem_details[vars['subsystem']][2]:
+        target_link_flags = "-dll"
+        target_ext = ".dll"
+
+
+    print "# As the target uses Python%s.dll, we must use this compiler option!" % version_suffix
+    print "cdl = /MD"
+    print
+    print "all: $(target)$(debug_suffix)%s" % (target_ext)
+    print
+
+    print '$(temp_dir):'
+    print '  if not exist $(temp_dir)\. mkdir $(temp_dir)'
+    print
+
+    objects = []
+    libs = ["shell32.lib", "comdlg32.lib", "wsock32.lib", "user32.lib", "oleaut32.lib"]
+    for moddefn in moddefns:
+        print "# Module", moddefn.name
+        for file in moddefn.sourceFiles:
+            base = os.path.basename(file)
+            base, ext = os.path.splitext(base)
+            objects.append(base + ".obj")
+            print '$(temp_dir)\%s.obj: "%s"' % (base, file)
+            print "\t@$(CC) -c -nologo /Fo$* $(cdl) $(c_debug) /D BUILD_FREEZE",
+            print '"-I$(pythonhome)/Include"  "-I$(pythonhome)/PC" \\'
+            print "\t\t$(cflags) $(cdebug) $(cinclude) \\"
+            extra = moddefn.GetCompilerOptions()
+            if extra:
+                print "\t\t%s \\" % (' '.join(extra),)
+            print '\t\t"%s"' % file
+            print
+
+        # Add .lib files this module needs
+        for modlib in moddefn.GetLinkerLibs():
+            if modlib not in libs:
+                libs.append(modlib)
+
+    print "ADDN_LINK_FILES=",
+    for addn in vars['addn_link']: print '"%s"' % (addn),
+    print ; print
+
+    print "OBJS=",
+    for obj in objects: print '"$(temp_dir)\%s"' % (obj),
+    print ; print
+
+    print "LIBS=",
+    for lib in libs: print '"%s"' % (lib),
+    print ; print
+
+    print "$(target)$(debug_suffix)%s: $(temp_dir) $(OBJS)" % (target_ext)
+    print "\tlink -out:$(target)$(debug_suffix)%s %s" % (target_ext, target_link_flags),
+    print "\t$(OBJS) \\"
+    print "\t$(LIBS) \\"
+    print "\t$(ADDN_LINK_FILES) \\"
+    print "\t$(pythonlib) $(lcustom) $(l_debug)\\"
+    print "\t$(resources)"
+    print
+    print "clean:"
+    print "\t-rm -f *.obj"
+    print "\t-rm -f $(target).exe"

Added: vendor/Python/current/Tools/i18n/makelocalealias.py
===================================================================
--- vendor/Python/current/Tools/i18n/makelocalealias.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/i18n/makelocalealias.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,73 @@
+#!/usr/bin/env python
+"""
+    Convert the X11 locale.alias file into a mapping dictionary suitable
+    for locale.py.
+
+    Written by Marc-Andre Lemburg <mal at genix.com>, 2004-12-10.
+
+"""
+import locale
+
+# Location of the alias file
+LOCALE_ALIAS = '/usr/lib/X11/locale/locale.alias'
+
+def parse(filename):
+
+    f = open(filename)
+    lines = f.read().splitlines()
+    data = {}
+    for line in lines:
+        line = line.strip()
+        if not line:
+            continue
+        if line[:1] == '#':
+            continue
+        locale, alias = line.split()
+        # Strip ':'
+        if locale[-1] == ':':
+            locale = locale[:-1]
+        # Lower-case locale
+        locale = locale.lower()
+        # Ignore one letter locale mappings (except for 'c')
+        if len(locale) == 1 and locale != 'c':
+            continue
+        # Normalize encoding, if given
+        if '.' in locale:
+            lang, encoding = locale.split('.')[:2]
+            encoding = encoding.replace('-', '')
+            encoding = encoding.replace('_', '')
+            locale = lang + '.' + encoding
+            if encoding.lower() == 'utf8':
+                # Ignore UTF-8 mappings - this encoding should be
+                # available for all locales
+                continue
+        data[locale] = alias
+    return data
+
+def pprint(data):
+
+    items = data.items()
+    items.sort()
+    for k,v in items:
+        print '    %-40s%r,' % ('%r:' % k, v)
+
+def print_differences(data, olddata):
+
+    items = olddata.items()
+    items.sort()
+    for k, v in items:
+        if not data.has_key(k):
+            print '#    removed %r' % k
+        elif olddata[k] != data[k]:
+            print '#    updated %r -> %r to %r' % \
+                  (k, olddata[k], data[k])
+        # Additions are not mentioned
+
+if __name__ == '__main__':
+    data = locale.locale_alias.copy()
+    data.update(parse(LOCALE_ALIAS))
+    print_differences(data, locale.locale_alias)
+    print
+    print 'locale_alias = {'
+    pprint(data)
+    print '}'

Added: vendor/Python/current/Tools/i18n/msgfmt.py
===================================================================
--- vendor/Python/current/Tools/i18n/msgfmt.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/i18n/msgfmt.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,203 @@
+#! /usr/bin/env python
+# -*- coding: iso-8859-1 -*-
+# Written by Martin v. Löwis <loewis at informatik.hu-berlin.de>
+
+"""Generate binary message catalog from textual translation description.
+
+This program converts a textual Uniforum-style message catalog (.po file) into
+a binary GNU catalog (.mo file).  This is essentially the same function as the
+GNU msgfmt program, however, it is a simpler implementation.
+
+Usage: msgfmt.py [OPTIONS] filename.po
+
+Options:
+    -o file
+    --output-file=file
+        Specify the output file to write to.  If omitted, output will go to a
+        file named filename.mo (based off the input file name).
+
+    -h
+    --help
+        Print this message and exit.
+
+    -V
+    --version
+        Display version information and exit.
+"""
+
+import sys
+import os
+import getopt
+import struct
+import array
+
+__version__ = "1.1"
+
+MESSAGES = {}
+
+
+
+def usage(code, msg=''):
+    print >> sys.stderr, __doc__
+    if msg:
+        print >> sys.stderr, msg
+    sys.exit(code)
+
+
+
+def add(id, str, fuzzy):
+    "Add a non-fuzzy translation to the dictionary."
+    global MESSAGES
+    if not fuzzy and str:
+        MESSAGES[id] = str
+
+
+
+def generate():
+    "Return the generated output."
+    global MESSAGES
+    keys = MESSAGES.keys()
+    # the keys are sorted in the .mo file
+    keys.sort()
+    offsets = []
+    ids = strs = ''
+    for id in keys:
+        # For each string, we need size and file offset.  Each string is NUL
+        # terminated; the NUL does not count into the size.
+        offsets.append((len(ids), len(id), len(strs), len(MESSAGES[id])))
+        ids += id + '\0'
+        strs += MESSAGES[id] + '\0'
+    output = ''
+    # The header is 7 32-bit unsigned integers.  We don't use hash tables, so
+    # the keys start right after the index tables.
+    # translated string.
+    keystart = 7*4+16*len(keys)
+    # and the values start after the keys
+    valuestart = keystart + len(ids)
+    koffsets = []
+    voffsets = []
+    # The string table first has the list of keys, then the list of values.
+    # Each entry has first the size of the string, then the file offset.
+    for o1, l1, o2, l2 in offsets:
+        koffsets += [l1, o1+keystart]
+        voffsets += [l2, o2+valuestart]
+    offsets = koffsets + voffsets
+    output = struct.pack("Iiiiiii",
+                         0x950412deL,       # Magic
+                         0,                 # Version
+                         len(keys),         # # of entries
+                         7*4,               # start of key index
+                         7*4+len(keys)*8,   # start of value index
+                         0, 0)              # size and offset of hash table
+    output += array.array("i", offsets).tostring()
+    output += ids
+    output += strs
+    return output
+
+
+
+def make(filename, outfile):
+    ID = 1
+    STR = 2
+
+    # Compute .mo name from .po name and arguments
+    if filename.endswith('.po'):
+        infile = filename
+    else:
+        infile = filename + '.po'
+    if outfile is None:
+        outfile = os.path.splitext(infile)[0] + '.mo'
+
+    try:
+        lines = open(infile).readlines()
+    except IOError, msg:
+        print >> sys.stderr, msg
+        sys.exit(1)
+
+    section = None
+    fuzzy = 0
+
+    # Parse the catalog
+    lno = 0
+    for l in lines:
+        lno += 1
+        # If we get a comment line after a msgstr, this is a new entry
+        if l[0] == '#' and section == STR:
+            add(msgid, msgstr, fuzzy)
+            section = None
+            fuzzy = 0
+        # Record a fuzzy mark
+        if l[:2] == '#,' and 'fuzzy' in l:
+            fuzzy = 1
+        # Skip comments
+        if l[0] == '#':
+            continue
+        # Now we are in a msgid section, output previous section
+        if l.startswith('msgid'):
+            if section == STR:
+                add(msgid, msgstr, fuzzy)
+            section = ID
+            l = l[5:]
+            msgid = msgstr = ''
+        # Now we are in a msgstr section
+        elif l.startswith('msgstr'):
+            section = STR
+            l = l[6:]
+        # Skip empty lines
+        l = l.strip()
+        if not l:
+            continue
+        # XXX: Does this always follow Python escape semantics?
+        l = eval(l)
+        if section == ID:
+            msgid += l
+        elif section == STR:
+            msgstr += l
+        else:
+            print >> sys.stderr, 'Syntax error on %s:%d' % (infile, lno), \
+                  'before:'
+            print >> sys.stderr, l
+            sys.exit(1)
+    # Add last entry
+    if section == STR:
+        add(msgid, msgstr, fuzzy)
+
+    # Compute output
+    output = generate()
+
+    try:
+        open(outfile,"wb").write(output)
+    except IOError,msg:
+        print >> sys.stderr, msg
+
+
+
+def main():
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], 'hVo:',
+                                   ['help', 'version', 'output-file='])
+    except getopt.error, msg:
+        usage(1, msg)
+
+    outfile = None
+    # parse options
+    for opt, arg in opts:
+        if opt in ('-h', '--help'):
+            usage(0)
+        elif opt in ('-V', '--version'):
+            print >> sys.stderr, "msgfmt.py", __version__
+            sys.exit(0)
+        elif opt in ('-o', '--output-file'):
+            outfile = arg
+    # do it
+    if not args:
+        print >> sys.stderr, 'No input file given'
+        print >> sys.stderr, "Try `msgfmt --help' for more information."
+        return
+
+    for filename in args:
+        make(filename, outfile)
+
+
+if __name__ == '__main__':
+    main()


Property changes on: vendor/Python/current/Tools/i18n/msgfmt.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/i18n/pygettext.py
===================================================================
--- vendor/Python/current/Tools/i18n/pygettext.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/i18n/pygettext.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,669 @@
+#! /usr/bin/env python
+# -*- coding: iso-8859-1 -*-
+# Originally written by Barry Warsaw <barry at zope.com>
+#
+# Minimally patched to make it even more xgettext compatible
+# by Peter Funk <pf at artcom-gmbh.de>
+#
+# 2002-11-22 Jürgen Hermann <jh at web.de>
+# Added checks that _() only contains string literals, and
+# command line args are resolved to module lists, i.e. you
+# can now pass a filename, a module or package name, or a
+# directory (including globbing chars, important for Win32).
+# Made docstring fit in 80 chars wide displays using pydoc.
+#
+
+# for selftesting
+try:
+    import fintl
+    _ = fintl.gettext
+except ImportError:
+    _ = lambda s: s
+
+__doc__ = _("""pygettext -- Python equivalent of xgettext(1)
+
+Many systems (Solaris, Linux, Gnu) provide extensive tools that ease the
+internationalization of C programs. Most of these tools are independent of
+the programming language and can be used from within Python programs.
+Martin von Loewis' work[1] helps considerably in this regard.
+
+There's one problem though; xgettext is the program that scans source code
+looking for message strings, but it groks only C (or C++). Python
+introduces a few wrinkles, such as dual quoting characters, triple quoted
+strings, and raw strings. xgettext understands none of this.
+
+Enter pygettext, which uses Python's standard tokenize module to scan
+Python source code, generating .pot files identical to what GNU xgettext[2]
+generates for C and C++ code. From there, the standard GNU tools can be
+used.
+
+A word about marking Python strings as candidates for translation. GNU
+xgettext recognizes the following keywords: gettext, dgettext, dcgettext,
+and gettext_noop. But those can be a lot of text to include all over your
+code. C and C++ have a trick: they use the C preprocessor. Most
+internationalized C source includes a #define for gettext() to _() so that
+what has to be written in the source is much less. Thus these are both
+translatable strings:
+
+    gettext("Translatable String")
+    _("Translatable String")
+
+Python of course has no preprocessor so this doesn't work so well.  Thus,
+pygettext searches only for _() by default, but see the -k/--keyword flag
+below for how to augment this.
+
+ [1] http://www.python.org/workshops/1997-10/proceedings/loewis.html
+ [2] http://www.gnu.org/software/gettext/gettext.html
+
+NOTE: pygettext attempts to be option and feature compatible with GNU
+xgettext where ever possible. However some options are still missing or are
+not fully implemented. Also, xgettext's use of command line switches with
+option arguments is broken, and in these cases, pygettext just defines
+additional switches.
+
+Usage: pygettext [options] inputfile ...
+
+Options:
+
+    -a
+    --extract-all
+        Extract all strings.
+
+    -d name
+    --default-domain=name
+        Rename the default output file from messages.pot to name.pot.
+
+    -E
+    --escape
+        Replace non-ASCII characters with octal escape sequences.
+
+    -D
+    --docstrings
+        Extract module, class, method, and function docstrings.  These do
+        not need to be wrapped in _() markers, and in fact cannot be for
+        Python to consider them docstrings. (See also the -X option).
+
+    -h
+    --help
+        Print this help message and exit.
+
+    -k word
+    --keyword=word
+        Keywords to look for in addition to the default set, which are:
+        %(DEFAULTKEYWORDS)s
+
+        You can have multiple -k flags on the command line.
+
+    -K
+    --no-default-keywords
+        Disable the default set of keywords (see above).  Any keywords
+        explicitly added with the -k/--keyword option are still recognized.
+
+    --no-location
+        Do not write filename/lineno location comments.
+
+    -n
+    --add-location
+        Write filename/lineno location comments indicating where each
+        extracted string is found in the source.  These lines appear before
+        each msgid.  The style of comments is controlled by the -S/--style
+        option.  This is the default.
+
+    -o filename
+    --output=filename
+        Rename the default output file from messages.pot to filename.  If
+        filename is `-' then the output is sent to standard out.
+
+    -p dir
+    --output-dir=dir
+        Output files will be placed in directory dir.
+
+    -S stylename
+    --style stylename
+        Specify which style to use for location comments.  Two styles are
+        supported:
+
+        Solaris  # File: filename, line: line-number
+        GNU      #: filename:line
+
+        The style name is case insensitive.  GNU style is the default.
+
+    -v
+    --verbose
+        Print the names of the files being processed.
+
+    -V
+    --version
+        Print the version of pygettext and exit.
+
+    -w columns
+    --width=columns
+        Set width of output to columns.
+
+    -x filename
+    --exclude-file=filename
+        Specify a file that contains a list of strings that are not be
+        extracted from the input files.  Each string to be excluded must
+        appear on a line by itself in the file.
+
+    -X filename
+    --no-docstrings=filename
+        Specify a file that contains a list of files (one per line) that
+        should not have their docstrings extracted.  This is only useful in
+        conjunction with the -D option above.
+
+If `inputfile' is -, standard input is read.
+""")
+
+import os
+import imp
+import sys
+import glob
+import time
+import getopt
+import token
+import tokenize
+import operator
+
+__version__ = '1.5'
+
+default_keywords = ['_']
+DEFAULTKEYWORDS = ', '.join(default_keywords)
+
+EMPTYSTRING = ''
+
+
+
+# The normal pot-file header. msgmerge and Emacs's po-mode work better if it's
+# there.
+pot_header = _('''\
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR ORGANIZATION
+# FIRST AUTHOR <EMAIL at ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\\n"
+"POT-Creation-Date: %(time)s\\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n"
+"Last-Translator: FULL NAME <EMAIL at ADDRESS>\\n"
+"Language-Team: LANGUAGE <LL at li.org>\\n"
+"MIME-Version: 1.0\\n"
+"Content-Type: text/plain; charset=CHARSET\\n"
+"Content-Transfer-Encoding: ENCODING\\n"
+"Generated-By: pygettext.py %(version)s\\n"
+
+''')
+
+
+def usage(code, msg=''):
+    print >> sys.stderr, __doc__ % globals()
+    if msg:
+        print >> sys.stderr, msg
+    sys.exit(code)
+
+
+
+escapes = []
+
+def make_escapes(pass_iso8859):
+    global escapes
+    if pass_iso8859:
+        # Allow iso-8859 characters to pass through so that e.g. 'msgid
+        # "Höhe"' would result not result in 'msgid "H\366he"'.  Otherwise we
+        # escape any character outside the 32..126 range.
+        mod = 128
+    else:
+        mod = 256
+    for i in range(256):
+        if 32 <= (i % mod) <= 126:
+            escapes.append(chr(i))
+        else:
+            escapes.append("\\%03o" % i)
+    escapes[ord('\\')] = '\\\\'
+    escapes[ord('\t')] = '\\t'
+    escapes[ord('\r')] = '\\r'
+    escapes[ord('\n')] = '\\n'
+    escapes[ord('\"')] = '\\"'
+
+
+def escape(s):
+    global escapes
+    s = list(s)
+    for i in range(len(s)):
+        s[i] = escapes[ord(s[i])]
+    return EMPTYSTRING.join(s)
+
+
+def safe_eval(s):
+    # unwrap quotes, safely
+    return eval(s, {'__builtins__':{}}, {})
+
+
+def normalize(s):
+    # This converts the various Python string types into a format that is
+    # appropriate for .po files, namely much closer to C style.
+    lines = s.split('\n')
+    if len(lines) == 1:
+        s = '"' + escape(s) + '"'
+    else:
+        if not lines[-1]:
+            del lines[-1]
+            lines[-1] = lines[-1] + '\n'
+        for i in range(len(lines)):
+            lines[i] = escape(lines[i])
+        lineterm = '\\n"\n"'
+        s = '""\n"' + lineterm.join(lines) + '"'
+    return s
+
+
+def containsAny(str, set):
+    """Check whether 'str' contains ANY of the chars in 'set'"""
+    return 1 in [c in str for c in set]
+
+
+def _visit_pyfiles(list, dirname, names):
+    """Helper for getFilesForName()."""
+    # get extension for python source files
+    if not globals().has_key('_py_ext'):
+        global _py_ext
+        _py_ext = [triple[0] for triple in imp.get_suffixes()
+                   if triple[2] == imp.PY_SOURCE][0]
+
+    # don't recurse into CVS directories
+    if 'CVS' in names:
+        names.remove('CVS')
+
+    # add all *.py files to list
+    list.extend(
+        [os.path.join(dirname, file) for file in names
+         if os.path.splitext(file)[1] == _py_ext]
+        )
+
+
+def _get_modpkg_path(dotted_name, pathlist=None):
+    """Get the filesystem path for a module or a package.
+
+    Return the file system path to a file for a module, and to a directory for
+    a package. Return None if the name is not found, or is a builtin or
+    extension module.
+    """
+    # split off top-most name
+    parts = dotted_name.split('.', 1)
+
+    if len(parts) > 1:
+        # we have a dotted path, import top-level package
+        try:
+            file, pathname, description = imp.find_module(parts[0], pathlist)
+            if file: file.close()
+        except ImportError:
+            return None
+
+        # check if it's indeed a package
+        if description[2] == imp.PKG_DIRECTORY:
+            # recursively handle the remaining name parts
+            pathname = _get_modpkg_path(parts[1], [pathname])
+        else:
+            pathname = None
+    else:
+        # plain name
+        try:
+            file, pathname, description = imp.find_module(
+                dotted_name, pathlist)
+            if file:
+                file.close()
+            if description[2] not in [imp.PY_SOURCE, imp.PKG_DIRECTORY]:
+                pathname = None
+        except ImportError:
+            pathname = None
+
+    return pathname
+
+
+def getFilesForName(name):
+    """Get a list of module files for a filename, a module or package name,
+    or a directory.
+    """
+    if not os.path.exists(name):
+        # check for glob chars
+        if containsAny(name, "*?[]"):
+            files = glob.glob(name)
+            list = []
+            for file in files:
+                list.extend(getFilesForName(file))
+            return list
+
+        # try to find module or package
+        name = _get_modpkg_path(name)
+        if not name:
+            return []
+
+    if os.path.isdir(name):
+        # find all python files in directory
+        list = []
+        os.path.walk(name, _visit_pyfiles, list)
+        return list
+    elif os.path.exists(name):
+        # a single file
+        return [name]
+
+    return []
+
+
+class TokenEater:
+    def __init__(self, options):
+        self.__options = options
+        self.__messages = {}
+        self.__state = self.__waiting
+        self.__data = []
+        self.__lineno = -1
+        self.__freshmodule = 1
+        self.__curfile = None
+
+    def __call__(self, ttype, tstring, stup, etup, line):
+        # dispatch
+##        import token
+##        print >> sys.stderr, 'ttype:', token.tok_name[ttype], \
+##              'tstring:', tstring
+        self.__state(ttype, tstring, stup[0])
+
+    def __waiting(self, ttype, tstring, lineno):
+        opts = self.__options
+        # Do docstring extractions, if enabled
+        if opts.docstrings and not opts.nodocstrings.get(self.__curfile):
+            # module docstring?
+            if self.__freshmodule:
+                if ttype == tokenize.STRING:
+                    self.__addentry(safe_eval(tstring), lineno, isdocstring=1)
+                    self.__freshmodule = 0
+                elif ttype not in (tokenize.COMMENT, tokenize.NL):
+                    self.__freshmodule = 0
+                return
+            # class docstring?
+            if ttype == tokenize.NAME and tstring in ('class', 'def'):
+                self.__state = self.__suiteseen
+                return
+        if ttype == tokenize.NAME and tstring in opts.keywords:
+            self.__state = self.__keywordseen
+
+    def __suiteseen(self, ttype, tstring, lineno):
+        # ignore anything until we see the colon
+        if ttype == tokenize.OP and tstring == ':':
+            self.__state = self.__suitedocstring
+
+    def __suitedocstring(self, ttype, tstring, lineno):
+        # ignore any intervening noise
+        if ttype == tokenize.STRING:
+            self.__addentry(safe_eval(tstring), lineno, isdocstring=1)
+            self.__state = self.__waiting
+        elif ttype not in (tokenize.NEWLINE, tokenize.INDENT,
+                           tokenize.COMMENT):
+            # there was no class docstring
+            self.__state = self.__waiting
+
+    def __keywordseen(self, ttype, tstring, lineno):
+        if ttype == tokenize.OP and tstring == '(':
+            self.__data = []
+            self.__lineno = lineno
+            self.__state = self.__openseen
+        else:
+            self.__state = self.__waiting
+
+    def __openseen(self, ttype, tstring, lineno):
+        if ttype == tokenize.OP and tstring == ')':
+            # We've seen the last of the translatable strings.  Record the
+            # line number of the first line of the strings and update the list
+            # of messages seen.  Reset state for the next batch.  If there
+            # were no strings inside _(), then just ignore this entry.
+            if self.__data:
+                self.__addentry(EMPTYSTRING.join(self.__data))
+            self.__state = self.__waiting
+        elif ttype == tokenize.STRING:
+            self.__data.append(safe_eval(tstring))
+        elif ttype not in [tokenize.COMMENT, token.INDENT, token.DEDENT,
+                           token.NEWLINE, tokenize.NL]:
+            # warn if we see anything else than STRING or whitespace
+            print >> sys.stderr, _(
+                '*** %(file)s:%(lineno)s: Seen unexpected token "%(token)s"'
+                ) % {
+                'token': tstring,
+                'file': self.__curfile,
+                'lineno': self.__lineno
+                }
+            self.__state = self.__waiting
+
+    def __addentry(self, msg, lineno=None, isdocstring=0):
+        if lineno is None:
+            lineno = self.__lineno
+        if not msg in self.__options.toexclude:
+            entry = (self.__curfile, lineno)
+            self.__messages.setdefault(msg, {})[entry] = isdocstring
+
+    def set_filename(self, filename):
+        self.__curfile = filename
+        self.__freshmodule = 1
+
+    def write(self, fp):
+        options = self.__options
+        timestamp = time.strftime('%Y-%m-%d %H:%M+%Z')
+        # The time stamp in the header doesn't have the same format as that
+        # generated by xgettext...
+        print >> fp, pot_header % {'time': timestamp, 'version': __version__}
+        # Sort the entries.  First sort each particular entry's keys, then
+        # sort all the entries by their first item.
+        reverse = {}
+        for k, v in self.__messages.items():
+            keys = v.keys()
+            keys.sort()
+            reverse.setdefault(tuple(keys), []).append((k, v))
+        rkeys = reverse.keys()
+        rkeys.sort()
+        for rkey in rkeys:
+            rentries = reverse[rkey]
+            rentries.sort()
+            for k, v in rentries:
+                isdocstring = 0
+                # If the entry was gleaned out of a docstring, then add a
+                # comment stating so.  This is to aid translators who may wish
+                # to skip translating some unimportant docstrings.
+                if reduce(operator.__add__, v.values()):
+                    isdocstring = 1
+                # k is the message string, v is a dictionary-set of (filename,
+                # lineno) tuples.  We want to sort the entries in v first by
+                # file name and then by line number.
+                v = v.keys()
+                v.sort()
+                if not options.writelocations:
+                    pass
+                # location comments are different b/w Solaris and GNU:
+                elif options.locationstyle == options.SOLARIS:
+                    for filename, lineno in v:
+                        d = {'filename': filename, 'lineno': lineno}
+                        print >>fp, _(
+                            '# File: %(filename)s, line: %(lineno)d') % d
+                elif options.locationstyle == options.GNU:
+                    # fit as many locations on one line, as long as the
+                    # resulting line length doesn't exceeds 'options.width'
+                    locline = '#:'
+                    for filename, lineno in v:
+                        d = {'filename': filename, 'lineno': lineno}
+                        s = _(' %(filename)s:%(lineno)d') % d
+                        if len(locline) + len(s) <= options.width:
+                            locline = locline + s
+                        else:
+                            print >> fp, locline
+                            locline = "#:" + s
+                    if len(locline) > 2:
+                        print >> fp, locline
+                if isdocstring:
+                    print >> fp, '#, docstring'
+                print >> fp, 'msgid', normalize(k)
+                print >> fp, 'msgstr ""\n'
+
+
+
+def main():
+    global default_keywords
+    try:
+        opts, args = getopt.getopt(
+            sys.argv[1:],
+            'ad:DEhk:Kno:p:S:Vvw:x:X:',
+            ['extract-all', 'default-domain=', 'escape', 'help',
+             'keyword=', 'no-default-keywords',
+             'add-location', 'no-location', 'output=', 'output-dir=',
+             'style=', 'verbose', 'version', 'width=', 'exclude-file=',
+             'docstrings', 'no-docstrings',
+             ])
+    except getopt.error, msg:
+        usage(1, msg)
+
+    # for holding option values
+    class Options:
+        # constants
+        GNU = 1
+        SOLARIS = 2
+        # defaults
+        extractall = 0 # FIXME: currently this option has no effect at all.
+        escape = 0
+        keywords = []
+        outpath = ''
+        outfile = 'messages.pot'
+        writelocations = 1
+        locationstyle = GNU
+        verbose = 0
+        width = 78
+        excludefilename = ''
+        docstrings = 0
+        nodocstrings = {}
+
+    options = Options()
+    locations = {'gnu' : options.GNU,
+                 'solaris' : options.SOLARIS,
+                 }
+
+    # parse options
+    for opt, arg in opts:
+        if opt in ('-h', '--help'):
+            usage(0)
+        elif opt in ('-a', '--extract-all'):
+            options.extractall = 1
+        elif opt in ('-d', '--default-domain'):
+            options.outfile = arg + '.pot'
+        elif opt in ('-E', '--escape'):
+            options.escape = 1
+        elif opt in ('-D', '--docstrings'):
+            options.docstrings = 1
+        elif opt in ('-k', '--keyword'):
+            options.keywords.append(arg)
+        elif opt in ('-K', '--no-default-keywords'):
+            default_keywords = []
+        elif opt in ('-n', '--add-location'):
+            options.writelocations = 1
+        elif opt in ('--no-location',):
+            options.writelocations = 0
+        elif opt in ('-S', '--style'):
+            options.locationstyle = locations.get(arg.lower())
+            if options.locationstyle is None:
+                usage(1, _('Invalid value for --style: %s') % arg)
+        elif opt in ('-o', '--output'):
+            options.outfile = arg
+        elif opt in ('-p', '--output-dir'):
+            options.outpath = arg
+        elif opt in ('-v', '--verbose'):
+            options.verbose = 1
+        elif opt in ('-V', '--version'):
+            print _('pygettext.py (xgettext for Python) %s') % __version__
+            sys.exit(0)
+        elif opt in ('-w', '--width'):
+            try:
+                options.width = int(arg)
+            except ValueError:
+                usage(1, _('--width argument must be an integer: %s') % arg)
+        elif opt in ('-x', '--exclude-file'):
+            options.excludefilename = arg
+        elif opt in ('-X', '--no-docstrings'):
+            fp = open(arg)
+            try:
+                while 1:
+                    line = fp.readline()
+                    if not line:
+                        break
+                    options.nodocstrings[line[:-1]] = 1
+            finally:
+                fp.close()
+
+    # calculate escapes
+    make_escapes(options.escape)
+
+    # calculate all keywords
+    options.keywords.extend(default_keywords)
+
+    # initialize list of strings to exclude
+    if options.excludefilename:
+        try:
+            fp = open(options.excludefilename)
+            options.toexclude = fp.readlines()
+            fp.close()
+        except IOError:
+            print >> sys.stderr, _(
+                "Can't read --exclude-file: %s") % options.excludefilename
+            sys.exit(1)
+    else:
+        options.toexclude = []
+
+    # resolve args to module lists
+    expanded = []
+    for arg in args:
+        if arg == '-':
+            expanded.append(arg)
+        else:
+            expanded.extend(getFilesForName(arg))
+    args = expanded
+
+    # slurp through all the files
+    eater = TokenEater(options)
+    for filename in args:
+        if filename == '-':
+            if options.verbose:
+                print _('Reading standard input')
+            fp = sys.stdin
+            closep = 0
+        else:
+            if options.verbose:
+                print _('Working on %s') % filename
+            fp = open(filename)
+            closep = 1
+        try:
+            eater.set_filename(filename)
+            try:
+                tokenize.tokenize(fp.readline, eater)
+            except tokenize.TokenError, e:
+                print >> sys.stderr, '%s: %s, line %d, column %d' % (
+                    e[0], filename, e[1][0], e[1][1])
+        finally:
+            if closep:
+                fp.close()
+
+    # write the output
+    if options.outfile == '-':
+        fp = sys.stdout
+        closep = 0
+    else:
+        if options.outpath:
+            options.outfile = os.path.join(options.outpath, options.outfile)
+        fp = open(options.outfile, 'w')
+        closep = 1
+    try:
+        eater.write(fp)
+    finally:
+        if closep:
+            fp.close()
+
+
+if __name__ == '__main__':
+    main()
+    # some more test strings
+    _(u'a unicode string')
+    # this one creates a warning
+    _('*** Seen unexpected token "%(token)s"') % {'token': 'test'}
+    _('more' 'than' 'one' 'string')


Property changes on: vendor/Python/current/Tools/i18n/pygettext.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/modulator/EXAMPLE.py
===================================================================
--- vendor/Python/current/Tools/modulator/EXAMPLE.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/modulator/EXAMPLE.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,53 @@
+#
+# Example input file for modulator if you don't have tk.
+#
+# You may also have to strip some imports out of modulator to make
+# it work.
+
+import genmodule
+
+#
+# Generate code for a simple object with a method called sample
+
+o = genmodule.object()
+o.name = 'simple object'
+o.abbrev = 'simp'
+o.methodlist = ['sample']
+o.funclist = ['new']
+
+#
+# Generate code for an object that looks numberish
+#
+o2 = genmodule.object()
+o2.name = 'number-like object'
+o2.abbrev = 'nl'
+o2.typelist = ['tp_as_number']
+o2.funclist = ['new', 'tp_repr', 'tp_compare']
+
+#
+# Generate code for a method with a full complement of functions,
+# some methods, accessible as sequence and allowing structmember.c type
+# structure access as well.
+#
+o3 = genmodule.object()
+o3.name = 'over-the-top object'
+o3.abbrev = 'ot'
+o3.methodlist = ['method1', 'method2']
+o3.funclist = ['new', 'tp_dealloc', 'tp_print', 'tp_getattr', 'tp_setattr',
+            'tp_compare', 'tp_repr', 'tp_hash']
+o3.typelist = ['tp_as_sequence', 'structure']
+
+#
+# Now generate code for a module that incorporates these object types.
+# Also add the boilerplates for functions to create instances of each
+# type.
+#
+m = genmodule.module()
+m.name = 'sample'
+m.abbrev = 'sample'
+m.methodlist = ['newsimple', 'newnumberish', 'newott']
+m.objects = [o, o2, o3]
+
+fp = open('EXAMPLEmodule.c', 'w')
+genmodule.write(fp, m)
+fp.close()

Added: vendor/Python/current/Tools/modulator/README
===================================================================
--- vendor/Python/current/Tools/modulator/README	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/modulator/README	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,25 @@
+This is release 1.2 of modulator, a generator of boilerplate code for
+modules to be written in C.
+
+Difference between 1.2 and 1.1: __doc__ templates are now generated
+(thanks to Jim Fulton).
+
+Difference between 1.1 and 1.0: the templates now use "new-style"
+naming conventions. Many thanks to Chak Tan <tan at ee.rochester.edu> for
+supplying them.
+
+Usage when you have tk is *really* simple: start modulator, fill out
+the forms specifying all the objects and methods, tell modulator
+whether objects should also be accessible as sequences, etc and press
+'generate code'. It will write a complete skeleton module for you.
+
+Usage when you don't have tk is slightly more difficult. Look at
+EXAMPLE.py for some details (to run, use "python EXAMPLE.py").  Don't
+bother with EXAMPLE.py if you have Tkinter!!!
+
+Oh yeah: you'll probably want to change Templates/copyright, or all
+your code ends up as being copyrighted to CWI:-)
+
+Let me know what you think,
+				Jack Jansen, jack at cwi.nl
+				

Added: vendor/Python/current/Tools/modulator/ScrolledListbox.py
===================================================================
--- vendor/Python/current/Tools/modulator/ScrolledListbox.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/modulator/ScrolledListbox.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,37 @@
+# A ScrolledList widget feels like a list widget but also has a
+# vertical scroll bar on its right.  (Later, options may be added to
+# add a horizontal bar as well, to make the bars disappear
+# automatically when not needed, to move them to the other side of the
+# window, etc.)
+#
+# Configuration options are passed to the List widget.
+# A Frame widget is inserted between the master and the list, to hold
+# the Scrollbar widget.
+# Most methods calls are inherited from the List widget; Pack methods
+# are redirected to the Frame widget however.
+
+from Tkinter import *
+from Tkinter import _cnfmerge
+
+class ScrolledListbox(Listbox):
+    def __init__(self, master=None, cnf={}):
+        cnf = _cnfmerge(cnf)
+        fcnf = {}
+        vcnf = {'name': 'vbar',
+            Pack: {'side': 'right', 'fill': 'y'},}
+        for k in cnf.keys():
+            if type(k) == ClassType or k == 'name':
+                fcnf[k] = cnf[k]
+                del cnf[k]
+        self.frame = Frame(master, fcnf)
+        self.vbar = Scrollbar(self.frame, vcnf)
+        cnf[Pack] = {'side': 'left', 'fill': 'both', 'expand': 'yes'}
+        cnf['name'] = 'list'
+        Listbox.__init__(self, self.frame, cnf)
+        self['yscrollcommand'] = (self.vbar, 'set')
+        self.vbar['command'] = (self, 'yview')
+
+        # Copy Pack methods of self.frame -- hack!
+        for m in Pack.__dict__.keys():
+            if m[0] != '_' and m != 'config':
+                setattr(self, m, getattr(self.frame, m))

Added: vendor/Python/current/Tools/modulator/Templates/copyright
===================================================================

Added: vendor/Python/current/Tools/modulator/Templates/module_head
===================================================================
--- vendor/Python/current/Tools/modulator/Templates/module_head	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/modulator/Templates/module_head	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,6 @@
+
+#include "Python.h"
+
+static PyObject *ErrorObject;
+
+/* ----------------------------------------------------- */

Added: vendor/Python/current/Tools/modulator/Templates/module_method
===================================================================
--- vendor/Python/current/Tools/modulator/Templates/module_method	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/modulator/Templates/module_method	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,14 @@
+
+static char $abbrev$_$method$__doc__[] =
+""
+;
+
+static PyObject *
+$abbrev$_$method$(PyObject *self /* Not used */, PyObject *args)
+{
+
+	if (!PyArg_ParseTuple(args, ""))
+		return NULL;
+	Py_INCREF(Py_None);
+	return Py_None;
+}

Added: vendor/Python/current/Tools/modulator/Templates/module_tail
===================================================================
--- vendor/Python/current/Tools/modulator/Templates/module_tail	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/modulator/Templates/module_tail	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,37 @@
+
+/* List of methods defined in the module */
+
+static struct PyMethodDef $abbrev$_methods[] = {
+	$methodlist$
+	{NULL,	 (PyCFunction)NULL, 0, NULL}		/* sentinel */
+};
+
+
+/* Initialization function for the module (*must* be called init$name$) */
+
+static char $name$_module_documentation[] = 
+""
+;
+
+void
+init$name$()
+{
+	PyObject *m, *d;
+
+	/* Create the module and add the functions */
+	m = Py_InitModule4("$name$", $abbrev$_methods,
+		$name$_module_documentation,
+		(PyObject*)NULL,PYTHON_API_VERSION);
+
+	/* Add some symbolic constants to the module */
+	d = PyModule_GetDict(m);
+	ErrorObject = PyString_FromString("$name$.error");
+	PyDict_SetItemString(d, "error", ErrorObject);
+
+	/* XXXX Add constants here */
+	
+	/* Check for errors */
+	if (PyErr_Occurred())
+		Py_FatalError("can't initialize module $name$");
+}
+

Added: vendor/Python/current/Tools/modulator/Templates/object_head
===================================================================
--- vendor/Python/current/Tools/modulator/Templates/object_head	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/modulator/Templates/object_head	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,13 @@
+
+/* Declarations for objects of type $name$ */
+
+typedef struct {
+	PyObject_HEAD
+	/* XXXX Add your own stuff here */
+} $abbrev$object;
+
+static PyTypeObject $Abbrev$type;
+
+
+
+/* ---------------------------------------------------------------- */

Added: vendor/Python/current/Tools/modulator/Templates/object_method
===================================================================
--- vendor/Python/current/Tools/modulator/Templates/object_method	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/modulator/Templates/object_method	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,14 @@
+
+static char $abbrev$_$method$__doc__[] = 
+""
+;
+
+static PyObject *
+$abbrev$_$method$($abbrev$object *self, PyObject *args)
+{
+	if (!PyArg_ParseTuple(args, ""))
+		return NULL;
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+

Added: vendor/Python/current/Tools/modulator/Templates/object_mlist
===================================================================
--- vendor/Python/current/Tools/modulator/Templates/object_mlist	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/modulator/Templates/object_mlist	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,8 @@
+
+static struct PyMethodDef $abbrev$_methods[] = {
+	$methodlist$
+	{NULL,		NULL}		/* sentinel */
+};
+
+/* ---------- */
+

Added: vendor/Python/current/Tools/modulator/Templates/object_new
===================================================================
--- vendor/Python/current/Tools/modulator/Templates/object_new	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/modulator/Templates/object_new	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,13 @@
+
+static $abbrev$object *
+new$abbrev$object()
+{
+	$abbrev$object *self;
+	
+	self = PyObject_NEW($abbrev$object, &$Abbrev$type);
+	if (self == NULL)
+		return NULL;
+	/* XXXX Add your own initializers here */
+	return self;
+}
+

Added: vendor/Python/current/Tools/modulator/Templates/object_structure
===================================================================
--- vendor/Python/current/Tools/modulator/Templates/object_structure	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/modulator/Templates/object_structure	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,37 @@
+
+/* Code to access structure members by accessing attributes */
+
+#include "structmember.h"
+
+#define OFF(x) offsetof(XXXXobject, x)
+
+static struct memberlist $abbrev$_memberlist[] = {
+	/* XXXX Add lines like { "foo", T_INT, OFF(foo), RO }  */
+
+	{NULL}	/* Sentinel */
+};
+
+static PyObject *
+$abbrev$_getattr($abbrev$object *self, char *name)
+{
+	PyObject *rv;
+	
+	/* XXXX Add your own getattr code here */
+	rv = PyMember_Get((char *)/*XXXX*/0, $abbrev$_memberlist, name);
+	if (rv)
+		return rv;
+	PyErr_Clear();
+	return Py_FindMethod($abbrev$_methods, (PyObject *)self, name);
+}
+
+
+static int
+$abbrev$_setattr($abbrev$object *self, char *name, PyObject *v)
+{
+	/* XXXX Add your own setattr code here */
+	if ( v == NULL ) {
+		PyErr_SetString(PyExc_AttributeError, "Cannot delete attribute");
+		return -1;
+	}
+	return PyMember_Set((char *)/*XXXX*/0, $abbrev$_memberlist, name, v);
+}

Added: vendor/Python/current/Tools/modulator/Templates/object_tail
===================================================================
--- vendor/Python/current/Tools/modulator/Templates/object_tail	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/modulator/Templates/object_tail	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,33 @@
+
+static char $Abbrev$type__doc__[] = 
+""
+;
+
+static PyTypeObject $Abbrev$type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,				/*ob_size*/
+	"$name$",			/*tp_name*/
+	sizeof($abbrev$object),		/*tp_basicsize*/
+	0,				/*tp_itemsize*/
+	/* methods */
+	(destructor)$tp_dealloc$,	/*tp_dealloc*/
+	(printfunc)$tp_print$,		/*tp_print*/
+	(getattrfunc)$tp_getattr$,	/*tp_getattr*/
+	(setattrfunc)$tp_setattr$,	/*tp_setattr*/
+	(cmpfunc)$tp_compare$,		/*tp_compare*/
+	(reprfunc)$tp_repr$,		/*tp_repr*/
+	$tp_as_number$,			/*tp_as_number*/
+	$tp_as_sequence$,		/*tp_as_sequence*/
+	$tp_as_mapping$,		/*tp_as_mapping*/
+	(hashfunc)$tp_hash$,		/*tp_hash*/
+	(ternaryfunc)$tp_call$,		/*tp_call*/
+	(reprfunc)$tp_str$,		/*tp_str*/
+
+	/* Space for future expansion */
+	0L,0L,0L,0L,
+	$Abbrev$type__doc__ /* Documentation string */
+};
+
+/* End of code for $name$ objects */
+/* -------------------------------------------------------- */
+

Added: vendor/Python/current/Tools/modulator/Templates/object_tp_as_mapping
===================================================================
--- vendor/Python/current/Tools/modulator/Templates/object_tp_as_mapping	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/modulator/Templates/object_tp_as_mapping	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,29 @@
+
+/* Code to access $name$ objects as mappings */
+
+static int
+$abbrev$_length($abbrev$object *self)
+{
+	/* XXXX Return the size of the mapping */
+}
+
+static PyObject *
+$abbrev$_subscript($abbrev$object *self, PyObject *key)
+{
+	/* XXXX Return the item of self indexed by key */
+}
+
+static int
+$abbrev$_ass_sub($abbrev$object *self, PyObject *v, PyObject *w)
+{
+	/* XXXX Put w in self under key v */
+	return 0;
+}
+
+static PyMappingMethods $abbrev$_as_mapping = {
+	(inquiry)$abbrev$_length,		/*mp_length*/
+	(binaryfunc)$abbrev$_subscript,		/*mp_subscript*/
+	(objobjargproc)$abbrev$_ass_sub,	/*mp_ass_subscript*/
+};
+
+/* -------------------------------------------------------- */

Added: vendor/Python/current/Tools/modulator/Templates/object_tp_as_number
===================================================================
--- vendor/Python/current/Tools/modulator/Templates/object_tp_as_number	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/modulator/Templates/object_tp_as_number	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,169 @@
+
+/* Code to access $name$ objects as numbers */
+
+static PyObject *
+$abbrev$_add($abbrev$object *v, $abbrev$object *w)
+{
+	/* XXXX Add them */
+}
+
+static PyObject *
+$abbrev$_sub($abbrev$object *v, $abbrev$object *w)
+{
+	/* XXXX Subtract them */
+}
+
+static PyObject *
+$abbrev$_mul($abbrev$object *v, $abbrev$object *w)
+{
+	/* XXXX Multiply them */
+}
+
+static PyObject *
+$abbrev$_div($abbrev$object *x, $abbrev$object *y)
+{
+	/* XXXX Divide them */
+}
+
+static PyObject *
+$abbrev$_mod($abbrev$object *x, $abbrev$object *y)
+{
+	/* XXXX Modulo them */
+}
+
+static PyObject *
+$abbrev$_divmod($abbrev$object *x, $abbrev$object *y)
+{
+	/* XXXX Return 2-tuple with div and mod */
+}
+
+static PyObject *
+$abbrev$_pow($abbrev$object *v, $abbrev$object *w, $abbrev$object *z)
+{
+	/* XXXX */
+}				
+
+static PyObject *
+$abbrev$_neg($abbrev$object *v)
+{
+	/* XXXX */
+}
+
+static PyObject *
+$abbrev$_pos($abbrev$object *v)
+{
+	/* XXXX */
+}
+
+static PyObject *
+$abbrev$_abs($abbrev$object *v)
+{
+	/* XXXX */
+}
+
+static int
+$abbrev$_nonzero($abbrev$object *v)
+{
+	/* XXXX Return 1 if non-zero */
+}
+
+static PyObject *
+$abbrev$_invert($abbrev$object *v)
+{
+	/* XXXX */
+}
+
+static PyObject *
+$abbrev$_lshift($abbrev$object *v, $abbrev$object *w)
+{
+	/* XXXX */
+}
+
+static PyObject *
+$abbrev$_rshift($abbrev$object *v, $abbrev$object *w)
+{
+	/* XXXX */
+}
+
+static PyObject *
+$abbrev$_and($abbrev$object *v, $abbrev$object *w)
+{
+	/* XXXX */
+}
+
+static PyObject *
+$abbrev$_xor($abbrev$object *v, $abbrev$object *w)
+{
+	/* XXXX */
+}
+
+static PyObject *
+$abbrev$_or($abbrev$object *v, $abbrev$object *w)
+{
+	/* XXXX */
+}
+
+static int
+$abbrev$_coerce(PyObject **pv, PyObject **pw)
+{
+	/* XXXX I haven't a clue... */
+	return 1;
+}
+
+static PyObject *
+$abbrev$_int($abbrev$object *v)
+{
+	/* XXXX */
+}
+
+static PyObject *
+$abbrev$_long($abbrev$object *v)
+{
+	/* XXXX */
+}
+
+static PyObject *
+$abbrev$_float($abbrev$object *v)
+{
+	/* XXXX */
+}
+
+static PyObject *
+$abbrev$_oct($abbrev$object *v)
+{
+	/* XXXX Return object as octal stringobject */
+}
+
+static PyObject *
+$abbrev$_hex($abbrev$object *v)
+{
+	/* XXXX Return object as hex stringobject */
+}
+
+static PyNumberMethods $abbrev$_as_number = {
+	(binaryfunc)$abbrev$_add,	/*nb_add*/
+	(binaryfunc)$abbrev$_sub,	/*nb_subtract*/
+	(binaryfunc)$abbrev$_mul,	/*nb_multiply*/
+	(binaryfunc)$abbrev$_div,	/*nb_divide*/
+	(binaryfunc)$abbrev$_mod,	/*nb_remainder*/
+	(binaryfunc)$abbrev$_divmod,	/*nb_divmod*/
+	(ternaryfunc)$abbrev$_pow,	/*nb_power*/
+	(unaryfunc)$abbrev$_neg,	/*nb_negative*/
+	(unaryfunc)$abbrev$_pos,	/*nb_positive*/
+	(unaryfunc)$abbrev$_abs,	/*nb_absolute*/
+	(inquiry)$abbrev$_nonzero,	/*nb_nonzero*/
+	(unaryfunc)$abbrev$_invert,	/*nb_invert*/
+	(binaryfunc)$abbrev$_lshift,	/*nb_lshift*/
+	(binaryfunc)$abbrev$_rshift,	/*nb_rshift*/
+	(binaryfunc)$abbrev$_and,	/*nb_and*/
+	(binaryfunc)$abbrev$_xor,	/*nb_xor*/
+	(binaryfunc)$abbrev$_or,	/*nb_or*/
+	(coercion)$abbrev$_coerce,	/*nb_coerce*/
+	(unaryfunc)$abbrev$_int,	/*nb_int*/
+	(unaryfunc)$abbrev$_long,	/*nb_long*/
+	(unaryfunc)$abbrev$_float,	/*nb_float*/
+	(unaryfunc)$abbrev$_oct,	/*nb_oct*/
+	(unaryfunc)$abbrev$_hex,	/*nb_hex*/
+};
+
+/* ------------------------------------------------------- */

Added: vendor/Python/current/Tools/modulator/Templates/object_tp_as_sequence
===================================================================
--- vendor/Python/current/Tools/modulator/Templates/object_tp_as_sequence	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/modulator/Templates/object_tp_as_sequence	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,58 @@
+
+/* Code to handle accessing $name$ objects as sequence objects */
+
+static int
+$abbrev$_length($abbrev$object *self)
+{
+	/* XXXX Return the size of the object */
+}
+
+static PyObject *
+$abbrev$_concat($abbrev$object *self, PyObject *bb)
+{
+	/* XXXX Return the concatenation of self and bb */
+}
+
+static PyObject *
+$abbrev$_repeat($abbrev$object *self, int n)
+{
+	/* XXXX Return a new object that is n times self */
+}
+
+static PyObject *
+$abbrev$_item($abbrev$object *self, int i)
+{
+	/* XXXX Return the i-th object of self */
+}
+
+static PyObject *
+$abbrev$_slice($abbrev$object *self, int ilow, int ihigh)
+{
+	/* XXXX Return the ilow..ihigh slice of self in a new object */
+}
+
+static int
+$abbrev$_ass_item($abbrev$object *self, int i, PyObject *v)
+{
+	/* XXXX Assign to the i-th element of self */
+	return 0;
+}
+
+static int
+$abbrev$_ass_slice(PyListObject *self, int ilow, int ihigh, PyObject *v)
+{
+	/* XXXX Replace ilow..ihigh slice of self with v */
+	return 0;
+}
+
+static PySequenceMethods $abbrev$_as_sequence = {
+	(inquiry)$abbrev$_length,		/*sq_length*/
+	(binaryfunc)$abbrev$_concat,		/*sq_concat*/
+	(intargfunc)$abbrev$_repeat,		/*sq_repeat*/
+	(intargfunc)$abbrev$_item,		/*sq_item*/
+	(intintargfunc)$abbrev$_slice,		/*sq_slice*/
+	(intobjargproc)$abbrev$_ass_item,	/*sq_ass_item*/
+	(intintobjargproc)$abbrev$_ass_slice,	/*sq_ass_slice*/
+};
+
+/* -------------------------------------------------------------- */

Added: vendor/Python/current/Tools/modulator/Templates/object_tp_call
===================================================================
--- vendor/Python/current/Tools/modulator/Templates/object_tp_call	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/modulator/Templates/object_tp_call	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,7 @@
+
+static PyObject *
+$abbrev$_call($abbrev$object *self, PyObject *args, PyObject *kwargs)
+{
+	/* XXXX Return the result of calling self with argument args */
+}
+

Added: vendor/Python/current/Tools/modulator/Templates/object_tp_compare
===================================================================
--- vendor/Python/current/Tools/modulator/Templates/object_tp_compare	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/modulator/Templates/object_tp_compare	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,6 @@
+
+static int
+$abbrev$_compare($abbrev$object *v, $abbrev$object *w)
+{
+	/* XXXX Compare objects and return -1, 0 or 1 */
+}

Added: vendor/Python/current/Tools/modulator/Templates/object_tp_dealloc
===================================================================
--- vendor/Python/current/Tools/modulator/Templates/object_tp_dealloc	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/modulator/Templates/object_tp_dealloc	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,7 @@
+
+static void
+$abbrev$_dealloc($abbrev$object *self)
+{
+	/* XXXX Add your own cleanup code here */
+	PyMem_DEL(self);
+}

Added: vendor/Python/current/Tools/modulator/Templates/object_tp_getattr
===================================================================
--- vendor/Python/current/Tools/modulator/Templates/object_tp_getattr	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/modulator/Templates/object_tp_getattr	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,7 @@
+
+static PyObject *
+$abbrev$_getattr($abbrev$object *self, char *name)
+{
+	/* XXXX Add your own getattr code here */
+	return Py_FindMethod($abbrev$_methods, (PyObject *)self, name);
+}

Added: vendor/Python/current/Tools/modulator/Templates/object_tp_hash
===================================================================
--- vendor/Python/current/Tools/modulator/Templates/object_tp_hash	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/modulator/Templates/object_tp_hash	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,6 @@
+
+static long
+$abbrev$_hash($abbrev$object *self)
+{
+	/* XXXX Return a hash of self (or -1) */
+}

Added: vendor/Python/current/Tools/modulator/Templates/object_tp_print
===================================================================
--- vendor/Python/current/Tools/modulator/Templates/object_tp_print	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/modulator/Templates/object_tp_print	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,7 @@
+
+static int
+$abbrev$_print($abbrev$object *self, FILE *fp, int flags)
+{
+	/* XXXX Add code here to print self to fp */
+	return 0;
+}

Added: vendor/Python/current/Tools/modulator/Templates/object_tp_repr
===================================================================
--- vendor/Python/current/Tools/modulator/Templates/object_tp_repr	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/modulator/Templates/object_tp_repr	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,9 @@
+
+static PyObject *
+$abbrev$_repr($abbrev$object *self)
+{
+	PyObject *s;
+
+	/* XXXX Add code here to put self into s */
+	return s;
+}

Added: vendor/Python/current/Tools/modulator/Templates/object_tp_setattr
===================================================================
--- vendor/Python/current/Tools/modulator/Templates/object_tp_setattr	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/modulator/Templates/object_tp_setattr	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,9 @@
+
+static int
+$abbrev$_setattr($abbrev$object *self, char *name, PyObject *v)
+{
+	/* Set attribute 'name' to value 'v'. v==NULL means delete */
+	
+	/* XXXX Add your own setattr code here */
+	return -1;
+}

Added: vendor/Python/current/Tools/modulator/Templates/object_tp_str
===================================================================
--- vendor/Python/current/Tools/modulator/Templates/object_tp_str	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/modulator/Templates/object_tp_str	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,10 @@
+
+static PyObject *
+$abbrev$_str($abbrev$object *self)
+{
+	PyObject *s;
+
+	/* XXXX Add code here to put self into s */
+	return s;
+}
+

Added: vendor/Python/current/Tools/modulator/Tkextra.py
===================================================================
--- vendor/Python/current/Tools/modulator/Tkextra.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/modulator/Tkextra.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,235 @@
+#! /usr/bin/env python
+
+# A Python function that generates dialog boxes with a text message,
+# optional bitmap, and any number of buttons.
+# Cf. Ousterhout, Tcl and the Tk Toolkit, Figs. 27.2-3, pp. 269-270.
+
+from Tkinter import *
+
+mainWidget = None
+
+def dialog(master, title, text, bitmap, default, *args):
+
+    # 1. Create the top-level window and divide it into top
+    # and bottom parts.
+
+    w = Toplevel(master, {'class': 'Dialog'})
+    w.title(title)
+    w.iconname('Dialog')
+
+    top = Frame(w, {'relief': 'raised', 'bd': 1,
+                    Pack: {'side': 'top', 'fill': 'both'}})
+    bot = Frame(w, {'relief': 'raised', 'bd': 1,
+                    Pack: {'side': 'bottom', 'fill': 'both'}})
+
+    # 2. Fill the top part with the bitmap and message.
+
+    msg = Message(top,
+                  {'width': '3i',
+                   'text': text,
+                   'font': '-Adobe-Times-Medium-R-Normal-*-180-*',
+                   Pack: {'side': 'right', 'expand': 1,
+                          'fill': 'both',
+                          'padx': '3m', 'pady': '3m'}})
+    if bitmap:
+        bm = Label(top, {'bitmap': bitmap,
+                         Pack: {'side': 'left',
+                                'padx': '3m', 'pady': '3m'}})
+
+    # 3. Create a row of buttons at the bottom of the dialog.
+
+    buttons = []
+    i = 0
+    for but in args:
+        b = Button(bot, {'text': but,
+                         'command': ('set', 'button', i)})
+        buttons.append(b)
+        if i == default:
+            bd = Frame(bot, {'relief': 'sunken', 'bd': 1,
+                             Pack: {'side': 'left', 'expand': 1,
+                                    'padx': '3m', 'pady': '2m'}})
+            b.lift()
+            b.pack ({'in': bd, 'side': 'left',
+                     'padx': '2m', 'pady': '2m',
+                     'ipadx': '2m', 'ipady': '1m'})
+        else:
+            b.pack ({'side': 'left', 'expand': 1,
+                     'padx': '3m', 'pady': '3m',
+                     'ipady': '2m', 'ipady': '1m'})
+        i = i+1
+
+    # 4. Set up a binding for <Return>, if there's a default,
+    # set a grab, and claim the focus too.
+
+    if default >= 0:
+        w.bind('<Return>',
+               lambda e, b=buttons[default], i=default:
+               (b.flash(),
+                b.setvar('button', i)))
+
+    oldFocus = w.tk.call('focus') # XXX
+    w.grab_set()
+    w.focus()
+
+    # 5. Wait for the user to respond, then restore the focus
+    # and return the index of the selected button.
+
+    w.waitvar('button')
+    w.destroy()
+    w.tk.call('focus', oldFocus) # XXX
+    return w.getint(w.getvar('button'))
+
+def strdialog(master, title, text, bitmap, default, *args):
+
+    # 1. Create the top-level window and divide it into top
+    # and bottom parts.
+
+    w = Toplevel(master, {'class': 'Dialog'})
+    w.title(title)
+    w.iconname('Dialog')
+
+    top = Frame(w, {'relief': 'raised', 'bd': 1,
+                    Pack: {'side': 'top', 'fill': 'both'}})
+    if args:
+        bot = Frame(w, {'relief': 'raised', 'bd': 1,
+                    Pack: {'side': 'bottom', 'fill': 'both'}})
+
+    # 2. Fill the top part with the bitmap, message and input field.
+
+    if bitmap:
+        bm = Label(top, {'bitmap': bitmap,
+                         Pack: {'side': 'left',
+                                'padx': '3m', 'pady': '3m'}})
+
+    msg = Message(top,
+                  {'width': '3i',
+                   'text': text,
+                   'font': '-Adobe-Times-Medium-R-Normal-*-180-*',
+                   Pack: {'side': 'left',
+                          'fill': 'both',
+                          'padx': '3m', 'pady': '3m'}})
+
+    field = Entry(top,
+                  {'relief':'sunken',
+                   Pack:{'side':'left',
+                         'fill':'x',
+                         'expand':1,
+                         'padx':'3m', 'pady':'3m'}})
+    # 3. Create a row of buttons at the bottom of the dialog.
+
+    buttons = []
+    i = 0
+    for but in args:
+        b = Button(bot, {'text': but,
+                         'command': ('set', 'button', i)})
+        buttons.append(b)
+        if i == default:
+            bd = Frame(bot, {'relief': 'sunken', 'bd': 1,
+                             Pack: {'side': 'left', 'expand': 1,
+                                    'padx': '3m', 'pady': '2m'}})
+            b.lift()
+            b.pack ({'in': bd, 'side': 'left',
+                     'padx': '2m', 'pady': '2m',
+                     'ipadx': '2m', 'ipady': '1m'})
+        else:
+            b.pack ({'side': 'left', 'expand': 1,
+                     'padx': '3m', 'pady': '3m',
+                     'ipady': '2m', 'ipady': '1m'})
+        i = i+1
+
+    # 4. Set up a binding for <Return>, if there's a default,
+    # set a grab, and claim the focus too.
+
+    if not args:
+        w.bind('<Return>', lambda arg, top=top: top.setvar('button', 0))
+        field.bind('<Return>', lambda arg, top=top: top.setvar('button', 0))
+    elif default >= 0:
+        w.bind('<Return>',
+               lambda e, b=buttons[default], i=default:
+               (b.flash(),
+                b.setvar('button', i)))
+        field.bind('<Return>',
+               lambda e, b=buttons[default], i=default:
+               (b.flash(),
+                b.setvar('button', i)))
+
+    oldFocus = w.tk.call('focus') # XXX
+    w.grab_set()
+    field.focus()
+
+    # 5. Wait for the user to respond, then restore the focus
+    # and return the index of the selected button.
+
+    w.waitvar('button')
+    v = field.get()
+    w.destroy()
+    w.tk.call('focus', oldFocus) # XXX
+    if args:
+        return v, w.getint(w.getvar('button'))
+    else:
+        return v
+
+def message(str):
+    i = dialog(mainWidget, 'Message', str, '', 0, 'OK')
+
+def askyn(str):
+    i = dialog(mainWidget, 'Question', str, '', 0, 'No', 'Yes')
+    return i
+
+def askync(str):
+    i = dialog(mainWidget, 'Question', str, '', 0, 'Cancel', 'No', 'Yes')
+    return i-1
+
+def askstr(str):
+    i = strdialog(mainWidget, 'Question', str, '', 0)
+    return i
+
+def askfile(str):       # XXXX For now...
+    i = strdialog(mainWidget, 'Question', str, '', 0)
+    return i
+
+# The rest is the test program.
+
+def _go():
+    i = dialog(mainWidget,
+               'Not Responding',
+               "The file server isn't responding right now; "
+               "I'll keep trying.",
+               '',
+               -1,
+               'OK')
+    print 'pressed button', i
+    i = dialog(mainWidget,
+               'File Modified',
+               'File "tcl.h" has been modified since '
+               'the last time it was saved. '
+               'Do you want to save it before exiting the application?',
+               'warning',
+               0,
+               'Save File',
+               'Discard Changes',
+               'Return To Editor')
+    print 'pressed button', i
+    print message('Test of message')
+    print askyn('Test of yes/no')
+    print askync('Test of yes/no/cancel')
+    print askstr('Type a string:')
+    print strdialog(mainWidget, 'Question', 'Another string:', '',
+                  0, 'Save', 'Save as text')
+
+def _test():
+    import sys
+    global mainWidget
+    mainWidget = Frame()
+    Pack.config(mainWidget)
+    start = Button(mainWidget,
+                   {'text': 'Press Here To Start', 'command': _go})
+    start.pack()
+    endit = Button(mainWidget,
+                   {'text': 'Exit',
+                    'command': 'exit',
+                    Pack: {'fill' : 'both'}})
+    mainWidget.mainloop()
+
+if __name__ == '__main__':
+    _test()


Property changes on: vendor/Python/current/Tools/modulator/Tkextra.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/modulator/genmodule.py
===================================================================
--- vendor/Python/current/Tools/modulator/genmodule.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/modulator/genmodule.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,160 @@
+#
+# Genmodule - A python program to help you build (template) modules.
+#
+# Usage:
+#
+# o = genmodule.object()
+# o.name = 'dwarve object'
+# o.abbrev = 'dw'
+# o.funclist = ['new', 'dealloc', 'getattr', 'setattr']
+# o.methodlist = ['dig']
+#
+# m = genmodule.module()
+# m.name = 'beings'
+# m.abbrev = 'be'
+# m.methodlist = ['newdwarve']
+# m.objects = [o]
+#
+# genmodule.write(sys.stdout, m)
+#
+import sys
+import os
+import varsubst
+
+error = 'genmodule.error'
+
+#
+# Names of functions in the object-description struct.
+#
+FUNCLIST = ['new', 'tp_dealloc', 'tp_print', 'tp_getattr', 'tp_setattr',
+            'tp_compare', 'tp_repr', 'tp_hash', 'tp_call', 'tp_str']
+TYPELIST = ['tp_as_number', 'tp_as_sequence', 'tp_as_mapping', 'structure']
+
+#
+# writer is a base class for the object and module classes
+# it contains code common to both.
+#
+class writer:
+    def __init__(self):
+        self._subst = None
+
+    def makesubst(self):
+        if not self._subst:
+            if not self.__dict__.has_key('abbrev'):
+                self.abbrev = self.name
+            self.Abbrev = self.abbrev[0].upper()+self.abbrev[1:]
+            subst = varsubst.Varsubst(self.__dict__)
+            subst.useindent(1)
+            self._subst = subst.subst
+
+    def addcode(self, name, fp):
+        ifp = self.opentemplate(name)
+        self.makesubst()
+        d = ifp.read()
+        d = self._subst(d)
+        fp.write(d)
+
+    def opentemplate(self, name):
+        for p in sys.path:
+            fn = os.path.join(p, name)
+            if os.path.exists(fn):
+                return open(fn, 'r')
+            fn = os.path.join(p, 'Templates')
+            fn = os.path.join(fn, name)
+            if os.path.exists(fn):
+                return open(fn, 'r')
+        raise error, 'Template '+name+' not found for '+self._type+' '+ \
+                     self.name
+
+class module(writer):
+    _type = 'module'
+
+    def writecode(self, fp):
+        self.addcode('copyright', fp)
+        self.addcode('module_head', fp)
+        for o in self.objects:
+            o.writehead(fp)
+        for o in self.objects:
+            o.writebody(fp)
+        new_ml = ''
+        for fn in self.methodlist:
+            self.method = fn
+            self.addcode('module_method', fp)
+            new_ml = new_ml + (
+                      '{"%s",\t(PyCFunction)%s_%s,\tMETH_VARARGS,\t%s_%s__doc__},\n'
+                      %(fn, self.abbrev, fn, self.abbrev, fn))
+        self.methodlist = new_ml
+        self.addcode('module_tail', fp)
+
+class object(writer):
+    _type = 'object'
+    def __init__(self):
+        self.typelist = []
+        self.methodlist = []
+        self.funclist = ['new']
+        writer.__init__(self)
+
+    def writecode(self, fp):
+        self.addcode('copyright', fp)
+        self.writehead(fp)
+        self.writebody(fp)
+
+    def writehead(self, fp):
+        self.addcode('object_head', fp)
+
+    def writebody(self, fp):
+        new_ml = ''
+        for fn in self.methodlist:
+            self.method = fn
+            self.addcode('object_method', fp)
+            new_ml = new_ml + (
+                      '{"%s",\t(PyCFunction)%s_%s,\tMETH_VARARGS,\t%s_%s__doc__},\n'
+                      %(fn, self.abbrev, fn, self.abbrev, fn))
+        self.methodlist = new_ml
+        self.addcode('object_mlist', fp)
+
+        # Add getattr if we have methods
+        if self.methodlist and not 'tp_getattr' in self.funclist:
+            self.funclist.insert(0, 'tp_getattr')
+
+        for fn in FUNCLIST:
+            setattr(self, fn, '0')
+
+        #
+        # Special case for structure-access objects: put getattr in the
+        # list of functions but don't generate code for it directly,
+        # the code is obtained from the object_structure template.
+        # The same goes for setattr.
+        #
+        if 'structure' in self.typelist:
+            if 'tp_getattr' in self.funclist:
+                self.funclist.remove('tp_getattr')
+            if 'tp_setattr' in self.funclist:
+                self.funclist.remove('tp_setattr')
+            self.tp_getattr = self.abbrev + '_getattr'
+            self.tp_setattr = self.abbrev + '_setattr'
+        for fn in self.funclist:
+            self.addcode('object_'+fn, fp)
+            setattr(self, fn, '%s_%s'%(self.abbrev, fn[3:]))
+        for tn in TYPELIST:
+            setattr(self, tn, '0')
+        for tn in self.typelist:
+            self.addcode('object_'+tn, fp)
+            setattr(self, tn, '&%s_%s'%(self.abbrev, tn[3:]))
+        self.addcode('object_tail', fp)
+
+def write(fp, obj):
+    obj.writecode(fp)
+
+if __name__ == '__main__':
+    o = object()
+    o.name = 'dwarve object'
+    o.abbrev = 'dw'
+    o.funclist = ['new', 'tp_dealloc']
+    o.methodlist = ['dig']
+    m = module()
+    m.name = 'beings'
+    m.abbrev = 'be'
+    m.methodlist = ['newdwarve']
+    m.objects = [o]
+    write(sys.stdout, m)


Property changes on: vendor/Python/current/Tools/modulator/genmodule.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/modulator/modulator.py
===================================================================
--- vendor/Python/current/Tools/modulator/modulator.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/modulator/modulator.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,383 @@
+#! /usr/bin/env python
+#
+# Modulator - Generate skeleton modules.
+#
+# The user fills out some forms with information about what the module
+# should support (methods, objects), names of these things, prefixes to
+# use for C code, whether the objects should also support access as numbers,
+# etc etc etc.
+# When the user presses 'Generate code' we generate a complete skeleton
+# module in C.
+#
+# Alternatively, the selections made can be save to a python sourcefile and
+# this sourcefile can be passed on the command line (resulting in the same
+# skeleton C code).
+#
+# Jack Jansen, CWI, October 1994.
+#
+
+import sys, os
+if os.name <> 'mac':
+    sys.path.append(os.path.join(os.environ['HOME'],
+                                 'src/python/Tools/modulator'))
+
+from Tkinter import *
+from Tkextra import *
+from ScrolledListbox import ScrolledListbox
+import sys
+import genmodule
+import string
+
+oops = 'oops'
+
+IDENTSTARTCHARS = string.letters + '_'
+IDENTCHARS = string.letters + string.digits + '_'
+
+# Check that string is a legal C identifier
+def checkid(str):
+    if not str: return 0
+    if not str[0] in IDENTSTARTCHARS:
+        return 0
+    for c in str[1:]:
+        if not c in IDENTCHARS:
+            return 0
+    return 1
+
+def getlistlist(list):
+    rv = []
+    n = list.size()
+    for i in range(n):
+        rv.append(list.get(i))
+    return rv
+
+class UI:
+    def __init__(self):
+        self.main = Frame()
+        self.main.pack()
+        self.main.master.title('Modulator: Module view')
+        self.cmdframe = Frame(self.main, {'relief':'raised', 'bd':'0.5m',
+                                          Pack:{'side':'top',
+                                                 'fill':'x'}})
+        self.objframe = Frame(self.main, {Pack:{'side':'top', 'fill':'x',
+                                                'expand':1}})
+
+
+        self.check_button = Button(self.cmdframe,
+                                  {'text':'Check', 'command':self.cb_check,
+                                   Pack:{'side':'left', 'padx':'0.5m'}})
+        self.save_button = Button(self.cmdframe,
+                                  {'text':'Save...', 'command':self.cb_save,
+                                   Pack:{'side':'left', 'padx':'0.5m'}})
+        self.code_button = Button(self.cmdframe,
+                                  {'text':'Generate code...',
+                                   'command':self.cb_gencode,
+                                   Pack:{'side':'left', 'padx':'0.5m'}})
+        self.quit_button = Button(self.cmdframe,
+                                  {'text':'Quit',
+                                   'command':self.cb_quit,
+                                   Pack:{'side':'right', 'padx':'0.5m'}})
+
+        self.module = UI_module(self)
+        self.objects = []
+        self.modified = 0
+
+    def run(self):
+        self.main.mainloop()
+
+    def cb_quit(self, *args):
+        if self.modified:
+            if not askyn('You have not saved\nAre you sure you want to quit?'):
+                return
+        sys.exit(0)
+
+    def cb_check(self, *args):
+        try:
+            self.module.synchronize()
+            for o in self.objects:
+                o.synchronize()
+        except oops:
+            pass
+
+    def cb_save(self, *args):
+        try:
+            pycode = self.module.gencode('m', self.objects)
+        except oops:
+            return
+
+        fn = askfile('Python file name: ')
+        if not fn:
+            return
+
+        fp = open(fn, 'w')
+
+        fp.write(pycode)
+        fp.close()
+
+    def cb_gencode(self, *args):
+        try:
+            pycode = self.module.gencode('m', self.objects)
+        except oops:
+            pass
+
+        fn = askfile('C file name: ')
+        if not fn:
+            return
+
+        fp = open(fn, 'w')
+
+        try:
+            exec pycode
+        except:
+            message('An error occurred:-)')
+            return
+        genmodule.write(fp, m)
+        fp.close()
+
+class UI_module:
+    def __init__(self, parent):
+        self.parent = parent
+        self.frame = Frame(parent.objframe, {'relief':'raised', 'bd':'0.2m',
+                                             Pack:{'side':'top',
+                                                   'fill':'x'}})
+        self.f1 = Frame(self.frame, {Pack:{'side':'top', 'pady':'0.5m',
+                                           'fill':'x'}})
+        self.f2 = Frame(self.frame, {Pack:{'side':'top', 'pady':'0.5m',
+                                           'fill':'x'}})
+        self.f3 = Frame(self.frame, {Pack:{'side':'top', 'pady':'0.5m',
+                                           'fill':'x'}})
+        self.f4 = Frame(self.frame, {Pack:{'side':'top', 'pady':'0.5m',
+                                           'fill':'x'}})
+
+        self.l1 = Label(self.f1, {'text':'Module:', Pack:{'side':'left',
+                                                        'padx':'0.5m'}})
+        self.name_entry = Entry(self.f1, {'relief':'sunken',
+                              Pack:{'side':'left', 'padx':'0.5m', 'expand':1}})
+        self.l2 = Label(self.f1, {'text':'Abbrev:', Pack:{'side':'left',
+                                                        'padx':'0.5m'}})
+        self.abbrev_entry = Entry(self.f1, {'relief':'sunken', 'width':5,
+                              Pack:{'side':'left', 'padx':'0.5m'}})
+
+        self.l3 = Label(self.f2, {'text':'Methods:', Pack:{'side':'left',
+                                                        'padx':'0.5m'}})
+        self.method_list = ScrolledListbox(self.f2, {'relief':'sunken','bd':2,
+                                      Pack:{'side':'left', 'expand':1,
+                                            'padx':'0.5m', 'fill':'both'}})
+
+        self.l4 = Label(self.f3, {'text':'Add method:', Pack:{'side':'left',
+                                                              'padx':'0.5m'}})
+        self.method_entry = Entry(self.f3, {'relief':'sunken',
+                             Pack:{'side':'left', 'padx':'0.5m', 'expand':1}})
+        self.method_entry.bind('<Return>', self.cb_method)
+        self.delete_button = Button(self.f3, {'text':'Delete method',
+                                              'command':self.cb_delmethod,
+                                              Pack:{'side':'left',
+                                                    'padx':'0.5m'}})
+
+        self.newobj_button = Button(self.f4, {'text':'new object',
+                                              'command':self.cb_newobj,
+                                              Pack:{'side':'left',
+                                                    'padx':'0.5m'}})
+
+    def cb_delmethod(self, *args):
+        list = self.method_list.curselection()
+        for i in list:
+            self.method_list.delete(i)
+
+    def cb_newobj(self, *arg):
+        self.parent.objects.append(UI_object(self.parent))
+
+    def cb_method(self, *arg):
+        name = self.method_entry.get()
+        if not name:
+            return
+        self.method_entry.delete('0', 'end')
+        self.method_list.insert('end', name)
+
+    def synchronize(self):
+        n = self.name_entry.get()
+        if not n:
+            message('Module name not set')
+            raise oops
+        if not checkid(n):
+            message('Module name not an identifier:\n'+n)
+            raise oops
+        if not self.abbrev_entry.get():
+            self.abbrev_entry.insert('end', n)
+        m = getlistlist(self.method_list)
+        for n in m:
+            if not checkid(n):
+                message('Method name not an identifier:\n'+n)
+                raise oops
+
+    def gencode(self, name, objects):
+        rv = ''
+        self.synchronize()
+        for o in objects:
+            o.synchronize()
+        onames = []
+        for i in range(len(objects)):
+            oname = 'o%d' % (i+1)
+            rv = rv + objects[i].gencode(oname)
+            onames.append(oname)
+        rv = rv + '%s = genmodule.module()\n' % (name,)
+        rv = rv + '%s.name = %r\n' % (name, self.name_entry.get())
+        rv = rv + '%s.abbrev = %r\n' % (name, self.abbrev_entry.get())
+        rv = rv + '%s.methodlist = %r\n' % (name, getlistlist(self.method_list))
+        rv = rv + '%s.objects = [%s]\n' % (name, ','.join(onames))
+        rv = rv + '\n'
+        return rv
+
+object_number = 0
+
+class UI_object:
+    def __init__(self, parent):
+        global object_number
+
+        object_number = object_number + 1
+        self.num = object_number
+        self.vpref = 'o%r_' % self.num
+        self.frame = Toplevel(parent.objframe)
+#       self.frame.pack()
+        self.frame.title('Modulator: object view')
+#       self.frame = Frame(parent.objframe, {'relief':'raised', 'bd':'0.2m',
+#                                            Pack:{'side':'top',
+#                                                  'fill':'x'}})
+        self.f1 = Frame(self.frame, {Pack:{'side':'top', 'pady':'0.5m',
+                                           'fill':'x'}})
+        self.f2 = Frame(self.frame, {Pack:{'side':'top', 'pady':'0.5m',
+                                           'fill':'x'}})
+        self.f3 = Frame(self.frame, {Pack:{'side':'top', 'pady':'0.5m',
+                                           'fill':'x'}})
+        self.f4 = Frame(self.frame, {Pack:{'side':'top', 'pady':'0.5m',
+                                           'fill':'x'}})
+
+
+        self.l1 = Label(self.f1, {'text':'Object:', Pack:{'side':'left',
+                                                        'padx':'0.5m'}})
+        self.name_entry = Entry(self.f1, {'relief':'sunken',
+                              Pack:{'side':'left', 'padx':'0.5m', 'expand':1}})
+        self.l2 = Label(self.f1, {'text':'Abbrev:', Pack:{'side':'left',
+                                                        'padx':'0.5m'}})
+        self.abbrev_entry = Entry(self.f1, {'relief':'sunken', 'width':5,
+                              Pack:{'side':'left', 'padx':'0.5m'}})
+
+        self.l3 = Label(self.f2, {'text':'Methods:', Pack:{'side':'left',
+                                                        'padx':'0.5m'}})
+        self.method_list = ScrolledListbox(self.f2, {'relief':'sunken','bd':2,
+                                      Pack:{'side':'left', 'expand':1,
+                                            'padx':'0.5m', 'fill':'both'}})
+
+        self.l4 = Label(self.f3, {'text':'Add method:', Pack:{'side':'left',
+                                                              'padx':'0.5m'}})
+        self.method_entry = Entry(self.f3, {'relief':'sunken',
+                             Pack:{'side':'left', 'padx':'0.5m', 'expand':1}})
+        self.method_entry.bind('<Return>', self.cb_method)
+        self.delete_button = Button(self.f3, {'text':'Delete method',
+                                              'command':self.cb_delmethod,
+                                              Pack:{'side':'left',
+                                                    'padx':'0.5m'}})
+
+
+        self.l5 = Label(self.f4, {'text':'functions:',
+                                  Pack:{'side':'left',
+                                        'padx':'0.5m'}})
+        self.f5 = Frame(self.f4, {Pack:{'side':'left', 'pady':'0.5m',
+                                           'fill':'both'}})
+        self.l6 = Label(self.f4, {'text':'Types:',
+                                  Pack:{'side':'left', 'padx':'0.5m'}})
+        self.f6 = Frame(self.f4, {Pack:{'side':'left', 'pady':'0.5m',
+                                           'fill':'x'}})
+        self.funcs = {}
+        for i in genmodule.FUNCLIST:
+            vname = self.vpref+i
+            self.f5.setvar(vname, 0)
+            b = Checkbutton(self.f5, {'variable':vname, 'text':i,
+                                      Pack:{'side':'top', 'pady':'0.5m',
+                                            'anchor':'w','expand':1}})
+            self.funcs[i] = b
+        self.f5.setvar(self.vpref+'new', 1)
+
+        self.types = {}
+        for i in genmodule.TYPELIST:
+            vname = self.vpref + i
+            self.f6.setvar(vname, 0)
+            b = Checkbutton(self.f6, {'variable':vname, 'text':i,
+                                      Pack:{'side':'top', 'pady':'0.5m',
+                                            'anchor':'w'}})
+            self.types[i] = b
+
+    def cb_method(self, *arg):
+        name = self.method_entry.get()
+        if not name:
+            return
+        self.method_entry.delete('0', 'end')
+        self.method_list.insert('end', name)
+
+    def cb_delmethod(self, *args):
+        list = self.method_list.curselection()
+        for i in list:
+            self.method_list.delete(i)
+
+    def synchronize(self):
+        n = self.name_entry.get()
+        if not n:
+            message('Object name not set')
+            raise oops
+        if not self.abbrev_entry.get():
+            self.abbrev_entry.insert('end', n)
+        n = self.abbrev_entry.get()
+        if not checkid(n):
+            message('Abbreviation not an identifier:\n'+n)
+            raise oops
+        m = getlistlist(self.method_list)
+        for n in m:
+            if not checkid(n):
+                message('Method name not an identifier:\n'+n)
+                raise oops
+        if m:
+            self.f5.setvar(self.vpref+'tp_getattr', 1)
+        pass
+
+    def gencode(self, name):
+        rv = ''
+        rv = rv + '%s = genmodule.object()\n' % (name,)
+        rv = rv + '%s.name = %r\n' % (name, self.name_entry.get())
+        rv = rv + '%s.abbrev = %r\n' % (name, self.abbrev_entry.get())
+        rv = rv + '%s.methodlist = %r\n' % (name, getlistlist(self.method_list))
+        fl = []
+        for fn in genmodule.FUNCLIST:
+            vname = self.vpref + fn
+            if self.f5.getvar(vname) == '1':
+                fl.append(fn)
+        rv = rv + '%s.funclist = %r\n' % (name, fl)
+
+        fl = []
+        for fn in genmodule.TYPELIST:
+            vname = self.vpref + fn
+            if self.f5.getvar(vname) == '1':
+                fl.append(fn)
+
+        rv = rv + '%s.typelist = %r\n' % (name, fl)
+
+        rv = rv + '\n'
+        return rv
+
+
+def main():
+    if len(sys.argv) < 2:
+        ui = UI()
+        ui.run()
+    elif len(sys.argv) == 2:
+        fp = open(sys.argv[1])
+        pycode = fp.read()
+        try:
+            exec pycode
+        except:
+            sys.stderr.write('An error occurred:-)\n')
+            sys.exit(1)
+        ##genmodule.write(sys.stdout, m)
+    else:
+        sys.stderr.write('Usage: modulator [file]\n')
+        sys.exit(1)
+
+main()


Property changes on: vendor/Python/current/Tools/modulator/modulator.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/modulator/varsubst.py
===================================================================
--- vendor/Python/current/Tools/modulator/varsubst.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/modulator/varsubst.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,56 @@
+#
+# Variable substitution. Variables are $delimited$
+#
+import re
+
+error = 'varsubst.error'
+
+class Varsubst:
+    def __init__(self, dict):
+        self.dict = dict
+        self.prog = re.compile('\$([a-zA-Z0-9_]*)\$')
+        self.do_useindent = 0
+
+    def useindent(self, onoff):
+        self.do_useindent = onoff
+
+    def subst(self, s):
+        rv = ''
+        while 1:
+            m = self.prog.search(s)
+            if not m:
+                return rv + s
+            rv = rv + s[:m.start()]
+            s = s[m.end():]
+            if m.end() - m.start() == 2:
+                # Escaped dollar
+                rv = rv + '$'
+                s = s[2:]
+                continue
+            name = m.group(1)
+            if not self.dict.has_key(name):
+                raise error, 'No such variable: '+name
+            value = self.dict[name]
+            if self.do_useindent and '\n' in value:
+                value = self._modindent(value, rv)
+            rv = rv + value
+
+    def _modindent(self, value, old):
+        lastnl = old.rfind('\n', 0) + 1
+        lastnl = len(old) - lastnl
+        sub = '\n' + (' '*lastnl)
+        return re.sub('\n', sub, value)
+
+def _test():
+    import sys
+    import os
+
+    sys.stderr.write('-- Copying stdin to stdout with environment map --\n')
+    c = Varsubst(os.environ)
+    c.useindent(1)
+    d = sys.stdin.read()
+    sys.stdout.write(c.subst(d))
+    sys.exit(1)
+
+if __name__ == '__main__':
+    _test()

Added: vendor/Python/current/Tools/msi/README.txt
===================================================================
--- vendor/Python/current/Tools/msi/README.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/msi/README.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,25 @@
+Packaging Python as a Microsoft Installer Package (MSI)
+=======================================================
+
+Using this library, Python can be packaged as a MS-Windows
+MSI file. To generate an installer package, you need
+a build tree. By default, the build tree root directory
+is assumed to be in "../..". This location can be changed
+by adding a file config.py; see the beginning of msi.py
+for additional customization options.
+
+The packaging process assumes that binaries have been 
+generated according to the instructions in PCBuild/README.txt,
+and that you have either Visual Studio or the Platform SDK
+installed. In addition, you need the Python COM extensions,
+either from PythonWin, or from ActivePython.
+
+To invoke the script, open a cmd.exe window which has 
+cabarc.exe in its PATH (e.g. "Visual Studio .NET 2003
+Command Prompt"). Then invoke
+
+<path-to-python.exe> msi.py
+
+If everything succeeds, pythonX.Y.Z.msi is generated
+in the current directory.
+

Added: vendor/Python/current/Tools/msi/msi.py
===================================================================
--- vendor/Python/current/Tools/msi/msi.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/msi/msi.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1203 @@
+# Python MSI Generator
+# (C) 2003 Martin v. Loewis
+# See "FOO" in comments refers to MSDN sections with the title FOO.
+import msilib, schema, sequence, os, glob, time, re
+from msilib import Feature, CAB, Directory, Dialog, Binary, add_data
+import uisample
+from win32com.client import constants
+from distutils.spawn import find_executable
+from uuids import product_codes
+
+# Settings can be overridden in config.py below
+# 0 for official python.org releases
+# 1 for intermediate releases by anybody, with
+# a new product code for every package.
+snapshot = 1
+# 1 means that file extension is px, not py,
+# and binaries start with x
+testpackage = 0
+# Location of build tree
+srcdir = os.path.abspath("../..")
+# Text to be displayed as the version in dialogs etc.
+# goes into file name and ProductCode. Defaults to
+# current_version.day for Snapshot, current_version otherwise
+full_current_version = None
+# Is Tcl available at all?
+have_tcl = True
+# Where is sqlite3.dll located, relative to srcdir?
+sqlite_dir = "../sqlite-source-3.3.4"
+
+try:
+    from config import *
+except ImportError:
+    pass
+
+# Extract current version from Include/patchlevel.h
+lines = open(srcdir + "/Include/patchlevel.h").readlines()
+major = minor = micro = level = serial = None
+levels = {
+    'PY_RELEASE_LEVEL_ALPHA':0xA,
+    'PY_RELEASE_LEVEL_BETA': 0xB,
+    'PY_RELEASE_LEVEL_GAMMA':0xC,
+    'PY_RELEASE_LEVEL_FINAL':0xF
+    }
+for l in lines:
+    if not l.startswith("#define"):
+        continue
+    l = l.split()
+    if len(l) != 3:
+        continue
+    _, name, value = l
+    if name == 'PY_MAJOR_VERSION': major = value
+    if name == 'PY_MINOR_VERSION': minor = value
+    if name == 'PY_MICRO_VERSION': micro = value
+    if name == 'PY_RELEASE_LEVEL': level = levels[value]
+    if name == 'PY_RELEASE_SERIAL': serial = value
+
+short_version = major+"."+minor
+# See PC/make_versioninfo.c
+FIELD3 = 1000*int(micro) + 10*level + int(serial)
+current_version = "%s.%d" % (short_version, FIELD3)
+
+# This should never change. The UpgradeCode of this package can be
+# used in the Upgrade table of future packages to make the future
+# package replace this one. See "UpgradeCode Property".
+upgrade_code_snapshot='{92A24481-3ECB-40FC-8836-04B7966EC0D5}'
+upgrade_code='{65E6DE48-A358-434D-AA4F-4AF72DB4718F}'
+
+if snapshot:
+    current_version = "%s.%s.%s" % (major, minor, int(time.time()/3600/24))
+    product_code = msilib.gen_uuid()
+else:
+    product_code = product_codes[current_version]
+
+if full_current_version is None:
+    full_current_version = current_version
+
+extensions = [
+    'bz2.pyd',
+    'pyexpat.pyd',
+    'select.pyd',
+    'unicodedata.pyd',
+    'winsound.pyd',
+    '_elementtree.pyd',
+    '_bsddb.pyd',
+    '_socket.pyd',
+    '_ssl.pyd',
+    '_testcapi.pyd',
+    '_tkinter.pyd',
+    '_msi.pyd',
+    '_ctypes.pyd',
+    '_ctypes_test.pyd',
+    '_sqlite3.pyd',
+    '_hashlib.pyd'
+]
+
+# Well-known component UUIDs
+# These are needed for SharedDLLs reference counter; if
+# a different UUID was used for each incarnation of, say,
+# python24.dll, an upgrade would set the reference counter
+# from 1 to 2 (due to what I consider a bug in MSI)
+# Using the same UUID is fine since these files are versioned,
+# so Installer will always keep the newest version.
+msvcr71_uuid = "{8666C8DD-D0B4-4B42-928E-A69E32FA5D4D}"
+pythondll_uuid = {
+    "24":"{9B81E618-2301-4035-AC77-75D9ABEB7301}",
+    "25":"{2e41b118-38bd-4c1b-a840-6977efd1b911}"
+    } [major+minor]
+
+# Build the mingw import library, libpythonXY.a
+# This requires 'nm' and 'dlltool' executables on your PATH
+def build_mingw_lib(lib_file, def_file, dll_file, mingw_lib):
+    warning = "WARNING: %s - libpythonXX.a not built"
+    nm = find_executable('nm')
+    dlltool = find_executable('dlltool')
+
+    if not nm or not dlltool:
+        print warning % "nm and/or dlltool were not found"
+        return False
+
+    nm_command = '%s -Cs %s' % (nm, lib_file)
+    dlltool_command = "%s --dllname %s --def %s --output-lib %s" % \
+        (dlltool, dll_file, def_file, mingw_lib)
+    export_match = re.compile(r"^_imp__(.*) in python\d+\.dll").match
+
+    f = open(def_file,'w')
+    print >>f, "LIBRARY %s" % dll_file
+    print >>f, "EXPORTS"
+
+    nm_pipe = os.popen(nm_command)
+    for line in nm_pipe.readlines():
+        m = export_match(line)
+        if m:
+            print >>f, m.group(1)
+    f.close()
+    exit = nm_pipe.close()
+
+    if exit:
+        print warning % "nm did not run successfully"
+        return False
+
+    if os.system(dlltool_command) != 0:
+        print warning % "dlltool did not run successfully"
+        return False
+
+    return True
+
+# Target files (.def and .a) go in PCBuild directory
+lib_file = os.path.join(srcdir, "PCBuild", "python%s%s.lib" % (major, minor))
+def_file = os.path.join(srcdir, "PCBuild", "python%s%s.def" % (major, minor))
+dll_file = "python%s%s.dll" % (major, minor)
+mingw_lib = os.path.join(srcdir, "PCBuild", "libpython%s%s.a" % (major, minor))
+
+have_mingw = build_mingw_lib(lib_file, def_file, dll_file, mingw_lib)
+
+# Determine the target architechture
+dll_path = os.path.join(srcdir, "PCBuild", dll_file)
+msilib.set_arch_from_file(dll_path)
+if msilib.pe_type(dll_path) != msilib.pe_type("msisupport.dll"):
+    raise SystemError, "msisupport.dll for incorrect architecture"
+
+if testpackage:
+    ext = 'px'
+    testprefix = 'x'
+else:
+    ext = 'py'
+    testprefix = ''
+
+if msilib.Win64:
+    SystemFolderName = "[SystemFolder64]"
+else:
+    SystemFolderName = "[SystemFolder]"
+
+msilib.reset()
+
+# condition in which to install pythonxy.dll in system32:
+# a) it is Windows 9x or
+# b) it is NT, the user is privileged, and has chosen per-machine installation
+sys32cond = "(Windows9x or (Privileged and ALLUSERS))"
+
+def build_database():
+    """Generate an empty database, with just the schema and the
+    Summary information stream."""
+    if snapshot:
+        uc = upgrade_code_snapshot
+    else:
+        uc = upgrade_code
+    # schema represents the installer 2.0 database schema.
+    # sequence is the set of standard sequences
+    # (ui/execute, admin/advt/install)
+    db = msilib.init_database("python-%s%s.msi" % (full_current_version, msilib.arch_ext),
+                  schema, ProductName="Python "+full_current_version,
+                  ProductCode=product_code,
+                  ProductVersion=current_version,
+                  Manufacturer=u"Martin v. L\xf6wis")
+    # The default sequencing of the RemoveExistingProducts action causes
+    # removal of files that got just installed. Place it after
+    # InstallInitialize, so we first uninstall everything, but still roll
+    # back in case the installation is interrupted
+    msilib.change_sequence(sequence.InstallExecuteSequence,
+                           "RemoveExistingProducts", 1510)
+    msilib.add_tables(db, sequence)
+    # We cannot set ALLUSERS in the property table, as this cannot be
+    # reset if the user choses a per-user installation. Instead, we
+    # maintain WhichUsers, which can be "ALL" or "JUSTME". The UI manages
+    # this property, and when the execution starts, ALLUSERS is set
+    # accordingly.
+    add_data(db, "Property", [("UpgradeCode", uc),
+                              ("WhichUsers", "ALL"),
+                              ("ProductLine", "Python%s%s" % (major, minor)),
+                             ])
+    db.Commit()
+    return db
+
+def remove_old_versions(db):
+    "Fill the upgrade table."
+    start = "%s.%s.0" % (major, minor)
+    # This requests that feature selection states of an older
+    # installation should be forwarded into this one. Upgrading
+    # requires that both the old and the new installation are
+    # either both per-machine or per-user.
+    migrate_features = 1
+    # See "Upgrade Table". We remove releases with the same major and
+    # minor version. For an snapshot, we remove all earlier snapshots. For
+    # a release, we remove all snapshots, and all earlier releases.
+    if snapshot:
+        add_data(db, "Upgrade",
+            [(upgrade_code_snapshot, start,
+              current_version,
+              None,                     # Ignore language
+              migrate_features,
+              None,                     # Migrate ALL features
+              "REMOVEOLDSNAPSHOT")])
+        props = "REMOVEOLDSNAPSHOT"
+    else:
+        add_data(db, "Upgrade",
+            [(upgrade_code, start, current_version,
+              None, migrate_features, None, "REMOVEOLDVERSION"),
+             (upgrade_code_snapshot, start, "%s.%d.0" % (major, int(minor)+1),
+              None, migrate_features, None, "REMOVEOLDSNAPSHOT")])
+        props = "REMOVEOLDSNAPSHOT;REMOVEOLDVERSION"
+    # Installer collects the product codes of the earlier releases in
+    # these properties. In order to allow modification of the properties,
+    # they must be declared as secure. See "SecureCustomProperties Property"
+    add_data(db, "Property", [("SecureCustomProperties", props)])
+
+class PyDialog(Dialog):
+    """Dialog class with a fixed layout: controls at the top, then a ruler,
+    then a list of buttons: back, next, cancel. Optionally a bitmap at the
+    left."""
+    def __init__(self, *args, **kw):
+        """Dialog(database, name, x, y, w, h, attributes, title, first,
+        default, cancel, bitmap=true)"""
+        Dialog.__init__(self, *args)
+        ruler = self.h - 36
+        bmwidth = 152*ruler/328
+        if kw.get("bitmap", True):
+            self.bitmap("Bitmap", 0, 0, bmwidth, ruler, "PythonWin")
+        self.line("BottomLine", 0, ruler, self.w, 0)
+
+    def title(self, title):
+        "Set the title text of the dialog at the top."
+        # name, x, y, w, h, flags=Visible|Enabled|Transparent|NoPrefix,
+        # text, in VerdanaBold10
+        self.text("Title", 135, 10, 220, 60, 0x30003,
+                  r"{\VerdanaBold10}%s" % title)
+
+    def back(self, title, next, name = "Back", active = 1):
+        """Add a back button with a given title, the tab-next button,
+        its name in the Control table, possibly initially disabled.
+
+        Return the button, so that events can be associated"""
+        if active:
+            flags = 3 # Visible|Enabled
+        else:
+            flags = 1 # Visible
+        return self.pushbutton(name, 180, self.h-27 , 56, 17, flags, title, next)
+
+    def cancel(self, title, next, name = "Cancel", active = 1):
+        """Add a cancel button with a given title, the tab-next button,
+        its name in the Control table, possibly initially disabled.
+
+        Return the button, so that events can be associated"""
+        if active:
+            flags = 3 # Visible|Enabled
+        else:
+            flags = 1 # Visible
+        return self.pushbutton(name, 304, self.h-27, 56, 17, flags, title, next)
+
+    def next(self, title, next, name = "Next", active = 1):
+        """Add a Next button with a given title, the tab-next button,
+        its name in the Control table, possibly initially disabled.
+
+        Return the button, so that events can be associated"""
+        if active:
+            flags = 3 # Visible|Enabled
+        else:
+            flags = 1 # Visible
+        return self.pushbutton(name, 236, self.h-27, 56, 17, flags, title, next)
+
+    def xbutton(self, name, title, next, xpos):
+        """Add a button with a given title, the tab-next button,
+        its name in the Control table, giving its x position; the
+        y-position is aligned with the other buttons.
+
+        Return the button, so that events can be associated"""
+        return self.pushbutton(name, int(self.w*xpos - 28), self.h-27, 56, 17, 3, title, next)
+
+def add_ui(db):
+    x = y = 50
+    w = 370
+    h = 300
+    title = "[ProductName] Setup"
+
+    # see "Dialog Style Bits"
+    modal = 3      # visible | modal
+    modeless = 1   # visible
+    track_disk_space = 32
+
+    add_data(db, 'ActionText', uisample.ActionText)
+    add_data(db, 'UIText', uisample.UIText)
+
+    # Bitmaps
+    if not os.path.exists(srcdir+r"\PC\python_icon.exe"):
+        raise "Run icons.mak in PC directory"
+    add_data(db, "Binary",
+             [("PythonWin", msilib.Binary(srcdir+r"\PCbuild\installer.bmp")), # 152x328 pixels
+              ("py.ico",msilib.Binary(srcdir+r"\PC\py.ico")),
+             ])
+    add_data(db, "Icon",
+             [("python_icon.exe", msilib.Binary(srcdir+r"\PC\python_icon.exe"))])
+
+    # Scripts
+    # CheckDir sets TargetExists if TARGETDIR exists.
+    # UpdateEditIDLE sets the REGISTRY.tcl component into
+    # the installed/uninstalled state according to both the
+    # Extensions and TclTk features.
+    if os.system("nmake /nologo /c /f msisupport.mak") != 0:
+        raise "'nmake /f msisupport.mak' failed"
+    add_data(db, "Binary", [("Script", msilib.Binary("msisupport.dll"))])
+    # See "Custom Action Type 1"
+    if msilib.Win64:
+        CheckDir = "CheckDir"
+        UpdateEditIDLE = "UpdateEditIDLE"
+    else:
+        CheckDir =  "_CheckDir at 4"
+        UpdateEditIDLE = "_UpdateEditIDLE at 4"
+    add_data(db, "CustomAction",
+        [("CheckDir", 1, "Script", CheckDir)])
+    if have_tcl:
+        add_data(db, "CustomAction",
+        [("UpdateEditIDLE", 1, "Script", UpdateEditIDLE)])
+
+    # UI customization properties
+    add_data(db, "Property",
+             # See "DefaultUIFont Property"
+             [("DefaultUIFont", "DlgFont8"),
+              # See "ErrorDialog Style Bit"
+              ("ErrorDialog", "ErrorDlg"),
+              ("Progress1", "Install"),   # modified in maintenance type dlg
+              ("Progress2", "installs"),
+              ("MaintenanceForm_Action", "Repair")])
+
+    # Fonts, see "TextStyle Table"
+    add_data(db, "TextStyle",
+             [("DlgFont8", "Tahoma", 9, None, 0),
+              ("DlgFontBold8", "Tahoma", 8, None, 1), #bold
+              ("VerdanaBold10", "Verdana", 10, None, 1),
+              ("VerdanaRed9", "Verdana", 9, 255, 0),
+             ])
+
+    compileargs = r'-Wi "[TARGETDIR]Lib\compileall.py" -f -x bad_coding|badsyntax|site-packages "[TARGETDIR]Lib"'
+    # See "CustomAction Table"
+    add_data(db, "CustomAction", [
+        # msidbCustomActionTypeFirstSequence + msidbCustomActionTypeTextData + msidbCustomActionTypeProperty
+        # See "Custom Action Type 51",
+        # "Custom Action Execution Scheduling Options"
+        ("InitialTargetDir", 307, "TARGETDIR",
+         "[WindowsVolume]Python%s%s" % (major, minor)),
+        ("SetDLLDirToTarget", 307, "DLLDIR", "[TARGETDIR]"),
+        ("SetDLLDirToSystem32", 307, "DLLDIR", SystemFolderName),
+        # msidbCustomActionTypeExe + msidbCustomActionTypeSourceFile
+        # See "Custom Action Type 18"
+        ("CompilePyc", 18, "python.exe", compileargs),
+        ("CompilePyo", 18, "python.exe", "-O "+compileargs),
+        ])
+
+    # UI Sequences, see "InstallUISequence Table", "Using a Sequence Table"
+    # Numbers indicate sequence; see sequence.py for how these action integrate
+    add_data(db, "InstallUISequence",
+             [("PrepareDlg", "Not Privileged or Windows9x or Installed", 140),
+              ("WhichUsersDlg", "Privileged and not Windows9x and not Installed", 141),
+              ("InitialTargetDir", 'TARGETDIR=""', 750),
+              # In the user interface, assume all-users installation if privileged.
+              ("SetDLLDirToSystem32", 'DLLDIR="" and ' + sys32cond, 751),
+              ("SetDLLDirToTarget", 'DLLDIR="" and not ' + sys32cond, 752),
+              ("SelectDirectoryDlg", "Not Installed", 1230),
+              # XXX no support for resume installations yet
+              #("ResumeDlg", "Installed AND (RESUME OR Preselected)", 1240),
+              ("MaintenanceTypeDlg", "Installed AND NOT RESUME AND NOT Preselected", 1250),
+              ("ProgressDlg", None, 1280)])
+    add_data(db, "AdminUISequence",
+             [("InitialTargetDir", 'TARGETDIR=""', 750),
+              ("SetDLLDirToTarget", 'DLLDIR=""', 751),
+             ])
+
+    # Execute Sequences
+    add_data(db, "InstallExecuteSequence",
+            [("InitialTargetDir", 'TARGETDIR=""', 750),
+             ("SetDLLDirToSystem32", 'DLLDIR="" and ' + sys32cond, 751),
+             ("SetDLLDirToTarget", 'DLLDIR="" and not ' + sys32cond, 752),
+             ("UpdateEditIDLE", None, 1050),
+             ("CompilePyc", "COMPILEALL", 6800),
+             ("CompilePyo", "COMPILEALL", 6801),
+            ])
+    add_data(db, "AdminExecuteSequence",
+            [("InitialTargetDir", 'TARGETDIR=""', 750),
+             ("SetDLLDirToTarget", 'DLLDIR=""', 751),
+             ("CompilePyc", "COMPILEALL", 6800),
+             ("CompilePyo", "COMPILEALL", 6801),
+            ])
+
+    #####################################################################
+    # Standard dialogs: FatalError, UserExit, ExitDialog
+    fatal=PyDialog(db, "FatalError", x, y, w, h, modal, title,
+                 "Finish", "Finish", "Finish")
+    fatal.title("[ProductName] Installer ended prematurely")
+    fatal.back("< Back", "Finish", active = 0)
+    fatal.cancel("Cancel", "Back", active = 0)
+    fatal.text("Description1", 135, 70, 220, 80, 0x30003,
+               "[ProductName] setup ended prematurely because of an error.  Your system has not been modified.  To install this program at a later time, please run the installation again.")
+    fatal.text("Description2", 135, 155, 220, 20, 0x30003,
+               "Click the Finish button to exit the Installer.")
+    c=fatal.next("Finish", "Cancel", name="Finish")
+    # See "ControlEvent Table". Parameters are the event, the parameter
+    # to the action, and optionally the condition for the event, and the order
+    # of events.
+    c.event("EndDialog", "Exit")
+
+    user_exit=PyDialog(db, "UserExit", x, y, w, h, modal, title,
+                 "Finish", "Finish", "Finish")
+    user_exit.title("[ProductName] Installer was interrupted")
+    user_exit.back("< Back", "Finish", active = 0)
+    user_exit.cancel("Cancel", "Back", active = 0)
+    user_exit.text("Description1", 135, 70, 220, 80, 0x30003,
+               "[ProductName] setup was interrupted.  Your system has not been modified.  "
+               "To install this program at a later time, please run the installation again.")
+    user_exit.text("Description2", 135, 155, 220, 20, 0x30003,
+               "Click the Finish button to exit the Installer.")
+    c = user_exit.next("Finish", "Cancel", name="Finish")
+    c.event("EndDialog", "Exit")
+
+    exit_dialog = PyDialog(db, "ExitDialog", x, y, w, h, modal, title,
+                         "Finish", "Finish", "Finish")
+    exit_dialog.title("Completing the [ProductName] Installer")
+    exit_dialog.back("< Back", "Finish", active = 0)
+    exit_dialog.cancel("Cancel", "Back", active = 0)
+    exit_dialog.text("Acknowledgements", 135, 95, 220, 120, 0x30003,
+      "Special Windows thanks to:\n"
+      "    Mark Hammond, without whose years of freely \n"
+      "    shared Windows expertise, Python for Windows \n"
+      "    would still be Python for DOS.")
+
+    c = exit_dialog.text("warning", 135, 200, 220, 40, 0x30003,
+            "{\\VerdanaRed9}Warning: Python 2.5.x is the last "
+            "Python release for Windows 9x.")
+    c.condition("Hide", "NOT Version9X")
+
+    exit_dialog.text("Description", 135, 235, 220, 20, 0x30003,
+               "Click the Finish button to exit the Installer.")
+    c = exit_dialog.next("Finish", "Cancel", name="Finish")
+    c.event("EndDialog", "Return")
+
+    #####################################################################
+    # Required dialog: FilesInUse, ErrorDlg
+    inuse = PyDialog(db, "FilesInUse",
+                     x, y, w, h,
+                     19,                # KeepModeless|Modal|Visible
+                     title,
+                     "Retry", "Retry", "Retry", bitmap=False)
+    inuse.text("Title", 15, 6, 200, 15, 0x30003,
+               r"{\DlgFontBold8}Files in Use")
+    inuse.text("Description", 20, 23, 280, 20, 0x30003,
+               "Some files that need to be updated are currently in use.")
+    inuse.text("Text", 20, 55, 330, 50, 3,
+               "The following applications are using files that need to be updated by this setup. Close these applications and then click Retry to continue the installation or Cancel to exit it.")
+    inuse.control("List", "ListBox", 20, 107, 330, 130, 7, "FileInUseProcess",
+                  None, None, None)
+    c=inuse.back("Exit", "Ignore", name="Exit")
+    c.event("EndDialog", "Exit")
+    c=inuse.next("Ignore", "Retry", name="Ignore")
+    c.event("EndDialog", "Ignore")
+    c=inuse.cancel("Retry", "Exit", name="Retry")
+    c.event("EndDialog","Retry")
+
+
+    # See "Error Dialog". See "ICE20" for the required names of the controls.
+    error = Dialog(db, "ErrorDlg",
+                   50, 10, 330, 101,
+                   65543,       # Error|Minimize|Modal|Visible
+                   title,
+                   "ErrorText", None, None)
+    error.text("ErrorText", 50,9,280,48,3, "")
+    error.control("ErrorIcon", "Icon", 15, 9, 24, 24, 5242881, None, "py.ico", None, None)
+    error.pushbutton("N",120,72,81,21,3,"No",None).event("EndDialog","ErrorNo")
+    error.pushbutton("Y",240,72,81,21,3,"Yes",None).event("EndDialog","ErrorYes")
+    error.pushbutton("A",0,72,81,21,3,"Abort",None).event("EndDialog","ErrorAbort")
+    error.pushbutton("C",42,72,81,21,3,"Cancel",None).event("EndDialog","ErrorCancel")
+    error.pushbutton("I",81,72,81,21,3,"Ignore",None).event("EndDialog","ErrorIgnore")
+    error.pushbutton("O",159,72,81,21,3,"Ok",None).event("EndDialog","ErrorOk")
+    error.pushbutton("R",198,72,81,21,3,"Retry",None).event("EndDialog","ErrorRetry")
+
+    #####################################################################
+    # Global "Query Cancel" dialog
+    cancel = Dialog(db, "CancelDlg", 50, 10, 260, 85, 3, title,
+                    "No", "No", "No")
+    cancel.text("Text", 48, 15, 194, 30, 3,
+                "Are you sure you want to cancel [ProductName] installation?")
+    cancel.control("Icon", "Icon", 15, 15, 24, 24, 5242881, None,
+                   "py.ico", None, None)
+    c=cancel.pushbutton("Yes", 72, 57, 56, 17, 3, "Yes", "No")
+    c.event("EndDialog", "Exit")
+
+    c=cancel.pushbutton("No", 132, 57, 56, 17, 3, "No", "Yes")
+    c.event("EndDialog", "Return")
+
+    #####################################################################
+    # Global "Wait for costing" dialog
+    costing = Dialog(db, "WaitForCostingDlg", 50, 10, 260, 85, modal, title,
+                     "Return", "Return", "Return")
+    costing.text("Text", 48, 15, 194, 30, 3,
+                 "Please wait while the installer finishes determining your disk space requirements.")
+    costing.control("Icon", "Icon", 15, 15, 24, 24, 5242881, None,
+                    "py.ico", None, None)
+    c = costing.pushbutton("Return", 102, 57, 56, 17, 3, "Return", None)
+    c.event("EndDialog", "Exit")
+
+    #####################################################################
+    # Preparation dialog: no user input except cancellation
+    prep = PyDialog(db, "PrepareDlg", x, y, w, h, modeless, title,
+                    "Cancel", "Cancel", "Cancel")
+    prep.text("Description", 135, 70, 220, 40, 0x30003,
+              "Please wait while the Installer prepares to guide you through the installation.")
+    prep.title("Welcome to the [ProductName] Installer")
+    c=prep.text("ActionText", 135, 110, 220, 20, 0x30003, "Pondering...")
+    c.mapping("ActionText", "Text")
+    c=prep.text("ActionData", 135, 135, 220, 30, 0x30003, None)
+    c.mapping("ActionData", "Text")
+    prep.back("Back", None, active=0)
+    prep.next("Next", None, active=0)
+    c=prep.cancel("Cancel", None)
+    c.event("SpawnDialog", "CancelDlg")
+
+    #####################################################################
+    # Target directory selection
+    seldlg = PyDialog(db, "SelectDirectoryDlg", x, y, w, h, modal, title,
+                    "Next", "Next", "Cancel")
+    seldlg.title("Select Destination Directory")
+    c = seldlg.text("Existing", 135, 25, 235, 30, 0x30003,
+                    "{\VerdanaRed9}This update will replace your existing [ProductLine] installation.")
+    c.condition("Hide", 'REMOVEOLDVERSION="" and REMOVEOLDSNAPSHOT=""')
+    seldlg.text("Description", 135, 50, 220, 40, 0x30003,
+               "Please select a directory for the [ProductName] files.")
+
+    seldlg.back("< Back", None, active=0)
+    c = seldlg.next("Next >", "Cancel")
+    c.event("DoAction", "CheckDir", "TargetExistsOk<>1", order=1)
+    # If the target exists, but we found that we are going to remove old versions, don't bother
+    # confirming that the target directory exists. Strictly speaking, we should determine that
+    # the target directory is indeed the target of the product that we are going to remove, but
+    # I don't know how to do that.
+    c.event("SpawnDialog", "ExistingDirectoryDlg", 'TargetExists=1 and REMOVEOLDVERSION="" and REMOVEOLDSNAPSHOT=""', 2)
+    c.event("SetTargetPath", "TARGETDIR", 'TargetExists=0 or REMOVEOLDVERSION<>"" or REMOVEOLDSNAPSHOT<>""', 3)
+    c.event("SpawnWaitDialog", "WaitForCostingDlg", "CostingComplete=1", 4)
+    c.event("NewDialog", "SelectFeaturesDlg", 'TargetExists=0 or REMOVEOLDVERSION<>"" or REMOVEOLDSNAPSHOT<>""', 5)
+
+    c = seldlg.cancel("Cancel", "DirectoryCombo")
+    c.event("SpawnDialog", "CancelDlg")
+
+    seldlg.control("DirectoryCombo", "DirectoryCombo", 135, 70, 172, 80, 393219,
+                   "TARGETDIR", None, "DirectoryList", None)
+    seldlg.control("DirectoryList", "DirectoryList", 135, 90, 208, 136, 3, "TARGETDIR",
+                   None, "PathEdit", None)
+    seldlg.control("PathEdit", "PathEdit", 135, 230, 206, 16, 3, "TARGETDIR", None, "Next", None)
+    c = seldlg.pushbutton("Up", 306, 70, 18, 18, 3, "Up", None)
+    c.event("DirectoryListUp", "0")
+    c = seldlg.pushbutton("NewDir", 324, 70, 30, 18, 3, "New", None)
+    c.event("DirectoryListNew", "0")
+
+    #####################################################################
+    # SelectFeaturesDlg
+    features = PyDialog(db, "SelectFeaturesDlg", x, y, w, h, modal|track_disk_space,
+                        title, "Tree", "Next", "Cancel")
+    features.title("Customize [ProductName]")
+    features.text("Description", 135, 35, 220, 15, 0x30003,
+                  "Select the way you want features to be installed.")
+    features.text("Text", 135,45,220,30, 3,
+                  "Click on the icons in the tree below to change the way features will be installed.")
+
+    c=features.back("< Back", "Next")
+    c.event("NewDialog", "SelectDirectoryDlg")
+
+    c=features.next("Next >", "Cancel")
+    c.mapping("SelectionNoItems", "Enabled")
+    c.event("SpawnDialog", "DiskCostDlg", "OutOfDiskSpace=1", order=1)
+    c.event("EndDialog", "Return", "OutOfDiskSpace<>1", order=2)
+
+    c=features.cancel("Cancel", "Tree")
+    c.event("SpawnDialog", "CancelDlg")
+
+    # The browse property is not used, since we have only a single target path (selected already)
+    features.control("Tree", "SelectionTree", 135, 75, 220, 95, 7, "_BrowseProperty",
+                     "Tree of selections", "Back", None)
+
+    #c=features.pushbutton("Reset", 42, 243, 56, 17, 3, "Reset", "DiskCost")
+    #c.mapping("SelectionNoItems", "Enabled")
+    #c.event("Reset", "0")
+
+    features.control("Box", "GroupBox", 135, 170, 225, 90, 1, None, None, None, None)
+
+    c=features.xbutton("DiskCost", "Disk &Usage", None, 0.10)
+    c.mapping("SelectionNoItems","Enabled")
+    c.event("SpawnDialog", "DiskCostDlg")
+
+    c=features.xbutton("Advanced", "Advanced", None, 0.30)
+    c.event("SpawnDialog", "AdvancedDlg")
+
+    c=features.text("ItemDescription", 140, 180, 210, 30, 3,
+                  "Multiline description of the currently selected item.")
+    c.mapping("SelectionDescription","Text")
+
+    c=features.text("ItemSize", 140, 210, 210, 45, 3,
+                    "The size of the currently selected item.")
+    c.mapping("SelectionSize", "Text")
+
+    #####################################################################
+    # Disk cost
+    cost = PyDialog(db, "DiskCostDlg", x, y, w, h, modal, title,
+                    "OK", "OK", "OK", bitmap=False)
+    cost.text("Title", 15, 6, 200, 15, 0x30003,
+              "{\DlgFontBold8}Disk Space Requirements")
+    cost.text("Description", 20, 20, 280, 20, 0x30003,
+              "The disk space required for the installation of the selected features.")
+    cost.text("Text", 20, 53, 330, 60, 3,
+              "The highlighted volumes (if any) do not have enough disk space "
+              "available for the currently selected features.  You can either "
+              "remove some files from the highlighted volumes, or choose to "
+              "install less features onto local drive(s), or select different "
+              "destination drive(s).")
+    cost.control("VolumeList", "VolumeCostList", 20, 100, 330, 150, 393223,
+                 None, "{120}{70}{70}{70}{70}", None, None)
+    cost.xbutton("OK", "Ok", None, 0.5).event("EndDialog", "Return")
+
+    #####################################################################
+    # WhichUsers Dialog. Only available on NT, and for privileged users.
+    # This must be run before FindRelatedProducts, because that will
+    # take into account whether the previous installation was per-user
+    # or per-machine. We currently don't support going back to this
+    # dialog after "Next" was selected; to support this, we would need to
+    # find how to reset the ALLUSERS property, and how to re-run
+    # FindRelatedProducts.
+    # On Windows9x, the ALLUSERS property is ignored on the command line
+    # and in the Property table, but installer fails according to the documentation
+    # if a dialog attempts to set ALLUSERS.
+    whichusers = PyDialog(db, "WhichUsersDlg", x, y, w, h, modal, title,
+                        "AdminInstall", "Next", "Cancel")
+    whichusers.title("Select whether to install [ProductName] for all users of this computer.")
+    # A radio group with two options: allusers, justme
+    g = whichusers.radiogroup("AdminInstall", 135, 60, 160, 50, 3,
+                              "WhichUsers", "", "Next")
+    g.add("ALL", 0, 5, 150, 20, "Install for all users")
+    g.add("JUSTME", 0, 25, 150, 20, "Install just for me")
+
+    whichusers.back("Back", None, active=0)
+
+    c = whichusers.next("Next >", "Cancel")
+    c.event("[ALLUSERS]", "1", 'WhichUsers="ALL"', 1)
+    c.event("EndDialog", "Return", order = 2)
+
+    c = whichusers.cancel("Cancel", "AdminInstall")
+    c.event("SpawnDialog", "CancelDlg")
+
+    #####################################################################
+    # Advanced Dialog.
+    advanced = PyDialog(db, "AdvancedDlg", x, y, w, h, modal, title,
+                        "CompilePyc", "Next", "Cancel")
+    advanced.title("Advanced Options for [ProductName]")
+    # A radio group with two options: allusers, justme
+    advanced.checkbox("CompilePyc", 135, 60, 230, 50, 3,
+                      "COMPILEALL", "Compile .py files to byte code after installation", "Next")
+
+    c = advanced.next("Finish", "Cancel")
+    c.event("EndDialog", "Return")
+
+    c = advanced.cancel("Cancel", "CompilePyc")
+    c.event("SpawnDialog", "CancelDlg")
+
+    #####################################################################
+    # Existing Directory dialog
+    dlg = Dialog(db, "ExistingDirectoryDlg", 50, 30, 200, 80, modal, title,
+                   "No", "No", "No")
+    dlg.text("Title", 10, 20, 180, 40, 3,
+             "[TARGETDIR] exists. Are you sure you want to overwrite existing files?")
+    c=dlg.pushbutton("Yes", 30, 60, 55, 17, 3, "Yes", "No")
+    c.event("[TargetExists]", "0", order=1)
+    c.event("[TargetExistsOk]", "1", order=2)
+    c.event("EndDialog", "Return", order=3)
+    c=dlg.pushbutton("No", 115, 60, 55, 17, 3, "No", "Yes")
+    c.event("EndDialog", "Return")
+
+    #####################################################################
+    # Installation Progress dialog (modeless)
+    progress = PyDialog(db, "ProgressDlg", x, y, w, h, modeless, title,
+                        "Cancel", "Cancel", "Cancel", bitmap=False)
+    progress.text("Title", 20, 15, 200, 15, 0x30003,
+                  "{\DlgFontBold8}[Progress1] [ProductName]")
+    progress.text("Text", 35, 65, 300, 30, 3,
+                  "Please wait while the Installer [Progress2] [ProductName]. "
+                  "This may take several minutes.")
+    progress.text("StatusLabel", 35, 100, 35, 20, 3, "Status:")
+
+    c=progress.text("ActionText", 70, 100, w-70, 20, 3, "Pondering...")
+    c.mapping("ActionText", "Text")
+
+    #c=progress.text("ActionData", 35, 140, 300, 20, 3, None)
+    #c.mapping("ActionData", "Text")
+
+    c=progress.control("ProgressBar", "ProgressBar", 35, 120, 300, 10, 65537,
+                       None, "Progress done", None, None)
+    c.mapping("SetProgress", "Progress")
+
+    progress.back("< Back", "Next", active=False)
+    progress.next("Next >", "Cancel", active=False)
+    progress.cancel("Cancel", "Back").event("SpawnDialog", "CancelDlg")
+
+    # Maintenance type: repair/uninstall
+    maint = PyDialog(db, "MaintenanceTypeDlg", x, y, w, h, modal, title,
+                     "Next", "Next", "Cancel")
+    maint.title("Welcome to the [ProductName] Setup Wizard")
+    maint.text("BodyText", 135, 63, 230, 42, 3,
+               "Select whether you want to repair or remove [ProductName].")
+    g=maint.radiogroup("RepairRadioGroup", 135, 108, 230, 60, 3,
+                        "MaintenanceForm_Action", "", "Next")
+    g.add("Change", 0, 0, 200, 17, "&Change [ProductName]")
+    g.add("Repair", 0, 18, 200, 17, "&Repair [ProductName]")
+    g.add("Remove", 0, 36, 200, 17, "Re&move [ProductName]")
+
+    maint.back("< Back", None, active=False)
+    c=maint.next("Finish", "Cancel")
+    # Change installation: Change progress dialog to "Change", then ask
+    # for feature selection
+    c.event("[Progress1]", "Change", 'MaintenanceForm_Action="Change"', 1)
+    c.event("[Progress2]", "changes", 'MaintenanceForm_Action="Change"', 2)
+
+    # Reinstall: Change progress dialog to "Repair", then invoke reinstall
+    # Also set list of reinstalled features to "ALL"
+    c.event("[REINSTALL]", "ALL", 'MaintenanceForm_Action="Repair"', 5)
+    c.event("[Progress1]", "Repairing", 'MaintenanceForm_Action="Repair"', 6)
+    c.event("[Progress2]", "repairs", 'MaintenanceForm_Action="Repair"', 7)
+    c.event("Reinstall", "ALL", 'MaintenanceForm_Action="Repair"', 8)
+
+    # Uninstall: Change progress to "Remove", then invoke uninstall
+    # Also set list of removed features to "ALL"
+    c.event("[REMOVE]", "ALL", 'MaintenanceForm_Action="Remove"', 11)
+    c.event("[Progress1]", "Removing", 'MaintenanceForm_Action="Remove"', 12)
+    c.event("[Progress2]", "removes", 'MaintenanceForm_Action="Remove"', 13)
+    c.event("Remove", "ALL", 'MaintenanceForm_Action="Remove"', 14)
+
+    # Close dialog when maintenance action scheduled
+    c.event("EndDialog", "Return", 'MaintenanceForm_Action<>"Change"', 20)
+    c.event("NewDialog", "SelectFeaturesDlg", 'MaintenanceForm_Action="Change"', 21)
+
+    maint.cancel("Cancel", "RepairRadioGroup").event("SpawnDialog", "CancelDlg")
+
+
+# See "Feature Table". The feature level is 1 for all features,
+# and the feature attributes are 0 for the DefaultFeature, and
+# FollowParent for all other features. The numbers are the Display
+# column.
+def add_features(db):
+    # feature attributes:
+    # msidbFeatureAttributesFollowParent == 2
+    # msidbFeatureAttributesDisallowAdvertise == 8
+    # Features that need to be installed with together with the main feature
+    # (i.e. additional Python libraries) need to follow the parent feature.
+    # Features that have no advertisement trigger (e.g. the test suite)
+    # must not support advertisement
+    global default_feature, tcltk, htmlfiles, tools, testsuite, ext_feature
+    default_feature = Feature(db, "DefaultFeature", "Python",
+                              "Python Interpreter and Libraries",
+                              1, directory = "TARGETDIR")
+    # We don't support advertisement of extensions
+    ext_feature = Feature(db, "Extensions", "Register Extensions",
+                          "Make this Python installation the default Python installation", 3,
+                         parent = default_feature, attributes=2|8)
+    if have_tcl:
+        tcltk = Feature(db, "TclTk", "Tcl/Tk", "Tkinter, IDLE, pydoc", 5,
+                    parent = default_feature, attributes=2)
+    htmlfiles = Feature(db, "Documentation", "Documentation",
+                        "Python HTMLHelp File", 7, parent = default_feature)
+    tools = Feature(db, "Tools", "Utility Scripts",
+                    "Python utility scripts (Tools/", 9,
+                    parent = default_feature, attributes=2)
+    testsuite = Feature(db, "Testsuite", "Test suite",
+                        "Python test suite (Lib/test/)", 11,
+                        parent = default_feature, attributes=2|8)
+
+def extract_msvcr71():
+    import _winreg
+    # Find the location of the merge modules
+    k = _winreg.OpenKey(
+        _winreg.HKEY_LOCAL_MACHINE,
+        r"Software\Microsoft\VisualStudio\7.1\Setup\VS")
+    dir = _winreg.QueryValueEx(k, "MSMDir")[0]
+    _winreg.CloseKey(k)
+    files = glob.glob1(dir, "*CRT71*")
+    assert len(files) == 1
+    file = os.path.join(dir, files[0])
+    # Extract msvcr71.dll
+    m = msilib.MakeMerge2()
+    m.OpenModule(file, 0)
+    m.ExtractFiles(".")
+    m.CloseModule()
+    # Find the version/language of msvcr71.dll
+    installer = msilib.MakeInstaller()
+    return installer.FileVersion("msvcr71.dll", 0), \
+           installer.FileVersion("msvcr71.dll", 1)
+
+class PyDirectory(Directory):
+    """By default, all components in the Python installer
+    can run from source."""
+    def __init__(self, *args, **kw):
+        if not kw.has_key("componentflags"):
+            kw['componentflags'] = 2 #msidbComponentAttributesOptional
+        Directory.__init__(self, *args, **kw)
+
+# See "File Table", "Component Table", "Directory Table",
+# "FeatureComponents Table"
+def add_files(db):
+    cab = CAB("python")
+    tmpfiles = []
+    # Add all executables, icons, text files into the TARGETDIR component
+    root = PyDirectory(db, cab, None, srcdir, "TARGETDIR", "SourceDir")
+    default_feature.set_current()
+    if not msilib.Win64:
+        root.add_file("PCBuild/w9xpopen.exe")
+    root.add_file("README.txt", src="README")
+    root.add_file("NEWS.txt", src="Misc/NEWS")
+    root.add_file("LICENSE.txt", src="LICENSE")
+    root.start_component("python.exe", keyfile="python.exe")
+    root.add_file("PCBuild/python.exe")
+    root.start_component("pythonw.exe", keyfile="pythonw.exe")
+    root.add_file("PCBuild/pythonw.exe")
+
+    # msidbComponentAttributesSharedDllRefCount = 8, see "Component Table"
+    dlldir = PyDirectory(db, cab, root, srcdir, "DLLDIR", ".")
+    pydll = "python%s%s.dll" % (major, minor)
+    pydllsrc = srcdir + "/PCBuild/" + pydll
+    dlldir.start_component("DLLDIR", flags = 8, keyfile = pydll, uuid = pythondll_uuid)
+    installer = msilib.MakeInstaller()
+    pyversion = installer.FileVersion(pydllsrc, 0)
+    if not snapshot:
+        # For releases, the Python DLL has the same version as the
+        # installer package.
+        assert pyversion.split(".")[:3] == current_version.split(".")
+    dlldir.add_file("PCBuild/python%s%s.dll" % (major, minor),
+                    version=pyversion,
+                    language=installer.FileVersion(pydllsrc, 1))
+    # XXX determine dependencies
+    version, lang = extract_msvcr71()
+    dlldir.start_component("msvcr71", flags=8, keyfile="msvcr71.dll", uuid=msvcr71_uuid)
+    dlldir.add_file("msvcr71.dll", src=os.path.abspath("msvcr71.dll"),
+                    version=version, language=lang)
+    tmpfiles.append("msvcr71.dll")
+
+    # Check if _ctypes.pyd exists
+    have_ctypes = os.path.exists(srcdir+"/PCBuild/_ctypes.pyd")
+    if not have_ctypes:
+        print "WARNING: _ctypes.pyd not found, ctypes will not be included"
+        extensions.remove("_ctypes.pyd")
+    
+    # Add all .py files in Lib, except lib-tk, test
+    dirs={}
+    pydirs = [(root,"Lib")]
+    while pydirs:
+        parent, dir = pydirs.pop()
+        if dir == ".svn" or dir.startswith("plat-"):
+            continue
+        elif dir in ["lib-tk", "idlelib", "Icons"]:
+            if not have_tcl:
+                continue
+            tcltk.set_current()
+        elif dir in ['test', 'tests', 'data', 'output']:
+            # test: Lib, Lib/email, Lib/bsddb, Lib/ctypes, Lib/sqlite3
+            # tests: Lib/distutils
+            # data: Lib/email/test
+            # output: Lib/test
+            testsuite.set_current()
+        elif not have_ctypes and dir == "ctypes":
+            continue
+        else:
+            default_feature.set_current()
+        lib = PyDirectory(db, cab, parent, dir, dir, "%s|%s" % (parent.make_short(dir), dir))
+        # Add additional files
+        dirs[dir]=lib
+        lib.glob("*.txt")
+        if dir=='site-packages':
+            lib.add_file("README.txt", src="README")
+            continue
+        files = lib.glob("*.py")
+        files += lib.glob("*.pyw")
+        if files:
+            # Add an entry to the RemoveFile table to remove bytecode files.
+            lib.remove_pyc()
+        if dir.endswith('.egg-info'):
+            lib.add_file('entry_points.txt')
+            lib.add_file('PKG-INFO')
+            lib.add_file('top_level.txt')
+            lib.add_file('zip-safe')
+            continue
+        if dir=='test' and parent.physical=='Lib':
+            lib.add_file("185test.db")
+            lib.add_file("audiotest.au")
+            lib.add_file("cfgparser.1")
+            lib.add_file("sgml_input.html")
+            lib.add_file("test.xml")
+            lib.add_file("test.xml.out")
+            lib.add_file("testtar.tar")
+            lib.add_file("test_difflib_expect.html")
+            lib.add_file("check_soundcard.vbs")
+            lib.add_file("empty.vbs")
+            lib.glob("*.uue")
+            lib.add_file("readme.txt", src="README")
+        if dir=='decimaltestdata':
+            lib.glob("*.decTest")
+        if dir=='output':
+            lib.glob("test_*")
+        if dir=='idlelib':
+            lib.glob("*.def")
+            lib.add_file("idle.bat")
+        if dir=="Icons":
+            lib.glob("*.gif")
+            lib.add_file("idle.icns")
+        if dir=="command" and parent.physical=="distutils":
+            lib.add_file("wininst-6.exe")
+            lib.add_file("wininst-7.1.exe")
+        if dir=="setuptools":
+            lib.add_file("cli.exe")
+            lib.add_file("gui.exe")
+        if dir=="data" and parent.physical=="test" and parent.basedir.physical=="email":
+            # This should contain all non-.svn files listed in subversion
+            for f in os.listdir(lib.absolute):
+                if f.endswith(".txt") or f==".svn":continue
+                if f.endswith(".au") or f.endswith(".gif"):
+                    lib.add_file(f)
+                else:
+                    print "WARNING: New file %s in email/test/data" % f
+        for f in os.listdir(lib.absolute):
+            if os.path.isdir(os.path.join(lib.absolute, f)):
+                pydirs.append((lib, f))
+    # Add DLLs
+    default_feature.set_current()
+    lib = PyDirectory(db, cab, root, srcdir+"/PCBuild", "DLLs", "DLLS|DLLs")
+    lib.add_file("py.ico", src="../PC/py.ico")
+    lib.add_file("pyc.ico", src="../PC/pyc.ico")
+    dlls = []
+    tclfiles = []
+    for f in extensions:
+        if f=="_tkinter.pyd":
+            continue
+        if not os.path.exists(srcdir+"/PCBuild/"+f):
+            print "WARNING: Missing extension", f
+            continue
+        dlls.append(f)
+        lib.add_file(f)
+    # Add sqlite
+    if msilib.msi_type=="Intel64;1033":
+        sqlite_arch = "/ia64"
+    elif msilib.msi_type=="x64;1033":
+        sqlite_arch = "/amd64"
+    else:
+        sqlite_arch = ""
+    lib.add_file(srcdir+"/"+sqlite_dir+sqlite_arch+"/sqlite3.dll")
+    if have_tcl:
+        if not os.path.exists(srcdir+"/PCBuild/_tkinter.pyd"):
+            print "WARNING: Missing _tkinter.pyd"
+        else:
+            lib.start_component("TkDLLs", tcltk)
+            lib.add_file("_tkinter.pyd")
+            dlls.append("_tkinter.pyd")
+            tcldir = os.path.normpath(srcdir+"/../tcltk/bin")
+            for f in glob.glob1(tcldir, "*.dll"):
+                lib.add_file(f, src=os.path.join(tcldir, f))
+    # check whether there are any unknown extensions
+    for f in glob.glob1(srcdir+"/PCBuild", "*.pyd"):
+        if f.endswith("_d.pyd"): continue # debug version
+        if f in dlls: continue
+        print "WARNING: Unknown extension", f
+
+    # Add headers
+    default_feature.set_current()
+    lib = PyDirectory(db, cab, root, "include", "include", "INCLUDE|include")
+    lib.glob("*.h")
+    lib.add_file("pyconfig.h", src="../PC/pyconfig.h")
+    # Add import libraries
+    lib = PyDirectory(db, cab, root, "PCBuild", "libs", "LIBS|libs")
+    for f in dlls:
+        lib.add_file(f.replace('pyd','lib'))
+    lib.add_file('python%s%s.lib' % (major, minor))
+    # Add the mingw-format library
+    if have_mingw:
+        lib.add_file('libpython%s%s.a' % (major, minor))
+    if have_tcl:
+        # Add Tcl/Tk
+        tcldirs = [(root, '../tcltk/lib', 'tcl')]
+        tcltk.set_current()
+        while tcldirs:
+            parent, phys, dir = tcldirs.pop()
+            lib = PyDirectory(db, cab, parent, phys, dir, "%s|%s" % (parent.make_short(dir), dir))
+            if not os.path.exists(lib.absolute):
+                continue
+            for f in os.listdir(lib.absolute):
+                if os.path.isdir(os.path.join(lib.absolute, f)):
+                    tcldirs.append((lib, f, f))
+                else:
+                    lib.add_file(f)
+    # Add tools
+    tools.set_current()
+    tooldir = PyDirectory(db, cab, root, "Tools", "Tools", "TOOLS|Tools")
+    for f in ['i18n', 'pynche', 'Scripts', 'versioncheck', 'webchecker']:
+        lib = PyDirectory(db, cab, tooldir, f, f, "%s|%s" % (tooldir.make_short(f), f))
+        lib.glob("*.py")
+        lib.glob("*.pyw", exclude=['pydocgui.pyw'])
+        lib.remove_pyc()
+        lib.glob("*.txt")
+        if f == "pynche":
+            x = PyDirectory(db, cab, lib, "X", "X", "X|X")
+            x.glob("*.txt")
+        if os.path.exists(os.path.join(lib.absolute, "README")):
+            lib.add_file("README.txt", src="README")
+        if f == 'Scripts':
+            if have_tcl:
+                lib.start_component("pydocgui.pyw", tcltk, keyfile="pydocgui.pyw")
+                lib.add_file("pydocgui.pyw")
+    # Add documentation
+    htmlfiles.set_current()
+    lib = PyDirectory(db, cab, root, "Doc", "Doc", "DOC|Doc")
+    lib.start_component("documentation", keyfile="Python%s%s.chm" % (major,minor))
+    lib.add_file("Python%s%s.chm" % (major, minor))
+
+    cab.commit(db)
+
+    for f in tmpfiles:
+        os.unlink(f)
+
+# See "Registry Table", "Component Table"
+def add_registry(db):
+    # File extensions, associated with the REGISTRY.def component
+    # IDLE verbs depend on the tcltk feature.
+    # msidbComponentAttributesRegistryKeyPath = 4
+    # -1 for Root specifies "dependent on ALLUSERS property"
+    tcldata = []
+    if have_tcl:
+        tcldata = [
+            ("REGISTRY.tcl", msilib.gen_uuid(), "TARGETDIR", 4, None,
+             "py.IDLE")]
+    add_data(db, "Component",
+             # msidbComponentAttributesRegistryKeyPath = 4
+             [("REGISTRY", msilib.gen_uuid(), "TARGETDIR", 4, None,
+               "InstallPath"),
+              ("REGISTRY.doc", msilib.gen_uuid(), "TARGETDIR", 4, None,
+               "Documentation"),
+              ("REGISTRY.def", msilib.gen_uuid(), "TARGETDIR", 4,
+               None, None)] + tcldata)
+    # See "FeatureComponents Table".
+    # The association between TclTk and pythonw.exe is necessary to make ICE59
+    # happy, because the installer otherwise believes that the IDLE and PyDoc
+    # shortcuts might get installed without pythonw.exe being install. This
+    # is not true, since installing TclTk will install the default feature, which
+    # will cause pythonw.exe to be installed.
+    # REGISTRY.tcl is not associated with any feature, as it will be requested
+    # through a custom action
+    tcldata = []
+    if have_tcl:
+        tcldata = [(tcltk.id, "pythonw.exe")]
+    add_data(db, "FeatureComponents",
+             [(default_feature.id, "REGISTRY"),
+              (htmlfiles.id, "REGISTRY.doc"),
+              (ext_feature.id, "REGISTRY.def")] +
+              tcldata
+              )
+    # Extensions are not advertised. For advertised extensions,
+    # we would need separate binaries that install along with the
+    # extension.
+    pat = r"Software\Classes\%sPython.%sFile\shell\%s\command"
+    ewi = "Edit with IDLE"
+    pat2 = r"Software\Classes\%sPython.%sFile\DefaultIcon"
+    pat3 = r"Software\Classes\%sPython.%sFile"
+    tcl_verbs = []
+    if have_tcl:
+        tcl_verbs=[
+             ("py.IDLE", -1, pat % (testprefix, "", ewi), "",
+              r'"[TARGETDIR]pythonw.exe" "[TARGETDIR]Lib\idlelib\idle.pyw" -n -e "%1"',
+              "REGISTRY.tcl"),
+             ("pyw.IDLE", -1, pat % (testprefix, "NoCon", ewi), "",
+              r'"[TARGETDIR]pythonw.exe" "[TARGETDIR]Lib\idlelib\idle.pyw" -n -e "%1"',
+              "REGISTRY.tcl"),
+        ]
+    add_data(db, "Registry",
+            [# Extensions
+             ("py.ext", -1, r"Software\Classes\."+ext, "",
+              "Python.File", "REGISTRY.def"),
+             ("pyw.ext", -1, r"Software\Classes\."+ext+'w', "",
+              "Python.NoConFile", "REGISTRY.def"),
+             ("pyc.ext", -1, r"Software\Classes\."+ext+'c', "",
+              "Python.CompiledFile", "REGISTRY.def"),
+             ("pyo.ext", -1, r"Software\Classes\."+ext+'o', "",
+              "Python.CompiledFile", "REGISTRY.def"),
+             # MIME types
+             ("py.mime", -1, r"Software\Classes\."+ext, "Content Type",
+              "text/plain", "REGISTRY.def"),
+             ("pyw.mime", -1, r"Software\Classes\."+ext+'w', "Content Type",
+              "text/plain", "REGISTRY.def"),
+             #Verbs
+             ("py.open", -1, pat % (testprefix, "", "open"), "",
+              r'"[TARGETDIR]python.exe" "%1" %*', "REGISTRY.def"),
+             ("pyw.open", -1, pat % (testprefix, "NoCon", "open"), "",
+              r'"[TARGETDIR]pythonw.exe" "%1" %*', "REGISTRY.def"),
+             ("pyc.open", -1, pat % (testprefix, "Compiled", "open"), "",
+              r'"[TARGETDIR]python.exe" "%1" %*', "REGISTRY.def"),
+             ] + tcl_verbs + [
+             #Icons
+             ("py.icon", -1, pat2 % (testprefix, ""), "",
+              r'[DLLs]py.ico', "REGISTRY.def"),
+             ("pyw.icon", -1, pat2 % (testprefix, "NoCon"), "",
+              r'[DLLs]py.ico', "REGISTRY.def"),
+             ("pyc.icon", -1, pat2 % (testprefix, "Compiled"), "",
+              r'[DLLs]pyc.ico', "REGISTRY.def"),
+             # Descriptions
+             ("py.txt", -1, pat3 % (testprefix, ""), "",
+              "Python File", "REGISTRY.def"),
+             ("pyw.txt", -1, pat3 % (testprefix, "NoCon"), "",
+              "Python File (no console)", "REGISTRY.def"),
+             ("pyc.txt", -1, pat3 % (testprefix, "Compiled"), "",
+              "Compiled Python File", "REGISTRY.def"),
+            ])
+
+    # Registry keys
+    prefix = r"Software\%sPython\PythonCore\%s" % (testprefix, short_version)
+    add_data(db, "Registry",
+             [("InstallPath", -1, prefix+r"\InstallPath", "", "[TARGETDIR]", "REGISTRY"),
+              ("InstallGroup", -1, prefix+r"\InstallPath\InstallGroup", "",
+               "Python %s" % short_version, "REGISTRY"),
+              ("PythonPath", -1, prefix+r"\PythonPath", "",
+               r"[TARGETDIR]Lib;[TARGETDIR]DLLs;[TARGETDIR]Lib\lib-tk", "REGISTRY"),
+              ("Documentation", -1, prefix+r"\Help\Main Python Documentation", "",
+               r"[TARGETDIR]Doc\Python%s%s.chm" % (major, minor), "REGISTRY.doc"),
+              ("Modules", -1, prefix+r"\Modules", "+", None, "REGISTRY"),
+              ("AppPaths", -1, r"Software\Microsoft\Windows\CurrentVersion\App Paths\Python.exe",
+               "", r"[TARGETDIR]Python.exe", "REGISTRY.def")
+              ])
+    # Shortcuts, see "Shortcut Table"
+    add_data(db, "Directory",
+             [("ProgramMenuFolder", "TARGETDIR", "."),
+              ("MenuDir", "ProgramMenuFolder", "PY%s%s|%sPython %s.%s" % (major,minor,testprefix,major,minor))])
+    add_data(db, "RemoveFile",
+             [("MenuDir", "TARGETDIR", None, "MenuDir", 2)])
+    tcltkshortcuts = []
+    if have_tcl:
+        tcltkshortcuts = [
+              ("IDLE", "MenuDir", "IDLE|IDLE (Python GUI)", "pythonw.exe",
+               tcltk.id, r'"[TARGETDIR]Lib\idlelib\idle.pyw"', None, None, "python_icon.exe", 0, None, "TARGETDIR"),
+              ("PyDoc", "MenuDir", "MODDOCS|Module Docs", "pythonw.exe",
+               tcltk.id, r'"[TARGETDIR]Tools\scripts\pydocgui.pyw"', None, None, "python_icon.exe", 0, None, "TARGETDIR"),
+              ]
+    add_data(db, "Shortcut",
+             tcltkshortcuts +
+             [# Advertised shortcuts: targets are features, not files
+              ("Python", "MenuDir", "PYTHON|Python (command line)", "python.exe",
+               default_feature.id, None, None, None, "python_icon.exe", 2, None, "TARGETDIR"),
+              # Advertising the Manual breaks on (some?) Win98, and the shortcut lacks an
+              # icon first.
+              #("Manual", "MenuDir", "MANUAL|Python Manuals", "documentation",
+              # htmlfiles.id, None, None, None, None, None, None, None),
+              ## Non-advertised shortcuts: must be associated with a registry component
+              ("Manual", "MenuDir", "MANUAL|Python Manuals", "REGISTRY.doc",
+               "[#Python%s%s.chm]" % (major,minor), None,
+               None, None, None, None, None, None),
+              ("Uninstall", "MenuDir", "UNINST|Uninstall Python", "REGISTRY",
+               SystemFolderName+"msiexec",  "/x%s" % product_code,
+               None, None, None, None, None, None),
+              ])
+    db.Commit()
+
+db = build_database()
+try:
+    add_features(db)
+    add_ui(db)
+    add_files(db)
+    add_registry(db)
+    remove_old_versions(db)
+    db.Commit()
+finally:
+    del db

Added: vendor/Python/current/Tools/msi/msilib.py
===================================================================
--- vendor/Python/current/Tools/msi/msilib.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/msi/msilib.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,674 @@
+# Microsoft Installer Library
+# (C) 2003 Martin v. Loewis
+
+import win32com.client.gencache
+import win32com.client
+import pythoncom, pywintypes
+from win32com.client import constants
+import re, string, os, sets, glob, popen2, sys, _winreg, struct
+
+try:
+    basestring
+except NameError:
+    basestring = (str, unicode)
+
+# Partially taken from Wine
+datasizemask=      0x00ff
+type_valid=        0x0100
+type_localizable=  0x0200
+
+typemask=          0x0c00
+type_long=         0x0000
+type_short=        0x0400
+type_string=       0x0c00
+type_binary=       0x0800
+
+type_nullable=     0x1000
+type_key=          0x2000
+# XXX temporary, localizable?
+knownbits = datasizemask | type_valid | type_localizable | \
+            typemask | type_nullable | type_key
+
+# Summary Info Property IDs
+PID_CODEPAGE=1
+PID_TITLE=2
+PID_SUBJECT=3
+PID_AUTHOR=4
+PID_KEYWORDS=5
+PID_COMMENTS=6
+PID_TEMPLATE=7
+PID_LASTAUTHOR=8
+PID_REVNUMBER=9
+PID_LASTPRINTED=11
+PID_CREATE_DTM=12
+PID_LASTSAVE_DTM=13
+PID_PAGECOUNT=14
+PID_WORDCOUNT=15
+PID_CHARCOUNT=16
+PID_APPNAME=18
+PID_SECURITY=19
+
+def reset():
+    global _directories
+    _directories = sets.Set()
+
+def EnsureMSI():
+    win32com.client.gencache.EnsureModule('{000C1092-0000-0000-C000-000000000046}', 1033, 1, 0)
+
+def EnsureMSM():
+    try:
+        win32com.client.gencache.EnsureModule('{0ADDA82F-2C26-11D2-AD65-00A0C9AF11A6}', 0, 1, 0)
+    except pywintypes.com_error:
+        win32com.client.gencache.EnsureModule('{0ADDA82F-2C26-11D2-AD65-00A0C9AF11A6}', 0, 2, 0)
+
+_Installer=None
+def MakeInstaller():
+    global _Installer
+    if _Installer is None:
+        EnsureMSI()
+        _Installer = win32com.client.Dispatch('WindowsInstaller.Installer',
+                     resultCLSID='{000C1090-0000-0000-C000-000000000046}')
+    return _Installer
+
+_Merge=None
+def MakeMerge2():
+    global _Merge
+    if _Merge is None:
+        EnsureMSM()
+        _Merge = win32com.client.Dispatch("Msm.Merge2.1")
+    return _Merge
+
+class Table:
+    def __init__(self, name):
+        self.name = name
+        self.fields = []
+
+    def add_field(self, index, name, type):
+        self.fields.append((index,name,type))
+
+    def sql(self):
+        fields = []
+        keys = []
+        self.fields.sort()
+        fields = [None]*len(self.fields)
+        for index, name, type in self.fields:
+            index -= 1
+            unk = type & ~knownbits
+            if unk:
+                print "%s.%s unknown bits %x" % (self.name, name, unk)
+            size = type & datasizemask
+            dtype = type & typemask
+            if dtype == type_string:
+                if size:
+                    tname="CHAR(%d)" % size
+                else:
+                    tname="CHAR"
+            elif dtype == type_short:
+                assert size==2
+                tname = "SHORT"
+            elif dtype == type_long:
+                assert size==4
+                tname="LONG"
+            elif dtype == type_binary:
+                assert size==0
+                tname="OBJECT"
+            else:
+                tname="unknown"
+                print "%s.%sunknown integer type %d" % (self.name, name, size)
+            if type & type_nullable:
+                flags = ""
+            else:
+                flags = " NOT NULL"
+            if type & type_localizable:
+                flags += " LOCALIZABLE"
+            fields[index] = "`%s` %s%s" % (name, tname, flags)
+            if type & type_key:
+                keys.append("`%s`" % name)
+        fields = ", ".join(fields)
+        keys = ", ".join(keys)
+        return "CREATE TABLE %s (%s PRIMARY KEY %s)" % (self.name, fields, keys)
+
+    def create(self, db):
+        v = db.OpenView(self.sql())
+        v.Execute(None)
+        v.Close()
+
+class Binary:
+    def __init__(self, fname):
+        self.name = fname
+    def __repr__(self):
+        return 'msilib.Binary(os.path.join(dirname,"%s"))' % self.name
+
+def gen_schema(destpath, schemapath):
+    d = MakeInstaller()
+    schema = d.OpenDatabase(schemapath,
+            win32com.client.constants.msiOpenDatabaseModeReadOnly)
+
+    # XXX ORBER BY
+    v=schema.OpenView("SELECT * FROM _Columns")
+    curtable=None
+    tables = []
+    v.Execute(None)
+    f = open(destpath, "wt")
+    f.write("from msilib import Table\n")
+    while 1:
+        r=v.Fetch()
+        if not r:break
+        name=r.StringData(1)
+        if curtable != name:
+            f.write("\n%s = Table('%s')\n" % (name,name))
+            curtable = name
+            tables.append(name)
+        f.write("%s.add_field(%d,'%s',%d)\n" %
+                (name, r.IntegerData(2), r.StringData(3), r.IntegerData(4)))
+    v.Close()
+
+    f.write("\ntables=[%s]\n\n" % (", ".join(tables)))
+
+    # Fill the _Validation table
+    f.write("_Validation_records = [\n")
+    v = schema.OpenView("SELECT * FROM _Validation")
+    v.Execute(None)
+    while 1:
+        r = v.Fetch()
+        if not r:break
+        # Table, Column, Nullable
+        f.write("(%s,%s,%s," %
+                (`r.StringData(1)`, `r.StringData(2)`, `r.StringData(3)`))
+        def put_int(i):
+            if r.IsNull(i):f.write("None, ")
+            else:f.write("%d," % r.IntegerData(i))
+        def put_str(i):
+            if r.IsNull(i):f.write("None, ")
+            else:f.write("%s," % `r.StringData(i)`)
+        put_int(4) # MinValue
+        put_int(5) # MaxValue
+        put_str(6) # KeyTable
+        put_int(7) # KeyColumn
+        put_str(8) # Category
+        put_str(9) # Set
+        put_str(10)# Description
+        f.write("),\n")
+    f.write("]\n\n")
+
+    f.close()
+
+def gen_sequence(destpath, msipath):
+    dir = os.path.dirname(destpath)
+    d = MakeInstaller()
+    seqmsi = d.OpenDatabase(msipath,
+            win32com.client.constants.msiOpenDatabaseModeReadOnly)
+
+    v = seqmsi.OpenView("SELECT * FROM _Tables");
+    v.Execute(None)
+    f = open(destpath, "w")
+    print >>f, "import msilib,os;dirname=os.path.dirname(__file__)"
+    tables = []
+    while 1:
+        r = v.Fetch()
+        if not r:break
+        table = r.StringData(1)
+        tables.append(table)
+        f.write("%s = [\n" % table)
+        v1 = seqmsi.OpenView("SELECT * FROM `%s`" % table)
+        v1.Execute(None)
+        info = v1.ColumnInfo(constants.msiColumnInfoTypes)
+        while 1:
+            r = v1.Fetch()
+            if not r:break
+            rec = []
+            for i in range(1,r.FieldCount+1):
+                if r.IsNull(i):
+                    rec.append(None)
+                elif info.StringData(i)[0] in "iI":
+                    rec.append(r.IntegerData(i))
+                elif info.StringData(i)[0] in "slSL":
+                    rec.append(r.StringData(i))
+                elif info.StringData(i)[0]=="v":
+                    size = r.DataSize(i)
+                    bytes = r.ReadStream(i, size, constants.msiReadStreamBytes)
+                    bytes = bytes.encode("latin-1") # binary data represented "as-is"
+                    if table == "Binary":
+                        fname = rec[0]+".bin"
+                        open(os.path.join(dir,fname),"wb").write(bytes)
+                        rec.append(Binary(fname))
+                    else:
+                        rec.append(bytes)
+                else:
+                    raise "Unsupported column type", info.StringData(i)
+            f.write(repr(tuple(rec))+",\n")
+        v1.Close()
+        f.write("]\n\n")
+    v.Close()
+    f.write("tables=%s\n" % repr(map(str,tables)))
+    f.close()
+
+class _Unspecified:pass
+def change_sequence(seq, action, seqno=_Unspecified, cond = _Unspecified):
+    "Change the sequence number of an action in a sequence list"
+    for i in range(len(seq)):
+        if seq[i][0] == action:
+            if cond is _Unspecified:
+                cond = seq[i][1]
+            if seqno is _Unspecified:
+                seqno = seq[i][2]
+            seq[i] = (action, cond, seqno)
+            return
+    raise ValueError, "Action not found in sequence"
+
+def add_data(db, table, values):
+    d = MakeInstaller()
+    v = db.OpenView("SELECT * FROM `%s`" % table)
+    count = v.ColumnInfo(0).FieldCount
+    r = d.CreateRecord(count)
+    for value in values:
+        assert len(value) == count, value
+        for i in range(count):
+            field = value[i]
+            if isinstance(field, (int, long)):
+                r.SetIntegerData(i+1,field)
+            elif isinstance(field, basestring):
+                r.SetStringData(i+1,field)
+            elif field is None:
+                pass
+            elif isinstance(field, Binary):
+                r.SetStream(i+1, field.name)
+            else:
+                raise TypeError, "Unsupported type %s" % field.__class__.__name__
+        v.Modify(win32com.client.constants.msiViewModifyInsert, r)
+        r.ClearData()
+    v.Close()
+
+def add_stream(db, name, path):
+    d = MakeInstaller()
+    v = db.OpenView("INSERT INTO _Streams (Name, Data) VALUES ('%s', ?)" % name)
+    r = d.CreateRecord(1)
+    r.SetStream(1, path)
+    v.Execute(r)
+    v.Close()
+
+def init_database(name, schema,
+                  ProductName, ProductCode, ProductVersion,
+                  Manufacturer):
+    try:
+        os.unlink(name)
+    except OSError:
+        pass
+    ProductCode = ProductCode.upper()
+    d = MakeInstaller()
+    # Create the database
+    db = d.OpenDatabase(name,
+         win32com.client.constants.msiOpenDatabaseModeCreate)
+    # Create the tables
+    for t in schema.tables:
+        t.create(db)
+    # Fill the validation table
+    add_data(db, "_Validation", schema._Validation_records)
+    # Initialize the summary information, allowing atmost 20 properties
+    si = db.GetSummaryInformation(20)
+    si.SetProperty(PID_TITLE, "Installation Database")
+    si.SetProperty(PID_SUBJECT, ProductName)
+    si.SetProperty(PID_AUTHOR, Manufacturer)
+    si.SetProperty(PID_TEMPLATE, msi_type)
+    si.SetProperty(PID_REVNUMBER, gen_uuid())
+    si.SetProperty(PID_WORDCOUNT, 2) # long file names, compressed, original media
+    si.SetProperty(PID_PAGECOUNT, 200)
+    si.SetProperty(PID_APPNAME, "Python MSI Library")
+    # XXX more properties
+    si.Persist()
+    add_data(db, "Property", [
+        ("ProductName", ProductName),
+        ("ProductCode", ProductCode),
+        ("ProductVersion", ProductVersion),
+        ("Manufacturer", Manufacturer),
+        ("ProductLanguage", "1033")])
+    db.Commit()
+    return db
+
+def add_tables(db, module):
+    for table in module.tables:
+        add_data(db, table, getattr(module, table))
+
+def make_id(str):
+    #str = str.replace(".", "_") # colons are allowed
+    str = str.replace(" ", "_")
+    str = str.replace("-", "_")
+    if str[0] in string.digits:
+        str = "_"+str
+    assert re.match("^[A-Za-z_][A-Za-z0-9_.]*$", str), "FILE"+str
+    return str
+
+def gen_uuid():
+    return str(pythoncom.CreateGuid())
+
+class CAB:
+    def __init__(self, name):
+        self.name = name
+        self.file = open(name+".txt", "wt")
+        self.filenames = sets.Set()
+        self.index = 0
+
+    def gen_id(self, dir, file):
+        logical = _logical = make_id(file)
+        pos = 1
+        while logical in self.filenames:
+            logical = "%s.%d" % (_logical, pos)
+            pos += 1
+        self.filenames.add(logical)
+        return logical
+
+    def append(self, full, file, logical = None):
+        if os.path.isdir(full):
+            return
+        if not logical:
+            logical = self.gen_id(dir, file)
+        self.index += 1
+        if full.find(" ")!=-1:
+            print >>self.file, '"%s" %s' % (full, logical)
+        else:
+            print >>self.file, '%s %s' % (full, logical)
+        return self.index, logical
+
+    def commit(self, db):
+        self.file.close()
+        try:
+            os.unlink(self.name+".cab")
+        except OSError:
+            pass
+        for k, v in [(r"Software\Microsoft\VisualStudio\7.1\Setup\VS", "VS7CommonBinDir"),
+                     (r"Software\Microsoft\Win32SDK\Directories", "Install Dir")]:
+            try:
+                key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, k)
+            except WindowsError:
+                continue
+            cabarc = os.path.join(_winreg.QueryValueEx(key, v)[0], r"Bin", "cabarc.exe")
+            _winreg.CloseKey(key)
+            if not os.path.exists(cabarc):continue
+            break
+        else:
+            print "WARNING: cabarc.exe not found in registry"
+            cabarc = "cabarc.exe"
+        f = popen2.popen4(r'"%s" -m lzx:21 n %s.cab @%s.txt' % (cabarc, self.name, self.name))[0]
+        for line in f:
+            if line.startswith("  -- adding "):
+                sys.stdout.write(".")
+            else:
+                sys.stdout.write(line)
+            sys.stdout.flush()
+        if not os.path.exists(self.name+".cab"):
+            raise IOError, "cabarc failed"
+        add_data(db, "Media",
+                [(1, self.index, None, "#"+self.name, None, None)])
+        add_stream(db, self.name, self.name+".cab")
+        os.unlink(self.name+".txt")
+        os.unlink(self.name+".cab")
+        db.Commit()
+
+_directories = sets.Set()
+class Directory:
+    def __init__(self, db, cab, basedir, physical, _logical, default, componentflags=None):
+        """Create a new directory in the Directory table. There is a current component
+        at each point in time for the directory, which is either explicitly created
+        through start_component, or implicitly when files are added for the first
+        time. Files are added into the current component, and into the cab file.
+        To create a directory, a base directory object needs to be specified (can be
+        None), the path to the physical directory, and a logical directory name.
+        Default specifies the DefaultDir slot in the directory table. componentflags
+        specifies the default flags that new components get."""
+        index = 1
+        _logical = make_id(_logical)
+        logical = _logical
+        while logical in _directories:
+            logical = "%s%d" % (_logical, index)
+            index += 1
+        _directories.add(logical)
+        self.db = db
+        self.cab = cab
+        self.basedir = basedir
+        self.physical = physical
+        self.logical = logical
+        self.component = None
+        self.short_names = sets.Set()
+        self.ids = sets.Set()
+        self.keyfiles = {}
+        self.componentflags = componentflags
+        if basedir:
+            self.absolute = os.path.join(basedir.absolute, physical)
+            blogical = basedir.logical
+        else:
+            self.absolute = physical
+            blogical = None
+        add_data(db, "Directory", [(logical, blogical, default)])
+
+    def start_component(self, component = None, feature = None, flags = None, keyfile = None, uuid=None):
+        """Add an entry to the Component table, and make this component the current for this
+        directory. If no component name is given, the directory name is used. If no feature
+        is given, the current feature is used. If no flags are given, the directory's default
+        flags are used. If no keyfile is given, the KeyPath is left null in the Component
+        table."""
+        if flags is None:
+            flags = self.componentflags
+        if uuid is None:
+            uuid = gen_uuid()
+        else:
+            uuid = uuid.upper()
+        if component is None:
+            component = self.logical
+        self.component = component
+        if Win64:
+            flags |= 256
+        if keyfile:
+            keyid = self.cab.gen_id(self.absolute, keyfile)
+            self.keyfiles[keyfile] = keyid
+        else:
+            keyid = None
+        add_data(self.db, "Component",
+                        [(component, uuid, self.logical, flags, None, keyid)])
+        if feature is None:
+            feature = current_feature
+        add_data(self.db, "FeatureComponents",
+                        [(feature.id, component)])
+
+    def make_short(self, file):
+        parts = file.split(".")
+        if len(parts)>1:
+            suffix = parts[-1].upper()
+        else:
+            suffix = None
+        prefix = parts[0].upper()
+        if len(prefix) <= 8 and (not suffix or len(suffix)<=3):
+            if suffix:
+                file = prefix+"."+suffix
+            else:
+                file = prefix
+            assert file not in self.short_names
+        else:
+            prefix = prefix[:6]
+            if suffix:
+                suffix = suffix[:3]
+            pos = 1
+            while 1:
+                if suffix:
+                    file = "%s~%d.%s" % (prefix, pos, suffix)
+                else:
+                    file = "%s~%d" % (prefix, pos)
+                if file not in self.short_names: break
+                pos += 1
+                assert pos < 10000
+                if pos in (10, 100, 1000):
+                    prefix = prefix[:-1]
+        self.short_names.add(file)
+        assert not re.search(r'[\?|><:/*"+,;=\[\]]', file) # restrictions on short names
+        return file
+
+    def add_file(self, file, src=None, version=None, language=None):
+        """Add a file to the current component of the directory, starting a new one
+        one if there is no current component. By default, the file name in the source
+        and the file table will be identical. If the src file is specified, it is
+        interpreted relative to the current directory. Optionally, a version and a
+        language can be specified for the entry in the File table."""
+        if not self.component:
+            self.start_component(self.logical, current_feature)
+        if not src:
+            # Allow relative paths for file if src is not specified
+            src = file
+            file = os.path.basename(file)
+        absolute = os.path.join(self.absolute, src)
+        assert not re.search(r'[\?|><:/*]"', file) # restrictions on long names
+        if self.keyfiles.has_key(file):
+            logical = self.keyfiles[file]
+        else:
+            logical = None
+        sequence, logical = self.cab.append(absolute, file, logical)
+        assert logical not in self.ids
+        self.ids.add(logical)
+        short = self.make_short(file)
+        full = "%s|%s" % (short, file)
+        filesize = os.stat(absolute).st_size
+        # constants.msidbFileAttributesVital
+        # Compressed omitted, since it is the database default
+        # could add r/o, system, hidden
+        attributes = 512
+        add_data(self.db, "File",
+                        [(logical, self.component, full, filesize, version,
+                         language, attributes, sequence)])
+        if not version:
+            # Add hash if the file is not versioned
+            filehash = MakeInstaller().FileHash(absolute, 0)
+            add_data(self.db, "MsiFileHash",
+                     [(logical, 0, filehash.IntegerData(1),
+                       filehash.IntegerData(2), filehash.IntegerData(3),
+                       filehash.IntegerData(4))])
+        # Automatically remove .pyc/.pyo files on uninstall (2)
+        # XXX: adding so many RemoveFile entries makes installer unbelievably
+        # slow. So instead, we have to use wildcard remove entries
+        # if file.endswith(".py"):
+        #     add_data(self.db, "RemoveFile",
+        #              [(logical+"c", self.component, "%sC|%sc" % (short, file),
+        #                self.logical, 2),
+        #               (logical+"o", self.component, "%sO|%so" % (short, file),
+        #                self.logical, 2)])
+
+    def glob(self, pattern, exclude = None):
+        """Add a list of files to the current component as specified in the
+        glob pattern. Individual files can be excluded in the exclude list."""
+        files = glob.glob1(self.absolute, pattern)
+        for f in files:
+            if exclude and f in exclude: continue
+            self.add_file(f)
+        return files
+
+    def remove_pyc(self):
+        "Remove .pyc/.pyo files on uninstall"
+        add_data(self.db, "RemoveFile",
+                 [(self.component+"c", self.component, "*.pyc", self.logical, 2),
+                  (self.component+"o", self.component, "*.pyo", self.logical, 2)])
+
+class Feature:
+    def __init__(self, db, id, title, desc, display, level = 1,
+                 parent=None, directory = None, attributes=0):
+        self.id = id
+        if parent:
+            parent = parent.id
+        add_data(db, "Feature",
+                        [(id, parent, title, desc, display,
+                          level, directory, attributes)])
+    def set_current(self):
+        global current_feature
+        current_feature = self
+
+class Control:
+    def __init__(self, dlg, name):
+        self.dlg = dlg
+        self.name = name
+
+    def event(self, ev, arg, cond = "1", order = None):
+        add_data(self.dlg.db, "ControlEvent",
+                 [(self.dlg.name, self.name, ev, arg, cond, order)])
+
+    def mapping(self, ev, attr):
+        add_data(self.dlg.db, "EventMapping",
+                 [(self.dlg.name, self.name, ev, attr)])
+
+    def condition(self, action, condition):
+        add_data(self.dlg.db, "ControlCondition",
+                 [(self.dlg.name, self.name, action, condition)])
+
+class RadioButtonGroup(Control):
+    def __init__(self, dlg, name, property):
+        self.dlg = dlg
+        self.name = name
+        self.property = property
+        self.index = 1
+
+    def add(self, name, x, y, w, h, text, value = None):
+        if value is None:
+            value = name
+        add_data(self.dlg.db, "RadioButton",
+                 [(self.property, self.index, value,
+                   x, y, w, h, text, None)])
+        self.index += 1
+
+class Dialog:
+    def __init__(self, db, name, x, y, w, h, attr, title, first, default, cancel):
+        self.db = db
+        self.name = name
+        self.x, self.y, self.w, self.h = x,y,w,h
+        add_data(db, "Dialog", [(name, x,y,w,h,attr,title,first,default,cancel)])
+
+    def control(self, name, type, x, y, w, h, attr, prop, text, next, help):
+        add_data(self.db, "Control",
+                 [(self.name, name, type, x, y, w, h, attr, prop, text, next, help)])
+        return Control(self, name)
+
+    def text(self, name, x, y, w, h, attr, text):
+        return self.control(name, "Text", x, y, w, h, attr, None,
+                     text, None, None)
+
+    def bitmap(self, name, x, y, w, h, text):
+        return self.control(name, "Bitmap", x, y, w, h, 1, None, text, None, None)
+
+    def line(self, name, x, y, w, h):
+        return self.control(name, "Line", x, y, w, h, 1, None, None, None, None)
+
+    def pushbutton(self, name, x, y, w, h, attr, text, next):
+        return self.control(name, "PushButton", x, y, w, h, attr, None, text, next, None)
+
+    def radiogroup(self, name, x, y, w, h, attr, prop, text, next):
+        add_data(self.db, "Control",
+                 [(self.name, name, "RadioButtonGroup",
+                   x, y, w, h, attr, prop, text, next, None)])
+        return RadioButtonGroup(self, name, prop)
+
+    def checkbox(self, name, x, y, w, h, attr, prop, text, next):
+        return self.control(name, "CheckBox", x, y, w, h, attr, prop, text, next, None)
+
+def pe_type(path):
+    header = open(path, "rb").read(1000)
+    # offset of PE header is at offset 0x3c
+    pe_offset = struct.unpack("<i", header[0x3c:0x40])[0]
+    assert header[pe_offset:pe_offset+4] == "PE\0\0"
+    machine = struct.unpack("<H", header[pe_offset+4:pe_offset+6])[0]
+    return machine
+
+def set_arch_from_file(path):
+    global msi_type, Win64, arch_ext
+    machine = pe_type(path)
+    if machine == 0x14c:
+        # i386
+        msi_type = "Intel"
+        Win64 = 0
+        arch_ext = ''
+    elif machine == 0x200:
+        # Itanium
+        msi_type = "Intel64"
+        Win64 = 1
+        arch_ext = '.ia64'
+    elif machine == 0x8664:
+        # AMD64
+        msi_type = "x64"
+        Win64 = 1
+        arch_ext = '.amd64'
+    else:
+        raise ValueError, "Unsupported architecture"
+    msi_type += ";1033"

Added: vendor/Python/current/Tools/msi/msisupport.c
===================================================================
--- vendor/Python/current/Tools/msi/msisupport.c	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/msi/msisupport.c	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,102 @@
+#include "windows.h"
+#include "msiquery.h"
+
+int isWinNT;
+
+/* Print a debug message to the installer log file.
+ * To see the debug messages, install with
+ * msiexec /i pythonxy.msi /l*v python.log
+ */
+static UINT debug(MSIHANDLE hInstall, LPCSTR msg)
+{
+	MSIHANDLE hRec = MsiCreateRecord(1);
+	if (!hRec || MsiRecordSetStringA(hRec, 1, msg) != ERROR_SUCCESS) {
+		return ERROR_INSTALL_FAILURE;
+	}
+	MsiProcessMessage(hInstall, INSTALLMESSAGE_INFO, hRec);
+	MsiCloseHandle(hRec);
+	return ERROR_SUCCESS;
+}
+
+/* Check whether the TARGETDIR exists and is a directory.
+ * Set TargetExists appropriately.
+ */
+UINT __declspec(dllexport) __stdcall CheckDir(MSIHANDLE hInstall)
+{
+#define PSIZE 1024
+	WCHAR wpath[PSIZE];
+	char path[PSIZE];
+	UINT result;
+	DWORD size = PSIZE;
+	DWORD attributes;
+
+	isWinNT = (GetVersion() < 0x80000000) ? 1 : 0;
+	
+	if (isWinNT)
+		result = MsiGetPropertyW(hInstall, L"TARGETDIR", wpath, &size);
+	else
+		result = MsiGetPropertyA(hInstall, "TARGETDIR", path, &size);
+	if (result != ERROR_SUCCESS)
+		return result;
+	wpath[size] = L'\0';
+	path[size] = L'\0';
+
+	if (isWinNT)
+		attributes = GetFileAttributesW(wpath);
+	else
+		attributes = GetFileAttributesA(path);
+	if (attributes == INVALID_FILE_ATTRIBUTES ||
+		!(attributes & FILE_ATTRIBUTE_DIRECTORY)) 
+	{
+		return MsiSetPropertyA(hInstall, "TargetExists", "0");
+	} else {
+		return MsiSetPropertyA(hInstall, "TargetExists", "1");
+	}
+}
+
+/* Update the state of the REGISTRY.tcl component according to the
+ * Extension and TclTk features. REGISTRY.tcl must be installed
+ * if both features are installed, and must be absent otherwise.
+ */
+UINT __declspec(dllexport) __stdcall UpdateEditIDLE(MSIHANDLE hInstall)
+{
+	INSTALLSTATE ext_old, ext_new, tcl_old, tcl_new, reg_new;
+	UINT result;
+
+	result = MsiGetFeatureStateA(hInstall, "Extensions", &ext_old, &ext_new);
+	if (result != ERROR_SUCCESS)
+		return result;
+	result = MsiGetFeatureStateA(hInstall, "TclTk", &tcl_old, &tcl_new);
+	if (result != ERROR_SUCCESS)
+		return result;
+
+	/* If the current state is Absent, and the user did not select
+	   the feature in the UI, Installer apparently sets the "selected"
+	   state to unknown. Update it to the current value, then. */
+	if (ext_new == INSTALLSTATE_UNKNOWN)
+		ext_new = ext_old;
+	if (tcl_new == INSTALLSTATE_UNKNOWN)
+		tcl_new = tcl_old;
+
+	// XXX consider current state of REGISTRY.tcl?
+	if (((tcl_new == INSTALLSTATE_LOCAL) ||
+		 (tcl_new == INSTALLSTATE_SOURCE) ||
+		 (tcl_new == INSTALLSTATE_DEFAULT)) &&
+		((ext_new == INSTALLSTATE_LOCAL) ||
+		 (ext_new == INSTALLSTATE_SOURCE) ||
+		 (ext_new == INSTALLSTATE_DEFAULT))) {
+		reg_new = INSTALLSTATE_SOURCE;
+	} else { 
+		reg_new = INSTALLSTATE_ABSENT;
+	}
+	result = MsiSetComponentStateA(hInstall, "REGISTRY.tcl", reg_new);
+	return result;
+}
+
+BOOL APIENTRY DllMain(HANDLE hModule, 
+                      DWORD  ul_reason_for_call, 
+                      LPVOID lpReserved)
+{
+    return TRUE;
+}
+

Added: vendor/Python/current/Tools/msi/msisupport.mak
===================================================================
--- vendor/Python/current/Tools/msi/msisupport.mak	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/msi/msisupport.mak	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,25 @@
+!IF "$(CPU)" == ""
+# VS environment
+
+# /OPT: REF and ICF are added by VS.NET by default
+# NOWIN98 saves 7k of executable size, at the expense of some
+# slowdown on Win98
+msisupport.dll:	msisupport.obj
+	link.exe /OUT:msisupport.dll /INCREMENTAL:NO /NOLOGO /DLL /MACHINE:X86 /SUBSYSTEM:WINDOWS /OPT:REF /OPT:ICF /OPT:NOWIN98 msisupport.obj msi.lib kernel32.lib
+
+# We request a static CRT, so that there will be no CRT dependencies
+# for the target system. We cannot do without a CRT, since it provides
+# the DLL entry point.
+msisupport.obj:	msisupport.c
+	cl /O2 /D WIN32 /D NDEBUG /D _WINDOWS /MT /W3 /c msisupport.c
+
+!ELSE
+# SDK environment: assume all options are already correct
+
+msisupport.dll:	msisupport.obj
+	link.exe /OUT:msisupport.dll /INCREMENTAL:NO /NOLOGO /DLL msisupport.obj msi.lib kernel32.lib
+
+msisupport.obj:	msisupport.c
+	cl /O2 /D WIN32 /D NDEBUG /D _WINDOWS /MD /W3 /GS- /c msisupport.c
+!ENDIF
+

Added: vendor/Python/current/Tools/msi/schema.py
===================================================================
--- vendor/Python/current/Tools/msi/schema.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/msi/schema.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1007 @@
+from msilib import Table
+
+_Validation = Table('_Validation')
+_Validation.add_field(1,'Table',11552)
+_Validation.add_field(2,'Column',11552)
+_Validation.add_field(3,'Nullable',3332)
+_Validation.add_field(4,'MinValue',4356)
+_Validation.add_field(5,'MaxValue',4356)
+_Validation.add_field(6,'KeyTable',7679)
+_Validation.add_field(7,'KeyColumn',5378)
+_Validation.add_field(8,'Category',7456)
+_Validation.add_field(9,'Set',7679)
+_Validation.add_field(10,'Description',7679)
+
+ActionText = Table('ActionText')
+ActionText.add_field(1,'Action',11592)
+ActionText.add_field(2,'Description',7936)
+ActionText.add_field(3,'Template',7936)
+
+AdminExecuteSequence = Table('AdminExecuteSequence')
+AdminExecuteSequence.add_field(1,'Action',11592)
+AdminExecuteSequence.add_field(2,'Condition',7679)
+AdminExecuteSequence.add_field(3,'Sequence',5378)
+
+Condition = Table('Condition')
+Condition.add_field(1,'Feature_',11558)
+Condition.add_field(2,'Level',9474)
+Condition.add_field(3,'Condition',7679)
+
+AdminUISequence = Table('AdminUISequence')
+AdminUISequence.add_field(1,'Action',11592)
+AdminUISequence.add_field(2,'Condition',7679)
+AdminUISequence.add_field(3,'Sequence',5378)
+
+AdvtExecuteSequence = Table('AdvtExecuteSequence')
+AdvtExecuteSequence.add_field(1,'Action',11592)
+AdvtExecuteSequence.add_field(2,'Condition',7679)
+AdvtExecuteSequence.add_field(3,'Sequence',5378)
+
+AdvtUISequence = Table('AdvtUISequence')
+AdvtUISequence.add_field(1,'Action',11592)
+AdvtUISequence.add_field(2,'Condition',7679)
+AdvtUISequence.add_field(3,'Sequence',5378)
+
+AppId = Table('AppId')
+AppId.add_field(1,'AppId',11558)
+AppId.add_field(2,'RemoteServerName',7679)
+AppId.add_field(3,'LocalService',7679)
+AppId.add_field(4,'ServiceParameters',7679)
+AppId.add_field(5,'DllSurrogate',7679)
+AppId.add_field(6,'ActivateAtStorage',5378)
+AppId.add_field(7,'RunAsInteractiveUser',5378)
+
+AppSearch = Table('AppSearch')
+AppSearch.add_field(1,'Property',11592)
+AppSearch.add_field(2,'Signature_',11592)
+
+Property = Table('Property')
+Property.add_field(1,'Property',11592)
+Property.add_field(2,'Value',3840)
+
+BBControl = Table('BBControl')
+BBControl.add_field(1,'Billboard_',11570)
+BBControl.add_field(2,'BBControl',11570)
+BBControl.add_field(3,'Type',3378)
+BBControl.add_field(4,'X',1282)
+BBControl.add_field(5,'Y',1282)
+BBControl.add_field(6,'Width',1282)
+BBControl.add_field(7,'Height',1282)
+BBControl.add_field(8,'Attributes',4356)
+BBControl.add_field(9,'Text',7986)
+
+Billboard = Table('Billboard')
+Billboard.add_field(1,'Billboard',11570)
+Billboard.add_field(2,'Feature_',3366)
+Billboard.add_field(3,'Action',7474)
+Billboard.add_field(4,'Ordering',5378)
+
+Feature = Table('Feature')
+Feature.add_field(1,'Feature',11558)
+Feature.add_field(2,'Feature_Parent',7462)
+Feature.add_field(3,'Title',8000)
+Feature.add_field(4,'Description',8191)
+Feature.add_field(5,'Display',5378)
+Feature.add_field(6,'Level',1282)
+Feature.add_field(7,'Directory_',7496)
+Feature.add_field(8,'Attributes',1282)
+
+Binary = Table('Binary')
+Binary.add_field(1,'Name',11592)
+Binary.add_field(2,'Data',2304)
+
+BindImage = Table('BindImage')
+BindImage.add_field(1,'File_',11592)
+BindImage.add_field(2,'Path',7679)
+
+File = Table('File')
+File.add_field(1,'File',11592)
+File.add_field(2,'Component_',3400)
+File.add_field(3,'FileName',4095)
+File.add_field(4,'FileSize',260)
+File.add_field(5,'Version',7496)
+File.add_field(6,'Language',7444)
+File.add_field(7,'Attributes',5378)
+File.add_field(8,'Sequence',1282)
+
+CCPSearch = Table('CCPSearch')
+CCPSearch.add_field(1,'Signature_',11592)
+
+CheckBox = Table('CheckBox')
+CheckBox.add_field(1,'Property',11592)
+CheckBox.add_field(2,'Value',7488)
+
+Class = Table('Class')
+Class.add_field(1,'CLSID',11558)
+Class.add_field(2,'Context',11552)
+Class.add_field(3,'Component_',11592)
+Class.add_field(4,'ProgId_Default',7679)
+Class.add_field(5,'Description',8191)
+Class.add_field(6,'AppId_',7462)
+Class.add_field(7,'FileTypeMask',7679)
+Class.add_field(8,'Icon_',7496)
+Class.add_field(9,'IconIndex',5378)
+Class.add_field(10,'DefInprocHandler',7456)
+Class.add_field(11,'Argument',7679)
+Class.add_field(12,'Feature_',3366)
+Class.add_field(13,'Attributes',5378)
+
+Component = Table('Component')
+Component.add_field(1,'Component',11592)
+Component.add_field(2,'ComponentId',7462)
+Component.add_field(3,'Directory_',3400)
+Component.add_field(4,'Attributes',1282)
+Component.add_field(5,'Condition',7679)
+Component.add_field(6,'KeyPath',7496)
+
+Icon = Table('Icon')
+Icon.add_field(1,'Name',11592)
+Icon.add_field(2,'Data',2304)
+
+ProgId = Table('ProgId')
+ProgId.add_field(1,'ProgId',11775)
+ProgId.add_field(2,'ProgId_Parent',7679)
+ProgId.add_field(3,'Class_',7462)
+ProgId.add_field(4,'Description',8191)
+ProgId.add_field(5,'Icon_',7496)
+ProgId.add_field(6,'IconIndex',5378)
+
+ComboBox = Table('ComboBox')
+ComboBox.add_field(1,'Property',11592)
+ComboBox.add_field(2,'Order',9474)
+ComboBox.add_field(3,'Value',3392)
+ComboBox.add_field(4,'Text',8000)
+
+CompLocator = Table('CompLocator')
+CompLocator.add_field(1,'Signature_',11592)
+CompLocator.add_field(2,'ComponentId',3366)
+CompLocator.add_field(3,'Type',5378)
+
+Complus = Table('Complus')
+Complus.add_field(1,'Component_',11592)
+Complus.add_field(2,'ExpType',13570)
+
+Directory = Table('Directory')
+Directory.add_field(1,'Directory',11592)
+Directory.add_field(2,'Directory_Parent',7496)
+Directory.add_field(3,'DefaultDir',4095)
+
+Control = Table('Control')
+Control.add_field(1,'Dialog_',11592)
+Control.add_field(2,'Control',11570)
+Control.add_field(3,'Type',3348)
+Control.add_field(4,'X',1282)
+Control.add_field(5,'Y',1282)
+Control.add_field(6,'Width',1282)
+Control.add_field(7,'Height',1282)
+Control.add_field(8,'Attributes',4356)
+Control.add_field(9,'Property',7474)
+Control.add_field(10,'Text',7936)
+Control.add_field(11,'Control_Next',7474)
+Control.add_field(12,'Help',7986)
+
+Dialog = Table('Dialog')
+Dialog.add_field(1,'Dialog',11592)
+Dialog.add_field(2,'HCentering',1282)
+Dialog.add_field(3,'VCentering',1282)
+Dialog.add_field(4,'Width',1282)
+Dialog.add_field(5,'Height',1282)
+Dialog.add_field(6,'Attributes',4356)
+Dialog.add_field(7,'Title',8064)
+Dialog.add_field(8,'Control_First',3378)
+Dialog.add_field(9,'Control_Default',7474)
+Dialog.add_field(10,'Control_Cancel',7474)
+
+ControlCondition = Table('ControlCondition')
+ControlCondition.add_field(1,'Dialog_',11592)
+ControlCondition.add_field(2,'Control_',11570)
+ControlCondition.add_field(3,'Action',11570)
+ControlCondition.add_field(4,'Condition',11775)
+
+ControlEvent = Table('ControlEvent')
+ControlEvent.add_field(1,'Dialog_',11592)
+ControlEvent.add_field(2,'Control_',11570)
+ControlEvent.add_field(3,'Event',11570)
+ControlEvent.add_field(4,'Argument',11775)
+ControlEvent.add_field(5,'Condition',15871)
+ControlEvent.add_field(6,'Ordering',5378)
+
+CreateFolder = Table('CreateFolder')
+CreateFolder.add_field(1,'Directory_',11592)
+CreateFolder.add_field(2,'Component_',11592)
+
+CustomAction = Table('CustomAction')
+CustomAction.add_field(1,'Action',11592)
+CustomAction.add_field(2,'Type',1282)
+CustomAction.add_field(3,'Source',7496)
+CustomAction.add_field(4,'Target',7679)
+
+DrLocator = Table('DrLocator')
+DrLocator.add_field(1,'Signature_',11592)
+DrLocator.add_field(2,'Parent',15688)
+DrLocator.add_field(3,'Path',15871)
+DrLocator.add_field(4,'Depth',5378)
+
+DuplicateFile = Table('DuplicateFile')
+DuplicateFile.add_field(1,'FileKey',11592)
+DuplicateFile.add_field(2,'Component_',3400)
+DuplicateFile.add_field(3,'File_',3400)
+DuplicateFile.add_field(4,'DestName',8191)
+DuplicateFile.add_field(5,'DestFolder',7496)
+
+Environment = Table('Environment')
+Environment.add_field(1,'Environment',11592)
+Environment.add_field(2,'Name',4095)
+Environment.add_field(3,'Value',8191)
+Environment.add_field(4,'Component_',3400)
+
+Error = Table('Error')
+Error.add_field(1,'Error',9474)
+Error.add_field(2,'Message',7936)
+
+EventMapping = Table('EventMapping')
+EventMapping.add_field(1,'Dialog_',11592)
+EventMapping.add_field(2,'Control_',11570)
+EventMapping.add_field(3,'Event',11570)
+EventMapping.add_field(4,'Attribute',3378)
+
+Extension = Table('Extension')
+Extension.add_field(1,'Extension',11775)
+Extension.add_field(2,'Component_',11592)
+Extension.add_field(3,'ProgId_',7679)
+Extension.add_field(4,'MIME_',7488)
+Extension.add_field(5,'Feature_',3366)
+
+MIME = Table('MIME')
+MIME.add_field(1,'ContentType',11584)
+MIME.add_field(2,'Extension_',3583)
+MIME.add_field(3,'CLSID',7462)
+
+FeatureComponents = Table('FeatureComponents')
+FeatureComponents.add_field(1,'Feature_',11558)
+FeatureComponents.add_field(2,'Component_',11592)
+
+FileSFPCatalog = Table('FileSFPCatalog')
+FileSFPCatalog.add_field(1,'File_',11592)
+FileSFPCatalog.add_field(2,'SFPCatalog_',11775)
+
+SFPCatalog = Table('SFPCatalog')
+SFPCatalog.add_field(1,'SFPCatalog',11775)
+SFPCatalog.add_field(2,'Catalog',2304)
+SFPCatalog.add_field(3,'Dependency',7424)
+
+Font = Table('Font')
+Font.add_field(1,'File_',11592)
+Font.add_field(2,'FontTitle',7552)
+
+IniFile = Table('IniFile')
+IniFile.add_field(1,'IniFile',11592)
+IniFile.add_field(2,'FileName',4095)
+IniFile.add_field(3,'DirProperty',7496)
+IniFile.add_field(4,'Section',3936)
+IniFile.add_field(5,'Key',3968)
+IniFile.add_field(6,'Value',4095)
+IniFile.add_field(7,'Action',1282)
+IniFile.add_field(8,'Component_',3400)
+
+IniLocator = Table('IniLocator')
+IniLocator.add_field(1,'Signature_',11592)
+IniLocator.add_field(2,'FileName',3583)
+IniLocator.add_field(3,'Section',3424)
+IniLocator.add_field(4,'Key',3456)
+IniLocator.add_field(5,'Field',5378)
+IniLocator.add_field(6,'Type',5378)
+
+InstallExecuteSequence = Table('InstallExecuteSequence')
+InstallExecuteSequence.add_field(1,'Action',11592)
+InstallExecuteSequence.add_field(2,'Condition',7679)
+InstallExecuteSequence.add_field(3,'Sequence',5378)
+
+InstallUISequence = Table('InstallUISequence')
+InstallUISequence.add_field(1,'Action',11592)
+InstallUISequence.add_field(2,'Condition',7679)
+InstallUISequence.add_field(3,'Sequence',5378)
+
+IsolatedComponent = Table('IsolatedComponent')
+IsolatedComponent.add_field(1,'Component_Shared',11592)
+IsolatedComponent.add_field(2,'Component_Application',11592)
+
+LaunchCondition = Table('LaunchCondition')
+LaunchCondition.add_field(1,'Condition',11775)
+LaunchCondition.add_field(2,'Description',4095)
+
+ListBox = Table('ListBox')
+ListBox.add_field(1,'Property',11592)
+ListBox.add_field(2,'Order',9474)
+ListBox.add_field(3,'Value',3392)
+ListBox.add_field(4,'Text',8000)
+
+ListView = Table('ListView')
+ListView.add_field(1,'Property',11592)
+ListView.add_field(2,'Order',9474)
+ListView.add_field(3,'Value',3392)
+ListView.add_field(4,'Text',8000)
+ListView.add_field(5,'Binary_',7496)
+
+LockPermissions = Table('LockPermissions')
+LockPermissions.add_field(1,'LockObject',11592)
+LockPermissions.add_field(2,'Table',11552)
+LockPermissions.add_field(3,'Domain',15871)
+LockPermissions.add_field(4,'User',11775)
+LockPermissions.add_field(5,'Permission',4356)
+
+Media = Table('Media')
+Media.add_field(1,'DiskId',9474)
+Media.add_field(2,'LastSequence',1282)
+Media.add_field(3,'DiskPrompt',8000)
+Media.add_field(4,'Cabinet',7679)
+Media.add_field(5,'VolumeLabel',7456)
+Media.add_field(6,'Source',7496)
+
+MoveFile = Table('MoveFile')
+MoveFile.add_field(1,'FileKey',11592)
+MoveFile.add_field(2,'Component_',3400)
+MoveFile.add_field(3,'SourceName',8191)
+MoveFile.add_field(4,'DestName',8191)
+MoveFile.add_field(5,'SourceFolder',7496)
+MoveFile.add_field(6,'DestFolder',3400)
+MoveFile.add_field(7,'Options',1282)
+
+MsiAssembly = Table('MsiAssembly')
+MsiAssembly.add_field(1,'Component_',11592)
+MsiAssembly.add_field(2,'Feature_',3366)
+MsiAssembly.add_field(3,'File_Manifest',7496)
+MsiAssembly.add_field(4,'File_Application',7496)
+MsiAssembly.add_field(5,'Attributes',5378)
+
+MsiAssemblyName = Table('MsiAssemblyName')
+MsiAssemblyName.add_field(1,'Component_',11592)
+MsiAssemblyName.add_field(2,'Name',11775)
+MsiAssemblyName.add_field(3,'Value',3583)
+
+MsiDigitalCertificate = Table('MsiDigitalCertificate')
+MsiDigitalCertificate.add_field(1,'DigitalCertificate',11592)
+MsiDigitalCertificate.add_field(2,'CertData',2304)
+
+MsiDigitalSignature = Table('MsiDigitalSignature')
+MsiDigitalSignature.add_field(1,'Table',11552)
+MsiDigitalSignature.add_field(2,'SignObject',11592)
+MsiDigitalSignature.add_field(3,'DigitalCertificate_',3400)
+MsiDigitalSignature.add_field(4,'Hash',6400)
+
+MsiFileHash = Table('MsiFileHash')
+MsiFileHash.add_field(1,'File_',11592)
+MsiFileHash.add_field(2,'Options',1282)
+MsiFileHash.add_field(3,'HashPart1',260)
+MsiFileHash.add_field(4,'HashPart2',260)
+MsiFileHash.add_field(5,'HashPart3',260)
+MsiFileHash.add_field(6,'HashPart4',260)
+
+MsiPatchHeaders = Table('MsiPatchHeaders')
+MsiPatchHeaders.add_field(1,'StreamRef',11558)
+MsiPatchHeaders.add_field(2,'Header',2304)
+
+ODBCAttribute = Table('ODBCAttribute')
+ODBCAttribute.add_field(1,'Driver_',11592)
+ODBCAttribute.add_field(2,'Attribute',11560)
+ODBCAttribute.add_field(3,'Value',8191)
+
+ODBCDriver = Table('ODBCDriver')
+ODBCDriver.add_field(1,'Driver',11592)
+ODBCDriver.add_field(2,'Component_',3400)
+ODBCDriver.add_field(3,'Description',3583)
+ODBCDriver.add_field(4,'File_',3400)
+ODBCDriver.add_field(5,'File_Setup',7496)
+
+ODBCDataSource = Table('ODBCDataSource')
+ODBCDataSource.add_field(1,'DataSource',11592)
+ODBCDataSource.add_field(2,'Component_',3400)
+ODBCDataSource.add_field(3,'Description',3583)
+ODBCDataSource.add_field(4,'DriverDescription',3583)
+ODBCDataSource.add_field(5,'Registration',1282)
+
+ODBCSourceAttribute = Table('ODBCSourceAttribute')
+ODBCSourceAttribute.add_field(1,'DataSource_',11592)
+ODBCSourceAttribute.add_field(2,'Attribute',11552)
+ODBCSourceAttribute.add_field(3,'Value',8191)
+
+ODBCTranslator = Table('ODBCTranslator')
+ODBCTranslator.add_field(1,'Translator',11592)
+ODBCTranslator.add_field(2,'Component_',3400)
+ODBCTranslator.add_field(3,'Description',3583)
+ODBCTranslator.add_field(4,'File_',3400)
+ODBCTranslator.add_field(5,'File_Setup',7496)
+
+Patch = Table('Patch')
+Patch.add_field(1,'File_',11592)
+Patch.add_field(2,'Sequence',9474)
+Patch.add_field(3,'PatchSize',260)
+Patch.add_field(4,'Attributes',1282)
+Patch.add_field(5,'Header',6400)
+Patch.add_field(6,'StreamRef_',7462)
+
+PatchPackage = Table('PatchPackage')
+PatchPackage.add_field(1,'PatchId',11558)
+PatchPackage.add_field(2,'Media_',1282)
+
+PublishComponent = Table('PublishComponent')
+PublishComponent.add_field(1,'ComponentId',11558)
+PublishComponent.add_field(2,'Qualifier',11775)
+PublishComponent.add_field(3,'Component_',11592)
+PublishComponent.add_field(4,'AppData',8191)
+PublishComponent.add_field(5,'Feature_',3366)
+
+RadioButton = Table('RadioButton')
+RadioButton.add_field(1,'Property',11592)
+RadioButton.add_field(2,'Order',9474)
+RadioButton.add_field(3,'Value',3392)
+RadioButton.add_field(4,'X',1282)
+RadioButton.add_field(5,'Y',1282)
+RadioButton.add_field(6,'Width',1282)
+RadioButton.add_field(7,'Height',1282)
+RadioButton.add_field(8,'Text',8000)
+RadioButton.add_field(9,'Help',7986)
+
+Registry = Table('Registry')
+Registry.add_field(1,'Registry',11592)
+Registry.add_field(2,'Root',1282)
+Registry.add_field(3,'Key',4095)
+Registry.add_field(4,'Name',8191)
+Registry.add_field(5,'Value',7936)
+Registry.add_field(6,'Component_',3400)
+
+RegLocator = Table('RegLocator')
+RegLocator.add_field(1,'Signature_',11592)
+RegLocator.add_field(2,'Root',1282)
+RegLocator.add_field(3,'Key',3583)
+RegLocator.add_field(4,'Name',7679)
+RegLocator.add_field(5,'Type',5378)
+
+RemoveFile = Table('RemoveFile')
+RemoveFile.add_field(1,'FileKey',11592)
+RemoveFile.add_field(2,'Component_',3400)
+RemoveFile.add_field(3,'FileName',8191)
+RemoveFile.add_field(4,'DirProperty',3400)
+RemoveFile.add_field(5,'InstallMode',1282)
+
+RemoveIniFile = Table('RemoveIniFile')
+RemoveIniFile.add_field(1,'RemoveIniFile',11592)
+RemoveIniFile.add_field(2,'FileName',4095)
+RemoveIniFile.add_field(3,'DirProperty',7496)
+RemoveIniFile.add_field(4,'Section',3936)
+RemoveIniFile.add_field(5,'Key',3968)
+RemoveIniFile.add_field(6,'Value',8191)
+RemoveIniFile.add_field(7,'Action',1282)
+RemoveIniFile.add_field(8,'Component_',3400)
+
+RemoveRegistry = Table('RemoveRegistry')
+RemoveRegistry.add_field(1,'RemoveRegistry',11592)
+RemoveRegistry.add_field(2,'Root',1282)
+RemoveRegistry.add_field(3,'Key',4095)
+RemoveRegistry.add_field(4,'Name',8191)
+RemoveRegistry.add_field(5,'Component_',3400)
+
+ReserveCost = Table('ReserveCost')
+ReserveCost.add_field(1,'ReserveKey',11592)
+ReserveCost.add_field(2,'Component_',3400)
+ReserveCost.add_field(3,'ReserveFolder',7496)
+ReserveCost.add_field(4,'ReserveLocal',260)
+ReserveCost.add_field(5,'ReserveSource',260)
+
+SelfReg = Table('SelfReg')
+SelfReg.add_field(1,'File_',11592)
+SelfReg.add_field(2,'Cost',5378)
+
+ServiceControl = Table('ServiceControl')
+ServiceControl.add_field(1,'ServiceControl',11592)
+ServiceControl.add_field(2,'Name',4095)
+ServiceControl.add_field(3,'Event',1282)
+ServiceControl.add_field(4,'Arguments',8191)
+ServiceControl.add_field(5,'Wait',5378)
+ServiceControl.add_field(6,'Component_',3400)
+
+ServiceInstall = Table('ServiceInstall')
+ServiceInstall.add_field(1,'ServiceInstall',11592)
+ServiceInstall.add_field(2,'Name',3583)
+ServiceInstall.add_field(3,'DisplayName',8191)
+ServiceInstall.add_field(4,'ServiceType',260)
+ServiceInstall.add_field(5,'StartType',260)
+ServiceInstall.add_field(6,'ErrorControl',260)
+ServiceInstall.add_field(7,'LoadOrderGroup',7679)
+ServiceInstall.add_field(8,'Dependencies',7679)
+ServiceInstall.add_field(9,'StartName',7679)
+ServiceInstall.add_field(10,'Password',7679)
+ServiceInstall.add_field(11,'Arguments',7679)
+ServiceInstall.add_field(12,'Component_',3400)
+ServiceInstall.add_field(13,'Description',8191)
+
+Shortcut = Table('Shortcut')
+Shortcut.add_field(1,'Shortcut',11592)
+Shortcut.add_field(2,'Directory_',3400)
+Shortcut.add_field(3,'Name',3968)
+Shortcut.add_field(4,'Component_',3400)
+Shortcut.add_field(5,'Target',3400)
+Shortcut.add_field(6,'Arguments',7679)
+Shortcut.add_field(7,'Description',8191)
+Shortcut.add_field(8,'Hotkey',5378)
+Shortcut.add_field(9,'Icon_',7496)
+Shortcut.add_field(10,'IconIndex',5378)
+Shortcut.add_field(11,'ShowCmd',5378)
+Shortcut.add_field(12,'WkDir',7496)
+
+Signature = Table('Signature')
+Signature.add_field(1,'Signature',11592)
+Signature.add_field(2,'FileName',3583)
+Signature.add_field(3,'MinVersion',7444)
+Signature.add_field(4,'MaxVersion',7444)
+Signature.add_field(5,'MinSize',4356)
+Signature.add_field(6,'MaxSize',4356)
+Signature.add_field(7,'MinDate',4356)
+Signature.add_field(8,'MaxDate',4356)
+Signature.add_field(9,'Languages',7679)
+
+TextStyle = Table('TextStyle')
+TextStyle.add_field(1,'TextStyle',11592)
+TextStyle.add_field(2,'FaceName',3360)
+TextStyle.add_field(3,'Size',1282)
+TextStyle.add_field(4,'Color',4356)
+TextStyle.add_field(5,'StyleBits',5378)
+
+TypeLib = Table('TypeLib')
+TypeLib.add_field(1,'LibID',11558)
+TypeLib.add_field(2,'Language',9474)
+TypeLib.add_field(3,'Component_',11592)
+TypeLib.add_field(4,'Version',4356)
+TypeLib.add_field(5,'Description',8064)
+TypeLib.add_field(6,'Directory_',7496)
+TypeLib.add_field(7,'Feature_',3366)
+TypeLib.add_field(8,'Cost',4356)
+
+UIText = Table('UIText')
+UIText.add_field(1,'Key',11592)
+UIText.add_field(2,'Text',8191)
+
+Upgrade = Table('Upgrade')
+Upgrade.add_field(1,'UpgradeCode',11558)
+Upgrade.add_field(2,'VersionMin',15636)
+Upgrade.add_field(3,'VersionMax',15636)
+Upgrade.add_field(4,'Language',15871)
+Upgrade.add_field(5,'Attributes',8452)
+Upgrade.add_field(6,'Remove',7679)
+Upgrade.add_field(7,'ActionProperty',3400)
+
+Verb = Table('Verb')
+Verb.add_field(1,'Extension_',11775)
+Verb.add_field(2,'Verb',11552)
+Verb.add_field(3,'Sequence',5378)
+Verb.add_field(4,'Command',8191)
+Verb.add_field(5,'Argument',8191)
+
+tables=[_Validation, ActionText, AdminExecuteSequence, Condition, AdminUISequence, AdvtExecuteSequence, AdvtUISequence, AppId, AppSearch, Property, BBControl, Billboard, Feature, Binary, BindImage, File, CCPSearch, CheckBox, Class, Component, Icon, ProgId, ComboBox, CompLocator, Complus, Directory, Control, Dialog, ControlCondition, ControlEvent, CreateFolder, CustomAction, DrLocator, DuplicateFile, Environment, Error, EventMapping, Extension, MIME, FeatureComponents, FileSFPCatalog, SFPCatalog, Font, IniFile, IniLocator, InstallExecuteSequence, InstallUISequence, IsolatedComponent, LaunchCondition, ListBox, ListView, LockPermissions, Media, MoveFile, MsiAssembly, MsiAssemblyName, MsiDigitalCertificate, MsiDigitalSignature, MsiFileHash, MsiPatchHeaders, ODBCAttribute, ODBCDriver, ODBCDataSource, ODBCSourceAttribute, ODBCTranslator, Patch, PatchPackage, PublishComponent, RadioButton, Registry, RegLocator, RemoveFile, RemoveIniFile, RemoveRegistry, ReserveCost, SelfReg, ServiceControl, ServiceInstall, Shortcut, Signature, TextStyle, TypeLib, UIText, Upgrade, Verb]
+
+_Validation_records = [
+(u'_Validation',u'Table',u'N',None, None, None, None, u'Identifier',None, u'Name of table',),
+(u'_Validation',u'Column',u'N',None, None, None, None, u'Identifier',None, u'Name of column',),
+(u'_Validation',u'Description',u'Y',None, None, None, None, u'Text',None, u'Description of column',),
+(u'_Validation',u'Set',u'Y',None, None, None, None, u'Text',None, u'Set of values that are permitted',),
+(u'_Validation',u'Category',u'Y',None, None, None, None, None, u'Text;Formatted;Template;Condition;Guid;Path;Version;Language;Identifier;Binary;UpperCase;LowerCase;Filename;Paths;AnyPath;WildCardFilename;RegPath;KeyFormatted;CustomSource;Property;Cabinet;Shortcut;URL',u'String category',),
+(u'_Validation',u'KeyColumn',u'Y',1,32,None, None, None, None, u'Column to which foreign key connects',),
+(u'_Validation',u'KeyTable',u'Y',None, None, None, None, u'Identifier',None, u'For foreign key, Name of table to which data must link',),
+(u'_Validation',u'MaxValue',u'Y',-2147483647,2147483647,None, None, None, None, u'Maximum value allowed',),
+(u'_Validation',u'MinValue',u'Y',-2147483647,2147483647,None, None, None, None, u'Minimum value allowed',),
+(u'_Validation',u'Nullable',u'N',None, None, None, None, None, u'Y;N;@',u'Whether the column is nullable',),
+(u'ActionText',u'Description',u'Y',None, None, None, None, u'Text',None, u'Localized description displayed in progress dialog and log when action is executing.',),
+(u'ActionText',u'Action',u'N',None, None, None, None, u'Identifier',None, u'Name of action to be described.',),
+(u'ActionText',u'Template',u'Y',None, None, None, None, u'Template',None, u'Optional localized format template used to format action data records for display during action execution.',),
+(u'AdminExecuteSequence',u'Action',u'N',None, None, None, None, u'Identifier',None, u'Name of action to invoke, either in the engine or the handler DLL.',),
+(u'AdminExecuteSequence',u'Condition',u'Y',None, None, None, None, u'Condition',None, u'Optional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData.',),
+(u'AdminExecuteSequence',u'Sequence',u'Y',-4,32767,None, None, None, None, u'Number that determines the sort order in which the actions are to be executed.  Leave blank to suppress action.',),
+(u'Condition',u'Condition',u'Y',None, None, None, None, u'Condition',None, u'Expression evaluated to determine if Level in the Feature table is to change.',),
+(u'Condition',u'Feature_',u'N',None, None, u'Feature',1,u'Identifier',None, u'Reference to a Feature entry in Feature table.',),
+(u'Condition',u'Level',u'N',0,32767,None, None, None, None, u'New selection Level to set in Feature table if Condition evaluates to TRUE.',),
+(u'AdminUISequence',u'Action',u'N',None, None, None, None, u'Identifier',None, u'Name of action to invoke, either in the engine or the handler DLL.',),
+(u'AdminUISequence',u'Condition',u'Y',None, None, None, None, u'Condition',None, u'Optional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData.',),
+(u'AdminUISequence',u'Sequence',u'Y',-4,32767,None, None, None, None, u'Number that determines the sort order in which the actions are to be executed.  Leave blank to suppress action.',),
+(u'AdvtExecuteSequence',u'Action',u'N',None, None, None, None, u'Identifier',None, u'Name of action to invoke, either in the engine or the handler DLL.',),
+(u'AdvtExecuteSequence',u'Condition',u'Y',None, None, None, None, u'Condition',None, u'Optional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData.',),
+(u'AdvtExecuteSequence',u'Sequence',u'Y',-4,32767,None, None, None, None, u'Number that determines the sort order in which the actions are to be executed.  Leave blank to suppress action.',),
+(u'AdvtUISequence',u'Action',u'N',None, None, None, None, u'Identifier',None, u'Name of action to invoke, either in the engine or the handler DLL.',),
+(u'AdvtUISequence',u'Condition',u'Y',None, None, None, None, u'Condition',None, u'Optional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData.',),
+(u'AdvtUISequence',u'Sequence',u'Y',-4,32767,None, None, None, None, u'Number that determines the sort order in which the actions are to be executed.  Leave blank to suppress action.',),
+(u'AppId',u'AppId',u'N',None, None, None, None, u'Guid',None, None, ),
+(u'AppId',u'ActivateAtStorage',u'Y',0,1,None, None, None, None, None, ),
+(u'AppId',u'DllSurrogate',u'Y',None, None, None, None, u'Text',None, None, ),
+(u'AppId',u'LocalService',u'Y',None, None, None, None, u'Text',None, None, ),
+(u'AppId',u'RemoteServerName',u'Y',None, None, None, None, u'Formatted',None, None, ),
+(u'AppId',u'RunAsInteractiveUser',u'Y',0,1,None, None, None, None, None, ),
+(u'AppId',u'ServiceParameters',u'Y',None, None, None, None, u'Text',None, None, ),
+(u'AppSearch',u'Property',u'N',None, None, None, None, u'Identifier',None, u'The property associated with a Signature',),
+(u'AppSearch',u'Signature_',u'N',None, None, u'Signature;RegLocator;IniLocator;DrLocator;CompLocator',1,u'Identifier',None, u'The Signature_ represents a unique file signature and is also the foreign key in the Signature,  RegLocator, IniLocator, CompLocator and the DrLocator tables.',),
+(u'Property',u'Property',u'N',None, None, None, None, u'Identifier',None, u'Name of property, uppercase if settable by launcher or loader.',),
+(u'Property',u'Value',u'N',None, None, None, None, u'Text',None, u'String value for property.  Never null or empty.',),
+(u'BBControl',u'Type',u'N',None, None, None, None, u'Identifier',None, u'The type of the control.',),
+(u'BBControl',u'Y',u'N',0,32767,None, None, None, None, u'Vertical coordinate of the upper left corner of the bounding rectangle of the control.',),
+(u'BBControl',u'Text',u'Y',None, None, None, None, u'Text',None, u'A string used to set the initial text contained within a control (if appropriate).',),
+(u'BBControl',u'BBControl',u'N',None, None, None, None, u'Identifier',None, u'Name of the control. This name must be unique within a billboard, but can repeat on different billboard.',),
+(u'BBControl',u'Attributes',u'Y',0,2147483647,None, None, None, None, u'A 32-bit word that specifies the attribute flags to be applied to this control.',),
+(u'BBControl',u'Billboard_',u'N',None, None, u'Billboard',1,u'Identifier',None, u'External key to the Billboard table, name of the billboard.',),
+(u'BBControl',u'Height',u'N',0,32767,None, None, None, None, u'Height of the bounding rectangle of the control.',),
+(u'BBControl',u'Width',u'N',0,32767,None, None, None, None, u'Width of the bounding rectangle of the control.',),
+(u'BBControl',u'X',u'N',0,32767,None, None, None, None, u'Horizontal coordinate of the upper left corner of the bounding rectangle of the control.',),
+(u'Billboard',u'Action',u'Y',None, None, None, None, u'Identifier',None, u'The name of an action. The billboard is displayed during the progress messages received from this action.',),
+(u'Billboard',u'Billboard',u'N',None, None, None, None, u'Identifier',None, u'Name of the billboard.',),
+(u'Billboard',u'Feature_',u'N',None, None, u'Feature',1,u'Identifier',None, u'An external key to the Feature Table. The billboard is shown only if this feature is being installed.',),
+(u'Billboard',u'Ordering',u'Y',0,32767,None, None, None, None, u'A positive integer. If there is more than one billboard corresponding to an action they will be shown in the order defined by this column.',),
+(u'Feature',u'Description',u'Y',None, None, None, None, u'Text',None, u'Longer descriptive text describing a visible feature item.',),
+(u'Feature',u'Attributes',u'N',None, None, None, None, None, u'0;1;2;4;5;6;8;9;10;16;17;18;20;21;22;24;25;26;32;33;34;36;37;38;48;49;50;52;53;54',u'Feature attributes',),
+(u'Feature',u'Feature',u'N',None, None, None, None, u'Identifier',None, u'Primary key used to identify a particular feature record.',),
+(u'Feature',u'Directory_',u'Y',None, None, u'Directory',1,u'UpperCase',None, u'The name of the Directory that can be configured by the UI. A non-null value will enable the browse button.',),
+(u'Feature',u'Level',u'N',0,32767,None, None, None, None, u'The install level at which record will be initially selected. An install level of 0 will disable an item and prevent its display.',),
+(u'Feature',u'Title',u'Y',None, None, None, None, u'Text',None, u'Short text identifying a visible feature item.',),
+(u'Feature',u'Display',u'Y',0,32767,None, None, None, None, u'Numeric sort order, used to force a specific display ordering.',),
+(u'Feature',u'Feature_Parent',u'Y',None, None, u'Feature',1,u'Identifier',None, u'Optional key of a parent record in the same table. If the parent is not selected, then the record will not be installed. Null indicates a root item.',),
+(u'Binary',u'Name',u'N',None, None, None, None, u'Identifier',None, u'Unique key identifying the binary data.',),
+(u'Binary',u'Data',u'N',None, None, None, None, u'Binary',None, u'The unformatted binary data.',),
+(u'BindImage',u'File_',u'N',None, None, u'File',1,u'Identifier',None, u'The index into the File table. This must be an executable file.',),
+(u'BindImage',u'Path',u'Y',None, None, None, None, u'Paths',None, u'A list of ;  delimited paths that represent the paths to be searched for the import DLLS. The list is usually a list of properties each enclosed within square brackets [] .',),
+(u'File',u'Sequence',u'N',1,32767,None, None, None, None, u'Sequence with respect to the media images; order must track cabinet order.',),
+(u'File',u'Attributes',u'Y',0,32767,None, None, None, None, u'Integer containing bit flags representing file attributes (with the decimal value of each bit position in parentheses)',),
+(u'File',u'File',u'N',None, None, None, None, u'Identifier',None, u'Primary key, non-localized token, must match identifier in cabinet.  For uncompressed files, this field is ignored.',),
+(u'File',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key referencing Component that controls the file.',),
+(u'File',u'FileName',u'N',None, None, None, None, u'Filename',None, u'File name used for installation, may be localized.  This may contain a "short name|long name" pair.',),
+(u'File',u'FileSize',u'N',0,2147483647,None, None, None, None, u'Size of file in bytes (long integer).',),
+(u'File',u'Language',u'Y',None, None, None, None, u'Language',None, u'List of decimal language Ids, comma-separated if more than one.',),
+(u'File',u'Version',u'Y',None, None, u'File',1,u'Version',None, u'Version string for versioned files;  Blank for unversioned files.',),
+(u'CCPSearch',u'Signature_',u'N',None, None, u'Signature;RegLocator;IniLocator;DrLocator;CompLocator',1,u'Identifier',None, u'The Signature_ represents a unique file signature and is also the foreign key in the Signature,  RegLocator, IniLocator, CompLocator and the DrLocator tables.',),
+(u'CheckBox',u'Property',u'N',None, None, None, None, u'Identifier',None, u'A named property to be tied to the item.',),
+(u'CheckBox',u'Value',u'Y',None, None, None, None, u'Formatted',None, u'The value string associated with the item.',),
+(u'Class',u'Description',u'Y',None, None, None, None, u'Text',None, u'Localized description for the Class.',),
+(u'Class',u'Attributes',u'Y',None, 32767,None, None, None, None, u'Class registration attributes.',),
+(u'Class',u'Feature_',u'N',None, None, u'Feature',1,u'Identifier',None, u'Required foreign key into the Feature Table, specifying the feature to validate or install in order for the CLSID factory to be operational.',),
+(u'Class',u'AppId_',u'Y',None, None, u'AppId',1,u'Guid',None, u'Optional AppID containing DCOM information for associated application (string GUID).',),
+(u'Class',u'Argument',u'Y',None, None, None, None, u'Formatted',None, u'optional argument for LocalServers.',),
+(u'Class',u'CLSID',u'N',None, None, None, None, u'Guid',None, u'The CLSID of an OLE factory.',),
+(u'Class',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Required foreign key into the Component Table, specifying the component for which to return a path when called through LocateComponent.',),
+(u'Class',u'Context',u'N',None, None, None, None, u'Identifier',None, u'The numeric server context for this server. CLSCTX_xxxx',),
+(u'Class',u'DefInprocHandler',u'Y',None, None, None, None, u'Filename',u'1;2;3',u'Optional default inproc handler.  Only optionally provided if Context=CLSCTX_LOCAL_SERVER.  Typically "ole32.dll" or "mapi32.dll"',),
+(u'Class',u'FileTypeMask',u'Y',None, None, None, None, u'Text',None, u'Optional string containing information for the HKCRthis CLSID) key. If multiple patterns exist, they must be delimited by a semicolon, and numeric subkeys will be generated: 0,1,2...',),
+(u'Class',u'Icon_',u'Y',None, None, u'Icon',1,u'Identifier',None, u'Optional foreign key into the Icon Table, specifying the icon file associated with this CLSID. Will be written under the DefaultIcon key.',),
+(u'Class',u'IconIndex',u'Y',-32767,32767,None, None, None, None, u'Optional icon index.',),
+(u'Class',u'ProgId_Default',u'Y',None, None, u'ProgId',1,u'Text',None, u'Optional ProgId associated with this CLSID.',),
+(u'Component',u'Condition',u'Y',None, None, None, None, u'Condition',None, u"A conditional statement that will disable this component if the specified condition evaluates to the 'True' state. If a component is disabled, it will not be installed, regardless of the 'Action' state associated with the component.",),
+(u'Component',u'Attributes',u'N',None, None, None, None, None, None, u'Remote execution option, one of irsEnum',),
+(u'Component',u'Component',u'N',None, None, None, None, u'Identifier',None, u'Primary key used to identify a particular component record.',),
+(u'Component',u'ComponentId',u'Y',None, None, None, None, u'Guid',None, u'A string GUID unique to this component, version, and language.',),
+(u'Component',u'Directory_',u'N',None, None, u'Directory',1,u'Identifier',None, u'Required key of a Directory table record. This is actually a property name whose value contains the actual path, set either by the AppSearch action or with the default setting obtained from the Directory table.',),
+(u'Component',u'KeyPath',u'Y',None, None, u'File;Registry;ODBCDataSource',1,u'Identifier',None, u'Either the primary key into the File table, Registry table, or ODBCDataSource table. This extract path is stored when the component is installed, and is used to detect the presence of the component and to return the path to it.',),
+(u'Icon',u'Name',u'N',None, None, None, None, u'Identifier',None, u'Primary key. Name of the icon file.',),
+(u'Icon',u'Data',u'N',None, None, None, None, u'Binary',None, u'Binary stream. The binary icon data in PE (.DLL or .EXE) or icon (.ICO) format.',),
+(u'ProgId',u'Description',u'Y',None, None, None, None, u'Text',None, u'Localized description for the Program identifier.',),
+(u'ProgId',u'Icon_',u'Y',None, None, u'Icon',1,u'Identifier',None, u'Optional foreign key into the Icon Table, specifying the icon file associated with this ProgId. Will be written under the DefaultIcon key.',),
+(u'ProgId',u'IconIndex',u'Y',-32767,32767,None, None, None, None, u'Optional icon index.',),
+(u'ProgId',u'ProgId',u'N',None, None, None, None, u'Text',None, u'The Program Identifier. Primary key.',),
+(u'ProgId',u'Class_',u'Y',None, None, u'Class',1,u'Guid',None, u'The CLSID of an OLE factory corresponding to the ProgId.',),
+(u'ProgId',u'ProgId_Parent',u'Y',None, None, u'ProgId',1,u'Text',None, u'The Parent Program Identifier. If specified, the ProgId column becomes a version independent prog id.',),
+(u'ComboBox',u'Text',u'Y',None, None, None, None, u'Formatted',None, u'The visible text to be assigned to the item. Optional. If this entry or the entire column is missing, the text is the same as the value.',),
+(u'ComboBox',u'Property',u'N',None, None, None, None, u'Identifier',None, u'A named property to be tied to this item. All the items tied to the same property become part of the same combobox.',),
+(u'ComboBox',u'Value',u'N',None, None, None, None, u'Formatted',None, u'The value string associated with this item. Selecting the line will set the associated property to this value.',),
+(u'ComboBox',u'Order',u'N',1,32767,None, None, None, None, u'A positive integer used to determine the ordering of the items within one list.\tThe integers do not have to be consecutive.',),
+(u'CompLocator',u'Type',u'Y',0,1,None, None, None, None, u'A boolean value that determines if the registry value is a filename or a directory location.',),
+(u'CompLocator',u'Signature_',u'N',None, None, None, None, u'Identifier',None, u'The table key. The Signature_ represents a unique file signature and is also the foreign key in the Signature table.',),
+(u'CompLocator',u'ComponentId',u'N',None, None, None, None, u'Guid',None, u'A string GUID unique to this component, version, and language.',),
+(u'Complus',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key referencing Component that controls the ComPlus component.',),
+(u'Complus',u'ExpType',u'Y',0,32767,None, None, None, None, u'ComPlus component attributes.',),
+(u'Directory',u'Directory',u'N',None, None, None, None, u'Identifier',None, u'Unique identifier for directory entry, primary key. If a property by this name is defined, it contains the full path to the directory.',),
+(u'Directory',u'DefaultDir',u'N',None, None, None, None, u'DefaultDir',None, u"The default sub-path under parent's path.",),
+(u'Directory',u'Directory_Parent',u'Y',None, None, u'Directory',1,u'Identifier',None, u'Reference to the entry in this table specifying the default parent directory. A record parented to itself or with a Null parent represents a root of the install tree.',),
+(u'Control',u'Type',u'N',None, None, None, None, u'Identifier',None, u'The type of the control.',),
+(u'Control',u'Y',u'N',0,32767,None, None, None, None, u'Vertical coordinate of the upper left corner of the bounding rectangle of the control.',),
+(u'Control',u'Text',u'Y',None, None, None, None, u'Formatted',None, u'A string used to set the initial text contained within a control (if appropriate).',),
+(u'Control',u'Property',u'Y',None, None, None, None, u'Identifier',None, u'The name of a defined property to be linked to this control. ',),
+(u'Control',u'Attributes',u'Y',0,2147483647,None, None, None, None, u'A 32-bit word that specifies the attribute flags to be applied to this control.',),
+(u'Control',u'Height',u'N',0,32767,None, None, None, None, u'Height of the bounding rectangle of the control.',),
+(u'Control',u'Width',u'N',0,32767,None, None, None, None, u'Width of the bounding rectangle of the control.',),
+(u'Control',u'X',u'N',0,32767,None, None, None, None, u'Horizontal coordinate of the upper left corner of the bounding rectangle of the control.',),
+(u'Control',u'Control',u'N',None, None, None, None, u'Identifier',None, u'Name of the control. This name must be unique within a dialog, but can repeat on different dialogs. ',),
+(u'Control',u'Control_Next',u'Y',None, None, u'Control',2,u'Identifier',None, u'The name of an other control on the same dialog. This link defines the tab order of the controls. The links have to form one or more cycles!',),
+(u'Control',u'Dialog_',u'N',None, None, u'Dialog',1,u'Identifier',None, u'External key to the Dialog table, name of the dialog.',),
+(u'Control',u'Help',u'Y',None, None, None, None, u'Text',None, u'The help strings used with the button. The text is optional. ',),
+(u'Dialog',u'Attributes',u'Y',0,2147483647,None, None, None, None, u'A 32-bit word that specifies the attribute flags to be applied to this dialog.',),
+(u'Dialog',u'Height',u'N',0,32767,None, None, None, None, u'Height of the bounding rectangle of the dialog.',),
+(u'Dialog',u'Width',u'N',0,32767,None, None, None, None, u'Width of the bounding rectangle of the dialog.',),
+(u'Dialog',u'Dialog',u'N',None, None, None, None, u'Identifier',None, u'Name of the dialog.',),
+(u'Dialog',u'Control_Cancel',u'Y',None, None, u'Control',2,u'Identifier',None, u'Defines the cancel control. Hitting escape or clicking on the close icon on the dialog is equivalent to pushing this button.',),
+(u'Dialog',u'Control_Default',u'Y',None, None, u'Control',2,u'Identifier',None, u'Defines the default control. Hitting return is equivalent to pushing this button.',),
+(u'Dialog',u'Control_First',u'N',None, None, u'Control',2,u'Identifier',None, u'Defines the control that has the focus when the dialog is created.',),
+(u'Dialog',u'HCentering',u'N',0,100,None, None, None, None, u'Horizontal position of the dialog on a 0-100 scale. 0 means left end, 100 means right end of the screen, 50 center.',),
+(u'Dialog',u'Title',u'Y',None, None, None, None, u'Formatted',None, u"A text string specifying the title to be displayed in the title bar of the dialog's window.",),
+(u'Dialog',u'VCentering',u'N',0,100,None, None, None, None, u'Vertical position of the dialog on a 0-100 scale. 0 means top end, 100 means bottom end of the screen, 50 center.',),
+(u'ControlCondition',u'Action',u'N',None, None, None, None, None, u'Default;Disable;Enable;Hide;Show',u'The desired action to be taken on the specified control.',),
+(u'ControlCondition',u'Condition',u'N',None, None, None, None, u'Condition',None, u'A standard conditional statement that specifies under which conditions the action should be triggered.',),
+(u'ControlCondition',u'Dialog_',u'N',None, None, u'Dialog',1,u'Identifier',None, u'A foreign key to the Dialog table, name of the dialog.',),
+(u'ControlCondition',u'Control_',u'N',None, None, u'Control',2,u'Identifier',None, u'A foreign key to the Control table, name of the control.',),
+(u'ControlEvent',u'Condition',u'Y',None, None, None, None, u'Condition',None, u'A standard conditional statement that specifies under which conditions an event should be triggered.',),
+(u'ControlEvent',u'Ordering',u'Y',0,2147483647,None, None, None, None, u'An integer used to order several events tied to the same control. Can be left blank.',),
+(u'ControlEvent',u'Argument',u'N',None, None, None, None, u'Formatted',None, u'A value to be used as a modifier when triggering a particular event.',),
+(u'ControlEvent',u'Dialog_',u'N',None, None, u'Dialog',1,u'Identifier',None, u'A foreign key to the Dialog table, name of the dialog.',),
+(u'ControlEvent',u'Control_',u'N',None, None, u'Control',2,u'Identifier',None, u'A foreign key to the Control table, name of the control',),
+(u'ControlEvent',u'Event',u'N',None, None, None, None, u'Formatted',None, u'An identifier that specifies the type of the event that should take place when the user interacts with control specified by the first two entries.',),
+(u'CreateFolder',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key into the Component table.',),
+(u'CreateFolder',u'Directory_',u'N',None, None, u'Directory',1,u'Identifier',None, u'Primary key, could be foreign key into the Directory table.',),
+(u'CustomAction',u'Type',u'N',1,16383,None, None, None, None, u'The numeric custom action type, consisting of source location, code type, entry, option flags.',),
+(u'CustomAction',u'Action',u'N',None, None, None, None, u'Identifier',None, u'Primary key, name of action, normally appears in sequence table unless private use.',),
+(u'CustomAction',u'Source',u'Y',None, None, None, None, u'CustomSource',None, u'The table reference of the source of the code.',),
+(u'CustomAction',u'Target',u'Y',None, None, None, None, u'Formatted',None, u'Excecution parameter, depends on the type of custom action',),
+(u'DrLocator',u'Signature_',u'N',None, None, None, None, u'Identifier',None, u'The Signature_ represents a unique file signature and is also the foreign key in the Signature table.',),
+(u'DrLocator',u'Path',u'Y',None, None, None, None, u'AnyPath',None, u'The path on the user system. This is a either a subpath below the value of the Parent or a full path. The path may contain properties enclosed within [ ] that will be expanded.',),
+(u'DrLocator',u'Depth',u'Y',0,32767,None, None, None, None, u'The depth below the path to which the Signature_ is recursively searched. If absent, the depth is assumed to be 0.',),
+(u'DrLocator',u'Parent',u'Y',None, None, None, None, u'Identifier',None, u'The parent file signature. It is also a foreign key in the Signature table. If null and the Path column does not expand to a full path, then all the fixed drives of the user system are searched using the Path.',),
+(u'DuplicateFile',u'File_',u'N',None, None, u'File',1,u'Identifier',None, u'Foreign key referencing the source file to be duplicated.',),
+(u'DuplicateFile',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key referencing Component that controls the duplicate file.',),
+(u'DuplicateFile',u'DestFolder',u'Y',None, None, None, None, u'Identifier',None, u'Name of a property whose value is assumed to resolve to the full pathname to a destination folder.',),
+(u'DuplicateFile',u'DestName',u'Y',None, None, None, None, u'Filename',None, u'Filename to be given to the duplicate file.',),
+(u'DuplicateFile',u'FileKey',u'N',None, None, None, None, u'Identifier',None, u'Primary key used to identify a particular file entry',),
+(u'Environment',u'Name',u'N',None, None, None, None, u'Text',None, u'The name of the environmental value.',),
+(u'Environment',u'Value',u'Y',None, None, None, None, u'Formatted',None, u'The value to set in the environmental settings.',),
+(u'Environment',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key into the Component table referencing component that controls the installing of the environmental value.',),
+(u'Environment',u'Environment',u'N',None, None, None, None, u'Identifier',None, u'Unique identifier for the environmental variable setting',),
+(u'Error',u'Error',u'N',0,32767,None, None, None, None, u'Integer error number, obtained from header file IError(...) macros.',),
+(u'Error',u'Message',u'Y',None, None, None, None, u'Template',None, u'Error formatting template, obtained from user ed. or localizers.',),
+(u'EventMapping',u'Dialog_',u'N',None, None, u'Dialog',1,u'Identifier',None, u'A foreign key to the Dialog table, name of the Dialog.',),
+(u'EventMapping',u'Control_',u'N',None, None, u'Control',2,u'Identifier',None, u'A foreign key to the Control table, name of the control.',),
+(u'EventMapping',u'Event',u'N',None, None, None, None, u'Identifier',None, u'An identifier that specifies the type of the event that the control subscribes to.',),
+(u'EventMapping',u'Attribute',u'N',None, None, None, None, u'Identifier',None, u'The name of the control attribute, that is set when this event is received.',),
+(u'Extension',u'Feature_',u'N',None, None, u'Feature',1,u'Identifier',None, u'Required foreign key into the Feature Table, specifying the feature to validate or install in order for the CLSID factory to be operational.',),
+(u'Extension',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Required foreign key into the Component Table, specifying the component for which to return a path when called through LocateComponent.',),
+(u'Extension',u'Extension',u'N',None, None, None, None, u'Text',None, u'The extension associated with the table row.',),
+(u'Extension',u'MIME_',u'Y',None, None, u'MIME',1,u'Text',None, u'Optional Context identifier, typically "type/format" associated with the extension',),
+(u'Extension',u'ProgId_',u'Y',None, None, u'ProgId',1,u'Text',None, u'Optional ProgId associated with this extension.',),
+(u'MIME',u'CLSID',u'Y',None, None, None, None, u'Guid',None, u'Optional associated CLSID.',),
+(u'MIME',u'ContentType',u'N',None, None, None, None, u'Text',None, u'Primary key. Context identifier, typically "type/format".',),
+(u'MIME',u'Extension_',u'N',None, None, u'Extension',1,u'Text',None, u'Optional associated extension (without dot)',),
+(u'FeatureComponents',u'Feature_',u'N',None, None, u'Feature',1,u'Identifier',None, u'Foreign key into Feature table.',),
+(u'FeatureComponents',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key into Component table.',),
+(u'FileSFPCatalog',u'File_',u'N',None, None, u'File',1,u'Identifier',None, u'File associated with the catalog',),
+(u'FileSFPCatalog',u'SFPCatalog_',u'N',None, None, u'SFPCatalog',1,u'Filename',None, u'Catalog associated with the file',),
+(u'SFPCatalog',u'SFPCatalog',u'N',None, None, None, None, u'Filename',None, u'File name for the catalog.',),
+(u'SFPCatalog',u'Catalog',u'N',None, None, None, None, u'Binary',None, u'SFP Catalog',),
+(u'SFPCatalog',u'Dependency',u'Y',None, None, None, None, u'Formatted',None, u'Parent catalog - only used by SFP',),
+(u'Font',u'File_',u'N',None, None, u'File',1,u'Identifier',None, u'Primary key, foreign key into File table referencing font file.',),
+(u'Font',u'FontTitle',u'Y',None, None, None, None, u'Text',None, u'Font name.',),
+(u'IniFile',u'Action',u'N',None, None, None, None, None, u'0;1;3',u'The type of modification to be made, one of iifEnum',),
+(u'IniFile',u'Value',u'N',None, None, None, None, u'Formatted',None, u'The value to be written.',),
+(u'IniFile',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key into the Component table referencing component that controls the installing of the .INI value.',),
+(u'IniFile',u'FileName',u'N',None, None, None, None, u'Filename',None, u'The .INI file name in which to write the information',),
+(u'IniFile',u'IniFile',u'N',None, None, None, None, u'Identifier',None, u'Primary key, non-localized token.',),
+(u'IniFile',u'DirProperty',u'Y',None, None, None, None, u'Identifier',None, u'Foreign key into the Directory table denoting the directory where the .INI file is.',),
+(u'IniFile',u'Key',u'N',None, None, None, None, u'Formatted',None, u'The .INI file key below Section.',),
+(u'IniFile',u'Section',u'N',None, None, None, None, u'Formatted',None, u'The .INI file Section.',),
+(u'IniLocator',u'Type',u'Y',0,2,None, None, None, None, u'An integer value that determines if the .INI value read is a filename or a directory location or to be used as is w/o interpretation.',),
+(u'IniLocator',u'Signature_',u'N',None, None, None, None, u'Identifier',None, u'The table key. The Signature_ represents a unique file signature and is also the foreign key in the Signature table.',),
+(u'IniLocator',u'FileName',u'N',None, None, None, None, u'Filename',None, u'The .INI file name.',),
+(u'IniLocator',u'Key',u'N',None, None, None, None, u'Text',None, u'Key value (followed by an equals sign in INI file).',),
+(u'IniLocator',u'Section',u'N',None, None, None, None, u'Text',None, u'Section name within in file (within square brackets in INI file).',),
+(u'IniLocator',u'Field',u'Y',0,32767,None, None, None, None, u'The field in the .INI line. If Field is null or 0 the entire line is read.',),
+(u'InstallExecuteSequence',u'Action',u'N',None, None, None, None, u'Identifier',None, u'Name of action to invoke, either in the engine or the handler DLL.',),
+(u'InstallExecuteSequence',u'Condition',u'Y',None, None, None, None, u'Condition',None, u'Optional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData.',),
+(u'InstallExecuteSequence',u'Sequence',u'Y',-4,32767,None, None, None, None, u'Number that determines the sort order in which the actions are to be executed.  Leave blank to suppress action.',),
+(u'InstallUISequence',u'Action',u'N',None, None, None, None, u'Identifier',None, u'Name of action to invoke, either in the engine or the handler DLL.',),
+(u'InstallUISequence',u'Condition',u'Y',None, None, None, None, u'Condition',None, u'Optional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData.',),
+(u'InstallUISequence',u'Sequence',u'Y',-4,32767,None, None, None, None, u'Number that determines the sort order in which the actions are to be executed.  Leave blank to suppress action.',),
+(u'IsolatedComponent',u'Component_Application',u'N',None, None, u'Component',1,u'Identifier',None, u'Key to Component table item for application',),
+(u'IsolatedComponent',u'Component_Shared',u'N',None, None, u'Component',1,u'Identifier',None, u'Key to Component table item to be isolated',),
+(u'LaunchCondition',u'Description',u'N',None, None, None, None, u'Formatted',None, u'Localizable text to display when condition fails and install must abort.',),
+(u'LaunchCondition',u'Condition',u'N',None, None, None, None, u'Condition',None, u'Expression which must evaluate to TRUE in order for install to commence.',),
+(u'ListBox',u'Text',u'Y',None, None, None, None, u'Text',None, u'The visible text to be assigned to the item. Optional. If this entry or the entire column is missing, the text is the same as the value.',),
+(u'ListBox',u'Property',u'N',None, None, None, None, u'Identifier',None, u'A named property to be tied to this item. All the items tied to the same property become part of the same listbox.',),
+(u'ListBox',u'Value',u'N',None, None, None, None, u'Formatted',None, u'The value string associated with this item. Selecting the line will set the associated property to this value.',),
+(u'ListBox',u'Order',u'N',1,32767,None, None, None, None, u'A positive integer used to determine the ordering of the items within one list..The integers do not have to be consecutive.',),
+(u'ListView',u'Text',u'Y',None, None, None, None, u'Text',None, u'The visible text to be assigned to the item. Optional. If this entry or the entire column is missing, the text is the same as the value.',),
+(u'ListView',u'Property',u'N',None, None, None, None, u'Identifier',None, u'A named property to be tied to this item. All the items tied to the same property become part of the same listview.',),
+(u'ListView',u'Value',u'N',None, None, None, None, u'Identifier',None, u'The value string associated with this item. Selecting the line will set the associated property to this value.',),
+(u'ListView',u'Order',u'N',1,32767,None, None, None, None, u'A positive integer used to determine the ordering of the items within one list..The integers do not have to be consecutive.',),
+(u'ListView',u'Binary_',u'Y',None, None, u'Binary',1,u'Identifier',None, u'The name of the icon to be displayed with the icon. The binary information is looked up from the Binary Table.',),
+(u'LockPermissions',u'Table',u'N',None, None, None, None, u'Identifier',u'Directory;File;Registry',u'Reference to another table name',),
+(u'LockPermissions',u'Domain',u'Y',None, None, None, None, u'Formatted',None, u'Domain name for user whose permissions are being set. (usually a property)',),
+(u'LockPermissions',u'LockObject',u'N',None, None, None, None, u'Identifier',None, u'Foreign key into Registry or File table',),
+(u'LockPermissions',u'Permission',u'Y',-2147483647,2147483647,None, None, None, None, u'Permission Access mask.  Full Control = 268435456 (GENERIC_ALL = 0x10000000)',),
+(u'LockPermissions',u'User',u'N',None, None, None, None, u'Formatted',None, u'User for permissions to be set.  (usually a property)',),
+(u'Media',u'Source',u'Y',None, None, None, None, u'Property',None, u'The property defining the location of the cabinet file.',),
+(u'Media',u'Cabinet',u'Y',None, None, None, None, u'Cabinet',None, u'If some or all of the files stored on the media are compressed in a cabinet, the name of that cabinet.',),
+(u'Media',u'DiskId',u'N',1,32767,None, None, None, None, u'Primary key, integer to determine sort order for table.',),
+(u'Media',u'DiskPrompt',u'Y',None, None, None, None, u'Text',None, u'Disk name: the visible text actually printed on the disk.  This will be used to prompt the user when this disk needs to be inserted.',),
+(u'Media',u'LastSequence',u'N',0,32767,None, None, None, None, u'File sequence number for the last file for this media.',),
+(u'Media',u'VolumeLabel',u'Y',None, None, None, None, u'Text',None, u'The label attributed to the volume.',),
+(u'ModuleComponents',u'Component',u'N',None, None, u'Component',1,u'Identifier',None, u'Component contained in the module.',),
+(u'ModuleComponents',u'Language',u'N',None, None, u'ModuleSignature',2,None, None, u'Default language ID for module (may be changed by transform).',),
+(u'ModuleComponents',u'ModuleID',u'N',None, None, u'ModuleSignature',1,u'Identifier',None, u'Module containing the component.',),
+(u'ModuleSignature',u'Language',u'N',None, None, None, None, None, None, u'Default decimal language of module.',),
+(u'ModuleSignature',u'Version',u'N',None, None, None, None, u'Version',None, u'Version of the module.',),
+(u'ModuleSignature',u'ModuleID',u'N',None, None, None, None, u'Identifier',None, u'Module identifier (String.GUID).',),
+(u'ModuleDependency',u'ModuleID',u'N',None, None, u'ModuleSignature',1,u'Identifier',None, u'Module requiring the dependency.',),
+(u'ModuleDependency',u'ModuleLanguage',u'N',None, None, u'ModuleSignature',2,None, None, u'Language of module requiring the dependency.',),
+(u'ModuleDependency',u'RequiredID',u'N',None, None, None, None, None, None, u'String.GUID of required module.',),
+(u'ModuleDependency',u'RequiredLanguage',u'N',None, None, None, None, None, None, u'LanguageID of the required module.',),
+(u'ModuleDependency',u'RequiredVersion',u'Y',None, None, None, None, u'Version',None, u'Version of the required version.',),
+(u'ModuleExclusion',u'ModuleID',u'N',None, None, u'ModuleSignature',1,u'Identifier',None, u'String.GUID of module with exclusion requirement.',),
+(u'ModuleExclusion',u'ModuleLanguage',u'N',None, None, u'ModuleSignature',2,None, None, u'LanguageID of module with exclusion requirement.',),
+(u'ModuleExclusion',u'ExcludedID',u'N',None, None, None, None, None, None, u'String.GUID of excluded module.',),
+(u'ModuleExclusion',u'ExcludedLanguage',u'N',None, None, None, None, None, None, u'Language of excluded module.',),
+(u'ModuleExclusion',u'ExcludedMaxVersion',u'Y',None, None, None, None, u'Version',None, u'Maximum version of excluded module.',),
+(u'ModuleExclusion',u'ExcludedMinVersion',u'Y',None, None, None, None, u'Version',None, u'Minimum version of excluded module.',),
+(u'MoveFile',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'If this component is not "selected" for installation or removal, no action will be taken on the associated MoveFile entry',),
+(u'MoveFile',u'DestFolder',u'N',None, None, None, None, u'Identifier',None, u'Name of a property whose value is assumed to resolve to the full path to the destination directory',),
+(u'MoveFile',u'DestName',u'Y',None, None, None, None, u'Filename',None, u'Name to be given to the original file after it is moved or copied.  If blank, the destination file will be given the same name as the source file',),
+(u'MoveFile',u'FileKey',u'N',None, None, None, None, u'Identifier',None, u'Primary key that uniquely identifies a particular MoveFile record',),
+(u'MoveFile',u'Options',u'N',0,1,None, None, None, None, u'Integer value specifying the MoveFile operating mode, one of imfoEnum',),
+(u'MoveFile',u'SourceFolder',u'Y',None, None, None, None, u'Identifier',None, u'Name of a property whose value is assumed to resolve to the full path to the source directory',),
+(u'MoveFile',u'SourceName',u'Y',None, None, None, None, u'Text',None, u"Name of the source file(s) to be moved or copied.  Can contain the '*' or '?' wildcards.",),
+(u'MsiAssembly',u'Attributes',u'Y',None, None, None, None, None, None, u'Assembly attributes',),
+(u'MsiAssembly',u'Feature_',u'N',None, None, u'Feature',1,u'Identifier',None, u'Foreign key into Feature table.',),
+(u'MsiAssembly',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key into Component table.',),
+(u'MsiAssembly',u'File_Application',u'Y',None, None, u'File',1,u'Identifier',None, u'Foreign key into File table, denoting the application context for private assemblies. Null for global assemblies.',),
+(u'MsiAssembly',u'File_Manifest',u'Y',None, None, u'File',1,u'Identifier',None, u'Foreign key into the File table denoting the manifest file for the assembly.',),
+(u'MsiAssemblyName',u'Name',u'N',None, None, None, None, u'Text',None, u'The name part of the name-value pairs for the assembly name.',),
+(u'MsiAssemblyName',u'Value',u'N',None, None, None, None, u'Text',None, u'The value part of the name-value pairs for the assembly name.',),
+(u'MsiAssemblyName',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key into Component table.',),
+(u'MsiDigitalCertificate',u'CertData',u'N',None, None, None, None, u'Binary',None, u'A certificate context blob for a signer certificate',),
+(u'MsiDigitalCertificate',u'DigitalCertificate',u'N',None, None, None, None, u'Identifier',None, u'A unique identifier for the row',),
+(u'MsiDigitalSignature',u'Table',u'N',None, None, None, None, None, u'Media',u'Reference to another table name (only Media table is supported)',),
+(u'MsiDigitalSignature',u'DigitalCertificate_',u'N',None, None, u'MsiDigitalCertificate',1,u'Identifier',None, u'Foreign key to MsiDigitalCertificate table identifying the signer certificate',),
+(u'MsiDigitalSignature',u'Hash',u'Y',None, None, None, None, u'Binary',None, u'The encoded hash blob from the digital signature',),
+(u'MsiDigitalSignature',u'SignObject',u'N',None, None, None, None, u'Text',None, u'Foreign key to Media table',),
+(u'MsiFileHash',u'File_',u'N',None, None, u'File',1,u'Identifier',None, u'Primary key, foreign key into File table referencing file with this hash',),
+(u'MsiFileHash',u'Options',u'N',0,32767,None, None, None, None, u'Various options and attributes for this hash.',),
+(u'MsiFileHash',u'HashPart1',u'N',None, None, None, None, None, None, u'Size of file in bytes (long integer).',),
+(u'MsiFileHash',u'HashPart2',u'N',None, None, None, None, None, None, u'Size of file in bytes (long integer).',),
+(u'MsiFileHash',u'HashPart3',u'N',None, None, None, None, None, None, u'Size of file in bytes (long integer).',),
+(u'MsiFileHash',u'HashPart4',u'N',None, None, None, None, None, None, u'Size of file in bytes (long integer).',),
+(u'MsiPatchHeaders',u'StreamRef',u'N',None, None, None, None, u'Identifier',None, u'Primary key. A unique identifier for the row.',),
+(u'MsiPatchHeaders',u'Header',u'N',None, None, None, None, u'Binary',None, u'Binary stream. The patch header, used for patch validation.',),
+(u'ODBCAttribute',u'Value',u'Y',None, None, None, None, u'Text',None, u'Value for ODBC driver attribute',),
+(u'ODBCAttribute',u'Attribute',u'N',None, None, None, None, u'Text',None, u'Name of ODBC driver attribute',),
+(u'ODBCAttribute',u'Driver_',u'N',None, None, u'ODBCDriver',1,u'Identifier',None, u'Reference to ODBC driver in ODBCDriver table',),
+(u'ODBCDriver',u'Description',u'N',None, None, None, None, u'Text',None, u'Text used as registered name for driver, non-localized',),
+(u'ODBCDriver',u'File_',u'N',None, None, u'File',1,u'Identifier',None, u'Reference to key driver file',),
+(u'ODBCDriver',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Reference to associated component',),
+(u'ODBCDriver',u'Driver',u'N',None, None, None, None, u'Identifier',None, u'Primary key, non-localized.internal token for driver',),
+(u'ODBCDriver',u'File_Setup',u'Y',None, None, u'File',1,u'Identifier',None, u'Optional reference to key driver setup DLL',),
+(u'ODBCDataSource',u'Description',u'N',None, None, None, None, u'Text',None, u'Text used as registered name for data source',),
+(u'ODBCDataSource',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Reference to associated component',),
+(u'ODBCDataSource',u'DataSource',u'N',None, None, None, None, u'Identifier',None, u'Primary key, non-localized.internal token for data source',),
+(u'ODBCDataSource',u'DriverDescription',u'N',None, None, None, None, u'Text',None, u'Reference to driver description, may be existing driver',),
+(u'ODBCDataSource',u'Registration',u'N',0,1,None, None, None, None, u'Registration option: 0=machine, 1=user, others t.b.d.',),
+(u'ODBCSourceAttribute',u'Value',u'Y',None, None, None, None, u'Text',None, u'Value for ODBC data source attribute',),
+(u'ODBCSourceAttribute',u'Attribute',u'N',None, None, None, None, u'Text',None, u'Name of ODBC data source attribute',),
+(u'ODBCSourceAttribute',u'DataSource_',u'N',None, None, u'ODBCDataSource',1,u'Identifier',None, u'Reference to ODBC data source in ODBCDataSource table',),
+(u'ODBCTranslator',u'Description',u'N',None, None, None, None, u'Text',None, u'Text used as registered name for translator',),
+(u'ODBCTranslator',u'File_',u'N',None, None, u'File',1,u'Identifier',None, u'Reference to key translator file',),
+(u'ODBCTranslator',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Reference to associated component',),
+(u'ODBCTranslator',u'File_Setup',u'Y',None, None, u'File',1,u'Identifier',None, u'Optional reference to key translator setup DLL',),
+(u'ODBCTranslator',u'Translator',u'N',None, None, None, None, u'Identifier',None, u'Primary key, non-localized.internal token for translator',),
+(u'Patch',u'Sequence',u'N',0,32767,None, None, None, None, u'Primary key, sequence with respect to the media images; order must track cabinet order.',),
+(u'Patch',u'Attributes',u'N',0,32767,None, None, None, None, u'Integer containing bit flags representing patch attributes',),
+(u'Patch',u'File_',u'N',None, None, None, None, u'Identifier',None, u'Primary key, non-localized token, foreign key to File table, must match identifier in cabinet.',),
+(u'Patch',u'Header',u'Y',None, None, None, None, u'Binary',None, u'Binary stream. The patch header, used for patch validation.',),
+(u'Patch',u'PatchSize',u'N',0,2147483647,None, None, None, None, u'Size of patch in bytes (long integer).',),
+(u'Patch',u'StreamRef_',u'Y',None, None, None, None, u'Identifier',None, u'Identifier. Foreign key to the StreamRef column of the MsiPatchHeaders table.',),
+(u'PatchPackage',u'Media_',u'N',0,32767,None, None, None, None, u'Foreign key to DiskId column of Media table. Indicates the disk containing the patch package.',),
+(u'PatchPackage',u'PatchId',u'N',None, None, None, None, u'Guid',None, u'A unique string GUID representing this patch.',),
+(u'PublishComponent',u'Feature_',u'N',None, None, u'Feature',1,u'Identifier',None, u'Foreign key into the Feature table.',),
+(u'PublishComponent',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key into the Component table.',),
+(u'PublishComponent',u'ComponentId',u'N',None, None, None, None, u'Guid',None, u'A string GUID that represents the component id that will be requested by the alien product.',),
+(u'PublishComponent',u'AppData',u'Y',None, None, None, None, u'Text',None, u'This is localisable Application specific data that can be associated with a Qualified Component.',),
+(u'PublishComponent',u'Qualifier',u'N',None, None, None, None, u'Text',None, u'This is defined only when the ComponentId column is an Qualified Component Id. This is the Qualifier for ProvideComponentIndirect.',),
+(u'RadioButton',u'Y',u'N',0,32767,None, None, None, None, u'The vertical coordinate of the upper left corner of the bounding rectangle of the radio button.',),
+(u'RadioButton',u'Text',u'Y',None, None, None, None, u'Text',None, u'The visible title to be assigned to the radio button.',),
+(u'RadioButton',u'Property',u'N',None, None, None, None, u'Identifier',None, u'A named property to be tied to this radio button. All the buttons tied to the same property become part of the same group.',),
+(u'RadioButton',u'Height',u'N',0,32767,None, None, None, None, u'The height of the button.',),
+(u'RadioButton',u'Width',u'N',0,32767,None, None, None, None, u'The width of the button.',),
+(u'RadioButton',u'X',u'N',0,32767,None, None, None, None, u'The horizontal coordinate of the upper left corner of the bounding rectangle of the radio button.',),
+(u'RadioButton',u'Value',u'N',None, None, None, None, u'Formatted',None, u'The value string associated with this button. Selecting the button will set the associated property to this value.',),
+(u'RadioButton',u'Order',u'N',1,32767,None, None, None, None, u'A positive integer used to determine the ordering of the items within one list..The integers do not have to be consecutive.',),
+(u'RadioButton',u'Help',u'Y',None, None, None, None, u'Text',None, u'The help strings used with the button. The text is optional.',),
+(u'Registry',u'Name',u'Y',None, None, None, None, u'Formatted',None, u'The registry value name.',),
+(u'Registry',u'Value',u'Y',None, None, None, None, u'Formatted',None, u'The registry value.',),
+(u'Registry',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key into the Component table referencing component that controls the installing of the registry value.',),
+(u'Registry',u'Key',u'N',None, None, None, None, u'RegPath',None, u'The key for the registry value.',),
+(u'Registry',u'Registry',u'N',None, None, None, None, u'Identifier',None, u'Primary key, non-localized token.',),
+(u'Registry',u'Root',u'N',-1,3,None, None, None, None, u'The predefined root key for the registry value, one of rrkEnum.',),
+(u'RegLocator',u'Name',u'Y',None, None, None, None, u'Formatted',None, u'The registry value name.',),
+(u'RegLocator',u'Type',u'Y',0,18,None, None, None, None, u'An integer value that determines if the registry value is a filename or a directory location or to be used as is w/o interpretation.',),
+(u'RegLocator',u'Signature_',u'N',None, None, None, None, u'Identifier',None, u'The table key. The Signature_ represents a unique file signature and is also the foreign key in the Signature table. If the type is 0, the registry values refers a directory, and _Signature is not a foreign key.',),
+(u'RegLocator',u'Key',u'N',None, None, None, None, u'RegPath',None, u'The key for the registry value.',),
+(u'RegLocator',u'Root',u'N',0,3,None, None, None, None, u'The predefined root key for the registry value, one of rrkEnum.',),
+(u'RemoveFile',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key referencing Component that controls the file to be removed.',),
+(u'RemoveFile',u'FileKey',u'N',None, None, None, None, u'Identifier',None, u'Primary key used to identify a particular file entry',),
+(u'RemoveFile',u'FileName',u'Y',None, None, None, None, u'WildCardFilename',None, u'Name of the file to be removed.',),
+(u'RemoveFile',u'DirProperty',u'N',None, None, None, None, u'Identifier',None, u'Name of a property whose value is assumed to resolve to the full pathname to the folder of the file to be removed.',),
+(u'RemoveFile',u'InstallMode',u'N',None, None, None, None, None, u'1;2;3',u'Installation option, one of iimEnum.',),
+(u'RemoveIniFile',u'Action',u'N',None, None, None, None, None, u'2;4',u'The type of modification to be made, one of iifEnum.',),
+(u'RemoveIniFile',u'Value',u'Y',None, None, None, None, u'Formatted',None, u'The value to be deleted. The value is required when Action is iifIniRemoveTag',),
+(u'RemoveIniFile',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key into the Component table referencing component that controls the deletion of the .INI value.',),
+(u'RemoveIniFile',u'FileName',u'N',None, None, None, None, u'Filename',None, u'The .INI file name in which to delete the information',),
+(u'RemoveIniFile',u'DirProperty',u'Y',None, None, None, None, u'Identifier',None, u'Foreign key into the Directory table denoting the directory where the .INI file is.',),
+(u'RemoveIniFile',u'Key',u'N',None, None, None, None, u'Formatted',None, u'The .INI file key below Section.',),
+(u'RemoveIniFile',u'Section',u'N',None, None, None, None, u'Formatted',None, u'The .INI file Section.',),
+(u'RemoveIniFile',u'RemoveIniFile',u'N',None, None, None, None, u'Identifier',None, u'Primary key, non-localized token.',),
+(u'RemoveRegistry',u'Name',u'Y',None, None, None, None, u'Formatted',None, u'The registry value name.',),
+(u'RemoveRegistry',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key into the Component table referencing component that controls the deletion of the registry value.',),
+(u'RemoveRegistry',u'Key',u'N',None, None, None, None, u'RegPath',None, u'The key for the registry value.',),
+(u'RemoveRegistry',u'Root',u'N',-1,3,None, None, None, None, u'The predefined root key for the registry value, one of rrkEnum',),
+(u'RemoveRegistry',u'RemoveRegistry',u'N',None, None, None, None, u'Identifier',None, u'Primary key, non-localized token.',),
+(u'ReserveCost',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Reserve a specified amount of space if this component is to be installed.',),
+(u'ReserveCost',u'ReserveFolder',u'Y',None, None, None, None, u'Identifier',None, u'Name of a property whose value is assumed to resolve to the full path to the destination directory',),
+(u'ReserveCost',u'ReserveKey',u'N',None, None, None, None, u'Identifier',None, u'Primary key that uniquely identifies a particular ReserveCost record',),
+(u'ReserveCost',u'ReserveLocal',u'N',0,2147483647,None, None, None, None, u'Disk space to reserve if linked component is installed locally.',),
+(u'ReserveCost',u'ReserveSource',u'N',0,2147483647,None, None, None, None, u'Disk space to reserve if linked component is installed to run from the source location.',),
+(u'SelfReg',u'File_',u'N',None, None, u'File',1,u'Identifier',None, u'Foreign key into the File table denoting the module that needs to be registered.',),
+(u'SelfReg',u'Cost',u'Y',0,32767,None, None, None, None, u'The cost of registering the module.',),
+(u'ServiceControl',u'Name',u'N',None, None, None, None, u'Formatted',None, u'Name of a service. /, \\, comma and space are invalid',),
+(u'ServiceControl',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Required foreign key into the Component Table that controls the startup of the service',),
+(u'ServiceControl',u'Event',u'N',0,187,None, None, None, None, u'Bit field:  Install:  0x1 = Start, 0x2 = Stop, 0x8 = Delete, Uninstall: 0x10 = Start, 0x20 = Stop, 0x80 = Delete',),
+(u'ServiceControl',u'ServiceControl',u'N',None, None, None, None, u'Identifier',None, u'Primary key, non-localized token.',),
+(u'ServiceControl',u'Arguments',u'Y',None, None, None, None, u'Formatted',None, u'Arguments for the service.  Separate by [~].',),
+(u'ServiceControl',u'Wait',u'Y',0,1,None, None, None, None, u'Boolean for whether to wait for the service to fully start',),
+(u'ServiceInstall',u'Name',u'N',None, None, None, None, u'Formatted',None, u'Internal Name of the Service',),
+(u'ServiceInstall',u'Description',u'Y',None, None, None, None, u'Text',None, u'Description of service.',),
+(u'ServiceInstall',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Required foreign key into the Component Table that controls the startup of the service',),
+(u'ServiceInstall',u'Arguments',u'Y',None, None, None, None, u'Formatted',None, u'Arguments to include in every start of the service, passed to WinMain',),
+(u'ServiceInstall',u'ServiceInstall',u'N',None, None, None, None, u'Identifier',None, u'Primary key, non-localized token.',),
+(u'ServiceInstall',u'Dependencies',u'Y',None, None, None, None, u'Formatted',None, u'Other services this depends on to start.  Separate by [~], and end with [~][~]',),
+(u'ServiceInstall',u'DisplayName',u'Y',None, None, None, None, u'Formatted',None, u'External Name of the Service',),
+(u'ServiceInstall',u'ErrorControl',u'N',-2147483647,2147483647,None, None, None, None, u'Severity of error if service fails to start',),
+(u'ServiceInstall',u'LoadOrderGroup',u'Y',None, None, None, None, u'Formatted',None, u'LoadOrderGroup',),
+(u'ServiceInstall',u'Password',u'Y',None, None, None, None, u'Formatted',None, u'password to run service with.  (with StartName)',),
+(u'ServiceInstall',u'ServiceType',u'N',-2147483647,2147483647,None, None, None, None, u'Type of the service',),
+(u'ServiceInstall',u'StartName',u'Y',None, None, None, None, u'Formatted',None, u'User or object name to run service as',),
+(u'ServiceInstall',u'StartType',u'N',0,4,None, None, None, None, u'Type of the service',),
+(u'Shortcut',u'Name',u'N',None, None, None, None, u'Filename',None, u'The name of the shortcut to be created.',),
+(u'Shortcut',u'Description',u'Y',None, None, None, None, u'Text',None, u'The description for the shortcut.',),
+(u'Shortcut',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key into the Component table denoting the component whose selection gates the the shortcut creation/deletion.',),
+(u'Shortcut',u'Icon_',u'Y',None, None, u'Icon',1,u'Identifier',None, u'Foreign key into the File table denoting the external icon file for the shortcut.',),
+(u'Shortcut',u'IconIndex',u'Y',-32767,32767,None, None, None, None, u'The icon index for the shortcut.',),
+(u'Shortcut',u'Directory_',u'N',None, None, u'Directory',1,u'Identifier',None, u'Foreign key into the Directory table denoting the directory where the shortcut file is created.',),
+(u'Shortcut',u'Target',u'N',None, None, None, None, u'Shortcut',None, u'The shortcut target. This is usually a property that is expanded to a file or a folder that the shortcut points to.',),
+(u'Shortcut',u'Arguments',u'Y',None, None, None, None, u'Formatted',None, u'The command-line arguments for the shortcut.',),
+(u'Shortcut',u'Shortcut',u'N',None, None, None, None, u'Identifier',None, u'Primary key, non-localized token.',),
+(u'Shortcut',u'Hotkey',u'Y',0,32767,None, None, None, None, u'The hotkey for the shortcut. It has the virtual-key code for the key in the low-order byte, and the modifier flags in the high-order byte. ',),
+(u'Shortcut',u'ShowCmd',u'Y',None, None, None, None, None, u'1;3;7',u'The show command for the application window.The following values may be used.',),
+(u'Shortcut',u'WkDir',u'Y',None, None, None, None, u'Identifier',None, u'Name of property defining location of working directory.',),
+(u'Signature',u'FileName',u'N',None, None, None, None, u'Filename',None, u'The name of the file. This may contain a "short name|long name" pair.',),
+(u'Signature',u'Signature',u'N',None, None, None, None, u'Identifier',None, u'The table key. The Signature represents a unique file signature.',),
+(u'Signature',u'Languages',u'Y',None, None, None, None, u'Language',None, u'The languages supported by the file.',),
+(u'Signature',u'MaxDate',u'Y',0,2147483647,None, None, None, None, u'The maximum creation date of the file.',),
+(u'Signature',u'MaxSize',u'Y',0,2147483647,None, None, None, None, u'The maximum size of the file. ',),
+(u'Signature',u'MaxVersion',u'Y',None, None, None, None, u'Text',None, u'The maximum version of the file.',),
+(u'Signature',u'MinDate',u'Y',0,2147483647,None, None, None, None, u'The minimum creation date of the file.',),
+(u'Signature',u'MinSize',u'Y',0,2147483647,None, None, None, None, u'The minimum size of the file.',),
+(u'Signature',u'MinVersion',u'Y',None, None, None, None, u'Text',None, u'The minimum version of the file.',),
+(u'TextStyle',u'TextStyle',u'N',None, None, None, None, u'Identifier',None, u'Name of the style. The primary key of this table. This name is embedded in the texts to indicate a style change.',),
+(u'TextStyle',u'Color',u'Y',0,16777215,None, None, None, None, u'A long integer indicating the color of the string in the RGB format (Red, Green, Blue each 0-255, RGB = R + 256*G + 256^2*B).',),
+(u'TextStyle',u'FaceName',u'N',None, None, None, None, u'Text',None, u'A string indicating the name of the font used. Required. The string must be at most 31 characters long.',),
+(u'TextStyle',u'Size',u'N',0,32767,None, None, None, None, u'The size of the font used. This size is given in our units (1/12 of the system font height). Assuming that the system font is set to 12 point size, this is equivalent to the point size.',),
+(u'TextStyle',u'StyleBits',u'Y',0,15,None, None, None, None, u'A combination of style bits.',),
+(u'TypeLib',u'Description',u'Y',None, None, None, None, u'Text',None, None, ),
+(u'TypeLib',u'Feature_',u'N',None, None, u'Feature',1,u'Identifier',None, u'Required foreign key into the Feature Table, specifying the feature to validate or install in order for the type library to be operational.',),
+(u'TypeLib',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Required foreign key into the Component Table, specifying the component for which to return a path when called through LocateComponent.',),
+(u'TypeLib',u'Directory_',u'Y',None, None, u'Directory',1,u'Identifier',None, u'Optional. The foreign key into the Directory table denoting the path to the help file for the type library.',),
+(u'TypeLib',u'Language',u'N',0,32767,None, None, None, None, u'The language of the library.',),
+(u'TypeLib',u'Version',u'Y',0,16777215,None, None, None, None, u'The version of the library. The minor version is in the lower 8 bits of the integer. The major version is in the next 16 bits. ',),
+(u'TypeLib',u'Cost',u'Y',0,2147483647,None, None, None, None, u'The cost associated with the registration of the typelib. This column is currently optional.',),
+(u'TypeLib',u'LibID',u'N',None, None, None, None, u'Guid',None, u'The GUID that represents the library.',),
+(u'UIText',u'Text',u'Y',None, None, None, None, u'Text',None, u'The localized version of the string.',),
+(u'UIText',u'Key',u'N',None, None, None, None, u'Identifier',None, u'A unique key that identifies the particular string.',),
+(u'Upgrade',u'Attributes',u'N',0,2147483647,None, None, None, None, u'The attributes of this product set.',),
+(u'Upgrade',u'Language',u'Y',None, None, None, None, u'Language',None, u'A comma-separated list of languages for either products in this set or products not in this set.',),
+(u'Upgrade',u'ActionProperty',u'N',None, None, None, None, u'UpperCase',None, u'The property to set when a product in this set is found.',),
+(u'Upgrade',u'Remove',u'Y',None, None, None, None, u'Formatted',None, u'The list of features to remove when uninstalling a product from this set.  The default is "ALL".',),
+(u'Upgrade',u'UpgradeCode',u'N',None, None, None, None, u'Guid',None, u'The UpgradeCode GUID belonging to the products in this set.',),
+(u'Upgrade',u'VersionMax',u'Y',None, None, None, None, u'Text',None, u'The maximum ProductVersion of the products in this set.  The set may or may not include products with this particular version.',),
+(u'Upgrade',u'VersionMin',u'Y',None, None, None, None, u'Text',None, u'The minimum ProductVersion of the products in this set.  The set may or may not include products with this particular version.',),
+(u'Verb',u'Sequence',u'Y',0,32767,None, None, None, None, u'Order within the verbs for a particular extension. Also used simply to specify the default verb.',),
+(u'Verb',u'Argument',u'Y',None, None, None, None, u'Formatted',None, u'Optional value for the command arguments.',),
+(u'Verb',u'Extension_',u'N',None, None, u'Extension',1,u'Text',None, u'The extension associated with the table row.',),
+(u'Verb',u'Verb',u'N',None, None, None, None, u'Text',None, u'The verb for the command.',),
+(u'Verb',u'Command',u'Y',None, None, None, None, u'Formatted',None, u'The command text.',),
+]

Added: vendor/Python/current/Tools/msi/sequence.py
===================================================================
--- vendor/Python/current/Tools/msi/sequence.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/msi/sequence.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,126 @@
+AdminExecuteSequence = [
+(u'InstallInitialize', None, 1500),
+(u'InstallFinalize', None, 6600),
+(u'InstallFiles', None, 4000),
+(u'InstallAdminPackage', None, 3900),
+(u'FileCost', None, 900),
+(u'CostInitialize', None, 800),
+(u'CostFinalize', None, 1000),
+(u'InstallValidate', None, 1400),
+]
+
+AdminUISequence = [
+(u'FileCost', None, 900),
+(u'CostInitialize', None, 800),
+(u'CostFinalize', None, 1000),
+(u'ExecuteAction', None, 1300),
+(u'ExitDialog', None, -1),
+(u'FatalError', None, -3),
+(u'UserExit', None, -2),
+]
+
+AdvtExecuteSequence = [
+(u'InstallInitialize', None, 1500),
+(u'InstallFinalize', None, 6600),
+(u'CostInitialize', None, 800),
+(u'CostFinalize', None, 1000),
+(u'InstallValidate', None, 1400),
+(u'CreateShortcuts', None, 4500),
+(u'MsiPublishAssemblies', None, 6250),
+(u'PublishComponents', None, 6200),
+(u'PublishFeatures', None, 6300),
+(u'PublishProduct', None, 6400),
+(u'RegisterClassInfo', None, 4600),
+(u'RegisterExtensionInfo', None, 4700),
+(u'RegisterMIMEInfo', None, 4900),
+(u'RegisterProgIdInfo', None, 4800),
+]
+
+InstallExecuteSequence = [
+(u'InstallInitialize', None, 1500),
+(u'InstallFinalize', None, 6600),
+(u'InstallFiles', None, 4000),
+(u'FileCost', None, 900),
+(u'CostInitialize', None, 800),
+(u'CostFinalize', None, 1000),
+(u'InstallValidate', None, 1400),
+(u'CreateShortcuts', None, 4500),
+(u'MsiPublishAssemblies', None, 6250),
+(u'PublishComponents', None, 6200),
+(u'PublishFeatures', None, 6300),
+(u'PublishProduct', None, 6400),
+(u'RegisterClassInfo', None, 4600),
+(u'RegisterExtensionInfo', None, 4700),
+(u'RegisterMIMEInfo', None, 4900),
+(u'RegisterProgIdInfo', None, 4800),
+(u'AllocateRegistrySpace', u'NOT Installed', 1550),
+(u'AppSearch', None, 400),
+(u'BindImage', None, 4300),
+(u'CCPSearch', u'NOT Installed', 500),
+(u'CreateFolders', None, 3700),
+(u'DeleteServices', u'VersionNT', 2000),
+(u'DuplicateFiles', None, 4210),
+(u'FindRelatedProducts', None, 200),
+(u'InstallODBC', None, 5400),
+(u'InstallServices', u'VersionNT', 5800),
+(u'IsolateComponents', None, 950),
+(u'LaunchConditions', None, 100),
+(u'MigrateFeatureStates', None, 1200),
+(u'MoveFiles', None, 3800),
+(u'PatchFiles', None, 4090),
+(u'ProcessComponents', None, 1600),
+(u'RegisterComPlus', None, 5700),
+(u'RegisterFonts', None, 5300),
+(u'RegisterProduct', None, 6100),
+(u'RegisterTypeLibraries', None, 5500),
+(u'RegisterUser', None, 6000),
+(u'RemoveDuplicateFiles', None, 3400),
+(u'RemoveEnvironmentStrings', None, 3300),
+(u'RemoveExistingProducts', None, 6700),
+(u'RemoveFiles', None, 3500),
+(u'RemoveFolders', None, 3600),
+(u'RemoveIniValues', None, 3100),
+(u'RemoveODBC', None, 2400),
+(u'RemoveRegistryValues', None, 2600),
+(u'RemoveShortcuts', None, 3200),
+(u'RMCCPSearch', u'NOT Installed', 600),
+(u'SelfRegModules', None, 5600),
+(u'SelfUnregModules', None, 2200),
+(u'SetODBCFolders', None, 1100),
+(u'StartServices', u'VersionNT', 5900),
+(u'StopServices', u'VersionNT', 1900),
+(u'MsiUnpublishAssemblies', None, 1750),
+(u'UnpublishComponents', None, 1700),
+(u'UnpublishFeatures', None, 1800),
+(u'UnregisterClassInfo', None, 2700),
+(u'UnregisterComPlus', None, 2100),
+(u'UnregisterExtensionInfo', None, 2800),
+(u'UnregisterFonts', None, 2500),
+(u'UnregisterMIMEInfo', None, 3000),
+(u'UnregisterProgIdInfo', None, 2900),
+(u'UnregisterTypeLibraries', None, 2300),
+(u'ValidateProductID', None, 700),
+(u'WriteEnvironmentStrings', None, 5200),
+(u'WriteIniValues', None, 5100),
+(u'WriteRegistryValues', None, 5000),
+]
+
+InstallUISequence = [
+(u'FileCost', None, 900),
+(u'CostInitialize', None, 800),
+(u'CostFinalize', None, 1000),
+(u'ExecuteAction', None, 1300),
+(u'ExitDialog', None, -1),
+(u'FatalError', None, -3),
+(u'UserExit', None, -2),
+(u'AppSearch', None, 400),
+(u'CCPSearch', u'NOT Installed', 500),
+(u'FindRelatedProducts', None, 200),
+(u'IsolateComponents', None, 950),
+(u'LaunchConditions', None, 100),
+(u'MigrateFeatureStates', None, 1200),
+(u'RMCCPSearch', u'NOT Installed', 600),
+(u'ValidateProductID', None, 700),
+]
+
+tables=['AdminExecuteSequence', 'AdminUISequence', 'AdvtExecuteSequence', 'InstallExecuteSequence', 'InstallUISequence']

Added: vendor/Python/current/Tools/msi/uisample.py
===================================================================
--- vendor/Python/current/Tools/msi/uisample.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/msi/uisample.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1400 @@
+
+import msilib,os;dirname=os.path.dirname(__file__)
+AdminExecuteSequence = [
+(u'InstallValidate', None, 1400),
+(u'InstallInitialize', None, 1500),
+(u'InstallFinalize', None, 6600),
+(u'InstallFiles', None, 4000),
+(u'InstallAdminPackage', None, 3900),
+(u'FileCost', None, 900),
+(u'CostInitialize', None, 800),
+(u'CostFinalize', None, 1000),
+]
+
+AdminUISequence = [
+(u'AdminWelcomeDlg', None, 1230),
+(u'FileCost', None, 900),
+(u'CostInitialize', None, 800),
+(u'CostFinalize', None, 1000),
+(u'ExecuteAction', None, 1300),
+(u'ExitDialog', None, -1),
+(u'FatalError', None, -3),
+(u'PrepareDlg', None, 140),
+(u'ProgressDlg', None, 1280),
+(u'UserExit', None, -2),
+]
+
+AdvtExecuteSequence = [
+(u'InstallValidate', None, 1400),
+(u'InstallInitialize', None, 1500),
+(u'InstallFinalize', None, 6600),
+(u'CostInitialize', None, 800),
+(u'CostFinalize', None, 1000),
+(u'CreateShortcuts', None, 4500),
+(u'PublishComponents', None, 6200),
+(u'PublishFeatures', None, 6300),
+(u'PublishProduct', None, 6400),
+(u'RegisterClassInfo', None, 4600),
+(u'RegisterExtensionInfo', None, 4700),
+(u'RegisterMIMEInfo', None, 4900),
+(u'RegisterProgIdInfo', None, 4800),
+]
+
+BBControl = [
+]
+
+Billboard = [
+]
+
+Binary = [
+(u'bannrbmp', msilib.Binary(os.path.join(dirname,"bannrbmp.bin"))),
+(u'completi', msilib.Binary(os.path.join(dirname,"completi.bin"))),
+(u'custicon', msilib.Binary(os.path.join(dirname,"custicon.bin"))),
+(u'dlgbmp', msilib.Binary(os.path.join(dirname,"dlgbmp.bin"))),
+(u'exclamic', msilib.Binary(os.path.join(dirname,"exclamic.bin"))),
+(u'info', msilib.Binary(os.path.join(dirname,"info.bin"))),
+(u'insticon', msilib.Binary(os.path.join(dirname,"insticon.bin"))),
+(u'New', msilib.Binary(os.path.join(dirname,"New.bin"))),
+(u'removico', msilib.Binary(os.path.join(dirname,"removico.bin"))),
+(u'repairic', msilib.Binary(os.path.join(dirname,"repairic.bin"))),
+(u'Up', msilib.Binary(os.path.join(dirname,"Up.bin"))),
+]
+
+CheckBox = [
+]
+
+Property = [
+(u'BannerBitmap', u'bannrbmp'),
+(u'IAgree', u'No'),
+(u'ProductID', u'none'),
+(u'ARPHELPLINK', u'http://www.microsoft.com/management'),
+(u'ButtonText_Back', u'< &Back'),
+(u'ButtonText_Browse', u'Br&owse'),
+(u'ButtonText_Cancel', u'Cancel'),
+(u'ButtonText_Exit', u'&Exit'),
+(u'ButtonText_Finish', u'&Finish'),
+(u'ButtonText_Ignore', u'&Ignore'),
+(u'ButtonText_Install', u'&Install'),
+(u'ButtonText_Next', u'&Next >'),
+(u'ButtonText_No', u'&No'),
+(u'ButtonText_OK', u'OK'),
+(u'ButtonText_Remove', u'&Remove'),
+(u'ButtonText_Repair', u'&Repair'),
+(u'ButtonText_Reset', u'&Reset'),
+(u'ButtonText_Resume', u'&Resume'),
+(u'ButtonText_Retry', u'&Retry'),
+(u'ButtonText_Return', u'&Return'),
+(u'ButtonText_Yes', u'&Yes'),
+(u'CompleteSetupIcon', u'completi'),
+(u'ComponentDownload', u'ftp://anonymous@microsoft.com/components/'),
+(u'CustomSetupIcon', u'custicon'),
+(u'DefaultUIFont', u'DlgFont8'),
+(u'DialogBitmap', u'dlgbmp'),
+(u'DlgTitleFont', u'{&DlgFontBold8}'),
+(u'ErrorDialog', u'ErrorDlg'),
+(u'ExclamationIcon', u'exclamic'),
+(u'InfoIcon', u'info'),
+(u'InstallerIcon', u'insticon'),
+(u'INSTALLLEVEL', u'3'),
+(u'InstallMode', u'Typical'),
+(u'PIDTemplate', u'12345<###-%%%%%%%>@@@@@'),
+#(u'ProductLanguage', u'1033'),
+(u'Progress1', u'Installing'),
+(u'Progress2', u'installs'),
+(u'PROMPTROLLBACKCOST', u'P'),
+(u'RemoveIcon', u'removico'),
+(u'RepairIcon', u'repairic'),
+(u'Setup', u'Setup'),
+(u'ShowUserRegistrationDlg', u'1'),
+(u'Wizard', u'Setup Wizard'),
+]
+
+ComboBox = [
+]
+
+Control = [
+(u'AdminWelcomeDlg', u'Bitmap', u'Bitmap', 0, 0, 370, 234, 1, None, u'[DialogBitmap]', u'Back', None),
+(u'AdminWelcomeDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None),
+(u'AdminWelcomeDlg', u'Cancel', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'Bitmap', None),
+(u'AdminWelcomeDlg', u'Description', u'Text', 135, 70, 220, 30, 196611, None, u'The [Wizard] will create a server image of [ProductName], at a specified network location.  Click Next to continue or Cancel to exit the [Wizard].', None, None),
+(u'AdminWelcomeDlg', u'Title', u'Text', 135, 20, 220, 60, 196611, None, u'{\\VerdanaBold13}Welcome to the [ProductName] [Wizard]', None, None),
+(u'AdminWelcomeDlg', u'Back', u'PushButton', 180, 243, 56, 17, 1, None, u'[ButtonText_Back]', u'Next', None),
+(u'AdminWelcomeDlg', u'Next', u'PushButton', 236, 243, 56, 17, 3, None, u'[ButtonText_Next]', u'Cancel', None),
+(u'ExitDialog', u'Bitmap', u'Bitmap', 0, 0, 370, 234, 1, None, u'[DialogBitmap]', u'Back', None),
+(u'ExitDialog', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None),
+(u'ExitDialog', u'Cancel', u'PushButton', 304, 243, 56, 17, 1, None, u'[ButtonText_Cancel]', u'Bitmap', None),
+(u'ExitDialog', u'Description', u'Text', 135, 70, 220, 20, 196611, None, u'Click the Finish button to exit the [Wizard].', None, None),
+(u'ExitDialog', u'Title', u'Text', 135, 20, 220, 60, 196611, None, u'{\\VerdanaBold13}Completing the [ProductName] [Wizard]', None, None),
+(u'ExitDialog', u'Back', u'PushButton', 180, 243, 56, 17, 1, None, u'[ButtonText_Back]', u'Finish', None),
+(u'ExitDialog', u'Finish', u'PushButton', 236, 243, 56, 17, 3, None, u'[ButtonText_Finish]', u'Cancel', None),
+(u'FatalError', u'Bitmap', u'Bitmap', 0, 0, 370, 234, 1, None, u'[DialogBitmap]', u'Back', None),
+(u'FatalError', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None),
+(u'FatalError', u'Cancel', u'PushButton', 304, 243, 56, 17, 1, None, u'[ButtonText_Cancel]', u'Bitmap', None),
+(u'FatalError', u'Title', u'Text', 135, 20, 220, 60, 196611, None, u'{\\VerdanaBold13}[ProductName] [Wizard] ended prematurely', None, None),
+(u'FatalError', u'Back', u'PushButton', 180, 243, 56, 17, 1, None, u'[ButtonText_Back]', u'Finish', None),
+(u'FatalError', u'Finish', u'PushButton', 236, 243, 56, 17, 3, None, u'[ButtonText_Finish]', u'Cancel', None),
+(u'FatalError', u'Description1', u'Text', 135, 70, 220, 40, 196611, None, u'[ProductName] setup ended prematurely because of an error.  Your system has not been modified.  To install this program at a later time, please run the installation again.', None, None),
+(u'FatalError', u'Description2', u'Text', 135, 115, 220, 20, 196611, None, u'Click the Finish button to exit the [Wizard].', None, None),
+(u'PrepareDlg', u'Bitmap', u'Bitmap', 0, 0, 370, 234, 1, None, u'[DialogBitmap]', u'Cancel', None),
+(u'PrepareDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None),
+(u'PrepareDlg', u'Cancel', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'Bitmap', None),
+(u'PrepareDlg', u'Description', u'Text', 135, 70, 220, 20, 196611, None, u'Please wait while the [Wizard] prepares to guide you through the installation.', None, None),
+(u'PrepareDlg', u'Title', u'Text', 135, 20, 220, 60, 196611, None, u'{\\VerdanaBold13}Welcome to the [ProductName] [Wizard]', None, None),
+(u'PrepareDlg', u'Back', u'PushButton', 180, 243, 56, 17, 1, None, u'[ButtonText_Back]', None, None),
+(u'PrepareDlg', u'Next', u'PushButton', 236, 243, 56, 17, 1, None, u'[ButtonText_Next]', None, None),
+(u'PrepareDlg', u'ActionData', u'Text', 135, 125, 220, 30, 196611, None, None, None, None),
+(u'PrepareDlg', u'ActionText', u'Text', 135, 100, 220, 20, 196611, None, None, None, None),
+(u'ProgressDlg', u'Text', u'Text', 35, 65, 300, 20, 3, None, u'Please wait while the [Wizard] [Progress2] [ProductName].  This may take several minutes.', None, None),
+(u'ProgressDlg', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'Back', None),
+(u'ProgressDlg', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None),
+(u'ProgressDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None),
+(u'ProgressDlg', u'Cancel', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'BannerBitmap', None),
+(u'ProgressDlg', u'Title', u'Text', 20, 15, 200, 15, 196611, None, u'[DlgTitleFont][Progress1] [ProductName]', None, None),
+(u'ProgressDlg', u'Back', u'PushButton', 180, 243, 56, 17, 1, None, u'[ButtonText_Back]', u'Next', None),
+(u'ProgressDlg', u'Next', u'PushButton', 236, 243, 56, 17, 1, None, u'[ButtonText_Next]', u'Cancel', None),
+(u'ProgressDlg', u'ActionText', u'Text', 70, 100, 265, 10, 3, None, None, None, None),
+(u'ProgressDlg', u'ProgressBar', u'ProgressBar', 35, 115, 300, 10, 65537, None, u'Progress done', None, None),
+(u'ProgressDlg', u'StatusLabel', u'Text', 35, 100, 35, 10, 3, None, u'Status:', None, None),
+(u'UserExit', u'Bitmap', u'Bitmap', 0, 0, 370, 234, 1, None, u'[DialogBitmap]', u'Back', None),
+(u'UserExit', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None),
+(u'UserExit', u'Cancel', u'PushButton', 304, 243, 56, 17, 1, None, u'[ButtonText_Cancel]', u'Bitmap', None),
+(u'UserExit', u'Title', u'Text', 135, 20, 220, 60, 196611, None, u'{\\VerdanaBold13}[ProductName] [Wizard] was interrupted', None, None),
+(u'UserExit', u'Back', u'PushButton', 180, 243, 56, 17, 1, None, u'[ButtonText_Back]', u'Finish', None),
+(u'UserExit', u'Finish', u'PushButton', 236, 243, 56, 17, 3, None, u'[ButtonText_Finish]', u'Cancel', None),
+(u'UserExit', u'Description1', u'Text', 135, 70, 220, 40, 196611, None, u'[ProductName] setup was interrupted.  Your system has not been modified.  To install this program at a later time, please run the installation again.', None, None),
+(u'UserExit', u'Description2', u'Text', 135, 115, 220, 20, 196611, None, u'Click the Finish button to exit the [Wizard].', None, None),
+(u'AdminBrowseDlg', u'Up', u'PushButton', 298, 55, 19, 19, 3670019, None, u'Up', u'NewFolder', u'Up One Level|'),
+(u'AdminBrowseDlg', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'PathEdit', None),
+(u'AdminBrowseDlg', u'PathEdit', u'PathEdit', 84, 202, 261, 17, 3, u'TARGETDIR', None, u'OK', None),
+(u'AdminBrowseDlg', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None),
+(u'AdminBrowseDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None),
+(u'AdminBrowseDlg', u'Cancel', u'PushButton', 240, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'ComboLabel', None),
+(u'AdminBrowseDlg', u'ComboLabel', u'Text', 25, 58, 44, 10, 3, None, u'&Look in:', u'DirectoryCombo', None),
+(u'AdminBrowseDlg', u'DirectoryCombo', u'DirectoryCombo', 70, 55, 220, 80, 458755, u'TARGETDIR', None, u'Up', None),
+(u'AdminBrowseDlg', u'Description', u'Text', 25, 23, 280, 15, 196611, None, u'Browse to the destination folder', None, None),
+(u'AdminBrowseDlg', u'DirectoryList', u'DirectoryList', 25, 83, 320, 110, 7, u'TARGETDIR', None, u'PathLabel', None),
+(u'AdminBrowseDlg', u'PathLabel', u'Text', 25, 205, 59, 10, 3, None, u'&Folder name:', u'BannerBitmap', None),
+(u'AdminBrowseDlg', u'NewFolder', u'PushButton', 325, 55, 19, 19, 3670019, None, u'New', u'DirectoryList', u'Create A New Folder|'),
+(u'AdminBrowseDlg', u'OK', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_OK]', u'Cancel', None),
+(u'AdminBrowseDlg', u'Title', u'Text', 15, 6, 200, 15, 196611, None, u'[DlgTitleFont]Change current destination folder', None, None),
+(u'AdminInstallPointDlg', u'Text', u'Text', 25, 80, 320, 10, 3, None, u'&Enter a new network location or click Browse to browse to one.', u'PathEdit', None),
+(u'AdminInstallPointDlg', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'Text', None),
+(u'AdminInstallPointDlg', u'PathEdit', u'PathEdit', 25, 93, 320, 18, 3, u'TARGETDIR', None, u'Browse', None),
+(u'AdminInstallPointDlg', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None),
+(u'AdminInstallPointDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None),
+(u'AdminInstallPointDlg', u'Cancel', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'BannerBitmap', None),
+(u'AdminInstallPointDlg', u'Description', u'Text', 25, 20, 280, 20, 196611, None, u'Please specify a network location for the server image of [ProductName] product', None, None),
+(u'AdminInstallPointDlg', u'Title', u'Text', 15, 6, 200, 15, 196611, None, u'[DlgTitleFont]Network Location', None, None),
+(u'AdminInstallPointDlg', u'Back', u'PushButton', 180, 243, 56, 17, 3, None, u'[ButtonText_Back]', u'Next', None),
+(u'AdminInstallPointDlg', u'Next', u'PushButton', 236, 243, 56, 17, 3, None, u'[ButtonText_Next]', u'Cancel', None),
+(u'AdminInstallPointDlg', u'Browse', u'PushButton', 289, 119, 56, 17, 3, None, u'[ButtonText_Browse]', u'Back', None),
+(u'AdminRegistrationDlg', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'OrganizationLabel', None),
+(u'AdminRegistrationDlg', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None),
+(u'AdminRegistrationDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None),
+(u'AdminRegistrationDlg', u'Cancel', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'BannerBitmap', None),
+(u'AdminRegistrationDlg', u'Description', u'Text', 25, 23, 280, 15, 196611, None, u'Please enter your company information', None, None),
+(u'AdminRegistrationDlg', u'Title', u'Text', 15, 6, 200, 15, 196611, None, u'[DlgTitleFont]Company Information', None, None),
+(u'AdminRegistrationDlg', u'Back', u'PushButton', 180, 243, 56, 17, 65539, None, u'[ButtonText_Back]', u'Next', None),
+(u'AdminRegistrationDlg', u'Next', u'PushButton', 236, 243, 56, 17, 3, None, u'[ButtonText_Next]', u'Cancel', None),
+(u'AdminRegistrationDlg', u'OrganizationLabel', u'Text', 45, 71, 285, 30, 3, None, u'&Please enter the name of your organization in the box below.  This will be used as default company name for subsequent installations of [ProductName]:', u'OrganizationEdit', None),
+(u'AdminRegistrationDlg', u'CDKeyEdit', u'MaskedEdit', 45, 143, 250, 16, 3, u'PIDKEY', u'[PIDTemplate]', u'Back', None),
+(u'AdminRegistrationDlg', u'CDKeyLabel', u'Text', 45, 130, 50, 10, 3, None, u'CD &Key:', u'CDKeyEdit', None),
+(u'AdminRegistrationDlg', u'OrganizationEdit', u'Edit', 45, 105, 220, 18, 3, u'COMPANYNAME', u'{80}', u'CDKeyLabel', None),
+(u'BrowseDlg', u'Up', u'PushButton', 298, 55, 19, 19, 3670019, None, u'Up', u'NewFolder', u'Up One Level|'),
+(u'BrowseDlg', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'PathEdit', None),
+(u'BrowseDlg', u'PathEdit', u'PathEdit', 84, 202, 261, 18, 11, u'_BrowseProperty', None, u'OK', None),
+(u'BrowseDlg', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None),
+(u'BrowseDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None),
+(u'BrowseDlg', u'Cancel', u'PushButton', 240, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'ComboLabel', None),
+(u'BrowseDlg', u'ComboLabel', u'Text', 25, 58, 44, 10, 3, None, u'&Look in:', u'DirectoryCombo', None),
+(u'BrowseDlg', u'DirectoryCombo', u'DirectoryCombo', 70, 55, 220, 80, 393227, u'_BrowseProperty', None, u'Up', None),
+(u'BrowseDlg', u'Description', u'Text', 25, 23, 280, 15, 196611, None, u'Browse to the destination folder', None, None),
+(u'BrowseDlg', u'DirectoryList', u'DirectoryList', 25, 83, 320, 110, 15, u'_BrowseProperty', None, u'PathLabel', None),
+(u'BrowseDlg', u'PathLabel', u'Text', 25, 205, 59, 10, 3, None, u'&Folder name:', u'BannerBitmap', None),
+(u'BrowseDlg', u'NewFolder', u'PushButton', 325, 55, 19, 19, 3670019, None, u'New', u'DirectoryList', u'Create A New Folder|'),
+(u'BrowseDlg', u'OK', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_OK]', u'Cancel', None),
+(u'BrowseDlg', u'Title', u'Text', 15, 6, 200, 15, 196611, None, u'[DlgTitleFont]Change current destination folder', None, None),
+(u'CancelDlg', u'Text', u'Text', 48, 15, 194, 30, 3, None, u'Are you sure you want to cancel [ProductName] installation?', None, None),
+(u'CancelDlg', u'Icon', u'Icon', 15, 15, 24, 24, 5242881, None, u'[InfoIcon]', None, u'Information icon|'),
+(u'CancelDlg', u'No', u'PushButton', 132, 57, 56, 17, 3, None, u'[ButtonText_No]', u'Yes', None),
+(u'CancelDlg', u'Yes', u'PushButton', 72, 57, 56, 17, 3, None, u'[ButtonText_Yes]', u'No', None),
+(u'CustomizeDlg', u'Text', u'Text', 25, 55, 320, 20, 3, None, u'Click on the icons in the tree below to change the way features will be installed.', None, None),
+(u'CustomizeDlg', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'Tree', None),
+(u'CustomizeDlg', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None),
+(u'CustomizeDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None),
+(u'CustomizeDlg', u'Cancel', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'BannerBitmap', None),
+(u'CustomizeDlg', u'Description', u'Text', 25, 23, 280, 15, 196611, None, u'Select the way you want features to be installed.', None, None),
+(u'CustomizeDlg', u'Title', u'Text', 15, 6, 200, 15, 196611, None, u'[DlgTitleFont]Custom Setup', None, None),
+(u'CustomizeDlg', u'Back', u'PushButton', 180, 243, 56, 17, 3, None, u'[ButtonText_Back]', u'Next', None),
+(u'CustomizeDlg', u'Next', u'PushButton', 236, 243, 56, 17, 3, None, u'[ButtonText_Next]', u'Cancel', None),
+(u'CustomizeDlg', u'Browse', u'PushButton', 304, 200, 56, 17, 3, None, u'[ButtonText_Browse]', u'Reset', None),
+(u'CustomizeDlg', u'Tree', u'SelectionTree', 25, 85, 175, 95, 7, u'_BrowseProperty', u'Tree of selections', u'Browse', None),
+(u'CustomizeDlg', u'Box', u'GroupBox', 210, 81, 140, 98, 1, None, None, None, None),
+(u'CustomizeDlg', u'Reset', u'PushButton', 42, 243, 56, 17, 3, None, u'[ButtonText_Reset]', u'DiskCost', None),
+(u'CustomizeDlg', u'DiskCost', u'PushButton', 111, 243, 56, 17, 3, None, u'Disk &Usage', u'Back', None),
+(u'CustomizeDlg', u'ItemDescription', u'Text', 215, 90, 131, 30, 3, None, u'Multiline description of the currently selected item.', None, None),
+(u'CustomizeDlg', u'ItemSize', u'Text', 215, 130, 131, 45, 3, None, u'The size of the currently selected item.', None, None),
+(u'CustomizeDlg', u'Location', u'Text', 75, 200, 215, 20, 3, None, u"<The selection's path>", None, None),
+(u'CustomizeDlg', u'LocationLabel', u'Text', 25, 200, 50, 10, 3, None, u'Location:', None, None),
+(u'DiskCostDlg', u'Text', u'Text', 20, 53, 330, 40, 3, None, u'The highlighted volumes (if any) do not have enough disk space available for the currently selected features.  You can either remove some files from the highlighted volumes, or choose to install less features onto local drive(s), or select different destination drive(s).', None, None),
+(u'DiskCostDlg', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'OK', None),
+(u'DiskCostDlg', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None),
+(u'DiskCostDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None),
+(u'DiskCostDlg', u'Description', u'Text', 20, 20, 280, 20, 196611, None, u'The disk space required for the installation of the selected features.', None, None),
+(u'DiskCostDlg', u'OK', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_OK]', u'BannerBitmap', None),
+(u'DiskCostDlg', u'Title', u'Text', 15, 6, 200, 15, 196611, None, u'[DlgTitleFont]Disk Space Requirements', None, None),
+(u'DiskCostDlg', u'VolumeList', u'VolumeCostList', 20, 100, 330, 120, 393223, None, u'{120}{70}{70}{70}{70}', None, None),
+(u'ErrorDlg', u'Y', u'PushButton', 100, 80, 56, 17, 3, None, u'[ButtonText_Yes]', None, None),
+(u'ErrorDlg', u'A', u'PushButton', 100, 80, 56, 17, 3, None, u'[ButtonText_Cancel]', None, None),
+(u'ErrorDlg', u'C', u'PushButton', 100, 80, 56, 17, 3, None, u'[ButtonText_Cancel]', None, None),
+(u'ErrorDlg', u'ErrorIcon', u'Icon', 15, 15, 24, 24, 5242881, None, u'[InfoIcon]', None, u'Information icon|'),
+(u'ErrorDlg', u'ErrorText', u'Text', 48, 15, 205, 60, 3, None, u'Information text', None, None),
+(u'ErrorDlg', u'I', u'PushButton', 100, 80, 56, 17, 3, None, u'[ButtonText_Ignore]', None, None),
+(u'ErrorDlg', u'N', u'PushButton', 100, 80, 56, 17, 3, None, u'[ButtonText_No]', None, None),
+(u'ErrorDlg', u'O', u'PushButton', 100, 80, 56, 17, 3, None, u'[ButtonText_OK]', None, None),
+(u'ErrorDlg', u'R', u'PushButton', 100, 80, 56, 17, 3, None, u'[ButtonText_Retry]', None, None),
+(u'FilesInUse', u'Text', u'Text', 20, 55, 330, 30, 3, None, u'The following applications are using files that need to be updated by this setup. Close these applications and then click Retry to continue the installation or Cancel to exit it.', None, None),
+(u'FilesInUse', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'Retry', None),
+(u'FilesInUse', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None),
+(u'FilesInUse', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None),
+(u'FilesInUse', u'Description', u'Text', 20, 23, 280, 20, 196611, None, u'Some files that need to be updated are currently in use.', None, None),
+(u'FilesInUse', u'Title', u'Text', 15, 6, 200, 15, 196611, None, u'[DlgTitleFont]Files in Use', None, None),
+(u'FilesInUse', u'Retry', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Retry]', u'Ignore', None),
+(u'FilesInUse', u'Exit', u'PushButton', 166, 243, 56, 17, 3, None, u'[ButtonText_Exit]', u'BannerBitmap', None),
+(u'FilesInUse', u'Ignore', u'PushButton', 235, 243, 56, 17, 3, None, u'[ButtonText_Ignore]', u'Exit', None),
+(u'FilesInUse', u'List', u'ListBox', 20, 87, 330, 130, 7, u'FileInUseProcess', None, None, None),
+(u'LicenseAgreementDlg', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'AgreementText', None),
+(u'LicenseAgreementDlg', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None),
+(u'LicenseAgreementDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None),
+(u'LicenseAgreementDlg', u'Cancel', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'BannerBitmap', None),
+(u'LicenseAgreementDlg', u'Description', u'Text', 25, 23, 280, 15, 196611, None, u'Please read the following license agreement carefully', None, None),
+(u'LicenseAgreementDlg', u'Title', u'Text', 15, 6, 200, 15, 196611, None, u'[DlgTitleFont]End-User License Agreement', None, None),
+(u'LicenseAgreementDlg', u'Back', u'PushButton', 180, 243, 56, 17, 3, None, u'[ButtonText_Back]', u'Next', None),
+(u'LicenseAgreementDlg', u'Next', u'PushButton', 236, 243, 56, 17, 3, None, u'[ButtonText_Next]', u'Cancel', None),
+(u'LicenseAgreementDlg', u'AgreementText', u'ScrollableText', 20, 60, 330, 120, 7, None, u'{\\rtf1\\ansi\\ansicpg1252\\deff0\\deftab720{\\fonttbl{\\f0\\froman\\fprq2 Times New Roman;}}{\\colortbl\\red0\\green0\\blue0;} \\deflang1033\\horzdoc{\\*\\fchars }{\\*\\lchars }\\pard\\plain\\f0\\fs20 <Your license agreement should go here.>\\par }', u'Buttons', None),
+(u'LicenseAgreementDlg', u'Buttons', u'RadioButtonGroup', 20, 187, 330, 40, 3, u'IAgree', None, u'Back', None),
+(u'MaintenanceTypeDlg', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'ChangeLabel', None),
+(u'MaintenanceTypeDlg', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None),
+(u'MaintenanceTypeDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None),
+(u'MaintenanceTypeDlg', u'Cancel', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'BannerBitmap', None),
+(u'MaintenanceTypeDlg', u'Description', u'Text', 25, 23, 280, 20, 196611, None, u'Select the operation you wish to perform.', None, None),
+(u'MaintenanceTypeDlg', u'Title', u'Text', 15, 6, 240, 15, 196611, None, u'[DlgTitleFont]Modify, Repair or Remove installation', None, None),
+(u'MaintenanceTypeDlg', u'Back', u'PushButton', 180, 243, 56, 17, 3, None, u'[ButtonText_Back]', u'Next', None),
+(u'MaintenanceTypeDlg', u'Next', u'PushButton', 236, 243, 56, 17, 1, None, u'[ButtonText_Next]', u'Cancel', None),
+(u'MaintenanceTypeDlg', u'ChangeLabel', u'Text', 105, 65, 100, 10, 3, None, u'[DlgTitleFont]&Modify', u'ChangeButton', None),
+(u'MaintenanceTypeDlg', u'ChangeButton', u'PushButton', 50, 65, 38, 38, 5767171, None, u'[CustomSetupIcon]', u'RepairLabel', u'Modify Installation|'),
+(u'MaintenanceTypeDlg', u'RepairLabel', u'Text', 105, 114, 100, 10, 3, None, u'[DlgTitleFont]Re&pair', u'RepairButton', None),
+(u'MaintenanceTypeDlg', u'ChangeText', u'Text', 105, 78, 230, 20, 3, None, u'Allows users to change the way features are installed.', None, None),
+(u'MaintenanceTypeDlg', u'RemoveButton', u'PushButton', 50, 163, 38, 38, 5767171, None, u'[RemoveIcon]', u'Back', u'Remove Installation|'),
+(u'MaintenanceTypeDlg', u'RemoveLabel', u'Text', 105, 163, 100, 10, 3, None, u'[DlgTitleFont]&Remove', u'RemoveButton', None),
+(u'MaintenanceTypeDlg', u'RemoveText', u'Text', 105, 176, 230, 20, 3, None, u'Removes [ProductName] from your computer.', None, None),
+(u'MaintenanceTypeDlg', u'RepairButton', u'PushButton', 50, 114, 38, 38, 5767171, None, u'[RepairIcon]', u'RemoveLabel', u'Repair Installation|'),
+(u'MaintenanceTypeDlg', u'RepairText', u'Text', 105, 127, 230, 30, 3, None, u'Repairs errors in the most recent installation state - fixes missing or corrupt files, shortcuts and registry entries.', None, None),
+(u'MaintenanceWelcomeDlg', u'Bitmap', u'Bitmap', 0, 0, 370, 234, 1, None, u'[DialogBitmap]', u'Back', None),
+(u'MaintenanceWelcomeDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None),
+(u'MaintenanceWelcomeDlg', u'Cancel', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'Bitmap', None),
+(u'MaintenanceWelcomeDlg', u'Description', u'Text', 135, 70, 220, 60, 196611, None, u'The [Wizard] will allow you to change the way [ProductName] features are installed on your computer or even to remove [ProductName] from your computer.  Click Next to continue or Cancel to exit the [Wizard].', None, None),
+(u'MaintenanceWelcomeDlg', u'Title', u'Text', 135, 20, 220, 60, 196611, None, u'{\\VerdanaBold13}Welcome to the [ProductName] [Wizard]', None, None),
+(u'MaintenanceWelcomeDlg', u'Back', u'PushButton', 180, 243, 56, 17, 1, None, u'[ButtonText_Back]', u'Next', None),
+(u'MaintenanceWelcomeDlg', u'Next', u'PushButton', 236, 243, 56, 17, 3, None, u'[ButtonText_Next]', u'Cancel', None),
+(u'OutOfDiskDlg', u'Text', u'Text', 20, 53, 330, 40, 3, None, u'The highlighted volumes do not have enough disk space available for the currently selected features.  You can either remove some files from the highlighted volumes, or choose to install less features onto local drive(s), or select different destination drive(s).', None, None),
+(u'OutOfDiskDlg', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'OK', None),
+(u'OutOfDiskDlg', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None),
+(u'OutOfDiskDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None),
+(u'OutOfDiskDlg', u'Description', u'Text', 20, 20, 280, 20, 196611, None, u'Disk space required for the installation exceeds available disk space.', None, None),
+(u'OutOfDiskDlg', u'OK', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_OK]', u'BannerBitmap', None),
+(u'OutOfDiskDlg', u'Title', u'Text', 15, 6, 200, 15, 196611, None, u'[DlgTitleFont]Out of Disk Space', None, None),
+(u'OutOfDiskDlg', u'VolumeList', u'VolumeCostList', 20, 100, 330, 120, 393223, None, u'{120}{70}{70}{70}{70}', None, None),
+(u'OutOfRbDiskDlg', u'Text', u'Text', 20, 53, 330, 40, 3, None, u'The highlighted volumes do not have enough disk space available for the currently selected features.  You can either remove some files from the highlighted volumes, or choose to install less features onto local drive(s), or select different destination drive(s).', None, None),
+(u'OutOfRbDiskDlg', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'No', None),
+(u'OutOfRbDiskDlg', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None),
+(u'OutOfRbDiskDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None),
+(u'OutOfRbDiskDlg', u'Description', u'Text', 20, 20, 280, 20, 196611, None, u'Disk space required for the installation exceeds available disk space.', None, None),
+(u'OutOfRbDiskDlg', u'Title', u'Text', 15, 6, 200, 15, 196611, None, u'[DlgTitleFont]Out of Disk Space', None, None),
+(u'OutOfRbDiskDlg', u'No', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_No]', u'Yes', None),
+(u'OutOfRbDiskDlg', u'Yes', u'PushButton', 240, 243, 56, 17, 3, None, u'[ButtonText_Yes]', u'BannerBitmap', None),
+(u'OutOfRbDiskDlg', u'VolumeList', u'VolumeCostList', 20, 140, 330, 80, 4587527, None, u'{120}{70}{70}{70}{70}', None, None),
+(u'OutOfRbDiskDlg', u'Text2', u'Text', 20, 94, 330, 40, 3, None, u"Alternatively, you may choose to disable the installer's rollback functionality.  This allows the installer to restore your computer's original state should the installation be interrupted in any way.  Click Yes if you wish to take the risk to disable rollback.", None, None),
+(u'ResumeDlg', u'Bitmap', u'Bitmap', 0, 0, 370, 234, 1, None, u'[DialogBitmap]', u'Back', None),
+(u'ResumeDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None),
+(u'ResumeDlg', u'Cancel', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'Bitmap', None),
+(u'ResumeDlg', u'Description', u'Text', 135, 70, 220, 30, 196611, None, u'The [Wizard] will complete the installation of [ProductName] on your computer.  Click Install to continue or Cancel to exit the [Wizard].', None, None),
+(u'ResumeDlg', u'Title', u'Text', 135, 20, 220, 60, 196611, None, u'{\\VerdanaBold13}Resuming the [ProductName] [Wizard]', None, None),
+(u'ResumeDlg', u'Back', u'PushButton', 180, 243, 56, 17, 1, None, u'[ButtonText_Back]', u'Install', None),
+(u'ResumeDlg', u'Install', u'PushButton', 236, 243, 56, 17, 3, None, u'[ButtonText_Install]', u'Cancel', None),
+(u'SetupTypeDlg', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'TypicalLabel', None),
+(u'SetupTypeDlg', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None),
+(u'SetupTypeDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None),
+(u'SetupTypeDlg', u'Cancel', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'BannerBitmap', None),
+(u'SetupTypeDlg', u'Description', u'Text', 25, 23, 280, 15, 196611, None, u'Choose the setup type that best suits your needs', None, None),
+(u'SetupTypeDlg', u'Title', u'Text', 15, 6, 200, 15, 196611, None, u'[DlgTitleFont]Choose Setup Type', None, None),
+(u'SetupTypeDlg', u'Back', u'PushButton', 180, 243, 56, 17, 3, None, u'[ButtonText_Back]', u'Next', None),
+(u'SetupTypeDlg', u'Next', u'PushButton', 236, 243, 56, 17, 1, None, u'[ButtonText_Next]', u'Cancel', None),
+(u'SetupTypeDlg', u'TypicalLabel', u'Text', 105, 65, 100, 10, 3, None, u'[DlgTitleFont]&Typical', u'TypicalButton', None),
+(u'SetupTypeDlg', u'CompleteButton', u'PushButton', 50, 171, 38, 38, 5767171, None, u'[CompleteSetupIcon]', u'Back', u'Complete Installation|'),
+(u'SetupTypeDlg', u'CompleteLabel', u'Text', 105, 171, 100, 10, 3, None, u'[DlgTitleFont]C&omplete', u'CompleteButton', None),
+(u'SetupTypeDlg', u'CompleteText', u'Text', 105, 184, 230, 20, 3, None, u'All program features will be installed.  (Requires most disk space)', None, None),
+(u'SetupTypeDlg', u'CustomButton', u'PushButton', 50, 118, 38, 38, 5767171, None, u'[CustomSetupIcon]', u'CompleteLabel', u'Custom Installation|'),
+(u'SetupTypeDlg', u'CustomLabel', u'Text', 105, 118, 100, 10, 3, None, u'[DlgTitleFont]C&ustom', u'CustomButton', None),
+(u'SetupTypeDlg', u'CustomText', u'Text', 105, 131, 230, 30, 3, None, u'Allows users to choose which program features will be installed and where they will be installed. Recommended for advanced users.', None, None),
+(u'SetupTypeDlg', u'TypicalButton', u'PushButton', 50, 65, 38, 38, 5767171, None, u'[InstallerIcon]', u'CustomLabel', u'Typical Installation|'),
+(u'SetupTypeDlg', u'TypicalText', u'Text', 105, 78, 230, 20, 3, None, u'Installs the most common program features. Recommended for most users.', None, None),
+(u'UserRegistrationDlg', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'NameLabel', None),
+(u'UserRegistrationDlg', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None),
+(u'UserRegistrationDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None),
+(u'UserRegistrationDlg', u'Cancel', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'BannerBitmap', None),
+(u'UserRegistrationDlg', u'Description', u'Text', 25, 23, 280, 15, 196611, None, u'Please enter your customer information', None, None),
+(u'UserRegistrationDlg', u'Title', u'Text', 15, 6, 200, 15, 196611, None, u'[DlgTitleFont]Customer Information', None, None),
+(u'UserRegistrationDlg', u'Back', u'PushButton', 180, 243, 56, 17, 3, None, u'[ButtonText_Back]', u'Next', None),
+(u'UserRegistrationDlg', u'Next', u'PushButton', 236, 243, 56, 17, 3, None, u'[ButtonText_Next]', u'Cancel', None),
+(u'UserRegistrationDlg', u'OrganizationLabel', u'Text', 45, 110, 100, 15, 3, None, u'&Organization:', u'OrganizationEdit', None),
+(u'UserRegistrationDlg', u'CDKeyEdit', u'MaskedEdit', 45, 159, 250, 16, 3, u'PIDKEY', u'[PIDTemplate]', u'Back', None),
+(u'UserRegistrationDlg', u'CDKeyLabel', u'Text', 45, 147, 50, 10, 3, None, u'CD &Key:', u'CDKeyEdit', None),
+(u'UserRegistrationDlg', u'OrganizationEdit', u'Edit', 45, 122, 220, 18, 3, u'COMPANYNAME', u'{80}', u'CDKeyLabel', None),
+(u'UserRegistrationDlg', u'NameLabel', u'Text', 45, 73, 100, 15, 3, None, u'&User Name:', u'NameEdit', None),
+(u'UserRegistrationDlg', u'NameEdit', u'Edit', 45, 85, 220, 18, 3, u'USERNAME', u'{80}', u'OrganizationLabel', None),
+(u'VerifyReadyDlg', u'Text', u'Text', 25, 70, 320, 20, 3, None, u'Click Install to begin the installation.  If you want to review or change any of your installation settings, click Back.  Click Cancel to exit the wizard.', None, None),
+(u'VerifyReadyDlg', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'Back', None),
+(u'VerifyReadyDlg', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None),
+(u'VerifyReadyDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None),
+(u'VerifyReadyDlg', u'Cancel', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'BannerBitmap', None),
+(u'VerifyReadyDlg', u'Description', u'Text', 25, 23, 280, 15, 196611, None, u'The [Wizard] is ready to begin the [InstallMode] installation', None, None),
+(u'VerifyReadyDlg', u'Title', u'Text', 15, 6, 200, 15, 196611, None, u'[DlgTitleFont]Ready to Install', None, None),
+(u'VerifyReadyDlg', u'Back', u'PushButton', 180, 243, 56, 17, 3, None, u'[ButtonText_Back]', u'Install', None),
+(u'VerifyReadyDlg', u'Install', u'PushButton', 236, 243, 56, 17, 3, None, u'[ButtonText_Install]', u'Cancel', None),
+(u'VerifyRemoveDlg', u'Text', u'Text', 25, 70, 320, 30, 3, None, u'Click Remove to remove [ProductName] from your computer.  If you want to review or change any of your installation settings, click Back.  Click Cancel to exit the wizard.', None, None),
+(u'VerifyRemoveDlg', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'Back', None),
+(u'VerifyRemoveDlg', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None),
+(u'VerifyRemoveDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None),
+(u'VerifyRemoveDlg', u'Cancel', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'BannerBitmap', None),
+(u'VerifyRemoveDlg', u'Description', u'Text', 25, 23, 280, 15, 196611, None, u'You have chosen to remove the program from your computer.', None, None),
+(u'VerifyRemoveDlg', u'Title', u'Text', 15, 6, 200, 15, 196611, None, u'[DlgTitleFont]Remove [ProductName]', None, None),
+(u'VerifyRemoveDlg', u'Back', u'PushButton', 180, 243, 56, 17, 3, None, u'[ButtonText_Back]', u'Remove', None),
+(u'VerifyRemoveDlg', u'Remove', u'PushButton', 236, 243, 56, 17, 3, None, u'[ButtonText_Remove]', u'Cancel', None),
+(u'VerifyRepairDlg', u'Text', u'Text', 25, 70, 320, 30, 3, None, u'Click Repair to repair the installation of [ProductName].  If you want to review or change any of your installation settings, click Back.  Click Cancel to exit the wizard.', None, None),
+(u'VerifyRepairDlg', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'Back', None),
+(u'VerifyRepairDlg', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None),
+(u'VerifyRepairDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None),
+(u'VerifyRepairDlg', u'Cancel', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'BannerBitmap', None),
+(u'VerifyRepairDlg', u'Description', u'Text', 25, 23, 280, 15, 196611, None, u'The [Wizard] is ready to begin the repair of [ProductName].', None, None),
+(u'VerifyRepairDlg', u'Title', u'Text', 15, 6, 200, 15, 196611, None, u'[DlgTitleFont]Repair [ProductName]', None, None),
+(u'VerifyRepairDlg', u'Back', u'PushButton', 180, 243, 56, 17, 3, None, u'[ButtonText_Back]', u'Repair', None),
+(u'VerifyRepairDlg', u'Repair', u'PushButton', 236, 243, 56, 17, 3, None, u'[ButtonText_Repair]', u'Cancel', None),
+(u'WaitForCostingDlg', u'Text', u'Text', 48, 15, 194, 30, 3, None, u'Please wait while the installer finishes determining your disk space requirements.', None, None),
+(u'WaitForCostingDlg', u'Icon', u'Icon', 15, 15, 24, 24, 5242881, None, u'[ExclamationIcon]', None, u'Exclamation icon|'),
+(u'WaitForCostingDlg', u'Return', u'PushButton', 102, 57, 56, 17, 3, None, u'[ButtonText_Return]', None, None),
+(u'WelcomeDlg', u'Bitmap', u'Bitmap', 0, 0, 370, 234, 1, None, u'[DialogBitmap]', u'Back', None),
+(u'WelcomeDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None),
+(u'WelcomeDlg', u'Cancel', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'Bitmap', None),
+(u'WelcomeDlg', u'Description', u'Text', 135, 70, 220, 30, 196611, None, u'The [Wizard] will install [ProductName] on your computer.  Click Next to continue or Cancel to exit the [Wizard].', None, None),
+(u'WelcomeDlg', u'Title', u'Text', 135, 20, 220, 60, 196611, None, u'{\\VerdanaBold13}Welcome to the [ProductName] [Wizard]', None, None),
+(u'WelcomeDlg', u'Back', u'PushButton', 180, 243, 56, 17, 1, None, u'[ButtonText_Back]', u'Next', None),
+(u'WelcomeDlg', u'Next', u'PushButton', 236, 243, 56, 17, 3, None, u'[ButtonText_Next]', u'Cancel', None),
+]
+
+ListBox = [
+]
+
+ActionText = [
+(u'InstallValidate', u'Validating install', None),
+(u'InstallFiles', u'Copying new files', u'File: [1],  Directory: [9],  Size: [6]'),
+(u'InstallAdminPackage', u'Copying network install files', u'File: [1], Directory: [9], Size: [6]'),
+(u'FileCost', u'Computing space requirements', None),
+(u'CostInitialize', u'Computing space requirements', None),
+(u'CostFinalize', u'Computing space requirements', None),
+(u'CreateShortcuts', u'Creating shortcuts', u'Shortcut: [1]'),
+(u'PublishComponents', u'Publishing Qualified Components', u'Component ID: [1], Qualifier: [2]'),
+(u'PublishFeatures', u'Publishing Product Features', u'Feature: [1]'),
+(u'PublishProduct', u'Publishing product information', None),
+(u'RegisterClassInfo', u'Registering Class servers', u'Class Id: [1]'),
+(u'RegisterExtensionInfo', u'Registering extension servers', u'Extension: [1]'),
+(u'RegisterMIMEInfo', u'Registering MIME info', u'MIME Content Type: [1], Extension: [2]'),
+(u'RegisterProgIdInfo', u'Registering program identifiers', u'ProgId: [1]'),
+(u'AllocateRegistrySpace', u'Allocating registry space', u'Free space: [1]'),
+(u'AppSearch', u'Searching for installed applications', u'Property: [1], Signature: [2]'),
+(u'BindImage', u'Binding executables', u'File: [1]'),
+(u'CCPSearch', u'Searching for qualifying products', None),
+(u'CreateFolders', u'Creating folders', u'Folder: [1]'),
+(u'DeleteServices', u'Deleting services', u'Service: [1]'),
+(u'DuplicateFiles', u'Creating duplicate files', u'File: [1],  Directory: [9],  Size: [6]'),
+(u'FindRelatedProducts', u'Searching for related applications', u'Found application: [1]'),
+(u'InstallODBC', u'Installing ODBC components', None),
+(u'InstallServices', u'Installing new services', u'Service: [2]'),
+(u'LaunchConditions', u'Evaluating launch conditions', None),
+(u'MigrateFeatureStates', u'Migrating feature states from related applications', u'Application: [1]'),
+(u'MoveFiles', u'Moving files', u'File: [1],  Directory: [9],  Size: [6]'),
+(u'PatchFiles', u'Patching files', u'File: [1],  Directory: [2],  Size: [3]'),
+(u'ProcessComponents', u'Updating component registration', None),
+(u'RegisterComPlus', u'Registering COM+ Applications and Components', u'AppId: [1]{{, AppType: [2], Users: [3], RSN: [4]}}'),
+(u'RegisterFonts', u'Registering fonts', u'Font: [1]'),
+(u'RegisterProduct', u'Registering product', u'[1]'),
+(u'RegisterTypeLibraries', u'Registering type libraries', u'LibID: [1]'),
+(u'RegisterUser', u'Registering user', u'[1]'),
+(u'RemoveDuplicateFiles', u'Removing duplicated files', u'File: [1], Directory: [9]'),
+(u'RemoveEnvironmentStrings', u'Updating environment strings', u'Name: [1], Value: [2], Action [3]'),
+(u'RemoveExistingProducts', u'Removing applications', u'Application: [1], Command line: [2]'),
+(u'RemoveFiles', u'Removing files', u'File: [1], Directory: [9]'),
+(u'RemoveFolders', u'Removing folders', u'Folder: [1]'),
+(u'RemoveIniValues', u'Removing INI files entries', u'File: [1],  Section: [2],  Key: [3], Value: [4]'),
+(u'RemoveODBC', u'Removing ODBC components', None),
+(u'RemoveRegistryValues', u'Removing system registry values', u'Key: [1], Name: [2]'),
+(u'RemoveShortcuts', u'Removing shortcuts', u'Shortcut: [1]'),
+(u'RMCCPSearch', u'Searching for qualifying products', None),
+(u'SelfRegModules', u'Registering modules', u'File: [1], Folder: [2]'),
+(u'SelfUnregModules', u'Unregistering modules', u'File: [1], Folder: [2]'),
+(u'SetODBCFolders', u'Initializing ODBC directories', None),
+(u'StartServices', u'Starting services', u'Service: [1]'),
+(u'StopServices', u'Stopping services', u'Service: [1]'),
+(u'UnpublishComponents', u'Unpublishing Qualified Components', u'Component ID: [1], Qualifier: [2]'),
+(u'UnpublishFeatures', u'Unpublishing Product Features', u'Feature: [1]'),
+(u'UnregisterClassInfo', u'Unregister Class servers', u'Class Id: [1]'),
+(u'UnregisterComPlus', u'Unregistering COM+ Applications and Components', u'AppId: [1]{{, AppType: [2]}}'),
+(u'UnregisterExtensionInfo', u'Unregistering extension servers', u'Extension: [1]'),
+(u'UnregisterFonts', u'Unregistering fonts', u'Font: [1]'),
+(u'UnregisterMIMEInfo', u'Unregistering MIME info', u'MIME Content Type: [1], Extension: [2]'),
+(u'UnregisterProgIdInfo', u'Unregistering program identifiers', u'ProgId: [1]'),
+(u'UnregisterTypeLibraries', u'Unregistering type libraries', u'LibID: [1]'),
+(u'WriteEnvironmentStrings', u'Updating environment strings', u'Name: [1], Value: [2], Action [3]'),
+(u'WriteIniValues', u'Writing INI files values', u'File: [1],  Section: [2],  Key: [3], Value: [4]'),
+(u'WriteRegistryValues', u'Writing system registry values', u'Key: [1], Name: [2], Value: [3]'),
+(u'Advertise', u'Advertising application', None),
+(u'GenerateScript', u'Generating script operations for action:', u'[1]'),
+(u'InstallSFPCatalogFile', u'Installing system catalog', u'File: [1],  Dependencies: [2]'),
+(u'MsiPublishAssemblies', u'Publishing assembly information', u'Application Context:[1], Assembly Name:[2]'),
+(u'MsiUnpublishAssemblies', u'Unpublishing assembly information', u'Application Context:[1], Assembly Name:[2]'),
+(u'Rollback', u'Rolling back action:', u'[1]'),
+(u'RollbackCleanup', u'Removing backup files', u'File: [1]'),
+(u'UnmoveFiles', u'Removing moved files', u'File: [1], Directory: [9]'),
+(u'UnpublishProduct', u'Unpublishing product information', None),
+]
+
+ControlCondition = [
+(u'CustomizeDlg', u'Browse', u'Hide', u'Installed'),
+(u'CustomizeDlg', u'Location', u'Hide', u'Installed'),
+(u'CustomizeDlg', u'LocationLabel', u'Hide', u'Installed'),
+(u'LicenseAgreementDlg', u'Next', u'Disable', u'IAgree <> "Yes"'),
+(u'LicenseAgreementDlg', u'Next', u'Enable', u'IAgree = "Yes"'),
+]
+
+ControlEvent = [
+(u'AdminWelcomeDlg', u'Cancel', u'SpawnDialog', u'CancelDlg', u'1', None),
+(u'AdminWelcomeDlg', u'Next', u'NewDialog', u'AdminRegistrationDlg', u'1', 2),
+(u'AdminWelcomeDlg', u'Next', u'[InstallMode]', u'Server Image', u'1', 1),
+(u'ExitDialog', u'Finish', u'EndDialog', u'Return', u'1', None),
+(u'FatalError', u'Finish', u'EndDialog', u'Exit', u'1', None),
+(u'PrepareDlg', u'Cancel', u'SpawnDialog', u'CancelDlg', u'1', None),
+(u'ProgressDlg', u'Cancel', u'SpawnDialog', u'CancelDlg', u'1', None),
+(u'UserExit', u'Finish', u'EndDialog', u'Exit', u'1', None),
+(u'AdminBrowseDlg', u'Up', u'DirectoryListUp', u'0', u'1', None),
+(u'AdminBrowseDlg', u'Cancel', u'Reset', u'0', u'1', 1),
+(u'AdminBrowseDlg', u'Cancel', u'EndDialog', u'Return', u'1', 2),
+(u'AdminBrowseDlg', u'NewFolder', u'DirectoryListNew', u'0', u'1', None),
+(u'AdminBrowseDlg', u'OK', u'EndDialog', u'Return', u'1', 2),
+(u'AdminBrowseDlg', u'OK', u'SetTargetPath', u'TARGETDIR', u'1', 1),
+(u'AdminInstallPointDlg', u'Cancel', u'SpawnDialog', u'CancelDlg', u'1', None),
+(u'AdminInstallPointDlg', u'Back', u'NewDialog', u'AdminRegistrationDlg', u'1', None),
+(u'AdminInstallPointDlg', u'Next', u'SetTargetPath', u'TARGETDIR', u'1', 1),
+(u'AdminInstallPointDlg', u'Next', u'NewDialog', u'VerifyReadyDlg', u'1', 2),
+(u'AdminInstallPointDlg', u'Browse', u'SpawnDialog', u'AdminBrowseDlg', u'1', None),
+(u'AdminRegistrationDlg', u'Cancel', u'SpawnDialog', u'CancelDlg', u'1', None),
+(u'AdminRegistrationDlg', u'Back', u'NewDialog', u'AdminWelcomeDlg', u'1', None),
+(u'AdminRegistrationDlg', u'Next', u'NewDialog', u'AdminInstallPointDlg', u'ProductID', 2),
+(u'AdminRegistrationDlg', u'Next', u'ValidateProductID', u'0', u'0', 1),
+(u'BrowseDlg', u'Up', u'DirectoryListUp', u'0', u'1', None),
+(u'BrowseDlg', u'Cancel', u'Reset', u'0', u'1', 1),
+(u'BrowseDlg', u'Cancel', u'EndDialog', u'Return', u'1', 2),
+(u'BrowseDlg', u'NewFolder', u'DirectoryListNew', u'0', u'1', None),
+(u'BrowseDlg', u'OK', u'EndDialog', u'Return', u'1', 2),
+(u'BrowseDlg', u'OK', u'SetTargetPath', u'[_BrowseProperty]', u'1', 1),
+(u'CancelDlg', u'No', u'EndDialog', u'Return', u'1', None),
+(u'CancelDlg', u'Yes', u'EndDialog', u'Exit', u'1', None),
+(u'CustomizeDlg', u'Cancel', u'SpawnDialog', u'CancelDlg', u'1', None),
+(u'CustomizeDlg', u'Back', u'NewDialog', u'MaintenanceTypeDlg', u'InstallMode = "Change"', None),
+(u'CustomizeDlg', u'Back', u'NewDialog', u'SetupTypeDlg', u'InstallMode = "Custom"', None),
+(u'CustomizeDlg', u'Next', u'NewDialog', u'VerifyReadyDlg', u'1', None),
+(u'CustomizeDlg', u'Browse', u'SelectionBrowse', u'BrowseDlg', u'1', None),
+(u'CustomizeDlg', u'Reset', u'Reset', u'0', u'1', None),
+(u'CustomizeDlg', u'DiskCost', u'SpawnDialog', u'DiskCostDlg', u'1', 2),
+(u'DiskCostDlg', u'OK', u'EndDialog', u'Return', u'1', None),
+(u'ErrorDlg', u'Y', u'EndDialog', u'ErrorYes', u'1', None),
+(u'ErrorDlg', u'A', u'EndDialog', u'ErrorAbort', u'1', None),
+(u'ErrorDlg', u'C', u'EndDialog', u'ErrorCancel', u'1', None),
+(u'ErrorDlg', u'I', u'EndDialog', u'ErrorIgnore', u'1', None),
+(u'ErrorDlg', u'N', u'EndDialog', u'ErrorNo', u'1', None),
+(u'ErrorDlg', u'O', u'EndDialog', u'ErrorOk', u'1', None),
+(u'ErrorDlg', u'R', u'EndDialog', u'ErrorRetry', u'1', None),
+(u'FilesInUse', u'Retry', u'EndDialog', u'Retry', u'1', None),
+(u'FilesInUse', u'Exit', u'EndDialog', u'Exit', u'1', None),
+(u'FilesInUse', u'Ignore', u'EndDialog', u'Ignore', u'1', None),
+(u'LicenseAgreementDlg', u'Cancel', u'SpawnDialog', u'CancelDlg', u'1', None),
+(u'LicenseAgreementDlg', u'Back', u'NewDialog', u'WelcomeDlg', u'1', None),
+(u'LicenseAgreementDlg', u'Next', u'NewDialog', u'SetupTypeDlg', u'IAgree = "Yes" AND ShowUserRegistrationDlg <> 1', 3),
+(u'LicenseAgreementDlg', u'Next', u'NewDialog', u'UserRegistrationDlg', u'IAgree = "Yes" AND ShowUserRegistrationDlg = 1', 1),
+(u'LicenseAgreementDlg', u'Next', u'SpawnWaitDialog', u'WaitForCostingDlg', u'CostingComplete = 1', 2),
+(u'MaintenanceTypeDlg', u'Cancel', u'SpawnDialog', u'CancelDlg', u'1', None),
+(u'MaintenanceTypeDlg', u'Back', u'NewDialog', u'MaintenanceWelcomeDlg', u'1', None),
+(u'MaintenanceTypeDlg', u'ChangeButton', u'NewDialog', u'CustomizeDlg', u'1', 4),
+(u'MaintenanceTypeDlg', u'ChangeButton', u'[InstallMode]', u'Change', u'1', 1),
+(u'MaintenanceTypeDlg', u'ChangeButton', u'[Progress1]', u'Changing', u'1', 2),
+(u'MaintenanceTypeDlg', u'ChangeButton', u'[Progress2]', u'changes', u'1', 3),
+(u'MaintenanceTypeDlg', u'RemoveButton', u'NewDialog', u'VerifyRemoveDlg', u'1', 4),
+(u'MaintenanceTypeDlg', u'RemoveButton', u'[InstallMode]', u'Remove', u'1', 1),
+(u'MaintenanceTypeDlg', u'RemoveButton', u'[Progress1]', u'Removing', u'1', 2),
+(u'MaintenanceTypeDlg', u'RemoveButton', u'[Progress2]', u'removes', u'1', 3),
+(u'MaintenanceTypeDlg', u'RepairButton', u'NewDialog', u'VerifyRepairDlg', u'1', 4),
+(u'MaintenanceTypeDlg', u'RepairButton', u'[InstallMode]', u'Repair', u'1', 1),
+(u'MaintenanceTypeDlg', u'RepairButton', u'[Progress1]', u'Repairing', u'1', 2),
+(u'MaintenanceTypeDlg', u'RepairButton', u'[Progress2]', u'repairs', u'1', 3),
+(u'MaintenanceWelcomeDlg', u'Cancel', u'SpawnDialog', u'CancelDlg', u'1', None),
+(u'MaintenanceWelcomeDlg', u'Next', u'NewDialog', u'MaintenanceTypeDlg', u'1', 2),
+(u'MaintenanceWelcomeDlg', u'Next', u'SpawnWaitDialog', u'WaitForCostingDlg', u'CostingComplete = 1', 1),
+(u'OutOfDiskDlg', u'OK', u'EndDialog', u'Return', u'1', None),
+(u'OutOfRbDiskDlg', u'No', u'EndDialog', u'Return', u'1', None),
+(u'OutOfRbDiskDlg', u'Yes', u'EndDialog', u'Return', u'1', 2),
+(u'OutOfRbDiskDlg', u'Yes', u'EnableRollback', u'False', u'1', 1),
+(u'ResumeDlg', u'Cancel', u'SpawnDialog', u'CancelDlg', u'1', None),
+(u'ResumeDlg', u'Install', u'EndDialog', u'Return', u'OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D"', 4),
+(u'ResumeDlg', u'Install', u'EndDialog', u'Return', u'OutOfDiskSpace <> 1', 2),
+(u'ResumeDlg', u'Install', u'SpawnDialog', u'OutOfDiskDlg', u'(OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 1) OR (OutOfDiskSpace = 1 AND PROMPTROLLBACKCOST="F")', 6),
+(u'ResumeDlg', u'Install', u'SpawnDialog', u'OutOfRbDiskDlg', u'OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND (PROMPTROLLBACKCOST="P" OR NOT PROMPTROLLBACKCOST)', 3),
+(u'ResumeDlg', u'Install', u'SpawnWaitDialog', u'WaitForCostingDlg', u'CostingComplete = 1', 1),
+(u'ResumeDlg', u'Install', u'EnableRollback', u'False', u'OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D"', 5),
+(u'SetupTypeDlg', u'Cancel', u'SpawnDialog', u'CancelDlg', u'1', None),
+(u'SetupTypeDlg', u'Back', u'NewDialog', u'LicenseAgreementDlg', u'ShowUserRegistrationDlg <> 1', None),
+(u'SetupTypeDlg', u'Back', u'NewDialog', u'UserRegistrationDlg', u'ShowUserRegistrationDlg = 1', None),
+(u'SetupTypeDlg', u'CompleteButton', u'NewDialog', u'VerifyReadyDlg', u'1', 3),
+(u'SetupTypeDlg', u'CompleteButton', u'[InstallMode]', u'Complete', u'1', 1),
+(u'SetupTypeDlg', u'CompleteButton', u'SetInstallLevel', u'1000', u'1', 2),
+(u'SetupTypeDlg', u'CustomButton', u'NewDialog', u'CustomizeDlg', u'1', 2),
+(u'SetupTypeDlg', u'CustomButton', u'[InstallMode]', u'Custom', u'1', 1),
+(u'SetupTypeDlg', u'TypicalButton', u'NewDialog', u'VerifyReadyDlg', u'1', 3),
+(u'SetupTypeDlg', u'TypicalButton', u'[InstallMode]', u'Typical', u'1', 1),
+(u'SetupTypeDlg', u'TypicalButton', u'SetInstallLevel', u'3', u'1', 2),
+(u'UserRegistrationDlg', u'Cancel', u'SpawnDialog', u'CancelDlg', u'1', None),
+(u'UserRegistrationDlg', u'Back', u'NewDialog', u'LicenseAgreementDlg', u'1', None),
+(u'UserRegistrationDlg', u'Next', u'NewDialog', u'SetupTypeDlg', u'ProductID', 3),
+(u'UserRegistrationDlg', u'Next', u'ValidateProductID', u'0', u'0', 1),
+(u'UserRegistrationDlg', u'Next', u'SpawnWaitDialog', u'WaitForCostingDlg', u'CostingComplete = 1', 2),
+(u'VerifyReadyDlg', u'Cancel', u'SpawnDialog', u'CancelDlg', u'1', None),
+(u'VerifyReadyDlg', u'Back', u'NewDialog', u'AdminInstallPointDlg', u'InstallMode = "Server Image"', None),
+(u'VerifyReadyDlg', u'Back', u'NewDialog', u'CustomizeDlg', u'InstallMode = "Custom" OR InstallMode = "Change"', None),
+(u'VerifyReadyDlg', u'Back', u'NewDialog', u'MaintenanceTypeDlg', u'InstallMode = "Repair"', None),
+(u'VerifyReadyDlg', u'Back', u'NewDialog', u'SetupTypeDlg', u'InstallMode = "Typical" OR InstallMode = "Complete"', None),
+(u'VerifyReadyDlg', u'Install', u'EndDialog', u'Return', u'OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D"', 3),
+(u'VerifyReadyDlg', u'Install', u'EndDialog', u'Return', u'OutOfDiskSpace <> 1', 1),
+(u'VerifyReadyDlg', u'Install', u'SpawnDialog', u'OutOfDiskDlg', u'(OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 1) OR (OutOfDiskSpace = 1 AND PROMPTROLLBACKCOST="F")', 5),
+(u'VerifyReadyDlg', u'Install', u'SpawnDialog', u'OutOfRbDiskDlg', u'OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND (PROMPTROLLBACKCOST="P" OR NOT PROMPTROLLBACKCOST)', 2),
+(u'VerifyReadyDlg', u'Install', u'EnableRollback', u'False', u'OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D"', 4),
+(u'VerifyRemoveDlg', u'Cancel', u'SpawnDialog', u'CancelDlg', u'1', None),
+(u'VerifyRemoveDlg', u'Back', u'NewDialog', u'MaintenanceTypeDlg', u'1', None),
+(u'VerifyRemoveDlg', u'Remove', u'Remove', u'All', u'OutOfDiskSpace <> 1', 1),
+(u'VerifyRemoveDlg', u'Remove', u'EndDialog', u'Return', u'OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D"', 4),
+(u'VerifyRemoveDlg', u'Remove', u'EndDialog', u'Return', u'OutOfDiskSpace <> 1', 2),
+(u'VerifyRemoveDlg', u'Remove', u'SpawnDialog', u'OutOfDiskDlg', u'(OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 1) OR (OutOfDiskSpace = 1 AND PROMPTROLLBACKCOST="F")', 6),
+(u'VerifyRemoveDlg', u'Remove', u'SpawnDialog', u'OutOfRbDiskDlg', u'OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND (PROMPTROLLBACKCOST="P" OR NOT PROMPTROLLBACKCOST)', 3),
+(u'VerifyRemoveDlg', u'Remove', u'EnableRollback', u'False', u'OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D"', 5),
+(u'VerifyRepairDlg', u'Cancel', u'SpawnDialog', u'CancelDlg', u'1', None),
+(u'VerifyRepairDlg', u'Back', u'NewDialog', u'MaintenanceTypeDlg', u'1', None),
+(u'VerifyRepairDlg', u'Repair', u'EndDialog', u'Return', u'OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D"', 5),
+(u'VerifyRepairDlg', u'Repair', u'EndDialog', u'Return', u'OutOfDiskSpace <> 1', 3),
+(u'VerifyRepairDlg', u'Repair', u'SpawnDialog', u'OutOfDiskDlg', u'(OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 1) OR (OutOfDiskSpace = 1 AND PROMPTROLLBACKCOST="F")', 7),
+(u'VerifyRepairDlg', u'Repair', u'SpawnDialog', u'OutOfRbDiskDlg', u'OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND (PROMPTROLLBACKCOST="P" OR NOT PROMPTROLLBACKCOST)', 4),
+(u'VerifyRepairDlg', u'Repair', u'EnableRollback', u'False', u'OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D"', 6),
+(u'VerifyRepairDlg', u'Repair', u'Reinstall', u'All', u'OutOfDiskSpace <> 1', 2),
+(u'VerifyRepairDlg', u'Repair', u'ReinstallMode', u'ecmus', u'OutOfDiskSpace <> 1', 1),
+(u'WaitForCostingDlg', u'Return', u'EndDialog', u'Exit', u'1', None),
+(u'WelcomeDlg', u'Cancel', u'SpawnDialog', u'CancelDlg', u'1', None),
+(u'WelcomeDlg', u'Next', u'NewDialog', u'LicenseAgreementDlg', u'1', None),
+]
+
+Dialog = [
+(u'AdminWelcomeDlg', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'Next', u'Next', u'Cancel'),
+(u'ExitDialog', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'Finish', u'Finish', u'Finish'),
+(u'FatalError', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'Finish', u'Finish', u'Finish'),
+(u'PrepareDlg', 50, 50, 370, 270, 1, u'[ProductName] [Setup]', u'Cancel', u'Cancel', u'Cancel'),
+(u'ProgressDlg', 50, 50, 370, 270, 1, u'[ProductName] [Setup]', u'Cancel', u'Cancel', u'Cancel'),
+(u'UserExit', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'Finish', u'Finish', u'Finish'),
+(u'AdminBrowseDlg', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'PathEdit', u'OK', u'Cancel'),
+(u'AdminInstallPointDlg', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'Text', u'Next', u'Cancel'),
+(u'AdminRegistrationDlg', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'OrganizationLabel', u'Next', u'Cancel'),
+(u'BrowseDlg', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'PathEdit', u'OK', u'Cancel'),
+(u'CancelDlg', 50, 10, 260, 85, 3, u'[ProductName] [Setup]', u'No', u'No', u'No'),
+(u'CustomizeDlg', 50, 50, 370, 270, 35, u'[ProductName] [Setup]', u'Tree', u'Next', u'Cancel'),
+(u'DiskCostDlg', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'OK', u'OK', u'OK'),
+(u'ErrorDlg', 50, 10, 270, 105, 65539, u'Installer Information', u'ErrorText', None, None),
+(u'FilesInUse', 50, 50, 370, 270, 19, u'[ProductName] [Setup]', u'Retry', u'Retry', u'Retry'),
+(u'LicenseAgreementDlg', 50, 50, 370, 270, 3, u'[ProductName] License Agreement', u'Buttons', u'Next', u'Cancel'),
+(u'MaintenanceTypeDlg', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'ChangeLabel', u'ChangeButton', u'Cancel'),
+(u'MaintenanceWelcomeDlg', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'Next', u'Next', u'Cancel'),
+(u'OutOfDiskDlg', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'OK', u'OK', u'OK'),
+(u'OutOfRbDiskDlg', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'No', u'No', u'No'),
+(u'ResumeDlg', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'Install', u'Install', u'Cancel'),
+(u'SetupTypeDlg', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'TypicalLabel', u'TypicalButton', u'Cancel'),
+(u'UserRegistrationDlg', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'NameLabel', u'Next', u'Cancel'),
+(u'VerifyReadyDlg', 50, 50, 370, 270, 35, u'[ProductName] [Setup]', u'Install', u'Install', u'Cancel'),
+(u'VerifyRemoveDlg', 50, 50, 370, 270, 35, u'[ProductName] [Setup]', u'Back', u'Back', u'Cancel'),
+(u'VerifyRepairDlg', 50, 50, 370, 270, 35, u'[ProductName] [Setup]', u'Repair', u'Repair', u'Cancel'),
+(u'WaitForCostingDlg', 50, 10, 260, 85, 3, u'[ProductName] [Setup]', u'Return', u'Return', u'Return'),
+(u'WelcomeDlg', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'Next', u'Next', u'Cancel'),
+]
+
+EventMapping = [
+(u'PrepareDlg', u'ActionData', u'ActionData', u'Text'),
+(u'PrepareDlg', u'ActionText', u'ActionText', u'Text'),
+(u'ProgressDlg', u'ActionText', u'ActionText', u'Text'),
+(u'ProgressDlg', u'ProgressBar', u'SetProgress', u'Progress'),
+(u'AdminBrowseDlg', u'DirectoryCombo', u'IgnoreChange', u'IgnoreChange'),
+(u'BrowseDlg', u'DirectoryCombo', u'IgnoreChange', u'IgnoreChange'),
+(u'CustomizeDlg', u'Next', u'SelectionNoItems', u'Enabled'),
+(u'CustomizeDlg', u'Reset', u'SelectionNoItems', u'Enabled'),
+(u'CustomizeDlg', u'DiskCost', u'SelectionNoItems', u'Enabled'),
+(u'CustomizeDlg', u'ItemDescription', u'SelectionDescription', u'Text'),
+(u'CustomizeDlg', u'ItemSize', u'SelectionSize', u'Text'),
+(u'CustomizeDlg', u'Location', u'SelectionPath', u'Text'),
+(u'CustomizeDlg', u'Location', u'SelectionPathOn', u'Visible'),
+(u'CustomizeDlg', u'LocationLabel', u'SelectionPathOn', u'Visible'),
+]
+
+InstallExecuteSequence = [
+(u'InstallValidate', None, 1400),
+(u'InstallInitialize', None, 1500),
+(u'InstallFinalize', None, 6600),
+(u'InstallFiles', None, 4000),
+(u'FileCost', None, 900),
+(u'CostInitialize', None, 800),
+(u'CostFinalize', None, 1000),
+(u'CreateShortcuts', None, 4500),
+(u'PublishComponents', None, 6200),
+(u'PublishFeatures', None, 6300),
+(u'PublishProduct', None, 6400),
+(u'RegisterClassInfo', None, 4600),
+(u'RegisterExtensionInfo', None, 4700),
+(u'RegisterMIMEInfo', None, 4900),
+(u'RegisterProgIdInfo', None, 4800),
+(u'ValidateProductID', None, 700),
+(u'AllocateRegistrySpace', u'NOT Installed', 1550),
+(u'AppSearch', None, 400),
+(u'BindImage', None, 4300),
+(u'CCPSearch', u'NOT Installed', 500),
+(u'CreateFolders', None, 3700),
+(u'DeleteServices', u'VersionNT', 2000),
+(u'DuplicateFiles', None, 4210),
+(u'FindRelatedProducts', None, 200),
+(u'InstallODBC', None, 5400),
+(u'InstallServices', u'VersionNT', 5800),
+(u'LaunchConditions', None, 100),
+(u'MigrateFeatureStates', None, 1200),
+(u'MoveFiles', None, 3800),
+(u'PatchFiles', None, 4090),
+(u'ProcessComponents', None, 1600),
+(u'RegisterComPlus', None, 5700),
+(u'RegisterFonts', None, 5300),
+(u'RegisterProduct', None, 6100),
+(u'RegisterTypeLibraries', None, 5500),
+(u'RegisterUser', None, 6000),
+(u'RemoveDuplicateFiles', None, 3400),
+(u'RemoveEnvironmentStrings', None, 3300),
+(u'RemoveExistingProducts', None, 6700),
+(u'RemoveFiles', None, 3500),
+(u'RemoveFolders', None, 3600),
+(u'RemoveIniValues', None, 3100),
+(u'RemoveODBC', None, 2400),
+(u'RemoveRegistryValues', None, 2600),
+(u'RemoveShortcuts', None, 3200),
+(u'RMCCPSearch', u'NOT Installed', 600),
+(u'SelfRegModules', None, 5600),
+(u'SelfUnregModules', None, 2200),
+(u'SetODBCFolders', None, 1100),
+(u'StartServices', u'VersionNT', 5900),
+(u'StopServices', u'VersionNT', 1900),
+(u'UnpublishComponents', None, 1700),
+(u'UnpublishFeatures', None, 1800),
+(u'UnregisterClassInfo', None, 2700),
+(u'UnregisterComPlus', None, 2100),
+(u'UnregisterExtensionInfo', None, 2800),
+(u'UnregisterFonts', None, 2500),
+(u'UnregisterMIMEInfo', None, 3000),
+(u'UnregisterProgIdInfo', None, 2900),
+(u'UnregisterTypeLibraries', None, 2300),
+(u'WriteEnvironmentStrings', None, 5200),
+(u'WriteIniValues', None, 5100),
+(u'WriteRegistryValues', None, 5000),
+]
+
+InstallUISequence = [
+#(u'FileCost', None, 900),
+#(u'CostInitialize', None, 800),
+#(u'CostFinalize', None, 1000),
+#(u'ExecuteAction', None, 1300),
+#(u'ExitDialog', None, -1),
+#(u'FatalError', None, -3),
+(u'PrepareDlg', None, 140),
+(u'ProgressDlg', None, 1280),
+#(u'UserExit', None, -2),
+(u'MaintenanceWelcomeDlg', u'Installed AND NOT RESUME AND NOT Preselected', 1250),
+(u'ResumeDlg', u'Installed AND (RESUME OR Preselected)', 1240),
+(u'WelcomeDlg', u'NOT Installed', 1230),
+#(u'AppSearch', None, 400),
+#(u'CCPSearch', u'NOT Installed', 500),
+#(u'FindRelatedProducts', None, 200),
+#(u'LaunchConditions', None, 100),
+#(u'MigrateFeatureStates', None, 1200),
+#(u'RMCCPSearch', u'NOT Installed', 600),
+]
+
+ListView = [
+]
+
+RadioButton = [
+(u'IAgree', 1, u'Yes', 5, 0, 250, 15, u'{\\DlgFont8}I &accept the terms in the License Agreement', None),
+(u'IAgree', 2, u'No', 5, 20, 250, 15, u'{\\DlgFont8}I &do not accept the terms in the License Agreement', None),
+]
+
+TextStyle = [
+(u'DlgFont8', u'Tahoma', 8, None, 0),
+(u'DlgFontBold8', u'Tahoma', 8, None, 1),
+(u'VerdanaBold13', u'Verdana', 13, None, 1),
+]
+
+UIText = [
+(u'AbsentPath', None),
+(u'bytes', u'bytes'),
+(u'GB', u'GB'),
+(u'KB', u'KB'),
+(u'MB', u'MB'),
+(u'MenuAbsent', u'Entire feature will be unavailable'),
+(u'MenuAdvertise', u'Feature will be installed when required'),
+(u'MenuAllCD', u'Entire feature will be installed to run from CD'),
+(u'MenuAllLocal', u'Entire feature will be installed on local hard drive'),
+(u'MenuAllNetwork', u'Entire feature will be installed to run from network'),
+(u'MenuCD', u'Will be installed to run from CD'),
+(u'MenuLocal', u'Will be installed on local hard drive'),
+(u'MenuNetwork', u'Will be installed to run from network'),
+(u'ScriptInProgress', u'Gathering required information...'),
+(u'SelAbsentAbsent', u'This feature will remain uninstalled'),
+(u'SelAbsentAdvertise', u'This feature will be set to be installed when required'),
+(u'SelAbsentCD', u'This feature will be installed to run from CD'),
+(u'SelAbsentLocal', u'This feature will be installed on the local hard drive'),
+(u'SelAbsentNetwork', u'This feature will be installed to run from the network'),
+(u'SelAdvertiseAbsent', u'This feature will become unavailable'),
+(u'SelAdvertiseAdvertise', u'Will be installed when required'),
+(u'SelAdvertiseCD', u'This feature will be available to run from CD'),
+(u'SelAdvertiseLocal', u'This feature will be installed on your local hard drive'),
+(u'SelAdvertiseNetwork', u'This feature will be available to run from the network'),
+(u'SelCDAbsent', u"This feature will be uninstalled completely, you won't be able to run it from CD"),
+(u'SelCDAdvertise', u'This feature will change from run from CD state to set to be installed when required'),
+(u'SelCDCD', u'This feature will remain to be run from CD'),
+(u'SelCDLocal', u'This feature will change from run from CD state to be installed on the local hard drive'),
+(u'SelChildCostNeg', u'This feature frees up [1] on your hard drive.'),
+(u'SelChildCostPos', u'This feature requires [1] on your hard drive.'),
+(u'SelCostPending', u'Compiling cost for this feature...'),
+(u'SelLocalAbsent', u'This feature will be completely removed'),
+(u'SelLocalAdvertise', u'This feature will be removed from your local hard drive, but will be set to be installed when required'),
+(u'SelLocalCD', u'This feature will be removed from your local hard drive, but will be still available to run from CD'),
+(u'SelLocalLocal', u'This feature will remain on you local hard drive'),
+(u'SelLocalNetwork', u'This feature will be removed from your local hard drive, but will be still available to run from the network'),
+(u'SelNetworkAbsent', u"This feature will be uninstalled completely, you won't be able to run it from the network"),
+(u'SelNetworkAdvertise', u'This feature will change from run from network state to set to be installed when required'),
+(u'SelNetworkLocal', u'This feature will change from run from network state to be installed on the local hard drive'),
+(u'SelNetworkNetwork', u'This feature will remain to be run from the network'),
+(u'SelParentCostNegNeg', u'This feature frees up [1] on your hard drive. It has [2] of [3] subfeatures selected. The subfeatures free up [4] on your hard drive.'),
+(u'SelParentCostNegPos', u'This feature frees up [1] on your hard drive. It has [2] of [3] subfeatures selected. The subfeatures require [4] on your hard drive.'),
+(u'SelParentCostPosNeg', u'This feature requires [1] on your hard drive. It has [2] of [3] subfeatures selected. The subfeatures free up [4] on your hard drive.'),
+(u'SelParentCostPosPos', u'This feature requires [1] on your hard drive. It has [2] of [3] subfeatures selected. The subfeatures require [4] on your hard drive.'),
+(u'TimeRemaining', u'Time remaining: {[1] minutes }{[2] seconds}'),
+(u'VolumeCostAvailable', u'Available'),
+(u'VolumeCostDifference', u'Difference'),
+(u'VolumeCostRequired', u'Required'),
+(u'VolumeCostSize', u'Disk Size'),
+(u'VolumeCostVolume', u'Volume'),
+]
+
+_Validation = [
+(u'AdminExecuteSequence', u'Action', u'N', None, None, None, None, u'Identifier', None, u'Name of action to invoke, either in the engine or the handler DLL.'),
+(u'AdminExecuteSequence', u'Sequence', u'Y', -4, 32767, None, None, None, None, u'Number that determines the sort order in which the actions are to be executed.  Leave blank to suppress action.'),
+(u'AdminExecuteSequence', u'Condition', u'Y', None, None, None, None, u'Condition', None, u'Optional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData.'),
+(u'AdminUISequence', u'Action', u'N', None, None, None, None, u'Identifier', None, u'Name of action to invoke, either in the engine or the handler DLL.'),
+(u'AdminUISequence', u'Sequence', u'Y', -4, 32767, None, None, None, None, u'Number that determines the sort order in which the actions are to be executed.  Leave blank to suppress action.'),
+(u'AdminUISequence', u'Condition', u'Y', None, None, None, None, u'Condition', None, u'Optional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData.'),
+(u'Condition', u'Condition', u'Y', None, None, None, None, u'Condition', None, u'Expression evaluated to determine if Level in the Feature table is to change.'),
+(u'Condition', u'Feature_', u'N', None, None, u'Feature', 1, u'Identifier', None, u'Reference to a Feature entry in Feature table.'),
+(u'Condition', u'Level', u'N', 0, 32767, None, None, None, None, u'New selection Level to set in Feature table if Condition evaluates to TRUE.'),
+(u'AdvtExecuteSequence', u'Action', u'N', None, None, None, None, u'Identifier', None, u'Name of action to invoke, either in the engine or the handler DLL.'),
+(u'AdvtExecuteSequence', u'Sequence', u'Y', -4, 32767, None, None, None, None, u'Number that determines the sort order in which the actions are to be executed.  Leave blank to suppress action.'),
+(u'AdvtExecuteSequence', u'Condition', u'Y', None, None, None, None, u'Condition', None, u'Optional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData.'),
+(u'BBControl', u'Type', u'N', None, None, None, None, u'Identifier', None, u'The type of the control.'),
+(u'BBControl', u'BBControl', u'N', None, None, None, None, u'Identifier', None, u'Name of the control. This name must be unique within a billboard, but can repeat on different billboard.'),
+(u'BBControl', u'Billboard_', u'N', None, None, u'Billboard', 1, u'Identifier', None, u'External key to the Billboard table, name of the billboard.'),
+(u'BBControl', u'X', u'N', 0, 32767, None, None, None, None, u'Horizontal coordinate of the upper left corner of the bounding rectangle of the control.'),
+(u'BBControl', u'Y', u'N', 0, 32767, None, None, None, None, u'Vertical coordinate of the upper left corner of the bounding rectangle of the control.'),
+(u'BBControl', u'Width', u'N', 0, 32767, None, None, None, None, u'Width of the bounding rectangle of the control.'),
+(u'BBControl', u'Height', u'N', 0, 32767, None, None, None, None, u'Height of the bounding rectangle of the control.'),
+(u'BBControl', u'Attributes', u'Y', 0, 2147483647, None, None, None, None, u'A 32-bit word that specifies the attribute flags to be applied to this control.'),
+(u'BBControl', u'Text', u'Y', None, None, None, None, u'Text', None, u'A string used to set the initial text contained within a control (if appropriate).'),
+(u'Billboard', u'Action', u'Y', None, None, None, None, u'Identifier', None, u'The name of an action. The billboard is displayed during the progress messages received from this action.'),
+(u'Billboard', u'Billboard', u'N', None, None, None, None, u'Identifier', None, u'Name of the billboard.'),
+(u'Billboard', u'Feature_', u'N', None, None, u'Feature', 1, u'Identifier', None, u'An external key to the Feature Table. The billboard is shown only if this feature is being installed.'),
+(u'Billboard', u'Ordering', u'Y', 0, 32767, None, None, None, None, u'A positive integer. If there is more than one billboard corresponding to an action they will be shown in the order defined by this column.'),
+(u'Binary', u'Name', u'N', None, None, None, None, u'Identifier', None, u'Unique key identifying the binary data.'),
+(u'Binary', u'Data', u'N', None, None, None, None, u'Binary', None, u'The unformatted binary data.'),
+(u'CheckBox', u'Property', u'N', None, None, None, None, u'Identifier', None, u'A named property to be tied to the item.'),
+(u'CheckBox', u'Value', u'Y', None, None, None, None, u'Formatted', None, u'The value string associated with the item.'),
+(u'Property', u'Property', u'N', None, None, None, None, u'Identifier', None, u'Name of property, uppercase if settable by launcher or loader.'),
+(u'Property', u'Value', u'N', None, None, None, None, u'Text', None, u'String value for property.  Never null or empty.'),
+(u'ComboBox', u'Text', u'Y', None, None, None, None, u'Formatted', None, u'The visible text to be assigned to the item. Optional. If this entry or the entire column is missing, the text is the same as the value.'),
+(u'ComboBox', u'Property', u'N', None, None, None, None, u'Identifier', None, u'A named property to be tied to this item. All the items tied to the same property become part of the same combobox.'),
+(u'ComboBox', u'Value', u'N', None, None, None, None, u'Formatted', None, u'The value string associated with this item. Selecting the line will set the associated property to this value.'),
+(u'ComboBox', u'Order', u'N', 1, 32767, None, None, None, None, u'A positive integer used to determine the ordering of the items within one list.\tThe integers do not have to be consecutive.'),
+(u'Control', u'Type', u'N', None, None, None, None, u'Identifier', None, u'The type of the control.'),
+(u'Control', u'X', u'N', 0, 32767, None, None, None, None, u'Horizontal coordinate of the upper left corner of the bounding rectangle of the control.'),
+(u'Control', u'Y', u'N', 0, 32767, None, None, None, None, u'Vertical coordinate of the upper left corner of the bounding rectangle of the control.'),
+(u'Control', u'Width', u'N', 0, 32767, None, None, None, None, u'Width of the bounding rectangle of the control.'),
+(u'Control', u'Height', u'N', 0, 32767, None, None, None, None, u'Height of the bounding rectangle of the control.'),
+(u'Control', u'Attributes', u'Y', 0, 2147483647, None, None, None, None, u'A 32-bit word that specifies the attribute flags to be applied to this control.'),
+(u'Control', u'Text', u'Y', None, None, None, None, u'Formatted', None, u'A string used to set the initial text contained within a control (if appropriate).'),
+(u'Control', u'Property', u'Y', None, None, None, None, u'Identifier', None, u'The name of a defined property to be linked to this control. '),
+(u'Control', u'Control', u'N', None, None, None, None, u'Identifier', None, u'Name of the control. This name must be unique within a dialog, but can repeat on different dialogs. '),
+(u'Control', u'Dialog_', u'N', None, None, u'Dialog', 1, u'Identifier', None, u'External key to the Dialog table, name of the dialog.'),
+(u'Control', u'Control_Next', u'Y', None, None, u'Control', 2, u'Identifier', None, u'The name of an other control on the same dialog. This link defines the tab order of the controls. The links have to form one or more cycles!'),
+(u'Control', u'Help', u'Y', None, None, None, None, u'Text', None, u'The help strings used with the button. The text is optional. '),
+(u'Icon', u'Name', u'N', None, None, None, None, u'Identifier', None, u'Primary key. Name of the icon file.'),
+(u'Icon', u'Data', u'N', None, None, None, None, u'Binary', None, u'Binary stream. The binary icon data in PE (.DLL or .EXE) or icon (.ICO) format.'),
+(u'ListBox', u'Text', u'Y', None, None, None, None, u'Text', None, u'The visible text to be assigned to the item. Optional. If this entry or the entire column is missing, the text is the same as the value.'),
+(u'ListBox', u'Property', u'N', None, None, None, None, u'Identifier', None, u'A named property to be tied to this item. All the items tied to the same property become part of the same listbox.'),
+(u'ListBox', u'Value', u'N', None, None, None, None, u'Formatted', None, u'The value string associated with this item. Selecting the line will set the associated property to this value.'),
+(u'ListBox', u'Order', u'N', 1, 32767, None, None, None, None, u'A positive integer used to determine the ordering of the items within one list..The integers do not have to be consecutive.'),
+(u'ActionText', u'Action', u'N', None, None, None, None, u'Identifier', None, u'Name of action to be described.'),
+(u'ActionText', u'Description', u'Y', None, None, None, None, u'Text', None, u'Localized description displayed in progress dialog and log when action is executing.'),
+(u'ActionText', u'Template', u'Y', None, None, None, None, u'Template', None, u'Optional localized format template used to format action data records for display during action execution.'),
+(u'ControlCondition', u'Action', u'N', None, None, None, None, None, u'Default;Disable;Enable;Hide;Show', u'The desired action to be taken on the specified control.'),
+(u'ControlCondition', u'Condition', u'N', None, None, None, None, u'Condition', None, u'A standard conditional statement that specifies under which conditions the action should be triggered.'),
+(u'ControlCondition', u'Dialog_', u'N', None, None, u'Dialog', 1, u'Identifier', None, u'A foreign key to the Dialog table, name of the dialog.'),
+(u'ControlCondition', u'Control_', u'N', None, None, u'Control', 2, u'Identifier', None, u'A foreign key to the Control table, name of the control.'),
+(u'ControlEvent', u'Condition', u'Y', None, None, None, None, u'Condition', None, u'A standard conditional statement that specifies under which conditions an event should be triggered.'),
+(u'ControlEvent', u'Ordering', u'Y', 0, 2147483647, None, None, None, None, u'An integer used to order several events tied to the same control. Can be left blank.'),
+(u'ControlEvent', u'Dialog_', u'N', None, None, u'Dialog', 1, u'Identifier', None, u'A foreign key to the Dialog table, name of the dialog.'),
+(u'ControlEvent', u'Control_', u'N', None, None, u'Control', 2, u'Identifier', None, u'A foreign key to the Control table, name of the control'),
+(u'ControlEvent', u'Event', u'N', None, None, None, None, u'Formatted', None, u'An identifier that specifies the type of the event that should take place when the user interacts with control specified by the first two entries.'),
+(u'ControlEvent', u'Argument', u'N', None, None, None, None, u'Formatted', None, u'A value to be used as a modifier when triggering a particular event.'),
+(u'Dialog', u'Width', u'N', 0, 32767, None, None, None, None, u'Width of the bounding rectangle of the dialog.'),
+(u'Dialog', u'Height', u'N', 0, 32767, None, None, None, None, u'Height of the bounding rectangle of the dialog.'),
+(u'Dialog', u'Attributes', u'Y', 0, 2147483647, None, None, None, None, u'A 32-bit word that specifies the attribute flags to be applied to this dialog.'),
+(u'Dialog', u'Title', u'Y', None, None, None, None, u'Formatted', None, u"A text string specifying the title to be displayed in the title bar of the dialog's window."),
+(u'Dialog', u'Dialog', u'N', None, None, None, None, u'Identifier', None, u'Name of the dialog.'),
+(u'Dialog', u'HCentering', u'N', 0, 100, None, None, None, None, u'Horizontal position of the dialog on a 0-100 scale. 0 means left end, 100 means right end of the screen, 50 center.'),
+(u'Dialog', u'VCentering', u'N', 0, 100, None, None, None, None, u'Vertical position of the dialog on a 0-100 scale. 0 means top end, 100 means bottom end of the screen, 50 center.'),
+(u'Dialog', u'Control_First', u'N', None, None, u'Control', 2, u'Identifier', None, u'Defines the control that has the focus when the dialog is created.'),
+(u'Dialog', u'Control_Default', u'Y', None, None, u'Control', 2, u'Identifier', None, u'Defines the default control. Hitting return is equivalent to pushing this button.'),
+(u'Dialog', u'Control_Cancel', u'Y', None, None, u'Control', 2, u'Identifier', None, u'Defines the cancel control. Hitting escape or clicking on the close icon on the dialog is equivalent to pushing this button.'),
+(u'EventMapping', u'Dialog_', u'N', None, None, u'Dialog', 1, u'Identifier', None, u'A foreign key to the Dialog table, name of the Dialog.'),
+(u'EventMapping', u'Control_', u'N', None, None, u'Control', 2, u'Identifier', None, u'A foreign key to the Control table, name of the control.'),
+(u'EventMapping', u'Event', u'N', None, None, None, None, u'Identifier', None, u'An identifier that specifies the type of the event that the control subscribes to.'),
+(u'EventMapping', u'Attribute', u'N', None, None, None, None, u'Identifier', None, u'The name of the control attribute, that is set when this event is received.'),
+(u'InstallExecuteSequence', u'Action', u'N', None, None, None, None, u'Identifier', None, u'Name of action to invoke, either in the engine or the handler DLL.'),
+(u'InstallExecuteSequence', u'Sequence', u'Y', -4, 32767, None, None, None, None, u'Number that determines the sort order in which the actions are to be executed.  Leave blank to suppress action.'),
+(u'InstallExecuteSequence', u'Condition', u'Y', None, None, None, None, u'Condition', None, u'Optional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData.'),
+(u'AppSearch', u'Property', u'N', None, None, None, None, u'Identifier', None, u'The property associated with a Signature'),
+(u'AppSearch', u'Signature_', u'N', None, None, u'Signature;RegLocator;IniLocator;DrLocator;CompLocator', 1, u'Identifier', None, u'The Signature_ represents a unique file signature and is also the foreign key in the Signature,  RegLocator, IniLocator, CompLocator and the DrLocator tables.'),
+(u'BindImage', u'File_', u'N', None, None, u'File', 1, u'Identifier', None, u'The index into the File table. This must be an executable file.'),
+(u'BindImage', u'Path', u'Y', None, None, None, None, u'Paths', None, u'A list of ;  delimited paths that represent the paths to be searched for the import DLLS. The list is usually a list of properties each enclosed within square brackets [] .'),
+(u'CCPSearch', u'Signature_', u'N', None, None, u'Signature;RegLocator;IniLocator;DrLocator;CompLocator', 1, u'Identifier', None, u'The Signature_ represents a unique file signature and is also the foreign key in the Signature,  RegLocator, IniLocator, CompLocator and the DrLocator tables.'),
+(u'InstallUISequence', u'Action', u'N', None, None, None, None, u'Identifier', None, u'Name of action to invoke, either in the engine or the handler DLL.'),
+(u'InstallUISequence', u'Sequence', u'Y', -4, 32767, None, None, None, None, u'Number that determines the sort order in which the actions are to be executed.  Leave blank to suppress action.'),
+(u'InstallUISequence', u'Condition', u'Y', None, None, None, None, u'Condition', None, u'Optional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData.'),
+(u'ListView', u'Text', u'Y', None, None, None, None, u'Text', None, u'The visible text to be assigned to the item. Optional. If this entry or the entire column is missing, the text is the same as the value.'),
+(u'ListView', u'Property', u'N', None, None, None, None, u'Identifier', None, u'A named property to be tied to this item. All the items tied to the same property become part of the same listview.'),
+(u'ListView', u'Value', u'N', None, None, None, None, u'Identifier', None, u'The value string associated with this item. Selecting the line will set the associated property to this value.'),
+(u'ListView', u'Order', u'N', 1, 32767, None, None, None, None, u'A positive integer used to determine the ordering of the items within one list..The integers do not have to be consecutive.'),
+(u'ListView', u'Binary_', u'Y', None, None, u'Binary', 1, u'Identifier', None, u'The name of the icon to be displayed with the icon. The binary information is looked up from the Binary Table.'),
+(u'RadioButton', u'X', u'N', 0, 32767, None, None, None, None, u'The horizontal coordinate of the upper left corner of the bounding rectangle of the radio button.'),
+(u'RadioButton', u'Y', u'N', 0, 32767, None, None, None, None, u'The vertical coordinate of the upper left corner of the bounding rectangle of the radio button.'),
+(u'RadioButton', u'Width', u'N', 0, 32767, None, None, None, None, u'The width of the button.'),
+(u'RadioButton', u'Height', u'N', 0, 32767, None, None, None, None, u'The height of the button.'),
+(u'RadioButton', u'Text', u'Y', None, None, None, None, u'Text', None, u'The visible title to be assigned to the radio button.'),
+(u'RadioButton', u'Property', u'N', None, None, None, None, u'Identifier', None, u'A named property to be tied to this radio button. All the buttons tied to the same property become part of the same group.'),
+(u'RadioButton', u'Value', u'N', None, None, None, None, u'Formatted', None, u'The value string associated with this button. Selecting the button will set the associated property to this value.'),
+(u'RadioButton', u'Order', u'N', 1, 32767, None, None, None, None, u'A positive integer used to determine the ordering of the items within one list..The integers do not have to be consecutive.'),
+(u'RadioButton', u'Help', u'Y', None, None, None, None, u'Text', None, u'The help strings used with the button. The text is optional.'),
+(u'TextStyle', u'TextStyle', u'N', None, None, None, None, u'Identifier', None, u'Name of the style. The primary key of this table. This name is embedded in the texts to indicate a style change.'),
+(u'TextStyle', u'FaceName', u'N', None, None, None, None, u'Text', None, u'A string indicating the name of the font used. Required. The string must be at most 31 characters long.'),
+(u'TextStyle', u'Size', u'N', 0, 32767, None, None, None, None, u'The size of the font used. This size is given in our units (1/12 of the system font height). Assuming that the system font is set to 12 point size, this is equivalent to the point size.'),
+(u'TextStyle', u'Color', u'Y', 0, 16777215, None, None, None, None, u'A long integer indicating the color of the string in the RGB format (Red, Green, Blue each 0-255, RGB = R + 256*G + 256^2*B).'),
+(u'TextStyle', u'StyleBits', u'Y', 0, 15, None, None, None, None, u'A combination of style bits.'),
+(u'UIText', u'Text', u'Y', None, None, None, None, u'Text', None, u'The localized version of the string.'),
+(u'UIText', u'Key', u'N', None, None, None, None, u'Identifier', None, u'A unique key that identifies the particular string.'),
+(u'_Validation', u'Table', u'N', None, None, None, None, u'Identifier', None, u'Name of table'),
+(u'_Validation', u'Description', u'Y', None, None, None, None, u'Text', None, u'Description of column'),
+(u'_Validation', u'Column', u'N', None, None, None, None, u'Identifier', None, u'Name of column'),
+(u'_Validation', u'Nullable', u'N', None, None, None, None, None, u'Y;N;@', u'Whether the column is nullable'),
+(u'_Validation', u'MinValue', u'Y', -2147483647, 2147483647, None, None, None, None, u'Minimum value allowed'),
+(u'_Validation', u'MaxValue', u'Y', -2147483647, 2147483647, None, None, None, None, u'Maximum value allowed'),
+(u'_Validation', u'KeyTable', u'Y', None, None, None, None, u'Identifier', None, u'For foreign key, Name of table to which data must link'),
+(u'_Validation', u'KeyColumn', u'Y', 1, 32, None, None, None, None, u'Column to which foreign key connects'),
+(u'_Validation', u'Category', u'Y', None, None, None, None, None, u'Text;Formatted;Template;Condition;Guid;Path;Version;Language;Identifier;Binary;UpperCase;LowerCase;Filename;Paths;AnyPath;WildCardFilename;RegPath;KeyFormatted;CustomSource;Property;Cabinet;Shortcut;URL', u'String category'),
+(u'_Validation', u'Set', u'Y', None, None, None, None, u'Text', None, u'Set of values that are permitted'),
+(u'AdvtUISequence', u'Action', u'N', None, None, None, None, u'Identifier', None, u'Name of action to invoke, either in the engine or the handler DLL.'),
+(u'AdvtUISequence', u'Sequence', u'Y', -4, 32767, None, None, None, None, u'Number that determines the sort order in which the actions are to be executed.  Leave blank to suppress action.'),
+(u'AdvtUISequence', u'Condition', u'Y', None, None, None, None, u'Condition', None, u'Optional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData.'),
+(u'AppId', u'AppId', u'N', None, None, None, None, u'Guid', None, None),
+(u'AppId', u'ActivateAtStorage', u'Y', 0, 1, None, None, None, None, None),
+(u'AppId', u'DllSurrogate', u'Y', None, None, None, None, u'Text', None, None),
+(u'AppId', u'LocalService', u'Y', None, None, None, None, u'Text', None, None),
+(u'AppId', u'RemoteServerName', u'Y', None, None, None, None, u'Formatted', None, None),
+(u'AppId', u'RunAsInteractiveUser', u'Y', 0, 1, None, None, None, None, None),
+(u'AppId', u'ServiceParameters', u'Y', None, None, None, None, u'Text', None, None),
+(u'Feature', u'Attributes', u'N', None, None, None, None, None, u'0;1;2;4;5;6;8;9;10;16;17;18;20;21;22;24;25;26;32;33;34;36;37;38;48;49;50;52;53;54', u'Feature attributes'),
+(u'Feature', u'Description', u'Y', None, None, None, None, u'Text', None, u'Longer descriptive text describing a visible feature item.'),
+(u'Feature', u'Title', u'Y', None, None, None, None, u'Text', None, u'Short text identifying a visible feature item.'),
+(u'Feature', u'Feature', u'N', None, None, None, None, u'Identifier', None, u'Primary key used to identify a particular feature record.'),
+(u'Feature', u'Directory_', u'Y', None, None, u'Directory', 1, u'UpperCase', None, u'The name of the Directory that can be configured by the UI. A non-null value will enable the browse button.'),
+(u'Feature', u'Level', u'N', 0, 32767, None, None, None, None, u'The install level at which record will be initially selected. An install level of 0 will disable an item and prevent its display.'),
+(u'Feature', u'Display', u'Y', 0, 32767, None, None, None, None, u'Numeric sort order, used to force a specific display ordering.'),
+(u'Feature', u'Feature_Parent', u'Y', None, None, u'Feature', 1, u'Identifier', None, u'Optional key of a parent record in the same table. If the parent is not selected, then the record will not be installed. Null indicates a root item.'),
+(u'File', u'Sequence', u'N', 1, 32767, None, None, None, None, u'Sequence with respect to the media images; order must track cabinet order.'),
+(u'File', u'Attributes', u'Y', 0, 32767, None, None, None, None, u'Integer containing bit flags representing file attributes (with the decimal value of each bit position in parentheses)'),
+(u'File', u'File', u'N', None, None, None, None, u'Identifier', None, u'Primary key, non-localized token, must match identifier in cabinet.  For uncompressed files, this field is ignored.'),
+(u'File', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Foreign key referencing Component that controls the file.'),
+(u'File', u'FileName', u'N', None, None, None, None, u'Filename', None, u'File name used for installation, may be localized.  This may contain a "short name|long name" pair.'),
+(u'File', u'FileSize', u'N', 0, 2147483647, None, None, None, None, u'Size of file in bytes (long integer).'),
+(u'File', u'Language', u'Y', None, None, None, None, u'Language', None, u'List of decimal language Ids, comma-separated if more than one.'),
+(u'File', u'Version', u'Y', None, None, u'File', 1, u'Version', None, u'Version string for versioned files;  Blank for unversioned files.'),
+(u'Class', u'Attributes', u'Y', None, 32767, None, None, None, None, u'Class registration attributes.'),
+(u'Class', u'Feature_', u'N', None, None, u'Feature', 1, u'Identifier', None, u'Required foreign key into the Feature Table, specifying the feature to validate or install in order for the CLSID factory to be operational.'),
+(u'Class', u'Description', u'Y', None, None, None, None, u'Text', None, u'Localized description for the Class.'),
+(u'Class', u'Argument', u'Y', None, None, None, None, u'Formatted', None, u'optional argument for LocalServers.'),
+(u'Class', u'AppId_', u'Y', None, None, u'AppId', 1, u'Guid', None, u'Optional AppID containing DCOM information for associated application (string GUID).'),
+(u'Class', u'CLSID', u'N', None, None, None, None, u'Guid', None, u'The CLSID of an OLE factory.'),
+(u'Class', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Required foreign key into the Component Table, specifying the component for which to return a path when called through LocateComponent.'),
+(u'Class', u'Context', u'N', None, None, None, None, u'Identifier', None, u'The numeric server context for this server. CLSCTX_xxxx'),
+(u'Class', u'DefInprocHandler', u'Y', None, None, None, None, u'Filename', u'1;2;3', u'Optional default inproc handler.  Only optionally provided if Context=CLSCTX_LOCAL_SERVER.  Typically "ole32.dll" or "mapi32.dll"'),
+(u'Class', u'FileTypeMask', u'Y', None, None, None, None, u'Text', None, u'Optional string containing information for the HKCRthis CLSID) key. If multiple patterns exist, they must be delimited by a semicolon, and numeric subkeys will be generated: 0,1,2...'),
+(u'Class', u'Icon_', u'Y', None, None, u'Icon', 1, u'Identifier', None, u'Optional foreign key into the Icon Table, specifying the icon file associated with this CLSID. Will be written under the DefaultIcon key.'),
+(u'Class', u'IconIndex', u'Y', -32767, 32767, None, None, None, None, u'Optional icon index.'),
+(u'Class', u'ProgId_Default', u'Y', None, None, u'ProgId', 1, u'Text', None, u'Optional ProgId associated with this CLSID.'),
+(u'Component', u'Condition', u'Y', None, None, None, None, u'Condition', None, u"A conditional statement that will disable this component if the specified condition evaluates to the 'True' state. If a component is disabled, it will not be installed, regardless of the 'Action' state associated with the component."),
+(u'Component', u'Attributes', u'N', None, None, None, None, None, None, u'Remote execution option, one of irsEnum'),
+(u'Component', u'Component', u'N', None, None, None, None, u'Identifier', None, u'Primary key used to identify a particular component record.'),
+(u'Component', u'ComponentId', u'Y', None, None, None, None, u'Guid', None, u'A string GUID unique to this component, version, and language.'),
+(u'Component', u'Directory_', u'N', None, None, u'Directory', 1, u'Identifier', None, u'Required key of a Directory table record. This is actually a property name whose value contains the actual path, set either by the AppSearch action or with the default setting obtained from the Directory table.'),
+(u'Component', u'KeyPath', u'Y', None, None, u'File;Registry;ODBCDataSource', 1, u'Identifier', None, u'Either the primary key into the File table, Registry table, or ODBCDataSource table. This extract path is stored when the component is installed, and is used to detect the presence of the component and to return the path to it.'),
+(u'ProgId', u'Description', u'Y', None, None, None, None, u'Text', None, u'Localized description for the Program identifier.'),
+(u'ProgId', u'Icon_', u'Y', None, None, u'Icon', 1, u'Identifier', None, u'Optional foreign key into the Icon Table, specifying the icon file associated with this ProgId. Will be written under the DefaultIcon key.'),
+(u'ProgId', u'IconIndex', u'Y', -32767, 32767, None, None, None, None, u'Optional icon index.'),
+(u'ProgId', u'ProgId', u'N', None, None, None, None, u'Text', None, u'The Program Identifier. Primary key.'),
+(u'ProgId', u'Class_', u'Y', None, None, u'Class', 1, u'Guid', None, u'The CLSID of an OLE factory corresponding to the ProgId.'),
+(u'ProgId', u'ProgId_Parent', u'Y', None, None, u'ProgId', 1, u'Text', None, u'The Parent Program Identifier. If specified, the ProgId column becomes a version independent prog id.'),
+(u'CompLocator', u'Type', u'Y', 0, 1, None, None, None, None, u'A boolean value that determines if the registry value is a filename or a directory location.'),
+(u'CompLocator', u'Signature_', u'N', None, None, None, None, u'Identifier', None, u'The table key. The Signature_ represents a unique file signature and is also the foreign key in the Signature table.'),
+(u'CompLocator', u'ComponentId', u'N', None, None, None, None, u'Guid', None, u'A string GUID unique to this component, version, and language.'),
+(u'Complus', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Foreign key referencing Component that controls the ComPlus component.'),
+(u'Complus', u'ExpType', u'Y', 0, 32767, None, None, None, None, u'ComPlus component attributes.'),
+(u'Directory', u'Directory', u'N', None, None, None, None, u'Identifier', None, u'Unique identifier for directory entry, primary key. If a property by this name is defined, it contains the full path to the directory.'),
+(u'Directory', u'DefaultDir', u'N', None, None, None, None, u'DefaultDir', None, u"The default sub-path under parent's path."),
+(u'Directory', u'Directory_Parent', u'Y', None, None, u'Directory', 1, u'Identifier', None, u'Reference to the entry in this table specifying the default parent directory. A record parented to itself or with a Null parent represents a root of the install tree.'),
+(u'CreateFolder', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Foreign key into the Component table.'),
+(u'CreateFolder', u'Directory_', u'N', None, None, u'Directory', 1, u'Identifier', None, u'Primary key, could be foreign key into the Directory table.'),
+(u'CustomAction', u'Type', u'N', 1, 16383, None, None, None, None, u'The numeric custom action type, consisting of source location, code type, entry, option flags.'),
+(u'CustomAction', u'Action', u'N', None, None, None, None, u'Identifier', None, u'Primary key, name of action, normally appears in sequence table unless private use.'),
+(u'CustomAction', u'Source', u'Y', None, None, None, None, u'CustomSource', None, u'The table reference of the source of the code.'),
+(u'CustomAction', u'Target', u'Y', None, None, None, None, u'Formatted', None, u'Excecution parameter, depends on the type of custom action'),
+(u'DrLocator', u'Signature_', u'N', None, None, None, None, u'Identifier', None, u'The Signature_ represents a unique file signature and is also the foreign key in the Signature table.'),
+(u'DrLocator', u'Path', u'Y', None, None, None, None, u'AnyPath', None, u'The path on the user system. This is a either a subpath below the value of the Parent or a full path. The path may contain properties enclosed within [ ] that will be expanded.'),
+(u'DrLocator', u'Depth', u'Y', 0, 32767, None, None, None, None, u'The depth below the path to which the Signature_ is recursively searched. If absent, the depth is assumed to be 0.'),
+(u'DrLocator', u'Parent', u'Y', None, None, None, None, u'Identifier', None, u'The parent file signature. It is also a foreign key in the Signature table. If null and the Path column does not expand to a full path, then all the fixed drives of the user system are searched using the Path.'),
+(u'DuplicateFile', u'File_', u'N', None, None, u'File', 1, u'Identifier', None, u'Foreign key referencing the source file to be duplicated.'),
+(u'DuplicateFile', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Foreign key referencing Component that controls the duplicate file.'),
+(u'DuplicateFile', u'DestFolder', u'Y', None, None, None, None, u'Identifier', None, u'Name of a property whose value is assumed to resolve to the full pathname to a destination folder.'),
+(u'DuplicateFile', u'DestName', u'Y', None, None, None, None, u'Filename', None, u'Filename to be given to the duplicate file.'),
+(u'DuplicateFile', u'FileKey', u'N', None, None, None, None, u'Identifier', None, u'Primary key used to identify a particular file entry'),
+(u'Environment', u'Name', u'N', None, None, None, None, u'Text', None, u'The name of the environmental value.'),
+(u'Environment', u'Value', u'Y', None, None, None, None, u'Formatted', None, u'The value to set in the environmental settings.'),
+(u'Environment', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Foreign key into the Component table referencing component that controls the installing of the environmental value.'),
+(u'Environment', u'Environment', u'N', None, None, None, None, u'Identifier', None, u'Unique identifier for the environmental variable setting'),
+(u'Error', u'Error', u'N', 0, 32767, None, None, None, None, u'Integer error number, obtained from header file IError(...) macros.'),
+(u'Error', u'Message', u'Y', None, None, None, None, u'Template', None, u'Error formatting template, obtained from user ed. or localizers.'),
+(u'Extension', u'Feature_', u'N', None, None, u'Feature', 1, u'Identifier', None, u'Required foreign key into the Feature Table, specifying the feature to validate or install in order for the CLSID factory to be operational.'),
+(u'Extension', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Required foreign key into the Component Table, specifying the component for which to return a path when called through LocateComponent.'),
+(u'Extension', u'Extension', u'N', None, None, None, None, u'Text', None, u'The extension associated with the table row.'),
+(u'Extension', u'MIME_', u'Y', None, None, u'MIME', 1, u'Text', None, u'Optional Context identifier, typically "type/format" associated with the extension'),
+(u'Extension', u'ProgId_', u'Y', None, None, u'ProgId', 1, u'Text', None, u'Optional ProgId associated with this extension.'),
+(u'MIME', u'CLSID', u'Y', None, None, None, None, u'Guid', None, u'Optional associated CLSID.'),
+(u'MIME', u'ContentType', u'N', None, None, None, None, u'Text', None, u'Primary key. Context identifier, typically "type/format".'),
+(u'MIME', u'Extension_', u'N', None, None, u'Extension', 1, u'Text', None, u'Optional associated extension (without dot)'),
+(u'FeatureComponents', u'Feature_', u'N', None, None, u'Feature', 1, u'Identifier', None, u'Foreign key into Feature table.'),
+(u'FeatureComponents', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Foreign key into Component table.'),
+(u'FileSFPCatalog', u'File_', u'N', None, None, u'File', 1, u'Identifier', None, u'File associated with the catalog'),
+(u'FileSFPCatalog', u'SFPCatalog_', u'N', None, None, u'SFPCatalog', 1, u'Filename', None, u'Catalog associated with the file'),
+(u'SFPCatalog', u'SFPCatalog', u'N', None, None, None, None, u'Filename', None, u'File name for the catalog.'),
+(u'SFPCatalog', u'Catalog', u'N', None, None, None, None, u'Binary', None, u'SFP Catalog'),
+(u'SFPCatalog', u'Dependency', u'Y', None, None, None, None, u'Formatted', None, u'Parent catalog - only used by SFP'),
+(u'Font', u'File_', u'N', None, None, u'File', 1, u'Identifier', None, u'Primary key, foreign key into File table referencing font file.'),
+(u'Font', u'FontTitle', u'Y', None, None, None, None, u'Text', None, u'Font name.'),
+(u'IniFile', u'Action', u'N', None, None, None, None, None, u'0;1;3', u'The type of modification to be made, one of iifEnum'),
+(u'IniFile', u'Value', u'N', None, None, None, None, u'Formatted', None, u'The value to be written.'),
+(u'IniFile', u'Key', u'N', None, None, None, None, u'Formatted', None, u'The .INI file key below Section.'),
+(u'IniFile', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Foreign key into the Component table referencing component that controls the installing of the .INI value.'),
+(u'IniFile', u'FileName', u'N', None, None, None, None, u'Filename', None, u'The .INI file name in which to write the information'),
+(u'IniFile', u'IniFile', u'N', None, None, None, None, u'Identifier', None, u'Primary key, non-localized token.'),
+(u'IniFile', u'DirProperty', u'Y', None, None, None, None, u'Identifier', None, u'Foreign key into the Directory table denoting the directory where the .INI file is.'),
+(u'IniFile', u'Section', u'N', None, None, None, None, u'Formatted', None, u'The .INI file Section.'),
+(u'IniLocator', u'Type', u'Y', 0, 2, None, None, None, None, u'An integer value that determines if the .INI value read is a filename or a directory location or to be used as is w/o interpretation.'),
+(u'IniLocator', u'Key', u'N', None, None, None, None, u'Text', None, u'Key value (followed by an equals sign in INI file).'),
+(u'IniLocator', u'Signature_', u'N', None, None, None, None, u'Identifier', None, u'The table key. The Signature_ represents a unique file signature and is also the foreign key in the Signature table.'),
+(u'IniLocator', u'FileName', u'N', None, None, None, None, u'Filename', None, u'The .INI file name.'),
+(u'IniLocator', u'Section', u'N', None, None, None, None, u'Text', None, u'Section name within in file (within square brackets in INI file).'),
+(u'IniLocator', u'Field', u'Y', 0, 32767, None, None, None, None, u'The field in the .INI line. If Field is null or 0 the entire line is read.'),
+(u'IsolatedComponent', u'Component_Application', u'N', None, None, u'Component', 1, u'Identifier', None, u'Key to Component table item for application'),
+(u'IsolatedComponent', u'Component_Shared', u'N', None, None, u'Component', 1, u'Identifier', None, u'Key to Component table item to be isolated'),
+(u'LaunchCondition', u'Condition', u'N', None, None, None, None, u'Condition', None, u'Expression which must evaluate to TRUE in order for install to commence.'),
+(u'LaunchCondition', u'Description', u'N', None, None, None, None, u'Formatted', None, u'Localizable text to display when condition fails and install must abort.'),
+(u'LockPermissions', u'Table', u'N', None, None, None, None, u'Identifier', u'Directory;File;Registry', u'Reference to another table name'),
+(u'LockPermissions', u'Domain', u'Y', None, None, None, None, u'Formatted', None, u'Domain name for user whose permissions are being set. (usually a property)'),
+(u'LockPermissions', u'LockObject', u'N', None, None, None, None, u'Identifier', None, u'Foreign key into Registry or File table'),
+(u'LockPermissions', u'Permission', u'Y', -2147483647, 2147483647, None, None, None, None, u'Permission Access mask.  Full Control = 268435456 (GENERIC_ALL = 0x10000000)'),
+(u'LockPermissions', u'User', u'N', None, None, None, None, u'Formatted', None, u'User for permissions to be set.  (usually a property)'),
+(u'Media', u'Source', u'Y', None, None, None, None, u'Property', None, u'The property defining the location of the cabinet file.'),
+(u'Media', u'Cabinet', u'Y', None, None, None, None, u'Cabinet', None, u'If some or all of the files stored on the media are compressed in a cabinet, the name of that cabinet.'),
+(u'Media', u'DiskId', u'N', 1, 32767, None, None, None, None, u'Primary key, integer to determine sort order for table.'),
+(u'Media', u'DiskPrompt', u'Y', None, None, None, None, u'Text', None, u'Disk name: the visible text actually printed on the disk.  This will be used to prompt the user when this disk needs to be inserted.'),
+(u'Media', u'LastSequence', u'N', 0, 32767, None, None, None, None, u'File sequence number for the last file for this media.'),
+(u'Media', u'VolumeLabel', u'Y', None, None, None, None, u'Text', None, u'The label attributed to the volume.'),
+(u'ModuleComponents', u'Component', u'N', None, None, u'Component', 1, u'Identifier', None, u'Component contained in the module.'),
+(u'ModuleComponents', u'Language', u'N', None, None, u'ModuleSignature', 2, None, None, u'Default language ID for module (may be changed by transform).'),
+(u'ModuleComponents', u'ModuleID', u'N', None, None, u'ModuleSignature', 1, u'Identifier', None, u'Module containing the component.'),
+(u'ModuleSignature', u'Language', u'N', None, None, None, None, None, None, u'Default decimal language of module.'),
+(u'ModuleSignature', u'Version', u'N', None, None, None, None, u'Version', None, u'Version of the module.'),
+(u'ModuleSignature', u'ModuleID', u'N', None, None, None, None, u'Identifier', None, u'Module identifier (String.GUID).'),
+(u'ModuleDependency', u'ModuleID', u'N', None, None, u'ModuleSignature', 1, u'Identifier', None, u'Module requiring the dependency.'),
+(u'ModuleDependency', u'ModuleLanguage', u'N', None, None, u'ModuleSignature', 2, None, None, u'Language of module requiring the dependency.'),
+(u'ModuleDependency', u'RequiredID', u'N', None, None, None, None, None, None, u'String.GUID of required module.'),
+(u'ModuleDependency', u'RequiredLanguage', u'N', None, None, None, None, None, None, u'LanguageID of the required module.'),
+(u'ModuleDependency', u'RequiredVersion', u'Y', None, None, None, None, u'Version', None, u'Version of the required version.'),
+(u'ModuleExclusion', u'ModuleID', u'N', None, None, u'ModuleSignature', 1, u'Identifier', None, u'String.GUID of module with exclusion requirement.'),
+(u'ModuleExclusion', u'ModuleLanguage', u'N', None, None, u'ModuleSignature', 2, None, None, u'LanguageID of module with exclusion requirement.'),
+(u'ModuleExclusion', u'ExcludedID', u'N', None, None, None, None, None, None, u'String.GUID of excluded module.'),
+(u'ModuleExclusion', u'ExcludedLanguage', u'N', None, None, None, None, None, None, u'Language of excluded module.'),
+(u'ModuleExclusion', u'ExcludedMaxVersion', u'Y', None, None, None, None, u'Version', None, u'Maximum version of excluded module.'),
+(u'ModuleExclusion', u'ExcludedMinVersion', u'Y', None, None, None, None, u'Version', None, u'Minimum version of excluded module.'),
+(u'MoveFile', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'If this component is not "selected" for installation or removal, no action will be taken on the associated MoveFile entry'),
+(u'MoveFile', u'DestFolder', u'N', None, None, None, None, u'Identifier', None, u'Name of a property whose value is assumed to resolve to the full path to the destination directory'),
+(u'MoveFile', u'DestName', u'Y', None, None, None, None, u'Filename', None, u'Name to be given to the original file after it is moved or copied.  If blank, the destination file will be given the same name as the source file'),
+(u'MoveFile', u'FileKey', u'N', None, None, None, None, u'Identifier', None, u'Primary key that uniquely identifies a particular MoveFile record'),
+(u'MoveFile', u'Options', u'N', 0, 1, None, None, None, None, u'Integer value specifying the MoveFile operating mode, one of imfoEnum'),
+(u'MoveFile', u'SourceFolder', u'Y', None, None, None, None, u'Identifier', None, u'Name of a property whose value is assumed to resolve to the full path to the source directory'),
+(u'MoveFile', u'SourceName', u'Y', None, None, None, None, u'Text', None, u"Name of the source file(s) to be moved or copied.  Can contain the '*' or '?' wildcards."),
+(u'MsiAssembly', u'Attributes', u'Y', None, None, None, None, None, None, u'Assembly attributes'),
+(u'MsiAssembly', u'Feature_', u'N', None, None, u'Feature', 1, u'Identifier', None, u'Foreign key into Feature table.'),
+(u'MsiAssembly', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Foreign key into Component table.'),
+(u'MsiAssembly', u'File_Application', u'Y', None, None, u'File', 1, u'Identifier', None, u'Foreign key into File table, denoting the application context for private assemblies. Null for global assemblies.'),
+(u'MsiAssembly', u'File_Manifest', u'Y', None, None, u'File', 1, u'Identifier', None, u'Foreign key into the File table denoting the manifest file for the assembly.'),
+(u'MsiAssemblyName', u'Name', u'N', None, None, None, None, u'Text', None, u'The name part of the name-value pairs for the assembly name.'),
+(u'MsiAssemblyName', u'Value', u'N', None, None, None, None, u'Text', None, u'The value part of the name-value pairs for the assembly name.'),
+(u'MsiAssemblyName', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Foreign key into Component table.'),
+(u'MsiDigitalCertificate', u'CertData', u'N', None, None, None, None, u'Binary', None, u'A certificate context blob for a signer certificate'),
+(u'MsiDigitalCertificate', u'DigitalCertificate', u'N', None, None, None, None, u'Identifier', None, u'A unique identifier for the row'),
+(u'MsiDigitalSignature', u'Table', u'N', None, None, None, None, None, u'Media', u'Reference to another table name (only Media table is supported)'),
+(u'MsiDigitalSignature', u'DigitalCertificate_', u'N', None, None, u'MsiDigitalCertificate', 1, u'Identifier', None, u'Foreign key to MsiDigitalCertificate table identifying the signer certificate'),
+(u'MsiDigitalSignature', u'Hash', u'Y', None, None, None, None, u'Binary', None, u'The encoded hash blob from the digital signature'),
+(u'MsiDigitalSignature', u'SignObject', u'N', None, None, None, None, u'Text', None, u'Foreign key to Media table'),
+(u'MsiFileHash', u'File_', u'N', None, None, u'File', 1, u'Identifier', None, u'Primary key, foreign key into File table referencing file with this hash'),
+(u'MsiFileHash', u'Options', u'N', 0, 32767, None, None, None, None, u'Various options and attributes for this hash.'),
+(u'MsiFileHash', u'HashPart1', u'N', None, None, None, None, None, None, u'Size of file in bytes (long integer).'),
+(u'MsiFileHash', u'HashPart2', u'N', None, None, None, None, None, None, u'Size of file in bytes (long integer).'),
+(u'MsiFileHash', u'HashPart3', u'N', None, None, None, None, None, None, u'Size of file in bytes (long integer).'),
+(u'MsiFileHash', u'HashPart4', u'N', None, None, None, None, None, None, u'Size of file in bytes (long integer).'),
+(u'MsiPatchHeaders', u'StreamRef', u'N', None, None, None, None, u'Identifier', None, u'Primary key. A unique identifier for the row.'),
+(u'MsiPatchHeaders', u'Header', u'N', None, None, None, None, u'Binary', None, u'Binary stream. The patch header, used for patch validation.'),
+(u'ODBCAttribute', u'Value', u'Y', None, None, None, None, u'Text', None, u'Value for ODBC driver attribute'),
+(u'ODBCAttribute', u'Attribute', u'N', None, None, None, None, u'Text', None, u'Name of ODBC driver attribute'),
+(u'ODBCAttribute', u'Driver_', u'N', None, None, u'ODBCDriver', 1, u'Identifier', None, u'Reference to ODBC driver in ODBCDriver table'),
+(u'ODBCDriver', u'Description', u'N', None, None, None, None, u'Text', None, u'Text used as registered name for driver, non-localized'),
+(u'ODBCDriver', u'File_', u'N', None, None, u'File', 1, u'Identifier', None, u'Reference to key driver file'),
+(u'ODBCDriver', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Reference to associated component'),
+(u'ODBCDriver', u'Driver', u'N', None, None, None, None, u'Identifier', None, u'Primary key, non-localized.internal token for driver'),
+(u'ODBCDriver', u'File_Setup', u'Y', None, None, u'File', 1, u'Identifier', None, u'Optional reference to key driver setup DLL'),
+(u'ODBCDataSource', u'Description', u'N', None, None, None, None, u'Text', None, u'Text used as registered name for data source'),
+(u'ODBCDataSource', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Reference to associated component'),
+(u'ODBCDataSource', u'DataSource', u'N', None, None, None, None, u'Identifier', None, u'Primary key, non-localized.internal token for data source'),
+(u'ODBCDataSource', u'DriverDescription', u'N', None, None, None, None, u'Text', None, u'Reference to driver description, may be existing driver'),
+(u'ODBCDataSource', u'Registration', u'N', 0, 1, None, None, None, None, u'Registration option: 0=machine, 1=user, others t.b.d.'),
+(u'ODBCSourceAttribute', u'Value', u'Y', None, None, None, None, u'Text', None, u'Value for ODBC data source attribute'),
+(u'ODBCSourceAttribute', u'Attribute', u'N', None, None, None, None, u'Text', None, u'Name of ODBC data source attribute'),
+(u'ODBCSourceAttribute', u'DataSource_', u'N', None, None, u'ODBCDataSource', 1, u'Identifier', None, u'Reference to ODBC data source in ODBCDataSource table'),
+(u'ODBCTranslator', u'Description', u'N', None, None, None, None, u'Text', None, u'Text used as registered name for translator'),
+(u'ODBCTranslator', u'File_', u'N', None, None, u'File', 1, u'Identifier', None, u'Reference to key translator file'),
+(u'ODBCTranslator', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Reference to associated component'),
+(u'ODBCTranslator', u'File_Setup', u'Y', None, None, u'File', 1, u'Identifier', None, u'Optional reference to key translator setup DLL'),
+(u'ODBCTranslator', u'Translator', u'N', None, None, None, None, u'Identifier', None, u'Primary key, non-localized.internal token for translator'),
+(u'Patch', u'Sequence', u'N', 0, 32767, None, None, None, None, u'Primary key, sequence with respect to the media images; order must track cabinet order.'),
+(u'Patch', u'Attributes', u'N', 0, 32767, None, None, None, None, u'Integer containing bit flags representing patch attributes'),
+(u'Patch', u'File_', u'N', None, None, None, None, u'Identifier', None, u'Primary key, non-localized token, foreign key to File table, must match identifier in cabinet.'),
+(u'Patch', u'Header', u'Y', None, None, None, None, u'Binary', None, u'Binary stream. The patch header, used for patch validation.'),
+(u'Patch', u'PatchSize', u'N', 0, 2147483647, None, None, None, None, u'Size of patch in bytes (long integer).'),
+(u'Patch', u'StreamRef_', u'Y', None, None, None, None, u'Identifier', None, u'Identifier. Foreign key to the StreamRef column of the MsiPatchHeaders table.'),
+(u'PatchPackage', u'Media_', u'N', 0, 32767, None, None, None, None, u'Foreign key to DiskId column of Media table. Indicates the disk containing the patch package.'),
+(u'PatchPackage', u'PatchId', u'N', None, None, None, None, u'Guid', None, u'A unique string GUID representing this patch.'),
+(u'PublishComponent', u'Feature_', u'N', None, None, u'Feature', 1, u'Identifier', None, u'Foreign key into the Feature table.'),
+(u'PublishComponent', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Foreign key into the Component table.'),
+(u'PublishComponent', u'ComponentId', u'N', None, None, None, None, u'Guid', None, u'A string GUID that represents the component id that will be requested by the alien product.'),
+(u'PublishComponent', u'AppData', u'Y', None, None, None, None, u'Text', None, u'This is localisable Application specific data that can be associated with a Qualified Component.'),
+(u'PublishComponent', u'Qualifier', u'N', None, None, None, None, u'Text', None, u'This is defined only when the ComponentId column is an Qualified Component Id. This is the Qualifier for ProvideComponentIndirect.'),
+(u'Registry', u'Name', u'Y', None, None, None, None, u'Formatted', None, u'The registry value name.'),
+(u'Registry', u'Value', u'Y', None, None, None, None, u'Formatted', None, u'The registry value.'),
+(u'Registry', u'Key', u'N', None, None, None, None, u'RegPath', None, u'The key for the registry value.'),
+(u'Registry', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Foreign key into the Component table referencing component that controls the installing of the registry value.'),
+(u'Registry', u'Registry', u'N', None, None, None, None, u'Identifier', None, u'Primary key, non-localized token.'),
+(u'Registry', u'Root', u'N', -1, 3, None, None, None, None, u'The predefined root key for the registry value, one of rrkEnum.'),
+(u'RegLocator', u'Name', u'Y', None, None, None, None, u'Formatted', None, u'The registry value name.'),
+(u'RegLocator', u'Type', u'Y', 0, 18, None, None, None, None, u'An integer value that determines if the registry value is a filename or a directory location or to be used as is w/o interpretation.'),
+(u'RegLocator', u'Key', u'N', None, None, None, None, u'RegPath', None, u'The key for the registry value.'),
+(u'RegLocator', u'Signature_', u'N', None, None, None, None, u'Identifier', None, u'The table key. The Signature_ represents a unique file signature and is also the foreign key in the Signature table. If the type is 0, the registry values refers a directory, and _Signature is not a foreign key.'),
+(u'RegLocator', u'Root', u'N', 0, 3, None, None, None, None, u'The predefined root key for the registry value, one of rrkEnum.'),
+(u'RemoveFile', u'InstallMode', u'N', None, None, None, None, None, u'1;2;3', u'Installation option, one of iimEnum.'),
+(u'RemoveFile', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Foreign key referencing Component that controls the file to be removed.'),
+(u'RemoveFile', u'FileKey', u'N', None, None, None, None, u'Identifier', None, u'Primary key used to identify a particular file entry'),
+(u'RemoveFile', u'FileName', u'Y', None, None, None, None, u'WildCardFilename', None, u'Name of the file to be removed.'),
+(u'RemoveFile', u'DirProperty', u'N', None, None, None, None, u'Identifier', None, u'Name of a property whose value is assumed to resolve to the full pathname to the folder of the file to be removed.'),
+(u'RemoveIniFile', u'Action', u'N', None, None, None, None, None, u'2;4', u'The type of modification to be made, one of iifEnum.'),
+(u'RemoveIniFile', u'Value', u'Y', None, None, None, None, u'Formatted', None, u'The value to be deleted. The value is required when Action is iifIniRemoveTag'),
+(u'RemoveIniFile', u'Key', u'N', None, None, None, None, u'Formatted', None, u'The .INI file key below Section.'),
+(u'RemoveIniFile', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Foreign key into the Component table referencing component that controls the deletion of the .INI value.'),
+(u'RemoveIniFile', u'FileName', u'N', None, None, None, None, u'Filename', None, u'The .INI file name in which to delete the information'),
+(u'RemoveIniFile', u'DirProperty', u'Y', None, None, None, None, u'Identifier', None, u'Foreign key into the Directory table denoting the directory where the .INI file is.'),
+(u'RemoveIniFile', u'Section', u'N', None, None, None, None, u'Formatted', None, u'The .INI file Section.'),
+(u'RemoveIniFile', u'RemoveIniFile', u'N', None, None, None, None, u'Identifier', None, u'Primary key, non-localized token.'),
+(u'RemoveRegistry', u'Name', u'Y', None, None, None, None, u'Formatted', None, u'The registry value name.'),
+(u'RemoveRegistry', u'Key', u'N', None, None, None, None, u'RegPath', None, u'The key for the registry value.'),
+(u'RemoveRegistry', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Foreign key into the Component table referencing component that controls the deletion of the registry value.'),
+(u'RemoveRegistry', u'Root', u'N', -1, 3, None, None, None, None, u'The predefined root key for the registry value, one of rrkEnum'),
+(u'RemoveRegistry', u'RemoveRegistry', u'N', None, None, None, None, u'Identifier', None, u'Primary key, non-localized token.'),
+(u'ReserveCost', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Reserve a specified amount of space if this component is to be installed.'),
+(u'ReserveCost', u'ReserveFolder', u'Y', None, None, None, None, u'Identifier', None, u'Name of a property whose value is assumed to resolve to the full path to the destination directory'),
+(u'ReserveCost', u'ReserveKey', u'N', None, None, None, None, u'Identifier', None, u'Primary key that uniquely identifies a particular ReserveCost record'),
+(u'ReserveCost', u'ReserveLocal', u'N', 0, 2147483647, None, None, None, None, u'Disk space to reserve if linked component is installed locally.'),
+(u'ReserveCost', u'ReserveSource', u'N', 0, 2147483647, None, None, None, None, u'Disk space to reserve if linked component is installed to run from the source location.'),
+(u'SelfReg', u'File_', u'N', None, None, u'File', 1, u'Identifier', None, u'Foreign key into the File table denoting the module that needs to be registered.'),
+(u'SelfReg', u'Cost', u'Y', 0, 32767, None, None, None, None, u'The cost of registering the module.'),
+(u'ServiceControl', u'Name', u'N', None, None, None, None, u'Formatted', None, u'Name of a service. /, \\, comma and space are invalid'),
+(u'ServiceControl', u'Event', u'N', 0, 187, None, None, None, None, u'Bit field:  Install:  0x1 = Start, 0x2 = Stop, 0x8 = Delete, Uninstall: 0x10 = Start, 0x20 = Stop, 0x80 = Delete'),
+(u'ServiceControl', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Required foreign key into the Component Table that controls the startup of the service'),
+(u'ServiceControl', u'ServiceControl', u'N', None, None, None, None, u'Identifier', None, u'Primary key, non-localized token.'),
+(u'ServiceControl', u'Arguments', u'Y', None, None, None, None, u'Formatted', None, u'Arguments for the service.  Separate by [~].'),
+(u'ServiceControl', u'Wait', u'Y', 0, 1, None, None, None, None, u'Boolean for whether to wait for the service to fully start'),
+(u'ServiceInstall', u'Name', u'N', None, None, None, None, u'Formatted', None, u'Internal Name of the Service'),
+(u'ServiceInstall', u'Description', u'Y', None, None, None, None, u'Text', None, u'Description of service.'),
+(u'ServiceInstall', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Required foreign key into the Component Table that controls the startup of the service'),
+(u'ServiceInstall', u'Arguments', u'Y', None, None, None, None, u'Formatted', None, u'Arguments to include in every start of the service, passed to WinMain'),
+(u'ServiceInstall', u'ServiceInstall', u'N', None, None, None, None, u'Identifier', None, u'Primary key, non-localized token.'),
+(u'ServiceInstall', u'Dependencies', u'Y', None, None, None, None, u'Formatted', None, u'Other services this depends on to start.  Separate by [~], and end with [~][~]'),
+(u'ServiceInstall', u'DisplayName', u'Y', None, None, None, None, u'Formatted', None, u'External Name of the Service'),
+(u'ServiceInstall', u'ErrorControl', u'N', -2147483647, 2147483647, None, None, None, None, u'Severity of error if service fails to start'),
+(u'ServiceInstall', u'LoadOrderGroup', u'Y', None, None, None, None, u'Formatted', None, u'LoadOrderGroup'),
+(u'ServiceInstall', u'Password', u'Y', None, None, None, None, u'Formatted', None, u'password to run service with.  (with StartName)'),
+(u'ServiceInstall', u'ServiceType', u'N', -2147483647, 2147483647, None, None, None, None, u'Type of the service'),
+(u'ServiceInstall', u'StartName', u'Y', None, None, None, None, u'Formatted', None, u'User or object name to run service as'),
+(u'ServiceInstall', u'StartType', u'N', 0, 4, None, None, None, None, u'Type of the service'),
+(u'Shortcut', u'Name', u'N', None, None, None, None, u'Filename', None, u'The name of the shortcut to be created.'),
+(u'Shortcut', u'Description', u'Y', None, None, None, None, u'Text', None, u'The description for the shortcut.'),
+(u'Shortcut', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Foreign key into the Component table denoting the component whose selection gates the the shortcut creation/deletion.'),
+(u'Shortcut', u'Icon_', u'Y', None, None, u'Icon', 1, u'Identifier', None, u'Foreign key into the File table denoting the external icon file for the shortcut.'),
+(u'Shortcut', u'IconIndex', u'Y', -32767, 32767, None, None, None, None, u'The icon index for the shortcut.'),
+(u'Shortcut', u'Directory_', u'N', None, None, u'Directory', 1, u'Identifier', None, u'Foreign key into the Directory table denoting the directory where the shortcut file is created.'),
+(u'Shortcut', u'Target', u'N', None, None, None, None, u'Shortcut', None, u'The shortcut target. This is usually a property that is expanded to a file or a folder that the shortcut points to.'),
+(u'Shortcut', u'Arguments', u'Y', None, None, None, None, u'Formatted', None, u'The command-line arguments for the shortcut.'),
+(u'Shortcut', u'Shortcut', u'N', None, None, None, None, u'Identifier', None, u'Primary key, non-localized token.'),
+(u'Shortcut', u'Hotkey', u'Y', 0, 32767, None, None, None, None, u'The hotkey for the shortcut. It has the virtual-key code for the key in the low-order byte, and the modifier flags in the high-order byte. '),
+(u'Shortcut', u'ShowCmd', u'Y', None, None, None, None, None, u'1;3;7', u'The show command for the application window.The following values may be used.'),
+(u'Shortcut', u'WkDir', u'Y', None, None, None, None, u'Identifier', None, u'Name of property defining location of working directory.'),
+(u'Signature', u'FileName', u'N', None, None, None, None, u'Filename', None, u'The name of the file. This may contain a "short name|long name" pair.'),
+(u'Signature', u'Signature', u'N', None, None, None, None, u'Identifier', None, u'The table key. The Signature represents a unique file signature.'),
+(u'Signature', u'Languages', u'Y', None, None, None, None, u'Language', None, u'The languages supported by the file.'),
+(u'Signature', u'MaxDate', u'Y', 0, 2147483647, None, None, None, None, u'The maximum creation date of the file.'),
+(u'Signature', u'MaxSize', u'Y', 0, 2147483647, None, None, None, None, u'The maximum size of the file. '),
+(u'Signature', u'MaxVersion', u'Y', None, None, None, None, u'Text', None, u'The maximum version of the file.'),
+(u'Signature', u'MinDate', u'Y', 0, 2147483647, None, None, None, None, u'The minimum creation date of the file.'),
+(u'Signature', u'MinSize', u'Y', 0, 2147483647, None, None, None, None, u'The minimum size of the file.'),
+(u'Signature', u'MinVersion', u'Y', None, None, None, None, u'Text', None, u'The minimum version of the file.'),
+(u'TypeLib', u'Feature_', u'N', None, None, u'Feature', 1, u'Identifier', None, u'Required foreign key into the Feature Table, specifying the feature to validate or install in order for the type library to be operational.'),
+(u'TypeLib', u'Description', u'Y', None, None, None, None, u'Text', None, None),
+(u'TypeLib', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Required foreign key into the Component Table, specifying the component for which to return a path when called through LocateComponent.'),
+(u'TypeLib', u'Directory_', u'Y', None, None, u'Directory', 1, u'Identifier', None, u'Optional. The foreign key into the Directory table denoting the path to the help file for the type library.'),
+(u'TypeLib', u'Language', u'N', 0, 32767, None, None, None, None, u'The language of the library.'),
+(u'TypeLib', u'Version', u'Y', 0, 16777215, None, None, None, None, u'The version of the library. The minor version is in the lower 8 bits of the integer. The major version is in the next 16 bits. '),
+(u'TypeLib', u'Cost', u'Y', 0, 2147483647, None, None, None, None, u'The cost associated with the registration of the typelib. This column is currently optional.'),
+(u'TypeLib', u'LibID', u'N', None, None, None, None, u'Guid', None, u'The GUID that represents the library.'),
+(u'Upgrade', u'Attributes', u'N', 0, 2147483647, None, None, None, None, u'The attributes of this product set.'),
+(u'Upgrade', u'Remove', u'Y', None, None, None, None, u'Formatted', None, u'The list of features to remove when uninstalling a product from this set.  The default is "ALL".'),
+(u'Upgrade', u'Language', u'Y', None, None, None, None, u'Language', None, u'A comma-separated list of languages for either products in this set or products not in this set.'),
+(u'Upgrade', u'ActionProperty', u'N', None, None, None, None, u'UpperCase', None, u'The property to set when a product in this set is found.'),
+(u'Upgrade', u'UpgradeCode', u'N', None, None, None, None, u'Guid', None, u'The UpgradeCode GUID belonging to the products in this set.'),
+(u'Upgrade', u'VersionMax', u'Y', None, None, None, None, u'Text', None, u'The maximum ProductVersion of the products in this set.  The set may or may not include products with this particular version.'),
+(u'Upgrade', u'VersionMin', u'Y', None, None, None, None, u'Text', None, u'The minimum ProductVersion of the products in this set.  The set may or may not include products with this particular version.'),
+(u'Verb', u'Sequence', u'Y', 0, 32767, None, None, None, None, u'Order within the verbs for a particular extension. Also used simply to specify the default verb.'),
+(u'Verb', u'Argument', u'Y', None, None, None, None, u'Formatted', None, u'Optional value for the command arguments.'),
+(u'Verb', u'Extension_', u'N', None, None, u'Extension', 1, u'Text', None, u'The extension associated with the table row.'),
+(u'Verb', u'Verb', u'N', None, None, None, None, u'Text', None, u'The verb for the command.'),
+(u'Verb', u'Command', u'Y', None, None, None, None, u'Formatted', None, u'The command text.'),
+]
+
+Error = [
+(0, u'{{Fatal error: }}'),
+(1, u'{{Error [1]. }}'),
+(2, u'Warning [1]. '),
+(3, None),
+(4, u'Info [1]. '),
+(5, u'The installer has encountered an unexpected error installing this package. This may indicate a problem with this package. The error code is [1]. {{The arguments are: [2], [3], [4]}}'),
+(6, None),
+(7, u'{{Disk full: }}'),
+(8, u'Action [Time]: [1]. [2]'),
+(9, u'[ProductName]'),
+(10, u'{[2]}{, [3]}{, [4]}'),
+(11, u'Message type: [1], Argument: [2]'),
+(12, u'=== Logging started: [Date]  [Time] ==='),
+(13, u'=== Logging stopped: [Date]  [Time] ==='),
+(14, u'Action start [Time]: [1].'),
+(15, u'Action ended [Time]: [1]. Return value [2].'),
+(16, u'Time remaining: {[1] minutes }{[2] seconds}'),
+(17, u'Out of memory. Shut down other applications before retrying.'),
+(18, u'Installer is no longer responding.'),
+(19, u'Installer stopped prematurely.'),
+(20, u'Please wait while Windows configures [ProductName]'),
+(21, u'Gathering required information...'),
+(22, u'Removing older versions of this application...'),
+(23, u'Preparing to remove older versions of this application...'),
+(32, u'{[ProductName] }Setup completed successfully.'),
+(33, u'{[ProductName] }Setup failed.'),
+(1101, u'Error reading from file: [2]. {{ System error [3].}}  Verify that the file exists and that you can access it.'),
+(1301, u"Cannot create the file '[2]'.  A directory with this name already exists.  Cancel the install and try installing to a different location."),
+(1302, u'Please insert the disk: [2]'),
+(1303, u'The installer has insufficient privileges to access this directory: [2].  The installation cannot continue.  Log on as administrator or contact your system administrator.'),
+(1304, u'Error writing to file: [2].  Verify that you have access to that directory.'),
+(1305, u'Error reading from file [2]. {{ System error [3].}} Verify that the file exists and that you can access it.'),
+(1306, u"Another application has exclusive access to the file '[2]'.  Please shut down all other applications, then click Retry."),
+(1307, u'There is not enough disk space to install this file: [2].  Free some disk space and click Retry, or click Cancel to exit.'),
+(1308, u'Source file not found: [2].  Verify that the file exists and that you can access it.'),
+(1309, u'Error reading from file: [3]. {{ System error [2].}}  Verify that the file exists and that you can access it.'),
+(1310, u'Error writing to file: [3]. {{ System error [2].}}  Verify that you have access to that directory.'),
+(1311, u'Source file not found{{(cabinet)}}: [2].  Verify that the file exists and that you can access it.'),
+(1312, u"Cannot create the directory '[2]'.  A file with this name already exists.  Please rename or remove the file and click retry, or click Cancel to exit."),
+(1313, u'The volume [2] is currently unavailable.  Please select another.'),
+(1314, u"The specified path '[2]' is unavailable."),
+(1315, u'Unable to write to the specified folder: [2].'),
+(1316, u'A network error occurred while attempting to read from the file: [2]'),
+(1317, u'An error occurred while attempting to create the directory: [2]'),
+(1318, u'A network error occurred while attempting to create the directory: [2]'),
+(1319, u'A network error occurred while attempting to open the source file cabinet: [2]'),
+(1320, u'The specified path is too long: [2]'),
+(1321, u'The Installer has insufficient privileges to modify this file: [2].'),
+(1322, u"A portion of the folder path '[2]' is invalid.  It is either empty or exceeds the length allowed by the system."),
+(1323, u"The folder path '[2]' contains words that are not valid in folder paths."),
+(1324, u"The folder path '[2]' contains an invalid character."),
+(1325, u"'[2]' is not a valid short file name."),
+(1326, u'Error getting file security: [3] GetLastError: [2]'),
+(1327, u'Invalid Drive: [2]'),
+(1328, u'Error applying patch to file [2].  It has probably been updated by other means, and can no longer be modified by this patch.  For more information contact your patch vendor.  {{System Error: [3]}}'),
+(1329, u'A file that is required cannot be installed because the cabinet file [2] is not digitally signed.  This may indicate that the cabinet file is corrupt.'),
+(1330, u'A file that is required cannot be installed because the cabinet file [2] has an invalid digital signature.  This may indicate that the cabinet file is corrupt.{{  Error [3] was returned by WinVerifyTrust.}}'),
+(1331, u'Failed to correctly copy [2] file: CRC error.'),
+(1332, u'Failed to correctly move [2] file: CRC error.'),
+(1333, u'Failed to correctly patch [2] file: CRC error.'),
+(1334, u"The file '[2]' cannot be installed because the file cannot be found in cabinet file '[3]'. This could indicate a network error, an error reading from the CD-ROM, or a problem with this package."),
+(1335, u"The cabinet file '[2]' required for this installation is corrupt and cannot be used. This could indicate a network error, an error reading from the CD-ROM, or a problem with this package."),
+(1336, u'There was an error creating a temporary file that is needed to complete this installation.{{  Folder: [3]. System error code: [2]}}'),
+(1401, u'Could not create key: [2]. {{ System error [3].}}  Verify that you have sufficient access to that key, or contact your support personnel. '),
+(1402, u'Could not open key: [2]. {{ System error [3].}}  Verify that you have sufficient access to that key, or contact your support personnel. '),
+(1403, u'Could not delete value [2] from key [3]. {{ System error [4].}}  Verify that you have sufficient access to that key, or contact your support personnel. '),
+(1404, u'Could not delete key [2]. {{ System error [3].}}  Verify that you have sufficient access to that key, or contact your support personnel. '),
+(1405, u'Could not read value [2] from key [3]. {{ System error [4].}}  Verify that you have sufficient access to that key, or contact your support personnel. '),
+(1406, u'Could not write value [2] to key [3]. {{ System error [4].}}  Verify that you have sufficient access to that key, or contact your support personnel.'),
+(1407, u'Could not get value names for key [2]. {{ System error [3].}}  Verify that you have sufficient access to that key, or contact your support personnel.'),
+(1408, u'Could not get sub key names for key [2]. {{ System error [3].}}  Verify that you have sufficient access to that key, or contact your support personnel.'),
+(1409, u'Could not read security information for key [2]. {{ System error [3].}}  Verify that you have sufficient access to that key, or contact your support personnel.'),
+(1410, u'Could not increase the available registry space. [2] KB of free registry space is required for the installation of this application.'),
+(1500, u'Another installation is in progress. You must complete that installation before continuing this one.'),
+(1501, u'Error accessing secured data. Please make sure the Windows Installer is configured properly and try the install again.'),
+(1502, u"User '[2]' has previously initiated an install for product '[3]'.  That user will need to run that install again before they can use that product.  Your current install will now continue."),
+(1503, u"User '[2]' has previously initiated an install for product '[3]'.  That user will need to run that install again before they can use that product."),
+(1601, u"Out of disk space -- Volume: '[2]'; required space: [3] KB; available space: [4] KB.  Free some disk space and retry."),
+(1602, u'Are you sure you want to cancel?'),
+(1603, u"The file [2][3] is being held in use{ by the following process: Name: [4], Id: [5], Window Title: '[6]'}.  Close that application and retry."),
+(1604, u"The product '[2]' is already installed, preventing the installation of this product.  The two products are incompatible."),
+(1605, u"There is not enough disk space on the volume '[2]' to continue the install with recovery enabled. [3] KB are required, but only [4] KB are available. Click Ignore to continue the install without saving recovery information, click Retry to check for available space again, or click Cancel to quit the installation."),
+(1606, u'Could not access network location [2].'),
+(1607, u'The following applications should be closed before continuing the install:'),
+(1608, u'Could not find any previously installed compliant products on the machine for installing this product.'),
+(1609, u"An error occurred while applying security settings. [2] is not a valid user or group. This could be a problem with the package, or a problem connecting to a domain controller on the network. Check your network connection and click Retry, or Cancel to end the install. {{Unable to locate the user's SID, system error [3]}}"),
+(1701, u'The key [2] is not valid.  Verify that you entered the correct key.'),
+(1702, u'The installer must restart your system before configuration of [2] can continue.  Click Yes to restart now or No if you plan to manually restart later.'),
+(1703, u'You must restart your system for the configuration changes made to [2] to take effect. Click Yes to restart now or No if you plan to manually restart later.'),
+(1704, u'An installation for [2] is currently suspended.  You must undo the changes made by that installation to continue.  Do you want to undo those changes?'),
+(1705, u'A previous installation for this product is in progress.  You must undo the changes made by that installation to continue.  Do you want to undo those changes?'),
+(1706, u"An installation package for the product [2] cannot be found. Try the installation again using a valid copy of the installation package '[3]'."),
+(1707, u'Installation completed successfully.'),
+(1708, u'Installation failed.'),
+(1709, u'Product: [2] -- [3]'),
+(1710, u'You may either restore your computer to its previous state or continue the install later. Would you like to restore?'),
+(1711, u'An error occurred while writing installation information to disk.  Check to make sure enough disk space is available, and click Retry, or Cancel to end the install.'),
+(1712, u'One or more of the files required to restore your computer to its previous state could not be found.  Restoration will not be possible.'),
+(1713, u'[2] cannot install one of its required products. Contact your technical support group.  {{System Error: [3].}}'),
+(1714, u'The older version of [2] cannot be removed.  Contact your technical support group.  {{System Error [3].}}'),
+(1715, u'Installed [2]'),
+(1716, u'Configured [2]'),
+(1717, u'Removed [2]'),
+(1718, u'File [2] was rejected by digital signature policy.'),
+(1719, u'The Windows Installer Service could not be accessed. This can occur if you are running Windows in safe mode, or if the Windows Installer is not correctly installed. Contact your support personnel for assistance.'),
+(1720, u'There is a problem with this Windows Installer package. A script required for this install to complete could not be run. Contact your support personnel or package vendor.  {{Custom action [2] script error [3], [4]: [5] Line [6], Column [7], [8] }}'),
+(1721, u'There is a problem with this Windows Installer package. A program required for this install to complete could not be run. Contact your support personnel or package vendor. {{Action: [2], location: [3], command: [4] }}'),
+(1722, u'There is a problem with this Windows Installer package. A program run as part of the setup did not finish as expected. Contact your support personnel or package vendor.  {{Action [2], location: [3], command: [4] }}'),
+(1723, u'There is a problem with this Windows Installer package. A DLL required for this install to complete could not be run. Contact your support personnel or package vendor.  {{Action [2], entry: [3], library: [4] }}'),
+(1724, u'Removal completed successfully.'),
+(1725, u'Removal failed.'),
+(1726, u'Advertisement completed successfully.'),
+(1727, u'Advertisement failed.'),
+(1728, u'Configuration completed successfully.'),
+(1729, u'Configuration failed.'),
+(1730, u'You must be an Administrator to remove this application. To remove this application, you can log on as an Administrator, or contact your technical support group for assistance.'),
+(1801, u'The path [2] is not valid.  Please specify a valid path.'),
+(1802, u'Out of memory. Shut down other applications before retrying.'),
+(1803, u'There is no disk in drive [2]. Please insert one and click Retry, or click Cancel to go back to the previously selected volume.'),
+(1804, u'There is no disk in drive [2]. Please insert one and click Retry, or click Cancel to return to the browse dialog and select a different volume.'),
+(1805, u'The folder [2] does not exist.  Please enter a path to an existing folder.'),
+(1806, u'You have insufficient privileges to read this folder.'),
+(1807, u'A valid destination folder for the install could not be determined.'),
+(1901, u'Error attempting to read from the source install database: [2].'),
+(1902, u'Scheduling reboot operation: Renaming file [2] to [3]. Must reboot to complete operation.'),
+(1903, u'Scheduling reboot operation: Deleting file [2]. Must reboot to complete operation.'),
+(1904, u'Module [2] failed to register.  HRESULT [3].  Contact your support personnel.'),
+(1905, u'Module [2] failed to unregister.  HRESULT [3].  Contact your support personnel.'),
+(1906, u'Failed to cache package [2]. Error: [3]. Contact your support personnel.'),
+(1907, u'Could not register font [2].  Verify that you have sufficient permissions to install fonts, and that the system supports this font.'),
+(1908, u'Could not unregister font [2]. Verify that you that you have sufficient permissions to remove fonts.'),
+(1909, u'Could not create Shortcut [2]. Verify that the destination folder exists and that you can access it.'),
+(1910, u'Could not remove Shortcut [2]. Verify that the shortcut file exists and that you can access it.'),
+(1911, u'Could not register type library for file [2].  Contact your support personnel.'),
+(1912, u'Could not unregister type library for file [2].  Contact your support personnel.'),
+(1913, u'Could not update the ini file [2][3].  Verify that the file exists and that you can access it.'),
+(1914, u'Could not schedule file [2] to replace file [3] on reboot.  Verify that you have write permissions to file [3].'),
+(1915, u'Error removing ODBC driver manager, ODBC error [2]: [3]. Contact your support personnel.'),
+(1916, u'Error installing ODBC driver manager, ODBC error [2]: [3]. Contact your support personnel.'),
+(1917, u'Error removing ODBC driver: [4], ODBC error [2]: [3]. Verify that you have sufficient privileges to remove ODBC drivers.'),
+(1918, u'Error installing ODBC driver: [4], ODBC error [2]: [3]. Verify that the file [4] exists and that you can access it.'),
+(1919, u'Error configuring ODBC data source: [4], ODBC error [2]: [3]. Verify that the file [4] exists and that you can access it.'),
+(1920, u"Service '[2]' ([3]) failed to start.  Verify that you have sufficient privileges to start system services."),
+(1921, u"Service '[2]' ([3]) could not be stopped.  Verify that you have sufficient privileges to stop system services."),
+(1922, u"Service '[2]' ([3]) could not be deleted.  Verify that you have sufficient privileges to remove system services."),
+(1923, u"Service '[2]' ([3]) could not be installed.  Verify that you have sufficient privileges to install system services."),
+(1924, u"Could not update environment variable '[2]'.  Verify that you have sufficient privileges to modify environment variables."),
+(1925, u'You do not have sufficient privileges to complete this installation for all users of the machine.  Log on as administrator and then retry this installation.'),
+(1926, u"Could not set file security for file '[3]'. Error: [2].  Verify that you have sufficient privileges to modify the security permissions for this file."),
+(1927, u'Component Services (COM+ 1.0) are not installed on this computer.  This installation requires Component Services in order to complete successfully.  Component Services are available on Windows 2000.'),
+(1928, u'Error registering COM+ Application.  Contact your support personnel for more information.'),
+(1929, u'Error unregistering COM+ Application.  Contact your support personnel for more information.'),
+(1930, u"The description for service '[2]' ([3]) could not be changed."),
+(1931, u'The Windows Installer service cannot update the system file [2] because the file is protected by Windows.  You may need to update your operating system for this program to work correctly. {{Package version: [3], OS Protected version: [4]}}'),
+(1932, u'The Windows Installer service cannot update the protected Windows file [2]. {{Package version: [3], OS Protected version: [4], SFP Error: [5]}}'),
+(1933, u'The Windows Installer service cannot update one or more protected Windows files. {{SFP Error: [2].  List of protected files:\\r\\n[3]}}'),
+(1934, u'User installations are disabled via policy on the machine.'),
+(1935, u'An error occurred during the installation of assembly component [2]. HRESULT: [3]. {{assembly interface: [4], function: [5], assembly name: [6]}}'),
+]
+
+tables=['AdminExecuteSequence', 'AdminUISequence', 'AdvtExecuteSequence', 'BBControl', 'Billboard', 'Binary', 'CheckBox', 'Property', 'ComboBox', 'Control', 'ListBox', 'ActionText', 'ControlCondition', 'ControlEvent', 'Dialog', 'EventMapping', 'InstallExecuteSequence', 'InstallUISequence', 'ListView', 'RadioButton', 'TextStyle', 'UIText', '_Validation', 'Error']

Added: vendor/Python/current/Tools/msi/uuids.py
===================================================================
--- vendor/Python/current/Tools/msi/uuids.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/msi/uuids.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,38 @@
+# This should be extended for each Python release.
+# The product code must change whenever the name of the MSI file
+# changes, and when new component codes are issued for existing
+# components. See "Changing the Product Code". As we change the
+# component codes with every build, we need a new product code
+# each time. For intermediate (snapshot) releases, they are automatically
+# generated. For official releases, we record the product codes,
+# so people can refer to them.
+product_codes = {
+    '2.4.101': '{0e9b4d8e-6cda-446e-a208-7b92f3ddffa0}', # 2.4a1, released as a snapshot
+    '2.4.102': '{1b998745-4901-4edb-bc52-213689e1b922}', # 2.4a2
+    '2.4.103': '{33fc8bd2-1e8f-4add-a40a-ade2728d5942}', # 2.4a3
+    '2.4.111': '{51a7e2a8-2025-4ef0-86ff-e6aab742d1fa}', # 2.4b1
+    '2.4.112': '{4a5e7c1d-c659-4fe3-b8c9-7c65bd9c95a5}', # 2.4b2
+    '2.4.121': '{75508821-a8e9-40a8-95bd-dbe6033ddbea}', # 2.4c1
+    '2.4.122': '{83a9118b-4bdd-473b-afc3-bcb142feca9e}', # 2.4c2
+    '2.4.150': '{82d9302e-f209-4805-b548-52087047483a}', # 2.4.0
+    '2.4.1121':'{be027411-8e6b-4440-a29b-b07df0690230}', # 2.4.1c1
+    '2.4.1122':'{02818752-48bf-4074-a281-7a4114c4f1b1}', # 2.4.1c2
+    '2.4.1150':'{4d4f5346-7e4a-40b5-9387-fdb6181357fc}', # 2.4.1
+    '2.4.2121':'{5ef9d6b6-df78-45d2-ab09-14786a3c5a99}', # 2.4.2c1
+    '2.4.2150':'{b191e49c-ea23-43b2-b28a-14e0784069b8}', # 2.4.2
+    '2.4.3121':'{f669ed4d-1dce-41c4-9617-d985397187a1}', # 2.4.3c1
+    '2.4.3150':'{75e71add-042c-4f30-bfac-a9ec42351313}', # 2.4.3
+    '2.5.101': '{bc14ce3e-5e72-4a64-ac1f-bf59a571898c}', # 2.5a1
+    '2.5.102': '{5eed51c1-8e9d-4071-94c5-b40de5d49ba5}', # 2.5a2
+    '2.5.103': '{73dcd966-ffec-415f-bb39-8342c1f47017}', # 2.5a3
+    '2.5.111': '{c797ecf8-a8e6-4fec-bb99-526b65f28626}', # 2.5b1
+    '2.5.112': '{32beb774-f625-439d-b587-7187487baf15}', # 2.5b2
+    '2.5.113': '{89f23918-11cf-4f08-be13-b9b2e6463fd9}', # 2.5b3
+    '2.5.121': '{8e9321bc-6b24-48a3-8fd4-c95f8e531e5f}', # 2.5c1
+    '2.5.122': '{a6cd508d-9599-45da-a441-cbffa9f7e070}', # 2.5c2
+    '2.5.150': '{0a2c5854-557e-48c8-835a-3b9f074bdcaa}', # 2.5.0
+    '2.5.1121':'{0378b43e-6184-4c2f-be1a-4a367781cd54}', # 2.5.1c1
+    '2.5.1150':'{31800004-6386-4999-a519-518f2d78d8f0}', # 2.5.1
+    '2.5.2150':'{6304a7da-1132-4e91-a343-a296269eab8a}', # 2.5.2c1
+    '2.5.2150':'{6b976adf-8ae8-434e-b282-a06c7f624d2f}', # 2.5.2
+}

Added: vendor/Python/current/Tools/pybench/Arithmetic.py
===================================================================
--- vendor/Python/current/Tools/pybench/Arithmetic.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/pybench/Arithmetic.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,777 @@
+from pybench import Test
+
+class SimpleIntegerArithmetic(Test):
+
+    version = 2.0
+    operations = 5 * (3 + 5 + 5 + 3 + 3 + 3)
+    rounds = 120000
+
+    def test(self):
+
+        for i in xrange(self.rounds):
+
+            a = 2
+            b = 3
+            c = 3
+
+            c = a + b
+            c = b + c
+            c = c + a
+            c = a + b
+            c = b + c
+
+            c = c - a
+            c = a - b
+            c = b - c
+            c = c - a
+            c = b - c
+
+            c = a / b
+            c = b / a
+            c = c / b
+
+            c = a * b
+            c = b * a
+            c = c * b
+
+            c = a / b
+            c = b / a
+            c = c / b
+
+            a = 2
+            b = 3
+            c = 3
+
+            c = a + b
+            c = b + c
+            c = c + a
+            c = a + b
+            c = b + c
+
+            c = c - a
+            c = a - b
+            c = b - c
+            c = c - a
+            c = b - c
+
+            c = a / b
+            c = b / a
+            c = c / b
+
+            c = a * b
+            c = b * a
+            c = c * b
+
+            c = a / b
+            c = b / a
+            c = c / b
+
+            a = 2
+            b = 3
+            c = 3
+
+            c = a + b
+            c = b + c
+            c = c + a
+            c = a + b
+            c = b + c
+
+            c = c - a
+            c = a - b
+            c = b - c
+            c = c - a
+            c = b - c
+
+            c = a / b
+            c = b / a
+            c = c / b
+
+            c = a * b
+            c = b * a
+            c = c * b
+
+            c = a / b
+            c = b / a
+            c = c / b
+
+            a = 2
+            b = 3
+            c = 3
+
+            c = a + b
+            c = b + c
+            c = c + a
+            c = a + b
+            c = b + c
+
+            c = c - a
+            c = a - b
+            c = b - c
+            c = c - a
+            c = b - c
+
+            c = a / b
+            c = b / a
+            c = c / b
+
+            c = a * b
+            c = b * a
+            c = c * b
+
+            c = a / b
+            c = b / a
+            c = c / b
+
+            a = 2
+            b = 3
+            c = 3
+
+            c = a + b
+            c = b + c
+            c = c + a
+            c = a + b
+            c = b + c
+
+            c = c - a
+            c = a - b
+            c = b - c
+            c = c - a
+            c = b - c
+
+            c = a / b
+            c = b / a
+            c = c / b
+
+            c = a * b
+            c = b * a
+            c = c * b
+
+            c = a / b
+            c = b / a
+            c = c / b
+
+    def calibrate(self):
+
+        for i in xrange(self.rounds):
+            pass
+
+class SimpleFloatArithmetic(Test):
+
+    version = 2.0
+    operations = 5 * (3 + 5 + 5 + 3 + 3 + 3)
+    rounds = 120000
+
+    def test(self):
+
+        for i in xrange(self.rounds):
+
+            a = 2.1
+            b = 3.3332
+            c = 3.14159
+
+            c = a + b
+            c = b + c
+            c = c + a
+            c = a + b
+            c = b + c
+
+            c = c - a
+            c = a - b
+            c = b - c
+            c = c - a
+            c = b - c
+
+            c = a / b
+            c = b / a
+            c = c / b
+
+            c = a * b
+            c = b * a
+            c = c * b
+
+            c = a / b
+            c = b / a
+            c = c / b
+
+            a = 2.1
+            b = 3.3332
+            c = 3.14159
+
+            c = a + b
+            c = b + c
+            c = c + a
+            c = a + b
+            c = b + c
+
+            c = c - a
+            c = a - b
+            c = b - c
+            c = c - a
+            c = b - c
+
+            c = a / b
+            c = b / a
+            c = c / b
+
+            c = a * b
+            c = b * a
+            c = c * b
+
+            c = a / b
+            c = b / a
+            c = c / b
+
+            a = 2.1
+            b = 3.3332
+            c = 3.14159
+
+            c = a + b
+            c = b + c
+            c = c + a
+            c = a + b
+            c = b + c
+
+            c = c - a
+            c = a - b
+            c = b - c
+            c = c - a
+            c = b - c
+
+            c = a / b
+            c = b / a
+            c = c / b
+
+            c = a * b
+            c = b * a
+            c = c * b
+
+            c = a / b
+            c = b / a
+            c = c / b
+
+            a = 2.1
+            b = 3.3332
+            c = 3.14159
+
+            c = a + b
+            c = b + c
+            c = c + a
+            c = a + b
+            c = b + c
+
+            c = c - a
+            c = a - b
+            c = b - c
+            c = c - a
+            c = b - c
+
+            c = a / b
+            c = b / a
+            c = c / b
+
+            c = a * b
+            c = b * a
+            c = c * b
+
+            c = a / b
+            c = b / a
+            c = c / b
+
+            a = 2.1
+            b = 3.3332
+            c = 3.14159
+
+            c = a + b
+            c = b + c
+            c = c + a
+            c = a + b
+            c = b + c
+
+            c = c - a
+            c = a - b
+            c = b - c
+            c = c - a
+            c = b - c
+
+            c = a / b
+            c = b / a
+            c = c / b
+
+            c = a * b
+            c = b * a
+            c = c * b
+
+            c = a / b
+            c = b / a
+            c = c / b
+
+    def calibrate(self):
+
+        for i in xrange(self.rounds):
+            pass
+
+class SimpleIntFloatArithmetic(Test):
+
+    version = 2.0
+    operations = 5 * (3 + 5 + 5 + 3 + 3 + 3)
+    rounds = 120000
+
+    def test(self):
+
+        for i in xrange(self.rounds):
+
+            a = 2
+            b = 3
+            c = 3.14159
+
+            c = a + b
+            c = b + c
+            c = c + a
+            c = a + b
+            c = b + c
+
+            c = c - a
+            c = a - b
+            c = b - c
+            c = c - a
+            c = b - c
+
+            c = a / b
+            c = b / a
+            c = c / b
+
+            c = a * b
+            c = b * a
+            c = c * b
+
+            c = a / b
+            c = b / a
+            c = c / b
+
+            a = 2
+            b = 3
+            c = 3.14159
+
+            c = a + b
+            c = b + c
+            c = c + a
+            c = a + b
+            c = b + c
+
+            c = c - a
+            c = a - b
+            c = b - c
+            c = c - a
+            c = b - c
+
+            c = a / b
+            c = b / a
+            c = c / b
+
+            c = a * b
+            c = b * a
+            c = c * b
+
+            c = a / b
+            c = b / a
+            c = c / b
+
+            a = 2
+            b = 3
+            c = 3.14159
+
+            c = a + b
+            c = b + c
+            c = c + a
+            c = a + b
+            c = b + c
+
+            c = c - a
+            c = a - b
+            c = b - c
+            c = c - a
+            c = b - c
+
+            c = a / b
+            c = b / a
+            c = c / b
+
+            c = a * b
+            c = b * a
+            c = c * b
+
+            c = a / b
+            c = b / a
+            c = c / b
+
+            a = 2
+            b = 3
+            c = 3.14159
+
+            c = a + b
+            c = b + c
+            c = c + a
+            c = a + b
+            c = b + c
+
+            c = c - a
+            c = a - b
+            c = b - c
+            c = c - a
+            c = b - c
+
+            c = a / b
+            c = b / a
+            c = c / b
+
+            c = a * b
+            c = b * a
+            c = c * b
+
+            c = a / b
+            c = b / a
+            c = c / b
+
+            a = 2
+            b = 3
+            c = 3.14159
+
+            c = a + b
+            c = b + c
+            c = c + a
+            c = a + b
+            c = b + c
+
+            c = c - a
+            c = a - b
+            c = b - c
+            c = c - a
+            c = b - c
+
+            c = a / b
+            c = b / a
+            c = c / b
+
+            c = a * b
+            c = b * a
+            c = c * b
+
+            c = a / b
+            c = b / a
+            c = c / b
+
+    def calibrate(self):
+
+        for i in xrange(self.rounds):
+            pass
+
+
+class SimpleLongArithmetic(Test):
+
+    version = 2.0
+    operations = 5 * (3 + 5 + 5 + 3 + 3 + 3)
+    rounds = 60000
+
+    def test(self):
+
+        for i in xrange(self.rounds):
+
+            a = 2220001L
+            b = 100001L
+            c = 30005L
+
+            c = a + b
+            c = b + c
+            c = c + a
+            c = a + b
+            c = b + c
+
+            c = c - a
+            c = a - b
+            c = b - c
+            c = c - a
+            c = b - c
+
+            c = a / b
+            c = b / a
+            c = c / b
+
+            c = a * b
+            c = b * a
+            c = c * b
+
+            c = a / b
+            c = b / a
+            c = c / b
+
+            a = 2220001L
+            b = 100001L
+            c = 30005L
+
+            c = a + b
+            c = b + c
+            c = c + a
+            c = a + b
+            c = b + c
+
+            c = c - a
+            c = a - b
+            c = b - c
+            c = c - a
+            c = b - c
+
+            c = a / b
+            c = b / a
+            c = c / b
+
+            c = a * b
+            c = b * a
+            c = c * b
+
+            c = a / b
+            c = b / a
+            c = c / b
+
+            a = 2220001L
+            b = 100001L
+            c = 30005L
+
+            c = a + b
+            c = b + c
+            c = c + a
+            c = a + b
+            c = b + c
+
+            c = c - a
+            c = a - b
+            c = b - c
+            c = c - a
+            c = b - c
+
+            c = a / b
+            c = b / a
+            c = c / b
+
+            c = a * b
+            c = b * a
+            c = c * b
+
+            c = a / b
+            c = b / a
+            c = c / b
+
+            a = 2220001L
+            b = 100001L
+            c = 30005L
+
+            c = a + b
+            c = b + c
+            c = c + a
+            c = a + b
+            c = b + c
+
+            c = c - a
+            c = a - b
+            c = b - c
+            c = c - a
+            c = b - c
+
+            c = a / b
+            c = b / a
+            c = c / b
+
+            c = a * b
+            c = b * a
+            c = c * b
+
+            c = a / b
+            c = b / a
+            c = c / b
+
+            a = 2220001L
+            b = 100001L
+            c = 30005L
+
+            c = a + b
+            c = b + c
+            c = c + a
+            c = a + b
+            c = b + c
+
+            c = c - a
+            c = a - b
+            c = b - c
+            c = c - a
+            c = b - c
+
+            c = a / b
+            c = b / a
+            c = c / b
+
+            c = a * b
+            c = b * a
+            c = c * b
+
+            c = a / b
+            c = b / a
+            c = c / b
+
+    def calibrate(self):
+
+        for i in xrange(self.rounds):
+            pass
+
+class SimpleComplexArithmetic(Test):
+
+    version = 2.0
+    operations = 5 * (3 + 5 + 5 + 3 + 3 + 3)
+    rounds = 80000
+
+    def test(self):
+
+        for i in xrange(self.rounds):
+
+            a = 2 + 3j
+            b = 2.5 + 4.5j
+            c = 1.2 + 6.2j
+
+            c = a + b
+            c = b + c
+            c = c + a
+            c = a + b
+            c = b + c
+
+            c = c - a
+            c = a - b
+            c = b - c
+            c = c - a
+            c = b - c
+
+            c = a / b
+            c = b / a
+            c = c / b
+
+            c = a * b
+            c = b * a
+            c = c * b
+
+            c = a / b
+            c = b / a
+            c = c / b
+
+            a = 2 + 3j
+            b = 2.5 + 4.5j
+            c = 1.2 + 6.2j
+
+            c = a + b
+            c = b + c
+            c = c + a
+            c = a + b
+            c = b + c
+
+            c = c - a
+            c = a - b
+            c = b - c
+            c = c - a
+            c = b - c
+
+            c = a / b
+            c = b / a
+            c = c / b
+
+            c = a * b
+            c = b * a
+            c = c * b
+
+            c = a / b
+            c = b / a
+            c = c / b
+
+            a = 2 + 3j
+            b = 2.5 + 4.5j
+            c = 1.2 + 6.2j
+
+            c = a + b
+            c = b + c
+            c = c + a
+            c = a + b
+            c = b + c
+
+            c = c - a
+            c = a - b
+            c = b - c
+            c = c - a
+            c = b - c
+
+            c = a / b
+            c = b / a
+            c = c / b
+
+            c = a * b
+            c = b * a
+            c = c * b
+
+            c = a / b
+            c = b / a
+            c = c / b
+
+            a = 2 + 3j
+            b = 2.5 + 4.5j
+            c = 1.2 + 6.2j
+
+            c = a + b
+            c = b + c
+            c = c + a
+            c = a + b
+            c = b + c
+
+            c = c - a
+            c = a - b
+            c = b - c
+            c = c - a
+            c = b - c
+
+            c = a / b
+            c = b / a
+            c = c / b
+
+            c = a * b
+            c = b * a
+            c = c * b
+
+            c = a / b
+            c = b / a
+            c = c / b
+
+            a = 2 + 3j
+            b = 2.5 + 4.5j
+            c = 1.2 + 6.2j
+
+            c = a + b
+            c = b + c
+            c = c + a
+            c = a + b
+            c = b + c
+
+            c = c - a
+            c = a - b
+            c = b - c
+            c = c - a
+            c = b - c
+
+            c = a / b
+            c = b / a
+            c = c / b
+
+            c = a * b
+            c = b * a
+            c = c * b
+
+            c = a / b
+            c = b / a
+            c = c / b
+
+    def calibrate(self):
+
+        for i in xrange(self.rounds):
+            pass

Added: vendor/Python/current/Tools/pybench/Calls.py
===================================================================
--- vendor/Python/current/Tools/pybench/Calls.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/pybench/Calls.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,502 @@
+from pybench import Test
+
+class PythonFunctionCalls(Test):
+
+    version = 2.0
+    operations = 5*(1+4+4+2)
+    rounds = 60000
+
+    def test(self):
+
+        global f,f1,g,h
+
+        # define functions
+        def f():
+            pass
+
+        def f1(x):
+            pass
+
+        def g(a,b,c):
+            return a,b,c
+
+        def h(a,b,c,d=1,e=2,f=3):
+            return d,e,f
+
+        # do calls
+        for i in xrange(self.rounds):
+
+            f()
+            f1(i)
+            f1(i)
+            f1(i)
+            f1(i)
+            g(i,i,i)
+            g(i,i,i)
+            g(i,i,i)
+            g(i,i,i)
+            h(i,i,3,i,i)
+            h(i,i,i,2,i,3)
+
+            f()
+            f1(i)
+            f1(i)
+            f1(i)
+            f1(i)
+            g(i,i,i)
+            g(i,i,i)
+            g(i,i,i)
+            g(i,i,i)
+            h(i,i,3,i,i)
+            h(i,i,i,2,i,3)
+
+            f()
+            f1(i)
+            f1(i)
+            f1(i)
+            f1(i)
+            g(i,i,i)
+            g(i,i,i)
+            g(i,i,i)
+            g(i,i,i)
+            h(i,i,3,i,i)
+            h(i,i,i,2,i,3)
+
+            f()
+            f1(i)
+            f1(i)
+            f1(i)
+            f1(i)
+            g(i,i,i)
+            g(i,i,i)
+            g(i,i,i)
+            g(i,i,i)
+            h(i,i,3,i,i)
+            h(i,i,i,2,i,3)
+
+            f()
+            f1(i)
+            f1(i)
+            f1(i)
+            f1(i)
+            g(i,i,i)
+            g(i,i,i)
+            g(i,i,i)
+            g(i,i,i)
+            h(i,i,3,i,i)
+            h(i,i,i,2,i,3)
+
+    def calibrate(self):
+
+        global f,f1,g,h
+
+        # define functions
+        def f():
+            pass
+
+        def f1(x):
+            pass
+
+        def g(a,b,c):
+            return a,b,c
+
+        def h(a,b,c,d=1,e=2,f=3):
+            return d,e,f
+
+        # do calls
+        for i in xrange(self.rounds):
+            pass
+
+###
+
+class BuiltinFunctionCalls(Test):
+
+    version = 2.0
+    operations = 5*(2+5+5+5)
+    rounds = 60000
+
+    def test(self):
+
+        # localize functions
+        f0 = globals
+        f1 = hash
+        f2 = cmp
+        f3 = range
+
+        # do calls
+        for i in xrange(self.rounds):
+
+            f0()
+            f0()
+            f1(i)
+            f1(i)
+            f1(i)
+            f1(i)
+            f1(i)
+            f2(1,2)
+            f2(1,2)
+            f2(1,2)
+            f2(1,2)
+            f2(1,2)
+            f3(1,3,2)
+            f3(1,3,2)
+            f3(1,3,2)
+            f3(1,3,2)
+            f3(1,3,2)
+
+            f0()
+            f0()
+            f1(i)
+            f1(i)
+            f1(i)
+            f1(i)
+            f1(i)
+            f2(1,2)
+            f2(1,2)
+            f2(1,2)
+            f2(1,2)
+            f2(1,2)
+            f3(1,3,2)
+            f3(1,3,2)
+            f3(1,3,2)
+            f3(1,3,2)
+            f3(1,3,2)
+
+            f0()
+            f0()
+            f1(i)
+            f1(i)
+            f1(i)
+            f1(i)
+            f1(i)
+            f2(1,2)
+            f2(1,2)
+            f2(1,2)
+            f2(1,2)
+            f2(1,2)
+            f3(1,3,2)
+            f3(1,3,2)
+            f3(1,3,2)
+            f3(1,3,2)
+            f3(1,3,2)
+
+            f0()
+            f0()
+            f1(i)
+            f1(i)
+            f1(i)
+            f1(i)
+            f1(i)
+            f2(1,2)
+            f2(1,2)
+            f2(1,2)
+            f2(1,2)
+            f2(1,2)
+            f3(1,3,2)
+            f3(1,3,2)
+            f3(1,3,2)
+            f3(1,3,2)
+            f3(1,3,2)
+
+            f0()
+            f0()
+            f1(i)
+            f1(i)
+            f1(i)
+            f1(i)
+            f1(i)
+            f2(1,2)
+            f2(1,2)
+            f2(1,2)
+            f2(1,2)
+            f2(1,2)
+            f3(1,3,2)
+            f3(1,3,2)
+            f3(1,3,2)
+            f3(1,3,2)
+            f3(1,3,2)
+
+    def calibrate(self):
+
+        # localize functions
+        f0 = dir
+        f1 = hash
+        f2 = range
+        f3 = range
+
+        # do calls
+        for i in xrange(self.rounds):
+            pass
+
+###
+
+class PythonMethodCalls(Test):
+
+    version = 2.0
+    operations = 5*(6 + 5 + 4)
+    rounds = 30000
+
+    def test(self):
+
+        class c:
+
+            x = 2
+            s = 'string'
+
+            def f(self):
+
+                return self.x
+
+            def j(self,a,b):
+
+                self.y = a
+                self.t = b
+                return self.y
+
+            def k(self,a,b,c=3):
+
+                self.y = a
+                self.s = b
+                self.t = c
+
+        o = c()
+
+        for i in xrange(self.rounds):
+
+            o.f()
+            o.f()
+            o.f()
+            o.f()
+            o.f()
+            o.f()
+            o.j(i,i)
+            o.j(i,i)
+            o.j(i,2)
+            o.j(i,2)
+            o.j(2,2)
+            o.k(i,i)
+            o.k(i,2)
+            o.k(i,2,3)
+            o.k(i,i,c=4)
+
+            o.f()
+            o.f()
+            o.f()
+            o.f()
+            o.f()
+            o.f()
+            o.j(i,i)
+            o.j(i,i)
+            o.j(i,2)
+            o.j(i,2)
+            o.j(2,2)
+            o.k(i,i)
+            o.k(i,2)
+            o.k(i,2,3)
+            o.k(i,i,c=4)
+
+            o.f()
+            o.f()
+            o.f()
+            o.f()
+            o.f()
+            o.f()
+            o.j(i,i)
+            o.j(i,i)
+            o.j(i,2)
+            o.j(i,2)
+            o.j(2,2)
+            o.k(i,i)
+            o.k(i,2)
+            o.k(i,2,3)
+            o.k(i,i,c=4)
+
+            o.f()
+            o.f()
+            o.f()
+            o.f()
+            o.f()
+            o.f()
+            o.j(i,i)
+            o.j(i,i)
+            o.j(i,2)
+            o.j(i,2)
+            o.j(2,2)
+            o.k(i,i)
+            o.k(i,2)
+            o.k(i,2,3)
+            o.k(i,i,c=4)
+
+            o.f()
+            o.f()
+            o.f()
+            o.f()
+            o.f()
+            o.f()
+            o.j(i,i)
+            o.j(i,i)
+            o.j(i,2)
+            o.j(i,2)
+            o.j(2,2)
+            o.k(i,i)
+            o.k(i,2)
+            o.k(i,2,3)
+            o.k(i,i,c=4)
+
+    def calibrate(self):
+
+        class c:
+
+            x = 2
+            s = 'string'
+
+            def f(self):
+
+                return self.x
+
+            def j(self,a,b):
+
+                self.y = a
+                self.t = b
+
+            def k(self,a,b,c=3):
+
+                self.y = a
+                self.s = b
+                self.t = c
+
+        o = c
+
+        for i in xrange(self.rounds):
+            pass
+
+###
+
+class Recursion(Test):
+
+    version = 2.0
+    operations = 5
+    rounds = 100000
+
+    def test(self):
+
+        global f
+
+        def f(x):
+
+            if x > 1:
+                return f(x-1)
+            return 1
+
+        for i in xrange(self.rounds):
+            f(10)
+            f(10)
+            f(10)
+            f(10)
+            f(10)
+
+    def calibrate(self):
+
+        global f
+
+        def f(x):
+
+            if x > 0:
+                return f(x-1)
+            return 1
+
+        for i in xrange(self.rounds):
+            pass
+
+
+### Test to make Fredrik happy...
+
+if __name__ == '__main__':
+    import timeit
+    if 0:
+        timeit.TestClass = PythonFunctionCalls
+        timeit.main(['-s', 'test = TestClass(); test.rounds = 1000',
+                     'test.test()'])
+    else:
+        setup = """\
+global f,f1,g,h
+
+# define functions
+def f():
+    pass
+
+def f1(x):
+    pass
+
+def g(a,b,c):
+    return a,b,c
+
+def h(a,b,c,d=1,e=2,f=3):
+    return d,e,f
+
+i = 1
+"""
+        test = """\
+f()
+f1(i)
+f1(i)
+f1(i)
+f1(i)
+g(i,i,i)
+g(i,i,i)
+g(i,i,i)
+g(i,i,i)
+h(i,i,3,i,i)
+h(i,i,i,2,i,3)
+
+f()
+f1(i)
+f1(i)
+f1(i)
+f1(i)
+g(i,i,i)
+g(i,i,i)
+g(i,i,i)
+g(i,i,i)
+h(i,i,3,i,i)
+h(i,i,i,2,i,3)
+
+f()
+f1(i)
+f1(i)
+f1(i)
+f1(i)
+g(i,i,i)
+g(i,i,i)
+g(i,i,i)
+g(i,i,i)
+h(i,i,3,i,i)
+h(i,i,i,2,i,3)
+
+f()
+f1(i)
+f1(i)
+f1(i)
+f1(i)
+g(i,i,i)
+g(i,i,i)
+g(i,i,i)
+g(i,i,i)
+h(i,i,3,i,i)
+h(i,i,i,2,i,3)
+
+f()
+f1(i)
+f1(i)
+f1(i)
+f1(i)
+g(i,i,i)
+g(i,i,i)
+g(i,i,i)
+g(i,i,i)
+h(i,i,3,i,i)
+h(i,i,i,2,i,3)
+"""
+
+        timeit.main(['-s', setup,
+                     test])

Added: vendor/Python/current/Tools/pybench/CommandLine.py
===================================================================
--- vendor/Python/current/Tools/pybench/CommandLine.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/pybench/CommandLine.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,634 @@
+""" CommandLine - Get and parse command line options
+
+    NOTE: This still is very much work in progress !!!
+
+    Different version are likely to be incompatible.
+
+    TODO:
+
+    * Incorporate the changes made by (see Inbox)
+    * Add number range option using srange()
+
+"""
+
+__copyright__ = """\
+Copyright (c), 1997-2006, Marc-Andre Lemburg (mal at lemburg.com)
+Copyright (c), 2000-2006, eGenix.com Software GmbH (info at egenix.com)
+See the documentation for further information on copyrights,
+or contact the author. All Rights Reserved.
+"""
+
+__version__ = '1.2'
+
+import sys, getopt, string, glob, os, re, exceptions, traceback
+
+### Helpers
+
+def _getopt_flags(options):
+
+    """ Convert the option list to a getopt flag string and long opt
+        list
+
+    """
+    s = []
+    l = []
+    for o in options:
+        if o.prefix == '-':
+            # short option
+            s.append(o.name)
+            if o.takes_argument:
+                s.append(':')
+        else:
+            # long option
+            if o.takes_argument:
+                l.append(o.name+'=')
+            else:
+                l.append(o.name)
+    return string.join(s,''),l
+
+def invisible_input(prompt='>>> '):
+
+    """ Get raw input from a terminal without echoing the characters to
+        the terminal, e.g. for password queries.
+
+    """
+    import getpass
+    entry = getpass.getpass(prompt)
+    if entry is None:
+        raise KeyboardInterrupt
+    return entry
+
+def fileopen(name, mode='wb', encoding=None):
+
+    """ Open a file using mode.
+
+        Default mode is 'wb' meaning to open the file for writing in
+        binary mode. If encoding is given, I/O to and from the file is
+        transparently encoded using the given encoding.
+
+        Files opened for writing are chmod()ed to 0600.
+
+    """
+    if name == 'stdout':
+        return sys.stdout
+    elif name == 'stderr':
+        return sys.stderr
+    elif name == 'stdin':
+        return sys.stdin
+    else:
+        if encoding is not None:
+            import codecs
+            f = codecs.open(name, mode, encoding)
+        else:
+            f = open(name, mode)
+        if 'w' in mode:
+            os.chmod(name, 0600)
+        return f
+
+def option_dict(options):
+
+    """ Return a dictionary mapping option names to Option instances.
+    """
+    d = {}
+    for option in options:
+        d[option.name] = option
+    return d
+
+# Alias
+getpasswd = invisible_input
+
+_integerRE = re.compile('\s*(-?\d+)\s*$')
+_integerRangeRE = re.compile('\s*(-?\d+)\s*-\s*(-?\d+)\s*$')
+
+def srange(s,
+
+           split=string.split,integer=_integerRE,
+           integerRange=_integerRangeRE):
+
+    """ Converts a textual representation of integer numbers and ranges
+        to a Python list.
+
+        Supported formats: 2,3,4,2-10,-1 - -3, 5 - -2
+
+        Values are appended to the created list in the order specified
+        in the string.
+
+    """
+    l = []
+    append = l.append
+    for entry in split(s,','):
+        m = integer.match(entry)
+        if m:
+            append(int(m.groups()[0]))
+            continue
+        m = integerRange.match(entry)
+        if m:
+            start,end = map(int,m.groups())
+            l[len(l):] = range(start,end+1)
+    return l
+
+def abspath(path,
+
+            expandvars=os.path.expandvars,expanduser=os.path.expanduser,
+            join=os.path.join,getcwd=os.getcwd):
+
+    """ Return the corresponding absolute path for path.
+
+        path is expanded in the usual shell ways before
+        joining it with the current working directory.
+
+    """
+    try:
+        path = expandvars(path)
+    except AttributeError:
+        pass
+    try:
+        path = expanduser(path)
+    except AttributeError:
+        pass
+    return join(getcwd(), path)
+
+### Option classes
+
+class Option:
+
+    """ Option base class. Takes no argument.
+
+    """
+    default = None
+    helptext = ''
+    prefix = '-'
+    takes_argument = 0
+    has_default = 0
+    tab = 15
+
+    def __init__(self,name,help=None):
+
+        if not name[:1] == '-':
+            raise TypeError,'option names must start with "-"'
+        if name[1:2] == '-':
+            self.prefix = '--'
+            self.name = name[2:]
+        else:
+            self.name = name[1:]
+        if help:
+            self.help = help
+
+    def __str__(self):
+
+        o = self
+        name = o.prefix + o.name
+        if o.takes_argument:
+            name = name + ' arg'
+        if len(name) > self.tab:
+            name = name + '\n' + ' ' * (self.tab + 1 + len(o.prefix))
+        else:
+            name = '%-*s ' % (self.tab, name)
+        description = o.help
+        if o.has_default:
+            description = description + ' (%s)' % o.default
+        return '%s %s' % (name, description)
+
+class ArgumentOption(Option):
+
+    """ Option that takes an argument.
+
+        An optional default argument can be given.
+
+    """
+    def __init__(self,name,help=None,default=None):
+
+        # Basemethod
+        Option.__init__(self,name,help)
+
+        if default is not None:
+            self.default = default
+            self.has_default = 1
+        self.takes_argument = 1
+
+class SwitchOption(Option):
+
+    """ Options that can be on or off. Has an optional default value.
+
+    """
+    def __init__(self,name,help=None,default=None):
+
+        # Basemethod
+        Option.__init__(self,name,help)
+
+        if default is not None:
+            self.default = default
+            self.has_default = 1
+
+### Application baseclass
+
+class Application:
+
+    """ Command line application interface with builtin argument
+        parsing.
+
+    """
+    # Options the program accepts (Option instances)
+    options = []
+
+    # Standard settings; these are appended to options in __init__
+    preset_options = [SwitchOption('-v',
+                                   'generate verbose output'),
+                      SwitchOption('-h',
+                                   'show this help text'),
+                      SwitchOption('--help',
+                                   'show this help text'),
+                      SwitchOption('--debug',
+                                   'enable debugging'),
+                      SwitchOption('--copyright',
+                                   'show copyright'),
+                      SwitchOption('--examples',
+                                   'show examples of usage')]
+
+    # The help layout looks like this:
+    # [header]   - defaults to ''
+    #
+    # [synopsis] - formatted as '<self.name> %s' % self.synopsis
+    #
+    # options:
+    # [options]  - formatted from self.options
+    #
+    # [version]  - formatted as 'Version:\n %s' % self.version, if given
+    #
+    # [about]    - defaults to ''
+    #
+    # Note: all fields that do not behave as template are formatted
+    #       using the instances dictionary as substitution namespace,
+    #       e.g. %(name)s will be replaced by the applications name.
+    #
+
+    # Header (default to program name)
+    header = ''
+
+    # Name (defaults to program name)
+    name = ''
+
+    # Synopsis (%(name)s is replaced by the program name)
+    synopsis = '%(name)s [option] files...'
+
+    # Version (optional)
+    version = ''
+
+    # General information printed after the possible options (optional)
+    about = ''
+
+    # Examples of usage to show when the --examples option is given (optional)
+    examples = ''
+
+    # Copyright to show
+    copyright = __copyright__
+
+    # Apply file globbing ?
+    globbing = 1
+
+    # Generate debug output ?
+    debug = 0
+
+    # Generate verbose output ?
+    verbose = 0
+
+    # Internal errors to catch
+    InternalError = exceptions.Exception
+
+    # Instance variables:
+    values = None       # Dictionary of passed options (or default values)
+                        # indexed by the options name, e.g. '-h'
+    files = None        # List of passed filenames
+    optionlist = None   # List of passed options
+
+    def __init__(self,argv=None):
+
+        # Setup application specs
+        if argv is None:
+            argv = sys.argv
+        self.filename = os.path.split(argv[0])[1]
+        if not self.name:
+            self.name = os.path.split(self.filename)[1]
+        else:
+            self.name = self.name
+        if not self.header:
+            self.header = self.name
+        else:
+            self.header = self.header
+
+        # Init .arguments list
+        self.arguments = argv[1:]
+
+        # Setup Option mapping
+        self.option_map = option_dict(self.options)
+
+        # Append preset options
+        for option in self.preset_options:
+            if not self.option_map.has_key(option.name):
+                self.add_option(option)
+
+        # Init .files list
+        self.files = []
+
+        # Start Application
+        try:
+            # Process startup
+            rc = self.startup()
+            if rc is not None:
+                raise SystemExit,rc
+
+            # Parse command line
+            rc = self.parse()
+            if rc is not None:
+                raise SystemExit,rc
+
+            # Start application
+            rc = self.main()
+            if rc is None:
+                rc = 0
+
+        except SystemExit,rc:
+            pass
+
+        except KeyboardInterrupt:
+            print
+            print '* User Break'
+            print
+            rc = 1
+
+        except self.InternalError:
+            print
+            print '* Internal Error (use --debug to display the traceback)'
+            if self.debug:
+                print
+                traceback.print_exc(20, sys.stdout)
+            elif self.verbose:
+                print '  %s: %s' % sys.exc_info()[:2]
+            print
+            rc = 1
+
+        raise SystemExit,rc
+
+    def add_option(self, option):
+
+        """ Add a new Option instance to the Application dynamically.
+
+            Note that this has to be done *before* .parse() is being
+            executed.
+
+        """
+        self.options.append(option)
+        self.option_map[option.name] = option
+
+    def startup(self):
+
+        """ Set user defined instance variables.
+
+            If this method returns anything other than None, the
+            process is terminated with the return value as exit code.
+
+        """
+        return None
+
+    def exit(self, rc=0):
+
+        """ Exit the program.
+
+            rc is used as exit code and passed back to the calling
+            program. It defaults to 0 which usually means: OK.
+
+        """
+        raise SystemExit, rc
+
+    def parse(self):
+
+        """ Parse the command line and fill in self.values and self.files.
+
+            After having parsed the options, the remaining command line
+            arguments are interpreted as files and passed to .handle_files()
+            for processing.
+
+            As final step the option handlers are called in the order
+            of the options given on the command line.
+
+        """
+        # Parse arguments
+        self.values = values = {}
+        for o in self.options:
+            if o.has_default:
+                values[o.prefix+o.name] = o.default
+            else:
+                values[o.prefix+o.name] = 0
+        flags,lflags = _getopt_flags(self.options)
+        try:
+            optlist,files = getopt.getopt(self.arguments,flags,lflags)
+            if self.globbing:
+                l = []
+                for f in files:
+                    gf = glob.glob(f)
+                    if not gf:
+                        l.append(f)
+                    else:
+                        l[len(l):] = gf
+                files = l
+            self.optionlist = optlist
+            self.files = files + self.files
+        except getopt.error,why:
+            self.help(why)
+            sys.exit(1)
+
+        # Call file handler
+        rc = self.handle_files(self.files)
+        if rc is not None:
+            sys.exit(rc)
+
+        # Call option handlers
+        for optionname, value in optlist:
+
+            # Try to convert value to integer
+            try:
+                value = string.atoi(value)
+            except ValueError:
+                pass
+
+            # Find handler and call it (or count the number of option
+            # instances on the command line)
+            handlername = 'handle' + string.replace(optionname, '-', '_')
+            try:
+                handler = getattr(self, handlername)
+            except AttributeError:
+                if value == '':
+                    # count the number of occurances
+                    if values.has_key(optionname):
+                        values[optionname] = values[optionname] + 1
+                    else:
+                        values[optionname] = 1
+                else:
+                    values[optionname] = value
+            else:
+                rc = handler(value)
+                if rc is not None:
+                    raise SystemExit, rc
+
+        # Apply final file check (for backward compatibility)
+        rc = self.check_files(self.files)
+        if rc is not None:
+            sys.exit(rc)
+
+    def check_files(self,filelist):
+
+        """ Apply some user defined checks on the files given in filelist.
+
+            This may modify filelist in place. A typical application
+            is checking that at least n files are given.
+
+            If this method returns anything other than None, the
+            process is terminated with the return value as exit code.
+
+        """
+        return None
+
+    def help(self,note=''):
+
+        self.print_header()
+        if self.synopsis:
+            print 'Synopsis:'
+            # To remain backward compatible:
+            try:
+                synopsis = self.synopsis % self.name
+            except (NameError, KeyError, TypeError):
+                synopsis = self.synopsis % self.__dict__
+            print ' ' + synopsis
+        print
+        self.print_options()
+        if self.version:
+            print 'Version:'
+            print ' %s' % self.version
+            print
+        if self.about:
+            print string.strip(self.about % self.__dict__)
+            print
+        if note:
+            print '-'*72
+            print 'Note:',note
+            print
+
+    def notice(self,note):
+
+        print '-'*72
+        print 'Note:',note
+        print '-'*72
+        print
+
+    def print_header(self):
+
+        print '-'*72
+        print self.header % self.__dict__
+        print '-'*72
+        print
+
+    def print_options(self):
+
+        options = self.options
+        print 'Options and default settings:'
+        if not options:
+            print '  None'
+            return
+        long = filter(lambda x: x.prefix == '--', options)
+        short = filter(lambda x: x.prefix == '-', options)
+        items = short + long
+        for o in options:
+            print ' ',o
+        print
+
+    #
+    # Example handlers:
+    #
+    # If a handler returns anything other than None, processing stops
+    # and the return value is passed to sys.exit() as argument.
+    #
+
+    # File handler
+    def handle_files(self,files):
+
+        """ This may process the files list in place.
+        """
+        return None
+
+    # Short option handler
+    def handle_h(self,arg):
+
+        self.help()
+        return 0
+
+    def handle_v(self, value):
+
+        """ Turn on verbose output.
+        """
+        self.verbose = 1
+
+    # Handlers for long options have two underscores in their name
+    def handle__help(self,arg):
+
+        self.help()
+        return 0
+
+    def handle__debug(self,arg):
+
+        self.debug = 1
+        # We don't want to catch internal errors:
+        self.InternalError = None
+
+    def handle__copyright(self,arg):
+
+        self.print_header()
+        print string.strip(self.copyright % self.__dict__)
+        print
+        return 0
+
+    def handle__examples(self,arg):
+
+        self.print_header()
+        if self.examples:
+            print 'Examples:'
+            print
+            print string.strip(self.examples % self.__dict__)
+            print
+        else:
+            print 'No examples available.'
+            print
+        return 0
+
+    def main(self):
+
+        """ Override this method as program entry point.
+
+            The return value is passed to sys.exit() as argument.  If
+            it is None, 0 is assumed (meaning OK). Unhandled
+            exceptions are reported with exit status code 1 (see
+            __init__ for further details).
+
+        """
+        return None
+
+# Alias
+CommandLine = Application
+
+def _test():
+
+    class MyApplication(Application):
+        header = 'Test Application'
+        version = __version__
+        options = [Option('-v','verbose')]
+
+        def handle_v(self,arg):
+            print 'VERBOSE, Yeah !'
+
+    cmd = MyApplication()
+    if not cmd.values['-h']:
+        cmd.help()
+    print 'files:',cmd.files
+    print 'Bye...'
+
+if __name__ == '__main__':
+    _test()

Added: vendor/Python/current/Tools/pybench/Constructs.py
===================================================================
--- vendor/Python/current/Tools/pybench/Constructs.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/pybench/Constructs.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,564 @@
+from pybench import Test
+
+class IfThenElse(Test):
+
+    version = 2.0
+    operations = 30*3 # hard to say...
+    rounds = 150000
+
+    def test(self):
+
+        a,b,c = 1,2,3
+        for i in xrange(self.rounds):
+
+            if a == 1:
+                if b == 2:
+                    if c != 3:
+                        c = 3
+                        b = 3
+                    else:
+                        c = 2
+                elif b == 3:
+                    b = 2
+                    a = 2
+            elif a == 2:
+                a = 3
+            else:
+                a = 1
+
+            if a == 1:
+                if b == 2:
+                    if c != 3:
+                        c = 3
+                        b = 3
+                    else:
+                        c = 2
+                elif b == 3:
+                    b = 2
+                    a = 2
+            elif a == 2:
+                a = 3
+            else:
+                a = 1
+
+            if a == 1:
+                if b == 2:
+                    if c != 3:
+                        c = 3
+                        b = 3
+                    else:
+                        c = 2
+                elif b == 3:
+                    b = 2
+                    a = 2
+            elif a == 2:
+                a = 3
+            else:
+                a = 1
+
+            if a == 1:
+                if b == 2:
+                    if c != 3:
+                        c = 3
+                        b = 3
+                    else:
+                        c = 2
+                elif b == 3:
+                    b = 2
+                    a = 2
+            elif a == 2:
+                a = 3
+            else:
+                a = 1
+
+            if a == 1:
+                if b == 2:
+                    if c != 3:
+                        c = 3
+                        b = 3
+                    else:
+                        c = 2
+                elif b == 3:
+                    b = 2
+                    a = 2
+            elif a == 2:
+                a = 3
+            else:
+                a = 1
+
+            if a == 1:
+                if b == 2:
+                    if c != 3:
+                        c = 3
+                        b = 3
+                    else:
+                        c = 2
+                elif b == 3:
+                    b = 2
+                    a = 2
+            elif a == 2:
+                a = 3
+            else:
+                a = 1
+
+            if a == 1:
+                if b == 2:
+                    if c != 3:
+                        c = 3
+                        b = 3
+                    else:
+                        c = 2
+                elif b == 3:
+                    b = 2
+                    a = 2
+            elif a == 2:
+                a = 3
+            else:
+                a = 1
+
+            if a == 1:
+                if b == 2:
+                    if c != 3:
+                        c = 3
+                        b = 3
+                    else:
+                        c = 2
+                elif b == 3:
+                    b = 2
+                    a = 2
+            elif a == 2:
+                a = 3
+            else:
+                a = 1
+
+            if a == 1:
+                if b == 2:
+                    if c != 3:
+                        c = 3
+                        b = 3
+                    else:
+                        c = 2
+                elif b == 3:
+                    b = 2
+                    a = 2
+            elif a == 2:
+                a = 3
+            else:
+                a = 1
+
+            if a == 1:
+                if b == 2:
+                    if c != 3:
+                        c = 3
+                        b = 3
+                    else:
+                        c = 2
+                elif b == 3:
+                    b = 2
+                    a = 2
+            elif a == 2:
+                a = 3
+            else:
+                a = 1
+
+            if a == 1:
+                if b == 2:
+                    if c != 3:
+                        c = 3
+                        b = 3
+                    else:
+                        c = 2
+                elif b == 3:
+                    b = 2
+                    a = 2
+            elif a == 2:
+                a = 3
+            else:
+                a = 1
+
+            if a == 1:
+                if b == 2:
+                    if c != 3:
+                        c = 3
+                        b = 3
+                    else:
+                        c = 2
+                elif b == 3:
+                    b = 2
+                    a = 2
+            elif a == 2:
+                a = 3
+            else:
+                a = 1
+
+            if a == 1:
+                if b == 2:
+                    if c != 3:
+                        c = 3
+                        b = 3
+                    else:
+                        c = 2
+                elif b == 3:
+                    b = 2
+                    a = 2
+            elif a == 2:
+                a = 3
+            else:
+                a = 1
+
+            if a == 1:
+                if b == 2:
+                    if c != 3:
+                        c = 3
+                        b = 3
+                    else:
+                        c = 2
+                elif b == 3:
+                    b = 2
+                    a = 2
+            elif a == 2:
+                a = 3
+            else:
+                a = 1
+
+            if a == 1:
+                if b == 2:
+                    if c != 3:
+                        c = 3
+                        b = 3
+                    else:
+                        c = 2
+                elif b == 3:
+                    b = 2
+                    a = 2
+            elif a == 2:
+                a = 3
+            else:
+                a = 1
+
+            if a == 1:
+                if b == 2:
+                    if c != 3:
+                        c = 3
+                        b = 3
+                    else:
+                        c = 2
+                elif b == 3:
+                    b = 2
+                    a = 2
+            elif a == 2:
+                a = 3
+            else:
+                a = 1
+
+            if a == 1:
+                if b == 2:
+                    if c != 3:
+                        c = 3
+                        b = 3
+                    else:
+                        c = 2
+                elif b == 3:
+                    b = 2
+                    a = 2
+            elif a == 2:
+                a = 3
+            else:
+                a = 1
+
+            if a == 1:
+                if b == 2:
+                    if c != 3:
+                        c = 3
+                        b = 3
+                    else:
+                        c = 2
+                elif b == 3:
+                    b = 2
+                    a = 2
+            elif a == 2:
+                a = 3
+            else:
+                a = 1
+
+            if a == 1:
+                if b == 2:
+                    if c != 3:
+                        c = 3
+                        b = 3
+                    else:
+                        c = 2
+                elif b == 3:
+                    b = 2
+                    a = 2
+            elif a == 2:
+                a = 3
+            else:
+                a = 1
+
+            if a == 1:
+                if b == 2:
+                    if c != 3:
+                        c = 3
+                        b = 3
+                    else:
+                        c = 2
+                elif b == 3:
+                    b = 2
+                    a = 2
+            elif a == 2:
+                a = 3
+            else:
+                a = 1
+
+            if a == 1:
+                if b == 2:
+                    if c != 3:
+                        c = 3
+                        b = 3
+                    else:
+                        c = 2
+                elif b == 3:
+                    b = 2
+                    a = 2
+            elif a == 2:
+                a = 3
+            else:
+                a = 1
+
+            if a == 1:
+                if b == 2:
+                    if c != 3:
+                        c = 3
+                        b = 3
+                    else:
+                        c = 2
+                elif b == 3:
+                    b = 2
+                    a = 2
+            elif a == 2:
+                a = 3
+            else:
+                a = 1
+
+            if a == 1:
+                if b == 2:
+                    if c != 3:
+                        c = 3
+                        b = 3
+                    else:
+                        c = 2
+                elif b == 3:
+                    b = 2
+                    a = 2
+            elif a == 2:
+                a = 3
+            else:
+                a = 1
+
+            if a == 1:
+                if b == 2:
+                    if c != 3:
+                        c = 3
+                        b = 3
+                    else:
+                        c = 2
+                elif b == 3:
+                    b = 2
+                    a = 2
+            elif a == 2:
+                a = 3
+            else:
+                a = 1
+
+            if a == 1:
+                if b == 2:
+                    if c != 3:
+                        c = 3
+                        b = 3
+                    else:
+                        c = 2
+                elif b == 3:
+                    b = 2
+                    a = 2
+            elif a == 2:
+                a = 3
+            else:
+                a = 1
+
+            if a == 1:
+                if b == 2:
+                    if c != 3:
+                        c = 3
+                        b = 3
+                    else:
+                        c = 2
+                elif b == 3:
+                    b = 2
+                    a = 2
+            elif a == 2:
+                a = 3
+            else:
+                a = 1
+
+            if a == 1:
+                if b == 2:
+                    if c != 3:
+                        c = 3
+                        b = 3
+                    else:
+                        c = 2
+                elif b == 3:
+                    b = 2
+                    a = 2
+            elif a == 2:
+                a = 3
+            else:
+                a = 1
+
+            if a == 1:
+                if b == 2:
+                    if c != 3:
+                        c = 3
+                        b = 3
+                    else:
+                        c = 2
+                elif b == 3:
+                    b = 2
+                    a = 2
+            elif a == 2:
+                a = 3
+            else:
+                a = 1
+
+            if a == 1:
+                if b == 2:
+                    if c != 3:
+                        c = 3
+                        b = 3
+                    else:
+                        c = 2
+                elif b == 3:
+                    b = 2
+                    a = 2
+            elif a == 2:
+                a = 3
+            else:
+                a = 1
+
+            if a == 1:
+                if b == 2:
+                    if c != 3:
+                        c = 3
+                        b = 3
+                    else:
+                        c = 2
+                elif b == 3:
+                    b = 2
+                    a = 2
+            elif a == 2:
+                a = 3
+            else:
+                a = 1
+
+    def calibrate(self):
+
+        a,b,c = 1,2,3
+        for i in xrange(self.rounds):
+            pass
+
+class NestedForLoops(Test):
+
+    version = 2.0
+    operations = 1000*10*5
+    rounds = 300
+
+    def test(self):
+
+        l1 = range(1000)
+        l2 = range(10)
+        l3 = range(5)
+        for i in xrange(self.rounds):
+            for i in l1:
+                for j in l2:
+                    for k in l3:
+                        pass
+
+    def calibrate(self):
+
+        l1 = range(1000)
+        l2 = range(10)
+        l3 = range(5)
+        for i in xrange(self.rounds):
+            pass
+
+class ForLoops(Test):
+
+    version = 2.0
+    operations = 5 * 5
+    rounds = 10000
+
+    def test(self):
+
+        l1 = range(100)
+        for i in xrange(self.rounds):
+            for i in l1:
+                pass
+            for i in l1:
+                pass
+            for i in l1:
+                pass
+            for i in l1:
+                pass
+            for i in l1:
+                pass
+
+            for i in l1:
+                pass
+            for i in l1:
+                pass
+            for i in l1:
+                pass
+            for i in l1:
+                pass
+            for i in l1:
+                pass
+
+            for i in l1:
+                pass
+            for i in l1:
+                pass
+            for i in l1:
+                pass
+            for i in l1:
+                pass
+            for i in l1:
+                pass
+
+            for i in l1:
+                pass
+            for i in l1:
+                pass
+            for i in l1:
+                pass
+            for i in l1:
+                pass
+            for i in l1:
+                pass
+
+            for i in l1:
+                pass
+            for i in l1:
+                pass
+            for i in l1:
+                pass
+            for i in l1:
+                pass
+            for i in l1:
+                pass
+
+    def calibrate(self):
+
+        l1 = range(1000)
+        for i in xrange(self.rounds):
+            pass

Added: vendor/Python/current/Tools/pybench/Dict.py
===================================================================
--- vendor/Python/current/Tools/pybench/Dict.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/pybench/Dict.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,504 @@
+from pybench import Test
+
+class DictCreation(Test):
+
+    version = 2.0
+    operations = 5*(5 + 5)
+    rounds = 80000
+
+    def test(self):
+
+        for i in xrange(self.rounds):
+
+            d1 = {}
+            d2 = {}
+            d3 = {}
+            d4 = {}
+            d5 = {}
+
+            d1 = {1:2,3:4,5:6}
+            d2 = {2:3,4:5,6:7}
+            d3 = {3:4,5:6,7:8}
+            d4 = {4:5,6:7,8:9}
+            d5 = {6:7,8:9,10:11}
+
+            d1 = {}
+            d2 = {}
+            d3 = {}
+            d4 = {}
+            d5 = {}
+
+            d1 = {1:2,3:4,5:6}
+            d2 = {2:3,4:5,6:7}
+            d3 = {3:4,5:6,7:8}
+            d4 = {4:5,6:7,8:9}
+            d5 = {6:7,8:9,10:11}
+
+            d1 = {}
+            d2 = {}
+            d3 = {}
+            d4 = {}
+            d5 = {}
+
+            d1 = {1:2,3:4,5:6}
+            d2 = {2:3,4:5,6:7}
+            d3 = {3:4,5:6,7:8}
+            d4 = {4:5,6:7,8:9}
+            d5 = {6:7,8:9,10:11}
+
+            d1 = {}
+            d2 = {}
+            d3 = {}
+            d4 = {}
+            d5 = {}
+
+            d1 = {1:2,3:4,5:6}
+            d2 = {2:3,4:5,6:7}
+            d3 = {3:4,5:6,7:8}
+            d4 = {4:5,6:7,8:9}
+            d5 = {6:7,8:9,10:11}
+
+            d1 = {}
+            d2 = {}
+            d3 = {}
+            d4 = {}
+            d5 = {}
+
+            d1 = {1:2,3:4,5:6}
+            d2 = {2:3,4:5,6:7}
+            d3 = {3:4,5:6,7:8}
+            d4 = {4:5,6:7,8:9}
+            d5 = {6:7,8:9,10:11}
+
+    def calibrate(self):
+
+        for i in xrange(self.rounds):
+            pass
+
+class DictWithStringKeys(Test):
+
+    version = 2.0
+    operations = 5*(6 + 6)
+    rounds = 200000
+
+    def test(self):
+
+        d = {}
+
+        for i in xrange(self.rounds):
+
+            d['abc'] = 1
+            d['def'] = 2
+            d['ghi'] = 3
+            d['jkl'] = 4
+            d['mno'] = 5
+            d['pqr'] = 6
+
+            d['abc']
+            d['def']
+            d['ghi']
+            d['jkl']
+            d['mno']
+            d['pqr']
+
+            d['abc'] = 1
+            d['def'] = 2
+            d['ghi'] = 3
+            d['jkl'] = 4
+            d['mno'] = 5
+            d['pqr'] = 6
+
+            d['abc']
+            d['def']
+            d['ghi']
+            d['jkl']
+            d['mno']
+            d['pqr']
+
+            d['abc'] = 1
+            d['def'] = 2
+            d['ghi'] = 3
+            d['jkl'] = 4
+            d['mno'] = 5
+            d['pqr'] = 6
+
+            d['abc']
+            d['def']
+            d['ghi']
+            d['jkl']
+            d['mno']
+            d['pqr']
+
+            d['abc'] = 1
+            d['def'] = 2
+            d['ghi'] = 3
+            d['jkl'] = 4
+            d['mno'] = 5
+            d['pqr'] = 6
+
+            d['abc']
+            d['def']
+            d['ghi']
+            d['jkl']
+            d['mno']
+            d['pqr']
+
+            d['abc'] = 1
+            d['def'] = 2
+            d['ghi'] = 3
+            d['jkl'] = 4
+            d['mno'] = 5
+            d['pqr'] = 6
+
+            d['abc']
+            d['def']
+            d['ghi']
+            d['jkl']
+            d['mno']
+            d['pqr']
+
+    def calibrate(self):
+
+        d = {}
+
+        for i in xrange(self.rounds):
+            pass
+
+class DictWithFloatKeys(Test):
+
+    version = 2.0
+    operations = 5*(6 + 6)
+    rounds = 150000
+
+    def test(self):
+
+        d = {}
+
+        for i in xrange(self.rounds):
+
+            d[1.234] = 1
+            d[2.345] = 2
+            d[3.456] = 3
+            d[4.567] = 4
+            d[5.678] = 5
+            d[6.789] = 6
+
+            d[1.234]
+            d[2.345]
+            d[3.456]
+            d[4.567]
+            d[5.678]
+            d[6.789]
+
+            d[1.234] = 1
+            d[2.345] = 2
+            d[3.456] = 3
+            d[4.567] = 4
+            d[5.678] = 5
+            d[6.789] = 6
+
+            d[1.234]
+            d[2.345]
+            d[3.456]
+            d[4.567]
+            d[5.678]
+            d[6.789]
+
+            d[1.234] = 1
+            d[2.345] = 2
+            d[3.456] = 3
+            d[4.567] = 4
+            d[5.678] = 5
+            d[6.789] = 6
+
+            d[1.234]
+            d[2.345]
+            d[3.456]
+            d[4.567]
+            d[5.678]
+            d[6.789]
+
+            d[1.234] = 1
+            d[2.345] = 2
+            d[3.456] = 3
+            d[4.567] = 4
+            d[5.678] = 5
+            d[6.789] = 6
+
+            d[1.234]
+            d[2.345]
+            d[3.456]
+            d[4.567]
+            d[5.678]
+            d[6.789]
+
+            d[1.234] = 1
+            d[2.345] = 2
+            d[3.456] = 3
+            d[4.567] = 4
+            d[5.678] = 5
+            d[6.789] = 6
+
+            d[1.234]
+            d[2.345]
+            d[3.456]
+            d[4.567]
+            d[5.678]
+            d[6.789]
+
+    def calibrate(self):
+
+        d = {}
+
+        for i in xrange(self.rounds):
+            pass
+
+class DictWithIntegerKeys(Test):
+
+    version = 2.0
+    operations = 5*(6 + 6)
+    rounds = 200000
+
+    def test(self):
+
+        d = {}
+
+        for i in xrange(self.rounds):
+
+            d[1] = 1
+            d[2] = 2
+            d[3] = 3
+            d[4] = 4
+            d[5] = 5
+            d[6] = 6
+
+            d[1]
+            d[2]
+            d[3]
+            d[4]
+            d[5]
+            d[6]
+
+            d[1] = 1
+            d[2] = 2
+            d[3] = 3
+            d[4] = 4
+            d[5] = 5
+            d[6] = 6
+
+            d[1]
+            d[2]
+            d[3]
+            d[4]
+            d[5]
+            d[6]
+
+            d[1] = 1
+            d[2] = 2
+            d[3] = 3
+            d[4] = 4
+            d[5] = 5
+            d[6] = 6
+
+            d[1]
+            d[2]
+            d[3]
+            d[4]
+            d[5]
+            d[6]
+
+            d[1] = 1
+            d[2] = 2
+            d[3] = 3
+            d[4] = 4
+            d[5] = 5
+            d[6] = 6
+
+            d[1]
+            d[2]
+            d[3]
+            d[4]
+            d[5]
+            d[6]
+
+            d[1] = 1
+            d[2] = 2
+            d[3] = 3
+            d[4] = 4
+            d[5] = 5
+            d[6] = 6
+
+            d[1]
+            d[2]
+            d[3]
+            d[4]
+            d[5]
+            d[6]
+
+    def calibrate(self):
+
+        d = {}
+
+        for i in xrange(self.rounds):
+            pass
+
+class SimpleDictManipulation(Test):
+
+    version = 2.0
+    operations = 5*(6 + 6 + 6 + 6)
+    rounds = 100000
+
+    def test(self):
+
+        d = {}
+        has_key = d.has_key
+
+        for i in xrange(self.rounds):
+
+            d[0] = 3
+            d[1] = 4
+            d[2] = 5
+            d[3] = 3
+            d[4] = 4
+            d[5] = 5
+
+            x = d[0]
+            x = d[1]
+            x = d[2]
+            x = d[3]
+            x = d[4]
+            x = d[5]
+
+            has_key(0)
+            has_key(2)
+            has_key(4)
+            has_key(6)
+            has_key(8)
+            has_key(10)
+
+            del d[0]
+            del d[1]
+            del d[2]
+            del d[3]
+            del d[4]
+            del d[5]
+
+            d[0] = 3
+            d[1] = 4
+            d[2] = 5
+            d[3] = 3
+            d[4] = 4
+            d[5] = 5
+
+            x = d[0]
+            x = d[1]
+            x = d[2]
+            x = d[3]
+            x = d[4]
+            x = d[5]
+
+            has_key(0)
+            has_key(2)
+            has_key(4)
+            has_key(6)
+            has_key(8)
+            has_key(10)
+
+            del d[0]
+            del d[1]
+            del d[2]
+            del d[3]
+            del d[4]
+            del d[5]
+
+            d[0] = 3
+            d[1] = 4
+            d[2] = 5
+            d[3] = 3
+            d[4] = 4
+            d[5] = 5
+
+            x = d[0]
+            x = d[1]
+            x = d[2]
+            x = d[3]
+            x = d[4]
+            x = d[5]
+
+            has_key(0)
+            has_key(2)
+            has_key(4)
+            has_key(6)
+            has_key(8)
+            has_key(10)
+
+            del d[0]
+            del d[1]
+            del d[2]
+            del d[3]
+            del d[4]
+            del d[5]
+
+            d[0] = 3
+            d[1] = 4
+            d[2] = 5
+            d[3] = 3
+            d[4] = 4
+            d[5] = 5
+
+            x = d[0]
+            x = d[1]
+            x = d[2]
+            x = d[3]
+            x = d[4]
+            x = d[5]
+
+            has_key(0)
+            has_key(2)
+            has_key(4)
+            has_key(6)
+            has_key(8)
+            has_key(10)
+
+            del d[0]
+            del d[1]
+            del d[2]
+            del d[3]
+            del d[4]
+            del d[5]
+
+            d[0] = 3
+            d[1] = 4
+            d[2] = 5
+            d[3] = 3
+            d[4] = 4
+            d[5] = 5
+
+            x = d[0]
+            x = d[1]
+            x = d[2]
+            x = d[3]
+            x = d[4]
+            x = d[5]
+
+            has_key(0)
+            has_key(2)
+            has_key(4)
+            has_key(6)
+            has_key(8)
+            has_key(10)
+
+            del d[0]
+            del d[1]
+            del d[2]
+            del d[3]
+            del d[4]
+            del d[5]
+
+    def calibrate(self):
+
+        d = {}
+        has_key = d.has_key
+
+        for i in xrange(self.rounds):
+            pass

Added: vendor/Python/current/Tools/pybench/Exceptions.py
===================================================================
--- vendor/Python/current/Tools/pybench/Exceptions.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/pybench/Exceptions.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,699 @@
+from pybench import Test
+
+class TryRaiseExcept(Test):
+
+    version = 2.0
+    operations = 2 + 3 + 3
+    rounds = 80000
+
+    def test(self):
+
+        error = ValueError
+
+        for i in xrange(self.rounds):
+            try:
+                raise error
+            except:
+                pass
+            try:
+                raise error
+            except:
+                pass
+            try:
+                raise error,"something"
+            except:
+                pass
+            try:
+                raise error,"something"
+            except:
+                pass
+            try:
+                raise error,"something"
+            except:
+                pass
+            try:
+                raise error("something")
+            except:
+                pass
+            try:
+                raise error("something")
+            except:
+                pass
+            try:
+                raise error("something")
+            except:
+                pass
+
+    def calibrate(self):
+
+        error = ValueError
+
+        for i in xrange(self.rounds):
+            pass
+
+
+class TryExcept(Test):
+
+    version = 2.0
+    operations = 15 * 10
+    rounds = 150000
+
+    def test(self):
+
+        for i in xrange(self.rounds):
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+
+
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+
+
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+
+
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+
+
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+
+
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+
+
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+
+
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+
+
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+
+
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+            try:
+                pass
+            except:
+                pass
+
+    def calibrate(self):
+
+        for i in xrange(self.rounds):
+            pass
+
+### Test to make Fredrik happy...
+
+if __name__ == '__main__':
+    import timeit
+    timeit.TestClass = TryRaiseExcept
+    timeit.main(['-s', 'test = TestClass(); test.rounds = 1000',
+                 'test.test()'])

Added: vendor/Python/current/Tools/pybench/Imports.py
===================================================================
--- vendor/Python/current/Tools/pybench/Imports.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/pybench/Imports.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,138 @@
+from pybench import Test
+
+# First imports:
+import os
+import package.submodule
+
+class SecondImport(Test):
+
+    version = 2.0
+    operations = 5 * 5
+    rounds = 40000
+
+    def test(self):
+
+        for i in xrange(self.rounds):
+            import os
+            import os
+            import os
+            import os
+            import os
+
+            import os
+            import os
+            import os
+            import os
+            import os
+
+            import os
+            import os
+            import os
+            import os
+            import os
+
+            import os
+            import os
+            import os
+            import os
+            import os
+
+            import os
+            import os
+            import os
+            import os
+            import os
+
+    def calibrate(self):
+
+        for i in xrange(self.rounds):
+            pass
+
+
+class SecondPackageImport(Test):
+
+    version = 2.0
+    operations = 5 * 5
+    rounds = 40000
+
+    def test(self):
+
+        for i in xrange(self.rounds):
+            import package
+            import package
+            import package
+            import package
+            import package
+
+            import package
+            import package
+            import package
+            import package
+            import package
+
+            import package
+            import package
+            import package
+            import package
+            import package
+
+            import package
+            import package
+            import package
+            import package
+            import package
+
+            import package
+            import package
+            import package
+            import package
+            import package
+
+    def calibrate(self):
+
+        for i in xrange(self.rounds):
+            pass
+
+class SecondSubmoduleImport(Test):
+
+    version = 2.0
+    operations = 5 * 5
+    rounds = 40000
+
+    def test(self):
+
+        for i in xrange(self.rounds):
+            import package.submodule
+            import package.submodule
+            import package.submodule
+            import package.submodule
+            import package.submodule
+
+            import package.submodule
+            import package.submodule
+            import package.submodule
+            import package.submodule
+            import package.submodule
+
+            import package.submodule
+            import package.submodule
+            import package.submodule
+            import package.submodule
+            import package.submodule
+
+            import package.submodule
+            import package.submodule
+            import package.submodule
+            import package.submodule
+            import package.submodule
+
+            import package.submodule
+            import package.submodule
+            import package.submodule
+            import package.submodule
+            import package.submodule
+
+    def calibrate(self):
+
+        for i in xrange(self.rounds):
+            pass

Added: vendor/Python/current/Tools/pybench/Instances.py
===================================================================
--- vendor/Python/current/Tools/pybench/Instances.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/pybench/Instances.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,66 @@
+from pybench import Test
+
+class CreateInstances(Test):
+
+    version = 2.0
+    operations = 3 + 7 + 4
+    rounds = 80000
+
+    def test(self):
+
+        class c:
+            pass
+
+        class d:
+            def __init__(self,a,b,c):
+                self.a = a
+                self.b = b
+                self.c = c
+
+        class e:
+            def __init__(self,a,b,c=4):
+                self.a = a
+                self.b = b
+                self.c = c
+                self.d = a
+                self.e = b
+                self.f = c
+
+        for i in xrange(self.rounds):
+            o = c()
+            o1 = c()
+            o2 = c()
+            p = d(i,i,3)
+            p1 = d(i,i,3)
+            p2 = d(i,3,3)
+            p3 = d(3,i,3)
+            p4 = d(i,i,i)
+            p5 = d(3,i,3)
+            p6 = d(i,i,i)
+            q = e(i,i,3)
+            q1 = e(i,i,3)
+            q2 = e(i,i,3)
+            q3 = e(i,i)
+
+    def calibrate(self):
+
+        class c:
+            pass
+
+        class d:
+            def __init__(self,a,b,c):
+                self.a = a
+                self.b = b
+                self.c = c
+
+        class e:
+            def __init__(self,a,b,c=4):
+                self.a = a
+                self.b = b
+                self.c = c
+                self.d = a
+                self.e = b
+                self.f = c
+
+        for i in xrange(self.rounds):
+            pass

Added: vendor/Python/current/Tools/pybench/LICENSE
===================================================================
--- vendor/Python/current/Tools/pybench/LICENSE	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/pybench/LICENSE	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,25 @@
+pybench License
+---------------
+
+This copyright notice and license applies to all files in the pybench
+directory of the pybench distribution.
+
+Copyright (c), 1997-2006, Marc-Andre Lemburg (mal at lemburg.com)
+Copyright (c), 2000-2006, eGenix.com Software GmbH (info at egenix.com)
+
+                   All Rights Reserved.
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee or royalty is hereby
+granted, provided that the above copyright notice appear in all copies
+and that both that copyright notice and this permission notice appear
+in supporting documentation or portions thereof, including
+modifications, that you make.
+
+THE AUTHOR MARC-ANDRE LEMBURG DISCLAIMS ALL WARRANTIES WITH REGARD TO
+THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
+INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+WITH THE USE OR PERFORMANCE OF THIS SOFTWARE !

Added: vendor/Python/current/Tools/pybench/Lists.py
===================================================================
--- vendor/Python/current/Tools/pybench/Lists.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/pybench/Lists.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,295 @@
+from pybench import Test
+
+class SimpleListManipulation(Test):
+
+    version = 2.0
+    operations = 5* (6 + 6 + 6)
+    rounds = 130000
+
+    def test(self):
+
+        l = []
+        append = l.append
+
+        for i in xrange(self.rounds):
+
+            append(2)
+            append(3)
+            append(4)
+            append(2)
+            append(3)
+            append(4)
+
+            l[0] = 3
+            l[1] = 4
+            l[2] = 5
+            l[3] = 3
+            l[4] = 4
+            l[5] = 5
+
+            x = l[0]
+            x = l[1]
+            x = l[2]
+            x = l[3]
+            x = l[4]
+            x = l[5]
+
+            append(2)
+            append(3)
+            append(4)
+            append(2)
+            append(3)
+            append(4)
+
+            l[0] = 3
+            l[1] = 4
+            l[2] = 5
+            l[3] = 3
+            l[4] = 4
+            l[5] = 5
+
+            x = l[0]
+            x = l[1]
+            x = l[2]
+            x = l[3]
+            x = l[4]
+            x = l[5]
+
+            append(2)
+            append(3)
+            append(4)
+            append(2)
+            append(3)
+            append(4)
+
+            l[0] = 3
+            l[1] = 4
+            l[2] = 5
+            l[3] = 3
+            l[4] = 4
+            l[5] = 5
+
+            x = l[0]
+            x = l[1]
+            x = l[2]
+            x = l[3]
+            x = l[4]
+            x = l[5]
+
+            append(2)
+            append(3)
+            append(4)
+            append(2)
+            append(3)
+            append(4)
+
+            l[0] = 3
+            l[1] = 4
+            l[2] = 5
+            l[3] = 3
+            l[4] = 4
+            l[5] = 5
+
+            x = l[0]
+            x = l[1]
+            x = l[2]
+            x = l[3]
+            x = l[4]
+            x = l[5]
+
+            append(2)
+            append(3)
+            append(4)
+            append(2)
+            append(3)
+            append(4)
+
+            l[0] = 3
+            l[1] = 4
+            l[2] = 5
+            l[3] = 3
+            l[4] = 4
+            l[5] = 5
+
+            x = l[0]
+            x = l[1]
+            x = l[2]
+            x = l[3]
+            x = l[4]
+            x = l[5]
+
+            if len(l) > 10000:
+                # cut down the size
+                del l[:]
+
+    def calibrate(self):
+
+        l = []
+        append = l.append
+
+        for i in xrange(self.rounds):
+            pass
+
+class ListSlicing(Test):
+
+    version = 2.0
+    operations = 25*(3+1+2+1)
+    rounds = 800
+
+    def test(self):
+
+        n = range(100)
+        r = range(25)
+
+        for i in xrange(self.rounds):
+
+            l = n[:]
+
+            for j in r:
+
+                m = l[50:]
+                m = l[:25]
+                m = l[50:55]
+                l[:3] = n
+                m = l[:-1]
+                m = l[1:]
+                l[-1:] = n
+
+    def calibrate(self):
+
+        n = range(100)
+        r = range(25)
+
+        for i in xrange(self.rounds):
+            for j in r:
+                pass
+
+class SmallLists(Test):
+
+    version = 2.0
+    operations = 5*(1+ 6 + 6 + 3 + 1)
+    rounds = 80000
+
+    def test(self):
+
+        for i in xrange(self.rounds):
+
+            l = []
+
+            append = l.append
+            append(2)
+            append(3)
+            append(4)
+            append(2)
+            append(3)
+            append(4)
+
+            l[0] = 3
+            l[1] = 4
+            l[2] = 5
+            l[3] = 3
+            l[4] = 4
+            l[5] = 5
+
+            l[:3] = [1,2,3]
+            m = l[:-1]
+            m = l[1:]
+
+            l[-1:] = [4,5,6]
+
+            l = []
+
+            append = l.append
+            append(2)
+            append(3)
+            append(4)
+            append(2)
+            append(3)
+            append(4)
+
+            l[0] = 3
+            l[1] = 4
+            l[2] = 5
+            l[3] = 3
+            l[4] = 4
+            l[5] = 5
+
+            l[:3] = [1,2,3]
+            m = l[:-1]
+            m = l[1:]
+
+            l[-1:] = [4,5,6]
+
+            l = []
+
+            append = l.append
+            append(2)
+            append(3)
+            append(4)
+            append(2)
+            append(3)
+            append(4)
+
+            l[0] = 3
+            l[1] = 4
+            l[2] = 5
+            l[3] = 3
+            l[4] = 4
+            l[5] = 5
+
+            l[:3] = [1,2,3]
+            m = l[:-1]
+            m = l[1:]
+
+            l[-1:] = [4,5,6]
+
+            l = []
+
+            append = l.append
+            append(2)
+            append(3)
+            append(4)
+            append(2)
+            append(3)
+            append(4)
+
+            l[0] = 3
+            l[1] = 4
+            l[2] = 5
+            l[3] = 3
+            l[4] = 4
+            l[5] = 5
+
+            l[:3] = [1,2,3]
+            m = l[:-1]
+            m = l[1:]
+
+            l[-1:] = [4,5,6]
+
+            l = []
+
+            append = l.append
+            append(2)
+            append(3)
+            append(4)
+            append(2)
+            append(3)
+            append(4)
+
+            l[0] = 3
+            l[1] = 4
+            l[2] = 5
+            l[3] = 3
+            l[4] = 4
+            l[5] = 5
+
+            l[:3] = [1,2,3]
+            m = l[:-1]
+            m = l[1:]
+
+            l[-1:] = [4,5,6]
+
+    def calibrate(self):
+
+        for i in xrange(self.rounds):
+            pass

Added: vendor/Python/current/Tools/pybench/Lookups.py
===================================================================
--- vendor/Python/current/Tools/pybench/Lookups.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/pybench/Lookups.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,945 @@
+from pybench import Test
+
+class SpecialClassAttribute(Test):
+
+    version = 2.0
+    operations = 5*(12 + 12)
+    rounds = 100000
+
+    def test(self):
+
+        class c:
+            pass
+
+        for i in xrange(self.rounds):
+
+            c.__a = 2
+            c.__b = 3
+            c.__c = 4
+
+            c.__a = 2
+            c.__b = 3
+            c.__c = 4
+
+            c.__a = 2
+            c.__b = 3
+            c.__c = 4
+
+            c.__a = 2
+            c.__b = 3
+            c.__c = 4
+
+            x = c.__a
+            x = c.__b
+            x = c.__c
+
+            x = c.__a
+            x = c.__b
+            x = c.__c
+
+            x = c.__a
+            x = c.__b
+            x = c.__c
+
+            x = c.__a
+            x = c.__b
+            x = c.__c
+
+            c.__a = 2
+            c.__b = 3
+            c.__c = 4
+
+            c.__a = 2
+            c.__b = 3
+            c.__c = 4
+
+            c.__a = 2
+            c.__b = 3
+            c.__c = 4
+
+            c.__a = 2
+            c.__b = 3
+            c.__c = 4
+
+            x = c.__a
+            x = c.__b
+            x = c.__c
+
+            x = c.__a
+            x = c.__b
+            x = c.__c
+
+            x = c.__a
+            x = c.__b
+            x = c.__c
+
+            x = c.__a
+            x = c.__b
+            x = c.__c
+
+            c.__a = 2
+            c.__b = 3
+            c.__c = 4
+
+            c.__a = 2
+            c.__b = 3
+            c.__c = 4
+
+            c.__a = 2
+            c.__b = 3
+            c.__c = 4
+
+            c.__a = 2
+            c.__b = 3
+            c.__c = 4
+
+            x = c.__a
+            x = c.__b
+            x = c.__c
+
+            x = c.__a
+            x = c.__b
+            x = c.__c
+
+            x = c.__a
+            x = c.__b
+            x = c.__c
+
+            x = c.__a
+            x = c.__b
+            x = c.__c
+
+            c.__a = 2
+            c.__b = 3
+            c.__c = 4
+
+            c.__a = 2
+            c.__b = 3
+            c.__c = 4
+
+            c.__a = 2
+            c.__b = 3
+            c.__c = 4
+
+            c.__a = 2
+            c.__b = 3
+            c.__c = 4
+
+            x = c.__a
+            x = c.__b
+            x = c.__c
+
+            x = c.__a
+            x = c.__b
+            x = c.__c
+
+            x = c.__a
+            x = c.__b
+            x = c.__c
+
+            x = c.__a
+            x = c.__b
+            x = c.__c
+
+            c.__a = 2
+            c.__b = 3
+            c.__c = 4
+
+            c.__a = 2
+            c.__b = 3
+            c.__c = 4
+
+            c.__a = 2
+            c.__b = 3
+            c.__c = 4
+
+            c.__a = 2
+            c.__b = 3
+            c.__c = 4
+
+            x = c.__a
+            x = c.__b
+            x = c.__c
+
+            x = c.__a
+            x = c.__b
+            x = c.__c
+
+            x = c.__a
+            x = c.__b
+            x = c.__c
+
+            x = c.__a
+            x = c.__b
+            x = c.__c
+
+    def calibrate(self):
+
+        class c:
+            pass
+
+        for i in xrange(self.rounds):
+            pass
+
+class NormalClassAttribute(Test):
+
+    version = 2.0
+    operations = 5*(12 + 12)
+    rounds = 100000
+
+    def test(self):
+
+        class c:
+            pass
+
+        for i in xrange(self.rounds):
+
+            c.a = 2
+            c.b = 3
+            c.c = 4
+
+            c.a = 2
+            c.b = 3
+            c.c = 4
+
+            c.a = 2
+            c.b = 3
+            c.c = 4
+
+            c.a = 2
+            c.b = 3
+            c.c = 4
+
+
+            x = c.a
+            x = c.b
+            x = c.c
+
+            x = c.a
+            x = c.b
+            x = c.c
+
+            x = c.a
+            x = c.b
+            x = c.c
+
+            x = c.a
+            x = c.b
+            x = c.c
+
+            c.a = 2
+            c.b = 3
+            c.c = 4
+
+            c.a = 2
+            c.b = 3
+            c.c = 4
+
+            c.a = 2
+            c.b = 3
+            c.c = 4
+
+            c.a = 2
+            c.b = 3
+            c.c = 4
+
+
+            x = c.a
+            x = c.b
+            x = c.c
+
+            x = c.a
+            x = c.b
+            x = c.c
+
+            x = c.a
+            x = c.b
+            x = c.c
+
+            x = c.a
+            x = c.b
+            x = c.c
+
+            c.a = 2
+            c.b = 3
+            c.c = 4
+
+            c.a = 2
+            c.b = 3
+            c.c = 4
+
+            c.a = 2
+            c.b = 3
+            c.c = 4
+
+            c.a = 2
+            c.b = 3
+            c.c = 4
+
+
+            x = c.a
+            x = c.b
+            x = c.c
+
+            x = c.a
+            x = c.b
+            x = c.c
+
+            x = c.a
+            x = c.b
+            x = c.c
+
+            x = c.a
+            x = c.b
+            x = c.c
+
+            c.a = 2
+            c.b = 3
+            c.c = 4
+
+            c.a = 2
+            c.b = 3
+            c.c = 4
+
+            c.a = 2
+            c.b = 3
+            c.c = 4
+
+            c.a = 2
+            c.b = 3
+            c.c = 4
+
+
+            x = c.a
+            x = c.b
+            x = c.c
+
+            x = c.a
+            x = c.b
+            x = c.c
+
+            x = c.a
+            x = c.b
+            x = c.c
+
+            x = c.a
+            x = c.b
+            x = c.c
+
+            c.a = 2
+            c.b = 3
+            c.c = 4
+
+            c.a = 2
+            c.b = 3
+            c.c = 4
+
+            c.a = 2
+            c.b = 3
+            c.c = 4
+
+            c.a = 2
+            c.b = 3
+            c.c = 4
+
+
+            x = c.a
+            x = c.b
+            x = c.c
+
+            x = c.a
+            x = c.b
+            x = c.c
+
+            x = c.a
+            x = c.b
+            x = c.c
+
+            x = c.a
+            x = c.b
+            x = c.c
+
+    def calibrate(self):
+
+        class c:
+            pass
+
+        for i in xrange(self.rounds):
+            pass
+
+class SpecialInstanceAttribute(Test):
+
+    version = 2.0
+    operations = 5*(12 + 12)
+    rounds = 100000
+
+    def test(self):
+
+        class c:
+            pass
+        o = c()
+
+        for i in xrange(self.rounds):
+
+            o.__a__ = 2
+            o.__b__ = 3
+            o.__c__ = 4
+
+            o.__a__ = 2
+            o.__b__ = 3
+            o.__c__ = 4
+
+            o.__a__ = 2
+            o.__b__ = 3
+            o.__c__ = 4
+
+            o.__a__ = 2
+            o.__b__ = 3
+            o.__c__ = 4
+
+
+            x = o.__a__
+            x = o.__b__
+            x = o.__c__
+
+            x = o.__a__
+            x = o.__b__
+            x = o.__c__
+
+            x = o.__a__
+            x = o.__b__
+            x = o.__c__
+
+            x = o.__a__
+            x = o.__b__
+            x = o.__c__
+
+            o.__a__ = 2
+            o.__b__ = 3
+            o.__c__ = 4
+
+            o.__a__ = 2
+            o.__b__ = 3
+            o.__c__ = 4
+
+            o.__a__ = 2
+            o.__b__ = 3
+            o.__c__ = 4
+
+            o.__a__ = 2
+            o.__b__ = 3
+            o.__c__ = 4
+
+
+            x = o.__a__
+            x = o.__b__
+            x = o.__c__
+
+            x = o.__a__
+            x = o.__b__
+            x = o.__c__
+
+            x = o.__a__
+            x = o.__b__
+            x = o.__c__
+
+            x = o.__a__
+            x = o.__b__
+            x = o.__c__
+
+            o.__a__ = 2
+            o.__b__ = 3
+            o.__c__ = 4
+
+            o.__a__ = 2
+            o.__b__ = 3
+            o.__c__ = 4
+
+            o.__a__ = 2
+            o.__b__ = 3
+            o.__c__ = 4
+
+            o.__a__ = 2
+            o.__b__ = 3
+            o.__c__ = 4
+
+
+            x = o.__a__
+            x = o.__b__
+            x = o.__c__
+
+            x = o.__a__
+            x = o.__b__
+            x = o.__c__
+
+            x = o.__a__
+            x = o.__b__
+            x = o.__c__
+
+            x = o.__a__
+            x = o.__b__
+            x = o.__c__
+
+            o.__a__ = 2
+            o.__b__ = 3
+            o.__c__ = 4
+
+            o.__a__ = 2
+            o.__b__ = 3
+            o.__c__ = 4
+
+            o.__a__ = 2
+            o.__b__ = 3
+            o.__c__ = 4
+
+            o.__a__ = 2
+            o.__b__ = 3
+            o.__c__ = 4
+
+
+            x = o.__a__
+            x = o.__b__
+            x = o.__c__
+
+            x = o.__a__
+            x = o.__b__
+            x = o.__c__
+
+            x = o.__a__
+            x = o.__b__
+            x = o.__c__
+
+            x = o.__a__
+            x = o.__b__
+            x = o.__c__
+
+            o.__a__ = 2
+            o.__b__ = 3
+            o.__c__ = 4
+
+            o.__a__ = 2
+            o.__b__ = 3
+            o.__c__ = 4
+
+            o.__a__ = 2
+            o.__b__ = 3
+            o.__c__ = 4
+
+            o.__a__ = 2
+            o.__b__ = 3
+            o.__c__ = 4
+
+
+            x = o.__a__
+            x = o.__b__
+            x = o.__c__
+
+            x = o.__a__
+            x = o.__b__
+            x = o.__c__
+
+            x = o.__a__
+            x = o.__b__
+            x = o.__c__
+
+            x = o.__a__
+            x = o.__b__
+            x = o.__c__
+
+    def calibrate(self):
+
+        class c:
+            pass
+        o = c()
+
+        for i in xrange(self.rounds):
+            pass
+
+class NormalInstanceAttribute(Test):
+
+    version = 2.0
+    operations = 5*(12 + 12)
+    rounds = 100000
+
+    def test(self):
+
+        class c:
+            pass
+        o = c()
+
+        for i in xrange(self.rounds):
+
+            o.a = 2
+            o.b = 3
+            o.c = 4
+
+            o.a = 2
+            o.b = 3
+            o.c = 4
+
+            o.a = 2
+            o.b = 3
+            o.c = 4
+
+            o.a = 2
+            o.b = 3
+            o.c = 4
+
+
+            x = o.a
+            x = o.b
+            x = o.c
+
+            x = o.a
+            x = o.b
+            x = o.c
+
+            x = o.a
+            x = o.b
+            x = o.c
+
+            x = o.a
+            x = o.b
+            x = o.c
+
+            o.a = 2
+            o.b = 3
+            o.c = 4
+
+            o.a = 2
+            o.b = 3
+            o.c = 4
+
+            o.a = 2
+            o.b = 3
+            o.c = 4
+
+            o.a = 2
+            o.b = 3
+            o.c = 4
+
+
+            x = o.a
+            x = o.b
+            x = o.c
+
+            x = o.a
+            x = o.b
+            x = o.c
+
+            x = o.a
+            x = o.b
+            x = o.c
+
+            x = o.a
+            x = o.b
+            x = o.c
+
+            o.a = 2
+            o.b = 3
+            o.c = 4
+
+            o.a = 2
+            o.b = 3
+            o.c = 4
+
+            o.a = 2
+            o.b = 3
+            o.c = 4
+
+            o.a = 2
+            o.b = 3
+            o.c = 4
+
+
+            x = o.a
+            x = o.b
+            x = o.c
+
+            x = o.a
+            x = o.b
+            x = o.c
+
+            x = o.a
+            x = o.b
+            x = o.c
+
+            x = o.a
+            x = o.b
+            x = o.c
+
+            o.a = 2
+            o.b = 3
+            o.c = 4
+
+            o.a = 2
+            o.b = 3
+            o.c = 4
+
+            o.a = 2
+            o.b = 3
+            o.c = 4
+
+            o.a = 2
+            o.b = 3
+            o.c = 4
+
+
+            x = o.a
+            x = o.b
+            x = o.c
+
+            x = o.a
+            x = o.b
+            x = o.c
+
+            x = o.a
+            x = o.b
+            x = o.c
+
+            x = o.a
+            x = o.b
+            x = o.c
+
+            o.a = 2
+            o.b = 3
+            o.c = 4
+
+            o.a = 2
+            o.b = 3
+            o.c = 4
+
+            o.a = 2
+            o.b = 3
+            o.c = 4
+
+            o.a = 2
+            o.b = 3
+            o.c = 4
+
+
+            x = o.a
+            x = o.b
+            x = o.c
+
+            x = o.a
+            x = o.b
+            x = o.c
+
+            x = o.a
+            x = o.b
+            x = o.c
+
+            x = o.a
+            x = o.b
+            x = o.c
+
+    def calibrate(self):
+
+        class c:
+            pass
+        o = c()
+
+        for i in xrange(self.rounds):
+            pass
+
+class BuiltinMethodLookup(Test):
+
+    version = 2.0
+    operations = 5*(3*5 + 3*5)
+    rounds = 70000
+
+    def test(self):
+
+        l = []
+        d = {}
+
+        for i in xrange(self.rounds):
+
+            l.append
+            l.append
+            l.append
+            l.append
+            l.append
+
+            l.insert
+            l.insert
+            l.insert
+            l.insert
+            l.insert
+
+            l.sort
+            l.sort
+            l.sort
+            l.sort
+            l.sort
+
+            d.has_key
+            d.has_key
+            d.has_key
+            d.has_key
+            d.has_key
+
+            d.items
+            d.items
+            d.items
+            d.items
+            d.items
+
+            d.get
+            d.get
+            d.get
+            d.get
+            d.get
+
+            l.append
+            l.append
+            l.append
+            l.append
+            l.append
+
+            l.insert
+            l.insert
+            l.insert
+            l.insert
+            l.insert
+
+            l.sort
+            l.sort
+            l.sort
+            l.sort
+            l.sort
+
+            d.has_key
+            d.has_key
+            d.has_key
+            d.has_key
+            d.has_key
+
+            d.items
+            d.items
+            d.items
+            d.items
+            d.items
+
+            d.get
+            d.get
+            d.get
+            d.get
+            d.get
+
+            l.append
+            l.append
+            l.append
+            l.append
+            l.append
+
+            l.insert
+            l.insert
+            l.insert
+            l.insert
+            l.insert
+
+            l.sort
+            l.sort
+            l.sort
+            l.sort
+            l.sort
+
+            d.has_key
+            d.has_key
+            d.has_key
+            d.has_key
+            d.has_key
+
+            d.items
+            d.items
+            d.items
+            d.items
+            d.items
+
+            d.get
+            d.get
+            d.get
+            d.get
+            d.get
+
+            l.append
+            l.append
+            l.append
+            l.append
+            l.append
+
+            l.insert
+            l.insert
+            l.insert
+            l.insert
+            l.insert
+
+            l.sort
+            l.sort
+            l.sort
+            l.sort
+            l.sort
+
+            d.has_key
+            d.has_key
+            d.has_key
+            d.has_key
+            d.has_key
+
+            d.items
+            d.items
+            d.items
+            d.items
+            d.items
+
+            d.get
+            d.get
+            d.get
+            d.get
+            d.get
+
+            l.append
+            l.append
+            l.append
+            l.append
+            l.append
+
+            l.insert
+            l.insert
+            l.insert
+            l.insert
+            l.insert
+
+            l.sort
+            l.sort
+            l.sort
+            l.sort
+            l.sort
+
+            d.has_key
+            d.has_key
+            d.has_key
+            d.has_key
+            d.has_key
+
+            d.items
+            d.items
+            d.items
+            d.items
+            d.items
+
+            d.get
+            d.get
+            d.get
+            d.get
+            d.get
+
+    def calibrate(self):
+
+        l = []
+        d = {}
+
+        for i in xrange(self.rounds):
+            pass

Added: vendor/Python/current/Tools/pybench/NewInstances.py
===================================================================
--- vendor/Python/current/Tools/pybench/NewInstances.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/pybench/NewInstances.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,75 @@
+from pybench import Test
+
+# Check for new-style class support:
+try:
+    class c(object):
+        pass
+except NameError:
+    raise ImportError
+
+###
+
+class CreateNewInstances(Test):
+
+    version = 2.0
+    operations = 3 + 7 + 4
+    rounds = 60000
+
+    def test(self):
+
+        class c(object):
+            pass
+
+        class d(object):
+            def __init__(self,a,b,c):
+                self.a = a
+                self.b = b
+                self.c = c
+
+        class e(object):
+            def __init__(self,a,b,c=4):
+                self.a = a
+                self.b = b
+                self.c = c
+                self.d = a
+                self.e = b
+                self.f = c
+
+        for i in xrange(self.rounds):
+            o = c()
+            o1 = c()
+            o2 = c()
+            p = d(i,i,3)
+            p1 = d(i,i,3)
+            p2 = d(i,3,3)
+            p3 = d(3,i,3)
+            p4 = d(i,i,i)
+            p5 = d(3,i,3)
+            p6 = d(i,i,i)
+            q = e(i,i,3)
+            q1 = e(i,i,3)
+            q2 = e(i,i,3)
+            q3 = e(i,i)
+
+    def calibrate(self):
+
+        class c(object):
+            pass
+
+        class d(object):
+            def __init__(self,a,b,c):
+                self.a = a
+                self.b = b
+                self.c = c
+
+        class e(object):
+            def __init__(self,a,b,c=4):
+                self.a = a
+                self.b = b
+                self.c = c
+                self.d = a
+                self.e = b
+                self.f = c
+
+        for i in xrange(self.rounds):
+            pass

Added: vendor/Python/current/Tools/pybench/Numbers.py
===================================================================
--- vendor/Python/current/Tools/pybench/Numbers.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/pybench/Numbers.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,784 @@
+from pybench import Test
+
+class CompareIntegers(Test):
+
+    version = 2.0
+    operations = 30 * 5
+    rounds = 120000
+
+    def test(self):
+
+        for i in xrange(self.rounds):
+
+            2 < 3
+            2 > 3
+            2 == 3
+            2 > 3
+            2 < 3
+
+            2 < 3
+            2 > 3
+            2 == 3
+            2 > 3
+            2 < 3
+
+            2 < 3
+            2 > 3
+            2 == 3
+            2 > 3
+            2 < 3
+
+            2 < 3
+            2 > 3
+            2 == 3
+            2 > 3
+            2 < 3
+
+            2 < 3
+            2 > 3
+            2 == 3
+            2 > 3
+            2 < 3
+
+            2 < 3
+            2 > 3
+            2 == 3
+            2 > 3
+            2 < 3
+
+            2 < 3
+            2 > 3
+            2 == 3
+            2 > 3
+            2 < 3
+
+            2 < 3
+            2 > 3
+            2 == 3
+            2 > 3
+            2 < 3
+
+            2 < 3
+            2 > 3
+            2 == 3
+            2 > 3
+            2 < 3
+
+            2 < 3
+            2 > 3
+            2 == 3
+            2 > 3
+            2 < 3
+
+            2 < 3
+            2 > 3
+            2 == 3
+            2 > 3
+            2 < 3
+
+            2 < 3
+            2 > 3
+            2 == 3
+            2 > 3
+            2 < 3
+
+            2 < 3
+            2 > 3
+            2 == 3
+            2 > 3
+            2 < 3
+
+            2 < 3
+            2 > 3
+            2 == 3
+            2 > 3
+            2 < 3
+
+            2 < 3
+            2 > 3
+            2 == 3
+            2 > 3
+            2 < 3
+
+            2 < 3
+            2 > 3
+            2 == 3
+            2 > 3
+            2 < 3
+
+            2 < 3
+            2 > 3
+            2 == 3
+            2 > 3
+            2 < 3
+
+            2 < 3
+            2 > 3
+            2 == 3
+            2 > 3
+            2 < 3
+
+            2 < 3
+            2 > 3
+            2 == 3
+            2 > 3
+            2 < 3
+
+            2 < 3
+            2 > 3
+            2 == 3
+            2 > 3
+            2 < 3
+
+            2 < 3
+            2 > 3
+            2 == 3
+            2 > 3
+            2 < 3
+
+            2 < 3
+            2 > 3
+            2 == 3
+            2 > 3
+            2 < 3
+
+            2 < 3
+            2 > 3
+            2 == 3
+            2 > 3
+            2 < 3
+
+            2 < 3
+            2 > 3
+            2 == 3
+            2 > 3
+            2 < 3
+
+            2 < 3
+            2 > 3
+            2 == 3
+            2 > 3
+            2 < 3
+
+            2 < 3
+            2 > 3
+            2 == 3
+            2 > 3
+            2 < 3
+
+            2 < 3
+            2 > 3
+            2 == 3
+            2 > 3
+            2 < 3
+
+            2 < 3
+            2 > 3
+            2 == 3
+            2 > 3
+            2 < 3
+
+            2 < 3
+            2 > 3
+            2 == 3
+            2 > 3
+            2 < 3
+
+            2 < 3
+            2 > 3
+            2 == 3
+            2 > 3
+            2 < 3
+
+    def calibrate(self):
+
+        for i in xrange(self.rounds):
+            pass
+
+
+class CompareFloats(Test):
+
+    version = 2.0
+    operations = 30 * 5
+    rounds = 80000
+
+    def test(self):
+
+        for i in xrange(self.rounds):
+
+            2.1 < 3.31
+            2.1 > 3.31
+            2.1 == 3.31
+            2.1 > 3.31
+            2.1 < 3.31
+
+            2.1 < 3.31
+            2.1 > 3.31
+            2.1 == 3.31
+            2.1 > 3.31
+            2.1 < 3.31
+
+            2.1 < 3.31
+            2.1 > 3.31
+            2.1 == 3.31
+            2.1 > 3.31
+            2.1 < 3.31
+
+            2.1 < 3.31
+            2.1 > 3.31
+            2.1 == 3.31
+            2.1 > 3.31
+            2.1 < 3.31
+
+            2.1 < 3.31
+            2.1 > 3.31
+            2.1 == 3.31
+            2.1 > 3.31
+            2.1 < 3.31
+
+            2.1 < 3.31
+            2.1 > 3.31
+            2.1 == 3.31
+            2.1 > 3.31
+            2.1 < 3.31
+
+            2.1 < 3.31
+            2.1 > 3.31
+            2.1 == 3.31
+            2.1 > 3.31
+            2.1 < 3.31
+
+            2.1 < 3.31
+            2.1 > 3.31
+            2.1 == 3.31
+            2.1 > 3.31
+            2.1 < 3.31
+
+            2.1 < 3.31
+            2.1 > 3.31
+            2.1 == 3.31
+            2.1 > 3.31
+            2.1 < 3.31
+
+            2.1 < 3.31
+            2.1 > 3.31
+            2.1 == 3.31
+            2.1 > 3.31
+            2.1 < 3.31
+
+            2.1 < 3.31
+            2.1 > 3.31
+            2.1 == 3.31
+            2.1 > 3.31
+            2.1 < 3.31
+
+            2.1 < 3.31
+            2.1 > 3.31
+            2.1 == 3.31
+            2.1 > 3.31
+            2.1 < 3.31
+
+            2.1 < 3.31
+            2.1 > 3.31
+            2.1 == 3.31
+            2.1 > 3.31
+            2.1 < 3.31
+
+            2.1 < 3.31
+            2.1 > 3.31
+            2.1 == 3.31
+            2.1 > 3.31
+            2.1 < 3.31
+
+            2.1 < 3.31
+            2.1 > 3.31
+            2.1 == 3.31
+            2.1 > 3.31
+            2.1 < 3.31
+
+            2.1 < 3.31
+            2.1 > 3.31
+            2.1 == 3.31
+            2.1 > 3.31
+            2.1 < 3.31
+
+            2.1 < 3.31
+            2.1 > 3.31
+            2.1 == 3.31
+            2.1 > 3.31
+            2.1 < 3.31
+
+            2.1 < 3.31
+            2.1 > 3.31
+            2.1 == 3.31
+            2.1 > 3.31
+            2.1 < 3.31
+
+            2.1 < 3.31
+            2.1 > 3.31
+            2.1 == 3.31
+            2.1 > 3.31
+            2.1 < 3.31
+
+            2.1 < 3.31
+            2.1 > 3.31
+            2.1 == 3.31
+            2.1 > 3.31
+            2.1 < 3.31
+
+            2.1 < 3.31
+            2.1 > 3.31
+            2.1 == 3.31
+            2.1 > 3.31
+            2.1 < 3.31
+
+            2.1 < 3.31
+            2.1 > 3.31
+            2.1 == 3.31
+            2.1 > 3.31
+            2.1 < 3.31
+
+            2.1 < 3.31
+            2.1 > 3.31
+            2.1 == 3.31
+            2.1 > 3.31
+            2.1 < 3.31
+
+            2.1 < 3.31
+            2.1 > 3.31
+            2.1 == 3.31
+            2.1 > 3.31
+            2.1 < 3.31
+
+            2.1 < 3.31
+            2.1 > 3.31
+            2.1 == 3.31
+            2.1 > 3.31
+            2.1 < 3.31
+
+            2.1 < 3.31
+            2.1 > 3.31
+            2.1 == 3.31
+            2.1 > 3.31
+            2.1 < 3.31
+
+            2.1 < 3.31
+            2.1 > 3.31
+            2.1 == 3.31
+            2.1 > 3.31
+            2.1 < 3.31
+
+            2.1 < 3.31
+            2.1 > 3.31
+            2.1 == 3.31
+            2.1 > 3.31
+            2.1 < 3.31
+
+            2.1 < 3.31
+            2.1 > 3.31
+            2.1 == 3.31
+            2.1 > 3.31
+            2.1 < 3.31
+
+            2.1 < 3.31
+            2.1 > 3.31
+            2.1 == 3.31
+            2.1 > 3.31
+            2.1 < 3.31
+
+    def calibrate(self):
+
+        for i in xrange(self.rounds):
+            pass
+
+
+class CompareFloatsIntegers(Test):
+
+    version = 2.0
+    operations = 30 * 5
+    rounds = 60000
+
+    def test(self):
+
+        for i in xrange(self.rounds):
+
+            2.1 < 4
+            2.1 > 4
+            2.1 == 4
+            2.1 > 4
+            2.1 < 4
+
+            2.1 < 4
+            2.1 > 4
+            2.1 == 4
+            2.1 > 4
+            2.1 < 4
+
+            2.1 < 4
+            2.1 > 4
+            2.1 == 4
+            2.1 > 4
+            2.1 < 4
+
+            2.1 < 4
+            2.1 > 4
+            2.1 == 4
+            2.1 > 4
+            2.1 < 4
+
+            2.1 < 4
+            2.1 > 4
+            2.1 == 4
+            2.1 > 4
+            2.1 < 4
+
+            2.1 < 4
+            2.1 > 4
+            2.1 == 4
+            2.1 > 4
+            2.1 < 4
+
+            2.1 < 4
+            2.1 > 4
+            2.1 == 4
+            2.1 > 4
+            2.1 < 4
+
+            2.1 < 4
+            2.1 > 4
+            2.1 == 4
+            2.1 > 4
+            2.1 < 4
+
+            2.1 < 4
+            2.1 > 4
+            2.1 == 4
+            2.1 > 4
+            2.1 < 4
+
+            2.1 < 4
+            2.1 > 4
+            2.1 == 4
+            2.1 > 4
+            2.1 < 4
+
+            2.1 < 4
+            2.1 > 4
+            2.1 == 4
+            2.1 > 4
+            2.1 < 4
+
+            2.1 < 4
+            2.1 > 4
+            2.1 == 4
+            2.1 > 4
+            2.1 < 4
+
+            2.1 < 4
+            2.1 > 4
+            2.1 == 4
+            2.1 > 4
+            2.1 < 4
+
+            2.1 < 4
+            2.1 > 4
+            2.1 == 4
+            2.1 > 4
+            2.1 < 4
+
+            2.1 < 4
+            2.1 > 4
+            2.1 == 4
+            2.1 > 4
+            2.1 < 4
+
+            2.1 < 4
+            2.1 > 4
+            2.1 == 4
+            2.1 > 4
+            2.1 < 4
+
+            2.1 < 4
+            2.1 > 4
+            2.1 == 4
+            2.1 > 4
+            2.1 < 4
+
+            2.1 < 4
+            2.1 > 4
+            2.1 == 4
+            2.1 > 4
+            2.1 < 4
+
+            2.1 < 4
+            2.1 > 4
+            2.1 == 4
+            2.1 > 4
+            2.1 < 4
+
+            2.1 < 4
+            2.1 > 4
+            2.1 == 4
+            2.1 > 4
+            2.1 < 4
+
+            2.1 < 4
+            2.1 > 4
+            2.1 == 4
+            2.1 > 4
+            2.1 < 4
+
+            2.1 < 4
+            2.1 > 4
+            2.1 == 4
+            2.1 > 4
+            2.1 < 4
+
+            2.1 < 4
+            2.1 > 4
+            2.1 == 4
+            2.1 > 4
+            2.1 < 4
+
+            2.1 < 4
+            2.1 > 4
+            2.1 == 4
+            2.1 > 4
+            2.1 < 4
+
+            2.1 < 4
+            2.1 > 4
+            2.1 == 4
+            2.1 > 4
+            2.1 < 4
+
+            2.1 < 4
+            2.1 > 4
+            2.1 == 4
+            2.1 > 4
+            2.1 < 4
+
+            2.1 < 4
+            2.1 > 4
+            2.1 == 4
+            2.1 > 4
+            2.1 < 4
+
+            2.1 < 4
+            2.1 > 4
+            2.1 == 4
+            2.1 > 4
+            2.1 < 4
+
+            2.1 < 4
+            2.1 > 4
+            2.1 == 4
+            2.1 > 4
+            2.1 < 4
+
+            2.1 < 4
+            2.1 > 4
+            2.1 == 4
+            2.1 > 4
+            2.1 < 4
+
+    def calibrate(self):
+
+        for i in xrange(self.rounds):
+            pass
+
+
+class CompareLongs(Test):
+
+    version = 2.0
+    operations = 30 * 5
+    rounds = 70000
+
+    def test(self):
+
+        for i in xrange(self.rounds):
+
+            1234567890L < 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L == 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L < 3456789012345L
+
+            1234567890L < 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L == 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L < 3456789012345L
+
+            1234567890L < 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L == 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L < 3456789012345L
+
+            1234567890L < 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L == 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L < 3456789012345L
+
+            1234567890L < 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L == 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L < 3456789012345L
+
+            1234567890L < 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L == 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L < 3456789012345L
+
+            1234567890L < 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L == 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L < 3456789012345L
+
+            1234567890L < 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L == 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L < 3456789012345L
+
+            1234567890L < 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L == 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L < 3456789012345L
+
+            1234567890L < 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L == 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L < 3456789012345L
+
+            1234567890L < 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L == 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L < 3456789012345L
+
+            1234567890L < 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L == 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L < 3456789012345L
+
+            1234567890L < 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L == 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L < 3456789012345L
+
+            1234567890L < 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L == 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L < 3456789012345L
+
+            1234567890L < 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L == 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L < 3456789012345L
+
+            1234567890L < 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L == 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L < 3456789012345L
+
+            1234567890L < 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L == 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L < 3456789012345L
+
+            1234567890L < 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L == 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L < 3456789012345L
+
+            1234567890L < 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L == 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L < 3456789012345L
+
+            1234567890L < 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L == 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L < 3456789012345L
+
+            1234567890L < 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L == 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L < 3456789012345L
+
+            1234567890L < 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L == 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L < 3456789012345L
+
+            1234567890L < 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L == 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L < 3456789012345L
+
+            1234567890L < 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L == 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L < 3456789012345L
+
+            1234567890L < 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L == 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L < 3456789012345L
+
+            1234567890L < 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L == 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L < 3456789012345L
+
+            1234567890L < 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L == 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L < 3456789012345L
+
+            1234567890L < 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L == 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L < 3456789012345L
+
+            1234567890L < 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L == 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L < 3456789012345L
+
+            1234567890L < 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L == 3456789012345L
+            1234567890L > 3456789012345L
+            1234567890L < 3456789012345L
+
+    def calibrate(self):
+
+        for i in xrange(self.rounds):
+            pass

Added: vendor/Python/current/Tools/pybench/README
===================================================================
--- vendor/Python/current/Tools/pybench/README	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/pybench/README	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,368 @@
+________________________________________________________________________
+
+PYBENCH - A Python Benchmark Suite
+________________________________________________________________________
+
+     Extendable suite of of low-level benchmarks for measuring
+          the performance of the Python implementation 
+                 (interpreter, compiler or VM).
+
+pybench is a collection of tests that provides a standardized way to
+measure the performance of Python implementations. It takes a very
+close look at different aspects of Python programs and let's you
+decide which factors are more important to you than others, rather
+than wrapping everything up in one number, like the other performance
+tests do (e.g. pystone which is included in the Python Standard
+Library).
+
+pybench has been used in the past by several Python developers to
+track down performance bottlenecks or to demonstrate the impact of
+optimizations and new features in Python.
+
+The command line interface for pybench is the file pybench.py. Run
+this script with option '--help' to get a listing of the possible
+options. Without options, pybench will simply execute the benchmark
+and then print out a report to stdout.
+
+
+Micro-Manual
+------------
+
+Run 'pybench.py -h' to see the help screen.  Run 'pybench.py' to run
+the benchmark suite using default settings and 'pybench.py -f <file>'
+to have it store the results in a file too.
+
+It is usually a good idea to run pybench.py multiple times to see
+whether the environment, timers and benchmark run-times are suitable
+for doing benchmark tests. 
+
+You can use the comparison feature of pybench.py ('pybench.py -c
+<file>') to check how well the system behaves in comparison to a
+reference run. 
+
+If the differences are well below 10% for each test, then you have a
+system that is good for doing benchmark testings.  Of you get random
+differences of more than 10% or significant differences between the
+values for minimum and average time, then you likely have some
+background processes running which cause the readings to become
+inconsistent. Examples include: web-browsers, email clients, RSS
+readers, music players, backup programs, etc.
+
+If you are only interested in a few tests of the whole suite, you can
+use the filtering option, e.g. 'pybench.py -t string' will only
+run/show the tests that have 'string' in their name.
+
+This is the current output of pybench.py --help:
+
+"""
+------------------------------------------------------------------------
+PYBENCH - a benchmark test suite for Python interpreters/compilers.
+------------------------------------------------------------------------
+
+Synopsis:
+ pybench.py [option] files...
+
+Options and default settings:
+  -n arg           number of rounds (10)
+  -f arg           save benchmark to file arg ()
+  -c arg           compare benchmark with the one in file arg ()
+  -s arg           show benchmark in file arg, then exit ()
+  -w arg           set warp factor to arg (10)
+  -t arg           run only tests with names matching arg ()
+  -C arg           set the number of calibration runs to arg (20)
+  -d               hide noise in comparisons (0)
+  -v               verbose output (not recommended) (0)
+  --with-gc        enable garbage collection (0)
+  --with-syscheck  use default sys check interval (0)
+  --timer arg      use given timer (time.time)
+  -h               show this help text
+  --help           show this help text
+  --debug          enable debugging
+  --copyright      show copyright
+  --examples       show examples of usage
+
+Version:
+ 2.0
+
+The normal operation is to run the suite and display the
+results. Use -f to save them for later reuse or comparisons.
+
+Available timers:
+
+   time.time
+   time.clock
+   systimes.processtime
+
+Examples:
+
+python2.1 pybench.py -f p21.pybench
+python2.5 pybench.py -f p25.pybench
+python pybench.py -s p25.pybench -c p21.pybench
+"""
+
+License
+-------
+
+See LICENSE file.
+
+
+Sample output
+-------------
+
+"""
+-------------------------------------------------------------------------------
+PYBENCH 2.0
+-------------------------------------------------------------------------------
+* using Python 2.4.2
+* disabled garbage collection
+* system check interval set to maximum: 2147483647
+* using timer: time.time
+
+Calibrating tests. Please wait...
+
+Running 10 round(s) of the suite at warp factor 10:
+
+* Round 1 done in 6.388 seconds.
+* Round 2 done in 6.485 seconds.
+* Round 3 done in 6.786 seconds.
+...
+* Round 10 done in 6.546 seconds.
+
+-------------------------------------------------------------------------------
+Benchmark: 2006-06-12 12:09:25
+-------------------------------------------------------------------------------
+
+    Rounds: 10
+    Warp:   10
+    Timer:  time.time
+
+    Machine Details:
+       Platform ID:  Linux-2.6.8-24.19-default-x86_64-with-SuSE-9.2-x86-64
+       Processor:    x86_64
+
+    Python:
+       Executable:   /usr/local/bin/python
+       Version:      2.4.2
+       Compiler:     GCC 3.3.4 (pre 3.3.5 20040809)
+       Bits:         64bit
+       Build:        Oct  1 2005 15:24:35 (#1)
+       Unicode:      UCS2
+
+
+Test                             minimum  average  operation  overhead
+-------------------------------------------------------------------------------
+          BuiltinFunctionCalls:    126ms    145ms    0.28us    0.274ms
+           BuiltinMethodLookup:    124ms    130ms    0.12us    0.316ms
+                 CompareFloats:    109ms    110ms    0.09us    0.361ms
+         CompareFloatsIntegers:    100ms    104ms    0.12us    0.271ms
+               CompareIntegers:    137ms    138ms    0.08us    0.542ms
+        CompareInternedStrings:    124ms    127ms    0.08us    1.367ms
+                  CompareLongs:    100ms    104ms    0.10us    0.316ms
+                CompareStrings:    111ms    115ms    0.12us    0.929ms
+                CompareUnicode:    108ms    128ms    0.17us    0.693ms
+                 ConcatStrings:    142ms    155ms    0.31us    0.562ms
+                 ConcatUnicode:    119ms    127ms    0.42us    0.384ms
+               CreateInstances:    123ms    128ms    1.14us    0.367ms
+            CreateNewInstances:    121ms    126ms    1.49us    0.335ms
+       CreateStringsWithConcat:    130ms    135ms    0.14us    0.916ms
+       CreateUnicodeWithConcat:    130ms    135ms    0.34us    0.361ms
+                  DictCreation:    108ms    109ms    0.27us    0.361ms
+             DictWithFloatKeys:    149ms    153ms    0.17us    0.678ms
+           DictWithIntegerKeys:    124ms    126ms    0.11us    0.915ms
+            DictWithStringKeys:    114ms    117ms    0.10us    0.905ms
+                      ForLoops:    110ms    111ms    4.46us    0.063ms
+                    IfThenElse:    118ms    119ms    0.09us    0.685ms
+                   ListSlicing:    116ms    120ms    8.59us    0.103ms
+                NestedForLoops:    125ms    137ms    0.09us    0.019ms
+          NormalClassAttribute:    124ms    136ms    0.11us    0.457ms
+       NormalInstanceAttribute:    110ms    117ms    0.10us    0.454ms
+           PythonFunctionCalls:    107ms    113ms    0.34us    0.271ms
+             PythonMethodCalls:    140ms    149ms    0.66us    0.141ms
+                     Recursion:    156ms    166ms    3.32us    0.452ms
+                  SecondImport:    112ms    118ms    1.18us    0.180ms
+           SecondPackageImport:    118ms    127ms    1.27us    0.180ms
+         SecondSubmoduleImport:    140ms    151ms    1.51us    0.180ms
+       SimpleComplexArithmetic:    128ms    139ms    0.16us    0.361ms
+        SimpleDictManipulation:    134ms    136ms    0.11us    0.452ms
+         SimpleFloatArithmetic:    110ms    113ms    0.09us    0.571ms
+      SimpleIntFloatArithmetic:    106ms    111ms    0.08us    0.548ms
+       SimpleIntegerArithmetic:    106ms    109ms    0.08us    0.544ms
+        SimpleListManipulation:    103ms    113ms    0.10us    0.587ms
+          SimpleLongArithmetic:    112ms    118ms    0.18us    0.271ms
+                    SmallLists:    105ms    116ms    0.17us    0.366ms
+                   SmallTuples:    108ms    128ms    0.24us    0.406ms
+         SpecialClassAttribute:    119ms    136ms    0.11us    0.453ms
+      SpecialInstanceAttribute:    143ms    155ms    0.13us    0.454ms
+                StringMappings:    115ms    121ms    0.48us    0.405ms
+              StringPredicates:    120ms    129ms    0.18us    2.064ms
+                 StringSlicing:    111ms    127ms    0.23us    0.781ms
+                     TryExcept:    125ms    126ms    0.06us    0.681ms
+                TryRaiseExcept:    133ms    137ms    2.14us    0.361ms
+                  TupleSlicing:    117ms    120ms    0.46us    0.066ms
+               UnicodeMappings:    156ms    160ms    4.44us    0.429ms
+             UnicodePredicates:    117ms    121ms    0.22us    2.487ms
+             UnicodeProperties:    115ms    153ms    0.38us    2.070ms
+                UnicodeSlicing:    126ms    129ms    0.26us    0.689ms
+-------------------------------------------------------------------------------
+Totals:                           6283ms   6673ms
+"""
+________________________________________________________________________
+
+Writing New Tests
+________________________________________________________________________
+
+pybench tests are simple modules defining one or more pybench.Test
+subclasses.
+
+Writing a test essentially boils down to providing two methods:
+.test() which runs .rounds number of .operations test operations each
+and .calibrate() which does the same except that it doesn't actually
+execute the operations.
+
+
+Here's an example:
+------------------
+
+from pybench import Test
+
+class IntegerCounting(Test):
+
+    # Version number of the test as float (x.yy); this is important
+    # for comparisons of benchmark runs - tests with unequal version
+    # number will not get compared.
+    version = 1.0
+    
+    # The number of abstract operations done in each round of the
+    # test. An operation is the basic unit of what you want to
+    # measure. The benchmark will output the amount of run-time per
+    # operation. Note that in order to raise the measured timings
+    # significantly above noise level, it is often required to repeat
+    # sets of operations more than once per test round. The measured
+    # overhead per test round should be less than 1 second.
+    operations = 20
+
+    # Number of rounds to execute per test run. This should be
+    # adjusted to a figure that results in a test run-time of between
+    # 1-2 seconds (at warp 1).
+    rounds = 100000
+
+    def test(self):
+
+	""" Run the test.
+
+	    The test needs to run self.rounds executing
+	    self.operations number of operations each.
+
+        """
+        # Init the test
+        a = 1
+
+        # Run test rounds
+	#
+        # NOTE: Use xrange() for all test loops unless you want to face
+	# a 20MB process !
+	#
+        for i in xrange(self.rounds):
+
+            # Repeat the operations per round to raise the run-time
+            # per operation significantly above the noise level of the
+            # for-loop overhead. 
+
+	    # Execute 20 operations (a += 1):
+            a += 1
+            a += 1
+            a += 1
+            a += 1
+            a += 1
+            a += 1
+            a += 1
+            a += 1
+            a += 1
+            a += 1
+            a += 1
+            a += 1
+            a += 1
+            a += 1
+            a += 1
+            a += 1
+            a += 1
+            a += 1
+            a += 1
+            a += 1
+
+    def calibrate(self):
+
+	""" Calibrate the test.
+
+	    This method should execute everything that is needed to
+	    setup and run the test - except for the actual operations
+	    that you intend to measure. pybench uses this method to
+            measure the test implementation overhead.
+
+        """
+        # Init the test
+        a = 1
+
+        # Run test rounds (without actually doing any operation)
+        for i in xrange(self.rounds):
+
+	    # Skip the actual execution of the operations, since we
+	    # only want to measure the test's administration overhead.
+            pass
+
+Registering a new test module
+-----------------------------
+
+To register a test module with pybench, the classes need to be
+imported into the pybench.Setup module. pybench will then scan all the
+symbols defined in that module for subclasses of pybench.Test and
+automatically add them to the benchmark suite.
+
+
+Breaking Comparability
+----------------------
+
+If a change is made to any individual test that means it is no
+longer strictly comparable with previous runs, the '.version' class
+variable should be updated. Therefafter, comparisons with previous
+versions of the test will list as "n/a" to reflect the change.
+
+
+Version History
+---------------
+
+  2.0: rewrote parts of pybench which resulted in more repeatable
+       timings:
+        - made timer a parameter
+        - changed the platform default timer to use high-resolution
+          timers rather than process timers (which have a much lower
+          resolution)
+        - added option to select timer
+        - added process time timer (using systimes.py)
+        - changed to use min() as timing estimator (average
+          is still taken as well to provide an idea of the difference)
+        - garbage collection is turned off per default
+        - sys check interval is set to the highest possible value
+        - calibration is now a separate step and done using
+          a different strategy that allows measuring the test
+          overhead more accurately
+        - modified the tests to each give a run-time of between
+          100-200ms using warp 10
+        - changed default warp factor to 10 (from 20)
+        - compared results with timeit.py and confirmed measurements
+        - bumped all test versions to 2.0
+        - updated platform.py to the latest version
+        - changed the output format a bit to make it look
+          nicer
+        - refactored the APIs somewhat
+  1.3+: Steve Holden added the NewInstances test and the filtering 
+       option during the NeedForSpeed sprint; this also triggered a long 
+       discussion on how to improve benchmark timing and finally
+       resulted in the release of 2.0
+  1.3: initial checkin into the Python SVN repository
+
+
+Have fun,
+--
+Marc-Andre Lemburg
+mal at lemburg.com

Added: vendor/Python/current/Tools/pybench/Setup.py
===================================================================
--- vendor/Python/current/Tools/pybench/Setup.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/pybench/Setup.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,39 @@
+#!python
+
+# Setup file for pybench
+#
+# This file has to import all tests to be run; it is executed as
+# Python source file, so you can do all kinds of manipulations here
+# rather than having to edit the tests themselves.
+#
+# Note: Please keep this module compatible to Python 1.5.2.
+#
+# Tests may include features in later Python versions, but these
+# should then be embedded in try-except clauses in this configuration
+# module.
+
+# Defaults
+Number_of_rounds = 10
+Warp_factor = 10
+
+# Import tests
+from Arithmetic import *
+from Calls import *
+from Constructs import *
+from Lookups import *
+from Instances import *
+try:
+    from NewInstances import *
+except ImportError:
+    pass
+from Lists import *
+from Tuples import *
+from Dict import *
+from Exceptions import *
+from Imports import *
+from Strings import *
+from Numbers import *
+try:
+    from Unicode import *
+except (ImportError, SyntaxError):
+    pass

Added: vendor/Python/current/Tools/pybench/Strings.py
===================================================================
--- vendor/Python/current/Tools/pybench/Strings.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/pybench/Strings.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,562 @@
+from pybench import Test
+from string import join
+
+class ConcatStrings(Test):
+
+    version = 2.0
+    operations = 10 * 5
+    rounds = 100000
+
+    def test(self):
+
+        # Make sure the strings are *not* interned
+        s = join(map(str,range(100)))
+        t = join(map(str,range(1,101)))
+
+        for i in xrange(self.rounds):
+            t + s
+            t + s
+            t + s
+            t + s
+            t + s
+
+            t + s
+            t + s
+            t + s
+            t + s
+            t + s
+
+            t + s
+            t + s
+            t + s
+            t + s
+            t + s
+
+            t + s
+            t + s
+            t + s
+            t + s
+            t + s
+
+            t + s
+            t + s
+            t + s
+            t + s
+            t + s
+
+            t + s
+            t + s
+            t + s
+            t + s
+            t + s
+
+            t + s
+            t + s
+            t + s
+            t + s
+            t + s
+
+            t + s
+            t + s
+            t + s
+            t + s
+            t + s
+
+            t + s
+            t + s
+            t + s
+            t + s
+            t + s
+
+            t + s
+            t + s
+            t + s
+            t + s
+            t + s
+
+    def calibrate(self):
+
+        s = join(map(str,range(100)))
+        t = join(map(str,range(1,101)))
+
+        for i in xrange(self.rounds):
+            pass
+
+
+class CompareStrings(Test):
+
+    version = 2.0
+    operations = 10 * 5
+    rounds = 200000
+
+    def test(self):
+
+        # Make sure the strings are *not* interned
+        s = join(map(str,range(10)))
+        t = join(map(str,range(10))) + "abc"
+
+        for i in xrange(self.rounds):
+            t < s
+            t > s
+            t == s
+            t > s
+            t < s
+
+            t < s
+            t > s
+            t == s
+            t > s
+            t < s
+
+            t < s
+            t > s
+            t == s
+            t > s
+            t < s
+
+            t < s
+            t > s
+            t == s
+            t > s
+            t < s
+
+            t < s
+            t > s
+            t == s
+            t > s
+            t < s
+
+            t < s
+            t > s
+            t == s
+            t > s
+            t < s
+
+            t < s
+            t > s
+            t == s
+            t > s
+            t < s
+
+            t < s
+            t > s
+            t == s
+            t > s
+            t < s
+
+            t < s
+            t > s
+            t == s
+            t > s
+            t < s
+
+            t < s
+            t > s
+            t == s
+            t > s
+            t < s
+
+    def calibrate(self):
+
+        s = join(map(str,range(10)))
+        t = join(map(str,range(10))) + "abc"
+
+        for i in xrange(self.rounds):
+            pass
+
+
+class CompareInternedStrings(Test):
+
+    version = 2.0
+    operations = 10 * 5
+    rounds = 300000
+
+    def test(self):
+
+        # Make sure the strings *are* interned
+        s = intern(join(map(str,range(10))))
+        t = s
+
+        for i in xrange(self.rounds):
+            t == s
+            t == s
+            t >= s
+            t > s
+            t < s
+
+            t == s
+            t == s
+            t >= s
+            t > s
+            t < s
+
+            t == s
+            t == s
+            t >= s
+            t > s
+            t < s
+
+            t == s
+            t == s
+            t >= s
+            t > s
+            t < s
+
+            t == s
+            t == s
+            t >= s
+            t > s
+            t < s
+
+            t == s
+            t == s
+            t >= s
+            t > s
+            t < s
+
+            t == s
+            t == s
+            t >= s
+            t > s
+            t < s
+
+            t == s
+            t == s
+            t >= s
+            t > s
+            t < s
+
+            t == s
+            t == s
+            t >= s
+            t > s
+            t < s
+
+            t == s
+            t == s
+            t >= s
+            t > s
+            t < s
+
+    def calibrate(self):
+
+        s = intern(join(map(str,range(10))))
+        t = s
+
+        for i in xrange(self.rounds):
+            pass
+
+
+class CreateStringsWithConcat(Test):
+
+    version = 2.0
+    operations = 10 * 5
+    rounds = 200000
+
+    def test(self):
+
+        for i in xrange(self.rounds):
+            s = 'om'
+            s = s + 'xbx'
+            s = s + 'xcx'
+            s = s + 'xdx'
+            s = s + 'xex'
+
+            s = s + 'xax'
+            s = s + 'xbx'
+            s = s + 'xcx'
+            s = s + 'xdx'
+            s = s + 'xex'
+
+            s = s + 'xax'
+            s = s + 'xbx'
+            s = s + 'xcx'
+            s = s + 'xdx'
+            s = s + 'xex'
+
+            s = s + 'xax'
+            s = s + 'xbx'
+            s = s + 'xcx'
+            s = s + 'xdx'
+            s = s + 'xex'
+
+            s = s + 'xax'
+            s = s + 'xbx'
+            s = s + 'xcx'
+            s = s + 'xdx'
+            s = s + 'xex'
+
+            s = s + 'xax'
+            s = s + 'xbx'
+            s = s + 'xcx'
+            s = s + 'xdx'
+            s = s + 'xex'
+
+            s = s + 'xax'
+            s = s + 'xbx'
+            s = s + 'xcx'
+            s = s + 'xdx'
+            s = s + 'xex'
+
+            s = s + 'xax'
+            s = s + 'xbx'
+            s = s + 'xcx'
+            s = s + 'xdx'
+            s = s + 'xex'
+
+            s = s + 'xax'
+            s = s + 'xbx'
+            s = s + 'xcx'
+            s = s + 'xdx'
+            s = s + 'xex'
+
+            s = s + 'xax'
+            s = s + 'xbx'
+            s = s + 'xcx'
+            s = s + 'xdx'
+            s = s + 'xex'
+
+    def calibrate(self):
+
+        for i in xrange(self.rounds):
+            pass
+
+
+class StringSlicing(Test):
+
+    version = 2.0
+    operations = 5 * 7
+    rounds = 160000
+
+    def test(self):
+
+        s = join(map(str,range(100)))
+
+        for i in xrange(self.rounds):
+
+            s[50:]
+            s[:25]
+            s[50:55]
+            s[-1:]
+            s[:1]
+            s[2:]
+            s[11:-11]
+
+            s[50:]
+            s[:25]
+            s[50:55]
+            s[-1:]
+            s[:1]
+            s[2:]
+            s[11:-11]
+
+            s[50:]
+            s[:25]
+            s[50:55]
+            s[-1:]
+            s[:1]
+            s[2:]
+            s[11:-11]
+
+            s[50:]
+            s[:25]
+            s[50:55]
+            s[-1:]
+            s[:1]
+            s[2:]
+            s[11:-11]
+
+            s[50:]
+            s[:25]
+            s[50:55]
+            s[-1:]
+            s[:1]
+            s[2:]
+            s[11:-11]
+
+    def calibrate(self):
+
+        s = join(map(str,range(100)))
+
+        for i in xrange(self.rounds):
+            pass
+
+### String methods
+
+if hasattr('', 'lower'):
+
+    class StringMappings(Test):
+
+        version = 2.0
+        operations = 3 * (5 + 4 + 2 + 1)
+        rounds = 70000
+
+        def test(self):
+
+            s = join(map(chr,range(20)),'')
+            t = join(map(chr,range(50)),'')
+            u = join(map(chr,range(100)),'')
+            v = join(map(chr,range(256)),'')
+
+            for i in xrange(self.rounds):
+
+                s.lower()
+                s.lower()
+                s.lower()
+                s.lower()
+                s.lower()
+
+                s.upper()
+                s.upper()
+                s.upper()
+                s.upper()
+                s.upper()
+
+                s.title()
+                s.title()
+                s.title()
+                s.title()
+                s.title()
+
+                t.lower()
+                t.lower()
+                t.lower()
+                t.lower()
+
+                t.upper()
+                t.upper()
+                t.upper()
+                t.upper()
+
+                t.title()
+                t.title()
+                t.title()
+                t.title()
+
+                u.lower()
+                u.lower()
+
+                u.upper()
+                u.upper()
+
+                u.title()
+                u.title()
+
+                v.lower()
+
+                v.upper()
+
+                v.title()
+
+        def calibrate(self):
+
+            s = join(map(chr,range(20)),'')
+            t = join(map(chr,range(50)),'')
+            u = join(map(chr,range(100)),'')
+            v = join(map(chr,range(256)),'')
+
+            for i in xrange(self.rounds):
+                pass
+
+    class StringPredicates(Test):
+
+        version = 2.0
+        operations = 10 * 7
+        rounds = 100000
+
+        def test(self):
+
+            data = ('abc', '123', '   ', '\xe4\xf6\xfc', '\xdf'*10)
+            len_data = len(data)
+
+            for i in xrange(self.rounds):
+                s = data[i % len_data]
+
+                s.isalnum()
+                s.isalpha()
+                s.isdigit()
+                s.islower()
+                s.isspace()
+                s.istitle()
+                s.isupper()
+
+                s.isalnum()
+                s.isalpha()
+                s.isdigit()
+                s.islower()
+                s.isspace()
+                s.istitle()
+                s.isupper()
+
+                s.isalnum()
+                s.isalpha()
+                s.isdigit()
+                s.islower()
+                s.isspace()
+                s.istitle()
+                s.isupper()
+
+                s.isalnum()
+                s.isalpha()
+                s.isdigit()
+                s.islower()
+                s.isspace()
+                s.istitle()
+                s.isupper()
+
+                s.isalnum()
+                s.isalpha()
+                s.isdigit()
+                s.islower()
+                s.isspace()
+                s.istitle()
+                s.isupper()
+
+                s.isalnum()
+                s.isalpha()
+                s.isdigit()
+                s.islower()
+                s.isspace()
+                s.istitle()
+                s.isupper()
+
+                s.isalnum()
+                s.isalpha()
+                s.isdigit()
+                s.islower()
+                s.isspace()
+                s.istitle()
+                s.isupper()
+
+                s.isalnum()
+                s.isalpha()
+                s.isdigit()
+                s.islower()
+                s.isspace()
+                s.istitle()
+                s.isupper()
+
+                s.isalnum()
+                s.isalpha()
+                s.isdigit()
+                s.islower()
+                s.isspace()
+                s.istitle()
+                s.isupper()
+
+                s.isalnum()
+                s.isalpha()
+                s.isdigit()
+                s.islower()
+                s.isspace()
+                s.istitle()
+                s.isupper()
+
+        def calibrate(self):
+
+            data = ('abc', '123', '   ', '\u1234\u2345\u3456', '\uFFFF'*10)
+            data = ('abc', '123', '   ', '\xe4\xf6\xfc', '\xdf'*10)
+            len_data = len(data)
+
+            for i in xrange(self.rounds):
+                s = data[i % len_data]

Added: vendor/Python/current/Tools/pybench/Tuples.py
===================================================================
--- vendor/Python/current/Tools/pybench/Tuples.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/pybench/Tuples.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,360 @@
+from pybench import Test
+
+class TupleSlicing(Test):
+
+    version = 2.0
+    operations = 3 * 25 * 10 * 7
+    rounds = 500
+
+    def test(self):
+
+        r = range(25)
+        t = tuple(range(100))
+
+        for i in xrange(self.rounds):
+
+            for j in r:
+
+                m = t[50:]
+                m = t[:25]
+                m = t[50:55]
+                m = t[:-1]
+                m = t[1:]
+                m = t[-10:]
+                m = t[:10]
+
+                m = t[50:]
+                m = t[:25]
+                m = t[50:55]
+                m = t[:-1]
+                m = t[1:]
+                m = t[-10:]
+                m = t[:10]
+
+                m = t[50:]
+                m = t[:25]
+                m = t[50:55]
+                m = t[:-1]
+                m = t[1:]
+                m = t[-10:]
+                m = t[:10]
+
+                m = t[50:]
+                m = t[:25]
+                m = t[50:55]
+                m = t[:-1]
+                m = t[1:]
+                m = t[-10:]
+                m = t[:10]
+
+                m = t[50:]
+                m = t[:25]
+                m = t[50:55]
+                m = t[:-1]
+                m = t[1:]
+                m = t[-10:]
+                m = t[:10]
+
+                m = t[50:]
+                m = t[:25]
+                m = t[50:55]
+                m = t[:-1]
+                m = t[1:]
+                m = t[-10:]
+                m = t[:10]
+
+                m = t[50:]
+                m = t[:25]
+                m = t[50:55]
+                m = t[:-1]
+                m = t[1:]
+                m = t[-10:]
+                m = t[:10]
+
+                m = t[50:]
+                m = t[:25]
+                m = t[50:55]
+                m = t[:-1]
+                m = t[1:]
+                m = t[-10:]
+                m = t[:10]
+
+                m = t[50:]
+                m = t[:25]
+                m = t[50:55]
+                m = t[:-1]
+                m = t[1:]
+                m = t[-10:]
+                m = t[:10]
+
+                m = t[50:]
+                m = t[:25]
+                m = t[50:55]
+                m = t[:-1]
+                m = t[1:]
+                m = t[-10:]
+                m = t[:10]
+
+                m = t[50:]
+                m = t[:25]
+                m = t[50:55]
+                m = t[:-1]
+                m = t[1:]
+                m = t[-10:]
+                m = t[:10]
+
+                m = t[50:]
+                m = t[:25]
+                m = t[50:55]
+                m = t[:-1]
+                m = t[1:]
+                m = t[-10:]
+                m = t[:10]
+
+                m = t[50:]
+                m = t[:25]
+                m = t[50:55]
+                m = t[:-1]
+                m = t[1:]
+                m = t[-10:]
+                m = t[:10]
+
+                m = t[50:]
+                m = t[:25]
+                m = t[50:55]
+                m = t[:-1]
+                m = t[1:]
+                m = t[-10:]
+                m = t[:10]
+
+                m = t[50:]
+                m = t[:25]
+                m = t[50:55]
+                m = t[:-1]
+                m = t[1:]
+                m = t[-10:]
+                m = t[:10]
+
+                m = t[50:]
+                m = t[:25]
+                m = t[50:55]
+                m = t[:-1]
+                m = t[1:]
+                m = t[-10:]
+                m = t[:10]
+
+                m = t[50:]
+                m = t[:25]
+                m = t[50:55]
+                m = t[:-1]
+                m = t[1:]
+                m = t[-10:]
+                m = t[:10]
+
+                m = t[50:]
+                m = t[:25]
+                m = t[50:55]
+                m = t[:-1]
+                m = t[1:]
+                m = t[-10:]
+                m = t[:10]
+
+                m = t[50:]
+                m = t[:25]
+                m = t[50:55]
+                m = t[:-1]
+                m = t[1:]
+                m = t[-10:]
+                m = t[:10]
+
+                m = t[50:]
+                m = t[:25]
+                m = t[50:55]
+                m = t[:-1]
+                m = t[1:]
+                m = t[-10:]
+                m = t[:10]
+
+                m = t[50:]
+                m = t[:25]
+                m = t[50:55]
+                m = t[:-1]
+                m = t[1:]
+                m = t[-10:]
+                m = t[:10]
+
+                m = t[50:]
+                m = t[:25]
+                m = t[50:55]
+                m = t[:-1]
+                m = t[1:]
+                m = t[-10:]
+                m = t[:10]
+
+                m = t[50:]
+                m = t[:25]
+                m = t[50:55]
+                m = t[:-1]
+                m = t[1:]
+                m = t[-10:]
+                m = t[:10]
+
+                m = t[50:]
+                m = t[:25]
+                m = t[50:55]
+                m = t[:-1]
+                m = t[1:]
+                m = t[-10:]
+                m = t[:10]
+
+                m = t[50:]
+                m = t[:25]
+                m = t[50:55]
+                m = t[:-1]
+                m = t[1:]
+                m = t[-10:]
+                m = t[:10]
+
+                m = t[50:]
+                m = t[:25]
+                m = t[50:55]
+                m = t[:-1]
+                m = t[1:]
+                m = t[-10:]
+                m = t[:10]
+
+                m = t[50:]
+                m = t[:25]
+                m = t[50:55]
+                m = t[:-1]
+                m = t[1:]
+                m = t[-10:]
+                m = t[:10]
+
+                m = t[50:]
+                m = t[:25]
+                m = t[50:55]
+                m = t[:-1]
+                m = t[1:]
+                m = t[-10:]
+                m = t[:10]
+
+                m = t[50:]
+                m = t[:25]
+                m = t[50:55]
+                m = t[:-1]
+                m = t[1:]
+                m = t[-10:]
+                m = t[:10]
+
+                m = t[50:]
+                m = t[:25]
+                m = t[50:55]
+                m = t[:-1]
+                m = t[1:]
+                m = t[-10:]
+                m = t[:10]
+
+    def calibrate(self):
+
+        r = range(25)
+        t = tuple(range(100))
+
+        for i in xrange(self.rounds):
+            for j in r:
+                pass
+
+class SmallTuples(Test):
+
+    version = 2.0
+    operations = 5*(1 + 3 + 6 + 2)
+    rounds = 90000
+
+    def test(self):
+
+        for i in xrange(self.rounds):
+
+            t = (1,2,3,4,5,6)
+
+            a,b,c,d,e,f = t
+            a,b,c,d,e,f = t
+            a,b,c,d,e,f = t
+
+            a,b,c = t[:3]
+            a,b,c = t[:3]
+            a,b,c = t[:3]
+            a,b,c = t[:3]
+            a,b,c = t[:3]
+            a,b,c = t[:3]
+
+            l = list(t)
+            t = tuple(l)
+
+            t = (1,2,3,4,5,6)
+
+            a,b,c,d,e,f = t
+            a,b,c,d,e,f = t
+            a,b,c,d,e,f = t
+
+            a,b,c = t[:3]
+            a,b,c = t[:3]
+            a,b,c = t[:3]
+            a,b,c = t[:3]
+            a,b,c = t[:3]
+            a,b,c = t[:3]
+
+            l = list(t)
+            t = tuple(l)
+
+            t = (1,2,3,4,5,6)
+
+            a,b,c,d,e,f = t
+            a,b,c,d,e,f = t
+            a,b,c,d,e,f = t
+
+            a,b,c = t[:3]
+            a,b,c = t[:3]
+            a,b,c = t[:3]
+            a,b,c = t[:3]
+            a,b,c = t[:3]
+            a,b,c = t[:3]
+
+            l = list(t)
+            t = tuple(l)
+
+            t = (1,2,3,4,5,6)
+
+            a,b,c,d,e,f = t
+            a,b,c,d,e,f = t
+            a,b,c,d,e,f = t
+
+            a,b,c = t[:3]
+            a,b,c = t[:3]
+            a,b,c = t[:3]
+            a,b,c = t[:3]
+            a,b,c = t[:3]
+            a,b,c = t[:3]
+
+            l = list(t)
+            t = tuple(l)
+
+            t = (1,2,3,4,5,6)
+
+            a,b,c,d,e,f = t
+            a,b,c,d,e,f = t
+            a,b,c,d,e,f = t
+
+            a,b,c = t[:3]
+            a,b,c = t[:3]
+            a,b,c = t[:3]
+            a,b,c = t[:3]
+            a,b,c = t[:3]
+            a,b,c = t[:3]
+
+            l = list(t)
+            t = tuple(l)
+
+    def calibrate(self):
+
+        for i in xrange(self.rounds):
+            pass

Added: vendor/Python/current/Tools/pybench/Unicode.py
===================================================================
--- vendor/Python/current/Tools/pybench/Unicode.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/pybench/Unicode.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,542 @@
+try:
+    unicode
+except NameError:
+    raise ImportError
+
+from pybench import Test
+from string import join
+
+class ConcatUnicode(Test):
+
+    version = 2.0
+    operations = 10 * 5
+    rounds = 60000
+
+    def test(self):
+
+        # Make sure the strings are *not* interned
+        s = unicode(join(map(str,range(100))))
+        t = unicode(join(map(str,range(1,101))))
+
+        for i in xrange(self.rounds):
+            t + s
+            t + s
+            t + s
+            t + s
+            t + s
+
+            t + s
+            t + s
+            t + s
+            t + s
+            t + s
+
+            t + s
+            t + s
+            t + s
+            t + s
+            t + s
+
+            t + s
+            t + s
+            t + s
+            t + s
+            t + s
+
+            t + s
+            t + s
+            t + s
+            t + s
+            t + s
+
+            t + s
+            t + s
+            t + s
+            t + s
+            t + s
+
+            t + s
+            t + s
+            t + s
+            t + s
+            t + s
+
+            t + s
+            t + s
+            t + s
+            t + s
+            t + s
+
+            t + s
+            t + s
+            t + s
+            t + s
+            t + s
+
+            t + s
+            t + s
+            t + s
+            t + s
+            t + s
+
+    def calibrate(self):
+
+        s = unicode(join(map(str,range(100))))
+        t = unicode(join(map(str,range(1,101))))
+
+        for i in xrange(self.rounds):
+            pass
+
+
+class CompareUnicode(Test):
+
+    version = 2.0
+    operations = 10 * 5
+    rounds = 150000
+
+    def test(self):
+
+        # Make sure the strings are *not* interned
+        s = unicode(join(map(str,range(10))))
+        t = unicode(join(map(str,range(10))) + "abc")
+
+        for i in xrange(self.rounds):
+            t < s
+            t > s
+            t == s
+            t > s
+            t < s
+
+            t < s
+            t > s
+            t == s
+            t > s
+            t < s
+
+            t < s
+            t > s
+            t == s
+            t > s
+            t < s
+
+            t < s
+            t > s
+            t == s
+            t > s
+            t < s
+
+            t < s
+            t > s
+            t == s
+            t > s
+            t < s
+
+            t < s
+            t > s
+            t == s
+            t > s
+            t < s
+
+            t < s
+            t > s
+            t == s
+            t > s
+            t < s
+
+            t < s
+            t > s
+            t == s
+            t > s
+            t < s
+
+            t < s
+            t > s
+            t == s
+            t > s
+            t < s
+
+            t < s
+            t > s
+            t == s
+            t > s
+            t < s
+
+    def calibrate(self):
+
+        s = unicode(join(map(str,range(10))))
+        t = unicode(join(map(str,range(10))) + "abc")
+
+        for i in xrange(self.rounds):
+            pass
+
+
+class CreateUnicodeWithConcat(Test):
+
+    version = 2.0
+    operations = 10 * 5
+    rounds = 80000
+
+    def test(self):
+
+        for i in xrange(self.rounds):
+            s = u'om'
+            s = s + u'xbx'
+            s = s + u'xcx'
+            s = s + u'xdx'
+            s = s + u'xex'
+
+            s = s + u'xax'
+            s = s + u'xbx'
+            s = s + u'xcx'
+            s = s + u'xdx'
+            s = s + u'xex'
+
+            s = s + u'xax'
+            s = s + u'xbx'
+            s = s + u'xcx'
+            s = s + u'xdx'
+            s = s + u'xex'
+
+            s = s + u'xax'
+            s = s + u'xbx'
+            s = s + u'xcx'
+            s = s + u'xdx'
+            s = s + u'xex'
+
+            s = s + u'xax'
+            s = s + u'xbx'
+            s = s + u'xcx'
+            s = s + u'xdx'
+            s = s + u'xex'
+
+            s = s + u'xax'
+            s = s + u'xbx'
+            s = s + u'xcx'
+            s = s + u'xdx'
+            s = s + u'xex'
+
+            s = s + u'xax'
+            s = s + u'xbx'
+            s = s + u'xcx'
+            s = s + u'xdx'
+            s = s + u'xex'
+
+            s = s + u'xax'
+            s = s + u'xbx'
+            s = s + u'xcx'
+            s = s + u'xdx'
+            s = s + u'xex'
+
+            s = s + u'xax'
+            s = s + u'xbx'
+            s = s + u'xcx'
+            s = s + u'xdx'
+            s = s + u'xex'
+
+            s = s + u'xax'
+            s = s + u'xbx'
+            s = s + u'xcx'
+            s = s + u'xdx'
+            s = s + u'xex'
+
+    def calibrate(self):
+
+        for i in xrange(self.rounds):
+            pass
+
+
+class UnicodeSlicing(Test):
+
+    version = 2.0
+    operations = 5 * 7
+    rounds = 140000
+
+    def test(self):
+
+        s = unicode(join(map(str,range(100))))
+
+        for i in xrange(self.rounds):
+
+            s[50:]
+            s[:25]
+            s[50:55]
+            s[-1:]
+            s[:1]
+            s[2:]
+            s[11:-11]
+
+            s[50:]
+            s[:25]
+            s[50:55]
+            s[-1:]
+            s[:1]
+            s[2:]
+            s[11:-11]
+
+            s[50:]
+            s[:25]
+            s[50:55]
+            s[-1:]
+            s[:1]
+            s[2:]
+            s[11:-11]
+
+            s[50:]
+            s[:25]
+            s[50:55]
+            s[-1:]
+            s[:1]
+            s[2:]
+            s[11:-11]
+
+            s[50:]
+            s[:25]
+            s[50:55]
+            s[-1:]
+            s[:1]
+            s[2:]
+            s[11:-11]
+
+    def calibrate(self):
+
+        s = unicode(join(map(str,range(100))))
+
+        for i in xrange(self.rounds):
+            pass
+
+### String methods
+
+class UnicodeMappings(Test):
+
+    version = 2.0
+    operations = 3 * (5 + 4 + 2 + 1)
+    rounds = 10000
+
+    def test(self):
+
+        s = join(map(unichr,range(20)),'')
+        t = join(map(unichr,range(100)),'')
+        u = join(map(unichr,range(500)),'')
+        v = join(map(unichr,range(1000)),'')
+
+        for i in xrange(self.rounds):
+
+            s.lower()
+            s.lower()
+            s.lower()
+            s.lower()
+            s.lower()
+
+            s.upper()
+            s.upper()
+            s.upper()
+            s.upper()
+            s.upper()
+
+            s.title()
+            s.title()
+            s.title()
+            s.title()
+            s.title()
+
+            t.lower()
+            t.lower()
+            t.lower()
+            t.lower()
+
+            t.upper()
+            t.upper()
+            t.upper()
+            t.upper()
+
+            t.title()
+            t.title()
+            t.title()
+            t.title()
+
+            u.lower()
+            u.lower()
+
+            u.upper()
+            u.upper()
+
+            u.title()
+            u.title()
+
+            v.lower()
+
+            v.upper()
+
+            v.title()
+
+    def calibrate(self):
+
+        s = join(map(unichr,range(20)),'')
+        t = join(map(unichr,range(100)),'')
+        u = join(map(unichr,range(500)),'')
+        v = join(map(unichr,range(1000)),'')
+
+        for i in xrange(self.rounds):
+            pass
+
+class UnicodePredicates(Test):
+
+    version = 2.0
+    operations = 5 * 9
+    rounds = 120000
+
+    def test(self):
+
+        data = (u'abc', u'123', u'   ', u'\u1234\u2345\u3456', u'\uFFFF'*10)
+        len_data = len(data)
+
+        for i in xrange(self.rounds):
+            s = data[i % len_data]
+
+            s.isalnum()
+            s.isalpha()
+            s.isdecimal()
+            s.isdigit()
+            s.islower()
+            s.isnumeric()
+            s.isspace()
+            s.istitle()
+            s.isupper()
+
+            s.isalnum()
+            s.isalpha()
+            s.isdecimal()
+            s.isdigit()
+            s.islower()
+            s.isnumeric()
+            s.isspace()
+            s.istitle()
+            s.isupper()
+
+            s.isalnum()
+            s.isalpha()
+            s.isdecimal()
+            s.isdigit()
+            s.islower()
+            s.isnumeric()
+            s.isspace()
+            s.istitle()
+            s.isupper()
+
+            s.isalnum()
+            s.isalpha()
+            s.isdecimal()
+            s.isdigit()
+            s.islower()
+            s.isnumeric()
+            s.isspace()
+            s.istitle()
+            s.isupper()
+
+            s.isalnum()
+            s.isalpha()
+            s.isdecimal()
+            s.isdigit()
+            s.islower()
+            s.isnumeric()
+            s.isspace()
+            s.istitle()
+            s.isupper()
+
+    def calibrate(self):
+
+        data = (u'abc', u'123', u'   ', u'\u1234\u2345\u3456', u'\uFFFF'*10)
+        len_data = len(data)
+
+        for i in xrange(self.rounds):
+            s = data[i % len_data]
+
+try:
+    import unicodedata
+except ImportError:
+    pass
+else:
+    class UnicodeProperties(Test):
+
+        version = 2.0
+        operations = 5 * 8
+        rounds = 100000
+
+        def test(self):
+
+            data = (u'a', u'1', u' ', u'\u1234', u'\uFFFF')
+            len_data = len(data)
+            digit = unicodedata.digit
+            numeric = unicodedata.numeric
+            decimal = unicodedata.decimal
+            category = unicodedata.category
+            bidirectional = unicodedata.bidirectional
+            decomposition = unicodedata.decomposition
+            mirrored = unicodedata.mirrored
+            combining = unicodedata.combining
+
+            for i in xrange(self.rounds):
+
+                c = data[i % len_data]
+
+                digit(c, None)
+                numeric(c, None)
+                decimal(c, None)
+                category(c)
+                bidirectional(c)
+                decomposition(c)
+                mirrored(c)
+                combining(c)
+
+                digit(c, None)
+                numeric(c, None)
+                decimal(c, None)
+                category(c)
+                bidirectional(c)
+                decomposition(c)
+                mirrored(c)
+                combining(c)
+
+                digit(c, None)
+                numeric(c, None)
+                decimal(c, None)
+                category(c)
+                bidirectional(c)
+                decomposition(c)
+                mirrored(c)
+                combining(c)
+
+                digit(c, None)
+                numeric(c, None)
+                decimal(c, None)
+                category(c)
+                bidirectional(c)
+                decomposition(c)
+                mirrored(c)
+                combining(c)
+
+                digit(c, None)
+                numeric(c, None)
+                decimal(c, None)
+                category(c)
+                bidirectional(c)
+                decomposition(c)
+                mirrored(c)
+                combining(c)
+
+        def calibrate(self):
+
+            data = (u'a', u'1', u' ', u'\u1234', u'\uFFFF')
+            len_data = len(data)
+            digit = unicodedata.digit
+            numeric = unicodedata.numeric
+            decimal = unicodedata.decimal
+            category = unicodedata.category
+            bidirectional = unicodedata.bidirectional
+            decomposition = unicodedata.decomposition
+            mirrored = unicodedata.mirrored
+            combining = unicodedata.combining
+
+            for i in xrange(self.rounds):
+
+                c = data[i % len_data]

Added: vendor/Python/current/Tools/pybench/clockres.py
===================================================================
--- vendor/Python/current/Tools/pybench/clockres.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/pybench/clockres.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,43 @@
+#!/usr/bin/env python
+
+""" clockres - calculates the resolution in seconds of a given timer.
+
+    Copyright (c) 2006, Marc-Andre Lemburg (mal at egenix.com). See the
+    documentation for further information on copyrights, or contact
+    the author. All Rights Reserved.
+
+"""
+import time
+
+TEST_TIME = 1.0
+
+def clockres(timer):
+    d = {}
+    wallclock = time.time
+    start = wallclock()
+    stop = wallclock() + TEST_TIME
+    spin_loops = range(1000)
+    while 1:
+        now = wallclock()
+        if now >= stop:
+            break
+        for i in spin_loops:
+            d[timer()] = 1
+    values = d.keys()
+    values.sort()
+    min_diff = TEST_TIME
+    for i in range(len(values) - 1):
+        diff = values[i+1] - values[i]
+        if diff < min_diff:
+            min_diff = diff
+    return min_diff
+
+if __name__ == '__main__':
+    print 'Clock resolution of various timer implementations:'
+    print 'time.clock:           %10.3fus' % (clockres(time.clock) * 1e6)
+    print 'time.time:            %10.3fus' % (clockres(time.time) * 1e6)
+    try:
+        import systimes
+        print 'systimes.processtime: %10.3fus' % (clockres(systimes.processtime) * 1e6)
+    except ImportError:
+        pass

Added: vendor/Python/current/Tools/pybench/package/__init__.py
===================================================================

Added: vendor/Python/current/Tools/pybench/package/submodule.py
===================================================================

Added: vendor/Python/current/Tools/pybench/pybench.py
===================================================================
--- vendor/Python/current/Tools/pybench/pybench.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/pybench/pybench.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,943 @@
+#!/usr/local/bin/python -O
+
+""" A Python Benchmark Suite
+
+"""
+#
+# Note: Please keep this module compatible to Python 1.5.2.
+#
+# Tests may include features in later Python versions, but these
+# should then be embedded in try-except clauses in the configuration
+# module Setup.py.
+#
+
+# pybench Copyright
+__copyright__ = """\
+Copyright (c), 1997-2006, Marc-Andre Lemburg (mal at lemburg.com)
+Copyright (c), 2000-2006, eGenix.com Software GmbH (info at egenix.com)
+
+                   All Rights Reserved.
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee or royalty is hereby
+granted, provided that the above copyright notice appear in all copies
+and that both that copyright notice and this permission notice appear
+in supporting documentation or portions thereof, including
+modifications, that you make.
+
+THE AUTHOR MARC-ANDRE LEMBURG DISCLAIMS ALL WARRANTIES WITH REGARD TO
+THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
+INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+WITH THE USE OR PERFORMANCE OF THIS SOFTWARE !
+"""
+
+import sys, time, operator, string
+from CommandLine import *
+
+try:
+    import cPickle
+    pickle = cPickle
+except ImportError:
+    import pickle
+
+# Version number; version history: see README file !
+__version__ = '2.0'
+
+### Constants
+
+# Second fractions
+MILLI_SECONDS = 1e3
+MICRO_SECONDS = 1e6
+
+# Percent unit
+PERCENT = 100
+
+# Horizontal line length
+LINE = 79
+
+# Minimum test run-time
+MIN_TEST_RUNTIME = 1e-3
+
+# Number of calibration runs to use for calibrating the tests
+CALIBRATION_RUNS = 20
+
+# Number of calibration loops to run for each calibration run
+CALIBRATION_LOOPS = 20
+
+# Allow skipping calibration ?
+ALLOW_SKIPPING_CALIBRATION = 1
+
+# Timer types
+TIMER_TIME_TIME = 'time.time'
+TIMER_TIME_CLOCK = 'time.clock'
+TIMER_SYSTIMES_PROCESSTIME = 'systimes.processtime'
+
+# Choose platform default timer
+if sys.platform[:3] == 'win':
+    # On WinXP this has 2.5ms resolution
+    TIMER_PLATFORM_DEFAULT = TIMER_TIME_CLOCK
+else:
+    # On Linux this has 1ms resolution
+    TIMER_PLATFORM_DEFAULT = TIMER_TIME_TIME
+
+# Print debug information ?
+_debug = 0
+
+### Helpers
+
+def get_timer(timertype):
+
+    if timertype == TIMER_TIME_TIME:
+        return time.time
+    elif timertype == TIMER_TIME_CLOCK:
+        return time.clock
+    elif timertype == TIMER_SYSTIMES_PROCESSTIME:
+        import systimes
+        return systimes.processtime
+    else:
+        raise TypeError('unknown timer type: %s' % timertype)
+
+def get_machine_details():
+
+    import platform
+    if _debug:
+        print 'Getting machine details...'
+    buildno, builddate = platform.python_build()
+    python = platform.python_version()
+    if python > '2.0':
+        try:
+            unichr(100000)
+        except ValueError:
+            # UCS2 build (standard)
+            unicode = 'UCS2'
+        else:
+            # UCS4 build (most recent Linux distros)
+            unicode = 'UCS4'
+    else:
+        unicode = None
+    bits, linkage = platform.architecture()
+    return {
+        'platform': platform.platform(),
+        'processor': platform.processor(),
+        'executable': sys.executable,
+        'python': platform.python_version(),
+        'compiler': platform.python_compiler(),
+        'buildno': buildno,
+        'builddate': builddate,
+        'unicode': unicode,
+        'bits': bits,
+        }
+
+def print_machine_details(d, indent=''):
+
+    l = ['Machine Details:',
+         '   Platform ID:  %s' % d.get('platform', 'n/a'),
+         '   Processor:    %s' % d.get('processor', 'n/a'),
+         '',
+         'Python:',
+         '   Executable:   %s' % d.get('executable', 'n/a'),
+         '   Version:      %s' % d.get('python', 'n/a'),
+         '   Compiler:     %s' % d.get('compiler', 'n/a'),
+         '   Bits:         %s' % d.get('bits', 'n/a'),
+         '   Build:        %s (#%s)' % (d.get('builddate', 'n/a'),
+                                        d.get('buildno', 'n/a')),
+         '   Unicode:      %s' % d.get('unicode', 'n/a'),
+         ]
+    print indent + string.join(l, '\n' + indent) + '\n'
+
+### Test baseclass
+
+class Test:
+
+    """ All test must have this class as baseclass. It provides
+        the necessary interface to the benchmark machinery.
+
+        The tests must set .rounds to a value high enough to let the
+        test run between 20-50 seconds. This is needed because
+        clock()-timing only gives rather inaccurate values (on Linux,
+        for example, it is accurate to a few hundreths of a
+        second). If you don't want to wait that long, use a warp
+        factor larger than 1.
+
+        It is also important to set the .operations variable to a
+        value representing the number of "virtual operations" done per
+        call of .run().
+
+        If you change a test in some way, don't forget to increase
+        it's version number.
+
+    """
+
+    ### Instance variables that each test should override
+
+    # Version number of the test as float (x.yy); this is important
+    # for comparisons of benchmark runs - tests with unequal version
+    # number will not get compared.
+    version = 2.0
+
+    # The number of abstract operations done in each round of the
+    # test. An operation is the basic unit of what you want to
+    # measure. The benchmark will output the amount of run-time per
+    # operation. Note that in order to raise the measured timings
+    # significantly above noise level, it is often required to repeat
+    # sets of operations more than once per test round. The measured
+    # overhead per test round should be less than 1 second.
+    operations = 1
+
+    # Number of rounds to execute per test run. This should be
+    # adjusted to a figure that results in a test run-time of between
+    # 1-2 seconds.
+    rounds = 100000
+
+    ### Internal variables
+
+    # Mark this class as implementing a test
+    is_a_test = 1
+
+    # Last timing: (real, run, overhead)
+    last_timing = (0.0, 0.0, 0.0)
+
+    # Warp factor to use for this test
+    warp = 1
+
+    # Number of calibration runs to use
+    calibration_runs = CALIBRATION_RUNS
+
+    # List of calibration timings
+    overhead_times = None
+
+    # List of test run timings
+    times = []
+
+    # Timer used for the benchmark
+    timer = TIMER_PLATFORM_DEFAULT
+
+    def __init__(self, warp=None, calibration_runs=None, timer=None):
+
+        # Set parameters
+        if warp is not None:
+            self.rounds = int(self.rounds / warp)
+            if self.rounds == 0:
+                raise ValueError('warp factor set too high')
+            self.warp = warp
+        if calibration_runs is not None:
+            if (not ALLOW_SKIPPING_CALIBRATION and
+                calibration_runs < 1):
+                raise ValueError('at least one calibration run is required')
+            self.calibration_runs = calibration_runs
+        if timer is not None:
+            timer = timer
+
+        # Init variables
+        self.times = []
+        self.overhead_times = []
+
+        # We want these to be in the instance dict, so that pickle
+        # saves them
+        self.version = self.version
+        self.operations = self.operations
+        self.rounds = self.rounds
+
+    def get_timer(self):
+
+        """ Return the timer function to use for the test.
+
+        """
+        return get_timer(self.timer)
+
+    def compatible(self, other):
+
+        """ Return 1/0 depending on whether the test is compatible
+            with the other Test instance or not.
+
+        """
+        if self.version != other.version:
+            return 0
+        if self.rounds != other.rounds:
+            return 0
+        return 1
+
+    def calibrate_test(self):
+
+        if self.calibration_runs == 0:
+            self.overhead_times = [0.0]
+            return
+
+        calibrate = self.calibrate
+        timer = self.get_timer()
+        calibration_loops = range(CALIBRATION_LOOPS)
+
+        # Time the calibration loop overhead
+        prep_times = []
+        for i in range(self.calibration_runs):
+            t = timer()
+            for i in calibration_loops:
+                pass
+            t = timer() - t
+            prep_times.append(t)
+        min_prep_time = min(prep_times)
+        if _debug:
+            print
+            print 'Calib. prep time     = %.6fms' % (
+                min_prep_time * MILLI_SECONDS)
+
+        # Time the calibration runs (doing CALIBRATION_LOOPS loops of
+        # .calibrate() method calls each)
+        for i in range(self.calibration_runs):
+            t = timer()
+            for i in calibration_loops:
+                calibrate()
+            t = timer() - t
+            self.overhead_times.append(t / CALIBRATION_LOOPS
+                                       - min_prep_time)
+
+        # Check the measured times
+        min_overhead = min(self.overhead_times)
+        max_overhead = max(self.overhead_times)
+        if _debug:
+            print 'Calib. overhead time = %.6fms' % (
+                min_overhead * MILLI_SECONDS)
+        if min_overhead < 0.0:
+            raise ValueError('calibration setup did not work')
+        if max_overhead - min_overhead > 0.1:
+            raise ValueError(
+                'overhead calibration timing range too inaccurate: '
+                '%r - %r' % (min_overhead, max_overhead))
+
+    def run(self):
+
+        """ Run the test in two phases: first calibrate, then
+            do the actual test. Be careful to keep the calibration
+            timing low w/r to the test timing.
+
+        """
+        test = self.test
+        timer = self.get_timer()
+
+        # Get calibration
+        min_overhead = min(self.overhead_times)
+
+        # Test run
+        t = timer()
+        test()
+        t = timer() - t
+        if t < MIN_TEST_RUNTIME:
+            raise ValueError('warp factor too high: '
+                             'test times are < 10ms')
+        eff_time = t - min_overhead
+        if eff_time < 0:
+            raise ValueError('wrong calibration')
+        self.last_timing = (eff_time, t, min_overhead)
+        self.times.append(eff_time)
+
+    def calibrate(self):
+
+        """ Calibrate the test.
+
+            This method should execute everything that is needed to
+            setup and run the test - except for the actual operations
+            that you intend to measure. pybench uses this method to
+            measure the test implementation overhead.
+
+        """
+        return
+
+    def test(self):
+
+        """ Run the test.
+
+            The test needs to run self.rounds executing
+            self.operations number of operations each.
+
+        """
+        return
+
+    def stat(self):
+
+        """ Return test run statistics as tuple:
+
+            (minimum run time,
+             average run time,
+             total run time,
+             average time per operation,
+             minimum overhead time)
+
+        """
+        runs = len(self.times)
+        if runs == 0:
+            return 0.0, 0.0, 0.0, 0.0
+        min_time = min(self.times)
+        total_time = reduce(operator.add, self.times, 0.0)
+        avg_time = total_time / float(runs)
+        operation_avg = total_time / float(runs
+                                           * self.rounds
+                                           * self.operations)
+        if self.overhead_times:
+            min_overhead = min(self.overhead_times)
+        else:
+            min_overhead = self.last_timing[2]
+        return min_time, avg_time, total_time, operation_avg, min_overhead
+
+### Load Setup
+
+# This has to be done after the definition of the Test class, since
+# the Setup module will import subclasses using this class.
+
+import Setup
+
+### Benchmark base class
+
+class Benchmark:
+
+    # Name of the benchmark
+    name = ''
+
+    # Number of benchmark rounds to run
+    rounds = 1
+
+    # Warp factor use to run the tests
+    warp = 1                    # Warp factor
+
+    # Average benchmark round time
+    roundtime = 0
+
+    # Benchmark version number as float x.yy
+    version = 2.0
+
+    # Produce verbose output ?
+    verbose = 0
+
+    # Dictionary with the machine details
+    machine_details = None
+
+    # Timer used for the benchmark
+    timer = TIMER_PLATFORM_DEFAULT
+
+    def __init__(self, name, verbose=None, timer=None, warp=None,
+                 calibration_runs=None):
+
+        if name:
+            self.name = name
+        else:
+            self.name = '%04i-%02i-%02i %02i:%02i:%02i' % \
+                        (time.localtime(time.time())[:6])
+        if verbose is not None:
+            self.verbose = verbose
+        if timer is not None:
+            self.timer = timer
+        if warp is not None:
+            self.warp = warp
+        if calibration_runs is not None:
+            self.calibration_runs = calibration_runs
+
+        # Init vars
+        self.tests = {}
+        if _debug:
+            print 'Getting machine details...'
+        self.machine_details = get_machine_details()
+
+        # Make .version an instance attribute to have it saved in the
+        # Benchmark pickle
+        self.version = self.version
+
+    def get_timer(self):
+
+        """ Return the timer function to use for the test.
+
+        """
+        return get_timer(self.timer)
+
+    def compatible(self, other):
+
+        """ Return 1/0 depending on whether the benchmark is
+            compatible with the other Benchmark instance or not.
+
+        """
+        if self.version != other.version:
+            return 0
+        if (self.machine_details == other.machine_details and
+            self.timer != other.timer):
+            return 0
+        if (self.calibration_runs == 0 and
+            other.calibration_runs != 0):
+            return 0
+        if (self.calibration_runs != 0 and
+            other.calibration_runs == 0):
+            return 0
+        return 1
+
+    def load_tests(self, setupmod, limitnames=None):
+
+        # Add tests
+        if self.verbose:
+            print 'Searching for tests ...'
+            print '--------------------------------------'
+        for testclass in setupmod.__dict__.values():
+            if not hasattr(testclass, 'is_a_test'):
+                continue
+            name = testclass.__name__
+            if  name == 'Test':
+                continue
+            if (limitnames is not None and
+                limitnames.search(name) is None):
+                continue
+            self.tests[name] = testclass(
+                warp=self.warp,
+                calibration_runs=self.calibration_runs,
+                timer=self.timer)
+        l = self.tests.keys()
+        l.sort()
+        if self.verbose:
+            for name in l:
+                print '  %s' % name
+            print '--------------------------------------'
+            print '  %i tests found' % len(l)
+            print
+
+    def calibrate(self):
+
+        print 'Calibrating tests. Please wait...'
+        if self.verbose:
+            print
+            print 'Test                              min      max'
+            print '-' * LINE
+        tests = self.tests.items()
+        tests.sort()
+        for i in range(len(tests)):
+            name, test = tests[i]
+            test.calibrate_test()
+            if self.verbose:
+                print '%30s:  %6.3fms  %6.3fms' % \
+                      (name,
+                       min(test.overhead_times) * MILLI_SECONDS,
+                       max(test.overhead_times) * MILLI_SECONDS)
+        print
+
+    def run(self):
+
+        tests = self.tests.items()
+        tests.sort()
+        timer = self.get_timer()
+        print 'Running %i round(s) of the suite at warp factor %i:' % \
+              (self.rounds, self.warp)
+        print
+        self.roundtimes = []
+        for i in range(self.rounds):
+            if self.verbose:
+                print ' Round %-25i  effective   absolute  overhead' % (i+1)
+            total_eff_time = 0.0
+            for j in range(len(tests)):
+                name, test = tests[j]
+                if self.verbose:
+                    print '%30s:' % name,
+                test.run()
+                (eff_time, abs_time, min_overhead) = test.last_timing
+                total_eff_time = total_eff_time + eff_time
+                if self.verbose:
+                    print '    %5.0fms    %5.0fms %7.3fms' % \
+                          (eff_time * MILLI_SECONDS,
+                           abs_time * MILLI_SECONDS,
+                           min_overhead * MILLI_SECONDS)
+            self.roundtimes.append(total_eff_time)
+            if self.verbose:
+                print ('                   '
+                       '               ------------------------------')
+                print ('                   '
+                       '     Totals:    %6.0fms' %
+                       (total_eff_time * MILLI_SECONDS))
+                print
+            else:
+                print '* Round %i done in %.3f seconds.' % (i+1,
+                                                            total_eff_time)
+        print
+
+    def stat(self):
+
+        """ Return benchmark run statistics as tuple:
+
+            (minimum round time,
+             average round time,
+             maximum round time)
+
+            XXX Currently not used, since the benchmark does test
+                statistics across all rounds.
+
+        """
+        runs = len(self.roundtimes)
+        if runs == 0:
+            return 0.0, 0.0
+        min_time = min(self.roundtimes)
+        total_time = reduce(operator.add, self.roundtimes, 0.0)
+        avg_time = total_time / float(runs)
+        max_time = max(self.roundtimes)
+        return (min_time, avg_time, max_time)
+
+    def print_header(self, title='Benchmark'):
+
+        print '-' * LINE
+        print '%s: %s' % (title, self.name)
+        print '-' * LINE
+        print
+        print '    Rounds: %s' % self.rounds
+        print '    Warp:   %s' % self.warp
+        print '    Timer:  %s' % self.timer
+        print
+        if self.machine_details:
+            print_machine_details(self.machine_details, indent='    ')
+            print
+
+    def print_benchmark(self, hidenoise=0, limitnames=None):
+
+        print ('Test                          '
+               '   minimum  average  operation  overhead')
+        print '-' * LINE
+        tests = self.tests.items()
+        tests.sort()
+        total_min_time = 0.0
+        total_avg_time = 0.0
+        for name, test in tests:
+            if (limitnames is not None and
+                limitnames.search(name) is None):
+                continue
+            (min_time,
+             avg_time,
+             total_time,
+             op_avg,
+             min_overhead) = test.stat()
+            total_min_time = total_min_time + min_time
+            total_avg_time = total_avg_time + avg_time
+            print '%30s:  %5.0fms  %5.0fms  %6.2fus  %7.3fms' % \
+                  (name,
+                   min_time * MILLI_SECONDS,
+                   avg_time * MILLI_SECONDS,
+                   op_avg * MICRO_SECONDS,
+                   min_overhead *MILLI_SECONDS)
+        print '-' * LINE
+        print ('Totals:                        '
+               ' %6.0fms %6.0fms' %
+               (total_min_time * MILLI_SECONDS,
+                total_avg_time * MILLI_SECONDS,
+                ))
+        print
+
+    def print_comparison(self, compare_to, hidenoise=0, limitnames=None):
+
+        # Check benchmark versions
+        if compare_to.version != self.version:
+            print ('* Benchmark versions differ: '
+                   'cannot compare this benchmark to "%s" !' %
+                   compare_to.name)
+            print
+            self.print_benchmark(hidenoise=hidenoise,
+                                 limitnames=limitnames)
+            return
+
+        # Print header
+        compare_to.print_header('Comparing with')
+        print ('Test                          '
+               '   minimum run-time        average  run-time')
+        print ('                              '
+               '   this    other   diff    this    other   diff')
+        print '-' * LINE
+
+        # Print test comparisons
+        tests = self.tests.items()
+        tests.sort()
+        total_min_time = other_total_min_time = 0.0
+        total_avg_time = other_total_avg_time = 0.0
+        benchmarks_compatible = self.compatible(compare_to)
+        tests_compatible = 1
+        for name, test in tests:
+            if (limitnames is not None and
+                limitnames.search(name) is None):
+                continue
+            (min_time,
+             avg_time,
+             total_time,
+             op_avg,
+             min_overhead) = test.stat()
+            total_min_time = total_min_time + min_time
+            total_avg_time = total_avg_time + avg_time
+            try:
+                other = compare_to.tests[name]
+            except KeyError:
+                other = None
+            if other is None:
+                # Other benchmark doesn't include the given test
+                min_diff, avg_diff = 'n/a', 'n/a'
+                other_min_time = 0.0
+                other_avg_time = 0.0
+                tests_compatible = 0
+            else:
+                (other_min_time,
+                 other_avg_time,
+                 other_total_time,
+                 other_op_avg,
+                 other_min_overhead) = other.stat()
+                other_total_min_time = other_total_min_time + other_min_time
+                other_total_avg_time = other_total_avg_time + other_avg_time
+                if (benchmarks_compatible and
+                    test.compatible(other)):
+                    # Both benchmark and tests are comparible
+                    min_diff = ((min_time * self.warp) /
+                                (other_min_time * other.warp) - 1.0)
+                    avg_diff = ((avg_time * self.warp) /
+                                (other_avg_time * other.warp) - 1.0)
+                    if hidenoise and abs(min_diff) < 10.0:
+                        min_diff = ''
+                    else:
+                        min_diff = '%+5.1f%%' % (min_diff * PERCENT)
+                    if hidenoise and abs(avg_diff) < 10.0:
+                        avg_diff = ''
+                    else:
+                        avg_diff = '%+5.1f%%' % (avg_diff * PERCENT)
+                else:
+                    # Benchmark or tests are not comparible
+                    min_diff, avg_diff = 'n/a', 'n/a'
+                    tests_compatible = 0
+            print '%30s: %5.0fms %5.0fms %7s %5.0fms %5.0fms %7s' % \
+                  (name,
+                   min_time * MILLI_SECONDS,
+                   other_min_time * MILLI_SECONDS * compare_to.warp / self.warp,
+                   min_diff,
+                   avg_time * MILLI_SECONDS,
+                   other_avg_time * MILLI_SECONDS * compare_to.warp / self.warp,
+                   avg_diff)
+        print '-' * LINE
+
+        # Summarise test results
+        if not benchmarks_compatible or not tests_compatible:
+            min_diff, avg_diff = 'n/a', 'n/a'
+        else:
+            if other_total_min_time != 0.0:
+                min_diff = '%+5.1f%%' % (
+                    ((total_min_time * self.warp) /
+                     (other_total_min_time * compare_to.warp) - 1.0) * PERCENT)
+            else:
+                min_diff = 'n/a'
+            if other_total_avg_time != 0.0:
+                avg_diff = '%+5.1f%%' % (
+                    ((total_avg_time * self.warp) /
+                     (other_total_avg_time * compare_to.warp) - 1.0) * PERCENT)
+            else:
+                avg_diff = 'n/a'
+        print ('Totals:                       '
+               '  %5.0fms %5.0fms %7s %5.0fms %5.0fms %7s' %
+               (total_min_time * MILLI_SECONDS,
+                (other_total_min_time * compare_to.warp/self.warp
+                 * MILLI_SECONDS),
+                min_diff,
+                total_avg_time * MILLI_SECONDS,
+                (other_total_avg_time * compare_to.warp/self.warp
+                 * MILLI_SECONDS),
+                avg_diff
+               ))
+        print
+        print '(this=%s, other=%s)' % (self.name,
+                                       compare_to.name)
+        print
+
+class PyBenchCmdline(Application):
+
+    header = ("PYBENCH - a benchmark test suite for Python "
+              "interpreters/compilers.")
+
+    version = __version__
+
+    debug = _debug
+
+    options = [ArgumentOption('-n',
+                              'number of rounds',
+                              Setup.Number_of_rounds),
+               ArgumentOption('-f',
+                              'save benchmark to file arg',
+                              ''),
+               ArgumentOption('-c',
+                              'compare benchmark with the one in file arg',
+                              ''),
+               ArgumentOption('-s',
+                              'show benchmark in file arg, then exit',
+                              ''),
+               ArgumentOption('-w',
+                              'set warp factor to arg',
+                              Setup.Warp_factor),
+               ArgumentOption('-t',
+                              'run only tests with names matching arg',
+                              ''),
+               ArgumentOption('-C',
+                              'set the number of calibration runs to arg',
+                              CALIBRATION_RUNS),
+               SwitchOption('-d',
+                            'hide noise in comparisons',
+                            0),
+               SwitchOption('-v',
+                            'verbose output (not recommended)',
+                            0),
+               SwitchOption('--with-gc',
+                            'enable garbage collection',
+                            0),
+               SwitchOption('--with-syscheck',
+                            'use default sys check interval',
+                            0),
+               ArgumentOption('--timer',
+                            'use given timer',
+                            TIMER_PLATFORM_DEFAULT),
+               ]
+
+    about = """\
+The normal operation is to run the suite and display the
+results. Use -f to save them for later reuse or comparisons.
+
+Available timers:
+
+   time.time
+   time.clock
+   systimes.processtime
+
+Examples:
+
+python2.1 pybench.py -f p21.pybench
+python2.5 pybench.py -f p25.pybench
+python pybench.py -s p25.pybench -c p21.pybench
+"""
+    copyright = __copyright__
+
+    def main(self):
+
+        rounds = self.values['-n']
+        reportfile = self.values['-f']
+        show_bench = self.values['-s']
+        compare_to = self.values['-c']
+        hidenoise = self.values['-d']
+        warp = int(self.values['-w'])
+        withgc = self.values['--with-gc']
+        limitnames = self.values['-t']
+        if limitnames:
+            if _debug:
+                print '* limiting test names to one with substring "%s"' % \
+                      limitnames
+            limitnames = re.compile(limitnames, re.I)
+        else:
+            limitnames = None
+        verbose = self.verbose
+        withsyscheck = self.values['--with-syscheck']
+        calibration_runs = self.values['-C']
+        timer = self.values['--timer']
+
+        print '-' * LINE
+        print 'PYBENCH %s' % __version__
+        print '-' * LINE
+        print '* using Python %s' % (string.split(sys.version)[0])
+
+        # Switch off garbage collection
+        if not withgc:
+            try:
+                import gc
+            except ImportError:
+                print '* Python version doesn\'t support garbage collection'
+            else:
+                gc.disable()
+                print '* disabled garbage collection'
+
+        # "Disable" sys check interval
+        if not withsyscheck:
+            # Too bad the check interval uses an int instead of a long...
+            value = 2147483647
+            sys.setcheckinterval(value)
+            print '* system check interval set to maximum: %s' % value
+
+        if timer == TIMER_SYSTIMES_PROCESSTIME:
+            import systimes
+            print '* using timer: systimes.processtime (%s)' % \
+                  systimes.SYSTIMES_IMPLEMENTATION
+        else:
+            print '* using timer: %s' % timer
+
+        print
+
+        if compare_to:
+            try:
+                f = open(compare_to,'rb')
+                bench = pickle.load(f)
+                bench.name = compare_to
+                f.close()
+                compare_to = bench
+            except IOError, reason:
+                print '* Error opening/reading file %s: %s' % (
+                    repr(compare_to),
+                    reason)
+                compare_to = None
+
+        if show_bench:
+            try:
+                f = open(show_bench,'rb')
+                bench = pickle.load(f)
+                bench.name = show_bench
+                f.close()
+                bench.print_header()
+                if compare_to:
+                    bench.print_comparison(compare_to,
+                                           hidenoise=hidenoise,
+                                           limitnames=limitnames)
+                else:
+                    bench.print_benchmark(hidenoise=hidenoise,
+                                          limitnames=limitnames)
+            except IOError, reason:
+                print '* Error opening/reading file %s: %s' % (
+                    repr(show_bench),
+                    reason)
+                print
+            return
+
+        if reportfile:
+            print 'Creating benchmark: %s (rounds=%i, warp=%i)' % \
+                  (reportfile, rounds, warp)
+            print
+
+        # Create benchmark object
+        bench = Benchmark(reportfile,
+                          verbose=verbose,
+                          timer=timer,
+                          warp=warp,
+                          calibration_runs=calibration_runs)
+        bench.rounds = rounds
+        bench.load_tests(Setup, limitnames=limitnames)
+        try:
+            bench.calibrate()
+            bench.run()
+        except KeyboardInterrupt:
+            print
+            print '*** KeyboardInterrupt -- Aborting'
+            print
+            return
+        bench.print_header()
+        if compare_to:
+            bench.print_comparison(compare_to,
+                                   hidenoise=hidenoise,
+                                   limitnames=limitnames)
+        else:
+            bench.print_benchmark(hidenoise=hidenoise,
+                                  limitnames=limitnames)
+
+        # Ring bell
+        sys.stderr.write('\007')
+
+        if reportfile:
+            try:
+                f = open(reportfile,'wb')
+                bench.name = reportfile
+                pickle.dump(bench,f)
+                f.close()
+            except IOError, reason:
+                print '* Error opening/writing reportfile'
+            except IOError, reason:
+                print '* Error opening/writing reportfile %s: %s' % (
+                    reportfile,
+                    reason)
+                print
+
+if __name__ == '__main__':
+    PyBenchCmdline()


Property changes on: vendor/Python/current/Tools/pybench/pybench.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/pybench/systimes.py
===================================================================
--- vendor/Python/current/Tools/pybench/systimes.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/pybench/systimes.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,211 @@
+#!/usr/bin/env python
+
+""" systimes() user and system timer implementations for use by
+    pybench.
+
+    This module implements various different strategies for measuring
+    performance timings. It tries to choose the best available method
+    based on the platforma and available tools.
+
+    On Windows, it is recommended to have the Mark Hammond win32
+    package installed. Alternatively, the Thomas Heller ctypes
+    packages can also be used.
+
+    On Unix systems, the standard resource module provides the highest
+    resolution timings. Unfortunately, it is not available on all Unix
+    platforms.
+
+    If no supported timing methods based on process time can be found,
+    the module reverts to the highest resolution wall-clock timer
+    instead. The system time part will then always be 0.0.
+
+    The module exports one public API:
+
+    def systimes():
+
+        Return the current timer values for measuring user and system
+        time as tuple of seconds (user_time, system_time).
+
+    Copyright (c) 2006, Marc-Andre Lemburg (mal at egenix.com). See the
+    documentation for further information on copyrights, or contact
+    the author. All Rights Reserved.
+
+"""
+import time, sys, struct
+
+#
+# Note: Please keep this module compatible to Python 1.5.2.
+#
+# TODOs:
+#
+# * Add ctypes wrapper for new clock_gettime() real-time POSIX APIs;
+#   these will then provide nano-second resolution where available.
+#
+# * Add a function that returns the resolution of systimes()
+#   values, ie. systimesres().
+#
+
+### Choose an implementation
+
+SYSTIMES_IMPLEMENTATION = None
+USE_CTYPES_GETPROCESSTIMES = 'cytpes GetProcessTimes() wrapper'
+USE_WIN32PROCESS_GETPROCESSTIMES = 'win32process.GetProcessTimes()'
+USE_RESOURCE_GETRUSAGE = 'resource.getrusage()'
+USE_PROCESS_TIME_CLOCK = 'time.clock() (process time)'
+USE_WALL_TIME_CLOCK = 'time.clock() (wall-clock)'
+USE_WALL_TIME_TIME = 'time.time() (wall-clock)'
+
+if sys.platform[:3] == 'win':
+    # Windows platform
+    try:
+        import win32process
+    except ImportError:
+        try:
+            import ctypes
+        except ImportError:
+            # Use the wall-clock implementation time.clock(), since this
+            # is the highest resolution clock available on Windows
+            SYSTIMES_IMPLEMENTATION = USE_WALL_TIME_CLOCK
+        else:
+            SYSTIMES_IMPLEMENTATION = USE_CTYPES_GETPROCESSTIMES
+    else:
+        SYSTIMES_IMPLEMENTATION = USE_WIN32PROCESS_GETPROCESSTIMES
+else:
+    # All other platforms
+    try:
+        import resource
+    except ImportError:
+        pass
+    else:
+        SYSTIMES_IMPLEMENTATION = USE_RESOURCE_GETRUSAGE
+
+# Fall-back solution
+if SYSTIMES_IMPLEMENTATION is None:
+    # Check whether we can use time.clock() as approximation
+    # for systimes()
+    start = time.clock()
+    time.sleep(0.1)
+    stop = time.clock()
+    if stop - start < 0.001:
+        # Looks like time.clock() is usable (and measures process
+        # time)
+        SYSTIMES_IMPLEMENTATION = USE_PROCESS_TIME_CLOCK
+    else:
+        # Use wall-clock implementation time.time() since this provides
+        # the highest resolution clock on most systems
+        SYSTIMES_IMPLEMENTATION = USE_WALL_TIME_TIME
+
+### Implementations
+
+def getrusage_systimes():
+    return resource.getrusage(resource.RUSAGE_SELF)[:2]
+
+def process_time_clock_systimes():
+    return (time.clock(), 0.0)
+
+def wall_clock_clock_systimes():
+    return (time.clock(), 0.0)
+
+def wall_clock_time_systimes():
+    return (time.time(), 0.0)
+
+# Number of clock ticks per second for the values returned
+# by GetProcessTimes() on Windows.
+#
+# Note: Ticks returned by GetProcessTimes() are 100ns intervals on
+# Windows XP. However, the process times are only updated with every
+# clock tick and the frequency of these is somewhat lower: depending
+# on the OS version between 10ms and 15ms. Even worse, the process
+# time seems to be allocated to process currently running when the
+# clock interrupt arrives, ie. it is possible that the current time
+# slice gets accounted to a different process.
+
+WIN32_PROCESS_TIMES_TICKS_PER_SECOND = 1e7
+
+def win32process_getprocesstimes_systimes():
+    d = win32process.GetProcessTimes(win32process.GetCurrentProcess())
+    return (d['UserTime'] / WIN32_PROCESS_TIMES_TICKS_PER_SECOND,
+            d['KernelTime'] / WIN32_PROCESS_TIMES_TICKS_PER_SECOND)
+
+def ctypes_getprocesstimes_systimes():
+    creationtime = ctypes.c_ulonglong()
+    exittime = ctypes.c_ulonglong()
+    kerneltime = ctypes.c_ulonglong()
+    usertime = ctypes.c_ulonglong()
+    rc = ctypes.windll.kernel32.GetProcessTimes(
+        ctypes.windll.kernel32.GetCurrentProcess(),
+        ctypes.byref(creationtime),
+        ctypes.byref(exittime),
+        ctypes.byref(kerneltime),
+        ctypes.byref(usertime))
+    if not rc:
+        raise TypeError('GetProcessTimes() returned an error')
+    return (usertime.value / WIN32_PROCESS_TIMES_TICKS_PER_SECOND,
+            kerneltime.value / WIN32_PROCESS_TIMES_TICKS_PER_SECOND)
+
+# Select the default for the systimes() function
+
+if SYSTIMES_IMPLEMENTATION is USE_RESOURCE_GETRUSAGE:
+    systimes = getrusage_systimes
+
+elif SYSTIMES_IMPLEMENTATION is USE_PROCESS_TIME_CLOCK:
+    systimes = process_time_clock_systimes
+
+elif SYSTIMES_IMPLEMENTATION is USE_WALL_TIME_CLOCK:
+    systimes = wall_clock_clock_systimes
+
+elif SYSTIMES_IMPLEMENTATION is USE_WALL_TIME_TIME:
+    systimes = wall_clock_time_systimes
+
+elif SYSTIMES_IMPLEMENTATION is USE_WIN32PROCESS_GETPROCESSTIMES:
+    systimes = win32process_getprocesstimes_systimes
+
+elif SYSTIMES_IMPLEMENTATION is USE_CTYPES_GETPROCESSTIMES:
+    systimes = ctypes_getprocesstimes_systimes
+
+else:
+    raise TypeError('no suitable systimes() implementation found')
+
+def processtime():
+
+    """ Return the total time spent on the process.
+
+        This is the sum of user and system time as returned by
+        systimes().
+
+    """
+    user, system = systimes()
+    return user + system
+
+### Testing
+
+def some_workload():
+    x = 0L
+    for i in xrange(10000000L):
+        x = x + 1L
+
+def test_workload():
+    print 'Testing systimes() under load conditions'
+    t0 = systimes()
+    some_workload()
+    t1 = systimes()
+    print 'before:', t0
+    print 'after:', t1
+    print 'differences:', (t1[0] - t0[0], t1[1] - t0[1])
+    print
+
+def test_idle():
+    print 'Testing systimes() under idle conditions'
+    t0 = systimes()
+    time.sleep(1)
+    t1 = systimes()
+    print 'before:', t0
+    print 'after:', t1
+    print 'differences:', (t1[0] - t0[0], t1[1] - t0[1])
+    print
+
+if __name__ == '__main__':
+    print 'Using %s as timer' % SYSTIMES_IMPLEMENTATION
+    print
+    test_workload()
+    test_idle()

Added: vendor/Python/current/Tools/pynche/ChipViewer.py
===================================================================
--- vendor/Python/current/Tools/pynche/ChipViewer.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/pynche/ChipViewer.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,131 @@
+"""Chip viewer and widget.
+
+In the lower left corner of the main Pynche window, you will see two
+ChipWidgets, one for the selected color and one for the nearest color.  The
+selected color is the actual RGB value expressed as an X11 #COLOR name. The
+nearest color is the named color from the X11 database that is closest to the
+selected color in 3D space.  There may be other colors equally close, but the
+nearest one is the first one found.
+
+Clicking on the nearest color chip selects that named color.
+
+The ChipViewer class includes the entire lower left quandrant; i.e. both the
+selected and nearest ChipWidgets.
+"""
+
+from types import StringType
+from Tkinter import *
+import ColorDB
+
+
+class ChipWidget:
+    _WIDTH = 150
+    _HEIGHT = 80
+
+    def __init__(self,
+                 master = None,
+                 width  = _WIDTH,
+                 height = _HEIGHT,
+                 text   = 'Color',
+                 initialcolor = 'blue',
+                 presscmd   = None,
+                 releasecmd = None):
+        # create the text label
+        self.__label = Label(master, text=text)
+        self.__label.grid(row=0, column=0)
+        # create the color chip, implemented as a frame
+        self.__chip = Frame(master, relief=RAISED, borderwidth=2,
+                            width=width,
+                            height=height,
+                            background=initialcolor)
+        self.__chip.grid(row=1, column=0)
+        # create the color name
+        self.__namevar = StringVar()
+        self.__namevar.set(initialcolor)
+        self.__name = Entry(master, textvariable=self.__namevar,
+                            relief=FLAT, justify=CENTER, state=DISABLED,
+                            font=self.__label['font'])
+        self.__name.grid(row=2, column=0)
+        # create the message area
+        self.__msgvar = StringVar()
+        self.__name = Entry(master, textvariable=self.__msgvar,
+                            relief=FLAT, justify=CENTER, state=DISABLED,
+                            font=self.__label['font'])
+        self.__name.grid(row=3, column=0)
+        # set bindings
+        if presscmd:
+            self.__chip.bind('<ButtonPress-1>', presscmd)
+        if releasecmd:
+            self.__chip.bind('<ButtonRelease-1>', releasecmd)
+
+    def set_color(self, color):
+        self.__chip.config(background=color)
+
+    def get_color(self):
+        return self.__chip['background']
+
+    def set_name(self, colorname):
+        self.__namevar.set(colorname)
+
+    def set_message(self, message):
+        self.__msgvar.set(message)
+
+    def press(self):
+        self.__chip.configure(relief=SUNKEN)
+
+    def release(self):
+        self.__chip.configure(relief=RAISED)
+
+
+
+class ChipViewer:
+    def __init__(self, switchboard, master=None):
+        self.__sb = switchboard
+        self.__frame = Frame(master, relief=RAISED, borderwidth=1)
+        self.__frame.grid(row=3, column=0, ipadx=5, sticky='NSEW')
+        # create the chip that will display the currently selected color
+        # exactly
+        self.__sframe = Frame(self.__frame)
+        self.__sframe.grid(row=0, column=0)
+        self.__selected = ChipWidget(self.__sframe, text='Selected')
+        # create the chip that will display the nearest real X11 color
+        # database color name
+        self.__nframe = Frame(self.__frame)
+        self.__nframe.grid(row=0, column=1)
+        self.__nearest = ChipWidget(self.__nframe, text='Nearest',
+                                    presscmd = self.__buttonpress,
+                                    releasecmd = self.__buttonrelease)
+
+    def update_yourself(self, red, green, blue):
+        # Selected always shows the #rrggbb name of the color, nearest always
+        # shows the name of the nearest color in the database.  BAW: should
+        # an exact match be indicated in some way?
+        #
+        # Always use the #rrggbb style to actually set the color, since we may
+        # not be using X color names (e.g. "web-safe" names)
+        colordb = self.__sb.colordb()
+        rgbtuple = (red, green, blue)
+        rrggbb = ColorDB.triplet_to_rrggbb(rgbtuple)
+        # find the nearest
+        nearest = colordb.nearest(red, green, blue)
+        nearest_tuple = colordb.find_byname(nearest)
+        nearest_rrggbb = ColorDB.triplet_to_rrggbb(nearest_tuple)
+        self.__selected.set_color(rrggbb)
+        self.__nearest.set_color(nearest_rrggbb)
+        # set the name and messages areas
+        self.__selected.set_name(rrggbb)
+        if rrggbb == nearest_rrggbb:
+            self.__selected.set_message(nearest)
+        else:
+            self.__selected.set_message('')
+        self.__nearest.set_name(nearest_rrggbb)
+        self.__nearest.set_message(nearest)
+
+    def __buttonpress(self, event=None):
+        self.__nearest.press()
+
+    def __buttonrelease(self, event=None):
+        self.__nearest.release()
+        rrggbb = self.__nearest.get_color()
+        red, green, blue = ColorDB.rrggbb_to_triplet(rrggbb)
+        self.__sb.update_views(red, green, blue)

Added: vendor/Python/current/Tools/pynche/ColorDB.py
===================================================================
--- vendor/Python/current/Tools/pynche/ColorDB.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/pynche/ColorDB.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,279 @@
+"""Color Database.
+
+This file contains one class, called ColorDB, and several utility functions.
+The class must be instantiated by the get_colordb() function in this file,
+passing it a filename to read a database out of.
+
+The get_colordb() function will try to examine the file to figure out what the
+format of the file is.  If it can't figure out the file format, or it has
+trouble reading the file, None is returned.  You can pass get_colordb() an
+optional filetype argument.
+
+Supporte file types are:
+
+    X_RGB_TXT -- X Consortium rgb.txt format files.  Three columns of numbers
+                 from 0 .. 255 separated by whitespace.  Arbitrary trailing
+                 columns used as the color name.
+
+The utility functions are useful for converting between the various expected
+color formats, and for calculating other color values.
+
+"""
+
+import sys
+import re
+from types import *
+import operator
+
+class BadColor(Exception):
+    pass
+
+DEFAULT_DB = None
+SPACE = ' '
+COMMASPACE = ', '
+
+
+
+# generic class
+class ColorDB:
+    def __init__(self, fp):
+        lineno = 2
+        self.__name = fp.name
+        # Maintain several dictionaries for indexing into the color database.
+        # Note that while Tk supports RGB intensities of 4, 8, 12, or 16 bits,
+        # for now we only support 8 bit intensities.  At least on OpenWindows,
+        # all intensities in the /usr/openwin/lib/rgb.txt file are 8-bit
+        #
+        # key is (red, green, blue) tuple, value is (name, [aliases])
+        self.__byrgb = {}
+        # key is name, value is (red, green, blue)
+        self.__byname = {}
+        # all unique names (non-aliases).  built-on demand
+        self.__allnames = None
+        while 1:
+            line = fp.readline()
+            if not line:
+                break
+            # get this compiled regular expression from derived class
+            mo = self._re.match(line)
+            if not mo:
+                print >> sys.stderr, 'Error in', fp.name, ' line', lineno
+                lineno += 1
+                continue
+            # extract the red, green, blue, and name
+            red, green, blue = self._extractrgb(mo)
+            name = self._extractname(mo)
+            keyname = name.lower()
+            # BAW: for now the `name' is just the first named color with the
+            # rgb values we find.  Later, we might want to make the two word
+            # version the `name', or the CapitalizedVersion, etc.
+            key = (red, green, blue)
+            foundname, aliases = self.__byrgb.get(key, (name, []))
+            if foundname <> name and foundname not in aliases:
+                aliases.append(name)
+            self.__byrgb[key] = (foundname, aliases)
+            # add to byname lookup
+            self.__byname[keyname] = key
+            lineno = lineno + 1
+
+    # override in derived classes
+    def _extractrgb(self, mo):
+        return [int(x) for x in mo.group('red', 'green', 'blue')]
+
+    def _extractname(self, mo):
+        return mo.group('name')
+
+    def filename(self):
+        return self.__name
+
+    def find_byrgb(self, rgbtuple):
+        """Return name for rgbtuple"""
+        try:
+            return self.__byrgb[rgbtuple]
+        except KeyError:
+            raise BadColor(rgbtuple)
+
+    def find_byname(self, name):
+        """Return (red, green, blue) for name"""
+        name = name.lower()
+        try:
+            return self.__byname[name]
+        except KeyError:
+            raise BadColor(name)
+
+    def nearest(self, red, green, blue):
+        """Return the name of color nearest (red, green, blue)"""
+        # BAW: should we use Voronoi diagrams, Delaunay triangulation, or
+        # octree for speeding up the locating of nearest point?  Exhaustive
+        # search is inefficient, but seems fast enough.
+        nearest = -1
+        nearest_name = ''
+        for name, aliases in self.__byrgb.values():
+            r, g, b = self.__byname[name.lower()]
+            rdelta = red - r
+            gdelta = green - g
+            bdelta = blue - b
+            distance = rdelta * rdelta + gdelta * gdelta + bdelta * bdelta
+            if nearest == -1 or distance < nearest:
+                nearest = distance
+                nearest_name = name
+        return nearest_name
+
+    def unique_names(self):
+        # sorted
+        if not self.__allnames:
+            self.__allnames = []
+            for name, aliases in self.__byrgb.values():
+                self.__allnames.append(name)
+            # sort irregardless of case
+            def nocase_cmp(n1, n2):
+                return cmp(n1.lower(), n2.lower())
+            self.__allnames.sort(nocase_cmp)
+        return self.__allnames
+
+    def aliases_of(self, red, green, blue):
+        try:
+            name, aliases = self.__byrgb[(red, green, blue)]
+        except KeyError:
+            raise BadColor((red, green, blue))
+        return [name] + aliases
+
+
+class RGBColorDB(ColorDB):
+    _re = re.compile(
+        '\s*(?P<red>\d+)\s+(?P<green>\d+)\s+(?P<blue>\d+)\s+(?P<name>.*)')
+
+
+class HTML40DB(ColorDB):
+    _re = re.compile('(?P<name>\S+)\s+(?P<hexrgb>#[0-9a-fA-F]{6})')
+
+    def _extractrgb(self, mo):
+        return rrggbb_to_triplet(mo.group('hexrgb'))
+
+class LightlinkDB(HTML40DB):
+    _re = re.compile('(?P<name>(.+))\s+(?P<hexrgb>#[0-9a-fA-F]{6})')
+
+    def _extractname(self, mo):
+        return mo.group('name').strip()
+
+class WebsafeDB(ColorDB):
+    _re = re.compile('(?P<hexrgb>#[0-9a-fA-F]{6})')
+
+    def _extractrgb(self, mo):
+        return rrggbb_to_triplet(mo.group('hexrgb'))
+
+    def _extractname(self, mo):
+        return mo.group('hexrgb').upper()
+
+
+
+# format is a tuple (RE, SCANLINES, CLASS) where RE is a compiled regular
+# expression, SCANLINES is the number of header lines to scan, and CLASS is
+# the class to instantiate if a match is found
+
+FILETYPES = [
+    (re.compile('Xorg'), RGBColorDB),
+    (re.compile('XConsortium'), RGBColorDB),
+    (re.compile('HTML'), HTML40DB),
+    (re.compile('lightlink'), LightlinkDB),
+    (re.compile('Websafe'), WebsafeDB),
+    ]
+
+def get_colordb(file, filetype=None):
+    colordb = None
+    fp = open(file)
+    try:
+        line = fp.readline()
+        if not line:
+            return None
+        # try to determine the type of RGB file it is
+        if filetype is None:
+            filetypes = FILETYPES
+        else:
+            filetypes = [filetype]
+        for typere, class_ in filetypes:
+            mo = typere.search(line)
+            if mo:
+                break
+        else:
+            # no matching type
+            return None
+        # we know the type and the class to grok the type, so suck it in
+        colordb = class_(fp)
+    finally:
+        fp.close()
+    # save a global copy
+    global DEFAULT_DB
+    DEFAULT_DB = colordb
+    return colordb
+
+
+
+_namedict = {}
+
+def rrggbb_to_triplet(color):
+    """Converts a #rrggbb color to the tuple (red, green, blue)."""
+    rgbtuple = _namedict.get(color)
+    if rgbtuple is None:
+        if color[0] <> '#':
+            raise BadColor(color)
+        red = color[1:3]
+        green = color[3:5]
+        blue = color[5:7]
+        rgbtuple = int(red, 16), int(green, 16), int(blue, 16)
+        _namedict[color] = rgbtuple
+    return rgbtuple
+
+
+_tripdict = {}
+def triplet_to_rrggbb(rgbtuple):
+    """Converts a (red, green, blue) tuple to #rrggbb."""
+    global _tripdict
+    hexname = _tripdict.get(rgbtuple)
+    if hexname is None:
+        hexname = '#%02x%02x%02x' % rgbtuple
+        _tripdict[rgbtuple] = hexname
+    return hexname
+
+
+_maxtuple = (256.0,) * 3
+def triplet_to_fractional_rgb(rgbtuple):
+    return map(operator.__div__, rgbtuple, _maxtuple)
+
+
+def triplet_to_brightness(rgbtuple):
+    # return the brightness (grey level) along the scale 0.0==black to
+    # 1.0==white
+    r = 0.299
+    g = 0.587
+    b = 0.114
+    return r*rgbtuple[0] + g*rgbtuple[1] + b*rgbtuple[2]
+
+
+
+if __name__ == '__main__':
+    colordb = get_colordb('/usr/openwin/lib/rgb.txt')
+    if not colordb:
+        print 'No parseable color database found'
+        sys.exit(1)
+    # on my system, this color matches exactly
+    target = 'navy'
+    red, green, blue = rgbtuple = colordb.find_byname(target)
+    print target, ':', red, green, blue, triplet_to_rrggbb(rgbtuple)
+    name, aliases = colordb.find_byrgb(rgbtuple)
+    print 'name:', name, 'aliases:', COMMASPACE.join(aliases)
+    r, g, b = (1, 1, 128)                         # nearest to navy
+    r, g, b = (145, 238, 144)                     # nearest to lightgreen
+    r, g, b = (255, 251, 250)                     # snow
+    print 'finding nearest to', target, '...'
+    import time
+    t0 = time.time()
+    nearest = colordb.nearest(r, g, b)
+    t1 = time.time()
+    print 'found nearest color', nearest, 'in', t1-t0, 'seconds'
+    # dump the database
+    for n in colordb.unique_names():
+        r, g, b = colordb.find_byname(n)
+        aliases = colordb.aliases_of(r, g, b)
+        print '%20s: (%3d/%3d/%3d) == %s' % (n, r, g, b,
+                                             SPACE.join(aliases[1:]))

Added: vendor/Python/current/Tools/pynche/DetailsViewer.py
===================================================================
--- vendor/Python/current/Tools/pynche/DetailsViewer.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/pynche/DetailsViewer.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,273 @@
+"""DetailsViewer class.
+
+This class implements a pure input window which allows you to meticulously
+edit the current color.  You have both mouse control of the color (via the
+buttons along the bottom row), and there are keyboard bindings for each of the
+increment/decrement buttons.
+
+The top three check buttons allow you to specify which of the three color
+variations are tied together when incrementing and decrementing.  Red, green,
+and blue are self evident.  By tying together red and green, you can modify
+the yellow level of the color.  By tying together red and blue, you can modify
+the magenta level of the color.  By tying together green and blue, you can
+modify the cyan level, and by tying all three together, you can modify the
+grey level.
+
+The behavior at the boundaries (0 and 255) are defined by the `At boundary'
+option menu:
+
+    Stop
+        When the increment or decrement would send any of the tied variations
+        out of bounds, the entire delta is discarded.
+
+    Wrap Around
+        When the increment or decrement would send any of the tied variations
+        out of bounds, the out of bounds variation is wrapped around to the
+        other side.  Thus if red were at 238 and 25 were added to it, red
+        would have the value 7.
+
+    Preseve Distance
+        When the increment or decrement would send any of the tied variations
+        out of bounds, all tied variations are wrapped as one, so as to
+        preserve the distance between them.  Thus if green and blue were tied,
+        and green was at 238 while blue was at 223, and an increment of 25
+        were applied, green would be at 15 and blue would be at 0.
+
+    Squash
+        When the increment or decrement would send any of the tied variations
+        out of bounds, the out of bounds variation is set to the ceiling of
+        255 or floor of 0, as appropriate.  In this way, all tied variations
+        are squashed to one edge or the other.
+
+The following key bindings can be used as accelerators.  Note that Pynche can
+fall behind if you hold the key down as a key repeat:
+
+Left arrow == -1
+Right arrow == +1
+
+Control + Left == -10
+Control + Right == 10
+
+Shift + Left == -25
+Shift + Right == +25
+"""
+
+from Tkinter import *
+
+STOP = 'Stop'
+WRAP = 'Wrap Around'
+RATIO = 'Preserve Distance'
+GRAV = 'Squash'
+
+ADDTOVIEW = 'Details Window...'
+
+
+class DetailsViewer:
+    def __init__(self, switchboard, master=None):
+        self.__sb = switchboard
+        optiondb = switchboard.optiondb()
+        self.__red, self.__green, self.__blue = switchboard.current_rgb()
+        # GUI
+        root = self.__root = Toplevel(master, class_='Pynche')
+        root.protocol('WM_DELETE_WINDOW', self.withdraw)
+        root.title('Pynche Details Window')
+        root.iconname('Pynche Details Window')
+        root.bind('<Alt-q>', self.__quit)
+        root.bind('<Alt-Q>', self.__quit)
+        root.bind('<Alt-w>', self.withdraw)
+        root.bind('<Alt-W>', self.withdraw)
+        # accelerators
+        root.bind('<KeyPress-Left>', self.__minus1)
+        root.bind('<KeyPress-Right>', self.__plus1)
+        root.bind('<Control-KeyPress-Left>', self.__minus10)
+        root.bind('<Control-KeyPress-Right>', self.__plus10)
+        root.bind('<Shift-KeyPress-Left>', self.__minus25)
+        root.bind('<Shift-KeyPress-Right>', self.__plus25)
+        #
+        # color ties
+        frame = self.__frame = Frame(root)
+        frame.pack(expand=YES, fill=X)
+        self.__l1 = Label(frame, text='Move Sliders:')
+        self.__l1.grid(row=1, column=0, sticky=E)
+        self.__rvar = IntVar()
+        self.__rvar.set(optiondb.get('RSLIDER', 4))
+        self.__radio1 = Checkbutton(frame, text='Red',
+                                    variable=self.__rvar,
+                                    command=self.__effect,
+                                    onvalue=4, offvalue=0)
+        self.__radio1.grid(row=1, column=1, sticky=W)
+        self.__gvar = IntVar()
+        self.__gvar.set(optiondb.get('GSLIDER', 2))
+        self.__radio2 = Checkbutton(frame, text='Green',
+                                    variable=self.__gvar,
+                                    command=self.__effect,
+                                    onvalue=2, offvalue=0)
+        self.__radio2.grid(row=2, column=1, sticky=W)
+        self.__bvar = IntVar()
+        self.__bvar.set(optiondb.get('BSLIDER', 1))
+        self.__radio3 = Checkbutton(frame, text='Blue',
+                                    variable=self.__bvar,
+                                    command=self.__effect,
+                                    onvalue=1, offvalue=0)
+        self.__radio3.grid(row=3, column=1, sticky=W)
+        self.__l2 = Label(frame)
+        self.__l2.grid(row=4, column=1, sticky=W)
+        self.__effect()
+        #
+        # Boundary behavior
+        self.__l3 = Label(frame, text='At boundary:')
+        self.__l3.grid(row=5, column=0, sticky=E)
+        self.__boundvar = StringVar()
+        self.__boundvar.set(optiondb.get('ATBOUND', STOP))
+        self.__omenu = OptionMenu(frame, self.__boundvar,
+                                  STOP, WRAP, RATIO, GRAV)
+        self.__omenu.grid(row=5, column=1, sticky=W)
+        self.__omenu.configure(width=17)
+        #
+        # Buttons
+        frame = self.__btnframe = Frame(frame)
+        frame.grid(row=0, column=0, columnspan=2, sticky='EW')
+        self.__down25 = Button(frame, text='-25',
+                               command=self.__minus25)
+        self.__down10 = Button(frame, text='-10',
+                               command=self.__minus10)
+        self.__down1 = Button(frame, text='-1',
+                              command=self.__minus1)
+        self.__up1 = Button(frame, text='+1',
+                            command=self.__plus1)
+        self.__up10 = Button(frame, text='+10',
+                             command=self.__plus10)
+        self.__up25 = Button(frame, text='+25',
+                             command=self.__plus25)
+        self.__down25.pack(expand=YES, fill=X, side=LEFT)
+        self.__down10.pack(expand=YES, fill=X, side=LEFT)
+        self.__down1.pack(expand=YES, fill=X, side=LEFT)
+        self.__up1.pack(expand=YES, fill=X, side=LEFT)
+        self.__up10.pack(expand=YES, fill=X, side=LEFT)
+        self.__up25.pack(expand=YES, fill=X, side=LEFT)
+
+    def __effect(self, event=None):
+        tie = self.__rvar.get() + self.__gvar.get() + self.__bvar.get()
+        if tie in (0, 1, 2, 4):
+            text = ''
+        else:
+            text = '(= %s Level)' % {3: 'Cyan',
+                                     5: 'Magenta',
+                                     6: 'Yellow',
+                                     7: 'Grey'}[tie]
+        self.__l2.configure(text=text)
+
+    def __quit(self, event=None):
+        self.__root.quit()
+
+    def withdraw(self, event=None):
+        self.__root.withdraw()
+
+    def deiconify(self, event=None):
+        self.__root.deiconify()
+
+    def __minus25(self, event=None):
+        self.__delta(-25)
+
+    def __minus10(self, event=None):
+        self.__delta(-10)
+
+    def __minus1(self, event=None):
+        self.__delta(-1)
+
+    def __plus1(self, event=None):
+        self.__delta(1)
+
+    def __plus10(self, event=None):
+        self.__delta(10)
+
+    def __plus25(self, event=None):
+        self.__delta(25)
+
+    def __delta(self, delta):
+        tie = []
+        if self.__rvar.get():
+            red = self.__red + delta
+            tie.append(red)
+        else:
+            red = self.__red
+        if self.__gvar.get():
+            green = self.__green + delta
+            tie.append(green)
+        else:
+            green = self.__green
+        if self.__bvar.get():
+            blue = self.__blue + delta
+            tie.append(blue)
+        else:
+            blue = self.__blue
+        # now apply at boundary behavior
+        atbound = self.__boundvar.get()
+        if atbound == STOP:
+            if red < 0 or green < 0 or blue < 0 or \
+               red > 255 or green > 255 or blue > 255:
+                # then
+                red, green, blue = self.__red, self.__green, self.__blue
+        elif atbound == WRAP or (atbound == RATIO and len(tie) < 2):
+            if red < 0:
+                red += 256
+            if green < 0:
+                green += 256
+            if blue < 0:
+                blue += 256
+            if red > 255:
+                red -= 256
+            if green > 255:
+                green -= 256
+            if blue > 255:
+                blue -= 256
+        elif atbound == RATIO:
+            # for when 2 or 3 colors are tied together
+            dir = 0
+            for c in tie:
+                if c < 0:
+                    dir = -1
+                elif c > 255:
+                    dir = 1
+            if dir == -1:
+                delta = max(tie)
+                if self.__rvar.get():
+                    red = red + 255 - delta
+                if self.__gvar.get():
+                    green = green + 255 - delta
+                if self.__bvar.get():
+                    blue = blue + 255 - delta
+            elif dir == 1:
+                delta = min(tie)
+                if self.__rvar.get():
+                    red = red - delta
+                if self.__gvar.get():
+                    green = green - delta
+                if self.__bvar.get():
+                    blue = blue - delta
+        elif atbound == GRAV:
+            if red < 0:
+                red = 0
+            if green < 0:
+                green = 0
+            if blue < 0:
+                blue = 0
+            if red > 255:
+                red = 255
+            if green > 255:
+                green = 255
+            if blue > 255:
+                blue = 255
+        self.__sb.update_views(red, green, blue)
+        self.__root.update_idletasks()
+
+    def update_yourself(self, red, green, blue):
+        self.__red = red
+        self.__green = green
+        self.__blue = blue
+
+    def save_options(self, optiondb):
+        optiondb['RSLIDER'] = self.__rvar.get()
+        optiondb['GSLIDER'] = self.__gvar.get()
+        optiondb['BSLIDER'] = self.__bvar.get()
+        optiondb['ATBOUND'] = self.__boundvar.get()

Added: vendor/Python/current/Tools/pynche/ListViewer.py
===================================================================
--- vendor/Python/current/Tools/pynche/ListViewer.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/pynche/ListViewer.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,175 @@
+"""ListViewer class.
+
+This class implements an input/output view on the color model.  It lists every
+unique color (e.g. unique r/g/b value) found in the color database.  Each
+color is shown by small swatch and primary color name.  Some colors have
+aliases -- more than one name for the same r/g/b value.  These aliases are
+displayed in the small listbox at the bottom of the screen.
+
+Clicking on a color name or swatch selects that color and updates all other
+windows.  When a color is selected in a different viewer, the color list is
+scrolled to the selected color and it is highlighted.  If the selected color
+is an r/g/b value without a name, no scrolling occurs.
+
+You can turn off Update On Click if all you want to see is the alias for a
+given name, without selecting the color.
+"""
+
+from Tkinter import *
+import ColorDB
+
+ADDTOVIEW = 'Color %List Window...'
+
+class ListViewer:
+    def __init__(self, switchboard, master=None):
+        self.__sb = switchboard
+        optiondb = switchboard.optiondb()
+        self.__lastbox = None
+        self.__dontcenter = 0
+        # GUI
+        root = self.__root = Toplevel(master, class_='Pynche')
+        root.protocol('WM_DELETE_WINDOW', self.withdraw)
+        root.title('Pynche Color List')
+        root.iconname('Pynche Color List')
+        root.bind('<Alt-q>', self.__quit)
+        root.bind('<Alt-Q>', self.__quit)
+        root.bind('<Alt-w>', self.withdraw)
+        root.bind('<Alt-W>', self.withdraw)
+        #
+        # create the canvas which holds everything, and its scrollbar
+        #
+        frame = self.__frame = Frame(root)
+        frame.pack()
+        canvas = self.__canvas = Canvas(frame, width=160, height=300,
+                                        borderwidth=2, relief=SUNKEN)
+        self.__scrollbar = Scrollbar(frame)
+        self.__scrollbar.pack(fill=Y, side=RIGHT)
+        canvas.pack(fill=BOTH, expand=1)
+        canvas.configure(yscrollcommand=(self.__scrollbar, 'set'))
+        self.__scrollbar.configure(command=(canvas, 'yview'))
+        self.__populate()
+        #
+        # Update on click
+        self.__uoc = BooleanVar()
+        self.__uoc.set(optiondb.get('UPONCLICK', 1))
+        self.__uocbtn = Checkbutton(root,
+                                    text='Update on Click',
+                                    variable=self.__uoc,
+                                    command=self.__toggleupdate)
+        self.__uocbtn.pack(expand=1, fill=BOTH)
+        #
+        # alias list
+        self.__alabel = Label(root, text='Aliases:')
+        self.__alabel.pack()
+        self.__aliases = Listbox(root, height=5,
+                                 selectmode=BROWSE)
+        self.__aliases.pack(expand=1, fill=BOTH)
+
+    def __populate(self):
+        #
+        # create all the buttons
+        colordb = self.__sb.colordb()
+        canvas = self.__canvas
+        row = 0
+        widest = 0
+        bboxes = self.__bboxes = []
+        for name in colordb.unique_names():
+            exactcolor = ColorDB.triplet_to_rrggbb(colordb.find_byname(name))
+            canvas.create_rectangle(5, row*20 + 5,
+                                    20, row*20 + 20,
+                                    fill=exactcolor)
+            textid = canvas.create_text(25, row*20 + 13,
+                                        text=name,
+                                        anchor=W)
+            x1, y1, textend, y2 = canvas.bbox(textid)
+            boxid = canvas.create_rectangle(3, row*20+3,
+                                            textend+3, row*20 + 23,
+                                            outline='',
+                                            tags=(exactcolor, 'all'))
+            canvas.bind('<ButtonRelease>', self.__onrelease)
+            bboxes.append(boxid)
+            if textend+3 > widest:
+                widest = textend+3
+            row += 1
+        canvheight = (row-1)*20 + 25
+        canvas.config(scrollregion=(0, 0, 150, canvheight))
+        for box in bboxes:
+            x1, y1, x2, y2 = canvas.coords(box)
+            canvas.coords(box, x1, y1, widest, y2)
+
+    def __onrelease(self, event=None):
+        canvas = self.__canvas
+        # find the current box
+        x = canvas.canvasx(event.x)
+        y = canvas.canvasy(event.y)
+        ids = canvas.find_overlapping(x, y, x, y)
+        for boxid in ids:
+            if boxid in self.__bboxes:
+                break
+        else:
+##            print 'No box found!'
+            return
+        tags = self.__canvas.gettags(boxid)
+        for t in tags:
+            if t[0] == '#':
+                break
+        else:
+##            print 'No color tag found!'
+            return
+        red, green, blue = ColorDB.rrggbb_to_triplet(t)
+        self.__dontcenter = 1
+        if self.__uoc.get():
+            self.__sb.update_views(red, green, blue)
+        else:
+            self.update_yourself(red, green, blue)
+            self.__red, self.__green, self.__blue = red, green, blue
+
+    def __toggleupdate(self, event=None):
+        if self.__uoc.get():
+            self.__sb.update_views(self.__red, self.__green, self.__blue)
+
+    def __quit(self, event=None):
+        self.__root.quit()
+
+    def withdraw(self, event=None):
+        self.__root.withdraw()
+
+    def deiconify(self, event=None):
+        self.__root.deiconify()
+
+    def update_yourself(self, red, green, blue):
+        canvas = self.__canvas
+        # turn off the last box
+        if self.__lastbox:
+            canvas.itemconfigure(self.__lastbox, outline='')
+        # turn on the current box
+        colortag = ColorDB.triplet_to_rrggbb((red, green, blue))
+        canvas.itemconfigure(colortag, outline='black')
+        self.__lastbox = colortag
+        # fill the aliases
+        self.__aliases.delete(0, END)
+        try:
+            aliases = self.__sb.colordb().aliases_of(red, green, blue)[1:]
+        except ColorDB.BadColor:
+            self.__aliases.insert(END, '<no matching color>')
+            return
+        if not aliases:
+            self.__aliases.insert(END, '<no aliases>')
+        else:
+            for name in aliases:
+                self.__aliases.insert(END, name)
+        # maybe scroll the canvas so that the item is visible
+        if self.__dontcenter:
+            self.__dontcenter = 0
+        else:
+            ig, ig, ig, y1 = canvas.coords(colortag)
+            ig, ig, ig, y2 = canvas.coords(self.__bboxes[-1])
+            h = int(canvas['height']) * 0.5
+            canvas.yview('moveto', (y1-h) / y2)
+
+    def save_options(self, optiondb):
+        optiondb['UPONCLICK'] = self.__uoc.get()
+
+    def colordb_changed(self, colordb):
+        self.__canvas.delete('all')
+        self.__populate()

Added: vendor/Python/current/Tools/pynche/Main.py
===================================================================
--- vendor/Python/current/Tools/pynche/Main.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/pynche/Main.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,229 @@
+"""Pynche -- The PYthon Natural Color and Hue Editor.
+
+Contact: %(AUTHNAME)s
+Email:   %(AUTHEMAIL)s
+Version: %(__version__)s
+
+Pynche is based largely on a similar color editor I wrote years ago for the
+SunView window system.  That editor was called ICE: the Interactive Color
+Editor.  I'd always wanted to port the editor to X but didn't feel like
+hacking X and C code to do it.  Fast forward many years, to where Python +
+Tkinter provides such a nice programming environment, with enough power, that
+I finally buckled down and implemented it.  I changed the name because these
+days, too many other systems have the acronym `ICE'.
+
+This program currently requires Python 2.2 with Tkinter.
+
+Usage: %(PROGRAM)s [-d file] [-i file] [-X] [-v] [-h] [initialcolor]
+
+Where:
+    --database file
+    -d file
+        Alternate location of a color database file
+
+    --initfile file
+    -i file
+        Alternate location of the initialization file.  This file contains a
+        persistent database of the current Pynche options and color.  This
+        means that Pynche restores its option settings and current color when
+        it restarts, using this file (unless the -X option is used).  The
+        default is ~/.pynche
+
+    --ignore
+    -X
+        Ignore the initialization file when starting up.  Pynche will still
+        write the current option settings to this file when it quits.
+
+    --version
+    -v
+        print the version number and exit
+
+    --help
+    -h
+        print this message
+
+    initialcolor
+        initial color, as a color name or #RRGGBB format
+"""
+
+__version__ = '1.4.1'
+
+import sys
+import os
+import getopt
+import ColorDB
+
+from PyncheWidget import PyncheWidget
+from Switchboard import Switchboard
+from StripViewer import StripViewer
+from ChipViewer import ChipViewer
+from TypeinViewer import TypeinViewer
+
+
+
+PROGRAM = sys.argv[0]
+AUTHNAME = 'Barry Warsaw'
+AUTHEMAIL = 'barry at python.org'
+
+# Default locations of rgb.txt or other textual color database
+RGB_TXT = [
+    # Solaris OpenWindows
+    '/usr/openwin/lib/rgb.txt',
+    # Linux
+    '/usr/lib/X11/rgb.txt',
+    # The X11R6.4 rgb.txt file
+    os.path.join(sys.path[0], 'X/rgb.txt'),
+    # add more here
+    ]
+
+
+
+# Do this because PyncheWidget.py wants to get at the interpolated docstring
+# too, for its Help menu.
+def docstring():
+    return __doc__ % globals()
+
+
+def usage(code, msg=''):
+    print docstring()
+    if msg:
+        print msg
+    sys.exit(code)
+
+
+
+def initial_color(s, colordb):
+    # function called on every color
+    def scan_color(s, colordb=colordb):
+        try:
+            r, g, b = colordb.find_byname(s)
+        except ColorDB.BadColor:
+            try:
+                r, g, b = ColorDB.rrggbb_to_triplet(s)
+            except ColorDB.BadColor:
+                return None, None, None
+        return r, g, b
+    #
+    # First try the passed in color
+    r, g, b = scan_color(s)
+    if r is None:
+        # try the same color with '#' prepended, since some shells require
+        # this to be escaped, which is a pain
+        r, g, b = scan_color('#' + s)
+    if r is None:
+        print 'Bad initial color, using gray50:', s
+        r, g, b = scan_color('gray50')
+    if r is None:
+        usage(1, 'Cannot find an initial color to use')
+        # does not return
+    return r, g, b
+
+
+
+def build(master=None, initialcolor=None, initfile=None, ignore=None,
+          dbfile=None):
+    # create all output widgets
+    s = Switchboard(not ignore and initfile)
+    # defer to the command line chosen color database, falling back to the one
+    # in the .pynche file.
+    if dbfile is None:
+        dbfile = s.optiondb().get('DBFILE')
+    # find a parseable color database
+    colordb = None
+    files = RGB_TXT[:]
+    if dbfile is None:
+        dbfile = files.pop()
+    while colordb is None:
+        try:
+            colordb = ColorDB.get_colordb(dbfile)
+        except (KeyError, IOError):
+            pass
+        if colordb is None:
+            if not files:
+                break
+            dbfile = files.pop(0)
+    if not colordb:
+        usage(1, 'No color database file found, see the -d option.')
+    s.set_colordb(colordb)
+
+    # create the application window decorations
+    app = PyncheWidget(__version__, s, master=master)
+    w = app.window()
+
+    # these built-in viewers live inside the main Pynche window
+    s.add_view(StripViewer(s, w))
+    s.add_view(ChipViewer(s, w))
+    s.add_view(TypeinViewer(s, w))
+
+    # get the initial color as components and set the color on all views.  if
+    # there was no initial color given on the command line, use the one that's
+    # stored in the option database
+    if initialcolor is None:
+        optiondb = s.optiondb()
+        red = optiondb.get('RED')
+        green = optiondb.get('GREEN')
+        blue = optiondb.get('BLUE')
+        # but if there wasn't any stored in the database, use grey50
+        if red is None or blue is None or green is None:
+            red, green, blue = initial_color('grey50', colordb)
+    else:
+        red, green, blue = initial_color(initialcolor, colordb)
+    s.update_views(red, green, blue)
+    return app, s
+
+
+def run(app, s):
+    try:
+        app.start()
+    except KeyboardInterrupt:
+        pass
+
+
+
+def main():
+    try:
+        opts, args = getopt.getopt(
+            sys.argv[1:],
+            'hd:i:Xv',
+            ['database=', 'initfile=', 'ignore', 'help', 'version'])
+    except getopt.error, msg:
+        usage(1, msg)
+
+    if len(args) == 0:
+        initialcolor = None
+    elif len(args) == 1:
+        initialcolor = args[0]
+    else:
+        usage(1)
+
+    ignore = False
+    dbfile = None
+    initfile = os.path.expanduser('~/.pynche')
+    for opt, arg in opts:
+        if opt in ('-h', '--help'):
+            usage(0)
+        elif opt in ('-v', '--version'):
+            print """\
+Pynche -- The PYthon Natural Color and Hue Editor.
+Contact: %(AUTHNAME)s
+Email:   %(AUTHEMAIL)s
+Version: %(__version__)s""" % globals()
+            sys.exit(0)
+        elif opt in ('-d', '--database'):
+            dbfile = arg
+        elif opt in ('-X', '--ignore'):
+            ignore = True
+        elif opt in ('-i', '--initfile'):
+            initfile = arg
+
+    app, sb = build(initialcolor=initialcolor,
+                    initfile=initfile,
+                    ignore=ignore,
+                    dbfile=dbfile)
+    run(app, sb)
+    sb.save_views()
+
+
+
+if __name__ == '__main__':
+    main()

Added: vendor/Python/current/Tools/pynche/PyncheWidget.py
===================================================================
--- vendor/Python/current/Tools/pynche/PyncheWidget.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/pynche/PyncheWidget.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,309 @@
+"""Main Pynche (Pythonically Natural Color and Hue Editor) widget.
+
+This window provides the basic decorations, primarily including the menubar.
+It is used to bring up other windows.
+"""
+
+import sys
+import os
+from Tkinter import *
+import tkMessageBox
+import tkFileDialog
+import ColorDB
+
+# Milliseconds between interrupt checks
+KEEPALIVE_TIMER = 500
+
+
+
+class PyncheWidget:
+    def __init__(self, version, switchboard, master=None, extrapath=[]):
+        self.__sb = switchboard
+        self.__version = version
+        self.__textwin = None
+        self.__listwin = None
+        self.__detailswin = None
+        self.__helpwin = None
+        self.__dialogstate = {}
+        modal = self.__modal = not not master
+        # If a master was given, we are running as a modal dialog servant to
+        # some other application.  We rearrange our UI in this case (there's
+        # no File menu and we get `Okay' and `Cancel' buttons), and we do a
+        # grab_set() to make ourselves modal
+        if modal:
+            self.__tkroot = tkroot = Toplevel(master, class_='Pynche')
+            tkroot.grab_set()
+            tkroot.withdraw()
+        else:
+            # Is there already a default root for Tk, say because we're
+            # running under Guido's IDE? :-) Two conditions say no, either the
+            # import fails or _default_root is None.
+            tkroot = None
+            try:
+                from Tkinter import _default_root
+                tkroot = self.__tkroot = _default_root
+            except ImportError:
+                pass
+            if not tkroot:
+                tkroot = self.__tkroot = Tk(className='Pynche')
+            # but this isn't our top level widget, so make it invisible
+            tkroot.withdraw()
+        # create the menubar
+        menubar = self.__menubar = Menu(tkroot)
+        #
+        # File menu
+        #
+        filemenu = self.__filemenu = Menu(menubar, tearoff=0)
+        filemenu.add_command(label='Load palette...',
+                             command=self.__load,
+                             underline=0)
+        if not modal:
+            filemenu.add_command(label='Quit',
+                                 command=self.__quit,
+                                 accelerator='Alt-Q',
+                                 underline=0)
+        #
+        # View menu
+        #
+        views = make_view_popups(self.__sb, self.__tkroot, extrapath)
+        viewmenu = Menu(menubar, tearoff=0)
+        for v in views:
+            viewmenu.add_command(label=v.menutext(),
+                                 command=v.popup,
+                                 underline=v.underline())
+        #
+        # Help menu
+        #
+        helpmenu = Menu(menubar, name='help', tearoff=0)
+        helpmenu.add_command(label='About Pynche...',
+                             command=self.__popup_about,
+                             underline=0)
+        helpmenu.add_command(label='Help...',
+                             command=self.__popup_usage,
+                             underline=0)
+        #
+        # Tie them all together
+        #
+        menubar.add_cascade(label='File',
+                            menu=filemenu,
+                            underline=0)
+        menubar.add_cascade(label='View',
+                            menu=viewmenu,
+                            underline=0)
+        menubar.add_cascade(label='Help',
+                            menu=helpmenu,
+                            underline=0)
+
+        # now create the top level window
+        root = self.__root = Toplevel(tkroot, class_='Pynche', menu=menubar)
+        root.protocol('WM_DELETE_WINDOW',
+                      modal and self.__bell or self.__quit)
+        root.title('Pynche %s' % version)
+        root.iconname('Pynche')
+        # Only bind accelerators for the File->Quit menu item if running as a
+        # standalone app
+        if not modal:
+            root.bind('<Alt-q>', self.__quit)
+            root.bind('<Alt-Q>', self.__quit)
+        else:
+            # We're a modal dialog so we have a new row of buttons
+            bframe = Frame(root, borderwidth=1, relief=RAISED)
+            bframe.grid(row=4, column=0, columnspan=2,
+                        sticky='EW',
+                        ipady=5)
+            okay = Button(bframe,
+                          text='Okay',
+                          command=self.__okay)
+            okay.pack(side=LEFT, expand=1)
+            cancel = Button(bframe,
+                            text='Cancel',
+                            command=self.__cancel)
+            cancel.pack(side=LEFT, expand=1)
+
+    def __quit(self, event=None):
+        self.__tkroot.quit()
+
+    def __bell(self, event=None):
+        self.__tkroot.bell()
+
+    def __okay(self, event=None):
+        self.__sb.withdraw_views()
+        self.__tkroot.grab_release()
+        self.__quit()
+
+    def __cancel(self, event=None):
+        self.__sb.canceled()
+        self.__okay()
+
+    def __keepalive(self):
+        # Exercise the Python interpreter regularly so keyboard interrupts get
+        # through.
+        self.__tkroot.tk.createtimerhandler(KEEPALIVE_TIMER, self.__keepalive)
+
+    def start(self):
+        if not self.__modal:
+            self.__keepalive()
+        self.__tkroot.mainloop()
+
+    def window(self):
+        return self.__root
+
+    def __popup_about(self, event=None):
+        from Main import __version__
+        tkMessageBox.showinfo('About Pynche ' + __version__,
+                              '''\
+Pynche %s
+The PYthonically Natural
+Color and Hue Editor
+
+For information
+contact: Barry A. Warsaw
+email:   bwarsaw at python.org''' % __version__)
+
+    def __popup_usage(self, event=None):
+        if not self.__helpwin:
+            self.__helpwin = Helpwin(self.__root, self.__quit)
+        self.__helpwin.deiconify()
+
+    def __load(self, event=None):
+        while 1:
+            idir, ifile = os.path.split(self.__sb.colordb().filename())
+            file = tkFileDialog.askopenfilename(
+                filetypes=[('Text files', '*.txt'),
+                           ('All files', '*'),
+                           ],
+                initialdir=idir,
+                initialfile=ifile)
+            if not file:
+                # cancel button
+                return
+            try:
+                colordb = ColorDB.get_colordb(file)
+            except IOError:
+                tkMessageBox.showerror('Read error', '''\
+Could not open file for reading:
+%s''' % file)
+                continue
+            if colordb is None:
+                tkMessageBox.showerror('Unrecognized color file type', '''\
+Unrecognized color file type in file:
+%s''' % file)
+                continue
+            break
+        self.__sb.set_colordb(colordb)
+
+    def withdraw(self):
+        self.__root.withdraw()
+
+    def deiconify(self):
+        self.__root.deiconify()
+
+
+
+class Helpwin:
+    def __init__(self, master, quitfunc):
+        from Main import docstring
+        self.__root = root = Toplevel(master, class_='Pynche')
+        root.protocol('WM_DELETE_WINDOW', self.__withdraw)
+        root.title('Pynche Help Window')
+        root.iconname('Pynche Help Window')
+        root.bind('<Alt-q>', quitfunc)
+        root.bind('<Alt-Q>', quitfunc)
+        root.bind('<Alt-w>', self.__withdraw)
+        root.bind('<Alt-W>', self.__withdraw)
+
+        # more elaborate help is available in the README file
+        readmefile = os.path.join(sys.path[0], 'README')
+        try:
+            fp = None
+            try:
+                fp = open(readmefile)
+                contents = fp.read()
+                # wax the last page, it contains Emacs cruft
+                i = contents.rfind('\f')
+                if i > 0:
+                    contents = contents[:i].rstrip()
+            finally:
+                if fp:
+                    fp.close()
+        except IOError:
+            sys.stderr.write("Couldn't open Pynche's README, "
+                             'using docstring instead.\n')
+            contents = docstring()
+
+        self.__text = text = Text(root, relief=SUNKEN,
+                                  width=80, height=24)
+        self.__text.focus_set()
+        text.insert(0.0, contents)
+        scrollbar = Scrollbar(root)
+        scrollbar.pack(fill=Y, side=RIGHT)
+        text.pack(fill=BOTH, expand=YES)
+        text.configure(yscrollcommand=(scrollbar, 'set'))
+        scrollbar.configure(command=(text, 'yview'))
+
+    def __withdraw(self, event=None):
+        self.__root.withdraw()
+
+    def deiconify(self):
+        self.__root.deiconify()
+
+
+
+class PopupViewer:
+    def __init__(self, module, name, switchboard, root):
+        self.__m = module
+        self.__name = name
+        self.__sb = switchboard
+        self.__root = root
+        self.__menutext = module.ADDTOVIEW
+        # find the underline character
+        underline = module.ADDTOVIEW.find('%')
+        if underline == -1:
+            underline = 0
+        else:
+            self.__menutext = module.ADDTOVIEW.replace('%', '', 1)
+        self.__underline = underline
+        self.__window = None
+
+    def menutext(self):
+        return self.__menutext
+
+    def underline(self):
+        return self.__underline
+
+    def popup(self, event=None):
+        if not self.__window:
+            # class and module must have the same name
+            class_ = getattr(self.__m, self.__name)
+            self.__window = class_(self.__sb, self.__root)
+            self.__sb.add_view(self.__window)
+        self.__window.deiconify()
+
+    def __cmp__(self, other):
+        return cmp(self.__menutext, other.__menutext)
+
+
+def make_view_popups(switchboard, root, extrapath):
+    viewers = []
+    # where we are in the file system
+    dirs = [os.path.dirname(__file__)] + extrapath
+    for dir in dirs:
+        if dir == '':
+            dir = '.'
+        for file in os.listdir(dir):
+            if file[-9:] == 'Viewer.py':
+                name = file[:-3]
+                try:
+                    module = __import__(name)
+                except ImportError:
+                    # Pynche is running from inside a package, so get the
+                    # module using the explicit path.
+                    pkg = __import__('pynche.'+name)
+                    module = getattr(pkg, name)
+                if hasattr(module, 'ADDTOVIEW') and module.ADDTOVIEW:
+                    # this is an external viewer
+                    v = PopupViewer(module, name, switchboard, root)
+                    viewers.append(v)
+    # sort alphabetically
+    viewers.sort()
+    return viewers

Added: vendor/Python/current/Tools/pynche/README
===================================================================
--- vendor/Python/current/Tools/pynche/README	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/pynche/README	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,398 @@
+Pynche - The PYthonically Natural Color and Hue Editor
+
+Contact: Barry A. Warsaw
+Email:   bwarsaw at python.org
+Version: 1.3
+
+Introduction
+
+    Pynche is a color editor based largely on a similar program that I
+    originally wrote back in 1987 for the Sunview window system.  That
+    editor was called ICE, the Interactive Color Editor.  I'd always
+    wanted to port this program to X but didn't feel like hacking X
+    and C code to do it.  Fast forward many years, to where Python +
+    Tkinter provides such a nice programming environment, with enough
+    power, that I finally buckled down and re-implemented it.  I
+    changed the name because these days, too many other systems have
+    the acronym `ICE'.
+
+    Pynche should work with any variant of Python after 1.5.2
+    (e.g. 2.0.1 and 2.1.1), using Tk 8.0.x.  It's been tested on
+    Solaris 2.6, Windows NT 4, and various Linux distros.  You'll want
+    to be sure to have at least Tk 8.0.3 for Windows.  Also, Pynche is
+    very colormap intensive, so it doesn't work very well on 8-bit
+    graphics cards; 24bit+ graphics cards are so cheap these days,
+    I'll probably never "fix" that.
+
+    Pynche must find a text database of colors names in order to
+    provide `nearest' color matching.  Pynche is distributed with an
+    rgb.txt file from the X11R6.4 distribution for this reason, along
+    with other "Web related" database (see below).  You can use a
+    different file with the -d option.  The file xlicense.txt contains
+    the license only for rgb.txt and both files are in the X/
+    subdirectory.
+
+    Pynche is pronounced: Pin'-chee
+
+
+Running Standalone
+
+    On Unix, start it by running the `pynche' script.  On Windows, run
+    pynche.pyw to inhibit the console window.  When run from the
+    command line, the following options are recognized:
+
+    --database file
+    -d file
+        Alternate location of the color database file.  Without this
+        option, the first valid file found will be used (see below).
+
+    --initfile file
+    -i file
+        Alternate location of the persistent initialization file.  See 
+        the section on Persistency below.
+
+    --ignore
+    -X
+        Ignore the persistent initialization file when starting up.
+        Pynche will still write the current option settings to the
+        persistent init file when it quits.
+
+    --help
+    -h
+        Print the help message.
+
+    initialcolor
+        a Tk color name or #rrggbb color spec to be used as the
+        initially selected color.  This overrides any color saved in
+        the persistent init file.  Since `#' needs to be escaped in
+        many shells, it is optional in the spec (e.g. #45dd1f is the
+        same as 45dd1f).
+
+
+Running as a Modal Dialog
+
+    Pynche can be run as a modal dialog, inside another application,
+    say as a general color chooser.  In fact, Grail 0.6 uses Pynche
+    and a future version of IDLE may as well.  Pynche supports the API
+    implemented by the Tkinter standard tkColorChooser module, with a
+    few changes as described below.  By importing pyColorChooser from
+    the Pynche package, you can run
+
+        pyColorChooser.askcolor()
+
+    which will popup Pynche as a modal dialog, and return the selected 
+    color.
+
+    There are some UI differences when running as a modal
+    vs. standalone.  When running as a modal, there is no "Quit" menu
+    item under the "File" menu.  Instead there are "Okay" and "Cancel"
+    buttons.
+
+    When "Okay" is hit, askcolor() returns the tuple
+
+        ((r, g, b), "name")
+
+    where r, g, and b are red, green, and blue color values
+    respectively (in the range 0 to 255).  "name" will be a color name
+    from the color database if there is an exact match, otherwise it
+    will be an X11 color spec of the form "#rrggbb".  Note that this
+    is different than tkColorChooser, which doesn't know anything
+    about color names.
+
+    askcolor() supports the following optional keyword arguments:
+
+        color
+            the color to set as the initial selected color
+
+        master[*]
+            the master window to use as the parent of the modal
+            dialog.  Without this argument, pyColorChooser will create 
+            its own Tkinter.Tk instance as the master.  This may not
+            be what you want.
+
+        databasefile
+            similar to the --database option, the value must be a
+            file name
+
+        initfile[*]
+            similar to the --initfile option, the value must be a
+            file name
+
+        ignore[*]
+            similar to the --ignore flag, the value is a boolean
+
+        wantspec
+            When this is true, the "name" field in the return tuple
+            will always be a color spec of the form "#rrggbb".  It
+            will not return a color name even if there is a match;
+            this is so pyColorChooser can exactly match the API of
+            tkColorChooser.
+
+        [*] these arguments must be specified the first time
+        askcolor() is used and cannot be changed on subsequent calls.
+
+
+The Colorstrip Window
+
+    The top part of the main Pynche window contains the "variation
+    strips".  Each strip contains a number of "color chips".  The
+    strips always indicate the currently selected color by a highlight
+    rectangle around the selected color chip, with an arrow pointing
+    to the chip.  Each arrow has an associated number giving you the
+    color value along the variation's axis.  Each variation strip
+    shows you the colors that are reachable from the selected color by
+    varying just one axis of the color solid.
+
+    For example, when the selected color is (in Red/Green/Blue
+    notation) 127/127/127, the Red Variations strip shows you every
+    color in the range 0/127/127 to 255/127/127.  Similarly for the
+    green and blue axes.  You can select any color by clicking on its
+    chip.  This will update the highlight rectangle and the arrow, as
+    well as other displays in Pynche.
+
+    Click on "Update while dragging" if you want Pynche to update the
+    selected color while you drag along any variation strip (this will
+    be a bit slower).  Click on "Hexadecimal" to display the arrow
+    numbers in hex.
+
+    There are also two shortcut buttons in this window, which
+    auto-select Black (0/0/0) and White (255/255/255).
+
+
+The Proof Window
+
+    In the lower left corner of the main window you see two larger
+    color chips.  The Selected chip shows you a larger version of the
+    color selected in the variation strips, along with its X11 color
+    specification.  The Nearest chip shows you the closest color in
+    the X11 database to the selected color, giving its X11 color
+    specification, and below that, its X11 color name.  When the
+    Selected chip color exactly matches the Nearest chip color, you
+    will see the color name appear below the color specification for
+    the Selected chip.
+    
+    Clicking on the Nearest color chip selects that color.  Color
+    distance is calculated in the 3D space of the RGB color solid and
+    if more than one color name is the same distance from the selected
+    color, the first one found will be chosen.
+
+    Note that there may be more than one X11 color name for the same
+    RGB value.  In that case, the first one found in the text database
+    is designated the "primary" name, and this is shown under the
+    Nearest chip.  The other names are "aliases" and they are visible
+    in the Color List Window (see below).
+
+    Both the color specifications and color names are selectable for
+    copying and pasting into another window.
+
+
+The Type-in Window
+
+    At the lower right of the main window are three entry fields.
+    Here you can type numeric values for any of the three color axes.
+    Legal values are between 0 and 255, and these fields do not allow
+    you to enter illegal values.  You must hit Enter or Tab to select
+    the new color.
+
+    Click on "Update while typing" if you want Pynche to select the
+    color on every keystroke (well, every one that produces a legal
+    value!)  Click on "Hexadecimal" to display and enter color values
+    in hex.
+
+
+Other Views
+
+    There are three secondary windows which are not displayed by
+    default.  You can bring these up via the "View" menu on the main
+    Pynche window.
+
+
+The Text Window
+
+    The "Text Window" allows you to see what effects various colors
+    have on the standard Tk text widget elements.  In the upper part
+    of the window is a plain Tk text widget and here you can edit the
+    text, select a region of text, etc.  Below this is a button "Track
+    color changes".  When this is turned on, any colors selected in
+    the other windows will change the text widget element specified in
+    the radio buttons below.  When this is turned off, text widget
+    elements are not affected by color selection.
+
+    You can choose which element gets changed by color selection by
+    clicking on one of the radio buttons in the bottom part of this
+    window.  Text foreground and background affect the text in the
+    upper part of the window.  Selection foreground and background
+    affect the colors of the primary selection which is what you see
+    when you click the middle button (depending on window system) and
+    drag it through some text.
+
+    The Insertion is the insertion cursor in the text window, where
+    new text will be inserted as you type.  The insertion cursor only
+    has a background.
+
+
+The Color List Window
+
+    The "Color List" window shows every named color in the color name
+    database (this window may take a while to come up).  In the upper
+    part of the window you see a scrolling list of all the color names
+    in the database, in alphabetical order.  Click on any color to
+    select it.  In the bottom part of the window is displayed any
+    aliases for the selected color (those color names that have the
+    same RGB value, but were found later in the text database).  For
+    example, find the color "Black" and you'll see that its aliases
+    are "gray0" and "grey0".
+
+    If the color has no aliases you'll see "<no aliases>" here.  If you
+    just want to see if a color has an alias, and do not want to select a
+    color when you click on it, turn off "Update on Click".
+
+    Note that the color list is always updated when a color is selected
+    from the main window.  There's no way to turn this feature off.  If
+    the selected color has no matching color name you'll see
+    "<no matching color>" in the Aliases window.
+
+
+The Details Window
+
+    The "Details" window gives you more control over color selection
+    than just clicking on a color chip in the main window.  The row of
+    buttons along the top apply the specified increment and decrement
+    amounts to the selected color.  These delta amounts are applied to
+    the variation strips specified by the check boxes labeled "Move
+    Sliders".  Thus if just Red and Green are selected, hitting -10
+    will subtract 10 from the color value along the red and green
+    variation only.  Note the message under the checkboxes; this
+    indicates the primary color level being changed when more than one
+    slider is tied together.  For example, if Red and Green are
+    selected, you will be changing the Yellow level of the selected
+    color.
+
+    The "At Boundary" behavior determines what happens when any color
+    variation hits either the lower or upper boundaries (0 or 255) as
+    a result of clicking on the top row buttons:
+
+    Stop
+        When the increment or decrement would send any of the tied
+        variations out of bounds, the entire delta is discarded.
+
+    Wrap Around
+        When the increment or decrement would send any of the tied
+        variations out of bounds, the out of bounds value is wrapped
+        around to the other side.  Thus if red were at 238 and +25
+        were clicked, red would have the value 7.
+
+    Preserve Distance
+        When the increment or decrement would send any of the tied
+        variations out of bounds, all tied variations are wrapped as
+        one, so as to preserve the distance between them.  Thus if
+        green and blue were tied, and green was at 238 while blue was
+        at 223, and +25 were clicked, green would be at 15 and blue
+        would be at 0.
+
+    Squash
+        When the increment or decrement would send any of the tied
+        variations out of bounds, the out of bounds variation is set
+        to the ceiling of 255 or floor of 0, as appropriate.  In this
+        way, all tied variations are squashed to one edge or the
+        other.
+
+    The top row buttons have the following keyboard accelerators:
+
+    -25 == Shift Left Arrow
+    -10 == Control Left Arrow
+     -1 == Left Arrow
+     +1 == Right Arrow
+    +10 == Control Right Arrow
+    +25 == Shift Right Arrow
+
+
+Keyboard Accelerators
+
+    Alt-w in any secondary window dismisses the window.  In the main
+    window it exits Pynche (except when running as a modal).
+
+    Alt-q in any window exits Pynche (except when running as a modal).
+
+
+Persistency
+
+    Pynche remembers various settings of options and colors between
+    invocations, storing these values in a `persistent initialization
+    file'.  The actual location of this file is specified by the
+    --initfile option (see above), and defaults to ~/.pynche.
+
+    When Pynche exits, it saves these values in the init file, and
+    re-reads them when it starts up.  There is no locking on this
+    file, so if you run multiple instances of Pynche at a time, you
+    may clobber the init file.
+
+    The actual options stored include
+
+    - the currently selected color
+
+    - all settings of checkbox and radio button options in all windows
+
+    - the contents of the text window, the current text selection and
+      insertion point, and all current text widget element color
+      settings.
+
+    - the name of the color database file (but not its contents)
+
+    You can inhibit Pynche from reading the init file by supplying the
+    --ignore option on the command line.  However, you cannot suppress
+    the storing of the settings in the init file on Pynche exit.  If
+    you really want to do this, use /dev/null as the init file, using
+    --initfile.
+
+
+Color Name Database Files
+
+    Pynche uses a color name database file to calculate the nearest
+    color to the selected color, and to display in the Color List
+    view.  Several files are distributed with Pynche, described
+    below.  By default, the X11 color name database file is selected.
+    Other files:
+
+    html40colors.txt -- the HTML 4.0 guaranteed color names
+
+    websafe.txt -- the 216 "Web-safe" colors that Netscape and MSIE
+    guarantee will not be dithered.  These are specified in #rrggbb
+    format for both values and names
+
+    webcolors.txt -- The 140 color names that Tim Peters and his
+    sister say NS and MSIE both understand (with some controversy over 
+    AliceBlue).
+
+    namedcolors.txt -- an alternative set of Netscape colors.
+
+    You can switch between files by choosing "Load palette..." from
+    the "File" menu.  This brings up a standard Tk file dialog.
+    Choose the file you want and then click "Ok".  If Pynche
+    understands the format in this file, it will load the database and 
+    update the appropriate windows.  If not, it will bring up an error 
+    dialog.
+
+
+To Do
+
+    Here's a brief list of things I want to do (some mythical day):
+
+    - Better support for resizing the top level windows
+
+    - More output views, e.g. color solids
+
+    - Have the notion of a `last color selected'; this may require a
+      new output view
+
+    - Support setting the font in the text view
+
+    - Support distutils setup.py for installation
+
+    I'm open to suggestions!
+
+
+
+Local Variables:
+indent-tabs-mode: nil
+End:

Added: vendor/Python/current/Tools/pynche/StripViewer.py
===================================================================
--- vendor/Python/current/Tools/pynche/StripViewer.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/pynche/StripViewer.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,433 @@
+"""Strip viewer and related widgets.
+
+The classes in this file implement the StripViewer shown in the top two thirds
+of the main Pynche window.  It consists of three StripWidgets which display
+the variations in red, green, and blue respectively of the currently selected
+r/g/b color value.
+
+Each StripWidget shows the color variations that are reachable by varying an
+axis of the currently selected color.  So for example, if the color is
+
+  (R,G,B)=(127,163,196)
+
+then the Red variations show colors from (0,163,196) to (255,163,196), the
+Green variations show colors from (127,0,196) to (127,255,196), and the Blue
+variations show colors from (127,163,0) to (127,163,255).
+
+The selected color is always visible in all three StripWidgets, and in fact
+each StripWidget highlights the selected color, and has an arrow pointing to
+the selected chip, which includes the value along that particular axis.
+
+Clicking on any chip in any StripWidget selects that color, and updates all
+arrows and other windows.  By toggling on Update while dragging, Pynche will
+select the color under the cursor while you drag it, but be forewarned that
+this can be slow.
+"""
+
+from Tkinter import *
+import ColorDB
+
+# Load this script into the Tcl interpreter and call it in
+# StripWidget.set_color().  This is about as fast as it can be with the
+# current _tkinter.c interface, which doesn't support Tcl Objects.
+TCLPROC = '''\
+proc setcolor {canv colors} {
+    set i 1
+    foreach c $colors {
+        $canv itemconfigure $i -fill $c -outline $c
+        incr i
+    }
+}
+'''
+
+# Tcl event types
+BTNDOWN = 4
+BTNUP = 5
+BTNDRAG = 6
+
+SPACE = ' '
+
+
+
+def constant(numchips):
+    step = 255.0 / (numchips - 1)
+    start = 0.0
+    seq = []
+    while numchips > 0:
+        seq.append(int(start))
+        start = start + step
+        numchips = numchips - 1
+    return seq
+
+# red variations, green+blue = cyan constant
+def constant_red_generator(numchips, red, green, blue):
+    seq = constant(numchips)
+    return map(None, [red] * numchips, seq, seq)
+
+# green variations, red+blue = magenta constant
+def constant_green_generator(numchips, red, green, blue):
+    seq = constant(numchips)
+    return map(None, seq, [green] * numchips, seq)
+
+# blue variations, red+green = yellow constant
+def constant_blue_generator(numchips, red, green, blue):
+    seq = constant(numchips)
+    return map(None, seq, seq, [blue] * numchips)
+
+# red variations, green+blue = cyan constant
+def constant_cyan_generator(numchips, red, green, blue):
+    seq = constant(numchips)
+    return map(None, seq, [green] * numchips, [blue] * numchips)
+
+# green variations, red+blue = magenta constant
+def constant_magenta_generator(numchips, red, green, blue):
+    seq = constant(numchips)
+    return map(None, [red] * numchips, seq, [blue] * numchips)
+
+# blue variations, red+green = yellow constant
+def constant_yellow_generator(numchips, red, green, blue):
+    seq = constant(numchips)
+    return map(None, [red] * numchips, [green] * numchips, seq)
+
+
+
+class LeftArrow:
+    _ARROWWIDTH = 30
+    _ARROWHEIGHT = 15
+    _YOFFSET = 13
+    _TEXTYOFFSET = 1
+    _TAG = ('leftarrow',)
+
+    def __init__(self, canvas, x):
+        self._canvas = canvas
+        self.__arrow, self.__text = self._create(x)
+        self.move_to(x)
+
+    def _create(self, x):
+        arrow = self._canvas.create_line(
+            x, self._ARROWHEIGHT + self._YOFFSET,
+            x, self._YOFFSET,
+            x + self._ARROWWIDTH, self._YOFFSET,
+            arrow='first',
+            width=3.0,
+            tags=self._TAG)
+        text = self._canvas.create_text(
+            x + self._ARROWWIDTH + 13,
+            self._ARROWHEIGHT - self._TEXTYOFFSET,
+            tags=self._TAG,
+            text='128')
+        return arrow, text
+
+    def _x(self):
+        coords = self._canvas.coords(self._TAG)
+        assert coords
+        return coords[0]
+
+    def move_to(self, x):
+        deltax = x - self._x()
+        self._canvas.move(self._TAG, deltax, 0)
+
+    def set_text(self, text):
+        self._canvas.itemconfigure(self.__text, text=text)
+
+
+class RightArrow(LeftArrow):
+    _TAG = ('rightarrow',)
+
+    def _create(self, x):
+        arrow = self._canvas.create_line(
+            x, self._YOFFSET,
+            x + self._ARROWWIDTH, self._YOFFSET,
+            x + self._ARROWWIDTH, self._ARROWHEIGHT + self._YOFFSET,
+            arrow='last',
+            width=3.0,
+            tags=self._TAG)
+        text = self._canvas.create_text(
+            x - self._ARROWWIDTH + 15,            # BAW: kludge
+            self._ARROWHEIGHT - self._TEXTYOFFSET,
+            justify=RIGHT,
+            text='128',
+            tags=self._TAG)
+        return arrow, text
+
+    def _x(self):
+        coords = self._canvas.coords(self._TAG)
+        assert coords
+        return coords[0] + self._ARROWWIDTH
+
+
+
+class StripWidget:
+    _CHIPHEIGHT = 50
+    _CHIPWIDTH = 10
+    _NUMCHIPS = 40
+
+    def __init__(self, switchboard,
+                 master     = None,
+                 chipwidth  = _CHIPWIDTH,
+                 chipheight = _CHIPHEIGHT,
+                 numchips   = _NUMCHIPS,
+                 generator  = None,
+                 axis       = None,
+                 label      = '',
+                 uwdvar     = None,
+                 hexvar     = None):
+        # instance variables
+        self.__generator = generator
+        self.__axis = axis
+        self.__numchips = numchips
+        assert self.__axis in (0, 1, 2)
+        self.__uwd = uwdvar
+        self.__hexp = hexvar
+        # the last chip selected
+        self.__lastchip = None
+        self.__sb = switchboard
+
+        canvaswidth = numchips * (chipwidth + 1)
+        canvasheight = chipheight + 43            # BAW: Kludge
+
+        # create the canvas and pack it
+        canvas = self.__canvas = Canvas(master,
+                                        width=canvaswidth,
+                                        height=canvasheight,
+##                                        borderwidth=2,
+##                                        relief=GROOVE
+                                        )
+
+        canvas.pack()
+        canvas.bind('<ButtonPress-1>', self.__select_chip)
+        canvas.bind('<ButtonRelease-1>', self.__select_chip)
+        canvas.bind('<B1-Motion>', self.__select_chip)
+
+        # Load a proc into the Tcl interpreter.  This is used in the
+        # set_color() method to speed up setting the chip colors.
+        canvas.tk.eval(TCLPROC)
+
+        # create the color strip
+        chips = self.__chips = []
+        x = 1
+        y = 30
+        tags = ('chip',)
+        for c in range(self.__numchips):
+            color = 'grey'
+            canvas.create_rectangle(
+                x, y, x+chipwidth, y+chipheight,
+                fill=color, outline=color,
+                tags=tags)
+            x = x + chipwidth + 1                 # for outline
+            chips.append(color)
+
+        # create the strip label
+        self.__label = canvas.create_text(
+            3, y + chipheight + 8,
+            text=label,
+            anchor=W)
+
+        # create the arrow and text item
+        chipx = self.__arrow_x(0)
+        self.__leftarrow = LeftArrow(canvas, chipx)
+
+        chipx = self.__arrow_x(len(chips) - 1)
+        self.__rightarrow = RightArrow(canvas, chipx)
+
+    def __arrow_x(self, chipnum):
+        coords = self.__canvas.coords(chipnum+1)
+        assert coords
+        x0, y0, x1, y1 = coords
+        return (x1 + x0) / 2.0
+
+    # Invoked when one of the chips is clicked.  This should just tell the
+    # switchboard to set the color on all the output components
+    def __select_chip(self, event=None):
+        x = event.x
+        y = event.y
+        canvas = self.__canvas
+        chip = canvas.find_overlapping(x, y, x, y)
+        if chip and (1 <= chip[0] <= self.__numchips):
+            color = self.__chips[chip[0]-1]
+            red, green, blue = ColorDB.rrggbb_to_triplet(color)
+            etype = int(event.type)
+            if (etype == BTNUP or self.__uwd.get()):
+                # update everyone
+                self.__sb.update_views(red, green, blue)
+            else:
+                # just track the arrows
+                self.__trackarrow(chip[0], (red, green, blue))
+
+    def __trackarrow(self, chip, rgbtuple):
+        # invert the last chip
+        if self.__lastchip is not None:
+            color = self.__canvas.itemcget(self.__lastchip, 'fill')
+            self.__canvas.itemconfigure(self.__lastchip, outline=color)
+        self.__lastchip = chip
+        # get the arrow's text
+        coloraxis = rgbtuple[self.__axis]
+        if self.__hexp.get():
+            # hex
+            text = hex(coloraxis)
+        else:
+            # decimal
+            text = repr(coloraxis)
+        # move the arrow, and set its text
+        if coloraxis <= 128:
+            # use the left arrow
+            self.__leftarrow.set_text(text)
+            self.__leftarrow.move_to(self.__arrow_x(chip-1))
+            self.__rightarrow.move_to(-100)
+        else:
+            # use the right arrow
+            self.__rightarrow.set_text(text)
+            self.__rightarrow.move_to(self.__arrow_x(chip-1))
+            self.__leftarrow.move_to(-100)
+        # and set the chip's outline
+        brightness = ColorDB.triplet_to_brightness(rgbtuple)
+        if brightness <= 128:
+            outline = 'white'
+        else:
+            outline = 'black'
+        self.__canvas.itemconfigure(chip, outline=outline)
+
+
+    def update_yourself(self, red, green, blue):
+        assert self.__generator
+        i = 1
+        chip = 0
+        chips = self.__chips = []
+        tk = self.__canvas.tk
+        # get the red, green, and blue components for all chips
+        for t in self.__generator(self.__numchips, red, green, blue):
+            rrggbb = ColorDB.triplet_to_rrggbb(t)
+            chips.append(rrggbb)
+            tred, tgreen, tblue = t
+            if tred <= red and tgreen <= green and tblue <= blue:
+                chip = i
+            i = i + 1
+        # call the raw tcl script
+        colors = SPACE.join(chips)
+        tk.eval('setcolor %s {%s}' % (self.__canvas._w, colors))
+        # move the arrows around
+        self.__trackarrow(chip, (red, green, blue))
+
+    def set(self, label, generator):
+        self.__canvas.itemconfigure(self.__label, text=label)
+        self.__generator = generator
+
+
+class StripViewer:
+    def __init__(self, switchboard, master=None):
+        self.__sb = switchboard
+        optiondb = switchboard.optiondb()
+        # create a frame inside the master.
+        frame = Frame(master, relief=RAISED, borderwidth=1)
+        frame.grid(row=1, column=0, columnspan=2, sticky='NSEW')
+        # create the options to be used later
+        uwd = self.__uwdvar = BooleanVar()
+        uwd.set(optiondb.get('UPWHILEDRAG', 0))
+        hexp = self.__hexpvar = BooleanVar()
+        hexp.set(optiondb.get('HEXSTRIP', 0))
+        # create the red, green, blue strips inside their own frame
+        frame1 = Frame(frame)
+        frame1.pack(expand=YES, fill=BOTH)
+        self.__reds = StripWidget(switchboard, frame1,
+                                  generator=constant_cyan_generator,
+                                  axis=0,
+                                  label='Red Variations',
+                                  uwdvar=uwd, hexvar=hexp)
+
+        self.__greens = StripWidget(switchboard, frame1,
+                                    generator=constant_magenta_generator,
+                                    axis=1,
+                                    label='Green Variations',
+                                    uwdvar=uwd, hexvar=hexp)
+
+        self.__blues = StripWidget(switchboard, frame1,
+                                   generator=constant_yellow_generator,
+                                   axis=2,
+                                   label='Blue Variations',
+                                   uwdvar=uwd, hexvar=hexp)
+
+        # create a frame to contain the controls
+        frame2 = Frame(frame)
+        frame2.pack(expand=YES, fill=BOTH)
+        frame2.columnconfigure(0, weight=20)
+        frame2.columnconfigure(2, weight=20)
+
+        padx = 8
+
+        # create the black button
+        blackbtn = Button(frame2,
+                          text='Black',
+                          command=self.__toblack)
+        blackbtn.grid(row=0, column=0, rowspan=2, sticky=W, padx=padx)
+
+        # create the controls
+        uwdbtn = Checkbutton(frame2,
+                             text='Update while dragging',
+                             variable=uwd)
+        uwdbtn.grid(row=0, column=1, sticky=W)
+        hexbtn = Checkbutton(frame2,
+                             text='Hexadecimal',
+                             variable=hexp,
+                             command=self.__togglehex)
+        hexbtn.grid(row=1, column=1, sticky=W)
+
+        # XXX: ignore this feature for now; it doesn't work quite right yet
+
+##        gentypevar = self.__gentypevar = IntVar()
+##        self.__variations = Radiobutton(frame,
+##                                        text='Variations',
+##                                        variable=gentypevar,
+##                                        value=0,
+##                                        command=self.__togglegentype)
+##        self.__variations.grid(row=0, column=1, sticky=W)
+##        self.__constants = Radiobutton(frame,
+##                                       text='Constants',
+##                                       variable=gentypevar,
+##                                       value=1,
+##                                       command=self.__togglegentype)
+##        self.__constants.grid(row=1, column=1, sticky=W)
+
+        # create the white button
+        whitebtn = Button(frame2,
+                          text='White',
+                          command=self.__towhite)
+        whitebtn.grid(row=0, column=2, rowspan=2, sticky=E, padx=padx)
+
+    def update_yourself(self, red, green, blue):
+        self.__reds.update_yourself(red, green, blue)
+        self.__greens.update_yourself(red, green, blue)
+        self.__blues.update_yourself(red, green, blue)
+
+    def __togglehex(self, event=None):
+        red, green, blue = self.__sb.current_rgb()
+        self.update_yourself(red, green, blue)
+
+##    def __togglegentype(self, event=None):
+##        which = self.__gentypevar.get()
+##        if which == 0:
+##            self.__reds.set(label='Red Variations',
+##                            generator=constant_cyan_generator)
+##            self.__greens.set(label='Green Variations',
+##                              generator=constant_magenta_generator)
+##            self.__blues.set(label='Blue Variations',
+##                             generator=constant_yellow_generator)
+##        elif which == 1:
+##            self.__reds.set(label='Red Constant',
+##                            generator=constant_red_generator)
+##            self.__greens.set(label='Green Constant',
+##                              generator=constant_green_generator)
+##            self.__blues.set(label='Blue Constant',
+##                             generator=constant_blue_generator)
+##        else:
+##            assert 0
+##        self.__sb.update_views_current()
+
+    def __toblack(self, event=None):
+        self.__sb.update_views(0, 0, 0)
+
+    def __towhite(self, event=None):
+        self.__sb.update_views(255, 255, 255)
+
+    def save_options(self, optiondb):
+        optiondb['UPWHILEDRAG'] = self.__uwdvar.get()
+        optiondb['HEXSTRIP'] = self.__hexpvar.get()

Added: vendor/Python/current/Tools/pynche/Switchboard.py
===================================================================
--- vendor/Python/current/Tools/pynche/Switchboard.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/pynche/Switchboard.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,139 @@
+"""Switchboard class.
+
+This class is used to coordinate updates among all Viewers.  Every Viewer must
+conform to the following interface:
+
+    - it must include a method called update_yourself() which takes three
+      arguments; the red, green, and blue values of the selected color.
+
+    - When a Viewer selects a color and wishes to update all other Views, it
+      should call update_views() on the Switchboard object.  Note that the
+      Viewer typically does *not* update itself before calling update_views(),
+      since this would cause it to get updated twice.
+
+Optionally, Viewers can also implement:
+
+    - save_options() which takes an optiondb (a dictionary).  Store into this
+      dictionary any values the Viewer wants to save in the persistent
+      ~/.pynche file.  This dictionary is saved using marshal.  The namespace
+      for the keys is ad-hoc; make sure you don't clobber some other Viewer's
+      keys!
+
+    - withdraw() which takes no arguments.  This is called when Pynche is
+      unmapped.  All Viewers should implement this.
+
+    - colordb_changed() which takes a single argument, an instance of
+      ColorDB.  This is called whenever the color name database is changed and
+      gives a chance for the Viewers to do something on those events.  See
+      ListViewer for details.
+
+External Viewers are found dynamically.  Viewer modules should have names such
+as FooViewer.py.  If such a named module has a module global variable called
+ADDTOVIEW and this variable is true, the Viewer will be added dynamically to
+the `View' menu.  ADDTOVIEW contains a string which is used as the menu item
+to display the Viewer (one kludge: if the string contains a `%', this is used
+to indicate that the next character will get an underline in the menu,
+otherwise the first character is underlined).
+
+FooViewer.py should contain a class called FooViewer, and its constructor
+should take two arguments, an instance of Switchboard, and optionally a Tk
+master window.
+
+"""
+
+import sys
+from types import DictType
+import marshal
+
+
+
+class Switchboard:
+    def __init__(self, initfile):
+        self.__initfile = initfile
+        self.__colordb = None
+        self.__optiondb = {}
+        self.__views = []
+        self.__red = 0
+        self.__green = 0
+        self.__blue = 0
+        self.__canceled = 0
+        # read the initialization file
+        fp = None
+        if initfile:
+            try:
+                try:
+                    fp = open(initfile)
+                    self.__optiondb = marshal.load(fp)
+                    if not isinstance(self.__optiondb, DictType):
+                        print >> sys.stderr, \
+                              'Problem reading options from file:', initfile
+                        self.__optiondb = {}
+                except (IOError, EOFError, ValueError):
+                    pass
+            finally:
+                if fp:
+                    fp.close()
+
+    def add_view(self, view):
+        self.__views.append(view)
+
+    def update_views(self, red, green, blue):
+        self.__red = red
+        self.__green = green
+        self.__blue = blue
+        for v in self.__views:
+            v.update_yourself(red, green, blue)
+
+    def update_views_current(self):
+        self.update_views(self.__red, self.__green, self.__blue)
+
+    def current_rgb(self):
+        return self.__red, self.__green, self.__blue
+
+    def colordb(self):
+        return self.__colordb
+
+    def set_colordb(self, colordb):
+        self.__colordb = colordb
+        for v in self.__views:
+            if hasattr(v, 'colordb_changed'):
+                v.colordb_changed(colordb)
+        self.update_views_current()
+
+    def optiondb(self):
+        return self.__optiondb
+
+    def save_views(self):
+        # save the current color
+        self.__optiondb['RED'] = self.__red
+        self.__optiondb['GREEN'] = self.__green
+        self.__optiondb['BLUE'] = self.__blue
+        for v in self.__views:
+            if hasattr(v, 'save_options'):
+                v.save_options(self.__optiondb)
+        # save the name of the file used for the color database.  we'll try to
+        # load this first.
+        self.__optiondb['DBFILE'] = self.__colordb.filename()
+        fp = None
+        try:
+            try:
+                fp = open(self.__initfile, 'w')
+            except IOError:
+                print >> sys.stderr, 'Cannot write options to file:', \
+                      self.__initfile
+            else:
+                marshal.dump(self.__optiondb, fp)
+        finally:
+            if fp:
+                fp.close()
+
+    def withdraw_views(self):
+        for v in self.__views:
+            if hasattr(v, 'withdraw'):
+                v.withdraw()
+
+    def canceled(self, flag=1):
+        self.__canceled = flag
+
+    def canceled_p(self):
+        return self.__canceled

Added: vendor/Python/current/Tools/pynche/TextViewer.py
===================================================================
--- vendor/Python/current/Tools/pynche/TextViewer.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/pynche/TextViewer.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,188 @@
+"""TextViewer class.
+
+The TextViewer allows you to see how the selected color would affect various
+characteristics of a Tk text widget.  This is an output viewer only.
+
+In the top part of the window is a standard text widget with some sample text
+in it.  You are free to edit this text in any way you want (BAW: allow you to
+change font characteristics).  If you want changes in other viewers to update
+text characteristics, turn on Track color changes.
+
+To select which characteristic tracks the change, select one of the radio
+buttons in the window below.  Text foreground and background affect the text
+in the window above.  The Selection is what you see when you click the middle
+button and drag it through some text.  The Insertion is the insertion cursor
+in the text window (which only has a background).
+"""
+
+from Tkinter import *
+import ColorDB
+
+ADDTOVIEW = 'Text Window...'
+
+
+
+class TextViewer:
+    def __init__(self, switchboard, master=None):
+        self.__sb = switchboard
+        optiondb = switchboard.optiondb()
+        root = self.__root = Toplevel(master, class_='Pynche')
+        root.protocol('WM_DELETE_WINDOW', self.withdraw)
+        root.title('Pynche Text Window')
+        root.iconname('Pynche Text Window')
+        root.bind('<Alt-q>', self.__quit)
+        root.bind('<Alt-Q>', self.__quit)
+        root.bind('<Alt-w>', self.withdraw)
+        root.bind('<Alt-W>', self.withdraw)
+        #
+        # create the text widget
+        #
+        self.__text = Text(root, relief=SUNKEN,
+                           background=optiondb.get('TEXTBG', 'black'),
+                           foreground=optiondb.get('TEXTFG', 'white'),
+                           width=35, height=15)
+        sfg = optiondb.get('TEXT_SFG')
+        if sfg:
+            self.__text.configure(selectforeground=sfg)
+        sbg = optiondb.get('TEXT_SBG')
+        if sbg:
+            self.__text.configure(selectbackground=sbg)
+        ibg = optiondb.get('TEXT_IBG')
+        if ibg:
+            self.__text.configure(insertbackground=ibg)
+        self.__text.pack()
+        self.__text.insert(0.0, optiondb.get('TEXT', '''\
+Insert some stuff here and play
+with the buttons below to see
+how the colors interact in
+textual displays.
+
+See how the selection can also
+be affected by tickling the buttons
+and choosing a color.'''))
+        insert = optiondb.get('TEXTINS')
+        if insert:
+            self.__text.mark_set(INSERT, insert)
+        try:
+            start, end = optiondb.get('TEXTSEL', (6.0, END))
+            self.__text.tag_add(SEL, start, end)
+        except ValueError:
+            # selection wasn't set
+            pass
+        self.__text.focus_set()
+        #
+        # variables
+        self.__trackp = BooleanVar()
+        self.__trackp.set(optiondb.get('TRACKP', 0))
+        self.__which = IntVar()
+        self.__which.set(optiondb.get('WHICH', 0))
+        #
+        # track toggle
+        self.__t = Checkbutton(root, text='Track color changes',
+                               variable=self.__trackp,
+                               relief=GROOVE,
+                               command=self.__toggletrack)
+        self.__t.pack(fill=X, expand=YES)
+        frame = self.__frame = Frame(root)
+        frame.pack()
+        #
+        # labels
+        self.__labels = []
+        row = 2
+        for text in ('Text:', 'Selection:', 'Insertion:'):
+            l = Label(frame, text=text)
+            l.grid(row=row, column=0, sticky=E)
+            self.__labels.append(l)
+            row += 1
+        col = 1
+        for text in ('Foreground', 'Background'):
+            l = Label(frame, text=text)
+            l.grid(row=1, column=col)
+            self.__labels.append(l)
+            col += 1
+        #
+        # radios
+        self.__radios = []
+        for col in (1, 2):
+            for row in (2, 3, 4):
+                # there is no insertforeground option
+                if row==4 and col==1:
+                    continue
+                r = Radiobutton(frame, variable=self.__which,
+                                value=(row-2)*2 + col-1,
+                                command=self.__set_color)
+                r.grid(row=row, column=col)
+                self.__radios.append(r)
+        self.__toggletrack()
+
+    def __quit(self, event=None):
+        self.__root.quit()
+
+    def withdraw(self, event=None):
+        self.__root.withdraw()
+
+    def deiconify(self, event=None):
+        self.__root.deiconify()
+
+    def __forceupdate(self, event=None):
+        self.__sb.update_views_current()
+
+    def __toggletrack(self, event=None):
+        if self.__trackp.get():
+            state = NORMAL
+            fg = self.__radios[0]['foreground']
+        else:
+            state = DISABLED
+            fg = self.__radios[0]['disabledforeground']
+        for r in self.__radios:
+            r.configure(state=state)
+        for l in self.__labels:
+            l.configure(foreground=fg)
+
+    def __set_color(self, event=None):
+        which = self.__which.get()
+        text = self.__text
+        if which == 0:
+            color = text['foreground']
+        elif which == 1:
+            color = text['background']
+        elif which == 2:
+            color = text['selectforeground']
+        elif which == 3:
+            color = text['selectbackground']
+        elif which == 5:
+            color = text['insertbackground']
+        try:
+            red, green, blue = ColorDB.rrggbb_to_triplet(color)
+        except ColorDB.BadColor:
+            # must have been a color name
+            red, green, blue = self.__sb.colordb().find_byname(color)
+        self.__sb.update_views(red, green, blue)
+
+    def update_yourself(self, red, green, blue):
+        if self.__trackp.get():
+            colorname = ColorDB.triplet_to_rrggbb((red, green, blue))
+            which = self.__which.get()
+            text = self.__text
+            if which == 0:
+                text.configure(foreground=colorname)
+            elif which == 1:
+                text.configure(background=colorname)
+            elif which == 2:
+                text.configure(selectforeground=colorname)
+            elif which == 3:
+                text.configure(selectbackground=colorname)
+            elif which == 5:
+                text.configure(insertbackground=colorname)
+
+    def save_options(self, optiondb):
+        optiondb['TRACKP'] = self.__trackp.get()
+        optiondb['WHICH'] = self.__which.get()
+        optiondb['TEXT'] = self.__text.get(0.0, 'end - 1c')
+        optiondb['TEXTSEL'] = self.__text.tag_ranges(SEL)[0:2]
+        optiondb['TEXTINS'] = self.__text.index(INSERT)
+        optiondb['TEXTFG'] = self.__text['foreground']
+        optiondb['TEXTBG'] = self.__text['background']
+        optiondb['TEXT_SFG'] = self.__text['selectforeground']
+        optiondb['TEXT_SBG'] = self.__text['selectbackground']
+        optiondb['TEXT_IBG'] = self.__text['insertbackground']

Added: vendor/Python/current/Tools/pynche/TypeinViewer.py
===================================================================
--- vendor/Python/current/Tools/pynche/TypeinViewer.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/pynche/TypeinViewer.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,163 @@
+"""TypeinViewer class.
+
+The TypeinViewer is what you see at the lower right of the main Pynche
+widget.  It contains three text entry fields, one each for red, green, blue.
+Input into these windows is highly constrained; it only allows you to enter
+values that are legal for a color axis.  This usually means 0-255 for decimal
+input and 0x0 - 0xff for hex input.
+
+You can toggle whether you want to view and input the values in either decimal
+or hex by clicking on Hexadecimal.  By clicking on Update while typing, the
+color selection will be made on every change to the text field.  Otherwise,
+you must hit Return or Tab to select the color.
+"""
+
+import sys
+import re
+from Tkinter import *
+
+
+
+class TypeinViewer:
+    def __init__(self, switchboard, master=None):
+        # non-gui ivars
+        self.__sb = switchboard
+        optiondb = switchboard.optiondb()
+        self.__hexp = BooleanVar()
+        self.__hexp.set(optiondb.get('HEXTYPE', 0))
+        self.__uwtyping = BooleanVar()
+        self.__uwtyping.set(optiondb.get('UPWHILETYPE', 0))
+        # create the gui
+        self.__frame = Frame(master, relief=RAISED, borderwidth=1)
+        self.__frame.grid(row=3, column=1, sticky='NSEW')
+        # Red
+        self.__xl = Label(self.__frame, text='Red:')
+        self.__xl.grid(row=0, column=0, sticky=E)
+        subframe = Frame(self.__frame)
+        subframe.grid(row=0, column=1)
+        self.__xox = Label(subframe, text='0x')
+        self.__xox.grid(row=0, column=0, sticky=E)
+        self.__xox['font'] = 'courier'
+        self.__x = Entry(subframe, width=3)
+        self.__x.grid(row=0, column=1)
+        self.__x.bindtags(self.__x.bindtags() + ('Normalize', 'Update'))
+        self.__x.bind_class('Normalize', '<Key>', self.__normalize)
+        self.__x.bind_class('Update'   , '<Key>', self.__maybeupdate)
+        # Green
+        self.__yl = Label(self.__frame, text='Green:')
+        self.__yl.grid(row=1, column=0, sticky=E)
+        subframe = Frame(self.__frame)
+        subframe.grid(row=1, column=1)
+        self.__yox = Label(subframe, text='0x')
+        self.__yox.grid(row=0, column=0, sticky=E)
+        self.__yox['font'] = 'courier'
+        self.__y = Entry(subframe, width=3)
+        self.__y.grid(row=0, column=1)
+        self.__y.bindtags(self.__y.bindtags() + ('Normalize', 'Update'))
+        # Blue
+        self.__zl = Label(self.__frame, text='Blue:')
+        self.__zl.grid(row=2, column=0, sticky=E)
+        subframe = Frame(self.__frame)
+        subframe.grid(row=2, column=1)
+        self.__zox = Label(subframe, text='0x')
+        self.__zox.grid(row=0, column=0, sticky=E)
+        self.__zox['font'] = 'courier'
+        self.__z = Entry(subframe, width=3)
+        self.__z.grid(row=0, column=1)
+        self.__z.bindtags(self.__z.bindtags() + ('Normalize', 'Update'))
+        # Update while typing?
+        self.__uwt = Checkbutton(self.__frame,
+                                 text='Update while typing',
+                                 variable=self.__uwtyping)
+        self.__uwt.grid(row=3, column=0, columnspan=2, sticky=W)
+        # Hex/Dec
+        self.__hex = Checkbutton(self.__frame,
+                                 text='Hexadecimal',
+                                 variable=self.__hexp,
+                                 command=self.__togglehex)
+        self.__hex.grid(row=4, column=0, columnspan=2, sticky=W)
+
+    def __togglehex(self, event=None):
+        red, green, blue = self.__sb.current_rgb()
+        if self.__hexp.get():
+            label = '0x'
+        else:
+            label = '  '
+        self.__xox['text'] = label
+        self.__yox['text'] = label
+        self.__zox['text'] = label
+        self.update_yourself(red, green, blue)
+
+    def __normalize(self, event=None):
+        ew = event.widget
+        contents = ew.get()
+        icursor = ew.index(INSERT)
+        if contents and contents[0] in 'xX' and self.__hexp.get():
+            contents = '0' + contents
+        # Figure out the contents in the current base.
+        try:
+            if self.__hexp.get():
+                v = int(contents, 16)
+            else:
+                v = int(contents)
+        except ValueError:
+            v = None
+        # If value is not legal, or empty, delete the last character inserted
+        # and ring the bell.  Don't ring the bell if the field is empty (it'll
+        # just equal zero.
+        if v is None:
+            pass
+        elif v < 0 or v > 255:
+            i = ew.index(INSERT)
+            if event.char:
+                contents = contents[:i-1] + contents[i:]
+                icursor -= 1
+            ew.bell()
+        elif self.__hexp.get():
+            contents = hex(v)[2:]
+        else:
+            contents = int(v)
+        ew.delete(0, END)
+        ew.insert(0, contents)
+        ew.icursor(icursor)
+
+    def __maybeupdate(self, event=None):
+        if self.__uwtyping.get() or event.keysym in ('Return', 'Tab'):
+            self.__update(event)
+
+    def __update(self, event=None):
+        redstr = self.__x.get() or '0'
+        greenstr = self.__y.get() or '0'
+        bluestr = self.__z.get() or '0'
+        if self.__hexp.get():
+            base = 16
+        else:
+            base = 10
+        red, green, blue = [int(x, base) for x in (redstr, greenstr, bluestr)]
+        self.__sb.update_views(red, green, blue)
+
+    def update_yourself(self, red, green, blue):
+        if self.__hexp.get():
+            sred, sgreen, sblue = [hex(x)[2:] for x in (red, green, blue)]
+        else:
+            sred, sgreen, sblue = red, green, blue
+        x, y, z = self.__x, self.__y, self.__z
+        xicursor = x.index(INSERT)
+        yicursor = y.index(INSERT)
+        zicursor = z.index(INSERT)
+        x.delete(0, END)
+        y.delete(0, END)
+        z.delete(0, END)
+        x.insert(0, sred)
+        y.insert(0, sgreen)
+        z.insert(0, sblue)
+        x.icursor(xicursor)
+        y.icursor(yicursor)
+        z.icursor(zicursor)
+
+    def hexp_var(self):
+        return self.__hexp
+
+    def save_options(self, optiondb):
+        optiondb['HEXTYPE'] = self.__hexp.get()
+        optiondb['UPWHILETYPE'] = self.__uwtyping.get()

Added: vendor/Python/current/Tools/pynche/X/rgb.txt
===================================================================
--- vendor/Python/current/Tools/pynche/X/rgb.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/pynche/X/rgb.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,753 @@
+! $XConsortium: rgb.txt,v 10.41 94/02/20 18:39:36 rws Exp $
+255 250 250		snow
+248 248 255		ghost white
+248 248 255		GhostWhite
+245 245 245		white smoke
+245 245 245		WhiteSmoke
+220 220 220		gainsboro
+255 250 240		floral white
+255 250 240		FloralWhite
+253 245 230		old lace
+253 245 230		OldLace
+250 240 230		linen
+250 235 215		antique white
+250 235 215		AntiqueWhite
+255 239 213		papaya whip
+255 239 213		PapayaWhip
+255 235 205		blanched almond
+255 235 205		BlanchedAlmond
+255 228 196		bisque
+255 218 185		peach puff
+255 218 185		PeachPuff
+255 222 173		navajo white
+255 222 173		NavajoWhite
+255 228 181		moccasin
+255 248 220		cornsilk
+255 255 240		ivory
+255 250 205		lemon chiffon
+255 250 205		LemonChiffon
+255 245 238		seashell
+240 255 240		honeydew
+245 255 250		mint cream
+245 255 250		MintCream
+240 255 255		azure
+240 248 255		alice blue
+240 248 255		AliceBlue
+230 230 250		lavender
+255 240 245		lavender blush
+255 240 245		LavenderBlush
+255 228 225		misty rose
+255 228 225		MistyRose
+255 255 255		white
+  0   0   0		black
+ 47  79  79		dark slate gray
+ 47  79  79		DarkSlateGray
+ 47  79  79		dark slate grey
+ 47  79  79		DarkSlateGrey
+105 105 105		dim gray
+105 105 105		DimGray
+105 105 105		dim grey
+105 105 105		DimGrey
+112 128 144		slate gray
+112 128 144		SlateGray
+112 128 144		slate grey
+112 128 144		SlateGrey
+119 136 153		light slate gray
+119 136 153		LightSlateGray
+119 136 153		light slate grey
+119 136 153		LightSlateGrey
+190 190 190		gray
+190 190 190		grey
+211 211 211		light grey
+211 211 211		LightGrey
+211 211 211		light gray
+211 211 211		LightGray
+ 25  25 112		midnight blue
+ 25  25 112		MidnightBlue
+  0   0 128		navy
+  0   0 128		navy blue
+  0   0 128		NavyBlue
+100 149 237		cornflower blue
+100 149 237		CornflowerBlue
+ 72  61 139		dark slate blue
+ 72  61 139		DarkSlateBlue
+106  90 205		slate blue
+106  90 205		SlateBlue
+123 104 238		medium slate blue
+123 104 238		MediumSlateBlue
+132 112 255		light slate blue
+132 112 255		LightSlateBlue
+  0   0 205		medium blue
+  0   0 205		MediumBlue
+ 65 105 225		royal blue
+ 65 105 225		RoyalBlue
+  0   0 255		blue
+ 30 144 255		dodger blue
+ 30 144 255		DodgerBlue
+  0 191 255		deep sky blue
+  0 191 255		DeepSkyBlue
+135 206 235		sky blue
+135 206 235		SkyBlue
+135 206 250		light sky blue
+135 206 250		LightSkyBlue
+ 70 130 180		steel blue
+ 70 130 180		SteelBlue
+176 196 222		light steel blue
+176 196 222		LightSteelBlue
+173 216 230		light blue
+173 216 230		LightBlue
+176 224 230		powder blue
+176 224 230		PowderBlue
+175 238 238		pale turquoise
+175 238 238		PaleTurquoise
+  0 206 209		dark turquoise
+  0 206 209		DarkTurquoise
+ 72 209 204		medium turquoise
+ 72 209 204		MediumTurquoise
+ 64 224 208		turquoise
+  0 255 255		cyan
+224 255 255		light cyan
+224 255 255		LightCyan
+ 95 158 160		cadet blue
+ 95 158 160		CadetBlue
+102 205 170		medium aquamarine
+102 205 170		MediumAquamarine
+127 255 212		aquamarine
+  0 100   0		dark green
+  0 100   0		DarkGreen
+ 85 107  47		dark olive green
+ 85 107  47		DarkOliveGreen
+143 188 143		dark sea green
+143 188 143		DarkSeaGreen
+ 46 139  87		sea green
+ 46 139  87		SeaGreen
+ 60 179 113		medium sea green
+ 60 179 113		MediumSeaGreen
+ 32 178 170		light sea green
+ 32 178 170		LightSeaGreen
+152 251 152		pale green
+152 251 152		PaleGreen
+  0 255 127		spring green
+  0 255 127		SpringGreen
+124 252   0		lawn green
+124 252   0		LawnGreen
+  0 255   0		green
+127 255   0		chartreuse
+  0 250 154		medium spring green
+  0 250 154		MediumSpringGreen
+173 255  47		green yellow
+173 255  47		GreenYellow
+ 50 205  50		lime green
+ 50 205  50		LimeGreen
+154 205  50		yellow green
+154 205  50		YellowGreen
+ 34 139  34		forest green
+ 34 139  34		ForestGreen
+107 142  35		olive drab
+107 142  35		OliveDrab
+189 183 107		dark khaki
+189 183 107		DarkKhaki
+240 230 140		khaki
+238 232 170		pale goldenrod
+238 232 170		PaleGoldenrod
+250 250 210		light goldenrod yellow
+250 250 210		LightGoldenrodYellow
+255 255 224		light yellow
+255 255 224		LightYellow
+255 255   0		yellow
+255 215   0 		gold
+238 221 130		light goldenrod
+238 221 130		LightGoldenrod
+218 165  32		goldenrod
+184 134  11		dark goldenrod
+184 134  11		DarkGoldenrod
+188 143 143		rosy brown
+188 143 143		RosyBrown
+205  92  92		indian red
+205  92  92		IndianRed
+139  69  19		saddle brown
+139  69  19		SaddleBrown
+160  82  45		sienna
+205 133  63		peru
+222 184 135		burlywood
+245 245 220		beige
+245 222 179		wheat
+244 164  96		sandy brown
+244 164  96		SandyBrown
+210 180 140		tan
+210 105  30		chocolate
+178  34  34		firebrick
+165  42  42		brown
+233 150 122		dark salmon
+233 150 122		DarkSalmon
+250 128 114		salmon
+255 160 122		light salmon
+255 160 122		LightSalmon
+255 165   0		orange
+255 140   0		dark orange
+255 140   0		DarkOrange
+255 127  80		coral
+240 128 128		light coral
+240 128 128		LightCoral
+255  99  71		tomato
+255  69   0		orange red
+255  69   0		OrangeRed
+255   0   0		red
+255 105 180		hot pink
+255 105 180		HotPink
+255  20 147		deep pink
+255  20 147		DeepPink
+255 192 203		pink
+255 182 193		light pink
+255 182 193		LightPink
+219 112 147		pale violet red
+219 112 147		PaleVioletRed
+176  48  96		maroon
+199  21 133		medium violet red
+199  21 133		MediumVioletRed
+208  32 144		violet red
+208  32 144		VioletRed
+255   0 255		magenta
+238 130 238		violet
+221 160 221		plum
+218 112 214		orchid
+186  85 211		medium orchid
+186  85 211		MediumOrchid
+153  50 204		dark orchid
+153  50 204		DarkOrchid
+148   0 211		dark violet
+148   0 211		DarkViolet
+138  43 226		blue violet
+138  43 226		BlueViolet
+160  32 240		purple
+147 112 219		medium purple
+147 112 219		MediumPurple
+216 191 216		thistle
+255 250 250		snow1
+238 233 233		snow2
+205 201 201		snow3
+139 137 137		snow4
+255 245 238		seashell1
+238 229 222		seashell2
+205 197 191		seashell3
+139 134 130		seashell4
+255 239 219		AntiqueWhite1
+238 223 204		AntiqueWhite2
+205 192 176		AntiqueWhite3
+139 131 120		AntiqueWhite4
+255 228 196		bisque1
+238 213 183		bisque2
+205 183 158		bisque3
+139 125 107		bisque4
+255 218 185		PeachPuff1
+238 203 173		PeachPuff2
+205 175 149		PeachPuff3
+139 119 101		PeachPuff4
+255 222 173		NavajoWhite1
+238 207 161		NavajoWhite2
+205 179 139		NavajoWhite3
+139 121	 94		NavajoWhite4
+255 250 205		LemonChiffon1
+238 233 191		LemonChiffon2
+205 201 165		LemonChiffon3
+139 137 112		LemonChiffon4
+255 248 220		cornsilk1
+238 232 205		cornsilk2
+205 200 177		cornsilk3
+139 136 120		cornsilk4
+255 255 240		ivory1
+238 238 224		ivory2
+205 205 193		ivory3
+139 139 131		ivory4
+240 255 240		honeydew1
+224 238 224		honeydew2
+193 205 193		honeydew3
+131 139 131		honeydew4
+255 240 245		LavenderBlush1
+238 224 229		LavenderBlush2
+205 193 197		LavenderBlush3
+139 131 134		LavenderBlush4
+255 228 225		MistyRose1
+238 213 210		MistyRose2
+205 183 181		MistyRose3
+139 125 123		MistyRose4
+240 255 255		azure1
+224 238 238		azure2
+193 205 205		azure3
+131 139 139		azure4
+131 111 255		SlateBlue1
+122 103 238		SlateBlue2
+105  89 205		SlateBlue3
+ 71  60 139		SlateBlue4
+ 72 118 255		RoyalBlue1
+ 67 110 238		RoyalBlue2
+ 58  95 205		RoyalBlue3
+ 39  64 139		RoyalBlue4
+  0   0 255		blue1
+  0   0 238		blue2
+  0   0 205		blue3
+  0   0 139		blue4
+ 30 144 255		DodgerBlue1
+ 28 134 238		DodgerBlue2
+ 24 116 205		DodgerBlue3
+ 16  78 139		DodgerBlue4
+ 99 184 255		SteelBlue1
+ 92 172 238		SteelBlue2
+ 79 148 205		SteelBlue3
+ 54 100 139		SteelBlue4
+  0 191 255		DeepSkyBlue1
+  0 178 238		DeepSkyBlue2
+  0 154 205		DeepSkyBlue3
+  0 104 139		DeepSkyBlue4
+135 206 255		SkyBlue1
+126 192 238		SkyBlue2
+108 166 205		SkyBlue3
+ 74 112 139		SkyBlue4
+176 226 255		LightSkyBlue1
+164 211 238		LightSkyBlue2
+141 182 205		LightSkyBlue3
+ 96 123 139		LightSkyBlue4
+198 226 255		SlateGray1
+185 211 238		SlateGray2
+159 182 205		SlateGray3
+108 123 139		SlateGray4
+202 225 255		LightSteelBlue1
+188 210 238		LightSteelBlue2
+162 181 205		LightSteelBlue3
+110 123 139		LightSteelBlue4
+191 239 255		LightBlue1
+178 223 238		LightBlue2
+154 192 205		LightBlue3
+104 131 139		LightBlue4
+224 255 255		LightCyan1
+209 238 238		LightCyan2
+180 205 205		LightCyan3
+122 139 139		LightCyan4
+187 255 255		PaleTurquoise1
+174 238 238		PaleTurquoise2
+150 205 205		PaleTurquoise3
+102 139 139		PaleTurquoise4
+152 245 255		CadetBlue1
+142 229 238		CadetBlue2
+122 197 205		CadetBlue3
+ 83 134 139		CadetBlue4
+  0 245 255		turquoise1
+  0 229 238		turquoise2
+  0 197 205		turquoise3
+  0 134 139		turquoise4
+  0 255 255		cyan1
+  0 238 238		cyan2
+  0 205 205		cyan3
+  0 139 139		cyan4
+151 255 255		DarkSlateGray1
+141 238 238		DarkSlateGray2
+121 205 205		DarkSlateGray3
+ 82 139 139		DarkSlateGray4
+127 255 212		aquamarine1
+118 238 198		aquamarine2
+102 205 170		aquamarine3
+ 69 139 116		aquamarine4
+193 255 193		DarkSeaGreen1
+180 238 180		DarkSeaGreen2
+155 205 155		DarkSeaGreen3
+105 139 105		DarkSeaGreen4
+ 84 255 159		SeaGreen1
+ 78 238 148		SeaGreen2
+ 67 205 128		SeaGreen3
+ 46 139	 87		SeaGreen4
+154 255 154		PaleGreen1
+144 238 144		PaleGreen2
+124 205 124		PaleGreen3
+ 84 139	 84		PaleGreen4
+  0 255 127		SpringGreen1
+  0 238 118		SpringGreen2
+  0 205 102		SpringGreen3
+  0 139	 69		SpringGreen4
+  0 255	  0		green1
+  0 238	  0		green2
+  0 205	  0		green3
+  0 139	  0		green4
+127 255	  0		chartreuse1
+118 238	  0		chartreuse2
+102 205	  0		chartreuse3
+ 69 139	  0		chartreuse4
+192 255	 62		OliveDrab1
+179 238	 58		OliveDrab2
+154 205	 50		OliveDrab3
+105 139	 34		OliveDrab4
+202 255 112		DarkOliveGreen1
+188 238 104		DarkOliveGreen2
+162 205	 90		DarkOliveGreen3
+110 139	 61		DarkOliveGreen4
+255 246 143		khaki1
+238 230 133		khaki2
+205 198 115		khaki3
+139 134	 78		khaki4
+255 236 139		LightGoldenrod1
+238 220 130		LightGoldenrod2
+205 190 112		LightGoldenrod3
+139 129	 76		LightGoldenrod4
+255 255 224		LightYellow1
+238 238 209		LightYellow2
+205 205 180		LightYellow3
+139 139 122		LightYellow4
+255 255	  0		yellow1
+238 238	  0		yellow2
+205 205	  0		yellow3
+139 139	  0		yellow4
+255 215	  0		gold1
+238 201	  0		gold2
+205 173	  0		gold3
+139 117	  0		gold4
+255 193	 37		goldenrod1
+238 180	 34		goldenrod2
+205 155	 29		goldenrod3
+139 105	 20		goldenrod4
+255 185	 15		DarkGoldenrod1
+238 173	 14		DarkGoldenrod2
+205 149	 12		DarkGoldenrod3
+139 101	  8		DarkGoldenrod4
+255 193 193		RosyBrown1
+238 180 180		RosyBrown2
+205 155 155		RosyBrown3
+139 105 105		RosyBrown4
+255 106 106		IndianRed1
+238  99	 99		IndianRed2
+205  85	 85		IndianRed3
+139  58	 58		IndianRed4
+255 130	 71		sienna1
+238 121	 66		sienna2
+205 104	 57		sienna3
+139  71	 38		sienna4
+255 211 155		burlywood1
+238 197 145		burlywood2
+205 170 125		burlywood3
+139 115	 85		burlywood4
+255 231 186		wheat1
+238 216 174		wheat2
+205 186 150		wheat3
+139 126 102		wheat4
+255 165	 79		tan1
+238 154	 73		tan2
+205 133	 63		tan3
+139  90	 43		tan4
+255 127	 36		chocolate1
+238 118	 33		chocolate2
+205 102	 29		chocolate3
+139  69	 19		chocolate4
+255  48	 48		firebrick1
+238  44	 44		firebrick2
+205  38	 38		firebrick3
+139  26	 26		firebrick4
+255  64	 64		brown1
+238  59	 59		brown2
+205  51	 51		brown3
+139  35	 35		brown4
+255 140 105		salmon1
+238 130	 98		salmon2
+205 112	 84		salmon3
+139  76	 57		salmon4
+255 160 122		LightSalmon1
+238 149 114		LightSalmon2
+205 129	 98		LightSalmon3
+139  87	 66		LightSalmon4
+255 165	  0		orange1
+238 154	  0		orange2
+205 133	  0		orange3
+139  90	  0		orange4
+255 127	  0		DarkOrange1
+238 118	  0		DarkOrange2
+205 102	  0		DarkOrange3
+139  69	  0		DarkOrange4
+255 114	 86		coral1
+238 106	 80		coral2
+205  91	 69		coral3
+139  62	 47		coral4
+255  99	 71		tomato1
+238  92	 66		tomato2
+205  79	 57		tomato3
+139  54	 38		tomato4
+255  69	  0		OrangeRed1
+238  64	  0		OrangeRed2
+205  55	  0		OrangeRed3
+139  37	  0		OrangeRed4
+255   0	  0		red1
+238   0	  0		red2
+205   0	  0		red3
+139   0	  0		red4
+255  20 147		DeepPink1
+238  18 137		DeepPink2
+205  16 118		DeepPink3
+139  10	 80		DeepPink4
+255 110 180		HotPink1
+238 106 167		HotPink2
+205  96 144		HotPink3
+139  58  98		HotPink4
+255 181 197		pink1
+238 169 184		pink2
+205 145 158		pink3
+139  99 108		pink4
+255 174 185		LightPink1
+238 162 173		LightPink2
+205 140 149		LightPink3
+139  95 101		LightPink4
+255 130 171		PaleVioletRed1
+238 121 159		PaleVioletRed2
+205 104 137		PaleVioletRed3
+139  71	 93		PaleVioletRed4
+255  52 179		maroon1
+238  48 167		maroon2
+205  41 144		maroon3
+139  28	 98		maroon4
+255  62 150		VioletRed1
+238  58 140		VioletRed2
+205  50 120		VioletRed3
+139  34	 82		VioletRed4
+255   0 255		magenta1
+238   0 238		magenta2
+205   0 205		magenta3
+139   0 139		magenta4
+255 131 250		orchid1
+238 122 233		orchid2
+205 105 201		orchid3
+139  71 137		orchid4
+255 187 255		plum1
+238 174 238		plum2
+205 150 205		plum3
+139 102 139		plum4
+224 102 255		MediumOrchid1
+209  95 238		MediumOrchid2
+180  82 205		MediumOrchid3
+122  55 139		MediumOrchid4
+191  62 255		DarkOrchid1
+178  58 238		DarkOrchid2
+154  50 205		DarkOrchid3
+104  34 139		DarkOrchid4
+155  48 255		purple1
+145  44 238		purple2
+125  38 205		purple3
+ 85  26 139		purple4
+171 130 255		MediumPurple1
+159 121 238		MediumPurple2
+137 104 205		MediumPurple3
+ 93  71 139		MediumPurple4
+255 225 255		thistle1
+238 210 238		thistle2
+205 181 205		thistle3
+139 123 139		thistle4
+  0   0   0		gray0
+  0   0   0		grey0
+  3   3   3		gray1
+  3   3   3		grey1
+  5   5   5		gray2
+  5   5   5		grey2
+  8   8   8		gray3
+  8   8   8		grey3
+ 10  10  10 		gray4
+ 10  10  10 		grey4
+ 13  13  13 		gray5
+ 13  13  13 		grey5
+ 15  15  15 		gray6
+ 15  15  15 		grey6
+ 18  18  18 		gray7
+ 18  18  18 		grey7
+ 20  20  20 		gray8
+ 20  20  20 		grey8
+ 23  23  23 		gray9
+ 23  23  23 		grey9
+ 26  26  26 		gray10
+ 26  26  26 		grey10
+ 28  28  28 		gray11
+ 28  28  28 		grey11
+ 31  31  31 		gray12
+ 31  31  31 		grey12
+ 33  33  33 		gray13
+ 33  33  33 		grey13
+ 36  36  36 		gray14
+ 36  36  36 		grey14
+ 38  38  38 		gray15
+ 38  38  38 		grey15
+ 41  41  41 		gray16
+ 41  41  41 		grey16
+ 43  43  43 		gray17
+ 43  43  43 		grey17
+ 46  46  46 		gray18
+ 46  46  46 		grey18
+ 48  48  48 		gray19
+ 48  48  48 		grey19
+ 51  51  51 		gray20
+ 51  51  51 		grey20
+ 54  54  54 		gray21
+ 54  54  54 		grey21
+ 56  56  56 		gray22
+ 56  56  56 		grey22
+ 59  59  59 		gray23
+ 59  59  59 		grey23
+ 61  61  61 		gray24
+ 61  61  61 		grey24
+ 64  64  64 		gray25
+ 64  64  64 		grey25
+ 66  66  66 		gray26
+ 66  66  66 		grey26
+ 69  69  69 		gray27
+ 69  69  69 		grey27
+ 71  71  71 		gray28
+ 71  71  71 		grey28
+ 74  74  74 		gray29
+ 74  74  74 		grey29
+ 77  77  77 		gray30
+ 77  77  77 		grey30
+ 79  79  79 		gray31
+ 79  79  79 		grey31
+ 82  82  82 		gray32
+ 82  82  82 		grey32
+ 84  84  84 		gray33
+ 84  84  84 		grey33
+ 87  87  87 		gray34
+ 87  87  87 		grey34
+ 89  89  89 		gray35
+ 89  89  89 		grey35
+ 92  92  92 		gray36
+ 92  92  92 		grey36
+ 94  94  94 		gray37
+ 94  94  94 		grey37
+ 97  97  97 		gray38
+ 97  97  97 		grey38
+ 99  99  99 		gray39
+ 99  99  99 		grey39
+102 102 102 		gray40
+102 102 102 		grey40
+105 105 105 		gray41
+105 105 105 		grey41
+107 107 107 		gray42
+107 107 107 		grey42
+110 110 110 		gray43
+110 110 110 		grey43
+112 112 112 		gray44
+112 112 112 		grey44
+115 115 115 		gray45
+115 115 115 		grey45
+117 117 117 		gray46
+117 117 117 		grey46
+120 120 120 		gray47
+120 120 120 		grey47
+122 122 122 		gray48
+122 122 122 		grey48
+125 125 125 		gray49
+125 125 125 		grey49
+127 127 127 		gray50
+127 127 127 		grey50
+130 130 130 		gray51
+130 130 130 		grey51
+133 133 133 		gray52
+133 133 133 		grey52
+135 135 135 		gray53
+135 135 135 		grey53
+138 138 138 		gray54
+138 138 138 		grey54
+140 140 140 		gray55
+140 140 140 		grey55
+143 143 143 		gray56
+143 143 143 		grey56
+145 145 145 		gray57
+145 145 145 		grey57
+148 148 148 		gray58
+148 148 148 		grey58
+150 150 150 		gray59
+150 150 150 		grey59
+153 153 153 		gray60
+153 153 153 		grey60
+156 156 156 		gray61
+156 156 156 		grey61
+158 158 158 		gray62
+158 158 158 		grey62
+161 161 161 		gray63
+161 161 161 		grey63
+163 163 163 		gray64
+163 163 163 		grey64
+166 166 166 		gray65
+166 166 166 		grey65
+168 168 168 		gray66
+168 168 168 		grey66
+171 171 171 		gray67
+171 171 171 		grey67
+173 173 173 		gray68
+173 173 173 		grey68
+176 176 176 		gray69
+176 176 176 		grey69
+179 179 179 		gray70
+179 179 179 		grey70
+181 181 181 		gray71
+181 181 181 		grey71
+184 184 184 		gray72
+184 184 184 		grey72
+186 186 186 		gray73
+186 186 186 		grey73
+189 189 189 		gray74
+189 189 189 		grey74
+191 191 191 		gray75
+191 191 191 		grey75
+194 194 194 		gray76
+194 194 194 		grey76
+196 196 196 		gray77
+196 196 196 		grey77
+199 199 199 		gray78
+199 199 199 		grey78
+201 201 201 		gray79
+201 201 201 		grey79
+204 204 204 		gray80
+204 204 204 		grey80
+207 207 207 		gray81
+207 207 207 		grey81
+209 209 209 		gray82
+209 209 209 		grey82
+212 212 212 		gray83
+212 212 212 		grey83
+214 214 214 		gray84
+214 214 214 		grey84
+217 217 217 		gray85
+217 217 217 		grey85
+219 219 219 		gray86
+219 219 219 		grey86
+222 222 222 		gray87
+222 222 222 		grey87
+224 224 224 		gray88
+224 224 224 		grey88
+227 227 227 		gray89
+227 227 227 		grey89
+229 229 229 		gray90
+229 229 229 		grey90
+232 232 232 		gray91
+232 232 232 		grey91
+235 235 235 		gray92
+235 235 235 		grey92
+237 237 237 		gray93
+237 237 237 		grey93
+240 240 240 		gray94
+240 240 240 		grey94
+242 242 242 		gray95
+242 242 242 		grey95
+245 245 245 		gray96
+245 245 245 		grey96
+247 247 247 		gray97
+247 247 247 		grey97
+250 250 250 		gray98
+250 250 250 		grey98
+252 252 252 		gray99
+252 252 252 		grey99
+255 255 255 		gray100
+255 255 255 		grey100
+169 169 169		dark grey
+169 169 169		DarkGrey
+169 169 169		dark gray
+169 169 169		DarkGray
+0     0 139		dark blue
+0     0 139		DarkBlue
+0   139 139		dark cyan
+0   139 139		DarkCyan
+139   0 139		dark magenta
+139   0 139		DarkMagenta
+139   0   0		dark red
+139   0   0		DarkRed
+144 238 144		light green
+144 238 144		LightGreen

Added: vendor/Python/current/Tools/pynche/X/xlicense.txt
===================================================================
--- vendor/Python/current/Tools/pynche/X/xlicense.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/pynche/X/xlicense.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,29 @@
+X Window System License - X11R6.4
+
+Copyright (c) 1998 The Open Group
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+X Window System is a trademark of The Open Group

Added: vendor/Python/current/Tools/pynche/__init__.py
===================================================================
--- vendor/Python/current/Tools/pynche/__init__.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/pynche/__init__.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1 @@
+# Dummy file to make this directory a package.

Added: vendor/Python/current/Tools/pynche/html40colors.txt
===================================================================
--- vendor/Python/current/Tools/pynche/html40colors.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/pynche/html40colors.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,17 @@
+# HTML 4.0 color names
+Black	#000000
+Silver	#c0c0c0
+Gray	#808080
+White	#ffffff
+Maroon	#800000
+Red	#ff0000
+Purple	#800080
+Fuchsia	#ff00ff
+Green	#008000
+Lime	#00ff00
+Olive	#808000
+Yellow	#ffff00
+Navy	#000080
+Blue	#0000ff
+Teal	#008080
+Aqua	#00ffff

Added: vendor/Python/current/Tools/pynche/namedcolors.txt
===================================================================
--- vendor/Python/current/Tools/pynche/namedcolors.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/pynche/namedcolors.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,100 @@
+# named colors from http://www.lightlink.com/xine/bells/namedcolors.html
+White                                            #FFFFFF
+Red                                              #FF0000
+Green                                            #00FF00
+Blue                                             #0000FF
+Magenta                                          #FF00FF
+Cyan                                             #00FFFF
+Yellow                                           #FFFF00
+Black                                            #000000
+Aquamarine                                       #70DB93
+Baker's Chocolate                                #5C3317
+Blue Violet                                      #9F5F9F
+Brass                                            #B5A642
+Bright Gold                                      #D9D919
+Brown                                            #A62A2A
+Bronze                                           #8C7853
+Bronze II                                        #A67D3D
+Cadet Blue                                       #5F9F9F
+Cool Copper                                      #D98719
+Copper                                           #B87333
+Coral                                            #FF7F00
+Corn Flower Blue                                 #42426F
+Dark Brown                                       #5C4033
+Dark Green                                       #2F4F2F
+Dark Green Copper                                #4A766E
+Dark Olive Green                                 #4F4F2F
+Dark Orchid                                      #9932CD
+Dark Purple                                      #871F78
+Dark Slate Blue                                  #6B238E
+Dark Slate Grey                                  #2F4F4F
+Dark Tan                                         #97694F
+Dark Turquoise                                   #7093DB
+Dark Wood                                        #855E42
+Dim Grey                                         #545454
+Dusty Rose                                       #856363
+Feldspar                                         #D19275
+Firebrick                                        #8E2323
+Forest Green                                     #238E23
+Gold                                             #CD7F32
+Goldenrod                                        #DBDB70
+Grey                                             #C0C0C0
+Green Copper                                     #527F76
+Green Yellow                                     #93DB70
+Hunter Green                                     #215E21
+Indian Red                                       #4E2F2F
+Khaki                                            #9F9F5F
+Light Blue                                       #C0D9D9
+Light Grey                                       #A8A8A8
+Light Steel Blue                                 #8F8FBD
+Light Wood                                       #E9C2A6
+Lime Green                                       #32CD32
+Mandarian Orange                                 #E47833
+Maroon                                           #8E236B
+Medium Aquamarine                                #32CD99
+Medium Blue                                      #3232CD
+Medium Forest Green                              #6B8E23
+Medium Goldenrod                                 #EAEAAE
+Medium Orchid                                    #9370DB
+Medium Sea Green                                 #426F42
+Medium Slate Blue                                #7F00FF
+Medium Spring Green                              #7FFF00
+Medium Turquoise                                 #70DBDB
+Medium Violet Red                                #DB7093
+Medium Wood                                      #A68064
+Midnight Blue                                    #2F2F4F
+Navy Blue                                        #23238E
+Neon Blue                                        #4D4DFF
+Neon Pink                                        #FF6EC7
+New Midnight Blue                                #00009C
+New Tan                                          #EBC79E
+Old Gold                                         #CFB53B
+Orange                                           #FF7F00
+Orange Red                                       #FF2400
+Orchid                                           #DB70DB
+Pale Green                                       #8FBC8F
+Pink                                             #BC8F8F
+Plum                                             #EAADEA
+Quartz                                           #D9D9F3
+Rich Blue                                        #5959AB
+Salmon                                           #6F4242
+Scarlet                                          #8C1717
+Sea Green                                        #238E68
+Semi-Sweet Chocolate                             #6B4226
+Sienna                                           #8E6B23
+Silver                                           #E6E8FA
+Sky Blue                                         #3299CC
+Slate Blue                                       #007FFF
+Spicy Pink                                       #FF1CAE
+Spring Green                                     #00FF7F
+Steel Blue                                       #236B8E
+Summer Sky                                       #38B0DE
+Tan                                              #DB9370
+Thistle                                          #D8BFD8
+Turquoise                                        #ADEAEA
+Very Dark Brown                                  #5C4033
+Very Light Grey                                  #CDCDCD
+Violet                                           #4F2F4F
+Violet Red                                       #CC3299
+Wheat                                            #D8D8BF
+Yellow Green                                     #99CC32

Added: vendor/Python/current/Tools/pynche/pyColorChooser.py
===================================================================
--- vendor/Python/current/Tools/pynche/pyColorChooser.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/pynche/pyColorChooser.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,125 @@
+"""Color chooser implementing (almost) the tkColorColor interface
+"""
+
+import os
+import Main
+import ColorDB
+
+
+
+class Chooser:
+    """Ask for a color"""
+    def __init__(self,
+                 master = None,
+                 databasefile = None,
+                 initfile = None,
+                 ignore = None,
+                 wantspec = None):
+        self.__master = master
+        self.__databasefile = databasefile
+        self.__initfile = initfile or os.path.expanduser('~/.pynche')
+        self.__ignore = ignore
+        self.__pw = None
+        self.__wantspec = wantspec
+
+    def show(self, color, options):
+        # scan for options that can override the ctor options
+        self.__wantspec = options.get('wantspec', self.__wantspec)
+        dbfile = options.get('databasefile', self.__databasefile)
+        # load the database file
+        colordb = None
+        if dbfile <> self.__databasefile:
+            colordb = ColorDB.get_colordb(dbfile)
+        if not self.__master:
+            from Tkinter import Tk
+            self.__master = Tk()
+        if not self.__pw:
+            self.__pw, self.__sb = \
+                       Main.build(master = self.__master,
+                                  initfile = self.__initfile,
+                                  ignore = self.__ignore)
+        else:
+            self.__pw.deiconify()
+        # convert color
+        if colordb:
+            self.__sb.set_colordb(colordb)
+        else:
+            colordb = self.__sb.colordb()
+        if color:
+            r, g, b = Main.initial_color(color, colordb)
+            self.__sb.update_views(r, g, b)
+        # reset the canceled flag and run it
+        self.__sb.canceled(0)
+        Main.run(self.__pw, self.__sb)
+        rgbtuple = self.__sb.current_rgb()
+        self.__pw.withdraw()
+        # check to see if the cancel button was pushed
+        if self.__sb.canceled_p():
+            return None, None
+        # Try to return the color name from the database if there is an exact
+        # match, otherwise use the "#rrggbb" spec.  BAW: Forget about color
+        # aliases for now, maybe later we should return these too.
+        name = None
+        if not self.__wantspec:
+            try:
+                name = colordb.find_byrgb(rgbtuple)[0]
+            except ColorDB.BadColor:
+                pass
+        if name is None:
+            name = ColorDB.triplet_to_rrggbb(rgbtuple)
+        return rgbtuple, name
+
+    def save(self):
+        if self.__sb:
+            self.__sb.save_views()
+
+
+# convenience stuff
+_chooser = None
+
+def askcolor(color = None, **options):
+    """Ask for a color"""
+    global _chooser
+    if not _chooser:
+        _chooser = apply(Chooser, (), options)
+    return _chooser.show(color, options)
+
+def save():
+    global _chooser
+    if _chooser:
+        _chooser.save()
+
+
+# test stuff
+if __name__ == '__main__':
+    from Tkinter import *
+
+    class Tester:
+        def __init__(self):
+            self.__root = tk = Tk()
+            b = Button(tk, text='Choose Color...', command=self.__choose)
+            b.pack()
+            self.__l = Label(tk)
+            self.__l.pack()
+            q = Button(tk, text='Quit', command=self.__quit)
+            q.pack()
+
+        def __choose(self, event=None):
+            rgb, name = askcolor(master=self.__root)
+            if rgb is None:
+                text = 'You hit CANCEL!'
+            else:
+                r, g, b = rgb
+                text = 'You picked %s (%3d/%3d/%3d)' % (name, r, g, b)
+            self.__l.configure(text=text)
+
+        def __quit(self, event=None):
+            self.__root.quit()
+
+        def run(self):
+            self.__root.mainloop()
+    t = Tester()
+    t.run()
+    # simpler
+##    print 'color:', askcolor()
+##    print 'color:', askcolor()

Added: vendor/Python/current/Tools/pynche/pynche
===================================================================
--- vendor/Python/current/Tools/pynche/pynche	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/pynche/pynche	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,7 @@
+#! /usr/bin/env python
+
+"""Run this file under Unix, or when debugging under Windows.
+Run the file pynche.pyw under Windows to inhibit the console window.
+"""
+import Main
+Main.main()


Property changes on: vendor/Python/current/Tools/pynche/pynche
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/pynche/pynche.pyw
===================================================================
--- vendor/Python/current/Tools/pynche/pynche.pyw	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/pynche/pynche.pyw	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,7 @@
+#! /usr/bin/env python
+
+"""Run this file under Windows to inhibit the console window.
+Run the file pynche.py under Unix or when debugging under Windows.
+"""
+import Main
+Main.main()


Property changes on: vendor/Python/current/Tools/pynche/pynche.pyw
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/pynche/webcolors.txt
===================================================================
--- vendor/Python/current/Tools/pynche/webcolors.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/pynche/webcolors.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,141 @@
+# De-facto NS & MSIE recognized HTML color names
+AliceBlue   	 #f0f8ff
+AntiqueWhite   	 #faebd7
+Aqua    	 #00ffff
+Aquamarine   	 #7fffd4
+Azure   	 #f0ffff
+Beige   	 #f5f5dc
+Bisque   	 #ffe4c4
+Black   	 #000000
+BlanchedAlmond 	 #ffebcd
+Blue    	 #0000ff
+BlueViolet   	 #8a2be2
+Brown   	 #a52a2a
+BurlyWood   	 #deb887
+CadetBlue   	 #5f9ea0
+Chartreuse   	 #7fff00
+Chocolate   	 #d2691e
+Coral   	 #ff7f50
+CornflowerBlue 	 #6495ed
+Cornsilk   	 #fff8dc
+Crimson   	 #dc143c
+Cyan    	 #00ffff
+DarkBlue   	 #00008b
+DarkCyan   	 #008b8b
+DarkGoldenrod  	 #b8860b
+DarkGray   	 #a9a9a9
+DarkGreen   	 #006400
+DarkKhaki   	 #bdb76b
+DarkMagenta   	 #8b008b
+DarkOliveGreen 	 #556b2f
+DarkOrange   	 #ff8c00
+DarkOrchid   	 #9932cc
+DarkRed   	 #8b0000
+DarkSalmon   	 #e9967a
+DarkSeaGreen   	 #8fbc8f
+DarkSlateBlue  	 #483d8b
+DarkSlateGray  	 #2f4f4f
+DarkTurquoise  	 #00ced1
+DarkViolet   	 #9400d3
+DeepPink   	 #ff1493
+DeepSkyBlue   	 #00bfff
+DimGray   	 #696969
+DodgerBlue   	 #1e90ff
+FireBrick   	 #b22222
+FloralWhite   	 #fffaf0
+ForestGreen   	 #228b22
+Fuchsia   	 #ff00ff
+Gainsboro   	 #dcdcdc
+GhostWhite   	 #f8f8ff
+Gold    	 #ffd700
+Goldenrod   	 #daa520
+Gray    	 #808080
+Green   	 #008000
+GreenYellow   	 #adff2f
+Honeydew   	 #f0fff0
+HotPink   	 #ff69b4
+IndianRed   	 #cd5c5c
+Indigo   	 #4b0082
+Ivory   	 #fffff0
+Khaki   	 #f0e68c
+Lavender   	 #e6e6fa
+LavenderBlush  	 #fff0f5
+LawnGreen   	 #7cfc00
+LemonChiffon   	 #fffacd
+LightBlue   	 #add8e6
+LightCoral   	 #f08080
+LightCyan   	 #e0ffff
+LightGoldenrodYellow	#fafad2
+LightGreen   	 #90ee90
+LightGrey   	 #d3d3d3
+LightPink   	 #ffb6c1
+LightSalmon   	 #ffa07a
+LightSeaGreen  	 #20b2aa
+LightSkyBlue   	 #87cefa
+LightSlateGray 	 #778899
+LightSteelBlue 	 #b0c4de
+LightYellow   	 #ffffe0
+Lime    	 #00ff00
+LimeGreen   	 #32cd32
+Linen   	 #faf0e6
+Magenta   	 #ff00ff
+Maroon   	 #800000
+MediumAquamarine #66cdaa
+MediumBlue   	 #0000cd
+MediumOrchid   	 #ba55d3
+MediumPurple   	 #9370db
+MediumSeaGreen 	 #3cb371
+MediumSlateBlue	 #7b68ee
+MediumSpringGreen	#00fa9a
+MediumTurquoise	 #48d1cc
+MediumVioletRed	 #c71585
+MidnightBlue   	 #191970
+MintCream   	 #f5fffa
+MistyRose   	 #ffe4e1
+Moccasin   	 #ffe4b5
+NavajoWhite   	 #ffdead
+Navy    	 #000080
+OldLace   	 #fdf5e6
+Olive   	 #808000
+OliveDrab   	 #6b8e23
+Orange   	 #ffa500
+OrangeRed   	 #ff4500
+Orchid   	 #da70d6
+PaleGoldenrod  	 #eee8aa
+PaleGreen   	 #98fb98
+PaleTurquoise  	 #afeeee
+PaleVioletRed  	 #db7093
+PapayaWhip   	 #ffefd5
+PeachPuff   	 #ffdab9
+Peru    	 #cd853f
+Pink    	 #ffc0cb
+Plum    	 #dda0dd
+PowderBlue   	 #b0e0e6
+Purple   	 #800080
+Red     	 #ff0000
+RosyBrown   	 #bc8f8f
+RoyalBlue   	 #4169e1
+SaddleBrown   	 #8b4513
+Salmon   	 #fa8072
+SandyBrown   	 #f4a460
+SeaGreen   	 #2e8b57
+Seashell   	 #fff5ee
+Sienna   	 #a0522d
+Silver   	 #c0c0c0
+SkyBlue   	 #87ceeb
+SlateBlue   	 #6a5acd
+SlateGray   	 #708090
+Snow    	 #fffafa
+SpringGreen   	 #00ff7f
+SteelBlue   	 #4682b4
+Tan     	 #d2b48c
+Teal    	 #008080
+Thistle   	 #d8bfd8
+Tomato   	 #ff6347
+Turquoise   	 #40e0d0
+Violet   	 #ee82ee
+Wheat   	 #f5deb3
+White   	 #ffffff
+WhiteSmoke   	 #f5f5f5
+Yellow   	 #ffff00
+YellowGreen   	 #9acd32

Added: vendor/Python/current/Tools/pynche/websafe.txt
===================================================================
--- vendor/Python/current/Tools/pynche/websafe.txt	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/pynche/websafe.txt	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,217 @@
+# Websafe RGB values
+#000000
+#000033
+#000066
+#000099
+#0000cc
+#0000ff
+#003300
+#003333
+#003366
+#003399
+#0033cc
+#0033ff
+#006600
+#006633
+#006666
+#006699
+#0066cc
+#0066ff
+#009900
+#009933
+#009966
+#009999
+#0099cc
+#0099ff
+#00cc00
+#00cc33
+#00cc66
+#00cc99
+#00cccc
+#00ccff
+#00ff00
+#00ff33
+#00ff66
+#00ff99
+#00ffcc
+#00ffff
+#330000
+#330033
+#330066
+#330099
+#3300cc
+#3300ff
+#333300
+#333333
+#333366
+#333399
+#3333cc
+#3333ff
+#336600
+#336633
+#336666
+#336699
+#3366cc
+#3366ff
+#339900
+#339933
+#339966
+#339999
+#3399cc
+#3399ff
+#33cc00
+#33cc33
+#33cc66
+#33cc99
+#33cccc
+#33ccff
+#33ff00
+#33ff33
+#33ff66
+#33ff99
+#33ffcc
+#33ffff
+#660000
+#660033
+#660066
+#660099
+#6600cc
+#6600ff
+#663300
+#663333
+#663366
+#663399
+#6633cc
+#6633ff
+#666600
+#666633
+#666666
+#666699
+#6666cc
+#6666ff
+#669900
+#669933
+#669966
+#669999
+#6699cc
+#6699ff
+#66cc00
+#66cc33
+#66cc66
+#66cc99
+#66cccc
+#66ccff
+#66ff00
+#66ff33
+#66ff66
+#66ff99
+#66ffcc
+#66ffff
+#990000
+#990033
+#990066
+#990099
+#9900cc
+#9900ff
+#993300
+#993333
+#993366
+#993399
+#9933cc
+#9933ff
+#996600
+#996633
+#996666
+#996699
+#9966cc
+#9966ff
+#999900
+#999933
+#999966
+#999999
+#9999cc
+#9999ff
+#99cc00
+#99cc33
+#99cc66
+#99cc99
+#99cccc
+#99ccff
+#99ff00
+#99ff33
+#99ff66
+#99ff99
+#99ffcc
+#99ffff
+#cc0000
+#cc0033
+#cc0066
+#cc0099
+#cc00cc
+#cc00ff
+#cc3300
+#cc3333
+#cc3366
+#cc3399
+#cc33cc
+#cc33ff
+#cc6600
+#cc6633
+#cc6666
+#cc6699
+#cc66cc
+#cc66ff
+#cc9900
+#cc9933
+#cc9966
+#cc9999
+#cc99cc
+#cc99ff
+#cccc00
+#cccc33
+#cccc66
+#cccc99
+#cccccc
+#ccccff
+#ccff00
+#ccff33
+#ccff66
+#ccff99
+#ccffcc
+#ccffff
+#ff0000
+#ff0033
+#ff0066
+#ff0099
+#ff00cc
+#ff00ff
+#ff3300
+#ff3333
+#ff3366
+#ff3399
+#ff33cc
+#ff33ff
+#ff6600
+#ff6633
+#ff6666
+#ff6699
+#ff66cc
+#ff66ff
+#ff9900
+#ff9933
+#ff9966
+#ff9999
+#ff99cc
+#ff99ff
+#ffcc00
+#ffcc33
+#ffcc66
+#ffcc99
+#ffcccc
+#ffccff
+#ffff00
+#ffff33
+#ffff66
+#ffff99
+#ffffcc
+#ffffff

Added: vendor/Python/current/Tools/scripts/README
===================================================================
--- vendor/Python/current/Tools/scripts/README	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/README	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,66 @@
+This directory contains a collection of executable Python scripts that
+are useful while building, extending or managing Python.  Some (e.g.,
+dutree or lll) are also generally useful UNIX tools.
+
+See also the Demo/scripts directory!
+
+byext.py		Print lines/words/chars stats of files by extension
+byteyears.py		Print product of a file's size and age
+checkappend.py		Search for multi-argument .append() calls
+checkpyc.py		Check presence and validity of ".pyc" files
+classfix.py		Convert old class syntax to new
+cleanfuture.py		Fix reduntant Python __future__ statements
+combinerefs.py		A helper for analyzing PYTHONDUMPREFS output.
+copytime.py		Copy one file's atime and mtime to another
+crlf.py			Change CRLF line endings to LF (Windows to Unix)
+cvsfiles.py		Print a list of files that are under CVS
+db2pickle.py		Dump a database file to a pickle
+diff.py			Print file diffs in context, unified, or ndiff formats
+dutree.py		Format du(1) output as a tree sorted by size
+eptags.py		Create Emacs TAGS file for Python modules
+finddiv.py		A grep-like tool that looks for division operators.
+findlinksto.py		Recursively find symbolic links to a given path prefix
+findnocoding.py		Find source files which need an encoding declaration
+fixcid.py		Massive identifier substitution on C source files
+fixdiv.py		Tool to fix division operators.
+fixheader.py		Add some cpp magic to a C include file
+fixnotice.py		Fix the copyright notice in source files
+fixps.py		Fix Python scripts' first line (if #!)
+ftpmirror.py		FTP mirror script
+google.py		Open a webbrowser with Google.
+gprof2html.py		Transform gprof(1) output into useful HTML.
+h2py.py			Translate #define's into Python assignments
+hotshotmain.py		Main program to run script under control of hotshot
+idle			Main program to start IDLE
+ifdef.py		Remove #if(n)def groups from C sources
+lfcr.py			Change LF line endings to CRLF (Unix to Windows)
+linktree.py		Make a copy of a tree with links to original files
+lll.py			Find and list symbolic links in current directory
+logmerge.py		Consolidate CVS/RCS logs read from stdin
+mailerdaemon.py		parse error messages from mailer daemons (Sjoerd&Jack)
+md5sum.py		Print MD5 checksums of argument files.
+methfix.py		Fix old method syntax def f(self, (a1, ..., aN)):
+mkreal.py		Turn a symbolic link into a real file or directory
+ndiff.py		Intelligent diff between text files (Tim Peters)
+nm2def.py		Create a template for PC/python_nt.def (Marc Lemburg)
+objgraph.py		Print object graph from nm output on a library
+parseentities.py	Utility for parsing HTML entity definitions
+pathfix.py		Change #!/usr/local/bin/python into something else
+pdeps.py		Print dependencies between Python modules
+pickle2db.py		Load a pickle generated by db2pickle.py to a database
+pindent.py		Indent Python code, giving block-closing comments
+ptags.py		Create vi tags file for Python modules
+pydoc			Python documentation browser.
+pysource.py		Find Python source files
+redemo.py		Basic regular expression demonstration facility
+reindent.py		Change .py files to use 4-space indents.
+rgrep.py		Reverse grep through a file (useful for big logfiles)
+setup.py		Install all scripts listed here.
+suff.py			Sort a list of files by suffix
+svneol.py		Sets svn:eol-style on all files in directory.
+texcheck.py             Validate Python LaTeX formatting (Raymond Hettinger)
+texi2html.py		Convert GNU texinfo files into HTML
+treesync.py		Synchronize source trees (very ideosyncratic)
+untabify.py		Replace tabs with spaces in argument files
+which.py		Find a program in $PATH
+xxci.py			Wrapper for rcsdiff and ci

Added: vendor/Python/current/Tools/scripts/byext.py
===================================================================
--- vendor/Python/current/Tools/scripts/byext.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/byext.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,131 @@
+#! /usr/bin/env python
+
+"""Show file statistics by extension."""
+
+import os
+import sys
+
+class Stats:
+
+    def __init__(self):
+        self.stats = {}
+
+    def statargs(self, args):
+        for arg in args:
+            if os.path.isdir(arg):
+                self.statdir(arg)
+            elif os.path.isfile(arg):
+                self.statfile(arg)
+            else:
+                sys.stderr.write("Can't find %s\n" % arg)
+                self.addstats("<???>", "unknown", 1)
+
+    def statdir(self, dir):
+        self.addstats("<dir>", "dirs", 1)
+        try:
+            names = os.listdir(dir)
+        except os.error, err:
+            sys.stderr.write("Can't list %s: %s\n" % (dir, err))
+            self.addstats("<dir>", "unlistable", 1)
+            return
+        names.sort()
+        for name in names:
+            if name.startswith(".#"):
+                continue # Skip CVS temp files
+            if name.endswith("~"):
+                continue# Skip Emacs backup files
+            full = os.path.join(dir, name)
+            if os.path.islink(full):
+                self.addstats("<lnk>", "links", 1)
+            elif os.path.isdir(full):
+                self.statdir(full)
+            else:
+                self.statfile(full)
+
+    def statfile(self, filename):
+        head, ext = os.path.splitext(filename)
+        head, base = os.path.split(filename)
+        if ext == base:
+            ext = "" # E.g. .cvsignore is deemed not to have an extension
+        ext = os.path.normcase(ext)
+        if not ext:
+            ext = "<none>"
+        self.addstats(ext, "files", 1)
+        try:
+            f = open(filename, "rb")
+        except IOError, err:
+            sys.stderr.write("Can't open %s: %s\n" % (filename, err))
+            self.addstats(ext, "unopenable", 1)
+            return
+        data = f.read()
+        f.close()
+        self.addstats(ext, "bytes", len(data))
+        if '\0' in data:
+            self.addstats(ext, "binary", 1)
+            return
+        if not data:
+            self.addstats(ext, "empty", 1)
+        #self.addstats(ext, "chars", len(data))
+        lines = data.splitlines()
+        self.addstats(ext, "lines", len(lines))
+        del lines
+        words = data.split()
+        self.addstats(ext, "words", len(words))
+
+    def addstats(self, ext, key, n):
+        d = self.stats.setdefault(ext, {})
+        d[key] = d.get(key, 0) + n
+
+    def report(self):
+        exts = self.stats.keys()
+        exts.sort()
+        # Get the column keys
+        columns = {}
+        for ext in exts:
+            columns.update(self.stats[ext])
+        cols = columns.keys()
+        cols.sort()
+        colwidth = {}
+        colwidth["ext"] = max([len(ext) for ext in exts])
+        minwidth = 6
+        self.stats["TOTAL"] = {}
+        for col in cols:
+            total = 0
+            cw = max(minwidth, len(col))
+            for ext in exts:
+                value = self.stats[ext].get(col)
+                if value is None:
+                    w = 0
+                else:
+                    w = len("%d" % value)
+                    total += value
+                cw = max(cw, w)
+            cw = max(cw, len(str(total)))
+            colwidth[col] = cw
+            self.stats["TOTAL"][col] = total
+        exts.append("TOTAL")
+        for ext in exts:
+            self.stats[ext]["ext"] = ext
+        cols.insert(0, "ext")
+        def printheader():
+            for col in cols:
+                print "%*s" % (colwidth[col], col),
+            print
+        printheader()
+        for ext in exts:
+            for col in cols:
+                value = self.stats[ext].get(col, "")
+                print "%*s" % (colwidth[col], value),
+            print
+        printheader() # Another header at the bottom
+
+def main():
+    args = sys.argv[1:]
+    if not args:
+        args = [os.curdir]
+    s = Stats()
+    s.statargs(args)
+    s.report()
+
+if __name__ == "__main__":
+    main()

Added: vendor/Python/current/Tools/scripts/byteyears.py
===================================================================
--- vendor/Python/current/Tools/scripts/byteyears.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/byteyears.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,61 @@
+#! /usr/bin/env python
+
+# Print the product of age and size of each file, in suitable units.
+#
+# Usage: byteyears [ -a | -m | -c ] file ...
+#
+# Options -[amc] select atime, mtime (default) or ctime as age.
+
+import sys, os, time
+from stat import *
+
+def main():
+
+    # Use lstat() to stat files if it exists, else stat()
+    try:
+        statfunc = os.lstat
+    except AttributeError:
+        statfunc = os.stat
+
+    # Parse options
+    if sys.argv[1] == '-m':
+        itime = ST_MTIME
+        del sys.argv[1]
+    elif sys.argv[1] == '-c':
+        itime = ST_CTIME
+        del sys.argv[1]
+    elif sys.argv[1] == '-a':
+        itime = ST_CTIME
+        del sys.argv[1]
+    else:
+        itime = ST_MTIME
+
+    secs_per_year = 365.0 * 24.0 * 3600.0   # Scale factor
+    now = time.time()                       # Current time, for age computations
+    status = 0                              # Exit status, set to 1 on errors
+
+    # Compute max file name length
+    maxlen = 1
+    for filename in sys.argv[1:]:
+        maxlen = max(maxlen, len(filename))
+
+    # Process each argument in turn
+    for filename in sys.argv[1:]:
+        try:
+            st = statfunc(filename)
+        except os.error, msg:
+            sys.stderr.write("can't stat %r: %r\n" % (filename, msg))
+            status = 1
+            st = ()
+        if st:
+            anytime = st[itime]
+            size = st[ST_SIZE]
+            age = now - anytime
+            byteyears = float(size) * float(age) / secs_per_year
+            print filename.ljust(maxlen),
+            print repr(int(byteyears)).rjust(8)
+
+    sys.exit(status)
+
+if __name__ == '__main__':
+    main()


Property changes on: vendor/Python/current/Tools/scripts/byteyears.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/scripts/checkappend.py
===================================================================
--- vendor/Python/current/Tools/scripts/checkappend.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/checkappend.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,167 @@
+#! /usr/bin/env python
+
+# Released to the public domain, by Tim Peters, 28 February 2000.
+
+"""checkappend.py -- search for multi-argument .append() calls.
+
+Usage:  specify one or more file or directory paths:
+    checkappend [-v] file_or_dir [file_or_dir] ...
+
+Each file_or_dir is checked for multi-argument .append() calls.  When
+a directory, all .py files in the directory, and recursively in its
+subdirectories, are checked.
+
+Use -v for status msgs.  Use -vv for more status msgs.
+
+In the absence of -v, the only output is pairs of the form
+
+    filename(linenumber):
+    line containing the suspicious append
+
+Note that this finds multi-argument append calls regardless of whether
+they're attached to list objects.  If a module defines a class with an
+append method that takes more than one argument, calls to that method
+will be listed.
+
+Note that this will not find multi-argument list.append calls made via a
+bound method object.  For example, this is not caught:
+
+    somelist = []
+    push = somelist.append
+    push(1, 2, 3)
+"""
+
+__version__ = 1, 0, 0
+
+import os
+import sys
+import getopt
+import tokenize
+
+verbose = 0
+
+def errprint(*args):
+    msg = ' '.join(args)
+    sys.stderr.write(msg)
+    sys.stderr.write("\n")
+
+def main():
+    args = sys.argv[1:]
+    global verbose
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], "v")
+    except getopt.error, msg:
+        errprint(str(msg) + "\n\n" + __doc__)
+        return
+    for opt, optarg in opts:
+        if opt == '-v':
+            verbose = verbose + 1
+    if not args:
+        errprint(__doc__)
+        return
+    for arg in args:
+        check(arg)
+
+def check(file):
+    if os.path.isdir(file) and not os.path.islink(file):
+        if verbose:
+            print "%r: listing directory" % (file,)
+        names = os.listdir(file)
+        for name in names:
+            fullname = os.path.join(file, name)
+            if ((os.path.isdir(fullname) and
+                 not os.path.islink(fullname))
+                or os.path.normcase(name[-3:]) == ".py"):
+                check(fullname)
+        return
+
+    try:
+        f = open(file)
+    except IOError, msg:
+        errprint("%r: I/O Error: %s" % (file, msg))
+        return
+
+    if verbose > 1:
+        print "checking %r ..." % (file,)
+
+    ok = AppendChecker(file, f).run()
+    if verbose and ok:
+        print "%r: Clean bill of health." % (file,)
+
+[FIND_DOT,
+ FIND_APPEND,
+ FIND_LPAREN,
+ FIND_COMMA,
+ FIND_STMT]   = range(5)
+
+class AppendChecker:
+    def __init__(self, fname, file):
+        self.fname = fname
+        self.file = file
+        self.state = FIND_DOT
+        self.nerrors = 0
+
+    def run(self):
+        try:
+            tokenize.tokenize(self.file.readline, self.tokeneater)
+        except tokenize.TokenError, msg:
+            errprint("%r: Token Error: %s" % (self.fname, msg))
+            self.nerrors = self.nerrors + 1
+        return self.nerrors == 0
+
+    def tokeneater(self, type, token, start, end, line,
+                NEWLINE=tokenize.NEWLINE,
+                JUNK=(tokenize.COMMENT, tokenize.NL),
+                OP=tokenize.OP,
+                NAME=tokenize.NAME):
+
+        state = self.state
+
+        if type in JUNK:
+            pass
+
+        elif state is FIND_DOT:
+            if type is OP and token == ".":
+                state = FIND_APPEND
+
+        elif state is FIND_APPEND:
+            if type is NAME and token == "append":
+                self.line = line
+                self.lineno = start[0]
+                state = FIND_LPAREN
+            else:
+                state = FIND_DOT
+
+        elif state is FIND_LPAREN:
+            if type is OP and token == "(":
+                self.level = 1
+                state = FIND_COMMA
+            else:
+                state = FIND_DOT
+
+        elif state is FIND_COMMA:
+            if type is OP:
+                if token in ("(", "{", "["):
+                    self.level = self.level + 1
+                elif token in (")", "}", "]"):
+                    self.level = self.level - 1
+                    if self.level == 0:
+                        state = FIND_DOT
+                elif token == "," and self.level == 1:
+                    self.nerrors = self.nerrors + 1
+                    print "%s(%d):\n%s" % (self.fname, self.lineno,
+                                           self.line)
+                    # don't gripe about this stmt again
+                    state = FIND_STMT
+
+        elif state is FIND_STMT:
+            if type is NEWLINE:
+                state = FIND_DOT
+
+        else:
+            raise SystemError("unknown internal state '%r'" % (state,))
+
+        self.state = state
+
+if __name__ == '__main__':
+    main()


Property changes on: vendor/Python/current/Tools/scripts/checkappend.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/scripts/checkpyc.py
===================================================================
--- vendor/Python/current/Tools/scripts/checkpyc.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/checkpyc.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,66 @@
+#! /usr/bin/env python
+# Check that all ".pyc" files exist and are up-to-date
+# Uses module 'os'
+
+import sys
+import os
+from stat import ST_MTIME
+import imp
+
+def main():
+    silent = 0
+    verbose = 0
+    if sys.argv[1:]:
+        if sys.argv[1] == '-v':
+            verbose = 1
+        elif sys.argv[1] == '-s':
+            silent = 1
+    MAGIC = imp.get_magic()
+    if not silent:
+        print 'Using MAGIC word', repr(MAGIC)
+    for dirname in sys.path:
+        try:
+            names = os.listdir(dirname)
+        except os.error:
+            print 'Cannot list directory', repr(dirname)
+            continue
+        if not silent:
+            print 'Checking ', repr(dirname), '...'
+        names.sort()
+        for name in names:
+            if name[-3:] == '.py':
+                name = os.path.join(dirname, name)
+                try:
+                    st = os.stat(name)
+                except os.error:
+                    print 'Cannot stat', repr(name)
+                    continue
+                if verbose:
+                    print 'Check', repr(name), '...'
+                name_c = name + 'c'
+                try:
+                    f = open(name_c, 'r')
+                except IOError:
+                    print 'Cannot open', repr(name_c)
+                    continue
+                magic_str = f.read(4)
+                mtime_str = f.read(4)
+                f.close()
+                if magic_str <> MAGIC:
+                    print 'Bad MAGIC word in ".pyc" file',
+                    print repr(name_c)
+                    continue
+                mtime = get_long(mtime_str)
+                if mtime == 0 or mtime == -1:
+                    print 'Bad ".pyc" file', repr(name_c)
+                elif mtime <> st[ST_MTIME]:
+                    print 'Out-of-date ".pyc" file',
+                    print repr(name_c)
+
+def get_long(s):
+    if len(s) <> 4:
+        return -1
+    return ord(s[0]) + (ord(s[1])<<8) + (ord(s[2])<<16) + (ord(s[3])<<24)
+
+if __name__ == '__main__':
+    main()


Property changes on: vendor/Python/current/Tools/scripts/checkpyc.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/scripts/classfix.py
===================================================================
--- vendor/Python/current/Tools/scripts/classfix.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/classfix.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,190 @@
+#! /usr/bin/env python
+
+# This script is obsolete -- it is kept for historical purposes only.
+#
+# Fix Python source files to use the new class definition syntax, i.e.,
+# the syntax used in Python versions before 0.9.8:
+#       class C() = base(), base(), ...: ...
+# is changed to the current syntax:
+#       class C(base, base, ...): ...
+#
+# The script uses heuristics to find class definitions that usually
+# work but occasionally can fail; carefully check the output!
+#
+# Command line arguments are files or directories to be processed.
+# Directories are searched recursively for files whose name looks
+# like a python module.
+# Symbolic links are always ignored (except as explicit directory
+# arguments).  Of course, the original file is kept as a back-up
+# (with a "~" attached to its name).
+#
+# Changes made are reported to stdout in a diff-like format.
+#
+# Undoubtedly you can do this using find and sed or perl, but this is
+# a nice example of Python code that recurses down a directory tree
+# and uses regular expressions.  Also note several subtleties like
+# preserving the file's mode and avoiding to even write a temp file
+# when no changes are needed for a file.
+#
+# NB: by changing only the function fixline() you can turn this
+# into a program for a different change to Python programs...
+
+import sys
+import re
+import os
+from stat import *
+
+err = sys.stderr.write
+dbg = err
+rep = sys.stdout.write
+
+def main():
+    bad = 0
+    if not sys.argv[1:]: # No arguments
+        err('usage: ' + sys.argv[0] + ' file-or-directory ...\n')
+        sys.exit(2)
+    for arg in sys.argv[1:]:
+        if os.path.isdir(arg):
+            if recursedown(arg): bad = 1
+        elif os.path.islink(arg):
+            err(arg + ': will not process symbolic links\n')
+            bad = 1
+        else:
+            if fix(arg): bad = 1
+    sys.exit(bad)
+
+ispythonprog = re.compile('^[a-zA-Z0-9_]+\.py$')
+def ispython(name):
+    return ispythonprog.match(name) >= 0
+
+def recursedown(dirname):
+    dbg('recursedown(%r)\n' % (dirname,))
+    bad = 0
+    try:
+        names = os.listdir(dirname)
+    except os.error, msg:
+        err('%s: cannot list directory: %r\n' % (dirname, msg))
+        return 1
+    names.sort()
+    subdirs = []
+    for name in names:
+        if name in (os.curdir, os.pardir): continue
+        fullname = os.path.join(dirname, name)
+        if os.path.islink(fullname): pass
+        elif os.path.isdir(fullname):
+            subdirs.append(fullname)
+        elif ispython(name):
+            if fix(fullname): bad = 1
+    for fullname in subdirs:
+        if recursedown(fullname): bad = 1
+    return bad
+
+def fix(filename):
+##  dbg('fix(%r)\n' % (filename,))
+    try:
+        f = open(filename, 'r')
+    except IOError, msg:
+        err('%s: cannot open: %r\n' % (filename, msg))
+        return 1
+    head, tail = os.path.split(filename)
+    tempname = os.path.join(head, '@' + tail)
+    g = None
+    # If we find a match, we rewind the file and start over but
+    # now copy everything to a temp file.
+    lineno = 0
+    while 1:
+        line = f.readline()
+        if not line: break
+        lineno = lineno + 1
+        while line[-2:] == '\\\n':
+            nextline = f.readline()
+            if not nextline: break
+            line = line + nextline
+            lineno = lineno + 1
+        newline = fixline(line)
+        if newline != line:
+            if g is None:
+                try:
+                    g = open(tempname, 'w')
+                except IOError, msg:
+                    f.close()
+                    err('%s: cannot create: %r\n' % (tempname, msg))
+                    return 1
+                f.seek(0)
+                lineno = 0
+                rep(filename + ':\n')
+                continue # restart from the beginning
+            rep(repr(lineno) + '\n')
+            rep('< ' + line)
+            rep('> ' + newline)
+        if g is not None:
+            g.write(newline)
+
+    # End of file
+    f.close()
+    if not g: return 0 # No changes
+
+    # Finishing touch -- move files
+
+    # First copy the file's mode to the temp file
+    try:
+        statbuf = os.stat(filename)
+        os.chmod(tempname, statbuf[ST_MODE] & 07777)
+    except os.error, msg:
+        err('%s: warning: chmod failed (%r)\n' % (tempname, msg))
+    # Then make a backup of the original file as filename~
+    try:
+        os.rename(filename, filename + '~')
+    except os.error, msg:
+        err('%s: warning: backup failed (%r)\n' % (filename, msg))
+    # Now move the temp file to the original file
+    try:
+        os.rename(tempname, filename)
+    except os.error, msg:
+        err('%s: rename failed (%r)\n' % (filename, msg))
+        return 1
+    # Return succes
+    return 0
+
+# This expression doesn't catch *all* class definition headers,
+# but it's pretty darn close.
+classexpr = '^([ \t]*class +[a-zA-Z0-9_]+) *( *) *((=.*)?):'
+classprog = re.compile(classexpr)
+
+# Expressions for finding base class expressions.
+baseexpr = '^ *(.*) *( *) *$'
+baseprog = re.compile(baseexpr)
+
+def fixline(line):
+    if classprog.match(line) < 0: # No 'class' keyword -- no change
+        return line
+
+    (a0, b0), (a1, b1), (a2, b2) = classprog.regs[:3]
+    # a0, b0 = Whole match (up to ':')
+    # a1, b1 = First subexpression (up to classname)
+    # a2, b2 = Second subexpression (=.*)
+    head = line[:b1]
+    tail = line[b0:] # Unmatched rest of line
+
+    if a2 == b2: # No base classes -- easy case
+        return head + ':' + tail
+
+    # Get rid of leading '='
+    basepart = line[a2+1:b2]
+
+    # Extract list of base expressions
+    bases = basepart.split(',')
+
+    # Strip trailing '()' from each base expression
+    for i in range(len(bases)):
+        if baseprog.match(bases[i]) >= 0:
+            x1, y1 = baseprog.regs[1]
+            bases[i] = bases[i][x1:y1]
+
+    # Join the bases back again and build the new line
+    basepart = ', '.join(bases)
+
+    return head + '(' + basepart + '):' + tail
+
+if __name__ == '__main__':
+    main()


Property changes on: vendor/Python/current/Tools/scripts/classfix.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/scripts/cleanfuture.py
===================================================================
--- vendor/Python/current/Tools/scripts/cleanfuture.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/cleanfuture.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,276 @@
+#! /usr/bin/env python
+
+"""cleanfuture [-d][-r][-v] path ...
+
+-d  Dry run.  Analyze, but don't make any changes to, files.
+-r  Recurse.  Search for all .py files in subdirectories too.
+-v  Verbose.  Print informative msgs.
+
+Search Python (.py) files for future statements, and remove the features
+from such statements that are already mandatory in the version of Python
+you're using.
+
+Pass one or more file and/or directory paths.  When a directory path, all
+.py files within the directory will be examined, and, if the -r option is
+given, likewise recursively for subdirectories.
+
+Overwrites files in place, renaming the originals with a .bak extension. If
+cleanfuture finds nothing to change, the file is left alone.  If cleanfuture
+does change a file, the changed file is a fixed-point (i.e., running
+cleanfuture on the resulting .py file won't change it again, at least not
+until you try it again with a later Python release).
+
+Limitations:  You can do these things, but this tool won't help you then:
+
++ A future statement cannot be mixed with any other statement on the same
+  physical line (separated by semicolon).
+
++ A future statement cannot contain an "as" clause.
+
+Example:  Assuming you're using Python 2.2, if a file containing
+
+from __future__ import nested_scopes, generators
+
+is analyzed by cleanfuture, the line is rewritten to
+
+from __future__ import generators
+
+because nested_scopes is no longer optional in 2.2 but generators is.
+"""
+
+import __future__
+import tokenize
+import os
+import sys
+
+dryrun  = 0
+recurse = 0
+verbose = 0
+
+def errprint(*args):
+    strings = map(str, args)
+    msg = ' '.join(strings)
+    if msg[-1:] != '\n':
+        msg += '\n'
+    sys.stderr.write(msg)
+
+def main():
+    import getopt
+    global verbose, recurse, dryrun
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], "drv")
+    except getopt.error, msg:
+        errprint(msg)
+        return
+    for o, a in opts:
+        if o == '-d':
+            dryrun += 1
+        elif o == '-r':
+            recurse += 1
+        elif o == '-v':
+            verbose += 1
+    if not args:
+        errprint("Usage:", __doc__)
+        return
+    for arg in args:
+        check(arg)
+
+def check(file):
+    if os.path.isdir(file) and not os.path.islink(file):
+        if verbose:
+            print "listing directory", file
+        names = os.listdir(file)
+        for name in names:
+            fullname = os.path.join(file, name)
+            if ((recurse and os.path.isdir(fullname) and
+                 not os.path.islink(fullname))
+                or name.lower().endswith(".py")):
+                check(fullname)
+        return
+
+    if verbose:
+        print "checking", file, "...",
+    try:
+        f = open(file)
+    except IOError, msg:
+        errprint("%r: I/O Error: %s" % (file, str(msg)))
+        return
+
+    ff = FutureFinder(f, file)
+    changed = ff.run()
+    if changed:
+        ff.gettherest()
+    f.close()
+    if changed:
+        if verbose:
+            print "changed."
+            if dryrun:
+                print "But this is a dry run, so leaving it alone."
+        for s, e, line in changed:
+            print "%r lines %d-%d" % (file, s+1, e+1)
+            for i in range(s, e+1):
+                print ff.lines[i],
+            if line is None:
+                print "-- deleted"
+            else:
+                print "-- change to:"
+                print line,
+        if not dryrun:
+            bak = file + ".bak"
+            if os.path.exists(bak):
+                os.remove(bak)
+            os.rename(file, bak)
+            if verbose:
+                print "renamed", file, "to", bak
+            g = open(file, "w")
+            ff.write(g)
+            g.close()
+            if verbose:
+                print "wrote new", file
+    else:
+        if verbose:
+            print "unchanged."
+
+class FutureFinder:
+
+    def __init__(self, f, fname):
+        self.f = f
+        self.fname = fname
+        self.ateof = 0
+        self.lines = [] # raw file lines
+
+        # List of (start_index, end_index, new_line) triples.
+        self.changed = []
+
+    # Line-getter for tokenize.
+    def getline(self):
+        if self.ateof:
+            return ""
+        line = self.f.readline()
+        if line == "":
+            self.ateof = 1
+        else:
+            self.lines.append(line)
+        return line
+
+    def run(self):
+        STRING = tokenize.STRING
+        NL = tokenize.NL
+        NEWLINE = tokenize.NEWLINE
+        COMMENT = tokenize.COMMENT
+        NAME = tokenize.NAME
+        OP = tokenize.OP
+
+        changed = self.changed
+        get = tokenize.generate_tokens(self.getline).next
+        type, token, (srow, scol), (erow, ecol), line = get()
+
+        # Chew up initial comments and blank lines (if any).
+        while type in (COMMENT, NL, NEWLINE):
+            type, token, (srow, scol), (erow, ecol), line = get()
+
+        # Chew up docstring (if any -- and it may be implicitly catenated!).
+        while type is STRING:
+            type, token, (srow, scol), (erow, ecol), line = get()
+
+        # Analyze the future stmts.
+        while 1:
+            # Chew up comments and blank lines (if any).
+            while type in (COMMENT, NL, NEWLINE):
+                type, token, (srow, scol), (erow, ecol), line = get()
+
+            if not (type is NAME and token == "from"):
+                break
+            startline = srow - 1    # tokenize is one-based
+            type, token, (srow, scol), (erow, ecol), line = get()
+
+            if not (type is NAME and token == "__future__"):
+                break
+            type, token, (srow, scol), (erow, ecol), line = get()
+
+            if not (type is NAME and token == "import"):
+                break
+            type, token, (srow, scol), (erow, ecol), line = get()
+
+            # Get the list of features.
+            features = []
+            while type is NAME:
+                features.append(token)
+                type, token, (srow, scol), (erow, ecol), line = get()
+
+                if not (type is OP and token == ','):
+                    break
+                type, token, (srow, scol), (erow, ecol), line = get()
+
+            # A trailing comment?
+            comment = None
+            if type is COMMENT:
+                comment = token
+                type, token, (srow, scol), (erow, ecol), line = get()
+
+            if type is not NEWLINE:
+                errprint("Skipping file %r; can't parse line %d:\n%s" %
+                         (self.fname, srow, line))
+                return []
+
+            endline = srow - 1
+
+            # Check for obsolete features.
+            okfeatures = []
+            for f in features:
+                object = getattr(__future__, f, None)
+                if object is None:
+                    # A feature we don't know about yet -- leave it in.
+                    # They'll get a compile-time error when they compile
+                    # this program, but that's not our job to sort out.
+                    okfeatures.append(f)
+                else:
+                    released = object.getMandatoryRelease()
+                    if released is None or released <= sys.version_info:
+                        # Withdrawn or obsolete.
+                        pass
+                    else:
+                        okfeatures.append(f)
+
+            # Rewrite the line if at least one future-feature is obsolete.
+            if len(okfeatures) < len(features):
+                if len(okfeatures) == 0:
+                    line = None
+                else:
+                    line = "from __future__ import "
+                    line += ', '.join(okfeatures)
+                    if comment is not None:
+                        line += ' ' + comment
+                    line += '\n'
+                changed.append((startline, endline, line))
+
+            # Loop back for more future statements.
+
+        return changed
+
+    def gettherest(self):
+        if self.ateof:
+            self.therest = ''
+        else:
+            self.therest = self.f.read()
+
+    def write(self, f):
+        changed = self.changed
+        assert changed
+        # Prevent calling this again.
+        self.changed = []
+        # Apply changes in reverse order.
+        changed.reverse()
+        for s, e, line in changed:
+            if line is None:
+                # pure deletion
+                del self.lines[s:e+1]
+            else:
+                self.lines[s:e+1] = [line]
+        f.writelines(self.lines)
+        # Copy over the remainder of the file.
+        if self.therest:
+            f.write(self.therest)
+
+if __name__ == '__main__':
+    main()

Added: vendor/Python/current/Tools/scripts/combinerefs.py
===================================================================
--- vendor/Python/current/Tools/scripts/combinerefs.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/combinerefs.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,127 @@
+#! /usr/bin/env python
+
+"""
+combinerefs path
+
+A helper for analyzing PYTHONDUMPREFS output.
+
+When the PYTHONDUMPREFS envar is set in a debug build, at Python shutdown
+time Py_Finalize() prints the list of all live objects twice:  first it
+prints the repr() of each object while the interpreter is still fully intact.
+After cleaning up everything it can, it prints all remaining live objects
+again, but the second time just prints their addresses, refcounts, and type
+names (because the interpreter has been torn down, calling repr methods at
+this point can get into infinite loops or blow up).
+
+Save all this output into a file, then run this script passing the path to
+that file.  The script finds both output chunks, combines them, then prints
+a line of output for each object still alive at the end:
+
+    address refcnt typename repr
+
+address is the address of the object, in whatever format the platform C
+produces for a %p format code.
+
+refcnt is of the form
+
+    "[" ref "]"
+
+when the object's refcount is the same in both PYTHONDUMPREFS output blocks,
+or
+
+    "[" ref_before "->" ref_after "]"
+
+if the refcount changed.
+
+typename is object->ob_type->tp_name, extracted from the second PYTHONDUMPREFS
+output block.
+
+repr is repr(object), extracted from the first PYTHONDUMPREFS output block.
+CAUTION:  If object is a container type, it may not actually contain all the
+objects shown in the repr:  the repr was captured from the first output block,
+and some of the containees may have been released since then.  For example,
+it's common for the line showing the dict of interned strings to display
+strings that no longer exist at the end of Py_Finalize; this can be recognized
+(albeit painfully) because such containees don't have a line of their own.
+
+The objects are listed in allocation order, with most-recently allocated
+printed first, and the first object allocated printed last.
+
+
+Simple examples:
+
+    00857060 [14] str '__len__'
+
+The str object '__len__' is alive at shutdown time, and both PYTHONDUMPREFS
+output blocks said there were 14 references to it.  This is probably due to
+C modules that intern the string "__len__" and keep a reference to it in a
+file static.
+
+    00857038 [46->5] tuple ()
+
+46-5 = 41 references to the empty tuple were removed by the cleanup actions
+between the times PYTHONDUMPREFS produced output.
+
+    00858028 [1025->1456] str '<dummy key>'
+
+The string '<dummy key>', which is used in dictobject.c to overwrite a real
+key that gets deleted, grew several hundred references during cleanup.  It
+suggests that stuff did get removed from dicts by cleanup, but that the dicts
+themselves are staying alive for some reason. """
+
+import re
+import sys
+
+# Generate lines from fileiter.  If whilematch is true, continue reading
+# while the regexp object pat matches line.  If whilematch is false, lines
+# are read so long as pat doesn't match them.  In any case, the first line
+# that doesn't match pat (when whilematch is true), or that does match pat
+# (when whilematch is false), is lost, and fileiter will resume at the line
+# following it.
+def read(fileiter, pat, whilematch):
+    for line in fileiter:
+        if bool(pat.match(line)) == whilematch:
+            yield line
+        else:
+            break
+
+def combine(fname):
+    f = file(fname)
+    fi = iter(f)
+
+    for line in read(fi, re.compile(r'^Remaining objects:$'), False):
+        pass
+
+    crack = re.compile(r'([a-zA-Z\d]+) \[(\d+)\] (.*)')
+    addr2rc = {}
+    addr2guts = {}
+    before = 0
+    for line in read(fi, re.compile(r'^Remaining object addresses:$'), False):
+        m = crack.match(line)
+        if m:
+            addr, addr2rc[addr], addr2guts[addr] = m.groups()
+            before += 1
+        else:
+            print '??? skipped:', line
+
+    after = 0
+    for line in read(fi, crack, True):
+        after += 1
+        m = crack.match(line)
+        assert m
+        addr, rc, guts = m.groups() # guts is type name here
+        if addr not in addr2rc:
+            print '??? new object created while tearing down:', line.rstrip()
+            continue
+        print addr,
+        if rc == addr2rc[addr]:
+            print '[%s]' % rc,
+        else:
+            print '[%s->%s]' % (addr2rc[addr], rc),
+        print guts, addr2guts[addr]
+
+    f.close()
+    print "%d objects before, %d after" % (before, after)
+
+if __name__ == '__main__':
+    combine(sys.argv[1])

Added: vendor/Python/current/Tools/scripts/copytime.py
===================================================================
--- vendor/Python/current/Tools/scripts/copytime.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/copytime.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,26 @@
+#! /usr/bin/env python
+
+# Copy one file's atime and mtime to another
+
+import sys
+import os
+from stat import ST_ATIME, ST_MTIME # Really constants 7 and 8
+
+def main():
+    if len(sys.argv) <> 3:
+        sys.stderr.write('usage: copytime source destination\n')
+        sys.exit(2)
+    file1, file2 = sys.argv[1], sys.argv[2]
+    try:
+        stat1 = os.stat(file1)
+    except os.error:
+        sys.stderr.write(file1 + ': cannot stat\n')
+        sys.exit(1)
+    try:
+        os.utime(file2, (stat1[ST_ATIME], stat1[ST_MTIME]))
+    except os.error:
+        sys.stderr.write(file2 + ': cannot change time\n')
+        sys.exit(2)
+
+if __name__ == '__main__':
+    main()


Property changes on: vendor/Python/current/Tools/scripts/copytime.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/scripts/crlf.py
===================================================================
--- vendor/Python/current/Tools/scripts/crlf.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/crlf.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,23 @@
+#! /usr/bin/env python
+"Replace CRLF with LF in argument files.  Print names of changed files."
+
+import sys, os
+
+def main():
+    for filename in sys.argv[1:]:
+        if os.path.isdir(filename):
+            print filename, "Directory!"
+            continue
+        data = open(filename, "rb").read()
+        if '\0' in data:
+            print filename, "Binary!"
+            continue
+        newdata = data.replace("\r\n", "\n")
+        if newdata != data:
+            print filename
+            f = open(filename, "wb")
+            f.write(newdata)
+            f.close()
+
+if __name__ == '__main__':
+    main()


Property changes on: vendor/Python/current/Tools/scripts/crlf.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/scripts/cvsfiles.py
===================================================================
--- vendor/Python/current/Tools/scripts/cvsfiles.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/cvsfiles.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,72 @@
+#! /usr/bin/env python
+
+"""Print a list of files that are mentioned in CVS directories.
+
+Usage: cvsfiles.py [-n file] [directory] ...
+
+If the '-n file' option is given, only files under CVS that are newer
+than the given file are printed; by default, all files under CVS are
+printed.  As a special case, if a file does not exist, it is always
+printed.
+"""
+
+import os
+import sys
+import stat
+import getopt
+
+cutofftime = 0
+
+def main():
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], "n:")
+    except getopt.error, msg:
+        print msg
+        print __doc__,
+        return 1
+    global cutofftime
+    newerfile = None
+    for o, a in opts:
+        if o == '-n':
+            cutofftime = getmtime(a)
+    if args:
+        for arg in args:
+            process(arg)
+    else:
+        process(".")
+
+def process(dir):
+    cvsdir = 0
+    subdirs = []
+    names = os.listdir(dir)
+    for name in names:
+        fullname = os.path.join(dir, name)
+        if name == "CVS":
+            cvsdir = fullname
+        else:
+            if os.path.isdir(fullname):
+                if not os.path.islink(fullname):
+                    subdirs.append(fullname)
+    if cvsdir:
+        entries = os.path.join(cvsdir, "Entries")
+        for e in open(entries).readlines():
+            words = e.split('/')
+            if words[0] == '' and words[1:]:
+                name = words[1]
+                fullname = os.path.join(dir, name)
+                if cutofftime and getmtime(fullname) <= cutofftime:
+                    pass
+                else:
+                    print fullname
+    for sub in subdirs:
+        process(sub)
+
+def getmtime(filename):
+    try:
+        st = os.stat(filename)
+    except os.error:
+        return 0
+    return st[stat.ST_MTIME]
+
+if __name__ == '__main__':
+    main()


Property changes on: vendor/Python/current/Tools/scripts/cvsfiles.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/scripts/db2pickle.py
===================================================================
--- vendor/Python/current/Tools/scripts/db2pickle.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/db2pickle.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,135 @@
+#!/usr/bin/env python
+
+"""
+Synopsis: %(prog)s [-h|-g|-b|-r|-a] dbfile [ picklefile ]
+
+Convert the database file given on the command line to a pickle
+representation.  The optional flags indicate the type of the database:
+
+    -a - open using anydbm
+    -b - open as bsddb btree file
+    -d - open as dbm file
+    -g - open as gdbm file
+    -h - open as bsddb hash file
+    -r - open as bsddb recno file
+
+The default is hash.  If a pickle file is named it is opened for write
+access (deleting any existing data).  If no pickle file is named, the pickle
+output is written to standard output.
+
+"""
+
+import getopt
+try:
+    import bsddb
+except ImportError:
+    bsddb = None
+try:
+    import dbm
+except ImportError:
+    dbm = None
+try:
+    import gdbm
+except ImportError:
+    gdbm = None
+try:
+    import anydbm
+except ImportError:
+    anydbm = None
+import sys
+try:
+    import cPickle as pickle
+except ImportError:
+    import pickle
+
+prog = sys.argv[0]
+
+def usage():
+    sys.stderr.write(__doc__ % globals())
+
+def main(args):
+    try:
+        opts, args = getopt.getopt(args, "hbrdag",
+                                   ["hash", "btree", "recno", "dbm",
+                                    "gdbm", "anydbm"])
+    except getopt.error:
+        usage()
+        return 1
+
+    if len(args) == 0 or len(args) > 2:
+        usage()
+        return 1
+    elif len(args) == 1:
+        dbfile = args[0]
+        pfile = sys.stdout
+    else:
+        dbfile = args[0]
+        try:
+            pfile = open(args[1], 'wb')
+        except IOError:
+            sys.stderr.write("Unable to open %s\n" % args[1])
+            return 1
+
+    dbopen = None
+    for opt, arg in opts:
+        if opt in ("-h", "--hash"):
+            try:
+                dbopen = bsddb.hashopen
+            except AttributeError:
+                sys.stderr.write("bsddb module unavailable.\n")
+                return 1
+        elif opt in ("-b", "--btree"):
+            try:
+                dbopen = bsddb.btopen
+            except AttributeError:
+                sys.stderr.write("bsddb module unavailable.\n")
+                return 1
+        elif opt in ("-r", "--recno"):
+            try:
+                dbopen = bsddb.rnopen
+            except AttributeError:
+                sys.stderr.write("bsddb module unavailable.\n")
+                return 1
+        elif opt in ("-a", "--anydbm"):
+            try:
+                dbopen = anydbm.open
+            except AttributeError:
+                sys.stderr.write("anydbm module unavailable.\n")
+                return 1
+        elif opt in ("-g", "--gdbm"):
+            try:
+                dbopen = gdbm.open
+            except AttributeError:
+                sys.stderr.write("gdbm module unavailable.\n")
+                return 1
+        elif opt in ("-d", "--dbm"):
+            try:
+                dbopen = dbm.open
+            except AttributeError:
+                sys.stderr.write("dbm module unavailable.\n")
+                return 1
+    if dbopen is None:
+        if bsddb is None:
+            sys.stderr.write("bsddb module unavailable - ")
+            sys.stderr.write("must specify dbtype.\n")
+            return 1
+        else:
+            dbopen = bsddb.hashopen
+
+    try:
+        db = dbopen(dbfile, 'r')
+    except bsddb.error:
+        sys.stderr.write("Unable to open %s.  " % dbfile)
+        sys.stderr.write("Check for format or version mismatch.\n")
+        return 1
+
+    for k in db.keys():
+        pickle.dump((k, db[k]), pfile, 1==1)
+
+    db.close()
+    pfile.close()
+
+    return 0
+
+if __name__ == "__main__":
+    sys.exit(main(sys.argv[1:]))

Added: vendor/Python/current/Tools/scripts/diff.py
===================================================================
--- vendor/Python/current/Tools/scripts/diff.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/diff.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,49 @@
+""" Command line interface to difflib.py providing diffs in four formats:
+
+* ndiff:    lists every line and highlights interline changes.
+* context:  highlights clusters of changes in a before/after format.
+* unified:  highlights clusters of changes in an inline format.
+* html:     generates side by side comparison with change highlights.
+
+"""
+
+import sys, os, time, difflib, optparse
+
+def main():
+
+    usage = "usage: %prog [options] fromfile tofile"
+    parser = optparse.OptionParser(usage)
+    parser.add_option("-c", action="store_true", default=False, help='Produce a context format diff (default)')
+    parser.add_option("-u", action="store_true", default=False, help='Produce a unified format diff')
+    parser.add_option("-m", action="store_true", default=False, help='Produce HTML side by side diff (can use -c and -l in conjunction)')
+    parser.add_option("-n", action="store_true", default=False, help='Produce a ndiff format diff')
+    parser.add_option("-l", "--lines", type="int", default=3, help='Set number of context lines (default 3)')
+    (options, args) = parser.parse_args()
+
+    if len(args) == 0:
+        parser.print_help()
+        sys.exit(1)
+    if len(args) != 2:
+        parser.error("need to specify both a fromfile and tofile")
+
+    n = options.lines
+    fromfile, tofile = args
+
+    fromdate = time.ctime(os.stat(fromfile).st_mtime)
+    todate = time.ctime(os.stat(tofile).st_mtime)
+    fromlines = open(fromfile, 'U').readlines()
+    tolines = open(tofile, 'U').readlines()
+
+    if options.u:
+        diff = difflib.unified_diff(fromlines, tolines, fromfile, tofile, fromdate, todate, n=n)
+    elif options.n:
+        diff = difflib.ndiff(fromlines, tolines)
+    elif options.m:
+        diff = difflib.HtmlDiff().make_file(fromlines,tolines,fromfile,tofile,context=options.c,numlines=n)
+    else:
+        diff = difflib.context_diff(fromlines, tolines, fromfile, tofile, fromdate, todate, n=n)
+
+    sys.stdout.writelines(diff)
+
+if __name__ == '__main__':
+    main()

Added: vendor/Python/current/Tools/scripts/dutree.doc
===================================================================
--- vendor/Python/current/Tools/scripts/dutree.doc	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/dutree.doc	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,54 @@
+Path: cwi.nl!sun4nl!mcsun!uunet!cs.utexas.edu!convex!usenet
+From: tchrist at convex.COM (Tom Christiansen)
+Newsgroups: comp.lang.perl
+Subject: Re: The problems of Perl (Re: Question (silly?))
+Message-ID: <1992Jan17.053115.4220 at convex.com>
+Date: 17 Jan 92 05:31:15 GMT
+References: <17458 at ector.cs.purdue.edu> <1992Jan16.165347.25583 at cherokee.uswest.com> <=#Hues+4 at cs.psu.edu>
+Sender: usenet at convex.com (news access account)
+Reply-To: tchrist at convex.COM (Tom Christiansen)
+Organization: CONVEX Realtime Development, Colorado Springs, CO
+Lines: 83
+Nntp-Posting-Host: pixel.convex.com
+
+From the keyboard of flee at cs.psu.edu (Felix Lee):
+:And Perl is definitely awkward with data types.  I haven't yet found a
+:pleasant way of shoving non-trivial data types into Perl's grammar.
+
+Yes, it's pretty aweful at that, alright.  Sometimes I write perl programs
+that need them, and sometimes it just takes a little creativity.  But
+sometimes it's not worth it.  I actually wrote a C program the other day
+(gasp) because I didn't want to deal with a game matrix with six links per node.
+
+:Here's a very simple problem that's tricky to express in Perl: process
+:the output of "du" to produce output that's indented to reflect the
+:tree structure, and with each subtree sorted by size.  Something like:
+:    434 /etc
+:      |     344 .
+:      |      50 install
+:      |      35 uucp
+:      |       3 nserve
+:      |       |       2 .
+:      |       |       1 auth.info
+:      |       1 sm
+:      |       1 sm.bak
+
+At first I thought I could just keep one local list around
+at once, but this seems inherently recursive.  Which means 
+I need an real recursive data structure.  Maybe you could
+do it with one of the %assoc arrays Larry uses in the begat
+programs, but I broke down and got dirty.  I think the hardest
+part was matching Felix's desired output exactly.  It's not 
+blazingly fast: I should probably inline the &childof routine,
+but it *was* faster to write than I could have written the 
+equivalent C program.
+
+
+--tom
+
+--
+"GUIs normally make it simple to accomplish simple actions and impossible
+to accomplish complex actions."   --Doug Gwyn  (22/Jun/91 in comp.unix.wizards)
+
+     Tom Christiansen           tchrist at convex.com      convex!tchrist
+

Added: vendor/Python/current/Tools/scripts/dutree.py
===================================================================
--- vendor/Python/current/Tools/scripts/dutree.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/dutree.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,60 @@
+#! /usr/bin/env python
+# Format du output in a tree shape
+
+import os, sys, errno
+
+def main():
+    p = os.popen('du ' + ' '.join(sys.argv[1:]), 'r')
+    total, d = None, {}
+    for line in p.readlines():
+        i = 0
+        while line[i] in '0123456789': i = i+1
+        size = eval(line[:i])
+        while line[i] in ' \t': i = i+1
+        filename = line[i:-1]
+        comps = filename.split('/')
+        if comps[0] == '': comps[0] = '/'
+        if comps[len(comps)-1] == '': del comps[len(comps)-1]
+        total, d = store(size, comps, total, d)
+    try:
+        display(total, d)
+    except IOError, e:
+        if e.errno != errno.EPIPE:
+            raise
+
+def store(size, comps, total, d):
+    if comps == []:
+        return size, d
+    if not d.has_key(comps[0]):
+        d[comps[0]] = None, {}
+    t1, d1 = d[comps[0]]
+    d[comps[0]] = store(size, comps[1:], t1, d1)
+    return total, d
+
+def display(total, d):
+    show(total, d, '')
+
+def show(total, d, prefix):
+    if not d: return
+    list = []
+    sum = 0
+    for key in d.keys():
+        tsub, dsub = d[key]
+        list.append((tsub, key))
+        if tsub is not None: sum = sum + tsub
+##  if sum < total:
+##      list.append((total - sum, os.curdir))
+    list.sort()
+    list.reverse()
+    width = len(repr(list[0][0]))
+    for tsub, key in list:
+        if tsub is None:
+            psub = prefix
+        else:
+            print prefix + repr(tsub).rjust(width) + ' ' + key
+            psub = prefix + ' '*(width-1) + '|' + ' '*(len(key)+1)
+        if d.has_key(key):
+            show(tsub, d[key][1], psub)
+
+if __name__ == '__main__':
+    main()


Property changes on: vendor/Python/current/Tools/scripts/dutree.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/scripts/eptags.py
===================================================================
--- vendor/Python/current/Tools/scripts/eptags.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/eptags.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,56 @@
+#! /usr/bin/env python
+"""Create a TAGS file for Python programs, usable with GNU Emacs.
+
+usage: eptags pyfiles...
+
+The output TAGS file is usable with Emacs version 18, 19, 20.
+Tagged are:
+ - functions (even inside other defs or classes)
+ - classes
+
+eptags warns about files it cannot open.
+eptags will not give warnings about duplicate tags.
+
+BUGS:
+   Because of tag duplication (methods with the same name in different
+   classes), TAGS files are not very useful for most object-oriented
+   python projects.
+"""
+import sys,re
+
+expr = r'^[ \t]*(def|class)[ \t]+([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*[:\(]'
+matcher = re.compile(expr)
+
+def treat_file(filename, outfp):
+    """Append tags found in file named 'filename' to the open file 'outfp'"""
+    try:
+        fp = open(filename, 'r')
+    except:
+        sys.stderr.write('Cannot open %s\n'%filename)
+        return
+    charno = 0
+    lineno = 0
+    tags = []
+    size = 0
+    while 1:
+        line = fp.readline()
+        if not line:
+            break
+        lineno = lineno + 1
+        m = matcher.search(line)
+        if m:
+            tag = m.group(0) + '\177%d,%d\n' % (lineno, charno)
+            tags.append(tag)
+            size = size + len(tag)
+        charno = charno + len(line)
+    outfp.write('\f\n%s,%d\n' % (filename,size))
+    for tag in tags:
+        outfp.write(tag)
+
+def main():
+    outfp = open('TAGS', 'w')
+    for filename in sys.argv[1:]:
+        treat_file(filename, outfp)
+
+if __name__=="__main__":
+    main()


Property changes on: vendor/Python/current/Tools/scripts/eptags.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/scripts/finddiv.py
===================================================================
--- vendor/Python/current/Tools/scripts/finddiv.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/finddiv.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,89 @@
+#! /usr/bin/env python
+
+"""finddiv - a grep-like tool that looks for division operators.
+
+Usage: finddiv [-l] file_or_directory ...
+
+For directory arguments, all files in the directory whose name ends in
+.py are processed, and subdirectories are processed recursively.
+
+This actually tokenizes the files to avoid false hits in comments or
+strings literals.
+
+By default, this prints all lines containing a / or /= operator, in
+grep -n style.  With the -l option specified, it prints the filename
+of files that contain at least one / or /= operator.
+"""
+
+import os
+import sys
+import getopt
+import tokenize
+
+def main():
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], "lh")
+    except getopt.error, msg:
+        usage(msg)
+        return 2
+    if not args:
+        usage("at least one file argument is required")
+        return 2
+    listnames = 0
+    for o, a in opts:
+        if o == "-h":
+            print __doc__
+            return
+        if o == "-l":
+            listnames = 1
+    exit = None
+    for filename in args:
+        x = process(filename, listnames)
+        exit = exit or x
+    return exit
+
+def usage(msg):
+    sys.stderr.write("%s: %s\n" % (sys.argv[0], msg))
+    sys.stderr.write("Usage: %s [-l] file ...\n" % sys.argv[0])
+    sys.stderr.write("Try `%s -h' for more information.\n" % sys.argv[0])
+
+def process(filename, listnames):
+    if os.path.isdir(filename):
+        return processdir(filename, listnames)
+    try:
+        fp = open(filename)
+    except IOError, msg:
+        sys.stderr.write("Can't open: %s\n" % msg)
+        return 1
+    g = tokenize.generate_tokens(fp.readline)
+    lastrow = None
+    for type, token, (row, col), end, line in g:
+        if token in ("/", "/="):
+            if listnames:
+                print filename
+                break
+            if row != lastrow:
+                lastrow = row
+                print "%s:%d:%s" % (filename, row, line),
+    fp.close()
+
+def processdir(dir, listnames):
+    try:
+        names = os.listdir(dir)
+    except os.error, msg:
+        sys.stderr.write("Can't list directory: %s\n" % dir)
+        return 1
+    files = []
+    for name in names:
+        fn = os.path.join(dir, name)
+        if os.path.normcase(fn).endswith(".py") or os.path.isdir(fn):
+            files.append(fn)
+    files.sort(lambda a, b: cmp(os.path.normcase(a), os.path.normcase(b)))
+    exit = None
+    for fn in files:
+        x = process(fn, listnames)
+        exit = exit or x
+    return exit
+
+if __name__ == "__main__":
+    sys.exit(main())


Property changes on: vendor/Python/current/Tools/scripts/finddiv.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/scripts/findlinksto.py
===================================================================
--- vendor/Python/current/Tools/scripts/findlinksto.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/findlinksto.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,43 @@
+#! /usr/bin/env python
+
+# findlinksto
+#
+# find symbolic links to a path matching a regular expression
+
+import os
+import sys
+import re
+import getopt
+
+def main():
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], '')
+        if len(args) < 2:
+            raise getopt.GetoptError('not enough arguments', None)
+    except getopt.GetoptError, msg:
+        sys.stdout = sys.stderr
+        print msg
+        print 'usage: findlinksto pattern directory ...'
+        sys.exit(2)
+    pat, dirs = args[0], args[1:]
+    prog = re.compile(pat)
+    for dirname in dirs:
+        os.path.walk(dirname, visit, prog)
+
+def visit(prog, dirname, names):
+    if os.path.islink(dirname):
+        names[:] = []
+        return
+    if os.path.ismount(dirname):
+        print 'descend into', dirname
+    for name in names:
+        name = os.path.join(dirname, name)
+        try:
+            linkto = os.readlink(name)
+            if prog.search(linkto) is not None:
+                print name, '->', linkto
+        except os.error:
+            pass
+
+if __name__ == '__main__':
+    main()


Property changes on: vendor/Python/current/Tools/scripts/findlinksto.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/scripts/findnocoding.py
===================================================================
--- vendor/Python/current/Tools/scripts/findnocoding.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/findnocoding.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,104 @@
+#!/usr/bin/env python
+
+"""List all those Python files that require a coding directive
+
+Usage: nocoding.py dir1 [dir2...]
+"""
+
+__author__ = "Oleg Broytmann, Georg Brandl"
+
+import sys, os, re, getopt
+
+# our pysource module finds Python source files
+try:
+    import pysource
+except:
+    # emulate the module with a simple os.walk
+    class pysource:
+        has_python_ext = looks_like_python = can_be_compiled = None
+        def walk_python_files(self, paths, *args, **kwargs):
+            for path in paths:
+                if os.path.isfile(path):
+                    yield path.endswith(".py")
+                elif os.path.isdir(path):
+                    for root, dirs, files in os.walk(path):
+                        for filename in files:
+                            if filename.endswith(".py"):
+                                yield os.path.join(root, filename)
+    pysource = pysource()
+
+
+    print >>sys.stderr, ("The pysource module is not available; "
+                         "no sophisticated Python source file search will be done.")
+
+
+decl_re = re.compile(r"coding[=:]\s*([-\w.]+)")
+
+def get_declaration(line):
+    match = decl_re.search(line)
+    if match:
+        return match.group(1)
+    return ''
+
+def has_correct_encoding(text, codec):
+    try:
+        unicode(text, codec)
+    except UnicodeDecodeError:
+        return False
+    else:
+        return True
+
+def needs_declaration(fullpath):
+    try:
+        infile = open(fullpath, 'rU')
+    except IOError: # Oops, the file was removed - ignore it
+        return None
+
+    line1 = infile.readline()
+    line2 = infile.readline()
+
+    if get_declaration(line1) or get_declaration(line2):
+        # the file does have an encoding declaration, so trust it
+        infile.close()
+        return False
+
+    # check the whole file for non-ASCII characters
+    rest = infile.read()
+    infile.close()
+
+    if has_correct_encoding(line1+line2+rest, "ascii"):
+        return False
+
+    return True
+
+
+usage = """Usage: %s [-cd] paths...
+    -c: recognize Python source files trying to compile them
+    -d: debug output""" % sys.argv[0]
+
+try:
+    opts, args = getopt.getopt(sys.argv[1:], 'cd')
+except getopt.error, msg:
+    print >>sys.stderr, msg
+    print >>sys.stderr, usage
+    sys.exit(1)
+
+is_python = pysource.looks_like_python
+debug = False
+
+for o, a in opts:
+    if o == '-c':
+        is_python = pysource.can_be_compiled
+    elif o == '-d':
+        debug = True
+
+if not args:
+    print >>sys.stderr, usage
+    sys.exit(1)
+
+for fullpath in pysource.walk_python_files(args, is_python):
+    if debug:
+        print "Testing for coding: %s" % fullpath
+    result = needs_declaration(fullpath)
+    if result:
+        print fullpath


Property changes on: vendor/Python/current/Tools/scripts/findnocoding.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/scripts/fixcid.py
===================================================================
--- vendor/Python/current/Tools/scripts/fixcid.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/fixcid.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,314 @@
+#! /usr/bin/env python
+
+# Perform massive identifier substitution on C source files.
+# This actually tokenizes the files (to some extent) so it can
+# avoid making substitutions inside strings or comments.
+# Inside strings, substitutions are never made; inside comments,
+# it is a user option (off by default).
+#
+# The substitutions are read from one or more files whose lines,
+# when not empty, after stripping comments starting with #,
+# must contain exactly two words separated by whitespace: the
+# old identifier and its replacement.
+#
+# The option -r reverses the sense of the substitutions (this may be
+# useful to undo a particular substitution).
+#
+# If the old identifier is prefixed with a '*' (with no intervening
+# whitespace), then it will not be substituted inside comments.
+#
+# Command line arguments are files or directories to be processed.
+# Directories are searched recursively for files whose name looks
+# like a C file (ends in .h or .c).  The special filename '-' means
+# operate in filter mode: read stdin, write stdout.
+#
+# Symbolic links are always ignored (except as explicit directory
+# arguments).
+#
+# The original files are kept as back-up with a "~" suffix.
+#
+# Changes made are reported to stdout in a diff-like format.
+#
+# NB: by changing only the function fixline() you can turn this
+# into a program for different changes to C source files; by
+# changing the function wanted() you can make a different selection of
+# files.
+
+import sys
+import re
+import os
+from stat import *
+import getopt
+
+err = sys.stderr.write
+dbg = err
+rep = sys.stdout.write
+
+def usage():
+    progname = sys.argv[0]
+    err('Usage: ' + progname +
+              ' [-c] [-r] [-s file] ... file-or-directory ...\n')
+    err('\n')
+    err('-c           : substitute inside comments\n')
+    err('-r           : reverse direction for following -s options\n')
+    err('-s substfile : add a file of substitutions\n')
+    err('\n')
+    err('Each non-empty non-comment line in a substitution file must\n')
+    err('contain exactly two words: an identifier and its replacement.\n')
+    err('Comments start with a # character and end at end of line.\n')
+    err('If an identifier is preceded with a *, it is not substituted\n')
+    err('inside a comment even when -c is specified.\n')
+
+def main():
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], 'crs:')
+    except getopt.error, msg:
+        err('Options error: ' + str(msg) + '\n')
+        usage()
+        sys.exit(2)
+    bad = 0
+    if not args: # No arguments
+        usage()
+        sys.exit(2)
+    for opt, arg in opts:
+        if opt == '-c':
+            setdocomments()
+        if opt == '-r':
+            setreverse()
+        if opt == '-s':
+            addsubst(arg)
+    for arg in args:
+        if os.path.isdir(arg):
+            if recursedown(arg): bad = 1
+        elif os.path.islink(arg):
+            err(arg + ': will not process symbolic links\n')
+            bad = 1
+        else:
+            if fix(arg): bad = 1
+    sys.exit(bad)
+
+# Change this regular expression to select a different set of files
+Wanted = '^[a-zA-Z0-9_]+\.[ch]$'
+def wanted(name):
+    return re.match(Wanted, name) >= 0
+
+def recursedown(dirname):
+    dbg('recursedown(%r)\n' % (dirname,))
+    bad = 0
+    try:
+        names = os.listdir(dirname)
+    except os.error, msg:
+        err(dirname + ': cannot list directory: ' + str(msg) + '\n')
+        return 1
+    names.sort()
+    subdirs = []
+    for name in names:
+        if name in (os.curdir, os.pardir): continue
+        fullname = os.path.join(dirname, name)
+        if os.path.islink(fullname): pass
+        elif os.path.isdir(fullname):
+            subdirs.append(fullname)
+        elif wanted(name):
+            if fix(fullname): bad = 1
+    for fullname in subdirs:
+        if recursedown(fullname): bad = 1
+    return bad
+
+def fix(filename):
+##  dbg('fix(%r)\n' % (filename,))
+    if filename == '-':
+        # Filter mode
+        f = sys.stdin
+        g = sys.stdout
+    else:
+        # File replacement mode
+        try:
+            f = open(filename, 'r')
+        except IOError, msg:
+            err(filename + ': cannot open: ' + str(msg) + '\n')
+            return 1
+        head, tail = os.path.split(filename)
+        tempname = os.path.join(head, '@' + tail)
+        g = None
+    # If we find a match, we rewind the file and start over but
+    # now copy everything to a temp file.
+    lineno = 0
+    initfixline()
+    while 1:
+        line = f.readline()
+        if not line: break
+        lineno = lineno + 1
+        while line[-2:] == '\\\n':
+            nextline = f.readline()
+            if not nextline: break
+            line = line + nextline
+            lineno = lineno + 1
+        newline = fixline(line)
+        if newline != line:
+            if g is None:
+                try:
+                    g = open(tempname, 'w')
+                except IOError, msg:
+                    f.close()
+                    err(tempname+': cannot create: '+
+                        str(msg)+'\n')
+                    return 1
+                f.seek(0)
+                lineno = 0
+                initfixline()
+                rep(filename + ':\n')
+                continue # restart from the beginning
+            rep(repr(lineno) + '\n')
+            rep('< ' + line)
+            rep('> ' + newline)
+        if g is not None:
+            g.write(newline)
+
+    # End of file
+    if filename == '-': return 0 # Done in filter mode
+    f.close()
+    if not g: return 0 # No changes
+
+    # Finishing touch -- move files
+
+    # First copy the file's mode to the temp file
+    try:
+        statbuf = os.stat(filename)
+        os.chmod(tempname, statbuf[ST_MODE] & 07777)
+    except os.error, msg:
+        err(tempname + ': warning: chmod failed (' + str(msg) + ')\n')
+    # Then make a backup of the original file as filename~
+    try:
+        os.rename(filename, filename + '~')
+    except os.error, msg:
+        err(filename + ': warning: backup failed (' + str(msg) + ')\n')
+    # Now move the temp file to the original file
+    try:
+        os.rename(tempname, filename)
+    except os.error, msg:
+        err(filename + ': rename failed (' + str(msg) + ')\n')
+        return 1
+    # Return succes
+    return 0
+
+# Tokenizing ANSI C (partly)
+
+Identifier = '\(struct \)?[a-zA-Z_][a-zA-Z0-9_]+'
+String = '"\([^\n\\"]\|\\\\.\)*"'
+Char = '\'\([^\n\\\']\|\\\\.\)*\''
+CommentStart = '/\*'
+CommentEnd = '\*/'
+
+Hexnumber = '0[xX][0-9a-fA-F]*[uUlL]*'
+Octnumber = '0[0-7]*[uUlL]*'
+Decnumber = '[1-9][0-9]*[uUlL]*'
+Intnumber = Hexnumber + '\|' + Octnumber + '\|' + Decnumber
+Exponent = '[eE][-+]?[0-9]+'
+Pointfloat = '\([0-9]+\.[0-9]*\|\.[0-9]+\)\(' + Exponent + '\)?'
+Expfloat = '[0-9]+' + Exponent
+Floatnumber = Pointfloat + '\|' + Expfloat
+Number = Floatnumber + '\|' + Intnumber
+
+# Anything else is an operator -- don't list this explicitly because of '/*'
+
+OutsideComment = (Identifier, Number, String, Char, CommentStart)
+OutsideCommentPattern = '(' + '|'.join(OutsideComment) + ')'
+OutsideCommentProgram = re.compile(OutsideCommentPattern)
+
+InsideComment = (Identifier, Number, CommentEnd)
+InsideCommentPattern = '(' + '|'.join(InsideComment) + ')'
+InsideCommentProgram = re.compile(InsideCommentPattern)
+
+def initfixline():
+    global Program
+    Program = OutsideCommentProgram
+
+def fixline(line):
+    global Program
+##  print '-->', repr(line)
+    i = 0
+    while i < len(line):
+        i = Program.search(line, i)
+        if i < 0: break
+        found = Program.group(0)
+##      if Program is InsideCommentProgram: print '...',
+##      else: print '   ',
+##      print found
+        if len(found) == 2:
+            if found == '/*':
+                Program = InsideCommentProgram
+            elif found == '*/':
+                Program = OutsideCommentProgram
+        n = len(found)
+        if Dict.has_key(found):
+            subst = Dict[found]
+            if Program is InsideCommentProgram:
+                if not Docomments:
+                    print 'Found in comment:', found
+                    i = i + n
+                    continue
+                if NotInComment.has_key(found):
+##                  print 'Ignored in comment:',
+##                  print found, '-->', subst
+##                  print 'Line:', line,
+                    subst = found
+##              else:
+##                  print 'Substituting in comment:',
+##                  print found, '-->', subst
+##                  print 'Line:', line,
+            line = line[:i] + subst + line[i+n:]
+            n = len(subst)
+        i = i + n
+    return line
+
+Docomments = 0
+def setdocomments():
+    global Docomments
+    Docomments = 1
+
+Reverse = 0
+def setreverse():
+    global Reverse
+    Reverse = (not Reverse)
+
+Dict = {}
+NotInComment = {}
+def addsubst(substfile):
+    try:
+        fp = open(substfile, 'r')
+    except IOError, msg:
+        err(substfile + ': cannot read substfile: ' + str(msg) + '\n')
+        sys.exit(1)
+    lineno = 0
+    while 1:
+        line = fp.readline()
+        if not line: break
+        lineno = lineno + 1
+        try:
+            i = line.index('#')
+        except ValueError:
+            i = -1          # Happens to delete trailing \n
+        words = line[:i].split()
+        if not words: continue
+        if len(words) == 3 and words[0] == 'struct':
+            words[:2] = [words[0] + ' ' + words[1]]
+        elif len(words) <> 2:
+            err(substfile + '%s:%r: warning: bad line: %r' % (substfile, lineno, line))
+            continue
+        if Reverse:
+            [value, key] = words
+        else:
+            [key, value] = words
+        if value[0] == '*':
+            value = value[1:]
+        if key[0] == '*':
+            key = key[1:]
+            NotInComment[key] = value
+        if Dict.has_key(key):
+            err('%s:%r: warning: overriding: %r %r\n' % (substfile, lineno, key, value))
+            err('%s:%r: warning: previous: %r\n' % (substfile, lineno, Dict[key]))
+        Dict[key] = value
+    fp.close()
+
+if __name__ == '__main__':
+    main()


Property changes on: vendor/Python/current/Tools/scripts/fixcid.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/scripts/fixdiv.py
===================================================================
--- vendor/Python/current/Tools/scripts/fixdiv.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/fixdiv.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,380 @@
+#! /usr/bin/env python
+
+"""fixdiv - tool to fix division operators.
+
+To use this tool, first run `python -Qwarnall yourscript.py 2>warnings'.
+This runs the script `yourscript.py' while writing warning messages
+about all uses of the classic division operator to the file
+`warnings'.  The warnings look like this:
+
+  <file>:<line>: DeprecationWarning: classic <type> division
+
+The warnings are written to stderr, so you must use `2>' for the I/O
+redirect.  I know of no way to redirect stderr on Windows in a DOS
+box, so you will have to modify the script to set sys.stderr to some
+kind of log file if you want to do this on Windows.
+
+The warnings are not limited to the script; modules imported by the
+script may also trigger warnings.  In fact a useful technique is to
+write a test script specifically intended to exercise all code in a
+particular module or set of modules.
+
+Then run `python fixdiv.py warnings'.  This first reads the warnings,
+looking for classic division warnings, and sorts them by file name and
+line number.  Then, for each file that received at least one warning,
+it parses the file and tries to match the warnings up to the division
+operators found in the source code.  If it is successful, it writes
+its findings to stdout, preceded by a line of dashes and a line of the
+form:
+
+  Index: <file>
+
+If the only findings found are suggestions to change a / operator into
+a // operator, the output is acceptable input for the Unix 'patch'
+program.
+
+Here are the possible messages on stdout (N stands for a line number):
+
+- A plain-diff-style change ('NcN', a line marked by '<', a line
+  containing '---', and a line marked by '>'):
+
+  A / operator was found that should be changed to //.  This is the
+  recommendation when only int and/or long arguments were seen.
+
+- 'True division / operator at line N' and a line marked by '=':
+
+  A / operator was found that can remain unchanged.  This is the
+  recommendation when only float and/or complex arguments were seen.
+
+- 'Ambiguous / operator (..., ...) at line N', line marked by '?':
+
+  A / operator was found for which int or long as well as float or
+  complex arguments were seen.  This is highly unlikely; if it occurs,
+  you may have to restructure the code to keep the classic semantics,
+  or maybe you don't care about the classic semantics.
+
+- 'No conclusive evidence on line N', line marked by '*':
+
+  A / operator was found for which no warnings were seen.  This could
+  be code that was never executed, or code that was only executed
+  with user-defined objects as arguments.  You will have to
+  investigate further.  Note that // can be overloaded separately from
+  /, using __floordiv__.  True division can also be separately
+  overloaded, using __truediv__.  Classic division should be the same
+  as either of those.  (XXX should I add a warning for division on
+  user-defined objects, to disambiguate this case from code that was
+  never executed?)
+
+- 'Phantom ... warnings for line N', line marked by '*':
+
+  A warning was seen for a line not containing a / operator.  The most
+  likely cause is a warning about code executed by 'exec' or eval()
+  (see note below), or an indirect invocation of the / operator, for
+  example via the div() function in the operator module.  It could
+  also be caused by a change to the file between the time the test
+  script was run to collect warnings and the time fixdiv was run.
+
+- 'More than one / operator in line N'; or
+  'More than one / operator per statement in lines N-N':
+
+  The scanner found more than one / operator on a single line, or in a
+  statement split across multiple lines.  Because the warnings
+  framework doesn't (and can't) show the offset within the line, and
+  the code generator doesn't always give the correct line number for
+  operations in a multi-line statement, we can't be sure whether all
+  operators in the statement were executed.  To be on the safe side,
+  by default a warning is issued about this case.  In practice, these
+  cases are usually safe, and the -m option suppresses these warning.
+
+- 'Can't find the / operator in line N', line marked by '*':
+
+  This really shouldn't happen.  It means that the tokenize module
+  reported a '/' operator but the line it returns didn't contain a '/'
+  character at the indicated position.
+
+- 'Bad warning for line N: XYZ', line marked by '*':
+
+  This really shouldn't happen.  It means that a 'classic XYZ
+  division' warning was read with XYZ being something other than
+  'int', 'long', 'float', or 'complex'.
+
+Notes:
+
+- The augmented assignment operator /= is handled the same way as the
+  / operator.
+
+- This tool never looks at the // operator; no warnings are ever
+  generated for use of this operator.
+
+- This tool never looks at the / operator when a future division
+  statement is in effect; no warnings are generated in this case, and
+  because the tool only looks at files for which at least one classic
+  division warning was seen, it will never look at files containing a
+  future division statement.
+
+- Warnings may be issued for code not read from a file, but executed
+  using an exec statement or the eval() function.  These may have
+  <string> in the filename position, in which case the fixdiv script
+  will attempt and fail to open a file named '<string>' and issue a
+  warning about this failure; or these may be reported as 'Phantom'
+  warnings (see above).  You're on your own to deal with these.  You
+  could make all recommended changes and add a future division
+  statement to all affected files, and then re-run the test script; it
+  should not issue any warnings.  If there are any, and you have a
+  hard time tracking down where they are generated, you can use the
+  -Werror option to force an error instead of a first warning,
+  generating a traceback.
+
+- The tool should be run from the same directory as that from which
+  the original script was run, otherwise it won't be able to open
+  files given by relative pathnames.
+"""
+
+import sys
+import getopt
+import re
+import tokenize
+
+multi_ok = 0
+
+def main():
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], "hm")
+    except getopt.error, msg:
+        usage(msg)
+        return 2
+    for o, a in opts:
+        if o == "-h":
+            print __doc__
+            return
+        if o == "-m":
+            global multi_ok
+            multi_ok = 1
+    if not args:
+        usage("at least one file argument is required")
+        return 2
+    if args[1:]:
+        sys.stderr.write("%s: extra file arguments ignored\n", sys.argv[0])
+    warnings = readwarnings(args[0])
+    if warnings is None:
+        return 1
+    files = warnings.keys()
+    if not files:
+        print "No classic division warnings read from", args[0]
+        return
+    files.sort()
+    exit = None
+    for filename in files:
+        x = process(filename, warnings[filename])
+        exit = exit or x
+    return exit
+
+def usage(msg):
+    sys.stderr.write("%s: %s\n" % (sys.argv[0], msg))
+    sys.stderr.write("Usage: %s [-m] warnings\n" % sys.argv[0])
+    sys.stderr.write("Try `%s -h' for more information.\n" % sys.argv[0])
+
+PATTERN = ("^(.+?):(\d+): DeprecationWarning: "
+           "classic (int|long|float|complex) division$")
+
+def readwarnings(warningsfile):
+    prog = re.compile(PATTERN)
+    try:
+        f = open(warningsfile)
+    except IOError, msg:
+        sys.stderr.write("can't open: %s\n" % msg)
+        return
+    warnings = {}
+    while 1:
+        line = f.readline()
+        if not line:
+            break
+        m = prog.match(line)
+        if not m:
+            if line.find("division") >= 0:
+                sys.stderr.write("Warning: ignored input " + line)
+            continue
+        filename, lineno, what = m.groups()
+        list = warnings.get(filename)
+        if list is None:
+            warnings[filename] = list = []
+        list.append((int(lineno), intern(what)))
+    f.close()
+    return warnings
+
+def process(filename, list):
+    print "-"*70
+    assert list # if this fails, readwarnings() is broken
+    try:
+        fp = open(filename)
+    except IOError, msg:
+        sys.stderr.write("can't open: %s\n" % msg)
+        return 1
+    print "Index:", filename
+    f = FileContext(fp)
+    list.sort()
+    index = 0 # list[:index] has been processed, list[index:] is still to do
+    g = tokenize.generate_tokens(f.readline)
+    while 1:
+        startlineno, endlineno, slashes = lineinfo = scanline(g)
+        if startlineno is None:
+            break
+        assert startlineno <= endlineno is not None
+        orphans = []
+        while index < len(list) and list[index][0] < startlineno:
+            orphans.append(list[index])
+            index += 1
+        if orphans:
+            reportphantomwarnings(orphans, f)
+        warnings = []
+        while index < len(list) and list[index][0] <= endlineno:
+            warnings.append(list[index])
+            index += 1
+        if not slashes and not warnings:
+            pass
+        elif slashes and not warnings:
+            report(slashes, "No conclusive evidence")
+        elif warnings and not slashes:
+            reportphantomwarnings(warnings, f)
+        else:
+            if len(slashes) > 1:
+                if not multi_ok:
+                    rows = []
+                    lastrow = None
+                    for (row, col), line in slashes:
+                        if row == lastrow:
+                            continue
+                        rows.append(row)
+                        lastrow = row
+                    assert rows
+                    if len(rows) == 1:
+                        print "*** More than one / operator in line", rows[0]
+                    else:
+                        print "*** More than one / operator per statement",
+                        print "in lines %d-%d" % (rows[0], rows[-1])
+            intlong = []
+            floatcomplex = []
+            bad = []
+            for lineno, what in warnings:
+                if what in ("int", "long"):
+                    intlong.append(what)
+                elif what in ("float", "complex"):
+                    floatcomplex.append(what)
+                else:
+                    bad.append(what)
+            lastrow = None
+            for (row, col), line in slashes:
+                if row == lastrow:
+                    continue
+                lastrow = row
+                line = chop(line)
+                if line[col:col+1] != "/":
+                    print "*** Can't find the / operator in line %d:" % row
+                    print "*", line
+                    continue
+                if bad:
+                    print "*** Bad warning for line %d:" % row, bad
+                    print "*", line
+                elif intlong and not floatcomplex:
+                    print "%dc%d" % (row, row)
+                    print "<", line
+                    print "---"
+                    print ">", line[:col] + "/" + line[col:]
+                elif floatcomplex and not intlong:
+                    print "True division / operator at line %d:" % row
+                    print "=", line
+                elif intlong and floatcomplex:
+                    print "*** Ambiguous / operator (%s, %s) at line %d:" % (
+                        "|".join(intlong), "|".join(floatcomplex), row)
+                    print "?", line
+    fp.close()
+
+def reportphantomwarnings(warnings, f):
+    blocks = []
+    lastrow = None
+    lastblock = None
+    for row, what in warnings:
+        if row != lastrow:
+            lastblock = [row]
+            blocks.append(lastblock)
+        lastblock.append(what)
+    for block in blocks:
+        row = block[0]
+        whats = "/".join(block[1:])
+        print "*** Phantom %s warnings for line %d:" % (whats, row)
+        f.report(row, mark="*")
+
+def report(slashes, message):
+    lastrow = None
+    for (row, col), line in slashes:
+        if row != lastrow:
+            print "*** %s on line %d:" % (message, row)
+            print "*", chop(line)
+            lastrow = row
+
+class FileContext:
+    def __init__(self, fp, window=5, lineno=1):
+        self.fp = fp
+        self.window = 5
+        self.lineno = 1
+        self.eoflookahead = 0
+        self.lookahead = []
+        self.buffer = []
+    def fill(self):
+        while len(self.lookahead) < self.window and not self.eoflookahead:
+            line = self.fp.readline()
+            if not line:
+                self.eoflookahead = 1
+                break
+            self.lookahead.append(line)
+    def readline(self):
+        self.fill()
+        if not self.lookahead:
+            return ""
+        line = self.lookahead.pop(0)
+        self.buffer.append(line)
+        self.lineno += 1
+        return line
+    def truncate(self):
+        del self.buffer[-window:]
+    def __getitem__(self, index):
+        self.fill()
+        bufstart = self.lineno - len(self.buffer)
+        lookend = self.lineno + len(self.lookahead)
+        if bufstart <= index < self.lineno:
+            return self.buffer[index - bufstart]
+        if self.lineno <= index < lookend:
+            return self.lookahead[index - self.lineno]
+        raise KeyError
+    def report(self, first, last=None, mark="*"):
+        if last is None:
+            last = first
+        for i in range(first, last+1):
+            try:
+                line = self[first]
+            except KeyError:
+                line = "<missing line>"
+            print mark, chop(line)
+
+def scanline(g):
+    slashes = []
+    startlineno = None
+    endlineno = None
+    for type, token, start, end, line in g:
+        endlineno = end[0]
+        if startlineno is None:
+            startlineno = endlineno
+        if token in ("/", "/="):
+            slashes.append((start, line))
+        if type == tokenize.NEWLINE:
+            break
+    return startlineno, endlineno, slashes
+
+def chop(line):
+    if line.endswith("\n"):
+        return line[:-1]
+    else:
+        return line
+
+if __name__ == "__main__":
+    sys.exit(main())


Property changes on: vendor/Python/current/Tools/scripts/fixdiv.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/scripts/fixheader.py
===================================================================
--- vendor/Python/current/Tools/scripts/fixheader.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/fixheader.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,49 @@
+#! /usr/bin/env python
+
+# Add some standard cpp magic to a header file
+
+import sys
+
+def main():
+    args = sys.argv[1:]
+    for filename in args:
+        process(filename)
+
+def process(filename):
+    try:
+        f = open(filename, 'r')
+    except IOError, msg:
+        sys.stderr.write('%s: can\'t open: %s\n' % (filename, str(msg)))
+        return
+    data = f.read()
+    f.close()
+    if data[:2] <> '/*':
+        sys.stderr.write('%s does not begin with C comment\n' % filename)
+        return
+    try:
+        f = open(filename, 'w')
+    except IOError, msg:
+        sys.stderr.write('%s: can\'t write: %s\n' % (filename, str(msg)))
+        return
+    sys.stderr.write('Processing %s ...\n' % filename)
+    magic = 'Py_'
+    for c in filename:
+        if ord(c)<=0x80 and c.isalnum():
+            magic = magic + c.upper()
+        else: magic = magic + '_'
+    sys.stdout = f
+    print '#ifndef', magic
+    print '#define', magic
+    print '#ifdef __cplusplus'
+    print 'extern "C" {'
+    print '#endif'
+    print
+    f.write(data)
+    print
+    print '#ifdef __cplusplus'
+    print '}'
+    print '#endif'
+    print '#endif /*', '!'+magic, '*/'
+
+if __name__ == '__main__':
+    main()


Property changes on: vendor/Python/current/Tools/scripts/fixheader.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/scripts/fixnotice.py
===================================================================
--- vendor/Python/current/Tools/scripts/fixnotice.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/fixnotice.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,113 @@
+#! /usr/bin/env python
+
+"""(Ostensibly) fix copyright notices in files.
+
+Actually, this sript will simply replace a block of text in a file from one
+string to another.  It will only do this once though, i.e. not globally
+throughout the file.  It writes a backup file and then does an os.rename()
+dance for atomicity.
+
+Usage: fixnotices.py [options] [filenames]
+Options:
+    -h / --help
+        Print this message and exit
+
+    --oldnotice=file
+        Use the notice in the file as the old (to be replaced) string, instead
+        of the hard coded value in the script.
+
+    --newnotice=file
+        Use the notice in the file as the new (replacement) string, instead of
+        the hard coded value in the script.
+
+    --dry-run
+        Don't actually make the changes, but print out the list of files that
+        would change.  When used with -v, a status will be printed for every
+        file.
+
+    -v / --verbose
+        Print a message for every file looked at, indicating whether the file
+        is changed or not.
+"""
+
+OLD_NOTICE = """/***********************************************************
+Copyright (c) 2000, BeOpen.com.
+Copyright (c) 1995-2000, Corporation for National Research Initiatives.
+Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
+All rights reserved.
+
+See the file "Misc/COPYRIGHT" for information on usage and
+redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+******************************************************************/
+"""
+import os
+import sys
+import getopt
+
+NEW_NOTICE = ""
+DRYRUN = 0
+VERBOSE = 0
+
+
+def usage(code, msg=''):
+    print __doc__ % globals()
+    if msg:
+        print msg
+    sys.exit(code)
+
+
+def main():
+    global DRYRUN, OLD_NOTICE, NEW_NOTICE, VERBOSE
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], 'hv',
+                                   ['help', 'oldnotice=', 'newnotice=',
+                                    'dry-run', 'verbose'])
+    except getopt.error, msg:
+        usage(1, msg)
+
+    for opt, arg in opts:
+        if opt in ('-h', '--help'):
+            usage(0)
+        elif opt in ('-v', '--verbose'):
+            VERBOSE = 1
+        elif opt == '--dry-run':
+            DRYRUN = 1
+        elif opt == '--oldnotice':
+            fp = open(arg)
+            OLD_NOTICE = fp.read()
+            fp.close()
+        elif opt == '--newnotice':
+            fp = open(arg)
+            NEW_NOTICE = fp.read()
+            fp.close()
+
+    for arg in args:
+        process(arg)
+
+
+def process(file):
+    f = open(file)
+    data = f.read()
+    f.close()
+    i = data.find(OLD_NOTICE)
+    if i < 0:
+        if VERBOSE:
+            print 'no change:', file
+        return
+    elif DRYRUN or VERBOSE:
+        print '   change:', file
+    if DRYRUN:
+        # Don't actually change the file
+        return
+    data = data[:i] + NEW_NOTICE + data[i+len(OLD_NOTICE):]
+    new = file + ".new"
+    backup = file + ".bak"
+    f = open(new, "w")
+    f.write(data)
+    f.close()
+    os.rename(file, backup)
+    os.rename(new, file)
+
+
+if __name__ == '__main__':
+    main()


Property changes on: vendor/Python/current/Tools/scripts/fixnotice.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/scripts/fixps.py
===================================================================
--- vendor/Python/current/Tools/scripts/fixps.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/fixps.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,33 @@
+#!/usr/bin/env python
+
+# Fix Python script(s) to reference the interpreter via /usr/bin/env python.
+# Warning: this overwrites the file without making a backup.
+
+import sys
+import re
+
+
+def main():
+    for filename in sys.argv[1:]:
+        try:
+            f = open(filename, 'r')
+        except IOError, msg:
+            print filename, ': can\'t open :', msg
+            continue
+        line = f.readline()
+        if not re.match('^#! */usr/local/bin/python', line):
+            print filename, ': not a /usr/local/bin/python script'
+            f.close()
+            continue
+        rest = f.read()
+        f.close()
+        line = re.sub('/usr/local/bin/python',
+                      '/usr/bin/env python', line)
+        print filename, ':', repr(line)
+        f = open(filename, "w")
+        f.write(line)
+        f.write(rest)
+        f.close()
+
+if __name__ == '__main__':
+    main()


Property changes on: vendor/Python/current/Tools/scripts/fixps.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/scripts/ftpmirror.py
===================================================================
--- vendor/Python/current/Tools/scripts/ftpmirror.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/ftpmirror.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,400 @@
+#! /usr/bin/env python
+
+"""Mirror a remote ftp subtree into a local directory tree.
+
+usage: ftpmirror [-v] [-q] [-i] [-m] [-n] [-r] [-s pat]
+                 [-l username [-p passwd [-a account]]]
+                 hostname[:port] [remotedir [localdir]]
+-v: verbose
+-q: quiet
+-i: interactive mode
+-m: macintosh server (NCSA telnet 2.4) (implies -n -s '*.o')
+-n: don't log in
+-r: remove local files/directories no longer pertinent
+-l username [-p passwd [-a account]]: login info (default .netrc or anonymous)
+-s pat: skip files matching pattern
+hostname: remote host w/ optional port separated by ':'
+remotedir: remote directory (default initial)
+localdir: local directory (default current)
+"""
+
+import os
+import sys
+import time
+import getopt
+import ftplib
+import netrc
+from fnmatch import fnmatch
+
+# Print usage message and exit
+def usage(*args):
+    sys.stdout = sys.stderr
+    for msg in args: print msg
+    print __doc__
+    sys.exit(2)
+
+verbose = 1 # 0 for -q, 2 for -v
+interactive = 0
+mac = 0
+rmok = 0
+nologin = 0
+skippats = ['.', '..', '.mirrorinfo']
+
+# Main program: parse command line and start processing
+def main():
+    global verbose, interactive, mac, rmok, nologin
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], 'a:bil:mnp:qrs:v')
+    except getopt.error, msg:
+        usage(msg)
+    login = ''
+    passwd = ''
+    account = ''
+    if not args: usage('hostname missing')
+    host = args[0]
+    port = 0
+    if ':' in host:
+        host, port = host.split(':', 1)
+        port = int(port)
+    try:
+        auth = netrc.netrc().authenticators(host)
+        if auth is not None:
+            login, account, passwd = auth
+    except (netrc.NetrcParseError, IOError):
+        pass
+    for o, a in opts:
+        if o == '-l': login = a
+        if o == '-p': passwd = a
+        if o == '-a': account = a
+        if o == '-v': verbose = verbose + 1
+        if o == '-q': verbose = 0
+        if o == '-i': interactive = 1
+        if o == '-m': mac = 1; nologin = 1; skippats.append('*.o')
+        if o == '-n': nologin = 1
+        if o == '-r': rmok = 1
+        if o == '-s': skippats.append(a)
+    remotedir = ''
+    localdir = ''
+    if args[1:]:
+        remotedir = args[1]
+        if args[2:]:
+            localdir = args[2]
+            if args[3:]: usage('too many arguments')
+    #
+    f = ftplib.FTP()
+    if verbose: print "Connecting to '%s%s'..." % (host,
+                                                   (port and ":%d"%port or ""))
+    f.connect(host,port)
+    if not nologin:
+        if verbose:
+            print 'Logging in as %r...' % (login or 'anonymous')
+        f.login(login, passwd, account)
+    if verbose: print 'OK.'
+    pwd = f.pwd()
+    if verbose > 1: print 'PWD =', repr(pwd)
+    if remotedir:
+        if verbose > 1: print 'cwd(%s)' % repr(remotedir)
+        f.cwd(remotedir)
+        if verbose > 1: print 'OK.'
+        pwd = f.pwd()
+        if verbose > 1: print 'PWD =', repr(pwd)
+    #
+    mirrorsubdir(f, localdir)
+
+# Core logic: mirror one subdirectory (recursively)
+def mirrorsubdir(f, localdir):
+    pwd = f.pwd()
+    if localdir and not os.path.isdir(localdir):
+        if verbose: print 'Creating local directory', repr(localdir)
+        try:
+            makedir(localdir)
+        except os.error, msg:
+            print "Failed to establish local directory", repr(localdir)
+            return
+    infofilename = os.path.join(localdir, '.mirrorinfo')
+    try:
+        text = open(infofilename, 'r').read()
+    except IOError, msg:
+        text = '{}'
+    try:
+        info = eval(text)
+    except (SyntaxError, NameError):
+        print 'Bad mirror info in', repr(infofilename)
+        info = {}
+    subdirs = []
+    listing = []
+    if verbose: print 'Listing remote directory %r...' % (pwd,)
+    f.retrlines('LIST', listing.append)
+    filesfound = []
+    for line in listing:
+        if verbose > 1: print '-->', repr(line)
+        if mac:
+            # Mac listing has just filenames;
+            # trailing / means subdirectory
+            filename = line.strip()
+            mode = '-'
+            if filename[-1:] == '/':
+                filename = filename[:-1]
+                mode = 'd'
+            infostuff = ''
+        else:
+            # Parse, assuming a UNIX listing
+            words = line.split(None, 8)
+            if len(words) < 6:
+                if verbose > 1: print 'Skipping short line'
+                continue
+            filename = words[-1].lstrip()
+            i = filename.find(" -> ")
+            if i >= 0:
+                # words[0] had better start with 'l'...
+                if verbose > 1:
+                    print 'Found symbolic link %r' % (filename,)
+                linkto = filename[i+4:]
+                filename = filename[:i]
+            infostuff = words[-5:-1]
+            mode = words[0]
+        skip = 0
+        for pat in skippats:
+            if fnmatch(filename, pat):
+                if verbose > 1:
+                    print 'Skip pattern', repr(pat),
+                    print 'matches', repr(filename)
+                skip = 1
+                break
+        if skip:
+            continue
+        if mode[0] == 'd':
+            if verbose > 1:
+                print 'Remembering subdirectory', repr(filename)
+            subdirs.append(filename)
+            continue
+        filesfound.append(filename)
+        if info.has_key(filename) and info[filename] == infostuff:
+            if verbose > 1:
+                print 'Already have this version of',repr(filename)
+            continue
+        fullname = os.path.join(localdir, filename)
+        tempname = os.path.join(localdir, '@'+filename)
+        if interactive:
+            doit = askabout('file', filename, pwd)
+            if not doit:
+                if not info.has_key(filename):
+                    info[filename] = 'Not retrieved'
+                continue
+        try:
+            os.unlink(tempname)
+        except os.error:
+            pass
+        if mode[0] == 'l':
+            if verbose:
+                print "Creating symlink %r -> %r" % (filename, linkto)
+            try:
+                os.symlink(linkto, tempname)
+            except IOError, msg:
+                print "Can't create %r: %s" % (tempname, msg)
+                continue
+        else:
+            try:
+                fp = open(tempname, 'wb')
+            except IOError, msg:
+                print "Can't create %r: %s" % (tempname, msg)
+                continue
+            if verbose:
+                print 'Retrieving %r from %r as %r...' % (filename, pwd, fullname)
+            if verbose:
+                fp1 = LoggingFile(fp, 1024, sys.stdout)
+            else:
+                fp1 = fp
+            t0 = time.time()
+            try:
+                f.retrbinary('RETR ' + filename,
+                             fp1.write, 8*1024)
+            except ftplib.error_perm, msg:
+                print msg
+            t1 = time.time()
+            bytes = fp.tell()
+            fp.close()
+            if fp1 != fp:
+                fp1.close()
+        try:
+            os.unlink(fullname)
+        except os.error:
+            pass            # Ignore the error
+        try:
+            os.rename(tempname, fullname)
+        except os.error, msg:
+            print "Can't rename %r to %r: %s" % (tempname, fullname, msg)
+            continue
+        info[filename] = infostuff
+        writedict(info, infofilename)
+        if verbose and mode[0] != 'l':
+            dt = t1 - t0
+            kbytes = bytes / 1024.0
+            print int(round(kbytes)),
+            print 'Kbytes in',
+            print int(round(dt)),
+            print 'seconds',
+            if t1 > t0:
+                print '(~%d Kbytes/sec)' % \
+                          int(round(kbytes/dt),)
+            print
+    #
+    # Remove files from info that are no longer remote
+    deletions = 0
+    for filename in info.keys():
+        if filename not in filesfound:
+            if verbose:
+                print "Removing obsolete info entry for",
+                print repr(filename), "in", repr(localdir or ".")
+            del info[filename]
+            deletions = deletions + 1
+    if deletions:
+        writedict(info, infofilename)
+    #
+    # Remove local files that are no longer in the remote directory
+    try:
+        if not localdir: names = os.listdir(os.curdir)
+        else: names = os.listdir(localdir)
+    except os.error:
+        names = []
+    for name in names:
+        if name[0] == '.' or info.has_key(name) or name in subdirs:
+            continue
+        skip = 0
+        for pat in skippats:
+            if fnmatch(name, pat):
+                if verbose > 1:
+                    print 'Skip pattern', repr(pat),
+                    print 'matches', repr(name)
+                skip = 1
+                break
+        if skip:
+            continue
+        fullname = os.path.join(localdir, name)
+        if not rmok:
+            if verbose:
+                print 'Local file', repr(fullname),
+                print 'is no longer pertinent'
+            continue
+        if verbose: print 'Removing local file/dir', repr(fullname)
+        remove(fullname)
+    #
+    # Recursively mirror subdirectories
+    for subdir in subdirs:
+        if interactive:
+            doit = askabout('subdirectory', subdir, pwd)
+            if not doit: continue
+        if verbose: print 'Processing subdirectory', repr(subdir)
+        localsubdir = os.path.join(localdir, subdir)
+        pwd = f.pwd()
+        if verbose > 1:
+            print 'Remote directory now:', repr(pwd)
+            print 'Remote cwd', repr(subdir)
+        try:
+            f.cwd(subdir)
+        except ftplib.error_perm, msg:
+            print "Can't chdir to", repr(subdir), ":", repr(msg)
+        else:
+            if verbose: print 'Mirroring as', repr(localsubdir)
+            mirrorsubdir(f, localsubdir)
+            if verbose > 1: print 'Remote cwd ..'
+            f.cwd('..')
+        newpwd = f.pwd()
+        if newpwd != pwd:
+            print 'Ended up in wrong directory after cd + cd ..'
+            print 'Giving up now.'
+            break
+        else:
+            if verbose > 1: print 'OK.'
+
+# Helper to remove a file or directory tree
+def remove(fullname):
+    if os.path.isdir(fullname) and not os.path.islink(fullname):
+        try:
+            names = os.listdir(fullname)
+        except os.error:
+            names = []
+        ok = 1
+        for name in names:
+            if not remove(os.path.join(fullname, name)):
+                ok = 0
+        if not ok:
+            return 0
+        try:
+            os.rmdir(fullname)
+        except os.error, msg:
+            print "Can't remove local directory %r: %s" % (fullname, msg)
+            return 0
+    else:
+        try:
+            os.unlink(fullname)
+        except os.error, msg:
+            print "Can't remove local file %r: %s" % (fullname, msg)
+            return 0
+    return 1
+
+# Wrapper around a file for writing to write a hash sign every block.
+class LoggingFile:
+    def __init__(self, fp, blocksize, outfp):
+        self.fp = fp
+        self.bytes = 0
+        self.hashes = 0
+        self.blocksize = blocksize
+        self.outfp = outfp
+    def write(self, data):
+        self.bytes = self.bytes + len(data)
+        hashes = int(self.bytes) / self.blocksize
+        while hashes > self.hashes:
+            self.outfp.write('#')
+            self.outfp.flush()
+            self.hashes = self.hashes + 1
+        self.fp.write(data)
+    def close(self):
+        self.outfp.write('\n')
+
+# Ask permission to download a file.
+def askabout(filetype, filename, pwd):
+    prompt = 'Retrieve %s %s from %s ? [ny] ' % (filetype, filename, pwd)
+    while 1:
+        reply = raw_input(prompt).strip().lower()
+        if reply in ['y', 'ye', 'yes']:
+            return 1
+        if reply in ['', 'n', 'no', 'nop', 'nope']:
+            return 0
+        print 'Please answer yes or no.'
+
+# Create a directory if it doesn't exist.  Recursively create the
+# parent directory as well if needed.
+def makedir(pathname):
+    if os.path.isdir(pathname):
+        return
+    dirname = os.path.dirname(pathname)
+    if dirname: makedir(dirname)
+    os.mkdir(pathname, 0777)
+
+# Write a dictionary to a file in a way that can be read back using
+# rval() but is still somewhat readable (i.e. not a single long line).
+# Also creates a backup file.
+def writedict(dict, filename):
+    dir, fname = os.path.split(filename)
+    tempname = os.path.join(dir, '@' + fname)
+    backup = os.path.join(dir, fname + '~')
+    try:
+        os.unlink(backup)
+    except os.error:
+        pass
+    fp = open(tempname, 'w')
+    fp.write('{\n')
+    for key, value in dict.items():
+        fp.write('%r: %r,\n' % (key, value))
+    fp.write('}\n')
+    fp.close()
+    try:
+        os.rename(filename, backup)
+    except os.error:
+        pass
+    os.rename(tempname, filename)
+
+
+if __name__ == '__main__':
+    main()


Property changes on: vendor/Python/current/Tools/scripts/ftpmirror.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/scripts/google.py
===================================================================
--- vendor/Python/current/Tools/scripts/google.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/google.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,23 @@
+#! /usr/bin/env python
+
+import sys, webbrowser
+
+def main():
+    args = sys.argv[1:]
+    if not args:
+        print "Usage: %s querystring" % sys.argv[0]
+        return
+    list = []
+    for arg in args:
+        if '+' in arg:
+            arg = arg.replace('+', '%2B')
+        if ' ' in arg:
+            arg = '"%s"' % arg
+        arg = arg.replace(' ', '+')
+        list.append(arg)
+    s = '+'.join(list)
+    url = "http://www.google.com/search?q=%s" % s
+    webbrowser.open(url)
+
+if __name__ == '__main__':
+    main()


Property changes on: vendor/Python/current/Tools/scripts/google.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/scripts/gprof2html.py
===================================================================
--- vendor/Python/current/Tools/scripts/gprof2html.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/gprof2html.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,79 @@
+#! /usr/bin/env python2.3
+
+"""Transform gprof(1) output into useful HTML."""
+
+import re, os, sys, cgi, webbrowser
+
+header = """\
+<html>
+<head>
+  <title>gprof output (%s)</title>
+</head>
+<body>
+<pre>
+"""
+
+trailer = """\
+</pre>
+</body>
+</html>
+"""
+
+def add_escapes(input):
+    for line in input:
+        yield cgi.escape(line)
+
+def main():
+    filename = "gprof.out"
+    if sys.argv[1:]:
+        filename = sys.argv[1]
+    outputfilename = filename + ".html"
+    input = add_escapes(file(filename))
+    output = file(outputfilename, "w")
+    output.write(header % filename)
+    for line in input:
+        output.write(line)
+        if line.startswith(" time"):
+            break
+    labels = {}
+    for line in input:
+        m = re.match(r"(.*  )(\w+)\n", line)
+        if not m:
+            output.write(line)
+            break
+        stuff, fname = m.group(1, 2)
+        labels[fname] = fname
+        output.write('%s<a name="flat:%s" href="#call:%s">%s</a>\n' %
+                     (stuff, fname, fname, fname))
+    for line in input:
+        output.write(line)
+        if line.startswith("index % time"):
+            break
+    for line in input:
+        m = re.match(r"(.*  )(\w+)(( &lt;cycle.*&gt;)? \[\d+\])\n", line)
+        if not m:
+            output.write(line)
+            if line.startswith("Index by function name"):
+                break
+            continue
+        prefix, fname, suffix = m.group(1, 2, 3)
+        if fname not in labels:
+            output.write(line)
+            continue
+        if line.startswith("["):
+            output.write('%s<a name="call:%s" href="#flat:%s">%s</a>%s\n' %
+                         (prefix, fname, fname, fname, suffix))
+        else:
+            output.write('%s<a href="#call:%s">%s</a>%s\n' %
+                         (prefix, fname, fname, suffix))
+    for line in input:
+        for part in re.findall(r"(\w+(?:\.c)?|\W+)", line):
+            if part in labels:
+                part = '<a href="#call:%s">%s</a>' % (part, part)
+            output.write(part)
+    output.write(trailer)
+    output.close()
+    webbrowser.open("file:" + os.path.abspath(outputfilename))
+
+if __name__ == '__main__':
+    main()


Property changes on: vendor/Python/current/Tools/scripts/gprof2html.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/scripts/h2py.py
===================================================================
--- vendor/Python/current/Tools/scripts/h2py.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/h2py.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,175 @@
+#! /usr/bin/env python
+
+# Read #define's and translate to Python code.
+# Handle #include statements.
+# Handle #define macros with one argument.
+# Anything that isn't recognized or doesn't translate into valid
+# Python is ignored.
+
+# Without filename arguments, acts as a filter.
+# If one or more filenames are given, output is written to corresponding
+# filenames in the local directory, translated to all uppercase, with
+# the extension replaced by ".py".
+
+# By passing one or more options of the form "-i regular_expression"
+# you can specify additional strings to be ignored.  This is useful
+# e.g. to ignore casts to u_long: simply specify "-i '(u_long)'".
+
+# XXX To do:
+# - turn trailing C comments into Python comments
+# - turn C Boolean operators "&& || !" into Python "and or not"
+# - what to do about #if(def)?
+# - what to do about macros with multiple parameters?
+
+import sys, re, getopt, os
+
+p_define = re.compile('^[\t ]*#[\t ]*define[\t ]+([a-zA-Z0-9_]+)[\t ]+')
+
+p_macro = re.compile(
+  '^[\t ]*#[\t ]*define[\t ]+'
+  '([a-zA-Z0-9_]+)\(([_a-zA-Z][_a-zA-Z0-9]*)\)[\t ]+')
+
+p_include = re.compile('^[\t ]*#[\t ]*include[\t ]+<([a-zA-Z0-9_/\.]+)')
+
+p_comment = re.compile(r'/\*([^*]+|\*+[^/])*(\*+/)?')
+p_cpp_comment = re.compile('//.*')
+
+ignores = [p_comment, p_cpp_comment]
+
+p_char = re.compile(r"'(\\.[^\\]*|[^\\])'")
+
+p_hex = re.compile(r"0x([0-9a-fA-F]+)L?")
+
+filedict = {}
+importable = {}
+
+try:
+    searchdirs=os.environ['include'].split(';')
+except KeyError:
+    try:
+        searchdirs=os.environ['INCLUDE'].split(';')
+    except KeyError:
+        try:
+            if  sys.platform.find("beos") == 0:
+                searchdirs=os.environ['BEINCLUDES'].split(';')
+            elif sys.platform.startswith("atheos"):
+                searchdirs=os.environ['C_INCLUDE_PATH'].split(':')
+            else:
+                raise KeyError
+        except KeyError:
+            searchdirs=['/usr/include']
+
+def main():
+    global filedict
+    opts, args = getopt.getopt(sys.argv[1:], 'i:')
+    for o, a in opts:
+        if o == '-i':
+            ignores.append(re.compile(a))
+    if not args:
+        args = ['-']
+    for filename in args:
+        if filename == '-':
+            sys.stdout.write('# Generated by h2py from stdin\n')
+            process(sys.stdin, sys.stdout)
+        else:
+            fp = open(filename, 'r')
+            outfile = os.path.basename(filename)
+            i = outfile.rfind('.')
+            if i > 0: outfile = outfile[:i]
+            modname = outfile.upper()
+            outfile = modname + '.py'
+            outfp = open(outfile, 'w')
+            outfp.write('# Generated by h2py from %s\n' % filename)
+            filedict = {}
+            for dir in searchdirs:
+                if filename[:len(dir)] == dir:
+                    filedict[filename[len(dir)+1:]] = None  # no '/' trailing
+                    importable[filename[len(dir)+1:]] = modname
+                    break
+            process(fp, outfp)
+            outfp.close()
+            fp.close()
+
+def pytify(body):
+    # replace ignored patterns by spaces
+    for p in ignores:
+        body = p.sub(' ', body)
+    # replace char literals by ord(...)
+    body = p_char.sub('ord(\\0)', body)
+    # Compute negative hexadecimal constants
+    start = 0
+    UMAX = 2*(sys.maxint+1)
+    while 1:
+        m = p_hex.search(body, start)
+        if not m: break
+        s,e = m.span()
+        val = long(body[slice(*m.span(1))], 16)
+        if val > sys.maxint:
+            val -= UMAX
+            body = body[:s] + "(" + str(val) + ")" + body[e:]
+        start = s + 1
+    return body
+
+def process(fp, outfp, env = {}):
+    lineno = 0
+    while 1:
+        line = fp.readline()
+        if not line: break
+        lineno = lineno + 1
+        match = p_define.match(line)
+        if match:
+            # gobble up continuation lines
+            while line[-2:] == '\\\n':
+                nextline = fp.readline()
+                if not nextline: break
+                lineno = lineno + 1
+                line = line + nextline
+            name = match.group(1)
+            body = line[match.end():]
+            body = pytify(body)
+            ok = 0
+            stmt = '%s = %s\n' % (name, body.strip())
+            try:
+                exec stmt in env
+            except:
+                sys.stderr.write('Skipping: %s' % stmt)
+            else:
+                outfp.write(stmt)
+        match = p_macro.match(line)
+        if match:
+            macro, arg = match.group(1, 2)
+            body = line[match.end():]
+            body = pytify(body)
+            stmt = 'def %s(%s): return %s\n' % (macro, arg, body)
+            try:
+                exec stmt in env
+            except:
+                sys.stderr.write('Skipping: %s' % stmt)
+            else:
+                outfp.write(stmt)
+        match = p_include.match(line)
+        if match:
+            regs = match.regs
+            a, b = regs[1]
+            filename = line[a:b]
+            if importable.has_key(filename):
+                outfp.write('from %s import *\n' % importable[filename])
+            elif not filedict.has_key(filename):
+                filedict[filename] = None
+                inclfp = None
+                for dir in searchdirs:
+                    try:
+                        inclfp = open(dir + '/' + filename)
+                        break
+                    except IOError:
+                        pass
+                if inclfp:
+                    outfp.write(
+                            '\n# Included from %s\n' % filename)
+                    process(inclfp, outfp, env)
+                else:
+                    sys.stderr.write('Warning - could not find file %s\n' %
+                                     filename)
+
+if __name__ == '__main__':
+    main()


Property changes on: vendor/Python/current/Tools/scripts/h2py.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/scripts/hotshotmain.py
===================================================================
--- vendor/Python/current/Tools/scripts/hotshotmain.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/hotshotmain.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,55 @@
+#!/usr/bin/env python
+# -*- coding: iso-8859-1 -*-
+
+"""
+Run a Python script under hotshot's control.
+
+Adapted from a posting on python-dev by Walter Dörwald
+
+usage %prog [ %prog args ] filename [ filename args ]
+
+Any arguments after the filename are used as sys.argv for the filename.
+"""
+
+import sys
+import optparse
+import os
+import hotshot
+import hotshot.stats
+
+PROFILE = "hotshot.prof"
+
+def run_hotshot(filename, profile, args):
+    prof = hotshot.Profile(profile)
+    sys.path.insert(0, os.path.dirname(filename))
+    sys.argv = [filename] + args
+    prof.run("execfile(%r)" % filename)
+    prof.close()
+    stats = hotshot.stats.load(profile)
+    stats.sort_stats("time", "calls")
+
+    # print_stats uses unadorned print statements, so the only way
+    # to force output to stderr is to reassign sys.stdout temporarily
+    save_stdout = sys.stdout
+    sys.stdout = sys.stderr
+    stats.print_stats()
+    sys.stdout = save_stdout
+
+    return 0
+
+def main(args):
+    parser = optparse.OptionParser(__doc__)
+    parser.disable_interspersed_args()
+    parser.add_option("-p", "--profile", action="store", default=PROFILE,
+                      dest="profile", help='Specify profile file to use')
+    (options, args) = parser.parse_args(args)
+
+    if len(args) == 0:
+        parser.print_help("missing script to execute")
+        return 1
+
+    filename = args[0]
+    return run_hotshot(filename, options.profile, args[1:])
+
+if __name__ == "__main__":
+    sys.exit(main(sys.argv[1:]))

Added: vendor/Python/current/Tools/scripts/idle
===================================================================
--- vendor/Python/current/Tools/scripts/idle	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/idle	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,5 @@
+#! /usr/bin/env python
+
+from idlelib.PyShell import main
+if __name__ == '__main__':
+    main()

Added: vendor/Python/current/Tools/scripts/ifdef.py
===================================================================
--- vendor/Python/current/Tools/scripts/ifdef.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/ifdef.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,112 @@
+#! /usr/bin/env python
+
+# Selectively preprocess #ifdef / #ifndef statements.
+# Usage:
+# ifdef [-Dname] ... [-Uname] ... [file] ...
+#
+# This scans the file(s), looking for #ifdef and #ifndef preprocessor
+# commands that test for one of the names mentioned in the -D and -U
+# options.  On standard output it writes a copy of the input file(s)
+# minus those code sections that are suppressed by the selected
+# combination of defined/undefined symbols.  The #if(n)def/#else/#else
+# lines themselfs (if the #if(n)def tests for one of the mentioned
+# names) are removed as well.
+
+# Features: Arbitrary nesting of recognized and unrecognized
+# preprocesor statements works correctly.  Unrecognized #if* commands
+# are left in place, so it will never remove too much, only too
+# little.  It does accept whitespace around the '#' character.
+
+# Restrictions: There should be no comments or other symbols on the
+# #if(n)def lines.  The effect of #define/#undef commands in the input
+# file or in included files is not taken into account.  Tests using
+# #if and the defined() pseudo function are not recognized.  The #elif
+# command is not recognized.  Improperly nesting is not detected.
+# Lines that look like preprocessor commands but which are actually
+# part of comments or string literals will be mistaken for
+# preprocessor commands.
+
+import sys
+import getopt
+
+defs = []
+undefs = []
+
+def main():
+    opts, args = getopt.getopt(sys.argv[1:], 'D:U:')
+    for o, a in opts:
+        if o == '-D':
+            defs.append(a)
+        if o == '-U':
+            undefs.append(a)
+    if not args:
+        args = ['-']
+    for filename in args:
+        if filename == '-':
+            process(sys.stdin, sys.stdout)
+        else:
+            f = open(filename, 'r')
+            process(f, sys.stdout)
+            f.close()
+
+def process(fpi, fpo):
+    keywords = ('if', 'ifdef', 'ifndef', 'else', 'endif')
+    ok = 1
+    stack = []
+    while 1:
+        line = fpi.readline()
+        if not line: break
+        while line[-2:] == '\\\n':
+            nextline = fpi.readline()
+            if not nextline: break
+            line = line + nextline
+        tmp = line.strip()
+        if tmp[:1] != '#':
+            if ok: fpo.write(line)
+            continue
+        tmp = tmp[1:].strip()
+        words = tmp.split()
+        keyword = words[0]
+        if keyword not in keywords:
+            if ok: fpo.write(line)
+            continue
+        if keyword in ('ifdef', 'ifndef') and len(words) == 2:
+            if keyword == 'ifdef':
+                ko = 1
+            else:
+                ko = 0
+            word = words[1]
+            if word in defs:
+                stack.append((ok, ko, word))
+                if not ko: ok = 0
+            elif word in undefs:
+                stack.append((ok, not ko, word))
+                if ko: ok = 0
+            else:
+                stack.append((ok, -1, word))
+                if ok: fpo.write(line)
+        elif keyword == 'if':
+            stack.append((ok, -1, ''))
+            if ok: fpo.write(line)
+        elif keyword == 'else' and stack:
+            s_ok, s_ko, s_word = stack[-1]
+            if s_ko < 0:
+                if ok: fpo.write(line)
+            else:
+                s_ko = not s_ko
+                ok = s_ok
+                if not s_ko: ok = 0
+                stack[-1] = s_ok, s_ko, s_word
+        elif keyword == 'endif' and stack:
+            s_ok, s_ko, s_word = stack[-1]
+            if s_ko < 0:
+                if ok: fpo.write(line)
+            del stack[-1]
+            ok = s_ok
+        else:
+            sys.stderr.write('Unknown keyword %s\n' % keyword)
+    if stack:
+        sys.stderr.write('stack: %s\n' % stack)
+
+if __name__ == '__main__':
+    main()


Property changes on: vendor/Python/current/Tools/scripts/ifdef.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/scripts/lfcr.py
===================================================================
--- vendor/Python/current/Tools/scripts/lfcr.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/lfcr.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,24 @@
+#! /usr/bin/env python
+
+"Replace LF with CRLF in argument files.  Print names of changed files."
+
+import sys, re, os
+
+def main():
+    for filename in sys.argv[1:]:
+        if os.path.isdir(filename):
+            print filename, "Directory!"
+            continue
+        data = open(filename, "rb").read()
+        if '\0' in data:
+            print filename, "Binary!"
+            continue
+        newdata = re.sub("\r?\n", "\r\n", data)
+        if newdata != data:
+            print filename
+            f = open(filename, "wb")
+            f.write(newdata)
+            f.close()
+
+if __name__ == '__main__':
+    main()


Property changes on: vendor/Python/current/Tools/scripts/lfcr.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/scripts/linktree.py
===================================================================
--- vendor/Python/current/Tools/scripts/linktree.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/linktree.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,80 @@
+#! /usr/bin/env python
+
+# linktree
+#
+# Make a copy of a directory tree with symbolic links to all files in the
+# original tree.
+# All symbolic links go to a special symbolic link at the top, so you
+# can easily fix things if the original source tree moves.
+# See also "mkreal".
+#
+# usage: mklinks oldtree newtree
+
+import sys, os
+
+LINK = '.LINK' # Name of special symlink at the top.
+
+debug = 0
+
+def main():
+    if not 3 <= len(sys.argv) <= 4:
+        print 'usage:', sys.argv[0], 'oldtree newtree [linkto]'
+        return 2
+    oldtree, newtree = sys.argv[1], sys.argv[2]
+    if len(sys.argv) > 3:
+        link = sys.argv[3]
+        link_may_fail = 1
+    else:
+        link = LINK
+        link_may_fail = 0
+    if not os.path.isdir(oldtree):
+        print oldtree + ': not a directory'
+        return 1
+    try:
+        os.mkdir(newtree, 0777)
+    except os.error, msg:
+        print newtree + ': cannot mkdir:', msg
+        return 1
+    linkname = os.path.join(newtree, link)
+    try:
+        os.symlink(os.path.join(os.pardir, oldtree), linkname)
+    except os.error, msg:
+        if not link_may_fail:
+            print linkname + ': cannot symlink:', msg
+            return 1
+        else:
+            print linkname + ': warning: cannot symlink:', msg
+    linknames(oldtree, newtree, link)
+    return 0
+
+def linknames(old, new, link):
+    if debug: print 'linknames', (old, new, link)
+    try:
+        names = os.listdir(old)
+    except os.error, msg:
+        print old + ': warning: cannot listdir:', msg
+        return
+    for name in names:
+        if name not in (os.curdir, os.pardir):
+            oldname = os.path.join(old, name)
+            linkname = os.path.join(link, name)
+            newname = os.path.join(new, name)
+            if debug > 1: print oldname, newname, linkname
+            if os.path.isdir(oldname) and \
+               not os.path.islink(oldname):
+                try:
+                    os.mkdir(newname, 0777)
+                    ok = 1
+                except:
+                    print newname + \
+                          ': warning: cannot mkdir:', msg
+                    ok = 0
+                if ok:
+                    linkname = os.path.join(os.pardir,
+                                            linkname)
+                    linknames(oldname, newname, linkname)
+            else:
+                os.symlink(linkname, newname)
+
+if __name__ == '__main__':
+    sys.exit(main())


Property changes on: vendor/Python/current/Tools/scripts/linktree.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/scripts/lll.py
===================================================================
--- vendor/Python/current/Tools/scripts/lll.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/lll.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,28 @@
+#! /usr/bin/env python
+
+# Find symbolic links and show where they point to.
+# Arguments are directories to search; default is current directory.
+# No recursion.
+# (This is a totally different program from "findsymlinks.py"!)
+
+import sys, os
+
+def lll(dirname):
+    for name in os.listdir(dirname):
+        if name not in (os.curdir, os.pardir):
+            full = os.path.join(dirname, name)
+            if os.path.islink(full):
+                print name, '->', os.readlink(full)
+def main():
+    args = sys.argv[1:]
+    if not args: args = [os.curdir]
+    first = 1
+    for arg in args:
+        if len(args) > 1:
+            if not first: print
+            first = 0
+            print arg + ':'
+    lll(arg)
+
+if __name__ == '__main__':
+    main()


Property changes on: vendor/Python/current/Tools/scripts/lll.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/scripts/logmerge.py
===================================================================
--- vendor/Python/current/Tools/scripts/logmerge.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/logmerge.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,185 @@
+#! /usr/bin/env python
+
+"""Consolidate a bunch of CVS or RCS logs read from stdin.
+
+Input should be the output of a CVS or RCS logging command, e.g.
+
+    cvs log -rrelease14:
+
+which dumps all log messages from release1.4 upwards (assuming that
+release 1.4 was tagged with tag 'release14').  Note the trailing
+colon!
+
+This collects all the revision records and outputs them sorted by date
+rather than by file, collapsing duplicate revision record, i.e.,
+records with the same message for different files.
+
+The -t option causes it to truncate (discard) the last revision log
+entry; this is useful when using something like the above cvs log
+command, which shows the revisions including the given tag, while you
+probably want everything *since* that tag.
+
+The -r option reverses the output (oldest first; the default is oldest
+last).
+
+The -b tag option restricts the output to *only* checkin messages
+belonging to the given branch tag.  The form -b HEAD restricts the
+output to checkin messages belonging to the CVS head (trunk).  (It
+produces some output if tag is a non-branch tag, but this output is
+not very useful.)
+
+-h prints this message and exits.
+
+XXX This code was created by reverse engineering CVS 1.9 and RCS 5.7
+from their output.
+"""
+
+import os, sys, errno, getopt, re
+
+sep1 = '='*77 + '\n'                    # file separator
+sep2 = '-'*28 + '\n'                    # revision separator
+
+def main():
+    """Main program"""
+    truncate_last = 0
+    reverse = 0
+    branch = None
+    opts, args = getopt.getopt(sys.argv[1:], "trb:h")
+    for o, a in opts:
+        if o == '-t':
+            truncate_last = 1
+        elif o == '-r':
+            reverse = 1
+        elif o == '-b':
+            branch = a
+        elif o == '-h':
+            print __doc__
+            sys.exit(0)
+    database = []
+    while 1:
+        chunk = read_chunk(sys.stdin)
+        if not chunk:
+            break
+        records = digest_chunk(chunk, branch)
+        if truncate_last:
+            del records[-1]
+        database[len(database):] = records
+    database.sort()
+    if not reverse:
+        database.reverse()
+    format_output(database)
+
+def read_chunk(fp):
+    """Read a chunk -- data for one file, ending with sep1.
+
+    Split the chunk in parts separated by sep2.
+
+    """
+    chunk = []
+    lines = []
+    while 1:
+        line = fp.readline()
+        if not line:
+            break
+        if line == sep1:
+            if lines:
+                chunk.append(lines)
+            break
+        if line == sep2:
+            if lines:
+                chunk.append(lines)
+                lines = []
+        else:
+            lines.append(line)
+    return chunk
+
+def digest_chunk(chunk, branch=None):
+    """Digest a chunk -- extract working file name and revisions"""
+    lines = chunk[0]
+    key = 'Working file:'
+    keylen = len(key)
+    for line in lines:
+        if line[:keylen] == key:
+            working_file = line[keylen:].strip()
+            break
+    else:
+        working_file = None
+    if branch is None:
+        pass
+    elif branch == "HEAD":
+        branch = re.compile(r"^\d+\.\d+$")
+    else:
+        revisions = {}
+        key = 'symbolic names:\n'
+        found = 0
+        for line in lines:
+            if line == key:
+                found = 1
+            elif found:
+                if line[0] in '\t ':
+                    tag, rev = line.split()
+                    if tag[-1] == ':':
+                        tag = tag[:-1]
+                    revisions[tag] = rev
+                else:
+                    found = 0
+        rev = revisions.get(branch)
+        branch = re.compile(r"^<>$") # <> to force a mismatch by default
+        if rev:
+            if rev.find('.0.') >= 0:
+                rev = rev.replace('.0.', '.')
+                branch = re.compile(r"^" + re.escape(rev) + r"\.\d+$")
+    records = []
+    for lines in chunk[1:]:
+        revline = lines[0]
+        dateline = lines[1]
+        text = lines[2:]
+        words = dateline.split()
+        author = None
+        if len(words) >= 3 and words[0] == 'date:':
+            dateword = words[1]
+            timeword = words[2]
+            if timeword[-1:] == ';':
+                timeword = timeword[:-1]
+            date = dateword + ' ' + timeword
+            if len(words) >= 5 and words[3] == 'author:':
+                author = words[4]
+                if author[-1:] == ';':
+                    author = author[:-1]
+        else:
+            date = None
+            text.insert(0, revline)
+        words = revline.split()
+        if len(words) >= 2 and words[0] == 'revision':
+            rev = words[1]
+        else:
+            # No 'revision' line -- weird...
+            rev = None
+            text.insert(0, revline)
+        if branch:
+            if rev is None or not branch.match(rev):
+                continue
+        records.append((date, working_file, rev, author, text))
+    return records
+
+def format_output(database):
+    prevtext = None
+    prev = []
+    database.append((None, None, None, None, None)) # Sentinel
+    for (date, working_file, rev, author, text) in database:
+        if text != prevtext:
+            if prev:
+                print sep2,
+                for (p_date, p_working_file, p_rev, p_author) in prev:
+                    print p_date, p_author, p_working_file, p_rev
+                sys.stdout.writelines(prevtext)
+            prev = []
+        prev.append((date, working_file, rev, author))
+        prevtext = text
+
+if __name__ == '__main__':
+    try:
+        main()
+    except IOError, e:
+        if e.errno != errno.EPIPE:
+            raise


Property changes on: vendor/Python/current/Tools/scripts/logmerge.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/scripts/mailerdaemon.py
===================================================================
--- vendor/Python/current/Tools/scripts/mailerdaemon.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/mailerdaemon.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,237 @@
+"""mailerdaemon - classes to parse mailer-daemon messages"""
+
+import rfc822
+import calendar
+import re
+import os
+import sys
+
+Unparseable = 'mailerdaemon.Unparseable'
+
+class ErrorMessage(rfc822.Message):
+    def __init__(self, fp):
+        rfc822.Message.__init__(self, fp)
+        self.sub = ''
+
+    def is_warning(self):
+        sub = self.getheader('Subject')
+        if not sub:
+            return 0
+        sub = sub.lower()
+        if sub.startswith('waiting mail'): return 1
+        if 'warning' in sub: return 1
+        self.sub = sub
+        return 0
+
+    def get_errors(self):
+        for p in EMPARSERS:
+            self.rewindbody()
+            try:
+                return p(self.fp, self.sub)
+            except Unparseable:
+                pass
+        raise Unparseable
+
+# List of re's or tuples of re's.
+# If a re, it should contain at least a group (?P<email>...) which
+# should refer to the email address.  The re can also contain a group
+# (?P<reason>...) which should refer to the reason (error message).
+# If no reason is present, the emparse_list_reason list is used to
+# find a reason.
+# If a tuple, the tuple should contain 2 re's.  The first re finds a
+# location, the second re is repeated one or more times to find
+# multiple email addresses.  The second re is matched (not searched)
+# where the previous match ended.
+# The re's are compiled using the re module.
+emparse_list_list = [
+    'error: (?P<reason>unresolvable): (?P<email>.+)',
+    ('----- The following addresses had permanent fatal errors -----\n',
+     '(?P<email>[^ \n].*)\n( .*\n)?'),
+    'remote execution.*\n.*rmail (?P<email>.+)',
+    ('The following recipients did not receive your message:\n\n',
+     ' +(?P<email>.*)\n(The following recipients did not receive your message:\n\n)?'),
+    '------- Failure Reasons  --------\n\n(?P<reason>.*)\n(?P<email>.*)',
+    '^<(?P<email>.*)>:\n(?P<reason>.*)',
+    '^(?P<reason>User mailbox exceeds allowed size): (?P<email>.+)',
+    '^5\\d{2} <(?P<email>[^\n>]+)>\\.\\.\\. (?P<reason>.+)',
+    '^Original-Recipient: rfc822;(?P<email>.*)',
+    '^did not reach the following recipient\\(s\\):\n\n(?P<email>.*) on .*\n +(?P<reason>.*)',
+    '^ <(?P<email>[^\n>]+)> \\.\\.\\. (?P<reason>.*)',
+    '^Report on your message to: (?P<email>.*)\nReason: (?P<reason>.*)',
+    '^Your message was not delivered to +(?P<email>.*)\n +for the following reason:\n +(?P<reason>.*)',
+    '^ was not +(?P<email>[^ \n].*?) *\n.*\n.*\n.*\n because:.*\n +(?P<reason>[^ \n].*?) *\n',
+    ]
+# compile the re's in the list and store them in-place.
+for i in range(len(emparse_list_list)):
+    x = emparse_list_list[i]
+    if type(x) is type(''):
+        x = re.compile(x, re.MULTILINE)
+    else:
+        xl = []
+        for x in x:
+            xl.append(re.compile(x, re.MULTILINE))
+        x = tuple(xl)
+        del xl
+    emparse_list_list[i] = x
+    del x
+del i
+
+# list of re's used to find reasons (error messages).
+# if a string, "<>" is replaced by a copy of the email address.
+# The expressions are searched for in order.  After the first match,
+# no more expressions are searched for.  So, order is important.
+emparse_list_reason = [
+    r'^5\d{2} <>\.\.\. (?P<reason>.*)',
+    '<>\.\.\. (?P<reason>.*)',
+    re.compile(r'^<<< 5\d{2} (?P<reason>.*)', re.MULTILINE),
+    re.compile('===== stderr was =====\nrmail: (?P<reason>.*)'),
+    re.compile('^Diagnostic-Code: (?P<reason>.*)', re.MULTILINE),
+    ]
+emparse_list_from = re.compile('^From:', re.IGNORECASE|re.MULTILINE)
+def emparse_list(fp, sub):
+    data = fp.read()
+    res = emparse_list_from.search(data)
+    if res is None:
+        from_index = len(data)
+    else:
+        from_index = res.start(0)
+    errors = []
+    emails = []
+    reason = None
+    for regexp in emparse_list_list:
+        if type(regexp) is type(()):
+            res = regexp[0].search(data, 0, from_index)
+            if res is not None:
+                try:
+                    reason = res.group('reason')
+                except IndexError:
+                    pass
+                while 1:
+                    res = regexp[1].match(data, res.end(0), from_index)
+                    if res is None:
+                        break
+                    emails.append(res.group('email'))
+                break
+        else:
+            res = regexp.search(data, 0, from_index)
+            if res is not None:
+                emails.append(res.group('email'))
+                try:
+                    reason = res.group('reason')
+                except IndexError:
+                    pass
+                break
+    if not emails:
+        raise Unparseable
+    if not reason:
+        reason = sub
+        if reason[:15] == 'returned mail: ':
+            reason = reason[15:]
+        for regexp in emparse_list_reason:
+            if type(regexp) is type(''):
+                for i in range(len(emails)-1,-1,-1):
+                    email = emails[i]
+                    exp = re.compile(re.escape(email).join(regexp.split('<>')), re.MULTILINE)
+                    res = exp.search(data)
+                    if res is not None:
+                        errors.append(' '.join((email.strip()+': '+res.group('reason')).split()))
+                        del emails[i]
+                continue
+            res = regexp.search(data)
+            if res is not None:
+                reason = res.group('reason')
+                break
+    for email in emails:
+        errors.append(' '.join((email.strip()+': '+reason).split()))
+    return errors
+
+EMPARSERS = [emparse_list, ]
+
+def sort_numeric(a, b):
+    a = int(a)
+    b = int(b)
+    if a < b: return -1
+    elif a > b: return 1
+    else: return 0
+
+def parsedir(dir, modify):
+    os.chdir(dir)
+    pat = re.compile('^[0-9]*$')
+    errordict = {}
+    errorfirst = {}
+    errorlast = {}
+    nok = nwarn = nbad = 0
+
+    # find all numeric file names and sort them
+    files = filter(lambda fn, pat=pat: pat.match(fn) is not None, os.listdir('.'))
+    files.sort(sort_numeric)
+
+    for fn in files:
+        # Lets try to parse the file.
+        fp = open(fn)
+        m = ErrorMessage(fp)
+        sender = m.getaddr('From')
+        print '%s\t%-40s\t'%(fn, sender[1]),
+
+        if m.is_warning():
+            fp.close()
+            print 'warning only'
+            nwarn = nwarn + 1
+            if modify:
+                os.rename(fn, ','+fn)
+##              os.unlink(fn)
+            continue
+
+        try:
+            errors = m.get_errors()
+        except Unparseable:
+            print '** Not parseable'
+            nbad = nbad + 1
+            fp.close()
+            continue
+        print len(errors), 'errors'
+
+        # Remember them
+        for e in errors:
+            try:
+                mm, dd = m.getdate('date')[1:1+2]
+                date = '%s %02d' % (calendar.month_abbr[mm], dd)
+            except:
+                date = '??????'
+            if not errordict.has_key(e):
+                errordict[e] = 1
+                errorfirst[e] = '%s (%s)' % (fn, date)
+            else:
+                errordict[e] = errordict[e] + 1
+            errorlast[e] = '%s (%s)' % (fn, date)
+
+        fp.close()
+        nok = nok + 1
+        if modify:
+            os.rename(fn, ','+fn)
+##          os.unlink(fn)
+
+    print '--------------'
+    print nok, 'files parsed,',nwarn,'files warning-only,',
+    print nbad,'files unparseable'
+    print '--------------'
+    list = []
+    for e in errordict.keys():
+        list.append((errordict[e], errorfirst[e], errorlast[e], e))
+    list.sort()
+    for num, first, last, e in list:
+        print '%d %s - %s\t%s' % (num, first, last, e)
+
+def main():
+    modify = 0
+    if len(sys.argv) > 1 and sys.argv[1] == '-d':
+        modify = 1
+        del sys.argv[1]
+    if len(sys.argv) > 1:
+        for folder in sys.argv[1:]:
+            parsedir(folder, modify)
+    else:
+        parsedir('/ufs/jack/Mail/errorsinbox', modify)
+
+if __name__ == '__main__' or sys.argv[0] == __name__:
+    main()


Property changes on: vendor/Python/current/Tools/scripts/mailerdaemon.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/scripts/md5sum.py
===================================================================
--- vendor/Python/current/Tools/scripts/md5sum.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/md5sum.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,90 @@
+#! /usr/bin/env python
+
+"""Python utility to print MD5 checksums of argument files.
+"""
+
+
+bufsize = 8096
+fnfilter = None
+rmode = 'rb'
+
+usage = """
+usage: sum5 [-b] [-t] [-l] [-s bufsize] [file ...]
+-b        : read files in binary mode (default)
+-t        : read files in text mode (you almost certainly don't want this!)
+-l        : print last pathname component only
+-s bufsize: read buffer size (default %d)
+file ...  : files to sum; '-' or no files means stdin
+""" % bufsize
+
+import sys
+import os
+import getopt
+import md5
+
+def sum(*files):
+    sts = 0
+    if files and isinstance(files[-1], file):
+        out, files = files[-1], files[:-1]
+    else:
+        out = sys.stdout
+    if len(files) == 1 and not isinstance(files[0], str):
+        files = files[0]
+    for f in files:
+        if isinstance(f, str):
+            if f == '-':
+                sts = printsumfp(sys.stdin, '<stdin>', out) or sts
+            else:
+                sts = printsum(f, out) or sts
+        else:
+            sts = sum(f, out) or sts
+    return sts
+
+def printsum(filename, out=sys.stdout):
+    try:
+        fp = open(filename, rmode)
+    except IOError, msg:
+        sys.stderr.write('%s: Can\'t open: %s\n' % (filename, msg))
+        return 1
+    if fnfilter:
+        filename = fnfilter(filename)
+    sts = printsumfp(fp, filename, out)
+    fp.close()
+    return sts
+
+def printsumfp(fp, filename, out=sys.stdout):
+    m = md5.new()
+    try:
+        while 1:
+            data = fp.read(bufsize)
+            if not data:
+                break
+            m.update(data)
+    except IOError, msg:
+        sys.stderr.write('%s: I/O error: %s\n' % (filename, msg))
+        return 1
+    out.write('%s %s\n' % (m.hexdigest(), filename))
+    return 0
+
+def main(args = sys.argv[1:], out=sys.stdout):
+    global fnfilter, rmode, bufsize
+    try:
+        opts, args = getopt.getopt(args, 'blts:')
+    except getopt.error, msg:
+        sys.stderr.write('%s: %s\n%s' % (sys.argv[0], msg, usage))
+        return 2
+    for o, a in opts:
+        if o == '-l':
+            fnfilter = os.path.basename
+        elif o == '-b':
+            rmode = 'rb'
+        elif o == '-t':
+            rmode = 'r'
+        elif o == '-s':
+            bufsize = int(a)
+    if not args:
+        args = ['-']
+    return sum(args, out)
+
+if __name__ == '__main__' or __name__ == sys.argv[0]:
+    sys.exit(main(sys.argv[1:], sys.stdout))

Added: vendor/Python/current/Tools/scripts/methfix.py
===================================================================
--- vendor/Python/current/Tools/scripts/methfix.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/methfix.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,171 @@
+#! /usr/bin/env python
+
+# Fix Python source files to avoid using
+#       def method(self, (arg1, ..., argn)):
+# instead of the more rational
+#       def method(self, arg1, ..., argn):
+#
+# Command line arguments are files or directories to be processed.
+# Directories are searched recursively for files whose name looks
+# like a python module.
+# Symbolic links are always ignored (except as explicit directory
+# arguments).  Of course, the original file is kept as a back-up
+# (with a "~" attached to its name).
+# It complains about binaries (files containing null bytes)
+# and about files that are ostensibly not Python files: if the first
+# line starts with '#!' and does not contain the string 'python'.
+#
+# Changes made are reported to stdout in a diff-like format.
+#
+# Undoubtedly you can do this using find and sed or perl, but this is
+# a nice example of Python code that recurses down a directory tree
+# and uses regular expressions.  Also note several subtleties like
+# preserving the file's mode and avoiding to even write a temp file
+# when no changes are needed for a file.
+#
+# NB: by changing only the function fixline() you can turn this
+# into a program for a different change to Python programs...
+
+import sys
+import re
+import os
+from stat import *
+
+err = sys.stderr.write
+dbg = err
+rep = sys.stdout.write
+
+def main():
+    bad = 0
+    if not sys.argv[1:]: # No arguments
+        err('usage: ' + sys.argv[0] + ' file-or-directory ...\n')
+        sys.exit(2)
+    for arg in sys.argv[1:]:
+        if os.path.isdir(arg):
+            if recursedown(arg): bad = 1
+        elif os.path.islink(arg):
+            err(arg + ': will not process symbolic links\n')
+            bad = 1
+        else:
+            if fix(arg): bad = 1
+    sys.exit(bad)
+
+ispythonprog = re.compile('^[a-zA-Z0-9_]+\.py$')
+def ispython(name):
+    return ispythonprog.match(name) >= 0
+
+def recursedown(dirname):
+    dbg('recursedown(%r)\n' % (dirname,))
+    bad = 0
+    try:
+        names = os.listdir(dirname)
+    except os.error, msg:
+        err('%s: cannot list directory: %r\n' % (dirname, msg))
+        return 1
+    names.sort()
+    subdirs = []
+    for name in names:
+        if name in (os.curdir, os.pardir): continue
+        fullname = os.path.join(dirname, name)
+        if os.path.islink(fullname): pass
+        elif os.path.isdir(fullname):
+            subdirs.append(fullname)
+        elif ispython(name):
+            if fix(fullname): bad = 1
+    for fullname in subdirs:
+        if recursedown(fullname): bad = 1
+    return bad
+
+def fix(filename):
+##  dbg('fix(%r)\n' % (filename,))
+    try:
+        f = open(filename, 'r')
+    except IOError, msg:
+        err('%s: cannot open: %r\n' % (filename, msg))
+        return 1
+    head, tail = os.path.split(filename)
+    tempname = os.path.join(head, '@' + tail)
+    g = None
+    # If we find a match, we rewind the file and start over but
+    # now copy everything to a temp file.
+    lineno = 0
+    while 1:
+        line = f.readline()
+        if not line: break
+        lineno = lineno + 1
+        if g is None and '\0' in line:
+            # Check for binary files
+            err(filename + ': contains null bytes; not fixed\n')
+            f.close()
+            return 1
+        if lineno == 1 and g is None and line[:2] == '#!':
+            # Check for non-Python scripts
+            words = line[2:].split()
+            if words and re.search('[pP]ython', words[0]) < 0:
+                msg = filename + ': ' + words[0]
+                msg = msg + ' script; not fixed\n'
+                err(msg)
+                f.close()
+                return 1
+        while line[-2:] == '\\\n':
+            nextline = f.readline()
+            if not nextline: break
+            line = line + nextline
+            lineno = lineno + 1
+        newline = fixline(line)
+        if newline != line:
+            if g is None:
+                try:
+                    g = open(tempname, 'w')
+                except IOError, msg:
+                    f.close()
+                    err('%s: cannot create: %r\n' % (tempname, msg))
+                    return 1
+                f.seek(0)
+                lineno = 0
+                rep(filename + ':\n')
+                continue # restart from the beginning
+            rep(repr(lineno) + '\n')
+            rep('< ' + line)
+            rep('> ' + newline)
+        if g is not None:
+            g.write(newline)
+
+    # End of file
+    f.close()
+    if not g: return 0 # No changes
+
+    # Finishing touch -- move files
+
+    # First copy the file's mode to the temp file
+    try:
+        statbuf = os.stat(filename)
+        os.chmod(tempname, statbuf[ST_MODE] & 07777)
+    except os.error, msg:
+        err('%s: warning: chmod failed (%r)\n' % (tempname, msg))
+    # Then make a backup of the original file as filename~
+    try:
+        os.rename(filename, filename + '~')
+    except os.error, msg:
+        err('%s: warning: backup failed (%r)\n' % (filename, msg))
+    # Now move the temp file to the original file
+    try:
+        os.rename(tempname, filename)
+    except os.error, msg:
+        err('%s: rename failed (%r)\n' % (filename, msg))
+        return 1
+    # Return succes
+    return 0
+
+
+fixpat = '^[ \t]+def +[a-zA-Z0-9_]+ *( *self *, *(( *(.*) *)) *) *:'
+fixprog = re.compile(fixpat)
+
+def fixline(line):
+    if fixprog.match(line) >= 0:
+        (a, b), (c, d) = fixprog.regs[1:3]
+        line = line[:a] + line[c:d] + line[b:]
+    return line
+
+if __name__ == '__main__':
+    main()


Property changes on: vendor/Python/current/Tools/scripts/methfix.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/scripts/mkreal.py
===================================================================
--- vendor/Python/current/Tools/scripts/mkreal.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/mkreal.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,66 @@
+#! /usr/bin/env python
+
+# mkreal
+#
+# turn a symlink to a directory into a real directory
+
+import sys
+import os
+from stat import *
+
+join = os.path.join
+
+error = 'mkreal error'
+
+BUFSIZE = 32*1024
+
+def mkrealfile(name):
+    st = os.stat(name) # Get the mode
+    mode = S_IMODE(st[ST_MODE])
+    linkto = os.readlink(name) # Make sure again it's a symlink
+    f_in = open(name, 'r') # This ensures it's a file
+    os.unlink(name)
+    f_out = open(name, 'w')
+    while 1:
+        buf = f_in.read(BUFSIZE)
+        if not buf: break
+        f_out.write(buf)
+    del f_out # Flush data to disk before changing mode
+    os.chmod(name, mode)
+
+def mkrealdir(name):
+    st = os.stat(name) # Get the mode
+    mode = S_IMODE(st[ST_MODE])
+    linkto = os.readlink(name)
+    files = os.listdir(name)
+    os.unlink(name)
+    os.mkdir(name, mode)
+    os.chmod(name, mode)
+    linkto = join(os.pardir, linkto)
+    #
+    for filename in files:
+        if filename not in (os.curdir, os.pardir):
+            os.symlink(join(linkto, filename), join(name, filename))
+
+def main():
+    sys.stdout = sys.stderr
+    progname = os.path.basename(sys.argv[0])
+    if progname == '-c': progname = 'mkreal'
+    args = sys.argv[1:]
+    if not args:
+        print 'usage:', progname, 'path ...'
+        sys.exit(2)
+    status = 0
+    for name in args:
+        if not os.path.islink(name):
+            print progname+':', name+':', 'not a symlink'
+            status = 1
+        else:
+            if os.path.isdir(name):
+                mkrealdir(name)
+            else:
+                mkrealfile(name)
+    sys.exit(status)
+
+if __name__ == '__main__':
+    main()


Property changes on: vendor/Python/current/Tools/scripts/mkreal.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/scripts/ndiff.py
===================================================================
--- vendor/Python/current/Tools/scripts/ndiff.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/ndiff.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,133 @@
+#! /usr/bin/env python
+
+# Module ndiff version 1.7.0
+# Released to the public domain 08-Dec-2000,
+# by Tim Peters (tim.one at home.com).
+
+# Provided as-is; use at your own risk; no warranty; no promises; enjoy!
+
+# ndiff.py is now simply a front-end to the difflib.ndiff() function.
+# Originally, it contained the difflib.SequenceMatcher class as well.
+# This completes the raiding of reusable code from this formerly
+# self-contained script.
+
+"""ndiff [-q] file1 file2
+    or
+ndiff (-r1 | -r2) < ndiff_output > file1_or_file2
+
+Print a human-friendly file difference report to stdout.  Both inter-
+and intra-line differences are noted.  In the second form, recreate file1
+(-r1) or file2 (-r2) on stdout, from an ndiff report on stdin.
+
+In the first form, if -q ("quiet") is not specified, the first two lines
+of output are
+
+-: file1
++: file2
+
+Each remaining line begins with a two-letter code:
+
+    "- "    line unique to file1
+    "+ "    line unique to file2
+    "  "    line common to both files
+    "? "    line not present in either input file
+
+Lines beginning with "? " attempt to guide the eye to intraline
+differences, and were not present in either input file.  These lines can be
+confusing if the source files contain tab characters.
+
+The first file can be recovered by retaining only lines that begin with
+"  " or "- ", and deleting those 2-character prefixes; use ndiff with -r1.
+
+The second file can be recovered similarly, but by retaining only "  " and
+"+ " lines; use ndiff with -r2; or, on Unix, the second file can be
+recovered by piping the output through
+
+    sed -n '/^[+ ] /s/^..//p'
+"""
+
+__version__ = 1, 7, 0
+
+import difflib, sys
+
+def fail(msg):
+    out = sys.stderr.write
+    out(msg + "\n\n")
+    out(__doc__)
+    return 0
+
+# open a file & return the file object; gripe and return 0 if it
+# couldn't be opened
+def fopen(fname):
+    try:
+        return open(fname, 'U')
+    except IOError, detail:
+        return fail("couldn't open " + fname + ": " + str(detail))
+
+# open two files & spray the diff to stdout; return false iff a problem
+def fcompare(f1name, f2name):
+    f1 = fopen(f1name)
+    f2 = fopen(f2name)
+    if not f1 or not f2:
+        return 0
+
+    a = f1.readlines(); f1.close()
+    b = f2.readlines(); f2.close()
+    for line in difflib.ndiff(a, b):
+        print line,
+
+    return 1
+
+# crack args (sys.argv[1:] is normal) & compare;
+# return false iff a problem
+
+def main(args):
+    import getopt
+    try:
+        opts, args = getopt.getopt(args, "qr:")
+    except getopt.error, detail:
+        return fail(str(detail))
+    noisy = 1
+    qseen = rseen = 0
+    for opt, val in opts:
+        if opt == "-q":
+            qseen = 1
+            noisy = 0
+        elif opt == "-r":
+            rseen = 1
+            whichfile = val
+    if qseen and rseen:
+        return fail("can't specify both -q and -r")
+    if rseen:
+        if args:
+            return fail("no args allowed with -r option")
+        if whichfile in ("1", "2"):
+            restore(whichfile)
+            return 1
+        return fail("-r value must be 1 or 2")
+    if len(args) != 2:
+        return fail("need 2 filename args")
+    f1name, f2name = args
+    if noisy:
+        print '-:', f1name
+        print '+:', f2name
+    return fcompare(f1name, f2name)
+
+# read ndiff output from stdin, and print file1 (which=='1') or
+# file2 (which=='2') to stdout
+
+def restore(which):
+    restored = difflib.restore(sys.stdin.readlines(), which)
+    sys.stdout.writelines(restored)
+
+if __name__ == '__main__':
+    args = sys.argv[1:]
+    if "-profile" in args:
+        import profile, pstats
+        args.remove("-profile")
+        statf = "ndiff.pro"
+        profile.run("main(args)", statf)
+        stats = pstats.Stats(statf)
+        stats.strip_dirs().sort_stats('time').print_stats()
+    else:
+        main(args)


Property changes on: vendor/Python/current/Tools/scripts/ndiff.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/scripts/nm2def.py
===================================================================
--- vendor/Python/current/Tools/scripts/nm2def.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/nm2def.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,103 @@
+#! /usr/bin/env python
+"""nm2def.py
+
+Helpers to extract symbols from Unix libs and auto-generate
+Windows definition files from them. Depends on nm(1). Tested
+on Linux and Solaris only (-p option to nm is for Solaris only).
+
+By Marc-Andre Lemburg, Aug 1998.
+
+Additional notes: the output of nm is supposed to look like this:
+
+acceler.o:
+000001fd T PyGrammar_AddAccelerators
+         U PyGrammar_FindDFA
+00000237 T PyGrammar_RemoveAccelerators
+         U _IO_stderr_
+         U exit
+         U fprintf
+         U free
+         U malloc
+         U printf
+
+grammar1.o:
+00000000 T PyGrammar_FindDFA
+00000034 T PyGrammar_LabelRepr
+         U _PyParser_TokenNames
+         U abort
+         U printf
+         U sprintf
+
+...
+
+Even if this isn't the default output of your nm, there is generally an
+option to produce this format (since it is the original v7 Unix format).
+
+"""
+import os,re,sys
+
+PYTHONLIB = 'libpython'+sys.version[:3]+'.a'
+PC_PYTHONLIB = 'Python'+sys.version[0]+sys.version[2]+'.dll'
+NM = 'nm -p -g %s'                      # For Linux, use "nm -g %s"
+
+def symbols(lib=PYTHONLIB,types=('T','C','D')):
+
+    lines = os.popen(NM % lib).readlines()
+    lines = [s.strip() for s in lines]
+    symbols = {}
+    for line in lines:
+        if len(line) == 0 or ':' in line:
+            continue
+        items = line.split()
+        if len(items) != 3:
+            continue
+        address, type, name = items
+        if type not in types:
+            continue
+        symbols[name] = address,type
+    return symbols
+
+def export_list(symbols):
+
+    data = []
+    code = []
+    for name,(addr,type) in symbols.items():
+        if type in ('C','D'):
+            data.append('\t'+name)
+        else:
+            code.append('\t'+name)
+    data.sort()
+    data.append('')
+    code.sort()
+    return ' DATA\n'.join(data)+'\n'+'\n'.join(code)
+
+# Definition file template
+DEF_TEMPLATE = """\
+EXPORTS
+%s
+"""
+
+# Special symbols that have to be included even though they don't
+# pass the filter
+SPECIALS = (
+    )
+
+def filter_Python(symbols,specials=SPECIALS):
+
+    for name in symbols.keys():
+        if name[:2] == 'Py' or name[:3] == '_Py':
+            pass
+        elif name not in specials:
+            del symbols[name]
+
+def main():
+
+    s = symbols(PYTHONLIB)
+    filter_Python(s)
+    exports = export_list(s)
+    f = sys.stdout # open('PC/python_nt.def','w')
+    f.write(DEF_TEMPLATE % (exports))
+    f.close()
+
+if __name__ == '__main__':
+    main()


Property changes on: vendor/Python/current/Tools/scripts/nm2def.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/scripts/objgraph.py
===================================================================
--- vendor/Python/current/Tools/scripts/objgraph.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/objgraph.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,215 @@
+#! /usr/bin/env python
+
+# objgraph
+#
+# Read "nm -o" input (on IRIX: "nm -Bo") of a set of libraries or modules
+# and print various interesting listings, such as:
+#
+# - which names are used but not defined in the set (and used where),
+# - which names are defined in the set (and where),
+# - which modules use which other modules,
+# - which modules are used by which other modules.
+#
+# Usage: objgraph [-cdu] [file] ...
+# -c: print callers per objectfile
+# -d: print callees per objectfile
+# -u: print usage of undefined symbols
+# If none of -cdu is specified, all are assumed.
+# Use "nm -o" to generate the input (on IRIX: "nm -Bo"),
+# e.g.: nm -o /lib/libc.a | objgraph
+
+
+import sys
+import os
+import getopt
+import re
+
+# Types of symbols.
+#
+definitions = 'TRGDSBAEC'
+externals = 'UV'
+ignore = 'Nntrgdsbavuc'
+
+# Regular expression to parse "nm -o" output.
+#
+matcher = re.compile('(.*):\t?........ (.) (.*)$')
+
+# Store "item" in "dict" under "key".
+# The dictionary maps keys to lists of items.
+# If there is no list for the key yet, it is created.
+#
+def store(dict, key, item):
+    if dict.has_key(key):
+        dict[key].append(item)
+    else:
+        dict[key] = [item]
+
+# Return a flattened version of a list of strings: the concatenation
+# of its elements with intervening spaces.
+#
+def flat(list):
+    s = ''
+    for item in list:
+        s = s + ' ' + item
+    return s[1:]
+
+# Global variables mapping defined/undefined names to files and back.
+#
+file2undef = {}
+def2file = {}
+file2def = {}
+undef2file = {}
+
+# Read one input file and merge the data into the tables.
+# Argument is an open file.
+#
+def readinput(fp):
+    while 1:
+        s = fp.readline()
+        if not s:
+            break
+        # If you get any output from this line,
+        # it is probably caused by an unexpected input line:
+        if matcher.search(s) < 0: s; continue # Shouldn't happen
+        (ra, rb), (r1a, r1b), (r2a, r2b), (r3a, r3b) = matcher.regs[:4]
+        fn, name, type = s[r1a:r1b], s[r3a:r3b], s[r2a:r2b]
+        if type in definitions:
+            store(def2file, name, fn)
+            store(file2def, fn, name)
+        elif type in externals:
+            store(file2undef, fn, name)
+            store(undef2file, name, fn)
+        elif not type in ignore:
+            print fn + ':' + name + ': unknown type ' + type
+
+# Print all names that were undefined in some module and where they are
+# defined.
+#
+def printcallee():
+    flist = file2undef.keys()
+    flist.sort()
+    for filename in flist:
+        print filename + ':'
+        elist = file2undef[filename]
+        elist.sort()
+        for ext in elist:
+            if len(ext) >= 8:
+                tabs = '\t'
+            else:
+                tabs = '\t\t'
+            if not def2file.has_key(ext):
+                print '\t' + ext + tabs + ' *undefined'
+            else:
+                print '\t' + ext + tabs + flat(def2file[ext])
+
+# Print for each module the names of the other modules that use it.
+#
+def printcaller():
+    files = file2def.keys()
+    files.sort()
+    for filename in files:
+        callers = []
+        for label in file2def[filename]:
+            if undef2file.has_key(label):
+                callers = callers + undef2file[label]
+        if callers:
+            callers.sort()
+            print filename + ':'
+            lastfn = ''
+            for fn in callers:
+                if fn <> lastfn:
+                    print '\t' + fn
+                lastfn = fn
+        else:
+            print filename + ': unused'
+
+# Print undefined names and where they are used.
+#
+def printundef():
+    undefs = {}
+    for filename in file2undef.keys():
+        for ext in file2undef[filename]:
+            if not def2file.has_key(ext):
+                store(undefs, ext, filename)
+    elist = undefs.keys()
+    elist.sort()
+    for ext in elist:
+        print ext + ':'
+        flist = undefs[ext]
+        flist.sort()
+        for filename in flist:
+            print '\t' + filename
+
+# Print warning messages about names defined in more than one file.
+#
+def warndups():
+    savestdout = sys.stdout
+    sys.stdout = sys.stderr
+    names = def2file.keys()
+    names.sort()
+    for name in names:
+        if len(def2file[name]) > 1:
+            print 'warning:', name, 'multiply defined:',
+            print flat(def2file[name])
+    sys.stdout = savestdout
+
+# Main program
+#
+def main():
+    try:
+        optlist, args = getopt.getopt(sys.argv[1:], 'cdu')
+    except getopt.error:
+        sys.stdout = sys.stderr
+        print 'Usage:', os.path.basename(sys.argv[0]),
+        print           '[-cdu] [file] ...'
+        print '-c: print callers per objectfile'
+        print '-d: print callees per objectfile'
+        print '-u: print usage of undefined symbols'
+        print 'If none of -cdu is specified, all are assumed.'
+        print 'Use "nm -o" to generate the input (on IRIX: "nm -Bo"),'
+        print 'e.g.: nm -o /lib/libc.a | objgraph'
+        return 1
+    optu = optc = optd = 0
+    for opt, void in optlist:
+        if opt == '-u':
+            optu = 1
+        elif opt == '-c':
+            optc = 1
+        elif opt == '-d':
+            optd = 1
+    if optu == optc == optd == 0:
+        optu = optc = optd = 1
+    if not args:
+        args = ['-']
+    for filename in args:
+        if filename == '-':
+            readinput(sys.stdin)
+        else:
+            readinput(open(filename, 'r'))
+    #
+    warndups()
+    #
+    more = (optu + optc + optd > 1)
+    if optd:
+        if more:
+            print '---------------All callees------------------'
+        printcallee()
+    if optu:
+        if more:
+            print '---------------Undefined callees------------'
+        printundef()
+    if optc:
+        if more:
+            print '---------------All Callers------------------'
+        printcaller()
+    return 0
+
+# Call the main program.
+# Use its return value as exit status.
+# Catch interrupts to avoid stack trace.
+#
+if __name__ == '__main__':
+    try:
+        sys.exit(main())
+    except KeyboardInterrupt:
+        sys.exit(1)


Property changes on: vendor/Python/current/Tools/scripts/objgraph.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/scripts/parseentities.py
===================================================================
--- vendor/Python/current/Tools/scripts/parseentities.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/parseentities.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,64 @@
+#!/usr/local/bin/python
+""" Utility for parsing HTML entity definitions available from:
+
+      http://www.w3.org/ as e.g.
+      http://www.w3.org/TR/REC-html40/HTMLlat1.ent
+
+    Input is read from stdin, output is written to stdout in form of a
+    Python snippet defining a dictionary "entitydefs" mapping literal
+    entity name to character or numeric entity.
+
+    Marc-Andre Lemburg, mal at lemburg.com, 1999.
+    Use as you like. NO WARRANTIES.
+
+"""
+import re,sys
+import TextTools
+
+entityRE = re.compile('<!ENTITY +(\w+) +CDATA +"([^"]+)" +-- +((?:.|\n)+?) *-->')
+
+def parse(text,pos=0,endpos=None):
+
+    pos = 0
+    if endpos is None:
+        endpos = len(text)
+    d = {}
+    while 1:
+        m = entityRE.search(text,pos,endpos)
+        if not m:
+            break
+        name,charcode,comment = m.groups()
+        d[name] = charcode,comment
+        pos = m.end()
+    return d
+
+def writefile(f,defs):
+
+    f.write("entitydefs = {\n")
+    items = defs.items()
+    items.sort()
+    for name,(charcode,comment) in items:
+        if charcode[:2] == '&#':
+            code = int(charcode[2:-1])
+            if code < 256:
+                charcode = "'\%o'" % code
+            else:
+                charcode = repr(charcode)
+        else:
+            charcode = repr(charcode)
+        comment = TextTools.collapse(comment)
+        f.write("    '%s':\t%s,  \t# %s\n" % (name,charcode,comment))
+    f.write('\n}\n')
+
+if __name__ == '__main__':
+    if len(sys.argv) > 1:
+        infile = open(sys.argv[1])
+    else:
+        infile = sys.stdin
+    if len(sys.argv) > 2:
+        outfile = open(sys.argv[2],'w')
+    else:
+        outfile = sys.stdout
+    text = infile.read()
+    defs = parse(text)
+    writefile(outfile,defs)


Property changes on: vendor/Python/current/Tools/scripts/parseentities.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/scripts/pathfix.py
===================================================================
--- vendor/Python/current/Tools/scripts/pathfix.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/pathfix.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,149 @@
+#! /usr/bin/env python
+
+# Change the #! line occurring in Python scripts.  The new interpreter
+# pathname must be given with a -i option.
+#
+# Command line arguments are files or directories to be processed.
+# Directories are searched recursively for files whose name looks
+# like a python module.
+# Symbolic links are always ignored (except as explicit directory
+# arguments).  Of course, the original file is kept as a back-up
+# (with a "~" attached to its name).
+#
+# Undoubtedly you can do this using find and sed or perl, but this is
+# a nice example of Python code that recurses down a directory tree
+# and uses regular expressions.  Also note several subtleties like
+# preserving the file's mode and avoiding to even write a temp file
+# when no changes are needed for a file.
+#
+# NB: by changing only the function fixfile() you can turn this
+# into a program for a different change to Python programs...
+
+import sys
+import re
+import os
+from stat import *
+import getopt
+
+err = sys.stderr.write
+dbg = err
+rep = sys.stdout.write
+
+new_interpreter = None
+
+def main():
+    global new_interpreter
+    usage = ('usage: %s -i /interpreter file-or-directory ...\n' %
+             sys.argv[0])
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], 'i:')
+    except getopt.error, msg:
+        err(msg + '\n')
+        err(usage)
+        sys.exit(2)
+    for o, a in opts:
+        if o == '-i':
+            new_interpreter = a
+    if not new_interpreter or new_interpreter[0] != '/' or not args:
+        err('-i option or file-or-directory missing\n')
+        err(usage)
+        sys.exit(2)
+    bad = 0
+    for arg in args:
+        if os.path.isdir(arg):
+            if recursedown(arg): bad = 1
+        elif os.path.islink(arg):
+            err(arg + ': will not process symbolic links\n')
+            bad = 1
+        else:
+            if fix(arg): bad = 1
+    sys.exit(bad)
+
+ispythonprog = re.compile('^[a-zA-Z0-9_]+\.py$')
+def ispython(name):
+    return ispythonprog.match(name) >= 0
+
+def recursedown(dirname):
+    dbg('recursedown(%r)\n' % (dirname,))
+    bad = 0
+    try:
+        names = os.listdir(dirname)
+    except os.error, msg:
+        err('%s: cannot list directory: %r\n' % (dirname, msg))
+        return 1
+    names.sort()
+    subdirs = []
+    for name in names:
+        if name in (os.curdir, os.pardir): continue
+        fullname = os.path.join(dirname, name)
+        if os.path.islink(fullname): pass
+        elif os.path.isdir(fullname):
+            subdirs.append(fullname)
+        elif ispython(name):
+            if fix(fullname): bad = 1
+    for fullname in subdirs:
+        if recursedown(fullname): bad = 1
+    return bad
+
+def fix(filename):
+##  dbg('fix(%r)\n' % (filename,))
+    try:
+        f = open(filename, 'r')
+    except IOError, msg:
+        err('%s: cannot open: %r\n' % (filename, msg))
+        return 1
+    line = f.readline()
+    fixed = fixline(line)
+    if line == fixed:
+        rep(filename+': no change\n')
+        f.close()
+        return
+    head, tail = os.path.split(filename)
+    tempname = os.path.join(head, '@' + tail)
+    try:
+        g = open(tempname, 'w')
+    except IOError, msg:
+        f.close()
+        err('%s: cannot create: %r\n' % (tempname, msg))
+        return 1
+    rep(filename + ': updating\n')
+    g.write(fixed)
+    BUFSIZE = 8*1024
+    while 1:
+        buf = f.read(BUFSIZE)
+        if not buf: break
+        g.write(buf)
+    g.close()
+    f.close()
+
+    # Finishing touch -- move files
+
+    # First copy the file's mode to the temp file
+    try:
+        statbuf = os.stat(filename)
+        os.chmod(tempname, statbuf[ST_MODE] & 07777)
+    except os.error, msg:
+        err('%s: warning: chmod failed (%r)\n' % (tempname, msg))
+    # Then make a backup of the original file as filename~
+    try:
+        os.rename(filename, filename + '~')
+    except os.error, msg:
+        err('%s: warning: backup failed (%r)\n' % (filename, msg))
+    # Now move the temp file to the original file
+    try:
+        os.rename(tempname, filename)
+    except os.error, msg:
+        err('%s: rename failed (%r)\n' % (filename, msg))
+        return 1
+    # Return succes
+    return 0
+
+def fixline(line):
+    if not line.startswith('#!'):
+        return line
+    if "python" not in line:
+        return line
+    return '#! %s\n' % new_interpreter
+
+if __name__ == '__main__':
+    main()


Property changes on: vendor/Python/current/Tools/scripts/pathfix.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/scripts/pdeps.py
===================================================================
--- vendor/Python/current/Tools/scripts/pdeps.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/pdeps.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,167 @@
+#! /usr/bin/env python
+
+# pdeps
+#
+# Find dependencies between a bunch of Python modules.
+#
+# Usage:
+#       pdeps file1.py file2.py ...
+#
+# Output:
+# Four tables separated by lines like '--- Closure ---':
+# 1) Direct dependencies, listing which module imports which other modules
+# 2) The inverse of (1)
+# 3) Indirect dependencies, or the closure of the above
+# 4) The inverse of (3)
+#
+# To do:
+# - command line options to select output type
+# - option to automatically scan the Python library for referenced modules
+# - option to limit output to particular modules
+
+
+import sys
+import re
+import os
+
+
+# Main program
+#
+def main():
+    args = sys.argv[1:]
+    if not args:
+        print 'usage: pdeps file.py file.py ...'
+        return 2
+    #
+    table = {}
+    for arg in args:
+        process(arg, table)
+    #
+    print '--- Uses ---'
+    printresults(table)
+    #
+    print '--- Used By ---'
+    inv = inverse(table)
+    printresults(inv)
+    #
+    print '--- Closure of Uses ---'
+    reach = closure(table)
+    printresults(reach)
+    #
+    print '--- Closure of Used By ---'
+    invreach = inverse(reach)
+    printresults(invreach)
+    #
+    return 0
+
+
+# Compiled regular expressions to search for import statements
+#
+m_import = re.compile('^[ \t]*from[ \t]+([^ \t]+)[ \t]+')
+m_from = re.compile('^[ \t]*import[ \t]+([^#]+)')
+
+
+# Collect data from one file
+#
+def process(filename, table):
+    fp = open(filename, 'r')
+    mod = os.path.basename(filename)
+    if mod[-3:] == '.py':
+        mod = mod[:-3]
+    table[mod] = list = []
+    while 1:
+        line = fp.readline()
+        if not line: break
+        while line[-1:] == '\\':
+            nextline = fp.readline()
+            if not nextline: break
+            line = line[:-1] + nextline
+        if m_import.match(line) >= 0:
+            (a, b), (a1, b1) = m_import.regs[:2]
+        elif m_from.match(line) >= 0:
+            (a, b), (a1, b1) = m_from.regs[:2]
+        else: continue
+        words = line[a1:b1].split(',')
+        # print '#', line, words
+        for word in words:
+            word = word.strip()
+            if word not in list:
+                list.append(word)
+
+
+# Compute closure (this is in fact totally general)
+#
+def closure(table):
+    modules = table.keys()
+    #
+    # Initialize reach with a copy of table
+    #
+    reach = {}
+    for mod in modules:
+        reach[mod] = table[mod][:]
+    #
+    # Iterate until no more change
+    #
+    change = 1
+    while change:
+        change = 0
+        for mod in modules:
+            for mo in reach[mod]:
+                if mo in modules:
+                    for m in reach[mo]:
+                        if m not in reach[mod]:
+                            reach[mod].append(m)
+                            change = 1
+    #
+    return reach
+
+
+# Invert a table (this is again totally general).
+# All keys of the original table are made keys of the inverse,
+# so there may be empty lists in the inverse.
+#
+def inverse(table):
+    inv = {}
+    for key in table.keys():
+        if not inv.has_key(key):
+            inv[key] = []
+        for item in table[key]:
+            store(inv, item, key)
+    return inv
+
+
+# Store "item" in "dict" under "key".
+# The dictionary maps keys to lists of items.
+# If there is no list for the key yet, it is created.
+#
+def store(dict, key, item):
+    if dict.has_key(key):
+        dict[key].append(item)
+    else:
+        dict[key] = [item]
+
+
+# Tabulate results neatly
+#
+def printresults(table):
+    modules = table.keys()
+    maxlen = 0
+    for mod in modules: maxlen = max(maxlen, len(mod))
+    modules.sort()
+    for mod in modules:
+        list = table[mod]
+        list.sort()
+        print mod.ljust(maxlen), ':',
+        if mod in list:
+            print '(*)',
+        for ref in list:
+            print ref,
+        print
+
+
+# Call main and honor exit status
+if __name__ == '__main__':
+    try:
+        sys.exit(main())
+    except KeyboardInterrupt:
+        sys.exit(1)


Property changes on: vendor/Python/current/Tools/scripts/pdeps.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/scripts/pickle2db.py
===================================================================
--- vendor/Python/current/Tools/scripts/pickle2db.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/pickle2db.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,147 @@
+#!/usr/bin/env python
+
+"""
+Synopsis: %(prog)s [-h|-b|-g|-r|-a|-d] [ picklefile ] dbfile
+
+Read the given picklefile as a series of key/value pairs and write to a new
+database.  If the database already exists, any contents are deleted.  The
+optional flags indicate the type of the output database:
+
+    -a - open using anydbm
+    -b - open as bsddb btree file
+    -d - open as dbm file
+    -g - open as gdbm file
+    -h - open as bsddb hash file
+    -r - open as bsddb recno file
+
+The default is hash.  If a pickle file is named it is opened for read
+access.  If no pickle file is named, the pickle input is read from standard
+input.
+
+Note that recno databases can only contain integer keys, so you can't dump a
+hash or btree database using db2pickle.py and reconstitute it to a recno
+database with %(prog)s unless your keys are integers.
+
+"""
+
+import getopt
+try:
+    import bsddb
+except ImportError:
+    bsddb = None
+try:
+    import dbm
+except ImportError:
+    dbm = None
+try:
+    import gdbm
+except ImportError:
+    gdbm = None
+try:
+    import anydbm
+except ImportError:
+    anydbm = None
+import sys
+try:
+    import cPickle as pickle
+except ImportError:
+    import pickle
+
+prog = sys.argv[0]
+
+def usage():
+    sys.stderr.write(__doc__ % globals())
+
+def main(args):
+    try:
+        opts, args = getopt.getopt(args, "hbrdag",
+                                   ["hash", "btree", "recno", "dbm", "anydbm",
+                                    "gdbm"])
+    except getopt.error:
+        usage()
+        return 1
+
+    if len(args) == 0 or len(args) > 2:
+        usage()
+        return 1
+    elif len(args) == 1:
+        pfile = sys.stdin
+        dbfile = args[0]
+    else:
+        try:
+            pfile = open(args[0], 'rb')
+        except IOError:
+            sys.stderr.write("Unable to open %s\n" % args[0])
+            return 1
+        dbfile = args[1]
+
+    dbopen = None
+    for opt, arg in opts:
+        if opt in ("-h", "--hash"):
+            try:
+                dbopen = bsddb.hashopen
+            except AttributeError:
+                sys.stderr.write("bsddb module unavailable.\n")
+                return 1
+        elif opt in ("-b", "--btree"):
+            try:
+                dbopen = bsddb.btopen
+            except AttributeError:
+                sys.stderr.write("bsddb module unavailable.\n")
+                return 1
+        elif opt in ("-r", "--recno"):
+            try:
+                dbopen = bsddb.rnopen
+            except AttributeError:
+                sys.stderr.write("bsddb module unavailable.\n")
+                return 1
+        elif opt in ("-a", "--anydbm"):
+            try:
+                dbopen = anydbm.open
+            except AttributeError:
+                sys.stderr.write("anydbm module unavailable.\n")
+                return 1
+        elif opt in ("-g", "--gdbm"):
+            try:
+                dbopen = gdbm.open
+            except AttributeError:
+                sys.stderr.write("gdbm module unavailable.\n")
+                return 1
+        elif opt in ("-d", "--dbm"):
+            try:
+                dbopen = dbm.open
+            except AttributeError:
+                sys.stderr.write("dbm module unavailable.\n")
+                return 1
+    if dbopen is None:
+        if bsddb is None:
+            sys.stderr.write("bsddb module unavailable - ")
+            sys.stderr.write("must specify dbtype.\n")
+            return 1
+        else:
+            dbopen = bsddb.hashopen
+
+    try:
+        db = dbopen(dbfile, 'c')
+    except bsddb.error:
+        sys.stderr.write("Unable to open %s.  " % dbfile)
+        sys.stderr.write("Check for format or version mismatch.\n")
+        return 1
+    else:
+        for k in db.keys():
+            del db[k]
+
+    while 1:
+        try:
+            (key, val) = pickle.load(pfile)
+        except EOFError:
+            break
+        db[key] = val
+
+    db.close()
+    pfile.close()
+
+    return 0
+
+if __name__ == "__main__":
+    sys.exit(main(sys.argv[1:]))

Added: vendor/Python/current/Tools/scripts/pindent.py
===================================================================
--- vendor/Python/current/Tools/scripts/pindent.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/pindent.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,543 @@
+#! /usr/bin/env python
+
+# This file contains a class and a main program that perform three
+# related (though complimentary) formatting operations on Python
+# programs.  When called as "pindent -c", it takes a valid Python
+# program as input and outputs a version augmented with block-closing
+# comments.  When called as "pindent -d", it assumes its input is a
+# Python program with block-closing comments and outputs a commentless
+# version.   When called as "pindent -r" it assumes its input is a
+# Python program with block-closing comments but with its indentation
+# messed up, and outputs a properly indented version.
+
+# A "block-closing comment" is a comment of the form '# end <keyword>'
+# where <keyword> is the keyword that opened the block.  If the
+# opening keyword is 'def' or 'class', the function or class name may
+# be repeated in the block-closing comment as well.  Here is an
+# example of a program fully augmented with block-closing comments:
+
+# def foobar(a, b):
+#    if a == b:
+#        a = a+1
+#    elif a < b:
+#        b = b-1
+#        if b > a: a = a-1
+#        # end if
+#    else:
+#        print 'oops!'
+#    # end if
+# # end def foobar
+
+# Note that only the last part of an if...elif...else... block needs a
+# block-closing comment; the same is true for other compound
+# statements (e.g. try...except).  Also note that "short-form" blocks
+# like the second 'if' in the example must be closed as well;
+# otherwise the 'else' in the example would be ambiguous (remember
+# that indentation is not significant when interpreting block-closing
+# comments).
+
+# The operations are idempotent (i.e. applied to their own output
+# they yield an identical result).  Running first "pindent -c" and
+# then "pindent -r" on a valid Python program produces a program that
+# is semantically identical to the input (though its indentation may
+# be different). Running "pindent -e" on that output produces a
+# program that only differs from the original in indentation.
+
+# Other options:
+# -s stepsize: set the indentation step size (default 8)
+# -t tabsize : set the number of spaces a tab character is worth (default 8)
+# -e         : expand TABs into spaces
+# file ...   : input file(s) (default standard input)
+# The results always go to standard output
+
+# Caveats:
+# - comments ending in a backslash will be mistaken for continued lines
+# - continuations using backslash are always left unchanged
+# - continuations inside parentheses are not extra indented by -r
+#   but must be indented for -c to work correctly (this breaks
+#   idempotency!)
+# - continued lines inside triple-quoted strings are totally garbled
+
+# Secret feature:
+# - On input, a block may also be closed with an "end statement" --
+#   this is a block-closing comment without the '#' sign.
+
+# Possible improvements:
+# - check syntax based on transitions in 'next' table
+# - better error reporting
+# - better error recovery
+# - check identifier after class/def
+
+# The following wishes need a more complete tokenization of the source:
+# - Don't get fooled by comments ending in backslash
+# - reindent continuation lines indicated by backslash
+# - handle continuation lines inside parentheses/braces/brackets
+# - handle triple quoted strings spanning lines
+# - realign comments
+# - optionally do much more thorough reformatting, a la C indent
+
+# Defaults
+STEPSIZE = 8
+TABSIZE = 8
+EXPANDTABS = 0
+
+import os
+import re
+import sys
+
+next = {}
+next['if'] = next['elif'] = 'elif', 'else', 'end'
+next['while'] = next['for'] = 'else', 'end'
+next['try'] = 'except', 'finally'
+next['except'] = 'except', 'else', 'end'
+next['else'] = next['finally'] = next['def'] = next['class'] = 'end'
+next['end'] = ()
+start = 'if', 'while', 'for', 'try', 'def', 'class'
+
+class PythonIndenter:
+
+    def __init__(self, fpi = sys.stdin, fpo = sys.stdout,
+                 indentsize = STEPSIZE, tabsize = TABSIZE, expandtabs = EXPANDTABS):
+        self.fpi = fpi
+        self.fpo = fpo
+        self.indentsize = indentsize
+        self.tabsize = tabsize
+        self.lineno = 0
+        self.expandtabs = expandtabs
+        self._write = fpo.write
+        self.kwprog = re.compile(
+                r'^\s*(?P<kw>[a-z]+)'
+                r'(\s+(?P<id>[a-zA-Z_]\w*))?'
+                r'[^\w]')
+        self.endprog = re.compile(
+                r'^\s*#?\s*end\s+(?P<kw>[a-z]+)'
+                r'(\s+(?P<id>[a-zA-Z_]\w*))?'
+                r'[^\w]')
+        self.wsprog = re.compile(r'^[ \t]*')
+    # end def __init__
+
+    def write(self, line):
+        if self.expandtabs:
+            self._write(line.expandtabs(self.tabsize))
+        else:
+            self._write(line)
+        # end if
+    # end def write
+
+    def readline(self):
+        line = self.fpi.readline()
+        if line: self.lineno = self.lineno + 1
+        # end if
+        return line
+    # end def readline
+
+    def error(self, fmt, *args):
+        if args: fmt = fmt % args
+        # end if
+        sys.stderr.write('Error at line %d: %s\n' % (self.lineno, fmt))
+        self.write('### %s ###\n' % fmt)
+    # end def error
+
+    def getline(self):
+        line = self.readline()
+        while line[-2:] == '\\\n':
+            line2 = self.readline()
+            if not line2: break
+            # end if
+            line = line + line2
+        # end while
+        return line
+    # end def getline
+
+    def putline(self, line, indent = None):
+        if indent is None:
+            self.write(line)
+            return
+        # end if
+        tabs, spaces = divmod(indent*self.indentsize, self.tabsize)
+        i = 0
+        m = self.wsprog.match(line)
+        if m: i = m.end()
+        # end if
+        self.write('\t'*tabs + ' '*spaces + line[i:])
+    # end def putline
+
+    def reformat(self):
+        stack = []
+        while 1:
+            line = self.getline()
+            if not line: break      # EOF
+            # end if
+            m = self.endprog.match(line)
+            if m:
+                kw = 'end'
+                kw2 = m.group('kw')
+                if not stack:
+                    self.error('unexpected end')
+                elif stack[-1][0] != kw2:
+                    self.error('unmatched end')
+                # end if
+                del stack[-1:]
+                self.putline(line, len(stack))
+                continue
+            # end if
+            m = self.kwprog.match(line)
+            if m:
+                kw = m.group('kw')
+                if kw in start:
+                    self.putline(line, len(stack))
+                    stack.append((kw, kw))
+                    continue
+                # end if
+                if next.has_key(kw) and stack:
+                    self.putline(line, len(stack)-1)
+                    kwa, kwb = stack[-1]
+                    stack[-1] = kwa, kw
+                    continue
+                # end if
+            # end if
+            self.putline(line, len(stack))
+        # end while
+        if stack:
+            self.error('unterminated keywords')
+            for kwa, kwb in stack:
+                self.write('\t%s\n' % kwa)
+            # end for
+        # end if
+    # end def reformat
+
+    def delete(self):
+        begin_counter = 0
+        end_counter = 0
+        while 1:
+            line = self.getline()
+            if not line: break      # EOF
+            # end if
+            m = self.endprog.match(line)
+            if m:
+                end_counter = end_counter + 1
+                continue
+            # end if
+            m = self.kwprog.match(line)
+            if m:
+                kw = m.group('kw')
+                if kw in start:
+                    begin_counter = begin_counter + 1
+                # end if
+            # end if
+            self.putline(line)
+        # end while
+        if begin_counter - end_counter < 0:
+            sys.stderr.write('Warning: input contained more end tags than expected\n')
+        elif begin_counter - end_counter > 0:
+            sys.stderr.write('Warning: input contained less end tags than expected\n')
+        # end if
+    # end def delete
+
+    def complete(self):
+        self.indentsize = 1
+        stack = []
+        todo = []
+        thisid = ''
+        current, firstkw, lastkw, topid = 0, '', '', ''
+        while 1:
+            line = self.getline()
+            i = 0
+            m = self.wsprog.match(line)
+            if m: i = m.end()
+            # end if
+            m = self.endprog.match(line)
+            if m:
+                thiskw = 'end'
+                endkw = m.group('kw')
+                thisid = m.group('id')
+            else:
+                m = self.kwprog.match(line)
+                if m:
+                    thiskw = m.group('kw')
+                    if not next.has_key(thiskw):
+                        thiskw = ''
+                    # end if
+                    if thiskw in ('def', 'class'):
+                        thisid = m.group('id')
+                    else:
+                        thisid = ''
+                    # end if
+                elif line[i:i+1] in ('\n', '#'):
+                    todo.append(line)
+                    continue
+                else:
+                    thiskw = ''
+                # end if
+            # end if
+            indent = len(line[:i].expandtabs(self.tabsize))
+            while indent < current:
+                if firstkw:
+                    if topid:
+                        s = '# end %s %s\n' % (
+                                firstkw, topid)
+                    else:
+                        s = '# end %s\n' % firstkw
+                    # end if
+                    self.putline(s, current)
+                    firstkw = lastkw = ''
+                # end if
+                current, firstkw, lastkw, topid = stack[-1]
+                del stack[-1]
+            # end while
+            if indent == current and firstkw:
+                if thiskw == 'end':
+                    if endkw != firstkw:
+                        self.error('mismatched end')
+                    # end if
+                    firstkw = lastkw = ''
+                elif not thiskw or thiskw in start:
+                    if topid:
+                        s = '# end %s %s\n' % (
+                                firstkw, topid)
+                    else:
+                        s = '# end %s\n' % firstkw
+                    # end if
+                    self.putline(s, current)
+                    firstkw = lastkw = topid = ''
+                # end if
+            # end if
+            if indent > current:
+                stack.append((current, firstkw, lastkw, topid))
+                if thiskw and thiskw not in start:
+                    # error
+                    thiskw = ''
+                # end if
+                current, firstkw, lastkw, topid = \
+                         indent, thiskw, thiskw, thisid
+            # end if
+            if thiskw:
+                if thiskw in start:
+                    firstkw = lastkw = thiskw
+                    topid = thisid
+                else:
+                    lastkw = thiskw
+                # end if
+            # end if
+            for l in todo: self.write(l)
+            # end for
+            todo = []
+            if not line: break
+            # end if
+            self.write(line)
+        # end while
+    # end def complete
+
+# end class PythonIndenter
+
+# Simplified user interface
+# - xxx_filter(input, output): read and write file objects
+# - xxx_string(s): take and return string object
+# - xxx_file(filename): process file in place, return true iff changed
+
+def complete_filter(input = sys.stdin, output = sys.stdout,
+                    stepsize = STEPSIZE, tabsize = TABSIZE, expandtabs = EXPANDTABS):
+    pi = PythonIndenter(input, output, stepsize, tabsize, expandtabs)
+    pi.complete()
+# end def complete_filter
+
+def delete_filter(input= sys.stdin, output = sys.stdout,
+                        stepsize = STEPSIZE, tabsize = TABSIZE, expandtabs = EXPANDTABS):
+    pi = PythonIndenter(input, output, stepsize, tabsize, expandtabs)
+    pi.delete()
+# end def delete_filter
+
+def reformat_filter(input = sys.stdin, output = sys.stdout,
+                    stepsize = STEPSIZE, tabsize = TABSIZE, expandtabs = EXPANDTABS):
+    pi = PythonIndenter(input, output, stepsize, tabsize, expandtabs)
+    pi.reformat()
+# end def reformat_filter
+
+class StringReader:
+    def __init__(self, buf):
+        self.buf = buf
+        self.pos = 0
+        self.len = len(self.buf)
+    # end def __init__
+    def read(self, n = 0):
+        if n <= 0:
+            n = self.len - self.pos
+        else:
+            n = min(n, self.len - self.pos)
+        # end if
+        r = self.buf[self.pos : self.pos + n]
+        self.pos = self.pos + n
+        return r
+    # end def read
+    def readline(self):
+        i = self.buf.find('\n', self.pos)
+        return self.read(i + 1 - self.pos)
+    # end def readline
+    def readlines(self):
+        lines = []
+        line = self.readline()
+        while line:
+            lines.append(line)
+            line = self.readline()
+        # end while
+        return lines
+    # end def readlines
+    # seek/tell etc. are left as an exercise for the reader
+# end class StringReader
+
+class StringWriter:
+    def __init__(self):
+        self.buf = ''
+    # end def __init__
+    def write(self, s):
+        self.buf = self.buf + s
+    # end def write
+    def getvalue(self):
+        return self.buf
+    # end def getvalue
+# end class StringWriter
+
+def complete_string(source, stepsize = STEPSIZE, tabsize = TABSIZE, expandtabs = EXPANDTABS):
+    input = StringReader(source)
+    output = StringWriter()
+    pi = PythonIndenter(input, output, stepsize, tabsize, expandtabs)
+    pi.complete()
+    return output.getvalue()
+# end def complete_string
+
+def delete_string(source, stepsize = STEPSIZE, tabsize = TABSIZE, expandtabs = EXPANDTABS):
+    input = StringReader(source)
+    output = StringWriter()
+    pi = PythonIndenter(input, output, stepsize, tabsize, expandtabs)
+    pi.delete()
+    return output.getvalue()
+# end def delete_string
+
+def reformat_string(source, stepsize = STEPSIZE, tabsize = TABSIZE, expandtabs = EXPANDTABS):
+    input = StringReader(source)
+    output = StringWriter()
+    pi = PythonIndenter(input, output, stepsize, tabsize, expandtabs)
+    pi.reformat()
+    return output.getvalue()
+# end def reformat_string
+
+def complete_file(filename, stepsize = STEPSIZE, tabsize = TABSIZE, expandtabs = EXPANDTABS):
+    source = open(filename, 'r').read()
+    result = complete_string(source, stepsize, tabsize, expandtabs)
+    if source == result: return 0
+    # end if
+    import os
+    try: os.rename(filename, filename + '~')
+    except os.error: pass
+    # end try
+    f = open(filename, 'w')
+    f.write(result)
+    f.close()
+    return 1
+# end def complete_file
+
+def delete_file(filename, stepsize = STEPSIZE, tabsize = TABSIZE, expandtabs = EXPANDTABS):
+    source = open(filename, 'r').read()
+    result = delete_string(source, stepsize, tabsize, expandtabs)
+    if source == result: return 0
+    # end if
+    import os
+    try: os.rename(filename, filename + '~')
+    except os.error: pass
+    # end try
+    f = open(filename, 'w')
+    f.write(result)
+    f.close()
+    return 1
+# end def delete_file
+
+def reformat_file(filename, stepsize = STEPSIZE, tabsize = TABSIZE, expandtabs = EXPANDTABS):
+    source = open(filename, 'r').read()
+    result = reformat_string(source, stepsize, tabsize, expandtabs)
+    if source == result: return 0
+    # end if
+    import os
+    try: os.rename(filename, filename + '~')
+    except os.error: pass
+    # end try
+    f = open(filename, 'w')
+    f.write(result)
+    f.close()
+    return 1
+# end def reformat_file
+
+# Test program when called as a script
+
+usage = """
+usage: pindent (-c|-d|-r) [-s stepsize] [-t tabsize] [-e] [file] ...
+-c         : complete a correctly indented program (add #end directives)
+-d         : delete #end directives
+-r         : reformat a completed program (use #end directives)
+-s stepsize: indentation step (default %(STEPSIZE)d)
+-t tabsize : the worth in spaces of a tab (default %(TABSIZE)d)
+-e         : expand TABs into spaces (defailt OFF)
+[file] ... : files are changed in place, with backups in file~
+If no files are specified or a single - is given,
+the program acts as a filter (reads stdin, writes stdout).
+""" % vars()
+
+def error_both(op1, op2):
+    sys.stderr.write('Error: You can not specify both '+op1+' and -'+op2[0]+' at the same time\n')
+    sys.stderr.write(usage)
+    sys.exit(2)
+# end def error_both
+
+def test():
+    import getopt
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], 'cdrs:t:e')
+    except getopt.error, msg:
+        sys.stderr.write('Error: %s\n' % msg)
+        sys.stderr.write(usage)
+        sys.exit(2)
+    # end try
+    action = None
+    stepsize = STEPSIZE
+    tabsize = TABSIZE
+    expandtabs = EXPANDTABS
+    for o, a in opts:
+        if o == '-c':
+            if action: error_both(o, action)
+            # end if
+            action = 'complete'
+        elif o == '-d':
+            if action: error_both(o, action)
+            # end if
+            action = 'delete'
+        elif o == '-r':
+            if action: error_both(o, action)
+            # end if
+            action = 'reformat'
+        elif o == '-s':
+            stepsize = int(a)
+        elif o == '-t':
+            tabsize = int(a)
+        elif o == '-e':
+            expandtabs = 1
+        # end if
+    # end for
+    if not action:
+        sys.stderr.write(
+                'You must specify -c(omplete), -d(elete) or -r(eformat)\n')
+        sys.stderr.write(usage)
+        sys.exit(2)
+    # end if
+    if not args or args == ['-']:
+        action = eval(action + '_filter')
+        action(sys.stdin, sys.stdout, stepsize, tabsize, expandtabs)
+    else:
+        action = eval(action + '_file')
+        for filename in args:
+            action(filename, stepsize, tabsize, expandtabs)
+        # end for
+    # end if
+# end def test
+
+if __name__ == '__main__':
+    test()
+# end if


Property changes on: vendor/Python/current/Tools/scripts/pindent.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/scripts/ptags.py
===================================================================
--- vendor/Python/current/Tools/scripts/ptags.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/ptags.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,53 @@
+#! /usr/bin/env python
+
+# ptags
+#
+# Create a tags file for Python programs, usable with vi.
+# Tagged are:
+# - functions (even inside other defs or classes)
+# - classes
+# - filenames
+# Warns about files it cannot open.
+# No warnings about duplicate tags.
+
+import sys, re, os
+
+tags = []    # Modified global variable!
+
+def main():
+    args = sys.argv[1:]
+    for filename in args:
+        treat_file(filename)
+    if tags:
+        fp = open('tags', 'w')
+        tags.sort()
+        for s in tags: fp.write(s)
+
+
+expr = '^[ \t]*(def|class)[ \t]+([a-zA-Z0-9_]+)[ \t]*[:\(]'
+matcher = re.compile(expr)
+
+def treat_file(filename):
+    try:
+        fp = open(filename, 'r')
+    except:
+        sys.stderr.write('Cannot open %s\n' % filename)
+        return
+    base = os.path.basename(filename)
+    if base[-3:] == '.py':
+        base = base[:-3]
+    s = base + '\t' + filename + '\t' + '1\n'
+    tags.append(s)
+    while 1:
+        line = fp.readline()
+        if not line:
+            break
+        m = matcher.match(line)
+        if m:
+            content = m.group(0)
+            name = m.group(2)
+            s = name + '\t' + filename + '\t/^' + content + '/\n'
+            tags.append(s)
+
+if __name__ == '__main__':
+    main()


Property changes on: vendor/Python/current/Tools/scripts/ptags.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/scripts/pydoc
===================================================================
--- vendor/Python/current/Tools/scripts/pydoc	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/pydoc	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,5 @@
+#!/usr/bin/env python
+
+import pydoc
+if __name__ == '__main__':
+    pydoc.cli()


Property changes on: vendor/Python/current/Tools/scripts/pydoc
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/scripts/pydocgui.pyw
===================================================================
--- vendor/Python/current/Tools/scripts/pydocgui.pyw	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/pydocgui.pyw	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,7 @@
+# Note:  this file must not be named pydoc.pyw, lest it just end up
+# importing itself (Python began allowing import of .pyw files
+# between 2.2a1 and 2.2a2).
+import pydoc
+
+if __name__ == '__main__':
+   pydoc.gui()

Added: vendor/Python/current/Tools/scripts/pysource.py
===================================================================
--- vendor/Python/current/Tools/scripts/pysource.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/pysource.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,130 @@
+#!/usr/bin/env python
+
+"""\
+List python source files.
+
+There are three functions to check whether a file is a Python source, listed
+here with increasing complexity:
+
+- has_python_ext() checks whether a file name ends in '.py[w]'.
+- look_like_python() checks whether the file is not binary and either has
+  the '.py[w]' extension or the first line contains the word 'python'.
+- can_be_compiled() checks whether the file can be compiled by compile().
+
+The file also must be of appropriate size - not bigger than a megabyte.
+
+walk_python_files() recursively lists all Python files under the given directories.
+"""
+__author__ = "Oleg Broytmann, Georg Brandl"
+
+__all__ = ["has_python_ext", "looks_like_python", "can_be_compiled", "walk_python_files"]
+
+
+import sys, os, re
+
+binary_re = re.compile('[\x00-\x08\x0E-\x1F\x7F]')
+
+debug = False
+
+def print_debug(msg):
+    if debug: print msg
+
+
+def _open(fullpath):
+    try:
+        size = os.stat(fullpath).st_size
+    except OSError, err: # Permission denied - ignore the file
+        print_debug("%s: permission denied: %s" % (fullpath, err))
+        return None
+
+    if size > 1024*1024: # too big
+        print_debug("%s: the file is too big: %d bytes" % (fullpath, size))
+        return None
+
+    try:
+        return open(fullpath, 'rU')
+    except IOError, err: # Access denied, or a special file - ignore it
+        print_debug("%s: access denied: %s" % (fullpath, err))
+        return None
+
+def has_python_ext(fullpath):
+    return fullpath.endswith(".py") or fullpath.endswith(".pyw")
+
+def looks_like_python(fullpath):
+    infile = _open(fullpath)
+    if infile is None:
+        return False
+
+    line = infile.readline()
+    infile.close()
+
+    if binary_re.search(line):
+        # file appears to be binary
+        print_debug("%s: appears to be binary" % fullpath)
+        return False
+
+    if fullpath.endswith(".py") or fullpath.endswith(".pyw"):
+        return True
+    elif "python" in line:
+        # disguised Python script (e.g. CGI)
+        return True
+
+    return False
+
+def can_be_compiled(fullpath):
+    infile = _open(fullpath)
+    if infile is None:
+        return False
+
+    code = infile.read()
+    infile.close()
+
+    try:
+        compile(code, fullpath, "exec")
+    except Exception, err:
+        print_debug("%s: cannot compile: %s" % (fullpath, err))
+        return False
+
+    return True
+
+
+def walk_python_files(paths, is_python=looks_like_python, exclude_dirs=None):
+    """\
+    Recursively yield all Python source files below the given paths.
+
+    paths: a list of files and/or directories to be checked.
+    is_python: a function that takes a file name and checks whether it is a
+               Python source file
+    exclude_dirs: a list of directory base names that should be excluded in
+                  the search
+    """
+    if exclude_dirs is None:
+        exclude_dirs=[]
+
+    for path in paths:
+        print_debug("testing: %s" % path)
+        if os.path.isfile(path):
+            if is_python(path):
+                yield path
+        elif os.path.isdir(path):
+            print_debug("    it is a directory")
+            for dirpath, dirnames, filenames in os.walk(path):
+                for exclude in exclude_dirs:
+                    if exclude in dirnames:
+                        dirnames.remove(exclude)
+                for filename in filenames:
+                    fullpath = os.path.join(dirpath, filename)
+                    print_debug("testing: %s" % fullpath)
+                    if is_python(fullpath):
+                        yield fullpath
+        else:
+            print_debug("    unknown type")
+
+
+if __name__ == "__main__":
+    # Two simple examples/tests
+    for fullpath in walk_python_files(['.']):
+        print fullpath
+    print "----------"
+    for fullpath in walk_python_files(['.'], is_python=can_be_compiled):
+        print fullpath

Added: vendor/Python/current/Tools/scripts/redemo.py
===================================================================
--- vendor/Python/current/Tools/scripts/redemo.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/redemo.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,171 @@
+"""Basic regular expression demostration facility (Perl style syntax)."""
+
+from Tkinter import *
+import re
+
+class ReDemo:
+
+    def __init__(self, master):
+        self.master = master
+
+        self.promptdisplay = Label(self.master, anchor=W,
+                text="Enter a Perl-style regular expression:")
+        self.promptdisplay.pack(side=TOP, fill=X)
+
+        self.regexdisplay = Entry(self.master)
+        self.regexdisplay.pack(fill=X)
+        self.regexdisplay.focus_set()
+
+        self.addoptions()
+
+        self.statusdisplay = Label(self.master, text="", anchor=W)
+        self.statusdisplay.pack(side=TOP, fill=X)
+
+        self.labeldisplay = Label(self.master, anchor=W,
+                text="Enter a string to search:")
+        self.labeldisplay.pack(fill=X)
+        self.labeldisplay.pack(fill=X)
+
+        self.showframe = Frame(master)
+        self.showframe.pack(fill=X, anchor=W)
+
+        self.showvar = StringVar(master)
+        self.showvar.set("first")
+
+        self.showfirstradio = Radiobutton(self.showframe,
+                                         text="Highlight first match",
+                                          variable=self.showvar,
+                                          value="first",
+                                          command=self.recompile)
+        self.showfirstradio.pack(side=LEFT)
+
+        self.showallradio = Radiobutton(self.showframe,
+                                        text="Highlight all matches",
+                                        variable=self.showvar,
+                                        value="all",
+                                        command=self.recompile)
+        self.showallradio.pack(side=LEFT)
+
+        self.stringdisplay = Text(self.master, width=60, height=4)
+        self.stringdisplay.pack(fill=BOTH, expand=1)
+        self.stringdisplay.tag_configure("hit", background="yellow")
+
+        self.grouplabel = Label(self.master, text="Groups:", anchor=W)
+        self.grouplabel.pack(fill=X)
+
+        self.grouplist = Listbox(self.master)
+        self.grouplist.pack(expand=1, fill=BOTH)
+
+        self.regexdisplay.bind('<Key>', self.recompile)
+        self.stringdisplay.bind('<Key>', self.reevaluate)
+
+        self.compiled = None
+        self.recompile()
+
+        btags = self.regexdisplay.bindtags()
+        self.regexdisplay.bindtags(btags[1:] + btags[:1])
+
+        btags = self.stringdisplay.bindtags()
+        self.stringdisplay.bindtags(btags[1:] + btags[:1])
+
+    def addoptions(self):
+        self.frames = []
+        self.boxes = []
+        self.vars = []
+        for name in ('IGNORECASE',
+                     'LOCALE',
+                     'MULTILINE',
+                     'DOTALL',
+                     'VERBOSE'):
+            if len(self.boxes) % 3 == 0:
+                frame = Frame(self.master)
+                frame.pack(fill=X)
+                self.frames.append(frame)
+            val = getattr(re, name)
+            var = IntVar()
+            box = Checkbutton(frame,
+                    variable=var, text=name,
+                    offvalue=0, onvalue=val,
+                    command=self.recompile)
+            box.pack(side=LEFT)
+            self.boxes.append(box)
+            self.vars.append(var)
+
+    def getflags(self):
+        flags = 0
+        for var in self.vars:
+            flags = flags | var.get()
+        flags = flags
+        return flags
+
+    def recompile(self, event=None):
+        try:
+            self.compiled = re.compile(self.regexdisplay.get(),
+                                       self.getflags())
+            bg = self.promptdisplay['background']
+            self.statusdisplay.config(text="", background=bg)
+        except re.error, msg:
+            self.compiled = None
+            self.statusdisplay.config(
+                    text="re.error: %s" % str(msg),
+                    background="red")
+        self.reevaluate()
+
+    def reevaluate(self, event=None):
+        try:
+            self.stringdisplay.tag_remove("hit", "1.0", END)
+        except TclError:
+            pass
+        try:
+            self.stringdisplay.tag_remove("hit0", "1.0", END)
+        except TclError:
+            pass
+        self.grouplist.delete(0, END)
+        if not self.compiled:
+            return
+        self.stringdisplay.tag_configure("hit", background="yellow")
+        self.stringdisplay.tag_configure("hit0", background="orange")
+        text = self.stringdisplay.get("1.0", END)
+        last = 0
+        nmatches = 0
+        while last <= len(text):
+            m = self.compiled.search(text, last)
+            if m is None:
+                break
+            first, last = m.span()
+            if last == first:
+                last = first+1
+                tag = "hit0"
+            else:
+                tag = "hit"
+            pfirst = "1.0 + %d chars" % first
+            plast = "1.0 + %d chars" % last
+            self.stringdisplay.tag_add(tag, pfirst, plast)
+            if nmatches == 0:
+                self.stringdisplay.yview_pickplace(pfirst)
+                groups = list(m.groups())
+                groups.insert(0, m.group())
+                for i in range(len(groups)):
+                    g = "%2d: %r" % (i, groups[i])
+                    self.grouplist.insert(END, g)
+            nmatches = nmatches + 1
+            if self.showvar.get() == "first":
+                break
+
+        if nmatches == 0:
+            self.statusdisplay.config(text="(no match)",
+                                      background="yellow")
+        else:
+            self.statusdisplay.config(text="")
+
+
+# Main function, run when invoked as a stand-alone Python program.
+
+def main():
+    root = Tk()
+    demo = ReDemo(root)
+    root.protocol('WM_DELETE_WINDOW', root.quit)
+    root.mainloop()
+
+if __name__ == '__main__':
+    main()

Added: vendor/Python/current/Tools/scripts/reindent.py
===================================================================
--- vendor/Python/current/Tools/scripts/reindent.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/reindent.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,293 @@
+#! /usr/bin/env python
+
+# Released to the public domain, by Tim Peters, 03 October 2000.
+
+"""reindent [-d][-r][-v] [ path ... ]
+
+-d (--dryrun)  Dry run.  Analyze, but don't make any changes to, files.
+-r (--recurse) Recurse.  Search for all .py files in subdirectories too.
+-v (--verbose) Verbose.  Print informative msgs; else no output.
+-h (--help)    Help.     Print this usage information and exit.
+
+Change Python (.py) files to use 4-space indents and no hard tab characters.
+Also trim excess spaces and tabs from ends of lines, and remove empty lines
+at the end of files.  Also ensure the last line ends with a newline.
+
+If no paths are given on the command line, reindent operates as a filter,
+reading a single source file from standard input and writing the transformed
+source to standard output.  In this case, the -d, -r and -v flags are
+ignored.
+
+You can pass one or more file and/or directory paths.  When a directory
+path, all .py files within the directory will be examined, and, if the -r
+option is given, likewise recursively for subdirectories.
+
+If output is not to standard output, reindent overwrites files in place,
+renaming the originals with a .bak extension.  If it finds nothing to
+change, the file is left alone.  If reindent does change a file, the changed
+file is a fixed-point for future runs (i.e., running reindent on the
+resulting .py file won't change it again).
+
+The hard part of reindenting is figuring out what to do with comment
+lines.  So long as the input files get a clean bill of health from
+tabnanny.py, reindent should do a good job.
+"""
+
+__version__ = "1"
+
+import tokenize
+import os
+import sys
+
+verbose = 0
+recurse = 0
+dryrun  = 0
+
+def usage(msg=None):
+    if msg is not None:
+        print >> sys.stderr, msg
+    print >> sys.stderr, __doc__
+
+def errprint(*args):
+    sep = ""
+    for arg in args:
+        sys.stderr.write(sep + str(arg))
+        sep = " "
+    sys.stderr.write("\n")
+
+def main():
+    import getopt
+    global verbose, recurse, dryrun
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], "drvh",
+                                   ["dryrun", "recurse", "verbose", "help"])
+    except getopt.error, msg:
+        usage(msg)
+        return
+    for o, a in opts:
+        if o in ('-d', '--dryrun'):
+            dryrun += 1
+        elif o in ('-r', '--recurse'):
+            recurse += 1
+        elif o in ('-v', '--verbose'):
+            verbose += 1
+        elif o in ('-h', '--help'):
+            usage()
+            return
+    if not args:
+        r = Reindenter(sys.stdin)
+        r.run()
+        r.write(sys.stdout)
+        return
+    for arg in args:
+        check(arg)
+
+def check(file):
+    if os.path.isdir(file) and not os.path.islink(file):
+        if verbose:
+            print "listing directory", file
+        names = os.listdir(file)
+        for name in names:
+            fullname = os.path.join(file, name)
+            if ((recurse and os.path.isdir(fullname) and
+                 not os.path.islink(fullname))
+                or name.lower().endswith(".py")):
+                check(fullname)
+        return
+
+    if verbose:
+        print "checking", file, "...",
+    try:
+        f = open(file)
+    except IOError, msg:
+        errprint("%s: I/O Error: %s" % (file, str(msg)))
+        return
+
+    r = Reindenter(f)
+    f.close()
+    if r.run():
+        if verbose:
+            print "changed."
+            if dryrun:
+                print "But this is a dry run, so leaving it alone."
+        if not dryrun:
+            bak = file + ".bak"
+            if os.path.exists(bak):
+                os.remove(bak)
+            os.rename(file, bak)
+            if verbose:
+                print "renamed", file, "to", bak
+            f = open(file, "w")
+            r.write(f)
+            f.close()
+            if verbose:
+                print "wrote new", file
+    else:
+        if verbose:
+            print "unchanged."
+
+def _rstrip(line, JUNK='\n \t'):
+    """Return line stripped of trailing spaces, tabs, newlines.
+
+    Note that line.rstrip() instead also strips sundry control characters,
+    but at least one known Emacs user expects to keep junk like that, not
+    mentioning Barry by name or anything <wink>.
+    """
+
+    i = len(line)
+    while i > 0 and line[i-1] in JUNK:
+        i -= 1
+    return line[:i]
+
+class Reindenter:
+
+    def __init__(self, f):
+        self.find_stmt = 1  # next token begins a fresh stmt?
+        self.level = 0      # current indent level
+
+        # Raw file lines.
+        self.raw = f.readlines()
+
+        # File lines, rstripped & tab-expanded.  Dummy at start is so
+        # that we can use tokenize's 1-based line numbering easily.
+        # Note that a line is all-blank iff it's "\n".
+        self.lines = [_rstrip(line).expandtabs() + "\n"
+                      for line in self.raw]
+        self.lines.insert(0, None)
+        self.index = 1  # index into self.lines of next line
+
+        # List of (lineno, indentlevel) pairs, one for each stmt and
+        # comment line.  indentlevel is -1 for comment lines, as a
+        # signal that tokenize doesn't know what to do about them;
+        # indeed, they're our headache!
+        self.stats = []
+
+    def run(self):
+        tokenize.tokenize(self.getline, self.tokeneater)
+        # Remove trailing empty lines.
+        lines = self.lines
+        while lines and lines[-1] == "\n":
+            lines.pop()
+        # Sentinel.
+        stats = self.stats
+        stats.append((len(lines), 0))
+        # Map count of leading spaces to # we want.
+        have2want = {}
+        # Program after transformation.
+        after = self.after = []
+        # Copy over initial empty lines -- there's nothing to do until
+        # we see a line with *something* on it.
+        i = stats[0][0]
+        after.extend(lines[1:i])
+        for i in range(len(stats)-1):
+            thisstmt, thislevel = stats[i]
+            nextstmt = stats[i+1][0]
+            have = getlspace(lines[thisstmt])
+            want = thislevel * 4
+            if want < 0:
+                # A comment line.
+                if have:
+                    # An indented comment line.  If we saw the same
+                    # indentation before, reuse what it most recently
+                    # mapped to.
+                    want = have2want.get(have, -1)
+                    if want < 0:
+                        # Then it probably belongs to the next real stmt.
+                        for j in xrange(i+1, len(stats)-1):
+                            jline, jlevel = stats[j]
+                            if jlevel >= 0:
+                                if have == getlspace(lines[jline]):
+                                    want = jlevel * 4
+                                break
+                    if want < 0:           # Maybe it's a hanging
+                                           # comment like this one,
+                        # in which case we should shift it like its base
+                        # line got shifted.
+                        for j in xrange(i-1, -1, -1):
+                            jline, jlevel = stats[j]
+                            if jlevel >= 0:
+                                want = have + getlspace(after[jline-1]) - \
+                                       getlspace(lines[jline])
+                                break
+                    if want < 0:
+                        # Still no luck -- leave it alone.
+                        want = have
+                else:
+                    want = 0
+            assert want >= 0
+            have2want[have] = want
+            diff = want - have
+            if diff == 0 or have == 0:
+                after.extend(lines[thisstmt:nextstmt])
+            else:
+                for line in lines[thisstmt:nextstmt]:
+                    if diff > 0:
+                        if line == "\n":
+                            after.append(line)
+                        else:
+                            after.append(" " * diff + line)
+                    else:
+                        remove = min(getlspace(line), -diff)
+                        after.append(line[remove:])
+        return self.raw != self.after
+
+    def write(self, f):
+        f.writelines(self.after)
+
+    # Line-getter for tokenize.
+    def getline(self):
+        if self.index >= len(self.lines):
+            line = ""
+        else:
+            line = self.lines[self.index]
+            self.index += 1
+        return line
+
+    # Line-eater for tokenize.
+    def tokeneater(self, type, token, (sline, scol), end, line,
+                   INDENT=tokenize.INDENT,
+                   DEDENT=tokenize.DEDENT,
+                   NEWLINE=tokenize.NEWLINE,
+                   COMMENT=tokenize.COMMENT,
+                   NL=tokenize.NL):
+
+        if type == NEWLINE:
+            # A program statement, or ENDMARKER, will eventually follow,
+            # after some (possibly empty) run of tokens of the form
+            #     (NL | COMMENT)* (INDENT | DEDENT+)?
+            self.find_stmt = 1
+
+        elif type == INDENT:
+            self.find_stmt = 1
+            self.level += 1
+
+        elif type == DEDENT:
+            self.find_stmt = 1
+            self.level -= 1
+
+        elif type == COMMENT:
+            if self.find_stmt:
+                self.stats.append((sline, -1))
+                # but we're still looking for a new stmt, so leave
+                # find_stmt alone
+
+        elif type == NL:
+            pass
+
+        elif self.find_stmt:
+            # This is the first "real token" following a NEWLINE, so it
+            # must be the first token of the next program statement, or an
+            # ENDMARKER.
+            self.find_stmt = 0
+            if line:   # not endmarker
+                self.stats.append((sline, self.level))
+
+# Count number of leading blanks.
+def getlspace(line):
+    i, n = 0, len(line)
+    while i < n and line[i] == " ":
+        i += 1
+    return i
+
+if __name__ == '__main__':
+    main()

Added: vendor/Python/current/Tools/scripts/rgrep.py
===================================================================
--- vendor/Python/current/Tools/scripts/rgrep.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/rgrep.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,64 @@
+#! /usr/bin/env python
+
+"""Reverse grep.
+
+Usage: rgrep [-i] pattern file
+"""
+
+import sys
+import re
+import getopt
+
+def main():
+    bufsize = 64*1024
+    reflags = 0
+    opts, args = getopt.getopt(sys.argv[1:], "i")
+    for o, a in opts:
+        if o == '-i':
+            reflags = reflags | re.IGNORECASE
+    if len(args) < 2:
+        usage("not enough arguments")
+    if len(args) > 2:
+        usage("exactly one file argument required")
+    pattern, filename = args
+    try:
+        prog = re.compile(pattern, reflags)
+    except re.error, msg:
+        usage("error in regular expression: %s" % str(msg))
+    try:
+        f = open(filename)
+    except IOError, msg:
+        usage("can't open %s: %s" % (repr(filename), str(msg)), 1)
+    f.seek(0, 2)
+    pos = f.tell()
+    leftover = None
+    while pos > 0:
+        size = min(pos, bufsize)
+        pos = pos - size
+        f.seek(pos)
+        buffer = f.read(size)
+        lines = buffer.split("\n")
+        del buffer
+        if leftover is None:
+            if not lines[-1]:
+                del lines[-1]
+        else:
+            lines[-1] = lines[-1] + leftover
+        if pos > 0:
+            leftover = lines[0]
+            del lines[0]
+        else:
+            leftover = None
+        lines.reverse()
+        for line in lines:
+            if prog.search(line):
+                print line
+
+def usage(msg, code=2):
+    sys.stdout = sys.stderr
+    print msg
+    print __doc__
+    sys.exit(code)
+
+if __name__ == '__main__':
+    main()


Property changes on: vendor/Python/current/Tools/scripts/rgrep.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/scripts/setup.py
===================================================================
--- vendor/Python/current/Tools/scripts/setup.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/setup.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,19 @@
+from distutils.core import setup
+
+if __name__ == '__main__':
+    setup(
+      scripts=[
+        'byteyears.py',
+        'checkpyc.py',
+        'copytime.py',
+        'crlf.py',
+        'dutree.py',
+        'ftpmirror.py',
+        'h2py.py',
+        'lfcr.py',
+        'logmerge.py',
+        '../../Lib/tabnanny.py',
+        '../../Lib/timeit.py',
+        'untabify.py',
+        ],
+      )

Added: vendor/Python/current/Tools/scripts/suff.py
===================================================================
--- vendor/Python/current/Tools/scripts/suff.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/suff.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,30 @@
+#! /usr/bin/env python
+
+# suff
+#
+# show different suffixes amongst arguments
+
+import sys
+
+def main():
+    files = sys.argv[1:]
+    suffixes = {}
+    for filename in files:
+        suff = getsuffix(filename)
+        if not suffixes.has_key(suff):
+            suffixes[suff] = []
+        suffixes[suff].append(filename)
+    keys = suffixes.keys()
+    keys.sort()
+    for suff in keys:
+        print repr(suff), len(suffixes[suff])
+
+def getsuffix(filename):
+    suff = ''
+    for i in range(len(filename)):
+        if filename[i] == '.':
+            suff = filename[i:]
+    return suff
+
+if __name__ == '__main__':
+    main()


Property changes on: vendor/Python/current/Tools/scripts/suff.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/scripts/svneol.py
===================================================================
--- vendor/Python/current/Tools/scripts/svneol.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/svneol.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,77 @@
+#! /usr/bin/env python
+
+"""
+SVN helper script.
+
+Try to set the svn:eol-style property to "native" on every .py, .txt, .c and
+.h file in the directory tree rooted at the current directory.
+
+Files with the svn:eol-style property already set (to anything) are skipped.
+
+svn will itself refuse to set this property on a file that's not under SVN
+control, or that has a binary mime-type property set.  This script inherits
+that behavior, and passes on whatever warning message the failing "svn
+propset" command produces.
+
+In the Python project, it's safe to invoke this script from the root of
+a checkout.
+
+No output is produced for files that are ignored.  For a file that gets
+svn:eol-style set, output looks like:
+
+    property 'svn:eol-style' set on 'Lib\ctypes\__init__.py'
+
+For a file not under version control:
+
+    svn: warning: 'patch-finalizer.txt' is not under version control
+
+and for a file with a binary mime-type property:
+
+    svn: File 'Lib\test\test_pep263.py' has binary mime type property
+"""
+
+import re
+import os
+
+def proplist(root, fn):
+    "Return a list of property names for file fn in directory root"
+    path = os.path.join(root, ".svn", "props", fn+".svn-work")
+    try:
+        f = open(path)
+    except IOError:
+        # no properties file: not under version control
+        return []
+    result = []
+    while 1:
+        # key-value pairs, of the form
+        # K <length>
+        # <keyname>NL
+        # V length
+        # <value>NL
+        # END
+        line = f.readline()
+        if line.startswith("END"):
+            break
+        assert line.startswith("K ")
+        L = int(line.split()[1])
+        key = f.read(L)
+        result.append(key)
+        f.readline()
+        line = f.readline()
+        assert line.startswith("V ")
+        L = int(line.split()[1])
+        value = f.read(L)
+        f.readline()
+    f.close()
+    return result
+
+possible_text_file = re.compile(r"\.([hc]|py|txt|sln|vcproj)$").search
+
+for root, dirs, files in os.walk('.'):
+    if '.svn' in dirs:
+        dirs.remove('.svn')
+    for fn in files:
+        if possible_text_file(fn):
+            if 'svn:eol-style' not in proplist(root, fn):
+                path = os.path.join(root, fn)
+                os.system('svn propset svn:eol-style native "%s"' % path)

Added: vendor/Python/current/Tools/scripts/texcheck.py
===================================================================
--- vendor/Python/current/Tools/scripts/texcheck.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/texcheck.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,233 @@
+""" TeXcheck.py -- rough syntax checking on Python style LaTeX documents.
+
+   Written by Raymond D. Hettinger <python at rcn.com>
+   Copyright (c) 2003 Python Software Foundation.  All rights reserved.
+
+Designed to catch common markup errors including:
+* Unbalanced or mismatched parenthesis, brackets, and braces.
+* Unbalanced or mismatched \\begin and \\end blocks.
+* Misspelled or invalid LaTeX commands.
+* Use of forward slashes instead of backslashes for commands.
+* Table line size mismatches.
+
+Sample command line usage:
+    python texcheck.py -k chapterheading -m lib/librandomtex *.tex
+
+Options:
+    -m          Munge parenthesis and brackets. [0,n) would normally mismatch.
+    -k keyword: Keyword is a valid LaTeX command. Do not include the backslash.
+    -d:         Delimiter check only (useful for non-LaTeX files).
+    -h:         Help
+    -s lineno:  Start at lineno (useful for skipping complex sections).
+    -v:         Verbose.  Trace the matching of //begin and //end blocks.
+"""
+
+import re
+import sys
+import getopt
+from itertools import izip, count, islice
+import glob
+
+cmdstr = r"""
+    \section \module \declaremodule \modulesynopsis \moduleauthor
+    \sectionauthor \versionadded \code \class \method \begin
+    \optional \var \ref \end \subsection \lineiii \hline \label
+    \indexii \textrm \ldots \keyword \stindex \index \item \note
+    \withsubitem \ttindex \footnote \citetitle \samp \opindex
+    \noindent \exception \strong \dfn \ctype \obindex \character
+    \indexiii \function \bifuncindex \refmodule \refbimodindex
+    \subsubsection \nodename \member \chapter \emph \ASCII \UNIX
+    \regexp \program \production \token \productioncont \term
+    \grammartoken \lineii \seemodule \file \EOF \documentclass
+    \usepackage \title \input \maketitle \ifhtml \fi \url \Cpp
+    \tableofcontents \kbd \programopt \envvar \refstmodindex
+    \cfunction \constant \NULL \moreargs \cfuncline \cdata
+    \textasciicircum \n \ABC \setindexsubitem \versionchanged
+    \deprecated \seetext \newcommand \POSIX \pep \warning \rfc
+    \verbatiminput \methodline \textgreater \seetitle \lineiv
+    \funclineni \ulink \manpage \funcline \dataline \unspecified
+    \textbackslash \mimetype \mailheader \seepep \textunderscore
+    \longprogramopt \infinity \plusminus \shortversion \version
+    \refmodindex \seerfc \makeindex \makemodindex \renewcommand
+    \indexname \appendix \protect \indexiv \mbox \textasciitilde
+    \platform \seeurl \leftmargin \labelwidth \localmoduletable
+    \LaTeX \copyright \memberline \backslash \pi \centerline
+    \caption \vspace \textwidth \menuselection \textless
+    \makevar \csimplemacro \menuselection \bfcode \sub \release
+    \email \kwindex \refexmodindex \filenq \e \menuselection
+    \exindex \linev \newsgroup \verbatim \setshortversion
+    \author \authoraddress \paragraph \subparagraph \cmemberline
+    \textbar \C \seelink
+"""
+
+def matchclose(c_lineno, c_symbol, openers, pairmap):
+    "Verify that closing delimiter matches most recent opening delimiter"
+    try:
+        o_lineno, o_symbol = openers.pop()
+    except IndexError:
+        print "\nDelimiter mismatch.  On line %d, encountered closing '%s' without corresponding open" % (c_lineno, c_symbol)
+        return
+    if o_symbol in pairmap.get(c_symbol, [c_symbol]): return
+    print "\nOpener '%s' on line %d was not closed before encountering '%s' on line %d" % (o_symbol, o_lineno, c_symbol, c_lineno)
+    return
+
+def checkit(source, opts, morecmds=[]):
+    """Check the LaTeX formatting in a sequence of lines.
+
+    Opts is a mapping of options to option values if any:
+        -m          munge parenthesis and brackets
+        -d          delimiters only checking
+        -v          verbose trace of delimiter matching
+        -s lineno:  linenumber to start scan (default is 1).
+
+    Morecmds is a sequence of LaTeX commands (without backslashes) that
+    are to be considered valid in the scan.
+    """
+
+    texcmd = re.compile(r'\\[A-Za-z]+')
+    falsetexcmd = re.compile(r'\/([A-Za-z]+)') # Mismarked with forward slash
+
+    validcmds = set(cmdstr.split())
+    for cmd in morecmds:
+        validcmds.add('\\' + cmd)
+
+    if '-m' in opts:
+        pairmap = {']':'[(', ')':'(['}      # Munged openers
+    else:
+        pairmap = {']':'[', ')':'('}        # Normal opener for a given closer
+    openpunct = set('([')                   # Set of valid openers
+
+    delimiters = re.compile(r'\\(begin|end){([_a-zA-Z]+)}|([()\[\]])')
+    braces = re.compile(r'({)|(})')
+    doubledwords = re.compile(r'(\b[A-za-z]+\b) \b\1\b')
+    spacingmarkup = re.compile(r'\\(ABC|ASCII|C|Cpp|EOF|infinity|NULL|plusminus|POSIX|UNIX)\s')
+
+    openers = []                            # Stack of pending open delimiters
+    bracestack = []                         # Stack of pending open braces
+
+    tablestart = re.compile(r'\\begin{(?:long)?table([iv]+)}')
+    tableline = re.compile(r'\\line([iv]+){')
+    tableend = re.compile(r'\\end{(?:long)?table([iv]+)}')
+    tablelevel = ''
+    tablestartline = 0
+
+    startline = int(opts.get('-s', '1'))
+    lineno = 0
+
+    for lineno, line in izip(count(startline), islice(source, startline-1, None)):
+        line = line.rstrip()
+
+        # Check balancing of open/close parenthesis, brackets, and begin/end blocks
+        for begend, name, punct in delimiters.findall(line):
+            if '-v' in opts:
+                print lineno, '|', begend, name, punct,
+            if begend == 'begin' and '-d' not in opts:
+                openers.append((lineno, name))
+            elif punct in openpunct:
+                openers.append((lineno, punct))
+            elif begend == 'end' and '-d' not in opts:
+                matchclose(lineno, name, openers, pairmap)
+            elif punct in pairmap:
+                matchclose(lineno, punct, openers, pairmap)
+            if '-v' in opts:
+                print '   --> ', openers
+
+        # Balance opening and closing braces
+        for open, close in braces.findall(line):
+            if open == '{':
+                bracestack.append(lineno)
+            if close == '}':
+                try:
+                    bracestack.pop()
+                except IndexError:
+                    print r'Warning, unmatched } on line %s.' % (lineno,)
+
+        # Optionally, skip LaTeX specific checks
+        if '-d' in opts:
+            continue
+
+        # Warn whenever forward slashes encountered with a LaTeX command
+        for cmd in falsetexcmd.findall(line):
+            if '822' in line or '.html' in line:
+                continue    # Ignore false positives for urls and for /rfc822
+            if '\\' + cmd in validcmds:
+                print 'Warning, forward slash used on line %d with cmd: /%s' % (lineno, cmd)
+
+        # Check for markup requiring {} for correct spacing
+        for cmd in spacingmarkup.findall(line):
+            print r'Warning, \%s should be written as \%s{} on line %d' % (cmd, cmd, lineno)
+
+        # Validate commands
+        nc = line.find(r'\newcommand')
+        if nc != -1:
+            start = line.find('{', nc)
+            end = line.find('}', start)
+            validcmds.add(line[start+1:end])
+        for cmd in texcmd.findall(line):
+            if cmd not in validcmds:
+                print r'Warning, unknown tex cmd on line %d: \%s' % (lineno, cmd)
+
+        # Check table levels (make sure lineii only inside tableii)
+        m = tablestart.search(line)
+        if m:
+            tablelevel = m.group(1)
+            tablestartline = lineno
+        m = tableline.search(line)
+        if m and m.group(1) != tablelevel:
+            print r'Warning, \line%s on line %d does not match \table%s on line %d' % (m.group(1), lineno, tablelevel, tablestartline)
+        if tableend.search(line):
+            tablelevel = ''
+
+        # Style guide warnings
+        if 'e.g.' in line or 'i.e.' in line:
+            print r'Style warning, avoid use of i.e or e.g. on line %d' % (lineno,)
+
+        for dw in doubledwords.findall(line):
+            print r'Doubled word warning.  "%s" on line %d' % (dw, lineno)
+
+    lastline = lineno
+    for lineno, symbol in openers:
+        print "Unmatched open delimiter '%s' on line %d" % (symbol, lineno)
+    for lineno in bracestack:
+        print "Unmatched { on line %d" % (lineno,)
+    print 'Done checking %d lines.' % (lastline,)
+    return 0
+
+def main(args=None):
+    if args is None:
+        args = sys.argv[1:]
+    optitems, arglist = getopt.getopt(args, "k:mdhs:v")
+    opts = dict(optitems)
+    if '-h' in opts or args==[]:
+        print __doc__
+        return 0
+
+    if len(arglist) < 1:
+        print 'Please specify a file to be checked'
+        return 1
+
+    for i, filespec in enumerate(arglist):
+        if '*' in filespec or '?' in filespec:
+            arglist[i:i+1] = glob.glob(filespec)
+
+    morecmds = [v for k,v in optitems if k=='-k']
+    err = []
+
+    for filename in arglist:
+        print '=' * 30
+        print "Checking", filename
+        try:
+            f = open(filename)
+        except IOError:
+            print 'Cannot open file %s.' % arglist[0]
+            return 2
+
+        try:
+            err.append(checkit(f, opts, morecmds))
+        finally:
+            f.close()
+
+    return max(err)
+
+if __name__ == '__main__':
+    sys.exit(main())

Added: vendor/Python/current/Tools/scripts/texi2html.py
===================================================================
--- vendor/Python/current/Tools/scripts/texi2html.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/texi2html.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,2078 @@
+#! /usr/bin/env python
+
+# Convert GNU texinfo files into HTML, one file per node.
+# Based on Texinfo 2.14.
+# Usage: texi2html [-d] [-d] [-c] inputfile outputdirectory
+# The input file must be a complete texinfo file, e.g. emacs.texi.
+# This creates many files (one per info node) in the output directory,
+# overwriting existing files of the same name.  All files created have
+# ".html" as their extension.
+
+
+# XXX To do:
+# - handle @comment*** correctly
+# - handle @xref {some words} correctly
+# - handle @ftable correctly (items aren't indexed?)
+# - handle @itemx properly
+# - handle @exdent properly
+# - add links directly to the proper line from indices
+# - check against the definitive list of @-cmds; we still miss (among others):
+# - @defindex (hard)
+# - @c(omment) in the middle of a line (rarely used)
+# - @this* (not really needed, only used in headers anyway)
+# - @today{} (ever used outside title page?)
+
+# More consistent handling of chapters/sections/etc.
+# Lots of documentation
+# Many more options:
+#       -top    designate top node
+#       -links  customize which types of links are included
+#       -split  split at chapters or sections instead of nodes
+#       -name   Allow different types of filename handling. Non unix systems
+#               will have problems with long node names
+#       ...
+# Support the most recent texinfo version and take a good look at HTML 3.0
+# More debugging output (customizable) and more flexible error handling
+# How about icons ?
+
+# rpyron 2002-05-07
+# Robert Pyron <rpyron at alum.mit.edu>
+# 1. BUGFIX: In function makefile(), strip blanks from the nodename.
+#    This is necesary to match the behavior of parser.makeref() and
+#    parser.do_node().
+# 2. BUGFIX fixed KeyError in end_ifset (well, I may have just made
+#    it go away, rather than fix it)
+# 3. BUGFIX allow @menu and menu items inside @ifset or @ifclear
+# 4. Support added for:
+#       @uref        URL reference
+#       @image       image file reference (see note below)
+#       @multitable  output an HTML table
+#       @vtable
+# 5. Partial support for accents, to match MAKEINFO output
+# 6. I added a new command-line option, '-H basename', to specify
+#    HTML Help output. This will cause three files to be created
+#    in the current directory:
+#       `basename`.hhp  HTML Help Workshop project file
+#       `basename`.hhc  Contents file for the project
+#       `basename`.hhk  Index file for the project
+#    When fed into HTML Help Workshop, the resulting file will be
+#    named `basename`.chm.
+# 7. A new class, HTMLHelp, to accomplish item 6.
+# 8. Various calls to HTMLHelp functions.
+# A NOTE ON IMAGES: Just as 'outputdirectory' must exist before
+# running this program, all referenced images must already exist
+# in outputdirectory.
+
+import os
+import sys
+import string
+import re
+
+MAGIC = '\\input texinfo'
+
+cmprog = re.compile('^@([a-z]+)([ \t]|$)')        # Command (line-oriented)
+blprog = re.compile('^[ \t]*$')                   # Blank line
+kwprog = re.compile('@[a-z]+')                    # Keyword (embedded, usually
+                                                  # with {} args)
+spprog = re.compile('[\n@{}&<>]')                 # Special characters in
+                                                  # running text
+                                                  #
+                                                  # menu item (Yuck!)
+miprog = re.compile('^\* ([^:]*):(:|[ \t]*([^\t,\n.]+)([^ \t\n]*))[ \t\n]*')
+#                   0    1     1 2        3          34         42        0
+#                         -----            ----------  ---------
+#                                 -|-----------------------------
+#                    -----------------------------------------------------
+
+
+
+
+class HTMLNode:
+    """Some of the parser's functionality is separated into this class.
+
+    A Node accumulates its contents, takes care of links to other Nodes
+    and saves itself when it is finished and all links are resolved.
+    """
+
+    DOCTYPE = '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">'
+
+    type = 0
+    cont = ''
+    epilogue = '</BODY></HTML>\n'
+
+    def __init__(self, dir, name, topname, title, next, prev, up):
+        self.dirname = dir
+        self.name = name
+        if topname:
+            self.topname = topname
+        else:
+            self.topname = name
+        self.title = title
+        self.next = next
+        self.prev = prev
+        self.up = up
+        self.lines = []
+
+    def write(self, *lines):
+        map(self.lines.append, lines)
+
+    def flush(self):
+        fp = open(self.dirname + '/' + makefile(self.name), 'w')
+        fp.write(self.prologue)
+        fp.write(self.text)
+        fp.write(self.epilogue)
+        fp.close()
+
+    def link(self, label, nodename, rel=None, rev=None):
+        if nodename:
+            if nodename.lower() == '(dir)':
+                addr = '../dir.html'
+                title = ''
+            else:
+                addr = makefile(nodename)
+                title = ' TITLE="%s"' % nodename
+            self.write(label, ': <A HREF="', addr, '"', \
+                       rel and (' REL=' + rel) or "", \
+                       rev and (' REV=' + rev) or "", \
+                       title, '>', nodename, '</A>  \n')
+
+    def finalize(self):
+        length = len(self.lines)
+        self.text = ''.join(self.lines)
+        self.lines = []
+        self.open_links()
+        self.output_links()
+        self.close_links()
+        links = ''.join(self.lines)
+        self.lines = []
+        self.prologue = (
+            self.DOCTYPE +
+            '\n<HTML><HEAD>\n'
+            '  <!-- Converted with texi2html and Python -->\n'
+            '  <TITLE>' + self.title + '</TITLE>\n'
+            '  <LINK REL=Next HREF="'
+                + makefile(self.next) + '" TITLE="' + self.next + '">\n'
+            '  <LINK REL=Previous HREF="'
+                + makefile(self.prev) + '" TITLE="' + self.prev  + '">\n'
+            '  <LINK REL=Up HREF="'
+                + makefile(self.up) + '" TITLE="' + self.up  + '">\n'
+            '</HEAD><BODY>\n' +
+            links)
+        if length > 20:
+            self.epilogue = '<P>\n%s</BODY></HTML>\n' % links
+
+    def open_links(self):
+        self.write('<HR>\n')
+
+    def close_links(self):
+        self.write('<HR>\n')
+
+    def output_links(self):
+        if self.cont != self.next:
+            self.link('  Cont', self.cont)
+        self.link('  Next', self.next, rel='Next')
+        self.link('  Prev', self.prev, rel='Previous')
+        self.link('  Up', self.up, rel='Up')
+        if self.name <> self.topname:
+            self.link('  Top', self.topname)
+
+
+class HTML3Node(HTMLNode):
+
+    DOCTYPE = '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML Level 3//EN//3.0">'
+
+    def open_links(self):
+        self.write('<DIV CLASS=Navigation>\n <HR>\n')
+
+    def close_links(self):
+        self.write(' <HR>\n</DIV>\n')
+
+
+class TexinfoParser:
+
+    COPYRIGHT_SYMBOL = "&copy;"
+    FN_ID_PATTERN = "(%(id)s)"
+    FN_SOURCE_PATTERN = '<A NAME=footnoteref%(id)s' \
+                        ' HREF="#footnotetext%(id)s">' \
+                        + FN_ID_PATTERN + '</A>'
+    FN_TARGET_PATTERN = '<A NAME=footnotetext%(id)s' \
+                        ' HREF="#footnoteref%(id)s">' \
+                        + FN_ID_PATTERN + '</A>\n%(text)s<P>\n'
+    FN_HEADER = '\n<P>\n<HR NOSHADE SIZE=1 WIDTH=200>\n' \
+                '<STRONG><EM>Footnotes</EM></STRONG>\n<P>'
+
+
+    Node = HTMLNode
+
+    # Initialize an instance
+    def __init__(self):
+        self.unknown = {}       # statistics about unknown @-commands
+        self.filenames = {}     # Check for identical filenames
+        self.debugging = 0      # larger values produce more output
+        self.print_headers = 0  # always print headers?
+        self.nodefp = None      # open file we're writing to
+        self.nodelineno = 0     # Linenumber relative to node
+        self.links = None       # Links from current node
+        self.savetext = None    # If not None, save text head instead
+        self.savestack = []     # If not None, save text head instead
+        self.htmlhelp = None    # html help data
+        self.dirname = 'tmp'    # directory where files are created
+        self.includedir = '.'   # directory to search @include files
+        self.nodename = ''      # name of current node
+        self.topname = ''       # name of top node (first node seen)
+        self.title = ''         # title of this whole Texinfo tree
+        self.resetindex()       # Reset all indices
+        self.contents = []      # Reset table of contents
+        self.numbering = []     # Reset section numbering counters
+        self.nofill = 0         # Normal operation: fill paragraphs
+        self.values={'html': 1} # Names that should be parsed in ifset
+        self.stackinfo={}       # Keep track of state in the stack
+        # XXX The following should be reset per node?!
+        self.footnotes = []     # Reset list of footnotes
+        self.itemarg = None     # Reset command used by @item
+        self.itemnumber = None  # Reset number for @item in @enumerate
+        self.itemindex = None   # Reset item index name
+        self.node = None
+        self.nodestack = []
+        self.cont = 0
+        self.includedepth = 0
+
+    # Set htmlhelp helper class
+    def sethtmlhelp(self, htmlhelp):
+        self.htmlhelp = htmlhelp
+
+    # Set (output) directory name
+    def setdirname(self, dirname):
+        self.dirname = dirname
+
+    # Set include directory name
+    def setincludedir(self, includedir):
+        self.includedir = includedir
+
+    # Parse the contents of an entire file
+    def parse(self, fp):
+        line = fp.readline()
+        lineno = 1
+        while line and (line[0] == '%' or blprog.match(line)):
+            line = fp.readline()
+            lineno = lineno + 1
+        if line[:len(MAGIC)] <> MAGIC:
+            raise SyntaxError, 'file does not begin with %r' % (MAGIC,)
+        self.parserest(fp, lineno)
+
+    # Parse the contents of a file, not expecting a MAGIC header
+    def parserest(self, fp, initial_lineno):
+        lineno = initial_lineno
+        self.done = 0
+        self.skip = 0
+        self.stack = []
+        accu = []
+        while not self.done:
+            line = fp.readline()
+            self.nodelineno = self.nodelineno + 1
+            if not line:
+                if accu:
+                    if not self.skip: self.process(accu)
+                    accu = []
+                if initial_lineno > 0:
+                    print '*** EOF before @bye'
+                break
+            lineno = lineno + 1
+            mo = cmprog.match(line)
+            if mo:
+                a, b = mo.span(1)
+                cmd = line[a:b]
+                if cmd in ('noindent', 'refill'):
+                    accu.append(line)
+                else:
+                    if accu:
+                        if not self.skip:
+                            self.process(accu)
+                        accu = []
+                    self.command(line, mo)
+            elif blprog.match(line) and \
+                 'format' not in self.stack and \
+                 'example' not in self.stack:
+                if accu:
+                    if not self.skip:
+                        self.process(accu)
+                        if self.nofill:
+                            self.write('\n')
+                        else:
+                            self.write('<P>\n')
+                        accu = []
+            else:
+                # Append the line including trailing \n!
+                accu.append(line)
+        #
+        if self.skip:
+            print '*** Still skipping at the end'
+        if self.stack:
+            print '*** Stack not empty at the end'
+            print '***', self.stack
+        if self.includedepth == 0:
+            while self.nodestack:
+                self.nodestack[-1].finalize()
+                self.nodestack[-1].flush()
+                del self.nodestack[-1]
+
+    # Start saving text in a buffer instead of writing it to a file
+    def startsaving(self):
+        if self.savetext <> None:
+            self.savestack.append(self.savetext)
+            # print '*** Recursively saving text, expect trouble'
+        self.savetext = ''
+
+    # Return the text saved so far and start writing to file again
+    def collectsavings(self):
+        savetext = self.savetext
+        if len(self.savestack) > 0:
+            self.savetext = self.savestack[-1]
+            del self.savestack[-1]
+        else:
+            self.savetext = None
+        return savetext or ''
+
+    # Write text to file, or save it in a buffer, or ignore it
+    def write(self, *args):
+        try:
+            text = ''.join(args)
+        except:
+            print args
+            raise TypeError
+        if self.savetext <> None:
+            self.savetext = self.savetext + text
+        elif self.nodefp:
+            self.nodefp.write(text)
+        elif self.node:
+            self.node.write(text)
+
+    # Complete the current node -- write footnotes and close file
+    def endnode(self):
+        if self.savetext <> None:
+            print '*** Still saving text at end of node'
+            dummy = self.collectsavings()
+        if self.footnotes:
+            self.writefootnotes()
+        if self.nodefp:
+            if self.nodelineno > 20:
+                self.write('<HR>\n')
+                [name, next, prev, up] = self.nodelinks[:4]
+                self.link('Next', next)
+                self.link('Prev', prev)
+                self.link('Up', up)
+                if self.nodename <> self.topname:
+                    self.link('Top', self.topname)
+                self.write('<HR>\n')
+            self.write('</BODY>\n')
+            self.nodefp.close()
+            self.nodefp = None
+        elif self.node:
+            if not self.cont and \
+               (not self.node.type or \
+                (self.node.next and self.node.prev and self.node.up)):
+                self.node.finalize()
+                self.node.flush()
+            else:
+                self.nodestack.append(self.node)
+            self.node = None
+        self.nodename = ''
+
+    # Process a list of lines, expanding embedded @-commands
+    # This mostly distinguishes between menus and normal text
+    def process(self, accu):
+        if self.debugging > 1:
+            print '!'*self.debugging, 'process:', self.skip, self.stack,
+            if accu: print accu[0][:30],
+            if accu[0][30:] or accu[1:]: print '...',
+            print
+        if self.inmenu():
+            # XXX should be done differently
+            for line in accu:
+                mo = miprog.match(line)
+                if not mo:
+                    line = line.strip() + '\n'
+                    self.expand(line)
+                    continue
+                bgn, end = mo.span(0)
+                a, b = mo.span(1)
+                c, d = mo.span(2)
+                e, f = mo.span(3)
+                g, h = mo.span(4)
+                label = line[a:b]
+                nodename = line[c:d]
+                if nodename[0] == ':': nodename = label
+                else: nodename = line[e:f]
+                punct = line[g:h]
+                self.write('  <LI><A HREF="',
+                           makefile(nodename),
+                           '">', nodename,
+                           '</A>', punct, '\n')
+                self.htmlhelp.menuitem(nodename)
+                self.expand(line[end:])
+        else:
+            text = ''.join(accu)
+            self.expand(text)
+
+    # find 'menu' (we might be inside 'ifset' or 'ifclear')
+    def inmenu(self):
+        #if 'menu' in self.stack:
+        #    print 'inmenu   :', self.skip, self.stack, self.stackinfo
+        stack = self.stack
+        while stack and stack[-1] in ('ifset','ifclear'):
+            try:
+                if self.stackinfo[len(stack)]:
+                    return 0
+            except KeyError:
+                pass
+            stack = stack[:-1]
+        return (stack and stack[-1] == 'menu')
+
+    # Write a string, expanding embedded @-commands
+    def expand(self, text):
+        stack = []
+        i = 0
+        n = len(text)
+        while i < n:
+            start = i
+            mo = spprog.search(text, i)
+            if mo:
+                i = mo.start()
+            else:
+                self.write(text[start:])
+                break
+            self.write(text[start:i])
+            c = text[i]
+            i = i+1
+            if c == '\n':
+                self.write('\n')
+                continue
+            if c == '<':
+                self.write('&lt;')
+                continue
+            if c == '>':
+                self.write('&gt;')
+                continue
+            if c == '&':
+                self.write('&amp;')
+                continue
+            if c == '{':
+                stack.append('')
+                continue
+            if c == '}':
+                if not stack:
+                    print '*** Unmatched }'
+                    self.write('}')
+                    continue
+                cmd = stack[-1]
+                del stack[-1]
+                try:
+                    method = getattr(self, 'close_' + cmd)
+                except AttributeError:
+                    self.unknown_close(cmd)
+                    continue
+                method()
+                continue
+            if c <> '@':
+                # Cannot happen unless spprog is changed
+                raise RuntimeError, 'unexpected funny %r' % c
+            start = i
+            while i < n and text[i] in string.ascii_letters: i = i+1
+            if i == start:
+                # @ plus non-letter: literal next character
+                i = i+1
+                c = text[start:i]
+                if c == ':':
+                    # `@:' means no extra space after
+                    # preceding `.', `?', `!' or `:'
+                    pass
+                else:
+                    # `@.' means a sentence-ending period;
+                    # `@@', `@{', `@}' quote `@', `{', `}'
+                    self.write(c)
+                continue
+            cmd = text[start:i]
+            if i < n and text[i] == '{':
+                i = i+1
+                stack.append(cmd)
+                try:
+                    method = getattr(self, 'open_' + cmd)
+                except AttributeError:
+                    self.unknown_open(cmd)
+                    continue
+                method()
+                continue
+            try:
+                method = getattr(self, 'handle_' + cmd)
+            except AttributeError:
+                self.unknown_handle(cmd)
+                continue
+            method()
+        if stack:
+            print '*** Stack not empty at para:', stack
+
+    # --- Handle unknown embedded @-commands ---
+
+    def unknown_open(self, cmd):
+        print '*** No open func for @' + cmd + '{...}'
+        cmd = cmd + '{'
+        self.write('@', cmd)
+        if not self.unknown.has_key(cmd):
+            self.unknown[cmd] = 1
+        else:
+            self.unknown[cmd] = self.unknown[cmd] + 1
+
+    def unknown_close(self, cmd):
+        print '*** No close func for @' + cmd + '{...}'
+        cmd = '}' + cmd
+        self.write('}')
+        if not self.unknown.has_key(cmd):
+            self.unknown[cmd] = 1
+        else:
+            self.unknown[cmd] = self.unknown[cmd] + 1
+
+    def unknown_handle(self, cmd):
+        print '*** No handler for @' + cmd
+        self.write('@', cmd)
+        if not self.unknown.has_key(cmd):
+            self.unknown[cmd] = 1
+        else:
+            self.unknown[cmd] = self.unknown[cmd] + 1
+
+    # XXX The following sections should be ordered as the texinfo docs
+
+    # --- Embedded @-commands without {} argument list --
+
+    def handle_noindent(self): pass
+
+    def handle_refill(self): pass
+
+    # --- Include file handling ---
+
+    def do_include(self, args):
+        file = args
+        file = os.path.join(self.includedir, file)
+        try:
+            fp = open(file, 'r')
+        except IOError, msg:
+            print '*** Can\'t open include file', repr(file)
+            return
+        print '!'*self.debugging, '--> file', repr(file)
+        save_done = self.done
+        save_skip = self.skip
+        save_stack = self.stack
+        self.includedepth = self.includedepth + 1
+        self.parserest(fp, 0)
+        self.includedepth = self.includedepth - 1
+        fp.close()
+        self.done = save_done
+        self.skip = save_skip
+        self.stack = save_stack
+        print '!'*self.debugging, '<-- file', repr(file)
+
+    # --- Special Insertions ---
+
+    def open_dmn(self): pass
+    def close_dmn(self): pass
+
+    def open_dots(self): self.write('...')
+    def close_dots(self): pass
+
+    def open_bullet(self): pass
+    def close_bullet(self): pass
+
+    def open_TeX(self): self.write('TeX')
+    def close_TeX(self): pass
+
+    def handle_copyright(self): self.write(self.COPYRIGHT_SYMBOL)
+    def open_copyright(self): self.write(self.COPYRIGHT_SYMBOL)
+    def close_copyright(self): pass
+
+    def open_minus(self): self.write('-')
+    def close_minus(self): pass
+
+    # --- Accents ---
+
+    # rpyron 2002-05-07
+    # I would like to do at least as well as makeinfo when
+    # it is producing HTML output:
+    #
+    #   input               output
+    #     @"o                 @"o                umlaut accent
+    #     @'o                 'o                 acute accent
+    #     @,{c}               @,{c}              cedilla accent
+    #     @=o                 @=o                macron/overbar accent
+    #     @^o                 @^o                circumflex accent
+    #     @`o                 `o                 grave accent
+    #     @~o                 @~o                tilde accent
+    #     @dotaccent{o}       @dotaccent{o}      overdot accent
+    #     @H{o}               @H{o}              long Hungarian umlaut
+    #     @ringaccent{o}      @ringaccent{o}     ring accent
+    #     @tieaccent{oo}      @tieaccent{oo}     tie-after accent
+    #     @u{o}               @u{o}              breve accent
+    #     @ubaraccent{o}      @ubaraccent{o}     underbar accent
+    #     @udotaccent{o}      @udotaccent{o}     underdot accent
+    #     @v{o}               @v{o}              hacek or check accent
+    #     @exclamdown{}       &#161;             upside-down !
+    #     @questiondown{}     &#191;             upside-down ?
+    #     @aa{}, at AA{}         &#229;,&#197;      a,A with circle
+    #     @ae{}, at AE{}         &#230;,&#198;      ae,AE ligatures
+    #     @dotless{i}         @dotless{i}        dotless i
+    #     @dotless{j}         @dotless{j}        dotless j
+    #     @l{}, at L{}           l/,L/              suppressed-L,l
+    #     @o{}, at O{}           &#248;,&#216;      O,o with slash
+    #     @oe{}, at OE{}         oe,OE              oe,OE ligatures
+    #     @ss{}               &#223;             es-zet or sharp S
+    #
+    # The following character codes and approximations have been
+    # copied from makeinfo's HTML output.
+
+    def open_exclamdown(self): self.write('&#161;')   # upside-down !
+    def close_exclamdown(self): pass
+    def open_questiondown(self): self.write('&#191;') # upside-down ?
+    def close_questiondown(self): pass
+    def open_aa(self): self.write('&#229;') # a with circle
+    def close_aa(self): pass
+    def open_AA(self): self.write('&#197;') # A with circle
+    def close_AA(self): pass
+    def open_ae(self): self.write('&#230;') # ae ligatures
+    def close_ae(self): pass
+    def open_AE(self): self.write('&#198;') # AE ligatures
+    def close_AE(self): pass
+    def open_o(self): self.write('&#248;')  # o with slash
+    def close_o(self): pass
+    def open_O(self): self.write('&#216;')  # O with slash
+    def close_O(self): pass
+    def open_ss(self): self.write('&#223;') # es-zet or sharp S
+    def close_ss(self): pass
+    def open_oe(self): self.write('oe')     # oe ligatures
+    def close_oe(self): pass
+    def open_OE(self): self.write('OE')     # OE ligatures
+    def close_OE(self): pass
+    def open_l(self): self.write('l/')      # suppressed-l
+    def close_l(self): pass
+    def open_L(self): self.write('L/')      # suppressed-L
+    def close_L(self): pass
+
+    # --- Special Glyphs for Examples ---
+
+    def open_result(self): self.write('=&gt;')
+    def close_result(self): pass
+
+    def open_expansion(self): self.write('==&gt;')
+    def close_expansion(self): pass
+
+    def open_print(self): self.write('-|')
+    def close_print(self): pass
+
+    def open_error(self): self.write('error--&gt;')
+    def close_error(self): pass
+
+    def open_equiv(self): self.write('==')
+    def close_equiv(self): pass
+
+    def open_point(self): self.write('-!-')
+    def close_point(self): pass
+
+    # --- Cross References ---
+
+    def open_pxref(self):
+        self.write('see ')
+        self.startsaving()
+    def close_pxref(self):
+        self.makeref()
+
+    def open_xref(self):
+        self.write('See ')
+        self.startsaving()
+    def close_xref(self):
+        self.makeref()
+
+    def open_ref(self):
+        self.startsaving()
+    def close_ref(self):
+        self.makeref()
+
+    def open_inforef(self):
+        self.write('See info file ')
+        self.startsaving()
+    def close_inforef(self):
+        text = self.collectsavings()
+        args = [s.strip() for s in text.split(',')]
+        while len(args) < 3: args.append('')
+        node = args[0]
+        file = args[2]
+        self.write('`', file, '\', node `', node, '\'')
+
+    def makeref(self):
+        text = self.collectsavings()
+        args = [s.strip() for s in text.split(',')]
+        while len(args) < 5: args.append('')
+        nodename = label = args[0]
+        if args[2]: label = args[2]
+        file = args[3]
+        title = args[4]
+        href = makefile(nodename)
+        if file:
+            href = '../' + file + '/' + href
+        self.write('<A HREF="', href, '">', label, '</A>')
+
+    # rpyron 2002-05-07  uref support
+    def open_uref(self):
+        self.startsaving()
+    def close_uref(self):
+        text = self.collectsavings()
+        args = [s.strip() for s in text.split(',')]
+        while len(args) < 2: args.append('')
+        href = args[0]
+        label = args[1]
+        if not label: label = href
+        self.write('<A HREF="', href, '">', label, '</A>')
+
+    # rpyron 2002-05-07  image support
+    # GNU makeinfo producing HTML output tries `filename.png'; if
+    # that does not exist, it tries `filename.jpg'. If that does
+    # not exist either, it complains. GNU makeinfo does not handle
+    # GIF files; however, I include GIF support here because
+    # MySQL documentation uses GIF files.
+
+    def open_image(self):
+        self.startsaving()
+    def close_image(self):
+        self.makeimage()
+    def makeimage(self):
+        text = self.collectsavings()
+        args = [s.strip() for s in text.split(',')]
+        while len(args) < 5: args.append('')
+        filename = args[0]
+        width    = args[1]
+        height   = args[2]
+        alt      = args[3]
+        ext      = args[4]
+
+        # The HTML output will have a reference to the image
+        # that is relative to the HTML output directory,
+        # which is what 'filename' gives us. However, we need
+        # to find it relative to our own current directory,
+        # so we construct 'imagename'.
+        imagelocation = self.dirname + '/' + filename
+
+        if   os.path.exists(imagelocation+'.png'):
+            filename += '.png'
+        elif os.path.exists(imagelocation+'.jpg'):
+            filename += '.jpg'
+        elif os.path.exists(imagelocation+'.gif'):   # MySQL uses GIF files
+            filename += '.gif'
+        else:
+            print "*** Cannot find image " + imagelocation
+        #TODO: what is 'ext'?
+        self.write('<IMG SRC="', filename, '"',                     \
+                    width  and (' WIDTH="'  + width  + '"') or "",  \
+                    height and (' HEIGHT="' + height + '"') or "",  \
+                    alt    and (' ALT="'    + alt    + '"') or "",  \
+                    '/>' )
+        self.htmlhelp.addimage(imagelocation)
+
+
+    # --- Marking Words and Phrases ---
+
+    # --- Other @xxx{...} commands ---
+
+    def open_(self): pass # Used by {text enclosed in braces}
+    def close_(self): pass
+
+    open_asis = open_
+    close_asis = close_
+
+    def open_cite(self): self.write('<CITE>')
+    def close_cite(self): self.write('</CITE>')
+
+    def open_code(self): self.write('<CODE>')
+    def close_code(self): self.write('</CODE>')
+
+    def open_t(self): self.write('<TT>')
+    def close_t(self): self.write('</TT>')
+
+    def open_dfn(self): self.write('<DFN>')
+    def close_dfn(self): self.write('</DFN>')
+
+    def open_emph(self): self.write('<EM>')
+    def close_emph(self): self.write('</EM>')
+
+    def open_i(self): self.write('<I>')
+    def close_i(self): self.write('</I>')
+
+    def open_footnote(self):
+        # if self.savetext <> None:
+        #       print '*** Recursive footnote -- expect weirdness'
+        id = len(self.footnotes) + 1
+        self.write(self.FN_SOURCE_PATTERN % {'id': repr(id)})
+        self.startsaving()
+
+    def close_footnote(self):
+        id = len(self.footnotes) + 1
+        self.footnotes.append((id, self.collectsavings()))
+
+    def writefootnotes(self):
+        self.write(self.FN_HEADER)
+        for id, text in self.footnotes:
+            self.write(self.FN_TARGET_PATTERN
+                       % {'id': repr(id), 'text': text})
+        self.footnotes = []
+
+    def open_file(self): self.write('<CODE>')
+    def close_file(self): self.write('</CODE>')
+
+    def open_kbd(self): self.write('<KBD>')
+    def close_kbd(self): self.write('</KBD>')
+
+    def open_key(self): self.write('<KEY>')
+    def close_key(self): self.write('</KEY>')
+
+    def open_r(self): self.write('<R>')
+    def close_r(self): self.write('</R>')
+
+    def open_samp(self): self.write('`<SAMP>')
+    def close_samp(self): self.write('</SAMP>\'')
+
+    def open_sc(self): self.write('<SMALLCAPS>')
+    def close_sc(self): self.write('</SMALLCAPS>')
+
+    def open_strong(self): self.write('<STRONG>')
+    def close_strong(self): self.write('</STRONG>')
+
+    def open_b(self): self.write('<B>')
+    def close_b(self): self.write('</B>')
+
+    def open_var(self): self.write('<VAR>')
+    def close_var(self): self.write('</VAR>')
+
+    def open_w(self): self.write('<NOBREAK>')
+    def close_w(self): self.write('</NOBREAK>')
+
+    def open_url(self): self.startsaving()
+    def close_url(self):
+        text = self.collectsavings()
+        self.write('<A HREF="', text, '">', text, '</A>')
+
+    def open_email(self): self.startsaving()
+    def close_email(self):
+        text = self.collectsavings()
+        self.write('<A HREF="mailto:', text, '">', text, '</A>')
+
+    open_titlefont = open_
+    close_titlefont = close_
+
+    def open_small(self): pass
+    def close_small(self): pass
+
+    def command(self, line, mo):
+        a, b = mo.span(1)
+        cmd = line[a:b]
+        args = line[b:].strip()
+        if self.debugging > 1:
+            print '!'*self.debugging, 'command:', self.skip, self.stack, \
+                  '@' + cmd, args
+        try:
+            func = getattr(self, 'do_' + cmd)
+        except AttributeError:
+            try:
+                func = getattr(self, 'bgn_' + cmd)
+            except AttributeError:
+                # don't complain if we are skipping anyway
+                if not self.skip:
+                    self.unknown_cmd(cmd, args)
+                return
+            self.stack.append(cmd)
+            func(args)
+            return
+        if not self.skip or cmd == 'end':
+            func(args)
+
+    def unknown_cmd(self, cmd, args):
+        print '*** unknown', '@' + cmd, args
+        if not self.unknown.has_key(cmd):
+            self.unknown[cmd] = 1
+        else:
+            self.unknown[cmd] = self.unknown[cmd] + 1
+
+    def do_end(self, args):
+        words = args.split()
+        if not words:
+            print '*** @end w/o args'
+        else:
+            cmd = words[0]
+            if not self.stack or self.stack[-1] <> cmd:
+                print '*** @end', cmd, 'unexpected'
+            else:
+                del self.stack[-1]
+            try:
+                func = getattr(self, 'end_' + cmd)
+            except AttributeError:
+                self.unknown_end(cmd)
+                return
+            func()
+
+    def unknown_end(self, cmd):
+        cmd = 'end ' + cmd
+        print '*** unknown', '@' + cmd
+        if not self.unknown.has_key(cmd):
+            self.unknown[cmd] = 1
+        else:
+            self.unknown[cmd] = self.unknown[cmd] + 1
+
+    # --- Comments ---
+
+    def do_comment(self, args): pass
+    do_c = do_comment
+
+    # --- Conditional processing ---
+
+    def bgn_ifinfo(self, args): pass
+    def end_ifinfo(self): pass
+
+    def bgn_iftex(self, args): self.skip = self.skip + 1
+    def end_iftex(self): self.skip = self.skip - 1
+
+    def bgn_ignore(self, args): self.skip = self.skip + 1
+    def end_ignore(self): self.skip = self.skip - 1
+
+    def bgn_tex(self, args): self.skip = self.skip + 1
+    def end_tex(self): self.skip = self.skip - 1
+
+    def do_set(self, args):
+        fields = args.split(' ')
+        key = fields[0]
+        if len(fields) == 1:
+            value = 1
+        else:
+            value = ' '.join(fields[1:])
+        self.values[key] = value
+
+    def do_clear(self, args):
+        self.values[args] = None
+
+    def bgn_ifset(self, args):
+        if args not in self.values.keys() \
+           or self.values[args] is None:
+            self.skip = self.skip + 1
+            self.stackinfo[len(self.stack)] = 1
+        else:
+            self.stackinfo[len(self.stack)] = 0
+    def end_ifset(self):
+        try:
+            if self.stackinfo[len(self.stack) + 1]:
+                self.skip = self.skip - 1
+            del self.stackinfo[len(self.stack) + 1]
+        except KeyError:
+            print '*** end_ifset: KeyError :', len(self.stack) + 1
+
+    def bgn_ifclear(self, args):
+        if args in self.values.keys() \
+           and self.values[args] is not None:
+            self.skip = self.skip + 1
+            self.stackinfo[len(self.stack)] = 1
+        else:
+            self.stackinfo[len(self.stack)] = 0
+    def end_ifclear(self):
+        try:
+            if self.stackinfo[len(self.stack) + 1]:
+                self.skip = self.skip - 1
+            del self.stackinfo[len(self.stack) + 1]
+        except KeyError:
+            print '*** end_ifclear: KeyError :', len(self.stack) + 1
+
+    def open_value(self):
+        self.startsaving()
+
+    def close_value(self):
+        key = self.collectsavings()
+        if key in self.values.keys():
+            self.write(self.values[key])
+        else:
+            print '*** Undefined value: ', key
+
+    # --- Beginning a file ---
+
+    do_finalout = do_comment
+    do_setchapternewpage = do_comment
+    do_setfilename = do_comment
+
+    def do_settitle(self, args):
+        self.startsaving()
+        self.expand(args)
+        self.title = self.collectsavings()
+    def do_parskip(self, args): pass
+
+    # --- Ending a file ---
+
+    def do_bye(self, args):
+        self.endnode()
+        self.done = 1
+
+    # --- Title page ---
+
+    def bgn_titlepage(self, args): self.skip = self.skip + 1
+    def end_titlepage(self): self.skip = self.skip - 1
+    def do_shorttitlepage(self, args): pass
+
+    def do_center(self, args):
+        # Actually not used outside title page...
+        self.write('<H1>')
+        self.expand(args)
+        self.write('</H1>\n')
+    do_title = do_center
+    do_subtitle = do_center
+    do_author = do_center
+
+    do_vskip = do_comment
+    do_vfill = do_comment
+    do_smallbook = do_comment
+
+    do_paragraphindent = do_comment
+    do_setchapternewpage = do_comment
+    do_headings = do_comment
+    do_footnotestyle = do_comment
+
+    do_evenheading = do_comment
+    do_evenfooting = do_comment
+    do_oddheading = do_comment
+    do_oddfooting = do_comment
+    do_everyheading = do_comment
+    do_everyfooting = do_comment
+
+    # --- Nodes ---
+
+    def do_node(self, args):
+        self.endnode()
+        self.nodelineno = 0
+        parts = [s.strip() for s in args.split(',')]
+        while len(parts) < 4: parts.append('')
+        self.nodelinks = parts
+        [name, next, prev, up] = parts[:4]
+        file = self.dirname + '/' + makefile(name)
+        if self.filenames.has_key(file):
+            print '*** Filename already in use: ', file
+        else:
+            if self.debugging: print '!'*self.debugging, '--- writing', file
+        self.filenames[file] = 1
+        # self.nodefp = open(file, 'w')
+        self.nodename = name
+        if self.cont and self.nodestack:
+            self.nodestack[-1].cont = self.nodename
+        if not self.topname: self.topname = name
+        title = name
+        if self.title: title = title + ' -- ' + self.title
+        self.node = self.Node(self.dirname, self.nodename, self.topname,
+                              title, next, prev, up)
+        self.htmlhelp.addnode(self.nodename,next,prev,up,file)
+
+    def link(self, label, nodename):
+        if nodename:
+            if nodename.lower() == '(dir)':
+                addr = '../dir.html'
+            else:
+                addr = makefile(nodename)
+            self.write(label, ': <A HREF="', addr, '" TYPE="',
+                       label, '">', nodename, '</A>  \n')
+
+    # --- Sectioning commands ---
+
+    def popstack(self, type):
+        if (self.node):
+            self.node.type = type
+            while self.nodestack:
+                if self.nodestack[-1].type > type:
+                    self.nodestack[-1].finalize()
+                    self.nodestack[-1].flush()
+                    del self.nodestack[-1]
+                elif self.nodestack[-1].type == type:
+                    if not self.nodestack[-1].next:
+                        self.nodestack[-1].next = self.node.name
+                    if not self.node.prev:
+                        self.node.prev = self.nodestack[-1].name
+                    self.nodestack[-1].finalize()
+                    self.nodestack[-1].flush()
+                    del self.nodestack[-1]
+                else:
+                    if type > 1 and not self.node.up:
+                        self.node.up = self.nodestack[-1].name
+                    break
+
+    def do_chapter(self, args):
+        self.heading('H1', args, 0)
+        self.popstack(1)
+
+    def do_unnumbered(self, args):
+        self.heading('H1', args, -1)
+        self.popstack(1)
+    def do_appendix(self, args):
+        self.heading('H1', args, -1)
+        self.popstack(1)
+    def do_top(self, args):
+        self.heading('H1', args, -1)
+    def do_chapheading(self, args):
+        self.heading('H1', args, -1)
+    def do_majorheading(self, args):
+        self.heading('H1', args, -1)
+
+    def do_section(self, args):
+        self.heading('H1', args, 1)
+        self.popstack(2)
+
+    def do_unnumberedsec(self, args):
+        self.heading('H1', args, -1)
+        self.popstack(2)
+    def do_appendixsec(self, args):
+        self.heading('H1', args, -1)
+        self.popstack(2)
+    do_appendixsection = do_appendixsec
+    def do_heading(self, args):
+        self.heading('H1', args, -1)
+
+    def do_subsection(self, args):
+        self.heading('H2', args, 2)
+        self.popstack(3)
+    def do_unnumberedsubsec(self, args):
+        self.heading('H2', args, -1)
+        self.popstack(3)
+    def do_appendixsubsec(self, args):
+        self.heading('H2', args, -1)
+        self.popstack(3)
+    def do_subheading(self, args):
+        self.heading('H2', args, -1)
+
+    def do_subsubsection(self, args):
+        self.heading('H3', args, 3)
+        self.popstack(4)
+    def do_unnumberedsubsubsec(self, args):
+        self.heading('H3', args, -1)
+        self.popstack(4)
+    def do_appendixsubsubsec(self, args):
+        self.heading('H3', args, -1)
+        self.popstack(4)
+    def do_subsubheading(self, args):
+        self.heading('H3', args, -1)
+
+    def heading(self, type, args, level):
+        if level >= 0:
+            while len(self.numbering) <= level:
+                self.numbering.append(0)
+            del self.numbering[level+1:]
+            self.numbering[level] = self.numbering[level] + 1
+            x = ''
+            for i in self.numbering:
+                x = x + repr(i) + '.'
+            args = x + ' ' + args
+            self.contents.append((level, args, self.nodename))
+        self.write('<', type, '>')
+        self.expand(args)
+        self.write('</', type, '>\n')
+        if self.debugging or self.print_headers:
+            print '---', args
+
+    def do_contents(self, args):
+        # pass
+        self.listcontents('Table of Contents', 999)
+
+    def do_shortcontents(self, args):
+        pass
+        # self.listcontents('Short Contents', 0)
+    do_summarycontents = do_shortcontents
+
+    def listcontents(self, title, maxlevel):
+        self.write('<H1>', title, '</H1>\n<UL COMPACT PLAIN>\n')
+        prevlevels = [0]
+        for level, title, node in self.contents:
+            if level > maxlevel:
+                continue
+            if level > prevlevels[-1]:
+                # can only advance one level at a time
+                self.write('  '*prevlevels[-1], '<UL PLAIN>\n')
+                prevlevels.append(level)
+            elif level < prevlevels[-1]:
+                # might drop back multiple levels
+                while level < prevlevels[-1]:
+                    del prevlevels[-1]
+                    self.write('  '*prevlevels[-1],
+                               '</UL>\n')
+            self.write('  '*level, '<LI> <A HREF="',
+                       makefile(node), '">')
+            self.expand(title)
+            self.write('</A>\n')
+        self.write('</UL>\n' * len(prevlevels))
+
+    # --- Page lay-out ---
+
+    # These commands are only meaningful in printed text
+
+    def do_page(self, args): pass
+
+    def do_need(self, args): pass
+
+    def bgn_group(self, args): pass
+    def end_group(self): pass
+
+    # --- Line lay-out ---
+
+    def do_sp(self, args):
+        if self.nofill:
+            self.write('\n')
+        else:
+            self.write('<P>\n')
+
+    def do_hline(self, args):
+        self.write('<HR>')
+
+    # --- Function and variable definitions ---
+
+    def bgn_deffn(self, args):
+        self.write('<DL>')
+        self.do_deffnx(args)
+
+    def end_deffn(self):
+        self.write('</DL>\n')
+
+    def do_deffnx(self, args):
+        self.write('<DT>')
+        words = splitwords(args, 2)
+        [category, name], rest = words[:2], words[2:]
+        self.expand('@b{%s}' % name)
+        for word in rest: self.expand(' ' + makevar(word))
+        #self.expand(' -- ' + category)
+        self.write('\n<DD>')
+        self.index('fn', name)
+
+    def bgn_defun(self, args): self.bgn_deffn('Function ' + args)
+    end_defun = end_deffn
+    def do_defunx(self, args): self.do_deffnx('Function ' + args)
+
+    def bgn_defmac(self, args): self.bgn_deffn('Macro ' + args)
+    end_defmac = end_deffn
+    def do_defmacx(self, args): self.do_deffnx('Macro ' + args)
+
+    def bgn_defspec(self, args): self.bgn_deffn('{Special Form} ' + args)
+    end_defspec = end_deffn
+    def do_defspecx(self, args): self.do_deffnx('{Special Form} ' + args)
+
+    def bgn_defvr(self, args):
+        self.write('<DL>')
+        self.do_defvrx(args)
+
+    end_defvr = end_deffn
+
+    def do_defvrx(self, args):
+        self.write('<DT>')
+        words = splitwords(args, 2)
+        [category, name], rest = words[:2], words[2:]
+        self.expand('@code{%s}' % name)
+        # If there are too many arguments, show them
+        for word in rest: self.expand(' ' + word)
+        #self.expand(' -- ' + category)
+        self.write('\n<DD>')
+        self.index('vr', name)
+
+    def bgn_defvar(self, args): self.bgn_defvr('Variable ' + args)
+    end_defvar = end_defvr
+    def do_defvarx(self, args): self.do_defvrx('Variable ' + args)
+
+    def bgn_defopt(self, args): self.bgn_defvr('{User Option} ' + args)
+    end_defopt = end_defvr
+    def do_defoptx(self, args): self.do_defvrx('{User Option} ' + args)
+
+    # --- Ditto for typed languages ---
+
+    def bgn_deftypefn(self, args):
+        self.write('<DL>')
+        self.do_deftypefnx(args)
+
+    end_deftypefn = end_deffn
+
+    def do_deftypefnx(self, args):
+        self.write('<DT>')
+        words = splitwords(args, 3)
+        [category, datatype, name], rest = words[:3], words[3:]
+        self.expand('@code{%s} @b{%s}' % (datatype, name))
+        for word in rest: self.expand(' ' + makevar(word))
+        #self.expand(' -- ' + category)
+        self.write('\n<DD>')
+        self.index('fn', name)
+
+
+    def bgn_deftypefun(self, args): self.bgn_deftypefn('Function ' + args)
+    end_deftypefun = end_deftypefn
+    def do_deftypefunx(self, args): self.do_deftypefnx('Function ' + args)
+
+    def bgn_deftypevr(self, args):
+        self.write('<DL>')
+        self.do_deftypevrx(args)
+
+    end_deftypevr = end_deftypefn
+
+    def do_deftypevrx(self, args):
+        self.write('<DT>')
+        words = splitwords(args, 3)
+        [category, datatype, name], rest = words[:3], words[3:]
+        self.expand('@code{%s} @b{%s}' % (datatype, name))
+        # If there are too many arguments, show them
+        for word in rest: self.expand(' ' + word)
+        #self.expand(' -- ' + category)
+        self.write('\n<DD>')
+        self.index('fn', name)
+
+    def bgn_deftypevar(self, args):
+        self.bgn_deftypevr('Variable ' + args)
+    end_deftypevar = end_deftypevr
+    def do_deftypevarx(self, args):
+        self.do_deftypevrx('Variable ' + args)
+
+    # --- Ditto for object-oriented languages ---
+
+    def bgn_defcv(self, args):
+        self.write('<DL>')
+        self.do_defcvx(args)
+
+    end_defcv = end_deftypevr
+
+    def do_defcvx(self, args):
+        self.write('<DT>')
+        words = splitwords(args, 3)
+        [category, classname, name], rest = words[:3], words[3:]
+        self.expand('@b{%s}' % name)
+        # If there are too many arguments, show them
+        for word in rest: self.expand(' ' + word)
+        #self.expand(' -- %s of @code{%s}' % (category, classname))
+        self.write('\n<DD>')
+        self.index('vr', '%s @r{on %s}' % (name, classname))
+
+    def bgn_defivar(self, args):
+        self.bgn_defcv('{Instance Variable} ' + args)
+    end_defivar = end_defcv
+    def do_defivarx(self, args):
+        self.do_defcvx('{Instance Variable} ' + args)
+
+    def bgn_defop(self, args):
+        self.write('<DL>')
+        self.do_defopx(args)
+
+    end_defop = end_defcv
+
+    def do_defopx(self, args):
+        self.write('<DT>')
+        words = splitwords(args, 3)
+        [category, classname, name], rest = words[:3], words[3:]
+        self.expand('@b{%s}' % name)
+        for word in rest: self.expand(' ' + makevar(word))
+        #self.expand(' -- %s of @code{%s}' % (category, classname))
+        self.write('\n<DD>')
+        self.index('fn', '%s @r{on %s}' % (name, classname))
+
+    def bgn_defmethod(self, args):
+        self.bgn_defop('Method ' + args)
+    end_defmethod = end_defop
+    def do_defmethodx(self, args):
+        self.do_defopx('Method ' + args)
+
+    # --- Ditto for data types ---
+
+    def bgn_deftp(self, args):
+        self.write('<DL>')
+        self.do_deftpx(args)
+
+    end_deftp = end_defcv
+
+    def do_deftpx(self, args):
+        self.write('<DT>')
+        words = splitwords(args, 2)
+        [category, name], rest = words[:2], words[2:]
+        self.expand('@b{%s}' % name)
+        for word in rest: self.expand(' ' + word)
+        #self.expand(' -- ' + category)
+        self.write('\n<DD>')
+        self.index('tp', name)
+
+    # --- Making Lists and Tables
+
+    def bgn_enumerate(self, args):
+        if not args:
+            self.write('<OL>\n')
+            self.stackinfo[len(self.stack)] = '</OL>\n'
+        else:
+            self.itemnumber = args
+            self.write('<UL>\n')
+            self.stackinfo[len(self.stack)] = '</UL>\n'
+    def end_enumerate(self):
+        self.itemnumber = None
+        self.write(self.stackinfo[len(self.stack) + 1])
+        del self.stackinfo[len(self.stack) + 1]
+
+    def bgn_itemize(self, args):
+        self.itemarg = args
+        self.write('<UL>\n')
+    def end_itemize(self):
+        self.itemarg = None
+        self.write('</UL>\n')
+
+    def bgn_table(self, args):
+        self.itemarg = args
+        self.write('<DL>\n')
+    def end_table(self):
+        self.itemarg = None
+        self.write('</DL>\n')
+
+    def bgn_ftable(self, args):
+        self.itemindex = 'fn'
+        self.bgn_table(args)
+    def end_ftable(self):
+        self.itemindex = None
+        self.end_table()
+
+    def bgn_vtable(self, args):
+        self.itemindex = 'vr'
+        self.bgn_table(args)
+    def end_vtable(self):
+        self.itemindex = None
+        self.end_table()
+
+    def do_item(self, args):
+        if self.itemindex: self.index(self.itemindex, args)
+        if self.itemarg:
+            if self.itemarg[0] == '@' and self.itemarg[1] and \
+                            self.itemarg[1] in string.ascii_letters:
+                args = self.itemarg + '{' + args + '}'
+            else:
+                # some other character, e.g. '-'
+                args = self.itemarg + ' ' + args
+        if self.itemnumber <> None:
+            args = self.itemnumber + '. ' + args
+            self.itemnumber = increment(self.itemnumber)
+        if self.stack and self.stack[-1] == 'table':
+            self.write('<DT>')
+            self.expand(args)
+            self.write('\n<DD>')
+        elif self.stack and self.stack[-1] == 'multitable':
+            self.write('<TR><TD>')
+            self.expand(args)
+            self.write('</TD>\n</TR>\n')
+        else:
+            self.write('<LI>')
+            self.expand(args)
+            self.write('  ')
+    do_itemx = do_item # XXX Should suppress leading blank line
+
+    # rpyron 2002-05-07  multitable support
+    def bgn_multitable(self, args):
+        self.itemarg = None     # should be handled by columnfractions
+        self.write('<TABLE BORDER="">\n')
+    def end_multitable(self):
+        self.itemarg = None
+        self.write('</TABLE>\n<BR>\n')
+    def handle_columnfractions(self):
+        # It would be better to handle this, but for now it's in the way...
+        self.itemarg = None
+    def handle_tab(self):
+        self.write('</TD>\n    <TD>')
+
+    # --- Enumerations, displays, quotations ---
+    # XXX Most of these should increase the indentation somehow
+
+    def bgn_quotation(self, args): self.write('<BLOCKQUOTE>')
+    def end_quotation(self): self.write('</BLOCKQUOTE>\n')
+
+    def bgn_example(self, args):
+        self.nofill = self.nofill + 1
+        self.write('<PRE>')
+    def end_example(self):
+        self.write('</PRE>\n')
+        self.nofill = self.nofill - 1
+
+    bgn_lisp = bgn_example # Synonym when contents are executable lisp code
+    end_lisp = end_example
+
+    bgn_smallexample = bgn_example # XXX Should use smaller font
+    end_smallexample = end_example
+
+    bgn_smalllisp = bgn_lisp # Ditto
+    end_smalllisp = end_lisp
+
+    bgn_display = bgn_example
+    end_display = end_example
+
+    bgn_format = bgn_display
+    end_format = end_display
+
+    def do_exdent(self, args): self.expand(args + '\n')
+    # XXX Should really mess with indentation
+
+    def bgn_flushleft(self, args):
+        self.nofill = self.nofill + 1
+        self.write('<PRE>\n')
+    def end_flushleft(self):
+        self.write('</PRE>\n')
+        self.nofill = self.nofill - 1
+
+    def bgn_flushright(self, args):
+        self.nofill = self.nofill + 1
+        self.write('<ADDRESS COMPACT>\n')
+    def end_flushright(self):
+        self.write('</ADDRESS>\n')
+        self.nofill = self.nofill - 1
+
+    def bgn_menu(self, args):
+        self.write('<DIR>\n')
+        self.write('  <STRONG><EM>Menu</EM></STRONG><P>\n')
+        self.htmlhelp.beginmenu()
+    def end_menu(self):
+        self.write('</DIR>\n')
+        self.htmlhelp.endmenu()
+
+    def bgn_cartouche(self, args): pass
+    def end_cartouche(self): pass
+
+    # --- Indices ---
+
+    def resetindex(self):
+        self.noncodeindices = ['cp']
+        self.indextitle = {}
+        self.indextitle['cp'] = 'Concept'
+        self.indextitle['fn'] = 'Function'
+        self.indextitle['ky'] = 'Keyword'
+        self.indextitle['pg'] = 'Program'
+        self.indextitle['tp'] = 'Type'
+        self.indextitle['vr'] = 'Variable'
+        #
+        self.whichindex = {}
+        for name in self.indextitle.keys():
+            self.whichindex[name] = []
+
+    def user_index(self, name, args):
+        if self.whichindex.has_key(name):
+            self.index(name, args)
+        else:
+            print '*** No index named', repr(name)
+
+    def do_cindex(self, args): self.index('cp', args)
+    def do_findex(self, args): self.index('fn', args)
+    def do_kindex(self, args): self.index('ky', args)
+    def do_pindex(self, args): self.index('pg', args)
+    def do_tindex(self, args): self.index('tp', args)
+    def do_vindex(self, args): self.index('vr', args)
+
+    def index(self, name, args):
+        self.whichindex[name].append((args, self.nodename))
+        self.htmlhelp.index(args, self.nodename)
+
+    def do_synindex(self, args):
+        words = args.split()
+        if len(words) <> 2:
+            print '*** bad @synindex', args
+            return
+        [old, new] = words
+        if not self.whichindex.has_key(old) or \
+                  not self.whichindex.has_key(new):
+            print '*** bad key(s) in @synindex', args
+            return
+        if old <> new and \
+                  self.whichindex[old] is not self.whichindex[new]:
+            inew = self.whichindex[new]
+            inew[len(inew):] = self.whichindex[old]
+            self.whichindex[old] = inew
+    do_syncodeindex = do_synindex # XXX Should use code font
+
+    def do_printindex(self, args):
+        words = args.split()
+        for name in words:
+            if self.whichindex.has_key(name):
+                self.prindex(name)
+            else:
+                print '*** No index named', repr(name)
+
+    def prindex(self, name):
+        iscodeindex = (name not in self.noncodeindices)
+        index = self.whichindex[name]
+        if not index: return
+        if self.debugging:
+            print '!'*self.debugging, '--- Generating', \
+                  self.indextitle[name], 'index'
+        #  The node already provides a title
+        index1 = []
+        junkprog = re.compile('^(@[a-z]+)?{')
+        for key, node in index:
+            sortkey = key.lower()
+            # Remove leading `@cmd{' from sort key
+            # -- don't bother about the matching `}'
+            oldsortkey = sortkey
+            while 1:
+                mo = junkprog.match(sortkey)
+                if not mo:
+                    break
+                i = mo.end()
+                sortkey = sortkey[i:]
+            index1.append((sortkey, key, node))
+        del index[:]
+        index1.sort()
+        self.write('<DL COMPACT>\n')
+        prevkey = prevnode = None
+        for sortkey, key, node in index1:
+            if (key, node) == (prevkey, prevnode):
+                continue
+            if self.debugging > 1: print '!'*self.debugging, key, ':', node
+            self.write('<DT>')
+            if iscodeindex: key = '@code{' + key + '}'
+            if key != prevkey:
+                self.expand(key)
+            self.write('\n<DD><A HREF="%s">%s</A>\n' % (makefile(node), node))
+            prevkey, prevnode = key, node
+        self.write('</DL>\n')
+
+    # --- Final error reports ---
+
+    def report(self):
+        if self.unknown:
+            print '--- Unrecognized commands ---'
+            cmds = self.unknown.keys()
+            cmds.sort()
+            for cmd in cmds:
+                print cmd.ljust(20), self.unknown[cmd]
+
+
+class TexinfoParserHTML3(TexinfoParser):
+
+    COPYRIGHT_SYMBOL = "&copy;"
+    FN_ID_PATTERN = "[%(id)s]"
+    FN_SOURCE_PATTERN = '<A ID=footnoteref%(id)s ' \
+                        'HREF="#footnotetext%(id)s">' + FN_ID_PATTERN + '</A>'
+    FN_TARGET_PATTERN = '<FN ID=footnotetext%(id)s>\n' \
+                        '<P><A HREF="#footnoteref%(id)s">' + FN_ID_PATTERN \
+                        + '</A>\n%(text)s</P></FN>\n'
+    FN_HEADER = '<DIV CLASS=footnotes>\n  <HR NOSHADE WIDTH=200>\n' \
+                '  <STRONG><EM>Footnotes</EM></STRONG>\n  <P>\n'
+
+    Node = HTML3Node
+
+    def bgn_quotation(self, args): self.write('<BQ>')
+    def end_quotation(self): self.write('</BQ>\n')
+
+    def bgn_example(self, args):
+        # this use of <CODE> would not be legal in HTML 2.0,
+        # but is in more recent DTDs.
+        self.nofill = self.nofill + 1
+        self.write('<PRE CLASS=example><CODE>')
+    def end_example(self):
+        self.write("</CODE></PRE>\n")
+        self.nofill = self.nofill - 1
+
+    def bgn_flushleft(self, args):
+        self.nofill = self.nofill + 1
+        self.write('<PRE CLASS=flushleft>\n')
+
+    def bgn_flushright(self, args):
+        self.nofill = self.nofill + 1
+        self.write('<DIV ALIGN=right CLASS=flushright><ADDRESS COMPACT>\n')
+    def end_flushright(self):
+        self.write('</ADDRESS></DIV>\n')
+        self.nofill = self.nofill - 1
+
+    def bgn_menu(self, args):
+        self.write('<UL PLAIN CLASS=menu>\n')
+        self.write('  <LH>Menu</LH>\n')
+    def end_menu(self):
+        self.write('</UL>\n')
+
+
+# rpyron 2002-05-07
+class HTMLHelp:
+    """
+    This class encapsulates support for HTML Help. Node names,
+    file names, menu items, index items, and image file names are
+    accumulated until a call to finalize(). At that time, three
+    output files are created in the current directory:
+
+        `helpbase`.hhp  is a HTML Help Workshop project file.
+                        It contains various information, some of
+                        which I do not understand; I just copied
+                        the default project info from a fresh
+                        installation.
+        `helpbase`.hhc  is the Contents file for the project.
+        `helpbase`.hhk  is the Index file for the project.
+
+    When these files are used as input to HTML Help Workshop,
+    the resulting file will be named:
+
+        `helpbase`.chm
+
+    If none of the defaults in `helpbase`.hhp are changed,
+    the .CHM file will have Contents, Index, Search, and
+    Favorites tabs.
+    """
+
+    codeprog = re.compile('@code{(.*?)}')
+
+    def __init__(self,helpbase,dirname):
+        self.helpbase    = helpbase
+        self.dirname     = dirname
+        self.projectfile = None
+        self.contentfile = None
+        self.indexfile   = None
+        self.nodelist    = []
+        self.nodenames   = {}         # nodename : index
+        self.nodeindex   = {}
+        self.filenames   = {}         # filename : filename
+        self.indexlist   = []         # (args,nodename) == (key,location)
+        self.current     = ''
+        self.menudict    = {}
+        self.dumped      = {}
+
+
+    def addnode(self,name,next,prev,up,filename):
+        node = (name,next,prev,up,filename)
+        # add this file to dict
+        # retrieve list with self.filenames.values()
+        self.filenames[filename] = filename
+        # add this node to nodelist
+        self.nodeindex[name] = len(self.nodelist)
+        self.nodelist.append(node)
+        # set 'current' for menu items
+        self.current = name
+        self.menudict[self.current] = []
+
+    def menuitem(self,nodename):
+        menu = self.menudict[self.current]
+        menu.append(nodename)
+
+
+    def addimage(self,imagename):
+        self.filenames[imagename] = imagename
+
+    def index(self, args, nodename):
+        self.indexlist.append((args,nodename))
+
+    def beginmenu(self):
+        pass
+
+    def endmenu(self):
+        pass
+
+    def finalize(self):
+        if not self.helpbase:
+            return
+
+        # generate interesting filenames
+        resultfile   = self.helpbase + '.chm'
+        projectfile  = self.helpbase + '.hhp'
+        contentfile  = self.helpbase + '.hhc'
+        indexfile    = self.helpbase + '.hhk'
+
+        # generate a reasonable title
+        title        = self.helpbase
+
+        # get the default topic file
+        (topname,topnext,topprev,topup,topfile) = self.nodelist[0]
+        defaulttopic = topfile
+
+        # PROJECT FILE
+        try:
+            fp = open(projectfile,'w')
+            print>>fp, '[OPTIONS]'
+            print>>fp, 'Auto Index=Yes'
+            print>>fp, 'Binary TOC=No'
+            print>>fp, 'Binary Index=Yes'
+            print>>fp, 'Compatibility=1.1'
+            print>>fp, 'Compiled file=' + resultfile + ''
+            print>>fp, 'Contents file=' + contentfile + ''
+            print>>fp, 'Default topic=' + defaulttopic + ''
+            print>>fp, 'Error log file=ErrorLog.log'
+            print>>fp, 'Index file=' + indexfile + ''
+            print>>fp, 'Title=' + title + ''
+            print>>fp, 'Display compile progress=Yes'
+            print>>fp, 'Full-text search=Yes'
+            print>>fp, 'Default window=main'
+            print>>fp, ''
+            print>>fp, '[WINDOWS]'
+            print>>fp, ('main=,"' + contentfile + '","' + indexfile
+                        + '","","",,,,,0x23520,222,0x1046,[10,10,780,560],'
+                        '0xB0000,,,,,,0')
+            print>>fp, ''
+            print>>fp, '[FILES]'
+            print>>fp, ''
+            self.dumpfiles(fp)
+            fp.close()
+        except IOError, msg:
+            print projectfile, ':', msg
+            sys.exit(1)
+
+        # CONTENT FILE
+        try:
+            fp = open(contentfile,'w')
+            print>>fp, '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">'
+            print>>fp, '<!-- This file defines the table of contents -->'
+            print>>fp, '<HTML>'
+            print>>fp, '<HEAD>'
+            print>>fp, ('<meta name="GENERATOR"'
+                        'content="Microsoft&reg; HTML Help Workshop 4.1">')
+            print>>fp, '<!-- Sitemap 1.0 -->'
+            print>>fp, '</HEAD>'
+            print>>fp, '<BODY>'
+            print>>fp, '   <OBJECT type="text/site properties">'
+            print>>fp, '     <param name="Window Styles" value="0x800025">'
+            print>>fp, '     <param name="comment" value="title:">'
+            print>>fp, '     <param name="comment" value="base:">'
+            print>>fp, '   </OBJECT>'
+            self.dumpnodes(fp)
+            print>>fp, '</BODY>'
+            print>>fp, '</HTML>'
+            fp.close()
+        except IOError, msg:
+            print contentfile, ':', msg
+            sys.exit(1)
+
+        # INDEX FILE
+        try:
+            fp = open(indexfile  ,'w')
+            print>>fp, '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">'
+            print>>fp, '<!-- This file defines the index -->'
+            print>>fp, '<HTML>'
+            print>>fp, '<HEAD>'
+            print>>fp, ('<meta name="GENERATOR"'
+                        'content="Microsoft&reg; HTML Help Workshop 4.1">')
+            print>>fp, '<!-- Sitemap 1.0 -->'
+            print>>fp, '</HEAD>'
+            print>>fp, '<BODY>'
+            print>>fp, '<OBJECT type="text/site properties">'
+            print>>fp, '</OBJECT>'
+            self.dumpindex(fp)
+            print>>fp, '</BODY>'
+            print>>fp, '</HTML>'
+            fp.close()
+        except IOError, msg:
+            print indexfile  , ':', msg
+            sys.exit(1)
+
+    def dumpfiles(self, outfile=sys.stdout):
+        filelist = self.filenames.values()
+        filelist.sort()
+        for filename in filelist:
+            print>>outfile, filename
+
+    def dumpnodes(self, outfile=sys.stdout):
+        self.dumped = {}
+        if self.nodelist:
+            nodename, dummy, dummy, dummy, dummy = self.nodelist[0]
+            self.topnode = nodename
+
+        print>>outfile,  '<UL>'
+        for node in self.nodelist:
+            self.dumpnode(node,0,outfile)
+        print>>outfile,  '</UL>'
+
+    def dumpnode(self, node, indent=0, outfile=sys.stdout):
+        if node:
+            # Retrieve info for this node
+            (nodename,next,prev,up,filename) = node
+            self.current = nodename
+
+            # Have we been dumped already?
+            if self.dumped.has_key(nodename):
+                return
+            self.dumped[nodename] = 1
+
+            # Print info for this node
+            print>>outfile, ' '*indent,
+            print>>outfile, '<LI><OBJECT type="text/sitemap">',
+            print>>outfile, '<param name="Name" value="' + nodename +'">',
+            print>>outfile, '<param name="Local" value="'+ filename +'">',
+            print>>outfile, '</OBJECT>'
+
+            # Does this node have menu items?
+            try:
+                menu = self.menudict[nodename]
+                self.dumpmenu(menu,indent+2,outfile)
+            except KeyError:
+                pass
+
+    def dumpmenu(self, menu, indent=0, outfile=sys.stdout):
+        if menu:
+            currentnode = self.current
+            if currentnode != self.topnode:    # XXX this is a hack
+                print>>outfile, ' '*indent + '<UL>'
+                indent += 2
+            for item in menu:
+                menunode = self.getnode(item)
+                self.dumpnode(menunode,indent,outfile)
+            if currentnode != self.topnode:    # XXX this is a hack
+                print>>outfile, ' '*indent + '</UL>'
+                indent -= 2
+
+    def getnode(self, nodename):
+        try:
+            index = self.nodeindex[nodename]
+            return self.nodelist[index]
+        except KeyError:
+            return None
+        except IndexError:
+            return None
+
+    # (args,nodename) == (key,location)
+    def dumpindex(self, outfile=sys.stdout):
+        print>>outfile,  '<UL>'
+        for (key,location) in self.indexlist:
+            key = self.codeexpand(key)
+            location = makefile(location)
+            location = self.dirname + '/' + location
+            print>>outfile, '<LI><OBJECT type="text/sitemap">',
+            print>>outfile, '<param name="Name" value="' + key + '">',
+            print>>outfile, '<param name="Local" value="' + location + '">',
+            print>>outfile, '</OBJECT>'
+        print>>outfile,  '</UL>'
+
+    def codeexpand(self, line):
+        co = self.codeprog.match(line)
+        if not co:
+            return line
+        bgn, end = co.span(0)
+        a, b = co.span(1)
+        line = line[:bgn] + line[a:b] + line[end:]
+        return line
+
+
+# Put @var{} around alphabetic substrings
+def makevar(str):
+    return '@var{'+str+'}'
+
+
+# Split a string in "words" according to findwordend
+def splitwords(str, minlength):
+    words = []
+    i = 0
+    n = len(str)
+    while i < n:
+        while i < n and str[i] in ' \t\n': i = i+1
+        if i >= n: break
+        start = i
+        i = findwordend(str, i, n)
+        words.append(str[start:i])
+    while len(words) < minlength: words.append('')
+    return words
+
+
+# Find the end of a "word", matching braces and interpreting @@ @{ @}
+fwprog = re.compile('[@{} ]')
+def findwordend(str, i, n):
+    level = 0
+    while i < n:
+        mo = fwprog.search(str, i)
+        if not mo:
+            break
+        i = mo.start()
+        c = str[i]; i = i+1
+        if c == '@': i = i+1 # Next character is not special
+        elif c == '{': level = level+1
+        elif c == '}': level = level-1
+        elif c == ' ' and level <= 0: return i-1
+    return n
+
+
+# Convert a node name into a file name
+def makefile(nodename):
+    nodename = nodename.strip()
+    return fixfunnychars(nodename) + '.html'
+
+
+# Characters that are perfectly safe in filenames and hyperlinks
+goodchars = string.ascii_letters + string.digits + '!@-=+.'
+
+# Replace characters that aren't perfectly safe by dashes
+# Underscores are bad since Cern HTTPD treats them as delimiters for
+# encoding times, so you get mismatches if you compress your files:
+# a.html.gz will map to a_b.html.gz
+def fixfunnychars(addr):
+    i = 0
+    while i < len(addr):
+        c = addr[i]
+        if c not in goodchars:
+            c = '-'
+            addr = addr[:i] + c + addr[i+1:]
+        i = i + len(c)
+    return addr
+
+
+# Increment a string used as an enumeration
+def increment(s):
+    if not s:
+        return '1'
+    for sequence in string.digits, string.lowercase, string.uppercase:
+        lastc = s[-1]
+        if lastc in sequence:
+            i = sequence.index(lastc) + 1
+            if i >= len(sequence):
+                if len(s) == 1:
+                    s = sequence[0]*2
+                    if s == '00':
+                        s = '10'
+                else:
+                    s = increment(s[:-1]) + sequence[0]
+            else:
+                s = s[:-1] + sequence[i]
+            return s
+    return s # Don't increment
+
+
+def test():
+    import sys
+    debugging = 0
+    print_headers = 0
+    cont = 0
+    html3 = 0
+    htmlhelp = ''
+
+    while sys.argv[1] == ['-d']:
+        debugging = debugging + 1
+        del sys.argv[1]
+    if sys.argv[1] == '-p':
+        print_headers = 1
+        del sys.argv[1]
+    if sys.argv[1] == '-c':
+        cont = 1
+        del sys.argv[1]
+    if sys.argv[1] == '-3':
+        html3 = 1
+        del sys.argv[1]
+    if sys.argv[1] == '-H':
+        helpbase = sys.argv[2]
+        del sys.argv[1:3]
+    if len(sys.argv) <> 3:
+        print 'usage: texi2hh [-d [-d]] [-p] [-c] [-3] [-H htmlhelp]', \
+              'inputfile outputdirectory'
+        sys.exit(2)
+
+    if html3:
+        parser = TexinfoParserHTML3()
+    else:
+        parser = TexinfoParser()
+    parser.cont = cont
+    parser.debugging = debugging
+    parser.print_headers = print_headers
+
+    file = sys.argv[1]
+    dirname  = sys.argv[2]
+    parser.setdirname(dirname)
+    parser.setincludedir(os.path.dirname(file))
+
+    htmlhelp = HTMLHelp(helpbase, dirname)
+    parser.sethtmlhelp(htmlhelp)
+
+    try:
+        fp = open(file, 'r')
+    except IOError, msg:
+        print file, ':', msg
+        sys.exit(1)
+
+    parser.parse(fp)
+    fp.close()
+    parser.report()
+
+    htmlhelp.finalize()
+
+
+if __name__ == "__main__":
+    test()


Property changes on: vendor/Python/current/Tools/scripts/texi2html.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/scripts/treesync.py
===================================================================
--- vendor/Python/current/Tools/scripts/treesync.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/treesync.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,205 @@
+#! /usr/bin/env python
+
+"""Script to synchronize two source trees.
+
+Invoke with two arguments:
+
+python treesync.py slave master
+
+The assumption is that "master" contains CVS administration while
+slave doesn't.  All files in the slave tree that have a CVS/Entries
+entry in the master tree are synchronized.  This means:
+
+    If the files differ:
+        if the slave file is newer:
+            normalize the slave file
+            if the files still differ:
+                copy the slave to the master
+        else (the master is newer):
+            copy the master to the slave
+
+    normalizing the slave means replacing CRLF with LF when the master
+    doesn't use CRLF
+
+"""
+
+import os, sys, stat, getopt
+
+# Interactivity options
+default_answer = "ask"
+create_files = "yes"
+create_directories = "no"
+write_slave = "ask"
+write_master = "ask"
+
+def main():
+    global always_no, always_yes
+    global create_directories, write_master, write_slave
+    opts, args = getopt.getopt(sys.argv[1:], "nym:s:d:f:a:")
+    for o, a in opts:
+        if o == '-y':
+            default_answer = "yes"
+        if o == '-n':
+            default_answer = "no"
+        if o == '-s':
+            write_slave = a
+        if o == '-m':
+            write_master = a
+        if o == '-d':
+            create_directories = a
+        if o == '-f':
+            create_files = a
+        if o == '-a':
+            create_files = create_directories = write_slave = write_master = a
+    try:
+        [slave, master] = args
+    except ValueError:
+        print "usage: python", sys.argv[0] or "treesync.py",
+        print "[-n] [-y] [-m y|n|a] [-s y|n|a] [-d y|n|a] [-f n|y|a]",
+        print "slavedir masterdir"
+        return
+    process(slave, master)
+
+def process(slave, master):
+    cvsdir = os.path.join(master, "CVS")
+    if not os.path.isdir(cvsdir):
+        print "skipping master subdirectory", master
+        print "-- not under CVS"
+        return
+    print "-"*40
+    print "slave ", slave
+    print "master", master
+    if not os.path.isdir(slave):
+        if not okay("create slave directory %s?" % slave,
+                    answer=create_directories):
+            print "skipping master subdirectory", master
+            print "-- no corresponding slave", slave
+            return
+        print "creating slave directory", slave
+        try:
+            os.mkdir(slave)
+        except os.error, msg:
+            print "can't make slave directory", slave, ":", msg
+            return
+        else:
+            print "made slave directory", slave
+    cvsdir = None
+    subdirs = []
+    names = os.listdir(master)
+    for name in names:
+        mastername = os.path.join(master, name)
+        slavename = os.path.join(slave, name)
+        if name == "CVS":
+            cvsdir = mastername
+        else:
+            if os.path.isdir(mastername) and not os.path.islink(mastername):
+                subdirs.append((slavename, mastername))
+    if cvsdir:
+        entries = os.path.join(cvsdir, "Entries")
+        for e in open(entries).readlines():
+            words = e.split('/')
+            if words[0] == '' and words[1:]:
+                name = words[1]
+                s = os.path.join(slave, name)
+                m = os.path.join(master, name)
+                compare(s, m)
+    for (s, m) in subdirs:
+        process(s, m)
+
+def compare(slave, master):
+    try:
+        sf = open(slave, 'r')
+    except IOError:
+        sf = None
+    try:
+        mf = open(master, 'rb')
+    except IOError:
+        mf = None
+    if not sf:
+        if not mf:
+            print "Neither master nor slave exists", master
+            return
+        print "Creating missing slave", slave
+        copy(master, slave, answer=create_files)
+        return
+    if not mf:
+        print "Not updating missing master", master
+        return
+    if sf and mf:
+        if identical(sf, mf):
+            return
+    sft = mtime(sf)
+    mft = mtime(mf)
+    if mft > sft:
+        # Master is newer -- copy master to slave
+        sf.close()
+        mf.close()
+        print "Master             ", master
+        print "is newer than slave", slave
+        copy(master, slave, answer=write_slave)
+        return
+    # Slave is newer -- copy slave to master
+    print "Slave is", sft-mft, "seconds newer than master"
+    # But first check what to do about CRLF
+    mf.seek(0)
+    fun = funnychars(mf)
+    mf.close()
+    sf.close()
+    if fun:
+        print "***UPDATING MASTER (BINARY COPY)***"
+        copy(slave, master, "rb", answer=write_master)
+    else:
+        print "***UPDATING MASTER***"
+        copy(slave, master, "r", answer=write_master)
+
+BUFSIZE = 16*1024
+
+def identical(sf, mf):
+    while 1:
+        sd = sf.read(BUFSIZE)
+        md = mf.read(BUFSIZE)
+        if sd != md: return 0
+        if not sd: break
+    return 1
+
+def mtime(f):
+    st = os.fstat(f.fileno())
+    return st[stat.ST_MTIME]
+
+def funnychars(f):
+    while 1:
+        buf = f.read(BUFSIZE)
+        if not buf: break
+        if '\r' in buf or '\0' in buf: return 1
+    return 0
+
+def copy(src, dst, rmode="rb", wmode="wb", answer='ask'):
+    print "copying", src
+    print "     to", dst
+    if not okay("okay to copy? ", answer):
+        return
+    f = open(src, rmode)
+    g = open(dst, wmode)
+    while 1:
+        buf = f.read(BUFSIZE)
+        if not buf: break
+        g.write(buf)
+    f.close()
+    g.close()
+
+def okay(prompt, answer='ask'):
+    answer = answer.strip().lower()
+    if not answer or answer[0] not in 'ny':
+        answer = raw_input(prompt)
+        answer = answer.strip().lower()
+        if not answer:
+            answer = default_answer
+    if answer[:1] == 'y':
+        return 1
+    if answer[:1] == 'n':
+        return 0
+    print "Yes or No please -- try again:"
+    return okay(prompt)
+
+if __name__ == '__main__':
+    main()


Property changes on: vendor/Python/current/Tools/scripts/treesync.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/scripts/untabify.py
===================================================================
--- vendor/Python/current/Tools/scripts/untabify.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/untabify.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,52 @@
+#! /usr/bin/env python
+
+"Replace tabs with spaces in argument files.  Print names of changed files."
+
+import os
+import sys
+import getopt
+
+def main():
+    tabsize = 8
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], "t:")
+        if not args:
+            raise getopt.error, "At least one file argument required"
+    except getopt.error, msg:
+        print msg
+        print "usage:", sys.argv[0], "[-t tabwidth] file ..."
+        return
+    for optname, optvalue in opts:
+        if optname == '-t':
+            tabsize = int(optvalue)
+
+    for filename in args:
+        process(filename, tabsize)
+
+def process(filename, tabsize):
+    try:
+        f = open(filename)
+        text = f.read()
+        f.close()
+    except IOError, msg:
+        print "%r: I/O error: %s" % (filename, msg)
+        return
+    newtext = text.expandtabs(tabsize)
+    if newtext == text:
+        return
+    backup = filename + "~"
+    try:
+        os.unlink(backup)
+    except os.error:
+        pass
+    try:
+        os.rename(filename, backup)
+    except os.error:
+        pass
+    f = open(filename, "w")
+    f.write(newtext)
+    f.close()
+    print filename
+
+if __name__ == '__main__':
+    main()


Property changes on: vendor/Python/current/Tools/scripts/untabify.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/scripts/which.py
===================================================================
--- vendor/Python/current/Tools/scripts/which.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/which.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,60 @@
+#! /usr/bin/env python
+
+# Variant of "which".
+# On stderr, near and total misses are reported.
+# '-l<flags>' argument adds ls -l<flags> of each file found.
+
+import sys
+if sys.path[0] in (".", ""): del sys.path[0]
+
+import sys, os
+from stat import *
+
+def msg(str):
+    sys.stderr.write(str + '\n')
+
+def main():
+    pathlist = os.environ['PATH'].split(os.pathsep)
+
+    sts = 0
+    longlist = ''
+
+    if sys.argv[1:] and sys.argv[1][:2] == '-l':
+        longlist = sys.argv[1]
+        del sys.argv[1]
+
+    for prog in sys.argv[1:]:
+        ident = ()
+        for dir in pathlist:
+            filename = os.path.join(dir, prog)
+            try:
+                st = os.stat(filename)
+            except os.error:
+                continue
+            if not S_ISREG(st[ST_MODE]):
+                msg(filename + ': not a disk file')
+            else:
+                mode = S_IMODE(st[ST_MODE])
+                if mode & 0111:
+                    if not ident:
+                        print filename
+                        ident = st[:3]
+                    else:
+                        if st[:3] == ident:
+                            s = 'same as: '
+                        else:
+                            s = 'also: '
+                        msg(s + filename)
+                else:
+                    msg(filename + ': not executable')
+            if longlist:
+                sts = os.system('ls ' + longlist + ' ' + filename)
+                if sts: msg('"ls -l" exit status: ' + repr(sts))
+        if not ident:
+            msg(prog + ': not found')
+            sts = 1
+
+    sys.exit(sts)
+
+if __name__ == '__main__':
+    main()


Property changes on: vendor/Python/current/Tools/scripts/which.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/scripts/xxci.py
===================================================================
--- vendor/Python/current/Tools/scripts/xxci.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/scripts/xxci.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,117 @@
+#! /usr/bin/env python
+
+# xxci
+#
+# check in files for which rcsdiff returns nonzero exit status
+
+import sys
+import os
+from stat import *
+import commands
+import fnmatch
+
+EXECMAGIC = '\001\140\000\010'
+
+MAXSIZE = 200*1024 # Files this big must be binaries and are skipped.
+
+def getargs():
+    args = sys.argv[1:]
+    if args:
+        return args
+    print 'No arguments, checking almost *, in "ls -t" order'
+    list = []
+    for file in os.listdir(os.curdir):
+        if not skipfile(file):
+            list.append((getmtime(file), file))
+    list.sort()
+    if not list:
+        print 'Nothing to do -- exit 1'
+        sys.exit(1)
+    list.sort()
+    list.reverse()
+    for mtime, file in list: args.append(file)
+    return args
+
+def getmtime(file):
+    try:
+        st = os.stat(file)
+        return st[ST_MTIME]
+    except os.error:
+        return -1
+
+badnames = ['tags', 'TAGS', 'xyzzy', 'nohup.out', 'core']
+badprefixes = ['.', ',', '@', '#', 'o.']
+badsuffixes = \
+        ['~', '.a', '.o', '.old', '.bak', '.orig', '.new', '.prev', '.not', \
+         '.pyc', '.fdc', '.rgb', '.elc', ',v']
+ignore = []
+
+def setup():
+    ignore[:] = badnames
+    for p in badprefixes:
+        ignore.append(p + '*')
+    for p in badsuffixes:
+        ignore.append('*' + p)
+    try:
+        f = open('.xxcign', 'r')
+    except IOError:
+        return
+    ignore[:] = ignore + f.read().split()
+
+def skipfile(file):
+    for p in ignore:
+        if fnmatch.fnmatch(file, p): return 1
+    try:
+        st = os.lstat(file)
+    except os.error:
+        return 1 # Doesn't exist -- skip it
+    # Skip non-plain files.
+    if not S_ISREG(st[ST_MODE]): return 1
+    # Skip huge files -- probably binaries.
+    if st[ST_SIZE] >= MAXSIZE: return 1
+    # Skip executables
+    try:
+        data = open(file, 'r').read(len(EXECMAGIC))
+        if data == EXECMAGIC: return 1
+    except:
+        pass
+    return 0
+
+def badprefix(file):
+    for bad in badprefixes:
+        if file[:len(bad)] == bad: return 1
+    return 0
+
+def badsuffix(file):
+    for bad in badsuffixes:
+        if file[-len(bad):] == bad: return 1
+    return 0
+
+def go(args):
+    for file in args:
+        print file + ':'
+        if differing(file):
+            showdiffs(file)
+            if askyesno('Check in ' + file + ' ? '):
+                sts = os.system('rcs -l ' + file) # ignored
+                sts = os.system('ci -l ' + file)
+
+def differing(file):
+    cmd = 'co -p ' + file + ' 2>/dev/null | cmp -s - ' + file
+    sts = os.system(cmd)
+    return sts != 0
+
+def showdiffs(file):
+    cmd = 'rcsdiff ' + file + ' 2>&1 | ${PAGER-more}'
+    sts = os.system(cmd)
+
+def askyesno(prompt):
+    s = raw_input(prompt)
+    return s in ['y', 'yes']
+
+if __name__ == '__main__':
+    try:
+        setup()
+        go(getargs())
+    except KeyboardInterrupt:
+        print '[Intr]'


Property changes on: vendor/Python/current/Tools/scripts/xxci.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/unicode/comparecodecs.py
===================================================================
--- vendor/Python/current/Tools/unicode/comparecodecs.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/unicode/comparecodecs.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,53 @@
+#!/usr/bin/env python
+
+""" Compare the output of two codecs.
+
+(c) Copyright 2005, Marc-Andre Lemburg (mal at lemburg.com).
+
+    Licensed to PSF under a Contributor Agreement.
+
+"""
+import sys
+
+def compare_codecs(encoding1, encoding2):
+
+    print 'Comparing encoding/decoding of   %r and   %r' % (encoding1, encoding2)
+    mismatch = 0
+    # Check encoding
+    for i in range(sys.maxunicode):
+        u = unichr(i)
+        try:
+            c1 = u.encode(encoding1)
+        except UnicodeError, reason:
+            c1 = '<undefined>'
+        try:
+            c2 = u.encode(encoding2)
+        except UnicodeError, reason:
+            c2 = '<undefined>'
+        if c1 != c2:
+            print ' * encoding mismatch for 0x%04X: %-14r != %r' % \
+                  (i, c1, c2)
+            mismatch += 1
+    # Check decoding
+    for i in range(256):
+        c = chr(i)
+        try:
+            u1 = c.decode(encoding1)
+        except UnicodeError:
+            u1 = u'<undefined>'
+        try:
+            u2 = c.decode(encoding2)
+        except UnicodeError:
+            u2 = u'<undefined>'
+        if u1 != u2:
+            print ' * decoding mismatch for 0x%04X: %-14r != %r' % \
+                  (i, u1, u2)
+            mismatch += 1
+    if mismatch:
+        print
+        print 'Found %i mismatches' % mismatch
+    else:
+        print '-> Codecs are identical.'
+
+if __name__ == '__main__':
+    compare_codecs(sys.argv[1], sys.argv[2])

Added: vendor/Python/current/Tools/unicode/gencjkcodecs.py
===================================================================
--- vendor/Python/current/Tools/unicode/gencjkcodecs.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/unicode/gencjkcodecs.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,68 @@
+import os, string
+
+codecs = {
+    'cn': ('gb2312', 'gbk', 'gb18030', 'hz'),
+    'tw': ('big5', 'cp950'),
+    'hk': ('big5hkscs',),
+    'jp': ('cp932', 'shift_jis', 'euc_jp', 'euc_jisx0213', 'shift_jisx0213',
+           'euc_jis_2004', 'shift_jis_2004'),
+    'kr': ('cp949', 'euc_kr', 'johab'),
+    'iso2022': ('iso2022_jp', 'iso2022_jp_1', 'iso2022_jp_2',
+                'iso2022_jp_2004', 'iso2022_jp_3', 'iso2022_jp_ext',
+                'iso2022_kr'),
+}
+
+TEMPLATE = string.Template("""\
+#
+# $encoding.py: Python Unicode Codec for $ENCODING
+#
+# Written by Hye-Shik Chang <perky at FreeBSD.org>
+#
+
+import _codecs_$owner, codecs
+import _multibytecodec as mbc
+
+codec = _codecs_$owner.getcodec('$encoding')
+
+class Codec(codecs.Codec):
+    encode = codec.encode
+    decode = codec.decode
+
+class IncrementalEncoder(mbc.MultibyteIncrementalEncoder,
+                         codecs.IncrementalEncoder):
+    codec = codec
+
+class IncrementalDecoder(mbc.MultibyteIncrementalDecoder,
+                         codecs.IncrementalDecoder):
+    codec = codec
+
+class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader):
+    codec = codec
+
+class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter):
+    codec = codec
+
+def getregentry():
+    return codecs.CodecInfo(
+        name='$encoding',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+""")
+
+def gencodecs(prefix):
+    for loc, encodings in codecs.iteritems():
+        for enc in encodings:
+            code = TEMPLATE.substitute(ENCODING=enc.upper(),
+                                       encoding=enc.lower(),
+                                       owner=loc)
+            codecpath = os.path.join(prefix, enc + '.py')
+            open(codecpath, 'w').write(code)
+
+if __name__ == '__main__':
+    import sys
+    gencodecs(sys.argv[1])

Added: vendor/Python/current/Tools/unicode/gencodec.py
===================================================================
--- vendor/Python/current/Tools/unicode/gencodec.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/unicode/gencodec.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,426 @@
+""" Unicode Mapping Parser and Codec Generator.
+
+This script parses Unicode mapping files as available from the Unicode
+site (ftp://ftp.unicode.org/Public/MAPPINGS/) and creates Python codec
+modules from them. The codecs use the standard character mapping codec
+to actually apply the mapping.
+
+Synopsis: gencodec.py dir codec_prefix
+
+All files in dir are scanned and those producing non-empty mappings
+will be written to <codec_prefix><mapname>.py with <mapname> being the
+first part of the map's filename ('a' in a.b.c.txt) converted to
+lowercase with hyphens replaced by underscores.
+
+The tool also writes marshalled versions of the mapping tables to the
+same location (with .mapping extension).
+
+Written by Marc-Andre Lemburg (mal at lemburg.com).
+
+(c) Copyright CNRI, All Rights Reserved. NO WARRANTY.
+(c) Copyright Guido van Rossum, 2000.
+
+Table generation:
+(c) Copyright Marc-Andre Lemburg, 2005.
+    Licensed to PSF under a Contributor Agreement.
+
+"""#"
+
+import re, os, time, marshal, codecs
+
+# Maximum allowed size of charmap tables
+MAX_TABLE_SIZE = 8192
+
+# Standard undefined Unicode code point
+UNI_UNDEFINED = unichr(0xFFFE)
+
+mapRE = re.compile('((?:0x[0-9a-fA-F]+\+?)+)'
+                   '\s+'
+                   '((?:(?:0x[0-9a-fA-Z]+|<[A-Za-z]+>)\+?)*)'
+                   '\s*'
+                   '(#.+)?')
+
+def parsecodes(codes,
+               len=len, filter=filter,range=range):
+
+    """ Converts code combinations to either a single code integer
+        or a tuple of integers.
+
+        meta-codes (in angular brackets, e.g. <LR> and <RL>) are
+        ignored.
+
+        Empty codes or illegal ones are returned as None.
+
+    """
+    if not codes:
+        return None
+    l = codes.split('+')
+    if len(l) == 1:
+        return int(l[0],16)
+    for i in range(len(l)):
+        try:
+            l[i] = int(l[i],16)
+        except ValueError:
+            l[i] = None
+    l = filter(lambda x: x is not None, l)
+    if len(l) == 1:
+        return l[0]
+    else:
+        return tuple(l)
+
+def readmap(filename):
+
+    f = open(filename,'r')
+    lines = f.readlines()
+    f.close()
+    enc2uni = {}
+    identity = []
+    unmapped = range(256)
+
+    # UTC mapping tables per convention don't include the identity
+    # mappings for code points 0x00 - 0x1F and 0x7F, unless these are
+    # explicitly mapped to different characters or undefined
+    for i in range(32) + [127]:
+        identity.append(i)
+        unmapped.remove(i)
+        enc2uni[i] = (i, 'CONTROL CHARACTER')
+
+    for line in lines:
+        line = line.strip()
+        if not line or line[0] == '#':
+            continue
+        m = mapRE.match(line)
+        if not m:
+            #print '* not matched: %s' % repr(line)
+            continue
+        enc,uni,comment = m.groups()
+        enc = parsecodes(enc)
+        uni = parsecodes(uni)
+        if comment is None:
+            comment = ''
+        else:
+            comment = comment[1:].strip()
+        if enc < 256:
+            if enc in unmapped:
+                unmapped.remove(enc)
+            if enc == uni:
+                identity.append(enc)
+            enc2uni[enc] = (uni,comment)
+        else:
+            enc2uni[enc] = (uni,comment)
+
+    # If there are more identity-mapped entries than unmapped entries,
+    # it pays to generate an identity dictionary first, and add explicit
+    # mappings to None for the rest
+    if len(identity) >= len(unmapped):
+        for enc in unmapped:
+            enc2uni[enc] = (None, "")
+        enc2uni['IDENTITY'] = 256
+
+    return enc2uni
+
+def hexrepr(t, precision=4):
+
+    if t is None:
+        return 'None'
+    try:
+        len(t)
+    except:
+        return '0x%0*X' % (precision, t)
+    try:
+        return '(' + ', '.join(['0x%0*X' % (precision, item)
+                                for item in t]) + ')'
+    except TypeError, why:
+        print '* failed to convert %r: %s' % (t, why)
+        raise
+
+def python_mapdef_code(varname, map, comments=1, precisions=(2, 4)):
+
+    l = []
+    append = l.append
+    if map.has_key("IDENTITY"):
+        append("%s = codecs.make_identity_dict(range(%d))" %
+               (varname, map["IDENTITY"]))
+        append("%s.update({" % varname)
+        splits = 1
+        del map["IDENTITY"]
+        identity = 1
+    else:
+        append("%s = {" % varname)
+        splits = 0
+        identity = 0
+
+    mappings = map.items()
+    mappings.sort()
+    i = 0
+    key_precision, value_precision = precisions
+    for mapkey, mapvalue in mappings:
+        mapcomment = ''
+        if isinstance(mapkey, tuple):
+            (mapkey, mapcomment) = mapkey
+        if isinstance(mapvalue, tuple):
+            (mapvalue, mapcomment) = mapvalue
+        if mapkey is None:
+            continue
+        if (identity and
+            mapkey == mapvalue and
+            mapkey < 256):
+            # No need to include identity mappings, since these
+            # are already set for the first 256 code points.
+            continue
+        key = hexrepr(mapkey, key_precision)
+        value = hexrepr(mapvalue, value_precision)
+        if mapcomment and comments:
+            append('    %s: %s,\t#  %s' % (key, value, mapcomment))
+        else:
+            append('    %s: %s,' % (key, value))
+        i += 1
+        if i == 4096:
+            # Split the definition into parts to that the Python
+            # parser doesn't dump core
+            if splits == 0:
+                append('}')
+            else:
+                append('})')
+            append('%s.update({' % varname)
+            i = 0
+            splits = splits + 1
+    if splits == 0:
+        append('}')
+    else:
+        append('})')
+
+    return l
+
+def python_tabledef_code(varname, map, comments=1, key_precision=2):
+
+    l = []
+    append = l.append
+    append('%s = (' % varname)
+
+    # Analyze map and create table dict
+    mappings = map.items()
+    mappings.sort()
+    table = {}
+    maxkey = 0
+    if map.has_key('IDENTITY'):
+        for key in range(256):
+            table[key] = (key, '')
+        maxkey = 255
+        del map['IDENTITY']
+    for mapkey, mapvalue in mappings:
+        mapcomment = ''
+        if isinstance(mapkey, tuple):
+            (mapkey, mapcomment) = mapkey
+        if isinstance(mapvalue, tuple):
+            (mapvalue, mapcomment) = mapvalue
+        if mapkey is None:
+            continue
+        table[mapkey] = (mapvalue, mapcomment)
+        if mapkey > maxkey:
+            maxkey = mapkey
+    if maxkey > MAX_TABLE_SIZE:
+        # Table too large
+        return None
+
+    # Create table code
+    for key in range(maxkey + 1):
+        if key not in table:
+            mapvalue = None
+            mapcomment = 'UNDEFINED'
+        else:
+            mapvalue, mapcomment = table[key]
+        if mapvalue is None:
+            mapchar = UNI_UNDEFINED
+        else:
+            if isinstance(mapvalue, tuple):
+                # 1-n mappings not supported
+                return None
+            else:
+                mapchar = unichr(mapvalue)
+        if mapcomment and comments:
+            append('    %r\t#  %s -> %s' % (mapchar,
+                                            hexrepr(key, key_precision),
+                                            mapcomment))
+        else:
+            append('    %r' % mapchar)
+
+    append(')')
+    return l
+
+def codegen(name, map, encodingname, comments=1):
+
+    """ Returns Python source for the given map.
+
+        Comments are included in the source, if comments is true (default).
+
+    """
+    # Generate code
+    decoding_map_code = python_mapdef_code(
+        'decoding_map',
+        map,
+        comments=comments)
+    decoding_table_code = python_tabledef_code(
+        'decoding_table',
+        map,
+        comments=comments)
+    encoding_map_code = python_mapdef_code(
+        'encoding_map',
+        codecs.make_encoding_map(map),
+        comments=comments,
+        precisions=(4, 2))
+
+    if decoding_table_code:
+        suffix = 'table'
+    else:
+        suffix = 'map'
+
+    l = [
+        '''\
+""" Python Character Mapping Codec %s generated from '%s' with gencodec.py.
+
+"""#"
+
+import codecs
+
+### Codec APIs
+
+class Codec(codecs.Codec):
+
+    def encode(self,input,errors='strict'):
+        return codecs.charmap_encode(input,errors,encoding_%s)
+
+    def decode(self,input,errors='strict'):
+        return codecs.charmap_decode(input,errors,decoding_%s)
+''' % (encodingname, name, suffix, suffix)]
+    l.append('''\
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_%s)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_%s)[0]''' %
+        (suffix, suffix))
+
+    l.append('''
+class StreamWriter(Codec,codecs.StreamWriter):
+    pass
+
+class StreamReader(Codec,codecs.StreamReader):
+    pass
+
+### encodings module API
+
+def getregentry():
+    return codecs.CodecInfo(
+        name=%r,
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
+''' % encodingname.replace('_', '-'))
+
+    # Add decoding table or map (with preference to the table)
+    if not decoding_table_code:
+        l.append('''
+### Decoding Map
+''')
+        l.extend(decoding_map_code)
+    else:
+        l.append('''
+### Decoding Table
+''')
+        l.extend(decoding_table_code)
+
+    # Add encoding map
+    if decoding_table_code:
+        l.append('''
+### Encoding table
+encoding_table=codecs.charmap_build(decoding_table)
+''')
+    else:
+        l.append('''
+### Encoding Map
+''')
+        l.extend(encoding_map_code)
+
+    # Final new-line
+    l.append('')
+
+    return '\n'.join(l).expandtabs()
+
+def pymap(name,map,pyfile,encodingname,comments=1):
+
+    code = codegen(name,map,encodingname,comments)
+    f = open(pyfile,'w')
+    f.write(code)
+    f.close()
+
+def marshalmap(name,map,marshalfile):
+
+    d = {}
+    for e,(u,c) in map.items():
+        d[e] = (u,c)
+    f = open(marshalfile,'wb')
+    marshal.dump(d,f)
+    f.close()
+
+def convertdir(dir, dirprefix='', nameprefix='', comments=1):
+
+    mapnames = os.listdir(dir)
+    for mapname in mapnames:
+        mappathname = os.path.join(dir, mapname)
+        if not os.path.isfile(mappathname):
+            continue
+        name = os.path.split(mapname)[1]
+        name = name.replace('-','_')
+        name = name.split('.')[0]
+        name = name.lower()
+        name = nameprefix + name
+        codefile = name + '.py'
+        marshalfile = name + '.mapping'
+        print 'converting %s to %s and %s' % (mapname,
+                                              dirprefix + codefile,
+                                              dirprefix + marshalfile)
+        try:
+            map = readmap(os.path.join(dir,mapname))
+            if not map:
+                print '* map is empty; skipping'
+            else:
+                pymap(mappathname, map, dirprefix + codefile,name,comments)
+                marshalmap(mappathname, map, dirprefix + marshalfile)
+        except ValueError, why:
+            print '* conversion failed: %s' % why
+            raise
+
+def rewritepythondir(dir, dirprefix='', comments=1):
+
+    mapnames = os.listdir(dir)
+    for mapname in mapnames:
+        if not mapname.endswith('.mapping'):
+            continue
+        name = mapname[:-len('.mapping')]
+        codefile = name + '.py'
+        print 'converting %s to %s' % (mapname,
+                                       dirprefix + codefile)
+        try:
+            map = marshal.load(open(os.path.join(dir,mapname),
+                               'rb'))
+            if not map:
+                print '* map is empty; skipping'
+            else:
+                pymap(mapname, map, dirprefix + codefile,name,comments)
+        except ValueError, why:
+            print '* conversion failed: %s' % why
+
+if __name__ == '__main__':
+
+    import sys
+    if 1:
+        apply(convertdir,tuple(sys.argv[1:]))
+    else:
+        apply(rewritepythondir,tuple(sys.argv[1:]))

Added: vendor/Python/current/Tools/unicode/listcodecs.py
===================================================================
--- vendor/Python/current/Tools/unicode/listcodecs.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/unicode/listcodecs.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,41 @@
+""" List all available codec modules.
+
+(c) Copyright 2005, Marc-Andre Lemburg (mal at lemburg.com).
+
+    Licensed to PSF under a Contributor Agreement.
+
+"""
+
+import os, codecs, encodings
+
+_debug = 0
+
+def listcodecs(dir):
+    names = []
+    for filename in os.listdir(dir):
+        if filename[-3:] != '.py':
+            continue
+        name = filename[:-3]
+        # Check whether we've found a true codec
+        try:
+            codecs.lookup(name)
+        except LookupError:
+            # Codec not found
+            continue
+        except Exception, reason:
+            # Probably an error from importing the codec; still it's
+            # a valid code name
+            if _debug:
+                print '* problem importing codec %r: %s' % \
+                      (name, reason)
+        names.append(name)
+    return names
+
+
+if __name__ == '__main__':
+    names = listcodecs(encodings.__path__[0])
+    names.sort()
+    print 'all_codecs = ['
+    for name in names:
+        print '    %r,' % name
+    print ']'

Added: vendor/Python/current/Tools/unicode/makeunicodedata.py
===================================================================
--- vendor/Python/current/Tools/unicode/makeunicodedata.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/unicode/makeunicodedata.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,943 @@
+#
+# (re)generate unicode property and type databases
+#
+# this script converts a unicode 3.2 database file to
+# Modules/unicodedata_db.h, Modules/unicodename_db.h,
+# and Objects/unicodetype_db.h
+#
+# history:
+# 2000-09-24 fl   created (based on bits and pieces from unidb)
+# 2000-09-25 fl   merged tim's splitbin fixes, separate decomposition table
+# 2000-09-25 fl   added character type table
+# 2000-09-26 fl   added LINEBREAK, DECIMAL, and DIGIT flags/fields (2.0)
+# 2000-11-03 fl   expand first/last ranges
+# 2001-01-19 fl   added character name tables (2.1)
+# 2001-01-21 fl   added decomp compression; dynamic phrasebook threshold
+# 2002-09-11 wd   use string methods
+# 2002-10-18 mvl  update to Unicode 3.2
+# 2002-10-22 mvl  generate NFC tables
+# 2002-11-24 mvl  expand all ranges, sort names version-independently
+# 2002-11-25 mvl  add UNIDATA_VERSION
+# 2004-05-29 perky add east asian width information
+# 2006-03-10 mvl  update to Unicode 4.1; add UCD 3.2 delta
+#
+# written by Fredrik Lundh (fredrik at pythonware.com)
+#
+
+import sys
+
+SCRIPT = sys.argv[0]
+VERSION = "2.5"
+
+# The Unicode Database
+UNIDATA_VERSION = "4.1.0"
+UNICODE_DATA = "UnicodeData%s.txt"
+COMPOSITION_EXCLUSIONS = "CompositionExclusions%s.txt"
+EASTASIAN_WIDTH = "EastAsianWidth%s.txt"
+
+old_versions = ["3.2.0"]
+
+CATEGORY_NAMES = [ "Cn", "Lu", "Ll", "Lt", "Mn", "Mc", "Me", "Nd",
+    "Nl", "No", "Zs", "Zl", "Zp", "Cc", "Cf", "Cs", "Co", "Cn", "Lm",
+    "Lo", "Pc", "Pd", "Ps", "Pe", "Pi", "Pf", "Po", "Sm", "Sc", "Sk",
+    "So" ]
+
+BIDIRECTIONAL_NAMES = [ "", "L", "LRE", "LRO", "R", "AL", "RLE", "RLO",
+    "PDF", "EN", "ES", "ET", "AN", "CS", "NSM", "BN", "B", "S", "WS",
+    "ON" ]
+
+EASTASIANWIDTH_NAMES = [ "F", "H", "W", "Na", "A", "N" ]
+
+# note: should match definitions in Objects/unicodectype.c
+ALPHA_MASK = 0x01
+DECIMAL_MASK = 0x02
+DIGIT_MASK = 0x04
+LOWER_MASK = 0x08
+LINEBREAK_MASK = 0x10
+SPACE_MASK = 0x20
+TITLE_MASK = 0x40
+UPPER_MASK = 0x80
+
+def maketables(trace=0):
+
+    print "--- Reading", UNICODE_DATA % "", "..."
+
+    version = ""
+    unicode = UnicodeData(UNICODE_DATA % version,
+                          COMPOSITION_EXCLUSIONS % version,
+                          EASTASIAN_WIDTH % version)
+
+    print len(filter(None, unicode.table)), "characters"
+
+    for version in old_versions:
+        print "--- Reading", UNICODE_DATA % ("-"+version), "..."
+        old_unicode = UnicodeData(UNICODE_DATA % ("-"+version),
+                                  COMPOSITION_EXCLUSIONS % ("-"+version),
+                                  EASTASIAN_WIDTH % ("-"+version))
+        print len(filter(None, old_unicode.table)), "characters"
+        merge_old_version(version, unicode, old_unicode)
+
+    makeunicodename(unicode, trace)
+    makeunicodedata(unicode, trace)
+    makeunicodetype(unicode, trace)
+
+# --------------------------------------------------------------------
+# unicode character properties
+
+def makeunicodedata(unicode, trace):
+
+    dummy = (0, 0, 0, 0, 0)
+    table = [dummy]
+    cache = {0: dummy}
+    index = [0] * len(unicode.chars)
+
+    FILE = "Modules/unicodedata_db.h"
+
+    print "--- Preparing", FILE, "..."
+
+    # 1) database properties
+
+    for char in unicode.chars:
+        record = unicode.table[char]
+        if record:
+            # extract database properties
+            category = CATEGORY_NAMES.index(record[2])
+            combining = int(record[3])
+            bidirectional = BIDIRECTIONAL_NAMES.index(record[4])
+            mirrored = record[9] == "Y"
+            eastasianwidth = EASTASIANWIDTH_NAMES.index(record[15])
+            item = (
+                category, combining, bidirectional, mirrored, eastasianwidth
+                )
+            # add entry to index and item tables
+            i = cache.get(item)
+            if i is None:
+                cache[item] = i = len(table)
+                table.append(item)
+            index[char] = i
+
+    # 2) decomposition data
+
+    decomp_data = [0]
+    decomp_prefix = [""]
+    decomp_index = [0] * len(unicode.chars)
+    decomp_size = 0
+
+    comp_pairs = []
+    comp_first = [None] * len(unicode.chars)
+    comp_last = [None] * len(unicode.chars)
+
+    for char in unicode.chars:
+        record = unicode.table[char]
+        if record:
+            if record[5]:
+                decomp = record[5].split()
+                if len(decomp) > 19:
+                    raise Exception, "character %x has a decomposition too large for nfd_nfkd" % char
+                # prefix
+                if decomp[0][0] == "<":
+                    prefix = decomp.pop(0)
+                else:
+                    prefix = ""
+                try:
+                    i = decomp_prefix.index(prefix)
+                except ValueError:
+                    i = len(decomp_prefix)
+                    decomp_prefix.append(prefix)
+                prefix = i
+                assert prefix < 256
+                # content
+                decomp = [prefix + (len(decomp)<<8)] +\
+                         map(lambda s: int(s, 16), decomp)
+                # Collect NFC pairs
+                if not prefix and len(decomp) == 3 and \
+                   char not in unicode.exclusions and \
+                   unicode.table[decomp[1]][3] == "0":
+                    p, l, r = decomp
+                    comp_first[l] = 1
+                    comp_last[r] = 1
+                    comp_pairs.append((l,r,char))
+                try:
+                    i = decomp_data.index(decomp)
+                except ValueError:
+                    i = len(decomp_data)
+                    decomp_data.extend(decomp)
+                    decomp_size = decomp_size + len(decomp) * 2
+            else:
+                i = 0
+            decomp_index[char] = i
+
+    f = l = 0
+    comp_first_ranges = []
+    comp_last_ranges = []
+    prev_f = prev_l = None
+    for i in unicode.chars:
+        if comp_first[i] is not None:
+            comp_first[i] = f
+            f += 1
+            if prev_f is None:
+                prev_f = (i,i)
+            elif prev_f[1]+1 == i:
+                prev_f = prev_f[0],i
+            else:
+                comp_first_ranges.append(prev_f)
+                prev_f = (i,i)
+        if comp_last[i] is not None:
+            comp_last[i] = l
+            l += 1
+            if prev_l is None:
+                prev_l = (i,i)
+            elif prev_l[1]+1 == i:
+                prev_l = prev_l[0],i
+            else:
+                comp_last_ranges.append(prev_l)
+                prev_l = (i,i)
+    comp_first_ranges.append(prev_f)
+    comp_last_ranges.append(prev_l)
+    total_first = f
+    total_last = l
+
+    comp_data = [0]*(total_first*total_last)
+    for f,l,char in comp_pairs:
+        f = comp_first[f]
+        l = comp_last[l]
+        comp_data[f*total_last+l] = char
+
+    print len(table), "unique properties"
+    print len(decomp_prefix), "unique decomposition prefixes"
+    print len(decomp_data), "unique decomposition entries:",
+    print decomp_size, "bytes"
+    print total_first, "first characters in NFC"
+    print total_last, "last characters in NFC"
+    print len(comp_pairs), "NFC pairs"
+
+    print "--- Writing", FILE, "..."
+
+    fp = open(FILE, "w")
+    print >>fp, "/* this file was generated by %s %s */" % (SCRIPT, VERSION)
+    print >>fp
+    print >>fp, '#define UNIDATA_VERSION "%s"' % UNIDATA_VERSION
+    print >>fp, "/* a list of unique database records */"
+    print >>fp, \
+          "const _PyUnicode_DatabaseRecord _PyUnicode_Database_Records[] = {"
+    for item in table:
+        print >>fp, "    {%d, %d, %d, %d, %d}," % item
+    print >>fp, "};"
+    print >>fp
+
+    print >>fp, "/* Reindexing of NFC first characters. */"
+    print >>fp, "#define TOTAL_FIRST",total_first
+    print >>fp, "#define TOTAL_LAST",total_last
+    print >>fp, "struct reindex{int start;short count,index;};"
+    print >>fp, "struct reindex nfc_first[] = {"
+    for start,end in comp_first_ranges:
+        print >>fp,"  { %d, %d, %d}," % (start,end-start,comp_first[start])
+    print >>fp,"  {0,0,0}"
+    print >>fp,"};\n"
+    print >>fp, "struct reindex nfc_last[] = {"
+    for start,end in comp_last_ranges:
+        print >>fp,"  { %d, %d, %d}," % (start,end-start,comp_last[start])
+    print >>fp,"  {0,0,0}"
+    print >>fp,"};\n"
+
+    # FIXME: <fl> the following tables could be made static, and
+    # the support code moved into unicodedatabase.c
+
+    print >>fp, "/* string literals */"
+    print >>fp, "const char *_PyUnicode_CategoryNames[] = {"
+    for name in CATEGORY_NAMES:
+        print >>fp, "    \"%s\"," % name
+    print >>fp, "    NULL"
+    print >>fp, "};"
+
+    print >>fp, "const char *_PyUnicode_BidirectionalNames[] = {"
+    for name in BIDIRECTIONAL_NAMES:
+        print >>fp, "    \"%s\"," % name
+    print >>fp, "    NULL"
+    print >>fp, "};"
+
+    print >>fp, "const char *_PyUnicode_EastAsianWidthNames[] = {"
+    for name in EASTASIANWIDTH_NAMES:
+        print >>fp, "    \"%s\"," % name
+    print >>fp, "    NULL"
+    print >>fp, "};"
+
+    print >>fp, "static const char *decomp_prefix[] = {"
+    for name in decomp_prefix:
+        print >>fp, "    \"%s\"," % name
+    print >>fp, "    NULL"
+    print >>fp, "};"
+
+    # split record index table
+    index1, index2, shift = splitbins(index, trace)
+
+    print >>fp, "/* index tables for the database records */"
+    print >>fp, "#define SHIFT", shift
+    Array("index1", index1).dump(fp, trace)
+    Array("index2", index2).dump(fp, trace)
+
+    # split decomposition index table
+    index1, index2, shift = splitbins(decomp_index, trace)
+
+    print >>fp, "/* decomposition data */"
+    Array("decomp_data", decomp_data).dump(fp, trace)
+
+    print >>fp, "/* index tables for the decomposition data */"
+    print >>fp, "#define DECOMP_SHIFT", shift
+    Array("decomp_index1", index1).dump(fp, trace)
+    Array("decomp_index2", index2).dump(fp, trace)
+
+    index, index2, shift = splitbins(comp_data, trace)
+    print >>fp, "/* NFC pairs */"
+    print >>fp, "#define COMP_SHIFT", shift
+    Array("comp_index", index).dump(fp, trace)
+    Array("comp_data", index2).dump(fp, trace)
+
+    # Generate delta tables for old versions
+    for version, table, normalization in unicode.changed:
+        cversion = version.replace(".","_")
+        records = [table[0]]
+        cache = {table[0]:0}
+        index = [0] * len(table)
+        for i, record in enumerate(table):
+            try:
+                index[i] = cache[record]
+            except KeyError:
+                index[i] = cache[record] = len(records)
+                records.append(record)
+        index1, index2, shift = splitbins(index, trace)
+        print >>fp, "static const change_record change_records_%s[] = {" % cversion
+        for record in records:
+            print >>fp, "\t{ %s }," % ", ".join(map(str,record))
+        print >>fp, "};"
+        Array("changes_%s_index" % cversion, index1).dump(fp, trace)
+        Array("changes_%s_data" % cversion, index2).dump(fp, trace)
+        print >>fp, "static const change_record* get_change_%s(Py_UCS4 n)" % cversion
+        print >>fp, "{"
+        print >>fp, "\tint index;"
+        print >>fp, "\tif (n >= 0x110000) index = 0;"
+        print >>fp, "\telse {"
+        print >>fp, "\t\tindex = changes_%s_index[n>>%d];" % (cversion, shift)
+        print >>fp, "\t\tindex = changes_%s_data[(index<<%d)+(n & %d)];" % \
+              (cversion, shift, ((1<<shift)-1))
+        print >>fp, "\t}"
+        print >>fp, "\treturn change_records_%s+index;" % cversion
+        print >>fp, "}\n"
+        print >>fp, "static Py_UCS4 normalization_%s(Py_UCS4 n)" % cversion
+        print >>fp, "{"
+        print >>fp, "\tswitch(n) {"
+        for k, v in normalization:
+            print >>fp, "\tcase %s: return 0x%s;" % (hex(k), v)
+        print >>fp, "\tdefault: return 0;"
+        print >>fp, "\t}\n}\n"
+
+    fp.close()
+
+# --------------------------------------------------------------------
+# unicode character type tables
+
+def makeunicodetype(unicode, trace):
+
+    FILE = "Objects/unicodetype_db.h"
+
+    print "--- Preparing", FILE, "..."
+
+    # extract unicode types
+    dummy = (0, 0, 0, 0, 0, 0)
+    table = [dummy]
+    cache = {0: dummy}
+    index = [0] * len(unicode.chars)
+
+    for char in unicode.chars:
+        record = unicode.table[char]
+        if record:
+            # extract database properties
+            category = record[2]
+            bidirectional = record[4]
+            flags = 0
+            if category in ["Lm", "Lt", "Lu", "Ll", "Lo"]:
+                flags |= ALPHA_MASK
+            if category == "Ll":
+                flags |= LOWER_MASK
+            if category == "Zl" or bidirectional == "B":
+                flags |= LINEBREAK_MASK
+            if category == "Zs" or bidirectional in ("WS", "B", "S"):
+                flags |= SPACE_MASK
+            if category == "Lt":
+                flags |= TITLE_MASK
+            if category == "Lu":
+                flags |= UPPER_MASK
+            # use delta predictor for upper/lower/title
+            if record[12]:
+                upper = int(record[12], 16) - char
+                assert -32768 <= upper <= 32767
+                upper = upper & 0xffff
+            else:
+                upper = 0
+            if record[13]:
+                lower = int(record[13], 16) - char
+                assert -32768 <= lower <= 32767
+                lower = lower & 0xffff
+            else:
+                lower = 0
+            if record[14]:
+                title = int(record[14], 16) - char
+                assert -32768 <= lower <= 32767
+                title = title & 0xffff
+            else:
+                title = 0
+            # decimal digit, integer digit
+            decimal = 0
+            if record[6]:
+                flags |= DECIMAL_MASK
+                decimal = int(record[6])
+            digit = 0
+            if record[7]:
+                flags |= DIGIT_MASK
+                digit = int(record[7])
+            item = (
+                upper, lower, title, decimal, digit, flags
+                )
+            # add entry to index and item tables
+            i = cache.get(item)
+            if i is None:
+                cache[item] = i = len(table)
+                table.append(item)
+            index[char] = i
+
+    print len(table), "unique character type entries"
+
+    print "--- Writing", FILE, "..."
+
+    fp = open(FILE, "w")
+    print >>fp, "/* this file was generated by %s %s */" % (SCRIPT, VERSION)
+    print >>fp
+    print >>fp, "/* a list of unique character type descriptors */"
+    print >>fp, "const _PyUnicode_TypeRecord _PyUnicode_TypeRecords[] = {"
+    for item in table:
+        print >>fp, "    {%d, %d, %d, %d, %d, %d}," % item
+    print >>fp, "};"
+    print >>fp
+
+    # split decomposition index table
+    index1, index2, shift = splitbins(index, trace)
+
+    print >>fp, "/* type indexes */"
+    print >>fp, "#define SHIFT", shift
+    Array("index1", index1).dump(fp, trace)
+    Array("index2", index2).dump(fp, trace)
+
+    fp.close()
+
+# --------------------------------------------------------------------
+# unicode name database
+
+def makeunicodename(unicode, trace):
+
+    FILE = "Modules/unicodename_db.h"
+
+    print "--- Preparing", FILE, "..."
+
+    # collect names
+    names = [None] * len(unicode.chars)
+
+    for char in unicode.chars:
+        record = unicode.table[char]
+        if record:
+            name = record[1].strip()
+            if name and name[0] != "<":
+                names[char] = name + chr(0)
+
+    print len(filter(lambda n: n is not None, names)), "distinct names"
+
+    # collect unique words from names (note that we differ between
+    # words inside a sentence, and words ending a sentence.  the
+    # latter includes the trailing null byte.
+
+    words = {}
+    n = b = 0
+    for char in unicode.chars:
+        name = names[char]
+        if name:
+            w = name.split()
+            b = b + len(name)
+            n = n + len(w)
+            for w in w:
+                l = words.get(w)
+                if l:
+                    l.append(None)
+                else:
+                    words[w] = [len(words)]
+
+    print n, "words in text;", b, "bytes"
+
+    wordlist = words.items()
+
+    # sort on falling frequency, then by name
+    def cmpwords((aword, alist),(bword, blist)):
+        r = -cmp(len(alist),len(blist))
+        if r:
+            return r
+        return cmp(aword, bword)
+    wordlist.sort(cmpwords)
+
+    # figure out how many phrasebook escapes we need
+    escapes = 0
+    while escapes * 256 < len(wordlist):
+        escapes = escapes + 1
+    print escapes, "escapes"
+
+    short = 256 - escapes
+
+    assert short > 0
+
+    print short, "short indexes in lexicon"
+
+    # statistics
+    n = 0
+    for i in range(short):
+        n = n + len(wordlist[i][1])
+    print n, "short indexes in phrasebook"
+
+    # pick the most commonly used words, and sort the rest on falling
+    # length (to maximize overlap)
+
+    wordlist, wordtail = wordlist[:short], wordlist[short:]
+    wordtail.sort(lambda a, b: len(b[0])-len(a[0]))
+    wordlist.extend(wordtail)
+
+    # generate lexicon from words
+
+    lexicon_offset = [0]
+    lexicon = ""
+    words = {}
+
+    # build a lexicon string
+    offset = 0
+    for w, x in wordlist:
+        # encoding: bit 7 indicates last character in word (chr(128)
+        # indicates the last character in an entire string)
+        ww = w[:-1] + chr(ord(w[-1])+128)
+        # reuse string tails, when possible
+        o = lexicon.find(ww)
+        if o < 0:
+            o = offset
+            lexicon = lexicon + ww
+            offset = offset + len(w)
+        words[w] = len(lexicon_offset)
+        lexicon_offset.append(o)
+
+    lexicon = map(ord, lexicon)
+
+    # generate phrasebook from names and lexicon
+    phrasebook = [0]
+    phrasebook_offset = [0] * len(unicode.chars)
+    for char in unicode.chars:
+        name = names[char]
+        if name:
+            w = name.split()
+            phrasebook_offset[char] = len(phrasebook)
+            for w in w:
+                i = words[w]
+                if i < short:
+                    phrasebook.append(i)
+                else:
+                    # store as two bytes
+                    phrasebook.append((i>>8) + short)
+                    phrasebook.append(i&255)
+
+    assert getsize(phrasebook) == 1
+
+    #
+    # unicode name hash table
+
+    # extract names
+    data = []
+    for char in unicode.chars:
+        record = unicode.table[char]
+        if record:
+            name = record[1].strip()
+            if name and name[0] != "<":
+                data.append((name, char))
+
+    # the magic number 47 was chosen to minimize the number of
+    # collisions on the current data set.  if you like, change it
+    # and see what happens...
+
+    codehash = Hash("code", data, 47)
+
+    print "--- Writing", FILE, "..."
+
+    fp = open(FILE, "w")
+    print >>fp, "/* this file was generated by %s %s */" % (SCRIPT, VERSION)
+    print >>fp
+    print >>fp, "#define NAME_MAXLEN", 256
+    print >>fp
+    print >>fp, "/* lexicon */"
+    Array("lexicon", lexicon).dump(fp, trace)
+    Array("lexicon_offset", lexicon_offset).dump(fp, trace)
+
+    # split decomposition index table
+    offset1, offset2, shift = splitbins(phrasebook_offset, trace)
+
+    print >>fp, "/* code->name phrasebook */"
+    print >>fp, "#define phrasebook_shift", shift
+    print >>fp, "#define phrasebook_short", short
+
+    Array("phrasebook", phrasebook).dump(fp, trace)
+    Array("phrasebook_offset1", offset1).dump(fp, trace)
+    Array("phrasebook_offset2", offset2).dump(fp, trace)
+
+    print >>fp, "/* name->code dictionary */"
+    codehash.dump(fp, trace)
+
+    fp.close()
+
+
+def merge_old_version(version, new, old):
+    # Changes to exclusion file not implemented yet
+    if old.exclusions != new.exclusions:
+        raise NotImplementedError, "exclusions differ"
+
+    # In these change records, 0xFF means "no change"
+    bidir_changes = [0xFF]*0x110000
+    category_changes = [0xFF]*0x110000
+    decimal_changes = [0xFF]*0x110000
+    # In numeric data, 0 means "no change",
+    # -1 means "did not have a numeric value
+    numeric_changes = [0] * 0x110000
+    # normalization_changes is a list of key-value pairs
+    normalization_changes = []
+    for i in range(0x110000):
+        if new.table[i] is None:
+            # Characters unassigned in the new version ought to
+            # be unassigned in the old one
+            assert old.table[i] is None
+            continue
+        # check characters unassigned in the old version
+        if old.table[i] is None:
+            # category 0 is "unassigned"
+            category_changes[i] = 0
+            continue
+        # check characters that differ
+        if old.table[i] != new.table[i]:
+            for k in range(len(old.table[i])):
+                if old.table[i][k] != new.table[i][k]:
+                    value = old.table[i][k]
+                    if k == 2:
+                        #print "CATEGORY",hex(i), old.table[i][k], new.table[i][k]
+                        category_changes[i] = CATEGORY_NAMES.index(value)
+                    elif k == 4:
+                        #print "BIDIR",hex(i), old.table[i][k], new.table[i][k]
+                        bidir_changes[i] = BIDIRECTIONAL_NAMES.index(value)
+                    elif k == 5:
+                        #print "DECOMP",hex(i), old.table[i][k], new.table[i][k]
+                        # We assume that all normalization changes are in 1:1 mappings
+                        assert " " not in value
+                        normalization_changes.append((i, value))
+                    elif k == 6:
+                        #print "DECIMAL",hex(i), old.table[i][k], new.table[i][k]
+                        # we only support changes where the old value is a single digit
+                        assert value in "0123456789"
+                        decimal_changes[i] = int(value)
+                    elif k == 8:
+                        # print "NUMERIC",hex(i), `old.table[i][k]`, new.table[i][k]
+                        # Since 0 encodes "no change", the old value is better not 0
+                        assert value != "0" and value != "-1"
+                        if not value:
+                            numeric_changes[i] = -1
+                        else:
+                            assert re.match("^[0-9]+$", value)
+                            numeric_changes[i] = int(value)
+                    elif k == 11:
+                        # change to ISO comment, ignore
+                        pass
+                    elif k == 12:
+                        # change to simple uppercase mapping; ignore
+                        pass
+                    elif k == 13:
+                        # change to simple lowercase mapping; ignore
+                        pass
+                    elif k == 14:
+                        # change to simple titlecase mapping; ignore
+                        pass
+                    else:
+                        class Difference(Exception):pass
+                        raise Difference, (hex(i), k, old.table[i], new.table[i])
+    new.changed.append((version, zip(bidir_changes, category_changes,
+                                     decimal_changes, numeric_changes),
+                        normalization_changes))
+
+
+# --------------------------------------------------------------------
+# the following support code is taken from the unidb utilities
+# Copyright (c) 1999-2000 by Secret Labs AB
+
+# load a unicode-data file from disk
+
+import sys
+
+class UnicodeData:
+
+    def __init__(self, filename, exclusions, eastasianwidth, expand=1):
+        self.changed = []
+        file = open(filename)
+        table = [None] * 0x110000
+        while 1:
+            s = file.readline()
+            if not s:
+                break
+            s = s.strip().split(";")
+            char = int(s[0], 16)
+            table[char] = s
+
+        # expand first-last ranges
+        if expand:
+            field = None
+            for i in range(0, 0x110000):
+                s = table[i]
+                if s:
+                    if s[1][-6:] == "First>":
+                        s[1] = ""
+                        field = s
+                    elif s[1][-5:] == "Last>":
+                        s[1] = ""
+                        field = None
+                elif field:
+                    f2 = field[:]
+                    f2[0] = "%X" % i
+                    table[i] = f2
+
+        # public attributes
+        self.filename = filename
+        self.table = table
+        self.chars = range(0x110000) # unicode 3.2
+
+        file = open(exclusions)
+        self.exclusions = {}
+        for s in file:
+            s = s.strip()
+            if not s:
+                continue
+            if s[0] == '#':
+                continue
+            char = int(s.split()[0],16)
+            self.exclusions[char] = 1
+
+        widths = [None] * 0x110000
+        for s in open(eastasianwidth):
+            s = s.strip()
+            if not s:
+                continue
+            if s[0] == '#':
+                continue
+            s = s.split()[0].split(';')
+            if '..' in s[0]:
+                first, last = [int(c, 16) for c in s[0].split('..')]
+                chars = range(first, last+1)
+            else:
+                chars = [int(s[0], 16)]
+            for char in chars:
+                widths[char] = s[1]
+        for i in range(0, 0x110000):
+            if table[i] is not None:
+                table[i].append(widths[i])
+
+    def uselatin1(self):
+        # restrict character range to ISO Latin 1
+        self.chars = range(256)
+
+# hash table tools
+
+# this is a straight-forward reimplementation of Python's built-in
+# dictionary type, using a static data structure, and a custom string
+# hash algorithm.
+
+def myhash(s, magic):
+    h = 0
+    for c in map(ord, s.upper()):
+        h = (h * magic) + c
+        ix = h & 0xff000000L
+        if ix:
+            h = (h ^ ((ix>>24) & 0xff)) & 0x00ffffff
+    return h
+
+SIZES = [
+    (4,3), (8,3), (16,3), (32,5), (64,3), (128,3), (256,29), (512,17),
+    (1024,9), (2048,5), (4096,83), (8192,27), (16384,43), (32768,3),
+    (65536,45), (131072,9), (262144,39), (524288,39), (1048576,9),
+    (2097152,5), (4194304,3), (8388608,33), (16777216,27)
+]
+
+class Hash:
+    def __init__(self, name, data, magic):
+        # turn a (key, value) list into a static hash table structure
+
+        # determine table size
+        for size, poly in SIZES:
+            if size > len(data):
+                poly = size + poly
+                break
+        else:
+            raise AssertionError, "ran out of polynominals"
+
+        print size, "slots in hash table"
+
+        table = [None] * size
+
+        mask = size-1
+
+        n = 0
+
+        hash = myhash
+
+        # initialize hash table
+        for key, value in data:
+            h = hash(key, magic)
+            i = (~h) & mask
+            v = table[i]
+            if v is None:
+                table[i] = value
+                continue
+            incr = (h ^ (h >> 3)) & mask;
+            if not incr:
+                incr = mask
+            while 1:
+                n = n + 1
+                i = (i + incr) & mask
+                v = table[i]
+                if v is None:
+                    table[i] = value
+                    break
+                incr = incr << 1
+                if incr > mask:
+                    incr = incr ^ poly
+
+        print n, "collisions"
+        self.collisions = n
+
+        for i in range(len(table)):
+            if table[i] is None:
+                table[i] = 0
+
+        self.data = Array(name + "_hash", table)
+        self.magic = magic
+        self.name = name
+        self.size = size
+        self.poly = poly
+
+    def dump(self, file, trace):
+        # write data to file, as a C array
+        self.data.dump(file, trace)
+        file.write("#define %s_magic %d\n" % (self.name, self.magic))
+        file.write("#define %s_size %d\n" % (self.name, self.size))
+        file.write("#define %s_poly %d\n" % (self.name, self.poly))
+
+# stuff to deal with arrays of unsigned integers
+
+class Array:
+
+    def __init__(self, name, data):
+        self.name = name
+        self.data = data
+
+    def dump(self, file, trace=0):
+        # write data to file, as a C array
+        size = getsize(self.data)
+        if trace:
+            print >>sys.stderr, self.name+":", size*len(self.data), "bytes"
+        file.write("static ")
+        if size == 1:
+            file.write("unsigned char")
+        elif size == 2:
+            file.write("unsigned short")
+        else:
+            file.write("unsigned int")
+        file.write(" " + self.name + "[] = {\n")
+        if self.data:
+            s = "    "
+            for item in self.data:
+                i = str(item) + ", "
+                if len(s) + len(i) > 78:
+                    file.write(s + "\n")
+                    s = "    " + i
+                else:
+                    s = s + i
+            if s.strip():
+                file.write(s + "\n")
+        file.write("};\n\n")
+
+def getsize(data):
+    # return smallest possible integer size for the given array
+    maxdata = max(data)
+    if maxdata < 256:
+        return 1
+    elif maxdata < 65536:
+        return 2
+    else:
+        return 4
+
+def splitbins(t, trace=0):
+    """t, trace=0 -> (t1, t2, shift).  Split a table to save space.
+
+    t is a sequence of ints.  This function can be useful to save space if
+    many of the ints are the same.  t1 and t2 are lists of ints, and shift
+    is an int, chosen to minimize the combined size of t1 and t2 (in C
+    code), and where for each i in range(len(t)),
+        t[i] == t2[(t1[i >> shift] << shift) + (i & mask)]
+    where mask is a bitmask isolating the last "shift" bits.
+
+    If optional arg trace is non-zero (default zero), progress info
+    is printed to sys.stderr.  The higher the value, the more info
+    you'll get.
+    """
+
+    import sys
+    if trace:
+        def dump(t1, t2, shift, bytes):
+            print >>sys.stderr, "%d+%d bins at shift %d; %d bytes" % (
+                len(t1), len(t2), shift, bytes)
+        print >>sys.stderr, "Size of original table:", len(t)*getsize(t), \
+                            "bytes"
+    n = len(t)-1    # last valid index
+    maxshift = 0    # the most we can shift n and still have something left
+    if n > 0:
+        while n >> 1:
+            n >>= 1
+            maxshift += 1
+    del n
+    bytes = sys.maxint  # smallest total size so far
+    t = tuple(t)    # so slices can be dict keys
+    for shift in range(maxshift + 1):
+        t1 = []
+        t2 = []
+        size = 2**shift
+        bincache = {}
+        for i in range(0, len(t), size):
+            bin = t[i:i+size]
+            index = bincache.get(bin)
+            if index is None:
+                index = len(t2)
+                bincache[bin] = index
+                t2.extend(bin)
+            t1.append(index >> shift)
+        # determine memory size
+        b = len(t1)*getsize(t1) + len(t2)*getsize(t2)
+        if trace > 1:
+            dump(t1, t2, shift, b)
+        if b < bytes:
+            best = t1, t2, shift
+            bytes = b
+    t1, t2, shift = best
+    if trace:
+        print >>sys.stderr, "Best:",
+        dump(t1, t2, shift, bytes)
+    if __debug__:
+        # exhaustively verify that the decomposition is correct
+        mask = ~((~0) << shift) # i.e., low-bit mask of shift bits
+        for i in xrange(len(t)):
+            assert t[i] == t2[(t1[i >> shift] << shift) + (i & mask)]
+    return best
+
+if __name__ == "__main__":
+    maketables(1)

Added: vendor/Python/current/Tools/unicode/mkstringprep.py
===================================================================
--- vendor/Python/current/Tools/unicode/mkstringprep.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/unicode/mkstringprep.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,431 @@
+import re, unicodedata, sys
+
+if sys.maxunicode == 65535:
+    raise RuntimeError, "need UCS-4 Python"
+
+def gen_category(cats):
+    for i in range(0, 0x110000):
+        if unicodedata.category(unichr(i)) in cats:
+            yield(i)
+
+def gen_bidirectional(cats):
+    for i in range(0, 0x110000):
+        if unicodedata.bidirectional(unichr(i)) in cats:
+            yield(i)
+
+def compact_set(l):
+    single = []
+    tuple = []
+    prev = None
+    span = 0
+    for e in l:
+        if prev is None:
+            prev = e
+            span = 0
+            continue
+        if prev+span+1 != e:
+            if span > 2:
+                tuple.append((prev,prev+span+1))
+            else:
+                for i in range(prev, prev+span+1):
+                    single.append(i)
+            prev = e
+            span = 0
+        else:
+            span += 1
+    if span:
+        tuple.append((prev,prev+span+1))
+    else:
+        single.append(prev)
+    tuple = " + ".join(["range(%d,%d)" % t for t in tuple])
+    if not single:
+        return "set(%s)" % tuple
+    if not tuple:
+        return "set(%s)" % repr(single)
+    return "set(%s + %s)" % (repr(single),tuple)
+
+############## Read the tables in the RFC #######################
+
+data = open("rfc3454.txt").readlines()
+
+tables = []
+curname = None
+for l in data:
+    l = l.strip()
+    if not l:
+        continue
+    # Skip RFC page breaks
+    if l.startswith("Hoffman & Blanchet") or\
+       l.startswith("RFC 3454"):
+        continue
+    # Find start/end lines
+    m = re.match("----- (Start|End) Table ([A-Z](.[0-9])+) -----", l)
+    if m:
+        if m.group(1) == "Start":
+            if curname:
+                raise "Double Start",(curname, l)
+            curname = m.group(2)
+            table = {}
+            tables.append((curname, table))
+            continue
+        else:
+            if not curname:
+                raise "End without start", l
+            curname = None
+            continue
+    if not curname:
+        continue
+    # Now we are in a table
+    fields = l.split(";")
+    if len(fields) > 1:
+        # Drop comment field
+        fields = fields[:-1]
+    if len(fields) == 1:
+        fields = fields[0].split("-")
+        if len(fields) > 1:
+            # range
+            try:
+                start, end = fields
+            except ValueError:
+                raise "Unpacking problem", l
+        else:
+            start = end = fields[0]
+        start = int(start, 16)
+        end = int(end, 16)
+        for i in range(start, end+1):
+            table[i] = i
+    else:
+        code, value = fields
+        value = value.strip()
+        if value:
+            value = [int(v, 16) for v in value.split(" ")]
+        else:
+            # table B.1
+            value = None
+        table[int(code, 16)] = value
+
+########### Generate compact Python versions of the tables #############
+
+print """# This file is generated by mkstringprep.py. DO NOT EDIT.
+\"\"\"Library that exposes various tables found in the StringPrep RFC 3454.
+
+There are two kinds of tables: sets, for which a member test is provided,
+and mappings, for which a mapping function is provided.
+\"\"\"
+
+import unicodedata
+"""
+
+print "assert unicodedata.unidata_version == %s" % repr(unicodedata.unidata_version)
+
+# A.1 is the table of unassigned characters
+# XXX Plane 15 PUA is listed as unassigned in Python.
+name, table = tables[0]
+del tables[0]
+assert name == "A.1"
+table = set(table.keys())
+Cn = set(gen_category(["Cn"]))
+
+# FDD0..FDEF are process internal codes
+Cn -= set(range(0xFDD0, 0xFDF0))
+# not a character
+Cn -= set(range(0xFFFE, 0x110000, 0x10000))
+Cn -= set(range(0xFFFF, 0x110000, 0x10000))
+
+# assert table == Cn
+
+print """
+def in_table_a1(code):
+    if unicodedata.category(code) != 'Cn': return False
+    c = ord(code)
+    if 0xFDD0 <= c < 0xFDF0: return False
+    return (c & 0xFFFF) not in (0xFFFE, 0xFFFF)
+"""
+
+# B.1 cannot easily be derived
+name, table = tables[0]
+del tables[0]
+assert name == "B.1"
+table = table.keys()
+table.sort()
+print """
+b1_set = """ + compact_set(table) + """
+def in_table_b1(code):
+    return ord(code) in b1_set
+"""
+
+# B.2 and B.3 is case folding.
+# It takes CaseFolding.txt into account, which is
+# not available in the Python database. Since
+# B.2 is derived from B.3, we process B.3 first.
+# B.3 supposedly *is* CaseFolding-3.2.0.txt.
+
+name, table_b2 = tables[0]
+del tables[0]
+assert name == "B.2"
+
+name, table_b3 = tables[0]
+del tables[0]
+assert name == "B.3"
+
+# B.3 is mostly Python's .lower, except for a number
+# of special cases, e.g. considering canonical forms.
+
+b3_exceptions = {}
+
+for k,v in table_b2.items():
+    if map(ord, unichr(k).lower()) != v:
+        b3_exceptions[k] = u"".join(map(unichr,v))
+
+b3 = b3_exceptions.items()
+b3.sort()
+
+print """
+b3_exceptions = {"""
+for i,(k,v) in enumerate(b3):
+    print "0x%x:%s," % (k, repr(v)),
+    if i % 4 == 3:
+        print
+print "}"
+
+print """
+def map_table_b3(code):
+    r = b3_exceptions.get(ord(code))
+    if r is not None: return r
+    return code.lower()
+"""
+
+def map_table_b3(code):
+    r = b3_exceptions.get(ord(code))
+    if r is not None: return r
+    return code.lower()
+
+# B.2 is case folding for NFKC. This is the same as B.3,
+# except where NormalizeWithKC(Fold(a)) !=
+# NormalizeWithKC(Fold(NormalizeWithKC(Fold(a))))
+
+def map_table_b2(a):
+    al = map_table_b3(a)
+    b = unicodedata.normalize("NFKC", al)
+    bl = u"".join([map_table_b3(ch) for ch in b])
+    c = unicodedata.normalize("NFKC", bl)
+    if b != c:
+        return c
+    else:
+        return al
+
+specials = {}
+for k,v in table_b2.items():
+    if map(ord, map_table_b2(unichr(k))) != v:
+        specials[k] = v
+
+# B.3 should not add any additional special cases
+assert specials == {}
+
+print """
+def map_table_b2(a):
+    al = map_table_b3(a)
+    b = unicodedata.normalize("NFKC", al)
+    bl = u"".join([map_table_b3(ch) for ch in b])
+    c = unicodedata.normalize("NFKC", bl)
+    if b != c:
+        return c
+    else:
+        return al
+"""
+
+# C.1.1 is a table with a single character
+name, table = tables[0]
+del tables[0]
+assert name == "C.1.1"
+assert table == {0x20:0x20}
+
+print """
+def in_table_c11(code):
+    return code == u" "
+"""
+
+# C.1.2 is the rest of all space characters
+name, table = tables[0]
+del tables[0]
+assert name == "C.1.2"
+
+# table = set(table.keys())
+# Zs = set(gen_category(["Zs"])) - set([0x20])
+# assert Zs == table
+
+print """
+def in_table_c12(code):
+    return unicodedata.category(code) == "Zs" and code != u" "
+
+def in_table_c11_c12(code):
+    return unicodedata.category(code) == "Zs"
+"""
+
+# C.2.1 ASCII control characters
+name, table_c21 = tables[0]
+del tables[0]
+assert name == "C.2.1"
+
+Cc = set(gen_category(["Cc"]))
+Cc_ascii = Cc & set(range(128))
+table_c21 = set(table_c21.keys())
+assert Cc_ascii == table_c21
+
+print """
+def in_table_c21(code):
+    return ord(code) < 128 and unicodedata.category(code) == "Cc"
+"""
+
+# C.2.2 Non-ASCII control characters. It also includes
+# a number of characters in category Cf.
+name, table_c22 = tables[0]
+del tables[0]
+assert name == "C.2.2"
+
+Cc_nonascii = Cc - Cc_ascii
+table_c22 = set(table_c22.keys())
+assert len(Cc_nonascii - table_c22) == 0
+
+specials = list(table_c22 - Cc_nonascii)
+specials.sort()
+
+print """c22_specials = """ + compact_set(specials) + """
+def in_table_c22(code):
+    c = ord(code)
+    if c < 128: return False
+    if unicodedata.category(code) == "Cc": return True
+    return c in c22_specials
+
+def in_table_c21_c22(code):
+    return unicodedata.category(code) == "Cc" or \\
+           ord(code) in c22_specials
+"""
+
+# C.3 Private use
+name, table = tables[0]
+del tables[0]
+assert name == "C.3"
+
+Co = set(gen_category(["Co"]))
+assert set(table.keys()) == Co
+
+print """
+def in_table_c3(code):
+    return unicodedata.category(code) == "Co"
+"""
+
+# C.4 Non-character code points, xFFFE, xFFFF
+# plus process internal codes
+name, table = tables[0]
+del tables[0]
+assert name == "C.4"
+
+nonchar = set(range(0xFDD0,0xFDF0) +
+              range(0xFFFE,0x110000,0x10000) +
+              range(0xFFFF,0x110000,0x10000))
+table = set(table.keys())
+assert table == nonchar
+
+print """
+def in_table_c4(code):
+    c = ord(code)
+    if c < 0xFDD0: return False
+    if c < 0xFDF0: return True
+    return (ord(code) & 0xFFFF) in (0xFFFE, 0xFFFF)
+"""
+
+# C.5 Surrogate codes
+name, table = tables[0]
+del tables[0]
+assert name == "C.5"
+
+Cs = set(gen_category(["Cs"]))
+assert set(table.keys()) == Cs
+
+print """
+def in_table_c5(code):
+    return unicodedata.category(code) == "Cs"
+"""
+
+# C.6 Inappropriate for plain text
+name, table = tables[0]
+del tables[0]
+assert name == "C.6"
+
+table = table.keys()
+table.sort()
+
+print """
+c6_set = """ + compact_set(table) + """
+def in_table_c6(code):
+    return ord(code) in c6_set
+"""
+
+# C.7 Inappropriate for canonical representation
+name, table = tables[0]
+del tables[0]
+assert name == "C.7"
+
+table = table.keys()
+table.sort()
+
+print """
+c7_set = """ + compact_set(table) + """
+def in_table_c7(code):
+    return ord(code) in c7_set
+"""
+
+# C.8 Change display properties or are deprecated
+name, table = tables[0]
+del tables[0]
+assert name == "C.8"
+
+table = table.keys()
+table.sort()
+
+print """
+c8_set = """ + compact_set(table) + """
+def in_table_c8(code):
+    return ord(code) in c8_set
+"""
+
+# C.9 Tagging characters
+name, table = tables[0]
+del tables[0]
+assert name == "C.9"
+
+table = table.keys()
+table.sort()
+
+print """
+c9_set = """ + compact_set(table) + """
+def in_table_c9(code):
+    return ord(code) in c9_set
+"""
+
+# D.1 Characters with bidirectional property "R" or "AL"
+name, table = tables[0]
+del tables[0]
+assert name == "D.1"
+
+RandAL = set(gen_bidirectional(["R","AL"]))
+assert set(table.keys()) == RandAL
+
+print """
+def in_table_d1(code):
+    return unicodedata.bidirectional(code) in ("R","AL")
+"""
+
+# D.2 Characters with bidirectional property "L"
+name, table = tables[0]
+del tables[0]
+assert name == "D.2"
+
+L = set(gen_bidirectional(["L"]))
+assert set(table.keys()) == L
+
+print """
+def in_table_d2(code):
+    return unicodedata.bidirectional(code) == "L"
+"""

Added: vendor/Python/current/Tools/unicode/python-mappings/CP1140.TXT
===================================================================
--- vendor/Python/current/Tools/unicode/python-mappings/CP1140.TXT	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/unicode/python-mappings/CP1140.TXT	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,291 @@
+#
+#       Name:             CP1140
+#	Unicode version:  3.2
+#	Table version:    1.0
+#	Table format:     Format A
+#	Date:             2005-10-25
+#	Authors:          Marc-Andre Lemburg <mal at egenix.com>
+#
+#       This encoding is a modified CP037 encoding (with added Euro
+#       currency sign).
+#
+#       (c) Copyright Marc-Andre Lemburg, 2005.
+#           Licensed to PSF under a Contributor Agreement.
+#
+#       Based on the file 
+#       ftp://ftp.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/EBCDIC/CP037.TXT
+#       which is:
+#
+#	Copyright (c) 2002 Unicode, Inc.  All Rights reserved.
+#
+#	This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
+#	No claims are made as to fitness for any particular purpose.  No
+#	warranties of any kind are expressed or implied.  The recipient
+#	agrees to determine applicability of information provided.  If this
+#	file has been provided on optical media by Unicode, Inc., the sole
+#	remedy for any claim will be exchange of defective media within 90
+#	days of receipt.
+#
+#	Unicode, Inc. hereby grants the right to freely use the information
+#	supplied in this file in the creation of products supporting the
+#	Unicode Standard, and to make copies of this file in any form for
+#	internal or external distribution as long as this notice remains
+#	attached.
+#
+0x00	0x0000	#NULL
+0x01	0x0001	#START OF HEADING
+0x02	0x0002	#START OF TEXT
+0x03	0x0003	#END OF TEXT
+0x04	0x009C	#CONTROL
+0x05	0x0009	#HORIZONTAL TABULATION
+0x06	0x0086	#CONTROL
+0x07	0x007F	#DELETE
+0x08	0x0097	#CONTROL
+0x09	0x008D	#CONTROL
+0x0A	0x008E	#CONTROL
+0x0B	0x000B	#VERTICAL TABULATION
+0x0C	0x000C	#FORM FEED
+0x0D	0x000D	#CARRIAGE RETURN
+0x0E	0x000E	#SHIFT OUT
+0x0F	0x000F	#SHIFT IN
+0x10	0x0010	#DATA LINK ESCAPE
+0x11	0x0011	#DEVICE CONTROL ONE
+0x12	0x0012	#DEVICE CONTROL TWO
+0x13	0x0013	#DEVICE CONTROL THREE
+0x14	0x009D	#CONTROL
+0x15	0x0085	#CONTROL
+0x16	0x0008	#BACKSPACE
+0x17	0x0087	#CONTROL
+0x18	0x0018	#CANCEL
+0x19	0x0019	#END OF MEDIUM
+0x1A	0x0092	#CONTROL
+0x1B	0x008F	#CONTROL
+0x1C	0x001C	#FILE SEPARATOR
+0x1D	0x001D	#GROUP SEPARATOR
+0x1E	0x001E	#RECORD SEPARATOR
+0x1F	0x001F	#UNIT SEPARATOR
+0x20	0x0080	#CONTROL
+0x21	0x0081	#CONTROL
+0x22	0x0082	#CONTROL
+0x23	0x0083	#CONTROL
+0x24	0x0084	#CONTROL
+0x25	0x000A	#LINE FEED
+0x26	0x0017	#END OF TRANSMISSION BLOCK
+0x27	0x001B	#ESCAPE
+0x28	0x0088	#CONTROL
+0x29	0x0089	#CONTROL
+0x2A	0x008A	#CONTROL
+0x2B	0x008B	#CONTROL
+0x2C	0x008C	#CONTROL
+0x2D	0x0005	#ENQUIRY
+0x2E	0x0006	#ACKNOWLEDGE
+0x2F	0x0007	#BELL
+0x30	0x0090	#CONTROL
+0x31	0x0091	#CONTROL
+0x32	0x0016	#SYNCHRONOUS IDLE
+0x33	0x0093	#CONTROL
+0x34	0x0094	#CONTROL
+0x35	0x0095	#CONTROL
+0x36	0x0096	#CONTROL
+0x37	0x0004	#END OF TRANSMISSION
+0x38	0x0098	#CONTROL
+0x39	0x0099	#CONTROL
+0x3A	0x009A	#CONTROL
+0x3B	0x009B	#CONTROL
+0x3C	0x0014	#DEVICE CONTROL FOUR
+0x3D	0x0015	#NEGATIVE ACKNOWLEDGE
+0x3E	0x009E	#CONTROL
+0x3F	0x001A	#SUBSTITUTE
+0x40	0x0020	#SPACE
+0x41	0x00A0	#NO-BREAK SPACE
+0x42	0x00E2	#LATIN SMALL LETTER A WITH CIRCUMFLEX
+0x43	0x00E4	#LATIN SMALL LETTER A WITH DIAERESIS
+0x44	0x00E0	#LATIN SMALL LETTER A WITH GRAVE
+0x45	0x00E1	#LATIN SMALL LETTER A WITH ACUTE
+0x46	0x00E3	#LATIN SMALL LETTER A WITH TILDE
+0x47	0x00E5	#LATIN SMALL LETTER A WITH RING ABOVE
+0x48	0x00E7	#LATIN SMALL LETTER C WITH CEDILLA
+0x49	0x00F1	#LATIN SMALL LETTER N WITH TILDE
+0x4A	0x00A2	#CENT SIGN
+0x4B	0x002E	#FULL STOP
+0x4C	0x003C	#LESS-THAN SIGN
+0x4D	0x0028	#LEFT PARENTHESIS
+0x4E	0x002B	#PLUS SIGN
+0x4F	0x007C	#VERTICAL LINE
+0x50	0x0026	#AMPERSAND
+0x51	0x00E9	#LATIN SMALL LETTER E WITH ACUTE
+0x52	0x00EA	#LATIN SMALL LETTER E WITH CIRCUMFLEX
+0x53	0x00EB	#LATIN SMALL LETTER E WITH DIAERESIS
+0x54	0x00E8	#LATIN SMALL LETTER E WITH GRAVE
+0x55	0x00ED	#LATIN SMALL LETTER I WITH ACUTE
+0x56	0x00EE	#LATIN SMALL LETTER I WITH CIRCUMFLEX
+0x57	0x00EF	#LATIN SMALL LETTER I WITH DIAERESIS
+0x58	0x00EC	#LATIN SMALL LETTER I WITH GRAVE
+0x59	0x00DF	#LATIN SMALL LETTER SHARP S (GERMAN)
+0x5A	0x0021	#EXCLAMATION MARK
+0x5B	0x0024	#DOLLAR SIGN
+0x5C	0x002A	#ASTERISK
+0x5D	0x0029	#RIGHT PARENTHESIS
+0x5E	0x003B	#SEMICOLON
+0x5F	0x00AC	#NOT SIGN
+0x60	0x002D	#HYPHEN-MINUS
+0x61	0x002F	#SOLIDUS
+0x62	0x00C2	#LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+0x63	0x00C4	#LATIN CAPITAL LETTER A WITH DIAERESIS
+0x64	0x00C0	#LATIN CAPITAL LETTER A WITH GRAVE
+0x65	0x00C1	#LATIN CAPITAL LETTER A WITH ACUTE
+0x66	0x00C3	#LATIN CAPITAL LETTER A WITH TILDE
+0x67	0x00C5	#LATIN CAPITAL LETTER A WITH RING ABOVE
+0x68	0x00C7	#LATIN CAPITAL LETTER C WITH CEDILLA
+0x69	0x00D1	#LATIN CAPITAL LETTER N WITH TILDE
+0x6A	0x00A6	#BROKEN BAR
+0x6B	0x002C	#COMMA
+0x6C	0x0025	#PERCENT SIGN
+0x6D	0x005F	#LOW LINE
+0x6E	0x003E	#GREATER-THAN SIGN
+0x6F	0x003F	#QUESTION MARK
+0x70	0x00F8	#LATIN SMALL LETTER O WITH STROKE
+0x71	0x00C9	#LATIN CAPITAL LETTER E WITH ACUTE
+0x72	0x00CA	#LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+0x73	0x00CB	#LATIN CAPITAL LETTER E WITH DIAERESIS
+0x74	0x00C8	#LATIN CAPITAL LETTER E WITH GRAVE
+0x75	0x00CD	#LATIN CAPITAL LETTER I WITH ACUTE
+0x76	0x00CE	#LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+0x77	0x00CF	#LATIN CAPITAL LETTER I WITH DIAERESIS
+0x78	0x00CC	#LATIN CAPITAL LETTER I WITH GRAVE
+0x79	0x0060	#GRAVE ACCENT
+0x7A	0x003A	#COLON
+0x7B	0x0023	#NUMBER SIGN
+0x7C	0x0040	#COMMERCIAL AT
+0x7D	0x0027	#APOSTROPHE
+0x7E	0x003D	#EQUALS SIGN
+0x7F	0x0022	#QUOTATION MARK
+0x80	0x00D8	#LATIN CAPITAL LETTER O WITH STROKE
+0x81	0x0061	#LATIN SMALL LETTER A
+0x82	0x0062	#LATIN SMALL LETTER B
+0x83	0x0063	#LATIN SMALL LETTER C
+0x84	0x0064	#LATIN SMALL LETTER D
+0x85	0x0065	#LATIN SMALL LETTER E
+0x86	0x0066	#LATIN SMALL LETTER F
+0x87	0x0067	#LATIN SMALL LETTER G
+0x88	0x0068	#LATIN SMALL LETTER H
+0x89	0x0069	#LATIN SMALL LETTER I
+0x8A	0x00AB	#LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+0x8B	0x00BB	#RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+0x8C	0x00F0	#LATIN SMALL LETTER ETH (ICELANDIC)
+0x8D	0x00FD	#LATIN SMALL LETTER Y WITH ACUTE
+0x8E	0x00FE	#LATIN SMALL LETTER THORN (ICELANDIC)
+0x8F	0x00B1	#PLUS-MINUS SIGN
+0x90	0x00B0	#DEGREE SIGN
+0x91	0x006A	#LATIN SMALL LETTER J
+0x92	0x006B	#LATIN SMALL LETTER K
+0x93	0x006C	#LATIN SMALL LETTER L
+0x94	0x006D	#LATIN SMALL LETTER M
+0x95	0x006E	#LATIN SMALL LETTER N
+0x96	0x006F	#LATIN SMALL LETTER O
+0x97	0x0070	#LATIN SMALL LETTER P
+0x98	0x0071	#LATIN SMALL LETTER Q
+0x99	0x0072	#LATIN SMALL LETTER R
+0x9A	0x00AA	#FEMININE ORDINAL INDICATOR
+0x9B	0x00BA	#MASCULINE ORDINAL INDICATOR
+0x9C	0x00E6	#LATIN SMALL LIGATURE AE
+0x9D	0x00B8	#CEDILLA
+0x9E	0x00C6	#LATIN CAPITAL LIGATURE AE
+#0x9F	0x00A4	#CURRENCY SIGN
+0x9F    0x20AC   # EURO SIGN
+0xA0	0x00B5	#MICRO SIGN
+0xA1	0x007E	#TILDE
+0xA2	0x0073	#LATIN SMALL LETTER S
+0xA3	0x0074	#LATIN SMALL LETTER T
+0xA4	0x0075	#LATIN SMALL LETTER U
+0xA5	0x0076	#LATIN SMALL LETTER V
+0xA6	0x0077	#LATIN SMALL LETTER W
+0xA7	0x0078	#LATIN SMALL LETTER X
+0xA8	0x0079	#LATIN SMALL LETTER Y
+0xA9	0x007A	#LATIN SMALL LETTER Z
+0xAA	0x00A1	#INVERTED EXCLAMATION MARK
+0xAB	0x00BF	#INVERTED QUESTION MARK
+0xAC	0x00D0	#LATIN CAPITAL LETTER ETH (ICELANDIC)
+0xAD	0x00DD	#LATIN CAPITAL LETTER Y WITH ACUTE
+0xAE	0x00DE	#LATIN CAPITAL LETTER THORN (ICELANDIC)
+0xAF	0x00AE	#REGISTERED SIGN
+0xB0	0x005E	#CIRCUMFLEX ACCENT
+0xB1	0x00A3	#POUND SIGN
+0xB2	0x00A5	#YEN SIGN
+0xB3	0x00B7	#MIDDLE DOT
+0xB4	0x00A9	#COPYRIGHT SIGN
+0xB5	0x00A7	#SECTION SIGN
+0xB6	0x00B6	#PILCROW SIGN
+0xB7	0x00BC	#VULGAR FRACTION ONE QUARTER
+0xB8	0x00BD	#VULGAR FRACTION ONE HALF
+0xB9	0x00BE	#VULGAR FRACTION THREE QUARTERS
+0xBA	0x005B	#LEFT SQUARE BRACKET
+0xBB	0x005D	#RIGHT SQUARE BRACKET
+0xBC	0x00AF	#MACRON
+0xBD	0x00A8	#DIAERESIS
+0xBE	0x00B4	#ACUTE ACCENT
+0xBF	0x00D7	#MULTIPLICATION SIGN
+0xC0	0x007B	#LEFT CURLY BRACKET
+0xC1	0x0041	#LATIN CAPITAL LETTER A
+0xC2	0x0042	#LATIN CAPITAL LETTER B
+0xC3	0x0043	#LATIN CAPITAL LETTER C
+0xC4	0x0044	#LATIN CAPITAL LETTER D
+0xC5	0x0045	#LATIN CAPITAL LETTER E
+0xC6	0x0046	#LATIN CAPITAL LETTER F
+0xC7	0x0047	#LATIN CAPITAL LETTER G
+0xC8	0x0048	#LATIN CAPITAL LETTER H
+0xC9	0x0049	#LATIN CAPITAL LETTER I
+0xCA	0x00AD	#SOFT HYPHEN
+0xCB	0x00F4	#LATIN SMALL LETTER O WITH CIRCUMFLEX
+0xCC	0x00F6	#LATIN SMALL LETTER O WITH DIAERESIS
+0xCD	0x00F2	#LATIN SMALL LETTER O WITH GRAVE
+0xCE	0x00F3	#LATIN SMALL LETTER O WITH ACUTE
+0xCF	0x00F5	#LATIN SMALL LETTER O WITH TILDE
+0xD0	0x007D	#RIGHT CURLY BRACKET
+0xD1	0x004A	#LATIN CAPITAL LETTER J
+0xD2	0x004B	#LATIN CAPITAL LETTER K
+0xD3	0x004C	#LATIN CAPITAL LETTER L
+0xD4	0x004D	#LATIN CAPITAL LETTER M
+0xD5	0x004E	#LATIN CAPITAL LETTER N
+0xD6	0x004F	#LATIN CAPITAL LETTER O
+0xD7	0x0050	#LATIN CAPITAL LETTER P
+0xD8	0x0051	#LATIN CAPITAL LETTER Q
+0xD9	0x0052	#LATIN CAPITAL LETTER R
+0xDA	0x00B9	#SUPERSCRIPT ONE
+0xDB	0x00FB	#LATIN SMALL LETTER U WITH CIRCUMFLEX
+0xDC	0x00FC	#LATIN SMALL LETTER U WITH DIAERESIS
+0xDD	0x00F9	#LATIN SMALL LETTER U WITH GRAVE
+0xDE	0x00FA	#LATIN SMALL LETTER U WITH ACUTE
+0xDF	0x00FF	#LATIN SMALL LETTER Y WITH DIAERESIS
+0xE0	0x005C	#REVERSE SOLIDUS
+0xE1	0x00F7	#DIVISION SIGN
+0xE2	0x0053	#LATIN CAPITAL LETTER S
+0xE3	0x0054	#LATIN CAPITAL LETTER T
+0xE4	0x0055	#LATIN CAPITAL LETTER U
+0xE5	0x0056	#LATIN CAPITAL LETTER V
+0xE6	0x0057	#LATIN CAPITAL LETTER W
+0xE7	0x0058	#LATIN CAPITAL LETTER X
+0xE8	0x0059	#LATIN CAPITAL LETTER Y
+0xE9	0x005A	#LATIN CAPITAL LETTER Z
+0xEA	0x00B2	#SUPERSCRIPT TWO
+0xEB	0x00D4	#LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+0xEC	0x00D6	#LATIN CAPITAL LETTER O WITH DIAERESIS
+0xED	0x00D2	#LATIN CAPITAL LETTER O WITH GRAVE
+0xEE	0x00D3	#LATIN CAPITAL LETTER O WITH ACUTE
+0xEF	0x00D5	#LATIN CAPITAL LETTER O WITH TILDE
+0xF0	0x0030	#DIGIT ZERO
+0xF1	0x0031	#DIGIT ONE
+0xF2	0x0032	#DIGIT TWO
+0xF3	0x0033	#DIGIT THREE
+0xF4	0x0034	#DIGIT FOUR
+0xF5	0x0035	#DIGIT FIVE
+0xF6	0x0036	#DIGIT SIX
+0xF7	0x0037	#DIGIT SEVEN
+0xF8	0x0038	#DIGIT EIGHT
+0xF9	0x0039	#DIGIT NINE
+0xFA	0x00B3	#SUPERSCRIPT THREE
+0xFB	0x00DB	#LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+0xFC	0x00DC	#LATIN CAPITAL LETTER U WITH DIAERESIS
+0xFD	0x00D9	#LATIN CAPITAL LETTER U WITH GRAVE
+0xFE	0x00DA	#LATIN CAPITAL LETTER U WITH ACUTE
+0xFF	0x009F	#CONTROL

Added: vendor/Python/current/Tools/unicode/python-mappings/KOI8-U.TXT
===================================================================
--- vendor/Python/current/Tools/unicode/python-mappings/KOI8-U.TXT	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/unicode/python-mappings/KOI8-U.TXT	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,298 @@
+#
+#	Name:             KOI8-U (RFC2319) to Unicode
+#	Unicode version:  3.2
+#	Table version:    1.0
+#	Table format:     Format A
+#	Date:             2005-10-25
+#	Authors:          Marc-Andre Lemburg <mal at egenix.com>
+#
+#       See RFC2319 for details. This encoding is a modified KOI8-R
+#       encoding.
+#
+#       (c) Copyright Marc-Andre Lemburg, 2005.
+#           Licensed to PSF under a Contributor Agreement.
+#
+#       Based on the file 
+#       ftp://ftp.unicode.org/Public/MAPPINGS/VENDORS/MISC/KOI8-R.TXT
+#       which is:
+#
+#	Copyright (c) 1991-1999 Unicode, Inc.  All Rights reserved.
+#
+#	This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
+#	No claims are made as to fitness for any particular purpose.  No
+#	warranties of any kind are expressed or implied.  The recipient
+#	agrees to determine applicability of information provided.  If this
+#	file has been provided on optical media by Unicode, Inc., the sole
+#	remedy for any claim will be exchange of defective media within 90
+#	days of receipt.
+#
+#	Unicode, Inc. hereby grants the right to freely use the information
+#	supplied in this file in the creation of products supporting the
+#	Unicode Standard, and to make copies of this file in any form for
+#	internal or external distribution as long as this notice remains
+#	attached.
+#
+0x00	0x0000	#	NULL
+0x01	0x0001	#	START OF HEADING
+0x02	0x0002	#	START OF TEXT
+0x03	0x0003	#	END OF TEXT
+0x04	0x0004	#	END OF TRANSMISSION
+0x05	0x0005	#	ENQUIRY
+0x06	0x0006	#	ACKNOWLEDGE
+0x07	0x0007	#	BELL
+0x08	0x0008	#	BACKSPACE
+0x09	0x0009	#	HORIZONTAL TABULATION
+0x0A	0x000A	#	LINE FEED
+0x0B	0x000B	#	VERTICAL TABULATION
+0x0C	0x000C	#	FORM FEED
+0x0D	0x000D	#	CARRIAGE RETURN
+0x0E	0x000E	#	SHIFT OUT
+0x0F	0x000F	#	SHIFT IN
+0x10	0x0010	#	DATA LINK ESCAPE
+0x11	0x0011	#	DEVICE CONTROL ONE
+0x12	0x0012	#	DEVICE CONTROL TWO
+0x13	0x0013	#	DEVICE CONTROL THREE
+0x14	0x0014	#	DEVICE CONTROL FOUR
+0x15	0x0015	#	NEGATIVE ACKNOWLEDGE
+0x16	0x0016	#	SYNCHRONOUS IDLE
+0x17	0x0017	#	END OF TRANSMISSION BLOCK
+0x18	0x0018	#	CANCEL
+0x19	0x0019	#	END OF MEDIUM
+0x1A	0x001A	#	SUBSTITUTE
+0x1B	0x001B	#	ESCAPE
+0x1C	0x001C	#	FILE SEPARATOR
+0x1D	0x001D	#	GROUP SEPARATOR
+0x1E	0x001E	#	RECORD SEPARATOR
+0x1F	0x001F	#	UNIT SEPARATOR
+0x20	0x0020	#	SPACE
+0x21	0x0021	#	EXCLAMATION MARK
+0x22	0x0022	#	QUOTATION MARK
+0x23	0x0023	#	NUMBER SIGN
+0x24	0x0024	#	DOLLAR SIGN
+0x25	0x0025	#	PERCENT SIGN
+0x26	0x0026	#	AMPERSAND
+0x27	0x0027	#	APOSTROPHE
+0x28	0x0028	#	LEFT PARENTHESIS
+0x29	0x0029	#	RIGHT PARENTHESIS
+0x2A	0x002A	#	ASTERISK
+0x2B	0x002B	#	PLUS SIGN
+0x2C	0x002C	#	COMMA
+0x2D	0x002D	#	HYPHEN-MINUS
+0x2E	0x002E	#	FULL STOP
+0x2F	0x002F	#	SOLIDUS
+0x30	0x0030	#	DIGIT ZERO
+0x31	0x0031	#	DIGIT ONE
+0x32	0x0032	#	DIGIT TWO
+0x33	0x0033	#	DIGIT THREE
+0x34	0x0034	#	DIGIT FOUR
+0x35	0x0035	#	DIGIT FIVE
+0x36	0x0036	#	DIGIT SIX
+0x37	0x0037	#	DIGIT SEVEN
+0x38	0x0038	#	DIGIT EIGHT
+0x39	0x0039	#	DIGIT NINE
+0x3A	0x003A	#	COLON
+0x3B	0x003B	#	SEMICOLON
+0x3C	0x003C	#	LESS-THAN SIGN
+0x3D	0x003D	#	EQUALS SIGN
+0x3E	0x003E	#	GREATER-THAN SIGN
+0x3F	0x003F	#	QUESTION MARK
+0x40	0x0040	#	COMMERCIAL AT
+0x41	0x0041	#	LATIN CAPITAL LETTER A
+0x42	0x0042	#	LATIN CAPITAL LETTER B
+0x43	0x0043	#	LATIN CAPITAL LETTER C
+0x44	0x0044	#	LATIN CAPITAL LETTER D
+0x45	0x0045	#	LATIN CAPITAL LETTER E
+0x46	0x0046	#	LATIN CAPITAL LETTER F
+0x47	0x0047	#	LATIN CAPITAL LETTER G
+0x48	0x0048	#	LATIN CAPITAL LETTER H
+0x49	0x0049	#	LATIN CAPITAL LETTER I
+0x4A	0x004A	#	LATIN CAPITAL LETTER J
+0x4B	0x004B	#	LATIN CAPITAL LETTER K
+0x4C	0x004C	#	LATIN CAPITAL LETTER L
+0x4D	0x004D	#	LATIN CAPITAL LETTER M
+0x4E	0x004E	#	LATIN CAPITAL LETTER N
+0x4F	0x004F	#	LATIN CAPITAL LETTER O
+0x50	0x0050	#	LATIN CAPITAL LETTER P
+0x51	0x0051	#	LATIN CAPITAL LETTER Q
+0x52	0x0052	#	LATIN CAPITAL LETTER R
+0x53	0x0053	#	LATIN CAPITAL LETTER S
+0x54	0x0054	#	LATIN CAPITAL LETTER T
+0x55	0x0055	#	LATIN CAPITAL LETTER U
+0x56	0x0056	#	LATIN CAPITAL LETTER V
+0x57	0x0057	#	LATIN CAPITAL LETTER W
+0x58	0x0058	#	LATIN CAPITAL LETTER X
+0x59	0x0059	#	LATIN CAPITAL LETTER Y
+0x5A	0x005A	#	LATIN CAPITAL LETTER Z
+0x5B	0x005B	#	LEFT SQUARE BRACKET
+0x5C	0x005C	#	REVERSE SOLIDUS
+0x5D	0x005D	#	RIGHT SQUARE BRACKET
+0x5E	0x005E	#	CIRCUMFLEX ACCENT
+0x5F	0x005F	#	LOW LINE
+0x60	0x0060	#	GRAVE ACCENT
+0x61	0x0061	#	LATIN SMALL LETTER A
+0x62	0x0062	#	LATIN SMALL LETTER B
+0x63	0x0063	#	LATIN SMALL LETTER C
+0x64	0x0064	#	LATIN SMALL LETTER D
+0x65	0x0065	#	LATIN SMALL LETTER E
+0x66	0x0066	#	LATIN SMALL LETTER F
+0x67	0x0067	#	LATIN SMALL LETTER G
+0x68	0x0068	#	LATIN SMALL LETTER H
+0x69	0x0069	#	LATIN SMALL LETTER I
+0x6A	0x006A	#	LATIN SMALL LETTER J
+0x6B	0x006B	#	LATIN SMALL LETTER K
+0x6C	0x006C	#	LATIN SMALL LETTER L
+0x6D	0x006D	#	LATIN SMALL LETTER M
+0x6E	0x006E	#	LATIN SMALL LETTER N
+0x6F	0x006F	#	LATIN SMALL LETTER O
+0x70	0x0070	#	LATIN SMALL LETTER P
+0x71	0x0071	#	LATIN SMALL LETTER Q
+0x72	0x0072	#	LATIN SMALL LETTER R
+0x73	0x0073	#	LATIN SMALL LETTER S
+0x74	0x0074	#	LATIN SMALL LETTER T
+0x75	0x0075	#	LATIN SMALL LETTER U
+0x76	0x0076	#	LATIN SMALL LETTER V
+0x77	0x0077	#	LATIN SMALL LETTER W
+0x78	0x0078	#	LATIN SMALL LETTER X
+0x79	0x0079	#	LATIN SMALL LETTER Y
+0x7A	0x007A	#	LATIN SMALL LETTER Z
+0x7B	0x007B	#	LEFT CURLY BRACKET
+0x7C	0x007C	#	VERTICAL LINE
+0x7D	0x007D	#	RIGHT CURLY BRACKET
+0x7E	0x007E	#	TILDE
+0x7F	0x007F	#	DELETE
+0x80	0x2500	#	BOX DRAWINGS LIGHT HORIZONTAL
+0x81	0x2502	#	BOX DRAWINGS LIGHT VERTICAL
+0x82	0x250C	#	BOX DRAWINGS LIGHT DOWN AND RIGHT
+0x83	0x2510	#	BOX DRAWINGS LIGHT DOWN AND LEFT
+0x84	0x2514	#	BOX DRAWINGS LIGHT UP AND RIGHT
+0x85	0x2518	#	BOX DRAWINGS LIGHT UP AND LEFT
+0x86	0x251C	#	BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+0x87	0x2524	#	BOX DRAWINGS LIGHT VERTICAL AND LEFT
+0x88	0x252C	#	BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+0x89	0x2534	#	BOX DRAWINGS LIGHT UP AND HORIZONTAL
+0x8A	0x253C	#	BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+0x8B	0x2580	#	UPPER HALF BLOCK
+0x8C	0x2584	#	LOWER HALF BLOCK
+0x8D	0x2588	#	FULL BLOCK
+0x8E	0x258C	#	LEFT HALF BLOCK
+0x8F	0x2590	#	RIGHT HALF BLOCK
+0x90	0x2591	#	LIGHT SHADE
+0x91	0x2592	#	MEDIUM SHADE
+0x92	0x2593	#	DARK SHADE
+0x93	0x2320	#	TOP HALF INTEGRAL
+0x94	0x25A0	#	BLACK SQUARE
+0x95	0x2219	#	BULLET OPERATOR
+0x96	0x221A	#	SQUARE ROOT
+0x97	0x2248	#	ALMOST EQUAL TO
+0x98	0x2264	#	LESS-THAN OR EQUAL TO
+0x99	0x2265	#	GREATER-THAN OR EQUAL TO
+0x9A	0x00A0	#	NO-BREAK SPACE
+0x9B	0x2321	#	BOTTOM HALF INTEGRAL
+0x9C	0x00B0	#	DEGREE SIGN
+0x9D	0x00B2	#	SUPERSCRIPT TWO
+0x9E	0x00B7	#	MIDDLE DOT
+0x9F	0x00F7	#	DIVISION SIGN
+0xA0	0x2550	#	BOX DRAWINGS DOUBLE HORIZONTAL
+0xA1	0x2551	#	BOX DRAWINGS DOUBLE VERTICAL
+0xA2	0x2552	#	BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+0xA3	0x0451	#	CYRILLIC SMALL LETTER IO
+#0xA4	0x2553	#	BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
+0xA4    0x0454  #       CYRILLIC SMALL LETTER UKRAINIAN IE
+0xA5	0x2554	#	BOX DRAWINGS DOUBLE DOWN AND RIGHT
+#0xA6	0x2555	#	BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
+0xA6    0x0456  #       CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
+#0xA7	0x2556	#	BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
+0xA7    0x0457  #       CYRILLIC SMALL LETTER YI (UKRAINIAN)
+0xA8	0x2557	#	BOX DRAWINGS DOUBLE DOWN AND LEFT
+0xA9	0x2558	#	BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+0xAA	0x2559	#	BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+0xAB	0x255A	#	BOX DRAWINGS DOUBLE UP AND RIGHT
+0xAC	0x255B	#	BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+#0xAD	0x255C	#	BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
+0xAD    0x0491  #       CYRILLIC SMALL LETTER UKRAINIAN GHE WITH UPTURN
+0xAE	0x255D	#	BOX DRAWINGS DOUBLE UP AND LEFT
+0xAF	0x255E	#	BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+0xB0	0x255F	#	BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+0xB1	0x2560	#	BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+0xB2	0x2561	#	BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+0xB3	0x0401	#	CYRILLIC CAPITAL LETTER IO
+#0xB4	0x2562	#	BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
+0xB4    0x0404  #       CYRILLIC CAPITAL LETTER UKRAINIAN IE
+0xB5	0x2563	#	BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+#0xB6	0x2564	#	BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
+0xB6    0x0406  #       CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I
+#0xB7	0x2565	#	BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
+0xB7    0x0407  #       CYRILLIC CAPITAL LETTER YI (UKRAINIAN)
+0xB8	0x2566	#	BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+0xB9	0x2567	#	BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+0xBA	0x2568	#	BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+0xBB	0x2569	#	BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+0xBC	0x256A	#	BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+#0xBD	0x256B	#	BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
+0xBD    0x0490  #       CYRILLIC CAPITAL LETTER UKRAINIAN GHE WITH UPTURN
+0xBE	0x256C	#	BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+0xBF	0x00A9	#	COPYRIGHT SIGN
+0xC0	0x044E	#	CYRILLIC SMALL LETTER YU
+0xC1	0x0430	#	CYRILLIC SMALL LETTER A
+0xC2	0x0431	#	CYRILLIC SMALL LETTER BE
+0xC3	0x0446	#	CYRILLIC SMALL LETTER TSE
+0xC4	0x0434	#	CYRILLIC SMALL LETTER DE
+0xC5	0x0435	#	CYRILLIC SMALL LETTER IE
+0xC6	0x0444	#	CYRILLIC SMALL LETTER EF
+0xC7	0x0433	#	CYRILLIC SMALL LETTER GHE
+0xC8	0x0445	#	CYRILLIC SMALL LETTER HA
+0xC9	0x0438	#	CYRILLIC SMALL LETTER I
+0xCA	0x0439	#	CYRILLIC SMALL LETTER SHORT I
+0xCB	0x043A	#	CYRILLIC SMALL LETTER KA
+0xCC	0x043B	#	CYRILLIC SMALL LETTER EL
+0xCD	0x043C	#	CYRILLIC SMALL LETTER EM
+0xCE	0x043D	#	CYRILLIC SMALL LETTER EN
+0xCF	0x043E	#	CYRILLIC SMALL LETTER O
+0xD0	0x043F	#	CYRILLIC SMALL LETTER PE
+0xD1	0x044F	#	CYRILLIC SMALL LETTER YA
+0xD2	0x0440	#	CYRILLIC SMALL LETTER ER
+0xD3	0x0441	#	CYRILLIC SMALL LETTER ES
+0xD4	0x0442	#	CYRILLIC SMALL LETTER TE
+0xD5	0x0443	#	CYRILLIC SMALL LETTER U
+0xD6	0x0436	#	CYRILLIC SMALL LETTER ZHE
+0xD7	0x0432	#	CYRILLIC SMALL LETTER VE
+0xD8	0x044C	#	CYRILLIC SMALL LETTER SOFT SIGN
+0xD9	0x044B	#	CYRILLIC SMALL LETTER YERU
+0xDA	0x0437	#	CYRILLIC SMALL LETTER ZE
+0xDB	0x0448	#	CYRILLIC SMALL LETTER SHA
+0xDC	0x044D	#	CYRILLIC SMALL LETTER E
+0xDD	0x0449	#	CYRILLIC SMALL LETTER SHCHA
+0xDE	0x0447	#	CYRILLIC SMALL LETTER CHE
+0xDF	0x044A	#	CYRILLIC SMALL LETTER HARD SIGN
+0xE0	0x042E	#	CYRILLIC CAPITAL LETTER YU
+0xE1	0x0410	#	CYRILLIC CAPITAL LETTER A
+0xE2	0x0411	#	CYRILLIC CAPITAL LETTER BE
+0xE3	0x0426	#	CYRILLIC CAPITAL LETTER TSE
+0xE4	0x0414	#	CYRILLIC CAPITAL LETTER DE
+0xE5	0x0415	#	CYRILLIC CAPITAL LETTER IE
+0xE6	0x0424	#	CYRILLIC CAPITAL LETTER EF
+0xE7	0x0413	#	CYRILLIC CAPITAL LETTER GHE
+0xE8	0x0425	#	CYRILLIC CAPITAL LETTER HA
+0xE9	0x0418	#	CYRILLIC CAPITAL LETTER I
+0xEA	0x0419	#	CYRILLIC CAPITAL LETTER SHORT I
+0xEB	0x041A	#	CYRILLIC CAPITAL LETTER KA
+0xEC	0x041B	#	CYRILLIC CAPITAL LETTER EL
+0xED	0x041C	#	CYRILLIC CAPITAL LETTER EM
+0xEE	0x041D	#	CYRILLIC CAPITAL LETTER EN
+0xEF	0x041E	#	CYRILLIC CAPITAL LETTER O
+0xF0	0x041F	#	CYRILLIC CAPITAL LETTER PE
+0xF1	0x042F	#	CYRILLIC CAPITAL LETTER YA
+0xF2	0x0420	#	CYRILLIC CAPITAL LETTER ER
+0xF3	0x0421	#	CYRILLIC CAPITAL LETTER ES
+0xF4	0x0422	#	CYRILLIC CAPITAL LETTER TE
+0xF5	0x0423	#	CYRILLIC CAPITAL LETTER U
+0xF6	0x0416	#	CYRILLIC CAPITAL LETTER ZHE
+0xF7	0x0412	#	CYRILLIC CAPITAL LETTER VE
+0xF8	0x042C	#	CYRILLIC CAPITAL LETTER SOFT SIGN
+0xF9	0x042B	#	CYRILLIC CAPITAL LETTER YERU
+0xFA	0x0417	#	CYRILLIC CAPITAL LETTER ZE
+0xFB	0x0428	#	CYRILLIC CAPITAL LETTER SHA
+0xFC	0x042D	#	CYRILLIC CAPITAL LETTER E
+0xFD	0x0429	#	CYRILLIC CAPITAL LETTER SHCHA
+0xFE	0x0427	#	CYRILLIC CAPITAL LETTER CHE
+0xFF	0x042A	#	CYRILLIC CAPITAL LETTER HARD SIGN

Added: vendor/Python/current/Tools/unicode/python-mappings/TIS-620.TXT
===================================================================
--- vendor/Python/current/Tools/unicode/python-mappings/TIS-620.TXT	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/unicode/python-mappings/TIS-620.TXT	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,284 @@
+#
+#	Name:             TIS-620
+#	Unicode version:  3.2
+#	Table version:    1.0
+#	Table format:     Format A
+#	Date:             2005-10-25
+#	Authors:          Marc-Andre Lemburg <mal at egenix.com>
+#
+#       According to
+#       ftp://ftp.unicode.org/Public/MAPPINGS/ISO8859/8859-11.TXT the
+#       TIS-620 is the identical to ISO_8859-11 with the 0xA0
+#       (no-break space) mapping removed.
+#
+#       (c) Copyright Marc-Andre Lemburg, 2005.
+#           Licensed to PSF under a Contributor Agreement.
+#
+#       Based on the file 
+#       ftp://ftp.unicode.org/Public/MAPPINGS/ISO8859/8859-11.TXT
+#       which is:
+#
+#	Copyright (c) 2002 Unicode, Inc.  All Rights reserved.
+#
+#	This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
+#	No claims are made as to fitness for any particular purpose.  No
+#	warranties of any kind are expressed or implied.  The recipient
+#	agrees to determine applicability of information provided.  If this
+#	file has been provided on optical media by Unicode, Inc., the sole
+#	remedy for any claim will be exchange of defective media within 90
+#	days of receipt.
+#
+#	Unicode, Inc. hereby grants the right to freely use the information
+#	supplied in this file in the creation of products supporting the
+#	Unicode Standard, and to make copies of this file in any form for
+#	internal or external distribution as long as this notice remains
+#	attached.
+#
+0x00	0x0000	#	NULL
+0x01	0x0001	#	START OF HEADING
+0x02	0x0002	#	START OF TEXT
+0x03	0x0003	#	END OF TEXT
+0x04	0x0004	#	END OF TRANSMISSION
+0x05	0x0005	#	ENQUIRY
+0x06	0x0006	#	ACKNOWLEDGE
+0x07	0x0007	#	BELL
+0x08	0x0008	#	BACKSPACE
+0x09	0x0009	#	HORIZONTAL TABULATION
+0x0A	0x000A	#	LINE FEED
+0x0B	0x000B	#	VERTICAL TABULATION
+0x0C	0x000C	#	FORM FEED
+0x0D	0x000D	#	CARRIAGE RETURN
+0x0E	0x000E	#	SHIFT OUT
+0x0F	0x000F	#	SHIFT IN
+0x10	0x0010	#	DATA LINK ESCAPE
+0x11	0x0011	#	DEVICE CONTROL ONE
+0x12	0x0012	#	DEVICE CONTROL TWO
+0x13	0x0013	#	DEVICE CONTROL THREE
+0x14	0x0014	#	DEVICE CONTROL FOUR
+0x15	0x0015	#	NEGATIVE ACKNOWLEDGE
+0x16	0x0016	#	SYNCHRONOUS IDLE
+0x17	0x0017	#	END OF TRANSMISSION BLOCK
+0x18	0x0018	#	CANCEL
+0x19	0x0019	#	END OF MEDIUM
+0x1A	0x001A	#	SUBSTITUTE
+0x1B	0x001B	#	ESCAPE
+0x1C	0x001C	#	FILE SEPARATOR
+0x1D	0x001D	#	GROUP SEPARATOR
+0x1E	0x001E	#	RECORD SEPARATOR
+0x1F	0x001F	#	UNIT SEPARATOR
+0x20	0x0020	#	SPACE
+0x21	0x0021	#	EXCLAMATION MARK
+0x22	0x0022	#	QUOTATION MARK
+0x23	0x0023	#	NUMBER SIGN
+0x24	0x0024	#	DOLLAR SIGN
+0x25	0x0025	#	PERCENT SIGN
+0x26	0x0026	#	AMPERSAND
+0x27	0x0027	#	APOSTROPHE
+0x28	0x0028	#	LEFT PARENTHESIS
+0x29	0x0029	#	RIGHT PARENTHESIS
+0x2A	0x002A	#	ASTERISK
+0x2B	0x002B	#	PLUS SIGN
+0x2C	0x002C	#	COMMA
+0x2D	0x002D	#	HYPHEN-MINUS
+0x2E	0x002E	#	FULL STOP
+0x2F	0x002F	#	SOLIDUS
+0x30	0x0030	#	DIGIT ZERO
+0x31	0x0031	#	DIGIT ONE
+0x32	0x0032	#	DIGIT TWO
+0x33	0x0033	#	DIGIT THREE
+0x34	0x0034	#	DIGIT FOUR
+0x35	0x0035	#	DIGIT FIVE
+0x36	0x0036	#	DIGIT SIX
+0x37	0x0037	#	DIGIT SEVEN
+0x38	0x0038	#	DIGIT EIGHT
+0x39	0x0039	#	DIGIT NINE
+0x3A	0x003A	#	COLON
+0x3B	0x003B	#	SEMICOLON
+0x3C	0x003C	#	LESS-THAN SIGN
+0x3D	0x003D	#	EQUALS SIGN
+0x3E	0x003E	#	GREATER-THAN SIGN
+0x3F	0x003F	#	QUESTION MARK
+0x40	0x0040	#	COMMERCIAL AT
+0x41	0x0041	#	LATIN CAPITAL LETTER A
+0x42	0x0042	#	LATIN CAPITAL LETTER B
+0x43	0x0043	#	LATIN CAPITAL LETTER C
+0x44	0x0044	#	LATIN CAPITAL LETTER D
+0x45	0x0045	#	LATIN CAPITAL LETTER E
+0x46	0x0046	#	LATIN CAPITAL LETTER F
+0x47	0x0047	#	LATIN CAPITAL LETTER G
+0x48	0x0048	#	LATIN CAPITAL LETTER H
+0x49	0x0049	#	LATIN CAPITAL LETTER I
+0x4A	0x004A	#	LATIN CAPITAL LETTER J
+0x4B	0x004B	#	LATIN CAPITAL LETTER K
+0x4C	0x004C	#	LATIN CAPITAL LETTER L
+0x4D	0x004D	#	LATIN CAPITAL LETTER M
+0x4E	0x004E	#	LATIN CAPITAL LETTER N
+0x4F	0x004F	#	LATIN CAPITAL LETTER O
+0x50	0x0050	#	LATIN CAPITAL LETTER P
+0x51	0x0051	#	LATIN CAPITAL LETTER Q
+0x52	0x0052	#	LATIN CAPITAL LETTER R
+0x53	0x0053	#	LATIN CAPITAL LETTER S
+0x54	0x0054	#	LATIN CAPITAL LETTER T
+0x55	0x0055	#	LATIN CAPITAL LETTER U
+0x56	0x0056	#	LATIN CAPITAL LETTER V
+0x57	0x0057	#	LATIN CAPITAL LETTER W
+0x58	0x0058	#	LATIN CAPITAL LETTER X
+0x59	0x0059	#	LATIN CAPITAL LETTER Y
+0x5A	0x005A	#	LATIN CAPITAL LETTER Z
+0x5B	0x005B	#	LEFT SQUARE BRACKET
+0x5C	0x005C	#	REVERSE SOLIDUS
+0x5D	0x005D	#	RIGHT SQUARE BRACKET
+0x5E	0x005E	#	CIRCUMFLEX ACCENT
+0x5F	0x005F	#	LOW LINE
+0x60	0x0060	#	GRAVE ACCENT
+0x61	0x0061	#	LATIN SMALL LETTER A
+0x62	0x0062	#	LATIN SMALL LETTER B
+0x63	0x0063	#	LATIN SMALL LETTER C
+0x64	0x0064	#	LATIN SMALL LETTER D
+0x65	0x0065	#	LATIN SMALL LETTER E
+0x66	0x0066	#	LATIN SMALL LETTER F
+0x67	0x0067	#	LATIN SMALL LETTER G
+0x68	0x0068	#	LATIN SMALL LETTER H
+0x69	0x0069	#	LATIN SMALL LETTER I
+0x6A	0x006A	#	LATIN SMALL LETTER J
+0x6B	0x006B	#	LATIN SMALL LETTER K
+0x6C	0x006C	#	LATIN SMALL LETTER L
+0x6D	0x006D	#	LATIN SMALL LETTER M
+0x6E	0x006E	#	LATIN SMALL LETTER N
+0x6F	0x006F	#	LATIN SMALL LETTER O
+0x70	0x0070	#	LATIN SMALL LETTER P
+0x71	0x0071	#	LATIN SMALL LETTER Q
+0x72	0x0072	#	LATIN SMALL LETTER R
+0x73	0x0073	#	LATIN SMALL LETTER S
+0x74	0x0074	#	LATIN SMALL LETTER T
+0x75	0x0075	#	LATIN SMALL LETTER U
+0x76	0x0076	#	LATIN SMALL LETTER V
+0x77	0x0077	#	LATIN SMALL LETTER W
+0x78	0x0078	#	LATIN SMALL LETTER X
+0x79	0x0079	#	LATIN SMALL LETTER Y
+0x7A	0x007A	#	LATIN SMALL LETTER Z
+0x7B	0x007B	#	LEFT CURLY BRACKET
+0x7C	0x007C	#	VERTICAL LINE
+0x7D	0x007D	#	RIGHT CURLY BRACKET
+0x7E	0x007E	#	TILDE
+0x7F	0x007F	#	DELETE
+0x80	0x0080	#	<control>
+0x81	0x0081	#	<control>
+0x82	0x0082	#	<control>
+0x83	0x0083	#	<control>
+0x84	0x0084	#	<control>
+0x85	0x0085	#	<control>
+0x86	0x0086	#	<control>
+0x87	0x0087	#	<control>
+0x88	0x0088	#	<control>
+0x89	0x0089	#	<control>
+0x8A	0x008A	#	<control>
+0x8B	0x008B	#	<control>
+0x8C	0x008C	#	<control>
+0x8D	0x008D	#	<control>
+0x8E	0x008E	#	<control>
+0x8F	0x008F	#	<control>
+0x90	0x0090	#	<control>
+0x91	0x0091	#	<control>
+0x92	0x0092	#	<control>
+0x93	0x0093	#	<control>
+0x94	0x0094	#	<control>
+0x95	0x0095	#	<control>
+0x96	0x0096	#	<control>
+0x97	0x0097	#	<control>
+0x98	0x0098	#	<control>
+0x99	0x0099	#	<control>
+0x9A	0x009A	#	<control>
+0x9B	0x009B	#	<control>
+0x9C	0x009C	#	<control>
+0x9D	0x009D	#	<control>
+0x9E	0x009E	#	<control>
+0x9F	0x009F	#	<control>
+#0xA0	0x00A0	#	NO-BREAK SPACE
+0xA1	0x0E01	#	THAI CHARACTER KO KAI
+0xA2	0x0E02	#	THAI CHARACTER KHO KHAI
+0xA3	0x0E03	#	THAI CHARACTER KHO KHUAT
+0xA4	0x0E04	#	THAI CHARACTER KHO KHWAI
+0xA5	0x0E05	#	THAI CHARACTER KHO KHON
+0xA6	0x0E06	#	THAI CHARACTER KHO RAKHANG
+0xA7	0x0E07	#	THAI CHARACTER NGO NGU
+0xA8	0x0E08	#	THAI CHARACTER CHO CHAN
+0xA9	0x0E09	#	THAI CHARACTER CHO CHING
+0xAA	0x0E0A	#	THAI CHARACTER CHO CHANG
+0xAB	0x0E0B	#	THAI CHARACTER SO SO
+0xAC	0x0E0C	#	THAI CHARACTER CHO CHOE
+0xAD	0x0E0D	#	THAI CHARACTER YO YING
+0xAE	0x0E0E	#	THAI CHARACTER DO CHADA
+0xAF	0x0E0F	#	THAI CHARACTER TO PATAK
+0xB0	0x0E10	#	THAI CHARACTER THO THAN
+0xB1	0x0E11	#	THAI CHARACTER THO NANGMONTHO
+0xB2	0x0E12	#	THAI CHARACTER THO PHUTHAO
+0xB3	0x0E13	#	THAI CHARACTER NO NEN
+0xB4	0x0E14	#	THAI CHARACTER DO DEK
+0xB5	0x0E15	#	THAI CHARACTER TO TAO
+0xB6	0x0E16	#	THAI CHARACTER THO THUNG
+0xB7	0x0E17	#	THAI CHARACTER THO THAHAN
+0xB8	0x0E18	#	THAI CHARACTER THO THONG
+0xB9	0x0E19	#	THAI CHARACTER NO NU
+0xBA	0x0E1A	#	THAI CHARACTER BO BAIMAI
+0xBB	0x0E1B	#	THAI CHARACTER PO PLA
+0xBC	0x0E1C	#	THAI CHARACTER PHO PHUNG
+0xBD	0x0E1D	#	THAI CHARACTER FO FA
+0xBE	0x0E1E	#	THAI CHARACTER PHO PHAN
+0xBF	0x0E1F	#	THAI CHARACTER FO FAN
+0xC0	0x0E20	#	THAI CHARACTER PHO SAMPHAO
+0xC1	0x0E21	#	THAI CHARACTER MO MA
+0xC2	0x0E22	#	THAI CHARACTER YO YAK
+0xC3	0x0E23	#	THAI CHARACTER RO RUA
+0xC4	0x0E24	#	THAI CHARACTER RU
+0xC5	0x0E25	#	THAI CHARACTER LO LING
+0xC6	0x0E26	#	THAI CHARACTER LU
+0xC7	0x0E27	#	THAI CHARACTER WO WAEN
+0xC8	0x0E28	#	THAI CHARACTER SO SALA
+0xC9	0x0E29	#	THAI CHARACTER SO RUSI
+0xCA	0x0E2A	#	THAI CHARACTER SO SUA
+0xCB	0x0E2B	#	THAI CHARACTER HO HIP
+0xCC	0x0E2C	#	THAI CHARACTER LO CHULA
+0xCD	0x0E2D	#	THAI CHARACTER O ANG
+0xCE	0x0E2E	#	THAI CHARACTER HO NOKHUK
+0xCF	0x0E2F	#	THAI CHARACTER PAIYANNOI
+0xD0	0x0E30	#	THAI CHARACTER SARA A
+0xD1	0x0E31	#	THAI CHARACTER MAI HAN-AKAT
+0xD2	0x0E32	#	THAI CHARACTER SARA AA
+0xD3	0x0E33	#	THAI CHARACTER SARA AM
+0xD4	0x0E34	#	THAI CHARACTER SARA I
+0xD5	0x0E35	#	THAI CHARACTER SARA II
+0xD6	0x0E36	#	THAI CHARACTER SARA UE
+0xD7	0x0E37	#	THAI CHARACTER SARA UEE
+0xD8	0x0E38	#	THAI CHARACTER SARA U
+0xD9	0x0E39	#	THAI CHARACTER SARA UU
+0xDA	0x0E3A	#	THAI CHARACTER PHINTHU
+0xDF	0x0E3F	#	THAI CURRENCY SYMBOL BAHT
+0xE0	0x0E40	#	THAI CHARACTER SARA E
+0xE1	0x0E41	#	THAI CHARACTER SARA AE
+0xE2	0x0E42	#	THAI CHARACTER SARA O
+0xE3	0x0E43	#	THAI CHARACTER SARA AI MAIMUAN
+0xE4	0x0E44	#	THAI CHARACTER SARA AI MAIMALAI
+0xE5	0x0E45	#	THAI CHARACTER LAKKHANGYAO
+0xE6	0x0E46	#	THAI CHARACTER MAIYAMOK
+0xE7	0x0E47	#	THAI CHARACTER MAITAIKHU
+0xE8	0x0E48	#	THAI CHARACTER MAI EK
+0xE9	0x0E49	#	THAI CHARACTER MAI THO
+0xEA	0x0E4A	#	THAI CHARACTER MAI TRI
+0xEB	0x0E4B	#	THAI CHARACTER MAI CHATTAWA
+0xEC	0x0E4C	#	THAI CHARACTER THANTHAKHAT
+0xED	0x0E4D	#	THAI CHARACTER NIKHAHIT
+0xEE	0x0E4E	#	THAI CHARACTER YAMAKKAN
+0xEF	0x0E4F	#	THAI CHARACTER FONGMAN
+0xF0	0x0E50	#	THAI DIGIT ZERO
+0xF1	0x0E51	#	THAI DIGIT ONE
+0xF2	0x0E52	#	THAI DIGIT TWO
+0xF3	0x0E53	#	THAI DIGIT THREE
+0xF4	0x0E54	#	THAI DIGIT FOUR
+0xF5	0x0E55	#	THAI DIGIT FIVE
+0xF6	0x0E56	#	THAI DIGIT SIX
+0xF7	0x0E57	#	THAI DIGIT SEVEN
+0xF8	0x0E58	#	THAI DIGIT EIGHT
+0xF9	0x0E59	#	THAI DIGIT NINE
+0xFA	0x0E5A	#	THAI CHARACTER ANGKHANKHU
+0xFB	0x0E5B	#	THAI CHARACTER KHOMUT

Added: vendor/Python/current/Tools/versioncheck/README
===================================================================
--- vendor/Python/current/Tools/versioncheck/README	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/versioncheck/README	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,41 @@
+This is versioncheck 1.0, a first stab at automatic checking of versions of
+Python extension packages installed on your system.
+
+The basic idea is that each package contains a _checkversion.py
+somewhere, probably at the root level of the package. In addition, each
+package maintainer makes a file available on the net, through ftp or
+http, which contains the version number of the most recent distribution
+and some readable text explaining the differences with previous
+versions, where to download the package, etc.
+
+The checkversions.py script walks through the installed Python tree (or
+through a tree of choice), and runs each _checkversion.py script. These
+scripts retrieve the current-version file over the net, compares version
+numbers and tells the user about new versions of packages available.
+
+A boilerplate for the _checkversion.py file can be found here. Replace
+package name, version and the URL of the version-check file and put it in
+your distribution. In stead of a single URL you can also specify a list
+of URLs. Each of these will be checked in order until one is available,
+this is handy for distributions that live in multiple places. Put the
+primary distribution site (the most up-to-date site) before others.
+The script is executed with execfile(), not imported, and the current
+directory is the checkversion directory, so be careful with globals,
+importing, etc.
+
+The version-check file consists of an rfc822-style header followed by
+plaintext. The only header field checked currently is
+'Current-Version:', which should contain te current version and is
+matched against the string contained in the _checkversion.py script.
+The rest of the file is human-readable text and presented to the user if
+there is a version mismatch. It should contain at the very least a URL
+of either the current distribution or a webpage describing it.
+
+Pycheckversion.py is the module that does the actual checking of versions.
+It should be fine where it is, it is imported by checkversion before anything
+else is done, but if imports fail you may want to move it to somewhere
+along sys.path.
+
+	Jack Jansen, CWI, 23-Dec-97.
+	<jack at cwi.nl>
+	

Added: vendor/Python/current/Tools/versioncheck/_checkversion.py
===================================================================
--- vendor/Python/current/Tools/versioncheck/_checkversion.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/versioncheck/_checkversion.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,16 @@
+"""This file (which is sourced, not imported) checks the version of the
+"versioncheck" package. It is also an example of how to format your own
+_checkversion.py file"""
+
+import pyversioncheck
+
+_PACKAGE="versioncheck"
+_VERSION="1.0"
+_URL="http://www.cwi.nl/~jack/versioncheck/curversion.txt"
+
+try:
+    _myverbose=VERBOSE
+except NameError:
+    _myverbose=1
+
+pyversioncheck.versioncheck(_PACKAGE, _URL, _VERSION, verbose=_myverbose)

Added: vendor/Python/current/Tools/versioncheck/checkversions.py
===================================================================
--- vendor/Python/current/Tools/versioncheck/checkversions.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/versioncheck/checkversions.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,52 @@
+"""Checkversions - recursively search a directory (default: sys.prefix)
+for _checkversion.py files, and run each of them. This will tell you of
+new versions available for any packages you have installed."""
+
+import os
+import getopt
+import sys
+import pyversioncheck
+
+CHECKNAME="_checkversion.py"
+
+VERBOSE=1
+
+USAGE="""Usage: checkversions [-v verboselevel] [dir ...]
+Recursively examine a tree (default: sys.prefix) and for each package
+with a _checkversion.py file compare the installed version against the current
+version.
+
+Values for verboselevel:
+0 - Minimal output, one line per package
+1 - Also print descriptions for outdated packages (default)
+2 - Print information on each URL checked
+3 - Check every URL for packages with multiple locations"""
+
+def check1dir(dummy, dir, files):
+    if CHECKNAME in files:
+        fullname = os.path.join(dir, CHECKNAME)
+        try:
+            execfile(fullname)
+        except:
+            print '** Exception in', fullname
+
+def walk1tree(tree):
+    os.path.walk(tree, check1dir, None)
+
+def main():
+    global VERBOSE
+    try:
+        options, arguments = getopt.getopt(sys.argv[1:], 'v:')
+    except getopt.error:
+        print USAGE
+        sys.exit(1)
+    for o, a in options:
+        if o == '-v':
+            VERBOSE = int(a)
+    if not arguments:
+        arguments = [sys.prefix]
+    for dir in arguments:
+        walk1tree(dir)
+
+if __name__ == '__main__':
+    main()

Added: vendor/Python/current/Tools/versioncheck/pyversioncheck.py
===================================================================
--- vendor/Python/current/Tools/versioncheck/pyversioncheck.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/versioncheck/pyversioncheck.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,98 @@
+"""pyversioncheck - Module to help with checking versions"""
+import types
+import rfc822
+import urllib
+import sys
+
+# Verbose options
+VERBOSE_SILENT=0        # Single-line reports per package
+VERBOSE_NORMAL=1        # Single-line reports per package, more info if outdated
+VERBOSE_EACHFILE=2      # Report on each URL checked
+VERBOSE_CHECKALL=3      # Check each URL for each package
+
+# Test directory
+## urllib bug: _TESTDIR="ftp://ftp.cwi.nl/pub/jack/python/versiontestdir/"
+_TESTDIR="http://www.cwi.nl/~jack/versiontestdir/"
+
+def versioncheck(package, url, version, verbose=0):
+    ok, newversion, fp = checkonly(package, url, version, verbose)
+    if verbose > VERBOSE_NORMAL:
+        return ok
+    if ok < 0:
+        print '%s: No correctly formatted current version file found'%(package)
+    elif ok == 1:
+        print '%s: up-to-date (version %s)'%(package, version)
+    else:
+        print '%s: version %s installed, version %s found:' % \
+                        (package, version, newversion)
+        if verbose > VERBOSE_SILENT:
+            while 1:
+                line = fp.readline()
+                if not line: break
+                sys.stdout.write('\t'+line)
+    return ok
+
+def checkonly(package, url, version, verbose=0):
+    if verbose >= VERBOSE_EACHFILE:
+        print '%s:'%package
+    if type(url) == types.StringType:
+        ok, newversion, fp = _check1version(package, url, version, verbose)
+    else:
+        for u in url:
+            ok, newversion, fp = _check1version(package, u, version, verbose)
+            if ok >= 0 and verbose < VERBOSE_CHECKALL:
+                break
+    return ok, newversion, fp
+
+def _check1version(package, url, version, verbose=0):
+    if verbose >= VERBOSE_EACHFILE:
+        print '  Checking %s'%url
+    try:
+        fp = urllib.urlopen(url)
+    except IOError, arg:
+        if verbose >= VERBOSE_EACHFILE:
+            print '    Cannot open:', arg
+        return -1, None, None
+    msg = rfc822.Message(fp, seekable=0)
+    newversion = msg.getheader('current-version')
+    if not newversion:
+        if verbose >= VERBOSE_EACHFILE:
+            print '    No "Current-Version:" header in URL or URL not found'
+        return -1, None, None
+    version = version.lower().strip()
+    newversion = newversion.lower().strip()
+    if version == newversion:
+        if verbose >= VERBOSE_EACHFILE:
+            print '    Version identical (%s)'%newversion
+        return 1, version, fp
+    else:
+        if verbose >= VERBOSE_EACHFILE:
+            print '    Versions different (installed: %s, new: %s)'% \
+                        (version, newversion)
+        return 0, newversion, fp
+
+
+def _test():
+    print '--- TEST VERBOSE=1'
+    print '--- Testing existing and identical version file'
+    versioncheck('VersionTestPackage', _TESTDIR+'Version10.txt', '1.0', verbose=1)
+    print '--- Testing existing package with new version'
+    versioncheck('VersionTestPackage', _TESTDIR+'Version11.txt', '1.0', verbose=1)
+    print '--- Testing package with non-existing version file'
+    versioncheck('VersionTestPackage', _TESTDIR+'nonexistent.txt', '1.0', verbose=1)
+    print '--- Test package with 2 locations, first non-existing second ok'
+    versfiles = [_TESTDIR+'nonexistent.txt', _TESTDIR+'Version10.txt']
+    versioncheck('VersionTestPackage', versfiles, '1.0', verbose=1)
+    print '--- TEST VERBOSE=2'
+    print '--- Testing existing and identical version file'
+    versioncheck('VersionTestPackage', _TESTDIR+'Version10.txt', '1.0', verbose=2)
+    print '--- Testing existing package with new version'
+    versioncheck('VersionTestPackage', _TESTDIR+'Version11.txt', '1.0', verbose=2)
+    print '--- Testing package with non-existing version file'
+    versioncheck('VersionTestPackage', _TESTDIR+'nonexistent.txt', '1.0', verbose=2)
+    print '--- Test package with 2 locations, first non-existing second ok'
+    versfiles = [_TESTDIR+'nonexistent.txt', _TESTDIR+'Version10.txt']
+    versioncheck('VersionTestPackage', versfiles, '1.0', verbose=2)
+
+if __name__ == '__main__':
+    _test()

Added: vendor/Python/current/Tools/webchecker/README
===================================================================
--- vendor/Python/current/Tools/webchecker/README	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/webchecker/README	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,23 @@
+Webchecker
+----------
+
+This is a simple web tree checker, useful to find bad links in a web
+tree.  It currently checks links pointing within the same subweb for
+validity.  The main program is "webchecker.py".  See its doc string
+(or invoke it with the option "-?") for more defails.
+
+History:
+
+- Jan 1997.  First release.  The module robotparser.py was written by
+Skip Montanaro; the rest is original work by Guido van Rossum.
+
+- May 1999.  Sam Bayer contributed a new version, wcnew.py, which
+supports checking internal links (#spam fragments in URLs) and some
+other options.
+
+- Nov 1999.  Sam Bayer contributed patches to reintegrate wcnew.py
+into webchecker.py, and corresponding mods to wcgui.py and
+websucker.py.
+
+- Mar 2004.  Chris Herborth contributed a patch to let webchecker.py
+handle XHTML's 'id' attribute.

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

Added: vendor/Python/current/Tools/webchecker/wcgui.py
===================================================================
--- vendor/Python/current/Tools/webchecker/wcgui.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/webchecker/wcgui.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,463 @@
+#! /usr/bin/env python
+
+"""GUI interface to webchecker.
+
+This works as a Grail applet too!  E.g.
+
+  <APPLET CODE=wcgui.py NAME=CheckerWindow></APPLET>
+
+Checkpoints are not (yet???  ever???) supported.
+
+User interface:
+
+Enter a root to check in the text entry box.  To enter more than one root,
+enter them one at a time and press <Return> for each one.
+
+Command buttons Start, Stop and "Check one" govern the checking process in
+the obvious way.  Start and "Check one" also enter the root from the text
+entry box if one is present.  There's also a check box (enabled by default)
+to decide whether actually to follow external links (since this can slow
+the checking down considerably).  Finally there's a Quit button.
+
+A series of checkbuttons determines whether the corresponding output panel
+is shown.  List panels are also automatically shown or hidden when their
+status changes between empty to non-empty.  There are six panels:
+
+Log        -- raw output from the checker (-v, -q affect this)
+To check   -- links discovered but not yet checked
+Checked    -- links that have been checked
+Bad links  -- links that failed upon checking
+Errors     -- pages containing at least one bad link
+Details    -- details about one URL; double click on a URL in any of
+              the above list panels (not in Log) will show details
+              for that URL
+
+Use your window manager's Close command to quit.
+
+Command line options:
+
+-m bytes  -- skip HTML pages larger than this size (default %(MAXPAGE)d)
+-q        -- quiet operation (also suppresses external links report)
+-v        -- verbose operation; repeating -v will increase verbosity
+-t root   -- specify root dir which should be treated as internal (can repeat)
+-a        -- don't check name anchors
+
+Command line arguments:
+
+rooturl   -- URL to start checking
+             (default %(DEFROOT)s)
+
+XXX The command line options (-m, -q, -v) should be GUI accessible.
+
+XXX The roots should be visible as a list (?).
+
+XXX The multipanel user interface is clumsy.
+
+"""
+
+# ' Emacs bait
+
+
+import sys
+import getopt
+from Tkinter import *
+import tktools
+import webchecker
+import random
+
+# Override some for a weaker platform
+if sys.platform == 'mac':
+    webchecker.DEFROOT = "http://grail.cnri.reston.va.us/"
+    webchecker.MAXPAGE = 50000
+    webchecker.verbose = 4
+
+def main():
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], 't:m:qva')
+    except getopt.error, msg:
+        sys.stdout = sys.stderr
+        print msg
+        print __doc__%vars(webchecker)
+        sys.exit(2)
+    webchecker.verbose = webchecker.VERBOSE
+    webchecker.nonames = webchecker.NONAMES
+    webchecker.maxpage = webchecker.MAXPAGE
+    extra_roots = []
+    for o, a in opts:
+        if o == '-m':
+            webchecker.maxpage = int(a)
+        if o == '-q':
+            webchecker.verbose = 0
+        if o == '-v':
+            webchecker.verbose = webchecker.verbose + 1
+        if o == '-t':
+            extra_roots.append(a)
+        if o == '-a':
+            webchecker.nonames = not webchecker.nonames
+    root = Tk(className='Webchecker')
+    root.protocol("WM_DELETE_WINDOW", root.quit)
+    c = CheckerWindow(root)
+    c.setflags(verbose=webchecker.verbose, maxpage=webchecker.maxpage,
+               nonames=webchecker.nonames)
+    if args:
+        for arg in args[:-1]:
+            c.addroot(arg)
+        c.suggestroot(args[-1])
+    # Usually conditioned on whether external links
+    # will be checked, but since that's not a command
+    # line option, just toss them in.
+    for url_root in extra_roots:
+        # Make sure it's terminated by a slash,
+        # so that addroot doesn't discard the last
+        # directory component.
+        if url_root[-1] != "/":
+            url_root = url_root + "/"
+        c.addroot(url_root, add_to_do = 0)
+    root.mainloop()
+
+
+class CheckerWindow(webchecker.Checker):
+
+    def __init__(self, parent, root=webchecker.DEFROOT):
+        self.__parent = parent
+
+        self.__topcontrols = Frame(parent)
+        self.__topcontrols.pack(side=TOP, fill=X)
+        self.__label = Label(self.__topcontrols, text="Root URL:")
+        self.__label.pack(side=LEFT)
+        self.__rootentry = Entry(self.__topcontrols, width=60)
+        self.__rootentry.pack(side=LEFT)
+        self.__rootentry.bind('<Return>', self.enterroot)
+        self.__rootentry.focus_set()
+
+        self.__controls = Frame(parent)
+        self.__controls.pack(side=TOP, fill=X)
+        self.__running = 0
+        self.__start = Button(self.__controls, text="Run", command=self.start)
+        self.__start.pack(side=LEFT)
+        self.__stop = Button(self.__controls, text="Stop", command=self.stop,
+                             state=DISABLED)
+        self.__stop.pack(side=LEFT)
+        self.__step = Button(self.__controls, text="Check one",
+                             command=self.step)
+        self.__step.pack(side=LEFT)
+        self.__cv = BooleanVar(parent)
+        self.__cv.set(self.checkext)
+        self.__checkext = Checkbutton(self.__controls, variable=self.__cv,
+                                      command=self.update_checkext,
+                                      text="Check nonlocal links",)
+        self.__checkext.pack(side=LEFT)
+        self.__reset = Button(self.__controls, text="Start over", command=self.reset)
+        self.__reset.pack(side=LEFT)
+        if __name__ == '__main__': # No Quit button under Grail!
+            self.__quit = Button(self.__controls, text="Quit",
+                                 command=self.__parent.quit)
+            self.__quit.pack(side=RIGHT)
+
+        self.__status = Label(parent, text="Status: initial", anchor=W)
+        self.__status.pack(side=TOP, fill=X)
+        self.__checking = Label(parent, text="Idle", anchor=W)
+        self.__checking.pack(side=TOP, fill=X)
+        self.__mp = mp = MultiPanel(parent)
+        sys.stdout = self.__log = LogPanel(mp, "Log")
+        self.__todo = ListPanel(mp, "To check", self, self.showinfo)
+        self.__done = ListPanel(mp, "Checked", self, self.showinfo)
+        self.__bad = ListPanel(mp, "Bad links", self, self.showinfo)
+        self.__errors = ListPanel(mp, "Pages w/ bad links", self, self.showinfo)
+        self.__details = LogPanel(mp, "Details")
+        self.root_seed = None
+        webchecker.Checker.__init__(self)
+        if root:
+            root = str(root).strip()
+            if root:
+                self.suggestroot(root)
+        self.newstatus()
+
+    def reset(self):
+        webchecker.Checker.reset(self)
+        for p in self.__todo, self.__done, self.__bad, self.__errors:
+            p.clear()
+        if self.root_seed:
+            self.suggestroot(self.root_seed)
+
+    def suggestroot(self, root):
+        self.__rootentry.delete(0, END)
+        self.__rootentry.insert(END, root)
+        self.__rootentry.select_range(0, END)
+        self.root_seed = root
+
+    def enterroot(self, event=None):
+        root = self.__rootentry.get()
+        root = root.strip()
+        if root:
+            self.__checking.config(text="Adding root "+root)
+            self.__checking.update_idletasks()
+            self.addroot(root)
+            self.__checking.config(text="Idle")
+            try:
+                i = self.__todo.items.index(root)
+            except (ValueError, IndexError):
+                pass
+            else:
+                self.__todo.list.select_clear(0, END)
+                self.__todo.list.select_set(i)
+                self.__todo.list.yview(i)
+        self.__rootentry.delete(0, END)
+
+    def start(self):
+        self.__start.config(state=DISABLED, relief=SUNKEN)
+        self.__stop.config(state=NORMAL)
+        self.__step.config(state=DISABLED)
+        self.enterroot()
+        self.__running = 1
+        self.go()
+
+    def stop(self):
+        self.__stop.config(state=DISABLED, relief=SUNKEN)
+        self.__running = 0
+
+    def step(self):
+        self.__start.config(state=DISABLED)
+        self.__step.config(state=DISABLED, relief=SUNKEN)
+        self.enterroot()
+        self.__running = 0
+        self.dosomething()
+
+    def go(self):
+        if self.__running:
+            self.__parent.after_idle(self.dosomething)
+        else:
+            self.__checking.config(text="Idle")
+            self.__start.config(state=NORMAL, relief=RAISED)
+            self.__stop.config(state=DISABLED, relief=RAISED)
+            self.__step.config(state=NORMAL, relief=RAISED)
+
+    __busy = 0
+
+    def dosomething(self):
+        if self.__busy: return
+        self.__busy = 1
+        if self.todo:
+            l = self.__todo.selectedindices()
+            if l:
+                i = l[0]
+            else:
+                i = 0
+                self.__todo.list.select_set(i)
+            self.__todo.list.yview(i)
+            url = self.__todo.items[i]
+            self.__checking.config(text="Checking "+self.format_url(url))
+            self.__parent.update()
+            self.dopage(url)
+        else:
+            self.stop()
+        self.__busy = 0
+        self.go()
+
+    def showinfo(self, url):
+        d = self.__details
+        d.clear()
+        d.put("URL:    %s\n" % self.format_url(url))
+        if self.bad.has_key(url):
+            d.put("Error:  %s\n" % str(self.bad[url]))
+        if url in self.roots:
+            d.put("Note:   This is a root URL\n")
+        if self.done.has_key(url):
+            d.put("Status: checked\n")
+            o = self.done[url]
+        elif self.todo.has_key(url):
+            d.put("Status: to check\n")
+            o = self.todo[url]
+        else:
+            d.put("Status: unknown (!)\n")
+            o = []
+        if (not url[1]) and self.errors.has_key(url[0]):
+            d.put("Bad links from this page:\n")
+            for triple in self.errors[url[0]]:
+                link, rawlink, msg = triple
+                d.put("  HREF  %s" % self.format_url(link))
+                if self.format_url(link) != rawlink: d.put(" (%s)" %rawlink)
+                d.put("\n")
+                d.put("  error %s\n" % str(msg))
+        self.__mp.showpanel("Details")
+        for source, rawlink in o:
+            d.put("Origin: %s" % source)
+            if rawlink != self.format_url(url):
+                d.put(" (%s)" % rawlink)
+            d.put("\n")
+        d.text.yview("1.0")
+
+    def setbad(self, url, msg):
+        webchecker.Checker.setbad(self, url, msg)
+        self.__bad.insert(url)
+        self.newstatus()
+
+    def setgood(self, url):
+        webchecker.Checker.setgood(self, url)
+        self.__bad.remove(url)
+        self.newstatus()
+
+    def newlink(self, url, origin):
+        webchecker.Checker.newlink(self, url, origin)
+        if self.done.has_key(url):
+            self.__done.insert(url)
+        elif self.todo.has_key(url):
+            self.__todo.insert(url)
+        self.newstatus()
+
+    def markdone(self, url):
+        webchecker.Checker.markdone(self, url)
+        self.__done.insert(url)
+        self.__todo.remove(url)
+        self.newstatus()
+
+    def seterror(self, url, triple):
+        webchecker.Checker.seterror(self, url, triple)
+        self.__errors.insert((url, ''))
+        self.newstatus()
+
+    def newstatus(self):
+        self.__status.config(text="Status: "+self.status())
+        self.__parent.update()
+
+    def update_checkext(self):
+        self.checkext = self.__cv.get()
+
+
+class ListPanel:
+
+    def __init__(self, mp, name, checker, showinfo=None):
+        self.mp = mp
+        self.name = name
+        self.showinfo = showinfo
+        self.checker = checker
+        self.panel = mp.addpanel(name)
+        self.list, self.frame = tktools.make_list_box(
+            self.panel, width=60, height=5)
+        self.list.config(exportselection=0)
+        if showinfo:
+            self.list.bind('<Double-Button-1>', self.doubleclick)
+        self.items = []
+
+    def clear(self):
+        self.items = []
+        self.list.delete(0, END)
+        self.mp.hidepanel(self.name)
+
+    def doubleclick(self, event):
+        l = self.selectedindices()
+        if l:
+            self.showinfo(self.items[l[0]])
+
+    def selectedindices(self):
+        l = self.list.curselection()
+        if not l: return []
+        return map(int, l)
+
+    def insert(self, url):
+        if url not in self.items:
+            if not self.items:
+                self.mp.showpanel(self.name)
+            # (I tried sorting alphabetically, but the display is too jumpy)
+            i = len(self.items)
+            self.list.insert(i, self.checker.format_url(url))
+            self.list.yview(i)
+            self.items.insert(i, url)
+
+    def remove(self, url):
+        try:
+            i = self.items.index(url)
+        except (ValueError, IndexError):
+            pass
+        else:
+            was_selected = i in self.selectedindices()
+            self.list.delete(i)
+            del self.items[i]
+            if not self.items:
+                self.mp.hidepanel(self.name)
+            elif was_selected:
+                if i >= len(self.items):
+                    i = len(self.items) - 1
+                self.list.select_set(i)
+
+
+class LogPanel:
+
+    def __init__(self, mp, name):
+        self.mp = mp
+        self.name = name
+        self.panel = mp.addpanel(name)
+        self.text, self.frame = tktools.make_text_box(self.panel, height=10)
+        self.text.config(wrap=NONE)
+
+    def clear(self):
+        self.text.delete("1.0", END)
+        self.text.yview("1.0")
+
+    def put(self, s):
+        self.text.insert(END, s)
+        if '\n' in s:
+            self.text.yview(END)
+
+    def write(self, s):
+        self.text.insert(END, s)
+        if '\n' in s:
+            self.text.yview(END)
+            self.panel.update()
+
+
+class MultiPanel:
+
+    def __init__(self, parent):
+        self.parent = parent
+        self.frame = Frame(self.parent)
+        self.frame.pack(expand=1, fill=BOTH)
+        self.topframe = Frame(self.frame, borderwidth=2, relief=RAISED)
+        self.topframe.pack(fill=X)
+        self.botframe = Frame(self.frame)
+        self.botframe.pack(expand=1, fill=BOTH)
+        self.panelnames = []
+        self.panels = {}
+
+    def addpanel(self, name, on=0):
+        v = StringVar(self.parent)
+        if on:
+            v.set(name)
+        else:
+            v.set("")
+        check = Checkbutton(self.topframe, text=name,
+                            offvalue="", onvalue=name, variable=v,
+                            command=self.checkpanel)
+        check.pack(side=LEFT)
+        panel = Frame(self.botframe)
+        label = Label(panel, text=name, borderwidth=2, relief=RAISED, anchor=W)
+        label.pack(side=TOP, fill=X)
+        t = v, check, panel
+        self.panelnames.append(name)
+        self.panels[name] = t
+        if on:
+            panel.pack(expand=1, fill=BOTH)
+        return panel
+
+    def showpanel(self, name):
+        v, check, panel = self.panels[name]
+        v.set(name)
+        panel.pack(expand=1, fill=BOTH)
+
+    def hidepanel(self, name):
+        v, check, panel = self.panels[name]
+        v.set("")
+        panel.pack_forget()
+
+    def checkpanel(self):
+        for name in self.panelnames:
+            v, check, panel = self.panels[name]
+            panel.pack_forget()
+        for name in self.panelnames:
+            v, check, panel = self.panels[name]
+            if v.get():
+                panel.pack(expand=1, fill=BOTH)
+
+
+if __name__ == '__main__':
+    main()


Property changes on: vendor/Python/current/Tools/webchecker/wcgui.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/webchecker/wcmac.py
===================================================================
--- vendor/Python/current/Tools/webchecker/wcmac.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/webchecker/wcmac.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,7 @@
+import webchecker, sys
+webchecker.DEFROOT = "http://www.python.org/python/"
+webchecker.MAXPAGE = 50000
+webchecker.verbose = 2
+sys.argv.append('-x')
+webchecker.main()
+raw_input("\nCR to exit: ")

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


Property changes on: vendor/Python/current/Tools/webchecker/webchecker.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/webchecker/websucker.py
===================================================================
--- vendor/Python/current/Tools/webchecker/websucker.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/webchecker/websucker.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,125 @@
+#! /usr/bin/env python
+
+"""A variant on webchecker that creates a mirror copy of a remote site."""
+
+__version__ = "$Revision: 28654 $"
+
+import os
+import sys
+import urllib
+import getopt
+
+import webchecker
+
+# Extract real version number if necessary
+if __version__[0] == '$':
+    _v = __version__.split()
+    if len(_v) == 3:
+        __version__ = _v[1]
+
+def main():
+    verbose = webchecker.VERBOSE
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], "qv")
+    except getopt.error, msg:
+        print msg
+        print "usage:", sys.argv[0], "[-qv] ... [rooturl] ..."
+        return 2
+    for o, a in opts:
+        if o == "-q":
+            verbose = 0
+        if o == "-v":
+            verbose = verbose + 1
+    c = Sucker()
+    c.setflags(verbose=verbose)
+    c.urlopener.addheaders = [
+            ('User-agent', 'websucker/%s' % __version__),
+        ]
+    for arg in args:
+        print "Adding root", arg
+        c.addroot(arg)
+    print "Run..."
+    c.run()
+
+class Sucker(webchecker.Checker):
+
+    checkext = 0
+    nonames = 1
+
+    # SAM 11/13/99: in general, URLs are now URL pairs.
+    # Since we've suppressed name anchor checking,
+    # we can ignore the second dimension.
+
+    def readhtml(self, url_pair):
+        url = url_pair[0]
+        text = None
+        path = self.savefilename(url)
+        try:
+            f = open(path, "rb")
+        except IOError:
+            f = self.openpage(url_pair)
+            if f:
+                info = f.info()
+                nurl = f.geturl()
+                if nurl != url:
+                    url = nurl
+                    path = self.savefilename(url)
+                text = f.read()
+                f.close()
+                self.savefile(text, path)
+                if not self.checkforhtml(info, url):
+                    text = None
+        else:
+            if self.checkforhtml({}, url):
+                text = f.read()
+            f.close()
+        return text, url
+
+    def savefile(self, text, path):
+        dir, base = os.path.split(path)
+        makedirs(dir)
+        try:
+            f = open(path, "wb")
+            f.write(text)
+            f.close()
+            self.message("saved %s", path)
+        except IOError, msg:
+            self.message("didn't save %s: %s", path, str(msg))
+
+    def savefilename(self, url):
+        type, rest = urllib.splittype(url)
+        host, path = urllib.splithost(rest)
+        path = path.lstrip("/")
+        user, host = urllib.splituser(host)
+        host, port = urllib.splitnport(host)
+        host = host.lower()
+        if not path or path[-1] == "/":
+            path = path + "index.html"
+        if os.sep != "/":
+            path = os.sep.join(path.split("/"))
+            if os.name == "mac":
+                path = os.sep + path
+        path = os.path.join(host, path)
+        return path
+
+def makedirs(dir):
+    if not dir:
+        return
+    if os.path.exists(dir):
+        if not os.path.isdir(dir):
+            try:
+                os.rename(dir, dir + ".bak")
+                os.mkdir(dir)
+                os.rename(dir + ".bak", os.path.join(dir, "index.html"))
+            except os.error:
+                pass
+        return
+    head, tail = os.path.split(dir)
+    if not tail:
+        print "Huh?  Don't know how to make dir", dir
+        return
+    makedirs(head)
+    os.mkdir(dir, 0777)
+
+if __name__ == '__main__':
+    sys.exit(main() or 0)


Property changes on: vendor/Python/current/Tools/webchecker/websucker.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/webchecker/wsgui.py
===================================================================
--- vendor/Python/current/Tools/webchecker/wsgui.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/webchecker/wsgui.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,242 @@
+#! /usr/bin/env python
+
+"""Tkinter-based GUI for websucker.
+
+Easy use: type or paste source URL and destination directory in
+their respective text boxes, click GO or hit return, and presto.
+"""
+
+from Tkinter import *
+import Tkinter
+import websucker
+import sys
+import os
+import threading
+import Queue
+import time
+
+VERBOSE = 2
+
+
+try:
+    class Canceled(Exception):
+        "Exception used to cancel run()."
+except (NameError, TypeError):
+    Canceled = __name__ + ".Canceled"
+
+
+class SuckerThread(websucker.Sucker):
+
+    stopit = 0
+    savedir = None
+    rootdir = None
+
+    def __init__(self, msgq):
+        self.msgq = msgq
+        websucker.Sucker.__init__(self)
+        self.setflags(verbose=VERBOSE)
+        self.urlopener.addheaders = [
+            ('User-agent', 'websucker/%s' % websucker.__version__),
+        ]
+
+    def message(self, format, *args):
+        if args:
+            format = format%args
+        ##print format
+        self.msgq.put(format)
+
+    def run1(self, url):
+        try:
+            try:
+                self.reset()
+                self.addroot(url)
+                self.run()
+            except Canceled:
+                self.message("[canceled]")
+            else:
+                self.message("[done]")
+        finally:
+            self.msgq.put(None)
+
+    def savefile(self, text, path):
+        if self.stopit:
+            raise Canceled
+        websucker.Sucker.savefile(self, text, path)
+
+    def getpage(self, url):
+        if self.stopit:
+            raise Canceled
+        return websucker.Sucker.getpage(self, url)
+
+    def savefilename(self, url):
+        path = websucker.Sucker.savefilename(self, url)
+        if self.savedir:
+            n = len(self.rootdir)
+            if path[:n] == self.rootdir:
+                path = path[n:]
+                while path[:1] == os.sep:
+                    path = path[1:]
+                path = os.path.join(self.savedir, path)
+        return path
+
+    def XXXaddrobot(self, *args):
+        pass
+
+    def XXXisallowed(self, *args):
+        return 1
+
+
+class App:
+
+    sucker = None
+    msgq = None
+
+    def __init__(self, top):
+        self.top = top
+        top.columnconfigure(99, weight=1)
+        self.url_label = Label(top, text="URL:")
+        self.url_label.grid(row=0, column=0, sticky='e')
+        self.url_entry = Entry(top, width=60, exportselection=0)
+        self.url_entry.grid(row=0, column=1, sticky='we',
+                    columnspan=99)
+        self.url_entry.focus_set()
+        self.url_entry.bind("<Key-Return>", self.go)
+        self.dir_label = Label(top, text="Directory:")
+        self.dir_label.grid(row=1, column=0, sticky='e')
+        self.dir_entry = Entry(top)
+        self.dir_entry.grid(row=1, column=1, sticky='we',
+                    columnspan=99)
+        self.go_button = Button(top, text="Go", command=self.go)
+        self.go_button.grid(row=2, column=1, sticky='w')
+        self.cancel_button = Button(top, text="Cancel",
+                        command=self.cancel,
+                                    state=DISABLED)
+        self.cancel_button.grid(row=2, column=2, sticky='w')
+        self.auto_button = Button(top, text="Paste+Go",
+                      command=self.auto)
+        self.auto_button.grid(row=2, column=3, sticky='w')
+        self.status_label = Label(top, text="[idle]")
+        self.status_label.grid(row=2, column=4, sticky='w')
+        self.top.update_idletasks()
+        self.top.grid_propagate(0)
+
+    def message(self, text, *args):
+        if args:
+            text = text % args
+        self.status_label.config(text=text)
+
+    def check_msgq(self):
+        while not self.msgq.empty():
+            msg = self.msgq.get()
+            if msg is None:
+                self.go_button.configure(state=NORMAL)
+                self.auto_button.configure(state=NORMAL)
+                self.cancel_button.configure(state=DISABLED)
+                if self.sucker:
+                    self.sucker.stopit = 0
+                self.top.bell()
+            else:
+                self.message(msg)
+        self.top.after(100, self.check_msgq)
+
+    def go(self, event=None):
+        if not self.msgq:
+            self.msgq = Queue.Queue(0)
+            self.check_msgq()
+        if not self.sucker:
+            self.sucker = SuckerThread(self.msgq)
+        if self.sucker.stopit:
+            return
+        self.url_entry.selection_range(0, END)
+        url = self.url_entry.get()
+        url = url.strip()
+        if not url:
+            self.top.bell()
+            self.message("[Error: No URL entered]")
+            return
+        self.rooturl = url
+        dir = self.dir_entry.get().strip()
+        if not dir:
+            self.sucker.savedir = None
+        else:
+            self.sucker.savedir = dir
+            self.sucker.rootdir = os.path.dirname(
+                websucker.Sucker.savefilename(self.sucker, url))
+        self.go_button.configure(state=DISABLED)
+        self.auto_button.configure(state=DISABLED)
+        self.cancel_button.configure(state=NORMAL)
+        self.message( '[running...]')
+        self.sucker.stopit = 0
+        t = threading.Thread(target=self.sucker.run1, args=(url,))
+        t.start()
+
+    def cancel(self):
+        if self.sucker:
+            self.sucker.stopit = 1
+        self.message("[canceling...]")
+
+    def auto(self):
+        tries = ['PRIMARY', 'CLIPBOARD']
+        text = ""
+        for t in tries:
+            try:
+                text = self.top.selection_get(selection=t)
+            except TclError:
+                continue
+            text = text.strip()
+            if text:
+                break
+        if not text:
+            self.top.bell()
+            self.message("[Error: clipboard is empty]")
+            return
+        self.url_entry.delete(0, END)
+        self.url_entry.insert(0, text)
+        self.go()
+
+
+class AppArray:
+
+    def __init__(self, top=None):
+        if not top:
+            top = Tk()
+            top.title("websucker GUI")
+            top.iconname("wsgui")
+            top.wm_protocol('WM_DELETE_WINDOW', self.exit)
+        self.top = top
+        self.appframe = Frame(self.top)
+        self.appframe.pack(fill='both')
+        self.applist = []
+        self.exit_button = Button(top, text="Exit", command=self.exit)
+        self.exit_button.pack(side=RIGHT)
+        self.new_button = Button(top, text="New", command=self.addsucker)
+        self.new_button.pack(side=LEFT)
+        self.addsucker()
+        ##self.applist[0].url_entry.insert(END, "http://www.python.org/doc/essays/")
+
+    def addsucker(self):
+        self.top.geometry("")
+        frame = Frame(self.appframe, borderwidth=2, relief=GROOVE)
+        frame.pack(fill='x')
+        app = App(frame)
+        self.applist.append(app)
+
+    done = 0
+
+    def mainloop(self):
+        while not self.done:
+            time.sleep(0.1)
+            self.top.update()
+
+    def exit(self):
+        for app in self.applist:
+            app.cancel()
+            app.message("[exiting...]")
+        self.done = 1
+
+
+def main():
+    AppArray().mainloop()
+
+if __name__ == '__main__':
+    main()


Property changes on: vendor/Python/current/Tools/webchecker/wsgui.py
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/Tools/world/README
===================================================================
--- vendor/Python/current/Tools/world/README	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/world/README	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,85 @@
+world -- Print mappings between country names and DNS country codes.
+
+Contact: Barry Warsaw
+Email:   bwarsaw at python.org
+
+This script will take a list of Internet addresses and print out where in the
+world those addresses originate from, based on the top-level domain country
+code found in the address.  Addresses can be in any of the following forms:
+
+    xx                -- just the country code or top-level domain identifier
+    host.domain.xx    -- any Internet host or network name
+    somebody at where.xx -- an Internet email address
+
+If no match is found, the address is interpreted as a regular expression [*]
+and a reverse lookup is attempted.  This script will search the country names
+and print a list of matching entries.  You can force reverse mappings with the
+`-r' flag (see below).
+
+For example:
+
+    %% world tz us
+    tz originated from Tanzania, United Republic of
+    us originated from United States
+
+    %% world united
+    united matches 6 countries:
+        ae: United Arab Emirates
+        uk: United Kingdom (common practice)
+        um: United States Minor Outlying Islands
+        us: United States
+        tz: Tanzania, United Republic of
+        gb: United Kingdom
+
+
+ [*] Note that regular expressions must conform to Python 1.5's re.py module
+ syntax.  The comparison is done with the search() method.
+
+Country codes are maintained by the RIPE Network Coordination Centre,
+in coordination with the ISO 3166 Maintenance Agency at DIN Berlin.  The
+authoritative source of counry code mappings is:
+
+    <url:ftp://info.ripe.net/iso3166-countrycodes>
+
+The latest known change to this information was:
+
+    Thu Aug  7 17:59:51 MET DST 1997
+
+This script also knows about non-geographic top-level domains.
+
+Usage: world [-d] [-p file] [-o] [-h] addr [addr ...]
+
+    --dump
+    -d
+        Print mapping of all top-level domains.
+
+    --parse file
+    -p file
+        Parse an iso3166-countrycodes file extracting the two letter country
+        code followed by the country name.  Note that the three letter country
+        codes and numbers, which are also provided in the standard format
+        file, are ignored.
+
+    --outputdict
+    -o
+        When used in conjunction with the `-p' option, output is in the form
+        of a Python dictionary, and country names are normalized
+        w.r.t. capitalization.  This makes it appropriate for cutting and
+        pasting back into this file.
+
+    --reverse
+    -r
+        Force reverse lookup.  In this mode the address can be any Python
+        regular expression; this is matched against all country names and a
+        list of matching mappings is printed.  In normal mode (e.g. without
+        this flag), reverse lookup is performed on addresses if no matching
+        country code is found.
+
+    -h
+    --help
+        Print this message.
+
+
+Local Variables:
+indent-tabs-mode: nil
+End:

Added: vendor/Python/current/Tools/world/world
===================================================================
--- vendor/Python/current/Tools/world/world	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/Tools/world/world	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,551 @@
+#! /usr/bin/env python
+
+"""world -- Print mappings between country names and DNS country codes.
+
+Contact: Barry Warsaw
+Email:   barry at python.org
+Version: %(__version__)s
+
+This script will take a list of Internet addresses and print out where in the
+world those addresses originate from, based on the top-level domain country
+code found in the address.  Addresses can be in any of the following forms:
+
+    xx                -- just the country code or top-level domain identifier
+    host.domain.xx    -- any Internet host or network name
+    somebody at where.xx -- an Internet email address
+
+If no match is found, the address is interpreted as a regular expression and a
+reverse lookup is attempted.  This script will search the country names and
+print a list of matching entries.  You can force reverse mappings with the
+`-r' flag (see below).
+
+For example:
+
+    %% world tz us
+    tz originated from Tanzania, United Republic of
+    us originated from United States
+
+    %% world united
+    united matches 6 countries:
+        ae: United Arab Emirates
+        uk: United Kingdom (common practice)
+        um: United States Minor Outlying Islands
+        us: United States
+        tz: Tanzania, United Republic of
+        gb: United Kingdom
+
+Country codes are maintained by the RIPE Network Coordination Centre,
+in coordination with the ISO 3166 Maintenance Agency at DIN Berlin.  The
+authoritative source of country code mappings is:
+
+    <url:ftp://ftp.ripe.net/iso3166-countrycodes.txt>
+
+The latest known change to this information was:
+
+    Friday, 5 April 2002, 12.00 CET 2002
+
+This script also knows about non-geographic top-level domains, and the
+additional ccTLDs reserved by IANA.
+
+Usage: %(PROGRAM)s [-d] [-p file] [-o] [-h] addr [addr ...]
+
+    --dump
+    -d
+        Print mapping of all top-level domains.
+
+    --parse file
+    -p file
+        Parse an iso3166-countrycodes file extracting the two letter country
+        code followed by the country name.  Note that the three letter country
+        codes and numbers, which are also provided in the standard format
+        file, are ignored.
+
+    --outputdict
+    -o
+        When used in conjunction with the `-p' option, output is in the form
+        of a Python dictionary, and country names are normalized
+        w.r.t. capitalization.  This makes it appropriate for cutting and
+        pasting back into this file.  Output is always to standard out.
+
+    --reverse
+    -r
+        Force reverse lookup.  In this mode the address can be any Python
+        regular expression; this is matched against all country names and a
+        list of matching mappings is printed.  In normal mode (e.g. without
+        this flag), reverse lookup is performed on addresses if no matching
+        country code is found.
+
+    -h
+    --help
+        Print this message.
+"""
+__version__ = '$Revision: 27624 $'
+
+
+import sys
+import getopt
+import re
+
+PROGRAM = sys.argv[0]
+
+
+
+def usage(code, msg=''):
+    print __doc__ % globals()
+    if msg:
+        print msg
+    sys.exit(code)
+
+
+
+def resolve(rawaddr):
+    parts = rawaddr.split('.')
+    if not len(parts):
+        # no top level domain found, bounce it to the next step
+        return rawaddr
+    addr = parts[-1]
+    if nameorgs.has_key(addr):
+        print rawaddr, 'is in the', nameorgs[addr], 'top level domain'
+        return None
+    elif countries.has_key(addr):
+        print rawaddr, 'originated from', countries[addr]
+        return None
+    else:
+        # Not resolved, bounce it to the next step
+        return rawaddr
+
+
+
+def reverse(regexp):
+    matches = []
+    cre = re.compile(regexp, re.IGNORECASE)
+    for code, country in all.items():
+        mo = cre.search(country)
+        if mo:
+            matches.append(code)
+    # print results
+    if not matches:
+        # not resolved, bounce it to the next step
+        return regexp
+    if len(matches) == 1:
+        code = matches[0]
+        print regexp, "matches code `%s', %s" % (code, all[code])
+    else:
+        print regexp, 'matches %d countries:' % len(matches)
+        for code in matches:
+            print "    %s: %s" % (code, all[code])
+    return None
+
+
+
+def parse(file, normalize):
+    try:
+        fp = open(file)
+    except IOError, (err, msg):
+        print msg, ':', file
+
+    cre = re.compile('(.*?)[ \t]+([A-Z]{2})[ \t]+[A-Z]{3}[ \t]+[0-9]{3}')
+    scanning = 0
+
+    if normalize:
+        print 'countries = {'
+
+    while 1:
+        line = fp.readline()
+        if line == '':
+            break                       # EOF
+        if scanning:
+            mo = cre.match(line)
+            if not mo:
+                line = line.strip()
+                if not line:
+                    continue
+                elif line[0] == '-':
+                    break
+                else:
+                    print 'Could not parse line:', line
+                    continue
+            country, code = mo.group(1, 2)
+            if normalize:
+                words = country.split()
+                for i in range(len(words)):
+                    w = words[i]
+                    # XXX special cases
+                    if w in ('AND', 'OF', 'OF)', 'name:', 'METROPOLITAN'):
+                        words[i] = w.lower()
+                    elif w == 'THE' and i <> 1:
+                        words[i] = w.lower()
+                    elif len(w) > 3 and w[1] == "'":
+                        words[i] = w[0:3].upper() + w[3:].lower()
+                    elif w in ('(U.S.)', 'U.S.'):
+                        pass
+                    elif w[0] == '(' and w <> '(local':
+                        words[i] = '(' + w[1:].capitalize()
+                    elif w.find('-') <> -1:
+                        words[i] = '-'.join(
+                            [s.capitalize() for s in w.split('-')])
+                    else:
+                        words[i] = w.capitalize()
+                code = code.lower()
+                country = ' '.join(words)
+                print '    "%s": "%s",' % (code, country)
+            else:
+                print code, country
+            
+        elif line[0] == '-':
+            scanning = 1
+
+    if normalize:
+        print '    }'
+
+
+def main():
+    help = 0
+    status = 0
+    dump = 0
+    parsefile = None
+    normalize = 0
+    forcerev = 0
+
+    try:
+        opts, args = getopt.getopt(
+            sys.argv[1:],
+            'p:rohd',
+            ['parse=', 'reverse', 'outputdict', 'help', 'dump'])
+    except getopt.error, msg:
+        usage(1, msg)
+
+    for opt, arg in opts:
+        if opt in ('-h', '--help'):
+            help = 1
+        elif opt in ('-d', '--dump'):
+            dump = 1
+        elif opt in ('-p', '--parse'):
+            parsefile = arg
+        elif opt in ('-o', '--outputdict'):
+            normalize = 1
+        elif opt in ('-r', '--reverse'):
+            forcerev = 1
+
+    if help:
+        usage(status)
+
+    if dump:
+        print 'Non-geographic domains:'
+        codes = nameorgs.keys()
+        codes.sort()
+        for code in codes:
+            print '    %4s:' % code, nameorgs[code]
+
+        print '\nCountry coded domains:'
+        codes = countries.keys()
+        codes.sort()
+        for code in codes:
+            print '    %2s:' % code, countries[code]
+    elif parsefile:
+        parse(parsefile, normalize)
+    else:
+        if not forcerev:
+            args = filter(None, map(resolve, args))
+        args = filter(None, map(reverse, args))
+        for arg in args:
+            print 'Where in the world is %s?' % arg
+
+
+
+# The mappings
+nameorgs = {
+    # New top level domains as described by ICANN
+    # http://www.icann.org/tlds/
+    "aero": "air-transport industry",
+    "arpa": "Arpanet",
+    "biz": "business",
+    "com": "commercial",
+    "coop": "cooperatives",
+    "edu": "educational",
+    "gov": "government",
+    "info": "unrestricted `info'",
+    "int": "international",
+    "mil": "military",
+    "museum": "museums",
+    "name": "`name' (for registration by individuals)",
+    "net": "networking",
+    "org": "non-commercial",
+    "pro": "professionals",
+    # These additional ccTLDs are included here even though they are not part
+    # of ISO 3166.  IANA has 5 reserved ccTLDs as described here:
+    #
+    # http://www.iso.org/iso/en/prods-services/iso3166ma/04background-on-iso-3166/iso3166-1-and-ccTLDs.html
+    #
+    # but I can't find an official list anywhere.
+    #
+    # Note that `uk' is the common practice country code for the United
+    # Kingdom.  AFAICT, the official `gb' code is routinely ignored!
+    #
+    # <D.M.Pick at qmw.ac.uk> tells me that `uk' was long in use before ISO3166
+    # was adopted for top-level DNS zone names (although in the reverse order
+    # like uk.ac.qmw) and was carried forward (with the reversal) to avoid a
+    # large-scale renaming process as the UK switched from their old `Coloured
+    # Book' protocols over X.25 to Internet protocols over IP.
+    #
+    # See <url:ftp://ftp.ripe.net/ripe/docs/ripe-159.txt>
+    #
+    # Also, `su', while obsolete is still in limited use.
+    "ac": "Ascension Island",
+    "gg": "Guernsey",
+    "im": "Isle of Man",
+    "je": "Jersey",
+    "uk": "United Kingdom (common practice)",
+    "su": "Soviet Union (still in limited use)",
+    }
+
+
+
+countries = {
+    "af": "Afghanistan",
+    "al": "Albania",
+    "dz": "Algeria",
+    "as": "American Samoa",
+    "ad": "Andorra",
+    "ao": "Angola",
+    "ai": "Anguilla",
+    "aq": "Antarctica",
+    "ag": "Antigua and Barbuda",
+    "ar": "Argentina",
+    "am": "Armenia",
+    "aw": "Aruba",
+    "au": "Australia",
+    "at": "Austria",
+    "az": "Azerbaijan",
+    "bs": "Bahamas",
+    "bh": "Bahrain",
+    "bd": "Bangladesh",
+    "bb": "Barbados",
+    "by": "Belarus",
+    "be": "Belgium",
+    "bz": "Belize",
+    "bj": "Benin",
+    "bm": "Bermuda",
+    "bt": "Bhutan",
+    "bo": "Bolivia",
+    "ba": "Bosnia and Herzegowina",
+    "bw": "Botswana",
+    "bv": "Bouvet Island",
+    "br": "Brazil",
+    "io": "British Indian Ocean Territory",
+    "bn": "Brunei Darussalam",
+    "bg": "Bulgaria",
+    "bf": "Burkina Faso",
+    "bi": "Burundi",
+    "kh": "Cambodia",
+    "cm": "Cameroon",
+    "ca": "Canada",
+    "cv": "Cape Verde",
+    "ky": "Cayman Islands",
+    "cf": "Central African Republic",
+    "td": "Chad",
+    "cl": "Chile",
+    "cn": "China",
+    "cx": "Christmas Island",
+    "cc": "Cocos (Keeling) Islands",
+    "co": "Colombia",
+    "km": "Comoros",
+    "cg": "Congo",
+    "cd": "Congo, The Democratic Republic of the",
+    "ck": "Cook Islands",
+    "cr": "Costa Rica",
+    "ci": "Cote D'Ivoire",
+    "hr": "Croatia",
+    "cu": "Cuba",
+    "cy": "Cyprus",
+    "cz": "Czech Republic",
+    "dk": "Denmark",
+    "dj": "Djibouti",
+    "dm": "Dominica",
+    "do": "Dominican Republic",
+    "tp": "East Timor",
+    "ec": "Ecuador",
+    "eg": "Egypt",
+    "sv": "El Salvador",
+    "gq": "Equatorial Guinea",
+    "er": "Eritrea",
+    "ee": "Estonia",
+    "et": "Ethiopia",
+    "fk": "Falkland Islands (Malvinas)",
+    "fo": "Faroe Islands",
+    "fj": "Fiji",
+    "fi": "Finland",
+    "fr": "France",
+    "gf": "French Guiana",
+    "pf": "French Polynesia",
+    "tf": "French Southern Territories",
+    "ga": "Gabon",
+    "gm": "Gambia",
+    "ge": "Georgia",
+    "de": "Germany",
+    "gh": "Ghana",
+    "gi": "Gibraltar",
+    "gr": "Greece",
+    "gl": "Greenland",
+    "gd": "Grenada",
+    "gp": "Guadeloupe",
+    "gu": "Guam",
+    "gt": "Guatemala",
+    "gn": "Guinea",
+    "gw": "Guinea-Bissau",
+    "gy": "Guyana",
+    "ht": "Haiti",
+    "hm": "Heard Island and Mcdonald Islands",
+    "va": "Holy See (Vatican City State)",
+    "hn": "Honduras",
+    "hk": "Hong Kong",
+    "hu": "Hungary",
+    "is": "Iceland",
+    "in": "India",
+    "id": "Indonesia",
+    "ir": "Iran, Islamic Republic of",
+    "iq": "Iraq",
+    "ie": "Ireland",
+    "il": "Israel",
+    "it": "Italy",
+    "jm": "Jamaica",
+    "jp": "Japan",
+    "jo": "Jordan",
+    "kz": "Kazakstan",
+    "ke": "Kenya",
+    "ki": "Kiribati",
+    "kp": "Korea, Democratic People's Republic of",
+    "kr": "Korea, Republic of",
+    "kw": "Kuwait",
+    "kg": "Kyrgyzstan",
+    "la": "Lao People's Democratic Republic",
+    "lv": "Latvia",
+    "lb": "Lebanon",
+    "ls": "Lesotho",
+    "lr": "Liberia",
+    "ly": "Libyan Arab Jamahiriya",
+    "li": "Liechtenstein",
+    "lt": "Lithuania",
+    "lu": "Luxembourg",
+    "mo": "Macau",
+    "mk": "Macedonia, The Former Yugoslav Republic of",
+    "mg": "Madagascar",
+    "mw": "Malawi",
+    "my": "Malaysia",
+    "mv": "Maldives",
+    "ml": "Mali",
+    "mt": "Malta",
+    "mh": "Marshall Islands",
+    "mq": "Martinique",
+    "mr": "Mauritania",
+    "mu": "Mauritius",
+    "yt": "Mayotte",
+    "mx": "Mexico",
+    "fm": "Micronesia, Federated States of",
+    "md": "Moldova, Republic of",
+    "mc": "Monaco",
+    "mn": "Mongolia",
+    "ms": "Montserrat",
+    "ma": "Morocco",
+    "mz": "Mozambique",
+    "mm": "Myanmar",
+    "na": "Namibia",
+    "nr": "Nauru",
+    "np": "Nepal",
+    "nl": "Netherlands",
+    "an": "Netherlands Antilles",
+    "nc": "New Caledonia",
+    "nz": "New Zealand",
+    "ni": "Nicaragua",
+    "ne": "Niger",
+    "ng": "Nigeria",
+    "nu": "Niue",
+    "nf": "Norfolk Island",
+    "mp": "Northern Mariana Islands",
+    "no": "Norway",
+    "om": "Oman",
+    "pk": "Pakistan",
+    "pw": "Palau",
+    "ps": "Palestinian Territory, Occupied",
+    "pa": "Panama",
+    "pg": "Papua New Guinea",
+    "py": "Paraguay",
+    "pe": "Peru",
+    "ph": "Philippines",
+    "pn": "Pitcairn",
+    "pl": "Poland",
+    "pt": "Portugal",
+    "pr": "Puerto Rico",
+    "qa": "Qatar",
+    "re": "Reunion",
+    "ro": "Romania",
+    "ru": "Russian Federation",
+    "rw": "Rwanda",
+    "sh": "Saint Helena",
+    "kn": "Saint Kitts and Nevis",
+    "lc": "Saint Lucia",
+    "pm": "Saint Pierre and Miquelon",
+    "vc": "Saint Vincent and the Grenadines",
+    "ws": "Samoa",
+    "sm": "San Marino",
+    "st": "Sao Tome and Principe",
+    "sa": "Saudi Arabia",
+    "sn": "Senegal",
+    "sc": "Seychelles",
+    "sl": "Sierra Leone",
+    "sg": "Singapore",
+    "sk": "Slovakia",
+    "si": "Slovenia",
+    "sb": "Solomon Islands",
+    "so": "Somalia",
+    "za": "South Africa",
+    "gs": "South Georgia and the South Sandwich Islands",
+    "es": "Spain",
+    "lk": "Sri Lanka",
+    "sd": "Sudan",
+    "sr": "Suriname",
+    "sj": "Svalbard and Jan Mayen",
+    "sz": "Swaziland",
+    "se": "Sweden",
+    "ch": "Switzerland",
+    "sy": "Syrian Arab Republic",
+    "tw": "Taiwan, Province of China",
+    "tj": "Tajikistan",
+    "tz": "Tanzania, United Republic of",
+    "th": "Thailand",
+    "tg": "Togo",
+    "tk": "Tokelau",
+    "to": "Tonga",
+    "tt": "Trinidad and Tobago",
+    "tn": "Tunisia",
+    "tr": "Turkey",
+    "tm": "Turkmenistan",
+    "tc": "Turks and Caicos Islands",
+    "tv": "Tuvalu",
+    "ug": "Uganda",
+    "ua": "Ukraine",
+    "ae": "United Arab Emirates",
+    "gb": "United Kingdom",
+    "us": "United States",
+    "um": "United States Minor Outlying Islands",
+    "uy": "Uruguay",
+    "uz": "Uzbekistan",
+    "vu": "Vanuatu",
+    "ve": "Venezuela",
+    "vn": "Viet Nam",
+    "vg": "Virgin Islands, British",
+    "vi": "Virgin Islands, U.S.",
+    "wf": "Wallis and Futuna",
+    "eh": "Western Sahara",
+    "ye": "Yemen",
+    "yu": "Yugoslavia",
+    "zm": "Zambia",
+    "zw": "Zimbabwe",
+    }
+
+all = nameorgs.copy()
+all.update(countries)
+
+
+if __name__ == '__main__':
+    main()


Property changes on: vendor/Python/current/Tools/world/world
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/configure.in
===================================================================
--- vendor/Python/current/configure.in	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/configure.in	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,3453 @@
+dnl Process this file with autoconf 2.0 or later to make a configure script.
+
+# Set VERSION so we only need to edit in one place (i.e., here)
+m4_define(PYTHON_VERSION, 2.5)
+
+AC_REVISION($Revision: 54284 $)
+AC_PREREQ(2.59)
+AC_INIT(python, PYTHON_VERSION, http://www.python.org/python-bugs)
+AC_CONFIG_SRCDIR([Include/object.h])
+AC_CONFIG_HEADER(pyconfig.h)
+
+dnl This is for stuff that absolutely must end up in pyconfig.h.
+dnl Please use pyport.h instead, if possible.
+AH_TOP([
+#ifndef Py_PYCONFIG_H
+#define Py_PYCONFIG_H
+])
+AH_BOTTOM([
+/* Define the macros needed if on a UnixWare 7.x system. */
+#if defined(__USLC__) && defined(__SCO_VERSION__)
+#define STRICT_SYSV_CURSES /* Don't use ncurses extensions */
+#endif
+
+#endif /*Py_PYCONFIG_H*/
+])
+
+# We don't use PACKAGE_ variables, and they cause conflicts
+# with other autoconf-based packages that include Python.h
+grep -v 'define PACKAGE_' <confdefs.h >confdefs.h.new
+rm confdefs.h
+mv confdefs.h.new confdefs.h
+
+AC_SUBST(VERSION)
+VERSION=PYTHON_VERSION
+
+AC_SUBST(SOVERSION)
+SOVERSION=1.0
+
+# The later defininition of _XOPEN_SOURCE disables certain features
+# on Linux, so we need _GNU_SOURCE to re-enable them (makedev, tm_zone).
+AC_DEFINE(_GNU_SOURCE, 1, [Define on Linux to activate all library features])
+
+# The later defininition of _XOPEN_SOURCE and _POSIX_C_SOURCE disables
+# certain features on NetBSD, so we need _NETBSD_SOURCE to re-enable
+# them.
+AC_DEFINE(_NETBSD_SOURCE, 1, [Define on NetBSD to activate all library features])
+
+# The later defininition of _XOPEN_SOURCE and _POSIX_C_SOURCE disables
+# certain features on FreeBSD, so we need __BSD_VISIBLE to re-enable
+# them.
+AC_DEFINE(__BSD_VISIBLE, 1, [Define on FreeBSD to activate all library features])
+
+# The later defininition of _XOPEN_SOURCE and _POSIX_C_SOURCE disables
+# u_int on Irix 5.3. Defining _BSD_TYPES brings it back.
+AC_DEFINE(_BSD_TYPES, 1, [Define on Irix to enable u_int])
+
+define_xopen_source=yes
+
+# Arguments passed to configure.
+AC_SUBST(CONFIG_ARGS)
+CONFIG_ARGS="$ac_configure_args"
+
+AC_ARG_ENABLE(universalsdk,
+	AC_HELP_STRING(--enable-universalsdk@<:@SDKDIR@:>@, Build agains Mac OS X 10.4u SDK (ppc/i386)),
+[
+	case $enableval in
+	yes)
+		enableval=/Developer/SDKs/MacOSX10.4u.sdk
+		;;
+	esac
+	case $enableval in
+	no)
+		UNIVERSALSDK=
+		enable_universalsdk=
+		;;
+	*)
+		UNIVERSALSDK=$enableval
+		;;
+	esac
+],[
+   	UNIVERSALSDK=
+	enable_universalsdk=
+])
+AC_SUBST(UNIVERSALSDK)
+
+dnl quadrigraphs "@<:@" and "@:>@" produce "[" and "]" in the output
+AC_ARG_ENABLE(framework,
+              AC_HELP_STRING(--enable-framework@<:@=INSTALLDIR@:>@, Build (MacOSX|Darwin) framework),
+[
+	case $enableval in
+	yes) 
+		enableval=/Library/Frameworks
+	esac
+	case $enableval in
+	no)
+		PYTHONFRAMEWORK=
+		PYTHONFRAMEWORKDIR=no-framework
+		PYTHONFRAMEWORKPREFIX=
+		PYTHONFRAMEWORKINSTALLDIR=
+		FRAMEWORKINSTALLFIRST=
+		FRAMEWORKINSTALLLAST=
+		FRAMEWORKALTINSTALLFIRST=
+		FRAMEWORKALTINSTALLLAST=
+		if test "x${prefix}" = "xNONE"; then
+			FRAMEWORKUNIXTOOLSPREFIX="${ac_default_prefix}"
+		else
+			FRAMEWORKUNIXTOOLSPREFIX="${prefix}"
+		fi
+		enable_framework=
+		;;
+	*)
+		PYTHONFRAMEWORK=Python
+		PYTHONFRAMEWORKDIR=Python.framework
+		PYTHONFRAMEWORKPREFIX=$enableval
+		PYTHONFRAMEWORKINSTALLDIR=$PYTHONFRAMEWORKPREFIX/$PYTHONFRAMEWORKDIR
+		FRAMEWORKINSTALLFIRST="frameworkinstallstructure"
+		FRAMEWORKINSTALLLAST="frameworkinstallmaclib frameworkinstallapps frameworkinstallunixtools"
+		FRAMEWORKALTINSTALLFIRST="${FRAMEWORKINSTALLFIRST} bininstall maninstall"
+		FRAMEWORKALTINSTALLLAST="frameworkinstallmaclib frameworkinstallapps frameworkaltinstallunixtools"
+		if test "x${prefix}" = "xNONE" ; then
+			FRAMEWORKUNIXTOOLSPREFIX="${ac_default_prefix}"
+		else
+			FRAMEWORKUNIXTOOLSPREFIX="${prefix}"
+		fi
+		prefix=$PYTHONFRAMEWORKINSTALLDIR/Versions/$VERSION
+
+		# Add makefiles for Mac specific code to the list of output
+		# files:
+		AC_CONFIG_FILES(Mac/Makefile)
+		AC_CONFIG_FILES(Mac/PythonLauncher/Makefile)
+		AC_CONFIG_FILES(Mac/IDLE/Makefile)
+	esac
+	],[
+	PYTHONFRAMEWORK=
+	PYTHONFRAMEWORKDIR=no-framework
+	PYTHONFRAMEWORKPREFIX=
+	PYTHONFRAMEWORKINSTALLDIR=
+	FRAMEWORKINSTALLFIRST=
+	FRAMEWORKINSTALLLAST=
+	FRAMEWORKALTINSTALLFIRST=
+	FRAMEWORKALTINSTALLLAST=
+	if test "x${prefix}" = "xNONE" ; then
+		FRAMEWORKUNIXTOOLSPREFIX="${ac_default_prefix}"
+	else
+		FRAMEWORKUNIXTOOLSPREFIX="${prefix}"
+	fi
+	enable_framework=
+])
+AC_SUBST(PYTHONFRAMEWORK)
+AC_SUBST(PYTHONFRAMEWORKDIR)
+AC_SUBST(PYTHONFRAMEWORKPREFIX)
+AC_SUBST(PYTHONFRAMEWORKINSTALLDIR)
+AC_SUBST(FRAMEWORKINSTALLFIRST)
+AC_SUBST(FRAMEWORKINSTALLLAST)
+AC_SUBST(FRAMEWORKALTINSTALLFIRST)
+AC_SUBST(FRAMEWORKALTINSTALLLAST)
+AC_SUBST(FRAMEWORKUNIXTOOLSPREFIX)
+
+##AC_ARG_WITH(dyld,
+##            AC_HELP_STRING(--with-dyld,
+##                           Use (OpenStep|Rhapsody) dynamic linker))
+##
+# Set name for machine-dependent library files
+AC_SUBST(MACHDEP)
+AC_MSG_CHECKING(MACHDEP)
+if test -z "$MACHDEP"
+then
+	ac_sys_system=`uname -s`
+	if test "$ac_sys_system" = "AIX" -o "$ac_sys_system" = "Monterey64" \
+	-o "$ac_sys_system" = "UnixWare" -o "$ac_sys_system" = "OpenUNIX"; then
+		ac_sys_release=`uname -v`
+	else
+		ac_sys_release=`uname -r`
+	fi
+	ac_md_system=`echo $ac_sys_system |
+			   tr -d '[/ ]' | tr '[[A-Z]]' '[[a-z]]'`
+	ac_md_release=`echo $ac_sys_release |
+			   tr -d '[/ ]' | sed 's/^[[A-Z]]\.//' | sed 's/\..*//'`
+	MACHDEP="$ac_md_system$ac_md_release"
+
+	case $MACHDEP in
+	cygwin*) MACHDEP="cygwin";;
+	darwin*) MACHDEP="darwin";;
+	atheos*) MACHDEP="atheos";;
+        irix646) MACHDEP="irix6";;
+	'')	MACHDEP="unknown";;
+	esac
+fi
+	
+# Some systems cannot stand _XOPEN_SOURCE being defined at all; they
+# disable features if it is defined, without any means to access these
+# features as extensions. For these systems, we skip the definition of
+# _XOPEN_SOURCE. Before adding a system to the list to gain access to
+# some feature, make sure there is no alternative way to access this
+# feature. Also, when using wildcards, make sure you have verified the
+# need for not defining _XOPEN_SOURCE on all systems matching the
+# wildcard, and that the wildcard does not include future systems
+# (which may remove their limitations).
+dnl quadrigraphs "@<:@" and "@:>@" produce "[" and "]" in the output
+case $ac_sys_system/$ac_sys_release in
+  # On OpenBSD, select(2) is not available if _XOPEN_SOURCE is defined,
+  # even though select is a POSIX function. Reported by J. Ribbens.
+  # Reconfirmed for OpenBSD 3.3 by Zachary Hamm, for 3.4 by Jason Ish.
+  OpenBSD/2.* | OpenBSD/3.@<:@0123456789@:>@ | OpenBSD/4.@<:@0@:>@) 
+    define_xopen_source=no;;
+  # Defining _XOPEN_SOURCE on NetBSD version prior to the introduction of
+  # _NETBSD_SOURCE disables certain features (eg. setgroups). Reported by
+  # Marc Recht
+  NetBSD/1.5 | NetBSD/1.5.* | NetBSD/1.6 | NetBSD/1.6.* | NetBSD/1.6[A-S])
+    define_xopen_source=no;;
+  # On Solaris 2.6, sys/wait.h is inconsistent in the usage
+  # of union __?sigval. Reported by Stuart Bishop.
+  SunOS/5.6)
+    define_xopen_source=no;;
+  # On UnixWare 7, u_long is never defined with _XOPEN_SOURCE,
+  # but used in /usr/include/netinet/tcp.h. Reported by Tim Rice.
+  # Reconfirmed for 7.1.4 by Martin v. Loewis.
+  OpenUNIX/8.0.0| UnixWare/7.1.@<:@0-4@:>@)
+    define_xopen_source=no;;
+  # On OpenServer 5, u_short is never defined with _XOPEN_SOURCE,
+  # but used in struct sockaddr.sa_family. Reported by Tim Rice.
+  SCO_SV/3.2)
+    define_xopen_source=no;;
+  # On FreeBSD 4.8 and MacOS X 10.2, a bug in ncurses.h means that
+  # it craps out if _XOPEN_EXTENDED_SOURCE is defined. Apparently,
+  # this is fixed in 10.3, which identifies itself as Darwin/7.*
+  # This should hopefully be fixed in FreeBSD 4.9
+  FreeBSD/4.8* | Darwin/6* )
+    define_xopen_source=no;;
+  # On AIX 4 and 5.1, mbstate_t is defined only when _XOPEN_SOURCE == 500 but
+  # used in wcsnrtombs() and mbsnrtowcs() even if _XOPEN_SOURCE is not defined
+  # or has another value. By not (re)defining it, the defaults come in place.
+  AIX/4)
+    define_xopen_source=no;;
+  AIX/5)
+    if test `uname -r` -eq 1; then
+      define_xopen_source=no
+    fi
+    ;;
+  # On Mac OS X 10.4, defining _POSIX_C_SOURCE or _XOPEN_SOURCE
+  # disables platform specific features beyond repair.
+  # On Mac OS X 10.3, defining _POSIX_C_SOURCE or _XOPEN_SOURCE 
+  # has no effect, don't bother defining them
+  Darwin/@<:@789@:>@.*)
+    define_xopen_source=no
+    ;;
+
+esac
+
+if test $define_xopen_source = yes
+then
+  # On Solaris w/ g++ it appears that _XOPEN_SOURCE has to be
+  # defined precisely as g++ defines it
+  # Furthermore, on Solaris 10, XPG6 requires the use of a C99
+  # compiler
+  case $ac_sys_system/$ac_sys_release in
+    SunOS/5.8|SunOS/5.9|SunOS/5.10)
+      AC_DEFINE(_XOPEN_SOURCE, 500, 
+                Define to the level of X/Open that your system supports)
+      ;;
+    *)
+      AC_DEFINE(_XOPEN_SOURCE, 600, 
+                Define to the level of X/Open that your system supports)
+      ;;
+  esac
+
+  # On Tru64 Unix 4.0F, defining _XOPEN_SOURCE also requires
+  # definition of _XOPEN_SOURCE_EXTENDED and _POSIX_C_SOURCE, or else
+  # several APIs are not declared. Since this is also needed in some
+  # cases for HP-UX, we define it globally.
+  # except for Solaris 10, where it must not be defined, 
+  # as it implies XPG4.2
+  case $ac_sys_system/$ac_sys_release in
+    SunOS/5.10)
+      ;;
+    *)
+      AC_DEFINE(_XOPEN_SOURCE_EXTENDED, 1,
+      		Define to activate Unix95-and-earlier features)
+      ;;
+  esac
+
+  AC_DEFINE(_POSIX_C_SOURCE, 200112L, Define to activate features from IEEE Stds 1003.1-2001)
+  
+fi
+
+#
+# SGI compilers allow the specification of the both the ABI and the
+# ISA on the command line.  Depending on the values of these switches,
+# different and often incompatable code will be generated.
+#
+# The SGI_ABI variable can be used to modify the CC and LDFLAGS and
+# thus supply support for various ABI/ISA combinations.  The MACHDEP
+# variable is also adjusted.
+#
+AC_SUBST(SGI_ABI)
+if test ! -z "$SGI_ABI"
+then
+        CC="cc $SGI_ABI"
+        LDFLAGS="$SGI_ABI $LDFLAGS"
+        MACHDEP=`echo "${MACHDEP}${SGI_ABI}" | sed 's/ *//g'`
+fi
+AC_MSG_RESULT($MACHDEP)
+
+# And add extra plat-mac for darwin
+AC_SUBST(EXTRAPLATDIR)
+AC_SUBST(EXTRAMACHDEPPATH)
+AC_MSG_CHECKING(EXTRAPLATDIR)
+if test -z "$EXTRAPLATDIR"
+then
+	case $MACHDEP in
+	darwin)	
+		EXTRAPLATDIR="\$(PLATMACDIRS)"
+		EXTRAMACHDEPPATH="\$(PLATMACPATH)"
+		;;
+	*) 
+		EXTRAPLATDIR=""
+		EXTRAMACHDEPPATH=""
+		;;
+	esac
+fi
+AC_MSG_RESULT($EXTRAPLATDIR)
+
+# Record the configure-time value of MACOSX_DEPLOYMENT_TARGET,
+# it may influence the way we can build extensions, so distutils
+# needs to check it
+AC_SUBST(CONFIGURE_MACOSX_DEPLOYMENT_TARGET)
+AC_SUBST(EXPORT_MACOSX_DEPLOYMENT_TARGET)
+CONFIGURE_MACOSX_DEPLOYMENT_TARGET=
+EXPORT_MACOSX_DEPLOYMENT_TARGET='#'
+
+# checks for alternative programs
+
+# compiler flags are generated in two sets, BASECFLAGS and OPT.  OPT is just
+# for debug/optimization stuff.  BASECFLAGS is for flags that are required
+# just to get things to compile and link.  Users are free to override OPT
+# when running configure or make.  The build should not break if they do.
+# BASECFLAGS should generally not be messed with, however.
+
+# XXX shouldn't some/most/all of this code be merged with the stuff later
+# on that fiddles with OPT and BASECFLAGS?
+AC_MSG_CHECKING(for --without-gcc)
+AC_ARG_WITH(gcc,
+            AC_HELP_STRING(--without-gcc,never use gcc),
+[
+	case $withval in
+	no)	CC=cc
+		without_gcc=yes;;
+	yes)	CC=gcc
+		without_gcc=no;;
+	*)	CC=$withval
+		without_gcc=$withval;;
+	esac], [
+	case $ac_sys_system in
+	AIX*)   CC=cc_r
+		without_gcc=;;
+	BeOS*)
+		case $BE_HOST_CPU in
+		ppc)
+			CC=mwcc
+			without_gcc=yes
+			BASECFLAGS="$BASECFLAGS -export pragma"
+			OPT="$OPT -O"
+			LDFLAGS="$LDFLAGS -nodup"
+			;;
+		x86)
+			CC=gcc
+			without_gcc=no
+			OPT="$OPT -O"
+			;;
+		*)
+			AC_MSG_ERROR([Unknown BeOS platform "$BE_HOST_CPU"])
+			;;
+		esac
+		AR="\$(srcdir)/Modules/ar_beos"
+		RANLIB=:
+		;;
+    Monterey*)
+        RANLIB=:
+        without_gcc=;;
+	*)	without_gcc=no;;
+	esac])
+AC_MSG_RESULT($without_gcc)
+
+# If the user switches compilers, we can't believe the cache
+if test ! -z "$ac_cv_prog_CC" -a ! -z "$CC" -a "$CC" != "$ac_cv_prog_CC"
+then
+  AC_MSG_ERROR([cached CC is different -- throw away $cache_file
+(it is also a good idea to do 'make clean' before compiling)])
+fi
+
+AC_PROG_CC
+
+AC_SUBST(CXX)
+AC_SUBST(MAINCC)
+AC_MSG_CHECKING(for --with-cxx-main=<compiler>)
+AC_ARG_WITH(cxx_main,
+            AC_HELP_STRING([--with-cxx-main=<compiler>],
+                           [compile main() and link python executable with C++ compiler]),
+[
+	
+	case $withval in
+	no)	with_cxx_main=no
+		MAINCC='$(CC)';;
+	yes)	with_cxx_main=yes
+		MAINCC='$(CXX)';;
+	*)	with_cxx_main=yes
+		MAINCC=$withval
+		if test -z "$CXX"
+		then
+			CXX=$withval
+		fi;;
+	esac], [
+	with_cxx_main=no
+	MAINCC='$(CC)'
+])
+AC_MSG_RESULT($with_cxx_main)
+
+preset_cxx="$CXX"
+if test -z "$CXX"
+then
+        case "$CC" in
+        gcc)    AC_PATH_PROG(CXX, [g++], [g++], [notfound]) ;;
+        cc)     AC_PATH_PROG(CXX, [c++], [c++], [notfound]) ;;
+        esac
+	if test "$CXX" = "notfound"
+	then
+		CXX=""
+	fi
+fi
+if test -z "$CXX"
+then
+	AC_CHECK_PROGS(CXX, $CCC c++ g++ gcc CC cxx cc++ cl, notfound)
+	if test "$CXX" = "notfound"
+	then
+		CXX=""
+	fi
+fi
+if test "$preset_cxx" != "$CXX"
+then
+        AC_MSG_WARN([
+
+  By default, distutils will build C++ extension modules with "$CXX".
+  If this is not intended, then set CXX on the configure command line.
+  ])
+fi
+
+
+# checks for UNIX variants that set C preprocessor variables
+AC_AIX
+
+# Check for unsupported systems
+case $ac_sys_system/$ac_sys_release in
+Linux*/1*)
+   echo This system \($ac_sys_system/$ac_sys_release\) is no longer supported.
+   echo See README for details.
+   exit 1;;
+esac
+
+AC_EXEEXT
+AC_MSG_CHECKING(for --with-suffix)
+AC_ARG_WITH(suffix,
+            AC_HELP_STRING(--with-suffix=.exe, set executable suffix),
+[
+	case $withval in
+	no)	EXEEXT=;;
+	yes)	EXEEXT=.exe;;
+	*)	EXEEXT=$withval;;
+	esac])
+AC_MSG_RESULT($EXEEXT)
+
+# Test whether we're running on a non-case-sensitive system, in which
+# case we give a warning if no ext is given
+AC_SUBST(BUILDEXEEXT)
+AC_MSG_CHECKING(for case-insensitive build directory)
+if test ! -d CaseSensitiveTestDir; then
+mkdir CaseSensitiveTestDir
+fi
+
+if test -d casesensitivetestdir
+then
+    AC_MSG_RESULT(yes)
+    BUILDEXEEXT=.exe
+else
+	AC_MSG_RESULT(no)
+	BUILDEXEEXT=$EXEEXT
+fi
+rmdir CaseSensitiveTestDir
+
+case $MACHDEP in
+bsdos*)
+    case $CC in
+    gcc) CC="$CC -D_HAVE_BSDI";;
+    esac;;
+esac
+
+case $ac_sys_system in
+hp*|HP*)
+    case $CC in
+    cc|*/cc) CC="$CC -Ae";;
+    esac;;
+Monterey*)
+    case $CC in
+    cc) CC="$CC -Wl,-Bexport";;
+    esac;;
+SunOS*)
+    # Some functions have a prototype only with that define, e.g. confstr
+    AC_DEFINE(__EXTENSIONS__, 1, [Defined on Solaris to see additional function prototypes.])
+    ;;
+esac
+
+
+AC_SUBST(LIBRARY)
+AC_MSG_CHECKING(LIBRARY)
+if test -z "$LIBRARY"
+then
+	LIBRARY='libpython$(VERSION).a'
+fi
+AC_MSG_RESULT($LIBRARY)
+
+# LDLIBRARY is the name of the library to link against (as opposed to the
+# name of the library into which to insert object files). BLDLIBRARY is also
+# the library to link against, usually. On Mac OS X frameworks, BLDLIBRARY
+# is blank as the main program is not linked directly against LDLIBRARY.
+# LDLIBRARYDIR is the path to LDLIBRARY, which is made in a subdirectory. On
+# systems without shared libraries, LDLIBRARY is the same as LIBRARY
+# (defined in the Makefiles). On Cygwin LDLIBRARY is the import library,
+# DLLLIBRARY is the shared (i.e., DLL) library.
+# 
+# RUNSHARED is used to run shared python without installed libraries
+#
+# INSTSONAME is the name of the shared library that will be use to install
+# on the system - some systems like version suffix, others don't
+AC_SUBST(LDLIBRARY)
+AC_SUBST(DLLLIBRARY)
+AC_SUBST(BLDLIBRARY)
+AC_SUBST(LDLIBRARYDIR)
+AC_SUBST(INSTSONAME)
+AC_SUBST(RUNSHARED)
+LDLIBRARY="$LIBRARY"
+BLDLIBRARY='$(LDLIBRARY)'
+INSTSONAME='$(LDLIBRARY)'
+DLLLIBRARY=''
+LDLIBRARYDIR=''
+RUNSHARED=''
+
+# LINKCC is the command that links the python executable -- default is $(CC).
+# If CXX is set, and if it is needed to link a main function that was
+# compiled with CXX, LINKCC is CXX instead. Always using CXX is undesirable:
+# python might then depend on the C++ runtime
+# This is altered for AIX in order to build the export list before 
+# linking.
+AC_SUBST(LINKCC)
+AC_MSG_CHECKING(LINKCC)
+if test -z "$LINKCC"
+then
+	LINKCC='$(PURIFY) $(MAINCC)'
+	case $ac_sys_system in
+	AIX*)
+	   exp_extra="\"\""
+	   if test $ac_sys_release -ge 5 -o \
+		   $ac_sys_release -eq 4 -a `uname -r` -ge 2 ; then
+	       exp_extra="."
+	   fi
+	   LINKCC="\$(srcdir)/Modules/makexp_aix Modules/python.exp $exp_extra \$(LIBRARY); $LINKCC";;
+	Monterey64*)
+	   LINKCC="$LINKCC -L/usr/lib/ia64l64";;
+	esac
+fi
+AC_MSG_RESULT($LINKCC)
+
+AC_MSG_CHECKING(for --enable-shared)
+AC_ARG_ENABLE(shared,
+              AC_HELP_STRING(--enable-shared, disable/enable building shared python library))
+
+if test -z "$enable_shared"
+then 
+  case $ac_sys_system in
+  CYGWIN* | atheos*)
+    enable_shared="yes";;
+  *)
+    enable_shared="no";;
+  esac
+fi
+AC_MSG_RESULT($enable_shared)
+
+AC_MSG_CHECKING(for --enable-profiling)
+AC_ARG_ENABLE(profiling,
+              AC_HELP_STRING(--enable-profiling, enable C-level code profiling),
+[ac_save_cc="$CC"
+ CC="$CC -pg"
+ AC_TRY_RUN([int main() { return 0; }],
+   ac_enable_profiling="yes",
+   ac_enable_profiling="no",
+   ac_enable_profiling="no")
+ CC="$ac_save_cc"])
+AC_MSG_RESULT($ac_enable_profiling)
+
+case "$ac_enable_profiling" in
+    "yes")
+	BASECFLAGS="-pg $BASECFLAGS"
+	LDFLAGS="-pg $LDFLAGS"
+    ;;
+esac
+
+AC_MSG_CHECKING(LDLIBRARY)
+
+# MacOSX framework builds need more magic. LDLIBRARY is the dynamic
+# library that we build, but we do not want to link against it (we
+# will find it with a -framework option). For this reason there is an
+# extra variable BLDLIBRARY against which Python and the extension
+# modules are linked, BLDLIBRARY. This is normally the same as
+# LDLIBRARY, but empty for MacOSX framework builds.
+if test "$enable_framework"
+then
+  LDLIBRARY='$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)'
+  RUNSHARED=DYLD_FRAMEWORK_PATH="`pwd`:$DYLD_FRAMEWORK_PATH"
+  BLDLIBRARY=''
+else
+  BLDLIBRARY='$(LDLIBRARY)'
+fi  
+
+# Other platforms follow
+if test $enable_shared = "yes"; then
+  AC_DEFINE(Py_ENABLE_SHARED, 1, [Defined if Python is built as a shared library.])
+  case $ac_sys_system in
+    BeOS*)
+          LDLIBRARY='libpython$(VERSION).so'
+          ;;
+    CYGWIN*)
+          LDLIBRARY='libpython$(VERSION).dll.a'
+          DLLLIBRARY='libpython$(VERSION).dll'
+          ;;
+    SunOS*)
+	  LDLIBRARY='libpython$(VERSION).so'
+	  BLDLIBRARY='-Wl,-R,$(LIBDIR) -L. -lpython$(VERSION)'
+	  RUNSHARED=LD_LIBRARY_PATH=`pwd`:${LD_LIBRARY_PATH}
+	  INSTSONAME="$LDLIBRARY".$SOVERSION
+          ;;
+    Linux*|GNU*|NetBSD*|FreeBSD*|DragonFly*)
+	  LDLIBRARY='libpython$(VERSION).so'
+	  BLDLIBRARY='-L. -lpython$(VERSION)'
+	  RUNSHARED=LD_LIBRARY_PATH=`pwd`:${LD_LIBRARY_PATH}
+	  case $ac_sys_system in
+	      FreeBSD*)
+		SOVERSION=`echo $SOVERSION|cut -d "." -f 1`
+		;;
+	  esac
+	  INSTSONAME="$LDLIBRARY".$SOVERSION
+	  ;;
+    hp*|HP*)
+	  case `uname -m` in
+		ia64)
+			LDLIBRARY='libpython$(VERSION).so'
+			;;
+		*)
+			LDLIBRARY='libpython$(VERSION).sl'
+			;;
+	  esac
+	  BLDLIBRARY='-Wl,+b,$(LIBDIR) -L. -lpython$(VERSION)'
+	  RUNSHARED=SHLIB_PATH=`pwd`:${SHLIB_PATH}
+	  ;;
+    OSF*)
+	  LDLIBRARY='libpython$(VERSION).so'
+	  BLDLIBRARY='-rpath $(LIBDIR) -L. -lpython$(VERSION)'
+	  RUNSHARED=LD_LIBRARY_PATH=`pwd`:${LD_LIBRARY_PATH}
+	  ;;
+    atheos*)
+	  LDLIBRARY='libpython$(VERSION).so'
+	  BLDLIBRARY='-L. -lpython$(VERSION)'
+	  RUNSHARED=DLL_PATH=`pwd`:${DLL_PATH:-/atheos/sys/libs:/atheos/autolnk/lib}
+	  ;;
+  esac
+else # shared is disabled
+  case $ac_sys_system in
+    CYGWIN*)
+          BLDLIBRARY='$(LIBRARY)'
+          LDLIBRARY='libpython$(VERSION).dll.a'
+          ;;
+  esac
+fi
+
+AC_MSG_RESULT($LDLIBRARY)
+
+AC_PROG_RANLIB
+AC_SUBST(AR)
+AC_CHECK_PROGS(AR, ar aal, ar)
+
+AC_SUBST(SVNVERSION)
+AC_CHECK_PROG(SVNVERSION, svnversion, found, not-found)
+if test $SVNVERSION = found
+then
+	SVNVERSION="svnversion \$(srcdir)"
+else
+	SVNVERSION="echo exported"
+fi
+
+case $MACHDEP in
+bsdos*|hp*|HP*)
+	# install -d does not work on BSDI or HP-UX
+	if test -z "$INSTALL"
+	then
+		INSTALL="${srcdir}/install-sh -c"
+	fi
+esac
+AC_PROG_INSTALL
+
+# Not every filesystem supports hard links
+AC_SUBST(LN)
+if test -z "$LN" ; then
+	case $ac_sys_system in
+		BeOS*) LN="ln -s";;
+		CYGWIN*) LN="ln -s";;
+		atheos*) LN="ln -s";;
+		*) LN=ln;;
+	esac
+fi
+
+# Check for --with-pydebug
+AC_MSG_CHECKING(for --with-pydebug)
+AC_ARG_WITH(pydebug, 
+            AC_HELP_STRING(--with-pydebug, build with Py_DEBUG defined),
+[
+if test "$withval" != no
+then 
+  AC_DEFINE(Py_DEBUG, 1, 
+  [Define if you want to build an interpreter with many run-time checks.]) 
+  AC_MSG_RESULT(yes); 
+  Py_DEBUG='true'
+else AC_MSG_RESULT(no); Py_DEBUG='false'
+fi],
+[AC_MSG_RESULT(no)])
+
+# XXX Shouldn't the code above that fiddles with BASECFLAGS and OPT be
+# merged with this chunk of code?
+
+# Optimizer/debugger flags
+# ------------------------
+# (The following bit of code is complicated enough - please keep things
+# indented properly.  Just pretend you're editing Python code. ;-)
+
+# There are two parallel sets of case statements below, one that checks to
+# see if OPT was set and one that does BASECFLAGS setting based upon
+# compiler and platform.  BASECFLAGS tweaks need to be made even if the
+# user set OPT.
+
+# tweak OPT based on compiler and platform, only if the user didn't set
+# it on the command line
+AC_SUBST(OPT)
+if test -z "$OPT"
+then
+    case $GCC in
+    yes)
+        if test "$CC" != 'g++' ; then
+	    STRICT_PROTO="-Wstrict-prototypes"
+	fi
+	case $ac_cv_prog_cc_g in
+	yes)
+	    if test "$Py_DEBUG" = 'true' ; then
+		# Optimization messes up debuggers, so turn it off for
+		# debug builds.
+		OPT="-g -Wall $STRICT_PROTO"
+	    else
+		OPT="-g -O3 -Wall $STRICT_PROTO"
+	    fi
+	    ;;
+	*)
+	    OPT="-O3 -Wall $STRICT_PROTO"
+	    ;;
+	esac
+	case $ac_sys_system in
+	    SCO_SV*) OPT="$OPT -m486 -DSCO5"
+	    ;;
+        esac
+	;;
+
+    *)
+	OPT="-O"
+	;;
+    esac
+
+    # The current (beta) Monterey compiler dies with optimizations
+    # XXX what is Monterey? Does it still die w/ -O? Can we get rid of this?
+    case $ac_sys_system in
+	Monterey*)
+	    OPT=""
+	    ;;
+    esac
+
+fi
+
+AC_SUBST(BASECFLAGS)
+# tweak BASECFLAGS based on compiler and platform
+case $GCC in
+yes)
+    # Python violates C99 rules, by casting between incompatible
+    # pointer types. GCC may generate bad code as a result of that,
+    # so use -fno-strict-aliasing if supported.
+    AC_MSG_CHECKING(whether $CC accepts -fno-strict-aliasing)
+     ac_save_cc="$CC"
+     CC="$CC -fno-strict-aliasing"
+     AC_TRY_RUN([int main() { return 0; }],
+     ac_cv_no_strict_aliasing_ok=yes,
+     ac_cv_no_strict_aliasing_ok=no,
+     ac_cv_no_strict_aliasing_ok=no)
+     CC="$ac_save_cc"
+    AC_MSG_RESULT($ac_cv_no_strict_aliasing_ok)
+    if test $ac_cv_no_strict_aliasing_ok = yes
+    then
+      BASECFLAGS="$BASECFLAGS -fno-strict-aliasing"
+    fi
+    case $ac_sys_system in
+	SCO_SV*)
+	    BASECFLAGS="$BASECFLAGS -m486 -DSCO5"
+	    ;;
+	# is there any other compiler on Darwin besides gcc?
+	Darwin*)
+	    BASECFLAGS="$BASECFLAGS -Wno-long-double -no-cpp-precomp -mno-fused-madd"
+	    if test "${enable_universalsdk}"; then
+		BASECFLAGS="-arch ppc -arch i386 -isysroot ${UNIVERSALSDK} ${BASECFLAGS}"
+	    fi
+
+	    ;;
+	OSF*)
+	    BASECFLAGS="$BASECFLAGS -mieee"
+	    ;;
+    esac
+    ;;
+
+*)
+    case $ac_sys_system in
+    OpenUNIX*|UnixWare*)
+	BASECFLAGS="$BASECFLAGS -K pentium,host,inline,loop_unroll,alloca "
+	;;
+    OSF*)
+	BASECFLAGS="$BASECFLAGS -ieee -std"
+    	;;
+    SCO_SV*)
+	BASECFLAGS="$BASECFLAGS -belf -Ki486 -DSCO5"
+	;;
+    esac
+    ;;
+esac
+
+if test "$Py_DEBUG" = 'true'; then
+  :
+else
+  OPT="-DNDEBUG $OPT"
+fi
+
+if test "$ac_arch_flags"
+then
+	BASECFLAGS="$BASECFLAGS $ac_arch_flags"
+fi
+
+# disable check for icc since it seems to pass, but generates a warning
+if test "$CC" = icc
+then
+  ac_cv_opt_olimit_ok=no
+fi
+
+AC_MSG_CHECKING(whether $CC accepts -OPT:Olimit=0)
+AC_CACHE_VAL(ac_cv_opt_olimit_ok,
+[ac_save_cc="$CC"
+CC="$CC -OPT:Olimit=0"
+AC_TRY_RUN([int main() { return 0; }],
+  ac_cv_opt_olimit_ok=yes,
+  ac_cv_opt_olimit_ok=no,
+  ac_cv_opt_olimit_ok=no)
+CC="$ac_save_cc"])
+AC_MSG_RESULT($ac_cv_opt_olimit_ok)
+if test $ac_cv_opt_olimit_ok = yes; then
+    case $ac_sys_system in
+	# XXX is this branch needed? On MacOSX 10.2.2 the result of the
+	# olimit_ok test is "no".  Is it "yes" in some other Darwin-esque
+	# environment?
+        Darwin*)
+	    ;;
+        *)
+	    BASECFLAGS="$BASECFLAGS -OPT:Olimit=0"
+	    ;;
+    esac
+else
+  AC_MSG_CHECKING(whether $CC accepts -Olimit 1500)
+  AC_CACHE_VAL(ac_cv_olimit_ok,
+  [ac_save_cc="$CC"
+  CC="$CC -Olimit 1500"
+  AC_TRY_RUN([int main() { return 0; }],
+    ac_cv_olimit_ok=yes,
+    ac_cv_olimit_ok=no,
+    ac_cv_olimit_ok=no)
+  CC="$ac_save_cc"])
+  AC_MSG_RESULT($ac_cv_olimit_ok)
+  if test $ac_cv_olimit_ok = yes; then
+    BASECFLAGS="$BASECFLAGS -Olimit 1500"
+  fi
+fi
+
+# On some compilers, pthreads are available without further options
+# (e.g. MacOS X). On some of these systems, the compiler will not
+# complain if unaccepted options are passed (e.g. gcc on Mac OS X).
+# So we have to see first whether pthreads are available without
+# options before we can check whether -Kpthread improves anything.
+AC_MSG_CHECKING(whether pthreads are available without options)
+AC_CACHE_VAL(ac_cv_pthread_is_default,
+[AC_TRY_RUN([
+#include <pthread.h>
+
+void* routine(void* p){return NULL;}
+
+int main(){
+  pthread_t p;
+  if(pthread_create(&p,NULL,routine,NULL)!=0)
+    return 1;
+  (void)pthread_detach(p);
+  return 0;
+}
+],
+[
+  ac_cv_pthread_is_default=yes
+  ac_cv_kthread=no
+  ac_cv_pthread=no
+],
+  ac_cv_pthread_is_default=no,
+  ac_cv_pthread_is_default=no)
+])
+AC_MSG_RESULT($ac_cv_pthread_is_default)
+
+
+if test $ac_cv_pthread_is_default = yes 
+then
+  ac_cv_kpthread=no
+else
+# -Kpthread, if available, provides the right #defines
+# and linker options to make pthread_create available
+# Some compilers won't report that they do not support -Kpthread,
+# so we need to run a program to see whether it really made the
+# function available.
+AC_MSG_CHECKING(whether $CC accepts -Kpthread)
+AC_CACHE_VAL(ac_cv_kpthread,
+[ac_save_cc="$CC"
+CC="$CC -Kpthread"
+AC_TRY_RUN([
+#include <pthread.h>
+
+void* routine(void* p){return NULL;}
+
+int main(){
+  pthread_t p;
+  if(pthread_create(&p,NULL,routine,NULL)!=0)
+    return 1;
+  (void)pthread_detach(p);
+  return 0;
+}
+],
+  ac_cv_kpthread=yes,
+  ac_cv_kpthread=no,
+  ac_cv_kpthread=no)
+CC="$ac_save_cc"])
+AC_MSG_RESULT($ac_cv_kpthread)
+fi
+
+if test $ac_cv_kpthread = no -a $ac_cv_pthread_is_default = no
+then
+# -Kthread, if available, provides the right #defines
+# and linker options to make pthread_create available
+# Some compilers won't report that they do not support -Kthread,
+# so we need to run a program to see whether it really made the
+# function available.
+AC_MSG_CHECKING(whether $CC accepts -Kthread)
+AC_CACHE_VAL(ac_cv_kthread,
+[ac_save_cc="$CC"
+CC="$CC -Kthread"
+AC_TRY_RUN([
+#include <pthread.h>
+
+void* routine(void* p){return NULL;}
+
+int main(){
+  pthread_t p;
+  if(pthread_create(&p,NULL,routine,NULL)!=0)
+    return 1;
+  (void)pthread_detach(p);
+  return 0;
+}
+],
+  ac_cv_kthread=yes,
+  ac_cv_kthread=no,
+  ac_cv_kthread=no)
+CC="$ac_save_cc"])
+AC_MSG_RESULT($ac_cv_kthread)
+fi
+
+if test $ac_cv_kthread = no -a $ac_cv_pthread_is_default = no
+then
+# -pthread, if available, provides the right #defines
+# and linker options to make pthread_create available
+# Some compilers won't report that they do not support -pthread,
+# so we need to run a program to see whether it really made the
+# function available.
+AC_MSG_CHECKING(whether $CC accepts -pthread)
+AC_CACHE_VAL(ac_cv_thread,
+[ac_save_cc="$CC"
+CC="$CC -pthread"
+AC_TRY_RUN([
+#include <pthread.h>
+
+void* routine(void* p){return NULL;}
+
+int main(){
+  pthread_t p;
+  if(pthread_create(&p,NULL,routine,NULL)!=0)
+    return 1;
+  (void)pthread_detach(p);
+  return 0;
+}
+],
+  ac_cv_pthread=yes,
+  ac_cv_pthread=no,
+  ac_cv_pthread=no)
+CC="$ac_save_cc"])
+AC_MSG_RESULT($ac_cv_pthread)
+fi
+
+# If we have set a CC compiler flag for thread support then
+# check if it works for CXX, too.
+ac_cv_cxx_thread=no
+if test ! -z "$CXX"
+then
+AC_MSG_CHECKING(whether $CXX also accepts flags for thread support)
+ac_save_cxx="$CXX"
+
+if test "$ac_cv_kpthread" = "yes"
+then
+  CXX="$CXX -Kpthread"  
+  ac_cv_cxx_thread=yes
+elif test "$ac_cv_kthread" = "yes"
+then
+  CXX="$CXX -Kthread"
+  ac_cv_cxx_thread=yes
+elif test "$ac_cv_pthread" = "yes"
+then 
+  CXX="$CXX -pthread"
+  ac_cv_cxx_thread=yes
+fi
+
+if test $ac_cv_cxx_thread = yes
+then
+  echo 'void foo();int main(){foo();}void foo(){}' > conftest.$ac_ext
+  $CXX -c conftest.$ac_ext 2>&5
+  if $CXX -o conftest$ac_exeext conftest.$ac_objext 2>&5 \
+     && test -s conftest$ac_exeext && ./conftest$ac_exeext
+  then
+    ac_cv_cxx_thread=yes
+  else
+    ac_cv_cxx_thread=no
+  fi
+  rm -fr conftest*
+fi
+AC_MSG_RESULT($ac_cv_cxx_thread)
+fi
+CXX="$ac_save_cxx"
+
+dnl # check for ANSI or K&R ("traditional") preprocessor
+dnl AC_MSG_CHECKING(for C preprocessor type)
+dnl AC_TRY_COMPILE([
+dnl #define spam(name, doc) {#name, &name, #name "() -- " doc}
+dnl int foo;
+dnl struct {char *name; int *addr; char *doc;} desc = spam(foo, "something");
+dnl ], [;], cpp_type=ansi, AC_DEFINE(HAVE_OLD_CPP) cpp_type=traditional)
+dnl AC_MSG_RESULT($cpp_type)
+
+# checks for header files
+AC_HEADER_STDC
+AC_CHECK_HEADERS(asm/types.h conio.h curses.h direct.h dlfcn.h errno.h \
+fcntl.h grp.h \
+io.h langinfo.h libintl.h ncurses.h poll.h process.h pthread.h \
+shadow.h signal.h stdint.h stropts.h termios.h thread.h \
+unistd.h utime.h \
+sys/audioio.h sys/bsdtty.h sys/file.h sys/loadavg.h sys/lock.h sys/mkdev.h \
+sys/modem.h \
+sys/param.h sys/poll.h sys/select.h sys/socket.h sys/statvfs.h sys/stat.h \
+sys/time.h \
+sys/times.h sys/types.h sys/un.h sys/utsname.h sys/wait.h pty.h libutil.h \
+sys/resource.h netpacket/packet.h sysexits.h bluetooth.h \
+bluetooth/bluetooth.h)
+AC_HEADER_DIRENT
+AC_HEADER_MAJOR
+
+# On Solaris, term.h requires curses.h
+AC_CHECK_HEADERS(term.h,,,[
+#ifdef HAVE_CURSES_H
+#include <curses.h>
+#endif
+])
+
+# On Linux, netlink.h requires asm/types.h
+AC_CHECK_HEADERS(linux/netlink.h,,,[
+#ifdef HAVE_ASM_TYPES_H
+#include <asm/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+])
+
+# checks for typedefs
+was_it_defined=no
+AC_MSG_CHECKING(for clock_t in time.h)
+AC_EGREP_HEADER(clock_t, time.h, was_it_defined=yes, [
+    AC_DEFINE(clock_t, long, [Define to 'long' if <time.h> doesn't define.])
+])
+AC_MSG_RESULT($was_it_defined)
+
+# Check whether using makedev requires defining _OSF_SOURCE
+AC_MSG_CHECKING(for makedev)
+AC_TRY_LINK([#include <sys/types.h> ],
+	    [ makedev(0, 0) ],
+	    ac_cv_has_makedev=yes,
+	    ac_cv_has_makedev=no)
+if test "$ac_cv_has_makedev" = "no"; then
+    # we didn't link, try if _OSF_SOURCE will allow us to link
+    AC_TRY_LINK([
+#define _OSF_SOURCE 1
+#include <sys/types.h>
+    ],
+    [ makedev(0, 0) ],
+    ac_cv_has_makedev=yes,
+    ac_cv_has_makedev=no)
+    if test "$ac_cv_has_makedev" = "yes"; then
+        AC_DEFINE(_OSF_SOURCE, 1, [Define _OSF_SOURCE to get the makedev macro.])
+    fi
+fi
+AC_MSG_RESULT($ac_cv_has_makedev)
+if test "$ac_cv_has_makedev" = "yes"; then
+    AC_DEFINE(HAVE_MAKEDEV, 1, [Define this if you have the makedev macro.])
+fi
+
+# Enabling LFS on Solaris (2.6 to 9) with gcc 2.95 triggers a bug in
+# the system headers: If _XOPEN_SOURCE and _LARGEFILE_SOURCE are
+# defined, but the compiler does not support pragma redefine_extname,
+# and _LARGEFILE64_SOURCE is not defined, the headers refer to 64-bit
+# structures (such as rlimit64) without declaring them. As a
+# work-around, disable LFS on such configurations
+
+use_lfs=yes
+AC_MSG_CHECKING(Solaris LFS bug)
+AC_TRY_COMPILE([
+#define _LARGEFILE_SOURCE 1
+#define _FILE_OFFSET_BITS 64
+#include <sys/resource.h>
+],struct rlimit foo;,sol_lfs_bug=no,sol_lfs_bug=yes)
+AC_MSG_RESULT($sol_lfs_bug)
+if test "$sol_lfs_bug" = "yes"; then
+  use_lfs=no
+fi
+
+if test "$use_lfs" = "yes"; then
+# Two defines needed to enable largefile support on various platforms
+# These may affect some typedefs
+AC_DEFINE(_LARGEFILE_SOURCE, 1, 
+[This must be defined on some systems to enable large file support.])
+AC_DEFINE(_FILE_OFFSET_BITS, 64,
+[This must be set to 64 on some systems to enable large file support.])
+fi
+
+# Add some code to confdefs.h so that the test for off_t works on SCO
+cat >> confdefs.h <<\EOF
+#if defined(SCO_DS)
+#undef _OFF_T
+#endif
+EOF
+
+# Type availability checks
+AC_TYPE_MODE_T
+AC_TYPE_OFF_T
+AC_TYPE_PID_T
+AC_TYPE_SIGNAL
+AC_TYPE_SIZE_T
+AC_TYPE_UID_T
+AC_CHECK_TYPE(ssize_t, 
+  AC_DEFINE(HAVE_SSIZE_T, 1, Define if your compiler provides ssize_t),,)
+
+# Sizes of various common basic types
+# ANSI C requires sizeof(char) == 1, so no need to check it
+AC_CHECK_SIZEOF(int, 4)
+AC_CHECK_SIZEOF(long, 4)
+AC_CHECK_SIZEOF(void *, 4)
+AC_CHECK_SIZEOF(short, 2)
+AC_CHECK_SIZEOF(float, 4)
+AC_CHECK_SIZEOF(double, 8)
+AC_CHECK_SIZEOF(fpos_t, 4)
+AC_CHECK_SIZEOF(size_t, 4)
+
+AC_MSG_CHECKING(for long long support)
+have_long_long=no
+AC_TRY_COMPILE([], [long long x; x = (long long)0;], [
+  AC_DEFINE(HAVE_LONG_LONG, 1, [Define this if you have the type long long.]) 
+  have_long_long=yes
+])
+AC_MSG_RESULT($have_long_long)
+if test "$have_long_long" = yes ; then
+AC_CHECK_SIZEOF(long long, 8)
+fi
+
+AC_CHECK_TYPES(uintptr_t, 
+   [AC_CHECK_SIZEOF(uintptr_t, 4)], 
+   [], [#ifdef HAVE_STDINT_H
+        #include <stdint.h>
+        #endif])
+
+
+# Hmph. AC_CHECK_SIZEOF() doesn't include <sys/types.h>.
+AC_MSG_CHECKING(size of off_t)
+AC_CACHE_VAL(ac_cv_sizeof_off_t,
+[AC_TRY_RUN([#include <stdio.h>
+#include <sys/types.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(off_t));
+  exit(0);
+}],
+ac_cv_sizeof_off_t=`cat conftestval`,
+ac_cv_sizeof_off_t=0,
+ac_cv_sizeof_off_t=4)
+])
+AC_MSG_RESULT($ac_cv_sizeof_off_t)
+AC_DEFINE_UNQUOTED(SIZEOF_OFF_T, $ac_cv_sizeof_off_t,
+[The number of bytes in an off_t.])
+
+AC_MSG_CHECKING(whether to enable large file support)
+if test "$have_long_long" = yes -a \
+	"$ac_cv_sizeof_off_t" -gt "$ac_cv_sizeof_long" -a \
+	"$ac_cv_sizeof_long_long" -ge "$ac_cv_sizeof_off_t"; then
+  AC_DEFINE(HAVE_LARGEFILE_SUPPORT, 1, 
+  [Defined to enable large file support when an off_t is bigger than a long
+   and long long is available and at least as big as an off_t. You may need
+   to add some flags for configuration and compilation to enable this mode.
+   (For Solaris and Linux, the necessary defines are already defined.)])
+  AC_MSG_RESULT(yes)
+else
+  AC_MSG_RESULT(no)
+fi
+
+# AC_CHECK_SIZEOF() doesn't include <time.h>.
+AC_MSG_CHECKING(size of time_t)
+AC_CACHE_VAL(ac_cv_sizeof_time_t,
+[AC_TRY_RUN([#include <stdio.h>
+#include <time.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(time_t));
+  exit(0);
+}],
+ac_cv_sizeof_time_t=`cat conftestval`,
+ac_cv_sizeof_time_t=0,
+ac_cv_sizeof_time_t=4)
+])
+AC_MSG_RESULT($ac_cv_sizeof_time_t)
+AC_DEFINE_UNQUOTED(SIZEOF_TIME_T, $ac_cv_sizeof_time_t, 
+[The number of bytes in a time_t.])
+
+
+# if have pthread_t then define SIZEOF_PTHREAD_T
+ac_save_cc="$CC"
+if test "$ac_cv_kpthread" = "yes"
+then CC="$CC -Kpthread"
+elif test "$ac_cv_kthread" = "yes"
+then CC="$CC -Kthread"
+elif test "$ac_cv_pthread" = "yes"
+then CC="$CC -pthread"
+fi
+AC_MSG_CHECKING(for pthread_t)
+have_pthread_t=no
+AC_TRY_COMPILE([#include <pthread.h>], [pthread_t x; x = *(pthread_t*)0;], have_pthread_t=yes)
+AC_MSG_RESULT($have_pthread_t)
+if test "$have_pthread_t" = yes ; then
+  # AC_CHECK_SIZEOF() doesn't include <pthread.h>.
+  AC_MSG_CHECKING(size of pthread_t)
+  AC_CACHE_VAL(ac_cv_sizeof_pthread_t,
+  [AC_TRY_RUN([#include <stdio.h>
+#include <pthread.h>
+  main()
+  {
+    FILE *f=fopen("conftestval", "w");
+    if (!f) exit(1);
+    fprintf(f, "%d\n", sizeof(pthread_t));
+    exit(0);
+  }],
+  ac_cv_sizeof_pthread_t=`cat conftestval`,
+  ac_cv_sizeof_pthread_t=0,
+  ac_cv_sizeof_pthread_t=4)
+  ])
+  AC_MSG_RESULT($ac_cv_sizeof_pthread_t)
+  AC_DEFINE_UNQUOTED(SIZEOF_PTHREAD_T, $ac_cv_sizeof_pthread_t,
+   [The number of bytes in a pthread_t.])
+fi
+CC="$ac_save_cc"
+
+AC_MSG_CHECKING(for --enable-toolbox-glue)
+AC_ARG_ENABLE(toolbox-glue,
+              AC_HELP_STRING(--enable-toolbox-glue, disable/enable MacOSX glue code for extensions))
+
+if test -z "$enable_toolbox_glue"
+then 
+	case $ac_sys_system/$ac_sys_release in
+	Darwin/*)
+		enable_toolbox_glue="yes";;
+	*)
+		enable_toolbox_glue="no";;
+	esac
+fi
+case "$enable_toolbox_glue" in
+yes)
+	extra_machdep_objs="Python/mactoolboxglue.o"
+	extra_undefs="-u _PyMac_Error"
+	AC_DEFINE(USE_TOOLBOX_OBJECT_GLUE, 1,
+         [Define if you want to use MacPython modules on MacOSX in unix-Python.])
+	;;
+*)
+	extra_machdep_objs=""
+	extra_undefs=""
+	;;
+esac
+AC_MSG_RESULT($enable_toolbox_glue)
+
+AC_SUBST(OTHER_LIBTOOL_OPT)
+case $ac_sys_system/$ac_sys_release in
+  Darwin/@<:@01567@:>@\..*) 
+    OTHER_LIBTOOL_OPT="-prebind -seg1addr 0x10000000"
+    ;;
+  Darwin/*)
+    OTHER_LIBTOOL_OPT=""
+    ;;
+esac
+
+AC_SUBST(LIBTOOL_CRUFT)
+case $ac_sys_system/$ac_sys_release in
+  Darwin/@<:@01567@:>@\..*) 
+    LIBTOOL_CRUFT="-framework System -lcc_dynamic"
+    if test "${enable_universalsdk}"; then
+	    :
+    else
+	LIBTOOL_CRUFT="${LIBTOOL_CRUFT} -arch_only `arch`"
+    fi
+    LIBTOOL_CRUFT=$LIBTOOL_CRUFT' -install_name $(PYTHONFRAMEWORKINSTALLDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)'
+    LIBTOOL_CRUFT=$LIBTOOL_CRUFT' -compatibility_version $(VERSION) -current_version $(VERSION)';;
+  Darwin/*)
+    gcc_version=`gcc -v 2>&1 |  grep version | cut -d\  -f3`
+    if test ${gcc_version} '<' 4.0
+        then
+            LIBTOOL_CRUFT="-lcc_dynamic"
+        else 
+            LIBTOOL_CRUFT=""
+    fi
+    LIBTOOL_CRUFT=$LIBTOOL_CRUFT" -lSystem -lSystemStubs -arch_only `arch`"
+    LIBTOOL_CRUFT=$LIBTOOL_CRUFT' -install_name $(PYTHONFRAMEWORKINSTALLDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)'
+    LIBTOOL_CRUFT=$LIBTOOL_CRUFT' -compatibility_version $(VERSION) -current_version $(VERSION)';;
+esac
+
+AC_MSG_CHECKING(for --enable-framework)
+if test "$enable_framework"
+then
+	BASECFLAGS="$BASECFLAGS -fno-common -dynamic"
+	# -F. is needed to allow linking to the framework while 
+	# in the build location.
+	AC_DEFINE(WITH_NEXT_FRAMEWORK, 1, 
+         [Define if you want to produce an OpenStep/Rhapsody framework
+         (shared library plus accessory files).])
+	AC_MSG_RESULT(yes)
+else
+	AC_MSG_RESULT(no)
+fi
+
+AC_MSG_CHECKING(for dyld)
+case $ac_sys_system/$ac_sys_release in
+  Darwin/*)
+  	AC_DEFINE(WITH_DYLD, 1, 
+        [Define if you want to use the new-style (Openstep, Rhapsody, MacOS)
+         dynamic linker (dyld) instead of the old-style (NextStep) dynamic
+         linker (rld). Dyld is necessary to support frameworks.])
+  	AC_MSG_RESULT(always on for Darwin)
+  	;;
+  *)
+	AC_MSG_RESULT(no)
+	;;
+esac
+
+# Set info about shared libraries.
+AC_SUBST(SO)
+AC_SUBST(LDSHARED)
+AC_SUBST(BLDSHARED)
+AC_SUBST(CCSHARED)
+AC_SUBST(LINKFORSHARED)
+# SO is the extension of shared libraries `(including the dot!)
+# -- usually .so, .sl on HP-UX, .dll on Cygwin
+AC_MSG_CHECKING(SO)
+if test -z "$SO"
+then
+	case $ac_sys_system in
+	hp*|HP*)
+		case `uname -m` in
+			ia64) SO=.so;;
+	  		*)    SO=.sl;;
+		esac
+		;;
+	CYGWIN*)   SO=.dll;;
+	*)	   SO=.so;;
+	esac
+else
+	# this might also be a termcap variable, see #610332
+        echo
+        echo '====================================================================='
+        echo '+                                                                   +'
+	echo '+ WARNING: You have set SO in your environment.                     +'
+        echo '+ Do you really mean to change the extension for shared libraries?  +'
+        echo '+ Continuing in 10 seconds to let you to ponder.                    +'
+        echo '+                                                                   +'
+        echo '====================================================================='
+	sleep 10
+fi
+AC_MSG_RESULT($SO)
+AC_DEFINE_UNQUOTED(SHLIB_EXT, "$SO", [Define this to be extension of shared libraries (including the dot!).])
+# LDSHARED is the ld *command* used to create shared library
+# -- "cc -G" on SunOS 5.x, "ld -shared" on IRIX 5
+# (Shared libraries in this instance are shared modules to be loaded into
+# Python, as opposed to building Python itself as a shared library.)
+AC_MSG_CHECKING(LDSHARED)
+if test -z "$LDSHARED"
+then
+	case $ac_sys_system/$ac_sys_release in
+	AIX*)
+		BLDSHARED="\$(srcdir)/Modules/ld_so_aix \$(CC) -bI:Modules/python.exp"
+		LDSHARED="\$(BINLIBDEST)/config/ld_so_aix \$(CC) -bI:\$(BINLIBDEST)/config/python.exp"
+		;;
+	BeOS*)
+		BLDSHARED="\$(srcdir)/Modules/ld_so_beos $LDLIBRARY"
+		LDSHARED="\$(BINLIBDEST)/config/ld_so_beos \$(LIBDIR)/$LDLIBRARY"
+		;;
+	IRIX/5*) LDSHARED="ld -shared";;
+	IRIX*/6*) LDSHARED="ld ${SGI_ABI} -shared -all";;
+	SunOS/5*) 
+		if test "$GCC" = "yes"
+		then LDSHARED='$(CC) -shared'
+		else LDSHARED='$(CC) -G';
+		fi ;;
+	hp*|HP*) LDSHARED="ld -b";;
+	OSF*) LDSHARED="ld -shared -expect_unresolved \"*\"";;
+	Darwin/1.3*)
+		LDSHARED='$(CC) $(LDFLAGS) -bundle'
+		if test "$enable_framework" ; then
+			# Link against the framework. All externals should be defined.
+			BLDSHARED="$LDSHARED "'$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)'
+			LDSHARED="$LDSHARED "'$(PYTHONFRAMEWORKPREFIX)/$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)'
+		else
+			# No framework. Ignore undefined symbols, assuming they come from Python
+			LDSHARED="$LDSHARED -undefined suppress"
+		fi ;;
+	Darwin/1.4*|Darwin/5.*|Darwin/6.*)
+		LDSHARED='$(CC) $(LDFLAGS) -bundle'
+		if test "$enable_framework" ; then
+			# Link against the framework. All externals should be defined.
+			BLDSHARED="$LDSHARED "'$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)'
+			LDSHARED="$LDSHARED "'$(PYTHONFRAMEWORKPREFIX)/$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)'
+		else
+			# No framework, use the Python app as bundle-loader
+			BLDSHARED="$LDSHARED "'-bundle_loader $(BUILDPYTHON)'
+			LDSHARED="$LDSHARED "'-bundle_loader $(BINDIR)/python$(VERSION)$(EXE)'
+		fi ;;
+	Darwin/*)
+		# Use -undefined dynamic_lookup whenever possible (10.3 and later).
+		# This allows an extension to be used in any Python
+		cur_target=`sw_vers -productVersion | sed 's/\(10\.[[0-9]]*\).*/\1/'`
+		if test ${cur_target} '>' 10.2; then
+			cur_target=10.3
+		fi
+		CONFIGURE_MACOSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET-${cur_target}}
+		EXPORT_MACOSX_DEPLOYMENT_TARGET=''
+		if test ${MACOSX_DEPLOYMENT_TARGET-${cur_target}} '>' 10.2
+		then
+			if test "${enable_universalsdk}"; then
+				LDFLAGS="-arch i386 -arch ppc -isysroot ${UNIVERSALSDK} ${LDFLAGS}"
+			fi
+			LDSHARED='$(CC) $(LDFLAGS) -bundle -undefined dynamic_lookup'
+			BLDSHARED="$LDSHARED"
+		else
+			LDSHARED='$(CC) $(LDFLAGS) -bundle'
+			if test "$enable_framework" ; then
+				# Link against the framework. All externals should be defined.
+				BLDSHARED="$LDSHARED "'$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)'
+				LDSHARED="$LDSHARED "'$(PYTHONFRAMEWORKPREFIX)/$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)'
+			else
+				# No framework, use the Python app as bundle-loader
+				BLDSHARED="$LDSHARED "'-bundle_loader $(BUILDPYTHON)'
+				LDSHARED="$LDSHARED "'-bundle_loader $(BINDIR)/python$(VERSION)$(EXE)'
+			fi
+		fi
+		;;
+	Linux*|GNU*) LDSHARED='$(CC) -shared';;
+	BSD/OS*/4*) LDSHARED="gcc -shared";;
+	FreeBSD*)
+		if [[ "`$CC -dM -E - </dev/null | grep __ELF__`" != "" ]]
+		then
+			LDSHARED="$CC -shared ${LDFLAGS}"
+		else
+			LDSHARED="ld -Bshareable ${LDFLAGS}"
+		fi;;
+	OpenBSD*)
+		if [[ "`$CC -dM -E - </dev/null | grep __ELF__`" != "" ]]
+		then
+				LDSHARED='$(CC) -shared $(CCSHARED) ${LDFLAGS}'
+		else
+				case `uname -r` in
+				[[01]].* | 2.[[0-7]] | 2.[[0-7]].*)
+				   LDSHARED="ld -Bshareable ${LDFLAGS}"
+				   ;;
+				*)
+				   LDSHARED='$(CC) -shared $(CCSHARED) ${LDFLAGS}'
+				   ;;
+				esac
+		fi;;
+	NetBSD*|DragonFly*) LDSHARED="cc -shared ${LDFLAGS}";;
+	OpenUNIX*|UnixWare*)
+		if test "$GCC" = "yes"
+		then LDSHARED='$(CC) -shared'
+		else LDSHARED='$(CC) -G'
+		fi;;
+	SCO_SV*) LDSHARED='$(CC) -Wl,-G,-Bexport';;
+	Monterey*) LDSHARED="cc -G -dy -Bdynamic -Bexport -L/usr/lib/ia64l64";;
+	CYGWIN*) LDSHARED="gcc -shared -Wl,--enable-auto-image-base";;
+	atheos*) LDSHARED="gcc -shared";;
+	*)	LDSHARED="ld";;
+	esac
+fi
+AC_MSG_RESULT($LDSHARED)
+BLDSHARED=${BLDSHARED-$LDSHARED}
+# CCSHARED are the C *flags* used to create objects to go into a shared
+# library (module) -- this is only needed for a few systems
+AC_MSG_CHECKING(CCSHARED)
+if test -z "$CCSHARED"
+then
+	case $ac_sys_system/$ac_sys_release in
+	SunOS*) if test "$GCC" = yes;
+		then CCSHARED="-fPIC";
+		elif test `uname -p` = sparc;
+		then CCSHARED="-xcode=pic32";
+		else CCSHARED="-Kpic";
+		fi;;
+	hp*|HP*) if test "$GCC" = yes;
+		 then CCSHARED="-fPIC";
+		 else CCSHARED="+z";
+		 fi;;
+	Linux*|GNU*) CCSHARED="-fPIC";;
+	BSD/OS*/4*) CCSHARED="-fpic";;
+	FreeBSD*|NetBSD*|OpenBSD*|DragonFly*) CCSHARED="-fPIC";;
+	OpenUNIX*|UnixWare*)
+		if test "$GCC" = "yes"
+		then CCSHARED="-fPIC"
+		else CCSHARED="-KPIC"
+		fi;;
+	SCO_SV*)
+		if test "$GCC" = "yes"
+		then CCSHARED="-fPIC"
+		else CCSHARED="-Kpic -belf"
+		fi;;
+	Monterey*) CCSHARED="-G";;
+	IRIX*/6*)  case $CC in
+		   *gcc*) CCSHARED="-shared";;
+		   *) CCSHARED="";;
+		   esac;;
+	atheos*) CCSHARED="-fPIC";;
+	esac
+fi
+AC_MSG_RESULT($CCSHARED)
+# LINKFORSHARED are the flags passed to the $(CC) command that links
+# the python executable -- this is only needed for a few systems
+AC_MSG_CHECKING(LINKFORSHARED)
+if test -z "$LINKFORSHARED"
+then
+	case $ac_sys_system/$ac_sys_release in
+	AIX*)	LINKFORSHARED='-Wl,-bE:Modules/python.exp -lld';;
+	hp*|HP*)
+	    LINKFORSHARED="-Wl,-E -Wl,+s";;
+#	    LINKFORSHARED="-Wl,-E -Wl,+s -Wl,+b\$(BINLIBDEST)/lib-dynload";;
+	BSD/OS/4*) LINKFORSHARED="-Xlinker -export-dynamic";;
+	Linux*|GNU*) LINKFORSHARED="-Xlinker -export-dynamic";;
+	# -u libsys_s pulls in all symbols in libsys
+	Darwin/*) 
+		# -u _PyMac_Error is needed to pull in the mac toolbox glue,
+		# which is
+		# not used by the core itself but which needs to be in the core so
+		# that dynamically loaded extension modules have access to it.
+		# -prebind is no longer used, because it actually seems to give a
+		# slowdown in stead of a speedup, maybe due to the large number of
+		# dynamic loads Python does.
+
+		LINKFORSHARED="$extra_undefs"
+		if test "$enable_framework"
+		then
+			LINKFORSHARED="$LINKFORSHARED "'$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)'
+		fi
+		LINKFORSHARED="$LINKFORSHARED";;
+	OpenUNIX*|UnixWare*) LINKFORSHARED="-Wl,-Bexport";;
+	SCO_SV*) LINKFORSHARED="-Wl,-Bexport";;
+	ReliantUNIX*) LINKFORSHARED="-W1 -Blargedynsym";;
+	FreeBSD*|NetBSD*|OpenBSD*|DragonFly*) 
+		if [[ "`$CC -dM -E - </dev/null | grep __ELF__`" != "" ]]
+		then
+			LINKFORSHARED="-Wl,--export-dynamic"
+		fi;;
+	SunOS/5*) case $CC in
+		  *gcc*)
+		    if $CC -Xlinker --help 2>&1 | grep export-dynamic >/dev/null
+		    then
+			LINKFORSHARED="-Xlinker --export-dynamic"
+		    fi;;
+		  esac;;
+	CYGWIN*)
+		if test $enable_shared = "no"
+		then
+			LINKFORSHARED='-Wl,--out-implib=$(LDLIBRARY)'
+		fi;;
+	esac
+fi
+AC_MSG_RESULT($LINKFORSHARED)
+
+AC_SUBST(CFLAGSFORSHARED)
+AC_MSG_CHECKING(CFLAGSFORSHARED)
+if test ! "$LIBRARY" = "$LDLIBRARY"
+then
+	case $ac_sys_system in
+	CYGWIN*)
+		# Cygwin needs CCSHARED when building extension DLLs
+		# but not when building the interpreter DLL.
+		CFLAGSFORSHARED='';;
+	*)
+		CFLAGSFORSHARED='$(CCSHARED)'
+	esac
+fi
+AC_MSG_RESULT($CFLAGSFORSHARED)
+
+# SHLIBS are libraries (except -lc and -lm) to link to the python shared
+# library (with --enable-shared).
+# For platforms on which shared libraries are not allowed to have unresolved
+# symbols, this must be set to $(LIBS) (expanded by make). We do this even
+# if it is not required, since it creates a dependency of the shared library
+# to LIBS. This, in turn, means that applications linking the shared libpython
+# don't need to link LIBS explicitly. The default should be only changed
+# on systems where this approach causes problems.
+AC_SUBST(SHLIBS)
+AC_MSG_CHECKING(SHLIBS)
+case "$ac_sys_system" in
+	*)
+		SHLIBS='$(LIBS)';;
+esac
+AC_MSG_RESULT($SHLIBS)
+
+
+# checks for libraries
+AC_CHECK_LIB(dl, dlopen)	# Dynamic linking for SunOS/Solaris and SYSV
+AC_CHECK_LIB(dld, shl_load)	# Dynamic linking for HP-UX
+
+# only check for sem_ini if thread support is requested
+if test "$with_threads" = "yes" -o -z "$with_threads"; then
+    AC_SEARCH_LIBS(sem_init, pthread rt posix4) # 'Real Time' functions on Solaris
+						# posix4 on Solaris 2.6
+						# pthread (first!) on Linux
+fi
+
+# check if we need libintl for locale functions
+AC_CHECK_LIB(intl, textdomain,
+	AC_DEFINE(WITH_LIBINTL, 1,
+	[Define to 1 if libintl is needed for locale functions.]))
+
+# checks for system dependent C++ extensions support
+case "$ac_sys_system" in
+	AIX*)	AC_MSG_CHECKING(for genuine AIX C++ extensions support)
+		AC_TRY_LINK([#include "/usr/lpp/xlC/include/load.h"],
+			    [loadAndInit("", 0, "")],
+			    [AC_DEFINE(AIX_GENUINE_CPLUSPLUS, 1,
+                      [Define for AIX if your compiler is a genuine IBM xlC/xlC_r
+                       and you want support for AIX C++ shared extension modules.])
+			     AC_MSG_RESULT(yes)],
+			    [AC_MSG_RESULT(no)]);;
+	*) ;;
+esac
+
+# Most SVR4 platforms (e.g. Solaris) need -lsocket and -lnsl.
+# BeOS' sockets are stashed in libnet.
+AC_CHECK_LIB(nsl, t_open, [LIBS="-lnsl $LIBS"]) # SVR4
+AC_CHECK_LIB(socket, socket, [LIBS="-lsocket $LIBS"], [], $LIBS) # SVR4 sockets
+
+case "$ac_sys_system" in
+BeOS*)
+AC_CHECK_LIB(net, socket, [LIBS="-lnet $LIBS"], [], $LIBS) # BeOS
+;;
+esac
+
+AC_MSG_CHECKING(for --with-libs)
+AC_ARG_WITH(libs,
+            AC_HELP_STRING(--with-libs='lib1 ...', link against additional libs),
+[
+AC_MSG_RESULT($withval)
+LIBS="$withval $LIBS"
+],
+[AC_MSG_RESULT(no)])
+
+# Check for use of the system libffi library
+AC_MSG_CHECKING(for --with-system-ffi)
+AC_ARG_WITH(system_ffi,
+            AC_HELP_STRING(--with-system-ffi, build _ctypes module using an installed ffi library))
+
+if test -z "$with_system_ffi"
+then with_system_ffi="no"
+fi
+AC_MSG_RESULT($with_system_ffi)
+
+# Determine if signalmodule should be used.
+AC_SUBST(USE_SIGNAL_MODULE)
+AC_SUBST(SIGNAL_OBJS)
+AC_MSG_CHECKING(for --with-signal-module)
+AC_ARG_WITH(signal-module,
+            AC_HELP_STRING(--with-signal-module, disable/enable signal module))
+
+if test -z "$with_signal_module"
+then with_signal_module="yes"
+fi
+AC_MSG_RESULT($with_signal_module)
+
+if test "${with_signal_module}" = "yes"; then
+	USE_SIGNAL_MODULE=""
+	SIGNAL_OBJS=""
+else
+	USE_SIGNAL_MODULE="#"
+	SIGNAL_OBJS="Parser/intrcheck.o Python/sigcheck.o"
+fi
+
+# This is used to generate Setup.config
+AC_SUBST(USE_THREAD_MODULE)
+USE_THREAD_MODULE=""
+
+AC_MSG_CHECKING(for --with-dec-threads)
+AC_SUBST(LDLAST)
+AC_ARG_WITH(dec-threads,
+            AC_HELP_STRING(--with-dec-threads, use DEC Alpha/OSF1 thread-safe libraries),
+[
+AC_MSG_RESULT($withval)
+LDLAST=-threads
+if test "${with_thread+set}" != set; then
+   with_thread="$withval";
+fi],
+[AC_MSG_RESULT(no)])
+
+# Templates for things AC_DEFINEd more than once.
+# For a single AC_DEFINE, no template is needed.
+AH_TEMPLATE(C_THREADS,[Define if you have the Mach cthreads package])
+AH_TEMPLATE(_REENTRANT,
+  [Define to force use of thread-safe errno, h_errno, and other functions])
+AH_TEMPLATE(WITH_THREAD,
+  [Define if you want to compile in rudimentary thread support])
+
+AC_MSG_CHECKING(for --with-threads)
+dnl quadrigraphs "@<:@" and "@:>@" produce "[" and "]" in the output
+AC_ARG_WITH(threads,
+            AC_HELP_STRING(--with(out)-threads@<:@=DIRECTORY@:>@, disable/enable thread support))
+
+# --with-thread is deprecated, but check for it anyway
+dnl quadrigraphs "@<:@" and "@:>@" produce "[" and "]" in the output
+AC_ARG_WITH(thread,
+            AC_HELP_STRING(--with(out)-thread@<:@=DIRECTORY@:>@, deprecated; use --with(out)-threads),
+            [with_threads=$with_thread])
+
+if test -z "$with_threads"
+then with_threads="yes"
+fi
+AC_MSG_RESULT($with_threads)
+
+AC_SUBST(THREADOBJ)
+if test "$with_threads" = "no"
+then
+    USE_THREAD_MODULE="#"
+elif test "$ac_cv_pthread_is_default" = yes
+then
+    AC_DEFINE(WITH_THREAD)
+    # Defining _REENTRANT on system with POSIX threads should not hurt.
+    AC_DEFINE(_REENTRANT)
+    posix_threads=yes
+    THREADOBJ="Python/thread.o"    
+elif test "$ac_cv_kpthread" = "yes"
+then
+    CC="$CC -Kpthread"
+    if test "$ac_cv_cxx_thread" = "yes"; then
+        CXX="$CXX -Kpthread"
+    fi
+    AC_DEFINE(WITH_THREAD)
+    posix_threads=yes
+    THREADOBJ="Python/thread.o"
+elif test "$ac_cv_kthread" = "yes"
+then
+    CC="$CC -Kthread"
+    if test "$ac_cv_cxx_thread" = "yes"; then
+        CXX="$CXX -Kthread"
+    fi
+    AC_DEFINE(WITH_THREAD)
+    posix_threads=yes
+    THREADOBJ="Python/thread.o"
+elif test "$ac_cv_pthread" = "yes"
+then
+    CC="$CC -pthread"
+    if test "$ac_cv_cxx_thread" = "yes"; then
+        CXX="$CXX -pthread"
+    fi
+    AC_DEFINE(WITH_THREAD)
+    posix_threads=yes
+    THREADOBJ="Python/thread.o"
+else
+    if test ! -z "$with_threads" -a -d "$with_threads"
+    then LDFLAGS="$LDFLAGS -L$with_threads"
+    fi
+    if test ! -z "$withval" -a -d "$withval"
+    then LDFLAGS="$LDFLAGS -L$withval"
+    fi
+
+    # According to the POSIX spec, a pthreads implementation must
+    # define _POSIX_THREADS in unistd.h. Some apparently don't
+    # (e.g. gnu pth with pthread emulation)
+    AC_MSG_CHECKING(for _POSIX_THREADS in unistd.h)
+    AC_EGREP_CPP(yes,
+    [
+#include <unistd.h>
+#ifdef _POSIX_THREADS
+yes
+#endif
+    ], unistd_defines_pthreads=yes, unistd_defines_pthreads=no)
+    AC_MSG_RESULT($unistd_defines_pthreads)
+
+    AC_DEFINE(_REENTRANT)
+    AC_CHECK_HEADER(cthreads.h, [AC_DEFINE(WITH_THREAD)
+    AC_DEFINE(C_THREADS)
+    AC_DEFINE(HURD_C_THREADS, 1,
+    [Define if you are using Mach cthreads directly under /include])
+    LIBS="$LIBS -lthreads"
+    THREADOBJ="Python/thread.o"],[
+    AC_CHECK_HEADER(mach/cthreads.h, [AC_DEFINE(WITH_THREAD)
+    AC_DEFINE(C_THREADS)
+    AC_DEFINE(MACH_C_THREADS, 1,
+    [Define if you are using Mach cthreads under mach /])
+    THREADOBJ="Python/thread.o"],[
+    AC_MSG_CHECKING(for --with-pth)
+    AC_ARG_WITH([pth],
+                AC_HELP_STRING(--with-pth, use GNU pth threading libraries),
+                [AC_MSG_RESULT($withval)
+                  AC_DEFINE([WITH_THREAD])
+                  AC_DEFINE([HAVE_PTH], 1,
+                            [Define if you have GNU PTH threads.])
+                  LIBS="-lpth $LIBS"
+                  THREADOBJ="Python/thread.o"],
+	        [AC_MSG_RESULT(no)
+
+    # Just looking for pthread_create in libpthread is not enough:
+    # on HP/UX, pthread.h renames pthread_create to a different symbol name.
+    # So we really have to include pthread.h, and then link.
+    _libs=$LIBS
+    LIBS="$LIBS -lpthread"
+    AC_MSG_CHECKING([for pthread_create in -lpthread])
+    AC_TRY_LINK([#include <pthread.h>
+
+void * start_routine (void *arg) { exit (0); }], [
+pthread_create (NULL, NULL, start_routine, NULL)], [
+    AC_MSG_RESULT(yes)
+    AC_DEFINE(WITH_THREAD)
+    posix_threads=yes
+    THREADOBJ="Python/thread.o"],[
+    LIBS=$_libs
+    AC_CHECK_FUNC(pthread_detach, [AC_DEFINE(WITH_THREAD)
+    posix_threads=yes
+    THREADOBJ="Python/thread.o"],[
+    AC_CHECK_HEADER(atheos/threads.h, [AC_DEFINE(WITH_THREAD)
+    AC_DEFINE(ATHEOS_THREADS, 1,
+    [Define this if you have AtheOS threads.])
+    THREADOBJ="Python/thread.o"],[
+    AC_CHECK_HEADER(kernel/OS.h, [AC_DEFINE(WITH_THREAD)
+    AC_DEFINE(BEOS_THREADS, 1,
+    [Define this if you have BeOS threads.])
+    THREADOBJ="Python/thread.o"],[
+    AC_CHECK_LIB(pthreads, pthread_create, [AC_DEFINE(WITH_THREAD)
+    posix_threads=yes
+    LIBS="$LIBS -lpthreads"
+    THREADOBJ="Python/thread.o"], [
+    AC_CHECK_LIB(c_r, pthread_create, [AC_DEFINE(WITH_THREAD)
+    posix_threads=yes
+    LIBS="$LIBS -lc_r"
+    THREADOBJ="Python/thread.o"], [
+    AC_CHECK_LIB(pthread, __pthread_create_system, [AC_DEFINE(WITH_THREAD)
+    posix_threads=yes
+    LIBS="$LIBS -lpthread"
+    THREADOBJ="Python/thread.o"], [
+    AC_CHECK_LIB(cma, pthread_create, [AC_DEFINE(WITH_THREAD)
+    posix_threads=yes
+    LIBS="$LIBS -lcma"
+    THREADOBJ="Python/thread.o"],[
+    USE_THREAD_MODULE="#"])
+    ])])])])])])])])])])
+
+    AC_CHECK_LIB(mpc, usconfig, [AC_DEFINE(WITH_THREAD)
+    LIBS="$LIBS -lmpc"
+    THREADOBJ="Python/thread.o"
+    USE_THREAD_MODULE=""])
+
+    if test "$posix_threads" != "yes"; then     
+      AC_CHECK_LIB(thread, thr_create, [AC_DEFINE(WITH_THREAD)
+      LIBS="$LIBS -lthread"
+      THREADOBJ="Python/thread.o"
+      USE_THREAD_MODULE=""])
+    fi
+
+    if test "$USE_THREAD_MODULE" != "#"
+    then
+        # If the above checks didn't disable threads, (at least) OSF1
+        # needs this '-threads' argument during linking.
+        case $ac_sys_system in
+        OSF1) LDLAST=-threads;;
+        esac
+    fi
+fi
+
+if test "$posix_threads" = "yes"; then
+      if test "$unistd_defines_pthreads" = "no"; then
+         AC_DEFINE(_POSIX_THREADS, 1,
+         [Define if you have POSIX threads, 
+          and your system does not define that.])
+      fi
+
+      # Bug 662787: Using semaphores causes unexplicable hangs on Solaris 8.
+      case  $ac_sys_system/$ac_sys_release in
+  SunOS/5.6) AC_DEFINE(HAVE_PTHREAD_DESTRUCTOR, 1,
+                       Defined for Solaris 2.6 bug in pthread header.)
+		       ;;
+      SunOS/5.8) AC_DEFINE(HAVE_BROKEN_POSIX_SEMAPHORES, 1,
+		       Define if the Posix semaphores do not work on your system)
+		       ;;
+      esac
+
+      AC_MSG_CHECKING(if PTHREAD_SCOPE_SYSTEM is supported)
+      AC_CACHE_VAL(ac_cv_pthread_system_supported,
+      [AC_TRY_RUN([#include <pthread.h>
+      void *foo(void *parm) {
+        return NULL;
+      }
+      main() {
+        pthread_attr_t attr;
+        pthread_t id;
+        if (pthread_attr_init(&attr)) exit(-1);
+        if (pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM)) exit(-1);
+        if (pthread_create(&id, &attr, foo, NULL)) exit(-1);
+        exit(0);
+      }],
+      ac_cv_pthread_system_supported=yes,
+      ac_cv_pthread_system_supported=no,
+      ac_cv_pthread_system_supported=no)
+      ])
+      AC_MSG_RESULT($ac_cv_pthread_system_supported)
+      if test "$ac_cv_pthread_system_supported" = "yes"; then
+        AC_DEFINE(PTHREAD_SYSTEM_SCHED_SUPPORTED, 1, [Defined if PTHREAD_SCOPE_SYSTEM supported.])
+      fi
+      AC_CHECK_FUNCS(pthread_sigmask,
+        [case $ac_sys_system in
+        CYGWIN*)
+          AC_DEFINE(HAVE_BROKEN_PTHREAD_SIGMASK, 1,
+            [Define if pthread_sigmask() does not work on your system.])
+            ;;
+        esac])
+fi
+
+
+# Check for enable-ipv6
+AH_TEMPLATE(ENABLE_IPV6, [Define if --enable-ipv6 is specified])
+AC_MSG_CHECKING([if --enable-ipv6 is specified])
+AC_ARG_ENABLE(ipv6,
+[  --enable-ipv6           Enable ipv6 (with ipv4) support
+  --disable-ipv6          Disable ipv6 support],
+[ case "$enableval" in
+  no)
+       AC_MSG_RESULT(no)
+       ipv6=no
+       ;;
+  *)   AC_MSG_RESULT(yes)
+       AC_DEFINE(ENABLE_IPV6)
+       ipv6=yes
+       ;;
+  esac ],
+
+[
+dnl the check does not work on cross compilation case...
+  AC_TRY_RUN([ /* AF_INET6 available check */
+#include <sys/types.h>
+#include <sys/socket.h>
+main()
+{
+ if (socket(AF_INET6, SOCK_STREAM, 0) < 0)
+   exit(1);
+ else
+   exit(0);
+}
+],
+  AC_MSG_RESULT(yes)
+  ipv6=yes,
+  AC_MSG_RESULT(no)
+  ipv6=no,
+  AC_MSG_RESULT(no)
+  ipv6=no
+)
+
+if test "$ipv6" = "yes"; then
+	AC_MSG_CHECKING(if RFC2553 API is available)
+	AC_TRY_COMPILE([#include <sys/types.h>
+#include <netinet/in.h>],
+	[struct sockaddr_in6 x;
+x.sin6_scope_id;],
+		AC_MSG_RESULT(yes)
+		ipv6=yes,
+		AC_MSG_RESULT(no, IPv6 disabled)
+		ipv6=no)
+fi
+
+if test "$ipv6" = "yes"; then
+	AC_DEFINE(ENABLE_IPV6)
+fi
+])
+
+ipv6type=unknown
+ipv6lib=none
+ipv6trylibc=no
+
+if test "$ipv6" = "yes"; then
+	AC_MSG_CHECKING([ipv6 stack type])
+	for i in inria kame linux-glibc linux-inet6 solaris toshiba v6d zeta;
+	do
+		case $i in
+		inria)
+			dnl http://www.kame.net/
+			AC_EGREP_CPP(yes, [
+#include <netinet/in.h>
+#ifdef IPV6_INRIA_VERSION
+yes
+#endif],
+				[ipv6type=$i])
+			;;
+		kame)
+			dnl http://www.kame.net/
+			AC_EGREP_CPP(yes, [
+#include <netinet/in.h>
+#ifdef __KAME__
+yes
+#endif],
+				[ipv6type=$i;
+				ipv6lib=inet6
+				ipv6libdir=/usr/local/v6/lib
+				ipv6trylibc=yes])
+			;;
+		linux-glibc)
+			dnl http://www.v6.linux.or.jp/
+			AC_EGREP_CPP(yes, [
+#include <features.h>
+#if defined(__GLIBC__) && ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) || (__GLIBC__ > 2))
+yes
+#endif],
+				[ipv6type=$i;
+				ipv6trylibc=yes])
+			;;
+		linux-inet6)
+			dnl http://www.v6.linux.or.jp/
+			if test -d /usr/inet6; then
+				ipv6type=$i
+				ipv6lib=inet6
+				ipv6libdir=/usr/inet6/lib
+				BASECFLAGS="-I/usr/inet6/include $BASECFLAGS"
+			fi
+			;;
+		solaris)
+			if test -f /etc/netconfig; then
+                          if /usr/xpg4/bin/grep -q tcp6 /etc/netconfig; then
+				ipv6type=$i
+				ipv6trylibc=yes
+                          fi
+                        fi
+			;;
+		toshiba)
+			AC_EGREP_CPP(yes, [
+#include <sys/param.h>
+#ifdef _TOSHIBA_INET6
+yes
+#endif],
+				[ipv6type=$i;
+				ipv6lib=inet6;
+				ipv6libdir=/usr/local/v6/lib])
+			;;
+		v6d)
+			AC_EGREP_CPP(yes, [
+#include </usr/local/v6/include/sys/v6config.h>
+#ifdef __V6D__
+yes
+#endif],
+				[ipv6type=$i;
+				ipv6lib=v6;
+				ipv6libdir=/usr/local/v6/lib;
+				BASECFLAGS="-I/usr/local/v6/include $BASECFLAGS"])
+			;;
+		zeta)
+			AC_EGREP_CPP(yes, [
+#include <sys/param.h>
+#ifdef _ZETA_MINAMI_INET6
+yes
+#endif],
+				[ipv6type=$i;
+				ipv6lib=inet6;
+				ipv6libdir=/usr/local/v6/lib])
+			;;
+		esac
+		if test "$ipv6type" != "unknown"; then
+			break
+		fi
+	done
+	AC_MSG_RESULT($ipv6type)
+fi
+
+if test "$ipv6" = "yes" -a "$ipv6lib" != "none"; then
+	if test -d $ipv6libdir -a -f $ipv6libdir/lib$ipv6lib.a; then
+		LIBS="-L$ipv6libdir -l$ipv6lib $LIBS"
+		echo "using lib$ipv6lib"
+	else
+		if test $ipv6trylibc = "yes"; then
+			echo "using libc"
+		else
+			echo 'Fatal: no $ipv6lib library found.  cannot continue.'
+			echo "You need to fetch lib$ipv6lib.a from appropriate"
+			echo 'ipv6 kit and compile beforehand.'
+			exit 1
+		fi
+	fi
+fi
+
+# Check for --with-doc-strings
+AC_MSG_CHECKING(for --with-doc-strings)
+AC_ARG_WITH(doc-strings,
+            AC_HELP_STRING(--with(out)-doc-strings, disable/enable documentation strings))
+
+if test -z "$with_doc_strings"
+then with_doc_strings="yes"
+fi
+if test "$with_doc_strings" != "no"
+then
+    AC_DEFINE(WITH_DOC_STRINGS, 1,
+      [Define if you want documentation strings in extension modules])
+fi
+AC_MSG_RESULT($with_doc_strings)
+
+# Check for Python-specific malloc support
+AC_MSG_CHECKING(for --with-tsc)
+AC_ARG_WITH(tsc,
+[  --with(out)-tsc         enable/disable timestamp counter profile], [
+if test "$withval" != no
+then 
+  AC_DEFINE(WITH_TSC, 1, 
+    [Define to profile with the Pentium timestamp counter]) 
+    AC_MSG_RESULT(yes)
+else AC_MSG_RESULT(no)
+fi],
+[AC_MSG_RESULT(no)])
+
+# Check for Python-specific malloc support
+AC_MSG_CHECKING(for --with-pymalloc)
+AC_ARG_WITH(pymalloc,
+            AC_HELP_STRING(--with(out)-pymalloc, disable/enable specialized mallocs))
+
+if test -z "$with_pymalloc"
+then with_pymalloc="yes"
+fi
+if test "$with_pymalloc" != "no"
+then
+    AC_DEFINE(WITH_PYMALLOC, 1, 
+     [Define if you want to compile in Python-specific mallocs])
+fi
+AC_MSG_RESULT($with_pymalloc)
+
+# Check for --with-wctype-functions
+AC_MSG_CHECKING(for --with-wctype-functions)
+AC_ARG_WITH(wctype-functions, 
+            AC_HELP_STRING(--with-wctype-functions, use wctype.h functions),
+[
+if test "$withval" != no
+then 
+  AC_DEFINE(WANT_WCTYPE_FUNCTIONS, 1,
+  [Define if you want wctype.h functions to be used instead of the
+   one supplied by Python itself. (see Include/unicodectype.h).]) 
+  AC_MSG_RESULT(yes)
+else AC_MSG_RESULT(no)
+fi],
+[AC_MSG_RESULT(no)])
+
+# -I${DLINCLDIR} is added to the compile rule for importdl.o
+AC_SUBST(DLINCLDIR)
+DLINCLDIR=.
+
+# the dlopen() function means we might want to use dynload_shlib.o. some
+# platforms, such as AIX, have dlopen(), but don't want to use it.
+AC_CHECK_FUNCS(dlopen)
+
+# DYNLOADFILE specifies which dynload_*.o file we will use for dynamic
+# loading of modules.
+AC_SUBST(DYNLOADFILE)
+AC_MSG_CHECKING(DYNLOADFILE)
+if test -z "$DYNLOADFILE"
+then
+	case $ac_sys_system/$ac_sys_release in
+	AIX*) # Use dynload_shlib.c and dlopen() if we have it; otherwise dynload_aix.c
+	if test "$ac_cv_func_dlopen" = yes
+	then DYNLOADFILE="dynload_shlib.o"
+	else DYNLOADFILE="dynload_aix.o"
+	fi
+	;;
+	BeOS*) DYNLOADFILE="dynload_beos.o";;
+	hp*|HP*) DYNLOADFILE="dynload_hpux.o";;
+	# Use dynload_next.c only on 10.2 and below, which don't have native dlopen()
+	Darwin/@<:@0156@:>@\..*) DYNLOADFILE="dynload_next.o";;
+	atheos*) DYNLOADFILE="dynload_atheos.o";;
+	*)
+	# use dynload_shlib.c and dlopen() if we have it; otherwise stub
+	# out any dynamic loading
+	if test "$ac_cv_func_dlopen" = yes
+	then DYNLOADFILE="dynload_shlib.o"
+	else DYNLOADFILE="dynload_stub.o"
+	fi
+	;;
+	esac
+fi
+AC_MSG_RESULT($DYNLOADFILE)
+if test "$DYNLOADFILE" != "dynload_stub.o"
+then
+	AC_DEFINE(HAVE_DYNAMIC_LOADING, 1,
+        [Defined when any dynamic module loading is enabled.])
+fi
+
+# MACHDEP_OBJS can be set to platform-specific object files needed by Python
+
+AC_SUBST(MACHDEP_OBJS)
+AC_MSG_CHECKING(MACHDEP_OBJS)
+if test -z "$MACHDEP_OBJS"
+then
+	MACHDEP_OBJS=$extra_machdep_objs
+else
+	MACHDEP_OBJS="$MACHDEP_OBJS $extra_machdep_objs"
+fi
+AC_MSG_RESULT(MACHDEP_OBJS)
+
+# checks for library functions
+AC_CHECK_FUNCS(alarm bind_textdomain_codeset chown clock confstr ctermid \
+ execv fork fpathconf ftime ftruncate \
+ gai_strerror getgroups getlogin getloadavg getpeername getpgid getpid \
+ getpriority getpwent getspnam getspent getsid getwd \
+ kill killpg lchown lstat mkfifo mknod mktime \
+ mremap nice pathconf pause plock poll pthread_init \
+ putenv readlink realpath \
+ select setegid seteuid setgid \
+ setlocale setregid setreuid setsid setpgid setpgrp setuid setvbuf snprintf \
+ sigaction siginterrupt sigrelse strftime \
+ sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \
+ truncate uname unsetenv utimes waitpid wait3 wait4 wcscoll _getpty)
+
+# For some functions, having a definition is not sufficient, since
+# we want to take their address.
+AC_MSG_CHECKING(for chroot)
+AC_TRY_COMPILE([#include <unistd.h>], void *x=chroot,
+  AC_DEFINE(HAVE_CHROOT, 1, Define if you have the 'chroot' function.)
+  AC_MSG_RESULT(yes),
+  AC_MSG_RESULT(no)
+)
+AC_MSG_CHECKING(for link)
+AC_TRY_COMPILE([#include <unistd.h>], void *x=link,
+  AC_DEFINE(HAVE_LINK, 1, Define if you have the 'link' function.)
+  AC_MSG_RESULT(yes),
+  AC_MSG_RESULT(no)
+)
+AC_MSG_CHECKING(for symlink)
+AC_TRY_COMPILE([#include <unistd.h>], void *x=symlink,
+  AC_DEFINE(HAVE_SYMLINK, 1, Define if you have the 'symlink' function.)
+  AC_MSG_RESULT(yes),
+  AC_MSG_RESULT(no)
+)
+AC_MSG_CHECKING(for fchdir)
+AC_TRY_COMPILE([#include <unistd.h>], void *x=fchdir,
+  AC_DEFINE(HAVE_FCHDIR, 1, Define if you have the 'fchdir' function.)
+  AC_MSG_RESULT(yes),
+  AC_MSG_RESULT(no)
+)
+AC_MSG_CHECKING(for fsync)
+AC_TRY_COMPILE([#include <unistd.h>], void *x=fsync,
+  AC_DEFINE(HAVE_FSYNC, 1, Define if you have the 'fsync' function.)
+  AC_MSG_RESULT(yes),
+  AC_MSG_RESULT(no)
+)
+AC_MSG_CHECKING(for fdatasync)
+AC_TRY_COMPILE([#include <unistd.h>], void *x=fdatasync,
+  AC_DEFINE(HAVE_FDATASYNC, 1, Define if you have the 'fdatasync' function.)
+  AC_MSG_RESULT(yes),
+  AC_MSG_RESULT(no)
+)
+
+# On some systems (eg. FreeBSD 5), we would find a definition of the
+# functions ctermid_r, setgroups in the library, but no prototype
+# (e.g. because we use _XOPEN_SOURCE). See whether we can take their
+# address to avoid compiler warnings and potential miscompilations
+# because of the missing prototypes.
+
+AC_MSG_CHECKING(for ctermid_r)
+AC_TRY_COMPILE([
+#include "confdefs.h" 
+#include <stdio.h>
+], void* p = ctermid_r,
+  AC_DEFINE(HAVE_CTERMID_R, 1, Define if you have the 'ctermid_r' function.)
+  AC_MSG_RESULT(yes),
+  AC_MSG_RESULT(no)
+)
+
+AC_MSG_CHECKING(for flock)
+AC_TRY_COMPILE([
+#include "confdefs.h" 
+#include <sys/file.h>
+], void* p = flock,
+  AC_DEFINE(HAVE_FLOCK, 1, Define if you have the 'flock' function.)
+  AC_MSG_RESULT(yes),
+  AC_MSG_RESULT(no)
+)
+
+AC_MSG_CHECKING(for getpagesize)
+AC_TRY_COMPILE([
+#include "confdefs.h" 
+#include <unistd.h>
+], void* p = getpagesize,
+  AC_DEFINE(HAVE_GETPAGESIZE, 1, Define if you have the 'getpagesize' function.)
+  AC_MSG_RESULT(yes),
+  AC_MSG_RESULT(no)
+)
+
+dnl check for true
+AC_CHECK_PROGS(TRUE, true, /bin/true)
+
+dnl On some systems (e.g. Solaris 9), hstrerror and inet_aton are in -lresolv
+dnl On others, they are in the C library, so we to take no action
+AC_CHECK_LIB(c, inet_aton, [$ac_cv_prog_TRUE],
+  AC_CHECK_LIB(resolv, inet_aton)
+)
+
+dnl Check if system zlib has *Copy() functions
+dnl
+dnl On MacOSX the linker will search for dylibs on the entire linker path
+dnl before searching for static libraries. setup.py adds -Wl,-search_paths_first
+dnl to revert to a more traditional unix behaviour and make it possible to
+dnl override the system libz with a local static library of libz. Temporarily
+dnl add that flag to our CFLAGS as well to ensure that we check the version
+dnl of libz that will be used by setup.py. 
+dnl The -L/usr/local/lib is needed as wel to get the same compilation 
+dnl environment as setup.py (and leaving it out can cause configure to use the
+dnl wrong version of the library)
+case $ac_sys_system/$ac_sys_release in
+Darwin/*) 
+	_CUR_CFLAGS="${CFLAGS}"
+	_CUR_LDFLAGS="${LDFLAGS}"
+	CFLAGS="${CFLAGS} -Wl,-search_paths_first"
+	LDFLAGS="${LDFLAGS} -Wl,-search_paths_first -L/usr/local/lib"
+	;;
+esac
+
+AC_CHECK_LIB(z, inflateCopy, AC_DEFINE(HAVE_ZLIB_COPY, 1, Define if the zlib library has inflateCopy))
+
+case $ac_sys_system/$ac_sys_release in
+Darwin/*) 
+	CFLAGS="${_CUR_CFLAGS}"
+	LDFLAGS="${_CUR_LDFLAGS}"
+	;;
+esac
+
+AC_MSG_CHECKING(for hstrerror)
+AC_TRY_LINK([
+#include "confdefs.h" 
+#include <netdb.h>
+], void* p = hstrerror; hstrerror(0),
+  AC_DEFINE(HAVE_HSTRERROR, 1, Define if you have the 'hstrerror' function.)
+  AC_MSG_RESULT(yes),
+  AC_MSG_RESULT(no)
+)
+
+AC_MSG_CHECKING(for inet_aton)
+AC_TRY_LINK([
+#include "confdefs.h" 
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+], void* p = inet_aton;inet_aton(0,0),
+  AC_DEFINE(HAVE_INET_ATON, 1, Define if you have the 'inet_aton' function.)
+  AC_MSG_RESULT(yes),
+  AC_MSG_RESULT(no)
+)
+
+AC_MSG_CHECKING(for inet_pton)
+AC_TRY_COMPILE([
+#include "confdefs.h" 
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+], void* p = inet_pton,
+  AC_DEFINE(HAVE_INET_PTON, 1, Define if you have the 'inet_pton' function.)
+  AC_MSG_RESULT(yes),
+  AC_MSG_RESULT(no)
+)
+
+# On some systems, setgroups is in unistd.h, on others, in grp.h
+AC_MSG_CHECKING(for setgroups)
+AC_TRY_COMPILE([
+#include "confdefs.h" 
+#include <unistd.h>
+#ifdef HAVE_GRP_H
+#include <grp.h>
+#endif
+], 
+void* p = setgroups,
+  AC_DEFINE(HAVE_SETGROUPS, 1, Define if you have the 'setgroups' function.)
+  AC_MSG_RESULT(yes),
+  AC_MSG_RESULT(no)
+)
+
+# check for openpty and forkpty
+
+AC_CHECK_FUNCS(openpty,, 
+   AC_CHECK_LIB(util,openpty,
+     [AC_DEFINE(HAVE_OPENPTY) LIBS="$LIBS -lutil"],
+     AC_CHECK_LIB(bsd,openpty, [AC_DEFINE(HAVE_OPENPTY) LIBS="$LIBS -lbsd"])
+   )
+)
+AC_CHECK_FUNCS(forkpty,, 
+   AC_CHECK_LIB(util,forkpty, 
+     [AC_DEFINE(HAVE_FORKPTY) LIBS="$LIBS -lutil"],
+     AC_CHECK_LIB(bsd,forkpty, [AC_DEFINE(HAVE_FORKPTY) LIBS="$LIBS -lbsd"])
+   )
+)
+
+# check for long file support functions
+AC_CHECK_FUNCS(fseek64 fseeko fstatvfs ftell64 ftello statvfs)
+
+AC_REPLACE_FUNCS(dup2 getcwd strdup strerror memmove)
+AC_CHECK_FUNCS(getpgrp, 
+  AC_TRY_COMPILE([#include <unistd.h>], 
+   [getpgrp(0);], 
+   AC_DEFINE(GETPGRP_HAVE_ARG, 1,
+   [Define if getpgrp() must be called as getpgrp(0).])
+ )
+)
+AC_CHECK_FUNCS(setpgrp,
+  AC_TRY_COMPILE([#include <unistd.h>],
+    [setpgrp(0,0);],
+    AC_DEFINE(SETPGRP_HAVE_ARG, 1,
+    [Define if setpgrp() must be called as setpgrp(0, 0).])
+  )
+)
+AC_CHECK_FUNCS(gettimeofday, 
+  AC_TRY_COMPILE([#include <sys/time.h>], 
+    [gettimeofday((struct timeval*)0,(struct timezone*)0);], ,
+    AC_DEFINE(GETTIMEOFDAY_NO_TZ, 1,
+    [Define if gettimeofday() does not have second (timezone) argument
+     This is the case on Motorola V4 (R40V4.2)])
+  )
+)
+
+AC_MSG_CHECKING(for major, minor, and makedev)
+AC_TRY_LINK([
+#if defined(MAJOR_IN_MKDEV)
+#include <sys/mkdev.h>
+#elif defined(MAJOR_IN_SYSMACROS)
+#include <sys/sysmacros.h>
+#else
+#include <sys/types.h>
+#endif
+],[
+  makedev(major(0),minor(0));
+],[
+  AC_DEFINE(HAVE_DEVICE_MACROS, 1,
+	    [Define to 1 if you have the device macros.])
+  AC_MSG_RESULT(yes)
+],[
+  AC_MSG_RESULT(no)
+])
+
+# On OSF/1 V5.1, getaddrinfo is available, but a define
+# for [no]getaddrinfo in netdb.h. 
+AC_MSG_CHECKING(for getaddrinfo)
+AC_TRY_LINK([
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <stdio.h>
+],[
+getaddrinfo(NULL, NULL, NULL, NULL);
+], [
+AC_MSG_RESULT(yes)
+AC_MSG_CHECKING(getaddrinfo bug)
+AC_TRY_RUN([
+#include <sys/types.h>
+#include <netdb.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+main()
+{
+  int passive, gaierr, inet4 = 0, inet6 = 0;
+  struct addrinfo hints, *ai, *aitop;
+  char straddr[INET6_ADDRSTRLEN], strport[16];
+
+  for (passive = 0; passive <= 1; passive++) {
+    memset(&hints, 0, sizeof(hints));
+    hints.ai_family = AF_UNSPEC;
+    hints.ai_flags = passive ? AI_PASSIVE : 0;
+    hints.ai_socktype = SOCK_STREAM;
+    hints.ai_protocol = IPPROTO_TCP;
+    if ((gaierr = getaddrinfo(NULL, "54321", &hints, &aitop)) != 0) {
+      (void)gai_strerror(gaierr);
+      goto bad;
+    }
+    for (ai = aitop; ai; ai = ai->ai_next) {
+      if (ai->ai_addr == NULL ||
+          ai->ai_addrlen == 0 ||
+          getnameinfo(ai->ai_addr, ai->ai_addrlen,
+                      straddr, sizeof(straddr), strport, sizeof(strport),
+                      NI_NUMERICHOST|NI_NUMERICSERV) != 0) {
+        goto bad;
+      }
+      switch (ai->ai_family) {
+      case AF_INET:
+        if (strcmp(strport, "54321") != 0) {
+          goto bad;
+        }
+        if (passive) {
+          if (strcmp(straddr, "0.0.0.0") != 0) {
+            goto bad;
+          }
+        } else {
+          if (strcmp(straddr, "127.0.0.1") != 0) {
+            goto bad;
+          }
+        }
+        inet4++;
+        break;
+      case AF_INET6:
+        if (strcmp(strport, "54321") != 0) {
+          goto bad;
+        }
+        if (passive) {
+          if (strcmp(straddr, "::") != 0) {
+            goto bad;
+          }
+        } else {
+          if (strcmp(straddr, "::1") != 0) {
+            goto bad;
+          }
+        }
+        inet6++;
+        break;
+      case AF_UNSPEC:
+        goto bad;
+        break;
+      default:
+        /* another family support? */
+        break;
+      }
+    }
+  }
+
+  if (!(inet4 == 0 || inet4 == 2))
+    goto bad;
+  if (!(inet6 == 0 || inet6 == 2))
+    goto bad;
+
+  if (aitop)
+    freeaddrinfo(aitop);
+  exit(0);
+
+ bad:
+  if (aitop)
+    freeaddrinfo(aitop);
+  exit(1);
+}
+],
+AC_MSG_RESULT(good)
+buggygetaddrinfo=no,
+AC_MSG_RESULT(buggy)
+buggygetaddrinfo=yes,
+AC_MSG_RESULT(buggy)
+buggygetaddrinfo=yes)], [
+AC_MSG_RESULT(no)
+buggygetaddrinfo=yes
+])
+
+if test "$buggygetaddrinfo" = "yes"; then
+	if test "$ipv6" = "yes"; then
+		echo 'Fatal: You must get working getaddrinfo() function.'
+		echo '       or you can specify "--disable-ipv6"'.
+		exit 1
+	fi
+else
+	AC_DEFINE(HAVE_GETADDRINFO, 1, [Define if you have the getaddrinfo function.])
+fi
+AC_CHECK_FUNCS(getnameinfo)
+
+# checks for structures
+AC_HEADER_TIME
+AC_STRUCT_TM
+AC_STRUCT_TIMEZONE
+AC_CHECK_MEMBERS([struct stat.st_rdev])
+AC_CHECK_MEMBERS([struct stat.st_blksize])
+AC_CHECK_MEMBERS([struct stat.st_flags])
+AC_CHECK_MEMBERS([struct stat.st_gen])
+AC_CHECK_MEMBERS([struct stat.st_birthtime])
+AC_STRUCT_ST_BLOCKS
+
+AC_MSG_CHECKING(for time.h that defines altzone)
+AC_CACHE_VAL(ac_cv_header_time_altzone,
+[AC_TRY_COMPILE([#include <time.h>], [return altzone;],
+  ac_cv_header_time_altzone=yes,
+  ac_cv_header_time_altzone=no)])
+AC_MSG_RESULT($ac_cv_header_time_altzone)
+if test $ac_cv_header_time_altzone = yes; then
+  AC_DEFINE(HAVE_ALTZONE, 1, [Define this if your time.h defines altzone.])
+fi
+
+was_it_defined=no
+AC_MSG_CHECKING(whether sys/select.h and sys/time.h may both be included)
+AC_TRY_COMPILE([
+#include <sys/types.h>
+#include <sys/select.h>
+#include <sys/time.h>
+], [;], [
+  AC_DEFINE(SYS_SELECT_WITH_SYS_TIME, 1,
+  [Define if  you can safely include both <sys/select.h> and <sys/time.h>
+   (which you can't on SCO ODT 3.0).]) 
+  was_it_defined=yes
+])
+AC_MSG_RESULT($was_it_defined)
+
+AC_MSG_CHECKING(for addrinfo)
+AC_CACHE_VAL(ac_cv_struct_addrinfo,
+AC_TRY_COMPILE([
+#		include <netdb.h>],
+	[struct addrinfo a],
+	ac_cv_struct_addrinfo=yes,
+	ac_cv_struct_addrinfo=no))
+AC_MSG_RESULT($ac_cv_struct_addrinfo)
+if test $ac_cv_struct_addrinfo = yes; then
+	AC_DEFINE(HAVE_ADDRINFO, 1, [struct addrinfo (netdb.h)])
+fi
+
+AC_MSG_CHECKING(for sockaddr_storage)
+AC_CACHE_VAL(ac_cv_struct_sockaddr_storage,
+AC_TRY_COMPILE([
+#		include <sys/types.h>
+#		include <sys/socket.h>],
+	[struct sockaddr_storage s],
+	ac_cv_struct_sockaddr_storage=yes,
+	ac_cv_struct_sockaddr_storage=no))
+AC_MSG_RESULT($ac_cv_struct_sockaddr_storage)
+if test $ac_cv_struct_sockaddr_storage = yes; then
+	AC_DEFINE(HAVE_SOCKADDR_STORAGE, 1, [struct sockaddr_storage (sys/socket.h)])
+fi
+
+# checks for compiler characteristics
+
+AC_C_CHAR_UNSIGNED
+AC_C_CONST
+
+works=no
+AC_MSG_CHECKING(for working volatile)
+AC_TRY_COMPILE([],[volatile int x; x = 0;], works=yes, 
+  AC_DEFINE(volatile, [], [Define to empty if the keyword does not work.])
+)
+AC_MSG_RESULT($works)
+
+works=no
+AC_MSG_CHECKING(for working signed char)
+AC_TRY_COMPILE([], [signed char c;], works=yes, 
+  AC_DEFINE(signed, [], [Define to empty if the keyword does not work.])
+)
+AC_MSG_RESULT($works)
+
+have_prototypes=no
+AC_MSG_CHECKING(for prototypes)
+AC_TRY_COMPILE([int foo(int x) { return 0; }], [return foo(10);],[
+  AC_DEFINE(HAVE_PROTOTYPES, 1, 
+   [Define if your compiler supports function prototype]) 
+  have_prototypes=yes
+])
+AC_MSG_RESULT($have_prototypes)
+
+works=no
+AC_MSG_CHECKING(for variable length prototypes and stdarg.h)
+AC_TRY_COMPILE([
+#include <stdarg.h>
+int foo(int x, ...) {
+	va_list va;
+	va_start(va, x);
+	va_arg(va, int);
+	va_arg(va, char *);
+	va_arg(va, double);
+	return 0;
+}
+], [return foo(10, "", 3.14);], [
+  AC_DEFINE(HAVE_STDARG_PROTOTYPES, 1,
+   [Define if your compiler supports variable length function prototypes
+   (e.g. void fprintf(FILE *, char *, ...);) *and* <stdarg.h>]) 
+  works=yes
+])
+AC_MSG_RESULT($works)
+
+# check for socketpair
+AC_MSG_CHECKING(for socketpair)
+AC_TRY_COMPILE([
+#include <sys/types.h>
+#include <sys/socket.h>
+], void *x=socketpair,
+  AC_DEFINE(HAVE_SOCKETPAIR, 1, Define if you have the 'socketpair' function.)
+  AC_MSG_RESULT(yes),
+  AC_MSG_RESULT(no)
+)
+
+# check if sockaddr has sa_len member
+AC_MSG_CHECKING(if sockaddr has sa_len member)
+AC_TRY_COMPILE([#include <sys/types.h>
+#include <sys/socket.h>],
+[struct sockaddr x;
+x.sa_len = 0;],
+	AC_MSG_RESULT(yes)
+	AC_DEFINE(HAVE_SOCKADDR_SA_LEN, 1, [Define if sockaddr has sa_len member]),
+	AC_MSG_RESULT(no))
+
+va_list_is_array=no
+AC_MSG_CHECKING(whether va_list is an array)
+AC_TRY_COMPILE([
+#ifdef HAVE_STDARG_PROTOTYPES
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+], [va_list list1, list2; list1 = list2;], , [
+ AC_DEFINE(VA_LIST_IS_ARRAY, 1, [Define if a va_list is an array of some kind]) 
+ va_list_is_array=yes
+])
+AC_MSG_RESULT($va_list_is_array)
+
+# sigh -- gethostbyname_r is a mess; it can have 3, 5 or 6 arguments :-(
+AH_TEMPLATE(HAVE_GETHOSTBYNAME_R,
+  [Define this if you have some version of gethostbyname_r()])
+
+AC_CHECK_FUNC(gethostbyname_r, [
+  AC_DEFINE(HAVE_GETHOSTBYNAME_R)
+  AC_MSG_CHECKING([gethostbyname_r with 6 args])
+  OLD_CFLAGS=$CFLAGS
+  CFLAGS="$CFLAGS $MY_CPPFLAGS $MY_THREAD_CPPFLAGS $MY_CFLAGS"
+  AC_TRY_COMPILE([
+#   include <netdb.h>
+  ], [
+    char *name;
+    struct hostent *he, *res;
+    char buffer[2048];
+    int buflen = 2048;
+    int h_errnop;
+
+    (void) gethostbyname_r(name, he, buffer, buflen, &res, &h_errnop)
+  ], [
+    AC_DEFINE(HAVE_GETHOSTBYNAME_R)
+    AC_DEFINE(HAVE_GETHOSTBYNAME_R_6_ARG, 1,
+    [Define this if you have the 6-arg version of gethostbyname_r().])
+    AC_MSG_RESULT(yes)
+  ], [
+    AC_MSG_RESULT(no)
+    AC_MSG_CHECKING([gethostbyname_r with 5 args])
+    AC_TRY_COMPILE([
+#     include <netdb.h>
+    ], [
+      char *name;
+      struct hostent *he;
+      char buffer[2048];
+      int buflen = 2048;
+      int h_errnop;
+
+      (void) gethostbyname_r(name, he, buffer, buflen, &h_errnop)
+    ], [
+      AC_DEFINE(HAVE_GETHOSTBYNAME_R)
+      AC_DEFINE(HAVE_GETHOSTBYNAME_R_5_ARG, 1,
+      [Define this if you have the 5-arg version of gethostbyname_r().])
+      AC_MSG_RESULT(yes)
+    ], [
+      AC_MSG_RESULT(no)
+      AC_MSG_CHECKING([gethostbyname_r with 3 args])
+      AC_TRY_COMPILE([
+#       include <netdb.h>
+      ], [
+        char *name;
+        struct hostent *he;
+        struct hostent_data data;
+
+        (void) gethostbyname_r(name, he, &data);
+      ], [
+        AC_DEFINE(HAVE_GETHOSTBYNAME_R)
+        AC_DEFINE(HAVE_GETHOSTBYNAME_R_3_ARG, 1,
+        [Define this if you have the 3-arg version of gethostbyname_r().])
+        AC_MSG_RESULT(yes)
+      ], [
+        AC_MSG_RESULT(no)
+      ])
+    ])
+  ])
+  CFLAGS=$OLD_CFLAGS
+], [
+  AC_CHECK_FUNCS(gethostbyname)
+])
+AC_SUBST(HAVE_GETHOSTBYNAME_R_6_ARG)
+AC_SUBST(HAVE_GETHOSTBYNAME_R_5_ARG)
+AC_SUBST(HAVE_GETHOSTBYNAME_R_3_ARG)
+AC_SUBST(HAVE_GETHOSTBYNAME_R)
+AC_SUBST(HAVE_GETHOSTBYNAME)
+
+# checks for system services
+# (none yet)
+
+# Linux requires this for correct f.p. operations
+AC_CHECK_FUNC(__fpu_control,
+  [],
+  [AC_CHECK_LIB(ieee, __fpu_control)
+])
+
+# Check for --with-fpectl
+AC_MSG_CHECKING(for --with-fpectl)
+AC_ARG_WITH(fpectl,
+            AC_HELP_STRING(--with-fpectl, enable SIGFPE catching),
+[
+if test "$withval" != no
+then 
+  AC_DEFINE(WANT_SIGFPE_HANDLER, 1,
+  [Define if you want SIGFPE handled (see Include/pyfpe.h).]) 
+  AC_MSG_RESULT(yes)
+else AC_MSG_RESULT(no)
+fi],
+[AC_MSG_RESULT(no)])
+
+# check for --with-libm=...
+AC_SUBST(LIBM)
+case $ac_sys_system in
+Darwin) ;;
+BeOS) ;;
+*) LIBM=-lm
+esac
+AC_MSG_CHECKING(for --with-libm=STRING)
+AC_ARG_WITH(libm,
+            AC_HELP_STRING(--with-libm=STRING, math library),
+[
+if test "$withval" = no
+then LIBM=
+     AC_MSG_RESULT(force LIBM empty)
+elif test "$withval" != yes
+then LIBM=$withval
+     AC_MSG_RESULT(set LIBM="$withval")
+else AC_MSG_ERROR([proper usage is --with-libm=STRING])
+fi],
+[AC_MSG_RESULT(default LIBM="$LIBM")])
+
+# check for --with-libc=...
+AC_SUBST(LIBC)
+AC_MSG_CHECKING(for --with-libc=STRING)
+AC_ARG_WITH(libc,
+            AC_HELP_STRING(--with-libc=STRING, C library),
+[
+if test "$withval" = no
+then LIBC=
+     AC_MSG_RESULT(force LIBC empty)
+elif test "$withval" != yes
+then LIBC=$withval
+     AC_MSG_RESULT(set LIBC="$withval")
+else AC_MSG_ERROR([proper usage is --with-libc=STRING])
+fi],
+[AC_MSG_RESULT(default LIBC="$LIBC")])
+
+# check for hypot() in math library
+LIBS_SAVE=$LIBS
+LIBS="$LIBS $LIBM"
+AC_REPLACE_FUNCS(hypot)
+LIBS=$LIBS_SAVE
+
+# check for wchar.h
+AC_CHECK_HEADER(wchar.h, [
+  AC_DEFINE(HAVE_WCHAR_H, 1, 
+  [Define if the compiler provides a wchar.h header file.]) 
+  wchar_h="yes"
+],
+wchar_h="no"
+)
+
+# determine wchar_t size
+if test "$wchar_h" = yes
+then
+  AC_CHECK_SIZEOF(wchar_t, 4, [#include <wchar.h>])
+fi
+
+AC_MSG_CHECKING(for UCS-4 tcl)
+have_ucs4_tcl=no
+AC_TRY_COMPILE([
+#include <tcl.h>
+#if TCL_UTF_MAX != 6
+# error "NOT UCS4_TCL"
+#endif], [], [
+  AC_DEFINE(HAVE_UCS4_TCL, 1, [Define this if you have tcl and TCL_UTF_MAX==6])
+  have_ucs4_tcl=yes
+])
+AC_MSG_RESULT($have_ucs4_tcl)
+
+# check whether wchar_t is signed or not
+if test "$wchar_h" = yes
+then
+  # check whether wchar_t is signed or not
+  AC_MSG_CHECKING(whether wchar_t is signed)
+  AC_CACHE_VAL(ac_cv_wchar_t_signed, [
+  AC_TRY_RUN([
+  #include <wchar.h>
+  int main()
+  {
+	/* Success: exit code 0 */
+        exit((((wchar_t) -1) < ((wchar_t) 0)) ? 0 : 1);
+  }
+  ],
+  ac_cv_wchar_t_signed=yes,
+  ac_cv_wchar_t_signed=no,
+  ac_cv_wchar_t_signed=yes)])
+  AC_MSG_RESULT($ac_cv_wchar_t_signed)
+fi
+  
+AC_MSG_CHECKING(what type to use for unicode)
+dnl quadrigraphs "@<:@" and "@:>@" produce "[" and "]" in the output
+AC_ARG_ENABLE(unicode, 
+              AC_HELP_STRING(--enable-unicode@<:@=ucs@<:@24@:>@@:>@, Enable Unicode strings (default is yes)),
+              [],
+              [enable_unicode=yes])
+
+if test $enable_unicode = yes
+then
+  # Without any arguments, Py_UNICODE defaults to two-byte mode
+  case "$have_ucs4_tcl" in
+  yes) enable_unicode="ucs4"
+       ;;
+  *)   enable_unicode="ucs2"
+       ;;
+  esac
+fi
+
+AH_TEMPLATE(Py_UNICODE_SIZE,
+  [Define as the size of the unicode type.])
+case "$enable_unicode" in
+ucs2) unicode_size="2"
+      AC_DEFINE(Py_UNICODE_SIZE,2)
+      ;;
+ucs4) unicode_size="4"
+      AC_DEFINE(Py_UNICODE_SIZE,4)
+      ;;
+esac
+
+AH_TEMPLATE(PY_UNICODE_TYPE,
+  [Define as the integral type used for Unicode representation.])
+
+AC_SUBST(UNICODE_OBJS)
+if test "$enable_unicode" = "no"
+then
+  UNICODE_OBJS=""
+  AC_MSG_RESULT(not used)
+else
+  UNICODE_OBJS="Objects/unicodeobject.o Objects/unicodectype.o"
+  AC_DEFINE(Py_USING_UNICODE, 1,
+  [Define if you want to have a Unicode type.])
+
+  # wchar_t is only usable if it maps to an unsigned type
+  if test "$unicode_size" = "$ac_cv_sizeof_wchar_t" \
+          -a "$ac_cv_wchar_t_signed" = "no"
+  then
+    PY_UNICODE_TYPE="wchar_t"
+    AC_DEFINE(HAVE_USABLE_WCHAR_T, 1,
+    [Define if you have a useable wchar_t type defined in wchar.h; useable
+     means wchar_t must be an unsigned type with at least 16 bits. (see
+     Include/unicodeobject.h).])
+    AC_DEFINE(PY_UNICODE_TYPE,wchar_t)
+  elif test "$ac_cv_sizeof_short" = "$unicode_size"
+  then
+       PY_UNICODE_TYPE="unsigned short"
+       AC_DEFINE(PY_UNICODE_TYPE,unsigned short)
+  elif test "$ac_cv_sizeof_long" = "$unicode_size"
+  then
+       PY_UNICODE_TYPE="unsigned long"
+       AC_DEFINE(PY_UNICODE_TYPE,unsigned long)
+  else
+       PY_UNICODE_TYPE="no type found"
+  fi
+  AC_MSG_RESULT($PY_UNICODE_TYPE)
+fi
+
+# check for endianness
+AC_C_BIGENDIAN
+AH_VERBATIM([WORDS_BIGENDIAN],
+[
+ /* Define to 1 if your processor stores words with the most significant byte
+    first (like Motorola and SPARC, unlike Intel and VAX). 
+
+    The block below does compile-time checking for endianness on platforms
+    that use GCC and therefore allows compiling fat binaries on OSX by using 
+    '-arch ppc -arch i386' as the compile flags. The phrasing was choosen
+    such that the configure-result is used on systems that don't use GCC.
+  */
+#ifdef __BIG_ENDIAN__
+#define WORDS_BIGENDIAN 1
+#else
+#ifndef __LITTLE_ENDIAN__
+#undef WORDS_BIGENDIAN
+#endif
+#endif])
+
+# Check whether right shifting a negative integer extends the sign bit
+# or fills with zeros (like the Cray J90, according to Tim Peters).
+AC_MSG_CHECKING(whether right shift extends the sign bit)
+AC_CACHE_VAL(ac_cv_rshift_extends_sign, [
+AC_TRY_RUN([
+int main()
+{
+	exit(((-1)>>3 == -1) ? 0 : 1);
+}
+],
+ac_cv_rshift_extends_sign=yes,
+ac_cv_rshift_extends_sign=no,
+ac_cv_rshift_extends_sign=yes)])
+AC_MSG_RESULT($ac_cv_rshift_extends_sign)
+if test "$ac_cv_rshift_extends_sign" = no
+then
+  AC_DEFINE(SIGNED_RIGHT_SHIFT_ZERO_FILLS, 1,
+  [Define if i>>j for signed int i does not extend the sign bit
+   when i < 0])
+fi
+
+# check for getc_unlocked and related locking functions
+AC_MSG_CHECKING(for getc_unlocked() and friends)
+AC_CACHE_VAL(ac_cv_have_getc_unlocked, [
+AC_TRY_LINK([#include <stdio.h>],[
+	FILE *f = fopen("/dev/null", "r");
+	flockfile(f);
+	getc_unlocked(f);
+	funlockfile(f);
+], ac_cv_have_getc_unlocked=yes, ac_cv_have_getc_unlocked=no)])
+AC_MSG_RESULT($ac_cv_have_getc_unlocked)
+if test "$ac_cv_have_getc_unlocked" = yes
+then
+  AC_DEFINE(HAVE_GETC_UNLOCKED, 1,
+  [Define this if you have flockfile(), getc_unlocked(), and funlockfile()])
+fi
+
+# check where readline lives
+# save the value of LIBS so we don't actually link Python with readline
+LIBS_no_readline=$LIBS
+AC_CHECK_LIB(readline, readline)
+if test "$ac_cv_have_readline_readline" = no
+then
+  AC_CHECK_LIB(termcap, readline)
+fi
+
+# check for readline 2.1
+AC_CHECK_LIB(readline, rl_callback_handler_install,
+	AC_DEFINE(HAVE_RL_CALLBACK, 1,
+        [Define if you have readline 2.1]), , )
+
+# check for readline 2.2
+AC_TRY_CPP([#include <readline/readline.h>],
+have_readline=yes, have_readline=no)
+if test $have_readline = yes
+then
+  AC_EGREP_HEADER([extern int rl_completion_append_character;],
+  [readline/readline.h],
+  AC_DEFINE(HAVE_RL_COMPLETION_APPEND_CHARACTER, 1,
+  [Define if you have readline 2.2]), )
+fi
+
+# check for readline 4.0
+AC_CHECK_LIB(readline, rl_pre_input_hook,
+	AC_DEFINE(HAVE_RL_PRE_INPUT_HOOK, 1,
+        [Define if you have readline 4.0]), , )
+
+# check for readline 4.2
+AC_CHECK_LIB(readline, rl_completion_matches,
+	AC_DEFINE(HAVE_RL_COMPLETION_MATCHES, 1,
+        [Define if you have readline 4.2]), , )
+
+# also in readline 4.2
+AC_TRY_CPP([#include <readline/readline.h>],
+have_readline=yes, have_readline=no)
+if test $have_readline = yes
+then
+  AC_EGREP_HEADER([extern int rl_catch_signals;],
+  [readline/readline.h],
+  AC_DEFINE(HAVE_RL_CATCH_SIGNAL, 1,
+  [Define if you can turn off readline's signal handling.]), )
+fi
+
+# End of readline checks: restore LIBS
+LIBS=$LIBS_no_readline
+
+AC_MSG_CHECKING(for broken nice())
+AC_CACHE_VAL(ac_cv_broken_nice, [
+AC_TRY_RUN([
+int main()
+{
+	int val1 = nice(1);
+	if (val1 != -1 && val1 == nice(2))
+		exit(0);
+	exit(1);
+}
+],
+ac_cv_broken_nice=yes,
+ac_cv_broken_nice=no,
+ac_cv_broken_nice=no)])
+AC_MSG_RESULT($ac_cv_broken_nice)
+if test "$ac_cv_broken_nice" = yes
+then
+  AC_DEFINE(HAVE_BROKEN_NICE, 1,
+  [Define if nice() returns success/failure instead of the new priority.])
+fi
+
+AC_MSG_CHECKING(for broken poll())
+AC_TRY_RUN([
+#include <poll.h>
+
+int main (void)
+    {
+    struct pollfd poll_struct = { 42, POLLIN|POLLPRI|POLLOUT, 0 };
+    
+    close (42);
+
+    int poll_test = poll (&poll_struct, 1, 0);
+
+    if (poll_test < 0)
+        {
+        exit(0);
+        }
+    else if (poll_test == 0 && poll_struct.revents != POLLNVAL)
+        {
+        exit(0);
+        }
+    else
+        {
+        exit(1);
+        }
+    }
+],
+ac_cv_broken_poll=yes,
+ac_cv_broken_poll=no,
+ac_cv_broken_poll=no)
+AC_MSG_RESULT($ac_cv_broken_poll)
+if test "$ac_cv_broken_poll" = yes
+then
+  AC_DEFINE(HAVE_BROKEN_POLL, 1,
+      [Define if poll() sets errno on invalid file descriptors.])
+fi
+
+# Before we can test tzset, we need to check if struct tm has a tm_zone 
+# (which is not required by ISO C or UNIX spec) and/or if we support
+# tzname[]
+AC_STRUCT_TIMEZONE
+
+# check tzset(3) exists and works like we expect it to
+AC_MSG_CHECKING(for working tzset())
+AC_CACHE_VAL(ac_cv_working_tzset, [
+AC_TRY_RUN([
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+
+#if HAVE_TZNAME
+extern char *tzname[];
+#endif
+
+int main()
+{
+	/* Note that we need to ensure that not only does tzset(3)
+	   do 'something' with localtime, but it works as documented
+	   in the library reference and as expected by the test suite.
+	   This includes making sure that tzname is set properly if
+	   tm->tm_zone does not exist since it is the alternative way
+	   of getting timezone info.
+
+	   Red Hat 6.2 doesn't understand the southern hemisphere 
+	   after New Year's Day.
+	*/
+
+	time_t groundhogday = 1044144000; /* GMT-based */
+	time_t midyear = groundhogday + (365 * 24 * 3600 / 2);
+
+	putenv("TZ=UTC+0");
+	tzset();
+	if (localtime(&groundhogday)->tm_hour != 0)
+	    exit(1);
+#if HAVE_TZNAME
+	/* For UTC, tzname[1] is sometimes "", sometimes "   " */
+	if (strcmp(tzname[0], "UTC") || 
+		(tzname[1][0] != 0 && tzname[1][0] != ' '))
+	    exit(1);
+#endif
+
+	putenv("TZ=EST+5EDT,M4.1.0,M10.5.0");
+	tzset();
+	if (localtime(&groundhogday)->tm_hour != 19)
+	    exit(1);
+#if HAVE_TZNAME
+	if (strcmp(tzname[0], "EST") || strcmp(tzname[1], "EDT"))
+	    exit(1);
+#endif
+
+	putenv("TZ=AEST-10AEDT-11,M10.5.0,M3.5.0");
+	tzset();
+	if (localtime(&groundhogday)->tm_hour != 11)
+	    exit(1);
+#if HAVE_TZNAME
+	if (strcmp(tzname[0], "AEST") || strcmp(tzname[1], "AEDT"))
+	    exit(1);
+#endif
+
+#if HAVE_STRUCT_TM_TM_ZONE
+	if (strcmp(localtime(&groundhogday)->tm_zone, "AEDT"))
+	    exit(1);
+	if (strcmp(localtime(&midyear)->tm_zone, "AEST"))
+	    exit(1);
+#endif
+
+	exit(0);
+}
+],
+ac_cv_working_tzset=yes,
+ac_cv_working_tzset=no,
+ac_cv_working_tzset=no)])
+AC_MSG_RESULT($ac_cv_working_tzset)
+if test "$ac_cv_working_tzset" = yes
+then
+  AC_DEFINE(HAVE_WORKING_TZSET, 1,
+  [Define if tzset() actually switches the local timezone in a meaningful way.])
+fi
+
+# Look for subsecond timestamps in struct stat
+AC_MSG_CHECKING(for tv_nsec in struct stat)
+AC_CACHE_VAL(ac_cv_stat_tv_nsec,
+AC_TRY_COMPILE([#include <sys/stat.h>], [
+struct stat st;
+st.st_mtim.tv_nsec = 1;
+],
+ac_cv_stat_tv_nsec=yes,
+ac_cv_stat_tv_nsec=no,
+ac_cv_stat_tv_nsec=no))
+AC_MSG_RESULT($ac_cv_stat_tv_nsec)
+if test "$ac_cv_stat_tv_nsec" = yes
+then
+  AC_DEFINE(HAVE_STAT_TV_NSEC, 1,
+  [Define if you have struct stat.st_mtim.tv_nsec])
+fi
+
+# Look for BSD style subsecond timestamps in struct stat
+AC_MSG_CHECKING(for tv_nsec2 in struct stat)
+AC_CACHE_VAL(ac_cv_stat_tv_nsec2,
+AC_TRY_COMPILE([#include <sys/stat.h>], [
+struct stat st;
+st.st_mtimespec.tv_nsec = 1;
+],
+ac_cv_stat_tv_nsec2=yes,
+ac_cv_stat_tv_nsec2=no,
+ac_cv_stat_tv_nsec2=no))
+AC_MSG_RESULT($ac_cv_stat_tv_nsec2)
+if test "$ac_cv_stat_tv_nsec2" = yes
+then
+  AC_DEFINE(HAVE_STAT_TV_NSEC2, 1,
+  [Define if you have struct stat.st_mtimensec])
+fi
+
+# On HP/UX 11.0, mvwdelch is a block with a return statement
+AC_MSG_CHECKING(whether mvwdelch is an expression)
+AC_CACHE_VAL(ac_cv_mvwdelch_is_expression,
+AC_TRY_COMPILE([#include <curses.h>], [
+  int rtn;
+  rtn = mvwdelch(0,0,0);
+], ac_cv_mvwdelch_is_expression=yes,
+   ac_cv_mvwdelch_is_expression=no,
+   ac_cv_mvwdelch_is_expression=yes))
+AC_MSG_RESULT($ac_cv_mvwdelch_is_expression)
+
+if test "$ac_cv_mvwdelch_is_expression" = yes
+then
+  AC_DEFINE(MVWDELCH_IS_EXPRESSION, 1,
+  [Define if mvwdelch in curses.h is an expression.])
+fi
+
+AC_MSG_CHECKING(whether WINDOW has _flags)
+AC_CACHE_VAL(ac_cv_window_has_flags,
+AC_TRY_COMPILE([#include <curses.h>], [
+  WINDOW *w;
+  w->_flags = 0;
+], ac_cv_window_has_flags=yes,
+   ac_cv_window_has_flags=no,
+   ac_cv_window_has_flags=no))
+AC_MSG_RESULT($ac_cv_window_has_flags)
+
+
+if test "$ac_cv_window_has_flags" = yes
+then
+  AC_DEFINE(WINDOW_HAS_FLAGS, 1, 
+  [Define if WINDOW in curses.h offers a field _flags.])
+fi
+
+AC_MSG_CHECKING(for is_term_resized)
+AC_TRY_COMPILE([#include <curses.h>], void *x=is_term_resized,
+  AC_DEFINE(HAVE_CURSES_IS_TERM_RESIZED, 1, Define if you have the 'is_term_resized' function.)
+  AC_MSG_RESULT(yes),
+  AC_MSG_RESULT(no)
+)
+
+AC_MSG_CHECKING(for resize_term)
+AC_TRY_COMPILE([#include <curses.h>], void *x=resize_term,
+  AC_DEFINE(HAVE_CURSES_RESIZE_TERM, 1, Define if you have the 'resize_term' function.)
+  AC_MSG_RESULT(yes),
+  AC_MSG_RESULT(no)
+)
+
+AC_MSG_CHECKING(for resizeterm)
+AC_TRY_COMPILE([#include <curses.h>], void *x=resizeterm,
+  AC_DEFINE(HAVE_CURSES_RESIZETERM, 1, Define if you have the 'resizeterm' function.)
+  AC_MSG_RESULT(yes),
+  AC_MSG_RESULT(no)
+)
+
+AC_MSG_CHECKING(for /dev/ptmx)
+
+if test -r /dev/ptmx
+then
+  AC_MSG_RESULT(yes)
+  AC_DEFINE(HAVE_DEV_PTMX, 1,
+  [Define if we have /dev/ptmx.])
+else
+  AC_MSG_RESULT(no)
+fi
+
+AC_MSG_CHECKING(for /dev/ptc)
+
+if test -r /dev/ptc
+then
+  AC_MSG_RESULT(yes)
+  AC_DEFINE(HAVE_DEV_PTC, 1,
+  [Define if we have /dev/ptc.])
+else
+  AC_MSG_RESULT(no)
+fi
+
+AC_MSG_CHECKING(for %zd printf() format support)
+AC_TRY_RUN([#include <stdio.h>
+#include <stddef.h>
+#include <string.h>
+
+int main()
+{
+    char buffer[256];
+
+#ifdef HAVE_SSIZE_T
+typedef ssize_t Py_ssize_t;
+#elif SIZEOF_VOID_P == SIZEOF_LONG
+typedef long Py_ssize_t;
+#else
+typedef int Py_ssize_t;
+#endif
+
+    if(sprintf(buffer, "%zd", (size_t)123) < 0)
+       	return 1;
+
+    if (strcmp(buffer, "123"))
+	return 1;
+
+    if (sprintf(buffer, "%zd", (Py_ssize_t)-123) < 0)
+       	return 1;
+
+    if (strcmp(buffer, "-123"))
+	return 1;
+
+    return 0;
+}],
+[AC_MSG_RESULT(yes)
+ AC_DEFINE(PY_FORMAT_SIZE_T, "z", [Define to printf format modifier for Py_ssize_t])],
+ AC_MSG_RESULT(no))
+
+AC_CHECK_TYPE(socklen_t,,
+  AC_DEFINE(socklen_t,int,
+            Define to `int' if <sys/socket.h> does not define.),[
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+])
+
+AC_SUBST(THREADHEADERS)
+
+for h in `(cd $srcdir;echo Python/thread_*.h)`
+do
+  THREADHEADERS="$THREADHEADERS \$(srcdir)/$h"
+done
+
+AC_SUBST(SRCDIRS)
+SRCDIRS="Parser Grammar Objects Python Modules Mac"
+AC_MSG_CHECKING(for build directories)
+for dir in $SRCDIRS; do
+    if test ! -d $dir; then
+        mkdir $dir
+    fi
+done
+AC_MSG_RESULT(done)
+
+# generate output files
+AC_CONFIG_FILES(Makefile.pre Modules/Setup.config)
+AC_OUTPUT
+
+echo "creating Modules/Setup"
+if test ! -f Modules/Setup
+then
+	cp $srcdir/Modules/Setup.dist Modules/Setup
+fi
+
+echo "creating Modules/Setup.local"
+if test ! -f Modules/Setup.local
+then
+	echo "# Edit this file for local setup changes" >Modules/Setup.local
+fi
+
+echo "creating Makefile"
+$SHELL $srcdir/Modules/makesetup -c $srcdir/Modules/config.c.in \
+			-s Modules Modules/Setup.config \
+			Modules/Setup.local Modules/Setup
+mv config.c Modules

Added: vendor/Python/current/install-sh
===================================================================
--- vendor/Python/current/install-sh	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/install-sh	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,294 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+#
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.  It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+	-c) instcmd=$cpprog
+	    shift
+	    continue;;
+
+	-d) dir_arg=true
+	    shift
+	    continue;;
+
+	-m) chmodcmd="$chmodprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-o) chowncmd="$chownprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-g) chgrpcmd="$chgrpprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-s) stripcmd=$stripprog
+	    shift
+	    continue;;
+
+	-t=*) transformarg=`echo $1 | sed 's/-t=//'`
+	    shift
+	    continue;;
+
+	-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+	    shift
+	    continue;;
+
+	*)  if [ x"$src" = x ]
+	    then
+		src=$1
+	    else
+		# this colon is to work around a 386BSD /bin/sh bug
+		:
+		dst=$1
+	    fi
+	    shift
+	    continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+	echo "$0: no input file specified" >&2
+	exit 1
+else
+	:
+fi
+
+if [ x"$dir_arg" != x ]; then
+	dst=$src
+	src=""
+
+	if [ -d "$dst" ]; then
+		instcmd=:
+		chmodcmd=""
+	else
+		instcmd=$mkdirprog
+	fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad
+# if $src (and thus $dsttmp) contains '*'.
+
+	if [ -f "$src" ] || [ -d "$src" ]
+	then
+		:
+	else
+		echo "$0: $src does not exist" >&2
+		exit 1
+	fi
+
+	if [ x"$dst" = x ]
+	then
+		echo "$0: no destination specified" >&2
+		exit 1
+	else
+		:
+	fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+	if [ -d "$dst" ]
+	then
+		dst=$dst/`basename "$src"`
+	else
+		:
+	fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+#  this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='
+	'
+IFS="${IFS-$defaultIFS}"
+
+oIFS=$IFS
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS=$oIFS
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+	pathcomp=$pathcomp$1
+	shift
+
+	if [ ! -d "$pathcomp" ] ;
+        then
+		$mkdirprog "$pathcomp"
+	else
+		:
+	fi
+
+	pathcomp=$pathcomp/
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+	$doit $instcmd "$dst" &&
+
+	if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi &&
+	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi &&
+	if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi &&
+	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+	if [ x"$transformarg" = x ]
+	then
+		dstfile=`basename "$dst"`
+	else
+		dstfile=`basename "$dst" $transformbasename |
+			sed $transformarg`$transformbasename
+	fi
+
+# don't allow the sed command to completely eliminate the filename
+
+	if [ x"$dstfile" = x ]
+	then
+		dstfile=`basename "$dst"`
+	else
+		:
+	fi
+
+# Make a couple of temp file names in the proper directory.
+
+	dsttmp=$dstdir/#inst.$$#
+	rmtmp=$dstdir/#rm.$$#
+
+# Trap to clean up temp files at exit.
+
+	trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0
+	trap '(exit $?); exit' 1 2 13 15
+
+# Move or copy the file name to the temp name
+
+	$doit $instcmd "$src" "$dsttmp" &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing.  If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+	if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi &&
+	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi &&
+	if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi &&
+	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi &&
+
+# Now remove or move aside any old file at destination location.  We try this
+# two ways since rm can't unlink itself on some systems and the destination
+# file might be busy for other reasons.  In this case, the final cleanup
+# might fail but the new file should still install successfully.
+
+{
+	if [ -f "$dstdir/$dstfile" ]
+	then
+		$doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null ||
+		$doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null ||
+		{
+		  echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
+		  (exit 1); exit
+		}
+	else
+		:
+	fi
+} &&
+
+# Now rename the file to the real destination.
+
+	$doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
+
+fi &&
+
+# The final little trick to "correctly" pass the exit status to the exit trap.
+
+{
+	(exit 0); exit
+}


Property changes on: vendor/Python/current/install-sh
___________________________________________________________________
Name: svn:executable
   + 

Added: vendor/Python/current/pyconfig.h.in
===================================================================
--- vendor/Python/current/pyconfig.h.in	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/pyconfig.h.in	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,996 @@
+/* pyconfig.h.in.  Generated from configure.in by autoheader.  */
+
+
+#ifndef Py_PYCONFIG_H
+#define Py_PYCONFIG_H
+
+
+/* Define for AIX if your compiler is a genuine IBM xlC/xlC_r and you want
+   support for AIX C++ shared extension modules. */
+#undef AIX_GENUINE_CPLUSPLUS
+
+/* Define this if you have AtheOS threads. */
+#undef ATHEOS_THREADS
+
+/* Define this if you have BeOS threads. */
+#undef BEOS_THREADS
+
+/* Define if you have the Mach cthreads package */
+#undef C_THREADS
+
+/* Define if --enable-ipv6 is specified */
+#undef ENABLE_IPV6
+
+/* Define if getpgrp() must be called as getpgrp(0). */
+#undef GETPGRP_HAVE_ARG
+
+/* Define if gettimeofday() does not have second (timezone) argument This is
+   the case on Motorola V4 (R40V4.2) */
+#undef GETTIMEOFDAY_NO_TZ
+
+/* struct addrinfo (netdb.h) */
+#undef HAVE_ADDRINFO
+
+/* Define to 1 if you have the `alarm' function. */
+#undef HAVE_ALARM
+
+/* Define this if your time.h defines altzone. */
+#undef HAVE_ALTZONE
+
+/* Define to 1 if you have the <asm/types.h> header file. */
+#undef HAVE_ASM_TYPES_H
+
+/* Define to 1 if you have the `bind_textdomain_codeset' function. */
+#undef HAVE_BIND_TEXTDOMAIN_CODESET
+
+/* Define to 1 if you have the <bluetooth/bluetooth.h> header file. */
+#undef HAVE_BLUETOOTH_BLUETOOTH_H
+
+/* Define to 1 if you have the <bluetooth.h> header file. */
+#undef HAVE_BLUETOOTH_H
+
+/* Define if nice() returns success/failure instead of the new priority. */
+#undef HAVE_BROKEN_NICE
+
+/* Define if poll() sets errno on invalid file descriptors. */
+#undef HAVE_BROKEN_POLL
+
+/* Define if the Posix semaphores do not work on your system */
+#undef HAVE_BROKEN_POSIX_SEMAPHORES
+
+/* Define if pthread_sigmask() does not work on your system. */
+#undef HAVE_BROKEN_PTHREAD_SIGMASK
+
+/* Define to 1 if you have the `chown' function. */
+#undef HAVE_CHOWN
+
+/* Define if you have the 'chroot' function. */
+#undef HAVE_CHROOT
+
+/* Define to 1 if you have the `clock' function. */
+#undef HAVE_CLOCK
+
+/* Define to 1 if you have the `confstr' function. */
+#undef HAVE_CONFSTR
+
+/* Define to 1 if you have the <conio.h> header file. */
+#undef HAVE_CONIO_H
+
+/* Define to 1 if you have the `ctermid' function. */
+#undef HAVE_CTERMID
+
+/* Define if you have the 'ctermid_r' function. */
+#undef HAVE_CTERMID_R
+
+/* Define to 1 if you have the <curses.h> header file. */
+#undef HAVE_CURSES_H
+
+/* Define if you have the 'is_term_resized' function. */
+#undef HAVE_CURSES_IS_TERM_RESIZED
+
+/* Define if you have the 'resizeterm' function. */
+#undef HAVE_CURSES_RESIZETERM
+
+/* Define if you have the 'resize_term' function. */
+#undef HAVE_CURSES_RESIZE_TERM
+
+/* Define to 1 if you have the device macros. */
+#undef HAVE_DEVICE_MACROS
+
+/* Define if we have /dev/ptc. */
+#undef HAVE_DEV_PTC
+
+/* Define if we have /dev/ptmx. */
+#undef HAVE_DEV_PTMX
+
+/* Define to 1 if you have the <direct.h> header file. */
+#undef HAVE_DIRECT_H
+
+/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
+   */
+#undef HAVE_DIRENT_H
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the `dlopen' function. */
+#undef HAVE_DLOPEN
+
+/* Define to 1 if you have the `dup2' function. */
+#undef HAVE_DUP2
+
+/* Defined when any dynamic module loading is enabled. */
+#undef HAVE_DYNAMIC_LOADING
+
+/* Define to 1 if you have the <errno.h> header file. */
+#undef HAVE_ERRNO_H
+
+/* Define to 1 if you have the `execv' function. */
+#undef HAVE_EXECV
+
+/* Define if you have the 'fchdir' function. */
+#undef HAVE_FCHDIR
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
+/* Define if you have the 'fdatasync' function. */
+#undef HAVE_FDATASYNC
+
+/* Define if you have the 'flock' function. */
+#undef HAVE_FLOCK
+
+/* Define to 1 if you have the `fork' function. */
+#undef HAVE_FORK
+
+/* Define to 1 if you have the `forkpty' function. */
+#undef HAVE_FORKPTY
+
+/* Define to 1 if you have the `fpathconf' function. */
+#undef HAVE_FPATHCONF
+
+/* Define to 1 if you have the `fseek64' function. */
+#undef HAVE_FSEEK64
+
+/* Define to 1 if you have the `fseeko' function. */
+#undef HAVE_FSEEKO
+
+/* Define to 1 if you have the `fstatvfs' function. */
+#undef HAVE_FSTATVFS
+
+/* Define if you have the 'fsync' function. */
+#undef HAVE_FSYNC
+
+/* Define to 1 if you have the `ftell64' function. */
+#undef HAVE_FTELL64
+
+/* Define to 1 if you have the `ftello' function. */
+#undef HAVE_FTELLO
+
+/* Define to 1 if you have the `ftime' function. */
+#undef HAVE_FTIME
+
+/* Define to 1 if you have the `ftruncate' function. */
+#undef HAVE_FTRUNCATE
+
+/* Define to 1 if you have the `gai_strerror' function. */
+#undef HAVE_GAI_STRERROR
+
+/* Define if you have the getaddrinfo function. */
+#undef HAVE_GETADDRINFO
+
+/* Define to 1 if you have the `getcwd' function. */
+#undef HAVE_GETCWD
+
+/* Define this if you have flockfile(), getc_unlocked(), and funlockfile() */
+#undef HAVE_GETC_UNLOCKED
+
+/* Define to 1 if you have the `getgroups' function. */
+#undef HAVE_GETGROUPS
+
+/* Define to 1 if you have the `gethostbyname' function. */
+#undef HAVE_GETHOSTBYNAME
+
+/* Define this if you have some version of gethostbyname_r() */
+#undef HAVE_GETHOSTBYNAME_R
+
+/* Define this if you have the 3-arg version of gethostbyname_r(). */
+#undef HAVE_GETHOSTBYNAME_R_3_ARG
+
+/* Define this if you have the 5-arg version of gethostbyname_r(). */
+#undef HAVE_GETHOSTBYNAME_R_5_ARG
+
+/* Define this if you have the 6-arg version of gethostbyname_r(). */
+#undef HAVE_GETHOSTBYNAME_R_6_ARG
+
+/* Define to 1 if you have the `getloadavg' function. */
+#undef HAVE_GETLOADAVG
+
+/* Define to 1 if you have the `getlogin' function. */
+#undef HAVE_GETLOGIN
+
+/* Define to 1 if you have the `getnameinfo' function. */
+#undef HAVE_GETNAMEINFO
+
+/* Define if you have the 'getpagesize' function. */
+#undef HAVE_GETPAGESIZE
+
+/* Define to 1 if you have the `getpeername' function. */
+#undef HAVE_GETPEERNAME
+
+/* Define to 1 if you have the `getpgid' function. */
+#undef HAVE_GETPGID
+
+/* Define to 1 if you have the `getpgrp' function. */
+#undef HAVE_GETPGRP
+
+/* Define to 1 if you have the `getpid' function. */
+#undef HAVE_GETPID
+
+/* Define to 1 if you have the `getpriority' function. */
+#undef HAVE_GETPRIORITY
+
+/* Define to 1 if you have the `getpwent' function. */
+#undef HAVE_GETPWENT
+
+/* Define to 1 if you have the `getsid' function. */
+#undef HAVE_GETSID
+
+/* Define to 1 if you have the `getspent' function. */
+#undef HAVE_GETSPENT
+
+/* Define to 1 if you have the `getspnam' function. */
+#undef HAVE_GETSPNAM
+
+/* Define to 1 if you have the `gettimeofday' function. */
+#undef HAVE_GETTIMEOFDAY
+
+/* Define to 1 if you have the `getwd' function. */
+#undef HAVE_GETWD
+
+/* Define to 1 if you have the <grp.h> header file. */
+#undef HAVE_GRP_H
+
+/* Define if you have the 'hstrerror' function. */
+#undef HAVE_HSTRERROR
+
+/* Define to 1 if you have the `hypot' function. */
+#undef HAVE_HYPOT
+
+/* Define if you have the 'inet_aton' function. */
+#undef HAVE_INET_ATON
+
+/* Define if you have the 'inet_pton' function. */
+#undef HAVE_INET_PTON
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the <io.h> header file. */
+#undef HAVE_IO_H
+
+/* Define to 1 if you have the `kill' function. */
+#undef HAVE_KILL
+
+/* Define to 1 if you have the `killpg' function. */
+#undef HAVE_KILLPG
+
+/* Define to 1 if you have the <langinfo.h> header file. */
+#undef HAVE_LANGINFO_H
+
+/* Defined to enable large file support when an off_t is bigger than a long
+   and long long is available and at least as big as an off_t. You may need to
+   add some flags for configuration and compilation to enable this mode. (For
+   Solaris and Linux, the necessary defines are already defined.) */
+#undef HAVE_LARGEFILE_SUPPORT
+
+/* Define to 1 if you have the `lchown' function. */
+#undef HAVE_LCHOWN
+
+/* Define to 1 if you have the `dl' library (-ldl). */
+#undef HAVE_LIBDL
+
+/* Define to 1 if you have the `dld' library (-ldld). */
+#undef HAVE_LIBDLD
+
+/* Define to 1 if you have the `ieee' library (-lieee). */
+#undef HAVE_LIBIEEE
+
+/* Define to 1 if you have the <libintl.h> header file. */
+#undef HAVE_LIBINTL_H
+
+/* Define to 1 if you have the `readline' library (-lreadline). */
+#undef HAVE_LIBREADLINE
+
+/* Define to 1 if you have the `resolv' library (-lresolv). */
+#undef HAVE_LIBRESOLV
+
+/* Define to 1 if you have the `termcap' library (-ltermcap). */
+#undef HAVE_LIBTERMCAP
+
+/* Define to 1 if you have the <libutil.h> header file. */
+#undef HAVE_LIBUTIL_H
+
+/* Define if you have the 'link' function. */
+#undef HAVE_LINK
+
+/* Define to 1 if you have the <linux/netlink.h> header file. */
+#undef HAVE_LINUX_NETLINK_H
+
+/* Define this if you have the type long long. */
+#undef HAVE_LONG_LONG
+
+/* Define to 1 if you have the `lstat' function. */
+#undef HAVE_LSTAT
+
+/* Define this if you have the makedev macro. */
+#undef HAVE_MAKEDEV
+
+/* Define to 1 if you have the `memmove' function. */
+#undef HAVE_MEMMOVE
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `mkfifo' function. */
+#undef HAVE_MKFIFO
+
+/* Define to 1 if you have the `mknod' function. */
+#undef HAVE_MKNOD
+
+/* Define to 1 if you have the `mktime' function. */
+#undef HAVE_MKTIME
+
+/* Define to 1 if you have the `mremap' function. */
+#undef HAVE_MREMAP
+
+/* Define to 1 if you have the <ncurses.h> header file. */
+#undef HAVE_NCURSES_H
+
+/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
+#undef HAVE_NDIR_H
+
+/* Define to 1 if you have the <netpacket/packet.h> header file. */
+#undef HAVE_NETPACKET_PACKET_H
+
+/* Define to 1 if you have the `nice' function. */
+#undef HAVE_NICE
+
+/* Define to 1 if you have the `openpty' function. */
+#undef HAVE_OPENPTY
+
+/* Define to 1 if you have the `pathconf' function. */
+#undef HAVE_PATHCONF
+
+/* Define to 1 if you have the `pause' function. */
+#undef HAVE_PAUSE
+
+/* Define to 1 if you have the `plock' function. */
+#undef HAVE_PLOCK
+
+/* Define to 1 if you have the `poll' function. */
+#undef HAVE_POLL
+
+/* Define to 1 if you have the <poll.h> header file. */
+#undef HAVE_POLL_H
+
+/* Define to 1 if you have the <process.h> header file. */
+#undef HAVE_PROCESS_H
+
+/* Define if your compiler supports function prototype */
+#undef HAVE_PROTOTYPES
+
+/* Define if you have GNU PTH threads. */
+#undef HAVE_PTH
+
+/* Defined for Solaris 2.6 bug in pthread header. */
+#undef HAVE_PTHREAD_DESTRUCTOR
+
+/* Define to 1 if you have the <pthread.h> header file. */
+#undef HAVE_PTHREAD_H
+
+/* Define to 1 if you have the `pthread_init' function. */
+#undef HAVE_PTHREAD_INIT
+
+/* Define to 1 if you have the `pthread_sigmask' function. */
+#undef HAVE_PTHREAD_SIGMASK
+
+/* Define to 1 if you have the <pty.h> header file. */
+#undef HAVE_PTY_H
+
+/* Define to 1 if you have the `putenv' function. */
+#undef HAVE_PUTENV
+
+/* Define to 1 if you have the `readlink' function. */
+#undef HAVE_READLINK
+
+/* Define to 1 if you have the `realpath' function. */
+#undef HAVE_REALPATH
+
+/* Define if you have readline 2.1 */
+#undef HAVE_RL_CALLBACK
+
+/* Define if you can turn off readline's signal handling. */
+#undef HAVE_RL_CATCH_SIGNAL
+
+/* Define if you have readline 2.2 */
+#undef HAVE_RL_COMPLETION_APPEND_CHARACTER
+
+/* Define if you have readline 4.2 */
+#undef HAVE_RL_COMPLETION_MATCHES
+
+/* Define if you have readline 4.0 */
+#undef HAVE_RL_PRE_INPUT_HOOK
+
+/* Define to 1 if you have the `select' function. */
+#undef HAVE_SELECT
+
+/* Define to 1 if you have the `setegid' function. */
+#undef HAVE_SETEGID
+
+/* Define to 1 if you have the `seteuid' function. */
+#undef HAVE_SETEUID
+
+/* Define to 1 if you have the `setgid' function. */
+#undef HAVE_SETGID
+
+/* Define if you have the 'setgroups' function. */
+#undef HAVE_SETGROUPS
+
+/* Define to 1 if you have the `setlocale' function. */
+#undef HAVE_SETLOCALE
+
+/* Define to 1 if you have the `setpgid' function. */
+#undef HAVE_SETPGID
+
+/* Define to 1 if you have the `setpgrp' function. */
+#undef HAVE_SETPGRP
+
+/* Define to 1 if you have the `setregid' function. */
+#undef HAVE_SETREGID
+
+/* Define to 1 if you have the `setreuid' function. */
+#undef HAVE_SETREUID
+
+/* Define to 1 if you have the `setsid' function. */
+#undef HAVE_SETSID
+
+/* Define to 1 if you have the `setuid' function. */
+#undef HAVE_SETUID
+
+/* Define to 1 if you have the `setvbuf' function. */
+#undef HAVE_SETVBUF
+
+/* Define to 1 if you have the <shadow.h> header file. */
+#undef HAVE_SHADOW_H
+
+/* Define to 1 if you have the `sigaction' function. */
+#undef HAVE_SIGACTION
+
+/* Define to 1 if you have the `siginterrupt' function. */
+#undef HAVE_SIGINTERRUPT
+
+/* Define to 1 if you have the <signal.h> header file. */
+#undef HAVE_SIGNAL_H
+
+/* Define to 1 if you have the `sigrelse' function. */
+#undef HAVE_SIGRELSE
+
+/* Define to 1 if you have the `snprintf' function. */
+#undef HAVE_SNPRINTF
+
+/* Define if sockaddr has sa_len member */
+#undef HAVE_SOCKADDR_SA_LEN
+
+/* struct sockaddr_storage (sys/socket.h) */
+#undef HAVE_SOCKADDR_STORAGE
+
+/* Define if you have the 'socketpair' function. */
+#undef HAVE_SOCKETPAIR
+
+/* Define if your compiler provides ssize_t */
+#undef HAVE_SSIZE_T
+
+/* Define to 1 if you have the `statvfs' function. */
+#undef HAVE_STATVFS
+
+/* Define if you have struct stat.st_mtim.tv_nsec */
+#undef HAVE_STAT_TV_NSEC
+
+/* Define if you have struct stat.st_mtimensec */
+#undef HAVE_STAT_TV_NSEC2
+
+/* Define if your compiler supports variable length function prototypes (e.g.
+   void fprintf(FILE *, char *, ...);) *and* <stdarg.h> */
+#undef HAVE_STDARG_PROTOTYPES
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the `strdup' function. */
+#undef HAVE_STRDUP
+
+/* Define to 1 if you have the `strerror' function. */
+#undef HAVE_STRERROR
+
+/* Define to 1 if you have the `strftime' function. */
+#undef HAVE_STRFTIME
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <stropts.h> header file. */
+#undef HAVE_STROPTS_H
+
+/* Define to 1 if `st_birthtime' is member of `struct stat'. */
+#undef HAVE_STRUCT_STAT_ST_BIRTHTIME
+
+/* Define to 1 if `st_blksize' is member of `struct stat'. */
+#undef HAVE_STRUCT_STAT_ST_BLKSIZE
+
+/* Define to 1 if `st_blocks' is member of `struct stat'. */
+#undef HAVE_STRUCT_STAT_ST_BLOCKS
+
+/* Define to 1 if `st_flags' is member of `struct stat'. */
+#undef HAVE_STRUCT_STAT_ST_FLAGS
+
+/* Define to 1 if `st_gen' is member of `struct stat'. */
+#undef HAVE_STRUCT_STAT_ST_GEN
+
+/* Define to 1 if `st_rdev' is member of `struct stat'. */
+#undef HAVE_STRUCT_STAT_ST_RDEV
+
+/* Define to 1 if `tm_zone' is member of `struct tm'. */
+#undef HAVE_STRUCT_TM_TM_ZONE
+
+/* Define to 1 if your `struct stat' has `st_blocks'. Deprecated, use
+   `HAVE_STRUCT_STAT_ST_BLOCKS' instead. */
+#undef HAVE_ST_BLOCKS
+
+/* Define if you have the 'symlink' function. */
+#undef HAVE_SYMLINK
+
+/* Define to 1 if you have the `sysconf' function. */
+#undef HAVE_SYSCONF
+
+/* Define to 1 if you have the <sysexits.h> header file. */
+#undef HAVE_SYSEXITS_H
+
+/* Define to 1 if you have the <sys/audioio.h> header file. */
+#undef HAVE_SYS_AUDIOIO_H
+
+/* Define to 1 if you have the <sys/bsdtty.h> header file. */
+#undef HAVE_SYS_BSDTTY_H
+
+/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
+   */
+#undef HAVE_SYS_DIR_H
+
+/* Define to 1 if you have the <sys/file.h> header file. */
+#undef HAVE_SYS_FILE_H
+
+/* Define to 1 if you have the <sys/loadavg.h> header file. */
+#undef HAVE_SYS_LOADAVG_H
+
+/* Define to 1 if you have the <sys/lock.h> header file. */
+#undef HAVE_SYS_LOCK_H
+
+/* Define to 1 if you have the <sys/mkdev.h> header file. */
+#undef HAVE_SYS_MKDEV_H
+
+/* Define to 1 if you have the <sys/modem.h> header file. */
+#undef HAVE_SYS_MODEM_H
+
+/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
+   */
+#undef HAVE_SYS_NDIR_H
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#undef HAVE_SYS_PARAM_H
+
+/* Define to 1 if you have the <sys/poll.h> header file. */
+#undef HAVE_SYS_POLL_H
+
+/* Define to 1 if you have the <sys/resource.h> header file. */
+#undef HAVE_SYS_RESOURCE_H
+
+/* Define to 1 if you have the <sys/select.h> header file. */
+#undef HAVE_SYS_SELECT_H
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#undef HAVE_SYS_SOCKET_H
+
+/* Define to 1 if you have the <sys/statvfs.h> header file. */
+#undef HAVE_SYS_STATVFS_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/times.h> header file. */
+#undef HAVE_SYS_TIMES_H
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#undef HAVE_SYS_TIME_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <sys/un.h> header file. */
+#undef HAVE_SYS_UN_H
+
+/* Define to 1 if you have the <sys/utsname.h> header file. */
+#undef HAVE_SYS_UTSNAME_H
+
+/* Define to 1 if you have the <sys/wait.h> header file. */
+#undef HAVE_SYS_WAIT_H
+
+/* Define to 1 if you have the `tcgetpgrp' function. */
+#undef HAVE_TCGETPGRP
+
+/* Define to 1 if you have the `tcsetpgrp' function. */
+#undef HAVE_TCSETPGRP
+
+/* Define to 1 if you have the `tempnam' function. */
+#undef HAVE_TEMPNAM
+
+/* Define to 1 if you have the <termios.h> header file. */
+#undef HAVE_TERMIOS_H
+
+/* Define to 1 if you have the <term.h> header file. */
+#undef HAVE_TERM_H
+
+/* Define to 1 if you have the <thread.h> header file. */
+#undef HAVE_THREAD_H
+
+/* Define to 1 if you have the `timegm' function. */
+#undef HAVE_TIMEGM
+
+/* Define to 1 if you have the `times' function. */
+#undef HAVE_TIMES
+
+/* Define to 1 if you have the `tmpfile' function. */
+#undef HAVE_TMPFILE
+
+/* Define to 1 if you have the `tmpnam' function. */
+#undef HAVE_TMPNAM
+
+/* Define to 1 if you have the `tmpnam_r' function. */
+#undef HAVE_TMPNAM_R
+
+/* Define to 1 if your `struct tm' has `tm_zone'. Deprecated, use
+   `HAVE_STRUCT_TM_TM_ZONE' instead. */
+#undef HAVE_TM_ZONE
+
+/* Define to 1 if you have the `truncate' function. */
+#undef HAVE_TRUNCATE
+
+/* Define to 1 if you don't have `tm_zone' but do have the external array
+   `tzname'. */
+#undef HAVE_TZNAME
+
+/* Define this if you have tcl and TCL_UTF_MAX==6 */
+#undef HAVE_UCS4_TCL
+
+/* Define to 1 if the system has the type `uintptr_t'. */
+#undef HAVE_UINTPTR_T
+
+/* Define to 1 if you have the `uname' function. */
+#undef HAVE_UNAME
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if you have the `unsetenv' function. */
+#undef HAVE_UNSETENV
+
+/* Define if you have a useable wchar_t type defined in wchar.h; useable means
+   wchar_t must be an unsigned type with at least 16 bits. (see
+   Include/unicodeobject.h). */
+#undef HAVE_USABLE_WCHAR_T
+
+/* Define to 1 if you have the `utimes' function. */
+#undef HAVE_UTIMES
+
+/* Define to 1 if you have the <utime.h> header file. */
+#undef HAVE_UTIME_H
+
+/* Define to 1 if you have the `wait3' function. */
+#undef HAVE_WAIT3
+
+/* Define to 1 if you have the `wait4' function. */
+#undef HAVE_WAIT4
+
+/* Define to 1 if you have the `waitpid' function. */
+#undef HAVE_WAITPID
+
+/* Define if the compiler provides a wchar.h header file. */
+#undef HAVE_WCHAR_H
+
+/* Define to 1 if you have the `wcscoll' function. */
+#undef HAVE_WCSCOLL
+
+/* Define if tzset() actually switches the local timezone in a meaningful way.
+   */
+#undef HAVE_WORKING_TZSET
+
+/* Define if the zlib library has inflateCopy */
+#undef HAVE_ZLIB_COPY
+
+/* Define to 1 if you have the `_getpty' function. */
+#undef HAVE__GETPTY
+
+/* Define if you are using Mach cthreads directly under /include */
+#undef HURD_C_THREADS
+
+/* Define if you are using Mach cthreads under mach / */
+#undef MACH_C_THREADS
+
+/* Define to 1 if `major', `minor', and `makedev' are declared in <mkdev.h>.
+   */
+#undef MAJOR_IN_MKDEV
+
+/* Define to 1 if `major', `minor', and `makedev' are declared in
+   <sysmacros.h>. */
+#undef MAJOR_IN_SYSMACROS
+
+/* Define if mvwdelch in curses.h is an expression. */
+#undef MVWDELCH_IS_EXPRESSION
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Defined if PTHREAD_SCOPE_SYSTEM supported. */
+#undef PTHREAD_SYSTEM_SCHED_SUPPORTED
+
+/* Define to printf format modifier for Py_ssize_t */
+#undef PY_FORMAT_SIZE_T
+
+/* Define as the integral type used for Unicode representation. */
+#undef PY_UNICODE_TYPE
+
+/* Define if you want to build an interpreter with many run-time checks. */
+#undef Py_DEBUG
+
+/* Defined if Python is built as a shared library. */
+#undef Py_ENABLE_SHARED
+
+/* Define as the size of the unicode type. */
+#undef Py_UNICODE_SIZE
+
+/* Define if you want to have a Unicode type. */
+#undef Py_USING_UNICODE
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#undef RETSIGTYPE
+
+/* Define if setpgrp() must be called as setpgrp(0, 0). */
+#undef SETPGRP_HAVE_ARG
+
+/* Define this to be extension of shared libraries (including the dot!). */
+#undef SHLIB_EXT
+
+/* Define if i>>j for signed int i does not extend the sign bit when i < 0 */
+#undef SIGNED_RIGHT_SHIFT_ZERO_FILLS
+
+/* The size of a `double', as computed by sizeof. */
+#undef SIZEOF_DOUBLE
+
+/* The size of a `float', as computed by sizeof. */
+#undef SIZEOF_FLOAT
+
+/* The size of a `fpos_t', as computed by sizeof. */
+#undef SIZEOF_FPOS_T
+
+/* The size of a `int', as computed by sizeof. */
+#undef SIZEOF_INT
+
+/* The size of a `long', as computed by sizeof. */
+#undef SIZEOF_LONG
+
+/* The size of a `long long', as computed by sizeof. */
+#undef SIZEOF_LONG_LONG
+
+/* The number of bytes in an off_t. */
+#undef SIZEOF_OFF_T
+
+/* The number of bytes in a pthread_t. */
+#undef SIZEOF_PTHREAD_T
+
+/* The size of a `short', as computed by sizeof. */
+#undef SIZEOF_SHORT
+
+/* The size of a `size_t', as computed by sizeof. */
+#undef SIZEOF_SIZE_T
+
+/* The number of bytes in a time_t. */
+#undef SIZEOF_TIME_T
+
+/* The size of a `uintptr_t', as computed by sizeof. */
+#undef SIZEOF_UINTPTR_T
+
+/* The size of a `void *', as computed by sizeof. */
+#undef SIZEOF_VOID_P
+
+/* The size of a `wchar_t', as computed by sizeof. */
+#undef SIZEOF_WCHAR_T
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define if you can safely include both <sys/select.h> and <sys/time.h>
+   (which you can't on SCO ODT 3.0). */
+#undef SYS_SELECT_WITH_SYS_TIME
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#undef TIME_WITH_SYS_TIME
+
+/* Define to 1 if your <sys/time.h> declares `struct tm'. */
+#undef TM_IN_SYS_TIME
+
+/* Define if you want to use MacPython modules on MacOSX in unix-Python. */
+#undef USE_TOOLBOX_OBJECT_GLUE
+
+/* Define if a va_list is an array of some kind */
+#undef VA_LIST_IS_ARRAY
+
+/* Define if you want SIGFPE handled (see Include/pyfpe.h). */
+#undef WANT_SIGFPE_HANDLER
+
+/* Define if you want wctype.h functions to be used instead of the one
+   supplied by Python itself. (see Include/unicodectype.h). */
+#undef WANT_WCTYPE_FUNCTIONS
+
+/* Define if WINDOW in curses.h offers a field _flags. */
+#undef WINDOW_HAS_FLAGS
+
+/* Define if you want documentation strings in extension modules */
+#undef WITH_DOC_STRINGS
+
+/* Define if you want to use the new-style (Openstep, Rhapsody, MacOS) dynamic
+   linker (dyld) instead of the old-style (NextStep) dynamic linker (rld).
+   Dyld is necessary to support frameworks. */
+#undef WITH_DYLD
+
+/* Define to 1 if libintl is needed for locale functions. */
+#undef WITH_LIBINTL
+
+/* Define if you want to produce an OpenStep/Rhapsody framework (shared
+   library plus accessory files). */
+#undef WITH_NEXT_FRAMEWORK
+
+/* Define if you want to compile in Python-specific mallocs */
+#undef WITH_PYMALLOC
+
+/* Define if you want to compile in rudimentary thread support */
+#undef WITH_THREAD
+
+/* Define to profile with the Pentium timestamp counter */
+#undef WITH_TSC
+
+
+ /* Define to 1 if your processor stores words with the most significant byte
+    first (like Motorola and SPARC, unlike Intel and VAX). 
+
+    The block below does compile-time checking for endianness on platforms
+    that use GCC and therefore allows compiling fat binaries on OSX by using 
+    '-arch ppc -arch i386' as the compile flags. The phrasing was choosen
+    such that the configure-result is used on systems that don't use GCC.
+  */
+#ifdef __BIG_ENDIAN__
+#define WORDS_BIGENDIAN 1
+#else
+#ifndef __LITTLE_ENDIAN__
+#undef WORDS_BIGENDIAN
+#endif
+#endif
+
+/* Define to 1 if on AIX 3.
+   System headers sometimes define this.
+   We just want to avoid a redefinition error message.  */
+#ifndef _ALL_SOURCE
+# undef _ALL_SOURCE
+#endif
+
+/* Define on Irix to enable u_int */
+#undef _BSD_TYPES
+
+/* This must be set to 64 on some systems to enable large file support. */
+#undef _FILE_OFFSET_BITS
+
+/* Define on Linux to activate all library features */
+#undef _GNU_SOURCE
+
+/* This must be defined on some systems to enable large file support. */
+#undef _LARGEFILE_SOURCE
+
+/* Define on NetBSD to activate all library features */
+#undef _NETBSD_SOURCE
+
+/* Define _OSF_SOURCE to get the makedev macro. */
+#undef _OSF_SOURCE
+
+/* Define to activate features from IEEE Stds 1003.1-2001 */
+#undef _POSIX_C_SOURCE
+
+/* Define if you have POSIX threads, and your system does not define that. */
+#undef _POSIX_THREADS
+
+/* Define to force use of thread-safe errno, h_errno, and other functions */
+#undef _REENTRANT
+
+/* Define to the level of X/Open that your system supports */
+#undef _XOPEN_SOURCE
+
+/* Define to activate Unix95-and-earlier features */
+#undef _XOPEN_SOURCE_EXTENDED
+
+/* Define on FreeBSD to activate all library features */
+#undef __BSD_VISIBLE
+
+/* Define to 1 if type `char' is unsigned and you are not using gcc.  */
+#ifndef __CHAR_UNSIGNED__
+# undef __CHAR_UNSIGNED__
+#endif
+
+/* Defined on Solaris to see additional function prototypes. */
+#undef __EXTENSIONS__
+
+/* Define to 'long' if <time.h> doesn't define. */
+#undef clock_t
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef gid_t
+
+/* Define to `int' if <sys/types.h> does not define. */
+#undef mode_t
+
+/* Define to `long' if <sys/types.h> does not define. */
+#undef off_t
+
+/* Define to `int' if <sys/types.h> does not define. */
+#undef pid_t
+
+/* Define to empty if the keyword does not work. */
+#undef signed
+
+/* Define to `unsigned' if <sys/types.h> does not define. */
+#undef size_t
+
+/* Define to `int' if <sys/socket.h> does not define. */
+#undef socklen_t
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef uid_t
+
+/* Define to empty if the keyword does not work. */
+#undef volatile
+
+
+/* Define the macros needed if on a UnixWare 7.x system. */
+#if defined(__USLC__) && defined(__SCO_VERSION__)
+#define STRICT_SYSV_CURSES /* Don't use ncurses extensions */
+#endif
+
+#endif /*Py_PYCONFIG_H*/
+

Added: vendor/Python/current/setup.py
===================================================================
--- vendor/Python/current/setup.py	2007-06-02 00:18:51 UTC (rev 7043)
+++ vendor/Python/current/setup.py	2007-06-02 00:21:15 UTC (rev 7044)
@@ -0,0 +1,1525 @@
+# Autodetecting setup.py script for building the Python extensions
+#
+
+__version__ = "$Revision: 53777 $"
+
+import sys, os, imp, re, optparse
+
+from distutils import log
+from distutils import sysconfig
+from distutils import text_file
+from distutils.errors import *
+from distutils.core import Extension, setup
+from distutils.command.build_ext import build_ext
+from distutils.command.install import install
+from distutils.command.install_lib import install_lib
+
+# This global variable is used to hold the list of modules to be disabled.
+disabled_module_list = []
+
+def add_dir_to_list(dirlist, dir):
+    """Add the directory 'dir' to the list 'dirlist' (at the front) if
+    1) 'dir' is not already in 'dirlist'
+    2) 'dir' actually exists, and is a directory."""
+    if dir is not None and os.path.isdir(dir) and dir not in dirlist:
+        dirlist.insert(0, dir)
+
+def find_file(filename, std_dirs, paths):
+    """Searches for the directory where a given file is located,
+    and returns a possibly-empty list of additional directories, or None
+    if the file couldn't be found at all.
+
+    'filename' is the name of a file, such as readline.h or libcrypto.a.
+    'std_dirs' is the list of standard system directories; if the
+        file is found in one of them, no additional directives are needed.
+    'paths' is a list of additional locations to check; if the file is
+        found in one of them, the resulting list will contain the directory.
+    """
+
+    # Check the standard locations
+    for dir in std_dirs:
+        f = os.path.join(dir, filename)
+        if os.path.exists(f): return []
+
+    # Check the additional directories
+    for dir in paths:
+        f = os.path.join(dir, filename)
+        if os.path.exists(f):
+            return [dir]
+
+    # Not found anywhere
+    return None
+
+def find_library_file(compiler, libname, std_dirs, paths):
+    result = compiler.find_library_file(std_dirs + paths, libname)
+    if result is None:
+        return None
+
+    # Check whether the found file is in one of the standard directories
+    dirname = os.path.dirname(result)
+    for p in std_dirs:
+        # Ensure path doesn't end with path separator
+        p = p.rstrip(os.sep)
+        if p == dirname:
+            return [ ]
+
+    # Otherwise, it must have been in one of the additional directories,
+    # so we have to figure out which one.
+    for p in paths:
+        # Ensure path doesn't end with path separator
+        p = p.rstrip(os.sep)
+        if p == dirname:
+            return [p]
+    else:
+        assert False, "Internal error: Path not found in std_dirs or paths"
+
+def module_enabled(extlist, modname):
+    """Returns whether the module 'modname' is present in the list
+    of extensions 'extlist'."""
+    extlist = [ext for ext in extlist if ext.name == modname]
+    return len(extlist)
+
+def find_module_file(module, dirlist):
+    """Find a module in a set of possible folders. If it is not found
+    return the unadorned filename"""
+    list = find_file(module, [], dirlist)
+    if not list:
+        return module
+    if len(list) > 1:
+        log.info("WARNING: multiple copies of %s found"%module)
+    return os.path.join(list[0], module)
+
+class PyBuildExt(build_ext):
+
+    def build_extensions(self):
+
+        # Detect which modules should be compiled
+        self.detect_modules()
+
+        # Remove modules that are present on the disabled list
+        self.extensions = [ext for ext in self.extensions
+                           if ext.name not in disabled_module_list]
+
+        # Fix up the autodetected modules, prefixing all the source files
+        # with Modules/ and adding Python's include directory to the path.
+        (srcdir,) = sysconfig.get_config_vars('srcdir')
+        if not srcdir:
+            # Maybe running on Windows but not using CYGWIN?
+            raise ValueError("No source directory; cannot proceed.")
+
+        # Figure out the location of the source code for extension modules
+        moddir = os.path.join(os.getcwd(), srcdir, 'Modules')
+        moddir = os.path.normpath(moddir)
+        srcdir, tail = os.path.split(moddir)
+        srcdir = os.path.normpath(srcdir)
+        moddir = os.path.normpath(moddir)
+
+        moddirlist = [moddir]
+        incdirlist = ['./Include']
+
+        # Platform-dependent module source and include directories
+        platform = self.get_platform()
+        if platform in ('darwin', 'mac') and ("--disable-toolbox-glue" not in
+            sysconfig.get_config_var("CONFIG_ARGS")):
+            # Mac OS X also includes some mac-specific modules
+            macmoddir = os.path.join(os.getcwd(), srcdir, 'Mac/Modules')
+            moddirlist.append(macmoddir)
+            incdirlist.append('./Mac/Include')
+
+        alldirlist = moddirlist + incdirlist
+
+        # Fix up the paths for scripts, too
+        self.distribution.scripts = [os.path.join(srcdir, filename)
+                                     for filename in self.distribution.scripts]
+
+        for ext in self.extensions[:]:
+            ext.sources = [ find_module_file(filename, moddirlist)
+                            for filename in ext.sources ]
+            if ext.depends is not None:
+                ext.depends = [find_module_file(filename, alldirlist)
+                               for filename in ext.depends]
+            ext.include_dirs.append( '.' ) # to get config.h
+            for incdir in incdirlist:
+                ext.include_dirs.append( os.path.join(srcdir, incdir) )
+
+            # If a module has already been built statically,
+            # don't build it here
+            if ext.name in sys.builtin_module_names:
+                self.extensions.remove(ext)
+
+        if platform != 'mac':
+            # Parse Modules/Setup and Modules/Setup.local to figure out which
+            # modules are turned on in the file.
+            remove_modules = []
+            for filename in ('Modules/Setup', 'Modules/Setup.local'):
+                input = text_file.TextFile(filename, join_lines=1)
+                while 1:
+                    line = input.readline()
+                    if not line: break
+                    line = line.split()
+                    remove_modules.append(line[0])
+                input.close()
+
+            for ext in self.extensions[:]:
+                if ext.name in remove_modules:
+                    self.extensions.remove(ext)
+
+        # When you run "make CC=altcc" or something similar, you really want
+        # those environment variables passed into the setup.py phase.  Here's
+        # a small set of useful ones.
+        compiler = os.environ.get('CC')
+        args = {}
+        # unfortunately, distutils doesn't let us provide separate C and C++
+        # compilers
+        if compiler is not None:
+            (ccshared,cflags) = sysconfig.get_config_vars('CCSHARED','CFLAGS')
+            args['compiler_so'] = compiler + ' ' + ccshared + ' ' + cflags
+        self.compiler.set_executables(**args)
+
+        build_ext.build_extensions(self)
+
+    def build_extension(self, ext):
+
+        if ext.name == '_ctypes':
+            if not self.configure_ctypes(ext):
+                return
+
+        try:
+            build_ext.build_extension(self, ext)
+        except (CCompilerError, DistutilsError), why:
+            self.announce('WARNING: building of extension "%s" failed: %s' %
+                          (ext.name, sys.exc_info()[1]))
+            return
+        # Workaround for Mac OS X: The Carbon-based modules cannot be
+        # reliably imported into a command-line Python
+        if 'Carbon' in ext.extra_link_args:
+            self.announce(
+                'WARNING: skipping import check for Carbon-based "%s"' %
+                ext.name)
+            return
+        # Workaround for Cygwin: Cygwin currently has fork issues when many
+        # modules have been imported
+        if self.get_platform() == 'cygwin':
+            self.announce('WARNING: skipping import check for Cygwin-based "%s"'
+                % ext.name)
+            return
+        ext_filename = os.path.join(
+            self.build_lib,
+            self.get_ext_filename(self.get_ext_fullname(ext.name)))
+        try:
+            imp.load_dynamic(ext.name, ext_filename)
+        except ImportError, why:
+            self.announce('*** WARNING: renaming "%s" since importing it'
+                          ' failed: %s' % (ext.name, why), level=3)
+            assert not self.inplace
+            basename, tail = os.path.splitext(ext_filename)
+            newname = basename + "_failed" + tail
+            if os.path.exists(newname):
+                os.remove(newname)
+            os.rename(ext_filename, newname)
+
+            # XXX -- This relies on a Vile HACK in
+            # distutils.command.build_ext.build_extension().  The
+            # _built_objects attribute is stored there strictly for
+            # use here.
+            # If there is a failure, _built_objects may not be there,
+            # so catch the AttributeError and move on.
+            try:
+                for filename in self._built_objects:
+                    os.remove(filename)
+            except AttributeError:
+                self.announce('unable to remove files (ignored)')
+        except:
+            exc_type, why, tb = sys.exc_info()
+            self.announce('*** WARNING: importing extension "%s" '
+                          'failed with %s: %s' % (ext.name, exc_type, why),
+                          level=3)
+
+    def get_platform(self):
+        # Get value of sys.platform
+        for platform in ['cygwin', 'beos', 'darwin', 'atheos', 'osf1']:
+            if sys.platform.startswith(platform):
+                return platform
+        return sys.platform
+
+    def detect_modules(self):
+        # Ensure that /usr/local is always used
+        add_dir_to_list(self.compiler.library_dirs, '/usr/local/lib')
+        add_dir_to_list(self.compiler.include_dirs, '/usr/local/include')
+
+        # Add paths specified in the environment variables LDFLAGS and
+        # CPPFLAGS for header and library files.
+        # We must get the values from the Makefile and not the environment
+        # directly since an inconsistently reproducible issue comes up where
+        # the environment variable is not set even though the value were passed
+        # into configure and stored in the Makefile (issue found on OS X 10.3).
+        for env_var, arg_name, dir_list in (
+                ('LDFLAGS', '-L', self.compiler.library_dirs),
+                ('CPPFLAGS', '-I', self.compiler.include_dirs)):
+            env_val = sysconfig.get_config_var(env_var)
+            if env_val:
+                # To prevent optparse from raising an exception about any
+                # options in env_val that is doesn't know about we strip out
+                # all double dashes and any dashes followed by a character
+                # that is not for the option we are dealing with.
+                #
+                # Please note that order of the regex is important!  We must
+                # strip out double-dashes first so that we don't end up with
+                # substituting "--Long" to "-Long" and thus lead to "ong" being
+                # used for a library directory.
+                env_val = re.sub(r'(^|\s+)-(-|(?!%s))' % arg_name[1], '', env_val)
+                parser = optparse.OptionParser()
+                # Make sure that allowing args interspersed with options is
+                # allowed
+                parser.allow_interspersed_args = True
+                parser.error = lambda msg: None
+                parser.add_option(arg_name, dest="dirs", action="append")
+                options = parser.parse_args(env_val.split())[0]
+                if options.dirs:
+                    for directory in options.dirs:
+                        add_dir_to_list(dir_list, directory)
+
+        if os.path.normpath(sys.prefix) != '/usr':
+            add_dir_to_list(self.compiler.library_dirs,
+                            sysconfig.get_config_var("LIBDIR"))
+            add_dir_to_list(self.compiler.include_dirs,
+                            sysconfig.get_config_var("INCLUDEDIR"))
+
+        try:
+            have_unicode = unicode
+        except NameError:
+            have_unicode = 0
+
+        # lib_dirs and inc_dirs are used to search for files;
+        # if a file is found in one of those directories, it can
+        # be assumed that no additional -I,-L directives are needed.
+        lib_dirs = self.compiler.library_dirs + [
+            '/lib64', '/usr/lib64',
+            '/lib', '/usr/lib',
+            ]
+        inc_dirs = self.compiler.include_dirs + ['/usr/include']
+        exts = []
+
+        config_h = sysconfig.get_config_h_filename()
+        config_h_vars = sysconfig.parse_config_h(open(config_h))
+
+        platform = self.get_platform()
+        (srcdir,) = sysconfig.get_config_vars('srcdir')
+
+        # Check for AtheOS which has libraries in non-standard locations
+        if platform == 'atheos':
+            lib_dirs += ['/system/libs', '/atheos/autolnk/lib']
+            lib_dirs += os.getenv('LIBRARY_PATH', '').split(os.pathsep)
+            inc_dirs += ['/system/include', '/atheos/autolnk/include']
+            inc_dirs += os.getenv('C_INCLUDE_PATH', '').split(os.pathsep)
+
+        # OSF/1 and Unixware have some stuff in /usr/ccs/lib (like -ldb)
+        if platform in ['osf1', 'unixware7', 'openunix8']:
+            lib_dirs += ['/usr/ccs/lib']
+
+        if platform == 'darwin':
+            # This should work on any unixy platform ;-)
+            # If the user has bothered specifying additional -I and -L flags
+            # in OPT and LDFLAGS we might as well use them here.
+            #   NOTE: using shlex.split would technically be more correct, but
+            # also gives a bootstrap problem. Let's hope nobody uses directories
+            # with whitespace in the name to store libraries.
+            cflags, ldflags = sysconfig.get_config_vars(
+                    'CFLAGS', 'LDFLAGS')
+            for item in cflags.split():
+                if item.startswith('-I'):
+                    inc_dirs.append(item[2:])
+
+            for item in ldflags.split():
+                if item.startswith('-L'):
+                    lib_dirs.append(item[2:])
+
+        # Check for MacOS X, which doesn't need libm.a at all
+        math_libs = ['m']
+        if platform in ['darwin', 'beos', 'mac']:
+            math_libs = []
+
+        # XXX Omitted modules: gl, pure, dl, SGI-specific modules
+
+        #
+        # The following modules are all pretty straightforward, and compile
+        # on pretty much any POSIXish platform.
+        #
+
+        # Some modules that are normally always on:
+        exts.append( Extension('_weakref', ['_weakref.c']) )
+
+        # array objects
+        exts.append( Extension('array', ['arraymodule.c']) )
+        # complex math library functions
+        exts.append( Extension('cmath', ['cmathmodule.c'],
+                               libraries=math_libs) )
+
+        # math library functions, e.g. sin()
+        exts.append( Extension('math',  ['mathmodule.c'],
+                               libraries=math_libs) )
+        # fast string operations implemented in C
+        exts.append( Extension('strop', ['stropmodule.c']) )
+        # time operations and variables
+        exts.append( Extension('time', ['timemodule.c'],
+                               libraries=math_libs) )
+        exts.append( Extension('datetime', ['datetimemodule.c', 'timemodule.c'],
+                               libraries=math_libs) )
+        # random number generator implemented in C
+        exts.append( Extension("_random", ["_randommodule.c"]) )
+        # fast iterator tools implemented in C
+        exts.append( Extension("itertools", ["itertoolsmodule.c"]) )
+        # high-performance collections
+        exts.append( Extension("collections", ["collectionsmodule.c"]) )
+        # bisect
+        exts.append( Extension("_bisect", ["_bisectmodule.c"]) )
+        # heapq
+        exts.append( Extension("_heapq", ["_heapqmodule.c"]) )
+        # operator.add() and similar goodies
+        exts.append( Extension('operator', ['operator.c']) )
+        # _functools
+        exts.append( Extension("_functools", ["_functoolsmodule.c"]) )
+        # Python C API test module
+        exts.append( Extension('_testcapi', ['_testcapimodule.c']) )
+        # profilers (_lsprof is for cProfile.py)
+        exts.append( Extension('_hotshot', ['_hotshot.c']) )
+        exts.append( Extension('_lsprof', ['_lsprof.c', 'rotatingtree.c']) )
+        # static Unicode character database
+        if have_unicode:
+            exts.append( Extension('unicodedata', ['unicodedata.c']) )
+        # access to ISO C locale support
+        data = open('pyconfig.h').read()
+        m = re.search(r"#s*define\s+WITH_LIBINTL\s+1\s*", data)
+        if m is not None:
+            locale_libs = ['intl']
+        else:
+            locale_libs = []
+        if platform == 'darwin':
+            locale_extra_link_args = ['-framework', 'CoreFoundation']
+        else:
+            locale_extra_link_args = []
+
+
+        exts.append( Extension('_locale', ['_localemodule.c'],
+                               libraries=locale_libs,
+                               extra_link_args=locale_extra_link_args) )
+
+        # Modules with some UNIX dependencies -- on by default:
+        # (If you have a really backward UNIX, select and socket may not be
+        # supported...)
+
+        # fcntl(2) and ioctl(2)
+        exts.append( Extension('fcntl', ['fcntlmodule.c']) )
+        if platform not in ['mac']:
+            # pwd(3)
+            exts.append( Extension('pwd', ['pwdmodule.c']) )
+            # grp(3)
+            exts.append( Extension('grp', ['grpmodule.c']) )
+            # spwd, shadow passwords
+            if (config_h_vars.get('HAVE_GETSPNAM', False) or
+                    config_h_vars.get('HAVE_GETSPENT', False)):
+                exts.append( Extension('spwd', ['spwdmodule.c']) )
+        # select(2); not on ancient System V
+        exts.append( Extension('select', ['selectmodule.c']) )
+
+        # Helper module for various ascii-encoders
+        exts.append( Extension('binascii', ['binascii.c']) )
+
+        # Fred Drake's interface to the Python parser
+        exts.append( Extension('parser', ['parsermodule.c']) )
+
+        # cStringIO and cPickle
+        exts.append( Extension('cStringIO', ['cStringIO.c']) )
+        exts.append( Extension('cPickle', ['cPickle.c']) )
+
+        # Memory-mapped files (also works on Win32).
+        if platform not in ['atheos', 'mac']:
+            exts.append( Extension('mmap', ['mmapmodule.c']) )
+
+        # Lance Ellinghaus's syslog module
+        if platform not in ['mac']:
+            # syslog daemon interface
+            exts.append( Extension('syslog', ['syslogmodule.c']) )
+
+        # George Neville-Neil's timing module:
+        # Deprecated in PEP 4 http://www.python.org/peps/pep-0004.html
+        # http://mail.python.org/pipermail/python-dev/2006-January/060023.html
+        #exts.append( Extension('timing', ['timingmodule.c']) )
+
+        #
+        # Here ends the simple stuff.  From here on, modules need certain
+        # libraries, are platform-specific, or present other surprises.
+        #
+
+        # Multimedia modules
+        # These don't work for 64-bit platforms!!!
+        # These represent audio samples or images as strings:
+
+        # Operations on audio samples
+        # According to #993173, this one should actually work fine on
+        # 64-bit platforms.
+        exts.append( Extension('audioop', ['audioop.c']) )
+
+        # Disabled on 64-bit platforms
+        if sys.maxint != 9223372036854775807L:
+            # Operations on images
+            exts.append( Extension('imageop', ['imageop.c']) )
+            # Read SGI RGB image files (but coded portably)
+            exts.append( Extension('rgbimg', ['rgbimgmodule.c']) )
+
+        # readline
+        do_readline = self.compiler.find_library_file(lib_dirs, 'readline')
+        if platform == 'darwin':
+            # MacOSX 10.4 has a broken readline. Don't try to build
+            # the readline module unless the user has installed a fixed
+            # readline package
+            if find_file('readline/rlconf.h', inc_dirs, []) is None:
+                do_readline = False
+        if do_readline:
+            if sys.platform == 'darwin':
+                # In every directory on the search path search for a dynamic
+                # library and then a static library, instead of first looking
+                # for dynamic libraries on the entiry path.
+                # This way a staticly linked custom readline gets picked up
+                # before the (broken) dynamic library in /usr/lib.
+                readline_extra_link_args = ('-Wl,-search_paths_first',)
+            else:
+                readline_extra_link_args = ()
+
+            readline_libs = ['readline']
+            if self.compiler.find_library_file(lib_dirs,
+                                                 'ncursesw'):
+                readline_libs.append('ncursesw')
+            elif self.compiler.find_library_file(lib_dirs,
+                                                 'ncurses'):
+                readline_libs.append('ncurses')
+            elif self.compiler.find_library_file(lib_dirs, 'curses'):
+                readline_libs.append('curses')
+            elif self.compiler.find_library_file(lib_dirs +
+                                               ['/usr/lib/termcap'],
+                                               'termcap'):
+                readline_libs.append('termcap')
+            exts.append( Extension('readline', ['readline.c'],
+                                   library_dirs=['/usr/lib/termcap'],
+                                   extra_link_args=readline_extra_link_args,
+                                   libraries=readline_libs) )
+        if platform not in ['mac']:
+            # crypt module.
+
+            if self.compiler.find_library_file(lib_dirs, 'crypt'):
+                libs = ['crypt']
+            else:
+                libs = []
+            exts.append( Extension('crypt', ['cryptmodule.c'], libraries=libs) )
+
+        # CSV files
+        exts.append( Extension('_csv', ['_csv.c']) )
+
+        # socket(2)
+        exts.append( Extension('_socket', ['socketmodule.c'],
+                               depends = ['socketmodule.h']) )
+        # Detect SSL support for the socket module (via _ssl)
+        search_for_ssl_incs_in = [
+                              '/usr/local/ssl/include',
+                              '/usr/contrib/ssl/include/'
+                             ]
+        ssl_incs = find_file('openssl/ssl.h', inc_dirs,
+                             search_for_ssl_incs_in
+                             )
+        if ssl_incs is not None:
+            krb5_h = find_file('krb5.h', inc_dirs,
+                               ['/usr/kerberos/include'])
+            if krb5_h:
+                ssl_incs += krb5_h
+        ssl_libs = find_library_file(self.compiler, 'ssl',lib_dirs,
+                                     ['/usr/local/ssl/lib',
+                                      '/usr/contrib/ssl/lib/'
+                                     ] )
+
+        if (ssl_incs is not None and
+            ssl_libs is not None):
+            exts.append( Extension('_ssl', ['_ssl.c'],
+                                   include_dirs = ssl_incs,
+                                   library_dirs = ssl_libs,
+                                   libraries = ['ssl', 'crypto'],
+                                   depends = ['socketmodule.h']), )
+
+        # find out which version of OpenSSL we have
+        openssl_ver = 0
+        openssl_ver_re = re.compile(
+            '^\s*#\s*define\s+OPENSSL_VERSION_NUMBER\s+(0x[0-9a-fA-F]+)' )
+        for ssl_inc_dir in inc_dirs + search_for_ssl_incs_in:
+            name = os.path.join(ssl_inc_dir, 'openssl', 'opensslv.h')
+            if os.path.isfile(name):
+                try:
+                    incfile = open(name, 'r')
+                    for line in incfile:
+                        m = openssl_ver_re.match(line)
+                        if m:
+                            openssl_ver = eval(m.group(1))
+                            break
+                except IOError:
+                    pass
+
+            # first version found is what we'll use (as the compiler should)
+            if openssl_ver:
+                break
+
+        #print 'openssl_ver = 0x%08x' % openssl_ver
+
+        if (ssl_incs is not None and
+            ssl_libs is not None and
+            openssl_ver >= 0x00907000):
+            # The _hashlib module wraps optimized implementations
+            # of hash functions from the OpenSSL library.
+            exts.append( Extension('_hashlib', ['_hashopenssl.c'],
+                                   include_dirs = ssl_incs,
+                                   library_dirs = ssl_libs,
+                                   libraries = ['ssl', 'crypto']) )
+        else:
+            # The _sha module implements the SHA1 hash algorithm.
+            exts.append( Extension('_sha', ['shamodule.c']) )
+            # The _md5 module implements the RSA Data Security, Inc. MD5
+            # Message-Digest Algorithm, described in RFC 1321.  The
+            # necessary files md5.c and md5.h are included here.
+            exts.append( Extension('_md5',
+                            sources = ['md5module.c', 'md5.c'],
+                            depends = ['md5.h']) )
+
+        if (openssl_ver < 0x00908000):
+            # OpenSSL doesn't do these until 0.9.8 so we'll bring our own hash
+            exts.append( Extension('_sha256', ['sha256module.c']) )
+            exts.append( Extension('_sha512', ['sha512module.c']) )
+
+
+        # Modules that provide persistent dictionary-like semantics.  You will
+        # probably want to arrange for at least one of them to be available on
+        # your machine, though none are defined by default because of library
+        # dependencies.  The Python module anydbm.py provides an
+        # implementation independent wrapper for these; dumbdbm.py provides
+        # similar functionality (but slower of course) implemented in Python.
+
+        # Sleepycat Berkeley DB interface.  http://www.sleepycat.com
+        #
+        # This requires the Sleepycat DB code. The supported versions
+        # are set below.  Visit http://www.sleepycat.com/ to download
+        # a release.  Most open source OSes come with one or more
+        # versions of BerkeleyDB already installed.
+
+        max_db_ver = (4, 5)
+        min_db_ver = (3, 3)
+        db_setup_debug = False   # verbose debug prints from this script?
+
+        # construct a list of paths to look for the header file in on
+        # top of the normal inc_dirs.
+        db_inc_paths = [
+            '/usr/include/db4',
+            '/usr/local/include/db4',
+            '/opt/sfw/include/db4',
+            '/sw/include/db4',
+            '/usr/include/db3',
+            '/usr/local/include/db3',
+            '/opt/sfw/include/db3',
+            '/sw/include/db3',
+        ]
+        # 4.x minor number specific paths
+        for x in (0,1,2,3,4,5):
+            db_inc_paths.append('/usr/include/db4%d' % x)
+            db_inc_paths.append('/usr/include/db4.%d' % x)
+            db_inc_paths.append('/usr/local/BerkeleyDB.4.%d/include' % x)
+            db_inc_paths.append('/usr/local/include/db4%d' % x)
+            db_inc_paths.append('/pkg/db-4.%d/include' % x)
+            db_inc_paths.append('/opt/db-4.%d/include' % x)
+        # 3.x minor number specific paths
+        for x in (3,):
+            db_inc_paths.append('/usr/include/db3%d' % x)
+            db_inc_paths.append('/usr/local/BerkeleyDB.3.%d/include' % x)
+            db_inc_paths.append('/usr/local/include/db3%d' % x)
+            db_inc_paths.append('/pkg/db-3.%d/include' % x)
+            db_inc_paths.append('/opt/db-3.%d/include' % x)
+
+        # Add some common subdirectories for Sleepycat DB to the list,
+        # based on the standard include directories. This way DB3/4 gets
+        # picked up when it is installed in a non-standard prefix and
+        # the user has added that prefix into inc_dirs.
+        std_variants = []
+        for dn in inc_dirs:
+            std_variants.append(os.path.join(dn, 'db3'))
+            std_variants.append(os.path.join(dn, 'db4'))
+            for x in (0,1,2,3,4):
+                std_variants.append(os.path.join(dn, "db4%d"%x))
+                std_variants.append(os.path.join(dn, "db4.%d"%x))
+            for x in (2,3):
+                std_variants.append(os.path.join(dn, "db3%d"%x))
+                std_variants.append(os.path.join(dn, "db3.%d"%x))
+
+        db_inc_paths = std_variants + db_inc_paths
+
+
+        db_ver_inc_map = {}
+
+        class db_found(Exception): pass
+        try:
+            # See whether there is a Sleepycat header in the standard
+            # search path.
+            for d in inc_dirs + db_inc_paths:
+                f = os.path.join(d, "db.h")
+                if db_setup_debug: print "db: looking for db.h in", f
+                if os.path.exists(f):
+                    f = open(f).read()
+                    m = re.search(r"#define\WDB_VERSION_MAJOR\W(\d+)", f)
+                    if m:
+                        db_major = int(m.group(1))
+                        m = re.search(r"#define\WDB_VERSION_MINOR\W(\d+)", f)
+                        db_minor = int(m.group(1))
+                        db_ver = (db_major, db_minor)
+
+                        if ( (not db_ver_inc_map.has_key(db_ver)) and
+                           (db_ver <= max_db_ver and db_ver >= min_db_ver) ):
+                            # save the include directory with the db.h version
+                            # (first occurrance only)
+                            db_ver_inc_map[db_ver] = d
+                            print "db.h: found", db_ver, "in", d
+                        else:
+                            # we already found a header for this library version
+                            if db_setup_debug: print "db.h: ignoring", d
+                    else:
+                        # ignore this header, it didn't contain a version number
+                        if db_setup_debug: print "db.h: unsupported version", db_ver, "in", d
+
+            db_found_vers = db_ver_inc_map.keys()
+            db_found_vers.sort()
+
+            while db_found_vers:
+                db_ver = db_found_vers.pop()
+                db_incdir = db_ver_inc_map[db_ver]
+
+                # check lib directories parallel to the location of the header
+                db_dirs_to_check = [
+                    os.path.join(db_incdir, '..', 'lib64'),
+                    os.path.join(db_incdir, '..', 'lib'),
+                    os.path.join(db_incdir, '..', '..', 'lib64'),
+                    os.path.join(db_incdir, '..', '..', 'lib'),
+                ]
+                db_dirs_to_check = filter(os.path.isdir, db_dirs_to_check)
+
+                # Look for a version specific db-X.Y before an ambiguoius dbX
+                # XXX should we -ever- look for a dbX name?  Do any
+                # systems really not name their library by version and
+                # symlink to more general names?
+                for dblib in (('db-%d.%d' % db_ver),
+                              ('db%d%d' % db_ver),
+                              ('db%d' % db_ver[0])):
+                    dblib_file = self.compiler.find_library_file(
+                                    db_dirs_to_check + lib_dirs, dblib )
+                    if dblib_file:
+                        dblib_dir = [ os.path.abspath(os.path.dirname(dblib_file)) ]
+                        raise db_found
+                    else:
+                        if db_setup_debug: print "db lib: ", dblib, "not found"
+
+        except db_found:
+            print "db lib: using", db_ver, dblib
+            if db_setup_debug: print "db: lib dir", dblib_dir, "inc dir", db_incdir
+            db_incs = [db_incdir]
+            dblibs = [dblib]
+            # We add the runtime_library_dirs argument because the
+            # BerkeleyDB lib we're linking against often isn't in the
+            # system dynamic library search path.  This is usually
+            # correct and most trouble free, but may cause problems in
+            # some unusual system configurations (e.g. the directory
+            # is on an NFS server that goes away).
+            exts.append(Extension('_bsddb', ['_bsddb.c'],
+                                  library_dirs=dblib_dir,
+                                  runtime_library_dirs=dblib_dir,
+                                  include_dirs=db_incs,
+                                  libraries=dblibs))
+        else:
+            if db_setup_debug: print "db: no appropriate library found"
+            db_incs = None
+            dblibs = []
+            dblib_dir = None
+
+        # The sqlite interface
+        sqlite_setup_debug = True   # verbose debug prints from this script?
+
+        # We hunt for #define SQLITE_VERSION "n.n.n"
+        # We need to find >= sqlite version 3.0.8
+        sqlite_incdir = sqlite_libdir = None
+        sqlite_inc_paths = [ '/usr/include',
+                             '/usr/include/sqlite',
+                             '/usr/include/sqlite3',
+                             '/usr/local/include',
+                             '/usr/local/include/sqlite',
+                             '/usr/local/include/sqlite3',
+                           ]
+        MIN_SQLITE_VERSION_NUMBER = (3, 0, 8)
+        MIN_SQLITE_VERSION = ".".join([str(x)
+                                    for x in MIN_SQLITE_VERSION_NUMBER])
+
+        # Scan the default include directories before the SQLite specific
+        # ones. This allows one to override the copy of sqlite on OSX,
+        # where /usr/include contains an old version of sqlite.
+        for d in inc_dirs + sqlite_inc_paths:
+            f = os.path.join(d, "sqlite3.h")
+            if os.path.exists(f):
+                if sqlite_setup_debug: print "sqlite: found %s"%f
+                incf = open(f).read()
+                m = re.search(
+                    r'\s*.*#\s*.*define\s.*SQLITE_VERSION\W*"(.*)"', incf)
+                if m:
+                    sqlite_version = m.group(1)
+                    sqlite_version_tuple = tuple([int(x)
+                                        for x in sqlite_version.split(".")])
+                    if sqlite_version_tuple >= MIN_SQLITE_VERSION_NUMBER:
+                        # we win!
+                        print "%s/sqlite3.h: version %s"%(d, sqlite_version)
+                        sqlite_incdir = d
+                        break
+                    else:
+                        if sqlite_setup_debug:
+                            print "%s: version %d is too old, need >= %s"%(d,
+                                        sqlite_version, MIN_SQLITE_VERSION)
+                elif sqlite_setup_debug:
+                    print "sqlite: %s had no SQLITE_VERSION"%(f,)
+
+        if sqlite_incdir:
+            sqlite_dirs_to_check = [
+                os.path.join(sqlite_incdir, '..', 'lib64'),
+                os.path.join(sqlite_incdir, '..', 'lib'),
+                os.path.join(sqlite_incdir, '..', '..', 'lib64'),
+                os.path.join(sqlite_incdir, '..', '..', 'lib'),
+            ]
+            sqlite_libfile = self.compiler.find_library_file(
+                                sqlite_dirs_to_check + lib_dirs, 'sqlite3')
+            sqlite_libdir = [os.path.abspath(os.path.dirname(sqlite_libfile))]
+
+        if sqlite_incdir and sqlite_libdir:
+            sqlite_srcs = ['_sqlite/cache.c',
+                '_sqlite/connection.c',
+                '_sqlite/cursor.c',
+                '_sqlite/microprotocols.c',
+                '_sqlite/module.c',
+                '_sqlite/prepare_protocol.c',
+                '_sqlite/row.c',
+                '_sqlite/statement.c',
+                '_sqlite/util.c', ]
+
+            sqlite_defines = []
+            if sys.platform != "win32":
+                sqlite_defines.append(('MODULE_NAME', '"sqlite3"'))
+            else:
+                sqlite_defines.append(('MODULE_NAME', '\\"sqlite3\\"'))
+
+
+            if sys.platform == 'darwin':
+                # In every directory on the search path search for a dynamic
+                # library and then a static library, instead of first looking
+                # for dynamic libraries on the entiry path.
+                # This way a staticly linked custom sqlite gets picked up
+                # before the dynamic library in /usr/lib.
+                sqlite_extra_link_args = ('-Wl,-search_paths_first',)
+            else:
+                sqlite_extra_link_args = ()
+
+            exts.append(Extension('_sqlite3', sqlite_srcs,
+                                  define_macros=sqlite_defines,
+                                  include_dirs=["Modules/_sqlite",
+                                                sqlite_incdir],
+                                  library_dirs=sqlite_libdir,
+                                  runtime_library_dirs=sqlite_libdir,
+                                  extra_link_args=sqlite_extra_link_args,
+                                  libraries=["sqlite3",]))
+
+        # Look for Berkeley db 1.85.   Note that it is built as a different
+        # module name so it can be included even when later versions are
+        # available.  A very restrictive search is performed to avoid
+        # accidentally building this module with a later version of the
+        # underlying db library.  May BSD-ish Unixes incorporate db 1.85
+        # symbols into libc and place the include file in /usr/include.
+        f = "/usr/include/db.h"
+        if os.path.exists(f):
+            data = open(f).read()
+            m = re.search(r"#s*define\s+HASHVERSION\s+2\s*", data)
+            if m is not None:
+                # bingo - old version used hash file format version 2
+                ### XXX this should be fixed to not be platform-dependent
+                ### but I don't have direct access to an osf1 platform and
+                ### seemed to be muffing the search somehow
+                libraries = platform == "osf1" and ['db'] or None
+                if libraries is not None:
+                    exts.append(Extension('bsddb185', ['bsddbmodule.c'],
+                                          libraries=libraries))
+                else:
+                    exts.append(Extension('bsddb185', ['bsddbmodule.c']))
+
+        # The standard Unix dbm module:
+        if platform not in ['cygwin']:
+            if find_file("ndbm.h", inc_dirs, []) is not None:
+                # Some systems have -lndbm, others don't
+                if self.compiler.find_library_file(lib_dirs, 'ndbm'):
+                    ndbm_libs = ['ndbm']
+                else:
+                    ndbm_libs = []
+                exts.append( Extension('dbm', ['dbmmodule.c'],
+                                       define_macros=[('HAVE_NDBM_H',None)],
+                                       libraries = ndbm_libs ) )
+            elif (self.compiler.find_library_file(lib_dirs, 'gdbm')
+                  and find_file("gdbm/ndbm.h", inc_dirs, []) is not None):
+                exts.append( Extension('dbm', ['dbmmodule.c'],
+                                       define_macros=[('HAVE_GDBM_NDBM_H',None)],
+                                       libraries = ['gdbm'] ) )
+            elif db_incs is not None:
+                exts.append( Extension('dbm', ['dbmmodule.c'],
+                                       library_dirs=dblib_dir,
+                                       runtime_library_dirs=dblib_dir,
+                                       include_dirs=db_incs,
+                                       define_macros=[('HAVE_BERKDB_H',None),
+                                                      ('DB_DBM_HSEARCH',None)],
+                                       libraries=dblibs))
+
+        # Anthony Baxter's gdbm module.  GNU dbm(3) will require -lgdbm:
+        if (self.compiler.find_library_file(lib_dirs, 'gdbm')):
+            exts.append( Extension('gdbm', ['gdbmmodule.c'],
+                                   libraries = ['gdbm'] ) )
+
+        # Unix-only modules
+        if platform not in ['mac', 'win32']:
+            # Steen Lumholt's termios module
+            exts.append( Extension('termios', ['termios.c']) )
+            # Jeremy Hylton's rlimit interface
+            if platform not in ['atheos']:
+                exts.append( Extension('resource', ['resource.c']) )
+
+            # Sun yellow pages. Some systems have the functions in libc.
+            if platform not in ['cygwin', 'atheos']:
+                if (self.compiler.find_library_file(lib_dirs, 'nsl')):
+                    libs = ['nsl']
+                else:
+                    libs = []
+                exts.append( Extension('nis', ['nismodule.c'],
+                                       libraries = libs) )
+
+        # Curses support, requiring the System V version of curses, often
+        # provided by the ncurses library.
+        panel_library = 'panel'
+        if (self.compiler.find_library_file(lib_dirs, 'ncursesw')):
+            curses_libs = ['ncursesw']
+            # Bug 1464056: If _curses.so links with ncursesw,
+            # _curses_panel.so must link with panelw.
+            panel_library = 'panelw'
+            exts.append( Extension('_curses', ['_cursesmodule.c'],
+                                   libraries = curses_libs) )
+        elif (self.compiler.find_library_file(lib_dirs, 'ncurses')):
+            curses_libs = ['ncurses']
+            exts.append( Extension('_curses', ['_cursesmodule.c'],
+                                   libraries = curses_libs) )
+        elif (self.compiler.find_library_file(lib_dirs, 'curses')
+              and platform != 'darwin'):
+                # OSX has an old Berkeley curses, not good enough for
+                # the _curses module.
+            if (self.compiler.find_library_file(lib_dirs, 'terminfo')):
+                curses_libs = ['curses', 'terminfo']
+            elif (self.compiler.find_library_file(lib_dirs, 'termcap')):
+                curses_libs = ['curses', 'termcap']
+            else:
+                curses_libs = ['curses']
+
+            exts.append( Extension('_curses', ['_cursesmodule.c'],
+                                   libraries = curses_libs) )
+
+        # If the curses module is enabled, check for the panel module
+        if (module_enabled(exts, '_curses') and
+            self.compiler.find_library_file(lib_dirs, panel_library)):
+            exts.append( Extension('_curses_panel', ['_curses_panel.c'],
+                                   libraries = [panel_library] + curses_libs) )
+
+
+        # Andrew Kuchling's zlib module.  Note that some versions of zlib
+        # 1.1.3 have security problems.  See CERT Advisory CA-2002-07:
+        # http://www.cert.org/advisories/CA-2002-07.html
+        #
+        # zlib 1.1.4 is fixed, but at least one vendor (RedHat) has decided to
+        # patch its zlib 1.1.3 package instead of upgrading to 1.1.4.  For
+        # now, we still accept 1.1.3, because we think it's difficult to
+        # exploit this in Python, and we'd rather make it RedHat's problem
+        # than our problem <wink>.
+        #
+        # You can upgrade zlib to version 1.1.4 yourself by going to
+        # http://www.gzip.org/zlib/
+        zlib_inc = find_file('zlib.h', [], inc_dirs)
+        if zlib_inc is not None:
+            zlib_h = zlib_inc[0] + '/zlib.h'
+            version = '"0.0.0"'
+            version_req = '"1.1.3"'
+            fp = open(zlib_h)
+            while 1:
+                line = fp.readline()
+                if not line:
+                    break
+                if line.startswith('#define ZLIB_VERSION'):
+                    version = line.split()[2]
+                    break
+            if version >= version_req:
+                if (self.compiler.find_library_file(lib_dirs, 'z')):
+                    if sys.platform == "darwin":
+                        zlib_extra_link_args = ('-Wl,-search_paths_first',)
+                    else:
+                        zlib_extra_link_args = ()
+                    exts.append( Extension('zlib', ['zlibmodule.c'],
+                                           libraries = ['z'],
+                                           extra_link_args = zlib_extra_link_args))
+
+        # Gustavo Niemeyer's bz2 module.
+        if (self.compiler.find_library_file(lib_dirs, 'bz2')):
+            if sys.platform == "darwin":
+                bz2_extra_link_args = ('-Wl,-search_paths_first',)
+            else:
+                bz2_extra_link_args = ()
+            exts.append( Extension('bz2', ['bz2module.c'],
+                                   libraries = ['bz2'],
+                                   extra_link_args = bz2_extra_link_args) )
+
+        # Interface to the Expat XML parser
+        #
+        # Expat was written by James Clark and is now maintained by a
+        # group of developers on SourceForge; see www.libexpat.org for
+        # more information.  The pyexpat module was written by Paul
+        # Prescod after a prototype by Jack Jansen.  The Expat source
+        # is included in Modules/expat/.  Usage of a system
+        # shared libexpat.so/expat.dll is not advised.
+        #
+        # More information on Expat can be found at www.libexpat.org.
+        #
+        expatinc = os.path.join(os.getcwd(), srcdir, 'Modules', 'expat')
+        define_macros = [
+            ('HAVE_EXPAT_CONFIG_H', '1'),
+        ]
+
+        exts.append(Extension('pyexpat',
+                              define_macros = define_macros,
+                              include_dirs = [expatinc],
+                              sources = ['pyexpat.c',
+                                         'expat/xmlparse.c',
+                                         'expat/xmlrole.c',
+                                         'expat/xmltok.c',
+                                         ],
+                              ))
+
+        # Fredrik Lundh's cElementTree module.  Note that this also
+        # uses expat (via the CAPI hook in pyexpat).
+
+        if os.path.isfile(os.path.join(srcdir, 'Modules', '_elementtree.c')):
+            define_macros.append(('USE_PYEXPAT_CAPI', None))
+            exts.append(Extension('_elementtree',
+                                  define_macros = define_macros,
+                                  include_dirs = [expatinc],
+                                  sources = ['_elementtree.c'],
+                                  ))
+
+        # Hye-Shik Chang's CJKCodecs modules.
+        if have_unicode:
+            exts.append(Extension('_multibytecodec',
+                                  ['cjkcodecs/multibytecodec.c']))
+            for loc in ('kr', 'jp', 'cn', 'tw', 'hk', 'iso2022'):
+                exts.append(Extension('_codecs_' + loc,
+                                      ['cjkcodecs/_codecs_%s.c' % loc]))
+
+        # Dynamic loading module
+        if sys.maxint == 0x7fffffff:
+            # This requires sizeof(int) == sizeof(long) == sizeof(char*)
+            dl_inc = find_file('dlfcn.h', [], inc_dirs)
+            if (dl_inc is not None) and (platform not in ['atheos']):
+                exts.append( Extension('dl', ['dlmodule.c']) )
+
+        # Thomas Heller's _ctypes module
+        self.detect_ctypes(inc_dirs, lib_dirs)
+
+        # Platform-specific libraries
+        if platform == 'linux2':
+            # Linux-specific modules
+            exts.append( Extension('linuxaudiodev', ['linuxaudiodev.c']) )
+
+        if platform in ('linux2', 'freebsd4', 'freebsd5', 'freebsd6',
+                        'freebsd7'):
+            exts.append( Extension('ossaudiodev', ['ossaudiodev.c']) )
+
+        if platform == 'sunos5':
+            # SunOS specific modules
+            exts.append( Extension('sunaudiodev', ['sunaudiodev.c']) )
+
+        if platform == 'darwin' and ("--disable-toolbox-glue" not in
+                sysconfig.get_config_var("CONFIG_ARGS")):
+
+            if os.uname()[2] > '8.':
+                # We're on Mac OS X 10.4 or later, the compiler should
+                # support '-Wno-deprecated-declarations'. This will
+                # surpress deprecation warnings for the Carbon extensions,
+                # these extensions wrap the Carbon APIs and even those
+                # parts that are deprecated.
+                carbon_extra_compile_args = ['-Wno-deprecated-declarations']
+            else:
+                carbon_extra_compile_args = []
+
+            # Mac OS X specific modules.
+            def macSrcExists(name1, name2=''):
+                if not name1:
+                    return None
+                names = (name1,)
+                if name2:
+                    names = (name1, name2)
+                path = os.path.join(srcdir, 'Mac', 'Modules', *names)
+                return os.path.exists(path)
+
+            def addMacExtension(name, kwds, extra_srcs=[]):
+                dirname = ''
+                if name[0] == '_':
+                    dirname = name[1:].lower()
+                cname = name + '.c'
+                cmodulename = name + 'module.c'
+                # Check for NNN.c, NNNmodule.c, _nnn/NNN.c, _nnn/NNNmodule.c
+                if macSrcExists(cname):
+                    srcs = [cname]
+                elif macSrcExists(cmodulename):
+                    srcs = [cmodulename]
+                elif macSrcExists(dirname, cname):
+                    # XXX(nnorwitz): If all the names ended with module, we
+                    # wouldn't need this condition.  ibcarbon is the only one.
+                    srcs = [os.path.join(dirname, cname)]
+                elif macSrcExists(dirname, cmodulename):
+                    srcs = [os.path.join(dirname, cmodulename)]
+                else:
+                    raise RuntimeError("%s not found" % name)
+
+                # Here's the whole point:  add the extension with sources
+                exts.append(Extension(name, srcs + extra_srcs, **kwds))
+
+            # Core Foundation
+            core_kwds = {'extra_compile_args': carbon_extra_compile_args,
+                         'extra_link_args': ['-framework', 'CoreFoundation'],
+                        }
+            addMacExtension('_CF', core_kwds, ['cf/pycfbridge.c'])
+            addMacExtension('autoGIL', core_kwds)
+
+            # Carbon
+            carbon_kwds = {'extra_compile_args': carbon_extra_compile_args,
+                           'extra_link_args': ['-framework', 'Carbon'],
+                          }
+            CARBON_EXTS = ['ColorPicker', 'gestalt', 'MacOS', 'Nav',
+                           'OSATerminology', 'icglue',
+                           # All these are in subdirs
+                           '_AE', '_AH', '_App', '_CarbonEvt', '_Cm', '_Ctl',
+                           '_Dlg', '_Drag', '_Evt', '_File', '_Folder', '_Fm',
+                           '_Help', '_Icn', '_IBCarbon', '_List',
+                           '_Menu', '_Mlte', '_OSA', '_Res', '_Qd', '_Qdoffs',
+                           '_Scrap', '_Snd', '_TE', '_Win',
+                          ]
+            for name in CARBON_EXTS:
+                addMacExtension(name, carbon_kwds)
+
+            # Application Services & QuickTime
+            app_kwds = {'extra_compile_args': carbon_extra_compile_args,
+                        'extra_link_args': ['-framework','ApplicationServices'],
+                       }
+            addMacExtension('_Launch', app_kwds)
+            addMacExtension('_CG', app_kwds)
+
+            exts.append( Extension('_Qt', ['qt/_Qtmodule.c'],
+                        extra_compile_args=carbon_extra_compile_args,
+                        extra_link_args=['-framework', 'QuickTime',
+                                     '-framework', 'Carbon']) )
+
+
+        self.extensions.extend(exts)
+
+        # Call the method for detecting whether _tkinter can be compiled
+        self.detect_tkinter(inc_dirs, lib_dirs)
+
+    def detect_tkinter_darwin(self, inc_dirs, lib_dirs):
+        # The _tkinter module, using frameworks. Since frameworks are quite
+        # different the UNIX search logic is not sharable.
+        from os.path import join, exists
+        framework_dirs = [
+            '/System/Library/Frameworks/',
+            '/Library/Frameworks',
+            join(os.getenv('HOME'), '/Library/Frameworks')
+        ]
+
+        # Find the directory that contains the Tcl.framework and Tk.framework
+        # bundles.
+        # XXX distutils should support -F!
+        for F in framework_dirs:
+            # both Tcl.framework and Tk.framework should be present
+            for fw in 'Tcl', 'Tk':
+                if not exists(join(F, fw + '.framework')):
+                    break
+            else:
+                # ok, F is now directory with both frameworks. Continure
+                # building
+                break
+        else:
+            # Tk and Tcl frameworks not found. Normal "unix" tkinter search
+            # will now resume.
+            return 0
+
+        # For 8.4a2, we must add -I options that point inside the Tcl and Tk
+        # frameworks. In later release we should hopefully be able to pass
+        # the -F option to gcc, which specifies a framework lookup path.
+        #
+        include_dirs = [
+            join(F, fw + '.framework', H)
+            for fw in 'Tcl', 'Tk'
+            for H in 'Headers', 'Versions/Current/PrivateHeaders'
+        ]
+
+        # For 8.4a2, the X11 headers are not included. Rather than include a
+        # complicated search, this is a hard-coded path. It could bail out
+        # if X11 libs are not found...
+        include_dirs.append('/usr/X11R6/include')
+        frameworks = ['-framework', 'Tcl', '-framework', 'Tk']
+
+        ext = Extension('_tkinter', ['_tkinter.c', 'tkappinit.c'],
+                        define_macros=[('WITH_APPINIT', 1)],
+                        include_dirs = include_dirs,
+                        libraries = [],
+                        extra_compile_args = frameworks,
+                        extra_link_args = frameworks,
+                        )
+        self.extensions.append(ext)
+        return 1
+
+
+    def detect_tkinter(self, inc_dirs, lib_dirs):
+        # The _tkinter module.
+
+        # Rather than complicate the code below, detecting and building
+        # AquaTk is a separate method. Only one Tkinter will be built on
+        # Darwin - either AquaTk, if it is found, or X11 based Tk.
+        platform = self.get_platform()
+        if (platform == 'darwin' and
+            self.detect_tkinter_darwin(inc_dirs, lib_dirs)):
+            return
+
+        # Assume we haven't found any of the libraries or include files
+        # The versions with dots are used on Unix, and the versions without
+        # dots on Windows, for detection by cygwin.
+        tcllib = tklib = tcl_includes = tk_includes = None
+        for version in ['8.5', '85', '8.4', '84', '8.3', '83', '8.2',
+                        '82', '8.1', '81', '8.0', '80']:
+            tklib = self.compiler.find_library_file(lib_dirs, 'tk' + version)
+            tcllib = self.compiler.find_library_file(lib_dirs, 'tcl' + version)
+            if tklib and tcllib:
+                # Exit the loop when we've found the Tcl/Tk libraries
+                break
+
+        # Now check for the header files
+        if tklib and tcllib:
+            # Check for the include files on Debian and {Free,Open}BSD, where
+            # they're put in /usr/include/{tcl,tk}X.Y
+            dotversion = version
+            if '.' not in dotversion and "bsd" in sys.platform.lower():
+                # OpenBSD and FreeBSD use Tcl/Tk library names like libtcl83.a,
+                # but the include subdirs are named like .../include/tcl8.3.
+                dotversion = dotversion[:-1] + '.' + dotversion[-1]
+            tcl_include_sub = []
+            tk_include_sub = []
+            for dir in inc_dirs:
+                tcl_include_sub += [dir + os.sep + "tcl" + dotversion]
+                tk_include_sub += [dir + os.sep + "tk" + dotversion]
+            tk_include_sub += tcl_include_sub
+            tcl_includes = find_file('tcl.h', inc_dirs, tcl_include_sub)
+            tk_includes = find_file('tk.h', inc_dirs, tk_include_sub)
+
+        if (tcllib is None or tklib is None or
+            tcl_includes is None or tk_includes is None):
+            self.announce("INFO: Can't locate Tcl/Tk libs and/or headers", 2)
+            return
+
+        # OK... everything seems to be present for Tcl/Tk.
+
+        include_dirs = [] ; libs = [] ; defs = [] ; added_lib_dirs = []
+        for dir in tcl_includes + tk_includes:
+            if dir not in include_dirs:
+                include_dirs.append(dir)
+
+        # Check for various platform-specific directories
+        if platform == 'sunos5':
+            include_dirs.append('/usr/openwin/include')
+            added_lib_dirs.append('/usr/openwin/lib')
+        elif os.path.exists('/usr/X11R6/include'):
+            include_dirs.append('/usr/X11R6/include')
+            added_lib_dirs.append('/usr/X11R6/lib64')
+            added_lib_dirs.append('/usr/X11R6/lib')
+        elif os.path.exists('/usr/X11R5/include'):
+            include_dirs.append('/usr/X11R5/include')
+            added_lib_dirs.append('/usr/X11R5/lib')
+        else:
+            # Assume default location for X11
+            include_dirs.append('/usr/X11/include')
+            added_lib_dirs.append('/usr/X11/lib')
+
+        # If Cygwin, then verify that X is installed before proceeding
+        if platform == 'cygwin':
+            x11_inc = find_file('X11/Xlib.h', [], include_dirs)
+            if x11_inc is None:
+                return
+
+        # Check for BLT extension
+        if self.compiler.find_library_file(lib_dirs + added_lib_dirs,
+                                           'BLT8.0'):
+            defs.append( ('WITH_BLT', 1) )
+            libs.append('BLT8.0')
+        elif self.compiler.find_library_file(lib_dirs + added_lib_dirs,
+                                           'BLT'):
+            defs.append( ('WITH_BLT', 1) )
+            libs.append('BLT')
+
+        # Add the Tcl/Tk libraries
+        libs.append('tk'+ version)
+        libs.append('tcl'+ version)
+
+        if platform in ['aix3', 'aix4']:
+            libs.append('ld')
+
+        # Finally, link with the X11 libraries (not appropriate on cygwin)
+        if platform != "cygwin":
+            libs.append('X11')
+
+        ext = Extension('_tkinter', ['_tkinter.c', 'tkappinit.c'],
+                        define_macros=[('WITH_APPINIT', 1)] + defs,
+                        include_dirs = include_dirs,
+                        libraries = libs,
+                        library_dirs = added_lib_dirs,
+                        )
+        self.extensions.append(ext)
+
+##         # Uncomment these lines if you want to play with xxmodule.c
+##         ext = Extension('xx', ['xxmodule.c'])
+##         self.extensions.append(ext)
+
+        # XXX handle these, but how to detect?
+        # *** Uncomment and edit for PIL (TkImaging) extension only:
+        #       -DWITH_PIL -I../Extensions/Imaging/libImaging  tkImaging.c \
+        # *** Uncomment and edit for TOGL extension only:
+        #       -DWITH_TOGL togl.c \
+        # *** Uncomment these for TOGL extension only:
+        #       -lGL -lGLU -lXext -lXmu \
+
+    def configure_ctypes(self, ext):
+        if not self.use_system_libffi:
+            (srcdir,) = sysconfig.get_config_vars('srcdir')
+            ffi_builddir = os.path.join(self.build_temp, 'libffi')
+            ffi_srcdir = os.path.abspath(os.path.join(srcdir, 'Modules',
+                                         '_ctypes', 'libffi'))
+            ffi_configfile = os.path.join(ffi_builddir, 'fficonfig.py')
+
+            from distutils.dep_util import newer_group
+
+            config_sources = [os.path.join(ffi_srcdir, fname)
+                              for fname in os.listdir(ffi_srcdir)
+                              if os.path.isfile(os.path.join(ffi_srcdir, fname))]
+            if self.force or newer_group(config_sources,
+                                         ffi_configfile):
+                from distutils.dir_util import mkpath
+                mkpath(ffi_builddir)
+                config_args = []
+
+                # Pass empty CFLAGS because we'll just append the resulting
+                # CFLAGS to Python's; -g or -O2 is to be avoided.
+                cmd = "cd %s && env CFLAGS='' '%s/configure' %s" \
+                      % (ffi_builddir, ffi_srcdir, " ".join(config_args))
+
+                res = os.system(cmd)
+                if res or not os.path.exists(ffi_configfile):
+                    print "Failed to configure _ctypes module"
+                    return False
+
+            fficonfig = {}
+            execfile(ffi_configfile, globals(), fficonfig)
+            ffi_srcdir = os.path.join(fficonfig['ffi_srcdir'], 'src')
+
+            # Add .S (preprocessed assembly) to C compiler source extensions.
+            self.compiler.src_extensions.append('.S')
+
+            include_dirs = [os.path.join(ffi_builddir, 'include'),
+                            ffi_builddir, ffi_srcdir]
+            extra_compile_args = fficonfig['ffi_cflags'].split()
+
+            ext.sources.extend(fficonfig['ffi_sources'])
+            ext.include_dirs.extend(include_dirs)
+            ext.extra_compile_args.extend(extra_compile_args)
+        return True
+
+    def detect_ctypes(self, inc_dirs, lib_dirs):
+        self.use_system_libffi = False
+        include_dirs = []
+        extra_compile_args = []
+        extra_link_args = []
+        sources = ['_ctypes/_ctypes.c',
+                   '_ctypes/callbacks.c',
+                   '_ctypes/callproc.c',
+                   '_ctypes/stgdict.c',
+                   '_ctypes/cfield.c',
+                   '_ctypes/malloc_closure.c']
+        depends = ['_ctypes/ctypes.h']
+
+        if sys.platform == 'darwin':
+            sources.append('_ctypes/darwin/dlfcn_simple.c')
+            include_dirs.append('_ctypes/darwin')
+# XXX Is this still needed?
+##            extra_link_args.extend(['-read_only_relocs', 'warning'])
+
+        elif sys.platform == 'sunos5':
+            # XXX This shouldn't be necessary; it appears that some
+            # of the assembler code is non-PIC (i.e. it has relocations
+            # when it shouldn't. The proper fix would be to rewrite
+            # the assembler code to be PIC.
+            # This only works with GCC; the Sun compiler likely refuses
+            # this option. If you want to compile ctypes with the Sun
+            # compiler, please research a proper solution, instead of
+            # finding some -z option for the Sun compiler.
+            extra_link_args.append('-mimpure-text')
+
+        ext = Extension('_ctypes',
+                        include_dirs=include_dirs,
+                        extra_compile_args=extra_compile_args,
+                        extra_link_args=extra_link_args,
+                        libraries=[],
+                        sources=sources,
+                        depends=depends)
+        ext_test = Extension('_ctypes_test',
+                             sources=['_ctypes/_ctypes_test.c'])
+        self.extensions.extend([ext, ext_test])
+
+        if not '--with-system-ffi' in sysconfig.get_config_var("CONFIG_ARGS"):
+            return
+
+        ffi_inc = find_file('ffi.h', [], inc_dirs)
+        if ffi_inc is not None:
+            ffi_h = ffi_inc[0] + '/ffi.h'
+            fp = open(ffi_h)
+            while 1:
+                line = fp.readline()
+                if not line:
+                    ffi_inc = None
+                    break
+                if line.startswith('#define LIBFFI_H'):
+                    break
+        ffi_lib = None
+        if ffi_inc is not None:
+            for lib_name in ('ffi_convenience', 'ffi_pic', 'ffi'):
+                if (self.compiler.find_library_file(lib_dirs, lib_name)):
+                    ffi_lib = lib_name
+                    break
+
+        if ffi_inc and ffi_lib:
+            ext.include_dirs.extend(ffi_inc)
+            ext.libraries.append(ffi_lib)
+            self.use_system_libffi = True
+
+
+class PyBuildInstall(install):
+    # Suppress the warning about installation into the lib_dynload
+    # directory, which is not in sys.path when running Python during
+    # installation:
+    def initialize_options (self):
+        install.initialize_options(self)
+        self.warn_dir=0
+
+class PyBuildInstallLib(install_lib):
+    # Do exactly what install_lib does but make sure correct access modes get
+    # set on installed directories and files. All installed files with get
+    # mode 644 unless they are a shared library in which case they will get
+    # mode 755. All installed directories will get mode 755.
+
+    so_ext = sysconfig.get_config_var("SO")
+
+    def install(self):
+        outfiles = install_lib.install(self)
+        self.set_file_modes(outfiles, 0644, 0755)
+        self.set_dir_modes(self.install_dir, 0755)
+        return outfiles
+
+    def set_file_modes(self, files, defaultMode, sharedLibMode):
+        if not self.is_chmod_supported(): return
+        if not files: return
+
+        for filename in files:
+            if os.path.islink(filename): continue
+            mode = defaultMode
+            if filename.endswith(self.so_ext): mode = sharedLibMode
+            log.info("changing mode of %s to %o", filename, mode)
+            if not self.dry_run: os.chmod(filename, mode)
+
+    def set_dir_modes(self, dirname, mode):
+        if not self.is_chmod_supported(): return
+        os.path.walk(dirname, self.set_dir_modes_visitor, mode)
+
+    def set_dir_modes_visitor(self, mode, dirname, names):
+        if os.path.islink(dirname): return
+        log.info("changing mode of %s to %o", dirname, mode)
+        if not self.dry_run: os.chmod(dirname, mode)
+
+    def is_chmod_supported(self):
+        return hasattr(os, 'chmod')
+
+SUMMARY = """
+Python is an interpreted, interactive, object-oriented programming
+language. It is often compared to Tcl, Perl, Scheme or Java.
+
+Python combines remarkable power with very clear syntax. It has
+modules, classes, exceptions, very high level dynamic data types, and
+dynamic typing. There are interfaces to many system calls and
+libraries, as well as to various windowing systems (X11, Motif, Tk,
+Mac, MFC). New built-in modules are easily written in C or C++. Python
+is also usable as an extension language for applications that need a
+programmable interface.
+
+The Python implementation is portable: it runs on many brands of UNIX,
+on Windows, DOS, OS/2, Mac, Amiga... If your favorite system isn't
+listed here, it may still be supported, if there's a C compiler for
+it. Ask around on comp.lang.python -- or just try compiling Python
+yourself.
+"""
+
+CLASSIFIERS = """
+Development Status :: 3 - Alpha
+Development Status :: 6 - Mature
+License :: OSI Approved :: Python Software Foundation License
+Natural Language :: English
+Programming Language :: C
+Programming Language :: Python
+Topic :: Software Development
+"""
+
+def main():
+    # turn off warnings when deprecated modules are imported
+    import warnings
+    warnings.filterwarnings("ignore",category=DeprecationWarning)
+    setup(# PyPI Metadata (PEP 301)
+          name = "Python",
+          version = sys.version.split()[0],
+          url = "http://www.python.org/%s" % sys.version[:3],
+          maintainer = "Guido van Rossum and the Python community",
+          maintainer_email = "python-dev at python.org",
+          description = "A high-level object-oriented programming language",
+          long_description = SUMMARY.strip(),
+          license = "PSF license",
+          classifiers = filter(None, CLASSIFIERS.split("\n")),
+          platforms = ["Many"],
+
+          # Build info
+          cmdclass = {'build_ext':PyBuildExt, 'install':PyBuildInstall,
+                      'install_lib':PyBuildInstallLib},
+          # The struct module is defined here, because build_ext won't be
+          # called unless there's at least one extension module defined.
+          ext_modules=[Extension('_struct', ['_struct.c'])],
+
+          # Scripts to install
+          scripts = ['Tools/scripts/pydoc', 'Tools/scripts/idle',
+                     'Lib/smtpd.py']
+        )
+
+# --install-platlib
+if __name__ == '__main__':
+    main()



More information about the cig-commits mailing list